From 32d479321b3185c903dca6bc5e0e755d0a030c0e Mon Sep 17 00:00:00 2001 From: yuanzihao Date: Tue, 29 Aug 2023 13:10:14 +0800 Subject: [PATCH] [bsp][stm32]: add NUCLEO-H563ZI (#7987) --- .github/workflows/action.yml | 3 +- bsp/stm32/README.md | 203 +- bsp/stm32/libraries/.ignore_format.yml | 1 + .../HAL_Drivers/config/h5/uart_config.h | 151 + bsp/stm32/libraries/HAL_Drivers/drv_config.h | 2 + bsp/stm32/libraries/HAL_Drivers/drv_dma.h | 2 +- bsp/stm32/libraries/HAL_Drivers/drv_gpio.c | 200 +- bsp/stm32/libraries/HAL_Drivers/drv_usart.c | 8 +- bsp/stm32/libraries/HAL_Drivers/drv_usart.h | 3 +- bsp/stm32/libraries/Kconfig | 5 + .../Include/Templates/partition_stm32h562xx.h | 649 + .../Include/Templates/partition_stm32h563xx.h | 654 + .../Include/Templates/partition_stm32h573xx.h | 680 + .../STM32H5xx/Include/partition_stm32h5xx.h | 68 + .../Device/ST/STM32H5xx/Include/stm32h503xx.h | 14040 +++++++++ .../Device/ST/STM32H5xx/Include/stm32h562xx.h | 21472 ++++++++++++++ .../Device/ST/STM32H5xx/Include/stm32h563xx.h | 23608 +++++++++++++++ .../Device/ST/STM32H5xx/Include/stm32h573xx.h | 24557 ++++++++++++++++ .../Device/ST/STM32H5xx/Include/stm32h5xx.h | 238 + .../ST/STM32H5xx/Include/system_stm32h5xx.h | 107 + .../CMSIS/Device/ST/STM32H5xx/LICENSE.txt | 6 + .../Templates/arm/startup_stm32h503xx.s | 479 + .../Templates/arm/startup_stm32h562xx.s | 563 + .../Templates/arm/startup_stm32h563xx.s | 573 + .../Templates/arm/startup_stm32h573xx.s | 581 + .../Templates/gcc/startup_stm32h503xx.s | 547 + .../Templates/gcc/startup_stm32h562xx.s | 680 + .../Templates/gcc/startup_stm32h563xx.s | 696 + .../Templates/gcc/startup_stm32h573xx.s | 712 + .../iar/linker/stm32h503xx_flash.icf | 33 + .../Templates/iar/linker/stm32h503xx_sram.icf | 33 + .../iar/linker/stm32h562xx_flash.icf | 33 + .../iar/linker/stm32h562xx_flash_ns.icf | 32 + .../iar/linker/stm32h562xx_flash_s.icf | 41 + .../Templates/iar/linker/stm32h562xx_sram.icf | 33 + .../iar/linker/stm32h562xx_sram_ns.icf | 33 + .../iar/linker/stm32h562xx_sram_s.icf | 40 + .../iar/linker/stm32h563xx_flash.icf | 33 + .../iar/linker/stm32h563xx_flash_ns.icf | 32 + .../iar/linker/stm32h563xx_flash_s.icf | 41 + .../Templates/iar/linker/stm32h563xx_sram.icf | 33 + .../iar/linker/stm32h563xx_sram_ns.icf | 33 + .../iar/linker/stm32h563xx_sram_s.icf | 40 + .../iar/linker/stm32h573xx_flash.icf | 33 + .../iar/linker/stm32h573xx_flash_ns.icf | 32 + .../iar/linker/stm32h573xx_flash_s.icf | 41 + .../Templates/iar/linker/stm32h573xx_sram.icf | 33 + .../iar/linker/stm32h573xx_sram_ns.icf | 33 + .../iar/linker/stm32h573xx_sram_s.icf | 40 + .../Templates/iar/startup_stm32h503xx.s | 670 + .../Templates/iar/startup_stm32h562xx.s | 887 + .../Templates/iar/startup_stm32h563xx.s | 912 + .../Templates/iar/startup_stm32h573xx.s | 932 + .../Source/Templates/system_stm32h5xx.c | 401 + .../Source/Templates/system_stm32h5xx_ns.c | 208 + .../Source/Templates/system_stm32h5xx_s.c | 430 + bsp/stm32/libraries/STM32H5xx_HAL/SConscript | 119 + .../Inc/Legacy/stm32_hal_legacy.h | 4331 +++ .../Inc/stm32_assert_template.h | 54 + .../STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal.h | 897 + .../Inc/stm32h5xx_hal_adc.h | 2029 ++ .../Inc/stm32h5xx_hal_adc_ex.h | 1216 + .../Inc/stm32h5xx_hal_cec.h | 804 + .../Inc/stm32h5xx_hal_comp.h | 622 + .../Inc/stm32h5xx_hal_conf_template.h | 488 + .../Inc/stm32h5xx_hal_cordic.h | 609 + .../Inc/stm32h5xx_hal_cortex.h | 411 + .../Inc/stm32h5xx_hal_crc.h | 342 + .../Inc/stm32h5xx_hal_crc_ex.h | 150 + .../Inc/stm32h5xx_hal_cryp.h | 724 + .../Inc/stm32h5xx_hal_cryp_ex.h | 154 + .../Inc/stm32h5xx_hal_dac.h | 593 + .../Inc/stm32h5xx_hal_dac_ex.h | 256 + .../Inc/stm32h5xx_hal_dcache.h | 355 + .../Inc/stm32h5xx_hal_dcmi.h | 698 + .../Inc/stm32h5xx_hal_def.h | 231 + .../Inc/stm32h5xx_hal_dma.h | 1180 + .../Inc/stm32h5xx_hal_dma_ex.h | 737 + .../Inc/stm32h5xx_hal_dts.h | 551 + .../Inc/stm32h5xx_hal_eth.h | 1827 ++ .../Inc/stm32h5xx_hal_eth_ex.h | 368 + .../Inc/stm32h5xx_hal_exti.h | 410 + .../Inc/stm32h5xx_hal_fdcan.h | 1442 + .../Inc/stm32h5xx_hal_flash.h | 810 + .../Inc/stm32h5xx_hal_flash_ex.h | 998 + .../Inc/stm32h5xx_hal_fmac.h | 727 + .../Inc/stm32h5xx_hal_gpio.h | 393 + .../Inc/stm32h5xx_hal_gpio_ex.h | 470 + .../Inc/stm32h5xx_hal_gtzc.h | 696 + .../Inc/stm32h5xx_hal_hash.h | 596 + .../Inc/stm32h5xx_hal_hcd.h | 598 + .../Inc/stm32h5xx_hal_i2c.h | 844 + .../Inc/stm32h5xx_hal_i2c_ex.h | 156 + .../Inc/stm32h5xx_hal_i2s.h | 663 + .../Inc/stm32h5xx_hal_i2s_ex.h | 26 + .../Inc/stm32h5xx_hal_i3c.h | 1319 + .../Inc/stm32h5xx_hal_icache.h | 300 + .../Inc/stm32h5xx_hal_irda.h | 902 + .../Inc/stm32h5xx_hal_irda_ex.h | 559 + .../Inc/stm32h5xx_hal_iwdg.h | 302 + .../Inc/stm32h5xx_hal_lptim.h | 1285 + .../Inc/stm32h5xx_hal_mmc.h | 823 + .../Inc/stm32h5xx_hal_mmc_ex.h | 122 + .../Inc/stm32h5xx_hal_nand.h | 378 + .../Inc/stm32h5xx_hal_nor.h | 326 + .../Inc/stm32h5xx_hal_opamp.h | 460 + .../Inc/stm32h5xx_hal_opamp_ex.h | 73 + .../Inc/stm32h5xx_hal_otfdec.h | 487 + .../Inc/stm32h5xx_hal_pcd.h | 629 + .../Inc/stm32h5xx_hal_pcd_ex.h | 88 + .../Inc/stm32h5xx_hal_pka.h | 653 + .../Inc/stm32h5xx_hal_pssi.h | 536 + .../Inc/stm32h5xx_hal_pwr.h | 695 + .../Inc/stm32h5xx_hal_pwr_ex.h | 548 + .../Inc/stm32h5xx_hal_ramcfg.h | 394 + .../Inc/stm32h5xx_hal_rcc.h | 5169 ++++ .../Inc/stm32h5xx_hal_rcc_ex.h | 3800 +++ .../Inc/stm32h5xx_hal_rng.h | 389 + .../Inc/stm32h5xx_hal_rng_ex.h | 263 + .../Inc/stm32h5xx_hal_rtc.h | 980 + .../Inc/stm32h5xx_hal_rtc_ex.h | 1890 ++ .../Inc/stm32h5xx_hal_sai.h | 972 + .../Inc/stm32h5xx_hal_sai_ex.h | 107 + .../Inc/stm32h5xx_hal_sd.h | 798 + .../Inc/stm32h5xx_hal_sd_ex.h | 119 + .../Inc/stm32h5xx_hal_sdram.h | 238 + .../Inc/stm32h5xx_hal_smartcard.h | 1403 + .../Inc/stm32h5xx_hal_smartcard_ex.h | 336 + .../Inc/stm32h5xx_hal_smbus.h | 789 + .../Inc/stm32h5xx_hal_smbus_ex.h | 133 + .../Inc/stm32h5xx_hal_spi.h | 1136 + .../Inc/stm32h5xx_hal_spi_ex.h | 99 + .../Inc/stm32h5xx_hal_sram.h | 232 + .../Inc/stm32h5xx_hal_tim.h | 2527 ++ .../Inc/stm32h5xx_hal_tim_ex.h | 1247 + .../Inc/stm32h5xx_hal_uart.h | 1778 ++ .../Inc/stm32h5xx_hal_uart_ex.h | 401 + .../Inc/stm32h5xx_hal_usart.h | 1175 + .../Inc/stm32h5xx_hal_usart_ex.h | 282 + .../Inc/stm32h5xx_hal_wwdg.h | 306 + .../Inc/stm32h5xx_hal_xspi.h | 1172 + .../Inc/stm32h5xx_ll_adc.h | 8316 ++++++ .../Inc/stm32h5xx_ll_bus.h | 2809 ++ .../Inc/stm32h5xx_ll_comp.h | 801 + .../Inc/stm32h5xx_ll_cordic.h | 783 + .../Inc/stm32h5xx_ll_cortex.h | 1383 + .../Inc/stm32h5xx_ll_crc.h | 461 + .../Inc/stm32h5xx_ll_crs.h | 797 + .../Inc/stm32h5xx_ll_dac.h | 2050 ++ .../Inc/stm32h5xx_ll_dcache.h | 667 + .../Inc/stm32h5xx_ll_dlyb.h | 143 + .../Inc/stm32h5xx_ll_dma.h | 6335 ++++ .../Inc/stm32h5xx_ll_exti.h | 2181 ++ .../Inc/stm32h5xx_ll_fmac.h | 1069 + .../Inc/stm32h5xx_ll_fmc.h | 1248 + .../Inc/stm32h5xx_ll_gpio.h | 1178 + .../Inc/stm32h5xx_ll_i2c.h | 2373 ++ .../Inc/stm32h5xx_ll_i3c.h | 4404 +++ .../Inc/stm32h5xx_ll_icache.h | 784 + .../Inc/stm32h5xx_ll_iwdg.h | 453 + .../Inc/stm32h5xx_ll_lptim.h | 2530 ++ .../Inc/stm32h5xx_ll_lpuart.h | 2643 ++ .../Inc/stm32h5xx_ll_opamp.h | 845 + .../Inc/stm32h5xx_ll_pka.h | 601 + .../Inc/stm32h5xx_ll_pwr.h | 2008 ++ .../Inc/stm32h5xx_ll_rcc.h | 6072 ++++ .../Inc/stm32h5xx_ll_rng.h | 724 + .../Inc/stm32h5xx_ll_rtc.h | 6462 ++++ .../Inc/stm32h5xx_ll_sdmmc.h | 1161 + .../Inc/stm32h5xx_ll_spi.h | 3662 +++ .../Inc/stm32h5xx_ll_system.h | 1824 ++ .../Inc/stm32h5xx_ll_tim.h | 6269 ++++ .../Inc/stm32h5xx_ll_ucpd.h | 1885 ++ .../Inc/stm32h5xx_ll_usart.h | 4401 +++ .../Inc/stm32h5xx_ll_usb.h | 908 + .../Inc/stm32h5xx_ll_utils.h | 354 + .../Inc/stm32h5xx_ll_wwdg.h | 328 + .../Inc/stm32h5xx_util_i3c.h | 133 + .../STM32H5xx_HAL_Driver/LICENSE.txt | 6 + .../STM32H5xx_HAL_Driver/Src/stm32h5xx_hal.c | 1298 + .../Src/stm32h5xx_hal_adc.c | 3773 +++ .../Src/stm32h5xx_hal_adc_ex.c | 2452 ++ .../Src/stm32h5xx_hal_cec.c | 997 + .../Src/stm32h5xx_hal_comp.c | 1192 + .../Src/stm32h5xx_hal_cordic.c | 1357 + .../Src/stm32h5xx_hal_cortex.c | 738 + .../Src/stm32h5xx_hal_crc.c | 516 + .../Src/stm32h5xx_hal_crc_ex.c | 232 + .../Src/stm32h5xx_hal_cryp.c | 6302 ++++ .../Src/stm32h5xx_hal_cryp_ex.c | 898 + .../Src/stm32h5xx_hal_dac.c | 1833 ++ .../Src/stm32h5xx_hal_dac_ex.c | 1010 + .../Src/stm32h5xx_hal_dcache.c | 1475 + .../Src/stm32h5xx_hal_dcmi.c | 1374 + .../Src/stm32h5xx_hal_dma.c | 1710 ++ .../Src/stm32h5xx_hal_dma_ex.c | 4715 +++ .../Src/stm32h5xx_hal_dts.c | 1091 + .../Src/stm32h5xx_hal_eth.c | 3326 +++ .../Src/stm32h5xx_hal_eth_ex.c | 576 + .../Src/stm32h5xx_hal_exti.c | 874 + .../Src/stm32h5xx_hal_fdcan.c | 3540 +++ .../Src/stm32h5xx_hal_flash.c | 919 + .../Src/stm32h5xx_hal_flash_ex.c | 1802 ++ .../Src/stm32h5xx_hal_fmac.c | 2725 ++ .../Src/stm32h5xx_hal_gpio.c | 753 + .../Src/stm32h5xx_hal_gtzc.c | 1852 ++ .../Src/stm32h5xx_hal_hash.c | 3133 ++ .../Src/stm32h5xx_hal_hcd.c | 2868 ++ .../Src/stm32h5xx_hal_i2c.c | 7719 +++++ .../Src/stm32h5xx_hal_i2c_ex.c | 359 + .../Src/stm32h5xx_hal_i2s.c | 2710 ++ .../Src/stm32h5xx_hal_i2s_ex.c | 31 + .../Src/stm32h5xx_hal_i3c.c | 9263 ++++++ .../Src/stm32h5xx_hal_icache.c | 659 + .../Src/stm32h5xx_hal_irda.c | 3023 ++ .../Src/stm32h5xx_hal_iwdg.c | 510 + .../Src/stm32h5xx_hal_lptim.c | 3747 +++ .../Src/stm32h5xx_hal_mmc.c | 4310 +++ .../Src/stm32h5xx_hal_mmc_ex.c | 448 + .../Src/stm32h5xx_hal_msp_template.c | 99 + .../Src/stm32h5xx_hal_nand.c | 2233 ++ .../Src/stm32h5xx_hal_nor.c | 1644 ++ .../Src/stm32h5xx_hal_opamp.c | 1169 + .../Src/stm32h5xx_hal_opamp_ex.c | 118 + .../Src/stm32h5xx_hal_otfdec.c | 1154 + .../Src/stm32h5xx_hal_pcd.c | 2234 ++ .../Src/stm32h5xx_hal_pcd_ex.c | 333 + .../Src/stm32h5xx_hal_pka.c | 2963 ++ .../Src/stm32h5xx_hal_pssi.c | 1870 ++ .../Src/stm32h5xx_hal_pwr.c | 666 + .../Src/stm32h5xx_hal_pwr_ex.c | 824 + .../Src/stm32h5xx_hal_ramcfg.c | 1084 + .../Src/stm32h5xx_hal_rcc.c | 1894 ++ .../Src/stm32h5xx_hal_rcc_ex.c | 6273 ++++ .../Src/stm32h5xx_hal_rng.c | 1027 + .../Src/stm32h5xx_hal_rng_ex.c | 339 + .../Src/stm32h5xx_hal_rtc.c | 2341 ++ .../Src/stm32h5xx_hal_rtc_ex.c | 3271 ++ .../Src/stm32h5xx_hal_sai.c | 2902 ++ .../Src/stm32h5xx_hal_sai_ex.c | 133 + .../Src/stm32h5xx_hal_sd.c | 4098 +++ .../Src/stm32h5xx_hal_sd_ex.c | 393 + .../Src/stm32h5xx_hal_sdram.c | 1431 + .../Src/stm32h5xx_hal_smartcard.c | 3283 +++ .../Src/stm32h5xx_hal_smartcard_ex.c | 495 + .../Src/stm32h5xx_hal_smbus.c | 2773 ++ .../Src/stm32h5xx_hal_smbus_ex.c | 243 + .../Src/stm32h5xx_hal_spi.c | 3810 +++ .../Src/stm32h5xx_hal_spi_ex.c | 228 + .../Src/stm32h5xx_hal_sram.c | 1238 + .../Src/stm32h5xx_hal_tim.c | 8305 ++++++ .../Src/stm32h5xx_hal_tim_ex.c | 3446 +++ ...tm32h5xx_hal_timebase_rtc_alarm_template.c | 284 + ...m32h5xx_hal_timebase_rtc_wakeup_template.c | 268 + .../Src/stm32h5xx_hal_timebase_tim_template.c | 203 + .../Src/stm32h5xx_hal_uart.c | 4764 +++ .../Src/stm32h5xx_hal_uart_ex.c | 1044 + .../Src/stm32h5xx_hal_usart.c | 3981 +++ .../Src/stm32h5xx_hal_usart_ex.c | 541 + .../Src/stm32h5xx_hal_wwdg.c | 419 + .../Src/stm32h5xx_hal_xspi.c | 3193 ++ .../Src/stm32h5xx_ll_adc.c | 1119 + .../Src/stm32h5xx_ll_comp.c | 260 + .../Src/stm32h5xx_ll_cordic.c | 102 + .../Src/stm32h5xx_ll_crc.c | 103 + .../Src/stm32h5xx_ll_crs.c | 84 + .../Src/stm32h5xx_ll_dac.c | 312 + .../Src/stm32h5xx_ll_dlyb.c | 243 + .../Src/stm32h5xx_ll_dma.c | 1130 + .../Src/stm32h5xx_ll_exti.c | 296 + .../Src/stm32h5xx_ll_fmac.c | 136 + .../Src/stm32h5xx_ll_fmc.c | 1162 + .../Src/stm32h5xx_ll_gpio.c | 288 + .../Src/stm32h5xx_ll_i2c.c | 244 + .../Src/stm32h5xx_ll_i3c.c | 212 + .../Src/stm32h5xx_ll_icache.c | 143 + .../Src/stm32h5xx_ll_lptim.c | 219 + .../Src/stm32h5xx_ll_lpuart.c | 285 + .../Src/stm32h5xx_ll_opamp.c | 218 + .../Src/stm32h5xx_ll_pka.c | 163 + .../Src/stm32h5xx_ll_pwr.c | 82 + .../Src/stm32h5xx_ll_rcc.c | 3313 +++ .../Src/stm32h5xx_ll_rng.c | 158 + .../Src/stm32h5xx_ll_rtc.c | 855 + .../Src/stm32h5xx_ll_sdmmc.c | 1883 ++ .../Src/stm32h5xx_ll_spi.c | 751 + .../Src/stm32h5xx_ll_tim.c | 1419 + .../Src/stm32h5xx_ll_ucpd.c | 169 + .../Src/stm32h5xx_ll_usart.c | 548 + .../Src/stm32h5xx_ll_usb.c | 1410 + .../Src/stm32h5xx_ll_utils.c | 933 + .../Src/stm32h5xx_util_i3c.c | 409 + bsp/stm32/stm32h563-st-nucleo/.config | 713 + bsp/stm32/stm32h563-st-nucleo/.gitignore | 42 + .../EventRecorderStub.scvd | 9 + bsp/stm32/stm32h563-st-nucleo/Kconfig | 21 + bsp/stm32/stm32h563-st-nucleo/README.md | 135 + bsp/stm32/stm32h563-st-nucleo/SConscript | 15 + bsp/stm32/stm32h563-st-nucleo/SConstruct | 59 + .../applications/SConscript | 18 + .../applications/arduino_main.cpp | 24 + .../applications/arduino_pinout/README.md | 51 + .../applications/arduino_pinout/SConscript | 9 + .../arduino_pinout/pins_arduino.c | 46 + .../arduino_pinout/pins_arduino.h | 46 + .../stm32h563-st-nucleo/applications/main.c | 33 + .../board/.ignore_format.yml | 7 + .../board/CubeMX_Config/.mxproject | 26 + .../board/CubeMX_Config/CubeMX_Config.ioc | 429 + .../board/CubeMX_Config/Inc/main.h | 146 + .../board/CubeMX_Config/Inc/stm32_assert.h | 53 + .../CubeMX_Config/Inc/stm32h5xx_hal_conf.h | 504 + .../board/CubeMX_Config/Inc/stm32h5xx_it.h | 66 + .../board/CubeMX_Config/Src/main.c | 593 + .../CubeMX_Config/Src/stm32h5xx_hal_msp.c | 467 + .../board/CubeMX_Config/Src/stm32h5xx_it.c | 203 + .../CubeMX_Config/Src/system_stm32h5xx.c | 401 + bsp/stm32/stm32h563-st-nucleo/board/Kconfig | 67 + .../stm32h563-st-nucleo/board/SConscript | 38 + bsp/stm32/stm32h563-st-nucleo/board/board.c | 68 + bsp/stm32/stm32h563-st-nucleo/board/board.h | 52 + .../board/linker_scripts/link.icf | 29 + .../board/linker_scripts/link.lds | 156 + .../board/linker_scripts/link.sct | 15 + .../stm32h563-st-nucleo/board/ports/drv_key.c | 276 + .../board/ports/drv_spi_flash.c | 70 + .../stm32h563-st-nucleo/context_rvds.lst | 779 + .../stm32h563-st-nucleo/figures/board.png | Bin 0 -> 2363086 bytes .../figures/hardware_block_diagram.png | Bin 0 -> 137233 bytes bsp/stm32/stm32h563-st-nucleo/project.ewd | 2834 ++ bsp/stm32/stm32h563-st-nucleo/project.ewp | 2417 ++ bsp/stm32/stm32h563-st-nucleo/project.eww | 10 + bsp/stm32/stm32h563-st-nucleo/project.uvoptx | 1304 + bsp/stm32/stm32h563-st-nucleo/project.uvprojx | 883 + bsp/stm32/stm32h563-st-nucleo/rtconfig.h | 217 + bsp/stm32/stm32h563-st-nucleo/rtconfig.py | 152 + .../startup_stm32h563xx.lst | 3069 ++ .../stm32h563-st-nucleo/syscall_rvds.lst | 177 + bsp/stm32/stm32h563-st-nucleo/template.ewp | 2106 ++ bsp/stm32/stm32h563-st-nucleo/template.eww | 10 + bsp/stm32/stm32h563-st-nucleo/template.uvoptx | 192 + .../stm32h563-st-nucleo/template.uvprojx | 406 + bsp/stm32/stm32u575-st-nucleo/.config | 375 +- bsp/stm32/stm32u575-st-nucleo/project.uvoptx | 1126 +- bsp/stm32/stm32u575-st-nucleo/project.uvprojx | 335 +- bsp/stm32/stm32u575-st-nucleo/rtconfig.h | 71 +- 346 files changed, 450191 insertions(+), 1805 deletions(-) create mode 100644 bsp/stm32/libraries/HAL_Drivers/config/h5/uart_config.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/Templates/partition_stm32h562xx.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/Templates/partition_stm32h563xx.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/Templates/partition_stm32h573xx.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/partition_stm32h5xx.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/stm32h503xx.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/stm32h562xx.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/stm32h563xx.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/stm32h573xx.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/stm32h5xx.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/system_stm32h5xx.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/LICENSE.txt create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/arm/startup_stm32h503xx.s create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/arm/startup_stm32h562xx.s create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/arm/startup_stm32h563xx.s create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/arm/startup_stm32h573xx.s create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/gcc/startup_stm32h503xx.s create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/gcc/startup_stm32h562xx.s create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/gcc/startup_stm32h563xx.s create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/gcc/startup_stm32h573xx.s create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h503xx_flash.icf create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h503xx_sram.icf create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h562xx_flash.icf create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h562xx_flash_ns.icf create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h562xx_flash_s.icf create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h562xx_sram.icf create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h562xx_sram_ns.icf create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h562xx_sram_s.icf create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h563xx_flash.icf create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h563xx_flash_ns.icf create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h563xx_flash_s.icf create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h563xx_sram.icf create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h563xx_sram_ns.icf create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h563xx_sram_s.icf create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h573xx_flash.icf create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h573xx_flash_ns.icf create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h573xx_flash_s.icf create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h573xx_sram.icf create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h573xx_sram_ns.icf create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h573xx_sram_s.icf create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/startup_stm32h503xx.s create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/startup_stm32h562xx.s create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/startup_stm32h563xx.s create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/startup_stm32h573xx.s create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/system_stm32h5xx.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/system_stm32h5xx_ns.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/system_stm32h5xx_s.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/SConscript create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32_assert_template.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_adc.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_adc_ex.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_cec.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_comp.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_conf_template.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_cordic.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_cortex.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_crc.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_crc_ex.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_cryp.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_cryp_ex.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_dac.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_dac_ex.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_dcache.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_dcmi.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_def.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_dma.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_dma_ex.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_dts.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_eth.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_eth_ex.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_exti.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_fdcan.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_flash.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_flash_ex.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_fmac.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_gpio.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_gpio_ex.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_gtzc.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_hash.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_hcd.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_i2c.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_i2c_ex.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_i2s.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_i2s_ex.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_i3c.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_icache.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_irda.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_irda_ex.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_iwdg.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_lptim.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_mmc.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_mmc_ex.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_nand.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_nor.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_opamp.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_opamp_ex.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_otfdec.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_pcd.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_pcd_ex.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_pka.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_pssi.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_pwr.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_pwr_ex.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_ramcfg.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_rcc.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_rcc_ex.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_rng.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_rng_ex.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_rtc.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_rtc_ex.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_sai.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_sai_ex.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_sd.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_sd_ex.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_sdram.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_smartcard.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_smartcard_ex.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_smbus.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_smbus_ex.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_spi.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_spi_ex.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_sram.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_tim.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_tim_ex.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_uart.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_uart_ex.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_usart.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_usart_ex.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_wwdg.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_xspi.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_adc.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_bus.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_comp.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_cordic.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_cortex.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_crc.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_crs.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_dac.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_dcache.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_dlyb.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_dma.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_exti.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_fmac.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_fmc.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_gpio.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_i2c.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_i3c.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_icache.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_iwdg.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_lptim.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_lpuart.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_opamp.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_pka.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_pwr.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_rcc.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_rng.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_rtc.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_sdmmc.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_spi.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_system.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_tim.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_ucpd.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_usart.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_usb.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_utils.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_wwdg.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_util_i3c.h create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/LICENSE.txt create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_adc.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_adc_ex.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_cec.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_comp.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_cordic.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_cortex.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_crc.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_crc_ex.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_cryp.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_cryp_ex.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dac.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dac_ex.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dcache.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dcmi.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dma.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dma_ex.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dts.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_eth.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_eth_ex.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_exti.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_fdcan.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_flash.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_flash_ex.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_fmac.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_gpio.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_gtzc.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_hash.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_hcd.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_i2c.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_i2c_ex.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_i2s.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_i2s_ex.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_i3c.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_icache.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_irda.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_iwdg.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_lptim.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_mmc.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_mmc_ex.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_msp_template.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_nand.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_nor.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_opamp.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_opamp_ex.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_otfdec.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pcd.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pcd_ex.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pka.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pssi.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pwr.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pwr_ex.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_ramcfg.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rcc.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rcc_ex.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rng.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rng_ex.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rtc.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rtc_ex.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sai.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sai_ex.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sd.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sd_ex.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sdram.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_smartcard.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_smartcard_ex.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_smbus.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_smbus_ex.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_spi.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_spi_ex.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sram.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_tim.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_tim_ex.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_timebase_rtc_alarm_template.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_timebase_rtc_wakeup_template.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_timebase_tim_template.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_uart.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_uart_ex.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_usart.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_usart_ex.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_wwdg.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_xspi.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_adc.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_comp.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_cordic.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_crc.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_crs.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_dac.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_dlyb.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_dma.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_exti.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_fmac.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_fmc.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_gpio.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_i2c.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_i3c.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_icache.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_lptim.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_lpuart.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_opamp.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_pka.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_pwr.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_rcc.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_rng.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_rtc.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_sdmmc.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_spi.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_tim.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_ucpd.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_usart.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_usb.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_utils.c create mode 100644 bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_util_i3c.c create mode 100644 bsp/stm32/stm32h563-st-nucleo/.config create mode 100644 bsp/stm32/stm32h563-st-nucleo/.gitignore create mode 100644 bsp/stm32/stm32h563-st-nucleo/EventRecorderStub.scvd create mode 100644 bsp/stm32/stm32h563-st-nucleo/Kconfig create mode 100644 bsp/stm32/stm32h563-st-nucleo/README.md create mode 100644 bsp/stm32/stm32h563-st-nucleo/SConscript create mode 100644 bsp/stm32/stm32h563-st-nucleo/SConstruct create mode 100644 bsp/stm32/stm32h563-st-nucleo/applications/SConscript create mode 100644 bsp/stm32/stm32h563-st-nucleo/applications/arduino_main.cpp create mode 100644 bsp/stm32/stm32h563-st-nucleo/applications/arduino_pinout/README.md create mode 100644 bsp/stm32/stm32h563-st-nucleo/applications/arduino_pinout/SConscript create mode 100644 bsp/stm32/stm32h563-st-nucleo/applications/arduino_pinout/pins_arduino.c create mode 100644 bsp/stm32/stm32h563-st-nucleo/applications/arduino_pinout/pins_arduino.h create mode 100644 bsp/stm32/stm32h563-st-nucleo/applications/main.c create mode 100644 bsp/stm32/stm32h563-st-nucleo/board/.ignore_format.yml create mode 100644 bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/.mxproject create mode 100644 bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/CubeMX_Config.ioc create mode 100644 bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Inc/main.h create mode 100644 bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Inc/stm32_assert.h create mode 100644 bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Inc/stm32h5xx_hal_conf.h create mode 100644 bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Inc/stm32h5xx_it.h create mode 100644 bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Src/main.c create mode 100644 bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Src/stm32h5xx_hal_msp.c create mode 100644 bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Src/stm32h5xx_it.c create mode 100644 bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Src/system_stm32h5xx.c create mode 100644 bsp/stm32/stm32h563-st-nucleo/board/Kconfig create mode 100644 bsp/stm32/stm32h563-st-nucleo/board/SConscript create mode 100644 bsp/stm32/stm32h563-st-nucleo/board/board.c create mode 100644 bsp/stm32/stm32h563-st-nucleo/board/board.h create mode 100644 bsp/stm32/stm32h563-st-nucleo/board/linker_scripts/link.icf create mode 100644 bsp/stm32/stm32h563-st-nucleo/board/linker_scripts/link.lds create mode 100644 bsp/stm32/stm32h563-st-nucleo/board/linker_scripts/link.sct create mode 100644 bsp/stm32/stm32h563-st-nucleo/board/ports/drv_key.c create mode 100644 bsp/stm32/stm32h563-st-nucleo/board/ports/drv_spi_flash.c create mode 100644 bsp/stm32/stm32h563-st-nucleo/context_rvds.lst create mode 100644 bsp/stm32/stm32h563-st-nucleo/figures/board.png create mode 100644 bsp/stm32/stm32h563-st-nucleo/figures/hardware_block_diagram.png create mode 100644 bsp/stm32/stm32h563-st-nucleo/project.ewd create mode 100644 bsp/stm32/stm32h563-st-nucleo/project.ewp create mode 100644 bsp/stm32/stm32h563-st-nucleo/project.eww create mode 100644 bsp/stm32/stm32h563-st-nucleo/project.uvoptx create mode 100644 bsp/stm32/stm32h563-st-nucleo/project.uvprojx create mode 100644 bsp/stm32/stm32h563-st-nucleo/rtconfig.h create mode 100644 bsp/stm32/stm32h563-st-nucleo/rtconfig.py create mode 100644 bsp/stm32/stm32h563-st-nucleo/startup_stm32h563xx.lst create mode 100644 bsp/stm32/stm32h563-st-nucleo/syscall_rvds.lst create mode 100644 bsp/stm32/stm32h563-st-nucleo/template.ewp create mode 100644 bsp/stm32/stm32h563-st-nucleo/template.eww create mode 100644 bsp/stm32/stm32h563-st-nucleo/template.uvoptx create mode 100644 bsp/stm32/stm32h563-st-nucleo/template.uvprojx diff --git a/.github/workflows/action.yml b/.github/workflows/action.yml index e7e992d7e2..929a0cc632 100644 --- a/.github/workflows/action.yml +++ b/.github/workflows/action.yml @@ -135,7 +135,7 @@ jobs: - "stm32/stm32f429-st-disco" - "stm32/stm32f446-st-nucleo" - "stm32/stm32f469-st-disco" - - RTT_BSP: "stm32_f7_g0_h7_mp15_u5_wb5" + - RTT_BSP: "stm32_f7_g0_h7_mp15_u5_h5_wb5" RTT_TOOL_CHAIN: "sourcery-arm" SUB_RTT_BSP: - "stm32/stm32f746-st-disco" @@ -149,6 +149,7 @@ jobs: - "stm32/stm32g071-st-nucleo" - "stm32/stm32g431-st-nucleo" - "stm32/stm32g474-st-nucleo" + - "stm32/stm32h563-st-nucleo" - "stm32/stm32h743-armfly-v7" - "stm32/stm32h743-atk-apollo" - "stm32/stm32h743-openmv-h7plus" diff --git a/bsp/stm32/README.md b/bsp/stm32/README.md index fea072f5e8..e7c9d57f74 100644 --- a/bsp/stm32/README.md +++ b/bsp/stm32/README.md @@ -1,108 +1,109 @@ - # STM32 BSP 说明 STM32 系列 BSP 目前支持情况如下表所示: -| **BSP 文件夹名称** | **开发板名称** | -|:------------------------- |:-------------------------- | -| **F0 系列** | | -| [stm32f072-st-nucleo](stm32f072-st-nucleo) | ST 官方 STM32F072-nucleo 开发板 | -| [stm32f091-st-nucleo](stm32f091-st-nucleo) | ST 官方 STM32F091-nucleo 开发板 | -| **F1 系列** | | -| [stm32f103-100ask-mini](stm32f103-100ask-mini) | 百问网F103 Mini开发板 | -| [stm32f103-100ask-pro](stm32f103-100ask-pro) | 百问网F103 Pro开发板 | -| [stm32f103-atk-nano](stm32f103-atk-nano) | 正点原子 F103 NANO 开发板 | -| [stm32f103-atk-warshipv3](stm32f103-atk-warshipv3) | 正点原子 F103 战舰V3 开发板 | -| [stm32f103-blue-pill](stm32f103-blue-pill) | STM32F103C8T6蓝色最小系统板 | -| [stm32f103-dofly-lyc8](stm32f103-dofly-lyc8) | 德飞莱 STM32F103 开发板 | -| [stm32f103-dofly-M3S](stm32f103-dofly-M3S) | 德飞莱 STM32F103 开发板 | -| [stm32f103-fire-arbitrary](stm32f103-fire-arbitrary/) | 野火 F103 霸道开发板 | -| [stm32f103-gizwits-gokitv21](stm32f103-gizwits-gokitv21) | GoKit V2.1开发板 | -| [stm32f103-hw100k-ibox](stm32f103-hw100k-ibox) | 硬件十万个为什么 STM32F103 iBox 开发板 | -| [stm32f103-onenet-nbiot](stm32f103-onenet-nbiot) | STM32F103 OneNET NB-IoT 开发板 | -| [stm32f103-yf-ufun](stm32f103-yf-ufun) | STM32F103 yf-ufun 开发板 | -| [stm32f107-uc-eval](stm32f107-uc-eval) | uC/Eval STM32F107 评估板(中国版) | -| **F2 系列** | | -| [stm32f207-st-nucleo](stm32f207-st-nucleo) | ST 官方 STM32F207-nucleo 开发板 | -| **F3 系列** | | -| [stm32f302-st-nucleo](stm32f302-st-nucleo) | ST 官方 STM32F302-nucleo 开发板 | -| [stm32f334-st-nucleo](stm32f334-st-nucleo) | ST 官方 STM32F334-nucleo 开发板 | -| **F4 系列** | | -| [stm32f407-rt-spark](stm32f407-rt-spark) | 睿赛德官方 F407 星火一号开发板 | -| [stm32f401-st-nucleo](stm32f401-st-nucleo) | ST 官方 STM32F401 Nucleo-64 开发板 | -| [stm32f405-smdz-breadfruit](stm32f405-smdz-breadfruit) | 三木电子 SM1432F405 开发板 | -| [stm32f407-atk-explorer](stm32f407-atk-explorer) | 正点原子 F407 探索者开发板 | -| [stm32f407-robomaster-c](stm32f407-robomaster-c) | 大疆公司 RoboMaster C型开发板 | -| [stm32f407-st-discovery](stm32f407-st-discovery) | ST 官方 STM32F407-discovery 开发板 | -| [stm32f410-st-nucleo](stm32f410-st-nucleo) | ST 官方 STM32F410-Nucleo-64 开发板 | -| [stm32f411-atk-nano](stm32f411-atk-nano/) | 正点原子 F411 NANO 开发板 | -| [stm32f411-st-nucleo](stm32f411-st-nucleo/) | ST 官方 STM32F411-Nucleo-64 开发板 | -| [stm32f411-weact-MiniF4](stm32f411-weact-MiniF4/) | F401/F411最小系统开发板(Black Pill) | -| [stm32f412-st-nucleo](stm32f412-st-nucleo/) | ST 官方 STM32F412-Nucleo-144 开发板 | -| [stm32f413-st-nucleo](stm32f413-st-nucleo/) | ST 官方 STM32F413-Nucleo-144 开发板 | -| [stm32f427-robomaster-a](stm32f427-robomaster-a/) |大疆公司 RoboMaster A型开发板| -| [stm32f429-armfly-v6](stm32f429-armfly-v6) |安富莱 F429-v6 开发板| -| [stm32f429-atk-apollo](stm32f429-atk-apollo) |正点原子 F429 阿波罗开发板| -| [stm32f429-fire-challenger](stm32f429-fire-challenger/) |野火 F429 挑战者开发板| -| [stm32f429-st-disco](stm32f429-st-disco) | ST 官方 STM32F429-discovery 开发板 | -| [stm32f446-st-nucleo](stm32f446-st-nucleo) | ST 官方 STM32F446-nucleo 开发板 | -| [stm32f469-st-disco](stm32f469-st-disco) | ST 官方 STM32F469-discovery 开发板 | -| **F7 系列** | | -| [stm32f746-st-disco](stm32f746-st-disco) | ST 官方 STM32F746-discovery 开发板 | -| [stm32f767-atk-apollo](stm32f767-atk-apollo) | 正点原子 F767 阿波罗开发板 | -| [stm32f767-fire-challenger-v1](stm32f767-fire-challenger-v1/) | 野火 F767-V1 挑战者开发板 | -| [stm32f767-st-nucleo](stm32f767-st-nucleo) | ST 官方 STM32F767-nucleo 开发板 | -| [stm32f769-st-disco](stm32f769-st-disco) | ST 官方 STM32f769-discovery 开发板 | -| **G0 系列** | | -| [stm32g070-st-nucleo](stm32g070-st-nucleo) | ST 官方 STM32G070-nucleo 开发板 | -| [stm32g071-st-nucleo](stm32g071-st-nucleo) | ST 官方 STM32G071-nucleo 开发板 | -| **G4 系列** | | -| [stm32g431-st-nucleo](stm32g431-st-nucleo) | ST 官方 STM32G431-nucleo 开发板 | -| **H7 系列** | | -| [stm32h743-armfly-v7](stm32h743-armfly-v7) | 安富莱 STM32H743 v7 开发板 | -| [stm32h743-atk-apollo](stm32h743-atk-apollo) | 正点原子 h743 阿波罗开发板 | -| [stm32h743-openmv-h7plus](stm32h743-openmv-h7plus) | OPENMV 官方 H7-PLUS 开发板 | -| [stm32h743-st-nucleo](stm32h743-st-nucleo) | ST 官方 STM32H743-nucleo 开发板 | -| [stm32h747-st-discovery](stm32h747-st-discovery) | ST 官方 STM32H747I-discovery 开发板 | -| [stm32h750-armfly-h7-tool](stm32h750-armfly-h7-tool) | 安富莱 STM32H750 Tool 开发板 | -| [stm32h750-artpi](stm32h750-artpi) | RT-Thread 官方 STM32H750-artpi 开发板 | -| [stm32h750-fk750m1-vbt6](stm32h750-fk750m1-vbt6) | 反客科技 FK750M1-VBT6 开发板 | -| [stm32h750-weact-ministm32h7xx](stm32h750-weact-ministm32h7xx) | 微行电子 STM32H7xx 核心板 | -| **L0 系列** | | -| [stm32l010-st-nucleo](stm32l010-st-nucleo) | ST 官方 STM32L010-nucleo 开发板 | -| [stm32l053-st-nucleo](stm32l053-st-nucleo) | ST 官方 STM32L053-nucleo 开发板 | -| **L4 系列** | | -| [stm32l4r5-st-nucleo](stm32l4r5-st-nucleo) | ST 官方 STM32L4R5-Nucleo 开发板 | -| [stm32l4r9-st-eval](stm32l4r9-st-eval) | ST 官方 STM32L4R9I-EVAL 开发板 | -| [stm32l412-st-nucleo](stm32l412-st-nucleo) | ST 官方 STM32L412-Nucleo 开发板 | -| [stm32l431-BearPi](stm32l431-BearPi) | STM32L431 小熊派 开发板 | -| [stm32l432-st-nucleo](stm32l432-st-nucleo) | ST 官方 STM32L432-Nucleo 开发板 | -| [stm32l433-st-nucleo](stm32l433-st-nucleo) | ST 官方 STM32L433-Nucleo 开发板 | -| [stm32l452-st-nucleo](stm32l452-st-nucleo) | ST 官方 STM32L452-Nucleo 开发板 | -| [stm32l475-atk-pandora](stm32l475-atk-pandora) | 正点原子 L475 潘多拉 IoT 开发板 | -| [stm32l475-st-discovery](stm32l475-st-discovery) | ST 官方 stm32l475-discovery 开发板 | -| [stm32l476-st-nucleo](stm32l476-st-nucleo) | ST 官方 STM32L476-Nucleo 开发板 | -| [stm32l433-ali-startkit](stm32l433-ali-startkit) | 诺行 STM32L433 Ali Start Kit 开发板 | -| [stm32l496-ali-developer](stm32l496-ali-developer) | 诺行 STM32L496 Ali Developer Kit 开发板 | -| [stm32l496-st-nucleo](stm32l496-st-nucleo) | ST 官方 STM32L496-Nucleo 开发板 | -| [stm32l496-st-discovery](stm32l496-st-discovery) | ST 官方 STM32L496G discovery 开发板 | -| **L5 系列** | | -| [stm32l552-st-nucleo](stm32l552-st-nucleo) | ST 官方 STM32L552-Nucleo 开发板 | -| **U5 系列** | | -| [stm32u575-st-nucleo](stm32u575-st-nucleo) | ST 官方 STM32U575ZI-Nucleo 开发板 | -| **MP1 系列** | | -| [stm32mp157a-st-discovery](stm32mp157a-st-discovery) | ST 官方 STM32MP157A-DK1 开发板 | -| [stm32mp157a-st-ev1](stm32mp157a-st-ev1) | ST 官方 STM32MP157A-EV1 开发板 | -| **WB 系列** | | -| [stm32wb55-st-nucleo](stm32wb55-st-nucleo) | ST 官方 STM32WB55-Nucleo 开发板 | -| [stm32wl55-st-nucleo](stm32wl55-st-nucleo) | ST 官方 STM32WL55-Nucleo 开发板 | +| **BSP 文件夹名称** | **开发板名称** | +|:-------------------------------------------------------------- |:---------------------------------- | +| **F0 系列** | | +| [stm32f072-st-nucleo](stm32f072-st-nucleo) | ST 官方 STM32F072-nucleo 开发板 | +| [stm32f091-st-nucleo](stm32f091-st-nucleo) | ST 官方 STM32F091-nucleo 开发板 | +| **F1 系列** | | +| [stm32f103-100ask-mini](stm32f103-100ask-mini) | 百问网F103 Mini开发板 | +| [stm32f103-100ask-pro](stm32f103-100ask-pro) | 百问网F103 Pro开发板 | +| [stm32f103-atk-nano](stm32f103-atk-nano) | 正点原子 F103 NANO 开发板 | +| [stm32f103-atk-warshipv3](stm32f103-atk-warshipv3) | 正点原子 F103 战舰V3 开发板 | +| [stm32f103-blue-pill](stm32f103-blue-pill) | STM32F103C8T6蓝色最小系统板 | +| [stm32f103-dofly-lyc8](stm32f103-dofly-lyc8) | 德飞莱 STM32F103 开发板 | +| [stm32f103-dofly-M3S](stm32f103-dofly-M3S) | 德飞莱 STM32F103 开发板 | +| [stm32f103-fire-arbitrary](stm32f103-fire-arbitrary/) | 野火 F103 霸道开发板 | +| [stm32f103-gizwits-gokitv21](stm32f103-gizwits-gokitv21) | GoKit V2.1开发板 | +| [stm32f103-hw100k-ibox](stm32f103-hw100k-ibox) | 硬件十万个为什么 STM32F103 iBox 开发板 | +| [stm32f103-onenet-nbiot](stm32f103-onenet-nbiot) | STM32F103 OneNET NB-IoT 开发板 | +| [stm32f103-yf-ufun](stm32f103-yf-ufun) | STM32F103 yf-ufun 开发板 | +| [stm32f107-uc-eval](stm32f107-uc-eval) | uC/Eval STM32F107 评估板(中国版) | +| **F2 系列** | | +| [stm32f207-st-nucleo](stm32f207-st-nucleo) | ST 官方 STM32F207-nucleo 开发板 | +| **F3 系列** | | +| [stm32f302-st-nucleo](stm32f302-st-nucleo) | ST 官方 STM32F302-nucleo 开发板 | +| [stm32f334-st-nucleo](stm32f334-st-nucleo) | ST 官方 STM32F334-nucleo 开发板 | +| **F4 系列** | | +| [stm32f407-rt-spark](stm32f407-rt-spark) | 睿赛德官方 F407 星火一号开发板 | +| [stm32f401-st-nucleo](stm32f401-st-nucleo) | ST 官方 STM32F401 Nucleo-64 开发板 | +| [stm32f405-smdz-breadfruit](stm32f405-smdz-breadfruit) | 三木电子 SM1432F405 开发板 | +| [stm32f407-atk-explorer](stm32f407-atk-explorer) | 正点原子 F407 探索者开发板 | +| [stm32f407-robomaster-c](stm32f407-robomaster-c) | 大疆公司 RoboMaster C型开发板 | +| [stm32f407-st-discovery](stm32f407-st-discovery) | ST 官方 STM32F407-discovery 开发板 | +| [stm32f410-st-nucleo](stm32f410-st-nucleo) | ST 官方 STM32F410-Nucleo-64 开发板 | +| [stm32f411-atk-nano](stm32f411-atk-nano/) | 正点原子 F411 NANO 开发板 | +| [stm32f411-st-nucleo](stm32f411-st-nucleo/) | ST 官方 STM32F411-Nucleo-64 开发板 | +| [stm32f411-weact-MiniF4](stm32f411-weact-MiniF4/) | F401/F411最小系统开发板(Black Pill) | +| [stm32f412-st-nucleo](stm32f412-st-nucleo/) | ST 官方 STM32F412-Nucleo-144 开发板 | +| [stm32f413-st-nucleo](stm32f413-st-nucleo/) | ST 官方 STM32F413-Nucleo-144 开发板 | +| [stm32f427-robomaster-a](stm32f427-robomaster-a/) | 大疆公司 RoboMaster A型开发板 | +| [stm32f429-armfly-v6](stm32f429-armfly-v6) | 安富莱 F429-v6 开发板 | +| [stm32f429-atk-apollo](stm32f429-atk-apollo) | 正点原子 F429 阿波罗开发板 | +| [stm32f429-fire-challenger](stm32f429-fire-challenger/) | 野火 F429 挑战者开发板 | +| [stm32f429-st-disco](stm32f429-st-disco) | ST 官方 STM32F429-discovery 开发板 | +| [stm32f446-st-nucleo](stm32f446-st-nucleo) | ST 官方 STM32F446-nucleo 开发板 | +| [stm32f469-st-disco](stm32f469-st-disco) | ST 官方 STM32F469-discovery 开发板 | +| **F7 系列** | | +| [stm32f746-st-disco](stm32f746-st-disco) | ST 官方 STM32F746-discovery 开发板 | +| [stm32f767-atk-apollo](stm32f767-atk-apollo) | 正点原子 F767 阿波罗开发板 | +| [stm32f767-fire-challenger-v1](stm32f767-fire-challenger-v1/) | 野火 F767-V1 挑战者开发板 | +| [stm32f767-st-nucleo](stm32f767-st-nucleo) | ST 官方 STM32F767-nucleo 开发板 | +| [stm32f769-st-disco](stm32f769-st-disco) | ST 官方 STM32f769-discovery 开发板 | +| **G0 系列** | | +| [stm32g070-st-nucleo](stm32g070-st-nucleo) | ST 官方 STM32G070-nucleo 开发板 | +| [stm32g071-st-nucleo](stm32g071-st-nucleo) | ST 官方 STM32G071-nucleo 开发板 | +| **G4 系列** | | +| [stm32g431-st-nucleo](stm32g431-st-nucleo) | ST 官方 STM32G431-nucleo 开发板 | +| **H7 系列** | | +| [stm32h743-armfly-v7](stm32h743-armfly-v7) | 安富莱 STM32H743 v7 开发板 | +| [stm32h743-atk-apollo](stm32h743-atk-apollo) | 正点原子 h743 阿波罗开发板 | +| [stm32h743-openmv-h7plus](stm32h743-openmv-h7plus) | OPENMV 官方 H7-PLUS 开发板 | +| [stm32h743-st-nucleo](stm32h743-st-nucleo) | ST 官方 STM32H743-nucleo 开发板 | +| [stm32h747-st-discovery](stm32h747-st-discovery) | ST 官方 STM32H747I-discovery 开发板 | +| [stm32h750-armfly-h7-tool](stm32h750-armfly-h7-tool) | 安富莱 STM32H750 Tool 开发板 | +| [stm32h750-artpi](stm32h750-artpi) | RT-Thread 官方 STM32H750-artpi 开发板 | +| [stm32h750-fk750m1-vbt6](stm32h750-fk750m1-vbt6) | 反客科技 FK750M1-VBT6 开发板 | +| [stm32h750-weact-ministm32h7xx](stm32h750-weact-ministm32h7xx) | 微行电子 STM32H7xx 核心板 | +| **L0 系列** | | +| [stm32l010-st-nucleo](stm32l010-st-nucleo) | ST 官方 STM32L010-nucleo 开发板 | +| [stm32l053-st-nucleo](stm32l053-st-nucleo) | ST 官方 STM32L053-nucleo 开发板 | +| **L4 系列** | | +| [stm32l4r5-st-nucleo](stm32l4r5-st-nucleo) | ST 官方 STM32L4R5-Nucleo 开发板 | +| [stm32l4r9-st-eval](stm32l4r9-st-eval) | ST 官方 STM32L4R9I-EVAL 开发板 | +| [stm32l412-st-nucleo](stm32l412-st-nucleo) | ST 官方 STM32L412-Nucleo 开发板 | +| [stm32l431-BearPi](stm32l431-BearPi) | STM32L431 小熊派 开发板 | +| [stm32l432-st-nucleo](stm32l432-st-nucleo) | ST 官方 STM32L432-Nucleo 开发板 | +| [stm32l433-st-nucleo](stm32l433-st-nucleo) | ST 官方 STM32L433-Nucleo 开发板 | +| [stm32l452-st-nucleo](stm32l452-st-nucleo) | ST 官方 STM32L452-Nucleo 开发板 | +| [stm32l475-atk-pandora](stm32l475-atk-pandora) | 正点原子 L475 潘多拉 IoT 开发板 | +| [stm32l475-st-discovery](stm32l475-st-discovery) | ST 官方 stm32l475-discovery 开发板 | +| [stm32l476-st-nucleo](stm32l476-st-nucleo) | ST 官方 STM32L476-Nucleo 开发板 | +| [stm32l433-ali-startkit](stm32l433-ali-startkit) | 诺行 STM32L433 Ali Start Kit 开发板 | +| [stm32l496-ali-developer](stm32l496-ali-developer) | 诺行 STM32L496 Ali Developer Kit 开发板 | +| [stm32l496-st-nucleo](stm32l496-st-nucleo) | ST 官方 STM32L496-Nucleo 开发板 | +| [stm32l496-st-discovery](stm32l496-st-discovery) | ST 官方 STM32L496G discovery 开发板 | +| **L5 系列** | | +| [stm32l552-st-nucleo](stm32l552-st-nucleo) | ST 官方 STM32L552-Nucleo 开发板 | +| **U5 系列** | | +| [stm32u575-st-nucleo](stm32u575-st-nucleo) | ST 官方 STM32U575ZI-Nucleo 开发板 | +| **H5 系列** | | +| [stm32h563-st-nucleo](stm32h563-st-nucleo) | ST 官方 STM32H563ZI-Nucleo 开发板 | +| **MP1 系列** | | +| [stm32mp157a-st-discovery](stm32mp157a-st-discovery) | ST 官方 STM32MP157A-DK1 开发板 | +| [stm32mp157a-st-ev1](stm32mp157a-st-ev1) | ST 官方 STM32MP157A-EV1 开发板 | +| **WB 系列** | | +| [stm32wb55-st-nucleo](stm32wb55-st-nucleo) | ST 官方 STM32WB55-Nucleo 开发板 | +| [stm32wl55-st-nucleo](stm32wl55-st-nucleo) | ST 官方 STM32WL55-Nucleo 开发板 | 可以通过阅读相应 BSP 下的 README 来快速上手,如果想要使用 BSP 更多功能可参考 docs 文件夹下提供的说明文档,如下表所示: -| **BSP 使用教程** | **简介** | -|:-------------------- |:------------------------------------------------- | -| [外设驱动使用教程](docs/STM32系列BSP外设驱动使用教程.md) | 讲解 BSP 上更多外设驱动的使用方法 | -| [外设驱动介绍与应用](docs/STM32系列驱动介绍.md) | 讲解 STM32 系列 BSP 驱动的支持情况,以及如何利用驱动框架开发应用程序 | -| **BSP 制作与提交** | **简介** | -| [BSP 制作教程](docs/STM32系列BSP制作教程.md) | 讲解 STM32 系列 BSP 的制作方法,以及在制作 BSP 和提交 BSP 时应当遵守的规范,视频教程请观看 :[《RT-Thread STM32 系列 BSP 制作视频教程》](https://url.cn/5qqxJMU?sf=uri) | -| [外设驱动添加指南](docs/STM32系列外设驱动添加指南.md) | 讲解 BSP 添加更多设备驱动的方法 | +| **BSP 使用教程** | **简介** | +|:-------------------------------------- |:-------------------------------------------------------------------------------------------------------------------------- | +| [外设驱动使用教程](docs/STM32系列BSP外设驱动使用教程.md) | 讲解 BSP 上更多外设驱动的使用方法 | +| [外设驱动介绍与应用](docs/STM32系列驱动介绍.md) | 讲解 STM32 系列 BSP 驱动的支持情况,以及如何利用驱动框架开发应用程序 | +| **BSP 制作与提交** | **简介** | +| [BSP 制作教程](docs/STM32系列BSP制作教程.md) | 讲解 STM32 系列 BSP 的制作方法,以及在制作 BSP 和提交 BSP 时应当遵守的规范,视频教程请观看 :[《RT-Thread STM32 系列 BSP 制作视频教程》](https://url.cn/5qqxJMU?sf=uri) | +| [外设驱动添加指南](docs/STM32系列外设驱动添加指南.md) | 讲解 BSP 添加更多设备驱动的方法 | diff --git a/bsp/stm32/libraries/.ignore_format.yml b/bsp/stm32/libraries/.ignore_format.yml index 549353ca06..d048d41ed5 100644 --- a/bsp/stm32/libraries/.ignore_format.yml +++ b/bsp/stm32/libraries/.ignore_format.yml @@ -18,5 +18,6 @@ dir_path: - STM32L5xx_HAL - STM32MPxx_HAL - STM32U5xx_HAL +- STM32H5xx_HAL - STM32WBxx_HAL - STM32WLxx_HAL diff --git a/bsp/stm32/libraries/HAL_Drivers/config/h5/uart_config.h b/bsp/stm32/libraries/HAL_Drivers/config/h5/uart_config.h new file mode 100644 index 0000000000..a94bb9ea1c --- /dev/null +++ b/bsp/stm32/libraries/HAL_Drivers/config/h5/uart_config.h @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-11-06 SummerGift first version + */ + +#ifndef __UART_CONFIG_H__ +#define __UART_CONFIG_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(BSP_USING_LPUART1) +#ifndef LPUART1_CONFIG +#define LPUART1_CONFIG \ + { \ + .name = "lpuart1", \ + .Instance = LPUART1, \ + .irq_type = LPUART1_IRQn, \ + } +#endif /* LPUART1_CONFIG */ +#if defined(BSP_LPUART1_RX_USING_DMA) +#ifndef LPUART1_DMA_CONFIG +#define LPUART1_DMA_CONFIG \ + { \ + .Instance = LPUART1_RX_DMA_INSTANCE, \ + .request = LPUART1_RX_DMA_REQUEST, \ + .dma_rcc = LPUART1_RX_DMA_RCC, \ + .dma_irq = LPUART1_RX_DMA_IRQ, \ + } +#endif /* LPUART1_DMA_CONFIG */ +#endif /* BSP_LPUART1_RX_USING_DMA */ +#endif /* BSP_USING_LPUART1 */ + +#if defined(BSP_USING_UART1) +#ifndef UART1_CONFIG +#define UART1_CONFIG \ + { \ + .name = "uart1", \ + .Instance = USART1, \ + .irq_type = USART1_IRQn, \ + } +#endif /* UART1_CONFIG */ +#endif /* BSP_USING_UART1 */ + +#if defined(BSP_UART1_RX_USING_DMA) +#ifndef UART1_DMA_RX_CONFIG +#define UART1_DMA_RX_CONFIG \ + { \ + .Instance = UART1_RX_DMA_INSTANCE, \ + .request = UART1_RX_DMA_REQUEST, \ + .dma_rcc = UART1_RX_DMA_RCC, \ + .dma_irq = UART1_RX_DMA_IRQ, \ + } +#endif /* UART1_DMA_RX_CONFIG */ +#endif /* BSP_UART1_RX_USING_DMA */ + +#if defined(BSP_UART1_TX_USING_DMA) +#ifndef UART1_DMA_TX_CONFIG +#define UART1_DMA_TX_CONFIG \ + { \ + .Instance = UART1_TX_DMA_INSTANCE, \ + .request = UART1_TX_DMA_REQUEST, \ + .dma_rcc = UART1_TX_DMA_RCC, \ + .dma_irq = UART1_TX_DMA_IRQ, \ + } +#endif /* UART1_DMA_TX_CONFIG */ +#endif /* BSP_UART1_TX_USING_DMA */ + +#if defined(BSP_USING_UART2) +#ifndef UART2_CONFIG +#define UART2_CONFIG \ + { \ + .name = "uart2", \ + .Instance = USART2, \ + .irq_type = USART2_IRQn, \ + } +#endif /* UART2_CONFIG */ +#endif /* BSP_USING_UART2 */ + +#if defined(BSP_UART2_RX_USING_DMA) +#ifndef UART2_DMA_RX_CONFIG +#define UART2_DMA_RX_CONFIG \ + { \ + .Instance = UART2_RX_DMA_INSTANCE, \ + .request = UART2_RX_DMA_REQUEST, \ + .dma_rcc = UART2_RX_DMA_RCC, \ + .dma_irq = UART2_RX_DMA_IRQ, \ + } +#endif /* UART2_DMA_RX_CONFIG */ +#endif /* BSP_UART2_RX_USING_DMA */ + +#if defined(BSP_UART2_TX_USING_DMA) +#ifndef UART2_DMA_TX_CONFIG +#define UART2_DMA_TX_CONFIG \ + { \ + .Instance = UART2_TX_DMA_INSTANCE, \ + .request = UART2_TX_DMA_REQUEST, \ + .dma_rcc = UART2_TX_DMA_RCC, \ + .dma_irq = UART2_TX_DMA_IRQ, \ + } +#endif /* UART2_DMA_TX_CONFIG */ +#endif /* BSP_UART2_TX_USING_DMA */ + +#if defined(BSP_USING_UART3) +#ifndef UART3_CONFIG +#define UART3_CONFIG \ + { \ + .name = "uart3", \ + .Instance = USART3, \ + .irq_type = USART3_IRQn, \ + } +#endif /* UART3_CONFIG */ +#endif /* BSP_USING_UART3 */ + +#if defined(BSP_UART3_RX_USING_DMA) +#ifndef UART3_DMA_RX_CONFIG +#define UART3_DMA_RX_CONFIG \ + { \ + .Instance = UART3_RX_DMA_INSTANCE, \ + .request = UART3_RX_DMA_REQUEST, \ + .dma_rcc = UART3_RX_DMA_RCC, \ + .dma_irq = UART3_RX_DMA_IRQ, \ + } +#endif /* UART3_DMA_RX_CONFIG */ +#endif /* BSP_UART3_RX_USING_DMA */ + +#if defined(BSP_UART3_TX_USING_DMA) +#ifndef UART3_DMA_TX_CONFIG +#define UART3_DMA_TX_CONFIG \ + { \ + .Instance = UART3_TX_DMA_INSTANCE, \ + .request = UART3_TX_DMA_REQUEST, \ + .dma_rcc = UART3_TX_DMA_RCC, \ + .dma_irq = UART3_TX_DMA_IRQ, \ + } +#endif /* UART3_DMA_TX_CONFIG */ +#endif /* BSP_UART3_TX_USING_DMA */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_config.h b/bsp/stm32/libraries/HAL_Drivers/drv_config.h index e23f6699af..817dee0247 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_config.h +++ b/bsp/stm32/libraries/HAL_Drivers/drv_config.h @@ -135,6 +135,8 @@ extern "C" { #include "u5/sdio_config.h" #include "u5/pwm_config.h" #include "u5/usbd_config.h" +#elif defined(SOC_SERIES_STM32H5) +#include "h5/uart_config.h" #elif defined(SOC_SERIES_STM32MP1) #include "mp1/dma_config.h" #include "mp1/uart_config.h" diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_dma.h b/bsp/stm32/libraries/HAL_Drivers/drv_dma.h index 76d82cbc3e..6000a4119b 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_dma.h +++ b/bsp/stm32/libraries/HAL_Drivers/drv_dma.h @@ -22,7 +22,7 @@ extern "C" { #if defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32L5)\ || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) || defined(SOC_SERIES_STM32G0) \ || defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32WB)|| defined(SOC_SERIES_STM32F3) \ - || defined(SOC_SERIES_STM32U5) + || defined(SOC_SERIES_STM32U5) || defined(SOC_SERIES_STM32H5) #define DMA_INSTANCE_TYPE DMA_Channel_TypeDef #elif defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)\ || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32MP1) diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_gpio.c b/bsp/stm32/libraries/HAL_Drivers/drv_gpio.c index d58b9c9557..f55162b400 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_gpio.c +++ b/bsp/stm32/libraries/HAL_Drivers/drv_gpio.c @@ -17,14 +17,14 @@ #ifdef BSP_USING_GPIO -#define PIN_NUM(port, no) (((((port) & 0xFu) << 4) | ((no) & 0xFu))) +#define PIN_NUM(port, no) (((((port)&0xFu) << 4) | ((no)&0xFu))) #define PIN_PORT(pin) ((uint8_t)(((pin) >> 4) & 0xFu)) -#define PIN_NO(pin) ((uint8_t)((pin) & 0xFu)) +#define PIN_NO(pin) ((uint8_t)((pin)&0xFu)) #if defined(SOC_SERIES_STM32MP1) #if defined(GPIOZ) #define gpioz_port_base (175) /* PIN_STPORT_MAX * 16 - 16 */ -#define PIN_STPORT(pin) ((pin > gpioz_port_base) ? ((GPIO_TypeDef *)(GPIOZ_BASE )) : ((GPIO_TypeDef *)(GPIOA_BASE + (0x1000u * PIN_PORT(pin))))) +#define PIN_STPORT(pin) ((pin > gpioz_port_base) ? ((GPIO_TypeDef *)(GPIOZ_BASE)) : ((GPIO_TypeDef *)(GPIOA_BASE + (0x1000u * PIN_PORT(pin))))) #else #define PIN_STPORT(pin) ((GPIO_TypeDef *)(GPIOA_BASE + (0x1000u * PIN_PORT(pin)))) #endif /* GPIOZ */ @@ -66,96 +66,96 @@ #define PIN_STPORT_MAX __STM32_PORT_MAX static const struct pin_irq_map pin_irq_map[] = -{ + { #if defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32G0) - {GPIO_PIN_0, EXTI0_1_IRQn}, - {GPIO_PIN_1, EXTI0_1_IRQn}, - {GPIO_PIN_2, EXTI2_3_IRQn}, - {GPIO_PIN_3, EXTI2_3_IRQn}, - {GPIO_PIN_4, EXTI4_15_IRQn}, - {GPIO_PIN_5, EXTI4_15_IRQn}, - {GPIO_PIN_6, EXTI4_15_IRQn}, - {GPIO_PIN_7, EXTI4_15_IRQn}, - {GPIO_PIN_8, EXTI4_15_IRQn}, - {GPIO_PIN_9, EXTI4_15_IRQn}, - {GPIO_PIN_10, EXTI4_15_IRQn}, - {GPIO_PIN_11, EXTI4_15_IRQn}, - {GPIO_PIN_12, EXTI4_15_IRQn}, - {GPIO_PIN_13, EXTI4_15_IRQn}, - {GPIO_PIN_14, EXTI4_15_IRQn}, - {GPIO_PIN_15, EXTI4_15_IRQn}, -#elif defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32L5) || defined(SOC_SERIES_STM32U5) - {GPIO_PIN_0, EXTI0_IRQn}, - {GPIO_PIN_1, EXTI1_IRQn}, - {GPIO_PIN_2, EXTI2_IRQn}, - {GPIO_PIN_3, EXTI3_IRQn}, - {GPIO_PIN_4, EXTI4_IRQn}, - {GPIO_PIN_5, EXTI5_IRQn}, - {GPIO_PIN_6, EXTI6_IRQn}, - {GPIO_PIN_7, EXTI7_IRQn}, - {GPIO_PIN_8, EXTI8_IRQn}, - {GPIO_PIN_9, EXTI9_IRQn}, - {GPIO_PIN_10, EXTI10_IRQn}, - {GPIO_PIN_11, EXTI11_IRQn}, - {GPIO_PIN_12, EXTI12_IRQn}, - {GPIO_PIN_13, EXTI13_IRQn}, - {GPIO_PIN_14, EXTI14_IRQn}, - {GPIO_PIN_15, EXTI15_IRQn}, + {GPIO_PIN_0, EXTI0_1_IRQn}, + {GPIO_PIN_1, EXTI0_1_IRQn}, + {GPIO_PIN_2, EXTI2_3_IRQn}, + {GPIO_PIN_3, EXTI2_3_IRQn}, + {GPIO_PIN_4, EXTI4_15_IRQn}, + {GPIO_PIN_5, EXTI4_15_IRQn}, + {GPIO_PIN_6, EXTI4_15_IRQn}, + {GPIO_PIN_7, EXTI4_15_IRQn}, + {GPIO_PIN_8, EXTI4_15_IRQn}, + {GPIO_PIN_9, EXTI4_15_IRQn}, + {GPIO_PIN_10, EXTI4_15_IRQn}, + {GPIO_PIN_11, EXTI4_15_IRQn}, + {GPIO_PIN_12, EXTI4_15_IRQn}, + {GPIO_PIN_13, EXTI4_15_IRQn}, + {GPIO_PIN_14, EXTI4_15_IRQn}, + {GPIO_PIN_15, EXTI4_15_IRQn}, +#elif defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32L5) || defined(SOC_SERIES_STM32U5) || defined(SOC_SERIES_STM32H5) + {GPIO_PIN_0, EXTI0_IRQn}, + {GPIO_PIN_1, EXTI1_IRQn}, + {GPIO_PIN_2, EXTI2_IRQn}, + {GPIO_PIN_3, EXTI3_IRQn}, + {GPIO_PIN_4, EXTI4_IRQn}, + {GPIO_PIN_5, EXTI5_IRQn}, + {GPIO_PIN_6, EXTI6_IRQn}, + {GPIO_PIN_7, EXTI7_IRQn}, + {GPIO_PIN_8, EXTI8_IRQn}, + {GPIO_PIN_9, EXTI9_IRQn}, + {GPIO_PIN_10, EXTI10_IRQn}, + {GPIO_PIN_11, EXTI11_IRQn}, + {GPIO_PIN_12, EXTI12_IRQn}, + {GPIO_PIN_13, EXTI13_IRQn}, + {GPIO_PIN_14, EXTI14_IRQn}, + {GPIO_PIN_15, EXTI15_IRQn}, #elif defined(SOC_SERIES_STM32F3) - {GPIO_PIN_0, EXTI0_IRQn}, - {GPIO_PIN_1, EXTI1_IRQn}, - {GPIO_PIN_2, EXTI2_TSC_IRQn}, - {GPIO_PIN_3, EXTI3_IRQn}, - {GPIO_PIN_4, EXTI4_IRQn}, - {GPIO_PIN_5, EXTI9_5_IRQn}, - {GPIO_PIN_6, EXTI9_5_IRQn}, - {GPIO_PIN_7, EXTI9_5_IRQn}, - {GPIO_PIN_8, EXTI9_5_IRQn}, - {GPIO_PIN_9, EXTI9_5_IRQn}, - {GPIO_PIN_10, EXTI15_10_IRQn}, - {GPIO_PIN_11, EXTI15_10_IRQn}, - {GPIO_PIN_12, EXTI15_10_IRQn}, - {GPIO_PIN_13, EXTI15_10_IRQn}, - {GPIO_PIN_14, EXTI15_10_IRQn}, - {GPIO_PIN_15, EXTI15_10_IRQn}, + {GPIO_PIN_0, EXTI0_IRQn}, + {GPIO_PIN_1, EXTI1_IRQn}, + {GPIO_PIN_2, EXTI2_TSC_IRQn}, + {GPIO_PIN_3, EXTI3_IRQn}, + {GPIO_PIN_4, EXTI4_IRQn}, + {GPIO_PIN_5, EXTI9_5_IRQn}, + {GPIO_PIN_6, EXTI9_5_IRQn}, + {GPIO_PIN_7, EXTI9_5_IRQn}, + {GPIO_PIN_8, EXTI9_5_IRQn}, + {GPIO_PIN_9, EXTI9_5_IRQn}, + {GPIO_PIN_10, EXTI15_10_IRQn}, + {GPIO_PIN_11, EXTI15_10_IRQn}, + {GPIO_PIN_12, EXTI15_10_IRQn}, + {GPIO_PIN_13, EXTI15_10_IRQn}, + {GPIO_PIN_14, EXTI15_10_IRQn}, + {GPIO_PIN_15, EXTI15_10_IRQn}, #else - {GPIO_PIN_0, EXTI0_IRQn}, - {GPIO_PIN_1, EXTI1_IRQn}, - {GPIO_PIN_2, EXTI2_IRQn}, - {GPIO_PIN_3, EXTI3_IRQn}, - {GPIO_PIN_4, EXTI4_IRQn}, - {GPIO_PIN_5, EXTI9_5_IRQn}, - {GPIO_PIN_6, EXTI9_5_IRQn}, - {GPIO_PIN_7, EXTI9_5_IRQn}, - {GPIO_PIN_8, EXTI9_5_IRQn}, - {GPIO_PIN_9, EXTI9_5_IRQn}, - {GPIO_PIN_10, EXTI15_10_IRQn}, - {GPIO_PIN_11, EXTI15_10_IRQn}, - {GPIO_PIN_12, EXTI15_10_IRQn}, - {GPIO_PIN_13, EXTI15_10_IRQn}, - {GPIO_PIN_14, EXTI15_10_IRQn}, - {GPIO_PIN_15, EXTI15_10_IRQn}, + {GPIO_PIN_0, EXTI0_IRQn}, + {GPIO_PIN_1, EXTI1_IRQn}, + {GPIO_PIN_2, EXTI2_IRQn}, + {GPIO_PIN_3, EXTI3_IRQn}, + {GPIO_PIN_4, EXTI4_IRQn}, + {GPIO_PIN_5, EXTI9_5_IRQn}, + {GPIO_PIN_6, EXTI9_5_IRQn}, + {GPIO_PIN_7, EXTI9_5_IRQn}, + {GPIO_PIN_8, EXTI9_5_IRQn}, + {GPIO_PIN_9, EXTI9_5_IRQn}, + {GPIO_PIN_10, EXTI15_10_IRQn}, + {GPIO_PIN_11, EXTI15_10_IRQn}, + {GPIO_PIN_12, EXTI15_10_IRQn}, + {GPIO_PIN_13, EXTI15_10_IRQn}, + {GPIO_PIN_14, EXTI15_10_IRQn}, + {GPIO_PIN_15, EXTI15_10_IRQn}, #endif }; static struct rt_pin_irq_hdr pin_irq_hdr_tab[] = -{ - {-1, 0, RT_NULL, RT_NULL}, - {-1, 0, RT_NULL, RT_NULL}, - {-1, 0, RT_NULL, RT_NULL}, - {-1, 0, RT_NULL, RT_NULL}, - {-1, 0, RT_NULL, RT_NULL}, - {-1, 0, RT_NULL, RT_NULL}, - {-1, 0, RT_NULL, RT_NULL}, - {-1, 0, RT_NULL, RT_NULL}, - {-1, 0, RT_NULL, RT_NULL}, - {-1, 0, RT_NULL, RT_NULL}, - {-1, 0, RT_NULL, RT_NULL}, - {-1, 0, RT_NULL, RT_NULL}, - {-1, 0, RT_NULL, RT_NULL}, - {-1, 0, RT_NULL, RT_NULL}, - {-1, 0, RT_NULL, RT_NULL}, - {-1, 0, RT_NULL, RT_NULL}, + { + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, + {-1, 0, RT_NULL, RT_NULL}, }; static uint32_t pin_irq_enable_mask = 0; @@ -221,7 +221,7 @@ static rt_int8_t stm32_pin_read(rt_device_t dev, rt_base_t pin) { GPIO_TypeDef *gpio_port; uint16_t gpio_pin; - GPIO_PinState state; + GPIO_PinState state = PIN_LOW; if (PIN_PORT(pin) < PIN_STPORT_MAX) { @@ -306,7 +306,7 @@ rt_inline const struct pin_irq_map *get_pin_irq_map(uint32_t pinbit) }; static rt_err_t stm32_pin_attach_irq(struct rt_device *device, rt_base_t pin, - rt_uint8_t mode, void (*hdr)(void *args), void *args) + rt_uint8_t mode, void (*hdr)(void *args), void *args) { rt_base_t level; rt_int32_t irqindex = -1; @@ -377,7 +377,7 @@ static rt_err_t stm32_pin_dettach_irq(struct rt_device *device, rt_base_t pin) } static rt_err_t stm32_pin_irq_enable(struct rt_device *device, rt_base_t pin, - rt_uint8_t enabled) + rt_uint8_t enabled) { const struct pin_irq_map *irqmap; rt_base_t level; @@ -503,14 +503,14 @@ static rt_err_t stm32_pin_irq_enable(struct rt_device *device, rt_base_t pin, return RT_EOK; } static const struct rt_pin_ops _stm32_pin_ops = -{ - stm32_pin_mode, - stm32_pin_write, - stm32_pin_read, - stm32_pin_attach_irq, - stm32_pin_dettach_irq, - stm32_pin_irq_enable, - stm32_pin_get, + { + stm32_pin_mode, + stm32_pin_write, + stm32_pin_read, + stm32_pin_attach_irq, + stm32_pin_dettach_irq, + stm32_pin_irq_enable, + stm32_pin_get, }; rt_inline void pin_irq_hdr(int irqno) @@ -773,9 +773,9 @@ int rt_hw_pin_init(void) #endif #if defined(__HAL_RCC_GPIOG_CLK_ENABLE) - #ifdef SOC_SERIES_STM32L4 - HAL_PWREx_EnableVddIO2(); - #endif +#ifdef SOC_SERIES_STM32L4 + HAL_PWREx_EnableVddIO2(); +#endif __HAL_RCC_GPIOG_CLK_ENABLE(); #endif diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_usart.c b/bsp/stm32/libraries/HAL_Drivers/drv_usart.c index e666df3733..a5665ac830 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_usart.c +++ b/bsp/stm32/libraries/HAL_Drivers/drv_usart.c @@ -317,7 +317,7 @@ static int stm32_putc(struct rt_serial_device *serial, char c) #if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32F0) \ || defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32L5) \ || defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32F3) \ - || defined(SOC_SERIES_STM32U5) + || defined(SOC_SERIES_STM32U5) || defined(SOC_SERIES_STM32H5) uart->handle.Instance->TDR = c; #else uart->handle.Instance->DR = c; @@ -339,7 +339,7 @@ static int stm32_getc(struct rt_serial_device *serial) #if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32WL) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32F0) \ || defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32L5) \ || defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32WB)|| defined(SOC_SERIES_STM32F3) \ - || defined(SOC_SERIES_STM32U5) + || defined(SOC_SERIES_STM32U5) || defined(SOC_SERIES_STM32H5) ch = uart->handle.Instance->RDR & uart->DR_mask; #else ch = uart->handle.Instance->DR & uart->DR_mask; @@ -477,7 +477,7 @@ static void uart_isr(struct rt_serial_device *serial) #if !defined(SOC_SERIES_STM32L4) && !defined(SOC_SERIES_STM32WL) && !defined(SOC_SERIES_STM32F7) && !defined(SOC_SERIES_STM32F0) \ && !defined(SOC_SERIES_STM32L0) && !defined(SOC_SERIES_STM32G0) && !defined(SOC_SERIES_STM32H7) \ && !defined(SOC_SERIES_STM32G4) && !defined(SOC_SERIES_STM32MP1) && !defined(SOC_SERIES_STM32WB) \ - && !defined(SOC_SERIES_STM32L5) && !defined(SOC_SERIES_STM32U5) + && !defined(SOC_SERIES_STM32L5) && !defined(SOC_SERIES_STM32U5) && !defined(SOC_SERIES_STM32H5) #ifdef SOC_SERIES_STM32F3 if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_LBDF) != RESET) { @@ -1003,7 +1003,7 @@ static void stm32_dma_config(struct rt_serial_device *serial, rt_ubase_t flag) __HAL_LINKDMA(&(uart->handle), hdmatx, uart->dma_tx.handle); } -#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32L0)|| defined(SOC_SERIES_STM32F3) || defined(SOC_SERIES_STM32L1) || defined(SOC_SERIES_STM32U5) +#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32L0)|| defined(SOC_SERIES_STM32F3) || defined(SOC_SERIES_STM32L1) || defined(SOC_SERIES_STM32U5) || defined(SOC_SERIES_STM32H5) DMA_Handle->Instance = dma_config->Instance; #elif defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) DMA_Handle->Instance = dma_config->Instance; diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_usart.h b/bsp/stm32/libraries/HAL_Drivers/drv_usart.h index cc6aa66b8a..7f0b073155 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_usart.h +++ b/bsp/stm32/libraries/HAL_Drivers/drv_usart.h @@ -31,7 +31,8 @@ int rt_hw_usart_init(void); #if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32L5) || defined(SOC_SERIES_STM32WL) \ || defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32G0) \ - || defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32WB)|| defined(SOC_SERIES_STM32F3) || defined(SOC_SERIES_STM32U5) + || defined(SOC_SERIES_STM32G4) || defined(SOC_SERIES_STM32WB)|| defined(SOC_SERIES_STM32F3) || defined(SOC_SERIES_STM32U5) \ + || defined(SOC_SERIES_STM32H5) #define UART_INSTANCE_CLEAR_FUNCTION __HAL_UART_CLEAR_FLAG #elif defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) \ || defined(SOC_SERIES_STM32MP1) diff --git a/bsp/stm32/libraries/Kconfig b/bsp/stm32/libraries/Kconfig index 51533c978b..c59e94deb2 100644 --- a/bsp/stm32/libraries/Kconfig +++ b/bsp/stm32/libraries/Kconfig @@ -71,6 +71,11 @@ config SOC_SERIES_STM32U5 select ARCH_ARM_CORTEX_M33 select SOC_FAMILY_STM32 +config SOC_SERIES_STM32H5 + bool + select ARCH_ARM_CORTEX_M33 + select SOC_FAMILY_STM32 + config SOC_SERIES_STM32MP1 bool select ARCH_ARM_CORTEX_M4 diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/Templates/partition_stm32h562xx.h b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/Templates/partition_stm32h562xx.h new file mode 100644 index 0000000000..19b5afb4e1 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/Templates/partition_stm32h562xx.h @@ -0,0 +1,649 @@ +/** + ****************************************************************************** + * @file partition_stm32h562xx.h + * @author MCD Application Team + * @brief CMSIS STM32H562xx Device Header File for Initial Setup for Secure / + * Non-Secure Zones for ARMCM33 based on CMSIS CORE partition_ARMCM33.h + * Template. + * + * This file contains: + * - Initialize Security Attribution Unit (SAU) CTRL register + * - Setup behavior of Sleep and Exception Handling + * - Setup behavior of Floating Point Unit + * - Setup Interrupt Target + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +#ifndef PARTITION_STM32H562XX_H +#define PARTITION_STM32H562XX_H + +/* +//-------- <<< Use Configuration Wizard in Context Menu >>> ----------------- +*/ + +/* +// Initialize Security Attribution Unit (SAU) CTRL register +*/ +#define SAU_INIT_CTRL 1 + +/* +// Enable SAU +// Value for SAU->CTRL register bit ENABLE +*/ +#define SAU_INIT_CTRL_ENABLE 0 + +/* +// When SAU is disabled +// <0=> All Memory is Secure +// <1=> All Memory is Non-Secure +// Value for SAU->CTRL register bit ALLNS +// When all Memory is Non-Secure (ALLNS is 1), IDAU can override memory map configuration. +*/ +#define SAU_INIT_CTRL_ALLNS 1 + +/* +// +*/ + +/* +// Initialize Security Attribution Unit (SAU) Address Regions +// SAU configuration specifies regions to be one of: +// - Secure and Non-Secure Callable +// - Non-Secure +// Note: All memory regions not configured by SAU are Secure +*/ +#define SAU_REGIONS_MAX 8 /* Max. number of SAU regions */ + +/* +// Initialize SAU Region 0 +// Setup SAU Region 0 memory attributes +*/ +#define SAU_INIT_REGION0 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START0 0x0C0FE000 /* start address of SAU region 0 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END0 0x0C0FFFFF /* end address of SAU region 0 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC0 1 +/* +// +*/ + +/* +// Initialize SAU Region 1 +// Setup SAU Region 1 memory attributes +*/ +#define SAU_INIT_REGION1 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START1 0x08100000 /* start address of SAU region 1 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END1 0x081FFFFF /* end address of SAU region 1 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC1 0 +/* +// +*/ + +/* +// Initialize SAU Region 2 +// Setup SAU Region 2 memory attributes +*/ +#define SAU_INIT_REGION2 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START2 0x20050000 /* start address of SAU region 2 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END2 0x2009FFFF /* end address of SAU region 2 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC2 0 +/* +// +*/ + +/* +// Initialize SAU Region 3 +// Setup SAU Region 3 memory attributes +*/ +#define SAU_INIT_REGION3 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START3 0x40000000 /* start address of SAU region 3 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END3 0x4FFFFFFF /* end address of SAU region 3 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC3 0 +/* +// +*/ + +/* +// Initialize SAU Region 4 +// Setup SAU Region 4 memory attributes +*/ +#define SAU_INIT_REGION4 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START4 0x60000000 /* start address of SAU region 4 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END4 0x9FFFFFFF /* end address of SAU region 4 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC4 0 +/* +// +*/ + +/* +// Initialize SAU Region 5 +// Setup SAU Region 5 memory attributes +*/ +#define SAU_INIT_REGION5 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START5 0x0BF90000 /* start address of SAU region 5 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END5 0x0BFA8FFF /* end address of SAU region 5 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC5 0 +/* +// +*/ + +/* +// Initialize SAU Region 6 +// Setup SAU Region 6 memory attributes +*/ +#define SAU_INIT_REGION6 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START6 0x00000000 /* start address of SAU region 6 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END6 0x00000000 /* end address of SAU region 6 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC6 0 +/* +// +*/ + +/* +// Initialize SAU Region 7 +// Setup SAU Region 7 memory attributes +*/ +#define SAU_INIT_REGION7 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START7 0x00000000 /* start address of SAU region 7 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END7 0x00000000 /* end address of SAU region 7 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC7 0 +/* +// +*/ + +/* +// +*/ + +/* +// Setup behaviour of Sleep and Exception Handling +*/ +#define SCB_CSR_AIRCR_INIT 0 + +/* +// Deep Sleep can be enabled by +// <0=>Secure and Non-Secure state +// <1=>Secure state only +// Value for SCB->CSR register bit DEEPSLEEPS +*/ +#define SCB_CSR_DEEPSLEEPS_VAL 0 + +/* +// System reset request accessible from +// <0=> Secure and Non-Secure state +// <1=> Secure state only +// Value for SCB->AIRCR register bit SYSRESETREQS +*/ +#define SCB_AIRCR_SYSRESETREQS_VAL 0 + +/* +// Priority of Non-Secure exceptions is +// <0=> Not altered +// <1=> Lowered to 0x04-0x07 +// Value for SCB->AIRCR register bit PRIS +*/ +#define SCB_AIRCR_PRIS_VAL 0 + +/* +// BusFault, HardFault, and NMI target +// <0=> Secure state +// <1=> Non-Secure state +// Value for SCB->AIRCR register bit BFHFNMINS +*/ +#define SCB_AIRCR_BFHFNMINS_VAL 0 + +/* +// +*/ + +/* +// Setup behaviour of Floating Point Unit +*/ +#define TZ_FPU_NS_USAGE 1 + +/* +// Floating Point Unit usage +// <0=> Secure state only +// <3=> Secure and Non-Secure state +// Value for SCB->NSACR register bits CP10, CP11 +*/ +#define SCB_NSACR_CP10_11_VAL 3 + +/* +// Treat floating-point registers as Secure +// <0=> Disabled +// <1=> Enabled +// Value for FPU->FPCCR register bit TS +*/ +#define FPU_FPCCR_TS_VAL 0 + +/* +// Clear on return (CLRONRET) accessibility +// <0=> Secure and Non-Secure state +// <1=> Secure state only +// Value for FPU->FPCCR register bit CLRONRETS +*/ +#define FPU_FPCCR_CLRONRETS_VAL 0 + +/* +// Clear floating-point caller saved registers on exception return +// <0=> Disabled +// <1=> Enabled +// Value for FPU->FPCCR register bit CLRONRET +*/ +#define FPU_FPCCR_CLRONRET_VAL 1 + +/* +// +*/ + +/* +// Setup Interrupt Target +*/ + +/* +// Initialize ITNS 0 (Interrupts 0..31) +*/ +#define NVIC_INIT_ITNS0 1 + +/* +// Interrupts 0..31 +// WWDG_IRQn <0=> Secure state <1=> Non-Secure state +// PVD_AVD_IRQn <0=> Secure state <1=> Non-Secure state +// RTC_IRQn <0=> Secure state <1=> Non-Secure state +// RTC_S_IRQn <0=> Secure state <1=> Non-Secure state +// TAMP_IRQn <0=> Secure state <1=> Non-Secure state +// RAMCFG_IRQn <0=> Secure state <1=> Non-Secure state +// FLASH_IRQn <0=> Secure state <1=> Non-Secure state +// FLASH_S_IRQn <0=> Secure state <1=> Non-Secure state +// GTZC_IRQn <0=> Secure state <1=> Non-Secure state +// RCC_IRQn <0=> Secure state <1=> Non-Secure state +// RCC_S_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI0_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI1_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI2_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI3_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI4_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI5_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI6_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI7_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI8_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI9_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI10_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI11_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI12_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI13_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI14_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI15_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA1_Channel0_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA1_Channel1_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA1_Channel2_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA1_Channel3_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA1_Channel4_IRQn <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS0_VAL 0x00000000 + +/* +// +*/ + +/* +// Initialize ITNS 1 (Interrupts 32..63) +*/ +#define NVIC_INIT_ITNS1 1 + +/* +// Interrupts 32..63 +// GPDMA1_Channel5_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA1_Channel6_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA1_Channel7_IRQn <0=> Secure state <1=> Non-Secure state +// IWDG_IRQn <0=> Secure state <1=> Non-Secure state +// ADC1_IRQn <0=> Secure state <1=> Non-Secure state +// DAC1_IRQn <0=> Secure state <1=> Non-Secure state +// FDCAN1_IT0_IRQn <0=> Secure state <1=> Non-Secure state +// FDCAN1_IT1_IRQn <0=> Secure state <1=> Non-Secure state +// TIM1_BRK_IRQn <0=> Secure state <1=> Non-Secure state +// TIM1_UP_IRQn <0=> Secure state <1=> Non-Secure state +// TIM1_TRG_COM_IRQn <0=> Secure state <1=> Non-Secure state +// TIM1_CC_IRQn <0=> Secure state <1=> Non-Secure state +// TIM2_IRQn <0=> Secure state <1=> Non-Secure state +// TIM3_IRQn <0=> Secure state <1=> Non-Secure state +// TIM4_IRQn <0=> Secure state <1=> Non-Secure state +// TIM5_IRQn <0=> Secure state <1=> Non-Secure state +// TIM6_IRQn <0=> Secure state <1=> Non-Secure state +// TIM7_IRQn <0=> Secure state <1=> Non-Secure state +// I2C1_EV_IRQn <0=> Secure state <1=> Non-Secure state +// I2C1_ER_IRQn <0=> Secure state <1=> Non-Secure state +// I2C2_EV_IRQn <0=> Secure state <1=> Non-Secure state +// I2C2_ER_IRQn <0=> Secure state <1=> Non-Secure state +// SPI1_IRQn <0=> Secure state <1=> Non-Secure state +// SPI2_IRQn <0=> Secure state <1=> Non-Secure state +// SPI3_IRQn <0=> Secure state <1=> Non-Secure state +// USART1_IRQn <0=> Secure state <1=> Non-Secure state +// USART2_IRQn <0=> Secure state <1=> Non-Secure state +// USART3_IRQn <0=> Secure state <1=> Non-Secure state +// UART4_IRQn <0=> Secure state <1=> Non-Secure state +// UART5_IRQn <0=> Secure state <1=> Non-Secure state +// LPUART1_IRQn <0=> Secure state <1=> Non-Secure state +// LPTIM1_IRQn <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS1_VAL 0x00000000 + +/* +// +*/ + +/* +// Initialize ITNS 2 (Interrupts 64..95) +*/ +#define NVIC_INIT_ITNS2 1 + +/* +// Interrupts 64..95 +// TIM8_BRK_IRQn <0=> Secure state <1=> Non-Secure state +// TIM8_UP_IRQn <0=> Secure state <1=> Non-Secure state +// TIM8_TRG_COM_IRQn <0=> Secure state <1=> Non-Secure state +// TIM8_CC_IRQn <0=> Secure state <1=> Non-Secure state +// ADC2_IRQn <0=> Secure state <1=> Non-Secure state +// LPTIM2_IRQn <0=> Secure state <1=> Non-Secure state +// TIM15_IRQn <0=> Secure state <1=> Non-Secure state +// TIM16_IRQn <0=> Secure state <1=> Non-Secure state +// TIM17_IRQn <0=> Secure state <1=> Non-Secure state +// USB_DRD_FS_IRQn <0=> Secure state <1=> Non-Secure state +// CRS_IRQn <0=> Secure state <1=> Non-Secure state +// UCPD1_IRQn <0=> Secure state <1=> Non-Secure state +// FMC_IRQn <0=> Secure state <1=> Non-Secure state +// OCTOSPI1_IRQn <0=> Secure state <1=> Non-Secure state +// SDMMC1_IRQn <0=> Secure state <1=> Non-Secure state +// I2C3_EV_IRQn <0=> Secure state <1=> Non-Secure state +// I2C3_ER_IRQn <0=> Secure state <1=> Non-Secure state +// SPI4_IRQn <0=> Secure state <1=> Non-Secure state +// SPI5_IRQn <0=> Secure state <1=> Non-Secure state +// SPI6_IRQn <0=> Secure state <1=> Non-Secure state +// USART6_IRQn <0=> Secure state <1=> Non-Secure state +// USART10_IRQn <0=> Secure state <1=> Non-Secure state +// USART11_IRQn <0=> Secure state <1=> Non-Secure state +// SAI1_IRQn <0=> Secure state <1=> Non-Secure state +// SAI2_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA2_Channel0_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA2_Channel1_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA2_Channel2_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA2_Channel3_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA2_Channel4_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA2_Channel5_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA2_Channel6_IRQn <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS2_VAL 0x00000000 + +/* +// +*/ + +/* +// Initialize ITNS 3 (Interrupts 96..121) +*/ +#define NVIC_INIT_ITNS3 1 + +/* +// Interrupts 96..121 +// GPDMA2_Channel7_IRQn <0=> Secure state <1=> Non-Secure state +// UART7_IRQn <0=> Secure state <1=> Non-Secure state +// UART8_IRQn <0=> Secure state <1=> Non-Secure state +// UART9_IRQn <0=> Secure state <1=> Non-Secure state +// UART12_IRQn <0=> Secure state <1=> Non-Secure state +// FPU_IRQn <0=> Secure state <1=> Non-Secure state +// ICACHE_IRQn <0=> Secure state <1=> Non-Secure state +// DCACHE_IRQn <0=> Secure state <1=> Non-Secure state +// DCMI_PSSI_IRQn <0=> Secure state <1=> Non-Secure state +// CORDIC_IRQn <0=> Secure state <1=> Non-Secure state +// FMAC_IRQn <0=> Secure state <1=> Non-Secure state +// DTS_IRQn <0=> Secure state <1=> Non-Secure state +// RNG_IRQn <0=> Secure state <1=> Non-Secure state +// HASH_IRQn <0=> Secure state <1=> Non-Secure state +// CEC_IRQn <0=> Secure state <1=> Non-Secure state +// TIM12_IRQn <0=> Secure state <1=> Non-Secure state +// TIM13_IRQn <0=> Secure state <1=> Non-Secure state +// TIM14_IRQn <0=> Secure state <1=> Non-Secure state +// I3C1_EV_IRQn <0=> Secure state <1=> Non-Secure state +// I3C1_ER_IRQn <0=> Secure state <1=> Non-Secure state +// I2C4_EV_IRQn <0=> Secure state <1=> Non-Secure state +// I2C4_ER_IRQn <0=> Secure state <1=> Non-Secure state +// LPTIM3_IRQn <0=> Secure state <1=> Non-Secure state +// LPTIM4_IRQn <0=> Secure state <1=> Non-Secure state +// LPTIM5_IRQn <0=> Secure state <1=> Non-Secure state +// LPTIM6_IRQn <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS3_VAL 0x00000000 + +/* +// +*/ + +/* + max 8 SAU regions. + SAU regions are defined in partition.h + */ + +#define SAU_INIT_REGION(n) \ + SAU->RNR = (n & SAU_RNR_REGION_Msk); \ + SAU->RBAR = (SAU_INIT_START##n & SAU_RBAR_BADDR_Msk); \ + SAU->RLAR = (SAU_INIT_END##n & SAU_RLAR_LADDR_Msk) | \ + ((SAU_INIT_NSC##n << SAU_RLAR_NSC_Pos) & SAU_RLAR_NSC_Msk) | 1U + +/** + \brief Setup a SAU Region + \details Writes the region information contained in SAU_Region to the + registers SAU_RNR, SAU_RBAR, and SAU_RLAR + */ +__STATIC_INLINE void TZ_SAU_Setup (void) +{ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + + #if defined (SAU_INIT_REGION0) && (SAU_INIT_REGION0 == 1U) + SAU_INIT_REGION(0); + #endif + + #if defined (SAU_INIT_REGION1) && (SAU_INIT_REGION1 == 1U) + SAU_INIT_REGION(1); + #endif + + #if defined (SAU_INIT_REGION2) && (SAU_INIT_REGION2 == 1U) + SAU_INIT_REGION(2); + #endif + + #if defined (SAU_INIT_REGION3) && (SAU_INIT_REGION3 == 1U) + SAU_INIT_REGION(3); + #endif + + #if defined (SAU_INIT_REGION4) && (SAU_INIT_REGION4 == 1U) + SAU_INIT_REGION(4); + #endif + + #if defined (SAU_INIT_REGION5) && (SAU_INIT_REGION5 == 1U) + SAU_INIT_REGION(5); + #endif + + #if defined (SAU_INIT_REGION6) && (SAU_INIT_REGION6 == 1U) + SAU_INIT_REGION(6); + #endif + + #if defined (SAU_INIT_REGION7) && (SAU_INIT_REGION7 == 1U) + SAU_INIT_REGION(7); + #endif + + /* repeat this for all possible SAU regions */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + + + #if defined (SAU_INIT_CTRL) && (SAU_INIT_CTRL == 1U) + SAU->CTRL = ((SAU_INIT_CTRL_ENABLE << SAU_CTRL_ENABLE_Pos) & SAU_CTRL_ENABLE_Msk) | + ((SAU_INIT_CTRL_ALLNS << SAU_CTRL_ALLNS_Pos) & SAU_CTRL_ALLNS_Msk) ; + #endif + + #if defined (SCB_CSR_AIRCR_INIT) && (SCB_CSR_AIRCR_INIT == 1U) + SCB->SCR = (SCB->SCR & ~(SCB_SCR_SLEEPDEEPS_Msk )) | + ((SCB_CSR_DEEPSLEEPS_VAL << SCB_SCR_SLEEPDEEPS_Pos) & SCB_SCR_SLEEPDEEPS_Msk); + + SCB->AIRCR = (SCB->AIRCR & ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_SYSRESETREQS_Msk | + SCB_AIRCR_BFHFNMINS_Msk | SCB_AIRCR_PRIS_Msk) ) | + ((0x05FAU << SCB_AIRCR_VECTKEY_Pos) & SCB_AIRCR_VECTKEY_Msk) | + ((SCB_AIRCR_SYSRESETREQS_VAL << SCB_AIRCR_SYSRESETREQS_Pos) & SCB_AIRCR_SYSRESETREQS_Msk) | + ((SCB_AIRCR_PRIS_VAL << SCB_AIRCR_PRIS_Pos) & SCB_AIRCR_PRIS_Msk) | + ((SCB_AIRCR_BFHFNMINS_VAL << SCB_AIRCR_BFHFNMINS_Pos) & SCB_AIRCR_BFHFNMINS_Msk); + #endif /* defined (SCB_CSR_AIRCR_INIT) && (SCB_CSR_AIRCR_INIT == 1U) */ + + #if defined (__FPU_USED) && (__FPU_USED == 1U) && \ + defined (TZ_FPU_NS_USAGE) && (TZ_FPU_NS_USAGE == 1U) + + SCB->NSACR = (SCB->NSACR & ~(SCB_NSACR_CP10_Msk | SCB_NSACR_CP11_Msk)) | + ((SCB_NSACR_CP10_11_VAL << SCB_NSACR_CP10_Pos) & (SCB_NSACR_CP10_Msk | SCB_NSACR_CP11_Msk)); + + FPU->FPCCR = (FPU->FPCCR & ~(FPU_FPCCR_TS_Msk | FPU_FPCCR_CLRONRETS_Msk | FPU_FPCCR_CLRONRET_Msk)) | + ((FPU_FPCCR_TS_VAL << FPU_FPCCR_TS_Pos ) & FPU_FPCCR_TS_Msk ) | + ((FPU_FPCCR_CLRONRETS_VAL << FPU_FPCCR_CLRONRETS_Pos) & FPU_FPCCR_CLRONRETS_Msk) | + ((FPU_FPCCR_CLRONRET_VAL << FPU_FPCCR_CLRONRET_Pos ) & FPU_FPCCR_CLRONRET_Msk ); + #endif + + #if defined (NVIC_INIT_ITNS0) && (NVIC_INIT_ITNS0 == 1U) + NVIC->ITNS[0] = NVIC_INIT_ITNS0_VAL; + #endif + + #if defined (NVIC_INIT_ITNS1) && (NVIC_INIT_ITNS1 == 1U) + NVIC->ITNS[1] = NVIC_INIT_ITNS1_VAL; + #endif + + #if defined (NVIC_INIT_ITNS2) && (NVIC_INIT_ITNS2 == 1U) + NVIC->ITNS[2] = NVIC_INIT_ITNS2_VAL; + #endif + + #if defined (NVIC_INIT_ITNS3) && (NVIC_INIT_ITNS3 == 1U) + NVIC->ITNS[3] = NVIC_INIT_ITNS3_VAL; + #endif + +} + +#endif /* PARTITION_STM32H562XX_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/Templates/partition_stm32h563xx.h b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/Templates/partition_stm32h563xx.h new file mode 100644 index 0000000000..57377ec842 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/Templates/partition_stm32h563xx.h @@ -0,0 +1,654 @@ +/** + ****************************************************************************** + * @file partition_stm32h563xx.h + * @author MCD Application Team + * @brief CMSIS STM32H563xx Device Header File for Initial Setup for Secure / + * Non-Secure Zones for ARMCM33 based on CMSIS CORE partition_ARMCM33.h + * Template. + * + * This file contains: + * - Initialize Security Attribution Unit (SAU) CTRL register + * - Setup behavior of Sleep and Exception Handling + * - Setup behavior of Floating Point Unit + * - Setup Interrupt Target + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +#ifndef PARTITION_STM32H563XX_H +#define PARTITION_STM32H563XX_H + +/* +//-------- <<< Use Configuration Wizard in Context Menu >>> ----------------- +*/ + +/* +// Initialize Security Attribution Unit (SAU) CTRL register +*/ +#define SAU_INIT_CTRL 1 + +/* +// Enable SAU +// Value for SAU->CTRL register bit ENABLE +*/ +#define SAU_INIT_CTRL_ENABLE 0 + +/* +// When SAU is disabled +// <0=> All Memory is Secure +// <1=> All Memory is Non-Secure +// Value for SAU->CTRL register bit ALLNS +// When all Memory is Non-Secure (ALLNS is 1), IDAU can override memory map configuration. +*/ +#define SAU_INIT_CTRL_ALLNS 1 + +/* +// +*/ + +/* +// Initialize Security Attribution Unit (SAU) Address Regions +// SAU configuration specifies regions to be one of: +// - Secure and Non-Secure Callable +// - Non-Secure +// Note: All memory regions not configured by SAU are Secure +*/ +#define SAU_REGIONS_MAX 8 /* Max. number of SAU regions */ + +/* +// Initialize SAU Region 0 +// Setup SAU Region 0 memory attributes +*/ +#define SAU_INIT_REGION0 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START0 0x0C0FE000 /* start address of SAU region 0 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END0 0x0C0FFFFF /* end address of SAU region 0 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC0 1 +/* +// +*/ + +/* +// Initialize SAU Region 1 +// Setup SAU Region 1 memory attributes +*/ +#define SAU_INIT_REGION1 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START1 0x08100000 /* start address of SAU region 1 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END1 0x081FFFFF /* end address of SAU region 1 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC1 0 +/* +// +*/ + +/* +// Initialize SAU Region 2 +// Setup SAU Region 2 memory attributes +*/ +#define SAU_INIT_REGION2 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START2 0x20050000 /* start address of SAU region 2 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END2 0x2009FFFF /* end address of SAU region 2 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC2 0 +/* +// +*/ + +/* +// Initialize SAU Region 3 +// Setup SAU Region 3 memory attributes +*/ +#define SAU_INIT_REGION3 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START3 0x40000000 /* start address of SAU region 3 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END3 0x4FFFFFFF /* end address of SAU region 3 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC3 0 +/* +// +*/ + +/* +// Initialize SAU Region 4 +// Setup SAU Region 4 memory attributes +*/ +#define SAU_INIT_REGION4 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START4 0x60000000 /* start address of SAU region 4 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END4 0x9FFFFFFF /* end address of SAU region 4 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC4 0 +/* +// +*/ + +/* +// Initialize SAU Region 5 +// Setup SAU Region 5 memory attributes +*/ +#define SAU_INIT_REGION5 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START5 0x0BF90000 /* start address of SAU region 5 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END5 0x0BFA8FFF /* end address of SAU region 5 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC5 0 +/* +// +*/ + +/* +// Initialize SAU Region 6 +// Setup SAU Region 6 memory attributes +*/ +#define SAU_INIT_REGION6 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START6 0x00000000 /* start address of SAU region 6 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END6 0x00000000 /* end address of SAU region 6 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC6 0 +/* +// +*/ + +/* +// Initialize SAU Region 7 +// Setup SAU Region 7 memory attributes +*/ +#define SAU_INIT_REGION7 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START7 0x00000000 /* start address of SAU region 7 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END7 0x00000000 /* end address of SAU region 7 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC7 0 +/* +// +*/ + +/* +// +*/ + +/* +// Setup behaviour of Sleep and Exception Handling +*/ +#define SCB_CSR_AIRCR_INIT 0 + +/* +// Deep Sleep can be enabled by +// <0=>Secure and Non-Secure state +// <1=>Secure state only +// Value for SCB->CSR register bit DEEPSLEEPS +*/ +#define SCB_CSR_DEEPSLEEPS_VAL 0 + +/* +// System reset request accessible from +// <0=> Secure and Non-Secure state +// <1=> Secure state only +// Value for SCB->AIRCR register bit SYSRESETREQS +*/ +#define SCB_AIRCR_SYSRESETREQS_VAL 0 + +/* +// Priority of Non-Secure exceptions is +// <0=> Not altered +// <1=> Lowered to 0x04-0x07 +// Value for SCB->AIRCR register bit PRIS +*/ +#define SCB_AIRCR_PRIS_VAL 0 + +/* +// BusFault, HardFault, and NMI target +// <0=> Secure state +// <1=> Non-Secure state +// Value for SCB->AIRCR register bit BFHFNMINS +*/ +#define SCB_AIRCR_BFHFNMINS_VAL 0 + +/* +// +*/ + +/* +// Setup behaviour of Floating Point Unit +*/ +#define TZ_FPU_NS_USAGE 1 + +/* +// Floating Point Unit usage +// <0=> Secure state only +// <3=> Secure and Non-Secure state +// Value for SCB->NSACR register bits CP10, CP11 +*/ +#define SCB_NSACR_CP10_11_VAL 3 + +/* +// Treat floating-point registers as Secure +// <0=> Disabled +// <1=> Enabled +// Value for FPU->FPCCR register bit TS +*/ +#define FPU_FPCCR_TS_VAL 0 + +/* +// Clear on return (CLRONRET) accessibility +// <0=> Secure and Non-Secure state +// <1=> Secure state only +// Value for FPU->FPCCR register bit CLRONRETS +*/ +#define FPU_FPCCR_CLRONRETS_VAL 0 + +/* +// Clear floating-point caller saved registers on exception return +// <0=> Disabled +// <1=> Enabled +// Value for FPU->FPCCR register bit CLRONRET +*/ +#define FPU_FPCCR_CLRONRET_VAL 1 + +/* +// +*/ + +/* +// Setup Interrupt Target +*/ + +/* +// Initialize ITNS 0 (Interrupts 0..31) +*/ +#define NVIC_INIT_ITNS0 1 + +/* +// Interrupts 0..31 +// WWDG_IRQn <0=> Secure state <1=> Non-Secure state +// PVD_AVD_IRQn <0=> Secure state <1=> Non-Secure state +// RTC_IRQn <0=> Secure state <1=> Non-Secure state +// RTC_S_IRQn <0=> Secure state <1=> Non-Secure state +// TAMP_IRQn <0=> Secure state <1=> Non-Secure state +// RAMCFG_IRQn <0=> Secure state <1=> Non-Secure state +// FLASH_IRQn <0=> Secure state <1=> Non-Secure state +// FLASH_S_IRQn <0=> Secure state <1=> Non-Secure state +// GTZC_IRQn <0=> Secure state <1=> Non-Secure state +// RCC_IRQn <0=> Secure state <1=> Non-Secure state +// RCC_S_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI0_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI1_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI2_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI3_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI4_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI5_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI6_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI7_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI8_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI9_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI10_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI11_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI12_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI13_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI14_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI15_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA1_Channel0_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA1_Channel1_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA1_Channel2_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA1_Channel3_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA1_Channel4_IRQn <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS0_VAL 0x00000000 + +/* +// +*/ + +/* +// Initialize ITNS 1 (Interrupts 32..63) +*/ +#define NVIC_INIT_ITNS1 1 + +/* +// Interrupts 32..63 +// GPDMA1_Channel5_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA1_Channel6_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA1_Channel7_IRQn <0=> Secure state <1=> Non-Secure state +// IWDG_IRQn <0=> Secure state <1=> Non-Secure state +// ADC1_IRQn <0=> Secure state <1=> Non-Secure state +// DAC1_IRQn <0=> Secure state <1=> Non-Secure state +// FDCAN1_IT0_IRQn <0=> Secure state <1=> Non-Secure state +// FDCAN1_IT1_IRQn <0=> Secure state <1=> Non-Secure state +// TIM1_BRK_IRQn <0=> Secure state <1=> Non-Secure state +// TIM1_UP_IRQn <0=> Secure state <1=> Non-Secure state +// TIM1_TRG_COM_IRQn <0=> Secure state <1=> Non-Secure state +// TIM1_CC_IRQn <0=> Secure state <1=> Non-Secure state +// TIM2_IRQn <0=> Secure state <1=> Non-Secure state +// TIM3_IRQn <0=> Secure state <1=> Non-Secure state +// TIM4_IRQn <0=> Secure state <1=> Non-Secure state +// TIM5_IRQn <0=> Secure state <1=> Non-Secure state +// TIM6_IRQn <0=> Secure state <1=> Non-Secure state +// TIM7_IRQn <0=> Secure state <1=> Non-Secure state +// I2C1_EV_IRQn <0=> Secure state <1=> Non-Secure state +// I2C1_ER_IRQn <0=> Secure state <1=> Non-Secure state +// I2C2_EV_IRQn <0=> Secure state <1=> Non-Secure state +// I2C2_ER_IRQn <0=> Secure state <1=> Non-Secure state +// SPI1_IRQn <0=> Secure state <1=> Non-Secure state +// SPI2_IRQn <0=> Secure state <1=> Non-Secure state +// SPI3_IRQn <0=> Secure state <1=> Non-Secure state +// USART1_IRQn <0=> Secure state <1=> Non-Secure state +// USART2_IRQn <0=> Secure state <1=> Non-Secure state +// USART3_IRQn <0=> Secure state <1=> Non-Secure state +// UART4_IRQn <0=> Secure state <1=> Non-Secure state +// UART5_IRQn <0=> Secure state <1=> Non-Secure state +// LPUART1_IRQn <0=> Secure state <1=> Non-Secure state +// LPTIM1_IRQn <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS1_VAL 0x00000000 + +/* +// +*/ + +/* +// Initialize ITNS 2 (Interrupts 64..95) +*/ +#define NVIC_INIT_ITNS2 1 + +/* +// Interrupts 64..95 +// TIM8_BRK_IRQn <0=> Secure state <1=> Non-Secure state +// TIM8_UP_IRQn <0=> Secure state <1=> Non-Secure state +// TIM8_TRG_COM_IRQn <0=> Secure state <1=> Non-Secure state +// TIM8_CC_IRQn <0=> Secure state <1=> Non-Secure state +// ADC2_IRQn <0=> Secure state <1=> Non-Secure state +// LPTIM2_IRQn <0=> Secure state <1=> Non-Secure state +// TIM15_IRQn <0=> Secure state <1=> Non-Secure state +// TIM16_IRQn <0=> Secure state <1=> Non-Secure state +// TIM17_IRQn <0=> Secure state <1=> Non-Secure state +// USB_DRD_FS_IRQn <0=> Secure state <1=> Non-Secure state +// CRS_IRQn <0=> Secure state <1=> Non-Secure state +// UCPD1_IRQn <0=> Secure state <1=> Non-Secure state +// FMC_IRQn <0=> Secure state <1=> Non-Secure state +// OCTOSPI1_IRQn <0=> Secure state <1=> Non-Secure state +// SDMMC1_IRQn <0=> Secure state <1=> Non-Secure state +// I2C3_EV_IRQn <0=> Secure state <1=> Non-Secure state +// I2C3_ER_IRQn <0=> Secure state <1=> Non-Secure state +// SPI4_IRQn <0=> Secure state <1=> Non-Secure state +// SPI5_IRQn <0=> Secure state <1=> Non-Secure state +// SPI6_IRQn <0=> Secure state <1=> Non-Secure state +// USART6_IRQn <0=> Secure state <1=> Non-Secure state +// USART10_IRQn <0=> Secure state <1=> Non-Secure state +// USART11_IRQn <0=> Secure state <1=> Non-Secure state +// SAI1_IRQn <0=> Secure state <1=> Non-Secure state +// SAI2_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA2_Channel0_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA2_Channel1_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA2_Channel2_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA2_Channel3_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA2_Channel4_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA2_Channel5_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA2_Channel6_IRQn <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS2_VAL 0x00000000 + +/* +// +*/ + +/* +// Initialize ITNS 3 (Interrupts 96..126) +*/ +#define NVIC_INIT_ITNS3 1 + +/* +// Interrupts 96..126 +// GPDMA2_Channel7_IRQn <0=> Secure state <1=> Non-Secure state +// UART7_IRQn <0=> Secure state <1=> Non-Secure state +// UART8_IRQn <0=> Secure state <1=> Non-Secure state +// UART9_IRQn <0=> Secure state <1=> Non-Secure state +// UART12_IRQn <0=> Secure state <1=> Non-Secure state +// SDMMC2_IRQn <0=> Secure state <1=> Non-Secure state +// FPU_IRQn <0=> Secure state <1=> Non-Secure state +// ICACHE_IRQn <0=> Secure state <1=> Non-Secure state +// DCACHE_IRQn <0=> Secure state <1=> Non-Secure state +// ETH_IRQn <0=> Secure state <1=> Non-Secure state +// ETH_WKUP_IRQn <0=> Secure state <1=> Non-Secure state +// DCMI_PSSI_IRQn <0=> Secure state <1=> Non-Secure state +// FDCAN2_IT0_IRQn <0=> Secure state <1=> Non-Secure state +// FDCAN2_IT1_IRQn <0=> Secure state <1=> Non-Secure state +// CORDIC_IRQn <0=> Secure state <1=> Non-Secure state +// FMAC_IRQn <0=> Secure state <1=> Non-Secure state +// DTS_IRQn <0=> Secure state <1=> Non-Secure state +// RNG_IRQn <0=> Secure state <1=> Non-Secure state +// HASH_IRQn <0=> Secure state <1=> Non-Secure state +// CEC_IRQn <0=> Secure state <1=> Non-Secure state +// TIM12_IRQn <0=> Secure state <1=> Non-Secure state +// TIM13_IRQn <0=> Secure state <1=> Non-Secure state +// TIM14_IRQn <0=> Secure state <1=> Non-Secure state +// I3C1_EV_IRQn <0=> Secure state <1=> Non-Secure state +// I3C1_ER_IRQn <0=> Secure state <1=> Non-Secure state +// I2C4_EV_IRQn <0=> Secure state <1=> Non-Secure state +// I2C4_ER_IRQn <0=> Secure state <1=> Non-Secure state +// LPTIM3_IRQn <0=> Secure state <1=> Non-Secure state +// LPTIM4_IRQn <0=> Secure state <1=> Non-Secure state +// LPTIM5_IRQn <0=> Secure state <1=> Non-Secure state +// LPTIM6_IRQn <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS3_VAL 0x00000000 + +/* +// +*/ + +/* + max 8 SAU regions. + SAU regions are defined in partition.h + */ + +#define SAU_INIT_REGION(n) \ + SAU->RNR = (n & SAU_RNR_REGION_Msk); \ + SAU->RBAR = (SAU_INIT_START##n & SAU_RBAR_BADDR_Msk); \ + SAU->RLAR = (SAU_INIT_END##n & SAU_RLAR_LADDR_Msk) | \ + ((SAU_INIT_NSC##n << SAU_RLAR_NSC_Pos) & SAU_RLAR_NSC_Msk) | 1U + +/** + \brief Setup a SAU Region + \details Writes the region information contained in SAU_Region to the + registers SAU_RNR, SAU_RBAR, and SAU_RLAR + */ +__STATIC_INLINE void TZ_SAU_Setup (void) +{ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + + #if defined (SAU_INIT_REGION0) && (SAU_INIT_REGION0 == 1U) + SAU_INIT_REGION(0); + #endif + + #if defined (SAU_INIT_REGION1) && (SAU_INIT_REGION1 == 1U) + SAU_INIT_REGION(1); + #endif + + #if defined (SAU_INIT_REGION2) && (SAU_INIT_REGION2 == 1U) + SAU_INIT_REGION(2); + #endif + + #if defined (SAU_INIT_REGION3) && (SAU_INIT_REGION3 == 1U) + SAU_INIT_REGION(3); + #endif + + #if defined (SAU_INIT_REGION4) && (SAU_INIT_REGION4 == 1U) + SAU_INIT_REGION(4); + #endif + + #if defined (SAU_INIT_REGION5) && (SAU_INIT_REGION5 == 1U) + SAU_INIT_REGION(5); + #endif + + #if defined (SAU_INIT_REGION6) && (SAU_INIT_REGION6 == 1U) + SAU_INIT_REGION(6); + #endif + + #if defined (SAU_INIT_REGION7) && (SAU_INIT_REGION7 == 1U) + SAU_INIT_REGION(7); + #endif + + /* repeat this for all possible SAU regions */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + + + #if defined (SAU_INIT_CTRL) && (SAU_INIT_CTRL == 1U) + SAU->CTRL = ((SAU_INIT_CTRL_ENABLE << SAU_CTRL_ENABLE_Pos) & SAU_CTRL_ENABLE_Msk) | + ((SAU_INIT_CTRL_ALLNS << SAU_CTRL_ALLNS_Pos) & SAU_CTRL_ALLNS_Msk) ; + #endif + + #if defined (SCB_CSR_AIRCR_INIT) && (SCB_CSR_AIRCR_INIT == 1U) + SCB->SCR = (SCB->SCR & ~(SCB_SCR_SLEEPDEEPS_Msk )) | + ((SCB_CSR_DEEPSLEEPS_VAL << SCB_SCR_SLEEPDEEPS_Pos) & SCB_SCR_SLEEPDEEPS_Msk); + + SCB->AIRCR = (SCB->AIRCR & ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_SYSRESETREQS_Msk | + SCB_AIRCR_BFHFNMINS_Msk | SCB_AIRCR_PRIS_Msk) ) | + ((0x05FAU << SCB_AIRCR_VECTKEY_Pos) & SCB_AIRCR_VECTKEY_Msk) | + ((SCB_AIRCR_SYSRESETREQS_VAL << SCB_AIRCR_SYSRESETREQS_Pos) & SCB_AIRCR_SYSRESETREQS_Msk) | + ((SCB_AIRCR_PRIS_VAL << SCB_AIRCR_PRIS_Pos) & SCB_AIRCR_PRIS_Msk) | + ((SCB_AIRCR_BFHFNMINS_VAL << SCB_AIRCR_BFHFNMINS_Pos) & SCB_AIRCR_BFHFNMINS_Msk); + #endif /* defined (SCB_CSR_AIRCR_INIT) && (SCB_CSR_AIRCR_INIT == 1U) */ + + #if defined (__FPU_USED) && (__FPU_USED == 1U) && \ + defined (TZ_FPU_NS_USAGE) && (TZ_FPU_NS_USAGE == 1U) + + SCB->NSACR = (SCB->NSACR & ~(SCB_NSACR_CP10_Msk | SCB_NSACR_CP11_Msk)) | + ((SCB_NSACR_CP10_11_VAL << SCB_NSACR_CP10_Pos) & (SCB_NSACR_CP10_Msk | SCB_NSACR_CP11_Msk)); + + FPU->FPCCR = (FPU->FPCCR & ~(FPU_FPCCR_TS_Msk | FPU_FPCCR_CLRONRETS_Msk | FPU_FPCCR_CLRONRET_Msk)) | + ((FPU_FPCCR_TS_VAL << FPU_FPCCR_TS_Pos ) & FPU_FPCCR_TS_Msk ) | + ((FPU_FPCCR_CLRONRETS_VAL << FPU_FPCCR_CLRONRETS_Pos) & FPU_FPCCR_CLRONRETS_Msk) | + ((FPU_FPCCR_CLRONRET_VAL << FPU_FPCCR_CLRONRET_Pos ) & FPU_FPCCR_CLRONRET_Msk ); + #endif + + #if defined (NVIC_INIT_ITNS0) && (NVIC_INIT_ITNS0 == 1U) + NVIC->ITNS[0] = NVIC_INIT_ITNS0_VAL; + #endif + + #if defined (NVIC_INIT_ITNS1) && (NVIC_INIT_ITNS1 == 1U) + NVIC->ITNS[1] = NVIC_INIT_ITNS1_VAL; + #endif + + #if defined (NVIC_INIT_ITNS2) && (NVIC_INIT_ITNS2 == 1U) + NVIC->ITNS[2] = NVIC_INIT_ITNS2_VAL; + #endif + + #if defined (NVIC_INIT_ITNS3) && (NVIC_INIT_ITNS3 == 1U) + NVIC->ITNS[3] = NVIC_INIT_ITNS3_VAL; + #endif + +} + +#endif /* PARTITION_STM32H563XX_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/Templates/partition_stm32h573xx.h b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/Templates/partition_stm32h573xx.h new file mode 100644 index 0000000000..adadcc42a9 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/Templates/partition_stm32h573xx.h @@ -0,0 +1,680 @@ +/** + ****************************************************************************** + * @file partition_stm32h573xx.h + * @author MCD Application Team + * @brief CMSIS STM32H573xx Device Header File for Initial Setup for Secure / + * Non-Secure Zones for ARMCM33 based on CMSIS CORE partition_ARMCM33.h + * Template. + * + * This file contains: + * - Initialize Security Attribution Unit (SAU) CTRL register + * - Setup behavior of Sleep and Exception Handling + * - Setup behavior of Floating Point Unit + * - Setup Interrupt Target + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +#ifndef PARTITION_STM32H573XX_H +#define PARTITION_STM32H573XX_H + +/* +//-------- <<< Use Configuration Wizard in Context Menu >>> ----------------- +*/ + +/* +// Initialize Security Attribution Unit (SAU) CTRL register +*/ +#define SAU_INIT_CTRL 1 + +/* +// Enable SAU +// Value for SAU->CTRL register bit ENABLE +*/ +#define SAU_INIT_CTRL_ENABLE 0 + +/* +// When SAU is disabled +// <0=> All Memory is Secure +// <1=> All Memory is Non-Secure +// Value for SAU->CTRL register bit ALLNS +// When all Memory is Non-Secure (ALLNS is 1), IDAU can override memory map configuration. +*/ +#define SAU_INIT_CTRL_ALLNS 1 + +/* +// +*/ + +/* +// Initialize Security Attribution Unit (SAU) Address Regions +// SAU configuration specifies regions to be one of: +// - Secure and Non-Secure Callable +// - Non-Secure +// Note: All memory regions not configured by SAU are Secure +*/ +#define SAU_REGIONS_MAX 8 /* Max. number of SAU regions */ + +/* +// Initialize SAU Region 0 +// Setup SAU Region 0 memory attributes +*/ +#define SAU_INIT_REGION0 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START0 0x0C0FE000 /* start address of SAU region 0 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END0 0x0C0FFFFF /* end address of SAU region 0 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC0 1 +/* +// +*/ + +/* +// Initialize SAU Region 1 +// Setup SAU Region 1 memory attributes +*/ +#define SAU_INIT_REGION1 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START1 0x08100000 /* start address of SAU region 1 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END1 0x081FFFFF /* end address of SAU region 1 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC1 0 +/* +// +*/ + +/* +// Initialize SAU Region 2 +// Setup SAU Region 2 memory attributes +*/ +#define SAU_INIT_REGION2 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START2 0x20050000 /* start address of SAU region 2 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END2 0x2009FFFF /* end address of SAU region 2 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC2 0 +/* +// +*/ + +/* +// Initialize SAU Region 3 +// Setup SAU Region 3 memory attributes +*/ +#define SAU_INIT_REGION3 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START3 0x40000000 /* start address of SAU region 3 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END3 0x4FFFFFFF /* end address of SAU region 3 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC3 0 +/* +// +*/ + +/* +// Initialize SAU Region 4 +// Setup SAU Region 4 memory attributes +*/ +#define SAU_INIT_REGION4 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START4 0x60000000 /* start address of SAU region 4 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END4 0x9FFFFFFF /* end address of SAU region 4 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC4 0 +/* +// +*/ + +/* +// Initialize SAU Region 5 +// Setup SAU Region 5 memory attributes +*/ +#define SAU_INIT_REGION5 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START5 0x0BF90000 /* start address of SAU region 5 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END5 0x0BFA8FFF /* end address of SAU region 5 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC5 0 +/* +// +*/ + +/* +// Initialize SAU Region 6 +// Setup SAU Region 6 memory attributes +*/ +#define SAU_INIT_REGION6 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START6 0x00000000 /* start address of SAU region 6 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END6 0x00000000 /* end address of SAU region 6 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC6 0 +/* +// +*/ + +/* +// Initialize SAU Region 7 +// Setup SAU Region 7 memory attributes +*/ +#define SAU_INIT_REGION7 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START7 0x00000000 /* start address of SAU region 7 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END7 0x00000000 /* end address of SAU region 7 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC7 0 +/* +// +*/ + +/* +// +*/ + +/* +// Setup behaviour of Sleep and Exception Handling +*/ +#define SCB_CSR_AIRCR_INIT 0 + +/* +// Deep Sleep can be enabled by +// <0=>Secure and Non-Secure state +// <1=>Secure state only +// Value for SCB->CSR register bit DEEPSLEEPS +*/ +#define SCB_CSR_DEEPSLEEPS_VAL 0 + +/* +// System reset request accessible from +// <0=> Secure and Non-Secure state +// <1=> Secure state only +// Value for SCB->AIRCR register bit SYSRESETREQS +*/ +#define SCB_AIRCR_SYSRESETREQS_VAL 0 + +/* +// Priority of Non-Secure exceptions is +// <0=> Not altered +// <1=> Lowered to 0x04-0x07 +// Value for SCB->AIRCR register bit PRIS +*/ +#define SCB_AIRCR_PRIS_VAL 0 + +/* +// BusFault, HardFault, and NMI target +// <0=> Secure state +// <1=> Non-Secure state +// Value for SCB->AIRCR register bit BFHFNMINS +*/ +#define SCB_AIRCR_BFHFNMINS_VAL 0 + +/* +// +*/ + +/* +// Setup behaviour of Floating Point Unit +*/ +#define TZ_FPU_NS_USAGE 1 + +/* +// Floating Point Unit usage +// <0=> Secure state only +// <3=> Secure and Non-Secure state +// Value for SCB->NSACR register bits CP10, CP11 +*/ +#define SCB_NSACR_CP10_11_VAL 3 + +/* +// Treat floating-point registers as Secure +// <0=> Disabled +// <1=> Enabled +// Value for FPU->FPCCR register bit TS +*/ +#define FPU_FPCCR_TS_VAL 0 + +/* +// Clear on return (CLRONRET) accessibility +// <0=> Secure and Non-Secure state +// <1=> Secure state only +// Value for FPU->FPCCR register bit CLRONRETS +*/ +#define FPU_FPCCR_CLRONRETS_VAL 0 + +/* +// Clear floating-point caller saved registers on exception return +// <0=> Disabled +// <1=> Enabled +// Value for FPU->FPCCR register bit CLRONRET +*/ +#define FPU_FPCCR_CLRONRET_VAL 1 + +/* +// +*/ + +/* +// Setup Interrupt Target +*/ + +/* +// Initialize ITNS 0 (Interrupts 0..31) +*/ +#define NVIC_INIT_ITNS0 1 + +/* +// Interrupts 0..31 +// WWDG_IRQn <0=> Secure state <1=> Non-Secure state +// PVD_AVD_IRQn <0=> Secure state <1=> Non-Secure state +// RTC_IRQn <0=> Secure state <1=> Non-Secure state +// RTC_S_IRQn <0=> Secure state <1=> Non-Secure state +// TAMP_IRQn <0=> Secure state <1=> Non-Secure state +// RAMCFG_IRQn <0=> Secure state <1=> Non-Secure state +// FLASH_IRQn <0=> Secure state <1=> Non-Secure state +// FLASH_S_IRQn <0=> Secure state <1=> Non-Secure state +// GTZC_IRQn <0=> Secure state <1=> Non-Secure state +// RCC_IRQn <0=> Secure state <1=> Non-Secure state +// RCC_S_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI0_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI1_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI2_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI3_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI4_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI5_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI6_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI7_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI8_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI9_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI10_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI11_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI12_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI13_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI14_IRQn <0=> Secure state <1=> Non-Secure state +// EXTI15_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA1_Channel0_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA1_Channel1_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA1_Channel2_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA1_Channel3_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA1_Channel4_IRQn <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS0_VAL 0x00000000 + +/* +// +*/ + +/* +// Initialize ITNS 1 (Interrupts 32..63) +*/ +#define NVIC_INIT_ITNS1 1 + +/* +// Interrupts 32..63 +// GPDMA1_Channel5_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA1_Channel6_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA1_Channel7_IRQn <0=> Secure state <1=> Non-Secure state +// IWDG_IRQn <0=> Secure state <1=> Non-Secure state +// SAES_IRQn <0=> Secure state <1=> Non-Secure state +// ADC1_IRQn <0=> Secure state <1=> Non-Secure state +// DAC1_IRQn <0=> Secure state <1=> Non-Secure state +// FDCAN1_IT0_IRQn <0=> Secure state <1=> Non-Secure state +// FDCAN1_IT1_IRQn <0=> Secure state <1=> Non-Secure state +// TIM1_BRK_IRQn <0=> Secure state <1=> Non-Secure state +// TIM1_UP_IRQn <0=> Secure state <1=> Non-Secure state +// TIM1_TRG_COM_IRQn <0=> Secure state <1=> Non-Secure state +// TIM1_CC_IRQn <0=> Secure state <1=> Non-Secure state +// TIM2_IRQn <0=> Secure state <1=> Non-Secure state +// TIM3_IRQn <0=> Secure state <1=> Non-Secure state +// TIM4_IRQn <0=> Secure state <1=> Non-Secure state +// TIM5_IRQn <0=> Secure state <1=> Non-Secure state +// TIM6_IRQn <0=> Secure state <1=> Non-Secure state +// TIM7_IRQn <0=> Secure state <1=> Non-Secure state +// I2C1_EV_IRQn <0=> Secure state <1=> Non-Secure state +// I2C1_ER_IRQn <0=> Secure state <1=> Non-Secure state +// I2C2_EV_IRQn <0=> Secure state <1=> Non-Secure state +// I2C2_ER_IRQn <0=> Secure state <1=> Non-Secure state +// SPI1_IRQn <0=> Secure state <1=> Non-Secure state +// SPI2_IRQn <0=> Secure state <1=> Non-Secure state +// SPI3_IRQn <0=> Secure state <1=> Non-Secure state +// USART1_IRQn <0=> Secure state <1=> Non-Secure state +// USART2_IRQn <0=> Secure state <1=> Non-Secure state +// USART3_IRQn <0=> Secure state <1=> Non-Secure state +// UART4_IRQn <0=> Secure state <1=> Non-Secure state +// UART5_IRQn <0=> Secure state <1=> Non-Secure state +// LPUART1_IRQn <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS1_VAL 0x00000000 + +/* +// +*/ + +/* +// Initialize ITNS 2 (Interrupts 64..95) +*/ +#define NVIC_INIT_ITNS2 1 + +/* +// Interrupts 64..95 +// LPTIM1_IRQn <0=> Secure state <1=> Non-Secure state +// TIM8_BRK_IRQn <0=> Secure state <1=> Non-Secure state +// TIM8_UP_IRQn <0=> Secure state <1=> Non-Secure state +// TIM8_TRG_COM_IRQn <0=> Secure state <1=> Non-Secure state +// TIM8_CC_IRQn <0=> Secure state <1=> Non-Secure state +// ADC2_IRQn <0=> Secure state <1=> Non-Secure state +// LPTIM2_IRQn <0=> Secure state <1=> Non-Secure state +// TIM15_IRQn <0=> Secure state <1=> Non-Secure state +// TIM16_IRQn <0=> Secure state <1=> Non-Secure state +// TIM17_IRQn <0=> Secure state <1=> Non-Secure state +// USB_DRD_FS_IRQn <0=> Secure state <1=> Non-Secure state +// CRS_IRQn <0=> Secure state <1=> Non-Secure state +// UCPD1_IRQn <0=> Secure state <1=> Non-Secure state +// FMC_IRQn <0=> Secure state <1=> Non-Secure state +// OCTOSPI1_IRQn <0=> Secure state <1=> Non-Secure state +// SDMMC1_IRQn <0=> Secure state <1=> Non-Secure state +// I2C3_EV_IRQn <0=> Secure state <1=> Non-Secure state +// I2C3_ER_IRQn <0=> Secure state <1=> Non-Secure state +// SPI4_IRQn <0=> Secure state <1=> Non-Secure state +// SPI5_IRQn <0=> Secure state <1=> Non-Secure state +// SPI6_IRQn <0=> Secure state <1=> Non-Secure state +// USART6_IRQn <0=> Secure state <1=> Non-Secure state +// USART10_IRQn <0=> Secure state <1=> Non-Secure state +// USART11_IRQn <0=> Secure state <1=> Non-Secure state +// SAI1_IRQn <0=> Secure state <1=> Non-Secure state +// SAI2_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA2_Channel0_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA2_Channel1_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA2_Channel2_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA2_Channel3_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA2_Channel4_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA2_Channel5_IRQn <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS2_VAL 0x00000000 + +/* +// +*/ + +/* +// Initialize ITNS 3 (Interrupts 96..127) +*/ +#define NVIC_INIT_ITNS3 1 + +/* +// Interrupts 96..127 +// GPDMA2_Channel6_IRQn <0=> Secure state <1=> Non-Secure state +// GPDMA2_Channel7_IRQn <0=> Secure state <1=> Non-Secure state +// UART7_IRQn <0=> Secure state <1=> Non-Secure state +// UART8_IRQn <0=> Secure state <1=> Non-Secure state +// UART9_IRQn <0=> Secure state <1=> Non-Secure state +// UART12_IRQn <0=> Secure state <1=> Non-Secure state +// SDMMC2_IRQn <0=> Secure state <1=> Non-Secure state +// FPU_IRQn <0=> Secure state <1=> Non-Secure state +// ICACHE_IRQn <0=> Secure state <1=> Non-Secure state +// DCACHE_IRQn <0=> Secure state <1=> Non-Secure state +// ETH_IRQn <0=> Secure state <1=> Non-Secure state +// ETH_WKUP_IRQn <0=> Secure state <1=> Non-Secure state +// DCMI_PSSI_IRQn <0=> Secure state <1=> Non-Secure state +// FDCAN2_IT0_IRQn <0=> Secure state <1=> Non-Secure state +// FDCAN2_IT1_IRQn <0=> Secure state <1=> Non-Secure state +// CORDIC_IRQn <0=> Secure state <1=> Non-Secure state +// FMAC_IRQn <0=> Secure state <1=> Non-Secure state +// DTS_IRQn <0=> Secure state <1=> Non-Secure state +// RNG_IRQn <0=> Secure state <1=> Non-Secure state +// OTFDEC1_IRQn <0=> Secure state <1=> Non-Secure state +// AES_IRQn <0=> Secure state <1=> Non-Secure state +// HASH_IRQn <0=> Secure state <1=> Non-Secure state +// PKA_IRQn <0=> Secure state <1=> Non-Secure state +// CEC_IRQn <0=> Secure state <1=> Non-Secure state +// TIM12_IRQn <0=> Secure state <1=> Non-Secure state +// TIM13_IRQn <0=> Secure state <1=> Non-Secure state +// TIM14_IRQn <0=> Secure state <1=> Non-Secure state +// I3C1_EV_IRQn <0=> Secure state <1=> Non-Secure state +// I3C1_ER_IRQn <0=> Secure state <1=> Non-Secure state +// I2C4_EV_IRQn <0=> Secure state <1=> Non-Secure state +// I2C4_ER_IRQn <0=> Secure state <1=> Non-Secure state +// LPTIM3_IRQn <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS3_VAL 0x00000000 + +/* +// +*/ + +/* +// Initialize ITNS 4 (Interrupts 128..130) +*/ +#define NVIC_INIT_ITNS4 1 + +/* +// Interrupts 128..130 +// LPTIM4_IRQn <0=> Secure state <1=> Non-Secure state +// LPTIM5_IRQn <0=> Secure state <1=> Non-Secure state +// LPTIM6_IRQn <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS4_VAL 0x00000000 + +/* +// +*/ + +/* +// +*/ + +/* + max 8 SAU regions. + SAU regions are defined in partition.h + */ + +#define SAU_INIT_REGION(n) \ + SAU->RNR = (n & SAU_RNR_REGION_Msk); \ + SAU->RBAR = (SAU_INIT_START##n & SAU_RBAR_BADDR_Msk); \ + SAU->RLAR = (SAU_INIT_END##n & SAU_RLAR_LADDR_Msk) | \ + ((SAU_INIT_NSC##n << SAU_RLAR_NSC_Pos) & SAU_RLAR_NSC_Msk) | 1U + +/** + \brief Setup a SAU Region + \details Writes the region information contained in SAU_Region to the + registers SAU_RNR, SAU_RBAR, and SAU_RLAR + */ +__STATIC_INLINE void TZ_SAU_Setup (void) +{ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + + #if defined (SAU_INIT_REGION0) && (SAU_INIT_REGION0 == 1U) + SAU_INIT_REGION(0); + #endif + + #if defined (SAU_INIT_REGION1) && (SAU_INIT_REGION1 == 1U) + SAU_INIT_REGION(1); + #endif + + #if defined (SAU_INIT_REGION2) && (SAU_INIT_REGION2 == 1U) + SAU_INIT_REGION(2); + #endif + + #if defined (SAU_INIT_REGION3) && (SAU_INIT_REGION3 == 1U) + SAU_INIT_REGION(3); + #endif + + #if defined (SAU_INIT_REGION4) && (SAU_INIT_REGION4 == 1U) + SAU_INIT_REGION(4); + #endif + + #if defined (SAU_INIT_REGION5) && (SAU_INIT_REGION5 == 1U) + SAU_INIT_REGION(5); + #endif + + #if defined (SAU_INIT_REGION6) && (SAU_INIT_REGION6 == 1U) + SAU_INIT_REGION(6); + #endif + + #if defined (SAU_INIT_REGION7) && (SAU_INIT_REGION7 == 1U) + SAU_INIT_REGION(7); + #endif + + /* repeat this for all possible SAU regions */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + + + #if defined (SAU_INIT_CTRL) && (SAU_INIT_CTRL == 1U) + SAU->CTRL = ((SAU_INIT_CTRL_ENABLE << SAU_CTRL_ENABLE_Pos) & SAU_CTRL_ENABLE_Msk) | + ((SAU_INIT_CTRL_ALLNS << SAU_CTRL_ALLNS_Pos) & SAU_CTRL_ALLNS_Msk) ; + #endif + + #if defined (SCB_CSR_AIRCR_INIT) && (SCB_CSR_AIRCR_INIT == 1U) + SCB->SCR = (SCB->SCR & ~(SCB_SCR_SLEEPDEEPS_Msk )) | + ((SCB_CSR_DEEPSLEEPS_VAL << SCB_SCR_SLEEPDEEPS_Pos) & SCB_SCR_SLEEPDEEPS_Msk); + + SCB->AIRCR = (SCB->AIRCR & ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_SYSRESETREQS_Msk | + SCB_AIRCR_BFHFNMINS_Msk | SCB_AIRCR_PRIS_Msk) ) | + ((0x05FAU << SCB_AIRCR_VECTKEY_Pos) & SCB_AIRCR_VECTKEY_Msk) | + ((SCB_AIRCR_SYSRESETREQS_VAL << SCB_AIRCR_SYSRESETREQS_Pos) & SCB_AIRCR_SYSRESETREQS_Msk) | + ((SCB_AIRCR_PRIS_VAL << SCB_AIRCR_PRIS_Pos) & SCB_AIRCR_PRIS_Msk) | + ((SCB_AIRCR_BFHFNMINS_VAL << SCB_AIRCR_BFHFNMINS_Pos) & SCB_AIRCR_BFHFNMINS_Msk); + #endif /* defined (SCB_CSR_AIRCR_INIT) && (SCB_CSR_AIRCR_INIT == 1U) */ + + #if defined (__FPU_USED) && (__FPU_USED == 1U) && \ + defined (TZ_FPU_NS_USAGE) && (TZ_FPU_NS_USAGE == 1U) + + SCB->NSACR = (SCB->NSACR & ~(SCB_NSACR_CP10_Msk | SCB_NSACR_CP11_Msk)) | + ((SCB_NSACR_CP10_11_VAL << SCB_NSACR_CP10_Pos) & (SCB_NSACR_CP10_Msk | SCB_NSACR_CP11_Msk)); + + FPU->FPCCR = (FPU->FPCCR & ~(FPU_FPCCR_TS_Msk | FPU_FPCCR_CLRONRETS_Msk | FPU_FPCCR_CLRONRET_Msk)) | + ((FPU_FPCCR_TS_VAL << FPU_FPCCR_TS_Pos ) & FPU_FPCCR_TS_Msk ) | + ((FPU_FPCCR_CLRONRETS_VAL << FPU_FPCCR_CLRONRETS_Pos) & FPU_FPCCR_CLRONRETS_Msk) | + ((FPU_FPCCR_CLRONRET_VAL << FPU_FPCCR_CLRONRET_Pos ) & FPU_FPCCR_CLRONRET_Msk ); + #endif + + #if defined (NVIC_INIT_ITNS0) && (NVIC_INIT_ITNS0 == 1U) + NVIC->ITNS[0] = NVIC_INIT_ITNS0_VAL; + #endif + + #if defined (NVIC_INIT_ITNS1) && (NVIC_INIT_ITNS1 == 1U) + NVIC->ITNS[1] = NVIC_INIT_ITNS1_VAL; + #endif + + #if defined (NVIC_INIT_ITNS2) && (NVIC_INIT_ITNS2 == 1U) + NVIC->ITNS[2] = NVIC_INIT_ITNS2_VAL; + #endif + + #if defined (NVIC_INIT_ITNS3) && (NVIC_INIT_ITNS3 == 1U) + NVIC->ITNS[3] = NVIC_INIT_ITNS3_VAL; + #endif + + #if defined (NVIC_INIT_ITNS4) && (NVIC_INIT_ITNS4 == 1U) + NVIC->ITNS[4] = NVIC_INIT_ITNS4_VAL; + #endif + +} + +#endif /* PARTITION_STM32H573XX_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/partition_stm32h5xx.h b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/partition_stm32h5xx.h new file mode 100644 index 0000000000..859bd89355 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/partition_stm32h5xx.h @@ -0,0 +1,68 @@ +/** + ****************************************************************************** + * @file partition_stm32h5xx.h + * @author MCD Application Team + * @brief CMSIS STM32H5xx Device Header File for Initial Setup for Secure / + * Non-Secure Zones for ARMCM33 based on CMSIS CORE partition_ARMCM33.h + * Template. + * + * The file is included in system_stm32h5xx_s.c in secure application. + * It includes the configuration section that allows to select the + * STM32H5xx device partitioning file for system core secure attributes + * and interrupt secure and non-secure assignment. + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32h5xx + * @{ + */ + +#ifndef PARTITION_STM32H5XX_H +#define PARTITION_STM32H5XX_H + +#ifdef __cplusplus + extern "C" { +#endif /* __cplusplus */ + +/** @addtogroup Secure_configuration_section + * @{ + */ + +#if defined(STM32H573xx) + #include "partition_stm32h573xx.h" +#elif defined(STM32H563xx) + #include "partition_stm32h563xx.h" +#elif defined(STM32H562xx) + #include "partition_stm32h562xx.h" +#else + #error "Please select first the target STM32H5xx device used in your application (in stm32h5xx.h file)" +#endif + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* PARTITION_STM32H5XX_H */ +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/stm32h503xx.h b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/stm32h503xx.h new file mode 100644 index 0000000000..a8e7560bea --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/stm32h503xx.h @@ -0,0 +1,14040 @@ +/** + ****************************************************************************** + * @file stm32h503xx.h + * @author MCD Application Team + * @brief CMSIS STM32H503xx Device Peripheral Access Layer Header File. + * + * This file contains: + * - Data structures and the address mapping for all peripherals + * - Peripheral's registers declarations and bits definition + * - Macros to access peripheral’s registers hardware + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +#ifndef STM32H503xx_H +#define STM32H503xx_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup ST + * @{ + */ + + +/** @addtogroup STM32H503xx + * @{ + */ + + +/** @addtogroup Configuration_of_CMSIS + * @{ + */ + + +/* =========================================================================================================================== */ +/* ================ Interrupt Number Definition ================ */ +/* =========================================================================================================================== */ + +typedef enum +{ +/* ======================================= ARM Cortex-M33 Specific Interrupt Numbers ======================================= */ + Reset_IRQn = -15, /*!< -15 Reset Vector, invoked on Power up and warm reset */ + NonMaskableInt_IRQn = -14, /*!< -14 Non maskable Interrupt, cannot be stopped or preempted */ + HardFault_IRQn = -13, /*!< -13 Hard Fault, all classes of Fault */ + MemoryManagement_IRQn = -12, /*!< -12 Memory Management, MPU mismatch, including Access Violation + and No Match */ + BusFault_IRQn = -11, /*!< -11 Bus Fault, Pre-Fetch-, Memory Access Fault, other address/memory + related Fault */ + UsageFault_IRQn = -10, /*!< -10 Usage Fault, i.e. Undef Instruction, Illegal State Transition */ + SVCall_IRQn = -5, /*!< -5 System Service Call via SVC instruction */ + DebugMonitor_IRQn = -4, /*!< -4 Debug Monitor */ + PendSV_IRQn = -2, /*!< -2 Pendable request for system service */ + SysTick_IRQn = -1, /*!< -1 System Tick Timer */ + +/* =========================================== STM32H503xx Specific Interrupt Numbers ====================================== */ + WWDG_IRQn = 0, /*!< Window WatchDog interrupt */ + PVD_AVD_IRQn = 1, /*!< PVD/AVD through EXTI Line detection Interrupt */ + RTC_IRQn = 2, /*!< RTC non-secure interrupt */ + TAMP_IRQn = 4, /*!< Tamper global interrupt */ + RAMCFG_IRQn = 5, /*!< RAMCFG global interrupt */ + FLASH_IRQn = 6, /*!< FLASH non-secure global interrupt */ + RCC_IRQn = 9, /*!< RCC non secure global interrupt */ + EXTI0_IRQn = 11, /*!< EXTI Line0 interrupt */ + EXTI1_IRQn = 12, /*!< EXTI Line1 interrupt */ + EXTI2_IRQn = 13, /*!< EXTI Line2 interrupt */ + EXTI3_IRQn = 14, /*!< EXTI Line3 interrupt */ + EXTI4_IRQn = 15, /*!< EXTI Line4 interrupt */ + EXTI5_IRQn = 16, /*!< EXTI Line5 interrupt */ + EXTI6_IRQn = 17, /*!< EXTI Line6 interrupt */ + EXTI7_IRQn = 18, /*!< EXTI Line7 interrupt */ + EXTI8_IRQn = 19, /*!< EXTI Line8 interrupt */ + EXTI9_IRQn = 20, /*!< EXTI Line9 interrupt */ + EXTI10_IRQn = 21, /*!< EXTI Line10 interrupt */ + EXTI11_IRQn = 22, /*!< EXTI Line11 interrupt */ + EXTI12_IRQn = 23, /*!< EXTI Line12 interrupt */ + EXTI13_IRQn = 24, /*!< EXTI Line13 interrupt */ + EXTI14_IRQn = 25, /*!< EXTI Line14 interrupt */ + EXTI15_IRQn = 26, /*!< EXTI Line15 interrupt */ + GPDMA1_Channel0_IRQn = 27, /*!< GPDMA1 Channel 0 global interrupt */ + GPDMA1_Channel1_IRQn = 28, /*!< GPDMA1 Channel 1 global interrupt */ + GPDMA1_Channel2_IRQn = 29, /*!< GPDMA1 Channel 2 global interrupt */ + GPDMA1_Channel3_IRQn = 30, /*!< GPDMA1 Channel 3 global interrupt */ + GPDMA1_Channel4_IRQn = 31, /*!< GPDMA1 Channel 4 global interrupt */ + GPDMA1_Channel5_IRQn = 32, /*!< GPDMA1 Channel 5 global interrupt */ + GPDMA1_Channel6_IRQn = 33, /*!< GPDMA1 Channel 6 global interrupt */ + GPDMA1_Channel7_IRQn = 34, /*!< GPDMA1 Channel 7 global interrupt */ + IWDG_IRQn = 35, /*!< IWDG global interrupt */ + ADC1_IRQn = 37, /*!< ADC1 global interrupt */ + DAC1_IRQn = 38, /*!< DAC1 global interrupt */ + FDCAN1_IT0_IRQn = 39, /*!< FDCAN1 interrupt 0 */ + FDCAN1_IT1_IRQn = 40, /*!< FDCAN1 interrupt 1 */ + TIM1_BRK_IRQn = 41, /*!< TIM1 Break interrupt */ + TIM1_UP_IRQn = 42, /*!< TIM1 Update interrupt */ + TIM1_TRG_COM_IRQn = 43, /*!< TIM1 Trigger and Commutation interrupt */ + TIM1_CC_IRQn = 44, /*!< TIM1 Capture Compare interrupt */ + TIM2_IRQn = 45, /*!< TIM2 global interrupt */ + TIM3_IRQn = 46, /*!< TIM3 global interrupt */ + TIM6_IRQn = 49, /*!< TIM6 global interrupt */ + TIM7_IRQn = 50, /*!< TIM7 global interrupt */ + I2C1_EV_IRQn = 51, /*!< I2C1 Event interrupt */ + I2C1_ER_IRQn = 52, /*!< I2C1 Error interrupt */ + I2C2_EV_IRQn = 53, /*!< I2C2 Event interrupt */ + I2C2_ER_IRQn = 54, /*!< I2C2 Error interrupt */ + SPI1_IRQn = 55, /*!< SPI1 global interrupt */ + SPI2_IRQn = 56, /*!< SPI2 global interrupt */ + SPI3_IRQn = 57, /*!< SPI3 global interrupt */ + USART1_IRQn = 58, /*!< USART1 global interrupt */ + USART2_IRQn = 59, /*!< USART2 global interrupt */ + USART3_IRQn = 60, /*!< USART3 global interrupt */ + LPUART1_IRQn = 63, /*!< LPUART1 global interrupt */ + LPTIM1_IRQn = 64, /*!< LPTIM1 global interrupt */ + LPTIM2_IRQn = 70, /*!< LPTIM2 global interrupt */ + USB_DRD_FS_IRQn = 74, /*!< USB FS global interrupt */ + CRS_IRQn = 75, /*!< CRS global interrupt */ + GPDMA2_Channel0_IRQn = 90, /*!< GPDMA2 Channel 0 global interrupt */ + GPDMA2_Channel1_IRQn = 91, /*!< GPDMA2 Channel 1 global interrupt */ + GPDMA2_Channel2_IRQn = 92, /*!< GPDMA2 Channel 2 global interrupt */ + GPDMA2_Channel3_IRQn = 93, /*!< GPDMA2 Channel 3 global interrupt */ + GPDMA2_Channel4_IRQn = 94, /*!< GPDMA2 Channel 4 global interrupt */ + GPDMA2_Channel5_IRQn = 95, /*!< GPDMA2 Channel 5 global interrupt */ + GPDMA2_Channel6_IRQn = 96, /*!< GPDMA2 Channel 6 global interrupt */ + GPDMA2_Channel7_IRQn = 97, /*!< GPDMA2 Channel 7 global interrupt */ + FPU_IRQn = 103, /*!< FPU global interrupt */ + ICACHE_IRQn = 104, /*!< Instruction cache global interrupt */ + DTS_IRQn = 113, /*!< DTS global interrupt */ + RNG_IRQn = 114, /*!< RNG global interrupt */ + HASH_IRQn = 117, /*!< HASH global interrupt */ + I3C1_EV_IRQn = 123, /*!< I3C1 event interrupt */ + I3C1_ER_IRQn = 124, /*!< I3C1 error interrupt */ + I3C2_EV_IRQn = 131, /*!< I3C2 Event interrupt */ + I3C2_ER_IRQn = 132, /*!< I3C2 Error interrupt */ + COMP1_IRQn = 133, /*!< COMP global interrupt */ +} IRQn_Type; + + + +/* =========================================================================================================================== */ +/* ================ Processor and Core Peripheral Section ================ */ +/* =========================================================================================================================== */ + +/* ------- Start of section using anonymous unions and disabling warnings ------- */ +#if defined (__CC_ARM) + #pragma push + #pragma anon_unions +#elif defined (__ICCARM__) + #pragma language=extended +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wc11-extensions" + #pragma clang diagnostic ignored "-Wreserved-id-macro" +#elif defined (__GNUC__) + /* anonymous unions are enabled by default */ +#elif defined (__TMS470__) + /* anonymous unions are enabled by default */ +#elif defined (__TASKING__) + #pragma warning 586 +#elif defined (__CSMC__) + /* anonymous unions are enabled by default */ +#else + #warning Not supported compiler type +#endif + + +/* -------- Configuration of the Cortex-M33 Processor and Core Peripherals ------ */ +#define __CM33_REV 0x0000U /* Core revision r0p1 */ +#define __SAUREGION_PRESENT 1U /* SAU regions present */ +#define __MPU_PRESENT 1U /* MPU present */ +#define __VTOR_PRESENT 1U /* VTOR present */ +#define __NVIC_PRIO_BITS 4U /* Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0U /* Set to 1 if different SysTick Config is used */ +#define __FPU_PRESENT 1U /* FPU present */ +#define __DSP_PRESENT 1U /* DSP extension present */ + +/** @} */ /* End of group Configuration_of_CMSIS */ + + +#include /*!< ARM Cortex-M33 processor and core peripherals */ +#include "system_stm32h5xx.h" /*!< STM32H5xx System */ + + +/* =========================================================================================================================== */ +/* ================ Device Specific Peripheral Section ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup STM32H5xx_peripherals + * @{ + */ + +/** + * @brief CRC calculation unit + */ +typedef struct +{ + __IO uint32_t DR; /*!< CRC Data register, Address offset: 0x00 */ + __IO uint32_t IDR; /*!< CRC Independent data register, Address offset: 0x04 */ + __IO uint32_t CR; /*!< CRC Control register, Address offset: 0x08 */ + uint32_t RESERVED2; /*!< Reserved, 0x0C */ + __IO uint32_t INIT; /*!< Initial CRC value register, Address offset: 0x10 */ + __IO uint32_t POL; /*!< CRC polynomial register, Address offset: 0x14 */ + uint32_t RESERVED3[246]; /*!< Reserved, */ + __IO uint32_t HWCFGR; /*!< CRC IP HWCFGR register, Address offset: 0x3F0 */ + __IO uint32_t VERR; /*!< CRC IP version register, Address offset: 0x3F4 */ + __IO uint32_t PIDR; /*!< CRC IP type identification register, Address offset: 0x3F8 */ + __IO uint32_t SIDR; /*!< CRC IP map Size ID register, Address offset: 0x3FC */ +} CRC_TypeDef; + +/** + * @brief Inter-integrated Circuit Interface + */ +typedef struct +{ + __IO uint32_t CR1; /*!< I2C Control register 1, Address offset: 0x00 */ + __IO uint32_t CR2; /*!< I2C Control register 2, Address offset: 0x04 */ + __IO uint32_t OAR1; /*!< I2C Own address 1 register, Address offset: 0x08 */ + __IO uint32_t OAR2; /*!< I2C Own address 2 register, Address offset: 0x0C */ + __IO uint32_t TIMINGR; /*!< I2C Timing register, Address offset: 0x10 */ + __IO uint32_t TIMEOUTR; /*!< I2C Timeout register, Address offset: 0x14 */ + __IO uint32_t ISR; /*!< I2C Interrupt and status register, Address offset: 0x18 */ + __IO uint32_t ICR; /*!< I2C Interrupt clear register, Address offset: 0x1C */ + __IO uint32_t PECR; /*!< I2C PEC register, Address offset: 0x20 */ + __IO uint32_t RXDR; /*!< I2C Receive data register, Address offset: 0x24 */ + __IO uint32_t TXDR; /*!< I2C Transmit data register, Address offset: 0x28 */ +} I2C_TypeDef; + +/** + * @brief Improved Inter-integrated Circuit Interface + */ +typedef struct +{ + __IO uint32_t CR; /*!< I3C Control register, Address offset: 0x00 */ + __IO uint32_t CFGR; /*!< I3C Controller Configuration register, Address offset: 0x04 */ + uint32_t RESERVED1[2]; /*!< Reserved, Address offset: 0x08-0x0C */ + __IO uint32_t RDR; /*!< I3C Received Data register, Address offset: 0x10 */ + __IO uint32_t RDWR; /*!< I3C Received Data Word register, Address offset: 0x14 */ + __IO uint32_t TDR; /*!< I3C Transmit Data register, Address offset: 0x18 */ + __IO uint32_t TDWR; /*!< I3C Transmit Data Word register, Address offset: 0x1C */ + __IO uint32_t IBIDR; /*!< I3C IBI payload Data register, Address offset: 0x20 */ + __IO uint32_t TGTTDR; /*!< I3C Target Transmit register, Address offset: 0x24 */ + uint32_t RESERVED2[2]; /*!< Reserved, Address offset: 0x28-0x2C */ + __IO uint32_t SR; /*!< I3C Status register, Address offset: 0x30 */ + __IO uint32_t SER; /*!< I3C Status Error register, Address offset: 0x34 */ + uint32_t RESERVED3[2]; /*!< Reserved, Address offset: 0x38-0x3C */ + __IO uint32_t RMR; /*!< I3C Received Message register, Address offset: 0x40 */ + uint32_t RESERVED4[3]; /*!< Reserved, Address offset: 0x44-0x4C */ + __IO uint32_t EVR; /*!< I3C Event register, Address offset: 0x50 */ + __IO uint32_t IER; /*!< I3C Interrupt Enable register, Address offset: 0x54 */ + __IO uint32_t CEVR; /*!< I3C Clear Event register, Address offset: 0x58 */ + uint32_t RESERVED5; /*!< Reserved, Address offset: 0x5C */ + __IO uint32_t DEVR0; /*!< I3C own Target characteristics register, Address offset: 0x60 */ + __IO uint32_t DEVRX[4]; /*!< I3C Target x (1<=x<=4) register, Address offset: 0x64-0x70 */ + uint32_t RESERVED6[7]; /*!< Reserved, Address offset: 0x74-0x8C */ + __IO uint32_t MAXRLR; /*!< I3C Maximum Read Length register, Address offset: 0x90 */ + __IO uint32_t MAXWLR; /*!< I3C Maximum Write Length register, Address offset: 0x94 */ + uint32_t RESERVED7[2]; /*!< Reserved, Address offset: 0x98-0x9C */ + __IO uint32_t TIMINGR0; /*!< I3C Timing 0 register, Address offset: 0xA0 */ + __IO uint32_t TIMINGR1; /*!< I3C Timing 1 register, Address offset: 0xA4 */ + __IO uint32_t TIMINGR2; /*!< I3C Timing 2 register, Address offset: 0xA8 */ + uint32_t RESERVED9[5]; /*!< Reserved, Address offset: 0xAC-0xBC */ + __IO uint32_t BCR; /*!< I3C Bus Characteristics register, Address offset: 0xC0 */ + __IO uint32_t DCR; /*!< I3C Device Characteristics register, Address offset: 0xC4 */ + __IO uint32_t GETCAPR; /*!< I3C GET CAPabilities register, Address offset: 0xC8 */ + __IO uint32_t CRCAPR; /*!< I3C Controller CAPabilities register, Address offset: 0xCC */ + __IO uint32_t GETMXDSR; /*!< I3C GET Max Data Speed register, Address offset: 0xD0 */ + __IO uint32_t EPIDR; /*!< I3C Extended Provisioned ID register, Address offset: 0xD4 */ +} I3C_TypeDef; + +/** + * @brief DAC + */ +typedef struct +{ + __IO uint32_t CR; /*!< DAC control register, Address offset: 0x00 */ + __IO uint32_t SWTRIGR; /*!< DAC software trigger register, Address offset: 0x04 */ + __IO uint32_t DHR12R1; /*!< DAC channel1 12-bit right-aligned data holding register, Address offset: 0x08 */ + __IO uint32_t DHR12L1; /*!< DAC channel1 12-bit left aligned data holding register, Address offset: 0x0C */ + __IO uint32_t DHR8R1; /*!< DAC channel1 8-bit right aligned data holding register, Address offset: 0x10 */ + __IO uint32_t DHR12R2; /*!< DAC channel2 12-bit right aligned data holding register, Address offset: 0x14 */ + __IO uint32_t DHR12L2; /*!< DAC channel2 12-bit left aligned data holding register, Address offset: 0x18 */ + __IO uint32_t DHR8R2; /*!< DAC channel2 8-bit right-aligned data holding register, Address offset: 0x1C */ + __IO uint32_t DHR12RD; /*!< Dual DAC 12-bit right-aligned data holding register, Address offset: 0x20 */ + __IO uint32_t DHR12LD; /*!< DUAL DAC 12-bit left aligned data holding register, Address offset: 0x24 */ + __IO uint32_t DHR8RD; /*!< DUAL DAC 8-bit right aligned data holding register, Address offset: 0x28 */ + __IO uint32_t DOR1; /*!< DAC channel1 data output register, Address offset: 0x2C */ + __IO uint32_t DOR2; /*!< DAC channel2 data output register, Address offset: 0x30 */ + __IO uint32_t SR; /*!< DAC status register, Address offset: 0x34 */ + __IO uint32_t CCR; /*!< DAC calibration control register, Address offset: 0x38 */ + __IO uint32_t MCR; /*!< DAC mode control register, Address offset: 0x3C */ + __IO uint32_t SHSR1; /*!< DAC Sample and Hold sample time register 1, Address offset: 0x40 */ + __IO uint32_t SHSR2; /*!< DAC Sample and Hold sample time register 2, Address offset: 0x44 */ + __IO uint32_t SHHR; /*!< DAC Sample and Hold hold time register, Address offset: 0x48 */ + __IO uint32_t SHRR; /*!< DAC Sample and Hold refresh time register, Address offset: 0x4C */ + __IO uint32_t RESERVED[1]; + __IO uint32_t AUTOCR; /*!< DAC Autonomous mode register, Address offset: 0x54 */ +} DAC_TypeDef; + +/** + * @brief Clock Recovery System + */ +typedef struct +{ +__IO uint32_t CR; /*!< CRS ccontrol register, Address offset: 0x00 */ +__IO uint32_t CFGR; /*!< CRS configuration register, Address offset: 0x04 */ +__IO uint32_t ISR; /*!< CRS interrupt and status register, Address offset: 0x08 */ +__IO uint32_t ICR; /*!< CRS interrupt flag clear register, Address offset: 0x0C */ +} CRS_TypeDef; + + +/** + * @brief HASH + */ +typedef struct +{ + __IO uint32_t CR; /*!< HASH control register, Address offset: 0x00 */ + __IO uint32_t DIN; /*!< HASH data input register, Address offset: 0x04 */ + __IO uint32_t STR; /*!< HASH start register, Address offset: 0x08 */ + __IO uint32_t HR[5]; /*!< HASH digest registers, Address offset: 0x0C-0x1C */ + __IO uint32_t IMR; /*!< HASH interrupt enable register, Address offset: 0x20 */ + __IO uint32_t SR; /*!< HASH status register, Address offset: 0x24 */ + uint32_t RESERVED[52]; /*!< Reserved, 0x28-0xF4 */ + __IO uint32_t CSR[54]; /*!< HASH context swap registers, Address offset: 0x0F8-0x1CC */ +} HASH_TypeDef; + +/** + * @brief HASH_DIGEST + */ +typedef struct +{ + __IO uint32_t HR[8]; /*!< HASH digest registers, Address offset: 0x310-0x32C */ +} HASH_DIGEST_TypeDef; + +/** + * @brief RNG + */ +typedef struct +{ + __IO uint32_t CR; /*!< RNG control register, Address offset: 0x00 */ + __IO uint32_t SR; /*!< RNG status register, Address offset: 0x04 */ + __IO uint32_t DR; /*!< RNG data register, Address offset: 0x08 */ + uint32_t RESERVED; + __IO uint32_t HTCR; /*!< RNG health test configuration register, Address offset: 0x10 */ +} RNG_TypeDef; + +/** + * @brief Debug MCU + */ +typedef struct +{ + __IO uint32_t IDCODE; /*!< MCU device ID code, Address offset: 0x00 */ + __IO uint32_t CR; /*!< Debug MCU configuration register, Address offset: 0x04 */ + __IO uint32_t APB1FZR1; /*!< Debug MCU APB1 freeze register 1, Address offset: 0x08 */ + __IO uint32_t APB1FZR2; /*!< Debug MCU APB1 freeze register 2, Address offset: 0x0C */ + __IO uint32_t APB2FZR; /*!< Debug MCU APB2 freeze register, Address offset: 0x10 */ + __IO uint32_t APB3FZR; /*!< Debug MCU APB3 freeze register, Address offset: 0x14 */ + uint32_t RESERVED1[2]; /*!< Reserved, 0x18 - 0x1C */ + __IO uint32_t AHB1FZR; /*!< Debug MCU AHB1 freeze register, Address offset: 0x20 */ + uint32_t RESERVED2[54]; /*!< Reserved, 0x24 - 0xF8 */ + __IO uint32_t SR; /*!< Debug MCU SR register, Address offset: 0xFC */ + __IO uint32_t DBG_AUTH_HOST; /*!< Debug DBG_AUTH_HOST register, Address offset: 0x100 */ + __IO uint32_t DBG_AUTH_DEV; /*!< Debug DBG_AUTH_DEV register, Address offset: 0x104 */ + __IO uint32_t DBG_AUTH_ACK; /*!< Debug DBG_AUTH_ACK register, Address offset: 0x108 */ + uint32_t RESERVED3[945]; /*!< Reserved, 0x10C - 0xFCC */ + __IO uint32_t PIDR4; /*!< Debug MCU Peripheral ID register 4, Address offset: 0xFD0 */ + __IO uint32_t PIDR5; /*!< Debug MCU Peripheral ID register 5, Address offset: 0xFD4 */ + __IO uint32_t PIDR6; /*!< Debug MCU Peripheral ID register 6, Address offset: 0xFD8 */ + __IO uint32_t PIDR7; /*!< Debug MCU Peripheral ID register 7, Address offset: 0xFDC */ + __IO uint32_t PIDR0; /*!< Debug MCU Peripheral ID register 0, Address offset: 0xFE0 */ + __IO uint32_t PIDR1; /*!< Debug MCU Peripheral ID register 1, Address offset: 0xFE4 */ + __IO uint32_t PIDR2; /*!< Debug MCU Peripheral ID register 2, Address offset: 0xFE8 */ + __IO uint32_t PIDR3; /*!< Debug MCU Peripheral ID register 3, Address offset: 0xFEC */ + __IO uint32_t CIDR0; /*!< Debug MCU Component ID register 0, Address offset: 0xFF0 */ + __IO uint32_t CIDR1; /*!< Debug MCU Component ID register 1, Address offset: 0xFF4 */ + __IO uint32_t CIDR2; /*!< Debug MCU Component ID register 2, Address offset: 0xFF8 */ + __IO uint32_t CIDR3; /*!< Debug MCU Component ID register 3, Address offset: 0xFFC */ +} DBGMCU_TypeDef; + + +/** + * @brief DMA Controller + */ +typedef struct +{ + uint32_t RESERVED0; /*!< Reserved Address offset: 0x00 */ + __IO uint32_t PRIVCFGR; /*!< DMA privileged configuration register, Address offset: 0x04 */ + uint32_t RESERVED1; /*!< Reserved Address offset: 0x08 */ + __IO uint32_t MISR; /*!< DMA non secure masked interrupt status register, Address offset: 0x0C */ + uint32_t RESERVED2; /*!< Reserved Address offset: 0x08 */ +} DMA_TypeDef; + +typedef struct +{ + __IO uint32_t CLBAR; /*!< DMA channel x linked-list base address register, Address offset: 0x50 + (x * 0x80) */ + uint32_t RESERVED1[2]; /*!< Reserved 1, Address offset: 0x54 -- 0x58 */ + __IO uint32_t CFCR; /*!< DMA channel x flag clear register, Address offset: 0x5C + (x * 0x80) */ + __IO uint32_t CSR; /*!< DMA channel x flag status register, Address offset: 0x60 + (x * 0x80) */ + __IO uint32_t CCR; /*!< DMA channel x control register, Address offset: 0x64 + (x * 0x80) */ + uint32_t RESERVED2[10];/*!< Reserved 2, Address offset: 0x68 -- 0x8C */ + __IO uint32_t CTR1; /*!< DMA channel x transfer register 1, Address offset: 0x90 + (x * 0x80) */ + __IO uint32_t CTR2; /*!< DMA channel x transfer register 2, Address offset: 0x94 + (x * 0x80) */ + __IO uint32_t CBR1; /*!< DMA channel x block register 1, Address offset: 0x98 + (x * 0x80) */ + __IO uint32_t CSAR; /*!< DMA channel x source address register, Address offset: 0x9C + (x * 0x80) */ + __IO uint32_t CDAR; /*!< DMA channel x destination address register, Address offset: 0xA0 + (x * 0x80) */ + __IO uint32_t CTR3; /*!< DMA channel x transfer register 3, Address offset: 0xA4 + (x * 0x80) */ + __IO uint32_t CBR2; /*!< DMA channel x block register 2, Address offset: 0xA8 + (x * 0x80) */ + uint32_t RESERVED3[8]; /*!< Reserved 3, Address offset: 0xAC -- 0xC8 */ + __IO uint32_t CLLR; /*!< DMA channel x linked-list address register, Address offset: 0xCC + (x * 0x80) */ +} DMA_Channel_TypeDef; + + +/** + * @brief Asynch Interrupt/Event Controller (EXTI) + */ +typedef struct +{ + __IO uint32_t RTSR1; /*!< EXTI Rising Trigger Selection Register 1, Address offset: 0x00 */ + __IO uint32_t FTSR1; /*!< EXTI Falling Trigger Selection Register 1, Address offset: 0x04 */ + __IO uint32_t SWIER1; /*!< EXTI Software Interrupt event Register 1, Address offset: 0x08 */ + __IO uint32_t RPR1; /*!< EXTI Rising Pending Register 1, Address offset: 0x0C */ + __IO uint32_t FPR1; /*!< EXTI Falling Pending Register 1, Address offset: 0x10 */ + __IO uint32_t SECCFGR1; /*!< EXTI Security Configuration Register 1, Address offset: 0x14 */ + __IO uint32_t PRIVCFGR1; /*!< EXTI Privilege Configuration Register 1, Address offset: 0x18 */ + uint32_t RESERVED1; /*!< Reserved 1, Address offset: 0x1C */ + __IO uint32_t RTSR2; /*!< EXTI Rising Trigger Selection Register 2, Address offset: 0x20 */ + __IO uint32_t FTSR2; /*!< EXTI Falling Trigger Selection Register 2, Address offset: 0x24 */ + __IO uint32_t SWIER2; /*!< EXTI Software Interrupt event Register 2, Address offset: 0x28 */ + __IO uint32_t RPR2; /*!< EXTI Rising Pending Register 2, Address offset: 0x2C */ + __IO uint32_t FPR2; /*!< EXTI Falling Pending Register 2, Address offset: 0x30 */ + __IO uint32_t SECCFGR2; /*!< EXTI Security Configuration Register 2, Address offset: 0x34 */ + __IO uint32_t PRIVCFGR2; /*!< EXTI Privilege Configuration Register 2, Address offset: 0x38 */ + uint32_t RESERVED2[9]; /*!< Reserved 2, 0x3C-- 0x5C */ + __IO uint32_t EXTICR[4]; /*!< EXIT External Interrupt Configuration Register, 0x60 -- 0x6C */ + uint32_t RESERVED3[4]; /*!< Reserved 3, 0x70 -- 0x7C */ + __IO uint32_t IMR1; /*!< EXTI Interrupt Mask Register 1, Address offset: 0x80 */ + __IO uint32_t EMR1; /*!< EXTI Event Mask Register 1, Address offset: 0x84 */ + uint32_t RESERVED4[2]; /*!< Reserved 4, 0x88 -- 0x8C */ + __IO uint32_t IMR2; /*!< EXTI Interrupt Mask Register 2, Address offset: 0x90 */ + __IO uint32_t EMR2; /*!< EXTI Event Mask Register 2, Address offset: 0x94 */ +} EXTI_TypeDef; + +/** + * @brief FLASH Registers + */ +typedef struct +{ + __IO uint32_t ACR; /*!< FLASH access control register, Address offset: 0x00 */ + __IO uint32_t NSKEYR; /*!< FLASH non-secure key register, Address offset: 0x04 */ + uint32_t RESERVED1; /*!< Reserved1, Address offset: 0x08 */ + __IO uint32_t OPTKEYR; /*!< FLASH option key register, Address offset: 0x0C */ + uint32_t RESERVED2[2]; /*!< Reserved2, Address offset: 0x10-0x14 */ + __IO uint32_t OPSR; /*!< FLASH OPSR register, Address offset: 0x18 */ + __IO uint32_t OPTCR; /*!< Flash Option Control Register, Address offset: 0x1C */ + __IO uint32_t NSSR; /*!< FLASH non-secure status register, Address offset: 0x20 */ + uint32_t RESERVED3; /*!< Reserved3, Address offset: 0x24 */ + __IO uint32_t NSCR; /*!< FLASH non-secure control register, Address offset: 0x28 */ + uint32_t RESERVED4; /*!< Reserved4, Address offset: 0x2C */ + __IO uint32_t NSCCR; /*!< FLASH non-secure clear control register, Address offset: 0x30 */ + uint32_t RESERVED5[2]; /*!< Reserved5, Address offset: 0x34-0x38 */ + __IO uint32_t PRIVCFGR; /*!< FLASH privilege configuration register, Address offset: 0x3C */ + uint32_t RESERVED6[2]; /*!< Reserved6, Address offset: 0x40-0x44 */ + __IO uint32_t HDPEXTR; /*!< FLASH HDP extension register, Address offset: 0x48 */ + uint32_t RESERVED7; /*!< Reserved7, Address offset: 0x4C */ + __IO uint32_t OPTSR_CUR; /*!< FLASH option status current register, Address offset: 0x50 */ + __IO uint32_t OPTSR_PRG; /*!< FLASH option status to program register, Address offset: 0x54 */ + uint32_t RESERVED8[2]; /*!< Reserved8, Address offset: 0x58-0x5C */ + __IO uint32_t NSEPOCHR_CUR; /*!< FLASH non-secure epoch current register, Address offset: 0x60 */ + __IO uint32_t NSEPOCHR_PRG; /*!< FLASH non-secure epoch to program register, Address offset: 0x64 */ + uint32_t RESERVED9[2]; /*!< Reserved9, Address offset: 0x68-0x6C */ + __IO uint32_t OPTSR2_CUR; /*!< FLASH option status current register 2, Address offset: 0x70 */ + __IO uint32_t OPTSR2_PRG; /*!< FLASH option status to program register 2, Address offset: 0x74 */ + uint32_t RESERVED10[2]; /*!< Reserved10, Address offset: 0x78-0x7C */ + __IO uint32_t NSBOOTR_CUR; /*!< FLASH non-secure unique boot entry current register, Address offset: 0x80 */ + __IO uint32_t NSBOOTR_PRG; /*!< FLASH non-secure unique boot entry to program register, Address offset: 0x84 */ + uint32_t RESERVED11[2]; /*!< Reserved11, Address offset: 0x88-0x8C */ + __IO uint32_t OTPBLR_CUR; /*!< FLASH OTP block lock current register, Address offset: 0x90 */ + __IO uint32_t OTPBLR_PRG; /*!< FLASH OTP block Lock to program register, Address offset: 0x94 */ + uint32_t RESERVED12[10]; /*!< Reserved12, Address offset: 0x98-0xBC */ + __IO uint32_t PRIVBB1R1; /*!< FLASH privilege block-based bank 1 register 1, Address offset: 0xC0 */ + uint32_t RESERVED13[9]; /*!< Reserved13, Address offset: 0xC4-0xE4 */ + __IO uint32_t WRP1R_CUR; /*!< FLASH write sector group protection current register for bank1, Address offset: 0xE8 */ + __IO uint32_t WRP1R_PRG; /*!< FLASH write sector group protection to program register for bank1, Address offset: 0xEC */ + uint32_t RESERVED14[2]; /*!< Reserved14, Address offset: 0xF0-0xF4 */ + __IO uint32_t HDP1R_CUR; /*!< FLASH HDP configuration current register for bank1, Address offset: 0xF8 */ + __IO uint32_t HDP1R_PRG; /*!< FLASH HDP configuration to program register for bank1, Address offset: 0xFC */ + __IO uint32_t ECCCORR; /*!< FLASH ECC correction register, Address offset: 0x100 */ + __IO uint32_t ECCDETR; /*!< FLASH ECC detection register, Address offset: 0x104 */ + __IO uint32_t ECCDR; /*!< FLASH ECC data register, Address offset: 0x108 */ + uint32_t RESERVED15[45]; /*!< Reserved15, Address offset: 0x10C-0x1BC */ + __IO uint32_t PRIVBB2R1; /*!< FLASH privilege block-based bank 2 register 1, Address offset: 0x1C0 */ + uint32_t RESERVED16[9]; /*!< Reserved16, Address offset: 0x1C4-0x1E4 */ + __IO uint32_t WRP2R_CUR; /*!< FLASH write sector group protection current register for bank2, Address offset: 0x1E8 */ + __IO uint32_t WRP2R_PRG; /*!< FLASH write sector group protection to program register for bank2, Address offset: 0x1EC */ + uint32_t RESERVED17[2]; /*!< Reserved17, Address offset: 0x1F0-0x1F4 */ + __IO uint32_t HDP2R_CUR; /*!< FLASH HDP configuration current register for bank2, Address offset: 0x1F8 */ + __IO uint32_t HDP2R_PRG; /*!< FLASH HDP configuration to program register for bank2, Address offset: 0x1FC */ +} FLASH_TypeDef; + +/** + * @brief General Purpose I/O + */ +typedef struct +{ + __IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */ + __IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */ + __IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */ + __IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ + __IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */ + __IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */ + __IO uint32_t BSRR; /*!< GPIO port bit set/reset register, Address offset: 0x18 */ + __IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */ + __IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */ + __IO uint32_t BRR; /*!< GPIO Bit Reset register, Address offset: 0x28 */ + __IO uint32_t HSLVR; /*!< GPIO high-speed low voltage register, Address offset: 0x2C */ + __IO uint32_t SECCFGR; /*!< GPIO secure configuration register, Address offset: 0x30 */ +} GPIO_TypeDef; + +/** + * @brief Global TrustZone Controller + */ +typedef struct +{ + uint32_t RESERVED1[8]; /*!< Reserved1, Address offset: 0x00-0x1C */ + __IO uint32_t PRIVCFGR1; /*!< TZSC privilege configuration register 1, Address offset: 0x20 */ + __IO uint32_t PRIVCFGR2; /*!< TZSC privilege configuration register 2, Address offset: 0x24 */ + __IO uint32_t PRIVCFGR3; /*!< TZSC privilege configuration register 3, Address offset: 0x28 */ + uint32_t RESERVED3[17]; /*!< Reserved3, Address offset: 0x2C-0x6C */ + __IO uint32_t MPCWM4ACFGR; /*!< TZSC memory 4 sub-region A watermark configuration register, Address offset: 0x70 */ + __IO uint32_t MPCWM4AR; /*!< TZSC memory 4 sub-region A watermark register, Address offset: 0x74 */ + __IO uint32_t MPCWM4BCFGR; /*!< TZSC memory 4 sub-region B watermark configuration register, Address offset: 0x78 */ + __IO uint32_t MPCWM4BR; /*!< TZSC memory 4 sub-region B watermark register, Address offset: 0x7c */ +} GTZC_TZSC_TypeDef; + +typedef struct +{ + uint32_t RESERVED1[128]; /*!< Reserved1, Address offset: 0x000-0x1FC */ + __IO uint32_t PRIVCFGR[32]; /*!< MPCBBx privilege configuration registers, Address offset: 0x200-0x280 */ +} GTZC_MPCBB_TypeDef; + +/** + * @brief Instruction Cache + */ +typedef struct +{ + __IO uint32_t CR; /*!< ICACHE control register, Address offset: 0x00 */ + __IO uint32_t SR; /*!< ICACHE status register, Address offset: 0x04 */ + __IO uint32_t IER; /*!< ICACHE interrupt enable register, Address offset: 0x08 */ + __IO uint32_t FCR; /*!< ICACHE Flag clear register, Address offset: 0x0C */ + __IO uint32_t HMONR; /*!< ICACHE hit monitor register, Address offset: 0x10 */ + __IO uint32_t MMONR; /*!< ICACHE miss monitor register, Address offset: 0x14 */ +} ICACHE_TypeDef; + +/** + * @brief TIM + */ +typedef struct +{ + __IO uint32_t CR1; /*!< TIM control register 1, Address offset: 0x00 */ + __IO uint32_t CR2; /*!< TIM control register 2, Address offset: 0x04 */ + __IO uint32_t SMCR; /*!< TIM slave mode control register, Address offset: 0x08 */ + __IO uint32_t DIER; /*!< TIM DMA/interrupt enable register, Address offset: 0x0C */ + __IO uint32_t SR; /*!< TIM status register, Address offset: 0x10 */ + __IO uint32_t EGR; /*!< TIM event generation register, Address offset: 0x14 */ + __IO uint32_t CCMR1; /*!< TIM capture/compare mode register 1, Address offset: 0x18 */ + __IO uint32_t CCMR2; /*!< TIM capture/compare mode register 2, Address offset: 0x1C */ + __IO uint32_t CCER; /*!< TIM capture/compare enable register, Address offset: 0x20 */ + __IO uint32_t CNT; /*!< TIM counter register, Address offset: 0x24 */ + __IO uint32_t PSC; /*!< TIM prescaler, Address offset: 0x28 */ + __IO uint32_t ARR; /*!< TIM auto-reload register, Address offset: 0x2C */ + __IO uint32_t RCR; /*!< TIM repetition counter register, Address offset: 0x30 */ + __IO uint32_t CCR1; /*!< TIM capture/compare register 1, Address offset: 0x34 */ + __IO uint32_t CCR2; /*!< TIM capture/compare register 2, Address offset: 0x38 */ + __IO uint32_t CCR3; /*!< TIM capture/compare register 3, Address offset: 0x3C */ + __IO uint32_t CCR4; /*!< TIM capture/compare register 4, Address offset: 0x40 */ + __IO uint32_t BDTR; /*!< TIM break and dead-time register, Address offset: 0x44 */ + __IO uint32_t CCR5; /*!< TIM capture/compare register 5, Address offset: 0x48 */ + __IO uint32_t CCR6; /*!< TIM capture/compare register 6, Address offset: 0x4C */ + __IO uint32_t CCMR3; /*!< TIM capture/compare mode register 3, Address offset: 0x50 */ + __IO uint32_t DTR2; /*!< TIM deadtime register 2, Address offset: 0x54 */ + __IO uint32_t ECR; /*!< TIM encoder control register, Address offset: 0x58 */ + __IO uint32_t TISEL; /*!< TIM Input Selection register, Address offset: 0x5C */ + __IO uint32_t AF1; /*!< TIM alternate function option register 1, Address offset: 0x60 */ + __IO uint32_t AF2; /*!< TIM alternate function option register 2, Address offset: 0x64 */ + uint32_t RESERVED0[221];/*!< Reserved, Address offset: 0x68 */ + __IO uint32_t DCR; /*!< TIM DMA control register, Address offset: 0x3DC */ + __IO uint32_t DMAR; /*!< TIM DMA address for full transfer, Address offset: 0x3E0 */ +} TIM_TypeDef; + +/** + * @brief LPTIMER + */ +typedef struct +{ + __IO uint32_t ISR; /*!< LPTIM Interrupt and Status register, Address offset: 0x00 */ + __IO uint32_t ICR; /*!< LPTIM Interrupt Clear register, Address offset: 0x04 */ + __IO uint32_t DIER; /*!< LPTIM Interrupt Enable register, Address offset: 0x08 */ + __IO uint32_t CFGR; /*!< LPTIM Configuration register, Address offset: 0x0C */ + __IO uint32_t CR; /*!< LPTIM Control register, Address offset: 0x10 */ + __IO uint32_t CCR1; /*!< LPTIM Capture/Compare register 1, Address offset: 0x14 */ + __IO uint32_t ARR; /*!< LPTIM Autoreload register, Address offset: 0x18 */ + __IO uint32_t CNT; /*!< LPTIM Counter register, Address offset: 0x1C */ + __IO uint32_t RESERVED0; /*!< Reserved, Address offset: 0x20 */ + __IO uint32_t CFGR2; /*!< LPTIM Configuration register 2, Address offset: 0x24 */ + __IO uint32_t RCR; /*!< LPTIM Repetition register, Address offset: 0x28 */ + __IO uint32_t CCMR1; /*!< LPTIM Capture/Compare mode register, Address offset: 0x2C */ + __IO uint32_t RESERVED1; /*!< Reserved, Address offset: 0x30 */ + __IO uint32_t CCR2; /*!< LPTIM Capture/Compare register 2, Address offset: 0x34 */ +} LPTIM_TypeDef; + +/** + * @brief Comparator + */ +typedef struct +{ + __IO uint32_t SR; /*!< Comparator status register, Address offset: 0x00 */ + __IO uint32_t ICFR; /*!< Comparator interrupt clear flag register, Address offset: 0x04 */ +} COMPOPT_TypeDef; + +typedef struct +{ + __IO uint32_t SR; /*!< Comparator status register, Address offset: 0x00 */ + __IO uint32_t ICFR; /*!< Comparator interrupt clear flag register, Address offset: 0x04 */ + __IO uint32_t RESERVED1; /*!< Reserved, Address offset: 0x08 */ + __IO uint32_t CFGR1; /*!< Comparator configuration register 1 , Address offset: 0x0C */ + __IO uint32_t CFGR2; /*!< Comparator configuration register 2 , Address offset: 0x10 */ +} COMP_TypeDef; + +typedef struct +{ + __IO uint32_t CFGR; /*!< COMP control and status register, used for bits common to several COMP instances, Address offset: 0x00 */ +} COMP_Common_TypeDef; + +/** + * @brief Operational Amplifier (OPAMP) + */ + +typedef struct +{ + __IO uint32_t CSR; /*!< OPAMP control/status register, Address offset: 0x00 */ + __IO uint32_t OTR; /*!< OPAMP offset trimming register for normal mode, Address offset: 0x04 */ + __IO uint32_t HSOTR; /*!< OPAMP offset trimming register for high speed mode, Address offset: 0x08 */ +} OPAMP_TypeDef; + + + +/** + * @brief Power Control + */ +typedef struct +{ + __IO uint32_t PMCR; /*!< Power mode control register , Address offset: 0x00 */ + __IO uint32_t PMSR; /*!< Power mode status register , Address offset: 0x04 */ + uint32_t RESERVED1[2]; /*!< Reserved, Address offset: 0x08-0x0C */ + __IO uint32_t VOSCR; /*!< Voltage scaling control register , Address offset: 0x10 */ + __IO uint32_t VOSSR; /*!< Voltage sacling status register , Address offset: 0x14 */ + uint32_t RESERVED2[2]; /*!< Reserved, Address offset: 0x18-0x1C */ + __IO uint32_t BDCR; /*!< BacKup domain control register , Address offset: 0x20 */ + __IO uint32_t DBPCR; /*!< DBP control register, Address offset: 0x24 */ + __IO uint32_t BDSR; /*!< BacKup domain status register, Address offset: 0x28 */ + uint32_t RESERVED3; /*!< Reserved, Address offset: 0x38 */ + __IO uint32_t SCCR; /*!< Supply configuration control register, Address offset: 0x30 */ + __IO uint32_t VMCR; /*!< Voltage Monitor Control Register, Address offset: 0x34 */ + uint32_t RESERVED4; /*!< Reserved, Address offset: 0x38 */ + __IO uint32_t VMSR; /*!< Status Register Voltage Monitoring, Address offset: 0x3C */ + __IO uint32_t WUSCR; /*!< WakeUP status clear register, Address offset: 0x40 */ + __IO uint32_t WUSR; /*!< WakeUP status Register, Address offset: 0x44 */ + __IO uint32_t WUCR; /*!< WakeUP configuration register, Address offset: 0x48 */ + uint32_t RESERVED5; /*!< Reserved, Address offset: 0x4C */ + __IO uint32_t IORETR; /*!< IO RETention Register, Address offset: 0x50 */ + uint32_t RESERVED6[43];/*!< Reserved, Address offset: 0x54-0xFC */ + uint32_t RESERVED7; /*!< Reserved, Address offset: 0x100 */ + __IO uint32_t PRIVCFGR; /*!< Privilege configuration register, Address offset: 0x104 */ +}PWR_TypeDef; + +/** + * @brief SRAMs configuration controller + */ +typedef struct +{ + __IO uint32_t CR; /*!< Control Register, Address offset: 0x00 */ + __IO uint32_t IER; /*!< Interrupt Enable Register, Address offset: 0x04 */ + __IO uint32_t ISR; /*!< Interrupt Status Register, Address offset: 0x08 */ + __IO uint32_t SEAR; /*!< ECC Single Error Address Register, Address offset: 0x0C */ + __IO uint32_t DEAR; /*!< ECC Double Error Address Register, Address offset: 0x10 */ + __IO uint32_t ICR; /*!< Interrupt Clear Register, Address offset: 0x14 */ + __IO uint32_t WPR1; /*!< SRAM Write Protection Register 1, Address offset: 0x18 */ + __IO uint32_t WPR2; /*!< SRAM Write Protection Register 2, Address offset: 0x1C */ + uint32_t RESERVED; /*!< Reserved, Address offset: 0x20 */ + __IO uint32_t ECCKEY; /*!< SRAM ECC Key Register, Address offset: 0x24 */ + __IO uint32_t ERKEYR; /*!< SRAM Erase Key Register, Address offset: 0x28 */ +}RAMCFG_TypeDef; + +/** + * @brief Reset and Clock Control + */ +typedef struct +{ + __IO uint32_t CR; /*!< RCC clock control register Address offset: 0x00 */ + uint32_t RESERVED1[3]; /*!< Reserved, Address offset: 0x04 */ + __IO uint32_t HSICFGR; /*!< RCC HSI Clock Calibration Register, Address offset: 0x10 */ + __IO uint32_t CRRCR; /*!< RCC Clock Recovery RC Register, Address offset: 0x14 */ + __IO uint32_t CSICFGR; /*!< RCC CSI Clock Calibration Register, Address offset: 0x18 */ + __IO uint32_t CFGR1; /*!< RCC clock configuration register 1 Address offset: 0x1C */ + __IO uint32_t CFGR2; /*!< RCC clock configuration register 2 Address offset: 0x20 */ + uint32_t RESERVED2; /*!< Reserved, Address offset: 0x24 */ + __IO uint32_t PLL1CFGR; /*!< RCC PLL1 Configuration Register Address offset: 0x28 */ + __IO uint32_t PLL2CFGR; /*!< RCC PLL2 Configuration Register Address offset: 0x2C */ + uint32_t RESERVED3; /*!< Reserved, Address offset: 0x30 */ + __IO uint32_t PLL1DIVR; /*!< RCC PLL1 Dividers Configuration Register Address offset: 0x34 */ + __IO uint32_t PLL1FRACR; /*!< RCC PLL1 Fractional Divider Configuration Register Address offset: 0x38 */ + __IO uint32_t PLL2DIVR; /*!< RCC PLL2 Dividers Configuration Register Address offset: 0x3C */ + __IO uint32_t PLL2FRACR; /*!< RCC PLL2 Fractional Divider Configuration Register Address offset: 0x40 */ + uint32_t RESERVED4[2]; /*!< Reserved, Address offset: 0x44 */ + uint32_t RESERVED5; /*!< Reserved Address offset: 0x4C */ + __IO uint32_t CIER; /*!< RCC Clock Interrupt Enable Register Address offset: 0x50 */ + __IO uint32_t CIFR; /*!< RCC Clock Interrupt Flag Register Address offset: 0x54 */ + __IO uint32_t CICR; /*!< RCC Clock Interrupt Clear Register Address offset: 0x58 */ + uint32_t RESERVED6; /*!< Reserved Address offset: 0x5C */ + __IO uint32_t AHB1RSTR; /*!< RCC AHB1 Peripherals Reset Register Address offset: 0x60 */ + __IO uint32_t AHB2RSTR; /*!< RCC AHB2 Peripherals Reset Register Address offset: 0x64 */ + uint32_t RESERVED7; /*!< Reserved Address offset: 0x68 */ + uint32_t RESERVED8; /*!< Reserved, Address offset: 0x6C */ + uint32_t RESERVED9; /*!< Reserved Address offset: 0x70 */ + __IO uint32_t APB1LRSTR; /*!< RCC APB1 Peripherals reset Low Word register Address offset: 0x74 */ + __IO uint32_t APB1HRSTR; /*!< RCC APB1 Peripherals reset High Word register Address offset: 0x78 */ + __IO uint32_t APB2RSTR; /*!< RCC APB2 Peripherals Reset Register Address offset: 0x7C */ + __IO uint32_t APB3RSTR; /*!< RCC APB3 Peripherals Reset Register Address offset: 0x80 */ + uint32_t RESERVED10; /*!< Reserved Address offset: 0x84 */ + __IO uint32_t AHB1ENR; /*!< RCC AHB1 Peripherals Clock Enable Register Address offset: 0x88 */ + __IO uint32_t AHB2ENR; /*!< RCC AHB2 Peripherals Clock Enable Register Address offset: 0x8C */ + uint32_t RESERVED11; /*!< Reserved Address offset: 0x90 */ + uint32_t RESERVED12; /*!< Reserved, Address offset: 0x94 */ + uint32_t RESERVED13; /*!< Reserved Address offset: 0x98 */ + __IO uint32_t APB1LENR; /*!< RCC APB1 Peripherals clock Enable Low Word register Address offset: 0x9C */ + __IO uint32_t APB1HENR; /*!< RCC APB1 Peripherals clock Enable High Word register Address offset: 0xA0 */ + __IO uint32_t APB2ENR; /*!< RCC APB2 Peripherals Clock Enable Register Address offset: 0xA4 */ + __IO uint32_t APB3ENR; /*!< RCC APB3 Peripherals Clock Enable Register Address offset: 0xA8 */ + uint32_t RESERVED14; /*!< Reserved Address offset: 0xAC */ + __IO uint32_t AHB1LPENR; /*!< RCC AHB1 Peripheral sleep clock Register Address offset: 0xB0 */ + __IO uint32_t AHB2LPENR; /*!< RCC AHB2 Peripheral sleep clock Register Address offset: 0xB4 */ + uint32_t RESERVED15; /*!< Reserved Address offset: 0xB8 */ + uint32_t RESERVED16; /*!< Reserved, Address offset: 0xBC */ + uint32_t RESERVED17; /*!< Reserved Address offset: 0xC0 */ + __IO uint32_t APB1LLPENR; /*!< RCC APB1 Peripherals sleep clock Low Word Register Address offset: 0xC4 */ + __IO uint32_t APB1HLPENR; /*!< RCC APB1 Peripherals sleep clock High Word Register Address offset: 0xC8 */ + __IO uint32_t APB2LPENR; /*!< RCC APB2 Peripherals sleep clock Register Address offset: 0xCC */ + __IO uint32_t APB3LPENR; /*!< RCC APB3 Peripherals Clock Low Power Enable Register Address offset: 0xD0 */ + uint32_t RESERVED18; /*!< Reserved Address offset: 0xD4 */ + __IO uint32_t CCIPR1; /*!< RCC IPs Clocks Configuration Register 1 Address offset: 0xD8 */ + __IO uint32_t CCIPR2; /*!< RCC IPs Clocks Configuration Register 2 Address offset: 0xDC */ + __IO uint32_t CCIPR3; /*!< RCC IPs Clocks Configuration Register 3 Address offset: 0xE0 */ + __IO uint32_t CCIPR4; /*!< RCC IPs Clocks Configuration Register 4 Address offset: 0xE4 */ + __IO uint32_t CCIPR5; /*!< RCC IPs Clocks Configuration Register 5 Address offset: 0xE8 */ + uint32_t RESERVED19; /*!< Reserved, Address offset: 0xEC */ + __IO uint32_t BDCR; /*!< RCC VSW Backup Domain & V33 Domain Control Register Address offset: 0xF0 */ + __IO uint32_t RSR; /*!< RCC Reset status Register Address offset: 0xF4 */ + uint32_t RESERVED20[6]; /*!< Reserved Address offset: 0xF8 */ + uint32_t RESERVED21; /*!< Reserved, Address offset: 0x110 */ + __IO uint32_t PRIVCFGR; /*!< RCC Privilege configuration register Address offset: 0x114 */ +} RCC_TypeDef; + +/* +* @brief RTC Specific device feature definitions +*/ +#define RTC_BKP_NB 32U +#define RTC_TAMP_NB 2U + +/** + * @brief Real-Time Clock + */ +typedef struct +{ + __IO uint32_t TR; /*!< RTC time register, Address offset: 0x00 */ + __IO uint32_t DR; /*!< RTC date register, Address offset: 0x04 */ + __IO uint32_t SSR; /*!< RTC sub second register, Address offset: 0x08 */ + __IO uint32_t ICSR; /*!< RTC initialization control and status register, Address offset: 0x0C */ + __IO uint32_t PRER; /*!< RTC prescaler register, Address offset: 0x10 */ + __IO uint32_t WUTR; /*!< RTC wakeup timer register, Address offset: 0x14 */ + __IO uint32_t CR; /*!< RTC control register, Address offset: 0x18 */ + __IO uint32_t PRIVCFGR; /*!< RTC privilege mode control register, Address offset: 0x1C */ + uint32_t RESERVED0; /*!< Reserved, Address offset: 0x20 */ + __IO uint32_t WPR; /*!< RTC write protection register, Address offset: 0x24 */ + __IO uint32_t CALR; /*!< RTC calibration register, Address offset: 0x28 */ + __IO uint32_t SHIFTR; /*!< RTC shift control register, Address offset: 0x2C */ + __IO uint32_t TSTR; /*!< RTC time stamp time register, Address offset: 0x30 */ + __IO uint32_t TSDR; /*!< RTC time stamp date register, Address offset: 0x34 */ + __IO uint32_t TSSSR; /*!< RTC time-stamp sub second register, Address offset: 0x38 */ + uint32_t RESERVED1; /*!< Reserved, Address offset: 0x3C */ + __IO uint32_t ALRMAR; /*!< RTC alarm A register, Address offset: 0x40 */ + __IO uint32_t ALRMASSR; /*!< RTC alarm A sub second register, Address offset: 0x44 */ + __IO uint32_t ALRMBR; /*!< RTC alarm B register, Address offset: 0x48 */ + __IO uint32_t ALRMBSSR; /*!< RTC alarm B sub second register, Address offset: 0x4C */ + __IO uint32_t SR; /*!< RTC Status register, Address offset: 0x50 */ + __IO uint32_t MISR; /*!< RTC masked interrupt status register, Address offset: 0x54 */ + uint32_t RESERVED2; /*!< Reserved, Address offset: 0x58 */ + __IO uint32_t SCR; /*!< RTC status Clear register, Address offset: 0x5C */ + __IO uint32_t OR; /*!< RTC option register, Address offset: 0x60 */ + uint32_t RESERVED3[3];/*!< Reserved, Address offset: 0x64 */ + __IO uint32_t ALRABINR; /*!< RTC alarm A binary mode register, Address offset: 0x70 */ + __IO uint32_t ALRBBINR; /*!< RTC alarm B binary mode register, Address offset: 0x74 */ +} RTC_TypeDef; + +/** + * @brief Tamper and backup registers + */ +typedef struct +{ + __IO uint32_t CR1; /*!< TAMP control register 1, Address offset: 0x00 */ + __IO uint32_t CR2; /*!< TAMP control register 2, Address offset: 0x04 */ + __IO uint32_t CR3; /*!< TAMP control register 3, Address offset: 0x08 */ + __IO uint32_t FLTCR; /*!< TAMP filter control register, Address offset: 0x0C */ + __IO uint32_t ATCR1; /*!< TAMP filter control register 1 Address offset: 0x10 */ + __IO uint32_t ATSEEDR; /*!< TAMP active tamper seed register, Address offset: 0x14 */ + __IO uint32_t ATOR; /*!< TAMP active tamper output register, Address offset: 0x18 */ + __IO uint32_t ATCR2; /*!< TAMP filter control register 2, Address offset: 0x1C */ + __IO uint32_t SECCFGR; /*!< TAMP secure mode control register, Address offset: 0x20 */ + __IO uint32_t PRIVCFGR; /*!< TAMP privilege mode control register, Address offset: 0x24 */ + uint32_t RESERVED0; /*!< Reserved, Address offset: 0x28 */ + __IO uint32_t IER; /*!< TAMP interrupt enable register, Address offset: 0x2C */ + __IO uint32_t SR; /*!< TAMP status register, Address offset: 0x30 */ + __IO uint32_t MISR; /*!< TAMP masked interrupt status register, Address offset: 0x34 */ + uint32_t RESERVED1; /*!< Reserved, Address offset: 0x38 */ + __IO uint32_t SCR; /*!< TAMP status clear register, Address offset: 0x3C */ + __IO uint32_t COUNT1R; /*!< TAMP monotonic counter register, Address offset: 0x40 */ + uint32_t RESERVED2[3];/*!< Reserved, Address offset: 0x44 -- 0x4C */ + __IO uint32_t OR; /*!< TAMP option register, Address offset: 0x50 */ + __IO uint32_t ERCFGR; /*!< TAMP erase configuration register, Address offset: 0x54 */ + uint32_t RESERVED3[42];/*!< Reserved, Address offset: 0x58 -- 0xFC */ + __IO uint32_t BKP0R; /*!< TAMP backup register 0, Address offset: 0x100 */ + __IO uint32_t BKP1R; /*!< TAMP backup register 1, Address offset: 0x104 */ + __IO uint32_t BKP2R; /*!< TAMP backup register 2, Address offset: 0x108 */ + __IO uint32_t BKP3R; /*!< TAMP backup register 3, Address offset: 0x10C */ + __IO uint32_t BKP4R; /*!< TAMP backup register 4, Address offset: 0x110 */ + __IO uint32_t BKP5R; /*!< TAMP backup register 5, Address offset: 0x114 */ + __IO uint32_t BKP6R; /*!< TAMP backup register 6, Address offset: 0x118 */ + __IO uint32_t BKP7R; /*!< TAMP backup register 7, Address offset: 0x11C */ + __IO uint32_t BKP8R; /*!< TAMP backup register 8, Address offset: 0x120 */ + __IO uint32_t BKP9R; /*!< TAMP backup register 9, Address offset: 0x124 */ + __IO uint32_t BKP10R; /*!< TAMP backup register 10, Address offset: 0x128 */ + __IO uint32_t BKP11R; /*!< TAMP backup register 11, Address offset: 0x12C */ + __IO uint32_t BKP12R; /*!< TAMP backup register 12, Address offset: 0x130 */ + __IO uint32_t BKP13R; /*!< TAMP backup register 13, Address offset: 0x134 */ + __IO uint32_t BKP14R; /*!< TAMP backup register 14, Address offset: 0x138 */ + __IO uint32_t BKP15R; /*!< TAMP backup register 15, Address offset: 0x13C */ + __IO uint32_t BKP16R; /*!< TAMP backup register 16, Address offset: 0x140 */ + __IO uint32_t BKP17R; /*!< TAMP backup register 17, Address offset: 0x144 */ + __IO uint32_t BKP18R; /*!< TAMP backup register 18, Address offset: 0x148 */ + __IO uint32_t BKP19R; /*!< TAMP backup register 19, Address offset: 0x14C */ + __IO uint32_t BKP20R; /*!< TAMP backup register 20, Address offset: 0x150 */ + __IO uint32_t BKP21R; /*!< TAMP backup register 21, Address offset: 0x154 */ + __IO uint32_t BKP22R; /*!< TAMP backup register 22, Address offset: 0x158 */ + __IO uint32_t BKP23R; /*!< TAMP backup register 23, Address offset: 0x15C */ + __IO uint32_t BKP24R; /*!< TAMP backup register 24, Address offset: 0x160 */ + __IO uint32_t BKP25R; /*!< TAMP backup register 25, Address offset: 0x164 */ + __IO uint32_t BKP26R; /*!< TAMP backup register 26, Address offset: 0x168 */ + __IO uint32_t BKP27R; /*!< TAMP backup register 27, Address offset: 0x16C */ + __IO uint32_t BKP28R; /*!< TAMP backup register 28, Address offset: 0x170 */ + __IO uint32_t BKP29R; /*!< TAMP backup register 29, Address offset: 0x174 */ + __IO uint32_t BKP30R; /*!< TAMP backup register 30, Address offset: 0x178 */ + __IO uint32_t BKP31R; /*!< TAMP backup register 31, Address offset: 0x17C */ +} TAMP_TypeDef; + +/** + * @brief Universal Synchronous Asynchronous Receiver Transmitter + */ +typedef struct +{ + __IO uint32_t CR1; /*!< USART Control register 1, Address offset: 0x00 */ + __IO uint32_t CR2; /*!< USART Control register 2, Address offset: 0x04 */ + __IO uint32_t CR3; /*!< USART Control register 3, Address offset: 0x08 */ + __IO uint32_t BRR; /*!< USART Baud rate register, Address offset: 0x0C */ + __IO uint32_t GTPR; /*!< USART Guard time and prescaler register, Address offset: 0x10 */ + __IO uint32_t RTOR; /*!< USART Receiver Time Out register, Address offset: 0x14 */ + __IO uint32_t RQR; /*!< USART Request register, Address offset: 0x18 */ + __IO uint32_t ISR; /*!< USART Interrupt and status register, Address offset: 0x1C */ + __IO uint32_t ICR; /*!< USART Interrupt flag Clear register, Address offset: 0x20 */ + __IO uint32_t RDR; /*!< USART Receive Data register, Address offset: 0x24 */ + __IO uint32_t TDR; /*!< USART Transmit Data register, Address offset: 0x28 */ + __IO uint32_t PRESC; /*!< USART Prescaler register, Address offset: 0x2C */ +} USART_TypeDef; + +/** + * @brief System configuration, Boot and Security + */ +typedef struct +{ + uint32_t RESERVED1[4]; /*!< RESERVED1, Address offset: 0x00 - 0x0C */ + __IO uint32_t HDPLCR; /*!< SBS HDPL Control Register, Address offset: 0x10 */ + __IO uint32_t HDPLSR; /*!< SBS HDPL Status Register, Address offset: 0x14 */ + __IO uint32_t RESERVED2[2]; /*!< RESERVED2, Address offset: 0x18 - 0x1C */ + __IO uint32_t DBGCR; /*!< SBS Debug Control Register, Address offset: 0x20 */ + __IO uint32_t DBGLOCKR; /*!< SBS Debug Lock Register, Address offset: 0x24 */ + uint32_t RESERVED3[3]; /*!< RESERVED3, Address offset: 0x28 - 0x30 */ + uint32_t RESERVED4[36]; /*!< RESERVED4, Address offset: 0x34 - 0xC0 */ + uint32_t RESERVED6[15]; /*!< RESERVED6, Address offset: 0xC4 - 0xFC */ + __IO uint32_t PMCR; /*!< SBS Product Mode & Config Register, Address offset: 0x100 */ + __IO uint32_t FPUIMR; /*!< SBS FPU Interrupt Mask Register, Address offset: 0x104 */ + __IO uint32_t MESR; /*!< SBS Memory Erase Status Register, Address offset: 0x108 */ + uint32_t RESERVED7; /*!< RESERVED7, Address offset: 0x10C */ + __IO uint32_t CCCSR; /*!< SBS Compensation Cell Control & Status Register, Address offset: 0x110 */ + __IO uint32_t CCVALR; /*!< SBS Compensation Cell Value Register, Address offset: 0x114 */ + __IO uint32_t CCSWCR; /*!< SBS Compensation Cell for I/Os sw code Register, Address offset: 0x118 */ + __IO uint32_t RESERVED8; /*!< RESERVED8, Address offset: 0x11C */ + __IO uint32_t CFGR2; /*!< SBS Class B Register, Address offset: 0x120 */ + uint32_t RESERVED9[8]; /*!< RESERVED9, Address offset: 0x124 - 0x140 */ + __IO uint32_t CNSLCKR; /*!< SBS CPU Non-secure Lock Register, Address offset: 0x144 */ + uint32_t RESERVED10; /*!< RESERVED10, Address offset: 0x148 */ + __IO uint32_t ECCNMIR; /*!< SBS FLITF ECC NMI MASK Register, Address offset: 0x14C */ +} SBS_TypeDef; + + +/** + * @brief Universal Serial Bus Full Speed Dual Role Device + */ +typedef struct +{ + __IO uint32_t CHEP0R; /*!< USB Channel/Endpoint 0 register, Address offset: 0x00 */ + __IO uint32_t CHEP1R; /*!< USB Channel/Endpoint 1 register, Address offset: 0x04 */ + __IO uint32_t CHEP2R; /*!< USB Channel/Endpoint 2 register, Address offset: 0x08 */ + __IO uint32_t CHEP3R; /*!< USB Channel/Endpoint 3 register, Address offset: 0x0C */ + __IO uint32_t CHEP4R; /*!< USB Channel/Endpoint 4 register, Address offset: 0x10 */ + __IO uint32_t CHEP5R; /*!< USB Channel/Endpoint 5 register, Address offset: 0x14 */ + __IO uint32_t CHEP6R; /*!< USB Channel/Endpoint 6 register, Address offset: 0x18 */ + __IO uint32_t CHEP7R; /*!< USB Channel/Endpoint 7 register, Address offset: 0x1C */ + __IO uint32_t RESERVED0[8]; /*!< Reserved, */ + __IO uint32_t CNTR; /*!< Control register, Address offset: 0x40 */ + __IO uint32_t ISTR; /*!< Interrupt status register, Address offset: 0x44 */ + __IO uint32_t FNR; /*!< Frame number register, Address offset: 0x48 */ + __IO uint32_t DADDR; /*!< Device address register, Address offset: 0x4C */ + __IO uint32_t RESERVED1; /*!< Reserved */ + __IO uint32_t LPMCSR; /*!< LPM Control and Status register, Address offset: 0x54 */ + __IO uint32_t BCDR; /*!< Battery Charging detector register, Address offset: 0x58 */ +} USB_DRD_TypeDef; + +/** + * @brief Universal Serial Bus PacketMemoryArea Buffer Descriptor Table + */ +typedef struct +{ + __IO uint32_t TXBD; /*!= 6010050) + #pragma clang diagnostic pop +#elif defined (__GNUC__) + /* anonymous unions are enabled by default */ +#elif defined (__TMS470__) + /* anonymous unions are enabled by default */ +#elif defined (__TASKING__) + #pragma warning restore +#elif defined (__CSMC__) + /* anonymous unions are enabled by default */ +#else + #warning Not supported compiler type +#endif + + +/* =========================================================================================================================== */ +/* ================ Device Specific Peripheral Address Map ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup STM32H5xx_Peripheral_peripheralAddr + * @{ + */ + +/* Internal SRAMs size */ + +#define SRAM1_SIZE (0x4000UL) /*!< SRAM1=16k */ +#define SRAM2_SIZE (0x4000UL) /*!< SRAM2=16k */ +#define BKPSRAM_SIZE (0x0800UL) /*!< BKPSRAM=2k */ + +/* Flash, Peripheral and internal SRAMs base addresses - Non secure */ +#define FLASH_BASE_NS (0x08000000UL) /*!< FLASH (up to 128 KB) non-secure base address */ +#define SRAM1_BASE_NS (0x20000000UL) /*!< SRAM1 (16 KB) non-secure base address */ +#define SRAM2_BASE_NS (0x20004000UL) /*!< SRAM2 (16 KB) non-secure base address */ +#define PERIPH_BASE_NS (0x40000000UL) /*!< Peripheral non-secure base address */ + +/* Peripheral memory map - Non secure */ +#define APB1PERIPH_BASE_NS PERIPH_BASE_NS +#define APB2PERIPH_BASE_NS (PERIPH_BASE_NS + 0x00010000UL) +#define AHB1PERIPH_BASE_NS (PERIPH_BASE_NS + 0x00020000UL) +#define AHB2PERIPH_BASE_NS (PERIPH_BASE_NS + 0x02020000UL) +#define APB3PERIPH_BASE_NS (PERIPH_BASE_NS + 0x04000000UL) +#define AHB3PERIPH_BASE_NS (PERIPH_BASE_NS + 0x04020000UL) + +/*!< APB1 Non secure peripherals */ +#define TIM2_BASE_NS (APB1PERIPH_BASE_NS + 0x0000UL) +#define TIM3_BASE_NS (APB1PERIPH_BASE_NS + 0x0400UL) +#define TIM6_BASE_NS (APB1PERIPH_BASE_NS + 0x1000UL) +#define TIM7_BASE_NS (APB1PERIPH_BASE_NS + 0x1400UL) +#define WWDG_BASE_NS (APB1PERIPH_BASE_NS + 0x2C00UL) +#define IWDG_BASE_NS (APB1PERIPH_BASE_NS + 0x3000UL) +#define OPAMP1_BASE_NS (APB1PERIPH_BASE_NS + 0x3400UL) +#define SPI2_BASE_NS (APB1PERIPH_BASE_NS + 0x3800UL) +#define SPI3_BASE_NS (APB1PERIPH_BASE_NS + 0x3C00UL) +#define COMP1_BASE_NS (APB1PERIPH_BASE_NS + 0x4000UL) +#define USART2_BASE_NS (APB1PERIPH_BASE_NS + 0x4400UL) +#define USART3_BASE_NS (APB1PERIPH_BASE_NS + 0x4800UL) +#define I2C1_BASE_NS (APB1PERIPH_BASE_NS + 0x5400UL) +#define I2C2_BASE_NS (APB1PERIPH_BASE_NS + 0x5800UL) +#define I3C1_BASE_NS (APB1PERIPH_BASE_NS + 0x5C00UL) +#define CRS_BASE_NS (APB1PERIPH_BASE_NS + 0x6000UL) +#define DTS_BASE_NS (APB1PERIPH_BASE_NS + 0x8C00UL) +#define LPTIM2_BASE_NS (APB1PERIPH_BASE_NS + 0x9400UL) +#define FDCAN1_BASE_NS (APB1PERIPH_BASE_NS + 0xA400UL) +#define FDCAN_CONFIG_BASE_NS (APB1PERIPH_BASE_NS + 0xA500UL) +#define SRAMCAN_BASE_NS (APB1PERIPH_BASE_NS + 0xAC00UL) + +/*!< APB2 Non secure peripherals */ +#define TIM1_BASE_NS (APB2PERIPH_BASE_NS + 0x2C00UL) +#define SPI1_BASE_NS (APB2PERIPH_BASE_NS + 0x3000UL) +#define USART1_BASE_NS (APB2PERIPH_BASE_NS + 0x3800UL) +#define USB_DRD_BASE_NS (APB2PERIPH_BASE_NS + 0x6000UL) +#define USB_DRD_PMAADDR_NS (APB2PERIPH_BASE_NS + 0x6400UL) + +/*!< AHB1 Non secure peripherals */ +#define GPDMA1_BASE_NS AHB1PERIPH_BASE_NS +#define GPDMA2_BASE_NS (AHB1PERIPH_BASE_NS + 0x01000UL) +#define FLASH_R_BASE_NS (AHB1PERIPH_BASE_NS + 0x02000UL) +#define CRC_BASE_NS (AHB1PERIPH_BASE_NS + 0x03000UL) +#define RAMCFG_BASE_NS (AHB1PERIPH_BASE_NS + 0x06000UL) +#define ICACHE_BASE_NS (AHB1PERIPH_BASE_NS + 0x10400UL) +#define GTZC_TZSC1_BASE_NS (AHB1PERIPH_BASE_NS + 0x12400UL) +#define GTZC_MPCBB1_BASE_NS (AHB1PERIPH_BASE_NS + 0x12C00UL) +#define GTZC_MPCBB2_BASE_NS (AHB1PERIPH_BASE_NS + 0x13000UL) +#define BKPSRAM_BASE_NS (AHB1PERIPH_BASE_NS + 0x16400UL) + +#define GPDMA1_Channel0_BASE_NS (GPDMA1_BASE_NS + 0x0050UL) +#define GPDMA1_Channel1_BASE_NS (GPDMA1_BASE_NS + 0x00D0UL) +#define GPDMA1_Channel2_BASE_NS (GPDMA1_BASE_NS + 0x0150UL) +#define GPDMA1_Channel3_BASE_NS (GPDMA1_BASE_NS + 0x01D0UL) +#define GPDMA1_Channel4_BASE_NS (GPDMA1_BASE_NS + 0x0250UL) +#define GPDMA1_Channel5_BASE_NS (GPDMA1_BASE_NS + 0x02D0UL) +#define GPDMA1_Channel6_BASE_NS (GPDMA1_BASE_NS + 0x0350UL) +#define GPDMA1_Channel7_BASE_NS (GPDMA1_BASE_NS + 0x03D0UL) +#define GPDMA2_Channel0_BASE_NS (GPDMA2_BASE_NS + 0x0050UL) +#define GPDMA2_Channel1_BASE_NS (GPDMA2_BASE_NS + 0x00D0UL) +#define GPDMA2_Channel2_BASE_NS (GPDMA2_BASE_NS + 0x0150UL) +#define GPDMA2_Channel3_BASE_NS (GPDMA2_BASE_NS + 0x01D0UL) +#define GPDMA2_Channel4_BASE_NS (GPDMA2_BASE_NS + 0x0250UL) +#define GPDMA2_Channel5_BASE_NS (GPDMA2_BASE_NS + 0x02D0UL) +#define GPDMA2_Channel6_BASE_NS (GPDMA2_BASE_NS + 0x0350UL) +#define GPDMA2_Channel7_BASE_NS (GPDMA2_BASE_NS + 0x03D0UL) + +#define RAMCFG_SRAM1_BASE_NS (RAMCFG_BASE_NS) +#define RAMCFG_SRAM2_BASE_NS (RAMCFG_BASE_NS + 0x0040UL) +#define RAMCFG_BKPRAM_BASE_NS (RAMCFG_BASE_NS + 0x0100UL) + +/*!< AHB2 Non secure peripherals */ +#define GPIOA_BASE_NS (AHB2PERIPH_BASE_NS + 0x00000UL) +#define GPIOB_BASE_NS (AHB2PERIPH_BASE_NS + 0x00400UL) +#define GPIOC_BASE_NS (AHB2PERIPH_BASE_NS + 0x00800UL) +#define GPIOD_BASE_NS (AHB2PERIPH_BASE_NS + 0x00C00UL) +#define GPIOH_BASE_NS (AHB2PERIPH_BASE_NS + 0x01C00UL) +#define ADC1_BASE_NS (AHB2PERIPH_BASE_NS + 0x08000UL) +#define ADC12_COMMON_BASE_NS (AHB2PERIPH_BASE_NS + 0x08300UL) +#define DAC1_BASE_NS (AHB2PERIPH_BASE_NS + 0x08400UL) + +#define HASH_BASE_NS (AHB2PERIPH_BASE_NS + 0xA0400UL) +#define HASH_DIGEST_BASE_NS (AHB2PERIPH_BASE_NS + 0xA0710UL) +#define RNG_BASE_NS (AHB2PERIPH_BASE_NS + 0xA0800UL) + + +/*!< APB3 Non secure peripherals */ +#define SBS_BASE_NS (APB3PERIPH_BASE_NS + 0x0400UL) +#define LPUART1_BASE_NS (APB3PERIPH_BASE_NS + 0x2400UL) +#define I3C2_BASE_NS (APB3PERIPH_BASE_NS + 0x3000UL) +#define LPTIM1_BASE_NS (APB3PERIPH_BASE_NS + 0x4400UL) +#define RTC_BASE_NS (APB3PERIPH_BASE_NS + 0x7800UL) +#define TAMP_BASE_NS (APB3PERIPH_BASE_NS + 0x7C00UL) + +/*!< AHB3 Non secure peripherals */ +#define PWR_BASE_NS (AHB3PERIPH_BASE_NS + 0x0800UL) +#define RCC_BASE_NS (AHB3PERIPH_BASE_NS + 0x0C00UL) +#define EXTI_BASE_NS (AHB3PERIPH_BASE_NS + 0x2000UL) +#define DEBUG_BASE_NS (AHB3PERIPH_BASE_NS + 0x4000UL) + +/* Debug MCU registers base address */ +#define DBGMCU_BASE (0x44024000UL) + +#define PACKAGE_BASE (0x08FFF80EUL) /*!< Package data register base address */ +#define UID_BASE (0x08FFF800UL) /*!< Unique device ID register base address */ +#define FLASHSIZE_BASE (0x08FFF80CUL) /*!< Flash size data register base address */ + + +/* Internal Flash OTP Area */ +#define FLASH_OTP_BASE (0x08FFF000UL) /*!< FLASH OTP (one-time programmable) base address */ +#define FLASH_OTP_SIZE (0x800U) /*!< 2048 bytes OTP (one-time programmable) */ + +/* Flash system Area */ +#define FLASH_SYSTEM_BASE_NS (0x0BF80000UL) /*!< FLASH System non-secure base address */ +#define FLASH_SYSTEM_SIZE (0x8000U) /*!< 32 Kbytes system Flash */ + + +/*!< USB PMA SIZE */ +#define USB_DRD_PMA_SIZE (2048U) /*!< USB PMA Size 2Kbyte */ + +/*!< Non Secure Service Library */ +/************ RSSLIB SAU system Flash region definition constants *************/ +#define NSSLIB_SYS_FLASH_NS_PFUNC_START (0xBF8FE6CUL) +#define NSSLIB_SYS_FLASH_NS_PFUNC_END (0xBF8FE74UL) + +/************ RSSLIB function return constants ********************************/ +#define NSSLIB_ERROR (0xF5F5F5F5UL) +#define NSSLIB_SUCCESS (0xEAEAEAEAUL) + +/*!< RSSLIB pointer function structure address definition */ +#define NSSLIB_PFUNC_BASE (0xBF8FE6CUL) +#define NSSLIB_PFUNC ((NSSLIB_pFunc_TypeDef *)NSSLIB_PFUNC_BASE) + +/** + * @brief Prototype of RSSLIB Jump to HDP level2 Function + * @detail This function increments HDP level up to HDP level 2 + * Then it enables the MPU region corresponding the MPU index + * provided as input parameter. The Vector Table shall be located + * within this MPU region. + * Then it jumps to the reset handler present within the + * Vector table. The function does not return on successful execution. + * @param pointer on the vector table containing the reset handler the function + * jumps to. + * @param MPU region index containing the vector table + * jumps to. + * @retval NSSLIB_RSS_ERROR on error on input parameter, otherwise does not return. + */ +typedef uint32_t (*NSSLIB_S_JumpHDPlvl2_TypeDef)(uint32_t VectorTableAddr, uint32_t MPUIndex); + +/** + * @brief Prototype of RSSLIB Jump to HDP level3 Function + * @detail This function increments HDP level up to HDP level 3 + * Then it enables the MPU region corresponding the MPU index + * provided as input parameter. The Vector Table shall be located + * within this MPU region. + * Then it jumps to the reset handler present within the + * Vector table. The function does not return on successful execution. + * @param pointer on the vector table containing the reset handler the function + * jumps to. + * @param MPU region index containing the vector table + * jumps to. + * @retval NSSLIB_RSS_ERROR on error on input parameter, otherwise does not return. + */ +typedef uint32_t (*NSSLIB_S_JumpHDPlvl3_TypeDef)(uint32_t VectorTableAddr, uint32_t MPUIndex); + +/** + * @brief RSSLib secure callable function pointer structure + */ +typedef struct +{ + __IM NSSLIB_S_JumpHDPlvl2_TypeDef JumpHDPLvl2; + __IM NSSLIB_S_JumpHDPlvl3_TypeDef JumpHDPLvl3; +} NSSLIB_pFunc_TypeDef; + + +/** @} */ /* End of group STM32H5xx_Peripheral_peripheralAddr */ + + +/* =========================================================================================================================== */ +/* ================ Peripheral declaration ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup STM32H5xx_Peripheral_declaration + * @{ + */ + +/*!< APB1 Non secure peripherals */ +#define TIM2_NS ((TIM_TypeDef *)TIM2_BASE_NS) +#define TIM3_NS ((TIM_TypeDef *)TIM3_BASE_NS) +#define TIM6_NS ((TIM_TypeDef *)TIM6_BASE_NS) +#define TIM7_NS ((TIM_TypeDef *)TIM7_BASE_NS) +#define WWDG_NS ((WWDG_TypeDef *)WWDG_BASE_NS) +#define IWDG_NS ((IWDG_TypeDef *)IWDG_BASE_NS) +#define OPAMP1_NS ((OPAMP_TypeDef *)OPAMP1_BASE_NS) +#define SPI2_NS ((SPI_TypeDef *)SPI2_BASE_NS) +#define SPI3_NS ((SPI_TypeDef *)SPI3_BASE_NS) +#define COMP1_NS ((COMP_TypeDef *)COMP1_BASE_NS) +#define USART2_NS ((USART_TypeDef *)USART2_BASE_NS) +#define USART3_NS ((USART_TypeDef *)USART3_BASE_NS) +#define I2C1_NS ((I2C_TypeDef *)I2C1_BASE_NS) +#define I2C2_NS ((I2C_TypeDef *)I2C2_BASE_NS) +#define I3C1_NS ((I3C_TypeDef *)I3C1_BASE_NS) +#define CRS_NS ((CRS_TypeDef *)CRS_BASE_NS) +#define DTS_NS ((DTS_TypeDef *)DTS_BASE_NS) +#define LPTIM2_NS ((LPTIM_TypeDef *)LPTIM2_BASE_NS) +#define FDCAN1_NS ((FDCAN_GlobalTypeDef *)FDCAN1_BASE_NS) +#define FDCAN_CONFIG_NS ((FDCAN_Config_TypeDef *)FDCAN_CONFIG_BASE_NS) + +/*!< APB2 Non secure peripherals */ +#define TIM1_NS ((TIM_TypeDef *) TIM1_BASE_NS) +#define SPI1_NS ((SPI_TypeDef *) SPI1_BASE_NS) +#define USART1_NS ((USART_TypeDef *) USART1_BASE_NS) +#define USB_DRD_FS_NS ((USB_DRD_TypeDef *) USB_DRD_BASE_NS) +#define USB_DRD_PMA_BUFF_NS ((USB_DRD_PMABuffDescTypeDef *) USB_DRD_PMAADDR_NS) + +/*!< AHB1 Non secure peripherals */ +#define GPDMA1_NS ((DMA_TypeDef *) GPDMA1_BASE_NS) +#define GPDMA2_NS ((DMA_TypeDef *) GPDMA2_BASE_NS) +#define FLASH_NS ((FLASH_TypeDef *) FLASH_R_BASE_NS) +#define CRC_NS ((CRC_TypeDef *) CRC_BASE_NS) +#define RAMCFG_SRAM1_NS ((RAMCFG_TypeDef *) RAMCFG_SRAM1_BASE_NS) +#define RAMCFG_SRAM2_NS ((RAMCFG_TypeDef *) RAMCFG_SRAM2_BASE_NS) +#define RAMCFG_BKPRAM_NS ((RAMCFG_TypeDef *) RAMCFG_BKPRAM_BASE_NS) +#define ICACHE_NS ((ICACHE_TypeDef *) ICACHE_BASE_NS) +#define GTZC_TZSC1_NS ((GTZC_TZSC_TypeDef *) GTZC_TZSC1_BASE_NS) +#define GTZC_MPCBB1_NS ((GTZC_MPCBB_TypeDef *) GTZC_MPCBB1_BASE_NS) +#define GTZC_MPCBB2_NS ((GTZC_MPCBB_TypeDef *) GTZC_MPCBB2_BASE_NS) +#define GPDMA1_Channel0_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel0_BASE_NS) +#define GPDMA1_Channel1_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel1_BASE_NS) +#define GPDMA1_Channel2_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel2_BASE_NS) +#define GPDMA1_Channel3_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel3_BASE_NS) +#define GPDMA1_Channel4_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel4_BASE_NS) +#define GPDMA1_Channel5_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel5_BASE_NS) +#define GPDMA1_Channel6_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel6_BASE_NS) +#define GPDMA1_Channel7_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel7_BASE_NS) +#define GPDMA2_Channel0_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel0_BASE_NS) +#define GPDMA2_Channel1_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel1_BASE_NS) +#define GPDMA2_Channel2_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel2_BASE_NS) +#define GPDMA2_Channel3_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel3_BASE_NS) +#define GPDMA2_Channel4_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel4_BASE_NS) +#define GPDMA2_Channel5_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel5_BASE_NS) +#define GPDMA2_Channel6_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel6_BASE_NS) +#define GPDMA2_Channel7_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel7_BASE_NS) + +/*!< AHB2 Non secure peripherals */ +#define GPIOA_NS ((GPIO_TypeDef *) GPIOA_BASE_NS) +#define GPIOB_NS ((GPIO_TypeDef *) GPIOB_BASE_NS) +#define GPIOC_NS ((GPIO_TypeDef *) GPIOC_BASE_NS) +#define GPIOD_NS ((GPIO_TypeDef *) GPIOD_BASE_NS) +#define GPIOH_NS ((GPIO_TypeDef *) GPIOH_BASE_NS) +#define ADC1_NS ((ADC_TypeDef *) ADC1_BASE_NS) +#define ADC12_COMMON_NS ((ADC_Common_TypeDef *) ADC12_COMMON_BASE_NS) +#define DAC1_NS ((DAC_TypeDef *) DAC1_BASE_NS) +#define HASH_NS ((HASH_TypeDef *) HASH_BASE_NS) +#define HASH_DIGEST_NS ((HASH_DIGEST_TypeDef *) HASH_DIGEST_BASE_NS) +#define RNG_NS ((RNG_TypeDef *) RNG_BASE_NS) + + +/*!< APB3 Non secure peripherals */ +#define SBS_NS ((SBS_TypeDef *) SBS_BASE_NS) +#define LPUART1_NS ((USART_TypeDef *) LPUART1_BASE_NS) +#define I3C2_NS ((I3C_TypeDef *) I3C2_BASE_NS) +#define LPTIM1_NS ((LPTIM_TypeDef *) LPTIM1_BASE_NS) +#define RTC_NS ((RTC_TypeDef *) RTC_BASE_NS) +#define TAMP_NS ((TAMP_TypeDef *) TAMP_BASE_NS) + +/*!< AHB3 Non secure peripherals */ +#define PWR_NS ((PWR_TypeDef *) PWR_BASE_NS) +#define RCC_NS ((RCC_TypeDef *) RCC_BASE_NS) +#define EXTI_NS ((EXTI_TypeDef *) EXTI_BASE_NS) + + +#define DBGMCU ((DBGMCU_TypeDef *) DBGMCU_BASE) + + +/*!< Memory base addresses for Non secure peripherals */ +#define FLASH_BASE FLASH_BASE_NS +#define FLASH_SYSTEM_BASE FLASH_SYSTEM_BASE_NS +#define SRAM1_BASE SRAM1_BASE_NS +#define SRAM2_BASE SRAM2_BASE_NS +#define BKPSRAM_BASE BKPSRAM_BASE_NS + +#define PERIPH_BASE PERIPH_BASE_NS +#define APB1PERIPH_BASE APB1PERIPH_BASE_NS +#define APB2PERIPH_BASE APB2PERIPH_BASE_NS +#define APB3PERIPH_BASE APB3PERIPH_BASE_NS +#define AHB1PERIPH_BASE AHB1PERIPH_BASE_NS +#define AHB2PERIPH_BASE AHB2PERIPH_BASE_NS +#define AHB3PERIPH_BASE AHB3PERIPH_BASE_NS + +/*!< Instance aliases and base addresses for Non secure peripherals */ +#define RCC RCC_NS +#define RCC_BASE RCC_BASE_NS + +#define DTS DTS_NS +#define DTS_BASE DTS_BASE_NS + +#define FLASH FLASH_NS +#define FLASH_R_BASE FLASH_R_BASE_NS + +#define GPDMA1 GPDMA1_NS +#define GPDMA1_BASE GPDMA1_BASE_NS + +#define GPDMA1_Channel0 GPDMA1_Channel0_NS +#define GPDMA1_Channel0_BASE GPDMA1_Channel0_BASE_NS + +#define GPDMA1_Channel1 GPDMA1_Channel1_NS +#define GPDMA1_Channel1_BASE GPDMA1_Channel1_BASE_NS + +#define GPDMA1_Channel2 GPDMA1_Channel2_NS +#define GPDMA1_Channel2_BASE GPDMA1_Channel2_BASE_NS + +#define GPDMA1_Channel3 GPDMA1_Channel3_NS +#define GPDMA1_Channel3_BASE GPDMA1_Channel3_BASE_NS + +#define GPDMA1_Channel4 GPDMA1_Channel4_NS +#define GPDMA1_Channel4_BASE GPDMA1_Channel4_BASE_NS + +#define GPDMA1_Channel5 GPDMA1_Channel5_NS +#define GPDMA1_Channel5_BASE GPDMA1_Channel5_BASE_NS + +#define GPDMA1_Channel6 GPDMA1_Channel6_NS +#define GPDMA1_Channel6_BASE GPDMA1_Channel6_BASE_NS + +#define GPDMA1_Channel7 GPDMA1_Channel7_NS +#define GPDMA1_Channel7_BASE GPDMA1_Channel7_BASE_NS + +#define GPDMA2 GPDMA2_NS +#define GPDMA2_BASE GPDMA2_BASE_NS + +#define GPDMA2_Channel0 GPDMA2_Channel0_NS +#define GPDMA2_Channel0_BASE GPDMA2_Channel0_BASE_NS + +#define GPDMA2_Channel1 GPDMA2_Channel1_NS +#define GPDMA2_Channel1_BASE GPDMA2_Channel1_BASE_NS + +#define GPDMA2_Channel2 GPDMA2_Channel2_NS +#define GPDMA2_Channel2_BASE GPDMA2_Channel2_BASE_NS + +#define GPDMA2_Channel3 GPDMA2_Channel3_NS +#define GPDMA2_Channel3_BASE GPDMA2_Channel3_BASE_NS + +#define GPDMA2_Channel4 GPDMA2_Channel4_NS +#define GPDMA2_Channel4_BASE GPDMA2_Channel4_BASE_NS + +#define GPDMA2_Channel5 GPDMA2_Channel5_NS +#define GPDMA2_Channel5_BASE GPDMA2_Channel5_BASE_NS + +#define GPDMA2_Channel6 GPDMA2_Channel6_NS +#define GPDMA2_Channel6_BASE GPDMA2_Channel6_BASE_NS + +#define GPDMA2_Channel7 GPDMA2_Channel7_NS +#define GPDMA2_Channel7_BASE GPDMA2_Channel7_BASE_NS + +#define GPIOA GPIOA_NS +#define GPIOA_BASE GPIOA_BASE_NS + +#define GPIOB GPIOB_NS +#define GPIOB_BASE GPIOB_BASE_NS + +#define GPIOC GPIOC_NS +#define GPIOC_BASE GPIOC_BASE_NS + +#define GPIOD GPIOD_NS +#define GPIOD_BASE GPIOD_BASE_NS + +#define GPIOH GPIOH_NS +#define GPIOH_BASE GPIOH_BASE_NS + +#define PWR PWR_NS +#define PWR_BASE PWR_BASE_NS + +#define RAMCFG_SRAM1 RAMCFG_SRAM1_NS +#define RAMCFG_SRAM1_BASE RAMCFG_SRAM1_BASE_NS + +#define RAMCFG_SRAM2 RAMCFG_SRAM2_NS +#define RAMCFG_SRAM2_BASE RAMCFG_SRAM2_BASE_NS + +#define RAMCFG_BKPRAM RAMCFG_BKPRAM_NS +#define RAMCFG_BKPRAM_BASE RAMCFG_BKPRAM_BASE_NS + +#define EXTI EXTI_NS +#define EXTI_BASE EXTI_BASE_NS + +#define ICACHE ICACHE_NS +#define ICACHE_BASE ICACHE_BASE_NS + +#define GTZC_TZSC1 GTZC_TZSC1_NS +#define GTZC_TZSC1_BASE GTZC_TZSC1_BASE_NS + +#define GTZC_MPCBB1 GTZC_MPCBB1_NS +#define GTZC_MPCBB1_BASE GTZC_MPCBB1_BASE_NS + +#define GTZC_MPCBB2 GTZC_MPCBB2_NS +#define GTZC_MPCBB2_BASE GTZC_MPCBB2_BASE_NS + +#define RTC RTC_NS +#define RTC_BASE RTC_BASE_NS + +#define TAMP TAMP_NS +#define TAMP_BASE TAMP_BASE_NS + +#define TIM1 TIM1_NS +#define TIM1_BASE TIM1_BASE_NS + +#define TIM2 TIM2_NS +#define TIM2_BASE TIM2_BASE_NS + +#define TIM3 TIM3_NS +#define TIM3_BASE TIM3_BASE_NS + +#define TIM6 TIM6_NS +#define TIM6_BASE TIM6_BASE_NS + +#define TIM7 TIM7_NS +#define TIM7_BASE TIM7_BASE_NS + +#define WWDG WWDG_NS +#define WWDG_BASE WWDG_BASE_NS + +#define IWDG IWDG_NS +#define IWDG_BASE IWDG_BASE_NS + +#define OPAMP1 OPAMP1_NS +#define OPAMP1_BASE OPAMP1_BASE_NS + +#define SPI1 SPI1_NS +#define SPI1_BASE SPI1_BASE_NS + +#define SPI2 SPI2_NS +#define SPI2_BASE SPI2_BASE_NS + +#define SPI3 SPI3_NS +#define SPI3_BASE SPI3_BASE_NS + +#define COMP1 COMP1_NS +#define COMP1_BASE COMP1_BASE_NS + +#define USART1 USART1_NS +#define USART1_BASE USART1_BASE_NS + +#define USART2 USART2_NS +#define USART2_BASE USART2_BASE_NS + +#define USART3 USART3_NS +#define USART3_BASE USART3_BASE_NS + +#define I2C1 I2C1_NS +#define I2C1_BASE I2C1_BASE_NS + +#define I2C2 I2C2_NS +#define I2C2_BASE I2C2_BASE_NS + +#define I3C1 I3C1_NS +#define I3C1_BASE I3C1_BASE_NS + +#define I3C2 I3C2_NS +#define I3C2_BASE I3C2_BASE_NS + +#define CRS CRS_NS +#define CRS_BASE CRS_BASE_NS + +#define FDCAN1 FDCAN1_NS +#define FDCAN1_BASE FDCAN1_BASE_NS + +#define FDCAN_CONFIG FDCAN_CONFIG_NS +#define FDCAN_CONFIG_BASE FDCAN_CONFIG_BASE_NS +#define SRAMCAN_BASE SRAMCAN_BASE_NS + +#define DAC1 DAC1_NS +#define DAC1_BASE DAC1_BASE_NS + +#define LPTIM1 LPTIM1_NS +#define LPTIM1_BASE LPTIM1_BASE_NS + +#define LPTIM2 LPTIM2_NS +#define LPTIM2_BASE LPTIM2_BASE_NS + +#define LPUART1 LPUART1_NS +#define LPUART1_BASE LPUART1_BASE_NS + +#define SBS SBS_NS +#define SBS_BASE SBS_BASE_NS + +#define USB_DRD_FS USB_DRD_FS_NS +#define USB_DRD_FS_BASE USB_DRD_BASE_NS +#define USB_DRD_PMAADDR USB_DRD_PMAADDR_NS +#define USB_DRD_PMA_BUFF USB_DRD_PMA_BUFF_NS + +#define CRC CRC_NS +#define CRC_BASE CRC_BASE_NS + +#define ADC1 ADC1_NS +#define ADC1_BASE ADC1_BASE_NS + +#define ADC12_COMMON ADC12_COMMON_NS +#define ADC12_COMMON_BASE ADC12_COMMON_BASE_NS + +#define HASH HASH_NS +#define HASH_BASE HASH_BASE_NS + +#define HASH_DIGEST HASH_DIGEST_NS +#define HASH_DIGEST_BASE HASH_DIGEST_BASE_NS + +#define RNG RNG_NS +#define RNG_BASE RNG_BASE_NS + + +/******************************************************************************/ +/* */ +/* Analog to Digital Converter */ +/* */ +/******************************************************************************/ +/******************** Bit definition for ADC_ISR register *******************/ +#define ADC_ISR_ADRDY_Pos (0U) +#define ADC_ISR_ADRDY_Msk (0x1UL << ADC_ISR_ADRDY_Pos) /*!< 0x00000001 */ +#define ADC_ISR_ADRDY ADC_ISR_ADRDY_Msk /*!< ADC ready flag */ +#define ADC_ISR_EOSMP_Pos (1U) +#define ADC_ISR_EOSMP_Msk (0x1UL << ADC_ISR_EOSMP_Pos) /*!< 0x00000002 */ +#define ADC_ISR_EOSMP ADC_ISR_EOSMP_Msk /*!< ADC group regular end of sampling flag */ +#define ADC_ISR_EOC_Pos (2U) +#define ADC_ISR_EOC_Msk (0x1UL << ADC_ISR_EOC_Pos) /*!< 0x00000004 */ +#define ADC_ISR_EOC ADC_ISR_EOC_Msk /*!< ADC group regular end of unitary conversion flag */ +#define ADC_ISR_EOS_Pos (3U) +#define ADC_ISR_EOS_Msk (0x1UL << ADC_ISR_EOS_Pos) /*!< 0x00000008 */ +#define ADC_ISR_EOS ADC_ISR_EOS_Msk /*!< ADC group regular end of sequence conversions flag */ +#define ADC_ISR_OVR_Pos (4U) +#define ADC_ISR_OVR_Msk (0x1UL << ADC_ISR_OVR_Pos) /*!< 0x00000010 */ +#define ADC_ISR_OVR ADC_ISR_OVR_Msk /*!< ADC group regular overrun flag */ +#define ADC_ISR_JEOC_Pos (5U) +#define ADC_ISR_JEOC_Msk (0x1UL << ADC_ISR_JEOC_Pos) /*!< 0x00000020 */ +#define ADC_ISR_JEOC ADC_ISR_JEOC_Msk /*!< ADC group injected end of unitary conversion flag */ +#define ADC_ISR_JEOS_Pos (6U) +#define ADC_ISR_JEOS_Msk (0x1UL << ADC_ISR_JEOS_Pos) /*!< 0x00000040 */ +#define ADC_ISR_JEOS ADC_ISR_JEOS_Msk /*!< ADC group injected end of sequence conversions flag */ +#define ADC_ISR_AWD1_Pos (7U) +#define ADC_ISR_AWD1_Msk (0x1UL << ADC_ISR_AWD1_Pos) /*!< 0x00000080 */ +#define ADC_ISR_AWD1 ADC_ISR_AWD1_Msk /*!< ADC analog watchdog 1 flag */ +#define ADC_ISR_AWD2_Pos (8U) +#define ADC_ISR_AWD2_Msk (0x1UL << ADC_ISR_AWD2_Pos) /*!< 0x00000100 */ +#define ADC_ISR_AWD2 ADC_ISR_AWD2_Msk /*!< ADC analog watchdog 2 flag */ +#define ADC_ISR_AWD3_Pos (9U) +#define ADC_ISR_AWD3_Msk (0x1UL << ADC_ISR_AWD3_Pos) /*!< 0x00000200 */ +#define ADC_ISR_AWD3 ADC_ISR_AWD3_Msk /*!< ADC analog watchdog 3 flag */ +#define ADC_ISR_JQOVF_Pos (10U) +#define ADC_ISR_JQOVF_Msk (0x1UL << ADC_ISR_JQOVF_Pos) /*!< 0x00000400 */ +#define ADC_ISR_JQOVF ADC_ISR_JQOVF_Msk /*!< ADC group injected contexts queue overflow flag */ + +/******************** Bit definition for ADC_IER register *******************/ +#define ADC_IER_ADRDYIE_Pos (0U) +#define ADC_IER_ADRDYIE_Msk (0x1UL << ADC_IER_ADRDYIE_Pos) /*!< 0x00000001 */ +#define ADC_IER_ADRDYIE ADC_IER_ADRDYIE_Msk /*!< ADC ready interrupt */ +#define ADC_IER_EOSMPIE_Pos (1U) +#define ADC_IER_EOSMPIE_Msk (0x1UL << ADC_IER_EOSMPIE_Pos) /*!< 0x00000002 */ +#define ADC_IER_EOSMPIE ADC_IER_EOSMPIE_Msk /*!< ADC group regular end of sampling interrupt */ +#define ADC_IER_EOCIE_Pos (2U) +#define ADC_IER_EOCIE_Msk (0x1UL << ADC_IER_EOCIE_Pos) /*!< 0x00000004 */ +#define ADC_IER_EOCIE ADC_IER_EOCIE_Msk /*!< ADC group regular end of unitary conversion interrupt */ +#define ADC_IER_EOSIE_Pos (3U) +#define ADC_IER_EOSIE_Msk (0x1UL << ADC_IER_EOSIE_Pos) /*!< 0x00000008 */ +#define ADC_IER_EOSIE ADC_IER_EOSIE_Msk /*!< ADC group regular end of sequence conversions interrupt */ +#define ADC_IER_OVRIE_Pos (4U) +#define ADC_IER_OVRIE_Msk (0x1UL << ADC_IER_OVRIE_Pos) /*!< 0x00000010 */ +#define ADC_IER_OVRIE ADC_IER_OVRIE_Msk /*!< ADC group regular overrun interrupt */ +#define ADC_IER_JEOCIE_Pos (5U) +#define ADC_IER_JEOCIE_Msk (0x1UL << ADC_IER_JEOCIE_Pos) /*!< 0x00000020 */ +#define ADC_IER_JEOCIE ADC_IER_JEOCIE_Msk /*!< ADC group injected end of unitary conversion interrupt */ +#define ADC_IER_JEOSIE_Pos (6U) +#define ADC_IER_JEOSIE_Msk (0x1UL << ADC_IER_JEOSIE_Pos) /*!< 0x00000040 */ +#define ADC_IER_JEOSIE ADC_IER_JEOSIE_Msk /*!< ADC group injected end of sequence conversions interrupt */ +#define ADC_IER_AWD1IE_Pos (7U) +#define ADC_IER_AWD1IE_Msk (0x1UL << ADC_IER_AWD1IE_Pos) /*!< 0x00000080 */ +#define ADC_IER_AWD1IE ADC_IER_AWD1IE_Msk /*!< ADC analog watchdog 1 interrupt */ +#define ADC_IER_AWD2IE_Pos (8U) +#define ADC_IER_AWD2IE_Msk (0x1UL << ADC_IER_AWD2IE_Pos) /*!< 0x00000100 */ +#define ADC_IER_AWD2IE ADC_IER_AWD2IE_Msk /*!< ADC analog watchdog 2 interrupt */ +#define ADC_IER_AWD3IE_Pos (9U) +#define ADC_IER_AWD3IE_Msk (0x1UL << ADC_IER_AWD3IE_Pos) /*!< 0x00000200 */ +#define ADC_IER_AWD3IE ADC_IER_AWD3IE_Msk /*!< ADC analog watchdog 3 interrupt */ +#define ADC_IER_JQOVFIE_Pos (10U) +#define ADC_IER_JQOVFIE_Msk (0x1UL << ADC_IER_JQOVFIE_Pos) /*!< 0x00000400 */ +#define ADC_IER_JQOVFIE ADC_IER_JQOVFIE_Msk /*!< ADC group injected contexts queue overflow interrupt */ + +/******************** Bit definition for ADC_CR register ********************/ +#define ADC_CR_ADEN_Pos (0U) +#define ADC_CR_ADEN_Msk (0x1UL << ADC_CR_ADEN_Pos) /*!< 0x00000001 */ +#define ADC_CR_ADEN ADC_CR_ADEN_Msk /*!< ADC enable */ +#define ADC_CR_ADDIS_Pos (1U) +#define ADC_CR_ADDIS_Msk (0x1UL << ADC_CR_ADDIS_Pos) /*!< 0x00000002 */ +#define ADC_CR_ADDIS ADC_CR_ADDIS_Msk /*!< ADC disable */ +#define ADC_CR_ADSTART_Pos (2U) +#define ADC_CR_ADSTART_Msk (0x1UL << ADC_CR_ADSTART_Pos) /*!< 0x00000004 */ +#define ADC_CR_ADSTART ADC_CR_ADSTART_Msk /*!< ADC group regular conversion start */ +#define ADC_CR_JADSTART_Pos (3U) +#define ADC_CR_JADSTART_Msk (0x1UL << ADC_CR_JADSTART_Pos) /*!< 0x00000008 */ +#define ADC_CR_JADSTART ADC_CR_JADSTART_Msk /*!< ADC group injected conversion start */ +#define ADC_CR_ADSTP_Pos (4U) +#define ADC_CR_ADSTP_Msk (0x1UL << ADC_CR_ADSTP_Pos) /*!< 0x00000010 */ +#define ADC_CR_ADSTP ADC_CR_ADSTP_Msk /*!< ADC group regular conversion stop */ +#define ADC_CR_JADSTP_Pos (5U) +#define ADC_CR_JADSTP_Msk (0x1UL << ADC_CR_JADSTP_Pos) /*!< 0x00000020 */ +#define ADC_CR_JADSTP ADC_CR_JADSTP_Msk /*!< ADC group injected conversion stop */ +#define ADC_CR_ADVREGEN_Pos (28U) +#define ADC_CR_ADVREGEN_Msk (0x1UL << ADC_CR_ADVREGEN_Pos) /*!< 0x10000000 */ +#define ADC_CR_ADVREGEN ADC_CR_ADVREGEN_Msk /*!< ADC voltage regulator enable */ +#define ADC_CR_DEEPPWD_Pos (29U) +#define ADC_CR_DEEPPWD_Msk (0x1UL << ADC_CR_DEEPPWD_Pos) /*!< 0x20000000 */ +#define ADC_CR_DEEPPWD ADC_CR_DEEPPWD_Msk /*!< ADC deep power down enable */ +#define ADC_CR_ADCALDIF_Pos (30U) +#define ADC_CR_ADCALDIF_Msk (0x1UL << ADC_CR_ADCALDIF_Pos) /*!< 0x40000000 */ +#define ADC_CR_ADCALDIF ADC_CR_ADCALDIF_Msk /*!< ADC differential mode for calibration */ +#define ADC_CR_ADCAL_Pos (31U) +#define ADC_CR_ADCAL_Msk (0x1UL << ADC_CR_ADCAL_Pos) /*!< 0x80000000 */ +#define ADC_CR_ADCAL ADC_CR_ADCAL_Msk /*!< ADC calibration */ + +/******************** Bit definition for ADC_CFGR register ******************/ +#define ADC_CFGR_DMAEN_Pos (0U) +#define ADC_CFGR_DMAEN_Msk (0x1UL << ADC_CFGR_DMAEN_Pos) /*!< 0x00000001 */ +#define ADC_CFGR_DMAEN ADC_CFGR_DMAEN_Msk /*!< ADC DMA transfer enable */ +#define ADC_CFGR_DMACFG_Pos (1U) +#define ADC_CFGR_DMACFG_Msk (0x1UL << ADC_CFGR_DMACFG_Pos) /*!< 0x00000002 */ +#define ADC_CFGR_DMACFG ADC_CFGR_DMACFG_Msk /*!< ADC DMA transfer configuration */ + +#define ADC_CFGR_RES_Pos (3U) +#define ADC_CFGR_RES_Msk (0x3UL << ADC_CFGR_RES_Pos) /*!< 0x00000018 */ +#define ADC_CFGR_RES ADC_CFGR_RES_Msk /*!< ADC data resolution */ +#define ADC_CFGR_RES_0 (0x1UL << ADC_CFGR_RES_Pos) /*!< 0x00000008 */ +#define ADC_CFGR_RES_1 (0x2UL << ADC_CFGR_RES_Pos) /*!< 0x00000010 */ + +#define ADC_CFGR_EXTSEL_Pos (5U) +#define ADC_CFGR_EXTSEL_Msk (0x1FUL << ADC_CFGR_EXTSEL_Pos) /*!< 0x000003E0 */ +#define ADC_CFGR_EXTSEL ADC_CFGR_EXTSEL_Msk /*!< ADC group regular external trigger source */ +#define ADC_CFGR_EXTSEL_0 (0x1UL << ADC_CFGR_EXTSEL_Pos) /*!< 0x00000020 */ +#define ADC_CFGR_EXTSEL_1 (0x2UL << ADC_CFGR_EXTSEL_Pos) /*!< 0x00000040 */ +#define ADC_CFGR_EXTSEL_2 (0x4UL << ADC_CFGR_EXTSEL_Pos) /*!< 0x00000080 */ +#define ADC_CFGR_EXTSEL_3 (0x8UL << ADC_CFGR_EXTSEL_Pos) /*!< 0x00000100 */ +#define ADC_CFGR_EXTSEL_4 (0x10UL << ADC_CFGR_EXTSEL_Pos) /*!< 0x00000200 */ + +#define ADC_CFGR_EXTEN_Pos (10U) +#define ADC_CFGR_EXTEN_Msk (0x3UL << ADC_CFGR_EXTEN_Pos) /*!< 0x00000C00 */ +#define ADC_CFGR_EXTEN ADC_CFGR_EXTEN_Msk /*!< ADC group regular external trigger polarity */ +#define ADC_CFGR_EXTEN_0 (0x1UL << ADC_CFGR_EXTEN_Pos) /*!< 0x00000400 */ +#define ADC_CFGR_EXTEN_1 (0x2UL << ADC_CFGR_EXTEN_Pos) /*!< 0x00000800 */ + +#define ADC_CFGR_OVRMOD_Pos (12U) +#define ADC_CFGR_OVRMOD_Msk (0x1UL << ADC_CFGR_OVRMOD_Pos) /*!< 0x00001000 */ +#define ADC_CFGR_OVRMOD ADC_CFGR_OVRMOD_Msk /*!< ADC group regular overrun configuration */ +#define ADC_CFGR_CONT_Pos (13U) +#define ADC_CFGR_CONT_Msk (0x1UL << ADC_CFGR_CONT_Pos) /*!< 0x00002000 */ +#define ADC_CFGR_CONT ADC_CFGR_CONT_Msk /*!< ADC group regular continuous conversion mode */ +#define ADC_CFGR_AUTDLY_Pos (14U) +#define ADC_CFGR_AUTDLY_Msk (0x1UL << ADC_CFGR_AUTDLY_Pos) /*!< 0x00004000 */ +#define ADC_CFGR_AUTDLY ADC_CFGR_AUTDLY_Msk /*!< ADC low power auto wait */ +#define ADC_CFGR_ALIGN_Pos (15U) +#define ADC_CFGR_ALIGN_Msk (0x1UL << ADC_CFGR_ALIGN_Pos) /*!< 0x00008000 */ +#define ADC_CFGR_ALIGN ADC_CFGR_ALIGN_Msk /*!< ADC data alignment */ +#define ADC_CFGR_DISCEN_Pos (16U) +#define ADC_CFGR_DISCEN_Msk (0x1UL << ADC_CFGR_DISCEN_Pos) /*!< 0x00010000 */ +#define ADC_CFGR_DISCEN ADC_CFGR_DISCEN_Msk /*!< ADC group regular sequencer discontinuous mode */ + +#define ADC_CFGR_DISCNUM_Pos (17U) +#define ADC_CFGR_DISCNUM_Msk (0x7UL << ADC_CFGR_DISCNUM_Pos) /*!< 0x000E0000 */ +#define ADC_CFGR_DISCNUM ADC_CFGR_DISCNUM_Msk /*!< ADC group regular sequencer discontinuous number of ranks */ +#define ADC_CFGR_DISCNUM_0 (0x1UL << ADC_CFGR_DISCNUM_Pos) /*!< 0x00020000 */ +#define ADC_CFGR_DISCNUM_1 (0x2UL << ADC_CFGR_DISCNUM_Pos) /*!< 0x00040000 */ +#define ADC_CFGR_DISCNUM_2 (0x4UL << ADC_CFGR_DISCNUM_Pos) /*!< 0x00080000 */ + +#define ADC_CFGR_JDISCEN_Pos (20U) +#define ADC_CFGR_JDISCEN_Msk (0x1UL << ADC_CFGR_JDISCEN_Pos) /*!< 0x00100000 */ +#define ADC_CFGR_JDISCEN ADC_CFGR_JDISCEN_Msk /*!< ADC group injected sequencer discontinuous mode */ +#define ADC_CFGR_JQM_Pos (21U) +#define ADC_CFGR_JQM_Msk (0x1UL << ADC_CFGR_JQM_Pos) /*!< 0x00200000 */ +#define ADC_CFGR_JQM ADC_CFGR_JQM_Msk /*!< ADC group injected contexts queue mode */ +#define ADC_CFGR_AWD1SGL_Pos (22U) +#define ADC_CFGR_AWD1SGL_Msk (0x1UL << ADC_CFGR_AWD1SGL_Pos) /*!< 0x00400000 */ +#define ADC_CFGR_AWD1SGL ADC_CFGR_AWD1SGL_Msk /*!< ADC analog watchdog 1 monitoring a single channel or all channels */ +#define ADC_CFGR_AWD1EN_Pos (23U) +#define ADC_CFGR_AWD1EN_Msk (0x1UL << ADC_CFGR_AWD1EN_Pos) /*!< 0x00800000 */ +#define ADC_CFGR_AWD1EN ADC_CFGR_AWD1EN_Msk /*!< ADC analog watchdog 1 enable on scope ADC group regular */ +#define ADC_CFGR_JAWD1EN_Pos (24U) +#define ADC_CFGR_JAWD1EN_Msk (0x1UL << ADC_CFGR_JAWD1EN_Pos) /*!< 0x01000000 */ +#define ADC_CFGR_JAWD1EN ADC_CFGR_JAWD1EN_Msk /*!< ADC analog watchdog 1 enable on scope ADC group injected */ +#define ADC_CFGR_JAUTO_Pos (25U) +#define ADC_CFGR_JAUTO_Msk (0x1UL << ADC_CFGR_JAUTO_Pos) /*!< 0x02000000 */ +#define ADC_CFGR_JAUTO ADC_CFGR_JAUTO_Msk /*!< ADC group injected automatic trigger mode */ + +#define ADC_CFGR_AWD1CH_Pos (26U) +#define ADC_CFGR_AWD1CH_Msk (0x1FUL << ADC_CFGR_AWD1CH_Pos) /*!< 0x7C000000 */ +#define ADC_CFGR_AWD1CH ADC_CFGR_AWD1CH_Msk /*!< ADC analog watchdog 1 monitored channel selection */ +#define ADC_CFGR_AWD1CH_0 (0x01UL << ADC_CFGR_AWD1CH_Pos) /*!< 0x04000000 */ +#define ADC_CFGR_AWD1CH_1 (0x02UL << ADC_CFGR_AWD1CH_Pos) /*!< 0x08000000 */ +#define ADC_CFGR_AWD1CH_2 (0x04UL << ADC_CFGR_AWD1CH_Pos) /*!< 0x10000000 */ +#define ADC_CFGR_AWD1CH_3 (0x08UL << ADC_CFGR_AWD1CH_Pos) /*!< 0x20000000 */ +#define ADC_CFGR_AWD1CH_4 (0x10UL << ADC_CFGR_AWD1CH_Pos) /*!< 0x40000000 */ + +#define ADC_CFGR_JQDIS_Pos (31U) +#define ADC_CFGR_JQDIS_Msk (0x1UL << ADC_CFGR_JQDIS_Pos) /*!< 0x80000000 */ +#define ADC_CFGR_JQDIS ADC_CFGR_JQDIS_Msk /*!< ADC group injected contexts queue disable */ + +/******************** Bit definition for ADC_CFGR2 register *****************/ +#define ADC_CFGR2_ROVSE_Pos (0U) +#define ADC_CFGR2_ROVSE_Msk (0x1UL << ADC_CFGR2_ROVSE_Pos) /*!< 0x00000001 */ +#define ADC_CFGR2_ROVSE ADC_CFGR2_ROVSE_Msk /*!< ADC oversampler enable on scope ADC group regular */ +#define ADC_CFGR2_JOVSE_Pos (1U) +#define ADC_CFGR2_JOVSE_Msk (0x1UL << ADC_CFGR2_JOVSE_Pos) /*!< 0x00000002 */ +#define ADC_CFGR2_JOVSE ADC_CFGR2_JOVSE_Msk /*!< ADC oversampler enable on scope ADC group injected */ + +#define ADC_CFGR2_OVSR_Pos (2U) +#define ADC_CFGR2_OVSR_Msk (0x7UL << ADC_CFGR2_OVSR_Pos) /*!< 0x0000001C */ +#define ADC_CFGR2_OVSR ADC_CFGR2_OVSR_Msk /*!< ADC oversampling ratio */ +#define ADC_CFGR2_OVSR_0 (0x1UL << ADC_CFGR2_OVSR_Pos) /*!< 0x00000004 */ +#define ADC_CFGR2_OVSR_1 (0x2UL << ADC_CFGR2_OVSR_Pos) /*!< 0x00000008 */ +#define ADC_CFGR2_OVSR_2 (0x4UL << ADC_CFGR2_OVSR_Pos) /*!< 0x00000010 */ + +#define ADC_CFGR2_OVSS_Pos (5U) +#define ADC_CFGR2_OVSS_Msk (0xFUL << ADC_CFGR2_OVSS_Pos) /*!< 0x000001E0 */ +#define ADC_CFGR2_OVSS ADC_CFGR2_OVSS_Msk /*!< ADC oversampling shift */ +#define ADC_CFGR2_OVSS_0 (0x1UL << ADC_CFGR2_OVSS_Pos) /*!< 0x00000020 */ +#define ADC_CFGR2_OVSS_1 (0x2UL << ADC_CFGR2_OVSS_Pos) /*!< 0x00000040 */ +#define ADC_CFGR2_OVSS_2 (0x4UL << ADC_CFGR2_OVSS_Pos) /*!< 0x00000080 */ +#define ADC_CFGR2_OVSS_3 (0x8UL << ADC_CFGR2_OVSS_Pos) /*!< 0x00000100 */ + +#define ADC_CFGR2_TROVS_Pos (9U) +#define ADC_CFGR2_TROVS_Msk (0x1UL << ADC_CFGR2_TROVS_Pos) /*!< 0x00000200 */ +#define ADC_CFGR2_TROVS ADC_CFGR2_TROVS_Msk /*!< ADC oversampling discontinuous mode (triggered mode) for ADC group regular */ +#define ADC_CFGR2_ROVSM_Pos (10U) +#define ADC_CFGR2_ROVSM_Msk (0x1UL << ADC_CFGR2_ROVSM_Pos) /*!< 0x00000400 */ +#define ADC_CFGR2_ROVSM ADC_CFGR2_ROVSM_Msk /*!< ADC oversampling mode managing interlaced conversions of ADC group regular and group injected */ + +#define ADC_CFGR2_GCOMP_Pos (16U) +#define ADC_CFGR2_GCOMP_Msk (0x1UL << ADC_CFGR2_GCOMP_Pos) /*!< 0x00010000 */ +#define ADC_CFGR2_GCOMP ADC_CFGR2_GCOMP_Msk /*!< ADC Gain Compensation mode */ + +#define ADC_CFGR2_SWTRIG_Pos (25U) +#define ADC_CFGR2_SWTRIG_Msk (0x1UL << ADC_CFGR2_SWTRIG_Pos) /*!< 0x02000000 */ +#define ADC_CFGR2_SWTRIG ADC_CFGR2_SWTRIG_Msk /*!< ADC Software Trigger Bit for Sample time control trigger mode */ +#define ADC_CFGR2_BULB_Pos (26U) +#define ADC_CFGR2_BULB_Msk (0x1UL << ADC_CFGR2_BULB_Pos) /*!< 0x04000000 */ +#define ADC_CFGR2_BULB ADC_CFGR2_BULB_Msk /*!< ADC Bulb sampling mode */ +#define ADC_CFGR2_SMPTRIG_Pos (27U) +#define ADC_CFGR2_SMPTRIG_Msk (0x1UL << ADC_CFGR2_SMPTRIG_Pos) /*!< 0x08000000 */ +#define ADC_CFGR2_SMPTRIG ADC_CFGR2_SMPTRIG_Msk /*!< ADC Sample Time Control Trigger mode */ + +#define ADC_CFGR2_LFTRIG_Pos (29U) +#define ADC_CFGR2_LFTRIG_Msk (0x1UL << ADC_CFGR2_LFTRIG_Pos) /*!< 0x20000000 */ +#define ADC_CFGR2_LFTRIG ADC_CFGR2_LFTRIG_Msk /*!< ADC Low Frequency Trigger */ + +/******************** Bit definition for ADC_SMPR1 register *****************/ +#define ADC_SMPR1_SMP0_Pos (0U) +#define ADC_SMPR1_SMP0_Msk (0x7UL << ADC_SMPR1_SMP0_Pos) /*!< 0x00000007 */ +#define ADC_SMPR1_SMP0 ADC_SMPR1_SMP0_Msk /*!< ADC channel 0 sampling time selection */ +#define ADC_SMPR1_SMP0_0 (0x1UL << ADC_SMPR1_SMP0_Pos) /*!< 0x00000001 */ +#define ADC_SMPR1_SMP0_1 (0x2UL << ADC_SMPR1_SMP0_Pos) /*!< 0x00000002 */ +#define ADC_SMPR1_SMP0_2 (0x4UL << ADC_SMPR1_SMP0_Pos) /*!< 0x00000004 */ + +#define ADC_SMPR1_SMP1_Pos (3U) +#define ADC_SMPR1_SMP1_Msk (0x7UL << ADC_SMPR1_SMP1_Pos) /*!< 0x00000038 */ +#define ADC_SMPR1_SMP1 ADC_SMPR1_SMP1_Msk /*!< ADC channel 1 sampling time selection */ +#define ADC_SMPR1_SMP1_0 (0x1UL << ADC_SMPR1_SMP1_Pos) /*!< 0x00000008 */ +#define ADC_SMPR1_SMP1_1 (0x2UL << ADC_SMPR1_SMP1_Pos) /*!< 0x00000010 */ +#define ADC_SMPR1_SMP1_2 (0x4UL << ADC_SMPR1_SMP1_Pos) /*!< 0x00000020 */ + +#define ADC_SMPR1_SMP2_Pos (6U) +#define ADC_SMPR1_SMP2_Msk (0x7UL << ADC_SMPR1_SMP2_Pos) /*!< 0x000001C0 */ +#define ADC_SMPR1_SMP2 ADC_SMPR1_SMP2_Msk /*!< ADC channel 2 sampling time selection */ +#define ADC_SMPR1_SMP2_0 (0x1UL << ADC_SMPR1_SMP2_Pos) /*!< 0x00000040 */ +#define ADC_SMPR1_SMP2_1 (0x2UL << ADC_SMPR1_SMP2_Pos) /*!< 0x00000080 */ +#define ADC_SMPR1_SMP2_2 (0x4UL << ADC_SMPR1_SMP2_Pos) /*!< 0x00000100 */ + +#define ADC_SMPR1_SMP3_Pos (9U) +#define ADC_SMPR1_SMP3_Msk (0x7UL << ADC_SMPR1_SMP3_Pos) /*!< 0x00000E00 */ +#define ADC_SMPR1_SMP3 ADC_SMPR1_SMP3_Msk /*!< ADC channel 3 sampling time selection */ +#define ADC_SMPR1_SMP3_0 (0x1UL << ADC_SMPR1_SMP3_Pos) /*!< 0x00000200 */ +#define ADC_SMPR1_SMP3_1 (0x2UL << ADC_SMPR1_SMP3_Pos) /*!< 0x00000400 */ +#define ADC_SMPR1_SMP3_2 (0x4UL << ADC_SMPR1_SMP3_Pos) /*!< 0x00000800 */ + +#define ADC_SMPR1_SMP4_Pos (12U) +#define ADC_SMPR1_SMP4_Msk (0x7UL << ADC_SMPR1_SMP4_Pos) /*!< 0x00007000 */ +#define ADC_SMPR1_SMP4 ADC_SMPR1_SMP4_Msk /*!< ADC channel 4 sampling time selection */ +#define ADC_SMPR1_SMP4_0 (0x1UL << ADC_SMPR1_SMP4_Pos) /*!< 0x00001000 */ +#define ADC_SMPR1_SMP4_1 (0x2UL << ADC_SMPR1_SMP4_Pos) /*!< 0x00002000 */ +#define ADC_SMPR1_SMP4_2 (0x4UL << ADC_SMPR1_SMP4_Pos) /*!< 0x00004000 */ + +#define ADC_SMPR1_SMP5_Pos (15U) +#define ADC_SMPR1_SMP5_Msk (0x7UL << ADC_SMPR1_SMP5_Pos) /*!< 0x00038000 */ +#define ADC_SMPR1_SMP5 ADC_SMPR1_SMP5_Msk /*!< ADC channel 5 sampling time selection */ +#define ADC_SMPR1_SMP5_0 (0x1UL << ADC_SMPR1_SMP5_Pos) /*!< 0x00008000 */ +#define ADC_SMPR1_SMP5_1 (0x2UL << ADC_SMPR1_SMP5_Pos) /*!< 0x00010000 */ +#define ADC_SMPR1_SMP5_2 (0x4UL << ADC_SMPR1_SMP5_Pos) /*!< 0x00020000 */ + +#define ADC_SMPR1_SMP6_Pos (18U) +#define ADC_SMPR1_SMP6_Msk (0x7UL << ADC_SMPR1_SMP6_Pos) /*!< 0x001C0000 */ +#define ADC_SMPR1_SMP6 ADC_SMPR1_SMP6_Msk /*!< ADC channel 6 sampling time selection */ +#define ADC_SMPR1_SMP6_0 (0x1UL << ADC_SMPR1_SMP6_Pos) /*!< 0x00040000 */ +#define ADC_SMPR1_SMP6_1 (0x2UL << ADC_SMPR1_SMP6_Pos) /*!< 0x00080000 */ +#define ADC_SMPR1_SMP6_2 (0x4UL << ADC_SMPR1_SMP6_Pos) /*!< 0x00100000 */ + +#define ADC_SMPR1_SMP7_Pos (21U) +#define ADC_SMPR1_SMP7_Msk (0x7UL << ADC_SMPR1_SMP7_Pos) /*!< 0x00E00000 */ +#define ADC_SMPR1_SMP7 ADC_SMPR1_SMP7_Msk /*!< ADC channel 7 sampling time selection */ +#define ADC_SMPR1_SMP7_0 (0x1UL << ADC_SMPR1_SMP7_Pos) /*!< 0x00200000 */ +#define ADC_SMPR1_SMP7_1 (0x2UL << ADC_SMPR1_SMP7_Pos) /*!< 0x00400000 */ +#define ADC_SMPR1_SMP7_2 (0x4UL << ADC_SMPR1_SMP7_Pos) /*!< 0x00800000 */ + +#define ADC_SMPR1_SMP8_Pos (24U) +#define ADC_SMPR1_SMP8_Msk (0x7UL << ADC_SMPR1_SMP8_Pos) /*!< 0x07000000 */ +#define ADC_SMPR1_SMP8 ADC_SMPR1_SMP8_Msk /*!< ADC channel 8 sampling time selection */ +#define ADC_SMPR1_SMP8_0 (0x1UL << ADC_SMPR1_SMP8_Pos) /*!< 0x01000000 */ +#define ADC_SMPR1_SMP8_1 (0x2UL << ADC_SMPR1_SMP8_Pos) /*!< 0x02000000 */ +#define ADC_SMPR1_SMP8_2 (0x4UL << ADC_SMPR1_SMP8_Pos) /*!< 0x04000000 */ + +#define ADC_SMPR1_SMP9_Pos (27U) +#define ADC_SMPR1_SMP9_Msk (0x7UL << ADC_SMPR1_SMP9_Pos) /*!< 0x38000000 */ +#define ADC_SMPR1_SMP9 ADC_SMPR1_SMP9_Msk /*!< ADC channel 9 sampling time selection */ +#define ADC_SMPR1_SMP9_0 (0x1UL << ADC_SMPR1_SMP9_Pos) /*!< 0x08000000 */ +#define ADC_SMPR1_SMP9_1 (0x2UL << ADC_SMPR1_SMP9_Pos) /*!< 0x10000000 */ +#define ADC_SMPR1_SMP9_2 (0x4UL << ADC_SMPR1_SMP9_Pos) /*!< 0x20000000 */ + +#define ADC_SMPR1_SMPPLUS_Pos (31U) +#define ADC_SMPR1_SMPPLUS_Msk (0x1UL << ADC_SMPR1_SMPPLUS_Pos) /*!< 0x80000000 */ +#define ADC_SMPR1_SMPPLUS ADC_SMPR1_SMPPLUS_Msk /*!< ADC channels sampling time additional setting */ + +/******************** Bit definition for ADC_SMPR2 register *****************/ +#define ADC_SMPR2_SMP10_Pos (0U) +#define ADC_SMPR2_SMP10_Msk (0x7UL << ADC_SMPR2_SMP10_Pos) /*!< 0x00000007 */ +#define ADC_SMPR2_SMP10 ADC_SMPR2_SMP10_Msk /*!< ADC channel 10 sampling time selection */ +#define ADC_SMPR2_SMP10_0 (0x1UL << ADC_SMPR2_SMP10_Pos) /*!< 0x00000001 */ +#define ADC_SMPR2_SMP10_1 (0x2UL << ADC_SMPR2_SMP10_Pos) /*!< 0x00000002 */ +#define ADC_SMPR2_SMP10_2 (0x4UL << ADC_SMPR2_SMP10_Pos) /*!< 0x00000004 */ + +#define ADC_SMPR2_SMP11_Pos (3U) +#define ADC_SMPR2_SMP11_Msk (0x7UL << ADC_SMPR2_SMP11_Pos) /*!< 0x00000038 */ +#define ADC_SMPR2_SMP11 ADC_SMPR2_SMP11_Msk /*!< ADC channel 11 sampling time selection */ +#define ADC_SMPR2_SMP11_0 (0x1UL << ADC_SMPR2_SMP11_Pos) /*!< 0x00000008 */ +#define ADC_SMPR2_SMP11_1 (0x2UL << ADC_SMPR2_SMP11_Pos) /*!< 0x00000010 */ +#define ADC_SMPR2_SMP11_2 (0x4UL << ADC_SMPR2_SMP11_Pos) /*!< 0x00000020 */ + +#define ADC_SMPR2_SMP12_Pos (6U) +#define ADC_SMPR2_SMP12_Msk (0x7UL << ADC_SMPR2_SMP12_Pos) /*!< 0x000001C0 */ +#define ADC_SMPR2_SMP12 ADC_SMPR2_SMP12_Msk /*!< ADC channel 12 sampling time selection */ +#define ADC_SMPR2_SMP12_0 (0x1UL << ADC_SMPR2_SMP12_Pos) /*!< 0x00000040 */ +#define ADC_SMPR2_SMP12_1 (0x2UL << ADC_SMPR2_SMP12_Pos) /*!< 0x00000080 */ +#define ADC_SMPR2_SMP12_2 (0x4UL << ADC_SMPR2_SMP12_Pos) /*!< 0x00000100 */ + +#define ADC_SMPR2_SMP13_Pos (9U) +#define ADC_SMPR2_SMP13_Msk (0x7UL << ADC_SMPR2_SMP13_Pos) /*!< 0x00000E00 */ +#define ADC_SMPR2_SMP13 ADC_SMPR2_SMP13_Msk /*!< ADC channel 13 sampling time selection */ +#define ADC_SMPR2_SMP13_0 (0x1UL << ADC_SMPR2_SMP13_Pos) /*!< 0x00000200 */ +#define ADC_SMPR2_SMP13_1 (0x2UL << ADC_SMPR2_SMP13_Pos) /*!< 0x00000400 */ +#define ADC_SMPR2_SMP13_2 (0x4UL << ADC_SMPR2_SMP13_Pos) /*!< 0x00000800 */ + +#define ADC_SMPR2_SMP14_Pos (12U) +#define ADC_SMPR2_SMP14_Msk (0x7UL << ADC_SMPR2_SMP14_Pos) /*!< 0x00007000 */ +#define ADC_SMPR2_SMP14 ADC_SMPR2_SMP14_Msk /*!< ADC channel 14 sampling time selection */ +#define ADC_SMPR2_SMP14_0 (0x1UL << ADC_SMPR2_SMP14_Pos) /*!< 0x00001000 */ +#define ADC_SMPR2_SMP14_1 (0x2UL << ADC_SMPR2_SMP14_Pos) /*!< 0x00002000 */ +#define ADC_SMPR2_SMP14_2 (0x4UL << ADC_SMPR2_SMP14_Pos) /*!< 0x00004000 */ + +#define ADC_SMPR2_SMP15_Pos (15U) +#define ADC_SMPR2_SMP15_Msk (0x7UL << ADC_SMPR2_SMP15_Pos) /*!< 0x00038000 */ +#define ADC_SMPR2_SMP15 ADC_SMPR2_SMP15_Msk /*!< ADC channel 15 sampling time selection */ +#define ADC_SMPR2_SMP15_0 (0x1UL << ADC_SMPR2_SMP15_Pos) /*!< 0x00008000 */ +#define ADC_SMPR2_SMP15_1 (0x2UL << ADC_SMPR2_SMP15_Pos) /*!< 0x00010000 */ +#define ADC_SMPR2_SMP15_2 (0x4UL << ADC_SMPR2_SMP15_Pos) /*!< 0x00020000 */ + +#define ADC_SMPR2_SMP16_Pos (18U) +#define ADC_SMPR2_SMP16_Msk (0x7UL << ADC_SMPR2_SMP16_Pos) /*!< 0x001C0000 */ +#define ADC_SMPR2_SMP16 ADC_SMPR2_SMP16_Msk /*!< ADC channel 16 sampling time selection */ +#define ADC_SMPR2_SMP16_0 (0x1UL << ADC_SMPR2_SMP16_Pos) /*!< 0x00040000 */ +#define ADC_SMPR2_SMP16_1 (0x2UL << ADC_SMPR2_SMP16_Pos) /*!< 0x00080000 */ +#define ADC_SMPR2_SMP16_2 (0x4UL << ADC_SMPR2_SMP16_Pos) /*!< 0x00100000 */ + +#define ADC_SMPR2_SMP17_Pos (21U) +#define ADC_SMPR2_SMP17_Msk (0x7UL << ADC_SMPR2_SMP17_Pos) /*!< 0x00E00000 */ +#define ADC_SMPR2_SMP17 ADC_SMPR2_SMP17_Msk /*!< ADC channel 17 sampling time selection */ +#define ADC_SMPR2_SMP17_0 (0x1UL << ADC_SMPR2_SMP17_Pos) /*!< 0x00200000 */ +#define ADC_SMPR2_SMP17_1 (0x2UL << ADC_SMPR2_SMP17_Pos) /*!< 0x00400000 */ +#define ADC_SMPR2_SMP17_2 (0x4UL << ADC_SMPR2_SMP17_Pos) /*!< 0x00800000 */ + +#define ADC_SMPR2_SMP18_Pos (24U) +#define ADC_SMPR2_SMP18_Msk (0x7UL << ADC_SMPR2_SMP18_Pos) /*!< 0x07000000 */ +#define ADC_SMPR2_SMP18 ADC_SMPR2_SMP18_Msk /*!< ADC channel 18 sampling time selection */ +#define ADC_SMPR2_SMP18_0 (0x1UL << ADC_SMPR2_SMP18_Pos) /*!< 0x01000000 */ +#define ADC_SMPR2_SMP18_1 (0x2UL << ADC_SMPR2_SMP18_Pos) /*!< 0x02000000 */ +#define ADC_SMPR2_SMP18_2 (0x4UL << ADC_SMPR2_SMP18_Pos) /*!< 0x04000000 */ + +/******************** Bit definition for ADC_TR1 register *******************/ +#define ADC_TR1_LT1_Pos (0U) +#define ADC_TR1_LT1_Msk (0xFFFUL << ADC_TR1_LT1_Pos) /*!< 0x00000FFF */ +#define ADC_TR1_LT1 ADC_TR1_LT1_Msk /*!< ADC analog watchdog 1 threshold low */ + +#define ADC_TR1_AWDFILT_Pos (12U) +#define ADC_TR1_AWDFILT_Msk (0x7UL << ADC_TR1_AWDFILT_Pos) /*!< 0x00007000 */ +#define ADC_TR1_AWDFILT ADC_TR1_AWDFILT_Msk /*!< ADC analog watchdog filtering parameter */ +#define ADC_TR1_AWDFILT_0 (0x1UL << ADC_TR1_AWDFILT_Pos) /*!< 0x00001000 */ +#define ADC_TR1_AWDFILT_1 (0x2UL << ADC_TR1_AWDFILT_Pos) /*!< 0x00002000 */ +#define ADC_TR1_AWDFILT_2 (0x4UL << ADC_TR1_AWDFILT_Pos) /*!< 0x00004000 */ + +#define ADC_TR1_HT1_Pos (16U) +#define ADC_TR1_HT1_Msk (0xFFFUL << ADC_TR1_HT1_Pos) /*!< 0x0FFF0000 */ +#define ADC_TR1_HT1 ADC_TR1_HT1_Msk /*!< ADC analog watchdog 1 threshold high */ + +/******************** Bit definition for ADC_TR2 register *******************/ +#define ADC_TR2_LT2_Pos (0U) +#define ADC_TR2_LT2_Msk (0xFFUL << ADC_TR2_LT2_Pos) /*!< 0x000000FF */ +#define ADC_TR2_LT2 ADC_TR2_LT2_Msk /*!< ADC analog watchdog 2 threshold low */ + +#define ADC_TR2_HT2_Pos (16U) +#define ADC_TR2_HT2_Msk (0xFFUL << ADC_TR2_HT2_Pos) /*!< 0x00FF0000 */ +#define ADC_TR2_HT2 ADC_TR2_HT2_Msk /*!< ADC analog watchdog 2 threshold high */ + +/******************** Bit definition for ADC_TR3 register *******************/ +#define ADC_TR3_LT3_Pos (0U) +#define ADC_TR3_LT3_Msk (0xFFUL << ADC_TR3_LT3_Pos) /*!< 0x000000FF */ +#define ADC_TR3_LT3 ADC_TR3_LT3_Msk /*!< ADC analog watchdog 3 threshold low */ + +#define ADC_TR3_HT3_Pos (16U) +#define ADC_TR3_HT3_Msk (0xFFUL << ADC_TR3_HT3_Pos) /*!< 0x00FF0000 */ +#define ADC_TR3_HT3 ADC_TR3_HT3_Msk /*!< ADC analog watchdog 3 threshold high */ + +/******************** Bit definition for ADC_SQR1 register ******************/ +#define ADC_SQR1_L_Pos (0U) +#define ADC_SQR1_L_Msk (0xFUL << ADC_SQR1_L_Pos) /*!< 0x0000000F */ +#define ADC_SQR1_L ADC_SQR1_L_Msk /*!< ADC group regular sequencer scan length */ +#define ADC_SQR1_L_0 (0x1UL << ADC_SQR1_L_Pos) /*!< 0x00000001 */ +#define ADC_SQR1_L_1 (0x2UL << ADC_SQR1_L_Pos) /*!< 0x00000002 */ +#define ADC_SQR1_L_2 (0x4UL << ADC_SQR1_L_Pos) /*!< 0x00000004 */ +#define ADC_SQR1_L_3 (0x8UL << ADC_SQR1_L_Pos) /*!< 0x00000008 */ + +#define ADC_SQR1_SQ1_Pos (6U) +#define ADC_SQR1_SQ1_Msk (0x1FUL << ADC_SQR1_SQ1_Pos) /*!< 0x000007C0 */ +#define ADC_SQR1_SQ1 ADC_SQR1_SQ1_Msk /*!< ADC group regular sequencer rank 1 */ +#define ADC_SQR1_SQ1_0 (0x01UL << ADC_SQR1_SQ1_Pos) /*!< 0x00000040 */ +#define ADC_SQR1_SQ1_1 (0x02UL << ADC_SQR1_SQ1_Pos) /*!< 0x00000080 */ +#define ADC_SQR1_SQ1_2 (0x04UL << ADC_SQR1_SQ1_Pos) /*!< 0x00000100 */ +#define ADC_SQR1_SQ1_3 (0x08UL << ADC_SQR1_SQ1_Pos) /*!< 0x00000200 */ +#define ADC_SQR1_SQ1_4 (0x10UL << ADC_SQR1_SQ1_Pos) /*!< 0x00000400 */ + +#define ADC_SQR1_SQ2_Pos (12U) +#define ADC_SQR1_SQ2_Msk (0x1FUL << ADC_SQR1_SQ2_Pos) /*!< 0x0001F000 */ +#define ADC_SQR1_SQ2 ADC_SQR1_SQ2_Msk /*!< ADC group regular sequencer rank 2 */ +#define ADC_SQR1_SQ2_0 (0x01UL << ADC_SQR1_SQ2_Pos) /*!< 0x00001000 */ +#define ADC_SQR1_SQ2_1 (0x02UL << ADC_SQR1_SQ2_Pos) /*!< 0x00002000 */ +#define ADC_SQR1_SQ2_2 (0x04UL << ADC_SQR1_SQ2_Pos) /*!< 0x00004000 */ +#define ADC_SQR1_SQ2_3 (0x08UL << ADC_SQR1_SQ2_Pos) /*!< 0x00008000 */ +#define ADC_SQR1_SQ2_4 (0x10UL << ADC_SQR1_SQ2_Pos) /*!< 0x00010000 */ + +#define ADC_SQR1_SQ3_Pos (18U) +#define ADC_SQR1_SQ3_Msk (0x1FUL << ADC_SQR1_SQ3_Pos) /*!< 0x007C0000 */ +#define ADC_SQR1_SQ3 ADC_SQR1_SQ3_Msk /*!< ADC group regular sequencer rank 3 */ +#define ADC_SQR1_SQ3_0 (0x01UL << ADC_SQR1_SQ3_Pos) /*!< 0x00040000 */ +#define ADC_SQR1_SQ3_1 (0x02UL << ADC_SQR1_SQ3_Pos) /*!< 0x00080000 */ +#define ADC_SQR1_SQ3_2 (0x04UL << ADC_SQR1_SQ3_Pos) /*!< 0x00100000 */ +#define ADC_SQR1_SQ3_3 (0x08UL << ADC_SQR1_SQ3_Pos) /*!< 0x00200000 */ +#define ADC_SQR1_SQ3_4 (0x10UL<< ADC_SQR1_SQ3_Pos) /*!< 0x00400000 */ + +#define ADC_SQR1_SQ4_Pos (24U) +#define ADC_SQR1_SQ4_Msk (0x1FUL << ADC_SQR1_SQ4_Pos) /*!< 0x1F000000 */ +#define ADC_SQR1_SQ4 ADC_SQR1_SQ4_Msk /*!< ADC group regular sequencer rank 4 */ +#define ADC_SQR1_SQ4_0 (0x01UL << ADC_SQR1_SQ4_Pos) /*!< 0x01000000 */ +#define ADC_SQR1_SQ4_1 (0x02UL << ADC_SQR1_SQ4_Pos) /*!< 0x02000000 */ +#define ADC_SQR1_SQ4_2 (0x04UL << ADC_SQR1_SQ4_Pos) /*!< 0x04000000 */ +#define ADC_SQR1_SQ4_3 (0x08UL << ADC_SQR1_SQ4_Pos) /*!< 0x08000000 */ +#define ADC_SQR1_SQ4_4 (0x10UL << ADC_SQR1_SQ4_Pos) /*!< 0x10000000 */ + +/******************** Bit definition for ADC_SQR2 register ******************/ +#define ADC_SQR2_SQ5_Pos (0U) +#define ADC_SQR2_SQ5_Msk (0x1FUL << ADC_SQR2_SQ5_Pos) /*!< 0x0000001F */ +#define ADC_SQR2_SQ5 ADC_SQR2_SQ5_Msk /*!< ADC group regular sequencer rank 5 */ +#define ADC_SQR2_SQ5_0 (0x01UL << ADC_SQR2_SQ5_Pos) /*!< 0x00000001 */ +#define ADC_SQR2_SQ5_1 (0x02UL << ADC_SQR2_SQ5_Pos) /*!< 0x00000002 */ +#define ADC_SQR2_SQ5_2 (0x04UL << ADC_SQR2_SQ5_Pos) /*!< 0x00000004 */ +#define ADC_SQR2_SQ5_3 (0x08UL << ADC_SQR2_SQ5_Pos) /*!< 0x00000008 */ +#define ADC_SQR2_SQ5_4 (0x10UL << ADC_SQR2_SQ5_Pos) /*!< 0x00000010 */ + +#define ADC_SQR2_SQ6_Pos (6U) +#define ADC_SQR2_SQ6_Msk (0x1FUL << ADC_SQR2_SQ6_Pos) /*!< 0x000007C0 */ +#define ADC_SQR2_SQ6 ADC_SQR2_SQ6_Msk /*!< ADC group regular sequencer rank 6 */ +#define ADC_SQR2_SQ6_0 (0x01UL << ADC_SQR2_SQ6_Pos) /*!< 0x00000040 */ +#define ADC_SQR2_SQ6_1 (0x02UL << ADC_SQR2_SQ6_Pos) /*!< 0x00000080 */ +#define ADC_SQR2_SQ6_2 (0x04UL << ADC_SQR2_SQ6_Pos) /*!< 0x00000100 */ +#define ADC_SQR2_SQ6_3 (0x08UL << ADC_SQR2_SQ6_Pos) /*!< 0x00000200 */ +#define ADC_SQR2_SQ6_4 (0x10UL << ADC_SQR2_SQ6_Pos) /*!< 0x00000400 */ + +#define ADC_SQR2_SQ7_Pos (12U) +#define ADC_SQR2_SQ7_Msk (0x1FUL << ADC_SQR2_SQ7_Pos) /*!< 0x0001F000 */ +#define ADC_SQR2_SQ7 ADC_SQR2_SQ7_Msk /*!< ADC group regular sequencer rank 7 */ +#define ADC_SQR2_SQ7_0 (0x01UL << ADC_SQR2_SQ7_Pos) /*!< 0x00001000 */ +#define ADC_SQR2_SQ7_1 (0x02UL << ADC_SQR2_SQ7_Pos) /*!< 0x00002000 */ +#define ADC_SQR2_SQ7_2 (0x04UL << ADC_SQR2_SQ7_Pos) /*!< 0x00004000 */ +#define ADC_SQR2_SQ7_3 (0x08UL << ADC_SQR2_SQ7_Pos) /*!< 0x00008000 */ +#define ADC_SQR2_SQ7_4 (0x10UL << ADC_SQR2_SQ7_Pos) /*!< 0x00010000 */ + +#define ADC_SQR2_SQ8_Pos (18U) +#define ADC_SQR2_SQ8_Msk (0x1FUL << ADC_SQR2_SQ8_Pos) /*!< 0x007C0000 */ +#define ADC_SQR2_SQ8 ADC_SQR2_SQ8_Msk /*!< ADC group regular sequencer rank 8 */ +#define ADC_SQR2_SQ8_0 (0x01UL << ADC_SQR2_SQ8_Pos) /*!< 0x00040000 */ +#define ADC_SQR2_SQ8_1 (0x02UL << ADC_SQR2_SQ8_Pos) /*!< 0x00080000 */ +#define ADC_SQR2_SQ8_2 (0x04UL << ADC_SQR2_SQ8_Pos) /*!< 0x00100000 */ +#define ADC_SQR2_SQ8_3 (0x08UL << ADC_SQR2_SQ8_Pos) /*!< 0x00200000 */ +#define ADC_SQR2_SQ8_4 (0x10UL << ADC_SQR2_SQ8_Pos) /*!< 0x00400000 */ + +#define ADC_SQR2_SQ9_Pos (24U) +#define ADC_SQR2_SQ9_Msk (0x1FUL << ADC_SQR2_SQ9_Pos) /*!< 0x1F000000 */ +#define ADC_SQR2_SQ9 ADC_SQR2_SQ9_Msk /*!< ADC group regular sequencer rank 9 */ +#define ADC_SQR2_SQ9_0 (0x01UL << ADC_SQR2_SQ9_Pos) /*!< 0x01000000 */ +#define ADC_SQR2_SQ9_1 (0x02UL << ADC_SQR2_SQ9_Pos) /*!< 0x02000000 */ +#define ADC_SQR2_SQ9_2 (0x04UL << ADC_SQR2_SQ9_Pos) /*!< 0x04000000 */ +#define ADC_SQR2_SQ9_3 (0x08UL << ADC_SQR2_SQ9_Pos) /*!< 0x08000000 */ +#define ADC_SQR2_SQ9_4 (0x10UL << ADC_SQR2_SQ9_Pos) /*!< 0x10000000 */ + +/******************** Bit definition for ADC_SQR3 register ******************/ +#define ADC_SQR3_SQ10_Pos (0U) +#define ADC_SQR3_SQ10_Msk (0x1FUL << ADC_SQR3_SQ10_Pos) /*!< 0x0000001F */ +#define ADC_SQR3_SQ10 ADC_SQR3_SQ10_Msk /*!< ADC group regular sequencer rank 10 */ +#define ADC_SQR3_SQ10_0 (0x01UL << ADC_SQR3_SQ10_Pos) /*!< 0x00000001 */ +#define ADC_SQR3_SQ10_1 (0x02UL << ADC_SQR3_SQ10_Pos) /*!< 0x00000002 */ +#define ADC_SQR3_SQ10_2 (0x04UL << ADC_SQR3_SQ10_Pos) /*!< 0x00000004 */ +#define ADC_SQR3_SQ10_3 (0x08UL << ADC_SQR3_SQ10_Pos) /*!< 0x00000008 */ +#define ADC_SQR3_SQ10_4 (0x10UL << ADC_SQR3_SQ10_Pos) /*!< 0x00000010 */ + +#define ADC_SQR3_SQ11_Pos (6U) +#define ADC_SQR3_SQ11_Msk (0x1FUL << ADC_SQR3_SQ11_Pos) /*!< 0x000007C0 */ +#define ADC_SQR3_SQ11 ADC_SQR3_SQ11_Msk /*!< ADC group regular sequencer rank 11 */ +#define ADC_SQR3_SQ11_0 (0x01UL << ADC_SQR3_SQ11_Pos) /*!< 0x00000040 */ +#define ADC_SQR3_SQ11_1 (0x02UL << ADC_SQR3_SQ11_Pos) /*!< 0x00000080 */ +#define ADC_SQR3_SQ11_2 (0x04UL << ADC_SQR3_SQ11_Pos) /*!< 0x00000100 */ +#define ADC_SQR3_SQ11_3 (0x08UL << ADC_SQR3_SQ11_Pos) /*!< 0x00000200 */ +#define ADC_SQR3_SQ11_4 (0x10UL << ADC_SQR3_SQ11_Pos) /*!< 0x00000400 */ + +#define ADC_SQR3_SQ12_Pos (12U) +#define ADC_SQR3_SQ12_Msk (0x1FUL << ADC_SQR3_SQ12_Pos) /*!< 0x0001F000 */ +#define ADC_SQR3_SQ12 ADC_SQR3_SQ12_Msk /*!< ADC group regular sequencer rank 12 */ +#define ADC_SQR3_SQ12_0 (0x01UL << ADC_SQR3_SQ12_Pos) /*!< 0x00001000 */ +#define ADC_SQR3_SQ12_1 (0x02UL << ADC_SQR3_SQ12_Pos) /*!< 0x00002000 */ +#define ADC_SQR3_SQ12_2 (0x04UL << ADC_SQR3_SQ12_Pos) /*!< 0x00004000 */ +#define ADC_SQR3_SQ12_3 (0x08UL << ADC_SQR3_SQ12_Pos) /*!< 0x00008000 */ +#define ADC_SQR3_SQ12_4 (0x10UL << ADC_SQR3_SQ12_Pos) /*!< 0x00010000 */ + +#define ADC_SQR3_SQ13_Pos (18U) +#define ADC_SQR3_SQ13_Msk (0x1FUL << ADC_SQR3_SQ13_Pos) /*!< 0x007C0000 */ +#define ADC_SQR3_SQ13 ADC_SQR3_SQ13_Msk /*!< ADC group regular sequencer rank 13 */ +#define ADC_SQR3_SQ13_0 (0x01UL << ADC_SQR3_SQ13_Pos) /*!< 0x00040000 */ +#define ADC_SQR3_SQ13_1 (0x02UL << ADC_SQR3_SQ13_Pos) /*!< 0x00080000 */ +#define ADC_SQR3_SQ13_2 (0x04UL << ADC_SQR3_SQ13_Pos) /*!< 0x00100000 */ +#define ADC_SQR3_SQ13_3 (0x08UL << ADC_SQR3_SQ13_Pos) /*!< 0x00200000 */ +#define ADC_SQR3_SQ13_4 (0x10UL << ADC_SQR3_SQ13_Pos) /*!< 0x00400000 */ + +#define ADC_SQR3_SQ14_Pos (24U) +#define ADC_SQR3_SQ14_Msk (0x1FUL << ADC_SQR3_SQ14_Pos) /*!< 0x1F000000 */ +#define ADC_SQR3_SQ14 ADC_SQR3_SQ14_Msk /*!< ADC group regular sequencer rank 14 */ +#define ADC_SQR3_SQ14_0 (0x01UL << ADC_SQR3_SQ14_Pos) /*!< 0x01000000 */ +#define ADC_SQR3_SQ14_1 (0x02UL << ADC_SQR3_SQ14_Pos) /*!< 0x02000000 */ +#define ADC_SQR3_SQ14_2 (0x04UL << ADC_SQR3_SQ14_Pos) /*!< 0x04000000 */ +#define ADC_SQR3_SQ14_3 (0x08UL << ADC_SQR3_SQ14_Pos) /*!< 0x08000000 */ +#define ADC_SQR3_SQ14_4 (0x10UL << ADC_SQR3_SQ14_Pos) /*!< 0x10000000 */ + +/******************** Bit definition for ADC_SQR4 register ******************/ +#define ADC_SQR4_SQ15_Pos (0U) +#define ADC_SQR4_SQ15_Msk (0x1FUL << ADC_SQR4_SQ15_Pos) /*!< 0x0000001F */ +#define ADC_SQR4_SQ15 ADC_SQR4_SQ15_Msk /*!< ADC group regular sequencer rank 15 */ +#define ADC_SQR4_SQ15_0 (0x01UL << ADC_SQR4_SQ15_Pos) /*!< 0x00000001 */ +#define ADC_SQR4_SQ15_1 (0x02UL << ADC_SQR4_SQ15_Pos) /*!< 0x00000002 */ +#define ADC_SQR4_SQ15_2 (0x04UL << ADC_SQR4_SQ15_Pos) /*!< 0x00000004 */ +#define ADC_SQR4_SQ15_3 (0x08UL << ADC_SQR4_SQ15_Pos) /*!< 0x00000008 */ +#define ADC_SQR4_SQ15_4 (0x10UL << ADC_SQR4_SQ15_Pos) /*!< 0x00000010 */ + +#define ADC_SQR4_SQ16_Pos (6U) +#define ADC_SQR4_SQ16_Msk (0x1FUL << ADC_SQR4_SQ16_Pos) /*!< 0x000007C0 */ +#define ADC_SQR4_SQ16 ADC_SQR4_SQ16_Msk /*!< ADC group regular sequencer rank 16 */ +#define ADC_SQR4_SQ16_0 (0x01UL << ADC_SQR4_SQ16_Pos) /*!< 0x00000040 */ +#define ADC_SQR4_SQ16_1 (0x02UL << ADC_SQR4_SQ16_Pos) /*!< 0x00000080 */ +#define ADC_SQR4_SQ16_2 (0x04UL << ADC_SQR4_SQ16_Pos) /*!< 0x00000100 */ +#define ADC_SQR4_SQ16_3 (0x08UL << ADC_SQR4_SQ16_Pos) /*!< 0x00000200 */ +#define ADC_SQR4_SQ16_4 (0x10UL << ADC_SQR4_SQ16_Pos) /*!< 0x00000400 */ + +/******************** Bit definition for ADC_DR register ********************/ +#define ADC_DR_RDATA_Pos (0U) +#define ADC_DR_RDATA_Msk (0xFFFFUL << ADC_DR_RDATA_Pos) /*!< 0x0000FFFF */ +#define ADC_DR_RDATA ADC_DR_RDATA_Msk /*!< ADC group regular conversion data */ + +/******************** Bit definition for ADC_JSQR register ******************/ +#define ADC_JSQR_JL_Pos (0U) +#define ADC_JSQR_JL_Msk (0x3UL << ADC_JSQR_JL_Pos) /*!< 0x00000003 */ +#define ADC_JSQR_JL ADC_JSQR_JL_Msk /*!< ADC group injected sequencer scan length */ +#define ADC_JSQR_JL_0 (0x1UL << ADC_JSQR_JL_Pos) /*!< 0x00000001 */ +#define ADC_JSQR_JL_1 (0x2UL << ADC_JSQR_JL_Pos) /*!< 0x00000002 */ + +#define ADC_JSQR_JEXTSEL_Pos (2U) +#define ADC_JSQR_JEXTSEL_Msk (0x1FUL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x0000007C */ +#define ADC_JSQR_JEXTSEL ADC_JSQR_JEXTSEL_Msk /*!< ADC group injected external trigger source */ +#define ADC_JSQR_JEXTSEL_0 (0x1UL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x00000004 */ +#define ADC_JSQR_JEXTSEL_1 (0x2UL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x00000008 */ +#define ADC_JSQR_JEXTSEL_2 (0x4UL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x00000010 */ +#define ADC_JSQR_JEXTSEL_3 (0x8UL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x00000020 */ +#define ADC_JSQR_JEXTSEL_4 (0x10UL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x00000040 */ + +#define ADC_JSQR_JEXTEN_Pos (7U) +#define ADC_JSQR_JEXTEN_Msk (0x3UL << ADC_JSQR_JEXTEN_Pos) /*!< 0x00000180 */ +#define ADC_JSQR_JEXTEN ADC_JSQR_JEXTEN_Msk /*!< ADC group injected external trigger polarity */ +#define ADC_JSQR_JEXTEN_0 (0x1UL << ADC_JSQR_JEXTEN_Pos) /*!< 0x00000080 */ +#define ADC_JSQR_JEXTEN_1 (0x2UL << ADC_JSQR_JEXTEN_Pos) /*!< 0x00000100 */ + +#define ADC_JSQR_JSQ1_Pos (9U) +#define ADC_JSQR_JSQ1_Msk (0x1FUL << ADC_JSQR_JSQ1_Pos) /*!< 0x00003E00 */ +#define ADC_JSQR_JSQ1 ADC_JSQR_JSQ1_Msk /*!< ADC group injected sequencer rank 1 */ +#define ADC_JSQR_JSQ1_0 (0x01UL << ADC_JSQR_JSQ1_Pos) /*!< 0x00000200 */ +#define ADC_JSQR_JSQ1_1 (0x02UL << ADC_JSQR_JSQ1_Pos) /*!< 0x00000400 */ +#define ADC_JSQR_JSQ1_2 (0x04UL << ADC_JSQR_JSQ1_Pos) /*!< 0x00000800 */ +#define ADC_JSQR_JSQ1_3 (0x08UL << ADC_JSQR_JSQ1_Pos) /*!< 0x00001000 */ +#define ADC_JSQR_JSQ1_4 (0x10UL << ADC_JSQR_JSQ1_Pos) /*!< 0x00002000 */ + +#define ADC_JSQR_JSQ2_Pos (15U) +#define ADC_JSQR_JSQ2_Msk (0x1FUL << ADC_JSQR_JSQ2_Pos) /*!< 0x0007C000 */ +#define ADC_JSQR_JSQ2 ADC_JSQR_JSQ2_Msk /*!< ADC group injected sequencer rank 2 */ +#define ADC_JSQR_JSQ2_0 (0x01UL << ADC_JSQR_JSQ2_Pos) /*!< 0x00004000 */ +#define ADC_JSQR_JSQ2_1 (0x02UL << ADC_JSQR_JSQ2_Pos) /*!< 0x00008000 */ +#define ADC_JSQR_JSQ2_2 (0x04UL << ADC_JSQR_JSQ2_Pos) /*!< 0x00010000 */ +#define ADC_JSQR_JSQ2_3 (0x08UL << ADC_JSQR_JSQ2_Pos) /*!< 0x00020000 */ +#define ADC_JSQR_JSQ2_4 (0x10UL << ADC_JSQR_JSQ2_Pos) /*!< 0x00040000 */ + +#define ADC_JSQR_JSQ3_Pos (21U) +#define ADC_JSQR_JSQ3_Msk (0x1FUL << ADC_JSQR_JSQ3_Pos) /*!< 0x03E00000 */ +#define ADC_JSQR_JSQ3 ADC_JSQR_JSQ3_Msk /*!< ADC group injected sequencer rank 3 */ +#define ADC_JSQR_JSQ3_0 (0x01UL << ADC_JSQR_JSQ3_Pos) /*!< 0x00200000 */ +#define ADC_JSQR_JSQ3_1 (0x02UL << ADC_JSQR_JSQ3_Pos) /*!< 0x00400000 */ +#define ADC_JSQR_JSQ3_2 (0x04UL << ADC_JSQR_JSQ3_Pos) /*!< 0x00800000 */ +#define ADC_JSQR_JSQ3_3 (0x08UL << ADC_JSQR_JSQ3_Pos) /*!< 0x01000000 */ +#define ADC_JSQR_JSQ3_4 (0x10UL << ADC_JSQR_JSQ3_Pos) /*!< 0x02000000 */ + +#define ADC_JSQR_JSQ4_Pos (27U) +#define ADC_JSQR_JSQ4_Msk (0x1FUL << ADC_JSQR_JSQ4_Pos) /*!< 0xF8000000 */ +#define ADC_JSQR_JSQ4 ADC_JSQR_JSQ4_Msk /*!< ADC group injected sequencer rank 4 */ +#define ADC_JSQR_JSQ4_0 (0x01UL << ADC_JSQR_JSQ4_Pos) /*!< 0x08000000 */ +#define ADC_JSQR_JSQ4_1 (0x02UL << ADC_JSQR_JSQ4_Pos) /*!< 0x10000000 */ +#define ADC_JSQR_JSQ4_2 (0x04UL << ADC_JSQR_JSQ4_Pos) /*!< 0x20000000 */ +#define ADC_JSQR_JSQ4_3 (0x08UL << ADC_JSQR_JSQ4_Pos) /*!< 0x40000000 */ +#define ADC_JSQR_JSQ4_4 (0x10UL << ADC_JSQR_JSQ4_Pos) /*!< 0x80000000 */ + +/******************** Bit definition for ADC_OFR1 register ******************/ +#define ADC_OFR1_OFFSET1_Pos (0U) +#define ADC_OFR1_OFFSET1_Msk (0xFFFUL << ADC_OFR1_OFFSET1_Pos) /*!< 0x00000FFF */ +#define ADC_OFR1_OFFSET1 ADC_OFR1_OFFSET1_Msk /*!< ADC offset number 1 offset level */ + +#define ADC_OFR1_OFFSETPOS_Pos (24U) +#define ADC_OFR1_OFFSETPOS_Msk (0x1UL << ADC_OFR1_OFFSETPOS_Pos) /*!< 0x01000000 */ +#define ADC_OFR1_OFFSETPOS ADC_OFR1_OFFSETPOS_Msk /*!< ADC offset number 1 positive */ +#define ADC_OFR1_SATEN_Pos (25U) +#define ADC_OFR1_SATEN_Msk (0x1UL << ADC_OFR1_SATEN_Pos) /*!< 0x02000000 */ +#define ADC_OFR1_SATEN ADC_OFR1_SATEN_Msk /*!< ADC offset number 1 saturation enable */ + +#define ADC_OFR1_OFFSET1_CH_Pos (26U) +#define ADC_OFR1_OFFSET1_CH_Msk (0x1FUL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x7C000000 */ +#define ADC_OFR1_OFFSET1_CH ADC_OFR1_OFFSET1_CH_Msk /*!< ADC offset number 1 channel selection */ +#define ADC_OFR1_OFFSET1_CH_0 (0x01UL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x04000000 */ +#define ADC_OFR1_OFFSET1_CH_1 (0x02UL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x08000000 */ +#define ADC_OFR1_OFFSET1_CH_2 (0x04UL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x10000000 */ +#define ADC_OFR1_OFFSET1_CH_3 (0x08UL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x20000000 */ +#define ADC_OFR1_OFFSET1_CH_4 (0x10UL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x40000000 */ + +#define ADC_OFR1_OFFSET1_EN_Pos (31U) +#define ADC_OFR1_OFFSET1_EN_Msk (0x1UL << ADC_OFR1_OFFSET1_EN_Pos) /*!< 0x80000000 */ +#define ADC_OFR1_OFFSET1_EN ADC_OFR1_OFFSET1_EN_Msk /*!< ADC offset number 1 enable */ + +/******************** Bit definition for ADC_OFR2 register ******************/ +#define ADC_OFR2_OFFSET2_Pos (0U) +#define ADC_OFR2_OFFSET2_Msk (0xFFFUL << ADC_OFR2_OFFSET2_Pos) /*!< 0x00000FFF */ +#define ADC_OFR2_OFFSET2 ADC_OFR2_OFFSET2_Msk /*!< ADC offset number 2 offset level */ + +#define ADC_OFR2_OFFSETPOS_Pos (24U) +#define ADC_OFR2_OFFSETPOS_Msk (0x1UL << ADC_OFR2_OFFSETPOS_Pos) /*!< 0x01000000 */ +#define ADC_OFR2_OFFSETPOS ADC_OFR2_OFFSETPOS_Msk /*!< ADC offset number 2 positive */ +#define ADC_OFR2_SATEN_Pos (25U) +#define ADC_OFR2_SATEN_Msk (0x1UL << ADC_OFR2_SATEN_Pos) /*!< 0x02000000 */ +#define ADC_OFR2_SATEN ADC_OFR2_SATEN_Msk /*!< ADC offset number 2 saturation enable */ + +#define ADC_OFR2_OFFSET2_CH_Pos (26U) +#define ADC_OFR2_OFFSET2_CH_Msk (0x1FUL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x7C000000 */ +#define ADC_OFR2_OFFSET2_CH ADC_OFR2_OFFSET2_CH_Msk /*!< ADC offset number 2 channel selection */ +#define ADC_OFR2_OFFSET2_CH_0 (0x01UL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x04000000 */ +#define ADC_OFR2_OFFSET2_CH_1 (0x02UL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x08000000 */ +#define ADC_OFR2_OFFSET2_CH_2 (0x04UL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x10000000 */ +#define ADC_OFR2_OFFSET2_CH_3 (0x08UL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x20000000 */ +#define ADC_OFR2_OFFSET2_CH_4 (0x10UL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x40000000 */ + +#define ADC_OFR2_OFFSET2_EN_Pos (31U) +#define ADC_OFR2_OFFSET2_EN_Msk (0x1UL << ADC_OFR2_OFFSET2_EN_Pos) /*!< 0x80000000 */ +#define ADC_OFR2_OFFSET2_EN ADC_OFR2_OFFSET2_EN_Msk /*!< ADC offset number 2 enable */ + +/******************** Bit definition for ADC_OFR3 register ******************/ +#define ADC_OFR3_OFFSET3_Pos (0U) +#define ADC_OFR3_OFFSET3_Msk (0xFFFUL << ADC_OFR3_OFFSET3_Pos) /*!< 0x00000FFF */ +#define ADC_OFR3_OFFSET3 ADC_OFR3_OFFSET3_Msk /*!< ADC offset number 3 offset level */ + +#define ADC_OFR3_OFFSETPOS_Pos (24U) +#define ADC_OFR3_OFFSETPOS_Msk (0x1UL << ADC_OFR3_OFFSETPOS_Pos) /*!< 0x01000000 */ +#define ADC_OFR3_OFFSETPOS ADC_OFR3_OFFSETPOS_Msk /*!< ADC offset number 3 positive */ +#define ADC_OFR3_SATEN_Pos (25U) +#define ADC_OFR3_SATEN_Msk (0x1UL << ADC_OFR3_SATEN_Pos) /*!< 0x02000000 */ +#define ADC_OFR3_SATEN ADC_OFR3_SATEN_Msk /*!< ADC offset number 3 saturation enable */ + +#define ADC_OFR3_OFFSET3_CH_Pos (26U) +#define ADC_OFR3_OFFSET3_CH_Msk (0x1FUL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x7C000000 */ +#define ADC_OFR3_OFFSET3_CH ADC_OFR3_OFFSET3_CH_Msk /*!< ADC offset number 3 channel selection */ +#define ADC_OFR3_OFFSET3_CH_0 (0x01UL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x04000000 */ +#define ADC_OFR3_OFFSET3_CH_1 (0x02UL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x08000000 */ +#define ADC_OFR3_OFFSET3_CH_2 (0x04UL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x10000000 */ +#define ADC_OFR3_OFFSET3_CH_3 (0x08UL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x20000000 */ +#define ADC_OFR3_OFFSET3_CH_4 (0x10UL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x40000000 */ + +#define ADC_OFR3_OFFSET3_EN_Pos (31U) +#define ADC_OFR3_OFFSET3_EN_Msk (0x1UL << ADC_OFR3_OFFSET3_EN_Pos) /*!< 0x80000000 */ +#define ADC_OFR3_OFFSET3_EN ADC_OFR3_OFFSET3_EN_Msk /*!< ADC offset number 3 enable */ + +/******************** Bit definition for ADC_OFR4 register ******************/ +#define ADC_OFR4_OFFSET4_Pos (0U) +#define ADC_OFR4_OFFSET4_Msk (0xFFFUL << ADC_OFR4_OFFSET4_Pos) /*!< 0x00000FFF */ +#define ADC_OFR4_OFFSET4 ADC_OFR4_OFFSET4_Msk /*!< ADC offset number 4 offset level */ + +#define ADC_OFR4_OFFSETPOS_Pos (24U) +#define ADC_OFR4_OFFSETPOS_Msk (0x1UL << ADC_OFR4_OFFSETPOS_Pos) /*!< 0x01000000 */ +#define ADC_OFR4_OFFSETPOS ADC_OFR4_OFFSETPOS_Msk /*!< ADC offset number 4 positive */ +#define ADC_OFR4_SATEN_Pos (25U) +#define ADC_OFR4_SATEN_Msk (0x1UL << ADC_OFR4_SATEN_Pos) /*!< 0x02000000 */ +#define ADC_OFR4_SATEN ADC_OFR4_SATEN_Msk /*!< ADC offset number 4 saturation enable */ + +#define ADC_OFR4_OFFSET4_CH_Pos (26U) +#define ADC_OFR4_OFFSET4_CH_Msk (0x1FUL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x7C000000 */ +#define ADC_OFR4_OFFSET4_CH ADC_OFR4_OFFSET4_CH_Msk /*!< ADC offset number 4 channel selection */ +#define ADC_OFR4_OFFSET4_CH_0 (0x01UL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x04000000 */ +#define ADC_OFR4_OFFSET4_CH_1 (0x02UL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x08000000 */ +#define ADC_OFR4_OFFSET4_CH_2 (0x04UL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x10000000 */ +#define ADC_OFR4_OFFSET4_CH_3 (0x08UL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x20000000 */ +#define ADC_OFR4_OFFSET4_CH_4 (0x10UL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x40000000 */ + +#define ADC_OFR4_OFFSET4_EN_Pos (31U) +#define ADC_OFR4_OFFSET4_EN_Msk (0x1UL << ADC_OFR4_OFFSET4_EN_Pos) /*!< 0x80000000 */ +#define ADC_OFR4_OFFSET4_EN ADC_OFR4_OFFSET4_EN_Msk /*!< ADC offset number 4 enable */ + +/******************** Bit definition for ADC_JDR1 register ******************/ +#define ADC_JDR1_JDATA_Pos (0U) +#define ADC_JDR1_JDATA_Msk (0xFFFFUL << ADC_JDR1_JDATA_Pos) /*!< 0x0000FFFF */ +#define ADC_JDR1_JDATA ADC_JDR1_JDATA_Msk /*!< ADC group injected sequencer rank 1 conversion data */ + +/******************** Bit definition for ADC_JDR2 register ******************/ +#define ADC_JDR2_JDATA_Pos (0U) +#define ADC_JDR2_JDATA_Msk (0xFFFFUL << ADC_JDR2_JDATA_Pos) /*!< 0x0000FFFF */ +#define ADC_JDR2_JDATA ADC_JDR2_JDATA_Msk /*!< ADC group injected sequencer rank 2 conversion data */ + +/******************** Bit definition for ADC_JDR3 register ******************/ +#define ADC_JDR3_JDATA_Pos (0U) +#define ADC_JDR3_JDATA_Msk (0xFFFFUL << ADC_JDR3_JDATA_Pos) /*!< 0x0000FFFF */ +#define ADC_JDR3_JDATA ADC_JDR3_JDATA_Msk /*!< ADC group injected sequencer rank 3 conversion data */ + +/******************** Bit definition for ADC_JDR4 register ******************/ +#define ADC_JDR4_JDATA_Pos (0U) +#define ADC_JDR4_JDATA_Msk (0xFFFFUL << ADC_JDR4_JDATA_Pos) /*!< 0x0000FFFF */ +#define ADC_JDR4_JDATA ADC_JDR4_JDATA_Msk /*!< ADC group injected sequencer rank 4 conversion data */ + +/******************** Bit definition for ADC_AWD2CR register ****************/ +#define ADC_AWD2CR_AWD2CH_Pos (0U) +#define ADC_AWD2CR_AWD2CH_Msk (0xFFFFFUL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x0007FFFF */ +#define ADC_AWD2CR_AWD2CH ADC_AWD2CR_AWD2CH_Msk /*!< ADC analog watchdog 2 monitored channel selection */ +#define ADC_AWD2CR_AWD2CH_0 (0x00001UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000001 */ +#define ADC_AWD2CR_AWD2CH_1 (0x00002UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000002 */ +#define ADC_AWD2CR_AWD2CH_2 (0x00004UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000004 */ +#define ADC_AWD2CR_AWD2CH_3 (0x00008UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000008 */ +#define ADC_AWD2CR_AWD2CH_4 (0x00010UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000010 */ +#define ADC_AWD2CR_AWD2CH_5 (0x00020UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000020 */ +#define ADC_AWD2CR_AWD2CH_6 (0x00040UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000040 */ +#define ADC_AWD2CR_AWD2CH_7 (0x00080UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000080 */ +#define ADC_AWD2CR_AWD2CH_8 (0x00100UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000100 */ +#define ADC_AWD2CR_AWD2CH_9 (0x00200UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000200 */ +#define ADC_AWD2CR_AWD2CH_10 (0x00400UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000400 */ +#define ADC_AWD2CR_AWD2CH_11 (0x00800UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000800 */ +#define ADC_AWD2CR_AWD2CH_12 (0x01000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00001000 */ +#define ADC_AWD2CR_AWD2CH_13 (0x02000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00002000 */ +#define ADC_AWD2CR_AWD2CH_14 (0x04000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00004000 */ +#define ADC_AWD2CR_AWD2CH_15 (0x08000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00008000 */ +#define ADC_AWD2CR_AWD2CH_16 (0x10000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00010000 */ +#define ADC_AWD2CR_AWD2CH_17 (0x20000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00020000 */ +#define ADC_AWD2CR_AWD2CH_18 (0x40000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00040000 */ +#define ADC_AWD2CR_AWD2CH_19 (0x80000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00080000 */ + +/******************** Bit definition for ADC_AWD3CR register ****************/ +#define ADC_AWD3CR_AWD3CH_Pos (0U) +#define ADC_AWD3CR_AWD3CH_Msk (0xFFFFFUL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x0007FFFF */ +#define ADC_AWD3CR_AWD3CH ADC_AWD3CR_AWD3CH_Msk /*!< ADC analog watchdog 3 monitored channel selection */ +#define ADC_AWD3CR_AWD3CH_0 (0x00001UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000001 */ +#define ADC_AWD3CR_AWD3CH_1 (0x00002UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000002 */ +#define ADC_AWD3CR_AWD3CH_2 (0x00004UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000004 */ +#define ADC_AWD3CR_AWD3CH_3 (0x00008UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000008 */ +#define ADC_AWD3CR_AWD3CH_4 (0x00010UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000010 */ +#define ADC_AWD3CR_AWD3CH_5 (0x00020UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000020 */ +#define ADC_AWD3CR_AWD3CH_6 (0x00040UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000040 */ +#define ADC_AWD3CR_AWD3CH_7 (0x00080UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000080 */ +#define ADC_AWD3CR_AWD3CH_8 (0x00100UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000100 */ +#define ADC_AWD3CR_AWD3CH_9 (0x00200UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000200 */ +#define ADC_AWD3CR_AWD3CH_10 (0x00400UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000400 */ +#define ADC_AWD3CR_AWD3CH_11 (0x00800UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000800 */ +#define ADC_AWD3CR_AWD3CH_12 (0x01000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00001000 */ +#define ADC_AWD3CR_AWD3CH_13 (0x02000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00002000 */ +#define ADC_AWD3CR_AWD3CH_14 (0x04000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00004000 */ +#define ADC_AWD3CR_AWD3CH_15 (0x08000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00008000 */ +#define ADC_AWD3CR_AWD3CH_16 (0x10000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00010000 */ +#define ADC_AWD3CR_AWD3CH_17 (0x20000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00020000 */ +#define ADC_AWD3CR_AWD3CH_18 (0x40000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00040000 */ +#define ADC_AWD3CR_AWD2CH_19 (0x80000UL << ADC_AWD3CR_AWD2CH_Pos) /*!< 0x00080000 */ + +/******************** Bit definition for ADC_DIFSEL register ****************/ +#define ADC_DIFSEL_DIFSEL_Pos (0U) +#define ADC_DIFSEL_DIFSEL_Msk (0xFFFFFUL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x0007FFFF */ +#define ADC_DIFSEL_DIFSEL ADC_DIFSEL_DIFSEL_Msk /*!< ADC channel differential or single-ended mode */ +#define ADC_DIFSEL_DIFSEL_0 (0x00001UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000001 */ +#define ADC_DIFSEL_DIFSEL_1 (0x00002UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000002 */ +#define ADC_DIFSEL_DIFSEL_2 (0x00004UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000004 */ +#define ADC_DIFSEL_DIFSEL_3 (0x00008UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000008 */ +#define ADC_DIFSEL_DIFSEL_4 (0x00010UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000010 */ +#define ADC_DIFSEL_DIFSEL_5 (0x00020UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000020 */ +#define ADC_DIFSEL_DIFSEL_6 (0x00040UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000040 */ +#define ADC_DIFSEL_DIFSEL_7 (0x00080UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000080 */ +#define ADC_DIFSEL_DIFSEL_8 (0x00100UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000100 */ +#define ADC_DIFSEL_DIFSEL_9 (0x00200UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000200 */ +#define ADC_DIFSEL_DIFSEL_10 (0x00400UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000400 */ +#define ADC_DIFSEL_DIFSEL_11 (0x00800UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000800 */ +#define ADC_DIFSEL_DIFSEL_12 (0x01000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00001000 */ +#define ADC_DIFSEL_DIFSEL_13 (0x02000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00002000 */ +#define ADC_DIFSEL_DIFSEL_14 (0x04000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00004000 */ +#define ADC_DIFSEL_DIFSEL_15 (0x08000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00008000 */ +#define ADC_DIFSEL_DIFSEL_16 (0x10000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00010000 */ +#define ADC_DIFSEL_DIFSEL_17 (0x20000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00020000 */ +#define ADC_DIFSEL_DIFSEL_18 (0x40000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00040000 */ +#define ADC_DIFSEL_DIFSEL_19 (0x80000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00080000 */ + +/******************** Bit definition for ADC_CALFACT register ***************/ +#define ADC_CALFACT_CALFACT_S_Pos (0U) +#define ADC_CALFACT_CALFACT_S_Msk (0x7FUL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x0000007F */ +#define ADC_CALFACT_CALFACT_S ADC_CALFACT_CALFACT_S_Msk /*!< ADC calibration factor in single-ended mode */ +#define ADC_CALFACT_CALFACT_S_0 (0x01UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000001 */ +#define ADC_CALFACT_CALFACT_S_1 (0x02UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000002 */ +#define ADC_CALFACT_CALFACT_S_2 (0x04UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000004 */ +#define ADC_CALFACT_CALFACT_S_3 (0x08UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000008 */ +#define ADC_CALFACT_CALFACT_S_4 (0x10UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000010 */ +#define ADC_CALFACT_CALFACT_S_5 (0x20UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000020 */ +#define ADC_CALFACT_CALFACT_S_6 (0x40UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000030 */ + +#define ADC_CALFACT_CALFACT_D_Pos (16U) +#define ADC_CALFACT_CALFACT_D_Msk (0x7FUL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x007F0000 */ +#define ADC_CALFACT_CALFACT_D ADC_CALFACT_CALFACT_D_Msk /*!< ADC calibration factor in differential mode */ +#define ADC_CALFACT_CALFACT_D_0 (0x01UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00010000 */ +#define ADC_CALFACT_CALFACT_D_1 (0x02UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00020000 */ +#define ADC_CALFACT_CALFACT_D_2 (0x04UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00040000 */ +#define ADC_CALFACT_CALFACT_D_3 (0x08UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00080000 */ +#define ADC_CALFACT_CALFACT_D_4 (0x10UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00100000 */ +#define ADC_CALFACT_CALFACT_D_5 (0x20UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00200000 */ +#define ADC_CALFACT_CALFACT_D_6 (0x40UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00300000 */ + +/******************** Bit definition for ADC_OR register *****************/ +#define ADC_OR_OP0_Pos (0U) +#define ADC_OR_OP0_Msk (0x01UL << ADC_OR_OP0_Pos) /*!< 0x00000001 */ +#define ADC_OR_OP0 ADC_OR_OP0_Msk /*!< ADC Option bit 0 */ +#define ADC_OR_OP1_Pos (1U) +#define ADC_OR_OP1_Msk (0x01UL << ADC_OR_OP1_Pos) /*!< 0x00000001 */ +#define ADC_OR_OP1 ADC_OR_OP1_Msk /*!< ADC Option bit 1 */ + +/************************* ADC Common registers *****************************/ +/******************** Bit definition for ADC_CSR register *******************/ +#define ADC_CSR_ADRDY_MST_Pos (0U) +#define ADC_CSR_ADRDY_MST_Msk (0x1UL << ADC_CSR_ADRDY_MST_Pos) /*!< 0x00000001 */ +#define ADC_CSR_ADRDY_MST ADC_CSR_ADRDY_MST_Msk /*!< ADC multimode master ready flag */ +#define ADC_CSR_EOSMP_MST_Pos (1U) +#define ADC_CSR_EOSMP_MST_Msk (0x1UL << ADC_CSR_EOSMP_MST_Pos) /*!< 0x00000002 */ +#define ADC_CSR_EOSMP_MST ADC_CSR_EOSMP_MST_Msk /*!< ADC multimode master group regular end of sampling flag */ +#define ADC_CSR_EOC_MST_Pos (2U) +#define ADC_CSR_EOC_MST_Msk (0x1UL << ADC_CSR_EOC_MST_Pos) /*!< 0x00000004 */ +#define ADC_CSR_EOC_MST ADC_CSR_EOC_MST_Msk /*!< ADC multimode master group regular end of unitary conversion flag */ +#define ADC_CSR_EOS_MST_Pos (3U) +#define ADC_CSR_EOS_MST_Msk (0x1UL << ADC_CSR_EOS_MST_Pos) /*!< 0x00000008 */ +#define ADC_CSR_EOS_MST ADC_CSR_EOS_MST_Msk /*!< ADC multimode master group regular end of sequence conversions flag */ +#define ADC_CSR_OVR_MST_Pos (4U) +#define ADC_CSR_OVR_MST_Msk (0x1UL << ADC_CSR_OVR_MST_Pos) /*!< 0x00000010 */ +#define ADC_CSR_OVR_MST ADC_CSR_OVR_MST_Msk /*!< ADC multimode master group regular overrun flag */ +#define ADC_CSR_JEOC_MST_Pos (5U) +#define ADC_CSR_JEOC_MST_Msk (0x1UL << ADC_CSR_JEOC_MST_Pos) /*!< 0x00000020 */ +#define ADC_CSR_JEOC_MST ADC_CSR_JEOC_MST_Msk /*!< ADC multimode master group injected end of unitary conversion flag */ +#define ADC_CSR_JEOS_MST_Pos (6U) +#define ADC_CSR_JEOS_MST_Msk (0x1UL << ADC_CSR_JEOS_MST_Pos) /*!< 0x00000040 */ +#define ADC_CSR_JEOS_MST ADC_CSR_JEOS_MST_Msk /*!< ADC multimode master group injected end of sequence conversions flag */ +#define ADC_CSR_AWD1_MST_Pos (7U) +#define ADC_CSR_AWD1_MST_Msk (0x1UL << ADC_CSR_AWD1_MST_Pos) /*!< 0x00000080 */ +#define ADC_CSR_AWD1_MST ADC_CSR_AWD1_MST_Msk /*!< ADC multimode master analog watchdog 1 flag */ +#define ADC_CSR_AWD2_MST_Pos (8U) +#define ADC_CSR_AWD2_MST_Msk (0x1UL << ADC_CSR_AWD2_MST_Pos) /*!< 0x00000100 */ +#define ADC_CSR_AWD2_MST ADC_CSR_AWD2_MST_Msk /*!< ADC multimode master analog watchdog 2 flag */ +#define ADC_CSR_AWD3_MST_Pos (9U) +#define ADC_CSR_AWD3_MST_Msk (0x1UL << ADC_CSR_AWD3_MST_Pos) /*!< 0x00000200 */ +#define ADC_CSR_AWD3_MST ADC_CSR_AWD3_MST_Msk /*!< ADC multimode master analog watchdog 3 flag */ +#define ADC_CSR_JQOVF_MST_Pos (10U) +#define ADC_CSR_JQOVF_MST_Msk (0x1UL << ADC_CSR_JQOVF_MST_Pos) /*!< 0x00000400 */ +#define ADC_CSR_JQOVF_MST ADC_CSR_JQOVF_MST_Msk /*!< ADC multimode master group injected contexts queue overflow flag */ + +#define ADC_CSR_ADRDY_SLV_Pos (16U) +#define ADC_CSR_ADRDY_SLV_Msk (0x1UL << ADC_CSR_ADRDY_SLV_Pos) /*!< 0x00010000 */ +#define ADC_CSR_ADRDY_SLV ADC_CSR_ADRDY_SLV_Msk /*!< ADC multimode slave ready flag */ +#define ADC_CSR_EOSMP_SLV_Pos (17U) +#define ADC_CSR_EOSMP_SLV_Msk (0x1UL << ADC_CSR_EOSMP_SLV_Pos) /*!< 0x00020000 */ +#define ADC_CSR_EOSMP_SLV ADC_CSR_EOSMP_SLV_Msk /*!< ADC multimode slave group regular end of sampling flag */ +#define ADC_CSR_EOC_SLV_Pos (18U) +#define ADC_CSR_EOC_SLV_Msk (0x1UL << ADC_CSR_EOC_SLV_Pos) /*!< 0x00040000 */ +#define ADC_CSR_EOC_SLV ADC_CSR_EOC_SLV_Msk /*!< ADC multimode slave group regular end of unitary conversion flag */ +#define ADC_CSR_EOS_SLV_Pos (19U) +#define ADC_CSR_EOS_SLV_Msk (0x1UL << ADC_CSR_EOS_SLV_Pos) /*!< 0x00080000 */ +#define ADC_CSR_EOS_SLV ADC_CSR_EOS_SLV_Msk /*!< ADC multimode slave group regular end of sequence conversions flag */ +#define ADC_CSR_OVR_SLV_Pos (20U) +#define ADC_CSR_OVR_SLV_Msk (0x1UL << ADC_CSR_OVR_SLV_Pos) /*!< 0x00100000 */ +#define ADC_CSR_OVR_SLV ADC_CSR_OVR_SLV_Msk /*!< ADC multimode slave group regular overrun flag */ +#define ADC_CSR_JEOC_SLV_Pos (21U) +#define ADC_CSR_JEOC_SLV_Msk (0x1UL << ADC_CSR_JEOC_SLV_Pos) /*!< 0x00200000 */ +#define ADC_CSR_JEOC_SLV ADC_CSR_JEOC_SLV_Msk /*!< ADC multimode slave group injected end of unitary conversion flag */ +#define ADC_CSR_JEOS_SLV_Pos (22U) +#define ADC_CSR_JEOS_SLV_Msk (0x1UL << ADC_CSR_JEOS_SLV_Pos) /*!< 0x00400000 */ +#define ADC_CSR_JEOS_SLV ADC_CSR_JEOS_SLV_Msk /*!< ADC multimode slave group injected end of sequence conversions flag */ +#define ADC_CSR_AWD1_SLV_Pos (23U) +#define ADC_CSR_AWD1_SLV_Msk (0x1UL << ADC_CSR_AWD1_SLV_Pos) /*!< 0x00800000 */ +#define ADC_CSR_AWD1_SLV ADC_CSR_AWD1_SLV_Msk /*!< ADC multimode slave analog watchdog 1 flag */ +#define ADC_CSR_AWD2_SLV_Pos (24U) +#define ADC_CSR_AWD2_SLV_Msk (0x1UL << ADC_CSR_AWD2_SLV_Pos) /*!< 0x01000000 */ +#define ADC_CSR_AWD2_SLV ADC_CSR_AWD2_SLV_Msk /*!< ADC multimode slave analog watchdog 2 flag */ +#define ADC_CSR_AWD3_SLV_Pos (25U) +#define ADC_CSR_AWD3_SLV_Msk (0x1UL << ADC_CSR_AWD3_SLV_Pos) /*!< 0x02000000 */ +#define ADC_CSR_AWD3_SLV ADC_CSR_AWD3_SLV_Msk /*!< ADC multimode slave analog watchdog 3 flag */ +#define ADC_CSR_JQOVF_SLV_Pos (26U) +#define ADC_CSR_JQOVF_SLV_Msk (0x1UL << ADC_CSR_JQOVF_SLV_Pos) /*!< 0x04000000 */ +#define ADC_CSR_JQOVF_SLV ADC_CSR_JQOVF_SLV_Msk /*!< ADC multimode slave group injected contexts queue overflow flag */ + +/******************** Bit definition for ADC_CCR register *******************/ +#define ADC_CCR_DUAL_Pos (0U) +#define ADC_CCR_DUAL_Msk (0x1FUL << ADC_CCR_DUAL_Pos) /*!< 0x0000001F */ +#define ADC_CCR_DUAL ADC_CCR_DUAL_Msk /*!< ADC multimode mode selection */ +#define ADC_CCR_DUAL_0 (0x01UL << ADC_CCR_DUAL_Pos) /*!< 0x00000001 */ +#define ADC_CCR_DUAL_1 (0x02UL << ADC_CCR_DUAL_Pos) /*!< 0x00000002 */ +#define ADC_CCR_DUAL_2 (0x04UL << ADC_CCR_DUAL_Pos) /*!< 0x00000004 */ +#define ADC_CCR_DUAL_3 (0x08UL << ADC_CCR_DUAL_Pos) /*!< 0x00000008 */ +#define ADC_CCR_DUAL_4 (0x10UL << ADC_CCR_DUAL_Pos) /*!< 0x00000010 */ + +#define ADC_CCR_DELAY_Pos (8U) +#define ADC_CCR_DELAY_Msk (0xFUL << ADC_CCR_DELAY_Pos) /*!< 0x00000F00 */ +#define ADC_CCR_DELAY ADC_CCR_DELAY_Msk /*!< ADC multimode delay between 2 sampling phases */ +#define ADC_CCR_DELAY_0 (0x1UL << ADC_CCR_DELAY_Pos) /*!< 0x00000100 */ +#define ADC_CCR_DELAY_1 (0x2UL << ADC_CCR_DELAY_Pos) /*!< 0x00000200 */ +#define ADC_CCR_DELAY_2 (0x4UL << ADC_CCR_DELAY_Pos) /*!< 0x00000400 */ +#define ADC_CCR_DELAY_3 (0x8UL << ADC_CCR_DELAY_Pos) /*!< 0x00000800 */ + +#define ADC_CCR_DMACFG_Pos (13U) +#define ADC_CCR_DMACFG_Msk (0x1UL << ADC_CCR_DMACFG_Pos) /*!< 0x00002000 */ +#define ADC_CCR_DMACFG ADC_CCR_DMACFG_Msk /*!< ADC multimode DMA transfer configuration */ + +#define ADC_CCR_MDMA_Pos (14U) +#define ADC_CCR_MDMA_Msk (0x3UL << ADC_CCR_MDMA_Pos) /*!< 0x0000C000 */ +#define ADC_CCR_MDMA ADC_CCR_MDMA_Msk /*!< ADC multimode DMA transfer enable */ +#define ADC_CCR_MDMA_0 (0x1UL << ADC_CCR_MDMA_Pos) /*!< 0x00004000 */ +#define ADC_CCR_MDMA_1 (0x2UL << ADC_CCR_MDMA_Pos) /*!< 0x00008000 */ + +#define ADC_CCR_CKMODE_Pos (16U) +#define ADC_CCR_CKMODE_Msk (0x3UL << ADC_CCR_CKMODE_Pos) /*!< 0x00030000 */ +#define ADC_CCR_CKMODE ADC_CCR_CKMODE_Msk /*!< ADC common clock source and prescaler (prescaler only for clock source synchronous) */ +#define ADC_CCR_CKMODE_0 (0x1UL << ADC_CCR_CKMODE_Pos) /*!< 0x00010000 */ +#define ADC_CCR_CKMODE_1 (0x2UL << ADC_CCR_CKMODE_Pos) /*!< 0x00020000 */ + +#define ADC_CCR_PRESC_Pos (18U) +#define ADC_CCR_PRESC_Msk (0xFUL << ADC_CCR_PRESC_Pos) /*!< 0x003C0000 */ +#define ADC_CCR_PRESC ADC_CCR_PRESC_Msk /*!< ADC common clock prescaler, only for clock source asynchronous */ +#define ADC_CCR_PRESC_0 (0x1UL << ADC_CCR_PRESC_Pos) /*!< 0x00040000 */ +#define ADC_CCR_PRESC_1 (0x2UL << ADC_CCR_PRESC_Pos) /*!< 0x00080000 */ +#define ADC_CCR_PRESC_2 (0x4UL << ADC_CCR_PRESC_Pos) /*!< 0x00100000 */ +#define ADC_CCR_PRESC_3 (0x8UL << ADC_CCR_PRESC_Pos) /*!< 0x00200000 */ + +#define ADC_CCR_VREFEN_Pos (22U) +#define ADC_CCR_VREFEN_Msk (0x1UL << ADC_CCR_VREFEN_Pos) /*!< 0x00400000 */ +#define ADC_CCR_VREFEN ADC_CCR_VREFEN_Msk /*!< ADC internal path to VrefInt enable */ +#define ADC_CCR_TSEN_Pos (23U) +#define ADC_CCR_TSEN_Msk (0x1UL << ADC_CCR_TSEN_Pos) /*!< 0x00800000 */ +#define ADC_CCR_TSEN ADC_CCR_TSEN_Msk /*!< ADC internal path to temperature sensor enable */ +#define ADC_CCR_VBATEN_Pos (24U) +#define ADC_CCR_VBATEN_Msk (0x1UL << ADC_CCR_VBATEN_Pos) /*!< 0x01000000 */ +#define ADC_CCR_VBATEN ADC_CCR_VBATEN_Msk /*!< ADC internal path to battery voltage enable */ + +/******************** Bit definition for ADC_CDR register *******************/ +#define ADC_CDR_RDATA_MST_Pos (0U) +#define ADC_CDR_RDATA_MST_Msk (0xFFFFUL << ADC_CDR_RDATA_MST_Pos) /*!< 0x0000FFFF */ +#define ADC_CDR_RDATA_MST ADC_CDR_RDATA_MST_Msk /*!< ADC multimode master group regular conversion data */ + +#define ADC_CDR_RDATA_SLV_Pos (16U) +#define ADC_CDR_RDATA_SLV_Msk (0xFFFFUL << ADC_CDR_RDATA_SLV_Pos) /*!< 0xFFFF0000 */ +#define ADC_CDR_RDATA_SLV ADC_CDR_RDATA_SLV_Msk /*!< ADC multimode slave group regular conversion data */ + + +/**********************************************************************************************************************/ +/* */ +/* Analog Comparators (COMP) */ +/* */ +/**********************************************************************************************************************/ + +/********************************** Bit definition for COMP_SR register *****************************************/ +#define COMP_SR_C1VAL_Pos (0U) +#define COMP_SR_C1VAL_Msk (0x1UL << COMP_SR_C1VAL_Pos) /*!< 0x00000001 */ +#define COMP_SR_C1VAL COMP_SR_C1VAL_Msk + +#define COMP_SR_C1IF_Pos (16U) +#define COMP_SR_C1IF_Msk (0x1UL << COMP_SR_C1IF_Pos) /*!< 0x00010000 */ +#define COMP_SR_C1IF COMP_SR_C1IF_Msk + +/********************************** Bit definition for COMP_ICFR register *****************************************/ +#define COMP_ICFR_CC1IF_Pos (16U) +#define COMP_ICFR_CC1IF_Msk (0x1UL << COMP_ICFR_CC1IF_Pos) /*!< 0x00010000 */ +#define COMP_ICFR_CC1IF COMP_ICFR_CC1IF_Msk + +/********************************** Bit definition for COMP_CFGR1 register **************************************/ +#define COMP_CFGR1_EN_Pos (0U) +#define COMP_CFGR1_EN_Msk (0x1UL << COMP_CFGR1_EN_Pos) /*!< 0x00000001 */ +#define COMP_CFGR1_EN COMP_CFGR1_EN_Msk /*!< COMP1 enable bit */ + +#define COMP_CFGR1_BRGEN_Pos (1U) +#define COMP_CFGR1_BRGEN_Msk (0x1UL << COMP_CFGR1_BRGEN_Pos) /*!< 0x00000002 */ +#define COMP_CFGR1_BRGEN COMP_CFGR1_BRGEN_Msk /*!< COMP1 Scaler bridge enable */ + +#define COMP_CFGR1_SCALEN_Pos (2U) +#define COMP_CFGR1_SCALEN_Msk (0x1UL << COMP_CFGR1_SCALEN_Pos) /*!< 0x00000004 */ +#define COMP_CFGR1_SCALEN COMP_CFGR1_SCALEN_Msk /*!< COMP1 Voltage scaler enable bit */ + +#define COMP_CFGR1_POLARITY_Pos (3U) +#define COMP_CFGR1_POLARITY_Msk (0x1UL << COMP_CFGR1_POLARITY_Pos) /*!< 0x00000008 */ +#define COMP_CFGR1_POLARITY COMP_CFGR1_POLARITY_Msk /*!< COMP1 polarity selection bit */ + +#define COMP_CFGR1_ITEN_Pos (6U) +#define COMP_CFGR1_ITEN_Msk (0x1UL << COMP_CFGR1_ITEN_Pos) /*!< 0x00000040 */ +#define COMP_CFGR1_ITEN COMP_CFGR1_ITEN_Msk /*!< COMP1 interrupt enable */ + +#define COMP_CFGR1_HYST_Pos (8U) +#define COMP_CFGR1_HYST_Msk (0x3UL << COMP_CFGR1_HYST_Pos) /*!< 0x00000300 */ +#define COMP_CFGR1_HYST COMP_CFGR1_HYST_Msk /*!< COMP1 hysteresis selection bits */ +#define COMP_CFGR1_HYST_0 (0x1UL << COMP_CFGR1_HYST_Pos) /*!< 0x00000100 */ +#define COMP_CFGR1_HYST_1 (0x2UL << COMP_CFGR1_HYST_Pos) /*!< 0x00000200 */ + +#define COMP_CFGR1_PWRMODE_Pos (12U) +#define COMP_CFGR1_PWRMODE_Msk (0x3UL << COMP_CFGR1_PWRMODE_Pos) /*!< 0x00003000 */ +#define COMP_CFGR1_PWRMODE COMP_CFGR1_PWRMODE_Msk /*!< COMP1 Power Mode of the comparator */ +#define COMP_CFGR1_PWRMODE_0 (0x1UL << COMP_CFGR1_PWRMODE_Pos) /*!< 0x00001000 */ +#define COMP_CFGR1_PWRMODE_1 (0x2UL << COMP_CFGR1_PWRMODE_Pos) /*!< 0x00002000 */ + +#define COMP_CFGR1_INMSEL_Pos (16U) +#define COMP_CFGR1_INMSEL_Msk (0xFUL << COMP_CFGR1_INMSEL_Pos) /*!< 0x000F0000 */ +#define COMP_CFGR1_INMSEL COMP_CFGR1_INMSEL_Msk /*!< COMP1 input minus selection bit */ +#define COMP_CFGR1_INMSEL_0 (0x1UL << COMP_CFGR1_INMSEL_Pos) /*!< 0x00010000 */ +#define COMP_CFGR1_INMSEL_1 (0x2UL << COMP_CFGR1_INMSEL_Pos) /*!< 0x00020000 */ +#define COMP_CFGR1_INMSEL_2 (0x4UL << COMP_CFGR1_INMSEL_Pos) /*!< 0x00040000 */ +#define COMP_CFGR1_INMSEL_3 (0x8UL << COMP_CFGR1_INMSEL_Pos) /*!< 0x00080000 */ + +#define COMP_CFGR1_INPSEL1_Pos (20U) +#define COMP_CFGR1_INPSEL1_Msk (0x1UL << COMP_CFGR1_INPSEL1_Pos) /*!< 0x00100000 */ +#define COMP_CFGR1_INPSEL1 COMP_CFGR1_INPSEL1_Msk /*!< COMP1 input plus 1 selection bit */ + +#define COMP_CFGR1_INPSEL2_Pos (22U) +#define COMP_CFGR1_INPSEL2_Msk (0x1UL << COMP_CFGR1_INPSEL2_Pos) /*!< 0x00400000 */ +#define COMP_CFGR1_INPSEL2 COMP_CFGR1_INPSEL2_Msk /*!< COMP1 input plus 2 selection bit */ + +#define COMP_CFGR1_BLANKING_Pos (24U) +#define COMP_CFGR1_BLANKING_Msk (0xFUL << COMP_CFGR1_BLANKING_Pos) /*!< 0x0F000000 */ +#define COMP_CFGR1_BLANKING COMP_CFGR1_BLANKING_Msk /*!< COMP1 blanking source selection bits */ +#define COMP_CFGR1_BLANKING_0 (0x1UL << COMP_CFGR1_BLANKING_Pos) /*!< 0x01000000 */ +#define COMP_CFGR1_BLANKING_1 (0x2UL << COMP_CFGR1_BLANKING_Pos) /*!< 0x02000000 */ +#define COMP_CFGR1_BLANKING_2 (0x4UL << COMP_CFGR1_BLANKING_Pos) /*!< 0x04000000 */ +#define COMP_CFGR1_BLANKING_3 (0x8UL << COMP_CFGR1_BLANKING_Pos) /*!< 0x08000000 */ + +#define COMP_CFGR1_LOCK_Pos (31U) +#define COMP_CFGR1_LOCK_Msk (0x1UL << COMP_CFGR1_LOCK_Pos) /*!< 0x80000000 */ +#define COMP_CFGR1_LOCK COMP_CFGR1_LOCK_Msk /*!< COMP1 Lock Bit */ + +/********************************* Bit definition for COMP_CFGR2 register *******************************************/ +#define COMP_CFGR2_INPSEL0_Pos (4U) +#define COMP_CFGR2_INPSEL0_Msk (0x1UL << COMP_CFGR2_INPSEL0_Pos) /*!< 0x00000010 */ +#define COMP_CFGR2_INPSEL0 COMP_CFGR2_INPSEL0_Msk /*!< COMP1 input plus 0 selection bit */ + +/**********************************************************************************************************************/ +/* */ +/* Operational Amplifier (OPAMP) */ +/* */ +/**********************************************************************************************************************/ + +/********************************** Bit definition for OPAMP_CSR register *****************************************/ +#define OPAMP_CSR_OPAMPxEN_Pos (0U) +#define OPAMP_CSR_OPAMPxEN_Msk (0x1UL << OPAMP_CSR_OPAMPxEN_Pos) /*!< 0x00000001 */ +#define OPAMP_CSR_OPAMPxEN OPAMP_CSR_OPAMPxEN_Msk /*!< OPAMP enable */ + +#define OPAMP_CSR_FORCEVP_Pos (1U) +#define OPAMP_CSR_FORCEVP_Msk (0x1UL << OPAMP_CSR_FORCEVP_Pos) /*!< 0x00000002 */ +#define OPAMP_CSR_FORCEVP OPAMP_CSR_FORCEVP_Msk /*!< Force internal reference on VP */ + +#define OPAMP_CSR_VPSEL_Pos (2U) +#define OPAMP_CSR_VPSEL_Msk (0x3UL << OPAMP_CSR_VPSEL_Pos) /*!< 0x0000000C */ +#define OPAMP_CSR_VPSEL OPAMP_CSR_VPSEL_Msk /*!< Non inverted input selection */ +#define OPAMP_CSR_VPSEL_0 (0x1UL << OPAMP_CSR_VPSEL_Pos) /*!< 0x00000004 */ +#define OPAMP_CSR_VPSEL_1 (0x2UL << OPAMP_CSR_VPSEL_Pos) /*!< 0x00000008 */ + +#define OPAMP_CSR_VMSEL_Pos (5U) +#define OPAMP_CSR_VMSEL_Msk (0x3UL << OPAMP_CSR_VMSEL_Pos) /*!< 0x00000060 */ +#define OPAMP_CSR_VMSEL OPAMP_CSR_VMSEL_Msk /*!< Inverting input selection */ +#define OPAMP_CSR_VMSEL_0 (0x1UL << OPAMP_CSR_VMSEL_Pos) /*!< 0x00000020 */ +#define OPAMP_CSR_VMSEL_1 (0x2UL << OPAMP_CSR_VMSEL_Pos) /*!< 0x00000040 */ + +#define OPAMP_CSR_OPAHSM_Pos (8U) +#define OPAMP_CSR_OPAHSM_Msk (0x1UL << OPAMP_CSR_OPAHSM_Pos) /*!< 0x00000100 */ +#define OPAMP_CSR_OPAHSM OPAMP_CSR_OPAHSM_Msk /*!< high speed mode */ + +#define OPAMP_CSR_CALON_Pos (11U) +#define OPAMP_CSR_CALON_Msk (0x1UL << OPAMP_CSR_CALON_Pos) /*!< 0x00000800 */ +#define OPAMP_CSR_CALON OPAMP_CSR_CALON_Msk /*!< Calibration mode enable */ + +#define OPAMP_CSR_CALSEL_Pos (12U) +#define OPAMP_CSR_CALSEL_Msk (0x3UL << OPAMP_CSR_CALSEL_Pos) /*!< 0x00003000 */ +#define OPAMP_CSR_CALSEL OPAMP_CSR_CALSEL_Msk /*!< Calibration selection */ +#define OPAMP_CSR_CALSEL_0 (0x1UL << OPAMP_CSR_CALSEL_Pos) /*!< 0x00001000 */ +#define OPAMP_CSR_CALSEL_1 (0x2UL << OPAMP_CSR_CALSEL_Pos) /*!< 0x00002000 */ + +#define OPAMP_CSR_PGGAIN_Pos (14U) +#define OPAMP_CSR_PGGAIN_Msk (0xFUL << OPAMP_CSR_PGGAIN_Pos) /*!< 0x0003C000 */ +#define OPAMP_CSR_PGGAIN OPAMP_CSR_PGGAIN_Msk /*!< Programmable amplifier gain value */ +#define OPAMP_CSR_PGGAIN_0 (0x1UL << OPAMP_CSR_PGGAIN_Pos) /*!< 0x00004000 */ +#define OPAMP_CSR_PGGAIN_1 (0x2UL << OPAMP_CSR_PGGAIN_Pos) /*!< 0x00008000 */ +#define OPAMP_CSR_PGGAIN_2 (0x4UL << OPAMP_CSR_PGGAIN_Pos) /*!< 0x00010000 */ +#define OPAMP_CSR_PGGAIN_3 (0x8UL << OPAMP_CSR_PGGAIN_Pos) /*!< 0x00020000 */ + +#define OPAMP_CSR_USERTRIM_Pos (18U) +#define OPAMP_CSR_USERTRIM_Msk (0x1UL << OPAMP_CSR_USERTRIM_Pos) /*!< 0x00040000 */ +#define OPAMP_CSR_USERTRIM OPAMP_CSR_USERTRIM_Msk /*!< User trimming enable */ + +#define OPAMP_CSR_TSTREF_Pos (29U) +#define OPAMP_CSR_TSTREF_Msk (0x1UL << OPAMP_CSR_TSTREF_Pos) /*!< 0x20000000 */ +#define OPAMP_CSR_TSTREF OPAMP_CSR_TSTREF_Msk /*!< calibration reference voltage output */ + +#define OPAMP_CSR_CALOUT_Pos (30U) +#define OPAMP_CSR_CALOUT_Msk (0x1UL << OPAMP_CSR_CALOUT_Pos) /*!< 0x40000000 */ +#define OPAMP_CSR_CALOUT OPAMP_CSR_CALOUT_Msk /*!< Calibration output */ + +/********************************** Bit definition for OPAMP_OTR register ******************************************/ +#define OPAMP_OTR_TRIMOFFSETN_Pos (0U) +#define OPAMP_OTR_TRIMOFFSETN_Msk (0x1FUL << OPAMP_OTR_TRIMOFFSETN_Pos) /*!< 0x0000001F */ +#define OPAMP_OTR_TRIMOFFSETN OPAMP_OTR_TRIMOFFSETN_Msk /*!< Trim for NMOS differential pairs */ + +#define OPAMP_OTR_TRIMOFFSETP_Pos (8U) +#define OPAMP_OTR_TRIMOFFSETP_Msk (0x1FUL << OPAMP_OTR_TRIMOFFSETP_Pos) /*!< 0x00001F00 */ +#define OPAMP_OTR_TRIMOFFSETP OPAMP_OTR_TRIMOFFSETP_Msk /*!< Trim for PMOS differential pairs */ + +/********************************** Bit definition for OPAMP_HSOTR register ***************************************/ +#define OPAMP_HSOTR_TRIMHSOFFSETN_Pos (0U) +#define OPAMP_HSOTR_TRIMHSOFFSETN_Msk (0x1FUL << OPAMP_HSOTR_TRIMHSOFFSETN_Pos) /*!< 0x0000001F */ +#define OPAMP_HSOTR_TRIMHSOFFSETN OPAMP_HSOTR_TRIMHSOFFSETN_Msk /*!< Trim for NMOS pairs */ + +#define OPAMP_HSOTR_TRIMHSOFFSETP_Pos (8U) +#define OPAMP_HSOTR_TRIMHSOFFSETP_Msk (0x1FUL << OPAMP_HSOTR_TRIMHSOFFSETP_Pos) /*!< 0x00001F00 */ +#define OPAMP_HSOTR_TRIMHSOFFSETP OPAMP_HSOTR_TRIMHSOFFSETP_Msk /*!< Trim for PMOS pairs */ + + +/******************************************************************************/ +/* */ +/* CRC calculation unit */ +/* */ +/******************************************************************************/ +/******************* Bit definition for CRC_DR register *********************/ +#define CRC_DR_DR_Pos (0U) +#define CRC_DR_DR_Msk (0xFFFFFFFFUL << CRC_DR_DR_Pos) /*!< 0xFFFFFFFF */ +#define CRC_DR_DR CRC_DR_DR_Msk /*!< Data register bits */ + +/******************* Bit definition for CRC_IDR register ********************/ +#define CRC_IDR_IDR_Pos (0U) +#define CRC_IDR_IDR_Msk (0xFFFFFFFFUL << CRC_IDR_IDR_Pos) /*!< 0xFFFFFFFF */ +#define CRC_IDR_IDR CRC_IDR_IDR_Msk /*!< General-purpose 32-bits data register bits */ + +/******************** Bit definition for CRC_CR register ********************/ +#define CRC_CR_RESET_Pos (0U) +#define CRC_CR_RESET_Msk (0x1UL << CRC_CR_RESET_Pos) /*!< 0x00000001 */ +#define CRC_CR_RESET CRC_CR_RESET_Msk /*!< RESET the CRC computation unit bit */ +#define CRC_CR_POLYSIZE_Pos (3U) +#define CRC_CR_POLYSIZE_Msk (0x3UL << CRC_CR_POLYSIZE_Pos) /*!< 0x00000018 */ +#define CRC_CR_POLYSIZE CRC_CR_POLYSIZE_Msk /*!< Polynomial size bits */ +#define CRC_CR_POLYSIZE_0 (0x1UL << CRC_CR_POLYSIZE_Pos) /*!< 0x00000008 */ +#define CRC_CR_POLYSIZE_1 (0x2UL << CRC_CR_POLYSIZE_Pos) /*!< 0x00000010 */ +#define CRC_CR_REV_IN_Pos (5U) +#define CRC_CR_REV_IN_Msk (0x3UL << CRC_CR_REV_IN_Pos) /*!< 0x00000060 */ +#define CRC_CR_REV_IN CRC_CR_REV_IN_Msk /*!< REV_IN Reverse Input Data bits */ +#define CRC_CR_REV_IN_0 (0x1UL << CRC_CR_REV_IN_Pos) /*!< 0x00000020 */ +#define CRC_CR_REV_IN_1 (0x2UL << CRC_CR_REV_IN_Pos) /*!< 0x00000040 */ +#define CRC_CR_REV_OUT_Pos (7U) +#define CRC_CR_REV_OUT_Msk (0x1UL << CRC_CR_REV_OUT_Pos) /*!< 0x00000080 */ +#define CRC_CR_REV_OUT CRC_CR_REV_OUT_Msk /*!< REV_OUT Reverse Output Data bits */ + +/******************* Bit definition for CRC_INIT register *******************/ +#define CRC_INIT_INIT_Pos (0U) +#define CRC_INIT_INIT_Msk (0xFFFFFFFFUL << CRC_INIT_INIT_Pos) /*!< 0xFFFFFFFF */ +#define CRC_INIT_INIT CRC_INIT_INIT_Msk /*!< Initial CRC value bits */ + +/******************* Bit definition for CRC_POL register ********************/ +#define CRC_POL_POL_Pos (0U) +#define CRC_POL_POL_Msk (0xFFFFFFFFUL << CRC_POL_POL_Pos) /*!< 0xFFFFFFFF */ +#define CRC_POL_POL CRC_POL_POL_Msk /*!< Coefficients of the polynomial */ + + +/******************************************************************************/ +/* */ +/* CRS Clock Recovery System */ +/******************************************************************************/ +/******************* Bit definition for CRS_CR register *********************/ +#define CRS_CR_SYNCOKIE_Pos (0U) +#define CRS_CR_SYNCOKIE_Msk (0x1UL << CRS_CR_SYNCOKIE_Pos) /*!< 0x00000001 */ +#define CRS_CR_SYNCOKIE CRS_CR_SYNCOKIE_Msk /*!< SYNC event OK interrupt enable */ +#define CRS_CR_SYNCWARNIE_Pos (1U) +#define CRS_CR_SYNCWARNIE_Msk (0x1UL << CRS_CR_SYNCWARNIE_Pos) /*!< 0x00000002 */ +#define CRS_CR_SYNCWARNIE CRS_CR_SYNCWARNIE_Msk /*!< SYNC warning interrupt enable */ +#define CRS_CR_ERRIE_Pos (2U) +#define CRS_CR_ERRIE_Msk (0x1UL << CRS_CR_ERRIE_Pos) /*!< 0x00000004 */ +#define CRS_CR_ERRIE CRS_CR_ERRIE_Msk /*!< SYNC error or trimming error interrupt enable */ +#define CRS_CR_ESYNCIE_Pos (3U) +#define CRS_CR_ESYNCIE_Msk (0x1UL << CRS_CR_ESYNCIE_Pos) /*!< 0x00000008 */ +#define CRS_CR_ESYNCIE CRS_CR_ESYNCIE_Msk /*!< Expected SYNC interrupt enable */ +#define CRS_CR_CEN_Pos (5U) +#define CRS_CR_CEN_Msk (0x1UL << CRS_CR_CEN_Pos) /*!< 0x00000020 */ +#define CRS_CR_CEN CRS_CR_CEN_Msk /*!< Frequency error counter enable */ +#define CRS_CR_AUTOTRIMEN_Pos (6U) +#define CRS_CR_AUTOTRIMEN_Msk (0x1UL << CRS_CR_AUTOTRIMEN_Pos) /*!< 0x00000040 */ +#define CRS_CR_AUTOTRIMEN CRS_CR_AUTOTRIMEN_Msk /*!< Automatic trimming enable */ +#define CRS_CR_SWSYNC_Pos (7U) +#define CRS_CR_SWSYNC_Msk (0x1UL << CRS_CR_SWSYNC_Pos) /*!< 0x00000080 */ +#define CRS_CR_SWSYNC CRS_CR_SWSYNC_Msk /*!< Generate software SYNC event */ +#define CRS_CR_TRIM_Pos (8U) +#define CRS_CR_TRIM_Msk (0x3FUL << CRS_CR_TRIM_Pos) /*!< 0x00003F00 */ +#define CRS_CR_TRIM CRS_CR_TRIM_Msk /*!< HSI48 oscillator smooth trimming */ + +/******************* Bit definition for CRS_CFGR register *********************/ +#define CRS_CFGR_RELOAD_Pos (0U) +#define CRS_CFGR_RELOAD_Msk (0xFFFFUL << CRS_CFGR_RELOAD_Pos) /*!< 0x0000FFFF */ +#define CRS_CFGR_RELOAD CRS_CFGR_RELOAD_Msk /*!< Counter reload value */ +#define CRS_CFGR_FELIM_Pos (16U) +#define CRS_CFGR_FELIM_Msk (0xFFUL << CRS_CFGR_FELIM_Pos) /*!< 0x00FF0000 */ +#define CRS_CFGR_FELIM CRS_CFGR_FELIM_Msk /*!< Frequency error limit */ +#define CRS_CFGR_SYNCDIV_Pos (24U) +#define CRS_CFGR_SYNCDIV_Msk (0x7UL << CRS_CFGR_SYNCDIV_Pos) /*!< 0x07000000 */ +#define CRS_CFGR_SYNCDIV CRS_CFGR_SYNCDIV_Msk /*!< SYNC divider */ +#define CRS_CFGR_SYNCDIV_0 (0x1UL << CRS_CFGR_SYNCDIV_Pos) /*!< 0x01000000 */ +#define CRS_CFGR_SYNCDIV_1 (0x2UL << CRS_CFGR_SYNCDIV_Pos) /*!< 0x02000000 */ +#define CRS_CFGR_SYNCDIV_2 (0x4UL << CRS_CFGR_SYNCDIV_Pos) /*!< 0x04000000 */ +#define CRS_CFGR_SYNCSRC_Pos (28U) +#define CRS_CFGR_SYNCSRC_Msk (0x3UL << CRS_CFGR_SYNCSRC_Pos) /*!< 0x30000000 */ +#define CRS_CFGR_SYNCSRC CRS_CFGR_SYNCSRC_Msk /*!< SYNC signal source selection */ +#define CRS_CFGR_SYNCSRC_0 (0x1UL << CRS_CFGR_SYNCSRC_Pos) /*!< 0x10000000 */ +#define CRS_CFGR_SYNCSRC_1 (0x2UL << CRS_CFGR_SYNCSRC_Pos) /*!< 0x20000000 */ +#define CRS_CFGR_SYNCPOL_Pos (31U) +#define CRS_CFGR_SYNCPOL_Msk (0x1UL << CRS_CFGR_SYNCPOL_Pos) /*!< 0x80000000 */ +#define CRS_CFGR_SYNCPOL CRS_CFGR_SYNCPOL_Msk /*!< SYNC polarity selection */ + +/******************* Bit definition for CRS_ISR register *********************/ +#define CRS_ISR_SYNCOKF_Pos (0U) +#define CRS_ISR_SYNCOKF_Msk (0x1UL << CRS_ISR_SYNCOKF_Pos) /*!< 0x00000001 */ +#define CRS_ISR_SYNCOKF CRS_ISR_SYNCOKF_Msk /*!< SYNC event OK flag */ +#define CRS_ISR_SYNCWARNF_Pos (1U) +#define CRS_ISR_SYNCWARNF_Msk (0x1UL << CRS_ISR_SYNCWARNF_Pos) /*!< 0x00000002 */ +#define CRS_ISR_SYNCWARNF CRS_ISR_SYNCWARNF_Msk /*!< SYNC warning flag */ +#define CRS_ISR_ERRF_Pos (2U) +#define CRS_ISR_ERRF_Msk (0x1UL << CRS_ISR_ERRF_Pos) /*!< 0x00000004 */ +#define CRS_ISR_ERRF CRS_ISR_ERRF_Msk /*!< Error flag */ +#define CRS_ISR_ESYNCF_Pos (3U) +#define CRS_ISR_ESYNCF_Msk (0x1UL << CRS_ISR_ESYNCF_Pos) /*!< 0x00000008 */ +#define CRS_ISR_ESYNCF CRS_ISR_ESYNCF_Msk /*!< Expected SYNC flag */ +#define CRS_ISR_SYNCERR_Pos (8U) +#define CRS_ISR_SYNCERR_Msk (0x1UL << CRS_ISR_SYNCERR_Pos) /*!< 0x00000100 */ +#define CRS_ISR_SYNCERR CRS_ISR_SYNCERR_Msk /*!< SYNC error */ +#define CRS_ISR_SYNCMISS_Pos (9U) +#define CRS_ISR_SYNCMISS_Msk (0x1UL << CRS_ISR_SYNCMISS_Pos) /*!< 0x00000200 */ +#define CRS_ISR_SYNCMISS CRS_ISR_SYNCMISS_Msk /*!< SYNC missed */ +#define CRS_ISR_TRIMOVF_Pos (10U) +#define CRS_ISR_TRIMOVF_Msk (0x1UL << CRS_ISR_TRIMOVF_Pos) /*!< 0x00000400 */ +#define CRS_ISR_TRIMOVF CRS_ISR_TRIMOVF_Msk /*!< Trimming overflow or underflow */ +#define CRS_ISR_FEDIR_Pos (15U) +#define CRS_ISR_FEDIR_Msk (0x1UL << CRS_ISR_FEDIR_Pos) /*!< 0x00008000 */ +#define CRS_ISR_FEDIR CRS_ISR_FEDIR_Msk /*!< Frequency error direction */ +#define CRS_ISR_FECAP_Pos (16U) +#define CRS_ISR_FECAP_Msk (0xFFFFUL << CRS_ISR_FECAP_Pos) /*!< 0xFFFF0000 */ +#define CRS_ISR_FECAP CRS_ISR_FECAP_Msk /*!< Frequency error capture */ + +/******************* Bit definition for CRS_ICR register *********************/ +#define CRS_ICR_SYNCOKC_Pos (0U) +#define CRS_ICR_SYNCOKC_Msk (0x1UL << CRS_ICR_SYNCOKC_Pos) /*!< 0x00000001 */ +#define CRS_ICR_SYNCOKC CRS_ICR_SYNCOKC_Msk /*!< SYNC event OK clear flag */ +#define CRS_ICR_SYNCWARNC_Pos (1U) +#define CRS_ICR_SYNCWARNC_Msk (0x1UL << CRS_ICR_SYNCWARNC_Pos) /*!< 0x00000002 */ +#define CRS_ICR_SYNCWARNC CRS_ICR_SYNCWARNC_Msk /*!< SYNC warning clear flag */ +#define CRS_ICR_ERRC_Pos (2U) +#define CRS_ICR_ERRC_Msk (0x1UL << CRS_ICR_ERRC_Pos) /*!< 0x00000004 */ +#define CRS_ICR_ERRC CRS_ICR_ERRC_Msk /*!< Error clear flag */ +#define CRS_ICR_ESYNCC_Pos (3U) +#define CRS_ICR_ESYNCC_Msk (0x1UL << CRS_ICR_ESYNCC_Pos) /*!< 0x00000008 */ +#define CRS_ICR_ESYNCC CRS_ICR_ESYNCC_Msk /*!< Expected SYNC clear flag */ + + +/******************************************************************************/ +/* */ +/* RNG */ +/* */ +/******************************************************************************/ +/******************** Bits definition for RNG_CR register *******************/ +#define RNG_CR_RNGEN_Pos (2U) +#define RNG_CR_RNGEN_Msk (0x1UL << RNG_CR_RNGEN_Pos) /*!< 0x00000004 */ +#define RNG_CR_RNGEN RNG_CR_RNGEN_Msk +#define RNG_CR_IE_Pos (3U) +#define RNG_CR_IE_Msk (0x1UL << RNG_CR_IE_Pos) /*!< 0x00000008 */ +#define RNG_CR_IE RNG_CR_IE_Msk +#define RNG_CR_CED_Pos (5U) +#define RNG_CR_CED_Msk (0x1UL << RNG_CR_CED_Pos) /*!< 0x00000020 */ +#define RNG_CR_CED RNG_CR_CED_Msk +#define RNG_CR_ARDIS_Pos (7U) +#define RNG_CR_ARDIS_Msk (0x1UL << RNG_CR_ARDIS_Pos) +#define RNG_CR_ARDIS RNG_CR_ARDIS_Msk +#define RNG_CR_RNG_CONFIG3_Pos (8U) +#define RNG_CR_RNG_CONFIG3_Msk (0xFUL << RNG_CR_RNG_CONFIG3_Pos) +#define RNG_CR_RNG_CONFIG3 RNG_CR_RNG_CONFIG3_Msk +#define RNG_CR_NISTC_Pos (12U) +#define RNG_CR_NISTC_Msk (0x1UL << RNG_CR_NISTC_Pos) +#define RNG_CR_NISTC RNG_CR_NISTC_Msk +#define RNG_CR_RNG_CONFIG2_Pos (13U) +#define RNG_CR_RNG_CONFIG2_Msk (0x7UL << RNG_CR_RNG_CONFIG2_Pos) +#define RNG_CR_RNG_CONFIG2 RNG_CR_RNG_CONFIG2_Msk +#define RNG_CR_CLKDIV_Pos (16U) +#define RNG_CR_CLKDIV_Msk (0xFUL << RNG_CR_CLKDIV_Pos) +#define RNG_CR_CLKDIV RNG_CR_CLKDIV_Msk +#define RNG_CR_CLKDIV_0 (0x1UL << RNG_CR_CLKDIV_Pos) /*!< 0x00010000 */ +#define RNG_CR_CLKDIV_1 (0x2UL << RNG_CR_CLKDIV_Pos) /*!< 0x00020000 */ +#define RNG_CR_CLKDIV_2 (0x4UL << RNG_CR_CLKDIV_Pos) /*!< 0x00040000 */ +#define RNG_CR_CLKDIV_3 (0x8UL << RNG_CR_CLKDIV_Pos) /*!< 0x00080000 */ +#define RNG_CR_RNG_CONFIG1_Pos (20U) +#define RNG_CR_RNG_CONFIG1_Msk (0x3FUL << RNG_CR_RNG_CONFIG1_Pos) +#define RNG_CR_RNG_CONFIG1 RNG_CR_RNG_CONFIG1_Msk +#define RNG_CR_CONDRST_Pos (30U) +#define RNG_CR_CONDRST_Msk (0x1UL << RNG_CR_CONDRST_Pos) +#define RNG_CR_CONDRST RNG_CR_CONDRST_Msk +#define RNG_CR_CONFIGLOCK_Pos (31U) +#define RNG_CR_CONFIGLOCK_Msk (0x1UL << RNG_CR_CONFIGLOCK_Pos) +#define RNG_CR_CONFIGLOCK RNG_CR_CONFIGLOCK_Msk + +/******************** Bits definition for RNG_SR register *******************/ +#define RNG_SR_DRDY_Pos (0U) +#define RNG_SR_DRDY_Msk (0x1UL << RNG_SR_DRDY_Pos) /*!< 0x00000001 */ +#define RNG_SR_DRDY RNG_SR_DRDY_Msk +#define RNG_SR_CECS_Pos (1U) +#define RNG_SR_CECS_Msk (0x1UL << RNG_SR_CECS_Pos) /*!< 0x00000002 */ +#define RNG_SR_CECS RNG_SR_CECS_Msk +#define RNG_SR_SECS_Pos (2U) +#define RNG_SR_SECS_Msk (0x1UL << RNG_SR_SECS_Pos) /*!< 0x00000004 */ +#define RNG_SR_SECS RNG_SR_SECS_Msk +#define RNG_SR_CEIS_Pos (5U) +#define RNG_SR_CEIS_Msk (0x1UL << RNG_SR_CEIS_Pos) /*!< 0x00000020 */ +#define RNG_SR_CEIS RNG_SR_CEIS_Msk +#define RNG_SR_SEIS_Pos (6U) +#define RNG_SR_SEIS_Msk (0x1UL << RNG_SR_SEIS_Pos) /*!< 0x00000040 */ +#define RNG_SR_SEIS RNG_SR_SEIS_Msk + +/******************** Bits definition for RNG_HTCR register *******************/ +#define RNG_HTCR_HTCFG_Pos (0U) +#define RNG_HTCR_HTCFG_Msk (0xFFFFFFFFUL << RNG_HTCR_HTCFG_Pos) /*!< 0xFFFFFFFF */ +#define RNG_HTCR_HTCFG RNG_HTCR_HTCFG_Msk + +/******************************************************************************/ +/* */ +/* Digital to Analog Converter */ +/* */ +/******************************************************************************/ +#define DAC_CHANNEL2_SUPPORT /*!< DAC feature available only on specific devices: DAC channel 2 available */ + +/******************** Bit definition for DAC_CR register ********************/ +#define DAC_CR_EN1_Pos (0U) +#define DAC_CR_EN1_Msk (0x1UL << DAC_CR_EN1_Pos) /*!< 0x00000001 */ +#define DAC_CR_EN1 DAC_CR_EN1_Msk /*!*/ +#define DAC_CR_CEN1_Pos (14U) +#define DAC_CR_CEN1_Msk (0x1UL << DAC_CR_CEN1_Pos) /*!< 0x00004000 */ +#define DAC_CR_CEN1 DAC_CR_CEN1_Msk /*!*/ +#define DAC_CR_EN2_Pos (16U) +#define DAC_CR_EN2_Msk (0x1UL << DAC_CR_EN2_Pos) /*!< 0x00010000 */ +#define DAC_CR_EN2 DAC_CR_EN2_Msk /*!*/ +#define DAC_CR_CEN2_Pos (30U) +#define DAC_CR_CEN2_Msk (0x1UL << DAC_CR_CEN2_Pos) /*!< 0x40000000 */ +#define DAC_CR_CEN2 DAC_CR_CEN2_Msk /*!*/ + +/***************** Bit definition for DAC_SWTRIGR register ******************/ +#define DAC_SWTRIGR_SWTRIG1_Pos (0U) +#define DAC_SWTRIGR_SWTRIG1_Msk (0x1UL << DAC_SWTRIGR_SWTRIG1_Pos) /*!< 0x00000001 */ +#define DAC_SWTRIGR_SWTRIG1 DAC_SWTRIGR_SWTRIG1_Msk /*!> 1U) /*!< FLASH Bank Size */ +#define FLASH_SECTOR_SIZE 0x2000U /*!< Flash Sector Size: 8 KB */ + +/******************* Bits definition for FLASH_ACR register *****************/ +#define FLASH_ACR_LATENCY_Pos (0U) +#define FLASH_ACR_LATENCY_Msk (0xFUL << FLASH_ACR_LATENCY_Pos) /*!< 0x0000000F */ +#define FLASH_ACR_LATENCY FLASH_ACR_LATENCY_Msk /*!< Latency */ +#define FLASH_ACR_LATENCY_0WS (0x00000000U) +#define FLASH_ACR_LATENCY_1WS (0x00000001U) +#define FLASH_ACR_LATENCY_2WS (0x00000002U) +#define FLASH_ACR_LATENCY_3WS (0x00000003U) +#define FLASH_ACR_LATENCY_4WS (0x00000004U) +#define FLASH_ACR_LATENCY_5WS (0x00000005U) +#define FLASH_ACR_LATENCY_6WS (0x00000006U) +#define FLASH_ACR_LATENCY_7WS (0x00000007U) +#define FLASH_ACR_LATENCY_8WS (0x00000008U) +#define FLASH_ACR_LATENCY_9WS (0x00000009U) +#define FLASH_ACR_LATENCY_10WS (0x0000000AU) +#define FLASH_ACR_LATENCY_11WS (0x0000000BU) +#define FLASH_ACR_LATENCY_12WS (0x0000000CU) +#define FLASH_ACR_LATENCY_13WS (0x0000000DU) +#define FLASH_ACR_LATENCY_14WS (0x0000000EU) +#define FLASH_ACR_LATENCY_15WS (0x0000000FU) +#define FLASH_ACR_WRHIGHFREQ_Pos (4U) +#define FLASH_ACR_WRHIGHFREQ_Msk (0x3UL << FLASH_ACR_WRHIGHFREQ_Pos) /*!< 0x00000030 */ +#define FLASH_ACR_WRHIGHFREQ FLASH_ACR_WRHIGHFREQ_Msk /*!< Flash signal delay */ +#define FLASH_ACR_WRHIGHFREQ_0 (0x1UL << FLASH_ACR_WRHIGHFREQ_Pos) /*!< 0x00000010 */ +#define FLASH_ACR_WRHIGHFREQ_1 (0x2UL << FLASH_ACR_WRHIGHFREQ_Pos) /*!< 0x00000020 */ +#define FLASH_ACR_PRFTEN_Pos (8U) +#define FLASH_ACR_PRFTEN_Msk (0x1UL << FLASH_ACR_PRFTEN_Pos) /*!< 0x00000100 */ +#define FLASH_ACR_PRFTEN FLASH_ACR_PRFTEN_Msk /*!< Prefetch enable */ + +/******************* Bits definition for FLASH_OPSR register ***************/ +#define FLASH_OPSR_ADDR_OP_Pos (0U) +#define FLASH_OPSR_ADDR_OP_Msk (0xFFFFFUL << FLASH_OPSR_ADDR_OP_Pos) /*!< 0x000FFFFF */ +#define FLASH_OPSR_ADDR_OP FLASH_OPSR_ADDR_OP_Msk /*!< Interrupted operation address */ +#define FLASH_OPSR_BK_OP_Pos (22U) +#define FLASH_OPSR_BK_OP_Msk (0x1UL << FLASH_OPSR_BK_OP_Pos) /*!< 0x00400000 */ +#define FLASH_OPSR_BK_OP FLASH_OPSR_BK_OP_Msk /*!< Interrupted operation bank */ +#define FLASH_OPSR_SYSF_OP_Pos (23U) +#define FLASH_OPSR_SYSF_OP_Msk (0x1UL << FLASH_OPSR_SYSF_OP_Pos) /*!< 0x00800000 */ +#define FLASH_OPSR_SYSF_OP FLASH_OPSR_SYSF_OP_Msk /*!< Operation in System Flash interrupted */ +#define FLASH_OPSR_OTP_OP_Pos (24U) +#define FLASH_OPSR_OTP_OP_Msk (0x1UL << FLASH_OPSR_OTP_OP_Pos) /*!< 0x01000000 */ +#define FLASH_OPSR_OTP_OP FLASH_OPSR_OTP_OP_Msk /*!< Operation in OTP area interrupted */ +#define FLASH_OPSR_CODE_OP_Pos (29U) +#define FLASH_OPSR_CODE_OP_Msk (0x7UL << FLASH_OPSR_CODE_OP_Pos) /*!< 0xE0000000 */ +#define FLASH_OPSR_CODE_OP FLASH_OPSR_CODE_OP_Msk /*!< Flash memory operation code */ +#define FLASH_OPSR_CODE_OP_0 (0x1UL << FLASH_OPSR_CODE_OP_Pos) /*!< 0x20000000 */ +#define FLASH_OPSR_CODE_OP_1 (0x2UL << FLASH_OPSR_CODE_OP_Pos) /*!< 0x40000000 */ +#define FLASH_OPSR_CODE_OP_2 (0x4UL << FLASH_OPSR_CODE_OP_Pos) /*!< 0x80000000 */ + +/******************* Bits definition for FLASH_OPTCR register *******************/ +#define FLASH_OPTCR_OPTLOCK_Pos (0U) +#define FLASH_OPTCR_OPTLOCK_Msk (0x1UL << FLASH_OPTCR_OPTLOCK_Pos) /*!< 0x00000001 */ +#define FLASH_OPTCR_OPTLOCK FLASH_OPTCR_OPTLOCK_Msk /*!< FLASH_OPTCR lock option configuration bit */ +#define FLASH_OPTCR_OPTSTART_Pos (1U) +#define FLASH_OPTCR_OPTSTART_Msk (0x1UL << FLASH_OPTCR_OPTSTART_Pos) /*!< 0x00000002 */ +#define FLASH_OPTCR_OPTSTART FLASH_OPTCR_OPTSTART_Msk /*!< Option byte start change option configuration bit */ +#define FLASH_OPTCR_SWAP_BANK_Pos (31U) +#define FLASH_OPTCR_SWAP_BANK_Msk (0x1UL << FLASH_OPTCR_SWAP_BANK_Pos) /*!< 0x80000000 */ +#define FLASH_OPTCR_SWAP_BANK FLASH_OPTCR_SWAP_BANK_Msk /*!< Bank swapping option configuration bit */ + +/******************* Bits definition for FLASH_SR register ***********************/ +#define FLASH_SR_BSY_Pos (0U) +#define FLASH_SR_BSY_Msk (0x1UL << FLASH_SR_BSY_Pos) /*!< 0x00000001 */ +#define FLASH_SR_BSY FLASH_SR_BSY_Msk /*!< Busy flag */ +#define FLASH_SR_WBNE_Pos (1U) +#define FLASH_SR_WBNE_Msk (0x1UL << FLASH_SR_WBNE_Pos) /*!< 0x00000002 */ +#define FLASH_SR_WBNE FLASH_SR_WBNE_Msk /*!< Write buffer not empty flag */ +#define FLASH_SR_DBNE_Pos (3U) +#define FLASH_SR_DBNE_Msk (0x1UL << FLASH_SR_DBNE_Pos) /*!< 0x00000008 */ +#define FLASH_SR_DBNE FLASH_SR_DBNE_Msk /*!< Data buffer not empty flag */ +#define FLASH_SR_EOP_Pos (16U) +#define FLASH_SR_EOP_Msk (0x1UL << FLASH_SR_EOP_Pos) /*!< 0x00010000 */ +#define FLASH_SR_EOP FLASH_SR_EOP_Msk /*!< End-of-program flag */ +#define FLASH_SR_WRPERR_Pos (17U) +#define FLASH_SR_WRPERR_Msk (0x1UL << FLASH_SR_WRPERR_Pos) /*!< 0x00020000 */ +#define FLASH_SR_WRPERR FLASH_SR_WRPERR_Msk /*!< Write protection error flag */ +#define FLASH_SR_PGSERR_Pos (18U) +#define FLASH_SR_PGSERR_Msk (0x1UL << FLASH_SR_PGSERR_Pos) /*!< 0x00040000 */ +#define FLASH_SR_PGSERR FLASH_SR_PGSERR_Msk /*!< Programming sequence error flag */ +#define FLASH_SR_STRBERR_Pos (19U) +#define FLASH_SR_STRBERR_Msk (0x1UL << FLASH_SR_STRBERR_Pos) /*!< 0x00080000 */ +#define FLASH_SR_STRBERR FLASH_SR_STRBERR_Msk /*!< Strobe error flag */ +#define FLASH_SR_INCERR_Pos (20U) +#define FLASH_SR_INCERR_Msk (0x1UL << FLASH_SR_INCERR_Pos) /*!< 0x00100000 */ +#define FLASH_SR_INCERR FLASH_SR_INCERR_Msk /*!< Inconsistency error flag */ +#define FLASH_SR_OPTCHANGEERR_Pos (23U) +#define FLASH_SR_OPTCHANGEERR_Msk (0x1UL << FLASH_SR_OPTCHANGEERR_Pos) /*!< 0x00800000 */ +#define FLASH_SR_OPTCHANGEERR FLASH_SR_OPTCHANGEERR_Msk /*!< Option byte change error flag */ + +/******************* Bits definition for FLASH_CR register ***********************/ +#define FLASH_CR_LOCK_Pos (0U) +#define FLASH_CR_LOCK_Msk (0x1UL << FLASH_CR_LOCK_Pos) /*!< 0x00000001 */ +#define FLASH_CR_LOCK FLASH_CR_LOCK_Msk /*!< Configuration lock bit */ +#define FLASH_CR_PG_Pos (1U) +#define FLASH_CR_PG_Msk (0x1UL << FLASH_CR_PG_Pos) /*!< 0x00000002 */ +#define FLASH_CR_PG FLASH_CR_PG_Msk /*!< Programming control bit */ +#define FLASH_CR_SER_Pos (2U) +#define FLASH_CR_SER_Msk (0x1UL << FLASH_CR_SER_Pos) /*!< 0x00000004 */ +#define FLASH_CR_SER FLASH_CR_SER_Msk /*!< Sector erase request */ +#define FLASH_CR_BER_Pos (3U) +#define FLASH_CR_BER_Msk (0x1UL << FLASH_CR_BER_Pos) /*!< 0x00000008 */ +#define FLASH_CR_BER FLASH_CR_BER_Msk /*!< Bank erase request */ +#define FLASH_CR_FW_Pos (4U) +#define FLASH_CR_FW_Msk (0x1UL << FLASH_CR_FW_Pos) /*!< 0x00000010 */ +#define FLASH_CR_FW FLASH_CR_FW_Msk /*!< Write forcing control bit */ +#define FLASH_CR_START_Pos (5U) +#define FLASH_CR_START_Msk (0x1UL << FLASH_CR_START_Pos) /*!< 0x00000020 */ +#define FLASH_CR_START FLASH_CR_START_Msk /*!< Erase start control bit */ +#define FLASH_CR_SNB_Pos (6U) +#define FLASH_CR_SNB_Msk (0x7FUL << FLASH_CR_SNB_Pos) /*!< 0x00001FC0 */ +#define FLASH_CR_SNB FLASH_CR_SNB_Msk /*!< Sector erase selection number */ +#define FLASH_CR_SNB_0 (0x01UL << FLASH_CR_SNB_Pos) /*!< 0x00000040 */ +#define FLASH_CR_SNB_1 (0x02UL << FLASH_CR_SNB_Pos) /*!< 0x00000080 */ +#define FLASH_CR_SNB_2 (0x04UL << FLASH_CR_SNB_Pos) /*!< 0x00000100 */ +#define FLASH_CR_SNB_3 (0x08UL << FLASH_CR_SNB_Pos) /*!< 0x00000200 */ +#define FLASH_CR_SNB_4 (0x10UL << FLASH_CR_SNB_Pos) /*!< 0x00000400 */ +#define FLASH_CR_SNB_5 (0x20UL << FLASH_CR_SNB_Pos) /*!< 0x00000800 */ +#define FLASH_CR_SNB_6 (0x40UL << FLASH_CR_SNB_Pos) /*!< 0x00001000 */ +#define FLASH_CR_MER_Pos (15U) +#define FLASH_CR_MER_Msk (0x1UL << FLASH_CR_MER_Pos) /*!< 0x00008000 */ +#define FLASH_CR_MER FLASH_CR_MER_Msk /*!< Mass erase */ +#define FLASH_CR_EOPIE_Pos (16U) +#define FLASH_CR_EOPIE_Msk (0x1UL << FLASH_CR_EOPIE_Pos) /*!< 0x00010000 */ +#define FLASH_CR_EOPIE FLASH_CR_EOPIE_Msk /*!< End-of-operation interrupt control bit */ +#define FLASH_CR_WRPERRIE_Pos (17U) +#define FLASH_CR_WRPERRIE_Msk (0x1UL << FLASH_CR_WRPERRIE_Pos) /*!< 0x00020000 */ +#define FLASH_CR_WRPERRIE FLASH_CR_WRPERRIE_Msk /*!< Write protection error interrupt enable bit */ +#define FLASH_CR_PGSERRIE_Pos (18U) +#define FLASH_CR_PGSERRIE_Msk (0x1UL << FLASH_CR_PGSERRIE_Pos) /*!< 0x00040000 */ +#define FLASH_CR_PGSERRIE FLASH_CR_PGSERRIE_Msk /*!< Programming sequence error interrupt enable bit */ +#define FLASH_CR_STRBERRIE_Pos (19U) +#define FLASH_CR_STRBERRIE_Msk (0x1UL << FLASH_CR_STRBERRIE_Pos) /*!< 0x00080000 */ +#define FLASH_CR_STRBERRIE FLASH_CR_STRBERRIE_Msk /*!< Strobe error interrupt enable bit */ +#define FLASH_CR_INCERRIE_Pos (20U) +#define FLASH_CR_INCERRIE_Msk (0x1UL << FLASH_CR_INCERRIE_Pos) /*!< 0x00100000 */ +#define FLASH_CR_INCERRIE FLASH_CR_INCERRIE_Msk /*!< Inconsistency error interrupt enable bit */ +#define FLASH_CR_OPTCHANGEERRIE_Pos (23U) +#define FLASH_CR_OPTCHANGEERRIE_Msk (0x1UL << FLASH_CR_OPTCHANGEERRIE_Pos) /*!< 0x00800000 */ +#define FLASH_CR_OPTCHANGEERRIE FLASH_CR_OPTCHANGEERRIE_Msk /*!< Option byte change error interrupt enable bit */ +#define FLASH_CR_INV_Pos (29U) +#define FLASH_CR_INV_Msk (0x1UL << FLASH_CR_INV_Pos) /*!< 0x20000000 */ +#define FLASH_CR_INV FLASH_CR_INV_Msk /*!< Flash Security State Invert */ +#define FLASH_CR_BKSEL_Pos (31U) +#define FLASH_CR_BKSEL_Msk (0x1UL << FLASH_CR_BKSEL_Pos) /*!< 0x10000000 */ +#define FLASH_CR_BKSEL FLASH_CR_BKSEL_Msk /*!< Bank selector */ + +/******************* Bits definition for FLASH_CCR register *******************/ +#define FLASH_CCR_CLR_EOP_Pos (16U) +#define FLASH_CCR_CLR_EOP_Msk (0x1UL << FLASH_CCR_CLR_EOP_Pos) /*!< 0x00010000 */ +#define FLASH_CCR_CLR_EOP FLASH_CCR_CLR_EOP_Msk /*!< EOP flag clear bit */ +#define FLASH_CCR_CLR_WRPERR_Pos (17U) +#define FLASH_CCR_CLR_WRPERR_Msk (0x1UL << FLASH_CCR_CLR_WRPERR_Pos) /*!< 0x00020000 */ +#define FLASH_CCR_CLR_WRPERR FLASH_CCR_CLR_WRPERR_Msk /*!< WRPERR flag clear bit */ +#define FLASH_CCR_CLR_PGSERR_Pos (18U) +#define FLASH_CCR_CLR_PGSERR_Msk (0x1UL << FLASH_CCR_CLR_PGSERR_Pos) /*!< 0x00040000 */ +#define FLASH_CCR_CLR_PGSERR FLASH_CCR_CLR_PGSERR_Msk /*!< PGSERR flag clear bit */ +#define FLASH_CCR_CLR_STRBERR_Pos (19U) +#define FLASH_CCR_CLR_STRBERR_Msk (0x1UL << FLASH_CCR_CLR_STRBERR_Pos) /*!< 0x00080000 */ +#define FLASH_CCR_CLR_STRBERR FLASH_CCR_CLR_STRBERR_Msk /*!< STRBERR flag clear bit */ +#define FLASH_CCR_CLR_INCERR_Pos (20U) +#define FLASH_CCR_CLR_INCERR_Msk (0x1UL << FLASH_CCR_CLR_INCERR_Pos) /*!< 0x00100000 */ +#define FLASH_CCR_CLR_INCERR FLASH_CCR_CLR_INCERR_Msk /*!< INCERR flag clear bit */ +#define FLASH_CCR_CLR_OPTCHANGEERR_Pos (23U) +#define FLASH_CCR_CLR_OPTCHANGEERR_Msk (0x1UL << FLASH_CCR_CLR_OPTCHANGEERR_Pos) /*!< 0x00800000 */ +#define FLASH_CCR_CLR_OPTCHANGEERR FLASH_CCR_CLR_OPTCHANGEERR_Msk /*!< Option byte change error clear bit */ + +/****************** Bits definition for FLASH_PRIVCFGR register ***********/ +#define FLASH_PRIVCFGR_NSPRIV_Pos (1U) +#define FLASH_PRIVCFGR_NSPRIV_Msk (0x1UL << FLASH_PRIVCFGR_NSPRIV_Pos) /*!< 0x00000002 */ +#define FLASH_PRIVCFGR_NSPRIV FLASH_PRIVCFGR_NSPRIV_Msk /*!< Privilege protection for non-secure registers */ + + +/****************** Bits definition for FLASH_HDPEXTR register *****************/ +#define FLASH_HDPEXTR_HDP1_EXT_Pos (0U) +#define FLASH_HDPEXTR_HDP1_EXT_Msk (0x7FUL << FLASH_HDPEXTR_HDP1_EXT_Pos) /*!< 0x0000007F */ +#define FLASH_HDPEXTR_HDP1_EXT FLASH_HDPEXTR_HDP1_EXT_Msk /*!< HDP area extension in 8kB sectors in bank 1 */ +#define FLASH_HDPEXTR_HDP2_EXT_Pos (16U) +#define FLASH_HDPEXTR_HDP2_EXT_Msk (0x7FUL << FLASH_HDPEXTR_HDP2_EXT_Pos) /*!< 0x007F0000 */ +#define FLASH_HDPEXTR_HDP2_EXT FLASH_HDPEXTR_HDP2_EXT_Msk /*!< HDP area extension in 8kB sectors in bank 2 */ + +/******************* Bits definition for FLASH_OPTSR register ***************/ +#define FLASH_OPTSR_BOR_LEV_Pos (0U) +#define FLASH_OPTSR_BOR_LEV_Msk (0x3UL << FLASH_OPTSR_BOR_LEV_Pos) /*!< 0x00000003 */ +#define FLASH_OPTSR_BOR_LEV FLASH_OPTSR_BOR_LEV_Msk /*!< Brownout level option bit */ +#define FLASH_OPTSR_BOR_LEV_0 (0x1UL << FLASH_OPTSR_BOR_LEV_Pos) /*!< 0x00000001 */ +#define FLASH_OPTSR_BOR_LEV_1 (0x2UL << FLASH_OPTSR_BOR_LEV_Pos) /*!< 0x00000002 */ +#define FLASH_OPTSR_BORH_EN_Pos (2U) +#define FLASH_OPTSR_BORH_EN_Msk (0x1UL << FLASH_OPTSR_BORH_EN_Pos) /*!< 0x00000004 */ +#define FLASH_OPTSR_BORH_EN FLASH_OPTSR_BORH_EN_Msk /*!< Brownout high enable configuration bit */ +#define FLASH_OPTSR_IWDG_SW_Pos (3U) +#define FLASH_OPTSR_IWDG_SW_Msk (0x1UL << FLASH_OPTSR_IWDG_SW_Pos) /*!< 0x00000008 */ +#define FLASH_OPTSR_IWDG_SW FLASH_OPTSR_IWDG_SW_Msk /*!< IWDG control mode option bit */ +#define FLASH_OPTSR_WWDG_SW_Pos (4U) +#define FLASH_OPTSR_WWDG_SW_Msk (0x1UL << FLASH_OPTSR_WWDG_SW_Pos) /*!< 0x00000010 */ +#define FLASH_OPTSR_WWDG_SW FLASH_OPTSR_WWDG_SW_Msk /*!< WWDG control mode option bit */ +#define FLASH_OPTSR_NRST_STOP_Pos (6U) +#define FLASH_OPTSR_NRST_STOP_Msk (0x1UL << FLASH_OPTSR_NRST_STOP_Pos) /*!< 0x00000040 */ +#define FLASH_OPTSR_NRST_STOP FLASH_OPTSR_NRST_STOP_Msk /*!< Stop mode entry reset option bit */ +#define FLASH_OPTSR_NRST_STDBY_Pos (7U) +#define FLASH_OPTSR_NRST_STDBY_Msk (0x1UL << FLASH_OPTSR_NRST_STDBY_Pos) /*!< 0x00000080 */ +#define FLASH_OPTSR_NRST_STDBY FLASH_OPTSR_NRST_STDBY_Msk /*!< Standby mode entry reset option bit */ +#define FLASH_OPTSR_PRODUCT_STATE_Pos (8U) +#define FLASH_OPTSR_PRODUCT_STATE_Msk (0xFFUL << FLASH_OPTSR_PRODUCT_STATE_Pos) /*!< 0x0000FF00 */ +#define FLASH_OPTSR_PRODUCT_STATE FLASH_OPTSR_PRODUCT_STATE_Msk /*!< Life state code option byte */ +#define FLASH_OPTSR_IO_VDD_HSLV_Pos (16U) +#define FLASH_OPTSR_IO_VDD_HSLV_Msk (0x1UL << FLASH_OPTSR_IO_VDD_HSLV_Pos) /*!< 0x00010000 */ +#define FLASH_OPTSR_IO_VDD_HSLV FLASH_OPTSR_IO_VDD_HSLV_Msk /*!< VDD I/O high-speed at low-voltage option bit */ +#define FLASH_OPTSR_IO_VDDIO2_HSLV_Pos (17U) +#define FLASH_OPTSR_IO_VDDIO2_HSLV_Msk (0x1UL << FLASH_OPTSR_IO_VDDIO2_HSLV_Pos) /*!< 0x00020000 */ +#define FLASH_OPTSR_IO_VDDIO2_HSLV FLASH_OPTSR_IO_VDDIO2_HSLV_Msk /*!< VDDIO2 I/O high-speed at low-voltage option bit */ +#define FLASH_OPTSR_IWDG_STOP_Pos (20U) +#define FLASH_OPTSR_IWDG_STOP_Msk (0x1UL << FLASH_OPTSR_IWDG_STOP_Pos) /*!< 0x00100000 */ +#define FLASH_OPTSR_IWDG_STOP FLASH_OPTSR_IWDG_STOP_Msk /*!< Independent watchdog counter freeze in Stop mode */ +#define FLASH_OPTSR_IWDG_STDBY_Pos (21U) +#define FLASH_OPTSR_IWDG_STDBY_Msk (0x1UL << FLASH_OPTSR_IWDG_STDBY_Pos) /*!< 0x00200000 */ +#define FLASH_OPTSR_IWDG_STDBY FLASH_OPTSR_IWDG_STDBY_Msk /*!< Independent watchdog counter freeze in Standby mode */ +#define FLASH_OPTSR_SWAP_BANK_Pos (31U) +#define FLASH_OPTSR_SWAP_BANK_Msk (0x1UL << FLASH_OPTSR_SWAP_BANK_Pos) /*!< 0x80000000 */ +#define FLASH_OPTSR_SWAP_BANK FLASH_OPTSR_SWAP_BANK_Msk /*!< Bank swapping option bit */ + +/******************* Bits definition for FLASH_EPOCHR register ***************/ +#define FLASH_EPOCHR_EPOCH_Pos (0U) +#define FLASH_EPOCHR_EPOCH_Msk (0xFFFFFFUL << FLASH_EPOCHR_EPOCH_Pos) /*!< 0x00FFFFFF */ +#define FLASH_EPOCHR_EPOCH FLASH_EPOCHR_EPOCH_Msk /*!< EPOCH counter */ + +/******************* Bits definition for FLASH_OPTSR2 register ***************/ +#define FLASH_OPTSR2_SRAM2_RST_Pos (3U) +#define FLASH_OPTSR2_SRAM2_RST_Msk (0x1UL << FLASH_OPTSR2_SRAM2_RST_Pos) /*!< 0x00000008 */ +#define FLASH_OPTSR2_SRAM2_RST FLASH_OPTSR2_SRAM2_RST_Msk /*!< SRAM2 erased when a system reset occurs*/ +#define FLASH_OPTSR2_BKPRAM_ECC_Pos (4U) +#define FLASH_OPTSR2_BKPRAM_ECC_Msk (0x1UL << FLASH_OPTSR2_BKPRAM_ECC_Pos) /*!< 0x00000010 */ +#define FLASH_OPTSR2_BKPRAM_ECC FLASH_OPTSR2_BKPRAM_ECC_Msk /*!< Backup RAM ECC detection and correction enable */ +#define FLASH_OPTSR2_SRAM2_ECC_Pos (6U) +#define FLASH_OPTSR2_SRAM2_ECC_Msk (0x1UL << FLASH_OPTSR2_SRAM2_ECC_Pos) /*!< 0x00000040 */ +#define FLASH_OPTSR2_SRAM2_ECC FLASH_OPTSR2_SRAM2_ECC_Msk /*!< SRAM2 ECC detection and correction disable */ +#define FLASH_OPTSR2_SRAM1_RST_Pos (9U) +#define FLASH_OPTSR2_SRAM1_RST_Msk (0x1UL << FLASH_OPTSR2_SRAM1_RST_Pos) /*!< 0x00000200 */ +#define FLASH_OPTSR2_SRAM1_RST FLASH_OPTSR2_SRAM1_RST_Msk /*!< SRAM1 erase upon a system reset */ +#define FLASH_OPTSR2_SRAM1_ECC_Pos (10U) +#define FLASH_OPTSR2_SRAM1_ECC_Msk (0x1UL << FLASH_OPTSR2_SRAM1_ECC_Pos) /*!< 0x00000400 */ +#define FLASH_OPTSR2_SRAM1_ECC FLASH_OPTSR2_SRAM1_ECC_Msk /*!< SRAM1 ECC detection and correction disable */ + +/**************** Bits definition for FLASH_BOOTR register **********************/ +#define FLASH_BOOTR_BOOT_LOCK_Pos (0U) +#define FLASH_BOOTR_BOOT_LOCK_Msk (0xFFUL << FLASH_BOOTR_BOOT_LOCK_Pos) /*!< 0x000000FF */ +#define FLASH_BOOTR_BOOT_LOCK FLASH_BOOTR_BOOT_LOCK_Msk /*!< Boot Lock */ +#define FLASH_BOOTR_BOOTADD_Pos (8U) +#define FLASH_BOOTR_BOOTADD_Msk (0xFFFFFFUL << FLASH_BOOTR_BOOTADD_Pos) /*!< 0xFFFFFF00 */ +#define FLASH_BOOTR_BOOTADD FLASH_BOOTR_BOOTADD_Msk /*!< Boot address */ + +/**************** Bits definition for FLASH_PRIVBBR register *******************/ +#define FLASH_PRIVBBR_PRIVBB_Pos (0U) +#define FLASH_PRIVBBR_PRIVBB_Msk (0x000000FFUL << FLASH_PRIVBBR_PRIVBB_Pos) /*!< 0x000000FF */ +#define FLASH_PRIVBBR_PRIVBB FLASH_PRIVBBR_PRIVBB_Msk /*!< Privileged/unprivileged 8-Kbyte Flash sector attribute */ + + +/***************** Bits definition for FLASH_WRPR register *********************/ +#define FLASH_WRPR_WRPSG_Pos (0U) +#define FLASH_WRPR_WRPSG_Msk (0x000000FFUL << FLASH_WRPR_WRPSG_Pos) /*!< 0x000000FF */ +#define FLASH_WRPR_WRPSG FLASH_WRPR_WRPSG_Msk /*!< Sector group protection option status */ + + +/***************** Bits definition for FLASH_HDPR register ********************/ +#define FLASH_HDPR_HDP_STRT_Pos (0U) +#define FLASH_HDPR_HDP_STRT_Msk (0x07UL << FLASH_HDPR_HDP_STRT_Pos) /*!< 0x00000007 */ +#define FLASH_HDPR_HDP_STRT FLASH_HDPR_HDP_STRT_Msk /*!< Start sector of hide protection area */ +#define FLASH_HDPR_HDP_END_Pos (16U) +#define FLASH_HDPR_HDP_END_Msk (0x07UL << FLASH_HDPR_HDP_END_Pos) /*!< 0x00070000 */ +#define FLASH_HDPR_HDP_END FLASH_HDPR_HDP_END_Msk /*!< End sector of hide protection area */ + +/******************* Bits definition for FLASH_ECCR register ***************/ +#define FLASH_ECCR_ADDR_ECC_Pos (0U) +#define FLASH_ECCR_ADDR_ECC_Msk (0xFFFFUL << FLASH_ECCR_ADDR_ECC_Pos) /*!< 0x0000FFFF */ +#define FLASH_ECCR_ADDR_ECC FLASH_ECCR_ADDR_ECC_Msk /*!< ECC fail address */ +#define FLASH_ECCR_BK_ECC_Pos (22U) +#define FLASH_ECCR_BK_ECC_Msk (0x1UL << FLASH_ECCR_BK_ECC_Pos) /*!< 0x00400000 */ +#define FLASH_ECCR_BK_ECC FLASH_ECCR_BK_ECC_Msk /*!< ECC fail bank */ +#define FLASH_ECCR_SYSF_ECC_Pos (23U) +#define FLASH_ECCR_SYSF_ECC_Msk (0x1UL << FLASH_ECCR_SYSF_ECC_Pos) /*!< 0x00800000 */ +#define FLASH_ECCR_SYSF_ECC FLASH_ECCR_SYSF_ECC_Msk /*!< System Flash ECC fail */ +#define FLASH_ECCR_OTP_ECC_Pos (24U) +#define FLASH_ECCR_OTP_ECC_Msk (0x1UL << FLASH_ECCR_OTP_ECC_Pos) /*!< 0x01000000 */ +#define FLASH_ECCR_OTP_ECC FLASH_ECCR_OTP_ECC_Msk /*!< Flash OTP ECC fail */ +#define FLASH_ECCR_ECCIE_Pos (25U) +#define FLASH_ECCR_ECCIE_Msk (0x1UL << FLASH_ECCR_ECCIE_Pos) /*!< 0x02000000 */ +#define FLASH_ECCR_ECCIE FLASH_ECCR_ECCIE_Msk /*!< ECC correction interrupt enable */ +#define FLASH_ECCR_ECCC_Pos (30U) +#define FLASH_ECCR_ECCC_Msk (0x1UL << FLASH_ECCR_ECCC_Pos) /*!< 0x40000000 */ +#define FLASH_ECCR_ECCC FLASH_ECCR_ECCC_Msk /*!< ECC correction */ +#define FLASH_ECCR_ECCD_Pos (31U) +#define FLASH_ECCR_ECCD_Msk (0x1UL << FLASH_ECCR_ECCD_Pos) /*!< 0x80000000 */ +#define FLASH_ECCR_ECCD FLASH_ECCR_ECCD_Msk /*!< ECC detection */ + +/******************* Bits definition for FLASH_ECCDR register ***************/ +#define FLASH_ECCDR_FAIL_DATA_Pos (0U) +#define FLASH_ECCDR_FAIL_DATA_Msk (0xFFFFUL << FLASH_ECCDR_FAIL_DATA_Pos) /*!< 0x0000FFFF */ +#define FLASH_ECCDR_FAIL_DATA FLASH_ECCDR_FAIL_DATA_Msk /*!< ECC fail data */ + + +/******************************************************************************/ +/* */ +/* General Purpose IOs (GPIO) */ +/* */ +/******************************************************************************/ +/****************** Bits definition for GPIO_MODER register *****************/ +#define GPIO_MODER_MODE0_Pos (0U) +#define GPIO_MODER_MODE0_Msk (0x3UL << GPIO_MODER_MODE0_Pos) /*!< 0x00000003 */ +#define GPIO_MODER_MODE0 GPIO_MODER_MODE0_Msk +#define GPIO_MODER_MODE0_0 (0x1UL << GPIO_MODER_MODE0_Pos) /*!< 0x00000001 */ +#define GPIO_MODER_MODE0_1 (0x2UL << GPIO_MODER_MODE0_Pos) /*!< 0x00000002 */ +#define GPIO_MODER_MODE1_Pos (2U) +#define GPIO_MODER_MODE1_Msk (0x3UL << GPIO_MODER_MODE1_Pos) /*!< 0x0000000C */ +#define GPIO_MODER_MODE1 GPIO_MODER_MODE1_Msk +#define GPIO_MODER_MODE1_0 (0x1UL << GPIO_MODER_MODE1_Pos) /*!< 0x00000004 */ +#define GPIO_MODER_MODE1_1 (0x2UL << GPIO_MODER_MODE1_Pos) /*!< 0x00000008 */ +#define GPIO_MODER_MODE2_Pos (4U) +#define GPIO_MODER_MODE2_Msk (0x3UL << GPIO_MODER_MODE2_Pos) /*!< 0x00000030 */ +#define GPIO_MODER_MODE2 GPIO_MODER_MODE2_Msk +#define GPIO_MODER_MODE2_0 (0x1UL << GPIO_MODER_MODE2_Pos) /*!< 0x00000010 */ +#define GPIO_MODER_MODE2_1 (0x2UL << GPIO_MODER_MODE2_Pos) /*!< 0x00000020 */ +#define GPIO_MODER_MODE3_Pos (6U) +#define GPIO_MODER_MODE3_Msk (0x3UL << GPIO_MODER_MODE3_Pos) /*!< 0x000000C0 */ +#define GPIO_MODER_MODE3 GPIO_MODER_MODE3_Msk +#define GPIO_MODER_MODE3_0 (0x1UL << GPIO_MODER_MODE3_Pos) /*!< 0x00000040 */ +#define GPIO_MODER_MODE3_1 (0x2UL << GPIO_MODER_MODE3_Pos) /*!< 0x00000080 */ +#define GPIO_MODER_MODE4_Pos (8U) +#define GPIO_MODER_MODE4_Msk (0x3UL << GPIO_MODER_MODE4_Pos) /*!< 0x00000300 */ +#define GPIO_MODER_MODE4 GPIO_MODER_MODE4_Msk +#define GPIO_MODER_MODE4_0 (0x1UL << GPIO_MODER_MODE4_Pos) /*!< 0x00000100 */ +#define GPIO_MODER_MODE4_1 (0x2UL << GPIO_MODER_MODE4_Pos) /*!< 0x00000200 */ +#define GPIO_MODER_MODE5_Pos (10U) +#define GPIO_MODER_MODE5_Msk (0x3UL << GPIO_MODER_MODE5_Pos) /*!< 0x00000C00 */ +#define GPIO_MODER_MODE5 GPIO_MODER_MODE5_Msk +#define GPIO_MODER_MODE5_0 (0x1UL << GPIO_MODER_MODE5_Pos) /*!< 0x00000400 */ +#define GPIO_MODER_MODE5_1 (0x2UL << GPIO_MODER_MODE5_Pos) /*!< 0x00000800 */ +#define GPIO_MODER_MODE6_Pos (12U) +#define GPIO_MODER_MODE6_Msk (0x3UL << GPIO_MODER_MODE6_Pos) /*!< 0x00003000 */ +#define GPIO_MODER_MODE6 GPIO_MODER_MODE6_Msk +#define GPIO_MODER_MODE6_0 (0x1UL << GPIO_MODER_MODE6_Pos) /*!< 0x00001000 */ +#define GPIO_MODER_MODE6_1 (0x2UL << GPIO_MODER_MODE6_Pos) /*!< 0x00002000 */ +#define GPIO_MODER_MODE7_Pos (14U) +#define GPIO_MODER_MODE7_Msk (0x3UL << GPIO_MODER_MODE7_Pos) /*!< 0x0000C000 */ +#define GPIO_MODER_MODE7 GPIO_MODER_MODE7_Msk +#define GPIO_MODER_MODE7_0 (0x1UL << GPIO_MODER_MODE7_Pos) /*!< 0x00004000 */ +#define GPIO_MODER_MODE7_1 (0x2UL << GPIO_MODER_MODE7_Pos) /*!< 0x00008000 */ +#define GPIO_MODER_MODE8_Pos (16U) +#define GPIO_MODER_MODE8_Msk (0x3UL << GPIO_MODER_MODE8_Pos) /*!< 0x00030000 */ +#define GPIO_MODER_MODE8 GPIO_MODER_MODE8_Msk +#define GPIO_MODER_MODE8_0 (0x1UL << GPIO_MODER_MODE8_Pos) /*!< 0x00010000 */ +#define GPIO_MODER_MODE8_1 (0x2UL << GPIO_MODER_MODE8_Pos) /*!< 0x00020000 */ +#define GPIO_MODER_MODE9_Pos (18U) +#define GPIO_MODER_MODE9_Msk (0x3UL << GPIO_MODER_MODE9_Pos) /*!< 0x000C0000 */ +#define GPIO_MODER_MODE9 GPIO_MODER_MODE9_Msk +#define GPIO_MODER_MODE9_0 (0x1UL << GPIO_MODER_MODE9_Pos) /*!< 0x00040000 */ +#define GPIO_MODER_MODE9_1 (0x2UL << GPIO_MODER_MODE9_Pos) /*!< 0x00080000 */ +#define GPIO_MODER_MODE10_Pos (20U) +#define GPIO_MODER_MODE10_Msk (0x3UL << GPIO_MODER_MODE10_Pos) /*!< 0x00300000 */ +#define GPIO_MODER_MODE10 GPIO_MODER_MODE10_Msk +#define GPIO_MODER_MODE10_0 (0x1UL << GPIO_MODER_MODE10_Pos) /*!< 0x00100000 */ +#define GPIO_MODER_MODE10_1 (0x2UL << GPIO_MODER_MODE10_Pos) /*!< 0x00200000 */ +#define GPIO_MODER_MODE11_Pos (22U) +#define GPIO_MODER_MODE11_Msk (0x3UL << GPIO_MODER_MODE11_Pos) /*!< 0x00C00000 */ +#define GPIO_MODER_MODE11 GPIO_MODER_MODE11_Msk +#define GPIO_MODER_MODE11_0 (0x1UL << GPIO_MODER_MODE11_Pos) /*!< 0x00400000 */ +#define GPIO_MODER_MODE11_1 (0x2UL << GPIO_MODER_MODE11_Pos) /*!< 0x00800000 */ +#define GPIO_MODER_MODE12_Pos (24U) +#define GPIO_MODER_MODE12_Msk (0x3UL << GPIO_MODER_MODE12_Pos) /*!< 0x03000000 */ +#define GPIO_MODER_MODE12 GPIO_MODER_MODE12_Msk +#define GPIO_MODER_MODE12_0 (0x1UL << GPIO_MODER_MODE12_Pos) /*!< 0x01000000 */ +#define GPIO_MODER_MODE12_1 (0x2UL << GPIO_MODER_MODE12_Pos) /*!< 0x02000000 */ +#define GPIO_MODER_MODE13_Pos (26U) +#define GPIO_MODER_MODE13_Msk (0x3UL << GPIO_MODER_MODE13_Pos) /*!< 0x0C000000 */ +#define GPIO_MODER_MODE13 GPIO_MODER_MODE13_Msk +#define GPIO_MODER_MODE13_0 (0x1UL << GPIO_MODER_MODE13_Pos) /*!< 0x04000000 */ +#define GPIO_MODER_MODE13_1 (0x2UL << GPIO_MODER_MODE13_Pos) /*!< 0x08000000 */ +#define GPIO_MODER_MODE14_Pos (28U) +#define GPIO_MODER_MODE14_Msk (0x3UL << GPIO_MODER_MODE14_Pos) /*!< 0x30000000 */ +#define GPIO_MODER_MODE14 GPIO_MODER_MODE14_Msk +#define GPIO_MODER_MODE14_0 (0x1UL << GPIO_MODER_MODE14_Pos) /*!< 0x10000000 */ +#define GPIO_MODER_MODE14_1 (0x2UL << GPIO_MODER_MODE14_Pos) /*!< 0x20000000 */ +#define GPIO_MODER_MODE15_Pos (30U) +#define GPIO_MODER_MODE15_Msk (0x3UL << GPIO_MODER_MODE15_Pos) /*!< 0xC0000000 */ +#define GPIO_MODER_MODE15 GPIO_MODER_MODE15_Msk +#define GPIO_MODER_MODE15_0 (0x1UL << GPIO_MODER_MODE15_Pos) /*!< 0x40000000 */ +#define GPIO_MODER_MODE15_1 (0x2UL << GPIO_MODER_MODE15_Pos) /*!< 0x80000000 */ + +/****************** Bits definition for GPIO_OTYPER register ****************/ +#define GPIO_OTYPER_OT0_Pos (0U) +#define GPIO_OTYPER_OT0_Msk (0x1UL << GPIO_OTYPER_OT0_Pos) /*!< 0x00000001 */ +#define GPIO_OTYPER_OT0 GPIO_OTYPER_OT0_Msk +#define GPIO_OTYPER_OT1_Pos (1U) +#define GPIO_OTYPER_OT1_Msk (0x1UL << GPIO_OTYPER_OT1_Pos) /*!< 0x00000002 */ +#define GPIO_OTYPER_OT1 GPIO_OTYPER_OT1_Msk +#define GPIO_OTYPER_OT2_Pos (2U) +#define GPIO_OTYPER_OT2_Msk (0x1UL << GPIO_OTYPER_OT2_Pos) /*!< 0x00000004 */ +#define GPIO_OTYPER_OT2 GPIO_OTYPER_OT2_Msk +#define GPIO_OTYPER_OT3_Pos (3U) +#define GPIO_OTYPER_OT3_Msk (0x1UL << GPIO_OTYPER_OT3_Pos) /*!< 0x00000008 */ +#define GPIO_OTYPER_OT3 GPIO_OTYPER_OT3_Msk +#define GPIO_OTYPER_OT4_Pos (4U) +#define GPIO_OTYPER_OT4_Msk (0x1UL << GPIO_OTYPER_OT4_Pos) /*!< 0x00000010 */ +#define GPIO_OTYPER_OT4 GPIO_OTYPER_OT4_Msk +#define GPIO_OTYPER_OT5_Pos (5U) +#define GPIO_OTYPER_OT5_Msk (0x1UL << GPIO_OTYPER_OT5_Pos) /*!< 0x00000020 */ +#define GPIO_OTYPER_OT5 GPIO_OTYPER_OT5_Msk +#define GPIO_OTYPER_OT6_Pos (6U) +#define GPIO_OTYPER_OT6_Msk (0x1UL << GPIO_OTYPER_OT6_Pos) /*!< 0x00000040 */ +#define GPIO_OTYPER_OT6 GPIO_OTYPER_OT6_Msk +#define GPIO_OTYPER_OT7_Pos (7U) +#define GPIO_OTYPER_OT7_Msk (0x1UL << GPIO_OTYPER_OT7_Pos) /*!< 0x00000080 */ +#define GPIO_OTYPER_OT7 GPIO_OTYPER_OT7_Msk +#define GPIO_OTYPER_OT8_Pos (8U) +#define GPIO_OTYPER_OT8_Msk (0x1UL << GPIO_OTYPER_OT8_Pos) /*!< 0x00000100 */ +#define GPIO_OTYPER_OT8 GPIO_OTYPER_OT8_Msk +#define GPIO_OTYPER_OT9_Pos (9U) +#define GPIO_OTYPER_OT9_Msk (0x1UL << GPIO_OTYPER_OT9_Pos) /*!< 0x00000200 */ +#define GPIO_OTYPER_OT9 GPIO_OTYPER_OT9_Msk +#define GPIO_OTYPER_OT10_Pos (10U) +#define GPIO_OTYPER_OT10_Msk (0x1UL << GPIO_OTYPER_OT10_Pos) /*!< 0x00000400 */ +#define GPIO_OTYPER_OT10 GPIO_OTYPER_OT10_Msk +#define GPIO_OTYPER_OT11_Pos (11U) +#define GPIO_OTYPER_OT11_Msk (0x1UL << GPIO_OTYPER_OT11_Pos) /*!< 0x00000800 */ +#define GPIO_OTYPER_OT11 GPIO_OTYPER_OT11_Msk +#define GPIO_OTYPER_OT12_Pos (12U) +#define GPIO_OTYPER_OT12_Msk (0x1UL << GPIO_OTYPER_OT12_Pos) /*!< 0x00001000 */ +#define GPIO_OTYPER_OT12 GPIO_OTYPER_OT12_Msk +#define GPIO_OTYPER_OT13_Pos (13U) +#define GPIO_OTYPER_OT13_Msk (0x1UL << GPIO_OTYPER_OT13_Pos) /*!< 0x00002000 */ +#define GPIO_OTYPER_OT13 GPIO_OTYPER_OT13_Msk +#define GPIO_OTYPER_OT14_Pos (14U) +#define GPIO_OTYPER_OT14_Msk (0x1UL << GPIO_OTYPER_OT14_Pos) /*!< 0x00004000 */ +#define GPIO_OTYPER_OT14 GPIO_OTYPER_OT14_Msk +#define GPIO_OTYPER_OT15_Pos (15U) +#define GPIO_OTYPER_OT15_Msk (0x1UL << GPIO_OTYPER_OT15_Pos) /*!< 0x00008000 */ +#define GPIO_OTYPER_OT15 GPIO_OTYPER_OT15_Msk + +/****************** Bits definition for GPIO_OSPEEDR register ***************/ +#define GPIO_OSPEEDR_OSPEED0_Pos (0U) +#define GPIO_OSPEEDR_OSPEED0_Msk (0x3UL << GPIO_OSPEEDR_OSPEED0_Pos) /*!< 0x00000003 */ +#define GPIO_OSPEEDR_OSPEED0 GPIO_OSPEEDR_OSPEED0_Msk +#define GPIO_OSPEEDR_OSPEED0_0 (0x1UL << GPIO_OSPEEDR_OSPEED0_Pos) /*!< 0x00000001 */ +#define GPIO_OSPEEDR_OSPEED0_1 (0x2UL << GPIO_OSPEEDR_OSPEED0_Pos) /*!< 0x00000002 */ +#define GPIO_OSPEEDR_OSPEED1_Pos (2U) +#define GPIO_OSPEEDR_OSPEED1_Msk (0x3UL << GPIO_OSPEEDR_OSPEED1_Pos) /*!< 0x0000000C */ +#define GPIO_OSPEEDR_OSPEED1 GPIO_OSPEEDR_OSPEED1_Msk +#define GPIO_OSPEEDR_OSPEED1_0 (0x1UL << GPIO_OSPEEDR_OSPEED1_Pos) /*!< 0x00000004 */ +#define GPIO_OSPEEDR_OSPEED1_1 (0x2UL << GPIO_OSPEEDR_OSPEED1_Pos) /*!< 0x00000008 */ +#define GPIO_OSPEEDR_OSPEED2_Pos (4U) +#define GPIO_OSPEEDR_OSPEED2_Msk (0x3UL << GPIO_OSPEEDR_OSPEED2_Pos) /*!< 0x00000030 */ +#define GPIO_OSPEEDR_OSPEED2 GPIO_OSPEEDR_OSPEED2_Msk +#define GPIO_OSPEEDR_OSPEED2_0 (0x1UL << GPIO_OSPEEDR_OSPEED2_Pos) /*!< 0x00000010 */ +#define GPIO_OSPEEDR_OSPEED2_1 (0x2UL << GPIO_OSPEEDR_OSPEED2_Pos) /*!< 0x00000020 */ +#define GPIO_OSPEEDR_OSPEED3_Pos (6U) +#define GPIO_OSPEEDR_OSPEED3_Msk (0x3UL << GPIO_OSPEEDR_OSPEED3_Pos) /*!< 0x000000C0 */ +#define GPIO_OSPEEDR_OSPEED3 GPIO_OSPEEDR_OSPEED3_Msk +#define GPIO_OSPEEDR_OSPEED3_0 (0x1UL << GPIO_OSPEEDR_OSPEED3_Pos) /*!< 0x00000040 */ +#define GPIO_OSPEEDR_OSPEED3_1 (0x2UL << GPIO_OSPEEDR_OSPEED3_Pos) /*!< 0x00000080 */ +#define GPIO_OSPEEDR_OSPEED4_Pos (8U) +#define GPIO_OSPEEDR_OSPEED4_Msk (0x3UL << GPIO_OSPEEDR_OSPEED4_Pos) /*!< 0x00000300 */ +#define GPIO_OSPEEDR_OSPEED4 GPIO_OSPEEDR_OSPEED4_Msk +#define GPIO_OSPEEDR_OSPEED4_0 (0x1UL << GPIO_OSPEEDR_OSPEED4_Pos) /*!< 0x00000100 */ +#define GPIO_OSPEEDR_OSPEED4_1 (0x2UL << GPIO_OSPEEDR_OSPEED4_Pos) /*!< 0x00000200 */ +#define GPIO_OSPEEDR_OSPEED5_Pos (10U) +#define GPIO_OSPEEDR_OSPEED5_Msk (0x3UL << GPIO_OSPEEDR_OSPEED5_Pos) /*!< 0x00000C00 */ +#define GPIO_OSPEEDR_OSPEED5 GPIO_OSPEEDR_OSPEED5_Msk +#define GPIO_OSPEEDR_OSPEED5_0 (0x1UL << GPIO_OSPEEDR_OSPEED5_Pos) /*!< 0x00000400 */ +#define GPIO_OSPEEDR_OSPEED5_1 (0x2UL << GPIO_OSPEEDR_OSPEED5_Pos) /*!< 0x00000800 */ +#define GPIO_OSPEEDR_OSPEED6_Pos (12U) +#define GPIO_OSPEEDR_OSPEED6_Msk (0x3UL << GPIO_OSPEEDR_OSPEED6_Pos) /*!< 0x00003000 */ +#define GPIO_OSPEEDR_OSPEED6 GPIO_OSPEEDR_OSPEED6_Msk +#define GPIO_OSPEEDR_OSPEED6_0 (0x1UL << GPIO_OSPEEDR_OSPEED6_Pos) /*!< 0x00001000 */ +#define GPIO_OSPEEDR_OSPEED6_1 (0x2UL << GPIO_OSPEEDR_OSPEED6_Pos) /*!< 0x00002000 */ +#define GPIO_OSPEEDR_OSPEED7_Pos (14U) +#define GPIO_OSPEEDR_OSPEED7_Msk (0x3UL << GPIO_OSPEEDR_OSPEED7_Pos) /*!< 0x0000C000 */ +#define GPIO_OSPEEDR_OSPEED7 GPIO_OSPEEDR_OSPEED7_Msk +#define GPIO_OSPEEDR_OSPEED7_0 (0x1UL << GPIO_OSPEEDR_OSPEED7_Pos) /*!< 0x00004000 */ +#define GPIO_OSPEEDR_OSPEED7_1 (0x2UL << GPIO_OSPEEDR_OSPEED7_Pos) /*!< 0x00008000 */ +#define GPIO_OSPEEDR_OSPEED8_Pos (16U) +#define GPIO_OSPEEDR_OSPEED8_Msk (0x3UL << GPIO_OSPEEDR_OSPEED8_Pos) /*!< 0x00030000 */ +#define GPIO_OSPEEDR_OSPEED8 GPIO_OSPEEDR_OSPEED8_Msk +#define GPIO_OSPEEDR_OSPEED8_0 (0x1UL << GPIO_OSPEEDR_OSPEED8_Pos) /*!< 0x00010000 */ +#define GPIO_OSPEEDR_OSPEED8_1 (0x2UL << GPIO_OSPEEDR_OSPEED8_Pos) /*!< 0x00020000 */ +#define GPIO_OSPEEDR_OSPEED9_Pos (18U) +#define GPIO_OSPEEDR_OSPEED9_Msk (0x3UL << GPIO_OSPEEDR_OSPEED9_Pos) /*!< 0x000C0000 */ +#define GPIO_OSPEEDR_OSPEED9 GPIO_OSPEEDR_OSPEED9_Msk +#define GPIO_OSPEEDR_OSPEED9_0 (0x1UL << GPIO_OSPEEDR_OSPEED9_Pos) /*!< 0x00040000 */ +#define GPIO_OSPEEDR_OSPEED9_1 (0x2UL << GPIO_OSPEEDR_OSPEED9_Pos) /*!< 0x00080000 */ +#define GPIO_OSPEEDR_OSPEED10_Pos (20U) +#define GPIO_OSPEEDR_OSPEED10_Msk (0x3UL << GPIO_OSPEEDR_OSPEED10_Pos) /*!< 0x00300000 */ +#define GPIO_OSPEEDR_OSPEED10 GPIO_OSPEEDR_OSPEED10_Msk +#define GPIO_OSPEEDR_OSPEED10_0 (0x1UL << GPIO_OSPEEDR_OSPEED10_Pos) /*!< 0x00100000 */ +#define GPIO_OSPEEDR_OSPEED10_1 (0x2UL << GPIO_OSPEEDR_OSPEED10_Pos) /*!< 0x00200000 */ +#define GPIO_OSPEEDR_OSPEED11_Pos (22U) +#define GPIO_OSPEEDR_OSPEED11_Msk (0x3UL << GPIO_OSPEEDR_OSPEED11_Pos) /*!< 0x00C00000 */ +#define GPIO_OSPEEDR_OSPEED11 GPIO_OSPEEDR_OSPEED11_Msk +#define GPIO_OSPEEDR_OSPEED11_0 (0x1UL << GPIO_OSPEEDR_OSPEED11_Pos) /*!< 0x00400000 */ +#define GPIO_OSPEEDR_OSPEED11_1 (0x2UL << GPIO_OSPEEDR_OSPEED11_Pos) /*!< 0x00800000 */ +#define GPIO_OSPEEDR_OSPEED12_Pos (24U) +#define GPIO_OSPEEDR_OSPEED12_Msk (0x3UL << GPIO_OSPEEDR_OSPEED12_Pos) /*!< 0x03000000 */ +#define GPIO_OSPEEDR_OSPEED12 GPIO_OSPEEDR_OSPEED12_Msk +#define GPIO_OSPEEDR_OSPEED12_0 (0x1UL << GPIO_OSPEEDR_OSPEED12_Pos) /*!< 0x01000000 */ +#define GPIO_OSPEEDR_OSPEED12_1 (0x2UL << GPIO_OSPEEDR_OSPEED12_Pos) /*!< 0x02000000 */ +#define GPIO_OSPEEDR_OSPEED13_Pos (26U) +#define GPIO_OSPEEDR_OSPEED13_Msk (0x3UL << GPIO_OSPEEDR_OSPEED13_Pos) /*!< 0x0C000000 */ +#define GPIO_OSPEEDR_OSPEED13 GPIO_OSPEEDR_OSPEED13_Msk +#define GPIO_OSPEEDR_OSPEED13_0 (0x1UL << GPIO_OSPEEDR_OSPEED13_Pos) /*!< 0x04000000 */ +#define GPIO_OSPEEDR_OSPEED13_1 (0x2UL << GPIO_OSPEEDR_OSPEED13_Pos) /*!< 0x08000000 */ +#define GPIO_OSPEEDR_OSPEED14_Pos (28U) +#define GPIO_OSPEEDR_OSPEED14_Msk (0x3UL << GPIO_OSPEEDR_OSPEED14_Pos) /*!< 0x30000000 */ +#define GPIO_OSPEEDR_OSPEED14 GPIO_OSPEEDR_OSPEED14_Msk +#define GPIO_OSPEEDR_OSPEED14_0 (0x1UL << GPIO_OSPEEDR_OSPEED14_Pos) /*!< 0x10000000 */ +#define GPIO_OSPEEDR_OSPEED14_1 (0x2UL << GPIO_OSPEEDR_OSPEED14_Pos) /*!< 0x20000000 */ +#define GPIO_OSPEEDR_OSPEED15_Pos (30U) +#define GPIO_OSPEEDR_OSPEED15_Msk (0x3UL << GPIO_OSPEEDR_OSPEED15_Pos) /*!< 0xC0000000 */ +#define GPIO_OSPEEDR_OSPEED15 GPIO_OSPEEDR_OSPEED15_Msk +#define GPIO_OSPEEDR_OSPEED15_0 (0x1UL << GPIO_OSPEEDR_OSPEED15_Pos) /*!< 0x40000000 */ +#define GPIO_OSPEEDR_OSPEED15_1 (0x2UL << GPIO_OSPEEDR_OSPEED15_Pos) /*!< 0x80000000 */ + +/****************** Bits definition for GPIO_PUPDR register *****************/ +#define GPIO_PUPDR_PUPD0_Pos (0U) +#define GPIO_PUPDR_PUPD0_Msk (0x3UL << GPIO_PUPDR_PUPD0_Pos) /*!< 0x00000003 */ +#define GPIO_PUPDR_PUPD0 GPIO_PUPDR_PUPD0_Msk +#define GPIO_PUPDR_PUPD0_0 (0x1UL << GPIO_PUPDR_PUPD0_Pos) /*!< 0x00000001 */ +#define GPIO_PUPDR_PUPD0_1 (0x2UL << GPIO_PUPDR_PUPD0_Pos) /*!< 0x00000002 */ +#define GPIO_PUPDR_PUPD1_Pos (2U) +#define GPIO_PUPDR_PUPD1_Msk (0x3UL << GPIO_PUPDR_PUPD1_Pos) /*!< 0x0000000C */ +#define GPIO_PUPDR_PUPD1 GPIO_PUPDR_PUPD1_Msk +#define GPIO_PUPDR_PUPD1_0 (0x1UL << GPIO_PUPDR_PUPD1_Pos) /*!< 0x00000004 */ +#define GPIO_PUPDR_PUPD1_1 (0x2UL << GPIO_PUPDR_PUPD1_Pos) /*!< 0x00000008 */ +#define GPIO_PUPDR_PUPD2_Pos (4U) +#define GPIO_PUPDR_PUPD2_Msk (0x3UL << GPIO_PUPDR_PUPD2_Pos) /*!< 0x00000030 */ +#define GPIO_PUPDR_PUPD2 GPIO_PUPDR_PUPD2_Msk +#define GPIO_PUPDR_PUPD2_0 (0x1UL << GPIO_PUPDR_PUPD2_Pos) /*!< 0x00000010 */ +#define GPIO_PUPDR_PUPD2_1 (0x2UL << GPIO_PUPDR_PUPD2_Pos) /*!< 0x00000020 */ +#define GPIO_PUPDR_PUPD3_Pos (6U) +#define GPIO_PUPDR_PUPD3_Msk (0x3UL << GPIO_PUPDR_PUPD3_Pos) /*!< 0x000000C0 */ +#define GPIO_PUPDR_PUPD3 GPIO_PUPDR_PUPD3_Msk +#define GPIO_PUPDR_PUPD3_0 (0x1UL << GPIO_PUPDR_PUPD3_Pos) /*!< 0x00000040 */ +#define GPIO_PUPDR_PUPD3_1 (0x2UL << GPIO_PUPDR_PUPD3_Pos) /*!< 0x00000080 */ +#define GPIO_PUPDR_PUPD4_Pos (8U) +#define GPIO_PUPDR_PUPD4_Msk (0x3UL << GPIO_PUPDR_PUPD4_Pos) /*!< 0x00000300 */ +#define GPIO_PUPDR_PUPD4 GPIO_PUPDR_PUPD4_Msk +#define GPIO_PUPDR_PUPD4_0 (0x1UL << GPIO_PUPDR_PUPD4_Pos) /*!< 0x00000100 */ +#define GPIO_PUPDR_PUPD4_1 (0x2UL << GPIO_PUPDR_PUPD4_Pos) /*!< 0x00000200 */ +#define GPIO_PUPDR_PUPD5_Pos (10U) +#define GPIO_PUPDR_PUPD5_Msk (0x3UL << GPIO_PUPDR_PUPD5_Pos) /*!< 0x00000C00 */ +#define GPIO_PUPDR_PUPD5 GPIO_PUPDR_PUPD5_Msk +#define GPIO_PUPDR_PUPD5_0 (0x1UL << GPIO_PUPDR_PUPD5_Pos) /*!< 0x00000400 */ +#define GPIO_PUPDR_PUPD5_1 (0x2UL << GPIO_PUPDR_PUPD5_Pos) /*!< 0x00000800 */ +#define GPIO_PUPDR_PUPD6_Pos (12U) +#define GPIO_PUPDR_PUPD6_Msk (0x3UL << GPIO_PUPDR_PUPD6_Pos) /*!< 0x00003000 */ +#define GPIO_PUPDR_PUPD6 GPIO_PUPDR_PUPD6_Msk +#define GPIO_PUPDR_PUPD6_0 (0x1UL << GPIO_PUPDR_PUPD6_Pos) /*!< 0x00001000 */ +#define GPIO_PUPDR_PUPD6_1 (0x2UL << GPIO_PUPDR_PUPD6_Pos) /*!< 0x00002000 */ +#define GPIO_PUPDR_PUPD7_Pos (14U) +#define GPIO_PUPDR_PUPD7_Msk (0x3UL << GPIO_PUPDR_PUPD7_Pos) /*!< 0x0000C000 */ +#define GPIO_PUPDR_PUPD7 GPIO_PUPDR_PUPD7_Msk +#define GPIO_PUPDR_PUPD7_0 (0x1UL << GPIO_PUPDR_PUPD7_Pos) /*!< 0x00004000 */ +#define GPIO_PUPDR_PUPD7_1 (0x2UL << GPIO_PUPDR_PUPD7_Pos) /*!< 0x00008000 */ +#define GPIO_PUPDR_PUPD8_Pos (16U) +#define GPIO_PUPDR_PUPD8_Msk (0x3UL << GPIO_PUPDR_PUPD8_Pos) /*!< 0x00030000 */ +#define GPIO_PUPDR_PUPD8 GPIO_PUPDR_PUPD8_Msk +#define GPIO_PUPDR_PUPD8_0 (0x1UL << GPIO_PUPDR_PUPD8_Pos) /*!< 0x00010000 */ +#define GPIO_PUPDR_PUPD8_1 (0x2UL << GPIO_PUPDR_PUPD8_Pos) /*!< 0x00020000 */ +#define GPIO_PUPDR_PUPD9_Pos (18U) +#define GPIO_PUPDR_PUPD9_Msk (0x3UL << GPIO_PUPDR_PUPD9_Pos) /*!< 0x000C0000 */ +#define GPIO_PUPDR_PUPD9 GPIO_PUPDR_PUPD9_Msk +#define GPIO_PUPDR_PUPD9_0 (0x1UL << GPIO_PUPDR_PUPD9_Pos) /*!< 0x00040000 */ +#define GPIO_PUPDR_PUPD9_1 (0x2UL << GPIO_PUPDR_PUPD9_Pos) /*!< 0x00080000 */ +#define GPIO_PUPDR_PUPD10_Pos (20U) +#define GPIO_PUPDR_PUPD10_Msk (0x3UL << GPIO_PUPDR_PUPD10_Pos) /*!< 0x00300000 */ +#define GPIO_PUPDR_PUPD10 GPIO_PUPDR_PUPD10_Msk +#define GPIO_PUPDR_PUPD10_0 (0x1UL << GPIO_PUPDR_PUPD10_Pos) /*!< 0x00100000 */ +#define GPIO_PUPDR_PUPD10_1 (0x2UL << GPIO_PUPDR_PUPD10_Pos) /*!< 0x00200000 */ +#define GPIO_PUPDR_PUPD11_Pos (22U) +#define GPIO_PUPDR_PUPD11_Msk (0x3UL << GPIO_PUPDR_PUPD11_Pos) /*!< 0x00C00000 */ +#define GPIO_PUPDR_PUPD11 GPIO_PUPDR_PUPD11_Msk +#define GPIO_PUPDR_PUPD11_0 (0x1UL << GPIO_PUPDR_PUPD11_Pos) /*!< 0x00400000 */ +#define GPIO_PUPDR_PUPD11_1 (0x2UL << GPIO_PUPDR_PUPD11_Pos) /*!< 0x00800000 */ +#define GPIO_PUPDR_PUPD12_Pos (24U) +#define GPIO_PUPDR_PUPD12_Msk (0x3UL << GPIO_PUPDR_PUPD12_Pos) /*!< 0x03000000 */ +#define GPIO_PUPDR_PUPD12 GPIO_PUPDR_PUPD12_Msk +#define GPIO_PUPDR_PUPD12_0 (0x1UL << GPIO_PUPDR_PUPD12_Pos) /*!< 0x01000000 */ +#define GPIO_PUPDR_PUPD12_1 (0x2UL << GPIO_PUPDR_PUPD12_Pos) /*!< 0x02000000 */ +#define GPIO_PUPDR_PUPD13_Pos (26U) +#define GPIO_PUPDR_PUPD13_Msk (0x3UL << GPIO_PUPDR_PUPD13_Pos) /*!< 0x0C000000 */ +#define GPIO_PUPDR_PUPD13 GPIO_PUPDR_PUPD13_Msk +#define GPIO_PUPDR_PUPD13_0 (0x1UL << GPIO_PUPDR_PUPD13_Pos) /*!< 0x04000000 */ +#define GPIO_PUPDR_PUPD13_1 (0x2UL << GPIO_PUPDR_PUPD13_Pos) /*!< 0x08000000 */ +#define GPIO_PUPDR_PUPD14_Pos (28U) +#define GPIO_PUPDR_PUPD14_Msk (0x3UL << GPIO_PUPDR_PUPD14_Pos) /*!< 0x30000000 */ +#define GPIO_PUPDR_PUPD14 GPIO_PUPDR_PUPD14_Msk +#define GPIO_PUPDR_PUPD14_0 (0x1UL << GPIO_PUPDR_PUPD14_Pos) /*!< 0x10000000 */ +#define GPIO_PUPDR_PUPD14_1 (0x2UL << GPIO_PUPDR_PUPD14_Pos) /*!< 0x20000000 */ +#define GPIO_PUPDR_PUPD15_Pos (30U) +#define GPIO_PUPDR_PUPD15_Msk (0x3UL << GPIO_PUPDR_PUPD15_Pos) /*!< 0xC0000000 */ +#define GPIO_PUPDR_PUPD15 GPIO_PUPDR_PUPD15_Msk +#define GPIO_PUPDR_PUPD15_0 (0x1UL << GPIO_PUPDR_PUPD15_Pos) /*!< 0x40000000 */ +#define GPIO_PUPDR_PUPD15_1 (0x2UL << GPIO_PUPDR_PUPD15_Pos) /*!< 0x80000000 */ + +/****************** Bits definition for GPIO_IDR register *******************/ +#define GPIO_IDR_ID0_Pos (0U) +#define GPIO_IDR_ID0_Msk (0x1UL << GPIO_IDR_ID0_Pos) /*!< 0x00000001 */ +#define GPIO_IDR_ID0 GPIO_IDR_ID0_Msk +#define GPIO_IDR_ID1_Pos (1U) +#define GPIO_IDR_ID1_Msk (0x1UL << GPIO_IDR_ID1_Pos) /*!< 0x00000002 */ +#define GPIO_IDR_ID1 GPIO_IDR_ID1_Msk +#define GPIO_IDR_ID2_Pos (2U) +#define GPIO_IDR_ID2_Msk (0x1UL << GPIO_IDR_ID2_Pos) /*!< 0x00000004 */ +#define GPIO_IDR_ID2 GPIO_IDR_ID2_Msk +#define GPIO_IDR_ID3_Pos (3U) +#define GPIO_IDR_ID3_Msk (0x1UL << GPIO_IDR_ID3_Pos) /*!< 0x00000008 */ +#define GPIO_IDR_ID3 GPIO_IDR_ID3_Msk +#define GPIO_IDR_ID4_Pos (4U) +#define GPIO_IDR_ID4_Msk (0x1UL << GPIO_IDR_ID4_Pos) /*!< 0x00000010 */ +#define GPIO_IDR_ID4 GPIO_IDR_ID4_Msk +#define GPIO_IDR_ID5_Pos (5U) +#define GPIO_IDR_ID5_Msk (0x1UL << GPIO_IDR_ID5_Pos) /*!< 0x00000020 */ +#define GPIO_IDR_ID5 GPIO_IDR_ID5_Msk +#define GPIO_IDR_ID6_Pos (6U) +#define GPIO_IDR_ID6_Msk (0x1UL << GPIO_IDR_ID6_Pos) /*!< 0x00000040 */ +#define GPIO_IDR_ID6 GPIO_IDR_ID6_Msk +#define GPIO_IDR_ID7_Pos (7U) +#define GPIO_IDR_ID7_Msk (0x1UL << GPIO_IDR_ID7_Pos) /*!< 0x00000080 */ +#define GPIO_IDR_ID7 GPIO_IDR_ID7_Msk +#define GPIO_IDR_ID8_Pos (8U) +#define GPIO_IDR_ID8_Msk (0x1UL << GPIO_IDR_ID8_Pos) /*!< 0x00000100 */ +#define GPIO_IDR_ID8 GPIO_IDR_ID8_Msk +#define GPIO_IDR_ID9_Pos (9U) +#define GPIO_IDR_ID9_Msk (0x1UL << GPIO_IDR_ID9_Pos) /*!< 0x00000200 */ +#define GPIO_IDR_ID9 GPIO_IDR_ID9_Msk +#define GPIO_IDR_ID10_Pos (10U) +#define GPIO_IDR_ID10_Msk (0x1UL << GPIO_IDR_ID10_Pos) /*!< 0x00000400 */ +#define GPIO_IDR_ID10 GPIO_IDR_ID10_Msk +#define GPIO_IDR_ID11_Pos (11U) +#define GPIO_IDR_ID11_Msk (0x1UL << GPIO_IDR_ID11_Pos) /*!< 0x00000800 */ +#define GPIO_IDR_ID11 GPIO_IDR_ID11_Msk +#define GPIO_IDR_ID12_Pos (12U) +#define GPIO_IDR_ID12_Msk (0x1UL << GPIO_IDR_ID12_Pos) /*!< 0x00001000 */ +#define GPIO_IDR_ID12 GPIO_IDR_ID12_Msk +#define GPIO_IDR_ID13_Pos (13U) +#define GPIO_IDR_ID13_Msk (0x1UL << GPIO_IDR_ID13_Pos) /*!< 0x00002000 */ +#define GPIO_IDR_ID13 GPIO_IDR_ID13_Msk +#define GPIO_IDR_ID14_Pos (14U) +#define GPIO_IDR_ID14_Msk (0x1UL << GPIO_IDR_ID14_Pos) /*!< 0x00004000 */ +#define GPIO_IDR_ID14 GPIO_IDR_ID14_Msk +#define GPIO_IDR_ID15_Pos (15U) +#define GPIO_IDR_ID15_Msk (0x1UL << GPIO_IDR_ID15_Pos) /*!< 0x00008000 */ +#define GPIO_IDR_ID15 GPIO_IDR_ID15_Msk + +/****************** Bits definition for GPIO_ODR register *******************/ +#define GPIO_ODR_OD0_Pos (0U) +#define GPIO_ODR_OD0_Msk (0x1UL << GPIO_ODR_OD0_Pos) /*!< 0x00000001 */ +#define GPIO_ODR_OD0 GPIO_ODR_OD0_Msk +#define GPIO_ODR_OD1_Pos (1U) +#define GPIO_ODR_OD1_Msk (0x1UL << GPIO_ODR_OD1_Pos) /*!< 0x00000002 */ +#define GPIO_ODR_OD1 GPIO_ODR_OD1_Msk +#define GPIO_ODR_OD2_Pos (2U) +#define GPIO_ODR_OD2_Msk (0x1UL << GPIO_ODR_OD2_Pos) /*!< 0x00000004 */ +#define GPIO_ODR_OD2 GPIO_ODR_OD2_Msk +#define GPIO_ODR_OD3_Pos (3U) +#define GPIO_ODR_OD3_Msk (0x1UL << GPIO_ODR_OD3_Pos) /*!< 0x00000008 */ +#define GPIO_ODR_OD3 GPIO_ODR_OD3_Msk +#define GPIO_ODR_OD4_Pos (4U) +#define GPIO_ODR_OD4_Msk (0x1UL << GPIO_ODR_OD4_Pos) /*!< 0x00000010 */ +#define GPIO_ODR_OD4 GPIO_ODR_OD4_Msk +#define GPIO_ODR_OD5_Pos (5U) +#define GPIO_ODR_OD5_Msk (0x1UL << GPIO_ODR_OD5_Pos) /*!< 0x00000020 */ +#define GPIO_ODR_OD5 GPIO_ODR_OD5_Msk +#define GPIO_ODR_OD6_Pos (6U) +#define GPIO_ODR_OD6_Msk (0x1UL << GPIO_ODR_OD6_Pos) /*!< 0x00000040 */ +#define GPIO_ODR_OD6 GPIO_ODR_OD6_Msk +#define GPIO_ODR_OD7_Pos (7U) +#define GPIO_ODR_OD7_Msk (0x1UL << GPIO_ODR_OD7_Pos) /*!< 0x00000080 */ +#define GPIO_ODR_OD7 GPIO_ODR_OD7_Msk +#define GPIO_ODR_OD8_Pos (8U) +#define GPIO_ODR_OD8_Msk (0x1UL << GPIO_ODR_OD8_Pos) /*!< 0x00000100 */ +#define GPIO_ODR_OD8 GPIO_ODR_OD8_Msk +#define GPIO_ODR_OD9_Pos (9U) +#define GPIO_ODR_OD9_Msk (0x1UL << GPIO_ODR_OD9_Pos) /*!< 0x00000200 */ +#define GPIO_ODR_OD9 GPIO_ODR_OD9_Msk +#define GPIO_ODR_OD10_Pos (10U) +#define GPIO_ODR_OD10_Msk (0x1UL << GPIO_ODR_OD10_Pos) /*!< 0x00000400 */ +#define GPIO_ODR_OD10 GPIO_ODR_OD10_Msk +#define GPIO_ODR_OD11_Pos (11U) +#define GPIO_ODR_OD11_Msk (0x1UL << GPIO_ODR_OD11_Pos) /*!< 0x00000800 */ +#define GPIO_ODR_OD11 GPIO_ODR_OD11_Msk +#define GPIO_ODR_OD12_Pos (12U) +#define GPIO_ODR_OD12_Msk (0x1UL << GPIO_ODR_OD12_Pos) /*!< 0x00001000 */ +#define GPIO_ODR_OD12 GPIO_ODR_OD12_Msk +#define GPIO_ODR_OD13_Pos (13U) +#define GPIO_ODR_OD13_Msk (0x1UL << GPIO_ODR_OD13_Pos) /*!< 0x00002000 */ +#define GPIO_ODR_OD13 GPIO_ODR_OD13_Msk +#define GPIO_ODR_OD14_Pos (14U) +#define GPIO_ODR_OD14_Msk (0x1UL << GPIO_ODR_OD14_Pos) /*!< 0x00004000 */ +#define GPIO_ODR_OD14 GPIO_ODR_OD14_Msk +#define GPIO_ODR_OD15_Pos (15U) +#define GPIO_ODR_OD15_Msk (0x1UL << GPIO_ODR_OD15_Pos) /*!< 0x00008000 */ +#define GPIO_ODR_OD15 GPIO_ODR_OD15_Msk + +/****************** Bits definition for GPIO_BSRR register ******************/ +#define GPIO_BSRR_BS0_Pos (0U) +#define GPIO_BSRR_BS0_Msk (0x1UL << GPIO_BSRR_BS0_Pos) /*!< 0x00000001 */ +#define GPIO_BSRR_BS0 GPIO_BSRR_BS0_Msk +#define GPIO_BSRR_BS1_Pos (1U) +#define GPIO_BSRR_BS1_Msk (0x1UL << GPIO_BSRR_BS1_Pos) /*!< 0x00000002 */ +#define GPIO_BSRR_BS1 GPIO_BSRR_BS1_Msk +#define GPIO_BSRR_BS2_Pos (2U) +#define GPIO_BSRR_BS2_Msk (0x1UL << GPIO_BSRR_BS2_Pos) /*!< 0x00000004 */ +#define GPIO_BSRR_BS2 GPIO_BSRR_BS2_Msk +#define GPIO_BSRR_BS3_Pos (3U) +#define GPIO_BSRR_BS3_Msk (0x1UL << GPIO_BSRR_BS3_Pos) /*!< 0x00000008 */ +#define GPIO_BSRR_BS3 GPIO_BSRR_BS3_Msk +#define GPIO_BSRR_BS4_Pos (4U) +#define GPIO_BSRR_BS4_Msk (0x1UL << GPIO_BSRR_BS4_Pos) /*!< 0x00000010 */ +#define GPIO_BSRR_BS4 GPIO_BSRR_BS4_Msk +#define GPIO_BSRR_BS5_Pos (5U) +#define GPIO_BSRR_BS5_Msk (0x1UL << GPIO_BSRR_BS5_Pos) /*!< 0x00000020 */ +#define GPIO_BSRR_BS5 GPIO_BSRR_BS5_Msk +#define GPIO_BSRR_BS6_Pos (6U) +#define GPIO_BSRR_BS6_Msk (0x1UL << GPIO_BSRR_BS6_Pos) /*!< 0x00000040 */ +#define GPIO_BSRR_BS6 GPIO_BSRR_BS6_Msk +#define GPIO_BSRR_BS7_Pos (7U) +#define GPIO_BSRR_BS7_Msk (0x1UL << GPIO_BSRR_BS7_Pos) /*!< 0x00000080 */ +#define GPIO_BSRR_BS7 GPIO_BSRR_BS7_Msk +#define GPIO_BSRR_BS8_Pos (8U) +#define GPIO_BSRR_BS8_Msk (0x1UL << GPIO_BSRR_BS8_Pos) /*!< 0x00000100 */ +#define GPIO_BSRR_BS8 GPIO_BSRR_BS8_Msk +#define GPIO_BSRR_BS9_Pos (9U) +#define GPIO_BSRR_BS9_Msk (0x1UL << GPIO_BSRR_BS9_Pos) /*!< 0x00000200 */ +#define GPIO_BSRR_BS9 GPIO_BSRR_BS9_Msk +#define GPIO_BSRR_BS10_Pos (10U) +#define GPIO_BSRR_BS10_Msk (0x1UL << GPIO_BSRR_BS10_Pos) /*!< 0x00000400 */ +#define GPIO_BSRR_BS10 GPIO_BSRR_BS10_Msk +#define GPIO_BSRR_BS11_Pos (11U) +#define GPIO_BSRR_BS11_Msk (0x1UL << GPIO_BSRR_BS11_Pos) /*!< 0x00000800 */ +#define GPIO_BSRR_BS11 GPIO_BSRR_BS11_Msk +#define GPIO_BSRR_BS12_Pos (12U) +#define GPIO_BSRR_BS12_Msk (0x1UL << GPIO_BSRR_BS12_Pos) /*!< 0x00001000 */ +#define GPIO_BSRR_BS12 GPIO_BSRR_BS12_Msk +#define GPIO_BSRR_BS13_Pos (13U) +#define GPIO_BSRR_BS13_Msk (0x1UL << GPIO_BSRR_BS13_Pos) /*!< 0x00002000 */ +#define GPIO_BSRR_BS13 GPIO_BSRR_BS13_Msk +#define GPIO_BSRR_BS14_Pos (14U) +#define GPIO_BSRR_BS14_Msk (0x1UL << GPIO_BSRR_BS14_Pos) /*!< 0x00004000 */ +#define GPIO_BSRR_BS14 GPIO_BSRR_BS14_Msk +#define GPIO_BSRR_BS15_Pos (15U) +#define GPIO_BSRR_BS15_Msk (0x1UL << GPIO_BSRR_BS15_Pos) /*!< 0x00008000 */ +#define GPIO_BSRR_BS15 GPIO_BSRR_BS15_Msk +#define GPIO_BSRR_BR0_Pos (16U) +#define GPIO_BSRR_BR0_Msk (0x1UL << GPIO_BSRR_BR0_Pos) /*!< 0x00010000 */ +#define GPIO_BSRR_BR0 GPIO_BSRR_BR0_Msk +#define GPIO_BSRR_BR1_Pos (17U) +#define GPIO_BSRR_BR1_Msk (0x1UL << GPIO_BSRR_BR1_Pos) /*!< 0x00020000 */ +#define GPIO_BSRR_BR1 GPIO_BSRR_BR1_Msk +#define GPIO_BSRR_BR2_Pos (18U) +#define GPIO_BSRR_BR2_Msk (0x1UL << GPIO_BSRR_BR2_Pos) /*!< 0x00040000 */ +#define GPIO_BSRR_BR2 GPIO_BSRR_BR2_Msk +#define GPIO_BSRR_BR3_Pos (19U) +#define GPIO_BSRR_BR3_Msk (0x1UL << GPIO_BSRR_BR3_Pos) /*!< 0x00080000 */ +#define GPIO_BSRR_BR3 GPIO_BSRR_BR3_Msk +#define GPIO_BSRR_BR4_Pos (20U) +#define GPIO_BSRR_BR4_Msk (0x1UL << GPIO_BSRR_BR4_Pos) /*!< 0x00100000 */ +#define GPIO_BSRR_BR4 GPIO_BSRR_BR4_Msk +#define GPIO_BSRR_BR5_Pos (21U) +#define GPIO_BSRR_BR5_Msk (0x1UL << GPIO_BSRR_BR5_Pos) /*!< 0x00200000 */ +#define GPIO_BSRR_BR5 GPIO_BSRR_BR5_Msk +#define GPIO_BSRR_BR6_Pos (22U) +#define GPIO_BSRR_BR6_Msk (0x1UL << GPIO_BSRR_BR6_Pos) /*!< 0x00400000 */ +#define GPIO_BSRR_BR6 GPIO_BSRR_BR6_Msk +#define GPIO_BSRR_BR7_Pos (23U) +#define GPIO_BSRR_BR7_Msk (0x1UL << GPIO_BSRR_BR7_Pos) /*!< 0x00800000 */ +#define GPIO_BSRR_BR7 GPIO_BSRR_BR7_Msk +#define GPIO_BSRR_BR8_Pos (24U) +#define GPIO_BSRR_BR8_Msk (0x1UL << GPIO_BSRR_BR8_Pos) /*!< 0x01000000 */ +#define GPIO_BSRR_BR8 GPIO_BSRR_BR8_Msk +#define GPIO_BSRR_BR9_Pos (25U) +#define GPIO_BSRR_BR9_Msk (0x1UL << GPIO_BSRR_BR9_Pos) /*!< 0x02000000 */ +#define GPIO_BSRR_BR9 GPIO_BSRR_BR9_Msk +#define GPIO_BSRR_BR10_Pos (26U) +#define GPIO_BSRR_BR10_Msk (0x1UL << GPIO_BSRR_BR10_Pos) /*!< 0x04000000 */ +#define GPIO_BSRR_BR10 GPIO_BSRR_BR10_Msk +#define GPIO_BSRR_BR11_Pos (27U) +#define GPIO_BSRR_BR11_Msk (0x1UL << GPIO_BSRR_BR11_Pos) /*!< 0x08000000 */ +#define GPIO_BSRR_BR11 GPIO_BSRR_BR11_Msk +#define GPIO_BSRR_BR12_Pos (28U) +#define GPIO_BSRR_BR12_Msk (0x1UL << GPIO_BSRR_BR12_Pos) /*!< 0x10000000 */ +#define GPIO_BSRR_BR12 GPIO_BSRR_BR12_Msk +#define GPIO_BSRR_BR13_Pos (29U) +#define GPIO_BSRR_BR13_Msk (0x1UL << GPIO_BSRR_BR13_Pos) /*!< 0x20000000 */ +#define GPIO_BSRR_BR13 GPIO_BSRR_BR13_Msk +#define GPIO_BSRR_BR14_Pos (30U) +#define GPIO_BSRR_BR14_Msk (0x1UL << GPIO_BSRR_BR14_Pos) /*!< 0x40000000 */ +#define GPIO_BSRR_BR14 GPIO_BSRR_BR14_Msk +#define GPIO_BSRR_BR15_Pos (31U) +#define GPIO_BSRR_BR15_Msk (0x1UL << GPIO_BSRR_BR15_Pos) /*!< 0x80000000 */ +#define GPIO_BSRR_BR15 GPIO_BSRR_BR15_Msk + +/****************** Bit definition for GPIO_LCKR register *********************/ +#define GPIO_LCKR_LCK0_Pos (0U) +#define GPIO_LCKR_LCK0_Msk (0x1UL << GPIO_LCKR_LCK0_Pos) /*!< 0x00000001 */ +#define GPIO_LCKR_LCK0 GPIO_LCKR_LCK0_Msk +#define GPIO_LCKR_LCK1_Pos (1U) +#define GPIO_LCKR_LCK1_Msk (0x1UL << GPIO_LCKR_LCK1_Pos) /*!< 0x00000002 */ +#define GPIO_LCKR_LCK1 GPIO_LCKR_LCK1_Msk +#define GPIO_LCKR_LCK2_Pos (2U) +#define GPIO_LCKR_LCK2_Msk (0x1UL << GPIO_LCKR_LCK2_Pos) /*!< 0x00000004 */ +#define GPIO_LCKR_LCK2 GPIO_LCKR_LCK2_Msk +#define GPIO_LCKR_LCK3_Pos (3U) +#define GPIO_LCKR_LCK3_Msk (0x1UL << GPIO_LCKR_LCK3_Pos) /*!< 0x00000008 */ +#define GPIO_LCKR_LCK3 GPIO_LCKR_LCK3_Msk +#define GPIO_LCKR_LCK4_Pos (4U) +#define GPIO_LCKR_LCK4_Msk (0x1UL << GPIO_LCKR_LCK4_Pos) /*!< 0x00000010 */ +#define GPIO_LCKR_LCK4 GPIO_LCKR_LCK4_Msk +#define GPIO_LCKR_LCK5_Pos (5U) +#define GPIO_LCKR_LCK5_Msk (0x1UL << GPIO_LCKR_LCK5_Pos) /*!< 0x00000020 */ +#define GPIO_LCKR_LCK5 GPIO_LCKR_LCK5_Msk +#define GPIO_LCKR_LCK6_Pos (6U) +#define GPIO_LCKR_LCK6_Msk (0x1UL << GPIO_LCKR_LCK6_Pos) /*!< 0x00000040 */ +#define GPIO_LCKR_LCK6 GPIO_LCKR_LCK6_Msk +#define GPIO_LCKR_LCK7_Pos (7U) +#define GPIO_LCKR_LCK7_Msk (0x1UL << GPIO_LCKR_LCK7_Pos) /*!< 0x00000080 */ +#define GPIO_LCKR_LCK7 GPIO_LCKR_LCK7_Msk +#define GPIO_LCKR_LCK8_Pos (8U) +#define GPIO_LCKR_LCK8_Msk (0x1UL << GPIO_LCKR_LCK8_Pos) /*!< 0x00000100 */ +#define GPIO_LCKR_LCK8 GPIO_LCKR_LCK8_Msk +#define GPIO_LCKR_LCK9_Pos (9U) +#define GPIO_LCKR_LCK9_Msk (0x1UL << GPIO_LCKR_LCK9_Pos) /*!< 0x00000200 */ +#define GPIO_LCKR_LCK9 GPIO_LCKR_LCK9_Msk +#define GPIO_LCKR_LCK10_Pos (10U) +#define GPIO_LCKR_LCK10_Msk (0x1UL << GPIO_LCKR_LCK10_Pos) /*!< 0x00000400 */ +#define GPIO_LCKR_LCK10 GPIO_LCKR_LCK10_Msk +#define GPIO_LCKR_LCK11_Pos (11U) +#define GPIO_LCKR_LCK11_Msk (0x1UL << GPIO_LCKR_LCK11_Pos) /*!< 0x00000800 */ +#define GPIO_LCKR_LCK11 GPIO_LCKR_LCK11_Msk +#define GPIO_LCKR_LCK12_Pos (12U) +#define GPIO_LCKR_LCK12_Msk (0x1UL << GPIO_LCKR_LCK12_Pos) /*!< 0x00001000 */ +#define GPIO_LCKR_LCK12 GPIO_LCKR_LCK12_Msk +#define GPIO_LCKR_LCK13_Pos (13U) +#define GPIO_LCKR_LCK13_Msk (0x1UL << GPIO_LCKR_LCK13_Pos) /*!< 0x00002000 */ +#define GPIO_LCKR_LCK13 GPIO_LCKR_LCK13_Msk +#define GPIO_LCKR_LCK14_Pos (14U) +#define GPIO_LCKR_LCK14_Msk (0x1UL << GPIO_LCKR_LCK14_Pos) /*!< 0x00004000 */ +#define GPIO_LCKR_LCK14 GPIO_LCKR_LCK14_Msk +#define GPIO_LCKR_LCK15_Pos (15U) +#define GPIO_LCKR_LCK15_Msk (0x1UL << GPIO_LCKR_LCK15_Pos) /*!< 0x00008000 */ +#define GPIO_LCKR_LCK15 GPIO_LCKR_LCK15_Msk +#define GPIO_LCKR_LCKK_Pos (16U) +#define GPIO_LCKR_LCKK_Msk (0x1UL << GPIO_LCKR_LCKK_Pos) /*!< 0x00010000 */ +#define GPIO_LCKR_LCKK GPIO_LCKR_LCKK_Msk + +/****************** Bit definition for GPIO_AFRL register *********************/ +#define GPIO_AFRL_AFSEL0_Pos (0U) +#define GPIO_AFRL_AFSEL0_Msk (0xFUL << GPIO_AFRL_AFSEL0_Pos) /*!< 0x0000000F */ +#define GPIO_AFRL_AFSEL0 GPIO_AFRL_AFSEL0_Msk +#define GPIO_AFRL_AFSEL0_0 (0x1UL << GPIO_AFRL_AFSEL0_Pos) /*!< 0x00000001 */ +#define GPIO_AFRL_AFSEL0_1 (0x2UL << GPIO_AFRL_AFSEL0_Pos) /*!< 0x00000002 */ +#define GPIO_AFRL_AFSEL0_2 (0x4UL << GPIO_AFRL_AFSEL0_Pos) /*!< 0x00000004 */ +#define GPIO_AFRL_AFSEL0_3 (0x8UL << GPIO_AFRL_AFSEL0_Pos) /*!< 0x00000008 */ +#define GPIO_AFRL_AFSEL1_Pos (4U) +#define GPIO_AFRL_AFSEL1_Msk (0xFUL << GPIO_AFRL_AFSEL1_Pos) /*!< 0x000000F0 */ +#define GPIO_AFRL_AFSEL1 GPIO_AFRL_AFSEL1_Msk +#define GPIO_AFRL_AFSEL1_0 (0x1UL << GPIO_AFRL_AFSEL1_Pos) /*!< 0x00000010 */ +#define GPIO_AFRL_AFSEL1_1 (0x2UL << GPIO_AFRL_AFSEL1_Pos) /*!< 0x00000020 */ +#define GPIO_AFRL_AFSEL1_2 (0x4UL << GPIO_AFRL_AFSEL1_Pos) /*!< 0x00000040 */ +#define GPIO_AFRL_AFSEL1_3 (0x8UL << GPIO_AFRL_AFSEL1_Pos) /*!< 0x00000080 */ +#define GPIO_AFRL_AFSEL2_Pos (8U) +#define GPIO_AFRL_AFSEL2_Msk (0xFUL << GPIO_AFRL_AFSEL2_Pos) /*!< 0x00000F00 */ +#define GPIO_AFRL_AFSEL2 GPIO_AFRL_AFSEL2_Msk +#define GPIO_AFRL_AFSEL2_0 (0x1UL << GPIO_AFRL_AFSEL2_Pos) /*!< 0x00000100 */ +#define GPIO_AFRL_AFSEL2_1 (0x2UL << GPIO_AFRL_AFSEL2_Pos) /*!< 0x00000200 */ +#define GPIO_AFRL_AFSEL2_2 (0x4UL << GPIO_AFRL_AFSEL2_Pos) /*!< 0x00000400 */ +#define GPIO_AFRL_AFSEL2_3 (0x8UL << GPIO_AFRL_AFSEL2_Pos) /*!< 0x00000800 */ +#define GPIO_AFRL_AFSEL3_Pos (12U) +#define GPIO_AFRL_AFSEL3_Msk (0xFUL << GPIO_AFRL_AFSEL3_Pos) /*!< 0x0000F000 */ +#define GPIO_AFRL_AFSEL3 GPIO_AFRL_AFSEL3_Msk +#define GPIO_AFRL_AFSEL3_0 (0x1UL << GPIO_AFRL_AFSEL3_Pos) /*!< 0x00001000 */ +#define GPIO_AFRL_AFSEL3_1 (0x2UL << GPIO_AFRL_AFSEL3_Pos) /*!< 0x00002000 */ +#define GPIO_AFRL_AFSEL3_2 (0x4UL << GPIO_AFRL_AFSEL3_Pos) /*!< 0x00004000 */ +#define GPIO_AFRL_AFSEL3_3 (0x8UL << GPIO_AFRL_AFSEL3_Pos) /*!< 0x00008000 */ +#define GPIO_AFRL_AFSEL4_Pos (16U) +#define GPIO_AFRL_AFSEL4_Msk (0xFUL << GPIO_AFRL_AFSEL4_Pos) /*!< 0x000F0000 */ +#define GPIO_AFRL_AFSEL4 GPIO_AFRL_AFSEL4_Msk +#define GPIO_AFRL_AFSEL4_0 (0x1UL << GPIO_AFRL_AFSEL4_Pos) /*!< 0x00010000 */ +#define GPIO_AFRL_AFSEL4_1 (0x2UL << GPIO_AFRL_AFSEL4_Pos) /*!< 0x00020000 */ +#define GPIO_AFRL_AFSEL4_2 (0x4UL << GPIO_AFRL_AFSEL4_Pos) /*!< 0x00040000 */ +#define GPIO_AFRL_AFSEL4_3 (0x8UL << GPIO_AFRL_AFSEL4_Pos) /*!< 0x00080000 */ +#define GPIO_AFRL_AFSEL5_Pos (20U) +#define GPIO_AFRL_AFSEL5_Msk (0xFUL << GPIO_AFRL_AFSEL5_Pos) /*!< 0x00F00000 */ +#define GPIO_AFRL_AFSEL5 GPIO_AFRL_AFSEL5_Msk +#define GPIO_AFRL_AFSEL5_0 (0x1UL << GPIO_AFRL_AFSEL5_Pos) /*!< 0x00100000 */ +#define GPIO_AFRL_AFSEL5_1 (0x2UL << GPIO_AFRL_AFSEL5_Pos) /*!< 0x00200000 */ +#define GPIO_AFRL_AFSEL5_2 (0x4UL << GPIO_AFRL_AFSEL5_Pos) /*!< 0x00400000 */ +#define GPIO_AFRL_AFSEL5_3 (0x8UL << GPIO_AFRL_AFSEL5_Pos) /*!< 0x00800000 */ +#define GPIO_AFRL_AFSEL6_Pos (24U) +#define GPIO_AFRL_AFSEL6_Msk (0xFUL << GPIO_AFRL_AFSEL6_Pos) /*!< 0x0F000000 */ +#define GPIO_AFRL_AFSEL6 GPIO_AFRL_AFSEL6_Msk +#define GPIO_AFRL_AFSEL6_0 (0x1UL << GPIO_AFRL_AFSEL6_Pos) /*!< 0x01000000 */ +#define GPIO_AFRL_AFSEL6_1 (0x2UL << GPIO_AFRL_AFSEL6_Pos) /*!< 0x02000000 */ +#define GPIO_AFRL_AFSEL6_2 (0x4UL << GPIO_AFRL_AFSEL6_Pos) /*!< 0x04000000 */ +#define GPIO_AFRL_AFSEL6_3 (0x8UL << GPIO_AFRL_AFSEL6_Pos) /*!< 0x08000000 */ +#define GPIO_AFRL_AFSEL7_Pos (28U) +#define GPIO_AFRL_AFSEL7_Msk (0xFUL << GPIO_AFRL_AFSEL7_Pos) /*!< 0xF0000000 */ +#define GPIO_AFRL_AFSEL7 GPIO_AFRL_AFSEL7_Msk +#define GPIO_AFRL_AFSEL7_0 (0x1UL << GPIO_AFRL_AFSEL7_Pos) /*!< 0x10000000 */ +#define GPIO_AFRL_AFSEL7_1 (0x2UL << GPIO_AFRL_AFSEL7_Pos) /*!< 0x20000000 */ +#define GPIO_AFRL_AFSEL7_2 (0x4UL << GPIO_AFRL_AFSEL7_Pos) /*!< 0x40000000 */ +#define GPIO_AFRL_AFSEL7_3 (0x8UL << GPIO_AFRL_AFSEL7_Pos) /*!< 0x80000000 */ + +/****************** Bit definition for GPIO_AFRH register *********************/ +#define GPIO_AFRH_AFSEL8_Pos (0U) +#define GPIO_AFRH_AFSEL8_Msk (0xFUL << GPIO_AFRH_AFSEL8_Pos) /*!< 0x0000000F */ +#define GPIO_AFRH_AFSEL8 GPIO_AFRH_AFSEL8_Msk +#define GPIO_AFRH_AFSEL8_0 (0x1UL << GPIO_AFRH_AFSEL8_Pos) /*!< 0x00000001 */ +#define GPIO_AFRH_AFSEL8_1 (0x2UL << GPIO_AFRH_AFSEL8_Pos) /*!< 0x00000002 */ +#define GPIO_AFRH_AFSEL8_2 (0x4UL << GPIO_AFRH_AFSEL8_Pos) /*!< 0x00000004 */ +#define GPIO_AFRH_AFSEL8_3 (0x8UL << GPIO_AFRH_AFSEL8_Pos) /*!< 0x00000008 */ +#define GPIO_AFRH_AFSEL9_Pos (4U) +#define GPIO_AFRH_AFSEL9_Msk (0xFUL << GPIO_AFRH_AFSEL9_Pos) /*!< 0x000000F0 */ +#define GPIO_AFRH_AFSEL9 GPIO_AFRH_AFSEL9_Msk +#define GPIO_AFRH_AFSEL9_0 (0x1UL << GPIO_AFRH_AFSEL9_Pos) /*!< 0x00000010 */ +#define GPIO_AFRH_AFSEL9_1 (0x2UL << GPIO_AFRH_AFSEL9_Pos) /*!< 0x00000020 */ +#define GPIO_AFRH_AFSEL9_2 (0x4UL << GPIO_AFRH_AFSEL9_Pos) /*!< 0x00000040 */ +#define GPIO_AFRH_AFSEL9_3 (0x8UL << GPIO_AFRH_AFSEL9_Pos) /*!< 0x00000080 */ +#define GPIO_AFRH_AFSEL10_Pos (8U) +#define GPIO_AFRH_AFSEL10_Msk (0xFUL << GPIO_AFRH_AFSEL10_Pos) /*!< 0x00000F00 */ +#define GPIO_AFRH_AFSEL10 GPIO_AFRH_AFSEL10_Msk +#define GPIO_AFRH_AFSEL10_0 (0x1UL << GPIO_AFRH_AFSEL10_Pos) /*!< 0x00000100 */ +#define GPIO_AFRH_AFSEL10_1 (0x2UL << GPIO_AFRH_AFSEL10_Pos) /*!< 0x00000200 */ +#define GPIO_AFRH_AFSEL10_2 (0x4UL << GPIO_AFRH_AFSEL10_Pos) /*!< 0x00000400 */ +#define GPIO_AFRH_AFSEL10_3 (0x8UL << GPIO_AFRH_AFSEL10_Pos) /*!< 0x00000800 */ +#define GPIO_AFRH_AFSEL11_Pos (12U) +#define GPIO_AFRH_AFSEL11_Msk (0xFUL << GPIO_AFRH_AFSEL11_Pos) /*!< 0x0000F000 */ +#define GPIO_AFRH_AFSEL11 GPIO_AFRH_AFSEL11_Msk +#define GPIO_AFRH_AFSEL11_0 (0x1UL << GPIO_AFRH_AFSEL11_Pos) /*!< 0x00001000 */ +#define GPIO_AFRH_AFSEL11_1 (0x2UL << GPIO_AFRH_AFSEL11_Pos) /*!< 0x00002000 */ +#define GPIO_AFRH_AFSEL11_2 (0x4UL << GPIO_AFRH_AFSEL11_Pos) /*!< 0x00004000 */ +#define GPIO_AFRH_AFSEL11_3 (0x8UL << GPIO_AFRH_AFSEL11_Pos) /*!< 0x00008000 */ +#define GPIO_AFRH_AFSEL12_Pos (16U) +#define GPIO_AFRH_AFSEL12_Msk (0xFUL << GPIO_AFRH_AFSEL12_Pos) /*!< 0x000F0000 */ +#define GPIO_AFRH_AFSEL12 GPIO_AFRH_AFSEL12_Msk +#define GPIO_AFRH_AFSEL12_0 (0x1UL << GPIO_AFRH_AFSEL12_Pos) /*!< 0x00010000 */ +#define GPIO_AFRH_AFSEL12_1 (0x2UL << GPIO_AFRH_AFSEL12_Pos) /*!< 0x00020000 */ +#define GPIO_AFRH_AFSEL12_2 (0x4UL << GPIO_AFRH_AFSEL12_Pos) /*!< 0x00040000 */ +#define GPIO_AFRH_AFSEL12_3 (0x8UL << GPIO_AFRH_AFSEL12_Pos) /*!< 0x00080000 */ +#define GPIO_AFRH_AFSEL13_Pos (20U) +#define GPIO_AFRH_AFSEL13_Msk (0xFUL << GPIO_AFRH_AFSEL13_Pos) /*!< 0x00F00000 */ +#define GPIO_AFRH_AFSEL13 GPIO_AFRH_AFSEL13_Msk +#define GPIO_AFRH_AFSEL13_0 (0x1UL << GPIO_AFRH_AFSEL13_Pos) /*!< 0x00100000 */ +#define GPIO_AFRH_AFSEL13_1 (0x2UL << GPIO_AFRH_AFSEL13_Pos) /*!< 0x00200000 */ +#define GPIO_AFRH_AFSEL13_2 (0x4UL << GPIO_AFRH_AFSEL13_Pos) /*!< 0x00400000 */ +#define GPIO_AFRH_AFSEL13_3 (0x8UL << GPIO_AFRH_AFSEL13_Pos) /*!< 0x00800000 */ +#define GPIO_AFRH_AFSEL14_Pos (24U) +#define GPIO_AFRH_AFSEL14_Msk (0xFUL << GPIO_AFRH_AFSEL14_Pos) /*!< 0x0F000000 */ +#define GPIO_AFRH_AFSEL14 GPIO_AFRH_AFSEL14_Msk +#define GPIO_AFRH_AFSEL14_0 (0x1UL << GPIO_AFRH_AFSEL14_Pos) /*!< 0x01000000 */ +#define GPIO_AFRH_AFSEL14_1 (0x2UL << GPIO_AFRH_AFSEL14_Pos) /*!< 0x02000000 */ +#define GPIO_AFRH_AFSEL14_2 (0x4UL << GPIO_AFRH_AFSEL14_Pos) /*!< 0x04000000 */ +#define GPIO_AFRH_AFSEL14_3 (0x8UL << GPIO_AFRH_AFSEL14_Pos) /*!< 0x08000000 */ +#define GPIO_AFRH_AFSEL15_Pos (28U) +#define GPIO_AFRH_AFSEL15_Msk (0xFUL << GPIO_AFRH_AFSEL15_Pos) /*!< 0xF0000000 */ +#define GPIO_AFRH_AFSEL15 GPIO_AFRH_AFSEL15_Msk +#define GPIO_AFRH_AFSEL15_0 (0x1UL << GPIO_AFRH_AFSEL15_Pos) /*!< 0x10000000 */ +#define GPIO_AFRH_AFSEL15_1 (0x2UL << GPIO_AFRH_AFSEL15_Pos) /*!< 0x20000000 */ +#define GPIO_AFRH_AFSEL15_2 (0x4UL << GPIO_AFRH_AFSEL15_Pos) /*!< 0x40000000 */ +#define GPIO_AFRH_AFSEL15_3 (0x8UL << GPIO_AFRH_AFSEL15_Pos) /*!< 0x80000000 */ + +/****************** Bits definition for GPIO_BRR register ******************/ +#define GPIO_BRR_BR0_Pos (0U) +#define GPIO_BRR_BR0_Msk (0x1UL << GPIO_BRR_BR0_Pos) /*!< 0x00000001 */ +#define GPIO_BRR_BR0 GPIO_BRR_BR0_Msk +#define GPIO_BRR_BR1_Pos (1U) +#define GPIO_BRR_BR1_Msk (0x1UL << GPIO_BRR_BR1_Pos) /*!< 0x00000002 */ +#define GPIO_BRR_BR1 GPIO_BRR_BR1_Msk +#define GPIO_BRR_BR2_Pos (2U) +#define GPIO_BRR_BR2_Msk (0x1UL << GPIO_BRR_BR2_Pos) /*!< 0x00000004 */ +#define GPIO_BRR_BR2 GPIO_BRR_BR2_Msk +#define GPIO_BRR_BR3_Pos (3U) +#define GPIO_BRR_BR3_Msk (0x1UL << GPIO_BRR_BR3_Pos) /*!< 0x00000008 */ +#define GPIO_BRR_BR3 GPIO_BRR_BR3_Msk +#define GPIO_BRR_BR4_Pos (4U) +#define GPIO_BRR_BR4_Msk (0x1UL << GPIO_BRR_BR4_Pos) /*!< 0x00000010 */ +#define GPIO_BRR_BR4 GPIO_BRR_BR4_Msk +#define GPIO_BRR_BR5_Pos (5U) +#define GPIO_BRR_BR5_Msk (0x1UL << GPIO_BRR_BR5_Pos) /*!< 0x00000020 */ +#define GPIO_BRR_BR5 GPIO_BRR_BR5_Msk +#define GPIO_BRR_BR6_Pos (6U) +#define GPIO_BRR_BR6_Msk (0x1UL << GPIO_BRR_BR6_Pos) /*!< 0x00000040 */ +#define GPIO_BRR_BR6 GPIO_BRR_BR6_Msk +#define GPIO_BRR_BR7_Pos (7U) +#define GPIO_BRR_BR7_Msk (0x1UL << GPIO_BRR_BR7_Pos) /*!< 0x00000080 */ +#define GPIO_BRR_BR7 GPIO_BRR_BR7_Msk +#define GPIO_BRR_BR8_Pos (8U) +#define GPIO_BRR_BR8_Msk (0x1UL << GPIO_BRR_BR8_Pos) /*!< 0x00000100 */ +#define GPIO_BRR_BR8 GPIO_BRR_BR8_Msk +#define GPIO_BRR_BR9_Pos (9U) +#define GPIO_BRR_BR9_Msk (0x1UL << GPIO_BRR_BR9_Pos) /*!< 0x00000200 */ +#define GPIO_BRR_BR9 GPIO_BRR_BR9_Msk +#define GPIO_BRR_BR10_Pos (10U) +#define GPIO_BRR_BR10_Msk (0x1UL << GPIO_BRR_BR10_Pos) /*!< 0x00000400 */ +#define GPIO_BRR_BR10 GPIO_BRR_BR10_Msk +#define GPIO_BRR_BR11_Pos (11U) +#define GPIO_BRR_BR11_Msk (0x1UL << GPIO_BRR_BR11_Pos) /*!< 0x00000800 */ +#define GPIO_BRR_BR11 GPIO_BRR_BR11_Msk +#define GPIO_BRR_BR12_Pos (12U) +#define GPIO_BRR_BR12_Msk (0x1UL << GPIO_BRR_BR12_Pos) /*!< 0x00001000 */ +#define GPIO_BRR_BR12 GPIO_BRR_BR12_Msk +#define GPIO_BRR_BR13_Pos (13U) +#define GPIO_BRR_BR13_Msk (0x1UL << GPIO_BRR_BR13_Pos) /*!< 0x00002000 */ +#define GPIO_BRR_BR13 GPIO_BRR_BR13_Msk +#define GPIO_BRR_BR14_Pos (14U) +#define GPIO_BRR_BR14_Msk (0x1UL << GPIO_BRR_BR14_Pos) /*!< 0x00004000 */ +#define GPIO_BRR_BR14 GPIO_BRR_BR14_Msk +#define GPIO_BRR_BR15_Pos (15U) +#define GPIO_BRR_BR15_Msk (0x1UL << GPIO_BRR_BR15_Pos) /*!< 0x00008000 */ +#define GPIO_BRR_BR15 GPIO_BRR_BR15_Msk + +/****************** Bits definition for GPIO_HSLVR register ******************/ +#define GPIO_HSLVR_HSLV0_Pos (0U) +#define GPIO_HSLVR_HSLV0_Msk (0x1UL << GPIO_HSLVR_HSLV0_Pos) /*!< 0x00000001 */ +#define GPIO_HSLVR_HSLV0 GPIO_HSLVR_HSLV0_Msk +#define GPIO_HSLVR_HSLV1_Pos (1U) +#define GPIO_HSLVR_HSLV1_Msk (0x1UL << GPIO_HSLVR_HSLV1_Pos) /*!< 0x00000002 */ +#define GPIO_HSLVR_HSLV1 GPIO_HSLVR_HSLV1_Msk +#define GPIO_HSLVR_HSLV2_Pos (2U) +#define GPIO_HSLVR_HSLV2_Msk (0x1UL << GPIO_HSLVR_HSLV2_Pos) /*!< 0x00000004 */ +#define GPIO_HSLVR_HSLV2 GPIO_HSLVR_HSLV2_Msk +#define GPIO_HSLVR_HSLV3_Pos (3U) +#define GPIO_HSLVR_HSLV3_Msk (0x1UL << GPIO_HSLVR_HSLV3_Pos) /*!< 0x00000008 */ +#define GPIO_HSLVR_HSLV3 GPIO_HSLVR_HSLV3_Msk +#define GPIO_HSLVR_HSLV4_Pos (4U) +#define GPIO_HSLVR_HSLV4_Msk (0x1UL << GPIO_HSLVR_HSLV4_Pos) /*!< 0x00000010 */ +#define GPIO_HSLVR_HSLV4 GPIO_HSLVR_HSLV4_Msk +#define GPIO_HSLVR_HSLV5_Pos (5U) +#define GPIO_HSLVR_HSLV5_Msk (0x1UL << GPIO_HSLVR_HSLV5_Pos) /*!< 0x00000020 */ +#define GPIO_HSLVR_HSLV5 GPIO_HSLVR_HSLV5_Msk +#define GPIO_HSLVR_HSLV6_Pos (6U) +#define GPIO_HSLVR_HSLV6_Msk (0x1UL << GPIO_HSLVR_HSLV6_Pos) /*!< 0x00000040 */ +#define GPIO_HSLVR_HSLV6 GPIO_HSLVR_HSLV6_Msk +#define GPIO_HSLVR_HSLV7_Pos (7U) +#define GPIO_HSLVR_HSLV7_Msk (0x1UL << GPIO_HSLVR_HSLV7_Pos) /*!< 0x00000080 */ +#define GPIO_HSLVR_HSLV7 GPIO_HSLVR_HSLV7_Msk +#define GPIO_HSLVR_HSLV8_Pos (8U) +#define GPIO_HSLVR_HSLV8_Msk (0x1UL << GPIO_HSLVR_HSLV8_Pos) /*!< 0x00000100 */ +#define GPIO_HSLVR_HSLV8 GPIO_HSLVR_HSLV8_Msk +#define GPIO_HSLVR_HSLV9_Pos (9U) +#define GPIO_HSLVR_HSLV9_Msk (0x1UL << GPIO_HSLVR_HSLV9_Pos) /*!< 0x00000200 */ +#define GPIO_HSLVR_HSLV9 GPIO_HSLVR_HSLV9_Msk +#define GPIO_HSLVR_HSLV10_Pos (10U) +#define GPIO_HSLVR_HSLV10_Msk (0x1UL << GPIO_HSLVR_HSLV10_Pos) /*!< 0x00000400 */ +#define GPIO_HSLVR_HSLV10 GPIO_HSLVR_HSLV10_Msk +#define GPIO_HSLVR_HSLV11_Pos (11U) +#define GPIO_HSLVR_HSLV11_Msk (x1UL << GPIO_HSLVR_HSLV11_Pos) /*!< 0x00000800 */ +#define GPIO_HSLVR_HSLV11 GPIO_HSLVR_HSLV11_Msk +#define GPIO_HSLVR_HSLV12_Pos (12U) +#define GPIO_HSLVR_HSLV12_Msk (0x1UL << GPIO_HSLVR_HSLV12_Pos) /*!< 0x00001000 */ +#define GPIO_HSLVR_HSLV12 GPIO_HSLVR_HSLV12_Msk +#define GPIO_HSLVR_HSLV13_Pos (13U) +#define GPIO_HSLVR_HSLV13_Msk (0x1UL << GPIO_HSLVR_HSLV13_Pos) /*!< 0x00002000 */ +#define GPIO_HSLVR_HSLV13 GPIO_HSLVR_HSLV13_Msk +#define GPIO_HSLVR_HSLV14_Pos (14U) +#define GPIO_HSLVR_HSLV14_Msk (0x1UL << GPIO_HSLVR_HSLV14_Pos) /*!< 0x00004000 */ +#define GPIO_HSLVR_HSLV14 GPIO_HSLVR_HSLV14_Msk +#define GPIO_HSLVR_HSLV15_Pos (15U) +#define GPIO_HSLVR_HSLV15_Msk (0x1UL << GPIO_HSLVR_HSLV15_Pos) /*!< 0x00008000 */ +#define GPIO_HSLVR_HSLV15 GPIO_HSLVR_HSLV15_Msk + +/****************** Bits definition for GPIO_SECCFGR register ******************/ +#define GPIO_SECCFGR_SEC0_Pos (0U) +#define GPIO_SECCFGR_SEC0_Msk (0x1UL << GPIO_SECCFGR_SEC0_Pos) /*!< 0x00000001 */ +#define GPIO_SECCFGR_SEC0 GPIO_SECCFGR_SEC0_Msk +#define GPIO_SECCFGR_SEC1_Pos (1U) +#define GPIO_SECCFGR_SEC1_Msk (0x1UL << GPIO_SECCFGR_SEC1_Pos) /*!< 0x00000002 */ +#define GPIO_SECCFGR_SEC1 GPIO_SECCFGR_SEC1_Msk +#define GPIO_SECCFGR_SEC2_Pos (2U) +#define GPIO_SECCFGR_SEC2_Msk (0x1UL << GPIO_SECCFGR_SEC2_Pos) /*!< 0x00000004 */ +#define GPIO_SECCFGR_SEC2 GPIO_SECCFGR_SEC2_Msk +#define GPIO_SECCFGR_SEC3_Pos (3U) +#define GPIO_SECCFGR_SEC3_Msk (0x1UL << GPIO_SECCFGR_SEC3_Pos) /*!< 0x00000008 */ +#define GPIO_SECCFGR_SEC3 GPIO_SECCFGR_SEC3_Msk +#define GPIO_SECCFGR_SEC4_Pos (4U) +#define GPIO_SECCFGR_SEC4_Msk (0x1UL << GPIO_SECCFGR_SEC4_Pos) /*!< 0x00000010 */ +#define GPIO_SECCFGR_SEC4 GPIO_SECCFGR_SEC4_Msk +#define GPIO_SECCFGR_SEC5_Pos (5U) +#define GPIO_SECCFGR_SEC5_Msk (0x1UL << GPIO_SECCFGR_SEC5_Pos) /*!< 0x00000020 */ +#define GPIO_SECCFGR_SEC5 GPIO_SECCFGR_SEC5_Msk +#define GPIO_SECCFGR_SEC6_Pos (6U) +#define GPIO_SECCFGR_SEC6_Msk (0x1UL << GPIO_SECCFGR_SEC6_Pos) /*!< 0x00000040 */ +#define GPIO_SECCFGR_SEC6 GPIO_SECCFGR_SEC6_Msk +#define GPIO_SECCFGR_SEC7_Pos (7U) +#define GPIO_SECCFGR_SEC7_Msk (0x1UL << GPIO_SECCFGR_SEC7_Pos) /*!< 0x00000080 */ +#define GPIO_SECCFGR_SEC7 GPIO_SECCFGR_SEC7_Msk +#define GPIO_SECCFGR_SEC8_Pos (8U) +#define GPIO_SECCFGR_SEC8_Msk (0x1UL << GPIO_SECCFGR_SEC8_Pos) /*!< 0x00000100 */ +#define GPIO_SECCFGR_SEC8 GPIO_SECCFGR_SEC8_Msk +#define GPIO_SECCFGR_SEC9_Pos (9U) +#define GPIO_SECCFGR_SEC9_Msk (0x1UL << GPIO_SECCFGR_SEC9_Pos) /*!< 0x00000200 */ +#define GPIO_SECCFGR_SEC9 GPIO_SECCFGR_SEC9_Msk +#define GPIO_SECCFGR_SEC10_Pos (10U) +#define GPIO_SECCFGR_SEC10_Msk (0x1UL << GPIO_SECCFGR_SEC10_Pos) /*!< 0x00000400 */ +#define GPIO_SECCFGR_SEC10 GPIO_SECCFGR_SEC10_Msk +#define GPIO_SECCFGR_SEC11_Pos (11U) +#define GPIO_SECCFGR_SEC11_Msk (x1UL << GPIO_SECCFGR_SEC11_Pos) /*!< 0x00000800 */ +#define GPIO_SECCFGR_SEC11 GPIO_SECCFGR_SEC11_Msk +#define GPIO_SECCFGR_SEC12_Pos (12U) +#define GPIO_SECCFGR_SEC12_Msk (0x1UL << GPIO_SECCFGR_SEC12_Pos) /*!< 0x00001000 */ +#define GPIO_SECCFGR_SEC12 GPIO_SECCFGR_SEC12_Msk +#define GPIO_SECCFGR_SEC13_Pos (13U) +#define GPIO_SECCFGR_SEC13_Msk (0x1UL << GPIO_SECCFGR_SEC13_Pos) /*!< 0x00002000 */ +#define GPIO_SECCFGR_SEC13 GPIO_SECCFGR_SEC13_Msk +#define GPIO_SECCFGR_SEC14_Pos (14U) +#define GPIO_SECCFGR_SEC14_Msk (0x1UL << GPIO_SECCFGR_SEC14_Pos) /*!< 0x00004000 */ +#define GPIO_SECCFGR_SEC14 GPIO_SECCFGR_SEC14_Msk +#define GPIO_SECCFGR_SEC15_Pos (15U) +#define GPIO_SECCFGR_SEC15_Msk (0x1UL << GPIO_SECCFGR_SEC15_Pos) /*!< 0x00008000 */ +#define GPIO_SECCFGR_SEC15 GPIO_SECCFGR_SEC15_Msk + +/******************************************************************************/ +/* */ +/* ICACHE */ +/* */ +/******************************************************************************/ +/****************** Bit definition for ICACHE_CR register *******************/ +#define ICACHE_CR_EN_Pos (0U) +#define ICACHE_CR_EN_Msk (0x1UL << ICACHE_CR_EN_Pos) /*!< 0x00000001 */ +#define ICACHE_CR_EN ICACHE_CR_EN_Msk /*!< Enable */ +#define ICACHE_CR_CACHEINV_Pos (1U) +#define ICACHE_CR_CACHEINV_Msk (0x1UL << ICACHE_CR_CACHEINV_Pos) /*!< 0x00000002 */ +#define ICACHE_CR_CACHEINV ICACHE_CR_CACHEINV_Msk /*!< Cache invalidation */ +#define ICACHE_CR_WAYSEL_Pos (2U) +#define ICACHE_CR_WAYSEL_Msk (0x1UL << ICACHE_CR_WAYSEL_Pos) /*!< 0x00000004 */ +#define ICACHE_CR_WAYSEL ICACHE_CR_WAYSEL_Msk /*!< Ways selection */ +#define ICACHE_CR_HITMEN_Pos (16U) +#define ICACHE_CR_HITMEN_Msk (0x1UL << ICACHE_CR_HITMEN_Pos) /*!< 0x00010000 */ +#define ICACHE_CR_HITMEN ICACHE_CR_HITMEN_Msk /*!< Hit monitor enable */ +#define ICACHE_CR_MISSMEN_Pos (17U) +#define ICACHE_CR_MISSMEN_Msk (0x1UL << ICACHE_CR_MISSMEN_Pos) /*!< 0x00020000 */ +#define ICACHE_CR_MISSMEN ICACHE_CR_MISSMEN_Msk /*!< Miss monitor enable */ +#define ICACHE_CR_HITMRST_Pos (18U) +#define ICACHE_CR_HITMRST_Msk (0x1UL << ICACHE_CR_HITMRST_Pos) /*!< 0x00040000 */ +#define ICACHE_CR_HITMRST ICACHE_CR_HITMRST_Msk /*!< Hit monitor reset */ +#define ICACHE_CR_MISSMRST_Pos (19U) +#define ICACHE_CR_MISSMRST_Msk (0x1UL << ICACHE_CR_MISSMRST_Pos) /*!< 0x00080000 */ +#define ICACHE_CR_MISSMRST ICACHE_CR_MISSMRST_Msk /*!< Miss monitor reset */ + +/****************** Bit definition for ICACHE_SR register *******************/ +#define ICACHE_SR_BUSYF_Pos (0U) +#define ICACHE_SR_BUSYF_Msk (0x1UL << ICACHE_SR_BUSYF_Pos) /*!< 0x00000001 */ +#define ICACHE_SR_BUSYF ICACHE_SR_BUSYF_Msk /*!< Busy flag */ +#define ICACHE_SR_BSYENDF_Pos (1U) +#define ICACHE_SR_BSYENDF_Msk (0x1UL << ICACHE_SR_BSYENDF_Pos) /*!< 0x00000002 */ +#define ICACHE_SR_BSYENDF ICACHE_SR_BSYENDF_Msk /*!< Busy end flag */ +#define ICACHE_SR_ERRF_Pos (2U) +#define ICACHE_SR_ERRF_Msk (0x1UL << ICACHE_SR_ERRF_Pos) /*!< 0x00000004 */ +#define ICACHE_SR_ERRF ICACHE_SR_ERRF_Msk /*!< Cache error flag */ + +/****************** Bit definition for ICACHE_IER register ******************/ +#define ICACHE_IER_BSYENDIE_Pos (1U) +#define ICACHE_IER_BSYENDIE_Msk (0x1UL << ICACHE_IER_BSYENDIE_Pos) /*!< 0x00000002 */ +#define ICACHE_IER_BSYENDIE ICACHE_IER_BSYENDIE_Msk /*!< Busy end interrupt enable */ +#define ICACHE_IER_ERRIE_Pos (2U) +#define ICACHE_IER_ERRIE_Msk (0x1UL << ICACHE_IER_ERRIE_Pos) /*!< 0x00000004 */ +#define ICACHE_IER_ERRIE ICACHE_IER_ERRIE_Msk /*!< Cache error interrupt enable */ + +/****************** Bit definition for ICACHE_FCR register ******************/ +#define ICACHE_FCR_CBSYENDF_Pos (1U) +#define ICACHE_FCR_CBSYENDF_Msk (0x1UL << ICACHE_FCR_CBSYENDF_Pos) /*!< 0x00000002 */ +#define ICACHE_FCR_CBSYENDF ICACHE_FCR_CBSYENDF_Msk /*!< Busy end flag clear */ +#define ICACHE_FCR_CERRF_Pos (2U) +#define ICACHE_FCR_CERRF_Msk (0x1UL << ICACHE_FCR_CERRF_Pos) /*!< 0x00000004 */ +#define ICACHE_FCR_CERRF ICACHE_FCR_CERRF_Msk /*!< Cache error flag clear */ + +/****************** Bit definition for ICACHE_HMONR register ****************/ +#define ICACHE_HMONR_HITMON_Pos (0U) +#define ICACHE_HMONR_HITMON_Msk (0xFFFFFFFFUL << ICACHE_HMONR_HITMON_Pos) /*!< 0xFFFFFFFF */ +#define ICACHE_HMONR_HITMON ICACHE_HMONR_HITMON_Msk /*!< Cache hit monitor register */ + +/****************** Bit definition for ICACHE_MMONR register ****************/ +#define ICACHE_MMONR_MISSMON_Pos (0U) +#define ICACHE_MMONR_MISSMON_Msk (0xFFFFUL << ICACHE_MMONR_MISSMON_Pos) /*!< 0x0000FFFF */ +#define ICACHE_MMONR_MISSMON ICACHE_MMONR_MISSMON_Msk /*!< Cache miss monitor register */ + + +/******************************************************************************/ +/* */ +/* Digital Temperature Sensor (DTS) */ +/* */ +/******************************************************************************/ + +/****************** Bit definition for DTS_CFGR1 register ******************/ +#define DTS_CFGR1_TS1_EN_Pos (0U) +#define DTS_CFGR1_TS1_EN_Msk (0x1UL << DTS_CFGR1_TS1_EN_Pos) /*!< 0x00000001 */ +#define DTS_CFGR1_TS1_EN DTS_CFGR1_TS1_EN_Msk /*!< DTS Enable */ +#define DTS_CFGR1_TS1_START_Pos (4U) +#define DTS_CFGR1_TS1_START_Msk (0x1UL << DTS_CFGR1_TS1_START_Pos) /*!< 0x00000010 */ +#define DTS_CFGR1_TS1_START DTS_CFGR1_TS1_START_Msk /*!< Proceed to a frequency measurement on DTS */ +#define DTS_CFGR1_TS1_INTRIG_SEL_Pos (8U) +#define DTS_CFGR1_TS1_INTRIG_SEL_Msk (0xFUL << DTS_CFGR1_TS1_INTRIG_SEL_Pos) /*!< 0x00000F00 */ +#define DTS_CFGR1_TS1_INTRIG_SEL DTS_CFGR1_TS1_INTRIG_SEL_Msk /*!< Input triggers selection bits [3:0] for DTS */ +#define DTS_CFGR1_TS1_INTRIG_SEL_0 (0x1UL << DTS_CFGR1_TS1_INTRIG_SEL_Pos) /*!< 0x00000100 */ +#define DTS_CFGR1_TS1_INTRIG_SEL_1 (0x2UL << DTS_CFGR1_TS1_INTRIG_SEL_Pos) /*!< 0x00000200 */ +#define DTS_CFGR1_TS1_INTRIG_SEL_2 (0x4UL << DTS_CFGR1_TS1_INTRIG_SEL_Pos) /*!< 0x00000400 */ +#define DTS_CFGR1_TS1_INTRIG_SEL_3 (0x8UL << DTS_CFGR1_TS1_INTRIG_SEL_Pos) /*!< 0x00000800 */ +#define DTS_CFGR1_TS1_SMP_TIME_Pos (16U) +#define DTS_CFGR1_TS1_SMP_TIME_Msk (0xFUL << DTS_CFGR1_TS1_SMP_TIME_Pos) /*!< 0x000F0000 */ +#define DTS_CFGR1_TS1_SMP_TIME DTS_CFGR1_TS1_SMP_TIME_Msk /*!< Sample time [3:0] for DTS */ +#define DTS_CFGR1_TS1_SMP_TIME_0 (0x1UL << DTS_CFGR1_TS1_SMP_TIME_Pos) /*!< 0x00010000 */ +#define DTS_CFGR1_TS1_SMP_TIME_1 (0x2UL << DTS_CFGR1_TS1_SMP_TIME_Pos) /*!< 0x00020000 */ +#define DTS_CFGR1_TS1_SMP_TIME_2 (0x4UL << DTS_CFGR1_TS1_SMP_TIME_Pos) /*!< 0x00040000 */ +#define DTS_CFGR1_TS1_SMP_TIME_3 (0x8UL << DTS_CFGR1_TS1_SMP_TIME_Pos) /*!< 0x00080000 */ +#define DTS_CFGR1_REFCLK_SEL_Pos (20U) +#define DTS_CFGR1_REFCLK_SEL_Msk (0x1UL << DTS_CFGR1_REFCLK_SEL_Pos) /*!< 0x00100000 */ +#define DTS_CFGR1_REFCLK_SEL DTS_CFGR1_REFCLK_SEL_Msk /*!< Reference Clock Selection */ +#define DTS_CFGR1_Q_MEAS_OPT_Pos (21U) +#define DTS_CFGR1_Q_MEAS_OPT_Msk (0x1UL << DTS_CFGR1_Q_MEAS_OPT_Pos) /*!< 0x00200000 */ +#define DTS_CFGR1_Q_MEAS_OPT DTS_CFGR1_Q_MEAS_OPT_Msk /*!< Quick measure option bit */ +#define DTS_CFGR1_HSREF_CLK_DIV_Pos (24U) +#define DTS_CFGR1_HSREF_CLK_DIV_Msk (0x7FUL << DTS_CFGR1_HSREF_CLK_DIV_Pos) /*!< 0x7F000000 */ +#define DTS_CFGR1_HSREF_CLK_DIV DTS_CFGR1_HSREF_CLK_DIV_Msk /*!< High Speed Clock Divider Ratio [6:0]*/ + +/****************** Bit definition for DTS_T0VALR1 register ******************/ +#define DTS_T0VALR1_TS1_FMT0_Pos (0U) +#define DTS_T0VALR1_TS1_FMT0_Msk (0xFFFFUL << DTS_T0VALR1_TS1_FMT0_Pos) /*!< 0x0000FFFF */ +#define DTS_T0VALR1_TS1_FMT0 DTS_T0VALR1_TS1_FMT0_Msk /*!< Engineering value of the measured frequency at T0 for DTS */ +#define DTS_T0VALR1_TS1_T0_Pos (16U) +#define DTS_T0VALR1_TS1_T0_Msk (0x3UL << DTS_T0VALR1_TS1_T0_Pos) /*!< 0x00030000 */ +#define DTS_T0VALR1_TS1_T0 DTS_T0VALR1_TS1_T0_Msk /*!< Engineering value of the DTSerature T0 for DTS */ + +/****************** Bit definition for DTS_RAMPVALR register ******************/ +#define DTS_RAMPVALR_TS1_RAMP_COEFF_Pos (0U) +#define DTS_RAMPVALR_TS1_RAMP_COEFF_Msk (0xFFFFUL << DTS_RAMPVALR_TS1_RAMP_COEFF_Pos) /*!< 0x0000FFFF */ +#define DTS_RAMPVALR_TS1_RAMP_COEFF DTS_RAMPVALR_TS1_RAMP_COEFF_Msk /*!< Engineering value of the ramp coefficient for DTS */ + +/****************** Bit definition for DTS_ITR1 register ******************/ +#define DTS_ITR1_TS1_LITTHD_Pos (0U) +#define DTS_ITR1_TS1_LITTHD_Msk (0xFFFFUL << DTS_ITR1_TS1_LITTHD_Pos) /*!< 0x0000FFFF */ +#define DTS_ITR1_TS1_LITTHD DTS_ITR1_TS1_LITTHD_Msk /*!< Low interrupt threshold[15:0] for DTS */ +#define DTS_ITR1_TS1_HITTHD_Pos (16U) +#define DTS_ITR1_TS1_HITTHD_Msk (0xFFFFUL << DTS_ITR1_TS1_HITTHD_Pos) /*!< 0xFFFF0000 */ +#define DTS_ITR1_TS1_HITTHD DTS_ITR1_TS1_HITTHD_Msk /*!< High interrupt threshold[15:0] for DTS */ + +/****************** Bit definition for DTS_DR register ******************/ +#define DTS_DR_TS1_MFREQ_Pos (0U) +#define DTS_DR_TS1_MFREQ_Msk (0xFFFFUL << DTS_DR_TS1_MFREQ_Pos) /*!< 0x0000FFFF */ +#define DTS_DR_TS1_MFREQ DTS_DR_TS1_MFREQ_Msk /*!< Measured Frequency[15:0] for DTS */ + +/****************** Bit definition for DTS_SR register ******************/ +#define DTS_SR_TS1_ITEF_Pos (0U) +#define DTS_SR_TS1_ITEF_Msk (0x1UL << DTS_SR_TS1_ITEF_Pos) /*!< 0x00000001 */ +#define DTS_SR_TS1_ITEF DTS_SR_TS1_ITEF_Msk /*!< Interrupt flag for end of measure for DTS */ +#define DTS_SR_TS1_ITLF_Pos (1U) +#define DTS_SR_TS1_ITLF_Msk (0x1UL << DTS_SR_TS1_ITLF_Pos) /*!< 0x00000002 */ +#define DTS_SR_TS1_ITLF DTS_SR_TS1_ITLF_Msk /*!< Interrupt flag for low threshold for DTS */ +#define DTS_SR_TS1_ITHF_Pos (2U) +#define DTS_SR_TS1_ITHF_Msk (0x1UL << DTS_SR_TS1_ITHF_Pos) /*!< 0x00000004 */ +#define DTS_SR_TS1_ITHF DTS_SR_TS1_ITHF_Msk /*!< Interrupt flag for high threshold for DTS */ +#define DTS_SR_TS1_AITEF_Pos (4U) +#define DTS_SR_TS1_AITEF_Msk (0x1UL << DTS_SR_TS1_AITEF_Pos) /*!< 0x00000010 */ +#define DTS_SR_TS1_AITEF DTS_SR_TS1_AITEF_Msk /*!< Asynchronous interrupt flag for end of measure for DTS */ +#define DTS_SR_TS1_AITLF_Pos (5U) +#define DTS_SR_TS1_AITLF_Msk (0x1UL << DTS_SR_TS1_AITLF_Pos) /*!< 0x00000020 */ +#define DTS_SR_TS1_AITLF DTS_SR_TS1_AITLF_Msk /*!< Asynchronous interrupt flag for low threshold for DTS */ +#define DTS_SR_TS1_AITHF_Pos (6U) +#define DTS_SR_TS1_AITHF_Msk (0x1UL << DTS_SR_TS1_AITHF_Pos) /*!< 0x00000040 */ +#define DTS_SR_TS1_AITHF DTS_SR_TS1_AITHF_Msk /*!< Asynchronous interrupt flag for high threshold for DTS */ +#define DTS_SR_TS1_RDY_Pos (15U) +#define DTS_SR_TS1_RDY_Msk (0x1UL << DTS_SR_TS1_RDY_Pos) /*!< 0x00008000 */ +#define DTS_SR_TS1_RDY DTS_SR_TS1_RDY_Msk /*!< DTS ready flag */ + +/****************** Bit definition for DTS_ITENR register ******************/ +#define DTS_ITENR_TS1_ITEEN_Pos (0U) +#define DTS_ITENR_TS1_ITEEN_Msk (0x1UL << DTS_ITENR_TS1_ITEEN_Pos) /*!< 0x00000001 */ +#define DTS_ITENR_TS1_ITEEN DTS_ITENR_TS1_ITEEN_Msk /*!< Enable interrupt flag for end of measure for DTS */ +#define DTS_ITENR_TS1_ITLEN_Pos (1U) +#define DTS_ITENR_TS1_ITLEN_Msk (0x1UL << DTS_ITENR_TS1_ITLEN_Pos) /*!< 0x00000002 */ +#define DTS_ITENR_TS1_ITLEN DTS_ITENR_TS1_ITLEN_Msk /*!< Enable interrupt flag for low threshold for DTS */ +#define DTS_ITENR_TS1_ITHEN_Pos (2U) +#define DTS_ITENR_TS1_ITHEN_Msk (0x1UL << DTS_ITENR_TS1_ITHEN_Pos) /*!< 0x00000004 */ +#define DTS_ITENR_TS1_ITHEN DTS_ITENR_TS1_ITHEN_Msk /*!< Enable interrupt flag for high threshold for DTS */ +#define DTS_ITENR_TS1_AITEEN_Pos (4U) +#define DTS_ITENR_TS1_AITEEN_Msk (0x1UL << DTS_ITENR_TS1_AITEEN_Pos) /*!< 0x00000010 */ +#define DTS_ITENR_TS1_AITEEN DTS_ITENR_TS1_AITEEN_Msk /*!< Enable asynchronous interrupt flag for end of measure for DTS */ +#define DTS_ITENR_TS1_AITLEN_Pos (5U) +#define DTS_ITENR_TS1_AITLEN_Msk (0x1UL << DTS_ITENR_TS1_AITLEN_Pos) /*!< 0x00000020 */ +#define DTS_ITENR_TS1_AITLEN DTS_ITENR_TS1_AITLEN_Msk /*!< Enable Asynchronous interrupt flag for low threshold for DTS */ +#define DTS_ITENR_TS1_AITHEN_Pos (6U) +#define DTS_ITENR_TS1_AITHEN_Msk (0x1UL << DTS_ITENR_TS1_AITHEN_Pos) /*!< 0x00000040 */ +#define DTS_ITENR_TS1_AITHEN DTS_ITENR_TS1_AITHEN_Msk /*!< Enable asynchronous interrupt flag for high threshold for DTS */ + +/****************** Bit definition for DTS_ICIFR register ******************/ +#define DTS_ICIFR_TS1_CITEF_Pos (0U) +#define DTS_ICIFR_TS1_CITEF_Msk (0x1UL << DTS_ICIFR_TS1_CITEF_Pos) /*!< 0x00000001 */ +#define DTS_ICIFR_TS1_CITEF DTS_ICIFR_TS1_CITEF_Msk /*!< Clear the IT flag for End Of Measure for DTS */ +#define DTS_ICIFR_TS1_CITLF_Pos (1U) +#define DTS_ICIFR_TS1_CITLF_Msk (0x1UL << DTS_ICIFR_TS1_CITLF_Pos) /*!< 0x00000002 */ +#define DTS_ICIFR_TS1_CITLF DTS_ICIFR_TS1_CITLF_Msk /*!< Clear the IT flag for low threshold for DTS */ +#define DTS_ICIFR_TS1_CITHF_Pos (2U) +#define DTS_ICIFR_TS1_CITHF_Msk (0x1UL << DTS_ICIFR_TS1_CITHF_Pos) /*!< 0x00000004 */ +#define DTS_ICIFR_TS1_CITHF DTS_ICIFR_TS1_CITHF_Msk /*!< Clear the IT flag for high threshold on DTS */ +#define DTS_ICIFR_TS1_CAITEF_Pos (4U) +#define DTS_ICIFR_TS1_CAITEF_Msk (0x1UL << DTS_ICIFR_TS1_CAITEF_Pos) /*!< 0x00000010 */ +#define DTS_ICIFR_TS1_CAITEF DTS_ICIFR_TS1_CAITEF_Msk /*!< Clear the asynchronous IT flag for End Of Measure for DTS */ +#define DTS_ICIFR_TS1_CAITLF_Pos (5U) +#define DTS_ICIFR_TS1_CAITLF_Msk (0x1UL << DTS_ICIFR_TS1_CAITLF_Pos) /*!< 0x00000020 */ +#define DTS_ICIFR_TS1_CAITLF DTS_ICIFR_TS1_CAITLF_Msk /*!< Clear the asynchronous IT flag for low threshold for DTS */ +#define DTS_ICIFR_TS1_CAITHF_Pos (6U) +#define DTS_ICIFR_TS1_CAITHF_Msk (0x1UL << DTS_ICIFR_TS1_CAITHF_Pos) /*!< 0x00000040 */ +#define DTS_ICIFR_TS1_CAITHF DTS_ICIFR_TS1_CAITHF_Msk /*!< Clear the asynchronous IT flag for high threshold on DTS */ + +/******************************************************************************/ +/* */ +/* TIM */ +/* */ +/******************************************************************************/ +/******************* Bit definition for TIM_CR1 register ********************/ +#define TIM_CR1_CEN_Pos (0U) +#define TIM_CR1_CEN_Msk (0x1UL << TIM_CR1_CEN_Pos) /*!< 0x00000001 */ +#define TIM_CR1_CEN TIM_CR1_CEN_Msk /*! */ + +/******************** Bits definition for RTC_ALRMAR register ***************/ +#define RTC_ALRMAR_SU_Pos (0U) +#define RTC_ALRMAR_SU_Msk (0xFUL << RTC_ALRMAR_SU_Pos) /*!< 0x0000000F */ +#define RTC_ALRMAR_SU RTC_ALRMAR_SU_Msk +#define RTC_ALRMAR_SU_0 (0x1UL << RTC_ALRMAR_SU_Pos) /*!< 0x00000001 */ +#define RTC_ALRMAR_SU_1 (0x2UL << RTC_ALRMAR_SU_Pos) /*!< 0x00000002 */ +#define RTC_ALRMAR_SU_2 (0x4UL << RTC_ALRMAR_SU_Pos) /*!< 0x00000004 */ +#define RTC_ALRMAR_SU_3 (0x8UL << RTC_ALRMAR_SU_Pos) /*!< 0x00000008 */ +#define RTC_ALRMAR_ST_Pos (4U) +#define RTC_ALRMAR_ST_Msk (0x7UL << RTC_ALRMAR_ST_Pos) /*!< 0x00000070 */ +#define RTC_ALRMAR_ST RTC_ALRMAR_ST_Msk +#define RTC_ALRMAR_ST_0 (0x1UL << RTC_ALRMAR_ST_Pos) /*!< 0x00000010 */ +#define RTC_ALRMAR_ST_1 (0x2UL << RTC_ALRMAR_ST_Pos) /*!< 0x00000020 */ +#define RTC_ALRMAR_ST_2 (0x4UL << RTC_ALRMAR_ST_Pos) /*!< 0x00000040 */ +#define RTC_ALRMAR_MSK1_Pos (7U) +#define RTC_ALRMAR_MSK1_Msk (0x1UL << RTC_ALRMAR_MSK1_Pos) /*!< 0x00000080 */ +#define RTC_ALRMAR_MSK1 RTC_ALRMAR_MSK1_Msk +#define RTC_ALRMAR_MNU_Pos (8U) +#define RTC_ALRMAR_MNU_Msk (0xFUL << RTC_ALRMAR_MNU_Pos) /*!< 0x00000F00 */ +#define RTC_ALRMAR_MNU RTC_ALRMAR_MNU_Msk +#define RTC_ALRMAR_MNU_0 (0x1UL << RTC_ALRMAR_MNU_Pos) /*!< 0x00000100 */ +#define RTC_ALRMAR_MNU_1 (0x2UL << RTC_ALRMAR_MNU_Pos) /*!< 0x00000200 */ +#define RTC_ALRMAR_MNU_2 (0x4UL << RTC_ALRMAR_MNU_Pos) /*!< 0x00000400 */ +#define RTC_ALRMAR_MNU_3 (0x8UL << RTC_ALRMAR_MNU_Pos) /*!< 0x00000800 */ +#define RTC_ALRMAR_MNT_Pos (12U) +#define RTC_ALRMAR_MNT_Msk (0x7UL << RTC_ALRMAR_MNT_Pos) /*!< 0x00007000 */ +#define RTC_ALRMAR_MNT RTC_ALRMAR_MNT_Msk +#define RTC_ALRMAR_MNT_0 (0x1UL << RTC_ALRMAR_MNT_Pos) /*!< 0x00001000 */ +#define RTC_ALRMAR_MNT_1 (0x2UL << RTC_ALRMAR_MNT_Pos) /*!< 0x00002000 */ +#define RTC_ALRMAR_MNT_2 (0x4UL << RTC_ALRMAR_MNT_Pos) /*!< 0x00004000 */ +#define RTC_ALRMAR_MSK2_Pos (15U) +#define RTC_ALRMAR_MSK2_Msk (0x1UL << RTC_ALRMAR_MSK2_Pos) /*!< 0x00008000 */ +#define RTC_ALRMAR_MSK2 RTC_ALRMAR_MSK2_Msk +#define RTC_ALRMAR_HU_Pos (16U) +#define RTC_ALRMAR_HU_Msk (0xFUL << RTC_ALRMAR_HU_Pos) /*!< 0x000F0000 */ +#define RTC_ALRMAR_HU RTC_ALRMAR_HU_Msk +#define RTC_ALRMAR_HU_0 (0x1UL << RTC_ALRMAR_HU_Pos) /*!< 0x00010000 */ +#define RTC_ALRMAR_HU_1 (0x2UL << RTC_ALRMAR_HU_Pos) /*!< 0x00020000 */ +#define RTC_ALRMAR_HU_2 (0x4UL << RTC_ALRMAR_HU_Pos) /*!< 0x00040000 */ +#define RTC_ALRMAR_HU_3 (0x8UL << RTC_ALRMAR_HU_Pos) /*!< 0x00080000 */ +#define RTC_ALRMAR_HT_Pos (20U) +#define RTC_ALRMAR_HT_Msk (0x3UL << RTC_ALRMAR_HT_Pos) /*!< 0x00300000 */ +#define RTC_ALRMAR_HT RTC_ALRMAR_HT_Msk +#define RTC_ALRMAR_HT_0 (0x1UL << RTC_ALRMAR_HT_Pos) /*!< 0x00100000 */ +#define RTC_ALRMAR_HT_1 (0x2UL << RTC_ALRMAR_HT_Pos) /*!< 0x00200000 */ +#define RTC_ALRMAR_PM_Pos (22U) +#define RTC_ALRMAR_PM_Msk (0x1UL << RTC_ALRMAR_PM_Pos) /*!< 0x00400000 */ +#define RTC_ALRMAR_PM RTC_ALRMAR_PM_Msk +#define RTC_ALRMAR_MSK3_Pos (23U) +#define RTC_ALRMAR_MSK3_Msk (0x1UL << RTC_ALRMAR_MSK3_Pos) /*!< 0x00800000 */ +#define RTC_ALRMAR_MSK3 RTC_ALRMAR_MSK3_Msk +#define RTC_ALRMAR_DU_Pos (24U) +#define RTC_ALRMAR_DU_Msk (0xFUL << RTC_ALRMAR_DU_Pos) /*!< 0x0F000000 */ +#define RTC_ALRMAR_DU RTC_ALRMAR_DU_Msk +#define RTC_ALRMAR_DU_0 (0x1UL << RTC_ALRMAR_DU_Pos) /*!< 0x01000000 */ +#define RTC_ALRMAR_DU_1 (0x2UL << RTC_ALRMAR_DU_Pos) /*!< 0x02000000 */ +#define RTC_ALRMAR_DU_2 (0x4UL << RTC_ALRMAR_DU_Pos) /*!< 0x04000000 */ +#define RTC_ALRMAR_DU_3 (0x8UL << RTC_ALRMAR_DU_Pos) /*!< 0x08000000 */ +#define RTC_ALRMAR_DT_Pos (28U) +#define RTC_ALRMAR_DT_Msk (0x3UL << RTC_ALRMAR_DT_Pos) /*!< 0x30000000 */ +#define RTC_ALRMAR_DT RTC_ALRMAR_DT_Msk +#define RTC_ALRMAR_DT_0 (0x1UL << RTC_ALRMAR_DT_Pos) /*!< 0x10000000 */ +#define RTC_ALRMAR_DT_1 (0x2UL << RTC_ALRMAR_DT_Pos) /*!< 0x20000000 */ +#define RTC_ALRMAR_WDSEL_Pos (30U) +#define RTC_ALRMAR_WDSEL_Msk (0x1UL << RTC_ALRMAR_WDSEL_Pos) /*!< 0x40000000 */ +#define RTC_ALRMAR_WDSEL RTC_ALRMAR_WDSEL_Msk +#define RTC_ALRMAR_MSK4_Pos (31U) +#define RTC_ALRMAR_MSK4_Msk (0x1UL << RTC_ALRMAR_MSK4_Pos) /*!< 0x80000000 */ +#define RTC_ALRMAR_MSK4 RTC_ALRMAR_MSK4_Msk + +/******************** Bits definition for RTC_ALRMASSR register *************/ +#define RTC_ALRMASSR_SS_Pos (0U) +#define RTC_ALRMASSR_SS_Msk (0x7FFFUL << RTC_ALRMASSR_SS_Pos) /*!< 0x00007FFF */ +#define RTC_ALRMASSR_SS RTC_ALRMASSR_SS_Msk +#define RTC_ALRMASSR_MASKSS_Pos (24U) +#define RTC_ALRMASSR_MASKSS_Msk (0x3FUL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x3F000000 */ +#define RTC_ALRMASSR_MASKSS RTC_ALRMASSR_MASKSS_Msk +#define RTC_ALRMASSR_MASKSS_0 (0x1UL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x01000000 */ +#define RTC_ALRMASSR_MASKSS_1 (0x2UL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x02000000 */ +#define RTC_ALRMASSR_MASKSS_2 (0x4UL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x04000000 */ +#define RTC_ALRMASSR_MASKSS_3 (0x8UL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x08000000 */ +#define RTC_ALRMASSR_MASKSS_4 (0x10UL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x10000000 */ +#define RTC_ALRMASSR_MASKSS_5 (0x20UL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x20000000 */ +#define RTC_ALRMASSR_SSCLR_Pos (31U) +#define RTC_ALRMASSR_SSCLR_Msk (0x1UL << RTC_ALRMASSR_SSCLR_Pos) /*!< 0x80000000 */ +#define RTC_ALRMASSR_SSCLR RTC_ALRMASSR_SSCLR_Msk + +/******************** Bits definition for RTC_ALRMBR register ***************/ +#define RTC_ALRMBR_SU_Pos (0U) +#define RTC_ALRMBR_SU_Msk (0xFUL << RTC_ALRMBR_SU_Pos) /*!< 0x0000000F */ +#define RTC_ALRMBR_SU RTC_ALRMBR_SU_Msk +#define RTC_ALRMBR_SU_0 (0x1UL << RTC_ALRMBR_SU_Pos) /*!< 0x00000001 */ +#define RTC_ALRMBR_SU_1 (0x2UL << RTC_ALRMBR_SU_Pos) /*!< 0x00000002 */ +#define RTC_ALRMBR_SU_2 (0x4UL << RTC_ALRMBR_SU_Pos) /*!< 0x00000004 */ +#define RTC_ALRMBR_SU_3 (0x8UL << RTC_ALRMBR_SU_Pos) /*!< 0x00000008 */ +#define RTC_ALRMBR_ST_Pos (4U) +#define RTC_ALRMBR_ST_Msk (0x7UL << RTC_ALRMBR_ST_Pos) /*!< 0x00000070 */ +#define RTC_ALRMBR_ST RTC_ALRMBR_ST_Msk +#define RTC_ALRMBR_ST_0 (0x1UL << RTC_ALRMBR_ST_Pos) /*!< 0x00000010 */ +#define RTC_ALRMBR_ST_1 (0x2UL << RTC_ALRMBR_ST_Pos) /*!< 0x00000020 */ +#define RTC_ALRMBR_ST_2 (0x4UL << RTC_ALRMBR_ST_Pos) /*!< 0x00000040 */ +#define RTC_ALRMBR_MSK1_Pos (7U) +#define RTC_ALRMBR_MSK1_Msk (0x1UL << RTC_ALRMBR_MSK1_Pos) /*!< 0x00000080 */ +#define RTC_ALRMBR_MSK1 RTC_ALRMBR_MSK1_Msk +#define RTC_ALRMBR_MNU_Pos (8U) +#define RTC_ALRMBR_MNU_Msk (0xFUL << RTC_ALRMBR_MNU_Pos) /*!< 0x00000F00 */ +#define RTC_ALRMBR_MNU RTC_ALRMBR_MNU_Msk +#define RTC_ALRMBR_MNU_0 (0x1UL << RTC_ALRMBR_MNU_Pos) /*!< 0x00000100 */ +#define RTC_ALRMBR_MNU_1 (0x2UL << RTC_ALRMBR_MNU_Pos) /*!< 0x00000200 */ +#define RTC_ALRMBR_MNU_2 (0x4UL << RTC_ALRMBR_MNU_Pos) /*!< 0x00000400 */ +#define RTC_ALRMBR_MNU_3 (0x8UL << RTC_ALRMBR_MNU_Pos) /*!< 0x00000800 */ +#define RTC_ALRMBR_MNT_Pos (12U) +#define RTC_ALRMBR_MNT_Msk (0x7UL << RTC_ALRMBR_MNT_Pos) /*!< 0x00007000 */ +#define RTC_ALRMBR_MNT RTC_ALRMBR_MNT_Msk +#define RTC_ALRMBR_MNT_0 (0x1UL << RTC_ALRMBR_MNT_Pos) /*!< 0x00001000 */ +#define RTC_ALRMBR_MNT_1 (0x2UL << RTC_ALRMBR_MNT_Pos) /*!< 0x00002000 */ +#define RTC_ALRMBR_MNT_2 (0x4UL << RTC_ALRMBR_MNT_Pos) /*!< 0x00004000 */ +#define RTC_ALRMBR_MSK2_Pos (15U) +#define RTC_ALRMBR_MSK2_Msk (0x1UL << RTC_ALRMBR_MSK2_Pos) /*!< 0x00008000 */ +#define RTC_ALRMBR_MSK2 RTC_ALRMBR_MSK2_Msk +#define RTC_ALRMBR_HU_Pos (16U) +#define RTC_ALRMBR_HU_Msk (0xFUL << RTC_ALRMBR_HU_Pos) /*!< 0x000F0000 */ +#define RTC_ALRMBR_HU RTC_ALRMBR_HU_Msk +#define RTC_ALRMBR_HU_0 (0x1UL << RTC_ALRMBR_HU_Pos) /*!< 0x00010000 */ +#define RTC_ALRMBR_HU_1 (0x2UL << RTC_ALRMBR_HU_Pos) /*!< 0x00020000 */ +#define RTC_ALRMBR_HU_2 (0x4UL << RTC_ALRMBR_HU_Pos) /*!< 0x00040000 */ +#define RTC_ALRMBR_HU_3 (0x8UL << RTC_ALRMBR_HU_Pos) /*!< 0x00080000 */ +#define RTC_ALRMBR_HT_Pos (20U) +#define RTC_ALRMBR_HT_Msk (0x3UL << RTC_ALRMBR_HT_Pos) /*!< 0x00300000 */ +#define RTC_ALRMBR_HT RTC_ALRMBR_HT_Msk +#define RTC_ALRMBR_HT_0 (0x1UL << RTC_ALRMBR_HT_Pos) /*!< 0x00100000 */ +#define RTC_ALRMBR_HT_1 (0x2UL << RTC_ALRMBR_HT_Pos) /*!< 0x00200000 */ +#define RTC_ALRMBR_PM_Pos (22U) +#define RTC_ALRMBR_PM_Msk (0x1UL << RTC_ALRMBR_PM_Pos) /*!< 0x00400000 */ +#define RTC_ALRMBR_PM RTC_ALRMBR_PM_Msk +#define RTC_ALRMBR_MSK3_Pos (23U) +#define RTC_ALRMBR_MSK3_Msk (0x1UL << RTC_ALRMBR_MSK3_Pos) /*!< 0x00800000 */ +#define RTC_ALRMBR_MSK3 RTC_ALRMBR_MSK3_Msk +#define RTC_ALRMBR_DU_Pos (24U) +#define RTC_ALRMBR_DU_Msk (0xFUL << RTC_ALRMBR_DU_Pos) /*!< 0x0F000000 */ +#define RTC_ALRMBR_DU RTC_ALRMBR_DU_Msk +#define RTC_ALRMBR_DU_0 (0x1UL << RTC_ALRMBR_DU_Pos) /*!< 0x01000000 */ +#define RTC_ALRMBR_DU_1 (0x2UL << RTC_ALRMBR_DU_Pos) /*!< 0x02000000 */ +#define RTC_ALRMBR_DU_2 (0x4UL << RTC_ALRMBR_DU_Pos) /*!< 0x04000000 */ +#define RTC_ALRMBR_DU_3 (0x8UL << RTC_ALRMBR_DU_Pos) /*!< 0x08000000 */ +#define RTC_ALRMBR_DT_Pos (28U) +#define RTC_ALRMBR_DT_Msk (0x3UL << RTC_ALRMBR_DT_Pos) /*!< 0x30000000 */ +#define RTC_ALRMBR_DT RTC_ALRMBR_DT_Msk +#define RTC_ALRMBR_DT_0 (0x1UL << RTC_ALRMBR_DT_Pos) /*!< 0x10000000 */ +#define RTC_ALRMBR_DT_1 (0x2UL << RTC_ALRMBR_DT_Pos) /*!< 0x20000000 */ +#define RTC_ALRMBR_WDSEL_Pos (30U) +#define RTC_ALRMBR_WDSEL_Msk (0x1UL << RTC_ALRMBR_WDSEL_Pos) /*!< 0x40000000 */ +#define RTC_ALRMBR_WDSEL RTC_ALRMBR_WDSEL_Msk +#define RTC_ALRMBR_MSK4_Pos (31U) +#define RTC_ALRMBR_MSK4_Msk (0x1UL << RTC_ALRMBR_MSK4_Pos) /*!< 0x80000000 */ +#define RTC_ALRMBR_MSK4 RTC_ALRMBR_MSK4_Msk + +/******************** Bits definition for RTC_ALRMBSSR register *************/ +#define RTC_ALRMBSSR_SS_Pos (0U) +#define RTC_ALRMBSSR_SS_Msk (0x7FFFUL << RTC_ALRMBSSR_SS_Pos) /*!< 0x00007FFF */ +#define RTC_ALRMBSSR_SS RTC_ALRMBSSR_SS_Msk +#define RTC_ALRMBSSR_MASKSS_Pos (24U) +#define RTC_ALRMBSSR_MASKSS_Msk (0x3FUL << RTC_ALRMBSSR_MASKSS_Pos) /*!< 0x3F000000 */ +#define RTC_ALRMBSSR_MASKSS RTC_ALRMBSSR_MASKSS_Msk +#define RTC_ALRMBSSR_MASKSS_0 (0x1UL << RTC_ALRMBSSR_MASKSS_Pos) /*!< 0x01000000 */ +#define RTC_ALRMBSSR_MASKSS_1 (0x2UL << RTC_ALRMBSSR_MASKSS_Pos) /*!< 0x02000000 */ +#define RTC_ALRMBSSR_MASKSS_2 (0x4UL << RTC_ALRMBSSR_MASKSS_Pos) /*!< 0x04000000 */ +#define RTC_ALRMBSSR_MASKSS_3 (0x8UL << RTC_ALRMBSSR_MASKSS_Pos) /*!< 0x08000000 */ +#define RTC_ALRMBSSR_MASKSS_4 (0x10UL << RTC_ALRMBSSR_MASKSS_Pos) /*!< 0x10000000 */ +#define RTC_ALRMBSSR_MASKSS_5 (0x20UL << RTC_ALRMBSSR_MASKSS_Pos) /*!< 0x20000000 */ +#define RTC_ALRMBSSR_SSCLR_Pos (31U) +#define RTC_ALRMBSSR_SSCLR_Msk (0x1UL << RTC_ALRMBSSR_SSCLR_Pos) /*!< 0x80000000 */ +#define RTC_ALRMBSSR_SSCLR RTC_ALRMBSSR_SSCLR_Msk + +/******************** Bits definition for RTC_SR register *******************/ +#define RTC_SR_ALRAF_Pos (0U) +#define RTC_SR_ALRAF_Msk (0x1UL << RTC_SR_ALRAF_Pos) /*!< 0x00000001 */ +#define RTC_SR_ALRAF RTC_SR_ALRAF_Msk +#define RTC_SR_ALRBF_Pos (1U) +#define RTC_SR_ALRBF_Msk (0x1UL << RTC_SR_ALRBF_Pos) /*!< 0x00000002 */ +#define RTC_SR_ALRBF RTC_SR_ALRBF_Msk +#define RTC_SR_WUTF_Pos (2U) +#define RTC_SR_WUTF_Msk (0x1UL << RTC_SR_WUTF_Pos) /*!< 0x00000004 */ +#define RTC_SR_WUTF RTC_SR_WUTF_Msk +#define RTC_SR_TSF_Pos (3U) +#define RTC_SR_TSF_Msk (0x1UL << RTC_SR_TSF_Pos) /*!< 0x00000008 */ +#define RTC_SR_TSF RTC_SR_TSF_Msk +#define RTC_SR_TSOVF_Pos (4U) +#define RTC_SR_TSOVF_Msk (0x1UL << RTC_SR_TSOVF_Pos) /*!< 0x00000010 */ +#define RTC_SR_TSOVF RTC_SR_TSOVF_Msk +#define RTC_SR_ITSF_Pos (5U) +#define RTC_SR_ITSF_Msk (0x1UL << RTC_SR_ITSF_Pos) /*!< 0x00000020 */ +#define RTC_SR_ITSF RTC_SR_ITSF_Msk +#define RTC_SR_SSRUF_Pos (6U) +#define RTC_SR_SSRUF_Msk (0x1UL << RTC_SR_SSRUF_Pos) /*!< 0x00000040 */ +#define RTC_SR_SSRUF RTC_SR_SSRUF_Msk + +/******************** Bits definition for RTC_MISR register *****************/ +#define RTC_MISR_ALRAMF_Pos (0U) +#define RTC_MISR_ALRAMF_Msk (0x1UL << RTC_MISR_ALRAMF_Pos) /*!< 0x00000001 */ +#define RTC_MISR_ALRAMF RTC_MISR_ALRAMF_Msk +#define RTC_MISR_ALRBMF_Pos (1U) +#define RTC_MISR_ALRBMF_Msk (0x1UL << RTC_MISR_ALRBMF_Pos) /*!< 0x00000002 */ +#define RTC_MISR_ALRBMF RTC_MISR_ALRBMF_Msk +#define RTC_MISR_WUTMF_Pos (2U) +#define RTC_MISR_WUTMF_Msk (0x1UL << RTC_MISR_WUTMF_Pos) /*!< 0x00000004 */ +#define RTC_MISR_WUTMF RTC_MISR_WUTMF_Msk +#define RTC_MISR_TSMF_Pos (3U) +#define RTC_MISR_TSMF_Msk (0x1UL << RTC_MISR_TSMF_Pos) /*!< 0x00000008 */ +#define RTC_MISR_TSMF RTC_MISR_TSMF_Msk +#define RTC_MISR_TSOVMF_Pos (4U) +#define RTC_MISR_TSOVMF_Msk (0x1UL << RTC_MISR_TSOVMF_Pos) /*!< 0x00000010 */ +#define RTC_MISR_TSOVMF RTC_MISR_TSOVMF_Msk +#define RTC_MISR_ITSMF_Pos (5U) +#define RTC_MISR_ITSMF_Msk (0x1UL << RTC_MISR_ITSMF_Pos) /*!< 0x00000020 */ +#define RTC_MISR_ITSMF RTC_MISR_ITSMF_Msk +#define RTC_MISR_SSRUMF_Pos (6U) +#define RTC_MISR_SSRUMF_Msk (0x1UL << RTC_MISR_SSRUMF_Pos) /*!< 0x00000040 */ +#define RTC_MISR_SSRUMF RTC_MISR_SSRUMF_Msk + + +/******************** Bits definition for RTC_SCR register ******************/ +#define RTC_SCR_CALRAF_Pos (0U) +#define RTC_SCR_CALRAF_Msk (0x1UL << RTC_SCR_CALRAF_Pos) /*!< 0x00000001 */ +#define RTC_SCR_CALRAF RTC_SCR_CALRAF_Msk +#define RTC_SCR_CALRBF_Pos (1U) +#define RTC_SCR_CALRBF_Msk (0x1UL << RTC_SCR_CALRBF_Pos) /*!< 0x00000002 */ +#define RTC_SCR_CALRBF RTC_SCR_CALRBF_Msk +#define RTC_SCR_CWUTF_Pos (2U) +#define RTC_SCR_CWUTF_Msk (0x1UL << RTC_SCR_CWUTF_Pos) /*!< 0x00000004 */ +#define RTC_SCR_CWUTF RTC_SCR_CWUTF_Msk +#define RTC_SCR_CTSF_Pos (3U) +#define RTC_SCR_CTSF_Msk (0x1UL << RTC_SCR_CTSF_Pos) /*!< 0x00000008 */ +#define RTC_SCR_CTSF RTC_SCR_CTSF_Msk +#define RTC_SCR_CTSOVF_Pos (4U) +#define RTC_SCR_CTSOVF_Msk (0x1UL << RTC_SCR_CTSOVF_Pos) /*!< 0x00000010 */ +#define RTC_SCR_CTSOVF RTC_SCR_CTSOVF_Msk +#define RTC_SCR_CITSF_Pos (5U) +#define RTC_SCR_CITSF_Msk (0x1UL << RTC_SCR_CITSF_Pos) /*!< 0x00000020 */ +#define RTC_SCR_CITSF RTC_SCR_CITSF_Msk +#define RTC_SCR_CSSRUF_Pos (6U) +#define RTC_SCR_CSSRUF_Msk (0x1UL << RTC_SCR_CSSRUF_Pos) /*!< 0x00000040 */ +#define RTC_SCR_CSSRUF RTC_SCR_CSSRUF_Msk + + +/******************** Bits definition for RTC_ALRABINR register ******************/ +#define RTC_ALRABINR_SS_Pos (0U) +#define RTC_ALRABINR_SS_Msk (0xFFFFFFFFUL << RTC_ALRABINR_SS_Pos) /*!< 0xFFFFFFFF */ +#define RTC_ALRABINR_SS RTC_ALRABINR_SS_Msk + +/******************** Bits definition for RTC_ALRBBINR register ******************/ +#define RTC_ALRBBINR_SS_Pos (0U) +#define RTC_ALRBBINR_SS_Msk (0xFFFFFFFFUL << RTC_ALRBBINR_SS_Pos) /*!< 0xFFFFFFFF */ +#define RTC_ALRBBINR_SS RTC_ALRBBINR_SS_Msk + +/******************************************************************************/ +/* */ +/* Tamper and backup register (TAMP) */ +/* */ +/******************************************************************************/ +/******************** Bits definition for TAMP_CR1 register *****************/ +#define TAMP_CR1_TAMP1E_Pos (0U) +#define TAMP_CR1_TAMP1E_Msk (0x1UL << TAMP_CR1_TAMP1E_Pos) /*!< 0x00000001 */ +#define TAMP_CR1_TAMP1E TAMP_CR1_TAMP1E_Msk +#define TAMP_CR1_TAMP2E_Pos (1U) +#define TAMP_CR1_TAMP2E_Msk (0x1UL << TAMP_CR1_TAMP2E_Pos) /*!< 0x00000002 */ +#define TAMP_CR1_TAMP2E TAMP_CR1_TAMP2E_Msk +#define TAMP_CR1_ITAMP1E_Pos (16U) +#define TAMP_CR1_ITAMP1E_Msk (0x1UL << TAMP_CR1_ITAMP1E_Pos) /*!< 0x00010000 */ +#define TAMP_CR1_ITAMP1E TAMP_CR1_ITAMP1E_Msk +#define TAMP_CR1_ITAMP2E_Pos (17U) +#define TAMP_CR1_ITAMP2E_Msk (0x1UL << TAMP_CR1_ITAMP2E_Pos) /*!< 0x00020000 */ +#define TAMP_CR1_ITAMP2E TAMP_CR1_ITAMP2E_Msk +#define TAMP_CR1_ITAMP3E_Pos (18U) +#define TAMP_CR1_ITAMP3E_Msk (0x1UL << TAMP_CR1_ITAMP3E_Pos) /*!< 0x00040000 */ +#define TAMP_CR1_ITAMP3E TAMP_CR1_ITAMP3E_Msk +#define TAMP_CR1_ITAMP4E_Pos (19U) +#define TAMP_CR1_ITAMP4E_Msk (0x1UL << TAMP_CR1_ITAMP4E_Pos) /*!< 0x00080000 */ +#define TAMP_CR1_ITAMP4E TAMP_CR1_ITAMP4E_Msk +#define TAMP_CR1_ITAMP5E_Pos (20U) +#define TAMP_CR1_ITAMP5E_Msk (0x1UL << TAMP_CR1_ITAMP5E_Pos) /*!< 0x00100000 */ +#define TAMP_CR1_ITAMP5E TAMP_CR1_ITAMP5E_Msk +#define TAMP_CR1_ITAMP6E_Pos (21U) +#define TAMP_CR1_ITAMP6E_Msk (0x1UL << TAMP_CR1_ITAMP6E_Pos) /*!< 0x00200000 */ +#define TAMP_CR1_ITAMP6E TAMP_CR1_ITAMP6E_Msk +#define TAMP_CR1_ITAMP7E_Pos (22U) +#define TAMP_CR1_ITAMP7E_Msk (0x1UL << TAMP_CR1_ITAMP7E_Pos) /*!< 0x00400000 */ +#define TAMP_CR1_ITAMP7E TAMP_CR1_ITAMP7E_Msk +#define TAMP_CR1_ITAMP8E_Pos (23U) +#define TAMP_CR1_ITAMP8E_Msk (0x1UL << TAMP_CR1_ITAMP8E_Pos) /*!< 0x00800000 */ +#define TAMP_CR1_ITAMP8E TAMP_CR1_ITAMP8E_Msk +#define TAMP_CR1_ITAMP9E_Pos (24U) +#define TAMP_CR1_ITAMP9E_Msk (0x1UL << TAMP_CR1_ITAMP9E_Pos) /*!< 0x01000000 */ +#define TAMP_CR1_ITAMP9E TAMP_CR1_ITAMP9E_Msk +#define TAMP_CR1_ITAMP11E_Pos (26U) +#define TAMP_CR1_ITAMP11E_Msk (0x1UL << TAMP_CR1_ITAMP11E_Pos) /*!< 0x04000000 */ +#define TAMP_CR1_ITAMP11E TAMP_CR1_ITAMP11E_Msk +#define TAMP_CR1_ITAMP12E_Pos (27U) +#define TAMP_CR1_ITAMP12E_Msk (0x1UL << TAMP_CR1_ITAMP12E_Pos) /*!< 0x08000000 */ +#define TAMP_CR1_ITAMP12E TAMP_CR1_ITAMP12E_Msk +#define TAMP_CR1_ITAMP13E_Pos (28U) +#define TAMP_CR1_ITAMP13E_Msk (0x1UL << TAMP_CR1_ITAMP13E_Pos) /*!< 0x10000000 */ +#define TAMP_CR1_ITAMP13E TAMP_CR1_ITAMP13E_Msk +#define TAMP_CR1_ITAMP15E_Pos (30U) +#define TAMP_CR1_ITAMP15E_Msk (0x1UL << TAMP_CR1_ITAMP15E_Pos) /*!< 0x40000000 */ +#define TAMP_CR1_ITAMP15E TAMP_CR1_ITAMP15E_Msk + +/******************** Bits definition for TAMP_CR2 register *****************/ +#define TAMP_CR2_TAMP1NOERASE_Pos (0U) +#define TAMP_CR2_TAMP1NOERASE_Msk (0x1UL << TAMP_CR2_TAMP1NOERASE_Pos) /*!< 0x00000001 */ +#define TAMP_CR2_TAMP1NOERASE TAMP_CR2_TAMP1NOERASE_Msk +#define TAMP_CR2_TAMP2NOERASE_Pos (1U) +#define TAMP_CR2_TAMP2NOERASE_Msk (0x1UL << TAMP_CR2_TAMP2NOERASE_Pos) /*!< 0x00000002 */ +#define TAMP_CR2_TAMP2NOERASE TAMP_CR2_TAMP2NOERASE_Msk +#define TAMP_CR2_TAMP1MSK_Pos (16U) +#define TAMP_CR2_TAMP1MSK_Msk (0x1UL << TAMP_CR2_TAMP1MSK_Pos) /*!< 0x00010000 */ +#define TAMP_CR2_TAMP1MSK TAMP_CR2_TAMP1MSK_Msk +#define TAMP_CR2_TAMP2MSK_Pos (17U) +#define TAMP_CR2_TAMP2MSK_Msk (0x1UL << TAMP_CR2_TAMP2MSK_Pos) /*!< 0x00020000 */ +#define TAMP_CR2_TAMP2MSK TAMP_CR2_TAMP2MSK_Msk +#define TAMP_CR2_BKBLOCK_Pos (22U) +#define TAMP_CR2_BKBLOCK_Msk (0x1UL << TAMP_CR2_BKBLOCK_Pos) /*!< 0x00400000 */ +#define TAMP_CR2_BKBLOCK TAMP_CR2_BKBLOCK_Msk +#define TAMP_CR2_BKERASE_Pos (23U) +#define TAMP_CR2_BKERASE_Msk (0x1UL << TAMP_CR2_BKERASE_Pos) /*!< 0x00800000 */ +#define TAMP_CR2_BKERASE TAMP_CR2_BKERASE_Msk +#define TAMP_CR2_TAMP1TRG_Pos (24U) +#define TAMP_CR2_TAMP1TRG_Msk (0x1UL << TAMP_CR2_TAMP1TRG_Pos) /*!< 0x01000000 */ +#define TAMP_CR2_TAMP1TRG TAMP_CR2_TAMP1TRG_Msk +#define TAMP_CR2_TAMP2TRG_Pos (25U) +#define TAMP_CR2_TAMP2TRG_Msk (0x1UL << TAMP_CR2_TAMP2TRG_Pos) /*!< 0x02000000 */ +#define TAMP_CR2_TAMP2TRG TAMP_CR2_TAMP2TRG_Msk + +/******************** Bits definition for TAMP_CR3 register *****************/ +#define TAMP_CR3_ITAMP1NOER_Pos (0U) +#define TAMP_CR3_ITAMP1NOER_Msk (0x1UL << TAMP_CR3_ITAMP1NOER_Pos) /*!< 0x00000001 */ +#define TAMP_CR3_ITAMP1NOER TAMP_CR3_ITAMP1NOER_Msk +#define TAMP_CR3_ITAMP2NOER_Pos (1U) +#define TAMP_CR3_ITAMP2NOER_Msk (0x1UL << TAMP_CR3_ITAMP2NOER_Pos) /*!< 0x00000002 */ +#define TAMP_CR3_ITAMP2NOER TAMP_CR3_ITAMP2NOER_Msk +#define TAMP_CR3_ITAMP3NOER_Pos (2U) +#define TAMP_CR3_ITAMP3NOER_Msk (0x1UL << TAMP_CR3_ITAMP3NOER_Pos) /*!< 0x00000004 */ +#define TAMP_CR3_ITAMP3NOER TAMP_CR3_ITAMP3NOER_Msk +#define TAMP_CR3_ITAMP4NOER_Pos (3U) +#define TAMP_CR3_ITAMP4NOER_Msk (0x1UL << TAMP_CR3_ITAMP4NOER_Pos) /*!< 0x00000008 */ +#define TAMP_CR3_ITAMP4NOER TAMP_CR3_ITAMP4NOER_Msk +#define TAMP_CR3_ITAMP5NOER_Pos (4U) +#define TAMP_CR3_ITAMP5NOER_Msk (0x1UL << TAMP_CR3_ITAMP5NOER_Pos) /*!< 0x00000010 */ +#define TAMP_CR3_ITAMP5NOER TAMP_CR3_ITAMP5NOER_Msk +#define TAMP_CR3_ITAMP6NOER_Pos (5U) +#define TAMP_CR3_ITAMP6NOER_Msk (0x1UL << TAMP_CR3_ITAMP6NOER_Pos) /*!< 0x00000020 */ +#define TAMP_CR3_ITAMP6NOER TAMP_CR3_ITAMP6NOER_Msk +#define TAMP_CR3_ITAMP7NOER_Pos (6U) +#define TAMP_CR3_ITAMP7NOER_Msk (0x1UL << TAMP_CR3_ITAMP7NOER_Pos) /*!< 0x00000040 */ +#define TAMP_CR3_ITAMP7NOER TAMP_CR3_ITAMP7NOER_Msk +#define TAMP_CR3_ITAMP8NOER_Pos (7U) +#define TAMP_CR3_ITAMP8NOER_Msk (0x1UL << TAMP_CR3_ITAMP8NOER_Pos) /*!< 0x00000080 */ +#define TAMP_CR3_ITAMP8NOER TAMP_CR3_ITAMP8NOER_Msk +#define TAMP_CR3_ITAMP9NOER_Pos (8U) +#define TAMP_CR3_ITAMP9NOER_Msk (0x1UL << TAMP_CR3_ITAMP9NOER_Pos) /*!< 0x00000100 */ +#define TAMP_CR3_ITAMP9NOER TAMP_CR3_ITAMP9NOER_Msk +#define TAMP_CR3_ITAMP11NOER_Pos (10U) +#define TAMP_CR3_ITAMP11NOER_Msk (0x1UL << TAMP_CR3_ITAMP11NOER_Pos) /*!< 0x00000400 */ +#define TAMP_CR3_ITAMP11NOER TAMP_CR3_ITAMP11NOER_Msk +#define TAMP_CR3_ITAMP12NOER_Pos (11U) +#define TAMP_CR3_ITAMP12NOER_Msk (0x1UL << TAMP_CR3_ITAMP12NOER_Pos) /*!< 0x00000800 */ +#define TAMP_CR3_ITAMP12NOER TAMP_CR3_ITAMP12NOER_Msk +#define TAMP_CR3_ITAMP13NOER_Pos (12U) +#define TAMP_CR3_ITAMP13NOER_Msk (0x1UL << TAMP_CR3_ITAMP13NOER_Pos) /*!< 0x00001000 */ +#define TAMP_CR3_ITAMP13NOER TAMP_CR3_ITAMP13NOER_Msk +#define TAMP_CR3_ITAMP15NOER_Pos (14U) +#define TAMP_CR3_ITAMP15NOER_Msk (0x1UL << TAMP_CR3_ITAMP15NOER_Pos) /*!< 0x00004000 */ +#define TAMP_CR3_ITAMP15NOER TAMP_CR3_ITAMP15NOER_Msk + +/******************** Bits definition for TAMP_FLTCR register ***************/ +#define TAMP_FLTCR_TAMPFREQ_Pos (0U) +#define TAMP_FLTCR_TAMPFREQ_Msk (0x7UL << TAMP_FLTCR_TAMPFREQ_Pos) /*!< 0x00000007 */ +#define TAMP_FLTCR_TAMPFREQ TAMP_FLTCR_TAMPFREQ_Msk +#define TAMP_FLTCR_TAMPFREQ_0 (0x1UL << TAMP_FLTCR_TAMPFREQ_Pos) /*!< 0x00000001 */ +#define TAMP_FLTCR_TAMPFREQ_1 (0x2UL << TAMP_FLTCR_TAMPFREQ_Pos) /*!< 0x00000002 */ +#define TAMP_FLTCR_TAMPFREQ_2 (0x4UL << TAMP_FLTCR_TAMPFREQ_Pos) /*!< 0x00000004 */ +#define TAMP_FLTCR_TAMPFLT_Pos (3U) +#define TAMP_FLTCR_TAMPFLT_Msk (0x3UL << TAMP_FLTCR_TAMPFLT_Pos) /*!< 0x00000018 */ +#define TAMP_FLTCR_TAMPFLT TAMP_FLTCR_TAMPFLT_Msk +#define TAMP_FLTCR_TAMPFLT_0 (0x1UL << TAMP_FLTCR_TAMPFLT_Pos) /*!< 0x00000008 */ +#define TAMP_FLTCR_TAMPFLT_1 (0x2UL << TAMP_FLTCR_TAMPFLT_Pos) /*!< 0x00000010 */ +#define TAMP_FLTCR_TAMPPRCH_Pos (5U) +#define TAMP_FLTCR_TAMPPRCH_Msk (0x3UL << TAMP_FLTCR_TAMPPRCH_Pos) /*!< 0x00000060 */ +#define TAMP_FLTCR_TAMPPRCH TAMP_FLTCR_TAMPPRCH_Msk +#define TAMP_FLTCR_TAMPPRCH_0 (0x1UL << TAMP_FLTCR_TAMPPRCH_Pos) /*!< 0x00000020 */ +#define TAMP_FLTCR_TAMPPRCH_1 (0x2UL << TAMP_FLTCR_TAMPPRCH_Pos) /*!< 0x00000040 */ +#define TAMP_FLTCR_TAMPPUDIS_Pos (7U) +#define TAMP_FLTCR_TAMPPUDIS_Msk (0x1UL << TAMP_FLTCR_TAMPPUDIS_Pos) /*!< 0x00000080 */ +#define TAMP_FLTCR_TAMPPUDIS TAMP_FLTCR_TAMPPUDIS_Msk + +/******************** Bits definition for TAMP_ATCR1 register ***************/ +#define TAMP_ATCR1_TAMP1AM_Pos (0U) +#define TAMP_ATCR1_TAMP1AM_Msk (0x1UL << TAMP_ATCR1_TAMP1AM_Pos) /*!< 0x00000001 */ +#define TAMP_ATCR1_TAMP1AM TAMP_ATCR1_TAMP1AM_Msk +#define TAMP_ATCR1_TAMP2AM_Pos (1U) +#define TAMP_ATCR1_TAMP2AM_Msk (0x1UL << TAMP_ATCR1_TAMP2AM_Pos) /*!< 0x00000002 */ +#define TAMP_ATCR1_TAMP2AM TAMP_ATCR1_TAMP2AM_Msk +#define TAMP_ATCR1_ATOSEL1_Pos (8U) +#define TAMP_ATCR1_ATOSEL1_Msk (0x3UL << TAMP_ATCR1_ATOSEL1_Pos) /*!< 0x00000300 */ +#define TAMP_ATCR1_ATOSEL1 TAMP_ATCR1_ATOSEL1_Msk +#define TAMP_ATCR1_ATOSEL1_0 (0x1UL << TAMP_ATCR1_ATOSEL1_Pos) /*!< 0x00000100 */ +#define TAMP_ATCR1_ATOSEL1_1 (0x2UL << TAMP_ATCR1_ATOSEL1_Pos) /*!< 0x00000200 */ +#define TAMP_ATCR1_ATOSEL2_Pos (10U) +#define TAMP_ATCR1_ATOSEL2_Msk (0x3UL << TAMP_ATCR1_ATOSEL2_Pos) /*!< 0x00000C00 */ +#define TAMP_ATCR1_ATOSEL2 TAMP_ATCR1_ATOSEL2_Msk +#define TAMP_ATCR1_ATOSEL2_0 (0x1UL << TAMP_ATCR1_ATOSEL2_Pos) /*!< 0x00000400 */ +#define TAMP_ATCR1_ATOSEL2_1 (0x2UL << TAMP_ATCR1_ATOSEL2_Pos) /*!< 0x00000800 */ +#define TAMP_ATCR1_ATCKSEL_Pos (16U) +#define TAMP_ATCR1_ATCKSEL_Msk (0xFUL << TAMP_ATCR1_ATCKSEL_Pos) /*!< 0x000F0000 */ +#define TAMP_ATCR1_ATCKSEL TAMP_ATCR1_ATCKSEL_Msk +#define TAMP_ATCR1_ATCKSEL_0 (0x1UL << TAMP_ATCR1_ATCKSEL_Pos) /*!< 0x00010000 */ +#define TAMP_ATCR1_ATCKSEL_1 (0x2UL << TAMP_ATCR1_ATCKSEL_Pos) /*!< 0x00020000 */ +#define TAMP_ATCR1_ATCKSEL_2 (0x4UL << TAMP_ATCR1_ATCKSEL_Pos) /*!< 0x00040000 */ +#define TAMP_ATCR1_ATCKSEL_3 (0x8UL << TAMP_ATCR1_ATCKSEL_Pos) /*!< 0x00080000 */ +#define TAMP_ATCR1_ATPER_Pos (24U) +#define TAMP_ATCR1_ATPER_Msk (0x7UL << TAMP_ATCR1_ATPER_Pos) /*!< 0x07000000 */ +#define TAMP_ATCR1_ATPER TAMP_ATCR1_ATPER_Msk +#define TAMP_ATCR1_ATPER_0 (0x1UL << TAMP_ATCR1_ATPER_Pos) /*!< 0x01000000 */ +#define TAMP_ATCR1_ATPER_1 (0x2UL << TAMP_ATCR1_ATPER_Pos) /*!< 0x02000000 */ +#define TAMP_ATCR1_ATPER_2 (0x4UL << TAMP_ATCR1_ATPER_Pos) /*!< 0x04000000 */ +#define TAMP_ATCR1_ATOSHARE_Pos (30U) +#define TAMP_ATCR1_ATOSHARE_Msk (0x1UL << TAMP_ATCR1_ATOSHARE_Pos) /*!< 0x40000000 */ +#define TAMP_ATCR1_ATOSHARE TAMP_ATCR1_ATOSHARE_Msk +#define TAMP_ATCR1_FLTEN_Pos (31U) +#define TAMP_ATCR1_FLTEN_Msk (0x1UL << TAMP_ATCR1_FLTEN_Pos) /*!< 0x80000000 */ +#define TAMP_ATCR1_FLTEN TAMP_ATCR1_FLTEN_Msk + +/******************** Bits definition for TAMP_ATSEEDR register ******************/ +#define TAMP_ATSEEDR_SEED_Pos (0U) +#define TAMP_ATSEEDR_SEED_Msk (0xFFFFFFFFUL << TAMP_ATSEEDR_SEED_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_ATSEEDR_SEED TAMP_ATSEEDR_SEED_Msk + +/******************** Bits definition for TAMP_ATOR register ******************/ +#define TAMP_ATOR_PRNG_Pos (0U) +#define TAMP_ATOR_PRNG_Msk (0xFFUL << TAMP_ATOR_PRNG_Pos) /*!< 0x000000FF */ +#define TAMP_ATOR_PRNG TAMP_ATOR_PRNG_Msk +#define TAMP_ATOR_PRNG_0 (0x1UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000001 */ +#define TAMP_ATOR_PRNG_1 (0x2UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000002 */ +#define TAMP_ATOR_PRNG_2 (0x4UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000004 */ +#define TAMP_ATOR_PRNG_3 (0x8UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000008 */ +#define TAMP_ATOR_PRNG_4 (0x10UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000010 */ +#define TAMP_ATOR_PRNG_5 (0x20UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000020 */ +#define TAMP_ATOR_PRNG_6 (0x40UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000040 */ +#define TAMP_ATOR_PRNG_7 (0x80UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000080 */ +#define TAMP_ATOR_SEEDF_Pos (14U) +#define TAMP_ATOR_SEEDF_Msk (1UL << TAMP_ATOR_SEEDF_Pos) /*!< 0x00004000 */ +#define TAMP_ATOR_SEEDF TAMP_ATOR_SEEDF_Msk +#define TAMP_ATOR_INITS_Pos (15U) +#define TAMP_ATOR_INITS_Msk (1UL << TAMP_ATOR_INITS_Pos) /*!< 0x00008000 */ +#define TAMP_ATOR_INITS TAMP_ATOR_INITS_Msk + +/******************** Bits definition for TAMP_ATCR2 register ***************/ +#define TAMP_ATCR2_ATOSEL1_Pos (8U) +#define TAMP_ATCR2_ATOSEL1_Msk (0x7UL << TAMP_ATCR2_ATOSEL1_Pos) /*!< 0x00000700 */ +#define TAMP_ATCR2_ATOSEL1 TAMP_ATCR2_ATOSEL1_Msk +#define TAMP_ATCR2_ATOSEL1_0 (0x1UL << TAMP_ATCR2_ATOSEL1_Pos) /*!< 0x00000100 */ +#define TAMP_ATCR2_ATOSEL1_1 (0x2UL << TAMP_ATCR2_ATOSEL1_Pos) /*!< 0x00000200 */ +#define TAMP_ATCR2_ATOSEL1_2 (0x4UL << TAMP_ATCR2_ATOSEL1_Pos) /*!< 0x00000400 */ +#define TAMP_ATCR2_ATOSEL2_Pos (11U) +#define TAMP_ATCR2_ATOSEL2_Msk (0x7UL << TAMP_ATCR2_ATOSEL2_Pos) /*!< 0x00003800 */ +#define TAMP_ATCR2_ATOSEL2 TAMP_ATCR2_ATOSEL2_Msk +#define TAMP_ATCR2_ATOSEL2_0 (0x1UL << TAMP_ATCR2_ATOSEL2_Pos) /*!< 0x00000800 */ +#define TAMP_ATCR2_ATOSEL2_1 (0x2UL << TAMP_ATCR2_ATOSEL2_Pos) /*!< 0x00001000 */ +#define TAMP_ATCR2_ATOSEL2_2 (0x4UL << TAMP_ATCR2_ATOSEL2_Pos) /*!< 0x00002000 */ + +/******************** Bits definition for TAMP_SECCFGR register *************/ +/* Keep SEC acronym name as following devices (STM32H562xx, STM32H563xx, STM32H573xx) with secure + acronym to avoid duplicated bits definitions */ +#define TAMP_SECCFGR_BKPRWSEC_Pos (0U) +#define TAMP_SECCFGR_BKPRWSEC_Msk (0xFFUL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x000000FF */ +#define TAMP_SECCFGR_BKPRWSEC TAMP_SECCFGR_BKPRWSEC_Msk +#define TAMP_SECCFGR_BKPRWSEC_0 (0x1UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000001 */ +#define TAMP_SECCFGR_BKPRWSEC_1 (0x2UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000002 */ +#define TAMP_SECCFGR_BKPRWSEC_2 (0x4UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000004 */ +#define TAMP_SECCFGR_BKPRWSEC_3 (0x8UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000008 */ +#define TAMP_SECCFGR_BKPRWSEC_4 (0x10UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000010 */ +#define TAMP_SECCFGR_BKPRWSEC_5 (0x20UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000020 */ +#define TAMP_SECCFGR_BKPRWSEC_6 (0x40UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000040 */ +#define TAMP_SECCFGR_BKPRWSEC_7 (0x80UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000080 */ +#define TAMP_SECCFGR_BKPWSEC_Pos (16U) +#define TAMP_SECCFGR_BKPWSEC_Msk (0xFFUL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00FF0000 */ +#define TAMP_SECCFGR_BKPWSEC TAMP_SECCFGR_BKPWSEC_Msk +#define TAMP_SECCFGR_BKPWSEC_0 (0x1UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00010000 */ +#define TAMP_SECCFGR_BKPWSEC_1 (0x2UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00020000 */ +#define TAMP_SECCFGR_BKPWSEC_2 (0x4UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00040000 */ +#define TAMP_SECCFGR_BKPWSEC_3 (0x8UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00080000 */ +#define TAMP_SECCFGR_BKPWSEC_4 (0x10UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00100000 */ +#define TAMP_SECCFGR_BKPWSEC_5 (0x20UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00200000 */ +#define TAMP_SECCFGR_BKPWSEC_6 (0x40UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00400000 */ +#define TAMP_SECCFGR_BKPWSEC_7 (0x80UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00800000 */ + +/******************** Bits definition for TAMP_PRIVCFGR register ************/ +#define TAMP_PRIVCFGR_CNT1PRIV_Pos (15U) +#define TAMP_PRIVCFGR_CNT1PRIV_Msk (0x1UL << TAMP_PRIVCFGR_CNT1PRIV_Pos) /*!< 0x20000000 */ +#define TAMP_PRIVCFGR_CNT1PRIV TAMP_PRIVCFGR_CNT1PRIV_Msk +#define TAMP_PRIVCFGR_BKPRWPRIV_Pos (29U) +#define TAMP_PRIVCFGR_BKPRWPRIV_Msk (0x1UL << TAMP_PRIVCFGR_BKPRWPRIV_Pos) /*!< 0x20000000 */ +#define TAMP_PRIVCFGR_BKPRWPRIV TAMP_PRIVCFGR_BKPRWPRIV_Msk +#define TAMP_PRIVCFGR_BKPWPRIV_Pos (30U) +#define TAMP_PRIVCFGR_BKPWPRIV_Msk (0x1UL << TAMP_PRIVCFGR_BKPWPRIV_Pos) /*!< 0x40000000 */ +#define TAMP_PRIVCFGR_BKPWPRIV TAMP_PRIVCFGR_BKPWPRIV_Msk +#define TAMP_PRIVCFGR_TAMPPRIV_Pos (31U) +#define TAMP_PRIVCFGR_TAMPPRIV_Msk (0x1UL << TAMP_PRIVCFGR_TAMPPRIV_Pos) /*!< 0x80000000 */ +#define TAMP_PRIVCFGR_TAMPPRIV TAMP_PRIVCFGR_TAMPPRIV_Msk + +/******************** Bits definition for TAMP_IER register *****************/ +#define TAMP_IER_TAMP1IE_Pos (0U) +#define TAMP_IER_TAMP1IE_Msk (0x1UL << TAMP_IER_TAMP1IE_Pos) /*!< 0x00000001 */ +#define TAMP_IER_TAMP1IE TAMP_IER_TAMP1IE_Msk +#define TAMP_IER_TAMP2IE_Pos (1U) +#define TAMP_IER_TAMP2IE_Msk (0x1UL << TAMP_IER_TAMP2IE_Pos) /*!< 0x00000002 */ +#define TAMP_IER_TAMP2IE TAMP_IER_TAMP2IE_Msk +#define TAMP_IER_ITAMP1IE_Pos (16U) +#define TAMP_IER_ITAMP1IE_Msk (0x1UL << TAMP_IER_ITAMP1IE_Pos) /*!< 0x00010000 */ +#define TAMP_IER_ITAMP1IE TAMP_IER_ITAMP1IE_Msk +#define TAMP_IER_ITAMP2IE_Pos (17U) +#define TAMP_IER_ITAMP2IE_Msk (0x1UL << TAMP_IER_ITAMP2IE_Pos) /*!< 0x00020000 */ +#define TAMP_IER_ITAMP2IE TAMP_IER_ITAMP2IE_Msk +#define TAMP_IER_ITAMP3IE_Pos (18U) +#define TAMP_IER_ITAMP3IE_Msk (0x1UL << TAMP_IER_ITAMP3IE_Pos) /*!< 0x00040000 */ +#define TAMP_IER_ITAMP3IE TAMP_IER_ITAMP3IE_Msk +#define TAMP_IER_ITAMP4IE_Pos (19U) +#define TAMP_IER_ITAMP4IE_Msk (0x1UL << TAMP_IER_ITAMP4IE_Pos) /*!< 0x00080000 */ +#define TAMP_IER_ITAMP4IE TAMP_IER_ITAMP4IE_Msk +#define TAMP_IER_ITAMP5IE_Pos (20U) +#define TAMP_IER_ITAMP5IE_Msk (0x1UL << TAMP_IER_ITAMP5IE_Pos) /*!< 0x00100000 */ +#define TAMP_IER_ITAMP5IE TAMP_IER_ITAMP5IE_Msk +#define TAMP_IER_ITAMP6IE_Pos (21U) +#define TAMP_IER_ITAMP6IE_Msk (0x1UL << TAMP_IER_ITAMP6IE_Pos) /*!< 0x00200000 */ +#define TAMP_IER_ITAMP6IE TAMP_IER_ITAMP6IE_Msk +#define TAMP_IER_ITAMP7IE_Pos (22U) +#define TAMP_IER_ITAMP7IE_Msk (0x1UL << TAMP_IER_ITAMP7IE_Pos) /*!< 0x00400000 */ +#define TAMP_IER_ITAMP7IE TAMP_IER_ITAMP7IE_Msk +#define TAMP_IER_ITAMP8IE_Pos (23U) +#define TAMP_IER_ITAMP8IE_Msk (0x1UL << TAMP_IER_ITAMP8IE_Pos) /*!< 0x00800000 */ +#define TAMP_IER_ITAMP8IE TAMP_IER_ITAMP8IE_Msk +#define TAMP_IER_ITAMP9IE_Pos (24U) +#define TAMP_IER_ITAMP9IE_Msk (0x1UL << TAMP_IER_ITAMP9IE_Pos) /*!< 0x01000000 */ +#define TAMP_IER_ITAMP9IE TAMP_IER_ITAMP9IE_Msk +#define TAMP_IER_ITAMP11IE_Pos (26U) +#define TAMP_IER_ITAMP11IE_Msk (0x1UL << TAMP_IER_ITAMP11IE_Pos) /*!< 0x04000000 */ +#define TAMP_IER_ITAMP11IE TAMP_IER_ITAMP11IE_Msk +#define TAMP_IER_ITAMP12IE_Pos (27U) +#define TAMP_IER_ITAMP12IE_Msk (0x1UL << TAMP_IER_ITAMP12IE_Pos) /*!< 0x08000000 */ +#define TAMP_IER_ITAMP12IE TAMP_IER_ITAMP12IE_Msk +#define TAMP_IER_ITAMP13IE_Pos (28U) +#define TAMP_IER_ITAMP13IE_Msk (0x1UL << TAMP_IER_ITAMP13IE_Pos) /*!< 0x10000000 */ +#define TAMP_IER_ITAMP13IE TAMP_IER_ITAMP13IE_Msk +#define TAMP_IER_ITAMP15IE_Pos (30U) +#define TAMP_IER_ITAMP15IE_Msk (0x1UL << TAMP_IER_ITAMP15IE_Pos) /*!< 0x40000000 */ +#define TAMP_IER_ITAMP15IE TAMP_IER_ITAMP15IE_Msk + +/******************** Bits definition for TAMP_SR register *****************/ +#define TAMP_SR_TAMP1F_Pos (0U) +#define TAMP_SR_TAMP1F_Msk (0x1UL << TAMP_SR_TAMP1F_Pos) /*!< 0x00000001 */ +#define TAMP_SR_TAMP1F TAMP_SR_TAMP1F_Msk +#define TAMP_SR_TAMP2F_Pos (1U) +#define TAMP_SR_TAMP2F_Msk (0x1UL << TAMP_SR_TAMP2F_Pos) /*!< 0x00000002 */ +#define TAMP_SR_TAMP2F TAMP_SR_TAMP2F_Msk +#define TAMP_SR_ITAMP1F_Pos (16U) +#define TAMP_SR_ITAMP1F_Msk (0x1UL << TAMP_SR_ITAMP1F_Pos) /*!< 0x00010000 */ +#define TAMP_SR_ITAMP1F TAMP_SR_ITAMP1F_Msk +#define TAMP_SR_ITAMP2F_Pos (17U) +#define TAMP_SR_ITAMP2F_Msk (0x1UL << TAMP_SR_ITAMP2F_Pos) /*!< 0x00020000 */ +#define TAMP_SR_ITAMP2F TAMP_SR_ITAMP2F_Msk +#define TAMP_SR_ITAMP3F_Pos (18U) +#define TAMP_SR_ITAMP3F_Msk (0x1UL << TAMP_SR_ITAMP3F_Pos) /*!< 0x00040000 */ +#define TAMP_SR_ITAMP3F TAMP_SR_ITAMP3F_Msk +#define TAMP_SR_ITAMP4F_Pos (19U) +#define TAMP_SR_ITAMP4F_Msk (0x1UL << TAMP_SR_ITAMP4F_Pos) /*!< 0x00080000 */ +#define TAMP_SR_ITAMP4F TAMP_SR_ITAMP4F_Msk +#define TAMP_SR_ITAMP5F_Pos (20U) +#define TAMP_SR_ITAMP5F_Msk (0x1UL << TAMP_SR_ITAMP5F_Pos) /*!< 0x00100000 */ +#define TAMP_SR_ITAMP5F TAMP_SR_ITAMP5F_Msk +#define TAMP_SR_ITAMP6F_Pos (21U) +#define TAMP_SR_ITAMP6F_Msk (0x1UL << TAMP_SR_ITAMP6F_Pos) /*!< 0x00200000 */ +#define TAMP_SR_ITAMP6F TAMP_SR_ITAMP6F_Msk +#define TAMP_SR_ITAMP7F_Pos (22U) +#define TAMP_SR_ITAMP7F_Msk (0x1UL << TAMP_SR_ITAMP7F_Pos) /*!< 0x00400000 */ +#define TAMP_SR_ITAMP7F TAMP_SR_ITAMP7F_Msk +#define TAMP_SR_ITAMP8F_Pos (23U) +#define TAMP_SR_ITAMP8F_Msk (0x1UL << TAMP_SR_ITAMP8F_Pos) /*!< 0x00800000 */ +#define TAMP_SR_ITAMP8F TAMP_SR_ITAMP8F_Msk +#define TAMP_SR_ITAMP9F_Pos (24U) +#define TAMP_SR_ITAMP9F_Msk (0x1UL << TAMP_SR_ITAMP9F_Pos) /*!< 0x01000000 */ +#define TAMP_SR_ITAMP9F TAMP_SR_ITAMP9F_Msk +#define TAMP_SR_ITAMP11F_Pos (26U) +#define TAMP_SR_ITAMP11F_Msk (0x1UL << TAMP_SR_ITAMP11F_Pos) /*!< 0x04000000 */ +#define TAMP_SR_ITAMP11F TAMP_SR_ITAMP11F_Msk +#define TAMP_SR_ITAMP12F_Pos (27U) +#define TAMP_SR_ITAMP12F_Msk (0x1UL << TAMP_SR_ITAMP12F_Pos) /*!< 0x08000000 */ +#define TAMP_SR_ITAMP12F TAMP_SR_ITAMP12F_Msk +#define TAMP_SR_ITAMP13F_Pos (28U) +#define TAMP_SR_ITAMP13F_Msk (0x1UL << TAMP_SR_ITAMP13F_Pos) /*!< 0x10000000 */ +#define TAMP_SR_ITAMP13F TAMP_SR_ITAMP13F_Msk +#define TAMP_SR_ITAMP15F_Pos (30U) +#define TAMP_SR_ITAMP15F_Msk (0x1UL << TAMP_SR_ITAMP15F_Pos) /*!< 0x40000000 */ +#define TAMP_SR_ITAMP15F TAMP_SR_ITAMP15F_Msk + +/******************** Bits definition for TAMP_MISR register ****************/ +#define TAMP_MISR_TAMP1MF_Pos (0U) +#define TAMP_MISR_TAMP1MF_Msk (0x1UL << TAMP_MISR_TAMP1MF_Pos) /*!< 0x00000001 */ +#define TAMP_MISR_TAMP1MF TAMP_MISR_TAMP1MF_Msk +#define TAMP_MISR_TAMP2MF_Pos (1U) +#define TAMP_MISR_TAMP2MF_Msk (0x1UL << TAMP_MISR_TAMP2MF_Pos) /*!< 0x00000002 */ +#define TAMP_MISR_TAMP2MF TAMP_MISR_TAMP2MF_Msk +#define TAMP_MISR_ITAMP1MF_Pos (16U) +#define TAMP_MISR_ITAMP1MF_Msk (0x1UL << TAMP_MISR_ITAMP1MF_Pos) /*!< 0x00010000 */ +#define TAMP_MISR_ITAMP1MF TAMP_MISR_ITAMP1MF_Msk +#define TAMP_MISR_ITAMP2MF_Pos (17U) +#define TAMP_MISR_ITAMP2MF_Msk (0x1UL << TAMP_MISR_ITAMP2MF_Pos) /*!< 0x00020000 */ +#define TAMP_MISR_ITAMP2MF TAMP_MISR_ITAMP2MF_Msk +#define TAMP_MISR_ITAMP3MF_Pos (18U) +#define TAMP_MISR_ITAMP3MF_Msk (0x1UL << TAMP_MISR_ITAMP3MF_Pos) /*!< 0x00040000 */ +#define TAMP_MISR_ITAMP3MF TAMP_MISR_ITAMP3MF_Msk +#define TAMP_MISR_ITAMP4MF_Pos (19U) +#define TAMP_MISR_ITAMP4MF_Msk (0x1UL << TAMP_MISR_ITAMP4MF_Pos) /*!< 0x00080000 */ +#define TAMP_MISR_ITAMP4MF TAMP_MISR_ITAMP4MF_Msk +#define TAMP_MISR_ITAMP5MF_Pos (20U) +#define TAMP_MISR_ITAMP5MF_Msk (0x1UL << TAMP_MISR_ITAMP5MF_Pos) /*!< 0x00100000 */ +#define TAMP_MISR_ITAMP5MF TAMP_MISR_ITAMP5MF_Msk +#define TAMP_MISR_ITAMP6MF_Pos (21U) +#define TAMP_MISR_ITAMP6MF_Msk (0x1UL << TAMP_MISR_ITAMP6MF_Pos) /*!< 0x00200000 */ +#define TAMP_MISR_ITAMP6MF TAMP_MISR_ITAMP6MF_Msk +#define TAMP_MISR_ITAMP7MF_Pos (22U) +#define TAMP_MISR_ITAMP7MF_Msk (0x1UL << TAMP_MISR_ITAMP7MF_Pos) /*!< 0x00400000 */ +#define TAMP_MISR_ITAMP7MF TAMP_MISR_ITAMP7MF_Msk +#define TAMP_MISR_ITAMP8MF_Pos (23U) +#define TAMP_MISR_ITAMP8MF_Msk (0x1UL << TAMP_MISR_ITAMP8MF_Pos) /*!< 0x00800000 */ +#define TAMP_MISR_ITAMP8MF TAMP_MISR_ITAMP8MF_Msk +#define TAMP_MISR_ITAMP9MF_Pos (24U) +#define TAMP_MISR_ITAMP9MF_Msk (0x1UL << TAMP_MISR_ITAMP9MF_Pos) /*!< 0x01000000 */ +#define TAMP_MISR_ITAMP9MF TAMP_MISR_ITAMP9MF_Msk +#define TAMP_MISR_ITAMP11MF_Pos (26U) +#define TAMP_MISR_ITAMP11MF_Msk (0x1UL << TAMP_MISR_ITAMP11MF_Pos) /*!< 0x04000000 */ +#define TAMP_MISR_ITAMP11MF TAMP_MISR_ITAMP11MF_Msk +#define TAMP_MISR_ITAMP12MF_Pos (27U) +#define TAMP_MISR_ITAMP12MF_Msk (0x1UL << TAMP_MISR_ITAMP12MF_Pos) /*!< 0x08000000 */ +#define TAMP_MISR_ITAMP12MF TAMP_MISR_ITAMP12MF_Msk +#define TAMP_MISR_ITAMP13MF_Pos (28U) +#define TAMP_MISR_ITAMP13MF_Msk (0x1UL << TAMP_MISR_ITAMP13MF_Pos) /*!< 0x10000000 */ +#define TAMP_MISR_ITAMP13MF TAMP_MISR_ITAMP13MF_Msk +#define TAMP_MISR_ITAMP15MF_Pos (30U) +#define TAMP_MISR_ITAMP15MF_Msk (0x1UL << TAMP_MISR_ITAMP15MF_Pos) /*!< 0x40000000 */ +#define TAMP_MISR_ITAMP15MF TAMP_MISR_ITAMP15MF_Msk + + +/******************** Bits definition for TAMP_SCR register *****************/ +#define TAMP_SCR_CTAMP1F_Pos (0U) +#define TAMP_SCR_CTAMP1F_Msk (0x1UL << TAMP_SCR_CTAMP1F_Pos) /*!< 0x00000001 */ +#define TAMP_SCR_CTAMP1F TAMP_SCR_CTAMP1F_Msk +#define TAMP_SCR_CTAMP2F_Pos (1U) +#define TAMP_SCR_CTAMP2F_Msk (0x1UL << TAMP_SCR_CTAMP2F_Pos) /*!< 0x00000002 */ +#define TAMP_SCR_CTAMP2F TAMP_SCR_CTAMP2F_Msk +#define TAMP_SCR_CITAMP1F_Pos (16U) +#define TAMP_SCR_CITAMP1F_Msk (0x1UL << TAMP_SCR_CITAMP1F_Pos) /*!< 0x00010000 */ +#define TAMP_SCR_CITAMP1F TAMP_SCR_CITAMP1F_Msk +#define TAMP_SCR_CITAMP2F_Pos (17U) +#define TAMP_SCR_CITAMP2F_Msk (0x1UL << TAMP_SCR_CITAMP2F_Pos) /*!< 0x00020000 */ +#define TAMP_SCR_CITAMP2F TAMP_SCR_CITAMP2F_Msk +#define TAMP_SCR_CITAMP3F_Pos (18U) +#define TAMP_SCR_CITAMP3F_Msk (0x1UL << TAMP_SCR_CITAMP3F_Pos) /*!< 0x00040000 */ +#define TAMP_SCR_CITAMP3F TAMP_SCR_CITAMP3F_Msk +#define TAMP_SCR_CITAMP4F_Pos (19U) +#define TAMP_SCR_CITAMP4F_Msk (0x1UL << TAMP_SCR_CITAMP4F_Pos) /*!< 0x00080000 */ +#define TAMP_SCR_CITAMP4F TAMP_SCR_CITAMP4F_Msk +#define TAMP_SCR_CITAMP5F_Pos (20U) +#define TAMP_SCR_CITAMP5F_Msk (0x1UL << TAMP_SCR_CITAMP5F_Pos) /*!< 0x00100000 */ +#define TAMP_SCR_CITAMP5F TAMP_SCR_CITAMP5F_Msk +#define TAMP_SCR_CITAMP6F_Pos (21U) +#define TAMP_SCR_CITAMP6F_Msk (0x1UL << TAMP_SCR_CITAMP6F_Pos) /*!< 0x00200000 */ +#define TAMP_SCR_CITAMP6F TAMP_SCR_CITAMP6F_Msk +#define TAMP_SCR_CITAMP7F_Pos (22U) +#define TAMP_SCR_CITAMP7F_Msk (0x1UL << TAMP_SCR_CITAMP7F_Pos) /*!< 0x00400000 */ +#define TAMP_SCR_CITAMP7F TAMP_SCR_CITAMP7F_Msk +#define TAMP_SCR_CITAMP8F_Pos (23U) +#define TAMP_SCR_CITAMP8F_Msk (0x1UL << TAMP_SCR_CITAMP8F_Pos) /*!< 0x00800000 */ +#define TAMP_SCR_CITAMP8F TAMP_SCR_CITAMP8F_Msk +#define TAMP_SCR_CITAMP9F_Pos (24U) +#define TAMP_SCR_CITAMP9F_Msk (0x1UL << TAMP_SCR_CITAMP9F_Pos) /*!< 0x00100000 */ +#define TAMP_SCR_CITAMP9F TAMP_SCR_CITAMP9F_Msk +#define TAMP_SCR_CITAMP11F_Pos (26U) +#define TAMP_SCR_CITAMP11F_Msk (0x1UL << TAMP_SCR_CITAMP11F_Pos) /*!< 0x00400000 */ +#define TAMP_SCR_CITAMP11F TAMP_SCR_CITAMP11F_Msk +#define TAMP_SCR_CITAMP12F_Pos (27U) +#define TAMP_SCR_CITAMP12F_Msk (0x1UL << TAMP_SCR_CITAMP12F_Pos) /*!< 0x08000000 */ +#define TAMP_SCR_CITAMP12F TAMP_SCR_CITAMP12F_Msk +#define TAMP_SCR_CITAMP13F_Pos (28U) +#define TAMP_SCR_CITAMP13F_Msk (0x1UL << TAMP_SCR_CITAMP13F_Pos) /*!< 0x10000000 */ +#define TAMP_SCR_CITAMP13F TAMP_SCR_CITAMP13F_Msk +#define TAMP_SCR_CITAMP15F_Pos (30U) +#define TAMP_SCR_CITAMP15F_Msk (0x1UL << TAMP_SCR_CITAMP15F_Pos) /*!< 0x40000000 */ +#define TAMP_SCR_CITAMP15F TAMP_SCR_CITAMP15F_Msk +/******************** Bits definition for TAMP_COUNT1R register ***************/ +#define TAMP_COUNT1R_COUNT_Pos (0U) +#define TAMP_COUNT1R_COUNT_Msk (0xFFFFFFFFUL << TAMP_COUNT1R_COUNT_Pos)/*!< 0xFFFFFFFF */ +#define TAMP_COUNT1R_COUNT TAMP_COUNT1R_COUNT_Msk + + +/******************** Bits definition for TAMP_ERCFG register ***************/ +#define TAMP_ERCFGR_ERCFG0_Pos (0U) +#define TAMP_ERCFGR_ERCFG0_Msk (0x1UL << TAMP_ERCFGR_ERCFG0_Pos) /*!< 0x00000001 */ +#define TAMP_ERCFGR_ERCFG0 TAMP_ERCFGR_ERCFG0_Msk + +/******************** Bits definition for TAMP_BKP0R register ***************/ +#define TAMP_BKP0R_Pos (0U) +#define TAMP_BKP0R_Msk (0xFFFFFFFFUL << TAMP_BKP0R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP0R TAMP_BKP0R_Msk + +/******************** Bits definition for TAMP_BKP1R register ****************/ +#define TAMP_BKP1R_Pos (0U) +#define TAMP_BKP1R_Msk (0xFFFFFFFFUL << TAMP_BKP1R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP1R TAMP_BKP1R_Msk + +/******************** Bits definition for TAMP_BKP2R register ****************/ +#define TAMP_BKP2R_Pos (0U) +#define TAMP_BKP2R_Msk (0xFFFFFFFFUL << TAMP_BKP2R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP2R TAMP_BKP2R_Msk + +/******************** Bits definition for TAMP_BKP3R register ****************/ +#define TAMP_BKP3R_Pos (0U) +#define TAMP_BKP3R_Msk (0xFFFFFFFFUL << TAMP_BKP3R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP3R TAMP_BKP3R_Msk + +/******************** Bits definition for TAMP_BKP4R register ****************/ +#define TAMP_BKP4R_Pos (0U) +#define TAMP_BKP4R_Msk (0xFFFFFFFFUL << TAMP_BKP4R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP4R TAMP_BKP4R_Msk + +/******************** Bits definition for TAMP_BKP5R register ****************/ +#define TAMP_BKP5R_Pos (0U) +#define TAMP_BKP5R_Msk (0xFFFFFFFFUL << TAMP_BKP5R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP5R TAMP_BKP5R_Msk + +/******************** Bits definition for TAMP_BKP6R register ****************/ +#define TAMP_BKP6R_Pos (0U) +#define TAMP_BKP6R_Msk (0xFFFFFFFFUL << TAMP_BKP6R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP6R TAMP_BKP6R_Msk + +/******************** Bits definition for TAMP_BKP7R register ****************/ +#define TAMP_BKP7R_Pos (0U) +#define TAMP_BKP7R_Msk (0xFFFFFFFFUL << TAMP_BKP7R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP7R TAMP_BKP7R_Msk + +/******************** Bits definition for TAMP_BKP8R register ****************/ +#define TAMP_BKP8R_Pos (0U) +#define TAMP_BKP8R_Msk (0xFFFFFFFFUL << TAMP_BKP8R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP8R TAMP_BKP8R_Msk + +/******************** Bits definition for TAMP_BKP9R register ****************/ +#define TAMP_BKP9R_Pos (0U) +#define TAMP_BKP9R_Msk (0xFFFFFFFFUL << TAMP_BKP9R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP9R TAMP_BKP9R_Msk + +/******************** Bits definition for TAMP_BKP10R register ***************/ +#define TAMP_BKP10R_Pos (0U) +#define TAMP_BKP10R_Msk (0xFFFFFFFFUL << TAMP_BKP10R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP10R TAMP_BKP10R_Msk + +/******************** Bits definition for TAMP_BKP11R register ***************/ +#define TAMP_BKP11R_Pos (0U) +#define TAMP_BKP11R_Msk (0xFFFFFFFFUL << TAMP_BKP11R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP11R TAMP_BKP11R_Msk + +/******************** Bits definition for TAMP_BKP12R register ***************/ +#define TAMP_BKP12R_Pos (0U) +#define TAMP_BKP12R_Msk (0xFFFFFFFFUL << TAMP_BKP12R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP12R TAMP_BKP12R_Msk + +/******************** Bits definition for TAMP_BKP13R register ***************/ +#define TAMP_BKP13R_Pos (0U) +#define TAMP_BKP13R_Msk (0xFFFFFFFFUL << TAMP_BKP13R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP13R TAMP_BKP13R_Msk + +/******************** Bits definition for TAMP_BKP14R register ***************/ +#define TAMP_BKP14R_Pos (0U) +#define TAMP_BKP14R_Msk (0xFFFFFFFFUL << TAMP_BKP14R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP14R TAMP_BKP14R_Msk + +/******************** Bits definition for TAMP_BKP15R register ***************/ +#define TAMP_BKP15R_Pos (0U) +#define TAMP_BKP15R_Msk (0xFFFFFFFFUL << TAMP_BKP15R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP15R TAMP_BKP15R_Msk + +/******************** Bits definition for TAMP_BKP16R register ***************/ +#define TAMP_BKP16R_Pos (0U) +#define TAMP_BKP16R_Msk (0xFFFFFFFFUL << TAMP_BKP16R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP16R TAMP_BKP16R_Msk + +/******************** Bits definition for TAMP_BKP17R register ***************/ +#define TAMP_BKP17R_Pos (0U) +#define TAMP_BKP17R_Msk (0xFFFFFFFFUL << TAMP_BKP17R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP17R TAMP_BKP17R_Msk + +/******************** Bits definition for TAMP_BKP18R register ***************/ +#define TAMP_BKP18R_Pos (0U) +#define TAMP_BKP18R_Msk (0xFFFFFFFFUL << TAMP_BKP18R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP18R TAMP_BKP18R_Msk + +/******************** Bits definition for TAMP_BKP19R register ***************/ +#define TAMP_BKP19R_Pos (0U) +#define TAMP_BKP19R_Msk (0xFFFFFFFFUL << TAMP_BKP19R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP19R TAMP_BKP19R_Msk + +/******************** Bits definition for TAMP_BKP20R register ***************/ +#define TAMP_BKP20R_Pos (0U) +#define TAMP_BKP20R_Msk (0xFFFFFFFFUL << TAMP_BKP20R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP20R TAMP_BKP20R_Msk + +/******************** Bits definition for TAMP_BKP21R register ***************/ +#define TAMP_BKP21R_Pos (0U) +#define TAMP_BKP21R_Msk (0xFFFFFFFFUL << TAMP_BKP21R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP21R TAMP_BKP21R_Msk + +/******************** Bits definition for TAMP_BKP22R register ***************/ +#define TAMP_BKP22R_Pos (0U) +#define TAMP_BKP22R_Msk (0xFFFFFFFFUL << TAMP_BKP22R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP22R TAMP_BKP22R_Msk + +/******************** Bits definition for TAMP_BKP23R register ***************/ +#define TAMP_BKP23R_Pos (0U) +#define TAMP_BKP23R_Msk (0xFFFFFFFFUL << TAMP_BKP23R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP23R TAMP_BKP23R_Msk + +/******************** Bits definition for TAMP_BKP24R register ***************/ +#define TAMP_BKP24R_Pos (0U) +#define TAMP_BKP24R_Msk (0xFFFFFFFFUL << TAMP_BKP24R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP24R TAMP_BKP24R_Msk + +/******************** Bits definition for TAMP_BKP25R register ***************/ +#define TAMP_BKP25R_Pos (0U) +#define TAMP_BKP25R_Msk (0xFFFFFFFFUL << TAMP_BKP25R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP25R TAMP_BKP25R_Msk + +/******************** Bits definition for TAMP_BKP26R register ***************/ +#define TAMP_BKP26R_Pos (0U) +#define TAMP_BKP26R_Msk (0xFFFFFFFFUL << TAMP_BKP26R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP26R TAMP_BKP26R_Msk + +/******************** Bits definition for TAMP_BKP27R register ***************/ +#define TAMP_BKP27R_Pos (0U) +#define TAMP_BKP27R_Msk (0xFFFFFFFFUL << TAMP_BKP27R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP27R TAMP_BKP27R_Msk + +/******************** Bits definition for TAMP_BKP28R register ***************/ +#define TAMP_BKP28R_Pos (0U) +#define TAMP_BKP28R_Msk (0xFFFFFFFFUL << TAMP_BKP28R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP28R TAMP_BKP28R_Msk + +/******************** Bits definition for TAMP_BKP29R register ***************/ +#define TAMP_BKP29R_Pos (0U) +#define TAMP_BKP29R_Msk (0xFFFFFFFFUL << TAMP_BKP29R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP29R TAMP_BKP29R_Msk + +/******************** Bits definition for TAMP_BKP30R register ***************/ +#define TAMP_BKP30R_Pos (0U) +#define TAMP_BKP30R_Msk (0xFFFFFFFFUL << TAMP_BKP30R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP30R TAMP_BKP30R_Msk + +/******************** Bits definition for TAMP_BKP31R register ***************/ +#define TAMP_BKP31R_Pos (0U) +#define TAMP_BKP31R_Msk (0xFFFFFFFFUL << TAMP_BKP31R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP31R TAMP_BKP31R_Msk + +/******************************************************************************/ +/* */ +/* SBS */ +/* */ +/******************************************************************************/ +/******************** Bit definition for SBS_HDPLCR register *****************/ +#define SBS_HDPLCR_INCR_HDPL_Pos (0U) +#define SBS_HDPLCR_INCR_HDPL_Msk (0xFFUL << SBS_HDPLCR_INCR_HDPL_Pos) /*!< 0x000000FF */ +#define SBS_HDPLCR_INCR_HDPL SBS_HDPLCR_INCR_HDPL_Msk /*!< Increment HDPL value. */ + +/******************** Bit definition for SBS_HDPLSR register *****************/ +#define SBS_HDPLSR_HDPL_Pos (0U) +#define SBS_HDPLSR_HDPL_Msk (0xFFUL << SBS_HDPLSR_HDPL_Pos) /*!< 0x000000FF */ +#define SBS_HDPLSR_HDPL SBS_HDPLSR_HDPL_Msk /*!< HDPL value. */ + +/******************** Bit definition for SBS_DBGCR register *****************/ +#define SBS_DBGCR_AP_UNLOCK_Pos (0U) +#define SBS_DBGCR_AP_UNLOCK_Msk (0xFFUL << SBS_DBGCR_AP_UNLOCK_Pos) /*!< 0x000000FF */ +#define SBS_DBGCR_AP_UNLOCK SBS_DBGCR_AP_UNLOCK_Msk /*!< Open the Access Port. */ + +#define SBS_DBGCR_DBG_UNLOCK_Pos (8U) +#define SBS_DBGCR_DBG_UNLOCK_Msk (0xFFUL << SBS_DBGCR_DBG_UNLOCK_Pos) /*!< 0x0000FF00 */ +#define SBS_DBGCR_DBG_UNLOCK SBS_DBGCR_DBG_UNLOCK_Msk /*!< Open the debug when DBG_AUTH_HDPL is reached. */ + +#define SBS_DBGCR_DBG_AUTH_HDPL_Pos (16U) +#define SBS_DBGCR_DBG_AUTH_HDPL_Msk (0xFFUL << SBS_DBGCR_DBG_AUTH_HDPL_Pos) /*!< 0x00FF0000 */ +#define SBS_DBGCR_DBG_AUTH_HDPL SBS_DBGCR_DBG_AUTH_HDPL_Msk /*!< HDPL value when the debug should be effectively opened. */ + +/******************** Bit definition for SBS_DBGLCKR register *****************/ +#define SBS_DBGLOCKR_DBGCFG_LOCK_Pos (0U) +#define SBS_DBGLOCKR_DBGCFG_LOCK_Msk (0xFFUL << SBS_DBGLOCKR_DBGCFG_LOCK_Pos) /*!< 0x000000FF */ +#define SBS_DBGLOCKR_DBGCFG_LOCK SBS_DBGLOCKR_DBGCFG_LOCK_Msk /*!< SBS_DBGLOCKR_DBGCFG_LOCK value. */ + +/****************** Bit definition for SBS_PMCR register ****************/ +#define SBS_PMCR_PB6_FMP_Pos (16U) +#define SBS_PMCR_PB6_FMP_Msk (0x1UL << SBS_PMCR_PB6_FMP_Pos) /*!< 0x00010000 */ +#define SBS_PMCR_PB6_FMP SBS_PMCR_PB6_FMP_Msk /*!< Fast-mode Plus command on PB(6) */ +#define SBS_PMCR_PB7_FMP_Pos (17U) +#define SBS_PMCR_PB7_FMP_Msk (0x1UL << SBS_PMCR_PB7_FMP_Pos) /*!< 0x00020000 */ +#define SBS_PMCR_PB7_FMP SBS_PMCR_PB7_FMP_Msk /*!< Fast-mode Plus command on PB(7) */ +#define SBS_PMCR_PB8_FMP_Pos (18U) +#define SBS_PMCR_PB8_FMP_Msk (0x1UL << SBS_PMCR_PB8_FMP_Pos) /*!< 0x00040000 */ +#define SBS_PMCR_PB8_FMP SBS_PMCR_PB8_FMP_Msk /*!< Fast-mode Plus command on PB(8) */ + +/****************** Bit definition for SBS_FPUIMR register ***************/ +#define SBS_FPUIMR_FPU_IE_Pos (0U) +#define SBS_FPUIMR_FPU_IE_Msk (0x3FUL << SBS_FPUIMR_FPU_IE_Pos) /*!< 0x0000003F - */ +#define SBS_FPUIMR_FPU_IE SBS_FPUIMR_FPU_IE_Msk /*!< All FPU interrupts enable */ +#define SBS_FPUIMR_FPU_IE_0 (0x1UL << SBS_FPUIMR_FPU_IE_Pos) /*!< 0x00000001 - Invalid operation Interrupt enable */ +#define SBS_FPUIMR_FPU_IE_1 (0x2UL << SBS_FPUIMR_FPU_IE_Pos) /*!< 0x00000002 - Divide-by-zero Interrupt enable */ +#define SBS_FPUIMR_FPU_IE_2 (0x4UL << SBS_FPUIMR_FPU_IE_Pos) /*!< 0x00000004 - Underflow Interrupt enable */ +#define SBS_FPUIMR_FPU_IE_3 (0x8UL << SBS_FPUIMR_FPU_IE_Pos) /*!< 0x00000008 - Overflow Interrupt enable */ +#define SBS_FPUIMR_FPU_IE_4 (0x10UL << SBS_FPUIMR_FPU_IE_Pos) /*!< 0x00000010 - Input denormal Interrupt enable */ +#define SBS_FPUIMR_FPU_IE_5 (0x20UL << SBS_FPUIMR_FPU_IE_Pos) /*!< 0x00000020 - Inexact Interrupt enable (interrupt disabled at reset) */ + +/****************** Bit definition for SBS_MESR register ****************/ +#define SBS_MESR_MCLR_Pos (0U) +#define SBS_MESR_MCLR_Msk (0x1UL << SBS_MESR_MCLR_Pos) /*!< 0x00000001 */ +#define SBS_MESR_MCLR SBS_MESR_MCLR_Msk /*!< Status of Erase after Reset */ +#define SBS_MESR_IPMEE_Pos (16U) +#define SBS_MESR_IPMEE_Msk (0x1UL << SBS_MESR_IPMEE_Pos) /*!< 0x00010000 */ +#define SBS_MESR_IPMEE SBS_MESR_IPMEE_Msk /*!< Status of End of Erase for ICache and PKA RAMs */ + +/****************** Bit definition for SBS_CCCSR register ****************/ +#define SBS_CCCSR_EN1_Pos (0U) +#define SBS_CCCSR_EN1_Msk (0x1UL << SBS_CCCSR_EN1_Pos) /*!< 0x00000001 */ +#define SBS_CCCSR_EN1 SBS_CCCSR_EN1_Msk /*!< Enable compensation cell for VDD power rail */ +#define SBS_CCCSR_CS1_Pos (1U) +#define SBS_CCCSR_CS1_Msk (0x1UL << SBS_CCCSR_CS1_Pos) /*!< 0x00000002 */ +#define SBS_CCCSR_CS1 SBS_CCCSR_CS1_Msk /*!< Code selection for VDD power rail */ +#define SBS_CCCSR_EN2_Pos (2U) +#define SBS_CCCSR_EN2_Msk (0x1UL << SBS_CCCSR_EN2_Pos) /*!< 0x00000004 */ +#define SBS_CCCSR_EN2 SBS_CCCSR_EN2_Msk /*!< Enable compensation cell for VDDIO power rail */ +#define SBS_CCCSR_CS2_Pos (3U) +#define SBS_CCCSR_CS2_Msk (0x1UL << SBS_CCCSR_CS2_Pos) /*!< 0x00000008 */ +#define SBS_CCCSR_CS2 SBS_CCCSR_CS2_Msk /*!< Code selection for VDDIO power rail */ +#define SBS_CCCSR_RDY1_Pos (8U) +#define SBS_CCCSR_RDY1_Msk (0x1UL << SBS_CCCSR_RDY1_Pos) /*!< 0x00000100 */ +#define SBS_CCCSR_RDY1 SBS_CCCSR_RDY1_Msk /*!< VDD compensation cell ready flag */ +#define SBS_CCCSR_RDY2_Pos (9U) +#define SBS_CCCSR_RDY2_Msk (0x1UL << SBS_CCCSR_RDY2_Pos) /*!< 0x00000200 */ +#define SBS_CCCSR_RDY2 SBS_CCCSR_RDY2_Msk /*!< VDDIO compensation cell ready flag */ + +/****************** Bit definition for SBS_CCVALR register ****************/ +#define SBS_CCVALR_ANSRC1_Pos (0U) +#define SBS_CCVALR_ANSRC1_Msk (0xFUL << SBS_CCVALR_ANSRC1_Pos) /*!< 0x0000000F */ +#define SBS_CCVALR_ANSRC1 SBS_CCVALR_ANSRC1_Msk /*!< NMOS compensation value */ +#define SBS_CCVALR_APSRC1_Pos (4U) +#define SBS_CCVALR_APSRC1_Msk (0xFUL << SBS_CCVALR_APSRC1_Pos) /*!< 0x000000F0 */ +#define SBS_CCVALR_APSRC1 SBS_CCVALR_APSRC1_Msk /*!< PMOS compensation value */ +#define SBS_CCVALR_ANSRC2_Pos (8U) +#define SBS_CCVALR_ANSRC2_Msk (0xFUL << SBS_CCVALR_ANSRC2_Pos) /*!< 0x00000F00 */ +#define SBS_CCVALR_ANSRC2 SBS_CCVALR_ANSRC2_Msk /*!< NMOS compensation value */ +#define SBS_CCVALR_APSRC2_Pos (12U) +#define SBS_CCVALR_APSRC2_Msk (0xFUL << SBS_CCVALR_APSRC2_Pos) /*!< 0x0000F000 */ +#define SBS_CCVALR_APSRC2 SBS_CCVALR_APSRC2_Msk /*!< PMOS compensation value */ + +/****************** Bit definition for SBS_CCSWCR register ****************/ +#define SBS_CCSWCR_SW_ANSRC1_Pos (0U) +#define SBS_CCSWCR_SW_ANSRC1_Msk (0xFUL << SBS_CCSWCR_SW_ANSRC1_Pos) /*!< 0x0000000F */ +#define SBS_CCSWCR_SW_ANSRC1 SBS_CCSWCR_SW_ANSRC1_Msk /*!< NMOS compensation code for VDD Power Rail */ +#define SBS_CCSWCR_SW_APSRC1_Pos (4U) +#define SBS_CCSWCR_SW_APSRC1_Msk (0xFUL << SBS_CCSWCR_SW_APSRC1_Pos) /*!< 0x000000F0 */ +#define SBS_CCSWCR_SW_APSRC1 SBS_CCSWCR_SW_APSRC1_Msk /*!< PMOS compensation code for VDD Power Rail */ +#define SBS_CCSWCR_SW_ANSRC2_Pos (8U) +#define SBS_CCSWCR_SW_ANSRC2_Msk (0xFUL << SBS_CCSWCR_SW_ANSRC2_Pos) /*!< 0x00000F00 */ +#define SBS_CCSWCR_SW_ANSRC2 SBS_CCSWCR_SW_ANSRC2_Msk /*!< NMOS compensation code for VDDIO Power Rail */ +#define SBS_CCSWCR_SW_APSRC2_Pos (12U) +#define SBS_CCSWCR_SW_APSRC2_Msk (0xFUL << SBS_CCSWCR_SW_APSRC2_Pos) /*!< 0x0000F000 */ +#define SBS_CCSWCR_SW_APSRC2 SBS_CCSWCR_SW_APSRC2_Msk /*!< PMOS compensation code for VDDIO Power Rail */ + +/****************** Bit definition for SBS_CFGR2 register ****************/ +#define SBS_CFGR2_CLL_Pos (0U) +#define SBS_CFGR2_CLL_Msk (0x1UL << SBS_CFGR2_CLL_Pos) /*!< 0x00000001 */ +#define SBS_CFGR2_CLL SBS_CFGR2_CLL_Msk /*!< Core Lockup Lock */ +#define SBS_CFGR2_SEL_Pos (1U) +#define SBS_CFGR2_SEL_Msk (0x1UL << SBS_CFGR2_SEL_Pos) /*!< 0x00000002 */ +#define SBS_CFGR2_SEL SBS_CFGR2_SEL_Msk /*!< SRAM ECC Lock */ +#define SBS_CFGR2_PVDL_Pos (2U) +#define SBS_CFGR2_PVDL_Msk (0x1UL << SBS_CFGR2_PVDL_Pos) /*!< 0x00000004 */ +#define SBS_CFGR2_PVDL SBS_CFGR2_PVDL_Msk /*!< PVD Lock */ +#define SBS_CFGR2_ECCL_Pos (3U) +#define SBS_CFGR2_ECCL_Msk (0x1UL << SBS_CFGR2_ECCL_Pos) /*!< 0x00000008 */ +#define SBS_CFGR2_ECCL SBS_CFGR2_ECCL_Msk /*!< Flash ECC Lock*/ + +/****************** Bit definition for SBS_CNSLCKR register **************/ +#define SBS_CNSLCKR_LOCKNSVTOR_Pos (0U) +#define SBS_CNSLCKR_LOCKNSVTOR_Msk (0x1UL << SBS_CNSLCKR_LOCKNSVTOR_Pos) /*!< 0x00000001 */ +#define SBS_CNSLCKR_LOCKNSVTOR SBS_CNSLCKR_LOCKNSVTOR_Msk /*!< Disable VTOR_NS register writes by SW or debug agent */ +#define SBS_CNSLCKR_LOCKNSMPU_Pos (1U) +#define SBS_CNSLCKR_LOCKNSMPU_Msk (0x1UL << SBS_CNSLCKR_LOCKNSMPU_Pos) /*!< 0x00000002 */ +#define SBS_CNSLCKR_LOCKNSMPU SBS_CNSLCKR_LOCKNSMPU_Msk /*!< Disable Non-Secure MPU registers writes by SW or debug agent */ + +/****************** Bit definition for SBS_ECCNMIR register ***************/ +#define SBS_ECCNMIR_ECCNMI_MASK_EN_Pos (0U) +#define SBS_ECCNMIR_ECCNMI_MASK_EN_Msk (0x1UL << SBS_ECCNMIR_ECCNMI_MASK_EN_Pos) /*!< 0x00000001 */ +#define SBS_ECCNMIR_ECCNMI_MASK_EN SBS_ECCNMIR_ECCNMI_MASK_EN_Msk /*!< Disable NMI in case of double ECC error in flash interface */ + +/*****************************************************************************/ +/* */ +/* Global TrustZone Control */ +/* */ +/*****************************************************************************/ + +/******************* Bits definition for GTZC_TZSC_MPCWM_CFGR register **********/ +#define GTZC_TZSC_MPCWM_CFGR_SREN_Pos (0U) +#define GTZC_TZSC_MPCWM_CFGR_SREN_Msk (0x1UL << GTZC_TZSC_MPCWM_CFGR_SREN_Pos) +#define GTZC_TZSC_MPCWM_CFGR_SREN GTZC_TZSC_MPCWM_CFGR_SREN_Msk +#define GTZC_TZSC_MPCWM_CFGR_SRLOCK_Pos (1U) +#define GTZC_TZSC_MPCWM_CFGR_SRLOCK_Msk (0x1UL << GTZC_TZSC_MPCWM_CFGR_SRLOCK_Pos) +#define GTZC_TZSC_MPCWM_CFGR_SRLOCK GTZC_TZSC_MPCWM_CFGR_SRLOCK_Msk +#define GTZC_TZSC_MPCWM_CFGR_PRIV_Pos (9U) +#define GTZC_TZSC_MPCWM_CFGR_PRIV_Msk (0x1UL << GTZC_TZSC_MPCWM_CFGR_PRIV_Pos) +#define GTZC_TZSC_MPCWM_CFGR_PRIV GTZC_TZSC_MPCWM_CFGR_PRIV_Msk + +/******************* Bits definition for GTZC_TZSC_MPCWMR register **************/ +#define GTZC_TZSC_MPCWMR_SUBZ_START_Pos (0U) +#define GTZC_TZSC_MPCWMR_SUBZ_START_Msk (0x7FFUL << GTZC_TZSC_MPCWMR_SUBZ_START_Pos) +#define GTZC_TZSC_MPCWMR_SUBZ_START GTZC_TZSC_MPCWMR_SUBZ_START_Msk +#define GTZC_TZSC_MPCWMR_SUBZ_LENGTH_Pos (16U) +#define GTZC_TZSC_MPCWMR_SUBZ_LENGTH_Msk (0xFFFUL << GTZC_TZSC_MPCWMR_SUBZ_LENGTH_Pos) +#define GTZC_TZSC_MPCWMR_SUBZ_LENGTH GTZC_TZSC_MPCWMR_SUBZ_LENGTH_Msk + +/******* Bits definition for TZSC _SECCFGRx/_PRIVCFGRx registers *****/ +/******* Bits definition for TZIC _IERx/_SRx/_IFCRx registers ********/ + +/*************** Bits definition for register x=1 (TZSC1) *************/ +#define GTZC_CFGR1_TIM2_Pos (0U) +#define GTZC_CFGR1_TIM2_Msk (0x01UL << GTZC_CFGR1_TIM2_Pos) +#define GTZC_CFGR1_TIM3_Pos (1U) +#define GTZC_CFGR1_TIM3_Msk (0x01UL << GTZC_CFGR1_TIM3_Pos) +#define GTZC_CFGR1_TIM6_Pos (4U) +#define GTZC_CFGR1_TIM6_Msk (0x01UL << GTZC_CFGR1_TIM6_Pos) +#define GTZC_CFGR1_TIM7_Pos (5U) +#define GTZC_CFGR1_TIM7_Msk (0x01UL << GTZC_CFGR1_TIM7_Pos) +#define GTZC_CFGR1_WWDG_Pos (9U) +#define GTZC_CFGR1_WWDG_Msk (0x01UL << GTZC_CFGR1_WWDG_Pos) +#define GTZC_CFGR1_IWDG_Pos (10U) +#define GTZC_CFGR1_IWDG_Msk (0x01UL << GTZC_CFGR1_IWDG_Pos) +#define GTZC_CFGR1_SPI2_Pos (11U) +#define GTZC_CFGR1_SPI2_Msk (0x01UL << GTZC_CFGR1_SPI2_Pos) +#define GTZC_CFGR1_SPI3_Pos (12U) +#define GTZC_CFGR1_SPI3_Msk (0x01UL << GTZC_CFGR1_SPI3_Pos) +#define GTZC_CFGR1_USART2_Pos (13U) +#define GTZC_CFGR1_USART2_Msk (0x01UL << GTZC_CFGR1_USART2_Pos) +#define GTZC_CFGR1_USART3_Pos (14U) +#define GTZC_CFGR1_USART3_Msk (0x01UL << GTZC_CFGR1_USART3_Pos) +#define GTZC_CFGR1_I2C1_Pos (17U) +#define GTZC_CFGR1_I2C1_Msk (0x01UL << GTZC_CFGR1_I2C1_Pos) +#define GTZC_CFGR1_I2C2_Pos (18U) +#define GTZC_CFGR1_I2C2_Msk (0x01UL << GTZC_CFGR1_I2C2_Pos) +#define GTZC_CFGR1_I3C1_Pos (19U) +#define GTZC_CFGR1_I3C1_Msk (0x01UL << GTZC_CFGR1_I3C1_Pos) +#define GTZC_CFGR1_CRS_Pos (20U) +#define GTZC_CFGR1_CRS_Msk (0x01UL << GTZC_CFGR1_CRS_Pos) +#define GTZC_CFGR1_DAC1_Pos (25U) +#define GTZC_CFGR1_DAC1_Msk (0x01UL << GTZC_CFGR1_DAC1_Pos) +#define GTZC_CFGR1_DTS_Pos (30U) +#define GTZC_CFGR1_DTS_Msk (0x01UL << GTZC_CFGR1_DTS_Pos) +#define GTZC_CFGR1_LPTIM2_Pos (31U) +#define GTZC_CFGR1_LPTIM2_Msk (0x01UL << GTZC_CFGR1_LPTIM2_Pos) + + +/*************** Bits definition for register x=2 (TZSC1) *************/ +#define GTZC_CFGR2_FDCAN1_Pos (0U) +#define GTZC_CFGR2_FDCAN1_Msk (0x01UL << GTZC_CFGR2_FDCAN1_Pos) +#define GTZC_CFGR2_OPAMP_Pos (3U) +#define GTZC_CFGR2_OPAMP_Msk (0x01UL << GTZC_CFGR2_OPAMP_Pos) +#define GTZC_CFGR2_COMP_Pos (4U) +#define GTZC_CFGR2_COMP_Msk (0x01UL << GTZC_CFGR2_COMP_Pos) +#define GTZC_CFGR2_TIM1_Pos (8U) +#define GTZC_CFGR2_TIM1_Msk (0x01UL << GTZC_CFGR2_TIM1_Pos) +#define GTZC_CFGR2_SPI1_Pos (9U) +#define GTZC_CFGR2_SPI1_Msk (0x01UL << GTZC_CFGR2_SPI1_Pos) +#define GTZC_CFGR2_USART1_Pos (11U) +#define GTZC_CFGR2_USART1_Msk (0x01UL << GTZC_CFGR2_USART1_Pos) +#define GTZC_CFGR2_USB_Pos (19U) +#define GTZC_CFGR2_USB_Msk (0x01UL << GTZC_CFGR2_USB_Pos) +#define GTZC_CFGR2_LPUART1_Pos (25U) +#define GTZC_CFGR2_LPUART1_Msk (0x01UL << GTZC_CFGR2_LPUART1_Pos) +#define GTZC_CFGR2_LPTIM1_Pos (28U) +#define GTZC_CFGR2_LPTIM1_Msk (0x01UL << GTZC_CFGR2_LPTIM1_Pos) + +/*************** Bits definition for register x=3 (TZSC1) *************/ +#define GTZC_CFGR3_I3C2_Pos (2U) +#define GTZC_CFGR3_I3C2_Msk (0x01UL << GTZC_CFGR3_I3C2_Pos) +#define GTZC_CFGR3_CRC_Pos (8U) +#define GTZC_CFGR3_CRC_Msk (0x01UL << GTZC_CFGR3_CRC_Pos) +#define GTZC_CFGR3_ICACHE_REG_Pos (12U) +#define GTZC_CFGR3_ICACHE_REG_Msk (0x01UL << GTZC_CFGR3_ICACHE_REG_Pos) +#define GTZC_CFGR3_ADC_Pos (14U) +#define GTZC_CFGR3_ADC_Msk (0x01UL << GTZC_CFGR3_ADC_Pos) +#define GTZC_CFGR3_HASH_Pos (17U) +#define GTZC_CFGR3_HASH_Msk (0x01UL << GTZC_CFGR3_HASH_Pos) +#define GTZC_CFGR3_RNG_Pos (18U) +#define GTZC_CFGR3_RNG_Msk (0x01UL << GTZC_CFGR3_RNG_Pos) +#define GTZC_CFGR3_RAMCFG_Pos (26U) +#define GTZC_CFGR3_RAMCFG_Msk (0x01UL << GTZC_CFGR3_RAMCFG_Pos) + +/*************** Bits definition for register x=4 (TZSC1) *************/ +#define GTZC_CFGR4_GPDMA1_Pos (0U) +#define GTZC_CFGR4_GPDMA1_Msk (0x01UL << GTZC_CFGR4_GPDMA1_Pos) +#define GTZC_CFGR4_GPDMA2_Pos (1U) +#define GTZC_CFGR4_GPDMA2_Msk (0x01UL << GTZC_CFGR4_GPDMA2_Pos) +#define GTZC_CFGR4_FLASH_Pos (2U) +#define GTZC_CFGR4_FLASH_Msk (0x01UL << GTZC_CFGR4_FLASH_Pos) +#define GTZC_CFGR4_FLASH_REG_Pos (3U) +#define GTZC_CFGR4_FLASH_REG_Msk (0x01UL << GTZC_CFGR4_FLASH_REG_Pos) +#define GTZC_CFGR4_SBS_Pos (6U) +#define GTZC_CFGR4_SBS_Msk (0x01UL << GTZC_CFGR4_SBS_Pos) +#define GTZC_CFGR4_RTC_Pos (7U) +#define GTZC_CFGR4_RTC_Msk (0x01UL << GTZC_CFGR4_RTC_Pos) +#define GTZC_CFGR4_TAMP_Pos (8U) +#define GTZC_CFGR4_TAMP_Msk (0x01UL << GTZC_CFGR4_TAMP_Pos) +#define GTZC_CFGR4_PWR_Pos (9U) +#define GTZC_CFGR4_PWR_Msk (0x01UL << GTZC_CFGR4_PWR_Pos) +#define GTZC_CFGR4_RCC_Pos (10U) +#define GTZC_CFGR4_RCC_Msk (0x01UL << GTZC_CFGR4_RCC_Pos) +#define GTZC_CFGR4_EXTI_Pos (11U) +#define GTZC_CFGR4_EXTI_Msk (0x01UL << GTZC_CFGR4_EXTI_Pos) +#define GTZC_CFGR4_TZSC_Pos (16U) +#define GTZC_CFGR4_TZSC_Msk (0x01UL << GTZC_CFGR4_TZSC_Pos) +#define GTZC_CFGR4_BKPSRAM_Pos (20U) +#define GTZC_CFGR4_BKPSRAM_Msk (0x01UL << GTZC_CFGR4_BKPSRAM_Pos) +#define GTZC_CFGR4_SRAM1_Pos (24U) +#define GTZC_CFGR4_SRAM1_Msk (0x01UL << GTZC_CFGR4_SRAM1_Pos) +#define GTZC_CFGR4_MPCBB1_REG_Pos (25U) +#define GTZC_CFGR4_MPCBB1_REG_Msk (0x01UL << GTZC_CFGR4_MPCBB1_REG_Pos) +#define GTZC_CFGR4_SRAM2_Pos (26U) +#define GTZC_CFGR4_SRAM2_Msk (0x01UL << GTZC_CFGR4_SRAM2_Pos) +#define GTZC_CFGR4_MPCBB2_REG_Pos (27U) +#define GTZC_CFGR4_MPCBB2_REG_Msk (0x01UL << GTZC_CFGR4_MPCBB2_REG_Pos) + + +/******************* Bits definition for GTZC_TZSC_PRIVCFGR1 register ***************/ +#define GTZC_TZSC1_PRIVCFGR1_TIM2_Pos GTZC_CFGR1_TIM2_Pos +#define GTZC_TZSC1_PRIVCFGR1_TIM2_Msk GTZC_CFGR1_TIM2_Msk +#define GTZC_TZSC1_PRIVCFGR1_TIM3_Pos GTZC_CFGR1_TIM3_Pos +#define GTZC_TZSC1_PRIVCFGR1_TIM3_Msk GTZC_CFGR1_TIM3_Msk +#define GTZC_TZSC1_PRIVCFGR1_TIM6_Pos GTZC_CFGR1_TIM6_Pos +#define GTZC_TZSC1_PRIVCFGR1_TIM6_Msk GTZC_CFGR1_TIM6_Msk +#define GTZC_TZSC1_PRIVCFGR1_TIM7_Pos GTZC_CFGR1_TIM7_Pos +#define GTZC_TZSC1_PRIVCFGR1_TIM7_Msk GTZC_CFGR1_TIM7_Msk +#define GTZC_TZSC1_PRIVCFGR1_WWDG_Pos GTZC_CFGR1_WWDG_Pos +#define GTZC_TZSC1_PRIVCFGR1_WWDG_Msk GTZC_CFGR1_WWDG_Msk +#define GTZC_TZSC1_PRIVCFGR1_IWDG_Pos GTZC_CFGR1_IWDG_Pos +#define GTZC_TZSC1_PRIVCFGR1_IWDG_Msk GTZC_CFGR1_IWDG_Msk +#define GTZC_TZSC1_PRIVCFGR1_SPI2_Pos GTZC_CFGR1_SPI2_Pos +#define GTZC_TZSC1_PRIVCFGR1_SPI2_Msk GTZC_CFGR1_SPI2_Msk +#define GTZC_TZSC1_PRIVCFGR1_SPI3_Pos GTZC_CFGR1_SPI3_Pos +#define GTZC_TZSC1_PRIVCFGR1_SPI3_Msk GTZC_CFGR1_SPI3_Msk +#define GTZC_TZSC1_PRIVCFGR1_I2C1_Pos GTZC_CFGR1_I2C1_Pos +#define GTZC_TZSC1_PRIVCFGR1_I2C1_Msk GTZC_CFGR1_I2C1_Msk +#define GTZC_TZSC1_PRIVCFGR1_I2C2_Pos GTZC_CFGR1_I2C2_Pos +#define GTZC_TZSC1_PRIVCFGR1_I2C2_Msk GTZC_CFGR1_I2C2_Msk +#define GTZC_TZSC1_PRIVCFGR1_I3C1_Pos GTZC_CFGR1_I3C1_Pos +#define GTZC_TZSC1_PRIVCFGR1_I3C1_Msk GTZC_CFGR1_I3C1_Msk +#define GTZC_TZSC1_PRIVCFGR1_CRS_Pos GTZC_CFGR1_CRS_Pos +#define GTZC_TZSC1_PRIVCFGR1_CRS_Msk GTZC_CFGR1_CRS_Msk +#define GTZC_TZSC1_PRIVCFGR1_DAC1_Pos GTZC_CFGR1_DAC1_Pos +#define GTZC_TZSC1_PRIVCFGR1_DAC1_Msk GTZC_CFGR1_DAC1_Msk +#define GTZC_TZSC1_PRIVCFGR1_DTS_Pos GTZC_CFGR1_DTS_Pos +#define GTZC_TZSC1_PRIVCFGR1_DTS_Msk GTZC_CFGR1_DTS_Msk +#define GTZC_TZSC1_PRIVCFGR1_LPTIM2_Pos GTZC_CFGR1_LPTIM2_Pos +#define GTZC_TZSC1_PRIVCFGR1_LPTIM2_Msk GTZC_CFGR1_LPTIM2_Msk + +/******************* Bits definition for GTZC_TZSC_PRIVCFGR2 register ***************/ +#define GTZC_TZSC1_PRIVCFGR2_FDCAN1_Pos GTZC_CFGR2_FDCAN1_Pos +#define GTZC_TZSC1_PRIVCFGR2_FDCAN1_Msk GTZC_CFGR2_FDCAN1_Msk +#define GTZC_TZSC1_PRIVCFGR2_TIM1_Pos GTZC_CFGR2_TIM1_Pos +#define GTZC_TZSC1_PRIVCFGR2_TIM1_Msk GTZC_CFGR2_TIM1_Msk +#define GTZC_TZSC1_PRIVCFGR2_SPI1_Pos GTZC_CFGR2_SPI1_Pos +#define GTZC_TZSC1_PRIVCFGR2_SPI1_Msk GTZC_CFGR2_SPI1_Msk +#define GTZC_TZSC1_PRIVCFGR2_USART1_Pos GTZC_CFGR2_USART1_Pos +#define GTZC_TZSC1_PRIVCFGR2_USART1_Msk GTZC_CFGR2_USART1_Msk +#define GTZC_TZSC1_PRIVCFGR2_USB_Pos GTZC_CFGR2_USB_Pos +#define GTZC_TZSC1_PRIVCFGR2_USB_Msk GTZC_CFGR2_USB_Msk +#define GTZC_TZSC1_PRIVCFGR2_LPUART1_Pos GTZC_CFGR2_LPUART1_Pos +#define GTZC_TZSC1_PRIVCFGR2_LPUART1_Msk GTZC_CFGR2_LPUART1_Msk +#define GTZC_TZSC1_PRIVCFGR2_LPTIM1_Pos GTZC_CFGR2_LPTIM1_Pos +#define GTZC_TZSC1_PRIVCFGR2_LPTIM1_Msk GTZC_CFGR2_LPTIM1_Msk + +/******************* Bits definition for GTZC_TZSC_PRIVCFGR3 register ***************/ +#define GTZC_TZSC1_PRIVCFGR3_CRC_Pos GTZC_CFGR3_CRC_Pos +#define GTZC_TZSC1_PRIVCFGR3_CRC_Msk GTZC_CFGR3_CRC_Msk +#define GTZC_TZSC1_PRIVCFGR3_ICACHE_REG_Pos GTZC_CFGR3_ICACHE_REG_Pos +#define GTZC_TZSC1_PRIVCFGR3_ICACHE_REG_Msk GTZC_CFGR3_ICACHE_REG_Msk +#define GTZC_TZSC1_PRIVCFGR3_ADC_Pos GTZC_CFGR3_ADC_Pos +#define GTZC_TZSC1_PRIVCFGR3_ADC_Msk GTZC_CFGR3_ADC_Msk +#define GTZC_TZSC1_PRIVCFGR3_HASH_Pos GTZC_CFGR3_HASH_Pos +#define GTZC_TZSC1_PRIVCFGR3_HASH_Msk GTZC_CFGR3_HASH_Msk +#define GTZC_TZSC1_PRIVCFGR3_RNG_Pos GTZC_CFGR3_RNG_Pos +#define GTZC_TZSC1_PRIVCFGR3_RNG_Msk GTZC_CFGR3_RNG_Msk +#define GTZC_TZSC1_PRIVCFGR3_RAMCFG_Pos GTZC_CFGR3_RAMCFG_Pos +#define GTZC_TZSC1_PRIVCFGR3_RAMCFG_Msk GTZC_CFGR3_RAMCFG_Msk + + +/******************* Bits definition for GTZC_MPCBB_CR register *****************/ +#define GTZC_MPCBB_CR_GLOCK_Pos (0U) +#define GTZC_MPCBB_CR_GLOCK_Msk (0x01UL << GTZC_MPCBB_CR_GLOCK_Pos) /*!< 0x00000001 */ +#define GTZC_MPCBB_CR_INVSECSTATE_Pos (30U) +#define GTZC_MPCBB_CR_INVSECSTATE_Msk (0x01UL << GTZC_MPCBB_CR_INVSECSTATE_Pos) /*!< 0x40000000 */ +#define GTZC_MPCBB_CR_SRWILADIS_Pos (31U) +#define GTZC_MPCBB_CR_SRWILADIS_Msk (0x01UL << GTZC_MPCBB_CR_SRWILADIS_Pos) /*!< 0x80000000 */ + +/******************* Bits definition for GTZC_MPCBB_CFGLOCKR1 register ************/ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK0_Pos (0U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK0_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK0_Pos) /*!< 0x00000001 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK1_Pos (1U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK1_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK1_Pos) /*!< 0x00000002 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK2_Pos (2U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK2_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK2_Pos) /*!< 0x00000004 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK3_Pos (3U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK3_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK3_Pos) /*!< 0x00000008 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK4_Pos (4U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK4_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK4_Pos) /*!< 0x00000010 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK5_Pos (5U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK5_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK5_Pos) /*!< 0x00000020 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK6_Pos (6U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK6_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK6_Pos) /*!< 0x00000040 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK7_Pos (7U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK7_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK7_Pos) /*!< 0x00000080 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK8_Pos (8U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK8_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK8_Pos) /*!< 0x00000100 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK9_Pos (9U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK9_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK9_Pos) /*!< 0x00000200 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK10_Pos (10U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK10_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK10_Pos) /*!< 0x00000400 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK11_Pos (11U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK11_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK11_Pos) /*!< 0x00000800 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK12_Pos (12U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK12_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK12_Pos) /*!< 0x00001000 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK13_Pos (13U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK13_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK13_Pos) /*!< 0x00002000 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK14_Pos (14U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK14_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK14_Pos) /*!< 0x00004000 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK15_Pos (15U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK15_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK15_Pos) /*!< 0x00008000 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK16_Pos (16U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK16_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK16_Pos) /*!< 0x00010000 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK17_Pos (17U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK17_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK17_Pos) /*!< 0x00020000 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK18_Pos (18U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK18_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK18_Pos) /*!< 0x00040000 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK19_Pos (19U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK19_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK19_Pos) /*!< 0x00080000 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK20_Pos (20U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK20_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK20_Pos) /*!< 0x00100000 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK21_Pos (21U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK21_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK21_Pos) /*!< 0x00200000 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK22_Pos (22U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK22_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK22_Pos) /*!< 0x00400000 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK23_Pos (23U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK23_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK23_Pos) /*!< 0x00800000 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK24_Pos (24U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK24_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK24_Pos) /*!< 0x01000000 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK25_Pos (25U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK25_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK25_Pos) /*!< 0x02000000 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK26_Pos (26U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK26_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK26_Pos) /*!< 0x04000000 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK27_Pos (27U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK27_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK27_Pos) /*!< 0x08000000 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK28_Pos (28U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK28_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK28_Pos) /*!< 0x10000000 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK29_Pos (29U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK29_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK29_Pos) /*!< 0x20000000 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK30_Pos (30U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK30_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK30_Pos) /*!< 0x40000000 */ +#define GTZC_MPCBB_CFGLOCKR1_SPLCK31_Pos (31U) +#define GTZC_MPCBB_CFGLOCKR1_SPLCK31_Msk (0x01UL << GTZC_MPCBB_CFGLOCKR1_SPLCK31_Pos) /*!< 0x80000000 */ + + + +/******************************************************************************/ +/* */ +/* Universal Synchronous Asynchronous Receiver Transmitter (USART) */ +/* */ +/******************************************************************************/ +/****************** Bit definition for USART_CR1 register *******************/ +#define USART_CR1_UE_Pos (0U) +#define USART_CR1_UE_Msk (0x1UL << USART_CR1_UE_Pos) /*!< 0x00000001 */ +#define USART_CR1_UE USART_CR1_UE_Msk /*!< USART Enable */ +#define USART_CR1_UESM_Pos (1U) +#define USART_CR1_UESM_Msk (0x1UL << USART_CR1_UESM_Pos) /*!< 0x00000002 */ +#define USART_CR1_UESM USART_CR1_UESM_Msk /*!< USART Enable in STOP Mode */ +#define USART_CR1_RE_Pos (2U) +#define USART_CR1_RE_Msk (0x1UL << USART_CR1_RE_Pos) /*!< 0x00000004 */ +#define USART_CR1_RE USART_CR1_RE_Msk /*!< Receiver Enable */ +#define USART_CR1_TE_Pos (3U) +#define USART_CR1_TE_Msk (0x1UL << USART_CR1_TE_Pos) /*!< 0x00000008 */ +#define USART_CR1_TE USART_CR1_TE_Msk /*!< Transmitter Enable */ +#define USART_CR1_IDLEIE_Pos (4U) +#define USART_CR1_IDLEIE_Msk (0x1UL << USART_CR1_IDLEIE_Pos) /*!< 0x00000010 */ +#define USART_CR1_IDLEIE USART_CR1_IDLEIE_Msk /*!< IDLE Interrupt Enable */ +#define USART_CR1_RXNEIE_Pos (5U) +#define USART_CR1_RXNEIE_Msk (0x1UL << USART_CR1_RXNEIE_Pos) /*!< 0x00000020 */ +#define USART_CR1_RXNEIE USART_CR1_RXNEIE_Msk /*!< RXNE Interrupt Enable */ +#define USART_CR1_RXNEIE_RXFNEIE_Pos USART_CR1_RXNEIE_Pos +#define USART_CR1_RXNEIE_RXFNEIE_Msk USART_CR1_RXNEIE_Msk /*!< 0x00000020 */ +#define USART_CR1_RXNEIE_RXFNEIE USART_CR1_RXNEIE_Msk /*!< RXNE and RX FIFO Not Empty Interrupt Enable */ +#define USART_CR1_TCIE_Pos (6U) +#define USART_CR1_TCIE_Msk (0x1UL << USART_CR1_TCIE_Pos) /*!< 0x00000040 */ +#define USART_CR1_TCIE USART_CR1_TCIE_Msk /*!< Transmission Complete Interrupt Enable */ +#define USART_CR1_TXEIE_Pos (7U) +#define USART_CR1_TXEIE_Msk (0x1UL << USART_CR1_TXEIE_Pos) /*!< 0x00000080 */ +#define USART_CR1_TXEIE USART_CR1_TXEIE_Msk /*!< TXE Interrupt Enable */ +#define USART_CR1_TXEIE_TXFNFIE_Pos (7U) +#define USART_CR1_TXEIE_TXFNFIE_Msk (0x1UL << USART_CR1_TXEIE_Pos) /*!< 0x00000080 */ +#define USART_CR1_TXEIE_TXFNFIE USART_CR1_TXEIE /*!< TXE and TX FIFO Not Full Interrupt Enable */ +#define USART_CR1_PEIE_Pos (8U) +#define USART_CR1_PEIE_Msk (0x1UL << USART_CR1_PEIE_Pos) /*!< 0x00000100 */ +#define USART_CR1_PEIE USART_CR1_PEIE_Msk /*!< PE Interrupt Enable */ +#define USART_CR1_PS_Pos (9U) +#define USART_CR1_PS_Msk (0x1UL << USART_CR1_PS_Pos) /*!< 0x00000200 */ +#define USART_CR1_PS USART_CR1_PS_Msk /*!< Parity Selection */ +#define USART_CR1_PCE_Pos (10U) +#define USART_CR1_PCE_Msk (0x1UL << USART_CR1_PCE_Pos) /*!< 0x00000400 */ +#define USART_CR1_PCE USART_CR1_PCE_Msk /*!< Parity Control Enable */ +#define USART_CR1_WAKE_Pos (11U) +#define USART_CR1_WAKE_Msk (0x1UL << USART_CR1_WAKE_Pos) /*!< 0x00000800 */ +#define USART_CR1_WAKE USART_CR1_WAKE_Msk /*!< Receiver Wakeup method */ +#define USART_CR1_M_Pos (12U) +#define USART_CR1_M_Msk (0x10001UL << USART_CR1_M_Pos) /*!< 0x10001000 */ +#define USART_CR1_M USART_CR1_M_Msk /*!< Word length */ +#define USART_CR1_M0_Pos (12U) +#define USART_CR1_M0_Msk (0x1UL << USART_CR1_M0_Pos) /*!< 0x00001000 */ +#define USART_CR1_M0 USART_CR1_M0_Msk /*!< Word length - Bit 0 */ +#define USART_CR1_MME_Pos (13U) +#define USART_CR1_MME_Msk (0x1UL << USART_CR1_MME_Pos) /*!< 0x00002000 */ +#define USART_CR1_MME USART_CR1_MME_Msk /*!< Mute Mode Enable */ +#define USART_CR1_CMIE_Pos (14U) +#define USART_CR1_CMIE_Msk (0x1UL << USART_CR1_CMIE_Pos) /*!< 0x00004000 */ +#define USART_CR1_CMIE USART_CR1_CMIE_Msk /*!< Character match interrupt enable */ +#define USART_CR1_OVER8_Pos (15U) +#define USART_CR1_OVER8_Msk (0x1UL << USART_CR1_OVER8_Pos) /*!< 0x00008000 */ +#define USART_CR1_OVER8 USART_CR1_OVER8_Msk /*!< Oversampling by 8-bit or 16-bit mode */ +#define USART_CR1_DEDT_Pos (16U) +#define USART_CR1_DEDT_Msk (0x1FUL << USART_CR1_DEDT_Pos) /*!< 0x001F0000 */ +#define USART_CR1_DEDT USART_CR1_DEDT_Msk /*!< DEDT[4:0] bits (Driver Enable Deassertion Time) */ +#define USART_CR1_DEDT_0 (0x01UL << USART_CR1_DEDT_Pos) /*!< 0x00010000 */ +#define USART_CR1_DEDT_1 (0x02UL << USART_CR1_DEDT_Pos) /*!< 0x00020000 */ +#define USART_CR1_DEDT_2 (0x04UL << USART_CR1_DEDT_Pos) /*!< 0x00040000 */ +#define USART_CR1_DEDT_3 (0x08UL << USART_CR1_DEDT_Pos) /*!< 0x00080000 */ +#define USART_CR1_DEDT_4 (0x10UL << USART_CR1_DEDT_Pos) /*!< 0x00100000 */ +#define USART_CR1_DEAT_Pos (21U) +#define USART_CR1_DEAT_Msk (0x1FUL << USART_CR1_DEAT_Pos) /*!< 0x03E00000 */ +#define USART_CR1_DEAT USART_CR1_DEAT_Msk /*!< DEAT[4:0] bits (Driver Enable Assertion Time) */ +#define USART_CR1_DEAT_0 (0x01UL << USART_CR1_DEAT_Pos) /*!< 0x00200000 */ +#define USART_CR1_DEAT_1 (0x02UL << USART_CR1_DEAT_Pos) /*!< 0x00400000 */ +#define USART_CR1_DEAT_2 (0x04UL << USART_CR1_DEAT_Pos) /*!< 0x00800000 */ +#define USART_CR1_DEAT_3 (0x08UL << USART_CR1_DEAT_Pos) /*!< 0x01000000 */ +#define USART_CR1_DEAT_4 (0x10UL << USART_CR1_DEAT_Pos) /*!< 0x02000000 */ +#define USART_CR1_RTOIE_Pos (26U) +#define USART_CR1_RTOIE_Msk (0x1UL << USART_CR1_RTOIE_Pos) /*!< 0x04000000 */ +#define USART_CR1_RTOIE USART_CR1_RTOIE_Msk /*!< Receive Time Out interrupt enable */ +#define USART_CR1_EOBIE_Pos (27U) +#define USART_CR1_EOBIE_Msk (0x1UL << USART_CR1_EOBIE_Pos) /*!< 0x08000000 */ +#define USART_CR1_EOBIE USART_CR1_EOBIE_Msk /*!< End of Block interrupt enable */ +#define USART_CR1_M1_Pos (28U) +#define USART_CR1_M1_Msk (0x1UL << USART_CR1_M1_Pos) /*!< 0x10000000 */ +#define USART_CR1_M1 USART_CR1_M1_Msk /*!< Word length - Bit 1 */ +#define USART_CR1_FIFOEN_Pos (29U) +#define USART_CR1_FIFOEN_Msk (0x1UL << USART_CR1_FIFOEN_Pos) /*!< 0x20000000 */ +#define USART_CR1_FIFOEN USART_CR1_FIFOEN_Msk /*!< FIFO mode enable */ +#define USART_CR1_TXFEIE_Pos (30U) +#define USART_CR1_TXFEIE_Msk (0x1UL << USART_CR1_TXFEIE_Pos) /*!< 0x40000000 */ +#define USART_CR1_TXFEIE USART_CR1_TXFEIE_Msk /*!< TXFIFO empty interrupt enable */ +#define USART_CR1_RXFFIE_Pos (31U) +#define USART_CR1_RXFFIE_Msk (0x1UL << USART_CR1_RXFFIE_Pos) /*!< 0x80000000 */ +#define USART_CR1_RXFFIE USART_CR1_RXFFIE_Msk /*!< RXFIFO Full interrupt enable */ + +/****************** Bit definition for USART_CR2 register *******************/ +#define USART_CR2_SLVEN_Pos (0U) +#define USART_CR2_SLVEN_Msk (0x1UL << USART_CR2_SLVEN_Pos) /*!< 0x00000001 */ +#define USART_CR2_SLVEN USART_CR2_SLVEN_Msk /*!< Synchronous Slave mode enable */ +#define USART_CR2_DIS_NSS_Pos (3U) +#define USART_CR2_DIS_NSS_Msk (0x1UL << USART_CR2_DIS_NSS_Pos) /*!< 0x00000008 */ +#define USART_CR2_DIS_NSS USART_CR2_DIS_NSS_Msk /*!< Slave Select (NSS) pin management */ +#define USART_CR2_ADDM7_Pos (4U) +#define USART_CR2_ADDM7_Msk (0x1UL << USART_CR2_ADDM7_Pos) /*!< 0x00000010 */ +#define USART_CR2_ADDM7 USART_CR2_ADDM7_Msk /*!< 7-bit or 4-bit Address Detection */ +#define USART_CR2_LBDL_Pos (5U) +#define USART_CR2_LBDL_Msk (0x1UL << USART_CR2_LBDL_Pos) /*!< 0x00000020 */ +#define USART_CR2_LBDL USART_CR2_LBDL_Msk /*!< LIN Break Detection Length */ +#define USART_CR2_LBDIE_Pos (6U) +#define USART_CR2_LBDIE_Msk (0x1UL << USART_CR2_LBDIE_Pos) /*!< 0x00000040 */ +#define USART_CR2_LBDIE USART_CR2_LBDIE_Msk /*!< LIN Break Detection Interrupt Enable */ +#define USART_CR2_LBCL_Pos (8U) +#define USART_CR2_LBCL_Msk (0x1UL << USART_CR2_LBCL_Pos) /*!< 0x00000100 */ +#define USART_CR2_LBCL USART_CR2_LBCL_Msk /*!< Last Bit Clock pulse */ +#define USART_CR2_CPHA_Pos (9U) +#define USART_CR2_CPHA_Msk (0x1UL << USART_CR2_CPHA_Pos) /*!< 0x00000200 */ +#define USART_CR2_CPHA USART_CR2_CPHA_Msk /*!< Clock Phase */ +#define USART_CR2_CPOL_Pos (10U) +#define USART_CR2_CPOL_Msk (0x1UL << USART_CR2_CPOL_Pos) /*!< 0x00000400 */ +#define USART_CR2_CPOL USART_CR2_CPOL_Msk /*!< Clock Polarity */ +#define USART_CR2_CLKEN_Pos (11U) +#define USART_CR2_CLKEN_Msk (0x1UL << USART_CR2_CLKEN_Pos) /*!< 0x00000800 */ +#define USART_CR2_CLKEN USART_CR2_CLKEN_Msk /*!< Clock Enable */ +#define USART_CR2_STOP_Pos (12U) +#define USART_CR2_STOP_Msk (0x3UL << USART_CR2_STOP_Pos) /*!< 0x00003000 */ +#define USART_CR2_STOP USART_CR2_STOP_Msk /*!< STOP[1:0] bits (STOP bits) */ +#define USART_CR2_STOP_0 (0x1UL << USART_CR2_STOP_Pos) /*!< 0x00001000 */ +#define USART_CR2_STOP_1 (0x2UL << USART_CR2_STOP_Pos) /*!< 0x00002000 */ +#define USART_CR2_LINEN_Pos (14U) +#define USART_CR2_LINEN_Msk (0x1UL << USART_CR2_LINEN_Pos) /*!< 0x00004000 */ +#define USART_CR2_LINEN USART_CR2_LINEN_Msk /*!< LIN mode enable */ +#define USART_CR2_SWAP_Pos (15U) +#define USART_CR2_SWAP_Msk (0x1UL << USART_CR2_SWAP_Pos) /*!< 0x00008000 */ +#define USART_CR2_SWAP USART_CR2_SWAP_Msk /*!< SWAP TX/RX pins */ +#define USART_CR2_RXINV_Pos (16U) +#define USART_CR2_RXINV_Msk (0x1UL << USART_CR2_RXINV_Pos) /*!< 0x00010000 */ +#define USART_CR2_RXINV USART_CR2_RXINV_Msk /*!< RX pin active level inversion */ +#define USART_CR2_TXINV_Pos (17U) +#define USART_CR2_TXINV_Msk (0x1UL << USART_CR2_TXINV_Pos) /*!< 0x00020000 */ +#define USART_CR2_TXINV USART_CR2_TXINV_Msk /*!< TX pin active level inversion */ +#define USART_CR2_DATAINV_Pos (18U) +#define USART_CR2_DATAINV_Msk (0x1UL << USART_CR2_DATAINV_Pos) /*!< 0x00040000 */ +#define USART_CR2_DATAINV USART_CR2_DATAINV_Msk /*!< Binary data inversion */ +#define USART_CR2_MSBFIRST_Pos (19U) +#define USART_CR2_MSBFIRST_Msk (0x1UL << USART_CR2_MSBFIRST_Pos) /*!< 0x00080000 */ +#define USART_CR2_MSBFIRST USART_CR2_MSBFIRST_Msk /*!< Most Significant Bit First */ +#define USART_CR2_ABREN_Pos (20U) +#define USART_CR2_ABREN_Msk (0x1UL << USART_CR2_ABREN_Pos) /*!< 0x00100000 */ +#define USART_CR2_ABREN USART_CR2_ABREN_Msk /*!< Auto Baud-Rate Enable*/ +#define USART_CR2_ABRMODE_Pos (21U) +#define USART_CR2_ABRMODE_Msk (0x3UL << USART_CR2_ABRMODE_Pos) /*!< 0x00600000 */ +#define USART_CR2_ABRMODE USART_CR2_ABRMODE_Msk /*!< ABRMOD[1:0] bits (Auto Baud-Rate Mode) */ +#define USART_CR2_ABRMODE_0 (0x1UL << USART_CR2_ABRMODE_Pos) /*!< 0x00200000 */ +#define USART_CR2_ABRMODE_1 (0x2UL << USART_CR2_ABRMODE_Pos) /*!< 0x00400000 */ +#define USART_CR2_RTOEN_Pos (23U) +#define USART_CR2_RTOEN_Msk (0x1UL << USART_CR2_RTOEN_Pos) /*!< 0x00800000 */ +#define USART_CR2_RTOEN USART_CR2_RTOEN_Msk /*!< Receiver Time-Out enable */ +#define USART_CR2_ADD_Pos (24U) +#define USART_CR2_ADD_Msk (0xFFUL << USART_CR2_ADD_Pos) /*!< 0xFF000000 */ +#define USART_CR2_ADD USART_CR2_ADD_Msk /*!< Address of the USART node */ + +/****************** Bit definition for USART_CR3 register *******************/ +#define USART_CR3_EIE_Pos (0U) +#define USART_CR3_EIE_Msk (0x1UL << USART_CR3_EIE_Pos) /*!< 0x00000001 */ +#define USART_CR3_EIE USART_CR3_EIE_Msk /*!< Error Interrupt Enable */ +#define USART_CR3_IREN_Pos (1U) +#define USART_CR3_IREN_Msk (0x1UL << USART_CR3_IREN_Pos) /*!< 0x00000002 */ +#define USART_CR3_IREN USART_CR3_IREN_Msk /*!< IrDA mode Enable */ +#define USART_CR3_IRLP_Pos (2U) +#define USART_CR3_IRLP_Msk (0x1UL << USART_CR3_IRLP_Pos) /*!< 0x00000004 */ +#define USART_CR3_IRLP USART_CR3_IRLP_Msk /*!< IrDA Low-Power */ +#define USART_CR3_HDSEL_Pos (3U) +#define USART_CR3_HDSEL_Msk (0x1UL << USART_CR3_HDSEL_Pos) /*!< 0x00000008 */ +#define USART_CR3_HDSEL USART_CR3_HDSEL_Msk /*!< Half-Duplex Selection */ +#define USART_CR3_NACK_Pos (4U) +#define USART_CR3_NACK_Msk (0x1UL << USART_CR3_NACK_Pos) /*!< 0x00000010 */ +#define USART_CR3_NACK USART_CR3_NACK_Msk /*!< SmartCard NACK enable */ +#define USART_CR3_SCEN_Pos (5U) +#define USART_CR3_SCEN_Msk (0x1UL << USART_CR3_SCEN_Pos) /*!< 0x00000020 */ +#define USART_CR3_SCEN USART_CR3_SCEN_Msk /*!< SmartCard mode enable */ +#define USART_CR3_DMAR_Pos (6U) +#define USART_CR3_DMAR_Msk (0x1UL << USART_CR3_DMAR_Pos) /*!< 0x00000040 */ +#define USART_CR3_DMAR USART_CR3_DMAR_Msk /*!< DMA Enable Receiver */ +#define USART_CR3_DMAT_Pos (7U) +#define USART_CR3_DMAT_Msk (0x1UL << USART_CR3_DMAT_Pos) /*!< 0x00000080 */ +#define USART_CR3_DMAT USART_CR3_DMAT_Msk /*!< DMA Enable Transmitter */ +#define USART_CR3_RTSE_Pos (8U) +#define USART_CR3_RTSE_Msk (0x1UL << USART_CR3_RTSE_Pos) /*!< 0x00000100 */ +#define USART_CR3_RTSE USART_CR3_RTSE_Msk /*!< RTS Enable */ +#define USART_CR3_CTSE_Pos (9U) +#define USART_CR3_CTSE_Msk (0x1UL << USART_CR3_CTSE_Pos) /*!< 0x00000200 */ +#define USART_CR3_CTSE USART_CR3_CTSE_Msk /*!< CTS Enable */ +#define USART_CR3_CTSIE_Pos (10U) +#define USART_CR3_CTSIE_Msk (0x1UL << USART_CR3_CTSIE_Pos) /*!< 0x00000400 */ +#define USART_CR3_CTSIE USART_CR3_CTSIE_Msk /*!< CTS Interrupt Enable */ +#define USART_CR3_ONEBIT_Pos (11U) +#define USART_CR3_ONEBIT_Msk (0x1UL << USART_CR3_ONEBIT_Pos) /*!< 0x00000800 */ +#define USART_CR3_ONEBIT USART_CR3_ONEBIT_Msk /*!< One sample bit method enable */ +#define USART_CR3_OVRDIS_Pos (12U) +#define USART_CR3_OVRDIS_Msk (0x1UL << USART_CR3_OVRDIS_Pos) /*!< 0x00001000 */ +#define USART_CR3_OVRDIS USART_CR3_OVRDIS_Msk /*!< Overrun Disable */ +#define USART_CR3_DDRE_Pos (13U) +#define USART_CR3_DDRE_Msk (0x1UL << USART_CR3_DDRE_Pos) /*!< 0x00002000 */ +#define USART_CR3_DDRE USART_CR3_DDRE_Msk /*!< DMA Disable on Reception Error */ +#define USART_CR3_DEM_Pos (14U) +#define USART_CR3_DEM_Msk (0x1UL << USART_CR3_DEM_Pos) /*!< 0x00004000 */ +#define USART_CR3_DEM USART_CR3_DEM_Msk /*!< Driver Enable Mode */ +#define USART_CR3_DEP_Pos (15U) +#define USART_CR3_DEP_Msk (0x1UL << USART_CR3_DEP_Pos) /*!< 0x00008000 */ +#define USART_CR3_DEP USART_CR3_DEP_Msk /*!< Driver Enable Polarity Selection */ +#define USART_CR3_SCARCNT_Pos (17U) +#define USART_CR3_SCARCNT_Msk (0x7UL << USART_CR3_SCARCNT_Pos) /*!< 0x000E0000 */ +#define USART_CR3_SCARCNT USART_CR3_SCARCNT_Msk /*!< SCARCNT[2:0] bits (SmartCard Auto-Retry Count) */ +#define USART_CR3_SCARCNT_0 (0x1UL << USART_CR3_SCARCNT_Pos) /*!< 0x00020000 */ +#define USART_CR3_SCARCNT_1 (0x2UL << USART_CR3_SCARCNT_Pos) /*!< 0x00040000 */ +#define USART_CR3_SCARCNT_2 (0x4UL << USART_CR3_SCARCNT_Pos) /*!< 0x00080000 */ +#define USART_CR3_WUS_Pos (20U) +#define USART_CR3_WUS_Msk (0x3UL << USART_CR3_WUS_Pos) /*!< 0x00300000 */ +#define USART_CR3_WUS USART_CR3_WUS_Msk /*!< WUS[1:0] bits (Wake UP Interrupt Flag Selection) */ +#define USART_CR3_WUS_0 (0x1UL << USART_CR3_WUS_Pos) /*!< 0x00100000 */ +#define USART_CR3_WUS_1 (0x2UL << USART_CR3_WUS_Pos) /*!< 0x00200000 */ +#define USART_CR3_WUFIE_Pos (22U) +#define USART_CR3_WUFIE_Msk (0x1UL << USART_CR3_WUFIE_Pos) /*!< 0x00400000 */ +#define USART_CR3_WUFIE USART_CR3_WUFIE_Msk /*!< Wake Up Interrupt Enable */ +#define USART_CR3_TXFTIE_Pos (23U) +#define USART_CR3_TXFTIE_Msk (0x1UL << USART_CR3_TXFTIE_Pos) /*!< 0x00800000 */ +#define USART_CR3_TXFTIE USART_CR3_TXFTIE_Msk /*!< TXFIFO threshold interrupt enable */ +#define USART_CR3_TCBGTIE_Pos (24U) +#define USART_CR3_TCBGTIE_Msk (0x1UL << USART_CR3_TCBGTIE_Pos) /*!< 0x01000000 */ +#define USART_CR3_TCBGTIE USART_CR3_TCBGTIE_Msk /*!< Transmission Complete Before Guard Time Interrupt Enable */ +#define USART_CR3_RXFTCFG_Pos (25U) +#define USART_CR3_RXFTCFG_Msk (0x7UL << USART_CR3_RXFTCFG_Pos) /*!< 0x0E000000 */ +#define USART_CR3_RXFTCFG USART_CR3_RXFTCFG_Msk /*!< RXFIFO FIFO threshold configuration */ +#define USART_CR3_RXFTCFG_0 (0x1UL << USART_CR3_RXFTCFG_Pos) /*!< 0x02000000 */ +#define USART_CR3_RXFTCFG_1 (0x2UL << USART_CR3_RXFTCFG_Pos) /*!< 0x04000000 */ +#define USART_CR3_RXFTCFG_2 (0x4UL << USART_CR3_RXFTCFG_Pos) /*!< 0x08000000 */ +#define USART_CR3_RXFTIE_Pos (28U) +#define USART_CR3_RXFTIE_Msk (0x1UL << USART_CR3_RXFTIE_Pos) /*!< 0x10000000 */ +#define USART_CR3_RXFTIE USART_CR3_RXFTIE_Msk /*!< RXFIFO threshold interrupt enable */ +#define USART_CR3_TXFTCFG_Pos (29U) +#define USART_CR3_TXFTCFG_Msk (0x7UL << USART_CR3_TXFTCFG_Pos) /*!< 0xE0000000 */ +#define USART_CR3_TXFTCFG USART_CR3_TXFTCFG_Msk /*!< TXFIFO threshold configuration */ +#define USART_CR3_TXFTCFG_0 (0x1UL << USART_CR3_TXFTCFG_Pos) /*!< 0x20000000 */ +#define USART_CR3_TXFTCFG_1 (0x2UL << USART_CR3_TXFTCFG_Pos) /*!< 0x40000000 */ +#define USART_CR3_TXFTCFG_2 (0x4UL << USART_CR3_TXFTCFG_Pos) /*!< 0x80000000 */ + +/****************** Bit definition for USART_BRR register *******************/ +#define USART_BRR_LPUART_Pos (0U) +#define USART_BRR_LPUART_Msk (0xFFFFFUL << USART_BRR_LPUART_Pos) /*!< 0x000FFFFF */ +#define USART_BRR_LPUART USART_BRR_LPUART_Msk /*!< LPUART Baud rate register [19:0] */ +#define USART_BRR_BRR ((uint16_t)0xFFFF) /*!< USART Baud rate register [15:0] */ + +/****************** Bit definition for USART_GTPR register ******************/ +#define USART_GTPR_PSC_Pos (0U) +#define USART_GTPR_PSC_Msk (0xFFUL << USART_GTPR_PSC_Pos) /*!< 0x000000FF */ +#define USART_GTPR_PSC USART_GTPR_PSC_Msk /*!< PSC[7:0] bits (Prescaler value) */ +#define USART_GTPR_GT_Pos (8U) +#define USART_GTPR_GT_Msk (0xFFUL << USART_GTPR_GT_Pos) /*!< 0x0000FF00 */ +#define USART_GTPR_GT USART_GTPR_GT_Msk /*!< GT[7:0] bits (Guard time value) */ + +/******************* Bit definition for USART_RTOR register *****************/ +#define USART_RTOR_RTO_Pos (0U) +#define USART_RTOR_RTO_Msk (0xFFFFFFUL << USART_RTOR_RTO_Pos) /*!< 0x00FFFFFF */ +#define USART_RTOR_RTO USART_RTOR_RTO_Msk /*!< Receiver Time Out Value */ +#define USART_RTOR_BLEN_Pos (24U) +#define USART_RTOR_BLEN_Msk (0xFFUL << USART_RTOR_BLEN_Pos) /*!< 0xFF000000 */ +#define USART_RTOR_BLEN USART_RTOR_BLEN_Msk /*!< Block Length */ + +/******************* Bit definition for USART_RQR register ******************/ +#define USART_RQR_ABRRQ ((uint16_t)0x0001) /*!< Auto-Baud Rate Request */ +#define USART_RQR_SBKRQ ((uint16_t)0x0002) /*!< Send Break Request */ +#define USART_RQR_MMRQ ((uint16_t)0x0004) /*!< Mute Mode Request */ +#define USART_RQR_RXFRQ ((uint16_t)0x0008) /*!< Receive Data flush Request */ +#define USART_RQR_TXFRQ ((uint16_t)0x0010) /*!< Transmit data flush Request */ + +/******************* Bit definition for USART_ISR register ******************/ +#define USART_ISR_PE_Pos (0U) +#define USART_ISR_PE_Msk (0x1UL << USART_ISR_PE_Pos) /*!< 0x00000001 */ +#define USART_ISR_PE USART_ISR_PE_Msk /*!< Parity Error */ +#define USART_ISR_FE_Pos (1U) +#define USART_ISR_FE_Msk (0x1UL << USART_ISR_FE_Pos) /*!< 0x00000002 */ +#define USART_ISR_FE USART_ISR_FE_Msk /*!< Framing Error */ +#define USART_ISR_NE_Pos (2U) +#define USART_ISR_NE_Msk (0x1UL << USART_ISR_NE_Pos) /*!< 0x00000004 */ +#define USART_ISR_NE USART_ISR_NE_Msk /*!< Noise detected Flag */ +#define USART_ISR_ORE_Pos (3U) +#define USART_ISR_ORE_Msk (0x1UL << USART_ISR_ORE_Pos) /*!< 0x00000008 */ +#define USART_ISR_ORE USART_ISR_ORE_Msk /*!< OverRun Error */ +#define USART_ISR_IDLE_Pos (4U) +#define USART_ISR_IDLE_Msk (0x1UL << USART_ISR_IDLE_Pos) /*!< 0x00000010 */ +#define USART_ISR_IDLE USART_ISR_IDLE_Msk /*!< IDLE line detected */ +#define USART_ISR_RXNE_Pos (5U) +#define USART_ISR_RXNE_Msk (0x1UL << USART_ISR_RXNE_Pos) /*!< 0x00000020 */ +#define USART_ISR_RXNE USART_ISR_RXNE_Msk /*!< Read Data Register Not Empty */ +#define USART_ISR_RXNE_RXFNE_Pos USART_ISR_RXNE_Pos +#define USART_ISR_RXNE_RXFNE_Msk USART_ISR_RXNE_Msk /*!< 0x00000020 */ +#define USART_ISR_RXNE_RXFNE USART_ISR_RXNE_Msk /*!< Read Data Register or RX FIFO Not Empty */ +#define USART_ISR_TC_Pos (6U) +#define USART_ISR_TC_Msk (0x1UL << USART_ISR_TC_Pos) /*!< 0x00000040 */ +#define USART_ISR_TC USART_ISR_TC_Msk /*!< Transmission Complete */ +#define USART_ISR_TXE_Pos (7U) +#define USART_ISR_TXE_Msk (0x1UL << USART_ISR_TXE_Pos) /*!< 0x00000080 */ +#define USART_ISR_TXE USART_ISR_TXE_Msk /*!< Transmit Data Register Empty */ +#define USART_ISR_TXE_TXFNF_Pos USART_ISR_TXE_Pos +#define USART_ISR_TXE_TXFNF_Msk USART_ISR_TXE_Msk /*!< 0x00000080 */ +#define USART_ISR_TXE_TXFNF USART_ISR_TXE_Msk /*!< Transmit Data Register Empty or TX FIFO Not Full Flag */ +#define USART_ISR_LBDF_Pos (8U) +#define USART_ISR_LBDF_Msk (0x1UL << USART_ISR_LBDF_Pos) /*!< 0x00000100 */ +#define USART_ISR_LBDF USART_ISR_LBDF_Msk /*!< LIN Break Detection Flag */ +#define USART_ISR_CTSIF_Pos (9U) +#define USART_ISR_CTSIF_Msk (0x1UL << USART_ISR_CTSIF_Pos) /*!< 0x00000200 */ +#define USART_ISR_CTSIF USART_ISR_CTSIF_Msk /*!< CTS interrupt flag */ +#define USART_ISR_CTS_Pos (10U) +#define USART_ISR_CTS_Msk (0x1UL << USART_ISR_CTS_Pos) /*!< 0x00000400 */ +#define USART_ISR_CTS USART_ISR_CTS_Msk /*!< CTS flag */ +#define USART_ISR_RTOF_Pos (11U) +#define USART_ISR_RTOF_Msk (0x1UL << USART_ISR_RTOF_Pos) /*!< 0x00000800 */ +#define USART_ISR_RTOF USART_ISR_RTOF_Msk /*!< Receiver Time Out */ +#define USART_ISR_EOBF_Pos (12U) +#define USART_ISR_EOBF_Msk (0x1UL << USART_ISR_EOBF_Pos) /*!< 0x00001000 */ +#define USART_ISR_EOBF USART_ISR_EOBF_Msk /*!< End Of Block Flag */ +#define USART_ISR_UDR_Pos (13U) +#define USART_ISR_UDR_Msk (0x1UL << USART_ISR_UDR_Pos) /*!< 0x00002000 */ +#define USART_ISR_UDR USART_ISR_UDR_Msk /*!< SPI slave underrun error flag */ +#define USART_ISR_ABRE_Pos (14U) +#define USART_ISR_ABRE_Msk (0x1UL << USART_ISR_ABRE_Pos) /*!< 0x00004000 */ +#define USART_ISR_ABRE USART_ISR_ABRE_Msk /*!< Auto-Baud Rate Error */ +#define USART_ISR_ABRF_Pos (15U) +#define USART_ISR_ABRF_Msk (0x1UL << USART_ISR_ABRF_Pos) /*!< 0x00008000 */ +#define USART_ISR_ABRF USART_ISR_ABRF_Msk /*!< Auto-Baud Rate Flag */ +#define USART_ISR_BUSY_Pos (16U) +#define USART_ISR_BUSY_Msk (0x1UL << USART_ISR_BUSY_Pos) /*!< 0x00010000 */ +#define USART_ISR_BUSY USART_ISR_BUSY_Msk /*!< Busy Flag */ +#define USART_ISR_CMF_Pos (17U) +#define USART_ISR_CMF_Msk (0x1UL << USART_ISR_CMF_Pos) /*!< 0x00020000 */ +#define USART_ISR_CMF USART_ISR_CMF_Msk /*!< Character Match Flag */ +#define USART_ISR_SBKF_Pos (18U) +#define USART_ISR_SBKF_Msk (0x1UL << USART_ISR_SBKF_Pos) /*!< 0x00040000 */ +#define USART_ISR_SBKF USART_ISR_SBKF_Msk /*!< Send Break Flag */ +#define USART_ISR_RWU_Pos (19U) +#define USART_ISR_RWU_Msk (0x1UL << USART_ISR_RWU_Pos) /*!< 0x00080000 */ +#define USART_ISR_RWU USART_ISR_RWU_Msk /*!< Receive Wake Up from mute mode Flag */ +#define USART_ISR_WUF_Pos (20U) +#define USART_ISR_WUF_Msk (0x1UL << USART_ISR_WUF_Pos) /*!< 0x00100000 */ +#define USART_ISR_WUF USART_ISR_WUF_Msk /*!< Wake Up from low power mode Flag */ +#define USART_ISR_TEACK_Pos (21U) +#define USART_ISR_TEACK_Msk (0x1UL << USART_ISR_TEACK_Pos) /*!< 0x00200000 */ +#define USART_ISR_TEACK USART_ISR_TEACK_Msk /*!< Transmit Enable Acknowledge Flag */ +#define USART_ISR_REACK_Pos (22U) +#define USART_ISR_REACK_Msk (0x1UL << USART_ISR_REACK_Pos) /*!< 0x00400000 */ +#define USART_ISR_REACK USART_ISR_REACK_Msk /*!< Receive Enable Acknowledge Flag */ +#define USART_ISR_TXFE_Pos (23U) +#define USART_ISR_TXFE_Msk (0x1UL << USART_ISR_TXFE_Pos) /*!< 0x00800000 */ +#define USART_ISR_TXFE USART_ISR_TXFE_Msk /*!< TXFIFO Empty */ +#define USART_ISR_RXFF_Pos (24U) +#define USART_ISR_RXFF_Msk (0x1UL << USART_ISR_RXFF_Pos) /*!< 0x01000000 */ +#define USART_ISR_RXFF USART_ISR_RXFF_Msk /*!< RXFIFO Full */ +#define USART_ISR_TCBGT_Pos (25U) +#define USART_ISR_TCBGT_Msk (0x1UL << USART_ISR_TCBGT_Pos) /*!< 0x02000000 */ +#define USART_ISR_TCBGT USART_ISR_TCBGT_Msk /*!< Transmission Complete Before Guard Time completion */ +#define USART_ISR_RXFT_Pos (26U) +#define USART_ISR_RXFT_Msk (0x1UL << USART_ISR_RXFT_Pos) /*!< 0x04000000 */ +#define USART_ISR_RXFT USART_ISR_RXFT_Msk /*!< RXFIFO threshold flag */ +#define USART_ISR_TXFT_Pos (27U) +#define USART_ISR_TXFT_Msk (0x1UL << USART_ISR_TXFT_Pos) /*!< 0x08000000 */ +#define USART_ISR_TXFT USART_ISR_TXFT_Msk /*!< TXFIFO threshold flag */ + +/******************* Bit definition for USART_ICR register ******************/ +#define USART_ICR_PECF_Pos (0U) +#define USART_ICR_PECF_Msk (0x1UL << USART_ICR_PECF_Pos) /*!< 0x00000001 */ +#define USART_ICR_PECF USART_ICR_PECF_Msk /*!< Parity Error Clear Flag */ +#define USART_ICR_FECF_Pos (1U) +#define USART_ICR_FECF_Msk (0x1UL << USART_ICR_FECF_Pos) /*!< 0x00000002 */ +#define USART_ICR_FECF USART_ICR_FECF_Msk /*!< Framing Error Clear Flag */ +#define USART_ICR_NECF_Pos (2U) +#define USART_ICR_NECF_Msk (0x1UL << USART_ICR_NECF_Pos) /*!< 0x00000004 */ +#define USART_ICR_NECF USART_ICR_NECF_Msk /*!< Noise detected Clear Flag */ +#define USART_ICR_ORECF_Pos (3U) +#define USART_ICR_ORECF_Msk (0x1UL << USART_ICR_ORECF_Pos) /*!< 0x00000008 */ +#define USART_ICR_ORECF USART_ICR_ORECF_Msk /*!< OverRun Error Clear Flag */ +#define USART_ICR_IDLECF_Pos (4U) +#define USART_ICR_IDLECF_Msk (0x1UL << USART_ICR_IDLECF_Pos) /*!< 0x00000010 */ +#define USART_ICR_IDLECF USART_ICR_IDLECF_Msk /*!< IDLE line detected Clear Flag */ +#define USART_ICR_TXFECF_Pos (5U) +#define USART_ICR_TXFECF_Msk (0x1UL << USART_ICR_TXFECF_Pos) /*!< 0x00000020 */ +#define USART_ICR_TXFECF USART_ICR_TXFECF_Msk /*!< TXFIFO empty Clear flag */ +#define USART_ICR_TCCF_Pos (6U) +#define USART_ICR_TCCF_Msk (0x1UL << USART_ICR_TCCF_Pos) /*!< 0x00000040 */ +#define USART_ICR_TCCF USART_ICR_TCCF_Msk /*!< Transmission Complete Clear Flag */ +#define USART_ICR_TCBGTCF_Pos (7U) +#define USART_ICR_TCBGTCF_Msk (0x1UL << USART_ICR_TCBGTCF_Pos) /*!< 0x00000080 */ +#define USART_ICR_TCBGTCF USART_ICR_TCBGTCF_Msk /*!< Transmission Complete Before Guard Time Clear Flag */ +#define USART_ICR_LBDCF_Pos (8U) +#define USART_ICR_LBDCF_Msk (0x1UL << USART_ICR_LBDCF_Pos) /*!< 0x00000100 */ +#define USART_ICR_LBDCF USART_ICR_LBDCF_Msk /*!< LIN Break Detection Clear Flag */ +#define USART_ICR_CTSCF_Pos (9U) +#define USART_ICR_CTSCF_Msk (0x1UL << USART_ICR_CTSCF_Pos) /*!< 0x00000200 */ +#define USART_ICR_CTSCF USART_ICR_CTSCF_Msk /*!< CTS Interrupt Clear Flag */ +#define USART_ICR_RTOCF_Pos (11U) +#define USART_ICR_RTOCF_Msk (0x1UL << USART_ICR_RTOCF_Pos) /*!< 0x00000800 */ +#define USART_ICR_RTOCF USART_ICR_RTOCF_Msk /*!< Receiver Time Out Clear Flag */ +#define USART_ICR_EOBCF_Pos (12U) +#define USART_ICR_EOBCF_Msk (0x1UL << USART_ICR_EOBCF_Pos) /*!< 0x00001000 */ +#define USART_ICR_EOBCF USART_ICR_EOBCF_Msk /*!< End Of Block Clear Flag */ +#define USART_ICR_UDRCF_Pos (13U) +#define USART_ICR_UDRCF_Msk (0x1UL << USART_ICR_UDRCF_Pos) /*!< 0x00002000 */ +#define USART_ICR_UDRCF USART_ICR_UDRCF_Msk /*!< SPI Slave Underrun Clear Flag */ +#define USART_ICR_CMCF_Pos (17U) +#define USART_ICR_CMCF_Msk (0x1UL << USART_ICR_CMCF_Pos) /*!< 0x00020000 */ +#define USART_ICR_CMCF USART_ICR_CMCF_Msk /*!< Character Match Clear Flag */ +#define USART_ICR_WUCF_Pos (20U) +#define USART_ICR_WUCF_Msk (0x1UL << USART_ICR_WUCF_Pos) /*!< 0x00100000 */ +#define USART_ICR_WUCF USART_ICR_WUCF_Msk /*!< Wake Up from stop mode Clear Flag */ + +/******************* Bit definition for USART_RDR register ******************/ +#define USART_RDR_RDR ((uint16_t)0x01FF) /*!< RDR[8:0] bits (Receive Data value) */ + +/******************* Bit definition for USART_TDR register ******************/ +#define USART_TDR_TDR ((uint16_t)0x01FF) /*!< TDR[8:0] bits (Transmit Data value) */ + +/******************* Bit definition for USART_PRESC register ****************/ +#define USART_PRESC_PRESCALER_Pos (0U) +#define USART_PRESC_PRESCALER_Msk (0xFUL << USART_PRESC_PRESCALER_Pos) /*!< 0x0000000F */ +#define USART_PRESC_PRESCALER USART_PRESC_PRESCALER_Msk /*!< PRESCALER[3:0] bits (Clock prescaler) */ +#define USART_PRESC_PRESCALER_0 (0x1UL << USART_PRESC_PRESCALER_Pos) /*!< 0x00000001 */ +#define USART_PRESC_PRESCALER_1 (0x2UL << USART_PRESC_PRESCALER_Pos) /*!< 0x00000002 */ +#define USART_PRESC_PRESCALER_2 (0x4UL << USART_PRESC_PRESCALER_Pos) /*!< 0x00000004 */ +#define USART_PRESC_PRESCALER_3 (0x8UL << USART_PRESC_PRESCALER_Pos) /*!< 0x00000008 */ + +/******************* Bit definition for USART_HWCFGR2 register **************/ +#define USART_HWCFGR2_CFG1_Pos (0U) +#define USART_HWCFGR2_CFG1_Msk (0xFUL << USART_HWCFGR2_CFG1_Pos) /*!< 0x0000000F */ +#define USART_HWCFGR2_CFG1 USART_HWCFGR2_CFG1_Msk /*!< CFG1[3:0] bits (USART hardware configuration 1) */ +#define USART_HWCFGR2_CFG2_Pos (4U) +#define USART_HWCFGR2_CFG2_Msk (0xFUL << USART_HWCFGR2_CFG2_Pos) /*!< 0x000000F0 */ +#define USART_HWCFGR2_CFG2 USART_HWCFGR2_CFG2_Msk /*!< CFG2[7:4] bits (USART hardware configuration 2) */ + +/******************* Bit definition for USART_HWCFGR1 register **************/ +#define USART_HWCFGR1_CFG1_Pos (0U) +#define USART_HWCFGR1_CFG1_Msk (0xFUL << USART_HWCFGR1_CFG1_Pos) /*!< 0x0000000F */ +#define USART_HWCFGR1_CFG1 USART_HWCFGR1_CFG1_Msk /*!< CFG1[3:0] bits (USART hardware configuration 1) */ +#define USART_HWCFGR1_CFG2_Pos (4U) +#define USART_HWCFGR1_CFG2_Msk (0xFUL << USART_HWCFGR1_CFG2_Pos) /*!< 0x000000F0 */ +#define USART_HWCFGR1_CFG2 USART_HWCFGR1_CFG2_Msk /*!< CFG2[7:4] bits (USART hardware configuration 2) */ +#define USART_HWCFGR1_CFG3_Pos (8U) +#define USART_HWCFGR1_CFG3_Msk (0xFUL << USART_HWCFGR1_CFG3_Pos) /*!< 0x00000F00 */ +#define USART_HWCFGR1_CFG3 USART_HWCFGR1_CFG3_Msk /*!< CFG3[11:8] bits (USART hardware configuration 3) */ +#define USART_HWCFGR1_CFG4_Pos (12U) +#define USART_HWCFGR1_CFG4_Msk (0xFUL << USART_HWCFGR1_CFG4_Pos) /*!< 0x0000F000 */ +#define USART_HWCFGR1_CFG4 USART_HWCFGR1_CFG4_Msk /*!< CFG4[15:12] bits (USART hardware configuration 4) */ +#define USART_HWCFGR1_CFG5_Pos (16U) +#define USART_HWCFGR1_CFG5_Msk (0xFUL << USART_HWCFGR1_CFG5_Pos) /*!< 0x000F0000 */ +#define USART_HWCFGR1_CFG5 USART_HWCFGR1_CFG5_Msk /*!< CFG5[19:16] bits (USART hardware configuration 5) */ +#define USART_HWCFGR1_CFG6_Pos (20U) +#define USART_HWCFGR1_CFG6_Msk (0xFUL << USART_HWCFGR1_CFG6_Pos) /*!< 0x00F00000 */ +#define USART_HWCFGR1_CFG6 USART_HWCFGR1_CFG6_Msk /*!< CFG6[23:20] bits (USART hardware configuration 6) */ +#define USART_HWCFGR1_CFG7_Pos (24U) +#define USART_HWCFGR1_CFG7_Msk (0xFUL << USART_HWCFGR1_CFG7_Pos) /*!< 0x0F000000 */ +#define USART_HWCFGR1_CFG7 USART_HWCFGR1_CFG7_Msk /*!< CFG7[27:24] bits (USART hardware configuration 7) */ +#define USART_HWCFGR1_CFG8_Pos (28U) +#define USART_HWCFGR1_CFG8_Msk (0xFUL << USART_HWCFGR1_CFG8_Pos) /*!< 0xF0000000 */ +#define USART_HWCFGR1_CFG8 USART_HWCFGR1_CFG8_Msk /*!< CFG8[31:28] bits (USART hardware configuration 8) */ + +/******************* Bit definition for USART_VERR register *****************/ +#define USART_VERR_MINREV_Pos (0U) +#define USART_VERR_MINREV_Msk (0xFUL << USART_VERR_MINREV_Pos) /*!< 0x0000000F */ +#define USART_VERR_MINREV USART_VERR_MINREV_Msk /*!< MAJREV[3:0] bits (Minor revision) */ +#define USART_VERR_MAJREV_Pos (4U) +#define USART_VERR_MAJREV_Msk (0xFUL << USART_VERR_MAJREV_Pos) /*!< 0x000000F0 */ +#define USART_VERR_MAJREV USART_VERR_MAJREV_Msk /*!< MINREV[3:0] bits (Major revision) */ + +/******************* Bit definition for USART_IPIDR register ****************/ +#define USART_IPIDR_ID_Pos (0U) +#define USART_IPIDR_ID_Msk (0xFFFFFFFFUL << USART_IPIDR_ID_Pos) /*!< 0xFFFFFFFF */ +#define USART_IPIDR_ID USART_IPIDR_ID_Msk /*!< ID[31:0] bits (Peripheral identifier) */ + +/******************* Bit definition for USART_SIDR register ****************/ +#define USART_SIDR_ID_Pos (0U) +#define USART_SIDR_ID_Msk (0xFFFFFFFFUL << USART_SIDR_ID_Pos) /*!< 0xFFFFFFFF */ +#define USART_SIDR_ID USART_SIDR_ID_Msk /*!< SID[31:0] bits (Size identification) */ + + +/******************************************************************************/ +/* */ +/* Inter-integrated Circuit Interface (I2C) */ +/* */ +/******************************************************************************/ +/******************* Bit definition for I2C_CR1 register *******************/ +#define I2C_CR1_PE_Pos (0U) +#define I2C_CR1_PE_Msk (0x1UL << I2C_CR1_PE_Pos) /*!< 0x00000001 */ +#define I2C_CR1_PE I2C_CR1_PE_Msk /*!< Peripheral enable */ +#define I2C_CR1_TXIE_Pos (1U) +#define I2C_CR1_TXIE_Msk (0x1UL << I2C_CR1_TXIE_Pos) /*!< 0x00000002 */ +#define I2C_CR1_TXIE I2C_CR1_TXIE_Msk /*!< TX interrupt enable */ +#define I2C_CR1_RXIE_Pos (2U) +#define I2C_CR1_RXIE_Msk (0x1UL << I2C_CR1_RXIE_Pos) /*!< 0x00000004 */ +#define I2C_CR1_RXIE I2C_CR1_RXIE_Msk /*!< RX interrupt enable */ +#define I2C_CR1_ADDRIE_Pos (3U) +#define I2C_CR1_ADDRIE_Msk (0x1UL << I2C_CR1_ADDRIE_Pos) /*!< 0x00000008 */ +#define I2C_CR1_ADDRIE I2C_CR1_ADDRIE_Msk /*!< Address match interrupt enable */ +#define I2C_CR1_NACKIE_Pos (4U) +#define I2C_CR1_NACKIE_Msk (0x1UL << I2C_CR1_NACKIE_Pos) /*!< 0x00000010 */ +#define I2C_CR1_NACKIE I2C_CR1_NACKIE_Msk /*!< NACK received interrupt enable */ +#define I2C_CR1_STOPIE_Pos (5U) +#define I2C_CR1_STOPIE_Msk (0x1UL << I2C_CR1_STOPIE_Pos) /*!< 0x00000020 */ +#define I2C_CR1_STOPIE I2C_CR1_STOPIE_Msk /*!< STOP detection interrupt enable */ +#define I2C_CR1_TCIE_Pos (6U) +#define I2C_CR1_TCIE_Msk (0x1UL << I2C_CR1_TCIE_Pos) /*!< 0x00000040 */ +#define I2C_CR1_TCIE I2C_CR1_TCIE_Msk /*!< Transfer complete interrupt enable */ +#define I2C_CR1_ERRIE_Pos (7U) +#define I2C_CR1_ERRIE_Msk (0x1UL << I2C_CR1_ERRIE_Pos) /*!< 0x00000080 */ +#define I2C_CR1_ERRIE I2C_CR1_ERRIE_Msk /*!< Errors interrupt enable */ +#define I2C_CR1_DNF_Pos (8U) +#define I2C_CR1_DNF_Msk (0xFUL << I2C_CR1_DNF_Pos) /*!< 0x00000F00 */ +#define I2C_CR1_DNF I2C_CR1_DNF_Msk /*!< Digital noise filter */ +#define I2C_CR1_ANFOFF_Pos (12U) +#define I2C_CR1_ANFOFF_Msk (0x1UL << I2C_CR1_ANFOFF_Pos) /*!< 0x00001000 */ +#define I2C_CR1_ANFOFF I2C_CR1_ANFOFF_Msk /*!< Analog noise filter OFF */ +#define I2C_CR1_SWRST_Pos (13U) +#define I2C_CR1_SWRST_Msk (0x1UL << I2C_CR1_SWRST_Pos) /*!< 0x00002000 */ +#define I2C_CR1_SWRST I2C_CR1_SWRST_Msk /*!< Software reset */ +#define I2C_CR1_TXDMAEN_Pos (14U) +#define I2C_CR1_TXDMAEN_Msk (0x1UL << I2C_CR1_TXDMAEN_Pos) /*!< 0x00004000 */ +#define I2C_CR1_TXDMAEN I2C_CR1_TXDMAEN_Msk /*!< DMA transmission requests enable */ +#define I2C_CR1_RXDMAEN_Pos (15U) +#define I2C_CR1_RXDMAEN_Msk (0x1UL << I2C_CR1_RXDMAEN_Pos) /*!< 0x00008000 */ +#define I2C_CR1_RXDMAEN I2C_CR1_RXDMAEN_Msk /*!< DMA reception requests enable */ +#define I2C_CR1_SBC_Pos (16U) +#define I2C_CR1_SBC_Msk (0x1UL << I2C_CR1_SBC_Pos) /*!< 0x00010000 */ +#define I2C_CR1_SBC I2C_CR1_SBC_Msk /*!< Slave byte control */ +#define I2C_CR1_NOSTRETCH_Pos (17U) +#define I2C_CR1_NOSTRETCH_Msk (0x1UL << I2C_CR1_NOSTRETCH_Pos) /*!< 0x00020000 */ +#define I2C_CR1_NOSTRETCH I2C_CR1_NOSTRETCH_Msk /*!< Clock stretching disable */ +#define I2C_CR1_WUPEN_Pos (18U) +#define I2C_CR1_WUPEN_Msk (0x1UL << I2C_CR1_WUPEN_Pos) /*!< 0x00040000 */ +#define I2C_CR1_WUPEN I2C_CR1_WUPEN_Msk /*!< Wakeup from STOP enable */ +#define I2C_CR1_GCEN_Pos (19U) +#define I2C_CR1_GCEN_Msk (0x1UL << I2C_CR1_GCEN_Pos) /*!< 0x00080000 */ +#define I2C_CR1_GCEN I2C_CR1_GCEN_Msk /*!< General call enable */ +#define I2C_CR1_SMBHEN_Pos (20U) +#define I2C_CR1_SMBHEN_Msk (0x1UL << I2C_CR1_SMBHEN_Pos) /*!< 0x00100000 */ +#define I2C_CR1_SMBHEN I2C_CR1_SMBHEN_Msk /*!< SMBus host address enable */ +#define I2C_CR1_SMBDEN_Pos (21U) +#define I2C_CR1_SMBDEN_Msk (0x1UL << I2C_CR1_SMBDEN_Pos) /*!< 0x00200000 */ +#define I2C_CR1_SMBDEN I2C_CR1_SMBDEN_Msk /*!< SMBus device default address enable */ +#define I2C_CR1_ALERTEN_Pos (22U) +#define I2C_CR1_ALERTEN_Msk (0x1UL << I2C_CR1_ALERTEN_Pos) /*!< 0x00400000 */ +#define I2C_CR1_ALERTEN I2C_CR1_ALERTEN_Msk /*!< SMBus alert enable */ +#define I2C_CR1_PECEN_Pos (23U) +#define I2C_CR1_PECEN_Msk (0x1UL << I2C_CR1_PECEN_Pos) /*!< 0x00800000 */ +#define I2C_CR1_PECEN I2C_CR1_PECEN_Msk /*!< PEC enable */ +#define I2C_CR1_FMP_Pos (24U) +#define I2C_CR1_FMP_Msk (0x1UL << I2C_CR1_FMP_Pos) /*!< 0x01000000 */ +#define I2C_CR1_FMP I2C_CR1_FMP_Msk /*!< Fast-mode Plus 20 mA drive enable */ +#define I2C_CR1_ADDRACLR_Pos (30U) +#define I2C_CR1_ADDRACLR_Msk (0x1UL << I2C_CR1_ADDRACLR_Pos) /*!< 0x40000000 */ +#define I2C_CR1_ADDRACLR I2C_CR1_ADDRACLR_Msk /*!< ADDRACLR enable */ +#define I2C_CR1_STOPFACLR_Pos (31U) +#define I2C_CR1_STOPFACLR_Msk (0x1UL << I2C_CR1_STOPFACLR_Pos) /*!< 0x80000000 */ +#define I2C_CR1_STOPFACLR I2C_CR1_STOPFACLR_Msk /*!< STOPFACLR enable */ + +/****************** Bit definition for I2C_CR2 register ********************/ +#define I2C_CR2_SADD_Pos (0U) +#define I2C_CR2_SADD_Msk (0x3FFUL << I2C_CR2_SADD_Pos) /*!< 0x000003FF */ +#define I2C_CR2_SADD I2C_CR2_SADD_Msk /*!< Slave address (master mode) */ +#define I2C_CR2_RD_WRN_Pos (10U) +#define I2C_CR2_RD_WRN_Msk (0x1UL << I2C_CR2_RD_WRN_Pos) /*!< 0x00000400 */ +#define I2C_CR2_RD_WRN I2C_CR2_RD_WRN_Msk /*!< Transfer direction (master mode) */ +#define I2C_CR2_ADD10_Pos (11U) +#define I2C_CR2_ADD10_Msk (0x1UL << I2C_CR2_ADD10_Pos) /*!< 0x00000800 */ +#define I2C_CR2_ADD10 I2C_CR2_ADD10_Msk /*!< 10-bit addressing mode (master mode) */ +#define I2C_CR2_HEAD10R_Pos (12U) +#define I2C_CR2_HEAD10R_Msk (0x1UL << I2C_CR2_HEAD10R_Pos) /*!< 0x00001000 */ +#define I2C_CR2_HEAD10R I2C_CR2_HEAD10R_Msk /*!< 10-bit address header only read direction (master mode) */ +#define I2C_CR2_START_Pos (13U) +#define I2C_CR2_START_Msk (0x1UL << I2C_CR2_START_Pos) /*!< 0x00002000 */ +#define I2C_CR2_START I2C_CR2_START_Msk /*!< START generation */ +#define I2C_CR2_STOP_Pos (14U) +#define I2C_CR2_STOP_Msk (0x1UL << I2C_CR2_STOP_Pos) /*!< 0x00004000 */ +#define I2C_CR2_STOP I2C_CR2_STOP_Msk /*!< STOP generation (master mode) */ +#define I2C_CR2_NACK_Pos (15U) +#define I2C_CR2_NACK_Msk (0x1UL << I2C_CR2_NACK_Pos) /*!< 0x00008000 */ +#define I2C_CR2_NACK I2C_CR2_NACK_Msk /*!< NACK generation (slave mode) */ +#define I2C_CR2_NBYTES_Pos (16U) +#define I2C_CR2_NBYTES_Msk (0xFFUL << I2C_CR2_NBYTES_Pos) /*!< 0x00FF0000 */ +#define I2C_CR2_NBYTES I2C_CR2_NBYTES_Msk /*!< Number of bytes */ +#define I2C_CR2_RELOAD_Pos (24U) +#define I2C_CR2_RELOAD_Msk (0x1UL << I2C_CR2_RELOAD_Pos) /*!< 0x01000000 */ +#define I2C_CR2_RELOAD I2C_CR2_RELOAD_Msk /*!< NBYTES reload mode */ +#define I2C_CR2_AUTOEND_Pos (25U) +#define I2C_CR2_AUTOEND_Msk (0x1UL << I2C_CR2_AUTOEND_Pos) /*!< 0x02000000 */ +#define I2C_CR2_AUTOEND I2C_CR2_AUTOEND_Msk /*!< Automatic end mode (master mode) */ +#define I2C_CR2_PECBYTE_Pos (26U) +#define I2C_CR2_PECBYTE_Msk (0x1UL << I2C_CR2_PECBYTE_Pos) /*!< 0x04000000 */ +#define I2C_CR2_PECBYTE I2C_CR2_PECBYTE_Msk /*!< Packet error checking byte */ + +/******************* Bit definition for I2C_OAR1 register ******************/ +#define I2C_OAR1_OA1_Pos (0U) +#define I2C_OAR1_OA1_Msk (0x3FFUL << I2C_OAR1_OA1_Pos) /*!< 0x000003FF */ +#define I2C_OAR1_OA1 I2C_OAR1_OA1_Msk /*!< Interface own address 1 */ +#define I2C_OAR1_OA1MODE_Pos (10U) +#define I2C_OAR1_OA1MODE_Msk (0x1UL << I2C_OAR1_OA1MODE_Pos) /*!< 0x00000400 */ +#define I2C_OAR1_OA1MODE I2C_OAR1_OA1MODE_Msk /*!< Own address 1 10-bit mode */ +#define I2C_OAR1_OA1EN_Pos (15U) +#define I2C_OAR1_OA1EN_Msk (0x1UL << I2C_OAR1_OA1EN_Pos) /*!< 0x00008000 */ +#define I2C_OAR1_OA1EN I2C_OAR1_OA1EN_Msk /*!< Own address 1 enable */ + +/******************* Bit definition for I2C_OAR2 register ******************/ +#define I2C_OAR2_OA2_Pos (1U) +#define I2C_OAR2_OA2_Msk (0x7FUL << I2C_OAR2_OA2_Pos) /*!< 0x000000FE */ +#define I2C_OAR2_OA2 I2C_OAR2_OA2_Msk /*!< Interface own address 2 */ +#define I2C_OAR2_OA2MSK_Pos (8U) +#define I2C_OAR2_OA2MSK_Msk (0x7UL << I2C_OAR2_OA2MSK_Pos) /*!< 0x00000700 */ +#define I2C_OAR2_OA2MSK I2C_OAR2_OA2MSK_Msk /*!< Own address 2 masks */ +#define I2C_OAR2_OA2NOMASK (0x00000000UL) /*!< No mask */ +#define I2C_OAR2_OA2MASK01_Pos (8U) +#define I2C_OAR2_OA2MASK01_Msk (0x1UL << I2C_OAR2_OA2MASK01_Pos) /*!< 0x00000100 */ +#define I2C_OAR2_OA2MASK01 I2C_OAR2_OA2MASK01_Msk /*!< OA2[1] is masked, Only OA2[7:2] are compared */ +#define I2C_OAR2_OA2MASK02_Pos (9U) +#define I2C_OAR2_OA2MASK02_Msk (0x1UL << I2C_OAR2_OA2MASK02_Pos) /*!< 0x00000200 */ +#define I2C_OAR2_OA2MASK02 I2C_OAR2_OA2MASK02_Msk /*!< OA2[2:1] is masked, Only OA2[7:3] are compared */ +#define I2C_OAR2_OA2MASK03_Pos (8U) +#define I2C_OAR2_OA2MASK03_Msk (0x3UL << I2C_OAR2_OA2MASK03_Pos) /*!< 0x00000300 */ +#define I2C_OAR2_OA2MASK03 I2C_OAR2_OA2MASK03_Msk /*!< OA2[3:1] is masked, Only OA2[7:4] are compared */ +#define I2C_OAR2_OA2MASK04_Pos (10U) +#define I2C_OAR2_OA2MASK04_Msk (0x1UL << I2C_OAR2_OA2MASK04_Pos) /*!< 0x00000400 */ +#define I2C_OAR2_OA2MASK04 I2C_OAR2_OA2MASK04_Msk /*!< OA2[4:1] is masked, Only OA2[7:5] are compared */ +#define I2C_OAR2_OA2MASK05_Pos (8U) +#define I2C_OAR2_OA2MASK05_Msk (0x5UL << I2C_OAR2_OA2MASK05_Pos) /*!< 0x00000500 */ +#define I2C_OAR2_OA2MASK05 I2C_OAR2_OA2MASK05_Msk /*!< OA2[5:1] is masked, Only OA2[7:6] are compared */ +#define I2C_OAR2_OA2MASK06_Pos (9U) +#define I2C_OAR2_OA2MASK06_Msk (0x3UL << I2C_OAR2_OA2MASK06_Pos) /*!< 0x00000600 */ +#define I2C_OAR2_OA2MASK06 I2C_OAR2_OA2MASK06_Msk /*!< OA2[6:1] is masked, Only OA2[7] are compared */ +#define I2C_OAR2_OA2MASK07_Pos (8U) +#define I2C_OAR2_OA2MASK07_Msk (0x7UL << I2C_OAR2_OA2MASK07_Pos) /*!< 0x00000700 */ +#define I2C_OAR2_OA2MASK07 I2C_OAR2_OA2MASK07_Msk /*!< OA2[7:1] is masked, No comparison is done */ +#define I2C_OAR2_OA2EN_Pos (15U) +#define I2C_OAR2_OA2EN_Msk (0x1UL << I2C_OAR2_OA2EN_Pos) /*!< 0x00008000 */ +#define I2C_OAR2_OA2EN I2C_OAR2_OA2EN_Msk /*!< Own address 2 enable */ + +/******************* Bit definition for I2C_TIMINGR register *******************/ +#define I2C_TIMINGR_SCLL_Pos (0U) +#define I2C_TIMINGR_SCLL_Msk (0xFFUL << I2C_TIMINGR_SCLL_Pos) /*!< 0x000000FF */ +#define I2C_TIMINGR_SCLL I2C_TIMINGR_SCLL_Msk /*!< SCL low period (master mode) */ +#define I2C_TIMINGR_SCLH_Pos (8U) +#define I2C_TIMINGR_SCLH_Msk (0xFFUL << I2C_TIMINGR_SCLH_Pos) /*!< 0x0000FF00 */ +#define I2C_TIMINGR_SCLH I2C_TIMINGR_SCLH_Msk /*!< SCL high period (master mode) */ +#define I2C_TIMINGR_SDADEL_Pos (16U) +#define I2C_TIMINGR_SDADEL_Msk (0xFUL << I2C_TIMINGR_SDADEL_Pos) /*!< 0x000F0000 */ +#define I2C_TIMINGR_SDADEL I2C_TIMINGR_SDADEL_Msk /*!< Data hold time */ +#define I2C_TIMINGR_SCLDEL_Pos (20U) +#define I2C_TIMINGR_SCLDEL_Msk (0xFUL << I2C_TIMINGR_SCLDEL_Pos) /*!< 0x00F00000 */ +#define I2C_TIMINGR_SCLDEL I2C_TIMINGR_SCLDEL_Msk /*!< Data setup time */ +#define I2C_TIMINGR_PRESC_Pos (28U) +#define I2C_TIMINGR_PRESC_Msk (0xFUL << I2C_TIMINGR_PRESC_Pos) /*!< 0xF0000000 */ +#define I2C_TIMINGR_PRESC I2C_TIMINGR_PRESC_Msk /*!< Timings prescaler */ + +/******************* Bit definition for I2C_TIMEOUTR register *******************/ +#define I2C_TIMEOUTR_TIMEOUTA_Pos (0U) +#define I2C_TIMEOUTR_TIMEOUTA_Msk (0xFFFUL << I2C_TIMEOUTR_TIMEOUTA_Pos) /*!< 0x00000FFF */ +#define I2C_TIMEOUTR_TIMEOUTA I2C_TIMEOUTR_TIMEOUTA_Msk /*!< Bus timeout A */ +#define I2C_TIMEOUTR_TIDLE_Pos (12U) +#define I2C_TIMEOUTR_TIDLE_Msk (0x1UL << I2C_TIMEOUTR_TIDLE_Pos) /*!< 0x00001000 */ +#define I2C_TIMEOUTR_TIDLE I2C_TIMEOUTR_TIDLE_Msk /*!< Idle clock timeout detection */ +#define I2C_TIMEOUTR_TIMOUTEN_Pos (15U) +#define I2C_TIMEOUTR_TIMOUTEN_Msk (0x1UL << I2C_TIMEOUTR_TIMOUTEN_Pos) /*!< 0x00008000 */ +#define I2C_TIMEOUTR_TIMOUTEN I2C_TIMEOUTR_TIMOUTEN_Msk /*!< Clock timeout enable */ +#define I2C_TIMEOUTR_TIMEOUTB_Pos (16U) +#define I2C_TIMEOUTR_TIMEOUTB_Msk (0xFFFUL << I2C_TIMEOUTR_TIMEOUTB_Pos) /*!< 0x0FFF0000 */ +#define I2C_TIMEOUTR_TIMEOUTB I2C_TIMEOUTR_TIMEOUTB_Msk /*!< Bus timeout B*/ +#define I2C_TIMEOUTR_TEXTEN_Pos (31U) +#define I2C_TIMEOUTR_TEXTEN_Msk (0x1UL << I2C_TIMEOUTR_TEXTEN_Pos) /*!< 0x80000000 */ +#define I2C_TIMEOUTR_TEXTEN I2C_TIMEOUTR_TEXTEN_Msk /*!< Extended clock timeout enable */ + +/****************** Bit definition for I2C_ISR register *********************/ +#define I2C_ISR_TXE_Pos (0U) +#define I2C_ISR_TXE_Msk (0x1UL << I2C_ISR_TXE_Pos) /*!< 0x00000001 */ +#define I2C_ISR_TXE I2C_ISR_TXE_Msk /*!< Transmit data register empty */ +#define I2C_ISR_TXIS_Pos (1U) +#define I2C_ISR_TXIS_Msk (0x1UL << I2C_ISR_TXIS_Pos) /*!< 0x00000002 */ +#define I2C_ISR_TXIS I2C_ISR_TXIS_Msk /*!< Transmit interrupt status */ +#define I2C_ISR_RXNE_Pos (2U) +#define I2C_ISR_RXNE_Msk (0x1UL << I2C_ISR_RXNE_Pos) /*!< 0x00000004 */ +#define I2C_ISR_RXNE I2C_ISR_RXNE_Msk /*!< Receive data register not empty */ +#define I2C_ISR_ADDR_Pos (3U) +#define I2C_ISR_ADDR_Msk (0x1UL << I2C_ISR_ADDR_Pos) /*!< 0x00000008 */ +#define I2C_ISR_ADDR I2C_ISR_ADDR_Msk /*!< Address matched (slave mode)*/ +#define I2C_ISR_NACKF_Pos (4U) +#define I2C_ISR_NACKF_Msk (0x1UL << I2C_ISR_NACKF_Pos) /*!< 0x00000010 */ +#define I2C_ISR_NACKF I2C_ISR_NACKF_Msk /*!< NACK received flag */ +#define I2C_ISR_STOPF_Pos (5U) +#define I2C_ISR_STOPF_Msk (0x1UL << I2C_ISR_STOPF_Pos) /*!< 0x00000020 */ +#define I2C_ISR_STOPF I2C_ISR_STOPF_Msk /*!< STOP detection flag */ +#define I2C_ISR_TC_Pos (6U) +#define I2C_ISR_TC_Msk (0x1UL << I2C_ISR_TC_Pos) /*!< 0x00000040 */ +#define I2C_ISR_TC I2C_ISR_TC_Msk /*!< Transfer complete (master mode) */ +#define I2C_ISR_TCR_Pos (7U) +#define I2C_ISR_TCR_Msk (0x1UL << I2C_ISR_TCR_Pos) /*!< 0x00000080 */ +#define I2C_ISR_TCR I2C_ISR_TCR_Msk /*!< Transfer complete reload */ +#define I2C_ISR_BERR_Pos (8U) +#define I2C_ISR_BERR_Msk (0x1UL << I2C_ISR_BERR_Pos) /*!< 0x00000100 */ +#define I2C_ISR_BERR I2C_ISR_BERR_Msk /*!< Bus error */ +#define I2C_ISR_ARLO_Pos (9U) +#define I2C_ISR_ARLO_Msk (0x1UL << I2C_ISR_ARLO_Pos) /*!< 0x00000200 */ +#define I2C_ISR_ARLO I2C_ISR_ARLO_Msk /*!< Arbitration lost */ +#define I2C_ISR_OVR_Pos (10U) +#define I2C_ISR_OVR_Msk (0x1UL << I2C_ISR_OVR_Pos) /*!< 0x00000400 */ +#define I2C_ISR_OVR I2C_ISR_OVR_Msk /*!< Overrun/Underrun */ +#define I2C_ISR_PECERR_Pos (11U) +#define I2C_ISR_PECERR_Msk (0x1UL << I2C_ISR_PECERR_Pos) /*!< 0x00000800 */ +#define I2C_ISR_PECERR I2C_ISR_PECERR_Msk /*!< PEC error in reception */ +#define I2C_ISR_TIMEOUT_Pos (12U) +#define I2C_ISR_TIMEOUT_Msk (0x1UL << I2C_ISR_TIMEOUT_Pos) /*!< 0x00001000 */ +#define I2C_ISR_TIMEOUT I2C_ISR_TIMEOUT_Msk /*!< Timeout or Tlow detection flag */ +#define I2C_ISR_ALERT_Pos (13U) +#define I2C_ISR_ALERT_Msk (0x1UL << I2C_ISR_ALERT_Pos) /*!< 0x00002000 */ +#define I2C_ISR_ALERT I2C_ISR_ALERT_Msk /*!< SMBus alert */ +#define I2C_ISR_BUSY_Pos (15U) +#define I2C_ISR_BUSY_Msk (0x1UL << I2C_ISR_BUSY_Pos) /*!< 0x00008000 */ +#define I2C_ISR_BUSY I2C_ISR_BUSY_Msk /*!< Bus busy */ +#define I2C_ISR_DIR_Pos (16U) +#define I2C_ISR_DIR_Msk (0x1UL << I2C_ISR_DIR_Pos) /*!< 0x00010000 */ +#define I2C_ISR_DIR I2C_ISR_DIR_Msk /*!< Transfer direction (slave mode) */ +#define I2C_ISR_ADDCODE_Pos (17U) +#define I2C_ISR_ADDCODE_Msk (0x7FUL << I2C_ISR_ADDCODE_Pos) /*!< 0x00FE0000 */ +#define I2C_ISR_ADDCODE I2C_ISR_ADDCODE_Msk /*!< Address match code (slave mode) */ + +/****************** Bit definition for I2C_ICR register *********************/ +#define I2C_ICR_ADDRCF_Pos (3U) +#define I2C_ICR_ADDRCF_Msk (0x1UL << I2C_ICR_ADDRCF_Pos) /*!< 0x00000008 */ +#define I2C_ICR_ADDRCF I2C_ICR_ADDRCF_Msk /*!< Address matched clear flag */ +#define I2C_ICR_NACKCF_Pos (4U) +#define I2C_ICR_NACKCF_Msk (0x1UL << I2C_ICR_NACKCF_Pos) /*!< 0x00000010 */ +#define I2C_ICR_NACKCF I2C_ICR_NACKCF_Msk /*!< NACK clear flag */ +#define I2C_ICR_STOPCF_Pos (5U) +#define I2C_ICR_STOPCF_Msk (0x1UL << I2C_ICR_STOPCF_Pos) /*!< 0x00000020 */ +#define I2C_ICR_STOPCF I2C_ICR_STOPCF_Msk /*!< STOP detection clear flag */ +#define I2C_ICR_BERRCF_Pos (8U) +#define I2C_ICR_BERRCF_Msk (0x1UL << I2C_ICR_BERRCF_Pos) /*!< 0x00000100 */ +#define I2C_ICR_BERRCF I2C_ICR_BERRCF_Msk /*!< Bus error clear flag */ +#define I2C_ICR_ARLOCF_Pos (9U) +#define I2C_ICR_ARLOCF_Msk (0x1UL << I2C_ICR_ARLOCF_Pos) /*!< 0x00000200 */ +#define I2C_ICR_ARLOCF I2C_ICR_ARLOCF_Msk /*!< Arbitration lost clear flag */ +#define I2C_ICR_OVRCF_Pos (10U) +#define I2C_ICR_OVRCF_Msk (0x1UL << I2C_ICR_OVRCF_Pos) /*!< 0x00000400 */ +#define I2C_ICR_OVRCF I2C_ICR_OVRCF_Msk /*!< Overrun/Underrun clear flag */ +#define I2C_ICR_PECCF_Pos (11U) +#define I2C_ICR_PECCF_Msk (0x1UL << I2C_ICR_PECCF_Pos) /*!< 0x00000800 */ +#define I2C_ICR_PECCF I2C_ICR_PECCF_Msk /*!< PAC error clear flag */ +#define I2C_ICR_TIMOUTCF_Pos (12U) +#define I2C_ICR_TIMOUTCF_Msk (0x1UL << I2C_ICR_TIMOUTCF_Pos) /*!< 0x00001000 */ +#define I2C_ICR_TIMOUTCF I2C_ICR_TIMOUTCF_Msk /*!< Timeout clear flag */ +#define I2C_ICR_ALERTCF_Pos (13U) +#define I2C_ICR_ALERTCF_Msk (0x1UL << I2C_ICR_ALERTCF_Pos) /*!< 0x00002000 */ +#define I2C_ICR_ALERTCF I2C_ICR_ALERTCF_Msk /*!< Alert clear flag */ + +/****************** Bit definition for I2C_PECR register *********************/ +#define I2C_PECR_PEC_Pos (0U) +#define I2C_PECR_PEC_Msk (0xFFUL << I2C_PECR_PEC_Pos) /*!< 0x000000FF */ +#define I2C_PECR_PEC I2C_PECR_PEC_Msk /*!< PEC register */ + +/****************** Bit definition for I2C_RXDR register *********************/ +#define I2C_RXDR_RXDATA_Pos (0U) +#define I2C_RXDR_RXDATA_Msk (0xFFUL << I2C_RXDR_RXDATA_Pos) /*!< 0x000000FF */ +#define I2C_RXDR_RXDATA I2C_RXDR_RXDATA_Msk /*!< 8-bit receive data */ + +/****************** Bit definition for I2C_TXDR register *********************/ +#define I2C_TXDR_TXDATA_Pos (0U) +#define I2C_TXDR_TXDATA_Msk (0xFFUL << I2C_TXDR_TXDATA_Pos) /*!< 0x000000FF */ +#define I2C_TXDR_TXDATA I2C_TXDR_TXDATA_Msk /*!< 8-bit transmit data */ + + +/******************************************************************************/ +/* */ +/* Improved Inter-integrated Circuit Interface (I3C) */ +/* */ +/******************************************************************************/ +/******************* Bit definition for I3C_CR register *********************/ +#define I3C_CR_DCNT_Pos (0U) +#define I3C_CR_DCNT_Msk (0xFFFFUL << I3C_CR_DCNT_Pos) /*!< 0x0000FFFF */ +#define I3C_CR_DCNT I3C_CR_DCNT_Msk /*!< Data Byte Count */ +#define I3C_CR_RNW_Pos (16U) +#define I3C_CR_RNW_Msk (0x1UL << I3C_CR_RNW_Pos) /*!< 0x00010000 */ +#define I3C_CR_RNW I3C_CR_RNW_Msk /*!< Read Not Write */ +#define I3C_CR_CCC_Pos (16U) +#define I3C_CR_CCC_Msk (0xFFUL << I3C_CR_CCC_Pos) /*!< 0x00FF0000 */ +#define I3C_CR_CCC I3C_CR_CCC_Msk /*!< 8-Bit CCC code */ +#define I3C_CR_ADD_Pos (17U) +#define I3C_CR_ADD_Msk (0x7FUL << I3C_CR_ADD_Pos) /*!< 0x00FE0000 */ +#define I3C_CR_ADD I3C_CR_ADD_Msk /*!< Target Address */ +#define I3C_CR_MTYPE_Pos (27U) +#define I3C_CR_MTYPE_Msk (0xFUL << I3C_CR_MTYPE_Pos) /*!< 0xF8000000 */ +#define I3C_CR_MTYPE I3C_CR_MTYPE_Msk /*!< Message Type */ +#define I3C_CR_MTYPE_0 (0x1UL << I3C_CR_MTYPE_Pos) /*!< 0x08000000 */ +#define I3C_CR_MTYPE_1 (0x2UL << I3C_CR_MTYPE_Pos) /*!< 0x10000000 */ +#define I3C_CR_MTYPE_2 (0x4UL << I3C_CR_MTYPE_Pos) /*!< 0x20000000 */ +#define I3C_CR_MTYPE_3 (0x8UL << I3C_CR_MTYPE_Pos) /*!< 0x40000000 */ +#define I3C_CR_MEND_Pos (31U) +#define I3C_CR_MEND_Msk (0x1UL << I3C_CR_MEND_Pos) /*!< 0x80000000 */ +#define I3C_CR_MEND I3C_CR_MEND_Msk /*!< Message End */ + +/******************* Bit definition for I3C_CFGR register *******************/ +#define I3C_CFGR_EN_Pos (0U) +#define I3C_CFGR_EN_Msk (0x1UL << I3C_CFGR_EN_Pos) /*!< 0x00000001 */ +#define I3C_CFGR_EN I3C_CFGR_EN_Msk /*!< Peripheral Enable */ +#define I3C_CFGR_CRINIT_Pos (1U) +#define I3C_CFGR_CRINIT_Msk (0x1UL << I3C_CFGR_CRINIT_Pos) /*!< 0x00000002 */ +#define I3C_CFGR_CRINIT I3C_CFGR_CRINIT_Msk /*!< Peripheral Init mode (Target/Controller) */ +#define I3C_CFGR_NOARBH_Pos (2U) +#define I3C_CFGR_NOARBH_Msk (0x1UL << I3C_CFGR_NOARBH_Pos) /*!< 0x00000004 */ +#define I3C_CFGR_NOARBH I3C_CFGR_NOARBH_Msk /*!< No Arbitration Header (7'h7E)*/ +#define I3C_CFGR_RSTPTRN_Pos (3U) +#define I3C_CFGR_RSTPTRN_Msk (0x1UL << I3C_CFGR_RSTPTRN_Pos) /*!< 0x00000008 */ +#define I3C_CFGR_RSTPTRN I3C_CFGR_RSTPTRN_Msk /*!< Reset Pattern enable */ +#define I3C_CFGR_EXITPTRN_Pos (4U) +#define I3C_CFGR_EXITPTRN_Msk (0x1UL << I3C_CFGR_EXITPTRN_Pos) /*!< 0x00000010 */ +#define I3C_CFGR_EXITPTRN I3C_CFGR_EXITPTRN_Msk /*!< Exit Pattern enable */ +#define I3C_CFGR_HKSDAEN_Pos (5U) +#define I3C_CFGR_HKSDAEN_Msk (0x1UL << I3C_CFGR_HKSDAEN_Pos) /*!< 0x00000020 */ +#define I3C_CFGR_HKSDAEN I3C_CFGR_HKSDAEN_Msk /*!< High-Keeper on SDA Enable */ +#define I3C_CFGR_HJACK_Pos (7U) +#define I3C_CFGR_HJACK_Msk (0x1UL << I3C_CFGR_HJACK_Pos) /*!< 0x00000080 */ +#define I3C_CFGR_HJACK I3C_CFGR_HJACK_Msk /*!< Hot Join Acknowledgment */ +#define I3C_CFGR_RXDMAEN_Pos (8U) +#define I3C_CFGR_RXDMAEN_Msk (0x1UL << I3C_CFGR_RXDMAEN_Pos) /*!< 0x00000100 */ +#define I3C_CFGR_RXDMAEN I3C_CFGR_RXDMAEN_Msk /*!< RX FIFO DMA mode Enable */ +#define I3C_CFGR_RXFLUSH_Pos (9U) +#define I3C_CFGR_RXFLUSH_Msk (0x1UL << I3C_CFGR_RXFLUSH_Pos) /*!< 0x00000200 */ +#define I3C_CFGR_RXFLUSH I3C_CFGR_RXFLUSH_Msk /*!< RX FIFO Flush */ +#define I3C_CFGR_RXTHRES_Pos (10U) +#define I3C_CFGR_RXTHRES_Msk (0x1UL << I3C_CFGR_RXTHRES_Pos) /*!< 0x00000400 */ +#define I3C_CFGR_RXTHRES I3C_CFGR_RXTHRES_Msk /*!< RX FIFO Threshold */ +#define I3C_CFGR_TXDMAEN_Pos (12U) +#define I3C_CFGR_TXDMAEN_Msk (0x1UL << I3C_CFGR_TXDMAEN_Pos) /*!< 0x00001000 */ +#define I3C_CFGR_TXDMAEN I3C_CFGR_TXDMAEN_Msk /*!< TX FIFO DMA mode Enable */ +#define I3C_CFGR_TXFLUSH_Pos (13U) +#define I3C_CFGR_TXFLUSH_Msk (0x1UL << I3C_CFGR_TXFLUSH_Pos) /*!< 0x00002000 */ +#define I3C_CFGR_TXFLUSH I3C_CFGR_TXFLUSH_Msk /*!< TX FIFO Flush */ +#define I3C_CFGR_TXTHRES_Pos (14U) +#define I3C_CFGR_TXTHRES_Msk (0x1UL << I3C_CFGR_TXTHRES_Pos) /*!< 0x00004000 */ +#define I3C_CFGR_TXTHRES I3C_CFGR_TXTHRES_Msk /*!< TX FIFO Threshold */ +#define I3C_CFGR_SDMAEN_Pos (16U) +#define I3C_CFGR_SDMAEN_Msk (0x1UL << I3C_CFGR_SDMAEN_Pos) /*!< 0x00010000 */ +#define I3C_CFGR_SDMAEN I3C_CFGR_SDMAEN_Msk /*!< Status FIFO DMA mode Enable */ +#define I3C_CFGR_SFLUSH_Pos (17U) +#define I3C_CFGR_SFLUSH_Msk (0x1UL << I3C_CFGR_SFLUSH_Pos) /*!< 0x00020000 */ +#define I3C_CFGR_SFLUSH I3C_CFGR_SFLUSH_Msk /*!< Status FIFO Flush */ +#define I3C_CFGR_SMODE_Pos (18U) +#define I3C_CFGR_SMODE_Msk (0x1UL << I3C_CFGR_SMODE_Pos) /*!< 0x00040000 */ +#define I3C_CFGR_SMODE I3C_CFGR_SMODE_Msk /*!< Status FIFO mode Enable */ +#define I3C_CFGR_TMODE_Pos (19U) +#define I3C_CFGR_TMODE_Msk (0x1UL << I3C_CFGR_TMODE_Pos) /*!< 0x00080000 */ +#define I3C_CFGR_TMODE I3C_CFGR_TMODE_Msk /*!< Control FIFO mode Enable */ +#define I3C_CFGR_CDMAEN_Pos (20U) +#define I3C_CFGR_CDMAEN_Msk (0x1UL << I3C_CFGR_CDMAEN_Pos) /*!< 0x00100000 */ +#define I3C_CFGR_CDMAEN I3C_CFGR_CDMAEN_Msk /*!< Control FIFO DMA mode Enable */ +#define I3C_CFGR_CFLUSH_Pos (21U) +#define I3C_CFGR_CFLUSH_Msk (0x1UL << I3C_CFGR_CFLUSH_Pos) /*!< 0x00200000 */ +#define I3C_CFGR_CFLUSH I3C_CFGR_CFLUSH_Msk /*!< Control FIFO Flush */ +#define I3C_CFGR_TSFSET_Pos (30U) +#define I3C_CFGR_TSFSET_Msk (0x1UL << I3C_CFGR_TSFSET_Pos) /*!< 0x40000000 */ +#define I3C_CFGR_TSFSET I3C_CFGR_TSFSET_Msk /*!< Transfer Set */ + +/******************* Bit definition for I3C_RDR register ********************/ +#define I3C_RDR_RDB0_Pos (0U) +#define I3C_RDR_RDB0_Msk (0xFFUL << I3C_RDR_RDB0_Pos) /*!< 0x000000FF */ +#define I3C_RDR_RDB0 I3C_RDR_RDB0_Msk /*!< Receive Data Byte */ + +/****************** Bit definition for I3C_RDWR register ********************/ +#define I3C_RDWR_RDBx_Pos (0U) +#define I3C_RDWR_RDBx_Msk (0xFFFFFFFFUL << I3C_RDWR_RDBx_Pos) /*!< 0xFFFFFFFF */ +#define I3C_RDWR_RDBx I3C_RDWR_RDBx_Msk /*!< Receive Data Byte, full double word */ +#define I3C_RDWR_RDB0_Pos (0U) +#define I3C_RDWR_RDB0_Msk (0xFFUL << I3C_RDWR_RDB0_Pos) /*!< 0x000000FF */ +#define I3C_RDWR_RDB0 I3C_RDWR_RDB0_Msk /*!< Receive Data Byte 0 */ +#define I3C_RDWR_RDB1_Pos (8U) +#define I3C_RDWR_RDB1_Msk (0xFFUL << I3C_RDWR_RDB1_Pos) /*!< 0x0000FF00 */ +#define I3C_RDWR_RDB1 I3C_RDWR_RDB1_Msk /*!< Receive Data Byte 1 */ +#define I3C_RDWR_RDB2_Pos (16U) +#define I3C_RDWR_RDB2_Msk (0xFFUL << I3C_RDWR_RDB2_Pos) /*!< 0x00FF0000 */ +#define I3C_RDWR_RDB2 I3C_RDWR_RDB2_Msk /*!< Receive Data Byte 2 */ +#define I3C_RDWR_RDB3_Pos (24U) +#define I3C_RDWR_RDB3_Msk (0xFFUL << I3C_RDWR_RDB3_Pos) /*!< 0xFF000000 */ +#define I3C_RDWR_RDB3 I3C_RDWR_RDB3_Msk /*!< Receive Data Byte 3 */ + +/******************* Bit definition for I3C_TDR register ********************/ +#define I3C_TDR_TDB0_Pos (0U) +#define I3C_TDR_TDB0_Msk (0xFFUL << I3C_TDR_TDB0_Pos) /*!< 0x000000FF */ +#define I3C_TDR_TDB0 I3C_TDR_TDB0_Msk /*!< Transmit Data Byte */ + +/****************** Bit definition for I3C_TDWR register ********************/ +#define I3C_TDWR_TDBx_Pos (0U) +#define I3C_TDWR_TDBx_Msk (0xFFFFFFFFUL << I3C_TDWR_TDBx_Pos) /*!< 0xFFFFFFFF */ +#define I3C_TDWR_TDBx I3C_TDWR_TDBx_Msk /*!< Transmit Data Byte, full double word */ +#define I3C_TDWR_TDB0_Pos (0U) +#define I3C_TDWR_TDB0_Msk (0xFFUL << I3C_TDWR_TDB0_Pos) /*!< 0x000000FF */ +#define I3C_TDWR_TDB0 I3C_TDWR_TDB0_Msk /*!< Transmit Data Byte 0 */ +#define I3C_TDWR_TDB1_Pos (8U) +#define I3C_TDWR_TDB1_Msk (0xFFUL << I3C_TDWR_TDB1_Pos) /*!< 0x0000FF00 */ +#define I3C_TDWR_TDB1 I3C_TDWR_TDB1_Msk /*!< Transmit Data Byte 1 */ +#define I3C_TDWR_TDB2_Pos (16U) +#define I3C_TDWR_TDB2_Msk (0xFFUL << I3C_TDWR_TDB2_Pos) /*!< 0x00FF0000 */ +#define I3C_TDWR_TDB2 I3C_TDWR_TDB2_Msk /*!< Transmit Data Byte 2 */ +#define I3C_TDWR_TDB3_Pos (24U) +#define I3C_TDWR_TDB3_Msk (0xFFUL << I3C_TDWR_TDB3_Pos) /*!< 0xFF000000 */ +#define I3C_TDWR_TDB3 I3C_TDWR_TDB3_Msk /*!< Transmit Data Byte 3 */ + +/******************* Bit definition for I3C_IBIDR register ******************/ +#define I3C_IBIDR_IBIDBx_Pos (0U) +#define I3C_IBIDR_IBIDBx_Msk (0xFFFFFFFFUL << I3C_IBIDR_IBIDBx_Pos) /*!< 0xFFFFFFFF */ +#define I3C_IBIDR_IBIDBx I3C_IBIDR_IBIDBx_Msk /*!< IBI Data Byte, full double word */ +#define I3C_IBIDR_IBIDB0_Pos (0U) +#define I3C_IBIDR_IBIDB0_Msk (0xFFUL << I3C_IBIDR_IBIDB0_Pos) /*!< 0x000000FF */ +#define I3C_IBIDR_IBIDB0 I3C_IBIDR_IBIDB0_Msk /*!< IBI Data Byte 0 */ +#define I3C_IBIDR_IBIDB1_Pos (8U) +#define I3C_IBIDR_IBIDB1_Msk (0xFFUL << I3C_IBIDR_IBIDB1_Pos) /*!< 0x0000FF00 */ +#define I3C_IBIDR_IBIDB1 I3C_IBIDR_IBIDB1_Msk /*!< IBI Data Byte 1 */ +#define I3C_IBIDR_IBIDB2_Pos (16U) +#define I3C_IBIDR_IBIDB2_Msk (0xFFUL << I3C_IBIDR_IBIDB2_Pos) /*!< 0x00FF0000 */ +#define I3C_IBIDR_IBIDB2 I3C_IBIDR_IBIDB2_Msk /*!< IBI Data Byte 2 */ +#define I3C_IBIDR_IBIDB3_Pos (24U) +#define I3C_IBIDR_IBIDB3_Msk (0xFFUL << I3C_IBIDR_IBIDB3_Pos) /*!< 0xFF000000 */ +#define I3C_IBIDR_IBIDB3 I3C_IBIDR_IBIDB3_Msk /*!< IBI Data Byte 3 */ + +/****************** Bit definition for I3C_TGTTDR register ******************/ +#define I3C_TGTTDR_TGTTDCNT_Pos (0U) +#define I3C_TGTTDR_TGTTDCNT_Msk (0xFFFFUL << I3C_TGTTDR_TGTTDCNT_Pos) /*!< 0x0000FFFF */ +#define I3C_TGTTDR_TGTTDCNT I3C_TGTTDR_TGTTDCNT_Msk /*!< Target Transmit Data Counter */ +#define I3C_TGTTDR_PRELOAD_Pos (16U) +#define I3C_TGTTDR_PRELOAD_Msk (0x1UL << I3C_TGTTDR_PRELOAD_Pos) /*!< 0x00010000 */ +#define I3C_TGTTDR_PRELOAD I3C_TGTTDR_PRELOAD_Msk /*!< Transmit FIFO Preload Enable/Status */ + +/******************* Bit definition for I3C_SR register *********************/ +#define I3C_SR_XDCNT_Pos (0U) +#define I3C_SR_XDCNT_Msk (0xFFFFUL << I3C_SR_XDCNT_Pos) /*!< 0x0000FFFF */ +#define I3C_SR_XDCNT I3C_SR_XDCNT_Msk /*!< Transfer Data Byte Count status */ +#define I3C_SR_ABT_Pos (17U) +#define I3C_SR_ABT_Msk (0x1UL << I3C_SR_ABT_Pos) /*!< 0x00020000 */ +#define I3C_SR_ABT I3C_SR_ABT_Msk /*!< Target Abort Indication */ +#define I3C_SR_DIR_Pos (18U) +#define I3C_SR_DIR_Msk (0x1UL << I3C_SR_DIR_Pos) /*!< 0x00040000 */ +#define I3C_SR_DIR I3C_SR_DIR_Msk /*!< Message Direction */ +#define I3C_SR_MID_Pos (24U) +#define I3C_SR_MID_Msk (0xFFUL << I3C_SR_MID_Pos) /*!< 0xFF000000 */ +#define I3C_SR_MID I3C_SR_MID_Msk /*!< Message Identifier */ + +/******************* Bit definition for I3C_SER register ********************/ +#define I3C_SER_CODERR_Pos (0U) +#define I3C_SER_CODERR_Msk (0xFUL << I3C_SER_CODERR_Pos) /*!< 0x0000000F */ +#define I3C_SER_CODERR I3C_SER_CODERR_Msk /*!< Protocol Error Code */ +#define I3C_SER_CODERR_0 (0x1UL << I3C_SER_CODERR_Pos) /*!< 0x00000001 */ +#define I3C_SER_CODERR_1 (0x2UL << I3C_SER_CODERR_Pos) /*!< 0x00000002 */ +#define I3C_SER_CODERR_2 (0x4UL << I3C_SER_CODERR_Pos) /*!< 0x00000004 */ +#define I3C_SER_CODERR_3 (0x8UL << I3C_SER_CODERR_Pos) /*!< 0x00000008 */ +#define I3C_SER_PERR_Pos (4U) +#define I3C_SER_PERR_Msk (0x1UL << I3C_SER_PERR_Pos) /*!< 0x00000010 */ +#define I3C_SER_PERR I3C_SER_PERR_Msk /*!< Protocol Error */ +#define I3C_SER_STALL_Pos (5U) +#define I3C_SER_STALL_Msk (0x1UL << I3C_SER_STALL_Pos) /*!< 0x00000020 */ +#define I3C_SER_STALL I3C_SER_STALL_Msk /*!< SCL Stall Error */ +#define I3C_SER_DOVR_Pos (6U) +#define I3C_SER_DOVR_Msk (0x1UL << I3C_SER_DOVR_Pos) /*!< 0x00000040 */ +#define I3C_SER_DOVR I3C_SER_DOVR_Msk /*!< RX/TX FIFO Overrun */ +#define I3C_SER_COVR_Pos (7U) +#define I3C_SER_COVR_Msk (0x1UL << I3C_SER_COVR_Pos) /*!< 0x00000080 */ +#define I3C_SER_COVR I3C_SER_COVR_Msk /*!< Status/Control FIFO Overrun */ +#define I3C_SER_ANACK_Pos (8U) +#define I3C_SER_ANACK_Msk (0x1UL << I3C_SER_ANACK_Pos) /*!< 0x00000100 */ +#define I3C_SER_ANACK I3C_SER_ANACK_Msk /*!< Address Not Acknowledged */ +#define I3C_SER_DNACK_Pos (9U) +#define I3C_SER_DNACK_Msk (0x1UL << I3C_SER_DNACK_Pos) /*!< 0x00000200 */ +#define I3C_SER_DNACK I3C_SER_DNACK_Msk /*!< Data Not Acknowledged */ +#define I3C_SER_DERR_Pos (10U) +#define I3C_SER_DERR_Msk (0x1UL << I3C_SER_DERR_Pos) /*!< 0x00000400 */ +#define I3C_SER_DERR I3C_SER_DERR_Msk /*!< Data Error during the controller-role hand-off procedure */ + +/******************* Bit definition for I3C_RMR register ********************/ +#define I3C_RMR_IBIRDCNT_Pos (0U) +#define I3C_RMR_IBIRDCNT_Msk (0x7UL << I3C_RMR_IBIRDCNT_Pos) /*!< 0x00000007 */ +#define I3C_RMR_IBIRDCNT I3C_RMR_IBIRDCNT_Msk /*!< Data Count when reading IBI data */ +#define I3C_RMR_RCODE_Pos (8U) +#define I3C_RMR_RCODE_Msk (0xFFUL << I3C_RMR_RCODE_Pos) /*!< 0x0000FF00 */ +#define I3C_RMR_RCODE I3C_RMR_RCODE_Msk /*!< CCC code of received command */ +#define I3C_RMR_RADD_Pos (17U) +#define I3C_RMR_RADD_Msk (0x7FUL << I3C_RMR_RADD_Pos) /*!< 0x00FE0000 */ +#define I3C_RMR_RADD I3C_RMR_RADD_Msk /*!< Target Address Received during accepted IBI or Controller-role request */ + +/******************* Bit definition for I3C_EVR register ********************/ +#define I3C_EVR_CFEF_Pos (0U) +#define I3C_EVR_CFEF_Msk (0x1UL << I3C_EVR_CFEF_Pos) /*!< 0x00000001 */ +#define I3C_EVR_CFEF I3C_EVR_CFEF_Msk /*!< Control FIFO Empty Flag */ +#define I3C_EVR_TXFEF_Pos (1U) +#define I3C_EVR_TXFEF_Msk (0x1UL << I3C_EVR_TXFEF_Pos) /*!< 0x00000002 */ +#define I3C_EVR_TXFEF I3C_EVR_TXFEF_Msk /*!< TX FIFO Empty Flag */ +#define I3C_EVR_CFNFF_Pos (2U) +#define I3C_EVR_CFNFF_Msk (0x1UL << I3C_EVR_CFNFF_Pos) /*!< 0x00000004 */ +#define I3C_EVR_CFNFF I3C_EVR_CFNFF_Msk /*!< Control FIFO Not Full Flag */ +#define I3C_EVR_SFNEF_Pos (3U) +#define I3C_EVR_SFNEF_Msk (0x1UL << I3C_EVR_SFNEF_Pos) /*!< 0x00000008 */ +#define I3C_EVR_SFNEF I3C_EVR_SFNEF_Msk /*!< Status FIFO Not Empty Flag */ +#define I3C_EVR_TXFNFF_Pos (4U) +#define I3C_EVR_TXFNFF_Msk (0x1UL << I3C_EVR_TXFNFF_Pos) /*!< 0x00000010 */ +#define I3C_EVR_TXFNFF I3C_EVR_TXFNFF_Msk /*!< TX FIFO Not Full Flag */ +#define I3C_EVR_RXFNEF_Pos (5U) +#define I3C_EVR_RXFNEF_Msk (0x1UL << I3C_EVR_RXFNEF_Pos) /*!< 0x00000020 */ +#define I3C_EVR_RXFNEF I3C_EVR_RXFNEF_Msk /*!< RX FIFO Not Empty Flag */ +#define I3C_EVR_TXLASTF_Pos (6U) +#define I3C_EVR_TXLASTF_Msk (0x1UL << I3C_EVR_TXLASTF_Pos) /*!< 0x00000040 */ +#define I3C_EVR_TXLASTF I3C_EVR_TXLASTF_Msk /*!< Last TX byte available in FIFO */ +#define I3C_EVR_RXLASTF_Pos (7U) +#define I3C_EVR_RXLASTF_Msk (0x1UL << I3C_EVR_RXLASTF_Pos) /*!< 0x00000080 */ +#define I3C_EVR_RXLASTF I3C_EVR_RXLASTF_Msk /*!< Last RX byte read from FIFO */ +#define I3C_EVR_FCF_Pos (9U) +#define I3C_EVR_FCF_Msk (0x1UL << I3C_EVR_FCF_Pos) /*!< 0x00000200 */ +#define I3C_EVR_FCF I3C_EVR_FCF_Msk /*!< Frame Complete Flag */ +#define I3C_EVR_RXTGTENDF_Pos (10U) +#define I3C_EVR_RXTGTENDF_Msk (0x1UL << I3C_EVR_RXTGTENDF_Pos) /*!< 0x00000400 */ +#define I3C_EVR_RXTGTENDF I3C_EVR_RXTGTENDF_Msk /*!< Reception Target End Flag */ +#define I3C_EVR_ERRF_Pos (11U) +#define I3C_EVR_ERRF_Msk (0x1UL << I3C_EVR_ERRF_Pos) /*!< 0x00000800 */ +#define I3C_EVR_ERRF I3C_EVR_ERRF_Msk /*!< Error Flag */ +#define I3C_EVR_IBIF_Pos (15U) +#define I3C_EVR_IBIF_Msk (0x1UL << I3C_EVR_IBIF_Pos) /*!< 0x00008000 */ +#define I3C_EVR_IBIF I3C_EVR_IBIF_Msk /*!< IBI Flag */ +#define I3C_EVR_IBIENDF_Pos (16U) +#define I3C_EVR_IBIENDF_Msk (0x1UL << I3C_EVR_IBIENDF_Pos) /*!< 0x00010000 */ +#define I3C_EVR_IBIENDF I3C_EVR_IBIENDF_Msk /*!< IBI End Flag */ +#define I3C_EVR_CRF_Pos (17U) +#define I3C_EVR_CRF_Msk (0x1UL << I3C_EVR_CRF_Pos) /*!< 0x00020000 */ +#define I3C_EVR_CRF I3C_EVR_CRF_Msk /*!< Controller-role Request Flag */ +#define I3C_EVR_CRUPDF_Pos (18U) +#define I3C_EVR_CRUPDF_Msk (0x1UL << I3C_EVR_CRUPDF_Pos) /*!< 0x00040000 */ +#define I3C_EVR_CRUPDF I3C_EVR_CRUPDF_Msk /*!< Controller-role Update Flag */ +#define I3C_EVR_HJF_Pos (19U) +#define I3C_EVR_HJF_Msk (0x1UL << I3C_EVR_HJF_Pos) /*!< 0x00080000 */ +#define I3C_EVR_HJF I3C_EVR_HJF_Msk /*!< Hot Join Flag */ +#define I3C_EVR_WKPF_Pos (21U) +#define I3C_EVR_WKPF_Msk (0x1UL << I3C_EVR_WKPF_Pos) /*!< 0x00200000 */ +#define I3C_EVR_WKPF I3C_EVR_WKPF_Msk /*!< Wake Up Flag */ +#define I3C_EVR_GETF_Pos (22U) +#define I3C_EVR_GETF_Msk (0x1UL << I3C_EVR_GETF_Pos) /*!< 0x00400000 */ +#define I3C_EVR_GETF I3C_EVR_GETF_Msk /*!< Get type CCC received Flag */ +#define I3C_EVR_STAF_Pos (23U) +#define I3C_EVR_STAF_Msk (0x1UL << I3C_EVR_STAF_Pos) /*!< 0x00800000 */ +#define I3C_EVR_STAF I3C_EVR_STAF_Msk /*!< Get Status Flag */ +#define I3C_EVR_DAUPDF_Pos (24U) +#define I3C_EVR_DAUPDF_Msk (0x1UL << I3C_EVR_DAUPDF_Pos) /*!< 0x01000000 */ +#define I3C_EVR_DAUPDF I3C_EVR_DAUPDF_Msk /*!< Dynamic Address Update Flag */ +#define I3C_EVR_MWLUPDF_Pos (25U) +#define I3C_EVR_MWLUPDF_Msk (0x1UL << I3C_EVR_MWLUPDF_Pos) /*!< 0x02000000 */ +#define I3C_EVR_MWLUPDF I3C_EVR_MWLUPDF_Msk /*!< Max Write Length Update Flag */ +#define I3C_EVR_MRLUPDF_Pos (26U) +#define I3C_EVR_MRLUPDF_Msk (0x1UL << I3C_EVR_MRLUPDF_Pos) /*!< 0x04000000 */ +#define I3C_EVR_MRLUPDF I3C_EVR_MRLUPDF_Msk /*!< Max Read Length Update Flag */ +#define I3C_EVR_RSTF_Pos (27U) +#define I3C_EVR_RSTF_Msk (0x1UL << I3C_EVR_RSTF_Pos) /*!< 0x08000000 */ +#define I3C_EVR_RSTF I3C_EVR_RSTF_Msk /*!< Reset Flag, due to Reset pattern received */ +#define I3C_EVR_ASUPDF_Pos (28U) +#define I3C_EVR_ASUPDF_Msk (0x1UL << I3C_EVR_ASUPDF_Pos) /*!< 0x10000000 */ +#define I3C_EVR_ASUPDF I3C_EVR_ASUPDF_Msk /*!< Activity State Flag */ +#define I3C_EVR_INTUPDF_Pos (29U) +#define I3C_EVR_INTUPDF_Msk (0x1UL << I3C_EVR_INTUPDF_Pos) /*!< 0x20000000 */ +#define I3C_EVR_INTUPDF I3C_EVR_INTUPDF_Msk /*!< Interrupt Update Flag */ +#define I3C_EVR_DEFF_Pos (30U) +#define I3C_EVR_DEFF_Msk (0x1UL << I3C_EVR_DEFF_Pos) /*!< 0x40000000 */ +#define I3C_EVR_DEFF I3C_EVR_DEFF_Msk /*!< List of Targets Command Received Flag */ +#define I3C_EVR_GRPF_Pos (31U) +#define I3C_EVR_GRPF_Msk (0x1UL << I3C_EVR_GRPF_Pos) /*!< 0x80000000 */ +#define I3C_EVR_GRPF I3C_EVR_GRPF_Msk /*!< List of Group Addresses Command Received Flag */ + +/******************* Bit definition for I3C_IER register ********************/ +#define I3C_IER_CFNFIE_Pos (2U) +#define I3C_IER_CFNFIE_Msk (0x1UL << I3C_IER_CFNFIE_Pos) /*!< 0x00000004 */ +#define I3C_IER_CFNFIE I3C_IER_CFNFIE_Msk /*!< Control FIFO Not Full Interrupt Enable */ +#define I3C_IER_SFNEIE_Pos (3U) +#define I3C_IER_SFNEIE_Msk (0x1UL << I3C_IER_SFNEIE_Pos) /*!< 0x00000008 */ +#define I3C_IER_SFNEIE I3C_IER_SFNEIE_Msk /*!< Status FIFO Not Empty Interrupt Enable */ +#define I3C_IER_TXFNFIE_Pos (4U) +#define I3C_IER_TXFNFIE_Msk (0x1UL << I3C_IER_TXFNFIE_Pos) /*!< 0x00000010 */ +#define I3C_IER_TXFNFIE I3C_IER_TXFNFIE_Msk /*!< TX FIFO Not Full Interrupt Enable */ +#define I3C_IER_RXFNEIE_Pos (5U) +#define I3C_IER_RXFNEIE_Msk (0x1UL << I3C_IER_RXFNEIE_Pos) /*!< 0x00000020 */ +#define I3C_IER_RXFNEIE I3C_IER_RXFNEIE_Msk /*!< RX FIFO Not Empty Interrupt Enable */ +#define I3C_IER_FCIE_Pos (9U) +#define I3C_IER_FCIE_Msk (0x1UL << I3C_IER_FCIE_Pos) /*!< 0x00000200 */ +#define I3C_IER_FCIE I3C_IER_FCIE_Msk /*!< Frame Complete Interrupt Enable */ +#define I3C_IER_RXTGTENDIE_Pos (10U) +#define I3C_IER_RXTGTENDIE_Msk (0x1UL << I3C_IER_RXTGTENDIE_Pos) /*!< 0x00000400 */ +#define I3C_IER_RXTGTENDIE I3C_IER_RXTGTENDIE_Msk /*!< Reception Target End Interrupt Enable */ +#define I3C_IER_ERRIE_Pos (11U) +#define I3C_IER_ERRIE_Msk (0x1UL << I3C_IER_ERRIE_Pos) /*!< 0x00000800 */ +#define I3C_IER_ERRIE I3C_IER_ERRIE_Msk /*!< Error Interrupt Enable */ +#define I3C_IER_IBIIE_Pos (15U) +#define I3C_IER_IBIIE_Msk (0x1UL << I3C_IER_IBIIE_Pos) /*!< 0x00008000 */ +#define I3C_IER_IBIIE I3C_IER_IBIIE_Msk /*!< IBI Interrupt Enable */ +#define I3C_IER_IBIENDIE_Pos (16U) +#define I3C_IER_IBIENDIE_Msk (0x1UL << I3C_IER_IBIENDIE_Pos) /*!< 0x00010000 */ +#define I3C_IER_IBIENDIE I3C_IER_IBIENDIE_Msk /*!< IBI End Interrupt Enable */ +#define I3C_IER_CRIE_Pos (17U) +#define I3C_IER_CRIE_Msk (0x1UL << I3C_IER_CRIE_Pos) /*!< 0x00020000 */ +#define I3C_IER_CRIE I3C_IER_CRIE_Msk /*!< Controller-role Interrupt Enable */ +#define I3C_IER_CRUPDIE_Pos (18U) +#define I3C_IER_CRUPDIE_Msk (0x1UL << I3C_IER_CRUPDIE_Pos) /*!< 0x00040000 */ +#define I3C_IER_CRUPDIE I3C_IER_CRUPDIE_Msk /*!< Controller-role Update Interrupt Enable */ +#define I3C_IER_HJIE_Pos (19U) +#define I3C_IER_HJIE_Msk (0x1UL << I3C_IER_HJIE_Pos) /*!< 0x00080000 */ +#define I3C_IER_HJIE I3C_IER_HJIE_Msk /*!< Hot Join Interrupt Enable */ +#define I3C_IER_WKPIE_Pos (21U) +#define I3C_IER_WKPIE_Msk (0x1UL << I3C_IER_WKPIE_Pos) /*!< 0x00200000 */ +#define I3C_IER_WKPIE I3C_IER_WKPIE_Msk /*!< Wake Up Interrupt Enable */ +#define I3C_IER_GETIE_Pos (22U) +#define I3C_IER_GETIE_Msk (0x1UL << I3C_IER_GETIE_Pos) /*!< 0x00400000 */ +#define I3C_IER_GETIE I3C_IER_GETIE_Msk /*!< Get type CCC received Interrupt Enable */ +#define I3C_IER_STAIE_Pos (23U) +#define I3C_IER_STAIE_Msk (0x1UL << I3C_IER_STAIE_Pos) /*!< 0x00800000 */ +#define I3C_IER_STAIE I3C_IER_STAIE_Msk /*!< Get Status Interrupt Enable */ +#define I3C_IER_DAUPDIE_Pos (24U) +#define I3C_IER_DAUPDIE_Msk (0x1UL << I3C_IER_DAUPDIE_Pos) /*!< 0x01000000 */ +#define I3C_IER_DAUPDIE I3C_IER_DAUPDIE_Msk /*!< Dynamic Address Update Interrupt Enable */ +#define I3C_IER_MWLUPDIE_Pos (25U) +#define I3C_IER_MWLUPDIE_Msk (0x1UL << I3C_IER_MWLUPDIE_Pos) /*!< 0x02000000 */ +#define I3C_IER_MWLUPDIE I3C_IER_MWLUPDIE_Msk /*!< Max Write Length Update Interrupt Enable */ +#define I3C_IER_MRLUPDIE_Pos (26U) +#define I3C_IER_MRLUPDIE_Msk (0x1UL << I3C_IER_MRLUPDIE_Pos) /*!< 0x04000000 */ +#define I3C_IER_MRLUPDIE I3C_IER_MRLUPDIE_Msk /*!< Max Read Length Update Interrupt Enable */ +#define I3C_IER_RSTIE_Pos (27U) +#define I3C_IER_RSTIE_Msk (0x1UL << I3C_IER_RSTIE_Pos) /*!< 0x08000000 */ +#define I3C_IER_RSTIE I3C_IER_RSTIE_Msk /*!< Reset Interrupt Enabled, due to Reset pattern received */ +#define I3C_IER_ASUPDIE_Pos (28U) +#define I3C_IER_ASUPDIE_Msk (0x1UL << I3C_IER_ASUPDIE_Pos) /*!< 0x10000000 */ +#define I3C_IER_ASUPDIE I3C_IER_ASUPDIE_Msk /*!< Activity State Interrupt Enable */ +#define I3C_IER_INTUPDIE_Pos (29U) +#define I3C_IER_INTUPDIE_Msk (0x1UL << I3C_IER_INTUPDIE_Pos) /*!< 0x20000000 */ +#define I3C_IER_INTUPDIE I3C_IER_INTUPDIE_Msk /*!< Interrupt Update Interrupt Enable */ +#define I3C_IER_DEFIE_Pos (30U) +#define I3C_IER_DEFIE_Msk (0x1UL << I3C_IER_DEFIE_Pos) /*!< 0x40000000 */ +#define I3C_IER_DEFIE I3C_IER_DEFIE_Msk /*!< List of Targets Command Received Interrupt Enable */ +#define I3C_IER_GRPIE_Pos (31U) +#define I3C_IER_GRPIE_Msk (0x1UL << I3C_IER_GRPIE_Pos) /*!< 0x80000000 */ +#define I3C_IER_GRPIE I3C_IER_GRPIE_Msk /*!< List of Group Addresses Command Received Interrupt Enable */ + +/******************* Bit definition for I3C_CEVR register *******************/ +#define I3C_CEVR_CFCF_Pos (9U) +#define I3C_CEVR_CFCF_Msk (0x1UL << I3C_CEVR_CFCF_Pos) /*!< 0x00000200 */ +#define I3C_CEVR_CFCF I3C_CEVR_CFCF_Msk /*!< Frame Complete Clear Flag */ +#define I3C_CEVR_CRXTGTENDF_Pos (10U) +#define I3C_CEVR_CRXTGTENDF_Msk (0x1UL << I3C_CEVR_CRXTGTENDF_Pos) /*!< 0x00000400 */ +#define I3C_CEVR_CRXTGTENDF I3C_CEVR_CRXTGTENDF_Msk /*!< Reception Target End Clear Flag */ +#define I3C_CEVR_CERRF_Pos (11U) +#define I3C_CEVR_CERRF_Msk (0x1UL << I3C_CEVR_CERRF_Pos) /*!< 0x00000800 */ +#define I3C_CEVR_CERRF I3C_CEVR_CERRF_Msk /*!< Error Clear Flag */ +#define I3C_CEVR_CIBIF_Pos (15U) +#define I3C_CEVR_CIBIF_Msk (0x1UL << I3C_CEVR_CIBIF_Pos) /*!< 0x00008000 */ +#define I3C_CEVR_CIBIF I3C_CEVR_CIBIF_Msk /*!< IBI Clear Flag */ +#define I3C_CEVR_CIBIENDF_Pos (16U) +#define I3C_CEVR_CIBIENDF_Msk (0x1UL << I3C_CEVR_CIBIENDF_Pos) /*!< 0x00010000 */ +#define I3C_CEVR_CIBIENDF I3C_CEVR_CIBIENDF_Msk /*!< IBI End Clear Flag */ +#define I3C_CEVR_CCRF_Pos (17U) +#define I3C_CEVR_CCRF_Msk (0x1UL << I3C_CEVR_CCRF_Pos) /*!< 0x00020000 */ +#define I3C_CEVR_CCRF I3C_CEVR_CCRF_Msk /*!< Controller-role Clear Flag */ +#define I3C_CEVR_CCRUPDF_Pos (18U) +#define I3C_CEVR_CCRUPDF_Msk (0x1UL << I3C_CEVR_CCRUPDF_Pos) /*!< 0x00040000 */ +#define I3C_CEVR_CCRUPDF I3C_CEVR_CCRUPDF_Msk /*!< Controller-role Update Clear Flag */ +#define I3C_CEVR_CHJF_Pos (19U) +#define I3C_CEVR_CHJF_Msk (0x1UL << I3C_CEVR_CHJF_Pos) /*!< 0x00080000 */ +#define I3C_CEVR_CHJF I3C_CEVR_CHJF_Msk /*!< Hot Join Clear Flag */ +#define I3C_CEVR_CWKPF_Pos (21U) +#define I3C_CEVR_CWKPF_Msk (0x1UL << I3C_CEVR_CWKPF_Pos) /*!< 0x00200000 */ +#define I3C_CEVR_CWKPF I3C_CEVR_CWKPF_Msk /*!< Wake Up Clear Flag */ +#define I3C_CEVR_CGETF_Pos (22U) +#define I3C_CEVR_CGETF_Msk (0x1UL << I3C_CEVR_CGETF_Pos) /*!< 0x00400000 */ +#define I3C_CEVR_CGETF I3C_CEVR_CGETF_Msk /*!< Get type CCC received Clear Flag */ +#define I3C_CEVR_CSTAF_Pos (23U) +#define I3C_CEVR_CSTAF_Msk (0x1UL << I3C_CEVR_CSTAF_Pos) /*!< 0x00800000 */ +#define I3C_CEVR_CSTAF I3C_CEVR_CSTAF_Msk /*!< Get Status Clear Flag */ +#define I3C_CEVR_CDAUPDF_Pos (24U) +#define I3C_CEVR_CDAUPDF_Msk (0x1UL << I3C_CEVR_CDAUPDF_Pos) /*!< 0x01000000 */ +#define I3C_CEVR_CDAUPDF I3C_CEVR_CDAUPDF_Msk /*!< Dynamic Address Update Clear Flag */ +#define I3C_CEVR_CMWLUPDF_Pos (25U) +#define I3C_CEVR_CMWLUPDF_Msk (0x1UL << I3C_CEVR_CMWLUPDF_Pos) /*!< 0x02000000 */ +#define I3C_CEVR_CMWLUPDF I3C_CEVR_CMWLUPDF_Msk /*!< Max Write Length Update Clear Flag */ +#define I3C_CEVR_CMRLUPDF_Pos (26U) +#define I3C_CEVR_CMRLUPDF_Msk (0x1UL << I3C_CEVR_CMRLUPDF_Pos) /*!< 0x04000000 */ +#define I3C_CEVR_CMRLUPDF I3C_CEVR_CMRLUPDF_Msk /*!< Max Read Length Update Clear Flag */ +#define I3C_CEVR_CRSTF_Pos (27U) +#define I3C_CEVR_CRSTF_Msk (0x1UL << I3C_CEVR_CRSTF_Pos) /*!< 0x08000000 */ +#define I3C_CEVR_CRSTF I3C_CEVR_CRSTF_Msk /*!< Reset Flag, due to Reset pattern received */ +#define I3C_CEVR_CASUPDF_Pos (28U) +#define I3C_CEVR_CASUPDF_Msk (0x1UL << I3C_CEVR_CASUPDF_Pos) /*!< 0x10000000 */ +#define I3C_CEVR_CASUPDF I3C_CEVR_CASUPDF_Msk /*!< Activity State Clear Flag */ +#define I3C_CEVR_CINTUPDF_Pos (29U) +#define I3C_CEVR_CINTUPDF_Msk (0x1UL << I3C_CEVR_CINTUPDF_Pos) /*!< 0x20000000 */ +#define I3C_CEVR_CINTUPDF I3C_CEVR_CINTUPDF_Msk /*!< Interrupt Update Clear Flag */ +#define I3C_CEVR_CDEFF_Pos (30U) +#define I3C_CEVR_CDEFF_Msk (0x1UL << I3C_CEVR_CDEFF_Pos) /*!< 0x40000000 */ +#define I3C_CEVR_CDEFF I3C_CEVR_CDEFF_Msk /*!< List of Targets Command Received Clear Flag */ +#define I3C_CEVR_CGRPF_Pos (31U) +#define I3C_CEVR_CGRPF_Msk (0x1UL << I3C_CEVR_CGRPF_Pos) /*!< 0x80000000 */ +#define I3C_CEVR_CGRPF I3C_CEVR_CGRPF_Msk /*!< List of Group Addresses Command Received Clear Flag */ + +/****************** Bit definition for I3C_DEVR0 register *******************/ +#define I3C_DEVR0_DAVAL_Pos (0U) +#define I3C_DEVR0_DAVAL_Msk (0x1UL << I3C_DEVR0_DAVAL_Pos) /*!< 0x00000001 */ +#define I3C_DEVR0_DAVAL I3C_DEVR0_DAVAL_Msk /*!< Dynamic Address Validity */ +#define I3C_DEVR0_DA_Pos (1U) +#define I3C_DEVR0_DA_Msk (0x7FUL << I3C_DEVR0_DA_Pos) /*!< 0x000000FE */ +#define I3C_DEVR0_DA I3C_DEVR0_DA_Msk /*!< Own Target Device Address */ +#define I3C_DEVR0_IBIEN_Pos (16U) +#define I3C_DEVR0_IBIEN_Msk (0x1UL << I3C_DEVR0_IBIEN_Pos) /*!< 0x00010000 */ +#define I3C_DEVR0_IBIEN I3C_DEVR0_IBIEN_Msk /*!< IBI Enable */ +#define I3C_DEVR0_CREN_Pos (17U) +#define I3C_DEVR0_CREN_Msk (0x1UL << I3C_DEVR0_CREN_Pos) /*!< 0x00020000 */ +#define I3C_DEVR0_CREN I3C_DEVR0_CREN_Msk /*!< Controller-role Enable */ +#define I3C_DEVR0_HJEN_Pos (19U) +#define I3C_DEVR0_HJEN_Msk (0x1UL << I3C_DEVR0_HJEN_Pos) /*!< 0x00080000 */ +#define I3C_DEVR0_HJEN I3C_DEVR0_HJEN_Msk /*!< Hot Join Enable */ +#define I3C_DEVR0_AS_Pos (20U) +#define I3C_DEVR0_AS_Msk (0x3UL << I3C_DEVR0_AS_Pos) /*!< 0x00300000 */ +#define I3C_DEVR0_AS I3C_DEVR0_AS_Msk /*!< Activity State value update after ENTAx received */ +#define I3C_DEVR0_AS_0 (0x1UL << I3C_DEVR0_AS_Pos) /*!< 0x00100000 */ +#define I3C_DEVR0_AS_1 (0x2UL << I3C_DEVR0_AS_Pos) /*!< 0x00200000 */ +#define I3C_DEVR0_RSTACT_Pos (22U) +#define I3C_DEVR0_RSTACT_Msk (0x3UL << I3C_DEVR0_RSTACT_Pos) /*!< 0x00C000000 */ +#define I3C_DEVR0_RSTACT I3C_DEVR0_RSTACT_Msk /*!< Reset Action value update after RSTACT received */ +#define I3C_DEVR0_RSTACT_0 (0x1UL << I3C_DEVR0_RSTACT_Pos) /*!< 0x00400000 */ +#define I3C_DEVR0_RSTACT_1 (0x2UL << I3C_DEVR0_RSTACT_Pos) /*!< 0x00800000 */ +#define I3C_DEVR0_RSTVAL_Pos (24U) +#define I3C_DEVR0_RSTVAL_Msk (0x1UL << I3C_DEVR0_RSTVAL_Pos) /*!< 0x01000000 */ +#define I3C_DEVR0_RSTVAL I3C_DEVR0_RSTVAL_Msk /*!< Reset Action Valid */ + +/****************** Bit definition for I3C_DEVRX register *******************/ +#define I3C_DEVRX_DA_Pos (1U) +#define I3C_DEVRX_DA_Msk (0x7FUL << I3C_DEVRX_DA_Pos) /*!< 0x000000FE */ +#define I3C_DEVRX_DA I3C_DEVRX_DA_Msk /*!< Dynamic Address Target x */ +#define I3C_DEVRX_IBIACK_Pos (16U) +#define I3C_DEVRX_IBIACK_Msk (0x1UL << I3C_DEVRX_IBIACK_Pos) /*!< 0x00010000 */ +#define I3C_DEVRX_IBIACK I3C_DEVRX_IBIACK_Msk /*!< IBI Acknowledge from Target x */ +#define I3C_DEVRX_CRACK_Pos (17U) +#define I3C_DEVRX_CRACK_Msk (0x1UL << I3C_DEVRX_CRACK_Pos) /*!< 0x00020000 */ +#define I3C_DEVRX_CRACK I3C_DEVRX_CRACK_Msk /*!< Controller-role Acknowledge from Target x */ +#define I3C_DEVRX_IBIDEN_Pos (18U) +#define I3C_DEVRX_IBIDEN_Msk (0x1UL << I3C_DEVRX_IBIDEN_Pos) /*!< 0x00040000 */ +#define I3C_DEVRX_IBIDEN I3C_DEVRX_IBIDEN_Msk /*!< IBI Additional Data Enable */ +#define I3C_DEVRX_SUSP_Pos (19U) +#define I3C_DEVRX_SUSP_Msk (0x1UL << I3C_DEVRX_SUSP_Pos) /*!< 0x00080000 */ +#define I3C_DEVRX_SUSP I3C_DEVRX_SUSP_Msk /*!< Suspended Transfer */ +#define I3C_DEVRX_DIS_Pos (31U) +#define I3C_DEVRX_DIS_Msk (0x1UL << I3C_DEVRX_DIS_Pos) /*!< 0x80000000 */ +#define I3C_DEVRX_DIS I3C_DEVRX_DIS_Msk /*!< Disable Register access */ + +/****************** Bit definition for I3C_MAXRLR register ******************/ +#define I3C_MAXRLR_MRL_Pos (0U) +#define I3C_MAXRLR_MRL_Msk (0xFFFFUL << I3C_MAXRLR_MRL_Pos) /*!< 0x0000FFFF */ +#define I3C_MAXRLR_MRL I3C_MAXRLR_MRL_Msk /*!< Maximum Read Length */ +#define I3C_MAXRLR_IBIP_Pos (16U) +#define I3C_MAXRLR_IBIP_Msk (0x7UL << I3C_MAXRLR_IBIP_Pos) /*!< 0x00070000 */ +#define I3C_MAXRLR_IBIP I3C_MAXRLR_IBIP_Msk /*!< IBI Payload size */ +#define I3C_MAXRLR_IBIP_0 (0x1UL << I3C_MAXRLR_IBIP_Pos) /*!< 0x00010000 */ +#define I3C_MAXRLR_IBIP_1 (0x2UL << I3C_MAXRLR_IBIP_Pos) /*!< 0x00020000 */ +#define I3C_MAXRLR_IBIP_2 (0x4UL << I3C_MAXRLR_IBIP_Pos) /*!< 0x00040000 */ + +/****************** Bit definition for I3C_MAXWLR register ******************/ +#define I3C_MAXWLR_MWL_Pos (0U) +#define I3C_MAXWLR_MWL_Msk (0xFFFFUL << I3C_MAXWLR_MWL_Pos) /*!< 0x0000FFFF */ +#define I3C_MAXWLR_MWL I3C_MAXWLR_MWL_Msk /*!< Maximum Write Length */ + +/**************** Bit definition for I3C_TIMINGR0 register ******************/ +#define I3C_TIMINGR0_SCLL_PP_Pos (0U) +#define I3C_TIMINGR0_SCLL_PP_Msk (0xFFUL << I3C_TIMINGR0_SCLL_PP_Pos) /*!< 0x000000FF */ +#define I3C_TIMINGR0_SCLL_PP I3C_TIMINGR0_SCLL_PP_Msk /*!< SCL Low duration during I3C Push-Pull phases */ +#define I3C_TIMINGR0_SCLH_I3C_Pos (8U) +#define I3C_TIMINGR0_SCLH_I3C_Msk (0xFFUL << I3C_TIMINGR0_SCLH_I3C_Pos) /*!< 0x0000FF00 */ +#define I3C_TIMINGR0_SCLH_I3C I3C_TIMINGR0_SCLH_I3C_Msk /*!< SCL High duration during I3C Open-drain and Push-Pull phases */ +#define I3C_TIMINGR0_SCLL_OD_Pos (16U) +#define I3C_TIMINGR0_SCLL_OD_Msk (0xFFUL << I3C_TIMINGR0_SCLL_OD_Pos) /*!< 0x00FF0000 */ +#define I3C_TIMINGR0_SCLL_OD I3C_TIMINGR0_SCLL_OD_Msk /*!< SCL Low duration during I3C Open-drain phases and I2C transfer */ +#define I3C_TIMINGR0_SCLH_I2C_Pos (24U) +#define I3C_TIMINGR0_SCLH_I2C_Msk (0xFFUL << I3C_TIMINGR0_SCLH_I2C_Pos) /*!< 0xFF000000 */ +#define I3C_TIMINGR0_SCLH_I2C I3C_TIMINGR0_SCLH_I2C_Msk /*!< SCL High duration during I2C transfer */ + +/**************** Bit definition for I3C_TIMINGR1 register ******************/ +#define I3C_TIMINGR1_AVAL_Pos (0U) +#define I3C_TIMINGR1_AVAL_Msk (0xFFUL << I3C_TIMINGR1_AVAL_Pos) /*!< 0x000000FF */ +#define I3C_TIMINGR1_AVAL I3C_TIMINGR1_AVAL_Msk /*!< Timing for I3C Bus Idle or Available condition */ +#define I3C_TIMINGR1_ASNCR_Pos (8U) +#define I3C_TIMINGR1_ASNCR_Msk (0x3UL << I3C_TIMINGR1_ASNCR_Pos) /*!< 0x00000300 */ +#define I3C_TIMINGR1_ASNCR I3C_TIMINGR1_ASNCR_Msk /*!< Activity State of the New Controller */ +#define I3C_TIMINGR1_ASNCR_0 (0x1UL << I3C_TIMINGR1_ASNCR_Pos) /*!< 0x00000100 */ +#define I3C_TIMINGR1_ASNCR_1 (0x2UL << I3C_TIMINGR1_ASNCR_Pos) /*!< 0x00000200 */ +#define I3C_TIMINGR1_FREE_Pos (16U) +#define I3C_TIMINGR1_FREE_Msk (0x7FUL << I3C_TIMINGR1_FREE_Pos) /*!< 0x007F0000 */ +#define I3C_TIMINGR1_FREE I3C_TIMINGR1_FREE_Msk /*!< Timing for I3C Bus Free condition */ +#define I3C_TIMINGR1_SDA_HD_Pos (28U) +#define I3C_TIMINGR1_SDA_HD_Msk (0x1UL << I3C_TIMINGR1_SDA_HD_Pos) /*!< 0x00010000 */ +#define I3C_TIMINGR1_SDA_HD I3C_TIMINGR1_SDA_HD_Msk /*!< SDA Hold Duration */ + +/**************** Bit definition for I3C_TIMINGR2 register ******************/ +#define I3C_TIMINGR2_STALLT_Pos (0U) +#define I3C_TIMINGR2_STALLT_Msk (0x1UL << I3C_TIMINGR2_STALLT_Pos) /*!< 0x00000001 */ +#define I3C_TIMINGR2_STALLT I3C_TIMINGR2_STALLT_Msk /*!< Stall on T bit */ +#define I3C_TIMINGR2_STALLD_Pos (1U) +#define I3C_TIMINGR2_STALLD_Msk (0x1UL << I3C_TIMINGR2_STALLD_Pos) /*!< 0x00000002 */ +#define I3C_TIMINGR2_STALLD I3C_TIMINGR2_STALLD_Msk /*!< Stall on PAR bit of data bytes */ +#define I3C_TIMINGR2_STALLC_Pos (2U) +#define I3C_TIMINGR2_STALLC_Msk (0x1UL << I3C_TIMINGR2_STALLC_Pos) /*!< 0x00000004 */ +#define I3C_TIMINGR2_STALLC I3C_TIMINGR2_STALLC_Msk /*!< Stall on PAR bit of CCC byte */ +#define I3C_TIMINGR2_STALLA_Pos (3U) +#define I3C_TIMINGR2_STALLA_Msk (0x1UL << I3C_TIMINGR2_STALLA_Pos) /*!< 0x00000008 */ +#define I3C_TIMINGR2_STALLA I3C_TIMINGR2_STALLA_Msk /*!< Stall on ACK bit */ +#define I3C_TIMINGR2_STALL_Pos (8U) +#define I3C_TIMINGR2_STALL_Msk (0xFFUL << I3C_TIMINGR2_STALL_Pos) /*!< 0x0000FF00 */ +#define I3C_TIMINGR2_STALL I3C_TIMINGR2_STALL_Msk /*!< Controller Stall duration */ + +/******************* Bit definition for I3C_BCR register ********************/ +#define I3C_BCR_BCR_Pos (0U) +#define I3C_BCR_BCR_Msk (0xFFUL << I3C_BCR_BCR_Pos) /*!< 0x000000FF */ +#define I3C_BCR_BCR I3C_BCR_BCR_Msk /*!< Bus Characteristics */ +#define I3C_BCR_BCR0_Pos (0U) +#define I3C_BCR_BCR0_Msk (0x1UL << I3C_BCR_BCR0_Pos) /*!< 0x00000001 */ +#define I3C_BCR_BCR0 I3C_BCR_BCR0_Msk /*!< Max Data Speed Limitation */ +#define I3C_BCR_BCR1_Pos (1U) +#define I3C_BCR_BCR1_Msk (0x1UL << I3C_BCR_BCR1_Pos) /*!< 0x00000002 */ +#define I3C_BCR_BCR1 I3C_BCR_BCR1_Msk /*!< IBI Request capable */ +#define I3C_BCR_BCR2_Pos (2U) +#define I3C_BCR_BCR2_Msk (0x1UL << I3C_BCR_BCR2_Pos) /*!< 0x00000004 */ +#define I3C_BCR_BCR2 I3C_BCR_BCR2_Msk /*!< IBI Payload additional Mandatory Data Byte */ +#define I3C_BCR_BCR6_Pos (6U) +#define I3C_BCR_BCR6_Msk (0x1UL << I3C_BCR_BCR6_Pos) /*!< 0x00000040 */ +#define I3C_BCR_BCR6 I3C_BCR_BCR6_Msk /*!< Device Role shared during Dynamic Address Assignment */ + +/******************* Bit definition for I3C_DCR register ********************/ +#define I3C_DCR_DCR_Pos (0U) +#define I3C_DCR_DCR_Msk (0xFFUL << I3C_DCR_DCR_Pos) /*!< 0x000000FF */ +#define I3C_DCR_DCR I3C_DCR_DCR_Msk /*!< Devices Characteristics */ + +/***************** Bit definition for I3C_GETCAPR register ******************/ +#define I3C_GETCAPR_CAPPEND_Pos (14U) +#define I3C_GETCAPR_CAPPEND_Msk (0x1UL << I3C_GETCAPR_CAPPEND_Pos) /*!< 0x00004000 */ +#define I3C_GETCAPR_CAPPEND I3C_GETCAPR_CAPPEND_Msk /*!< IBI Request with Mandatory Data Byte */ + +/***************** Bit definition for I3C_CRCAPR register *******************/ +#define I3C_CRCAPR_CAPDHOFF_Pos (3U) +#define I3C_CRCAPR_CAPDHOFF_Msk (0x1UL << I3C_CRCAPR_CAPDHOFF_Pos) /*!< 0x00000008 */ +#define I3C_CRCAPR_CAPDHOFF I3C_CRCAPR_CAPDHOFF_Msk /*!< Controller-role handoff needed */ +#define I3C_CRCAPR_CAPGRP_Pos (9U) +#define I3C_CRCAPR_CAPGRP_Msk (0x1UL << I3C_CRCAPR_CAPGRP_Pos) /*!< 0x00000200 */ +#define I3C_CRCAPR_CAPGRP I3C_CRCAPR_CAPGRP_Msk /*!< Group Address handoff supported */ + +/**************** Bit definition for I3C_GETMXDSR register ******************/ +#define I3C_GETMXDSR_HOFFAS_Pos (0U) +#define I3C_GETMXDSR_HOFFAS_Msk (0x3UL << I3C_GETMXDSR_HOFFAS_Pos) /*!< 0x00000003 */ +#define I3C_GETMXDSR_HOFFAS I3C_GETMXDSR_HOFFAS_Msk /*!< Handoff Activity State */ +#define I3C_GETMXDSR_HOFFAS_0 (0x1UL << I3C_GETMXDSR_HOFFAS_Pos) /*!< 0x00000001 */ +#define I3C_GETMXDSR_HOFFAS_1 (0x2UL << I3C_GETMXDSR_HOFFAS_Pos) /*!< 0x00000002 */ +#define I3C_GETMXDSR_FMT_Pos (8U) +#define I3C_GETMXDSR_FMT_Msk (0x3UL << I3C_GETMXDSR_FMT_Pos) /*!< 0x00000300 */ +#define I3C_GETMXDSR_FMT I3C_GETMXDSR_FMT_Msk /*!< Get Max Data Speed response in format 2 */ +#define I3C_GETMXDSR_FMT_0 (0x1UL << I3C_GETMXDSR_FMT_Pos) /*!< 0x00000100 */ +#define I3C_GETMXDSR_FMT_1 (0x2UL << I3C_GETMXDSR_FMT_Pos) /*!< 0x00000200 */ +#define I3C_GETMXDSR_RDTURN_Pos (16U) +#define I3C_GETMXDSR_RDTURN_Msk (0xFFUL << I3C_GETMXDSR_RDTURN_Pos) /*!< 0x00FF0000 */ +#define I3C_GETMXDSR_RDTURN I3C_GETMXDSR_RDTURN_Msk /*!< Max Read Turnaround Middle Byte */ +#define I3C_GETMXDSR_TSCO_Pos (24U) +#define I3C_GETMXDSR_TSCO_Msk (0x1UL << I3C_GETMXDSR_TSCO_Pos) /*!< 0x01000000 */ +#define I3C_GETMXDSR_TSCO I3C_GETMXDSR_TSCO_Msk /*!< Clock-to-data Turnaround time */ + +/****************** Bit definition for I3C_EPIDR register *******************/ +#define I3C_EPIDR_MIPIID_Pos (12U) +#define I3C_EPIDR_MIPIID_Msk (0xFUL << I3C_EPIDR_MIPIID_Pos) /*!< 0x0000F000 */ +#define I3C_EPIDR_MIPIID I3C_EPIDR_MIPIID_Msk /*!< MIPI Instance ID */ +#define I3C_EPIDR_IDTSEL_Pos (16U) +#define I3C_EPIDR_IDTSEL_Msk (0x1UL << I3C_EPIDR_IDTSEL_Pos) /*!< 0x00010000 */ +#define I3C_EPIDR_IDTSEL I3C_EPIDR_IDTSEL_Msk /*!< ID Type Selector */ +#define I3C_EPIDR_MIPIMID_Pos (17U) +#define I3C_EPIDR_MIPIMID_Msk (0x7FFFUL << I3C_EPIDR_MIPIMID_Pos) /*!< 0xFFFE0000 */ +#define I3C_EPIDR_MIPIMID I3C_EPIDR_MIPIMID_Msk /*!< MIPI Manufacturer ID */ + +/******************************************************************************/ +/* */ +/* Independent WATCHDOG */ +/* */ +/******************************************************************************/ +/******************* Bit definition for IWDG_KR register ********************/ +#define IWDG_KR_KEY_Pos (0U) +#define IWDG_KR_KEY_Msk (0xFFFFUL << IWDG_KR_KEY_Pos) /*!< 0x0000FFFF */ +#define IWDG_KR_KEY IWDG_KR_KEY_Msk /*!= 6010050) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wc11-extensions" + #pragma clang diagnostic ignored "-Wreserved-id-macro" +#elif defined (__GNUC__) + /* anonymous unions are enabled by default */ +#elif defined (__TMS470__) + /* anonymous unions are enabled by default */ +#elif defined (__TASKING__) + #pragma warning 586 +#elif defined (__CSMC__) + /* anonymous unions are enabled by default */ +#else + #warning Not supported compiler type +#endif + +#define SMPS /*!< Switched mode power supply feature */ + +/* -------- Configuration of the Cortex-M33 Processor and Core Peripherals ------ */ +#define __CM33_REV 0x0000U /* Core revision r0p1 */ +#define __SAUREGION_PRESENT 1U /* SAU regions present */ +#define __MPU_PRESENT 1U /* MPU present */ +#define __VTOR_PRESENT 1U /* VTOR present */ +#define __NVIC_PRIO_BITS 4U /* Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0U /* Set to 1 if different SysTick Config is used */ +#define __FPU_PRESENT 1U /* FPU present */ +#define __DSP_PRESENT 1U /* DSP extension present */ + +/** @} */ /* End of group Configuration_of_CMSIS */ + + +#include /*!< ARM Cortex-M33 processor and core peripherals */ +#include "system_stm32h5xx.h" /*!< STM32H5xx System */ + + +/* =========================================================================================================================== */ +/* ================ Device Specific Peripheral Section ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup STM32H5xx_peripherals + * @{ + */ + +/** + * @brief CRC calculation unit + */ +typedef struct +{ + __IO uint32_t DR; /*!< CRC Data register, Address offset: 0x00 */ + __IO uint32_t IDR; /*!< CRC Independent data register, Address offset: 0x04 */ + __IO uint32_t CR; /*!< CRC Control register, Address offset: 0x08 */ + uint32_t RESERVED2; /*!< Reserved, 0x0C */ + __IO uint32_t INIT; /*!< Initial CRC value register, Address offset: 0x10 */ + __IO uint32_t POL; /*!< CRC polynomial register, Address offset: 0x14 */ + uint32_t RESERVED3[246]; /*!< Reserved, */ + __IO uint32_t HWCFGR; /*!< CRC IP HWCFGR register, Address offset: 0x3F0 */ + __IO uint32_t VERR; /*!< CRC IP version register, Address offset: 0x3F4 */ + __IO uint32_t PIDR; /*!< CRC IP type identification register, Address offset: 0x3F8 */ + __IO uint32_t SIDR; /*!< CRC IP map Size ID register, Address offset: 0x3FC */ +} CRC_TypeDef; + +/** + * @brief Inter-integrated Circuit Interface + */ +typedef struct +{ + __IO uint32_t CR1; /*!< I2C Control register 1, Address offset: 0x00 */ + __IO uint32_t CR2; /*!< I2C Control register 2, Address offset: 0x04 */ + __IO uint32_t OAR1; /*!< I2C Own address 1 register, Address offset: 0x08 */ + __IO uint32_t OAR2; /*!< I2C Own address 2 register, Address offset: 0x0C */ + __IO uint32_t TIMINGR; /*!< I2C Timing register, Address offset: 0x10 */ + __IO uint32_t TIMEOUTR; /*!< I2C Timeout register, Address offset: 0x14 */ + __IO uint32_t ISR; /*!< I2C Interrupt and status register, Address offset: 0x18 */ + __IO uint32_t ICR; /*!< I2C Interrupt clear register, Address offset: 0x1C */ + __IO uint32_t PECR; /*!< I2C PEC register, Address offset: 0x20 */ + __IO uint32_t RXDR; /*!< I2C Receive data register, Address offset: 0x24 */ + __IO uint32_t TXDR; /*!< I2C Transmit data register, Address offset: 0x28 */ +} I2C_TypeDef; + +/** + * @brief Improved Inter-integrated Circuit Interface + */ +typedef struct +{ + __IO uint32_t CR; /*!< I3C Control register, Address offset: 0x00 */ + __IO uint32_t CFGR; /*!< I3C Controller Configuration register, Address offset: 0x04 */ + uint32_t RESERVED1[2]; /*!< Reserved, Address offset: 0x08-0x0C */ + __IO uint32_t RDR; /*!< I3C Received Data register, Address offset: 0x10 */ + __IO uint32_t RDWR; /*!< I3C Received Data Word register, Address offset: 0x14 */ + __IO uint32_t TDR; /*!< I3C Transmit Data register, Address offset: 0x18 */ + __IO uint32_t TDWR; /*!< I3C Transmit Data Word register, Address offset: 0x1C */ + __IO uint32_t IBIDR; /*!< I3C IBI payload Data register, Address offset: 0x20 */ + __IO uint32_t TGTTDR; /*!< I3C Target Transmit register, Address offset: 0x24 */ + uint32_t RESERVED2[2]; /*!< Reserved, Address offset: 0x28-0x2C */ + __IO uint32_t SR; /*!< I3C Status register, Address offset: 0x30 */ + __IO uint32_t SER; /*!< I3C Status Error register, Address offset: 0x34 */ + uint32_t RESERVED3[2]; /*!< Reserved, Address offset: 0x38-0x3C */ + __IO uint32_t RMR; /*!< I3C Received Message register, Address offset: 0x40 */ + uint32_t RESERVED4[3]; /*!< Reserved, Address offset: 0x44-0x4C */ + __IO uint32_t EVR; /*!< I3C Event register, Address offset: 0x50 */ + __IO uint32_t IER; /*!< I3C Interrupt Enable register, Address offset: 0x54 */ + __IO uint32_t CEVR; /*!< I3C Clear Event register, Address offset: 0x58 */ + uint32_t RESERVED5; /*!< Reserved, Address offset: 0x5C */ + __IO uint32_t DEVR0; /*!< I3C own Target characteristics register, Address offset: 0x60 */ + __IO uint32_t DEVRX[4]; /*!< I3C Target x (1<=x<=4) register, Address offset: 0x64-0x70 */ + uint32_t RESERVED6[7]; /*!< Reserved, Address offset: 0x74-0x8C */ + __IO uint32_t MAXRLR; /*!< I3C Maximum Read Length register, Address offset: 0x90 */ + __IO uint32_t MAXWLR; /*!< I3C Maximum Write Length register, Address offset: 0x94 */ + uint32_t RESERVED7[2]; /*!< Reserved, Address offset: 0x98-0x9C */ + __IO uint32_t TIMINGR0; /*!< I3C Timing 0 register, Address offset: 0xA0 */ + __IO uint32_t TIMINGR1; /*!< I3C Timing 1 register, Address offset: 0xA4 */ + __IO uint32_t TIMINGR2; /*!< I3C Timing 2 register, Address offset: 0xA8 */ + uint32_t RESERVED9[5]; /*!< Reserved, Address offset: 0xAC-0xBC */ + __IO uint32_t BCR; /*!< I3C Bus Characteristics register, Address offset: 0xC0 */ + __IO uint32_t DCR; /*!< I3C Device Characteristics register, Address offset: 0xC4 */ + __IO uint32_t GETCAPR; /*!< I3C GET CAPabilities register, Address offset: 0xC8 */ + __IO uint32_t CRCAPR; /*!< I3C Controller CAPabilities register, Address offset: 0xCC */ + __IO uint32_t GETMXDSR; /*!< I3C GET Max Data Speed register, Address offset: 0xD0 */ + __IO uint32_t EPIDR; /*!< I3C Extended Provisioned ID register, Address offset: 0xD4 */ +} I3C_TypeDef; + +/** + * @brief DAC + */ +typedef struct +{ + __IO uint32_t CR; /*!< DAC control register, Address offset: 0x00 */ + __IO uint32_t SWTRIGR; /*!< DAC software trigger register, Address offset: 0x04 */ + __IO uint32_t DHR12R1; /*!< DAC channel1 12-bit right-aligned data holding register, Address offset: 0x08 */ + __IO uint32_t DHR12L1; /*!< DAC channel1 12-bit left aligned data holding register, Address offset: 0x0C */ + __IO uint32_t DHR8R1; /*!< DAC channel1 8-bit right aligned data holding register, Address offset: 0x10 */ + __IO uint32_t DHR12R2; /*!< DAC channel2 12-bit right aligned data holding register, Address offset: 0x14 */ + __IO uint32_t DHR12L2; /*!< DAC channel2 12-bit left aligned data holding register, Address offset: 0x18 */ + __IO uint32_t DHR8R2; /*!< DAC channel2 8-bit right-aligned data holding register, Address offset: 0x1C */ + __IO uint32_t DHR12RD; /*!< Dual DAC 12-bit right-aligned data holding register, Address offset: 0x20 */ + __IO uint32_t DHR12LD; /*!< DUAL DAC 12-bit left aligned data holding register, Address offset: 0x24 */ + __IO uint32_t DHR8RD; /*!< DUAL DAC 8-bit right aligned data holding register, Address offset: 0x28 */ + __IO uint32_t DOR1; /*!< DAC channel1 data output register, Address offset: 0x2C */ + __IO uint32_t DOR2; /*!< DAC channel2 data output register, Address offset: 0x30 */ + __IO uint32_t SR; /*!< DAC status register, Address offset: 0x34 */ + __IO uint32_t CCR; /*!< DAC calibration control register, Address offset: 0x38 */ + __IO uint32_t MCR; /*!< DAC mode control register, Address offset: 0x3C */ + __IO uint32_t SHSR1; /*!< DAC Sample and Hold sample time register 1, Address offset: 0x40 */ + __IO uint32_t SHSR2; /*!< DAC Sample and Hold sample time register 2, Address offset: 0x44 */ + __IO uint32_t SHHR; /*!< DAC Sample and Hold hold time register, Address offset: 0x48 */ + __IO uint32_t SHRR; /*!< DAC Sample and Hold refresh time register, Address offset: 0x4C */ + __IO uint32_t RESERVED[1]; + __IO uint32_t AUTOCR; /*!< DAC Autonomous mode register, Address offset: 0x54 */ +} DAC_TypeDef; + +/** + * @brief Clock Recovery System + */ +typedef struct +{ +__IO uint32_t CR; /*!< CRS ccontrol register, Address offset: 0x00 */ +__IO uint32_t CFGR; /*!< CRS configuration register, Address offset: 0x04 */ +__IO uint32_t ISR; /*!< CRS interrupt and status register, Address offset: 0x08 */ +__IO uint32_t ICR; /*!< CRS interrupt flag clear register, Address offset: 0x0C */ +} CRS_TypeDef; + + +/** + * @brief HASH + */ +typedef struct +{ + __IO uint32_t CR; /*!< HASH control register, Address offset: 0x00 */ + __IO uint32_t DIN; /*!< HASH data input register, Address offset: 0x04 */ + __IO uint32_t STR; /*!< HASH start register, Address offset: 0x08 */ + __IO uint32_t HR[5]; /*!< HASH digest registers, Address offset: 0x0C-0x1C */ + __IO uint32_t IMR; /*!< HASH interrupt enable register, Address offset: 0x20 */ + __IO uint32_t SR; /*!< HASH status register, Address offset: 0x24 */ + uint32_t RESERVED[52]; /*!< Reserved, 0x28-0xF4 */ + __IO uint32_t CSR[103]; /*!< HASH context swap registers, Address offset: 0x0F8-0x290 */ +} HASH_TypeDef; + +/** + * @brief HASH_DIGEST + */ +typedef struct +{ + __IO uint32_t HR[16]; /*!< HASH digest registers, Address offset: 0x310-0x34C */ +} HASH_DIGEST_TypeDef; + +/** + * @brief RNG + */ +typedef struct +{ + __IO uint32_t CR; /*!< RNG control register, Address offset: 0x00 */ + __IO uint32_t SR; /*!< RNG status register, Address offset: 0x04 */ + __IO uint32_t DR; /*!< RNG data register, Address offset: 0x08 */ + uint32_t RESERVED; + __IO uint32_t HTCR; /*!< RNG health test configuration register, Address offset: 0x10 */ +} RNG_TypeDef; + +/** + * @brief Debug MCU + */ +typedef struct +{ + __IO uint32_t IDCODE; /*!< MCU device ID code, Address offset: 0x00 */ + __IO uint32_t CR; /*!< Debug MCU configuration register, Address offset: 0x04 */ + __IO uint32_t APB1FZR1; /*!< Debug MCU APB1 freeze register 1, Address offset: 0x08 */ + __IO uint32_t APB1FZR2; /*!< Debug MCU APB1 freeze register 2, Address offset: 0x0C */ + __IO uint32_t APB2FZR; /*!< Debug MCU APB2 freeze register, Address offset: 0x10 */ + __IO uint32_t APB3FZR; /*!< Debug MCU APB3 freeze register, Address offset: 0x14 */ + uint32_t RESERVED1[2]; /*!< Reserved, 0x18 - 0x1C */ + __IO uint32_t AHB1FZR; /*!< Debug MCU AHB1 freeze register, Address offset: 0x20 */ + uint32_t RESERVED2[54]; /*!< Reserved, 0x24 - 0xF8 */ + __IO uint32_t SR; /*!< Debug MCU SR register, Address offset: 0xFC */ + __IO uint32_t DBG_AUTH_HOST; /*!< Debug DBG_AUTH_HOST register, Address offset: 0x100 */ + __IO uint32_t DBG_AUTH_DEV; /*!< Debug DBG_AUTH_DEV register, Address offset: 0x104 */ + __IO uint32_t DBG_AUTH_ACK; /*!< Debug DBG_AUTH_ACK register, Address offset: 0x108 */ + uint32_t RESERVED3[945]; /*!< Reserved, 0x10C - 0xFCC */ + __IO uint32_t PIDR4; /*!< Debug MCU Peripheral ID register 4, Address offset: 0xFD0 */ + __IO uint32_t PIDR5; /*!< Debug MCU Peripheral ID register 5, Address offset: 0xFD4 */ + __IO uint32_t PIDR6; /*!< Debug MCU Peripheral ID register 6, Address offset: 0xFD8 */ + __IO uint32_t PIDR7; /*!< Debug MCU Peripheral ID register 7, Address offset: 0xFDC */ + __IO uint32_t PIDR0; /*!< Debug MCU Peripheral ID register 0, Address offset: 0xFE0 */ + __IO uint32_t PIDR1; /*!< Debug MCU Peripheral ID register 1, Address offset: 0xFE4 */ + __IO uint32_t PIDR2; /*!< Debug MCU Peripheral ID register 2, Address offset: 0xFE8 */ + __IO uint32_t PIDR3; /*!< Debug MCU Peripheral ID register 3, Address offset: 0xFEC */ + __IO uint32_t CIDR0; /*!< Debug MCU Component ID register 0, Address offset: 0xFF0 */ + __IO uint32_t CIDR1; /*!< Debug MCU Component ID register 1, Address offset: 0xFF4 */ + __IO uint32_t CIDR2; /*!< Debug MCU Component ID register 2, Address offset: 0xFF8 */ + __IO uint32_t CIDR3; /*!< Debug MCU Component ID register 3, Address offset: 0xFFC */ +} DBGMCU_TypeDef; + +/** + * @brief DCMI + */ +typedef struct +{ + __IO uint32_t CR; /*!< DCMI control register 1, Address offset: 0x00 */ + __IO uint32_t SR; /*!< DCMI status register, Address offset: 0x04 */ + __IO uint32_t RISR; /*!< DCMI raw interrupt status register, Address offset: 0x08 */ + __IO uint32_t IER; /*!< DCMI interrupt enable register, Address offset: 0x0C */ + __IO uint32_t MISR; /*!< DCMI masked interrupt status register, Address offset: 0x10 */ + __IO uint32_t ICR; /*!< DCMI interrupt clear register, Address offset: 0x14 */ + __IO uint32_t ESCR; /*!< DCMI embedded synchronization code register, Address offset: 0x18 */ + __IO uint32_t ESUR; /*!< DCMI embedded synchronization unmask register, Address offset: 0x1C */ + __IO uint32_t CWSTRTR; /*!< DCMI crop window start, Address offset: 0x20 */ + __IO uint32_t CWSIZER; /*!< DCMI crop window size, Address offset: 0x24 */ + __IO uint32_t DR; /*!< DCMI data register, Address offset: 0x28 */ +} DCMI_TypeDef; + +/** + * @brief PSSI + */ +typedef struct +{ + __IO uint32_t CR; /*!< PSSI control register, Address offset: 0x000 */ + __IO uint32_t SR; /*!< PSSI status register, Address offset: 0x004 */ + __IO uint32_t RIS; /*!< PSSI raw interrupt status register, Address offset: 0x008 */ + __IO uint32_t IER; /*!< PSSI interrupt enable register, Address offset: 0x00C */ + __IO uint32_t MIS; /*!< PSSI masked interrupt status register, Address offset: 0x010 */ + __IO uint32_t ICR; /*!< PSSI interrupt clear register, Address offset: 0x014 */ + __IO uint32_t RESERVED1[4]; /*!< Reserved, 0x018 - 0x024 */ + __IO uint32_t DR; /*!< PSSI data register, Address offset: 0x028 */ +} PSSI_TypeDef; + +/** + * @brief DMA Controller + */ +typedef struct +{ + __IO uint32_t SECCFGR; /*!< DMA secure configuration register, Address offset: 0x00 */ + __IO uint32_t PRIVCFGR; /*!< DMA privileged configuration register, Address offset: 0x04 */ + __IO uint32_t RCFGLOCKR; /*!< DMA lock configuration register, Address offset: 0x08 */ + __IO uint32_t MISR; /*!< DMA non secure masked interrupt status register, Address offset: 0x0C */ + __IO uint32_t SMISR; /*!< DMA secure masked interrupt status register, Address offset: 0x10 */ +} DMA_TypeDef; + +typedef struct +{ + __IO uint32_t CLBAR; /*!< DMA channel x linked-list base address register, Address offset: 0x50 + (x * 0x80) */ + uint32_t RESERVED1[2]; /*!< Reserved 1, Address offset: 0x54 -- 0x58 */ + __IO uint32_t CFCR; /*!< DMA channel x flag clear register, Address offset: 0x5C + (x * 0x80) */ + __IO uint32_t CSR; /*!< DMA channel x flag status register, Address offset: 0x60 + (x * 0x80) */ + __IO uint32_t CCR; /*!< DMA channel x control register, Address offset: 0x64 + (x * 0x80) */ + uint32_t RESERVED2[10];/*!< Reserved 2, Address offset: 0x68 -- 0x8C */ + __IO uint32_t CTR1; /*!< DMA channel x transfer register 1, Address offset: 0x90 + (x * 0x80) */ + __IO uint32_t CTR2; /*!< DMA channel x transfer register 2, Address offset: 0x94 + (x * 0x80) */ + __IO uint32_t CBR1; /*!< DMA channel x block register 1, Address offset: 0x98 + (x * 0x80) */ + __IO uint32_t CSAR; /*!< DMA channel x source address register, Address offset: 0x9C + (x * 0x80) */ + __IO uint32_t CDAR; /*!< DMA channel x destination address register, Address offset: 0xA0 + (x * 0x80) */ + __IO uint32_t CTR3; /*!< DMA channel x transfer register 3, Address offset: 0xA4 + (x * 0x80) */ + __IO uint32_t CBR2; /*!< DMA channel x block register 2, Address offset: 0xA8 + (x * 0x80) */ + uint32_t RESERVED3[8]; /*!< Reserved 3, Address offset: 0xAC -- 0xC8 */ + __IO uint32_t CLLR; /*!< DMA channel x linked-list address register, Address offset: 0xCC + (x * 0x80) */ +} DMA_Channel_TypeDef; + + +/** + * @brief Asynch Interrupt/Event Controller (EXTI) + */ +typedef struct +{ + __IO uint32_t RTSR1; /*!< EXTI Rising Trigger Selection Register 1, Address offset: 0x00 */ + __IO uint32_t FTSR1; /*!< EXTI Falling Trigger Selection Register 1, Address offset: 0x04 */ + __IO uint32_t SWIER1; /*!< EXTI Software Interrupt event Register 1, Address offset: 0x08 */ + __IO uint32_t RPR1; /*!< EXTI Rising Pending Register 1, Address offset: 0x0C */ + __IO uint32_t FPR1; /*!< EXTI Falling Pending Register 1, Address offset: 0x10 */ + __IO uint32_t SECCFGR1; /*!< EXTI Security Configuration Register 1, Address offset: 0x14 */ + __IO uint32_t PRIVCFGR1; /*!< EXTI Privilege Configuration Register 1, Address offset: 0x18 */ + uint32_t RESERVED1; /*!< Reserved 1, Address offset: 0x1C */ + __IO uint32_t RTSR2; /*!< EXTI Rising Trigger Selection Register 2, Address offset: 0x20 */ + __IO uint32_t FTSR2; /*!< EXTI Falling Trigger Selection Register 2, Address offset: 0x24 */ + __IO uint32_t SWIER2; /*!< EXTI Software Interrupt event Register 2, Address offset: 0x28 */ + __IO uint32_t RPR2; /*!< EXTI Rising Pending Register 2, Address offset: 0x2C */ + __IO uint32_t FPR2; /*!< EXTI Falling Pending Register 2, Address offset: 0x30 */ + __IO uint32_t SECCFGR2; /*!< EXTI Security Configuration Register 2, Address offset: 0x34 */ + __IO uint32_t PRIVCFGR2; /*!< EXTI Privilege Configuration Register 2, Address offset: 0x38 */ + uint32_t RESERVED2[9]; /*!< Reserved 2, 0x3C-- 0x5C */ + __IO uint32_t EXTICR[4]; /*!< EXIT External Interrupt Configuration Register, 0x60 -- 0x6C */ + __IO uint32_t LOCKR; /*!< EXTI Lock Register, Address offset: 0x70 */ + uint32_t RESERVED3[3]; /*!< Reserved 3, 0x74 -- 0x7C */ + __IO uint32_t IMR1; /*!< EXTI Interrupt Mask Register 1, Address offset: 0x80 */ + __IO uint32_t EMR1; /*!< EXTI Event Mask Register 1, Address offset: 0x84 */ + uint32_t RESERVED4[2]; /*!< Reserved 4, 0x88 -- 0x8C */ + __IO uint32_t IMR2; /*!< EXTI Interrupt Mask Register 2, Address offset: 0x90 */ + __IO uint32_t EMR2; /*!< EXTI Event Mask Register 2, Address offset: 0x94 */ +} EXTI_TypeDef; + +/** + * @brief FLASH Registers + */ +typedef struct +{ + __IO uint32_t ACR; /*!< FLASH access control register, Address offset: 0x00 */ + __IO uint32_t NSKEYR; /*!< FLASH non-secure key register, Address offset: 0x04 */ + __IO uint32_t SECKEYR; /*!< FLASH secure key register, Address offset: 0x08 */ + __IO uint32_t OPTKEYR; /*!< FLASH option key register, Address offset: 0x0C */ + __IO uint32_t NSOBKKEYR; /*!< FLASH non-secure option bytes keys key register, Address offset: 0x10 */ + __IO uint32_t SECOBKKEYR; /*!< FLASH secure option bytes keys key register, Address offset: 0x14 */ + __IO uint32_t OPSR; /*!< FLASH OPSR register, Address offset: 0x18 */ + __IO uint32_t OPTCR; /*!< Flash Option Control Register, Address offset: 0x1C */ + __IO uint32_t NSSR; /*!< FLASH non-secure status register, Address offset: 0x20 */ + __IO uint32_t SECSR; /*!< FLASH secure status register, Address offset: 0x24 */ + __IO uint32_t NSCR; /*!< FLASH non-secure control register, Address offset: 0x28 */ + __IO uint32_t SECCR; /*!< FLASH secure control register, Address offset: 0x2C */ + __IO uint32_t NSCCR; /*!< FLASH non-secure clear control register, Address offset: 0x30 */ + __IO uint32_t SECCCR; /*!< FLASH secure clear control register, Address offset: 0x34 */ + uint32_t RESERVED1; /*!< Reserved1, Address offset: 0x38 */ + __IO uint32_t PRIVCFGR; /*!< FLASH privilege configuration register, Address offset: 0x3C */ + __IO uint32_t NSOBKCFGR; /*!< FLASH non-secure option byte key configuration register, Address offset: 0x40 */ + __IO uint32_t SECOBKCFGR; /*!< FLASH secure option byte key configuration register, Address offset: 0x44 */ + __IO uint32_t HDPEXTR; /*!< FLASH HDP extension register, Address offset: 0x48 */ + uint32_t RESERVED2; /*!< Reserved2, Address offset: 0x4C */ + __IO uint32_t OPTSR_CUR; /*!< FLASH option status current register, Address offset: 0x50 */ + __IO uint32_t OPTSR_PRG; /*!< FLASH option status to program register, Address offset: 0x54 */ + uint32_t RESERVED3[2]; /*!< Reserved3, Address offset: 0x58-0x5C */ + __IO uint32_t NSEPOCHR_CUR; /*!< FLASH non-secure epoch current register, Address offset: 0x60 */ + __IO uint32_t NSEPOCHR_PRG; /*!< FLASH non-secure epoch to program register, Address offset: 0x64 */ + __IO uint32_t SECEPOCHR_CUR; /*!< FLASH secure epoch current register, Address offset: 0x68 */ + __IO uint32_t SECEPOCHR_PRG; /*!< FLASH secure epoch to program register, Address offset: 0x6C */ + __IO uint32_t OPTSR2_CUR; /*!< FLASH option status current register 2, Address offset: 0x70 */ + __IO uint32_t OPTSR2_PRG; /*!< FLASH option status to program register 2, Address offset: 0x74 */ + uint32_t RESERVED4[2]; /*!< Reserved4, Address offset: 0x78-0x7C */ + __IO uint32_t NSBOOTR_CUR; /*!< FLASH non-secure unique boot entry current register, Address offset: 0x80 */ + __IO uint32_t NSBOOTR_PRG; /*!< FLASH non-secure unique boot entry to program register, Address offset: 0x84 */ + __IO uint32_t SECBOOTR_CUR; /*!< FLASH secure unique boot entry current register, Address offset: 0x88 */ + __IO uint32_t SECBOOTR_PRG; /*!< FLASH secure unique boot entry to program register, Address offset: 0x8C */ + __IO uint32_t OTPBLR_CUR; /*!< FLASH OTP block lock current register, Address offset: 0x90 */ + __IO uint32_t OTPBLR_PRG; /*!< FLASH OTP block Lock to program register, Address offset: 0x94 */ + uint32_t RESERVED5[2]; /*!< Reserved5, Address offset: 0x98-0x9C */ + __IO uint32_t SECBB1R1; /*!< FLASH secure block-based bank 1 register 1, Address offset: 0xA0 */ + __IO uint32_t SECBB1R2; /*!< FLASH secure block-based bank 1 register 2, Address offset: 0xA4 */ + __IO uint32_t SECBB1R3; /*!< FLASH secure block-based bank 1 register 3, Address offset: 0xA8 */ + __IO uint32_t SECBB1R4; /*!< FLASH secure block-based bank 1 register 4, Address offset: 0xAC */ + uint32_t RESERVED6[4]; /*!< Reserved6, Address offset: 0xB0-0xBC */ + __IO uint32_t PRIVBB1R1; /*!< FLASH privilege block-based bank 1 register 1, Address offset: 0xC0 */ + __IO uint32_t PRIVBB1R2; /*!< FLASH privilege block-based bank 1 register 2, Address offset: 0xC4 */ + __IO uint32_t PRIVBB1R3; /*!< FLASH privilege block-based bank 1 register 3, Address offset: 0xC8 */ + __IO uint32_t PRIVBB1R4; /*!< FLASH privilege block-based bank 1 register 4, Address offset: 0xCC */ + uint32_t RESERVED7[4]; /*!< Reserved7, Address offset: 0xD0-0xDC */ + __IO uint32_t SECWM1R_CUR; /*!< FLASH secure watermark 1 current register, Address offset: 0xE0 */ + __IO uint32_t SECWM1R_PRG; /*!< FLASH secure watermark 1 to program register, Address offset: 0xE4 */ + __IO uint32_t WRP1R_CUR; /*!< FLASH write sector group protection current register for bank1, Address offset: 0xE8 */ + __IO uint32_t WRP1R_PRG; /*!< FLASH write sector group protection to program register for bank1, Address offset: 0xEC */ + __IO uint32_t EDATA1R_CUR; /*!< FLASH data sectors configuration current register for bank1, Address offset: 0xF0 */ + __IO uint32_t EDATA1R_PRG; /*!< FLASH data sectors configuration to program register for bank1, Address offset: 0xF4 */ + __IO uint32_t HDP1R_CUR; /*!< FLASH HDP configuration current register for bank1, Address offset: 0xF8 */ + __IO uint32_t HDP1R_PRG; /*!< FLASH HDP configuration to program register for bank1, Address offset: 0xFC */ + __IO uint32_t ECCCORR; /*!< FLASH ECC correction register, Address offset: 0x100 */ + __IO uint32_t ECCDETR; /*!< FLASH ECC detection register, Address offset: 0x104 */ + __IO uint32_t ECCDR; /*!< FLASH ECC data register, Address offset: 0x108 */ + uint32_t RESERVED8[37]; /*!< Reserved8, Address offset: 0x10C-0x19C */ + __IO uint32_t SECBB2R1; /*!< FLASH secure block-based bank 2 register 1, Address offset: 0x1A0 */ + __IO uint32_t SECBB2R2; /*!< FLASH secure block-based bank 2 register 2, Address offset: 0x1A4 */ + __IO uint32_t SECBB2R3; /*!< FLASH secure block-based bank 2 register 3, Address offset: 0x1A8 */ + __IO uint32_t SECBB2R4; /*!< FLASH secure block-based bank 2 register 4, Address offset: 0x1AC */ + uint32_t RESERVED9[4]; /*!< Reserved9, Address offset: 0x1B0-0x1BC */ + __IO uint32_t PRIVBB2R1; /*!< FLASH privilege block-based bank 2 register 1, Address offset: 0x1C0 */ + __IO uint32_t PRIVBB2R2; /*!< FLASH privilege block-based bank 2 register 2, Address offset: 0x1C4 */ + __IO uint32_t PRIVBB2R3; /*!< FLASH privilege block-based bank 2 register 3, Address offset: 0x1C8 */ + __IO uint32_t PRIVBB2R4; /*!< FLASH privilege block-based bank 2 register 4, Address offset: 0x1CC */ + uint32_t RESERVED10[4]; /*!< Reserved10, Address offset: 0x1D0-0x1DC */ + __IO uint32_t SECWM2R_CUR; /*!< FLASH secure watermark 2 current register, Address offset: 0x1E0 */ + __IO uint32_t SECWM2R_PRG; /*!< FLASH secure watermark 2 to program register, Address offset: 0x1E4 */ + __IO uint32_t WRP2R_CUR; /*!< FLASH write sector group protection current register for bank2, Address offset: 0x1E8 */ + __IO uint32_t WRP2R_PRG; /*!< FLASH write sector group protection to program register for bank2, Address offset: 0x1EC */ + __IO uint32_t EDATA2R_CUR; /*!< FLASH data sectors configuration current register for bank2, Address offset: 0x1F0 */ + __IO uint32_t EDATA2R_PRG; /*!< FLASH data sectors configuration to program register for bank2, Address offset: 0x1F4 */ + __IO uint32_t HDP2R_CUR; /*!< FLASH HDP configuration current register for bank2, Address offset: 0x1F8 */ + __IO uint32_t HDP2R_PRG; /*!< FLASH HDP configuration to program register for bank2, Address offset: 0x1FC */ +} FLASH_TypeDef; + +/** + * @brief FMAC + */ +typedef struct +{ + __IO uint32_t X1BUFCFG; /*!< FMAC X1 Buffer Configuration register, Address offset: 0x00 */ + __IO uint32_t X2BUFCFG; /*!< FMAC X2 Buffer Configuration register, Address offset: 0x04 */ + __IO uint32_t YBUFCFG; /*!< FMAC Y Buffer Configuration register, Address offset: 0x08 */ + __IO uint32_t PARAM; /*!< FMAC Parameter register, Address offset: 0x0C */ + __IO uint32_t CR; /*!< FMAC Control register, Address offset: 0x10 */ + __IO uint32_t SR; /*!< FMAC Status register, Address offset: 0x14 */ + __IO uint32_t WDATA; /*!< FMAC Write Data register, Address offset: 0x18 */ + __IO uint32_t RDATA; /*!< FMAC Read Data register, Address offset: 0x1C */ +} FMAC_TypeDef; +/** + * @brief General Purpose I/O + */ +typedef struct +{ + __IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */ + __IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */ + __IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */ + __IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ + __IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */ + __IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */ + __IO uint32_t BSRR; /*!< GPIO port bit set/reset register, Address offset: 0x18 */ + __IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */ + __IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */ + __IO uint32_t BRR; /*!< GPIO Bit Reset register, Address offset: 0x28 */ + __IO uint32_t HSLVR; /*!< GPIO high-speed low voltage register, Address offset: 0x2C */ + __IO uint32_t SECCFGR; /*!< GPIO secure configuration register, Address offset: 0x30 */ +} GPIO_TypeDef; + +/** + * @brief Global TrustZone Controller + */ +typedef struct +{ + __IO uint32_t CR; /*!< TZSC control register, Address offset: 0x00 */ + uint32_t RESERVED1[3]; /*!< Reserved1, Address offset: 0x04-0x0C */ + __IO uint32_t SECCFGR1; /*!< TZSC secure configuration register 1, Address offset: 0x10 */ + __IO uint32_t SECCFGR2; /*!< TZSC secure configuration register 2, Address offset: 0x14 */ + __IO uint32_t SECCFGR3; /*!< TZSC secure configuration register 3, Address offset: 0x18 */ + uint32_t RESERVED2; /*!< Reserved2, Address offset: 0x1C */ + __IO uint32_t PRIVCFGR1; /*!< TZSC privilege configuration register 1, Address offset: 0x20 */ + __IO uint32_t PRIVCFGR2; /*!< TZSC privilege configuration register 2, Address offset: 0x24 */ + __IO uint32_t PRIVCFGR3; /*!< TZSC privilege configuration register 3, Address offset: 0x28 */ + uint32_t RESERVED3[5]; /*!< Reserved3, Address offset: 0x2C-0x3C */ + __IO uint32_t MPCWM1ACFGR; /*!< TZSC memory 1 sub-region A watermark configuration register, Address offset: 0x40 */ + __IO uint32_t MPCWM1AR; /*!< TZSC memory 1 sub-region A watermark register, Address offset: 0x44 */ + __IO uint32_t MPCWM1BCFGR; /*!< TZSC memory 1 sub-region B watermark configuration register, Address offset: 0x48 */ + __IO uint32_t MPCWM1BR; /*!< TZSC memory 1 sub-region B watermark register, Address offset: 0x4C */ + __IO uint32_t MPCWM2ACFGR; /*!< TZSC memory 2 sub-region A watermark configuration register, Address offset: 0x50 */ + __IO uint32_t MPCWM2AR; /*!< TZSC memory 2 sub-region A watermark register, Address offset: 0x54 */ + __IO uint32_t MPCWM2BCFGR; /*!< TZSC memory 2 sub-region B watermark configuration register, Address offset: 0x58 */ + __IO uint32_t MPCWM2BR; /*!< TZSC memory 2 sub-region B watermark register, Address offset: 0x5C */ + __IO uint32_t MPCWM3ACFGR; /*!< TZSC memory 3 sub-region A watermark configuration register, Address offset: 0x60 */ + __IO uint32_t MPCWM3AR; /*!< TZSC memory 3 sub-region A watermark register, Address offset: 0x64 */ + __IO uint32_t MPCWM3BCFGR; /*!< TZSC memory 3 sub-region B watermark configuration register, Address offset: 0x68 */ + __IO uint32_t MPCWM3BR; /*!< TZSC memory 3 sub-region B watermark register, Address offset: 0x6C */ + __IO uint32_t MPCWM4ACFGR; /*!< TZSC memory 4 sub-region A watermark configuration register, Address offset: 0x70 */ + __IO uint32_t MPCWM4AR; /*!< TZSC memory 4 sub-region A watermark register, Address offset: 0x74 */ + __IO uint32_t MPCWM4BCFGR; /*!< TZSC memory 4 sub-region B watermark configuration register, Address offset: 0x78 */ + __IO uint32_t MPCWM4BR; /*!< TZSC memory 4 sub-region B watermark register, Address offset: 0x7c */ +} GTZC_TZSC_TypeDef; + +typedef struct +{ + __IO uint32_t CR; /*!< MPCBBx control register, Address offset: 0x00 */ + uint32_t RESERVED1[3]; /*!< Reserved1, Address offset: 0x04-0x0C */ + __IO uint32_t CFGLOCKR1; /*!< MPCBBx lock register, Address offset: 0x10 */ + uint32_t RESERVED2[59]; /*!< Reserved2, Address offset: 0x14-0xFC */ + __IO uint32_t SECCFGR[32]; /*!< MPCBBx security configuration registers, Address offset: 0x100-0x17C */ + uint32_t RESERVED3[32]; /*!< Reserved3, Address offset: 0x180-0x1FC */ + __IO uint32_t PRIVCFGR[32]; /*!< MPCBBx privilege configuration registers, Address offset: 0x200-0x280 */ +} GTZC_MPCBB_TypeDef; + +typedef struct +{ + __IO uint32_t IER1; /*!< TZIC interrupt enable register 1, Address offset: 0x00 */ + __IO uint32_t IER2; /*!< TZIC interrupt enable register 2, Address offset: 0x04 */ + __IO uint32_t IER3; /*!< TZIC interrupt enable register 3, Address offset: 0x08 */ + __IO uint32_t IER4; /*!< TZIC interrupt enable register 4, Address offset: 0x0C */ + __IO uint32_t SR1; /*!< TZIC status register 1, Address offset: 0x10 */ + __IO uint32_t SR2; /*!< TZIC status register 2, Address offset: 0x14 */ + __IO uint32_t SR3; /*!< TZIC status register 3, Address offset: 0x18 */ + __IO uint32_t SR4; /*!< TZIC status register 4, Address offset: 0x1C */ + __IO uint32_t FCR1; /*!< TZIC flag clear register 1, Address offset: 0x20 */ + __IO uint32_t FCR2; /*!< TZIC flag clear register 2, Address offset: 0x24 */ + __IO uint32_t FCR3; /*!< TZIC flag clear register 3, Address offset: 0x28 */ + __IO uint32_t FCR4; /*!< TZIC flag clear register 3, Address offset: 0x2C */ +} GTZC_TZIC_TypeDef; + +/** + * @brief Instruction Cache + */ +typedef struct +{ + __IO uint32_t CR; /*!< ICACHE control register, Address offset: 0x00 */ + __IO uint32_t SR; /*!< ICACHE status register, Address offset: 0x04 */ + __IO uint32_t IER; /*!< ICACHE interrupt enable register, Address offset: 0x08 */ + __IO uint32_t FCR; /*!< ICACHE Flag clear register, Address offset: 0x0C */ + __IO uint32_t HMONR; /*!< ICACHE hit monitor register, Address offset: 0x10 */ + __IO uint32_t MMONR; /*!< ICACHE miss monitor register, Address offset: 0x14 */ + uint32_t RESERVED1[2]; /*!< Reserved, Address offset: 0x018-0x01C */ + __IO uint32_t CRR0; /*!< ICACHE region 0 configuration register, Address offset: 0x20 */ + __IO uint32_t CRR1; /*!< ICACHE region 1 configuration register, Address offset: 0x24 */ + __IO uint32_t CRR2; /*!< ICACHE region 2 configuration register, Address offset: 0x28 */ + __IO uint32_t CRR3; /*!< ICACHE region 3 configuration register, Address offset: 0x2C */ +} ICACHE_TypeDef; + +/** + * @brief Data Cache + */ +typedef struct +{ + __IO uint32_t CR; /*!< DCACHE control register, Address offset: 0x00 */ + __IO uint32_t SR; /*!< DCACHE status register, Address offset: 0x04 */ + __IO uint32_t IER; /*!< DCACHE interrupt enable register, Address offset: 0x08 */ + __IO uint32_t FCR; /*!< DCACHE Flag clear register, Address offset: 0x0C */ + __IO uint32_t RHMONR; /*!< DCACHE Read hit monitor register, Address offset: 0x10 */ + __IO uint32_t RMMONR; /*!< DCACHE Read miss monitor register, Address offset: 0x14 */ + uint32_t RESERVED1[2]; /*!< Reserved, Address offset: 0x18-0x1C */ + __IO uint32_t WHMONR; /*!< DCACHE Write hit monitor register, Address offset: 0x20 */ + __IO uint32_t WMMONR; /*!< DCACHE Write miss monitor register, Address offset: 0x24 */ + __IO uint32_t CMDRSADDRR; /*!< DCACHE Command Start Address register, Address offset: 0x28 */ + __IO uint32_t CMDREADDRR; /*!< DCACHE Command End Address register, Address offset: 0x2C */ +} DCACHE_TypeDef; + +/** + * @brief TIM + */ +typedef struct +{ + __IO uint32_t CR1; /*!< TIM control register 1, Address offset: 0x00 */ + __IO uint32_t CR2; /*!< TIM control register 2, Address offset: 0x04 */ + __IO uint32_t SMCR; /*!< TIM slave mode control register, Address offset: 0x08 */ + __IO uint32_t DIER; /*!< TIM DMA/interrupt enable register, Address offset: 0x0C */ + __IO uint32_t SR; /*!< TIM status register, Address offset: 0x10 */ + __IO uint32_t EGR; /*!< TIM event generation register, Address offset: 0x14 */ + __IO uint32_t CCMR1; /*!< TIM capture/compare mode register 1, Address offset: 0x18 */ + __IO uint32_t CCMR2; /*!< TIM capture/compare mode register 2, Address offset: 0x1C */ + __IO uint32_t CCER; /*!< TIM capture/compare enable register, Address offset: 0x20 */ + __IO uint32_t CNT; /*!< TIM counter register, Address offset: 0x24 */ + __IO uint32_t PSC; /*!< TIM prescaler, Address offset: 0x28 */ + __IO uint32_t ARR; /*!< TIM auto-reload register, Address offset: 0x2C */ + __IO uint32_t RCR; /*!< TIM repetition counter register, Address offset: 0x30 */ + __IO uint32_t CCR1; /*!< TIM capture/compare register 1, Address offset: 0x34 */ + __IO uint32_t CCR2; /*!< TIM capture/compare register 2, Address offset: 0x38 */ + __IO uint32_t CCR3; /*!< TIM capture/compare register 3, Address offset: 0x3C */ + __IO uint32_t CCR4; /*!< TIM capture/compare register 4, Address offset: 0x40 */ + __IO uint32_t BDTR; /*!< TIM break and dead-time register, Address offset: 0x44 */ + __IO uint32_t CCR5; /*!< TIM capture/compare register 5, Address offset: 0x48 */ + __IO uint32_t CCR6; /*!< TIM capture/compare register 6, Address offset: 0x4C */ + __IO uint32_t CCMR3; /*!< TIM capture/compare mode register 3, Address offset: 0x50 */ + __IO uint32_t DTR2; /*!< TIM deadtime register 2, Address offset: 0x54 */ + __IO uint32_t ECR; /*!< TIM encoder control register, Address offset: 0x58 */ + __IO uint32_t TISEL; /*!< TIM Input Selection register, Address offset: 0x5C */ + __IO uint32_t AF1; /*!< TIM alternate function option register 1, Address offset: 0x60 */ + __IO uint32_t AF2; /*!< TIM alternate function option register 2, Address offset: 0x64 */ + uint32_t RESERVED0[221];/*!< Reserved, Address offset: 0x68 */ + __IO uint32_t DCR; /*!< TIM DMA control register, Address offset: 0x3DC */ + __IO uint32_t DMAR; /*!< TIM DMA address for full transfer, Address offset: 0x3E0 */ +} TIM_TypeDef; + +/** + * @brief LPTIMER + */ +typedef struct +{ + __IO uint32_t ISR; /*!< LPTIM Interrupt and Status register, Address offset: 0x00 */ + __IO uint32_t ICR; /*!< LPTIM Interrupt Clear register, Address offset: 0x04 */ + __IO uint32_t DIER; /*!< LPTIM Interrupt Enable register, Address offset: 0x08 */ + __IO uint32_t CFGR; /*!< LPTIM Configuration register, Address offset: 0x0C */ + __IO uint32_t CR; /*!< LPTIM Control register, Address offset: 0x10 */ + __IO uint32_t CCR1; /*!< LPTIM Capture/Compare register 1, Address offset: 0x14 */ + __IO uint32_t ARR; /*!< LPTIM Autoreload register, Address offset: 0x18 */ + __IO uint32_t CNT; /*!< LPTIM Counter register, Address offset: 0x1C */ + __IO uint32_t RESERVED0; /*!< Reserved, Address offset: 0x20 */ + __IO uint32_t CFGR2; /*!< LPTIM Configuration register 2, Address offset: 0x24 */ + __IO uint32_t RCR; /*!< LPTIM Repetition register, Address offset: 0x28 */ + __IO uint32_t CCMR1; /*!< LPTIM Capture/Compare mode register, Address offset: 0x2C */ + __IO uint32_t RESERVED1; /*!< Reserved, Address offset: 0x30 */ + __IO uint32_t CCR2; /*!< LPTIM Capture/Compare register 2, Address offset: 0x34 */ +} LPTIM_TypeDef; + +/** + * @brief OCTO Serial Peripheral Interface + */ + +typedef struct +{ + __IO uint32_t CR; /*!< OCTOSPI Control register, Address offset: 0x000 */ + uint32_t RESERVED; /*!< Reserved, Address offset: 0x004 */ + __IO uint32_t DCR1; /*!< OCTOSPI Device Configuration register 1, Address offset: 0x008 */ + __IO uint32_t DCR2; /*!< OCTOSPI Device Configuration register 2, Address offset: 0x00C */ + __IO uint32_t DCR3; /*!< OCTOSPI Device Configuration register 3, Address offset: 0x010 */ + __IO uint32_t DCR4; /*!< OCTOSPI Device Configuration register 4, Address offset: 0x014 */ + uint32_t RESERVED1[2]; /*!< Reserved, Address offset: 0x018-0x01C */ + __IO uint32_t SR; /*!< OCTOSPI Status register, Address offset: 0x020 */ + __IO uint32_t FCR; /*!< OCTOSPI Flag Clear register, Address offset: 0x024 */ + uint32_t RESERVED2[6]; /*!< Reserved, Address offset: 0x028-0x03C */ + __IO uint32_t DLR; /*!< OCTOSPI Data Length register, Address offset: 0x040 */ + uint32_t RESERVED3; /*!< Reserved, Address offset: 0x044 */ + __IO uint32_t AR; /*!< OCTOSPI Address register, Address offset: 0x048 */ + uint32_t RESERVED4; /*!< Reserved, Address offset: 0x04C */ + __IO uint32_t DR; /*!< OCTOSPI Data register, Address offset: 0x050 */ + uint32_t RESERVED5[11]; /*!< Reserved, Address offset: 0x054-0x07C */ + __IO uint32_t PSMKR; /*!< OCTOSPI Polling Status Mask register, Address offset: 0x080 */ + uint32_t RESERVED6; /*!< Reserved, Address offset: 0x084 */ + __IO uint32_t PSMAR; /*!< OCTOSPI Polling Status Match register, Address offset: 0x088 */ + uint32_t RESERVED7; /*!< Reserved, Address offset: 0x08C */ + __IO uint32_t PIR; /*!< OCTOSPI Polling Interval register, Address offset: 0x090 */ + uint32_t RESERVED8[27]; /*!< Reserved, Address offset: 0x094-0x0FC */ + __IO uint32_t CCR; /*!< OCTOSPI Communication Configuration register, Address offset: 0x100 */ + uint32_t RESERVED9; /*!< Reserved, Address offset: 0x104 */ + __IO uint32_t TCR; /*!< OCTOSPI Timing Configuration register, Address offset: 0x108 */ + uint32_t RESERVED10; /*!< Reserved, Address offset: 0x10C */ + __IO uint32_t IR; /*!< OCTOSPI Instruction register, Address offset: 0x110 */ + uint32_t RESERVED11[3]; /*!< Reserved, Address offset: 0x114-0x11C */ + __IO uint32_t ABR; /*!< OCTOSPI Alternate Bytes register, Address offset: 0x120 */ + uint32_t RESERVED12[3]; /*!< Reserved, Address offset: 0x124-0x12C */ + __IO uint32_t LPTR; /*!< OCTOSPI Low Power Timeout register, Address offset: 0x130 */ + uint32_t RESERVED13[3]; /*!< Reserved, Address offset: 0x134-0x13C */ + __IO uint32_t WPCCR; /*!< OCTOSPI Wrap Communication Configuration register, Address offset: 0x140 */ + uint32_t RESERVED14; /*!< Reserved, Address offset: 0x144 */ + __IO uint32_t WPTCR; /*!< OCTOSPI Wrap Timing Configuration register, Address offset: 0x148 */ + uint32_t RESERVED15; /*!< Reserved, Address offset: 0x14C */ + __IO uint32_t WPIR; /*!< OCTOSPI Wrap Instruction register, Address offset: 0x150 */ + uint32_t RESERVED16[3]; /*!< Reserved, Address offset: 0x154-0x15C */ + __IO uint32_t WPABR; /*!< OCTOSPI Wrap Alternate Bytes register, Address offset: 0x160 */ + uint32_t RESERVED17[7]; /*!< Reserved, Address offset: 0x164-0x17C */ + __IO uint32_t WCCR; /*!< OCTOSPI Write Communication Configuration register, Address offset: 0x180 */ + uint32_t RESERVED18; /*!< Reserved, Address offset: 0x184 */ + __IO uint32_t WTCR; /*!< OCTOSPI Write Timing Configuration register, Address offset: 0x188 */ + uint32_t RESERVED19; /*!< Reserved, Address offset: 0x18C */ + __IO uint32_t WIR; /*!< OCTOSPI Write Instruction register, Address offset: 0x190 */ + uint32_t RESERVED20[3]; /*!< Reserved, Address offset: 0x194-0x19C */ + __IO uint32_t WABR; /*!< OCTOSPI Write Alternate Bytes register, Address offset: 0x1A0 */ + uint32_t RESERVED21[23]; /*!< Reserved, Address offset: 0x1A4-0x1FC */ + __IO uint32_t HLCR; /*!< OCTOSPI Hyperbus Latency Configuration register, Address offset: 0x200 */ +} XSPI_TypeDef; + +typedef XSPI_TypeDef OCTOSPI_TypeDef; + +/** + * @brief Power Control + */ +typedef struct +{ + __IO uint32_t PMCR; /*!< Power mode control register , Address offset: 0x00 */ + __IO uint32_t PMSR; /*!< Power mode status register , Address offset: 0x04 */ + uint32_t RESERVED1[2]; /*!< Reserved, Address offset: 0x08-0x0C */ + __IO uint32_t VOSCR; /*!< Voltage scaling control register , Address offset: 0x10 */ + __IO uint32_t VOSSR; /*!< Voltage sacling status register , Address offset: 0x14 */ + uint32_t RESERVED2[2]; /*!< Reserved, Address offset: 0x18-0x1C */ + __IO uint32_t BDCR; /*!< BacKup domain control register , Address offset: 0x20 */ + __IO uint32_t DBPCR; /*!< DBP control register, Address offset: 0x24 */ + __IO uint32_t BDSR; /*!< BacKup domain status register, Address offset: 0x28 */ + __IO uint32_t UCPDR; /*!< Usb typeC and Power Delivery Register, Address offset: 0x2C */ + __IO uint32_t SCCR; /*!< Supply configuration control register, Address offset: 0x30 */ + __IO uint32_t VMCR; /*!< Voltage Monitor Control Register, Address offset: 0x34 */ + __IO uint32_t USBSCR; /*!< USB Supply Control Register Address offset: 0x38 */ + __IO uint32_t VMSR; /*!< Status Register Voltage Monitoring, Address offset: 0x3C */ + __IO uint32_t WUSCR; /*!< WakeUP status clear register, Address offset: 0x40 */ + __IO uint32_t WUSR; /*!< WakeUP status Register, Address offset: 0x44 */ + __IO uint32_t WUCR; /*!< WakeUP configuration register, Address offset: 0x48 */ + uint32_t RESERVED3; /*!< Reserved, Address offset: 0x4C */ + __IO uint32_t IORETR; /*!< IO RETention Register, Address offset: 0x50 */ + uint32_t RESERVED4[43];/*!< Reserved, Address offset: 0x54-0xFC */ + __IO uint32_t SECCFGR; /*!< Security configuration register, Address offset: 0x100 */ + __IO uint32_t PRIVCFGR; /*!< Privilege configuration register, Address offset: 0x104 */ +}PWR_TypeDef; + +/** + * @brief SRAMs configuration controller + */ +typedef struct +{ + __IO uint32_t CR; /*!< Control Register, Address offset: 0x00 */ + __IO uint32_t IER; /*!< Interrupt Enable Register, Address offset: 0x04 */ + __IO uint32_t ISR; /*!< Interrupt Status Register, Address offset: 0x08 */ + __IO uint32_t SEAR; /*!< ECC Single Error Address Register, Address offset: 0x0C */ + __IO uint32_t DEAR; /*!< ECC Double Error Address Register, Address offset: 0x10 */ + __IO uint32_t ICR; /*!< Interrupt Clear Register, Address offset: 0x14 */ + __IO uint32_t WPR1; /*!< SRAM Write Protection Register 1, Address offset: 0x18 */ + __IO uint32_t WPR2; /*!< SRAM Write Protection Register 2, Address offset: 0x1C */ + uint32_t RESERVED; /*!< Reserved, Address offset: 0x20 */ + __IO uint32_t ECCKEY; /*!< SRAM ECC Key Register, Address offset: 0x24 */ + __IO uint32_t ERKEYR; /*!< SRAM Erase Key Register, Address offset: 0x28 */ +}RAMCFG_TypeDef; + +/** + * @brief Reset and Clock Control + */ +typedef struct +{ + __IO uint32_t CR; /*!< RCC clock control register Address offset: 0x00 */ + uint32_t RESERVED1[3]; /*!< Reserved, Address offset: 0x04 */ + __IO uint32_t HSICFGR; /*!< RCC HSI Clock Calibration Register, Address offset: 0x10 */ + __IO uint32_t CRRCR; /*!< RCC Clock Recovery RC Register, Address offset: 0x14 */ + __IO uint32_t CSICFGR; /*!< RCC CSI Clock Calibration Register, Address offset: 0x18 */ + __IO uint32_t CFGR1; /*!< RCC clock configuration register 1 Address offset: 0x1C */ + __IO uint32_t CFGR2; /*!< RCC clock configuration register 2 Address offset: 0x20 */ + uint32_t RESERVED2; /*!< Reserved, Address offset: 0x24 */ + __IO uint32_t PLL1CFGR; /*!< RCC PLL1 Configuration Register Address offset: 0x28 */ + __IO uint32_t PLL2CFGR; /*!< RCC PLL2 Configuration Register Address offset: 0x2C */ + __IO uint32_t PLL3CFGR; /*!< RCC PLL3 Configuration Register Address offset: 0x30 */ + __IO uint32_t PLL1DIVR; /*!< RCC PLL1 Dividers Configuration Register Address offset: 0x34 */ + __IO uint32_t PLL1FRACR; /*!< RCC PLL1 Fractional Divider Configuration Register Address offset: 0x38 */ + __IO uint32_t PLL2DIVR; /*!< RCC PLL2 Dividers Configuration Register Address offset: 0x3C */ + __IO uint32_t PLL2FRACR; /*!< RCC PLL2 Fractional Divider Configuration Register Address offset: 0x40 */ + __IO uint32_t PLL3DIVR; /*!< RCC PLL3 Dividers Configuration Register Address offset: 0x44 */ + __IO uint32_t PLL3FRACR; /*!< RCC PLL3 Fractional Divider Configuration Register Address offset: 0x48 */ + uint32_t RESERVED5; /*!< Reserved Address offset: 0x4C */ + __IO uint32_t CIER; /*!< RCC Clock Interrupt Enable Register Address offset: 0x50 */ + __IO uint32_t CIFR; /*!< RCC Clock Interrupt Flag Register Address offset: 0x54 */ + __IO uint32_t CICR; /*!< RCC Clock Interrupt Clear Register Address offset: 0x58 */ + uint32_t RESERVED6; /*!< Reserved Address offset: 0x5C */ + __IO uint32_t AHB1RSTR; /*!< RCC AHB1 Peripherals Reset Register Address offset: 0x60 */ + __IO uint32_t AHB2RSTR; /*!< RCC AHB2 Peripherals Reset Register Address offset: 0x64 */ + uint32_t RESERVED7; /*!< Reserved Address offset: 0x68 */ + __IO uint32_t AHB4RSTR; /*!< RCC AHB4 Peripherals Reset Register Address offset: 0x6C */ + uint32_t RESERVED9; /*!< Reserved Address offset: 0x70 */ + __IO uint32_t APB1LRSTR; /*!< RCC APB1 Peripherals reset Low Word register Address offset: 0x74 */ + __IO uint32_t APB1HRSTR; /*!< RCC APB1 Peripherals reset High Word register Address offset: 0x78 */ + __IO uint32_t APB2RSTR; /*!< RCC APB2 Peripherals Reset Register Address offset: 0x7C */ + __IO uint32_t APB3RSTR; /*!< RCC APB3 Peripherals Reset Register Address offset: 0x80 */ + uint32_t RESERVED10; /*!< Reserved Address offset: 0x84 */ + __IO uint32_t AHB1ENR; /*!< RCC AHB1 Peripherals Clock Enable Register Address offset: 0x88 */ + __IO uint32_t AHB2ENR; /*!< RCC AHB2 Peripherals Clock Enable Register Address offset: 0x8C */ + uint32_t RESERVED11; /*!< Reserved Address offset: 0x90 */ + __IO uint32_t AHB4ENR; /*!< RCC AHB4 Peripherals Clock Enable Register Address offset: 0x94 */ + uint32_t RESERVED13; /*!< Reserved Address offset: 0x98 */ + __IO uint32_t APB1LENR; /*!< RCC APB1 Peripherals clock Enable Low Word register Address offset: 0x9C */ + __IO uint32_t APB1HENR; /*!< RCC APB1 Peripherals clock Enable High Word register Address offset: 0xA0 */ + __IO uint32_t APB2ENR; /*!< RCC APB2 Peripherals Clock Enable Register Address offset: 0xA4 */ + __IO uint32_t APB3ENR; /*!< RCC APB3 Peripherals Clock Enable Register Address offset: 0xA8 */ + uint32_t RESERVED14; /*!< Reserved Address offset: 0xAC */ + __IO uint32_t AHB1LPENR; /*!< RCC AHB1 Peripheral sleep clock Register Address offset: 0xB0 */ + __IO uint32_t AHB2LPENR; /*!< RCC AHB2 Peripheral sleep clock Register Address offset: 0xB4 */ + uint32_t RESERVED15; /*!< Reserved Address offset: 0xB8 */ + __IO uint32_t AHB4LPENR; /*!< RCC AHB4 Peripherals sleep clock Register Address offset: 0xBC */ + uint32_t RESERVED17; /*!< Reserved Address offset: 0xC0 */ + __IO uint32_t APB1LLPENR; /*!< RCC APB1 Peripherals sleep clock Low Word Register Address offset: 0xC4 */ + __IO uint32_t APB1HLPENR; /*!< RCC APB1 Peripherals sleep clock High Word Register Address offset: 0xC8 */ + __IO uint32_t APB2LPENR; /*!< RCC APB2 Peripherals sleep clock Register Address offset: 0xCC */ + __IO uint32_t APB3LPENR; /*!< RCC APB3 Peripherals Clock Low Power Enable Register Address offset: 0xD0 */ + uint32_t RESERVED18; /*!< Reserved Address offset: 0xD4 */ + __IO uint32_t CCIPR1; /*!< RCC IPs Clocks Configuration Register 1 Address offset: 0xD8 */ + __IO uint32_t CCIPR2; /*!< RCC IPs Clocks Configuration Register 2 Address offset: 0xDC */ + __IO uint32_t CCIPR3; /*!< RCC IPs Clocks Configuration Register 3 Address offset: 0xE0 */ + __IO uint32_t CCIPR4; /*!< RCC IPs Clocks Configuration Register 4 Address offset: 0xE4 */ + __IO uint32_t CCIPR5; /*!< RCC IPs Clocks Configuration Register 5 Address offset: 0xE8 */ + uint32_t RESERVED19; /*!< Reserved, Address offset: 0xEC */ + __IO uint32_t BDCR; /*!< RCC VSW Backup Domain & V33 Domain Control Register Address offset: 0xF0 */ + __IO uint32_t RSR; /*!< RCC Reset status Register Address offset: 0xF4 */ + uint32_t RESERVED20[6]; /*!< Reserved Address offset: 0xF8 */ + __IO uint32_t SECCFGR; /*!< RCC Secure mode configuration register Address offset: 0x110 */ + __IO uint32_t PRIVCFGR; /*!< RCC Privilege configuration register Address offset: 0x114 */ +} RCC_TypeDef; + +/* +* @brief RTC Specific device feature definitions +*/ +#define RTC_BKP_NB 32U +#define RTC_TAMP_NB 8U + +/** + * @brief Real-Time Clock + */ +typedef struct +{ + __IO uint32_t TR; /*!< RTC time register, Address offset: 0x00 */ + __IO uint32_t DR; /*!< RTC date register, Address offset: 0x04 */ + __IO uint32_t SSR; /*!< RTC sub second register, Address offset: 0x08 */ + __IO uint32_t ICSR; /*!< RTC initialization control and status register, Address offset: 0x0C */ + __IO uint32_t PRER; /*!< RTC prescaler register, Address offset: 0x10 */ + __IO uint32_t WUTR; /*!< RTC wakeup timer register, Address offset: 0x14 */ + __IO uint32_t CR; /*!< RTC control register, Address offset: 0x18 */ + __IO uint32_t PRIVCFGR; /*!< RTC privilege mode control register, Address offset: 0x1C */ + __IO uint32_t SECCFGR; /*!< RTC secure mode control register, Address offset: 0x20 */ + __IO uint32_t WPR; /*!< RTC write protection register, Address offset: 0x24 */ + __IO uint32_t CALR; /*!< RTC calibration register, Address offset: 0x28 */ + __IO uint32_t SHIFTR; /*!< RTC shift control register, Address offset: 0x2C */ + __IO uint32_t TSTR; /*!< RTC time stamp time register, Address offset: 0x30 */ + __IO uint32_t TSDR; /*!< RTC time stamp date register, Address offset: 0x34 */ + __IO uint32_t TSSSR; /*!< RTC time-stamp sub second register, Address offset: 0x38 */ + uint32_t RESERVED0; /*!< Reserved, Address offset: 0x3C */ + __IO uint32_t ALRMAR; /*!< RTC alarm A register, Address offset: 0x40 */ + __IO uint32_t ALRMASSR; /*!< RTC alarm A sub second register, Address offset: 0x44 */ + __IO uint32_t ALRMBR; /*!< RTC alarm B register, Address offset: 0x48 */ + __IO uint32_t ALRMBSSR; /*!< RTC alarm B sub second register, Address offset: 0x4C */ + __IO uint32_t SR; /*!< RTC Status register, Address offset: 0x50 */ + __IO uint32_t MISR; /*!< RTC masked interrupt status register, Address offset: 0x54 */ + __IO uint32_t SMISR; /*!< RTC secure masked interrupt status register, Address offset: 0x58 */ + __IO uint32_t SCR; /*!< RTC status Clear register, Address offset: 0x5C */ + __IO uint32_t OR; /*!< RTC option register, Address offset: 0x60 */ + uint32_t RESERVED1[3];/*!< Reserved, Address offset: 0x64 */ + __IO uint32_t ALRABINR; /*!< RTC alarm A binary mode register, Address offset: 0x70 */ + __IO uint32_t ALRBBINR; /*!< RTC alarm B binary mode register, Address offset: 0x74 */ +} RTC_TypeDef; + +/** + * @brief Tamper and backup registers + */ +typedef struct +{ + __IO uint32_t CR1; /*!< TAMP control register 1, Address offset: 0x00 */ + __IO uint32_t CR2; /*!< TAMP control register 2, Address offset: 0x04 */ + __IO uint32_t CR3; /*!< TAMP control register 3, Address offset: 0x08 */ + __IO uint32_t FLTCR; /*!< TAMP filter control register, Address offset: 0x0C */ + __IO uint32_t ATCR1; /*!< TAMP filter control register 1 Address offset: 0x10 */ + __IO uint32_t ATSEEDR; /*!< TAMP active tamper seed register, Address offset: 0x14 */ + __IO uint32_t ATOR; /*!< TAMP active tamper output register, Address offset: 0x18 */ + __IO uint32_t ATCR2; /*!< TAMP filter control register 2, Address offset: 0x1C */ + __IO uint32_t SECCFGR; /*!< TAMP secure mode control register, Address offset: 0x20 */ + __IO uint32_t PRIVCFGR; /*!< TAMP privilege mode control register, Address offset: 0x24 */ + uint32_t RESERVED0; /*!< Reserved, Address offset: 0x28 */ + __IO uint32_t IER; /*!< TAMP interrupt enable register, Address offset: 0x2C */ + __IO uint32_t SR; /*!< TAMP status register, Address offset: 0x30 */ + __IO uint32_t MISR; /*!< TAMP masked interrupt status register, Address offset: 0x34 */ + __IO uint32_t SMISR; /*!< TAMP secure masked interrupt status register, Address offset: 0x38 */ + __IO uint32_t SCR; /*!< TAMP status clear register, Address offset: 0x3C */ + __IO uint32_t COUNT1R; /*!< TAMP monotonic counter register, Address offset: 0x40 */ + uint32_t RESERVED1[3];/*!< Reserved, Address offset: 0x44 -- 0x4C */ + __IO uint32_t OR; /*!< TAMP option register, Address offset: 0x50 */ + __IO uint32_t ERCFGR; /*!< TAMP erase configuration register, Address offset: 0x54 */ + uint32_t RESERVED2[42];/*!< Reserved, Address offset: 0x58 -- 0xFC */ + __IO uint32_t BKP0R; /*!< TAMP backup register 0, Address offset: 0x100 */ + __IO uint32_t BKP1R; /*!< TAMP backup register 1, Address offset: 0x104 */ + __IO uint32_t BKP2R; /*!< TAMP backup register 2, Address offset: 0x108 */ + __IO uint32_t BKP3R; /*!< TAMP backup register 3, Address offset: 0x10C */ + __IO uint32_t BKP4R; /*!< TAMP backup register 4, Address offset: 0x110 */ + __IO uint32_t BKP5R; /*!< TAMP backup register 5, Address offset: 0x114 */ + __IO uint32_t BKP6R; /*!< TAMP backup register 6, Address offset: 0x118 */ + __IO uint32_t BKP7R; /*!< TAMP backup register 7, Address offset: 0x11C */ + __IO uint32_t BKP8R; /*!< TAMP backup register 8, Address offset: 0x120 */ + __IO uint32_t BKP9R; /*!< TAMP backup register 9, Address offset: 0x124 */ + __IO uint32_t BKP10R; /*!< TAMP backup register 10, Address offset: 0x128 */ + __IO uint32_t BKP11R; /*!< TAMP backup register 11, Address offset: 0x12C */ + __IO uint32_t BKP12R; /*!< TAMP backup register 12, Address offset: 0x130 */ + __IO uint32_t BKP13R; /*!< TAMP backup register 13, Address offset: 0x134 */ + __IO uint32_t BKP14R; /*!< TAMP backup register 14, Address offset: 0x138 */ + __IO uint32_t BKP15R; /*!< TAMP backup register 15, Address offset: 0x13C */ + __IO uint32_t BKP16R; /*!< TAMP backup register 16, Address offset: 0x140 */ + __IO uint32_t BKP17R; /*!< TAMP backup register 17, Address offset: 0x144 */ + __IO uint32_t BKP18R; /*!< TAMP backup register 18, Address offset: 0x148 */ + __IO uint32_t BKP19R; /*!< TAMP backup register 19, Address offset: 0x14C */ + __IO uint32_t BKP20R; /*!< TAMP backup register 20, Address offset: 0x150 */ + __IO uint32_t BKP21R; /*!< TAMP backup register 21, Address offset: 0x154 */ + __IO uint32_t BKP22R; /*!< TAMP backup register 22, Address offset: 0x158 */ + __IO uint32_t BKP23R; /*!< TAMP backup register 23, Address offset: 0x15C */ + __IO uint32_t BKP24R; /*!< TAMP backup register 24, Address offset: 0x160 */ + __IO uint32_t BKP25R; /*!< TAMP backup register 25, Address offset: 0x164 */ + __IO uint32_t BKP26R; /*!< TAMP backup register 26, Address offset: 0x168 */ + __IO uint32_t BKP27R; /*!< TAMP backup register 27, Address offset: 0x16C */ + __IO uint32_t BKP28R; /*!< TAMP backup register 28, Address offset: 0x170 */ + __IO uint32_t BKP29R; /*!< TAMP backup register 29, Address offset: 0x174 */ + __IO uint32_t BKP30R; /*!< TAMP backup register 30, Address offset: 0x178 */ + __IO uint32_t BKP31R; /*!< TAMP backup register 31, Address offset: 0x17C */ +} TAMP_TypeDef; + +/** + * @brief Universal Synchronous Asynchronous Receiver Transmitter + */ +typedef struct +{ + __IO uint32_t CR1; /*!< USART Control register 1, Address offset: 0x00 */ + __IO uint32_t CR2; /*!< USART Control register 2, Address offset: 0x04 */ + __IO uint32_t CR3; /*!< USART Control register 3, Address offset: 0x08 */ + __IO uint32_t BRR; /*!< USART Baud rate register, Address offset: 0x0C */ + __IO uint32_t GTPR; /*!< USART Guard time and prescaler register, Address offset: 0x10 */ + __IO uint32_t RTOR; /*!< USART Receiver Time Out register, Address offset: 0x14 */ + __IO uint32_t RQR; /*!< USART Request register, Address offset: 0x18 */ + __IO uint32_t ISR; /*!< USART Interrupt and status register, Address offset: 0x1C */ + __IO uint32_t ICR; /*!< USART Interrupt flag Clear register, Address offset: 0x20 */ + __IO uint32_t RDR; /*!< USART Receive Data register, Address offset: 0x24 */ + __IO uint32_t TDR; /*!< USART Transmit Data register, Address offset: 0x28 */ + __IO uint32_t PRESC; /*!< USART Prescaler register, Address offset: 0x2C */ +} USART_TypeDef; + +/** + * @brief Serial Audio Interface + */ +typedef struct +{ + __IO uint32_t GCR; /*!< SAI global configuration register, Address offset: 0x00 */ + uint32_t RESERVED[16]; /*!< Reserved, Address offset: 0x04 to 0x40 */ + __IO uint32_t PDMCR; /*!< SAI PDM control register, Address offset: 0x44 */ + __IO uint32_t PDMDLY; /*!< SAI PDM delay register, Address offset: 0x48 */ +} SAI_TypeDef; + +typedef struct +{ + __IO uint32_t CR1; /*!< SAI block x configuration register 1, Address offset: 0x04 */ + __IO uint32_t CR2; /*!< SAI block x configuration register 2, Address offset: 0x08 */ + __IO uint32_t FRCR; /*!< SAI block x frame configuration register, Address offset: 0x0C */ + __IO uint32_t SLOTR; /*!< SAI block x slot register, Address offset: 0x10 */ + __IO uint32_t IMR; /*!< SAI block x interrupt mask register, Address offset: 0x14 */ + __IO uint32_t SR; /*!< SAI block x status register, Address offset: 0x18 */ + __IO uint32_t CLRFR; /*!< SAI block x clear flag register, Address offset: 0x1C */ + __IO uint32_t DR; /*!< SAI block x data register, Address offset: 0x20 */ +} SAI_Block_TypeDef; +/** + * @brief System configuration, Boot and Security + */ +typedef struct +{ + uint32_t RESERVED1[4]; /*!< RESERVED1, Address offset: 0x00 - 0x0C */ + __IO uint32_t HDPLCR; /*!< SBS HDPL Control Register, Address offset: 0x10 */ + __IO uint32_t HDPLSR; /*!< SBS HDPL Status Register, Address offset: 0x14 */ + __IO uint32_t NEXTHDPLCR; /*!< NEXT HDPL Control Register, Address offset: 0x18 */ + __IO uint32_t RESERVED2; /*!< RESERVED2, Address offset: 0x1C */ + __IO uint32_t DBGCR; /*!< SBS Debug Control Register, Address offset: 0x20 */ + __IO uint32_t DBGLOCKR; /*!< SBS Debug Lock Register, Address offset: 0x24 */ + uint32_t RESERVED3[3]; /*!< RESERVED3, Address offset: 0x28 - 0x30 */ + __IO uint32_t RSSCMDR; /*!< SBS RSS Command Register, Address offset: 0x34 */ + uint32_t RESERVED4[26]; /*!< RESERVED4, Address offset: 0x38 - 0x9C */ + __IO uint32_t EPOCHSELCR; /*!< EPOCH Selection Register, Address offset: 0xA0 */ + uint32_t RESERVED5[7]; /*!< RESERVED5, Address offset: 0xA4 - 0xBC */ + __IO uint32_t SECCFGR; /*!< SBS Security Mode Configuration, Address offset: 0xC0 */ + uint32_t RESERVED6[15]; /*!< RESERVED6, Address offset: 0xC4 - 0xFC */ + __IO uint32_t PMCR; /*!< SBS Product Mode & Config Register, Address offset: 0x100 */ + __IO uint32_t FPUIMR; /*!< SBS FPU Interrupt Mask Register, Address offset: 0x104 */ + __IO uint32_t MESR; /*!< SBS Memory Erase Status Register, Address offset: 0x108 */ + uint32_t RESERVED7; /*!< RESERVED7, Address offset: 0x10C */ + __IO uint32_t CCCSR; /*!< SBS Compensation Cell Control & Status Register, Address offset: 0x110 */ + __IO uint32_t CCVALR; /*!< SBS Compensation Cell Value Register, Address offset: 0x114 */ + __IO uint32_t CCSWCR; /*!< SBS Compensation Cell for I/Os sw code Register, Address offset: 0x118 */ + __IO uint32_t RESERVED8; /*!< RESERVED8, Address offset: 0x11C */ + __IO uint32_t CFGR2; /*!< SBS Class B Register, Address offset: 0x120 */ + uint32_t RESERVED9[8]; /*!< RESERVED9, Address offset: 0x124 - 0x140 */ + __IO uint32_t CNSLCKR; /*!< SBS CPU Non-secure Lock Register, Address offset: 0x144 */ + __IO uint32_t CSLCKR; /*!< SBS CPU Secure Lock Register, Address offset: 0x148 */ + __IO uint32_t ECCNMIR; /*!< SBS FLITF ECC NMI MASK Register, Address offset: 0x14C */ +} SBS_TypeDef; + +/** + * @brief Secure digital input/output Interface + */ +typedef struct +{ + __IO uint32_t POWER; /*!< SDMMC power control register, Address offset: 0x00 */ + __IO uint32_t CLKCR; /*!< SDMMC clock control register, Address offset: 0x04 */ + __IO uint32_t ARG; /*!< SDMMC argument register, Address offset: 0x08 */ + __IO uint32_t CMD; /*!< SDMMC command register, Address offset: 0x0C */ + __I uint32_t RESPCMD; /*!< SDMMC command response register, Address offset: 0x10 */ + __I uint32_t RESP1; /*!< SDMMC response 1 register, Address offset: 0x14 */ + __I uint32_t RESP2; /*!< SDMMC response 2 register, Address offset: 0x18 */ + __I uint32_t RESP3; /*!< SDMMC response 3 register, Address offset: 0x1C */ + __I uint32_t RESP4; /*!< SDMMC response 4 register, Address offset: 0x20 */ + __IO uint32_t DTIMER; /*!< SDMMC data timer register, Address offset: 0x24 */ + __IO uint32_t DLEN; /*!< SDMMC data length register, Address offset: 0x28 */ + __IO uint32_t DCTRL; /*!< SDMMC data control register, Address offset: 0x2C */ + __I uint32_t DCOUNT; /*!< SDMMC data counter register, Address offset: 0x30 */ + __I uint32_t STA; /*!< SDMMC status register, Address offset: 0x34 */ + __IO uint32_t ICR; /*!< SDMMC interrupt clear register, Address offset: 0x38 */ + __IO uint32_t MASK; /*!< SDMMC mask register, Address offset: 0x3C */ + __IO uint32_t ACKTIME; /*!< SDMMC Acknowledgement timer register, Address offset: 0x40 */ + uint32_t RESERVED0[3]; /*!< Reserved, 0x44 - 0x4C - 0x4C */ + __IO uint32_t IDMACTRL; /*!< SDMMC DMA control register, Address offset: 0x50 */ + __IO uint32_t IDMABSIZE; /*!< SDMMC DMA buffer size register, Address offset: 0x54 */ + __IO uint32_t IDMABASER; /*!< SDMMC DMA buffer base address register, Address offset: 0x58 */ + uint32_t RESERVED1[2]; /*!< Reserved, 0x60 */ + __IO uint32_t IDMALAR; /*!< SDMMC DMA linked list address register, Address offset: 0x64 */ + __IO uint32_t IDMABAR; /*!< SDMMC DMA linked list memory base register,Address offset: 0x68 */ + uint32_t RESERVED2[5]; /*!< Reserved, 0x6C-0x7C */ + __IO uint32_t FIFO; /*!< SDMMC data FIFO register, Address offset: 0x80 */ +} SDMMC_TypeDef; + + + +/** + * @brief Delay Block DLYB + */ + +typedef struct +{ + __IO uint32_t CR; /*!< DELAY BLOCK control register, Address offset: 0x00 */ + __IO uint32_t CFGR; /*!< DELAY BLOCK configuration register, Address offset: 0x04 */ +} DLYB_TypeDef; + +/** + * @brief UCPD + */ +typedef struct +{ + __IO uint32_t CFG1; /*!< UCPD configuration register 1, Address offset: 0x00 */ + __IO uint32_t CFG2; /*!< UCPD configuration register 2, Address offset: 0x04 */ + __IO uint32_t CFG3; /*!< UCPD configuration register 3, Address offset: 0x08 */ + __IO uint32_t CR; /*!< UCPD control register, Address offset: 0x0C */ + __IO uint32_t IMR; /*!< UCPD interrupt mask register, Address offset: 0x10 */ + __IO uint32_t SR; /*!< UCPD status register, Address offset: 0x14 */ + __IO uint32_t ICR; /*!< UCPD interrupt flag clear register Address offset: 0x18 */ + __IO uint32_t TX_ORDSET; /*!< UCPD Tx ordered set type register, Address offset: 0x1C */ + __IO uint32_t TX_PAYSZ; /*!< UCPD Tx payload size register, Address offset: 0x20 */ + __IO uint32_t TXDR; /*!< UCPD Tx data register, Address offset: 0x24 */ + __IO uint32_t RX_ORDSET; /*!< UCPD Rx ordered set type register, Address offset: 0x28 */ + __IO uint32_t RX_PAYSZ; /*!< UCPD Rx payload size register, Address offset: 0x2C */ + __IO uint32_t RXDR; /*!< UCPD Rx data register, Address offset: 0x30 */ + __IO uint32_t RX_ORDEXT1; /*!< UCPD Rx ordered set extension 1 register, Address offset: 0x34 */ + __IO uint32_t RX_ORDEXT2; /*!< UCPD Rx ordered set extension 2 register, Address offset: 0x38 */ + uint32_t RESERVED[949];/*!< Reserved, Address offset: 0x3C -- 0x3F0 */ + __IO uint32_t IPVER; /*!< UCPD IP version register, Address offset: 0x3F4 */ + __IO uint32_t IPID; /*!< UCPD IP Identification register, Address offset: 0x3F8 */ + __IO uint32_t MID; /*!< UCPD Magic Identification register, Address offset: 0x3FC */ +} UCPD_TypeDef; + +/** + * @brief Universal Serial Bus Full Speed Dual Role Device + */ +typedef struct +{ + __IO uint32_t CHEP0R; /*!< USB Channel/Endpoint 0 register, Address offset: 0x00 */ + __IO uint32_t CHEP1R; /*!< USB Channel/Endpoint 1 register, Address offset: 0x04 */ + __IO uint32_t CHEP2R; /*!< USB Channel/Endpoint 2 register, Address offset: 0x08 */ + __IO uint32_t CHEP3R; /*!< USB Channel/Endpoint 3 register, Address offset: 0x0C */ + __IO uint32_t CHEP4R; /*!< USB Channel/Endpoint 4 register, Address offset: 0x10 */ + __IO uint32_t CHEP5R; /*!< USB Channel/Endpoint 5 register, Address offset: 0x14 */ + __IO uint32_t CHEP6R; /*!< USB Channel/Endpoint 6 register, Address offset: 0x18 */ + __IO uint32_t CHEP7R; /*!< USB Channel/Endpoint 7 register, Address offset: 0x1C */ + __IO uint32_t RESERVED0[8]; /*!< Reserved, */ + __IO uint32_t CNTR; /*!< Control register, Address offset: 0x40 */ + __IO uint32_t ISTR; /*!< Interrupt status register, Address offset: 0x44 */ + __IO uint32_t FNR; /*!< Frame number register, Address offset: 0x48 */ + __IO uint32_t DADDR; /*!< Device address register, Address offset: 0x4C */ + __IO uint32_t RESERVED1; /*!< Reserved */ + __IO uint32_t LPMCSR; /*!< LPM Control and Status register, Address offset: 0x54 */ + __IO uint32_t BCDR; /*!< Battery Charging detector register, Address offset: 0x58 */ +} USB_DRD_TypeDef; + +/** + * @brief Universal Serial Bus PacketMemoryArea Buffer Descriptor Table + */ +typedef struct +{ + __IO uint32_t TXBD; /*!= 6010050) + #pragma clang diagnostic pop +#elif defined (__GNUC__) + /* anonymous unions are enabled by default */ +#elif defined (__TMS470__) + /* anonymous unions are enabled by default */ +#elif defined (__TASKING__) + #pragma warning restore +#elif defined (__CSMC__) + /* anonymous unions are enabled by default */ +#else + #warning Not supported compiler type +#endif + + +/* =========================================================================================================================== */ +/* ================ Device Specific Peripheral Address Map ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup STM32H5xx_Peripheral_peripheralAddr + * @{ + */ + +/* Internal SRAMs size */ +#define SRAM1_SIZE (0x40000UL) /*!< SRAM1=256k */ +#define SRAM2_SIZE (0x10000UL) /*!< SRAM2=64k */ +#define SRAM3_SIZE (0x50000UL) /*!< SRAM3=320k */ +#define BKPSRAM_SIZE (0x01000UL) /*!< BKPSRAM=4k */ + +/* Flash, Peripheral and internal SRAMs base addresses - Non secure */ +#define FLASH_BASE_NS (0x08000000UL) /*!< FLASH (up to 2 MB) non-secure base address */ +#define SRAM1_BASE_NS (0x20000000UL) /*!< SRAM1 (256 KB) non-secure base address */ +#define SRAM2_BASE_NS (0x20040000UL) /*!< SRAM2 (64 KB) non-secure base address */ +#define SRAM3_BASE_NS (0x20050000UL) /*!< SRAM3 (320 KB) non-secure base address */ +#define PERIPH_BASE_NS (0x40000000UL) /*!< Peripheral non-secure base address */ + +/* External memories base addresses - Not aliased */ +#define FMC_BASE (0x60000000UL) /*!< FMC base address */ +#define OCTOSPI1_BASE (0x90000000UL) /*!< OCTOSPI1 memories accessible over AHB base address */ + +#define FMC_BANK1 FMC_BASE +#define FMC_BANK1_1 FMC_BANK1 +#define FMC_BANK1_2 (FMC_BANK1 + 0x04000000UL) /*!< FMC Memory Bank1 for SRAM, NOR and PSRAM */ +#define FMC_BANK1_3 (FMC_BANK1 + 0x08000000UL) +#define FMC_BANK1_4 (FMC_BANK1 + 0x0C000000UL) +#define FMC_BANK3 (FMC_BASE + 0x20000000UL) /*!< FMC Memory Bank3 for NAND */ +#define FMC_SDRAM_BANK_1 (FMC_BASE + 0x60000000UL) /*!< FMC Memory SDRAM Bank1 */ +#define FMC_SDRAM_BANK_2 (FMC_BASE + 0x70000000UL) /*!< FMC Memory SDRAM Bank2 */ + + +/* Peripheral memory map - Non secure */ +#define APB1PERIPH_BASE_NS PERIPH_BASE_NS +#define APB2PERIPH_BASE_NS (PERIPH_BASE_NS + 0x00010000UL) +#define AHB1PERIPH_BASE_NS (PERIPH_BASE_NS + 0x00020000UL) +#define AHB2PERIPH_BASE_NS (PERIPH_BASE_NS + 0x02020000UL) +#define APB3PERIPH_BASE_NS (PERIPH_BASE_NS + 0x04000000UL) +#define AHB3PERIPH_BASE_NS (PERIPH_BASE_NS + 0x04020000UL) +#define AHB4PERIPH_BASE_NS (PERIPH_BASE_NS + 0x06000000UL) + +/*!< APB1 Non secure peripherals */ +#define TIM2_BASE_NS (APB1PERIPH_BASE_NS + 0x0000UL) +#define TIM3_BASE_NS (APB1PERIPH_BASE_NS + 0x0400UL) +#define TIM4_BASE_NS (APB1PERIPH_BASE_NS + 0x0800UL) +#define TIM5_BASE_NS (APB1PERIPH_BASE_NS + 0x0C00UL) +#define TIM6_BASE_NS (APB1PERIPH_BASE_NS + 0x1000UL) +#define TIM7_BASE_NS (APB1PERIPH_BASE_NS + 0x1400UL) +#define TIM12_BASE_NS (APB1PERIPH_BASE_NS + 0x1800UL) +#define TIM13_BASE_NS (APB1PERIPH_BASE_NS + 0x1C00UL) +#define TIM14_BASE_NS (APB1PERIPH_BASE_NS + 0x2000UL) +#define WWDG_BASE_NS (APB1PERIPH_BASE_NS + 0x2C00UL) +#define IWDG_BASE_NS (APB1PERIPH_BASE_NS + 0x3000UL) +#define SPI2_BASE_NS (APB1PERIPH_BASE_NS + 0x3800UL) +#define SPI3_BASE_NS (APB1PERIPH_BASE_NS + 0x3C00UL) +#define USART2_BASE_NS (APB1PERIPH_BASE_NS + 0x4400UL) +#define USART3_BASE_NS (APB1PERIPH_BASE_NS + 0x4800UL) +#define UART4_BASE_NS (APB1PERIPH_BASE_NS + 0x4C00UL) +#define UART5_BASE_NS (APB1PERIPH_BASE_NS + 0x5000UL) +#define I2C1_BASE_NS (APB1PERIPH_BASE_NS + 0x5400UL) +#define I2C2_BASE_NS (APB1PERIPH_BASE_NS + 0x5800UL) +#define I3C1_BASE_NS (APB1PERIPH_BASE_NS + 0x5C00UL) +#define CRS_BASE_NS (APB1PERIPH_BASE_NS + 0x6000UL) +#define USART6_BASE_NS (APB1PERIPH_BASE_NS + 0x6400UL) +#define USART10_BASE_NS (APB1PERIPH_BASE_NS + 0x6800UL) +#define USART11_BASE_NS (APB1PERIPH_BASE_NS + 0x6C00UL) +#define CEC_BASE_NS (APB1PERIPH_BASE_NS + 0x7000UL) +#define UART7_BASE_NS (APB1PERIPH_BASE_NS + 0x7800UL) +#define UART8_BASE_NS (APB1PERIPH_BASE_NS + 0x7C00UL) +#define UART9_BASE_NS (APB1PERIPH_BASE_NS + 0x8000UL) +#define UART12_BASE_NS (APB1PERIPH_BASE_NS + 0x8400UL) +#define DTS_BASE_NS (APB1PERIPH_BASE_NS + 0x8C00UL) +#define LPTIM2_BASE_NS (APB1PERIPH_BASE_NS + 0x9400UL) +#define FDCAN1_BASE_NS (APB1PERIPH_BASE_NS + 0xA400UL) +#define FDCAN_CONFIG_BASE_NS (APB1PERIPH_BASE_NS + 0xA500UL) +#define SRAMCAN_BASE_NS (APB1PERIPH_BASE_NS + 0xAC00UL) +#define UCPD1_BASE_NS (APB1PERIPH_BASE_NS + 0xDC00UL) + +/*!< APB2 Non secure peripherals */ +#define TIM1_BASE_NS (APB2PERIPH_BASE_NS + 0x2C00UL) +#define SPI1_BASE_NS (APB2PERIPH_BASE_NS + 0x3000UL) +#define TIM8_BASE_NS (APB2PERIPH_BASE_NS + 0x3400UL) +#define USART1_BASE_NS (APB2PERIPH_BASE_NS + 0x3800UL) +#define TIM15_BASE_NS (APB2PERIPH_BASE_NS + 0x4000UL) +#define TIM16_BASE_NS (APB2PERIPH_BASE_NS + 0x4400UL) +#define TIM17_BASE_NS (APB2PERIPH_BASE_NS + 0x4800UL) +#define SPI4_BASE_NS (APB2PERIPH_BASE_NS + 0x4C00UL) +#define SPI6_BASE_NS (APB2PERIPH_BASE_NS + 0x5000UL) +#define SAI1_BASE_NS (APB2PERIPH_BASE_NS + 0x5400UL) +#define SAI1_Block_A_BASE_NS (SAI1_BASE_NS + 0x004UL) +#define SAI1_Block_B_BASE_NS (SAI1_BASE_NS + 0x024UL) +#define SAI2_BASE_NS (APB2PERIPH_BASE_NS + 0x5800UL) +#define SAI2_Block_A_BASE_NS (SAI2_BASE_NS + 0x004UL) +#define SAI2_Block_B_BASE_NS (SAI2_BASE_NS + 0x024UL) +#define USB_DRD_BASE_NS (APB2PERIPH_BASE_NS + 0x6000UL) +#define USB_DRD_PMAADDR_NS (APB2PERIPH_BASE_NS + 0x6400UL) + +/*!< AHB1 Non secure peripherals */ +#define GPDMA1_BASE_NS AHB1PERIPH_BASE_NS +#define GPDMA2_BASE_NS (AHB1PERIPH_BASE_NS + 0x01000UL) +#define FLASH_R_BASE_NS (AHB1PERIPH_BASE_NS + 0x02000UL) +#define CRC_BASE_NS (AHB1PERIPH_BASE_NS + 0x03000UL) +#define CORDIC_BASE_NS (AHB1PERIPH_BASE_NS + 0x03800UL) +#define FMAC_BASE_NS (AHB1PERIPH_BASE_NS + 0x03C00UL) +#define RAMCFG_BASE_NS (AHB1PERIPH_BASE_NS + 0x06000UL) +#define ICACHE_BASE_NS (AHB1PERIPH_BASE_NS + 0x10400UL) +#define DCACHE1_BASE_NS (AHB1PERIPH_BASE_NS + 0x11400UL) +#define GTZC_TZSC1_BASE_NS (AHB1PERIPH_BASE_NS + 0x12400UL) +#define GTZC_TZIC1_BASE_NS (AHB1PERIPH_BASE_NS + 0x12800UL) +#define GTZC_MPCBB1_BASE_NS (AHB1PERIPH_BASE_NS + 0x12C00UL) +#define GTZC_MPCBB2_BASE_NS (AHB1PERIPH_BASE_NS + 0x13000UL) +#define GTZC_MPCBB3_BASE_NS (AHB1PERIPH_BASE_NS + 0x13400UL) +#define BKPSRAM_BASE_NS (AHB1PERIPH_BASE_NS + 0x16400UL) + +#define GPDMA1_Channel0_BASE_NS (GPDMA1_BASE_NS + 0x0050UL) +#define GPDMA1_Channel1_BASE_NS (GPDMA1_BASE_NS + 0x00D0UL) +#define GPDMA1_Channel2_BASE_NS (GPDMA1_BASE_NS + 0x0150UL) +#define GPDMA1_Channel3_BASE_NS (GPDMA1_BASE_NS + 0x01D0UL) +#define GPDMA1_Channel4_BASE_NS (GPDMA1_BASE_NS + 0x0250UL) +#define GPDMA1_Channel5_BASE_NS (GPDMA1_BASE_NS + 0x02D0UL) +#define GPDMA1_Channel6_BASE_NS (GPDMA1_BASE_NS + 0x0350UL) +#define GPDMA1_Channel7_BASE_NS (GPDMA1_BASE_NS + 0x03D0UL) +#define GPDMA2_Channel0_BASE_NS (GPDMA2_BASE_NS + 0x0050UL) +#define GPDMA2_Channel1_BASE_NS (GPDMA2_BASE_NS + 0x00D0UL) +#define GPDMA2_Channel2_BASE_NS (GPDMA2_BASE_NS + 0x0150UL) +#define GPDMA2_Channel3_BASE_NS (GPDMA2_BASE_NS + 0x01D0UL) +#define GPDMA2_Channel4_BASE_NS (GPDMA2_BASE_NS + 0x0250UL) +#define GPDMA2_Channel5_BASE_NS (GPDMA2_BASE_NS + 0x02D0UL) +#define GPDMA2_Channel6_BASE_NS (GPDMA2_BASE_NS + 0x0350UL) +#define GPDMA2_Channel7_BASE_NS (GPDMA2_BASE_NS + 0x03D0UL) + +#define RAMCFG_SRAM1_BASE_NS (RAMCFG_BASE_NS) +#define RAMCFG_SRAM2_BASE_NS (RAMCFG_BASE_NS + 0x0040UL) +#define RAMCFG_SRAM3_BASE_NS (RAMCFG_BASE_NS + 0x0080UL) +#define RAMCFG_BKPRAM_BASE_NS (RAMCFG_BASE_NS + 0x0100UL) + +/*!< AHB2 Non secure peripherals */ +#define GPIOA_BASE_NS (AHB2PERIPH_BASE_NS + 0x00000UL) +#define GPIOB_BASE_NS (AHB2PERIPH_BASE_NS + 0x00400UL) +#define GPIOC_BASE_NS (AHB2PERIPH_BASE_NS + 0x00800UL) +#define GPIOD_BASE_NS (AHB2PERIPH_BASE_NS + 0x00C00UL) +#define GPIOE_BASE_NS (AHB2PERIPH_BASE_NS + 0x01000UL) +#define GPIOF_BASE_NS (AHB2PERIPH_BASE_NS + 0x01400UL) +#define GPIOG_BASE_NS (AHB2PERIPH_BASE_NS + 0x01800UL) +#define GPIOH_BASE_NS (AHB2PERIPH_BASE_NS + 0x01C00UL) +#define GPIOI_BASE_NS (AHB2PERIPH_BASE_NS + 0x02000UL) +#define ADC1_BASE_NS (AHB2PERIPH_BASE_NS + 0x08000UL) +#define ADC2_BASE_NS (AHB2PERIPH_BASE_NS + 0x08100UL) +#define ADC12_COMMON_BASE_NS (AHB2PERIPH_BASE_NS + 0x08300UL) +#define DAC1_BASE_NS (AHB2PERIPH_BASE_NS + 0x08400UL) +#define DCMI_BASE_NS (AHB2PERIPH_BASE_NS + 0x0C000UL) +#define PSSI_BASE_NS (AHB2PERIPH_BASE_NS + 0x0C400UL) + +#define HASH_BASE_NS (AHB2PERIPH_BASE_NS + 0xA0400UL) +#define HASH_DIGEST_BASE_NS (AHB2PERIPH_BASE_NS + 0xA0710UL) +#define RNG_BASE_NS (AHB2PERIPH_BASE_NS + 0xA0800UL) + + +/*!< APB3 Non secure peripherals */ +#define SBS_BASE_NS (APB3PERIPH_BASE_NS + 0x0400UL) +#define SPI5_BASE_NS (APB3PERIPH_BASE_NS + 0x2000UL) +#define LPUART1_BASE_NS (APB3PERIPH_BASE_NS + 0x2400UL) +#define I2C3_BASE_NS (APB3PERIPH_BASE_NS + 0x2800UL) +#define I2C4_BASE_NS (APB3PERIPH_BASE_NS + 0x2C00UL) +#define LPTIM1_BASE_NS (APB3PERIPH_BASE_NS + 0x4400UL) +#define LPTIM3_BASE_NS (APB3PERIPH_BASE_NS + 0x4800UL) +#define LPTIM4_BASE_NS (APB3PERIPH_BASE_NS + 0x4C00UL) +#define LPTIM5_BASE_NS (APB3PERIPH_BASE_NS + 0x5000UL) +#define LPTIM6_BASE_NS (APB3PERIPH_BASE_NS + 0x5400UL) +#define VREFBUF_BASE_NS (APB3PERIPH_BASE_NS + 0x7400UL) +#define RTC_BASE_NS (APB3PERIPH_BASE_NS + 0x7800UL) +#define TAMP_BASE_NS (APB3PERIPH_BASE_NS + 0x7C00UL) + +/*!< AHB3 Non secure peripherals */ +#define PWR_BASE_NS (AHB3PERIPH_BASE_NS + 0x0800UL) +#define RCC_BASE_NS (AHB3PERIPH_BASE_NS + 0x0C00UL) +#define EXTI_BASE_NS (AHB3PERIPH_BASE_NS + 0x2000UL) +#define DEBUG_BASE_NS (AHB3PERIPH_BASE_NS + 0x4000UL) +/*!< AHB4 Non secure peripherals */ +#define SDMMC1_BASE_NS (AHB4PERIPH_BASE_NS + 0x8000UL) +#define DLYB_SDMMC1_BASE_NS (AHB4PERIPH_BASE_NS + 0x8400UL) + +#define FMC_R_BASE_NS (AHB4PERIPH_BASE_NS + 0x1000400UL) /*!< FMC control registers base address */ +#define OCTOSPI1_R_BASE_NS (AHB4PERIPH_BASE_NS + 0x1001400UL) /*!< OCTOSPI1 control registers base address */ +#define DLYB_OCTOSPI1_BASE_NS (AHB4PERIPH_BASE_NS + 0x0F000UL) + +/*!< FMC Banks Non secure registers base address */ +#define FMC_Bank1_R_BASE_NS (FMC_R_BASE_NS + 0x0000UL) +#define FMC_Bank1E_R_BASE_NS (FMC_R_BASE_NS + 0x0104UL) +#define FMC_Bank3_R_BASE_NS (FMC_R_BASE_NS + 0x0080UL) +#define FMC_Bank5_6_R_BASE_NS (FMC_R_BASE_NS + 0x0140UL) + +/* Flash, Peripheral and internal SRAMs base addresses - Secure */ +#define FLASH_BASE_S (0x0C000000UL) /*!< FLASH (up to 2 MB) secure base address */ +#define SRAM1_BASE_S (0x30000000UL) /*!< SRAM1 (192 KB) secure base address */ +#define SRAM2_BASE_S (0x30040000UL) /*!< SRAM2 (64 KB) secure base address */ +#define SRAM3_BASE_S (0x30050000UL) /*!< SRAM3 (512 KB) secure base address */ +#define PERIPH_BASE_S (0x50000000UL) /*!< Peripheral secure base address */ + +/* Peripheral memory map - Secure */ +#define APB1PERIPH_BASE_S PERIPH_BASE_S +#define APB2PERIPH_BASE_S (PERIPH_BASE_S + 0x00010000UL) +#define AHB1PERIPH_BASE_S (PERIPH_BASE_S + 0x00020000UL) +#define AHB2PERIPH_BASE_S (PERIPH_BASE_S + 0x02020000UL) +#define APB3PERIPH_BASE_S (PERIPH_BASE_S + 0x04000000UL) +#define AHB3PERIPH_BASE_S (PERIPH_BASE_S + 0x04020000UL) +#define AHB4PERIPH_BASE_S (PERIPH_BASE_S + 0x06000000UL) + +/*!< APB1 secure peripherals */ +#define TIM2_BASE_S (APB1PERIPH_BASE_S + 0x0000UL) +#define TIM3_BASE_S (APB1PERIPH_BASE_S + 0x0400UL) +#define TIM4_BASE_S (APB1PERIPH_BASE_S + 0x0800UL) +#define TIM5_BASE_S (APB1PERIPH_BASE_S + 0x0C00UL) +#define TIM6_BASE_S (APB1PERIPH_BASE_S + 0x1000UL) +#define TIM7_BASE_S (APB1PERIPH_BASE_S + 0x1400UL) +#define TIM12_BASE_S (APB1PERIPH_BASE_S + 0x1800UL) +#define TIM13_BASE_S (APB1PERIPH_BASE_S + 0x1C00UL) +#define TIM14_BASE_S (APB1PERIPH_BASE_S + 0x2000UL) +#define WWDG_BASE_S (APB1PERIPH_BASE_S + 0x2C00UL) +#define IWDG_BASE_S (APB1PERIPH_BASE_S + 0x3000UL) +#define SPI2_BASE_S (APB1PERIPH_BASE_S + 0x3800UL) +#define SPI3_BASE_S (APB1PERIPH_BASE_S + 0x3C00UL) +#define USART2_BASE_S (APB1PERIPH_BASE_S + 0x4400UL) +#define USART3_BASE_S (APB1PERIPH_BASE_S + 0x4800UL) +#define UART4_BASE_S (APB1PERIPH_BASE_S + 0x4C00UL) +#define UART5_BASE_S (APB1PERIPH_BASE_S + 0x5000UL) +#define I2C1_BASE_S (APB1PERIPH_BASE_S + 0x5400UL) +#define I2C2_BASE_S (APB1PERIPH_BASE_S + 0x5800UL) +#define I3C1_BASE_S (APB1PERIPH_BASE_S + 0x5C00UL) +#define CRS_BASE_S (APB1PERIPH_BASE_S + 0x6000UL) +#define USART6_BASE_S (APB1PERIPH_BASE_S + 0x6400UL) +#define USART10_BASE_S (APB1PERIPH_BASE_S + 0x6800UL) +#define USART11_BASE_S (APB1PERIPH_BASE_S + 0x6C00UL) +#define CEC_BASE_S (APB1PERIPH_BASE_S + 0x7000UL) +#define UART7_BASE_S (APB1PERIPH_BASE_S + 0x7800UL) +#define UART8_BASE_S (APB1PERIPH_BASE_S + 0x7C00UL) +#define UART9_BASE_S (APB1PERIPH_BASE_S + 0x8000UL) +#define UART12_BASE_S (APB1PERIPH_BASE_S + 0x8400UL) +#define DTS_BASE_S (APB1PERIPH_BASE_S + 0x8C00UL) +#define LPTIM2_BASE_S (APB1PERIPH_BASE_S + 0x9400UL) +#define FDCAN1_BASE_S (APB1PERIPH_BASE_S + 0xA400UL) +#define FDCAN_CONFIG_BASE_S (APB1PERIPH_BASE_S + 0xA500UL) +#define SRAMCAN_BASE_S (APB1PERIPH_BASE_S + 0xAC00UL) +#define UCPD1_BASE_S (APB1PERIPH_BASE_S + 0xDC00UL) + +/*!< APB2 Secure peripherals */ +#define TIM1_BASE_S (APB2PERIPH_BASE_S + 0x2C00UL) +#define SPI1_BASE_S (APB2PERIPH_BASE_S + 0x3000UL) +#define TIM8_BASE_S (APB2PERIPH_BASE_S + 0x3400UL) +#define USART1_BASE_S (APB2PERIPH_BASE_S + 0x3800UL) +#define TIM15_BASE_S (APB2PERIPH_BASE_S + 0x4000UL) +#define TIM16_BASE_S (APB2PERIPH_BASE_S + 0x4400UL) +#define TIM17_BASE_S (APB2PERIPH_BASE_S + 0x4800UL) +#define SPI4_BASE_S (APB2PERIPH_BASE_S + 0x4C00UL) +#define SPI6_BASE_S (APB2PERIPH_BASE_S + 0x5000UL) +#define SAI1_BASE_S (APB2PERIPH_BASE_S + 0x5400UL) +#define SAI1_Block_A_BASE_S (SAI1_BASE_S + 0x004UL) +#define SAI1_Block_B_BASE_S (SAI1_BASE_S + 0x024UL) +#define SAI2_BASE_S (APB2PERIPH_BASE_S + 0x5800UL) +#define SAI2_Block_A_BASE_S (SAI2_BASE_S + 0x004UL) +#define SAI2_Block_B_BASE_S (SAI2_BASE_S + 0x024UL) +#define USB_DRD_BASE_S (APB2PERIPH_BASE_S + 0x6000UL) +#define USB_DRD_PMAADDR_S (APB2PERIPH_BASE_S + 0x6400UL) + +/*!< AHB1 secure peripherals */ +#define GPDMA1_BASE_S AHB1PERIPH_BASE_S +#define GPDMA2_BASE_S (AHB1PERIPH_BASE_S + 0x01000UL) +#define FLASH_R_BASE_S (AHB1PERIPH_BASE_S + 0x02000UL) +#define CRC_BASE_S (AHB1PERIPH_BASE_S + 0x03000UL) +#define CORDIC_BASE_S (AHB1PERIPH_BASE_S + 0x03800UL) +#define FMAC_BASE_S (AHB1PERIPH_BASE_S + 0x03C00UL) +#define RAMCFG_BASE_S (AHB1PERIPH_BASE_S + 0x06000UL) +#define ICACHE_BASE_S (AHB1PERIPH_BASE_S + 0x10400UL) +#define DCACHE1_BASE_S (AHB1PERIPH_BASE_S + 0x11400UL) +#define GTZC_TZSC1_BASE_S (AHB1PERIPH_BASE_S + 0x12400UL) +#define GTZC_TZIC1_BASE_S (AHB1PERIPH_BASE_S + 0x12800UL) +#define GTZC_MPCBB1_BASE_S (AHB1PERIPH_BASE_S + 0x12C00UL) +#define GTZC_MPCBB2_BASE_S (AHB1PERIPH_BASE_S + 0x13000UL) +#define GTZC_MPCBB3_BASE_S (AHB1PERIPH_BASE_S + 0x13400UL) +#define BKPSRAM_BASE_S (AHB1PERIPH_BASE_S + 0x16400UL) + +#define GPDMA1_Channel0_BASE_S (GPDMA1_BASE_S + 0x0050UL) +#define GPDMA1_Channel1_BASE_S (GPDMA1_BASE_S + 0x00D0UL) +#define GPDMA1_Channel2_BASE_S (GPDMA1_BASE_S + 0x0150UL) +#define GPDMA1_Channel3_BASE_S (GPDMA1_BASE_S + 0x01D0UL) +#define GPDMA1_Channel4_BASE_S (GPDMA1_BASE_S + 0x0250UL) +#define GPDMA1_Channel5_BASE_S (GPDMA1_BASE_S + 0x02D0UL) +#define GPDMA1_Channel6_BASE_S (GPDMA1_BASE_S + 0x0350UL) +#define GPDMA1_Channel7_BASE_S (GPDMA1_BASE_S + 0x03D0UL) +#define GPDMA2_Channel0_BASE_S (GPDMA2_BASE_S + 0x0050UL) +#define GPDMA2_Channel1_BASE_S (GPDMA2_BASE_S + 0x00D0UL) +#define GPDMA2_Channel2_BASE_S (GPDMA2_BASE_S + 0x0150UL) +#define GPDMA2_Channel3_BASE_S (GPDMA2_BASE_S + 0x01D0UL) +#define GPDMA2_Channel4_BASE_S (GPDMA2_BASE_S + 0x0250UL) +#define GPDMA2_Channel5_BASE_S (GPDMA2_BASE_S + 0x02D0UL) +#define GPDMA2_Channel6_BASE_S (GPDMA2_BASE_S + 0x0350UL) +#define GPDMA2_Channel7_BASE_S (GPDMA2_BASE_S + 0x03D0UL) + +#define RAMCFG_SRAM1_BASE_S (RAMCFG_BASE_S) +#define RAMCFG_SRAM2_BASE_S (RAMCFG_BASE_S + 0x0040UL) +#define RAMCFG_SRAM3_BASE_S (RAMCFG_BASE_S + 0x0080UL) +#define RAMCFG_BKPRAM_BASE_S (RAMCFG_BASE_S + 0x0100UL) + +/*!< AHB2 secure peripherals */ +#define GPIOA_BASE_S (AHB2PERIPH_BASE_S + 0x00000UL) +#define GPIOB_BASE_S (AHB2PERIPH_BASE_S + 0x00400UL) +#define GPIOC_BASE_S (AHB2PERIPH_BASE_S + 0x00800UL) +#define GPIOD_BASE_S (AHB2PERIPH_BASE_S + 0x00C00UL) +#define GPIOE_BASE_S (AHB2PERIPH_BASE_S + 0x01000UL) +#define GPIOF_BASE_S (AHB2PERIPH_BASE_S + 0x01400UL) +#define GPIOG_BASE_S (AHB2PERIPH_BASE_S + 0x01800UL) +#define GPIOH_BASE_S (AHB2PERIPH_BASE_S + 0x01C00UL) +#define GPIOI_BASE_S (AHB2PERIPH_BASE_S + 0x02000UL) +#define ADC1_BASE_S (AHB2PERIPH_BASE_S + 0x08000UL) +#define ADC2_BASE_S (AHB2PERIPH_BASE_S + 0x08100UL) +#define ADC12_COMMON_BASE_S (AHB2PERIPH_BASE_S + 0x08300UL) +#define DAC1_BASE_S (AHB2PERIPH_BASE_S + 0x08400UL) +#define DCMI_BASE_S (AHB2PERIPH_BASE_S + 0x0C000UL) +#define PSSI_BASE_S (AHB2PERIPH_BASE_S + 0x0C400UL) +#define HASH_BASE_S (AHB2PERIPH_BASE_S + 0xA0400UL) +#define HASH_DIGEST_BASE_S (AHB2PERIPH_BASE_S + 0xA0710UL) +#define RNG_BASE_S (AHB2PERIPH_BASE_S + 0xA0800UL) + +/*!< APB3 secure peripherals */ +#define SBS_BASE_S (APB3PERIPH_BASE_S + 0x0400UL) +#define SPI5_BASE_S (APB3PERIPH_BASE_S + 0x2000UL) +#define LPUART1_BASE_S (APB3PERIPH_BASE_S + 0x2400UL) +#define I2C3_BASE_S (APB3PERIPH_BASE_S + 0x2800UL) +#define I2C4_BASE_S (APB3PERIPH_BASE_S + 0x2C00UL) +#define LPTIM1_BASE_S (APB3PERIPH_BASE_S + 0x4400UL) +#define LPTIM3_BASE_S (APB3PERIPH_BASE_S + 0x4800UL) +#define LPTIM4_BASE_S (APB3PERIPH_BASE_S + 0x4C00UL) +#define LPTIM5_BASE_S (APB3PERIPH_BASE_S + 0x5000UL) +#define LPTIM6_BASE_S (APB3PERIPH_BASE_S + 0x5400UL) +#define VREFBUF_BASE_S (APB3PERIPH_BASE_S + 0x7400UL) +#define RTC_BASE_S (APB3PERIPH_BASE_S + 0x7800UL) +#define TAMP_BASE_S (APB3PERIPH_BASE_S + 0x7C00UL) + +/*!< AHB3 secure peripherals */ +#define PWR_BASE_S (AHB3PERIPH_BASE_S + 0x0800UL) +#define RCC_BASE_S (AHB3PERIPH_BASE_S + 0x0C00UL) +#define EXTI_BASE_S (AHB3PERIPH_BASE_S + 0x2000UL) +#define DEBUG_BASE_S (AHB3PERIPH_BASE_S + 0x4000UL) + +/*!< AHB4 secure peripherals */ +#define SDMMC1_BASE_S (AHB4PERIPH_BASE_S + 0x8000UL) +#define DLYB_SDMMC1_BASE_S (AHB4PERIPH_BASE_S + 0x8400UL) + +#define FMC_R_BASE_S (AHB4PERIPH_BASE_S + 0x1000400UL) /*!< FMC control registers base address */ +#define OCTOSPI1_R_BASE_S (AHB4PERIPH_BASE_S + 0x1001400UL) /*!< OCTOSPI1 control registers base address */ +#define DLYB_OCTOSPI1_BASE_S (AHB4PERIPH_BASE_S + 0x0F000UL) + +/*!< FMC Banks Non secure registers base address */ +#define FMC_Bank1_R_BASE_S (FMC_R_BASE_S + 0x0000UL) +#define FMC_Bank1E_R_BASE_S (FMC_R_BASE_S + 0x0104UL) +#define FMC_Bank3_R_BASE_S (FMC_R_BASE_S + 0x0080UL) +#define FMC_Bank5_6_R_BASE_S (FMC_R_BASE_S + 0x0140UL) + +/* Debug MCU registers base address */ +#define DBGMCU_BASE (0x44024000UL) + +#define PACKAGE_BASE (0x08FFF80EUL) /*!< Package data register base address */ +#define UID_BASE (0x08FFF800UL) /*!< Unique device ID register base address */ +#define FLASHSIZE_BASE (0x08FFF80CUL) /*!< Flash size data register base address */ + + +/* Internal Flash OTP Area */ +#define FLASH_OTP_BASE (0x08FFF000UL) /*!< FLASH OTP (one-time programmable) base address */ +#define FLASH_OTP_SIZE (0x800U) /*!< 2048 bytes OTP (one-time programmable) */ + +/* Flash system Area */ +#define FLASH_SYSTEM_BASE_NS (0x0BF80000UL) /*!< FLASH System non-secure base address */ +#define FLASH_SYSTEM_BASE_S (0x0FF80000UL) /*!< FLASH System secure base address */ +#define FLASH_SYSTEM_SIZE (0x10000U) /*!< 64 Kbytes system Flash */ + +/* Internal Flash EDATA Area */ +#define FLASH_EDATA_BASE_NS (0x09000000UL) /*!< FLASH high-cycle data non-secure base address */ +#define FLASH_EDATA_BASE_S (0x0D000000UL) /*!< FLASH high-cycle data secure base address */ +#define FLASH_EDATA_SIZE (0x18000U) /*!< 96 KB of Flash high-cycle data */ + +/* Internal Flash OBK Area */ +#define FLASH_OBK_BASE_NS (0x0BFD0000UL) /*!< FLASH OBK (option byte keys) non-secure base address */ +#define FLASH_OBK_BASE_S (0x0FFD0000UL) /*!< FLASH OBK (option byte keys) secure base address */ +#define FLASH_OBK_SIZE (0x2000U) /*!< 8 KB of option byte keys */ +#define FLASH_OBK_HDPL0_SIZE (0x100U) /*!< 256 Bytes of HDPL1 option byte keys */ + +#define FLASH_OBK_HDPL1_BASE_NS (FLASH_OBK_BASE_NS + FLASH_OBK_HDPL0_SIZE) /*!< FLASH OBK HDPL1 non-secure base address */ +#define FLASH_OBK_HDPL1_BASE_S (FLASH_OBK_BASE_S + FLASH_OBK_HDPL0_SIZE) /*!< FLASH OBK HDPL1 secure base address */ +#define FLASH_OBK_HDPL1_SIZE (0x800U) /*!< 2 KB of HDPL1 option byte keys */ + +#define FLASH_OBK_HDPL2_BASE_NS (FLASH_OBK_HDPL1_BASE_NS + FLASH_OBK_HDPL1_SIZE) /*!< FLASH OBK HDPL2 non-secure base address */ +#define FLASH_OBK_HDPL2_BASE_S (FLASH_OBK_HDPL1_BASE_S + FLASH_OBK_HDPL1_SIZE) /*!< FLASH OBK HDPL2 secure base address */ +#define FLASH_OBK_HDPL2_SIZE (0x300U) /*!< 768 Bytes of HDPL2 option byte keys */ + +#define FLASH_OBK_HDPL3_BASE_NS (FLASH_OBK_HDPL2_BASE_NS + FLASH_OBK_HDPL2_SIZE) /*!< FLASH OBK HDPL3 non-secure base address */ +#define FLASH_OBK_HDPL3_BASE_S (FLASH_OBK_HDPL2_BASE_S + FLASH_OBK_HDPL2_SIZE) /*!< FLASH OBK HDPL3 secure base address */ +#define FLASH_OBK_HDPL3_SIZE (0x13F0U) /*!< 5104 Bytes HDPL3 option byte keys */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define FLASH_OBK_HDPL3S_BASE_NS (FLASH_OBK_HDPL3_BASE_NS) /*!< FLASH OBK HDPL3 non-secure base address */ +#define FLASH_OBK_HDPL3S_BASE_S (FLASH_OBK_HDPL3_BASE_S) /*!< FLASH OBK HDPL3 secure base address */ +#define FLASH_OBK_HDPL3S_SIZE (0x0C00U) /*!< 3072 Bytes of secure HDPL3 option byte keys */ + +#define FLASH_OBK_HDPL3NS_BASE_NS (FLASH_OBK_HDPL3_BASE_NS + FLASH_OBK_HDPL3S_SIZE) /*!< FLASH OBK HDPL3 non-secure base address */ +#define FLASH_OBK_HDPL3NS_BASE_S (FLASH_OBK_HDPL3_BASE_S + FLASH_OBK_HDPL3S_SIZE) /*!< FLASH OBK HDPL3 secure base address */ +#define FLASH_OBK_HDPL3NS_SIZE (FLASH_OBK_HDPL3_SIZE - FLASH_OBK_HDPL3S_SIZE) /*!< 2032 Bytes of non-secure HDPL3 option byte keys */ +#endif /* CMSE */ + +/*!< USB PMA SIZE */ +#define USB_DRD_PMA_SIZE (2048U) /*!< USB PMA Size 2Kbyte */ + +/*!< Root Secure Service Library */ +/************ RSSLIB SAU system Flash region definition constants *************/ +#define RSSLIB_SYS_FLASH_NS_PFUNC_START (0xBF9FB68UL) +#define RSSLIB_SYS_FLASH_NS_PFUNC_END (0xBF9FB84UL) + +/************ RSSLIB function return constants ********************************/ +#define RSSLIB_ERROR (0xF5F5F5F5UL) +#define RSSLIB_SUCCESS (0xEAEAEAEAUL) + +/*!< RSSLIB pointer function structure address definition */ +#define RSSLIB_PFUNC_BASE (0xBF9FB68UL) +#define RSSLIB_PFUNC ((RSSLIB_pFunc_TypeDef *)RSSLIB_PFUNC_BASE) + +/** + * @brief Prototype of RSSLIB Jump to HDP level2 Function + * @detail This function increments HDP level up to HDP level 2 + * Then it enables the MPU region corresponding the MPU index + * provided as input parameter. The Vector Table shall be located + * within this MPU region. + * Then it jumps to the reset handler present within the + * Vector table. The function does not return on successful execution. + * @param pointer on the vector table containing the reset handler the function + * jumps to. + * @param MPU region index containing the vector table + * jumps to. + * @retval RSSLIB_RSS_ERROR on error on input parameter, otherwise does not return. + */ +typedef uint32_t (*RSSLIB_S_JumpHDPlvl2_TypeDef)(uint32_t VectorTableAddr, uint32_t MPUIndex); + +/** + * @brief Prototype of RSSLIB Jump to HDP level3 Function + * @detail This function increments HDP level up to HDP level 3 + * Then it enables the MPU region corresponding the MPU index + * provided as input parameter. The Vector Table shall be located + * within this MPU region. + * Then it jumps to the reset handler present within the + * Vector table. The function does not return on successful execution. + * @param pointer on the vector table containing the reset handler the function + * jumps to. + * @param MPU region index containing the vector table + * jumps to. + * @retval RSSLIB_RSS_ERROR on error on input parameter, otherwise does not return. + */ +typedef uint32_t (*RSSLIB_S_JumpHDPlvl3_TypeDef)(uint32_t VectorTableAddr, uint32_t MPUIndex); + +/** + * @brief Prototype of RSSLIB Jump to HDP level3 Function + * @detail This function increments HDP level up to HDP level 3 + * Then it jumps to the non-secure reset handler present within the + * Vector table. The function does not return on successful execution. + * @param pointer on the vector table containing the reset handler the function + * jumps to. + * @retval RSSLIB_RSS_ERROR on error on input parameter, otherwise does not return. + */ +typedef uint32_t (*RSSLIB_S_JumpHDPlvl3NS_TypeDef)(uint32_t VectorTableAddr); + +/** + * @brief Input parameter definition of RSSLIB_DataProvisioning + */ +typedef struct +{ + uint32_t *pSource; /*!< Address of the Data to be provisioned, shall be in SRAM3 */ + uint32_t *pDestination; /*!< Address in OBKeys sections where to provision Data */ + uint32_t Size; /*!< Size in bytes of the Data to be provisioned*/ + uint32_t DoEncryption; /*!< Notifies RSSLIB_DataProvisioning to encrypt or not Data*/ + uint32_t Crc; /*!< CRC over full Data buffer and previous field in the structure*/ +} RSSLIB_DataProvisioningConf_t; + +/** + * @brief Prototype of RSSLIB Data Provisioning Function + * @detail This function write Data within OBKeys sections. + * @param pointer on the structure defining Data to be provisioned and where to + * provision them within OBKeys sections. + * @retval RSSLIB_RSS_ERROR on error on input parameter, otherwise does not return. + */ +typedef uint32_t (*RSSLIB_NSC_DataProvisioning_TypeDef)(RSSLIB_DataProvisioningConf_t *pConfig); + + +/** + * @brief RSSLib secure callable function pointer structure + */ +typedef struct +{ + __IM RSSLIB_S_JumpHDPlvl2_TypeDef JumpHDPLvl2; + __IM RSSLIB_S_JumpHDPlvl3_TypeDef JumpHDPLvl3; + __IM RSSLIB_S_JumpHDPlvl3NS_TypeDef JumpHDPLvl3NS; +} S_pFuncTypeDef; + +/** + * @brief RSSLib Non-secure callable function pointer structure + */ +typedef struct +{ + __IM RSSLIB_NSC_DataProvisioning_TypeDef DataProvisioning; +} NSC_pFuncTypeDef; + +/** + * @brief RSSLib function pointer structure + */ +typedef struct +{ + NSC_pFuncTypeDef NSC; + uint32_t RESERVED1[3]; + S_pFuncTypeDef S; +}RSSLIB_pFunc_TypeDef; + +/*!< Non Secure Service Library */ +/************ RSSLIB SAU system Flash region definition constants *************/ +#define NSSLIB_SYS_FLASH_NS_PFUNC_START (0xBF9FB6CUL) +#define NSSLIB_SYS_FLASH_NS_PFUNC_END (0xBF9FB74UL) + +/************ RSSLIB function return constants ********************************/ +#define NSSLIB_ERROR (0xF5F5F5F5UL) +#define NSSLIB_SUCCESS (0xEAEAEAEAUL) + +/*!< RSSLIB pointer function structure address definition */ +#define NSSLIB_PFUNC_BASE (0xBF9FB6CUL) +#define NSSLIB_PFUNC ((NSSLIB_pFunc_TypeDef *)NSSLIB_PFUNC_BASE) + +/** + * @brief Prototype of RSSLIB Jump to HDP level2 Function + * @detail This function increments HDP level up to HDP level 2 + * Then it enables the MPU region corresponding the MPU index + * provided as input parameter. The Vector Table shall be located + * within this MPU region. + * Then it jumps to the reset handler present within the + * Vector table. The function does not return on successful execution. + * @param pointer on the vector table containing the reset handler the function + * jumps to. + * @param MPU region index containing the vector table + * jumps to. + * @retval NSSLIB_RSS_ERROR on error on input parameter, otherwise does not return. + */ +typedef uint32_t (*NSSLIB_S_JumpHDPlvl2_TypeDef)(uint32_t VectorTableAddr, uint32_t MPUIndex); + +/** + * @brief Prototype of RSSLIB Jump to HDP level3 Function + * @detail This function increments HDP level up to HDP level 3 + * Then it enables the MPU region corresponding the MPU index + * provided as input parameter. The Vector Table shall be located + * within this MPU region. + * Then it jumps to the reset handler present within the + * Vector table. The function does not return on successful execution. + * @param pointer on the vector table containing the reset handler the function + * jumps to. + * @param MPU region index containing the vector table + * jumps to. + * @retval NSSLIB_RSS_ERROR on error on input parameter, otherwise does not return. + */ +typedef uint32_t (*NSSLIB_S_JumpHDPlvl3_TypeDef)(uint32_t VectorTableAddr, uint32_t MPUIndex); + +/** + * @brief RSSLib secure callable function pointer structure + */ +typedef struct +{ + __IM NSSLIB_S_JumpHDPlvl2_TypeDef JumpHDPLvl2; + __IM NSSLIB_S_JumpHDPlvl3_TypeDef JumpHDPLvl3; +} NSSLIB_pFunc_TypeDef; + + +/** @} */ /* End of group STM32H5xx_Peripheral_peripheralAddr */ + + +/* =========================================================================================================================== */ +/* ================ Peripheral declaration ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup STM32H5xx_Peripheral_declaration + * @{ + */ + +/*!< APB1 Non secure peripherals */ +#define TIM2_NS ((TIM_TypeDef *)TIM2_BASE_NS) +#define TIM3_NS ((TIM_TypeDef *)TIM3_BASE_NS) +#define TIM4_NS ((TIM_TypeDef *)TIM4_BASE_NS) +#define TIM5_NS ((TIM_TypeDef *)TIM5_BASE_NS) +#define TIM6_NS ((TIM_TypeDef *)TIM6_BASE_NS) +#define TIM7_NS ((TIM_TypeDef *)TIM7_BASE_NS) +#define TIM12_NS ((TIM_TypeDef *)TIM12_BASE_NS) +#define TIM13_NS ((TIM_TypeDef *)TIM13_BASE_NS) +#define TIM14_NS ((TIM_TypeDef *)TIM14_BASE_NS) +#define WWDG_NS ((WWDG_TypeDef *)WWDG_BASE_NS) +#define IWDG_NS ((IWDG_TypeDef *)IWDG_BASE_NS) +#define SPI2_NS ((SPI_TypeDef *)SPI2_BASE_NS) +#define SPI3_NS ((SPI_TypeDef *)SPI3_BASE_NS) +#define USART2_NS ((USART_TypeDef *)USART2_BASE_NS) +#define USART3_NS ((USART_TypeDef *)USART3_BASE_NS) +#define UART4_NS ((USART_TypeDef *)UART4_BASE_NS) +#define UART5_NS ((USART_TypeDef *)UART5_BASE_NS) +#define I2C1_NS ((I2C_TypeDef *)I2C1_BASE_NS) +#define I2C2_NS ((I2C_TypeDef *)I2C2_BASE_NS) +#define I3C1_NS ((I3C_TypeDef *)I3C1_BASE_NS) +#define CRS_NS ((CRS_TypeDef *)CRS_BASE_NS) +#define USART6_NS ((USART_TypeDef *)USART6_BASE_NS) +#define USART10_NS ((USART_TypeDef *)USART10_BASE_NS) +#define USART11_NS ((USART_TypeDef *)USART11_BASE_NS) +#define CEC_NS ((CEC_TypeDef *)CEC_BASE_NS) +#define UART7_NS ((USART_TypeDef *)UART7_BASE_NS) +#define UART8_NS ((USART_TypeDef *)UART8_BASE_NS) +#define UART9_NS ((USART_TypeDef *)UART9_BASE_NS) +#define UART12_NS ((USART_TypeDef *)UART12_BASE_NS) +#define DTS_NS ((DTS_TypeDef *)DTS_BASE_NS) +#define LPTIM2_NS ((LPTIM_TypeDef *)LPTIM2_BASE_NS) +#define FDCAN1_NS ((FDCAN_GlobalTypeDef *)FDCAN1_BASE_NS) +#define FDCAN_CONFIG_NS ((FDCAN_Config_TypeDef *)FDCAN_CONFIG_BASE_NS) +#define UCPD1_NS ((UCPD_TypeDef *)UCPD1_BASE_NS) + +/*!< APB2 Non secure peripherals */ +#define TIM1_NS ((TIM_TypeDef *) TIM1_BASE_NS) +#define SPI1_NS ((SPI_TypeDef *) SPI1_BASE_NS) +#define TIM8_NS ((TIM_TypeDef *) TIM8_BASE_NS) +#define USART1_NS ((USART_TypeDef *) USART1_BASE_NS) +#define TIM15_NS ((TIM_TypeDef *) TIM15_BASE_NS) +#define TIM16_NS ((TIM_TypeDef *) TIM16_BASE_NS) +#define TIM17_NS ((TIM_TypeDef *) TIM17_BASE_NS) +#define SPI4_NS ((SPI_TypeDef *) SPI4_BASE_NS) +#define SPI6_NS ((SPI_TypeDef *) SPI6_BASE_NS) +#define SAI1_NS ((SAI_TypeDef *) SAI1_BASE_NS) +#define SAI1_Block_A_NS ((SAI_Block_TypeDef *)SAI1_Block_A_BASE_NS) +#define SAI1_Block_B_NS ((SAI_Block_TypeDef *)SAI1_Block_B_BASE_NS) +#define SAI2_NS ((SAI_TypeDef *) SAI2_BASE_NS) +#define SAI2_Block_A_NS ((SAI_Block_TypeDef *)SAI2_Block_A_BASE_NS) +#define SAI2_Block_B_NS ((SAI_Block_TypeDef *)SAI2_Block_B_BASE_NS) +#define USB_DRD_FS_NS ((USB_DRD_TypeDef *) USB_DRD_BASE_NS) +#define USB_DRD_PMA_BUFF_NS ((USB_DRD_PMABuffDescTypeDef *) USB_DRD_PMAADDR_NS) + +/*!< AHB1 Non secure peripherals */ +#define GPDMA1_NS ((DMA_TypeDef *) GPDMA1_BASE_NS) +#define GPDMA2_NS ((DMA_TypeDef *) GPDMA2_BASE_NS) +#define FLASH_NS ((FLASH_TypeDef *) FLASH_R_BASE_NS) +#define CRC_NS ((CRC_TypeDef *) CRC_BASE_NS) +#define CORDIC_NS ((CORDIC_TypeDef *) CORDIC_BASE_NS) +#define FMAC_NS ((FMAC_TypeDef *) FMAC_BASE_NS) +#define RAMCFG_SRAM1_NS ((RAMCFG_TypeDef *) RAMCFG_SRAM1_BASE_NS) +#define RAMCFG_SRAM2_NS ((RAMCFG_TypeDef *) RAMCFG_SRAM2_BASE_NS) +#define RAMCFG_SRAM3_NS ((RAMCFG_TypeDef *) RAMCFG_SRAM3_BASE_NS) +#define RAMCFG_BKPRAM_NS ((RAMCFG_TypeDef *) RAMCFG_BKPRAM_BASE_NS) +#define ICACHE_NS ((ICACHE_TypeDef *) ICACHE_BASE_NS) +#define DCACHE1_NS ((DCACHE_TypeDef *) DCACHE1_BASE_NS) +#define GTZC_TZSC1_NS ((GTZC_TZSC_TypeDef *) GTZC_TZSC1_BASE_NS) +#define GTZC_TZIC1_NS ((GTZC_TZIC_TypeDef *) GTZC_TZIC1_BASE_NS) +#define GTZC_MPCBB1_NS ((GTZC_MPCBB_TypeDef *) GTZC_MPCBB1_BASE_NS) +#define GTZC_MPCBB2_NS ((GTZC_MPCBB_TypeDef *) GTZC_MPCBB2_BASE_NS) +#define GTZC_MPCBB3_NS ((GTZC_MPCBB_TypeDef *) GTZC_MPCBB3_BASE_NS) +#define GPDMA1_Channel0_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel0_BASE_NS) +#define GPDMA1_Channel1_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel1_BASE_NS) +#define GPDMA1_Channel2_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel2_BASE_NS) +#define GPDMA1_Channel3_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel3_BASE_NS) +#define GPDMA1_Channel4_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel4_BASE_NS) +#define GPDMA1_Channel5_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel5_BASE_NS) +#define GPDMA1_Channel6_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel6_BASE_NS) +#define GPDMA1_Channel7_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel7_BASE_NS) +#define GPDMA2_Channel0_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel0_BASE_NS) +#define GPDMA2_Channel1_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel1_BASE_NS) +#define GPDMA2_Channel2_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel2_BASE_NS) +#define GPDMA2_Channel3_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel3_BASE_NS) +#define GPDMA2_Channel4_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel4_BASE_NS) +#define GPDMA2_Channel5_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel5_BASE_NS) +#define GPDMA2_Channel6_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel6_BASE_NS) +#define GPDMA2_Channel7_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel7_BASE_NS) + +/*!< AHB2 Non secure peripherals */ +#define GPIOA_NS ((GPIO_TypeDef *) GPIOA_BASE_NS) +#define GPIOB_NS ((GPIO_TypeDef *) GPIOB_BASE_NS) +#define GPIOC_NS ((GPIO_TypeDef *) GPIOC_BASE_NS) +#define GPIOD_NS ((GPIO_TypeDef *) GPIOD_BASE_NS) +#define GPIOE_NS ((GPIO_TypeDef *) GPIOE_BASE_NS) +#define GPIOF_NS ((GPIO_TypeDef *) GPIOF_BASE_NS) +#define GPIOG_NS ((GPIO_TypeDef *) GPIOG_BASE_NS) +#define GPIOH_NS ((GPIO_TypeDef *) GPIOH_BASE_NS) +#define GPIOI_NS ((GPIO_TypeDef *) GPIOI_BASE_NS) +#define ADC1_NS ((ADC_TypeDef *) ADC1_BASE_NS) +#define ADC2_NS ((ADC_TypeDef *) ADC2_BASE_NS) +#define ADC12_COMMON_NS ((ADC_Common_TypeDef *) ADC12_COMMON_BASE_NS) +#define DAC1_NS ((DAC_TypeDef *) DAC1_BASE_NS) +#define DCMI_NS ((DCMI_TypeDef *) DCMI_BASE_NS) +#define PSSI_NS ((PSSI_TypeDef *) PSSI_BASE_NS) +#define HASH_NS ((HASH_TypeDef *) HASH_BASE_NS) +#define HASH_DIGEST_NS ((HASH_DIGEST_TypeDef *) HASH_DIGEST_BASE_NS) +#define RNG_NS ((RNG_TypeDef *) RNG_BASE_NS) + + +/*!< APB3 Non secure peripherals */ +#define SBS_NS ((SBS_TypeDef *) SBS_BASE_NS) +#define SPI5_NS ((SPI_TypeDef *) SPI5_BASE_NS) +#define LPUART1_NS ((USART_TypeDef *) LPUART1_BASE_NS) +#define I2C3_NS ((I2C_TypeDef *) I2C3_BASE_NS) +#define I2C4_NS ((I2C_TypeDef *) I2C4_BASE_NS) +#define LPTIM1_NS ((LPTIM_TypeDef *) LPTIM1_BASE_NS) +#define LPTIM3_NS ((LPTIM_TypeDef *) LPTIM3_BASE_NS) +#define LPTIM4_NS ((LPTIM_TypeDef *) LPTIM4_BASE_NS) +#define LPTIM5_NS ((LPTIM_TypeDef *) LPTIM5_BASE_NS) +#define LPTIM6_NS ((LPTIM_TypeDef *) LPTIM6_BASE_NS) +#define VREFBUF_NS ((VREFBUF_TypeDef *) VREFBUF_BASE_NS) +#define RTC_NS ((RTC_TypeDef *) RTC_BASE_NS) +#define TAMP_NS ((TAMP_TypeDef *) TAMP_BASE_NS) + +/*!< AHB3 Non secure peripherals */ +#define PWR_NS ((PWR_TypeDef *) PWR_BASE_NS) +#define RCC_NS ((RCC_TypeDef *) RCC_BASE_NS) +#define EXTI_NS ((EXTI_TypeDef *) EXTI_BASE_NS) + +/*!< AHB4 Non secure peripherals */ +#define SDMMC1_NS ((SDMMC_TypeDef *) SDMMC1_BASE_NS) +#define DLYB_SDMMC1_NS ((DLYB_TypeDef *) DLYB_SDMMC1_BASE_NS) + +#define OCTOSPI1_NS ((OCTOSPI_TypeDef *) OCTOSPI1_R_BASE_NS) +#define DLYB_OCTOSPI1_NS ((DLYB_TypeDef *) DLYB_OCTOSPI1_BASE_NS) + +/*!< FMC Banks Non secure registers base address */ +#define FMC_Bank1_R_NS ((FMC_Bank1_TypeDef *) FMC_Bank1_R_BASE_NS) +#define FMC_Bank1E_R_NS ((FMC_Bank1E_TypeDef *) FMC_Bank1E_R_BASE_NS) +#define FMC_Bank3_R_NS ((FMC_Bank3_TypeDef *) FMC_Bank3_R_BASE_NS) +#define FMC_Bank5_6_R_NS ((FMC_Bank5_6_TypeDef *) FMC_Bank5_6_R_BASE_NS) + +/*!< APB1 Secure peripherals */ +#define TIM2_S ((TIM_TypeDef *)TIM2_BASE_S) +#define TIM3_S ((TIM_TypeDef *)TIM3_BASE_S) +#define TIM4_S ((TIM_TypeDef *)TIM4_BASE_S) +#define TIM5_S ((TIM_TypeDef *)TIM5_BASE_S) +#define TIM6_S ((TIM_TypeDef *)TIM6_BASE_S) +#define TIM7_S ((TIM_TypeDef *)TIM7_BASE_S) +#define TIM12_S ((TIM_TypeDef *)TIM12_BASE_S) +#define TIM13_S ((TIM_TypeDef *)TIM13_BASE_S) +#define TIM14_S ((TIM_TypeDef *)TIM14_BASE_S) +#define WWDG_S ((WWDG_TypeDef *)WWDG_BASE_S) +#define IWDG_S ((IWDG_TypeDef *)IWDG_BASE_S) +#define SPI2_S ((SPI_TypeDef *)SPI2_BASE_S) +#define SPI3_S ((SPI_TypeDef *)SPI3_BASE_S) +#define USART2_S ((USART_TypeDef *)USART2_BASE_S) +#define USART3_S ((USART_TypeDef *)USART3_BASE_S) +#define UART4_S ((USART_TypeDef *)UART4_BASE_S) +#define UART5_S ((USART_TypeDef *)UART5_BASE_S) +#define I2C1_S ((I2C_TypeDef *)I2C1_BASE_S) +#define I2C2_S ((I2C_TypeDef *)I2C2_BASE_S) +#define I3C1_S ((I3C_TypeDef *)I3C1_BASE_S) +#define CRS_S ((CRS_TypeDef *)CRS_BASE_S) +#define USART6_S ((USART_TypeDef *)USART6_BASE_S) +#define USART10_S ((USART_TypeDef *)USART10_BASE_S) +#define USART11_S ((USART_TypeDef *)USART11_BASE_S) +#define CEC_S ((CEC_TypeDef *)CEC_BASE_S) +#define UART7_S ((USART_TypeDef *)UART7_BASE_S) +#define UART8_S ((USART_TypeDef *)UART8_BASE_S) +#define UART9_S ((USART_TypeDef *)UART9_BASE_S) +#define UART12_S ((USART_TypeDef *)UART12_BASE_S) +#define DTS_S ((DTS_TypeDef *)DTS_BASE_S) +#define LPTIM2_S ((LPTIM_TypeDef *)LPTIM2_BASE_S) +#define FDCAN1_S ((FDCAN_GlobalTypeDef *)FDCAN1_BASE_S) +#define FDCAN_CONFIG_S ((FDCAN_Config_TypeDef *)FDCAN_CONFIG_BASE_S) +#define UCPD1_S ((UCPD_TypeDef *)UCPD1_BASE_S) + +/*!< APB2 secure peripherals */ +#define TIM1_S ((TIM_TypeDef *) TIM1_BASE_S) +#define SPI1_S ((SPI_TypeDef *) SPI1_BASE_S) +#define TIM8_S ((TIM_TypeDef *) TIM8_BASE_S) +#define USART1_S ((USART_TypeDef *) USART1_BASE_S) +#define TIM15_S ((TIM_TypeDef *) TIM15_BASE_S) +#define TIM16_S ((TIM_TypeDef *) TIM16_BASE_S) +#define TIM17_S ((TIM_TypeDef *) TIM17_BASE_S) +#define SPI4_S ((SPI_TypeDef *) SPI4_BASE_S) +#define SPI6_S ((SPI_TypeDef *) SPI6_BASE_S) +#define SAI1_S ((SAI_TypeDef *) SAI1_BASE_S) +#define SAI1_Block_A_S ((SAI_Block_TypeDef *)SAI1_Block_A_BASE_S) +#define SAI1_Block_B_S ((SAI_Block_TypeDef *)SAI1_Block_B_BASE_S) +#define SAI2_S ((SAI_TypeDef *) SAI2_BASE_S) +#define SAI2_Block_A_S ((SAI_Block_TypeDef *)SAI2_Block_A_BASE_S) +#define SAI2_Block_B_S ((SAI_Block_TypeDef *)SAI2_Block_B_BASE_S) +#define USB_DRD_FS_S ((USB_DRD_TypeDef *)USB_DRD_BASE_S) +#define USB_DRD_PMA_BUFF_S ((USB_DRD_PMABuffDescTypeDef *) USB_DRD_PMAADDR_S) + +/*!< AHB1 secure peripherals */ +#define GPDMA1_S ((DMA_TypeDef *) GPDMA1_BASE_S) +#define GPDMA2_S ((DMA_TypeDef *) GPDMA2_BASE_S) +#define FLASH_S ((FLASH_TypeDef *) FLASH_R_BASE_S) +#define CRC_S ((CRC_TypeDef *) CRC_BASE_S) +#define CORDIC_S ((CORDIC_TypeDef *) CORDIC_BASE_S) +#define FMAC_S ((FMAC_TypeDef *) FMAC_BASE_S) +#define RAMCFG_SRAM1_S ((RAMCFG_TypeDef *) RAMCFG_SRAM1_BASE_S) +#define RAMCFG_SRAM2_S ((RAMCFG_TypeDef *) RAMCFG_SRAM2_BASE_S) +#define RAMCFG_SRAM3_S ((RAMCFG_TypeDef *) RAMCFG_SRAM3_BASE_S) +#define RAMCFG_BKPRAM_S ((RAMCFG_TypeDef *) RAMCFG_BKPRAM_BASE_S) +#define ICACHE_S ((ICACHE_TypeDef *) ICACHE_BASE_S) +#define DCACHE1_S ((DCACHE_TypeDef *) DCACHE1_BASE_S) +#define GTZC_TZSC1_S ((GTZC_TZSC_TypeDef *) GTZC_TZSC1_BASE_S) +#define GTZC_TZIC1_S ((GTZC_TZIC_TypeDef *) GTZC_TZIC1_BASE_S) +#define GTZC_MPCBB1_S ((GTZC_MPCBB_TypeDef *) GTZC_MPCBB1_BASE_S) +#define GTZC_MPCBB2_S ((GTZC_MPCBB_TypeDef *) GTZC_MPCBB2_BASE_S) +#define GTZC_MPCBB3_S ((GTZC_MPCBB_TypeDef *) GTZC_MPCBB3_BASE_S) +#define GPDMA1_Channel0_S ((DMA_Channel_TypeDef *) GPDMA1_Channel0_BASE_S) +#define GPDMA1_Channel1_S ((DMA_Channel_TypeDef *) GPDMA1_Channel1_BASE_S) +#define GPDMA1_Channel2_S ((DMA_Channel_TypeDef *) GPDMA1_Channel2_BASE_S) +#define GPDMA1_Channel3_S ((DMA_Channel_TypeDef *) GPDMA1_Channel3_BASE_S) +#define GPDMA1_Channel4_S ((DMA_Channel_TypeDef *) GPDMA1_Channel4_BASE_S) +#define GPDMA1_Channel5_S ((DMA_Channel_TypeDef *) GPDMA1_Channel5_BASE_S) +#define GPDMA1_Channel6_S ((DMA_Channel_TypeDef *) GPDMA1_Channel6_BASE_S) +#define GPDMA1_Channel7_S ((DMA_Channel_TypeDef *) GPDMA1_Channel7_BASE_S) +#define GPDMA2_Channel0_S ((DMA_Channel_TypeDef *) GPDMA2_Channel0_BASE_S) +#define GPDMA2_Channel1_S ((DMA_Channel_TypeDef *) GPDMA2_Channel1_BASE_S) +#define GPDMA2_Channel2_S ((DMA_Channel_TypeDef *) GPDMA2_Channel2_BASE_S) +#define GPDMA2_Channel3_S ((DMA_Channel_TypeDef *) GPDMA2_Channel3_BASE_S) +#define GPDMA2_Channel4_S ((DMA_Channel_TypeDef *) GPDMA2_Channel4_BASE_S) +#define GPDMA2_Channel5_S ((DMA_Channel_TypeDef *) GPDMA2_Channel5_BASE_S) +#define GPDMA2_Channel6_S ((DMA_Channel_TypeDef *) GPDMA2_Channel6_BASE_S) +#define GPDMA2_Channel7_S ((DMA_Channel_TypeDef *) GPDMA2_Channel7_BASE_S) + + +/*!< AHB2 secure peripherals */ +#define GPIOA_S ((GPIO_TypeDef *) GPIOA_BASE_S) +#define GPIOB_S ((GPIO_TypeDef *) GPIOB_BASE_S) +#define GPIOC_S ((GPIO_TypeDef *) GPIOC_BASE_S) +#define GPIOD_S ((GPIO_TypeDef *) GPIOD_BASE_S) +#define GPIOE_S ((GPIO_TypeDef *) GPIOE_BASE_S) +#define GPIOF_S ((GPIO_TypeDef *) GPIOF_BASE_S) +#define GPIOG_S ((GPIO_TypeDef *) GPIOG_BASE_S) +#define GPIOH_S ((GPIO_TypeDef *) GPIOH_BASE_S) +#define GPIOI_S ((GPIO_TypeDef *) GPIOI_BASE_S) +#define ADC1_S ((ADC_TypeDef *) ADC1_BASE_S) +#define ADC2_S ((ADC_TypeDef *) ADC2_BASE_S) +#define ADC12_COMMON_S ((ADC_Common_TypeDef *) ADC12_COMMON_BASE_S) +#define DAC1_S ((DAC_TypeDef *) DAC1_BASE_S) +#define DCMI_S ((DCMI_TypeDef *) DCMI_BASE_S) +#define PSSI_S ((PSSI_TypeDef *) PSSI_BASE_S) +#define HASH_S ((HASH_TypeDef *) HASH_BASE_S) +#define HASH_DIGEST_S ((HASH_DIGEST_TypeDef *) HASH_DIGEST_BASE_S) +#define RNG_S ((RNG_TypeDef *) RNG_BASE_S) + +/*!< APB3 secure peripherals */ +#define SBS_S ((SBS_TypeDef *) SBS_BASE_S) +#define SPI5_S ((SPI_TypeDef *) SPI5_BASE_S) +#define LPUART1_S ((USART_TypeDef *) LPUART1_BASE_S) +#define I2C3_S ((I2C_TypeDef *) I2C3_BASE_S) +#define I2C4_S ((I2C_TypeDef *) I2C4_BASE_S) +#define LPTIM1_S ((LPTIM_TypeDef *) LPTIM1_BASE_S) +#define LPTIM3_S ((LPTIM_TypeDef *) LPTIM3_BASE_S) +#define LPTIM4_S ((LPTIM_TypeDef *) LPTIM4_BASE_S) +#define LPTIM5_S ((LPTIM_TypeDef *) LPTIM5_BASE_S) +#define LPTIM6_S ((LPTIM_TypeDef *) LPTIM6_BASE_S) +#define VREFBUF_S ((VREFBUF_TypeDef *) VREFBUF_BASE_S) +#define RTC_S ((RTC_TypeDef *) RTC_BASE_S) +#define TAMP_S ((TAMP_TypeDef *) TAMP_BASE_S) + +/*!< AHB3 Secure peripherals */ +#define PWR_S ((PWR_TypeDef *) PWR_BASE_S) +#define RCC_S ((RCC_TypeDef *) RCC_BASE_S) +#define EXTI_S ((EXTI_TypeDef *) EXTI_BASE_S) + +/*!< AHB4 secure peripherals */ +#define SDMMC1_S ((SDMMC_TypeDef *) SDMMC1_BASE_S) +#define DLYB_SDMMC1_S ((DLYB_TypeDef *) DLYB_SDMMC1_BASE_S) + +#define FMC_Bank1_R_S ((FMC_Bank1_TypeDef *) FMC_Bank1_R_BASE_S) +#define FMC_Bank1E_R_S ((FMC_Bank1E_TypeDef *) FMC_Bank1E_R_BASE_S) +#define FMC_Bank3_R_S ((FMC_Bank3_TypeDef *) FMC_Bank3_R_BASE_S) +#define FMC_Bank5_6_R_S ((FMC_Bank5_6_TypeDef *) FMC_Bank5_6_R_BASE_S) + +#define OCTOSPI1_S ((OCTOSPI_TypeDef *) OCTOSPI1_R_BASE_S) +#define DLYB_OCTOSPI1_S ((DLYB_TypeDef *) DLYB_OCTOSPI1_BASE_S) + +#define DBGMCU ((DBGMCU_TypeDef *) DBGMCU_BASE) + +/*!< Memory & Instance aliases and base addresses for Non-Secure/Secure peripherals */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/*!< Memory base addresses for Secure peripherals */ +#define FLASH_BASE FLASH_BASE_S +#define FLASH_OBK_BASE FLASH_OBK_BASE_S +#define FLASH_EDATA_BASE FLASH_EDATA_BASE_S +#define FLASH_SYSTEM_BASE FLASH_SYSTEM_BASE_S +#define SRAM1_BASE SRAM1_BASE_S +#define SRAM2_BASE SRAM2_BASE_S +#define SRAM3_BASE SRAM3_BASE_S +#define BKPSRAM_BASE BKPSRAM_BASE_S +#define PERIPH_BASE PERIPH_BASE_S +#define APB1PERIPH_BASE APB1PERIPH_BASE_S +#define APB2PERIPH_BASE APB2PERIPH_BASE_S +#define APB3PERIPH_BASE APB3PERIPH_BASE_S +#define AHB1PERIPH_BASE AHB1PERIPH_BASE_S +#define AHB2PERIPH_BASE AHB2PERIPH_BASE_S +#define AHB3PERIPH_BASE AHB3PERIPH_BASE_S +#define AHB4PERIPH_BASE AHB4PERIPH_BASE_S + +/*!< Instance aliases and base addresses for Secure peripherals */ +#define CORDIC CORDIC_S +#define CORDIC_BASE CORDIC_BASE_S + +#define RCC RCC_S +#define RCC_BASE RCC_BASE_S + +#define DCMI DCMI_S +#define DCMI_BASE DCMI_BASE_S + +#define PSSI PSSI_S +#define PSSI_BASE PSSI_BASE_S + +#define DTS DTS_S +#define DTS_BASE DTS_BASE_S + +#define FLASH FLASH_S +#define FLASH_R_BASE FLASH_R_BASE_S + +#define FMAC FMAC_S +#define FMAC_BASE FMAC_BASE_S + +#define GPDMA1 GPDMA1_S +#define GPDMA1_BASE GPDMA1_BASE_S + +#define GPDMA1_Channel0 GPDMA1_Channel0_S +#define GPDMA1_Channel0_BASE GPDMA1_Channel0_BASE_S + +#define GPDMA1_Channel1 GPDMA1_Channel1_S +#define GPDMA1_Channel1_BASE GPDMA1_Channel1_BASE_S + +#define GPDMA1_Channel2 GPDMA1_Channel2_S +#define GPDMA1_Channel2_BASE GPDMA1_Channel2_BASE_S + +#define GPDMA1_Channel3 GPDMA1_Channel3_S +#define GPDMA1_Channel3_BASE GPDMA1_Channel3_BASE_S + +#define GPDMA1_Channel4 GPDMA1_Channel4_S +#define GPDMA1_Channel4_BASE GPDMA1_Channel4_BASE_S + +#define GPDMA1_Channel5 GPDMA1_Channel5_S +#define GPDMA1_Channel5_BASE GPDMA1_Channel5_BASE_S + +#define GPDMA1_Channel6 GPDMA1_Channel6_S +#define GPDMA1_Channel6_BASE GPDMA1_Channel6_BASE_S + +#define GPDMA1_Channel7 GPDMA1_Channel7_S +#define GPDMA1_Channel7_BASE GPDMA1_Channel7_BASE_S + +#define GPDMA2 GPDMA2_S +#define GPDMA2_BASE GPDMA2_BASE_S + +#define GPDMA2_Channel0 GPDMA2_Channel0_S +#define GPDMA2_Channel0_BASE GPDMA2_Channel0_BASE_S + +#define GPDMA2_Channel1 GPDMA2_Channel1_S +#define GPDMA2_Channel1_BASE GPDMA2_Channel1_BASE_S + +#define GPDMA2_Channel2 GPDMA2_Channel2_S +#define GPDMA2_Channel2_BASE GPDMA2_Channel2_BASE_S + +#define GPDMA2_Channel3 GPDMA2_Channel3_S +#define GPDMA2_Channel3_BASE GPDMA2_Channel3_BASE_S + +#define GPDMA2_Channel4 GPDMA2_Channel4_S +#define GPDMA2_Channel4_BASE GPDMA2_Channel4_BASE_S + +#define GPDMA2_Channel5 GPDMA2_Channel5_S +#define GPDMA2_Channel5_BASE GPDMA2_Channel5_BASE_S + +#define GPDMA2_Channel6 GPDMA2_Channel6_S +#define GPDMA2_Channel6_BASE GPDMA2_Channel6_BASE_S + +#define GPDMA2_Channel7 GPDMA2_Channel7_S +#define GPDMA2_Channel7_BASE GPDMA2_Channel7_BASE_S + +#define GPIOA GPIOA_S +#define GPIOA_BASE GPIOA_BASE_S + +#define GPIOB GPIOB_S +#define GPIOB_BASE GPIOB_BASE_S + +#define GPIOC GPIOC_S +#define GPIOC_BASE GPIOC_BASE_S + +#define GPIOD GPIOD_S +#define GPIOD_BASE GPIOD_BASE_S + +#define GPIOE GPIOE_S +#define GPIOE_BASE GPIOE_BASE_S + +#define GPIOF GPIOF_S +#define GPIOF_BASE GPIOF_BASE_S + +#define GPIOG GPIOG_S +#define GPIOG_BASE GPIOG_BASE_S + +#define GPIOH GPIOH_S +#define GPIOH_BASE GPIOH_BASE_S + +#define GPIOI GPIOI_S +#define GPIOI_BASE GPIOI_BASE_S + +#define PWR PWR_S +#define PWR_BASE PWR_BASE_S + +#define RAMCFG_SRAM1 RAMCFG_SRAM1_S +#define RAMCFG_SRAM1_BASE RAMCFG_SRAM1_BASE_S + +#define RAMCFG_SRAM2 RAMCFG_SRAM2_S +#define RAMCFG_SRAM2_BASE RAMCFG_SRAM2_BASE_S + +#define RAMCFG_SRAM3 RAMCFG_SRAM3_S +#define RAMCFG_SRAM3_BASE RAMCFG_SRAM3_BASE_S + +#define RAMCFG_BKPRAM RAMCFG_BKPRAM_S +#define RAMCFG_BKPRAM_BASE RAMCFG_BKPRAM_BASE_S + +#define EXTI EXTI_S +#define EXTI_BASE EXTI_BASE_S + +#define ICACHE ICACHE_S +#define ICACHE_BASE ICACHE_BASE_S + +#define DCACHE1 DCACHE1_S +#define DCACHE1_BASE DCACHE1_BASE_S + +#define GTZC_TZSC1 GTZC_TZSC1_S +#define GTZC_TZSC1_BASE GTZC_TZSC1_BASE_S + +#define GTZC_TZIC1 GTZC_TZIC1_S +#define GTZC_TZIC1_BASE GTZC_TZIC1_BASE_S + +#define GTZC_MPCBB1 GTZC_MPCBB1_S +#define GTZC_MPCBB1_BASE GTZC_MPCBB1_BASE_S + +#define GTZC_MPCBB2 GTZC_MPCBB2_S +#define GTZC_MPCBB2_BASE GTZC_MPCBB2_BASE_S + +#define GTZC_MPCBB3 GTZC_MPCBB3_S +#define GTZC_MPCBB3_BASE GTZC_MPCBB3_BASE_S + +#define RTC RTC_S +#define RTC_BASE RTC_BASE_S + +#define TAMP TAMP_S +#define TAMP_BASE TAMP_BASE_S + +#define TIM1 TIM1_S +#define TIM1_BASE TIM1_BASE_S + +#define TIM2 TIM2_S +#define TIM2_BASE TIM2_BASE_S + +#define TIM3 TIM3_S +#define TIM3_BASE TIM3_BASE_S + +#define TIM4 TIM4_S +#define TIM4_BASE TIM4_BASE_S + +#define TIM5 TIM5_S +#define TIM5_BASE TIM5_BASE_S + +#define TIM6 TIM6_S +#define TIM6_BASE TIM6_BASE_S + +#define TIM7 TIM7_S +#define TIM7_BASE TIM7_BASE_S + +#define TIM8 TIM8_S +#define TIM8_BASE TIM8_BASE_S + +#define TIM15 TIM15_S +#define TIM15_BASE TIM15_BASE_S + +#define TIM12 TIM12_S +#define TIM12_BASE TIM12_BASE_S + +#define TIM13 TIM13_S +#define TIM13_BASE TIM13_BASE_S + +#define TIM14 TIM14_S +#define TIM14_BASE TIM14_BASE_S + +#define TIM16 TIM16_S +#define TIM16_BASE TIM16_BASE_S + +#define TIM17 TIM17_S +#define TIM17_BASE TIM17_BASE_S + +#define WWDG WWDG_S +#define WWDG_BASE WWDG_BASE_S + +#define IWDG IWDG_S +#define IWDG_BASE IWDG_BASE_S + +#define SPI1 SPI1_S +#define SPI1_BASE SPI1_BASE_S + +#define SPI2 SPI2_S +#define SPI2_BASE SPI2_BASE_S + +#define SPI3 SPI3_S +#define SPI3_BASE SPI3_BASE_S + +#define SPI4 SPI4_S +#define SPI4_BASE SPI4_BASE_S + +#define SPI5 SPI5_S +#define SPI5_BASE SPI5_BASE_S + +#define SPI6 SPI6_S +#define SPI6_BASE SPI6_BASE_S + +#define USART1 USART1_S +#define USART1_BASE USART1_BASE_S + +#define USART2 USART2_S +#define USART2_BASE USART2_BASE_S + +#define USART3 USART3_S +#define USART3_BASE USART3_BASE_S + +#define UART4 UART4_S +#define UART4_BASE UART4_BASE_S + +#define UART5 UART5_S +#define UART5_BASE UART5_BASE_S + +#define USART6 USART6_S +#define USART6_BASE USART6_BASE_S + +#define UART7 UART7_S +#define UART7_BASE UART7_BASE_S + +#define UART8 UART8_S +#define UART8_BASE UART8_BASE_S + +#define UART9 UART9_S +#define UART9_BASE UART9_BASE_S + +#define USART10 USART10_S +#define USART10_BASE USART10_BASE_S + +#define USART11 USART11_S +#define USART11_BASE USART11_BASE_S + +#define UART12 UART12_S +#define UART12_BASE UART12_BASE_S + +#define CEC CEC_S +#define CEC_BASE CEC_BASE_S + +#define I2C1 I2C1_S +#define I2C1_BASE I2C1_BASE_S + +#define I2C2 I2C2_S +#define I2C2_BASE I2C2_BASE_S + +#define I2C3 I2C3_S +#define I2C3_BASE I2C3_BASE_S + +#define I2C4 I2C4_S +#define I2C4_BASE I2C4_BASE_S + +#define I3C1 I3C1_S +#define I3C1_BASE I3C1_BASE_S + +#define CRS CRS_S +#define CRS_BASE CRS_BASE_S + +#define FDCAN1 FDCAN1_S +#define FDCAN1_BASE FDCAN1_BASE_S + +#define FDCAN_CONFIG FDCAN_CONFIG_S +#define FDCAN_CONFIG_BASE FDCAN_CONFIG_BASE_S +#define SRAMCAN_BASE SRAMCAN_BASE_S + + +#define DAC1 DAC1_S +#define DAC1_BASE DAC1_BASE_S + +#define LPTIM1 LPTIM1_S +#define LPTIM1_BASE LPTIM1_BASE_S + +#define LPTIM2 LPTIM2_S +#define LPTIM2_BASE LPTIM2_BASE_S + +#define LPTIM3 LPTIM3_S +#define LPTIM3_BASE LPTIM3_BASE_S + +#define LPTIM4 LPTIM4_S +#define LPTIM4_BASE LPTIM4_BASE_S + +#define LPTIM5 LPTIM5_S +#define LPTIM5_BASE LPTIM5_BASE_S + +#define LPTIM6 LPTIM6_S +#define LPTIM6_BASE LPTIM6_BASE_S + +#define LPUART1 LPUART1_S +#define LPUART1_BASE LPUART1_BASE_S + +#define UCPD1 UCPD1_S +#define UCPD1_BASE UCPD1_BASE_S + +#define SBS SBS_S +#define SBS_BASE SBS_BASE_S + +#define VREFBUF VREFBUF_S +#define VREFBUF_BASE VREFBUF_BASE_S + +#define SAI1 SAI1_S +#define SAI1_BASE SAI1_BASE_S + +#define SAI1_Block_A SAI1_Block_A_S +#define SAI1_Block_A_BASE SAI1_Block_A_BASE_S + +#define SAI1_Block_B SAI1_Block_B_S +#define SAI1_Block_B_BASE SAI1_Block_B_BASE_S + +#define SAI2 SAI2_S +#define SAI2_BASE SAI2_BASE_S + +#define SAI2_Block_A SAI2_Block_A_S +#define SAI2_Block_A_BASE SAI2_Block_A_BASE_S + +#define SAI2_Block_B SAI2_Block_B_S +#define SAI2_Block_B_BASE SAI2_Block_B_BASE_S + +#define USB_DRD_FS USB_DRD_FS_S +#define USB_DRD_BASE USB_DRD_BASE_S +#define USB_DRD_PMAADDR USB_DRD_PMAADDR_S +#define USB_DRD_PMA_BUFF USB_DRD_PMA_BUFF_S + +#define CRC CRC_S +#define CRC_BASE CRC_BASE_S + +#define ADC1 ADC1_S +#define ADC1_BASE ADC1_BASE_S + +#define ADC2 ADC2_S +#define ADC2_BASE ADC2_BASE_S + +#define ADC12_COMMON ADC12_COMMON_S +#define ADC12_COMMON_BASE ADC12_COMMON_BASE_S + +#define HASH HASH_S +#define HASH_BASE HASH_BASE_S + +#define HASH_DIGEST HASH_DIGEST_S +#define HASH_DIGEST_BASE HASH_DIGEST_BASE_S + +#define RNG RNG_S +#define RNG_BASE RNG_BASE_S + + + +#define SDMMC1 SDMMC1_S +#define SDMMC1_BASE SDMMC1_BASE_S + + +#define FMC_Bank1_R FMC_Bank1_R_S +#define FMC_Bank1_R_BASE FMC_Bank1_R_BASE_S + +#define FMC_Bank1E_R FMC_Bank1E_R_S +#define FMC_Bank1E_R_BASE FMC_Bank1E_R_BASE_S + +#define FMC_Bank3_R FMC_Bank3_R_S +#define FMC_Bank3_R_BASE FMC_Bank3_R_BASE_S + +#define FMC_Bank5_6_R FMC_Bank5_6_R_S +#define FMC_Bank5_6_R_BASE FMC_Bank5_6_R_BASE_S + +#define OCTOSPI1 OCTOSPI1_S +#define OCTOSPI1_R_BASE OCTOSPI1_R_BASE_S + +#define DLYB_SDMMC1 DLYB_SDMMC1_S +#define DLYB_SDMMC1_BASE DLYB_SDMMC1_BASE_S + +#define DLYB_OCTOSPI1 DLYB_OCTOSPI1_S +#define DLYB_OCTOSPI1_BASE DLYB_OCTOSPI1_BASE_S + +#else + +/*!< Memory base addresses for Non secure peripherals */ +#define FLASH_BASE FLASH_BASE_NS +#define FLASH_OBK_BASE FLASH_OBK_BASE_NS +#define FLASH_EDATA_BASE FLASH_EDATA_BASE_NS +#define FLASH_SYSTEM_BASE FLASH_SYSTEM_BASE_NS + +#define SRAM1_BASE SRAM1_BASE_NS +#define SRAM2_BASE SRAM2_BASE_NS + +#define SRAM3_BASE SRAM3_BASE_NS +#define BKPSRAM_BASE BKPSRAM_BASE_NS + +#define PERIPH_BASE PERIPH_BASE_NS +#define APB1PERIPH_BASE APB1PERIPH_BASE_NS +#define APB2PERIPH_BASE APB2PERIPH_BASE_NS +#define APB3PERIPH_BASE APB3PERIPH_BASE_NS +#define AHB1PERIPH_BASE AHB1PERIPH_BASE_NS +#define AHB2PERIPH_BASE AHB2PERIPH_BASE_NS +#define AHB3PERIPH_BASE AHB3PERIPH_BASE_NS +#define AHB4PERIPH_BASE AHB4PERIPH_BASE_NS + +/*!< Instance aliases and base addresses for Non secure peripherals */ +#define CORDIC CORDIC_NS +#define CORDIC_BASE CORDIC_BASE_NS + +#define RCC RCC_NS +#define RCC_BASE RCC_BASE_NS + +#define DCMI DCMI_NS +#define DCMI_BASE DCMI_BASE_NS + +#define PSSI PSSI_NS +#define PSSI_BASE PSSI_BASE_NS + +#define DTS DTS_NS +#define DTS_BASE DTS_BASE_NS + +#define FLASH FLASH_NS +#define FLASH_R_BASE FLASH_R_BASE_NS + +#define FMAC FMAC_NS +#define FMAC_BASE FMAC_BASE_NS + +#define GPDMA1 GPDMA1_NS +#define GPDMA1_BASE GPDMA1_BASE_NS + +#define GPDMA1_Channel0 GPDMA1_Channel0_NS +#define GPDMA1_Channel0_BASE GPDMA1_Channel0_BASE_NS + +#define GPDMA1_Channel1 GPDMA1_Channel1_NS +#define GPDMA1_Channel1_BASE GPDMA1_Channel1_BASE_NS + +#define GPDMA1_Channel2 GPDMA1_Channel2_NS +#define GPDMA1_Channel2_BASE GPDMA1_Channel2_BASE_NS + +#define GPDMA1_Channel3 GPDMA1_Channel3_NS +#define GPDMA1_Channel3_BASE GPDMA1_Channel3_BASE_NS + +#define GPDMA1_Channel4 GPDMA1_Channel4_NS +#define GPDMA1_Channel4_BASE GPDMA1_Channel4_BASE_NS + +#define GPDMA1_Channel5 GPDMA1_Channel5_NS +#define GPDMA1_Channel5_BASE GPDMA1_Channel5_BASE_NS + +#define GPDMA1_Channel6 GPDMA1_Channel6_NS +#define GPDMA1_Channel6_BASE GPDMA1_Channel6_BASE_NS + +#define GPDMA1_Channel7 GPDMA1_Channel7_NS +#define GPDMA1_Channel7_BASE GPDMA1_Channel7_BASE_NS + +#define GPDMA2 GPDMA2_NS +#define GPDMA2_BASE GPDMA2_BASE_NS + +#define GPDMA2_Channel0 GPDMA2_Channel0_NS +#define GPDMA2_Channel0_BASE GPDMA2_Channel0_BASE_NS + +#define GPDMA2_Channel1 GPDMA2_Channel1_NS +#define GPDMA2_Channel1_BASE GPDMA2_Channel1_BASE_NS + +#define GPDMA2_Channel2 GPDMA2_Channel2_NS +#define GPDMA2_Channel2_BASE GPDMA2_Channel2_BASE_NS + +#define GPDMA2_Channel3 GPDMA2_Channel3_NS +#define GPDMA2_Channel3_BASE GPDMA2_Channel3_BASE_NS + +#define GPDMA2_Channel4 GPDMA2_Channel4_NS +#define GPDMA2_Channel4_BASE GPDMA2_Channel4_BASE_NS + +#define GPDMA2_Channel5 GPDMA2_Channel5_NS +#define GPDMA2_Channel5_BASE GPDMA2_Channel5_BASE_NS + +#define GPDMA2_Channel6 GPDMA2_Channel6_NS +#define GPDMA2_Channel6_BASE GPDMA2_Channel6_BASE_NS + +#define GPDMA2_Channel7 GPDMA2_Channel7_NS +#define GPDMA2_Channel7_BASE GPDMA2_Channel7_BASE_NS + +#define GPIOA GPIOA_NS +#define GPIOA_BASE GPIOA_BASE_NS + +#define GPIOB GPIOB_NS +#define GPIOB_BASE GPIOB_BASE_NS + +#define GPIOC GPIOC_NS +#define GPIOC_BASE GPIOC_BASE_NS + +#define GPIOD GPIOD_NS +#define GPIOD_BASE GPIOD_BASE_NS + +#define GPIOE GPIOE_NS +#define GPIOE_BASE GPIOE_BASE_NS + +#define GPIOF GPIOF_NS +#define GPIOF_BASE GPIOF_BASE_NS + +#define GPIOG GPIOG_NS +#define GPIOG_BASE GPIOG_BASE_NS + +#define GPIOH GPIOH_NS +#define GPIOH_BASE GPIOH_BASE_NS + +#define GPIOI GPIOI_NS +#define GPIOI_BASE GPIOI_BASE_NS + +#define PWR PWR_NS +#define PWR_BASE PWR_BASE_NS + +#define RAMCFG_SRAM1 RAMCFG_SRAM1_NS +#define RAMCFG_SRAM1_BASE RAMCFG_SRAM1_BASE_NS + +#define RAMCFG_SRAM2 RAMCFG_SRAM2_NS +#define RAMCFG_SRAM2_BASE RAMCFG_SRAM2_BASE_NS + +#define RAMCFG_SRAM3 RAMCFG_SRAM3_NS +#define RAMCFG_SRAM3_BASE RAMCFG_SRAM3_BASE_NS + +#define RAMCFG_BKPRAM RAMCFG_BKPRAM_NS +#define RAMCFG_BKPRAM_BASE RAMCFG_BKPRAM_BASE_NS + +#define EXTI EXTI_NS +#define EXTI_BASE EXTI_BASE_NS + +#define ICACHE ICACHE_NS +#define ICACHE_BASE ICACHE_BASE_NS + +#define DCACHE1 DCACHE1_NS +#define DCACHE1_BASE DCACHE1_BASE_NS + +#define GTZC_TZSC1 GTZC_TZSC1_NS +#define GTZC_TZSC1_BASE GTZC_TZSC1_BASE_NS + +#define GTZC_TZIC1 GTZC_TZIC1_NS +#define GTZC_TZIC1_BASE GTZC_TZIC1_BASE_NS + +#define GTZC_MPCBB1 GTZC_MPCBB1_NS +#define GTZC_MPCBB1_BASE GTZC_MPCBB1_BASE_NS + +#define GTZC_MPCBB2 GTZC_MPCBB2_NS +#define GTZC_MPCBB2_BASE GTZC_MPCBB2_BASE_NS + +#define GTZC_MPCBB3 GTZC_MPCBB3_NS +#define GTZC_MPCBB3_BASE GTZC_MPCBB3_BASE_NS + +#define RTC RTC_NS +#define RTC_BASE RTC_BASE_NS + +#define TAMP TAMP_NS +#define TAMP_BASE TAMP_BASE_NS + +#define TIM1 TIM1_NS +#define TIM1_BASE TIM1_BASE_NS + +#define TIM2 TIM2_NS +#define TIM2_BASE TIM2_BASE_NS + +#define TIM3 TIM3_NS +#define TIM3_BASE TIM3_BASE_NS + +#define TIM4 TIM4_NS +#define TIM4_BASE TIM4_BASE_NS + +#define TIM5 TIM5_NS +#define TIM5_BASE TIM5_BASE_NS + +#define TIM6 TIM6_NS +#define TIM6_BASE TIM6_BASE_NS + +#define TIM7 TIM7_NS +#define TIM7_BASE TIM7_BASE_NS + +#define TIM8 TIM8_NS +#define TIM8_BASE TIM8_BASE_NS + +#define TIM12 TIM12_NS +#define TIM12_BASE TIM12_BASE_NS + +#define TIM13 TIM13_NS +#define TIM13_BASE TIM13_BASE_NS + +#define TIM14 TIM14_NS +#define TIM14_BASE TIM14_BASE_NS + +#define TIM15 TIM15_NS +#define TIM15_BASE TIM15_BASE_NS + +#define TIM16 TIM16_NS +#define TIM16_BASE TIM16_BASE_NS + +#define TIM17 TIM17_NS +#define TIM17_BASE TIM17_BASE_NS + +#define WWDG WWDG_NS +#define WWDG_BASE WWDG_BASE_NS + +#define IWDG IWDG_NS +#define IWDG_BASE IWDG_BASE_NS + +#define SPI1 SPI1_NS +#define SPI1_BASE SPI1_BASE_NS + +#define SPI2 SPI2_NS +#define SPI2_BASE SPI2_BASE_NS + +#define SPI3 SPI3_NS +#define SPI3_BASE SPI3_BASE_NS + +#define SPI4 SPI4_NS +#define SPI4_BASE SPI4_BASE_NS + +#define SPI5 SPI5_NS +#define SPI5_BASE SPI5_BASE_NS + +#define SPI6 SPI6_NS +#define SPI6_BASE SPI6_BASE_NS + +#define USART1 USART1_NS +#define USART1_BASE USART1_BASE_NS + +#define USART2 USART2_NS +#define USART2_BASE USART2_BASE_NS + +#define USART3 USART3_NS +#define USART3_BASE USART3_BASE_NS + +#define UART4 UART4_NS +#define UART4_BASE UART4_BASE_NS + +#define UART5 UART5_NS +#define UART5_BASE UART5_BASE_NS + +#define USART6 USART6_NS +#define USART6_BASE USART6_BASE_NS + +#define UART7 UART7_NS +#define UART7_BASE UART7_BASE_NS + +#define UART8 UART8_NS +#define UART8_BASE UART8_BASE_NS + +#define UART9 UART9_NS +#define UART9_BASE UART9_BASE_NS + +#define USART10 USART10_NS +#define USART10_BASE USART10_BASE_NS + +#define USART11 USART11_NS +#define USART11_BASE USART11_BASE_NS + +#define UART12 UART12_NS +#define UART12_BASE UART12_BASE_NS + +#define CEC CEC_NS +#define CEC_BASE CEC_BASE_NS + +#define I2C1 I2C1_NS +#define I2C1_BASE I2C1_BASE_NS + +#define I2C2 I2C2_NS +#define I2C2_BASE I2C2_BASE_NS + +#define I2C3 I2C3_NS +#define I2C3_BASE I2C3_BASE_NS + +#define I2C4 I2C4_NS +#define I2C4_BASE I2C4_BASE_NS + +#define I3C1 I3C1_NS +#define I3C1_BASE I3C1_BASE_NS + +#define CRS CRS_NS +#define CRS_BASE CRS_BASE_NS + +#define FDCAN1 FDCAN1_NS +#define FDCAN1_BASE FDCAN1_BASE_NS + +#define FDCAN_CONFIG FDCAN_CONFIG_NS +#define FDCAN_CONFIG_BASE FDCAN_CONFIG_BASE_NS +#define SRAMCAN_BASE SRAMCAN_BASE_NS + + +#define DAC1 DAC1_NS +#define DAC1_BASE DAC1_BASE_NS + +#define LPTIM1 LPTIM1_NS +#define LPTIM1_BASE LPTIM1_BASE_NS + +#define LPTIM2 LPTIM2_NS +#define LPTIM2_BASE LPTIM2_BASE_NS + +#define LPTIM3 LPTIM3_NS +#define LPTIM3_BASE LPTIM3_BASE_NS + +#define LPTIM4 LPTIM4_NS +#define LPTIM4_BASE LPTIM4_BASE_NS + +#define LPTIM5 LPTIM5_NS +#define LPTIM5_BASE LPTIM5_BASE_NS + +#define LPTIM6 LPTIM6_NS +#define LPTIM6_BASE LPTIM6_BASE_NS + +#define LPUART1 LPUART1_NS +#define LPUART1_BASE LPUART1_BASE_NS + +#define UCPD1 UCPD1_NS +#define UCPD1_BASE UCPD1_BASE_NS + +#define SBS SBS_NS +#define SBS_BASE SBS_BASE_NS + +#define VREFBUF VREFBUF_NS +#define VREFBUF_BASE VREFBUF_BASE_NS + +#define SAI1 SAI1_NS +#define SAI1_BASE SAI1_BASE_NS + +#define SAI1_Block_A SAI1_Block_A_NS +#define SAI1_Block_A_BASE SAI1_Block_A_BASE_NS + +#define SAI1_Block_B SAI1_Block_B_NS +#define SAI1_Block_B_BASE SAI1_Block_B_BASE_NS + +#define SAI2 SAI2_NS +#define SAI2_BASE SAI2_BASE_NS + +#define SAI2_Block_A SAI2_Block_A_NS +#define SAI2_Block_A_BASE SAI2_Block_A_BASE_NS + +#define SAI2_Block_B SAI2_Block_B_NS +#define SAI2_Block_B_BASE SAI2_Block_B_BASE_NS + +#define USB_DRD_FS USB_DRD_FS_NS +#define USB_DRD_BASE USB_DRD_BASE_NS +#define USB_DRD_PMAADDR USB_DRD_PMAADDR_NS +#define USB_DRD_PMA_BUFF USB_DRD_PMA_BUFF_NS + +#define CRC CRC_NS +#define CRC_BASE CRC_BASE_NS + +#define ADC1 ADC1_NS +#define ADC1_BASE ADC1_BASE_NS + +#define ADC2 ADC2_NS +#define ADC2_BASE ADC2_BASE_NS + +#define ADC12_COMMON ADC12_COMMON_NS +#define ADC12_COMMON_BASE ADC12_COMMON_BASE_NS + +#define HASH HASH_NS +#define HASH_BASE HASH_BASE_NS + +#define HASH_DIGEST HASH_DIGEST_NS +#define HASH_DIGEST_BASE HASH_DIGEST_BASE_NS + +#define RNG RNG_NS +#define RNG_BASE RNG_BASE_NS + + + +#define SDMMC1 SDMMC1_NS +#define SDMMC1_BASE SDMMC1_BASE_NS + + +#define FMC_Bank1_R FMC_Bank1_R_NS +#define FMC_Bank1_R_BASE FMC_Bank1_R_BASE_NS + +#define FMC_Bank1E_R FMC_Bank1E_R_NS +#define FMC_Bank1E_R_BASE FMC_Bank1E_R_BASE_NS + +#define FMC_Bank3_R FMC_Bank3_R_NS +#define FMC_Bank3_R_BASE FMC_Bank3_R_BASE_NS + +#define FMC_Bank5_6_R FMC_Bank5_6_R_NS +#define FMC_Bank5_6_R_BASE FMC_Bank5_6_R_BASE_NS + +#define OCTOSPI1 OCTOSPI1_NS +#define OCTOSPI1_R_BASE OCTOSPI1_R_BASE_NS + +#define DLYB_SDMMC1 DLYB_SDMMC1_NS +#define DLYB_SDMMC1_BASE DLYB_SDMMC1_BASE_NS + +#define DLYB_OCTOSPI1 DLYB_OCTOSPI1_NS +#define DLYB_OCTOSPI1_BASE DLYB_OCTOSPI1_BASE_NS + +#endif + + +/******************************************************************************/ +/* */ +/* Analog to Digital Converter */ +/* */ +/******************************************************************************/ +#define ADC_MULTIMODE_SUPPORT /*!< ADC feature available only on specific devices: multimode available on devices with several ADC instances */ +/******************** Bit definition for ADC_ISR register *******************/ +#define ADC_ISR_ADRDY_Pos (0U) +#define ADC_ISR_ADRDY_Msk (0x1UL << ADC_ISR_ADRDY_Pos) /*!< 0x00000001 */ +#define ADC_ISR_ADRDY ADC_ISR_ADRDY_Msk /*!< ADC ready flag */ +#define ADC_ISR_EOSMP_Pos (1U) +#define ADC_ISR_EOSMP_Msk (0x1UL << ADC_ISR_EOSMP_Pos) /*!< 0x00000002 */ +#define ADC_ISR_EOSMP ADC_ISR_EOSMP_Msk /*!< ADC group regular end of sampling flag */ +#define ADC_ISR_EOC_Pos (2U) +#define ADC_ISR_EOC_Msk (0x1UL << ADC_ISR_EOC_Pos) /*!< 0x00000004 */ +#define ADC_ISR_EOC ADC_ISR_EOC_Msk /*!< ADC group regular end of unitary conversion flag */ +#define ADC_ISR_EOS_Pos (3U) +#define ADC_ISR_EOS_Msk (0x1UL << ADC_ISR_EOS_Pos) /*!< 0x00000008 */ +#define ADC_ISR_EOS ADC_ISR_EOS_Msk /*!< ADC group regular end of sequence conversions flag */ +#define ADC_ISR_OVR_Pos (4U) +#define ADC_ISR_OVR_Msk (0x1UL << ADC_ISR_OVR_Pos) /*!< 0x00000010 */ +#define ADC_ISR_OVR ADC_ISR_OVR_Msk /*!< ADC group regular overrun flag */ +#define ADC_ISR_JEOC_Pos (5U) +#define ADC_ISR_JEOC_Msk (0x1UL << ADC_ISR_JEOC_Pos) /*!< 0x00000020 */ +#define ADC_ISR_JEOC ADC_ISR_JEOC_Msk /*!< ADC group injected end of unitary conversion flag */ +#define ADC_ISR_JEOS_Pos (6U) +#define ADC_ISR_JEOS_Msk (0x1UL << ADC_ISR_JEOS_Pos) /*!< 0x00000040 */ +#define ADC_ISR_JEOS ADC_ISR_JEOS_Msk /*!< ADC group injected end of sequence conversions flag */ +#define ADC_ISR_AWD1_Pos (7U) +#define ADC_ISR_AWD1_Msk (0x1UL << ADC_ISR_AWD1_Pos) /*!< 0x00000080 */ +#define ADC_ISR_AWD1 ADC_ISR_AWD1_Msk /*!< ADC analog watchdog 1 flag */ +#define ADC_ISR_AWD2_Pos (8U) +#define ADC_ISR_AWD2_Msk (0x1UL << ADC_ISR_AWD2_Pos) /*!< 0x00000100 */ +#define ADC_ISR_AWD2 ADC_ISR_AWD2_Msk /*!< ADC analog watchdog 2 flag */ +#define ADC_ISR_AWD3_Pos (9U) +#define ADC_ISR_AWD3_Msk (0x1UL << ADC_ISR_AWD3_Pos) /*!< 0x00000200 */ +#define ADC_ISR_AWD3 ADC_ISR_AWD3_Msk /*!< ADC analog watchdog 3 flag */ +#define ADC_ISR_JQOVF_Pos (10U) +#define ADC_ISR_JQOVF_Msk (0x1UL << ADC_ISR_JQOVF_Pos) /*!< 0x00000400 */ +#define ADC_ISR_JQOVF ADC_ISR_JQOVF_Msk /*!< ADC group injected contexts queue overflow flag */ + +/******************** Bit definition for ADC_IER register *******************/ +#define ADC_IER_ADRDYIE_Pos (0U) +#define ADC_IER_ADRDYIE_Msk (0x1UL << ADC_IER_ADRDYIE_Pos) /*!< 0x00000001 */ +#define ADC_IER_ADRDYIE ADC_IER_ADRDYIE_Msk /*!< ADC ready interrupt */ +#define ADC_IER_EOSMPIE_Pos (1U) +#define ADC_IER_EOSMPIE_Msk (0x1UL << ADC_IER_EOSMPIE_Pos) /*!< 0x00000002 */ +#define ADC_IER_EOSMPIE ADC_IER_EOSMPIE_Msk /*!< ADC group regular end of sampling interrupt */ +#define ADC_IER_EOCIE_Pos (2U) +#define ADC_IER_EOCIE_Msk (0x1UL << ADC_IER_EOCIE_Pos) /*!< 0x00000004 */ +#define ADC_IER_EOCIE ADC_IER_EOCIE_Msk /*!< ADC group regular end of unitary conversion interrupt */ +#define ADC_IER_EOSIE_Pos (3U) +#define ADC_IER_EOSIE_Msk (0x1UL << ADC_IER_EOSIE_Pos) /*!< 0x00000008 */ +#define ADC_IER_EOSIE ADC_IER_EOSIE_Msk /*!< ADC group regular end of sequence conversions interrupt */ +#define ADC_IER_OVRIE_Pos (4U) +#define ADC_IER_OVRIE_Msk (0x1UL << ADC_IER_OVRIE_Pos) /*!< 0x00000010 */ +#define ADC_IER_OVRIE ADC_IER_OVRIE_Msk /*!< ADC group regular overrun interrupt */ +#define ADC_IER_JEOCIE_Pos (5U) +#define ADC_IER_JEOCIE_Msk (0x1UL << ADC_IER_JEOCIE_Pos) /*!< 0x00000020 */ +#define ADC_IER_JEOCIE ADC_IER_JEOCIE_Msk /*!< ADC group injected end of unitary conversion interrupt */ +#define ADC_IER_JEOSIE_Pos (6U) +#define ADC_IER_JEOSIE_Msk (0x1UL << ADC_IER_JEOSIE_Pos) /*!< 0x00000040 */ +#define ADC_IER_JEOSIE ADC_IER_JEOSIE_Msk /*!< ADC group injected end of sequence conversions interrupt */ +#define ADC_IER_AWD1IE_Pos (7U) +#define ADC_IER_AWD1IE_Msk (0x1UL << ADC_IER_AWD1IE_Pos) /*!< 0x00000080 */ +#define ADC_IER_AWD1IE ADC_IER_AWD1IE_Msk /*!< ADC analog watchdog 1 interrupt */ +#define ADC_IER_AWD2IE_Pos (8U) +#define ADC_IER_AWD2IE_Msk (0x1UL << ADC_IER_AWD2IE_Pos) /*!< 0x00000100 */ +#define ADC_IER_AWD2IE ADC_IER_AWD2IE_Msk /*!< ADC analog watchdog 2 interrupt */ +#define ADC_IER_AWD3IE_Pos (9U) +#define ADC_IER_AWD3IE_Msk (0x1UL << ADC_IER_AWD3IE_Pos) /*!< 0x00000200 */ +#define ADC_IER_AWD3IE ADC_IER_AWD3IE_Msk /*!< ADC analog watchdog 3 interrupt */ +#define ADC_IER_JQOVFIE_Pos (10U) +#define ADC_IER_JQOVFIE_Msk (0x1UL << ADC_IER_JQOVFIE_Pos) /*!< 0x00000400 */ +#define ADC_IER_JQOVFIE ADC_IER_JQOVFIE_Msk /*!< ADC group injected contexts queue overflow interrupt */ + +/******************** Bit definition for ADC_CR register ********************/ +#define ADC_CR_ADEN_Pos (0U) +#define ADC_CR_ADEN_Msk (0x1UL << ADC_CR_ADEN_Pos) /*!< 0x00000001 */ +#define ADC_CR_ADEN ADC_CR_ADEN_Msk /*!< ADC enable */ +#define ADC_CR_ADDIS_Pos (1U) +#define ADC_CR_ADDIS_Msk (0x1UL << ADC_CR_ADDIS_Pos) /*!< 0x00000002 */ +#define ADC_CR_ADDIS ADC_CR_ADDIS_Msk /*!< ADC disable */ +#define ADC_CR_ADSTART_Pos (2U) +#define ADC_CR_ADSTART_Msk (0x1UL << ADC_CR_ADSTART_Pos) /*!< 0x00000004 */ +#define ADC_CR_ADSTART ADC_CR_ADSTART_Msk /*!< ADC group regular conversion start */ +#define ADC_CR_JADSTART_Pos (3U) +#define ADC_CR_JADSTART_Msk (0x1UL << ADC_CR_JADSTART_Pos) /*!< 0x00000008 */ +#define ADC_CR_JADSTART ADC_CR_JADSTART_Msk /*!< ADC group injected conversion start */ +#define ADC_CR_ADSTP_Pos (4U) +#define ADC_CR_ADSTP_Msk (0x1UL << ADC_CR_ADSTP_Pos) /*!< 0x00000010 */ +#define ADC_CR_ADSTP ADC_CR_ADSTP_Msk /*!< ADC group regular conversion stop */ +#define ADC_CR_JADSTP_Pos (5U) +#define ADC_CR_JADSTP_Msk (0x1UL << ADC_CR_JADSTP_Pos) /*!< 0x00000020 */ +#define ADC_CR_JADSTP ADC_CR_JADSTP_Msk /*!< ADC group injected conversion stop */ +#define ADC_CR_ADVREGEN_Pos (28U) +#define ADC_CR_ADVREGEN_Msk (0x1UL << ADC_CR_ADVREGEN_Pos) /*!< 0x10000000 */ +#define ADC_CR_ADVREGEN ADC_CR_ADVREGEN_Msk /*!< ADC voltage regulator enable */ +#define ADC_CR_DEEPPWD_Pos (29U) +#define ADC_CR_DEEPPWD_Msk (0x1UL << ADC_CR_DEEPPWD_Pos) /*!< 0x20000000 */ +#define ADC_CR_DEEPPWD ADC_CR_DEEPPWD_Msk /*!< ADC deep power down enable */ +#define ADC_CR_ADCALDIF_Pos (30U) +#define ADC_CR_ADCALDIF_Msk (0x1UL << ADC_CR_ADCALDIF_Pos) /*!< 0x40000000 */ +#define ADC_CR_ADCALDIF ADC_CR_ADCALDIF_Msk /*!< ADC differential mode for calibration */ +#define ADC_CR_ADCAL_Pos (31U) +#define ADC_CR_ADCAL_Msk (0x1UL << ADC_CR_ADCAL_Pos) /*!< 0x80000000 */ +#define ADC_CR_ADCAL ADC_CR_ADCAL_Msk /*!< ADC calibration */ + +/******************** Bit definition for ADC_CFGR register ******************/ +#define ADC_CFGR_DMAEN_Pos (0U) +#define ADC_CFGR_DMAEN_Msk (0x1UL << ADC_CFGR_DMAEN_Pos) /*!< 0x00000001 */ +#define ADC_CFGR_DMAEN ADC_CFGR_DMAEN_Msk /*!< ADC DMA transfer enable */ +#define ADC_CFGR_DMACFG_Pos (1U) +#define ADC_CFGR_DMACFG_Msk (0x1UL << ADC_CFGR_DMACFG_Pos) /*!< 0x00000002 */ +#define ADC_CFGR_DMACFG ADC_CFGR_DMACFG_Msk /*!< ADC DMA transfer configuration */ + +#define ADC_CFGR_RES_Pos (3U) +#define ADC_CFGR_RES_Msk (0x3UL << ADC_CFGR_RES_Pos) /*!< 0x00000018 */ +#define ADC_CFGR_RES ADC_CFGR_RES_Msk /*!< ADC data resolution */ +#define ADC_CFGR_RES_0 (0x1UL << ADC_CFGR_RES_Pos) /*!< 0x00000008 */ +#define ADC_CFGR_RES_1 (0x2UL << ADC_CFGR_RES_Pos) /*!< 0x00000010 */ + +#define ADC_CFGR_EXTSEL_Pos (5U) +#define ADC_CFGR_EXTSEL_Msk (0x1FUL << ADC_CFGR_EXTSEL_Pos) /*!< 0x000003E0 */ +#define ADC_CFGR_EXTSEL ADC_CFGR_EXTSEL_Msk /*!< ADC group regular external trigger source */ +#define ADC_CFGR_EXTSEL_0 (0x1UL << ADC_CFGR_EXTSEL_Pos) /*!< 0x00000020 */ +#define ADC_CFGR_EXTSEL_1 (0x2UL << ADC_CFGR_EXTSEL_Pos) /*!< 0x00000040 */ +#define ADC_CFGR_EXTSEL_2 (0x4UL << ADC_CFGR_EXTSEL_Pos) /*!< 0x00000080 */ +#define ADC_CFGR_EXTSEL_3 (0x8UL << ADC_CFGR_EXTSEL_Pos) /*!< 0x00000100 */ +#define ADC_CFGR_EXTSEL_4 (0x10UL << ADC_CFGR_EXTSEL_Pos) /*!< 0x00000200 */ + +#define ADC_CFGR_EXTEN_Pos (10U) +#define ADC_CFGR_EXTEN_Msk (0x3UL << ADC_CFGR_EXTEN_Pos) /*!< 0x00000C00 */ +#define ADC_CFGR_EXTEN ADC_CFGR_EXTEN_Msk /*!< ADC group regular external trigger polarity */ +#define ADC_CFGR_EXTEN_0 (0x1UL << ADC_CFGR_EXTEN_Pos) /*!< 0x00000400 */ +#define ADC_CFGR_EXTEN_1 (0x2UL << ADC_CFGR_EXTEN_Pos) /*!< 0x00000800 */ + +#define ADC_CFGR_OVRMOD_Pos (12U) +#define ADC_CFGR_OVRMOD_Msk (0x1UL << ADC_CFGR_OVRMOD_Pos) /*!< 0x00001000 */ +#define ADC_CFGR_OVRMOD ADC_CFGR_OVRMOD_Msk /*!< ADC group regular overrun configuration */ +#define ADC_CFGR_CONT_Pos (13U) +#define ADC_CFGR_CONT_Msk (0x1UL << ADC_CFGR_CONT_Pos) /*!< 0x00002000 */ +#define ADC_CFGR_CONT ADC_CFGR_CONT_Msk /*!< ADC group regular continuous conversion mode */ +#define ADC_CFGR_AUTDLY_Pos (14U) +#define ADC_CFGR_AUTDLY_Msk (0x1UL << ADC_CFGR_AUTDLY_Pos) /*!< 0x00004000 */ +#define ADC_CFGR_AUTDLY ADC_CFGR_AUTDLY_Msk /*!< ADC low power auto wait */ +#define ADC_CFGR_ALIGN_Pos (15U) +#define ADC_CFGR_ALIGN_Msk (0x1UL << ADC_CFGR_ALIGN_Pos) /*!< 0x00008000 */ +#define ADC_CFGR_ALIGN ADC_CFGR_ALIGN_Msk /*!< ADC data alignment */ +#define ADC_CFGR_DISCEN_Pos (16U) +#define ADC_CFGR_DISCEN_Msk (0x1UL << ADC_CFGR_DISCEN_Pos) /*!< 0x00010000 */ +#define ADC_CFGR_DISCEN ADC_CFGR_DISCEN_Msk /*!< ADC group regular sequencer discontinuous mode */ + +#define ADC_CFGR_DISCNUM_Pos (17U) +#define ADC_CFGR_DISCNUM_Msk (0x7UL << ADC_CFGR_DISCNUM_Pos) /*!< 0x000E0000 */ +#define ADC_CFGR_DISCNUM ADC_CFGR_DISCNUM_Msk /*!< ADC group regular sequencer discontinuous number of ranks */ +#define ADC_CFGR_DISCNUM_0 (0x1UL << ADC_CFGR_DISCNUM_Pos) /*!< 0x00020000 */ +#define ADC_CFGR_DISCNUM_1 (0x2UL << ADC_CFGR_DISCNUM_Pos) /*!< 0x00040000 */ +#define ADC_CFGR_DISCNUM_2 (0x4UL << ADC_CFGR_DISCNUM_Pos) /*!< 0x00080000 */ + +#define ADC_CFGR_JDISCEN_Pos (20U) +#define ADC_CFGR_JDISCEN_Msk (0x1UL << ADC_CFGR_JDISCEN_Pos) /*!< 0x00100000 */ +#define ADC_CFGR_JDISCEN ADC_CFGR_JDISCEN_Msk /*!< ADC group injected sequencer discontinuous mode */ +#define ADC_CFGR_JQM_Pos (21U) +#define ADC_CFGR_JQM_Msk (0x1UL << ADC_CFGR_JQM_Pos) /*!< 0x00200000 */ +#define ADC_CFGR_JQM ADC_CFGR_JQM_Msk /*!< ADC group injected contexts queue mode */ +#define ADC_CFGR_AWD1SGL_Pos (22U) +#define ADC_CFGR_AWD1SGL_Msk (0x1UL << ADC_CFGR_AWD1SGL_Pos) /*!< 0x00400000 */ +#define ADC_CFGR_AWD1SGL ADC_CFGR_AWD1SGL_Msk /*!< ADC analog watchdog 1 monitoring a single channel or all channels */ +#define ADC_CFGR_AWD1EN_Pos (23U) +#define ADC_CFGR_AWD1EN_Msk (0x1UL << ADC_CFGR_AWD1EN_Pos) /*!< 0x00800000 */ +#define ADC_CFGR_AWD1EN ADC_CFGR_AWD1EN_Msk /*!< ADC analog watchdog 1 enable on scope ADC group regular */ +#define ADC_CFGR_JAWD1EN_Pos (24U) +#define ADC_CFGR_JAWD1EN_Msk (0x1UL << ADC_CFGR_JAWD1EN_Pos) /*!< 0x01000000 */ +#define ADC_CFGR_JAWD1EN ADC_CFGR_JAWD1EN_Msk /*!< ADC analog watchdog 1 enable on scope ADC group injected */ +#define ADC_CFGR_JAUTO_Pos (25U) +#define ADC_CFGR_JAUTO_Msk (0x1UL << ADC_CFGR_JAUTO_Pos) /*!< 0x02000000 */ +#define ADC_CFGR_JAUTO ADC_CFGR_JAUTO_Msk /*!< ADC group injected automatic trigger mode */ + +#define ADC_CFGR_AWD1CH_Pos (26U) +#define ADC_CFGR_AWD1CH_Msk (0x1FUL << ADC_CFGR_AWD1CH_Pos) /*!< 0x7C000000 */ +#define ADC_CFGR_AWD1CH ADC_CFGR_AWD1CH_Msk /*!< ADC analog watchdog 1 monitored channel selection */ +#define ADC_CFGR_AWD1CH_0 (0x01UL << ADC_CFGR_AWD1CH_Pos) /*!< 0x04000000 */ +#define ADC_CFGR_AWD1CH_1 (0x02UL << ADC_CFGR_AWD1CH_Pos) /*!< 0x08000000 */ +#define ADC_CFGR_AWD1CH_2 (0x04UL << ADC_CFGR_AWD1CH_Pos) /*!< 0x10000000 */ +#define ADC_CFGR_AWD1CH_3 (0x08UL << ADC_CFGR_AWD1CH_Pos) /*!< 0x20000000 */ +#define ADC_CFGR_AWD1CH_4 (0x10UL << ADC_CFGR_AWD1CH_Pos) /*!< 0x40000000 */ + +#define ADC_CFGR_JQDIS_Pos (31U) +#define ADC_CFGR_JQDIS_Msk (0x1UL << ADC_CFGR_JQDIS_Pos) /*!< 0x80000000 */ +#define ADC_CFGR_JQDIS ADC_CFGR_JQDIS_Msk /*!< ADC group injected contexts queue disable */ + +/******************** Bit definition for ADC_CFGR2 register *****************/ +#define ADC_CFGR2_ROVSE_Pos (0U) +#define ADC_CFGR2_ROVSE_Msk (0x1UL << ADC_CFGR2_ROVSE_Pos) /*!< 0x00000001 */ +#define ADC_CFGR2_ROVSE ADC_CFGR2_ROVSE_Msk /*!< ADC oversampler enable on scope ADC group regular */ +#define ADC_CFGR2_JOVSE_Pos (1U) +#define ADC_CFGR2_JOVSE_Msk (0x1UL << ADC_CFGR2_JOVSE_Pos) /*!< 0x00000002 */ +#define ADC_CFGR2_JOVSE ADC_CFGR2_JOVSE_Msk /*!< ADC oversampler enable on scope ADC group injected */ + +#define ADC_CFGR2_OVSR_Pos (2U) +#define ADC_CFGR2_OVSR_Msk (0x7UL << ADC_CFGR2_OVSR_Pos) /*!< 0x0000001C */ +#define ADC_CFGR2_OVSR ADC_CFGR2_OVSR_Msk /*!< ADC oversampling ratio */ +#define ADC_CFGR2_OVSR_0 (0x1UL << ADC_CFGR2_OVSR_Pos) /*!< 0x00000004 */ +#define ADC_CFGR2_OVSR_1 (0x2UL << ADC_CFGR2_OVSR_Pos) /*!< 0x00000008 */ +#define ADC_CFGR2_OVSR_2 (0x4UL << ADC_CFGR2_OVSR_Pos) /*!< 0x00000010 */ + +#define ADC_CFGR2_OVSS_Pos (5U) +#define ADC_CFGR2_OVSS_Msk (0xFUL << ADC_CFGR2_OVSS_Pos) /*!< 0x000001E0 */ +#define ADC_CFGR2_OVSS ADC_CFGR2_OVSS_Msk /*!< ADC oversampling shift */ +#define ADC_CFGR2_OVSS_0 (0x1UL << ADC_CFGR2_OVSS_Pos) /*!< 0x00000020 */ +#define ADC_CFGR2_OVSS_1 (0x2UL << ADC_CFGR2_OVSS_Pos) /*!< 0x00000040 */ +#define ADC_CFGR2_OVSS_2 (0x4UL << ADC_CFGR2_OVSS_Pos) /*!< 0x00000080 */ +#define ADC_CFGR2_OVSS_3 (0x8UL << ADC_CFGR2_OVSS_Pos) /*!< 0x00000100 */ + +#define ADC_CFGR2_TROVS_Pos (9U) +#define ADC_CFGR2_TROVS_Msk (0x1UL << ADC_CFGR2_TROVS_Pos) /*!< 0x00000200 */ +#define ADC_CFGR2_TROVS ADC_CFGR2_TROVS_Msk /*!< ADC oversampling discontinuous mode (triggered mode) for ADC group regular */ +#define ADC_CFGR2_ROVSM_Pos (10U) +#define ADC_CFGR2_ROVSM_Msk (0x1UL << ADC_CFGR2_ROVSM_Pos) /*!< 0x00000400 */ +#define ADC_CFGR2_ROVSM ADC_CFGR2_ROVSM_Msk /*!< ADC oversampling mode managing interlaced conversions of ADC group regular and group injected */ + +#define ADC_CFGR2_GCOMP_Pos (16U) +#define ADC_CFGR2_GCOMP_Msk (0x1UL << ADC_CFGR2_GCOMP_Pos) /*!< 0x00010000 */ +#define ADC_CFGR2_GCOMP ADC_CFGR2_GCOMP_Msk /*!< ADC Gain Compensation mode */ + +#define ADC_CFGR2_SWTRIG_Pos (25U) +#define ADC_CFGR2_SWTRIG_Msk (0x1UL << ADC_CFGR2_SWTRIG_Pos) /*!< 0x02000000 */ +#define ADC_CFGR2_SWTRIG ADC_CFGR2_SWTRIG_Msk /*!< ADC Software Trigger Bit for Sample time control trigger mode */ +#define ADC_CFGR2_BULB_Pos (26U) +#define ADC_CFGR2_BULB_Msk (0x1UL << ADC_CFGR2_BULB_Pos) /*!< 0x04000000 */ +#define ADC_CFGR2_BULB ADC_CFGR2_BULB_Msk /*!< ADC Bulb sampling mode */ +#define ADC_CFGR2_SMPTRIG_Pos (27U) +#define ADC_CFGR2_SMPTRIG_Msk (0x1UL << ADC_CFGR2_SMPTRIG_Pos) /*!< 0x08000000 */ +#define ADC_CFGR2_SMPTRIG ADC_CFGR2_SMPTRIG_Msk /*!< ADC Sample Time Control Trigger mode */ + +#define ADC_CFGR2_LFTRIG_Pos (29U) +#define ADC_CFGR2_LFTRIG_Msk (0x1UL << ADC_CFGR2_LFTRIG_Pos) /*!< 0x20000000 */ +#define ADC_CFGR2_LFTRIG ADC_CFGR2_LFTRIG_Msk /*!< ADC Low Frequency Trigger */ + +/******************** Bit definition for ADC_SMPR1 register *****************/ +#define ADC_SMPR1_SMP0_Pos (0U) +#define ADC_SMPR1_SMP0_Msk (0x7UL << ADC_SMPR1_SMP0_Pos) /*!< 0x00000007 */ +#define ADC_SMPR1_SMP0 ADC_SMPR1_SMP0_Msk /*!< ADC channel 0 sampling time selection */ +#define ADC_SMPR1_SMP0_0 (0x1UL << ADC_SMPR1_SMP0_Pos) /*!< 0x00000001 */ +#define ADC_SMPR1_SMP0_1 (0x2UL << ADC_SMPR1_SMP0_Pos) /*!< 0x00000002 */ +#define ADC_SMPR1_SMP0_2 (0x4UL << ADC_SMPR1_SMP0_Pos) /*!< 0x00000004 */ + +#define ADC_SMPR1_SMP1_Pos (3U) +#define ADC_SMPR1_SMP1_Msk (0x7UL << ADC_SMPR1_SMP1_Pos) /*!< 0x00000038 */ +#define ADC_SMPR1_SMP1 ADC_SMPR1_SMP1_Msk /*!< ADC channel 1 sampling time selection */ +#define ADC_SMPR1_SMP1_0 (0x1UL << ADC_SMPR1_SMP1_Pos) /*!< 0x00000008 */ +#define ADC_SMPR1_SMP1_1 (0x2UL << ADC_SMPR1_SMP1_Pos) /*!< 0x00000010 */ +#define ADC_SMPR1_SMP1_2 (0x4UL << ADC_SMPR1_SMP1_Pos) /*!< 0x00000020 */ + +#define ADC_SMPR1_SMP2_Pos (6U) +#define ADC_SMPR1_SMP2_Msk (0x7UL << ADC_SMPR1_SMP2_Pos) /*!< 0x000001C0 */ +#define ADC_SMPR1_SMP2 ADC_SMPR1_SMP2_Msk /*!< ADC channel 2 sampling time selection */ +#define ADC_SMPR1_SMP2_0 (0x1UL << ADC_SMPR1_SMP2_Pos) /*!< 0x00000040 */ +#define ADC_SMPR1_SMP2_1 (0x2UL << ADC_SMPR1_SMP2_Pos) /*!< 0x00000080 */ +#define ADC_SMPR1_SMP2_2 (0x4UL << ADC_SMPR1_SMP2_Pos) /*!< 0x00000100 */ + +#define ADC_SMPR1_SMP3_Pos (9U) +#define ADC_SMPR1_SMP3_Msk (0x7UL << ADC_SMPR1_SMP3_Pos) /*!< 0x00000E00 */ +#define ADC_SMPR1_SMP3 ADC_SMPR1_SMP3_Msk /*!< ADC channel 3 sampling time selection */ +#define ADC_SMPR1_SMP3_0 (0x1UL << ADC_SMPR1_SMP3_Pos) /*!< 0x00000200 */ +#define ADC_SMPR1_SMP3_1 (0x2UL << ADC_SMPR1_SMP3_Pos) /*!< 0x00000400 */ +#define ADC_SMPR1_SMP3_2 (0x4UL << ADC_SMPR1_SMP3_Pos) /*!< 0x00000800 */ + +#define ADC_SMPR1_SMP4_Pos (12U) +#define ADC_SMPR1_SMP4_Msk (0x7UL << ADC_SMPR1_SMP4_Pos) /*!< 0x00007000 */ +#define ADC_SMPR1_SMP4 ADC_SMPR1_SMP4_Msk /*!< ADC channel 4 sampling time selection */ +#define ADC_SMPR1_SMP4_0 (0x1UL << ADC_SMPR1_SMP4_Pos) /*!< 0x00001000 */ +#define ADC_SMPR1_SMP4_1 (0x2UL << ADC_SMPR1_SMP4_Pos) /*!< 0x00002000 */ +#define ADC_SMPR1_SMP4_2 (0x4UL << ADC_SMPR1_SMP4_Pos) /*!< 0x00004000 */ + +#define ADC_SMPR1_SMP5_Pos (15U) +#define ADC_SMPR1_SMP5_Msk (0x7UL << ADC_SMPR1_SMP5_Pos) /*!< 0x00038000 */ +#define ADC_SMPR1_SMP5 ADC_SMPR1_SMP5_Msk /*!< ADC channel 5 sampling time selection */ +#define ADC_SMPR1_SMP5_0 (0x1UL << ADC_SMPR1_SMP5_Pos) /*!< 0x00008000 */ +#define ADC_SMPR1_SMP5_1 (0x2UL << ADC_SMPR1_SMP5_Pos) /*!< 0x00010000 */ +#define ADC_SMPR1_SMP5_2 (0x4UL << ADC_SMPR1_SMP5_Pos) /*!< 0x00020000 */ + +#define ADC_SMPR1_SMP6_Pos (18U) +#define ADC_SMPR1_SMP6_Msk (0x7UL << ADC_SMPR1_SMP6_Pos) /*!< 0x001C0000 */ +#define ADC_SMPR1_SMP6 ADC_SMPR1_SMP6_Msk /*!< ADC channel 6 sampling time selection */ +#define ADC_SMPR1_SMP6_0 (0x1UL << ADC_SMPR1_SMP6_Pos) /*!< 0x00040000 */ +#define ADC_SMPR1_SMP6_1 (0x2UL << ADC_SMPR1_SMP6_Pos) /*!< 0x00080000 */ +#define ADC_SMPR1_SMP6_2 (0x4UL << ADC_SMPR1_SMP6_Pos) /*!< 0x00100000 */ + +#define ADC_SMPR1_SMP7_Pos (21U) +#define ADC_SMPR1_SMP7_Msk (0x7UL << ADC_SMPR1_SMP7_Pos) /*!< 0x00E00000 */ +#define ADC_SMPR1_SMP7 ADC_SMPR1_SMP7_Msk /*!< ADC channel 7 sampling time selection */ +#define ADC_SMPR1_SMP7_0 (0x1UL << ADC_SMPR1_SMP7_Pos) /*!< 0x00200000 */ +#define ADC_SMPR1_SMP7_1 (0x2UL << ADC_SMPR1_SMP7_Pos) /*!< 0x00400000 */ +#define ADC_SMPR1_SMP7_2 (0x4UL << ADC_SMPR1_SMP7_Pos) /*!< 0x00800000 */ + +#define ADC_SMPR1_SMP8_Pos (24U) +#define ADC_SMPR1_SMP8_Msk (0x7UL << ADC_SMPR1_SMP8_Pos) /*!< 0x07000000 */ +#define ADC_SMPR1_SMP8 ADC_SMPR1_SMP8_Msk /*!< ADC channel 8 sampling time selection */ +#define ADC_SMPR1_SMP8_0 (0x1UL << ADC_SMPR1_SMP8_Pos) /*!< 0x01000000 */ +#define ADC_SMPR1_SMP8_1 (0x2UL << ADC_SMPR1_SMP8_Pos) /*!< 0x02000000 */ +#define ADC_SMPR1_SMP8_2 (0x4UL << ADC_SMPR1_SMP8_Pos) /*!< 0x04000000 */ + +#define ADC_SMPR1_SMP9_Pos (27U) +#define ADC_SMPR1_SMP9_Msk (0x7UL << ADC_SMPR1_SMP9_Pos) /*!< 0x38000000 */ +#define ADC_SMPR1_SMP9 ADC_SMPR1_SMP9_Msk /*!< ADC channel 9 sampling time selection */ +#define ADC_SMPR1_SMP9_0 (0x1UL << ADC_SMPR1_SMP9_Pos) /*!< 0x08000000 */ +#define ADC_SMPR1_SMP9_1 (0x2UL << ADC_SMPR1_SMP9_Pos) /*!< 0x10000000 */ +#define ADC_SMPR1_SMP9_2 (0x4UL << ADC_SMPR1_SMP9_Pos) /*!< 0x20000000 */ + +#define ADC_SMPR1_SMPPLUS_Pos (31U) +#define ADC_SMPR1_SMPPLUS_Msk (0x1UL << ADC_SMPR1_SMPPLUS_Pos) /*!< 0x80000000 */ +#define ADC_SMPR1_SMPPLUS ADC_SMPR1_SMPPLUS_Msk /*!< ADC channels sampling time additional setting */ + +/******************** Bit definition for ADC_SMPR2 register *****************/ +#define ADC_SMPR2_SMP10_Pos (0U) +#define ADC_SMPR2_SMP10_Msk (0x7UL << ADC_SMPR2_SMP10_Pos) /*!< 0x00000007 */ +#define ADC_SMPR2_SMP10 ADC_SMPR2_SMP10_Msk /*!< ADC channel 10 sampling time selection */ +#define ADC_SMPR2_SMP10_0 (0x1UL << ADC_SMPR2_SMP10_Pos) /*!< 0x00000001 */ +#define ADC_SMPR2_SMP10_1 (0x2UL << ADC_SMPR2_SMP10_Pos) /*!< 0x00000002 */ +#define ADC_SMPR2_SMP10_2 (0x4UL << ADC_SMPR2_SMP10_Pos) /*!< 0x00000004 */ + +#define ADC_SMPR2_SMP11_Pos (3U) +#define ADC_SMPR2_SMP11_Msk (0x7UL << ADC_SMPR2_SMP11_Pos) /*!< 0x00000038 */ +#define ADC_SMPR2_SMP11 ADC_SMPR2_SMP11_Msk /*!< ADC channel 11 sampling time selection */ +#define ADC_SMPR2_SMP11_0 (0x1UL << ADC_SMPR2_SMP11_Pos) /*!< 0x00000008 */ +#define ADC_SMPR2_SMP11_1 (0x2UL << ADC_SMPR2_SMP11_Pos) /*!< 0x00000010 */ +#define ADC_SMPR2_SMP11_2 (0x4UL << ADC_SMPR2_SMP11_Pos) /*!< 0x00000020 */ + +#define ADC_SMPR2_SMP12_Pos (6U) +#define ADC_SMPR2_SMP12_Msk (0x7UL << ADC_SMPR2_SMP12_Pos) /*!< 0x000001C0 */ +#define ADC_SMPR2_SMP12 ADC_SMPR2_SMP12_Msk /*!< ADC channel 12 sampling time selection */ +#define ADC_SMPR2_SMP12_0 (0x1UL << ADC_SMPR2_SMP12_Pos) /*!< 0x00000040 */ +#define ADC_SMPR2_SMP12_1 (0x2UL << ADC_SMPR2_SMP12_Pos) /*!< 0x00000080 */ +#define ADC_SMPR2_SMP12_2 (0x4UL << ADC_SMPR2_SMP12_Pos) /*!< 0x00000100 */ + +#define ADC_SMPR2_SMP13_Pos (9U) +#define ADC_SMPR2_SMP13_Msk (0x7UL << ADC_SMPR2_SMP13_Pos) /*!< 0x00000E00 */ +#define ADC_SMPR2_SMP13 ADC_SMPR2_SMP13_Msk /*!< ADC channel 13 sampling time selection */ +#define ADC_SMPR2_SMP13_0 (0x1UL << ADC_SMPR2_SMP13_Pos) /*!< 0x00000200 */ +#define ADC_SMPR2_SMP13_1 (0x2UL << ADC_SMPR2_SMP13_Pos) /*!< 0x00000400 */ +#define ADC_SMPR2_SMP13_2 (0x4UL << ADC_SMPR2_SMP13_Pos) /*!< 0x00000800 */ + +#define ADC_SMPR2_SMP14_Pos (12U) +#define ADC_SMPR2_SMP14_Msk (0x7UL << ADC_SMPR2_SMP14_Pos) /*!< 0x00007000 */ +#define ADC_SMPR2_SMP14 ADC_SMPR2_SMP14_Msk /*!< ADC channel 14 sampling time selection */ +#define ADC_SMPR2_SMP14_0 (0x1UL << ADC_SMPR2_SMP14_Pos) /*!< 0x00001000 */ +#define ADC_SMPR2_SMP14_1 (0x2UL << ADC_SMPR2_SMP14_Pos) /*!< 0x00002000 */ +#define ADC_SMPR2_SMP14_2 (0x4UL << ADC_SMPR2_SMP14_Pos) /*!< 0x00004000 */ + +#define ADC_SMPR2_SMP15_Pos (15U) +#define ADC_SMPR2_SMP15_Msk (0x7UL << ADC_SMPR2_SMP15_Pos) /*!< 0x00038000 */ +#define ADC_SMPR2_SMP15 ADC_SMPR2_SMP15_Msk /*!< ADC channel 15 sampling time selection */ +#define ADC_SMPR2_SMP15_0 (0x1UL << ADC_SMPR2_SMP15_Pos) /*!< 0x00008000 */ +#define ADC_SMPR2_SMP15_1 (0x2UL << ADC_SMPR2_SMP15_Pos) /*!< 0x00010000 */ +#define ADC_SMPR2_SMP15_2 (0x4UL << ADC_SMPR2_SMP15_Pos) /*!< 0x00020000 */ + +#define ADC_SMPR2_SMP16_Pos (18U) +#define ADC_SMPR2_SMP16_Msk (0x7UL << ADC_SMPR2_SMP16_Pos) /*!< 0x001C0000 */ +#define ADC_SMPR2_SMP16 ADC_SMPR2_SMP16_Msk /*!< ADC channel 16 sampling time selection */ +#define ADC_SMPR2_SMP16_0 (0x1UL << ADC_SMPR2_SMP16_Pos) /*!< 0x00040000 */ +#define ADC_SMPR2_SMP16_1 (0x2UL << ADC_SMPR2_SMP16_Pos) /*!< 0x00080000 */ +#define ADC_SMPR2_SMP16_2 (0x4UL << ADC_SMPR2_SMP16_Pos) /*!< 0x00100000 */ + +#define ADC_SMPR2_SMP17_Pos (21U) +#define ADC_SMPR2_SMP17_Msk (0x7UL << ADC_SMPR2_SMP17_Pos) /*!< 0x00E00000 */ +#define ADC_SMPR2_SMP17 ADC_SMPR2_SMP17_Msk /*!< ADC channel 17 sampling time selection */ +#define ADC_SMPR2_SMP17_0 (0x1UL << ADC_SMPR2_SMP17_Pos) /*!< 0x00200000 */ +#define ADC_SMPR2_SMP17_1 (0x2UL << ADC_SMPR2_SMP17_Pos) /*!< 0x00400000 */ +#define ADC_SMPR2_SMP17_2 (0x4UL << ADC_SMPR2_SMP17_Pos) /*!< 0x00800000 */ + +#define ADC_SMPR2_SMP18_Pos (24U) +#define ADC_SMPR2_SMP18_Msk (0x7UL << ADC_SMPR2_SMP18_Pos) /*!< 0x07000000 */ +#define ADC_SMPR2_SMP18 ADC_SMPR2_SMP18_Msk /*!< ADC channel 18 sampling time selection */ +#define ADC_SMPR2_SMP18_0 (0x1UL << ADC_SMPR2_SMP18_Pos) /*!< 0x01000000 */ +#define ADC_SMPR2_SMP18_1 (0x2UL << ADC_SMPR2_SMP18_Pos) /*!< 0x02000000 */ +#define ADC_SMPR2_SMP18_2 (0x4UL << ADC_SMPR2_SMP18_Pos) /*!< 0x04000000 */ + +/******************** Bit definition for ADC_TR1 register *******************/ +#define ADC_TR1_LT1_Pos (0U) +#define ADC_TR1_LT1_Msk (0xFFFUL << ADC_TR1_LT1_Pos) /*!< 0x00000FFF */ +#define ADC_TR1_LT1 ADC_TR1_LT1_Msk /*!< ADC analog watchdog 1 threshold low */ + +#define ADC_TR1_AWDFILT_Pos (12U) +#define ADC_TR1_AWDFILT_Msk (0x7UL << ADC_TR1_AWDFILT_Pos) /*!< 0x00007000 */ +#define ADC_TR1_AWDFILT ADC_TR1_AWDFILT_Msk /*!< ADC analog watchdog filtering parameter */ +#define ADC_TR1_AWDFILT_0 (0x1UL << ADC_TR1_AWDFILT_Pos) /*!< 0x00001000 */ +#define ADC_TR1_AWDFILT_1 (0x2UL << ADC_TR1_AWDFILT_Pos) /*!< 0x00002000 */ +#define ADC_TR1_AWDFILT_2 (0x4UL << ADC_TR1_AWDFILT_Pos) /*!< 0x00004000 */ + +#define ADC_TR1_HT1_Pos (16U) +#define ADC_TR1_HT1_Msk (0xFFFUL << ADC_TR1_HT1_Pos) /*!< 0x0FFF0000 */ +#define ADC_TR1_HT1 ADC_TR1_HT1_Msk /*!< ADC analog watchdog 1 threshold high */ + +/******************** Bit definition for ADC_TR2 register *******************/ +#define ADC_TR2_LT2_Pos (0U) +#define ADC_TR2_LT2_Msk (0xFFUL << ADC_TR2_LT2_Pos) /*!< 0x000000FF */ +#define ADC_TR2_LT2 ADC_TR2_LT2_Msk /*!< ADC analog watchdog 2 threshold low */ + +#define ADC_TR2_HT2_Pos (16U) +#define ADC_TR2_HT2_Msk (0xFFUL << ADC_TR2_HT2_Pos) /*!< 0x00FF0000 */ +#define ADC_TR2_HT2 ADC_TR2_HT2_Msk /*!< ADC analog watchdog 2 threshold high */ + +/******************** Bit definition for ADC_TR3 register *******************/ +#define ADC_TR3_LT3_Pos (0U) +#define ADC_TR3_LT3_Msk (0xFFUL << ADC_TR3_LT3_Pos) /*!< 0x000000FF */ +#define ADC_TR3_LT3 ADC_TR3_LT3_Msk /*!< ADC analog watchdog 3 threshold low */ + +#define ADC_TR3_HT3_Pos (16U) +#define ADC_TR3_HT3_Msk (0xFFUL << ADC_TR3_HT3_Pos) /*!< 0x00FF0000 */ +#define ADC_TR3_HT3 ADC_TR3_HT3_Msk /*!< ADC analog watchdog 3 threshold high */ + +/******************** Bit definition for ADC_SQR1 register ******************/ +#define ADC_SQR1_L_Pos (0U) +#define ADC_SQR1_L_Msk (0xFUL << ADC_SQR1_L_Pos) /*!< 0x0000000F */ +#define ADC_SQR1_L ADC_SQR1_L_Msk /*!< ADC group regular sequencer scan length */ +#define ADC_SQR1_L_0 (0x1UL << ADC_SQR1_L_Pos) /*!< 0x00000001 */ +#define ADC_SQR1_L_1 (0x2UL << ADC_SQR1_L_Pos) /*!< 0x00000002 */ +#define ADC_SQR1_L_2 (0x4UL << ADC_SQR1_L_Pos) /*!< 0x00000004 */ +#define ADC_SQR1_L_3 (0x8UL << ADC_SQR1_L_Pos) /*!< 0x00000008 */ + +#define ADC_SQR1_SQ1_Pos (6U) +#define ADC_SQR1_SQ1_Msk (0x1FUL << ADC_SQR1_SQ1_Pos) /*!< 0x000007C0 */ +#define ADC_SQR1_SQ1 ADC_SQR1_SQ1_Msk /*!< ADC group regular sequencer rank 1 */ +#define ADC_SQR1_SQ1_0 (0x01UL << ADC_SQR1_SQ1_Pos) /*!< 0x00000040 */ +#define ADC_SQR1_SQ1_1 (0x02UL << ADC_SQR1_SQ1_Pos) /*!< 0x00000080 */ +#define ADC_SQR1_SQ1_2 (0x04UL << ADC_SQR1_SQ1_Pos) /*!< 0x00000100 */ +#define ADC_SQR1_SQ1_3 (0x08UL << ADC_SQR1_SQ1_Pos) /*!< 0x00000200 */ +#define ADC_SQR1_SQ1_4 (0x10UL << ADC_SQR1_SQ1_Pos) /*!< 0x00000400 */ + +#define ADC_SQR1_SQ2_Pos (12U) +#define ADC_SQR1_SQ2_Msk (0x1FUL << ADC_SQR1_SQ2_Pos) /*!< 0x0001F000 */ +#define ADC_SQR1_SQ2 ADC_SQR1_SQ2_Msk /*!< ADC group regular sequencer rank 2 */ +#define ADC_SQR1_SQ2_0 (0x01UL << ADC_SQR1_SQ2_Pos) /*!< 0x00001000 */ +#define ADC_SQR1_SQ2_1 (0x02UL << ADC_SQR1_SQ2_Pos) /*!< 0x00002000 */ +#define ADC_SQR1_SQ2_2 (0x04UL << ADC_SQR1_SQ2_Pos) /*!< 0x00004000 */ +#define ADC_SQR1_SQ2_3 (0x08UL << ADC_SQR1_SQ2_Pos) /*!< 0x00008000 */ +#define ADC_SQR1_SQ2_4 (0x10UL << ADC_SQR1_SQ2_Pos) /*!< 0x00010000 */ + +#define ADC_SQR1_SQ3_Pos (18U) +#define ADC_SQR1_SQ3_Msk (0x1FUL << ADC_SQR1_SQ3_Pos) /*!< 0x007C0000 */ +#define ADC_SQR1_SQ3 ADC_SQR1_SQ3_Msk /*!< ADC group regular sequencer rank 3 */ +#define ADC_SQR1_SQ3_0 (0x01UL << ADC_SQR1_SQ3_Pos) /*!< 0x00040000 */ +#define ADC_SQR1_SQ3_1 (0x02UL << ADC_SQR1_SQ3_Pos) /*!< 0x00080000 */ +#define ADC_SQR1_SQ3_2 (0x04UL << ADC_SQR1_SQ3_Pos) /*!< 0x00100000 */ +#define ADC_SQR1_SQ3_3 (0x08UL << ADC_SQR1_SQ3_Pos) /*!< 0x00200000 */ +#define ADC_SQR1_SQ3_4 (0x10UL<< ADC_SQR1_SQ3_Pos) /*!< 0x00400000 */ + +#define ADC_SQR1_SQ4_Pos (24U) +#define ADC_SQR1_SQ4_Msk (0x1FUL << ADC_SQR1_SQ4_Pos) /*!< 0x1F000000 */ +#define ADC_SQR1_SQ4 ADC_SQR1_SQ4_Msk /*!< ADC group regular sequencer rank 4 */ +#define ADC_SQR1_SQ4_0 (0x01UL << ADC_SQR1_SQ4_Pos) /*!< 0x01000000 */ +#define ADC_SQR1_SQ4_1 (0x02UL << ADC_SQR1_SQ4_Pos) /*!< 0x02000000 */ +#define ADC_SQR1_SQ4_2 (0x04UL << ADC_SQR1_SQ4_Pos) /*!< 0x04000000 */ +#define ADC_SQR1_SQ4_3 (0x08UL << ADC_SQR1_SQ4_Pos) /*!< 0x08000000 */ +#define ADC_SQR1_SQ4_4 (0x10UL << ADC_SQR1_SQ4_Pos) /*!< 0x10000000 */ + +/******************** Bit definition for ADC_SQR2 register ******************/ +#define ADC_SQR2_SQ5_Pos (0U) +#define ADC_SQR2_SQ5_Msk (0x1FUL << ADC_SQR2_SQ5_Pos) /*!< 0x0000001F */ +#define ADC_SQR2_SQ5 ADC_SQR2_SQ5_Msk /*!< ADC group regular sequencer rank 5 */ +#define ADC_SQR2_SQ5_0 (0x01UL << ADC_SQR2_SQ5_Pos) /*!< 0x00000001 */ +#define ADC_SQR2_SQ5_1 (0x02UL << ADC_SQR2_SQ5_Pos) /*!< 0x00000002 */ +#define ADC_SQR2_SQ5_2 (0x04UL << ADC_SQR2_SQ5_Pos) /*!< 0x00000004 */ +#define ADC_SQR2_SQ5_3 (0x08UL << ADC_SQR2_SQ5_Pos) /*!< 0x00000008 */ +#define ADC_SQR2_SQ5_4 (0x10UL << ADC_SQR2_SQ5_Pos) /*!< 0x00000010 */ + +#define ADC_SQR2_SQ6_Pos (6U) +#define ADC_SQR2_SQ6_Msk (0x1FUL << ADC_SQR2_SQ6_Pos) /*!< 0x000007C0 */ +#define ADC_SQR2_SQ6 ADC_SQR2_SQ6_Msk /*!< ADC group regular sequencer rank 6 */ +#define ADC_SQR2_SQ6_0 (0x01UL << ADC_SQR2_SQ6_Pos) /*!< 0x00000040 */ +#define ADC_SQR2_SQ6_1 (0x02UL << ADC_SQR2_SQ6_Pos) /*!< 0x00000080 */ +#define ADC_SQR2_SQ6_2 (0x04UL << ADC_SQR2_SQ6_Pos) /*!< 0x00000100 */ +#define ADC_SQR2_SQ6_3 (0x08UL << ADC_SQR2_SQ6_Pos) /*!< 0x00000200 */ +#define ADC_SQR2_SQ6_4 (0x10UL << ADC_SQR2_SQ6_Pos) /*!< 0x00000400 */ + +#define ADC_SQR2_SQ7_Pos (12U) +#define ADC_SQR2_SQ7_Msk (0x1FUL << ADC_SQR2_SQ7_Pos) /*!< 0x0001F000 */ +#define ADC_SQR2_SQ7 ADC_SQR2_SQ7_Msk /*!< ADC group regular sequencer rank 7 */ +#define ADC_SQR2_SQ7_0 (0x01UL << ADC_SQR2_SQ7_Pos) /*!< 0x00001000 */ +#define ADC_SQR2_SQ7_1 (0x02UL << ADC_SQR2_SQ7_Pos) /*!< 0x00002000 */ +#define ADC_SQR2_SQ7_2 (0x04UL << ADC_SQR2_SQ7_Pos) /*!< 0x00004000 */ +#define ADC_SQR2_SQ7_3 (0x08UL << ADC_SQR2_SQ7_Pos) /*!< 0x00008000 */ +#define ADC_SQR2_SQ7_4 (0x10UL << ADC_SQR2_SQ7_Pos) /*!< 0x00010000 */ + +#define ADC_SQR2_SQ8_Pos (18U) +#define ADC_SQR2_SQ8_Msk (0x1FUL << ADC_SQR2_SQ8_Pos) /*!< 0x007C0000 */ +#define ADC_SQR2_SQ8 ADC_SQR2_SQ8_Msk /*!< ADC group regular sequencer rank 8 */ +#define ADC_SQR2_SQ8_0 (0x01UL << ADC_SQR2_SQ8_Pos) /*!< 0x00040000 */ +#define ADC_SQR2_SQ8_1 (0x02UL << ADC_SQR2_SQ8_Pos) /*!< 0x00080000 */ +#define ADC_SQR2_SQ8_2 (0x04UL << ADC_SQR2_SQ8_Pos) /*!< 0x00100000 */ +#define ADC_SQR2_SQ8_3 (0x08UL << ADC_SQR2_SQ8_Pos) /*!< 0x00200000 */ +#define ADC_SQR2_SQ8_4 (0x10UL << ADC_SQR2_SQ8_Pos) /*!< 0x00400000 */ + +#define ADC_SQR2_SQ9_Pos (24U) +#define ADC_SQR2_SQ9_Msk (0x1FUL << ADC_SQR2_SQ9_Pos) /*!< 0x1F000000 */ +#define ADC_SQR2_SQ9 ADC_SQR2_SQ9_Msk /*!< ADC group regular sequencer rank 9 */ +#define ADC_SQR2_SQ9_0 (0x01UL << ADC_SQR2_SQ9_Pos) /*!< 0x01000000 */ +#define ADC_SQR2_SQ9_1 (0x02UL << ADC_SQR2_SQ9_Pos) /*!< 0x02000000 */ +#define ADC_SQR2_SQ9_2 (0x04UL << ADC_SQR2_SQ9_Pos) /*!< 0x04000000 */ +#define ADC_SQR2_SQ9_3 (0x08UL << ADC_SQR2_SQ9_Pos) /*!< 0x08000000 */ +#define ADC_SQR2_SQ9_4 (0x10UL << ADC_SQR2_SQ9_Pos) /*!< 0x10000000 */ + +/******************** Bit definition for ADC_SQR3 register ******************/ +#define ADC_SQR3_SQ10_Pos (0U) +#define ADC_SQR3_SQ10_Msk (0x1FUL << ADC_SQR3_SQ10_Pos) /*!< 0x0000001F */ +#define ADC_SQR3_SQ10 ADC_SQR3_SQ10_Msk /*!< ADC group regular sequencer rank 10 */ +#define ADC_SQR3_SQ10_0 (0x01UL << ADC_SQR3_SQ10_Pos) /*!< 0x00000001 */ +#define ADC_SQR3_SQ10_1 (0x02UL << ADC_SQR3_SQ10_Pos) /*!< 0x00000002 */ +#define ADC_SQR3_SQ10_2 (0x04UL << ADC_SQR3_SQ10_Pos) /*!< 0x00000004 */ +#define ADC_SQR3_SQ10_3 (0x08UL << ADC_SQR3_SQ10_Pos) /*!< 0x00000008 */ +#define ADC_SQR3_SQ10_4 (0x10UL << ADC_SQR3_SQ10_Pos) /*!< 0x00000010 */ + +#define ADC_SQR3_SQ11_Pos (6U) +#define ADC_SQR3_SQ11_Msk (0x1FUL << ADC_SQR3_SQ11_Pos) /*!< 0x000007C0 */ +#define ADC_SQR3_SQ11 ADC_SQR3_SQ11_Msk /*!< ADC group regular sequencer rank 11 */ +#define ADC_SQR3_SQ11_0 (0x01UL << ADC_SQR3_SQ11_Pos) /*!< 0x00000040 */ +#define ADC_SQR3_SQ11_1 (0x02UL << ADC_SQR3_SQ11_Pos) /*!< 0x00000080 */ +#define ADC_SQR3_SQ11_2 (0x04UL << ADC_SQR3_SQ11_Pos) /*!< 0x00000100 */ +#define ADC_SQR3_SQ11_3 (0x08UL << ADC_SQR3_SQ11_Pos) /*!< 0x00000200 */ +#define ADC_SQR3_SQ11_4 (0x10UL << ADC_SQR3_SQ11_Pos) /*!< 0x00000400 */ + +#define ADC_SQR3_SQ12_Pos (12U) +#define ADC_SQR3_SQ12_Msk (0x1FUL << ADC_SQR3_SQ12_Pos) /*!< 0x0001F000 */ +#define ADC_SQR3_SQ12 ADC_SQR3_SQ12_Msk /*!< ADC group regular sequencer rank 12 */ +#define ADC_SQR3_SQ12_0 (0x01UL << ADC_SQR3_SQ12_Pos) /*!< 0x00001000 */ +#define ADC_SQR3_SQ12_1 (0x02UL << ADC_SQR3_SQ12_Pos) /*!< 0x00002000 */ +#define ADC_SQR3_SQ12_2 (0x04UL << ADC_SQR3_SQ12_Pos) /*!< 0x00004000 */ +#define ADC_SQR3_SQ12_3 (0x08UL << ADC_SQR3_SQ12_Pos) /*!< 0x00008000 */ +#define ADC_SQR3_SQ12_4 (0x10UL << ADC_SQR3_SQ12_Pos) /*!< 0x00010000 */ + +#define ADC_SQR3_SQ13_Pos (18U) +#define ADC_SQR3_SQ13_Msk (0x1FUL << ADC_SQR3_SQ13_Pos) /*!< 0x007C0000 */ +#define ADC_SQR3_SQ13 ADC_SQR3_SQ13_Msk /*!< ADC group regular sequencer rank 13 */ +#define ADC_SQR3_SQ13_0 (0x01UL << ADC_SQR3_SQ13_Pos) /*!< 0x00040000 */ +#define ADC_SQR3_SQ13_1 (0x02UL << ADC_SQR3_SQ13_Pos) /*!< 0x00080000 */ +#define ADC_SQR3_SQ13_2 (0x04UL << ADC_SQR3_SQ13_Pos) /*!< 0x00100000 */ +#define ADC_SQR3_SQ13_3 (0x08UL << ADC_SQR3_SQ13_Pos) /*!< 0x00200000 */ +#define ADC_SQR3_SQ13_4 (0x10UL << ADC_SQR3_SQ13_Pos) /*!< 0x00400000 */ + +#define ADC_SQR3_SQ14_Pos (24U) +#define ADC_SQR3_SQ14_Msk (0x1FUL << ADC_SQR3_SQ14_Pos) /*!< 0x1F000000 */ +#define ADC_SQR3_SQ14 ADC_SQR3_SQ14_Msk /*!< ADC group regular sequencer rank 14 */ +#define ADC_SQR3_SQ14_0 (0x01UL << ADC_SQR3_SQ14_Pos) /*!< 0x01000000 */ +#define ADC_SQR3_SQ14_1 (0x02UL << ADC_SQR3_SQ14_Pos) /*!< 0x02000000 */ +#define ADC_SQR3_SQ14_2 (0x04UL << ADC_SQR3_SQ14_Pos) /*!< 0x04000000 */ +#define ADC_SQR3_SQ14_3 (0x08UL << ADC_SQR3_SQ14_Pos) /*!< 0x08000000 */ +#define ADC_SQR3_SQ14_4 (0x10UL << ADC_SQR3_SQ14_Pos) /*!< 0x10000000 */ + +/******************** Bit definition for ADC_SQR4 register ******************/ +#define ADC_SQR4_SQ15_Pos (0U) +#define ADC_SQR4_SQ15_Msk (0x1FUL << ADC_SQR4_SQ15_Pos) /*!< 0x0000001F */ +#define ADC_SQR4_SQ15 ADC_SQR4_SQ15_Msk /*!< ADC group regular sequencer rank 15 */ +#define ADC_SQR4_SQ15_0 (0x01UL << ADC_SQR4_SQ15_Pos) /*!< 0x00000001 */ +#define ADC_SQR4_SQ15_1 (0x02UL << ADC_SQR4_SQ15_Pos) /*!< 0x00000002 */ +#define ADC_SQR4_SQ15_2 (0x04UL << ADC_SQR4_SQ15_Pos) /*!< 0x00000004 */ +#define ADC_SQR4_SQ15_3 (0x08UL << ADC_SQR4_SQ15_Pos) /*!< 0x00000008 */ +#define ADC_SQR4_SQ15_4 (0x10UL << ADC_SQR4_SQ15_Pos) /*!< 0x00000010 */ + +#define ADC_SQR4_SQ16_Pos (6U) +#define ADC_SQR4_SQ16_Msk (0x1FUL << ADC_SQR4_SQ16_Pos) /*!< 0x000007C0 */ +#define ADC_SQR4_SQ16 ADC_SQR4_SQ16_Msk /*!< ADC group regular sequencer rank 16 */ +#define ADC_SQR4_SQ16_0 (0x01UL << ADC_SQR4_SQ16_Pos) /*!< 0x00000040 */ +#define ADC_SQR4_SQ16_1 (0x02UL << ADC_SQR4_SQ16_Pos) /*!< 0x00000080 */ +#define ADC_SQR4_SQ16_2 (0x04UL << ADC_SQR4_SQ16_Pos) /*!< 0x00000100 */ +#define ADC_SQR4_SQ16_3 (0x08UL << ADC_SQR4_SQ16_Pos) /*!< 0x00000200 */ +#define ADC_SQR4_SQ16_4 (0x10UL << ADC_SQR4_SQ16_Pos) /*!< 0x00000400 */ + +/******************** Bit definition for ADC_DR register ********************/ +#define ADC_DR_RDATA_Pos (0U) +#define ADC_DR_RDATA_Msk (0xFFFFUL << ADC_DR_RDATA_Pos) /*!< 0x0000FFFF */ +#define ADC_DR_RDATA ADC_DR_RDATA_Msk /*!< ADC group regular conversion data */ + +/******************** Bit definition for ADC_JSQR register ******************/ +#define ADC_JSQR_JL_Pos (0U) +#define ADC_JSQR_JL_Msk (0x3UL << ADC_JSQR_JL_Pos) /*!< 0x00000003 */ +#define ADC_JSQR_JL ADC_JSQR_JL_Msk /*!< ADC group injected sequencer scan length */ +#define ADC_JSQR_JL_0 (0x1UL << ADC_JSQR_JL_Pos) /*!< 0x00000001 */ +#define ADC_JSQR_JL_1 (0x2UL << ADC_JSQR_JL_Pos) /*!< 0x00000002 */ + +#define ADC_JSQR_JEXTSEL_Pos (2U) +#define ADC_JSQR_JEXTSEL_Msk (0x1FUL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x0000007C */ +#define ADC_JSQR_JEXTSEL ADC_JSQR_JEXTSEL_Msk /*!< ADC group injected external trigger source */ +#define ADC_JSQR_JEXTSEL_0 (0x1UL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x00000004 */ +#define ADC_JSQR_JEXTSEL_1 (0x2UL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x00000008 */ +#define ADC_JSQR_JEXTSEL_2 (0x4UL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x00000010 */ +#define ADC_JSQR_JEXTSEL_3 (0x8UL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x00000020 */ +#define ADC_JSQR_JEXTSEL_4 (0x10UL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x00000040 */ + +#define ADC_JSQR_JEXTEN_Pos (7U) +#define ADC_JSQR_JEXTEN_Msk (0x3UL << ADC_JSQR_JEXTEN_Pos) /*!< 0x00000180 */ +#define ADC_JSQR_JEXTEN ADC_JSQR_JEXTEN_Msk /*!< ADC group injected external trigger polarity */ +#define ADC_JSQR_JEXTEN_0 (0x1UL << ADC_JSQR_JEXTEN_Pos) /*!< 0x00000080 */ +#define ADC_JSQR_JEXTEN_1 (0x2UL << ADC_JSQR_JEXTEN_Pos) /*!< 0x00000100 */ + +#define ADC_JSQR_JSQ1_Pos (9U) +#define ADC_JSQR_JSQ1_Msk (0x1FUL << ADC_JSQR_JSQ1_Pos) /*!< 0x00003E00 */ +#define ADC_JSQR_JSQ1 ADC_JSQR_JSQ1_Msk /*!< ADC group injected sequencer rank 1 */ +#define ADC_JSQR_JSQ1_0 (0x01UL << ADC_JSQR_JSQ1_Pos) /*!< 0x00000200 */ +#define ADC_JSQR_JSQ1_1 (0x02UL << ADC_JSQR_JSQ1_Pos) /*!< 0x00000400 */ +#define ADC_JSQR_JSQ1_2 (0x04UL << ADC_JSQR_JSQ1_Pos) /*!< 0x00000800 */ +#define ADC_JSQR_JSQ1_3 (0x08UL << ADC_JSQR_JSQ1_Pos) /*!< 0x00001000 */ +#define ADC_JSQR_JSQ1_4 (0x10UL << ADC_JSQR_JSQ1_Pos) /*!< 0x00002000 */ + +#define ADC_JSQR_JSQ2_Pos (15U) +#define ADC_JSQR_JSQ2_Msk (0x1FUL << ADC_JSQR_JSQ2_Pos) /*!< 0x0007C000 */ +#define ADC_JSQR_JSQ2 ADC_JSQR_JSQ2_Msk /*!< ADC group injected sequencer rank 2 */ +#define ADC_JSQR_JSQ2_0 (0x01UL << ADC_JSQR_JSQ2_Pos) /*!< 0x00004000 */ +#define ADC_JSQR_JSQ2_1 (0x02UL << ADC_JSQR_JSQ2_Pos) /*!< 0x00008000 */ +#define ADC_JSQR_JSQ2_2 (0x04UL << ADC_JSQR_JSQ2_Pos) /*!< 0x00010000 */ +#define ADC_JSQR_JSQ2_3 (0x08UL << ADC_JSQR_JSQ2_Pos) /*!< 0x00020000 */ +#define ADC_JSQR_JSQ2_4 (0x10UL << ADC_JSQR_JSQ2_Pos) /*!< 0x00040000 */ + +#define ADC_JSQR_JSQ3_Pos (21U) +#define ADC_JSQR_JSQ3_Msk (0x1FUL << ADC_JSQR_JSQ3_Pos) /*!< 0x03E00000 */ +#define ADC_JSQR_JSQ3 ADC_JSQR_JSQ3_Msk /*!< ADC group injected sequencer rank 3 */ +#define ADC_JSQR_JSQ3_0 (0x01UL << ADC_JSQR_JSQ3_Pos) /*!< 0x00200000 */ +#define ADC_JSQR_JSQ3_1 (0x02UL << ADC_JSQR_JSQ3_Pos) /*!< 0x00400000 */ +#define ADC_JSQR_JSQ3_2 (0x04UL << ADC_JSQR_JSQ3_Pos) /*!< 0x00800000 */ +#define ADC_JSQR_JSQ3_3 (0x08UL << ADC_JSQR_JSQ3_Pos) /*!< 0x01000000 */ +#define ADC_JSQR_JSQ3_4 (0x10UL << ADC_JSQR_JSQ3_Pos) /*!< 0x02000000 */ + +#define ADC_JSQR_JSQ4_Pos (27U) +#define ADC_JSQR_JSQ4_Msk (0x1FUL << ADC_JSQR_JSQ4_Pos) /*!< 0xF8000000 */ +#define ADC_JSQR_JSQ4 ADC_JSQR_JSQ4_Msk /*!< ADC group injected sequencer rank 4 */ +#define ADC_JSQR_JSQ4_0 (0x01UL << ADC_JSQR_JSQ4_Pos) /*!< 0x08000000 */ +#define ADC_JSQR_JSQ4_1 (0x02UL << ADC_JSQR_JSQ4_Pos) /*!< 0x10000000 */ +#define ADC_JSQR_JSQ4_2 (0x04UL << ADC_JSQR_JSQ4_Pos) /*!< 0x20000000 */ +#define ADC_JSQR_JSQ4_3 (0x08UL << ADC_JSQR_JSQ4_Pos) /*!< 0x40000000 */ +#define ADC_JSQR_JSQ4_4 (0x10UL << ADC_JSQR_JSQ4_Pos) /*!< 0x80000000 */ + +/******************** Bit definition for ADC_OFR1 register ******************/ +#define ADC_OFR1_OFFSET1_Pos (0U) +#define ADC_OFR1_OFFSET1_Msk (0xFFFUL << ADC_OFR1_OFFSET1_Pos) /*!< 0x00000FFF */ +#define ADC_OFR1_OFFSET1 ADC_OFR1_OFFSET1_Msk /*!< ADC offset number 1 offset level */ + +#define ADC_OFR1_OFFSETPOS_Pos (24U) +#define ADC_OFR1_OFFSETPOS_Msk (0x1UL << ADC_OFR1_OFFSETPOS_Pos) /*!< 0x01000000 */ +#define ADC_OFR1_OFFSETPOS ADC_OFR1_OFFSETPOS_Msk /*!< ADC offset number 1 positive */ +#define ADC_OFR1_SATEN_Pos (25U) +#define ADC_OFR1_SATEN_Msk (0x1UL << ADC_OFR1_SATEN_Pos) /*!< 0x02000000 */ +#define ADC_OFR1_SATEN ADC_OFR1_SATEN_Msk /*!< ADC offset number 1 saturation enable */ + +#define ADC_OFR1_OFFSET1_CH_Pos (26U) +#define ADC_OFR1_OFFSET1_CH_Msk (0x1FUL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x7C000000 */ +#define ADC_OFR1_OFFSET1_CH ADC_OFR1_OFFSET1_CH_Msk /*!< ADC offset number 1 channel selection */ +#define ADC_OFR1_OFFSET1_CH_0 (0x01UL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x04000000 */ +#define ADC_OFR1_OFFSET1_CH_1 (0x02UL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x08000000 */ +#define ADC_OFR1_OFFSET1_CH_2 (0x04UL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x10000000 */ +#define ADC_OFR1_OFFSET1_CH_3 (0x08UL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x20000000 */ +#define ADC_OFR1_OFFSET1_CH_4 (0x10UL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x40000000 */ + +#define ADC_OFR1_OFFSET1_EN_Pos (31U) +#define ADC_OFR1_OFFSET1_EN_Msk (0x1UL << ADC_OFR1_OFFSET1_EN_Pos) /*!< 0x80000000 */ +#define ADC_OFR1_OFFSET1_EN ADC_OFR1_OFFSET1_EN_Msk /*!< ADC offset number 1 enable */ + +/******************** Bit definition for ADC_OFR2 register ******************/ +#define ADC_OFR2_OFFSET2_Pos (0U) +#define ADC_OFR2_OFFSET2_Msk (0xFFFUL << ADC_OFR2_OFFSET2_Pos) /*!< 0x00000FFF */ +#define ADC_OFR2_OFFSET2 ADC_OFR2_OFFSET2_Msk /*!< ADC offset number 2 offset level */ + +#define ADC_OFR2_OFFSETPOS_Pos (24U) +#define ADC_OFR2_OFFSETPOS_Msk (0x1UL << ADC_OFR2_OFFSETPOS_Pos) /*!< 0x01000000 */ +#define ADC_OFR2_OFFSETPOS ADC_OFR2_OFFSETPOS_Msk /*!< ADC offset number 2 positive */ +#define ADC_OFR2_SATEN_Pos (25U) +#define ADC_OFR2_SATEN_Msk (0x1UL << ADC_OFR2_SATEN_Pos) /*!< 0x02000000 */ +#define ADC_OFR2_SATEN ADC_OFR2_SATEN_Msk /*!< ADC offset number 2 saturation enable */ + +#define ADC_OFR2_OFFSET2_CH_Pos (26U) +#define ADC_OFR2_OFFSET2_CH_Msk (0x1FUL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x7C000000 */ +#define ADC_OFR2_OFFSET2_CH ADC_OFR2_OFFSET2_CH_Msk /*!< ADC offset number 2 channel selection */ +#define ADC_OFR2_OFFSET2_CH_0 (0x01UL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x04000000 */ +#define ADC_OFR2_OFFSET2_CH_1 (0x02UL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x08000000 */ +#define ADC_OFR2_OFFSET2_CH_2 (0x04UL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x10000000 */ +#define ADC_OFR2_OFFSET2_CH_3 (0x08UL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x20000000 */ +#define ADC_OFR2_OFFSET2_CH_4 (0x10UL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x40000000 */ + +#define ADC_OFR2_OFFSET2_EN_Pos (31U) +#define ADC_OFR2_OFFSET2_EN_Msk (0x1UL << ADC_OFR2_OFFSET2_EN_Pos) /*!< 0x80000000 */ +#define ADC_OFR2_OFFSET2_EN ADC_OFR2_OFFSET2_EN_Msk /*!< ADC offset number 2 enable */ + +/******************** Bit definition for ADC_OFR3 register ******************/ +#define ADC_OFR3_OFFSET3_Pos (0U) +#define ADC_OFR3_OFFSET3_Msk (0xFFFUL << ADC_OFR3_OFFSET3_Pos) /*!< 0x00000FFF */ +#define ADC_OFR3_OFFSET3 ADC_OFR3_OFFSET3_Msk /*!< ADC offset number 3 offset level */ + +#define ADC_OFR3_OFFSETPOS_Pos (24U) +#define ADC_OFR3_OFFSETPOS_Msk (0x1UL << ADC_OFR3_OFFSETPOS_Pos) /*!< 0x01000000 */ +#define ADC_OFR3_OFFSETPOS ADC_OFR3_OFFSETPOS_Msk /*!< ADC offset number 3 positive */ +#define ADC_OFR3_SATEN_Pos (25U) +#define ADC_OFR3_SATEN_Msk (0x1UL << ADC_OFR3_SATEN_Pos) /*!< 0x02000000 */ +#define ADC_OFR3_SATEN ADC_OFR3_SATEN_Msk /*!< ADC offset number 3 saturation enable */ + +#define ADC_OFR3_OFFSET3_CH_Pos (26U) +#define ADC_OFR3_OFFSET3_CH_Msk (0x1FUL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x7C000000 */ +#define ADC_OFR3_OFFSET3_CH ADC_OFR3_OFFSET3_CH_Msk /*!< ADC offset number 3 channel selection */ +#define ADC_OFR3_OFFSET3_CH_0 (0x01UL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x04000000 */ +#define ADC_OFR3_OFFSET3_CH_1 (0x02UL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x08000000 */ +#define ADC_OFR3_OFFSET3_CH_2 (0x04UL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x10000000 */ +#define ADC_OFR3_OFFSET3_CH_3 (0x08UL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x20000000 */ +#define ADC_OFR3_OFFSET3_CH_4 (0x10UL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x40000000 */ + +#define ADC_OFR3_OFFSET3_EN_Pos (31U) +#define ADC_OFR3_OFFSET3_EN_Msk (0x1UL << ADC_OFR3_OFFSET3_EN_Pos) /*!< 0x80000000 */ +#define ADC_OFR3_OFFSET3_EN ADC_OFR3_OFFSET3_EN_Msk /*!< ADC offset number 3 enable */ + +/******************** Bit definition for ADC_OFR4 register ******************/ +#define ADC_OFR4_OFFSET4_Pos (0U) +#define ADC_OFR4_OFFSET4_Msk (0xFFFUL << ADC_OFR4_OFFSET4_Pos) /*!< 0x00000FFF */ +#define ADC_OFR4_OFFSET4 ADC_OFR4_OFFSET4_Msk /*!< ADC offset number 4 offset level */ + +#define ADC_OFR4_OFFSETPOS_Pos (24U) +#define ADC_OFR4_OFFSETPOS_Msk (0x1UL << ADC_OFR4_OFFSETPOS_Pos) /*!< 0x01000000 */ +#define ADC_OFR4_OFFSETPOS ADC_OFR4_OFFSETPOS_Msk /*!< ADC offset number 4 positive */ +#define ADC_OFR4_SATEN_Pos (25U) +#define ADC_OFR4_SATEN_Msk (0x1UL << ADC_OFR4_SATEN_Pos) /*!< 0x02000000 */ +#define ADC_OFR4_SATEN ADC_OFR4_SATEN_Msk /*!< ADC offset number 4 saturation enable */ + +#define ADC_OFR4_OFFSET4_CH_Pos (26U) +#define ADC_OFR4_OFFSET4_CH_Msk (0x1FUL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x7C000000 */ +#define ADC_OFR4_OFFSET4_CH ADC_OFR4_OFFSET4_CH_Msk /*!< ADC offset number 4 channel selection */ +#define ADC_OFR4_OFFSET4_CH_0 (0x01UL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x04000000 */ +#define ADC_OFR4_OFFSET4_CH_1 (0x02UL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x08000000 */ +#define ADC_OFR4_OFFSET4_CH_2 (0x04UL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x10000000 */ +#define ADC_OFR4_OFFSET4_CH_3 (0x08UL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x20000000 */ +#define ADC_OFR4_OFFSET4_CH_4 (0x10UL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x40000000 */ + +#define ADC_OFR4_OFFSET4_EN_Pos (31U) +#define ADC_OFR4_OFFSET4_EN_Msk (0x1UL << ADC_OFR4_OFFSET4_EN_Pos) /*!< 0x80000000 */ +#define ADC_OFR4_OFFSET4_EN ADC_OFR4_OFFSET4_EN_Msk /*!< ADC offset number 4 enable */ + +/******************** Bit definition for ADC_JDR1 register ******************/ +#define ADC_JDR1_JDATA_Pos (0U) +#define ADC_JDR1_JDATA_Msk (0xFFFFUL << ADC_JDR1_JDATA_Pos) /*!< 0x0000FFFF */ +#define ADC_JDR1_JDATA ADC_JDR1_JDATA_Msk /*!< ADC group injected sequencer rank 1 conversion data */ + +/******************** Bit definition for ADC_JDR2 register ******************/ +#define ADC_JDR2_JDATA_Pos (0U) +#define ADC_JDR2_JDATA_Msk (0xFFFFUL << ADC_JDR2_JDATA_Pos) /*!< 0x0000FFFF */ +#define ADC_JDR2_JDATA ADC_JDR2_JDATA_Msk /*!< ADC group injected sequencer rank 2 conversion data */ + +/******************** Bit definition for ADC_JDR3 register ******************/ +#define ADC_JDR3_JDATA_Pos (0U) +#define ADC_JDR3_JDATA_Msk (0xFFFFUL << ADC_JDR3_JDATA_Pos) /*!< 0x0000FFFF */ +#define ADC_JDR3_JDATA ADC_JDR3_JDATA_Msk /*!< ADC group injected sequencer rank 3 conversion data */ + +/******************** Bit definition for ADC_JDR4 register ******************/ +#define ADC_JDR4_JDATA_Pos (0U) +#define ADC_JDR4_JDATA_Msk (0xFFFFUL << ADC_JDR4_JDATA_Pos) /*!< 0x0000FFFF */ +#define ADC_JDR4_JDATA ADC_JDR4_JDATA_Msk /*!< ADC group injected sequencer rank 4 conversion data */ + +/******************** Bit definition for ADC_AWD2CR register ****************/ +#define ADC_AWD2CR_AWD2CH_Pos (0U) +#define ADC_AWD2CR_AWD2CH_Msk (0xFFFFFUL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x0007FFFF */ +#define ADC_AWD2CR_AWD2CH ADC_AWD2CR_AWD2CH_Msk /*!< ADC analog watchdog 2 monitored channel selection */ +#define ADC_AWD2CR_AWD2CH_0 (0x00001UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000001 */ +#define ADC_AWD2CR_AWD2CH_1 (0x00002UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000002 */ +#define ADC_AWD2CR_AWD2CH_2 (0x00004UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000004 */ +#define ADC_AWD2CR_AWD2CH_3 (0x00008UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000008 */ +#define ADC_AWD2CR_AWD2CH_4 (0x00010UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000010 */ +#define ADC_AWD2CR_AWD2CH_5 (0x00020UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000020 */ +#define ADC_AWD2CR_AWD2CH_6 (0x00040UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000040 */ +#define ADC_AWD2CR_AWD2CH_7 (0x00080UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000080 */ +#define ADC_AWD2CR_AWD2CH_8 (0x00100UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000100 */ +#define ADC_AWD2CR_AWD2CH_9 (0x00200UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000200 */ +#define ADC_AWD2CR_AWD2CH_10 (0x00400UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000400 */ +#define ADC_AWD2CR_AWD2CH_11 (0x00800UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000800 */ +#define ADC_AWD2CR_AWD2CH_12 (0x01000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00001000 */ +#define ADC_AWD2CR_AWD2CH_13 (0x02000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00002000 */ +#define ADC_AWD2CR_AWD2CH_14 (0x04000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00004000 */ +#define ADC_AWD2CR_AWD2CH_15 (0x08000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00008000 */ +#define ADC_AWD2CR_AWD2CH_16 (0x10000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00010000 */ +#define ADC_AWD2CR_AWD2CH_17 (0x20000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00020000 */ +#define ADC_AWD2CR_AWD2CH_18 (0x40000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00040000 */ +#define ADC_AWD2CR_AWD2CH_19 (0x80000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00080000 */ + +/******************** Bit definition for ADC_AWD3CR register ****************/ +#define ADC_AWD3CR_AWD3CH_Pos (0U) +#define ADC_AWD3CR_AWD3CH_Msk (0xFFFFFUL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x0007FFFF */ +#define ADC_AWD3CR_AWD3CH ADC_AWD3CR_AWD3CH_Msk /*!< ADC analog watchdog 3 monitored channel selection */ +#define ADC_AWD3CR_AWD3CH_0 (0x00001UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000001 */ +#define ADC_AWD3CR_AWD3CH_1 (0x00002UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000002 */ +#define ADC_AWD3CR_AWD3CH_2 (0x00004UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000004 */ +#define ADC_AWD3CR_AWD3CH_3 (0x00008UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000008 */ +#define ADC_AWD3CR_AWD3CH_4 (0x00010UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000010 */ +#define ADC_AWD3CR_AWD3CH_5 (0x00020UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000020 */ +#define ADC_AWD3CR_AWD3CH_6 (0x00040UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000040 */ +#define ADC_AWD3CR_AWD3CH_7 (0x00080UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000080 */ +#define ADC_AWD3CR_AWD3CH_8 (0x00100UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000100 */ +#define ADC_AWD3CR_AWD3CH_9 (0x00200UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000200 */ +#define ADC_AWD3CR_AWD3CH_10 (0x00400UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000400 */ +#define ADC_AWD3CR_AWD3CH_11 (0x00800UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000800 */ +#define ADC_AWD3CR_AWD3CH_12 (0x01000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00001000 */ +#define ADC_AWD3CR_AWD3CH_13 (0x02000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00002000 */ +#define ADC_AWD3CR_AWD3CH_14 (0x04000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00004000 */ +#define ADC_AWD3CR_AWD3CH_15 (0x08000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00008000 */ +#define ADC_AWD3CR_AWD3CH_16 (0x10000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00010000 */ +#define ADC_AWD3CR_AWD3CH_17 (0x20000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00020000 */ +#define ADC_AWD3CR_AWD3CH_18 (0x40000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00040000 */ +#define ADC_AWD3CR_AWD2CH_19 (0x80000UL << ADC_AWD3CR_AWD2CH_Pos) /*!< 0x00080000 */ + +/******************** Bit definition for ADC_DIFSEL register ****************/ +#define ADC_DIFSEL_DIFSEL_Pos (0U) +#define ADC_DIFSEL_DIFSEL_Msk (0xFFFFFUL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x0007FFFF */ +#define ADC_DIFSEL_DIFSEL ADC_DIFSEL_DIFSEL_Msk /*!< ADC channel differential or single-ended mode */ +#define ADC_DIFSEL_DIFSEL_0 (0x00001UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000001 */ +#define ADC_DIFSEL_DIFSEL_1 (0x00002UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000002 */ +#define ADC_DIFSEL_DIFSEL_2 (0x00004UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000004 */ +#define ADC_DIFSEL_DIFSEL_3 (0x00008UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000008 */ +#define ADC_DIFSEL_DIFSEL_4 (0x00010UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000010 */ +#define ADC_DIFSEL_DIFSEL_5 (0x00020UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000020 */ +#define ADC_DIFSEL_DIFSEL_6 (0x00040UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000040 */ +#define ADC_DIFSEL_DIFSEL_7 (0x00080UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000080 */ +#define ADC_DIFSEL_DIFSEL_8 (0x00100UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000100 */ +#define ADC_DIFSEL_DIFSEL_9 (0x00200UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000200 */ +#define ADC_DIFSEL_DIFSEL_10 (0x00400UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000400 */ +#define ADC_DIFSEL_DIFSEL_11 (0x00800UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000800 */ +#define ADC_DIFSEL_DIFSEL_12 (0x01000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00001000 */ +#define ADC_DIFSEL_DIFSEL_13 (0x02000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00002000 */ +#define ADC_DIFSEL_DIFSEL_14 (0x04000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00004000 */ +#define ADC_DIFSEL_DIFSEL_15 (0x08000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00008000 */ +#define ADC_DIFSEL_DIFSEL_16 (0x10000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00010000 */ +#define ADC_DIFSEL_DIFSEL_17 (0x20000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00020000 */ +#define ADC_DIFSEL_DIFSEL_18 (0x40000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00040000 */ +#define ADC_DIFSEL_DIFSEL_19 (0x80000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00080000 */ + +/******************** Bit definition for ADC_CALFACT register ***************/ +#define ADC_CALFACT_CALFACT_S_Pos (0U) +#define ADC_CALFACT_CALFACT_S_Msk (0x7FUL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x0000007F */ +#define ADC_CALFACT_CALFACT_S ADC_CALFACT_CALFACT_S_Msk /*!< ADC calibration factor in single-ended mode */ +#define ADC_CALFACT_CALFACT_S_0 (0x01UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000001 */ +#define ADC_CALFACT_CALFACT_S_1 (0x02UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000002 */ +#define ADC_CALFACT_CALFACT_S_2 (0x04UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000004 */ +#define ADC_CALFACT_CALFACT_S_3 (0x08UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000008 */ +#define ADC_CALFACT_CALFACT_S_4 (0x10UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000010 */ +#define ADC_CALFACT_CALFACT_S_5 (0x20UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000020 */ +#define ADC_CALFACT_CALFACT_S_6 (0x40UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000030 */ + +#define ADC_CALFACT_CALFACT_D_Pos (16U) +#define ADC_CALFACT_CALFACT_D_Msk (0x7FUL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x007F0000 */ +#define ADC_CALFACT_CALFACT_D ADC_CALFACT_CALFACT_D_Msk /*!< ADC calibration factor in differential mode */ +#define ADC_CALFACT_CALFACT_D_0 (0x01UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00010000 */ +#define ADC_CALFACT_CALFACT_D_1 (0x02UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00020000 */ +#define ADC_CALFACT_CALFACT_D_2 (0x04UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00040000 */ +#define ADC_CALFACT_CALFACT_D_3 (0x08UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00080000 */ +#define ADC_CALFACT_CALFACT_D_4 (0x10UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00100000 */ +#define ADC_CALFACT_CALFACT_D_5 (0x20UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00200000 */ +#define ADC_CALFACT_CALFACT_D_6 (0x40UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00300000 */ + +/******************** Bit definition for ADC_OR register *****************/ +#define ADC_OR_OP0_Pos (0U) +#define ADC_OR_OP0_Msk (0x01UL << ADC_OR_OP0_Pos) /*!< 0x00000001 */ +#define ADC_OR_OP0 ADC_OR_OP0_Msk /*!< ADC Option bit 0 */ +#define ADC_OR_OP1_Pos (1U) +#define ADC_OR_OP1_Msk (0x01UL << ADC_OR_OP1_Pos) /*!< 0x00000001 */ +#define ADC_OR_OP1 ADC_OR_OP1_Msk /*!< ADC Option bit 1 */ + +/************************* ADC Common registers *****************************/ +/******************** Bit definition for ADC_CSR register *******************/ +#define ADC_CSR_ADRDY_MST_Pos (0U) +#define ADC_CSR_ADRDY_MST_Msk (0x1UL << ADC_CSR_ADRDY_MST_Pos) /*!< 0x00000001 */ +#define ADC_CSR_ADRDY_MST ADC_CSR_ADRDY_MST_Msk /*!< ADC multimode master ready flag */ +#define ADC_CSR_EOSMP_MST_Pos (1U) +#define ADC_CSR_EOSMP_MST_Msk (0x1UL << ADC_CSR_EOSMP_MST_Pos) /*!< 0x00000002 */ +#define ADC_CSR_EOSMP_MST ADC_CSR_EOSMP_MST_Msk /*!< ADC multimode master group regular end of sampling flag */ +#define ADC_CSR_EOC_MST_Pos (2U) +#define ADC_CSR_EOC_MST_Msk (0x1UL << ADC_CSR_EOC_MST_Pos) /*!< 0x00000004 */ +#define ADC_CSR_EOC_MST ADC_CSR_EOC_MST_Msk /*!< ADC multimode master group regular end of unitary conversion flag */ +#define ADC_CSR_EOS_MST_Pos (3U) +#define ADC_CSR_EOS_MST_Msk (0x1UL << ADC_CSR_EOS_MST_Pos) /*!< 0x00000008 */ +#define ADC_CSR_EOS_MST ADC_CSR_EOS_MST_Msk /*!< ADC multimode master group regular end of sequence conversions flag */ +#define ADC_CSR_OVR_MST_Pos (4U) +#define ADC_CSR_OVR_MST_Msk (0x1UL << ADC_CSR_OVR_MST_Pos) /*!< 0x00000010 */ +#define ADC_CSR_OVR_MST ADC_CSR_OVR_MST_Msk /*!< ADC multimode master group regular overrun flag */ +#define ADC_CSR_JEOC_MST_Pos (5U) +#define ADC_CSR_JEOC_MST_Msk (0x1UL << ADC_CSR_JEOC_MST_Pos) /*!< 0x00000020 */ +#define ADC_CSR_JEOC_MST ADC_CSR_JEOC_MST_Msk /*!< ADC multimode master group injected end of unitary conversion flag */ +#define ADC_CSR_JEOS_MST_Pos (6U) +#define ADC_CSR_JEOS_MST_Msk (0x1UL << ADC_CSR_JEOS_MST_Pos) /*!< 0x00000040 */ +#define ADC_CSR_JEOS_MST ADC_CSR_JEOS_MST_Msk /*!< ADC multimode master group injected end of sequence conversions flag */ +#define ADC_CSR_AWD1_MST_Pos (7U) +#define ADC_CSR_AWD1_MST_Msk (0x1UL << ADC_CSR_AWD1_MST_Pos) /*!< 0x00000080 */ +#define ADC_CSR_AWD1_MST ADC_CSR_AWD1_MST_Msk /*!< ADC multimode master analog watchdog 1 flag */ +#define ADC_CSR_AWD2_MST_Pos (8U) +#define ADC_CSR_AWD2_MST_Msk (0x1UL << ADC_CSR_AWD2_MST_Pos) /*!< 0x00000100 */ +#define ADC_CSR_AWD2_MST ADC_CSR_AWD2_MST_Msk /*!< ADC multimode master analog watchdog 2 flag */ +#define ADC_CSR_AWD3_MST_Pos (9U) +#define ADC_CSR_AWD3_MST_Msk (0x1UL << ADC_CSR_AWD3_MST_Pos) /*!< 0x00000200 */ +#define ADC_CSR_AWD3_MST ADC_CSR_AWD3_MST_Msk /*!< ADC multimode master analog watchdog 3 flag */ +#define ADC_CSR_JQOVF_MST_Pos (10U) +#define ADC_CSR_JQOVF_MST_Msk (0x1UL << ADC_CSR_JQOVF_MST_Pos) /*!< 0x00000400 */ +#define ADC_CSR_JQOVF_MST ADC_CSR_JQOVF_MST_Msk /*!< ADC multimode master group injected contexts queue overflow flag */ + +#define ADC_CSR_ADRDY_SLV_Pos (16U) +#define ADC_CSR_ADRDY_SLV_Msk (0x1UL << ADC_CSR_ADRDY_SLV_Pos) /*!< 0x00010000 */ +#define ADC_CSR_ADRDY_SLV ADC_CSR_ADRDY_SLV_Msk /*!< ADC multimode slave ready flag */ +#define ADC_CSR_EOSMP_SLV_Pos (17U) +#define ADC_CSR_EOSMP_SLV_Msk (0x1UL << ADC_CSR_EOSMP_SLV_Pos) /*!< 0x00020000 */ +#define ADC_CSR_EOSMP_SLV ADC_CSR_EOSMP_SLV_Msk /*!< ADC multimode slave group regular end of sampling flag */ +#define ADC_CSR_EOC_SLV_Pos (18U) +#define ADC_CSR_EOC_SLV_Msk (0x1UL << ADC_CSR_EOC_SLV_Pos) /*!< 0x00040000 */ +#define ADC_CSR_EOC_SLV ADC_CSR_EOC_SLV_Msk /*!< ADC multimode slave group regular end of unitary conversion flag */ +#define ADC_CSR_EOS_SLV_Pos (19U) +#define ADC_CSR_EOS_SLV_Msk (0x1UL << ADC_CSR_EOS_SLV_Pos) /*!< 0x00080000 */ +#define ADC_CSR_EOS_SLV ADC_CSR_EOS_SLV_Msk /*!< ADC multimode slave group regular end of sequence conversions flag */ +#define ADC_CSR_OVR_SLV_Pos (20U) +#define ADC_CSR_OVR_SLV_Msk (0x1UL << ADC_CSR_OVR_SLV_Pos) /*!< 0x00100000 */ +#define ADC_CSR_OVR_SLV ADC_CSR_OVR_SLV_Msk /*!< ADC multimode slave group regular overrun flag */ +#define ADC_CSR_JEOC_SLV_Pos (21U) +#define ADC_CSR_JEOC_SLV_Msk (0x1UL << ADC_CSR_JEOC_SLV_Pos) /*!< 0x00200000 */ +#define ADC_CSR_JEOC_SLV ADC_CSR_JEOC_SLV_Msk /*!< ADC multimode slave group injected end of unitary conversion flag */ +#define ADC_CSR_JEOS_SLV_Pos (22U) +#define ADC_CSR_JEOS_SLV_Msk (0x1UL << ADC_CSR_JEOS_SLV_Pos) /*!< 0x00400000 */ +#define ADC_CSR_JEOS_SLV ADC_CSR_JEOS_SLV_Msk /*!< ADC multimode slave group injected end of sequence conversions flag */ +#define ADC_CSR_AWD1_SLV_Pos (23U) +#define ADC_CSR_AWD1_SLV_Msk (0x1UL << ADC_CSR_AWD1_SLV_Pos) /*!< 0x00800000 */ +#define ADC_CSR_AWD1_SLV ADC_CSR_AWD1_SLV_Msk /*!< ADC multimode slave analog watchdog 1 flag */ +#define ADC_CSR_AWD2_SLV_Pos (24U) +#define ADC_CSR_AWD2_SLV_Msk (0x1UL << ADC_CSR_AWD2_SLV_Pos) /*!< 0x01000000 */ +#define ADC_CSR_AWD2_SLV ADC_CSR_AWD2_SLV_Msk /*!< ADC multimode slave analog watchdog 2 flag */ +#define ADC_CSR_AWD3_SLV_Pos (25U) +#define ADC_CSR_AWD3_SLV_Msk (0x1UL << ADC_CSR_AWD3_SLV_Pos) /*!< 0x02000000 */ +#define ADC_CSR_AWD3_SLV ADC_CSR_AWD3_SLV_Msk /*!< ADC multimode slave analog watchdog 3 flag */ +#define ADC_CSR_JQOVF_SLV_Pos (26U) +#define ADC_CSR_JQOVF_SLV_Msk (0x1UL << ADC_CSR_JQOVF_SLV_Pos) /*!< 0x04000000 */ +#define ADC_CSR_JQOVF_SLV ADC_CSR_JQOVF_SLV_Msk /*!< ADC multimode slave group injected contexts queue overflow flag */ + +/******************** Bit definition for ADC_CCR register *******************/ +#define ADC_CCR_DUAL_Pos (0U) +#define ADC_CCR_DUAL_Msk (0x1FUL << ADC_CCR_DUAL_Pos) /*!< 0x0000001F */ +#define ADC_CCR_DUAL ADC_CCR_DUAL_Msk /*!< ADC multimode mode selection */ +#define ADC_CCR_DUAL_0 (0x01UL << ADC_CCR_DUAL_Pos) /*!< 0x00000001 */ +#define ADC_CCR_DUAL_1 (0x02UL << ADC_CCR_DUAL_Pos) /*!< 0x00000002 */ +#define ADC_CCR_DUAL_2 (0x04UL << ADC_CCR_DUAL_Pos) /*!< 0x00000004 */ +#define ADC_CCR_DUAL_3 (0x08UL << ADC_CCR_DUAL_Pos) /*!< 0x00000008 */ +#define ADC_CCR_DUAL_4 (0x10UL << ADC_CCR_DUAL_Pos) /*!< 0x00000010 */ + +#define ADC_CCR_DELAY_Pos (8U) +#define ADC_CCR_DELAY_Msk (0xFUL << ADC_CCR_DELAY_Pos) /*!< 0x00000F00 */ +#define ADC_CCR_DELAY ADC_CCR_DELAY_Msk /*!< ADC multimode delay between 2 sampling phases */ +#define ADC_CCR_DELAY_0 (0x1UL << ADC_CCR_DELAY_Pos) /*!< 0x00000100 */ +#define ADC_CCR_DELAY_1 (0x2UL << ADC_CCR_DELAY_Pos) /*!< 0x00000200 */ +#define ADC_CCR_DELAY_2 (0x4UL << ADC_CCR_DELAY_Pos) /*!< 0x00000400 */ +#define ADC_CCR_DELAY_3 (0x8UL << ADC_CCR_DELAY_Pos) /*!< 0x00000800 */ + +#define ADC_CCR_DMACFG_Pos (13U) +#define ADC_CCR_DMACFG_Msk (0x1UL << ADC_CCR_DMACFG_Pos) /*!< 0x00002000 */ +#define ADC_CCR_DMACFG ADC_CCR_DMACFG_Msk /*!< ADC multimode DMA transfer configuration */ + +#define ADC_CCR_MDMA_Pos (14U) +#define ADC_CCR_MDMA_Msk (0x3UL << ADC_CCR_MDMA_Pos) /*!< 0x0000C000 */ +#define ADC_CCR_MDMA ADC_CCR_MDMA_Msk /*!< ADC multimode DMA transfer enable */ +#define ADC_CCR_MDMA_0 (0x1UL << ADC_CCR_MDMA_Pos) /*!< 0x00004000 */ +#define ADC_CCR_MDMA_1 (0x2UL << ADC_CCR_MDMA_Pos) /*!< 0x00008000 */ + +#define ADC_CCR_CKMODE_Pos (16U) +#define ADC_CCR_CKMODE_Msk (0x3UL << ADC_CCR_CKMODE_Pos) /*!< 0x00030000 */ +#define ADC_CCR_CKMODE ADC_CCR_CKMODE_Msk /*!< ADC common clock source and prescaler (prescaler only for clock source synchronous) */ +#define ADC_CCR_CKMODE_0 (0x1UL << ADC_CCR_CKMODE_Pos) /*!< 0x00010000 */ +#define ADC_CCR_CKMODE_1 (0x2UL << ADC_CCR_CKMODE_Pos) /*!< 0x00020000 */ + +#define ADC_CCR_PRESC_Pos (18U) +#define ADC_CCR_PRESC_Msk (0xFUL << ADC_CCR_PRESC_Pos) /*!< 0x003C0000 */ +#define ADC_CCR_PRESC ADC_CCR_PRESC_Msk /*!< ADC common clock prescaler, only for clock source asynchronous */ +#define ADC_CCR_PRESC_0 (0x1UL << ADC_CCR_PRESC_Pos) /*!< 0x00040000 */ +#define ADC_CCR_PRESC_1 (0x2UL << ADC_CCR_PRESC_Pos) /*!< 0x00080000 */ +#define ADC_CCR_PRESC_2 (0x4UL << ADC_CCR_PRESC_Pos) /*!< 0x00100000 */ +#define ADC_CCR_PRESC_3 (0x8UL << ADC_CCR_PRESC_Pos) /*!< 0x00200000 */ + +#define ADC_CCR_VREFEN_Pos (22U) +#define ADC_CCR_VREFEN_Msk (0x1UL << ADC_CCR_VREFEN_Pos) /*!< 0x00400000 */ +#define ADC_CCR_VREFEN ADC_CCR_VREFEN_Msk /*!< ADC internal path to VrefInt enable */ +#define ADC_CCR_TSEN_Pos (23U) +#define ADC_CCR_TSEN_Msk (0x1UL << ADC_CCR_TSEN_Pos) /*!< 0x00800000 */ +#define ADC_CCR_TSEN ADC_CCR_TSEN_Msk /*!< ADC internal path to temperature sensor enable */ +#define ADC_CCR_VBATEN_Pos (24U) +#define ADC_CCR_VBATEN_Msk (0x1UL << ADC_CCR_VBATEN_Pos) /*!< 0x01000000 */ +#define ADC_CCR_VBATEN ADC_CCR_VBATEN_Msk /*!< ADC internal path to battery voltage enable */ + +/******************** Bit definition for ADC_CDR register *******************/ +#define ADC_CDR_RDATA_MST_Pos (0U) +#define ADC_CDR_RDATA_MST_Msk (0xFFFFUL << ADC_CDR_RDATA_MST_Pos) /*!< 0x0000FFFF */ +#define ADC_CDR_RDATA_MST ADC_CDR_RDATA_MST_Msk /*!< ADC multimode master group regular conversion data */ + +#define ADC_CDR_RDATA_SLV_Pos (16U) +#define ADC_CDR_RDATA_SLV_Msk (0xFFFFUL << ADC_CDR_RDATA_SLV_Pos) /*!< 0xFFFF0000 */ +#define ADC_CDR_RDATA_SLV ADC_CDR_RDATA_SLV_Msk /*!< ADC multimode slave group regular conversion data */ + + +/******************************************************************************/ +/* */ +/* CORDIC calculation unit */ +/* */ +/******************************************************************************/ +/******************* Bit definition for CORDIC_CSR register *****************/ +#define CORDIC_CSR_FUNC_Pos (0U) +#define CORDIC_CSR_FUNC_Msk (0xFUL << CORDIC_CSR_FUNC_Pos) /*!< 0x0000000F */ +#define CORDIC_CSR_FUNC CORDIC_CSR_FUNC_Msk /*!< Function */ +#define CORDIC_CSR_FUNC_0 (0x1UL << CORDIC_CSR_FUNC_Pos) /*!< 0x00000001 */ +#define CORDIC_CSR_FUNC_1 (0x2UL << CORDIC_CSR_FUNC_Pos) /*!< 0x00000002 */ +#define CORDIC_CSR_FUNC_2 (0x4UL << CORDIC_CSR_FUNC_Pos) /*!< 0x00000004 */ +#define CORDIC_CSR_FUNC_3 (0x8UL << CORDIC_CSR_FUNC_Pos) /*!< 0x00000008 */ +#define CORDIC_CSR_PRECISION_Pos (4U) +#define CORDIC_CSR_PRECISION_Msk (0xFUL << CORDIC_CSR_PRECISION_Pos) /*!< 0x000000F0 */ +#define CORDIC_CSR_PRECISION CORDIC_CSR_PRECISION_Msk /*!< Precision */ +#define CORDIC_CSR_PRECISION_0 (0x1UL << CORDIC_CSR_PRECISION_Pos) /*!< 0x00000010 */ +#define CORDIC_CSR_PRECISION_1 (0x2UL << CORDIC_CSR_PRECISION_Pos) /*!< 0x00000020 */ +#define CORDIC_CSR_PRECISION_2 (0x4UL << CORDIC_CSR_PRECISION_Pos) /*!< 0x00000040 */ +#define CORDIC_CSR_PRECISION_3 (0x8UL << CORDIC_CSR_PRECISION_Pos) /*!< 0x00000080 */ +#define CORDIC_CSR_SCALE_Pos (8U) +#define CORDIC_CSR_SCALE_Msk (0x7UL << CORDIC_CSR_SCALE_Pos) /*!< 0x00000700 */ +#define CORDIC_CSR_SCALE CORDIC_CSR_SCALE_Msk /*!< Scaling factor */ +#define CORDIC_CSR_SCALE_0 (0x1UL << CORDIC_CSR_SCALE_Pos) /*!< 0x00000100 */ +#define CORDIC_CSR_SCALE_1 (0x2UL << CORDIC_CSR_SCALE_Pos) /*!< 0x00000200 */ +#define CORDIC_CSR_SCALE_2 (0x4UL << CORDIC_CSR_SCALE_Pos) /*!< 0x00000400 */ +#define CORDIC_CSR_IEN_Pos (16U) +#define CORDIC_CSR_IEN_Msk (0x1UL << CORDIC_CSR_IEN_Pos) /*!< 0x00010000 */ +#define CORDIC_CSR_IEN CORDIC_CSR_IEN_Msk /*!< Interrupt Enable */ +#define CORDIC_CSR_DMAREN_Pos (17U) +#define CORDIC_CSR_DMAREN_Msk (0x1UL << CORDIC_CSR_DMAREN_Pos) /*!< 0x00020000 */ +#define CORDIC_CSR_DMAREN CORDIC_CSR_DMAREN_Msk /*!< DMA Read channel Enable */ +#define CORDIC_CSR_DMAWEN_Pos (18U) +#define CORDIC_CSR_DMAWEN_Msk (0x1UL << CORDIC_CSR_DMAWEN_Pos) /*!< 0x00040000 */ +#define CORDIC_CSR_DMAWEN CORDIC_CSR_DMAWEN_Msk /*!< DMA Write channel Enable */ +#define CORDIC_CSR_NRES_Pos (19U) +#define CORDIC_CSR_NRES_Msk (0x1UL << CORDIC_CSR_NRES_Pos) /*!< 0x00080000 */ +#define CORDIC_CSR_NRES CORDIC_CSR_NRES_Msk /*!< Number of results in WDATA register */ +#define CORDIC_CSR_NARGS_Pos (20U) +#define CORDIC_CSR_NARGS_Msk (0x1UL << CORDIC_CSR_NARGS_Pos) /*!< 0x00100000 */ +#define CORDIC_CSR_NARGS CORDIC_CSR_NARGS_Msk /*!< Number of arguments in RDATA register */ +#define CORDIC_CSR_RESSIZE_Pos (21U) +#define CORDIC_CSR_RESSIZE_Msk (0x1UL << CORDIC_CSR_RESSIZE_Pos) /*!< 0x00200000 */ +#define CORDIC_CSR_RESSIZE CORDIC_CSR_RESSIZE_Msk /*!< Width of output data */ +#define CORDIC_CSR_ARGSIZE_Pos (22U) +#define CORDIC_CSR_ARGSIZE_Msk (0x1UL << CORDIC_CSR_ARGSIZE_Pos) /*!< 0x00400000 */ +#define CORDIC_CSR_ARGSIZE CORDIC_CSR_ARGSIZE_Msk /*!< Width of input data */ +#define CORDIC_CSR_RRDY_Pos (31U) +#define CORDIC_CSR_RRDY_Msk (0x1UL << CORDIC_CSR_RRDY_Pos) /*!< 0x80000000 */ +#define CORDIC_CSR_RRDY CORDIC_CSR_RRDY_Msk /*!< Result Ready Flag */ + +/******************* Bit definition for CORDIC_WDATA register ***************/ +#define CORDIC_WDATA_ARG_Pos (0U) +#define CORDIC_WDATA_ARG_Msk (0xFFFFFFFFUL << CORDIC_WDATA_ARG_Pos) /*!< 0xFFFFFFFF */ +#define CORDIC_WDATA_ARG CORDIC_WDATA_ARG_Msk /*!< Input Argument */ + +/******************* Bit definition for CORDIC_RDATA register ***************/ +#define CORDIC_RDATA_RES_Pos (0U) +#define CORDIC_RDATA_RES_Msk (0xFFFFFFFFUL << CORDIC_RDATA_RES_Pos) /*!< 0xFFFFFFFF */ +#define CORDIC_RDATA_RES CORDIC_RDATA_RES_Msk /*!< Output Result */ + +/******************************************************************************/ +/* */ +/* CRC calculation unit */ +/* */ +/******************************************************************************/ +/******************* Bit definition for CRC_DR register *********************/ +#define CRC_DR_DR_Pos (0U) +#define CRC_DR_DR_Msk (0xFFFFFFFFUL << CRC_DR_DR_Pos) /*!< 0xFFFFFFFF */ +#define CRC_DR_DR CRC_DR_DR_Msk /*!< Data register bits */ + +/******************* Bit definition for CRC_IDR register ********************/ +#define CRC_IDR_IDR_Pos (0U) +#define CRC_IDR_IDR_Msk (0xFFFFFFFFUL << CRC_IDR_IDR_Pos) /*!< 0xFFFFFFFF */ +#define CRC_IDR_IDR CRC_IDR_IDR_Msk /*!< General-purpose 32-bits data register bits */ + +/******************** Bit definition for CRC_CR register ********************/ +#define CRC_CR_RESET_Pos (0U) +#define CRC_CR_RESET_Msk (0x1UL << CRC_CR_RESET_Pos) /*!< 0x00000001 */ +#define CRC_CR_RESET CRC_CR_RESET_Msk /*!< RESET the CRC computation unit bit */ +#define CRC_CR_POLYSIZE_Pos (3U) +#define CRC_CR_POLYSIZE_Msk (0x3UL << CRC_CR_POLYSIZE_Pos) /*!< 0x00000018 */ +#define CRC_CR_POLYSIZE CRC_CR_POLYSIZE_Msk /*!< Polynomial size bits */ +#define CRC_CR_POLYSIZE_0 (0x1UL << CRC_CR_POLYSIZE_Pos) /*!< 0x00000008 */ +#define CRC_CR_POLYSIZE_1 (0x2UL << CRC_CR_POLYSIZE_Pos) /*!< 0x00000010 */ +#define CRC_CR_REV_IN_Pos (5U) +#define CRC_CR_REV_IN_Msk (0x3UL << CRC_CR_REV_IN_Pos) /*!< 0x00000060 */ +#define CRC_CR_REV_IN CRC_CR_REV_IN_Msk /*!< REV_IN Reverse Input Data bits */ +#define CRC_CR_REV_IN_0 (0x1UL << CRC_CR_REV_IN_Pos) /*!< 0x00000020 */ +#define CRC_CR_REV_IN_1 (0x2UL << CRC_CR_REV_IN_Pos) /*!< 0x00000040 */ +#define CRC_CR_REV_OUT_Pos (7U) +#define CRC_CR_REV_OUT_Msk (0x1UL << CRC_CR_REV_OUT_Pos) /*!< 0x00000080 */ +#define CRC_CR_REV_OUT CRC_CR_REV_OUT_Msk /*!< REV_OUT Reverse Output Data bits */ + +/******************* Bit definition for CRC_INIT register *******************/ +#define CRC_INIT_INIT_Pos (0U) +#define CRC_INIT_INIT_Msk (0xFFFFFFFFUL << CRC_INIT_INIT_Pos) /*!< 0xFFFFFFFF */ +#define CRC_INIT_INIT CRC_INIT_INIT_Msk /*!< Initial CRC value bits */ + +/******************* Bit definition for CRC_POL register ********************/ +#define CRC_POL_POL_Pos (0U) +#define CRC_POL_POL_Msk (0xFFFFFFFFUL << CRC_POL_POL_Pos) /*!< 0xFFFFFFFF */ +#define CRC_POL_POL CRC_POL_POL_Msk /*!< Coefficients of the polynomial */ + + +/******************************************************************************/ +/* */ +/* CRS Clock Recovery System */ +/******************************************************************************/ +/******************* Bit definition for CRS_CR register *********************/ +#define CRS_CR_SYNCOKIE_Pos (0U) +#define CRS_CR_SYNCOKIE_Msk (0x1UL << CRS_CR_SYNCOKIE_Pos) /*!< 0x00000001 */ +#define CRS_CR_SYNCOKIE CRS_CR_SYNCOKIE_Msk /*!< SYNC event OK interrupt enable */ +#define CRS_CR_SYNCWARNIE_Pos (1U) +#define CRS_CR_SYNCWARNIE_Msk (0x1UL << CRS_CR_SYNCWARNIE_Pos) /*!< 0x00000002 */ +#define CRS_CR_SYNCWARNIE CRS_CR_SYNCWARNIE_Msk /*!< SYNC warning interrupt enable */ +#define CRS_CR_ERRIE_Pos (2U) +#define CRS_CR_ERRIE_Msk (0x1UL << CRS_CR_ERRIE_Pos) /*!< 0x00000004 */ +#define CRS_CR_ERRIE CRS_CR_ERRIE_Msk /*!< SYNC error or trimming error interrupt enable */ +#define CRS_CR_ESYNCIE_Pos (3U) +#define CRS_CR_ESYNCIE_Msk (0x1UL << CRS_CR_ESYNCIE_Pos) /*!< 0x00000008 */ +#define CRS_CR_ESYNCIE CRS_CR_ESYNCIE_Msk /*!< Expected SYNC interrupt enable */ +#define CRS_CR_CEN_Pos (5U) +#define CRS_CR_CEN_Msk (0x1UL << CRS_CR_CEN_Pos) /*!< 0x00000020 */ +#define CRS_CR_CEN CRS_CR_CEN_Msk /*!< Frequency error counter enable */ +#define CRS_CR_AUTOTRIMEN_Pos (6U) +#define CRS_CR_AUTOTRIMEN_Msk (0x1UL << CRS_CR_AUTOTRIMEN_Pos) /*!< 0x00000040 */ +#define CRS_CR_AUTOTRIMEN CRS_CR_AUTOTRIMEN_Msk /*!< Automatic trimming enable */ +#define CRS_CR_SWSYNC_Pos (7U) +#define CRS_CR_SWSYNC_Msk (0x1UL << CRS_CR_SWSYNC_Pos) /*!< 0x00000080 */ +#define CRS_CR_SWSYNC CRS_CR_SWSYNC_Msk /*!< Generate software SYNC event */ +#define CRS_CR_TRIM_Pos (8U) +#define CRS_CR_TRIM_Msk (0x3FUL << CRS_CR_TRIM_Pos) /*!< 0x00003F00 */ +#define CRS_CR_TRIM CRS_CR_TRIM_Msk /*!< HSI48 oscillator smooth trimming */ + +/******************* Bit definition for CRS_CFGR register *********************/ +#define CRS_CFGR_RELOAD_Pos (0U) +#define CRS_CFGR_RELOAD_Msk (0xFFFFUL << CRS_CFGR_RELOAD_Pos) /*!< 0x0000FFFF */ +#define CRS_CFGR_RELOAD CRS_CFGR_RELOAD_Msk /*!< Counter reload value */ +#define CRS_CFGR_FELIM_Pos (16U) +#define CRS_CFGR_FELIM_Msk (0xFFUL << CRS_CFGR_FELIM_Pos) /*!< 0x00FF0000 */ +#define CRS_CFGR_FELIM CRS_CFGR_FELIM_Msk /*!< Frequency error limit */ +#define CRS_CFGR_SYNCDIV_Pos (24U) +#define CRS_CFGR_SYNCDIV_Msk (0x7UL << CRS_CFGR_SYNCDIV_Pos) /*!< 0x07000000 */ +#define CRS_CFGR_SYNCDIV CRS_CFGR_SYNCDIV_Msk /*!< SYNC divider */ +#define CRS_CFGR_SYNCDIV_0 (0x1UL << CRS_CFGR_SYNCDIV_Pos) /*!< 0x01000000 */ +#define CRS_CFGR_SYNCDIV_1 (0x2UL << CRS_CFGR_SYNCDIV_Pos) /*!< 0x02000000 */ +#define CRS_CFGR_SYNCDIV_2 (0x4UL << CRS_CFGR_SYNCDIV_Pos) /*!< 0x04000000 */ +#define CRS_CFGR_SYNCSRC_Pos (28U) +#define CRS_CFGR_SYNCSRC_Msk (0x3UL << CRS_CFGR_SYNCSRC_Pos) /*!< 0x30000000 */ +#define CRS_CFGR_SYNCSRC CRS_CFGR_SYNCSRC_Msk /*!< SYNC signal source selection */ +#define CRS_CFGR_SYNCSRC_0 (0x1UL << CRS_CFGR_SYNCSRC_Pos) /*!< 0x10000000 */ +#define CRS_CFGR_SYNCSRC_1 (0x2UL << CRS_CFGR_SYNCSRC_Pos) /*!< 0x20000000 */ +#define CRS_CFGR_SYNCPOL_Pos (31U) +#define CRS_CFGR_SYNCPOL_Msk (0x1UL << CRS_CFGR_SYNCPOL_Pos) /*!< 0x80000000 */ +#define CRS_CFGR_SYNCPOL CRS_CFGR_SYNCPOL_Msk /*!< SYNC polarity selection */ + +/******************* Bit definition for CRS_ISR register *********************/ +#define CRS_ISR_SYNCOKF_Pos (0U) +#define CRS_ISR_SYNCOKF_Msk (0x1UL << CRS_ISR_SYNCOKF_Pos) /*!< 0x00000001 */ +#define CRS_ISR_SYNCOKF CRS_ISR_SYNCOKF_Msk /*!< SYNC event OK flag */ +#define CRS_ISR_SYNCWARNF_Pos (1U) +#define CRS_ISR_SYNCWARNF_Msk (0x1UL << CRS_ISR_SYNCWARNF_Pos) /*!< 0x00000002 */ +#define CRS_ISR_SYNCWARNF CRS_ISR_SYNCWARNF_Msk /*!< SYNC warning flag */ +#define CRS_ISR_ERRF_Pos (2U) +#define CRS_ISR_ERRF_Msk (0x1UL << CRS_ISR_ERRF_Pos) /*!< 0x00000004 */ +#define CRS_ISR_ERRF CRS_ISR_ERRF_Msk /*!< Error flag */ +#define CRS_ISR_ESYNCF_Pos (3U) +#define CRS_ISR_ESYNCF_Msk (0x1UL << CRS_ISR_ESYNCF_Pos) /*!< 0x00000008 */ +#define CRS_ISR_ESYNCF CRS_ISR_ESYNCF_Msk /*!< Expected SYNC flag */ +#define CRS_ISR_SYNCERR_Pos (8U) +#define CRS_ISR_SYNCERR_Msk (0x1UL << CRS_ISR_SYNCERR_Pos) /*!< 0x00000100 */ +#define CRS_ISR_SYNCERR CRS_ISR_SYNCERR_Msk /*!< SYNC error */ +#define CRS_ISR_SYNCMISS_Pos (9U) +#define CRS_ISR_SYNCMISS_Msk (0x1UL << CRS_ISR_SYNCMISS_Pos) /*!< 0x00000200 */ +#define CRS_ISR_SYNCMISS CRS_ISR_SYNCMISS_Msk /*!< SYNC missed */ +#define CRS_ISR_TRIMOVF_Pos (10U) +#define CRS_ISR_TRIMOVF_Msk (0x1UL << CRS_ISR_TRIMOVF_Pos) /*!< 0x00000400 */ +#define CRS_ISR_TRIMOVF CRS_ISR_TRIMOVF_Msk /*!< Trimming overflow or underflow */ +#define CRS_ISR_FEDIR_Pos (15U) +#define CRS_ISR_FEDIR_Msk (0x1UL << CRS_ISR_FEDIR_Pos) /*!< 0x00008000 */ +#define CRS_ISR_FEDIR CRS_ISR_FEDIR_Msk /*!< Frequency error direction */ +#define CRS_ISR_FECAP_Pos (16U) +#define CRS_ISR_FECAP_Msk (0xFFFFUL << CRS_ISR_FECAP_Pos) /*!< 0xFFFF0000 */ +#define CRS_ISR_FECAP CRS_ISR_FECAP_Msk /*!< Frequency error capture */ + +/******************* Bit definition for CRS_ICR register *********************/ +#define CRS_ICR_SYNCOKC_Pos (0U) +#define CRS_ICR_SYNCOKC_Msk (0x1UL << CRS_ICR_SYNCOKC_Pos) /*!< 0x00000001 */ +#define CRS_ICR_SYNCOKC CRS_ICR_SYNCOKC_Msk /*!< SYNC event OK clear flag */ +#define CRS_ICR_SYNCWARNC_Pos (1U) +#define CRS_ICR_SYNCWARNC_Msk (0x1UL << CRS_ICR_SYNCWARNC_Pos) /*!< 0x00000002 */ +#define CRS_ICR_SYNCWARNC CRS_ICR_SYNCWARNC_Msk /*!< SYNC warning clear flag */ +#define CRS_ICR_ERRC_Pos (2U) +#define CRS_ICR_ERRC_Msk (0x1UL << CRS_ICR_ERRC_Pos) /*!< 0x00000004 */ +#define CRS_ICR_ERRC CRS_ICR_ERRC_Msk /*!< Error clear flag */ +#define CRS_ICR_ESYNCC_Pos (3U) +#define CRS_ICR_ESYNCC_Msk (0x1UL << CRS_ICR_ESYNCC_Pos) /*!< 0x00000008 */ +#define CRS_ICR_ESYNCC CRS_ICR_ESYNCC_Msk /*!< Expected SYNC clear flag */ + + +/******************************************************************************/ +/* */ +/* RNG */ +/* */ +/******************************************************************************/ +/******************** Bits definition for RNG_CR register *******************/ +#define RNG_CR_RNGEN_Pos (2U) +#define RNG_CR_RNGEN_Msk (0x1UL << RNG_CR_RNGEN_Pos) /*!< 0x00000004 */ +#define RNG_CR_RNGEN RNG_CR_RNGEN_Msk +#define RNG_CR_IE_Pos (3U) +#define RNG_CR_IE_Msk (0x1UL << RNG_CR_IE_Pos) /*!< 0x00000008 */ +#define RNG_CR_IE RNG_CR_IE_Msk +#define RNG_CR_CED_Pos (5U) +#define RNG_CR_CED_Msk (0x1UL << RNG_CR_CED_Pos) /*!< 0x00000020 */ +#define RNG_CR_CED RNG_CR_CED_Msk +#define RNG_CR_ARDIS_Pos (7U) +#define RNG_CR_ARDIS_Msk (0x1UL << RNG_CR_ARDIS_Pos) +#define RNG_CR_ARDIS RNG_CR_ARDIS_Msk +#define RNG_CR_RNG_CONFIG3_Pos (8U) +#define RNG_CR_RNG_CONFIG3_Msk (0xFUL << RNG_CR_RNG_CONFIG3_Pos) +#define RNG_CR_RNG_CONFIG3 RNG_CR_RNG_CONFIG3_Msk +#define RNG_CR_NISTC_Pos (12U) +#define RNG_CR_NISTC_Msk (0x1UL << RNG_CR_NISTC_Pos) +#define RNG_CR_NISTC RNG_CR_NISTC_Msk +#define RNG_CR_RNG_CONFIG2_Pos (13U) +#define RNG_CR_RNG_CONFIG2_Msk (0x7UL << RNG_CR_RNG_CONFIG2_Pos) +#define RNG_CR_RNG_CONFIG2 RNG_CR_RNG_CONFIG2_Msk +#define RNG_CR_CLKDIV_Pos (16U) +#define RNG_CR_CLKDIV_Msk (0xFUL << RNG_CR_CLKDIV_Pos) +#define RNG_CR_CLKDIV RNG_CR_CLKDIV_Msk +#define RNG_CR_CLKDIV_0 (0x1UL << RNG_CR_CLKDIV_Pos) /*!< 0x00010000 */ +#define RNG_CR_CLKDIV_1 (0x2UL << RNG_CR_CLKDIV_Pos) /*!< 0x00020000 */ +#define RNG_CR_CLKDIV_2 (0x4UL << RNG_CR_CLKDIV_Pos) /*!< 0x00040000 */ +#define RNG_CR_CLKDIV_3 (0x8UL << RNG_CR_CLKDIV_Pos) /*!< 0x00080000 */ +#define RNG_CR_RNG_CONFIG1_Pos (20U) +#define RNG_CR_RNG_CONFIG1_Msk (0x3FUL << RNG_CR_RNG_CONFIG1_Pos) +#define RNG_CR_RNG_CONFIG1 RNG_CR_RNG_CONFIG1_Msk +#define RNG_CR_CONDRST_Pos (30U) +#define RNG_CR_CONDRST_Msk (0x1UL << RNG_CR_CONDRST_Pos) +#define RNG_CR_CONDRST RNG_CR_CONDRST_Msk +#define RNG_CR_CONFIGLOCK_Pos (31U) +#define RNG_CR_CONFIGLOCK_Msk (0x1UL << RNG_CR_CONFIGLOCK_Pos) +#define RNG_CR_CONFIGLOCK RNG_CR_CONFIGLOCK_Msk + +/******************** Bits definition for RNG_SR register *******************/ +#define RNG_SR_DRDY_Pos (0U) +#define RNG_SR_DRDY_Msk (0x1UL << RNG_SR_DRDY_Pos) /*!< 0x00000001 */ +#define RNG_SR_DRDY RNG_SR_DRDY_Msk +#define RNG_SR_CECS_Pos (1U) +#define RNG_SR_CECS_Msk (0x1UL << RNG_SR_CECS_Pos) /*!< 0x00000002 */ +#define RNG_SR_CECS RNG_SR_CECS_Msk +#define RNG_SR_SECS_Pos (2U) +#define RNG_SR_SECS_Msk (0x1UL << RNG_SR_SECS_Pos) /*!< 0x00000004 */ +#define RNG_SR_SECS RNG_SR_SECS_Msk +#define RNG_SR_CEIS_Pos (5U) +#define RNG_SR_CEIS_Msk (0x1UL << RNG_SR_CEIS_Pos) /*!< 0x00000020 */ +#define RNG_SR_CEIS RNG_SR_CEIS_Msk +#define RNG_SR_SEIS_Pos (6U) +#define RNG_SR_SEIS_Msk (0x1UL << RNG_SR_SEIS_Pos) /*!< 0x00000040 */ +#define RNG_SR_SEIS RNG_SR_SEIS_Msk + +/******************** Bits definition for RNG_HTCR register *******************/ +#define RNG_HTCR_HTCFG_Pos (0U) +#define RNG_HTCR_HTCFG_Msk (0xFFFFFFFFUL << RNG_HTCR_HTCFG_Pos) /*!< 0xFFFFFFFF */ +#define RNG_HTCR_HTCFG RNG_HTCR_HTCFG_Msk + +/******************************************************************************/ +/* */ +/* Digital to Analog Converter */ +/* */ +/******************************************************************************/ +#define DAC_CHANNEL2_SUPPORT /*!< DAC feature available only on specific devices: DAC channel 2 available */ + +/******************** Bit definition for DAC_CR register ********************/ +#define DAC_CR_EN1_Pos (0U) +#define DAC_CR_EN1_Msk (0x1UL << DAC_CR_EN1_Pos) /*!< 0x00000001 */ +#define DAC_CR_EN1 DAC_CR_EN1_Msk /*!*/ +#define DAC_CR_CEN1_Pos (14U) +#define DAC_CR_CEN1_Msk (0x1UL << DAC_CR_CEN1_Pos) /*!< 0x00004000 */ +#define DAC_CR_CEN1 DAC_CR_CEN1_Msk /*!*/ +#define DAC_CR_EN2_Pos (16U) +#define DAC_CR_EN2_Msk (0x1UL << DAC_CR_EN2_Pos) /*!< 0x00010000 */ +#define DAC_CR_EN2 DAC_CR_EN2_Msk /*!*/ +#define DAC_CR_CEN2_Pos (30U) +#define DAC_CR_CEN2_Msk (0x1UL << DAC_CR_CEN2_Pos) /*!< 0x40000000 */ +#define DAC_CR_CEN2 DAC_CR_CEN2_Msk /*!*/ + +/***************** Bit definition for DAC_SWTRIGR register ******************/ +#define DAC_SWTRIGR_SWTRIG1_Pos (0U) +#define DAC_SWTRIGR_SWTRIG1_Msk (0x1UL << DAC_SWTRIGR_SWTRIG1_Pos) /*!< 0x00000001 */ +#define DAC_SWTRIGR_SWTRIG1 DAC_SWTRIGR_SWTRIG1_Msk /*!> 1U) /*!< FLASH Bank Size */ +#define FLASH_SECTOR_SIZE 0x2000U /*!< Flash Sector Size: 8 KB */ + +/******************* Bits definition for FLASH_ACR register *****************/ +#define FLASH_ACR_LATENCY_Pos (0U) +#define FLASH_ACR_LATENCY_Msk (0xFUL << FLASH_ACR_LATENCY_Pos) /*!< 0x0000000F */ +#define FLASH_ACR_LATENCY FLASH_ACR_LATENCY_Msk /*!< Latency */ +#define FLASH_ACR_LATENCY_0WS (0x00000000U) +#define FLASH_ACR_LATENCY_1WS (0x00000001U) +#define FLASH_ACR_LATENCY_2WS (0x00000002U) +#define FLASH_ACR_LATENCY_3WS (0x00000003U) +#define FLASH_ACR_LATENCY_4WS (0x00000004U) +#define FLASH_ACR_LATENCY_5WS (0x00000005U) +#define FLASH_ACR_LATENCY_6WS (0x00000006U) +#define FLASH_ACR_LATENCY_7WS (0x00000007U) +#define FLASH_ACR_LATENCY_8WS (0x00000008U) +#define FLASH_ACR_LATENCY_9WS (0x00000009U) +#define FLASH_ACR_LATENCY_10WS (0x0000000AU) +#define FLASH_ACR_LATENCY_11WS (0x0000000BU) +#define FLASH_ACR_LATENCY_12WS (0x0000000CU) +#define FLASH_ACR_LATENCY_13WS (0x0000000DU) +#define FLASH_ACR_LATENCY_14WS (0x0000000EU) +#define FLASH_ACR_LATENCY_15WS (0x0000000FU) +#define FLASH_ACR_WRHIGHFREQ_Pos (4U) +#define FLASH_ACR_WRHIGHFREQ_Msk (0x3UL << FLASH_ACR_WRHIGHFREQ_Pos) /*!< 0x00000030 */ +#define FLASH_ACR_WRHIGHFREQ FLASH_ACR_WRHIGHFREQ_Msk /*!< Flash signal delay */ +#define FLASH_ACR_WRHIGHFREQ_0 (0x1UL << FLASH_ACR_WRHIGHFREQ_Pos) /*!< 0x00000010 */ +#define FLASH_ACR_WRHIGHFREQ_1 (0x2UL << FLASH_ACR_WRHIGHFREQ_Pos) /*!< 0x00000020 */ +#define FLASH_ACR_PRFTEN_Pos (8U) +#define FLASH_ACR_PRFTEN_Msk (0x1UL << FLASH_ACR_PRFTEN_Pos) /*!< 0x00000100 */ +#define FLASH_ACR_PRFTEN FLASH_ACR_PRFTEN_Msk /*!< Prefetch enable */ + +/******************* Bits definition for FLASH_OPSR register ***************/ +#define FLASH_OPSR_ADDR_OP_Pos (0U) +#define FLASH_OPSR_ADDR_OP_Msk (0xFFFFFUL << FLASH_OPSR_ADDR_OP_Pos) /*!< 0x000FFFFF */ +#define FLASH_OPSR_ADDR_OP FLASH_OPSR_ADDR_OP_Msk /*!< Interrupted operation address */ +#define FLASH_OPSR_DATA_OP_Pos (21U) +#define FLASH_OPSR_DATA_OP_Msk (0x1UL << FLASH_OPSR_DATA_OP_Pos) /*!< 0x00200000 */ +#define FLASH_OPSR_DATA_OP FLASH_OPSR_DATA_OP_Msk /*!< Operation in Flash high-cycle data area interrupted */ +#define FLASH_OPSR_BK_OP_Pos (22U) +#define FLASH_OPSR_BK_OP_Msk (0x1UL << FLASH_OPSR_BK_OP_Pos) /*!< 0x00400000 */ +#define FLASH_OPSR_BK_OP FLASH_OPSR_BK_OP_Msk /*!< Interrupted operation bank */ +#define FLASH_OPSR_SYSF_OP_Pos (23U) +#define FLASH_OPSR_SYSF_OP_Msk (0x1UL << FLASH_OPSR_SYSF_OP_Pos) /*!< 0x00800000 */ +#define FLASH_OPSR_SYSF_OP FLASH_OPSR_SYSF_OP_Msk /*!< Operation in System Flash interrupted */ +#define FLASH_OPSR_OTP_OP_Pos (24U) +#define FLASH_OPSR_OTP_OP_Msk (0x1UL << FLASH_OPSR_OTP_OP_Pos) /*!< 0x01000000 */ +#define FLASH_OPSR_OTP_OP FLASH_OPSR_OTP_OP_Msk /*!< Operation in OTP area interrupted */ +#define FLASH_OPSR_CODE_OP_Pos (29U) +#define FLASH_OPSR_CODE_OP_Msk (0x7UL << FLASH_OPSR_CODE_OP_Pos) /*!< 0xE0000000 */ +#define FLASH_OPSR_CODE_OP FLASH_OPSR_CODE_OP_Msk /*!< Flash memory operation code */ +#define FLASH_OPSR_CODE_OP_0 (0x1UL << FLASH_OPSR_CODE_OP_Pos) /*!< 0x20000000 */ +#define FLASH_OPSR_CODE_OP_1 (0x2UL << FLASH_OPSR_CODE_OP_Pos) /*!< 0x40000000 */ +#define FLASH_OPSR_CODE_OP_2 (0x4UL << FLASH_OPSR_CODE_OP_Pos) /*!< 0x80000000 */ + +/******************* Bits definition for FLASH_OPTCR register *******************/ +#define FLASH_OPTCR_OPTLOCK_Pos (0U) +#define FLASH_OPTCR_OPTLOCK_Msk (0x1UL << FLASH_OPTCR_OPTLOCK_Pos) /*!< 0x00000001 */ +#define FLASH_OPTCR_OPTLOCK FLASH_OPTCR_OPTLOCK_Msk /*!< FLASH_OPTCR lock option configuration bit */ +#define FLASH_OPTCR_OPTSTART_Pos (1U) +#define FLASH_OPTCR_OPTSTART_Msk (0x1UL << FLASH_OPTCR_OPTSTART_Pos) /*!< 0x00000002 */ +#define FLASH_OPTCR_OPTSTART FLASH_OPTCR_OPTSTART_Msk /*!< Option byte start change option configuration bit */ +#define FLASH_OPTCR_SWAP_BANK_Pos (31U) +#define FLASH_OPTCR_SWAP_BANK_Msk (0x1UL << FLASH_OPTCR_SWAP_BANK_Pos) /*!< 0x80000000 */ +#define FLASH_OPTCR_SWAP_BANK FLASH_OPTCR_SWAP_BANK_Msk /*!< Bank swapping option configuration bit */ + +/******************* Bits definition for FLASH_SR register ***********************/ +#define FLASH_SR_BSY_Pos (0U) +#define FLASH_SR_BSY_Msk (0x1UL << FLASH_SR_BSY_Pos) /*!< 0x00000001 */ +#define FLASH_SR_BSY FLASH_SR_BSY_Msk /*!< Busy flag */ +#define FLASH_SR_WBNE_Pos (1U) +#define FLASH_SR_WBNE_Msk (0x1UL << FLASH_SR_WBNE_Pos) /*!< 0x00000002 */ +#define FLASH_SR_WBNE FLASH_SR_WBNE_Msk /*!< Write buffer not empty flag */ +#define FLASH_SR_DBNE_Pos (3U) +#define FLASH_SR_DBNE_Msk (0x1UL << FLASH_SR_DBNE_Pos) /*!< 0x00000008 */ +#define FLASH_SR_DBNE FLASH_SR_DBNE_Msk /*!< Data buffer not empty flag */ +#define FLASH_SR_EOP_Pos (16U) +#define FLASH_SR_EOP_Msk (0x1UL << FLASH_SR_EOP_Pos) /*!< 0x00010000 */ +#define FLASH_SR_EOP FLASH_SR_EOP_Msk /*!< End-of-program flag */ +#define FLASH_SR_WRPERR_Pos (17U) +#define FLASH_SR_WRPERR_Msk (0x1UL << FLASH_SR_WRPERR_Pos) /*!< 0x00020000 */ +#define FLASH_SR_WRPERR FLASH_SR_WRPERR_Msk /*!< Write protection error flag */ +#define FLASH_SR_PGSERR_Pos (18U) +#define FLASH_SR_PGSERR_Msk (0x1UL << FLASH_SR_PGSERR_Pos) /*!< 0x00040000 */ +#define FLASH_SR_PGSERR FLASH_SR_PGSERR_Msk /*!< Programming sequence error flag */ +#define FLASH_SR_STRBERR_Pos (19U) +#define FLASH_SR_STRBERR_Msk (0x1UL << FLASH_SR_STRBERR_Pos) /*!< 0x00080000 */ +#define FLASH_SR_STRBERR FLASH_SR_STRBERR_Msk /*!< Strobe error flag */ +#define FLASH_SR_INCERR_Pos (20U) +#define FLASH_SR_INCERR_Msk (0x1UL << FLASH_SR_INCERR_Pos) /*!< 0x00100000 */ +#define FLASH_SR_INCERR FLASH_SR_INCERR_Msk /*!< Inconsistency error flag */ +#define FLASH_SR_OBKERR_Pos (21U) +#define FLASH_SR_OBKERR_Msk (0x1UL << FLASH_SR_OBKERR_Pos) /*!< 0x00200000 */ +#define FLASH_SR_OBKERR FLASH_SR_OBKERR_Msk /*!< OBK general error flag */ +#define FLASH_SR_OBKWERR_Pos (22U) +#define FLASH_SR_OBKWERR_Msk (0x1UL << FLASH_SR_OBKWERR_Pos) /*!< 0x00400000 */ +#define FLASH_SR_OBKWERR FLASH_SR_OBKWERR_Msk /*!< OBK write error flag */ +#define FLASH_SR_OPTCHANGEERR_Pos (23U) +#define FLASH_SR_OPTCHANGEERR_Msk (0x1UL << FLASH_SR_OPTCHANGEERR_Pos) /*!< 0x00800000 */ +#define FLASH_SR_OPTCHANGEERR FLASH_SR_OPTCHANGEERR_Msk /*!< Option byte change error flag */ + +/******************* Bits definition for FLASH_CR register ***********************/ +#define FLASH_CR_LOCK_Pos (0U) +#define FLASH_CR_LOCK_Msk (0x1UL << FLASH_CR_LOCK_Pos) /*!< 0x00000001 */ +#define FLASH_CR_LOCK FLASH_CR_LOCK_Msk /*!< Configuration lock bit */ +#define FLASH_CR_PG_Pos (1U) +#define FLASH_CR_PG_Msk (0x1UL << FLASH_CR_PG_Pos) /*!< 0x00000002 */ +#define FLASH_CR_PG FLASH_CR_PG_Msk /*!< Programming control bit */ +#define FLASH_CR_SER_Pos (2U) +#define FLASH_CR_SER_Msk (0x1UL << FLASH_CR_SER_Pos) /*!< 0x00000004 */ +#define FLASH_CR_SER FLASH_CR_SER_Msk /*!< Sector erase request */ +#define FLASH_CR_BER_Pos (3U) +#define FLASH_CR_BER_Msk (0x1UL << FLASH_CR_BER_Pos) /*!< 0x00000008 */ +#define FLASH_CR_BER FLASH_CR_BER_Msk /*!< Bank erase request */ +#define FLASH_CR_FW_Pos (4U) +#define FLASH_CR_FW_Msk (0x1UL << FLASH_CR_FW_Pos) /*!< 0x00000010 */ +#define FLASH_CR_FW FLASH_CR_FW_Msk /*!< Write forcing control bit */ +#define FLASH_CR_START_Pos (5U) +#define FLASH_CR_START_Msk (0x1UL << FLASH_CR_START_Pos) /*!< 0x00000020 */ +#define FLASH_CR_START FLASH_CR_START_Msk /*!< Erase start control bit */ +#define FLASH_CR_SNB_Pos (6U) +#define FLASH_CR_SNB_Msk (0x7FUL << FLASH_CR_SNB_Pos) /*!< 0x00001FC0 */ +#define FLASH_CR_SNB FLASH_CR_SNB_Msk /*!< Sector erase selection number */ +#define FLASH_CR_SNB_0 (0x01UL << FLASH_CR_SNB_Pos) /*!< 0x00000040 */ +#define FLASH_CR_SNB_1 (0x02UL << FLASH_CR_SNB_Pos) /*!< 0x00000080 */ +#define FLASH_CR_SNB_2 (0x04UL << FLASH_CR_SNB_Pos) /*!< 0x00000100 */ +#define FLASH_CR_SNB_3 (0x08UL << FLASH_CR_SNB_Pos) /*!< 0x00000200 */ +#define FLASH_CR_SNB_4 (0x10UL << FLASH_CR_SNB_Pos) /*!< 0x00000400 */ +#define FLASH_CR_SNB_5 (0x20UL << FLASH_CR_SNB_Pos) /*!< 0x00000800 */ +#define FLASH_CR_SNB_6 (0x40UL << FLASH_CR_SNB_Pos) /*!< 0x00001000 */ +#define FLASH_CR_MER_Pos (15U) +#define FLASH_CR_MER_Msk (0x1UL << FLASH_CR_MER_Pos) /*!< 0x00008000 */ +#define FLASH_CR_MER FLASH_CR_MER_Msk /*!< Mass erase */ +#define FLASH_CR_EOPIE_Pos (16U) +#define FLASH_CR_EOPIE_Msk (0x1UL << FLASH_CR_EOPIE_Pos) /*!< 0x00010000 */ +#define FLASH_CR_EOPIE FLASH_CR_EOPIE_Msk /*!< End-of-operation interrupt control bit */ +#define FLASH_CR_WRPERRIE_Pos (17U) +#define FLASH_CR_WRPERRIE_Msk (0x1UL << FLASH_CR_WRPERRIE_Pos) /*!< 0x00020000 */ +#define FLASH_CR_WRPERRIE FLASH_CR_WRPERRIE_Msk /*!< Write protection error interrupt enable bit */ +#define FLASH_CR_PGSERRIE_Pos (18U) +#define FLASH_CR_PGSERRIE_Msk (0x1UL << FLASH_CR_PGSERRIE_Pos) /*!< 0x00040000 */ +#define FLASH_CR_PGSERRIE FLASH_CR_PGSERRIE_Msk /*!< Programming sequence error interrupt enable bit */ +#define FLASH_CR_STRBERRIE_Pos (19U) +#define FLASH_CR_STRBERRIE_Msk (0x1UL << FLASH_CR_STRBERRIE_Pos) /*!< 0x00080000 */ +#define FLASH_CR_STRBERRIE FLASH_CR_STRBERRIE_Msk /*!< Strobe error interrupt enable bit */ +#define FLASH_CR_INCERRIE_Pos (20U) +#define FLASH_CR_INCERRIE_Msk (0x1UL << FLASH_CR_INCERRIE_Pos) /*!< 0x00100000 */ +#define FLASH_CR_INCERRIE FLASH_CR_INCERRIE_Msk /*!< Inconsistency error interrupt enable bit */ +#define FLASH_CR_OBKERRIE_Pos (21U) +#define FLASH_CR_OBKERRIE_Msk (0x1UL << FLASH_CR_OBKERRIE_Pos) /*!< 0x00200000 */ +#define FLASH_CR_OBKERRIE FLASH_CR_OBKERRIE_Msk /*!< OBK general error interrupt enable bitt */ +#define FLASH_CR_OBKWERRIE_Pos (22U) +#define FLASH_CR_OBKWERRIE_Msk (0x1UL << FLASH_CR_OBKWERRIE_Pos) /*!< 0x00400000 */ +#define FLASH_CR_OBKWERRIE FLASH_CR_OBKWERRIE_Msk /*!< OBK write error interrupt enable bit */ +#define FLASH_CR_OPTCHANGEERRIE_Pos (23U) +#define FLASH_CR_OPTCHANGEERRIE_Msk (0x1UL << FLASH_CR_OPTCHANGEERRIE_Pos) /*!< 0x00800000 */ +#define FLASH_CR_OPTCHANGEERRIE FLASH_CR_OPTCHANGEERRIE_Msk /*!< Option byte change error interrupt enable bit */ +#define FLASH_CR_INV_Pos (29U) +#define FLASH_CR_INV_Msk (0x1UL << FLASH_CR_INV_Pos) /*!< 0x20000000 */ +#define FLASH_CR_INV FLASH_CR_INV_Msk /*!< Flash Security State Invert */ +#define FLASH_CR_BKSEL_Pos (31U) +#define FLASH_CR_BKSEL_Msk (0x1UL << FLASH_CR_BKSEL_Pos) /*!< 0x10000000 */ +#define FLASH_CR_BKSEL FLASH_CR_BKSEL_Msk /*!< Bank selector */ + +/******************* Bits definition for FLASH_CCR register *******************/ +#define FLASH_CCR_CLR_EOP_Pos (16U) +#define FLASH_CCR_CLR_EOP_Msk (0x1UL << FLASH_CCR_CLR_EOP_Pos) /*!< 0x00010000 */ +#define FLASH_CCR_CLR_EOP FLASH_CCR_CLR_EOP_Msk /*!< EOP flag clear bit */ +#define FLASH_CCR_CLR_WRPERR_Pos (17U) +#define FLASH_CCR_CLR_WRPERR_Msk (0x1UL << FLASH_CCR_CLR_WRPERR_Pos) /*!< 0x00020000 */ +#define FLASH_CCR_CLR_WRPERR FLASH_CCR_CLR_WRPERR_Msk /*!< WRPERR flag clear bit */ +#define FLASH_CCR_CLR_PGSERR_Pos (18U) +#define FLASH_CCR_CLR_PGSERR_Msk (0x1UL << FLASH_CCR_CLR_PGSERR_Pos) /*!< 0x00040000 */ +#define FLASH_CCR_CLR_PGSERR FLASH_CCR_CLR_PGSERR_Msk /*!< PGSERR flag clear bit */ +#define FLASH_CCR_CLR_STRBERR_Pos (19U) +#define FLASH_CCR_CLR_STRBERR_Msk (0x1UL << FLASH_CCR_CLR_STRBERR_Pos) /*!< 0x00080000 */ +#define FLASH_CCR_CLR_STRBERR FLASH_CCR_CLR_STRBERR_Msk /*!< STRBERR flag clear bit */ +#define FLASH_CCR_CLR_INCERR_Pos (20U) +#define FLASH_CCR_CLR_INCERR_Msk (0x1UL << FLASH_CCR_CLR_INCERR_Pos) /*!< 0x00100000 */ +#define FLASH_CCR_CLR_INCERR FLASH_CCR_CLR_INCERR_Msk /*!< INCERR flag clear bit */ +#define FLASH_CCR_CLR_OBKERR_Pos (21U) +#define FLASH_CCR_CLR_OBKERR_Msk (0x1UL << FLASH_CCR_CLR_OBKERR_Pos) /*!< 0x00200000 */ +#define FLASH_CCR_CLR_OBKERR FLASH_CCR_CLR_OBKERR_Msk /*!< OBKERR flag clear bit */ +#define FLASH_CCR_CLR_OBKWERR_Pos (22U) +#define FLASH_CCR_CLR_OBKWERR_Msk (0x1UL << FLASH_CCR_CLR_OBKWERR_Pos) /*!< 0x00400000 */ +#define FLASH_CCR_CLR_OBKWERR FLASH_CCR_CLR_OBKWERR_Msk /*!< OBKWERR flag clear bit */ +#define FLASH_CCR_CLR_OPTCHANGEERR_Pos (23U) +#define FLASH_CCR_CLR_OPTCHANGEERR_Msk (0x1UL << FLASH_CCR_CLR_OPTCHANGEERR_Pos) /*!< 0x00800000 */ +#define FLASH_CCR_CLR_OPTCHANGEERR FLASH_CCR_CLR_OPTCHANGEERR_Msk /*!< Option byte change error clear bit */ + +/****************** Bits definition for FLASH_PRIVCFGR register ***********/ +#define FLASH_PRIVCFGR_SPRIV_Pos (0U) +#define FLASH_PRIVCFGR_SPRIV_Msk (0x1UL << FLASH_PRIVCFGR_SPRIV_Pos) /*!< 0x00000001 */ +#define FLASH_PRIVCFGR_SPRIV FLASH_PRIVCFGR_SPRIV_Msk /*!< Privilege protection for secure registers */ +#define FLASH_PRIVCFGR_NSPRIV_Pos (1U) +#define FLASH_PRIVCFGR_NSPRIV_Msk (0x1UL << FLASH_PRIVCFGR_NSPRIV_Pos) /*!< 0x00000002 */ +#define FLASH_PRIVCFGR_NSPRIV FLASH_PRIVCFGR_NSPRIV_Msk /*!< Privilege protection for non-secure registers */ + +/****************** Bits definition for FLASH_OBKCFGR register *****************/ +#define FLASH_OBKCFGR_LOCK_Pos (0U) +#define FLASH_OBKCFGR_LOCK_Msk (0x1UL << FLASH_OBKCFGR_LOCK_Pos) /*!< 0x00000001 */ +#define FLASH_OBKCFGR_LOCK FLASH_OBKCFGR_LOCK_Msk /*!< OBKCFGR lock */ +#define FLASH_OBKCFGR_SWAP_SECT_REQ_Pos (1U) +#define FLASH_OBKCFGR_SWAP_SECT_REQ_Msk (0x1UL << FLASH_OBKCFGR_SWAP_SECT_REQ_Pos) /*!< 0x00000002 */ +#define FLASH_OBKCFGR_SWAP_SECT_REQ FLASH_OBKCFGR_SWAP_SECT_REQ_Msk /*!< OBK swap sector request */ +#define FLASH_OBKCFGR_ALT_SECT_Pos (2U) +#define FLASH_OBKCFGR_ALT_SECT_Msk (0x1UL << FLASH_OBKCFGR_ALT_SECT_Pos) /*!< 0x00000004 */ +#define FLASH_OBKCFGR_ALT_SECT FLASH_OBKCFGR_ALT_SECT_Msk /*!< Alternate sector */ +#define FLASH_OBKCFGR_ALT_SECT_ERASE_Pos (3U) +#define FLASH_OBKCFGR_ALT_SECT_ERASE_Msk (0x1UL << FLASH_OBKCFGR_ALT_SECT_ERASE_Pos) /*!< 0x00000008 */ +#define FLASH_OBKCFGR_ALT_SECT_ERASE FLASH_OBKCFGR_ALT_SECT_ERASE_Msk /*!< Alternate sector erase */ +#define FLASH_OBKCFGR_SWAP_OFFSET_Pos (16U) +#define FLASH_OBKCFGR_SWAP_OFFSET_Msk (0x1FFUL << FLASH_OBKCFGR_SWAP_OFFSET_Pos) /*!< 0x01FF0000 */ +#define FLASH_OBKCFGR_SWAP_OFFSET FLASH_OBKCFGR_SWAP_OFFSET_Msk /*!< Swap offset */ + +/****************** Bits definition for FLASH_HDPEXTR register *****************/ +#define FLASH_HDPEXTR_HDP1_EXT_Pos (0U) +#define FLASH_HDPEXTR_HDP1_EXT_Msk (0x7FUL << FLASH_HDPEXTR_HDP1_EXT_Pos) /*!< 0x0000007F */ +#define FLASH_HDPEXTR_HDP1_EXT FLASH_HDPEXTR_HDP1_EXT_Msk /*!< HDP area extension in 8kB sectors in bank 1 */ +#define FLASH_HDPEXTR_HDP2_EXT_Pos (16U) +#define FLASH_HDPEXTR_HDP2_EXT_Msk (0x7FUL << FLASH_HDPEXTR_HDP2_EXT_Pos) /*!< 0x007F0000 */ +#define FLASH_HDPEXTR_HDP2_EXT FLASH_HDPEXTR_HDP2_EXT_Msk /*!< HDP area extension in 8kB sectors in bank 2 */ + +/******************* Bits definition for FLASH_OPTSR register ***************/ +#define FLASH_OPTSR_BOR_LEV_Pos (0U) +#define FLASH_OPTSR_BOR_LEV_Msk (0x3UL << FLASH_OPTSR_BOR_LEV_Pos) /*!< 0x00000003 */ +#define FLASH_OPTSR_BOR_LEV FLASH_OPTSR_BOR_LEV_Msk /*!< Brownout level option bit */ +#define FLASH_OPTSR_BOR_LEV_0 (0x1UL << FLASH_OPTSR_BOR_LEV_Pos) /*!< 0x00000001 */ +#define FLASH_OPTSR_BOR_LEV_1 (0x2UL << FLASH_OPTSR_BOR_LEV_Pos) /*!< 0x00000002 */ +#define FLASH_OPTSR_BORH_EN_Pos (2U) +#define FLASH_OPTSR_BORH_EN_Msk (0x1UL << FLASH_OPTSR_BORH_EN_Pos) /*!< 0x00000004 */ +#define FLASH_OPTSR_BORH_EN FLASH_OPTSR_BORH_EN_Msk /*!< Brownout high enable configuration bit */ +#define FLASH_OPTSR_IWDG_SW_Pos (3U) +#define FLASH_OPTSR_IWDG_SW_Msk (0x1UL << FLASH_OPTSR_IWDG_SW_Pos) /*!< 0x00000008 */ +#define FLASH_OPTSR_IWDG_SW FLASH_OPTSR_IWDG_SW_Msk /*!< IWDG control mode option bit */ +#define FLASH_OPTSR_WWDG_SW_Pos (4U) +#define FLASH_OPTSR_WWDG_SW_Msk (0x1UL << FLASH_OPTSR_WWDG_SW_Pos) /*!< 0x00000010 */ +#define FLASH_OPTSR_WWDG_SW FLASH_OPTSR_WWDG_SW_Msk /*!< WWDG control mode option bit */ +#define FLASH_OPTSR_NRST_STOP_Pos (6U) +#define FLASH_OPTSR_NRST_STOP_Msk (0x1UL << FLASH_OPTSR_NRST_STOP_Pos) /*!< 0x00000040 */ +#define FLASH_OPTSR_NRST_STOP FLASH_OPTSR_NRST_STOP_Msk /*!< Stop mode entry reset option bit */ +#define FLASH_OPTSR_NRST_STDBY_Pos (7U) +#define FLASH_OPTSR_NRST_STDBY_Msk (0x1UL << FLASH_OPTSR_NRST_STDBY_Pos) /*!< 0x00000080 */ +#define FLASH_OPTSR_NRST_STDBY FLASH_OPTSR_NRST_STDBY_Msk /*!< Standby mode entry reset option bit */ +#define FLASH_OPTSR_PRODUCT_STATE_Pos (8U) +#define FLASH_OPTSR_PRODUCT_STATE_Msk (0xFFUL << FLASH_OPTSR_PRODUCT_STATE_Pos) /*!< 0x0000FF00 */ +#define FLASH_OPTSR_PRODUCT_STATE FLASH_OPTSR_PRODUCT_STATE_Msk /*!< Life state code option byte */ +#define FLASH_OPTSR_IO_VDD_HSLV_Pos (16U) +#define FLASH_OPTSR_IO_VDD_HSLV_Msk (0x1UL << FLASH_OPTSR_IO_VDD_HSLV_Pos) /*!< 0x00010000 */ +#define FLASH_OPTSR_IO_VDD_HSLV FLASH_OPTSR_IO_VDD_HSLV_Msk /*!< VDD I/O high-speed at low-voltage option bit */ +#define FLASH_OPTSR_IO_VDDIO2_HSLV_Pos (17U) +#define FLASH_OPTSR_IO_VDDIO2_HSLV_Msk (0x1UL << FLASH_OPTSR_IO_VDDIO2_HSLV_Pos) /*!< 0x00020000 */ +#define FLASH_OPTSR_IO_VDDIO2_HSLV FLASH_OPTSR_IO_VDDIO2_HSLV_Msk /*!< VDDIO2 I/O high-speed at low-voltage option bit */ +#define FLASH_OPTSR_IWDG_STOP_Pos (20U) +#define FLASH_OPTSR_IWDG_STOP_Msk (0x1UL << FLASH_OPTSR_IWDG_STOP_Pos) /*!< 0x00100000 */ +#define FLASH_OPTSR_IWDG_STOP FLASH_OPTSR_IWDG_STOP_Msk /*!< Independent watchdog counter freeze in Stop mode */ +#define FLASH_OPTSR_IWDG_STDBY_Pos (21U) +#define FLASH_OPTSR_IWDG_STDBY_Msk (0x1UL << FLASH_OPTSR_IWDG_STDBY_Pos) /*!< 0x00200000 */ +#define FLASH_OPTSR_IWDG_STDBY FLASH_OPTSR_IWDG_STDBY_Msk /*!< Independent watchdog counter freeze in Standby mode */ +#define FLASH_OPTSR_BOOT_UBE_Pos (22U) +#define FLASH_OPTSR_BOOT_UBE_Msk (0xFFUL << FLASH_OPTSR_BOOT_UBE_Pos) /*!< 0x3FC00000 */ +#define FLASH_OPTSR_BOOT_UBE FLASH_OPTSR_BOOT_UBE_Msk /*!< Unique boot entry option byte */ +#define FLASH_OPTSR_SWAP_BANK_Pos (31U) +#define FLASH_OPTSR_SWAP_BANK_Msk (0x1UL << FLASH_OPTSR_SWAP_BANK_Pos) /*!< 0x80000000 */ +#define FLASH_OPTSR_SWAP_BANK FLASH_OPTSR_SWAP_BANK_Msk /*!< Bank swapping option bit */ + +/******************* Bits definition for FLASH_EPOCHR register ***************/ +#define FLASH_EPOCHR_EPOCH_Pos (0U) +#define FLASH_EPOCHR_EPOCH_Msk (0xFFFFFFUL << FLASH_EPOCHR_EPOCH_Pos) /*!< 0x00FFFFFF */ +#define FLASH_EPOCHR_EPOCH FLASH_EPOCHR_EPOCH_Msk /*!< EPOCH counter */ + +/******************* Bits definition for FLASH_OPTSR2 register ***************/ +#define FLASH_OPTSR2_SRAM1_3_RST_Pos (2U) +#define FLASH_OPTSR2_SRAM1_3_RST_Msk (0x1UL << FLASH_OPTSR2_SRAM1_3_RST_Pos) /*!< 0x00000004 */ +#define FLASH_OPTSR2_SRAM1_3_RST FLASH_OPTSR2_SRAM1_3_RST_Msk /*!< SRAM1 and SRAM3 erased when a system reset occurs */ +#define FLASH_OPTSR2_SRAM2_RST_Pos (3U) +#define FLASH_OPTSR2_SRAM2_RST_Msk (0x1UL << FLASH_OPTSR2_SRAM2_RST_Pos) /*!< 0x00000008 */ +#define FLASH_OPTSR2_SRAM2_RST FLASH_OPTSR2_SRAM2_RST_Msk /*!< SRAM2 erased when a system reset occurs*/ +#define FLASH_OPTSR2_BKPRAM_ECC_Pos (4U) +#define FLASH_OPTSR2_BKPRAM_ECC_Msk (0x1UL << FLASH_OPTSR2_BKPRAM_ECC_Pos) /*!< 0x00000010 */ +#define FLASH_OPTSR2_BKPRAM_ECC FLASH_OPTSR2_BKPRAM_ECC_Msk /*!< Backup RAM ECC detection and correction enable */ +#define FLASH_OPTSR2_SRAM3_ECC_Pos (5U) +#define FLASH_OPTSR2_SRAM3_ECC_Msk (0x1UL << FLASH_OPTSR2_SRAM3_ECC_Pos) /*!< 0x00000020 */ +#define FLASH_OPTSR2_SRAM3_ECC FLASH_OPTSR2_SRAM3_ECC_Msk /*!< SRAM3 ECC detection and correction enable */ +#define FLASH_OPTSR2_SRAM2_ECC_Pos (6U) +#define FLASH_OPTSR2_SRAM2_ECC_Msk (0x1UL << FLASH_OPTSR2_SRAM2_ECC_Pos) /*!< 0x00000040 */ +#define FLASH_OPTSR2_SRAM2_ECC FLASH_OPTSR2_SRAM2_ECC_Msk /*!< SRAM2 ECC detection and correction disable */ +#define FLASH_OPTSR2_TZEN_Pos (24U) +#define FLASH_OPTSR2_TZEN_Msk (0xFFUL << FLASH_OPTSR2_TZEN_Pos) /*!< 0xFF000000 */ +#define FLASH_OPTSR2_TZEN FLASH_OPTSR2_TZEN_Msk /*!< TrustZone enable */ + +/**************** Bits definition for FLASH_BOOTR register **********************/ +#define FLASH_BOOTR_BOOT_LOCK_Pos (0U) +#define FLASH_BOOTR_BOOT_LOCK_Msk (0xFFUL << FLASH_BOOTR_BOOT_LOCK_Pos) /*!< 0x000000FF */ +#define FLASH_BOOTR_BOOT_LOCK FLASH_BOOTR_BOOT_LOCK_Msk /*!< Boot Lock */ +#define FLASH_BOOTR_BOOTADD_Pos (8U) +#define FLASH_BOOTR_BOOTADD_Msk (0xFFFFFFUL << FLASH_BOOTR_BOOTADD_Pos) /*!< 0xFFFFFF00 */ +#define FLASH_BOOTR_BOOTADD FLASH_BOOTR_BOOTADD_Msk /*!< Boot address */ + +/**************** Bits definition for FLASH_PRIVBBR register *******************/ +#define FLASH_PRIVBBR_PRIVBB_Pos (0U) +#define FLASH_PRIVBBR_PRIVBB_Msk (0xFFFFFFFFUL << FLASH_PRIVBBR_PRIVBB_Pos) /*!< 0xFFFFFFFF */ +#define FLASH_PRIVBBR_PRIVBB FLASH_PRIVBBR_PRIVBB_Msk /*!< Privileged/unprivileged 8-Kbyte Flash sector attribute */ + +/***************** Bits definition for FLASH_SECWMR register ********************/ +#define FLASH_SECWMR_SECWM_STRT_Pos (0U) +#define FLASH_SECWMR_SECWM_STRT_Msk (0x7FUL << FLASH_SECWMR_SECWM_STRT_Pos) /*!< 0x0000007F */ +#define FLASH_SECWMR_SECWM_STRT FLASH_SECWMR_SECWM_STRT_Msk /*!< Start sector of secure area */ +#define FLASH_SECWMR_SECWM_END_Pos (16U) +#define FLASH_SECWMR_SECWM_END_Msk (0x7FUL << FLASH_SECWMR_SECWM_END_Pos) /*!< 0x007F0000 */ +#define FLASH_SECWMR_SECWM_END FLASH_SECWMR_SECWM_END_Msk /*!< End sector of secure area */ + +/***************** Bits definition for FLASH_WRPR register *********************/ +#define FLASH_WRPR_WRPSG_Pos (0U) +#define FLASH_WRPR_WRPSG_Msk (0xFFFFFFFFUL << FLASH_WRPR_WRPSG_Pos) /*!< 0xFFFFFFFF */ +#define FLASH_WRPR_WRPSG FLASH_WRPR_WRPSG_Msk /*!< Sector group protection option status */ + +/***************** Bits definition for FLASH_EDATA register ********************/ +#define FLASH_EDATAR_EDATA_STRT_Pos (0U) +#define FLASH_EDATAR_EDATA_STRT_Msk (0x3UL << FLASH_EDATAR_EDATA_STRT_Pos) /*!< 0x00000003 */ +#define FLASH_EDATAR_EDATA_STRT FLASH_EDATAR_EDATA_STRT_Msk /*!< Flash high-cycle data start sector */ +#define FLASH_EDATAR_EDATA_EN_Pos (15U) +#define FLASH_EDATAR_EDATA_EN_Msk (0x1UL << FLASH_EDATAR_EDATA_EN_Pos) /*!< 0x00008000 */ +#define FLASH_EDATAR_EDATA_EN FLASH_EDATAR_EDATA_EN_Msk /*!< Flash high-cycle data enable */ + +/***************** Bits definition for FLASH_HDPR register ********************/ +#define FLASH_HDPR_HDP_STRT_Pos (0U) +#define FLASH_HDPR_HDP_STRT_Msk (0x7FUL << FLASH_HDPR_HDP_STRT_Pos) /*!< 0x0000007F */ +#define FLASH_HDPR_HDP_STRT FLASH_HDPR_HDP_STRT_Msk /*!< Start sector of hide protection area */ +#define FLASH_HDPR_HDP_END_Pos (16U) +#define FLASH_HDPR_HDP_END_Msk (0x7FUL << FLASH_HDPR_HDP_END_Pos) /*!< 0x007F0000 */ +#define FLASH_HDPR_HDP_END FLASH_HDPR_HDP_END_Msk /*!< End sector of hide protection area */ + +/******************* Bits definition for FLASH_ECCR register ***************/ +#define FLASH_ECCR_ADDR_ECC_Pos (0U) +#define FLASH_ECCR_ADDR_ECC_Msk (0xFFFFUL << FLASH_ECCR_ADDR_ECC_Pos) /*!< 0x0000FFFF */ +#define FLASH_ECCR_ADDR_ECC FLASH_ECCR_ADDR_ECC_Msk /*!< ECC fail address */ +#define FLASH_ECCR_OBK_ECC_Pos (20U) +#define FLASH_ECCR_OBK_ECC_Msk (0x1UL << FLASH_ECCR_OBK_ECC_Pos) /*!< 0x00200000 */ +#define FLASH_ECCR_OBK_ECC FLASH_ECCR_OBK_ECC_Msk /*!< Flash OB Keys storage area ECC fail */ +#define FLASH_ECCR_DATA_ECC_Pos (21U) +#define FLASH_ECCR_DATA_ECC_Msk (0x1UL << FLASH_ECCR_DATA_ECC_Pos) /*!< 0x00400000 */ +#define FLASH_ECCR_DATA_ECC FLASH_ECCR_DATA_ECC_Msk /*!< Flash high-cycle data ECC fail */ +#define FLASH_ECCR_BK_ECC_Pos (22U) +#define FLASH_ECCR_BK_ECC_Msk (0x1UL << FLASH_ECCR_BK_ECC_Pos) /*!< 0x00400000 */ +#define FLASH_ECCR_BK_ECC FLASH_ECCR_BK_ECC_Msk /*!< ECC fail bank */ +#define FLASH_ECCR_SYSF_ECC_Pos (23U) +#define FLASH_ECCR_SYSF_ECC_Msk (0x1UL << FLASH_ECCR_SYSF_ECC_Pos) /*!< 0x00800000 */ +#define FLASH_ECCR_SYSF_ECC FLASH_ECCR_SYSF_ECC_Msk /*!< System Flash ECC fail */ +#define FLASH_ECCR_OTP_ECC_Pos (24U) +#define FLASH_ECCR_OTP_ECC_Msk (0x1UL << FLASH_ECCR_OTP_ECC_Pos) /*!< 0x01000000 */ +#define FLASH_ECCR_OTP_ECC FLASH_ECCR_OTP_ECC_Msk /*!< Flash OTP ECC fail */ +#define FLASH_ECCR_ECCIE_Pos (25U) +#define FLASH_ECCR_ECCIE_Msk (0x1UL << FLASH_ECCR_ECCIE_Pos) /*!< 0x02000000 */ +#define FLASH_ECCR_ECCIE FLASH_ECCR_ECCIE_Msk /*!< ECC correction interrupt enable */ +#define FLASH_ECCR_ECCC_Pos (30U) +#define FLASH_ECCR_ECCC_Msk (0x1UL << FLASH_ECCR_ECCC_Pos) /*!< 0x40000000 */ +#define FLASH_ECCR_ECCC FLASH_ECCR_ECCC_Msk /*!< ECC correction */ +#define FLASH_ECCR_ECCD_Pos (31U) +#define FLASH_ECCR_ECCD_Msk (0x1UL << FLASH_ECCR_ECCD_Pos) /*!< 0x80000000 */ +#define FLASH_ECCR_ECCD FLASH_ECCR_ECCD_Msk /*!< ECC detection */ + +/******************* Bits definition for FLASH_ECCDR register ***************/ +#define FLASH_ECCDR_FAIL_DATA_Pos (0U) +#define FLASH_ECCDR_FAIL_DATA_Msk (0xFFFFUL << FLASH_ECCDR_FAIL_DATA_Pos) /*!< 0x0000FFFF */ +#define FLASH_ECCDR_FAIL_DATA FLASH_ECCDR_FAIL_DATA_Msk /*!< ECC fail data */ + + +/******************************************************************************/ +/* */ +/* Filter Mathematical ACcelerator unit (FMAC) */ +/* */ +/******************************************************************************/ +/***************** Bit definition for FMAC_X1BUFCFG register ****************/ +#define FMAC_X1BUFCFG_X1_BASE_Pos (0U) +#define FMAC_X1BUFCFG_X1_BASE_Msk (0xFFUL << FMAC_X1BUFCFG_X1_BASE_Pos) /*!< 0x000000FF */ +#define FMAC_X1BUFCFG_X1_BASE FMAC_X1BUFCFG_X1_BASE_Msk /*!< Base address of X1 buffer */ +#define FMAC_X1BUFCFG_X1_BUF_SIZE_Pos (8U) +#define FMAC_X1BUFCFG_X1_BUF_SIZE_Msk (0xFFUL << FMAC_X1BUFCFG_X1_BUF_SIZE_Pos) /*!< 0x0000FF00 */ +#define FMAC_X1BUFCFG_X1_BUF_SIZE FMAC_X1BUFCFG_X1_BUF_SIZE_Msk /*!< Allocated size of X1 buffer in 16-bit words */ +#define FMAC_X1BUFCFG_FULL_WM_Pos (24U) +#define FMAC_X1BUFCFG_FULL_WM_Msk (0x3UL << FMAC_X1BUFCFG_FULL_WM_Pos) /*!< 0x03000000 */ +#define FMAC_X1BUFCFG_FULL_WM FMAC_X1BUFCFG_FULL_WM_Msk /*!< Watermark for buffer full flag */ + +/***************** Bit definition for FMAC_X2BUFCFG register ****************/ +#define FMAC_X2BUFCFG_X2_BASE_Pos (0U) +#define FMAC_X2BUFCFG_X2_BASE_Msk (0xFFUL << FMAC_X2BUFCFG_X2_BASE_Pos) /*!< 0x000000FF */ +#define FMAC_X2BUFCFG_X2_BASE FMAC_X2BUFCFG_X2_BASE_Msk /*!< Base address of X2 buffer */ +#define FMAC_X2BUFCFG_X2_BUF_SIZE_Pos (8U) +#define FMAC_X2BUFCFG_X2_BUF_SIZE_Msk (0xFFUL << FMAC_X2BUFCFG_X2_BUF_SIZE_Pos) /*!< 0x0000FF00 */ +#define FMAC_X2BUFCFG_X2_BUF_SIZE FMAC_X2BUFCFG_X2_BUF_SIZE_Msk /*!< Size of X2 buffer in 16-bit words */ + +/***************** Bit definition for FMAC_YBUFCFG register *****************/ +#define FMAC_YBUFCFG_Y_BASE_Pos (0U) +#define FMAC_YBUFCFG_Y_BASE_Msk (0xFFUL << FMAC_YBUFCFG_Y_BASE_Pos) /*!< 0x000000FF */ +#define FMAC_YBUFCFG_Y_BASE FMAC_YBUFCFG_Y_BASE_Msk /*!< Base address of Y buffer */ +#define FMAC_YBUFCFG_Y_BUF_SIZE_Pos (8U) +#define FMAC_YBUFCFG_Y_BUF_SIZE_Msk (0xFFUL << FMAC_YBUFCFG_Y_BUF_SIZE_Pos) /*!< 0x0000FF00 */ +#define FMAC_YBUFCFG_Y_BUF_SIZE FMAC_YBUFCFG_Y_BUF_SIZE_Msk /*!< Size of Y buffer in 16-bit words */ +#define FMAC_YBUFCFG_EMPTY_WM_Pos (24U) +#define FMAC_YBUFCFG_EMPTY_WM_Msk (0x3UL << FMAC_YBUFCFG_EMPTY_WM_Pos) /*!< 0x03000000 */ +#define FMAC_YBUFCFG_EMPTY_WM FMAC_YBUFCFG_EMPTY_WM_Msk /*!< Watermark for buffer empty flag */ + +/****************** Bit definition for FMAC_PARAM register ******************/ +#define FMAC_PARAM_P_Pos (0U) +#define FMAC_PARAM_P_Msk (0xFFUL << FMAC_PARAM_P_Pos) /*!< 0x000000FF */ +#define FMAC_PARAM_P FMAC_PARAM_P_Msk /*!< Input parameter P */ +#define FMAC_PARAM_Q_Pos (8U) +#define FMAC_PARAM_Q_Msk (0xFFUL << FMAC_PARAM_Q_Pos) /*!< 0x0000FF00 */ +#define FMAC_PARAM_Q FMAC_PARAM_Q_Msk /*!< Input parameter Q */ +#define FMAC_PARAM_R_Pos (16U) +#define FMAC_PARAM_R_Msk (0xFFUL << FMAC_PARAM_R_Pos) /*!< 0x00FF0000 */ +#define FMAC_PARAM_R FMAC_PARAM_R_Msk /*!< Input parameter R */ +#define FMAC_PARAM_FUNC_Pos (24U) +#define FMAC_PARAM_FUNC_Msk (0x7FUL << FMAC_PARAM_FUNC_Pos) /*!< 0x7F000000 */ +#define FMAC_PARAM_FUNC FMAC_PARAM_FUNC_Msk /*!< Function */ +#define FMAC_PARAM_FUNC_0 (0x1UL << FMAC_PARAM_FUNC_Pos) /*!< 0x01000000 */ +#define FMAC_PARAM_FUNC_1 (0x2UL << FMAC_PARAM_FUNC_Pos) /*!< 0x02000000 */ +#define FMAC_PARAM_FUNC_2 (0x4UL << FMAC_PARAM_FUNC_Pos) /*!< 0x04000000 */ +#define FMAC_PARAM_FUNC_3 (0x8UL << FMAC_PARAM_FUNC_Pos) /*!< 0x08000000 */ +#define FMAC_PARAM_FUNC_4 (0x10UL << FMAC_PARAM_FUNC_Pos) /*!< 0x10000000 */ +#define FMAC_PARAM_FUNC_5 (0x20UL << FMAC_PARAM_FUNC_Pos) /*!< 0x20000000 */ +#define FMAC_PARAM_FUNC_6 (0x40UL << FMAC_PARAM_FUNC_Pos) /*!< 0x40000000 */ +#define FMAC_PARAM_START_Pos (31U) +#define FMAC_PARAM_START_Msk (0x1UL << FMAC_PARAM_START_Pos) /*!< 0x80000000 */ +#define FMAC_PARAM_START FMAC_PARAM_START_Msk /*!< Enable execution */ + +/******************** Bit definition for FMAC_CR register *******************/ +#define FMAC_CR_RIEN_Pos (0U) +#define FMAC_CR_RIEN_Msk (0x1UL << FMAC_CR_RIEN_Pos) /*!< 0x00000001 */ +#define FMAC_CR_RIEN FMAC_CR_RIEN_Msk /*!< Enable read interrupt */ +#define FMAC_CR_WIEN_Pos (1U) +#define FMAC_CR_WIEN_Msk (0x1UL << FMAC_CR_WIEN_Pos) /*!< 0x00000002 */ +#define FMAC_CR_WIEN FMAC_CR_WIEN_Msk /*!< Enable write interrupt */ +#define FMAC_CR_OVFLIEN_Pos (2U) +#define FMAC_CR_OVFLIEN_Msk (0x1UL << FMAC_CR_OVFLIEN_Pos) /*!< 0x00000004 */ +#define FMAC_CR_OVFLIEN FMAC_CR_OVFLIEN_Msk /*!< Enable overflow error interrupts */ +#define FMAC_CR_UNFLIEN_Pos (3U) +#define FMAC_CR_UNFLIEN_Msk (0x1UL << FMAC_CR_UNFLIEN_Pos) /*!< 0x00000008 */ +#define FMAC_CR_UNFLIEN FMAC_CR_UNFLIEN_Msk /*!< Enable underflow error interrupts */ +#define FMAC_CR_SATIEN_Pos (4U) +#define FMAC_CR_SATIEN_Msk (0x1UL << FMAC_CR_SATIEN_Pos) /*!< 0x00000010 */ +#define FMAC_CR_SATIEN FMAC_CR_SATIEN_Msk /*!< Enable saturation error interrupts */ +#define FMAC_CR_DMAREN_Pos (8U) +#define FMAC_CR_DMAREN_Msk (0x1UL << FMAC_CR_DMAREN_Pos) /*!< 0x00000100 */ +#define FMAC_CR_DMAREN FMAC_CR_DMAREN_Msk /*!< Enable DMA read channel requests */ +#define FMAC_CR_DMAWEN_Pos (9U) +#define FMAC_CR_DMAWEN_Msk (0x1UL << FMAC_CR_DMAWEN_Pos) /*!< 0x00000200 */ +#define FMAC_CR_DMAWEN FMAC_CR_DMAWEN_Msk /*!< Enable DMA write channel requests */ +#define FMAC_CR_CLIPEN_Pos (15U) +#define FMAC_CR_CLIPEN_Msk (0x1UL << FMAC_CR_CLIPEN_Pos) /*!< 0x00008000 */ +#define FMAC_CR_CLIPEN FMAC_CR_CLIPEN_Msk /*!< Enable clipping */ +#define FMAC_CR_RESET_Pos (16U) +#define FMAC_CR_RESET_Msk (0x1UL << FMAC_CR_RESET_Pos) /*!< 0x00010000 */ +#define FMAC_CR_RESET FMAC_CR_RESET_Msk /*!< Reset filter mathematical accelerator unit */ + +/******************* Bit definition for FMAC_SR register ********************/ +#define FMAC_SR_YEMPTY_Pos (0U) +#define FMAC_SR_YEMPTY_Msk (0x1UL << FMAC_SR_YEMPTY_Pos) /*!< 0x00000001 */ +#define FMAC_SR_YEMPTY FMAC_SR_YEMPTY_Msk /*!< Y buffer empty flag */ +#define FMAC_SR_X1FULL_Pos (1U) +#define FMAC_SR_X1FULL_Msk (0x1UL << FMAC_SR_X1FULL_Pos) /*!< 0x00000002 */ +#define FMAC_SR_X1FULL FMAC_SR_X1FULL_Msk /*!< X1 buffer full flag */ +#define FMAC_SR_OVFL_Pos (8U) +#define FMAC_SR_OVFL_Msk (0x1UL << FMAC_SR_OVFL_Pos) /*!< 0x00000100 */ +#define FMAC_SR_OVFL FMAC_SR_OVFL_Msk /*!< Overflow error flag */ +#define FMAC_SR_UNFL_Pos (9U) +#define FMAC_SR_UNFL_Msk (0x1UL << FMAC_SR_UNFL_Pos) /*!< 0x00000200 */ +#define FMAC_SR_UNFL FMAC_SR_UNFL_Msk /*!< Underflow error flag */ +#define FMAC_SR_SAT_Pos (10U) +#define FMAC_SR_SAT_Msk (0x1UL << FMAC_SR_SAT_Pos) /*!< 0x00000400 */ +#define FMAC_SR_SAT FMAC_SR_SAT_Msk /*!< Saturation error flag */ + +/****************** Bit definition for FMAC_WDATA register ******************/ +#define FMAC_WDATA_WDATA_Pos (0U) +#define FMAC_WDATA_WDATA_Msk (0xFFFFUL << FMAC_WDATA_WDATA_Pos) /*!< 0x0000FFFF */ +#define FMAC_WDATA_WDATA FMAC_WDATA_WDATA_Msk /*!< Write data */ + +/****************** Bit definition for FMACX_RDATA register *****************/ +#define FMAC_RDATA_RDATA_Pos (0U) +#define FMAC_RDATA_RDATA_Msk (0xFFFFUL << FMAC_RDATA_RDATA_Pos) /*!< 0x0000FFFF */ +#define FMAC_RDATA_RDATA FMAC_RDATA_RDATA_Msk /*!< Read data */ + + +/******************************************************************************/ +/* */ +/* Flexible Memory Controller */ +/* */ +/******************************************************************************/ +/****************** Bit definition for FMC_BCR1 register *******************/ +#define FMC_BCR1_CCLKEN_Pos (20U) +#define FMC_BCR1_CCLKEN_Msk (0x1UL << FMC_BCR1_CCLKEN_Pos) /*!< 0x00100000 */ +#define FMC_BCR1_CCLKEN FMC_BCR1_CCLKEN_Msk /*! */ + +/******************** Bits definition for RTC_ALRMAR register ***************/ +#define RTC_ALRMAR_SU_Pos (0U) +#define RTC_ALRMAR_SU_Msk (0xFUL << RTC_ALRMAR_SU_Pos) /*!< 0x0000000F */ +#define RTC_ALRMAR_SU RTC_ALRMAR_SU_Msk +#define RTC_ALRMAR_SU_0 (0x1UL << RTC_ALRMAR_SU_Pos) /*!< 0x00000001 */ +#define RTC_ALRMAR_SU_1 (0x2UL << RTC_ALRMAR_SU_Pos) /*!< 0x00000002 */ +#define RTC_ALRMAR_SU_2 (0x4UL << RTC_ALRMAR_SU_Pos) /*!< 0x00000004 */ +#define RTC_ALRMAR_SU_3 (0x8UL << RTC_ALRMAR_SU_Pos) /*!< 0x00000008 */ +#define RTC_ALRMAR_ST_Pos (4U) +#define RTC_ALRMAR_ST_Msk (0x7UL << RTC_ALRMAR_ST_Pos) /*!< 0x00000070 */ +#define RTC_ALRMAR_ST RTC_ALRMAR_ST_Msk +#define RTC_ALRMAR_ST_0 (0x1UL << RTC_ALRMAR_ST_Pos) /*!< 0x00000010 */ +#define RTC_ALRMAR_ST_1 (0x2UL << RTC_ALRMAR_ST_Pos) /*!< 0x00000020 */ +#define RTC_ALRMAR_ST_2 (0x4UL << RTC_ALRMAR_ST_Pos) /*!< 0x00000040 */ +#define RTC_ALRMAR_MSK1_Pos (7U) +#define RTC_ALRMAR_MSK1_Msk (0x1UL << RTC_ALRMAR_MSK1_Pos) /*!< 0x00000080 */ +#define RTC_ALRMAR_MSK1 RTC_ALRMAR_MSK1_Msk +#define RTC_ALRMAR_MNU_Pos (8U) +#define RTC_ALRMAR_MNU_Msk (0xFUL << RTC_ALRMAR_MNU_Pos) /*!< 0x00000F00 */ +#define RTC_ALRMAR_MNU RTC_ALRMAR_MNU_Msk +#define RTC_ALRMAR_MNU_0 (0x1UL << RTC_ALRMAR_MNU_Pos) /*!< 0x00000100 */ +#define RTC_ALRMAR_MNU_1 (0x2UL << RTC_ALRMAR_MNU_Pos) /*!< 0x00000200 */ +#define RTC_ALRMAR_MNU_2 (0x4UL << RTC_ALRMAR_MNU_Pos) /*!< 0x00000400 */ +#define RTC_ALRMAR_MNU_3 (0x8UL << RTC_ALRMAR_MNU_Pos) /*!< 0x00000800 */ +#define RTC_ALRMAR_MNT_Pos (12U) +#define RTC_ALRMAR_MNT_Msk (0x7UL << RTC_ALRMAR_MNT_Pos) /*!< 0x00007000 */ +#define RTC_ALRMAR_MNT RTC_ALRMAR_MNT_Msk +#define RTC_ALRMAR_MNT_0 (0x1UL << RTC_ALRMAR_MNT_Pos) /*!< 0x00001000 */ +#define RTC_ALRMAR_MNT_1 (0x2UL << RTC_ALRMAR_MNT_Pos) /*!< 0x00002000 */ +#define RTC_ALRMAR_MNT_2 (0x4UL << RTC_ALRMAR_MNT_Pos) /*!< 0x00004000 */ +#define RTC_ALRMAR_MSK2_Pos (15U) +#define RTC_ALRMAR_MSK2_Msk (0x1UL << RTC_ALRMAR_MSK2_Pos) /*!< 0x00008000 */ +#define RTC_ALRMAR_MSK2 RTC_ALRMAR_MSK2_Msk +#define RTC_ALRMAR_HU_Pos (16U) +#define RTC_ALRMAR_HU_Msk (0xFUL << RTC_ALRMAR_HU_Pos) /*!< 0x000F0000 */ +#define RTC_ALRMAR_HU RTC_ALRMAR_HU_Msk +#define RTC_ALRMAR_HU_0 (0x1UL << RTC_ALRMAR_HU_Pos) /*!< 0x00010000 */ +#define RTC_ALRMAR_HU_1 (0x2UL << RTC_ALRMAR_HU_Pos) /*!< 0x00020000 */ +#define RTC_ALRMAR_HU_2 (0x4UL << RTC_ALRMAR_HU_Pos) /*!< 0x00040000 */ +#define RTC_ALRMAR_HU_3 (0x8UL << RTC_ALRMAR_HU_Pos) /*!< 0x00080000 */ +#define RTC_ALRMAR_HT_Pos (20U) +#define RTC_ALRMAR_HT_Msk (0x3UL << RTC_ALRMAR_HT_Pos) /*!< 0x00300000 */ +#define RTC_ALRMAR_HT RTC_ALRMAR_HT_Msk +#define RTC_ALRMAR_HT_0 (0x1UL << RTC_ALRMAR_HT_Pos) /*!< 0x00100000 */ +#define RTC_ALRMAR_HT_1 (0x2UL << RTC_ALRMAR_HT_Pos) /*!< 0x00200000 */ +#define RTC_ALRMAR_PM_Pos (22U) +#define RTC_ALRMAR_PM_Msk (0x1UL << RTC_ALRMAR_PM_Pos) /*!< 0x00400000 */ +#define RTC_ALRMAR_PM RTC_ALRMAR_PM_Msk +#define RTC_ALRMAR_MSK3_Pos (23U) +#define RTC_ALRMAR_MSK3_Msk (0x1UL << RTC_ALRMAR_MSK3_Pos) /*!< 0x00800000 */ +#define RTC_ALRMAR_MSK3 RTC_ALRMAR_MSK3_Msk +#define RTC_ALRMAR_DU_Pos (24U) +#define RTC_ALRMAR_DU_Msk (0xFUL << RTC_ALRMAR_DU_Pos) /*!< 0x0F000000 */ +#define RTC_ALRMAR_DU RTC_ALRMAR_DU_Msk +#define RTC_ALRMAR_DU_0 (0x1UL << RTC_ALRMAR_DU_Pos) /*!< 0x01000000 */ +#define RTC_ALRMAR_DU_1 (0x2UL << RTC_ALRMAR_DU_Pos) /*!< 0x02000000 */ +#define RTC_ALRMAR_DU_2 (0x4UL << RTC_ALRMAR_DU_Pos) /*!< 0x04000000 */ +#define RTC_ALRMAR_DU_3 (0x8UL << RTC_ALRMAR_DU_Pos) /*!< 0x08000000 */ +#define RTC_ALRMAR_DT_Pos (28U) +#define RTC_ALRMAR_DT_Msk (0x3UL << RTC_ALRMAR_DT_Pos) /*!< 0x30000000 */ +#define RTC_ALRMAR_DT RTC_ALRMAR_DT_Msk +#define RTC_ALRMAR_DT_0 (0x1UL << RTC_ALRMAR_DT_Pos) /*!< 0x10000000 */ +#define RTC_ALRMAR_DT_1 (0x2UL << RTC_ALRMAR_DT_Pos) /*!< 0x20000000 */ +#define RTC_ALRMAR_WDSEL_Pos (30U) +#define RTC_ALRMAR_WDSEL_Msk (0x1UL << RTC_ALRMAR_WDSEL_Pos) /*!< 0x40000000 */ +#define RTC_ALRMAR_WDSEL RTC_ALRMAR_WDSEL_Msk +#define RTC_ALRMAR_MSK4_Pos (31U) +#define RTC_ALRMAR_MSK4_Msk (0x1UL << RTC_ALRMAR_MSK4_Pos) /*!< 0x80000000 */ +#define RTC_ALRMAR_MSK4 RTC_ALRMAR_MSK4_Msk + +/******************** Bits definition for RTC_ALRMASSR register *************/ +#define RTC_ALRMASSR_SS_Pos (0U) +#define RTC_ALRMASSR_SS_Msk (0x7FFFUL << RTC_ALRMASSR_SS_Pos) /*!< 0x00007FFF */ +#define RTC_ALRMASSR_SS RTC_ALRMASSR_SS_Msk +#define RTC_ALRMASSR_MASKSS_Pos (24U) +#define RTC_ALRMASSR_MASKSS_Msk (0x3FUL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x3F000000 */ +#define RTC_ALRMASSR_MASKSS RTC_ALRMASSR_MASKSS_Msk +#define RTC_ALRMASSR_MASKSS_0 (0x1UL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x01000000 */ +#define RTC_ALRMASSR_MASKSS_1 (0x2UL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x02000000 */ +#define RTC_ALRMASSR_MASKSS_2 (0x4UL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x04000000 */ +#define RTC_ALRMASSR_MASKSS_3 (0x8UL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x08000000 */ +#define RTC_ALRMASSR_MASKSS_4 (0x10UL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x10000000 */ +#define RTC_ALRMASSR_MASKSS_5 (0x20UL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x20000000 */ +#define RTC_ALRMASSR_SSCLR_Pos (31U) +#define RTC_ALRMASSR_SSCLR_Msk (0x1UL << RTC_ALRMASSR_SSCLR_Pos) /*!< 0x80000000 */ +#define RTC_ALRMASSR_SSCLR RTC_ALRMASSR_SSCLR_Msk + +/******************** Bits definition for RTC_ALRMBR register ***************/ +#define RTC_ALRMBR_SU_Pos (0U) +#define RTC_ALRMBR_SU_Msk (0xFUL << RTC_ALRMBR_SU_Pos) /*!< 0x0000000F */ +#define RTC_ALRMBR_SU RTC_ALRMBR_SU_Msk +#define RTC_ALRMBR_SU_0 (0x1UL << RTC_ALRMBR_SU_Pos) /*!< 0x00000001 */ +#define RTC_ALRMBR_SU_1 (0x2UL << RTC_ALRMBR_SU_Pos) /*!< 0x00000002 */ +#define RTC_ALRMBR_SU_2 (0x4UL << RTC_ALRMBR_SU_Pos) /*!< 0x00000004 */ +#define RTC_ALRMBR_SU_3 (0x8UL << RTC_ALRMBR_SU_Pos) /*!< 0x00000008 */ +#define RTC_ALRMBR_ST_Pos (4U) +#define RTC_ALRMBR_ST_Msk (0x7UL << RTC_ALRMBR_ST_Pos) /*!< 0x00000070 */ +#define RTC_ALRMBR_ST RTC_ALRMBR_ST_Msk +#define RTC_ALRMBR_ST_0 (0x1UL << RTC_ALRMBR_ST_Pos) /*!< 0x00000010 */ +#define RTC_ALRMBR_ST_1 (0x2UL << RTC_ALRMBR_ST_Pos) /*!< 0x00000020 */ +#define RTC_ALRMBR_ST_2 (0x4UL << RTC_ALRMBR_ST_Pos) /*!< 0x00000040 */ +#define RTC_ALRMBR_MSK1_Pos (7U) +#define RTC_ALRMBR_MSK1_Msk (0x1UL << RTC_ALRMBR_MSK1_Pos) /*!< 0x00000080 */ +#define RTC_ALRMBR_MSK1 RTC_ALRMBR_MSK1_Msk +#define RTC_ALRMBR_MNU_Pos (8U) +#define RTC_ALRMBR_MNU_Msk (0xFUL << RTC_ALRMBR_MNU_Pos) /*!< 0x00000F00 */ +#define RTC_ALRMBR_MNU RTC_ALRMBR_MNU_Msk +#define RTC_ALRMBR_MNU_0 (0x1UL << RTC_ALRMBR_MNU_Pos) /*!< 0x00000100 */ +#define RTC_ALRMBR_MNU_1 (0x2UL << RTC_ALRMBR_MNU_Pos) /*!< 0x00000200 */ +#define RTC_ALRMBR_MNU_2 (0x4UL << RTC_ALRMBR_MNU_Pos) /*!< 0x00000400 */ +#define RTC_ALRMBR_MNU_3 (0x8UL << RTC_ALRMBR_MNU_Pos) /*!< 0x00000800 */ +#define RTC_ALRMBR_MNT_Pos (12U) +#define RTC_ALRMBR_MNT_Msk (0x7UL << RTC_ALRMBR_MNT_Pos) /*!< 0x00007000 */ +#define RTC_ALRMBR_MNT RTC_ALRMBR_MNT_Msk +#define RTC_ALRMBR_MNT_0 (0x1UL << RTC_ALRMBR_MNT_Pos) /*!< 0x00001000 */ +#define RTC_ALRMBR_MNT_1 (0x2UL << RTC_ALRMBR_MNT_Pos) /*!< 0x00002000 */ +#define RTC_ALRMBR_MNT_2 (0x4UL << RTC_ALRMBR_MNT_Pos) /*!< 0x00004000 */ +#define RTC_ALRMBR_MSK2_Pos (15U) +#define RTC_ALRMBR_MSK2_Msk (0x1UL << RTC_ALRMBR_MSK2_Pos) /*!< 0x00008000 */ +#define RTC_ALRMBR_MSK2 RTC_ALRMBR_MSK2_Msk +#define RTC_ALRMBR_HU_Pos (16U) +#define RTC_ALRMBR_HU_Msk (0xFUL << RTC_ALRMBR_HU_Pos) /*!< 0x000F0000 */ +#define RTC_ALRMBR_HU RTC_ALRMBR_HU_Msk +#define RTC_ALRMBR_HU_0 (0x1UL << RTC_ALRMBR_HU_Pos) /*!< 0x00010000 */ +#define RTC_ALRMBR_HU_1 (0x2UL << RTC_ALRMBR_HU_Pos) /*!< 0x00020000 */ +#define RTC_ALRMBR_HU_2 (0x4UL << RTC_ALRMBR_HU_Pos) /*!< 0x00040000 */ +#define RTC_ALRMBR_HU_3 (0x8UL << RTC_ALRMBR_HU_Pos) /*!< 0x00080000 */ +#define RTC_ALRMBR_HT_Pos (20U) +#define RTC_ALRMBR_HT_Msk (0x3UL << RTC_ALRMBR_HT_Pos) /*!< 0x00300000 */ +#define RTC_ALRMBR_HT RTC_ALRMBR_HT_Msk +#define RTC_ALRMBR_HT_0 (0x1UL << RTC_ALRMBR_HT_Pos) /*!< 0x00100000 */ +#define RTC_ALRMBR_HT_1 (0x2UL << RTC_ALRMBR_HT_Pos) /*!< 0x00200000 */ +#define RTC_ALRMBR_PM_Pos (22U) +#define RTC_ALRMBR_PM_Msk (0x1UL << RTC_ALRMBR_PM_Pos) /*!< 0x00400000 */ +#define RTC_ALRMBR_PM RTC_ALRMBR_PM_Msk +#define RTC_ALRMBR_MSK3_Pos (23U) +#define RTC_ALRMBR_MSK3_Msk (0x1UL << RTC_ALRMBR_MSK3_Pos) /*!< 0x00800000 */ +#define RTC_ALRMBR_MSK3 RTC_ALRMBR_MSK3_Msk +#define RTC_ALRMBR_DU_Pos (24U) +#define RTC_ALRMBR_DU_Msk (0xFUL << RTC_ALRMBR_DU_Pos) /*!< 0x0F000000 */ +#define RTC_ALRMBR_DU RTC_ALRMBR_DU_Msk +#define RTC_ALRMBR_DU_0 (0x1UL << RTC_ALRMBR_DU_Pos) /*!< 0x01000000 */ +#define RTC_ALRMBR_DU_1 (0x2UL << RTC_ALRMBR_DU_Pos) /*!< 0x02000000 */ +#define RTC_ALRMBR_DU_2 (0x4UL << RTC_ALRMBR_DU_Pos) /*!< 0x04000000 */ +#define RTC_ALRMBR_DU_3 (0x8UL << RTC_ALRMBR_DU_Pos) /*!< 0x08000000 */ +#define RTC_ALRMBR_DT_Pos (28U) +#define RTC_ALRMBR_DT_Msk (0x3UL << RTC_ALRMBR_DT_Pos) /*!< 0x30000000 */ +#define RTC_ALRMBR_DT RTC_ALRMBR_DT_Msk +#define RTC_ALRMBR_DT_0 (0x1UL << RTC_ALRMBR_DT_Pos) /*!< 0x10000000 */ +#define RTC_ALRMBR_DT_1 (0x2UL << RTC_ALRMBR_DT_Pos) /*!< 0x20000000 */ +#define RTC_ALRMBR_WDSEL_Pos (30U) +#define RTC_ALRMBR_WDSEL_Msk (0x1UL << RTC_ALRMBR_WDSEL_Pos) /*!< 0x40000000 */ +#define RTC_ALRMBR_WDSEL RTC_ALRMBR_WDSEL_Msk +#define RTC_ALRMBR_MSK4_Pos (31U) +#define RTC_ALRMBR_MSK4_Msk (0x1UL << RTC_ALRMBR_MSK4_Pos) /*!< 0x80000000 */ +#define RTC_ALRMBR_MSK4 RTC_ALRMBR_MSK4_Msk + +/******************** Bits definition for RTC_ALRMBSSR register *************/ +#define RTC_ALRMBSSR_SS_Pos (0U) +#define RTC_ALRMBSSR_SS_Msk (0x7FFFUL << RTC_ALRMBSSR_SS_Pos) /*!< 0x00007FFF */ +#define RTC_ALRMBSSR_SS RTC_ALRMBSSR_SS_Msk +#define RTC_ALRMBSSR_MASKSS_Pos (24U) +#define RTC_ALRMBSSR_MASKSS_Msk (0x3FUL << RTC_ALRMBSSR_MASKSS_Pos) /*!< 0x3F000000 */ +#define RTC_ALRMBSSR_MASKSS RTC_ALRMBSSR_MASKSS_Msk +#define RTC_ALRMBSSR_MASKSS_0 (0x1UL << RTC_ALRMBSSR_MASKSS_Pos) /*!< 0x01000000 */ +#define RTC_ALRMBSSR_MASKSS_1 (0x2UL << RTC_ALRMBSSR_MASKSS_Pos) /*!< 0x02000000 */ +#define RTC_ALRMBSSR_MASKSS_2 (0x4UL << RTC_ALRMBSSR_MASKSS_Pos) /*!< 0x04000000 */ +#define RTC_ALRMBSSR_MASKSS_3 (0x8UL << RTC_ALRMBSSR_MASKSS_Pos) /*!< 0x08000000 */ +#define RTC_ALRMBSSR_MASKSS_4 (0x10UL << RTC_ALRMBSSR_MASKSS_Pos) /*!< 0x10000000 */ +#define RTC_ALRMBSSR_MASKSS_5 (0x20UL << RTC_ALRMBSSR_MASKSS_Pos) /*!< 0x20000000 */ +#define RTC_ALRMBSSR_SSCLR_Pos (31U) +#define RTC_ALRMBSSR_SSCLR_Msk (0x1UL << RTC_ALRMBSSR_SSCLR_Pos) /*!< 0x80000000 */ +#define RTC_ALRMBSSR_SSCLR RTC_ALRMBSSR_SSCLR_Msk + +/******************** Bits definition for RTC_SR register *******************/ +#define RTC_SR_ALRAF_Pos (0U) +#define RTC_SR_ALRAF_Msk (0x1UL << RTC_SR_ALRAF_Pos) /*!< 0x00000001 */ +#define RTC_SR_ALRAF RTC_SR_ALRAF_Msk +#define RTC_SR_ALRBF_Pos (1U) +#define RTC_SR_ALRBF_Msk (0x1UL << RTC_SR_ALRBF_Pos) /*!< 0x00000002 */ +#define RTC_SR_ALRBF RTC_SR_ALRBF_Msk +#define RTC_SR_WUTF_Pos (2U) +#define RTC_SR_WUTF_Msk (0x1UL << RTC_SR_WUTF_Pos) /*!< 0x00000004 */ +#define RTC_SR_WUTF RTC_SR_WUTF_Msk +#define RTC_SR_TSF_Pos (3U) +#define RTC_SR_TSF_Msk (0x1UL << RTC_SR_TSF_Pos) /*!< 0x00000008 */ +#define RTC_SR_TSF RTC_SR_TSF_Msk +#define RTC_SR_TSOVF_Pos (4U) +#define RTC_SR_TSOVF_Msk (0x1UL << RTC_SR_TSOVF_Pos) /*!< 0x00000010 */ +#define RTC_SR_TSOVF RTC_SR_TSOVF_Msk +#define RTC_SR_ITSF_Pos (5U) +#define RTC_SR_ITSF_Msk (0x1UL << RTC_SR_ITSF_Pos) /*!< 0x00000020 */ +#define RTC_SR_ITSF RTC_SR_ITSF_Msk +#define RTC_SR_SSRUF_Pos (6U) +#define RTC_SR_SSRUF_Msk (0x1UL << RTC_SR_SSRUF_Pos) /*!< 0x00000040 */ +#define RTC_SR_SSRUF RTC_SR_SSRUF_Msk + +/******************** Bits definition for RTC_MISR register *****************/ +#define RTC_MISR_ALRAMF_Pos (0U) +#define RTC_MISR_ALRAMF_Msk (0x1UL << RTC_MISR_ALRAMF_Pos) /*!< 0x00000001 */ +#define RTC_MISR_ALRAMF RTC_MISR_ALRAMF_Msk +#define RTC_MISR_ALRBMF_Pos (1U) +#define RTC_MISR_ALRBMF_Msk (0x1UL << RTC_MISR_ALRBMF_Pos) /*!< 0x00000002 */ +#define RTC_MISR_ALRBMF RTC_MISR_ALRBMF_Msk +#define RTC_MISR_WUTMF_Pos (2U) +#define RTC_MISR_WUTMF_Msk (0x1UL << RTC_MISR_WUTMF_Pos) /*!< 0x00000004 */ +#define RTC_MISR_WUTMF RTC_MISR_WUTMF_Msk +#define RTC_MISR_TSMF_Pos (3U) +#define RTC_MISR_TSMF_Msk (0x1UL << RTC_MISR_TSMF_Pos) /*!< 0x00000008 */ +#define RTC_MISR_TSMF RTC_MISR_TSMF_Msk +#define RTC_MISR_TSOVMF_Pos (4U) +#define RTC_MISR_TSOVMF_Msk (0x1UL << RTC_MISR_TSOVMF_Pos) /*!< 0x00000010 */ +#define RTC_MISR_TSOVMF RTC_MISR_TSOVMF_Msk +#define RTC_MISR_ITSMF_Pos (5U) +#define RTC_MISR_ITSMF_Msk (0x1UL << RTC_MISR_ITSMF_Pos) /*!< 0x00000020 */ +#define RTC_MISR_ITSMF RTC_MISR_ITSMF_Msk +#define RTC_MISR_SSRUMF_Pos (6U) +#define RTC_MISR_SSRUMF_Msk (0x1UL << RTC_MISR_SSRUMF_Pos) /*!< 0x00000040 */ +#define RTC_MISR_SSRUMF RTC_MISR_SSRUMF_Msk + +/******************** Bits definition for RTC_SMISR register *****************/ +#define RTC_SMISR_ALRAMF_Pos (0U) +#define RTC_SMISR_ALRAMF_Msk (0x1UL << RTC_SMISR_ALRAMF_Pos) /*!< 0x00000001 */ +#define RTC_SMISR_ALRAMF RTC_SMISR_ALRAMF_Msk +#define RTC_SMISR_ALRBMF_Pos (1U) +#define RTC_SMISR_ALRBMF_Msk (0x1UL << RTC_SMISR_ALRBMF_Pos) /*!< 0x00000002 */ +#define RTC_SMISR_ALRBMF RTC_SMISR_ALRBMF_Msk +#define RTC_SMISR_WUTMF_Pos (2U) +#define RTC_SMISR_WUTMF_Msk (0x1UL << RTC_SMISR_WUTMF_Pos) /*!< 0x00000004 */ +#define RTC_SMISR_WUTMF RTC_SMISR_WUTMF_Msk +#define RTC_SMISR_TSMF_Pos (3U) +#define RTC_SMISR_TSMF_Msk (0x1UL << RTC_SMISR_TSMF_Pos) /*!< 0x00000008 */ +#define RTC_SMISR_TSMF RTC_SMISR_TSMF_Msk +#define RTC_SMISR_TSOVMF_Pos (4U) +#define RTC_SMISR_TSOVMF_Msk (0x1UL << RTC_SMISR_TSOVMF_Pos) /*!< 0x00000010 */ +#define RTC_SMISR_TSOVMF RTC_SMISR_TSOVMF_Msk +#define RTC_SMISR_ITSMF_Pos (5U) +#define RTC_SMISR_ITSMF_Msk (0x1UL << RTC_SMISR_ITSMF_Pos) /*!< 0x00000020 */ +#define RTC_SMISR_ITSMF RTC_SMISR_ITSMF_Msk +#define RTC_SMISR_SSRUMF_Pos (6U) +#define RTC_SMISR_SSRUMF_Msk (0x1UL << RTC_SMISR_SSRUMF_Pos) /*!< 0x00000040 */ +#define RTC_SMISR_SSRUMF RTC_SMISR_SSRUMF_Msk + +/******************** Bits definition for RTC_SCR register ******************/ +#define RTC_SCR_CALRAF_Pos (0U) +#define RTC_SCR_CALRAF_Msk (0x1UL << RTC_SCR_CALRAF_Pos) /*!< 0x00000001 */ +#define RTC_SCR_CALRAF RTC_SCR_CALRAF_Msk +#define RTC_SCR_CALRBF_Pos (1U) +#define RTC_SCR_CALRBF_Msk (0x1UL << RTC_SCR_CALRBF_Pos) /*!< 0x00000002 */ +#define RTC_SCR_CALRBF RTC_SCR_CALRBF_Msk +#define RTC_SCR_CWUTF_Pos (2U) +#define RTC_SCR_CWUTF_Msk (0x1UL << RTC_SCR_CWUTF_Pos) /*!< 0x00000004 */ +#define RTC_SCR_CWUTF RTC_SCR_CWUTF_Msk +#define RTC_SCR_CTSF_Pos (3U) +#define RTC_SCR_CTSF_Msk (0x1UL << RTC_SCR_CTSF_Pos) /*!< 0x00000008 */ +#define RTC_SCR_CTSF RTC_SCR_CTSF_Msk +#define RTC_SCR_CTSOVF_Pos (4U) +#define RTC_SCR_CTSOVF_Msk (0x1UL << RTC_SCR_CTSOVF_Pos) /*!< 0x00000010 */ +#define RTC_SCR_CTSOVF RTC_SCR_CTSOVF_Msk +#define RTC_SCR_CITSF_Pos (5U) +#define RTC_SCR_CITSF_Msk (0x1UL << RTC_SCR_CITSF_Pos) /*!< 0x00000020 */ +#define RTC_SCR_CITSF RTC_SCR_CITSF_Msk +#define RTC_SCR_CSSRUF_Pos (6U) +#define RTC_SCR_CSSRUF_Msk (0x1UL << RTC_SCR_CSSRUF_Pos) /*!< 0x00000040 */ +#define RTC_SCR_CSSRUF RTC_SCR_CSSRUF_Msk + +/******************** Bits definition for RTC_OR register ******************/ +#define RTC_OR_OUT2_RMP_Pos (0U) +#define RTC_OR_OUT2_RMP_Msk (0x1UL << RTC_OR_OUT2_RMP_Pos) /*!< 0x00000001 */ +#define RTC_OR_OUT2_RMP RTC_OR_OUT2_RMP_Msk + +/******************** Bits definition for RTC_ALRABINR register ******************/ +#define RTC_ALRABINR_SS_Pos (0U) +#define RTC_ALRABINR_SS_Msk (0xFFFFFFFFUL << RTC_ALRABINR_SS_Pos) /*!< 0xFFFFFFFF */ +#define RTC_ALRABINR_SS RTC_ALRABINR_SS_Msk + +/******************** Bits definition for RTC_ALRBBINR register ******************/ +#define RTC_ALRBBINR_SS_Pos (0U) +#define RTC_ALRBBINR_SS_Msk (0xFFFFFFFFUL << RTC_ALRBBINR_SS_Pos) /*!< 0xFFFFFFFF */ +#define RTC_ALRBBINR_SS RTC_ALRBBINR_SS_Msk + +/******************************************************************************/ +/* */ +/* Tamper and backup register (TAMP) */ +/* */ +/******************************************************************************/ +/******************** Bits definition for TAMP_CR1 register *****************/ +#define TAMP_CR1_TAMP1E_Pos (0U) +#define TAMP_CR1_TAMP1E_Msk (0x1UL << TAMP_CR1_TAMP1E_Pos) /*!< 0x00000001 */ +#define TAMP_CR1_TAMP1E TAMP_CR1_TAMP1E_Msk +#define TAMP_CR1_TAMP2E_Pos (1U) +#define TAMP_CR1_TAMP2E_Msk (0x1UL << TAMP_CR1_TAMP2E_Pos) /*!< 0x00000002 */ +#define TAMP_CR1_TAMP2E TAMP_CR1_TAMP2E_Msk +#define TAMP_CR1_TAMP3E_Pos (2U) +#define TAMP_CR1_TAMP3E_Msk (0x1UL << TAMP_CR1_TAMP3E_Pos) /*!< 0x00000004 */ +#define TAMP_CR1_TAMP3E TAMP_CR1_TAMP3E_Msk +#define TAMP_CR1_TAMP4E_Pos (3U) +#define TAMP_CR1_TAMP4E_Msk (0x1UL << TAMP_CR1_TAMP4E_Pos) /*!< 0x00000008 */ +#define TAMP_CR1_TAMP4E TAMP_CR1_TAMP4E_Msk +#define TAMP_CR1_TAMP5E_Pos (4U) +#define TAMP_CR1_TAMP5E_Msk (0x1UL << TAMP_CR1_TAMP5E_Pos) /*!< 0x00000010 */ +#define TAMP_CR1_TAMP5E TAMP_CR1_TAMP5E_Msk +#define TAMP_CR1_TAMP6E_Pos (5U) +#define TAMP_CR1_TAMP6E_Msk (0x1UL << TAMP_CR1_TAMP6E_Pos) /*!< 0x00000020 */ +#define TAMP_CR1_TAMP6E TAMP_CR1_TAMP6E_Msk +#define TAMP_CR1_TAMP7E_Pos (6U) +#define TAMP_CR1_TAMP7E_Msk (0x1UL << TAMP_CR1_TAMP7E_Pos) /*!< 0x00000040 */ +#define TAMP_CR1_TAMP7E TAMP_CR1_TAMP7E_Msk +#define TAMP_CR1_TAMP8E_Pos (7U) +#define TAMP_CR1_TAMP8E_Msk (0x1UL << TAMP_CR1_TAMP8E_Pos) /*!< 0x00000080 */ +#define TAMP_CR1_TAMP8E TAMP_CR1_TAMP8E_Msk +#define TAMP_CR1_ITAMP1E_Pos (16U) +#define TAMP_CR1_ITAMP1E_Msk (0x1UL << TAMP_CR1_ITAMP1E_Pos) /*!< 0x00010000 */ +#define TAMP_CR1_ITAMP1E TAMP_CR1_ITAMP1E_Msk +#define TAMP_CR1_ITAMP2E_Pos (17U) +#define TAMP_CR1_ITAMP2E_Msk (0x1UL << TAMP_CR1_ITAMP2E_Pos) /*!< 0x00020000 */ +#define TAMP_CR1_ITAMP2E TAMP_CR1_ITAMP2E_Msk +#define TAMP_CR1_ITAMP3E_Pos (18U) +#define TAMP_CR1_ITAMP3E_Msk (0x1UL << TAMP_CR1_ITAMP3E_Pos) /*!< 0x00040000 */ +#define TAMP_CR1_ITAMP3E TAMP_CR1_ITAMP3E_Msk +#define TAMP_CR1_ITAMP4E_Pos (19U) +#define TAMP_CR1_ITAMP4E_Msk (0x1UL << TAMP_CR1_ITAMP4E_Pos) /*!< 0x00080000 */ +#define TAMP_CR1_ITAMP4E TAMP_CR1_ITAMP4E_Msk +#define TAMP_CR1_ITAMP5E_Pos (20U) +#define TAMP_CR1_ITAMP5E_Msk (0x1UL << TAMP_CR1_ITAMP5E_Pos) /*!< 0x00100000 */ +#define TAMP_CR1_ITAMP5E TAMP_CR1_ITAMP5E_Msk +#define TAMP_CR1_ITAMP6E_Pos (21U) +#define TAMP_CR1_ITAMP6E_Msk (0x1UL << TAMP_CR1_ITAMP6E_Pos) /*!< 0x00200000 */ +#define TAMP_CR1_ITAMP6E TAMP_CR1_ITAMP6E_Msk +#define TAMP_CR1_ITAMP7E_Pos (22U) +#define TAMP_CR1_ITAMP7E_Msk (0x1UL << TAMP_CR1_ITAMP7E_Pos) /*!< 0x00400000 */ +#define TAMP_CR1_ITAMP7E TAMP_CR1_ITAMP7E_Msk +#define TAMP_CR1_ITAMP8E_Pos (23U) +#define TAMP_CR1_ITAMP8E_Msk (0x1UL << TAMP_CR1_ITAMP8E_Pos) /*!< 0x00800000 */ +#define TAMP_CR1_ITAMP8E TAMP_CR1_ITAMP8E_Msk +#define TAMP_CR1_ITAMP9E_Pos (24U) +#define TAMP_CR1_ITAMP9E_Msk (0x1UL << TAMP_CR1_ITAMP9E_Pos) /*!< 0x01000000 */ +#define TAMP_CR1_ITAMP9E TAMP_CR1_ITAMP9E_Msk +#define TAMP_CR1_ITAMP11E_Pos (26U) +#define TAMP_CR1_ITAMP11E_Msk (0x1UL << TAMP_CR1_ITAMP11E_Pos) /*!< 0x04000000 */ +#define TAMP_CR1_ITAMP11E TAMP_CR1_ITAMP11E_Msk +#define TAMP_CR1_ITAMP12E_Pos (27U) +#define TAMP_CR1_ITAMP12E_Msk (0x1UL << TAMP_CR1_ITAMP12E_Pos) /*!< 0x08000000 */ +#define TAMP_CR1_ITAMP12E TAMP_CR1_ITAMP12E_Msk +#define TAMP_CR1_ITAMP13E_Pos (28U) +#define TAMP_CR1_ITAMP13E_Msk (0x1UL << TAMP_CR1_ITAMP13E_Pos) /*!< 0x10000000 */ +#define TAMP_CR1_ITAMP13E TAMP_CR1_ITAMP13E_Msk +#define TAMP_CR1_ITAMP15E_Pos (30U) +#define TAMP_CR1_ITAMP15E_Msk (0x1UL << TAMP_CR1_ITAMP15E_Pos) /*!< 0x40000000 */ +#define TAMP_CR1_ITAMP15E TAMP_CR1_ITAMP15E_Msk + +/******************** Bits definition for TAMP_CR2 register *****************/ +#define TAMP_CR2_TAMP1NOERASE_Pos (0U) +#define TAMP_CR2_TAMP1NOERASE_Msk (0x1UL << TAMP_CR2_TAMP1NOERASE_Pos) /*!< 0x00000001 */ +#define TAMP_CR2_TAMP1NOERASE TAMP_CR2_TAMP1NOERASE_Msk +#define TAMP_CR2_TAMP2NOERASE_Pos (1U) +#define TAMP_CR2_TAMP2NOERASE_Msk (0x1UL << TAMP_CR2_TAMP2NOERASE_Pos) /*!< 0x00000002 */ +#define TAMP_CR2_TAMP2NOERASE TAMP_CR2_TAMP2NOERASE_Msk +#define TAMP_CR2_TAMP3NOERASE_Pos (2U) +#define TAMP_CR2_TAMP3NOERASE_Msk (0x1UL << TAMP_CR2_TAMP3NOERASE_Pos) /*!< 0x00000004 */ +#define TAMP_CR2_TAMP3NOERASE TAMP_CR2_TAMP3NOERASE_Msk +#define TAMP_CR2_TAMP4NOERASE_Pos (3U) +#define TAMP_CR2_TAMP4NOERASE_Msk (0x1UL << TAMP_CR2_TAMP4NOERASE_Pos) /*!< 0x00000008 */ +#define TAMP_CR2_TAMP4NOERASE TAMP_CR2_TAMP4NOERASE_Msk +#define TAMP_CR2_TAMP5NOERASE_Pos (4U) +#define TAMP_CR2_TAMP5NOERASE_Msk (0x1UL << TAMP_CR2_TAMP5NOERASE_Pos) /*!< 0x00000010 */ +#define TAMP_CR2_TAMP5NOERASE TAMP_CR2_TAMP5NOERASE_Msk +#define TAMP_CR2_TAMP6NOERASE_Pos (5U) +#define TAMP_CR2_TAMP6NOERASE_Msk (0x1UL << TAMP_CR2_TAMP6NOERASE_Pos) /*!< 0x00000020 */ +#define TAMP_CR2_TAMP6NOERASE TAMP_CR2_TAMP6NOERASE_Msk +#define TAMP_CR2_TAMP7NOERASE_Pos (6U) +#define TAMP_CR2_TAMP7NOERASE_Msk (0x1UL << TAMP_CR2_TAMP7NOERASE_Pos) /*!< 0x00000040 */ +#define TAMP_CR2_TAMP7NOERASE TAMP_CR2_TAMP7NOERASE_Msk +#define TAMP_CR2_TAMP8NOERASE_Pos (7U) +#define TAMP_CR2_TAMP8NOERASE_Msk (0x1UL << TAMP_CR2_TAMP8NOERASE_Pos) /*!< 0x00000080 */ +#define TAMP_CR2_TAMP8NOERASE TAMP_CR2_TAMP8NOERASE_Msk +#define TAMP_CR2_TAMP1MSK_Pos (16U) +#define TAMP_CR2_TAMP1MSK_Msk (0x1UL << TAMP_CR2_TAMP1MSK_Pos) /*!< 0x00010000 */ +#define TAMP_CR2_TAMP1MSK TAMP_CR2_TAMP1MSK_Msk +#define TAMP_CR2_TAMP2MSK_Pos (17U) +#define TAMP_CR2_TAMP2MSK_Msk (0x1UL << TAMP_CR2_TAMP2MSK_Pos) /*!< 0x00020000 */ +#define TAMP_CR2_TAMP2MSK TAMP_CR2_TAMP2MSK_Msk +#define TAMP_CR2_TAMP3MSK_Pos (18U) +#define TAMP_CR2_TAMP3MSK_Msk (0x1UL << TAMP_CR2_TAMP3MSK_Pos) /*!< 0x00040000 */ +#define TAMP_CR2_TAMP3MSK TAMP_CR2_TAMP3MSK_Msk +#define TAMP_CR2_BKBLOCK_Pos (22U) +#define TAMP_CR2_BKBLOCK_Msk (0x1UL << TAMP_CR2_BKBLOCK_Pos) /*!< 0x00400000 */ +#define TAMP_CR2_BKBLOCK TAMP_CR2_BKBLOCK_Msk +#define TAMP_CR2_BKERASE_Pos (23U) +#define TAMP_CR2_BKERASE_Msk (0x1UL << TAMP_CR2_BKERASE_Pos) /*!< 0x00800000 */ +#define TAMP_CR2_BKERASE TAMP_CR2_BKERASE_Msk +#define TAMP_CR2_TAMP1TRG_Pos (24U) +#define TAMP_CR2_TAMP1TRG_Msk (0x1UL << TAMP_CR2_TAMP1TRG_Pos) /*!< 0x01000000 */ +#define TAMP_CR2_TAMP1TRG TAMP_CR2_TAMP1TRG_Msk +#define TAMP_CR2_TAMP2TRG_Pos (25U) +#define TAMP_CR2_TAMP2TRG_Msk (0x1UL << TAMP_CR2_TAMP2TRG_Pos) /*!< 0x02000000 */ +#define TAMP_CR2_TAMP2TRG TAMP_CR2_TAMP2TRG_Msk +#define TAMP_CR2_TAMP3TRG_Pos (26U) +#define TAMP_CR2_TAMP3TRG_Msk (0x1UL << TAMP_CR2_TAMP3TRG_Pos) /*!< 0x02000000 */ +#define TAMP_CR2_TAMP3TRG TAMP_CR2_TAMP3TRG_Msk +#define TAMP_CR2_TAMP4TRG_Pos (27U) +#define TAMP_CR2_TAMP4TRG_Msk (0x1UL << TAMP_CR2_TAMP4TRG_Pos) /*!< 0x02000000 */ +#define TAMP_CR2_TAMP4TRG TAMP_CR2_TAMP4TRG_Msk +#define TAMP_CR2_TAMP5TRG_Pos (28U) +#define TAMP_CR2_TAMP5TRG_Msk (0x1UL << TAMP_CR2_TAMP5TRG_Pos) /*!< 0x02000000 */ +#define TAMP_CR2_TAMP5TRG TAMP_CR2_TAMP5TRG_Msk +#define TAMP_CR2_TAMP6TRG_Pos (29U) +#define TAMP_CR2_TAMP6TRG_Msk (0x1UL << TAMP_CR2_TAMP6TRG_Pos) /*!< 0x02000000 */ +#define TAMP_CR2_TAMP6TRG TAMP_CR2_TAMP6TRG_Msk +#define TAMP_CR2_TAMP7TRG_Pos (30U) +#define TAMP_CR2_TAMP7TRG_Msk (0x1UL << TAMP_CR2_TAMP7TRG_Pos) /*!< 0x02000000 */ +#define TAMP_CR2_TAMP7TRG TAMP_CR2_TAMP7TRG_Msk +#define TAMP_CR2_TAMP8TRG_Pos (31U) +#define TAMP_CR2_TAMP8TRG_Msk (0x1UL << TAMP_CR2_TAMP8TRG_Pos) /*!< 0x02000000 */ +#define TAMP_CR2_TAMP8TRG TAMP_CR2_TAMP8TRG_Msk + +/******************** Bits definition for TAMP_CR3 register *****************/ +#define TAMP_CR3_ITAMP1NOER_Pos (0U) +#define TAMP_CR3_ITAMP1NOER_Msk (0x1UL << TAMP_CR3_ITAMP1NOER_Pos) /*!< 0x00000001 */ +#define TAMP_CR3_ITAMP1NOER TAMP_CR3_ITAMP1NOER_Msk +#define TAMP_CR3_ITAMP2NOER_Pos (1U) +#define TAMP_CR3_ITAMP2NOER_Msk (0x1UL << TAMP_CR3_ITAMP2NOER_Pos) /*!< 0x00000002 */ +#define TAMP_CR3_ITAMP2NOER TAMP_CR3_ITAMP2NOER_Msk +#define TAMP_CR3_ITAMP3NOER_Pos (2U) +#define TAMP_CR3_ITAMP3NOER_Msk (0x1UL << TAMP_CR3_ITAMP3NOER_Pos) /*!< 0x00000004 */ +#define TAMP_CR3_ITAMP3NOER TAMP_CR3_ITAMP3NOER_Msk +#define TAMP_CR3_ITAMP4NOER_Pos (3U) +#define TAMP_CR3_ITAMP4NOER_Msk (0x1UL << TAMP_CR3_ITAMP4NOER_Pos) /*!< 0x00000008 */ +#define TAMP_CR3_ITAMP4NOER TAMP_CR3_ITAMP4NOER_Msk +#define TAMP_CR3_ITAMP5NOER_Pos (4U) +#define TAMP_CR3_ITAMP5NOER_Msk (0x1UL << TAMP_CR3_ITAMP5NOER_Pos) /*!< 0x00000010 */ +#define TAMP_CR3_ITAMP5NOER TAMP_CR3_ITAMP5NOER_Msk +#define TAMP_CR3_ITAMP6NOER_Pos (5U) +#define TAMP_CR3_ITAMP6NOER_Msk (0x1UL << TAMP_CR3_ITAMP6NOER_Pos) /*!< 0x00000020 */ +#define TAMP_CR3_ITAMP6NOER TAMP_CR3_ITAMP6NOER_Msk +#define TAMP_CR3_ITAMP7NOER_Pos (6U) +#define TAMP_CR3_ITAMP7NOER_Msk (0x1UL << TAMP_CR3_ITAMP7NOER_Pos) /*!< 0x00000040 */ +#define TAMP_CR3_ITAMP7NOER TAMP_CR3_ITAMP7NOER_Msk +#define TAMP_CR3_ITAMP8NOER_Pos (7U) +#define TAMP_CR3_ITAMP8NOER_Msk (0x1UL << TAMP_CR3_ITAMP8NOER_Pos) /*!< 0x00000080 */ +#define TAMP_CR3_ITAMP8NOER TAMP_CR3_ITAMP8NOER_Msk +#define TAMP_CR3_ITAMP9NOER_Pos (8U) +#define TAMP_CR3_ITAMP9NOER_Msk (0x1UL << TAMP_CR3_ITAMP9NOER_Pos) /*!< 0x00000100 */ +#define TAMP_CR3_ITAMP9NOER TAMP_CR3_ITAMP9NOER_Msk +#define TAMP_CR3_ITAMP11NOER_Pos (10U) +#define TAMP_CR3_ITAMP11NOER_Msk (0x1UL << TAMP_CR3_ITAMP11NOER_Pos) /*!< 0x00000400 */ +#define TAMP_CR3_ITAMP11NOER TAMP_CR3_ITAMP11NOER_Msk +#define TAMP_CR3_ITAMP12NOER_Pos (11U) +#define TAMP_CR3_ITAMP12NOER_Msk (0x1UL << TAMP_CR3_ITAMP12NOER_Pos) /*!< 0x00000800 */ +#define TAMP_CR3_ITAMP12NOER TAMP_CR3_ITAMP12NOER_Msk +#define TAMP_CR3_ITAMP13NOER_Pos (12U) +#define TAMP_CR3_ITAMP13NOER_Msk (0x1UL << TAMP_CR3_ITAMP13NOER_Pos) /*!< 0x00001000 */ +#define TAMP_CR3_ITAMP13NOER TAMP_CR3_ITAMP13NOER_Msk +#define TAMP_CR3_ITAMP15NOER_Pos (14U) +#define TAMP_CR3_ITAMP15NOER_Msk (0x1UL << TAMP_CR3_ITAMP15NOER_Pos) /*!< 0x00004000 */ +#define TAMP_CR3_ITAMP15NOER TAMP_CR3_ITAMP15NOER_Msk + +/******************** Bits definition for TAMP_FLTCR register ***************/ +#define TAMP_FLTCR_TAMPFREQ_Pos (0U) +#define TAMP_FLTCR_TAMPFREQ_Msk (0x7UL << TAMP_FLTCR_TAMPFREQ_Pos) /*!< 0x00000007 */ +#define TAMP_FLTCR_TAMPFREQ TAMP_FLTCR_TAMPFREQ_Msk +#define TAMP_FLTCR_TAMPFREQ_0 (0x1UL << TAMP_FLTCR_TAMPFREQ_Pos) /*!< 0x00000001 */ +#define TAMP_FLTCR_TAMPFREQ_1 (0x2UL << TAMP_FLTCR_TAMPFREQ_Pos) /*!< 0x00000002 */ +#define TAMP_FLTCR_TAMPFREQ_2 (0x4UL << TAMP_FLTCR_TAMPFREQ_Pos) /*!< 0x00000004 */ +#define TAMP_FLTCR_TAMPFLT_Pos (3U) +#define TAMP_FLTCR_TAMPFLT_Msk (0x3UL << TAMP_FLTCR_TAMPFLT_Pos) /*!< 0x00000018 */ +#define TAMP_FLTCR_TAMPFLT TAMP_FLTCR_TAMPFLT_Msk +#define TAMP_FLTCR_TAMPFLT_0 (0x1UL << TAMP_FLTCR_TAMPFLT_Pos) /*!< 0x00000008 */ +#define TAMP_FLTCR_TAMPFLT_1 (0x2UL << TAMP_FLTCR_TAMPFLT_Pos) /*!< 0x00000010 */ +#define TAMP_FLTCR_TAMPPRCH_Pos (5U) +#define TAMP_FLTCR_TAMPPRCH_Msk (0x3UL << TAMP_FLTCR_TAMPPRCH_Pos) /*!< 0x00000060 */ +#define TAMP_FLTCR_TAMPPRCH TAMP_FLTCR_TAMPPRCH_Msk +#define TAMP_FLTCR_TAMPPRCH_0 (0x1UL << TAMP_FLTCR_TAMPPRCH_Pos) /*!< 0x00000020 */ +#define TAMP_FLTCR_TAMPPRCH_1 (0x2UL << TAMP_FLTCR_TAMPPRCH_Pos) /*!< 0x00000040 */ +#define TAMP_FLTCR_TAMPPUDIS_Pos (7U) +#define TAMP_FLTCR_TAMPPUDIS_Msk (0x1UL << TAMP_FLTCR_TAMPPUDIS_Pos) /*!< 0x00000080 */ +#define TAMP_FLTCR_TAMPPUDIS TAMP_FLTCR_TAMPPUDIS_Msk + +/******************** Bits definition for TAMP_ATCR1 register ***************/ +#define TAMP_ATCR1_TAMP1AM_Pos (0U) +#define TAMP_ATCR1_TAMP1AM_Msk (0x1UL << TAMP_ATCR1_TAMP1AM_Pos) /*!< 0x00000001 */ +#define TAMP_ATCR1_TAMP1AM TAMP_ATCR1_TAMP1AM_Msk +#define TAMP_ATCR1_TAMP2AM_Pos (1U) +#define TAMP_ATCR1_TAMP2AM_Msk (0x1UL << TAMP_ATCR1_TAMP2AM_Pos) /*!< 0x00000002 */ +#define TAMP_ATCR1_TAMP2AM TAMP_ATCR1_TAMP2AM_Msk +#define TAMP_ATCR1_TAMP3AM_Pos (2U) +#define TAMP_ATCR1_TAMP3AM_Msk (0x1UL << TAMP_ATCR1_TAMP3AM_Pos) /*!< 0x00000004 */ +#define TAMP_ATCR1_TAMP3AM TAMP_ATCR1_TAMP3AM_Msk +#define TAMP_ATCR1_TAMP4AM_Pos (3U) +#define TAMP_ATCR1_TAMP4AM_Msk (0x1UL << TAMP_ATCR1_TAMP4AM_Pos) /*!< 0x00000008 */ +#define TAMP_ATCR1_TAMP4AM TAMP_ATCR1_TAMP4AM_Msk +#define TAMP_ATCR1_TAMP5AM_Pos (4U) +#define TAMP_ATCR1_TAMP5AM_Msk (0x1UL << TAMP_ATCR1_TAMP5AM_Pos) /*!< 0x00000010 */ +#define TAMP_ATCR1_TAMP5AM TAMP_ATCR1_TAMP5AM_Msk +#define TAMP_ATCR1_TAMP6AM_Pos (5U) +#define TAMP_ATCR1_TAMP6AM_Msk (0x1UL << TAMP_ATCR1_TAMP6AM_Pos) /*!< 0x00000010 */ +#define TAMP_ATCR1_TAMP6AM TAMP_ATCR1_TAMP6AM_Msk +#define TAMP_ATCR1_TAMP7AM_Pos (6U) +#define TAMP_ATCR1_TAMP7AM_Msk (0x1UL << TAMP_ATCR1_TAMP7AM_Pos) /*!< 0x00000040 */ +#define TAMP_ATCR1_TAMP7AM TAMP_ATCR1_TAMP7AM_Msk +#define TAMP_ATCR1_TAMP8AM_Pos (7U) +#define TAMP_ATCR1_TAMP8AM_Msk (0x1UL << TAMP_ATCR1_TAMP8AM_Pos) /*!< 0x00000080 */ +#define TAMP_ATCR1_TAMP8AM TAMP_ATCR1_TAMP8AM_Msk +#define TAMP_ATCR1_ATOSEL1_Pos (8U) +#define TAMP_ATCR1_ATOSEL1_Msk (0x3UL << TAMP_ATCR1_ATOSEL1_Pos) /*!< 0x00000300 */ +#define TAMP_ATCR1_ATOSEL1 TAMP_ATCR1_ATOSEL1_Msk +#define TAMP_ATCR1_ATOSEL1_0 (0x1UL << TAMP_ATCR1_ATOSEL1_Pos) /*!< 0x00000100 */ +#define TAMP_ATCR1_ATOSEL1_1 (0x2UL << TAMP_ATCR1_ATOSEL1_Pos) /*!< 0x00000200 */ +#define TAMP_ATCR1_ATOSEL2_Pos (10U) +#define TAMP_ATCR1_ATOSEL2_Msk (0x3UL << TAMP_ATCR1_ATOSEL2_Pos) /*!< 0x00000C00 */ +#define TAMP_ATCR1_ATOSEL2 TAMP_ATCR1_ATOSEL2_Msk +#define TAMP_ATCR1_ATOSEL2_0 (0x1UL << TAMP_ATCR1_ATOSEL2_Pos) /*!< 0x00000400 */ +#define TAMP_ATCR1_ATOSEL2_1 (0x2UL << TAMP_ATCR1_ATOSEL2_Pos) /*!< 0x00000800 */ +#define TAMP_ATCR1_ATOSEL3_Pos (12U) +#define TAMP_ATCR1_ATOSEL3_Msk (0x3UL << TAMP_ATCR1_ATOSEL3_Pos) /*!< 0x00003000 */ +#define TAMP_ATCR1_ATOSEL3 TAMP_ATCR1_ATOSEL3_Msk +#define TAMP_ATCR1_ATOSEL3_0 (0x1UL << TAMP_ATCR1_ATOSEL3_Pos) /*!< 0x00001000 */ +#define TAMP_ATCR1_ATOSEL3_1 (0x2UL << TAMP_ATCR1_ATOSEL3_Pos) /*!< 0x00002000 */ +#define TAMP_ATCR1_ATOSEL4_Pos (14U) +#define TAMP_ATCR1_ATOSEL4_Msk (0x3UL << TAMP_ATCR1_ATOSEL4_Pos) /*!< 0x0000C000 */ +#define TAMP_ATCR1_ATOSEL4 TAMP_ATCR1_ATOSEL4_Msk +#define TAMP_ATCR1_ATOSEL4_0 (0x1UL << TAMP_ATCR1_ATOSEL4_Pos) /*!< 0x00004000 */ +#define TAMP_ATCR1_ATOSEL4_1 (0x2UL << TAMP_ATCR1_ATOSEL4_Pos) /*!< 0x00008000 */ +#define TAMP_ATCR1_ATCKSEL_Pos (16U) +#define TAMP_ATCR1_ATCKSEL_Msk (0xFUL << TAMP_ATCR1_ATCKSEL_Pos) /*!< 0x000F0000 */ +#define TAMP_ATCR1_ATCKSEL TAMP_ATCR1_ATCKSEL_Msk +#define TAMP_ATCR1_ATCKSEL_0 (0x1UL << TAMP_ATCR1_ATCKSEL_Pos) /*!< 0x00010000 */ +#define TAMP_ATCR1_ATCKSEL_1 (0x2UL << TAMP_ATCR1_ATCKSEL_Pos) /*!< 0x00020000 */ +#define TAMP_ATCR1_ATCKSEL_2 (0x4UL << TAMP_ATCR1_ATCKSEL_Pos) /*!< 0x00040000 */ +#define TAMP_ATCR1_ATCKSEL_3 (0x8UL << TAMP_ATCR1_ATCKSEL_Pos) /*!< 0x00080000 */ +#define TAMP_ATCR1_ATPER_Pos (24U) +#define TAMP_ATCR1_ATPER_Msk (0x7UL << TAMP_ATCR1_ATPER_Pos) /*!< 0x07000000 */ +#define TAMP_ATCR1_ATPER TAMP_ATCR1_ATPER_Msk +#define TAMP_ATCR1_ATPER_0 (0x1UL << TAMP_ATCR1_ATPER_Pos) /*!< 0x01000000 */ +#define TAMP_ATCR1_ATPER_1 (0x2UL << TAMP_ATCR1_ATPER_Pos) /*!< 0x02000000 */ +#define TAMP_ATCR1_ATPER_2 (0x4UL << TAMP_ATCR1_ATPER_Pos) /*!< 0x04000000 */ +#define TAMP_ATCR1_ATOSHARE_Pos (30U) +#define TAMP_ATCR1_ATOSHARE_Msk (0x1UL << TAMP_ATCR1_ATOSHARE_Pos) /*!< 0x40000000 */ +#define TAMP_ATCR1_ATOSHARE TAMP_ATCR1_ATOSHARE_Msk +#define TAMP_ATCR1_FLTEN_Pos (31U) +#define TAMP_ATCR1_FLTEN_Msk (0x1UL << TAMP_ATCR1_FLTEN_Pos) /*!< 0x80000000 */ +#define TAMP_ATCR1_FLTEN TAMP_ATCR1_FLTEN_Msk + +/******************** Bits definition for TAMP_ATSEEDR register ******************/ +#define TAMP_ATSEEDR_SEED_Pos (0U) +#define TAMP_ATSEEDR_SEED_Msk (0xFFFFFFFFUL << TAMP_ATSEEDR_SEED_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_ATSEEDR_SEED TAMP_ATSEEDR_SEED_Msk + +/******************** Bits definition for TAMP_ATOR register ******************/ +#define TAMP_ATOR_PRNG_Pos (0U) +#define TAMP_ATOR_PRNG_Msk (0xFFUL << TAMP_ATOR_PRNG_Pos) /*!< 0x000000FF */ +#define TAMP_ATOR_PRNG TAMP_ATOR_PRNG_Msk +#define TAMP_ATOR_PRNG_0 (0x1UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000001 */ +#define TAMP_ATOR_PRNG_1 (0x2UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000002 */ +#define TAMP_ATOR_PRNG_2 (0x4UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000004 */ +#define TAMP_ATOR_PRNG_3 (0x8UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000008 */ +#define TAMP_ATOR_PRNG_4 (0x10UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000010 */ +#define TAMP_ATOR_PRNG_5 (0x20UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000020 */ +#define TAMP_ATOR_PRNG_6 (0x40UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000040 */ +#define TAMP_ATOR_PRNG_7 (0x80UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000080 */ +#define TAMP_ATOR_SEEDF_Pos (14U) +#define TAMP_ATOR_SEEDF_Msk (1UL << TAMP_ATOR_SEEDF_Pos) /*!< 0x00004000 */ +#define TAMP_ATOR_SEEDF TAMP_ATOR_SEEDF_Msk +#define TAMP_ATOR_INITS_Pos (15U) +#define TAMP_ATOR_INITS_Msk (1UL << TAMP_ATOR_INITS_Pos) /*!< 0x00008000 */ +#define TAMP_ATOR_INITS TAMP_ATOR_INITS_Msk + +/******************** Bits definition for TAMP_ATCR2 register ***************/ +#define TAMP_ATCR2_ATOSEL1_Pos (8U) +#define TAMP_ATCR2_ATOSEL1_Msk (0x7UL << TAMP_ATCR2_ATOSEL1_Pos) /*!< 0x00000700 */ +#define TAMP_ATCR2_ATOSEL1 TAMP_ATCR2_ATOSEL1_Msk +#define TAMP_ATCR2_ATOSEL1_0 (0x1UL << TAMP_ATCR2_ATOSEL1_Pos) /*!< 0x00000100 */ +#define TAMP_ATCR2_ATOSEL1_1 (0x2UL << TAMP_ATCR2_ATOSEL1_Pos) /*!< 0x00000200 */ +#define TAMP_ATCR2_ATOSEL1_2 (0x4UL << TAMP_ATCR2_ATOSEL1_Pos) /*!< 0x00000400 */ +#define TAMP_ATCR2_ATOSEL2_Pos (11U) +#define TAMP_ATCR2_ATOSEL2_Msk (0x7UL << TAMP_ATCR2_ATOSEL2_Pos) /*!< 0x00003800 */ +#define TAMP_ATCR2_ATOSEL2 TAMP_ATCR2_ATOSEL2_Msk +#define TAMP_ATCR2_ATOSEL2_0 (0x1UL << TAMP_ATCR2_ATOSEL2_Pos) /*!< 0x00000800 */ +#define TAMP_ATCR2_ATOSEL2_1 (0x2UL << TAMP_ATCR2_ATOSEL2_Pos) /*!< 0x00001000 */ +#define TAMP_ATCR2_ATOSEL2_2 (0x4UL << TAMP_ATCR2_ATOSEL2_Pos) /*!< 0x00002000 */ +#define TAMP_ATCR2_ATOSEL3_Pos (14U) +#define TAMP_ATCR2_ATOSEL3_Msk (0x7UL << TAMP_ATCR2_ATOSEL3_Pos) /*!< 0x0001C000 */ +#define TAMP_ATCR2_ATOSEL3 TAMP_ATCR2_ATOSEL3_Msk +#define TAMP_ATCR2_ATOSEL3_0 (0x1UL << TAMP_ATCR2_ATOSEL3_Pos) /*!< 0x00004000 */ +#define TAMP_ATCR2_ATOSEL3_1 (0x2UL << TAMP_ATCR2_ATOSEL3_Pos) /*!< 0x00008000 */ +#define TAMP_ATCR2_ATOSEL3_2 (0x4UL << TAMP_ATCR2_ATOSEL3_Pos) /*!< 0x00010000 */ +#define TAMP_ATCR2_ATOSEL4_Pos (17U) +#define TAMP_ATCR2_ATOSEL4_Msk (0x7UL << TAMP_ATCR2_ATOSEL4_Pos) /*!< 0x000E0000 */ +#define TAMP_ATCR2_ATOSEL4 TAMP_ATCR2_ATOSEL4_Msk +#define TAMP_ATCR2_ATOSEL4_0 (0x1UL << TAMP_ATCR2_ATOSEL4_Pos) /*!< 0x00020000 */ +#define TAMP_ATCR2_ATOSEL4_1 (0x2UL << TAMP_ATCR2_ATOSEL4_Pos) /*!< 0x00040000 */ +#define TAMP_ATCR2_ATOSEL4_2 (0x4UL << TAMP_ATCR2_ATOSEL4_Pos) /*!< 0x00080000 */ +#define TAMP_ATCR2_ATOSEL5_Pos (20U) +#define TAMP_ATCR2_ATOSEL5_Msk (0x7UL << TAMP_ATCR2_ATOSEL5_Pos) /*!< 0x00700000 */ +#define TAMP_ATCR2_ATOSEL5 TAMP_ATCR2_ATOSEL5_Msk +#define TAMP_ATCR2_ATOSEL5_0 (0x1UL << TAMP_ATCR2_ATOSEL5_Pos) /*!< 0x00100000 */ +#define TAMP_ATCR2_ATOSEL5_1 (0x2UL << TAMP_ATCR2_ATOSEL5_Pos) /*!< 0x00200000 */ +#define TAMP_ATCR2_ATOSEL5_2 (0x4UL << TAMP_ATCR2_ATOSEL5_Pos) /*!< 0x00400000 */ +#define TAMP_ATCR2_ATOSEL6_Pos (23U) +#define TAMP_ATCR2_ATOSEL6_Msk (0x7UL << TAMP_ATCR2_ATOSEL6_Pos) /*!< 0x03800000 */ +#define TAMP_ATCR2_ATOSEL6 TAMP_ATCR2_ATOSEL6_Msk +#define TAMP_ATCR2_ATOSEL6_0 (0x1UL << TAMP_ATCR2_ATOSEL6_Pos) /*!< 0x00800000 */ +#define TAMP_ATCR2_ATOSEL6_1 (0x2UL << TAMP_ATCR2_ATOSEL6_Pos) /*!< 0x01000000 */ +#define TAMP_ATCR2_ATOSEL6_2 (0x4UL << TAMP_ATCR2_ATOSEL6_Pos) /*!< 0x02000000 */ +#define TAMP_ATCR2_ATOSEL7_Pos (26U) +#define TAMP_ATCR2_ATOSEL7_Msk (0x7UL << TAMP_ATCR2_ATOSEL7_Pos) /*!< 0x1C000000 */ +#define TAMP_ATCR2_ATOSEL7 TAMP_ATCR2_ATOSEL7_Msk +#define TAMP_ATCR2_ATOSEL7_0 (0x1UL << TAMP_ATCR2_ATOSEL7_Pos) /*!< 0x04000000 */ +#define TAMP_ATCR2_ATOSEL7_1 (0x2UL << TAMP_ATCR2_ATOSEL7_Pos) /*!< 0x08000000 */ +#define TAMP_ATCR2_ATOSEL7_2 (0x4UL << TAMP_ATCR2_ATOSEL7_Pos) /*!< 0x10000000 */ +#define TAMP_ATCR2_ATOSEL8_Pos (29U) +#define TAMP_ATCR2_ATOSEL8_Msk (0x7UL << TAMP_ATCR2_ATOSEL8_Pos) /*!< 0xE0000000 */ +#define TAMP_ATCR2_ATOSEL8 TAMP_ATCR2_ATOSEL8_Msk +#define TAMP_ATCR2_ATOSEL8_0 (0x1UL << TAMP_ATCR2_ATOSEL8_Pos) /*!< 0x20000000 */ +#define TAMP_ATCR2_ATOSEL8_1 (0x2UL << TAMP_ATCR2_ATOSEL8_Pos) /*!< 0x40000000 */ +#define TAMP_ATCR2_ATOSEL8_2 (0x4UL << TAMP_ATCR2_ATOSEL8_Pos) /*!< 0x80000000 */ + +/******************** Bits definition for TAMP_SECCFGR register *************/ +#define TAMP_SECCFGR_BKPRWSEC_Pos (0U) +#define TAMP_SECCFGR_BKPRWSEC_Msk (0xFFUL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x000000FF */ +#define TAMP_SECCFGR_BKPRWSEC TAMP_SECCFGR_BKPRWSEC_Msk +#define TAMP_SECCFGR_BKPRWSEC_0 (0x1UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000001 */ +#define TAMP_SECCFGR_BKPRWSEC_1 (0x2UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000002 */ +#define TAMP_SECCFGR_BKPRWSEC_2 (0x4UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000004 */ +#define TAMP_SECCFGR_BKPRWSEC_3 (0x8UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000008 */ +#define TAMP_SECCFGR_BKPRWSEC_4 (0x10UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000010 */ +#define TAMP_SECCFGR_BKPRWSEC_5 (0x20UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000020 */ +#define TAMP_SECCFGR_BKPRWSEC_6 (0x40UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000040 */ +#define TAMP_SECCFGR_BKPRWSEC_7 (0x80UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000080 */ +#define TAMP_SECCFGR_CNT1SEC_Pos (15U) +#define TAMP_SECCFGR_CNT1SEC_Msk (0x1UL << TAMP_SECCFGR_CNT1SEC_Pos) /*!< 0x00008000 */ +#define TAMP_SECCFGR_CNT1SEC TAMP_SECCFGR_CNT1SEC_Msk +#define TAMP_SECCFGR_BKPWSEC_Pos (16U) +#define TAMP_SECCFGR_BKPWSEC_Msk (0xFFUL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00FF0000 */ +#define TAMP_SECCFGR_BKPWSEC TAMP_SECCFGR_BKPWSEC_Msk +#define TAMP_SECCFGR_BKPWSEC_0 (0x1UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00010000 */ +#define TAMP_SECCFGR_BKPWSEC_1 (0x2UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00020000 */ +#define TAMP_SECCFGR_BKPWSEC_2 (0x4UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00040000 */ +#define TAMP_SECCFGR_BKPWSEC_3 (0x8UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00080000 */ +#define TAMP_SECCFGR_BKPWSEC_4 (0x10UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00100000 */ +#define TAMP_SECCFGR_BKPWSEC_5 (0x20UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00200000 */ +#define TAMP_SECCFGR_BKPWSEC_6 (0x40UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00400000 */ +#define TAMP_SECCFGR_BKPWSEC_7 (0x80UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00800000 */ +#define TAMP_SECCFGR_BHKLOCK_Pos (30U) +#define TAMP_SECCFGR_BHKLOCK_Msk (0x1UL << TAMP_SECCFGR_BHKLOCK_Pos) /*!< 0x40000000 */ +#define TAMP_SECCFGR_BHKLOCK TAMP_SECCFGR_BHKLOCK_Msk +#define TAMP_SECCFGR_TAMPSEC_Pos (31U) +#define TAMP_SECCFGR_TAMPSEC_Msk (0x1UL << TAMP_SECCFGR_TAMPSEC_Pos) /*!< 0x80000000 */ +#define TAMP_SECCFGR_TAMPSEC TAMP_SECCFGR_TAMPSEC_Msk + +/******************** Bits definition for TAMP_PRIVCFGR register ************/ +#define TAMP_PRIVCFGR_CNT1PRIV_Pos (15U) +#define TAMP_PRIVCFGR_CNT1PRIV_Msk (0x1UL << TAMP_PRIVCFGR_CNT1PRIV_Pos) /*!< 0x20000000 */ +#define TAMP_PRIVCFGR_CNT1PRIV TAMP_PRIVCFGR_CNT1PRIV_Msk +#define TAMP_PRIVCFGR_BKPRWPRIV_Pos (29U) +#define TAMP_PRIVCFGR_BKPRWPRIV_Msk (0x1UL << TAMP_PRIVCFGR_BKPRWPRIV_Pos) /*!< 0x20000000 */ +#define TAMP_PRIVCFGR_BKPRWPRIV TAMP_PRIVCFGR_BKPRWPRIV_Msk +#define TAMP_PRIVCFGR_BKPWPRIV_Pos (30U) +#define TAMP_PRIVCFGR_BKPWPRIV_Msk (0x1UL << TAMP_PRIVCFGR_BKPWPRIV_Pos) /*!< 0x40000000 */ +#define TAMP_PRIVCFGR_BKPWPRIV TAMP_PRIVCFGR_BKPWPRIV_Msk +#define TAMP_PRIVCFGR_TAMPPRIV_Pos (31U) +#define TAMP_PRIVCFGR_TAMPPRIV_Msk (0x1UL << TAMP_PRIVCFGR_TAMPPRIV_Pos) /*!< 0x80000000 */ +#define TAMP_PRIVCFGR_TAMPPRIV TAMP_PRIVCFGR_TAMPPRIV_Msk + +/******************** Bits definition for TAMP_IER register *****************/ +#define TAMP_IER_TAMP1IE_Pos (0U) +#define TAMP_IER_TAMP1IE_Msk (0x1UL << TAMP_IER_TAMP1IE_Pos) /*!< 0x00000001 */ +#define TAMP_IER_TAMP1IE TAMP_IER_TAMP1IE_Msk +#define TAMP_IER_TAMP2IE_Pos (1U) +#define TAMP_IER_TAMP2IE_Msk (0x1UL << TAMP_IER_TAMP2IE_Pos) /*!< 0x00000002 */ +#define TAMP_IER_TAMP2IE TAMP_IER_TAMP2IE_Msk +#define TAMP_IER_TAMP3IE_Pos (2U) +#define TAMP_IER_TAMP3IE_Msk (0x1UL << TAMP_IER_TAMP3IE_Pos) /*!< 0x00000004 */ +#define TAMP_IER_TAMP3IE TAMP_IER_TAMP3IE_Msk +#define TAMP_IER_TAMP4IE_Pos (3U) +#define TAMP_IER_TAMP4IE_Msk (0x1UL << TAMP_IER_TAMP4IE_Pos) /*!< 0x00000008 */ +#define TAMP_IER_TAMP4IE TAMP_IER_TAMP4IE_Msk +#define TAMP_IER_TAMP5IE_Pos (4U) +#define TAMP_IER_TAMP5IE_Msk (0x1UL << TAMP_IER_TAMP5IE_Pos) /*!< 0x00000010 */ +#define TAMP_IER_TAMP5IE TAMP_IER_TAMP5IE_Msk +#define TAMP_IER_TAMP6IE_Pos (5U) +#define TAMP_IER_TAMP6IE_Msk (0x1UL << TAMP_IER_TAMP6IE_Pos) /*!< 0x00000020 */ +#define TAMP_IER_TAMP6IE TAMP_IER_TAMP6IE_Msk +#define TAMP_IER_TAMP7IE_Pos (6U) +#define TAMP_IER_TAMP7IE_Msk (0x1UL << TAMP_IER_TAMP7IE_Pos) /*!< 0x00000040 */ +#define TAMP_IER_TAMP7IE TAMP_IER_TAMP7IE_Msk +#define TAMP_IER_TAMP8IE_Pos (7U) +#define TAMP_IER_TAMP8IE_Msk (0x1UL << TAMP_IER_TAMP8IE_Pos) /*!< 0x00000080 */ +#define TAMP_IER_TAMP8IE TAMP_IER_TAMP8IE_Msk +#define TAMP_IER_ITAMP1IE_Pos (16U) +#define TAMP_IER_ITAMP1IE_Msk (0x1UL << TAMP_IER_ITAMP1IE_Pos) /*!< 0x00010000 */ +#define TAMP_IER_ITAMP1IE TAMP_IER_ITAMP1IE_Msk +#define TAMP_IER_ITAMP2IE_Pos (17U) +#define TAMP_IER_ITAMP2IE_Msk (0x1UL << TAMP_IER_ITAMP2IE_Pos) /*!< 0x00020000 */ +#define TAMP_IER_ITAMP2IE TAMP_IER_ITAMP2IE_Msk +#define TAMP_IER_ITAMP3IE_Pos (18U) +#define TAMP_IER_ITAMP3IE_Msk (0x1UL << TAMP_IER_ITAMP3IE_Pos) /*!< 0x00040000 */ +#define TAMP_IER_ITAMP3IE TAMP_IER_ITAMP3IE_Msk +#define TAMP_IER_ITAMP4IE_Pos (19U) +#define TAMP_IER_ITAMP4IE_Msk (0x1UL << TAMP_IER_ITAMP4IE_Pos) /*!< 0x00080000 */ +#define TAMP_IER_ITAMP4IE TAMP_IER_ITAMP4IE_Msk +#define TAMP_IER_ITAMP5IE_Pos (20U) +#define TAMP_IER_ITAMP5IE_Msk (0x1UL << TAMP_IER_ITAMP5IE_Pos) /*!< 0x00100000 */ +#define TAMP_IER_ITAMP5IE TAMP_IER_ITAMP5IE_Msk +#define TAMP_IER_ITAMP6IE_Pos (21U) +#define TAMP_IER_ITAMP6IE_Msk (0x1UL << TAMP_IER_ITAMP6IE_Pos) /*!< 0x00200000 */ +#define TAMP_IER_ITAMP6IE TAMP_IER_ITAMP6IE_Msk +#define TAMP_IER_ITAMP7IE_Pos (22U) +#define TAMP_IER_ITAMP7IE_Msk (0x1UL << TAMP_IER_ITAMP7IE_Pos) /*!< 0x00400000 */ +#define TAMP_IER_ITAMP7IE TAMP_IER_ITAMP7IE_Msk +#define TAMP_IER_ITAMP8IE_Pos (23U) +#define TAMP_IER_ITAMP8IE_Msk (0x1UL << TAMP_IER_ITAMP8IE_Pos) /*!< 0x00800000 */ +#define TAMP_IER_ITAMP8IE TAMP_IER_ITAMP8IE_Msk +#define TAMP_IER_ITAMP9IE_Pos (24U) +#define TAMP_IER_ITAMP9IE_Msk (0x1UL << TAMP_IER_ITAMP9IE_Pos) /*!< 0x01000000 */ +#define TAMP_IER_ITAMP9IE TAMP_IER_ITAMP9IE_Msk +#define TAMP_IER_ITAMP11IE_Pos (26U) +#define TAMP_IER_ITAMP11IE_Msk (0x1UL << TAMP_IER_ITAMP11IE_Pos) /*!< 0x04000000 */ +#define TAMP_IER_ITAMP11IE TAMP_IER_ITAMP11IE_Msk +#define TAMP_IER_ITAMP12IE_Pos (27U) +#define TAMP_IER_ITAMP12IE_Msk (0x1UL << TAMP_IER_ITAMP12IE_Pos) /*!< 0x08000000 */ +#define TAMP_IER_ITAMP12IE TAMP_IER_ITAMP12IE_Msk +#define TAMP_IER_ITAMP13IE_Pos (28U) +#define TAMP_IER_ITAMP13IE_Msk (0x1UL << TAMP_IER_ITAMP13IE_Pos) /*!< 0x10000000 */ +#define TAMP_IER_ITAMP13IE TAMP_IER_ITAMP13IE_Msk +#define TAMP_IER_ITAMP15IE_Pos (30U) +#define TAMP_IER_ITAMP15IE_Msk (0x1UL << TAMP_IER_ITAMP15IE_Pos) /*!< 0x40000000 */ +#define TAMP_IER_ITAMP15IE TAMP_IER_ITAMP15IE_Msk + +/******************** Bits definition for TAMP_SR register *****************/ +#define TAMP_SR_TAMP1F_Pos (0U) +#define TAMP_SR_TAMP1F_Msk (0x1UL << TAMP_SR_TAMP1F_Pos) /*!< 0x00000001 */ +#define TAMP_SR_TAMP1F TAMP_SR_TAMP1F_Msk +#define TAMP_SR_TAMP2F_Pos (1U) +#define TAMP_SR_TAMP2F_Msk (0x1UL << TAMP_SR_TAMP2F_Pos) /*!< 0x00000002 */ +#define TAMP_SR_TAMP2F TAMP_SR_TAMP2F_Msk +#define TAMP_SR_TAMP3F_Pos (2U) +#define TAMP_SR_TAMP3F_Msk (0x1UL << TAMP_SR_TAMP3F_Pos) /*!< 0x00000004 */ +#define TAMP_SR_TAMP3F TAMP_SR_TAMP3F_Msk +#define TAMP_SR_TAMP4F_Pos (3U) +#define TAMP_SR_TAMP4F_Msk (0x1UL << TAMP_SR_TAMP4F_Pos) /*!< 0x00000008 */ +#define TAMP_SR_TAMP4F TAMP_SR_TAMP4F_Msk +#define TAMP_SR_TAMP5F_Pos (4U) +#define TAMP_SR_TAMP5F_Msk (0x1UL << TAMP_SR_TAMP5F_Pos) /*!< 0x00000010 */ +#define TAMP_SR_TAMP5F TAMP_SR_TAMP5F_Msk +#define TAMP_SR_TAMP6F_Pos (5U) +#define TAMP_SR_TAMP6F_Msk (0x1UL << TAMP_SR_TAMP6F_Pos) /*!< 0x00000020 */ +#define TAMP_SR_TAMP6F TAMP_SR_TAMP6F_Msk +#define TAMP_SR_TAMP7F_Pos (6U) +#define TAMP_SR_TAMP7F_Msk (0x1UL << TAMP_SR_TAMP7F_Pos) /*!< 0x00000040 */ +#define TAMP_SR_TAMP7F TAMP_SR_TAMP7F_Msk +#define TAMP_SR_TAMP8F_Pos (7U) +#define TAMP_SR_TAMP8F_Msk (0x1UL << TAMP_SR_TAMP8F_Pos) /*!< 0x00000080 */ +#define TAMP_SR_TAMP8F TAMP_SR_TAMP8F_Msk +#define TAMP_SR_ITAMP1F_Pos (16U) +#define TAMP_SR_ITAMP1F_Msk (0x1UL << TAMP_SR_ITAMP1F_Pos) /*!< 0x00010000 */ +#define TAMP_SR_ITAMP1F TAMP_SR_ITAMP1F_Msk +#define TAMP_SR_ITAMP2F_Pos (17U) +#define TAMP_SR_ITAMP2F_Msk (0x1UL << TAMP_SR_ITAMP2F_Pos) /*!< 0x00020000 */ +#define TAMP_SR_ITAMP2F TAMP_SR_ITAMP2F_Msk +#define TAMP_SR_ITAMP3F_Pos (18U) +#define TAMP_SR_ITAMP3F_Msk (0x1UL << TAMP_SR_ITAMP3F_Pos) /*!< 0x00040000 */ +#define TAMP_SR_ITAMP3F TAMP_SR_ITAMP3F_Msk +#define TAMP_SR_ITAMP4F_Pos (19U) +#define TAMP_SR_ITAMP4F_Msk (0x1UL << TAMP_SR_ITAMP4F_Pos) /*!< 0x00080000 */ +#define TAMP_SR_ITAMP4F TAMP_SR_ITAMP4F_Msk +#define TAMP_SR_ITAMP5F_Pos (20U) +#define TAMP_SR_ITAMP5F_Msk (0x1UL << TAMP_SR_ITAMP5F_Pos) /*!< 0x00100000 */ +#define TAMP_SR_ITAMP5F TAMP_SR_ITAMP5F_Msk +#define TAMP_SR_ITAMP6F_Pos (21U) +#define TAMP_SR_ITAMP6F_Msk (0x1UL << TAMP_SR_ITAMP6F_Pos) /*!< 0x00200000 */ +#define TAMP_SR_ITAMP6F TAMP_SR_ITAMP6F_Msk +#define TAMP_SR_ITAMP7F_Pos (22U) +#define TAMP_SR_ITAMP7F_Msk (0x1UL << TAMP_SR_ITAMP7F_Pos) /*!< 0x00400000 */ +#define TAMP_SR_ITAMP7F TAMP_SR_ITAMP7F_Msk +#define TAMP_SR_ITAMP8F_Pos (23U) +#define TAMP_SR_ITAMP8F_Msk (0x1UL << TAMP_SR_ITAMP8F_Pos) /*!< 0x00800000 */ +#define TAMP_SR_ITAMP8F TAMP_SR_ITAMP8F_Msk +#define TAMP_SR_ITAMP9F_Pos (24U) +#define TAMP_SR_ITAMP9F_Msk (0x1UL << TAMP_SR_ITAMP9F_Pos) /*!< 0x01000000 */ +#define TAMP_SR_ITAMP9F TAMP_SR_ITAMP9F_Msk +#define TAMP_SR_ITAMP11F_Pos (26U) +#define TAMP_SR_ITAMP11F_Msk (0x1UL << TAMP_SR_ITAMP11F_Pos) /*!< 0x04000000 */ +#define TAMP_SR_ITAMP11F TAMP_SR_ITAMP11F_Msk +#define TAMP_SR_ITAMP12F_Pos (27U) +#define TAMP_SR_ITAMP12F_Msk (0x1UL << TAMP_SR_ITAMP12F_Pos) /*!< 0x08000000 */ +#define TAMP_SR_ITAMP12F TAMP_SR_ITAMP12F_Msk +#define TAMP_SR_ITAMP13F_Pos (28U) +#define TAMP_SR_ITAMP13F_Msk (0x1UL << TAMP_SR_ITAMP13F_Pos) /*!< 0x10000000 */ +#define TAMP_SR_ITAMP13F TAMP_SR_ITAMP13F_Msk +#define TAMP_SR_ITAMP15F_Pos (30U) +#define TAMP_SR_ITAMP15F_Msk (0x1UL << TAMP_SR_ITAMP15F_Pos) /*!< 0x40000000 */ +#define TAMP_SR_ITAMP15F TAMP_SR_ITAMP15F_Msk + +/******************** Bits definition for TAMP_MISR register ****************/ +#define TAMP_MISR_TAMP1MF_Pos (0U) +#define TAMP_MISR_TAMP1MF_Msk (0x1UL << TAMP_MISR_TAMP1MF_Pos) /*!< 0x00000001 */ +#define TAMP_MISR_TAMP1MF TAMP_MISR_TAMP1MF_Msk +#define TAMP_MISR_TAMP2MF_Pos (1U) +#define TAMP_MISR_TAMP2MF_Msk (0x1UL << TAMP_MISR_TAMP2MF_Pos) /*!< 0x00000002 */ +#define TAMP_MISR_TAMP2MF TAMP_MISR_TAMP2MF_Msk +#define TAMP_MISR_TAMP3MF_Pos (2U) +#define TAMP_MISR_TAMP3MF_Msk (0x1UL << TAMP_MISR_TAMP3MF_Pos) /*!< 0x00000004 */ +#define TAMP_MISR_TAMP3MF TAMP_MISR_TAMP3MF_Msk +#define TAMP_MISR_TAMP4MF_Pos (3U) +#define TAMP_MISR_TAMP4MF_Msk (0x1UL << TAMP_MISR_TAMP4MF_Pos) /*!< 0x00000008 */ +#define TAMP_MISR_TAMP4MF TAMP_MISR_TAMP4MF_Msk +#define TAMP_MISR_TAMP5MF_Pos (4U) +#define TAMP_MISR_TAMP5MF_Msk (0x1UL << TAMP_MISR_TAMP5MF_Pos) /*!< 0x00000010 */ +#define TAMP_MISR_TAMP5MF TAMP_MISR_TAMP5MF_Msk +#define TAMP_MISR_TAMP6MF_Pos (5U) +#define TAMP_MISR_TAMP6MF_Msk (0x1UL << TAMP_MISR_TAMP6MF_Pos) /*!< 0x00000020 */ +#define TAMP_MISR_TAMP6MF TAMP_MISR_TAMP6MF_Msk +#define TAMP_MISR_TAMP7MF_Pos (6U) +#define TAMP_MISR_TAMP7MF_Msk (0x1UL << TAMP_MISR_TAMP7MF_Pos) /*!< 0x00000040 */ +#define TAMP_MISR_TAMP7MF TAMP_MISR_TAMP7MF_Msk +#define TAMP_MISR_TAMP8MF_Pos (7U) +#define TAMP_MISR_TAMP8MF_Msk (0x1UL << TAMP_MISR_TAMP8MF_Pos) /*!< 0x00000080 */ +#define TAMP_MISR_TAMP8MF TAMP_MISR_TAMP8MF_Msk +#define TAMP_MISR_ITAMP1MF_Pos (16U) +#define TAMP_MISR_ITAMP1MF_Msk (0x1UL << TAMP_MISR_ITAMP1MF_Pos) /*!< 0x00010000 */ +#define TAMP_MISR_ITAMP1MF TAMP_MISR_ITAMP1MF_Msk +#define TAMP_MISR_ITAMP2MF_Pos (17U) +#define TAMP_MISR_ITAMP2MF_Msk (0x1UL << TAMP_MISR_ITAMP2MF_Pos) /*!< 0x00020000 */ +#define TAMP_MISR_ITAMP2MF TAMP_MISR_ITAMP2MF_Msk +#define TAMP_MISR_ITAMP3MF_Pos (18U) +#define TAMP_MISR_ITAMP3MF_Msk (0x1UL << TAMP_MISR_ITAMP3MF_Pos) /*!< 0x00040000 */ +#define TAMP_MISR_ITAMP3MF TAMP_MISR_ITAMP3MF_Msk +#define TAMP_MISR_ITAMP4MF_Pos (19U) +#define TAMP_MISR_ITAMP4MF_Msk (0x1UL << TAMP_MISR_ITAMP4MF_Pos) /*!< 0x00080000 */ +#define TAMP_MISR_ITAMP4MF TAMP_MISR_ITAMP4MF_Msk +#define TAMP_MISR_ITAMP5MF_Pos (20U) +#define TAMP_MISR_ITAMP5MF_Msk (0x1UL << TAMP_MISR_ITAMP5MF_Pos) /*!< 0x00100000 */ +#define TAMP_MISR_ITAMP5MF TAMP_MISR_ITAMP5MF_Msk +#define TAMP_MISR_ITAMP6MF_Pos (21U) +#define TAMP_MISR_ITAMP6MF_Msk (0x1UL << TAMP_MISR_ITAMP6MF_Pos) /*!< 0x00200000 */ +#define TAMP_MISR_ITAMP6MF TAMP_MISR_ITAMP6MF_Msk +#define TAMP_MISR_ITAMP7MF_Pos (22U) +#define TAMP_MISR_ITAMP7MF_Msk (0x1UL << TAMP_MISR_ITAMP7MF_Pos) /*!< 0x00400000 */ +#define TAMP_MISR_ITAMP7MF TAMP_MISR_ITAMP7MF_Msk +#define TAMP_MISR_ITAMP8MF_Pos (23U) +#define TAMP_MISR_ITAMP8MF_Msk (0x1UL << TAMP_MISR_ITAMP8MF_Pos) /*!< 0x00800000 */ +#define TAMP_MISR_ITAMP8MF TAMP_MISR_ITAMP8MF_Msk +#define TAMP_MISR_ITAMP9MF_Pos (24U) +#define TAMP_MISR_ITAMP9MF_Msk (0x1UL << TAMP_MISR_ITAMP9MF_Pos) /*!< 0x01000000 */ +#define TAMP_MISR_ITAMP9MF TAMP_MISR_ITAMP9MF_Msk +#define TAMP_MISR_ITAMP11MF_Pos (26U) +#define TAMP_MISR_ITAMP11MF_Msk (0x1UL << TAMP_MISR_ITAMP11MF_Pos) /*!< 0x04000000 */ +#define TAMP_MISR_ITAMP11MF TAMP_MISR_ITAMP11MF_Msk +#define TAMP_MISR_ITAMP12MF_Pos (27U) +#define TAMP_MISR_ITAMP12MF_Msk (0x1UL << TAMP_MISR_ITAMP12MF_Pos) /*!< 0x08000000 */ +#define TAMP_MISR_ITAMP12MF TAMP_MISR_ITAMP12MF_Msk +#define TAMP_MISR_ITAMP13MF_Pos (28U) +#define TAMP_MISR_ITAMP13MF_Msk (0x1UL << TAMP_MISR_ITAMP13MF_Pos) /*!< 0x10000000 */ +#define TAMP_MISR_ITAMP13MF TAMP_MISR_ITAMP13MF_Msk +#define TAMP_MISR_ITAMP15MF_Pos (30U) +#define TAMP_MISR_ITAMP15MF_Msk (0x1UL << TAMP_MISR_ITAMP15MF_Pos) /*!< 0x40000000 */ +#define TAMP_MISR_ITAMP15MF TAMP_MISR_ITAMP15MF_Msk + +/******************** Bits definition for TAMP_SMISR register ************ *****/ +#define TAMP_SMISR_TAMP1MF_Pos (0U) +#define TAMP_SMISR_TAMP1MF_Msk (0x1UL << TAMP_SMISR_TAMP1MF_Pos) /*!< 0x00000001 */ +#define TAMP_SMISR_TAMP1MF TAMP_SMISR_TAMP1MF_Msk +#define TAMP_SMISR_TAMP2MF_Pos (1U) +#define TAMP_SMISR_TAMP2MF_Msk (0x1UL << TAMP_SMISR_TAMP2MF_Pos) /*!< 0x00000002 */ +#define TAMP_SMISR_TAMP2MF TAMP_SMISR_TAMP2MF_Msk +#define TAMP_SMISR_TAMP3MF_Pos (2U) +#define TAMP_SMISR_TAMP3MF_Msk (0x1UL << TAMP_SMISR_TAMP3MF_Pos) /*!< 0x00000004 */ +#define TAMP_SMISR_TAMP3MF TAMP_SMISR_TAMP3MF_Msk +#define TAMP_SMISR_TAMP4MF_Pos (3U) +#define TAMP_SMISR_TAMP4MF_Msk (0x1UL << TAMP_SMISR_TAMP4MF_Pos) /*!< 0x00000008 */ +#define TAMP_SMISR_TAMP4MF TAMP_SMISR_TAMP4MF_Msk +#define TAMP_SMISR_TAMP5MF_Pos (4U) +#define TAMP_SMISR_TAMP5MF_Msk (0x1UL << TAMP_SMISR_TAMP5MF_Pos) /*!< 0x00000010 */ +#define TAMP_SMISR_TAMP5MF TAMP_SMISR_TAMP5MF_Msk +#define TAMP_SMISR_TAMP6MF_Pos (5U) +#define TAMP_SMISR_TAMP6MF_Msk (0x1UL << TAMP_SMISR_TAMP6MF_Pos) /*!< 0x00000020 */ +#define TAMP_SMISR_TAMP6MF TAMP_SMISR_TAMP6MF_Msk +#define TAMP_SMISR_TAMP7MF_Pos (6U) +#define TAMP_SMISR_TAMP7MF_Msk (0x1UL << TAMP_SMISR_TAMP7MF_Pos) /*!< 0x00000040 */ +#define TAMP_SMISR_TAMP7MF TAMP_SMISR_TAMP7MF_Msk +#define TAMP_SMISR_TAMP8MF_Pos (7U) +#define TAMP_SMISR_TAMP8MF_Msk (0x1UL << TAMP_SMISR_TAMP8MF_Pos) /*!< 0x00000080 */ +#define TAMP_SMISR_TAMP8MF TAMP_SMISR_TAMP8MF_Msk +#define TAMP_SMISR_ITAMP1MF_Pos (16U) +#define TAMP_SMISR_ITAMP1MF_Msk (0x1UL << TAMP_SMISR_ITAMP1MF_Pos) /*!< 0x00010000 */ +#define TAMP_SMISR_ITAMP1MF TAMP_SMISR_ITAMP1MF_Msk +#define TAMP_SMISR_ITAMP2MF_Pos (17U) +#define TAMP_SMISR_ITAMP2MF_Msk (0x1UL << TAMP_SMISR_ITAMP2MF_Pos) /*!< 0x00020000 */ +#define TAMP_SMISR_ITAMP2MF TAMP_SMISR_ITAMP2MF_Msk +#define TAMP_SMISR_ITAMP3MF_Pos (18U) +#define TAMP_SMISR_ITAMP3MF_Msk (0x1UL << TAMP_SMISR_ITAMP3MF_Pos) /*!< 0x00040000 */ +#define TAMP_SMISR_ITAMP3MF TAMP_SMISR_ITAMP3MF_Msk +#define TAMP_SMISR_ITAMP4MF_Pos (19U) +#define TAMP_SMISR_ITAMP4MF_Msk (0x1UL << TAMP_SMISR_ITAMP4MF_Pos) /*!< 0x00080000 */ +#define TAMP_SMISR_ITAMP4MF TAMP_SMISR_ITAMP4MF_Msk +#define TAMP_SMISR_ITAMP5MF_Pos (20U) +#define TAMP_SMISR_ITAMP5MF_Msk (0x1UL << TAMP_SMISR_ITAMP5MF_Pos) /*!< 0x00100000 */ +#define TAMP_SMISR_ITAMP5MF TAMP_SMISR_ITAMP5MF_Msk +#define TAMP_SMISR_ITAMP6MF_Pos (21U) +#define TAMP_SMISR_ITAMP6MF_Msk (0x1UL << TAMP_SMISR_ITAMP6MF_Pos) /*!< 0x00200000 */ +#define TAMP_SMISR_ITAMP6MF TAMP_SMISR_ITAMP6MF_Msk +#define TAMP_SMISR_ITAMP7MF_Pos (22U) +#define TAMP_SMISR_ITAMP7MF_Msk (0x1UL << TAMP_SMISR_ITAMP7MF_Pos) /*!< 0x00400000 */ +#define TAMP_SMISR_ITAMP7MF TAMP_SMISR_ITAMP7MF_Msk +#define TAMP_SMISR_ITAMP8MF_Pos (23U) +#define TAMP_SMISR_ITAMP8MF_Msk (0x1UL << TAMP_SMISR_ITAMP8MF_Pos) /*!< 0x00800000 */ +#define TAMP_SMISR_ITAMP8MF TAMP_SMISR_ITAMP8MF_Msk +#define TAMP_SMISR_ITAMP9MF_Pos (24U) +#define TAMP_SMISR_ITAMP9MF_Msk (0x1UL << TAMP_SMISR_ITAMP9MF_Pos) /*!< 0x00100000 */ +#define TAMP_SMISR_ITAMP9MF TAMP_SMISR_ITAMP9MF_Msk +#define TAMP_SMISR_ITAMP11MF_Pos (26U) +#define TAMP_SMISR_ITAMP11MF_Msk (0x1UL << TAMP_SMISR_ITAMP11MF_Pos) /*!< 0x00400000 */ +#define TAMP_SMISR_ITAMP11MF TAMP_SMISR_ITAMP11MF_Msk +#define TAMP_SMISR_ITAMP12MF_Pos (27U) +#define TAMP_SMISR_ITAMP12MF_Msk (0x1UL << TAMP_SMISR_ITAMP12MF_Pos) /*!< 0x08000000 */ +#define TAMP_SMISR_ITAMP12MF TAMP_SMISR_ITAMP12MF_Msk +#define TAMP_SMISR_ITAMP13MF_Pos (28U) +#define TAMP_SMISR_ITAMP13MF_Msk (0x1UL << TAMP_SMISR_ITAMP13MF_Pos) /*!< 0x10000000 */ +#define TAMP_SMISR_ITAMP13MF TAMP_SMISR_ITAMP13MF_Msk +#define TAMP_SMISR_ITAMP15MF_Pos (30U) +#define TAMP_SMISR_ITAMP15MF_Msk (0x1UL << TAMP_SMISR_ITAMP15MF_Pos) /*!< 0x40000000 */ +#define TAMP_SMISR_ITAMP15MF TAMP_SMISR_ITAMP15MF_Msk + +/******************** Bits definition for TAMP_SCR register *****************/ +#define TAMP_SCR_CTAMP1F_Pos (0U) +#define TAMP_SCR_CTAMP1F_Msk (0x1UL << TAMP_SCR_CTAMP1F_Pos) /*!< 0x00000001 */ +#define TAMP_SCR_CTAMP1F TAMP_SCR_CTAMP1F_Msk +#define TAMP_SCR_CTAMP2F_Pos (1U) +#define TAMP_SCR_CTAMP2F_Msk (0x1UL << TAMP_SCR_CTAMP2F_Pos) /*!< 0x00000002 */ +#define TAMP_SCR_CTAMP2F TAMP_SCR_CTAMP2F_Msk +#define TAMP_SCR_CTAMP3F_Pos (2U) +#define TAMP_SCR_CTAMP3F_Msk (0x1UL << TAMP_SCR_CTAMP3F_Pos) /*!< 0x00000004 */ +#define TAMP_SCR_CTAMP3F TAMP_SCR_CTAMP3F_Msk +#define TAMP_SCR_CTAMP4F_Pos (3U) +#define TAMP_SCR_CTAMP4F_Msk (0x1UL << TAMP_SCR_CTAMP4F_Pos) /*!< 0x00000008 */ +#define TAMP_SCR_CTAMP4F TAMP_SCR_CTAMP4F_Msk +#define TAMP_SCR_CTAMP5F_Pos (4U) +#define TAMP_SCR_CTAMP5F_Msk (0x1UL << TAMP_SCR_CTAMP5F_Pos) /*!< 0x00000010 */ +#define TAMP_SCR_CTAMP5F TAMP_SCR_CTAMP5F_Msk +#define TAMP_SCR_CTAMP6F_Pos (5U) +#define TAMP_SCR_CTAMP6F_Msk (0x1UL << TAMP_SCR_CTAMP6F_Pos) /*!< 0x00000020 */ +#define TAMP_SCR_CTAMP6F TAMP_SCR_CTAMP6F_Msk +#define TAMP_SCR_CTAMP7F_Pos (6U) +#define TAMP_SCR_CTAMP7F_Msk (0x1UL << TAMP_SCR_CTAMP7F_Pos) /*!< 0x00000040 */ +#define TAMP_SCR_CTAMP7F TAMP_SCR_CTAMP7F_Msk +#define TAMP_SCR_CTAMP8F_Pos (7U) +#define TAMP_SCR_CTAMP8F_Msk (0x1UL << TAMP_SCR_CTAMP8F_Pos) /*!< 0x00000080 */ +#define TAMP_SCR_CTAMP8F TAMP_SCR_CTAMP8F_Msk +#define TAMP_SCR_CITAMP1F_Pos (16U) +#define TAMP_SCR_CITAMP1F_Msk (0x1UL << TAMP_SCR_CITAMP1F_Pos) /*!< 0x00010000 */ +#define TAMP_SCR_CITAMP1F TAMP_SCR_CITAMP1F_Msk +#define TAMP_SCR_CITAMP2F_Pos (17U) +#define TAMP_SCR_CITAMP2F_Msk (0x1UL << TAMP_SCR_CITAMP2F_Pos) /*!< 0x00020000 */ +#define TAMP_SCR_CITAMP2F TAMP_SCR_CITAMP2F_Msk +#define TAMP_SCR_CITAMP3F_Pos (18U) +#define TAMP_SCR_CITAMP3F_Msk (0x1UL << TAMP_SCR_CITAMP3F_Pos) /*!< 0x00040000 */ +#define TAMP_SCR_CITAMP3F TAMP_SCR_CITAMP3F_Msk +#define TAMP_SCR_CITAMP4F_Pos (19U) +#define TAMP_SCR_CITAMP4F_Msk (0x1UL << TAMP_SCR_CITAMP4F_Pos) /*!< 0x00080000 */ +#define TAMP_SCR_CITAMP4F TAMP_SCR_CITAMP4F_Msk +#define TAMP_SCR_CITAMP5F_Pos (20U) +#define TAMP_SCR_CITAMP5F_Msk (0x1UL << TAMP_SCR_CITAMP5F_Pos) /*!< 0x00100000 */ +#define TAMP_SCR_CITAMP5F TAMP_SCR_CITAMP5F_Msk +#define TAMP_SCR_CITAMP6F_Pos (21U) +#define TAMP_SCR_CITAMP6F_Msk (0x1UL << TAMP_SCR_CITAMP6F_Pos) /*!< 0x00200000 */ +#define TAMP_SCR_CITAMP6F TAMP_SCR_CITAMP6F_Msk +#define TAMP_SCR_CITAMP7F_Pos (22U) +#define TAMP_SCR_CITAMP7F_Msk (0x1UL << TAMP_SCR_CITAMP7F_Pos) /*!< 0x00400000 */ +#define TAMP_SCR_CITAMP7F TAMP_SCR_CITAMP7F_Msk +#define TAMP_SCR_CITAMP8F_Pos (23U) +#define TAMP_SCR_CITAMP8F_Msk (0x1UL << TAMP_SCR_CITAMP8F_Pos) /*!< 0x00800000 */ +#define TAMP_SCR_CITAMP8F TAMP_SCR_CITAMP8F_Msk +#define TAMP_SCR_CITAMP9F_Pos (24U) +#define TAMP_SCR_CITAMP9F_Msk (0x1UL << TAMP_SCR_CITAMP9F_Pos) /*!< 0x00100000 */ +#define TAMP_SCR_CITAMP9F TAMP_SCR_CITAMP9F_Msk +#define TAMP_SCR_CITAMP11F_Pos (26U) +#define TAMP_SCR_CITAMP11F_Msk (0x1UL << TAMP_SCR_CITAMP11F_Pos) /*!< 0x00400000 */ +#define TAMP_SCR_CITAMP11F TAMP_SCR_CITAMP11F_Msk +#define TAMP_SCR_CITAMP12F_Pos (27U) +#define TAMP_SCR_CITAMP12F_Msk (0x1UL << TAMP_SCR_CITAMP12F_Pos) /*!< 0x08000000 */ +#define TAMP_SCR_CITAMP12F TAMP_SCR_CITAMP12F_Msk +#define TAMP_SCR_CITAMP13F_Pos (28U) +#define TAMP_SCR_CITAMP13F_Msk (0x1UL << TAMP_SCR_CITAMP13F_Pos) /*!< 0x10000000 */ +#define TAMP_SCR_CITAMP13F TAMP_SCR_CITAMP13F_Msk +#define TAMP_SCR_CITAMP15F_Pos (30U) +#define TAMP_SCR_CITAMP15F_Msk (0x1UL << TAMP_SCR_CITAMP15F_Pos) /*!< 0x40000000 */ +#define TAMP_SCR_CITAMP15F TAMP_SCR_CITAMP15F_Msk +/******************** Bits definition for TAMP_COUNT1R register ***************/ +#define TAMP_COUNT1R_COUNT_Pos (0U) +#define TAMP_COUNT1R_COUNT_Msk (0xFFFFFFFFUL << TAMP_COUNT1R_COUNT_Pos)/*!< 0xFFFFFFFF */ +#define TAMP_COUNT1R_COUNT TAMP_COUNT1R_COUNT_Msk + +/******************** Bits definition for TAMP_OR register ***************/ +#define TAMP_OR_OUT3_RMP_Pos (1U) +#define TAMP_OR_OUT3_RMP_Msk (0x2UL << TAMP_OR_OUT3_RMP_Pos) /*!< 0x00000006 */ +#define TAMP_OR_OUT3_RMP TAMP_OR_OUT3_RMP_Msk +#define TAMP_OR_OUT3_RMP_0 (0x1UL << TAMP_OR_OUT3_RMP_Pos) /*!< 0x00100000 */ +#define TAMP_OR_OUT3_RMP_1 (0x2UL << TAMP_OR_OUT3_RMP_Pos) /*!< 0x00200000 */ +#define TAMP_OR_OUT5_RMP_Pos (3U) +#define TAMP_OR_OUT5_RMP_Msk (0x1UL << TAMP_OR_OUT5_RMP_Pos) /*!< 0x00000001 */ +#define TAMP_OR_OUT5_RMP TAMP_OR_OUT5_RMP_Msk +#define TAMP_OR_IN2_RMP_Pos (8U) +#define TAMP_OR_IN2_RMP_Msk (0x1UL << TAMP_OR_IN2_RMP_Pos) /*!< 0x00000001 */ +#define TAMP_OR_IN2_RMP TAMP_OR_IN2_RMP_Msk +#define TAMP_OR_IN3_RMP_Pos (9U) +#define TAMP_OR_IN3_RMP_Msk (0x1UL << TAMP_OR_IN3_RMP_Pos) /*!< 0x00000001 */ +#define TAMP_OR_IN3_RMP TAMP_OR_IN3_RMP_Msk +#define TAMP_OR_IN4_RMP_Pos (10U) +#define TAMP_OR_IN4_RMP_Msk (0x1UL << TAMP_OR_IN4_RMP_Pos) /*!< 0x00000001 */ +#define TAMP_OR_IN4_RMP TAMP_OR_IN4_RMP_Msk + +/******************** Bits definition for TAMP_ERCFG register ***************/ +#define TAMP_ERCFGR_ERCFG0_Pos (0U) +#define TAMP_ERCFGR_ERCFG0_Msk (0x1UL << TAMP_ERCFGR_ERCFG0_Pos) /*!< 0x00000001 */ +#define TAMP_ERCFGR_ERCFG0 TAMP_ERCFGR_ERCFG0_Msk + +/******************** Bits definition for TAMP_BKP0R register ***************/ +#define TAMP_BKP0R_Pos (0U) +#define TAMP_BKP0R_Msk (0xFFFFFFFFUL << TAMP_BKP0R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP0R TAMP_BKP0R_Msk + +/******************** Bits definition for TAMP_BKP1R register ****************/ +#define TAMP_BKP1R_Pos (0U) +#define TAMP_BKP1R_Msk (0xFFFFFFFFUL << TAMP_BKP1R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP1R TAMP_BKP1R_Msk + +/******************** Bits definition for TAMP_BKP2R register ****************/ +#define TAMP_BKP2R_Pos (0U) +#define TAMP_BKP2R_Msk (0xFFFFFFFFUL << TAMP_BKP2R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP2R TAMP_BKP2R_Msk + +/******************** Bits definition for TAMP_BKP3R register ****************/ +#define TAMP_BKP3R_Pos (0U) +#define TAMP_BKP3R_Msk (0xFFFFFFFFUL << TAMP_BKP3R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP3R TAMP_BKP3R_Msk + +/******************** Bits definition for TAMP_BKP4R register ****************/ +#define TAMP_BKP4R_Pos (0U) +#define TAMP_BKP4R_Msk (0xFFFFFFFFUL << TAMP_BKP4R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP4R TAMP_BKP4R_Msk + +/******************** Bits definition for TAMP_BKP5R register ****************/ +#define TAMP_BKP5R_Pos (0U) +#define TAMP_BKP5R_Msk (0xFFFFFFFFUL << TAMP_BKP5R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP5R TAMP_BKP5R_Msk + +/******************** Bits definition for TAMP_BKP6R register ****************/ +#define TAMP_BKP6R_Pos (0U) +#define TAMP_BKP6R_Msk (0xFFFFFFFFUL << TAMP_BKP6R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP6R TAMP_BKP6R_Msk + +/******************** Bits definition for TAMP_BKP7R register ****************/ +#define TAMP_BKP7R_Pos (0U) +#define TAMP_BKP7R_Msk (0xFFFFFFFFUL << TAMP_BKP7R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP7R TAMP_BKP7R_Msk + +/******************** Bits definition for TAMP_BKP8R register ****************/ +#define TAMP_BKP8R_Pos (0U) +#define TAMP_BKP8R_Msk (0xFFFFFFFFUL << TAMP_BKP8R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP8R TAMP_BKP8R_Msk + +/******************** Bits definition for TAMP_BKP9R register ****************/ +#define TAMP_BKP9R_Pos (0U) +#define TAMP_BKP9R_Msk (0xFFFFFFFFUL << TAMP_BKP9R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP9R TAMP_BKP9R_Msk + +/******************** Bits definition for TAMP_BKP10R register ***************/ +#define TAMP_BKP10R_Pos (0U) +#define TAMP_BKP10R_Msk (0xFFFFFFFFUL << TAMP_BKP10R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP10R TAMP_BKP10R_Msk + +/******************** Bits definition for TAMP_BKP11R register ***************/ +#define TAMP_BKP11R_Pos (0U) +#define TAMP_BKP11R_Msk (0xFFFFFFFFUL << TAMP_BKP11R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP11R TAMP_BKP11R_Msk + +/******************** Bits definition for TAMP_BKP12R register ***************/ +#define TAMP_BKP12R_Pos (0U) +#define TAMP_BKP12R_Msk (0xFFFFFFFFUL << TAMP_BKP12R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP12R TAMP_BKP12R_Msk + +/******************** Bits definition for TAMP_BKP13R register ***************/ +#define TAMP_BKP13R_Pos (0U) +#define TAMP_BKP13R_Msk (0xFFFFFFFFUL << TAMP_BKP13R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP13R TAMP_BKP13R_Msk + +/******************** Bits definition for TAMP_BKP14R register ***************/ +#define TAMP_BKP14R_Pos (0U) +#define TAMP_BKP14R_Msk (0xFFFFFFFFUL << TAMP_BKP14R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP14R TAMP_BKP14R_Msk + +/******************** Bits definition for TAMP_BKP15R register ***************/ +#define TAMP_BKP15R_Pos (0U) +#define TAMP_BKP15R_Msk (0xFFFFFFFFUL << TAMP_BKP15R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP15R TAMP_BKP15R_Msk + +/******************** Bits definition for TAMP_BKP16R register ***************/ +#define TAMP_BKP16R_Pos (0U) +#define TAMP_BKP16R_Msk (0xFFFFFFFFUL << TAMP_BKP16R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP16R TAMP_BKP16R_Msk + +/******************** Bits definition for TAMP_BKP17R register ***************/ +#define TAMP_BKP17R_Pos (0U) +#define TAMP_BKP17R_Msk (0xFFFFFFFFUL << TAMP_BKP17R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP17R TAMP_BKP17R_Msk + +/******************** Bits definition for TAMP_BKP18R register ***************/ +#define TAMP_BKP18R_Pos (0U) +#define TAMP_BKP18R_Msk (0xFFFFFFFFUL << TAMP_BKP18R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP18R TAMP_BKP18R_Msk + +/******************** Bits definition for TAMP_BKP19R register ***************/ +#define TAMP_BKP19R_Pos (0U) +#define TAMP_BKP19R_Msk (0xFFFFFFFFUL << TAMP_BKP19R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP19R TAMP_BKP19R_Msk + +/******************** Bits definition for TAMP_BKP20R register ***************/ +#define TAMP_BKP20R_Pos (0U) +#define TAMP_BKP20R_Msk (0xFFFFFFFFUL << TAMP_BKP20R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP20R TAMP_BKP20R_Msk + +/******************** Bits definition for TAMP_BKP21R register ***************/ +#define TAMP_BKP21R_Pos (0U) +#define TAMP_BKP21R_Msk (0xFFFFFFFFUL << TAMP_BKP21R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP21R TAMP_BKP21R_Msk + +/******************** Bits definition for TAMP_BKP22R register ***************/ +#define TAMP_BKP22R_Pos (0U) +#define TAMP_BKP22R_Msk (0xFFFFFFFFUL << TAMP_BKP22R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP22R TAMP_BKP22R_Msk + +/******************** Bits definition for TAMP_BKP23R register ***************/ +#define TAMP_BKP23R_Pos (0U) +#define TAMP_BKP23R_Msk (0xFFFFFFFFUL << TAMP_BKP23R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP23R TAMP_BKP23R_Msk + +/******************** Bits definition for TAMP_BKP24R register ***************/ +#define TAMP_BKP24R_Pos (0U) +#define TAMP_BKP24R_Msk (0xFFFFFFFFUL << TAMP_BKP24R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP24R TAMP_BKP24R_Msk + +/******************** Bits definition for TAMP_BKP25R register ***************/ +#define TAMP_BKP25R_Pos (0U) +#define TAMP_BKP25R_Msk (0xFFFFFFFFUL << TAMP_BKP25R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP25R TAMP_BKP25R_Msk + +/******************** Bits definition for TAMP_BKP26R register ***************/ +#define TAMP_BKP26R_Pos (0U) +#define TAMP_BKP26R_Msk (0xFFFFFFFFUL << TAMP_BKP26R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP26R TAMP_BKP26R_Msk + +/******************** Bits definition for TAMP_BKP27R register ***************/ +#define TAMP_BKP27R_Pos (0U) +#define TAMP_BKP27R_Msk (0xFFFFFFFFUL << TAMP_BKP27R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP27R TAMP_BKP27R_Msk + +/******************** Bits definition for TAMP_BKP28R register ***************/ +#define TAMP_BKP28R_Pos (0U) +#define TAMP_BKP28R_Msk (0xFFFFFFFFUL << TAMP_BKP28R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP28R TAMP_BKP28R_Msk + +/******************** Bits definition for TAMP_BKP29R register ***************/ +#define TAMP_BKP29R_Pos (0U) +#define TAMP_BKP29R_Msk (0xFFFFFFFFUL << TAMP_BKP29R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP29R TAMP_BKP29R_Msk + +/******************** Bits definition for TAMP_BKP30R register ***************/ +#define TAMP_BKP30R_Pos (0U) +#define TAMP_BKP30R_Msk (0xFFFFFFFFUL << TAMP_BKP30R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP30R TAMP_BKP30R_Msk + +/******************** Bits definition for TAMP_BKP31R register ***************/ +#define TAMP_BKP31R_Pos (0U) +#define TAMP_BKP31R_Msk (0xFFFFFFFFUL << TAMP_BKP31R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP31R TAMP_BKP31R_Msk + +/******************************************************************************/ +/* */ +/* Serial Audio Interface */ +/* */ +/******************************************************************************/ +/******************** Bit definition for SAI_GCR register *******************/ +#define SAI_GCR_SYNCIN_Pos (0U) +#define SAI_GCR_SYNCIN_Msk (0x3UL << SAI_GCR_SYNCIN_Pos) /*!< 0x00000003 */ +#define SAI_GCR_SYNCIN SAI_GCR_SYNCIN_Msk /*!= 6010050) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wc11-extensions" + #pragma clang diagnostic ignored "-Wreserved-id-macro" +#elif defined (__GNUC__) + /* anonymous unions are enabled by default */ +#elif defined (__TMS470__) + /* anonymous unions are enabled by default */ +#elif defined (__TASKING__) + #pragma warning 586 +#elif defined (__CSMC__) + /* anonymous unions are enabled by default */ +#else + #warning Not supported compiler type +#endif + +#define SMPS /*!< Switched mode power supply feature */ + +/* -------- Configuration of the Cortex-M33 Processor and Core Peripherals ------ */ +#define __CM33_REV 0x0000U /* Core revision r0p1 */ +#define __SAUREGION_PRESENT 1U /* SAU regions present */ +#define __MPU_PRESENT 1U /* MPU present */ +#define __VTOR_PRESENT 1U /* VTOR present */ +#define __NVIC_PRIO_BITS 4U /* Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0U /* Set to 1 if different SysTick Config is used */ +#define __FPU_PRESENT 1U /* FPU present */ +#define __DSP_PRESENT 1U /* DSP extension present */ + +/** @} */ /* End of group Configuration_of_CMSIS */ + + +#include /*!< ARM Cortex-M33 processor and core peripherals */ +#include "system_stm32h5xx.h" /*!< STM32H5xx System */ + + +/* =========================================================================================================================== */ +/* ================ Device Specific Peripheral Section ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup STM32H5xx_peripherals + * @{ + */ + +/** + * @brief CRC calculation unit + */ +typedef struct +{ + __IO uint32_t DR; /*!< CRC Data register, Address offset: 0x00 */ + __IO uint32_t IDR; /*!< CRC Independent data register, Address offset: 0x04 */ + __IO uint32_t CR; /*!< CRC Control register, Address offset: 0x08 */ + uint32_t RESERVED2; /*!< Reserved, 0x0C */ + __IO uint32_t INIT; /*!< Initial CRC value register, Address offset: 0x10 */ + __IO uint32_t POL; /*!< CRC polynomial register, Address offset: 0x14 */ + uint32_t RESERVED3[246]; /*!< Reserved, */ + __IO uint32_t HWCFGR; /*!< CRC IP HWCFGR register, Address offset: 0x3F0 */ + __IO uint32_t VERR; /*!< CRC IP version register, Address offset: 0x3F4 */ + __IO uint32_t PIDR; /*!< CRC IP type identification register, Address offset: 0x3F8 */ + __IO uint32_t SIDR; /*!< CRC IP map Size ID register, Address offset: 0x3FC */ +} CRC_TypeDef; + +/** + * @brief Inter-integrated Circuit Interface + */ +typedef struct +{ + __IO uint32_t CR1; /*!< I2C Control register 1, Address offset: 0x00 */ + __IO uint32_t CR2; /*!< I2C Control register 2, Address offset: 0x04 */ + __IO uint32_t OAR1; /*!< I2C Own address 1 register, Address offset: 0x08 */ + __IO uint32_t OAR2; /*!< I2C Own address 2 register, Address offset: 0x0C */ + __IO uint32_t TIMINGR; /*!< I2C Timing register, Address offset: 0x10 */ + __IO uint32_t TIMEOUTR; /*!< I2C Timeout register, Address offset: 0x14 */ + __IO uint32_t ISR; /*!< I2C Interrupt and status register, Address offset: 0x18 */ + __IO uint32_t ICR; /*!< I2C Interrupt clear register, Address offset: 0x1C */ + __IO uint32_t PECR; /*!< I2C PEC register, Address offset: 0x20 */ + __IO uint32_t RXDR; /*!< I2C Receive data register, Address offset: 0x24 */ + __IO uint32_t TXDR; /*!< I2C Transmit data register, Address offset: 0x28 */ +} I2C_TypeDef; + +/** + * @brief Improved Inter-integrated Circuit Interface + */ +typedef struct +{ + __IO uint32_t CR; /*!< I3C Control register, Address offset: 0x00 */ + __IO uint32_t CFGR; /*!< I3C Controller Configuration register, Address offset: 0x04 */ + uint32_t RESERVED1[2]; /*!< Reserved, Address offset: 0x08-0x0C */ + __IO uint32_t RDR; /*!< I3C Received Data register, Address offset: 0x10 */ + __IO uint32_t RDWR; /*!< I3C Received Data Word register, Address offset: 0x14 */ + __IO uint32_t TDR; /*!< I3C Transmit Data register, Address offset: 0x18 */ + __IO uint32_t TDWR; /*!< I3C Transmit Data Word register, Address offset: 0x1C */ + __IO uint32_t IBIDR; /*!< I3C IBI payload Data register, Address offset: 0x20 */ + __IO uint32_t TGTTDR; /*!< I3C Target Transmit register, Address offset: 0x24 */ + uint32_t RESERVED2[2]; /*!< Reserved, Address offset: 0x28-0x2C */ + __IO uint32_t SR; /*!< I3C Status register, Address offset: 0x30 */ + __IO uint32_t SER; /*!< I3C Status Error register, Address offset: 0x34 */ + uint32_t RESERVED3[2]; /*!< Reserved, Address offset: 0x38-0x3C */ + __IO uint32_t RMR; /*!< I3C Received Message register, Address offset: 0x40 */ + uint32_t RESERVED4[3]; /*!< Reserved, Address offset: 0x44-0x4C */ + __IO uint32_t EVR; /*!< I3C Event register, Address offset: 0x50 */ + __IO uint32_t IER; /*!< I3C Interrupt Enable register, Address offset: 0x54 */ + __IO uint32_t CEVR; /*!< I3C Clear Event register, Address offset: 0x58 */ + uint32_t RESERVED5; /*!< Reserved, Address offset: 0x5C */ + __IO uint32_t DEVR0; /*!< I3C own Target characteristics register, Address offset: 0x60 */ + __IO uint32_t DEVRX[4]; /*!< I3C Target x (1<=x<=4) register, Address offset: 0x64-0x70 */ + uint32_t RESERVED6[7]; /*!< Reserved, Address offset: 0x74-0x8C */ + __IO uint32_t MAXRLR; /*!< I3C Maximum Read Length register, Address offset: 0x90 */ + __IO uint32_t MAXWLR; /*!< I3C Maximum Write Length register, Address offset: 0x94 */ + uint32_t RESERVED7[2]; /*!< Reserved, Address offset: 0x98-0x9C */ + __IO uint32_t TIMINGR0; /*!< I3C Timing 0 register, Address offset: 0xA0 */ + __IO uint32_t TIMINGR1; /*!< I3C Timing 1 register, Address offset: 0xA4 */ + __IO uint32_t TIMINGR2; /*!< I3C Timing 2 register, Address offset: 0xA8 */ + uint32_t RESERVED9[5]; /*!< Reserved, Address offset: 0xAC-0xBC */ + __IO uint32_t BCR; /*!< I3C Bus Characteristics register, Address offset: 0xC0 */ + __IO uint32_t DCR; /*!< I3C Device Characteristics register, Address offset: 0xC4 */ + __IO uint32_t GETCAPR; /*!< I3C GET CAPabilities register, Address offset: 0xC8 */ + __IO uint32_t CRCAPR; /*!< I3C Controller CAPabilities register, Address offset: 0xCC */ + __IO uint32_t GETMXDSR; /*!< I3C GET Max Data Speed register, Address offset: 0xD0 */ + __IO uint32_t EPIDR; /*!< I3C Extended Provisioned ID register, Address offset: 0xD4 */ +} I3C_TypeDef; + +/** + * @brief DAC + */ +typedef struct +{ + __IO uint32_t CR; /*!< DAC control register, Address offset: 0x00 */ + __IO uint32_t SWTRIGR; /*!< DAC software trigger register, Address offset: 0x04 */ + __IO uint32_t DHR12R1; /*!< DAC channel1 12-bit right-aligned data holding register, Address offset: 0x08 */ + __IO uint32_t DHR12L1; /*!< DAC channel1 12-bit left aligned data holding register, Address offset: 0x0C */ + __IO uint32_t DHR8R1; /*!< DAC channel1 8-bit right aligned data holding register, Address offset: 0x10 */ + __IO uint32_t DHR12R2; /*!< DAC channel2 12-bit right aligned data holding register, Address offset: 0x14 */ + __IO uint32_t DHR12L2; /*!< DAC channel2 12-bit left aligned data holding register, Address offset: 0x18 */ + __IO uint32_t DHR8R2; /*!< DAC channel2 8-bit right-aligned data holding register, Address offset: 0x1C */ + __IO uint32_t DHR12RD; /*!< Dual DAC 12-bit right-aligned data holding register, Address offset: 0x20 */ + __IO uint32_t DHR12LD; /*!< DUAL DAC 12-bit left aligned data holding register, Address offset: 0x24 */ + __IO uint32_t DHR8RD; /*!< DUAL DAC 8-bit right aligned data holding register, Address offset: 0x28 */ + __IO uint32_t DOR1; /*!< DAC channel1 data output register, Address offset: 0x2C */ + __IO uint32_t DOR2; /*!< DAC channel2 data output register, Address offset: 0x30 */ + __IO uint32_t SR; /*!< DAC status register, Address offset: 0x34 */ + __IO uint32_t CCR; /*!< DAC calibration control register, Address offset: 0x38 */ + __IO uint32_t MCR; /*!< DAC mode control register, Address offset: 0x3C */ + __IO uint32_t SHSR1; /*!< DAC Sample and Hold sample time register 1, Address offset: 0x40 */ + __IO uint32_t SHSR2; /*!< DAC Sample and Hold sample time register 2, Address offset: 0x44 */ + __IO uint32_t SHHR; /*!< DAC Sample and Hold hold time register, Address offset: 0x48 */ + __IO uint32_t SHRR; /*!< DAC Sample and Hold refresh time register, Address offset: 0x4C */ + __IO uint32_t RESERVED[1]; + __IO uint32_t AUTOCR; /*!< DAC Autonomous mode register, Address offset: 0x54 */ +} DAC_TypeDef; + +/** + * @brief Clock Recovery System + */ +typedef struct +{ +__IO uint32_t CR; /*!< CRS ccontrol register, Address offset: 0x00 */ +__IO uint32_t CFGR; /*!< CRS configuration register, Address offset: 0x04 */ +__IO uint32_t ISR; /*!< CRS interrupt and status register, Address offset: 0x08 */ +__IO uint32_t ICR; /*!< CRS interrupt flag clear register, Address offset: 0x0C */ +} CRS_TypeDef; + + +/** + * @brief HASH + */ +typedef struct +{ + __IO uint32_t CR; /*!< HASH control register, Address offset: 0x00 */ + __IO uint32_t DIN; /*!< HASH data input register, Address offset: 0x04 */ + __IO uint32_t STR; /*!< HASH start register, Address offset: 0x08 */ + __IO uint32_t HR[5]; /*!< HASH digest registers, Address offset: 0x0C-0x1C */ + __IO uint32_t IMR; /*!< HASH interrupt enable register, Address offset: 0x20 */ + __IO uint32_t SR; /*!< HASH status register, Address offset: 0x24 */ + uint32_t RESERVED[52]; /*!< Reserved, 0x28-0xF4 */ + __IO uint32_t CSR[103]; /*!< HASH context swap registers, Address offset: 0x0F8-0x290 */ +} HASH_TypeDef; + +/** + * @brief HASH_DIGEST + */ +typedef struct +{ + __IO uint32_t HR[16]; /*!< HASH digest registers, Address offset: 0x310-0x34C */ +} HASH_DIGEST_TypeDef; + +/** + * @brief RNG + */ +typedef struct +{ + __IO uint32_t CR; /*!< RNG control register, Address offset: 0x00 */ + __IO uint32_t SR; /*!< RNG status register, Address offset: 0x04 */ + __IO uint32_t DR; /*!< RNG data register, Address offset: 0x08 */ + uint32_t RESERVED; + __IO uint32_t HTCR; /*!< RNG health test configuration register, Address offset: 0x10 */ +} RNG_TypeDef; + +/** + * @brief Debug MCU + */ +typedef struct +{ + __IO uint32_t IDCODE; /*!< MCU device ID code, Address offset: 0x00 */ + __IO uint32_t CR; /*!< Debug MCU configuration register, Address offset: 0x04 */ + __IO uint32_t APB1FZR1; /*!< Debug MCU APB1 freeze register 1, Address offset: 0x08 */ + __IO uint32_t APB1FZR2; /*!< Debug MCU APB1 freeze register 2, Address offset: 0x0C */ + __IO uint32_t APB2FZR; /*!< Debug MCU APB2 freeze register, Address offset: 0x10 */ + __IO uint32_t APB3FZR; /*!< Debug MCU APB3 freeze register, Address offset: 0x14 */ + uint32_t RESERVED1[2]; /*!< Reserved, 0x18 - 0x1C */ + __IO uint32_t AHB1FZR; /*!< Debug MCU AHB1 freeze register, Address offset: 0x20 */ + uint32_t RESERVED2[54]; /*!< Reserved, 0x24 - 0xF8 */ + __IO uint32_t SR; /*!< Debug MCU SR register, Address offset: 0xFC */ + __IO uint32_t DBG_AUTH_HOST; /*!< Debug DBG_AUTH_HOST register, Address offset: 0x100 */ + __IO uint32_t DBG_AUTH_DEV; /*!< Debug DBG_AUTH_DEV register, Address offset: 0x104 */ + __IO uint32_t DBG_AUTH_ACK; /*!< Debug DBG_AUTH_ACK register, Address offset: 0x108 */ + uint32_t RESERVED3[945]; /*!< Reserved, 0x10C - 0xFCC */ + __IO uint32_t PIDR4; /*!< Debug MCU Peripheral ID register 4, Address offset: 0xFD0 */ + __IO uint32_t PIDR5; /*!< Debug MCU Peripheral ID register 5, Address offset: 0xFD4 */ + __IO uint32_t PIDR6; /*!< Debug MCU Peripheral ID register 6, Address offset: 0xFD8 */ + __IO uint32_t PIDR7; /*!< Debug MCU Peripheral ID register 7, Address offset: 0xFDC */ + __IO uint32_t PIDR0; /*!< Debug MCU Peripheral ID register 0, Address offset: 0xFE0 */ + __IO uint32_t PIDR1; /*!< Debug MCU Peripheral ID register 1, Address offset: 0xFE4 */ + __IO uint32_t PIDR2; /*!< Debug MCU Peripheral ID register 2, Address offset: 0xFE8 */ + __IO uint32_t PIDR3; /*!< Debug MCU Peripheral ID register 3, Address offset: 0xFEC */ + __IO uint32_t CIDR0; /*!< Debug MCU Component ID register 0, Address offset: 0xFF0 */ + __IO uint32_t CIDR1; /*!< Debug MCU Component ID register 1, Address offset: 0xFF4 */ + __IO uint32_t CIDR2; /*!< Debug MCU Component ID register 2, Address offset: 0xFF8 */ + __IO uint32_t CIDR3; /*!< Debug MCU Component ID register 3, Address offset: 0xFFC */ +} DBGMCU_TypeDef; + +/** + * @brief DCMI + */ +typedef struct +{ + __IO uint32_t CR; /*!< DCMI control register 1, Address offset: 0x00 */ + __IO uint32_t SR; /*!< DCMI status register, Address offset: 0x04 */ + __IO uint32_t RISR; /*!< DCMI raw interrupt status register, Address offset: 0x08 */ + __IO uint32_t IER; /*!< DCMI interrupt enable register, Address offset: 0x0C */ + __IO uint32_t MISR; /*!< DCMI masked interrupt status register, Address offset: 0x10 */ + __IO uint32_t ICR; /*!< DCMI interrupt clear register, Address offset: 0x14 */ + __IO uint32_t ESCR; /*!< DCMI embedded synchronization code register, Address offset: 0x18 */ + __IO uint32_t ESUR; /*!< DCMI embedded synchronization unmask register, Address offset: 0x1C */ + __IO uint32_t CWSTRTR; /*!< DCMI crop window start, Address offset: 0x20 */ + __IO uint32_t CWSIZER; /*!< DCMI crop window size, Address offset: 0x24 */ + __IO uint32_t DR; /*!< DCMI data register, Address offset: 0x28 */ +} DCMI_TypeDef; + +/** + * @brief PSSI + */ +typedef struct +{ + __IO uint32_t CR; /*!< PSSI control register, Address offset: 0x000 */ + __IO uint32_t SR; /*!< PSSI status register, Address offset: 0x004 */ + __IO uint32_t RIS; /*!< PSSI raw interrupt status register, Address offset: 0x008 */ + __IO uint32_t IER; /*!< PSSI interrupt enable register, Address offset: 0x00C */ + __IO uint32_t MIS; /*!< PSSI masked interrupt status register, Address offset: 0x010 */ + __IO uint32_t ICR; /*!< PSSI interrupt clear register, Address offset: 0x014 */ + __IO uint32_t RESERVED1[4]; /*!< Reserved, 0x018 - 0x024 */ + __IO uint32_t DR; /*!< PSSI data register, Address offset: 0x028 */ +} PSSI_TypeDef; + +/** + * @brief DMA Controller + */ +typedef struct +{ + __IO uint32_t SECCFGR; /*!< DMA secure configuration register, Address offset: 0x00 */ + __IO uint32_t PRIVCFGR; /*!< DMA privileged configuration register, Address offset: 0x04 */ + __IO uint32_t RCFGLOCKR; /*!< DMA lock configuration register, Address offset: 0x08 */ + __IO uint32_t MISR; /*!< DMA non secure masked interrupt status register, Address offset: 0x0C */ + __IO uint32_t SMISR; /*!< DMA secure masked interrupt status register, Address offset: 0x10 */ +} DMA_TypeDef; + +typedef struct +{ + __IO uint32_t CLBAR; /*!< DMA channel x linked-list base address register, Address offset: 0x50 + (x * 0x80) */ + uint32_t RESERVED1[2]; /*!< Reserved 1, Address offset: 0x54 -- 0x58 */ + __IO uint32_t CFCR; /*!< DMA channel x flag clear register, Address offset: 0x5C + (x * 0x80) */ + __IO uint32_t CSR; /*!< DMA channel x flag status register, Address offset: 0x60 + (x * 0x80) */ + __IO uint32_t CCR; /*!< DMA channel x control register, Address offset: 0x64 + (x * 0x80) */ + uint32_t RESERVED2[10];/*!< Reserved 2, Address offset: 0x68 -- 0x8C */ + __IO uint32_t CTR1; /*!< DMA channel x transfer register 1, Address offset: 0x90 + (x * 0x80) */ + __IO uint32_t CTR2; /*!< DMA channel x transfer register 2, Address offset: 0x94 + (x * 0x80) */ + __IO uint32_t CBR1; /*!< DMA channel x block register 1, Address offset: 0x98 + (x * 0x80) */ + __IO uint32_t CSAR; /*!< DMA channel x source address register, Address offset: 0x9C + (x * 0x80) */ + __IO uint32_t CDAR; /*!< DMA channel x destination address register, Address offset: 0xA0 + (x * 0x80) */ + __IO uint32_t CTR3; /*!< DMA channel x transfer register 3, Address offset: 0xA4 + (x * 0x80) */ + __IO uint32_t CBR2; /*!< DMA channel x block register 2, Address offset: 0xA8 + (x * 0x80) */ + uint32_t RESERVED3[8]; /*!< Reserved 3, Address offset: 0xAC -- 0xC8 */ + __IO uint32_t CLLR; /*!< DMA channel x linked-list address register, Address offset: 0xCC + (x * 0x80) */ +} DMA_Channel_TypeDef; + +/** + * @brief Ethernet MAC + */ +typedef struct +{ + __IO uint32_t MACCR; + __IO uint32_t MACECR; + __IO uint32_t MACPFR; + __IO uint32_t MACWTR; + __IO uint32_t MACHT0R; + __IO uint32_t MACHT1R; + uint32_t RESERVED1[14]; + __IO uint32_t MACVTR; + uint32_t RESERVED2; + __IO uint32_t MACVHTR; + uint32_t RESERVED3; + __IO uint32_t MACVIR; + __IO uint32_t MACIVIR; + uint32_t RESERVED4[2]; + __IO uint32_t MACTFCR; + uint32_t RESERVED5[7]; + __IO uint32_t MACRFCR; + uint32_t RESERVED6[7]; + __IO uint32_t MACISR; + __IO uint32_t MACIER; + __IO uint32_t MACRXTXSR; + uint32_t RESERVED7; + __IO uint32_t MACPCSR; + __IO uint32_t MACRWKPFR; + uint32_t RESERVED8[2]; + __IO uint32_t MACLCSR; + __IO uint32_t MACLTCR; + __IO uint32_t MACLETR; + __IO uint32_t MAC1USTCR; + uint32_t RESERVED9[12]; + __IO uint32_t MACVR; + __IO uint32_t MACDR; + uint32_t RESERVED10; + __IO uint32_t MACHWF0R; + __IO uint32_t MACHWF1R; + __IO uint32_t MACHWF2R; + uint32_t RESERVED11[54]; + __IO uint32_t MACMDIOAR; + __IO uint32_t MACMDIODR; + uint32_t RESERVED12[2]; + __IO uint32_t MACARPAR; + uint32_t RESERVED13[59]; + __IO uint32_t MACA0HR; + __IO uint32_t MACA0LR; + __IO uint32_t MACA1HR; + __IO uint32_t MACA1LR; + __IO uint32_t MACA2HR; + __IO uint32_t MACA2LR; + __IO uint32_t MACA3HR; + __IO uint32_t MACA3LR; + uint32_t RESERVED14[248]; + __IO uint32_t MMCCR; + __IO uint32_t MMCRIR; + __IO uint32_t MMCTIR; + __IO uint32_t MMCRIMR; + __IO uint32_t MMCTIMR; + uint32_t RESERVED15[14]; + __IO uint32_t MMCTSCGPR; + __IO uint32_t MMCTMCGPR; + uint32_t RESERVED16[5]; + __IO uint32_t MMCTPCGR; + uint32_t RESERVED17[10]; + __IO uint32_t MMCRCRCEPR; + __IO uint32_t MMCRAEPR; + uint32_t RESERVED18[10]; + __IO uint32_t MMCRUPGR; + uint32_t RESERVED19[9]; + __IO uint32_t MMCTLPIMSTR; + __IO uint32_t MMCTLPITCR; + __IO uint32_t MMCRLPIMSTR; + __IO uint32_t MMCRLPITCR; + uint32_t RESERVED20[65]; + __IO uint32_t MACL3L4C0R; + __IO uint32_t MACL4A0R; + uint32_t RESERVED21[2]; + __IO uint32_t MACL3A0R0R; + __IO uint32_t MACL3A1R0R; + __IO uint32_t MACL3A2R0R; + __IO uint32_t MACL3A3R0R; + uint32_t RESERVED22[4]; + __IO uint32_t MACL3L4C1R; + __IO uint32_t MACL4A1R; + uint32_t RESERVED23[2]; + __IO uint32_t MACL3A0R1R; + __IO uint32_t MACL3A1R1R; + __IO uint32_t MACL3A2R1R; + __IO uint32_t MACL3A3R1R; + uint32_t RESERVED24[108]; + __IO uint32_t MACTSCR; + __IO uint32_t MACSSIR; + __IO uint32_t MACSTSR; + __IO uint32_t MACSTNR; + __IO uint32_t MACSTSUR; + __IO uint32_t MACSTNUR; + __IO uint32_t MACTSAR; + uint32_t RESERVED25; + __IO uint32_t MACTSSR; + uint32_t RESERVED26[3]; + __IO uint32_t MACTTSSNR; + __IO uint32_t MACTTSSSR; + uint32_t RESERVED27[2]; + __IO uint32_t MACACR; + uint32_t RESERVED28; + __IO uint32_t MACATSNR; + __IO uint32_t MACATSSR; + __IO uint32_t MACTSIACR; + __IO uint32_t MACTSEACR; + __IO uint32_t MACTSICNR; + __IO uint32_t MACTSECNR; + uint32_t RESERVED29[4]; + __IO uint32_t MACPPSCR; + uint32_t RESERVED30[3]; + __IO uint32_t MACPPSTTSR; + __IO uint32_t MACPPSTTNR; + __IO uint32_t MACPPSIR; + __IO uint32_t MACPPSWR; + uint32_t RESERVED31[12]; + __IO uint32_t MACPOCR; + __IO uint32_t MACSPI0R; + __IO uint32_t MACSPI1R; + __IO uint32_t MACSPI2R; + __IO uint32_t MACLMIR; + uint32_t RESERVED32[11]; + __IO uint32_t MTLOMR; + uint32_t RESERVED33[7]; + __IO uint32_t MTLISR; + uint32_t RESERVED34[55]; + __IO uint32_t MTLTQOMR; + __IO uint32_t MTLTQUR; + __IO uint32_t MTLTQDR; + uint32_t RESERVED35[8]; + __IO uint32_t MTLQICSR; + __IO uint32_t MTLRQOMR; + __IO uint32_t MTLRQMPOCR; + __IO uint32_t MTLRQDR; + uint32_t RESERVED36[177]; + __IO uint32_t DMAMR; + __IO uint32_t DMASBMR; + __IO uint32_t DMAISR; + __IO uint32_t DMADSR; + uint32_t RESERVED37[60]; + __IO uint32_t DMACCR; + __IO uint32_t DMACTCR; + __IO uint32_t DMACRCR; + uint32_t RESERVED38[2]; + __IO uint32_t DMACTDLAR; + uint32_t RESERVED39; + __IO uint32_t DMACRDLAR; + __IO uint32_t DMACTDTPR; + uint32_t RESERVED40; + __IO uint32_t DMACRDTPR; + __IO uint32_t DMACTDRLR; + __IO uint32_t DMACRDRLR; + __IO uint32_t DMACIER; + __IO uint32_t DMACRIWTR; + __IO uint32_t DMACSFCSR; + uint32_t RESERVED41; + __IO uint32_t DMACCATDR; + uint32_t RESERVED42; + __IO uint32_t DMACCARDR; + uint32_t RESERVED43; + __IO uint32_t DMACCATBR; + uint32_t RESERVED44; + __IO uint32_t DMACCARBR; + __IO uint32_t DMACSR; + uint32_t RESERVED45[2]; + __IO uint32_t DMACMFCR; +}ETH_TypeDef; + +/** + * @brief Asynch Interrupt/Event Controller (EXTI) + */ +typedef struct +{ + __IO uint32_t RTSR1; /*!< EXTI Rising Trigger Selection Register 1, Address offset: 0x00 */ + __IO uint32_t FTSR1; /*!< EXTI Falling Trigger Selection Register 1, Address offset: 0x04 */ + __IO uint32_t SWIER1; /*!< EXTI Software Interrupt event Register 1, Address offset: 0x08 */ + __IO uint32_t RPR1; /*!< EXTI Rising Pending Register 1, Address offset: 0x0C */ + __IO uint32_t FPR1; /*!< EXTI Falling Pending Register 1, Address offset: 0x10 */ + __IO uint32_t SECCFGR1; /*!< EXTI Security Configuration Register 1, Address offset: 0x14 */ + __IO uint32_t PRIVCFGR1; /*!< EXTI Privilege Configuration Register 1, Address offset: 0x18 */ + uint32_t RESERVED1; /*!< Reserved 1, Address offset: 0x1C */ + __IO uint32_t RTSR2; /*!< EXTI Rising Trigger Selection Register 2, Address offset: 0x20 */ + __IO uint32_t FTSR2; /*!< EXTI Falling Trigger Selection Register 2, Address offset: 0x24 */ + __IO uint32_t SWIER2; /*!< EXTI Software Interrupt event Register 2, Address offset: 0x28 */ + __IO uint32_t RPR2; /*!< EXTI Rising Pending Register 2, Address offset: 0x2C */ + __IO uint32_t FPR2; /*!< EXTI Falling Pending Register 2, Address offset: 0x30 */ + __IO uint32_t SECCFGR2; /*!< EXTI Security Configuration Register 2, Address offset: 0x34 */ + __IO uint32_t PRIVCFGR2; /*!< EXTI Privilege Configuration Register 2, Address offset: 0x38 */ + uint32_t RESERVED2[9]; /*!< Reserved 2, 0x3C-- 0x5C */ + __IO uint32_t EXTICR[4]; /*!< EXIT External Interrupt Configuration Register, 0x60 -- 0x6C */ + __IO uint32_t LOCKR; /*!< EXTI Lock Register, Address offset: 0x70 */ + uint32_t RESERVED3[3]; /*!< Reserved 3, 0x74 -- 0x7C */ + __IO uint32_t IMR1; /*!< EXTI Interrupt Mask Register 1, Address offset: 0x80 */ + __IO uint32_t EMR1; /*!< EXTI Event Mask Register 1, Address offset: 0x84 */ + uint32_t RESERVED4[2]; /*!< Reserved 4, 0x88 -- 0x8C */ + __IO uint32_t IMR2; /*!< EXTI Interrupt Mask Register 2, Address offset: 0x90 */ + __IO uint32_t EMR2; /*!< EXTI Event Mask Register 2, Address offset: 0x94 */ +} EXTI_TypeDef; + +/** + * @brief FLASH Registers + */ +typedef struct +{ + __IO uint32_t ACR; /*!< FLASH access control register, Address offset: 0x00 */ + __IO uint32_t NSKEYR; /*!< FLASH non-secure key register, Address offset: 0x04 */ + __IO uint32_t SECKEYR; /*!< FLASH secure key register, Address offset: 0x08 */ + __IO uint32_t OPTKEYR; /*!< FLASH option key register, Address offset: 0x0C */ + __IO uint32_t NSOBKKEYR; /*!< FLASH non-secure option bytes keys key register, Address offset: 0x10 */ + __IO uint32_t SECOBKKEYR; /*!< FLASH secure option bytes keys key register, Address offset: 0x14 */ + __IO uint32_t OPSR; /*!< FLASH OPSR register, Address offset: 0x18 */ + __IO uint32_t OPTCR; /*!< Flash Option Control Register, Address offset: 0x1C */ + __IO uint32_t NSSR; /*!< FLASH non-secure status register, Address offset: 0x20 */ + __IO uint32_t SECSR; /*!< FLASH secure status register, Address offset: 0x24 */ + __IO uint32_t NSCR; /*!< FLASH non-secure control register, Address offset: 0x28 */ + __IO uint32_t SECCR; /*!< FLASH secure control register, Address offset: 0x2C */ + __IO uint32_t NSCCR; /*!< FLASH non-secure clear control register, Address offset: 0x30 */ + __IO uint32_t SECCCR; /*!< FLASH secure clear control register, Address offset: 0x34 */ + uint32_t RESERVED1; /*!< Reserved1, Address offset: 0x38 */ + __IO uint32_t PRIVCFGR; /*!< FLASH privilege configuration register, Address offset: 0x3C */ + __IO uint32_t NSOBKCFGR; /*!< FLASH non-secure option byte key configuration register, Address offset: 0x40 */ + __IO uint32_t SECOBKCFGR; /*!< FLASH secure option byte key configuration register, Address offset: 0x44 */ + __IO uint32_t HDPEXTR; /*!< FLASH HDP extension register, Address offset: 0x48 */ + uint32_t RESERVED2; /*!< Reserved2, Address offset: 0x4C */ + __IO uint32_t OPTSR_CUR; /*!< FLASH option status current register, Address offset: 0x50 */ + __IO uint32_t OPTSR_PRG; /*!< FLASH option status to program register, Address offset: 0x54 */ + uint32_t RESERVED3[2]; /*!< Reserved3, Address offset: 0x58-0x5C */ + __IO uint32_t NSEPOCHR_CUR; /*!< FLASH non-secure epoch current register, Address offset: 0x60 */ + __IO uint32_t NSEPOCHR_PRG; /*!< FLASH non-secure epoch to program register, Address offset: 0x64 */ + __IO uint32_t SECEPOCHR_CUR; /*!< FLASH secure epoch current register, Address offset: 0x68 */ + __IO uint32_t SECEPOCHR_PRG; /*!< FLASH secure epoch to program register, Address offset: 0x6C */ + __IO uint32_t OPTSR2_CUR; /*!< FLASH option status current register 2, Address offset: 0x70 */ + __IO uint32_t OPTSR2_PRG; /*!< FLASH option status to program register 2, Address offset: 0x74 */ + uint32_t RESERVED4[2]; /*!< Reserved4, Address offset: 0x78-0x7C */ + __IO uint32_t NSBOOTR_CUR; /*!< FLASH non-secure unique boot entry current register, Address offset: 0x80 */ + __IO uint32_t NSBOOTR_PRG; /*!< FLASH non-secure unique boot entry to program register, Address offset: 0x84 */ + __IO uint32_t SECBOOTR_CUR; /*!< FLASH secure unique boot entry current register, Address offset: 0x88 */ + __IO uint32_t SECBOOTR_PRG; /*!< FLASH secure unique boot entry to program register, Address offset: 0x8C */ + __IO uint32_t OTPBLR_CUR; /*!< FLASH OTP block lock current register, Address offset: 0x90 */ + __IO uint32_t OTPBLR_PRG; /*!< FLASH OTP block Lock to program register, Address offset: 0x94 */ + uint32_t RESERVED5[2]; /*!< Reserved5, Address offset: 0x98-0x9C */ + __IO uint32_t SECBB1R1; /*!< FLASH secure block-based bank 1 register 1, Address offset: 0xA0 */ + __IO uint32_t SECBB1R2; /*!< FLASH secure block-based bank 1 register 2, Address offset: 0xA4 */ + __IO uint32_t SECBB1R3; /*!< FLASH secure block-based bank 1 register 3, Address offset: 0xA8 */ + __IO uint32_t SECBB1R4; /*!< FLASH secure block-based bank 1 register 4, Address offset: 0xAC */ + uint32_t RESERVED6[4]; /*!< Reserved6, Address offset: 0xB0-0xBC */ + __IO uint32_t PRIVBB1R1; /*!< FLASH privilege block-based bank 1 register 1, Address offset: 0xC0 */ + __IO uint32_t PRIVBB1R2; /*!< FLASH privilege block-based bank 1 register 2, Address offset: 0xC4 */ + __IO uint32_t PRIVBB1R3; /*!< FLASH privilege block-based bank 1 register 3, Address offset: 0xC8 */ + __IO uint32_t PRIVBB1R4; /*!< FLASH privilege block-based bank 1 register 4, Address offset: 0xCC */ + uint32_t RESERVED7[4]; /*!< Reserved7, Address offset: 0xD0-0xDC */ + __IO uint32_t SECWM1R_CUR; /*!< FLASH secure watermark 1 current register, Address offset: 0xE0 */ + __IO uint32_t SECWM1R_PRG; /*!< FLASH secure watermark 1 to program register, Address offset: 0xE4 */ + __IO uint32_t WRP1R_CUR; /*!< FLASH write sector group protection current register for bank1, Address offset: 0xE8 */ + __IO uint32_t WRP1R_PRG; /*!< FLASH write sector group protection to program register for bank1, Address offset: 0xEC */ + __IO uint32_t EDATA1R_CUR; /*!< FLASH data sectors configuration current register for bank1, Address offset: 0xF0 */ + __IO uint32_t EDATA1R_PRG; /*!< FLASH data sectors configuration to program register for bank1, Address offset: 0xF4 */ + __IO uint32_t HDP1R_CUR; /*!< FLASH HDP configuration current register for bank1, Address offset: 0xF8 */ + __IO uint32_t HDP1R_PRG; /*!< FLASH HDP configuration to program register for bank1, Address offset: 0xFC */ + __IO uint32_t ECCCORR; /*!< FLASH ECC correction register, Address offset: 0x100 */ + __IO uint32_t ECCDETR; /*!< FLASH ECC detection register, Address offset: 0x104 */ + __IO uint32_t ECCDR; /*!< FLASH ECC data register, Address offset: 0x108 */ + uint32_t RESERVED8[37]; /*!< Reserved8, Address offset: 0x10C-0x19C */ + __IO uint32_t SECBB2R1; /*!< FLASH secure block-based bank 2 register 1, Address offset: 0x1A0 */ + __IO uint32_t SECBB2R2; /*!< FLASH secure block-based bank 2 register 2, Address offset: 0x1A4 */ + __IO uint32_t SECBB2R3; /*!< FLASH secure block-based bank 2 register 3, Address offset: 0x1A8 */ + __IO uint32_t SECBB2R4; /*!< FLASH secure block-based bank 2 register 4, Address offset: 0x1AC */ + uint32_t RESERVED9[4]; /*!< Reserved9, Address offset: 0x1B0-0x1BC */ + __IO uint32_t PRIVBB2R1; /*!< FLASH privilege block-based bank 2 register 1, Address offset: 0x1C0 */ + __IO uint32_t PRIVBB2R2; /*!< FLASH privilege block-based bank 2 register 2, Address offset: 0x1C4 */ + __IO uint32_t PRIVBB2R3; /*!< FLASH privilege block-based bank 2 register 3, Address offset: 0x1C8 */ + __IO uint32_t PRIVBB2R4; /*!< FLASH privilege block-based bank 2 register 4, Address offset: 0x1CC */ + uint32_t RESERVED10[4]; /*!< Reserved10, Address offset: 0x1D0-0x1DC */ + __IO uint32_t SECWM2R_CUR; /*!< FLASH secure watermark 2 current register, Address offset: 0x1E0 */ + __IO uint32_t SECWM2R_PRG; /*!< FLASH secure watermark 2 to program register, Address offset: 0x1E4 */ + __IO uint32_t WRP2R_CUR; /*!< FLASH write sector group protection current register for bank2, Address offset: 0x1E8 */ + __IO uint32_t WRP2R_PRG; /*!< FLASH write sector group protection to program register for bank2, Address offset: 0x1EC */ + __IO uint32_t EDATA2R_CUR; /*!< FLASH data sectors configuration current register for bank2, Address offset: 0x1F0 */ + __IO uint32_t EDATA2R_PRG; /*!< FLASH data sectors configuration to program register for bank2, Address offset: 0x1F4 */ + __IO uint32_t HDP2R_CUR; /*!< FLASH HDP configuration current register for bank2, Address offset: 0x1F8 */ + __IO uint32_t HDP2R_PRG; /*!< FLASH HDP configuration to program register for bank2, Address offset: 0x1FC */ +} FLASH_TypeDef; + +/** + * @brief FMAC + */ +typedef struct +{ + __IO uint32_t X1BUFCFG; /*!< FMAC X1 Buffer Configuration register, Address offset: 0x00 */ + __IO uint32_t X2BUFCFG; /*!< FMAC X2 Buffer Configuration register, Address offset: 0x04 */ + __IO uint32_t YBUFCFG; /*!< FMAC Y Buffer Configuration register, Address offset: 0x08 */ + __IO uint32_t PARAM; /*!< FMAC Parameter register, Address offset: 0x0C */ + __IO uint32_t CR; /*!< FMAC Control register, Address offset: 0x10 */ + __IO uint32_t SR; /*!< FMAC Status register, Address offset: 0x14 */ + __IO uint32_t WDATA; /*!< FMAC Write Data register, Address offset: 0x18 */ + __IO uint32_t RDATA; /*!< FMAC Read Data register, Address offset: 0x1C */ +} FMAC_TypeDef; +/** + * @brief General Purpose I/O + */ +typedef struct +{ + __IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */ + __IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */ + __IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */ + __IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ + __IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */ + __IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */ + __IO uint32_t BSRR; /*!< GPIO port bit set/reset register, Address offset: 0x18 */ + __IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */ + __IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */ + __IO uint32_t BRR; /*!< GPIO Bit Reset register, Address offset: 0x28 */ + __IO uint32_t HSLVR; /*!< GPIO high-speed low voltage register, Address offset: 0x2C */ + __IO uint32_t SECCFGR; /*!< GPIO secure configuration register, Address offset: 0x30 */ +} GPIO_TypeDef; + +/** + * @brief Global TrustZone Controller + */ +typedef struct +{ + __IO uint32_t CR; /*!< TZSC control register, Address offset: 0x00 */ + uint32_t RESERVED1[3]; /*!< Reserved1, Address offset: 0x04-0x0C */ + __IO uint32_t SECCFGR1; /*!< TZSC secure configuration register 1, Address offset: 0x10 */ + __IO uint32_t SECCFGR2; /*!< TZSC secure configuration register 2, Address offset: 0x14 */ + __IO uint32_t SECCFGR3; /*!< TZSC secure configuration register 3, Address offset: 0x18 */ + uint32_t RESERVED2; /*!< Reserved2, Address offset: 0x1C */ + __IO uint32_t PRIVCFGR1; /*!< TZSC privilege configuration register 1, Address offset: 0x20 */ + __IO uint32_t PRIVCFGR2; /*!< TZSC privilege configuration register 2, Address offset: 0x24 */ + __IO uint32_t PRIVCFGR3; /*!< TZSC privilege configuration register 3, Address offset: 0x28 */ + uint32_t RESERVED3[5]; /*!< Reserved3, Address offset: 0x2C-0x3C */ + __IO uint32_t MPCWM1ACFGR; /*!< TZSC memory 1 sub-region A watermark configuration register, Address offset: 0x40 */ + __IO uint32_t MPCWM1AR; /*!< TZSC memory 1 sub-region A watermark register, Address offset: 0x44 */ + __IO uint32_t MPCWM1BCFGR; /*!< TZSC memory 1 sub-region B watermark configuration register, Address offset: 0x48 */ + __IO uint32_t MPCWM1BR; /*!< TZSC memory 1 sub-region B watermark register, Address offset: 0x4C */ + __IO uint32_t MPCWM2ACFGR; /*!< TZSC memory 2 sub-region A watermark configuration register, Address offset: 0x50 */ + __IO uint32_t MPCWM2AR; /*!< TZSC memory 2 sub-region A watermark register, Address offset: 0x54 */ + __IO uint32_t MPCWM2BCFGR; /*!< TZSC memory 2 sub-region B watermark configuration register, Address offset: 0x58 */ + __IO uint32_t MPCWM2BR; /*!< TZSC memory 2 sub-region B watermark register, Address offset: 0x5C */ + __IO uint32_t MPCWM3ACFGR; /*!< TZSC memory 3 sub-region A watermark configuration register, Address offset: 0x60 */ + __IO uint32_t MPCWM3AR; /*!< TZSC memory 3 sub-region A watermark register, Address offset: 0x64 */ + __IO uint32_t MPCWM3BCFGR; /*!< TZSC memory 3 sub-region B watermark configuration register, Address offset: 0x68 */ + __IO uint32_t MPCWM3BR; /*!< TZSC memory 3 sub-region B watermark register, Address offset: 0x6C */ + __IO uint32_t MPCWM4ACFGR; /*!< TZSC memory 4 sub-region A watermark configuration register, Address offset: 0x70 */ + __IO uint32_t MPCWM4AR; /*!< TZSC memory 4 sub-region A watermark register, Address offset: 0x74 */ + __IO uint32_t MPCWM4BCFGR; /*!< TZSC memory 4 sub-region B watermark configuration register, Address offset: 0x78 */ + __IO uint32_t MPCWM4BR; /*!< TZSC memory 4 sub-region B watermark register, Address offset: 0x7c */ +} GTZC_TZSC_TypeDef; + +typedef struct +{ + __IO uint32_t CR; /*!< MPCBBx control register, Address offset: 0x00 */ + uint32_t RESERVED1[3]; /*!< Reserved1, Address offset: 0x04-0x0C */ + __IO uint32_t CFGLOCKR1; /*!< MPCBBx lock register, Address offset: 0x10 */ + uint32_t RESERVED2[59]; /*!< Reserved2, Address offset: 0x14-0xFC */ + __IO uint32_t SECCFGR[32]; /*!< MPCBBx security configuration registers, Address offset: 0x100-0x17C */ + uint32_t RESERVED3[32]; /*!< Reserved3, Address offset: 0x180-0x1FC */ + __IO uint32_t PRIVCFGR[32]; /*!< MPCBBx privilege configuration registers, Address offset: 0x200-0x280 */ +} GTZC_MPCBB_TypeDef; + +typedef struct +{ + __IO uint32_t IER1; /*!< TZIC interrupt enable register 1, Address offset: 0x00 */ + __IO uint32_t IER2; /*!< TZIC interrupt enable register 2, Address offset: 0x04 */ + __IO uint32_t IER3; /*!< TZIC interrupt enable register 3, Address offset: 0x08 */ + __IO uint32_t IER4; /*!< TZIC interrupt enable register 4, Address offset: 0x0C */ + __IO uint32_t SR1; /*!< TZIC status register 1, Address offset: 0x10 */ + __IO uint32_t SR2; /*!< TZIC status register 2, Address offset: 0x14 */ + __IO uint32_t SR3; /*!< TZIC status register 3, Address offset: 0x18 */ + __IO uint32_t SR4; /*!< TZIC status register 4, Address offset: 0x1C */ + __IO uint32_t FCR1; /*!< TZIC flag clear register 1, Address offset: 0x20 */ + __IO uint32_t FCR2; /*!< TZIC flag clear register 2, Address offset: 0x24 */ + __IO uint32_t FCR3; /*!< TZIC flag clear register 3, Address offset: 0x28 */ + __IO uint32_t FCR4; /*!< TZIC flag clear register 3, Address offset: 0x2C */ +} GTZC_TZIC_TypeDef; + +/** + * @brief Instruction Cache + */ +typedef struct +{ + __IO uint32_t CR; /*!< ICACHE control register, Address offset: 0x00 */ + __IO uint32_t SR; /*!< ICACHE status register, Address offset: 0x04 */ + __IO uint32_t IER; /*!< ICACHE interrupt enable register, Address offset: 0x08 */ + __IO uint32_t FCR; /*!< ICACHE Flag clear register, Address offset: 0x0C */ + __IO uint32_t HMONR; /*!< ICACHE hit monitor register, Address offset: 0x10 */ + __IO uint32_t MMONR; /*!< ICACHE miss monitor register, Address offset: 0x14 */ + uint32_t RESERVED1[2]; /*!< Reserved, Address offset: 0x018-0x01C */ + __IO uint32_t CRR0; /*!< ICACHE region 0 configuration register, Address offset: 0x20 */ + __IO uint32_t CRR1; /*!< ICACHE region 1 configuration register, Address offset: 0x24 */ + __IO uint32_t CRR2; /*!< ICACHE region 2 configuration register, Address offset: 0x28 */ + __IO uint32_t CRR3; /*!< ICACHE region 3 configuration register, Address offset: 0x2C */ +} ICACHE_TypeDef; + +/** + * @brief Data Cache + */ +typedef struct +{ + __IO uint32_t CR; /*!< DCACHE control register, Address offset: 0x00 */ + __IO uint32_t SR; /*!< DCACHE status register, Address offset: 0x04 */ + __IO uint32_t IER; /*!< DCACHE interrupt enable register, Address offset: 0x08 */ + __IO uint32_t FCR; /*!< DCACHE Flag clear register, Address offset: 0x0C */ + __IO uint32_t RHMONR; /*!< DCACHE Read hit monitor register, Address offset: 0x10 */ + __IO uint32_t RMMONR; /*!< DCACHE Read miss monitor register, Address offset: 0x14 */ + uint32_t RESERVED1[2]; /*!< Reserved, Address offset: 0x18-0x1C */ + __IO uint32_t WHMONR; /*!< DCACHE Write hit monitor register, Address offset: 0x20 */ + __IO uint32_t WMMONR; /*!< DCACHE Write miss monitor register, Address offset: 0x24 */ + __IO uint32_t CMDRSADDRR; /*!< DCACHE Command Start Address register, Address offset: 0x28 */ + __IO uint32_t CMDREADDRR; /*!< DCACHE Command End Address register, Address offset: 0x2C */ +} DCACHE_TypeDef; + +/** + * @brief TIM + */ +typedef struct +{ + __IO uint32_t CR1; /*!< TIM control register 1, Address offset: 0x00 */ + __IO uint32_t CR2; /*!< TIM control register 2, Address offset: 0x04 */ + __IO uint32_t SMCR; /*!< TIM slave mode control register, Address offset: 0x08 */ + __IO uint32_t DIER; /*!< TIM DMA/interrupt enable register, Address offset: 0x0C */ + __IO uint32_t SR; /*!< TIM status register, Address offset: 0x10 */ + __IO uint32_t EGR; /*!< TIM event generation register, Address offset: 0x14 */ + __IO uint32_t CCMR1; /*!< TIM capture/compare mode register 1, Address offset: 0x18 */ + __IO uint32_t CCMR2; /*!< TIM capture/compare mode register 2, Address offset: 0x1C */ + __IO uint32_t CCER; /*!< TIM capture/compare enable register, Address offset: 0x20 */ + __IO uint32_t CNT; /*!< TIM counter register, Address offset: 0x24 */ + __IO uint32_t PSC; /*!< TIM prescaler, Address offset: 0x28 */ + __IO uint32_t ARR; /*!< TIM auto-reload register, Address offset: 0x2C */ + __IO uint32_t RCR; /*!< TIM repetition counter register, Address offset: 0x30 */ + __IO uint32_t CCR1; /*!< TIM capture/compare register 1, Address offset: 0x34 */ + __IO uint32_t CCR2; /*!< TIM capture/compare register 2, Address offset: 0x38 */ + __IO uint32_t CCR3; /*!< TIM capture/compare register 3, Address offset: 0x3C */ + __IO uint32_t CCR4; /*!< TIM capture/compare register 4, Address offset: 0x40 */ + __IO uint32_t BDTR; /*!< TIM break and dead-time register, Address offset: 0x44 */ + __IO uint32_t CCR5; /*!< TIM capture/compare register 5, Address offset: 0x48 */ + __IO uint32_t CCR6; /*!< TIM capture/compare register 6, Address offset: 0x4C */ + __IO uint32_t CCMR3; /*!< TIM capture/compare mode register 3, Address offset: 0x50 */ + __IO uint32_t DTR2; /*!< TIM deadtime register 2, Address offset: 0x54 */ + __IO uint32_t ECR; /*!< TIM encoder control register, Address offset: 0x58 */ + __IO uint32_t TISEL; /*!< TIM Input Selection register, Address offset: 0x5C */ + __IO uint32_t AF1; /*!< TIM alternate function option register 1, Address offset: 0x60 */ + __IO uint32_t AF2; /*!< TIM alternate function option register 2, Address offset: 0x64 */ + uint32_t RESERVED0[221];/*!< Reserved, Address offset: 0x68 */ + __IO uint32_t DCR; /*!< TIM DMA control register, Address offset: 0x3DC */ + __IO uint32_t DMAR; /*!< TIM DMA address for full transfer, Address offset: 0x3E0 */ +} TIM_TypeDef; + +/** + * @brief LPTIMER + */ +typedef struct +{ + __IO uint32_t ISR; /*!< LPTIM Interrupt and Status register, Address offset: 0x00 */ + __IO uint32_t ICR; /*!< LPTIM Interrupt Clear register, Address offset: 0x04 */ + __IO uint32_t DIER; /*!< LPTIM Interrupt Enable register, Address offset: 0x08 */ + __IO uint32_t CFGR; /*!< LPTIM Configuration register, Address offset: 0x0C */ + __IO uint32_t CR; /*!< LPTIM Control register, Address offset: 0x10 */ + __IO uint32_t CCR1; /*!< LPTIM Capture/Compare register 1, Address offset: 0x14 */ + __IO uint32_t ARR; /*!< LPTIM Autoreload register, Address offset: 0x18 */ + __IO uint32_t CNT; /*!< LPTIM Counter register, Address offset: 0x1C */ + __IO uint32_t RESERVED0; /*!< Reserved, Address offset: 0x20 */ + __IO uint32_t CFGR2; /*!< LPTIM Configuration register 2, Address offset: 0x24 */ + __IO uint32_t RCR; /*!< LPTIM Repetition register, Address offset: 0x28 */ + __IO uint32_t CCMR1; /*!< LPTIM Capture/Compare mode register, Address offset: 0x2C */ + __IO uint32_t RESERVED1; /*!< Reserved, Address offset: 0x30 */ + __IO uint32_t CCR2; /*!< LPTIM Capture/Compare register 2, Address offset: 0x34 */ +} LPTIM_TypeDef; + +/** + * @brief OCTO Serial Peripheral Interface + */ + +typedef struct +{ + __IO uint32_t CR; /*!< OCTOSPI Control register, Address offset: 0x000 */ + uint32_t RESERVED; /*!< Reserved, Address offset: 0x004 */ + __IO uint32_t DCR1; /*!< OCTOSPI Device Configuration register 1, Address offset: 0x008 */ + __IO uint32_t DCR2; /*!< OCTOSPI Device Configuration register 2, Address offset: 0x00C */ + __IO uint32_t DCR3; /*!< OCTOSPI Device Configuration register 3, Address offset: 0x010 */ + __IO uint32_t DCR4; /*!< OCTOSPI Device Configuration register 4, Address offset: 0x014 */ + uint32_t RESERVED1[2]; /*!< Reserved, Address offset: 0x018-0x01C */ + __IO uint32_t SR; /*!< OCTOSPI Status register, Address offset: 0x020 */ + __IO uint32_t FCR; /*!< OCTOSPI Flag Clear register, Address offset: 0x024 */ + uint32_t RESERVED2[6]; /*!< Reserved, Address offset: 0x028-0x03C */ + __IO uint32_t DLR; /*!< OCTOSPI Data Length register, Address offset: 0x040 */ + uint32_t RESERVED3; /*!< Reserved, Address offset: 0x044 */ + __IO uint32_t AR; /*!< OCTOSPI Address register, Address offset: 0x048 */ + uint32_t RESERVED4; /*!< Reserved, Address offset: 0x04C */ + __IO uint32_t DR; /*!< OCTOSPI Data register, Address offset: 0x050 */ + uint32_t RESERVED5[11]; /*!< Reserved, Address offset: 0x054-0x07C */ + __IO uint32_t PSMKR; /*!< OCTOSPI Polling Status Mask register, Address offset: 0x080 */ + uint32_t RESERVED6; /*!< Reserved, Address offset: 0x084 */ + __IO uint32_t PSMAR; /*!< OCTOSPI Polling Status Match register, Address offset: 0x088 */ + uint32_t RESERVED7; /*!< Reserved, Address offset: 0x08C */ + __IO uint32_t PIR; /*!< OCTOSPI Polling Interval register, Address offset: 0x090 */ + uint32_t RESERVED8[27]; /*!< Reserved, Address offset: 0x094-0x0FC */ + __IO uint32_t CCR; /*!< OCTOSPI Communication Configuration register, Address offset: 0x100 */ + uint32_t RESERVED9; /*!< Reserved, Address offset: 0x104 */ + __IO uint32_t TCR; /*!< OCTOSPI Timing Configuration register, Address offset: 0x108 */ + uint32_t RESERVED10; /*!< Reserved, Address offset: 0x10C */ + __IO uint32_t IR; /*!< OCTOSPI Instruction register, Address offset: 0x110 */ + uint32_t RESERVED11[3]; /*!< Reserved, Address offset: 0x114-0x11C */ + __IO uint32_t ABR; /*!< OCTOSPI Alternate Bytes register, Address offset: 0x120 */ + uint32_t RESERVED12[3]; /*!< Reserved, Address offset: 0x124-0x12C */ + __IO uint32_t LPTR; /*!< OCTOSPI Low Power Timeout register, Address offset: 0x130 */ + uint32_t RESERVED13[3]; /*!< Reserved, Address offset: 0x134-0x13C */ + __IO uint32_t WPCCR; /*!< OCTOSPI Wrap Communication Configuration register, Address offset: 0x140 */ + uint32_t RESERVED14; /*!< Reserved, Address offset: 0x144 */ + __IO uint32_t WPTCR; /*!< OCTOSPI Wrap Timing Configuration register, Address offset: 0x148 */ + uint32_t RESERVED15; /*!< Reserved, Address offset: 0x14C */ + __IO uint32_t WPIR; /*!< OCTOSPI Wrap Instruction register, Address offset: 0x150 */ + uint32_t RESERVED16[3]; /*!< Reserved, Address offset: 0x154-0x15C */ + __IO uint32_t WPABR; /*!< OCTOSPI Wrap Alternate Bytes register, Address offset: 0x160 */ + uint32_t RESERVED17[7]; /*!< Reserved, Address offset: 0x164-0x17C */ + __IO uint32_t WCCR; /*!< OCTOSPI Write Communication Configuration register, Address offset: 0x180 */ + uint32_t RESERVED18; /*!< Reserved, Address offset: 0x184 */ + __IO uint32_t WTCR; /*!< OCTOSPI Write Timing Configuration register, Address offset: 0x188 */ + uint32_t RESERVED19; /*!< Reserved, Address offset: 0x18C */ + __IO uint32_t WIR; /*!< OCTOSPI Write Instruction register, Address offset: 0x190 */ + uint32_t RESERVED20[3]; /*!< Reserved, Address offset: 0x194-0x19C */ + __IO uint32_t WABR; /*!< OCTOSPI Write Alternate Bytes register, Address offset: 0x1A0 */ + uint32_t RESERVED21[23]; /*!< Reserved, Address offset: 0x1A4-0x1FC */ + __IO uint32_t HLCR; /*!< OCTOSPI Hyperbus Latency Configuration register, Address offset: 0x200 */ +} XSPI_TypeDef; + +typedef XSPI_TypeDef OCTOSPI_TypeDef; + +/** + * @brief Power Control + */ +typedef struct +{ + __IO uint32_t PMCR; /*!< Power mode control register , Address offset: 0x00 */ + __IO uint32_t PMSR; /*!< Power mode status register , Address offset: 0x04 */ + uint32_t RESERVED1[2]; /*!< Reserved, Address offset: 0x08-0x0C */ + __IO uint32_t VOSCR; /*!< Voltage scaling control register , Address offset: 0x10 */ + __IO uint32_t VOSSR; /*!< Voltage sacling status register , Address offset: 0x14 */ + uint32_t RESERVED2[2]; /*!< Reserved, Address offset: 0x18-0x1C */ + __IO uint32_t BDCR; /*!< BacKup domain control register , Address offset: 0x20 */ + __IO uint32_t DBPCR; /*!< DBP control register, Address offset: 0x24 */ + __IO uint32_t BDSR; /*!< BacKup domain status register, Address offset: 0x28 */ + __IO uint32_t UCPDR; /*!< Usb typeC and Power Delivery Register, Address offset: 0x2C */ + __IO uint32_t SCCR; /*!< Supply configuration control register, Address offset: 0x30 */ + __IO uint32_t VMCR; /*!< Voltage Monitor Control Register, Address offset: 0x34 */ + __IO uint32_t USBSCR; /*!< USB Supply Control Register Address offset: 0x38 */ + __IO uint32_t VMSR; /*!< Status Register Voltage Monitoring, Address offset: 0x3C */ + __IO uint32_t WUSCR; /*!< WakeUP status clear register, Address offset: 0x40 */ + __IO uint32_t WUSR; /*!< WakeUP status Register, Address offset: 0x44 */ + __IO uint32_t WUCR; /*!< WakeUP configuration register, Address offset: 0x48 */ + uint32_t RESERVED3; /*!< Reserved, Address offset: 0x4C */ + __IO uint32_t IORETR; /*!< IO RETention Register, Address offset: 0x50 */ + uint32_t RESERVED4[43];/*!< Reserved, Address offset: 0x54-0xFC */ + __IO uint32_t SECCFGR; /*!< Security configuration register, Address offset: 0x100 */ + __IO uint32_t PRIVCFGR; /*!< Privilege configuration register, Address offset: 0x104 */ +}PWR_TypeDef; + +/** + * @brief SRAMs configuration controller + */ +typedef struct +{ + __IO uint32_t CR; /*!< Control Register, Address offset: 0x00 */ + __IO uint32_t IER; /*!< Interrupt Enable Register, Address offset: 0x04 */ + __IO uint32_t ISR; /*!< Interrupt Status Register, Address offset: 0x08 */ + __IO uint32_t SEAR; /*!< ECC Single Error Address Register, Address offset: 0x0C */ + __IO uint32_t DEAR; /*!< ECC Double Error Address Register, Address offset: 0x10 */ + __IO uint32_t ICR; /*!< Interrupt Clear Register, Address offset: 0x14 */ + __IO uint32_t WPR1; /*!< SRAM Write Protection Register 1, Address offset: 0x18 */ + __IO uint32_t WPR2; /*!< SRAM Write Protection Register 2, Address offset: 0x1C */ + uint32_t RESERVED; /*!< Reserved, Address offset: 0x20 */ + __IO uint32_t ECCKEY; /*!< SRAM ECC Key Register, Address offset: 0x24 */ + __IO uint32_t ERKEYR; /*!< SRAM Erase Key Register, Address offset: 0x28 */ +}RAMCFG_TypeDef; + +/** + * @brief Reset and Clock Control + */ +typedef struct +{ + __IO uint32_t CR; /*!< RCC clock control register Address offset: 0x00 */ + uint32_t RESERVED1[3]; /*!< Reserved, Address offset: 0x04 */ + __IO uint32_t HSICFGR; /*!< RCC HSI Clock Calibration Register, Address offset: 0x10 */ + __IO uint32_t CRRCR; /*!< RCC Clock Recovery RC Register, Address offset: 0x14 */ + __IO uint32_t CSICFGR; /*!< RCC CSI Clock Calibration Register, Address offset: 0x18 */ + __IO uint32_t CFGR1; /*!< RCC clock configuration register 1 Address offset: 0x1C */ + __IO uint32_t CFGR2; /*!< RCC clock configuration register 2 Address offset: 0x20 */ + uint32_t RESERVED2; /*!< Reserved, Address offset: 0x24 */ + __IO uint32_t PLL1CFGR; /*!< RCC PLL1 Configuration Register Address offset: 0x28 */ + __IO uint32_t PLL2CFGR; /*!< RCC PLL2 Configuration Register Address offset: 0x2C */ + __IO uint32_t PLL3CFGR; /*!< RCC PLL3 Configuration Register Address offset: 0x30 */ + __IO uint32_t PLL1DIVR; /*!< RCC PLL1 Dividers Configuration Register Address offset: 0x34 */ + __IO uint32_t PLL1FRACR; /*!< RCC PLL1 Fractional Divider Configuration Register Address offset: 0x38 */ + __IO uint32_t PLL2DIVR; /*!< RCC PLL2 Dividers Configuration Register Address offset: 0x3C */ + __IO uint32_t PLL2FRACR; /*!< RCC PLL2 Fractional Divider Configuration Register Address offset: 0x40 */ + __IO uint32_t PLL3DIVR; /*!< RCC PLL3 Dividers Configuration Register Address offset: 0x44 */ + __IO uint32_t PLL3FRACR; /*!< RCC PLL3 Fractional Divider Configuration Register Address offset: 0x48 */ + uint32_t RESERVED5; /*!< Reserved Address offset: 0x4C */ + __IO uint32_t CIER; /*!< RCC Clock Interrupt Enable Register Address offset: 0x50 */ + __IO uint32_t CIFR; /*!< RCC Clock Interrupt Flag Register Address offset: 0x54 */ + __IO uint32_t CICR; /*!< RCC Clock Interrupt Clear Register Address offset: 0x58 */ + uint32_t RESERVED6; /*!< Reserved Address offset: 0x5C */ + __IO uint32_t AHB1RSTR; /*!< RCC AHB1 Peripherals Reset Register Address offset: 0x60 */ + __IO uint32_t AHB2RSTR; /*!< RCC AHB2 Peripherals Reset Register Address offset: 0x64 */ + uint32_t RESERVED7; /*!< Reserved Address offset: 0x68 */ + __IO uint32_t AHB4RSTR; /*!< RCC AHB4 Peripherals Reset Register Address offset: 0x6C */ + uint32_t RESERVED9; /*!< Reserved Address offset: 0x70 */ + __IO uint32_t APB1LRSTR; /*!< RCC APB1 Peripherals reset Low Word register Address offset: 0x74 */ + __IO uint32_t APB1HRSTR; /*!< RCC APB1 Peripherals reset High Word register Address offset: 0x78 */ + __IO uint32_t APB2RSTR; /*!< RCC APB2 Peripherals Reset Register Address offset: 0x7C */ + __IO uint32_t APB3RSTR; /*!< RCC APB3 Peripherals Reset Register Address offset: 0x80 */ + uint32_t RESERVED10; /*!< Reserved Address offset: 0x84 */ + __IO uint32_t AHB1ENR; /*!< RCC AHB1 Peripherals Clock Enable Register Address offset: 0x88 */ + __IO uint32_t AHB2ENR; /*!< RCC AHB2 Peripherals Clock Enable Register Address offset: 0x8C */ + uint32_t RESERVED11; /*!< Reserved Address offset: 0x90 */ + __IO uint32_t AHB4ENR; /*!< RCC AHB4 Peripherals Clock Enable Register Address offset: 0x94 */ + uint32_t RESERVED13; /*!< Reserved Address offset: 0x98 */ + __IO uint32_t APB1LENR; /*!< RCC APB1 Peripherals clock Enable Low Word register Address offset: 0x9C */ + __IO uint32_t APB1HENR; /*!< RCC APB1 Peripherals clock Enable High Word register Address offset: 0xA0 */ + __IO uint32_t APB2ENR; /*!< RCC APB2 Peripherals Clock Enable Register Address offset: 0xA4 */ + __IO uint32_t APB3ENR; /*!< RCC APB3 Peripherals Clock Enable Register Address offset: 0xA8 */ + uint32_t RESERVED14; /*!< Reserved Address offset: 0xAC */ + __IO uint32_t AHB1LPENR; /*!< RCC AHB1 Peripheral sleep clock Register Address offset: 0xB0 */ + __IO uint32_t AHB2LPENR; /*!< RCC AHB2 Peripheral sleep clock Register Address offset: 0xB4 */ + uint32_t RESERVED15; /*!< Reserved Address offset: 0xB8 */ + __IO uint32_t AHB4LPENR; /*!< RCC AHB4 Peripherals sleep clock Register Address offset: 0xBC */ + uint32_t RESERVED17; /*!< Reserved Address offset: 0xC0 */ + __IO uint32_t APB1LLPENR; /*!< RCC APB1 Peripherals sleep clock Low Word Register Address offset: 0xC4 */ + __IO uint32_t APB1HLPENR; /*!< RCC APB1 Peripherals sleep clock High Word Register Address offset: 0xC8 */ + __IO uint32_t APB2LPENR; /*!< RCC APB2 Peripherals sleep clock Register Address offset: 0xCC */ + __IO uint32_t APB3LPENR; /*!< RCC APB3 Peripherals Clock Low Power Enable Register Address offset: 0xD0 */ + uint32_t RESERVED18; /*!< Reserved Address offset: 0xD4 */ + __IO uint32_t CCIPR1; /*!< RCC IPs Clocks Configuration Register 1 Address offset: 0xD8 */ + __IO uint32_t CCIPR2; /*!< RCC IPs Clocks Configuration Register 2 Address offset: 0xDC */ + __IO uint32_t CCIPR3; /*!< RCC IPs Clocks Configuration Register 3 Address offset: 0xE0 */ + __IO uint32_t CCIPR4; /*!< RCC IPs Clocks Configuration Register 4 Address offset: 0xE4 */ + __IO uint32_t CCIPR5; /*!< RCC IPs Clocks Configuration Register 5 Address offset: 0xE8 */ + uint32_t RESERVED19; /*!< Reserved, Address offset: 0xEC */ + __IO uint32_t BDCR; /*!< RCC VSW Backup Domain & V33 Domain Control Register Address offset: 0xF0 */ + __IO uint32_t RSR; /*!< RCC Reset status Register Address offset: 0xF4 */ + uint32_t RESERVED20[6]; /*!< Reserved Address offset: 0xF8 */ + __IO uint32_t SECCFGR; /*!< RCC Secure mode configuration register Address offset: 0x110 */ + __IO uint32_t PRIVCFGR; /*!< RCC Privilege configuration register Address offset: 0x114 */ +} RCC_TypeDef; + +/* +* @brief RTC Specific device feature definitions +*/ +#define RTC_BKP_NB 32U +#define RTC_TAMP_NB 8U + +/** + * @brief Real-Time Clock + */ +typedef struct +{ + __IO uint32_t TR; /*!< RTC time register, Address offset: 0x00 */ + __IO uint32_t DR; /*!< RTC date register, Address offset: 0x04 */ + __IO uint32_t SSR; /*!< RTC sub second register, Address offset: 0x08 */ + __IO uint32_t ICSR; /*!< RTC initialization control and status register, Address offset: 0x0C */ + __IO uint32_t PRER; /*!< RTC prescaler register, Address offset: 0x10 */ + __IO uint32_t WUTR; /*!< RTC wakeup timer register, Address offset: 0x14 */ + __IO uint32_t CR; /*!< RTC control register, Address offset: 0x18 */ + __IO uint32_t PRIVCFGR; /*!< RTC privilege mode control register, Address offset: 0x1C */ + __IO uint32_t SECCFGR; /*!< RTC secure mode control register, Address offset: 0x20 */ + __IO uint32_t WPR; /*!< RTC write protection register, Address offset: 0x24 */ + __IO uint32_t CALR; /*!< RTC calibration register, Address offset: 0x28 */ + __IO uint32_t SHIFTR; /*!< RTC shift control register, Address offset: 0x2C */ + __IO uint32_t TSTR; /*!< RTC time stamp time register, Address offset: 0x30 */ + __IO uint32_t TSDR; /*!< RTC time stamp date register, Address offset: 0x34 */ + __IO uint32_t TSSSR; /*!< RTC time-stamp sub second register, Address offset: 0x38 */ + uint32_t RESERVED0; /*!< Reserved, Address offset: 0x3C */ + __IO uint32_t ALRMAR; /*!< RTC alarm A register, Address offset: 0x40 */ + __IO uint32_t ALRMASSR; /*!< RTC alarm A sub second register, Address offset: 0x44 */ + __IO uint32_t ALRMBR; /*!< RTC alarm B register, Address offset: 0x48 */ + __IO uint32_t ALRMBSSR; /*!< RTC alarm B sub second register, Address offset: 0x4C */ + __IO uint32_t SR; /*!< RTC Status register, Address offset: 0x50 */ + __IO uint32_t MISR; /*!< RTC masked interrupt status register, Address offset: 0x54 */ + __IO uint32_t SMISR; /*!< RTC secure masked interrupt status register, Address offset: 0x58 */ + __IO uint32_t SCR; /*!< RTC status Clear register, Address offset: 0x5C */ + __IO uint32_t OR; /*!< RTC option register, Address offset: 0x60 */ + uint32_t RESERVED1[3];/*!< Reserved, Address offset: 0x64 */ + __IO uint32_t ALRABINR; /*!< RTC alarm A binary mode register, Address offset: 0x70 */ + __IO uint32_t ALRBBINR; /*!< RTC alarm B binary mode register, Address offset: 0x74 */ +} RTC_TypeDef; + +/** + * @brief Tamper and backup registers + */ +typedef struct +{ + __IO uint32_t CR1; /*!< TAMP control register 1, Address offset: 0x00 */ + __IO uint32_t CR2; /*!< TAMP control register 2, Address offset: 0x04 */ + __IO uint32_t CR3; /*!< TAMP control register 3, Address offset: 0x08 */ + __IO uint32_t FLTCR; /*!< TAMP filter control register, Address offset: 0x0C */ + __IO uint32_t ATCR1; /*!< TAMP filter control register 1 Address offset: 0x10 */ + __IO uint32_t ATSEEDR; /*!< TAMP active tamper seed register, Address offset: 0x14 */ + __IO uint32_t ATOR; /*!< TAMP active tamper output register, Address offset: 0x18 */ + __IO uint32_t ATCR2; /*!< TAMP filter control register 2, Address offset: 0x1C */ + __IO uint32_t SECCFGR; /*!< TAMP secure mode control register, Address offset: 0x20 */ + __IO uint32_t PRIVCFGR; /*!< TAMP privilege mode control register, Address offset: 0x24 */ + uint32_t RESERVED0; /*!< Reserved, Address offset: 0x28 */ + __IO uint32_t IER; /*!< TAMP interrupt enable register, Address offset: 0x2C */ + __IO uint32_t SR; /*!< TAMP status register, Address offset: 0x30 */ + __IO uint32_t MISR; /*!< TAMP masked interrupt status register, Address offset: 0x34 */ + __IO uint32_t SMISR; /*!< TAMP secure masked interrupt status register, Address offset: 0x38 */ + __IO uint32_t SCR; /*!< TAMP status clear register, Address offset: 0x3C */ + __IO uint32_t COUNT1R; /*!< TAMP monotonic counter register, Address offset: 0x40 */ + uint32_t RESERVED1[3];/*!< Reserved, Address offset: 0x44 -- 0x4C */ + __IO uint32_t OR; /*!< TAMP option register, Address offset: 0x50 */ + __IO uint32_t ERCFGR; /*!< TAMP erase configuration register, Address offset: 0x54 */ + uint32_t RESERVED2[42];/*!< Reserved, Address offset: 0x58 -- 0xFC */ + __IO uint32_t BKP0R; /*!< TAMP backup register 0, Address offset: 0x100 */ + __IO uint32_t BKP1R; /*!< TAMP backup register 1, Address offset: 0x104 */ + __IO uint32_t BKP2R; /*!< TAMP backup register 2, Address offset: 0x108 */ + __IO uint32_t BKP3R; /*!< TAMP backup register 3, Address offset: 0x10C */ + __IO uint32_t BKP4R; /*!< TAMP backup register 4, Address offset: 0x110 */ + __IO uint32_t BKP5R; /*!< TAMP backup register 5, Address offset: 0x114 */ + __IO uint32_t BKP6R; /*!< TAMP backup register 6, Address offset: 0x118 */ + __IO uint32_t BKP7R; /*!< TAMP backup register 7, Address offset: 0x11C */ + __IO uint32_t BKP8R; /*!< TAMP backup register 8, Address offset: 0x120 */ + __IO uint32_t BKP9R; /*!< TAMP backup register 9, Address offset: 0x124 */ + __IO uint32_t BKP10R; /*!< TAMP backup register 10, Address offset: 0x128 */ + __IO uint32_t BKP11R; /*!< TAMP backup register 11, Address offset: 0x12C */ + __IO uint32_t BKP12R; /*!< TAMP backup register 12, Address offset: 0x130 */ + __IO uint32_t BKP13R; /*!< TAMP backup register 13, Address offset: 0x134 */ + __IO uint32_t BKP14R; /*!< TAMP backup register 14, Address offset: 0x138 */ + __IO uint32_t BKP15R; /*!< TAMP backup register 15, Address offset: 0x13C */ + __IO uint32_t BKP16R; /*!< TAMP backup register 16, Address offset: 0x140 */ + __IO uint32_t BKP17R; /*!< TAMP backup register 17, Address offset: 0x144 */ + __IO uint32_t BKP18R; /*!< TAMP backup register 18, Address offset: 0x148 */ + __IO uint32_t BKP19R; /*!< TAMP backup register 19, Address offset: 0x14C */ + __IO uint32_t BKP20R; /*!< TAMP backup register 20, Address offset: 0x150 */ + __IO uint32_t BKP21R; /*!< TAMP backup register 21, Address offset: 0x154 */ + __IO uint32_t BKP22R; /*!< TAMP backup register 22, Address offset: 0x158 */ + __IO uint32_t BKP23R; /*!< TAMP backup register 23, Address offset: 0x15C */ + __IO uint32_t BKP24R; /*!< TAMP backup register 24, Address offset: 0x160 */ + __IO uint32_t BKP25R; /*!< TAMP backup register 25, Address offset: 0x164 */ + __IO uint32_t BKP26R; /*!< TAMP backup register 26, Address offset: 0x168 */ + __IO uint32_t BKP27R; /*!< TAMP backup register 27, Address offset: 0x16C */ + __IO uint32_t BKP28R; /*!< TAMP backup register 28, Address offset: 0x170 */ + __IO uint32_t BKP29R; /*!< TAMP backup register 29, Address offset: 0x174 */ + __IO uint32_t BKP30R; /*!< TAMP backup register 30, Address offset: 0x178 */ + __IO uint32_t BKP31R; /*!< TAMP backup register 31, Address offset: 0x17C */ +} TAMP_TypeDef; + +/** + * @brief Universal Synchronous Asynchronous Receiver Transmitter + */ +typedef struct +{ + __IO uint32_t CR1; /*!< USART Control register 1, Address offset: 0x00 */ + __IO uint32_t CR2; /*!< USART Control register 2, Address offset: 0x04 */ + __IO uint32_t CR3; /*!< USART Control register 3, Address offset: 0x08 */ + __IO uint32_t BRR; /*!< USART Baud rate register, Address offset: 0x0C */ + __IO uint32_t GTPR; /*!< USART Guard time and prescaler register, Address offset: 0x10 */ + __IO uint32_t RTOR; /*!< USART Receiver Time Out register, Address offset: 0x14 */ + __IO uint32_t RQR; /*!< USART Request register, Address offset: 0x18 */ + __IO uint32_t ISR; /*!< USART Interrupt and status register, Address offset: 0x1C */ + __IO uint32_t ICR; /*!< USART Interrupt flag Clear register, Address offset: 0x20 */ + __IO uint32_t RDR; /*!< USART Receive Data register, Address offset: 0x24 */ + __IO uint32_t TDR; /*!< USART Transmit Data register, Address offset: 0x28 */ + __IO uint32_t PRESC; /*!< USART Prescaler register, Address offset: 0x2C */ +} USART_TypeDef; + +/** + * @brief Serial Audio Interface + */ +typedef struct +{ + __IO uint32_t GCR; /*!< SAI global configuration register, Address offset: 0x00 */ + uint32_t RESERVED[16]; /*!< Reserved, Address offset: 0x04 to 0x40 */ + __IO uint32_t PDMCR; /*!< SAI PDM control register, Address offset: 0x44 */ + __IO uint32_t PDMDLY; /*!< SAI PDM delay register, Address offset: 0x48 */ +} SAI_TypeDef; + +typedef struct +{ + __IO uint32_t CR1; /*!< SAI block x configuration register 1, Address offset: 0x04 */ + __IO uint32_t CR2; /*!< SAI block x configuration register 2, Address offset: 0x08 */ + __IO uint32_t FRCR; /*!< SAI block x frame configuration register, Address offset: 0x0C */ + __IO uint32_t SLOTR; /*!< SAI block x slot register, Address offset: 0x10 */ + __IO uint32_t IMR; /*!< SAI block x interrupt mask register, Address offset: 0x14 */ + __IO uint32_t SR; /*!< SAI block x status register, Address offset: 0x18 */ + __IO uint32_t CLRFR; /*!< SAI block x clear flag register, Address offset: 0x1C */ + __IO uint32_t DR; /*!< SAI block x data register, Address offset: 0x20 */ +} SAI_Block_TypeDef; +/** + * @brief System configuration, Boot and Security + */ +typedef struct +{ + uint32_t RESERVED1[4]; /*!< RESERVED1, Address offset: 0x00 - 0x0C */ + __IO uint32_t HDPLCR; /*!< SBS HDPL Control Register, Address offset: 0x10 */ + __IO uint32_t HDPLSR; /*!< SBS HDPL Status Register, Address offset: 0x14 */ + __IO uint32_t NEXTHDPLCR; /*!< NEXT HDPL Control Register, Address offset: 0x18 */ + __IO uint32_t RESERVED2; /*!< RESERVED2, Address offset: 0x1C */ + __IO uint32_t DBGCR; /*!< SBS Debug Control Register, Address offset: 0x20 */ + __IO uint32_t DBGLOCKR; /*!< SBS Debug Lock Register, Address offset: 0x24 */ + uint32_t RESERVED3[3]; /*!< RESERVED3, Address offset: 0x28 - 0x30 */ + __IO uint32_t RSSCMDR; /*!< SBS RSS Command Register, Address offset: 0x34 */ + uint32_t RESERVED4[26]; /*!< RESERVED4, Address offset: 0x38 - 0x9C */ + __IO uint32_t EPOCHSELCR; /*!< EPOCH Selection Register, Address offset: 0xA0 */ + uint32_t RESERVED5[7]; /*!< RESERVED5, Address offset: 0xA4 - 0xBC */ + __IO uint32_t SECCFGR; /*!< SBS Security Mode Configuration, Address offset: 0xC0 */ + uint32_t RESERVED6[15]; /*!< RESERVED6, Address offset: 0xC4 - 0xFC */ + __IO uint32_t PMCR; /*!< SBS Product Mode & Config Register, Address offset: 0x100 */ + __IO uint32_t FPUIMR; /*!< SBS FPU Interrupt Mask Register, Address offset: 0x104 */ + __IO uint32_t MESR; /*!< SBS Memory Erase Status Register, Address offset: 0x108 */ + uint32_t RESERVED7; /*!< RESERVED7, Address offset: 0x10C */ + __IO uint32_t CCCSR; /*!< SBS Compensation Cell Control & Status Register, Address offset: 0x110 */ + __IO uint32_t CCVALR; /*!< SBS Compensation Cell Value Register, Address offset: 0x114 */ + __IO uint32_t CCSWCR; /*!< SBS Compensation Cell for I/Os sw code Register, Address offset: 0x118 */ + __IO uint32_t RESERVED8; /*!< RESERVED8, Address offset: 0x11C */ + __IO uint32_t CFGR2; /*!< SBS Class B Register, Address offset: 0x120 */ + uint32_t RESERVED9[8]; /*!< RESERVED9, Address offset: 0x124 - 0x140 */ + __IO uint32_t CNSLCKR; /*!< SBS CPU Non-secure Lock Register, Address offset: 0x144 */ + __IO uint32_t CSLCKR; /*!< SBS CPU Secure Lock Register, Address offset: 0x148 */ + __IO uint32_t ECCNMIR; /*!< SBS FLITF ECC NMI MASK Register, Address offset: 0x14C */ +} SBS_TypeDef; + +/** + * @brief Secure digital input/output Interface + */ +typedef struct +{ + __IO uint32_t POWER; /*!< SDMMC power control register, Address offset: 0x00 */ + __IO uint32_t CLKCR; /*!< SDMMC clock control register, Address offset: 0x04 */ + __IO uint32_t ARG; /*!< SDMMC argument register, Address offset: 0x08 */ + __IO uint32_t CMD; /*!< SDMMC command register, Address offset: 0x0C */ + __I uint32_t RESPCMD; /*!< SDMMC command response register, Address offset: 0x10 */ + __I uint32_t RESP1; /*!< SDMMC response 1 register, Address offset: 0x14 */ + __I uint32_t RESP2; /*!< SDMMC response 2 register, Address offset: 0x18 */ + __I uint32_t RESP3; /*!< SDMMC response 3 register, Address offset: 0x1C */ + __I uint32_t RESP4; /*!< SDMMC response 4 register, Address offset: 0x20 */ + __IO uint32_t DTIMER; /*!< SDMMC data timer register, Address offset: 0x24 */ + __IO uint32_t DLEN; /*!< SDMMC data length register, Address offset: 0x28 */ + __IO uint32_t DCTRL; /*!< SDMMC data control register, Address offset: 0x2C */ + __I uint32_t DCOUNT; /*!< SDMMC data counter register, Address offset: 0x30 */ + __I uint32_t STA; /*!< SDMMC status register, Address offset: 0x34 */ + __IO uint32_t ICR; /*!< SDMMC interrupt clear register, Address offset: 0x38 */ + __IO uint32_t MASK; /*!< SDMMC mask register, Address offset: 0x3C */ + __IO uint32_t ACKTIME; /*!< SDMMC Acknowledgement timer register, Address offset: 0x40 */ + uint32_t RESERVED0[3]; /*!< Reserved, 0x44 - 0x4C - 0x4C */ + __IO uint32_t IDMACTRL; /*!< SDMMC DMA control register, Address offset: 0x50 */ + __IO uint32_t IDMABSIZE; /*!< SDMMC DMA buffer size register, Address offset: 0x54 */ + __IO uint32_t IDMABASER; /*!< SDMMC DMA buffer base address register, Address offset: 0x58 */ + uint32_t RESERVED1[2]; /*!< Reserved, 0x60 */ + __IO uint32_t IDMALAR; /*!< SDMMC DMA linked list address register, Address offset: 0x64 */ + __IO uint32_t IDMABAR; /*!< SDMMC DMA linked list memory base register,Address offset: 0x68 */ + uint32_t RESERVED2[5]; /*!< Reserved, 0x6C-0x7C */ + __IO uint32_t FIFO; /*!< SDMMC data FIFO register, Address offset: 0x80 */ +} SDMMC_TypeDef; + + + +/** + * @brief Delay Block DLYB + */ + +typedef struct +{ + __IO uint32_t CR; /*!< DELAY BLOCK control register, Address offset: 0x00 */ + __IO uint32_t CFGR; /*!< DELAY BLOCK configuration register, Address offset: 0x04 */ +} DLYB_TypeDef; + +/** + * @brief UCPD + */ +typedef struct +{ + __IO uint32_t CFG1; /*!< UCPD configuration register 1, Address offset: 0x00 */ + __IO uint32_t CFG2; /*!< UCPD configuration register 2, Address offset: 0x04 */ + __IO uint32_t CFG3; /*!< UCPD configuration register 3, Address offset: 0x08 */ + __IO uint32_t CR; /*!< UCPD control register, Address offset: 0x0C */ + __IO uint32_t IMR; /*!< UCPD interrupt mask register, Address offset: 0x10 */ + __IO uint32_t SR; /*!< UCPD status register, Address offset: 0x14 */ + __IO uint32_t ICR; /*!< UCPD interrupt flag clear register Address offset: 0x18 */ + __IO uint32_t TX_ORDSET; /*!< UCPD Tx ordered set type register, Address offset: 0x1C */ + __IO uint32_t TX_PAYSZ; /*!< UCPD Tx payload size register, Address offset: 0x20 */ + __IO uint32_t TXDR; /*!< UCPD Tx data register, Address offset: 0x24 */ + __IO uint32_t RX_ORDSET; /*!< UCPD Rx ordered set type register, Address offset: 0x28 */ + __IO uint32_t RX_PAYSZ; /*!< UCPD Rx payload size register, Address offset: 0x2C */ + __IO uint32_t RXDR; /*!< UCPD Rx data register, Address offset: 0x30 */ + __IO uint32_t RX_ORDEXT1; /*!< UCPD Rx ordered set extension 1 register, Address offset: 0x34 */ + __IO uint32_t RX_ORDEXT2; /*!< UCPD Rx ordered set extension 2 register, Address offset: 0x38 */ + uint32_t RESERVED[949];/*!< Reserved, Address offset: 0x3C -- 0x3F0 */ + __IO uint32_t IPVER; /*!< UCPD IP version register, Address offset: 0x3F4 */ + __IO uint32_t IPID; /*!< UCPD IP Identification register, Address offset: 0x3F8 */ + __IO uint32_t MID; /*!< UCPD Magic Identification register, Address offset: 0x3FC */ +} UCPD_TypeDef; + +/** + * @brief Universal Serial Bus Full Speed Dual Role Device + */ +typedef struct +{ + __IO uint32_t CHEP0R; /*!< USB Channel/Endpoint 0 register, Address offset: 0x00 */ + __IO uint32_t CHEP1R; /*!< USB Channel/Endpoint 1 register, Address offset: 0x04 */ + __IO uint32_t CHEP2R; /*!< USB Channel/Endpoint 2 register, Address offset: 0x08 */ + __IO uint32_t CHEP3R; /*!< USB Channel/Endpoint 3 register, Address offset: 0x0C */ + __IO uint32_t CHEP4R; /*!< USB Channel/Endpoint 4 register, Address offset: 0x10 */ + __IO uint32_t CHEP5R; /*!< USB Channel/Endpoint 5 register, Address offset: 0x14 */ + __IO uint32_t CHEP6R; /*!< USB Channel/Endpoint 6 register, Address offset: 0x18 */ + __IO uint32_t CHEP7R; /*!< USB Channel/Endpoint 7 register, Address offset: 0x1C */ + __IO uint32_t RESERVED0[8]; /*!< Reserved, */ + __IO uint32_t CNTR; /*!< Control register, Address offset: 0x40 */ + __IO uint32_t ISTR; /*!< Interrupt status register, Address offset: 0x44 */ + __IO uint32_t FNR; /*!< Frame number register, Address offset: 0x48 */ + __IO uint32_t DADDR; /*!< Device address register, Address offset: 0x4C */ + __IO uint32_t RESERVED1; /*!< Reserved */ + __IO uint32_t LPMCSR; /*!< LPM Control and Status register, Address offset: 0x54 */ + __IO uint32_t BCDR; /*!< Battery Charging detector register, Address offset: 0x58 */ +} USB_DRD_TypeDef; + +/** + * @brief Universal Serial Bus PacketMemoryArea Buffer Descriptor Table + */ +typedef struct +{ + __IO uint32_t TXBD; /*!= 6010050) + #pragma clang diagnostic pop +#elif defined (__GNUC__) + /* anonymous unions are enabled by default */ +#elif defined (__TMS470__) + /* anonymous unions are enabled by default */ +#elif defined (__TASKING__) + #pragma warning restore +#elif defined (__CSMC__) + /* anonymous unions are enabled by default */ +#else + #warning Not supported compiler type +#endif + + +/* =========================================================================================================================== */ +/* ================ Device Specific Peripheral Address Map ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup STM32H5xx_Peripheral_peripheralAddr + * @{ + */ + +/* Internal SRAMs size */ +#define SRAM1_SIZE (0x40000UL) /*!< SRAM1=256k */ +#define SRAM2_SIZE (0x10000UL) /*!< SRAM2=64k */ +#define SRAM3_SIZE (0x50000UL) /*!< SRAM3=320k */ +#define BKPSRAM_SIZE (0x01000UL) /*!< BKPSRAM=4k */ + +/* Flash, Peripheral and internal SRAMs base addresses - Non secure */ +#define FLASH_BASE_NS (0x08000000UL) /*!< FLASH (up to 2 MB) non-secure base address */ +#define SRAM1_BASE_NS (0x20000000UL) /*!< SRAM1 (256 KB) non-secure base address */ +#define SRAM2_BASE_NS (0x20040000UL) /*!< SRAM2 (64 KB) non-secure base address */ +#define SRAM3_BASE_NS (0x20050000UL) /*!< SRAM3 (320 KB) non-secure base address */ +#define PERIPH_BASE_NS (0x40000000UL) /*!< Peripheral non-secure base address */ + +/* External memories base addresses - Not aliased */ +#define FMC_BASE (0x60000000UL) /*!< FMC base address */ +#define OCTOSPI1_BASE (0x90000000UL) /*!< OCTOSPI1 memories accessible over AHB base address */ + +#define FMC_BANK1 FMC_BASE +#define FMC_BANK1_1 FMC_BANK1 +#define FMC_BANK1_2 (FMC_BANK1 + 0x04000000UL) /*!< FMC Memory Bank1 for SRAM, NOR and PSRAM */ +#define FMC_BANK1_3 (FMC_BANK1 + 0x08000000UL) +#define FMC_BANK1_4 (FMC_BANK1 + 0x0C000000UL) +#define FMC_BANK3 (FMC_BASE + 0x20000000UL) /*!< FMC Memory Bank3 for NAND */ +#define FMC_SDRAM_BANK_1 (FMC_BASE + 0x60000000UL) /*!< FMC Memory SDRAM Bank1 */ +#define FMC_SDRAM_BANK_2 (FMC_BASE + 0x70000000UL) /*!< FMC Memory SDRAM Bank2 */ + + +/* Peripheral memory map - Non secure */ +#define APB1PERIPH_BASE_NS PERIPH_BASE_NS +#define APB2PERIPH_BASE_NS (PERIPH_BASE_NS + 0x00010000UL) +#define AHB1PERIPH_BASE_NS (PERIPH_BASE_NS + 0x00020000UL) +#define AHB2PERIPH_BASE_NS (PERIPH_BASE_NS + 0x02020000UL) +#define APB3PERIPH_BASE_NS (PERIPH_BASE_NS + 0x04000000UL) +#define AHB3PERIPH_BASE_NS (PERIPH_BASE_NS + 0x04020000UL) +#define AHB4PERIPH_BASE_NS (PERIPH_BASE_NS + 0x06000000UL) + +/*!< APB1 Non secure peripherals */ +#define TIM2_BASE_NS (APB1PERIPH_BASE_NS + 0x0000UL) +#define TIM3_BASE_NS (APB1PERIPH_BASE_NS + 0x0400UL) +#define TIM4_BASE_NS (APB1PERIPH_BASE_NS + 0x0800UL) +#define TIM5_BASE_NS (APB1PERIPH_BASE_NS + 0x0C00UL) +#define TIM6_BASE_NS (APB1PERIPH_BASE_NS + 0x1000UL) +#define TIM7_BASE_NS (APB1PERIPH_BASE_NS + 0x1400UL) +#define TIM12_BASE_NS (APB1PERIPH_BASE_NS + 0x1800UL) +#define TIM13_BASE_NS (APB1PERIPH_BASE_NS + 0x1C00UL) +#define TIM14_BASE_NS (APB1PERIPH_BASE_NS + 0x2000UL) +#define WWDG_BASE_NS (APB1PERIPH_BASE_NS + 0x2C00UL) +#define IWDG_BASE_NS (APB1PERIPH_BASE_NS + 0x3000UL) +#define SPI2_BASE_NS (APB1PERIPH_BASE_NS + 0x3800UL) +#define SPI3_BASE_NS (APB1PERIPH_BASE_NS + 0x3C00UL) +#define USART2_BASE_NS (APB1PERIPH_BASE_NS + 0x4400UL) +#define USART3_BASE_NS (APB1PERIPH_BASE_NS + 0x4800UL) +#define UART4_BASE_NS (APB1PERIPH_BASE_NS + 0x4C00UL) +#define UART5_BASE_NS (APB1PERIPH_BASE_NS + 0x5000UL) +#define I2C1_BASE_NS (APB1PERIPH_BASE_NS + 0x5400UL) +#define I2C2_BASE_NS (APB1PERIPH_BASE_NS + 0x5800UL) +#define I3C1_BASE_NS (APB1PERIPH_BASE_NS + 0x5C00UL) +#define CRS_BASE_NS (APB1PERIPH_BASE_NS + 0x6000UL) +#define USART6_BASE_NS (APB1PERIPH_BASE_NS + 0x6400UL) +#define USART10_BASE_NS (APB1PERIPH_BASE_NS + 0x6800UL) +#define USART11_BASE_NS (APB1PERIPH_BASE_NS + 0x6C00UL) +#define CEC_BASE_NS (APB1PERIPH_BASE_NS + 0x7000UL) +#define UART7_BASE_NS (APB1PERIPH_BASE_NS + 0x7800UL) +#define UART8_BASE_NS (APB1PERIPH_BASE_NS + 0x7C00UL) +#define UART9_BASE_NS (APB1PERIPH_BASE_NS + 0x8000UL) +#define UART12_BASE_NS (APB1PERIPH_BASE_NS + 0x8400UL) +#define DTS_BASE_NS (APB1PERIPH_BASE_NS + 0x8C00UL) +#define LPTIM2_BASE_NS (APB1PERIPH_BASE_NS + 0x9400UL) +#define FDCAN1_BASE_NS (APB1PERIPH_BASE_NS + 0xA400UL) +#define FDCAN_CONFIG_BASE_NS (APB1PERIPH_BASE_NS + 0xA500UL) +#define SRAMCAN_BASE_NS (APB1PERIPH_BASE_NS + 0xAC00UL) +#define FDCAN2_BASE_NS (APB1PERIPH_BASE_NS + 0xA800UL) +#define UCPD1_BASE_NS (APB1PERIPH_BASE_NS + 0xDC00UL) + +/*!< APB2 Non secure peripherals */ +#define TIM1_BASE_NS (APB2PERIPH_BASE_NS + 0x2C00UL) +#define SPI1_BASE_NS (APB2PERIPH_BASE_NS + 0x3000UL) +#define TIM8_BASE_NS (APB2PERIPH_BASE_NS + 0x3400UL) +#define USART1_BASE_NS (APB2PERIPH_BASE_NS + 0x3800UL) +#define TIM15_BASE_NS (APB2PERIPH_BASE_NS + 0x4000UL) +#define TIM16_BASE_NS (APB2PERIPH_BASE_NS + 0x4400UL) +#define TIM17_BASE_NS (APB2PERIPH_BASE_NS + 0x4800UL) +#define SPI4_BASE_NS (APB2PERIPH_BASE_NS + 0x4C00UL) +#define SPI6_BASE_NS (APB2PERIPH_BASE_NS + 0x5000UL) +#define SAI1_BASE_NS (APB2PERIPH_BASE_NS + 0x5400UL) +#define SAI1_Block_A_BASE_NS (SAI1_BASE_NS + 0x004UL) +#define SAI1_Block_B_BASE_NS (SAI1_BASE_NS + 0x024UL) +#define SAI2_BASE_NS (APB2PERIPH_BASE_NS + 0x5800UL) +#define SAI2_Block_A_BASE_NS (SAI2_BASE_NS + 0x004UL) +#define SAI2_Block_B_BASE_NS (SAI2_BASE_NS + 0x024UL) +#define USB_DRD_BASE_NS (APB2PERIPH_BASE_NS + 0x6000UL) +#define USB_DRD_PMAADDR_NS (APB2PERIPH_BASE_NS + 0x6400UL) + +/*!< AHB1 Non secure peripherals */ +#define GPDMA1_BASE_NS AHB1PERIPH_BASE_NS +#define GPDMA2_BASE_NS (AHB1PERIPH_BASE_NS + 0x01000UL) +#define FLASH_R_BASE_NS (AHB1PERIPH_BASE_NS + 0x02000UL) +#define CRC_BASE_NS (AHB1PERIPH_BASE_NS + 0x03000UL) +#define CORDIC_BASE_NS (AHB1PERIPH_BASE_NS + 0x03800UL) +#define FMAC_BASE_NS (AHB1PERIPH_BASE_NS + 0x03C00UL) +#define RAMCFG_BASE_NS (AHB1PERIPH_BASE_NS + 0x06000UL) +#define ETH_BASE_NS (AHB1PERIPH_BASE_NS + 0x8000UL) +#define ETH_MAC_BASE_NS (ETH_BASE) +#define ICACHE_BASE_NS (AHB1PERIPH_BASE_NS + 0x10400UL) +#define DCACHE1_BASE_NS (AHB1PERIPH_BASE_NS + 0x11400UL) +#define GTZC_TZSC1_BASE_NS (AHB1PERIPH_BASE_NS + 0x12400UL) +#define GTZC_TZIC1_BASE_NS (AHB1PERIPH_BASE_NS + 0x12800UL) +#define GTZC_MPCBB1_BASE_NS (AHB1PERIPH_BASE_NS + 0x12C00UL) +#define GTZC_MPCBB2_BASE_NS (AHB1PERIPH_BASE_NS + 0x13000UL) +#define GTZC_MPCBB3_BASE_NS (AHB1PERIPH_BASE_NS + 0x13400UL) +#define BKPSRAM_BASE_NS (AHB1PERIPH_BASE_NS + 0x16400UL) + +#define GPDMA1_Channel0_BASE_NS (GPDMA1_BASE_NS + 0x0050UL) +#define GPDMA1_Channel1_BASE_NS (GPDMA1_BASE_NS + 0x00D0UL) +#define GPDMA1_Channel2_BASE_NS (GPDMA1_BASE_NS + 0x0150UL) +#define GPDMA1_Channel3_BASE_NS (GPDMA1_BASE_NS + 0x01D0UL) +#define GPDMA1_Channel4_BASE_NS (GPDMA1_BASE_NS + 0x0250UL) +#define GPDMA1_Channel5_BASE_NS (GPDMA1_BASE_NS + 0x02D0UL) +#define GPDMA1_Channel6_BASE_NS (GPDMA1_BASE_NS + 0x0350UL) +#define GPDMA1_Channel7_BASE_NS (GPDMA1_BASE_NS + 0x03D0UL) +#define GPDMA2_Channel0_BASE_NS (GPDMA2_BASE_NS + 0x0050UL) +#define GPDMA2_Channel1_BASE_NS (GPDMA2_BASE_NS + 0x00D0UL) +#define GPDMA2_Channel2_BASE_NS (GPDMA2_BASE_NS + 0x0150UL) +#define GPDMA2_Channel3_BASE_NS (GPDMA2_BASE_NS + 0x01D0UL) +#define GPDMA2_Channel4_BASE_NS (GPDMA2_BASE_NS + 0x0250UL) +#define GPDMA2_Channel5_BASE_NS (GPDMA2_BASE_NS + 0x02D0UL) +#define GPDMA2_Channel6_BASE_NS (GPDMA2_BASE_NS + 0x0350UL) +#define GPDMA2_Channel7_BASE_NS (GPDMA2_BASE_NS + 0x03D0UL) + +#define RAMCFG_SRAM1_BASE_NS (RAMCFG_BASE_NS) +#define RAMCFG_SRAM2_BASE_NS (RAMCFG_BASE_NS + 0x0040UL) +#define RAMCFG_SRAM3_BASE_NS (RAMCFG_BASE_NS + 0x0080UL) +#define RAMCFG_BKPRAM_BASE_NS (RAMCFG_BASE_NS + 0x0100UL) + +/*!< AHB2 Non secure peripherals */ +#define GPIOA_BASE_NS (AHB2PERIPH_BASE_NS + 0x00000UL) +#define GPIOB_BASE_NS (AHB2PERIPH_BASE_NS + 0x00400UL) +#define GPIOC_BASE_NS (AHB2PERIPH_BASE_NS + 0x00800UL) +#define GPIOD_BASE_NS (AHB2PERIPH_BASE_NS + 0x00C00UL) +#define GPIOE_BASE_NS (AHB2PERIPH_BASE_NS + 0x01000UL) +#define GPIOF_BASE_NS (AHB2PERIPH_BASE_NS + 0x01400UL) +#define GPIOG_BASE_NS (AHB2PERIPH_BASE_NS + 0x01800UL) +#define GPIOH_BASE_NS (AHB2PERIPH_BASE_NS + 0x01C00UL) +#define GPIOI_BASE_NS (AHB2PERIPH_BASE_NS + 0x02000UL) +#define ADC1_BASE_NS (AHB2PERIPH_BASE_NS + 0x08000UL) +#define ADC2_BASE_NS (AHB2PERIPH_BASE_NS + 0x08100UL) +#define ADC12_COMMON_BASE_NS (AHB2PERIPH_BASE_NS + 0x08300UL) +#define DAC1_BASE_NS (AHB2PERIPH_BASE_NS + 0x08400UL) +#define DCMI_BASE_NS (AHB2PERIPH_BASE_NS + 0x0C000UL) +#define PSSI_BASE_NS (AHB2PERIPH_BASE_NS + 0x0C400UL) + +#define HASH_BASE_NS (AHB2PERIPH_BASE_NS + 0xA0400UL) +#define HASH_DIGEST_BASE_NS (AHB2PERIPH_BASE_NS + 0xA0710UL) +#define RNG_BASE_NS (AHB2PERIPH_BASE_NS + 0xA0800UL) + + +/*!< APB3 Non secure peripherals */ +#define SBS_BASE_NS (APB3PERIPH_BASE_NS + 0x0400UL) +#define SPI5_BASE_NS (APB3PERIPH_BASE_NS + 0x2000UL) +#define LPUART1_BASE_NS (APB3PERIPH_BASE_NS + 0x2400UL) +#define I2C3_BASE_NS (APB3PERIPH_BASE_NS + 0x2800UL) +#define I2C4_BASE_NS (APB3PERIPH_BASE_NS + 0x2C00UL) +#define LPTIM1_BASE_NS (APB3PERIPH_BASE_NS + 0x4400UL) +#define LPTIM3_BASE_NS (APB3PERIPH_BASE_NS + 0x4800UL) +#define LPTIM4_BASE_NS (APB3PERIPH_BASE_NS + 0x4C00UL) +#define LPTIM5_BASE_NS (APB3PERIPH_BASE_NS + 0x5000UL) +#define LPTIM6_BASE_NS (APB3PERIPH_BASE_NS + 0x5400UL) +#define VREFBUF_BASE_NS (APB3PERIPH_BASE_NS + 0x7400UL) +#define RTC_BASE_NS (APB3PERIPH_BASE_NS + 0x7800UL) +#define TAMP_BASE_NS (APB3PERIPH_BASE_NS + 0x7C00UL) + +/*!< AHB3 Non secure peripherals */ +#define PWR_BASE_NS (AHB3PERIPH_BASE_NS + 0x0800UL) +#define RCC_BASE_NS (AHB3PERIPH_BASE_NS + 0x0C00UL) +#define EXTI_BASE_NS (AHB3PERIPH_BASE_NS + 0x2000UL) +#define DEBUG_BASE_NS (AHB3PERIPH_BASE_NS + 0x4000UL) +/*!< AHB4 Non secure peripherals */ +#define SDMMC1_BASE_NS (AHB4PERIPH_BASE_NS + 0x8000UL) +#define DLYB_SDMMC1_BASE_NS (AHB4PERIPH_BASE_NS + 0x8400UL) +#define SDMMC2_BASE_NS (AHB4PERIPH_BASE_NS + 0x8C00UL) +#define DLYB_SDMMC2_BASE_NS (AHB4PERIPH_BASE_NS + 0x8800UL) + +#define FMC_R_BASE_NS (AHB4PERIPH_BASE_NS + 0x1000400UL) /*!< FMC control registers base address */ +#define OCTOSPI1_R_BASE_NS (AHB4PERIPH_BASE_NS + 0x1001400UL) /*!< OCTOSPI1 control registers base address */ +#define DLYB_OCTOSPI1_BASE_NS (AHB4PERIPH_BASE_NS + 0x0F000UL) + +/*!< FMC Banks Non secure registers base address */ +#define FMC_Bank1_R_BASE_NS (FMC_R_BASE_NS + 0x0000UL) +#define FMC_Bank1E_R_BASE_NS (FMC_R_BASE_NS + 0x0104UL) +#define FMC_Bank3_R_BASE_NS (FMC_R_BASE_NS + 0x0080UL) +#define FMC_Bank5_6_R_BASE_NS (FMC_R_BASE_NS + 0x0140UL) + +/* Flash, Peripheral and internal SRAMs base addresses - Secure */ +#define FLASH_BASE_S (0x0C000000UL) /*!< FLASH (up to 2 MB) secure base address */ +#define SRAM1_BASE_S (0x30000000UL) /*!< SRAM1 (192 KB) secure base address */ +#define SRAM2_BASE_S (0x30040000UL) /*!< SRAM2 (64 KB) secure base address */ +#define SRAM3_BASE_S (0x30050000UL) /*!< SRAM3 (512 KB) secure base address */ +#define PERIPH_BASE_S (0x50000000UL) /*!< Peripheral secure base address */ + +/* Peripheral memory map - Secure */ +#define APB1PERIPH_BASE_S PERIPH_BASE_S +#define APB2PERIPH_BASE_S (PERIPH_BASE_S + 0x00010000UL) +#define AHB1PERIPH_BASE_S (PERIPH_BASE_S + 0x00020000UL) +#define AHB2PERIPH_BASE_S (PERIPH_BASE_S + 0x02020000UL) +#define APB3PERIPH_BASE_S (PERIPH_BASE_S + 0x04000000UL) +#define AHB3PERIPH_BASE_S (PERIPH_BASE_S + 0x04020000UL) +#define AHB4PERIPH_BASE_S (PERIPH_BASE_S + 0x06000000UL) + +/*!< APB1 secure peripherals */ +#define TIM2_BASE_S (APB1PERIPH_BASE_S + 0x0000UL) +#define TIM3_BASE_S (APB1PERIPH_BASE_S + 0x0400UL) +#define TIM4_BASE_S (APB1PERIPH_BASE_S + 0x0800UL) +#define TIM5_BASE_S (APB1PERIPH_BASE_S + 0x0C00UL) +#define TIM6_BASE_S (APB1PERIPH_BASE_S + 0x1000UL) +#define TIM7_BASE_S (APB1PERIPH_BASE_S + 0x1400UL) +#define TIM12_BASE_S (APB1PERIPH_BASE_S + 0x1800UL) +#define TIM13_BASE_S (APB1PERIPH_BASE_S + 0x1C00UL) +#define TIM14_BASE_S (APB1PERIPH_BASE_S + 0x2000UL) +#define WWDG_BASE_S (APB1PERIPH_BASE_S + 0x2C00UL) +#define IWDG_BASE_S (APB1PERIPH_BASE_S + 0x3000UL) +#define SPI2_BASE_S (APB1PERIPH_BASE_S + 0x3800UL) +#define SPI3_BASE_S (APB1PERIPH_BASE_S + 0x3C00UL) +#define USART2_BASE_S (APB1PERIPH_BASE_S + 0x4400UL) +#define USART3_BASE_S (APB1PERIPH_BASE_S + 0x4800UL) +#define UART4_BASE_S (APB1PERIPH_BASE_S + 0x4C00UL) +#define UART5_BASE_S (APB1PERIPH_BASE_S + 0x5000UL) +#define I2C1_BASE_S (APB1PERIPH_BASE_S + 0x5400UL) +#define I2C2_BASE_S (APB1PERIPH_BASE_S + 0x5800UL) +#define I3C1_BASE_S (APB1PERIPH_BASE_S + 0x5C00UL) +#define CRS_BASE_S (APB1PERIPH_BASE_S + 0x6000UL) +#define USART6_BASE_S (APB1PERIPH_BASE_S + 0x6400UL) +#define USART10_BASE_S (APB1PERIPH_BASE_S + 0x6800UL) +#define USART11_BASE_S (APB1PERIPH_BASE_S + 0x6C00UL) +#define CEC_BASE_S (APB1PERIPH_BASE_S + 0x7000UL) +#define UART7_BASE_S (APB1PERIPH_BASE_S + 0x7800UL) +#define UART8_BASE_S (APB1PERIPH_BASE_S + 0x7C00UL) +#define UART9_BASE_S (APB1PERIPH_BASE_S + 0x8000UL) +#define UART12_BASE_S (APB1PERIPH_BASE_S + 0x8400UL) +#define DTS_BASE_S (APB1PERIPH_BASE_S + 0x8C00UL) +#define LPTIM2_BASE_S (APB1PERIPH_BASE_S + 0x9400UL) +#define FDCAN1_BASE_S (APB1PERIPH_BASE_S + 0xA400UL) +#define FDCAN_CONFIG_BASE_S (APB1PERIPH_BASE_S + 0xA500UL) +#define SRAMCAN_BASE_S (APB1PERIPH_BASE_S + 0xAC00UL) +#define FDCAN2_BASE_S (APB1PERIPH_BASE_S + 0xA800UL) +#define UCPD1_BASE_S (APB1PERIPH_BASE_S + 0xDC00UL) + +/*!< APB2 Secure peripherals */ +#define TIM1_BASE_S (APB2PERIPH_BASE_S + 0x2C00UL) +#define SPI1_BASE_S (APB2PERIPH_BASE_S + 0x3000UL) +#define TIM8_BASE_S (APB2PERIPH_BASE_S + 0x3400UL) +#define USART1_BASE_S (APB2PERIPH_BASE_S + 0x3800UL) +#define TIM15_BASE_S (APB2PERIPH_BASE_S + 0x4000UL) +#define TIM16_BASE_S (APB2PERIPH_BASE_S + 0x4400UL) +#define TIM17_BASE_S (APB2PERIPH_BASE_S + 0x4800UL) +#define SPI4_BASE_S (APB2PERIPH_BASE_S + 0x4C00UL) +#define SPI6_BASE_S (APB2PERIPH_BASE_S + 0x5000UL) +#define SAI1_BASE_S (APB2PERIPH_BASE_S + 0x5400UL) +#define SAI1_Block_A_BASE_S (SAI1_BASE_S + 0x004UL) +#define SAI1_Block_B_BASE_S (SAI1_BASE_S + 0x024UL) +#define SAI2_BASE_S (APB2PERIPH_BASE_S + 0x5800UL) +#define SAI2_Block_A_BASE_S (SAI2_BASE_S + 0x004UL) +#define SAI2_Block_B_BASE_S (SAI2_BASE_S + 0x024UL) +#define USB_DRD_BASE_S (APB2PERIPH_BASE_S + 0x6000UL) +#define USB_DRD_PMAADDR_S (APB2PERIPH_BASE_S + 0x6400UL) + +/*!< AHB1 secure peripherals */ +#define GPDMA1_BASE_S AHB1PERIPH_BASE_S +#define GPDMA2_BASE_S (AHB1PERIPH_BASE_S + 0x01000UL) +#define FLASH_R_BASE_S (AHB1PERIPH_BASE_S + 0x02000UL) +#define CRC_BASE_S (AHB1PERIPH_BASE_S + 0x03000UL) +#define CORDIC_BASE_S (AHB1PERIPH_BASE_S + 0x03800UL) +#define FMAC_BASE_S (AHB1PERIPH_BASE_S + 0x03C00UL) +#define RAMCFG_BASE_S (AHB1PERIPH_BASE_S + 0x06000UL) +#define ETH_BASE_S (AHB1PERIPH_BASE_S + 0x8000UL) +#define ETH_MAC_BASE_S (ETH_BASE_S) +#define ICACHE_BASE_S (AHB1PERIPH_BASE_S + 0x10400UL) +#define DCACHE1_BASE_S (AHB1PERIPH_BASE_S + 0x11400UL) +#define GTZC_TZSC1_BASE_S (AHB1PERIPH_BASE_S + 0x12400UL) +#define GTZC_TZIC1_BASE_S (AHB1PERIPH_BASE_S + 0x12800UL) +#define GTZC_MPCBB1_BASE_S (AHB1PERIPH_BASE_S + 0x12C00UL) +#define GTZC_MPCBB2_BASE_S (AHB1PERIPH_BASE_S + 0x13000UL) +#define GTZC_MPCBB3_BASE_S (AHB1PERIPH_BASE_S + 0x13400UL) +#define BKPSRAM_BASE_S (AHB1PERIPH_BASE_S + 0x16400UL) + +#define GPDMA1_Channel0_BASE_S (GPDMA1_BASE_S + 0x0050UL) +#define GPDMA1_Channel1_BASE_S (GPDMA1_BASE_S + 0x00D0UL) +#define GPDMA1_Channel2_BASE_S (GPDMA1_BASE_S + 0x0150UL) +#define GPDMA1_Channel3_BASE_S (GPDMA1_BASE_S + 0x01D0UL) +#define GPDMA1_Channel4_BASE_S (GPDMA1_BASE_S + 0x0250UL) +#define GPDMA1_Channel5_BASE_S (GPDMA1_BASE_S + 0x02D0UL) +#define GPDMA1_Channel6_BASE_S (GPDMA1_BASE_S + 0x0350UL) +#define GPDMA1_Channel7_BASE_S (GPDMA1_BASE_S + 0x03D0UL) +#define GPDMA2_Channel0_BASE_S (GPDMA2_BASE_S + 0x0050UL) +#define GPDMA2_Channel1_BASE_S (GPDMA2_BASE_S + 0x00D0UL) +#define GPDMA2_Channel2_BASE_S (GPDMA2_BASE_S + 0x0150UL) +#define GPDMA2_Channel3_BASE_S (GPDMA2_BASE_S + 0x01D0UL) +#define GPDMA2_Channel4_BASE_S (GPDMA2_BASE_S + 0x0250UL) +#define GPDMA2_Channel5_BASE_S (GPDMA2_BASE_S + 0x02D0UL) +#define GPDMA2_Channel6_BASE_S (GPDMA2_BASE_S + 0x0350UL) +#define GPDMA2_Channel7_BASE_S (GPDMA2_BASE_S + 0x03D0UL) + +#define RAMCFG_SRAM1_BASE_S (RAMCFG_BASE_S) +#define RAMCFG_SRAM2_BASE_S (RAMCFG_BASE_S + 0x0040UL) +#define RAMCFG_SRAM3_BASE_S (RAMCFG_BASE_S + 0x0080UL) +#define RAMCFG_BKPRAM_BASE_S (RAMCFG_BASE_S + 0x0100UL) + +/*!< AHB2 secure peripherals */ +#define GPIOA_BASE_S (AHB2PERIPH_BASE_S + 0x00000UL) +#define GPIOB_BASE_S (AHB2PERIPH_BASE_S + 0x00400UL) +#define GPIOC_BASE_S (AHB2PERIPH_BASE_S + 0x00800UL) +#define GPIOD_BASE_S (AHB2PERIPH_BASE_S + 0x00C00UL) +#define GPIOE_BASE_S (AHB2PERIPH_BASE_S + 0x01000UL) +#define GPIOF_BASE_S (AHB2PERIPH_BASE_S + 0x01400UL) +#define GPIOG_BASE_S (AHB2PERIPH_BASE_S + 0x01800UL) +#define GPIOH_BASE_S (AHB2PERIPH_BASE_S + 0x01C00UL) +#define GPIOI_BASE_S (AHB2PERIPH_BASE_S + 0x02000UL) +#define ADC1_BASE_S (AHB2PERIPH_BASE_S + 0x08000UL) +#define ADC2_BASE_S (AHB2PERIPH_BASE_S + 0x08100UL) +#define ADC12_COMMON_BASE_S (AHB2PERIPH_BASE_S + 0x08300UL) +#define DAC1_BASE_S (AHB2PERIPH_BASE_S + 0x08400UL) +#define DCMI_BASE_S (AHB2PERIPH_BASE_S + 0x0C000UL) +#define PSSI_BASE_S (AHB2PERIPH_BASE_S + 0x0C400UL) +#define HASH_BASE_S (AHB2PERIPH_BASE_S + 0xA0400UL) +#define HASH_DIGEST_BASE_S (AHB2PERIPH_BASE_S + 0xA0710UL) +#define RNG_BASE_S (AHB2PERIPH_BASE_S + 0xA0800UL) + +/*!< APB3 secure peripherals */ +#define SBS_BASE_S (APB3PERIPH_BASE_S + 0x0400UL) +#define SPI5_BASE_S (APB3PERIPH_BASE_S + 0x2000UL) +#define LPUART1_BASE_S (APB3PERIPH_BASE_S + 0x2400UL) +#define I2C3_BASE_S (APB3PERIPH_BASE_S + 0x2800UL) +#define I2C4_BASE_S (APB3PERIPH_BASE_S + 0x2C00UL) +#define LPTIM1_BASE_S (APB3PERIPH_BASE_S + 0x4400UL) +#define LPTIM3_BASE_S (APB3PERIPH_BASE_S + 0x4800UL) +#define LPTIM4_BASE_S (APB3PERIPH_BASE_S + 0x4C00UL) +#define LPTIM5_BASE_S (APB3PERIPH_BASE_S + 0x5000UL) +#define LPTIM6_BASE_S (APB3PERIPH_BASE_S + 0x5400UL) +#define VREFBUF_BASE_S (APB3PERIPH_BASE_S + 0x7400UL) +#define RTC_BASE_S (APB3PERIPH_BASE_S + 0x7800UL) +#define TAMP_BASE_S (APB3PERIPH_BASE_S + 0x7C00UL) + +/*!< AHB3 secure peripherals */ +#define PWR_BASE_S (AHB3PERIPH_BASE_S + 0x0800UL) +#define RCC_BASE_S (AHB3PERIPH_BASE_S + 0x0C00UL) +#define EXTI_BASE_S (AHB3PERIPH_BASE_S + 0x2000UL) +#define DEBUG_BASE_S (AHB3PERIPH_BASE_S + 0x4000UL) + +/*!< AHB4 secure peripherals */ +#define SDMMC1_BASE_S (AHB4PERIPH_BASE_S + 0x8000UL) +#define DLYB_SDMMC1_BASE_S (AHB4PERIPH_BASE_S + 0x8400UL) +#define SDMMC2_BASE_S (AHB4PERIPH_BASE_S + 0x8C00UL) +#define DLYB_SDMMC2_BASE_S (AHB4PERIPH_BASE_S + 0x8800UL) + +#define FMC_R_BASE_S (AHB4PERIPH_BASE_S + 0x1000400UL) /*!< FMC control registers base address */ +#define OCTOSPI1_R_BASE_S (AHB4PERIPH_BASE_S + 0x1001400UL) /*!< OCTOSPI1 control registers base address */ +#define DLYB_OCTOSPI1_BASE_S (AHB4PERIPH_BASE_S + 0x0F000UL) + +/*!< FMC Banks Non secure registers base address */ +#define FMC_Bank1_R_BASE_S (FMC_R_BASE_S + 0x0000UL) +#define FMC_Bank1E_R_BASE_S (FMC_R_BASE_S + 0x0104UL) +#define FMC_Bank3_R_BASE_S (FMC_R_BASE_S + 0x0080UL) +#define FMC_Bank5_6_R_BASE_S (FMC_R_BASE_S + 0x0140UL) + +/* Debug MCU registers base address */ +#define DBGMCU_BASE (0x44024000UL) + +#define PACKAGE_BASE (0x08FFF80EUL) /*!< Package data register base address */ +#define UID_BASE (0x08FFF800UL) /*!< Unique device ID register base address */ +#define FLASHSIZE_BASE (0x08FFF80CUL) /*!< Flash size data register base address */ + + +/* Internal Flash OTP Area */ +#define FLASH_OTP_BASE (0x08FFF000UL) /*!< FLASH OTP (one-time programmable) base address */ +#define FLASH_OTP_SIZE (0x800U) /*!< 2048 bytes OTP (one-time programmable) */ + +/* Flash system Area */ +#define FLASH_SYSTEM_BASE_NS (0x0BF80000UL) /*!< FLASH System non-secure base address */ +#define FLASH_SYSTEM_BASE_S (0x0FF80000UL) /*!< FLASH System secure base address */ +#define FLASH_SYSTEM_SIZE (0x10000U) /*!< 64 Kbytes system Flash */ + +/* Internal Flash EDATA Area */ +#define FLASH_EDATA_BASE_NS (0x09000000UL) /*!< FLASH high-cycle data non-secure base address */ +#define FLASH_EDATA_BASE_S (0x0D000000UL) /*!< FLASH high-cycle data secure base address */ +#define FLASH_EDATA_SIZE (0x18000U) /*!< 96 KB of Flash high-cycle data */ + +/* Internal Flash OBK Area */ +#define FLASH_OBK_BASE_NS (0x0BFD0000UL) /*!< FLASH OBK (option byte keys) non-secure base address */ +#define FLASH_OBK_BASE_S (0x0FFD0000UL) /*!< FLASH OBK (option byte keys) secure base address */ +#define FLASH_OBK_SIZE (0x2000U) /*!< 8 KB of option byte keys */ +#define FLASH_OBK_HDPL0_SIZE (0x100U) /*!< 256 Bytes of HDPL1 option byte keys */ + +#define FLASH_OBK_HDPL1_BASE_NS (FLASH_OBK_BASE_NS + FLASH_OBK_HDPL0_SIZE) /*!< FLASH OBK HDPL1 non-secure base address */ +#define FLASH_OBK_HDPL1_BASE_S (FLASH_OBK_BASE_S + FLASH_OBK_HDPL0_SIZE) /*!< FLASH OBK HDPL1 secure base address */ +#define FLASH_OBK_HDPL1_SIZE (0x800U) /*!< 2 KB of HDPL1 option byte keys */ + +#define FLASH_OBK_HDPL2_BASE_NS (FLASH_OBK_HDPL1_BASE_NS + FLASH_OBK_HDPL1_SIZE) /*!< FLASH OBK HDPL2 non-secure base address */ +#define FLASH_OBK_HDPL2_BASE_S (FLASH_OBK_HDPL1_BASE_S + FLASH_OBK_HDPL1_SIZE) /*!< FLASH OBK HDPL2 secure base address */ +#define FLASH_OBK_HDPL2_SIZE (0x300U) /*!< 768 Bytes of HDPL2 option byte keys */ + +#define FLASH_OBK_HDPL3_BASE_NS (FLASH_OBK_HDPL2_BASE_NS + FLASH_OBK_HDPL2_SIZE) /*!< FLASH OBK HDPL3 non-secure base address */ +#define FLASH_OBK_HDPL3_BASE_S (FLASH_OBK_HDPL2_BASE_S + FLASH_OBK_HDPL2_SIZE) /*!< FLASH OBK HDPL3 secure base address */ +#define FLASH_OBK_HDPL3_SIZE (0x13F0U) /*!< 5104 Bytes HDPL3 option byte keys */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define FLASH_OBK_HDPL3S_BASE_NS (FLASH_OBK_HDPL3_BASE_NS) /*!< FLASH OBK HDPL3 non-secure base address */ +#define FLASH_OBK_HDPL3S_BASE_S (FLASH_OBK_HDPL3_BASE_S) /*!< FLASH OBK HDPL3 secure base address */ +#define FLASH_OBK_HDPL3S_SIZE (0x0C00U) /*!< 3072 Bytes of secure HDPL3 option byte keys */ + +#define FLASH_OBK_HDPL3NS_BASE_NS (FLASH_OBK_HDPL3_BASE_NS + FLASH_OBK_HDPL3S_SIZE) /*!< FLASH OBK HDPL3 non-secure base address */ +#define FLASH_OBK_HDPL3NS_BASE_S (FLASH_OBK_HDPL3_BASE_S + FLASH_OBK_HDPL3S_SIZE) /*!< FLASH OBK HDPL3 secure base address */ +#define FLASH_OBK_HDPL3NS_SIZE (FLASH_OBK_HDPL3_SIZE - FLASH_OBK_HDPL3S_SIZE) /*!< 2032 Bytes of non-secure HDPL3 option byte keys */ +#endif /* CMSE */ + +/*!< USB PMA SIZE */ +#define USB_DRD_PMA_SIZE (2048U) /*!< USB PMA Size 2Kbyte */ + +/*!< Root Secure Service Library */ +/************ RSSLIB SAU system Flash region definition constants *************/ +#define RSSLIB_SYS_FLASH_NS_PFUNC_START (0xBF9FB68UL) +#define RSSLIB_SYS_FLASH_NS_PFUNC_END (0xBF9FB84UL) + +/************ RSSLIB function return constants ********************************/ +#define RSSLIB_ERROR (0xF5F5F5F5UL) +#define RSSLIB_SUCCESS (0xEAEAEAEAUL) + +/*!< RSSLIB pointer function structure address definition */ +#define RSSLIB_PFUNC_BASE (0xBF9FB68UL) +#define RSSLIB_PFUNC ((RSSLIB_pFunc_TypeDef *)RSSLIB_PFUNC_BASE) + +/** + * @brief Prototype of RSSLIB Jump to HDP level2 Function + * @detail This function increments HDP level up to HDP level 2 + * Then it enables the MPU region corresponding the MPU index + * provided as input parameter. The Vector Table shall be located + * within this MPU region. + * Then it jumps to the reset handler present within the + * Vector table. The function does not return on successful execution. + * @param pointer on the vector table containing the reset handler the function + * jumps to. + * @param MPU region index containing the vector table + * jumps to. + * @retval RSSLIB_RSS_ERROR on error on input parameter, otherwise does not return. + */ +typedef uint32_t (*RSSLIB_S_JumpHDPlvl2_TypeDef)(uint32_t VectorTableAddr, uint32_t MPUIndex); + +/** + * @brief Prototype of RSSLIB Jump to HDP level3 Function + * @detail This function increments HDP level up to HDP level 3 + * Then it enables the MPU region corresponding the MPU index + * provided as input parameter. The Vector Table shall be located + * within this MPU region. + * Then it jumps to the reset handler present within the + * Vector table. The function does not return on successful execution. + * @param pointer on the vector table containing the reset handler the function + * jumps to. + * @param MPU region index containing the vector table + * jumps to. + * @retval RSSLIB_RSS_ERROR on error on input parameter, otherwise does not return. + */ +typedef uint32_t (*RSSLIB_S_JumpHDPlvl3_TypeDef)(uint32_t VectorTableAddr, uint32_t MPUIndex); + +/** + * @brief Prototype of RSSLIB Jump to HDP level3 Function + * @detail This function increments HDP level up to HDP level 3 + * Then it jumps to the non-secure reset handler present within the + * Vector table. The function does not return on successful execution. + * @param pointer on the vector table containing the reset handler the function + * jumps to. + * @retval RSSLIB_RSS_ERROR on error on input parameter, otherwise does not return. + */ +typedef uint32_t (*RSSLIB_S_JumpHDPlvl3NS_TypeDef)(uint32_t VectorTableAddr); + +/** + * @brief Input parameter definition of RSSLIB_DataProvisioning + */ +typedef struct +{ + uint32_t *pSource; /*!< Address of the Data to be provisioned, shall be in SRAM3 */ + uint32_t *pDestination; /*!< Address in OBKeys sections where to provision Data */ + uint32_t Size; /*!< Size in bytes of the Data to be provisioned*/ + uint32_t DoEncryption; /*!< Notifies RSSLIB_DataProvisioning to encrypt or not Data*/ + uint32_t Crc; /*!< CRC over full Data buffer and previous field in the structure*/ +} RSSLIB_DataProvisioningConf_t; + +/** + * @brief Prototype of RSSLIB Data Provisioning Function + * @detail This function write Data within OBKeys sections. + * @param pointer on the structure defining Data to be provisioned and where to + * provision them within OBKeys sections. + * @retval RSSLIB_RSS_ERROR on error on input parameter, otherwise does not return. + */ +typedef uint32_t (*RSSLIB_NSC_DataProvisioning_TypeDef)(RSSLIB_DataProvisioningConf_t *pConfig); + + +/** + * @brief RSSLib secure callable function pointer structure + */ +typedef struct +{ + __IM RSSLIB_S_JumpHDPlvl2_TypeDef JumpHDPLvl2; + __IM RSSLIB_S_JumpHDPlvl3_TypeDef JumpHDPLvl3; + __IM RSSLIB_S_JumpHDPlvl3NS_TypeDef JumpHDPLvl3NS; +} S_pFuncTypeDef; + +/** + * @brief RSSLib Non-secure callable function pointer structure + */ +typedef struct +{ + __IM RSSLIB_NSC_DataProvisioning_TypeDef DataProvisioning; +} NSC_pFuncTypeDef; + +/** + * @brief RSSLib function pointer structure + */ +typedef struct +{ + NSC_pFuncTypeDef NSC; + uint32_t RESERVED1[3]; + S_pFuncTypeDef S; +}RSSLIB_pFunc_TypeDef; + +/*!< Non Secure Service Library */ +/************ RSSLIB SAU system Flash region definition constants *************/ +#define NSSLIB_SYS_FLASH_NS_PFUNC_START (0xBF9FB6CUL) +#define NSSLIB_SYS_FLASH_NS_PFUNC_END (0xBF9FB74UL) + +/************ RSSLIB function return constants ********************************/ +#define NSSLIB_ERROR (0xF5F5F5F5UL) +#define NSSLIB_SUCCESS (0xEAEAEAEAUL) + +/*!< RSSLIB pointer function structure address definition */ +#define NSSLIB_PFUNC_BASE (0xBF9FB6CUL) +#define NSSLIB_PFUNC ((NSSLIB_pFunc_TypeDef *)NSSLIB_PFUNC_BASE) + +/** + * @brief Prototype of RSSLIB Jump to HDP level2 Function + * @detail This function increments HDP level up to HDP level 2 + * Then it enables the MPU region corresponding the MPU index + * provided as input parameter. The Vector Table shall be located + * within this MPU region. + * Then it jumps to the reset handler present within the + * Vector table. The function does not return on successful execution. + * @param pointer on the vector table containing the reset handler the function + * jumps to. + * @param MPU region index containing the vector table + * jumps to. + * @retval NSSLIB_RSS_ERROR on error on input parameter, otherwise does not return. + */ +typedef uint32_t (*NSSLIB_S_JumpHDPlvl2_TypeDef)(uint32_t VectorTableAddr, uint32_t MPUIndex); + +/** + * @brief Prototype of RSSLIB Jump to HDP level3 Function + * @detail This function increments HDP level up to HDP level 3 + * Then it enables the MPU region corresponding the MPU index + * provided as input parameter. The Vector Table shall be located + * within this MPU region. + * Then it jumps to the reset handler present within the + * Vector table. The function does not return on successful execution. + * @param pointer on the vector table containing the reset handler the function + * jumps to. + * @param MPU region index containing the vector table + * jumps to. + * @retval NSSLIB_RSS_ERROR on error on input parameter, otherwise does not return. + */ +typedef uint32_t (*NSSLIB_S_JumpHDPlvl3_TypeDef)(uint32_t VectorTableAddr, uint32_t MPUIndex); + +/** + * @brief RSSLib secure callable function pointer structure + */ +typedef struct +{ + __IM NSSLIB_S_JumpHDPlvl2_TypeDef JumpHDPLvl2; + __IM NSSLIB_S_JumpHDPlvl3_TypeDef JumpHDPLvl3; +} NSSLIB_pFunc_TypeDef; + + +/** @} */ /* End of group STM32H5xx_Peripheral_peripheralAddr */ + + +/* =========================================================================================================================== */ +/* ================ Peripheral declaration ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup STM32H5xx_Peripheral_declaration + * @{ + */ + +/*!< APB1 Non secure peripherals */ +#define TIM2_NS ((TIM_TypeDef *)TIM2_BASE_NS) +#define TIM3_NS ((TIM_TypeDef *)TIM3_BASE_NS) +#define TIM4_NS ((TIM_TypeDef *)TIM4_BASE_NS) +#define TIM5_NS ((TIM_TypeDef *)TIM5_BASE_NS) +#define TIM6_NS ((TIM_TypeDef *)TIM6_BASE_NS) +#define TIM7_NS ((TIM_TypeDef *)TIM7_BASE_NS) +#define TIM12_NS ((TIM_TypeDef *)TIM12_BASE_NS) +#define TIM13_NS ((TIM_TypeDef *)TIM13_BASE_NS) +#define TIM14_NS ((TIM_TypeDef *)TIM14_BASE_NS) +#define WWDG_NS ((WWDG_TypeDef *)WWDG_BASE_NS) +#define IWDG_NS ((IWDG_TypeDef *)IWDG_BASE_NS) +#define SPI2_NS ((SPI_TypeDef *)SPI2_BASE_NS) +#define SPI3_NS ((SPI_TypeDef *)SPI3_BASE_NS) +#define USART2_NS ((USART_TypeDef *)USART2_BASE_NS) +#define USART3_NS ((USART_TypeDef *)USART3_BASE_NS) +#define UART4_NS ((USART_TypeDef *)UART4_BASE_NS) +#define UART5_NS ((USART_TypeDef *)UART5_BASE_NS) +#define I2C1_NS ((I2C_TypeDef *)I2C1_BASE_NS) +#define I2C2_NS ((I2C_TypeDef *)I2C2_BASE_NS) +#define I3C1_NS ((I3C_TypeDef *)I3C1_BASE_NS) +#define CRS_NS ((CRS_TypeDef *)CRS_BASE_NS) +#define USART6_NS ((USART_TypeDef *)USART6_BASE_NS) +#define USART10_NS ((USART_TypeDef *)USART10_BASE_NS) +#define USART11_NS ((USART_TypeDef *)USART11_BASE_NS) +#define CEC_NS ((CEC_TypeDef *)CEC_BASE_NS) +#define UART7_NS ((USART_TypeDef *)UART7_BASE_NS) +#define UART8_NS ((USART_TypeDef *)UART8_BASE_NS) +#define UART9_NS ((USART_TypeDef *)UART9_BASE_NS) +#define UART12_NS ((USART_TypeDef *)UART12_BASE_NS) +#define DTS_NS ((DTS_TypeDef *)DTS_BASE_NS) +#define LPTIM2_NS ((LPTIM_TypeDef *)LPTIM2_BASE_NS) +#define FDCAN1_NS ((FDCAN_GlobalTypeDef *)FDCAN1_BASE_NS) +#define FDCAN_CONFIG_NS ((FDCAN_Config_TypeDef *)FDCAN_CONFIG_BASE_NS) +#define FDCAN2_NS ((FDCAN_GlobalTypeDef *)FDCAN2_BASE_NS) +#define UCPD1_NS ((UCPD_TypeDef *)UCPD1_BASE_NS) + +/*!< APB2 Non secure peripherals */ +#define TIM1_NS ((TIM_TypeDef *) TIM1_BASE_NS) +#define SPI1_NS ((SPI_TypeDef *) SPI1_BASE_NS) +#define TIM8_NS ((TIM_TypeDef *) TIM8_BASE_NS) +#define USART1_NS ((USART_TypeDef *) USART1_BASE_NS) +#define TIM15_NS ((TIM_TypeDef *) TIM15_BASE_NS) +#define TIM16_NS ((TIM_TypeDef *) TIM16_BASE_NS) +#define TIM17_NS ((TIM_TypeDef *) TIM17_BASE_NS) +#define SPI4_NS ((SPI_TypeDef *) SPI4_BASE_NS) +#define SPI6_NS ((SPI_TypeDef *) SPI6_BASE_NS) +#define SAI1_NS ((SAI_TypeDef *) SAI1_BASE_NS) +#define SAI1_Block_A_NS ((SAI_Block_TypeDef *)SAI1_Block_A_BASE_NS) +#define SAI1_Block_B_NS ((SAI_Block_TypeDef *)SAI1_Block_B_BASE_NS) +#define SAI2_NS ((SAI_TypeDef *) SAI2_BASE_NS) +#define SAI2_Block_A_NS ((SAI_Block_TypeDef *)SAI2_Block_A_BASE_NS) +#define SAI2_Block_B_NS ((SAI_Block_TypeDef *)SAI2_Block_B_BASE_NS) +#define USB_DRD_FS_NS ((USB_DRD_TypeDef *) USB_DRD_BASE_NS) +#define USB_DRD_PMA_BUFF_NS ((USB_DRD_PMABuffDescTypeDef *) USB_DRD_PMAADDR_NS) + +/*!< AHB1 Non secure peripherals */ +#define GPDMA1_NS ((DMA_TypeDef *) GPDMA1_BASE_NS) +#define GPDMA2_NS ((DMA_TypeDef *) GPDMA2_BASE_NS) +#define FLASH_NS ((FLASH_TypeDef *) FLASH_R_BASE_NS) +#define CRC_NS ((CRC_TypeDef *) CRC_BASE_NS) +#define CORDIC_NS ((CORDIC_TypeDef *) CORDIC_BASE_NS) +#define FMAC_NS ((FMAC_TypeDef *) FMAC_BASE_NS) +#define RAMCFG_SRAM1_NS ((RAMCFG_TypeDef *) RAMCFG_SRAM1_BASE_NS) +#define RAMCFG_SRAM2_NS ((RAMCFG_TypeDef *) RAMCFG_SRAM2_BASE_NS) +#define RAMCFG_SRAM3_NS ((RAMCFG_TypeDef *) RAMCFG_SRAM3_BASE_NS) +#define RAMCFG_BKPRAM_NS ((RAMCFG_TypeDef *) RAMCFG_BKPRAM_BASE_NS) +#define ETH_NS ((ETH_TypeDef *) ETH_BASE_NS) +#define ETH_MAC_NS ((ETH_TypeDef *) ETH_MAC_BASE_NS) +#define ICACHE_NS ((ICACHE_TypeDef *) ICACHE_BASE_NS) +#define DCACHE1_NS ((DCACHE_TypeDef *) DCACHE1_BASE_NS) +#define GTZC_TZSC1_NS ((GTZC_TZSC_TypeDef *) GTZC_TZSC1_BASE_NS) +#define GTZC_TZIC1_NS ((GTZC_TZIC_TypeDef *) GTZC_TZIC1_BASE_NS) +#define GTZC_MPCBB1_NS ((GTZC_MPCBB_TypeDef *) GTZC_MPCBB1_BASE_NS) +#define GTZC_MPCBB2_NS ((GTZC_MPCBB_TypeDef *) GTZC_MPCBB2_BASE_NS) +#define GTZC_MPCBB3_NS ((GTZC_MPCBB_TypeDef *) GTZC_MPCBB3_BASE_NS) +#define GPDMA1_Channel0_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel0_BASE_NS) +#define GPDMA1_Channel1_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel1_BASE_NS) +#define GPDMA1_Channel2_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel2_BASE_NS) +#define GPDMA1_Channel3_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel3_BASE_NS) +#define GPDMA1_Channel4_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel4_BASE_NS) +#define GPDMA1_Channel5_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel5_BASE_NS) +#define GPDMA1_Channel6_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel6_BASE_NS) +#define GPDMA1_Channel7_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel7_BASE_NS) +#define GPDMA2_Channel0_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel0_BASE_NS) +#define GPDMA2_Channel1_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel1_BASE_NS) +#define GPDMA2_Channel2_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel2_BASE_NS) +#define GPDMA2_Channel3_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel3_BASE_NS) +#define GPDMA2_Channel4_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel4_BASE_NS) +#define GPDMA2_Channel5_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel5_BASE_NS) +#define GPDMA2_Channel6_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel6_BASE_NS) +#define GPDMA2_Channel7_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel7_BASE_NS) + +/*!< AHB2 Non secure peripherals */ +#define GPIOA_NS ((GPIO_TypeDef *) GPIOA_BASE_NS) +#define GPIOB_NS ((GPIO_TypeDef *) GPIOB_BASE_NS) +#define GPIOC_NS ((GPIO_TypeDef *) GPIOC_BASE_NS) +#define GPIOD_NS ((GPIO_TypeDef *) GPIOD_BASE_NS) +#define GPIOE_NS ((GPIO_TypeDef *) GPIOE_BASE_NS) +#define GPIOF_NS ((GPIO_TypeDef *) GPIOF_BASE_NS) +#define GPIOG_NS ((GPIO_TypeDef *) GPIOG_BASE_NS) +#define GPIOH_NS ((GPIO_TypeDef *) GPIOH_BASE_NS) +#define GPIOI_NS ((GPIO_TypeDef *) GPIOI_BASE_NS) +#define ADC1_NS ((ADC_TypeDef *) ADC1_BASE_NS) +#define ADC2_NS ((ADC_TypeDef *) ADC2_BASE_NS) +#define ADC12_COMMON_NS ((ADC_Common_TypeDef *) ADC12_COMMON_BASE_NS) +#define DAC1_NS ((DAC_TypeDef *) DAC1_BASE_NS) +#define DCMI_NS ((DCMI_TypeDef *) DCMI_BASE_NS) +#define PSSI_NS ((PSSI_TypeDef *) PSSI_BASE_NS) +#define HASH_NS ((HASH_TypeDef *) HASH_BASE_NS) +#define HASH_DIGEST_NS ((HASH_DIGEST_TypeDef *) HASH_DIGEST_BASE_NS) +#define RNG_NS ((RNG_TypeDef *) RNG_BASE_NS) + + +/*!< APB3 Non secure peripherals */ +#define SBS_NS ((SBS_TypeDef *) SBS_BASE_NS) +#define SPI5_NS ((SPI_TypeDef *) SPI5_BASE_NS) +#define LPUART1_NS ((USART_TypeDef *) LPUART1_BASE_NS) +#define I2C3_NS ((I2C_TypeDef *) I2C3_BASE_NS) +#define I2C4_NS ((I2C_TypeDef *) I2C4_BASE_NS) +#define LPTIM1_NS ((LPTIM_TypeDef *) LPTIM1_BASE_NS) +#define LPTIM3_NS ((LPTIM_TypeDef *) LPTIM3_BASE_NS) +#define LPTIM4_NS ((LPTIM_TypeDef *) LPTIM4_BASE_NS) +#define LPTIM5_NS ((LPTIM_TypeDef *) LPTIM5_BASE_NS) +#define LPTIM6_NS ((LPTIM_TypeDef *) LPTIM6_BASE_NS) +#define VREFBUF_NS ((VREFBUF_TypeDef *) VREFBUF_BASE_NS) +#define RTC_NS ((RTC_TypeDef *) RTC_BASE_NS) +#define TAMP_NS ((TAMP_TypeDef *) TAMP_BASE_NS) + +/*!< AHB3 Non secure peripherals */ +#define PWR_NS ((PWR_TypeDef *) PWR_BASE_NS) +#define RCC_NS ((RCC_TypeDef *) RCC_BASE_NS) +#define EXTI_NS ((EXTI_TypeDef *) EXTI_BASE_NS) + +/*!< AHB4 Non secure peripherals */ +#define SDMMC1_NS ((SDMMC_TypeDef *) SDMMC1_BASE_NS) +#define DLYB_SDMMC1_NS ((DLYB_TypeDef *) DLYB_SDMMC1_BASE_NS) +#define SDMMC2_NS ((SDMMC_TypeDef *) SDMMC2_BASE_NS) +#define DLYB_SDMMC2_NS ((DLYB_TypeDef *) DLYB_SDMMC2_BASE_NS) + +#define OCTOSPI1_NS ((OCTOSPI_TypeDef *) OCTOSPI1_R_BASE_NS) +#define DLYB_OCTOSPI1_NS ((DLYB_TypeDef *) DLYB_OCTOSPI1_BASE_NS) + +/*!< FMC Banks Non secure registers base address */ +#define FMC_Bank1_R_NS ((FMC_Bank1_TypeDef *) FMC_Bank1_R_BASE_NS) +#define FMC_Bank1E_R_NS ((FMC_Bank1E_TypeDef *) FMC_Bank1E_R_BASE_NS) +#define FMC_Bank3_R_NS ((FMC_Bank3_TypeDef *) FMC_Bank3_R_BASE_NS) +#define FMC_Bank5_6_R_NS ((FMC_Bank5_6_TypeDef *) FMC_Bank5_6_R_BASE_NS) + +/*!< APB1 Secure peripherals */ +#define TIM2_S ((TIM_TypeDef *)TIM2_BASE_S) +#define TIM3_S ((TIM_TypeDef *)TIM3_BASE_S) +#define TIM4_S ((TIM_TypeDef *)TIM4_BASE_S) +#define TIM5_S ((TIM_TypeDef *)TIM5_BASE_S) +#define TIM6_S ((TIM_TypeDef *)TIM6_BASE_S) +#define TIM7_S ((TIM_TypeDef *)TIM7_BASE_S) +#define TIM12_S ((TIM_TypeDef *)TIM12_BASE_S) +#define TIM13_S ((TIM_TypeDef *)TIM13_BASE_S) +#define TIM14_S ((TIM_TypeDef *)TIM14_BASE_S) +#define WWDG_S ((WWDG_TypeDef *)WWDG_BASE_S) +#define IWDG_S ((IWDG_TypeDef *)IWDG_BASE_S) +#define SPI2_S ((SPI_TypeDef *)SPI2_BASE_S) +#define SPI3_S ((SPI_TypeDef *)SPI3_BASE_S) +#define USART2_S ((USART_TypeDef *)USART2_BASE_S) +#define USART3_S ((USART_TypeDef *)USART3_BASE_S) +#define UART4_S ((USART_TypeDef *)UART4_BASE_S) +#define UART5_S ((USART_TypeDef *)UART5_BASE_S) +#define I2C1_S ((I2C_TypeDef *)I2C1_BASE_S) +#define I2C2_S ((I2C_TypeDef *)I2C2_BASE_S) +#define I3C1_S ((I3C_TypeDef *)I3C1_BASE_S) +#define CRS_S ((CRS_TypeDef *)CRS_BASE_S) +#define USART6_S ((USART_TypeDef *)USART6_BASE_S) +#define USART10_S ((USART_TypeDef *)USART10_BASE_S) +#define USART11_S ((USART_TypeDef *)USART11_BASE_S) +#define CEC_S ((CEC_TypeDef *)CEC_BASE_S) +#define UART7_S ((USART_TypeDef *)UART7_BASE_S) +#define UART8_S ((USART_TypeDef *)UART8_BASE_S) +#define UART9_S ((USART_TypeDef *)UART9_BASE_S) +#define UART12_S ((USART_TypeDef *)UART12_BASE_S) +#define DTS_S ((DTS_TypeDef *)DTS_BASE_S) +#define LPTIM2_S ((LPTIM_TypeDef *)LPTIM2_BASE_S) +#define FDCAN1_S ((FDCAN_GlobalTypeDef *)FDCAN1_BASE_S) +#define FDCAN_CONFIG_S ((FDCAN_Config_TypeDef *)FDCAN_CONFIG_BASE_S) +#define FDCAN2_S ((FDCAN_GlobalTypeDef *)FDCAN2_BASE_S) +#define UCPD1_S ((UCPD_TypeDef *)UCPD1_BASE_S) + +/*!< APB2 secure peripherals */ +#define TIM1_S ((TIM_TypeDef *) TIM1_BASE_S) +#define SPI1_S ((SPI_TypeDef *) SPI1_BASE_S) +#define TIM8_S ((TIM_TypeDef *) TIM8_BASE_S) +#define USART1_S ((USART_TypeDef *) USART1_BASE_S) +#define TIM15_S ((TIM_TypeDef *) TIM15_BASE_S) +#define TIM16_S ((TIM_TypeDef *) TIM16_BASE_S) +#define TIM17_S ((TIM_TypeDef *) TIM17_BASE_S) +#define SPI4_S ((SPI_TypeDef *) SPI4_BASE_S) +#define SPI6_S ((SPI_TypeDef *) SPI6_BASE_S) +#define SAI1_S ((SAI_TypeDef *) SAI1_BASE_S) +#define SAI1_Block_A_S ((SAI_Block_TypeDef *)SAI1_Block_A_BASE_S) +#define SAI1_Block_B_S ((SAI_Block_TypeDef *)SAI1_Block_B_BASE_S) +#define SAI2_S ((SAI_TypeDef *) SAI2_BASE_S) +#define SAI2_Block_A_S ((SAI_Block_TypeDef *)SAI2_Block_A_BASE_S) +#define SAI2_Block_B_S ((SAI_Block_TypeDef *)SAI2_Block_B_BASE_S) +#define USB_DRD_FS_S ((USB_DRD_TypeDef *)USB_DRD_BASE_S) +#define USB_DRD_PMA_BUFF_S ((USB_DRD_PMABuffDescTypeDef *) USB_DRD_PMAADDR_S) + +/*!< AHB1 secure peripherals */ +#define GPDMA1_S ((DMA_TypeDef *) GPDMA1_BASE_S) +#define GPDMA2_S ((DMA_TypeDef *) GPDMA2_BASE_S) +#define FLASH_S ((FLASH_TypeDef *) FLASH_R_BASE_S) +#define CRC_S ((CRC_TypeDef *) CRC_BASE_S) +#define CORDIC_S ((CORDIC_TypeDef *) CORDIC_BASE_S) +#define FMAC_S ((FMAC_TypeDef *) FMAC_BASE_S) +#define RAMCFG_SRAM1_S ((RAMCFG_TypeDef *) RAMCFG_SRAM1_BASE_S) +#define RAMCFG_SRAM2_S ((RAMCFG_TypeDef *) RAMCFG_SRAM2_BASE_S) +#define RAMCFG_SRAM3_S ((RAMCFG_TypeDef *) RAMCFG_SRAM3_BASE_S) +#define RAMCFG_BKPRAM_S ((RAMCFG_TypeDef *) RAMCFG_BKPRAM_BASE_S) +#define ETH_S ((ETH_TypeDef *) ETH_BASE_S) +#define ETH_MAC_S ((ETH_TypeDef *) ETH_MAC_BASE_S) +#define ICACHE_S ((ICACHE_TypeDef *) ICACHE_BASE_S) +#define DCACHE1_S ((DCACHE_TypeDef *) DCACHE1_BASE_S) +#define GTZC_TZSC1_S ((GTZC_TZSC_TypeDef *) GTZC_TZSC1_BASE_S) +#define GTZC_TZIC1_S ((GTZC_TZIC_TypeDef *) GTZC_TZIC1_BASE_S) +#define GTZC_MPCBB1_S ((GTZC_MPCBB_TypeDef *) GTZC_MPCBB1_BASE_S) +#define GTZC_MPCBB2_S ((GTZC_MPCBB_TypeDef *) GTZC_MPCBB2_BASE_S) +#define GTZC_MPCBB3_S ((GTZC_MPCBB_TypeDef *) GTZC_MPCBB3_BASE_S) +#define GPDMA1_Channel0_S ((DMA_Channel_TypeDef *) GPDMA1_Channel0_BASE_S) +#define GPDMA1_Channel1_S ((DMA_Channel_TypeDef *) GPDMA1_Channel1_BASE_S) +#define GPDMA1_Channel2_S ((DMA_Channel_TypeDef *) GPDMA1_Channel2_BASE_S) +#define GPDMA1_Channel3_S ((DMA_Channel_TypeDef *) GPDMA1_Channel3_BASE_S) +#define GPDMA1_Channel4_S ((DMA_Channel_TypeDef *) GPDMA1_Channel4_BASE_S) +#define GPDMA1_Channel5_S ((DMA_Channel_TypeDef *) GPDMA1_Channel5_BASE_S) +#define GPDMA1_Channel6_S ((DMA_Channel_TypeDef *) GPDMA1_Channel6_BASE_S) +#define GPDMA1_Channel7_S ((DMA_Channel_TypeDef *) GPDMA1_Channel7_BASE_S) +#define GPDMA2_Channel0_S ((DMA_Channel_TypeDef *) GPDMA2_Channel0_BASE_S) +#define GPDMA2_Channel1_S ((DMA_Channel_TypeDef *) GPDMA2_Channel1_BASE_S) +#define GPDMA2_Channel2_S ((DMA_Channel_TypeDef *) GPDMA2_Channel2_BASE_S) +#define GPDMA2_Channel3_S ((DMA_Channel_TypeDef *) GPDMA2_Channel3_BASE_S) +#define GPDMA2_Channel4_S ((DMA_Channel_TypeDef *) GPDMA2_Channel4_BASE_S) +#define GPDMA2_Channel5_S ((DMA_Channel_TypeDef *) GPDMA2_Channel5_BASE_S) +#define GPDMA2_Channel6_S ((DMA_Channel_TypeDef *) GPDMA2_Channel6_BASE_S) +#define GPDMA2_Channel7_S ((DMA_Channel_TypeDef *) GPDMA2_Channel7_BASE_S) + + +/*!< AHB2 secure peripherals */ +#define GPIOA_S ((GPIO_TypeDef *) GPIOA_BASE_S) +#define GPIOB_S ((GPIO_TypeDef *) GPIOB_BASE_S) +#define GPIOC_S ((GPIO_TypeDef *) GPIOC_BASE_S) +#define GPIOD_S ((GPIO_TypeDef *) GPIOD_BASE_S) +#define GPIOE_S ((GPIO_TypeDef *) GPIOE_BASE_S) +#define GPIOF_S ((GPIO_TypeDef *) GPIOF_BASE_S) +#define GPIOG_S ((GPIO_TypeDef *) GPIOG_BASE_S) +#define GPIOH_S ((GPIO_TypeDef *) GPIOH_BASE_S) +#define GPIOI_S ((GPIO_TypeDef *) GPIOI_BASE_S) +#define ADC1_S ((ADC_TypeDef *) ADC1_BASE_S) +#define ADC2_S ((ADC_TypeDef *) ADC2_BASE_S) +#define ADC12_COMMON_S ((ADC_Common_TypeDef *) ADC12_COMMON_BASE_S) +#define DAC1_S ((DAC_TypeDef *) DAC1_BASE_S) +#define DCMI_S ((DCMI_TypeDef *) DCMI_BASE_S) +#define PSSI_S ((PSSI_TypeDef *) PSSI_BASE_S) +#define HASH_S ((HASH_TypeDef *) HASH_BASE_S) +#define HASH_DIGEST_S ((HASH_DIGEST_TypeDef *) HASH_DIGEST_BASE_S) +#define RNG_S ((RNG_TypeDef *) RNG_BASE_S) + +/*!< APB3 secure peripherals */ +#define SBS_S ((SBS_TypeDef *) SBS_BASE_S) +#define SPI5_S ((SPI_TypeDef *) SPI5_BASE_S) +#define LPUART1_S ((USART_TypeDef *) LPUART1_BASE_S) +#define I2C3_S ((I2C_TypeDef *) I2C3_BASE_S) +#define I2C4_S ((I2C_TypeDef *) I2C4_BASE_S) +#define LPTIM1_S ((LPTIM_TypeDef *) LPTIM1_BASE_S) +#define LPTIM3_S ((LPTIM_TypeDef *) LPTIM3_BASE_S) +#define LPTIM4_S ((LPTIM_TypeDef *) LPTIM4_BASE_S) +#define LPTIM5_S ((LPTIM_TypeDef *) LPTIM5_BASE_S) +#define LPTIM6_S ((LPTIM_TypeDef *) LPTIM6_BASE_S) +#define VREFBUF_S ((VREFBUF_TypeDef *) VREFBUF_BASE_S) +#define RTC_S ((RTC_TypeDef *) RTC_BASE_S) +#define TAMP_S ((TAMP_TypeDef *) TAMP_BASE_S) + +/*!< AHB3 Secure peripherals */ +#define PWR_S ((PWR_TypeDef *) PWR_BASE_S) +#define RCC_S ((RCC_TypeDef *) RCC_BASE_S) +#define EXTI_S ((EXTI_TypeDef *) EXTI_BASE_S) + +/*!< AHB4 secure peripherals */ +#define SDMMC1_S ((SDMMC_TypeDef *) SDMMC1_BASE_S) +#define DLYB_SDMMC1_S ((DLYB_TypeDef *) DLYB_SDMMC1_BASE_S) +#define SDMMC2_S ((SDMMC_TypeDef *) SDMMC2_BASE_S) +#define DLYB_SDMMC2_S ((DLYB_TypeDef *) DLYB_SDMMC2_BASE_S) + +#define FMC_Bank1_R_S ((FMC_Bank1_TypeDef *) FMC_Bank1_R_BASE_S) +#define FMC_Bank1E_R_S ((FMC_Bank1E_TypeDef *) FMC_Bank1E_R_BASE_S) +#define FMC_Bank3_R_S ((FMC_Bank3_TypeDef *) FMC_Bank3_R_BASE_S) +#define FMC_Bank5_6_R_S ((FMC_Bank5_6_TypeDef *) FMC_Bank5_6_R_BASE_S) + +#define OCTOSPI1_S ((OCTOSPI_TypeDef *) OCTOSPI1_R_BASE_S) +#define DLYB_OCTOSPI1_S ((DLYB_TypeDef *) DLYB_OCTOSPI1_BASE_S) + +#define DBGMCU ((DBGMCU_TypeDef *) DBGMCU_BASE) + +/*!< Memory & Instance aliases and base addresses for Non-Secure/Secure peripherals */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/*!< Memory base addresses for Secure peripherals */ +#define FLASH_BASE FLASH_BASE_S +#define FLASH_OBK_BASE FLASH_OBK_BASE_S +#define FLASH_EDATA_BASE FLASH_EDATA_BASE_S +#define FLASH_SYSTEM_BASE FLASH_SYSTEM_BASE_S +#define SRAM1_BASE SRAM1_BASE_S +#define SRAM2_BASE SRAM2_BASE_S +#define SRAM3_BASE SRAM3_BASE_S +#define BKPSRAM_BASE BKPSRAM_BASE_S +#define PERIPH_BASE PERIPH_BASE_S +#define APB1PERIPH_BASE APB1PERIPH_BASE_S +#define APB2PERIPH_BASE APB2PERIPH_BASE_S +#define APB3PERIPH_BASE APB3PERIPH_BASE_S +#define AHB1PERIPH_BASE AHB1PERIPH_BASE_S +#define AHB2PERIPH_BASE AHB2PERIPH_BASE_S +#define AHB3PERIPH_BASE AHB3PERIPH_BASE_S +#define AHB4PERIPH_BASE AHB4PERIPH_BASE_S + +/*!< Instance aliases and base addresses for Secure peripherals */ +#define CORDIC CORDIC_S +#define CORDIC_BASE CORDIC_BASE_S + +#define RCC RCC_S +#define RCC_BASE RCC_BASE_S + +#define DCMI DCMI_S +#define DCMI_BASE DCMI_BASE_S + +#define PSSI PSSI_S +#define PSSI_BASE PSSI_BASE_S + +#define DTS DTS_S +#define DTS_BASE DTS_BASE_S + +#define FLASH FLASH_S +#define FLASH_R_BASE FLASH_R_BASE_S + +#define FMAC FMAC_S +#define FMAC_BASE FMAC_BASE_S + +#define GPDMA1 GPDMA1_S +#define GPDMA1_BASE GPDMA1_BASE_S + +#define GPDMA1_Channel0 GPDMA1_Channel0_S +#define GPDMA1_Channel0_BASE GPDMA1_Channel0_BASE_S + +#define GPDMA1_Channel1 GPDMA1_Channel1_S +#define GPDMA1_Channel1_BASE GPDMA1_Channel1_BASE_S + +#define GPDMA1_Channel2 GPDMA1_Channel2_S +#define GPDMA1_Channel2_BASE GPDMA1_Channel2_BASE_S + +#define GPDMA1_Channel3 GPDMA1_Channel3_S +#define GPDMA1_Channel3_BASE GPDMA1_Channel3_BASE_S + +#define GPDMA1_Channel4 GPDMA1_Channel4_S +#define GPDMA1_Channel4_BASE GPDMA1_Channel4_BASE_S + +#define GPDMA1_Channel5 GPDMA1_Channel5_S +#define GPDMA1_Channel5_BASE GPDMA1_Channel5_BASE_S + +#define GPDMA1_Channel6 GPDMA1_Channel6_S +#define GPDMA1_Channel6_BASE GPDMA1_Channel6_BASE_S + +#define GPDMA1_Channel7 GPDMA1_Channel7_S +#define GPDMA1_Channel7_BASE GPDMA1_Channel7_BASE_S + +#define GPDMA2 GPDMA2_S +#define GPDMA2_BASE GPDMA2_BASE_S + +#define GPDMA2_Channel0 GPDMA2_Channel0_S +#define GPDMA2_Channel0_BASE GPDMA2_Channel0_BASE_S + +#define GPDMA2_Channel1 GPDMA2_Channel1_S +#define GPDMA2_Channel1_BASE GPDMA2_Channel1_BASE_S + +#define GPDMA2_Channel2 GPDMA2_Channel2_S +#define GPDMA2_Channel2_BASE GPDMA2_Channel2_BASE_S + +#define GPDMA2_Channel3 GPDMA2_Channel3_S +#define GPDMA2_Channel3_BASE GPDMA2_Channel3_BASE_S + +#define GPDMA2_Channel4 GPDMA2_Channel4_S +#define GPDMA2_Channel4_BASE GPDMA2_Channel4_BASE_S + +#define GPDMA2_Channel5 GPDMA2_Channel5_S +#define GPDMA2_Channel5_BASE GPDMA2_Channel5_BASE_S + +#define GPDMA2_Channel6 GPDMA2_Channel6_S +#define GPDMA2_Channel6_BASE GPDMA2_Channel6_BASE_S + +#define GPDMA2_Channel7 GPDMA2_Channel7_S +#define GPDMA2_Channel7_BASE GPDMA2_Channel7_BASE_S + +#define GPIOA GPIOA_S +#define GPIOA_BASE GPIOA_BASE_S + +#define GPIOB GPIOB_S +#define GPIOB_BASE GPIOB_BASE_S + +#define GPIOC GPIOC_S +#define GPIOC_BASE GPIOC_BASE_S + +#define GPIOD GPIOD_S +#define GPIOD_BASE GPIOD_BASE_S + +#define GPIOE GPIOE_S +#define GPIOE_BASE GPIOE_BASE_S + +#define GPIOF GPIOF_S +#define GPIOF_BASE GPIOF_BASE_S + +#define GPIOG GPIOG_S +#define GPIOG_BASE GPIOG_BASE_S + +#define GPIOH GPIOH_S +#define GPIOH_BASE GPIOH_BASE_S + +#define GPIOI GPIOI_S +#define GPIOI_BASE GPIOI_BASE_S + +#define PWR PWR_S +#define PWR_BASE PWR_BASE_S + +#define RAMCFG_SRAM1 RAMCFG_SRAM1_S +#define RAMCFG_SRAM1_BASE RAMCFG_SRAM1_BASE_S + +#define RAMCFG_SRAM2 RAMCFG_SRAM2_S +#define RAMCFG_SRAM2_BASE RAMCFG_SRAM2_BASE_S + +#define RAMCFG_SRAM3 RAMCFG_SRAM3_S +#define RAMCFG_SRAM3_BASE RAMCFG_SRAM3_BASE_S + +#define RAMCFG_BKPRAM RAMCFG_BKPRAM_S +#define RAMCFG_BKPRAM_BASE RAMCFG_BKPRAM_BASE_S + +#define EXTI EXTI_S +#define EXTI_BASE EXTI_BASE_S + +#define ICACHE ICACHE_S +#define ICACHE_BASE ICACHE_BASE_S + +#define DCACHE1 DCACHE1_S +#define DCACHE1_BASE DCACHE1_BASE_S + +#define GTZC_TZSC1 GTZC_TZSC1_S +#define GTZC_TZSC1_BASE GTZC_TZSC1_BASE_S + +#define GTZC_TZIC1 GTZC_TZIC1_S +#define GTZC_TZIC1_BASE GTZC_TZIC1_BASE_S + +#define GTZC_MPCBB1 GTZC_MPCBB1_S +#define GTZC_MPCBB1_BASE GTZC_MPCBB1_BASE_S + +#define GTZC_MPCBB2 GTZC_MPCBB2_S +#define GTZC_MPCBB2_BASE GTZC_MPCBB2_BASE_S + +#define GTZC_MPCBB3 GTZC_MPCBB3_S +#define GTZC_MPCBB3_BASE GTZC_MPCBB3_BASE_S + +#define RTC RTC_S +#define RTC_BASE RTC_BASE_S + +#define TAMP TAMP_S +#define TAMP_BASE TAMP_BASE_S + +#define TIM1 TIM1_S +#define TIM1_BASE TIM1_BASE_S + +#define TIM2 TIM2_S +#define TIM2_BASE TIM2_BASE_S + +#define TIM3 TIM3_S +#define TIM3_BASE TIM3_BASE_S + +#define TIM4 TIM4_S +#define TIM4_BASE TIM4_BASE_S + +#define TIM5 TIM5_S +#define TIM5_BASE TIM5_BASE_S + +#define TIM6 TIM6_S +#define TIM6_BASE TIM6_BASE_S + +#define TIM7 TIM7_S +#define TIM7_BASE TIM7_BASE_S + +#define TIM8 TIM8_S +#define TIM8_BASE TIM8_BASE_S + +#define TIM15 TIM15_S +#define TIM15_BASE TIM15_BASE_S + +#define TIM12 TIM12_S +#define TIM12_BASE TIM12_BASE_S + +#define TIM13 TIM13_S +#define TIM13_BASE TIM13_BASE_S + +#define TIM14 TIM14_S +#define TIM14_BASE TIM14_BASE_S + +#define TIM16 TIM16_S +#define TIM16_BASE TIM16_BASE_S + +#define TIM17 TIM17_S +#define TIM17_BASE TIM17_BASE_S + +#define WWDG WWDG_S +#define WWDG_BASE WWDG_BASE_S + +#define IWDG IWDG_S +#define IWDG_BASE IWDG_BASE_S + +#define SPI1 SPI1_S +#define SPI1_BASE SPI1_BASE_S + +#define SPI2 SPI2_S +#define SPI2_BASE SPI2_BASE_S + +#define SPI3 SPI3_S +#define SPI3_BASE SPI3_BASE_S + +#define SPI4 SPI4_S +#define SPI4_BASE SPI4_BASE_S + +#define SPI5 SPI5_S +#define SPI5_BASE SPI5_BASE_S + +#define SPI6 SPI6_S +#define SPI6_BASE SPI6_BASE_S + +#define USART1 USART1_S +#define USART1_BASE USART1_BASE_S + +#define USART2 USART2_S +#define USART2_BASE USART2_BASE_S + +#define USART3 USART3_S +#define USART3_BASE USART3_BASE_S + +#define UART4 UART4_S +#define UART4_BASE UART4_BASE_S + +#define UART5 UART5_S +#define UART5_BASE UART5_BASE_S + +#define USART6 USART6_S +#define USART6_BASE USART6_BASE_S + +#define UART7 UART7_S +#define UART7_BASE UART7_BASE_S + +#define UART8 UART8_S +#define UART8_BASE UART8_BASE_S + +#define UART9 UART9_S +#define UART9_BASE UART9_BASE_S + +#define USART10 USART10_S +#define USART10_BASE USART10_BASE_S + +#define USART11 USART11_S +#define USART11_BASE USART11_BASE_S + +#define UART12 UART12_S +#define UART12_BASE UART12_BASE_S + +#define CEC CEC_S +#define CEC_BASE CEC_BASE_S + +#define I2C1 I2C1_S +#define I2C1_BASE I2C1_BASE_S + +#define I2C2 I2C2_S +#define I2C2_BASE I2C2_BASE_S + +#define I2C3 I2C3_S +#define I2C3_BASE I2C3_BASE_S + +#define I2C4 I2C4_S +#define I2C4_BASE I2C4_BASE_S + +#define I3C1 I3C1_S +#define I3C1_BASE I3C1_BASE_S + +#define CRS CRS_S +#define CRS_BASE CRS_BASE_S + +#define FDCAN1 FDCAN1_S +#define FDCAN1_BASE FDCAN1_BASE_S + +#define FDCAN_CONFIG FDCAN_CONFIG_S +#define FDCAN_CONFIG_BASE FDCAN_CONFIG_BASE_S +#define SRAMCAN_BASE SRAMCAN_BASE_S + +#define FDCAN2 FDCAN2_S +#define FDCAN2_BASE FDCAN2_BASE_S + +#define DAC1 DAC1_S +#define DAC1_BASE DAC1_BASE_S + +#define LPTIM1 LPTIM1_S +#define LPTIM1_BASE LPTIM1_BASE_S + +#define LPTIM2 LPTIM2_S +#define LPTIM2_BASE LPTIM2_BASE_S + +#define LPTIM3 LPTIM3_S +#define LPTIM3_BASE LPTIM3_BASE_S + +#define LPTIM4 LPTIM4_S +#define LPTIM4_BASE LPTIM4_BASE_S + +#define LPTIM5 LPTIM5_S +#define LPTIM5_BASE LPTIM5_BASE_S + +#define LPTIM6 LPTIM6_S +#define LPTIM6_BASE LPTIM6_BASE_S + +#define LPUART1 LPUART1_S +#define LPUART1_BASE LPUART1_BASE_S + +#define UCPD1 UCPD1_S +#define UCPD1_BASE UCPD1_BASE_S + +#define SBS SBS_S +#define SBS_BASE SBS_BASE_S + +#define VREFBUF VREFBUF_S +#define VREFBUF_BASE VREFBUF_BASE_S + +#define SAI1 SAI1_S +#define SAI1_BASE SAI1_BASE_S + +#define SAI1_Block_A SAI1_Block_A_S +#define SAI1_Block_A_BASE SAI1_Block_A_BASE_S + +#define SAI1_Block_B SAI1_Block_B_S +#define SAI1_Block_B_BASE SAI1_Block_B_BASE_S + +#define SAI2 SAI2_S +#define SAI2_BASE SAI2_BASE_S + +#define SAI2_Block_A SAI2_Block_A_S +#define SAI2_Block_A_BASE SAI2_Block_A_BASE_S + +#define SAI2_Block_B SAI2_Block_B_S +#define SAI2_Block_B_BASE SAI2_Block_B_BASE_S + +#define USB_DRD_FS USB_DRD_FS_S +#define USB_DRD_BASE USB_DRD_BASE_S +#define USB_DRD_PMAADDR USB_DRD_PMAADDR_S +#define USB_DRD_PMA_BUFF USB_DRD_PMA_BUFF_S + +#define CRC CRC_S +#define CRC_BASE CRC_BASE_S + +#define ADC1 ADC1_S +#define ADC1_BASE ADC1_BASE_S + +#define ADC2 ADC2_S +#define ADC2_BASE ADC2_BASE_S + +#define ADC12_COMMON ADC12_COMMON_S +#define ADC12_COMMON_BASE ADC12_COMMON_BASE_S + +#define HASH HASH_S +#define HASH_BASE HASH_BASE_S + +#define HASH_DIGEST HASH_DIGEST_S +#define HASH_DIGEST_BASE HASH_DIGEST_BASE_S + +#define RNG RNG_S +#define RNG_BASE RNG_BASE_S + + +#define ETH ETH_S +#define ETH_BASE ETH_BASE_S +#define ETH_MAC ETH_MAC_S +#define ETH_MAC_BASE ETH_MAC_BASE_S + +#define SDMMC1 SDMMC1_S +#define SDMMC1_BASE SDMMC1_BASE_S + +#define SDMMC2 SDMMC2_S +#define SDMMC2_BASE SDMMC2_BASE_S + +#define FMC_Bank1_R FMC_Bank1_R_S +#define FMC_Bank1_R_BASE FMC_Bank1_R_BASE_S + +#define FMC_Bank1E_R FMC_Bank1E_R_S +#define FMC_Bank1E_R_BASE FMC_Bank1E_R_BASE_S + +#define FMC_Bank3_R FMC_Bank3_R_S +#define FMC_Bank3_R_BASE FMC_Bank3_R_BASE_S + +#define FMC_Bank5_6_R FMC_Bank5_6_R_S +#define FMC_Bank5_6_R_BASE FMC_Bank5_6_R_BASE_S + +#define OCTOSPI1 OCTOSPI1_S +#define OCTOSPI1_R_BASE OCTOSPI1_R_BASE_S + +#define DLYB_SDMMC1 DLYB_SDMMC1_S +#define DLYB_SDMMC1_BASE DLYB_SDMMC1_BASE_S + +#define DLYB_SDMMC2 DLYB_SDMMC2_S +#define DLYB_SDMMC2_BASE DLYB_SDMMC2_BASE_S + +#define DLYB_OCTOSPI1 DLYB_OCTOSPI1_S +#define DLYB_OCTOSPI1_BASE DLYB_OCTOSPI1_BASE_S + +#else + +/*!< Memory base addresses for Non secure peripherals */ +#define FLASH_BASE FLASH_BASE_NS +#define FLASH_OBK_BASE FLASH_OBK_BASE_NS +#define FLASH_EDATA_BASE FLASH_EDATA_BASE_NS +#define FLASH_SYSTEM_BASE FLASH_SYSTEM_BASE_NS + +#define SRAM1_BASE SRAM1_BASE_NS +#define SRAM2_BASE SRAM2_BASE_NS + +#define SRAM3_BASE SRAM3_BASE_NS +#define BKPSRAM_BASE BKPSRAM_BASE_NS + +#define PERIPH_BASE PERIPH_BASE_NS +#define APB1PERIPH_BASE APB1PERIPH_BASE_NS +#define APB2PERIPH_BASE APB2PERIPH_BASE_NS +#define APB3PERIPH_BASE APB3PERIPH_BASE_NS +#define AHB1PERIPH_BASE AHB1PERIPH_BASE_NS +#define AHB2PERIPH_BASE AHB2PERIPH_BASE_NS +#define AHB3PERIPH_BASE AHB3PERIPH_BASE_NS +#define AHB4PERIPH_BASE AHB4PERIPH_BASE_NS + +/*!< Instance aliases and base addresses for Non secure peripherals */ +#define CORDIC CORDIC_NS +#define CORDIC_BASE CORDIC_BASE_NS + +#define RCC RCC_NS +#define RCC_BASE RCC_BASE_NS + +#define DCMI DCMI_NS +#define DCMI_BASE DCMI_BASE_NS + +#define PSSI PSSI_NS +#define PSSI_BASE PSSI_BASE_NS + +#define DTS DTS_NS +#define DTS_BASE DTS_BASE_NS + +#define FLASH FLASH_NS +#define FLASH_R_BASE FLASH_R_BASE_NS + +#define FMAC FMAC_NS +#define FMAC_BASE FMAC_BASE_NS + +#define GPDMA1 GPDMA1_NS +#define GPDMA1_BASE GPDMA1_BASE_NS + +#define GPDMA1_Channel0 GPDMA1_Channel0_NS +#define GPDMA1_Channel0_BASE GPDMA1_Channel0_BASE_NS + +#define GPDMA1_Channel1 GPDMA1_Channel1_NS +#define GPDMA1_Channel1_BASE GPDMA1_Channel1_BASE_NS + +#define GPDMA1_Channel2 GPDMA1_Channel2_NS +#define GPDMA1_Channel2_BASE GPDMA1_Channel2_BASE_NS + +#define GPDMA1_Channel3 GPDMA1_Channel3_NS +#define GPDMA1_Channel3_BASE GPDMA1_Channel3_BASE_NS + +#define GPDMA1_Channel4 GPDMA1_Channel4_NS +#define GPDMA1_Channel4_BASE GPDMA1_Channel4_BASE_NS + +#define GPDMA1_Channel5 GPDMA1_Channel5_NS +#define GPDMA1_Channel5_BASE GPDMA1_Channel5_BASE_NS + +#define GPDMA1_Channel6 GPDMA1_Channel6_NS +#define GPDMA1_Channel6_BASE GPDMA1_Channel6_BASE_NS + +#define GPDMA1_Channel7 GPDMA1_Channel7_NS +#define GPDMA1_Channel7_BASE GPDMA1_Channel7_BASE_NS + +#define GPDMA2 GPDMA2_NS +#define GPDMA2_BASE GPDMA2_BASE_NS + +#define GPDMA2_Channel0 GPDMA2_Channel0_NS +#define GPDMA2_Channel0_BASE GPDMA2_Channel0_BASE_NS + +#define GPDMA2_Channel1 GPDMA2_Channel1_NS +#define GPDMA2_Channel1_BASE GPDMA2_Channel1_BASE_NS + +#define GPDMA2_Channel2 GPDMA2_Channel2_NS +#define GPDMA2_Channel2_BASE GPDMA2_Channel2_BASE_NS + +#define GPDMA2_Channel3 GPDMA2_Channel3_NS +#define GPDMA2_Channel3_BASE GPDMA2_Channel3_BASE_NS + +#define GPDMA2_Channel4 GPDMA2_Channel4_NS +#define GPDMA2_Channel4_BASE GPDMA2_Channel4_BASE_NS + +#define GPDMA2_Channel5 GPDMA2_Channel5_NS +#define GPDMA2_Channel5_BASE GPDMA2_Channel5_BASE_NS + +#define GPDMA2_Channel6 GPDMA2_Channel6_NS +#define GPDMA2_Channel6_BASE GPDMA2_Channel6_BASE_NS + +#define GPDMA2_Channel7 GPDMA2_Channel7_NS +#define GPDMA2_Channel7_BASE GPDMA2_Channel7_BASE_NS + +#define GPIOA GPIOA_NS +#define GPIOA_BASE GPIOA_BASE_NS + +#define GPIOB GPIOB_NS +#define GPIOB_BASE GPIOB_BASE_NS + +#define GPIOC GPIOC_NS +#define GPIOC_BASE GPIOC_BASE_NS + +#define GPIOD GPIOD_NS +#define GPIOD_BASE GPIOD_BASE_NS + +#define GPIOE GPIOE_NS +#define GPIOE_BASE GPIOE_BASE_NS + +#define GPIOF GPIOF_NS +#define GPIOF_BASE GPIOF_BASE_NS + +#define GPIOG GPIOG_NS +#define GPIOG_BASE GPIOG_BASE_NS + +#define GPIOH GPIOH_NS +#define GPIOH_BASE GPIOH_BASE_NS + +#define GPIOI GPIOI_NS +#define GPIOI_BASE GPIOI_BASE_NS + +#define PWR PWR_NS +#define PWR_BASE PWR_BASE_NS + +#define RAMCFG_SRAM1 RAMCFG_SRAM1_NS +#define RAMCFG_SRAM1_BASE RAMCFG_SRAM1_BASE_NS + +#define RAMCFG_SRAM2 RAMCFG_SRAM2_NS +#define RAMCFG_SRAM2_BASE RAMCFG_SRAM2_BASE_NS + +#define RAMCFG_SRAM3 RAMCFG_SRAM3_NS +#define RAMCFG_SRAM3_BASE RAMCFG_SRAM3_BASE_NS + +#define RAMCFG_BKPRAM RAMCFG_BKPRAM_NS +#define RAMCFG_BKPRAM_BASE RAMCFG_BKPRAM_BASE_NS + +#define EXTI EXTI_NS +#define EXTI_BASE EXTI_BASE_NS + +#define ICACHE ICACHE_NS +#define ICACHE_BASE ICACHE_BASE_NS + +#define DCACHE1 DCACHE1_NS +#define DCACHE1_BASE DCACHE1_BASE_NS + +#define GTZC_TZSC1 GTZC_TZSC1_NS +#define GTZC_TZSC1_BASE GTZC_TZSC1_BASE_NS + +#define GTZC_TZIC1 GTZC_TZIC1_NS +#define GTZC_TZIC1_BASE GTZC_TZIC1_BASE_NS + +#define GTZC_MPCBB1 GTZC_MPCBB1_NS +#define GTZC_MPCBB1_BASE GTZC_MPCBB1_BASE_NS + +#define GTZC_MPCBB2 GTZC_MPCBB2_NS +#define GTZC_MPCBB2_BASE GTZC_MPCBB2_BASE_NS + +#define GTZC_MPCBB3 GTZC_MPCBB3_NS +#define GTZC_MPCBB3_BASE GTZC_MPCBB3_BASE_NS + +#define RTC RTC_NS +#define RTC_BASE RTC_BASE_NS + +#define TAMP TAMP_NS +#define TAMP_BASE TAMP_BASE_NS + +#define TIM1 TIM1_NS +#define TIM1_BASE TIM1_BASE_NS + +#define TIM2 TIM2_NS +#define TIM2_BASE TIM2_BASE_NS + +#define TIM3 TIM3_NS +#define TIM3_BASE TIM3_BASE_NS + +#define TIM4 TIM4_NS +#define TIM4_BASE TIM4_BASE_NS + +#define TIM5 TIM5_NS +#define TIM5_BASE TIM5_BASE_NS + +#define TIM6 TIM6_NS +#define TIM6_BASE TIM6_BASE_NS + +#define TIM7 TIM7_NS +#define TIM7_BASE TIM7_BASE_NS + +#define TIM8 TIM8_NS +#define TIM8_BASE TIM8_BASE_NS + +#define TIM12 TIM12_NS +#define TIM12_BASE TIM12_BASE_NS + +#define TIM13 TIM13_NS +#define TIM13_BASE TIM13_BASE_NS + +#define TIM14 TIM14_NS +#define TIM14_BASE TIM14_BASE_NS + +#define TIM15 TIM15_NS +#define TIM15_BASE TIM15_BASE_NS + +#define TIM16 TIM16_NS +#define TIM16_BASE TIM16_BASE_NS + +#define TIM17 TIM17_NS +#define TIM17_BASE TIM17_BASE_NS + +#define WWDG WWDG_NS +#define WWDG_BASE WWDG_BASE_NS + +#define IWDG IWDG_NS +#define IWDG_BASE IWDG_BASE_NS + +#define SPI1 SPI1_NS +#define SPI1_BASE SPI1_BASE_NS + +#define SPI2 SPI2_NS +#define SPI2_BASE SPI2_BASE_NS + +#define SPI3 SPI3_NS +#define SPI3_BASE SPI3_BASE_NS + +#define SPI4 SPI4_NS +#define SPI4_BASE SPI4_BASE_NS + +#define SPI5 SPI5_NS +#define SPI5_BASE SPI5_BASE_NS + +#define SPI6 SPI6_NS +#define SPI6_BASE SPI6_BASE_NS + +#define USART1 USART1_NS +#define USART1_BASE USART1_BASE_NS + +#define USART2 USART2_NS +#define USART2_BASE USART2_BASE_NS + +#define USART3 USART3_NS +#define USART3_BASE USART3_BASE_NS + +#define UART4 UART4_NS +#define UART4_BASE UART4_BASE_NS + +#define UART5 UART5_NS +#define UART5_BASE UART5_BASE_NS + +#define USART6 USART6_NS +#define USART6_BASE USART6_BASE_NS + +#define UART7 UART7_NS +#define UART7_BASE UART7_BASE_NS + +#define UART8 UART8_NS +#define UART8_BASE UART8_BASE_NS + +#define UART9 UART9_NS +#define UART9_BASE UART9_BASE_NS + +#define USART10 USART10_NS +#define USART10_BASE USART10_BASE_NS + +#define USART11 USART11_NS +#define USART11_BASE USART11_BASE_NS + +#define UART12 UART12_NS +#define UART12_BASE UART12_BASE_NS + +#define CEC CEC_NS +#define CEC_BASE CEC_BASE_NS + +#define I2C1 I2C1_NS +#define I2C1_BASE I2C1_BASE_NS + +#define I2C2 I2C2_NS +#define I2C2_BASE I2C2_BASE_NS + +#define I2C3 I2C3_NS +#define I2C3_BASE I2C3_BASE_NS + +#define I2C4 I2C4_NS +#define I2C4_BASE I2C4_BASE_NS + +#define I3C1 I3C1_NS +#define I3C1_BASE I3C1_BASE_NS + +#define CRS CRS_NS +#define CRS_BASE CRS_BASE_NS + +#define FDCAN1 FDCAN1_NS +#define FDCAN1_BASE FDCAN1_BASE_NS + +#define FDCAN_CONFIG FDCAN_CONFIG_NS +#define FDCAN_CONFIG_BASE FDCAN_CONFIG_BASE_NS +#define SRAMCAN_BASE SRAMCAN_BASE_NS + +#define FDCAN2 FDCAN2_NS +#define FDCAN2_BASE FDCAN2_BASE_NS + +#define DAC1 DAC1_NS +#define DAC1_BASE DAC1_BASE_NS + +#define LPTIM1 LPTIM1_NS +#define LPTIM1_BASE LPTIM1_BASE_NS + +#define LPTIM2 LPTIM2_NS +#define LPTIM2_BASE LPTIM2_BASE_NS + +#define LPTIM3 LPTIM3_NS +#define LPTIM3_BASE LPTIM3_BASE_NS + +#define LPTIM4 LPTIM4_NS +#define LPTIM4_BASE LPTIM4_BASE_NS + +#define LPTIM5 LPTIM5_NS +#define LPTIM5_BASE LPTIM5_BASE_NS + +#define LPTIM6 LPTIM6_NS +#define LPTIM6_BASE LPTIM6_BASE_NS + +#define LPUART1 LPUART1_NS +#define LPUART1_BASE LPUART1_BASE_NS + +#define UCPD1 UCPD1_NS +#define UCPD1_BASE UCPD1_BASE_NS + +#define SBS SBS_NS +#define SBS_BASE SBS_BASE_NS + +#define VREFBUF VREFBUF_NS +#define VREFBUF_BASE VREFBUF_BASE_NS + +#define SAI1 SAI1_NS +#define SAI1_BASE SAI1_BASE_NS + +#define SAI1_Block_A SAI1_Block_A_NS +#define SAI1_Block_A_BASE SAI1_Block_A_BASE_NS + +#define SAI1_Block_B SAI1_Block_B_NS +#define SAI1_Block_B_BASE SAI1_Block_B_BASE_NS + +#define SAI2 SAI2_NS +#define SAI2_BASE SAI2_BASE_NS + +#define SAI2_Block_A SAI2_Block_A_NS +#define SAI2_Block_A_BASE SAI2_Block_A_BASE_NS + +#define SAI2_Block_B SAI2_Block_B_NS +#define SAI2_Block_B_BASE SAI2_Block_B_BASE_NS + +#define USB_DRD_FS USB_DRD_FS_NS +#define USB_DRD_BASE USB_DRD_BASE_NS +#define USB_DRD_PMAADDR USB_DRD_PMAADDR_NS +#define USB_DRD_PMA_BUFF USB_DRD_PMA_BUFF_NS + +#define CRC CRC_NS +#define CRC_BASE CRC_BASE_NS + +#define ADC1 ADC1_NS +#define ADC1_BASE ADC1_BASE_NS + +#define ADC2 ADC2_NS +#define ADC2_BASE ADC2_BASE_NS + +#define ADC12_COMMON ADC12_COMMON_NS +#define ADC12_COMMON_BASE ADC12_COMMON_BASE_NS + +#define HASH HASH_NS +#define HASH_BASE HASH_BASE_NS + +#define HASH_DIGEST HASH_DIGEST_NS +#define HASH_DIGEST_BASE HASH_DIGEST_BASE_NS + +#define RNG RNG_NS +#define RNG_BASE RNG_BASE_NS + + +#define ETH ETH_NS +#define ETH_BASE ETH_BASE_NS +#define ETH_MAC ETH_MAC_NS +#define ETH_MAC_BASE ETH_MAC_BASE_NS + +#define SDMMC1 SDMMC1_NS +#define SDMMC1_BASE SDMMC1_BASE_NS + +#define SDMMC2 SDMMC2_NS +#define SDMMC2_BASE SDMMC2_BASE_NS + +#define FMC_Bank1_R FMC_Bank1_R_NS +#define FMC_Bank1_R_BASE FMC_Bank1_R_BASE_NS + +#define FMC_Bank1E_R FMC_Bank1E_R_NS +#define FMC_Bank1E_R_BASE FMC_Bank1E_R_BASE_NS + +#define FMC_Bank3_R FMC_Bank3_R_NS +#define FMC_Bank3_R_BASE FMC_Bank3_R_BASE_NS + +#define FMC_Bank5_6_R FMC_Bank5_6_R_NS +#define FMC_Bank5_6_R_BASE FMC_Bank5_6_R_BASE_NS + +#define OCTOSPI1 OCTOSPI1_NS +#define OCTOSPI1_R_BASE OCTOSPI1_R_BASE_NS + +#define DLYB_SDMMC1 DLYB_SDMMC1_NS +#define DLYB_SDMMC1_BASE DLYB_SDMMC1_BASE_NS + +#define DLYB_SDMMC2 DLYB_SDMMC2_NS +#define DLYB_SDMMC2_BASE DLYB_SDMMC2_BASE_NS + +#define DLYB_OCTOSPI1 DLYB_OCTOSPI1_NS +#define DLYB_OCTOSPI1_BASE DLYB_OCTOSPI1_BASE_NS + +#endif + + +/******************************************************************************/ +/* */ +/* Analog to Digital Converter */ +/* */ +/******************************************************************************/ +#define ADC_MULTIMODE_SUPPORT /*!< ADC feature available only on specific devices: multimode available on devices with several ADC instances */ +/******************** Bit definition for ADC_ISR register *******************/ +#define ADC_ISR_ADRDY_Pos (0U) +#define ADC_ISR_ADRDY_Msk (0x1UL << ADC_ISR_ADRDY_Pos) /*!< 0x00000001 */ +#define ADC_ISR_ADRDY ADC_ISR_ADRDY_Msk /*!< ADC ready flag */ +#define ADC_ISR_EOSMP_Pos (1U) +#define ADC_ISR_EOSMP_Msk (0x1UL << ADC_ISR_EOSMP_Pos) /*!< 0x00000002 */ +#define ADC_ISR_EOSMP ADC_ISR_EOSMP_Msk /*!< ADC group regular end of sampling flag */ +#define ADC_ISR_EOC_Pos (2U) +#define ADC_ISR_EOC_Msk (0x1UL << ADC_ISR_EOC_Pos) /*!< 0x00000004 */ +#define ADC_ISR_EOC ADC_ISR_EOC_Msk /*!< ADC group regular end of unitary conversion flag */ +#define ADC_ISR_EOS_Pos (3U) +#define ADC_ISR_EOS_Msk (0x1UL << ADC_ISR_EOS_Pos) /*!< 0x00000008 */ +#define ADC_ISR_EOS ADC_ISR_EOS_Msk /*!< ADC group regular end of sequence conversions flag */ +#define ADC_ISR_OVR_Pos (4U) +#define ADC_ISR_OVR_Msk (0x1UL << ADC_ISR_OVR_Pos) /*!< 0x00000010 */ +#define ADC_ISR_OVR ADC_ISR_OVR_Msk /*!< ADC group regular overrun flag */ +#define ADC_ISR_JEOC_Pos (5U) +#define ADC_ISR_JEOC_Msk (0x1UL << ADC_ISR_JEOC_Pos) /*!< 0x00000020 */ +#define ADC_ISR_JEOC ADC_ISR_JEOC_Msk /*!< ADC group injected end of unitary conversion flag */ +#define ADC_ISR_JEOS_Pos (6U) +#define ADC_ISR_JEOS_Msk (0x1UL << ADC_ISR_JEOS_Pos) /*!< 0x00000040 */ +#define ADC_ISR_JEOS ADC_ISR_JEOS_Msk /*!< ADC group injected end of sequence conversions flag */ +#define ADC_ISR_AWD1_Pos (7U) +#define ADC_ISR_AWD1_Msk (0x1UL << ADC_ISR_AWD1_Pos) /*!< 0x00000080 */ +#define ADC_ISR_AWD1 ADC_ISR_AWD1_Msk /*!< ADC analog watchdog 1 flag */ +#define ADC_ISR_AWD2_Pos (8U) +#define ADC_ISR_AWD2_Msk (0x1UL << ADC_ISR_AWD2_Pos) /*!< 0x00000100 */ +#define ADC_ISR_AWD2 ADC_ISR_AWD2_Msk /*!< ADC analog watchdog 2 flag */ +#define ADC_ISR_AWD3_Pos (9U) +#define ADC_ISR_AWD3_Msk (0x1UL << ADC_ISR_AWD3_Pos) /*!< 0x00000200 */ +#define ADC_ISR_AWD3 ADC_ISR_AWD3_Msk /*!< ADC analog watchdog 3 flag */ +#define ADC_ISR_JQOVF_Pos (10U) +#define ADC_ISR_JQOVF_Msk (0x1UL << ADC_ISR_JQOVF_Pos) /*!< 0x00000400 */ +#define ADC_ISR_JQOVF ADC_ISR_JQOVF_Msk /*!< ADC group injected contexts queue overflow flag */ + +/******************** Bit definition for ADC_IER register *******************/ +#define ADC_IER_ADRDYIE_Pos (0U) +#define ADC_IER_ADRDYIE_Msk (0x1UL << ADC_IER_ADRDYIE_Pos) /*!< 0x00000001 */ +#define ADC_IER_ADRDYIE ADC_IER_ADRDYIE_Msk /*!< ADC ready interrupt */ +#define ADC_IER_EOSMPIE_Pos (1U) +#define ADC_IER_EOSMPIE_Msk (0x1UL << ADC_IER_EOSMPIE_Pos) /*!< 0x00000002 */ +#define ADC_IER_EOSMPIE ADC_IER_EOSMPIE_Msk /*!< ADC group regular end of sampling interrupt */ +#define ADC_IER_EOCIE_Pos (2U) +#define ADC_IER_EOCIE_Msk (0x1UL << ADC_IER_EOCIE_Pos) /*!< 0x00000004 */ +#define ADC_IER_EOCIE ADC_IER_EOCIE_Msk /*!< ADC group regular end of unitary conversion interrupt */ +#define ADC_IER_EOSIE_Pos (3U) +#define ADC_IER_EOSIE_Msk (0x1UL << ADC_IER_EOSIE_Pos) /*!< 0x00000008 */ +#define ADC_IER_EOSIE ADC_IER_EOSIE_Msk /*!< ADC group regular end of sequence conversions interrupt */ +#define ADC_IER_OVRIE_Pos (4U) +#define ADC_IER_OVRIE_Msk (0x1UL << ADC_IER_OVRIE_Pos) /*!< 0x00000010 */ +#define ADC_IER_OVRIE ADC_IER_OVRIE_Msk /*!< ADC group regular overrun interrupt */ +#define ADC_IER_JEOCIE_Pos (5U) +#define ADC_IER_JEOCIE_Msk (0x1UL << ADC_IER_JEOCIE_Pos) /*!< 0x00000020 */ +#define ADC_IER_JEOCIE ADC_IER_JEOCIE_Msk /*!< ADC group injected end of unitary conversion interrupt */ +#define ADC_IER_JEOSIE_Pos (6U) +#define ADC_IER_JEOSIE_Msk (0x1UL << ADC_IER_JEOSIE_Pos) /*!< 0x00000040 */ +#define ADC_IER_JEOSIE ADC_IER_JEOSIE_Msk /*!< ADC group injected end of sequence conversions interrupt */ +#define ADC_IER_AWD1IE_Pos (7U) +#define ADC_IER_AWD1IE_Msk (0x1UL << ADC_IER_AWD1IE_Pos) /*!< 0x00000080 */ +#define ADC_IER_AWD1IE ADC_IER_AWD1IE_Msk /*!< ADC analog watchdog 1 interrupt */ +#define ADC_IER_AWD2IE_Pos (8U) +#define ADC_IER_AWD2IE_Msk (0x1UL << ADC_IER_AWD2IE_Pos) /*!< 0x00000100 */ +#define ADC_IER_AWD2IE ADC_IER_AWD2IE_Msk /*!< ADC analog watchdog 2 interrupt */ +#define ADC_IER_AWD3IE_Pos (9U) +#define ADC_IER_AWD3IE_Msk (0x1UL << ADC_IER_AWD3IE_Pos) /*!< 0x00000200 */ +#define ADC_IER_AWD3IE ADC_IER_AWD3IE_Msk /*!< ADC analog watchdog 3 interrupt */ +#define ADC_IER_JQOVFIE_Pos (10U) +#define ADC_IER_JQOVFIE_Msk (0x1UL << ADC_IER_JQOVFIE_Pos) /*!< 0x00000400 */ +#define ADC_IER_JQOVFIE ADC_IER_JQOVFIE_Msk /*!< ADC group injected contexts queue overflow interrupt */ + +/******************** Bit definition for ADC_CR register ********************/ +#define ADC_CR_ADEN_Pos (0U) +#define ADC_CR_ADEN_Msk (0x1UL << ADC_CR_ADEN_Pos) /*!< 0x00000001 */ +#define ADC_CR_ADEN ADC_CR_ADEN_Msk /*!< ADC enable */ +#define ADC_CR_ADDIS_Pos (1U) +#define ADC_CR_ADDIS_Msk (0x1UL << ADC_CR_ADDIS_Pos) /*!< 0x00000002 */ +#define ADC_CR_ADDIS ADC_CR_ADDIS_Msk /*!< ADC disable */ +#define ADC_CR_ADSTART_Pos (2U) +#define ADC_CR_ADSTART_Msk (0x1UL << ADC_CR_ADSTART_Pos) /*!< 0x00000004 */ +#define ADC_CR_ADSTART ADC_CR_ADSTART_Msk /*!< ADC group regular conversion start */ +#define ADC_CR_JADSTART_Pos (3U) +#define ADC_CR_JADSTART_Msk (0x1UL << ADC_CR_JADSTART_Pos) /*!< 0x00000008 */ +#define ADC_CR_JADSTART ADC_CR_JADSTART_Msk /*!< ADC group injected conversion start */ +#define ADC_CR_ADSTP_Pos (4U) +#define ADC_CR_ADSTP_Msk (0x1UL << ADC_CR_ADSTP_Pos) /*!< 0x00000010 */ +#define ADC_CR_ADSTP ADC_CR_ADSTP_Msk /*!< ADC group regular conversion stop */ +#define ADC_CR_JADSTP_Pos (5U) +#define ADC_CR_JADSTP_Msk (0x1UL << ADC_CR_JADSTP_Pos) /*!< 0x00000020 */ +#define ADC_CR_JADSTP ADC_CR_JADSTP_Msk /*!< ADC group injected conversion stop */ +#define ADC_CR_ADVREGEN_Pos (28U) +#define ADC_CR_ADVREGEN_Msk (0x1UL << ADC_CR_ADVREGEN_Pos) /*!< 0x10000000 */ +#define ADC_CR_ADVREGEN ADC_CR_ADVREGEN_Msk /*!< ADC voltage regulator enable */ +#define ADC_CR_DEEPPWD_Pos (29U) +#define ADC_CR_DEEPPWD_Msk (0x1UL << ADC_CR_DEEPPWD_Pos) /*!< 0x20000000 */ +#define ADC_CR_DEEPPWD ADC_CR_DEEPPWD_Msk /*!< ADC deep power down enable */ +#define ADC_CR_ADCALDIF_Pos (30U) +#define ADC_CR_ADCALDIF_Msk (0x1UL << ADC_CR_ADCALDIF_Pos) /*!< 0x40000000 */ +#define ADC_CR_ADCALDIF ADC_CR_ADCALDIF_Msk /*!< ADC differential mode for calibration */ +#define ADC_CR_ADCAL_Pos (31U) +#define ADC_CR_ADCAL_Msk (0x1UL << ADC_CR_ADCAL_Pos) /*!< 0x80000000 */ +#define ADC_CR_ADCAL ADC_CR_ADCAL_Msk /*!< ADC calibration */ + +/******************** Bit definition for ADC_CFGR register ******************/ +#define ADC_CFGR_DMAEN_Pos (0U) +#define ADC_CFGR_DMAEN_Msk (0x1UL << ADC_CFGR_DMAEN_Pos) /*!< 0x00000001 */ +#define ADC_CFGR_DMAEN ADC_CFGR_DMAEN_Msk /*!< ADC DMA transfer enable */ +#define ADC_CFGR_DMACFG_Pos (1U) +#define ADC_CFGR_DMACFG_Msk (0x1UL << ADC_CFGR_DMACFG_Pos) /*!< 0x00000002 */ +#define ADC_CFGR_DMACFG ADC_CFGR_DMACFG_Msk /*!< ADC DMA transfer configuration */ + +#define ADC_CFGR_RES_Pos (3U) +#define ADC_CFGR_RES_Msk (0x3UL << ADC_CFGR_RES_Pos) /*!< 0x00000018 */ +#define ADC_CFGR_RES ADC_CFGR_RES_Msk /*!< ADC data resolution */ +#define ADC_CFGR_RES_0 (0x1UL << ADC_CFGR_RES_Pos) /*!< 0x00000008 */ +#define ADC_CFGR_RES_1 (0x2UL << ADC_CFGR_RES_Pos) /*!< 0x00000010 */ + +#define ADC_CFGR_EXTSEL_Pos (5U) +#define ADC_CFGR_EXTSEL_Msk (0x1FUL << ADC_CFGR_EXTSEL_Pos) /*!< 0x000003E0 */ +#define ADC_CFGR_EXTSEL ADC_CFGR_EXTSEL_Msk /*!< ADC group regular external trigger source */ +#define ADC_CFGR_EXTSEL_0 (0x1UL << ADC_CFGR_EXTSEL_Pos) /*!< 0x00000020 */ +#define ADC_CFGR_EXTSEL_1 (0x2UL << ADC_CFGR_EXTSEL_Pos) /*!< 0x00000040 */ +#define ADC_CFGR_EXTSEL_2 (0x4UL << ADC_CFGR_EXTSEL_Pos) /*!< 0x00000080 */ +#define ADC_CFGR_EXTSEL_3 (0x8UL << ADC_CFGR_EXTSEL_Pos) /*!< 0x00000100 */ +#define ADC_CFGR_EXTSEL_4 (0x10UL << ADC_CFGR_EXTSEL_Pos) /*!< 0x00000200 */ + +#define ADC_CFGR_EXTEN_Pos (10U) +#define ADC_CFGR_EXTEN_Msk (0x3UL << ADC_CFGR_EXTEN_Pos) /*!< 0x00000C00 */ +#define ADC_CFGR_EXTEN ADC_CFGR_EXTEN_Msk /*!< ADC group regular external trigger polarity */ +#define ADC_CFGR_EXTEN_0 (0x1UL << ADC_CFGR_EXTEN_Pos) /*!< 0x00000400 */ +#define ADC_CFGR_EXTEN_1 (0x2UL << ADC_CFGR_EXTEN_Pos) /*!< 0x00000800 */ + +#define ADC_CFGR_OVRMOD_Pos (12U) +#define ADC_CFGR_OVRMOD_Msk (0x1UL << ADC_CFGR_OVRMOD_Pos) /*!< 0x00001000 */ +#define ADC_CFGR_OVRMOD ADC_CFGR_OVRMOD_Msk /*!< ADC group regular overrun configuration */ +#define ADC_CFGR_CONT_Pos (13U) +#define ADC_CFGR_CONT_Msk (0x1UL << ADC_CFGR_CONT_Pos) /*!< 0x00002000 */ +#define ADC_CFGR_CONT ADC_CFGR_CONT_Msk /*!< ADC group regular continuous conversion mode */ +#define ADC_CFGR_AUTDLY_Pos (14U) +#define ADC_CFGR_AUTDLY_Msk (0x1UL << ADC_CFGR_AUTDLY_Pos) /*!< 0x00004000 */ +#define ADC_CFGR_AUTDLY ADC_CFGR_AUTDLY_Msk /*!< ADC low power auto wait */ +#define ADC_CFGR_ALIGN_Pos (15U) +#define ADC_CFGR_ALIGN_Msk (0x1UL << ADC_CFGR_ALIGN_Pos) /*!< 0x00008000 */ +#define ADC_CFGR_ALIGN ADC_CFGR_ALIGN_Msk /*!< ADC data alignment */ +#define ADC_CFGR_DISCEN_Pos (16U) +#define ADC_CFGR_DISCEN_Msk (0x1UL << ADC_CFGR_DISCEN_Pos) /*!< 0x00010000 */ +#define ADC_CFGR_DISCEN ADC_CFGR_DISCEN_Msk /*!< ADC group regular sequencer discontinuous mode */ + +#define ADC_CFGR_DISCNUM_Pos (17U) +#define ADC_CFGR_DISCNUM_Msk (0x7UL << ADC_CFGR_DISCNUM_Pos) /*!< 0x000E0000 */ +#define ADC_CFGR_DISCNUM ADC_CFGR_DISCNUM_Msk /*!< ADC group regular sequencer discontinuous number of ranks */ +#define ADC_CFGR_DISCNUM_0 (0x1UL << ADC_CFGR_DISCNUM_Pos) /*!< 0x00020000 */ +#define ADC_CFGR_DISCNUM_1 (0x2UL << ADC_CFGR_DISCNUM_Pos) /*!< 0x00040000 */ +#define ADC_CFGR_DISCNUM_2 (0x4UL << ADC_CFGR_DISCNUM_Pos) /*!< 0x00080000 */ + +#define ADC_CFGR_JDISCEN_Pos (20U) +#define ADC_CFGR_JDISCEN_Msk (0x1UL << ADC_CFGR_JDISCEN_Pos) /*!< 0x00100000 */ +#define ADC_CFGR_JDISCEN ADC_CFGR_JDISCEN_Msk /*!< ADC group injected sequencer discontinuous mode */ +#define ADC_CFGR_JQM_Pos (21U) +#define ADC_CFGR_JQM_Msk (0x1UL << ADC_CFGR_JQM_Pos) /*!< 0x00200000 */ +#define ADC_CFGR_JQM ADC_CFGR_JQM_Msk /*!< ADC group injected contexts queue mode */ +#define ADC_CFGR_AWD1SGL_Pos (22U) +#define ADC_CFGR_AWD1SGL_Msk (0x1UL << ADC_CFGR_AWD1SGL_Pos) /*!< 0x00400000 */ +#define ADC_CFGR_AWD1SGL ADC_CFGR_AWD1SGL_Msk /*!< ADC analog watchdog 1 monitoring a single channel or all channels */ +#define ADC_CFGR_AWD1EN_Pos (23U) +#define ADC_CFGR_AWD1EN_Msk (0x1UL << ADC_CFGR_AWD1EN_Pos) /*!< 0x00800000 */ +#define ADC_CFGR_AWD1EN ADC_CFGR_AWD1EN_Msk /*!< ADC analog watchdog 1 enable on scope ADC group regular */ +#define ADC_CFGR_JAWD1EN_Pos (24U) +#define ADC_CFGR_JAWD1EN_Msk (0x1UL << ADC_CFGR_JAWD1EN_Pos) /*!< 0x01000000 */ +#define ADC_CFGR_JAWD1EN ADC_CFGR_JAWD1EN_Msk /*!< ADC analog watchdog 1 enable on scope ADC group injected */ +#define ADC_CFGR_JAUTO_Pos (25U) +#define ADC_CFGR_JAUTO_Msk (0x1UL << ADC_CFGR_JAUTO_Pos) /*!< 0x02000000 */ +#define ADC_CFGR_JAUTO ADC_CFGR_JAUTO_Msk /*!< ADC group injected automatic trigger mode */ + +#define ADC_CFGR_AWD1CH_Pos (26U) +#define ADC_CFGR_AWD1CH_Msk (0x1FUL << ADC_CFGR_AWD1CH_Pos) /*!< 0x7C000000 */ +#define ADC_CFGR_AWD1CH ADC_CFGR_AWD1CH_Msk /*!< ADC analog watchdog 1 monitored channel selection */ +#define ADC_CFGR_AWD1CH_0 (0x01UL << ADC_CFGR_AWD1CH_Pos) /*!< 0x04000000 */ +#define ADC_CFGR_AWD1CH_1 (0x02UL << ADC_CFGR_AWD1CH_Pos) /*!< 0x08000000 */ +#define ADC_CFGR_AWD1CH_2 (0x04UL << ADC_CFGR_AWD1CH_Pos) /*!< 0x10000000 */ +#define ADC_CFGR_AWD1CH_3 (0x08UL << ADC_CFGR_AWD1CH_Pos) /*!< 0x20000000 */ +#define ADC_CFGR_AWD1CH_4 (0x10UL << ADC_CFGR_AWD1CH_Pos) /*!< 0x40000000 */ + +#define ADC_CFGR_JQDIS_Pos (31U) +#define ADC_CFGR_JQDIS_Msk (0x1UL << ADC_CFGR_JQDIS_Pos) /*!< 0x80000000 */ +#define ADC_CFGR_JQDIS ADC_CFGR_JQDIS_Msk /*!< ADC group injected contexts queue disable */ + +/******************** Bit definition for ADC_CFGR2 register *****************/ +#define ADC_CFGR2_ROVSE_Pos (0U) +#define ADC_CFGR2_ROVSE_Msk (0x1UL << ADC_CFGR2_ROVSE_Pos) /*!< 0x00000001 */ +#define ADC_CFGR2_ROVSE ADC_CFGR2_ROVSE_Msk /*!< ADC oversampler enable on scope ADC group regular */ +#define ADC_CFGR2_JOVSE_Pos (1U) +#define ADC_CFGR2_JOVSE_Msk (0x1UL << ADC_CFGR2_JOVSE_Pos) /*!< 0x00000002 */ +#define ADC_CFGR2_JOVSE ADC_CFGR2_JOVSE_Msk /*!< ADC oversampler enable on scope ADC group injected */ + +#define ADC_CFGR2_OVSR_Pos (2U) +#define ADC_CFGR2_OVSR_Msk (0x7UL << ADC_CFGR2_OVSR_Pos) /*!< 0x0000001C */ +#define ADC_CFGR2_OVSR ADC_CFGR2_OVSR_Msk /*!< ADC oversampling ratio */ +#define ADC_CFGR2_OVSR_0 (0x1UL << ADC_CFGR2_OVSR_Pos) /*!< 0x00000004 */ +#define ADC_CFGR2_OVSR_1 (0x2UL << ADC_CFGR2_OVSR_Pos) /*!< 0x00000008 */ +#define ADC_CFGR2_OVSR_2 (0x4UL << ADC_CFGR2_OVSR_Pos) /*!< 0x00000010 */ + +#define ADC_CFGR2_OVSS_Pos (5U) +#define ADC_CFGR2_OVSS_Msk (0xFUL << ADC_CFGR2_OVSS_Pos) /*!< 0x000001E0 */ +#define ADC_CFGR2_OVSS ADC_CFGR2_OVSS_Msk /*!< ADC oversampling shift */ +#define ADC_CFGR2_OVSS_0 (0x1UL << ADC_CFGR2_OVSS_Pos) /*!< 0x00000020 */ +#define ADC_CFGR2_OVSS_1 (0x2UL << ADC_CFGR2_OVSS_Pos) /*!< 0x00000040 */ +#define ADC_CFGR2_OVSS_2 (0x4UL << ADC_CFGR2_OVSS_Pos) /*!< 0x00000080 */ +#define ADC_CFGR2_OVSS_3 (0x8UL << ADC_CFGR2_OVSS_Pos) /*!< 0x00000100 */ + +#define ADC_CFGR2_TROVS_Pos (9U) +#define ADC_CFGR2_TROVS_Msk (0x1UL << ADC_CFGR2_TROVS_Pos) /*!< 0x00000200 */ +#define ADC_CFGR2_TROVS ADC_CFGR2_TROVS_Msk /*!< ADC oversampling discontinuous mode (triggered mode) for ADC group regular */ +#define ADC_CFGR2_ROVSM_Pos (10U) +#define ADC_CFGR2_ROVSM_Msk (0x1UL << ADC_CFGR2_ROVSM_Pos) /*!< 0x00000400 */ +#define ADC_CFGR2_ROVSM ADC_CFGR2_ROVSM_Msk /*!< ADC oversampling mode managing interlaced conversions of ADC group regular and group injected */ + +#define ADC_CFGR2_GCOMP_Pos (16U) +#define ADC_CFGR2_GCOMP_Msk (0x1UL << ADC_CFGR2_GCOMP_Pos) /*!< 0x00010000 */ +#define ADC_CFGR2_GCOMP ADC_CFGR2_GCOMP_Msk /*!< ADC Gain Compensation mode */ + +#define ADC_CFGR2_SWTRIG_Pos (25U) +#define ADC_CFGR2_SWTRIG_Msk (0x1UL << ADC_CFGR2_SWTRIG_Pos) /*!< 0x02000000 */ +#define ADC_CFGR2_SWTRIG ADC_CFGR2_SWTRIG_Msk /*!< ADC Software Trigger Bit for Sample time control trigger mode */ +#define ADC_CFGR2_BULB_Pos (26U) +#define ADC_CFGR2_BULB_Msk (0x1UL << ADC_CFGR2_BULB_Pos) /*!< 0x04000000 */ +#define ADC_CFGR2_BULB ADC_CFGR2_BULB_Msk /*!< ADC Bulb sampling mode */ +#define ADC_CFGR2_SMPTRIG_Pos (27U) +#define ADC_CFGR2_SMPTRIG_Msk (0x1UL << ADC_CFGR2_SMPTRIG_Pos) /*!< 0x08000000 */ +#define ADC_CFGR2_SMPTRIG ADC_CFGR2_SMPTRIG_Msk /*!< ADC Sample Time Control Trigger mode */ + +#define ADC_CFGR2_LFTRIG_Pos (29U) +#define ADC_CFGR2_LFTRIG_Msk (0x1UL << ADC_CFGR2_LFTRIG_Pos) /*!< 0x20000000 */ +#define ADC_CFGR2_LFTRIG ADC_CFGR2_LFTRIG_Msk /*!< ADC Low Frequency Trigger */ + +/******************** Bit definition for ADC_SMPR1 register *****************/ +#define ADC_SMPR1_SMP0_Pos (0U) +#define ADC_SMPR1_SMP0_Msk (0x7UL << ADC_SMPR1_SMP0_Pos) /*!< 0x00000007 */ +#define ADC_SMPR1_SMP0 ADC_SMPR1_SMP0_Msk /*!< ADC channel 0 sampling time selection */ +#define ADC_SMPR1_SMP0_0 (0x1UL << ADC_SMPR1_SMP0_Pos) /*!< 0x00000001 */ +#define ADC_SMPR1_SMP0_1 (0x2UL << ADC_SMPR1_SMP0_Pos) /*!< 0x00000002 */ +#define ADC_SMPR1_SMP0_2 (0x4UL << ADC_SMPR1_SMP0_Pos) /*!< 0x00000004 */ + +#define ADC_SMPR1_SMP1_Pos (3U) +#define ADC_SMPR1_SMP1_Msk (0x7UL << ADC_SMPR1_SMP1_Pos) /*!< 0x00000038 */ +#define ADC_SMPR1_SMP1 ADC_SMPR1_SMP1_Msk /*!< ADC channel 1 sampling time selection */ +#define ADC_SMPR1_SMP1_0 (0x1UL << ADC_SMPR1_SMP1_Pos) /*!< 0x00000008 */ +#define ADC_SMPR1_SMP1_1 (0x2UL << ADC_SMPR1_SMP1_Pos) /*!< 0x00000010 */ +#define ADC_SMPR1_SMP1_2 (0x4UL << ADC_SMPR1_SMP1_Pos) /*!< 0x00000020 */ + +#define ADC_SMPR1_SMP2_Pos (6U) +#define ADC_SMPR1_SMP2_Msk (0x7UL << ADC_SMPR1_SMP2_Pos) /*!< 0x000001C0 */ +#define ADC_SMPR1_SMP2 ADC_SMPR1_SMP2_Msk /*!< ADC channel 2 sampling time selection */ +#define ADC_SMPR1_SMP2_0 (0x1UL << ADC_SMPR1_SMP2_Pos) /*!< 0x00000040 */ +#define ADC_SMPR1_SMP2_1 (0x2UL << ADC_SMPR1_SMP2_Pos) /*!< 0x00000080 */ +#define ADC_SMPR1_SMP2_2 (0x4UL << ADC_SMPR1_SMP2_Pos) /*!< 0x00000100 */ + +#define ADC_SMPR1_SMP3_Pos (9U) +#define ADC_SMPR1_SMP3_Msk (0x7UL << ADC_SMPR1_SMP3_Pos) /*!< 0x00000E00 */ +#define ADC_SMPR1_SMP3 ADC_SMPR1_SMP3_Msk /*!< ADC channel 3 sampling time selection */ +#define ADC_SMPR1_SMP3_0 (0x1UL << ADC_SMPR1_SMP3_Pos) /*!< 0x00000200 */ +#define ADC_SMPR1_SMP3_1 (0x2UL << ADC_SMPR1_SMP3_Pos) /*!< 0x00000400 */ +#define ADC_SMPR1_SMP3_2 (0x4UL << ADC_SMPR1_SMP3_Pos) /*!< 0x00000800 */ + +#define ADC_SMPR1_SMP4_Pos (12U) +#define ADC_SMPR1_SMP4_Msk (0x7UL << ADC_SMPR1_SMP4_Pos) /*!< 0x00007000 */ +#define ADC_SMPR1_SMP4 ADC_SMPR1_SMP4_Msk /*!< ADC channel 4 sampling time selection */ +#define ADC_SMPR1_SMP4_0 (0x1UL << ADC_SMPR1_SMP4_Pos) /*!< 0x00001000 */ +#define ADC_SMPR1_SMP4_1 (0x2UL << ADC_SMPR1_SMP4_Pos) /*!< 0x00002000 */ +#define ADC_SMPR1_SMP4_2 (0x4UL << ADC_SMPR1_SMP4_Pos) /*!< 0x00004000 */ + +#define ADC_SMPR1_SMP5_Pos (15U) +#define ADC_SMPR1_SMP5_Msk (0x7UL << ADC_SMPR1_SMP5_Pos) /*!< 0x00038000 */ +#define ADC_SMPR1_SMP5 ADC_SMPR1_SMP5_Msk /*!< ADC channel 5 sampling time selection */ +#define ADC_SMPR1_SMP5_0 (0x1UL << ADC_SMPR1_SMP5_Pos) /*!< 0x00008000 */ +#define ADC_SMPR1_SMP5_1 (0x2UL << ADC_SMPR1_SMP5_Pos) /*!< 0x00010000 */ +#define ADC_SMPR1_SMP5_2 (0x4UL << ADC_SMPR1_SMP5_Pos) /*!< 0x00020000 */ + +#define ADC_SMPR1_SMP6_Pos (18U) +#define ADC_SMPR1_SMP6_Msk (0x7UL << ADC_SMPR1_SMP6_Pos) /*!< 0x001C0000 */ +#define ADC_SMPR1_SMP6 ADC_SMPR1_SMP6_Msk /*!< ADC channel 6 sampling time selection */ +#define ADC_SMPR1_SMP6_0 (0x1UL << ADC_SMPR1_SMP6_Pos) /*!< 0x00040000 */ +#define ADC_SMPR1_SMP6_1 (0x2UL << ADC_SMPR1_SMP6_Pos) /*!< 0x00080000 */ +#define ADC_SMPR1_SMP6_2 (0x4UL << ADC_SMPR1_SMP6_Pos) /*!< 0x00100000 */ + +#define ADC_SMPR1_SMP7_Pos (21U) +#define ADC_SMPR1_SMP7_Msk (0x7UL << ADC_SMPR1_SMP7_Pos) /*!< 0x00E00000 */ +#define ADC_SMPR1_SMP7 ADC_SMPR1_SMP7_Msk /*!< ADC channel 7 sampling time selection */ +#define ADC_SMPR1_SMP7_0 (0x1UL << ADC_SMPR1_SMP7_Pos) /*!< 0x00200000 */ +#define ADC_SMPR1_SMP7_1 (0x2UL << ADC_SMPR1_SMP7_Pos) /*!< 0x00400000 */ +#define ADC_SMPR1_SMP7_2 (0x4UL << ADC_SMPR1_SMP7_Pos) /*!< 0x00800000 */ + +#define ADC_SMPR1_SMP8_Pos (24U) +#define ADC_SMPR1_SMP8_Msk (0x7UL << ADC_SMPR1_SMP8_Pos) /*!< 0x07000000 */ +#define ADC_SMPR1_SMP8 ADC_SMPR1_SMP8_Msk /*!< ADC channel 8 sampling time selection */ +#define ADC_SMPR1_SMP8_0 (0x1UL << ADC_SMPR1_SMP8_Pos) /*!< 0x01000000 */ +#define ADC_SMPR1_SMP8_1 (0x2UL << ADC_SMPR1_SMP8_Pos) /*!< 0x02000000 */ +#define ADC_SMPR1_SMP8_2 (0x4UL << ADC_SMPR1_SMP8_Pos) /*!< 0x04000000 */ + +#define ADC_SMPR1_SMP9_Pos (27U) +#define ADC_SMPR1_SMP9_Msk (0x7UL << ADC_SMPR1_SMP9_Pos) /*!< 0x38000000 */ +#define ADC_SMPR1_SMP9 ADC_SMPR1_SMP9_Msk /*!< ADC channel 9 sampling time selection */ +#define ADC_SMPR1_SMP9_0 (0x1UL << ADC_SMPR1_SMP9_Pos) /*!< 0x08000000 */ +#define ADC_SMPR1_SMP9_1 (0x2UL << ADC_SMPR1_SMP9_Pos) /*!< 0x10000000 */ +#define ADC_SMPR1_SMP9_2 (0x4UL << ADC_SMPR1_SMP9_Pos) /*!< 0x20000000 */ + +#define ADC_SMPR1_SMPPLUS_Pos (31U) +#define ADC_SMPR1_SMPPLUS_Msk (0x1UL << ADC_SMPR1_SMPPLUS_Pos) /*!< 0x80000000 */ +#define ADC_SMPR1_SMPPLUS ADC_SMPR1_SMPPLUS_Msk /*!< ADC channels sampling time additional setting */ + +/******************** Bit definition for ADC_SMPR2 register *****************/ +#define ADC_SMPR2_SMP10_Pos (0U) +#define ADC_SMPR2_SMP10_Msk (0x7UL << ADC_SMPR2_SMP10_Pos) /*!< 0x00000007 */ +#define ADC_SMPR2_SMP10 ADC_SMPR2_SMP10_Msk /*!< ADC channel 10 sampling time selection */ +#define ADC_SMPR2_SMP10_0 (0x1UL << ADC_SMPR2_SMP10_Pos) /*!< 0x00000001 */ +#define ADC_SMPR2_SMP10_1 (0x2UL << ADC_SMPR2_SMP10_Pos) /*!< 0x00000002 */ +#define ADC_SMPR2_SMP10_2 (0x4UL << ADC_SMPR2_SMP10_Pos) /*!< 0x00000004 */ + +#define ADC_SMPR2_SMP11_Pos (3U) +#define ADC_SMPR2_SMP11_Msk (0x7UL << ADC_SMPR2_SMP11_Pos) /*!< 0x00000038 */ +#define ADC_SMPR2_SMP11 ADC_SMPR2_SMP11_Msk /*!< ADC channel 11 sampling time selection */ +#define ADC_SMPR2_SMP11_0 (0x1UL << ADC_SMPR2_SMP11_Pos) /*!< 0x00000008 */ +#define ADC_SMPR2_SMP11_1 (0x2UL << ADC_SMPR2_SMP11_Pos) /*!< 0x00000010 */ +#define ADC_SMPR2_SMP11_2 (0x4UL << ADC_SMPR2_SMP11_Pos) /*!< 0x00000020 */ + +#define ADC_SMPR2_SMP12_Pos (6U) +#define ADC_SMPR2_SMP12_Msk (0x7UL << ADC_SMPR2_SMP12_Pos) /*!< 0x000001C0 */ +#define ADC_SMPR2_SMP12 ADC_SMPR2_SMP12_Msk /*!< ADC channel 12 sampling time selection */ +#define ADC_SMPR2_SMP12_0 (0x1UL << ADC_SMPR2_SMP12_Pos) /*!< 0x00000040 */ +#define ADC_SMPR2_SMP12_1 (0x2UL << ADC_SMPR2_SMP12_Pos) /*!< 0x00000080 */ +#define ADC_SMPR2_SMP12_2 (0x4UL << ADC_SMPR2_SMP12_Pos) /*!< 0x00000100 */ + +#define ADC_SMPR2_SMP13_Pos (9U) +#define ADC_SMPR2_SMP13_Msk (0x7UL << ADC_SMPR2_SMP13_Pos) /*!< 0x00000E00 */ +#define ADC_SMPR2_SMP13 ADC_SMPR2_SMP13_Msk /*!< ADC channel 13 sampling time selection */ +#define ADC_SMPR2_SMP13_0 (0x1UL << ADC_SMPR2_SMP13_Pos) /*!< 0x00000200 */ +#define ADC_SMPR2_SMP13_1 (0x2UL << ADC_SMPR2_SMP13_Pos) /*!< 0x00000400 */ +#define ADC_SMPR2_SMP13_2 (0x4UL << ADC_SMPR2_SMP13_Pos) /*!< 0x00000800 */ + +#define ADC_SMPR2_SMP14_Pos (12U) +#define ADC_SMPR2_SMP14_Msk (0x7UL << ADC_SMPR2_SMP14_Pos) /*!< 0x00007000 */ +#define ADC_SMPR2_SMP14 ADC_SMPR2_SMP14_Msk /*!< ADC channel 14 sampling time selection */ +#define ADC_SMPR2_SMP14_0 (0x1UL << ADC_SMPR2_SMP14_Pos) /*!< 0x00001000 */ +#define ADC_SMPR2_SMP14_1 (0x2UL << ADC_SMPR2_SMP14_Pos) /*!< 0x00002000 */ +#define ADC_SMPR2_SMP14_2 (0x4UL << ADC_SMPR2_SMP14_Pos) /*!< 0x00004000 */ + +#define ADC_SMPR2_SMP15_Pos (15U) +#define ADC_SMPR2_SMP15_Msk (0x7UL << ADC_SMPR2_SMP15_Pos) /*!< 0x00038000 */ +#define ADC_SMPR2_SMP15 ADC_SMPR2_SMP15_Msk /*!< ADC channel 15 sampling time selection */ +#define ADC_SMPR2_SMP15_0 (0x1UL << ADC_SMPR2_SMP15_Pos) /*!< 0x00008000 */ +#define ADC_SMPR2_SMP15_1 (0x2UL << ADC_SMPR2_SMP15_Pos) /*!< 0x00010000 */ +#define ADC_SMPR2_SMP15_2 (0x4UL << ADC_SMPR2_SMP15_Pos) /*!< 0x00020000 */ + +#define ADC_SMPR2_SMP16_Pos (18U) +#define ADC_SMPR2_SMP16_Msk (0x7UL << ADC_SMPR2_SMP16_Pos) /*!< 0x001C0000 */ +#define ADC_SMPR2_SMP16 ADC_SMPR2_SMP16_Msk /*!< ADC channel 16 sampling time selection */ +#define ADC_SMPR2_SMP16_0 (0x1UL << ADC_SMPR2_SMP16_Pos) /*!< 0x00040000 */ +#define ADC_SMPR2_SMP16_1 (0x2UL << ADC_SMPR2_SMP16_Pos) /*!< 0x00080000 */ +#define ADC_SMPR2_SMP16_2 (0x4UL << ADC_SMPR2_SMP16_Pos) /*!< 0x00100000 */ + +#define ADC_SMPR2_SMP17_Pos (21U) +#define ADC_SMPR2_SMP17_Msk (0x7UL << ADC_SMPR2_SMP17_Pos) /*!< 0x00E00000 */ +#define ADC_SMPR2_SMP17 ADC_SMPR2_SMP17_Msk /*!< ADC channel 17 sampling time selection */ +#define ADC_SMPR2_SMP17_0 (0x1UL << ADC_SMPR2_SMP17_Pos) /*!< 0x00200000 */ +#define ADC_SMPR2_SMP17_1 (0x2UL << ADC_SMPR2_SMP17_Pos) /*!< 0x00400000 */ +#define ADC_SMPR2_SMP17_2 (0x4UL << ADC_SMPR2_SMP17_Pos) /*!< 0x00800000 */ + +#define ADC_SMPR2_SMP18_Pos (24U) +#define ADC_SMPR2_SMP18_Msk (0x7UL << ADC_SMPR2_SMP18_Pos) /*!< 0x07000000 */ +#define ADC_SMPR2_SMP18 ADC_SMPR2_SMP18_Msk /*!< ADC channel 18 sampling time selection */ +#define ADC_SMPR2_SMP18_0 (0x1UL << ADC_SMPR2_SMP18_Pos) /*!< 0x01000000 */ +#define ADC_SMPR2_SMP18_1 (0x2UL << ADC_SMPR2_SMP18_Pos) /*!< 0x02000000 */ +#define ADC_SMPR2_SMP18_2 (0x4UL << ADC_SMPR2_SMP18_Pos) /*!< 0x04000000 */ + +/******************** Bit definition for ADC_TR1 register *******************/ +#define ADC_TR1_LT1_Pos (0U) +#define ADC_TR1_LT1_Msk (0xFFFUL << ADC_TR1_LT1_Pos) /*!< 0x00000FFF */ +#define ADC_TR1_LT1 ADC_TR1_LT1_Msk /*!< ADC analog watchdog 1 threshold low */ + +#define ADC_TR1_AWDFILT_Pos (12U) +#define ADC_TR1_AWDFILT_Msk (0x7UL << ADC_TR1_AWDFILT_Pos) /*!< 0x00007000 */ +#define ADC_TR1_AWDFILT ADC_TR1_AWDFILT_Msk /*!< ADC analog watchdog filtering parameter */ +#define ADC_TR1_AWDFILT_0 (0x1UL << ADC_TR1_AWDFILT_Pos) /*!< 0x00001000 */ +#define ADC_TR1_AWDFILT_1 (0x2UL << ADC_TR1_AWDFILT_Pos) /*!< 0x00002000 */ +#define ADC_TR1_AWDFILT_2 (0x4UL << ADC_TR1_AWDFILT_Pos) /*!< 0x00004000 */ + +#define ADC_TR1_HT1_Pos (16U) +#define ADC_TR1_HT1_Msk (0xFFFUL << ADC_TR1_HT1_Pos) /*!< 0x0FFF0000 */ +#define ADC_TR1_HT1 ADC_TR1_HT1_Msk /*!< ADC analog watchdog 1 threshold high */ + +/******************** Bit definition for ADC_TR2 register *******************/ +#define ADC_TR2_LT2_Pos (0U) +#define ADC_TR2_LT2_Msk (0xFFUL << ADC_TR2_LT2_Pos) /*!< 0x000000FF */ +#define ADC_TR2_LT2 ADC_TR2_LT2_Msk /*!< ADC analog watchdog 2 threshold low */ + +#define ADC_TR2_HT2_Pos (16U) +#define ADC_TR2_HT2_Msk (0xFFUL << ADC_TR2_HT2_Pos) /*!< 0x00FF0000 */ +#define ADC_TR2_HT2 ADC_TR2_HT2_Msk /*!< ADC analog watchdog 2 threshold high */ + +/******************** Bit definition for ADC_TR3 register *******************/ +#define ADC_TR3_LT3_Pos (0U) +#define ADC_TR3_LT3_Msk (0xFFUL << ADC_TR3_LT3_Pos) /*!< 0x000000FF */ +#define ADC_TR3_LT3 ADC_TR3_LT3_Msk /*!< ADC analog watchdog 3 threshold low */ + +#define ADC_TR3_HT3_Pos (16U) +#define ADC_TR3_HT3_Msk (0xFFUL << ADC_TR3_HT3_Pos) /*!< 0x00FF0000 */ +#define ADC_TR3_HT3 ADC_TR3_HT3_Msk /*!< ADC analog watchdog 3 threshold high */ + +/******************** Bit definition for ADC_SQR1 register ******************/ +#define ADC_SQR1_L_Pos (0U) +#define ADC_SQR1_L_Msk (0xFUL << ADC_SQR1_L_Pos) /*!< 0x0000000F */ +#define ADC_SQR1_L ADC_SQR1_L_Msk /*!< ADC group regular sequencer scan length */ +#define ADC_SQR1_L_0 (0x1UL << ADC_SQR1_L_Pos) /*!< 0x00000001 */ +#define ADC_SQR1_L_1 (0x2UL << ADC_SQR1_L_Pos) /*!< 0x00000002 */ +#define ADC_SQR1_L_2 (0x4UL << ADC_SQR1_L_Pos) /*!< 0x00000004 */ +#define ADC_SQR1_L_3 (0x8UL << ADC_SQR1_L_Pos) /*!< 0x00000008 */ + +#define ADC_SQR1_SQ1_Pos (6U) +#define ADC_SQR1_SQ1_Msk (0x1FUL << ADC_SQR1_SQ1_Pos) /*!< 0x000007C0 */ +#define ADC_SQR1_SQ1 ADC_SQR1_SQ1_Msk /*!< ADC group regular sequencer rank 1 */ +#define ADC_SQR1_SQ1_0 (0x01UL << ADC_SQR1_SQ1_Pos) /*!< 0x00000040 */ +#define ADC_SQR1_SQ1_1 (0x02UL << ADC_SQR1_SQ1_Pos) /*!< 0x00000080 */ +#define ADC_SQR1_SQ1_2 (0x04UL << ADC_SQR1_SQ1_Pos) /*!< 0x00000100 */ +#define ADC_SQR1_SQ1_3 (0x08UL << ADC_SQR1_SQ1_Pos) /*!< 0x00000200 */ +#define ADC_SQR1_SQ1_4 (0x10UL << ADC_SQR1_SQ1_Pos) /*!< 0x00000400 */ + +#define ADC_SQR1_SQ2_Pos (12U) +#define ADC_SQR1_SQ2_Msk (0x1FUL << ADC_SQR1_SQ2_Pos) /*!< 0x0001F000 */ +#define ADC_SQR1_SQ2 ADC_SQR1_SQ2_Msk /*!< ADC group regular sequencer rank 2 */ +#define ADC_SQR1_SQ2_0 (0x01UL << ADC_SQR1_SQ2_Pos) /*!< 0x00001000 */ +#define ADC_SQR1_SQ2_1 (0x02UL << ADC_SQR1_SQ2_Pos) /*!< 0x00002000 */ +#define ADC_SQR1_SQ2_2 (0x04UL << ADC_SQR1_SQ2_Pos) /*!< 0x00004000 */ +#define ADC_SQR1_SQ2_3 (0x08UL << ADC_SQR1_SQ2_Pos) /*!< 0x00008000 */ +#define ADC_SQR1_SQ2_4 (0x10UL << ADC_SQR1_SQ2_Pos) /*!< 0x00010000 */ + +#define ADC_SQR1_SQ3_Pos (18U) +#define ADC_SQR1_SQ3_Msk (0x1FUL << ADC_SQR1_SQ3_Pos) /*!< 0x007C0000 */ +#define ADC_SQR1_SQ3 ADC_SQR1_SQ3_Msk /*!< ADC group regular sequencer rank 3 */ +#define ADC_SQR1_SQ3_0 (0x01UL << ADC_SQR1_SQ3_Pos) /*!< 0x00040000 */ +#define ADC_SQR1_SQ3_1 (0x02UL << ADC_SQR1_SQ3_Pos) /*!< 0x00080000 */ +#define ADC_SQR1_SQ3_2 (0x04UL << ADC_SQR1_SQ3_Pos) /*!< 0x00100000 */ +#define ADC_SQR1_SQ3_3 (0x08UL << ADC_SQR1_SQ3_Pos) /*!< 0x00200000 */ +#define ADC_SQR1_SQ3_4 (0x10UL<< ADC_SQR1_SQ3_Pos) /*!< 0x00400000 */ + +#define ADC_SQR1_SQ4_Pos (24U) +#define ADC_SQR1_SQ4_Msk (0x1FUL << ADC_SQR1_SQ4_Pos) /*!< 0x1F000000 */ +#define ADC_SQR1_SQ4 ADC_SQR1_SQ4_Msk /*!< ADC group regular sequencer rank 4 */ +#define ADC_SQR1_SQ4_0 (0x01UL << ADC_SQR1_SQ4_Pos) /*!< 0x01000000 */ +#define ADC_SQR1_SQ4_1 (0x02UL << ADC_SQR1_SQ4_Pos) /*!< 0x02000000 */ +#define ADC_SQR1_SQ4_2 (0x04UL << ADC_SQR1_SQ4_Pos) /*!< 0x04000000 */ +#define ADC_SQR1_SQ4_3 (0x08UL << ADC_SQR1_SQ4_Pos) /*!< 0x08000000 */ +#define ADC_SQR1_SQ4_4 (0x10UL << ADC_SQR1_SQ4_Pos) /*!< 0x10000000 */ + +/******************** Bit definition for ADC_SQR2 register ******************/ +#define ADC_SQR2_SQ5_Pos (0U) +#define ADC_SQR2_SQ5_Msk (0x1FUL << ADC_SQR2_SQ5_Pos) /*!< 0x0000001F */ +#define ADC_SQR2_SQ5 ADC_SQR2_SQ5_Msk /*!< ADC group regular sequencer rank 5 */ +#define ADC_SQR2_SQ5_0 (0x01UL << ADC_SQR2_SQ5_Pos) /*!< 0x00000001 */ +#define ADC_SQR2_SQ5_1 (0x02UL << ADC_SQR2_SQ5_Pos) /*!< 0x00000002 */ +#define ADC_SQR2_SQ5_2 (0x04UL << ADC_SQR2_SQ5_Pos) /*!< 0x00000004 */ +#define ADC_SQR2_SQ5_3 (0x08UL << ADC_SQR2_SQ5_Pos) /*!< 0x00000008 */ +#define ADC_SQR2_SQ5_4 (0x10UL << ADC_SQR2_SQ5_Pos) /*!< 0x00000010 */ + +#define ADC_SQR2_SQ6_Pos (6U) +#define ADC_SQR2_SQ6_Msk (0x1FUL << ADC_SQR2_SQ6_Pos) /*!< 0x000007C0 */ +#define ADC_SQR2_SQ6 ADC_SQR2_SQ6_Msk /*!< ADC group regular sequencer rank 6 */ +#define ADC_SQR2_SQ6_0 (0x01UL << ADC_SQR2_SQ6_Pos) /*!< 0x00000040 */ +#define ADC_SQR2_SQ6_1 (0x02UL << ADC_SQR2_SQ6_Pos) /*!< 0x00000080 */ +#define ADC_SQR2_SQ6_2 (0x04UL << ADC_SQR2_SQ6_Pos) /*!< 0x00000100 */ +#define ADC_SQR2_SQ6_3 (0x08UL << ADC_SQR2_SQ6_Pos) /*!< 0x00000200 */ +#define ADC_SQR2_SQ6_4 (0x10UL << ADC_SQR2_SQ6_Pos) /*!< 0x00000400 */ + +#define ADC_SQR2_SQ7_Pos (12U) +#define ADC_SQR2_SQ7_Msk (0x1FUL << ADC_SQR2_SQ7_Pos) /*!< 0x0001F000 */ +#define ADC_SQR2_SQ7 ADC_SQR2_SQ7_Msk /*!< ADC group regular sequencer rank 7 */ +#define ADC_SQR2_SQ7_0 (0x01UL << ADC_SQR2_SQ7_Pos) /*!< 0x00001000 */ +#define ADC_SQR2_SQ7_1 (0x02UL << ADC_SQR2_SQ7_Pos) /*!< 0x00002000 */ +#define ADC_SQR2_SQ7_2 (0x04UL << ADC_SQR2_SQ7_Pos) /*!< 0x00004000 */ +#define ADC_SQR2_SQ7_3 (0x08UL << ADC_SQR2_SQ7_Pos) /*!< 0x00008000 */ +#define ADC_SQR2_SQ7_4 (0x10UL << ADC_SQR2_SQ7_Pos) /*!< 0x00010000 */ + +#define ADC_SQR2_SQ8_Pos (18U) +#define ADC_SQR2_SQ8_Msk (0x1FUL << ADC_SQR2_SQ8_Pos) /*!< 0x007C0000 */ +#define ADC_SQR2_SQ8 ADC_SQR2_SQ8_Msk /*!< ADC group regular sequencer rank 8 */ +#define ADC_SQR2_SQ8_0 (0x01UL << ADC_SQR2_SQ8_Pos) /*!< 0x00040000 */ +#define ADC_SQR2_SQ8_1 (0x02UL << ADC_SQR2_SQ8_Pos) /*!< 0x00080000 */ +#define ADC_SQR2_SQ8_2 (0x04UL << ADC_SQR2_SQ8_Pos) /*!< 0x00100000 */ +#define ADC_SQR2_SQ8_3 (0x08UL << ADC_SQR2_SQ8_Pos) /*!< 0x00200000 */ +#define ADC_SQR2_SQ8_4 (0x10UL << ADC_SQR2_SQ8_Pos) /*!< 0x00400000 */ + +#define ADC_SQR2_SQ9_Pos (24U) +#define ADC_SQR2_SQ9_Msk (0x1FUL << ADC_SQR2_SQ9_Pos) /*!< 0x1F000000 */ +#define ADC_SQR2_SQ9 ADC_SQR2_SQ9_Msk /*!< ADC group regular sequencer rank 9 */ +#define ADC_SQR2_SQ9_0 (0x01UL << ADC_SQR2_SQ9_Pos) /*!< 0x01000000 */ +#define ADC_SQR2_SQ9_1 (0x02UL << ADC_SQR2_SQ9_Pos) /*!< 0x02000000 */ +#define ADC_SQR2_SQ9_2 (0x04UL << ADC_SQR2_SQ9_Pos) /*!< 0x04000000 */ +#define ADC_SQR2_SQ9_3 (0x08UL << ADC_SQR2_SQ9_Pos) /*!< 0x08000000 */ +#define ADC_SQR2_SQ9_4 (0x10UL << ADC_SQR2_SQ9_Pos) /*!< 0x10000000 */ + +/******************** Bit definition for ADC_SQR3 register ******************/ +#define ADC_SQR3_SQ10_Pos (0U) +#define ADC_SQR3_SQ10_Msk (0x1FUL << ADC_SQR3_SQ10_Pos) /*!< 0x0000001F */ +#define ADC_SQR3_SQ10 ADC_SQR3_SQ10_Msk /*!< ADC group regular sequencer rank 10 */ +#define ADC_SQR3_SQ10_0 (0x01UL << ADC_SQR3_SQ10_Pos) /*!< 0x00000001 */ +#define ADC_SQR3_SQ10_1 (0x02UL << ADC_SQR3_SQ10_Pos) /*!< 0x00000002 */ +#define ADC_SQR3_SQ10_2 (0x04UL << ADC_SQR3_SQ10_Pos) /*!< 0x00000004 */ +#define ADC_SQR3_SQ10_3 (0x08UL << ADC_SQR3_SQ10_Pos) /*!< 0x00000008 */ +#define ADC_SQR3_SQ10_4 (0x10UL << ADC_SQR3_SQ10_Pos) /*!< 0x00000010 */ + +#define ADC_SQR3_SQ11_Pos (6U) +#define ADC_SQR3_SQ11_Msk (0x1FUL << ADC_SQR3_SQ11_Pos) /*!< 0x000007C0 */ +#define ADC_SQR3_SQ11 ADC_SQR3_SQ11_Msk /*!< ADC group regular sequencer rank 11 */ +#define ADC_SQR3_SQ11_0 (0x01UL << ADC_SQR3_SQ11_Pos) /*!< 0x00000040 */ +#define ADC_SQR3_SQ11_1 (0x02UL << ADC_SQR3_SQ11_Pos) /*!< 0x00000080 */ +#define ADC_SQR3_SQ11_2 (0x04UL << ADC_SQR3_SQ11_Pos) /*!< 0x00000100 */ +#define ADC_SQR3_SQ11_3 (0x08UL << ADC_SQR3_SQ11_Pos) /*!< 0x00000200 */ +#define ADC_SQR3_SQ11_4 (0x10UL << ADC_SQR3_SQ11_Pos) /*!< 0x00000400 */ + +#define ADC_SQR3_SQ12_Pos (12U) +#define ADC_SQR3_SQ12_Msk (0x1FUL << ADC_SQR3_SQ12_Pos) /*!< 0x0001F000 */ +#define ADC_SQR3_SQ12 ADC_SQR3_SQ12_Msk /*!< ADC group regular sequencer rank 12 */ +#define ADC_SQR3_SQ12_0 (0x01UL << ADC_SQR3_SQ12_Pos) /*!< 0x00001000 */ +#define ADC_SQR3_SQ12_1 (0x02UL << ADC_SQR3_SQ12_Pos) /*!< 0x00002000 */ +#define ADC_SQR3_SQ12_2 (0x04UL << ADC_SQR3_SQ12_Pos) /*!< 0x00004000 */ +#define ADC_SQR3_SQ12_3 (0x08UL << ADC_SQR3_SQ12_Pos) /*!< 0x00008000 */ +#define ADC_SQR3_SQ12_4 (0x10UL << ADC_SQR3_SQ12_Pos) /*!< 0x00010000 */ + +#define ADC_SQR3_SQ13_Pos (18U) +#define ADC_SQR3_SQ13_Msk (0x1FUL << ADC_SQR3_SQ13_Pos) /*!< 0x007C0000 */ +#define ADC_SQR3_SQ13 ADC_SQR3_SQ13_Msk /*!< ADC group regular sequencer rank 13 */ +#define ADC_SQR3_SQ13_0 (0x01UL << ADC_SQR3_SQ13_Pos) /*!< 0x00040000 */ +#define ADC_SQR3_SQ13_1 (0x02UL << ADC_SQR3_SQ13_Pos) /*!< 0x00080000 */ +#define ADC_SQR3_SQ13_2 (0x04UL << ADC_SQR3_SQ13_Pos) /*!< 0x00100000 */ +#define ADC_SQR3_SQ13_3 (0x08UL << ADC_SQR3_SQ13_Pos) /*!< 0x00200000 */ +#define ADC_SQR3_SQ13_4 (0x10UL << ADC_SQR3_SQ13_Pos) /*!< 0x00400000 */ + +#define ADC_SQR3_SQ14_Pos (24U) +#define ADC_SQR3_SQ14_Msk (0x1FUL << ADC_SQR3_SQ14_Pos) /*!< 0x1F000000 */ +#define ADC_SQR3_SQ14 ADC_SQR3_SQ14_Msk /*!< ADC group regular sequencer rank 14 */ +#define ADC_SQR3_SQ14_0 (0x01UL << ADC_SQR3_SQ14_Pos) /*!< 0x01000000 */ +#define ADC_SQR3_SQ14_1 (0x02UL << ADC_SQR3_SQ14_Pos) /*!< 0x02000000 */ +#define ADC_SQR3_SQ14_2 (0x04UL << ADC_SQR3_SQ14_Pos) /*!< 0x04000000 */ +#define ADC_SQR3_SQ14_3 (0x08UL << ADC_SQR3_SQ14_Pos) /*!< 0x08000000 */ +#define ADC_SQR3_SQ14_4 (0x10UL << ADC_SQR3_SQ14_Pos) /*!< 0x10000000 */ + +/******************** Bit definition for ADC_SQR4 register ******************/ +#define ADC_SQR4_SQ15_Pos (0U) +#define ADC_SQR4_SQ15_Msk (0x1FUL << ADC_SQR4_SQ15_Pos) /*!< 0x0000001F */ +#define ADC_SQR4_SQ15 ADC_SQR4_SQ15_Msk /*!< ADC group regular sequencer rank 15 */ +#define ADC_SQR4_SQ15_0 (0x01UL << ADC_SQR4_SQ15_Pos) /*!< 0x00000001 */ +#define ADC_SQR4_SQ15_1 (0x02UL << ADC_SQR4_SQ15_Pos) /*!< 0x00000002 */ +#define ADC_SQR4_SQ15_2 (0x04UL << ADC_SQR4_SQ15_Pos) /*!< 0x00000004 */ +#define ADC_SQR4_SQ15_3 (0x08UL << ADC_SQR4_SQ15_Pos) /*!< 0x00000008 */ +#define ADC_SQR4_SQ15_4 (0x10UL << ADC_SQR4_SQ15_Pos) /*!< 0x00000010 */ + +#define ADC_SQR4_SQ16_Pos (6U) +#define ADC_SQR4_SQ16_Msk (0x1FUL << ADC_SQR4_SQ16_Pos) /*!< 0x000007C0 */ +#define ADC_SQR4_SQ16 ADC_SQR4_SQ16_Msk /*!< ADC group regular sequencer rank 16 */ +#define ADC_SQR4_SQ16_0 (0x01UL << ADC_SQR4_SQ16_Pos) /*!< 0x00000040 */ +#define ADC_SQR4_SQ16_1 (0x02UL << ADC_SQR4_SQ16_Pos) /*!< 0x00000080 */ +#define ADC_SQR4_SQ16_2 (0x04UL << ADC_SQR4_SQ16_Pos) /*!< 0x00000100 */ +#define ADC_SQR4_SQ16_3 (0x08UL << ADC_SQR4_SQ16_Pos) /*!< 0x00000200 */ +#define ADC_SQR4_SQ16_4 (0x10UL << ADC_SQR4_SQ16_Pos) /*!< 0x00000400 */ + +/******************** Bit definition for ADC_DR register ********************/ +#define ADC_DR_RDATA_Pos (0U) +#define ADC_DR_RDATA_Msk (0xFFFFUL << ADC_DR_RDATA_Pos) /*!< 0x0000FFFF */ +#define ADC_DR_RDATA ADC_DR_RDATA_Msk /*!< ADC group regular conversion data */ + +/******************** Bit definition for ADC_JSQR register ******************/ +#define ADC_JSQR_JL_Pos (0U) +#define ADC_JSQR_JL_Msk (0x3UL << ADC_JSQR_JL_Pos) /*!< 0x00000003 */ +#define ADC_JSQR_JL ADC_JSQR_JL_Msk /*!< ADC group injected sequencer scan length */ +#define ADC_JSQR_JL_0 (0x1UL << ADC_JSQR_JL_Pos) /*!< 0x00000001 */ +#define ADC_JSQR_JL_1 (0x2UL << ADC_JSQR_JL_Pos) /*!< 0x00000002 */ + +#define ADC_JSQR_JEXTSEL_Pos (2U) +#define ADC_JSQR_JEXTSEL_Msk (0x1FUL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x0000007C */ +#define ADC_JSQR_JEXTSEL ADC_JSQR_JEXTSEL_Msk /*!< ADC group injected external trigger source */ +#define ADC_JSQR_JEXTSEL_0 (0x1UL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x00000004 */ +#define ADC_JSQR_JEXTSEL_1 (0x2UL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x00000008 */ +#define ADC_JSQR_JEXTSEL_2 (0x4UL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x00000010 */ +#define ADC_JSQR_JEXTSEL_3 (0x8UL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x00000020 */ +#define ADC_JSQR_JEXTSEL_4 (0x10UL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x00000040 */ + +#define ADC_JSQR_JEXTEN_Pos (7U) +#define ADC_JSQR_JEXTEN_Msk (0x3UL << ADC_JSQR_JEXTEN_Pos) /*!< 0x00000180 */ +#define ADC_JSQR_JEXTEN ADC_JSQR_JEXTEN_Msk /*!< ADC group injected external trigger polarity */ +#define ADC_JSQR_JEXTEN_0 (0x1UL << ADC_JSQR_JEXTEN_Pos) /*!< 0x00000080 */ +#define ADC_JSQR_JEXTEN_1 (0x2UL << ADC_JSQR_JEXTEN_Pos) /*!< 0x00000100 */ + +#define ADC_JSQR_JSQ1_Pos (9U) +#define ADC_JSQR_JSQ1_Msk (0x1FUL << ADC_JSQR_JSQ1_Pos) /*!< 0x00003E00 */ +#define ADC_JSQR_JSQ1 ADC_JSQR_JSQ1_Msk /*!< ADC group injected sequencer rank 1 */ +#define ADC_JSQR_JSQ1_0 (0x01UL << ADC_JSQR_JSQ1_Pos) /*!< 0x00000200 */ +#define ADC_JSQR_JSQ1_1 (0x02UL << ADC_JSQR_JSQ1_Pos) /*!< 0x00000400 */ +#define ADC_JSQR_JSQ1_2 (0x04UL << ADC_JSQR_JSQ1_Pos) /*!< 0x00000800 */ +#define ADC_JSQR_JSQ1_3 (0x08UL << ADC_JSQR_JSQ1_Pos) /*!< 0x00001000 */ +#define ADC_JSQR_JSQ1_4 (0x10UL << ADC_JSQR_JSQ1_Pos) /*!< 0x00002000 */ + +#define ADC_JSQR_JSQ2_Pos (15U) +#define ADC_JSQR_JSQ2_Msk (0x1FUL << ADC_JSQR_JSQ2_Pos) /*!< 0x0007C000 */ +#define ADC_JSQR_JSQ2 ADC_JSQR_JSQ2_Msk /*!< ADC group injected sequencer rank 2 */ +#define ADC_JSQR_JSQ2_0 (0x01UL << ADC_JSQR_JSQ2_Pos) /*!< 0x00004000 */ +#define ADC_JSQR_JSQ2_1 (0x02UL << ADC_JSQR_JSQ2_Pos) /*!< 0x00008000 */ +#define ADC_JSQR_JSQ2_2 (0x04UL << ADC_JSQR_JSQ2_Pos) /*!< 0x00010000 */ +#define ADC_JSQR_JSQ2_3 (0x08UL << ADC_JSQR_JSQ2_Pos) /*!< 0x00020000 */ +#define ADC_JSQR_JSQ2_4 (0x10UL << ADC_JSQR_JSQ2_Pos) /*!< 0x00040000 */ + +#define ADC_JSQR_JSQ3_Pos (21U) +#define ADC_JSQR_JSQ3_Msk (0x1FUL << ADC_JSQR_JSQ3_Pos) /*!< 0x03E00000 */ +#define ADC_JSQR_JSQ3 ADC_JSQR_JSQ3_Msk /*!< ADC group injected sequencer rank 3 */ +#define ADC_JSQR_JSQ3_0 (0x01UL << ADC_JSQR_JSQ3_Pos) /*!< 0x00200000 */ +#define ADC_JSQR_JSQ3_1 (0x02UL << ADC_JSQR_JSQ3_Pos) /*!< 0x00400000 */ +#define ADC_JSQR_JSQ3_2 (0x04UL << ADC_JSQR_JSQ3_Pos) /*!< 0x00800000 */ +#define ADC_JSQR_JSQ3_3 (0x08UL << ADC_JSQR_JSQ3_Pos) /*!< 0x01000000 */ +#define ADC_JSQR_JSQ3_4 (0x10UL << ADC_JSQR_JSQ3_Pos) /*!< 0x02000000 */ + +#define ADC_JSQR_JSQ4_Pos (27U) +#define ADC_JSQR_JSQ4_Msk (0x1FUL << ADC_JSQR_JSQ4_Pos) /*!< 0xF8000000 */ +#define ADC_JSQR_JSQ4 ADC_JSQR_JSQ4_Msk /*!< ADC group injected sequencer rank 4 */ +#define ADC_JSQR_JSQ4_0 (0x01UL << ADC_JSQR_JSQ4_Pos) /*!< 0x08000000 */ +#define ADC_JSQR_JSQ4_1 (0x02UL << ADC_JSQR_JSQ4_Pos) /*!< 0x10000000 */ +#define ADC_JSQR_JSQ4_2 (0x04UL << ADC_JSQR_JSQ4_Pos) /*!< 0x20000000 */ +#define ADC_JSQR_JSQ4_3 (0x08UL << ADC_JSQR_JSQ4_Pos) /*!< 0x40000000 */ +#define ADC_JSQR_JSQ4_4 (0x10UL << ADC_JSQR_JSQ4_Pos) /*!< 0x80000000 */ + +/******************** Bit definition for ADC_OFR1 register ******************/ +#define ADC_OFR1_OFFSET1_Pos (0U) +#define ADC_OFR1_OFFSET1_Msk (0xFFFUL << ADC_OFR1_OFFSET1_Pos) /*!< 0x00000FFF */ +#define ADC_OFR1_OFFSET1 ADC_OFR1_OFFSET1_Msk /*!< ADC offset number 1 offset level */ + +#define ADC_OFR1_OFFSETPOS_Pos (24U) +#define ADC_OFR1_OFFSETPOS_Msk (0x1UL << ADC_OFR1_OFFSETPOS_Pos) /*!< 0x01000000 */ +#define ADC_OFR1_OFFSETPOS ADC_OFR1_OFFSETPOS_Msk /*!< ADC offset number 1 positive */ +#define ADC_OFR1_SATEN_Pos (25U) +#define ADC_OFR1_SATEN_Msk (0x1UL << ADC_OFR1_SATEN_Pos) /*!< 0x02000000 */ +#define ADC_OFR1_SATEN ADC_OFR1_SATEN_Msk /*!< ADC offset number 1 saturation enable */ + +#define ADC_OFR1_OFFSET1_CH_Pos (26U) +#define ADC_OFR1_OFFSET1_CH_Msk (0x1FUL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x7C000000 */ +#define ADC_OFR1_OFFSET1_CH ADC_OFR1_OFFSET1_CH_Msk /*!< ADC offset number 1 channel selection */ +#define ADC_OFR1_OFFSET1_CH_0 (0x01UL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x04000000 */ +#define ADC_OFR1_OFFSET1_CH_1 (0x02UL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x08000000 */ +#define ADC_OFR1_OFFSET1_CH_2 (0x04UL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x10000000 */ +#define ADC_OFR1_OFFSET1_CH_3 (0x08UL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x20000000 */ +#define ADC_OFR1_OFFSET1_CH_4 (0x10UL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x40000000 */ + +#define ADC_OFR1_OFFSET1_EN_Pos (31U) +#define ADC_OFR1_OFFSET1_EN_Msk (0x1UL << ADC_OFR1_OFFSET1_EN_Pos) /*!< 0x80000000 */ +#define ADC_OFR1_OFFSET1_EN ADC_OFR1_OFFSET1_EN_Msk /*!< ADC offset number 1 enable */ + +/******************** Bit definition for ADC_OFR2 register ******************/ +#define ADC_OFR2_OFFSET2_Pos (0U) +#define ADC_OFR2_OFFSET2_Msk (0xFFFUL << ADC_OFR2_OFFSET2_Pos) /*!< 0x00000FFF */ +#define ADC_OFR2_OFFSET2 ADC_OFR2_OFFSET2_Msk /*!< ADC offset number 2 offset level */ + +#define ADC_OFR2_OFFSETPOS_Pos (24U) +#define ADC_OFR2_OFFSETPOS_Msk (0x1UL << ADC_OFR2_OFFSETPOS_Pos) /*!< 0x01000000 */ +#define ADC_OFR2_OFFSETPOS ADC_OFR2_OFFSETPOS_Msk /*!< ADC offset number 2 positive */ +#define ADC_OFR2_SATEN_Pos (25U) +#define ADC_OFR2_SATEN_Msk (0x1UL << ADC_OFR2_SATEN_Pos) /*!< 0x02000000 */ +#define ADC_OFR2_SATEN ADC_OFR2_SATEN_Msk /*!< ADC offset number 2 saturation enable */ + +#define ADC_OFR2_OFFSET2_CH_Pos (26U) +#define ADC_OFR2_OFFSET2_CH_Msk (0x1FUL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x7C000000 */ +#define ADC_OFR2_OFFSET2_CH ADC_OFR2_OFFSET2_CH_Msk /*!< ADC offset number 2 channel selection */ +#define ADC_OFR2_OFFSET2_CH_0 (0x01UL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x04000000 */ +#define ADC_OFR2_OFFSET2_CH_1 (0x02UL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x08000000 */ +#define ADC_OFR2_OFFSET2_CH_2 (0x04UL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x10000000 */ +#define ADC_OFR2_OFFSET2_CH_3 (0x08UL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x20000000 */ +#define ADC_OFR2_OFFSET2_CH_4 (0x10UL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x40000000 */ + +#define ADC_OFR2_OFFSET2_EN_Pos (31U) +#define ADC_OFR2_OFFSET2_EN_Msk (0x1UL << ADC_OFR2_OFFSET2_EN_Pos) /*!< 0x80000000 */ +#define ADC_OFR2_OFFSET2_EN ADC_OFR2_OFFSET2_EN_Msk /*!< ADC offset number 2 enable */ + +/******************** Bit definition for ADC_OFR3 register ******************/ +#define ADC_OFR3_OFFSET3_Pos (0U) +#define ADC_OFR3_OFFSET3_Msk (0xFFFUL << ADC_OFR3_OFFSET3_Pos) /*!< 0x00000FFF */ +#define ADC_OFR3_OFFSET3 ADC_OFR3_OFFSET3_Msk /*!< ADC offset number 3 offset level */ + +#define ADC_OFR3_OFFSETPOS_Pos (24U) +#define ADC_OFR3_OFFSETPOS_Msk (0x1UL << ADC_OFR3_OFFSETPOS_Pos) /*!< 0x01000000 */ +#define ADC_OFR3_OFFSETPOS ADC_OFR3_OFFSETPOS_Msk /*!< ADC offset number 3 positive */ +#define ADC_OFR3_SATEN_Pos (25U) +#define ADC_OFR3_SATEN_Msk (0x1UL << ADC_OFR3_SATEN_Pos) /*!< 0x02000000 */ +#define ADC_OFR3_SATEN ADC_OFR3_SATEN_Msk /*!< ADC offset number 3 saturation enable */ + +#define ADC_OFR3_OFFSET3_CH_Pos (26U) +#define ADC_OFR3_OFFSET3_CH_Msk (0x1FUL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x7C000000 */ +#define ADC_OFR3_OFFSET3_CH ADC_OFR3_OFFSET3_CH_Msk /*!< ADC offset number 3 channel selection */ +#define ADC_OFR3_OFFSET3_CH_0 (0x01UL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x04000000 */ +#define ADC_OFR3_OFFSET3_CH_1 (0x02UL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x08000000 */ +#define ADC_OFR3_OFFSET3_CH_2 (0x04UL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x10000000 */ +#define ADC_OFR3_OFFSET3_CH_3 (0x08UL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x20000000 */ +#define ADC_OFR3_OFFSET3_CH_4 (0x10UL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x40000000 */ + +#define ADC_OFR3_OFFSET3_EN_Pos (31U) +#define ADC_OFR3_OFFSET3_EN_Msk (0x1UL << ADC_OFR3_OFFSET3_EN_Pos) /*!< 0x80000000 */ +#define ADC_OFR3_OFFSET3_EN ADC_OFR3_OFFSET3_EN_Msk /*!< ADC offset number 3 enable */ + +/******************** Bit definition for ADC_OFR4 register ******************/ +#define ADC_OFR4_OFFSET4_Pos (0U) +#define ADC_OFR4_OFFSET4_Msk (0xFFFUL << ADC_OFR4_OFFSET4_Pos) /*!< 0x00000FFF */ +#define ADC_OFR4_OFFSET4 ADC_OFR4_OFFSET4_Msk /*!< ADC offset number 4 offset level */ + +#define ADC_OFR4_OFFSETPOS_Pos (24U) +#define ADC_OFR4_OFFSETPOS_Msk (0x1UL << ADC_OFR4_OFFSETPOS_Pos) /*!< 0x01000000 */ +#define ADC_OFR4_OFFSETPOS ADC_OFR4_OFFSETPOS_Msk /*!< ADC offset number 4 positive */ +#define ADC_OFR4_SATEN_Pos (25U) +#define ADC_OFR4_SATEN_Msk (0x1UL << ADC_OFR4_SATEN_Pos) /*!< 0x02000000 */ +#define ADC_OFR4_SATEN ADC_OFR4_SATEN_Msk /*!< ADC offset number 4 saturation enable */ + +#define ADC_OFR4_OFFSET4_CH_Pos (26U) +#define ADC_OFR4_OFFSET4_CH_Msk (0x1FUL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x7C000000 */ +#define ADC_OFR4_OFFSET4_CH ADC_OFR4_OFFSET4_CH_Msk /*!< ADC offset number 4 channel selection */ +#define ADC_OFR4_OFFSET4_CH_0 (0x01UL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x04000000 */ +#define ADC_OFR4_OFFSET4_CH_1 (0x02UL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x08000000 */ +#define ADC_OFR4_OFFSET4_CH_2 (0x04UL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x10000000 */ +#define ADC_OFR4_OFFSET4_CH_3 (0x08UL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x20000000 */ +#define ADC_OFR4_OFFSET4_CH_4 (0x10UL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x40000000 */ + +#define ADC_OFR4_OFFSET4_EN_Pos (31U) +#define ADC_OFR4_OFFSET4_EN_Msk (0x1UL << ADC_OFR4_OFFSET4_EN_Pos) /*!< 0x80000000 */ +#define ADC_OFR4_OFFSET4_EN ADC_OFR4_OFFSET4_EN_Msk /*!< ADC offset number 4 enable */ + +/******************** Bit definition for ADC_JDR1 register ******************/ +#define ADC_JDR1_JDATA_Pos (0U) +#define ADC_JDR1_JDATA_Msk (0xFFFFUL << ADC_JDR1_JDATA_Pos) /*!< 0x0000FFFF */ +#define ADC_JDR1_JDATA ADC_JDR1_JDATA_Msk /*!< ADC group injected sequencer rank 1 conversion data */ + +/******************** Bit definition for ADC_JDR2 register ******************/ +#define ADC_JDR2_JDATA_Pos (0U) +#define ADC_JDR2_JDATA_Msk (0xFFFFUL << ADC_JDR2_JDATA_Pos) /*!< 0x0000FFFF */ +#define ADC_JDR2_JDATA ADC_JDR2_JDATA_Msk /*!< ADC group injected sequencer rank 2 conversion data */ + +/******************** Bit definition for ADC_JDR3 register ******************/ +#define ADC_JDR3_JDATA_Pos (0U) +#define ADC_JDR3_JDATA_Msk (0xFFFFUL << ADC_JDR3_JDATA_Pos) /*!< 0x0000FFFF */ +#define ADC_JDR3_JDATA ADC_JDR3_JDATA_Msk /*!< ADC group injected sequencer rank 3 conversion data */ + +/******************** Bit definition for ADC_JDR4 register ******************/ +#define ADC_JDR4_JDATA_Pos (0U) +#define ADC_JDR4_JDATA_Msk (0xFFFFUL << ADC_JDR4_JDATA_Pos) /*!< 0x0000FFFF */ +#define ADC_JDR4_JDATA ADC_JDR4_JDATA_Msk /*!< ADC group injected sequencer rank 4 conversion data */ + +/******************** Bit definition for ADC_AWD2CR register ****************/ +#define ADC_AWD2CR_AWD2CH_Pos (0U) +#define ADC_AWD2CR_AWD2CH_Msk (0xFFFFFUL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x0007FFFF */ +#define ADC_AWD2CR_AWD2CH ADC_AWD2CR_AWD2CH_Msk /*!< ADC analog watchdog 2 monitored channel selection */ +#define ADC_AWD2CR_AWD2CH_0 (0x00001UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000001 */ +#define ADC_AWD2CR_AWD2CH_1 (0x00002UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000002 */ +#define ADC_AWD2CR_AWD2CH_2 (0x00004UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000004 */ +#define ADC_AWD2CR_AWD2CH_3 (0x00008UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000008 */ +#define ADC_AWD2CR_AWD2CH_4 (0x00010UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000010 */ +#define ADC_AWD2CR_AWD2CH_5 (0x00020UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000020 */ +#define ADC_AWD2CR_AWD2CH_6 (0x00040UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000040 */ +#define ADC_AWD2CR_AWD2CH_7 (0x00080UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000080 */ +#define ADC_AWD2CR_AWD2CH_8 (0x00100UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000100 */ +#define ADC_AWD2CR_AWD2CH_9 (0x00200UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000200 */ +#define ADC_AWD2CR_AWD2CH_10 (0x00400UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000400 */ +#define ADC_AWD2CR_AWD2CH_11 (0x00800UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000800 */ +#define ADC_AWD2CR_AWD2CH_12 (0x01000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00001000 */ +#define ADC_AWD2CR_AWD2CH_13 (0x02000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00002000 */ +#define ADC_AWD2CR_AWD2CH_14 (0x04000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00004000 */ +#define ADC_AWD2CR_AWD2CH_15 (0x08000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00008000 */ +#define ADC_AWD2CR_AWD2CH_16 (0x10000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00010000 */ +#define ADC_AWD2CR_AWD2CH_17 (0x20000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00020000 */ +#define ADC_AWD2CR_AWD2CH_18 (0x40000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00040000 */ +#define ADC_AWD2CR_AWD2CH_19 (0x80000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00080000 */ + +/******************** Bit definition for ADC_AWD3CR register ****************/ +#define ADC_AWD3CR_AWD3CH_Pos (0U) +#define ADC_AWD3CR_AWD3CH_Msk (0xFFFFFUL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x0007FFFF */ +#define ADC_AWD3CR_AWD3CH ADC_AWD3CR_AWD3CH_Msk /*!< ADC analog watchdog 3 monitored channel selection */ +#define ADC_AWD3CR_AWD3CH_0 (0x00001UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000001 */ +#define ADC_AWD3CR_AWD3CH_1 (0x00002UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000002 */ +#define ADC_AWD3CR_AWD3CH_2 (0x00004UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000004 */ +#define ADC_AWD3CR_AWD3CH_3 (0x00008UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000008 */ +#define ADC_AWD3CR_AWD3CH_4 (0x00010UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000010 */ +#define ADC_AWD3CR_AWD3CH_5 (0x00020UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000020 */ +#define ADC_AWD3CR_AWD3CH_6 (0x00040UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000040 */ +#define ADC_AWD3CR_AWD3CH_7 (0x00080UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000080 */ +#define ADC_AWD3CR_AWD3CH_8 (0x00100UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000100 */ +#define ADC_AWD3CR_AWD3CH_9 (0x00200UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000200 */ +#define ADC_AWD3CR_AWD3CH_10 (0x00400UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000400 */ +#define ADC_AWD3CR_AWD3CH_11 (0x00800UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000800 */ +#define ADC_AWD3CR_AWD3CH_12 (0x01000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00001000 */ +#define ADC_AWD3CR_AWD3CH_13 (0x02000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00002000 */ +#define ADC_AWD3CR_AWD3CH_14 (0x04000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00004000 */ +#define ADC_AWD3CR_AWD3CH_15 (0x08000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00008000 */ +#define ADC_AWD3CR_AWD3CH_16 (0x10000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00010000 */ +#define ADC_AWD3CR_AWD3CH_17 (0x20000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00020000 */ +#define ADC_AWD3CR_AWD3CH_18 (0x40000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00040000 */ +#define ADC_AWD3CR_AWD2CH_19 (0x80000UL << ADC_AWD3CR_AWD2CH_Pos) /*!< 0x00080000 */ + +/******************** Bit definition for ADC_DIFSEL register ****************/ +#define ADC_DIFSEL_DIFSEL_Pos (0U) +#define ADC_DIFSEL_DIFSEL_Msk (0xFFFFFUL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x0007FFFF */ +#define ADC_DIFSEL_DIFSEL ADC_DIFSEL_DIFSEL_Msk /*!< ADC channel differential or single-ended mode */ +#define ADC_DIFSEL_DIFSEL_0 (0x00001UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000001 */ +#define ADC_DIFSEL_DIFSEL_1 (0x00002UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000002 */ +#define ADC_DIFSEL_DIFSEL_2 (0x00004UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000004 */ +#define ADC_DIFSEL_DIFSEL_3 (0x00008UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000008 */ +#define ADC_DIFSEL_DIFSEL_4 (0x00010UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000010 */ +#define ADC_DIFSEL_DIFSEL_5 (0x00020UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000020 */ +#define ADC_DIFSEL_DIFSEL_6 (0x00040UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000040 */ +#define ADC_DIFSEL_DIFSEL_7 (0x00080UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000080 */ +#define ADC_DIFSEL_DIFSEL_8 (0x00100UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000100 */ +#define ADC_DIFSEL_DIFSEL_9 (0x00200UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000200 */ +#define ADC_DIFSEL_DIFSEL_10 (0x00400UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000400 */ +#define ADC_DIFSEL_DIFSEL_11 (0x00800UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000800 */ +#define ADC_DIFSEL_DIFSEL_12 (0x01000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00001000 */ +#define ADC_DIFSEL_DIFSEL_13 (0x02000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00002000 */ +#define ADC_DIFSEL_DIFSEL_14 (0x04000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00004000 */ +#define ADC_DIFSEL_DIFSEL_15 (0x08000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00008000 */ +#define ADC_DIFSEL_DIFSEL_16 (0x10000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00010000 */ +#define ADC_DIFSEL_DIFSEL_17 (0x20000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00020000 */ +#define ADC_DIFSEL_DIFSEL_18 (0x40000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00040000 */ +#define ADC_DIFSEL_DIFSEL_19 (0x80000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00080000 */ + +/******************** Bit definition for ADC_CALFACT register ***************/ +#define ADC_CALFACT_CALFACT_S_Pos (0U) +#define ADC_CALFACT_CALFACT_S_Msk (0x7FUL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x0000007F */ +#define ADC_CALFACT_CALFACT_S ADC_CALFACT_CALFACT_S_Msk /*!< ADC calibration factor in single-ended mode */ +#define ADC_CALFACT_CALFACT_S_0 (0x01UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000001 */ +#define ADC_CALFACT_CALFACT_S_1 (0x02UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000002 */ +#define ADC_CALFACT_CALFACT_S_2 (0x04UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000004 */ +#define ADC_CALFACT_CALFACT_S_3 (0x08UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000008 */ +#define ADC_CALFACT_CALFACT_S_4 (0x10UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000010 */ +#define ADC_CALFACT_CALFACT_S_5 (0x20UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000020 */ +#define ADC_CALFACT_CALFACT_S_6 (0x40UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000030 */ + +#define ADC_CALFACT_CALFACT_D_Pos (16U) +#define ADC_CALFACT_CALFACT_D_Msk (0x7FUL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x007F0000 */ +#define ADC_CALFACT_CALFACT_D ADC_CALFACT_CALFACT_D_Msk /*!< ADC calibration factor in differential mode */ +#define ADC_CALFACT_CALFACT_D_0 (0x01UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00010000 */ +#define ADC_CALFACT_CALFACT_D_1 (0x02UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00020000 */ +#define ADC_CALFACT_CALFACT_D_2 (0x04UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00040000 */ +#define ADC_CALFACT_CALFACT_D_3 (0x08UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00080000 */ +#define ADC_CALFACT_CALFACT_D_4 (0x10UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00100000 */ +#define ADC_CALFACT_CALFACT_D_5 (0x20UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00200000 */ +#define ADC_CALFACT_CALFACT_D_6 (0x40UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00300000 */ + +/******************** Bit definition for ADC_OR register *****************/ +#define ADC_OR_OP0_Pos (0U) +#define ADC_OR_OP0_Msk (0x01UL << ADC_OR_OP0_Pos) /*!< 0x00000001 */ +#define ADC_OR_OP0 ADC_OR_OP0_Msk /*!< ADC Option bit 0 */ +#define ADC_OR_OP1_Pos (1U) +#define ADC_OR_OP1_Msk (0x01UL << ADC_OR_OP1_Pos) /*!< 0x00000001 */ +#define ADC_OR_OP1 ADC_OR_OP1_Msk /*!< ADC Option bit 1 */ + +/************************* ADC Common registers *****************************/ +/******************** Bit definition for ADC_CSR register *******************/ +#define ADC_CSR_ADRDY_MST_Pos (0U) +#define ADC_CSR_ADRDY_MST_Msk (0x1UL << ADC_CSR_ADRDY_MST_Pos) /*!< 0x00000001 */ +#define ADC_CSR_ADRDY_MST ADC_CSR_ADRDY_MST_Msk /*!< ADC multimode master ready flag */ +#define ADC_CSR_EOSMP_MST_Pos (1U) +#define ADC_CSR_EOSMP_MST_Msk (0x1UL << ADC_CSR_EOSMP_MST_Pos) /*!< 0x00000002 */ +#define ADC_CSR_EOSMP_MST ADC_CSR_EOSMP_MST_Msk /*!< ADC multimode master group regular end of sampling flag */ +#define ADC_CSR_EOC_MST_Pos (2U) +#define ADC_CSR_EOC_MST_Msk (0x1UL << ADC_CSR_EOC_MST_Pos) /*!< 0x00000004 */ +#define ADC_CSR_EOC_MST ADC_CSR_EOC_MST_Msk /*!< ADC multimode master group regular end of unitary conversion flag */ +#define ADC_CSR_EOS_MST_Pos (3U) +#define ADC_CSR_EOS_MST_Msk (0x1UL << ADC_CSR_EOS_MST_Pos) /*!< 0x00000008 */ +#define ADC_CSR_EOS_MST ADC_CSR_EOS_MST_Msk /*!< ADC multimode master group regular end of sequence conversions flag */ +#define ADC_CSR_OVR_MST_Pos (4U) +#define ADC_CSR_OVR_MST_Msk (0x1UL << ADC_CSR_OVR_MST_Pos) /*!< 0x00000010 */ +#define ADC_CSR_OVR_MST ADC_CSR_OVR_MST_Msk /*!< ADC multimode master group regular overrun flag */ +#define ADC_CSR_JEOC_MST_Pos (5U) +#define ADC_CSR_JEOC_MST_Msk (0x1UL << ADC_CSR_JEOC_MST_Pos) /*!< 0x00000020 */ +#define ADC_CSR_JEOC_MST ADC_CSR_JEOC_MST_Msk /*!< ADC multimode master group injected end of unitary conversion flag */ +#define ADC_CSR_JEOS_MST_Pos (6U) +#define ADC_CSR_JEOS_MST_Msk (0x1UL << ADC_CSR_JEOS_MST_Pos) /*!< 0x00000040 */ +#define ADC_CSR_JEOS_MST ADC_CSR_JEOS_MST_Msk /*!< ADC multimode master group injected end of sequence conversions flag */ +#define ADC_CSR_AWD1_MST_Pos (7U) +#define ADC_CSR_AWD1_MST_Msk (0x1UL << ADC_CSR_AWD1_MST_Pos) /*!< 0x00000080 */ +#define ADC_CSR_AWD1_MST ADC_CSR_AWD1_MST_Msk /*!< ADC multimode master analog watchdog 1 flag */ +#define ADC_CSR_AWD2_MST_Pos (8U) +#define ADC_CSR_AWD2_MST_Msk (0x1UL << ADC_CSR_AWD2_MST_Pos) /*!< 0x00000100 */ +#define ADC_CSR_AWD2_MST ADC_CSR_AWD2_MST_Msk /*!< ADC multimode master analog watchdog 2 flag */ +#define ADC_CSR_AWD3_MST_Pos (9U) +#define ADC_CSR_AWD3_MST_Msk (0x1UL << ADC_CSR_AWD3_MST_Pos) /*!< 0x00000200 */ +#define ADC_CSR_AWD3_MST ADC_CSR_AWD3_MST_Msk /*!< ADC multimode master analog watchdog 3 flag */ +#define ADC_CSR_JQOVF_MST_Pos (10U) +#define ADC_CSR_JQOVF_MST_Msk (0x1UL << ADC_CSR_JQOVF_MST_Pos) /*!< 0x00000400 */ +#define ADC_CSR_JQOVF_MST ADC_CSR_JQOVF_MST_Msk /*!< ADC multimode master group injected contexts queue overflow flag */ + +#define ADC_CSR_ADRDY_SLV_Pos (16U) +#define ADC_CSR_ADRDY_SLV_Msk (0x1UL << ADC_CSR_ADRDY_SLV_Pos) /*!< 0x00010000 */ +#define ADC_CSR_ADRDY_SLV ADC_CSR_ADRDY_SLV_Msk /*!< ADC multimode slave ready flag */ +#define ADC_CSR_EOSMP_SLV_Pos (17U) +#define ADC_CSR_EOSMP_SLV_Msk (0x1UL << ADC_CSR_EOSMP_SLV_Pos) /*!< 0x00020000 */ +#define ADC_CSR_EOSMP_SLV ADC_CSR_EOSMP_SLV_Msk /*!< ADC multimode slave group regular end of sampling flag */ +#define ADC_CSR_EOC_SLV_Pos (18U) +#define ADC_CSR_EOC_SLV_Msk (0x1UL << ADC_CSR_EOC_SLV_Pos) /*!< 0x00040000 */ +#define ADC_CSR_EOC_SLV ADC_CSR_EOC_SLV_Msk /*!< ADC multimode slave group regular end of unitary conversion flag */ +#define ADC_CSR_EOS_SLV_Pos (19U) +#define ADC_CSR_EOS_SLV_Msk (0x1UL << ADC_CSR_EOS_SLV_Pos) /*!< 0x00080000 */ +#define ADC_CSR_EOS_SLV ADC_CSR_EOS_SLV_Msk /*!< ADC multimode slave group regular end of sequence conversions flag */ +#define ADC_CSR_OVR_SLV_Pos (20U) +#define ADC_CSR_OVR_SLV_Msk (0x1UL << ADC_CSR_OVR_SLV_Pos) /*!< 0x00100000 */ +#define ADC_CSR_OVR_SLV ADC_CSR_OVR_SLV_Msk /*!< ADC multimode slave group regular overrun flag */ +#define ADC_CSR_JEOC_SLV_Pos (21U) +#define ADC_CSR_JEOC_SLV_Msk (0x1UL << ADC_CSR_JEOC_SLV_Pos) /*!< 0x00200000 */ +#define ADC_CSR_JEOC_SLV ADC_CSR_JEOC_SLV_Msk /*!< ADC multimode slave group injected end of unitary conversion flag */ +#define ADC_CSR_JEOS_SLV_Pos (22U) +#define ADC_CSR_JEOS_SLV_Msk (0x1UL << ADC_CSR_JEOS_SLV_Pos) /*!< 0x00400000 */ +#define ADC_CSR_JEOS_SLV ADC_CSR_JEOS_SLV_Msk /*!< ADC multimode slave group injected end of sequence conversions flag */ +#define ADC_CSR_AWD1_SLV_Pos (23U) +#define ADC_CSR_AWD1_SLV_Msk (0x1UL << ADC_CSR_AWD1_SLV_Pos) /*!< 0x00800000 */ +#define ADC_CSR_AWD1_SLV ADC_CSR_AWD1_SLV_Msk /*!< ADC multimode slave analog watchdog 1 flag */ +#define ADC_CSR_AWD2_SLV_Pos (24U) +#define ADC_CSR_AWD2_SLV_Msk (0x1UL << ADC_CSR_AWD2_SLV_Pos) /*!< 0x01000000 */ +#define ADC_CSR_AWD2_SLV ADC_CSR_AWD2_SLV_Msk /*!< ADC multimode slave analog watchdog 2 flag */ +#define ADC_CSR_AWD3_SLV_Pos (25U) +#define ADC_CSR_AWD3_SLV_Msk (0x1UL << ADC_CSR_AWD3_SLV_Pos) /*!< 0x02000000 */ +#define ADC_CSR_AWD3_SLV ADC_CSR_AWD3_SLV_Msk /*!< ADC multimode slave analog watchdog 3 flag */ +#define ADC_CSR_JQOVF_SLV_Pos (26U) +#define ADC_CSR_JQOVF_SLV_Msk (0x1UL << ADC_CSR_JQOVF_SLV_Pos) /*!< 0x04000000 */ +#define ADC_CSR_JQOVF_SLV ADC_CSR_JQOVF_SLV_Msk /*!< ADC multimode slave group injected contexts queue overflow flag */ + +/******************** Bit definition for ADC_CCR register *******************/ +#define ADC_CCR_DUAL_Pos (0U) +#define ADC_CCR_DUAL_Msk (0x1FUL << ADC_CCR_DUAL_Pos) /*!< 0x0000001F */ +#define ADC_CCR_DUAL ADC_CCR_DUAL_Msk /*!< ADC multimode mode selection */ +#define ADC_CCR_DUAL_0 (0x01UL << ADC_CCR_DUAL_Pos) /*!< 0x00000001 */ +#define ADC_CCR_DUAL_1 (0x02UL << ADC_CCR_DUAL_Pos) /*!< 0x00000002 */ +#define ADC_CCR_DUAL_2 (0x04UL << ADC_CCR_DUAL_Pos) /*!< 0x00000004 */ +#define ADC_CCR_DUAL_3 (0x08UL << ADC_CCR_DUAL_Pos) /*!< 0x00000008 */ +#define ADC_CCR_DUAL_4 (0x10UL << ADC_CCR_DUAL_Pos) /*!< 0x00000010 */ + +#define ADC_CCR_DELAY_Pos (8U) +#define ADC_CCR_DELAY_Msk (0xFUL << ADC_CCR_DELAY_Pos) /*!< 0x00000F00 */ +#define ADC_CCR_DELAY ADC_CCR_DELAY_Msk /*!< ADC multimode delay between 2 sampling phases */ +#define ADC_CCR_DELAY_0 (0x1UL << ADC_CCR_DELAY_Pos) /*!< 0x00000100 */ +#define ADC_CCR_DELAY_1 (0x2UL << ADC_CCR_DELAY_Pos) /*!< 0x00000200 */ +#define ADC_CCR_DELAY_2 (0x4UL << ADC_CCR_DELAY_Pos) /*!< 0x00000400 */ +#define ADC_CCR_DELAY_3 (0x8UL << ADC_CCR_DELAY_Pos) /*!< 0x00000800 */ + +#define ADC_CCR_DMACFG_Pos (13U) +#define ADC_CCR_DMACFG_Msk (0x1UL << ADC_CCR_DMACFG_Pos) /*!< 0x00002000 */ +#define ADC_CCR_DMACFG ADC_CCR_DMACFG_Msk /*!< ADC multimode DMA transfer configuration */ + +#define ADC_CCR_MDMA_Pos (14U) +#define ADC_CCR_MDMA_Msk (0x3UL << ADC_CCR_MDMA_Pos) /*!< 0x0000C000 */ +#define ADC_CCR_MDMA ADC_CCR_MDMA_Msk /*!< ADC multimode DMA transfer enable */ +#define ADC_CCR_MDMA_0 (0x1UL << ADC_CCR_MDMA_Pos) /*!< 0x00004000 */ +#define ADC_CCR_MDMA_1 (0x2UL << ADC_CCR_MDMA_Pos) /*!< 0x00008000 */ + +#define ADC_CCR_CKMODE_Pos (16U) +#define ADC_CCR_CKMODE_Msk (0x3UL << ADC_CCR_CKMODE_Pos) /*!< 0x00030000 */ +#define ADC_CCR_CKMODE ADC_CCR_CKMODE_Msk /*!< ADC common clock source and prescaler (prescaler only for clock source synchronous) */ +#define ADC_CCR_CKMODE_0 (0x1UL << ADC_CCR_CKMODE_Pos) /*!< 0x00010000 */ +#define ADC_CCR_CKMODE_1 (0x2UL << ADC_CCR_CKMODE_Pos) /*!< 0x00020000 */ + +#define ADC_CCR_PRESC_Pos (18U) +#define ADC_CCR_PRESC_Msk (0xFUL << ADC_CCR_PRESC_Pos) /*!< 0x003C0000 */ +#define ADC_CCR_PRESC ADC_CCR_PRESC_Msk /*!< ADC common clock prescaler, only for clock source asynchronous */ +#define ADC_CCR_PRESC_0 (0x1UL << ADC_CCR_PRESC_Pos) /*!< 0x00040000 */ +#define ADC_CCR_PRESC_1 (0x2UL << ADC_CCR_PRESC_Pos) /*!< 0x00080000 */ +#define ADC_CCR_PRESC_2 (0x4UL << ADC_CCR_PRESC_Pos) /*!< 0x00100000 */ +#define ADC_CCR_PRESC_3 (0x8UL << ADC_CCR_PRESC_Pos) /*!< 0x00200000 */ + +#define ADC_CCR_VREFEN_Pos (22U) +#define ADC_CCR_VREFEN_Msk (0x1UL << ADC_CCR_VREFEN_Pos) /*!< 0x00400000 */ +#define ADC_CCR_VREFEN ADC_CCR_VREFEN_Msk /*!< ADC internal path to VrefInt enable */ +#define ADC_CCR_TSEN_Pos (23U) +#define ADC_CCR_TSEN_Msk (0x1UL << ADC_CCR_TSEN_Pos) /*!< 0x00800000 */ +#define ADC_CCR_TSEN ADC_CCR_TSEN_Msk /*!< ADC internal path to temperature sensor enable */ +#define ADC_CCR_VBATEN_Pos (24U) +#define ADC_CCR_VBATEN_Msk (0x1UL << ADC_CCR_VBATEN_Pos) /*!< 0x01000000 */ +#define ADC_CCR_VBATEN ADC_CCR_VBATEN_Msk /*!< ADC internal path to battery voltage enable */ + +/******************** Bit definition for ADC_CDR register *******************/ +#define ADC_CDR_RDATA_MST_Pos (0U) +#define ADC_CDR_RDATA_MST_Msk (0xFFFFUL << ADC_CDR_RDATA_MST_Pos) /*!< 0x0000FFFF */ +#define ADC_CDR_RDATA_MST ADC_CDR_RDATA_MST_Msk /*!< ADC multimode master group regular conversion data */ + +#define ADC_CDR_RDATA_SLV_Pos (16U) +#define ADC_CDR_RDATA_SLV_Msk (0xFFFFUL << ADC_CDR_RDATA_SLV_Pos) /*!< 0xFFFF0000 */ +#define ADC_CDR_RDATA_SLV ADC_CDR_RDATA_SLV_Msk /*!< ADC multimode slave group regular conversion data */ + + +/******************************************************************************/ +/* */ +/* CORDIC calculation unit */ +/* */ +/******************************************************************************/ +/******************* Bit definition for CORDIC_CSR register *****************/ +#define CORDIC_CSR_FUNC_Pos (0U) +#define CORDIC_CSR_FUNC_Msk (0xFUL << CORDIC_CSR_FUNC_Pos) /*!< 0x0000000F */ +#define CORDIC_CSR_FUNC CORDIC_CSR_FUNC_Msk /*!< Function */ +#define CORDIC_CSR_FUNC_0 (0x1UL << CORDIC_CSR_FUNC_Pos) /*!< 0x00000001 */ +#define CORDIC_CSR_FUNC_1 (0x2UL << CORDIC_CSR_FUNC_Pos) /*!< 0x00000002 */ +#define CORDIC_CSR_FUNC_2 (0x4UL << CORDIC_CSR_FUNC_Pos) /*!< 0x00000004 */ +#define CORDIC_CSR_FUNC_3 (0x8UL << CORDIC_CSR_FUNC_Pos) /*!< 0x00000008 */ +#define CORDIC_CSR_PRECISION_Pos (4U) +#define CORDIC_CSR_PRECISION_Msk (0xFUL << CORDIC_CSR_PRECISION_Pos) /*!< 0x000000F0 */ +#define CORDIC_CSR_PRECISION CORDIC_CSR_PRECISION_Msk /*!< Precision */ +#define CORDIC_CSR_PRECISION_0 (0x1UL << CORDIC_CSR_PRECISION_Pos) /*!< 0x00000010 */ +#define CORDIC_CSR_PRECISION_1 (0x2UL << CORDIC_CSR_PRECISION_Pos) /*!< 0x00000020 */ +#define CORDIC_CSR_PRECISION_2 (0x4UL << CORDIC_CSR_PRECISION_Pos) /*!< 0x00000040 */ +#define CORDIC_CSR_PRECISION_3 (0x8UL << CORDIC_CSR_PRECISION_Pos) /*!< 0x00000080 */ +#define CORDIC_CSR_SCALE_Pos (8U) +#define CORDIC_CSR_SCALE_Msk (0x7UL << CORDIC_CSR_SCALE_Pos) /*!< 0x00000700 */ +#define CORDIC_CSR_SCALE CORDIC_CSR_SCALE_Msk /*!< Scaling factor */ +#define CORDIC_CSR_SCALE_0 (0x1UL << CORDIC_CSR_SCALE_Pos) /*!< 0x00000100 */ +#define CORDIC_CSR_SCALE_1 (0x2UL << CORDIC_CSR_SCALE_Pos) /*!< 0x00000200 */ +#define CORDIC_CSR_SCALE_2 (0x4UL << CORDIC_CSR_SCALE_Pos) /*!< 0x00000400 */ +#define CORDIC_CSR_IEN_Pos (16U) +#define CORDIC_CSR_IEN_Msk (0x1UL << CORDIC_CSR_IEN_Pos) /*!< 0x00010000 */ +#define CORDIC_CSR_IEN CORDIC_CSR_IEN_Msk /*!< Interrupt Enable */ +#define CORDIC_CSR_DMAREN_Pos (17U) +#define CORDIC_CSR_DMAREN_Msk (0x1UL << CORDIC_CSR_DMAREN_Pos) /*!< 0x00020000 */ +#define CORDIC_CSR_DMAREN CORDIC_CSR_DMAREN_Msk /*!< DMA Read channel Enable */ +#define CORDIC_CSR_DMAWEN_Pos (18U) +#define CORDIC_CSR_DMAWEN_Msk (0x1UL << CORDIC_CSR_DMAWEN_Pos) /*!< 0x00040000 */ +#define CORDIC_CSR_DMAWEN CORDIC_CSR_DMAWEN_Msk /*!< DMA Write channel Enable */ +#define CORDIC_CSR_NRES_Pos (19U) +#define CORDIC_CSR_NRES_Msk (0x1UL << CORDIC_CSR_NRES_Pos) /*!< 0x00080000 */ +#define CORDIC_CSR_NRES CORDIC_CSR_NRES_Msk /*!< Number of results in WDATA register */ +#define CORDIC_CSR_NARGS_Pos (20U) +#define CORDIC_CSR_NARGS_Msk (0x1UL << CORDIC_CSR_NARGS_Pos) /*!< 0x00100000 */ +#define CORDIC_CSR_NARGS CORDIC_CSR_NARGS_Msk /*!< Number of arguments in RDATA register */ +#define CORDIC_CSR_RESSIZE_Pos (21U) +#define CORDIC_CSR_RESSIZE_Msk (0x1UL << CORDIC_CSR_RESSIZE_Pos) /*!< 0x00200000 */ +#define CORDIC_CSR_RESSIZE CORDIC_CSR_RESSIZE_Msk /*!< Width of output data */ +#define CORDIC_CSR_ARGSIZE_Pos (22U) +#define CORDIC_CSR_ARGSIZE_Msk (0x1UL << CORDIC_CSR_ARGSIZE_Pos) /*!< 0x00400000 */ +#define CORDIC_CSR_ARGSIZE CORDIC_CSR_ARGSIZE_Msk /*!< Width of input data */ +#define CORDIC_CSR_RRDY_Pos (31U) +#define CORDIC_CSR_RRDY_Msk (0x1UL << CORDIC_CSR_RRDY_Pos) /*!< 0x80000000 */ +#define CORDIC_CSR_RRDY CORDIC_CSR_RRDY_Msk /*!< Result Ready Flag */ + +/******************* Bit definition for CORDIC_WDATA register ***************/ +#define CORDIC_WDATA_ARG_Pos (0U) +#define CORDIC_WDATA_ARG_Msk (0xFFFFFFFFUL << CORDIC_WDATA_ARG_Pos) /*!< 0xFFFFFFFF */ +#define CORDIC_WDATA_ARG CORDIC_WDATA_ARG_Msk /*!< Input Argument */ + +/******************* Bit definition for CORDIC_RDATA register ***************/ +#define CORDIC_RDATA_RES_Pos (0U) +#define CORDIC_RDATA_RES_Msk (0xFFFFFFFFUL << CORDIC_RDATA_RES_Pos) /*!< 0xFFFFFFFF */ +#define CORDIC_RDATA_RES CORDIC_RDATA_RES_Msk /*!< Output Result */ + +/******************************************************************************/ +/* */ +/* CRC calculation unit */ +/* */ +/******************************************************************************/ +/******************* Bit definition for CRC_DR register *********************/ +#define CRC_DR_DR_Pos (0U) +#define CRC_DR_DR_Msk (0xFFFFFFFFUL << CRC_DR_DR_Pos) /*!< 0xFFFFFFFF */ +#define CRC_DR_DR CRC_DR_DR_Msk /*!< Data register bits */ + +/******************* Bit definition for CRC_IDR register ********************/ +#define CRC_IDR_IDR_Pos (0U) +#define CRC_IDR_IDR_Msk (0xFFFFFFFFUL << CRC_IDR_IDR_Pos) /*!< 0xFFFFFFFF */ +#define CRC_IDR_IDR CRC_IDR_IDR_Msk /*!< General-purpose 32-bits data register bits */ + +/******************** Bit definition for CRC_CR register ********************/ +#define CRC_CR_RESET_Pos (0U) +#define CRC_CR_RESET_Msk (0x1UL << CRC_CR_RESET_Pos) /*!< 0x00000001 */ +#define CRC_CR_RESET CRC_CR_RESET_Msk /*!< RESET the CRC computation unit bit */ +#define CRC_CR_POLYSIZE_Pos (3U) +#define CRC_CR_POLYSIZE_Msk (0x3UL << CRC_CR_POLYSIZE_Pos) /*!< 0x00000018 */ +#define CRC_CR_POLYSIZE CRC_CR_POLYSIZE_Msk /*!< Polynomial size bits */ +#define CRC_CR_POLYSIZE_0 (0x1UL << CRC_CR_POLYSIZE_Pos) /*!< 0x00000008 */ +#define CRC_CR_POLYSIZE_1 (0x2UL << CRC_CR_POLYSIZE_Pos) /*!< 0x00000010 */ +#define CRC_CR_REV_IN_Pos (5U) +#define CRC_CR_REV_IN_Msk (0x3UL << CRC_CR_REV_IN_Pos) /*!< 0x00000060 */ +#define CRC_CR_REV_IN CRC_CR_REV_IN_Msk /*!< REV_IN Reverse Input Data bits */ +#define CRC_CR_REV_IN_0 (0x1UL << CRC_CR_REV_IN_Pos) /*!< 0x00000020 */ +#define CRC_CR_REV_IN_1 (0x2UL << CRC_CR_REV_IN_Pos) /*!< 0x00000040 */ +#define CRC_CR_REV_OUT_Pos (7U) +#define CRC_CR_REV_OUT_Msk (0x1UL << CRC_CR_REV_OUT_Pos) /*!< 0x00000080 */ +#define CRC_CR_REV_OUT CRC_CR_REV_OUT_Msk /*!< REV_OUT Reverse Output Data bits */ + +/******************* Bit definition for CRC_INIT register *******************/ +#define CRC_INIT_INIT_Pos (0U) +#define CRC_INIT_INIT_Msk (0xFFFFFFFFUL << CRC_INIT_INIT_Pos) /*!< 0xFFFFFFFF */ +#define CRC_INIT_INIT CRC_INIT_INIT_Msk /*!< Initial CRC value bits */ + +/******************* Bit definition for CRC_POL register ********************/ +#define CRC_POL_POL_Pos (0U) +#define CRC_POL_POL_Msk (0xFFFFFFFFUL << CRC_POL_POL_Pos) /*!< 0xFFFFFFFF */ +#define CRC_POL_POL CRC_POL_POL_Msk /*!< Coefficients of the polynomial */ + + +/******************************************************************************/ +/* */ +/* CRS Clock Recovery System */ +/******************************************************************************/ +/******************* Bit definition for CRS_CR register *********************/ +#define CRS_CR_SYNCOKIE_Pos (0U) +#define CRS_CR_SYNCOKIE_Msk (0x1UL << CRS_CR_SYNCOKIE_Pos) /*!< 0x00000001 */ +#define CRS_CR_SYNCOKIE CRS_CR_SYNCOKIE_Msk /*!< SYNC event OK interrupt enable */ +#define CRS_CR_SYNCWARNIE_Pos (1U) +#define CRS_CR_SYNCWARNIE_Msk (0x1UL << CRS_CR_SYNCWARNIE_Pos) /*!< 0x00000002 */ +#define CRS_CR_SYNCWARNIE CRS_CR_SYNCWARNIE_Msk /*!< SYNC warning interrupt enable */ +#define CRS_CR_ERRIE_Pos (2U) +#define CRS_CR_ERRIE_Msk (0x1UL << CRS_CR_ERRIE_Pos) /*!< 0x00000004 */ +#define CRS_CR_ERRIE CRS_CR_ERRIE_Msk /*!< SYNC error or trimming error interrupt enable */ +#define CRS_CR_ESYNCIE_Pos (3U) +#define CRS_CR_ESYNCIE_Msk (0x1UL << CRS_CR_ESYNCIE_Pos) /*!< 0x00000008 */ +#define CRS_CR_ESYNCIE CRS_CR_ESYNCIE_Msk /*!< Expected SYNC interrupt enable */ +#define CRS_CR_CEN_Pos (5U) +#define CRS_CR_CEN_Msk (0x1UL << CRS_CR_CEN_Pos) /*!< 0x00000020 */ +#define CRS_CR_CEN CRS_CR_CEN_Msk /*!< Frequency error counter enable */ +#define CRS_CR_AUTOTRIMEN_Pos (6U) +#define CRS_CR_AUTOTRIMEN_Msk (0x1UL << CRS_CR_AUTOTRIMEN_Pos) /*!< 0x00000040 */ +#define CRS_CR_AUTOTRIMEN CRS_CR_AUTOTRIMEN_Msk /*!< Automatic trimming enable */ +#define CRS_CR_SWSYNC_Pos (7U) +#define CRS_CR_SWSYNC_Msk (0x1UL << CRS_CR_SWSYNC_Pos) /*!< 0x00000080 */ +#define CRS_CR_SWSYNC CRS_CR_SWSYNC_Msk /*!< Generate software SYNC event */ +#define CRS_CR_TRIM_Pos (8U) +#define CRS_CR_TRIM_Msk (0x3FUL << CRS_CR_TRIM_Pos) /*!< 0x00003F00 */ +#define CRS_CR_TRIM CRS_CR_TRIM_Msk /*!< HSI48 oscillator smooth trimming */ + +/******************* Bit definition for CRS_CFGR register *********************/ +#define CRS_CFGR_RELOAD_Pos (0U) +#define CRS_CFGR_RELOAD_Msk (0xFFFFUL << CRS_CFGR_RELOAD_Pos) /*!< 0x0000FFFF */ +#define CRS_CFGR_RELOAD CRS_CFGR_RELOAD_Msk /*!< Counter reload value */ +#define CRS_CFGR_FELIM_Pos (16U) +#define CRS_CFGR_FELIM_Msk (0xFFUL << CRS_CFGR_FELIM_Pos) /*!< 0x00FF0000 */ +#define CRS_CFGR_FELIM CRS_CFGR_FELIM_Msk /*!< Frequency error limit */ +#define CRS_CFGR_SYNCDIV_Pos (24U) +#define CRS_CFGR_SYNCDIV_Msk (0x7UL << CRS_CFGR_SYNCDIV_Pos) /*!< 0x07000000 */ +#define CRS_CFGR_SYNCDIV CRS_CFGR_SYNCDIV_Msk /*!< SYNC divider */ +#define CRS_CFGR_SYNCDIV_0 (0x1UL << CRS_CFGR_SYNCDIV_Pos) /*!< 0x01000000 */ +#define CRS_CFGR_SYNCDIV_1 (0x2UL << CRS_CFGR_SYNCDIV_Pos) /*!< 0x02000000 */ +#define CRS_CFGR_SYNCDIV_2 (0x4UL << CRS_CFGR_SYNCDIV_Pos) /*!< 0x04000000 */ +#define CRS_CFGR_SYNCSRC_Pos (28U) +#define CRS_CFGR_SYNCSRC_Msk (0x3UL << CRS_CFGR_SYNCSRC_Pos) /*!< 0x30000000 */ +#define CRS_CFGR_SYNCSRC CRS_CFGR_SYNCSRC_Msk /*!< SYNC signal source selection */ +#define CRS_CFGR_SYNCSRC_0 (0x1UL << CRS_CFGR_SYNCSRC_Pos) /*!< 0x10000000 */ +#define CRS_CFGR_SYNCSRC_1 (0x2UL << CRS_CFGR_SYNCSRC_Pos) /*!< 0x20000000 */ +#define CRS_CFGR_SYNCPOL_Pos (31U) +#define CRS_CFGR_SYNCPOL_Msk (0x1UL << CRS_CFGR_SYNCPOL_Pos) /*!< 0x80000000 */ +#define CRS_CFGR_SYNCPOL CRS_CFGR_SYNCPOL_Msk /*!< SYNC polarity selection */ + +/******************* Bit definition for CRS_ISR register *********************/ +#define CRS_ISR_SYNCOKF_Pos (0U) +#define CRS_ISR_SYNCOKF_Msk (0x1UL << CRS_ISR_SYNCOKF_Pos) /*!< 0x00000001 */ +#define CRS_ISR_SYNCOKF CRS_ISR_SYNCOKF_Msk /*!< SYNC event OK flag */ +#define CRS_ISR_SYNCWARNF_Pos (1U) +#define CRS_ISR_SYNCWARNF_Msk (0x1UL << CRS_ISR_SYNCWARNF_Pos) /*!< 0x00000002 */ +#define CRS_ISR_SYNCWARNF CRS_ISR_SYNCWARNF_Msk /*!< SYNC warning flag */ +#define CRS_ISR_ERRF_Pos (2U) +#define CRS_ISR_ERRF_Msk (0x1UL << CRS_ISR_ERRF_Pos) /*!< 0x00000004 */ +#define CRS_ISR_ERRF CRS_ISR_ERRF_Msk /*!< Error flag */ +#define CRS_ISR_ESYNCF_Pos (3U) +#define CRS_ISR_ESYNCF_Msk (0x1UL << CRS_ISR_ESYNCF_Pos) /*!< 0x00000008 */ +#define CRS_ISR_ESYNCF CRS_ISR_ESYNCF_Msk /*!< Expected SYNC flag */ +#define CRS_ISR_SYNCERR_Pos (8U) +#define CRS_ISR_SYNCERR_Msk (0x1UL << CRS_ISR_SYNCERR_Pos) /*!< 0x00000100 */ +#define CRS_ISR_SYNCERR CRS_ISR_SYNCERR_Msk /*!< SYNC error */ +#define CRS_ISR_SYNCMISS_Pos (9U) +#define CRS_ISR_SYNCMISS_Msk (0x1UL << CRS_ISR_SYNCMISS_Pos) /*!< 0x00000200 */ +#define CRS_ISR_SYNCMISS CRS_ISR_SYNCMISS_Msk /*!< SYNC missed */ +#define CRS_ISR_TRIMOVF_Pos (10U) +#define CRS_ISR_TRIMOVF_Msk (0x1UL << CRS_ISR_TRIMOVF_Pos) /*!< 0x00000400 */ +#define CRS_ISR_TRIMOVF CRS_ISR_TRIMOVF_Msk /*!< Trimming overflow or underflow */ +#define CRS_ISR_FEDIR_Pos (15U) +#define CRS_ISR_FEDIR_Msk (0x1UL << CRS_ISR_FEDIR_Pos) /*!< 0x00008000 */ +#define CRS_ISR_FEDIR CRS_ISR_FEDIR_Msk /*!< Frequency error direction */ +#define CRS_ISR_FECAP_Pos (16U) +#define CRS_ISR_FECAP_Msk (0xFFFFUL << CRS_ISR_FECAP_Pos) /*!< 0xFFFF0000 */ +#define CRS_ISR_FECAP CRS_ISR_FECAP_Msk /*!< Frequency error capture */ + +/******************* Bit definition for CRS_ICR register *********************/ +#define CRS_ICR_SYNCOKC_Pos (0U) +#define CRS_ICR_SYNCOKC_Msk (0x1UL << CRS_ICR_SYNCOKC_Pos) /*!< 0x00000001 */ +#define CRS_ICR_SYNCOKC CRS_ICR_SYNCOKC_Msk /*!< SYNC event OK clear flag */ +#define CRS_ICR_SYNCWARNC_Pos (1U) +#define CRS_ICR_SYNCWARNC_Msk (0x1UL << CRS_ICR_SYNCWARNC_Pos) /*!< 0x00000002 */ +#define CRS_ICR_SYNCWARNC CRS_ICR_SYNCWARNC_Msk /*!< SYNC warning clear flag */ +#define CRS_ICR_ERRC_Pos (2U) +#define CRS_ICR_ERRC_Msk (0x1UL << CRS_ICR_ERRC_Pos) /*!< 0x00000004 */ +#define CRS_ICR_ERRC CRS_ICR_ERRC_Msk /*!< Error clear flag */ +#define CRS_ICR_ESYNCC_Pos (3U) +#define CRS_ICR_ESYNCC_Msk (0x1UL << CRS_ICR_ESYNCC_Pos) /*!< 0x00000008 */ +#define CRS_ICR_ESYNCC CRS_ICR_ESYNCC_Msk /*!< Expected SYNC clear flag */ + + +/******************************************************************************/ +/* */ +/* RNG */ +/* */ +/******************************************************************************/ +/******************** Bits definition for RNG_CR register *******************/ +#define RNG_CR_RNGEN_Pos (2U) +#define RNG_CR_RNGEN_Msk (0x1UL << RNG_CR_RNGEN_Pos) /*!< 0x00000004 */ +#define RNG_CR_RNGEN RNG_CR_RNGEN_Msk +#define RNG_CR_IE_Pos (3U) +#define RNG_CR_IE_Msk (0x1UL << RNG_CR_IE_Pos) /*!< 0x00000008 */ +#define RNG_CR_IE RNG_CR_IE_Msk +#define RNG_CR_CED_Pos (5U) +#define RNG_CR_CED_Msk (0x1UL << RNG_CR_CED_Pos) /*!< 0x00000020 */ +#define RNG_CR_CED RNG_CR_CED_Msk +#define RNG_CR_ARDIS_Pos (7U) +#define RNG_CR_ARDIS_Msk (0x1UL << RNG_CR_ARDIS_Pos) +#define RNG_CR_ARDIS RNG_CR_ARDIS_Msk +#define RNG_CR_RNG_CONFIG3_Pos (8U) +#define RNG_CR_RNG_CONFIG3_Msk (0xFUL << RNG_CR_RNG_CONFIG3_Pos) +#define RNG_CR_RNG_CONFIG3 RNG_CR_RNG_CONFIG3_Msk +#define RNG_CR_NISTC_Pos (12U) +#define RNG_CR_NISTC_Msk (0x1UL << RNG_CR_NISTC_Pos) +#define RNG_CR_NISTC RNG_CR_NISTC_Msk +#define RNG_CR_RNG_CONFIG2_Pos (13U) +#define RNG_CR_RNG_CONFIG2_Msk (0x7UL << RNG_CR_RNG_CONFIG2_Pos) +#define RNG_CR_RNG_CONFIG2 RNG_CR_RNG_CONFIG2_Msk +#define RNG_CR_CLKDIV_Pos (16U) +#define RNG_CR_CLKDIV_Msk (0xFUL << RNG_CR_CLKDIV_Pos) +#define RNG_CR_CLKDIV RNG_CR_CLKDIV_Msk +#define RNG_CR_CLKDIV_0 (0x1UL << RNG_CR_CLKDIV_Pos) /*!< 0x00010000 */ +#define RNG_CR_CLKDIV_1 (0x2UL << RNG_CR_CLKDIV_Pos) /*!< 0x00020000 */ +#define RNG_CR_CLKDIV_2 (0x4UL << RNG_CR_CLKDIV_Pos) /*!< 0x00040000 */ +#define RNG_CR_CLKDIV_3 (0x8UL << RNG_CR_CLKDIV_Pos) /*!< 0x00080000 */ +#define RNG_CR_RNG_CONFIG1_Pos (20U) +#define RNG_CR_RNG_CONFIG1_Msk (0x3FUL << RNG_CR_RNG_CONFIG1_Pos) +#define RNG_CR_RNG_CONFIG1 RNG_CR_RNG_CONFIG1_Msk +#define RNG_CR_CONDRST_Pos (30U) +#define RNG_CR_CONDRST_Msk (0x1UL << RNG_CR_CONDRST_Pos) +#define RNG_CR_CONDRST RNG_CR_CONDRST_Msk +#define RNG_CR_CONFIGLOCK_Pos (31U) +#define RNG_CR_CONFIGLOCK_Msk (0x1UL << RNG_CR_CONFIGLOCK_Pos) +#define RNG_CR_CONFIGLOCK RNG_CR_CONFIGLOCK_Msk + +/******************** Bits definition for RNG_SR register *******************/ +#define RNG_SR_DRDY_Pos (0U) +#define RNG_SR_DRDY_Msk (0x1UL << RNG_SR_DRDY_Pos) /*!< 0x00000001 */ +#define RNG_SR_DRDY RNG_SR_DRDY_Msk +#define RNG_SR_CECS_Pos (1U) +#define RNG_SR_CECS_Msk (0x1UL << RNG_SR_CECS_Pos) /*!< 0x00000002 */ +#define RNG_SR_CECS RNG_SR_CECS_Msk +#define RNG_SR_SECS_Pos (2U) +#define RNG_SR_SECS_Msk (0x1UL << RNG_SR_SECS_Pos) /*!< 0x00000004 */ +#define RNG_SR_SECS RNG_SR_SECS_Msk +#define RNG_SR_CEIS_Pos (5U) +#define RNG_SR_CEIS_Msk (0x1UL << RNG_SR_CEIS_Pos) /*!< 0x00000020 */ +#define RNG_SR_CEIS RNG_SR_CEIS_Msk +#define RNG_SR_SEIS_Pos (6U) +#define RNG_SR_SEIS_Msk (0x1UL << RNG_SR_SEIS_Pos) /*!< 0x00000040 */ +#define RNG_SR_SEIS RNG_SR_SEIS_Msk + +/******************** Bits definition for RNG_HTCR register *******************/ +#define RNG_HTCR_HTCFG_Pos (0U) +#define RNG_HTCR_HTCFG_Msk (0xFFFFFFFFUL << RNG_HTCR_HTCFG_Pos) /*!< 0xFFFFFFFF */ +#define RNG_HTCR_HTCFG RNG_HTCR_HTCFG_Msk + +/******************************************************************************/ +/* */ +/* Digital to Analog Converter */ +/* */ +/******************************************************************************/ +#define DAC_CHANNEL2_SUPPORT /*!< DAC feature available only on specific devices: DAC channel 2 available */ + +/******************** Bit definition for DAC_CR register ********************/ +#define DAC_CR_EN1_Pos (0U) +#define DAC_CR_EN1_Msk (0x1UL << DAC_CR_EN1_Pos) /*!< 0x00000001 */ +#define DAC_CR_EN1 DAC_CR_EN1_Msk /*!*/ +#define DAC_CR_CEN1_Pos (14U) +#define DAC_CR_CEN1_Msk (0x1UL << DAC_CR_CEN1_Pos) /*!< 0x00004000 */ +#define DAC_CR_CEN1 DAC_CR_CEN1_Msk /*!*/ +#define DAC_CR_EN2_Pos (16U) +#define DAC_CR_EN2_Msk (0x1UL << DAC_CR_EN2_Pos) /*!< 0x00010000 */ +#define DAC_CR_EN2 DAC_CR_EN2_Msk /*!*/ +#define DAC_CR_CEN2_Pos (30U) +#define DAC_CR_CEN2_Msk (0x1UL << DAC_CR_CEN2_Pos) /*!< 0x40000000 */ +#define DAC_CR_CEN2 DAC_CR_CEN2_Msk /*!*/ + +/***************** Bit definition for DAC_SWTRIGR register ******************/ +#define DAC_SWTRIGR_SWTRIG1_Pos (0U) +#define DAC_SWTRIGR_SWTRIG1_Msk (0x1UL << DAC_SWTRIGR_SWTRIG1_Pos) /*!< 0x00000001 */ +#define DAC_SWTRIGR_SWTRIG1 DAC_SWTRIGR_SWTRIG1_Msk /*!> 1U) /*!< FLASH Bank Size */ +#define FLASH_SECTOR_SIZE 0x2000U /*!< Flash Sector Size: 8 KB */ + +/******************* Bits definition for FLASH_ACR register *****************/ +#define FLASH_ACR_LATENCY_Pos (0U) +#define FLASH_ACR_LATENCY_Msk (0xFUL << FLASH_ACR_LATENCY_Pos) /*!< 0x0000000F */ +#define FLASH_ACR_LATENCY FLASH_ACR_LATENCY_Msk /*!< Latency */ +#define FLASH_ACR_LATENCY_0WS (0x00000000U) +#define FLASH_ACR_LATENCY_1WS (0x00000001U) +#define FLASH_ACR_LATENCY_2WS (0x00000002U) +#define FLASH_ACR_LATENCY_3WS (0x00000003U) +#define FLASH_ACR_LATENCY_4WS (0x00000004U) +#define FLASH_ACR_LATENCY_5WS (0x00000005U) +#define FLASH_ACR_LATENCY_6WS (0x00000006U) +#define FLASH_ACR_LATENCY_7WS (0x00000007U) +#define FLASH_ACR_LATENCY_8WS (0x00000008U) +#define FLASH_ACR_LATENCY_9WS (0x00000009U) +#define FLASH_ACR_LATENCY_10WS (0x0000000AU) +#define FLASH_ACR_LATENCY_11WS (0x0000000BU) +#define FLASH_ACR_LATENCY_12WS (0x0000000CU) +#define FLASH_ACR_LATENCY_13WS (0x0000000DU) +#define FLASH_ACR_LATENCY_14WS (0x0000000EU) +#define FLASH_ACR_LATENCY_15WS (0x0000000FU) +#define FLASH_ACR_WRHIGHFREQ_Pos (4U) +#define FLASH_ACR_WRHIGHFREQ_Msk (0x3UL << FLASH_ACR_WRHIGHFREQ_Pos) /*!< 0x00000030 */ +#define FLASH_ACR_WRHIGHFREQ FLASH_ACR_WRHIGHFREQ_Msk /*!< Flash signal delay */ +#define FLASH_ACR_WRHIGHFREQ_0 (0x1UL << FLASH_ACR_WRHIGHFREQ_Pos) /*!< 0x00000010 */ +#define FLASH_ACR_WRHIGHFREQ_1 (0x2UL << FLASH_ACR_WRHIGHFREQ_Pos) /*!< 0x00000020 */ +#define FLASH_ACR_PRFTEN_Pos (8U) +#define FLASH_ACR_PRFTEN_Msk (0x1UL << FLASH_ACR_PRFTEN_Pos) /*!< 0x00000100 */ +#define FLASH_ACR_PRFTEN FLASH_ACR_PRFTEN_Msk /*!< Prefetch enable */ + +/******************* Bits definition for FLASH_OPSR register ***************/ +#define FLASH_OPSR_ADDR_OP_Pos (0U) +#define FLASH_OPSR_ADDR_OP_Msk (0xFFFFFUL << FLASH_OPSR_ADDR_OP_Pos) /*!< 0x000FFFFF */ +#define FLASH_OPSR_ADDR_OP FLASH_OPSR_ADDR_OP_Msk /*!< Interrupted operation address */ +#define FLASH_OPSR_DATA_OP_Pos (21U) +#define FLASH_OPSR_DATA_OP_Msk (0x1UL << FLASH_OPSR_DATA_OP_Pos) /*!< 0x00200000 */ +#define FLASH_OPSR_DATA_OP FLASH_OPSR_DATA_OP_Msk /*!< Operation in Flash high-cycle data area interrupted */ +#define FLASH_OPSR_BK_OP_Pos (22U) +#define FLASH_OPSR_BK_OP_Msk (0x1UL << FLASH_OPSR_BK_OP_Pos) /*!< 0x00400000 */ +#define FLASH_OPSR_BK_OP FLASH_OPSR_BK_OP_Msk /*!< Interrupted operation bank */ +#define FLASH_OPSR_SYSF_OP_Pos (23U) +#define FLASH_OPSR_SYSF_OP_Msk (0x1UL << FLASH_OPSR_SYSF_OP_Pos) /*!< 0x00800000 */ +#define FLASH_OPSR_SYSF_OP FLASH_OPSR_SYSF_OP_Msk /*!< Operation in System Flash interrupted */ +#define FLASH_OPSR_OTP_OP_Pos (24U) +#define FLASH_OPSR_OTP_OP_Msk (0x1UL << FLASH_OPSR_OTP_OP_Pos) /*!< 0x01000000 */ +#define FLASH_OPSR_OTP_OP FLASH_OPSR_OTP_OP_Msk /*!< Operation in OTP area interrupted */ +#define FLASH_OPSR_CODE_OP_Pos (29U) +#define FLASH_OPSR_CODE_OP_Msk (0x7UL << FLASH_OPSR_CODE_OP_Pos) /*!< 0xE0000000 */ +#define FLASH_OPSR_CODE_OP FLASH_OPSR_CODE_OP_Msk /*!< Flash memory operation code */ +#define FLASH_OPSR_CODE_OP_0 (0x1UL << FLASH_OPSR_CODE_OP_Pos) /*!< 0x20000000 */ +#define FLASH_OPSR_CODE_OP_1 (0x2UL << FLASH_OPSR_CODE_OP_Pos) /*!< 0x40000000 */ +#define FLASH_OPSR_CODE_OP_2 (0x4UL << FLASH_OPSR_CODE_OP_Pos) /*!< 0x80000000 */ + +/******************* Bits definition for FLASH_OPTCR register *******************/ +#define FLASH_OPTCR_OPTLOCK_Pos (0U) +#define FLASH_OPTCR_OPTLOCK_Msk (0x1UL << FLASH_OPTCR_OPTLOCK_Pos) /*!< 0x00000001 */ +#define FLASH_OPTCR_OPTLOCK FLASH_OPTCR_OPTLOCK_Msk /*!< FLASH_OPTCR lock option configuration bit */ +#define FLASH_OPTCR_OPTSTART_Pos (1U) +#define FLASH_OPTCR_OPTSTART_Msk (0x1UL << FLASH_OPTCR_OPTSTART_Pos) /*!< 0x00000002 */ +#define FLASH_OPTCR_OPTSTART FLASH_OPTCR_OPTSTART_Msk /*!< Option byte start change option configuration bit */ +#define FLASH_OPTCR_SWAP_BANK_Pos (31U) +#define FLASH_OPTCR_SWAP_BANK_Msk (0x1UL << FLASH_OPTCR_SWAP_BANK_Pos) /*!< 0x80000000 */ +#define FLASH_OPTCR_SWAP_BANK FLASH_OPTCR_SWAP_BANK_Msk /*!< Bank swapping option configuration bit */ + +/******************* Bits definition for FLASH_SR register ***********************/ +#define FLASH_SR_BSY_Pos (0U) +#define FLASH_SR_BSY_Msk (0x1UL << FLASH_SR_BSY_Pos) /*!< 0x00000001 */ +#define FLASH_SR_BSY FLASH_SR_BSY_Msk /*!< Busy flag */ +#define FLASH_SR_WBNE_Pos (1U) +#define FLASH_SR_WBNE_Msk (0x1UL << FLASH_SR_WBNE_Pos) /*!< 0x00000002 */ +#define FLASH_SR_WBNE FLASH_SR_WBNE_Msk /*!< Write buffer not empty flag */ +#define FLASH_SR_DBNE_Pos (3U) +#define FLASH_SR_DBNE_Msk (0x1UL << FLASH_SR_DBNE_Pos) /*!< 0x00000008 */ +#define FLASH_SR_DBNE FLASH_SR_DBNE_Msk /*!< Data buffer not empty flag */ +#define FLASH_SR_EOP_Pos (16U) +#define FLASH_SR_EOP_Msk (0x1UL << FLASH_SR_EOP_Pos) /*!< 0x00010000 */ +#define FLASH_SR_EOP FLASH_SR_EOP_Msk /*!< End-of-program flag */ +#define FLASH_SR_WRPERR_Pos (17U) +#define FLASH_SR_WRPERR_Msk (0x1UL << FLASH_SR_WRPERR_Pos) /*!< 0x00020000 */ +#define FLASH_SR_WRPERR FLASH_SR_WRPERR_Msk /*!< Write protection error flag */ +#define FLASH_SR_PGSERR_Pos (18U) +#define FLASH_SR_PGSERR_Msk (0x1UL << FLASH_SR_PGSERR_Pos) /*!< 0x00040000 */ +#define FLASH_SR_PGSERR FLASH_SR_PGSERR_Msk /*!< Programming sequence error flag */ +#define FLASH_SR_STRBERR_Pos (19U) +#define FLASH_SR_STRBERR_Msk (0x1UL << FLASH_SR_STRBERR_Pos) /*!< 0x00080000 */ +#define FLASH_SR_STRBERR FLASH_SR_STRBERR_Msk /*!< Strobe error flag */ +#define FLASH_SR_INCERR_Pos (20U) +#define FLASH_SR_INCERR_Msk (0x1UL << FLASH_SR_INCERR_Pos) /*!< 0x00100000 */ +#define FLASH_SR_INCERR FLASH_SR_INCERR_Msk /*!< Inconsistency error flag */ +#define FLASH_SR_OBKERR_Pos (21U) +#define FLASH_SR_OBKERR_Msk (0x1UL << FLASH_SR_OBKERR_Pos) /*!< 0x00200000 */ +#define FLASH_SR_OBKERR FLASH_SR_OBKERR_Msk /*!< OBK general error flag */ +#define FLASH_SR_OBKWERR_Pos (22U) +#define FLASH_SR_OBKWERR_Msk (0x1UL << FLASH_SR_OBKWERR_Pos) /*!< 0x00400000 */ +#define FLASH_SR_OBKWERR FLASH_SR_OBKWERR_Msk /*!< OBK write error flag */ +#define FLASH_SR_OPTCHANGEERR_Pos (23U) +#define FLASH_SR_OPTCHANGEERR_Msk (0x1UL << FLASH_SR_OPTCHANGEERR_Pos) /*!< 0x00800000 */ +#define FLASH_SR_OPTCHANGEERR FLASH_SR_OPTCHANGEERR_Msk /*!< Option byte change error flag */ + +/******************* Bits definition for FLASH_CR register ***********************/ +#define FLASH_CR_LOCK_Pos (0U) +#define FLASH_CR_LOCK_Msk (0x1UL << FLASH_CR_LOCK_Pos) /*!< 0x00000001 */ +#define FLASH_CR_LOCK FLASH_CR_LOCK_Msk /*!< Configuration lock bit */ +#define FLASH_CR_PG_Pos (1U) +#define FLASH_CR_PG_Msk (0x1UL << FLASH_CR_PG_Pos) /*!< 0x00000002 */ +#define FLASH_CR_PG FLASH_CR_PG_Msk /*!< Programming control bit */ +#define FLASH_CR_SER_Pos (2U) +#define FLASH_CR_SER_Msk (0x1UL << FLASH_CR_SER_Pos) /*!< 0x00000004 */ +#define FLASH_CR_SER FLASH_CR_SER_Msk /*!< Sector erase request */ +#define FLASH_CR_BER_Pos (3U) +#define FLASH_CR_BER_Msk (0x1UL << FLASH_CR_BER_Pos) /*!< 0x00000008 */ +#define FLASH_CR_BER FLASH_CR_BER_Msk /*!< Bank erase request */ +#define FLASH_CR_FW_Pos (4U) +#define FLASH_CR_FW_Msk (0x1UL << FLASH_CR_FW_Pos) /*!< 0x00000010 */ +#define FLASH_CR_FW FLASH_CR_FW_Msk /*!< Write forcing control bit */ +#define FLASH_CR_START_Pos (5U) +#define FLASH_CR_START_Msk (0x1UL << FLASH_CR_START_Pos) /*!< 0x00000020 */ +#define FLASH_CR_START FLASH_CR_START_Msk /*!< Erase start control bit */ +#define FLASH_CR_SNB_Pos (6U) +#define FLASH_CR_SNB_Msk (0x7FUL << FLASH_CR_SNB_Pos) /*!< 0x00001FC0 */ +#define FLASH_CR_SNB FLASH_CR_SNB_Msk /*!< Sector erase selection number */ +#define FLASH_CR_SNB_0 (0x01UL << FLASH_CR_SNB_Pos) /*!< 0x00000040 */ +#define FLASH_CR_SNB_1 (0x02UL << FLASH_CR_SNB_Pos) /*!< 0x00000080 */ +#define FLASH_CR_SNB_2 (0x04UL << FLASH_CR_SNB_Pos) /*!< 0x00000100 */ +#define FLASH_CR_SNB_3 (0x08UL << FLASH_CR_SNB_Pos) /*!< 0x00000200 */ +#define FLASH_CR_SNB_4 (0x10UL << FLASH_CR_SNB_Pos) /*!< 0x00000400 */ +#define FLASH_CR_SNB_5 (0x20UL << FLASH_CR_SNB_Pos) /*!< 0x00000800 */ +#define FLASH_CR_SNB_6 (0x40UL << FLASH_CR_SNB_Pos) /*!< 0x00001000 */ +#define FLASH_CR_MER_Pos (15U) +#define FLASH_CR_MER_Msk (0x1UL << FLASH_CR_MER_Pos) /*!< 0x00008000 */ +#define FLASH_CR_MER FLASH_CR_MER_Msk /*!< Mass erase */ +#define FLASH_CR_EOPIE_Pos (16U) +#define FLASH_CR_EOPIE_Msk (0x1UL << FLASH_CR_EOPIE_Pos) /*!< 0x00010000 */ +#define FLASH_CR_EOPIE FLASH_CR_EOPIE_Msk /*!< End-of-operation interrupt control bit */ +#define FLASH_CR_WRPERRIE_Pos (17U) +#define FLASH_CR_WRPERRIE_Msk (0x1UL << FLASH_CR_WRPERRIE_Pos) /*!< 0x00020000 */ +#define FLASH_CR_WRPERRIE FLASH_CR_WRPERRIE_Msk /*!< Write protection error interrupt enable bit */ +#define FLASH_CR_PGSERRIE_Pos (18U) +#define FLASH_CR_PGSERRIE_Msk (0x1UL << FLASH_CR_PGSERRIE_Pos) /*!< 0x00040000 */ +#define FLASH_CR_PGSERRIE FLASH_CR_PGSERRIE_Msk /*!< Programming sequence error interrupt enable bit */ +#define FLASH_CR_STRBERRIE_Pos (19U) +#define FLASH_CR_STRBERRIE_Msk (0x1UL << FLASH_CR_STRBERRIE_Pos) /*!< 0x00080000 */ +#define FLASH_CR_STRBERRIE FLASH_CR_STRBERRIE_Msk /*!< Strobe error interrupt enable bit */ +#define FLASH_CR_INCERRIE_Pos (20U) +#define FLASH_CR_INCERRIE_Msk (0x1UL << FLASH_CR_INCERRIE_Pos) /*!< 0x00100000 */ +#define FLASH_CR_INCERRIE FLASH_CR_INCERRIE_Msk /*!< Inconsistency error interrupt enable bit */ +#define FLASH_CR_OBKERRIE_Pos (21U) +#define FLASH_CR_OBKERRIE_Msk (0x1UL << FLASH_CR_OBKERRIE_Pos) /*!< 0x00200000 */ +#define FLASH_CR_OBKERRIE FLASH_CR_OBKERRIE_Msk /*!< OBK general error interrupt enable bitt */ +#define FLASH_CR_OBKWERRIE_Pos (22U) +#define FLASH_CR_OBKWERRIE_Msk (0x1UL << FLASH_CR_OBKWERRIE_Pos) /*!< 0x00400000 */ +#define FLASH_CR_OBKWERRIE FLASH_CR_OBKWERRIE_Msk /*!< OBK write error interrupt enable bit */ +#define FLASH_CR_OPTCHANGEERRIE_Pos (23U) +#define FLASH_CR_OPTCHANGEERRIE_Msk (0x1UL << FLASH_CR_OPTCHANGEERRIE_Pos) /*!< 0x00800000 */ +#define FLASH_CR_OPTCHANGEERRIE FLASH_CR_OPTCHANGEERRIE_Msk /*!< Option byte change error interrupt enable bit */ +#define FLASH_CR_INV_Pos (29U) +#define FLASH_CR_INV_Msk (0x1UL << FLASH_CR_INV_Pos) /*!< 0x20000000 */ +#define FLASH_CR_INV FLASH_CR_INV_Msk /*!< Flash Security State Invert */ +#define FLASH_CR_BKSEL_Pos (31U) +#define FLASH_CR_BKSEL_Msk (0x1UL << FLASH_CR_BKSEL_Pos) /*!< 0x10000000 */ +#define FLASH_CR_BKSEL FLASH_CR_BKSEL_Msk /*!< Bank selector */ + +/******************* Bits definition for FLASH_CCR register *******************/ +#define FLASH_CCR_CLR_EOP_Pos (16U) +#define FLASH_CCR_CLR_EOP_Msk (0x1UL << FLASH_CCR_CLR_EOP_Pos) /*!< 0x00010000 */ +#define FLASH_CCR_CLR_EOP FLASH_CCR_CLR_EOP_Msk /*!< EOP flag clear bit */ +#define FLASH_CCR_CLR_WRPERR_Pos (17U) +#define FLASH_CCR_CLR_WRPERR_Msk (0x1UL << FLASH_CCR_CLR_WRPERR_Pos) /*!< 0x00020000 */ +#define FLASH_CCR_CLR_WRPERR FLASH_CCR_CLR_WRPERR_Msk /*!< WRPERR flag clear bit */ +#define FLASH_CCR_CLR_PGSERR_Pos (18U) +#define FLASH_CCR_CLR_PGSERR_Msk (0x1UL << FLASH_CCR_CLR_PGSERR_Pos) /*!< 0x00040000 */ +#define FLASH_CCR_CLR_PGSERR FLASH_CCR_CLR_PGSERR_Msk /*!< PGSERR flag clear bit */ +#define FLASH_CCR_CLR_STRBERR_Pos (19U) +#define FLASH_CCR_CLR_STRBERR_Msk (0x1UL << FLASH_CCR_CLR_STRBERR_Pos) /*!< 0x00080000 */ +#define FLASH_CCR_CLR_STRBERR FLASH_CCR_CLR_STRBERR_Msk /*!< STRBERR flag clear bit */ +#define FLASH_CCR_CLR_INCERR_Pos (20U) +#define FLASH_CCR_CLR_INCERR_Msk (0x1UL << FLASH_CCR_CLR_INCERR_Pos) /*!< 0x00100000 */ +#define FLASH_CCR_CLR_INCERR FLASH_CCR_CLR_INCERR_Msk /*!< INCERR flag clear bit */ +#define FLASH_CCR_CLR_OBKERR_Pos (21U) +#define FLASH_CCR_CLR_OBKERR_Msk (0x1UL << FLASH_CCR_CLR_OBKERR_Pos) /*!< 0x00200000 */ +#define FLASH_CCR_CLR_OBKERR FLASH_CCR_CLR_OBKERR_Msk /*!< OBKERR flag clear bit */ +#define FLASH_CCR_CLR_OBKWERR_Pos (22U) +#define FLASH_CCR_CLR_OBKWERR_Msk (0x1UL << FLASH_CCR_CLR_OBKWERR_Pos) /*!< 0x00400000 */ +#define FLASH_CCR_CLR_OBKWERR FLASH_CCR_CLR_OBKWERR_Msk /*!< OBKWERR flag clear bit */ +#define FLASH_CCR_CLR_OPTCHANGEERR_Pos (23U) +#define FLASH_CCR_CLR_OPTCHANGEERR_Msk (0x1UL << FLASH_CCR_CLR_OPTCHANGEERR_Pos) /*!< 0x00800000 */ +#define FLASH_CCR_CLR_OPTCHANGEERR FLASH_CCR_CLR_OPTCHANGEERR_Msk /*!< Option byte change error clear bit */ + +/****************** Bits definition for FLASH_PRIVCFGR register ***********/ +#define FLASH_PRIVCFGR_SPRIV_Pos (0U) +#define FLASH_PRIVCFGR_SPRIV_Msk (0x1UL << FLASH_PRIVCFGR_SPRIV_Pos) /*!< 0x00000001 */ +#define FLASH_PRIVCFGR_SPRIV FLASH_PRIVCFGR_SPRIV_Msk /*!< Privilege protection for secure registers */ +#define FLASH_PRIVCFGR_NSPRIV_Pos (1U) +#define FLASH_PRIVCFGR_NSPRIV_Msk (0x1UL << FLASH_PRIVCFGR_NSPRIV_Pos) /*!< 0x00000002 */ +#define FLASH_PRIVCFGR_NSPRIV FLASH_PRIVCFGR_NSPRIV_Msk /*!< Privilege protection for non-secure registers */ + +/****************** Bits definition for FLASH_OBKCFGR register *****************/ +#define FLASH_OBKCFGR_LOCK_Pos (0U) +#define FLASH_OBKCFGR_LOCK_Msk (0x1UL << FLASH_OBKCFGR_LOCK_Pos) /*!< 0x00000001 */ +#define FLASH_OBKCFGR_LOCK FLASH_OBKCFGR_LOCK_Msk /*!< OBKCFGR lock */ +#define FLASH_OBKCFGR_SWAP_SECT_REQ_Pos (1U) +#define FLASH_OBKCFGR_SWAP_SECT_REQ_Msk (0x1UL << FLASH_OBKCFGR_SWAP_SECT_REQ_Pos) /*!< 0x00000002 */ +#define FLASH_OBKCFGR_SWAP_SECT_REQ FLASH_OBKCFGR_SWAP_SECT_REQ_Msk /*!< OBK swap sector request */ +#define FLASH_OBKCFGR_ALT_SECT_Pos (2U) +#define FLASH_OBKCFGR_ALT_SECT_Msk (0x1UL << FLASH_OBKCFGR_ALT_SECT_Pos) /*!< 0x00000004 */ +#define FLASH_OBKCFGR_ALT_SECT FLASH_OBKCFGR_ALT_SECT_Msk /*!< Alternate sector */ +#define FLASH_OBKCFGR_ALT_SECT_ERASE_Pos (3U) +#define FLASH_OBKCFGR_ALT_SECT_ERASE_Msk (0x1UL << FLASH_OBKCFGR_ALT_SECT_ERASE_Pos) /*!< 0x00000008 */ +#define FLASH_OBKCFGR_ALT_SECT_ERASE FLASH_OBKCFGR_ALT_SECT_ERASE_Msk /*!< Alternate sector erase */ +#define FLASH_OBKCFGR_SWAP_OFFSET_Pos (16U) +#define FLASH_OBKCFGR_SWAP_OFFSET_Msk (0x1FFUL << FLASH_OBKCFGR_SWAP_OFFSET_Pos) /*!< 0x01FF0000 */ +#define FLASH_OBKCFGR_SWAP_OFFSET FLASH_OBKCFGR_SWAP_OFFSET_Msk /*!< Swap offset */ + +/****************** Bits definition for FLASH_HDPEXTR register *****************/ +#define FLASH_HDPEXTR_HDP1_EXT_Pos (0U) +#define FLASH_HDPEXTR_HDP1_EXT_Msk (0x7FUL << FLASH_HDPEXTR_HDP1_EXT_Pos) /*!< 0x0000007F */ +#define FLASH_HDPEXTR_HDP1_EXT FLASH_HDPEXTR_HDP1_EXT_Msk /*!< HDP area extension in 8kB sectors in bank 1 */ +#define FLASH_HDPEXTR_HDP2_EXT_Pos (16U) +#define FLASH_HDPEXTR_HDP2_EXT_Msk (0x7FUL << FLASH_HDPEXTR_HDP2_EXT_Pos) /*!< 0x007F0000 */ +#define FLASH_HDPEXTR_HDP2_EXT FLASH_HDPEXTR_HDP2_EXT_Msk /*!< HDP area extension in 8kB sectors in bank 2 */ + +/******************* Bits definition for FLASH_OPTSR register ***************/ +#define FLASH_OPTSR_BOR_LEV_Pos (0U) +#define FLASH_OPTSR_BOR_LEV_Msk (0x3UL << FLASH_OPTSR_BOR_LEV_Pos) /*!< 0x00000003 */ +#define FLASH_OPTSR_BOR_LEV FLASH_OPTSR_BOR_LEV_Msk /*!< Brownout level option bit */ +#define FLASH_OPTSR_BOR_LEV_0 (0x1UL << FLASH_OPTSR_BOR_LEV_Pos) /*!< 0x00000001 */ +#define FLASH_OPTSR_BOR_LEV_1 (0x2UL << FLASH_OPTSR_BOR_LEV_Pos) /*!< 0x00000002 */ +#define FLASH_OPTSR_BORH_EN_Pos (2U) +#define FLASH_OPTSR_BORH_EN_Msk (0x1UL << FLASH_OPTSR_BORH_EN_Pos) /*!< 0x00000004 */ +#define FLASH_OPTSR_BORH_EN FLASH_OPTSR_BORH_EN_Msk /*!< Brownout high enable configuration bit */ +#define FLASH_OPTSR_IWDG_SW_Pos (3U) +#define FLASH_OPTSR_IWDG_SW_Msk (0x1UL << FLASH_OPTSR_IWDG_SW_Pos) /*!< 0x00000008 */ +#define FLASH_OPTSR_IWDG_SW FLASH_OPTSR_IWDG_SW_Msk /*!< IWDG control mode option bit */ +#define FLASH_OPTSR_WWDG_SW_Pos (4U) +#define FLASH_OPTSR_WWDG_SW_Msk (0x1UL << FLASH_OPTSR_WWDG_SW_Pos) /*!< 0x00000010 */ +#define FLASH_OPTSR_WWDG_SW FLASH_OPTSR_WWDG_SW_Msk /*!< WWDG control mode option bit */ +#define FLASH_OPTSR_NRST_STOP_Pos (6U) +#define FLASH_OPTSR_NRST_STOP_Msk (0x1UL << FLASH_OPTSR_NRST_STOP_Pos) /*!< 0x00000040 */ +#define FLASH_OPTSR_NRST_STOP FLASH_OPTSR_NRST_STOP_Msk /*!< Stop mode entry reset option bit */ +#define FLASH_OPTSR_NRST_STDBY_Pos (7U) +#define FLASH_OPTSR_NRST_STDBY_Msk (0x1UL << FLASH_OPTSR_NRST_STDBY_Pos) /*!< 0x00000080 */ +#define FLASH_OPTSR_NRST_STDBY FLASH_OPTSR_NRST_STDBY_Msk /*!< Standby mode entry reset option bit */ +#define FLASH_OPTSR_PRODUCT_STATE_Pos (8U) +#define FLASH_OPTSR_PRODUCT_STATE_Msk (0xFFUL << FLASH_OPTSR_PRODUCT_STATE_Pos) /*!< 0x0000FF00 */ +#define FLASH_OPTSR_PRODUCT_STATE FLASH_OPTSR_PRODUCT_STATE_Msk /*!< Life state code option byte */ +#define FLASH_OPTSR_IO_VDD_HSLV_Pos (16U) +#define FLASH_OPTSR_IO_VDD_HSLV_Msk (0x1UL << FLASH_OPTSR_IO_VDD_HSLV_Pos) /*!< 0x00010000 */ +#define FLASH_OPTSR_IO_VDD_HSLV FLASH_OPTSR_IO_VDD_HSLV_Msk /*!< VDD I/O high-speed at low-voltage option bit */ +#define FLASH_OPTSR_IO_VDDIO2_HSLV_Pos (17U) +#define FLASH_OPTSR_IO_VDDIO2_HSLV_Msk (0x1UL << FLASH_OPTSR_IO_VDDIO2_HSLV_Pos) /*!< 0x00020000 */ +#define FLASH_OPTSR_IO_VDDIO2_HSLV FLASH_OPTSR_IO_VDDIO2_HSLV_Msk /*!< VDDIO2 I/O high-speed at low-voltage option bit */ +#define FLASH_OPTSR_IWDG_STOP_Pos (20U) +#define FLASH_OPTSR_IWDG_STOP_Msk (0x1UL << FLASH_OPTSR_IWDG_STOP_Pos) /*!< 0x00100000 */ +#define FLASH_OPTSR_IWDG_STOP FLASH_OPTSR_IWDG_STOP_Msk /*!< Independent watchdog counter freeze in Stop mode */ +#define FLASH_OPTSR_IWDG_STDBY_Pos (21U) +#define FLASH_OPTSR_IWDG_STDBY_Msk (0x1UL << FLASH_OPTSR_IWDG_STDBY_Pos) /*!< 0x00200000 */ +#define FLASH_OPTSR_IWDG_STDBY FLASH_OPTSR_IWDG_STDBY_Msk /*!< Independent watchdog counter freeze in Standby mode */ +#define FLASH_OPTSR_BOOT_UBE_Pos (22U) +#define FLASH_OPTSR_BOOT_UBE_Msk (0xFFUL << FLASH_OPTSR_BOOT_UBE_Pos) /*!< 0x3FC00000 */ +#define FLASH_OPTSR_BOOT_UBE FLASH_OPTSR_BOOT_UBE_Msk /*!< Unique boot entry option byte */ +#define FLASH_OPTSR_SWAP_BANK_Pos (31U) +#define FLASH_OPTSR_SWAP_BANK_Msk (0x1UL << FLASH_OPTSR_SWAP_BANK_Pos) /*!< 0x80000000 */ +#define FLASH_OPTSR_SWAP_BANK FLASH_OPTSR_SWAP_BANK_Msk /*!< Bank swapping option bit */ + +/******************* Bits definition for FLASH_EPOCHR register ***************/ +#define FLASH_EPOCHR_EPOCH_Pos (0U) +#define FLASH_EPOCHR_EPOCH_Msk (0xFFFFFFUL << FLASH_EPOCHR_EPOCH_Pos) /*!< 0x00FFFFFF */ +#define FLASH_EPOCHR_EPOCH FLASH_EPOCHR_EPOCH_Msk /*!< EPOCH counter */ + +/******************* Bits definition for FLASH_OPTSR2 register ***************/ +#define FLASH_OPTSR2_SRAM1_3_RST_Pos (2U) +#define FLASH_OPTSR2_SRAM1_3_RST_Msk (0x1UL << FLASH_OPTSR2_SRAM1_3_RST_Pos) /*!< 0x00000004 */ +#define FLASH_OPTSR2_SRAM1_3_RST FLASH_OPTSR2_SRAM1_3_RST_Msk /*!< SRAM1 and SRAM3 erased when a system reset occurs */ +#define FLASH_OPTSR2_SRAM2_RST_Pos (3U) +#define FLASH_OPTSR2_SRAM2_RST_Msk (0x1UL << FLASH_OPTSR2_SRAM2_RST_Pos) /*!< 0x00000008 */ +#define FLASH_OPTSR2_SRAM2_RST FLASH_OPTSR2_SRAM2_RST_Msk /*!< SRAM2 erased when a system reset occurs*/ +#define FLASH_OPTSR2_BKPRAM_ECC_Pos (4U) +#define FLASH_OPTSR2_BKPRAM_ECC_Msk (0x1UL << FLASH_OPTSR2_BKPRAM_ECC_Pos) /*!< 0x00000010 */ +#define FLASH_OPTSR2_BKPRAM_ECC FLASH_OPTSR2_BKPRAM_ECC_Msk /*!< Backup RAM ECC detection and correction enable */ +#define FLASH_OPTSR2_SRAM3_ECC_Pos (5U) +#define FLASH_OPTSR2_SRAM3_ECC_Msk (0x1UL << FLASH_OPTSR2_SRAM3_ECC_Pos) /*!< 0x00000020 */ +#define FLASH_OPTSR2_SRAM3_ECC FLASH_OPTSR2_SRAM3_ECC_Msk /*!< SRAM3 ECC detection and correction enable */ +#define FLASH_OPTSR2_SRAM2_ECC_Pos (6U) +#define FLASH_OPTSR2_SRAM2_ECC_Msk (0x1UL << FLASH_OPTSR2_SRAM2_ECC_Pos) /*!< 0x00000040 */ +#define FLASH_OPTSR2_SRAM2_ECC FLASH_OPTSR2_SRAM2_ECC_Msk /*!< SRAM2 ECC detection and correction disable */ +#define FLASH_OPTSR2_TZEN_Pos (24U) +#define FLASH_OPTSR2_TZEN_Msk (0xFFUL << FLASH_OPTSR2_TZEN_Pos) /*!< 0xFF000000 */ +#define FLASH_OPTSR2_TZEN FLASH_OPTSR2_TZEN_Msk /*!< TrustZone enable */ + +/**************** Bits definition for FLASH_BOOTR register **********************/ +#define FLASH_BOOTR_BOOT_LOCK_Pos (0U) +#define FLASH_BOOTR_BOOT_LOCK_Msk (0xFFUL << FLASH_BOOTR_BOOT_LOCK_Pos) /*!< 0x000000FF */ +#define FLASH_BOOTR_BOOT_LOCK FLASH_BOOTR_BOOT_LOCK_Msk /*!< Boot Lock */ +#define FLASH_BOOTR_BOOTADD_Pos (8U) +#define FLASH_BOOTR_BOOTADD_Msk (0xFFFFFFUL << FLASH_BOOTR_BOOTADD_Pos) /*!< 0xFFFFFF00 */ +#define FLASH_BOOTR_BOOTADD FLASH_BOOTR_BOOTADD_Msk /*!< Boot address */ + +/**************** Bits definition for FLASH_PRIVBBR register *******************/ +#define FLASH_PRIVBBR_PRIVBB_Pos (0U) +#define FLASH_PRIVBBR_PRIVBB_Msk (0xFFFFFFFFUL << FLASH_PRIVBBR_PRIVBB_Pos) /*!< 0xFFFFFFFF */ +#define FLASH_PRIVBBR_PRIVBB FLASH_PRIVBBR_PRIVBB_Msk /*!< Privileged/unprivileged 8-Kbyte Flash sector attribute */ + +/***************** Bits definition for FLASH_SECWMR register ********************/ +#define FLASH_SECWMR_SECWM_STRT_Pos (0U) +#define FLASH_SECWMR_SECWM_STRT_Msk (0x7FUL << FLASH_SECWMR_SECWM_STRT_Pos) /*!< 0x0000007F */ +#define FLASH_SECWMR_SECWM_STRT FLASH_SECWMR_SECWM_STRT_Msk /*!< Start sector of secure area */ +#define FLASH_SECWMR_SECWM_END_Pos (16U) +#define FLASH_SECWMR_SECWM_END_Msk (0x7FUL << FLASH_SECWMR_SECWM_END_Pos) /*!< 0x007F0000 */ +#define FLASH_SECWMR_SECWM_END FLASH_SECWMR_SECWM_END_Msk /*!< End sector of secure area */ + +/***************** Bits definition for FLASH_WRPR register *********************/ +#define FLASH_WRPR_WRPSG_Pos (0U) +#define FLASH_WRPR_WRPSG_Msk (0xFFFFFFFFUL << FLASH_WRPR_WRPSG_Pos) /*!< 0xFFFFFFFF */ +#define FLASH_WRPR_WRPSG FLASH_WRPR_WRPSG_Msk /*!< Sector group protection option status */ + +/***************** Bits definition for FLASH_EDATA register ********************/ +#define FLASH_EDATAR_EDATA_STRT_Pos (0U) +#define FLASH_EDATAR_EDATA_STRT_Msk (0x3UL << FLASH_EDATAR_EDATA_STRT_Pos) /*!< 0x00000003 */ +#define FLASH_EDATAR_EDATA_STRT FLASH_EDATAR_EDATA_STRT_Msk /*!< Flash high-cycle data start sector */ +#define FLASH_EDATAR_EDATA_EN_Pos (15U) +#define FLASH_EDATAR_EDATA_EN_Msk (0x1UL << FLASH_EDATAR_EDATA_EN_Pos) /*!< 0x00008000 */ +#define FLASH_EDATAR_EDATA_EN FLASH_EDATAR_EDATA_EN_Msk /*!< Flash high-cycle data enable */ + +/***************** Bits definition for FLASH_HDPR register ********************/ +#define FLASH_HDPR_HDP_STRT_Pos (0U) +#define FLASH_HDPR_HDP_STRT_Msk (0x7FUL << FLASH_HDPR_HDP_STRT_Pos) /*!< 0x0000007F */ +#define FLASH_HDPR_HDP_STRT FLASH_HDPR_HDP_STRT_Msk /*!< Start sector of hide protection area */ +#define FLASH_HDPR_HDP_END_Pos (16U) +#define FLASH_HDPR_HDP_END_Msk (0x7FUL << FLASH_HDPR_HDP_END_Pos) /*!< 0x007F0000 */ +#define FLASH_HDPR_HDP_END FLASH_HDPR_HDP_END_Msk /*!< End sector of hide protection area */ + +/******************* Bits definition for FLASH_ECCR register ***************/ +#define FLASH_ECCR_ADDR_ECC_Pos (0U) +#define FLASH_ECCR_ADDR_ECC_Msk (0xFFFFUL << FLASH_ECCR_ADDR_ECC_Pos) /*!< 0x0000FFFF */ +#define FLASH_ECCR_ADDR_ECC FLASH_ECCR_ADDR_ECC_Msk /*!< ECC fail address */ +#define FLASH_ECCR_OBK_ECC_Pos (20U) +#define FLASH_ECCR_OBK_ECC_Msk (0x1UL << FLASH_ECCR_OBK_ECC_Pos) /*!< 0x00200000 */ +#define FLASH_ECCR_OBK_ECC FLASH_ECCR_OBK_ECC_Msk /*!< Flash OB Keys storage area ECC fail */ +#define FLASH_ECCR_DATA_ECC_Pos (21U) +#define FLASH_ECCR_DATA_ECC_Msk (0x1UL << FLASH_ECCR_DATA_ECC_Pos) /*!< 0x00400000 */ +#define FLASH_ECCR_DATA_ECC FLASH_ECCR_DATA_ECC_Msk /*!< Flash high-cycle data ECC fail */ +#define FLASH_ECCR_BK_ECC_Pos (22U) +#define FLASH_ECCR_BK_ECC_Msk (0x1UL << FLASH_ECCR_BK_ECC_Pos) /*!< 0x00400000 */ +#define FLASH_ECCR_BK_ECC FLASH_ECCR_BK_ECC_Msk /*!< ECC fail bank */ +#define FLASH_ECCR_SYSF_ECC_Pos (23U) +#define FLASH_ECCR_SYSF_ECC_Msk (0x1UL << FLASH_ECCR_SYSF_ECC_Pos) /*!< 0x00800000 */ +#define FLASH_ECCR_SYSF_ECC FLASH_ECCR_SYSF_ECC_Msk /*!< System Flash ECC fail */ +#define FLASH_ECCR_OTP_ECC_Pos (24U) +#define FLASH_ECCR_OTP_ECC_Msk (0x1UL << FLASH_ECCR_OTP_ECC_Pos) /*!< 0x01000000 */ +#define FLASH_ECCR_OTP_ECC FLASH_ECCR_OTP_ECC_Msk /*!< Flash OTP ECC fail */ +#define FLASH_ECCR_ECCIE_Pos (25U) +#define FLASH_ECCR_ECCIE_Msk (0x1UL << FLASH_ECCR_ECCIE_Pos) /*!< 0x02000000 */ +#define FLASH_ECCR_ECCIE FLASH_ECCR_ECCIE_Msk /*!< ECC correction interrupt enable */ +#define FLASH_ECCR_ECCC_Pos (30U) +#define FLASH_ECCR_ECCC_Msk (0x1UL << FLASH_ECCR_ECCC_Pos) /*!< 0x40000000 */ +#define FLASH_ECCR_ECCC FLASH_ECCR_ECCC_Msk /*!< ECC correction */ +#define FLASH_ECCR_ECCD_Pos (31U) +#define FLASH_ECCR_ECCD_Msk (0x1UL << FLASH_ECCR_ECCD_Pos) /*!< 0x80000000 */ +#define FLASH_ECCR_ECCD FLASH_ECCR_ECCD_Msk /*!< ECC detection */ + +/******************* Bits definition for FLASH_ECCDR register ***************/ +#define FLASH_ECCDR_FAIL_DATA_Pos (0U) +#define FLASH_ECCDR_FAIL_DATA_Msk (0xFFFFUL << FLASH_ECCDR_FAIL_DATA_Pos) /*!< 0x0000FFFF */ +#define FLASH_ECCDR_FAIL_DATA FLASH_ECCDR_FAIL_DATA_Msk /*!< ECC fail data */ + + +/******************************************************************************/ +/* */ +/* Filter Mathematical ACcelerator unit (FMAC) */ +/* */ +/******************************************************************************/ +/***************** Bit definition for FMAC_X1BUFCFG register ****************/ +#define FMAC_X1BUFCFG_X1_BASE_Pos (0U) +#define FMAC_X1BUFCFG_X1_BASE_Msk (0xFFUL << FMAC_X1BUFCFG_X1_BASE_Pos) /*!< 0x000000FF */ +#define FMAC_X1BUFCFG_X1_BASE FMAC_X1BUFCFG_X1_BASE_Msk /*!< Base address of X1 buffer */ +#define FMAC_X1BUFCFG_X1_BUF_SIZE_Pos (8U) +#define FMAC_X1BUFCFG_X1_BUF_SIZE_Msk (0xFFUL << FMAC_X1BUFCFG_X1_BUF_SIZE_Pos) /*!< 0x0000FF00 */ +#define FMAC_X1BUFCFG_X1_BUF_SIZE FMAC_X1BUFCFG_X1_BUF_SIZE_Msk /*!< Allocated size of X1 buffer in 16-bit words */ +#define FMAC_X1BUFCFG_FULL_WM_Pos (24U) +#define FMAC_X1BUFCFG_FULL_WM_Msk (0x3UL << FMAC_X1BUFCFG_FULL_WM_Pos) /*!< 0x03000000 */ +#define FMAC_X1BUFCFG_FULL_WM FMAC_X1BUFCFG_FULL_WM_Msk /*!< Watermark for buffer full flag */ + +/***************** Bit definition for FMAC_X2BUFCFG register ****************/ +#define FMAC_X2BUFCFG_X2_BASE_Pos (0U) +#define FMAC_X2BUFCFG_X2_BASE_Msk (0xFFUL << FMAC_X2BUFCFG_X2_BASE_Pos) /*!< 0x000000FF */ +#define FMAC_X2BUFCFG_X2_BASE FMAC_X2BUFCFG_X2_BASE_Msk /*!< Base address of X2 buffer */ +#define FMAC_X2BUFCFG_X2_BUF_SIZE_Pos (8U) +#define FMAC_X2BUFCFG_X2_BUF_SIZE_Msk (0xFFUL << FMAC_X2BUFCFG_X2_BUF_SIZE_Pos) /*!< 0x0000FF00 */ +#define FMAC_X2BUFCFG_X2_BUF_SIZE FMAC_X2BUFCFG_X2_BUF_SIZE_Msk /*!< Size of X2 buffer in 16-bit words */ + +/***************** Bit definition for FMAC_YBUFCFG register *****************/ +#define FMAC_YBUFCFG_Y_BASE_Pos (0U) +#define FMAC_YBUFCFG_Y_BASE_Msk (0xFFUL << FMAC_YBUFCFG_Y_BASE_Pos) /*!< 0x000000FF */ +#define FMAC_YBUFCFG_Y_BASE FMAC_YBUFCFG_Y_BASE_Msk /*!< Base address of Y buffer */ +#define FMAC_YBUFCFG_Y_BUF_SIZE_Pos (8U) +#define FMAC_YBUFCFG_Y_BUF_SIZE_Msk (0xFFUL << FMAC_YBUFCFG_Y_BUF_SIZE_Pos) /*!< 0x0000FF00 */ +#define FMAC_YBUFCFG_Y_BUF_SIZE FMAC_YBUFCFG_Y_BUF_SIZE_Msk /*!< Size of Y buffer in 16-bit words */ +#define FMAC_YBUFCFG_EMPTY_WM_Pos (24U) +#define FMAC_YBUFCFG_EMPTY_WM_Msk (0x3UL << FMAC_YBUFCFG_EMPTY_WM_Pos) /*!< 0x03000000 */ +#define FMAC_YBUFCFG_EMPTY_WM FMAC_YBUFCFG_EMPTY_WM_Msk /*!< Watermark for buffer empty flag */ + +/****************** Bit definition for FMAC_PARAM register ******************/ +#define FMAC_PARAM_P_Pos (0U) +#define FMAC_PARAM_P_Msk (0xFFUL << FMAC_PARAM_P_Pos) /*!< 0x000000FF */ +#define FMAC_PARAM_P FMAC_PARAM_P_Msk /*!< Input parameter P */ +#define FMAC_PARAM_Q_Pos (8U) +#define FMAC_PARAM_Q_Msk (0xFFUL << FMAC_PARAM_Q_Pos) /*!< 0x0000FF00 */ +#define FMAC_PARAM_Q FMAC_PARAM_Q_Msk /*!< Input parameter Q */ +#define FMAC_PARAM_R_Pos (16U) +#define FMAC_PARAM_R_Msk (0xFFUL << FMAC_PARAM_R_Pos) /*!< 0x00FF0000 */ +#define FMAC_PARAM_R FMAC_PARAM_R_Msk /*!< Input parameter R */ +#define FMAC_PARAM_FUNC_Pos (24U) +#define FMAC_PARAM_FUNC_Msk (0x7FUL << FMAC_PARAM_FUNC_Pos) /*!< 0x7F000000 */ +#define FMAC_PARAM_FUNC FMAC_PARAM_FUNC_Msk /*!< Function */ +#define FMAC_PARAM_FUNC_0 (0x1UL << FMAC_PARAM_FUNC_Pos) /*!< 0x01000000 */ +#define FMAC_PARAM_FUNC_1 (0x2UL << FMAC_PARAM_FUNC_Pos) /*!< 0x02000000 */ +#define FMAC_PARAM_FUNC_2 (0x4UL << FMAC_PARAM_FUNC_Pos) /*!< 0x04000000 */ +#define FMAC_PARAM_FUNC_3 (0x8UL << FMAC_PARAM_FUNC_Pos) /*!< 0x08000000 */ +#define FMAC_PARAM_FUNC_4 (0x10UL << FMAC_PARAM_FUNC_Pos) /*!< 0x10000000 */ +#define FMAC_PARAM_FUNC_5 (0x20UL << FMAC_PARAM_FUNC_Pos) /*!< 0x20000000 */ +#define FMAC_PARAM_FUNC_6 (0x40UL << FMAC_PARAM_FUNC_Pos) /*!< 0x40000000 */ +#define FMAC_PARAM_START_Pos (31U) +#define FMAC_PARAM_START_Msk (0x1UL << FMAC_PARAM_START_Pos) /*!< 0x80000000 */ +#define FMAC_PARAM_START FMAC_PARAM_START_Msk /*!< Enable execution */ + +/******************** Bit definition for FMAC_CR register *******************/ +#define FMAC_CR_RIEN_Pos (0U) +#define FMAC_CR_RIEN_Msk (0x1UL << FMAC_CR_RIEN_Pos) /*!< 0x00000001 */ +#define FMAC_CR_RIEN FMAC_CR_RIEN_Msk /*!< Enable read interrupt */ +#define FMAC_CR_WIEN_Pos (1U) +#define FMAC_CR_WIEN_Msk (0x1UL << FMAC_CR_WIEN_Pos) /*!< 0x00000002 */ +#define FMAC_CR_WIEN FMAC_CR_WIEN_Msk /*!< Enable write interrupt */ +#define FMAC_CR_OVFLIEN_Pos (2U) +#define FMAC_CR_OVFLIEN_Msk (0x1UL << FMAC_CR_OVFLIEN_Pos) /*!< 0x00000004 */ +#define FMAC_CR_OVFLIEN FMAC_CR_OVFLIEN_Msk /*!< Enable overflow error interrupts */ +#define FMAC_CR_UNFLIEN_Pos (3U) +#define FMAC_CR_UNFLIEN_Msk (0x1UL << FMAC_CR_UNFLIEN_Pos) /*!< 0x00000008 */ +#define FMAC_CR_UNFLIEN FMAC_CR_UNFLIEN_Msk /*!< Enable underflow error interrupts */ +#define FMAC_CR_SATIEN_Pos (4U) +#define FMAC_CR_SATIEN_Msk (0x1UL << FMAC_CR_SATIEN_Pos) /*!< 0x00000010 */ +#define FMAC_CR_SATIEN FMAC_CR_SATIEN_Msk /*!< Enable saturation error interrupts */ +#define FMAC_CR_DMAREN_Pos (8U) +#define FMAC_CR_DMAREN_Msk (0x1UL << FMAC_CR_DMAREN_Pos) /*!< 0x00000100 */ +#define FMAC_CR_DMAREN FMAC_CR_DMAREN_Msk /*!< Enable DMA read channel requests */ +#define FMAC_CR_DMAWEN_Pos (9U) +#define FMAC_CR_DMAWEN_Msk (0x1UL << FMAC_CR_DMAWEN_Pos) /*!< 0x00000200 */ +#define FMAC_CR_DMAWEN FMAC_CR_DMAWEN_Msk /*!< Enable DMA write channel requests */ +#define FMAC_CR_CLIPEN_Pos (15U) +#define FMAC_CR_CLIPEN_Msk (0x1UL << FMAC_CR_CLIPEN_Pos) /*!< 0x00008000 */ +#define FMAC_CR_CLIPEN FMAC_CR_CLIPEN_Msk /*!< Enable clipping */ +#define FMAC_CR_RESET_Pos (16U) +#define FMAC_CR_RESET_Msk (0x1UL << FMAC_CR_RESET_Pos) /*!< 0x00010000 */ +#define FMAC_CR_RESET FMAC_CR_RESET_Msk /*!< Reset filter mathematical accelerator unit */ + +/******************* Bit definition for FMAC_SR register ********************/ +#define FMAC_SR_YEMPTY_Pos (0U) +#define FMAC_SR_YEMPTY_Msk (0x1UL << FMAC_SR_YEMPTY_Pos) /*!< 0x00000001 */ +#define FMAC_SR_YEMPTY FMAC_SR_YEMPTY_Msk /*!< Y buffer empty flag */ +#define FMAC_SR_X1FULL_Pos (1U) +#define FMAC_SR_X1FULL_Msk (0x1UL << FMAC_SR_X1FULL_Pos) /*!< 0x00000002 */ +#define FMAC_SR_X1FULL FMAC_SR_X1FULL_Msk /*!< X1 buffer full flag */ +#define FMAC_SR_OVFL_Pos (8U) +#define FMAC_SR_OVFL_Msk (0x1UL << FMAC_SR_OVFL_Pos) /*!< 0x00000100 */ +#define FMAC_SR_OVFL FMAC_SR_OVFL_Msk /*!< Overflow error flag */ +#define FMAC_SR_UNFL_Pos (9U) +#define FMAC_SR_UNFL_Msk (0x1UL << FMAC_SR_UNFL_Pos) /*!< 0x00000200 */ +#define FMAC_SR_UNFL FMAC_SR_UNFL_Msk /*!< Underflow error flag */ +#define FMAC_SR_SAT_Pos (10U) +#define FMAC_SR_SAT_Msk (0x1UL << FMAC_SR_SAT_Pos) /*!< 0x00000400 */ +#define FMAC_SR_SAT FMAC_SR_SAT_Msk /*!< Saturation error flag */ + +/****************** Bit definition for FMAC_WDATA register ******************/ +#define FMAC_WDATA_WDATA_Pos (0U) +#define FMAC_WDATA_WDATA_Msk (0xFFFFUL << FMAC_WDATA_WDATA_Pos) /*!< 0x0000FFFF */ +#define FMAC_WDATA_WDATA FMAC_WDATA_WDATA_Msk /*!< Write data */ + +/****************** Bit definition for FMACX_RDATA register *****************/ +#define FMAC_RDATA_RDATA_Pos (0U) +#define FMAC_RDATA_RDATA_Msk (0xFFFFUL << FMAC_RDATA_RDATA_Pos) /*!< 0x0000FFFF */ +#define FMAC_RDATA_RDATA FMAC_RDATA_RDATA_Msk /*!< Read data */ + + +/******************************************************************************/ +/* */ +/* Flexible Memory Controller */ +/* */ +/******************************************************************************/ +/****************** Bit definition for FMC_BCR1 register *******************/ +#define FMC_BCR1_CCLKEN_Pos (20U) +#define FMC_BCR1_CCLKEN_Msk (0x1UL << FMC_BCR1_CCLKEN_Pos) /*!< 0x00100000 */ +#define FMC_BCR1_CCLKEN FMC_BCR1_CCLKEN_Msk /*! */ + +/******************** Bits definition for RTC_ALRMAR register ***************/ +#define RTC_ALRMAR_SU_Pos (0U) +#define RTC_ALRMAR_SU_Msk (0xFUL << RTC_ALRMAR_SU_Pos) /*!< 0x0000000F */ +#define RTC_ALRMAR_SU RTC_ALRMAR_SU_Msk +#define RTC_ALRMAR_SU_0 (0x1UL << RTC_ALRMAR_SU_Pos) /*!< 0x00000001 */ +#define RTC_ALRMAR_SU_1 (0x2UL << RTC_ALRMAR_SU_Pos) /*!< 0x00000002 */ +#define RTC_ALRMAR_SU_2 (0x4UL << RTC_ALRMAR_SU_Pos) /*!< 0x00000004 */ +#define RTC_ALRMAR_SU_3 (0x8UL << RTC_ALRMAR_SU_Pos) /*!< 0x00000008 */ +#define RTC_ALRMAR_ST_Pos (4U) +#define RTC_ALRMAR_ST_Msk (0x7UL << RTC_ALRMAR_ST_Pos) /*!< 0x00000070 */ +#define RTC_ALRMAR_ST RTC_ALRMAR_ST_Msk +#define RTC_ALRMAR_ST_0 (0x1UL << RTC_ALRMAR_ST_Pos) /*!< 0x00000010 */ +#define RTC_ALRMAR_ST_1 (0x2UL << RTC_ALRMAR_ST_Pos) /*!< 0x00000020 */ +#define RTC_ALRMAR_ST_2 (0x4UL << RTC_ALRMAR_ST_Pos) /*!< 0x00000040 */ +#define RTC_ALRMAR_MSK1_Pos (7U) +#define RTC_ALRMAR_MSK1_Msk (0x1UL << RTC_ALRMAR_MSK1_Pos) /*!< 0x00000080 */ +#define RTC_ALRMAR_MSK1 RTC_ALRMAR_MSK1_Msk +#define RTC_ALRMAR_MNU_Pos (8U) +#define RTC_ALRMAR_MNU_Msk (0xFUL << RTC_ALRMAR_MNU_Pos) /*!< 0x00000F00 */ +#define RTC_ALRMAR_MNU RTC_ALRMAR_MNU_Msk +#define RTC_ALRMAR_MNU_0 (0x1UL << RTC_ALRMAR_MNU_Pos) /*!< 0x00000100 */ +#define RTC_ALRMAR_MNU_1 (0x2UL << RTC_ALRMAR_MNU_Pos) /*!< 0x00000200 */ +#define RTC_ALRMAR_MNU_2 (0x4UL << RTC_ALRMAR_MNU_Pos) /*!< 0x00000400 */ +#define RTC_ALRMAR_MNU_3 (0x8UL << RTC_ALRMAR_MNU_Pos) /*!< 0x00000800 */ +#define RTC_ALRMAR_MNT_Pos (12U) +#define RTC_ALRMAR_MNT_Msk (0x7UL << RTC_ALRMAR_MNT_Pos) /*!< 0x00007000 */ +#define RTC_ALRMAR_MNT RTC_ALRMAR_MNT_Msk +#define RTC_ALRMAR_MNT_0 (0x1UL << RTC_ALRMAR_MNT_Pos) /*!< 0x00001000 */ +#define RTC_ALRMAR_MNT_1 (0x2UL << RTC_ALRMAR_MNT_Pos) /*!< 0x00002000 */ +#define RTC_ALRMAR_MNT_2 (0x4UL << RTC_ALRMAR_MNT_Pos) /*!< 0x00004000 */ +#define RTC_ALRMAR_MSK2_Pos (15U) +#define RTC_ALRMAR_MSK2_Msk (0x1UL << RTC_ALRMAR_MSK2_Pos) /*!< 0x00008000 */ +#define RTC_ALRMAR_MSK2 RTC_ALRMAR_MSK2_Msk +#define RTC_ALRMAR_HU_Pos (16U) +#define RTC_ALRMAR_HU_Msk (0xFUL << RTC_ALRMAR_HU_Pos) /*!< 0x000F0000 */ +#define RTC_ALRMAR_HU RTC_ALRMAR_HU_Msk +#define RTC_ALRMAR_HU_0 (0x1UL << RTC_ALRMAR_HU_Pos) /*!< 0x00010000 */ +#define RTC_ALRMAR_HU_1 (0x2UL << RTC_ALRMAR_HU_Pos) /*!< 0x00020000 */ +#define RTC_ALRMAR_HU_2 (0x4UL << RTC_ALRMAR_HU_Pos) /*!< 0x00040000 */ +#define RTC_ALRMAR_HU_3 (0x8UL << RTC_ALRMAR_HU_Pos) /*!< 0x00080000 */ +#define RTC_ALRMAR_HT_Pos (20U) +#define RTC_ALRMAR_HT_Msk (0x3UL << RTC_ALRMAR_HT_Pos) /*!< 0x00300000 */ +#define RTC_ALRMAR_HT RTC_ALRMAR_HT_Msk +#define RTC_ALRMAR_HT_0 (0x1UL << RTC_ALRMAR_HT_Pos) /*!< 0x00100000 */ +#define RTC_ALRMAR_HT_1 (0x2UL << RTC_ALRMAR_HT_Pos) /*!< 0x00200000 */ +#define RTC_ALRMAR_PM_Pos (22U) +#define RTC_ALRMAR_PM_Msk (0x1UL << RTC_ALRMAR_PM_Pos) /*!< 0x00400000 */ +#define RTC_ALRMAR_PM RTC_ALRMAR_PM_Msk +#define RTC_ALRMAR_MSK3_Pos (23U) +#define RTC_ALRMAR_MSK3_Msk (0x1UL << RTC_ALRMAR_MSK3_Pos) /*!< 0x00800000 */ +#define RTC_ALRMAR_MSK3 RTC_ALRMAR_MSK3_Msk +#define RTC_ALRMAR_DU_Pos (24U) +#define RTC_ALRMAR_DU_Msk (0xFUL << RTC_ALRMAR_DU_Pos) /*!< 0x0F000000 */ +#define RTC_ALRMAR_DU RTC_ALRMAR_DU_Msk +#define RTC_ALRMAR_DU_0 (0x1UL << RTC_ALRMAR_DU_Pos) /*!< 0x01000000 */ +#define RTC_ALRMAR_DU_1 (0x2UL << RTC_ALRMAR_DU_Pos) /*!< 0x02000000 */ +#define RTC_ALRMAR_DU_2 (0x4UL << RTC_ALRMAR_DU_Pos) /*!< 0x04000000 */ +#define RTC_ALRMAR_DU_3 (0x8UL << RTC_ALRMAR_DU_Pos) /*!< 0x08000000 */ +#define RTC_ALRMAR_DT_Pos (28U) +#define RTC_ALRMAR_DT_Msk (0x3UL << RTC_ALRMAR_DT_Pos) /*!< 0x30000000 */ +#define RTC_ALRMAR_DT RTC_ALRMAR_DT_Msk +#define RTC_ALRMAR_DT_0 (0x1UL << RTC_ALRMAR_DT_Pos) /*!< 0x10000000 */ +#define RTC_ALRMAR_DT_1 (0x2UL << RTC_ALRMAR_DT_Pos) /*!< 0x20000000 */ +#define RTC_ALRMAR_WDSEL_Pos (30U) +#define RTC_ALRMAR_WDSEL_Msk (0x1UL << RTC_ALRMAR_WDSEL_Pos) /*!< 0x40000000 */ +#define RTC_ALRMAR_WDSEL RTC_ALRMAR_WDSEL_Msk +#define RTC_ALRMAR_MSK4_Pos (31U) +#define RTC_ALRMAR_MSK4_Msk (0x1UL << RTC_ALRMAR_MSK4_Pos) /*!< 0x80000000 */ +#define RTC_ALRMAR_MSK4 RTC_ALRMAR_MSK4_Msk + +/******************** Bits definition for RTC_ALRMASSR register *************/ +#define RTC_ALRMASSR_SS_Pos (0U) +#define RTC_ALRMASSR_SS_Msk (0x7FFFUL << RTC_ALRMASSR_SS_Pos) /*!< 0x00007FFF */ +#define RTC_ALRMASSR_SS RTC_ALRMASSR_SS_Msk +#define RTC_ALRMASSR_MASKSS_Pos (24U) +#define RTC_ALRMASSR_MASKSS_Msk (0x3FUL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x3F000000 */ +#define RTC_ALRMASSR_MASKSS RTC_ALRMASSR_MASKSS_Msk +#define RTC_ALRMASSR_MASKSS_0 (0x1UL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x01000000 */ +#define RTC_ALRMASSR_MASKSS_1 (0x2UL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x02000000 */ +#define RTC_ALRMASSR_MASKSS_2 (0x4UL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x04000000 */ +#define RTC_ALRMASSR_MASKSS_3 (0x8UL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x08000000 */ +#define RTC_ALRMASSR_MASKSS_4 (0x10UL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x10000000 */ +#define RTC_ALRMASSR_MASKSS_5 (0x20UL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x20000000 */ +#define RTC_ALRMASSR_SSCLR_Pos (31U) +#define RTC_ALRMASSR_SSCLR_Msk (0x1UL << RTC_ALRMASSR_SSCLR_Pos) /*!< 0x80000000 */ +#define RTC_ALRMASSR_SSCLR RTC_ALRMASSR_SSCLR_Msk + +/******************** Bits definition for RTC_ALRMBR register ***************/ +#define RTC_ALRMBR_SU_Pos (0U) +#define RTC_ALRMBR_SU_Msk (0xFUL << RTC_ALRMBR_SU_Pos) /*!< 0x0000000F */ +#define RTC_ALRMBR_SU RTC_ALRMBR_SU_Msk +#define RTC_ALRMBR_SU_0 (0x1UL << RTC_ALRMBR_SU_Pos) /*!< 0x00000001 */ +#define RTC_ALRMBR_SU_1 (0x2UL << RTC_ALRMBR_SU_Pos) /*!< 0x00000002 */ +#define RTC_ALRMBR_SU_2 (0x4UL << RTC_ALRMBR_SU_Pos) /*!< 0x00000004 */ +#define RTC_ALRMBR_SU_3 (0x8UL << RTC_ALRMBR_SU_Pos) /*!< 0x00000008 */ +#define RTC_ALRMBR_ST_Pos (4U) +#define RTC_ALRMBR_ST_Msk (0x7UL << RTC_ALRMBR_ST_Pos) /*!< 0x00000070 */ +#define RTC_ALRMBR_ST RTC_ALRMBR_ST_Msk +#define RTC_ALRMBR_ST_0 (0x1UL << RTC_ALRMBR_ST_Pos) /*!< 0x00000010 */ +#define RTC_ALRMBR_ST_1 (0x2UL << RTC_ALRMBR_ST_Pos) /*!< 0x00000020 */ +#define RTC_ALRMBR_ST_2 (0x4UL << RTC_ALRMBR_ST_Pos) /*!< 0x00000040 */ +#define RTC_ALRMBR_MSK1_Pos (7U) +#define RTC_ALRMBR_MSK1_Msk (0x1UL << RTC_ALRMBR_MSK1_Pos) /*!< 0x00000080 */ +#define RTC_ALRMBR_MSK1 RTC_ALRMBR_MSK1_Msk +#define RTC_ALRMBR_MNU_Pos (8U) +#define RTC_ALRMBR_MNU_Msk (0xFUL << RTC_ALRMBR_MNU_Pos) /*!< 0x00000F00 */ +#define RTC_ALRMBR_MNU RTC_ALRMBR_MNU_Msk +#define RTC_ALRMBR_MNU_0 (0x1UL << RTC_ALRMBR_MNU_Pos) /*!< 0x00000100 */ +#define RTC_ALRMBR_MNU_1 (0x2UL << RTC_ALRMBR_MNU_Pos) /*!< 0x00000200 */ +#define RTC_ALRMBR_MNU_2 (0x4UL << RTC_ALRMBR_MNU_Pos) /*!< 0x00000400 */ +#define RTC_ALRMBR_MNU_3 (0x8UL << RTC_ALRMBR_MNU_Pos) /*!< 0x00000800 */ +#define RTC_ALRMBR_MNT_Pos (12U) +#define RTC_ALRMBR_MNT_Msk (0x7UL << RTC_ALRMBR_MNT_Pos) /*!< 0x00007000 */ +#define RTC_ALRMBR_MNT RTC_ALRMBR_MNT_Msk +#define RTC_ALRMBR_MNT_0 (0x1UL << RTC_ALRMBR_MNT_Pos) /*!< 0x00001000 */ +#define RTC_ALRMBR_MNT_1 (0x2UL << RTC_ALRMBR_MNT_Pos) /*!< 0x00002000 */ +#define RTC_ALRMBR_MNT_2 (0x4UL << RTC_ALRMBR_MNT_Pos) /*!< 0x00004000 */ +#define RTC_ALRMBR_MSK2_Pos (15U) +#define RTC_ALRMBR_MSK2_Msk (0x1UL << RTC_ALRMBR_MSK2_Pos) /*!< 0x00008000 */ +#define RTC_ALRMBR_MSK2 RTC_ALRMBR_MSK2_Msk +#define RTC_ALRMBR_HU_Pos (16U) +#define RTC_ALRMBR_HU_Msk (0xFUL << RTC_ALRMBR_HU_Pos) /*!< 0x000F0000 */ +#define RTC_ALRMBR_HU RTC_ALRMBR_HU_Msk +#define RTC_ALRMBR_HU_0 (0x1UL << RTC_ALRMBR_HU_Pos) /*!< 0x00010000 */ +#define RTC_ALRMBR_HU_1 (0x2UL << RTC_ALRMBR_HU_Pos) /*!< 0x00020000 */ +#define RTC_ALRMBR_HU_2 (0x4UL << RTC_ALRMBR_HU_Pos) /*!< 0x00040000 */ +#define RTC_ALRMBR_HU_3 (0x8UL << RTC_ALRMBR_HU_Pos) /*!< 0x00080000 */ +#define RTC_ALRMBR_HT_Pos (20U) +#define RTC_ALRMBR_HT_Msk (0x3UL << RTC_ALRMBR_HT_Pos) /*!< 0x00300000 */ +#define RTC_ALRMBR_HT RTC_ALRMBR_HT_Msk +#define RTC_ALRMBR_HT_0 (0x1UL << RTC_ALRMBR_HT_Pos) /*!< 0x00100000 */ +#define RTC_ALRMBR_HT_1 (0x2UL << RTC_ALRMBR_HT_Pos) /*!< 0x00200000 */ +#define RTC_ALRMBR_PM_Pos (22U) +#define RTC_ALRMBR_PM_Msk (0x1UL << RTC_ALRMBR_PM_Pos) /*!< 0x00400000 */ +#define RTC_ALRMBR_PM RTC_ALRMBR_PM_Msk +#define RTC_ALRMBR_MSK3_Pos (23U) +#define RTC_ALRMBR_MSK3_Msk (0x1UL << RTC_ALRMBR_MSK3_Pos) /*!< 0x00800000 */ +#define RTC_ALRMBR_MSK3 RTC_ALRMBR_MSK3_Msk +#define RTC_ALRMBR_DU_Pos (24U) +#define RTC_ALRMBR_DU_Msk (0xFUL << RTC_ALRMBR_DU_Pos) /*!< 0x0F000000 */ +#define RTC_ALRMBR_DU RTC_ALRMBR_DU_Msk +#define RTC_ALRMBR_DU_0 (0x1UL << RTC_ALRMBR_DU_Pos) /*!< 0x01000000 */ +#define RTC_ALRMBR_DU_1 (0x2UL << RTC_ALRMBR_DU_Pos) /*!< 0x02000000 */ +#define RTC_ALRMBR_DU_2 (0x4UL << RTC_ALRMBR_DU_Pos) /*!< 0x04000000 */ +#define RTC_ALRMBR_DU_3 (0x8UL << RTC_ALRMBR_DU_Pos) /*!< 0x08000000 */ +#define RTC_ALRMBR_DT_Pos (28U) +#define RTC_ALRMBR_DT_Msk (0x3UL << RTC_ALRMBR_DT_Pos) /*!< 0x30000000 */ +#define RTC_ALRMBR_DT RTC_ALRMBR_DT_Msk +#define RTC_ALRMBR_DT_0 (0x1UL << RTC_ALRMBR_DT_Pos) /*!< 0x10000000 */ +#define RTC_ALRMBR_DT_1 (0x2UL << RTC_ALRMBR_DT_Pos) /*!< 0x20000000 */ +#define RTC_ALRMBR_WDSEL_Pos (30U) +#define RTC_ALRMBR_WDSEL_Msk (0x1UL << RTC_ALRMBR_WDSEL_Pos) /*!< 0x40000000 */ +#define RTC_ALRMBR_WDSEL RTC_ALRMBR_WDSEL_Msk +#define RTC_ALRMBR_MSK4_Pos (31U) +#define RTC_ALRMBR_MSK4_Msk (0x1UL << RTC_ALRMBR_MSK4_Pos) /*!< 0x80000000 */ +#define RTC_ALRMBR_MSK4 RTC_ALRMBR_MSK4_Msk + +/******************** Bits definition for RTC_ALRMBSSR register *************/ +#define RTC_ALRMBSSR_SS_Pos (0U) +#define RTC_ALRMBSSR_SS_Msk (0x7FFFUL << RTC_ALRMBSSR_SS_Pos) /*!< 0x00007FFF */ +#define RTC_ALRMBSSR_SS RTC_ALRMBSSR_SS_Msk +#define RTC_ALRMBSSR_MASKSS_Pos (24U) +#define RTC_ALRMBSSR_MASKSS_Msk (0x3FUL << RTC_ALRMBSSR_MASKSS_Pos) /*!< 0x3F000000 */ +#define RTC_ALRMBSSR_MASKSS RTC_ALRMBSSR_MASKSS_Msk +#define RTC_ALRMBSSR_MASKSS_0 (0x1UL << RTC_ALRMBSSR_MASKSS_Pos) /*!< 0x01000000 */ +#define RTC_ALRMBSSR_MASKSS_1 (0x2UL << RTC_ALRMBSSR_MASKSS_Pos) /*!< 0x02000000 */ +#define RTC_ALRMBSSR_MASKSS_2 (0x4UL << RTC_ALRMBSSR_MASKSS_Pos) /*!< 0x04000000 */ +#define RTC_ALRMBSSR_MASKSS_3 (0x8UL << RTC_ALRMBSSR_MASKSS_Pos) /*!< 0x08000000 */ +#define RTC_ALRMBSSR_MASKSS_4 (0x10UL << RTC_ALRMBSSR_MASKSS_Pos) /*!< 0x10000000 */ +#define RTC_ALRMBSSR_MASKSS_5 (0x20UL << RTC_ALRMBSSR_MASKSS_Pos) /*!< 0x20000000 */ +#define RTC_ALRMBSSR_SSCLR_Pos (31U) +#define RTC_ALRMBSSR_SSCLR_Msk (0x1UL << RTC_ALRMBSSR_SSCLR_Pos) /*!< 0x80000000 */ +#define RTC_ALRMBSSR_SSCLR RTC_ALRMBSSR_SSCLR_Msk + +/******************** Bits definition for RTC_SR register *******************/ +#define RTC_SR_ALRAF_Pos (0U) +#define RTC_SR_ALRAF_Msk (0x1UL << RTC_SR_ALRAF_Pos) /*!< 0x00000001 */ +#define RTC_SR_ALRAF RTC_SR_ALRAF_Msk +#define RTC_SR_ALRBF_Pos (1U) +#define RTC_SR_ALRBF_Msk (0x1UL << RTC_SR_ALRBF_Pos) /*!< 0x00000002 */ +#define RTC_SR_ALRBF RTC_SR_ALRBF_Msk +#define RTC_SR_WUTF_Pos (2U) +#define RTC_SR_WUTF_Msk (0x1UL << RTC_SR_WUTF_Pos) /*!< 0x00000004 */ +#define RTC_SR_WUTF RTC_SR_WUTF_Msk +#define RTC_SR_TSF_Pos (3U) +#define RTC_SR_TSF_Msk (0x1UL << RTC_SR_TSF_Pos) /*!< 0x00000008 */ +#define RTC_SR_TSF RTC_SR_TSF_Msk +#define RTC_SR_TSOVF_Pos (4U) +#define RTC_SR_TSOVF_Msk (0x1UL << RTC_SR_TSOVF_Pos) /*!< 0x00000010 */ +#define RTC_SR_TSOVF RTC_SR_TSOVF_Msk +#define RTC_SR_ITSF_Pos (5U) +#define RTC_SR_ITSF_Msk (0x1UL << RTC_SR_ITSF_Pos) /*!< 0x00000020 */ +#define RTC_SR_ITSF RTC_SR_ITSF_Msk +#define RTC_SR_SSRUF_Pos (6U) +#define RTC_SR_SSRUF_Msk (0x1UL << RTC_SR_SSRUF_Pos) /*!< 0x00000040 */ +#define RTC_SR_SSRUF RTC_SR_SSRUF_Msk + +/******************** Bits definition for RTC_MISR register *****************/ +#define RTC_MISR_ALRAMF_Pos (0U) +#define RTC_MISR_ALRAMF_Msk (0x1UL << RTC_MISR_ALRAMF_Pos) /*!< 0x00000001 */ +#define RTC_MISR_ALRAMF RTC_MISR_ALRAMF_Msk +#define RTC_MISR_ALRBMF_Pos (1U) +#define RTC_MISR_ALRBMF_Msk (0x1UL << RTC_MISR_ALRBMF_Pos) /*!< 0x00000002 */ +#define RTC_MISR_ALRBMF RTC_MISR_ALRBMF_Msk +#define RTC_MISR_WUTMF_Pos (2U) +#define RTC_MISR_WUTMF_Msk (0x1UL << RTC_MISR_WUTMF_Pos) /*!< 0x00000004 */ +#define RTC_MISR_WUTMF RTC_MISR_WUTMF_Msk +#define RTC_MISR_TSMF_Pos (3U) +#define RTC_MISR_TSMF_Msk (0x1UL << RTC_MISR_TSMF_Pos) /*!< 0x00000008 */ +#define RTC_MISR_TSMF RTC_MISR_TSMF_Msk +#define RTC_MISR_TSOVMF_Pos (4U) +#define RTC_MISR_TSOVMF_Msk (0x1UL << RTC_MISR_TSOVMF_Pos) /*!< 0x00000010 */ +#define RTC_MISR_TSOVMF RTC_MISR_TSOVMF_Msk +#define RTC_MISR_ITSMF_Pos (5U) +#define RTC_MISR_ITSMF_Msk (0x1UL << RTC_MISR_ITSMF_Pos) /*!< 0x00000020 */ +#define RTC_MISR_ITSMF RTC_MISR_ITSMF_Msk +#define RTC_MISR_SSRUMF_Pos (6U) +#define RTC_MISR_SSRUMF_Msk (0x1UL << RTC_MISR_SSRUMF_Pos) /*!< 0x00000040 */ +#define RTC_MISR_SSRUMF RTC_MISR_SSRUMF_Msk + +/******************** Bits definition for RTC_SMISR register *****************/ +#define RTC_SMISR_ALRAMF_Pos (0U) +#define RTC_SMISR_ALRAMF_Msk (0x1UL << RTC_SMISR_ALRAMF_Pos) /*!< 0x00000001 */ +#define RTC_SMISR_ALRAMF RTC_SMISR_ALRAMF_Msk +#define RTC_SMISR_ALRBMF_Pos (1U) +#define RTC_SMISR_ALRBMF_Msk (0x1UL << RTC_SMISR_ALRBMF_Pos) /*!< 0x00000002 */ +#define RTC_SMISR_ALRBMF RTC_SMISR_ALRBMF_Msk +#define RTC_SMISR_WUTMF_Pos (2U) +#define RTC_SMISR_WUTMF_Msk (0x1UL << RTC_SMISR_WUTMF_Pos) /*!< 0x00000004 */ +#define RTC_SMISR_WUTMF RTC_SMISR_WUTMF_Msk +#define RTC_SMISR_TSMF_Pos (3U) +#define RTC_SMISR_TSMF_Msk (0x1UL << RTC_SMISR_TSMF_Pos) /*!< 0x00000008 */ +#define RTC_SMISR_TSMF RTC_SMISR_TSMF_Msk +#define RTC_SMISR_TSOVMF_Pos (4U) +#define RTC_SMISR_TSOVMF_Msk (0x1UL << RTC_SMISR_TSOVMF_Pos) /*!< 0x00000010 */ +#define RTC_SMISR_TSOVMF RTC_SMISR_TSOVMF_Msk +#define RTC_SMISR_ITSMF_Pos (5U) +#define RTC_SMISR_ITSMF_Msk (0x1UL << RTC_SMISR_ITSMF_Pos) /*!< 0x00000020 */ +#define RTC_SMISR_ITSMF RTC_SMISR_ITSMF_Msk +#define RTC_SMISR_SSRUMF_Pos (6U) +#define RTC_SMISR_SSRUMF_Msk (0x1UL << RTC_SMISR_SSRUMF_Pos) /*!< 0x00000040 */ +#define RTC_SMISR_SSRUMF RTC_SMISR_SSRUMF_Msk + +/******************** Bits definition for RTC_SCR register ******************/ +#define RTC_SCR_CALRAF_Pos (0U) +#define RTC_SCR_CALRAF_Msk (0x1UL << RTC_SCR_CALRAF_Pos) /*!< 0x00000001 */ +#define RTC_SCR_CALRAF RTC_SCR_CALRAF_Msk +#define RTC_SCR_CALRBF_Pos (1U) +#define RTC_SCR_CALRBF_Msk (0x1UL << RTC_SCR_CALRBF_Pos) /*!< 0x00000002 */ +#define RTC_SCR_CALRBF RTC_SCR_CALRBF_Msk +#define RTC_SCR_CWUTF_Pos (2U) +#define RTC_SCR_CWUTF_Msk (0x1UL << RTC_SCR_CWUTF_Pos) /*!< 0x00000004 */ +#define RTC_SCR_CWUTF RTC_SCR_CWUTF_Msk +#define RTC_SCR_CTSF_Pos (3U) +#define RTC_SCR_CTSF_Msk (0x1UL << RTC_SCR_CTSF_Pos) /*!< 0x00000008 */ +#define RTC_SCR_CTSF RTC_SCR_CTSF_Msk +#define RTC_SCR_CTSOVF_Pos (4U) +#define RTC_SCR_CTSOVF_Msk (0x1UL << RTC_SCR_CTSOVF_Pos) /*!< 0x00000010 */ +#define RTC_SCR_CTSOVF RTC_SCR_CTSOVF_Msk +#define RTC_SCR_CITSF_Pos (5U) +#define RTC_SCR_CITSF_Msk (0x1UL << RTC_SCR_CITSF_Pos) /*!< 0x00000020 */ +#define RTC_SCR_CITSF RTC_SCR_CITSF_Msk +#define RTC_SCR_CSSRUF_Pos (6U) +#define RTC_SCR_CSSRUF_Msk (0x1UL << RTC_SCR_CSSRUF_Pos) /*!< 0x00000040 */ +#define RTC_SCR_CSSRUF RTC_SCR_CSSRUF_Msk + +/******************** Bits definition for RTC_OR register ******************/ +#define RTC_OR_OUT2_RMP_Pos (0U) +#define RTC_OR_OUT2_RMP_Msk (0x1UL << RTC_OR_OUT2_RMP_Pos) /*!< 0x00000001 */ +#define RTC_OR_OUT2_RMP RTC_OR_OUT2_RMP_Msk + +/******************** Bits definition for RTC_ALRABINR register ******************/ +#define RTC_ALRABINR_SS_Pos (0U) +#define RTC_ALRABINR_SS_Msk (0xFFFFFFFFUL << RTC_ALRABINR_SS_Pos) /*!< 0xFFFFFFFF */ +#define RTC_ALRABINR_SS RTC_ALRABINR_SS_Msk + +/******************** Bits definition for RTC_ALRBBINR register ******************/ +#define RTC_ALRBBINR_SS_Pos (0U) +#define RTC_ALRBBINR_SS_Msk (0xFFFFFFFFUL << RTC_ALRBBINR_SS_Pos) /*!< 0xFFFFFFFF */ +#define RTC_ALRBBINR_SS RTC_ALRBBINR_SS_Msk + +/******************************************************************************/ +/* */ +/* Tamper and backup register (TAMP) */ +/* */ +/******************************************************************************/ +/******************** Bits definition for TAMP_CR1 register *****************/ +#define TAMP_CR1_TAMP1E_Pos (0U) +#define TAMP_CR1_TAMP1E_Msk (0x1UL << TAMP_CR1_TAMP1E_Pos) /*!< 0x00000001 */ +#define TAMP_CR1_TAMP1E TAMP_CR1_TAMP1E_Msk +#define TAMP_CR1_TAMP2E_Pos (1U) +#define TAMP_CR1_TAMP2E_Msk (0x1UL << TAMP_CR1_TAMP2E_Pos) /*!< 0x00000002 */ +#define TAMP_CR1_TAMP2E TAMP_CR1_TAMP2E_Msk +#define TAMP_CR1_TAMP3E_Pos (2U) +#define TAMP_CR1_TAMP3E_Msk (0x1UL << TAMP_CR1_TAMP3E_Pos) /*!< 0x00000004 */ +#define TAMP_CR1_TAMP3E TAMP_CR1_TAMP3E_Msk +#define TAMP_CR1_TAMP4E_Pos (3U) +#define TAMP_CR1_TAMP4E_Msk (0x1UL << TAMP_CR1_TAMP4E_Pos) /*!< 0x00000008 */ +#define TAMP_CR1_TAMP4E TAMP_CR1_TAMP4E_Msk +#define TAMP_CR1_TAMP5E_Pos (4U) +#define TAMP_CR1_TAMP5E_Msk (0x1UL << TAMP_CR1_TAMP5E_Pos) /*!< 0x00000010 */ +#define TAMP_CR1_TAMP5E TAMP_CR1_TAMP5E_Msk +#define TAMP_CR1_TAMP6E_Pos (5U) +#define TAMP_CR1_TAMP6E_Msk (0x1UL << TAMP_CR1_TAMP6E_Pos) /*!< 0x00000020 */ +#define TAMP_CR1_TAMP6E TAMP_CR1_TAMP6E_Msk +#define TAMP_CR1_TAMP7E_Pos (6U) +#define TAMP_CR1_TAMP7E_Msk (0x1UL << TAMP_CR1_TAMP7E_Pos) /*!< 0x00000040 */ +#define TAMP_CR1_TAMP7E TAMP_CR1_TAMP7E_Msk +#define TAMP_CR1_TAMP8E_Pos (7U) +#define TAMP_CR1_TAMP8E_Msk (0x1UL << TAMP_CR1_TAMP8E_Pos) /*!< 0x00000080 */ +#define TAMP_CR1_TAMP8E TAMP_CR1_TAMP8E_Msk +#define TAMP_CR1_ITAMP1E_Pos (16U) +#define TAMP_CR1_ITAMP1E_Msk (0x1UL << TAMP_CR1_ITAMP1E_Pos) /*!< 0x00010000 */ +#define TAMP_CR1_ITAMP1E TAMP_CR1_ITAMP1E_Msk +#define TAMP_CR1_ITAMP2E_Pos (17U) +#define TAMP_CR1_ITAMP2E_Msk (0x1UL << TAMP_CR1_ITAMP2E_Pos) /*!< 0x00020000 */ +#define TAMP_CR1_ITAMP2E TAMP_CR1_ITAMP2E_Msk +#define TAMP_CR1_ITAMP3E_Pos (18U) +#define TAMP_CR1_ITAMP3E_Msk (0x1UL << TAMP_CR1_ITAMP3E_Pos) /*!< 0x00040000 */ +#define TAMP_CR1_ITAMP3E TAMP_CR1_ITAMP3E_Msk +#define TAMP_CR1_ITAMP4E_Pos (19U) +#define TAMP_CR1_ITAMP4E_Msk (0x1UL << TAMP_CR1_ITAMP4E_Pos) /*!< 0x00080000 */ +#define TAMP_CR1_ITAMP4E TAMP_CR1_ITAMP4E_Msk +#define TAMP_CR1_ITAMP5E_Pos (20U) +#define TAMP_CR1_ITAMP5E_Msk (0x1UL << TAMP_CR1_ITAMP5E_Pos) /*!< 0x00100000 */ +#define TAMP_CR1_ITAMP5E TAMP_CR1_ITAMP5E_Msk +#define TAMP_CR1_ITAMP6E_Pos (21U) +#define TAMP_CR1_ITAMP6E_Msk (0x1UL << TAMP_CR1_ITAMP6E_Pos) /*!< 0x00200000 */ +#define TAMP_CR1_ITAMP6E TAMP_CR1_ITAMP6E_Msk +#define TAMP_CR1_ITAMP7E_Pos (22U) +#define TAMP_CR1_ITAMP7E_Msk (0x1UL << TAMP_CR1_ITAMP7E_Pos) /*!< 0x00400000 */ +#define TAMP_CR1_ITAMP7E TAMP_CR1_ITAMP7E_Msk +#define TAMP_CR1_ITAMP8E_Pos (23U) +#define TAMP_CR1_ITAMP8E_Msk (0x1UL << TAMP_CR1_ITAMP8E_Pos) /*!< 0x00800000 */ +#define TAMP_CR1_ITAMP8E TAMP_CR1_ITAMP8E_Msk +#define TAMP_CR1_ITAMP9E_Pos (24U) +#define TAMP_CR1_ITAMP9E_Msk (0x1UL << TAMP_CR1_ITAMP9E_Pos) /*!< 0x01000000 */ +#define TAMP_CR1_ITAMP9E TAMP_CR1_ITAMP9E_Msk +#define TAMP_CR1_ITAMP11E_Pos (26U) +#define TAMP_CR1_ITAMP11E_Msk (0x1UL << TAMP_CR1_ITAMP11E_Pos) /*!< 0x04000000 */ +#define TAMP_CR1_ITAMP11E TAMP_CR1_ITAMP11E_Msk +#define TAMP_CR1_ITAMP12E_Pos (27U) +#define TAMP_CR1_ITAMP12E_Msk (0x1UL << TAMP_CR1_ITAMP12E_Pos) /*!< 0x08000000 */ +#define TAMP_CR1_ITAMP12E TAMP_CR1_ITAMP12E_Msk +#define TAMP_CR1_ITAMP13E_Pos (28U) +#define TAMP_CR1_ITAMP13E_Msk (0x1UL << TAMP_CR1_ITAMP13E_Pos) /*!< 0x10000000 */ +#define TAMP_CR1_ITAMP13E TAMP_CR1_ITAMP13E_Msk +#define TAMP_CR1_ITAMP15E_Pos (30U) +#define TAMP_CR1_ITAMP15E_Msk (0x1UL << TAMP_CR1_ITAMP15E_Pos) /*!< 0x40000000 */ +#define TAMP_CR1_ITAMP15E TAMP_CR1_ITAMP15E_Msk + +/******************** Bits definition for TAMP_CR2 register *****************/ +#define TAMP_CR2_TAMP1NOERASE_Pos (0U) +#define TAMP_CR2_TAMP1NOERASE_Msk (0x1UL << TAMP_CR2_TAMP1NOERASE_Pos) /*!< 0x00000001 */ +#define TAMP_CR2_TAMP1NOERASE TAMP_CR2_TAMP1NOERASE_Msk +#define TAMP_CR2_TAMP2NOERASE_Pos (1U) +#define TAMP_CR2_TAMP2NOERASE_Msk (0x1UL << TAMP_CR2_TAMP2NOERASE_Pos) /*!< 0x00000002 */ +#define TAMP_CR2_TAMP2NOERASE TAMP_CR2_TAMP2NOERASE_Msk +#define TAMP_CR2_TAMP3NOERASE_Pos (2U) +#define TAMP_CR2_TAMP3NOERASE_Msk (0x1UL << TAMP_CR2_TAMP3NOERASE_Pos) /*!< 0x00000004 */ +#define TAMP_CR2_TAMP3NOERASE TAMP_CR2_TAMP3NOERASE_Msk +#define TAMP_CR2_TAMP4NOERASE_Pos (3U) +#define TAMP_CR2_TAMP4NOERASE_Msk (0x1UL << TAMP_CR2_TAMP4NOERASE_Pos) /*!< 0x00000008 */ +#define TAMP_CR2_TAMP4NOERASE TAMP_CR2_TAMP4NOERASE_Msk +#define TAMP_CR2_TAMP5NOERASE_Pos (4U) +#define TAMP_CR2_TAMP5NOERASE_Msk (0x1UL << TAMP_CR2_TAMP5NOERASE_Pos) /*!< 0x00000010 */ +#define TAMP_CR2_TAMP5NOERASE TAMP_CR2_TAMP5NOERASE_Msk +#define TAMP_CR2_TAMP6NOERASE_Pos (5U) +#define TAMP_CR2_TAMP6NOERASE_Msk (0x1UL << TAMP_CR2_TAMP6NOERASE_Pos) /*!< 0x00000020 */ +#define TAMP_CR2_TAMP6NOERASE TAMP_CR2_TAMP6NOERASE_Msk +#define TAMP_CR2_TAMP7NOERASE_Pos (6U) +#define TAMP_CR2_TAMP7NOERASE_Msk (0x1UL << TAMP_CR2_TAMP7NOERASE_Pos) /*!< 0x00000040 */ +#define TAMP_CR2_TAMP7NOERASE TAMP_CR2_TAMP7NOERASE_Msk +#define TAMP_CR2_TAMP8NOERASE_Pos (7U) +#define TAMP_CR2_TAMP8NOERASE_Msk (0x1UL << TAMP_CR2_TAMP8NOERASE_Pos) /*!< 0x00000080 */ +#define TAMP_CR2_TAMP8NOERASE TAMP_CR2_TAMP8NOERASE_Msk +#define TAMP_CR2_TAMP1MSK_Pos (16U) +#define TAMP_CR2_TAMP1MSK_Msk (0x1UL << TAMP_CR2_TAMP1MSK_Pos) /*!< 0x00010000 */ +#define TAMP_CR2_TAMP1MSK TAMP_CR2_TAMP1MSK_Msk +#define TAMP_CR2_TAMP2MSK_Pos (17U) +#define TAMP_CR2_TAMP2MSK_Msk (0x1UL << TAMP_CR2_TAMP2MSK_Pos) /*!< 0x00020000 */ +#define TAMP_CR2_TAMP2MSK TAMP_CR2_TAMP2MSK_Msk +#define TAMP_CR2_TAMP3MSK_Pos (18U) +#define TAMP_CR2_TAMP3MSK_Msk (0x1UL << TAMP_CR2_TAMP3MSK_Pos) /*!< 0x00040000 */ +#define TAMP_CR2_TAMP3MSK TAMP_CR2_TAMP3MSK_Msk +#define TAMP_CR2_BKBLOCK_Pos (22U) +#define TAMP_CR2_BKBLOCK_Msk (0x1UL << TAMP_CR2_BKBLOCK_Pos) /*!< 0x00400000 */ +#define TAMP_CR2_BKBLOCK TAMP_CR2_BKBLOCK_Msk +#define TAMP_CR2_BKERASE_Pos (23U) +#define TAMP_CR2_BKERASE_Msk (0x1UL << TAMP_CR2_BKERASE_Pos) /*!< 0x00800000 */ +#define TAMP_CR2_BKERASE TAMP_CR2_BKERASE_Msk +#define TAMP_CR2_TAMP1TRG_Pos (24U) +#define TAMP_CR2_TAMP1TRG_Msk (0x1UL << TAMP_CR2_TAMP1TRG_Pos) /*!< 0x01000000 */ +#define TAMP_CR2_TAMP1TRG TAMP_CR2_TAMP1TRG_Msk +#define TAMP_CR2_TAMP2TRG_Pos (25U) +#define TAMP_CR2_TAMP2TRG_Msk (0x1UL << TAMP_CR2_TAMP2TRG_Pos) /*!< 0x02000000 */ +#define TAMP_CR2_TAMP2TRG TAMP_CR2_TAMP2TRG_Msk +#define TAMP_CR2_TAMP3TRG_Pos (26U) +#define TAMP_CR2_TAMP3TRG_Msk (0x1UL << TAMP_CR2_TAMP3TRG_Pos) /*!< 0x02000000 */ +#define TAMP_CR2_TAMP3TRG TAMP_CR2_TAMP3TRG_Msk +#define TAMP_CR2_TAMP4TRG_Pos (27U) +#define TAMP_CR2_TAMP4TRG_Msk (0x1UL << TAMP_CR2_TAMP4TRG_Pos) /*!< 0x02000000 */ +#define TAMP_CR2_TAMP4TRG TAMP_CR2_TAMP4TRG_Msk +#define TAMP_CR2_TAMP5TRG_Pos (28U) +#define TAMP_CR2_TAMP5TRG_Msk (0x1UL << TAMP_CR2_TAMP5TRG_Pos) /*!< 0x02000000 */ +#define TAMP_CR2_TAMP5TRG TAMP_CR2_TAMP5TRG_Msk +#define TAMP_CR2_TAMP6TRG_Pos (29U) +#define TAMP_CR2_TAMP6TRG_Msk (0x1UL << TAMP_CR2_TAMP6TRG_Pos) /*!< 0x02000000 */ +#define TAMP_CR2_TAMP6TRG TAMP_CR2_TAMP6TRG_Msk +#define TAMP_CR2_TAMP7TRG_Pos (30U) +#define TAMP_CR2_TAMP7TRG_Msk (0x1UL << TAMP_CR2_TAMP7TRG_Pos) /*!< 0x02000000 */ +#define TAMP_CR2_TAMP7TRG TAMP_CR2_TAMP7TRG_Msk +#define TAMP_CR2_TAMP8TRG_Pos (31U) +#define TAMP_CR2_TAMP8TRG_Msk (0x1UL << TAMP_CR2_TAMP8TRG_Pos) /*!< 0x02000000 */ +#define TAMP_CR2_TAMP8TRG TAMP_CR2_TAMP8TRG_Msk + +/******************** Bits definition for TAMP_CR3 register *****************/ +#define TAMP_CR3_ITAMP1NOER_Pos (0U) +#define TAMP_CR3_ITAMP1NOER_Msk (0x1UL << TAMP_CR3_ITAMP1NOER_Pos) /*!< 0x00000001 */ +#define TAMP_CR3_ITAMP1NOER TAMP_CR3_ITAMP1NOER_Msk +#define TAMP_CR3_ITAMP2NOER_Pos (1U) +#define TAMP_CR3_ITAMP2NOER_Msk (0x1UL << TAMP_CR3_ITAMP2NOER_Pos) /*!< 0x00000002 */ +#define TAMP_CR3_ITAMP2NOER TAMP_CR3_ITAMP2NOER_Msk +#define TAMP_CR3_ITAMP3NOER_Pos (2U) +#define TAMP_CR3_ITAMP3NOER_Msk (0x1UL << TAMP_CR3_ITAMP3NOER_Pos) /*!< 0x00000004 */ +#define TAMP_CR3_ITAMP3NOER TAMP_CR3_ITAMP3NOER_Msk +#define TAMP_CR3_ITAMP4NOER_Pos (3U) +#define TAMP_CR3_ITAMP4NOER_Msk (0x1UL << TAMP_CR3_ITAMP4NOER_Pos) /*!< 0x00000008 */ +#define TAMP_CR3_ITAMP4NOER TAMP_CR3_ITAMP4NOER_Msk +#define TAMP_CR3_ITAMP5NOER_Pos (4U) +#define TAMP_CR3_ITAMP5NOER_Msk (0x1UL << TAMP_CR3_ITAMP5NOER_Pos) /*!< 0x00000010 */ +#define TAMP_CR3_ITAMP5NOER TAMP_CR3_ITAMP5NOER_Msk +#define TAMP_CR3_ITAMP6NOER_Pos (5U) +#define TAMP_CR3_ITAMP6NOER_Msk (0x1UL << TAMP_CR3_ITAMP6NOER_Pos) /*!< 0x00000020 */ +#define TAMP_CR3_ITAMP6NOER TAMP_CR3_ITAMP6NOER_Msk +#define TAMP_CR3_ITAMP7NOER_Pos (6U) +#define TAMP_CR3_ITAMP7NOER_Msk (0x1UL << TAMP_CR3_ITAMP7NOER_Pos) /*!< 0x00000040 */ +#define TAMP_CR3_ITAMP7NOER TAMP_CR3_ITAMP7NOER_Msk +#define TAMP_CR3_ITAMP8NOER_Pos (7U) +#define TAMP_CR3_ITAMP8NOER_Msk (0x1UL << TAMP_CR3_ITAMP8NOER_Pos) /*!< 0x00000080 */ +#define TAMP_CR3_ITAMP8NOER TAMP_CR3_ITAMP8NOER_Msk +#define TAMP_CR3_ITAMP9NOER_Pos (8U) +#define TAMP_CR3_ITAMP9NOER_Msk (0x1UL << TAMP_CR3_ITAMP9NOER_Pos) /*!< 0x00000100 */ +#define TAMP_CR3_ITAMP9NOER TAMP_CR3_ITAMP9NOER_Msk +#define TAMP_CR3_ITAMP11NOER_Pos (10U) +#define TAMP_CR3_ITAMP11NOER_Msk (0x1UL << TAMP_CR3_ITAMP11NOER_Pos) /*!< 0x00000400 */ +#define TAMP_CR3_ITAMP11NOER TAMP_CR3_ITAMP11NOER_Msk +#define TAMP_CR3_ITAMP12NOER_Pos (11U) +#define TAMP_CR3_ITAMP12NOER_Msk (0x1UL << TAMP_CR3_ITAMP12NOER_Pos) /*!< 0x00000800 */ +#define TAMP_CR3_ITAMP12NOER TAMP_CR3_ITAMP12NOER_Msk +#define TAMP_CR3_ITAMP13NOER_Pos (12U) +#define TAMP_CR3_ITAMP13NOER_Msk (0x1UL << TAMP_CR3_ITAMP13NOER_Pos) /*!< 0x00001000 */ +#define TAMP_CR3_ITAMP13NOER TAMP_CR3_ITAMP13NOER_Msk +#define TAMP_CR3_ITAMP15NOER_Pos (14U) +#define TAMP_CR3_ITAMP15NOER_Msk (0x1UL << TAMP_CR3_ITAMP15NOER_Pos) /*!< 0x00004000 */ +#define TAMP_CR3_ITAMP15NOER TAMP_CR3_ITAMP15NOER_Msk + +/******************** Bits definition for TAMP_FLTCR register ***************/ +#define TAMP_FLTCR_TAMPFREQ_Pos (0U) +#define TAMP_FLTCR_TAMPFREQ_Msk (0x7UL << TAMP_FLTCR_TAMPFREQ_Pos) /*!< 0x00000007 */ +#define TAMP_FLTCR_TAMPFREQ TAMP_FLTCR_TAMPFREQ_Msk +#define TAMP_FLTCR_TAMPFREQ_0 (0x1UL << TAMP_FLTCR_TAMPFREQ_Pos) /*!< 0x00000001 */ +#define TAMP_FLTCR_TAMPFREQ_1 (0x2UL << TAMP_FLTCR_TAMPFREQ_Pos) /*!< 0x00000002 */ +#define TAMP_FLTCR_TAMPFREQ_2 (0x4UL << TAMP_FLTCR_TAMPFREQ_Pos) /*!< 0x00000004 */ +#define TAMP_FLTCR_TAMPFLT_Pos (3U) +#define TAMP_FLTCR_TAMPFLT_Msk (0x3UL << TAMP_FLTCR_TAMPFLT_Pos) /*!< 0x00000018 */ +#define TAMP_FLTCR_TAMPFLT TAMP_FLTCR_TAMPFLT_Msk +#define TAMP_FLTCR_TAMPFLT_0 (0x1UL << TAMP_FLTCR_TAMPFLT_Pos) /*!< 0x00000008 */ +#define TAMP_FLTCR_TAMPFLT_1 (0x2UL << TAMP_FLTCR_TAMPFLT_Pos) /*!< 0x00000010 */ +#define TAMP_FLTCR_TAMPPRCH_Pos (5U) +#define TAMP_FLTCR_TAMPPRCH_Msk (0x3UL << TAMP_FLTCR_TAMPPRCH_Pos) /*!< 0x00000060 */ +#define TAMP_FLTCR_TAMPPRCH TAMP_FLTCR_TAMPPRCH_Msk +#define TAMP_FLTCR_TAMPPRCH_0 (0x1UL << TAMP_FLTCR_TAMPPRCH_Pos) /*!< 0x00000020 */ +#define TAMP_FLTCR_TAMPPRCH_1 (0x2UL << TAMP_FLTCR_TAMPPRCH_Pos) /*!< 0x00000040 */ +#define TAMP_FLTCR_TAMPPUDIS_Pos (7U) +#define TAMP_FLTCR_TAMPPUDIS_Msk (0x1UL << TAMP_FLTCR_TAMPPUDIS_Pos) /*!< 0x00000080 */ +#define TAMP_FLTCR_TAMPPUDIS TAMP_FLTCR_TAMPPUDIS_Msk + +/******************** Bits definition for TAMP_ATCR1 register ***************/ +#define TAMP_ATCR1_TAMP1AM_Pos (0U) +#define TAMP_ATCR1_TAMP1AM_Msk (0x1UL << TAMP_ATCR1_TAMP1AM_Pos) /*!< 0x00000001 */ +#define TAMP_ATCR1_TAMP1AM TAMP_ATCR1_TAMP1AM_Msk +#define TAMP_ATCR1_TAMP2AM_Pos (1U) +#define TAMP_ATCR1_TAMP2AM_Msk (0x1UL << TAMP_ATCR1_TAMP2AM_Pos) /*!< 0x00000002 */ +#define TAMP_ATCR1_TAMP2AM TAMP_ATCR1_TAMP2AM_Msk +#define TAMP_ATCR1_TAMP3AM_Pos (2U) +#define TAMP_ATCR1_TAMP3AM_Msk (0x1UL << TAMP_ATCR1_TAMP3AM_Pos) /*!< 0x00000004 */ +#define TAMP_ATCR1_TAMP3AM TAMP_ATCR1_TAMP3AM_Msk +#define TAMP_ATCR1_TAMP4AM_Pos (3U) +#define TAMP_ATCR1_TAMP4AM_Msk (0x1UL << TAMP_ATCR1_TAMP4AM_Pos) /*!< 0x00000008 */ +#define TAMP_ATCR1_TAMP4AM TAMP_ATCR1_TAMP4AM_Msk +#define TAMP_ATCR1_TAMP5AM_Pos (4U) +#define TAMP_ATCR1_TAMP5AM_Msk (0x1UL << TAMP_ATCR1_TAMP5AM_Pos) /*!< 0x00000010 */ +#define TAMP_ATCR1_TAMP5AM TAMP_ATCR1_TAMP5AM_Msk +#define TAMP_ATCR1_TAMP6AM_Pos (5U) +#define TAMP_ATCR1_TAMP6AM_Msk (0x1UL << TAMP_ATCR1_TAMP6AM_Pos) /*!< 0x00000010 */ +#define TAMP_ATCR1_TAMP6AM TAMP_ATCR1_TAMP6AM_Msk +#define TAMP_ATCR1_TAMP7AM_Pos (6U) +#define TAMP_ATCR1_TAMP7AM_Msk (0x1UL << TAMP_ATCR1_TAMP7AM_Pos) /*!< 0x00000040 */ +#define TAMP_ATCR1_TAMP7AM TAMP_ATCR1_TAMP7AM_Msk +#define TAMP_ATCR1_TAMP8AM_Pos (7U) +#define TAMP_ATCR1_TAMP8AM_Msk (0x1UL << TAMP_ATCR1_TAMP8AM_Pos) /*!< 0x00000080 */ +#define TAMP_ATCR1_TAMP8AM TAMP_ATCR1_TAMP8AM_Msk +#define TAMP_ATCR1_ATOSEL1_Pos (8U) +#define TAMP_ATCR1_ATOSEL1_Msk (0x3UL << TAMP_ATCR1_ATOSEL1_Pos) /*!< 0x00000300 */ +#define TAMP_ATCR1_ATOSEL1 TAMP_ATCR1_ATOSEL1_Msk +#define TAMP_ATCR1_ATOSEL1_0 (0x1UL << TAMP_ATCR1_ATOSEL1_Pos) /*!< 0x00000100 */ +#define TAMP_ATCR1_ATOSEL1_1 (0x2UL << TAMP_ATCR1_ATOSEL1_Pos) /*!< 0x00000200 */ +#define TAMP_ATCR1_ATOSEL2_Pos (10U) +#define TAMP_ATCR1_ATOSEL2_Msk (0x3UL << TAMP_ATCR1_ATOSEL2_Pos) /*!< 0x00000C00 */ +#define TAMP_ATCR1_ATOSEL2 TAMP_ATCR1_ATOSEL2_Msk +#define TAMP_ATCR1_ATOSEL2_0 (0x1UL << TAMP_ATCR1_ATOSEL2_Pos) /*!< 0x00000400 */ +#define TAMP_ATCR1_ATOSEL2_1 (0x2UL << TAMP_ATCR1_ATOSEL2_Pos) /*!< 0x00000800 */ +#define TAMP_ATCR1_ATOSEL3_Pos (12U) +#define TAMP_ATCR1_ATOSEL3_Msk (0x3UL << TAMP_ATCR1_ATOSEL3_Pos) /*!< 0x00003000 */ +#define TAMP_ATCR1_ATOSEL3 TAMP_ATCR1_ATOSEL3_Msk +#define TAMP_ATCR1_ATOSEL3_0 (0x1UL << TAMP_ATCR1_ATOSEL3_Pos) /*!< 0x00001000 */ +#define TAMP_ATCR1_ATOSEL3_1 (0x2UL << TAMP_ATCR1_ATOSEL3_Pos) /*!< 0x00002000 */ +#define TAMP_ATCR1_ATOSEL4_Pos (14U) +#define TAMP_ATCR1_ATOSEL4_Msk (0x3UL << TAMP_ATCR1_ATOSEL4_Pos) /*!< 0x0000C000 */ +#define TAMP_ATCR1_ATOSEL4 TAMP_ATCR1_ATOSEL4_Msk +#define TAMP_ATCR1_ATOSEL4_0 (0x1UL << TAMP_ATCR1_ATOSEL4_Pos) /*!< 0x00004000 */ +#define TAMP_ATCR1_ATOSEL4_1 (0x2UL << TAMP_ATCR1_ATOSEL4_Pos) /*!< 0x00008000 */ +#define TAMP_ATCR1_ATCKSEL_Pos (16U) +#define TAMP_ATCR1_ATCKSEL_Msk (0xFUL << TAMP_ATCR1_ATCKSEL_Pos) /*!< 0x000F0000 */ +#define TAMP_ATCR1_ATCKSEL TAMP_ATCR1_ATCKSEL_Msk +#define TAMP_ATCR1_ATCKSEL_0 (0x1UL << TAMP_ATCR1_ATCKSEL_Pos) /*!< 0x00010000 */ +#define TAMP_ATCR1_ATCKSEL_1 (0x2UL << TAMP_ATCR1_ATCKSEL_Pos) /*!< 0x00020000 */ +#define TAMP_ATCR1_ATCKSEL_2 (0x4UL << TAMP_ATCR1_ATCKSEL_Pos) /*!< 0x00040000 */ +#define TAMP_ATCR1_ATCKSEL_3 (0x8UL << TAMP_ATCR1_ATCKSEL_Pos) /*!< 0x00080000 */ +#define TAMP_ATCR1_ATPER_Pos (24U) +#define TAMP_ATCR1_ATPER_Msk (0x7UL << TAMP_ATCR1_ATPER_Pos) /*!< 0x07000000 */ +#define TAMP_ATCR1_ATPER TAMP_ATCR1_ATPER_Msk +#define TAMP_ATCR1_ATPER_0 (0x1UL << TAMP_ATCR1_ATPER_Pos) /*!< 0x01000000 */ +#define TAMP_ATCR1_ATPER_1 (0x2UL << TAMP_ATCR1_ATPER_Pos) /*!< 0x02000000 */ +#define TAMP_ATCR1_ATPER_2 (0x4UL << TAMP_ATCR1_ATPER_Pos) /*!< 0x04000000 */ +#define TAMP_ATCR1_ATOSHARE_Pos (30U) +#define TAMP_ATCR1_ATOSHARE_Msk (0x1UL << TAMP_ATCR1_ATOSHARE_Pos) /*!< 0x40000000 */ +#define TAMP_ATCR1_ATOSHARE TAMP_ATCR1_ATOSHARE_Msk +#define TAMP_ATCR1_FLTEN_Pos (31U) +#define TAMP_ATCR1_FLTEN_Msk (0x1UL << TAMP_ATCR1_FLTEN_Pos) /*!< 0x80000000 */ +#define TAMP_ATCR1_FLTEN TAMP_ATCR1_FLTEN_Msk + +/******************** Bits definition for TAMP_ATSEEDR register ******************/ +#define TAMP_ATSEEDR_SEED_Pos (0U) +#define TAMP_ATSEEDR_SEED_Msk (0xFFFFFFFFUL << TAMP_ATSEEDR_SEED_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_ATSEEDR_SEED TAMP_ATSEEDR_SEED_Msk + +/******************** Bits definition for TAMP_ATOR register ******************/ +#define TAMP_ATOR_PRNG_Pos (0U) +#define TAMP_ATOR_PRNG_Msk (0xFFUL << TAMP_ATOR_PRNG_Pos) /*!< 0x000000FF */ +#define TAMP_ATOR_PRNG TAMP_ATOR_PRNG_Msk +#define TAMP_ATOR_PRNG_0 (0x1UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000001 */ +#define TAMP_ATOR_PRNG_1 (0x2UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000002 */ +#define TAMP_ATOR_PRNG_2 (0x4UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000004 */ +#define TAMP_ATOR_PRNG_3 (0x8UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000008 */ +#define TAMP_ATOR_PRNG_4 (0x10UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000010 */ +#define TAMP_ATOR_PRNG_5 (0x20UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000020 */ +#define TAMP_ATOR_PRNG_6 (0x40UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000040 */ +#define TAMP_ATOR_PRNG_7 (0x80UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000080 */ +#define TAMP_ATOR_SEEDF_Pos (14U) +#define TAMP_ATOR_SEEDF_Msk (1UL << TAMP_ATOR_SEEDF_Pos) /*!< 0x00004000 */ +#define TAMP_ATOR_SEEDF TAMP_ATOR_SEEDF_Msk +#define TAMP_ATOR_INITS_Pos (15U) +#define TAMP_ATOR_INITS_Msk (1UL << TAMP_ATOR_INITS_Pos) /*!< 0x00008000 */ +#define TAMP_ATOR_INITS TAMP_ATOR_INITS_Msk + +/******************** Bits definition for TAMP_ATCR2 register ***************/ +#define TAMP_ATCR2_ATOSEL1_Pos (8U) +#define TAMP_ATCR2_ATOSEL1_Msk (0x7UL << TAMP_ATCR2_ATOSEL1_Pos) /*!< 0x00000700 */ +#define TAMP_ATCR2_ATOSEL1 TAMP_ATCR2_ATOSEL1_Msk +#define TAMP_ATCR2_ATOSEL1_0 (0x1UL << TAMP_ATCR2_ATOSEL1_Pos) /*!< 0x00000100 */ +#define TAMP_ATCR2_ATOSEL1_1 (0x2UL << TAMP_ATCR2_ATOSEL1_Pos) /*!< 0x00000200 */ +#define TAMP_ATCR2_ATOSEL1_2 (0x4UL << TAMP_ATCR2_ATOSEL1_Pos) /*!< 0x00000400 */ +#define TAMP_ATCR2_ATOSEL2_Pos (11U) +#define TAMP_ATCR2_ATOSEL2_Msk (0x7UL << TAMP_ATCR2_ATOSEL2_Pos) /*!< 0x00003800 */ +#define TAMP_ATCR2_ATOSEL2 TAMP_ATCR2_ATOSEL2_Msk +#define TAMP_ATCR2_ATOSEL2_0 (0x1UL << TAMP_ATCR2_ATOSEL2_Pos) /*!< 0x00000800 */ +#define TAMP_ATCR2_ATOSEL2_1 (0x2UL << TAMP_ATCR2_ATOSEL2_Pos) /*!< 0x00001000 */ +#define TAMP_ATCR2_ATOSEL2_2 (0x4UL << TAMP_ATCR2_ATOSEL2_Pos) /*!< 0x00002000 */ +#define TAMP_ATCR2_ATOSEL3_Pos (14U) +#define TAMP_ATCR2_ATOSEL3_Msk (0x7UL << TAMP_ATCR2_ATOSEL3_Pos) /*!< 0x0001C000 */ +#define TAMP_ATCR2_ATOSEL3 TAMP_ATCR2_ATOSEL3_Msk +#define TAMP_ATCR2_ATOSEL3_0 (0x1UL << TAMP_ATCR2_ATOSEL3_Pos) /*!< 0x00004000 */ +#define TAMP_ATCR2_ATOSEL3_1 (0x2UL << TAMP_ATCR2_ATOSEL3_Pos) /*!< 0x00008000 */ +#define TAMP_ATCR2_ATOSEL3_2 (0x4UL << TAMP_ATCR2_ATOSEL3_Pos) /*!< 0x00010000 */ +#define TAMP_ATCR2_ATOSEL4_Pos (17U) +#define TAMP_ATCR2_ATOSEL4_Msk (0x7UL << TAMP_ATCR2_ATOSEL4_Pos) /*!< 0x000E0000 */ +#define TAMP_ATCR2_ATOSEL4 TAMP_ATCR2_ATOSEL4_Msk +#define TAMP_ATCR2_ATOSEL4_0 (0x1UL << TAMP_ATCR2_ATOSEL4_Pos) /*!< 0x00020000 */ +#define TAMP_ATCR2_ATOSEL4_1 (0x2UL << TAMP_ATCR2_ATOSEL4_Pos) /*!< 0x00040000 */ +#define TAMP_ATCR2_ATOSEL4_2 (0x4UL << TAMP_ATCR2_ATOSEL4_Pos) /*!< 0x00080000 */ +#define TAMP_ATCR2_ATOSEL5_Pos (20U) +#define TAMP_ATCR2_ATOSEL5_Msk (0x7UL << TAMP_ATCR2_ATOSEL5_Pos) /*!< 0x00700000 */ +#define TAMP_ATCR2_ATOSEL5 TAMP_ATCR2_ATOSEL5_Msk +#define TAMP_ATCR2_ATOSEL5_0 (0x1UL << TAMP_ATCR2_ATOSEL5_Pos) /*!< 0x00100000 */ +#define TAMP_ATCR2_ATOSEL5_1 (0x2UL << TAMP_ATCR2_ATOSEL5_Pos) /*!< 0x00200000 */ +#define TAMP_ATCR2_ATOSEL5_2 (0x4UL << TAMP_ATCR2_ATOSEL5_Pos) /*!< 0x00400000 */ +#define TAMP_ATCR2_ATOSEL6_Pos (23U) +#define TAMP_ATCR2_ATOSEL6_Msk (0x7UL << TAMP_ATCR2_ATOSEL6_Pos) /*!< 0x03800000 */ +#define TAMP_ATCR2_ATOSEL6 TAMP_ATCR2_ATOSEL6_Msk +#define TAMP_ATCR2_ATOSEL6_0 (0x1UL << TAMP_ATCR2_ATOSEL6_Pos) /*!< 0x00800000 */ +#define TAMP_ATCR2_ATOSEL6_1 (0x2UL << TAMP_ATCR2_ATOSEL6_Pos) /*!< 0x01000000 */ +#define TAMP_ATCR2_ATOSEL6_2 (0x4UL << TAMP_ATCR2_ATOSEL6_Pos) /*!< 0x02000000 */ +#define TAMP_ATCR2_ATOSEL7_Pos (26U) +#define TAMP_ATCR2_ATOSEL7_Msk (0x7UL << TAMP_ATCR2_ATOSEL7_Pos) /*!< 0x1C000000 */ +#define TAMP_ATCR2_ATOSEL7 TAMP_ATCR2_ATOSEL7_Msk +#define TAMP_ATCR2_ATOSEL7_0 (0x1UL << TAMP_ATCR2_ATOSEL7_Pos) /*!< 0x04000000 */ +#define TAMP_ATCR2_ATOSEL7_1 (0x2UL << TAMP_ATCR2_ATOSEL7_Pos) /*!< 0x08000000 */ +#define TAMP_ATCR2_ATOSEL7_2 (0x4UL << TAMP_ATCR2_ATOSEL7_Pos) /*!< 0x10000000 */ +#define TAMP_ATCR2_ATOSEL8_Pos (29U) +#define TAMP_ATCR2_ATOSEL8_Msk (0x7UL << TAMP_ATCR2_ATOSEL8_Pos) /*!< 0xE0000000 */ +#define TAMP_ATCR2_ATOSEL8 TAMP_ATCR2_ATOSEL8_Msk +#define TAMP_ATCR2_ATOSEL8_0 (0x1UL << TAMP_ATCR2_ATOSEL8_Pos) /*!< 0x20000000 */ +#define TAMP_ATCR2_ATOSEL8_1 (0x2UL << TAMP_ATCR2_ATOSEL8_Pos) /*!< 0x40000000 */ +#define TAMP_ATCR2_ATOSEL8_2 (0x4UL << TAMP_ATCR2_ATOSEL8_Pos) /*!< 0x80000000 */ + +/******************** Bits definition for TAMP_SECCFGR register *************/ +#define TAMP_SECCFGR_BKPRWSEC_Pos (0U) +#define TAMP_SECCFGR_BKPRWSEC_Msk (0xFFUL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x000000FF */ +#define TAMP_SECCFGR_BKPRWSEC TAMP_SECCFGR_BKPRWSEC_Msk +#define TAMP_SECCFGR_BKPRWSEC_0 (0x1UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000001 */ +#define TAMP_SECCFGR_BKPRWSEC_1 (0x2UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000002 */ +#define TAMP_SECCFGR_BKPRWSEC_2 (0x4UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000004 */ +#define TAMP_SECCFGR_BKPRWSEC_3 (0x8UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000008 */ +#define TAMP_SECCFGR_BKPRWSEC_4 (0x10UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000010 */ +#define TAMP_SECCFGR_BKPRWSEC_5 (0x20UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000020 */ +#define TAMP_SECCFGR_BKPRWSEC_6 (0x40UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000040 */ +#define TAMP_SECCFGR_BKPRWSEC_7 (0x80UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000080 */ +#define TAMP_SECCFGR_CNT1SEC_Pos (15U) +#define TAMP_SECCFGR_CNT1SEC_Msk (0x1UL << TAMP_SECCFGR_CNT1SEC_Pos) /*!< 0x00008000 */ +#define TAMP_SECCFGR_CNT1SEC TAMP_SECCFGR_CNT1SEC_Msk +#define TAMP_SECCFGR_BKPWSEC_Pos (16U) +#define TAMP_SECCFGR_BKPWSEC_Msk (0xFFUL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00FF0000 */ +#define TAMP_SECCFGR_BKPWSEC TAMP_SECCFGR_BKPWSEC_Msk +#define TAMP_SECCFGR_BKPWSEC_0 (0x1UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00010000 */ +#define TAMP_SECCFGR_BKPWSEC_1 (0x2UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00020000 */ +#define TAMP_SECCFGR_BKPWSEC_2 (0x4UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00040000 */ +#define TAMP_SECCFGR_BKPWSEC_3 (0x8UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00080000 */ +#define TAMP_SECCFGR_BKPWSEC_4 (0x10UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00100000 */ +#define TAMP_SECCFGR_BKPWSEC_5 (0x20UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00200000 */ +#define TAMP_SECCFGR_BKPWSEC_6 (0x40UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00400000 */ +#define TAMP_SECCFGR_BKPWSEC_7 (0x80UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00800000 */ +#define TAMP_SECCFGR_BHKLOCK_Pos (30U) +#define TAMP_SECCFGR_BHKLOCK_Msk (0x1UL << TAMP_SECCFGR_BHKLOCK_Pos) /*!< 0x40000000 */ +#define TAMP_SECCFGR_BHKLOCK TAMP_SECCFGR_BHKLOCK_Msk +#define TAMP_SECCFGR_TAMPSEC_Pos (31U) +#define TAMP_SECCFGR_TAMPSEC_Msk (0x1UL << TAMP_SECCFGR_TAMPSEC_Pos) /*!< 0x80000000 */ +#define TAMP_SECCFGR_TAMPSEC TAMP_SECCFGR_TAMPSEC_Msk + +/******************** Bits definition for TAMP_PRIVCFGR register ************/ +#define TAMP_PRIVCFGR_CNT1PRIV_Pos (15U) +#define TAMP_PRIVCFGR_CNT1PRIV_Msk (0x1UL << TAMP_PRIVCFGR_CNT1PRIV_Pos) /*!< 0x20000000 */ +#define TAMP_PRIVCFGR_CNT1PRIV TAMP_PRIVCFGR_CNT1PRIV_Msk +#define TAMP_PRIVCFGR_BKPRWPRIV_Pos (29U) +#define TAMP_PRIVCFGR_BKPRWPRIV_Msk (0x1UL << TAMP_PRIVCFGR_BKPRWPRIV_Pos) /*!< 0x20000000 */ +#define TAMP_PRIVCFGR_BKPRWPRIV TAMP_PRIVCFGR_BKPRWPRIV_Msk +#define TAMP_PRIVCFGR_BKPWPRIV_Pos (30U) +#define TAMP_PRIVCFGR_BKPWPRIV_Msk (0x1UL << TAMP_PRIVCFGR_BKPWPRIV_Pos) /*!< 0x40000000 */ +#define TAMP_PRIVCFGR_BKPWPRIV TAMP_PRIVCFGR_BKPWPRIV_Msk +#define TAMP_PRIVCFGR_TAMPPRIV_Pos (31U) +#define TAMP_PRIVCFGR_TAMPPRIV_Msk (0x1UL << TAMP_PRIVCFGR_TAMPPRIV_Pos) /*!< 0x80000000 */ +#define TAMP_PRIVCFGR_TAMPPRIV TAMP_PRIVCFGR_TAMPPRIV_Msk + +/******************** Bits definition for TAMP_IER register *****************/ +#define TAMP_IER_TAMP1IE_Pos (0U) +#define TAMP_IER_TAMP1IE_Msk (0x1UL << TAMP_IER_TAMP1IE_Pos) /*!< 0x00000001 */ +#define TAMP_IER_TAMP1IE TAMP_IER_TAMP1IE_Msk +#define TAMP_IER_TAMP2IE_Pos (1U) +#define TAMP_IER_TAMP2IE_Msk (0x1UL << TAMP_IER_TAMP2IE_Pos) /*!< 0x00000002 */ +#define TAMP_IER_TAMP2IE TAMP_IER_TAMP2IE_Msk +#define TAMP_IER_TAMP3IE_Pos (2U) +#define TAMP_IER_TAMP3IE_Msk (0x1UL << TAMP_IER_TAMP3IE_Pos) /*!< 0x00000004 */ +#define TAMP_IER_TAMP3IE TAMP_IER_TAMP3IE_Msk +#define TAMP_IER_TAMP4IE_Pos (3U) +#define TAMP_IER_TAMP4IE_Msk (0x1UL << TAMP_IER_TAMP4IE_Pos) /*!< 0x00000008 */ +#define TAMP_IER_TAMP4IE TAMP_IER_TAMP4IE_Msk +#define TAMP_IER_TAMP5IE_Pos (4U) +#define TAMP_IER_TAMP5IE_Msk (0x1UL << TAMP_IER_TAMP5IE_Pos) /*!< 0x00000010 */ +#define TAMP_IER_TAMP5IE TAMP_IER_TAMP5IE_Msk +#define TAMP_IER_TAMP6IE_Pos (5U) +#define TAMP_IER_TAMP6IE_Msk (0x1UL << TAMP_IER_TAMP6IE_Pos) /*!< 0x00000020 */ +#define TAMP_IER_TAMP6IE TAMP_IER_TAMP6IE_Msk +#define TAMP_IER_TAMP7IE_Pos (6U) +#define TAMP_IER_TAMP7IE_Msk (0x1UL << TAMP_IER_TAMP7IE_Pos) /*!< 0x00000040 */ +#define TAMP_IER_TAMP7IE TAMP_IER_TAMP7IE_Msk +#define TAMP_IER_TAMP8IE_Pos (7U) +#define TAMP_IER_TAMP8IE_Msk (0x1UL << TAMP_IER_TAMP8IE_Pos) /*!< 0x00000080 */ +#define TAMP_IER_TAMP8IE TAMP_IER_TAMP8IE_Msk +#define TAMP_IER_ITAMP1IE_Pos (16U) +#define TAMP_IER_ITAMP1IE_Msk (0x1UL << TAMP_IER_ITAMP1IE_Pos) /*!< 0x00010000 */ +#define TAMP_IER_ITAMP1IE TAMP_IER_ITAMP1IE_Msk +#define TAMP_IER_ITAMP2IE_Pos (17U) +#define TAMP_IER_ITAMP2IE_Msk (0x1UL << TAMP_IER_ITAMP2IE_Pos) /*!< 0x00020000 */ +#define TAMP_IER_ITAMP2IE TAMP_IER_ITAMP2IE_Msk +#define TAMP_IER_ITAMP3IE_Pos (18U) +#define TAMP_IER_ITAMP3IE_Msk (0x1UL << TAMP_IER_ITAMP3IE_Pos) /*!< 0x00040000 */ +#define TAMP_IER_ITAMP3IE TAMP_IER_ITAMP3IE_Msk +#define TAMP_IER_ITAMP4IE_Pos (19U) +#define TAMP_IER_ITAMP4IE_Msk (0x1UL << TAMP_IER_ITAMP4IE_Pos) /*!< 0x00080000 */ +#define TAMP_IER_ITAMP4IE TAMP_IER_ITAMP4IE_Msk +#define TAMP_IER_ITAMP5IE_Pos (20U) +#define TAMP_IER_ITAMP5IE_Msk (0x1UL << TAMP_IER_ITAMP5IE_Pos) /*!< 0x00100000 */ +#define TAMP_IER_ITAMP5IE TAMP_IER_ITAMP5IE_Msk +#define TAMP_IER_ITAMP6IE_Pos (21U) +#define TAMP_IER_ITAMP6IE_Msk (0x1UL << TAMP_IER_ITAMP6IE_Pos) /*!< 0x00200000 */ +#define TAMP_IER_ITAMP6IE TAMP_IER_ITAMP6IE_Msk +#define TAMP_IER_ITAMP7IE_Pos (22U) +#define TAMP_IER_ITAMP7IE_Msk (0x1UL << TAMP_IER_ITAMP7IE_Pos) /*!< 0x00400000 */ +#define TAMP_IER_ITAMP7IE TAMP_IER_ITAMP7IE_Msk +#define TAMP_IER_ITAMP8IE_Pos (23U) +#define TAMP_IER_ITAMP8IE_Msk (0x1UL << TAMP_IER_ITAMP8IE_Pos) /*!< 0x00800000 */ +#define TAMP_IER_ITAMP8IE TAMP_IER_ITAMP8IE_Msk +#define TAMP_IER_ITAMP9IE_Pos (24U) +#define TAMP_IER_ITAMP9IE_Msk (0x1UL << TAMP_IER_ITAMP9IE_Pos) /*!< 0x01000000 */ +#define TAMP_IER_ITAMP9IE TAMP_IER_ITAMP9IE_Msk +#define TAMP_IER_ITAMP11IE_Pos (26U) +#define TAMP_IER_ITAMP11IE_Msk (0x1UL << TAMP_IER_ITAMP11IE_Pos) /*!< 0x04000000 */ +#define TAMP_IER_ITAMP11IE TAMP_IER_ITAMP11IE_Msk +#define TAMP_IER_ITAMP12IE_Pos (27U) +#define TAMP_IER_ITAMP12IE_Msk (0x1UL << TAMP_IER_ITAMP12IE_Pos) /*!< 0x08000000 */ +#define TAMP_IER_ITAMP12IE TAMP_IER_ITAMP12IE_Msk +#define TAMP_IER_ITAMP13IE_Pos (28U) +#define TAMP_IER_ITAMP13IE_Msk (0x1UL << TAMP_IER_ITAMP13IE_Pos) /*!< 0x10000000 */ +#define TAMP_IER_ITAMP13IE TAMP_IER_ITAMP13IE_Msk +#define TAMP_IER_ITAMP15IE_Pos (30U) +#define TAMP_IER_ITAMP15IE_Msk (0x1UL << TAMP_IER_ITAMP15IE_Pos) /*!< 0x40000000 */ +#define TAMP_IER_ITAMP15IE TAMP_IER_ITAMP15IE_Msk + +/******************** Bits definition for TAMP_SR register *****************/ +#define TAMP_SR_TAMP1F_Pos (0U) +#define TAMP_SR_TAMP1F_Msk (0x1UL << TAMP_SR_TAMP1F_Pos) /*!< 0x00000001 */ +#define TAMP_SR_TAMP1F TAMP_SR_TAMP1F_Msk +#define TAMP_SR_TAMP2F_Pos (1U) +#define TAMP_SR_TAMP2F_Msk (0x1UL << TAMP_SR_TAMP2F_Pos) /*!< 0x00000002 */ +#define TAMP_SR_TAMP2F TAMP_SR_TAMP2F_Msk +#define TAMP_SR_TAMP3F_Pos (2U) +#define TAMP_SR_TAMP3F_Msk (0x1UL << TAMP_SR_TAMP3F_Pos) /*!< 0x00000004 */ +#define TAMP_SR_TAMP3F TAMP_SR_TAMP3F_Msk +#define TAMP_SR_TAMP4F_Pos (3U) +#define TAMP_SR_TAMP4F_Msk (0x1UL << TAMP_SR_TAMP4F_Pos) /*!< 0x00000008 */ +#define TAMP_SR_TAMP4F TAMP_SR_TAMP4F_Msk +#define TAMP_SR_TAMP5F_Pos (4U) +#define TAMP_SR_TAMP5F_Msk (0x1UL << TAMP_SR_TAMP5F_Pos) /*!< 0x00000010 */ +#define TAMP_SR_TAMP5F TAMP_SR_TAMP5F_Msk +#define TAMP_SR_TAMP6F_Pos (5U) +#define TAMP_SR_TAMP6F_Msk (0x1UL << TAMP_SR_TAMP6F_Pos) /*!< 0x00000020 */ +#define TAMP_SR_TAMP6F TAMP_SR_TAMP6F_Msk +#define TAMP_SR_TAMP7F_Pos (6U) +#define TAMP_SR_TAMP7F_Msk (0x1UL << TAMP_SR_TAMP7F_Pos) /*!< 0x00000040 */ +#define TAMP_SR_TAMP7F TAMP_SR_TAMP7F_Msk +#define TAMP_SR_TAMP8F_Pos (7U) +#define TAMP_SR_TAMP8F_Msk (0x1UL << TAMP_SR_TAMP8F_Pos) /*!< 0x00000080 */ +#define TAMP_SR_TAMP8F TAMP_SR_TAMP8F_Msk +#define TAMP_SR_ITAMP1F_Pos (16U) +#define TAMP_SR_ITAMP1F_Msk (0x1UL << TAMP_SR_ITAMP1F_Pos) /*!< 0x00010000 */ +#define TAMP_SR_ITAMP1F TAMP_SR_ITAMP1F_Msk +#define TAMP_SR_ITAMP2F_Pos (17U) +#define TAMP_SR_ITAMP2F_Msk (0x1UL << TAMP_SR_ITAMP2F_Pos) /*!< 0x00020000 */ +#define TAMP_SR_ITAMP2F TAMP_SR_ITAMP2F_Msk +#define TAMP_SR_ITAMP3F_Pos (18U) +#define TAMP_SR_ITAMP3F_Msk (0x1UL << TAMP_SR_ITAMP3F_Pos) /*!< 0x00040000 */ +#define TAMP_SR_ITAMP3F TAMP_SR_ITAMP3F_Msk +#define TAMP_SR_ITAMP4F_Pos (19U) +#define TAMP_SR_ITAMP4F_Msk (0x1UL << TAMP_SR_ITAMP4F_Pos) /*!< 0x00080000 */ +#define TAMP_SR_ITAMP4F TAMP_SR_ITAMP4F_Msk +#define TAMP_SR_ITAMP5F_Pos (20U) +#define TAMP_SR_ITAMP5F_Msk (0x1UL << TAMP_SR_ITAMP5F_Pos) /*!< 0x00100000 */ +#define TAMP_SR_ITAMP5F TAMP_SR_ITAMP5F_Msk +#define TAMP_SR_ITAMP6F_Pos (21U) +#define TAMP_SR_ITAMP6F_Msk (0x1UL << TAMP_SR_ITAMP6F_Pos) /*!< 0x00200000 */ +#define TAMP_SR_ITAMP6F TAMP_SR_ITAMP6F_Msk +#define TAMP_SR_ITAMP7F_Pos (22U) +#define TAMP_SR_ITAMP7F_Msk (0x1UL << TAMP_SR_ITAMP7F_Pos) /*!< 0x00400000 */ +#define TAMP_SR_ITAMP7F TAMP_SR_ITAMP7F_Msk +#define TAMP_SR_ITAMP8F_Pos (23U) +#define TAMP_SR_ITAMP8F_Msk (0x1UL << TAMP_SR_ITAMP8F_Pos) /*!< 0x00800000 */ +#define TAMP_SR_ITAMP8F TAMP_SR_ITAMP8F_Msk +#define TAMP_SR_ITAMP9F_Pos (24U) +#define TAMP_SR_ITAMP9F_Msk (0x1UL << TAMP_SR_ITAMP9F_Pos) /*!< 0x01000000 */ +#define TAMP_SR_ITAMP9F TAMP_SR_ITAMP9F_Msk +#define TAMP_SR_ITAMP11F_Pos (26U) +#define TAMP_SR_ITAMP11F_Msk (0x1UL << TAMP_SR_ITAMP11F_Pos) /*!< 0x04000000 */ +#define TAMP_SR_ITAMP11F TAMP_SR_ITAMP11F_Msk +#define TAMP_SR_ITAMP12F_Pos (27U) +#define TAMP_SR_ITAMP12F_Msk (0x1UL << TAMP_SR_ITAMP12F_Pos) /*!< 0x08000000 */ +#define TAMP_SR_ITAMP12F TAMP_SR_ITAMP12F_Msk +#define TAMP_SR_ITAMP13F_Pos (28U) +#define TAMP_SR_ITAMP13F_Msk (0x1UL << TAMP_SR_ITAMP13F_Pos) /*!< 0x10000000 */ +#define TAMP_SR_ITAMP13F TAMP_SR_ITAMP13F_Msk +#define TAMP_SR_ITAMP15F_Pos (30U) +#define TAMP_SR_ITAMP15F_Msk (0x1UL << TAMP_SR_ITAMP15F_Pos) /*!< 0x40000000 */ +#define TAMP_SR_ITAMP15F TAMP_SR_ITAMP15F_Msk + +/******************** Bits definition for TAMP_MISR register ****************/ +#define TAMP_MISR_TAMP1MF_Pos (0U) +#define TAMP_MISR_TAMP1MF_Msk (0x1UL << TAMP_MISR_TAMP1MF_Pos) /*!< 0x00000001 */ +#define TAMP_MISR_TAMP1MF TAMP_MISR_TAMP1MF_Msk +#define TAMP_MISR_TAMP2MF_Pos (1U) +#define TAMP_MISR_TAMP2MF_Msk (0x1UL << TAMP_MISR_TAMP2MF_Pos) /*!< 0x00000002 */ +#define TAMP_MISR_TAMP2MF TAMP_MISR_TAMP2MF_Msk +#define TAMP_MISR_TAMP3MF_Pos (2U) +#define TAMP_MISR_TAMP3MF_Msk (0x1UL << TAMP_MISR_TAMP3MF_Pos) /*!< 0x00000004 */ +#define TAMP_MISR_TAMP3MF TAMP_MISR_TAMP3MF_Msk +#define TAMP_MISR_TAMP4MF_Pos (3U) +#define TAMP_MISR_TAMP4MF_Msk (0x1UL << TAMP_MISR_TAMP4MF_Pos) /*!< 0x00000008 */ +#define TAMP_MISR_TAMP4MF TAMP_MISR_TAMP4MF_Msk +#define TAMP_MISR_TAMP5MF_Pos (4U) +#define TAMP_MISR_TAMP5MF_Msk (0x1UL << TAMP_MISR_TAMP5MF_Pos) /*!< 0x00000010 */ +#define TAMP_MISR_TAMP5MF TAMP_MISR_TAMP5MF_Msk +#define TAMP_MISR_TAMP6MF_Pos (5U) +#define TAMP_MISR_TAMP6MF_Msk (0x1UL << TAMP_MISR_TAMP6MF_Pos) /*!< 0x00000020 */ +#define TAMP_MISR_TAMP6MF TAMP_MISR_TAMP6MF_Msk +#define TAMP_MISR_TAMP7MF_Pos (6U) +#define TAMP_MISR_TAMP7MF_Msk (0x1UL << TAMP_MISR_TAMP7MF_Pos) /*!< 0x00000040 */ +#define TAMP_MISR_TAMP7MF TAMP_MISR_TAMP7MF_Msk +#define TAMP_MISR_TAMP8MF_Pos (7U) +#define TAMP_MISR_TAMP8MF_Msk (0x1UL << TAMP_MISR_TAMP8MF_Pos) /*!< 0x00000080 */ +#define TAMP_MISR_TAMP8MF TAMP_MISR_TAMP8MF_Msk +#define TAMP_MISR_ITAMP1MF_Pos (16U) +#define TAMP_MISR_ITAMP1MF_Msk (0x1UL << TAMP_MISR_ITAMP1MF_Pos) /*!< 0x00010000 */ +#define TAMP_MISR_ITAMP1MF TAMP_MISR_ITAMP1MF_Msk +#define TAMP_MISR_ITAMP2MF_Pos (17U) +#define TAMP_MISR_ITAMP2MF_Msk (0x1UL << TAMP_MISR_ITAMP2MF_Pos) /*!< 0x00020000 */ +#define TAMP_MISR_ITAMP2MF TAMP_MISR_ITAMP2MF_Msk +#define TAMP_MISR_ITAMP3MF_Pos (18U) +#define TAMP_MISR_ITAMP3MF_Msk (0x1UL << TAMP_MISR_ITAMP3MF_Pos) /*!< 0x00040000 */ +#define TAMP_MISR_ITAMP3MF TAMP_MISR_ITAMP3MF_Msk +#define TAMP_MISR_ITAMP4MF_Pos (19U) +#define TAMP_MISR_ITAMP4MF_Msk (0x1UL << TAMP_MISR_ITAMP4MF_Pos) /*!< 0x00080000 */ +#define TAMP_MISR_ITAMP4MF TAMP_MISR_ITAMP4MF_Msk +#define TAMP_MISR_ITAMP5MF_Pos (20U) +#define TAMP_MISR_ITAMP5MF_Msk (0x1UL << TAMP_MISR_ITAMP5MF_Pos) /*!< 0x00100000 */ +#define TAMP_MISR_ITAMP5MF TAMP_MISR_ITAMP5MF_Msk +#define TAMP_MISR_ITAMP6MF_Pos (21U) +#define TAMP_MISR_ITAMP6MF_Msk (0x1UL << TAMP_MISR_ITAMP6MF_Pos) /*!< 0x00200000 */ +#define TAMP_MISR_ITAMP6MF TAMP_MISR_ITAMP6MF_Msk +#define TAMP_MISR_ITAMP7MF_Pos (22U) +#define TAMP_MISR_ITAMP7MF_Msk (0x1UL << TAMP_MISR_ITAMP7MF_Pos) /*!< 0x00400000 */ +#define TAMP_MISR_ITAMP7MF TAMP_MISR_ITAMP7MF_Msk +#define TAMP_MISR_ITAMP8MF_Pos (23U) +#define TAMP_MISR_ITAMP8MF_Msk (0x1UL << TAMP_MISR_ITAMP8MF_Pos) /*!< 0x00800000 */ +#define TAMP_MISR_ITAMP8MF TAMP_MISR_ITAMP8MF_Msk +#define TAMP_MISR_ITAMP9MF_Pos (24U) +#define TAMP_MISR_ITAMP9MF_Msk (0x1UL << TAMP_MISR_ITAMP9MF_Pos) /*!< 0x01000000 */ +#define TAMP_MISR_ITAMP9MF TAMP_MISR_ITAMP9MF_Msk +#define TAMP_MISR_ITAMP11MF_Pos (26U) +#define TAMP_MISR_ITAMP11MF_Msk (0x1UL << TAMP_MISR_ITAMP11MF_Pos) /*!< 0x04000000 */ +#define TAMP_MISR_ITAMP11MF TAMP_MISR_ITAMP11MF_Msk +#define TAMP_MISR_ITAMP12MF_Pos (27U) +#define TAMP_MISR_ITAMP12MF_Msk (0x1UL << TAMP_MISR_ITAMP12MF_Pos) /*!< 0x08000000 */ +#define TAMP_MISR_ITAMP12MF TAMP_MISR_ITAMP12MF_Msk +#define TAMP_MISR_ITAMP13MF_Pos (28U) +#define TAMP_MISR_ITAMP13MF_Msk (0x1UL << TAMP_MISR_ITAMP13MF_Pos) /*!< 0x10000000 */ +#define TAMP_MISR_ITAMP13MF TAMP_MISR_ITAMP13MF_Msk +#define TAMP_MISR_ITAMP15MF_Pos (30U) +#define TAMP_MISR_ITAMP15MF_Msk (0x1UL << TAMP_MISR_ITAMP15MF_Pos) /*!< 0x40000000 */ +#define TAMP_MISR_ITAMP15MF TAMP_MISR_ITAMP15MF_Msk + +/******************** Bits definition for TAMP_SMISR register ************ *****/ +#define TAMP_SMISR_TAMP1MF_Pos (0U) +#define TAMP_SMISR_TAMP1MF_Msk (0x1UL << TAMP_SMISR_TAMP1MF_Pos) /*!< 0x00000001 */ +#define TAMP_SMISR_TAMP1MF TAMP_SMISR_TAMP1MF_Msk +#define TAMP_SMISR_TAMP2MF_Pos (1U) +#define TAMP_SMISR_TAMP2MF_Msk (0x1UL << TAMP_SMISR_TAMP2MF_Pos) /*!< 0x00000002 */ +#define TAMP_SMISR_TAMP2MF TAMP_SMISR_TAMP2MF_Msk +#define TAMP_SMISR_TAMP3MF_Pos (2U) +#define TAMP_SMISR_TAMP3MF_Msk (0x1UL << TAMP_SMISR_TAMP3MF_Pos) /*!< 0x00000004 */ +#define TAMP_SMISR_TAMP3MF TAMP_SMISR_TAMP3MF_Msk +#define TAMP_SMISR_TAMP4MF_Pos (3U) +#define TAMP_SMISR_TAMP4MF_Msk (0x1UL << TAMP_SMISR_TAMP4MF_Pos) /*!< 0x00000008 */ +#define TAMP_SMISR_TAMP4MF TAMP_SMISR_TAMP4MF_Msk +#define TAMP_SMISR_TAMP5MF_Pos (4U) +#define TAMP_SMISR_TAMP5MF_Msk (0x1UL << TAMP_SMISR_TAMP5MF_Pos) /*!< 0x00000010 */ +#define TAMP_SMISR_TAMP5MF TAMP_SMISR_TAMP5MF_Msk +#define TAMP_SMISR_TAMP6MF_Pos (5U) +#define TAMP_SMISR_TAMP6MF_Msk (0x1UL << TAMP_SMISR_TAMP6MF_Pos) /*!< 0x00000020 */ +#define TAMP_SMISR_TAMP6MF TAMP_SMISR_TAMP6MF_Msk +#define TAMP_SMISR_TAMP7MF_Pos (6U) +#define TAMP_SMISR_TAMP7MF_Msk (0x1UL << TAMP_SMISR_TAMP7MF_Pos) /*!< 0x00000040 */ +#define TAMP_SMISR_TAMP7MF TAMP_SMISR_TAMP7MF_Msk +#define TAMP_SMISR_TAMP8MF_Pos (7U) +#define TAMP_SMISR_TAMP8MF_Msk (0x1UL << TAMP_SMISR_TAMP8MF_Pos) /*!< 0x00000080 */ +#define TAMP_SMISR_TAMP8MF TAMP_SMISR_TAMP8MF_Msk +#define TAMP_SMISR_ITAMP1MF_Pos (16U) +#define TAMP_SMISR_ITAMP1MF_Msk (0x1UL << TAMP_SMISR_ITAMP1MF_Pos) /*!< 0x00010000 */ +#define TAMP_SMISR_ITAMP1MF TAMP_SMISR_ITAMP1MF_Msk +#define TAMP_SMISR_ITAMP2MF_Pos (17U) +#define TAMP_SMISR_ITAMP2MF_Msk (0x1UL << TAMP_SMISR_ITAMP2MF_Pos) /*!< 0x00020000 */ +#define TAMP_SMISR_ITAMP2MF TAMP_SMISR_ITAMP2MF_Msk +#define TAMP_SMISR_ITAMP3MF_Pos (18U) +#define TAMP_SMISR_ITAMP3MF_Msk (0x1UL << TAMP_SMISR_ITAMP3MF_Pos) /*!< 0x00040000 */ +#define TAMP_SMISR_ITAMP3MF TAMP_SMISR_ITAMP3MF_Msk +#define TAMP_SMISR_ITAMP4MF_Pos (19U) +#define TAMP_SMISR_ITAMP4MF_Msk (0x1UL << TAMP_SMISR_ITAMP4MF_Pos) /*!< 0x00080000 */ +#define TAMP_SMISR_ITAMP4MF TAMP_SMISR_ITAMP4MF_Msk +#define TAMP_SMISR_ITAMP5MF_Pos (20U) +#define TAMP_SMISR_ITAMP5MF_Msk (0x1UL << TAMP_SMISR_ITAMP5MF_Pos) /*!< 0x00100000 */ +#define TAMP_SMISR_ITAMP5MF TAMP_SMISR_ITAMP5MF_Msk +#define TAMP_SMISR_ITAMP6MF_Pos (21U) +#define TAMP_SMISR_ITAMP6MF_Msk (0x1UL << TAMP_SMISR_ITAMP6MF_Pos) /*!< 0x00200000 */ +#define TAMP_SMISR_ITAMP6MF TAMP_SMISR_ITAMP6MF_Msk +#define TAMP_SMISR_ITAMP7MF_Pos (22U) +#define TAMP_SMISR_ITAMP7MF_Msk (0x1UL << TAMP_SMISR_ITAMP7MF_Pos) /*!< 0x00400000 */ +#define TAMP_SMISR_ITAMP7MF TAMP_SMISR_ITAMP7MF_Msk +#define TAMP_SMISR_ITAMP8MF_Pos (23U) +#define TAMP_SMISR_ITAMP8MF_Msk (0x1UL << TAMP_SMISR_ITAMP8MF_Pos) /*!< 0x00800000 */ +#define TAMP_SMISR_ITAMP8MF TAMP_SMISR_ITAMP8MF_Msk +#define TAMP_SMISR_ITAMP9MF_Pos (24U) +#define TAMP_SMISR_ITAMP9MF_Msk (0x1UL << TAMP_SMISR_ITAMP9MF_Pos) /*!< 0x00100000 */ +#define TAMP_SMISR_ITAMP9MF TAMP_SMISR_ITAMP9MF_Msk +#define TAMP_SMISR_ITAMP11MF_Pos (26U) +#define TAMP_SMISR_ITAMP11MF_Msk (0x1UL << TAMP_SMISR_ITAMP11MF_Pos) /*!< 0x00400000 */ +#define TAMP_SMISR_ITAMP11MF TAMP_SMISR_ITAMP11MF_Msk +#define TAMP_SMISR_ITAMP12MF_Pos (27U) +#define TAMP_SMISR_ITAMP12MF_Msk (0x1UL << TAMP_SMISR_ITAMP12MF_Pos) /*!< 0x08000000 */ +#define TAMP_SMISR_ITAMP12MF TAMP_SMISR_ITAMP12MF_Msk +#define TAMP_SMISR_ITAMP13MF_Pos (28U) +#define TAMP_SMISR_ITAMP13MF_Msk (0x1UL << TAMP_SMISR_ITAMP13MF_Pos) /*!< 0x10000000 */ +#define TAMP_SMISR_ITAMP13MF TAMP_SMISR_ITAMP13MF_Msk +#define TAMP_SMISR_ITAMP15MF_Pos (30U) +#define TAMP_SMISR_ITAMP15MF_Msk (0x1UL << TAMP_SMISR_ITAMP15MF_Pos) /*!< 0x40000000 */ +#define TAMP_SMISR_ITAMP15MF TAMP_SMISR_ITAMP15MF_Msk + +/******************** Bits definition for TAMP_SCR register *****************/ +#define TAMP_SCR_CTAMP1F_Pos (0U) +#define TAMP_SCR_CTAMP1F_Msk (0x1UL << TAMP_SCR_CTAMP1F_Pos) /*!< 0x00000001 */ +#define TAMP_SCR_CTAMP1F TAMP_SCR_CTAMP1F_Msk +#define TAMP_SCR_CTAMP2F_Pos (1U) +#define TAMP_SCR_CTAMP2F_Msk (0x1UL << TAMP_SCR_CTAMP2F_Pos) /*!< 0x00000002 */ +#define TAMP_SCR_CTAMP2F TAMP_SCR_CTAMP2F_Msk +#define TAMP_SCR_CTAMP3F_Pos (2U) +#define TAMP_SCR_CTAMP3F_Msk (0x1UL << TAMP_SCR_CTAMP3F_Pos) /*!< 0x00000004 */ +#define TAMP_SCR_CTAMP3F TAMP_SCR_CTAMP3F_Msk +#define TAMP_SCR_CTAMP4F_Pos (3U) +#define TAMP_SCR_CTAMP4F_Msk (0x1UL << TAMP_SCR_CTAMP4F_Pos) /*!< 0x00000008 */ +#define TAMP_SCR_CTAMP4F TAMP_SCR_CTAMP4F_Msk +#define TAMP_SCR_CTAMP5F_Pos (4U) +#define TAMP_SCR_CTAMP5F_Msk (0x1UL << TAMP_SCR_CTAMP5F_Pos) /*!< 0x00000010 */ +#define TAMP_SCR_CTAMP5F TAMP_SCR_CTAMP5F_Msk +#define TAMP_SCR_CTAMP6F_Pos (5U) +#define TAMP_SCR_CTAMP6F_Msk (0x1UL << TAMP_SCR_CTAMP6F_Pos) /*!< 0x00000020 */ +#define TAMP_SCR_CTAMP6F TAMP_SCR_CTAMP6F_Msk +#define TAMP_SCR_CTAMP7F_Pos (6U) +#define TAMP_SCR_CTAMP7F_Msk (0x1UL << TAMP_SCR_CTAMP7F_Pos) /*!< 0x00000040 */ +#define TAMP_SCR_CTAMP7F TAMP_SCR_CTAMP7F_Msk +#define TAMP_SCR_CTAMP8F_Pos (7U) +#define TAMP_SCR_CTAMP8F_Msk (0x1UL << TAMP_SCR_CTAMP8F_Pos) /*!< 0x00000080 */ +#define TAMP_SCR_CTAMP8F TAMP_SCR_CTAMP8F_Msk +#define TAMP_SCR_CITAMP1F_Pos (16U) +#define TAMP_SCR_CITAMP1F_Msk (0x1UL << TAMP_SCR_CITAMP1F_Pos) /*!< 0x00010000 */ +#define TAMP_SCR_CITAMP1F TAMP_SCR_CITAMP1F_Msk +#define TAMP_SCR_CITAMP2F_Pos (17U) +#define TAMP_SCR_CITAMP2F_Msk (0x1UL << TAMP_SCR_CITAMP2F_Pos) /*!< 0x00020000 */ +#define TAMP_SCR_CITAMP2F TAMP_SCR_CITAMP2F_Msk +#define TAMP_SCR_CITAMP3F_Pos (18U) +#define TAMP_SCR_CITAMP3F_Msk (0x1UL << TAMP_SCR_CITAMP3F_Pos) /*!< 0x00040000 */ +#define TAMP_SCR_CITAMP3F TAMP_SCR_CITAMP3F_Msk +#define TAMP_SCR_CITAMP4F_Pos (19U) +#define TAMP_SCR_CITAMP4F_Msk (0x1UL << TAMP_SCR_CITAMP4F_Pos) /*!< 0x00080000 */ +#define TAMP_SCR_CITAMP4F TAMP_SCR_CITAMP4F_Msk +#define TAMP_SCR_CITAMP5F_Pos (20U) +#define TAMP_SCR_CITAMP5F_Msk (0x1UL << TAMP_SCR_CITAMP5F_Pos) /*!< 0x00100000 */ +#define TAMP_SCR_CITAMP5F TAMP_SCR_CITAMP5F_Msk +#define TAMP_SCR_CITAMP6F_Pos (21U) +#define TAMP_SCR_CITAMP6F_Msk (0x1UL << TAMP_SCR_CITAMP6F_Pos) /*!< 0x00200000 */ +#define TAMP_SCR_CITAMP6F TAMP_SCR_CITAMP6F_Msk +#define TAMP_SCR_CITAMP7F_Pos (22U) +#define TAMP_SCR_CITAMP7F_Msk (0x1UL << TAMP_SCR_CITAMP7F_Pos) /*!< 0x00400000 */ +#define TAMP_SCR_CITAMP7F TAMP_SCR_CITAMP7F_Msk +#define TAMP_SCR_CITAMP8F_Pos (23U) +#define TAMP_SCR_CITAMP8F_Msk (0x1UL << TAMP_SCR_CITAMP8F_Pos) /*!< 0x00800000 */ +#define TAMP_SCR_CITAMP8F TAMP_SCR_CITAMP8F_Msk +#define TAMP_SCR_CITAMP9F_Pos (24U) +#define TAMP_SCR_CITAMP9F_Msk (0x1UL << TAMP_SCR_CITAMP9F_Pos) /*!< 0x00100000 */ +#define TAMP_SCR_CITAMP9F TAMP_SCR_CITAMP9F_Msk +#define TAMP_SCR_CITAMP11F_Pos (26U) +#define TAMP_SCR_CITAMP11F_Msk (0x1UL << TAMP_SCR_CITAMP11F_Pos) /*!< 0x00400000 */ +#define TAMP_SCR_CITAMP11F TAMP_SCR_CITAMP11F_Msk +#define TAMP_SCR_CITAMP12F_Pos (27U) +#define TAMP_SCR_CITAMP12F_Msk (0x1UL << TAMP_SCR_CITAMP12F_Pos) /*!< 0x08000000 */ +#define TAMP_SCR_CITAMP12F TAMP_SCR_CITAMP12F_Msk +#define TAMP_SCR_CITAMP13F_Pos (28U) +#define TAMP_SCR_CITAMP13F_Msk (0x1UL << TAMP_SCR_CITAMP13F_Pos) /*!< 0x10000000 */ +#define TAMP_SCR_CITAMP13F TAMP_SCR_CITAMP13F_Msk +#define TAMP_SCR_CITAMP15F_Pos (30U) +#define TAMP_SCR_CITAMP15F_Msk (0x1UL << TAMP_SCR_CITAMP15F_Pos) /*!< 0x40000000 */ +#define TAMP_SCR_CITAMP15F TAMP_SCR_CITAMP15F_Msk +/******************** Bits definition for TAMP_COUNT1R register ***************/ +#define TAMP_COUNT1R_COUNT_Pos (0U) +#define TAMP_COUNT1R_COUNT_Msk (0xFFFFFFFFUL << TAMP_COUNT1R_COUNT_Pos)/*!< 0xFFFFFFFF */ +#define TAMP_COUNT1R_COUNT TAMP_COUNT1R_COUNT_Msk + +/******************** Bits definition for TAMP_OR register ***************/ +#define TAMP_OR_OUT3_RMP_Pos (1U) +#define TAMP_OR_OUT3_RMP_Msk (0x2UL << TAMP_OR_OUT3_RMP_Pos) /*!< 0x00000006 */ +#define TAMP_OR_OUT3_RMP TAMP_OR_OUT3_RMP_Msk +#define TAMP_OR_OUT3_RMP_0 (0x1UL << TAMP_OR_OUT3_RMP_Pos) /*!< 0x00100000 */ +#define TAMP_OR_OUT3_RMP_1 (0x2UL << TAMP_OR_OUT3_RMP_Pos) /*!< 0x00200000 */ +#define TAMP_OR_OUT5_RMP_Pos (3U) +#define TAMP_OR_OUT5_RMP_Msk (0x1UL << TAMP_OR_OUT5_RMP_Pos) /*!< 0x00000001 */ +#define TAMP_OR_OUT5_RMP TAMP_OR_OUT5_RMP_Msk +#define TAMP_OR_IN2_RMP_Pos (8U) +#define TAMP_OR_IN2_RMP_Msk (0x1UL << TAMP_OR_IN2_RMP_Pos) /*!< 0x00000001 */ +#define TAMP_OR_IN2_RMP TAMP_OR_IN2_RMP_Msk +#define TAMP_OR_IN3_RMP_Pos (9U) +#define TAMP_OR_IN3_RMP_Msk (0x1UL << TAMP_OR_IN3_RMP_Pos) /*!< 0x00000001 */ +#define TAMP_OR_IN3_RMP TAMP_OR_IN3_RMP_Msk +#define TAMP_OR_IN4_RMP_Pos (10U) +#define TAMP_OR_IN4_RMP_Msk (0x1UL << TAMP_OR_IN4_RMP_Pos) /*!< 0x00000001 */ +#define TAMP_OR_IN4_RMP TAMP_OR_IN4_RMP_Msk + +/******************** Bits definition for TAMP_ERCFG register ***************/ +#define TAMP_ERCFGR_ERCFG0_Pos (0U) +#define TAMP_ERCFGR_ERCFG0_Msk (0x1UL << TAMP_ERCFGR_ERCFG0_Pos) /*!< 0x00000001 */ +#define TAMP_ERCFGR_ERCFG0 TAMP_ERCFGR_ERCFG0_Msk + +/******************** Bits definition for TAMP_BKP0R register ***************/ +#define TAMP_BKP0R_Pos (0U) +#define TAMP_BKP0R_Msk (0xFFFFFFFFUL << TAMP_BKP0R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP0R TAMP_BKP0R_Msk + +/******************** Bits definition for TAMP_BKP1R register ****************/ +#define TAMP_BKP1R_Pos (0U) +#define TAMP_BKP1R_Msk (0xFFFFFFFFUL << TAMP_BKP1R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP1R TAMP_BKP1R_Msk + +/******************** Bits definition for TAMP_BKP2R register ****************/ +#define TAMP_BKP2R_Pos (0U) +#define TAMP_BKP2R_Msk (0xFFFFFFFFUL << TAMP_BKP2R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP2R TAMP_BKP2R_Msk + +/******************** Bits definition for TAMP_BKP3R register ****************/ +#define TAMP_BKP3R_Pos (0U) +#define TAMP_BKP3R_Msk (0xFFFFFFFFUL << TAMP_BKP3R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP3R TAMP_BKP3R_Msk + +/******************** Bits definition for TAMP_BKP4R register ****************/ +#define TAMP_BKP4R_Pos (0U) +#define TAMP_BKP4R_Msk (0xFFFFFFFFUL << TAMP_BKP4R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP4R TAMP_BKP4R_Msk + +/******************** Bits definition for TAMP_BKP5R register ****************/ +#define TAMP_BKP5R_Pos (0U) +#define TAMP_BKP5R_Msk (0xFFFFFFFFUL << TAMP_BKP5R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP5R TAMP_BKP5R_Msk + +/******************** Bits definition for TAMP_BKP6R register ****************/ +#define TAMP_BKP6R_Pos (0U) +#define TAMP_BKP6R_Msk (0xFFFFFFFFUL << TAMP_BKP6R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP6R TAMP_BKP6R_Msk + +/******************** Bits definition for TAMP_BKP7R register ****************/ +#define TAMP_BKP7R_Pos (0U) +#define TAMP_BKP7R_Msk (0xFFFFFFFFUL << TAMP_BKP7R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP7R TAMP_BKP7R_Msk + +/******************** Bits definition for TAMP_BKP8R register ****************/ +#define TAMP_BKP8R_Pos (0U) +#define TAMP_BKP8R_Msk (0xFFFFFFFFUL << TAMP_BKP8R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP8R TAMP_BKP8R_Msk + +/******************** Bits definition for TAMP_BKP9R register ****************/ +#define TAMP_BKP9R_Pos (0U) +#define TAMP_BKP9R_Msk (0xFFFFFFFFUL << TAMP_BKP9R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP9R TAMP_BKP9R_Msk + +/******************** Bits definition for TAMP_BKP10R register ***************/ +#define TAMP_BKP10R_Pos (0U) +#define TAMP_BKP10R_Msk (0xFFFFFFFFUL << TAMP_BKP10R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP10R TAMP_BKP10R_Msk + +/******************** Bits definition for TAMP_BKP11R register ***************/ +#define TAMP_BKP11R_Pos (0U) +#define TAMP_BKP11R_Msk (0xFFFFFFFFUL << TAMP_BKP11R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP11R TAMP_BKP11R_Msk + +/******************** Bits definition for TAMP_BKP12R register ***************/ +#define TAMP_BKP12R_Pos (0U) +#define TAMP_BKP12R_Msk (0xFFFFFFFFUL << TAMP_BKP12R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP12R TAMP_BKP12R_Msk + +/******************** Bits definition for TAMP_BKP13R register ***************/ +#define TAMP_BKP13R_Pos (0U) +#define TAMP_BKP13R_Msk (0xFFFFFFFFUL << TAMP_BKP13R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP13R TAMP_BKP13R_Msk + +/******************** Bits definition for TAMP_BKP14R register ***************/ +#define TAMP_BKP14R_Pos (0U) +#define TAMP_BKP14R_Msk (0xFFFFFFFFUL << TAMP_BKP14R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP14R TAMP_BKP14R_Msk + +/******************** Bits definition for TAMP_BKP15R register ***************/ +#define TAMP_BKP15R_Pos (0U) +#define TAMP_BKP15R_Msk (0xFFFFFFFFUL << TAMP_BKP15R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP15R TAMP_BKP15R_Msk + +/******************** Bits definition for TAMP_BKP16R register ***************/ +#define TAMP_BKP16R_Pos (0U) +#define TAMP_BKP16R_Msk (0xFFFFFFFFUL << TAMP_BKP16R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP16R TAMP_BKP16R_Msk + +/******************** Bits definition for TAMP_BKP17R register ***************/ +#define TAMP_BKP17R_Pos (0U) +#define TAMP_BKP17R_Msk (0xFFFFFFFFUL << TAMP_BKP17R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP17R TAMP_BKP17R_Msk + +/******************** Bits definition for TAMP_BKP18R register ***************/ +#define TAMP_BKP18R_Pos (0U) +#define TAMP_BKP18R_Msk (0xFFFFFFFFUL << TAMP_BKP18R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP18R TAMP_BKP18R_Msk + +/******************** Bits definition for TAMP_BKP19R register ***************/ +#define TAMP_BKP19R_Pos (0U) +#define TAMP_BKP19R_Msk (0xFFFFFFFFUL << TAMP_BKP19R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP19R TAMP_BKP19R_Msk + +/******************** Bits definition for TAMP_BKP20R register ***************/ +#define TAMP_BKP20R_Pos (0U) +#define TAMP_BKP20R_Msk (0xFFFFFFFFUL << TAMP_BKP20R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP20R TAMP_BKP20R_Msk + +/******************** Bits definition for TAMP_BKP21R register ***************/ +#define TAMP_BKP21R_Pos (0U) +#define TAMP_BKP21R_Msk (0xFFFFFFFFUL << TAMP_BKP21R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP21R TAMP_BKP21R_Msk + +/******************** Bits definition for TAMP_BKP22R register ***************/ +#define TAMP_BKP22R_Pos (0U) +#define TAMP_BKP22R_Msk (0xFFFFFFFFUL << TAMP_BKP22R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP22R TAMP_BKP22R_Msk + +/******************** Bits definition for TAMP_BKP23R register ***************/ +#define TAMP_BKP23R_Pos (0U) +#define TAMP_BKP23R_Msk (0xFFFFFFFFUL << TAMP_BKP23R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP23R TAMP_BKP23R_Msk + +/******************** Bits definition for TAMP_BKP24R register ***************/ +#define TAMP_BKP24R_Pos (0U) +#define TAMP_BKP24R_Msk (0xFFFFFFFFUL << TAMP_BKP24R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP24R TAMP_BKP24R_Msk + +/******************** Bits definition for TAMP_BKP25R register ***************/ +#define TAMP_BKP25R_Pos (0U) +#define TAMP_BKP25R_Msk (0xFFFFFFFFUL << TAMP_BKP25R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP25R TAMP_BKP25R_Msk + +/******************** Bits definition for TAMP_BKP26R register ***************/ +#define TAMP_BKP26R_Pos (0U) +#define TAMP_BKP26R_Msk (0xFFFFFFFFUL << TAMP_BKP26R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP26R TAMP_BKP26R_Msk + +/******************** Bits definition for TAMP_BKP27R register ***************/ +#define TAMP_BKP27R_Pos (0U) +#define TAMP_BKP27R_Msk (0xFFFFFFFFUL << TAMP_BKP27R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP27R TAMP_BKP27R_Msk + +/******************** Bits definition for TAMP_BKP28R register ***************/ +#define TAMP_BKP28R_Pos (0U) +#define TAMP_BKP28R_Msk (0xFFFFFFFFUL << TAMP_BKP28R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP28R TAMP_BKP28R_Msk + +/******************** Bits definition for TAMP_BKP29R register ***************/ +#define TAMP_BKP29R_Pos (0U) +#define TAMP_BKP29R_Msk (0xFFFFFFFFUL << TAMP_BKP29R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP29R TAMP_BKP29R_Msk + +/******************** Bits definition for TAMP_BKP30R register ***************/ +#define TAMP_BKP30R_Pos (0U) +#define TAMP_BKP30R_Msk (0xFFFFFFFFUL << TAMP_BKP30R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP30R TAMP_BKP30R_Msk + +/******************** Bits definition for TAMP_BKP31R register ***************/ +#define TAMP_BKP31R_Pos (0U) +#define TAMP_BKP31R_Msk (0xFFFFFFFFUL << TAMP_BKP31R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP31R TAMP_BKP31R_Msk + +/******************************************************************************/ +/* */ +/* Serial Audio Interface */ +/* */ +/******************************************************************************/ +/******************** Bit definition for SAI_GCR register *******************/ +#define SAI_GCR_SYNCIN_Pos (0U) +#define SAI_GCR_SYNCIN_Msk (0x3UL << SAI_GCR_SYNCIN_Pos) /*!< 0x00000003 */ +#define SAI_GCR_SYNCIN SAI_GCR_SYNCIN_Msk /*!= 6010050) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wc11-extensions" + #pragma clang diagnostic ignored "-Wreserved-id-macro" +#elif defined (__GNUC__) + /* anonymous unions are enabled by default */ +#elif defined (__TMS470__) + /* anonymous unions are enabled by default */ +#elif defined (__TASKING__) + #pragma warning 586 +#elif defined (__CSMC__) + /* anonymous unions are enabled by default */ +#else + #warning Not supported compiler type +#endif + +#define SMPS /*!< Switched mode power supply feature */ + +/* -------- Configuration of the Cortex-M33 Processor and Core Peripherals ------ */ +#define __CM33_REV 0x0000U /* Core revision r0p1 */ +#define __SAUREGION_PRESENT 1U /* SAU regions present */ +#define __MPU_PRESENT 1U /* MPU present */ +#define __VTOR_PRESENT 1U /* VTOR present */ +#define __NVIC_PRIO_BITS 4U /* Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0U /* Set to 1 if different SysTick Config is used */ +#define __FPU_PRESENT 1U /* FPU present */ +#define __DSP_PRESENT 1U /* DSP extension present */ + +/** @} */ /* End of group Configuration_of_CMSIS */ + + +#include /*!< ARM Cortex-M33 processor and core peripherals */ +#include "system_stm32h5xx.h" /*!< STM32H5xx System */ + + +/* =========================================================================================================================== */ +/* ================ Device Specific Peripheral Section ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup STM32H5xx_peripherals + * @{ + */ + +/** + * @brief CRC calculation unit + */ +typedef struct +{ + __IO uint32_t DR; /*!< CRC Data register, Address offset: 0x00 */ + __IO uint32_t IDR; /*!< CRC Independent data register, Address offset: 0x04 */ + __IO uint32_t CR; /*!< CRC Control register, Address offset: 0x08 */ + uint32_t RESERVED2; /*!< Reserved, 0x0C */ + __IO uint32_t INIT; /*!< Initial CRC value register, Address offset: 0x10 */ + __IO uint32_t POL; /*!< CRC polynomial register, Address offset: 0x14 */ + uint32_t RESERVED3[246]; /*!< Reserved, */ + __IO uint32_t HWCFGR; /*!< CRC IP HWCFGR register, Address offset: 0x3F0 */ + __IO uint32_t VERR; /*!< CRC IP version register, Address offset: 0x3F4 */ + __IO uint32_t PIDR; /*!< CRC IP type identification register, Address offset: 0x3F8 */ + __IO uint32_t SIDR; /*!< CRC IP map Size ID register, Address offset: 0x3FC */ +} CRC_TypeDef; + +/** + * @brief Inter-integrated Circuit Interface + */ +typedef struct +{ + __IO uint32_t CR1; /*!< I2C Control register 1, Address offset: 0x00 */ + __IO uint32_t CR2; /*!< I2C Control register 2, Address offset: 0x04 */ + __IO uint32_t OAR1; /*!< I2C Own address 1 register, Address offset: 0x08 */ + __IO uint32_t OAR2; /*!< I2C Own address 2 register, Address offset: 0x0C */ + __IO uint32_t TIMINGR; /*!< I2C Timing register, Address offset: 0x10 */ + __IO uint32_t TIMEOUTR; /*!< I2C Timeout register, Address offset: 0x14 */ + __IO uint32_t ISR; /*!< I2C Interrupt and status register, Address offset: 0x18 */ + __IO uint32_t ICR; /*!< I2C Interrupt clear register, Address offset: 0x1C */ + __IO uint32_t PECR; /*!< I2C PEC register, Address offset: 0x20 */ + __IO uint32_t RXDR; /*!< I2C Receive data register, Address offset: 0x24 */ + __IO uint32_t TXDR; /*!< I2C Transmit data register, Address offset: 0x28 */ +} I2C_TypeDef; + +/** + * @brief Improved Inter-integrated Circuit Interface + */ +typedef struct +{ + __IO uint32_t CR; /*!< I3C Control register, Address offset: 0x00 */ + __IO uint32_t CFGR; /*!< I3C Controller Configuration register, Address offset: 0x04 */ + uint32_t RESERVED1[2]; /*!< Reserved, Address offset: 0x08-0x0C */ + __IO uint32_t RDR; /*!< I3C Received Data register, Address offset: 0x10 */ + __IO uint32_t RDWR; /*!< I3C Received Data Word register, Address offset: 0x14 */ + __IO uint32_t TDR; /*!< I3C Transmit Data register, Address offset: 0x18 */ + __IO uint32_t TDWR; /*!< I3C Transmit Data Word register, Address offset: 0x1C */ + __IO uint32_t IBIDR; /*!< I3C IBI payload Data register, Address offset: 0x20 */ + __IO uint32_t TGTTDR; /*!< I3C Target Transmit register, Address offset: 0x24 */ + uint32_t RESERVED2[2]; /*!< Reserved, Address offset: 0x28-0x2C */ + __IO uint32_t SR; /*!< I3C Status register, Address offset: 0x30 */ + __IO uint32_t SER; /*!< I3C Status Error register, Address offset: 0x34 */ + uint32_t RESERVED3[2]; /*!< Reserved, Address offset: 0x38-0x3C */ + __IO uint32_t RMR; /*!< I3C Received Message register, Address offset: 0x40 */ + uint32_t RESERVED4[3]; /*!< Reserved, Address offset: 0x44-0x4C */ + __IO uint32_t EVR; /*!< I3C Event register, Address offset: 0x50 */ + __IO uint32_t IER; /*!< I3C Interrupt Enable register, Address offset: 0x54 */ + __IO uint32_t CEVR; /*!< I3C Clear Event register, Address offset: 0x58 */ + uint32_t RESERVED5; /*!< Reserved, Address offset: 0x5C */ + __IO uint32_t DEVR0; /*!< I3C own Target characteristics register, Address offset: 0x60 */ + __IO uint32_t DEVRX[4]; /*!< I3C Target x (1<=x<=4) register, Address offset: 0x64-0x70 */ + uint32_t RESERVED6[7]; /*!< Reserved, Address offset: 0x74-0x8C */ + __IO uint32_t MAXRLR; /*!< I3C Maximum Read Length register, Address offset: 0x90 */ + __IO uint32_t MAXWLR; /*!< I3C Maximum Write Length register, Address offset: 0x94 */ + uint32_t RESERVED7[2]; /*!< Reserved, Address offset: 0x98-0x9C */ + __IO uint32_t TIMINGR0; /*!< I3C Timing 0 register, Address offset: 0xA0 */ + __IO uint32_t TIMINGR1; /*!< I3C Timing 1 register, Address offset: 0xA4 */ + __IO uint32_t TIMINGR2; /*!< I3C Timing 2 register, Address offset: 0xA8 */ + uint32_t RESERVED9[5]; /*!< Reserved, Address offset: 0xAC-0xBC */ + __IO uint32_t BCR; /*!< I3C Bus Characteristics register, Address offset: 0xC0 */ + __IO uint32_t DCR; /*!< I3C Device Characteristics register, Address offset: 0xC4 */ + __IO uint32_t GETCAPR; /*!< I3C GET CAPabilities register, Address offset: 0xC8 */ + __IO uint32_t CRCAPR; /*!< I3C Controller CAPabilities register, Address offset: 0xCC */ + __IO uint32_t GETMXDSR; /*!< I3C GET Max Data Speed register, Address offset: 0xD0 */ + __IO uint32_t EPIDR; /*!< I3C Extended Provisioned ID register, Address offset: 0xD4 */ +} I3C_TypeDef; + +/** + * @brief DAC + */ +typedef struct +{ + __IO uint32_t CR; /*!< DAC control register, Address offset: 0x00 */ + __IO uint32_t SWTRIGR; /*!< DAC software trigger register, Address offset: 0x04 */ + __IO uint32_t DHR12R1; /*!< DAC channel1 12-bit right-aligned data holding register, Address offset: 0x08 */ + __IO uint32_t DHR12L1; /*!< DAC channel1 12-bit left aligned data holding register, Address offset: 0x0C */ + __IO uint32_t DHR8R1; /*!< DAC channel1 8-bit right aligned data holding register, Address offset: 0x10 */ + __IO uint32_t DHR12R2; /*!< DAC channel2 12-bit right aligned data holding register, Address offset: 0x14 */ + __IO uint32_t DHR12L2; /*!< DAC channel2 12-bit left aligned data holding register, Address offset: 0x18 */ + __IO uint32_t DHR8R2; /*!< DAC channel2 8-bit right-aligned data holding register, Address offset: 0x1C */ + __IO uint32_t DHR12RD; /*!< Dual DAC 12-bit right-aligned data holding register, Address offset: 0x20 */ + __IO uint32_t DHR12LD; /*!< DUAL DAC 12-bit left aligned data holding register, Address offset: 0x24 */ + __IO uint32_t DHR8RD; /*!< DUAL DAC 8-bit right aligned data holding register, Address offset: 0x28 */ + __IO uint32_t DOR1; /*!< DAC channel1 data output register, Address offset: 0x2C */ + __IO uint32_t DOR2; /*!< DAC channel2 data output register, Address offset: 0x30 */ + __IO uint32_t SR; /*!< DAC status register, Address offset: 0x34 */ + __IO uint32_t CCR; /*!< DAC calibration control register, Address offset: 0x38 */ + __IO uint32_t MCR; /*!< DAC mode control register, Address offset: 0x3C */ + __IO uint32_t SHSR1; /*!< DAC Sample and Hold sample time register 1, Address offset: 0x40 */ + __IO uint32_t SHSR2; /*!< DAC Sample and Hold sample time register 2, Address offset: 0x44 */ + __IO uint32_t SHHR; /*!< DAC Sample and Hold hold time register, Address offset: 0x48 */ + __IO uint32_t SHRR; /*!< DAC Sample and Hold refresh time register, Address offset: 0x4C */ + __IO uint32_t RESERVED[1]; + __IO uint32_t AUTOCR; /*!< DAC Autonomous mode register, Address offset: 0x54 */ +} DAC_TypeDef; + +/** + * @brief Clock Recovery System + */ +typedef struct +{ +__IO uint32_t CR; /*!< CRS ccontrol register, Address offset: 0x00 */ +__IO uint32_t CFGR; /*!< CRS configuration register, Address offset: 0x04 */ +__IO uint32_t ISR; /*!< CRS interrupt and status register, Address offset: 0x08 */ +__IO uint32_t ICR; /*!< CRS interrupt flag clear register, Address offset: 0x0C */ +} CRS_TypeDef; + +/** + * @brief AES hardware accelerator + */ +typedef struct +{ + __IO uint32_t CR; /*!< AES control register, Address offset: 0x00 */ + __IO uint32_t SR; /*!< AES status register, Address offset: 0x04 */ + __IO uint32_t DINR; /*!< AES data input register, Address offset: 0x08 */ + __IO uint32_t DOUTR; /*!< AES data output register, Address offset: 0x0C */ + __IO uint32_t KEYR0; /*!< AES key register 0, Address offset: 0x10 */ + __IO uint32_t KEYR1; /*!< AES key register 1, Address offset: 0x14 */ + __IO uint32_t KEYR2; /*!< AES key register 2, Address offset: 0x18 */ + __IO uint32_t KEYR3; /*!< AES key register 3, Address offset: 0x1C */ + __IO uint32_t IVR0; /*!< AES initialization vector register 0, Address offset: 0x20 */ + __IO uint32_t IVR1; /*!< AES initialization vector register 1, Address offset: 0x24 */ + __IO uint32_t IVR2; /*!< AES initialization vector register 2, Address offset: 0x28 */ + __IO uint32_t IVR3; /*!< AES initialization vector register 3, Address offset: 0x2C */ + __IO uint32_t KEYR4; /*!< AES key register 4, Address offset: 0x30 */ + __IO uint32_t KEYR5; /*!< AES key register 5, Address offset: 0x34 */ + __IO uint32_t KEYR6; /*!< AES key register 6, Address offset: 0x38 */ + __IO uint32_t KEYR7; /*!< AES key register 7, Address offset: 0x3C */ + __IO uint32_t SUSP0R; /*!< AES Suspend register 0, Address offset: 0x40 */ + __IO uint32_t SUSP1R; /*!< AES Suspend register 1, Address offset: 0x44 */ + __IO uint32_t SUSP2R; /*!< AES Suspend register 2, Address offset: 0x48 */ + __IO uint32_t SUSP3R; /*!< AES Suspend register 3, Address offset: 0x4C */ + __IO uint32_t SUSP4R; /*!< AES Suspend register 4, Address offset: 0x50 */ + __IO uint32_t SUSP5R; /*!< AES Suspend register 5, Address offset: 0x54 */ + __IO uint32_t SUSP6R; /*!< AES Suspend register 6, Address offset: 0x58 */ + __IO uint32_t SUSP7R; /*!< AES Suspend register 7, Address offset: 0x5C */ + uint32_t RESERVED1[168];/*!< Reserved, Address offset: 0x60 -- 0x2FC */ + __IO uint32_t IER; /*!< AES Interrupt Enable Register, Address offset: 0x300 */ + __IO uint32_t ISR; /*!< AES Interrupt Status Register, Address offset: 0x304 */ + __IO uint32_t ICR; /*!< AES Interrupt Clear Register, Address offset: 0x308 */ +} AES_TypeDef; + +/** + * @brief HASH + */ +typedef struct +{ + __IO uint32_t CR; /*!< HASH control register, Address offset: 0x00 */ + __IO uint32_t DIN; /*!< HASH data input register, Address offset: 0x04 */ + __IO uint32_t STR; /*!< HASH start register, Address offset: 0x08 */ + __IO uint32_t HR[5]; /*!< HASH digest registers, Address offset: 0x0C-0x1C */ + __IO uint32_t IMR; /*!< HASH interrupt enable register, Address offset: 0x20 */ + __IO uint32_t SR; /*!< HASH status register, Address offset: 0x24 */ + uint32_t RESERVED[52]; /*!< Reserved, 0x28-0xF4 */ + __IO uint32_t CSR[103]; /*!< HASH context swap registers, Address offset: 0x0F8-0x290 */ +} HASH_TypeDef; + +/** + * @brief HASH_DIGEST + */ +typedef struct +{ + __IO uint32_t HR[16]; /*!< HASH digest registers, Address offset: 0x310-0x34C */ +} HASH_DIGEST_TypeDef; + +/** + * @brief RNG + */ +typedef struct +{ + __IO uint32_t CR; /*!< RNG control register, Address offset: 0x00 */ + __IO uint32_t SR; /*!< RNG status register, Address offset: 0x04 */ + __IO uint32_t DR; /*!< RNG data register, Address offset: 0x08 */ + uint32_t RESERVED; + __IO uint32_t HTCR; /*!< RNG health test configuration register, Address offset: 0x10 */ +} RNG_TypeDef; + +/** + * @brief Debug MCU + */ +typedef struct +{ + __IO uint32_t IDCODE; /*!< MCU device ID code, Address offset: 0x00 */ + __IO uint32_t CR; /*!< Debug MCU configuration register, Address offset: 0x04 */ + __IO uint32_t APB1FZR1; /*!< Debug MCU APB1 freeze register 1, Address offset: 0x08 */ + __IO uint32_t APB1FZR2; /*!< Debug MCU APB1 freeze register 2, Address offset: 0x0C */ + __IO uint32_t APB2FZR; /*!< Debug MCU APB2 freeze register, Address offset: 0x10 */ + __IO uint32_t APB3FZR; /*!< Debug MCU APB3 freeze register, Address offset: 0x14 */ + uint32_t RESERVED1[2]; /*!< Reserved, 0x18 - 0x1C */ + __IO uint32_t AHB1FZR; /*!< Debug MCU AHB1 freeze register, Address offset: 0x20 */ + uint32_t RESERVED2[54]; /*!< Reserved, 0x24 - 0xF8 */ + __IO uint32_t SR; /*!< Debug MCU SR register, Address offset: 0xFC */ + __IO uint32_t DBG_AUTH_HOST; /*!< Debug DBG_AUTH_HOST register, Address offset: 0x100 */ + __IO uint32_t DBG_AUTH_DEV; /*!< Debug DBG_AUTH_DEV register, Address offset: 0x104 */ + __IO uint32_t DBG_AUTH_ACK; /*!< Debug DBG_AUTH_ACK register, Address offset: 0x108 */ + uint32_t RESERVED3[945]; /*!< Reserved, 0x10C - 0xFCC */ + __IO uint32_t PIDR4; /*!< Debug MCU Peripheral ID register 4, Address offset: 0xFD0 */ + __IO uint32_t PIDR5; /*!< Debug MCU Peripheral ID register 5, Address offset: 0xFD4 */ + __IO uint32_t PIDR6; /*!< Debug MCU Peripheral ID register 6, Address offset: 0xFD8 */ + __IO uint32_t PIDR7; /*!< Debug MCU Peripheral ID register 7, Address offset: 0xFDC */ + __IO uint32_t PIDR0; /*!< Debug MCU Peripheral ID register 0, Address offset: 0xFE0 */ + __IO uint32_t PIDR1; /*!< Debug MCU Peripheral ID register 1, Address offset: 0xFE4 */ + __IO uint32_t PIDR2; /*!< Debug MCU Peripheral ID register 2, Address offset: 0xFE8 */ + __IO uint32_t PIDR3; /*!< Debug MCU Peripheral ID register 3, Address offset: 0xFEC */ + __IO uint32_t CIDR0; /*!< Debug MCU Component ID register 0, Address offset: 0xFF0 */ + __IO uint32_t CIDR1; /*!< Debug MCU Component ID register 1, Address offset: 0xFF4 */ + __IO uint32_t CIDR2; /*!< Debug MCU Component ID register 2, Address offset: 0xFF8 */ + __IO uint32_t CIDR3; /*!< Debug MCU Component ID register 3, Address offset: 0xFFC */ +} DBGMCU_TypeDef; + +/** + * @brief DCMI + */ +typedef struct +{ + __IO uint32_t CR; /*!< DCMI control register 1, Address offset: 0x00 */ + __IO uint32_t SR; /*!< DCMI status register, Address offset: 0x04 */ + __IO uint32_t RISR; /*!< DCMI raw interrupt status register, Address offset: 0x08 */ + __IO uint32_t IER; /*!< DCMI interrupt enable register, Address offset: 0x0C */ + __IO uint32_t MISR; /*!< DCMI masked interrupt status register, Address offset: 0x10 */ + __IO uint32_t ICR; /*!< DCMI interrupt clear register, Address offset: 0x14 */ + __IO uint32_t ESCR; /*!< DCMI embedded synchronization code register, Address offset: 0x18 */ + __IO uint32_t ESUR; /*!< DCMI embedded synchronization unmask register, Address offset: 0x1C */ + __IO uint32_t CWSTRTR; /*!< DCMI crop window start, Address offset: 0x20 */ + __IO uint32_t CWSIZER; /*!< DCMI crop window size, Address offset: 0x24 */ + __IO uint32_t DR; /*!< DCMI data register, Address offset: 0x28 */ +} DCMI_TypeDef; + +/** + * @brief PSSI + */ +typedef struct +{ + __IO uint32_t CR; /*!< PSSI control register, Address offset: 0x000 */ + __IO uint32_t SR; /*!< PSSI status register, Address offset: 0x004 */ + __IO uint32_t RIS; /*!< PSSI raw interrupt status register, Address offset: 0x008 */ + __IO uint32_t IER; /*!< PSSI interrupt enable register, Address offset: 0x00C */ + __IO uint32_t MIS; /*!< PSSI masked interrupt status register, Address offset: 0x010 */ + __IO uint32_t ICR; /*!< PSSI interrupt clear register, Address offset: 0x014 */ + __IO uint32_t RESERVED1[4]; /*!< Reserved, 0x018 - 0x024 */ + __IO uint32_t DR; /*!< PSSI data register, Address offset: 0x028 */ +} PSSI_TypeDef; + +/** + * @brief DMA Controller + */ +typedef struct +{ + __IO uint32_t SECCFGR; /*!< DMA secure configuration register, Address offset: 0x00 */ + __IO uint32_t PRIVCFGR; /*!< DMA privileged configuration register, Address offset: 0x04 */ + __IO uint32_t RCFGLOCKR; /*!< DMA lock configuration register, Address offset: 0x08 */ + __IO uint32_t MISR; /*!< DMA non secure masked interrupt status register, Address offset: 0x0C */ + __IO uint32_t SMISR; /*!< DMA secure masked interrupt status register, Address offset: 0x10 */ +} DMA_TypeDef; + +typedef struct +{ + __IO uint32_t CLBAR; /*!< DMA channel x linked-list base address register, Address offset: 0x50 + (x * 0x80) */ + uint32_t RESERVED1[2]; /*!< Reserved 1, Address offset: 0x54 -- 0x58 */ + __IO uint32_t CFCR; /*!< DMA channel x flag clear register, Address offset: 0x5C + (x * 0x80) */ + __IO uint32_t CSR; /*!< DMA channel x flag status register, Address offset: 0x60 + (x * 0x80) */ + __IO uint32_t CCR; /*!< DMA channel x control register, Address offset: 0x64 + (x * 0x80) */ + uint32_t RESERVED2[10];/*!< Reserved 2, Address offset: 0x68 -- 0x8C */ + __IO uint32_t CTR1; /*!< DMA channel x transfer register 1, Address offset: 0x90 + (x * 0x80) */ + __IO uint32_t CTR2; /*!< DMA channel x transfer register 2, Address offset: 0x94 + (x * 0x80) */ + __IO uint32_t CBR1; /*!< DMA channel x block register 1, Address offset: 0x98 + (x * 0x80) */ + __IO uint32_t CSAR; /*!< DMA channel x source address register, Address offset: 0x9C + (x * 0x80) */ + __IO uint32_t CDAR; /*!< DMA channel x destination address register, Address offset: 0xA0 + (x * 0x80) */ + __IO uint32_t CTR3; /*!< DMA channel x transfer register 3, Address offset: 0xA4 + (x * 0x80) */ + __IO uint32_t CBR2; /*!< DMA channel x block register 2, Address offset: 0xA8 + (x * 0x80) */ + uint32_t RESERVED3[8]; /*!< Reserved 3, Address offset: 0xAC -- 0xC8 */ + __IO uint32_t CLLR; /*!< DMA channel x linked-list address register, Address offset: 0xCC + (x * 0x80) */ +} DMA_Channel_TypeDef; + +/** + * @brief Ethernet MAC + */ +typedef struct +{ + __IO uint32_t MACCR; + __IO uint32_t MACECR; + __IO uint32_t MACPFR; + __IO uint32_t MACWTR; + __IO uint32_t MACHT0R; + __IO uint32_t MACHT1R; + uint32_t RESERVED1[14]; + __IO uint32_t MACVTR; + uint32_t RESERVED2; + __IO uint32_t MACVHTR; + uint32_t RESERVED3; + __IO uint32_t MACVIR; + __IO uint32_t MACIVIR; + uint32_t RESERVED4[2]; + __IO uint32_t MACTFCR; + uint32_t RESERVED5[7]; + __IO uint32_t MACRFCR; + uint32_t RESERVED6[7]; + __IO uint32_t MACISR; + __IO uint32_t MACIER; + __IO uint32_t MACRXTXSR; + uint32_t RESERVED7; + __IO uint32_t MACPCSR; + __IO uint32_t MACRWKPFR; + uint32_t RESERVED8[2]; + __IO uint32_t MACLCSR; + __IO uint32_t MACLTCR; + __IO uint32_t MACLETR; + __IO uint32_t MAC1USTCR; + uint32_t RESERVED9[12]; + __IO uint32_t MACVR; + __IO uint32_t MACDR; + uint32_t RESERVED10; + __IO uint32_t MACHWF0R; + __IO uint32_t MACHWF1R; + __IO uint32_t MACHWF2R; + uint32_t RESERVED11[54]; + __IO uint32_t MACMDIOAR; + __IO uint32_t MACMDIODR; + uint32_t RESERVED12[2]; + __IO uint32_t MACARPAR; + uint32_t RESERVED13[59]; + __IO uint32_t MACA0HR; + __IO uint32_t MACA0LR; + __IO uint32_t MACA1HR; + __IO uint32_t MACA1LR; + __IO uint32_t MACA2HR; + __IO uint32_t MACA2LR; + __IO uint32_t MACA3HR; + __IO uint32_t MACA3LR; + uint32_t RESERVED14[248]; + __IO uint32_t MMCCR; + __IO uint32_t MMCRIR; + __IO uint32_t MMCTIR; + __IO uint32_t MMCRIMR; + __IO uint32_t MMCTIMR; + uint32_t RESERVED15[14]; + __IO uint32_t MMCTSCGPR; + __IO uint32_t MMCTMCGPR; + uint32_t RESERVED16[5]; + __IO uint32_t MMCTPCGR; + uint32_t RESERVED17[10]; + __IO uint32_t MMCRCRCEPR; + __IO uint32_t MMCRAEPR; + uint32_t RESERVED18[10]; + __IO uint32_t MMCRUPGR; + uint32_t RESERVED19[9]; + __IO uint32_t MMCTLPIMSTR; + __IO uint32_t MMCTLPITCR; + __IO uint32_t MMCRLPIMSTR; + __IO uint32_t MMCRLPITCR; + uint32_t RESERVED20[65]; + __IO uint32_t MACL3L4C0R; + __IO uint32_t MACL4A0R; + uint32_t RESERVED21[2]; + __IO uint32_t MACL3A0R0R; + __IO uint32_t MACL3A1R0R; + __IO uint32_t MACL3A2R0R; + __IO uint32_t MACL3A3R0R; + uint32_t RESERVED22[4]; + __IO uint32_t MACL3L4C1R; + __IO uint32_t MACL4A1R; + uint32_t RESERVED23[2]; + __IO uint32_t MACL3A0R1R; + __IO uint32_t MACL3A1R1R; + __IO uint32_t MACL3A2R1R; + __IO uint32_t MACL3A3R1R; + uint32_t RESERVED24[108]; + __IO uint32_t MACTSCR; + __IO uint32_t MACSSIR; + __IO uint32_t MACSTSR; + __IO uint32_t MACSTNR; + __IO uint32_t MACSTSUR; + __IO uint32_t MACSTNUR; + __IO uint32_t MACTSAR; + uint32_t RESERVED25; + __IO uint32_t MACTSSR; + uint32_t RESERVED26[3]; + __IO uint32_t MACTTSSNR; + __IO uint32_t MACTTSSSR; + uint32_t RESERVED27[2]; + __IO uint32_t MACACR; + uint32_t RESERVED28; + __IO uint32_t MACATSNR; + __IO uint32_t MACATSSR; + __IO uint32_t MACTSIACR; + __IO uint32_t MACTSEACR; + __IO uint32_t MACTSICNR; + __IO uint32_t MACTSECNR; + uint32_t RESERVED29[4]; + __IO uint32_t MACPPSCR; + uint32_t RESERVED30[3]; + __IO uint32_t MACPPSTTSR; + __IO uint32_t MACPPSTTNR; + __IO uint32_t MACPPSIR; + __IO uint32_t MACPPSWR; + uint32_t RESERVED31[12]; + __IO uint32_t MACPOCR; + __IO uint32_t MACSPI0R; + __IO uint32_t MACSPI1R; + __IO uint32_t MACSPI2R; + __IO uint32_t MACLMIR; + uint32_t RESERVED32[11]; + __IO uint32_t MTLOMR; + uint32_t RESERVED33[7]; + __IO uint32_t MTLISR; + uint32_t RESERVED34[55]; + __IO uint32_t MTLTQOMR; + __IO uint32_t MTLTQUR; + __IO uint32_t MTLTQDR; + uint32_t RESERVED35[8]; + __IO uint32_t MTLQICSR; + __IO uint32_t MTLRQOMR; + __IO uint32_t MTLRQMPOCR; + __IO uint32_t MTLRQDR; + uint32_t RESERVED36[177]; + __IO uint32_t DMAMR; + __IO uint32_t DMASBMR; + __IO uint32_t DMAISR; + __IO uint32_t DMADSR; + uint32_t RESERVED37[60]; + __IO uint32_t DMACCR; + __IO uint32_t DMACTCR; + __IO uint32_t DMACRCR; + uint32_t RESERVED38[2]; + __IO uint32_t DMACTDLAR; + uint32_t RESERVED39; + __IO uint32_t DMACRDLAR; + __IO uint32_t DMACTDTPR; + uint32_t RESERVED40; + __IO uint32_t DMACRDTPR; + __IO uint32_t DMACTDRLR; + __IO uint32_t DMACRDRLR; + __IO uint32_t DMACIER; + __IO uint32_t DMACRIWTR; + __IO uint32_t DMACSFCSR; + uint32_t RESERVED41; + __IO uint32_t DMACCATDR; + uint32_t RESERVED42; + __IO uint32_t DMACCARDR; + uint32_t RESERVED43; + __IO uint32_t DMACCATBR; + uint32_t RESERVED44; + __IO uint32_t DMACCARBR; + __IO uint32_t DMACSR; + uint32_t RESERVED45[2]; + __IO uint32_t DMACMFCR; +}ETH_TypeDef; + +/** + * @brief Asynch Interrupt/Event Controller (EXTI) + */ +typedef struct +{ + __IO uint32_t RTSR1; /*!< EXTI Rising Trigger Selection Register 1, Address offset: 0x00 */ + __IO uint32_t FTSR1; /*!< EXTI Falling Trigger Selection Register 1, Address offset: 0x04 */ + __IO uint32_t SWIER1; /*!< EXTI Software Interrupt event Register 1, Address offset: 0x08 */ + __IO uint32_t RPR1; /*!< EXTI Rising Pending Register 1, Address offset: 0x0C */ + __IO uint32_t FPR1; /*!< EXTI Falling Pending Register 1, Address offset: 0x10 */ + __IO uint32_t SECCFGR1; /*!< EXTI Security Configuration Register 1, Address offset: 0x14 */ + __IO uint32_t PRIVCFGR1; /*!< EXTI Privilege Configuration Register 1, Address offset: 0x18 */ + uint32_t RESERVED1; /*!< Reserved 1, Address offset: 0x1C */ + __IO uint32_t RTSR2; /*!< EXTI Rising Trigger Selection Register 2, Address offset: 0x20 */ + __IO uint32_t FTSR2; /*!< EXTI Falling Trigger Selection Register 2, Address offset: 0x24 */ + __IO uint32_t SWIER2; /*!< EXTI Software Interrupt event Register 2, Address offset: 0x28 */ + __IO uint32_t RPR2; /*!< EXTI Rising Pending Register 2, Address offset: 0x2C */ + __IO uint32_t FPR2; /*!< EXTI Falling Pending Register 2, Address offset: 0x30 */ + __IO uint32_t SECCFGR2; /*!< EXTI Security Configuration Register 2, Address offset: 0x34 */ + __IO uint32_t PRIVCFGR2; /*!< EXTI Privilege Configuration Register 2, Address offset: 0x38 */ + uint32_t RESERVED2[9]; /*!< Reserved 2, 0x3C-- 0x5C */ + __IO uint32_t EXTICR[4]; /*!< EXIT External Interrupt Configuration Register, 0x60 -- 0x6C */ + __IO uint32_t LOCKR; /*!< EXTI Lock Register, Address offset: 0x70 */ + uint32_t RESERVED3[3]; /*!< Reserved 3, 0x74 -- 0x7C */ + __IO uint32_t IMR1; /*!< EXTI Interrupt Mask Register 1, Address offset: 0x80 */ + __IO uint32_t EMR1; /*!< EXTI Event Mask Register 1, Address offset: 0x84 */ + uint32_t RESERVED4[2]; /*!< Reserved 4, 0x88 -- 0x8C */ + __IO uint32_t IMR2; /*!< EXTI Interrupt Mask Register 2, Address offset: 0x90 */ + __IO uint32_t EMR2; /*!< EXTI Event Mask Register 2, Address offset: 0x94 */ +} EXTI_TypeDef; + +/** + * @brief FLASH Registers + */ +typedef struct +{ + __IO uint32_t ACR; /*!< FLASH access control register, Address offset: 0x00 */ + __IO uint32_t NSKEYR; /*!< FLASH non-secure key register, Address offset: 0x04 */ + __IO uint32_t SECKEYR; /*!< FLASH secure key register, Address offset: 0x08 */ + __IO uint32_t OPTKEYR; /*!< FLASH option key register, Address offset: 0x0C */ + __IO uint32_t NSOBKKEYR; /*!< FLASH non-secure option bytes keys key register, Address offset: 0x10 */ + __IO uint32_t SECOBKKEYR; /*!< FLASH secure option bytes keys key register, Address offset: 0x14 */ + __IO uint32_t OPSR; /*!< FLASH OPSR register, Address offset: 0x18 */ + __IO uint32_t OPTCR; /*!< Flash Option Control Register, Address offset: 0x1C */ + __IO uint32_t NSSR; /*!< FLASH non-secure status register, Address offset: 0x20 */ + __IO uint32_t SECSR; /*!< FLASH secure status register, Address offset: 0x24 */ + __IO uint32_t NSCR; /*!< FLASH non-secure control register, Address offset: 0x28 */ + __IO uint32_t SECCR; /*!< FLASH secure control register, Address offset: 0x2C */ + __IO uint32_t NSCCR; /*!< FLASH non-secure clear control register, Address offset: 0x30 */ + __IO uint32_t SECCCR; /*!< FLASH secure clear control register, Address offset: 0x34 */ + uint32_t RESERVED1; /*!< Reserved1, Address offset: 0x38 */ + __IO uint32_t PRIVCFGR; /*!< FLASH privilege configuration register, Address offset: 0x3C */ + __IO uint32_t NSOBKCFGR; /*!< FLASH non-secure option byte key configuration register, Address offset: 0x40 */ + __IO uint32_t SECOBKCFGR; /*!< FLASH secure option byte key configuration register, Address offset: 0x44 */ + __IO uint32_t HDPEXTR; /*!< FLASH HDP extension register, Address offset: 0x48 */ + uint32_t RESERVED2; /*!< Reserved2, Address offset: 0x4C */ + __IO uint32_t OPTSR_CUR; /*!< FLASH option status current register, Address offset: 0x50 */ + __IO uint32_t OPTSR_PRG; /*!< FLASH option status to program register, Address offset: 0x54 */ + uint32_t RESERVED3[2]; /*!< Reserved3, Address offset: 0x58-0x5C */ + __IO uint32_t NSEPOCHR_CUR; /*!< FLASH non-secure epoch current register, Address offset: 0x60 */ + __IO uint32_t NSEPOCHR_PRG; /*!< FLASH non-secure epoch to program register, Address offset: 0x64 */ + __IO uint32_t SECEPOCHR_CUR; /*!< FLASH secure epoch current register, Address offset: 0x68 */ + __IO uint32_t SECEPOCHR_PRG; /*!< FLASH secure epoch to program register, Address offset: 0x6C */ + __IO uint32_t OPTSR2_CUR; /*!< FLASH option status current register 2, Address offset: 0x70 */ + __IO uint32_t OPTSR2_PRG; /*!< FLASH option status to program register 2, Address offset: 0x74 */ + uint32_t RESERVED4[2]; /*!< Reserved4, Address offset: 0x78-0x7C */ + __IO uint32_t NSBOOTR_CUR; /*!< FLASH non-secure unique boot entry current register, Address offset: 0x80 */ + __IO uint32_t NSBOOTR_PRG; /*!< FLASH non-secure unique boot entry to program register, Address offset: 0x84 */ + __IO uint32_t SECBOOTR_CUR; /*!< FLASH secure unique boot entry current register, Address offset: 0x88 */ + __IO uint32_t SECBOOTR_PRG; /*!< FLASH secure unique boot entry to program register, Address offset: 0x8C */ + __IO uint32_t OTPBLR_CUR; /*!< FLASH OTP block lock current register, Address offset: 0x90 */ + __IO uint32_t OTPBLR_PRG; /*!< FLASH OTP block Lock to program register, Address offset: 0x94 */ + uint32_t RESERVED5[2]; /*!< Reserved5, Address offset: 0x98-0x9C */ + __IO uint32_t SECBB1R1; /*!< FLASH secure block-based bank 1 register 1, Address offset: 0xA0 */ + __IO uint32_t SECBB1R2; /*!< FLASH secure block-based bank 1 register 2, Address offset: 0xA4 */ + __IO uint32_t SECBB1R3; /*!< FLASH secure block-based bank 1 register 3, Address offset: 0xA8 */ + __IO uint32_t SECBB1R4; /*!< FLASH secure block-based bank 1 register 4, Address offset: 0xAC */ + uint32_t RESERVED6[4]; /*!< Reserved6, Address offset: 0xB0-0xBC */ + __IO uint32_t PRIVBB1R1; /*!< FLASH privilege block-based bank 1 register 1, Address offset: 0xC0 */ + __IO uint32_t PRIVBB1R2; /*!< FLASH privilege block-based bank 1 register 2, Address offset: 0xC4 */ + __IO uint32_t PRIVBB1R3; /*!< FLASH privilege block-based bank 1 register 3, Address offset: 0xC8 */ + __IO uint32_t PRIVBB1R4; /*!< FLASH privilege block-based bank 1 register 4, Address offset: 0xCC */ + uint32_t RESERVED7[4]; /*!< Reserved7, Address offset: 0xD0-0xDC */ + __IO uint32_t SECWM1R_CUR; /*!< FLASH secure watermark 1 current register, Address offset: 0xE0 */ + __IO uint32_t SECWM1R_PRG; /*!< FLASH secure watermark 1 to program register, Address offset: 0xE4 */ + __IO uint32_t WRP1R_CUR; /*!< FLASH write sector group protection current register for bank1, Address offset: 0xE8 */ + __IO uint32_t WRP1R_PRG; /*!< FLASH write sector group protection to program register for bank1, Address offset: 0xEC */ + __IO uint32_t EDATA1R_CUR; /*!< FLASH data sectors configuration current register for bank1, Address offset: 0xF0 */ + __IO uint32_t EDATA1R_PRG; /*!< FLASH data sectors configuration to program register for bank1, Address offset: 0xF4 */ + __IO uint32_t HDP1R_CUR; /*!< FLASH HDP configuration current register for bank1, Address offset: 0xF8 */ + __IO uint32_t HDP1R_PRG; /*!< FLASH HDP configuration to program register for bank1, Address offset: 0xFC */ + __IO uint32_t ECCCORR; /*!< FLASH ECC correction register, Address offset: 0x100 */ + __IO uint32_t ECCDETR; /*!< FLASH ECC detection register, Address offset: 0x104 */ + __IO uint32_t ECCDR; /*!< FLASH ECC data register, Address offset: 0x108 */ + uint32_t RESERVED8[37]; /*!< Reserved8, Address offset: 0x10C-0x19C */ + __IO uint32_t SECBB2R1; /*!< FLASH secure block-based bank 2 register 1, Address offset: 0x1A0 */ + __IO uint32_t SECBB2R2; /*!< FLASH secure block-based bank 2 register 2, Address offset: 0x1A4 */ + __IO uint32_t SECBB2R3; /*!< FLASH secure block-based bank 2 register 3, Address offset: 0x1A8 */ + __IO uint32_t SECBB2R4; /*!< FLASH secure block-based bank 2 register 4, Address offset: 0x1AC */ + uint32_t RESERVED9[4]; /*!< Reserved9, Address offset: 0x1B0-0x1BC */ + __IO uint32_t PRIVBB2R1; /*!< FLASH privilege block-based bank 2 register 1, Address offset: 0x1C0 */ + __IO uint32_t PRIVBB2R2; /*!< FLASH privilege block-based bank 2 register 2, Address offset: 0x1C4 */ + __IO uint32_t PRIVBB2R3; /*!< FLASH privilege block-based bank 2 register 3, Address offset: 0x1C8 */ + __IO uint32_t PRIVBB2R4; /*!< FLASH privilege block-based bank 2 register 4, Address offset: 0x1CC */ + uint32_t RESERVED10[4]; /*!< Reserved10, Address offset: 0x1D0-0x1DC */ + __IO uint32_t SECWM2R_CUR; /*!< FLASH secure watermark 2 current register, Address offset: 0x1E0 */ + __IO uint32_t SECWM2R_PRG; /*!< FLASH secure watermark 2 to program register, Address offset: 0x1E4 */ + __IO uint32_t WRP2R_CUR; /*!< FLASH write sector group protection current register for bank2, Address offset: 0x1E8 */ + __IO uint32_t WRP2R_PRG; /*!< FLASH write sector group protection to program register for bank2, Address offset: 0x1EC */ + __IO uint32_t EDATA2R_CUR; /*!< FLASH data sectors configuration current register for bank2, Address offset: 0x1F0 */ + __IO uint32_t EDATA2R_PRG; /*!< FLASH data sectors configuration to program register for bank2, Address offset: 0x1F4 */ + __IO uint32_t HDP2R_CUR; /*!< FLASH HDP configuration current register for bank2, Address offset: 0x1F8 */ + __IO uint32_t HDP2R_PRG; /*!< FLASH HDP configuration to program register for bank2, Address offset: 0x1FC */ +} FLASH_TypeDef; + +/** + * @brief FMAC + */ +typedef struct +{ + __IO uint32_t X1BUFCFG; /*!< FMAC X1 Buffer Configuration register, Address offset: 0x00 */ + __IO uint32_t X2BUFCFG; /*!< FMAC X2 Buffer Configuration register, Address offset: 0x04 */ + __IO uint32_t YBUFCFG; /*!< FMAC Y Buffer Configuration register, Address offset: 0x08 */ + __IO uint32_t PARAM; /*!< FMAC Parameter register, Address offset: 0x0C */ + __IO uint32_t CR; /*!< FMAC Control register, Address offset: 0x10 */ + __IO uint32_t SR; /*!< FMAC Status register, Address offset: 0x14 */ + __IO uint32_t WDATA; /*!< FMAC Write Data register, Address offset: 0x18 */ + __IO uint32_t RDATA; /*!< FMAC Read Data register, Address offset: 0x1C */ +} FMAC_TypeDef; +/** + * @brief General Purpose I/O + */ +typedef struct +{ + __IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */ + __IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */ + __IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */ + __IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ + __IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */ + __IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */ + __IO uint32_t BSRR; /*!< GPIO port bit set/reset register, Address offset: 0x18 */ + __IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */ + __IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */ + __IO uint32_t BRR; /*!< GPIO Bit Reset register, Address offset: 0x28 */ + __IO uint32_t HSLVR; /*!< GPIO high-speed low voltage register, Address offset: 0x2C */ + __IO uint32_t SECCFGR; /*!< GPIO secure configuration register, Address offset: 0x30 */ +} GPIO_TypeDef; + +/** + * @brief Global TrustZone Controller + */ +typedef struct +{ + __IO uint32_t CR; /*!< TZSC control register, Address offset: 0x00 */ + uint32_t RESERVED1[3]; /*!< Reserved1, Address offset: 0x04-0x0C */ + __IO uint32_t SECCFGR1; /*!< TZSC secure configuration register 1, Address offset: 0x10 */ + __IO uint32_t SECCFGR2; /*!< TZSC secure configuration register 2, Address offset: 0x14 */ + __IO uint32_t SECCFGR3; /*!< TZSC secure configuration register 3, Address offset: 0x18 */ + uint32_t RESERVED2; /*!< Reserved2, Address offset: 0x1C */ + __IO uint32_t PRIVCFGR1; /*!< TZSC privilege configuration register 1, Address offset: 0x20 */ + __IO uint32_t PRIVCFGR2; /*!< TZSC privilege configuration register 2, Address offset: 0x24 */ + __IO uint32_t PRIVCFGR3; /*!< TZSC privilege configuration register 3, Address offset: 0x28 */ + uint32_t RESERVED3[5]; /*!< Reserved3, Address offset: 0x2C-0x3C */ + __IO uint32_t MPCWM1ACFGR; /*!< TZSC memory 1 sub-region A watermark configuration register, Address offset: 0x40 */ + __IO uint32_t MPCWM1AR; /*!< TZSC memory 1 sub-region A watermark register, Address offset: 0x44 */ + __IO uint32_t MPCWM1BCFGR; /*!< TZSC memory 1 sub-region B watermark configuration register, Address offset: 0x48 */ + __IO uint32_t MPCWM1BR; /*!< TZSC memory 1 sub-region B watermark register, Address offset: 0x4C */ + __IO uint32_t MPCWM2ACFGR; /*!< TZSC memory 2 sub-region A watermark configuration register, Address offset: 0x50 */ + __IO uint32_t MPCWM2AR; /*!< TZSC memory 2 sub-region A watermark register, Address offset: 0x54 */ + __IO uint32_t MPCWM2BCFGR; /*!< TZSC memory 2 sub-region B watermark configuration register, Address offset: 0x58 */ + __IO uint32_t MPCWM2BR; /*!< TZSC memory 2 sub-region B watermark register, Address offset: 0x5C */ + __IO uint32_t MPCWM3ACFGR; /*!< TZSC memory 3 sub-region A watermark configuration register, Address offset: 0x60 */ + __IO uint32_t MPCWM3AR; /*!< TZSC memory 3 sub-region A watermark register, Address offset: 0x64 */ + __IO uint32_t MPCWM3BCFGR; /*!< TZSC memory 3 sub-region B watermark configuration register, Address offset: 0x68 */ + __IO uint32_t MPCWM3BR; /*!< TZSC memory 3 sub-region B watermark register, Address offset: 0x6C */ + __IO uint32_t MPCWM4ACFGR; /*!< TZSC memory 4 sub-region A watermark configuration register, Address offset: 0x70 */ + __IO uint32_t MPCWM4AR; /*!< TZSC memory 4 sub-region A watermark register, Address offset: 0x74 */ + __IO uint32_t MPCWM4BCFGR; /*!< TZSC memory 4 sub-region B watermark configuration register, Address offset: 0x78 */ + __IO uint32_t MPCWM4BR; /*!< TZSC memory 4 sub-region B watermark register, Address offset: 0x7c */ +} GTZC_TZSC_TypeDef; + +typedef struct +{ + __IO uint32_t CR; /*!< MPCBBx control register, Address offset: 0x00 */ + uint32_t RESERVED1[3]; /*!< Reserved1, Address offset: 0x04-0x0C */ + __IO uint32_t CFGLOCKR1; /*!< MPCBBx lock register, Address offset: 0x10 */ + uint32_t RESERVED2[59]; /*!< Reserved2, Address offset: 0x14-0xFC */ + __IO uint32_t SECCFGR[32]; /*!< MPCBBx security configuration registers, Address offset: 0x100-0x17C */ + uint32_t RESERVED3[32]; /*!< Reserved3, Address offset: 0x180-0x1FC */ + __IO uint32_t PRIVCFGR[32]; /*!< MPCBBx privilege configuration registers, Address offset: 0x200-0x280 */ +} GTZC_MPCBB_TypeDef; + +typedef struct +{ + __IO uint32_t IER1; /*!< TZIC interrupt enable register 1, Address offset: 0x00 */ + __IO uint32_t IER2; /*!< TZIC interrupt enable register 2, Address offset: 0x04 */ + __IO uint32_t IER3; /*!< TZIC interrupt enable register 3, Address offset: 0x08 */ + __IO uint32_t IER4; /*!< TZIC interrupt enable register 4, Address offset: 0x0C */ + __IO uint32_t SR1; /*!< TZIC status register 1, Address offset: 0x10 */ + __IO uint32_t SR2; /*!< TZIC status register 2, Address offset: 0x14 */ + __IO uint32_t SR3; /*!< TZIC status register 3, Address offset: 0x18 */ + __IO uint32_t SR4; /*!< TZIC status register 4, Address offset: 0x1C */ + __IO uint32_t FCR1; /*!< TZIC flag clear register 1, Address offset: 0x20 */ + __IO uint32_t FCR2; /*!< TZIC flag clear register 2, Address offset: 0x24 */ + __IO uint32_t FCR3; /*!< TZIC flag clear register 3, Address offset: 0x28 */ + __IO uint32_t FCR4; /*!< TZIC flag clear register 3, Address offset: 0x2C */ +} GTZC_TZIC_TypeDef; + +/** + * @brief Instruction Cache + */ +typedef struct +{ + __IO uint32_t CR; /*!< ICACHE control register, Address offset: 0x00 */ + __IO uint32_t SR; /*!< ICACHE status register, Address offset: 0x04 */ + __IO uint32_t IER; /*!< ICACHE interrupt enable register, Address offset: 0x08 */ + __IO uint32_t FCR; /*!< ICACHE Flag clear register, Address offset: 0x0C */ + __IO uint32_t HMONR; /*!< ICACHE hit monitor register, Address offset: 0x10 */ + __IO uint32_t MMONR; /*!< ICACHE miss monitor register, Address offset: 0x14 */ + uint32_t RESERVED1[2]; /*!< Reserved, Address offset: 0x018-0x01C */ + __IO uint32_t CRR0; /*!< ICACHE region 0 configuration register, Address offset: 0x20 */ + __IO uint32_t CRR1; /*!< ICACHE region 1 configuration register, Address offset: 0x24 */ + __IO uint32_t CRR2; /*!< ICACHE region 2 configuration register, Address offset: 0x28 */ + __IO uint32_t CRR3; /*!< ICACHE region 3 configuration register, Address offset: 0x2C */ +} ICACHE_TypeDef; + +/** + * @brief Data Cache + */ +typedef struct +{ + __IO uint32_t CR; /*!< DCACHE control register, Address offset: 0x00 */ + __IO uint32_t SR; /*!< DCACHE status register, Address offset: 0x04 */ + __IO uint32_t IER; /*!< DCACHE interrupt enable register, Address offset: 0x08 */ + __IO uint32_t FCR; /*!< DCACHE Flag clear register, Address offset: 0x0C */ + __IO uint32_t RHMONR; /*!< DCACHE Read hit monitor register, Address offset: 0x10 */ + __IO uint32_t RMMONR; /*!< DCACHE Read miss monitor register, Address offset: 0x14 */ + uint32_t RESERVED1[2]; /*!< Reserved, Address offset: 0x18-0x1C */ + __IO uint32_t WHMONR; /*!< DCACHE Write hit monitor register, Address offset: 0x20 */ + __IO uint32_t WMMONR; /*!< DCACHE Write miss monitor register, Address offset: 0x24 */ + __IO uint32_t CMDRSADDRR; /*!< DCACHE Command Start Address register, Address offset: 0x28 */ + __IO uint32_t CMDREADDRR; /*!< DCACHE Command End Address register, Address offset: 0x2C */ +} DCACHE_TypeDef; + +/** + * @brief TIM + */ +typedef struct +{ + __IO uint32_t CR1; /*!< TIM control register 1, Address offset: 0x00 */ + __IO uint32_t CR2; /*!< TIM control register 2, Address offset: 0x04 */ + __IO uint32_t SMCR; /*!< TIM slave mode control register, Address offset: 0x08 */ + __IO uint32_t DIER; /*!< TIM DMA/interrupt enable register, Address offset: 0x0C */ + __IO uint32_t SR; /*!< TIM status register, Address offset: 0x10 */ + __IO uint32_t EGR; /*!< TIM event generation register, Address offset: 0x14 */ + __IO uint32_t CCMR1; /*!< TIM capture/compare mode register 1, Address offset: 0x18 */ + __IO uint32_t CCMR2; /*!< TIM capture/compare mode register 2, Address offset: 0x1C */ + __IO uint32_t CCER; /*!< TIM capture/compare enable register, Address offset: 0x20 */ + __IO uint32_t CNT; /*!< TIM counter register, Address offset: 0x24 */ + __IO uint32_t PSC; /*!< TIM prescaler, Address offset: 0x28 */ + __IO uint32_t ARR; /*!< TIM auto-reload register, Address offset: 0x2C */ + __IO uint32_t RCR; /*!< TIM repetition counter register, Address offset: 0x30 */ + __IO uint32_t CCR1; /*!< TIM capture/compare register 1, Address offset: 0x34 */ + __IO uint32_t CCR2; /*!< TIM capture/compare register 2, Address offset: 0x38 */ + __IO uint32_t CCR3; /*!< TIM capture/compare register 3, Address offset: 0x3C */ + __IO uint32_t CCR4; /*!< TIM capture/compare register 4, Address offset: 0x40 */ + __IO uint32_t BDTR; /*!< TIM break and dead-time register, Address offset: 0x44 */ + __IO uint32_t CCR5; /*!< TIM capture/compare register 5, Address offset: 0x48 */ + __IO uint32_t CCR6; /*!< TIM capture/compare register 6, Address offset: 0x4C */ + __IO uint32_t CCMR3; /*!< TIM capture/compare mode register 3, Address offset: 0x50 */ + __IO uint32_t DTR2; /*!< TIM deadtime register 2, Address offset: 0x54 */ + __IO uint32_t ECR; /*!< TIM encoder control register, Address offset: 0x58 */ + __IO uint32_t TISEL; /*!< TIM Input Selection register, Address offset: 0x5C */ + __IO uint32_t AF1; /*!< TIM alternate function option register 1, Address offset: 0x60 */ + __IO uint32_t AF2; /*!< TIM alternate function option register 2, Address offset: 0x64 */ + uint32_t RESERVED0[221];/*!< Reserved, Address offset: 0x68 */ + __IO uint32_t DCR; /*!< TIM DMA control register, Address offset: 0x3DC */ + __IO uint32_t DMAR; /*!< TIM DMA address for full transfer, Address offset: 0x3E0 */ +} TIM_TypeDef; + +/** + * @brief LPTIMER + */ +typedef struct +{ + __IO uint32_t ISR; /*!< LPTIM Interrupt and Status register, Address offset: 0x00 */ + __IO uint32_t ICR; /*!< LPTIM Interrupt Clear register, Address offset: 0x04 */ + __IO uint32_t DIER; /*!< LPTIM Interrupt Enable register, Address offset: 0x08 */ + __IO uint32_t CFGR; /*!< LPTIM Configuration register, Address offset: 0x0C */ + __IO uint32_t CR; /*!< LPTIM Control register, Address offset: 0x10 */ + __IO uint32_t CCR1; /*!< LPTIM Capture/Compare register 1, Address offset: 0x14 */ + __IO uint32_t ARR; /*!< LPTIM Autoreload register, Address offset: 0x18 */ + __IO uint32_t CNT; /*!< LPTIM Counter register, Address offset: 0x1C */ + __IO uint32_t RESERVED0; /*!< Reserved, Address offset: 0x20 */ + __IO uint32_t CFGR2; /*!< LPTIM Configuration register 2, Address offset: 0x24 */ + __IO uint32_t RCR; /*!< LPTIM Repetition register, Address offset: 0x28 */ + __IO uint32_t CCMR1; /*!< LPTIM Capture/Compare mode register, Address offset: 0x2C */ + __IO uint32_t RESERVED1; /*!< Reserved, Address offset: 0x30 */ + __IO uint32_t CCR2; /*!< LPTIM Capture/Compare register 2, Address offset: 0x34 */ +} LPTIM_TypeDef; + +/** + * @brief OCTO Serial Peripheral Interface + */ + +typedef struct +{ + __IO uint32_t CR; /*!< OCTOSPI Control register, Address offset: 0x000 */ + uint32_t RESERVED; /*!< Reserved, Address offset: 0x004 */ + __IO uint32_t DCR1; /*!< OCTOSPI Device Configuration register 1, Address offset: 0x008 */ + __IO uint32_t DCR2; /*!< OCTOSPI Device Configuration register 2, Address offset: 0x00C */ + __IO uint32_t DCR3; /*!< OCTOSPI Device Configuration register 3, Address offset: 0x010 */ + __IO uint32_t DCR4; /*!< OCTOSPI Device Configuration register 4, Address offset: 0x014 */ + uint32_t RESERVED1[2]; /*!< Reserved, Address offset: 0x018-0x01C */ + __IO uint32_t SR; /*!< OCTOSPI Status register, Address offset: 0x020 */ + __IO uint32_t FCR; /*!< OCTOSPI Flag Clear register, Address offset: 0x024 */ + uint32_t RESERVED2[6]; /*!< Reserved, Address offset: 0x028-0x03C */ + __IO uint32_t DLR; /*!< OCTOSPI Data Length register, Address offset: 0x040 */ + uint32_t RESERVED3; /*!< Reserved, Address offset: 0x044 */ + __IO uint32_t AR; /*!< OCTOSPI Address register, Address offset: 0x048 */ + uint32_t RESERVED4; /*!< Reserved, Address offset: 0x04C */ + __IO uint32_t DR; /*!< OCTOSPI Data register, Address offset: 0x050 */ + uint32_t RESERVED5[11]; /*!< Reserved, Address offset: 0x054-0x07C */ + __IO uint32_t PSMKR; /*!< OCTOSPI Polling Status Mask register, Address offset: 0x080 */ + uint32_t RESERVED6; /*!< Reserved, Address offset: 0x084 */ + __IO uint32_t PSMAR; /*!< OCTOSPI Polling Status Match register, Address offset: 0x088 */ + uint32_t RESERVED7; /*!< Reserved, Address offset: 0x08C */ + __IO uint32_t PIR; /*!< OCTOSPI Polling Interval register, Address offset: 0x090 */ + uint32_t RESERVED8[27]; /*!< Reserved, Address offset: 0x094-0x0FC */ + __IO uint32_t CCR; /*!< OCTOSPI Communication Configuration register, Address offset: 0x100 */ + uint32_t RESERVED9; /*!< Reserved, Address offset: 0x104 */ + __IO uint32_t TCR; /*!< OCTOSPI Timing Configuration register, Address offset: 0x108 */ + uint32_t RESERVED10; /*!< Reserved, Address offset: 0x10C */ + __IO uint32_t IR; /*!< OCTOSPI Instruction register, Address offset: 0x110 */ + uint32_t RESERVED11[3]; /*!< Reserved, Address offset: 0x114-0x11C */ + __IO uint32_t ABR; /*!< OCTOSPI Alternate Bytes register, Address offset: 0x120 */ + uint32_t RESERVED12[3]; /*!< Reserved, Address offset: 0x124-0x12C */ + __IO uint32_t LPTR; /*!< OCTOSPI Low Power Timeout register, Address offset: 0x130 */ + uint32_t RESERVED13[3]; /*!< Reserved, Address offset: 0x134-0x13C */ + __IO uint32_t WPCCR; /*!< OCTOSPI Wrap Communication Configuration register, Address offset: 0x140 */ + uint32_t RESERVED14; /*!< Reserved, Address offset: 0x144 */ + __IO uint32_t WPTCR; /*!< OCTOSPI Wrap Timing Configuration register, Address offset: 0x148 */ + uint32_t RESERVED15; /*!< Reserved, Address offset: 0x14C */ + __IO uint32_t WPIR; /*!< OCTOSPI Wrap Instruction register, Address offset: 0x150 */ + uint32_t RESERVED16[3]; /*!< Reserved, Address offset: 0x154-0x15C */ + __IO uint32_t WPABR; /*!< OCTOSPI Wrap Alternate Bytes register, Address offset: 0x160 */ + uint32_t RESERVED17[7]; /*!< Reserved, Address offset: 0x164-0x17C */ + __IO uint32_t WCCR; /*!< OCTOSPI Write Communication Configuration register, Address offset: 0x180 */ + uint32_t RESERVED18; /*!< Reserved, Address offset: 0x184 */ + __IO uint32_t WTCR; /*!< OCTOSPI Write Timing Configuration register, Address offset: 0x188 */ + uint32_t RESERVED19; /*!< Reserved, Address offset: 0x18C */ + __IO uint32_t WIR; /*!< OCTOSPI Write Instruction register, Address offset: 0x190 */ + uint32_t RESERVED20[3]; /*!< Reserved, Address offset: 0x194-0x19C */ + __IO uint32_t WABR; /*!< OCTOSPI Write Alternate Bytes register, Address offset: 0x1A0 */ + uint32_t RESERVED21[23]; /*!< Reserved, Address offset: 0x1A4-0x1FC */ + __IO uint32_t HLCR; /*!< OCTOSPI Hyperbus Latency Configuration register, Address offset: 0x200 */ +} XSPI_TypeDef; + +typedef XSPI_TypeDef OCTOSPI_TypeDef; +/** + * @brief OTFDEC register + */ +typedef struct +{ + __IO uint32_t REG_CONFIGR; /*!< OTFDEC Region Configuration register, Address offset: 0x20 + 0x30 * (x -1) (x = 1 to 4) */ + __IO uint32_t REG_START_ADDR; /*!< OTFDEC Region Start Address register, Address offset: 0x24 + 0x30 * (x -1) (x = 1 to 4) */ + __IO uint32_t REG_END_ADDR; /*!< OTFDEC Region End Address register, Address offset: 0x28 + 0x30 * (x -1) (x = 1 to 4) */ + __IO uint32_t REG_NONCER0; /*!< OTFDEC Region Nonce register 0, Address offset: 0x2C + 0x30 * (x -1) (x = 1 to 4) */ + __IO uint32_t REG_NONCER1; /*!< OTFDEC Region Nonce register 1, Address offset: 0x30 + 0x30 * (x -1) (x = 1 to 4) */ + __IO uint32_t REG_KEYR0; /*!< OTFDEC Region Key register 0, Address offset: 0x34 + 0x30 * (x -1) (x = 1 to 4) */ + __IO uint32_t REG_KEYR1; /*!< OTFDEC Region Key register 1, Address offset: 0x38 + 0x30 * (x -1) (x = 1 to 4) */ + __IO uint32_t REG_KEYR2; /*!< OTFDEC Region Key register 2, Address offset: 0x3C + 0x30 * (x -1) (x = 1 to 4) */ + __IO uint32_t REG_KEYR3; /*!< OTFDEC Region Key register 3, Address offset: 0x40 + 0x30 * (x -1) (x = 1 to 4) */ +} OTFDEC_Region_TypeDef; + +typedef struct +{ + __IO uint32_t CR; /*!< OTFDEC Control register, Address offset: 0x000 */ + uint32_t RESERVED1[3]; /*!< Reserved, Address offset: 0x004-0x00C */ + __IO uint32_t PRIVCFGR; /*!< OTFDEC Privileged access control Configuration register, Address offset: 0x010 */ + uint32_t RESERVED2[187]; /*!< Reserved, Address offset: 0x014-0x2FC */ + __IO uint32_t ISR; /*!< OTFDEC Interrupt Status register, Address offset: 0x300 */ + __IO uint32_t ICR; /*!< OTFDEC Interrupt Clear register, Address offset: 0x304 */ + __IO uint32_t IER; /*!< OTFDEC Interrupt Enable register, Address offset: 0x308 */ +} OTFDEC_TypeDef; + + +/** + * @brief Power Control + */ +typedef struct +{ + __IO uint32_t PMCR; /*!< Power mode control register , Address offset: 0x00 */ + __IO uint32_t PMSR; /*!< Power mode status register , Address offset: 0x04 */ + uint32_t RESERVED1[2]; /*!< Reserved, Address offset: 0x08-0x0C */ + __IO uint32_t VOSCR; /*!< Voltage scaling control register , Address offset: 0x10 */ + __IO uint32_t VOSSR; /*!< Voltage sacling status register , Address offset: 0x14 */ + uint32_t RESERVED2[2]; /*!< Reserved, Address offset: 0x18-0x1C */ + __IO uint32_t BDCR; /*!< BacKup domain control register , Address offset: 0x20 */ + __IO uint32_t DBPCR; /*!< DBP control register, Address offset: 0x24 */ + __IO uint32_t BDSR; /*!< BacKup domain status register, Address offset: 0x28 */ + __IO uint32_t UCPDR; /*!< Usb typeC and Power Delivery Register, Address offset: 0x2C */ + __IO uint32_t SCCR; /*!< Supply configuration control register, Address offset: 0x30 */ + __IO uint32_t VMCR; /*!< Voltage Monitor Control Register, Address offset: 0x34 */ + __IO uint32_t USBSCR; /*!< USB Supply Control Register Address offset: 0x38 */ + __IO uint32_t VMSR; /*!< Status Register Voltage Monitoring, Address offset: 0x3C */ + __IO uint32_t WUSCR; /*!< WakeUP status clear register, Address offset: 0x40 */ + __IO uint32_t WUSR; /*!< WakeUP status Register, Address offset: 0x44 */ + __IO uint32_t WUCR; /*!< WakeUP configuration register, Address offset: 0x48 */ + uint32_t RESERVED3; /*!< Reserved, Address offset: 0x4C */ + __IO uint32_t IORETR; /*!< IO RETention Register, Address offset: 0x50 */ + uint32_t RESERVED4[43];/*!< Reserved, Address offset: 0x54-0xFC */ + __IO uint32_t SECCFGR; /*!< Security configuration register, Address offset: 0x100 */ + __IO uint32_t PRIVCFGR; /*!< Privilege configuration register, Address offset: 0x104 */ +}PWR_TypeDef; + +/** + * @brief SRAMs configuration controller + */ +typedef struct +{ + __IO uint32_t CR; /*!< Control Register, Address offset: 0x00 */ + __IO uint32_t IER; /*!< Interrupt Enable Register, Address offset: 0x04 */ + __IO uint32_t ISR; /*!< Interrupt Status Register, Address offset: 0x08 */ + __IO uint32_t SEAR; /*!< ECC Single Error Address Register, Address offset: 0x0C */ + __IO uint32_t DEAR; /*!< ECC Double Error Address Register, Address offset: 0x10 */ + __IO uint32_t ICR; /*!< Interrupt Clear Register, Address offset: 0x14 */ + __IO uint32_t WPR1; /*!< SRAM Write Protection Register 1, Address offset: 0x18 */ + __IO uint32_t WPR2; /*!< SRAM Write Protection Register 2, Address offset: 0x1C */ + uint32_t RESERVED; /*!< Reserved, Address offset: 0x20 */ + __IO uint32_t ECCKEY; /*!< SRAM ECC Key Register, Address offset: 0x24 */ + __IO uint32_t ERKEYR; /*!< SRAM Erase Key Register, Address offset: 0x28 */ +}RAMCFG_TypeDef; + +/** + * @brief Reset and Clock Control + */ +typedef struct +{ + __IO uint32_t CR; /*!< RCC clock control register Address offset: 0x00 */ + uint32_t RESERVED1[3]; /*!< Reserved, Address offset: 0x04 */ + __IO uint32_t HSICFGR; /*!< RCC HSI Clock Calibration Register, Address offset: 0x10 */ + __IO uint32_t CRRCR; /*!< RCC Clock Recovery RC Register, Address offset: 0x14 */ + __IO uint32_t CSICFGR; /*!< RCC CSI Clock Calibration Register, Address offset: 0x18 */ + __IO uint32_t CFGR1; /*!< RCC clock configuration register 1 Address offset: 0x1C */ + __IO uint32_t CFGR2; /*!< RCC clock configuration register 2 Address offset: 0x20 */ + uint32_t RESERVED2; /*!< Reserved, Address offset: 0x24 */ + __IO uint32_t PLL1CFGR; /*!< RCC PLL1 Configuration Register Address offset: 0x28 */ + __IO uint32_t PLL2CFGR; /*!< RCC PLL2 Configuration Register Address offset: 0x2C */ + __IO uint32_t PLL3CFGR; /*!< RCC PLL3 Configuration Register Address offset: 0x30 */ + __IO uint32_t PLL1DIVR; /*!< RCC PLL1 Dividers Configuration Register Address offset: 0x34 */ + __IO uint32_t PLL1FRACR; /*!< RCC PLL1 Fractional Divider Configuration Register Address offset: 0x38 */ + __IO uint32_t PLL2DIVR; /*!< RCC PLL2 Dividers Configuration Register Address offset: 0x3C */ + __IO uint32_t PLL2FRACR; /*!< RCC PLL2 Fractional Divider Configuration Register Address offset: 0x40 */ + __IO uint32_t PLL3DIVR; /*!< RCC PLL3 Dividers Configuration Register Address offset: 0x44 */ + __IO uint32_t PLL3FRACR; /*!< RCC PLL3 Fractional Divider Configuration Register Address offset: 0x48 */ + uint32_t RESERVED5; /*!< Reserved Address offset: 0x4C */ + __IO uint32_t CIER; /*!< RCC Clock Interrupt Enable Register Address offset: 0x50 */ + __IO uint32_t CIFR; /*!< RCC Clock Interrupt Flag Register Address offset: 0x54 */ + __IO uint32_t CICR; /*!< RCC Clock Interrupt Clear Register Address offset: 0x58 */ + uint32_t RESERVED6; /*!< Reserved Address offset: 0x5C */ + __IO uint32_t AHB1RSTR; /*!< RCC AHB1 Peripherals Reset Register Address offset: 0x60 */ + __IO uint32_t AHB2RSTR; /*!< RCC AHB2 Peripherals Reset Register Address offset: 0x64 */ + uint32_t RESERVED7; /*!< Reserved Address offset: 0x68 */ + __IO uint32_t AHB4RSTR; /*!< RCC AHB4 Peripherals Reset Register Address offset: 0x6C */ + uint32_t RESERVED9; /*!< Reserved Address offset: 0x70 */ + __IO uint32_t APB1LRSTR; /*!< RCC APB1 Peripherals reset Low Word register Address offset: 0x74 */ + __IO uint32_t APB1HRSTR; /*!< RCC APB1 Peripherals reset High Word register Address offset: 0x78 */ + __IO uint32_t APB2RSTR; /*!< RCC APB2 Peripherals Reset Register Address offset: 0x7C */ + __IO uint32_t APB3RSTR; /*!< RCC APB3 Peripherals Reset Register Address offset: 0x80 */ + uint32_t RESERVED10; /*!< Reserved Address offset: 0x84 */ + __IO uint32_t AHB1ENR; /*!< RCC AHB1 Peripherals Clock Enable Register Address offset: 0x88 */ + __IO uint32_t AHB2ENR; /*!< RCC AHB2 Peripherals Clock Enable Register Address offset: 0x8C */ + uint32_t RESERVED11; /*!< Reserved Address offset: 0x90 */ + __IO uint32_t AHB4ENR; /*!< RCC AHB4 Peripherals Clock Enable Register Address offset: 0x94 */ + uint32_t RESERVED13; /*!< Reserved Address offset: 0x98 */ + __IO uint32_t APB1LENR; /*!< RCC APB1 Peripherals clock Enable Low Word register Address offset: 0x9C */ + __IO uint32_t APB1HENR; /*!< RCC APB1 Peripherals clock Enable High Word register Address offset: 0xA0 */ + __IO uint32_t APB2ENR; /*!< RCC APB2 Peripherals Clock Enable Register Address offset: 0xA4 */ + __IO uint32_t APB3ENR; /*!< RCC APB3 Peripherals Clock Enable Register Address offset: 0xA8 */ + uint32_t RESERVED14; /*!< Reserved Address offset: 0xAC */ + __IO uint32_t AHB1LPENR; /*!< RCC AHB1 Peripheral sleep clock Register Address offset: 0xB0 */ + __IO uint32_t AHB2LPENR; /*!< RCC AHB2 Peripheral sleep clock Register Address offset: 0xB4 */ + uint32_t RESERVED15; /*!< Reserved Address offset: 0xB8 */ + __IO uint32_t AHB4LPENR; /*!< RCC AHB4 Peripherals sleep clock Register Address offset: 0xBC */ + uint32_t RESERVED17; /*!< Reserved Address offset: 0xC0 */ + __IO uint32_t APB1LLPENR; /*!< RCC APB1 Peripherals sleep clock Low Word Register Address offset: 0xC4 */ + __IO uint32_t APB1HLPENR; /*!< RCC APB1 Peripherals sleep clock High Word Register Address offset: 0xC8 */ + __IO uint32_t APB2LPENR; /*!< RCC APB2 Peripherals sleep clock Register Address offset: 0xCC */ + __IO uint32_t APB3LPENR; /*!< RCC APB3 Peripherals Clock Low Power Enable Register Address offset: 0xD0 */ + uint32_t RESERVED18; /*!< Reserved Address offset: 0xD4 */ + __IO uint32_t CCIPR1; /*!< RCC IPs Clocks Configuration Register 1 Address offset: 0xD8 */ + __IO uint32_t CCIPR2; /*!< RCC IPs Clocks Configuration Register 2 Address offset: 0xDC */ + __IO uint32_t CCIPR3; /*!< RCC IPs Clocks Configuration Register 3 Address offset: 0xE0 */ + __IO uint32_t CCIPR4; /*!< RCC IPs Clocks Configuration Register 4 Address offset: 0xE4 */ + __IO uint32_t CCIPR5; /*!< RCC IPs Clocks Configuration Register 5 Address offset: 0xE8 */ + uint32_t RESERVED19; /*!< Reserved, Address offset: 0xEC */ + __IO uint32_t BDCR; /*!< RCC VSW Backup Domain & V33 Domain Control Register Address offset: 0xF0 */ + __IO uint32_t RSR; /*!< RCC Reset status Register Address offset: 0xF4 */ + uint32_t RESERVED20[6]; /*!< Reserved Address offset: 0xF8 */ + __IO uint32_t SECCFGR; /*!< RCC Secure mode configuration register Address offset: 0x110 */ + __IO uint32_t PRIVCFGR; /*!< RCC Privilege configuration register Address offset: 0x114 */ +} RCC_TypeDef; + +/** + * @brief PKA + */ +typedef struct +{ + __IO uint32_t CR; /*!< PKA control register, Address offset: 0x00 */ + __IO uint32_t SR; /*!< PKA status register, Address offset: 0x04 */ + __IO uint32_t CLRFR; /*!< PKA clear flag register, Address offset: 0x08 */ + uint32_t Reserved[253]; /*!< Reserved memory area Address offset: 0x0C -> 0x03FC */ + __IO uint32_t RAM[1334]; /*!< PKA RAM Address offset: 0x400 -> 0x18D4 */ +} PKA_TypeDef; + +/* +* @brief RTC Specific device feature definitions +*/ +#define RTC_BKP_NB 32U +#define RTC_TAMP_NB 8U + +/** + * @brief Real-Time Clock + */ +typedef struct +{ + __IO uint32_t TR; /*!< RTC time register, Address offset: 0x00 */ + __IO uint32_t DR; /*!< RTC date register, Address offset: 0x04 */ + __IO uint32_t SSR; /*!< RTC sub second register, Address offset: 0x08 */ + __IO uint32_t ICSR; /*!< RTC initialization control and status register, Address offset: 0x0C */ + __IO uint32_t PRER; /*!< RTC prescaler register, Address offset: 0x10 */ + __IO uint32_t WUTR; /*!< RTC wakeup timer register, Address offset: 0x14 */ + __IO uint32_t CR; /*!< RTC control register, Address offset: 0x18 */ + __IO uint32_t PRIVCFGR; /*!< RTC privilege mode control register, Address offset: 0x1C */ + __IO uint32_t SECCFGR; /*!< RTC secure mode control register, Address offset: 0x20 */ + __IO uint32_t WPR; /*!< RTC write protection register, Address offset: 0x24 */ + __IO uint32_t CALR; /*!< RTC calibration register, Address offset: 0x28 */ + __IO uint32_t SHIFTR; /*!< RTC shift control register, Address offset: 0x2C */ + __IO uint32_t TSTR; /*!< RTC time stamp time register, Address offset: 0x30 */ + __IO uint32_t TSDR; /*!< RTC time stamp date register, Address offset: 0x34 */ + __IO uint32_t TSSSR; /*!< RTC time-stamp sub second register, Address offset: 0x38 */ + uint32_t RESERVED0; /*!< Reserved, Address offset: 0x3C */ + __IO uint32_t ALRMAR; /*!< RTC alarm A register, Address offset: 0x40 */ + __IO uint32_t ALRMASSR; /*!< RTC alarm A sub second register, Address offset: 0x44 */ + __IO uint32_t ALRMBR; /*!< RTC alarm B register, Address offset: 0x48 */ + __IO uint32_t ALRMBSSR; /*!< RTC alarm B sub second register, Address offset: 0x4C */ + __IO uint32_t SR; /*!< RTC Status register, Address offset: 0x50 */ + __IO uint32_t MISR; /*!< RTC masked interrupt status register, Address offset: 0x54 */ + __IO uint32_t SMISR; /*!< RTC secure masked interrupt status register, Address offset: 0x58 */ + __IO uint32_t SCR; /*!< RTC status Clear register, Address offset: 0x5C */ + __IO uint32_t OR; /*!< RTC option register, Address offset: 0x60 */ + uint32_t RESERVED1[3];/*!< Reserved, Address offset: 0x64 */ + __IO uint32_t ALRABINR; /*!< RTC alarm A binary mode register, Address offset: 0x70 */ + __IO uint32_t ALRBBINR; /*!< RTC alarm B binary mode register, Address offset: 0x74 */ +} RTC_TypeDef; + +/** + * @brief Tamper and backup registers + */ +typedef struct +{ + __IO uint32_t CR1; /*!< TAMP control register 1, Address offset: 0x00 */ + __IO uint32_t CR2; /*!< TAMP control register 2, Address offset: 0x04 */ + __IO uint32_t CR3; /*!< TAMP control register 3, Address offset: 0x08 */ + __IO uint32_t FLTCR; /*!< TAMP filter control register, Address offset: 0x0C */ + __IO uint32_t ATCR1; /*!< TAMP filter control register 1 Address offset: 0x10 */ + __IO uint32_t ATSEEDR; /*!< TAMP active tamper seed register, Address offset: 0x14 */ + __IO uint32_t ATOR; /*!< TAMP active tamper output register, Address offset: 0x18 */ + __IO uint32_t ATCR2; /*!< TAMP filter control register 2, Address offset: 0x1C */ + __IO uint32_t SECCFGR; /*!< TAMP secure mode control register, Address offset: 0x20 */ + __IO uint32_t PRIVCFGR; /*!< TAMP privilege mode control register, Address offset: 0x24 */ + uint32_t RESERVED0; /*!< Reserved, Address offset: 0x28 */ + __IO uint32_t IER; /*!< TAMP interrupt enable register, Address offset: 0x2C */ + __IO uint32_t SR; /*!< TAMP status register, Address offset: 0x30 */ + __IO uint32_t MISR; /*!< TAMP masked interrupt status register, Address offset: 0x34 */ + __IO uint32_t SMISR; /*!< TAMP secure masked interrupt status register, Address offset: 0x38 */ + __IO uint32_t SCR; /*!< TAMP status clear register, Address offset: 0x3C */ + __IO uint32_t COUNT1R; /*!< TAMP monotonic counter register, Address offset: 0x40 */ + uint32_t RESERVED1[3];/*!< Reserved, Address offset: 0x44 -- 0x4C */ + __IO uint32_t OR; /*!< TAMP option register, Address offset: 0x50 */ + __IO uint32_t ERCFGR; /*!< TAMP erase configuration register, Address offset: 0x54 */ + uint32_t RESERVED2[42];/*!< Reserved, Address offset: 0x58 -- 0xFC */ + __IO uint32_t BKP0R; /*!< TAMP backup register 0, Address offset: 0x100 */ + __IO uint32_t BKP1R; /*!< TAMP backup register 1, Address offset: 0x104 */ + __IO uint32_t BKP2R; /*!< TAMP backup register 2, Address offset: 0x108 */ + __IO uint32_t BKP3R; /*!< TAMP backup register 3, Address offset: 0x10C */ + __IO uint32_t BKP4R; /*!< TAMP backup register 4, Address offset: 0x110 */ + __IO uint32_t BKP5R; /*!< TAMP backup register 5, Address offset: 0x114 */ + __IO uint32_t BKP6R; /*!< TAMP backup register 6, Address offset: 0x118 */ + __IO uint32_t BKP7R; /*!< TAMP backup register 7, Address offset: 0x11C */ + __IO uint32_t BKP8R; /*!< TAMP backup register 8, Address offset: 0x120 */ + __IO uint32_t BKP9R; /*!< TAMP backup register 9, Address offset: 0x124 */ + __IO uint32_t BKP10R; /*!< TAMP backup register 10, Address offset: 0x128 */ + __IO uint32_t BKP11R; /*!< TAMP backup register 11, Address offset: 0x12C */ + __IO uint32_t BKP12R; /*!< TAMP backup register 12, Address offset: 0x130 */ + __IO uint32_t BKP13R; /*!< TAMP backup register 13, Address offset: 0x134 */ + __IO uint32_t BKP14R; /*!< TAMP backup register 14, Address offset: 0x138 */ + __IO uint32_t BKP15R; /*!< TAMP backup register 15, Address offset: 0x13C */ + __IO uint32_t BKP16R; /*!< TAMP backup register 16, Address offset: 0x140 */ + __IO uint32_t BKP17R; /*!< TAMP backup register 17, Address offset: 0x144 */ + __IO uint32_t BKP18R; /*!< TAMP backup register 18, Address offset: 0x148 */ + __IO uint32_t BKP19R; /*!< TAMP backup register 19, Address offset: 0x14C */ + __IO uint32_t BKP20R; /*!< TAMP backup register 20, Address offset: 0x150 */ + __IO uint32_t BKP21R; /*!< TAMP backup register 21, Address offset: 0x154 */ + __IO uint32_t BKP22R; /*!< TAMP backup register 22, Address offset: 0x158 */ + __IO uint32_t BKP23R; /*!< TAMP backup register 23, Address offset: 0x15C */ + __IO uint32_t BKP24R; /*!< TAMP backup register 24, Address offset: 0x160 */ + __IO uint32_t BKP25R; /*!< TAMP backup register 25, Address offset: 0x164 */ + __IO uint32_t BKP26R; /*!< TAMP backup register 26, Address offset: 0x168 */ + __IO uint32_t BKP27R; /*!< TAMP backup register 27, Address offset: 0x16C */ + __IO uint32_t BKP28R; /*!< TAMP backup register 28, Address offset: 0x170 */ + __IO uint32_t BKP29R; /*!< TAMP backup register 29, Address offset: 0x174 */ + __IO uint32_t BKP30R; /*!< TAMP backup register 30, Address offset: 0x178 */ + __IO uint32_t BKP31R; /*!< TAMP backup register 31, Address offset: 0x17C */ +} TAMP_TypeDef; + +/** + * @brief Universal Synchronous Asynchronous Receiver Transmitter + */ +typedef struct +{ + __IO uint32_t CR1; /*!< USART Control register 1, Address offset: 0x00 */ + __IO uint32_t CR2; /*!< USART Control register 2, Address offset: 0x04 */ + __IO uint32_t CR3; /*!< USART Control register 3, Address offset: 0x08 */ + __IO uint32_t BRR; /*!< USART Baud rate register, Address offset: 0x0C */ + __IO uint32_t GTPR; /*!< USART Guard time and prescaler register, Address offset: 0x10 */ + __IO uint32_t RTOR; /*!< USART Receiver Time Out register, Address offset: 0x14 */ + __IO uint32_t RQR; /*!< USART Request register, Address offset: 0x18 */ + __IO uint32_t ISR; /*!< USART Interrupt and status register, Address offset: 0x1C */ + __IO uint32_t ICR; /*!< USART Interrupt flag Clear register, Address offset: 0x20 */ + __IO uint32_t RDR; /*!< USART Receive Data register, Address offset: 0x24 */ + __IO uint32_t TDR; /*!< USART Transmit Data register, Address offset: 0x28 */ + __IO uint32_t PRESC; /*!< USART Prescaler register, Address offset: 0x2C */ +} USART_TypeDef; + +/** + * @brief Serial Audio Interface + */ +typedef struct +{ + __IO uint32_t GCR; /*!< SAI global configuration register, Address offset: 0x00 */ + uint32_t RESERVED[16]; /*!< Reserved, Address offset: 0x04 to 0x40 */ + __IO uint32_t PDMCR; /*!< SAI PDM control register, Address offset: 0x44 */ + __IO uint32_t PDMDLY; /*!< SAI PDM delay register, Address offset: 0x48 */ +} SAI_TypeDef; + +typedef struct +{ + __IO uint32_t CR1; /*!< SAI block x configuration register 1, Address offset: 0x04 */ + __IO uint32_t CR2; /*!< SAI block x configuration register 2, Address offset: 0x08 */ + __IO uint32_t FRCR; /*!< SAI block x frame configuration register, Address offset: 0x0C */ + __IO uint32_t SLOTR; /*!< SAI block x slot register, Address offset: 0x10 */ + __IO uint32_t IMR; /*!< SAI block x interrupt mask register, Address offset: 0x14 */ + __IO uint32_t SR; /*!< SAI block x status register, Address offset: 0x18 */ + __IO uint32_t CLRFR; /*!< SAI block x clear flag register, Address offset: 0x1C */ + __IO uint32_t DR; /*!< SAI block x data register, Address offset: 0x20 */ +} SAI_Block_TypeDef; +/** + * @brief System configuration, Boot and Security + */ +typedef struct +{ + uint32_t RESERVED1[4]; /*!< RESERVED1, Address offset: 0x00 - 0x0C */ + __IO uint32_t HDPLCR; /*!< SBS HDPL Control Register, Address offset: 0x10 */ + __IO uint32_t HDPLSR; /*!< SBS HDPL Status Register, Address offset: 0x14 */ + __IO uint32_t NEXTHDPLCR; /*!< NEXT HDPL Control Register, Address offset: 0x18 */ + __IO uint32_t RESERVED2; /*!< RESERVED2, Address offset: 0x1C */ + __IO uint32_t DBGCR; /*!< SBS Debug Control Register, Address offset: 0x20 */ + __IO uint32_t DBGLOCKR; /*!< SBS Debug Lock Register, Address offset: 0x24 */ + uint32_t RESERVED3[3]; /*!< RESERVED3, Address offset: 0x28 - 0x30 */ + __IO uint32_t RSSCMDR; /*!< SBS RSS Command Register, Address offset: 0x34 */ + uint32_t RESERVED4[26]; /*!< RESERVED4, Address offset: 0x38 - 0x9C */ + __IO uint32_t EPOCHSELCR; /*!< EPOCH Selection Register, Address offset: 0xA0 */ + uint32_t RESERVED5[7]; /*!< RESERVED5, Address offset: 0xA4 - 0xBC */ + __IO uint32_t SECCFGR; /*!< SBS Security Mode Configuration, Address offset: 0xC0 */ + uint32_t RESERVED6[15]; /*!< RESERVED6, Address offset: 0xC4 - 0xFC */ + __IO uint32_t PMCR; /*!< SBS Product Mode & Config Register, Address offset: 0x100 */ + __IO uint32_t FPUIMR; /*!< SBS FPU Interrupt Mask Register, Address offset: 0x104 */ + __IO uint32_t MESR; /*!< SBS Memory Erase Status Register, Address offset: 0x108 */ + uint32_t RESERVED7; /*!< RESERVED7, Address offset: 0x10C */ + __IO uint32_t CCCSR; /*!< SBS Compensation Cell Control & Status Register, Address offset: 0x110 */ + __IO uint32_t CCVALR; /*!< SBS Compensation Cell Value Register, Address offset: 0x114 */ + __IO uint32_t CCSWCR; /*!< SBS Compensation Cell for I/Os sw code Register, Address offset: 0x118 */ + __IO uint32_t RESERVED8; /*!< RESERVED8, Address offset: 0x11C */ + __IO uint32_t CFGR2; /*!< SBS Class B Register, Address offset: 0x120 */ + uint32_t RESERVED9[8]; /*!< RESERVED9, Address offset: 0x124 - 0x140 */ + __IO uint32_t CNSLCKR; /*!< SBS CPU Non-secure Lock Register, Address offset: 0x144 */ + __IO uint32_t CSLCKR; /*!< SBS CPU Secure Lock Register, Address offset: 0x148 */ + __IO uint32_t ECCNMIR; /*!< SBS FLITF ECC NMI MASK Register, Address offset: 0x14C */ +} SBS_TypeDef; + +/** + * @brief Secure digital input/output Interface + */ +typedef struct +{ + __IO uint32_t POWER; /*!< SDMMC power control register, Address offset: 0x00 */ + __IO uint32_t CLKCR; /*!< SDMMC clock control register, Address offset: 0x04 */ + __IO uint32_t ARG; /*!< SDMMC argument register, Address offset: 0x08 */ + __IO uint32_t CMD; /*!< SDMMC command register, Address offset: 0x0C */ + __I uint32_t RESPCMD; /*!< SDMMC command response register, Address offset: 0x10 */ + __I uint32_t RESP1; /*!< SDMMC response 1 register, Address offset: 0x14 */ + __I uint32_t RESP2; /*!< SDMMC response 2 register, Address offset: 0x18 */ + __I uint32_t RESP3; /*!< SDMMC response 3 register, Address offset: 0x1C */ + __I uint32_t RESP4; /*!< SDMMC response 4 register, Address offset: 0x20 */ + __IO uint32_t DTIMER; /*!< SDMMC data timer register, Address offset: 0x24 */ + __IO uint32_t DLEN; /*!< SDMMC data length register, Address offset: 0x28 */ + __IO uint32_t DCTRL; /*!< SDMMC data control register, Address offset: 0x2C */ + __I uint32_t DCOUNT; /*!< SDMMC data counter register, Address offset: 0x30 */ + __I uint32_t STA; /*!< SDMMC status register, Address offset: 0x34 */ + __IO uint32_t ICR; /*!< SDMMC interrupt clear register, Address offset: 0x38 */ + __IO uint32_t MASK; /*!< SDMMC mask register, Address offset: 0x3C */ + __IO uint32_t ACKTIME; /*!< SDMMC Acknowledgement timer register, Address offset: 0x40 */ + uint32_t RESERVED0[3]; /*!< Reserved, 0x44 - 0x4C - 0x4C */ + __IO uint32_t IDMACTRL; /*!< SDMMC DMA control register, Address offset: 0x50 */ + __IO uint32_t IDMABSIZE; /*!< SDMMC DMA buffer size register, Address offset: 0x54 */ + __IO uint32_t IDMABASER; /*!< SDMMC DMA buffer base address register, Address offset: 0x58 */ + uint32_t RESERVED1[2]; /*!< Reserved, 0x60 */ + __IO uint32_t IDMALAR; /*!< SDMMC DMA linked list address register, Address offset: 0x64 */ + __IO uint32_t IDMABAR; /*!< SDMMC DMA linked list memory base register,Address offset: 0x68 */ + uint32_t RESERVED2[5]; /*!< Reserved, 0x6C-0x7C */ + __IO uint32_t FIFO; /*!< SDMMC data FIFO register, Address offset: 0x80 */ +} SDMMC_TypeDef; + + + +/** + * @brief Delay Block DLYB + */ + +typedef struct +{ + __IO uint32_t CR; /*!< DELAY BLOCK control register, Address offset: 0x00 */ + __IO uint32_t CFGR; /*!< DELAY BLOCK configuration register, Address offset: 0x04 */ +} DLYB_TypeDef; + +/** + * @brief UCPD + */ +typedef struct +{ + __IO uint32_t CFG1; /*!< UCPD configuration register 1, Address offset: 0x00 */ + __IO uint32_t CFG2; /*!< UCPD configuration register 2, Address offset: 0x04 */ + __IO uint32_t CFG3; /*!< UCPD configuration register 3, Address offset: 0x08 */ + __IO uint32_t CR; /*!< UCPD control register, Address offset: 0x0C */ + __IO uint32_t IMR; /*!< UCPD interrupt mask register, Address offset: 0x10 */ + __IO uint32_t SR; /*!< UCPD status register, Address offset: 0x14 */ + __IO uint32_t ICR; /*!< UCPD interrupt flag clear register Address offset: 0x18 */ + __IO uint32_t TX_ORDSET; /*!< UCPD Tx ordered set type register, Address offset: 0x1C */ + __IO uint32_t TX_PAYSZ; /*!< UCPD Tx payload size register, Address offset: 0x20 */ + __IO uint32_t TXDR; /*!< UCPD Tx data register, Address offset: 0x24 */ + __IO uint32_t RX_ORDSET; /*!< UCPD Rx ordered set type register, Address offset: 0x28 */ + __IO uint32_t RX_PAYSZ; /*!< UCPD Rx payload size register, Address offset: 0x2C */ + __IO uint32_t RXDR; /*!< UCPD Rx data register, Address offset: 0x30 */ + __IO uint32_t RX_ORDEXT1; /*!< UCPD Rx ordered set extension 1 register, Address offset: 0x34 */ + __IO uint32_t RX_ORDEXT2; /*!< UCPD Rx ordered set extension 2 register, Address offset: 0x38 */ + uint32_t RESERVED[949];/*!< Reserved, Address offset: 0x3C -- 0x3F0 */ + __IO uint32_t IPVER; /*!< UCPD IP version register, Address offset: 0x3F4 */ + __IO uint32_t IPID; /*!< UCPD IP Identification register, Address offset: 0x3F8 */ + __IO uint32_t MID; /*!< UCPD Magic Identification register, Address offset: 0x3FC */ +} UCPD_TypeDef; + +/** + * @brief Universal Serial Bus Full Speed Dual Role Device + */ +typedef struct +{ + __IO uint32_t CHEP0R; /*!< USB Channel/Endpoint 0 register, Address offset: 0x00 */ + __IO uint32_t CHEP1R; /*!< USB Channel/Endpoint 1 register, Address offset: 0x04 */ + __IO uint32_t CHEP2R; /*!< USB Channel/Endpoint 2 register, Address offset: 0x08 */ + __IO uint32_t CHEP3R; /*!< USB Channel/Endpoint 3 register, Address offset: 0x0C */ + __IO uint32_t CHEP4R; /*!< USB Channel/Endpoint 4 register, Address offset: 0x10 */ + __IO uint32_t CHEP5R; /*!< USB Channel/Endpoint 5 register, Address offset: 0x14 */ + __IO uint32_t CHEP6R; /*!< USB Channel/Endpoint 6 register, Address offset: 0x18 */ + __IO uint32_t CHEP7R; /*!< USB Channel/Endpoint 7 register, Address offset: 0x1C */ + __IO uint32_t RESERVED0[8]; /*!< Reserved, */ + __IO uint32_t CNTR; /*!< Control register, Address offset: 0x40 */ + __IO uint32_t ISTR; /*!< Interrupt status register, Address offset: 0x44 */ + __IO uint32_t FNR; /*!< Frame number register, Address offset: 0x48 */ + __IO uint32_t DADDR; /*!< Device address register, Address offset: 0x4C */ + __IO uint32_t RESERVED1; /*!< Reserved */ + __IO uint32_t LPMCSR; /*!< LPM Control and Status register, Address offset: 0x54 */ + __IO uint32_t BCDR; /*!< Battery Charging detector register, Address offset: 0x58 */ +} USB_DRD_TypeDef; + +/** + * @brief Universal Serial Bus PacketMemoryArea Buffer Descriptor Table + */ +typedef struct +{ + __IO uint32_t TXBD; /*!= 6010050) + #pragma clang diagnostic pop +#elif defined (__GNUC__) + /* anonymous unions are enabled by default */ +#elif defined (__TMS470__) + /* anonymous unions are enabled by default */ +#elif defined (__TASKING__) + #pragma warning restore +#elif defined (__CSMC__) + /* anonymous unions are enabled by default */ +#else + #warning Not supported compiler type +#endif + + +/* =========================================================================================================================== */ +/* ================ Device Specific Peripheral Address Map ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup STM32H5xx_Peripheral_peripheralAddr + * @{ + */ + +/* Internal SRAMs size */ +#define SRAM1_SIZE (0x40000UL) /*!< SRAM1=256k */ +#define SRAM2_SIZE (0x10000UL) /*!< SRAM2=64k */ +#define SRAM3_SIZE (0x50000UL) /*!< SRAM3=320k */ +#define BKPSRAM_SIZE (0x01000UL) /*!< BKPSRAM=4k */ + +/* Flash, Peripheral and internal SRAMs base addresses - Non secure */ +#define FLASH_BASE_NS (0x08000000UL) /*!< FLASH (up to 2 MB) non-secure base address */ +#define SRAM1_BASE_NS (0x20000000UL) /*!< SRAM1 (256 KB) non-secure base address */ +#define SRAM2_BASE_NS (0x20040000UL) /*!< SRAM2 (64 KB) non-secure base address */ +#define SRAM3_BASE_NS (0x20050000UL) /*!< SRAM3 (320 KB) non-secure base address */ +#define PERIPH_BASE_NS (0x40000000UL) /*!< Peripheral non-secure base address */ + +/* External memories base addresses - Not aliased */ +#define FMC_BASE (0x60000000UL) /*!< FMC base address */ +#define OCTOSPI1_BASE (0x90000000UL) /*!< OCTOSPI1 memories accessible over AHB base address */ + +#define FMC_BANK1 FMC_BASE +#define FMC_BANK1_1 FMC_BANK1 +#define FMC_BANK1_2 (FMC_BANK1 + 0x04000000UL) /*!< FMC Memory Bank1 for SRAM, NOR and PSRAM */ +#define FMC_BANK1_3 (FMC_BANK1 + 0x08000000UL) +#define FMC_BANK1_4 (FMC_BANK1 + 0x0C000000UL) +#define FMC_BANK3 (FMC_BASE + 0x20000000UL) /*!< FMC Memory Bank3 for NAND */ +#define FMC_SDRAM_BANK_1 (FMC_BASE + 0x60000000UL) /*!< FMC Memory SDRAM Bank1 */ +#define FMC_SDRAM_BANK_2 (FMC_BASE + 0x70000000UL) /*!< FMC Memory SDRAM Bank2 */ + + +/* Peripheral memory map - Non secure */ +#define APB1PERIPH_BASE_NS PERIPH_BASE_NS +#define APB2PERIPH_BASE_NS (PERIPH_BASE_NS + 0x00010000UL) +#define AHB1PERIPH_BASE_NS (PERIPH_BASE_NS + 0x00020000UL) +#define AHB2PERIPH_BASE_NS (PERIPH_BASE_NS + 0x02020000UL) +#define APB3PERIPH_BASE_NS (PERIPH_BASE_NS + 0x04000000UL) +#define AHB3PERIPH_BASE_NS (PERIPH_BASE_NS + 0x04020000UL) +#define AHB4PERIPH_BASE_NS (PERIPH_BASE_NS + 0x06000000UL) + +/*!< APB1 Non secure peripherals */ +#define TIM2_BASE_NS (APB1PERIPH_BASE_NS + 0x0000UL) +#define TIM3_BASE_NS (APB1PERIPH_BASE_NS + 0x0400UL) +#define TIM4_BASE_NS (APB1PERIPH_BASE_NS + 0x0800UL) +#define TIM5_BASE_NS (APB1PERIPH_BASE_NS + 0x0C00UL) +#define TIM6_BASE_NS (APB1PERIPH_BASE_NS + 0x1000UL) +#define TIM7_BASE_NS (APB1PERIPH_BASE_NS + 0x1400UL) +#define TIM12_BASE_NS (APB1PERIPH_BASE_NS + 0x1800UL) +#define TIM13_BASE_NS (APB1PERIPH_BASE_NS + 0x1C00UL) +#define TIM14_BASE_NS (APB1PERIPH_BASE_NS + 0x2000UL) +#define WWDG_BASE_NS (APB1PERIPH_BASE_NS + 0x2C00UL) +#define IWDG_BASE_NS (APB1PERIPH_BASE_NS + 0x3000UL) +#define SPI2_BASE_NS (APB1PERIPH_BASE_NS + 0x3800UL) +#define SPI3_BASE_NS (APB1PERIPH_BASE_NS + 0x3C00UL) +#define USART2_BASE_NS (APB1PERIPH_BASE_NS + 0x4400UL) +#define USART3_BASE_NS (APB1PERIPH_BASE_NS + 0x4800UL) +#define UART4_BASE_NS (APB1PERIPH_BASE_NS + 0x4C00UL) +#define UART5_BASE_NS (APB1PERIPH_BASE_NS + 0x5000UL) +#define I2C1_BASE_NS (APB1PERIPH_BASE_NS + 0x5400UL) +#define I2C2_BASE_NS (APB1PERIPH_BASE_NS + 0x5800UL) +#define I3C1_BASE_NS (APB1PERIPH_BASE_NS + 0x5C00UL) +#define CRS_BASE_NS (APB1PERIPH_BASE_NS + 0x6000UL) +#define USART6_BASE_NS (APB1PERIPH_BASE_NS + 0x6400UL) +#define USART10_BASE_NS (APB1PERIPH_BASE_NS + 0x6800UL) +#define USART11_BASE_NS (APB1PERIPH_BASE_NS + 0x6C00UL) +#define CEC_BASE_NS (APB1PERIPH_BASE_NS + 0x7000UL) +#define UART7_BASE_NS (APB1PERIPH_BASE_NS + 0x7800UL) +#define UART8_BASE_NS (APB1PERIPH_BASE_NS + 0x7C00UL) +#define UART9_BASE_NS (APB1PERIPH_BASE_NS + 0x8000UL) +#define UART12_BASE_NS (APB1PERIPH_BASE_NS + 0x8400UL) +#define DTS_BASE_NS (APB1PERIPH_BASE_NS + 0x8C00UL) +#define LPTIM2_BASE_NS (APB1PERIPH_BASE_NS + 0x9400UL) +#define FDCAN1_BASE_NS (APB1PERIPH_BASE_NS + 0xA400UL) +#define FDCAN_CONFIG_BASE_NS (APB1PERIPH_BASE_NS + 0xA500UL) +#define SRAMCAN_BASE_NS (APB1PERIPH_BASE_NS + 0xAC00UL) +#define FDCAN2_BASE_NS (APB1PERIPH_BASE_NS + 0xA800UL) +#define UCPD1_BASE_NS (APB1PERIPH_BASE_NS + 0xDC00UL) + +/*!< APB2 Non secure peripherals */ +#define TIM1_BASE_NS (APB2PERIPH_BASE_NS + 0x2C00UL) +#define SPI1_BASE_NS (APB2PERIPH_BASE_NS + 0x3000UL) +#define TIM8_BASE_NS (APB2PERIPH_BASE_NS + 0x3400UL) +#define USART1_BASE_NS (APB2PERIPH_BASE_NS + 0x3800UL) +#define TIM15_BASE_NS (APB2PERIPH_BASE_NS + 0x4000UL) +#define TIM16_BASE_NS (APB2PERIPH_BASE_NS + 0x4400UL) +#define TIM17_BASE_NS (APB2PERIPH_BASE_NS + 0x4800UL) +#define SPI4_BASE_NS (APB2PERIPH_BASE_NS + 0x4C00UL) +#define SPI6_BASE_NS (APB2PERIPH_BASE_NS + 0x5000UL) +#define SAI1_BASE_NS (APB2PERIPH_BASE_NS + 0x5400UL) +#define SAI1_Block_A_BASE_NS (SAI1_BASE_NS + 0x004UL) +#define SAI1_Block_B_BASE_NS (SAI1_BASE_NS + 0x024UL) +#define SAI2_BASE_NS (APB2PERIPH_BASE_NS + 0x5800UL) +#define SAI2_Block_A_BASE_NS (SAI2_BASE_NS + 0x004UL) +#define SAI2_Block_B_BASE_NS (SAI2_BASE_NS + 0x024UL) +#define USB_DRD_BASE_NS (APB2PERIPH_BASE_NS + 0x6000UL) +#define USB_DRD_PMAADDR_NS (APB2PERIPH_BASE_NS + 0x6400UL) + +/*!< AHB1 Non secure peripherals */ +#define GPDMA1_BASE_NS AHB1PERIPH_BASE_NS +#define GPDMA2_BASE_NS (AHB1PERIPH_BASE_NS + 0x01000UL) +#define FLASH_R_BASE_NS (AHB1PERIPH_BASE_NS + 0x02000UL) +#define CRC_BASE_NS (AHB1PERIPH_BASE_NS + 0x03000UL) +#define CORDIC_BASE_NS (AHB1PERIPH_BASE_NS + 0x03800UL) +#define FMAC_BASE_NS (AHB1PERIPH_BASE_NS + 0x03C00UL) +#define RAMCFG_BASE_NS (AHB1PERIPH_BASE_NS + 0x06000UL) +#define ETH_BASE_NS (AHB1PERIPH_BASE_NS + 0x8000UL) +#define ETH_MAC_BASE_NS (ETH_BASE) +#define ICACHE_BASE_NS (AHB1PERIPH_BASE_NS + 0x10400UL) +#define DCACHE1_BASE_NS (AHB1PERIPH_BASE_NS + 0x11400UL) +#define GTZC_TZSC1_BASE_NS (AHB1PERIPH_BASE_NS + 0x12400UL) +#define GTZC_TZIC1_BASE_NS (AHB1PERIPH_BASE_NS + 0x12800UL) +#define GTZC_MPCBB1_BASE_NS (AHB1PERIPH_BASE_NS + 0x12C00UL) +#define GTZC_MPCBB2_BASE_NS (AHB1PERIPH_BASE_NS + 0x13000UL) +#define GTZC_MPCBB3_BASE_NS (AHB1PERIPH_BASE_NS + 0x13400UL) +#define BKPSRAM_BASE_NS (AHB1PERIPH_BASE_NS + 0x16400UL) + +#define GPDMA1_Channel0_BASE_NS (GPDMA1_BASE_NS + 0x0050UL) +#define GPDMA1_Channel1_BASE_NS (GPDMA1_BASE_NS + 0x00D0UL) +#define GPDMA1_Channel2_BASE_NS (GPDMA1_BASE_NS + 0x0150UL) +#define GPDMA1_Channel3_BASE_NS (GPDMA1_BASE_NS + 0x01D0UL) +#define GPDMA1_Channel4_BASE_NS (GPDMA1_BASE_NS + 0x0250UL) +#define GPDMA1_Channel5_BASE_NS (GPDMA1_BASE_NS + 0x02D0UL) +#define GPDMA1_Channel6_BASE_NS (GPDMA1_BASE_NS + 0x0350UL) +#define GPDMA1_Channel7_BASE_NS (GPDMA1_BASE_NS + 0x03D0UL) +#define GPDMA2_Channel0_BASE_NS (GPDMA2_BASE_NS + 0x0050UL) +#define GPDMA2_Channel1_BASE_NS (GPDMA2_BASE_NS + 0x00D0UL) +#define GPDMA2_Channel2_BASE_NS (GPDMA2_BASE_NS + 0x0150UL) +#define GPDMA2_Channel3_BASE_NS (GPDMA2_BASE_NS + 0x01D0UL) +#define GPDMA2_Channel4_BASE_NS (GPDMA2_BASE_NS + 0x0250UL) +#define GPDMA2_Channel5_BASE_NS (GPDMA2_BASE_NS + 0x02D0UL) +#define GPDMA2_Channel6_BASE_NS (GPDMA2_BASE_NS + 0x0350UL) +#define GPDMA2_Channel7_BASE_NS (GPDMA2_BASE_NS + 0x03D0UL) + +#define RAMCFG_SRAM1_BASE_NS (RAMCFG_BASE_NS) +#define RAMCFG_SRAM2_BASE_NS (RAMCFG_BASE_NS + 0x0040UL) +#define RAMCFG_SRAM3_BASE_NS (RAMCFG_BASE_NS + 0x0080UL) +#define RAMCFG_BKPRAM_BASE_NS (RAMCFG_BASE_NS + 0x0100UL) + +/*!< AHB2 Non secure peripherals */ +#define GPIOA_BASE_NS (AHB2PERIPH_BASE_NS + 0x00000UL) +#define GPIOB_BASE_NS (AHB2PERIPH_BASE_NS + 0x00400UL) +#define GPIOC_BASE_NS (AHB2PERIPH_BASE_NS + 0x00800UL) +#define GPIOD_BASE_NS (AHB2PERIPH_BASE_NS + 0x00C00UL) +#define GPIOE_BASE_NS (AHB2PERIPH_BASE_NS + 0x01000UL) +#define GPIOF_BASE_NS (AHB2PERIPH_BASE_NS + 0x01400UL) +#define GPIOG_BASE_NS (AHB2PERIPH_BASE_NS + 0x01800UL) +#define GPIOH_BASE_NS (AHB2PERIPH_BASE_NS + 0x01C00UL) +#define GPIOI_BASE_NS (AHB2PERIPH_BASE_NS + 0x02000UL) +#define ADC1_BASE_NS (AHB2PERIPH_BASE_NS + 0x08000UL) +#define ADC2_BASE_NS (AHB2PERIPH_BASE_NS + 0x08100UL) +#define ADC12_COMMON_BASE_NS (AHB2PERIPH_BASE_NS + 0x08300UL) +#define DAC1_BASE_NS (AHB2PERIPH_BASE_NS + 0x08400UL) +#define DCMI_BASE_NS (AHB2PERIPH_BASE_NS + 0x0C000UL) +#define PSSI_BASE_NS (AHB2PERIPH_BASE_NS + 0x0C400UL) + +#define AES_BASE_NS (AHB2PERIPH_BASE_NS + 0xA0000UL) +#define HASH_BASE_NS (AHB2PERIPH_BASE_NS + 0xA0400UL) +#define HASH_DIGEST_BASE_NS (AHB2PERIPH_BASE_NS + 0xA0710UL) +#define RNG_BASE_NS (AHB2PERIPH_BASE_NS + 0xA0800UL) +#define SAES_BASE_NS (AHB2PERIPH_BASE_NS + 0xA0C00UL) +#define PKA_BASE_NS (AHB2PERIPH_BASE_NS + 0xA2000UL) +#define PKA_RAM_BASE_NS (AHB2PERIPH_BASE_NS + 0xA2400UL) + + +/*!< APB3 Non secure peripherals */ +#define SBS_BASE_NS (APB3PERIPH_BASE_NS + 0x0400UL) +#define SPI5_BASE_NS (APB3PERIPH_BASE_NS + 0x2000UL) +#define LPUART1_BASE_NS (APB3PERIPH_BASE_NS + 0x2400UL) +#define I2C3_BASE_NS (APB3PERIPH_BASE_NS + 0x2800UL) +#define I2C4_BASE_NS (APB3PERIPH_BASE_NS + 0x2C00UL) +#define LPTIM1_BASE_NS (APB3PERIPH_BASE_NS + 0x4400UL) +#define LPTIM3_BASE_NS (APB3PERIPH_BASE_NS + 0x4800UL) +#define LPTIM4_BASE_NS (APB3PERIPH_BASE_NS + 0x4C00UL) +#define LPTIM5_BASE_NS (APB3PERIPH_BASE_NS + 0x5000UL) +#define LPTIM6_BASE_NS (APB3PERIPH_BASE_NS + 0x5400UL) +#define VREFBUF_BASE_NS (APB3PERIPH_BASE_NS + 0x7400UL) +#define RTC_BASE_NS (APB3PERIPH_BASE_NS + 0x7800UL) +#define TAMP_BASE_NS (APB3PERIPH_BASE_NS + 0x7C00UL) + +/*!< AHB3 Non secure peripherals */ +#define PWR_BASE_NS (AHB3PERIPH_BASE_NS + 0x0800UL) +#define RCC_BASE_NS (AHB3PERIPH_BASE_NS + 0x0C00UL) +#define EXTI_BASE_NS (AHB3PERIPH_BASE_NS + 0x2000UL) +#define DEBUG_BASE_NS (AHB3PERIPH_BASE_NS + 0x4000UL) +/*!< AHB4 Non secure peripherals */ +#define OTFDEC1_BASE_NS (AHB4PERIPH_BASE_NS + 0x5000UL) +#define OTFDEC1_REGION1_BASE_NS (OTFDEC1_BASE_NS + 0x20UL) +#define OTFDEC1_REGION2_BASE_NS (OTFDEC1_BASE_NS + 0x50UL) +#define OTFDEC1_REGION3_BASE_NS (OTFDEC1_BASE_NS + 0x80UL) +#define OTFDEC1_REGION4_BASE_NS (OTFDEC1_BASE_NS + 0xB0UL) +#define SDMMC1_BASE_NS (AHB4PERIPH_BASE_NS + 0x8000UL) +#define DLYB_SDMMC1_BASE_NS (AHB4PERIPH_BASE_NS + 0x8400UL) +#define SDMMC2_BASE_NS (AHB4PERIPH_BASE_NS + 0x8C00UL) +#define DLYB_SDMMC2_BASE_NS (AHB4PERIPH_BASE_NS + 0x8800UL) + +#define FMC_R_BASE_NS (AHB4PERIPH_BASE_NS + 0x1000400UL) /*!< FMC control registers base address */ +#define OCTOSPI1_R_BASE_NS (AHB4PERIPH_BASE_NS + 0x1001400UL) /*!< OCTOSPI1 control registers base address */ +#define DLYB_OCTOSPI1_BASE_NS (AHB4PERIPH_BASE_NS + 0x0F000UL) + +/*!< FMC Banks Non secure registers base address */ +#define FMC_Bank1_R_BASE_NS (FMC_R_BASE_NS + 0x0000UL) +#define FMC_Bank1E_R_BASE_NS (FMC_R_BASE_NS + 0x0104UL) +#define FMC_Bank3_R_BASE_NS (FMC_R_BASE_NS + 0x0080UL) +#define FMC_Bank5_6_R_BASE_NS (FMC_R_BASE_NS + 0x0140UL) + +/* Flash, Peripheral and internal SRAMs base addresses - Secure */ +#define FLASH_BASE_S (0x0C000000UL) /*!< FLASH (up to 2 MB) secure base address */ +#define SRAM1_BASE_S (0x30000000UL) /*!< SRAM1 (192 KB) secure base address */ +#define SRAM2_BASE_S (0x30040000UL) /*!< SRAM2 (64 KB) secure base address */ +#define SRAM3_BASE_S (0x30050000UL) /*!< SRAM3 (512 KB) secure base address */ +#define PERIPH_BASE_S (0x50000000UL) /*!< Peripheral secure base address */ + +/* Peripheral memory map - Secure */ +#define APB1PERIPH_BASE_S PERIPH_BASE_S +#define APB2PERIPH_BASE_S (PERIPH_BASE_S + 0x00010000UL) +#define AHB1PERIPH_BASE_S (PERIPH_BASE_S + 0x00020000UL) +#define AHB2PERIPH_BASE_S (PERIPH_BASE_S + 0x02020000UL) +#define APB3PERIPH_BASE_S (PERIPH_BASE_S + 0x04000000UL) +#define AHB3PERIPH_BASE_S (PERIPH_BASE_S + 0x04020000UL) +#define AHB4PERIPH_BASE_S (PERIPH_BASE_S + 0x06000000UL) + +/*!< APB1 secure peripherals */ +#define TIM2_BASE_S (APB1PERIPH_BASE_S + 0x0000UL) +#define TIM3_BASE_S (APB1PERIPH_BASE_S + 0x0400UL) +#define TIM4_BASE_S (APB1PERIPH_BASE_S + 0x0800UL) +#define TIM5_BASE_S (APB1PERIPH_BASE_S + 0x0C00UL) +#define TIM6_BASE_S (APB1PERIPH_BASE_S + 0x1000UL) +#define TIM7_BASE_S (APB1PERIPH_BASE_S + 0x1400UL) +#define TIM12_BASE_S (APB1PERIPH_BASE_S + 0x1800UL) +#define TIM13_BASE_S (APB1PERIPH_BASE_S + 0x1C00UL) +#define TIM14_BASE_S (APB1PERIPH_BASE_S + 0x2000UL) +#define WWDG_BASE_S (APB1PERIPH_BASE_S + 0x2C00UL) +#define IWDG_BASE_S (APB1PERIPH_BASE_S + 0x3000UL) +#define SPI2_BASE_S (APB1PERIPH_BASE_S + 0x3800UL) +#define SPI3_BASE_S (APB1PERIPH_BASE_S + 0x3C00UL) +#define USART2_BASE_S (APB1PERIPH_BASE_S + 0x4400UL) +#define USART3_BASE_S (APB1PERIPH_BASE_S + 0x4800UL) +#define UART4_BASE_S (APB1PERIPH_BASE_S + 0x4C00UL) +#define UART5_BASE_S (APB1PERIPH_BASE_S + 0x5000UL) +#define I2C1_BASE_S (APB1PERIPH_BASE_S + 0x5400UL) +#define I2C2_BASE_S (APB1PERIPH_BASE_S + 0x5800UL) +#define I3C1_BASE_S (APB1PERIPH_BASE_S + 0x5C00UL) +#define CRS_BASE_S (APB1PERIPH_BASE_S + 0x6000UL) +#define USART6_BASE_S (APB1PERIPH_BASE_S + 0x6400UL) +#define USART10_BASE_S (APB1PERIPH_BASE_S + 0x6800UL) +#define USART11_BASE_S (APB1PERIPH_BASE_S + 0x6C00UL) +#define CEC_BASE_S (APB1PERIPH_BASE_S + 0x7000UL) +#define UART7_BASE_S (APB1PERIPH_BASE_S + 0x7800UL) +#define UART8_BASE_S (APB1PERIPH_BASE_S + 0x7C00UL) +#define UART9_BASE_S (APB1PERIPH_BASE_S + 0x8000UL) +#define UART12_BASE_S (APB1PERIPH_BASE_S + 0x8400UL) +#define DTS_BASE_S (APB1PERIPH_BASE_S + 0x8C00UL) +#define LPTIM2_BASE_S (APB1PERIPH_BASE_S + 0x9400UL) +#define FDCAN1_BASE_S (APB1PERIPH_BASE_S + 0xA400UL) +#define FDCAN_CONFIG_BASE_S (APB1PERIPH_BASE_S + 0xA500UL) +#define SRAMCAN_BASE_S (APB1PERIPH_BASE_S + 0xAC00UL) +#define FDCAN2_BASE_S (APB1PERIPH_BASE_S + 0xA800UL) +#define UCPD1_BASE_S (APB1PERIPH_BASE_S + 0xDC00UL) + +/*!< APB2 Secure peripherals */ +#define TIM1_BASE_S (APB2PERIPH_BASE_S + 0x2C00UL) +#define SPI1_BASE_S (APB2PERIPH_BASE_S + 0x3000UL) +#define TIM8_BASE_S (APB2PERIPH_BASE_S + 0x3400UL) +#define USART1_BASE_S (APB2PERIPH_BASE_S + 0x3800UL) +#define TIM15_BASE_S (APB2PERIPH_BASE_S + 0x4000UL) +#define TIM16_BASE_S (APB2PERIPH_BASE_S + 0x4400UL) +#define TIM17_BASE_S (APB2PERIPH_BASE_S + 0x4800UL) +#define SPI4_BASE_S (APB2PERIPH_BASE_S + 0x4C00UL) +#define SPI6_BASE_S (APB2PERIPH_BASE_S + 0x5000UL) +#define SAI1_BASE_S (APB2PERIPH_BASE_S + 0x5400UL) +#define SAI1_Block_A_BASE_S (SAI1_BASE_S + 0x004UL) +#define SAI1_Block_B_BASE_S (SAI1_BASE_S + 0x024UL) +#define SAI2_BASE_S (APB2PERIPH_BASE_S + 0x5800UL) +#define SAI2_Block_A_BASE_S (SAI2_BASE_S + 0x004UL) +#define SAI2_Block_B_BASE_S (SAI2_BASE_S + 0x024UL) +#define USB_DRD_BASE_S (APB2PERIPH_BASE_S + 0x6000UL) +#define USB_DRD_PMAADDR_S (APB2PERIPH_BASE_S + 0x6400UL) + +/*!< AHB1 secure peripherals */ +#define GPDMA1_BASE_S AHB1PERIPH_BASE_S +#define GPDMA2_BASE_S (AHB1PERIPH_BASE_S + 0x01000UL) +#define FLASH_R_BASE_S (AHB1PERIPH_BASE_S + 0x02000UL) +#define CRC_BASE_S (AHB1PERIPH_BASE_S + 0x03000UL) +#define CORDIC_BASE_S (AHB1PERIPH_BASE_S + 0x03800UL) +#define FMAC_BASE_S (AHB1PERIPH_BASE_S + 0x03C00UL) +#define RAMCFG_BASE_S (AHB1PERIPH_BASE_S + 0x06000UL) +#define ETH_BASE_S (AHB1PERIPH_BASE_S + 0x8000UL) +#define ETH_MAC_BASE_S (ETH_BASE_S) +#define ICACHE_BASE_S (AHB1PERIPH_BASE_S + 0x10400UL) +#define DCACHE1_BASE_S (AHB1PERIPH_BASE_S + 0x11400UL) +#define GTZC_TZSC1_BASE_S (AHB1PERIPH_BASE_S + 0x12400UL) +#define GTZC_TZIC1_BASE_S (AHB1PERIPH_BASE_S + 0x12800UL) +#define GTZC_MPCBB1_BASE_S (AHB1PERIPH_BASE_S + 0x12C00UL) +#define GTZC_MPCBB2_BASE_S (AHB1PERIPH_BASE_S + 0x13000UL) +#define GTZC_MPCBB3_BASE_S (AHB1PERIPH_BASE_S + 0x13400UL) +#define BKPSRAM_BASE_S (AHB1PERIPH_BASE_S + 0x16400UL) + +#define GPDMA1_Channel0_BASE_S (GPDMA1_BASE_S + 0x0050UL) +#define GPDMA1_Channel1_BASE_S (GPDMA1_BASE_S + 0x00D0UL) +#define GPDMA1_Channel2_BASE_S (GPDMA1_BASE_S + 0x0150UL) +#define GPDMA1_Channel3_BASE_S (GPDMA1_BASE_S + 0x01D0UL) +#define GPDMA1_Channel4_BASE_S (GPDMA1_BASE_S + 0x0250UL) +#define GPDMA1_Channel5_BASE_S (GPDMA1_BASE_S + 0x02D0UL) +#define GPDMA1_Channel6_BASE_S (GPDMA1_BASE_S + 0x0350UL) +#define GPDMA1_Channel7_BASE_S (GPDMA1_BASE_S + 0x03D0UL) +#define GPDMA2_Channel0_BASE_S (GPDMA2_BASE_S + 0x0050UL) +#define GPDMA2_Channel1_BASE_S (GPDMA2_BASE_S + 0x00D0UL) +#define GPDMA2_Channel2_BASE_S (GPDMA2_BASE_S + 0x0150UL) +#define GPDMA2_Channel3_BASE_S (GPDMA2_BASE_S + 0x01D0UL) +#define GPDMA2_Channel4_BASE_S (GPDMA2_BASE_S + 0x0250UL) +#define GPDMA2_Channel5_BASE_S (GPDMA2_BASE_S + 0x02D0UL) +#define GPDMA2_Channel6_BASE_S (GPDMA2_BASE_S + 0x0350UL) +#define GPDMA2_Channel7_BASE_S (GPDMA2_BASE_S + 0x03D0UL) + +#define RAMCFG_SRAM1_BASE_S (RAMCFG_BASE_S) +#define RAMCFG_SRAM2_BASE_S (RAMCFG_BASE_S + 0x0040UL) +#define RAMCFG_SRAM3_BASE_S (RAMCFG_BASE_S + 0x0080UL) +#define RAMCFG_BKPRAM_BASE_S (RAMCFG_BASE_S + 0x0100UL) + +/*!< AHB2 secure peripherals */ +#define GPIOA_BASE_S (AHB2PERIPH_BASE_S + 0x00000UL) +#define GPIOB_BASE_S (AHB2PERIPH_BASE_S + 0x00400UL) +#define GPIOC_BASE_S (AHB2PERIPH_BASE_S + 0x00800UL) +#define GPIOD_BASE_S (AHB2PERIPH_BASE_S + 0x00C00UL) +#define GPIOE_BASE_S (AHB2PERIPH_BASE_S + 0x01000UL) +#define GPIOF_BASE_S (AHB2PERIPH_BASE_S + 0x01400UL) +#define GPIOG_BASE_S (AHB2PERIPH_BASE_S + 0x01800UL) +#define GPIOH_BASE_S (AHB2PERIPH_BASE_S + 0x01C00UL) +#define GPIOI_BASE_S (AHB2PERIPH_BASE_S + 0x02000UL) +#define ADC1_BASE_S (AHB2PERIPH_BASE_S + 0x08000UL) +#define ADC2_BASE_S (AHB2PERIPH_BASE_S + 0x08100UL) +#define ADC12_COMMON_BASE_S (AHB2PERIPH_BASE_S + 0x08300UL) +#define DAC1_BASE_S (AHB2PERIPH_BASE_S + 0x08400UL) +#define DCMI_BASE_S (AHB2PERIPH_BASE_S + 0x0C000UL) +#define PSSI_BASE_S (AHB2PERIPH_BASE_S + 0x0C400UL) +#define AES_BASE_S (AHB2PERIPH_BASE_S + 0xA0000UL) +#define HASH_BASE_S (AHB2PERIPH_BASE_S + 0xA0400UL) +#define HASH_DIGEST_BASE_S (AHB2PERIPH_BASE_S + 0xA0710UL) +#define RNG_BASE_S (AHB2PERIPH_BASE_S + 0xA0800UL) +#define SAES_BASE_S (AHB2PERIPH_BASE_S + 0xA0C00UL) +#define PKA_BASE_S (AHB2PERIPH_BASE_S + 0xA2000UL) +#define PKA_RAM_BASE_S (AHB2PERIPH_BASE_S + 0xA2400UL) + +/*!< APB3 secure peripherals */ +#define SBS_BASE_S (APB3PERIPH_BASE_S + 0x0400UL) +#define SPI5_BASE_S (APB3PERIPH_BASE_S + 0x2000UL) +#define LPUART1_BASE_S (APB3PERIPH_BASE_S + 0x2400UL) +#define I2C3_BASE_S (APB3PERIPH_BASE_S + 0x2800UL) +#define I2C4_BASE_S (APB3PERIPH_BASE_S + 0x2C00UL) +#define LPTIM1_BASE_S (APB3PERIPH_BASE_S + 0x4400UL) +#define LPTIM3_BASE_S (APB3PERIPH_BASE_S + 0x4800UL) +#define LPTIM4_BASE_S (APB3PERIPH_BASE_S + 0x4C00UL) +#define LPTIM5_BASE_S (APB3PERIPH_BASE_S + 0x5000UL) +#define LPTIM6_BASE_S (APB3PERIPH_BASE_S + 0x5400UL) +#define VREFBUF_BASE_S (APB3PERIPH_BASE_S + 0x7400UL) +#define RTC_BASE_S (APB3PERIPH_BASE_S + 0x7800UL) +#define TAMP_BASE_S (APB3PERIPH_BASE_S + 0x7C00UL) + +/*!< AHB3 secure peripherals */ +#define PWR_BASE_S (AHB3PERIPH_BASE_S + 0x0800UL) +#define RCC_BASE_S (AHB3PERIPH_BASE_S + 0x0C00UL) +#define EXTI_BASE_S (AHB3PERIPH_BASE_S + 0x2000UL) +#define DEBUG_BASE_S (AHB3PERIPH_BASE_S + 0x4000UL) + +/*!< AHB4 secure peripherals */ +#define OTFDEC1_BASE_S (AHB4PERIPH_BASE_S + 0x5000UL) +#define OTFDEC1_REGION1_BASE_S (OTFDEC1_BASE_S + 0x20UL) +#define OTFDEC1_REGION2_BASE_S (OTFDEC1_BASE_S + 0x50UL) +#define OTFDEC1_REGION3_BASE_S (OTFDEC1_BASE_S + 0x80UL) +#define OTFDEC1_REGION4_BASE_S (OTFDEC1_BASE_S + 0xB0UL) +#define SDMMC1_BASE_S (AHB4PERIPH_BASE_S + 0x8000UL) +#define DLYB_SDMMC1_BASE_S (AHB4PERIPH_BASE_S + 0x8400UL) +#define SDMMC2_BASE_S (AHB4PERIPH_BASE_S + 0x8C00UL) +#define DLYB_SDMMC2_BASE_S (AHB4PERIPH_BASE_S + 0x8800UL) + +#define FMC_R_BASE_S (AHB4PERIPH_BASE_S + 0x1000400UL) /*!< FMC control registers base address */ +#define OCTOSPI1_R_BASE_S (AHB4PERIPH_BASE_S + 0x1001400UL) /*!< OCTOSPI1 control registers base address */ +#define DLYB_OCTOSPI1_BASE_S (AHB4PERIPH_BASE_S + 0x0F000UL) + +/*!< FMC Banks Non secure registers base address */ +#define FMC_Bank1_R_BASE_S (FMC_R_BASE_S + 0x0000UL) +#define FMC_Bank1E_R_BASE_S (FMC_R_BASE_S + 0x0104UL) +#define FMC_Bank3_R_BASE_S (FMC_R_BASE_S + 0x0080UL) +#define FMC_Bank5_6_R_BASE_S (FMC_R_BASE_S + 0x0140UL) + +/* Debug MCU registers base address */ +#define DBGMCU_BASE (0x44024000UL) + +#define PACKAGE_BASE (0x08FFF80EUL) /*!< Package data register base address */ +#define UID_BASE (0x08FFF800UL) /*!< Unique device ID register base address */ +#define FLASHSIZE_BASE (0x08FFF80CUL) /*!< Flash size data register base address */ + + +/* Internal Flash OTP Area */ +#define FLASH_OTP_BASE (0x08FFF000UL) /*!< FLASH OTP (one-time programmable) base address */ +#define FLASH_OTP_SIZE (0x800U) /*!< 2048 bytes OTP (one-time programmable) */ + +/* Flash system Area */ +#define FLASH_SYSTEM_BASE_NS (0x0BF80000UL) /*!< FLASH System non-secure base address */ +#define FLASH_SYSTEM_BASE_S (0x0FF80000UL) /*!< FLASH System secure base address */ +#define FLASH_SYSTEM_SIZE (0x10000U) /*!< 64 Kbytes system Flash */ + +/* Internal Flash EDATA Area */ +#define FLASH_EDATA_BASE_NS (0x09000000UL) /*!< FLASH high-cycle data non-secure base address */ +#define FLASH_EDATA_BASE_S (0x0D000000UL) /*!< FLASH high-cycle data secure base address */ +#define FLASH_EDATA_SIZE (0x18000U) /*!< 96 KB of Flash high-cycle data */ + +/* Internal Flash OBK Area */ +#define FLASH_OBK_BASE_NS (0x0BFD0000UL) /*!< FLASH OBK (option byte keys) non-secure base address */ +#define FLASH_OBK_BASE_S (0x0FFD0000UL) /*!< FLASH OBK (option byte keys) secure base address */ +#define FLASH_OBK_SIZE (0x2000U) /*!< 8 KB of option byte keys */ +#define FLASH_OBK_HDPL0_SIZE (0x100U) /*!< 256 Bytes of HDPL1 option byte keys */ + +#define FLASH_OBK_HDPL1_BASE_NS (FLASH_OBK_BASE_NS + FLASH_OBK_HDPL0_SIZE) /*!< FLASH OBK HDPL1 non-secure base address */ +#define FLASH_OBK_HDPL1_BASE_S (FLASH_OBK_BASE_S + FLASH_OBK_HDPL0_SIZE) /*!< FLASH OBK HDPL1 secure base address */ +#define FLASH_OBK_HDPL1_SIZE (0x800U) /*!< 2 KB of HDPL1 option byte keys */ + +#define FLASH_OBK_HDPL2_BASE_NS (FLASH_OBK_HDPL1_BASE_NS + FLASH_OBK_HDPL1_SIZE) /*!< FLASH OBK HDPL2 non-secure base address */ +#define FLASH_OBK_HDPL2_BASE_S (FLASH_OBK_HDPL1_BASE_S + FLASH_OBK_HDPL1_SIZE) /*!< FLASH OBK HDPL2 secure base address */ +#define FLASH_OBK_HDPL2_SIZE (0x300U) /*!< 768 Bytes of HDPL2 option byte keys */ + +#define FLASH_OBK_HDPL3_BASE_NS (FLASH_OBK_HDPL2_BASE_NS + FLASH_OBK_HDPL2_SIZE) /*!< FLASH OBK HDPL3 non-secure base address */ +#define FLASH_OBK_HDPL3_BASE_S (FLASH_OBK_HDPL2_BASE_S + FLASH_OBK_HDPL2_SIZE) /*!< FLASH OBK HDPL3 secure base address */ +#define FLASH_OBK_HDPL3_SIZE (0x13F0U) /*!< 5104 Bytes HDPL3 option byte keys */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define FLASH_OBK_HDPL3S_BASE_NS (FLASH_OBK_HDPL3_BASE_NS) /*!< FLASH OBK HDPL3 non-secure base address */ +#define FLASH_OBK_HDPL3S_BASE_S (FLASH_OBK_HDPL3_BASE_S) /*!< FLASH OBK HDPL3 secure base address */ +#define FLASH_OBK_HDPL3S_SIZE (0x0C00U) /*!< 3072 Bytes of secure HDPL3 option byte keys */ + +#define FLASH_OBK_HDPL3NS_BASE_NS (FLASH_OBK_HDPL3_BASE_NS + FLASH_OBK_HDPL3S_SIZE) /*!< FLASH OBK HDPL3 non-secure base address */ +#define FLASH_OBK_HDPL3NS_BASE_S (FLASH_OBK_HDPL3_BASE_S + FLASH_OBK_HDPL3S_SIZE) /*!< FLASH OBK HDPL3 secure base address */ +#define FLASH_OBK_HDPL3NS_SIZE (FLASH_OBK_HDPL3_SIZE - FLASH_OBK_HDPL3S_SIZE) /*!< 2032 Bytes of non-secure HDPL3 option byte keys */ +#endif /* CMSE */ + +/*!< USB PMA SIZE */ +#define USB_DRD_PMA_SIZE (2048U) /*!< USB PMA Size 2Kbyte */ + +/*!< Root Secure Service Library */ +/************ RSSLIB SAU system Flash region definition constants *************/ +#define RSSLIB_SYS_FLASH_NS_PFUNC_START (0xBF9FB68UL) +#define RSSLIB_SYS_FLASH_NS_PFUNC_END (0xBF9FB84UL) + +/************ RSSLIB function return constants ********************************/ +#define RSSLIB_ERROR (0xF5F5F5F5UL) +#define RSSLIB_SUCCESS (0xEAEAEAEAUL) + +/*!< RSSLIB pointer function structure address definition */ +#define RSSLIB_PFUNC_BASE (0xBF9FB68UL) +#define RSSLIB_PFUNC ((RSSLIB_pFunc_TypeDef *)RSSLIB_PFUNC_BASE) + +/** + * @brief Prototype of RSSLIB Jump to HDP level2 Function + * @detail This function increments HDP level up to HDP level 2 + * Then it enables the MPU region corresponding the MPU index + * provided as input parameter. The Vector Table shall be located + * within this MPU region. + * Then it jumps to the reset handler present within the + * Vector table. The function does not return on successful execution. + * @param pointer on the vector table containing the reset handler the function + * jumps to. + * @param MPU region index containing the vector table + * jumps to. + * @retval RSSLIB_RSS_ERROR on error on input parameter, otherwise does not return. + */ +typedef uint32_t (*RSSLIB_S_JumpHDPlvl2_TypeDef)(uint32_t VectorTableAddr, uint32_t MPUIndex); + +/** + * @brief Prototype of RSSLIB Jump to HDP level3 Function + * @detail This function increments HDP level up to HDP level 3 + * Then it enables the MPU region corresponding the MPU index + * provided as input parameter. The Vector Table shall be located + * within this MPU region. + * Then it jumps to the reset handler present within the + * Vector table. The function does not return on successful execution. + * @param pointer on the vector table containing the reset handler the function + * jumps to. + * @param MPU region index containing the vector table + * jumps to. + * @retval RSSLIB_RSS_ERROR on error on input parameter, otherwise does not return. + */ +typedef uint32_t (*RSSLIB_S_JumpHDPlvl3_TypeDef)(uint32_t VectorTableAddr, uint32_t MPUIndex); + +/** + * @brief Prototype of RSSLIB Jump to HDP level3 Function + * @detail This function increments HDP level up to HDP level 3 + * Then it jumps to the non-secure reset handler present within the + * Vector table. The function does not return on successful execution. + * @param pointer on the vector table containing the reset handler the function + * jumps to. + * @retval RSSLIB_RSS_ERROR on error on input parameter, otherwise does not return. + */ +typedef uint32_t (*RSSLIB_S_JumpHDPlvl3NS_TypeDef)(uint32_t VectorTableAddr); + +/** + * @brief Input parameter definition of RSSLIB_DataProvisioning + */ +typedef struct +{ + uint32_t *pSource; /*!< Address of the Data to be provisioned, shall be in SRAM3 */ + uint32_t *pDestination; /*!< Address in OBKeys sections where to provision Data */ + uint32_t Size; /*!< Size in bytes of the Data to be provisioned*/ + uint32_t DoEncryption; /*!< Notifies RSSLIB_DataProvisioning to encrypt or not Data*/ + uint32_t Crc; /*!< CRC over full Data buffer and previous field in the structure*/ +} RSSLIB_DataProvisioningConf_t; + +/** + * @brief Prototype of RSSLIB Data Provisioning Function + * @detail This function write Data within OBKeys sections. + * @param pointer on the structure defining Data to be provisioned and where to + * provision them within OBKeys sections. + * @retval RSSLIB_RSS_ERROR on error on input parameter, otherwise does not return. + */ +typedef uint32_t (*RSSLIB_NSC_DataProvisioning_TypeDef)(RSSLIB_DataProvisioningConf_t *pConfig); + + +/** + * @brief RSSLib secure callable function pointer structure + */ +typedef struct +{ + __IM RSSLIB_S_JumpHDPlvl2_TypeDef JumpHDPLvl2; + __IM RSSLIB_S_JumpHDPlvl3_TypeDef JumpHDPLvl3; + __IM RSSLIB_S_JumpHDPlvl3NS_TypeDef JumpHDPLvl3NS; +} S_pFuncTypeDef; + +/** + * @brief RSSLib Non-secure callable function pointer structure + */ +typedef struct +{ + __IM RSSLIB_NSC_DataProvisioning_TypeDef DataProvisioning; +} NSC_pFuncTypeDef; + +/** + * @brief RSSLib function pointer structure + */ +typedef struct +{ + NSC_pFuncTypeDef NSC; + uint32_t RESERVED1[3]; + S_pFuncTypeDef S; +}RSSLIB_pFunc_TypeDef; + +/*!< Non Secure Service Library */ +/************ RSSLIB SAU system Flash region definition constants *************/ +#define NSSLIB_SYS_FLASH_NS_PFUNC_START (0xBF9FB6CUL) +#define NSSLIB_SYS_FLASH_NS_PFUNC_END (0xBF9FB74UL) + +/************ RSSLIB function return constants ********************************/ +#define NSSLIB_ERROR (0xF5F5F5F5UL) +#define NSSLIB_SUCCESS (0xEAEAEAEAUL) + +/*!< RSSLIB pointer function structure address definition */ +#define NSSLIB_PFUNC_BASE (0xBF9FB6CUL) +#define NSSLIB_PFUNC ((NSSLIB_pFunc_TypeDef *)NSSLIB_PFUNC_BASE) + +/** + * @brief Prototype of RSSLIB Jump to HDP level2 Function + * @detail This function increments HDP level up to HDP level 2 + * Then it enables the MPU region corresponding the MPU index + * provided as input parameter. The Vector Table shall be located + * within this MPU region. + * Then it jumps to the reset handler present within the + * Vector table. The function does not return on successful execution. + * @param pointer on the vector table containing the reset handler the function + * jumps to. + * @param MPU region index containing the vector table + * jumps to. + * @retval NSSLIB_RSS_ERROR on error on input parameter, otherwise does not return. + */ +typedef uint32_t (*NSSLIB_S_JumpHDPlvl2_TypeDef)(uint32_t VectorTableAddr, uint32_t MPUIndex); + +/** + * @brief Prototype of RSSLIB Jump to HDP level3 Function + * @detail This function increments HDP level up to HDP level 3 + * Then it enables the MPU region corresponding the MPU index + * provided as input parameter. The Vector Table shall be located + * within this MPU region. + * Then it jumps to the reset handler present within the + * Vector table. The function does not return on successful execution. + * @param pointer on the vector table containing the reset handler the function + * jumps to. + * @param MPU region index containing the vector table + * jumps to. + * @retval NSSLIB_RSS_ERROR on error on input parameter, otherwise does not return. + */ +typedef uint32_t (*NSSLIB_S_JumpHDPlvl3_TypeDef)(uint32_t VectorTableAddr, uint32_t MPUIndex); + +/** + * @brief RSSLib secure callable function pointer structure + */ +typedef struct +{ + __IM NSSLIB_S_JumpHDPlvl2_TypeDef JumpHDPLvl2; + __IM NSSLIB_S_JumpHDPlvl3_TypeDef JumpHDPLvl3; +} NSSLIB_pFunc_TypeDef; + +/* + * Certificate address description + */ +#define CERT_CHIP_PACK1_ADDR (0x0BF9FE00U) +#define CERT_CHIP_PACK1_SIZE (0x200U) +#define CERT_CHIP_PACK2_ADDR (0x0BF9FC00U) +#define CERT_CHIP_PACK2_SIZE (0x200U) + +#define CERT_CHIP_PACK_ADDR (CERT_CHIP_PACK2_ADDR) +#define CERT_CHIP_PACK_SIZE (CERT_CHIP_PACK1_SIZE + CERT_CHIP_PACK2_SIZE) + +#define CERT_ST_DUA_INIT_ATTEST_PUB_KEY_OFFSET (152U) +#define CERT_ST_DUA_INIT_ATTEST_PUB_KEY_ADDR (CERT_CHIP_PACK1_ADDR + CERT_ST_DUA_INIT_ATTEST_PUB_KEY_OFFSET) +#define CERT_ST_DUA_INIT_ATTEST_SIGN_OFFSET (216U) +#define CERT_ST_DUA_INIT_ATTEST_SIGN_ADDR (CERT_CHIP_PACK1_ADDR + CERT_ST_DUA_INIT_ATTEST_SIGN_OFFSET) +#define CERT_ST_DUA_INIT_ATTEST_SERIAL_OFFSET (484U) +#define CERT_ST_DUA_INIT_ATTEST_SERIAL_ADDR (CERT_CHIP_PACK1_ADDR + CERT_ST_DUA_INIT_ATTEST_SERIAL_OFFSET) + +#define CERT_ST_DUA_USER_PUB_KEY_OFFSET (12U) +#define CERT_ST_DUA_USER_PUB_KEY_ADDR (CERT_CHIP_PACK2_ADDR + CERT_ST_DUA_USER_PUB_KEY_OFFSET) +#define CERT_ST_DUA_USER_SIGN_OFFSET (76U) +#define CERT_ST_DUA_USER_SIGN_ADDR (CERT_CHIP_PACK2_ADDR + CERT_ST_DUA_USER_SIGN_OFFSET) +#define CERT_ST_DUA_USER_SERIAL_OFFSET (140U) +#define CERT_ST_DUA_USER_SERIAL_ADDR (CERT_CHIP_PACK2_ADDR + CERT_ST_DUA_USER_SERIAL_OFFSET) + +/** @} */ /* End of group STM32H5xx_Peripheral_peripheralAddr */ + + +/* =========================================================================================================================== */ +/* ================ Peripheral declaration ================ */ +/* =========================================================================================================================== */ + + +/** @addtogroup STM32H5xx_Peripheral_declaration + * @{ + */ + +/*!< APB1 Non secure peripherals */ +#define TIM2_NS ((TIM_TypeDef *)TIM2_BASE_NS) +#define TIM3_NS ((TIM_TypeDef *)TIM3_BASE_NS) +#define TIM4_NS ((TIM_TypeDef *)TIM4_BASE_NS) +#define TIM5_NS ((TIM_TypeDef *)TIM5_BASE_NS) +#define TIM6_NS ((TIM_TypeDef *)TIM6_BASE_NS) +#define TIM7_NS ((TIM_TypeDef *)TIM7_BASE_NS) +#define TIM12_NS ((TIM_TypeDef *)TIM12_BASE_NS) +#define TIM13_NS ((TIM_TypeDef *)TIM13_BASE_NS) +#define TIM14_NS ((TIM_TypeDef *)TIM14_BASE_NS) +#define WWDG_NS ((WWDG_TypeDef *)WWDG_BASE_NS) +#define IWDG_NS ((IWDG_TypeDef *)IWDG_BASE_NS) +#define SPI2_NS ((SPI_TypeDef *)SPI2_BASE_NS) +#define SPI3_NS ((SPI_TypeDef *)SPI3_BASE_NS) +#define USART2_NS ((USART_TypeDef *)USART2_BASE_NS) +#define USART3_NS ((USART_TypeDef *)USART3_BASE_NS) +#define UART4_NS ((USART_TypeDef *)UART4_BASE_NS) +#define UART5_NS ((USART_TypeDef *)UART5_BASE_NS) +#define I2C1_NS ((I2C_TypeDef *)I2C1_BASE_NS) +#define I2C2_NS ((I2C_TypeDef *)I2C2_BASE_NS) +#define I3C1_NS ((I3C_TypeDef *)I3C1_BASE_NS) +#define CRS_NS ((CRS_TypeDef *)CRS_BASE_NS) +#define USART6_NS ((USART_TypeDef *)USART6_BASE_NS) +#define USART10_NS ((USART_TypeDef *)USART10_BASE_NS) +#define USART11_NS ((USART_TypeDef *)USART11_BASE_NS) +#define CEC_NS ((CEC_TypeDef *)CEC_BASE_NS) +#define UART7_NS ((USART_TypeDef *)UART7_BASE_NS) +#define UART8_NS ((USART_TypeDef *)UART8_BASE_NS) +#define UART9_NS ((USART_TypeDef *)UART9_BASE_NS) +#define UART12_NS ((USART_TypeDef *)UART12_BASE_NS) +#define DTS_NS ((DTS_TypeDef *)DTS_BASE_NS) +#define LPTIM2_NS ((LPTIM_TypeDef *)LPTIM2_BASE_NS) +#define FDCAN1_NS ((FDCAN_GlobalTypeDef *)FDCAN1_BASE_NS) +#define FDCAN_CONFIG_NS ((FDCAN_Config_TypeDef *)FDCAN_CONFIG_BASE_NS) +#define FDCAN2_NS ((FDCAN_GlobalTypeDef *)FDCAN2_BASE_NS) +#define UCPD1_NS ((UCPD_TypeDef *)UCPD1_BASE_NS) + +/*!< APB2 Non secure peripherals */ +#define TIM1_NS ((TIM_TypeDef *) TIM1_BASE_NS) +#define SPI1_NS ((SPI_TypeDef *) SPI1_BASE_NS) +#define TIM8_NS ((TIM_TypeDef *) TIM8_BASE_NS) +#define USART1_NS ((USART_TypeDef *) USART1_BASE_NS) +#define TIM15_NS ((TIM_TypeDef *) TIM15_BASE_NS) +#define TIM16_NS ((TIM_TypeDef *) TIM16_BASE_NS) +#define TIM17_NS ((TIM_TypeDef *) TIM17_BASE_NS) +#define SPI4_NS ((SPI_TypeDef *) SPI4_BASE_NS) +#define SPI6_NS ((SPI_TypeDef *) SPI6_BASE_NS) +#define SAI1_NS ((SAI_TypeDef *) SAI1_BASE_NS) +#define SAI1_Block_A_NS ((SAI_Block_TypeDef *)SAI1_Block_A_BASE_NS) +#define SAI1_Block_B_NS ((SAI_Block_TypeDef *)SAI1_Block_B_BASE_NS) +#define SAI2_NS ((SAI_TypeDef *) SAI2_BASE_NS) +#define SAI2_Block_A_NS ((SAI_Block_TypeDef *)SAI2_Block_A_BASE_NS) +#define SAI2_Block_B_NS ((SAI_Block_TypeDef *)SAI2_Block_B_BASE_NS) +#define USB_DRD_FS_NS ((USB_DRD_TypeDef *) USB_DRD_BASE_NS) +#define USB_DRD_PMA_BUFF_NS ((USB_DRD_PMABuffDescTypeDef *) USB_DRD_PMAADDR_NS) + +/*!< AHB1 Non secure peripherals */ +#define GPDMA1_NS ((DMA_TypeDef *) GPDMA1_BASE_NS) +#define GPDMA2_NS ((DMA_TypeDef *) GPDMA2_BASE_NS) +#define FLASH_NS ((FLASH_TypeDef *) FLASH_R_BASE_NS) +#define CRC_NS ((CRC_TypeDef *) CRC_BASE_NS) +#define CORDIC_NS ((CORDIC_TypeDef *) CORDIC_BASE_NS) +#define FMAC_NS ((FMAC_TypeDef *) FMAC_BASE_NS) +#define RAMCFG_SRAM1_NS ((RAMCFG_TypeDef *) RAMCFG_SRAM1_BASE_NS) +#define RAMCFG_SRAM2_NS ((RAMCFG_TypeDef *) RAMCFG_SRAM2_BASE_NS) +#define RAMCFG_SRAM3_NS ((RAMCFG_TypeDef *) RAMCFG_SRAM3_BASE_NS) +#define RAMCFG_BKPRAM_NS ((RAMCFG_TypeDef *) RAMCFG_BKPRAM_BASE_NS) +#define ETH_NS ((ETH_TypeDef *) ETH_BASE_NS) +#define ETH_MAC_NS ((ETH_TypeDef *) ETH_MAC_BASE_NS) +#define ICACHE_NS ((ICACHE_TypeDef *) ICACHE_BASE_NS) +#define DCACHE1_NS ((DCACHE_TypeDef *) DCACHE1_BASE_NS) +#define GTZC_TZSC1_NS ((GTZC_TZSC_TypeDef *) GTZC_TZSC1_BASE_NS) +#define GTZC_TZIC1_NS ((GTZC_TZIC_TypeDef *) GTZC_TZIC1_BASE_NS) +#define GTZC_MPCBB1_NS ((GTZC_MPCBB_TypeDef *) GTZC_MPCBB1_BASE_NS) +#define GTZC_MPCBB2_NS ((GTZC_MPCBB_TypeDef *) GTZC_MPCBB2_BASE_NS) +#define GTZC_MPCBB3_NS ((GTZC_MPCBB_TypeDef *) GTZC_MPCBB3_BASE_NS) +#define GPDMA1_Channel0_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel0_BASE_NS) +#define GPDMA1_Channel1_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel1_BASE_NS) +#define GPDMA1_Channel2_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel2_BASE_NS) +#define GPDMA1_Channel3_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel3_BASE_NS) +#define GPDMA1_Channel4_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel4_BASE_NS) +#define GPDMA1_Channel5_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel5_BASE_NS) +#define GPDMA1_Channel6_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel6_BASE_NS) +#define GPDMA1_Channel7_NS ((DMA_Channel_TypeDef *) GPDMA1_Channel7_BASE_NS) +#define GPDMA2_Channel0_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel0_BASE_NS) +#define GPDMA2_Channel1_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel1_BASE_NS) +#define GPDMA2_Channel2_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel2_BASE_NS) +#define GPDMA2_Channel3_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel3_BASE_NS) +#define GPDMA2_Channel4_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel4_BASE_NS) +#define GPDMA2_Channel5_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel5_BASE_NS) +#define GPDMA2_Channel6_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel6_BASE_NS) +#define GPDMA2_Channel7_NS ((DMA_Channel_TypeDef *) GPDMA2_Channel7_BASE_NS) + +/*!< AHB2 Non secure peripherals */ +#define GPIOA_NS ((GPIO_TypeDef *) GPIOA_BASE_NS) +#define GPIOB_NS ((GPIO_TypeDef *) GPIOB_BASE_NS) +#define GPIOC_NS ((GPIO_TypeDef *) GPIOC_BASE_NS) +#define GPIOD_NS ((GPIO_TypeDef *) GPIOD_BASE_NS) +#define GPIOE_NS ((GPIO_TypeDef *) GPIOE_BASE_NS) +#define GPIOF_NS ((GPIO_TypeDef *) GPIOF_BASE_NS) +#define GPIOG_NS ((GPIO_TypeDef *) GPIOG_BASE_NS) +#define GPIOH_NS ((GPIO_TypeDef *) GPIOH_BASE_NS) +#define GPIOI_NS ((GPIO_TypeDef *) GPIOI_BASE_NS) +#define ADC1_NS ((ADC_TypeDef *) ADC1_BASE_NS) +#define ADC2_NS ((ADC_TypeDef *) ADC2_BASE_NS) +#define ADC12_COMMON_NS ((ADC_Common_TypeDef *) ADC12_COMMON_BASE_NS) +#define DAC1_NS ((DAC_TypeDef *) DAC1_BASE_NS) +#define DCMI_NS ((DCMI_TypeDef *) DCMI_BASE_NS) +#define PSSI_NS ((PSSI_TypeDef *) PSSI_BASE_NS) +#define HASH_NS ((HASH_TypeDef *) HASH_BASE_NS) +#define HASH_DIGEST_NS ((HASH_DIGEST_TypeDef *) HASH_DIGEST_BASE_NS) +#define AES_NS ((AES_TypeDef *) AES_BASE_NS) +#define RNG_NS ((RNG_TypeDef *) RNG_BASE_NS) +#define SAES_NS ((AES_TypeDef *) SAES_BASE_NS) +#define PKA_NS ((PKA_TypeDef *) PKA_BASE_NS) + + +/*!< APB3 Non secure peripherals */ +#define SBS_NS ((SBS_TypeDef *) SBS_BASE_NS) +#define SPI5_NS ((SPI_TypeDef *) SPI5_BASE_NS) +#define LPUART1_NS ((USART_TypeDef *) LPUART1_BASE_NS) +#define I2C3_NS ((I2C_TypeDef *) I2C3_BASE_NS) +#define I2C4_NS ((I2C_TypeDef *) I2C4_BASE_NS) +#define LPTIM1_NS ((LPTIM_TypeDef *) LPTIM1_BASE_NS) +#define LPTIM3_NS ((LPTIM_TypeDef *) LPTIM3_BASE_NS) +#define LPTIM4_NS ((LPTIM_TypeDef *) LPTIM4_BASE_NS) +#define LPTIM5_NS ((LPTIM_TypeDef *) LPTIM5_BASE_NS) +#define LPTIM6_NS ((LPTIM_TypeDef *) LPTIM6_BASE_NS) +#define VREFBUF_NS ((VREFBUF_TypeDef *) VREFBUF_BASE_NS) +#define RTC_NS ((RTC_TypeDef *) RTC_BASE_NS) +#define TAMP_NS ((TAMP_TypeDef *) TAMP_BASE_NS) + +/*!< AHB3 Non secure peripherals */ +#define PWR_NS ((PWR_TypeDef *) PWR_BASE_NS) +#define RCC_NS ((RCC_TypeDef *) RCC_BASE_NS) +#define EXTI_NS ((EXTI_TypeDef *) EXTI_BASE_NS) + +/*!< AHB4 Non secure peripherals */ +#define OTFDEC1_NS ((OTFDEC_TypeDef *) OTFDEC1_BASE_NS) +#define OTFDEC1_REGION1_NS ((OTFDEC_Region_TypeDef *) OTFDEC1_REGION1_BASE_NS) +#define OTFDEC1_REGION2_NS ((OTFDEC_Region_TypeDef *) OTFDEC1_REGION2_BASE_NS) +#define OTFDEC1_REGION3_NS ((OTFDEC_Region_TypeDef *) OTFDEC1_REGION3_BASE_NS) +#define OTFDEC1_REGION4_NS ((OTFDEC_Region_TypeDef *) OTFDEC1_REGION4_BASE_NS) +#define SDMMC1_NS ((SDMMC_TypeDef *) SDMMC1_BASE_NS) +#define DLYB_SDMMC1_NS ((DLYB_TypeDef *) DLYB_SDMMC1_BASE_NS) +#define SDMMC2_NS ((SDMMC_TypeDef *) SDMMC2_BASE_NS) +#define DLYB_SDMMC2_NS ((DLYB_TypeDef *) DLYB_SDMMC2_BASE_NS) + +#define OCTOSPI1_NS ((OCTOSPI_TypeDef *) OCTOSPI1_R_BASE_NS) +#define DLYB_OCTOSPI1_NS ((DLYB_TypeDef *) DLYB_OCTOSPI1_BASE_NS) + +/*!< FMC Banks Non secure registers base address */ +#define FMC_Bank1_R_NS ((FMC_Bank1_TypeDef *) FMC_Bank1_R_BASE_NS) +#define FMC_Bank1E_R_NS ((FMC_Bank1E_TypeDef *) FMC_Bank1E_R_BASE_NS) +#define FMC_Bank3_R_NS ((FMC_Bank3_TypeDef *) FMC_Bank3_R_BASE_NS) +#define FMC_Bank5_6_R_NS ((FMC_Bank5_6_TypeDef *) FMC_Bank5_6_R_BASE_NS) + +/*!< APB1 Secure peripherals */ +#define TIM2_S ((TIM_TypeDef *)TIM2_BASE_S) +#define TIM3_S ((TIM_TypeDef *)TIM3_BASE_S) +#define TIM4_S ((TIM_TypeDef *)TIM4_BASE_S) +#define TIM5_S ((TIM_TypeDef *)TIM5_BASE_S) +#define TIM6_S ((TIM_TypeDef *)TIM6_BASE_S) +#define TIM7_S ((TIM_TypeDef *)TIM7_BASE_S) +#define TIM12_S ((TIM_TypeDef *)TIM12_BASE_S) +#define TIM13_S ((TIM_TypeDef *)TIM13_BASE_S) +#define TIM14_S ((TIM_TypeDef *)TIM14_BASE_S) +#define WWDG_S ((WWDG_TypeDef *)WWDG_BASE_S) +#define IWDG_S ((IWDG_TypeDef *)IWDG_BASE_S) +#define SPI2_S ((SPI_TypeDef *)SPI2_BASE_S) +#define SPI3_S ((SPI_TypeDef *)SPI3_BASE_S) +#define USART2_S ((USART_TypeDef *)USART2_BASE_S) +#define USART3_S ((USART_TypeDef *)USART3_BASE_S) +#define UART4_S ((USART_TypeDef *)UART4_BASE_S) +#define UART5_S ((USART_TypeDef *)UART5_BASE_S) +#define I2C1_S ((I2C_TypeDef *)I2C1_BASE_S) +#define I2C2_S ((I2C_TypeDef *)I2C2_BASE_S) +#define I3C1_S ((I3C_TypeDef *)I3C1_BASE_S) +#define CRS_S ((CRS_TypeDef *)CRS_BASE_S) +#define USART6_S ((USART_TypeDef *)USART6_BASE_S) +#define USART10_S ((USART_TypeDef *)USART10_BASE_S) +#define USART11_S ((USART_TypeDef *)USART11_BASE_S) +#define CEC_S ((CEC_TypeDef *)CEC_BASE_S) +#define UART7_S ((USART_TypeDef *)UART7_BASE_S) +#define UART8_S ((USART_TypeDef *)UART8_BASE_S) +#define UART9_S ((USART_TypeDef *)UART9_BASE_S) +#define UART12_S ((USART_TypeDef *)UART12_BASE_S) +#define DTS_S ((DTS_TypeDef *)DTS_BASE_S) +#define LPTIM2_S ((LPTIM_TypeDef *)LPTIM2_BASE_S) +#define FDCAN1_S ((FDCAN_GlobalTypeDef *)FDCAN1_BASE_S) +#define FDCAN_CONFIG_S ((FDCAN_Config_TypeDef *)FDCAN_CONFIG_BASE_S) +#define FDCAN2_S ((FDCAN_GlobalTypeDef *)FDCAN2_BASE_S) +#define UCPD1_S ((UCPD_TypeDef *)UCPD1_BASE_S) + +/*!< APB2 secure peripherals */ +#define TIM1_S ((TIM_TypeDef *) TIM1_BASE_S) +#define SPI1_S ((SPI_TypeDef *) SPI1_BASE_S) +#define TIM8_S ((TIM_TypeDef *) TIM8_BASE_S) +#define USART1_S ((USART_TypeDef *) USART1_BASE_S) +#define TIM15_S ((TIM_TypeDef *) TIM15_BASE_S) +#define TIM16_S ((TIM_TypeDef *) TIM16_BASE_S) +#define TIM17_S ((TIM_TypeDef *) TIM17_BASE_S) +#define SPI4_S ((SPI_TypeDef *) SPI4_BASE_S) +#define SPI6_S ((SPI_TypeDef *) SPI6_BASE_S) +#define SAI1_S ((SAI_TypeDef *) SAI1_BASE_S) +#define SAI1_Block_A_S ((SAI_Block_TypeDef *)SAI1_Block_A_BASE_S) +#define SAI1_Block_B_S ((SAI_Block_TypeDef *)SAI1_Block_B_BASE_S) +#define SAI2_S ((SAI_TypeDef *) SAI2_BASE_S) +#define SAI2_Block_A_S ((SAI_Block_TypeDef *)SAI2_Block_A_BASE_S) +#define SAI2_Block_B_S ((SAI_Block_TypeDef *)SAI2_Block_B_BASE_S) +#define USB_DRD_FS_S ((USB_DRD_TypeDef *)USB_DRD_BASE_S) +#define USB_DRD_PMA_BUFF_S ((USB_DRD_PMABuffDescTypeDef *) USB_DRD_PMAADDR_S) + +/*!< AHB1 secure peripherals */ +#define GPDMA1_S ((DMA_TypeDef *) GPDMA1_BASE_S) +#define GPDMA2_S ((DMA_TypeDef *) GPDMA2_BASE_S) +#define FLASH_S ((FLASH_TypeDef *) FLASH_R_BASE_S) +#define CRC_S ((CRC_TypeDef *) CRC_BASE_S) +#define CORDIC_S ((CORDIC_TypeDef *) CORDIC_BASE_S) +#define FMAC_S ((FMAC_TypeDef *) FMAC_BASE_S) +#define RAMCFG_SRAM1_S ((RAMCFG_TypeDef *) RAMCFG_SRAM1_BASE_S) +#define RAMCFG_SRAM2_S ((RAMCFG_TypeDef *) RAMCFG_SRAM2_BASE_S) +#define RAMCFG_SRAM3_S ((RAMCFG_TypeDef *) RAMCFG_SRAM3_BASE_S) +#define RAMCFG_BKPRAM_S ((RAMCFG_TypeDef *) RAMCFG_BKPRAM_BASE_S) +#define ETH_S ((ETH_TypeDef *) ETH_BASE_S) +#define ETH_MAC_S ((ETH_TypeDef *) ETH_MAC_BASE_S) +#define ICACHE_S ((ICACHE_TypeDef *) ICACHE_BASE_S) +#define DCACHE1_S ((DCACHE_TypeDef *) DCACHE1_BASE_S) +#define GTZC_TZSC1_S ((GTZC_TZSC_TypeDef *) GTZC_TZSC1_BASE_S) +#define GTZC_TZIC1_S ((GTZC_TZIC_TypeDef *) GTZC_TZIC1_BASE_S) +#define GTZC_MPCBB1_S ((GTZC_MPCBB_TypeDef *) GTZC_MPCBB1_BASE_S) +#define GTZC_MPCBB2_S ((GTZC_MPCBB_TypeDef *) GTZC_MPCBB2_BASE_S) +#define GTZC_MPCBB3_S ((GTZC_MPCBB_TypeDef *) GTZC_MPCBB3_BASE_S) +#define GPDMA1_Channel0_S ((DMA_Channel_TypeDef *) GPDMA1_Channel0_BASE_S) +#define GPDMA1_Channel1_S ((DMA_Channel_TypeDef *) GPDMA1_Channel1_BASE_S) +#define GPDMA1_Channel2_S ((DMA_Channel_TypeDef *) GPDMA1_Channel2_BASE_S) +#define GPDMA1_Channel3_S ((DMA_Channel_TypeDef *) GPDMA1_Channel3_BASE_S) +#define GPDMA1_Channel4_S ((DMA_Channel_TypeDef *) GPDMA1_Channel4_BASE_S) +#define GPDMA1_Channel5_S ((DMA_Channel_TypeDef *) GPDMA1_Channel5_BASE_S) +#define GPDMA1_Channel6_S ((DMA_Channel_TypeDef *) GPDMA1_Channel6_BASE_S) +#define GPDMA1_Channel7_S ((DMA_Channel_TypeDef *) GPDMA1_Channel7_BASE_S) +#define GPDMA2_Channel0_S ((DMA_Channel_TypeDef *) GPDMA2_Channel0_BASE_S) +#define GPDMA2_Channel1_S ((DMA_Channel_TypeDef *) GPDMA2_Channel1_BASE_S) +#define GPDMA2_Channel2_S ((DMA_Channel_TypeDef *) GPDMA2_Channel2_BASE_S) +#define GPDMA2_Channel3_S ((DMA_Channel_TypeDef *) GPDMA2_Channel3_BASE_S) +#define GPDMA2_Channel4_S ((DMA_Channel_TypeDef *) GPDMA2_Channel4_BASE_S) +#define GPDMA2_Channel5_S ((DMA_Channel_TypeDef *) GPDMA2_Channel5_BASE_S) +#define GPDMA2_Channel6_S ((DMA_Channel_TypeDef *) GPDMA2_Channel6_BASE_S) +#define GPDMA2_Channel7_S ((DMA_Channel_TypeDef *) GPDMA2_Channel7_BASE_S) + + +/*!< AHB2 secure peripherals */ +#define GPIOA_S ((GPIO_TypeDef *) GPIOA_BASE_S) +#define GPIOB_S ((GPIO_TypeDef *) GPIOB_BASE_S) +#define GPIOC_S ((GPIO_TypeDef *) GPIOC_BASE_S) +#define GPIOD_S ((GPIO_TypeDef *) GPIOD_BASE_S) +#define GPIOE_S ((GPIO_TypeDef *) GPIOE_BASE_S) +#define GPIOF_S ((GPIO_TypeDef *) GPIOF_BASE_S) +#define GPIOG_S ((GPIO_TypeDef *) GPIOG_BASE_S) +#define GPIOH_S ((GPIO_TypeDef *) GPIOH_BASE_S) +#define GPIOI_S ((GPIO_TypeDef *) GPIOI_BASE_S) +#define ADC1_S ((ADC_TypeDef *) ADC1_BASE_S) +#define ADC2_S ((ADC_TypeDef *) ADC2_BASE_S) +#define ADC12_COMMON_S ((ADC_Common_TypeDef *) ADC12_COMMON_BASE_S) +#define DAC1_S ((DAC_TypeDef *) DAC1_BASE_S) +#define DCMI_S ((DCMI_TypeDef *) DCMI_BASE_S) +#define PSSI_S ((PSSI_TypeDef *) PSSI_BASE_S) +#define HASH_S ((HASH_TypeDef *) HASH_BASE_S) +#define HASH_DIGEST_S ((HASH_DIGEST_TypeDef *) HASH_DIGEST_BASE_S) +#define AES_S ((AES_TypeDef *) AES_BASE_S) +#define RNG_S ((RNG_TypeDef *) RNG_BASE_S) +#define SAES_S ((AES_TypeDef *) SAES_BASE_S) +#define PKA_S ((PKA_TypeDef *) PKA_BASE_S) + +/*!< APB3 secure peripherals */ +#define SBS_S ((SBS_TypeDef *) SBS_BASE_S) +#define SPI5_S ((SPI_TypeDef *) SPI5_BASE_S) +#define LPUART1_S ((USART_TypeDef *) LPUART1_BASE_S) +#define I2C3_S ((I2C_TypeDef *) I2C3_BASE_S) +#define I2C4_S ((I2C_TypeDef *) I2C4_BASE_S) +#define LPTIM1_S ((LPTIM_TypeDef *) LPTIM1_BASE_S) +#define LPTIM3_S ((LPTIM_TypeDef *) LPTIM3_BASE_S) +#define LPTIM4_S ((LPTIM_TypeDef *) LPTIM4_BASE_S) +#define LPTIM5_S ((LPTIM_TypeDef *) LPTIM5_BASE_S) +#define LPTIM6_S ((LPTIM_TypeDef *) LPTIM6_BASE_S) +#define VREFBUF_S ((VREFBUF_TypeDef *) VREFBUF_BASE_S) +#define RTC_S ((RTC_TypeDef *) RTC_BASE_S) +#define TAMP_S ((TAMP_TypeDef *) TAMP_BASE_S) + +/*!< AHB3 Secure peripherals */ +#define PWR_S ((PWR_TypeDef *) PWR_BASE_S) +#define RCC_S ((RCC_TypeDef *) RCC_BASE_S) +#define EXTI_S ((EXTI_TypeDef *) EXTI_BASE_S) + +/*!< AHB4 secure peripherals */ +#define OTFDEC1_S ((OTFDEC_TypeDef *) OTFDEC1_BASE_S) +#define OTFDEC1_REGION1_S ((OTFDEC_Region_TypeDef *) OTFDEC1_REGION1_BASE_S) +#define OTFDEC1_REGION2_S ((OTFDEC_Region_TypeDef *) OTFDEC1_REGION2_BASE_S) +#define OTFDEC1_REGION3_S ((OTFDEC_Region_TypeDef *) OTFDEC1_REGION3_BASE_S) +#define OTFDEC1_REGION4_S ((OTFDEC_Region_TypeDef *) OTFDEC1_REGION4_BASE_S) +#define SDMMC1_S ((SDMMC_TypeDef *) SDMMC1_BASE_S) +#define DLYB_SDMMC1_S ((DLYB_TypeDef *) DLYB_SDMMC1_BASE_S) +#define SDMMC2_S ((SDMMC_TypeDef *) SDMMC2_BASE_S) +#define DLYB_SDMMC2_S ((DLYB_TypeDef *) DLYB_SDMMC2_BASE_S) + +#define FMC_Bank1_R_S ((FMC_Bank1_TypeDef *) FMC_Bank1_R_BASE_S) +#define FMC_Bank1E_R_S ((FMC_Bank1E_TypeDef *) FMC_Bank1E_R_BASE_S) +#define FMC_Bank3_R_S ((FMC_Bank3_TypeDef *) FMC_Bank3_R_BASE_S) +#define FMC_Bank5_6_R_S ((FMC_Bank5_6_TypeDef *) FMC_Bank5_6_R_BASE_S) + +#define OCTOSPI1_S ((OCTOSPI_TypeDef *) OCTOSPI1_R_BASE_S) +#define DLYB_OCTOSPI1_S ((DLYB_TypeDef *) DLYB_OCTOSPI1_BASE_S) + +#define DBGMCU ((DBGMCU_TypeDef *) DBGMCU_BASE) + +/*!< Memory & Instance aliases and base addresses for Non-Secure/Secure peripherals */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/*!< Memory base addresses for Secure peripherals */ +#define FLASH_BASE FLASH_BASE_S +#define FLASH_OBK_BASE FLASH_OBK_BASE_S +#define FLASH_EDATA_BASE FLASH_EDATA_BASE_S +#define FLASH_SYSTEM_BASE FLASH_SYSTEM_BASE_S +#define SRAM1_BASE SRAM1_BASE_S +#define SRAM2_BASE SRAM2_BASE_S +#define SRAM3_BASE SRAM3_BASE_S +#define BKPSRAM_BASE BKPSRAM_BASE_S +#define PERIPH_BASE PERIPH_BASE_S +#define APB1PERIPH_BASE APB1PERIPH_BASE_S +#define APB2PERIPH_BASE APB2PERIPH_BASE_S +#define APB3PERIPH_BASE APB3PERIPH_BASE_S +#define AHB1PERIPH_BASE AHB1PERIPH_BASE_S +#define AHB2PERIPH_BASE AHB2PERIPH_BASE_S +#define AHB3PERIPH_BASE AHB3PERIPH_BASE_S +#define AHB4PERIPH_BASE AHB4PERIPH_BASE_S + +/*!< Instance aliases and base addresses for Secure peripherals */ +#define CORDIC CORDIC_S +#define CORDIC_BASE CORDIC_BASE_S + +#define RCC RCC_S +#define RCC_BASE RCC_BASE_S + +#define DCMI DCMI_S +#define DCMI_BASE DCMI_BASE_S + +#define PSSI PSSI_S +#define PSSI_BASE PSSI_BASE_S + +#define DTS DTS_S +#define DTS_BASE DTS_BASE_S + +#define FLASH FLASH_S +#define FLASH_R_BASE FLASH_R_BASE_S + +#define FMAC FMAC_S +#define FMAC_BASE FMAC_BASE_S + +#define GPDMA1 GPDMA1_S +#define GPDMA1_BASE GPDMA1_BASE_S + +#define GPDMA1_Channel0 GPDMA1_Channel0_S +#define GPDMA1_Channel0_BASE GPDMA1_Channel0_BASE_S + +#define GPDMA1_Channel1 GPDMA1_Channel1_S +#define GPDMA1_Channel1_BASE GPDMA1_Channel1_BASE_S + +#define GPDMA1_Channel2 GPDMA1_Channel2_S +#define GPDMA1_Channel2_BASE GPDMA1_Channel2_BASE_S + +#define GPDMA1_Channel3 GPDMA1_Channel3_S +#define GPDMA1_Channel3_BASE GPDMA1_Channel3_BASE_S + +#define GPDMA1_Channel4 GPDMA1_Channel4_S +#define GPDMA1_Channel4_BASE GPDMA1_Channel4_BASE_S + +#define GPDMA1_Channel5 GPDMA1_Channel5_S +#define GPDMA1_Channel5_BASE GPDMA1_Channel5_BASE_S + +#define GPDMA1_Channel6 GPDMA1_Channel6_S +#define GPDMA1_Channel6_BASE GPDMA1_Channel6_BASE_S + +#define GPDMA1_Channel7 GPDMA1_Channel7_S +#define GPDMA1_Channel7_BASE GPDMA1_Channel7_BASE_S + +#define GPDMA2 GPDMA2_S +#define GPDMA2_BASE GPDMA2_BASE_S + +#define GPDMA2_Channel0 GPDMA2_Channel0_S +#define GPDMA2_Channel0_BASE GPDMA2_Channel0_BASE_S + +#define GPDMA2_Channel1 GPDMA2_Channel1_S +#define GPDMA2_Channel1_BASE GPDMA2_Channel1_BASE_S + +#define GPDMA2_Channel2 GPDMA2_Channel2_S +#define GPDMA2_Channel2_BASE GPDMA2_Channel2_BASE_S + +#define GPDMA2_Channel3 GPDMA2_Channel3_S +#define GPDMA2_Channel3_BASE GPDMA2_Channel3_BASE_S + +#define GPDMA2_Channel4 GPDMA2_Channel4_S +#define GPDMA2_Channel4_BASE GPDMA2_Channel4_BASE_S + +#define GPDMA2_Channel5 GPDMA2_Channel5_S +#define GPDMA2_Channel5_BASE GPDMA2_Channel5_BASE_S + +#define GPDMA2_Channel6 GPDMA2_Channel6_S +#define GPDMA2_Channel6_BASE GPDMA2_Channel6_BASE_S + +#define GPDMA2_Channel7 GPDMA2_Channel7_S +#define GPDMA2_Channel7_BASE GPDMA2_Channel7_BASE_S + +#define GPIOA GPIOA_S +#define GPIOA_BASE GPIOA_BASE_S + +#define GPIOB GPIOB_S +#define GPIOB_BASE GPIOB_BASE_S + +#define GPIOC GPIOC_S +#define GPIOC_BASE GPIOC_BASE_S + +#define GPIOD GPIOD_S +#define GPIOD_BASE GPIOD_BASE_S + +#define GPIOE GPIOE_S +#define GPIOE_BASE GPIOE_BASE_S + +#define GPIOF GPIOF_S +#define GPIOF_BASE GPIOF_BASE_S + +#define GPIOG GPIOG_S +#define GPIOG_BASE GPIOG_BASE_S + +#define GPIOH GPIOH_S +#define GPIOH_BASE GPIOH_BASE_S + +#define GPIOI GPIOI_S +#define GPIOI_BASE GPIOI_BASE_S + +#define PWR PWR_S +#define PWR_BASE PWR_BASE_S + +#define RAMCFG_SRAM1 RAMCFG_SRAM1_S +#define RAMCFG_SRAM1_BASE RAMCFG_SRAM1_BASE_S + +#define RAMCFG_SRAM2 RAMCFG_SRAM2_S +#define RAMCFG_SRAM2_BASE RAMCFG_SRAM2_BASE_S + +#define RAMCFG_SRAM3 RAMCFG_SRAM3_S +#define RAMCFG_SRAM3_BASE RAMCFG_SRAM3_BASE_S + +#define RAMCFG_BKPRAM RAMCFG_BKPRAM_S +#define RAMCFG_BKPRAM_BASE RAMCFG_BKPRAM_BASE_S + +#define EXTI EXTI_S +#define EXTI_BASE EXTI_BASE_S + +#define ICACHE ICACHE_S +#define ICACHE_BASE ICACHE_BASE_S + +#define DCACHE1 DCACHE1_S +#define DCACHE1_BASE DCACHE1_BASE_S + +#define GTZC_TZSC1 GTZC_TZSC1_S +#define GTZC_TZSC1_BASE GTZC_TZSC1_BASE_S + +#define GTZC_TZIC1 GTZC_TZIC1_S +#define GTZC_TZIC1_BASE GTZC_TZIC1_BASE_S + +#define GTZC_MPCBB1 GTZC_MPCBB1_S +#define GTZC_MPCBB1_BASE GTZC_MPCBB1_BASE_S + +#define GTZC_MPCBB2 GTZC_MPCBB2_S +#define GTZC_MPCBB2_BASE GTZC_MPCBB2_BASE_S + +#define GTZC_MPCBB3 GTZC_MPCBB3_S +#define GTZC_MPCBB3_BASE GTZC_MPCBB3_BASE_S + +#define RTC RTC_S +#define RTC_BASE RTC_BASE_S + +#define TAMP TAMP_S +#define TAMP_BASE TAMP_BASE_S + +#define TIM1 TIM1_S +#define TIM1_BASE TIM1_BASE_S + +#define TIM2 TIM2_S +#define TIM2_BASE TIM2_BASE_S + +#define TIM3 TIM3_S +#define TIM3_BASE TIM3_BASE_S + +#define TIM4 TIM4_S +#define TIM4_BASE TIM4_BASE_S + +#define TIM5 TIM5_S +#define TIM5_BASE TIM5_BASE_S + +#define TIM6 TIM6_S +#define TIM6_BASE TIM6_BASE_S + +#define TIM7 TIM7_S +#define TIM7_BASE TIM7_BASE_S + +#define TIM8 TIM8_S +#define TIM8_BASE TIM8_BASE_S + +#define TIM15 TIM15_S +#define TIM15_BASE TIM15_BASE_S + +#define TIM12 TIM12_S +#define TIM12_BASE TIM12_BASE_S + +#define TIM13 TIM13_S +#define TIM13_BASE TIM13_BASE_S + +#define TIM14 TIM14_S +#define TIM14_BASE TIM14_BASE_S + +#define TIM16 TIM16_S +#define TIM16_BASE TIM16_BASE_S + +#define TIM17 TIM17_S +#define TIM17_BASE TIM17_BASE_S + +#define WWDG WWDG_S +#define WWDG_BASE WWDG_BASE_S + +#define IWDG IWDG_S +#define IWDG_BASE IWDG_BASE_S + +#define SPI1 SPI1_S +#define SPI1_BASE SPI1_BASE_S + +#define SPI2 SPI2_S +#define SPI2_BASE SPI2_BASE_S + +#define SPI3 SPI3_S +#define SPI3_BASE SPI3_BASE_S + +#define SPI4 SPI4_S +#define SPI4_BASE SPI4_BASE_S + +#define SPI5 SPI5_S +#define SPI5_BASE SPI5_BASE_S + +#define SPI6 SPI6_S +#define SPI6_BASE SPI6_BASE_S + +#define USART1 USART1_S +#define USART1_BASE USART1_BASE_S + +#define USART2 USART2_S +#define USART2_BASE USART2_BASE_S + +#define USART3 USART3_S +#define USART3_BASE USART3_BASE_S + +#define UART4 UART4_S +#define UART4_BASE UART4_BASE_S + +#define UART5 UART5_S +#define UART5_BASE UART5_BASE_S + +#define USART6 USART6_S +#define USART6_BASE USART6_BASE_S + +#define UART7 UART7_S +#define UART7_BASE UART7_BASE_S + +#define UART8 UART8_S +#define UART8_BASE UART8_BASE_S + +#define UART9 UART9_S +#define UART9_BASE UART9_BASE_S + +#define USART10 USART10_S +#define USART10_BASE USART10_BASE_S + +#define USART11 USART11_S +#define USART11_BASE USART11_BASE_S + +#define UART12 UART12_S +#define UART12_BASE UART12_BASE_S + +#define CEC CEC_S +#define CEC_BASE CEC_BASE_S + +#define I2C1 I2C1_S +#define I2C1_BASE I2C1_BASE_S + +#define I2C2 I2C2_S +#define I2C2_BASE I2C2_BASE_S + +#define I2C3 I2C3_S +#define I2C3_BASE I2C3_BASE_S + +#define I2C4 I2C4_S +#define I2C4_BASE I2C4_BASE_S + +#define I3C1 I3C1_S +#define I3C1_BASE I3C1_BASE_S + +#define CRS CRS_S +#define CRS_BASE CRS_BASE_S + +#define FDCAN1 FDCAN1_S +#define FDCAN1_BASE FDCAN1_BASE_S + +#define FDCAN_CONFIG FDCAN_CONFIG_S +#define FDCAN_CONFIG_BASE FDCAN_CONFIG_BASE_S +#define SRAMCAN_BASE SRAMCAN_BASE_S + +#define FDCAN2 FDCAN2_S +#define FDCAN2_BASE FDCAN2_BASE_S + +#define DAC1 DAC1_S +#define DAC1_BASE DAC1_BASE_S + +#define LPTIM1 LPTIM1_S +#define LPTIM1_BASE LPTIM1_BASE_S + +#define LPTIM2 LPTIM2_S +#define LPTIM2_BASE LPTIM2_BASE_S + +#define LPTIM3 LPTIM3_S +#define LPTIM3_BASE LPTIM3_BASE_S + +#define LPTIM4 LPTIM4_S +#define LPTIM4_BASE LPTIM4_BASE_S + +#define LPTIM5 LPTIM5_S +#define LPTIM5_BASE LPTIM5_BASE_S + +#define LPTIM6 LPTIM6_S +#define LPTIM6_BASE LPTIM6_BASE_S + +#define LPUART1 LPUART1_S +#define LPUART1_BASE LPUART1_BASE_S + +#define UCPD1 UCPD1_S +#define UCPD1_BASE UCPD1_BASE_S + +#define SBS SBS_S +#define SBS_BASE SBS_BASE_S + +#define VREFBUF VREFBUF_S +#define VREFBUF_BASE VREFBUF_BASE_S + +#define SAI1 SAI1_S +#define SAI1_BASE SAI1_BASE_S + +#define SAI1_Block_A SAI1_Block_A_S +#define SAI1_Block_A_BASE SAI1_Block_A_BASE_S + +#define SAI1_Block_B SAI1_Block_B_S +#define SAI1_Block_B_BASE SAI1_Block_B_BASE_S + +#define SAI2 SAI2_S +#define SAI2_BASE SAI2_BASE_S + +#define SAI2_Block_A SAI2_Block_A_S +#define SAI2_Block_A_BASE SAI2_Block_A_BASE_S + +#define SAI2_Block_B SAI2_Block_B_S +#define SAI2_Block_B_BASE SAI2_Block_B_BASE_S + +#define USB_DRD_FS USB_DRD_FS_S +#define USB_DRD_BASE USB_DRD_BASE_S +#define USB_DRD_PMAADDR USB_DRD_PMAADDR_S +#define USB_DRD_PMA_BUFF USB_DRD_PMA_BUFF_S + +#define CRC CRC_S +#define CRC_BASE CRC_BASE_S + +#define ADC1 ADC1_S +#define ADC1_BASE ADC1_BASE_S + +#define ADC2 ADC2_S +#define ADC2_BASE ADC2_BASE_S + +#define ADC12_COMMON ADC12_COMMON_S +#define ADC12_COMMON_BASE ADC12_COMMON_BASE_S + +#define HASH HASH_S +#define HASH_BASE HASH_BASE_S + +#define HASH_DIGEST HASH_DIGEST_S +#define HASH_DIGEST_BASE HASH_DIGEST_BASE_S + +#define AES AES_S +#define AES_BASE AES_BASE_S + +#define RNG RNG_S +#define RNG_BASE RNG_BASE_S + +#define SAES SAES_S +#define SAES_BASE SAES_BASE_S + +#define PKA PKA_S +#define PKA_BASE PKA_BASE_S +#define PKA_RAM_BASE PKA_RAM_BASE_S + +#define OTFDEC1 OTFDEC1_S +#define OTFDEC1_BASE OTFDEC1_BASE_S + +#define OTFDEC1_REGION1 OTFDEC1_REGION1_S +#define OTFDEC1_REGION1_BASE OTFDEC1_REGION1_BASE_S + +#define OTFDEC1_REGION2 OTFDEC1_REGION2_S +#define OTFDEC1_REGION2_BASE OTFDEC1_REGION2_BASE_S + +#define OTFDEC1_REGION3 OTFDEC1_REGION3_S +#define OTFDEC1_REGION3_BASE OTFDEC1_REGION3_BASE_S + +#define OTFDEC1_REGION4 OTFDEC1_REGION4_S +#define OTFDEC1_REGION4_BASE OTFDEC1_REGION4_BASE_S + + +#define ETH ETH_S +#define ETH_BASE ETH_BASE_S +#define ETH_MAC ETH_MAC_S +#define ETH_MAC_BASE ETH_MAC_BASE_S + +#define SDMMC1 SDMMC1_S +#define SDMMC1_BASE SDMMC1_BASE_S + +#define SDMMC2 SDMMC2_S +#define SDMMC2_BASE SDMMC2_BASE_S + +#define FMC_Bank1_R FMC_Bank1_R_S +#define FMC_Bank1_R_BASE FMC_Bank1_R_BASE_S + +#define FMC_Bank1E_R FMC_Bank1E_R_S +#define FMC_Bank1E_R_BASE FMC_Bank1E_R_BASE_S + +#define FMC_Bank3_R FMC_Bank3_R_S +#define FMC_Bank3_R_BASE FMC_Bank3_R_BASE_S + +#define FMC_Bank5_6_R FMC_Bank5_6_R_S +#define FMC_Bank5_6_R_BASE FMC_Bank5_6_R_BASE_S + +#define OCTOSPI1 OCTOSPI1_S +#define OCTOSPI1_R_BASE OCTOSPI1_R_BASE_S + +#define DLYB_SDMMC1 DLYB_SDMMC1_S +#define DLYB_SDMMC1_BASE DLYB_SDMMC1_BASE_S + +#define DLYB_SDMMC2 DLYB_SDMMC2_S +#define DLYB_SDMMC2_BASE DLYB_SDMMC2_BASE_S + +#define DLYB_OCTOSPI1 DLYB_OCTOSPI1_S +#define DLYB_OCTOSPI1_BASE DLYB_OCTOSPI1_BASE_S + +#else + +/*!< Memory base addresses for Non secure peripherals */ +#define FLASH_BASE FLASH_BASE_NS +#define FLASH_OBK_BASE FLASH_OBK_BASE_NS +#define FLASH_EDATA_BASE FLASH_EDATA_BASE_NS +#define FLASH_SYSTEM_BASE FLASH_SYSTEM_BASE_NS + +#define SRAM1_BASE SRAM1_BASE_NS +#define SRAM2_BASE SRAM2_BASE_NS + +#define SRAM3_BASE SRAM3_BASE_NS +#define BKPSRAM_BASE BKPSRAM_BASE_NS + +#define PERIPH_BASE PERIPH_BASE_NS +#define APB1PERIPH_BASE APB1PERIPH_BASE_NS +#define APB2PERIPH_BASE APB2PERIPH_BASE_NS +#define APB3PERIPH_BASE APB3PERIPH_BASE_NS +#define AHB1PERIPH_BASE AHB1PERIPH_BASE_NS +#define AHB2PERIPH_BASE AHB2PERIPH_BASE_NS +#define AHB3PERIPH_BASE AHB3PERIPH_BASE_NS +#define AHB4PERIPH_BASE AHB4PERIPH_BASE_NS + +/*!< Instance aliases and base addresses for Non secure peripherals */ +#define CORDIC CORDIC_NS +#define CORDIC_BASE CORDIC_BASE_NS + +#define RCC RCC_NS +#define RCC_BASE RCC_BASE_NS + +#define DCMI DCMI_NS +#define DCMI_BASE DCMI_BASE_NS + +#define PSSI PSSI_NS +#define PSSI_BASE PSSI_BASE_NS + +#define DTS DTS_NS +#define DTS_BASE DTS_BASE_NS + +#define FLASH FLASH_NS +#define FLASH_R_BASE FLASH_R_BASE_NS + +#define FMAC FMAC_NS +#define FMAC_BASE FMAC_BASE_NS + +#define GPDMA1 GPDMA1_NS +#define GPDMA1_BASE GPDMA1_BASE_NS + +#define GPDMA1_Channel0 GPDMA1_Channel0_NS +#define GPDMA1_Channel0_BASE GPDMA1_Channel0_BASE_NS + +#define GPDMA1_Channel1 GPDMA1_Channel1_NS +#define GPDMA1_Channel1_BASE GPDMA1_Channel1_BASE_NS + +#define GPDMA1_Channel2 GPDMA1_Channel2_NS +#define GPDMA1_Channel2_BASE GPDMA1_Channel2_BASE_NS + +#define GPDMA1_Channel3 GPDMA1_Channel3_NS +#define GPDMA1_Channel3_BASE GPDMA1_Channel3_BASE_NS + +#define GPDMA1_Channel4 GPDMA1_Channel4_NS +#define GPDMA1_Channel4_BASE GPDMA1_Channel4_BASE_NS + +#define GPDMA1_Channel5 GPDMA1_Channel5_NS +#define GPDMA1_Channel5_BASE GPDMA1_Channel5_BASE_NS + +#define GPDMA1_Channel6 GPDMA1_Channel6_NS +#define GPDMA1_Channel6_BASE GPDMA1_Channel6_BASE_NS + +#define GPDMA1_Channel7 GPDMA1_Channel7_NS +#define GPDMA1_Channel7_BASE GPDMA1_Channel7_BASE_NS + +#define GPDMA2 GPDMA2_NS +#define GPDMA2_BASE GPDMA2_BASE_NS + +#define GPDMA2_Channel0 GPDMA2_Channel0_NS +#define GPDMA2_Channel0_BASE GPDMA2_Channel0_BASE_NS + +#define GPDMA2_Channel1 GPDMA2_Channel1_NS +#define GPDMA2_Channel1_BASE GPDMA2_Channel1_BASE_NS + +#define GPDMA2_Channel2 GPDMA2_Channel2_NS +#define GPDMA2_Channel2_BASE GPDMA2_Channel2_BASE_NS + +#define GPDMA2_Channel3 GPDMA2_Channel3_NS +#define GPDMA2_Channel3_BASE GPDMA2_Channel3_BASE_NS + +#define GPDMA2_Channel4 GPDMA2_Channel4_NS +#define GPDMA2_Channel4_BASE GPDMA2_Channel4_BASE_NS + +#define GPDMA2_Channel5 GPDMA2_Channel5_NS +#define GPDMA2_Channel5_BASE GPDMA2_Channel5_BASE_NS + +#define GPDMA2_Channel6 GPDMA2_Channel6_NS +#define GPDMA2_Channel6_BASE GPDMA2_Channel6_BASE_NS + +#define GPDMA2_Channel7 GPDMA2_Channel7_NS +#define GPDMA2_Channel7_BASE GPDMA2_Channel7_BASE_NS + +#define GPIOA GPIOA_NS +#define GPIOA_BASE GPIOA_BASE_NS + +#define GPIOB GPIOB_NS +#define GPIOB_BASE GPIOB_BASE_NS + +#define GPIOC GPIOC_NS +#define GPIOC_BASE GPIOC_BASE_NS + +#define GPIOD GPIOD_NS +#define GPIOD_BASE GPIOD_BASE_NS + +#define GPIOE GPIOE_NS +#define GPIOE_BASE GPIOE_BASE_NS + +#define GPIOF GPIOF_NS +#define GPIOF_BASE GPIOF_BASE_NS + +#define GPIOG GPIOG_NS +#define GPIOG_BASE GPIOG_BASE_NS + +#define GPIOH GPIOH_NS +#define GPIOH_BASE GPIOH_BASE_NS + +#define GPIOI GPIOI_NS +#define GPIOI_BASE GPIOI_BASE_NS + +#define PWR PWR_NS +#define PWR_BASE PWR_BASE_NS + +#define RAMCFG_SRAM1 RAMCFG_SRAM1_NS +#define RAMCFG_SRAM1_BASE RAMCFG_SRAM1_BASE_NS + +#define RAMCFG_SRAM2 RAMCFG_SRAM2_NS +#define RAMCFG_SRAM2_BASE RAMCFG_SRAM2_BASE_NS + +#define RAMCFG_SRAM3 RAMCFG_SRAM3_NS +#define RAMCFG_SRAM3_BASE RAMCFG_SRAM3_BASE_NS + +#define RAMCFG_BKPRAM RAMCFG_BKPRAM_NS +#define RAMCFG_BKPRAM_BASE RAMCFG_BKPRAM_BASE_NS + +#define EXTI EXTI_NS +#define EXTI_BASE EXTI_BASE_NS + +#define ICACHE ICACHE_NS +#define ICACHE_BASE ICACHE_BASE_NS + +#define DCACHE1 DCACHE1_NS +#define DCACHE1_BASE DCACHE1_BASE_NS + +#define GTZC_TZSC1 GTZC_TZSC1_NS +#define GTZC_TZSC1_BASE GTZC_TZSC1_BASE_NS + +#define GTZC_TZIC1 GTZC_TZIC1_NS +#define GTZC_TZIC1_BASE GTZC_TZIC1_BASE_NS + +#define GTZC_MPCBB1 GTZC_MPCBB1_NS +#define GTZC_MPCBB1_BASE GTZC_MPCBB1_BASE_NS + +#define GTZC_MPCBB2 GTZC_MPCBB2_NS +#define GTZC_MPCBB2_BASE GTZC_MPCBB2_BASE_NS + +#define GTZC_MPCBB3 GTZC_MPCBB3_NS +#define GTZC_MPCBB3_BASE GTZC_MPCBB3_BASE_NS + +#define RTC RTC_NS +#define RTC_BASE RTC_BASE_NS + +#define TAMP TAMP_NS +#define TAMP_BASE TAMP_BASE_NS + +#define TIM1 TIM1_NS +#define TIM1_BASE TIM1_BASE_NS + +#define TIM2 TIM2_NS +#define TIM2_BASE TIM2_BASE_NS + +#define TIM3 TIM3_NS +#define TIM3_BASE TIM3_BASE_NS + +#define TIM4 TIM4_NS +#define TIM4_BASE TIM4_BASE_NS + +#define TIM5 TIM5_NS +#define TIM5_BASE TIM5_BASE_NS + +#define TIM6 TIM6_NS +#define TIM6_BASE TIM6_BASE_NS + +#define TIM7 TIM7_NS +#define TIM7_BASE TIM7_BASE_NS + +#define TIM8 TIM8_NS +#define TIM8_BASE TIM8_BASE_NS + +#define TIM12 TIM12_NS +#define TIM12_BASE TIM12_BASE_NS + +#define TIM13 TIM13_NS +#define TIM13_BASE TIM13_BASE_NS + +#define TIM14 TIM14_NS +#define TIM14_BASE TIM14_BASE_NS + +#define TIM15 TIM15_NS +#define TIM15_BASE TIM15_BASE_NS + +#define TIM16 TIM16_NS +#define TIM16_BASE TIM16_BASE_NS + +#define TIM17 TIM17_NS +#define TIM17_BASE TIM17_BASE_NS + +#define WWDG WWDG_NS +#define WWDG_BASE WWDG_BASE_NS + +#define IWDG IWDG_NS +#define IWDG_BASE IWDG_BASE_NS + +#define SPI1 SPI1_NS +#define SPI1_BASE SPI1_BASE_NS + +#define SPI2 SPI2_NS +#define SPI2_BASE SPI2_BASE_NS + +#define SPI3 SPI3_NS +#define SPI3_BASE SPI3_BASE_NS + +#define SPI4 SPI4_NS +#define SPI4_BASE SPI4_BASE_NS + +#define SPI5 SPI5_NS +#define SPI5_BASE SPI5_BASE_NS + +#define SPI6 SPI6_NS +#define SPI6_BASE SPI6_BASE_NS + +#define USART1 USART1_NS +#define USART1_BASE USART1_BASE_NS + +#define USART2 USART2_NS +#define USART2_BASE USART2_BASE_NS + +#define USART3 USART3_NS +#define USART3_BASE USART3_BASE_NS + +#define UART4 UART4_NS +#define UART4_BASE UART4_BASE_NS + +#define UART5 UART5_NS +#define UART5_BASE UART5_BASE_NS + +#define USART6 USART6_NS +#define USART6_BASE USART6_BASE_NS + +#define UART7 UART7_NS +#define UART7_BASE UART7_BASE_NS + +#define UART8 UART8_NS +#define UART8_BASE UART8_BASE_NS + +#define UART9 UART9_NS +#define UART9_BASE UART9_BASE_NS + +#define USART10 USART10_NS +#define USART10_BASE USART10_BASE_NS + +#define USART11 USART11_NS +#define USART11_BASE USART11_BASE_NS + +#define UART12 UART12_NS +#define UART12_BASE UART12_BASE_NS + +#define CEC CEC_NS +#define CEC_BASE CEC_BASE_NS + +#define I2C1 I2C1_NS +#define I2C1_BASE I2C1_BASE_NS + +#define I2C2 I2C2_NS +#define I2C2_BASE I2C2_BASE_NS + +#define I2C3 I2C3_NS +#define I2C3_BASE I2C3_BASE_NS + +#define I2C4 I2C4_NS +#define I2C4_BASE I2C4_BASE_NS + +#define I3C1 I3C1_NS +#define I3C1_BASE I3C1_BASE_NS + +#define CRS CRS_NS +#define CRS_BASE CRS_BASE_NS + +#define FDCAN1 FDCAN1_NS +#define FDCAN1_BASE FDCAN1_BASE_NS + +#define FDCAN_CONFIG FDCAN_CONFIG_NS +#define FDCAN_CONFIG_BASE FDCAN_CONFIG_BASE_NS +#define SRAMCAN_BASE SRAMCAN_BASE_NS + +#define FDCAN2 FDCAN2_NS +#define FDCAN2_BASE FDCAN2_BASE_NS + +#define DAC1 DAC1_NS +#define DAC1_BASE DAC1_BASE_NS + +#define LPTIM1 LPTIM1_NS +#define LPTIM1_BASE LPTIM1_BASE_NS + +#define LPTIM2 LPTIM2_NS +#define LPTIM2_BASE LPTIM2_BASE_NS + +#define LPTIM3 LPTIM3_NS +#define LPTIM3_BASE LPTIM3_BASE_NS + +#define LPTIM4 LPTIM4_NS +#define LPTIM4_BASE LPTIM4_BASE_NS + +#define LPTIM5 LPTIM5_NS +#define LPTIM5_BASE LPTIM5_BASE_NS + +#define LPTIM6 LPTIM6_NS +#define LPTIM6_BASE LPTIM6_BASE_NS + +#define LPUART1 LPUART1_NS +#define LPUART1_BASE LPUART1_BASE_NS + +#define UCPD1 UCPD1_NS +#define UCPD1_BASE UCPD1_BASE_NS + +#define SBS SBS_NS +#define SBS_BASE SBS_BASE_NS + +#define VREFBUF VREFBUF_NS +#define VREFBUF_BASE VREFBUF_BASE_NS + +#define SAI1 SAI1_NS +#define SAI1_BASE SAI1_BASE_NS + +#define SAI1_Block_A SAI1_Block_A_NS +#define SAI1_Block_A_BASE SAI1_Block_A_BASE_NS + +#define SAI1_Block_B SAI1_Block_B_NS +#define SAI1_Block_B_BASE SAI1_Block_B_BASE_NS + +#define SAI2 SAI2_NS +#define SAI2_BASE SAI2_BASE_NS + +#define SAI2_Block_A SAI2_Block_A_NS +#define SAI2_Block_A_BASE SAI2_Block_A_BASE_NS + +#define SAI2_Block_B SAI2_Block_B_NS +#define SAI2_Block_B_BASE SAI2_Block_B_BASE_NS + +#define USB_DRD_FS USB_DRD_FS_NS +#define USB_DRD_BASE USB_DRD_BASE_NS +#define USB_DRD_PMAADDR USB_DRD_PMAADDR_NS +#define USB_DRD_PMA_BUFF USB_DRD_PMA_BUFF_NS + +#define CRC CRC_NS +#define CRC_BASE CRC_BASE_NS + +#define ADC1 ADC1_NS +#define ADC1_BASE ADC1_BASE_NS + +#define ADC2 ADC2_NS +#define ADC2_BASE ADC2_BASE_NS + +#define ADC12_COMMON ADC12_COMMON_NS +#define ADC12_COMMON_BASE ADC12_COMMON_BASE_NS + +#define HASH HASH_NS +#define HASH_BASE HASH_BASE_NS + +#define HASH_DIGEST HASH_DIGEST_NS +#define HASH_DIGEST_BASE HASH_DIGEST_BASE_NS + +#define AES AES_NS +#define AES_BASE AES_BASE_NS + +#define RNG RNG_NS +#define RNG_BASE RNG_BASE_NS + +#define SAES SAES_NS +#define SAES_BASE SAES_BASE_NS + +#define PKA PKA_NS +#define PKA_BASE PKA_BASE_NS +#define PKA_RAM_BASE PKA_RAM_BASE_NS + +#define OTFDEC1 OTFDEC1_NS +#define OTFDEC1_BASE OTFDEC1_BASE_NS + +#define OTFDEC1_REGION1 OTFDEC1_REGION1_NS +#define OTFDEC1_REGION1_BASE OTFDEC1_REGION1_BASE_NS + +#define OTFDEC1_REGION2 OTFDEC1_REGION2_NS +#define OTFDEC1_REGION2_BASE OTFDEC1_REGION2_BASE_NS + +#define OTFDEC1_REGION3 OTFDEC1_REGION3_NS +#define OTFDEC1_REGION3_BASE OTFDEC1_REGION3_BASE_NS + +#define OTFDEC1_REGION4 OTFDEC1_REGION4_NS +#define OTFDEC1_REGION4_BASE OTFDEC1_REGION4_BASE_NS + + +#define ETH ETH_NS +#define ETH_BASE ETH_BASE_NS +#define ETH_MAC ETH_MAC_NS +#define ETH_MAC_BASE ETH_MAC_BASE_NS + +#define SDMMC1 SDMMC1_NS +#define SDMMC1_BASE SDMMC1_BASE_NS + +#define SDMMC2 SDMMC2_NS +#define SDMMC2_BASE SDMMC2_BASE_NS + +#define FMC_Bank1_R FMC_Bank1_R_NS +#define FMC_Bank1_R_BASE FMC_Bank1_R_BASE_NS + +#define FMC_Bank1E_R FMC_Bank1E_R_NS +#define FMC_Bank1E_R_BASE FMC_Bank1E_R_BASE_NS + +#define FMC_Bank3_R FMC_Bank3_R_NS +#define FMC_Bank3_R_BASE FMC_Bank3_R_BASE_NS + +#define FMC_Bank5_6_R FMC_Bank5_6_R_NS +#define FMC_Bank5_6_R_BASE FMC_Bank5_6_R_BASE_NS + +#define OCTOSPI1 OCTOSPI1_NS +#define OCTOSPI1_R_BASE OCTOSPI1_R_BASE_NS + +#define DLYB_SDMMC1 DLYB_SDMMC1_NS +#define DLYB_SDMMC1_BASE DLYB_SDMMC1_BASE_NS + +#define DLYB_SDMMC2 DLYB_SDMMC2_NS +#define DLYB_SDMMC2_BASE DLYB_SDMMC2_BASE_NS + +#define DLYB_OCTOSPI1 DLYB_OCTOSPI1_NS +#define DLYB_OCTOSPI1_BASE DLYB_OCTOSPI1_BASE_NS + +#endif + + +/******************************************************************************/ +/* */ +/* Analog to Digital Converter */ +/* */ +/******************************************************************************/ +#define ADC_MULTIMODE_SUPPORT /*!< ADC feature available only on specific devices: multimode available on devices with several ADC instances */ +/******************** Bit definition for ADC_ISR register *******************/ +#define ADC_ISR_ADRDY_Pos (0U) +#define ADC_ISR_ADRDY_Msk (0x1UL << ADC_ISR_ADRDY_Pos) /*!< 0x00000001 */ +#define ADC_ISR_ADRDY ADC_ISR_ADRDY_Msk /*!< ADC ready flag */ +#define ADC_ISR_EOSMP_Pos (1U) +#define ADC_ISR_EOSMP_Msk (0x1UL << ADC_ISR_EOSMP_Pos) /*!< 0x00000002 */ +#define ADC_ISR_EOSMP ADC_ISR_EOSMP_Msk /*!< ADC group regular end of sampling flag */ +#define ADC_ISR_EOC_Pos (2U) +#define ADC_ISR_EOC_Msk (0x1UL << ADC_ISR_EOC_Pos) /*!< 0x00000004 */ +#define ADC_ISR_EOC ADC_ISR_EOC_Msk /*!< ADC group regular end of unitary conversion flag */ +#define ADC_ISR_EOS_Pos (3U) +#define ADC_ISR_EOS_Msk (0x1UL << ADC_ISR_EOS_Pos) /*!< 0x00000008 */ +#define ADC_ISR_EOS ADC_ISR_EOS_Msk /*!< ADC group regular end of sequence conversions flag */ +#define ADC_ISR_OVR_Pos (4U) +#define ADC_ISR_OVR_Msk (0x1UL << ADC_ISR_OVR_Pos) /*!< 0x00000010 */ +#define ADC_ISR_OVR ADC_ISR_OVR_Msk /*!< ADC group regular overrun flag */ +#define ADC_ISR_JEOC_Pos (5U) +#define ADC_ISR_JEOC_Msk (0x1UL << ADC_ISR_JEOC_Pos) /*!< 0x00000020 */ +#define ADC_ISR_JEOC ADC_ISR_JEOC_Msk /*!< ADC group injected end of unitary conversion flag */ +#define ADC_ISR_JEOS_Pos (6U) +#define ADC_ISR_JEOS_Msk (0x1UL << ADC_ISR_JEOS_Pos) /*!< 0x00000040 */ +#define ADC_ISR_JEOS ADC_ISR_JEOS_Msk /*!< ADC group injected end of sequence conversions flag */ +#define ADC_ISR_AWD1_Pos (7U) +#define ADC_ISR_AWD1_Msk (0x1UL << ADC_ISR_AWD1_Pos) /*!< 0x00000080 */ +#define ADC_ISR_AWD1 ADC_ISR_AWD1_Msk /*!< ADC analog watchdog 1 flag */ +#define ADC_ISR_AWD2_Pos (8U) +#define ADC_ISR_AWD2_Msk (0x1UL << ADC_ISR_AWD2_Pos) /*!< 0x00000100 */ +#define ADC_ISR_AWD2 ADC_ISR_AWD2_Msk /*!< ADC analog watchdog 2 flag */ +#define ADC_ISR_AWD3_Pos (9U) +#define ADC_ISR_AWD3_Msk (0x1UL << ADC_ISR_AWD3_Pos) /*!< 0x00000200 */ +#define ADC_ISR_AWD3 ADC_ISR_AWD3_Msk /*!< ADC analog watchdog 3 flag */ +#define ADC_ISR_JQOVF_Pos (10U) +#define ADC_ISR_JQOVF_Msk (0x1UL << ADC_ISR_JQOVF_Pos) /*!< 0x00000400 */ +#define ADC_ISR_JQOVF ADC_ISR_JQOVF_Msk /*!< ADC group injected contexts queue overflow flag */ + +/******************** Bit definition for ADC_IER register *******************/ +#define ADC_IER_ADRDYIE_Pos (0U) +#define ADC_IER_ADRDYIE_Msk (0x1UL << ADC_IER_ADRDYIE_Pos) /*!< 0x00000001 */ +#define ADC_IER_ADRDYIE ADC_IER_ADRDYIE_Msk /*!< ADC ready interrupt */ +#define ADC_IER_EOSMPIE_Pos (1U) +#define ADC_IER_EOSMPIE_Msk (0x1UL << ADC_IER_EOSMPIE_Pos) /*!< 0x00000002 */ +#define ADC_IER_EOSMPIE ADC_IER_EOSMPIE_Msk /*!< ADC group regular end of sampling interrupt */ +#define ADC_IER_EOCIE_Pos (2U) +#define ADC_IER_EOCIE_Msk (0x1UL << ADC_IER_EOCIE_Pos) /*!< 0x00000004 */ +#define ADC_IER_EOCIE ADC_IER_EOCIE_Msk /*!< ADC group regular end of unitary conversion interrupt */ +#define ADC_IER_EOSIE_Pos (3U) +#define ADC_IER_EOSIE_Msk (0x1UL << ADC_IER_EOSIE_Pos) /*!< 0x00000008 */ +#define ADC_IER_EOSIE ADC_IER_EOSIE_Msk /*!< ADC group regular end of sequence conversions interrupt */ +#define ADC_IER_OVRIE_Pos (4U) +#define ADC_IER_OVRIE_Msk (0x1UL << ADC_IER_OVRIE_Pos) /*!< 0x00000010 */ +#define ADC_IER_OVRIE ADC_IER_OVRIE_Msk /*!< ADC group regular overrun interrupt */ +#define ADC_IER_JEOCIE_Pos (5U) +#define ADC_IER_JEOCIE_Msk (0x1UL << ADC_IER_JEOCIE_Pos) /*!< 0x00000020 */ +#define ADC_IER_JEOCIE ADC_IER_JEOCIE_Msk /*!< ADC group injected end of unitary conversion interrupt */ +#define ADC_IER_JEOSIE_Pos (6U) +#define ADC_IER_JEOSIE_Msk (0x1UL << ADC_IER_JEOSIE_Pos) /*!< 0x00000040 */ +#define ADC_IER_JEOSIE ADC_IER_JEOSIE_Msk /*!< ADC group injected end of sequence conversions interrupt */ +#define ADC_IER_AWD1IE_Pos (7U) +#define ADC_IER_AWD1IE_Msk (0x1UL << ADC_IER_AWD1IE_Pos) /*!< 0x00000080 */ +#define ADC_IER_AWD1IE ADC_IER_AWD1IE_Msk /*!< ADC analog watchdog 1 interrupt */ +#define ADC_IER_AWD2IE_Pos (8U) +#define ADC_IER_AWD2IE_Msk (0x1UL << ADC_IER_AWD2IE_Pos) /*!< 0x00000100 */ +#define ADC_IER_AWD2IE ADC_IER_AWD2IE_Msk /*!< ADC analog watchdog 2 interrupt */ +#define ADC_IER_AWD3IE_Pos (9U) +#define ADC_IER_AWD3IE_Msk (0x1UL << ADC_IER_AWD3IE_Pos) /*!< 0x00000200 */ +#define ADC_IER_AWD3IE ADC_IER_AWD3IE_Msk /*!< ADC analog watchdog 3 interrupt */ +#define ADC_IER_JQOVFIE_Pos (10U) +#define ADC_IER_JQOVFIE_Msk (0x1UL << ADC_IER_JQOVFIE_Pos) /*!< 0x00000400 */ +#define ADC_IER_JQOVFIE ADC_IER_JQOVFIE_Msk /*!< ADC group injected contexts queue overflow interrupt */ + +/******************** Bit definition for ADC_CR register ********************/ +#define ADC_CR_ADEN_Pos (0U) +#define ADC_CR_ADEN_Msk (0x1UL << ADC_CR_ADEN_Pos) /*!< 0x00000001 */ +#define ADC_CR_ADEN ADC_CR_ADEN_Msk /*!< ADC enable */ +#define ADC_CR_ADDIS_Pos (1U) +#define ADC_CR_ADDIS_Msk (0x1UL << ADC_CR_ADDIS_Pos) /*!< 0x00000002 */ +#define ADC_CR_ADDIS ADC_CR_ADDIS_Msk /*!< ADC disable */ +#define ADC_CR_ADSTART_Pos (2U) +#define ADC_CR_ADSTART_Msk (0x1UL << ADC_CR_ADSTART_Pos) /*!< 0x00000004 */ +#define ADC_CR_ADSTART ADC_CR_ADSTART_Msk /*!< ADC group regular conversion start */ +#define ADC_CR_JADSTART_Pos (3U) +#define ADC_CR_JADSTART_Msk (0x1UL << ADC_CR_JADSTART_Pos) /*!< 0x00000008 */ +#define ADC_CR_JADSTART ADC_CR_JADSTART_Msk /*!< ADC group injected conversion start */ +#define ADC_CR_ADSTP_Pos (4U) +#define ADC_CR_ADSTP_Msk (0x1UL << ADC_CR_ADSTP_Pos) /*!< 0x00000010 */ +#define ADC_CR_ADSTP ADC_CR_ADSTP_Msk /*!< ADC group regular conversion stop */ +#define ADC_CR_JADSTP_Pos (5U) +#define ADC_CR_JADSTP_Msk (0x1UL << ADC_CR_JADSTP_Pos) /*!< 0x00000020 */ +#define ADC_CR_JADSTP ADC_CR_JADSTP_Msk /*!< ADC group injected conversion stop */ +#define ADC_CR_ADVREGEN_Pos (28U) +#define ADC_CR_ADVREGEN_Msk (0x1UL << ADC_CR_ADVREGEN_Pos) /*!< 0x10000000 */ +#define ADC_CR_ADVREGEN ADC_CR_ADVREGEN_Msk /*!< ADC voltage regulator enable */ +#define ADC_CR_DEEPPWD_Pos (29U) +#define ADC_CR_DEEPPWD_Msk (0x1UL << ADC_CR_DEEPPWD_Pos) /*!< 0x20000000 */ +#define ADC_CR_DEEPPWD ADC_CR_DEEPPWD_Msk /*!< ADC deep power down enable */ +#define ADC_CR_ADCALDIF_Pos (30U) +#define ADC_CR_ADCALDIF_Msk (0x1UL << ADC_CR_ADCALDIF_Pos) /*!< 0x40000000 */ +#define ADC_CR_ADCALDIF ADC_CR_ADCALDIF_Msk /*!< ADC differential mode for calibration */ +#define ADC_CR_ADCAL_Pos (31U) +#define ADC_CR_ADCAL_Msk (0x1UL << ADC_CR_ADCAL_Pos) /*!< 0x80000000 */ +#define ADC_CR_ADCAL ADC_CR_ADCAL_Msk /*!< ADC calibration */ + +/******************** Bit definition for ADC_CFGR register ******************/ +#define ADC_CFGR_DMAEN_Pos (0U) +#define ADC_CFGR_DMAEN_Msk (0x1UL << ADC_CFGR_DMAEN_Pos) /*!< 0x00000001 */ +#define ADC_CFGR_DMAEN ADC_CFGR_DMAEN_Msk /*!< ADC DMA transfer enable */ +#define ADC_CFGR_DMACFG_Pos (1U) +#define ADC_CFGR_DMACFG_Msk (0x1UL << ADC_CFGR_DMACFG_Pos) /*!< 0x00000002 */ +#define ADC_CFGR_DMACFG ADC_CFGR_DMACFG_Msk /*!< ADC DMA transfer configuration */ + +#define ADC_CFGR_RES_Pos (3U) +#define ADC_CFGR_RES_Msk (0x3UL << ADC_CFGR_RES_Pos) /*!< 0x00000018 */ +#define ADC_CFGR_RES ADC_CFGR_RES_Msk /*!< ADC data resolution */ +#define ADC_CFGR_RES_0 (0x1UL << ADC_CFGR_RES_Pos) /*!< 0x00000008 */ +#define ADC_CFGR_RES_1 (0x2UL << ADC_CFGR_RES_Pos) /*!< 0x00000010 */ + +#define ADC_CFGR_EXTSEL_Pos (5U) +#define ADC_CFGR_EXTSEL_Msk (0x1FUL << ADC_CFGR_EXTSEL_Pos) /*!< 0x000003E0 */ +#define ADC_CFGR_EXTSEL ADC_CFGR_EXTSEL_Msk /*!< ADC group regular external trigger source */ +#define ADC_CFGR_EXTSEL_0 (0x1UL << ADC_CFGR_EXTSEL_Pos) /*!< 0x00000020 */ +#define ADC_CFGR_EXTSEL_1 (0x2UL << ADC_CFGR_EXTSEL_Pos) /*!< 0x00000040 */ +#define ADC_CFGR_EXTSEL_2 (0x4UL << ADC_CFGR_EXTSEL_Pos) /*!< 0x00000080 */ +#define ADC_CFGR_EXTSEL_3 (0x8UL << ADC_CFGR_EXTSEL_Pos) /*!< 0x00000100 */ +#define ADC_CFGR_EXTSEL_4 (0x10UL << ADC_CFGR_EXTSEL_Pos) /*!< 0x00000200 */ + +#define ADC_CFGR_EXTEN_Pos (10U) +#define ADC_CFGR_EXTEN_Msk (0x3UL << ADC_CFGR_EXTEN_Pos) /*!< 0x00000C00 */ +#define ADC_CFGR_EXTEN ADC_CFGR_EXTEN_Msk /*!< ADC group regular external trigger polarity */ +#define ADC_CFGR_EXTEN_0 (0x1UL << ADC_CFGR_EXTEN_Pos) /*!< 0x00000400 */ +#define ADC_CFGR_EXTEN_1 (0x2UL << ADC_CFGR_EXTEN_Pos) /*!< 0x00000800 */ + +#define ADC_CFGR_OVRMOD_Pos (12U) +#define ADC_CFGR_OVRMOD_Msk (0x1UL << ADC_CFGR_OVRMOD_Pos) /*!< 0x00001000 */ +#define ADC_CFGR_OVRMOD ADC_CFGR_OVRMOD_Msk /*!< ADC group regular overrun configuration */ +#define ADC_CFGR_CONT_Pos (13U) +#define ADC_CFGR_CONT_Msk (0x1UL << ADC_CFGR_CONT_Pos) /*!< 0x00002000 */ +#define ADC_CFGR_CONT ADC_CFGR_CONT_Msk /*!< ADC group regular continuous conversion mode */ +#define ADC_CFGR_AUTDLY_Pos (14U) +#define ADC_CFGR_AUTDLY_Msk (0x1UL << ADC_CFGR_AUTDLY_Pos) /*!< 0x00004000 */ +#define ADC_CFGR_AUTDLY ADC_CFGR_AUTDLY_Msk /*!< ADC low power auto wait */ +#define ADC_CFGR_ALIGN_Pos (15U) +#define ADC_CFGR_ALIGN_Msk (0x1UL << ADC_CFGR_ALIGN_Pos) /*!< 0x00008000 */ +#define ADC_CFGR_ALIGN ADC_CFGR_ALIGN_Msk /*!< ADC data alignment */ +#define ADC_CFGR_DISCEN_Pos (16U) +#define ADC_CFGR_DISCEN_Msk (0x1UL << ADC_CFGR_DISCEN_Pos) /*!< 0x00010000 */ +#define ADC_CFGR_DISCEN ADC_CFGR_DISCEN_Msk /*!< ADC group regular sequencer discontinuous mode */ + +#define ADC_CFGR_DISCNUM_Pos (17U) +#define ADC_CFGR_DISCNUM_Msk (0x7UL << ADC_CFGR_DISCNUM_Pos) /*!< 0x000E0000 */ +#define ADC_CFGR_DISCNUM ADC_CFGR_DISCNUM_Msk /*!< ADC group regular sequencer discontinuous number of ranks */ +#define ADC_CFGR_DISCNUM_0 (0x1UL << ADC_CFGR_DISCNUM_Pos) /*!< 0x00020000 */ +#define ADC_CFGR_DISCNUM_1 (0x2UL << ADC_CFGR_DISCNUM_Pos) /*!< 0x00040000 */ +#define ADC_CFGR_DISCNUM_2 (0x4UL << ADC_CFGR_DISCNUM_Pos) /*!< 0x00080000 */ + +#define ADC_CFGR_JDISCEN_Pos (20U) +#define ADC_CFGR_JDISCEN_Msk (0x1UL << ADC_CFGR_JDISCEN_Pos) /*!< 0x00100000 */ +#define ADC_CFGR_JDISCEN ADC_CFGR_JDISCEN_Msk /*!< ADC group injected sequencer discontinuous mode */ +#define ADC_CFGR_JQM_Pos (21U) +#define ADC_CFGR_JQM_Msk (0x1UL << ADC_CFGR_JQM_Pos) /*!< 0x00200000 */ +#define ADC_CFGR_JQM ADC_CFGR_JQM_Msk /*!< ADC group injected contexts queue mode */ +#define ADC_CFGR_AWD1SGL_Pos (22U) +#define ADC_CFGR_AWD1SGL_Msk (0x1UL << ADC_CFGR_AWD1SGL_Pos) /*!< 0x00400000 */ +#define ADC_CFGR_AWD1SGL ADC_CFGR_AWD1SGL_Msk /*!< ADC analog watchdog 1 monitoring a single channel or all channels */ +#define ADC_CFGR_AWD1EN_Pos (23U) +#define ADC_CFGR_AWD1EN_Msk (0x1UL << ADC_CFGR_AWD1EN_Pos) /*!< 0x00800000 */ +#define ADC_CFGR_AWD1EN ADC_CFGR_AWD1EN_Msk /*!< ADC analog watchdog 1 enable on scope ADC group regular */ +#define ADC_CFGR_JAWD1EN_Pos (24U) +#define ADC_CFGR_JAWD1EN_Msk (0x1UL << ADC_CFGR_JAWD1EN_Pos) /*!< 0x01000000 */ +#define ADC_CFGR_JAWD1EN ADC_CFGR_JAWD1EN_Msk /*!< ADC analog watchdog 1 enable on scope ADC group injected */ +#define ADC_CFGR_JAUTO_Pos (25U) +#define ADC_CFGR_JAUTO_Msk (0x1UL << ADC_CFGR_JAUTO_Pos) /*!< 0x02000000 */ +#define ADC_CFGR_JAUTO ADC_CFGR_JAUTO_Msk /*!< ADC group injected automatic trigger mode */ + +#define ADC_CFGR_AWD1CH_Pos (26U) +#define ADC_CFGR_AWD1CH_Msk (0x1FUL << ADC_CFGR_AWD1CH_Pos) /*!< 0x7C000000 */ +#define ADC_CFGR_AWD1CH ADC_CFGR_AWD1CH_Msk /*!< ADC analog watchdog 1 monitored channel selection */ +#define ADC_CFGR_AWD1CH_0 (0x01UL << ADC_CFGR_AWD1CH_Pos) /*!< 0x04000000 */ +#define ADC_CFGR_AWD1CH_1 (0x02UL << ADC_CFGR_AWD1CH_Pos) /*!< 0x08000000 */ +#define ADC_CFGR_AWD1CH_2 (0x04UL << ADC_CFGR_AWD1CH_Pos) /*!< 0x10000000 */ +#define ADC_CFGR_AWD1CH_3 (0x08UL << ADC_CFGR_AWD1CH_Pos) /*!< 0x20000000 */ +#define ADC_CFGR_AWD1CH_4 (0x10UL << ADC_CFGR_AWD1CH_Pos) /*!< 0x40000000 */ + +#define ADC_CFGR_JQDIS_Pos (31U) +#define ADC_CFGR_JQDIS_Msk (0x1UL << ADC_CFGR_JQDIS_Pos) /*!< 0x80000000 */ +#define ADC_CFGR_JQDIS ADC_CFGR_JQDIS_Msk /*!< ADC group injected contexts queue disable */ + +/******************** Bit definition for ADC_CFGR2 register *****************/ +#define ADC_CFGR2_ROVSE_Pos (0U) +#define ADC_CFGR2_ROVSE_Msk (0x1UL << ADC_CFGR2_ROVSE_Pos) /*!< 0x00000001 */ +#define ADC_CFGR2_ROVSE ADC_CFGR2_ROVSE_Msk /*!< ADC oversampler enable on scope ADC group regular */ +#define ADC_CFGR2_JOVSE_Pos (1U) +#define ADC_CFGR2_JOVSE_Msk (0x1UL << ADC_CFGR2_JOVSE_Pos) /*!< 0x00000002 */ +#define ADC_CFGR2_JOVSE ADC_CFGR2_JOVSE_Msk /*!< ADC oversampler enable on scope ADC group injected */ + +#define ADC_CFGR2_OVSR_Pos (2U) +#define ADC_CFGR2_OVSR_Msk (0x7UL << ADC_CFGR2_OVSR_Pos) /*!< 0x0000001C */ +#define ADC_CFGR2_OVSR ADC_CFGR2_OVSR_Msk /*!< ADC oversampling ratio */ +#define ADC_CFGR2_OVSR_0 (0x1UL << ADC_CFGR2_OVSR_Pos) /*!< 0x00000004 */ +#define ADC_CFGR2_OVSR_1 (0x2UL << ADC_CFGR2_OVSR_Pos) /*!< 0x00000008 */ +#define ADC_CFGR2_OVSR_2 (0x4UL << ADC_CFGR2_OVSR_Pos) /*!< 0x00000010 */ + +#define ADC_CFGR2_OVSS_Pos (5U) +#define ADC_CFGR2_OVSS_Msk (0xFUL << ADC_CFGR2_OVSS_Pos) /*!< 0x000001E0 */ +#define ADC_CFGR2_OVSS ADC_CFGR2_OVSS_Msk /*!< ADC oversampling shift */ +#define ADC_CFGR2_OVSS_0 (0x1UL << ADC_CFGR2_OVSS_Pos) /*!< 0x00000020 */ +#define ADC_CFGR2_OVSS_1 (0x2UL << ADC_CFGR2_OVSS_Pos) /*!< 0x00000040 */ +#define ADC_CFGR2_OVSS_2 (0x4UL << ADC_CFGR2_OVSS_Pos) /*!< 0x00000080 */ +#define ADC_CFGR2_OVSS_3 (0x8UL << ADC_CFGR2_OVSS_Pos) /*!< 0x00000100 */ + +#define ADC_CFGR2_TROVS_Pos (9U) +#define ADC_CFGR2_TROVS_Msk (0x1UL << ADC_CFGR2_TROVS_Pos) /*!< 0x00000200 */ +#define ADC_CFGR2_TROVS ADC_CFGR2_TROVS_Msk /*!< ADC oversampling discontinuous mode (triggered mode) for ADC group regular */ +#define ADC_CFGR2_ROVSM_Pos (10U) +#define ADC_CFGR2_ROVSM_Msk (0x1UL << ADC_CFGR2_ROVSM_Pos) /*!< 0x00000400 */ +#define ADC_CFGR2_ROVSM ADC_CFGR2_ROVSM_Msk /*!< ADC oversampling mode managing interlaced conversions of ADC group regular and group injected */ + +#define ADC_CFGR2_GCOMP_Pos (16U) +#define ADC_CFGR2_GCOMP_Msk (0x1UL << ADC_CFGR2_GCOMP_Pos) /*!< 0x00010000 */ +#define ADC_CFGR2_GCOMP ADC_CFGR2_GCOMP_Msk /*!< ADC Gain Compensation mode */ + +#define ADC_CFGR2_SWTRIG_Pos (25U) +#define ADC_CFGR2_SWTRIG_Msk (0x1UL << ADC_CFGR2_SWTRIG_Pos) /*!< 0x02000000 */ +#define ADC_CFGR2_SWTRIG ADC_CFGR2_SWTRIG_Msk /*!< ADC Software Trigger Bit for Sample time control trigger mode */ +#define ADC_CFGR2_BULB_Pos (26U) +#define ADC_CFGR2_BULB_Msk (0x1UL << ADC_CFGR2_BULB_Pos) /*!< 0x04000000 */ +#define ADC_CFGR2_BULB ADC_CFGR2_BULB_Msk /*!< ADC Bulb sampling mode */ +#define ADC_CFGR2_SMPTRIG_Pos (27U) +#define ADC_CFGR2_SMPTRIG_Msk (0x1UL << ADC_CFGR2_SMPTRIG_Pos) /*!< 0x08000000 */ +#define ADC_CFGR2_SMPTRIG ADC_CFGR2_SMPTRIG_Msk /*!< ADC Sample Time Control Trigger mode */ + +#define ADC_CFGR2_LFTRIG_Pos (29U) +#define ADC_CFGR2_LFTRIG_Msk (0x1UL << ADC_CFGR2_LFTRIG_Pos) /*!< 0x20000000 */ +#define ADC_CFGR2_LFTRIG ADC_CFGR2_LFTRIG_Msk /*!< ADC Low Frequency Trigger */ + +/******************** Bit definition for ADC_SMPR1 register *****************/ +#define ADC_SMPR1_SMP0_Pos (0U) +#define ADC_SMPR1_SMP0_Msk (0x7UL << ADC_SMPR1_SMP0_Pos) /*!< 0x00000007 */ +#define ADC_SMPR1_SMP0 ADC_SMPR1_SMP0_Msk /*!< ADC channel 0 sampling time selection */ +#define ADC_SMPR1_SMP0_0 (0x1UL << ADC_SMPR1_SMP0_Pos) /*!< 0x00000001 */ +#define ADC_SMPR1_SMP0_1 (0x2UL << ADC_SMPR1_SMP0_Pos) /*!< 0x00000002 */ +#define ADC_SMPR1_SMP0_2 (0x4UL << ADC_SMPR1_SMP0_Pos) /*!< 0x00000004 */ + +#define ADC_SMPR1_SMP1_Pos (3U) +#define ADC_SMPR1_SMP1_Msk (0x7UL << ADC_SMPR1_SMP1_Pos) /*!< 0x00000038 */ +#define ADC_SMPR1_SMP1 ADC_SMPR1_SMP1_Msk /*!< ADC channel 1 sampling time selection */ +#define ADC_SMPR1_SMP1_0 (0x1UL << ADC_SMPR1_SMP1_Pos) /*!< 0x00000008 */ +#define ADC_SMPR1_SMP1_1 (0x2UL << ADC_SMPR1_SMP1_Pos) /*!< 0x00000010 */ +#define ADC_SMPR1_SMP1_2 (0x4UL << ADC_SMPR1_SMP1_Pos) /*!< 0x00000020 */ + +#define ADC_SMPR1_SMP2_Pos (6U) +#define ADC_SMPR1_SMP2_Msk (0x7UL << ADC_SMPR1_SMP2_Pos) /*!< 0x000001C0 */ +#define ADC_SMPR1_SMP2 ADC_SMPR1_SMP2_Msk /*!< ADC channel 2 sampling time selection */ +#define ADC_SMPR1_SMP2_0 (0x1UL << ADC_SMPR1_SMP2_Pos) /*!< 0x00000040 */ +#define ADC_SMPR1_SMP2_1 (0x2UL << ADC_SMPR1_SMP2_Pos) /*!< 0x00000080 */ +#define ADC_SMPR1_SMP2_2 (0x4UL << ADC_SMPR1_SMP2_Pos) /*!< 0x00000100 */ + +#define ADC_SMPR1_SMP3_Pos (9U) +#define ADC_SMPR1_SMP3_Msk (0x7UL << ADC_SMPR1_SMP3_Pos) /*!< 0x00000E00 */ +#define ADC_SMPR1_SMP3 ADC_SMPR1_SMP3_Msk /*!< ADC channel 3 sampling time selection */ +#define ADC_SMPR1_SMP3_0 (0x1UL << ADC_SMPR1_SMP3_Pos) /*!< 0x00000200 */ +#define ADC_SMPR1_SMP3_1 (0x2UL << ADC_SMPR1_SMP3_Pos) /*!< 0x00000400 */ +#define ADC_SMPR1_SMP3_2 (0x4UL << ADC_SMPR1_SMP3_Pos) /*!< 0x00000800 */ + +#define ADC_SMPR1_SMP4_Pos (12U) +#define ADC_SMPR1_SMP4_Msk (0x7UL << ADC_SMPR1_SMP4_Pos) /*!< 0x00007000 */ +#define ADC_SMPR1_SMP4 ADC_SMPR1_SMP4_Msk /*!< ADC channel 4 sampling time selection */ +#define ADC_SMPR1_SMP4_0 (0x1UL << ADC_SMPR1_SMP4_Pos) /*!< 0x00001000 */ +#define ADC_SMPR1_SMP4_1 (0x2UL << ADC_SMPR1_SMP4_Pos) /*!< 0x00002000 */ +#define ADC_SMPR1_SMP4_2 (0x4UL << ADC_SMPR1_SMP4_Pos) /*!< 0x00004000 */ + +#define ADC_SMPR1_SMP5_Pos (15U) +#define ADC_SMPR1_SMP5_Msk (0x7UL << ADC_SMPR1_SMP5_Pos) /*!< 0x00038000 */ +#define ADC_SMPR1_SMP5 ADC_SMPR1_SMP5_Msk /*!< ADC channel 5 sampling time selection */ +#define ADC_SMPR1_SMP5_0 (0x1UL << ADC_SMPR1_SMP5_Pos) /*!< 0x00008000 */ +#define ADC_SMPR1_SMP5_1 (0x2UL << ADC_SMPR1_SMP5_Pos) /*!< 0x00010000 */ +#define ADC_SMPR1_SMP5_2 (0x4UL << ADC_SMPR1_SMP5_Pos) /*!< 0x00020000 */ + +#define ADC_SMPR1_SMP6_Pos (18U) +#define ADC_SMPR1_SMP6_Msk (0x7UL << ADC_SMPR1_SMP6_Pos) /*!< 0x001C0000 */ +#define ADC_SMPR1_SMP6 ADC_SMPR1_SMP6_Msk /*!< ADC channel 6 sampling time selection */ +#define ADC_SMPR1_SMP6_0 (0x1UL << ADC_SMPR1_SMP6_Pos) /*!< 0x00040000 */ +#define ADC_SMPR1_SMP6_1 (0x2UL << ADC_SMPR1_SMP6_Pos) /*!< 0x00080000 */ +#define ADC_SMPR1_SMP6_2 (0x4UL << ADC_SMPR1_SMP6_Pos) /*!< 0x00100000 */ + +#define ADC_SMPR1_SMP7_Pos (21U) +#define ADC_SMPR1_SMP7_Msk (0x7UL << ADC_SMPR1_SMP7_Pos) /*!< 0x00E00000 */ +#define ADC_SMPR1_SMP7 ADC_SMPR1_SMP7_Msk /*!< ADC channel 7 sampling time selection */ +#define ADC_SMPR1_SMP7_0 (0x1UL << ADC_SMPR1_SMP7_Pos) /*!< 0x00200000 */ +#define ADC_SMPR1_SMP7_1 (0x2UL << ADC_SMPR1_SMP7_Pos) /*!< 0x00400000 */ +#define ADC_SMPR1_SMP7_2 (0x4UL << ADC_SMPR1_SMP7_Pos) /*!< 0x00800000 */ + +#define ADC_SMPR1_SMP8_Pos (24U) +#define ADC_SMPR1_SMP8_Msk (0x7UL << ADC_SMPR1_SMP8_Pos) /*!< 0x07000000 */ +#define ADC_SMPR1_SMP8 ADC_SMPR1_SMP8_Msk /*!< ADC channel 8 sampling time selection */ +#define ADC_SMPR1_SMP8_0 (0x1UL << ADC_SMPR1_SMP8_Pos) /*!< 0x01000000 */ +#define ADC_SMPR1_SMP8_1 (0x2UL << ADC_SMPR1_SMP8_Pos) /*!< 0x02000000 */ +#define ADC_SMPR1_SMP8_2 (0x4UL << ADC_SMPR1_SMP8_Pos) /*!< 0x04000000 */ + +#define ADC_SMPR1_SMP9_Pos (27U) +#define ADC_SMPR1_SMP9_Msk (0x7UL << ADC_SMPR1_SMP9_Pos) /*!< 0x38000000 */ +#define ADC_SMPR1_SMP9 ADC_SMPR1_SMP9_Msk /*!< ADC channel 9 sampling time selection */ +#define ADC_SMPR1_SMP9_0 (0x1UL << ADC_SMPR1_SMP9_Pos) /*!< 0x08000000 */ +#define ADC_SMPR1_SMP9_1 (0x2UL << ADC_SMPR1_SMP9_Pos) /*!< 0x10000000 */ +#define ADC_SMPR1_SMP9_2 (0x4UL << ADC_SMPR1_SMP9_Pos) /*!< 0x20000000 */ + +#define ADC_SMPR1_SMPPLUS_Pos (31U) +#define ADC_SMPR1_SMPPLUS_Msk (0x1UL << ADC_SMPR1_SMPPLUS_Pos) /*!< 0x80000000 */ +#define ADC_SMPR1_SMPPLUS ADC_SMPR1_SMPPLUS_Msk /*!< ADC channels sampling time additional setting */ + +/******************** Bit definition for ADC_SMPR2 register *****************/ +#define ADC_SMPR2_SMP10_Pos (0U) +#define ADC_SMPR2_SMP10_Msk (0x7UL << ADC_SMPR2_SMP10_Pos) /*!< 0x00000007 */ +#define ADC_SMPR2_SMP10 ADC_SMPR2_SMP10_Msk /*!< ADC channel 10 sampling time selection */ +#define ADC_SMPR2_SMP10_0 (0x1UL << ADC_SMPR2_SMP10_Pos) /*!< 0x00000001 */ +#define ADC_SMPR2_SMP10_1 (0x2UL << ADC_SMPR2_SMP10_Pos) /*!< 0x00000002 */ +#define ADC_SMPR2_SMP10_2 (0x4UL << ADC_SMPR2_SMP10_Pos) /*!< 0x00000004 */ + +#define ADC_SMPR2_SMP11_Pos (3U) +#define ADC_SMPR2_SMP11_Msk (0x7UL << ADC_SMPR2_SMP11_Pos) /*!< 0x00000038 */ +#define ADC_SMPR2_SMP11 ADC_SMPR2_SMP11_Msk /*!< ADC channel 11 sampling time selection */ +#define ADC_SMPR2_SMP11_0 (0x1UL << ADC_SMPR2_SMP11_Pos) /*!< 0x00000008 */ +#define ADC_SMPR2_SMP11_1 (0x2UL << ADC_SMPR2_SMP11_Pos) /*!< 0x00000010 */ +#define ADC_SMPR2_SMP11_2 (0x4UL << ADC_SMPR2_SMP11_Pos) /*!< 0x00000020 */ + +#define ADC_SMPR2_SMP12_Pos (6U) +#define ADC_SMPR2_SMP12_Msk (0x7UL << ADC_SMPR2_SMP12_Pos) /*!< 0x000001C0 */ +#define ADC_SMPR2_SMP12 ADC_SMPR2_SMP12_Msk /*!< ADC channel 12 sampling time selection */ +#define ADC_SMPR2_SMP12_0 (0x1UL << ADC_SMPR2_SMP12_Pos) /*!< 0x00000040 */ +#define ADC_SMPR2_SMP12_1 (0x2UL << ADC_SMPR2_SMP12_Pos) /*!< 0x00000080 */ +#define ADC_SMPR2_SMP12_2 (0x4UL << ADC_SMPR2_SMP12_Pos) /*!< 0x00000100 */ + +#define ADC_SMPR2_SMP13_Pos (9U) +#define ADC_SMPR2_SMP13_Msk (0x7UL << ADC_SMPR2_SMP13_Pos) /*!< 0x00000E00 */ +#define ADC_SMPR2_SMP13 ADC_SMPR2_SMP13_Msk /*!< ADC channel 13 sampling time selection */ +#define ADC_SMPR2_SMP13_0 (0x1UL << ADC_SMPR2_SMP13_Pos) /*!< 0x00000200 */ +#define ADC_SMPR2_SMP13_1 (0x2UL << ADC_SMPR2_SMP13_Pos) /*!< 0x00000400 */ +#define ADC_SMPR2_SMP13_2 (0x4UL << ADC_SMPR2_SMP13_Pos) /*!< 0x00000800 */ + +#define ADC_SMPR2_SMP14_Pos (12U) +#define ADC_SMPR2_SMP14_Msk (0x7UL << ADC_SMPR2_SMP14_Pos) /*!< 0x00007000 */ +#define ADC_SMPR2_SMP14 ADC_SMPR2_SMP14_Msk /*!< ADC channel 14 sampling time selection */ +#define ADC_SMPR2_SMP14_0 (0x1UL << ADC_SMPR2_SMP14_Pos) /*!< 0x00001000 */ +#define ADC_SMPR2_SMP14_1 (0x2UL << ADC_SMPR2_SMP14_Pos) /*!< 0x00002000 */ +#define ADC_SMPR2_SMP14_2 (0x4UL << ADC_SMPR2_SMP14_Pos) /*!< 0x00004000 */ + +#define ADC_SMPR2_SMP15_Pos (15U) +#define ADC_SMPR2_SMP15_Msk (0x7UL << ADC_SMPR2_SMP15_Pos) /*!< 0x00038000 */ +#define ADC_SMPR2_SMP15 ADC_SMPR2_SMP15_Msk /*!< ADC channel 15 sampling time selection */ +#define ADC_SMPR2_SMP15_0 (0x1UL << ADC_SMPR2_SMP15_Pos) /*!< 0x00008000 */ +#define ADC_SMPR2_SMP15_1 (0x2UL << ADC_SMPR2_SMP15_Pos) /*!< 0x00010000 */ +#define ADC_SMPR2_SMP15_2 (0x4UL << ADC_SMPR2_SMP15_Pos) /*!< 0x00020000 */ + +#define ADC_SMPR2_SMP16_Pos (18U) +#define ADC_SMPR2_SMP16_Msk (0x7UL << ADC_SMPR2_SMP16_Pos) /*!< 0x001C0000 */ +#define ADC_SMPR2_SMP16 ADC_SMPR2_SMP16_Msk /*!< ADC channel 16 sampling time selection */ +#define ADC_SMPR2_SMP16_0 (0x1UL << ADC_SMPR2_SMP16_Pos) /*!< 0x00040000 */ +#define ADC_SMPR2_SMP16_1 (0x2UL << ADC_SMPR2_SMP16_Pos) /*!< 0x00080000 */ +#define ADC_SMPR2_SMP16_2 (0x4UL << ADC_SMPR2_SMP16_Pos) /*!< 0x00100000 */ + +#define ADC_SMPR2_SMP17_Pos (21U) +#define ADC_SMPR2_SMP17_Msk (0x7UL << ADC_SMPR2_SMP17_Pos) /*!< 0x00E00000 */ +#define ADC_SMPR2_SMP17 ADC_SMPR2_SMP17_Msk /*!< ADC channel 17 sampling time selection */ +#define ADC_SMPR2_SMP17_0 (0x1UL << ADC_SMPR2_SMP17_Pos) /*!< 0x00200000 */ +#define ADC_SMPR2_SMP17_1 (0x2UL << ADC_SMPR2_SMP17_Pos) /*!< 0x00400000 */ +#define ADC_SMPR2_SMP17_2 (0x4UL << ADC_SMPR2_SMP17_Pos) /*!< 0x00800000 */ + +#define ADC_SMPR2_SMP18_Pos (24U) +#define ADC_SMPR2_SMP18_Msk (0x7UL << ADC_SMPR2_SMP18_Pos) /*!< 0x07000000 */ +#define ADC_SMPR2_SMP18 ADC_SMPR2_SMP18_Msk /*!< ADC channel 18 sampling time selection */ +#define ADC_SMPR2_SMP18_0 (0x1UL << ADC_SMPR2_SMP18_Pos) /*!< 0x01000000 */ +#define ADC_SMPR2_SMP18_1 (0x2UL << ADC_SMPR2_SMP18_Pos) /*!< 0x02000000 */ +#define ADC_SMPR2_SMP18_2 (0x4UL << ADC_SMPR2_SMP18_Pos) /*!< 0x04000000 */ + +/******************** Bit definition for ADC_TR1 register *******************/ +#define ADC_TR1_LT1_Pos (0U) +#define ADC_TR1_LT1_Msk (0xFFFUL << ADC_TR1_LT1_Pos) /*!< 0x00000FFF */ +#define ADC_TR1_LT1 ADC_TR1_LT1_Msk /*!< ADC analog watchdog 1 threshold low */ + +#define ADC_TR1_AWDFILT_Pos (12U) +#define ADC_TR1_AWDFILT_Msk (0x7UL << ADC_TR1_AWDFILT_Pos) /*!< 0x00007000 */ +#define ADC_TR1_AWDFILT ADC_TR1_AWDFILT_Msk /*!< ADC analog watchdog filtering parameter */ +#define ADC_TR1_AWDFILT_0 (0x1UL << ADC_TR1_AWDFILT_Pos) /*!< 0x00001000 */ +#define ADC_TR1_AWDFILT_1 (0x2UL << ADC_TR1_AWDFILT_Pos) /*!< 0x00002000 */ +#define ADC_TR1_AWDFILT_2 (0x4UL << ADC_TR1_AWDFILT_Pos) /*!< 0x00004000 */ + +#define ADC_TR1_HT1_Pos (16U) +#define ADC_TR1_HT1_Msk (0xFFFUL << ADC_TR1_HT1_Pos) /*!< 0x0FFF0000 */ +#define ADC_TR1_HT1 ADC_TR1_HT1_Msk /*!< ADC analog watchdog 1 threshold high */ + +/******************** Bit definition for ADC_TR2 register *******************/ +#define ADC_TR2_LT2_Pos (0U) +#define ADC_TR2_LT2_Msk (0xFFUL << ADC_TR2_LT2_Pos) /*!< 0x000000FF */ +#define ADC_TR2_LT2 ADC_TR2_LT2_Msk /*!< ADC analog watchdog 2 threshold low */ + +#define ADC_TR2_HT2_Pos (16U) +#define ADC_TR2_HT2_Msk (0xFFUL << ADC_TR2_HT2_Pos) /*!< 0x00FF0000 */ +#define ADC_TR2_HT2 ADC_TR2_HT2_Msk /*!< ADC analog watchdog 2 threshold high */ + +/******************** Bit definition for ADC_TR3 register *******************/ +#define ADC_TR3_LT3_Pos (0U) +#define ADC_TR3_LT3_Msk (0xFFUL << ADC_TR3_LT3_Pos) /*!< 0x000000FF */ +#define ADC_TR3_LT3 ADC_TR3_LT3_Msk /*!< ADC analog watchdog 3 threshold low */ + +#define ADC_TR3_HT3_Pos (16U) +#define ADC_TR3_HT3_Msk (0xFFUL << ADC_TR3_HT3_Pos) /*!< 0x00FF0000 */ +#define ADC_TR3_HT3 ADC_TR3_HT3_Msk /*!< ADC analog watchdog 3 threshold high */ + +/******************** Bit definition for ADC_SQR1 register ******************/ +#define ADC_SQR1_L_Pos (0U) +#define ADC_SQR1_L_Msk (0xFUL << ADC_SQR1_L_Pos) /*!< 0x0000000F */ +#define ADC_SQR1_L ADC_SQR1_L_Msk /*!< ADC group regular sequencer scan length */ +#define ADC_SQR1_L_0 (0x1UL << ADC_SQR1_L_Pos) /*!< 0x00000001 */ +#define ADC_SQR1_L_1 (0x2UL << ADC_SQR1_L_Pos) /*!< 0x00000002 */ +#define ADC_SQR1_L_2 (0x4UL << ADC_SQR1_L_Pos) /*!< 0x00000004 */ +#define ADC_SQR1_L_3 (0x8UL << ADC_SQR1_L_Pos) /*!< 0x00000008 */ + +#define ADC_SQR1_SQ1_Pos (6U) +#define ADC_SQR1_SQ1_Msk (0x1FUL << ADC_SQR1_SQ1_Pos) /*!< 0x000007C0 */ +#define ADC_SQR1_SQ1 ADC_SQR1_SQ1_Msk /*!< ADC group regular sequencer rank 1 */ +#define ADC_SQR1_SQ1_0 (0x01UL << ADC_SQR1_SQ1_Pos) /*!< 0x00000040 */ +#define ADC_SQR1_SQ1_1 (0x02UL << ADC_SQR1_SQ1_Pos) /*!< 0x00000080 */ +#define ADC_SQR1_SQ1_2 (0x04UL << ADC_SQR1_SQ1_Pos) /*!< 0x00000100 */ +#define ADC_SQR1_SQ1_3 (0x08UL << ADC_SQR1_SQ1_Pos) /*!< 0x00000200 */ +#define ADC_SQR1_SQ1_4 (0x10UL << ADC_SQR1_SQ1_Pos) /*!< 0x00000400 */ + +#define ADC_SQR1_SQ2_Pos (12U) +#define ADC_SQR1_SQ2_Msk (0x1FUL << ADC_SQR1_SQ2_Pos) /*!< 0x0001F000 */ +#define ADC_SQR1_SQ2 ADC_SQR1_SQ2_Msk /*!< ADC group regular sequencer rank 2 */ +#define ADC_SQR1_SQ2_0 (0x01UL << ADC_SQR1_SQ2_Pos) /*!< 0x00001000 */ +#define ADC_SQR1_SQ2_1 (0x02UL << ADC_SQR1_SQ2_Pos) /*!< 0x00002000 */ +#define ADC_SQR1_SQ2_2 (0x04UL << ADC_SQR1_SQ2_Pos) /*!< 0x00004000 */ +#define ADC_SQR1_SQ2_3 (0x08UL << ADC_SQR1_SQ2_Pos) /*!< 0x00008000 */ +#define ADC_SQR1_SQ2_4 (0x10UL << ADC_SQR1_SQ2_Pos) /*!< 0x00010000 */ + +#define ADC_SQR1_SQ3_Pos (18U) +#define ADC_SQR1_SQ3_Msk (0x1FUL << ADC_SQR1_SQ3_Pos) /*!< 0x007C0000 */ +#define ADC_SQR1_SQ3 ADC_SQR1_SQ3_Msk /*!< ADC group regular sequencer rank 3 */ +#define ADC_SQR1_SQ3_0 (0x01UL << ADC_SQR1_SQ3_Pos) /*!< 0x00040000 */ +#define ADC_SQR1_SQ3_1 (0x02UL << ADC_SQR1_SQ3_Pos) /*!< 0x00080000 */ +#define ADC_SQR1_SQ3_2 (0x04UL << ADC_SQR1_SQ3_Pos) /*!< 0x00100000 */ +#define ADC_SQR1_SQ3_3 (0x08UL << ADC_SQR1_SQ3_Pos) /*!< 0x00200000 */ +#define ADC_SQR1_SQ3_4 (0x10UL<< ADC_SQR1_SQ3_Pos) /*!< 0x00400000 */ + +#define ADC_SQR1_SQ4_Pos (24U) +#define ADC_SQR1_SQ4_Msk (0x1FUL << ADC_SQR1_SQ4_Pos) /*!< 0x1F000000 */ +#define ADC_SQR1_SQ4 ADC_SQR1_SQ4_Msk /*!< ADC group regular sequencer rank 4 */ +#define ADC_SQR1_SQ4_0 (0x01UL << ADC_SQR1_SQ4_Pos) /*!< 0x01000000 */ +#define ADC_SQR1_SQ4_1 (0x02UL << ADC_SQR1_SQ4_Pos) /*!< 0x02000000 */ +#define ADC_SQR1_SQ4_2 (0x04UL << ADC_SQR1_SQ4_Pos) /*!< 0x04000000 */ +#define ADC_SQR1_SQ4_3 (0x08UL << ADC_SQR1_SQ4_Pos) /*!< 0x08000000 */ +#define ADC_SQR1_SQ4_4 (0x10UL << ADC_SQR1_SQ4_Pos) /*!< 0x10000000 */ + +/******************** Bit definition for ADC_SQR2 register ******************/ +#define ADC_SQR2_SQ5_Pos (0U) +#define ADC_SQR2_SQ5_Msk (0x1FUL << ADC_SQR2_SQ5_Pos) /*!< 0x0000001F */ +#define ADC_SQR2_SQ5 ADC_SQR2_SQ5_Msk /*!< ADC group regular sequencer rank 5 */ +#define ADC_SQR2_SQ5_0 (0x01UL << ADC_SQR2_SQ5_Pos) /*!< 0x00000001 */ +#define ADC_SQR2_SQ5_1 (0x02UL << ADC_SQR2_SQ5_Pos) /*!< 0x00000002 */ +#define ADC_SQR2_SQ5_2 (0x04UL << ADC_SQR2_SQ5_Pos) /*!< 0x00000004 */ +#define ADC_SQR2_SQ5_3 (0x08UL << ADC_SQR2_SQ5_Pos) /*!< 0x00000008 */ +#define ADC_SQR2_SQ5_4 (0x10UL << ADC_SQR2_SQ5_Pos) /*!< 0x00000010 */ + +#define ADC_SQR2_SQ6_Pos (6U) +#define ADC_SQR2_SQ6_Msk (0x1FUL << ADC_SQR2_SQ6_Pos) /*!< 0x000007C0 */ +#define ADC_SQR2_SQ6 ADC_SQR2_SQ6_Msk /*!< ADC group regular sequencer rank 6 */ +#define ADC_SQR2_SQ6_0 (0x01UL << ADC_SQR2_SQ6_Pos) /*!< 0x00000040 */ +#define ADC_SQR2_SQ6_1 (0x02UL << ADC_SQR2_SQ6_Pos) /*!< 0x00000080 */ +#define ADC_SQR2_SQ6_2 (0x04UL << ADC_SQR2_SQ6_Pos) /*!< 0x00000100 */ +#define ADC_SQR2_SQ6_3 (0x08UL << ADC_SQR2_SQ6_Pos) /*!< 0x00000200 */ +#define ADC_SQR2_SQ6_4 (0x10UL << ADC_SQR2_SQ6_Pos) /*!< 0x00000400 */ + +#define ADC_SQR2_SQ7_Pos (12U) +#define ADC_SQR2_SQ7_Msk (0x1FUL << ADC_SQR2_SQ7_Pos) /*!< 0x0001F000 */ +#define ADC_SQR2_SQ7 ADC_SQR2_SQ7_Msk /*!< ADC group regular sequencer rank 7 */ +#define ADC_SQR2_SQ7_0 (0x01UL << ADC_SQR2_SQ7_Pos) /*!< 0x00001000 */ +#define ADC_SQR2_SQ7_1 (0x02UL << ADC_SQR2_SQ7_Pos) /*!< 0x00002000 */ +#define ADC_SQR2_SQ7_2 (0x04UL << ADC_SQR2_SQ7_Pos) /*!< 0x00004000 */ +#define ADC_SQR2_SQ7_3 (0x08UL << ADC_SQR2_SQ7_Pos) /*!< 0x00008000 */ +#define ADC_SQR2_SQ7_4 (0x10UL << ADC_SQR2_SQ7_Pos) /*!< 0x00010000 */ + +#define ADC_SQR2_SQ8_Pos (18U) +#define ADC_SQR2_SQ8_Msk (0x1FUL << ADC_SQR2_SQ8_Pos) /*!< 0x007C0000 */ +#define ADC_SQR2_SQ8 ADC_SQR2_SQ8_Msk /*!< ADC group regular sequencer rank 8 */ +#define ADC_SQR2_SQ8_0 (0x01UL << ADC_SQR2_SQ8_Pos) /*!< 0x00040000 */ +#define ADC_SQR2_SQ8_1 (0x02UL << ADC_SQR2_SQ8_Pos) /*!< 0x00080000 */ +#define ADC_SQR2_SQ8_2 (0x04UL << ADC_SQR2_SQ8_Pos) /*!< 0x00100000 */ +#define ADC_SQR2_SQ8_3 (0x08UL << ADC_SQR2_SQ8_Pos) /*!< 0x00200000 */ +#define ADC_SQR2_SQ8_4 (0x10UL << ADC_SQR2_SQ8_Pos) /*!< 0x00400000 */ + +#define ADC_SQR2_SQ9_Pos (24U) +#define ADC_SQR2_SQ9_Msk (0x1FUL << ADC_SQR2_SQ9_Pos) /*!< 0x1F000000 */ +#define ADC_SQR2_SQ9 ADC_SQR2_SQ9_Msk /*!< ADC group regular sequencer rank 9 */ +#define ADC_SQR2_SQ9_0 (0x01UL << ADC_SQR2_SQ9_Pos) /*!< 0x01000000 */ +#define ADC_SQR2_SQ9_1 (0x02UL << ADC_SQR2_SQ9_Pos) /*!< 0x02000000 */ +#define ADC_SQR2_SQ9_2 (0x04UL << ADC_SQR2_SQ9_Pos) /*!< 0x04000000 */ +#define ADC_SQR2_SQ9_3 (0x08UL << ADC_SQR2_SQ9_Pos) /*!< 0x08000000 */ +#define ADC_SQR2_SQ9_4 (0x10UL << ADC_SQR2_SQ9_Pos) /*!< 0x10000000 */ + +/******************** Bit definition for ADC_SQR3 register ******************/ +#define ADC_SQR3_SQ10_Pos (0U) +#define ADC_SQR3_SQ10_Msk (0x1FUL << ADC_SQR3_SQ10_Pos) /*!< 0x0000001F */ +#define ADC_SQR3_SQ10 ADC_SQR3_SQ10_Msk /*!< ADC group regular sequencer rank 10 */ +#define ADC_SQR3_SQ10_0 (0x01UL << ADC_SQR3_SQ10_Pos) /*!< 0x00000001 */ +#define ADC_SQR3_SQ10_1 (0x02UL << ADC_SQR3_SQ10_Pos) /*!< 0x00000002 */ +#define ADC_SQR3_SQ10_2 (0x04UL << ADC_SQR3_SQ10_Pos) /*!< 0x00000004 */ +#define ADC_SQR3_SQ10_3 (0x08UL << ADC_SQR3_SQ10_Pos) /*!< 0x00000008 */ +#define ADC_SQR3_SQ10_4 (0x10UL << ADC_SQR3_SQ10_Pos) /*!< 0x00000010 */ + +#define ADC_SQR3_SQ11_Pos (6U) +#define ADC_SQR3_SQ11_Msk (0x1FUL << ADC_SQR3_SQ11_Pos) /*!< 0x000007C0 */ +#define ADC_SQR3_SQ11 ADC_SQR3_SQ11_Msk /*!< ADC group regular sequencer rank 11 */ +#define ADC_SQR3_SQ11_0 (0x01UL << ADC_SQR3_SQ11_Pos) /*!< 0x00000040 */ +#define ADC_SQR3_SQ11_1 (0x02UL << ADC_SQR3_SQ11_Pos) /*!< 0x00000080 */ +#define ADC_SQR3_SQ11_2 (0x04UL << ADC_SQR3_SQ11_Pos) /*!< 0x00000100 */ +#define ADC_SQR3_SQ11_3 (0x08UL << ADC_SQR3_SQ11_Pos) /*!< 0x00000200 */ +#define ADC_SQR3_SQ11_4 (0x10UL << ADC_SQR3_SQ11_Pos) /*!< 0x00000400 */ + +#define ADC_SQR3_SQ12_Pos (12U) +#define ADC_SQR3_SQ12_Msk (0x1FUL << ADC_SQR3_SQ12_Pos) /*!< 0x0001F000 */ +#define ADC_SQR3_SQ12 ADC_SQR3_SQ12_Msk /*!< ADC group regular sequencer rank 12 */ +#define ADC_SQR3_SQ12_0 (0x01UL << ADC_SQR3_SQ12_Pos) /*!< 0x00001000 */ +#define ADC_SQR3_SQ12_1 (0x02UL << ADC_SQR3_SQ12_Pos) /*!< 0x00002000 */ +#define ADC_SQR3_SQ12_2 (0x04UL << ADC_SQR3_SQ12_Pos) /*!< 0x00004000 */ +#define ADC_SQR3_SQ12_3 (0x08UL << ADC_SQR3_SQ12_Pos) /*!< 0x00008000 */ +#define ADC_SQR3_SQ12_4 (0x10UL << ADC_SQR3_SQ12_Pos) /*!< 0x00010000 */ + +#define ADC_SQR3_SQ13_Pos (18U) +#define ADC_SQR3_SQ13_Msk (0x1FUL << ADC_SQR3_SQ13_Pos) /*!< 0x007C0000 */ +#define ADC_SQR3_SQ13 ADC_SQR3_SQ13_Msk /*!< ADC group regular sequencer rank 13 */ +#define ADC_SQR3_SQ13_0 (0x01UL << ADC_SQR3_SQ13_Pos) /*!< 0x00040000 */ +#define ADC_SQR3_SQ13_1 (0x02UL << ADC_SQR3_SQ13_Pos) /*!< 0x00080000 */ +#define ADC_SQR3_SQ13_2 (0x04UL << ADC_SQR3_SQ13_Pos) /*!< 0x00100000 */ +#define ADC_SQR3_SQ13_3 (0x08UL << ADC_SQR3_SQ13_Pos) /*!< 0x00200000 */ +#define ADC_SQR3_SQ13_4 (0x10UL << ADC_SQR3_SQ13_Pos) /*!< 0x00400000 */ + +#define ADC_SQR3_SQ14_Pos (24U) +#define ADC_SQR3_SQ14_Msk (0x1FUL << ADC_SQR3_SQ14_Pos) /*!< 0x1F000000 */ +#define ADC_SQR3_SQ14 ADC_SQR3_SQ14_Msk /*!< ADC group regular sequencer rank 14 */ +#define ADC_SQR3_SQ14_0 (0x01UL << ADC_SQR3_SQ14_Pos) /*!< 0x01000000 */ +#define ADC_SQR3_SQ14_1 (0x02UL << ADC_SQR3_SQ14_Pos) /*!< 0x02000000 */ +#define ADC_SQR3_SQ14_2 (0x04UL << ADC_SQR3_SQ14_Pos) /*!< 0x04000000 */ +#define ADC_SQR3_SQ14_3 (0x08UL << ADC_SQR3_SQ14_Pos) /*!< 0x08000000 */ +#define ADC_SQR3_SQ14_4 (0x10UL << ADC_SQR3_SQ14_Pos) /*!< 0x10000000 */ + +/******************** Bit definition for ADC_SQR4 register ******************/ +#define ADC_SQR4_SQ15_Pos (0U) +#define ADC_SQR4_SQ15_Msk (0x1FUL << ADC_SQR4_SQ15_Pos) /*!< 0x0000001F */ +#define ADC_SQR4_SQ15 ADC_SQR4_SQ15_Msk /*!< ADC group regular sequencer rank 15 */ +#define ADC_SQR4_SQ15_0 (0x01UL << ADC_SQR4_SQ15_Pos) /*!< 0x00000001 */ +#define ADC_SQR4_SQ15_1 (0x02UL << ADC_SQR4_SQ15_Pos) /*!< 0x00000002 */ +#define ADC_SQR4_SQ15_2 (0x04UL << ADC_SQR4_SQ15_Pos) /*!< 0x00000004 */ +#define ADC_SQR4_SQ15_3 (0x08UL << ADC_SQR4_SQ15_Pos) /*!< 0x00000008 */ +#define ADC_SQR4_SQ15_4 (0x10UL << ADC_SQR4_SQ15_Pos) /*!< 0x00000010 */ + +#define ADC_SQR4_SQ16_Pos (6U) +#define ADC_SQR4_SQ16_Msk (0x1FUL << ADC_SQR4_SQ16_Pos) /*!< 0x000007C0 */ +#define ADC_SQR4_SQ16 ADC_SQR4_SQ16_Msk /*!< ADC group regular sequencer rank 16 */ +#define ADC_SQR4_SQ16_0 (0x01UL << ADC_SQR4_SQ16_Pos) /*!< 0x00000040 */ +#define ADC_SQR4_SQ16_1 (0x02UL << ADC_SQR4_SQ16_Pos) /*!< 0x00000080 */ +#define ADC_SQR4_SQ16_2 (0x04UL << ADC_SQR4_SQ16_Pos) /*!< 0x00000100 */ +#define ADC_SQR4_SQ16_3 (0x08UL << ADC_SQR4_SQ16_Pos) /*!< 0x00000200 */ +#define ADC_SQR4_SQ16_4 (0x10UL << ADC_SQR4_SQ16_Pos) /*!< 0x00000400 */ + +/******************** Bit definition for ADC_DR register ********************/ +#define ADC_DR_RDATA_Pos (0U) +#define ADC_DR_RDATA_Msk (0xFFFFUL << ADC_DR_RDATA_Pos) /*!< 0x0000FFFF */ +#define ADC_DR_RDATA ADC_DR_RDATA_Msk /*!< ADC group regular conversion data */ + +/******************** Bit definition for ADC_JSQR register ******************/ +#define ADC_JSQR_JL_Pos (0U) +#define ADC_JSQR_JL_Msk (0x3UL << ADC_JSQR_JL_Pos) /*!< 0x00000003 */ +#define ADC_JSQR_JL ADC_JSQR_JL_Msk /*!< ADC group injected sequencer scan length */ +#define ADC_JSQR_JL_0 (0x1UL << ADC_JSQR_JL_Pos) /*!< 0x00000001 */ +#define ADC_JSQR_JL_1 (0x2UL << ADC_JSQR_JL_Pos) /*!< 0x00000002 */ + +#define ADC_JSQR_JEXTSEL_Pos (2U) +#define ADC_JSQR_JEXTSEL_Msk (0x1FUL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x0000007C */ +#define ADC_JSQR_JEXTSEL ADC_JSQR_JEXTSEL_Msk /*!< ADC group injected external trigger source */ +#define ADC_JSQR_JEXTSEL_0 (0x1UL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x00000004 */ +#define ADC_JSQR_JEXTSEL_1 (0x2UL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x00000008 */ +#define ADC_JSQR_JEXTSEL_2 (0x4UL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x00000010 */ +#define ADC_JSQR_JEXTSEL_3 (0x8UL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x00000020 */ +#define ADC_JSQR_JEXTSEL_4 (0x10UL << ADC_JSQR_JEXTSEL_Pos) /*!< 0x00000040 */ + +#define ADC_JSQR_JEXTEN_Pos (7U) +#define ADC_JSQR_JEXTEN_Msk (0x3UL << ADC_JSQR_JEXTEN_Pos) /*!< 0x00000180 */ +#define ADC_JSQR_JEXTEN ADC_JSQR_JEXTEN_Msk /*!< ADC group injected external trigger polarity */ +#define ADC_JSQR_JEXTEN_0 (0x1UL << ADC_JSQR_JEXTEN_Pos) /*!< 0x00000080 */ +#define ADC_JSQR_JEXTEN_1 (0x2UL << ADC_JSQR_JEXTEN_Pos) /*!< 0x00000100 */ + +#define ADC_JSQR_JSQ1_Pos (9U) +#define ADC_JSQR_JSQ1_Msk (0x1FUL << ADC_JSQR_JSQ1_Pos) /*!< 0x00003E00 */ +#define ADC_JSQR_JSQ1 ADC_JSQR_JSQ1_Msk /*!< ADC group injected sequencer rank 1 */ +#define ADC_JSQR_JSQ1_0 (0x01UL << ADC_JSQR_JSQ1_Pos) /*!< 0x00000200 */ +#define ADC_JSQR_JSQ1_1 (0x02UL << ADC_JSQR_JSQ1_Pos) /*!< 0x00000400 */ +#define ADC_JSQR_JSQ1_2 (0x04UL << ADC_JSQR_JSQ1_Pos) /*!< 0x00000800 */ +#define ADC_JSQR_JSQ1_3 (0x08UL << ADC_JSQR_JSQ1_Pos) /*!< 0x00001000 */ +#define ADC_JSQR_JSQ1_4 (0x10UL << ADC_JSQR_JSQ1_Pos) /*!< 0x00002000 */ + +#define ADC_JSQR_JSQ2_Pos (15U) +#define ADC_JSQR_JSQ2_Msk (0x1FUL << ADC_JSQR_JSQ2_Pos) /*!< 0x0007C000 */ +#define ADC_JSQR_JSQ2 ADC_JSQR_JSQ2_Msk /*!< ADC group injected sequencer rank 2 */ +#define ADC_JSQR_JSQ2_0 (0x01UL << ADC_JSQR_JSQ2_Pos) /*!< 0x00004000 */ +#define ADC_JSQR_JSQ2_1 (0x02UL << ADC_JSQR_JSQ2_Pos) /*!< 0x00008000 */ +#define ADC_JSQR_JSQ2_2 (0x04UL << ADC_JSQR_JSQ2_Pos) /*!< 0x00010000 */ +#define ADC_JSQR_JSQ2_3 (0x08UL << ADC_JSQR_JSQ2_Pos) /*!< 0x00020000 */ +#define ADC_JSQR_JSQ2_4 (0x10UL << ADC_JSQR_JSQ2_Pos) /*!< 0x00040000 */ + +#define ADC_JSQR_JSQ3_Pos (21U) +#define ADC_JSQR_JSQ3_Msk (0x1FUL << ADC_JSQR_JSQ3_Pos) /*!< 0x03E00000 */ +#define ADC_JSQR_JSQ3 ADC_JSQR_JSQ3_Msk /*!< ADC group injected sequencer rank 3 */ +#define ADC_JSQR_JSQ3_0 (0x01UL << ADC_JSQR_JSQ3_Pos) /*!< 0x00200000 */ +#define ADC_JSQR_JSQ3_1 (0x02UL << ADC_JSQR_JSQ3_Pos) /*!< 0x00400000 */ +#define ADC_JSQR_JSQ3_2 (0x04UL << ADC_JSQR_JSQ3_Pos) /*!< 0x00800000 */ +#define ADC_JSQR_JSQ3_3 (0x08UL << ADC_JSQR_JSQ3_Pos) /*!< 0x01000000 */ +#define ADC_JSQR_JSQ3_4 (0x10UL << ADC_JSQR_JSQ3_Pos) /*!< 0x02000000 */ + +#define ADC_JSQR_JSQ4_Pos (27U) +#define ADC_JSQR_JSQ4_Msk (0x1FUL << ADC_JSQR_JSQ4_Pos) /*!< 0xF8000000 */ +#define ADC_JSQR_JSQ4 ADC_JSQR_JSQ4_Msk /*!< ADC group injected sequencer rank 4 */ +#define ADC_JSQR_JSQ4_0 (0x01UL << ADC_JSQR_JSQ4_Pos) /*!< 0x08000000 */ +#define ADC_JSQR_JSQ4_1 (0x02UL << ADC_JSQR_JSQ4_Pos) /*!< 0x10000000 */ +#define ADC_JSQR_JSQ4_2 (0x04UL << ADC_JSQR_JSQ4_Pos) /*!< 0x20000000 */ +#define ADC_JSQR_JSQ4_3 (0x08UL << ADC_JSQR_JSQ4_Pos) /*!< 0x40000000 */ +#define ADC_JSQR_JSQ4_4 (0x10UL << ADC_JSQR_JSQ4_Pos) /*!< 0x80000000 */ + +/******************** Bit definition for ADC_OFR1 register ******************/ +#define ADC_OFR1_OFFSET1_Pos (0U) +#define ADC_OFR1_OFFSET1_Msk (0xFFFUL << ADC_OFR1_OFFSET1_Pos) /*!< 0x00000FFF */ +#define ADC_OFR1_OFFSET1 ADC_OFR1_OFFSET1_Msk /*!< ADC offset number 1 offset level */ + +#define ADC_OFR1_OFFSETPOS_Pos (24U) +#define ADC_OFR1_OFFSETPOS_Msk (0x1UL << ADC_OFR1_OFFSETPOS_Pos) /*!< 0x01000000 */ +#define ADC_OFR1_OFFSETPOS ADC_OFR1_OFFSETPOS_Msk /*!< ADC offset number 1 positive */ +#define ADC_OFR1_SATEN_Pos (25U) +#define ADC_OFR1_SATEN_Msk (0x1UL << ADC_OFR1_SATEN_Pos) /*!< 0x02000000 */ +#define ADC_OFR1_SATEN ADC_OFR1_SATEN_Msk /*!< ADC offset number 1 saturation enable */ + +#define ADC_OFR1_OFFSET1_CH_Pos (26U) +#define ADC_OFR1_OFFSET1_CH_Msk (0x1FUL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x7C000000 */ +#define ADC_OFR1_OFFSET1_CH ADC_OFR1_OFFSET1_CH_Msk /*!< ADC offset number 1 channel selection */ +#define ADC_OFR1_OFFSET1_CH_0 (0x01UL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x04000000 */ +#define ADC_OFR1_OFFSET1_CH_1 (0x02UL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x08000000 */ +#define ADC_OFR1_OFFSET1_CH_2 (0x04UL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x10000000 */ +#define ADC_OFR1_OFFSET1_CH_3 (0x08UL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x20000000 */ +#define ADC_OFR1_OFFSET1_CH_4 (0x10UL << ADC_OFR1_OFFSET1_CH_Pos) /*!< 0x40000000 */ + +#define ADC_OFR1_OFFSET1_EN_Pos (31U) +#define ADC_OFR1_OFFSET1_EN_Msk (0x1UL << ADC_OFR1_OFFSET1_EN_Pos) /*!< 0x80000000 */ +#define ADC_OFR1_OFFSET1_EN ADC_OFR1_OFFSET1_EN_Msk /*!< ADC offset number 1 enable */ + +/******************** Bit definition for ADC_OFR2 register ******************/ +#define ADC_OFR2_OFFSET2_Pos (0U) +#define ADC_OFR2_OFFSET2_Msk (0xFFFUL << ADC_OFR2_OFFSET2_Pos) /*!< 0x00000FFF */ +#define ADC_OFR2_OFFSET2 ADC_OFR2_OFFSET2_Msk /*!< ADC offset number 2 offset level */ + +#define ADC_OFR2_OFFSETPOS_Pos (24U) +#define ADC_OFR2_OFFSETPOS_Msk (0x1UL << ADC_OFR2_OFFSETPOS_Pos) /*!< 0x01000000 */ +#define ADC_OFR2_OFFSETPOS ADC_OFR2_OFFSETPOS_Msk /*!< ADC offset number 2 positive */ +#define ADC_OFR2_SATEN_Pos (25U) +#define ADC_OFR2_SATEN_Msk (0x1UL << ADC_OFR2_SATEN_Pos) /*!< 0x02000000 */ +#define ADC_OFR2_SATEN ADC_OFR2_SATEN_Msk /*!< ADC offset number 2 saturation enable */ + +#define ADC_OFR2_OFFSET2_CH_Pos (26U) +#define ADC_OFR2_OFFSET2_CH_Msk (0x1FUL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x7C000000 */ +#define ADC_OFR2_OFFSET2_CH ADC_OFR2_OFFSET2_CH_Msk /*!< ADC offset number 2 channel selection */ +#define ADC_OFR2_OFFSET2_CH_0 (0x01UL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x04000000 */ +#define ADC_OFR2_OFFSET2_CH_1 (0x02UL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x08000000 */ +#define ADC_OFR2_OFFSET2_CH_2 (0x04UL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x10000000 */ +#define ADC_OFR2_OFFSET2_CH_3 (0x08UL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x20000000 */ +#define ADC_OFR2_OFFSET2_CH_4 (0x10UL << ADC_OFR2_OFFSET2_CH_Pos) /*!< 0x40000000 */ + +#define ADC_OFR2_OFFSET2_EN_Pos (31U) +#define ADC_OFR2_OFFSET2_EN_Msk (0x1UL << ADC_OFR2_OFFSET2_EN_Pos) /*!< 0x80000000 */ +#define ADC_OFR2_OFFSET2_EN ADC_OFR2_OFFSET2_EN_Msk /*!< ADC offset number 2 enable */ + +/******************** Bit definition for ADC_OFR3 register ******************/ +#define ADC_OFR3_OFFSET3_Pos (0U) +#define ADC_OFR3_OFFSET3_Msk (0xFFFUL << ADC_OFR3_OFFSET3_Pos) /*!< 0x00000FFF */ +#define ADC_OFR3_OFFSET3 ADC_OFR3_OFFSET3_Msk /*!< ADC offset number 3 offset level */ + +#define ADC_OFR3_OFFSETPOS_Pos (24U) +#define ADC_OFR3_OFFSETPOS_Msk (0x1UL << ADC_OFR3_OFFSETPOS_Pos) /*!< 0x01000000 */ +#define ADC_OFR3_OFFSETPOS ADC_OFR3_OFFSETPOS_Msk /*!< ADC offset number 3 positive */ +#define ADC_OFR3_SATEN_Pos (25U) +#define ADC_OFR3_SATEN_Msk (0x1UL << ADC_OFR3_SATEN_Pos) /*!< 0x02000000 */ +#define ADC_OFR3_SATEN ADC_OFR3_SATEN_Msk /*!< ADC offset number 3 saturation enable */ + +#define ADC_OFR3_OFFSET3_CH_Pos (26U) +#define ADC_OFR3_OFFSET3_CH_Msk (0x1FUL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x7C000000 */ +#define ADC_OFR3_OFFSET3_CH ADC_OFR3_OFFSET3_CH_Msk /*!< ADC offset number 3 channel selection */ +#define ADC_OFR3_OFFSET3_CH_0 (0x01UL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x04000000 */ +#define ADC_OFR3_OFFSET3_CH_1 (0x02UL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x08000000 */ +#define ADC_OFR3_OFFSET3_CH_2 (0x04UL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x10000000 */ +#define ADC_OFR3_OFFSET3_CH_3 (0x08UL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x20000000 */ +#define ADC_OFR3_OFFSET3_CH_4 (0x10UL << ADC_OFR3_OFFSET3_CH_Pos) /*!< 0x40000000 */ + +#define ADC_OFR3_OFFSET3_EN_Pos (31U) +#define ADC_OFR3_OFFSET3_EN_Msk (0x1UL << ADC_OFR3_OFFSET3_EN_Pos) /*!< 0x80000000 */ +#define ADC_OFR3_OFFSET3_EN ADC_OFR3_OFFSET3_EN_Msk /*!< ADC offset number 3 enable */ + +/******************** Bit definition for ADC_OFR4 register ******************/ +#define ADC_OFR4_OFFSET4_Pos (0U) +#define ADC_OFR4_OFFSET4_Msk (0xFFFUL << ADC_OFR4_OFFSET4_Pos) /*!< 0x00000FFF */ +#define ADC_OFR4_OFFSET4 ADC_OFR4_OFFSET4_Msk /*!< ADC offset number 4 offset level */ + +#define ADC_OFR4_OFFSETPOS_Pos (24U) +#define ADC_OFR4_OFFSETPOS_Msk (0x1UL << ADC_OFR4_OFFSETPOS_Pos) /*!< 0x01000000 */ +#define ADC_OFR4_OFFSETPOS ADC_OFR4_OFFSETPOS_Msk /*!< ADC offset number 4 positive */ +#define ADC_OFR4_SATEN_Pos (25U) +#define ADC_OFR4_SATEN_Msk (0x1UL << ADC_OFR4_SATEN_Pos) /*!< 0x02000000 */ +#define ADC_OFR4_SATEN ADC_OFR4_SATEN_Msk /*!< ADC offset number 4 saturation enable */ + +#define ADC_OFR4_OFFSET4_CH_Pos (26U) +#define ADC_OFR4_OFFSET4_CH_Msk (0x1FUL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x7C000000 */ +#define ADC_OFR4_OFFSET4_CH ADC_OFR4_OFFSET4_CH_Msk /*!< ADC offset number 4 channel selection */ +#define ADC_OFR4_OFFSET4_CH_0 (0x01UL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x04000000 */ +#define ADC_OFR4_OFFSET4_CH_1 (0x02UL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x08000000 */ +#define ADC_OFR4_OFFSET4_CH_2 (0x04UL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x10000000 */ +#define ADC_OFR4_OFFSET4_CH_3 (0x08UL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x20000000 */ +#define ADC_OFR4_OFFSET4_CH_4 (0x10UL << ADC_OFR4_OFFSET4_CH_Pos) /*!< 0x40000000 */ + +#define ADC_OFR4_OFFSET4_EN_Pos (31U) +#define ADC_OFR4_OFFSET4_EN_Msk (0x1UL << ADC_OFR4_OFFSET4_EN_Pos) /*!< 0x80000000 */ +#define ADC_OFR4_OFFSET4_EN ADC_OFR4_OFFSET4_EN_Msk /*!< ADC offset number 4 enable */ + +/******************** Bit definition for ADC_JDR1 register ******************/ +#define ADC_JDR1_JDATA_Pos (0U) +#define ADC_JDR1_JDATA_Msk (0xFFFFUL << ADC_JDR1_JDATA_Pos) /*!< 0x0000FFFF */ +#define ADC_JDR1_JDATA ADC_JDR1_JDATA_Msk /*!< ADC group injected sequencer rank 1 conversion data */ + +/******************** Bit definition for ADC_JDR2 register ******************/ +#define ADC_JDR2_JDATA_Pos (0U) +#define ADC_JDR2_JDATA_Msk (0xFFFFUL << ADC_JDR2_JDATA_Pos) /*!< 0x0000FFFF */ +#define ADC_JDR2_JDATA ADC_JDR2_JDATA_Msk /*!< ADC group injected sequencer rank 2 conversion data */ + +/******************** Bit definition for ADC_JDR3 register ******************/ +#define ADC_JDR3_JDATA_Pos (0U) +#define ADC_JDR3_JDATA_Msk (0xFFFFUL << ADC_JDR3_JDATA_Pos) /*!< 0x0000FFFF */ +#define ADC_JDR3_JDATA ADC_JDR3_JDATA_Msk /*!< ADC group injected sequencer rank 3 conversion data */ + +/******************** Bit definition for ADC_JDR4 register ******************/ +#define ADC_JDR4_JDATA_Pos (0U) +#define ADC_JDR4_JDATA_Msk (0xFFFFUL << ADC_JDR4_JDATA_Pos) /*!< 0x0000FFFF */ +#define ADC_JDR4_JDATA ADC_JDR4_JDATA_Msk /*!< ADC group injected sequencer rank 4 conversion data */ + +/******************** Bit definition for ADC_AWD2CR register ****************/ +#define ADC_AWD2CR_AWD2CH_Pos (0U) +#define ADC_AWD2CR_AWD2CH_Msk (0xFFFFFUL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x0007FFFF */ +#define ADC_AWD2CR_AWD2CH ADC_AWD2CR_AWD2CH_Msk /*!< ADC analog watchdog 2 monitored channel selection */ +#define ADC_AWD2CR_AWD2CH_0 (0x00001UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000001 */ +#define ADC_AWD2CR_AWD2CH_1 (0x00002UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000002 */ +#define ADC_AWD2CR_AWD2CH_2 (0x00004UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000004 */ +#define ADC_AWD2CR_AWD2CH_3 (0x00008UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000008 */ +#define ADC_AWD2CR_AWD2CH_4 (0x00010UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000010 */ +#define ADC_AWD2CR_AWD2CH_5 (0x00020UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000020 */ +#define ADC_AWD2CR_AWD2CH_6 (0x00040UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000040 */ +#define ADC_AWD2CR_AWD2CH_7 (0x00080UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000080 */ +#define ADC_AWD2CR_AWD2CH_8 (0x00100UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000100 */ +#define ADC_AWD2CR_AWD2CH_9 (0x00200UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000200 */ +#define ADC_AWD2CR_AWD2CH_10 (0x00400UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000400 */ +#define ADC_AWD2CR_AWD2CH_11 (0x00800UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00000800 */ +#define ADC_AWD2CR_AWD2CH_12 (0x01000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00001000 */ +#define ADC_AWD2CR_AWD2CH_13 (0x02000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00002000 */ +#define ADC_AWD2CR_AWD2CH_14 (0x04000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00004000 */ +#define ADC_AWD2CR_AWD2CH_15 (0x08000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00008000 */ +#define ADC_AWD2CR_AWD2CH_16 (0x10000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00010000 */ +#define ADC_AWD2CR_AWD2CH_17 (0x20000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00020000 */ +#define ADC_AWD2CR_AWD2CH_18 (0x40000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00040000 */ +#define ADC_AWD2CR_AWD2CH_19 (0x80000UL << ADC_AWD2CR_AWD2CH_Pos) /*!< 0x00080000 */ + +/******************** Bit definition for ADC_AWD3CR register ****************/ +#define ADC_AWD3CR_AWD3CH_Pos (0U) +#define ADC_AWD3CR_AWD3CH_Msk (0xFFFFFUL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x0007FFFF */ +#define ADC_AWD3CR_AWD3CH ADC_AWD3CR_AWD3CH_Msk /*!< ADC analog watchdog 3 monitored channel selection */ +#define ADC_AWD3CR_AWD3CH_0 (0x00001UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000001 */ +#define ADC_AWD3CR_AWD3CH_1 (0x00002UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000002 */ +#define ADC_AWD3CR_AWD3CH_2 (0x00004UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000004 */ +#define ADC_AWD3CR_AWD3CH_3 (0x00008UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000008 */ +#define ADC_AWD3CR_AWD3CH_4 (0x00010UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000010 */ +#define ADC_AWD3CR_AWD3CH_5 (0x00020UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000020 */ +#define ADC_AWD3CR_AWD3CH_6 (0x00040UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000040 */ +#define ADC_AWD3CR_AWD3CH_7 (0x00080UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000080 */ +#define ADC_AWD3CR_AWD3CH_8 (0x00100UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000100 */ +#define ADC_AWD3CR_AWD3CH_9 (0x00200UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000200 */ +#define ADC_AWD3CR_AWD3CH_10 (0x00400UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000400 */ +#define ADC_AWD3CR_AWD3CH_11 (0x00800UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00000800 */ +#define ADC_AWD3CR_AWD3CH_12 (0x01000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00001000 */ +#define ADC_AWD3CR_AWD3CH_13 (0x02000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00002000 */ +#define ADC_AWD3CR_AWD3CH_14 (0x04000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00004000 */ +#define ADC_AWD3CR_AWD3CH_15 (0x08000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00008000 */ +#define ADC_AWD3CR_AWD3CH_16 (0x10000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00010000 */ +#define ADC_AWD3CR_AWD3CH_17 (0x20000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00020000 */ +#define ADC_AWD3CR_AWD3CH_18 (0x40000UL << ADC_AWD3CR_AWD3CH_Pos) /*!< 0x00040000 */ +#define ADC_AWD3CR_AWD2CH_19 (0x80000UL << ADC_AWD3CR_AWD2CH_Pos) /*!< 0x00080000 */ + +/******************** Bit definition for ADC_DIFSEL register ****************/ +#define ADC_DIFSEL_DIFSEL_Pos (0U) +#define ADC_DIFSEL_DIFSEL_Msk (0xFFFFFUL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x0007FFFF */ +#define ADC_DIFSEL_DIFSEL ADC_DIFSEL_DIFSEL_Msk /*!< ADC channel differential or single-ended mode */ +#define ADC_DIFSEL_DIFSEL_0 (0x00001UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000001 */ +#define ADC_DIFSEL_DIFSEL_1 (0x00002UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000002 */ +#define ADC_DIFSEL_DIFSEL_2 (0x00004UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000004 */ +#define ADC_DIFSEL_DIFSEL_3 (0x00008UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000008 */ +#define ADC_DIFSEL_DIFSEL_4 (0x00010UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000010 */ +#define ADC_DIFSEL_DIFSEL_5 (0x00020UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000020 */ +#define ADC_DIFSEL_DIFSEL_6 (0x00040UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000040 */ +#define ADC_DIFSEL_DIFSEL_7 (0x00080UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000080 */ +#define ADC_DIFSEL_DIFSEL_8 (0x00100UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000100 */ +#define ADC_DIFSEL_DIFSEL_9 (0x00200UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000200 */ +#define ADC_DIFSEL_DIFSEL_10 (0x00400UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000400 */ +#define ADC_DIFSEL_DIFSEL_11 (0x00800UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00000800 */ +#define ADC_DIFSEL_DIFSEL_12 (0x01000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00001000 */ +#define ADC_DIFSEL_DIFSEL_13 (0x02000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00002000 */ +#define ADC_DIFSEL_DIFSEL_14 (0x04000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00004000 */ +#define ADC_DIFSEL_DIFSEL_15 (0x08000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00008000 */ +#define ADC_DIFSEL_DIFSEL_16 (0x10000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00010000 */ +#define ADC_DIFSEL_DIFSEL_17 (0x20000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00020000 */ +#define ADC_DIFSEL_DIFSEL_18 (0x40000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00040000 */ +#define ADC_DIFSEL_DIFSEL_19 (0x80000UL << ADC_DIFSEL_DIFSEL_Pos) /*!< 0x00080000 */ + +/******************** Bit definition for ADC_CALFACT register ***************/ +#define ADC_CALFACT_CALFACT_S_Pos (0U) +#define ADC_CALFACT_CALFACT_S_Msk (0x7FUL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x0000007F */ +#define ADC_CALFACT_CALFACT_S ADC_CALFACT_CALFACT_S_Msk /*!< ADC calibration factor in single-ended mode */ +#define ADC_CALFACT_CALFACT_S_0 (0x01UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000001 */ +#define ADC_CALFACT_CALFACT_S_1 (0x02UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000002 */ +#define ADC_CALFACT_CALFACT_S_2 (0x04UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000004 */ +#define ADC_CALFACT_CALFACT_S_3 (0x08UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000008 */ +#define ADC_CALFACT_CALFACT_S_4 (0x10UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000010 */ +#define ADC_CALFACT_CALFACT_S_5 (0x20UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000020 */ +#define ADC_CALFACT_CALFACT_S_6 (0x40UL << ADC_CALFACT_CALFACT_S_Pos) /*!< 0x00000030 */ + +#define ADC_CALFACT_CALFACT_D_Pos (16U) +#define ADC_CALFACT_CALFACT_D_Msk (0x7FUL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x007F0000 */ +#define ADC_CALFACT_CALFACT_D ADC_CALFACT_CALFACT_D_Msk /*!< ADC calibration factor in differential mode */ +#define ADC_CALFACT_CALFACT_D_0 (0x01UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00010000 */ +#define ADC_CALFACT_CALFACT_D_1 (0x02UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00020000 */ +#define ADC_CALFACT_CALFACT_D_2 (0x04UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00040000 */ +#define ADC_CALFACT_CALFACT_D_3 (0x08UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00080000 */ +#define ADC_CALFACT_CALFACT_D_4 (0x10UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00100000 */ +#define ADC_CALFACT_CALFACT_D_5 (0x20UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00200000 */ +#define ADC_CALFACT_CALFACT_D_6 (0x40UL << ADC_CALFACT_CALFACT_D_Pos) /*!< 0x00300000 */ + +/******************** Bit definition for ADC_OR register *****************/ +#define ADC_OR_OP0_Pos (0U) +#define ADC_OR_OP0_Msk (0x01UL << ADC_OR_OP0_Pos) /*!< 0x00000001 */ +#define ADC_OR_OP0 ADC_OR_OP0_Msk /*!< ADC Option bit 0 */ +#define ADC_OR_OP1_Pos (1U) +#define ADC_OR_OP1_Msk (0x01UL << ADC_OR_OP1_Pos) /*!< 0x00000001 */ +#define ADC_OR_OP1 ADC_OR_OP1_Msk /*!< ADC Option bit 1 */ + +/************************* ADC Common registers *****************************/ +/******************** Bit definition for ADC_CSR register *******************/ +#define ADC_CSR_ADRDY_MST_Pos (0U) +#define ADC_CSR_ADRDY_MST_Msk (0x1UL << ADC_CSR_ADRDY_MST_Pos) /*!< 0x00000001 */ +#define ADC_CSR_ADRDY_MST ADC_CSR_ADRDY_MST_Msk /*!< ADC multimode master ready flag */ +#define ADC_CSR_EOSMP_MST_Pos (1U) +#define ADC_CSR_EOSMP_MST_Msk (0x1UL << ADC_CSR_EOSMP_MST_Pos) /*!< 0x00000002 */ +#define ADC_CSR_EOSMP_MST ADC_CSR_EOSMP_MST_Msk /*!< ADC multimode master group regular end of sampling flag */ +#define ADC_CSR_EOC_MST_Pos (2U) +#define ADC_CSR_EOC_MST_Msk (0x1UL << ADC_CSR_EOC_MST_Pos) /*!< 0x00000004 */ +#define ADC_CSR_EOC_MST ADC_CSR_EOC_MST_Msk /*!< ADC multimode master group regular end of unitary conversion flag */ +#define ADC_CSR_EOS_MST_Pos (3U) +#define ADC_CSR_EOS_MST_Msk (0x1UL << ADC_CSR_EOS_MST_Pos) /*!< 0x00000008 */ +#define ADC_CSR_EOS_MST ADC_CSR_EOS_MST_Msk /*!< ADC multimode master group regular end of sequence conversions flag */ +#define ADC_CSR_OVR_MST_Pos (4U) +#define ADC_CSR_OVR_MST_Msk (0x1UL << ADC_CSR_OVR_MST_Pos) /*!< 0x00000010 */ +#define ADC_CSR_OVR_MST ADC_CSR_OVR_MST_Msk /*!< ADC multimode master group regular overrun flag */ +#define ADC_CSR_JEOC_MST_Pos (5U) +#define ADC_CSR_JEOC_MST_Msk (0x1UL << ADC_CSR_JEOC_MST_Pos) /*!< 0x00000020 */ +#define ADC_CSR_JEOC_MST ADC_CSR_JEOC_MST_Msk /*!< ADC multimode master group injected end of unitary conversion flag */ +#define ADC_CSR_JEOS_MST_Pos (6U) +#define ADC_CSR_JEOS_MST_Msk (0x1UL << ADC_CSR_JEOS_MST_Pos) /*!< 0x00000040 */ +#define ADC_CSR_JEOS_MST ADC_CSR_JEOS_MST_Msk /*!< ADC multimode master group injected end of sequence conversions flag */ +#define ADC_CSR_AWD1_MST_Pos (7U) +#define ADC_CSR_AWD1_MST_Msk (0x1UL << ADC_CSR_AWD1_MST_Pos) /*!< 0x00000080 */ +#define ADC_CSR_AWD1_MST ADC_CSR_AWD1_MST_Msk /*!< ADC multimode master analog watchdog 1 flag */ +#define ADC_CSR_AWD2_MST_Pos (8U) +#define ADC_CSR_AWD2_MST_Msk (0x1UL << ADC_CSR_AWD2_MST_Pos) /*!< 0x00000100 */ +#define ADC_CSR_AWD2_MST ADC_CSR_AWD2_MST_Msk /*!< ADC multimode master analog watchdog 2 flag */ +#define ADC_CSR_AWD3_MST_Pos (9U) +#define ADC_CSR_AWD3_MST_Msk (0x1UL << ADC_CSR_AWD3_MST_Pos) /*!< 0x00000200 */ +#define ADC_CSR_AWD3_MST ADC_CSR_AWD3_MST_Msk /*!< ADC multimode master analog watchdog 3 flag */ +#define ADC_CSR_JQOVF_MST_Pos (10U) +#define ADC_CSR_JQOVF_MST_Msk (0x1UL << ADC_CSR_JQOVF_MST_Pos) /*!< 0x00000400 */ +#define ADC_CSR_JQOVF_MST ADC_CSR_JQOVF_MST_Msk /*!< ADC multimode master group injected contexts queue overflow flag */ + +#define ADC_CSR_ADRDY_SLV_Pos (16U) +#define ADC_CSR_ADRDY_SLV_Msk (0x1UL << ADC_CSR_ADRDY_SLV_Pos) /*!< 0x00010000 */ +#define ADC_CSR_ADRDY_SLV ADC_CSR_ADRDY_SLV_Msk /*!< ADC multimode slave ready flag */ +#define ADC_CSR_EOSMP_SLV_Pos (17U) +#define ADC_CSR_EOSMP_SLV_Msk (0x1UL << ADC_CSR_EOSMP_SLV_Pos) /*!< 0x00020000 */ +#define ADC_CSR_EOSMP_SLV ADC_CSR_EOSMP_SLV_Msk /*!< ADC multimode slave group regular end of sampling flag */ +#define ADC_CSR_EOC_SLV_Pos (18U) +#define ADC_CSR_EOC_SLV_Msk (0x1UL << ADC_CSR_EOC_SLV_Pos) /*!< 0x00040000 */ +#define ADC_CSR_EOC_SLV ADC_CSR_EOC_SLV_Msk /*!< ADC multimode slave group regular end of unitary conversion flag */ +#define ADC_CSR_EOS_SLV_Pos (19U) +#define ADC_CSR_EOS_SLV_Msk (0x1UL << ADC_CSR_EOS_SLV_Pos) /*!< 0x00080000 */ +#define ADC_CSR_EOS_SLV ADC_CSR_EOS_SLV_Msk /*!< ADC multimode slave group regular end of sequence conversions flag */ +#define ADC_CSR_OVR_SLV_Pos (20U) +#define ADC_CSR_OVR_SLV_Msk (0x1UL << ADC_CSR_OVR_SLV_Pos) /*!< 0x00100000 */ +#define ADC_CSR_OVR_SLV ADC_CSR_OVR_SLV_Msk /*!< ADC multimode slave group regular overrun flag */ +#define ADC_CSR_JEOC_SLV_Pos (21U) +#define ADC_CSR_JEOC_SLV_Msk (0x1UL << ADC_CSR_JEOC_SLV_Pos) /*!< 0x00200000 */ +#define ADC_CSR_JEOC_SLV ADC_CSR_JEOC_SLV_Msk /*!< ADC multimode slave group injected end of unitary conversion flag */ +#define ADC_CSR_JEOS_SLV_Pos (22U) +#define ADC_CSR_JEOS_SLV_Msk (0x1UL << ADC_CSR_JEOS_SLV_Pos) /*!< 0x00400000 */ +#define ADC_CSR_JEOS_SLV ADC_CSR_JEOS_SLV_Msk /*!< ADC multimode slave group injected end of sequence conversions flag */ +#define ADC_CSR_AWD1_SLV_Pos (23U) +#define ADC_CSR_AWD1_SLV_Msk (0x1UL << ADC_CSR_AWD1_SLV_Pos) /*!< 0x00800000 */ +#define ADC_CSR_AWD1_SLV ADC_CSR_AWD1_SLV_Msk /*!< ADC multimode slave analog watchdog 1 flag */ +#define ADC_CSR_AWD2_SLV_Pos (24U) +#define ADC_CSR_AWD2_SLV_Msk (0x1UL << ADC_CSR_AWD2_SLV_Pos) /*!< 0x01000000 */ +#define ADC_CSR_AWD2_SLV ADC_CSR_AWD2_SLV_Msk /*!< ADC multimode slave analog watchdog 2 flag */ +#define ADC_CSR_AWD3_SLV_Pos (25U) +#define ADC_CSR_AWD3_SLV_Msk (0x1UL << ADC_CSR_AWD3_SLV_Pos) /*!< 0x02000000 */ +#define ADC_CSR_AWD3_SLV ADC_CSR_AWD3_SLV_Msk /*!< ADC multimode slave analog watchdog 3 flag */ +#define ADC_CSR_JQOVF_SLV_Pos (26U) +#define ADC_CSR_JQOVF_SLV_Msk (0x1UL << ADC_CSR_JQOVF_SLV_Pos) /*!< 0x04000000 */ +#define ADC_CSR_JQOVF_SLV ADC_CSR_JQOVF_SLV_Msk /*!< ADC multimode slave group injected contexts queue overflow flag */ + +/******************** Bit definition for ADC_CCR register *******************/ +#define ADC_CCR_DUAL_Pos (0U) +#define ADC_CCR_DUAL_Msk (0x1FUL << ADC_CCR_DUAL_Pos) /*!< 0x0000001F */ +#define ADC_CCR_DUAL ADC_CCR_DUAL_Msk /*!< ADC multimode mode selection */ +#define ADC_CCR_DUAL_0 (0x01UL << ADC_CCR_DUAL_Pos) /*!< 0x00000001 */ +#define ADC_CCR_DUAL_1 (0x02UL << ADC_CCR_DUAL_Pos) /*!< 0x00000002 */ +#define ADC_CCR_DUAL_2 (0x04UL << ADC_CCR_DUAL_Pos) /*!< 0x00000004 */ +#define ADC_CCR_DUAL_3 (0x08UL << ADC_CCR_DUAL_Pos) /*!< 0x00000008 */ +#define ADC_CCR_DUAL_4 (0x10UL << ADC_CCR_DUAL_Pos) /*!< 0x00000010 */ + +#define ADC_CCR_DELAY_Pos (8U) +#define ADC_CCR_DELAY_Msk (0xFUL << ADC_CCR_DELAY_Pos) /*!< 0x00000F00 */ +#define ADC_CCR_DELAY ADC_CCR_DELAY_Msk /*!< ADC multimode delay between 2 sampling phases */ +#define ADC_CCR_DELAY_0 (0x1UL << ADC_CCR_DELAY_Pos) /*!< 0x00000100 */ +#define ADC_CCR_DELAY_1 (0x2UL << ADC_CCR_DELAY_Pos) /*!< 0x00000200 */ +#define ADC_CCR_DELAY_2 (0x4UL << ADC_CCR_DELAY_Pos) /*!< 0x00000400 */ +#define ADC_CCR_DELAY_3 (0x8UL << ADC_CCR_DELAY_Pos) /*!< 0x00000800 */ + +#define ADC_CCR_DMACFG_Pos (13U) +#define ADC_CCR_DMACFG_Msk (0x1UL << ADC_CCR_DMACFG_Pos) /*!< 0x00002000 */ +#define ADC_CCR_DMACFG ADC_CCR_DMACFG_Msk /*!< ADC multimode DMA transfer configuration */ + +#define ADC_CCR_MDMA_Pos (14U) +#define ADC_CCR_MDMA_Msk (0x3UL << ADC_CCR_MDMA_Pos) /*!< 0x0000C000 */ +#define ADC_CCR_MDMA ADC_CCR_MDMA_Msk /*!< ADC multimode DMA transfer enable */ +#define ADC_CCR_MDMA_0 (0x1UL << ADC_CCR_MDMA_Pos) /*!< 0x00004000 */ +#define ADC_CCR_MDMA_1 (0x2UL << ADC_CCR_MDMA_Pos) /*!< 0x00008000 */ + +#define ADC_CCR_CKMODE_Pos (16U) +#define ADC_CCR_CKMODE_Msk (0x3UL << ADC_CCR_CKMODE_Pos) /*!< 0x00030000 */ +#define ADC_CCR_CKMODE ADC_CCR_CKMODE_Msk /*!< ADC common clock source and prescaler (prescaler only for clock source synchronous) */ +#define ADC_CCR_CKMODE_0 (0x1UL << ADC_CCR_CKMODE_Pos) /*!< 0x00010000 */ +#define ADC_CCR_CKMODE_1 (0x2UL << ADC_CCR_CKMODE_Pos) /*!< 0x00020000 */ + +#define ADC_CCR_PRESC_Pos (18U) +#define ADC_CCR_PRESC_Msk (0xFUL << ADC_CCR_PRESC_Pos) /*!< 0x003C0000 */ +#define ADC_CCR_PRESC ADC_CCR_PRESC_Msk /*!< ADC common clock prescaler, only for clock source asynchronous */ +#define ADC_CCR_PRESC_0 (0x1UL << ADC_CCR_PRESC_Pos) /*!< 0x00040000 */ +#define ADC_CCR_PRESC_1 (0x2UL << ADC_CCR_PRESC_Pos) /*!< 0x00080000 */ +#define ADC_CCR_PRESC_2 (0x4UL << ADC_CCR_PRESC_Pos) /*!< 0x00100000 */ +#define ADC_CCR_PRESC_3 (0x8UL << ADC_CCR_PRESC_Pos) /*!< 0x00200000 */ + +#define ADC_CCR_VREFEN_Pos (22U) +#define ADC_CCR_VREFEN_Msk (0x1UL << ADC_CCR_VREFEN_Pos) /*!< 0x00400000 */ +#define ADC_CCR_VREFEN ADC_CCR_VREFEN_Msk /*!< ADC internal path to VrefInt enable */ +#define ADC_CCR_TSEN_Pos (23U) +#define ADC_CCR_TSEN_Msk (0x1UL << ADC_CCR_TSEN_Pos) /*!< 0x00800000 */ +#define ADC_CCR_TSEN ADC_CCR_TSEN_Msk /*!< ADC internal path to temperature sensor enable */ +#define ADC_CCR_VBATEN_Pos (24U) +#define ADC_CCR_VBATEN_Msk (0x1UL << ADC_CCR_VBATEN_Pos) /*!< 0x01000000 */ +#define ADC_CCR_VBATEN ADC_CCR_VBATEN_Msk /*!< ADC internal path to battery voltage enable */ + +/******************** Bit definition for ADC_CDR register *******************/ +#define ADC_CDR_RDATA_MST_Pos (0U) +#define ADC_CDR_RDATA_MST_Msk (0xFFFFUL << ADC_CDR_RDATA_MST_Pos) /*!< 0x0000FFFF */ +#define ADC_CDR_RDATA_MST ADC_CDR_RDATA_MST_Msk /*!< ADC multimode master group regular conversion data */ + +#define ADC_CDR_RDATA_SLV_Pos (16U) +#define ADC_CDR_RDATA_SLV_Msk (0xFFFFUL << ADC_CDR_RDATA_SLV_Pos) /*!< 0xFFFF0000 */ +#define ADC_CDR_RDATA_SLV ADC_CDR_RDATA_SLV_Msk /*!< ADC multimode slave group regular conversion data */ + + +/******************************************************************************/ +/* */ +/* CORDIC calculation unit */ +/* */ +/******************************************************************************/ +/******************* Bit definition for CORDIC_CSR register *****************/ +#define CORDIC_CSR_FUNC_Pos (0U) +#define CORDIC_CSR_FUNC_Msk (0xFUL << CORDIC_CSR_FUNC_Pos) /*!< 0x0000000F */ +#define CORDIC_CSR_FUNC CORDIC_CSR_FUNC_Msk /*!< Function */ +#define CORDIC_CSR_FUNC_0 (0x1UL << CORDIC_CSR_FUNC_Pos) /*!< 0x00000001 */ +#define CORDIC_CSR_FUNC_1 (0x2UL << CORDIC_CSR_FUNC_Pos) /*!< 0x00000002 */ +#define CORDIC_CSR_FUNC_2 (0x4UL << CORDIC_CSR_FUNC_Pos) /*!< 0x00000004 */ +#define CORDIC_CSR_FUNC_3 (0x8UL << CORDIC_CSR_FUNC_Pos) /*!< 0x00000008 */ +#define CORDIC_CSR_PRECISION_Pos (4U) +#define CORDIC_CSR_PRECISION_Msk (0xFUL << CORDIC_CSR_PRECISION_Pos) /*!< 0x000000F0 */ +#define CORDIC_CSR_PRECISION CORDIC_CSR_PRECISION_Msk /*!< Precision */ +#define CORDIC_CSR_PRECISION_0 (0x1UL << CORDIC_CSR_PRECISION_Pos) /*!< 0x00000010 */ +#define CORDIC_CSR_PRECISION_1 (0x2UL << CORDIC_CSR_PRECISION_Pos) /*!< 0x00000020 */ +#define CORDIC_CSR_PRECISION_2 (0x4UL << CORDIC_CSR_PRECISION_Pos) /*!< 0x00000040 */ +#define CORDIC_CSR_PRECISION_3 (0x8UL << CORDIC_CSR_PRECISION_Pos) /*!< 0x00000080 */ +#define CORDIC_CSR_SCALE_Pos (8U) +#define CORDIC_CSR_SCALE_Msk (0x7UL << CORDIC_CSR_SCALE_Pos) /*!< 0x00000700 */ +#define CORDIC_CSR_SCALE CORDIC_CSR_SCALE_Msk /*!< Scaling factor */ +#define CORDIC_CSR_SCALE_0 (0x1UL << CORDIC_CSR_SCALE_Pos) /*!< 0x00000100 */ +#define CORDIC_CSR_SCALE_1 (0x2UL << CORDIC_CSR_SCALE_Pos) /*!< 0x00000200 */ +#define CORDIC_CSR_SCALE_2 (0x4UL << CORDIC_CSR_SCALE_Pos) /*!< 0x00000400 */ +#define CORDIC_CSR_IEN_Pos (16U) +#define CORDIC_CSR_IEN_Msk (0x1UL << CORDIC_CSR_IEN_Pos) /*!< 0x00010000 */ +#define CORDIC_CSR_IEN CORDIC_CSR_IEN_Msk /*!< Interrupt Enable */ +#define CORDIC_CSR_DMAREN_Pos (17U) +#define CORDIC_CSR_DMAREN_Msk (0x1UL << CORDIC_CSR_DMAREN_Pos) /*!< 0x00020000 */ +#define CORDIC_CSR_DMAREN CORDIC_CSR_DMAREN_Msk /*!< DMA Read channel Enable */ +#define CORDIC_CSR_DMAWEN_Pos (18U) +#define CORDIC_CSR_DMAWEN_Msk (0x1UL << CORDIC_CSR_DMAWEN_Pos) /*!< 0x00040000 */ +#define CORDIC_CSR_DMAWEN CORDIC_CSR_DMAWEN_Msk /*!< DMA Write channel Enable */ +#define CORDIC_CSR_NRES_Pos (19U) +#define CORDIC_CSR_NRES_Msk (0x1UL << CORDIC_CSR_NRES_Pos) /*!< 0x00080000 */ +#define CORDIC_CSR_NRES CORDIC_CSR_NRES_Msk /*!< Number of results in WDATA register */ +#define CORDIC_CSR_NARGS_Pos (20U) +#define CORDIC_CSR_NARGS_Msk (0x1UL << CORDIC_CSR_NARGS_Pos) /*!< 0x00100000 */ +#define CORDIC_CSR_NARGS CORDIC_CSR_NARGS_Msk /*!< Number of arguments in RDATA register */ +#define CORDIC_CSR_RESSIZE_Pos (21U) +#define CORDIC_CSR_RESSIZE_Msk (0x1UL << CORDIC_CSR_RESSIZE_Pos) /*!< 0x00200000 */ +#define CORDIC_CSR_RESSIZE CORDIC_CSR_RESSIZE_Msk /*!< Width of output data */ +#define CORDIC_CSR_ARGSIZE_Pos (22U) +#define CORDIC_CSR_ARGSIZE_Msk (0x1UL << CORDIC_CSR_ARGSIZE_Pos) /*!< 0x00400000 */ +#define CORDIC_CSR_ARGSIZE CORDIC_CSR_ARGSIZE_Msk /*!< Width of input data */ +#define CORDIC_CSR_RRDY_Pos (31U) +#define CORDIC_CSR_RRDY_Msk (0x1UL << CORDIC_CSR_RRDY_Pos) /*!< 0x80000000 */ +#define CORDIC_CSR_RRDY CORDIC_CSR_RRDY_Msk /*!< Result Ready Flag */ + +/******************* Bit definition for CORDIC_WDATA register ***************/ +#define CORDIC_WDATA_ARG_Pos (0U) +#define CORDIC_WDATA_ARG_Msk (0xFFFFFFFFUL << CORDIC_WDATA_ARG_Pos) /*!< 0xFFFFFFFF */ +#define CORDIC_WDATA_ARG CORDIC_WDATA_ARG_Msk /*!< Input Argument */ + +/******************* Bit definition for CORDIC_RDATA register ***************/ +#define CORDIC_RDATA_RES_Pos (0U) +#define CORDIC_RDATA_RES_Msk (0xFFFFFFFFUL << CORDIC_RDATA_RES_Pos) /*!< 0xFFFFFFFF */ +#define CORDIC_RDATA_RES CORDIC_RDATA_RES_Msk /*!< Output Result */ + +/******************************************************************************/ +/* */ +/* CRC calculation unit */ +/* */ +/******************************************************************************/ +/******************* Bit definition for CRC_DR register *********************/ +#define CRC_DR_DR_Pos (0U) +#define CRC_DR_DR_Msk (0xFFFFFFFFUL << CRC_DR_DR_Pos) /*!< 0xFFFFFFFF */ +#define CRC_DR_DR CRC_DR_DR_Msk /*!< Data register bits */ + +/******************* Bit definition for CRC_IDR register ********************/ +#define CRC_IDR_IDR_Pos (0U) +#define CRC_IDR_IDR_Msk (0xFFFFFFFFUL << CRC_IDR_IDR_Pos) /*!< 0xFFFFFFFF */ +#define CRC_IDR_IDR CRC_IDR_IDR_Msk /*!< General-purpose 32-bits data register bits */ + +/******************** Bit definition for CRC_CR register ********************/ +#define CRC_CR_RESET_Pos (0U) +#define CRC_CR_RESET_Msk (0x1UL << CRC_CR_RESET_Pos) /*!< 0x00000001 */ +#define CRC_CR_RESET CRC_CR_RESET_Msk /*!< RESET the CRC computation unit bit */ +#define CRC_CR_POLYSIZE_Pos (3U) +#define CRC_CR_POLYSIZE_Msk (0x3UL << CRC_CR_POLYSIZE_Pos) /*!< 0x00000018 */ +#define CRC_CR_POLYSIZE CRC_CR_POLYSIZE_Msk /*!< Polynomial size bits */ +#define CRC_CR_POLYSIZE_0 (0x1UL << CRC_CR_POLYSIZE_Pos) /*!< 0x00000008 */ +#define CRC_CR_POLYSIZE_1 (0x2UL << CRC_CR_POLYSIZE_Pos) /*!< 0x00000010 */ +#define CRC_CR_REV_IN_Pos (5U) +#define CRC_CR_REV_IN_Msk (0x3UL << CRC_CR_REV_IN_Pos) /*!< 0x00000060 */ +#define CRC_CR_REV_IN CRC_CR_REV_IN_Msk /*!< REV_IN Reverse Input Data bits */ +#define CRC_CR_REV_IN_0 (0x1UL << CRC_CR_REV_IN_Pos) /*!< 0x00000020 */ +#define CRC_CR_REV_IN_1 (0x2UL << CRC_CR_REV_IN_Pos) /*!< 0x00000040 */ +#define CRC_CR_REV_OUT_Pos (7U) +#define CRC_CR_REV_OUT_Msk (0x1UL << CRC_CR_REV_OUT_Pos) /*!< 0x00000080 */ +#define CRC_CR_REV_OUT CRC_CR_REV_OUT_Msk /*!< REV_OUT Reverse Output Data bits */ + +/******************* Bit definition for CRC_INIT register *******************/ +#define CRC_INIT_INIT_Pos (0U) +#define CRC_INIT_INIT_Msk (0xFFFFFFFFUL << CRC_INIT_INIT_Pos) /*!< 0xFFFFFFFF */ +#define CRC_INIT_INIT CRC_INIT_INIT_Msk /*!< Initial CRC value bits */ + +/******************* Bit definition for CRC_POL register ********************/ +#define CRC_POL_POL_Pos (0U) +#define CRC_POL_POL_Msk (0xFFFFFFFFUL << CRC_POL_POL_Pos) /*!< 0xFFFFFFFF */ +#define CRC_POL_POL CRC_POL_POL_Msk /*!< Coefficients of the polynomial */ + + +/******************************************************************************/ +/* */ +/* CRS Clock Recovery System */ +/******************************************************************************/ +/******************* Bit definition for CRS_CR register *********************/ +#define CRS_CR_SYNCOKIE_Pos (0U) +#define CRS_CR_SYNCOKIE_Msk (0x1UL << CRS_CR_SYNCOKIE_Pos) /*!< 0x00000001 */ +#define CRS_CR_SYNCOKIE CRS_CR_SYNCOKIE_Msk /*!< SYNC event OK interrupt enable */ +#define CRS_CR_SYNCWARNIE_Pos (1U) +#define CRS_CR_SYNCWARNIE_Msk (0x1UL << CRS_CR_SYNCWARNIE_Pos) /*!< 0x00000002 */ +#define CRS_CR_SYNCWARNIE CRS_CR_SYNCWARNIE_Msk /*!< SYNC warning interrupt enable */ +#define CRS_CR_ERRIE_Pos (2U) +#define CRS_CR_ERRIE_Msk (0x1UL << CRS_CR_ERRIE_Pos) /*!< 0x00000004 */ +#define CRS_CR_ERRIE CRS_CR_ERRIE_Msk /*!< SYNC error or trimming error interrupt enable */ +#define CRS_CR_ESYNCIE_Pos (3U) +#define CRS_CR_ESYNCIE_Msk (0x1UL << CRS_CR_ESYNCIE_Pos) /*!< 0x00000008 */ +#define CRS_CR_ESYNCIE CRS_CR_ESYNCIE_Msk /*!< Expected SYNC interrupt enable */ +#define CRS_CR_CEN_Pos (5U) +#define CRS_CR_CEN_Msk (0x1UL << CRS_CR_CEN_Pos) /*!< 0x00000020 */ +#define CRS_CR_CEN CRS_CR_CEN_Msk /*!< Frequency error counter enable */ +#define CRS_CR_AUTOTRIMEN_Pos (6U) +#define CRS_CR_AUTOTRIMEN_Msk (0x1UL << CRS_CR_AUTOTRIMEN_Pos) /*!< 0x00000040 */ +#define CRS_CR_AUTOTRIMEN CRS_CR_AUTOTRIMEN_Msk /*!< Automatic trimming enable */ +#define CRS_CR_SWSYNC_Pos (7U) +#define CRS_CR_SWSYNC_Msk (0x1UL << CRS_CR_SWSYNC_Pos) /*!< 0x00000080 */ +#define CRS_CR_SWSYNC CRS_CR_SWSYNC_Msk /*!< Generate software SYNC event */ +#define CRS_CR_TRIM_Pos (8U) +#define CRS_CR_TRIM_Msk (0x3FUL << CRS_CR_TRIM_Pos) /*!< 0x00003F00 */ +#define CRS_CR_TRIM CRS_CR_TRIM_Msk /*!< HSI48 oscillator smooth trimming */ + +/******************* Bit definition for CRS_CFGR register *********************/ +#define CRS_CFGR_RELOAD_Pos (0U) +#define CRS_CFGR_RELOAD_Msk (0xFFFFUL << CRS_CFGR_RELOAD_Pos) /*!< 0x0000FFFF */ +#define CRS_CFGR_RELOAD CRS_CFGR_RELOAD_Msk /*!< Counter reload value */ +#define CRS_CFGR_FELIM_Pos (16U) +#define CRS_CFGR_FELIM_Msk (0xFFUL << CRS_CFGR_FELIM_Pos) /*!< 0x00FF0000 */ +#define CRS_CFGR_FELIM CRS_CFGR_FELIM_Msk /*!< Frequency error limit */ +#define CRS_CFGR_SYNCDIV_Pos (24U) +#define CRS_CFGR_SYNCDIV_Msk (0x7UL << CRS_CFGR_SYNCDIV_Pos) /*!< 0x07000000 */ +#define CRS_CFGR_SYNCDIV CRS_CFGR_SYNCDIV_Msk /*!< SYNC divider */ +#define CRS_CFGR_SYNCDIV_0 (0x1UL << CRS_CFGR_SYNCDIV_Pos) /*!< 0x01000000 */ +#define CRS_CFGR_SYNCDIV_1 (0x2UL << CRS_CFGR_SYNCDIV_Pos) /*!< 0x02000000 */ +#define CRS_CFGR_SYNCDIV_2 (0x4UL << CRS_CFGR_SYNCDIV_Pos) /*!< 0x04000000 */ +#define CRS_CFGR_SYNCSRC_Pos (28U) +#define CRS_CFGR_SYNCSRC_Msk (0x3UL << CRS_CFGR_SYNCSRC_Pos) /*!< 0x30000000 */ +#define CRS_CFGR_SYNCSRC CRS_CFGR_SYNCSRC_Msk /*!< SYNC signal source selection */ +#define CRS_CFGR_SYNCSRC_0 (0x1UL << CRS_CFGR_SYNCSRC_Pos) /*!< 0x10000000 */ +#define CRS_CFGR_SYNCSRC_1 (0x2UL << CRS_CFGR_SYNCSRC_Pos) /*!< 0x20000000 */ +#define CRS_CFGR_SYNCPOL_Pos (31U) +#define CRS_CFGR_SYNCPOL_Msk (0x1UL << CRS_CFGR_SYNCPOL_Pos) /*!< 0x80000000 */ +#define CRS_CFGR_SYNCPOL CRS_CFGR_SYNCPOL_Msk /*!< SYNC polarity selection */ + +/******************* Bit definition for CRS_ISR register *********************/ +#define CRS_ISR_SYNCOKF_Pos (0U) +#define CRS_ISR_SYNCOKF_Msk (0x1UL << CRS_ISR_SYNCOKF_Pos) /*!< 0x00000001 */ +#define CRS_ISR_SYNCOKF CRS_ISR_SYNCOKF_Msk /*!< SYNC event OK flag */ +#define CRS_ISR_SYNCWARNF_Pos (1U) +#define CRS_ISR_SYNCWARNF_Msk (0x1UL << CRS_ISR_SYNCWARNF_Pos) /*!< 0x00000002 */ +#define CRS_ISR_SYNCWARNF CRS_ISR_SYNCWARNF_Msk /*!< SYNC warning flag */ +#define CRS_ISR_ERRF_Pos (2U) +#define CRS_ISR_ERRF_Msk (0x1UL << CRS_ISR_ERRF_Pos) /*!< 0x00000004 */ +#define CRS_ISR_ERRF CRS_ISR_ERRF_Msk /*!< Error flag */ +#define CRS_ISR_ESYNCF_Pos (3U) +#define CRS_ISR_ESYNCF_Msk (0x1UL << CRS_ISR_ESYNCF_Pos) /*!< 0x00000008 */ +#define CRS_ISR_ESYNCF CRS_ISR_ESYNCF_Msk /*!< Expected SYNC flag */ +#define CRS_ISR_SYNCERR_Pos (8U) +#define CRS_ISR_SYNCERR_Msk (0x1UL << CRS_ISR_SYNCERR_Pos) /*!< 0x00000100 */ +#define CRS_ISR_SYNCERR CRS_ISR_SYNCERR_Msk /*!< SYNC error */ +#define CRS_ISR_SYNCMISS_Pos (9U) +#define CRS_ISR_SYNCMISS_Msk (0x1UL << CRS_ISR_SYNCMISS_Pos) /*!< 0x00000200 */ +#define CRS_ISR_SYNCMISS CRS_ISR_SYNCMISS_Msk /*!< SYNC missed */ +#define CRS_ISR_TRIMOVF_Pos (10U) +#define CRS_ISR_TRIMOVF_Msk (0x1UL << CRS_ISR_TRIMOVF_Pos) /*!< 0x00000400 */ +#define CRS_ISR_TRIMOVF CRS_ISR_TRIMOVF_Msk /*!< Trimming overflow or underflow */ +#define CRS_ISR_FEDIR_Pos (15U) +#define CRS_ISR_FEDIR_Msk (0x1UL << CRS_ISR_FEDIR_Pos) /*!< 0x00008000 */ +#define CRS_ISR_FEDIR CRS_ISR_FEDIR_Msk /*!< Frequency error direction */ +#define CRS_ISR_FECAP_Pos (16U) +#define CRS_ISR_FECAP_Msk (0xFFFFUL << CRS_ISR_FECAP_Pos) /*!< 0xFFFF0000 */ +#define CRS_ISR_FECAP CRS_ISR_FECAP_Msk /*!< Frequency error capture */ + +/******************* Bit definition for CRS_ICR register *********************/ +#define CRS_ICR_SYNCOKC_Pos (0U) +#define CRS_ICR_SYNCOKC_Msk (0x1UL << CRS_ICR_SYNCOKC_Pos) /*!< 0x00000001 */ +#define CRS_ICR_SYNCOKC CRS_ICR_SYNCOKC_Msk /*!< SYNC event OK clear flag */ +#define CRS_ICR_SYNCWARNC_Pos (1U) +#define CRS_ICR_SYNCWARNC_Msk (0x1UL << CRS_ICR_SYNCWARNC_Pos) /*!< 0x00000002 */ +#define CRS_ICR_SYNCWARNC CRS_ICR_SYNCWARNC_Msk /*!< SYNC warning clear flag */ +#define CRS_ICR_ERRC_Pos (2U) +#define CRS_ICR_ERRC_Msk (0x1UL << CRS_ICR_ERRC_Pos) /*!< 0x00000004 */ +#define CRS_ICR_ERRC CRS_ICR_ERRC_Msk /*!< Error clear flag */ +#define CRS_ICR_ESYNCC_Pos (3U) +#define CRS_ICR_ESYNCC_Msk (0x1UL << CRS_ICR_ESYNCC_Pos) /*!< 0x00000008 */ +#define CRS_ICR_ESYNCC CRS_ICR_ESYNCC_Msk /*!< Expected SYNC clear flag */ + + +/******************************************************************************/ +/* */ +/* RNG */ +/* */ +/******************************************************************************/ +/******************** Bits definition for RNG_CR register *******************/ +#define RNG_CR_RNGEN_Pos (2U) +#define RNG_CR_RNGEN_Msk (0x1UL << RNG_CR_RNGEN_Pos) /*!< 0x00000004 */ +#define RNG_CR_RNGEN RNG_CR_RNGEN_Msk +#define RNG_CR_IE_Pos (3U) +#define RNG_CR_IE_Msk (0x1UL << RNG_CR_IE_Pos) /*!< 0x00000008 */ +#define RNG_CR_IE RNG_CR_IE_Msk +#define RNG_CR_CED_Pos (5U) +#define RNG_CR_CED_Msk (0x1UL << RNG_CR_CED_Pos) /*!< 0x00000020 */ +#define RNG_CR_CED RNG_CR_CED_Msk +#define RNG_CR_ARDIS_Pos (7U) +#define RNG_CR_ARDIS_Msk (0x1UL << RNG_CR_ARDIS_Pos) +#define RNG_CR_ARDIS RNG_CR_ARDIS_Msk +#define RNG_CR_RNG_CONFIG3_Pos (8U) +#define RNG_CR_RNG_CONFIG3_Msk (0xFUL << RNG_CR_RNG_CONFIG3_Pos) +#define RNG_CR_RNG_CONFIG3 RNG_CR_RNG_CONFIG3_Msk +#define RNG_CR_NISTC_Pos (12U) +#define RNG_CR_NISTC_Msk (0x1UL << RNG_CR_NISTC_Pos) +#define RNG_CR_NISTC RNG_CR_NISTC_Msk +#define RNG_CR_RNG_CONFIG2_Pos (13U) +#define RNG_CR_RNG_CONFIG2_Msk (0x7UL << RNG_CR_RNG_CONFIG2_Pos) +#define RNG_CR_RNG_CONFIG2 RNG_CR_RNG_CONFIG2_Msk +#define RNG_CR_CLKDIV_Pos (16U) +#define RNG_CR_CLKDIV_Msk (0xFUL << RNG_CR_CLKDIV_Pos) +#define RNG_CR_CLKDIV RNG_CR_CLKDIV_Msk +#define RNG_CR_CLKDIV_0 (0x1UL << RNG_CR_CLKDIV_Pos) /*!< 0x00010000 */ +#define RNG_CR_CLKDIV_1 (0x2UL << RNG_CR_CLKDIV_Pos) /*!< 0x00020000 */ +#define RNG_CR_CLKDIV_2 (0x4UL << RNG_CR_CLKDIV_Pos) /*!< 0x00040000 */ +#define RNG_CR_CLKDIV_3 (0x8UL << RNG_CR_CLKDIV_Pos) /*!< 0x00080000 */ +#define RNG_CR_RNG_CONFIG1_Pos (20U) +#define RNG_CR_RNG_CONFIG1_Msk (0x3FUL << RNG_CR_RNG_CONFIG1_Pos) +#define RNG_CR_RNG_CONFIG1 RNG_CR_RNG_CONFIG1_Msk +#define RNG_CR_CONDRST_Pos (30U) +#define RNG_CR_CONDRST_Msk (0x1UL << RNG_CR_CONDRST_Pos) +#define RNG_CR_CONDRST RNG_CR_CONDRST_Msk +#define RNG_CR_CONFIGLOCK_Pos (31U) +#define RNG_CR_CONFIGLOCK_Msk (0x1UL << RNG_CR_CONFIGLOCK_Pos) +#define RNG_CR_CONFIGLOCK RNG_CR_CONFIGLOCK_Msk + +/******************** Bits definition for RNG_SR register *******************/ +#define RNG_SR_DRDY_Pos (0U) +#define RNG_SR_DRDY_Msk (0x1UL << RNG_SR_DRDY_Pos) /*!< 0x00000001 */ +#define RNG_SR_DRDY RNG_SR_DRDY_Msk +#define RNG_SR_CECS_Pos (1U) +#define RNG_SR_CECS_Msk (0x1UL << RNG_SR_CECS_Pos) /*!< 0x00000002 */ +#define RNG_SR_CECS RNG_SR_CECS_Msk +#define RNG_SR_SECS_Pos (2U) +#define RNG_SR_SECS_Msk (0x1UL << RNG_SR_SECS_Pos) /*!< 0x00000004 */ +#define RNG_SR_SECS RNG_SR_SECS_Msk +#define RNG_SR_CEIS_Pos (5U) +#define RNG_SR_CEIS_Msk (0x1UL << RNG_SR_CEIS_Pos) /*!< 0x00000020 */ +#define RNG_SR_CEIS RNG_SR_CEIS_Msk +#define RNG_SR_SEIS_Pos (6U) +#define RNG_SR_SEIS_Msk (0x1UL << RNG_SR_SEIS_Pos) /*!< 0x00000040 */ +#define RNG_SR_SEIS RNG_SR_SEIS_Msk + +/******************** Bits definition for RNG_HTCR register *******************/ +#define RNG_HTCR_HTCFG_Pos (0U) +#define RNG_HTCR_HTCFG_Msk (0xFFFFFFFFUL << RNG_HTCR_HTCFG_Pos) /*!< 0xFFFFFFFF */ +#define RNG_HTCR_HTCFG RNG_HTCR_HTCFG_Msk + +/******************************************************************************/ +/* */ +/* Digital to Analog Converter */ +/* */ +/******************************************************************************/ +#define DAC_CHANNEL2_SUPPORT /*!< DAC feature available only on specific devices: DAC channel 2 available */ + +/******************** Bit definition for DAC_CR register ********************/ +#define DAC_CR_EN1_Pos (0U) +#define DAC_CR_EN1_Msk (0x1UL << DAC_CR_EN1_Pos) /*!< 0x00000001 */ +#define DAC_CR_EN1 DAC_CR_EN1_Msk /*!*/ +#define DAC_CR_CEN1_Pos (14U) +#define DAC_CR_CEN1_Msk (0x1UL << DAC_CR_CEN1_Pos) /*!< 0x00004000 */ +#define DAC_CR_CEN1 DAC_CR_CEN1_Msk /*!*/ +#define DAC_CR_EN2_Pos (16U) +#define DAC_CR_EN2_Msk (0x1UL << DAC_CR_EN2_Pos) /*!< 0x00010000 */ +#define DAC_CR_EN2 DAC_CR_EN2_Msk /*!*/ +#define DAC_CR_CEN2_Pos (30U) +#define DAC_CR_CEN2_Msk (0x1UL << DAC_CR_CEN2_Pos) /*!< 0x40000000 */ +#define DAC_CR_CEN2 DAC_CR_CEN2_Msk /*!*/ + +/***************** Bit definition for DAC_SWTRIGR register ******************/ +#define DAC_SWTRIGR_SWTRIG1_Pos (0U) +#define DAC_SWTRIGR_SWTRIG1_Msk (0x1UL << DAC_SWTRIGR_SWTRIG1_Pos) /*!< 0x00000001 */ +#define DAC_SWTRIGR_SWTRIG1 DAC_SWTRIGR_SWTRIG1_Msk /*!> 1U) /*!< FLASH Bank Size */ +#define FLASH_SECTOR_SIZE 0x2000U /*!< Flash Sector Size: 8 KB */ + +/******************* Bits definition for FLASH_ACR register *****************/ +#define FLASH_ACR_LATENCY_Pos (0U) +#define FLASH_ACR_LATENCY_Msk (0xFUL << FLASH_ACR_LATENCY_Pos) /*!< 0x0000000F */ +#define FLASH_ACR_LATENCY FLASH_ACR_LATENCY_Msk /*!< Latency */ +#define FLASH_ACR_LATENCY_0WS (0x00000000U) +#define FLASH_ACR_LATENCY_1WS (0x00000001U) +#define FLASH_ACR_LATENCY_2WS (0x00000002U) +#define FLASH_ACR_LATENCY_3WS (0x00000003U) +#define FLASH_ACR_LATENCY_4WS (0x00000004U) +#define FLASH_ACR_LATENCY_5WS (0x00000005U) +#define FLASH_ACR_LATENCY_6WS (0x00000006U) +#define FLASH_ACR_LATENCY_7WS (0x00000007U) +#define FLASH_ACR_LATENCY_8WS (0x00000008U) +#define FLASH_ACR_LATENCY_9WS (0x00000009U) +#define FLASH_ACR_LATENCY_10WS (0x0000000AU) +#define FLASH_ACR_LATENCY_11WS (0x0000000BU) +#define FLASH_ACR_LATENCY_12WS (0x0000000CU) +#define FLASH_ACR_LATENCY_13WS (0x0000000DU) +#define FLASH_ACR_LATENCY_14WS (0x0000000EU) +#define FLASH_ACR_LATENCY_15WS (0x0000000FU) +#define FLASH_ACR_WRHIGHFREQ_Pos (4U) +#define FLASH_ACR_WRHIGHFREQ_Msk (0x3UL << FLASH_ACR_WRHIGHFREQ_Pos) /*!< 0x00000030 */ +#define FLASH_ACR_WRHIGHFREQ FLASH_ACR_WRHIGHFREQ_Msk /*!< Flash signal delay */ +#define FLASH_ACR_WRHIGHFREQ_0 (0x1UL << FLASH_ACR_WRHIGHFREQ_Pos) /*!< 0x00000010 */ +#define FLASH_ACR_WRHIGHFREQ_1 (0x2UL << FLASH_ACR_WRHIGHFREQ_Pos) /*!< 0x00000020 */ +#define FLASH_ACR_PRFTEN_Pos (8U) +#define FLASH_ACR_PRFTEN_Msk (0x1UL << FLASH_ACR_PRFTEN_Pos) /*!< 0x00000100 */ +#define FLASH_ACR_PRFTEN FLASH_ACR_PRFTEN_Msk /*!< Prefetch enable */ + +/******************* Bits definition for FLASH_OPSR register ***************/ +#define FLASH_OPSR_ADDR_OP_Pos (0U) +#define FLASH_OPSR_ADDR_OP_Msk (0xFFFFFUL << FLASH_OPSR_ADDR_OP_Pos) /*!< 0x000FFFFF */ +#define FLASH_OPSR_ADDR_OP FLASH_OPSR_ADDR_OP_Msk /*!< Interrupted operation address */ +#define FLASH_OPSR_DATA_OP_Pos (21U) +#define FLASH_OPSR_DATA_OP_Msk (0x1UL << FLASH_OPSR_DATA_OP_Pos) /*!< 0x00200000 */ +#define FLASH_OPSR_DATA_OP FLASH_OPSR_DATA_OP_Msk /*!< Operation in Flash high-cycle data area interrupted */ +#define FLASH_OPSR_BK_OP_Pos (22U) +#define FLASH_OPSR_BK_OP_Msk (0x1UL << FLASH_OPSR_BK_OP_Pos) /*!< 0x00400000 */ +#define FLASH_OPSR_BK_OP FLASH_OPSR_BK_OP_Msk /*!< Interrupted operation bank */ +#define FLASH_OPSR_SYSF_OP_Pos (23U) +#define FLASH_OPSR_SYSF_OP_Msk (0x1UL << FLASH_OPSR_SYSF_OP_Pos) /*!< 0x00800000 */ +#define FLASH_OPSR_SYSF_OP FLASH_OPSR_SYSF_OP_Msk /*!< Operation in System Flash interrupted */ +#define FLASH_OPSR_OTP_OP_Pos (24U) +#define FLASH_OPSR_OTP_OP_Msk (0x1UL << FLASH_OPSR_OTP_OP_Pos) /*!< 0x01000000 */ +#define FLASH_OPSR_OTP_OP FLASH_OPSR_OTP_OP_Msk /*!< Operation in OTP area interrupted */ +#define FLASH_OPSR_CODE_OP_Pos (29U) +#define FLASH_OPSR_CODE_OP_Msk (0x7UL << FLASH_OPSR_CODE_OP_Pos) /*!< 0xE0000000 */ +#define FLASH_OPSR_CODE_OP FLASH_OPSR_CODE_OP_Msk /*!< Flash memory operation code */ +#define FLASH_OPSR_CODE_OP_0 (0x1UL << FLASH_OPSR_CODE_OP_Pos) /*!< 0x20000000 */ +#define FLASH_OPSR_CODE_OP_1 (0x2UL << FLASH_OPSR_CODE_OP_Pos) /*!< 0x40000000 */ +#define FLASH_OPSR_CODE_OP_2 (0x4UL << FLASH_OPSR_CODE_OP_Pos) /*!< 0x80000000 */ + +/******************* Bits definition for FLASH_OPTCR register *******************/ +#define FLASH_OPTCR_OPTLOCK_Pos (0U) +#define FLASH_OPTCR_OPTLOCK_Msk (0x1UL << FLASH_OPTCR_OPTLOCK_Pos) /*!< 0x00000001 */ +#define FLASH_OPTCR_OPTLOCK FLASH_OPTCR_OPTLOCK_Msk /*!< FLASH_OPTCR lock option configuration bit */ +#define FLASH_OPTCR_OPTSTART_Pos (1U) +#define FLASH_OPTCR_OPTSTART_Msk (0x1UL << FLASH_OPTCR_OPTSTART_Pos) /*!< 0x00000002 */ +#define FLASH_OPTCR_OPTSTART FLASH_OPTCR_OPTSTART_Msk /*!< Option byte start change option configuration bit */ +#define FLASH_OPTCR_SWAP_BANK_Pos (31U) +#define FLASH_OPTCR_SWAP_BANK_Msk (0x1UL << FLASH_OPTCR_SWAP_BANK_Pos) /*!< 0x80000000 */ +#define FLASH_OPTCR_SWAP_BANK FLASH_OPTCR_SWAP_BANK_Msk /*!< Bank swapping option configuration bit */ + +/******************* Bits definition for FLASH_SR register ***********************/ +#define FLASH_SR_BSY_Pos (0U) +#define FLASH_SR_BSY_Msk (0x1UL << FLASH_SR_BSY_Pos) /*!< 0x00000001 */ +#define FLASH_SR_BSY FLASH_SR_BSY_Msk /*!< Busy flag */ +#define FLASH_SR_WBNE_Pos (1U) +#define FLASH_SR_WBNE_Msk (0x1UL << FLASH_SR_WBNE_Pos) /*!< 0x00000002 */ +#define FLASH_SR_WBNE FLASH_SR_WBNE_Msk /*!< Write buffer not empty flag */ +#define FLASH_SR_DBNE_Pos (3U) +#define FLASH_SR_DBNE_Msk (0x1UL << FLASH_SR_DBNE_Pos) /*!< 0x00000008 */ +#define FLASH_SR_DBNE FLASH_SR_DBNE_Msk /*!< Data buffer not empty flag */ +#define FLASH_SR_EOP_Pos (16U) +#define FLASH_SR_EOP_Msk (0x1UL << FLASH_SR_EOP_Pos) /*!< 0x00010000 */ +#define FLASH_SR_EOP FLASH_SR_EOP_Msk /*!< End-of-program flag */ +#define FLASH_SR_WRPERR_Pos (17U) +#define FLASH_SR_WRPERR_Msk (0x1UL << FLASH_SR_WRPERR_Pos) /*!< 0x00020000 */ +#define FLASH_SR_WRPERR FLASH_SR_WRPERR_Msk /*!< Write protection error flag */ +#define FLASH_SR_PGSERR_Pos (18U) +#define FLASH_SR_PGSERR_Msk (0x1UL << FLASH_SR_PGSERR_Pos) /*!< 0x00040000 */ +#define FLASH_SR_PGSERR FLASH_SR_PGSERR_Msk /*!< Programming sequence error flag */ +#define FLASH_SR_STRBERR_Pos (19U) +#define FLASH_SR_STRBERR_Msk (0x1UL << FLASH_SR_STRBERR_Pos) /*!< 0x00080000 */ +#define FLASH_SR_STRBERR FLASH_SR_STRBERR_Msk /*!< Strobe error flag */ +#define FLASH_SR_INCERR_Pos (20U) +#define FLASH_SR_INCERR_Msk (0x1UL << FLASH_SR_INCERR_Pos) /*!< 0x00100000 */ +#define FLASH_SR_INCERR FLASH_SR_INCERR_Msk /*!< Inconsistency error flag */ +#define FLASH_SR_OBKERR_Pos (21U) +#define FLASH_SR_OBKERR_Msk (0x1UL << FLASH_SR_OBKERR_Pos) /*!< 0x00200000 */ +#define FLASH_SR_OBKERR FLASH_SR_OBKERR_Msk /*!< OBK general error flag */ +#define FLASH_SR_OBKWERR_Pos (22U) +#define FLASH_SR_OBKWERR_Msk (0x1UL << FLASH_SR_OBKWERR_Pos) /*!< 0x00400000 */ +#define FLASH_SR_OBKWERR FLASH_SR_OBKWERR_Msk /*!< OBK write error flag */ +#define FLASH_SR_OPTCHANGEERR_Pos (23U) +#define FLASH_SR_OPTCHANGEERR_Msk (0x1UL << FLASH_SR_OPTCHANGEERR_Pos) /*!< 0x00800000 */ +#define FLASH_SR_OPTCHANGEERR FLASH_SR_OPTCHANGEERR_Msk /*!< Option byte change error flag */ + +/******************* Bits definition for FLASH_CR register ***********************/ +#define FLASH_CR_LOCK_Pos (0U) +#define FLASH_CR_LOCK_Msk (0x1UL << FLASH_CR_LOCK_Pos) /*!< 0x00000001 */ +#define FLASH_CR_LOCK FLASH_CR_LOCK_Msk /*!< Configuration lock bit */ +#define FLASH_CR_PG_Pos (1U) +#define FLASH_CR_PG_Msk (0x1UL << FLASH_CR_PG_Pos) /*!< 0x00000002 */ +#define FLASH_CR_PG FLASH_CR_PG_Msk /*!< Programming control bit */ +#define FLASH_CR_SER_Pos (2U) +#define FLASH_CR_SER_Msk (0x1UL << FLASH_CR_SER_Pos) /*!< 0x00000004 */ +#define FLASH_CR_SER FLASH_CR_SER_Msk /*!< Sector erase request */ +#define FLASH_CR_BER_Pos (3U) +#define FLASH_CR_BER_Msk (0x1UL << FLASH_CR_BER_Pos) /*!< 0x00000008 */ +#define FLASH_CR_BER FLASH_CR_BER_Msk /*!< Bank erase request */ +#define FLASH_CR_FW_Pos (4U) +#define FLASH_CR_FW_Msk (0x1UL << FLASH_CR_FW_Pos) /*!< 0x00000010 */ +#define FLASH_CR_FW FLASH_CR_FW_Msk /*!< Write forcing control bit */ +#define FLASH_CR_START_Pos (5U) +#define FLASH_CR_START_Msk (0x1UL << FLASH_CR_START_Pos) /*!< 0x00000020 */ +#define FLASH_CR_START FLASH_CR_START_Msk /*!< Erase start control bit */ +#define FLASH_CR_SNB_Pos (6U) +#define FLASH_CR_SNB_Msk (0x7FUL << FLASH_CR_SNB_Pos) /*!< 0x00001FC0 */ +#define FLASH_CR_SNB FLASH_CR_SNB_Msk /*!< Sector erase selection number */ +#define FLASH_CR_SNB_0 (0x01UL << FLASH_CR_SNB_Pos) /*!< 0x00000040 */ +#define FLASH_CR_SNB_1 (0x02UL << FLASH_CR_SNB_Pos) /*!< 0x00000080 */ +#define FLASH_CR_SNB_2 (0x04UL << FLASH_CR_SNB_Pos) /*!< 0x00000100 */ +#define FLASH_CR_SNB_3 (0x08UL << FLASH_CR_SNB_Pos) /*!< 0x00000200 */ +#define FLASH_CR_SNB_4 (0x10UL << FLASH_CR_SNB_Pos) /*!< 0x00000400 */ +#define FLASH_CR_SNB_5 (0x20UL << FLASH_CR_SNB_Pos) /*!< 0x00000800 */ +#define FLASH_CR_SNB_6 (0x40UL << FLASH_CR_SNB_Pos) /*!< 0x00001000 */ +#define FLASH_CR_MER_Pos (15U) +#define FLASH_CR_MER_Msk (0x1UL << FLASH_CR_MER_Pos) /*!< 0x00008000 */ +#define FLASH_CR_MER FLASH_CR_MER_Msk /*!< Mass erase */ +#define FLASH_CR_EOPIE_Pos (16U) +#define FLASH_CR_EOPIE_Msk (0x1UL << FLASH_CR_EOPIE_Pos) /*!< 0x00010000 */ +#define FLASH_CR_EOPIE FLASH_CR_EOPIE_Msk /*!< End-of-operation interrupt control bit */ +#define FLASH_CR_WRPERRIE_Pos (17U) +#define FLASH_CR_WRPERRIE_Msk (0x1UL << FLASH_CR_WRPERRIE_Pos) /*!< 0x00020000 */ +#define FLASH_CR_WRPERRIE FLASH_CR_WRPERRIE_Msk /*!< Write protection error interrupt enable bit */ +#define FLASH_CR_PGSERRIE_Pos (18U) +#define FLASH_CR_PGSERRIE_Msk (0x1UL << FLASH_CR_PGSERRIE_Pos) /*!< 0x00040000 */ +#define FLASH_CR_PGSERRIE FLASH_CR_PGSERRIE_Msk /*!< Programming sequence error interrupt enable bit */ +#define FLASH_CR_STRBERRIE_Pos (19U) +#define FLASH_CR_STRBERRIE_Msk (0x1UL << FLASH_CR_STRBERRIE_Pos) /*!< 0x00080000 */ +#define FLASH_CR_STRBERRIE FLASH_CR_STRBERRIE_Msk /*!< Strobe error interrupt enable bit */ +#define FLASH_CR_INCERRIE_Pos (20U) +#define FLASH_CR_INCERRIE_Msk (0x1UL << FLASH_CR_INCERRIE_Pos) /*!< 0x00100000 */ +#define FLASH_CR_INCERRIE FLASH_CR_INCERRIE_Msk /*!< Inconsistency error interrupt enable bit */ +#define FLASH_CR_OBKERRIE_Pos (21U) +#define FLASH_CR_OBKERRIE_Msk (0x1UL << FLASH_CR_OBKERRIE_Pos) /*!< 0x00200000 */ +#define FLASH_CR_OBKERRIE FLASH_CR_OBKERRIE_Msk /*!< OBK general error interrupt enable bitt */ +#define FLASH_CR_OBKWERRIE_Pos (22U) +#define FLASH_CR_OBKWERRIE_Msk (0x1UL << FLASH_CR_OBKWERRIE_Pos) /*!< 0x00400000 */ +#define FLASH_CR_OBKWERRIE FLASH_CR_OBKWERRIE_Msk /*!< OBK write error interrupt enable bit */ +#define FLASH_CR_OPTCHANGEERRIE_Pos (23U) +#define FLASH_CR_OPTCHANGEERRIE_Msk (0x1UL << FLASH_CR_OPTCHANGEERRIE_Pos) /*!< 0x00800000 */ +#define FLASH_CR_OPTCHANGEERRIE FLASH_CR_OPTCHANGEERRIE_Msk /*!< Option byte change error interrupt enable bit */ +#define FLASH_CR_INV_Pos (29U) +#define FLASH_CR_INV_Msk (0x1UL << FLASH_CR_INV_Pos) /*!< 0x20000000 */ +#define FLASH_CR_INV FLASH_CR_INV_Msk /*!< Flash Security State Invert */ +#define FLASH_CR_BKSEL_Pos (31U) +#define FLASH_CR_BKSEL_Msk (0x1UL << FLASH_CR_BKSEL_Pos) /*!< 0x10000000 */ +#define FLASH_CR_BKSEL FLASH_CR_BKSEL_Msk /*!< Bank selector */ + +/******************* Bits definition for FLASH_CCR register *******************/ +#define FLASH_CCR_CLR_EOP_Pos (16U) +#define FLASH_CCR_CLR_EOP_Msk (0x1UL << FLASH_CCR_CLR_EOP_Pos) /*!< 0x00010000 */ +#define FLASH_CCR_CLR_EOP FLASH_CCR_CLR_EOP_Msk /*!< EOP flag clear bit */ +#define FLASH_CCR_CLR_WRPERR_Pos (17U) +#define FLASH_CCR_CLR_WRPERR_Msk (0x1UL << FLASH_CCR_CLR_WRPERR_Pos) /*!< 0x00020000 */ +#define FLASH_CCR_CLR_WRPERR FLASH_CCR_CLR_WRPERR_Msk /*!< WRPERR flag clear bit */ +#define FLASH_CCR_CLR_PGSERR_Pos (18U) +#define FLASH_CCR_CLR_PGSERR_Msk (0x1UL << FLASH_CCR_CLR_PGSERR_Pos) /*!< 0x00040000 */ +#define FLASH_CCR_CLR_PGSERR FLASH_CCR_CLR_PGSERR_Msk /*!< PGSERR flag clear bit */ +#define FLASH_CCR_CLR_STRBERR_Pos (19U) +#define FLASH_CCR_CLR_STRBERR_Msk (0x1UL << FLASH_CCR_CLR_STRBERR_Pos) /*!< 0x00080000 */ +#define FLASH_CCR_CLR_STRBERR FLASH_CCR_CLR_STRBERR_Msk /*!< STRBERR flag clear bit */ +#define FLASH_CCR_CLR_INCERR_Pos (20U) +#define FLASH_CCR_CLR_INCERR_Msk (0x1UL << FLASH_CCR_CLR_INCERR_Pos) /*!< 0x00100000 */ +#define FLASH_CCR_CLR_INCERR FLASH_CCR_CLR_INCERR_Msk /*!< INCERR flag clear bit */ +#define FLASH_CCR_CLR_OBKERR_Pos (21U) +#define FLASH_CCR_CLR_OBKERR_Msk (0x1UL << FLASH_CCR_CLR_OBKERR_Pos) /*!< 0x00200000 */ +#define FLASH_CCR_CLR_OBKERR FLASH_CCR_CLR_OBKERR_Msk /*!< OBKERR flag clear bit */ +#define FLASH_CCR_CLR_OBKWERR_Pos (22U) +#define FLASH_CCR_CLR_OBKWERR_Msk (0x1UL << FLASH_CCR_CLR_OBKWERR_Pos) /*!< 0x00400000 */ +#define FLASH_CCR_CLR_OBKWERR FLASH_CCR_CLR_OBKWERR_Msk /*!< OBKWERR flag clear bit */ +#define FLASH_CCR_CLR_OPTCHANGEERR_Pos (23U) +#define FLASH_CCR_CLR_OPTCHANGEERR_Msk (0x1UL << FLASH_CCR_CLR_OPTCHANGEERR_Pos) /*!< 0x00800000 */ +#define FLASH_CCR_CLR_OPTCHANGEERR FLASH_CCR_CLR_OPTCHANGEERR_Msk /*!< Option byte change error clear bit */ + +/****************** Bits definition for FLASH_PRIVCFGR register ***********/ +#define FLASH_PRIVCFGR_SPRIV_Pos (0U) +#define FLASH_PRIVCFGR_SPRIV_Msk (0x1UL << FLASH_PRIVCFGR_SPRIV_Pos) /*!< 0x00000001 */ +#define FLASH_PRIVCFGR_SPRIV FLASH_PRIVCFGR_SPRIV_Msk /*!< Privilege protection for secure registers */ +#define FLASH_PRIVCFGR_NSPRIV_Pos (1U) +#define FLASH_PRIVCFGR_NSPRIV_Msk (0x1UL << FLASH_PRIVCFGR_NSPRIV_Pos) /*!< 0x00000002 */ +#define FLASH_PRIVCFGR_NSPRIV FLASH_PRIVCFGR_NSPRIV_Msk /*!< Privilege protection for non-secure registers */ + +/****************** Bits definition for FLASH_OBKCFGR register *****************/ +#define FLASH_OBKCFGR_LOCK_Pos (0U) +#define FLASH_OBKCFGR_LOCK_Msk (0x1UL << FLASH_OBKCFGR_LOCK_Pos) /*!< 0x00000001 */ +#define FLASH_OBKCFGR_LOCK FLASH_OBKCFGR_LOCK_Msk /*!< OBKCFGR lock */ +#define FLASH_OBKCFGR_SWAP_SECT_REQ_Pos (1U) +#define FLASH_OBKCFGR_SWAP_SECT_REQ_Msk (0x1UL << FLASH_OBKCFGR_SWAP_SECT_REQ_Pos) /*!< 0x00000002 */ +#define FLASH_OBKCFGR_SWAP_SECT_REQ FLASH_OBKCFGR_SWAP_SECT_REQ_Msk /*!< OBK swap sector request */ +#define FLASH_OBKCFGR_ALT_SECT_Pos (2U) +#define FLASH_OBKCFGR_ALT_SECT_Msk (0x1UL << FLASH_OBKCFGR_ALT_SECT_Pos) /*!< 0x00000004 */ +#define FLASH_OBKCFGR_ALT_SECT FLASH_OBKCFGR_ALT_SECT_Msk /*!< Alternate sector */ +#define FLASH_OBKCFGR_ALT_SECT_ERASE_Pos (3U) +#define FLASH_OBKCFGR_ALT_SECT_ERASE_Msk (0x1UL << FLASH_OBKCFGR_ALT_SECT_ERASE_Pos) /*!< 0x00000008 */ +#define FLASH_OBKCFGR_ALT_SECT_ERASE FLASH_OBKCFGR_ALT_SECT_ERASE_Msk /*!< Alternate sector erase */ +#define FLASH_OBKCFGR_SWAP_OFFSET_Pos (16U) +#define FLASH_OBKCFGR_SWAP_OFFSET_Msk (0x1FFUL << FLASH_OBKCFGR_SWAP_OFFSET_Pos) /*!< 0x01FF0000 */ +#define FLASH_OBKCFGR_SWAP_OFFSET FLASH_OBKCFGR_SWAP_OFFSET_Msk /*!< Swap offset */ + +/****************** Bits definition for FLASH_HDPEXTR register *****************/ +#define FLASH_HDPEXTR_HDP1_EXT_Pos (0U) +#define FLASH_HDPEXTR_HDP1_EXT_Msk (0x7FUL << FLASH_HDPEXTR_HDP1_EXT_Pos) /*!< 0x0000007F */ +#define FLASH_HDPEXTR_HDP1_EXT FLASH_HDPEXTR_HDP1_EXT_Msk /*!< HDP area extension in 8kB sectors in bank 1 */ +#define FLASH_HDPEXTR_HDP2_EXT_Pos (16U) +#define FLASH_HDPEXTR_HDP2_EXT_Msk (0x7FUL << FLASH_HDPEXTR_HDP2_EXT_Pos) /*!< 0x007F0000 */ +#define FLASH_HDPEXTR_HDP2_EXT FLASH_HDPEXTR_HDP2_EXT_Msk /*!< HDP area extension in 8kB sectors in bank 2 */ + +/******************* Bits definition for FLASH_OPTSR register ***************/ +#define FLASH_OPTSR_BOR_LEV_Pos (0U) +#define FLASH_OPTSR_BOR_LEV_Msk (0x3UL << FLASH_OPTSR_BOR_LEV_Pos) /*!< 0x00000003 */ +#define FLASH_OPTSR_BOR_LEV FLASH_OPTSR_BOR_LEV_Msk /*!< Brownout level option bit */ +#define FLASH_OPTSR_BOR_LEV_0 (0x1UL << FLASH_OPTSR_BOR_LEV_Pos) /*!< 0x00000001 */ +#define FLASH_OPTSR_BOR_LEV_1 (0x2UL << FLASH_OPTSR_BOR_LEV_Pos) /*!< 0x00000002 */ +#define FLASH_OPTSR_BORH_EN_Pos (2U) +#define FLASH_OPTSR_BORH_EN_Msk (0x1UL << FLASH_OPTSR_BORH_EN_Pos) /*!< 0x00000004 */ +#define FLASH_OPTSR_BORH_EN FLASH_OPTSR_BORH_EN_Msk /*!< Brownout high enable configuration bit */ +#define FLASH_OPTSR_IWDG_SW_Pos (3U) +#define FLASH_OPTSR_IWDG_SW_Msk (0x1UL << FLASH_OPTSR_IWDG_SW_Pos) /*!< 0x00000008 */ +#define FLASH_OPTSR_IWDG_SW FLASH_OPTSR_IWDG_SW_Msk /*!< IWDG control mode option bit */ +#define FLASH_OPTSR_WWDG_SW_Pos (4U) +#define FLASH_OPTSR_WWDG_SW_Msk (0x1UL << FLASH_OPTSR_WWDG_SW_Pos) /*!< 0x00000010 */ +#define FLASH_OPTSR_WWDG_SW FLASH_OPTSR_WWDG_SW_Msk /*!< WWDG control mode option bit */ +#define FLASH_OPTSR_NRST_STOP_Pos (6U) +#define FLASH_OPTSR_NRST_STOP_Msk (0x1UL << FLASH_OPTSR_NRST_STOP_Pos) /*!< 0x00000040 */ +#define FLASH_OPTSR_NRST_STOP FLASH_OPTSR_NRST_STOP_Msk /*!< Stop mode entry reset option bit */ +#define FLASH_OPTSR_NRST_STDBY_Pos (7U) +#define FLASH_OPTSR_NRST_STDBY_Msk (0x1UL << FLASH_OPTSR_NRST_STDBY_Pos) /*!< 0x00000080 */ +#define FLASH_OPTSR_NRST_STDBY FLASH_OPTSR_NRST_STDBY_Msk /*!< Standby mode entry reset option bit */ +#define FLASH_OPTSR_PRODUCT_STATE_Pos (8U) +#define FLASH_OPTSR_PRODUCT_STATE_Msk (0xFFUL << FLASH_OPTSR_PRODUCT_STATE_Pos) /*!< 0x0000FF00 */ +#define FLASH_OPTSR_PRODUCT_STATE FLASH_OPTSR_PRODUCT_STATE_Msk /*!< Life state code option byte */ +#define FLASH_OPTSR_IO_VDD_HSLV_Pos (16U) +#define FLASH_OPTSR_IO_VDD_HSLV_Msk (0x1UL << FLASH_OPTSR_IO_VDD_HSLV_Pos) /*!< 0x00010000 */ +#define FLASH_OPTSR_IO_VDD_HSLV FLASH_OPTSR_IO_VDD_HSLV_Msk /*!< VDD I/O high-speed at low-voltage option bit */ +#define FLASH_OPTSR_IO_VDDIO2_HSLV_Pos (17U) +#define FLASH_OPTSR_IO_VDDIO2_HSLV_Msk (0x1UL << FLASH_OPTSR_IO_VDDIO2_HSLV_Pos) /*!< 0x00020000 */ +#define FLASH_OPTSR_IO_VDDIO2_HSLV FLASH_OPTSR_IO_VDDIO2_HSLV_Msk /*!< VDDIO2 I/O high-speed at low-voltage option bit */ +#define FLASH_OPTSR_IWDG_STOP_Pos (20U) +#define FLASH_OPTSR_IWDG_STOP_Msk (0x1UL << FLASH_OPTSR_IWDG_STOP_Pos) /*!< 0x00100000 */ +#define FLASH_OPTSR_IWDG_STOP FLASH_OPTSR_IWDG_STOP_Msk /*!< Independent watchdog counter freeze in Stop mode */ +#define FLASH_OPTSR_IWDG_STDBY_Pos (21U) +#define FLASH_OPTSR_IWDG_STDBY_Msk (0x1UL << FLASH_OPTSR_IWDG_STDBY_Pos) /*!< 0x00200000 */ +#define FLASH_OPTSR_IWDG_STDBY FLASH_OPTSR_IWDG_STDBY_Msk /*!< Independent watchdog counter freeze in Standby mode */ +#define FLASH_OPTSR_BOOT_UBE_Pos (22U) +#define FLASH_OPTSR_BOOT_UBE_Msk (0xFFUL << FLASH_OPTSR_BOOT_UBE_Pos) /*!< 0x3FC00000 */ +#define FLASH_OPTSR_BOOT_UBE FLASH_OPTSR_BOOT_UBE_Msk /*!< Unique boot entry option byte */ +#define FLASH_OPTSR_SWAP_BANK_Pos (31U) +#define FLASH_OPTSR_SWAP_BANK_Msk (0x1UL << FLASH_OPTSR_SWAP_BANK_Pos) /*!< 0x80000000 */ +#define FLASH_OPTSR_SWAP_BANK FLASH_OPTSR_SWAP_BANK_Msk /*!< Bank swapping option bit */ + +/******************* Bits definition for FLASH_EPOCHR register ***************/ +#define FLASH_EPOCHR_EPOCH_Pos (0U) +#define FLASH_EPOCHR_EPOCH_Msk (0xFFFFFFUL << FLASH_EPOCHR_EPOCH_Pos) /*!< 0x00FFFFFF */ +#define FLASH_EPOCHR_EPOCH FLASH_EPOCHR_EPOCH_Msk /*!< EPOCH counter */ + +/******************* Bits definition for FLASH_OPTSR2 register ***************/ +#define FLASH_OPTSR2_SRAM1_3_RST_Pos (2U) +#define FLASH_OPTSR2_SRAM1_3_RST_Msk (0x1UL << FLASH_OPTSR2_SRAM1_3_RST_Pos) /*!< 0x00000004 */ +#define FLASH_OPTSR2_SRAM1_3_RST FLASH_OPTSR2_SRAM1_3_RST_Msk /*!< SRAM1 and SRAM3 erased when a system reset occurs */ +#define FLASH_OPTSR2_SRAM2_RST_Pos (3U) +#define FLASH_OPTSR2_SRAM2_RST_Msk (0x1UL << FLASH_OPTSR2_SRAM2_RST_Pos) /*!< 0x00000008 */ +#define FLASH_OPTSR2_SRAM2_RST FLASH_OPTSR2_SRAM2_RST_Msk /*!< SRAM2 erased when a system reset occurs*/ +#define FLASH_OPTSR2_BKPRAM_ECC_Pos (4U) +#define FLASH_OPTSR2_BKPRAM_ECC_Msk (0x1UL << FLASH_OPTSR2_BKPRAM_ECC_Pos) /*!< 0x00000010 */ +#define FLASH_OPTSR2_BKPRAM_ECC FLASH_OPTSR2_BKPRAM_ECC_Msk /*!< Backup RAM ECC detection and correction enable */ +#define FLASH_OPTSR2_SRAM3_ECC_Pos (5U) +#define FLASH_OPTSR2_SRAM3_ECC_Msk (0x1UL << FLASH_OPTSR2_SRAM3_ECC_Pos) /*!< 0x00000020 */ +#define FLASH_OPTSR2_SRAM3_ECC FLASH_OPTSR2_SRAM3_ECC_Msk /*!< SRAM3 ECC detection and correction enable */ +#define FLASH_OPTSR2_SRAM2_ECC_Pos (6U) +#define FLASH_OPTSR2_SRAM2_ECC_Msk (0x1UL << FLASH_OPTSR2_SRAM2_ECC_Pos) /*!< 0x00000040 */ +#define FLASH_OPTSR2_SRAM2_ECC FLASH_OPTSR2_SRAM2_ECC_Msk /*!< SRAM2 ECC detection and correction disable */ +#define FLASH_OPTSR2_TZEN_Pos (24U) +#define FLASH_OPTSR2_TZEN_Msk (0xFFUL << FLASH_OPTSR2_TZEN_Pos) /*!< 0xFF000000 */ +#define FLASH_OPTSR2_TZEN FLASH_OPTSR2_TZEN_Msk /*!< TrustZone enable */ + +/**************** Bits definition for FLASH_BOOTR register **********************/ +#define FLASH_BOOTR_BOOT_LOCK_Pos (0U) +#define FLASH_BOOTR_BOOT_LOCK_Msk (0xFFUL << FLASH_BOOTR_BOOT_LOCK_Pos) /*!< 0x000000FF */ +#define FLASH_BOOTR_BOOT_LOCK FLASH_BOOTR_BOOT_LOCK_Msk /*!< Boot Lock */ +#define FLASH_BOOTR_BOOTADD_Pos (8U) +#define FLASH_BOOTR_BOOTADD_Msk (0xFFFFFFUL << FLASH_BOOTR_BOOTADD_Pos) /*!< 0xFFFFFF00 */ +#define FLASH_BOOTR_BOOTADD FLASH_BOOTR_BOOTADD_Msk /*!< Boot address */ + +/**************** Bits definition for FLASH_PRIVBBR register *******************/ +#define FLASH_PRIVBBR_PRIVBB_Pos (0U) +#define FLASH_PRIVBBR_PRIVBB_Msk (0xFFFFFFFFUL << FLASH_PRIVBBR_PRIVBB_Pos) /*!< 0xFFFFFFFF */ +#define FLASH_PRIVBBR_PRIVBB FLASH_PRIVBBR_PRIVBB_Msk /*!< Privileged/unprivileged 8-Kbyte Flash sector attribute */ + +/***************** Bits definition for FLASH_SECWMR register ********************/ +#define FLASH_SECWMR_SECWM_STRT_Pos (0U) +#define FLASH_SECWMR_SECWM_STRT_Msk (0x7FUL << FLASH_SECWMR_SECWM_STRT_Pos) /*!< 0x0000007F */ +#define FLASH_SECWMR_SECWM_STRT FLASH_SECWMR_SECWM_STRT_Msk /*!< Start sector of secure area */ +#define FLASH_SECWMR_SECWM_END_Pos (16U) +#define FLASH_SECWMR_SECWM_END_Msk (0x7FUL << FLASH_SECWMR_SECWM_END_Pos) /*!< 0x007F0000 */ +#define FLASH_SECWMR_SECWM_END FLASH_SECWMR_SECWM_END_Msk /*!< End sector of secure area */ + +/***************** Bits definition for FLASH_WRPR register *********************/ +#define FLASH_WRPR_WRPSG_Pos (0U) +#define FLASH_WRPR_WRPSG_Msk (0xFFFFFFFFUL << FLASH_WRPR_WRPSG_Pos) /*!< 0xFFFFFFFF */ +#define FLASH_WRPR_WRPSG FLASH_WRPR_WRPSG_Msk /*!< Sector group protection option status */ + +/***************** Bits definition for FLASH_EDATA register ********************/ +#define FLASH_EDATAR_EDATA_STRT_Pos (0U) +#define FLASH_EDATAR_EDATA_STRT_Msk (0x3UL << FLASH_EDATAR_EDATA_STRT_Pos) /*!< 0x00000003 */ +#define FLASH_EDATAR_EDATA_STRT FLASH_EDATAR_EDATA_STRT_Msk /*!< Flash high-cycle data start sector */ +#define FLASH_EDATAR_EDATA_EN_Pos (15U) +#define FLASH_EDATAR_EDATA_EN_Msk (0x1UL << FLASH_EDATAR_EDATA_EN_Pos) /*!< 0x00008000 */ +#define FLASH_EDATAR_EDATA_EN FLASH_EDATAR_EDATA_EN_Msk /*!< Flash high-cycle data enable */ + +/***************** Bits definition for FLASH_HDPR register ********************/ +#define FLASH_HDPR_HDP_STRT_Pos (0U) +#define FLASH_HDPR_HDP_STRT_Msk (0x7FUL << FLASH_HDPR_HDP_STRT_Pos) /*!< 0x0000007F */ +#define FLASH_HDPR_HDP_STRT FLASH_HDPR_HDP_STRT_Msk /*!< Start sector of hide protection area */ +#define FLASH_HDPR_HDP_END_Pos (16U) +#define FLASH_HDPR_HDP_END_Msk (0x7FUL << FLASH_HDPR_HDP_END_Pos) /*!< 0x007F0000 */ +#define FLASH_HDPR_HDP_END FLASH_HDPR_HDP_END_Msk /*!< End sector of hide protection area */ + +/******************* Bits definition for FLASH_ECCR register ***************/ +#define FLASH_ECCR_ADDR_ECC_Pos (0U) +#define FLASH_ECCR_ADDR_ECC_Msk (0xFFFFUL << FLASH_ECCR_ADDR_ECC_Pos) /*!< 0x0000FFFF */ +#define FLASH_ECCR_ADDR_ECC FLASH_ECCR_ADDR_ECC_Msk /*!< ECC fail address */ +#define FLASH_ECCR_OBK_ECC_Pos (20U) +#define FLASH_ECCR_OBK_ECC_Msk (0x1UL << FLASH_ECCR_OBK_ECC_Pos) /*!< 0x00200000 */ +#define FLASH_ECCR_OBK_ECC FLASH_ECCR_OBK_ECC_Msk /*!< Flash OB Keys storage area ECC fail */ +#define FLASH_ECCR_DATA_ECC_Pos (21U) +#define FLASH_ECCR_DATA_ECC_Msk (0x1UL << FLASH_ECCR_DATA_ECC_Pos) /*!< 0x00400000 */ +#define FLASH_ECCR_DATA_ECC FLASH_ECCR_DATA_ECC_Msk /*!< Flash high-cycle data ECC fail */ +#define FLASH_ECCR_BK_ECC_Pos (22U) +#define FLASH_ECCR_BK_ECC_Msk (0x1UL << FLASH_ECCR_BK_ECC_Pos) /*!< 0x00400000 */ +#define FLASH_ECCR_BK_ECC FLASH_ECCR_BK_ECC_Msk /*!< ECC fail bank */ +#define FLASH_ECCR_SYSF_ECC_Pos (23U) +#define FLASH_ECCR_SYSF_ECC_Msk (0x1UL << FLASH_ECCR_SYSF_ECC_Pos) /*!< 0x00800000 */ +#define FLASH_ECCR_SYSF_ECC FLASH_ECCR_SYSF_ECC_Msk /*!< System Flash ECC fail */ +#define FLASH_ECCR_OTP_ECC_Pos (24U) +#define FLASH_ECCR_OTP_ECC_Msk (0x1UL << FLASH_ECCR_OTP_ECC_Pos) /*!< 0x01000000 */ +#define FLASH_ECCR_OTP_ECC FLASH_ECCR_OTP_ECC_Msk /*!< Flash OTP ECC fail */ +#define FLASH_ECCR_ECCIE_Pos (25U) +#define FLASH_ECCR_ECCIE_Msk (0x1UL << FLASH_ECCR_ECCIE_Pos) /*!< 0x02000000 */ +#define FLASH_ECCR_ECCIE FLASH_ECCR_ECCIE_Msk /*!< ECC correction interrupt enable */ +#define FLASH_ECCR_ECCC_Pos (30U) +#define FLASH_ECCR_ECCC_Msk (0x1UL << FLASH_ECCR_ECCC_Pos) /*!< 0x40000000 */ +#define FLASH_ECCR_ECCC FLASH_ECCR_ECCC_Msk /*!< ECC correction */ +#define FLASH_ECCR_ECCD_Pos (31U) +#define FLASH_ECCR_ECCD_Msk (0x1UL << FLASH_ECCR_ECCD_Pos) /*!< 0x80000000 */ +#define FLASH_ECCR_ECCD FLASH_ECCR_ECCD_Msk /*!< ECC detection */ + +/******************* Bits definition for FLASH_ECCDR register ***************/ +#define FLASH_ECCDR_FAIL_DATA_Pos (0U) +#define FLASH_ECCDR_FAIL_DATA_Msk (0xFFFFUL << FLASH_ECCDR_FAIL_DATA_Pos) /*!< 0x0000FFFF */ +#define FLASH_ECCDR_FAIL_DATA FLASH_ECCDR_FAIL_DATA_Msk /*!< ECC fail data */ + + +/******************************************************************************/ +/* */ +/* Filter Mathematical ACcelerator unit (FMAC) */ +/* */ +/******************************************************************************/ +/***************** Bit definition for FMAC_X1BUFCFG register ****************/ +#define FMAC_X1BUFCFG_X1_BASE_Pos (0U) +#define FMAC_X1BUFCFG_X1_BASE_Msk (0xFFUL << FMAC_X1BUFCFG_X1_BASE_Pos) /*!< 0x000000FF */ +#define FMAC_X1BUFCFG_X1_BASE FMAC_X1BUFCFG_X1_BASE_Msk /*!< Base address of X1 buffer */ +#define FMAC_X1BUFCFG_X1_BUF_SIZE_Pos (8U) +#define FMAC_X1BUFCFG_X1_BUF_SIZE_Msk (0xFFUL << FMAC_X1BUFCFG_X1_BUF_SIZE_Pos) /*!< 0x0000FF00 */ +#define FMAC_X1BUFCFG_X1_BUF_SIZE FMAC_X1BUFCFG_X1_BUF_SIZE_Msk /*!< Allocated size of X1 buffer in 16-bit words */ +#define FMAC_X1BUFCFG_FULL_WM_Pos (24U) +#define FMAC_X1BUFCFG_FULL_WM_Msk (0x3UL << FMAC_X1BUFCFG_FULL_WM_Pos) /*!< 0x03000000 */ +#define FMAC_X1BUFCFG_FULL_WM FMAC_X1BUFCFG_FULL_WM_Msk /*!< Watermark for buffer full flag */ + +/***************** Bit definition for FMAC_X2BUFCFG register ****************/ +#define FMAC_X2BUFCFG_X2_BASE_Pos (0U) +#define FMAC_X2BUFCFG_X2_BASE_Msk (0xFFUL << FMAC_X2BUFCFG_X2_BASE_Pos) /*!< 0x000000FF */ +#define FMAC_X2BUFCFG_X2_BASE FMAC_X2BUFCFG_X2_BASE_Msk /*!< Base address of X2 buffer */ +#define FMAC_X2BUFCFG_X2_BUF_SIZE_Pos (8U) +#define FMAC_X2BUFCFG_X2_BUF_SIZE_Msk (0xFFUL << FMAC_X2BUFCFG_X2_BUF_SIZE_Pos) /*!< 0x0000FF00 */ +#define FMAC_X2BUFCFG_X2_BUF_SIZE FMAC_X2BUFCFG_X2_BUF_SIZE_Msk /*!< Size of X2 buffer in 16-bit words */ + +/***************** Bit definition for FMAC_YBUFCFG register *****************/ +#define FMAC_YBUFCFG_Y_BASE_Pos (0U) +#define FMAC_YBUFCFG_Y_BASE_Msk (0xFFUL << FMAC_YBUFCFG_Y_BASE_Pos) /*!< 0x000000FF */ +#define FMAC_YBUFCFG_Y_BASE FMAC_YBUFCFG_Y_BASE_Msk /*!< Base address of Y buffer */ +#define FMAC_YBUFCFG_Y_BUF_SIZE_Pos (8U) +#define FMAC_YBUFCFG_Y_BUF_SIZE_Msk (0xFFUL << FMAC_YBUFCFG_Y_BUF_SIZE_Pos) /*!< 0x0000FF00 */ +#define FMAC_YBUFCFG_Y_BUF_SIZE FMAC_YBUFCFG_Y_BUF_SIZE_Msk /*!< Size of Y buffer in 16-bit words */ +#define FMAC_YBUFCFG_EMPTY_WM_Pos (24U) +#define FMAC_YBUFCFG_EMPTY_WM_Msk (0x3UL << FMAC_YBUFCFG_EMPTY_WM_Pos) /*!< 0x03000000 */ +#define FMAC_YBUFCFG_EMPTY_WM FMAC_YBUFCFG_EMPTY_WM_Msk /*!< Watermark for buffer empty flag */ + +/****************** Bit definition for FMAC_PARAM register ******************/ +#define FMAC_PARAM_P_Pos (0U) +#define FMAC_PARAM_P_Msk (0xFFUL << FMAC_PARAM_P_Pos) /*!< 0x000000FF */ +#define FMAC_PARAM_P FMAC_PARAM_P_Msk /*!< Input parameter P */ +#define FMAC_PARAM_Q_Pos (8U) +#define FMAC_PARAM_Q_Msk (0xFFUL << FMAC_PARAM_Q_Pos) /*!< 0x0000FF00 */ +#define FMAC_PARAM_Q FMAC_PARAM_Q_Msk /*!< Input parameter Q */ +#define FMAC_PARAM_R_Pos (16U) +#define FMAC_PARAM_R_Msk (0xFFUL << FMAC_PARAM_R_Pos) /*!< 0x00FF0000 */ +#define FMAC_PARAM_R FMAC_PARAM_R_Msk /*!< Input parameter R */ +#define FMAC_PARAM_FUNC_Pos (24U) +#define FMAC_PARAM_FUNC_Msk (0x7FUL << FMAC_PARAM_FUNC_Pos) /*!< 0x7F000000 */ +#define FMAC_PARAM_FUNC FMAC_PARAM_FUNC_Msk /*!< Function */ +#define FMAC_PARAM_FUNC_0 (0x1UL << FMAC_PARAM_FUNC_Pos) /*!< 0x01000000 */ +#define FMAC_PARAM_FUNC_1 (0x2UL << FMAC_PARAM_FUNC_Pos) /*!< 0x02000000 */ +#define FMAC_PARAM_FUNC_2 (0x4UL << FMAC_PARAM_FUNC_Pos) /*!< 0x04000000 */ +#define FMAC_PARAM_FUNC_3 (0x8UL << FMAC_PARAM_FUNC_Pos) /*!< 0x08000000 */ +#define FMAC_PARAM_FUNC_4 (0x10UL << FMAC_PARAM_FUNC_Pos) /*!< 0x10000000 */ +#define FMAC_PARAM_FUNC_5 (0x20UL << FMAC_PARAM_FUNC_Pos) /*!< 0x20000000 */ +#define FMAC_PARAM_FUNC_6 (0x40UL << FMAC_PARAM_FUNC_Pos) /*!< 0x40000000 */ +#define FMAC_PARAM_START_Pos (31U) +#define FMAC_PARAM_START_Msk (0x1UL << FMAC_PARAM_START_Pos) /*!< 0x80000000 */ +#define FMAC_PARAM_START FMAC_PARAM_START_Msk /*!< Enable execution */ + +/******************** Bit definition for FMAC_CR register *******************/ +#define FMAC_CR_RIEN_Pos (0U) +#define FMAC_CR_RIEN_Msk (0x1UL << FMAC_CR_RIEN_Pos) /*!< 0x00000001 */ +#define FMAC_CR_RIEN FMAC_CR_RIEN_Msk /*!< Enable read interrupt */ +#define FMAC_CR_WIEN_Pos (1U) +#define FMAC_CR_WIEN_Msk (0x1UL << FMAC_CR_WIEN_Pos) /*!< 0x00000002 */ +#define FMAC_CR_WIEN FMAC_CR_WIEN_Msk /*!< Enable write interrupt */ +#define FMAC_CR_OVFLIEN_Pos (2U) +#define FMAC_CR_OVFLIEN_Msk (0x1UL << FMAC_CR_OVFLIEN_Pos) /*!< 0x00000004 */ +#define FMAC_CR_OVFLIEN FMAC_CR_OVFLIEN_Msk /*!< Enable overflow error interrupts */ +#define FMAC_CR_UNFLIEN_Pos (3U) +#define FMAC_CR_UNFLIEN_Msk (0x1UL << FMAC_CR_UNFLIEN_Pos) /*!< 0x00000008 */ +#define FMAC_CR_UNFLIEN FMAC_CR_UNFLIEN_Msk /*!< Enable underflow error interrupts */ +#define FMAC_CR_SATIEN_Pos (4U) +#define FMAC_CR_SATIEN_Msk (0x1UL << FMAC_CR_SATIEN_Pos) /*!< 0x00000010 */ +#define FMAC_CR_SATIEN FMAC_CR_SATIEN_Msk /*!< Enable saturation error interrupts */ +#define FMAC_CR_DMAREN_Pos (8U) +#define FMAC_CR_DMAREN_Msk (0x1UL << FMAC_CR_DMAREN_Pos) /*!< 0x00000100 */ +#define FMAC_CR_DMAREN FMAC_CR_DMAREN_Msk /*!< Enable DMA read channel requests */ +#define FMAC_CR_DMAWEN_Pos (9U) +#define FMAC_CR_DMAWEN_Msk (0x1UL << FMAC_CR_DMAWEN_Pos) /*!< 0x00000200 */ +#define FMAC_CR_DMAWEN FMAC_CR_DMAWEN_Msk /*!< Enable DMA write channel requests */ +#define FMAC_CR_CLIPEN_Pos (15U) +#define FMAC_CR_CLIPEN_Msk (0x1UL << FMAC_CR_CLIPEN_Pos) /*!< 0x00008000 */ +#define FMAC_CR_CLIPEN FMAC_CR_CLIPEN_Msk /*!< Enable clipping */ +#define FMAC_CR_RESET_Pos (16U) +#define FMAC_CR_RESET_Msk (0x1UL << FMAC_CR_RESET_Pos) /*!< 0x00010000 */ +#define FMAC_CR_RESET FMAC_CR_RESET_Msk /*!< Reset filter mathematical accelerator unit */ + +/******************* Bit definition for FMAC_SR register ********************/ +#define FMAC_SR_YEMPTY_Pos (0U) +#define FMAC_SR_YEMPTY_Msk (0x1UL << FMAC_SR_YEMPTY_Pos) /*!< 0x00000001 */ +#define FMAC_SR_YEMPTY FMAC_SR_YEMPTY_Msk /*!< Y buffer empty flag */ +#define FMAC_SR_X1FULL_Pos (1U) +#define FMAC_SR_X1FULL_Msk (0x1UL << FMAC_SR_X1FULL_Pos) /*!< 0x00000002 */ +#define FMAC_SR_X1FULL FMAC_SR_X1FULL_Msk /*!< X1 buffer full flag */ +#define FMAC_SR_OVFL_Pos (8U) +#define FMAC_SR_OVFL_Msk (0x1UL << FMAC_SR_OVFL_Pos) /*!< 0x00000100 */ +#define FMAC_SR_OVFL FMAC_SR_OVFL_Msk /*!< Overflow error flag */ +#define FMAC_SR_UNFL_Pos (9U) +#define FMAC_SR_UNFL_Msk (0x1UL << FMAC_SR_UNFL_Pos) /*!< 0x00000200 */ +#define FMAC_SR_UNFL FMAC_SR_UNFL_Msk /*!< Underflow error flag */ +#define FMAC_SR_SAT_Pos (10U) +#define FMAC_SR_SAT_Msk (0x1UL << FMAC_SR_SAT_Pos) /*!< 0x00000400 */ +#define FMAC_SR_SAT FMAC_SR_SAT_Msk /*!< Saturation error flag */ + +/****************** Bit definition for FMAC_WDATA register ******************/ +#define FMAC_WDATA_WDATA_Pos (0U) +#define FMAC_WDATA_WDATA_Msk (0xFFFFUL << FMAC_WDATA_WDATA_Pos) /*!< 0x0000FFFF */ +#define FMAC_WDATA_WDATA FMAC_WDATA_WDATA_Msk /*!< Write data */ + +/****************** Bit definition for FMACX_RDATA register *****************/ +#define FMAC_RDATA_RDATA_Pos (0U) +#define FMAC_RDATA_RDATA_Msk (0xFFFFUL << FMAC_RDATA_RDATA_Pos) /*!< 0x0000FFFF */ +#define FMAC_RDATA_RDATA FMAC_RDATA_RDATA_Msk /*!< Read data */ + + +/******************************************************************************/ +/* */ +/* Flexible Memory Controller */ +/* */ +/******************************************************************************/ +/****************** Bit definition for FMC_BCR1 register *******************/ +#define FMC_BCR1_CCLKEN_Pos (20U) +#define FMC_BCR1_CCLKEN_Msk (0x1UL << FMC_BCR1_CCLKEN_Pos) /*!< 0x00100000 */ +#define FMC_BCR1_CCLKEN FMC_BCR1_CCLKEN_Msk /*! */ + +/******************** Bits definition for RTC_ALRMAR register ***************/ +#define RTC_ALRMAR_SU_Pos (0U) +#define RTC_ALRMAR_SU_Msk (0xFUL << RTC_ALRMAR_SU_Pos) /*!< 0x0000000F */ +#define RTC_ALRMAR_SU RTC_ALRMAR_SU_Msk +#define RTC_ALRMAR_SU_0 (0x1UL << RTC_ALRMAR_SU_Pos) /*!< 0x00000001 */ +#define RTC_ALRMAR_SU_1 (0x2UL << RTC_ALRMAR_SU_Pos) /*!< 0x00000002 */ +#define RTC_ALRMAR_SU_2 (0x4UL << RTC_ALRMAR_SU_Pos) /*!< 0x00000004 */ +#define RTC_ALRMAR_SU_3 (0x8UL << RTC_ALRMAR_SU_Pos) /*!< 0x00000008 */ +#define RTC_ALRMAR_ST_Pos (4U) +#define RTC_ALRMAR_ST_Msk (0x7UL << RTC_ALRMAR_ST_Pos) /*!< 0x00000070 */ +#define RTC_ALRMAR_ST RTC_ALRMAR_ST_Msk +#define RTC_ALRMAR_ST_0 (0x1UL << RTC_ALRMAR_ST_Pos) /*!< 0x00000010 */ +#define RTC_ALRMAR_ST_1 (0x2UL << RTC_ALRMAR_ST_Pos) /*!< 0x00000020 */ +#define RTC_ALRMAR_ST_2 (0x4UL << RTC_ALRMAR_ST_Pos) /*!< 0x00000040 */ +#define RTC_ALRMAR_MSK1_Pos (7U) +#define RTC_ALRMAR_MSK1_Msk (0x1UL << RTC_ALRMAR_MSK1_Pos) /*!< 0x00000080 */ +#define RTC_ALRMAR_MSK1 RTC_ALRMAR_MSK1_Msk +#define RTC_ALRMAR_MNU_Pos (8U) +#define RTC_ALRMAR_MNU_Msk (0xFUL << RTC_ALRMAR_MNU_Pos) /*!< 0x00000F00 */ +#define RTC_ALRMAR_MNU RTC_ALRMAR_MNU_Msk +#define RTC_ALRMAR_MNU_0 (0x1UL << RTC_ALRMAR_MNU_Pos) /*!< 0x00000100 */ +#define RTC_ALRMAR_MNU_1 (0x2UL << RTC_ALRMAR_MNU_Pos) /*!< 0x00000200 */ +#define RTC_ALRMAR_MNU_2 (0x4UL << RTC_ALRMAR_MNU_Pos) /*!< 0x00000400 */ +#define RTC_ALRMAR_MNU_3 (0x8UL << RTC_ALRMAR_MNU_Pos) /*!< 0x00000800 */ +#define RTC_ALRMAR_MNT_Pos (12U) +#define RTC_ALRMAR_MNT_Msk (0x7UL << RTC_ALRMAR_MNT_Pos) /*!< 0x00007000 */ +#define RTC_ALRMAR_MNT RTC_ALRMAR_MNT_Msk +#define RTC_ALRMAR_MNT_0 (0x1UL << RTC_ALRMAR_MNT_Pos) /*!< 0x00001000 */ +#define RTC_ALRMAR_MNT_1 (0x2UL << RTC_ALRMAR_MNT_Pos) /*!< 0x00002000 */ +#define RTC_ALRMAR_MNT_2 (0x4UL << RTC_ALRMAR_MNT_Pos) /*!< 0x00004000 */ +#define RTC_ALRMAR_MSK2_Pos (15U) +#define RTC_ALRMAR_MSK2_Msk (0x1UL << RTC_ALRMAR_MSK2_Pos) /*!< 0x00008000 */ +#define RTC_ALRMAR_MSK2 RTC_ALRMAR_MSK2_Msk +#define RTC_ALRMAR_HU_Pos (16U) +#define RTC_ALRMAR_HU_Msk (0xFUL << RTC_ALRMAR_HU_Pos) /*!< 0x000F0000 */ +#define RTC_ALRMAR_HU RTC_ALRMAR_HU_Msk +#define RTC_ALRMAR_HU_0 (0x1UL << RTC_ALRMAR_HU_Pos) /*!< 0x00010000 */ +#define RTC_ALRMAR_HU_1 (0x2UL << RTC_ALRMAR_HU_Pos) /*!< 0x00020000 */ +#define RTC_ALRMAR_HU_2 (0x4UL << RTC_ALRMAR_HU_Pos) /*!< 0x00040000 */ +#define RTC_ALRMAR_HU_3 (0x8UL << RTC_ALRMAR_HU_Pos) /*!< 0x00080000 */ +#define RTC_ALRMAR_HT_Pos (20U) +#define RTC_ALRMAR_HT_Msk (0x3UL << RTC_ALRMAR_HT_Pos) /*!< 0x00300000 */ +#define RTC_ALRMAR_HT RTC_ALRMAR_HT_Msk +#define RTC_ALRMAR_HT_0 (0x1UL << RTC_ALRMAR_HT_Pos) /*!< 0x00100000 */ +#define RTC_ALRMAR_HT_1 (0x2UL << RTC_ALRMAR_HT_Pos) /*!< 0x00200000 */ +#define RTC_ALRMAR_PM_Pos (22U) +#define RTC_ALRMAR_PM_Msk (0x1UL << RTC_ALRMAR_PM_Pos) /*!< 0x00400000 */ +#define RTC_ALRMAR_PM RTC_ALRMAR_PM_Msk +#define RTC_ALRMAR_MSK3_Pos (23U) +#define RTC_ALRMAR_MSK3_Msk (0x1UL << RTC_ALRMAR_MSK3_Pos) /*!< 0x00800000 */ +#define RTC_ALRMAR_MSK3 RTC_ALRMAR_MSK3_Msk +#define RTC_ALRMAR_DU_Pos (24U) +#define RTC_ALRMAR_DU_Msk (0xFUL << RTC_ALRMAR_DU_Pos) /*!< 0x0F000000 */ +#define RTC_ALRMAR_DU RTC_ALRMAR_DU_Msk +#define RTC_ALRMAR_DU_0 (0x1UL << RTC_ALRMAR_DU_Pos) /*!< 0x01000000 */ +#define RTC_ALRMAR_DU_1 (0x2UL << RTC_ALRMAR_DU_Pos) /*!< 0x02000000 */ +#define RTC_ALRMAR_DU_2 (0x4UL << RTC_ALRMAR_DU_Pos) /*!< 0x04000000 */ +#define RTC_ALRMAR_DU_3 (0x8UL << RTC_ALRMAR_DU_Pos) /*!< 0x08000000 */ +#define RTC_ALRMAR_DT_Pos (28U) +#define RTC_ALRMAR_DT_Msk (0x3UL << RTC_ALRMAR_DT_Pos) /*!< 0x30000000 */ +#define RTC_ALRMAR_DT RTC_ALRMAR_DT_Msk +#define RTC_ALRMAR_DT_0 (0x1UL << RTC_ALRMAR_DT_Pos) /*!< 0x10000000 */ +#define RTC_ALRMAR_DT_1 (0x2UL << RTC_ALRMAR_DT_Pos) /*!< 0x20000000 */ +#define RTC_ALRMAR_WDSEL_Pos (30U) +#define RTC_ALRMAR_WDSEL_Msk (0x1UL << RTC_ALRMAR_WDSEL_Pos) /*!< 0x40000000 */ +#define RTC_ALRMAR_WDSEL RTC_ALRMAR_WDSEL_Msk +#define RTC_ALRMAR_MSK4_Pos (31U) +#define RTC_ALRMAR_MSK4_Msk (0x1UL << RTC_ALRMAR_MSK4_Pos) /*!< 0x80000000 */ +#define RTC_ALRMAR_MSK4 RTC_ALRMAR_MSK4_Msk + +/******************** Bits definition for RTC_ALRMASSR register *************/ +#define RTC_ALRMASSR_SS_Pos (0U) +#define RTC_ALRMASSR_SS_Msk (0x7FFFUL << RTC_ALRMASSR_SS_Pos) /*!< 0x00007FFF */ +#define RTC_ALRMASSR_SS RTC_ALRMASSR_SS_Msk +#define RTC_ALRMASSR_MASKSS_Pos (24U) +#define RTC_ALRMASSR_MASKSS_Msk (0x3FUL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x3F000000 */ +#define RTC_ALRMASSR_MASKSS RTC_ALRMASSR_MASKSS_Msk +#define RTC_ALRMASSR_MASKSS_0 (0x1UL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x01000000 */ +#define RTC_ALRMASSR_MASKSS_1 (0x2UL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x02000000 */ +#define RTC_ALRMASSR_MASKSS_2 (0x4UL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x04000000 */ +#define RTC_ALRMASSR_MASKSS_3 (0x8UL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x08000000 */ +#define RTC_ALRMASSR_MASKSS_4 (0x10UL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x10000000 */ +#define RTC_ALRMASSR_MASKSS_5 (0x20UL << RTC_ALRMASSR_MASKSS_Pos) /*!< 0x20000000 */ +#define RTC_ALRMASSR_SSCLR_Pos (31U) +#define RTC_ALRMASSR_SSCLR_Msk (0x1UL << RTC_ALRMASSR_SSCLR_Pos) /*!< 0x80000000 */ +#define RTC_ALRMASSR_SSCLR RTC_ALRMASSR_SSCLR_Msk + +/******************** Bits definition for RTC_ALRMBR register ***************/ +#define RTC_ALRMBR_SU_Pos (0U) +#define RTC_ALRMBR_SU_Msk (0xFUL << RTC_ALRMBR_SU_Pos) /*!< 0x0000000F */ +#define RTC_ALRMBR_SU RTC_ALRMBR_SU_Msk +#define RTC_ALRMBR_SU_0 (0x1UL << RTC_ALRMBR_SU_Pos) /*!< 0x00000001 */ +#define RTC_ALRMBR_SU_1 (0x2UL << RTC_ALRMBR_SU_Pos) /*!< 0x00000002 */ +#define RTC_ALRMBR_SU_2 (0x4UL << RTC_ALRMBR_SU_Pos) /*!< 0x00000004 */ +#define RTC_ALRMBR_SU_3 (0x8UL << RTC_ALRMBR_SU_Pos) /*!< 0x00000008 */ +#define RTC_ALRMBR_ST_Pos (4U) +#define RTC_ALRMBR_ST_Msk (0x7UL << RTC_ALRMBR_ST_Pos) /*!< 0x00000070 */ +#define RTC_ALRMBR_ST RTC_ALRMBR_ST_Msk +#define RTC_ALRMBR_ST_0 (0x1UL << RTC_ALRMBR_ST_Pos) /*!< 0x00000010 */ +#define RTC_ALRMBR_ST_1 (0x2UL << RTC_ALRMBR_ST_Pos) /*!< 0x00000020 */ +#define RTC_ALRMBR_ST_2 (0x4UL << RTC_ALRMBR_ST_Pos) /*!< 0x00000040 */ +#define RTC_ALRMBR_MSK1_Pos (7U) +#define RTC_ALRMBR_MSK1_Msk (0x1UL << RTC_ALRMBR_MSK1_Pos) /*!< 0x00000080 */ +#define RTC_ALRMBR_MSK1 RTC_ALRMBR_MSK1_Msk +#define RTC_ALRMBR_MNU_Pos (8U) +#define RTC_ALRMBR_MNU_Msk (0xFUL << RTC_ALRMBR_MNU_Pos) /*!< 0x00000F00 */ +#define RTC_ALRMBR_MNU RTC_ALRMBR_MNU_Msk +#define RTC_ALRMBR_MNU_0 (0x1UL << RTC_ALRMBR_MNU_Pos) /*!< 0x00000100 */ +#define RTC_ALRMBR_MNU_1 (0x2UL << RTC_ALRMBR_MNU_Pos) /*!< 0x00000200 */ +#define RTC_ALRMBR_MNU_2 (0x4UL << RTC_ALRMBR_MNU_Pos) /*!< 0x00000400 */ +#define RTC_ALRMBR_MNU_3 (0x8UL << RTC_ALRMBR_MNU_Pos) /*!< 0x00000800 */ +#define RTC_ALRMBR_MNT_Pos (12U) +#define RTC_ALRMBR_MNT_Msk (0x7UL << RTC_ALRMBR_MNT_Pos) /*!< 0x00007000 */ +#define RTC_ALRMBR_MNT RTC_ALRMBR_MNT_Msk +#define RTC_ALRMBR_MNT_0 (0x1UL << RTC_ALRMBR_MNT_Pos) /*!< 0x00001000 */ +#define RTC_ALRMBR_MNT_1 (0x2UL << RTC_ALRMBR_MNT_Pos) /*!< 0x00002000 */ +#define RTC_ALRMBR_MNT_2 (0x4UL << RTC_ALRMBR_MNT_Pos) /*!< 0x00004000 */ +#define RTC_ALRMBR_MSK2_Pos (15U) +#define RTC_ALRMBR_MSK2_Msk (0x1UL << RTC_ALRMBR_MSK2_Pos) /*!< 0x00008000 */ +#define RTC_ALRMBR_MSK2 RTC_ALRMBR_MSK2_Msk +#define RTC_ALRMBR_HU_Pos (16U) +#define RTC_ALRMBR_HU_Msk (0xFUL << RTC_ALRMBR_HU_Pos) /*!< 0x000F0000 */ +#define RTC_ALRMBR_HU RTC_ALRMBR_HU_Msk +#define RTC_ALRMBR_HU_0 (0x1UL << RTC_ALRMBR_HU_Pos) /*!< 0x00010000 */ +#define RTC_ALRMBR_HU_1 (0x2UL << RTC_ALRMBR_HU_Pos) /*!< 0x00020000 */ +#define RTC_ALRMBR_HU_2 (0x4UL << RTC_ALRMBR_HU_Pos) /*!< 0x00040000 */ +#define RTC_ALRMBR_HU_3 (0x8UL << RTC_ALRMBR_HU_Pos) /*!< 0x00080000 */ +#define RTC_ALRMBR_HT_Pos (20U) +#define RTC_ALRMBR_HT_Msk (0x3UL << RTC_ALRMBR_HT_Pos) /*!< 0x00300000 */ +#define RTC_ALRMBR_HT RTC_ALRMBR_HT_Msk +#define RTC_ALRMBR_HT_0 (0x1UL << RTC_ALRMBR_HT_Pos) /*!< 0x00100000 */ +#define RTC_ALRMBR_HT_1 (0x2UL << RTC_ALRMBR_HT_Pos) /*!< 0x00200000 */ +#define RTC_ALRMBR_PM_Pos (22U) +#define RTC_ALRMBR_PM_Msk (0x1UL << RTC_ALRMBR_PM_Pos) /*!< 0x00400000 */ +#define RTC_ALRMBR_PM RTC_ALRMBR_PM_Msk +#define RTC_ALRMBR_MSK3_Pos (23U) +#define RTC_ALRMBR_MSK3_Msk (0x1UL << RTC_ALRMBR_MSK3_Pos) /*!< 0x00800000 */ +#define RTC_ALRMBR_MSK3 RTC_ALRMBR_MSK3_Msk +#define RTC_ALRMBR_DU_Pos (24U) +#define RTC_ALRMBR_DU_Msk (0xFUL << RTC_ALRMBR_DU_Pos) /*!< 0x0F000000 */ +#define RTC_ALRMBR_DU RTC_ALRMBR_DU_Msk +#define RTC_ALRMBR_DU_0 (0x1UL << RTC_ALRMBR_DU_Pos) /*!< 0x01000000 */ +#define RTC_ALRMBR_DU_1 (0x2UL << RTC_ALRMBR_DU_Pos) /*!< 0x02000000 */ +#define RTC_ALRMBR_DU_2 (0x4UL << RTC_ALRMBR_DU_Pos) /*!< 0x04000000 */ +#define RTC_ALRMBR_DU_3 (0x8UL << RTC_ALRMBR_DU_Pos) /*!< 0x08000000 */ +#define RTC_ALRMBR_DT_Pos (28U) +#define RTC_ALRMBR_DT_Msk (0x3UL << RTC_ALRMBR_DT_Pos) /*!< 0x30000000 */ +#define RTC_ALRMBR_DT RTC_ALRMBR_DT_Msk +#define RTC_ALRMBR_DT_0 (0x1UL << RTC_ALRMBR_DT_Pos) /*!< 0x10000000 */ +#define RTC_ALRMBR_DT_1 (0x2UL << RTC_ALRMBR_DT_Pos) /*!< 0x20000000 */ +#define RTC_ALRMBR_WDSEL_Pos (30U) +#define RTC_ALRMBR_WDSEL_Msk (0x1UL << RTC_ALRMBR_WDSEL_Pos) /*!< 0x40000000 */ +#define RTC_ALRMBR_WDSEL RTC_ALRMBR_WDSEL_Msk +#define RTC_ALRMBR_MSK4_Pos (31U) +#define RTC_ALRMBR_MSK4_Msk (0x1UL << RTC_ALRMBR_MSK4_Pos) /*!< 0x80000000 */ +#define RTC_ALRMBR_MSK4 RTC_ALRMBR_MSK4_Msk + +/******************** Bits definition for RTC_ALRMBSSR register *************/ +#define RTC_ALRMBSSR_SS_Pos (0U) +#define RTC_ALRMBSSR_SS_Msk (0x7FFFUL << RTC_ALRMBSSR_SS_Pos) /*!< 0x00007FFF */ +#define RTC_ALRMBSSR_SS RTC_ALRMBSSR_SS_Msk +#define RTC_ALRMBSSR_MASKSS_Pos (24U) +#define RTC_ALRMBSSR_MASKSS_Msk (0x3FUL << RTC_ALRMBSSR_MASKSS_Pos) /*!< 0x3F000000 */ +#define RTC_ALRMBSSR_MASKSS RTC_ALRMBSSR_MASKSS_Msk +#define RTC_ALRMBSSR_MASKSS_0 (0x1UL << RTC_ALRMBSSR_MASKSS_Pos) /*!< 0x01000000 */ +#define RTC_ALRMBSSR_MASKSS_1 (0x2UL << RTC_ALRMBSSR_MASKSS_Pos) /*!< 0x02000000 */ +#define RTC_ALRMBSSR_MASKSS_2 (0x4UL << RTC_ALRMBSSR_MASKSS_Pos) /*!< 0x04000000 */ +#define RTC_ALRMBSSR_MASKSS_3 (0x8UL << RTC_ALRMBSSR_MASKSS_Pos) /*!< 0x08000000 */ +#define RTC_ALRMBSSR_MASKSS_4 (0x10UL << RTC_ALRMBSSR_MASKSS_Pos) /*!< 0x10000000 */ +#define RTC_ALRMBSSR_MASKSS_5 (0x20UL << RTC_ALRMBSSR_MASKSS_Pos) /*!< 0x20000000 */ +#define RTC_ALRMBSSR_SSCLR_Pos (31U) +#define RTC_ALRMBSSR_SSCLR_Msk (0x1UL << RTC_ALRMBSSR_SSCLR_Pos) /*!< 0x80000000 */ +#define RTC_ALRMBSSR_SSCLR RTC_ALRMBSSR_SSCLR_Msk + +/******************** Bits definition for RTC_SR register *******************/ +#define RTC_SR_ALRAF_Pos (0U) +#define RTC_SR_ALRAF_Msk (0x1UL << RTC_SR_ALRAF_Pos) /*!< 0x00000001 */ +#define RTC_SR_ALRAF RTC_SR_ALRAF_Msk +#define RTC_SR_ALRBF_Pos (1U) +#define RTC_SR_ALRBF_Msk (0x1UL << RTC_SR_ALRBF_Pos) /*!< 0x00000002 */ +#define RTC_SR_ALRBF RTC_SR_ALRBF_Msk +#define RTC_SR_WUTF_Pos (2U) +#define RTC_SR_WUTF_Msk (0x1UL << RTC_SR_WUTF_Pos) /*!< 0x00000004 */ +#define RTC_SR_WUTF RTC_SR_WUTF_Msk +#define RTC_SR_TSF_Pos (3U) +#define RTC_SR_TSF_Msk (0x1UL << RTC_SR_TSF_Pos) /*!< 0x00000008 */ +#define RTC_SR_TSF RTC_SR_TSF_Msk +#define RTC_SR_TSOVF_Pos (4U) +#define RTC_SR_TSOVF_Msk (0x1UL << RTC_SR_TSOVF_Pos) /*!< 0x00000010 */ +#define RTC_SR_TSOVF RTC_SR_TSOVF_Msk +#define RTC_SR_ITSF_Pos (5U) +#define RTC_SR_ITSF_Msk (0x1UL << RTC_SR_ITSF_Pos) /*!< 0x00000020 */ +#define RTC_SR_ITSF RTC_SR_ITSF_Msk +#define RTC_SR_SSRUF_Pos (6U) +#define RTC_SR_SSRUF_Msk (0x1UL << RTC_SR_SSRUF_Pos) /*!< 0x00000040 */ +#define RTC_SR_SSRUF RTC_SR_SSRUF_Msk + +/******************** Bits definition for RTC_MISR register *****************/ +#define RTC_MISR_ALRAMF_Pos (0U) +#define RTC_MISR_ALRAMF_Msk (0x1UL << RTC_MISR_ALRAMF_Pos) /*!< 0x00000001 */ +#define RTC_MISR_ALRAMF RTC_MISR_ALRAMF_Msk +#define RTC_MISR_ALRBMF_Pos (1U) +#define RTC_MISR_ALRBMF_Msk (0x1UL << RTC_MISR_ALRBMF_Pos) /*!< 0x00000002 */ +#define RTC_MISR_ALRBMF RTC_MISR_ALRBMF_Msk +#define RTC_MISR_WUTMF_Pos (2U) +#define RTC_MISR_WUTMF_Msk (0x1UL << RTC_MISR_WUTMF_Pos) /*!< 0x00000004 */ +#define RTC_MISR_WUTMF RTC_MISR_WUTMF_Msk +#define RTC_MISR_TSMF_Pos (3U) +#define RTC_MISR_TSMF_Msk (0x1UL << RTC_MISR_TSMF_Pos) /*!< 0x00000008 */ +#define RTC_MISR_TSMF RTC_MISR_TSMF_Msk +#define RTC_MISR_TSOVMF_Pos (4U) +#define RTC_MISR_TSOVMF_Msk (0x1UL << RTC_MISR_TSOVMF_Pos) /*!< 0x00000010 */ +#define RTC_MISR_TSOVMF RTC_MISR_TSOVMF_Msk +#define RTC_MISR_ITSMF_Pos (5U) +#define RTC_MISR_ITSMF_Msk (0x1UL << RTC_MISR_ITSMF_Pos) /*!< 0x00000020 */ +#define RTC_MISR_ITSMF RTC_MISR_ITSMF_Msk +#define RTC_MISR_SSRUMF_Pos (6U) +#define RTC_MISR_SSRUMF_Msk (0x1UL << RTC_MISR_SSRUMF_Pos) /*!< 0x00000040 */ +#define RTC_MISR_SSRUMF RTC_MISR_SSRUMF_Msk + +/******************** Bits definition for RTC_SMISR register *****************/ +#define RTC_SMISR_ALRAMF_Pos (0U) +#define RTC_SMISR_ALRAMF_Msk (0x1UL << RTC_SMISR_ALRAMF_Pos) /*!< 0x00000001 */ +#define RTC_SMISR_ALRAMF RTC_SMISR_ALRAMF_Msk +#define RTC_SMISR_ALRBMF_Pos (1U) +#define RTC_SMISR_ALRBMF_Msk (0x1UL << RTC_SMISR_ALRBMF_Pos) /*!< 0x00000002 */ +#define RTC_SMISR_ALRBMF RTC_SMISR_ALRBMF_Msk +#define RTC_SMISR_WUTMF_Pos (2U) +#define RTC_SMISR_WUTMF_Msk (0x1UL << RTC_SMISR_WUTMF_Pos) /*!< 0x00000004 */ +#define RTC_SMISR_WUTMF RTC_SMISR_WUTMF_Msk +#define RTC_SMISR_TSMF_Pos (3U) +#define RTC_SMISR_TSMF_Msk (0x1UL << RTC_SMISR_TSMF_Pos) /*!< 0x00000008 */ +#define RTC_SMISR_TSMF RTC_SMISR_TSMF_Msk +#define RTC_SMISR_TSOVMF_Pos (4U) +#define RTC_SMISR_TSOVMF_Msk (0x1UL << RTC_SMISR_TSOVMF_Pos) /*!< 0x00000010 */ +#define RTC_SMISR_TSOVMF RTC_SMISR_TSOVMF_Msk +#define RTC_SMISR_ITSMF_Pos (5U) +#define RTC_SMISR_ITSMF_Msk (0x1UL << RTC_SMISR_ITSMF_Pos) /*!< 0x00000020 */ +#define RTC_SMISR_ITSMF RTC_SMISR_ITSMF_Msk +#define RTC_SMISR_SSRUMF_Pos (6U) +#define RTC_SMISR_SSRUMF_Msk (0x1UL << RTC_SMISR_SSRUMF_Pos) /*!< 0x00000040 */ +#define RTC_SMISR_SSRUMF RTC_SMISR_SSRUMF_Msk + +/******************** Bits definition for RTC_SCR register ******************/ +#define RTC_SCR_CALRAF_Pos (0U) +#define RTC_SCR_CALRAF_Msk (0x1UL << RTC_SCR_CALRAF_Pos) /*!< 0x00000001 */ +#define RTC_SCR_CALRAF RTC_SCR_CALRAF_Msk +#define RTC_SCR_CALRBF_Pos (1U) +#define RTC_SCR_CALRBF_Msk (0x1UL << RTC_SCR_CALRBF_Pos) /*!< 0x00000002 */ +#define RTC_SCR_CALRBF RTC_SCR_CALRBF_Msk +#define RTC_SCR_CWUTF_Pos (2U) +#define RTC_SCR_CWUTF_Msk (0x1UL << RTC_SCR_CWUTF_Pos) /*!< 0x00000004 */ +#define RTC_SCR_CWUTF RTC_SCR_CWUTF_Msk +#define RTC_SCR_CTSF_Pos (3U) +#define RTC_SCR_CTSF_Msk (0x1UL << RTC_SCR_CTSF_Pos) /*!< 0x00000008 */ +#define RTC_SCR_CTSF RTC_SCR_CTSF_Msk +#define RTC_SCR_CTSOVF_Pos (4U) +#define RTC_SCR_CTSOVF_Msk (0x1UL << RTC_SCR_CTSOVF_Pos) /*!< 0x00000010 */ +#define RTC_SCR_CTSOVF RTC_SCR_CTSOVF_Msk +#define RTC_SCR_CITSF_Pos (5U) +#define RTC_SCR_CITSF_Msk (0x1UL << RTC_SCR_CITSF_Pos) /*!< 0x00000020 */ +#define RTC_SCR_CITSF RTC_SCR_CITSF_Msk +#define RTC_SCR_CSSRUF_Pos (6U) +#define RTC_SCR_CSSRUF_Msk (0x1UL << RTC_SCR_CSSRUF_Pos) /*!< 0x00000040 */ +#define RTC_SCR_CSSRUF RTC_SCR_CSSRUF_Msk + +/******************** Bits definition for RTC_OR register ******************/ +#define RTC_OR_OUT2_RMP_Pos (0U) +#define RTC_OR_OUT2_RMP_Msk (0x1UL << RTC_OR_OUT2_RMP_Pos) /*!< 0x00000001 */ +#define RTC_OR_OUT2_RMP RTC_OR_OUT2_RMP_Msk + +/******************** Bits definition for RTC_ALRABINR register ******************/ +#define RTC_ALRABINR_SS_Pos (0U) +#define RTC_ALRABINR_SS_Msk (0xFFFFFFFFUL << RTC_ALRABINR_SS_Pos) /*!< 0xFFFFFFFF */ +#define RTC_ALRABINR_SS RTC_ALRABINR_SS_Msk + +/******************** Bits definition for RTC_ALRBBINR register ******************/ +#define RTC_ALRBBINR_SS_Pos (0U) +#define RTC_ALRBBINR_SS_Msk (0xFFFFFFFFUL << RTC_ALRBBINR_SS_Pos) /*!< 0xFFFFFFFF */ +#define RTC_ALRBBINR_SS RTC_ALRBBINR_SS_Msk + +/******************************************************************************/ +/* */ +/* Tamper and backup register (TAMP) */ +/* */ +/******************************************************************************/ +/******************** Bits definition for TAMP_CR1 register *****************/ +#define TAMP_CR1_TAMP1E_Pos (0U) +#define TAMP_CR1_TAMP1E_Msk (0x1UL << TAMP_CR1_TAMP1E_Pos) /*!< 0x00000001 */ +#define TAMP_CR1_TAMP1E TAMP_CR1_TAMP1E_Msk +#define TAMP_CR1_TAMP2E_Pos (1U) +#define TAMP_CR1_TAMP2E_Msk (0x1UL << TAMP_CR1_TAMP2E_Pos) /*!< 0x00000002 */ +#define TAMP_CR1_TAMP2E TAMP_CR1_TAMP2E_Msk +#define TAMP_CR1_TAMP3E_Pos (2U) +#define TAMP_CR1_TAMP3E_Msk (0x1UL << TAMP_CR1_TAMP3E_Pos) /*!< 0x00000004 */ +#define TAMP_CR1_TAMP3E TAMP_CR1_TAMP3E_Msk +#define TAMP_CR1_TAMP4E_Pos (3U) +#define TAMP_CR1_TAMP4E_Msk (0x1UL << TAMP_CR1_TAMP4E_Pos) /*!< 0x00000008 */ +#define TAMP_CR1_TAMP4E TAMP_CR1_TAMP4E_Msk +#define TAMP_CR1_TAMP5E_Pos (4U) +#define TAMP_CR1_TAMP5E_Msk (0x1UL << TAMP_CR1_TAMP5E_Pos) /*!< 0x00000010 */ +#define TAMP_CR1_TAMP5E TAMP_CR1_TAMP5E_Msk +#define TAMP_CR1_TAMP6E_Pos (5U) +#define TAMP_CR1_TAMP6E_Msk (0x1UL << TAMP_CR1_TAMP6E_Pos) /*!< 0x00000020 */ +#define TAMP_CR1_TAMP6E TAMP_CR1_TAMP6E_Msk +#define TAMP_CR1_TAMP7E_Pos (6U) +#define TAMP_CR1_TAMP7E_Msk (0x1UL << TAMP_CR1_TAMP7E_Pos) /*!< 0x00000040 */ +#define TAMP_CR1_TAMP7E TAMP_CR1_TAMP7E_Msk +#define TAMP_CR1_TAMP8E_Pos (7U) +#define TAMP_CR1_TAMP8E_Msk (0x1UL << TAMP_CR1_TAMP8E_Pos) /*!< 0x00000080 */ +#define TAMP_CR1_TAMP8E TAMP_CR1_TAMP8E_Msk +#define TAMP_CR1_ITAMP1E_Pos (16U) +#define TAMP_CR1_ITAMP1E_Msk (0x1UL << TAMP_CR1_ITAMP1E_Pos) /*!< 0x00010000 */ +#define TAMP_CR1_ITAMP1E TAMP_CR1_ITAMP1E_Msk +#define TAMP_CR1_ITAMP2E_Pos (17U) +#define TAMP_CR1_ITAMP2E_Msk (0x1UL << TAMP_CR1_ITAMP2E_Pos) /*!< 0x00020000 */ +#define TAMP_CR1_ITAMP2E TAMP_CR1_ITAMP2E_Msk +#define TAMP_CR1_ITAMP3E_Pos (18U) +#define TAMP_CR1_ITAMP3E_Msk (0x1UL << TAMP_CR1_ITAMP3E_Pos) /*!< 0x00040000 */ +#define TAMP_CR1_ITAMP3E TAMP_CR1_ITAMP3E_Msk +#define TAMP_CR1_ITAMP4E_Pos (19U) +#define TAMP_CR1_ITAMP4E_Msk (0x1UL << TAMP_CR1_ITAMP4E_Pos) /*!< 0x00080000 */ +#define TAMP_CR1_ITAMP4E TAMP_CR1_ITAMP4E_Msk +#define TAMP_CR1_ITAMP5E_Pos (20U) +#define TAMP_CR1_ITAMP5E_Msk (0x1UL << TAMP_CR1_ITAMP5E_Pos) /*!< 0x00100000 */ +#define TAMP_CR1_ITAMP5E TAMP_CR1_ITAMP5E_Msk +#define TAMP_CR1_ITAMP6E_Pos (21U) +#define TAMP_CR1_ITAMP6E_Msk (0x1UL << TAMP_CR1_ITAMP6E_Pos) /*!< 0x00200000 */ +#define TAMP_CR1_ITAMP6E TAMP_CR1_ITAMP6E_Msk +#define TAMP_CR1_ITAMP7E_Pos (22U) +#define TAMP_CR1_ITAMP7E_Msk (0x1UL << TAMP_CR1_ITAMP7E_Pos) /*!< 0x00400000 */ +#define TAMP_CR1_ITAMP7E TAMP_CR1_ITAMP7E_Msk +#define TAMP_CR1_ITAMP8E_Pos (23U) +#define TAMP_CR1_ITAMP8E_Msk (0x1UL << TAMP_CR1_ITAMP8E_Pos) /*!< 0x00800000 */ +#define TAMP_CR1_ITAMP8E TAMP_CR1_ITAMP8E_Msk +#define TAMP_CR1_ITAMP9E_Pos (24U) +#define TAMP_CR1_ITAMP9E_Msk (0x1UL << TAMP_CR1_ITAMP9E_Pos) /*!< 0x01000000 */ +#define TAMP_CR1_ITAMP9E TAMP_CR1_ITAMP9E_Msk +#define TAMP_CR1_ITAMP11E_Pos (26U) +#define TAMP_CR1_ITAMP11E_Msk (0x1UL << TAMP_CR1_ITAMP11E_Pos) /*!< 0x04000000 */ +#define TAMP_CR1_ITAMP11E TAMP_CR1_ITAMP11E_Msk +#define TAMP_CR1_ITAMP12E_Pos (27U) +#define TAMP_CR1_ITAMP12E_Msk (0x1UL << TAMP_CR1_ITAMP12E_Pos) /*!< 0x08000000 */ +#define TAMP_CR1_ITAMP12E TAMP_CR1_ITAMP12E_Msk +#define TAMP_CR1_ITAMP13E_Pos (28U) +#define TAMP_CR1_ITAMP13E_Msk (0x1UL << TAMP_CR1_ITAMP13E_Pos) /*!< 0x10000000 */ +#define TAMP_CR1_ITAMP13E TAMP_CR1_ITAMP13E_Msk +#define TAMP_CR1_ITAMP15E_Pos (30U) +#define TAMP_CR1_ITAMP15E_Msk (0x1UL << TAMP_CR1_ITAMP15E_Pos) /*!< 0x40000000 */ +#define TAMP_CR1_ITAMP15E TAMP_CR1_ITAMP15E_Msk + +/******************** Bits definition for TAMP_CR2 register *****************/ +#define TAMP_CR2_TAMP1NOERASE_Pos (0U) +#define TAMP_CR2_TAMP1NOERASE_Msk (0x1UL << TAMP_CR2_TAMP1NOERASE_Pos) /*!< 0x00000001 */ +#define TAMP_CR2_TAMP1NOERASE TAMP_CR2_TAMP1NOERASE_Msk +#define TAMP_CR2_TAMP2NOERASE_Pos (1U) +#define TAMP_CR2_TAMP2NOERASE_Msk (0x1UL << TAMP_CR2_TAMP2NOERASE_Pos) /*!< 0x00000002 */ +#define TAMP_CR2_TAMP2NOERASE TAMP_CR2_TAMP2NOERASE_Msk +#define TAMP_CR2_TAMP3NOERASE_Pos (2U) +#define TAMP_CR2_TAMP3NOERASE_Msk (0x1UL << TAMP_CR2_TAMP3NOERASE_Pos) /*!< 0x00000004 */ +#define TAMP_CR2_TAMP3NOERASE TAMP_CR2_TAMP3NOERASE_Msk +#define TAMP_CR2_TAMP4NOERASE_Pos (3U) +#define TAMP_CR2_TAMP4NOERASE_Msk (0x1UL << TAMP_CR2_TAMP4NOERASE_Pos) /*!< 0x00000008 */ +#define TAMP_CR2_TAMP4NOERASE TAMP_CR2_TAMP4NOERASE_Msk +#define TAMP_CR2_TAMP5NOERASE_Pos (4U) +#define TAMP_CR2_TAMP5NOERASE_Msk (0x1UL << TAMP_CR2_TAMP5NOERASE_Pos) /*!< 0x00000010 */ +#define TAMP_CR2_TAMP5NOERASE TAMP_CR2_TAMP5NOERASE_Msk +#define TAMP_CR2_TAMP6NOERASE_Pos (5U) +#define TAMP_CR2_TAMP6NOERASE_Msk (0x1UL << TAMP_CR2_TAMP6NOERASE_Pos) /*!< 0x00000020 */ +#define TAMP_CR2_TAMP6NOERASE TAMP_CR2_TAMP6NOERASE_Msk +#define TAMP_CR2_TAMP7NOERASE_Pos (6U) +#define TAMP_CR2_TAMP7NOERASE_Msk (0x1UL << TAMP_CR2_TAMP7NOERASE_Pos) /*!< 0x00000040 */ +#define TAMP_CR2_TAMP7NOERASE TAMP_CR2_TAMP7NOERASE_Msk +#define TAMP_CR2_TAMP8NOERASE_Pos (7U) +#define TAMP_CR2_TAMP8NOERASE_Msk (0x1UL << TAMP_CR2_TAMP8NOERASE_Pos) /*!< 0x00000080 */ +#define TAMP_CR2_TAMP8NOERASE TAMP_CR2_TAMP8NOERASE_Msk +#define TAMP_CR2_TAMP1MSK_Pos (16U) +#define TAMP_CR2_TAMP1MSK_Msk (0x1UL << TAMP_CR2_TAMP1MSK_Pos) /*!< 0x00010000 */ +#define TAMP_CR2_TAMP1MSK TAMP_CR2_TAMP1MSK_Msk +#define TAMP_CR2_TAMP2MSK_Pos (17U) +#define TAMP_CR2_TAMP2MSK_Msk (0x1UL << TAMP_CR2_TAMP2MSK_Pos) /*!< 0x00020000 */ +#define TAMP_CR2_TAMP2MSK TAMP_CR2_TAMP2MSK_Msk +#define TAMP_CR2_TAMP3MSK_Pos (18U) +#define TAMP_CR2_TAMP3MSK_Msk (0x1UL << TAMP_CR2_TAMP3MSK_Pos) /*!< 0x00040000 */ +#define TAMP_CR2_TAMP3MSK TAMP_CR2_TAMP3MSK_Msk +#define TAMP_CR2_BKBLOCK_Pos (22U) +#define TAMP_CR2_BKBLOCK_Msk (0x1UL << TAMP_CR2_BKBLOCK_Pos) /*!< 0x00400000 */ +#define TAMP_CR2_BKBLOCK TAMP_CR2_BKBLOCK_Msk +#define TAMP_CR2_BKERASE_Pos (23U) +#define TAMP_CR2_BKERASE_Msk (0x1UL << TAMP_CR2_BKERASE_Pos) /*!< 0x00800000 */ +#define TAMP_CR2_BKERASE TAMP_CR2_BKERASE_Msk +#define TAMP_CR2_TAMP1TRG_Pos (24U) +#define TAMP_CR2_TAMP1TRG_Msk (0x1UL << TAMP_CR2_TAMP1TRG_Pos) /*!< 0x01000000 */ +#define TAMP_CR2_TAMP1TRG TAMP_CR2_TAMP1TRG_Msk +#define TAMP_CR2_TAMP2TRG_Pos (25U) +#define TAMP_CR2_TAMP2TRG_Msk (0x1UL << TAMP_CR2_TAMP2TRG_Pos) /*!< 0x02000000 */ +#define TAMP_CR2_TAMP2TRG TAMP_CR2_TAMP2TRG_Msk +#define TAMP_CR2_TAMP3TRG_Pos (26U) +#define TAMP_CR2_TAMP3TRG_Msk (0x1UL << TAMP_CR2_TAMP3TRG_Pos) /*!< 0x02000000 */ +#define TAMP_CR2_TAMP3TRG TAMP_CR2_TAMP3TRG_Msk +#define TAMP_CR2_TAMP4TRG_Pos (27U) +#define TAMP_CR2_TAMP4TRG_Msk (0x1UL << TAMP_CR2_TAMP4TRG_Pos) /*!< 0x02000000 */ +#define TAMP_CR2_TAMP4TRG TAMP_CR2_TAMP4TRG_Msk +#define TAMP_CR2_TAMP5TRG_Pos (28U) +#define TAMP_CR2_TAMP5TRG_Msk (0x1UL << TAMP_CR2_TAMP5TRG_Pos) /*!< 0x02000000 */ +#define TAMP_CR2_TAMP5TRG TAMP_CR2_TAMP5TRG_Msk +#define TAMP_CR2_TAMP6TRG_Pos (29U) +#define TAMP_CR2_TAMP6TRG_Msk (0x1UL << TAMP_CR2_TAMP6TRG_Pos) /*!< 0x02000000 */ +#define TAMP_CR2_TAMP6TRG TAMP_CR2_TAMP6TRG_Msk +#define TAMP_CR2_TAMP7TRG_Pos (30U) +#define TAMP_CR2_TAMP7TRG_Msk (0x1UL << TAMP_CR2_TAMP7TRG_Pos) /*!< 0x02000000 */ +#define TAMP_CR2_TAMP7TRG TAMP_CR2_TAMP7TRG_Msk +#define TAMP_CR2_TAMP8TRG_Pos (31U) +#define TAMP_CR2_TAMP8TRG_Msk (0x1UL << TAMP_CR2_TAMP8TRG_Pos) /*!< 0x02000000 */ +#define TAMP_CR2_TAMP8TRG TAMP_CR2_TAMP8TRG_Msk + +/******************** Bits definition for TAMP_CR3 register *****************/ +#define TAMP_CR3_ITAMP1NOER_Pos (0U) +#define TAMP_CR3_ITAMP1NOER_Msk (0x1UL << TAMP_CR3_ITAMP1NOER_Pos) /*!< 0x00000001 */ +#define TAMP_CR3_ITAMP1NOER TAMP_CR3_ITAMP1NOER_Msk +#define TAMP_CR3_ITAMP2NOER_Pos (1U) +#define TAMP_CR3_ITAMP2NOER_Msk (0x1UL << TAMP_CR3_ITAMP2NOER_Pos) /*!< 0x00000002 */ +#define TAMP_CR3_ITAMP2NOER TAMP_CR3_ITAMP2NOER_Msk +#define TAMP_CR3_ITAMP3NOER_Pos (2U) +#define TAMP_CR3_ITAMP3NOER_Msk (0x1UL << TAMP_CR3_ITAMP3NOER_Pos) /*!< 0x00000004 */ +#define TAMP_CR3_ITAMP3NOER TAMP_CR3_ITAMP3NOER_Msk +#define TAMP_CR3_ITAMP4NOER_Pos (3U) +#define TAMP_CR3_ITAMP4NOER_Msk (0x1UL << TAMP_CR3_ITAMP4NOER_Pos) /*!< 0x00000008 */ +#define TAMP_CR3_ITAMP4NOER TAMP_CR3_ITAMP4NOER_Msk +#define TAMP_CR3_ITAMP5NOER_Pos (4U) +#define TAMP_CR3_ITAMP5NOER_Msk (0x1UL << TAMP_CR3_ITAMP5NOER_Pos) /*!< 0x00000010 */ +#define TAMP_CR3_ITAMP5NOER TAMP_CR3_ITAMP5NOER_Msk +#define TAMP_CR3_ITAMP6NOER_Pos (5U) +#define TAMP_CR3_ITAMP6NOER_Msk (0x1UL << TAMP_CR3_ITAMP6NOER_Pos) /*!< 0x00000020 */ +#define TAMP_CR3_ITAMP6NOER TAMP_CR3_ITAMP6NOER_Msk +#define TAMP_CR3_ITAMP7NOER_Pos (6U) +#define TAMP_CR3_ITAMP7NOER_Msk (0x1UL << TAMP_CR3_ITAMP7NOER_Pos) /*!< 0x00000040 */ +#define TAMP_CR3_ITAMP7NOER TAMP_CR3_ITAMP7NOER_Msk +#define TAMP_CR3_ITAMP8NOER_Pos (7U) +#define TAMP_CR3_ITAMP8NOER_Msk (0x1UL << TAMP_CR3_ITAMP8NOER_Pos) /*!< 0x00000080 */ +#define TAMP_CR3_ITAMP8NOER TAMP_CR3_ITAMP8NOER_Msk +#define TAMP_CR3_ITAMP9NOER_Pos (8U) +#define TAMP_CR3_ITAMP9NOER_Msk (0x1UL << TAMP_CR3_ITAMP9NOER_Pos) /*!< 0x00000100 */ +#define TAMP_CR3_ITAMP9NOER TAMP_CR3_ITAMP9NOER_Msk +#define TAMP_CR3_ITAMP11NOER_Pos (10U) +#define TAMP_CR3_ITAMP11NOER_Msk (0x1UL << TAMP_CR3_ITAMP11NOER_Pos) /*!< 0x00000400 */ +#define TAMP_CR3_ITAMP11NOER TAMP_CR3_ITAMP11NOER_Msk +#define TAMP_CR3_ITAMP12NOER_Pos (11U) +#define TAMP_CR3_ITAMP12NOER_Msk (0x1UL << TAMP_CR3_ITAMP12NOER_Pos) /*!< 0x00000800 */ +#define TAMP_CR3_ITAMP12NOER TAMP_CR3_ITAMP12NOER_Msk +#define TAMP_CR3_ITAMP13NOER_Pos (12U) +#define TAMP_CR3_ITAMP13NOER_Msk (0x1UL << TAMP_CR3_ITAMP13NOER_Pos) /*!< 0x00001000 */ +#define TAMP_CR3_ITAMP13NOER TAMP_CR3_ITAMP13NOER_Msk +#define TAMP_CR3_ITAMP15NOER_Pos (14U) +#define TAMP_CR3_ITAMP15NOER_Msk (0x1UL << TAMP_CR3_ITAMP15NOER_Pos) /*!< 0x00004000 */ +#define TAMP_CR3_ITAMP15NOER TAMP_CR3_ITAMP15NOER_Msk + +/******************** Bits definition for TAMP_FLTCR register ***************/ +#define TAMP_FLTCR_TAMPFREQ_Pos (0U) +#define TAMP_FLTCR_TAMPFREQ_Msk (0x7UL << TAMP_FLTCR_TAMPFREQ_Pos) /*!< 0x00000007 */ +#define TAMP_FLTCR_TAMPFREQ TAMP_FLTCR_TAMPFREQ_Msk +#define TAMP_FLTCR_TAMPFREQ_0 (0x1UL << TAMP_FLTCR_TAMPFREQ_Pos) /*!< 0x00000001 */ +#define TAMP_FLTCR_TAMPFREQ_1 (0x2UL << TAMP_FLTCR_TAMPFREQ_Pos) /*!< 0x00000002 */ +#define TAMP_FLTCR_TAMPFREQ_2 (0x4UL << TAMP_FLTCR_TAMPFREQ_Pos) /*!< 0x00000004 */ +#define TAMP_FLTCR_TAMPFLT_Pos (3U) +#define TAMP_FLTCR_TAMPFLT_Msk (0x3UL << TAMP_FLTCR_TAMPFLT_Pos) /*!< 0x00000018 */ +#define TAMP_FLTCR_TAMPFLT TAMP_FLTCR_TAMPFLT_Msk +#define TAMP_FLTCR_TAMPFLT_0 (0x1UL << TAMP_FLTCR_TAMPFLT_Pos) /*!< 0x00000008 */ +#define TAMP_FLTCR_TAMPFLT_1 (0x2UL << TAMP_FLTCR_TAMPFLT_Pos) /*!< 0x00000010 */ +#define TAMP_FLTCR_TAMPPRCH_Pos (5U) +#define TAMP_FLTCR_TAMPPRCH_Msk (0x3UL << TAMP_FLTCR_TAMPPRCH_Pos) /*!< 0x00000060 */ +#define TAMP_FLTCR_TAMPPRCH TAMP_FLTCR_TAMPPRCH_Msk +#define TAMP_FLTCR_TAMPPRCH_0 (0x1UL << TAMP_FLTCR_TAMPPRCH_Pos) /*!< 0x00000020 */ +#define TAMP_FLTCR_TAMPPRCH_1 (0x2UL << TAMP_FLTCR_TAMPPRCH_Pos) /*!< 0x00000040 */ +#define TAMP_FLTCR_TAMPPUDIS_Pos (7U) +#define TAMP_FLTCR_TAMPPUDIS_Msk (0x1UL << TAMP_FLTCR_TAMPPUDIS_Pos) /*!< 0x00000080 */ +#define TAMP_FLTCR_TAMPPUDIS TAMP_FLTCR_TAMPPUDIS_Msk + +/******************** Bits definition for TAMP_ATCR1 register ***************/ +#define TAMP_ATCR1_TAMP1AM_Pos (0U) +#define TAMP_ATCR1_TAMP1AM_Msk (0x1UL << TAMP_ATCR1_TAMP1AM_Pos) /*!< 0x00000001 */ +#define TAMP_ATCR1_TAMP1AM TAMP_ATCR1_TAMP1AM_Msk +#define TAMP_ATCR1_TAMP2AM_Pos (1U) +#define TAMP_ATCR1_TAMP2AM_Msk (0x1UL << TAMP_ATCR1_TAMP2AM_Pos) /*!< 0x00000002 */ +#define TAMP_ATCR1_TAMP2AM TAMP_ATCR1_TAMP2AM_Msk +#define TAMP_ATCR1_TAMP3AM_Pos (2U) +#define TAMP_ATCR1_TAMP3AM_Msk (0x1UL << TAMP_ATCR1_TAMP3AM_Pos) /*!< 0x00000004 */ +#define TAMP_ATCR1_TAMP3AM TAMP_ATCR1_TAMP3AM_Msk +#define TAMP_ATCR1_TAMP4AM_Pos (3U) +#define TAMP_ATCR1_TAMP4AM_Msk (0x1UL << TAMP_ATCR1_TAMP4AM_Pos) /*!< 0x00000008 */ +#define TAMP_ATCR1_TAMP4AM TAMP_ATCR1_TAMP4AM_Msk +#define TAMP_ATCR1_TAMP5AM_Pos (4U) +#define TAMP_ATCR1_TAMP5AM_Msk (0x1UL << TAMP_ATCR1_TAMP5AM_Pos) /*!< 0x00000010 */ +#define TAMP_ATCR1_TAMP5AM TAMP_ATCR1_TAMP5AM_Msk +#define TAMP_ATCR1_TAMP6AM_Pos (5U) +#define TAMP_ATCR1_TAMP6AM_Msk (0x1UL << TAMP_ATCR1_TAMP6AM_Pos) /*!< 0x00000010 */ +#define TAMP_ATCR1_TAMP6AM TAMP_ATCR1_TAMP6AM_Msk +#define TAMP_ATCR1_TAMP7AM_Pos (6U) +#define TAMP_ATCR1_TAMP7AM_Msk (0x1UL << TAMP_ATCR1_TAMP7AM_Pos) /*!< 0x00000040 */ +#define TAMP_ATCR1_TAMP7AM TAMP_ATCR1_TAMP7AM_Msk +#define TAMP_ATCR1_TAMP8AM_Pos (7U) +#define TAMP_ATCR1_TAMP8AM_Msk (0x1UL << TAMP_ATCR1_TAMP8AM_Pos) /*!< 0x00000080 */ +#define TAMP_ATCR1_TAMP8AM TAMP_ATCR1_TAMP8AM_Msk +#define TAMP_ATCR1_ATOSEL1_Pos (8U) +#define TAMP_ATCR1_ATOSEL1_Msk (0x3UL << TAMP_ATCR1_ATOSEL1_Pos) /*!< 0x00000300 */ +#define TAMP_ATCR1_ATOSEL1 TAMP_ATCR1_ATOSEL1_Msk +#define TAMP_ATCR1_ATOSEL1_0 (0x1UL << TAMP_ATCR1_ATOSEL1_Pos) /*!< 0x00000100 */ +#define TAMP_ATCR1_ATOSEL1_1 (0x2UL << TAMP_ATCR1_ATOSEL1_Pos) /*!< 0x00000200 */ +#define TAMP_ATCR1_ATOSEL2_Pos (10U) +#define TAMP_ATCR1_ATOSEL2_Msk (0x3UL << TAMP_ATCR1_ATOSEL2_Pos) /*!< 0x00000C00 */ +#define TAMP_ATCR1_ATOSEL2 TAMP_ATCR1_ATOSEL2_Msk +#define TAMP_ATCR1_ATOSEL2_0 (0x1UL << TAMP_ATCR1_ATOSEL2_Pos) /*!< 0x00000400 */ +#define TAMP_ATCR1_ATOSEL2_1 (0x2UL << TAMP_ATCR1_ATOSEL2_Pos) /*!< 0x00000800 */ +#define TAMP_ATCR1_ATOSEL3_Pos (12U) +#define TAMP_ATCR1_ATOSEL3_Msk (0x3UL << TAMP_ATCR1_ATOSEL3_Pos) /*!< 0x00003000 */ +#define TAMP_ATCR1_ATOSEL3 TAMP_ATCR1_ATOSEL3_Msk +#define TAMP_ATCR1_ATOSEL3_0 (0x1UL << TAMP_ATCR1_ATOSEL3_Pos) /*!< 0x00001000 */ +#define TAMP_ATCR1_ATOSEL3_1 (0x2UL << TAMP_ATCR1_ATOSEL3_Pos) /*!< 0x00002000 */ +#define TAMP_ATCR1_ATOSEL4_Pos (14U) +#define TAMP_ATCR1_ATOSEL4_Msk (0x3UL << TAMP_ATCR1_ATOSEL4_Pos) /*!< 0x0000C000 */ +#define TAMP_ATCR1_ATOSEL4 TAMP_ATCR1_ATOSEL4_Msk +#define TAMP_ATCR1_ATOSEL4_0 (0x1UL << TAMP_ATCR1_ATOSEL4_Pos) /*!< 0x00004000 */ +#define TAMP_ATCR1_ATOSEL4_1 (0x2UL << TAMP_ATCR1_ATOSEL4_Pos) /*!< 0x00008000 */ +#define TAMP_ATCR1_ATCKSEL_Pos (16U) +#define TAMP_ATCR1_ATCKSEL_Msk (0xFUL << TAMP_ATCR1_ATCKSEL_Pos) /*!< 0x000F0000 */ +#define TAMP_ATCR1_ATCKSEL TAMP_ATCR1_ATCKSEL_Msk +#define TAMP_ATCR1_ATCKSEL_0 (0x1UL << TAMP_ATCR1_ATCKSEL_Pos) /*!< 0x00010000 */ +#define TAMP_ATCR1_ATCKSEL_1 (0x2UL << TAMP_ATCR1_ATCKSEL_Pos) /*!< 0x00020000 */ +#define TAMP_ATCR1_ATCKSEL_2 (0x4UL << TAMP_ATCR1_ATCKSEL_Pos) /*!< 0x00040000 */ +#define TAMP_ATCR1_ATCKSEL_3 (0x8UL << TAMP_ATCR1_ATCKSEL_Pos) /*!< 0x00080000 */ +#define TAMP_ATCR1_ATPER_Pos (24U) +#define TAMP_ATCR1_ATPER_Msk (0x7UL << TAMP_ATCR1_ATPER_Pos) /*!< 0x07000000 */ +#define TAMP_ATCR1_ATPER TAMP_ATCR1_ATPER_Msk +#define TAMP_ATCR1_ATPER_0 (0x1UL << TAMP_ATCR1_ATPER_Pos) /*!< 0x01000000 */ +#define TAMP_ATCR1_ATPER_1 (0x2UL << TAMP_ATCR1_ATPER_Pos) /*!< 0x02000000 */ +#define TAMP_ATCR1_ATPER_2 (0x4UL << TAMP_ATCR1_ATPER_Pos) /*!< 0x04000000 */ +#define TAMP_ATCR1_ATOSHARE_Pos (30U) +#define TAMP_ATCR1_ATOSHARE_Msk (0x1UL << TAMP_ATCR1_ATOSHARE_Pos) /*!< 0x40000000 */ +#define TAMP_ATCR1_ATOSHARE TAMP_ATCR1_ATOSHARE_Msk +#define TAMP_ATCR1_FLTEN_Pos (31U) +#define TAMP_ATCR1_FLTEN_Msk (0x1UL << TAMP_ATCR1_FLTEN_Pos) /*!< 0x80000000 */ +#define TAMP_ATCR1_FLTEN TAMP_ATCR1_FLTEN_Msk + +/******************** Bits definition for TAMP_ATSEEDR register ******************/ +#define TAMP_ATSEEDR_SEED_Pos (0U) +#define TAMP_ATSEEDR_SEED_Msk (0xFFFFFFFFUL << TAMP_ATSEEDR_SEED_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_ATSEEDR_SEED TAMP_ATSEEDR_SEED_Msk + +/******************** Bits definition for TAMP_ATOR register ******************/ +#define TAMP_ATOR_PRNG_Pos (0U) +#define TAMP_ATOR_PRNG_Msk (0xFFUL << TAMP_ATOR_PRNG_Pos) /*!< 0x000000FF */ +#define TAMP_ATOR_PRNG TAMP_ATOR_PRNG_Msk +#define TAMP_ATOR_PRNG_0 (0x1UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000001 */ +#define TAMP_ATOR_PRNG_1 (0x2UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000002 */ +#define TAMP_ATOR_PRNG_2 (0x4UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000004 */ +#define TAMP_ATOR_PRNG_3 (0x8UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000008 */ +#define TAMP_ATOR_PRNG_4 (0x10UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000010 */ +#define TAMP_ATOR_PRNG_5 (0x20UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000020 */ +#define TAMP_ATOR_PRNG_6 (0x40UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000040 */ +#define TAMP_ATOR_PRNG_7 (0x80UL << TAMP_ATOR_PRNG_Pos) /*!< 0x00000080 */ +#define TAMP_ATOR_SEEDF_Pos (14U) +#define TAMP_ATOR_SEEDF_Msk (1UL << TAMP_ATOR_SEEDF_Pos) /*!< 0x00004000 */ +#define TAMP_ATOR_SEEDF TAMP_ATOR_SEEDF_Msk +#define TAMP_ATOR_INITS_Pos (15U) +#define TAMP_ATOR_INITS_Msk (1UL << TAMP_ATOR_INITS_Pos) /*!< 0x00008000 */ +#define TAMP_ATOR_INITS TAMP_ATOR_INITS_Msk + +/******************** Bits definition for TAMP_ATCR2 register ***************/ +#define TAMP_ATCR2_ATOSEL1_Pos (8U) +#define TAMP_ATCR2_ATOSEL1_Msk (0x7UL << TAMP_ATCR2_ATOSEL1_Pos) /*!< 0x00000700 */ +#define TAMP_ATCR2_ATOSEL1 TAMP_ATCR2_ATOSEL1_Msk +#define TAMP_ATCR2_ATOSEL1_0 (0x1UL << TAMP_ATCR2_ATOSEL1_Pos) /*!< 0x00000100 */ +#define TAMP_ATCR2_ATOSEL1_1 (0x2UL << TAMP_ATCR2_ATOSEL1_Pos) /*!< 0x00000200 */ +#define TAMP_ATCR2_ATOSEL1_2 (0x4UL << TAMP_ATCR2_ATOSEL1_Pos) /*!< 0x00000400 */ +#define TAMP_ATCR2_ATOSEL2_Pos (11U) +#define TAMP_ATCR2_ATOSEL2_Msk (0x7UL << TAMP_ATCR2_ATOSEL2_Pos) /*!< 0x00003800 */ +#define TAMP_ATCR2_ATOSEL2 TAMP_ATCR2_ATOSEL2_Msk +#define TAMP_ATCR2_ATOSEL2_0 (0x1UL << TAMP_ATCR2_ATOSEL2_Pos) /*!< 0x00000800 */ +#define TAMP_ATCR2_ATOSEL2_1 (0x2UL << TAMP_ATCR2_ATOSEL2_Pos) /*!< 0x00001000 */ +#define TAMP_ATCR2_ATOSEL2_2 (0x4UL << TAMP_ATCR2_ATOSEL2_Pos) /*!< 0x00002000 */ +#define TAMP_ATCR2_ATOSEL3_Pos (14U) +#define TAMP_ATCR2_ATOSEL3_Msk (0x7UL << TAMP_ATCR2_ATOSEL3_Pos) /*!< 0x0001C000 */ +#define TAMP_ATCR2_ATOSEL3 TAMP_ATCR2_ATOSEL3_Msk +#define TAMP_ATCR2_ATOSEL3_0 (0x1UL << TAMP_ATCR2_ATOSEL3_Pos) /*!< 0x00004000 */ +#define TAMP_ATCR2_ATOSEL3_1 (0x2UL << TAMP_ATCR2_ATOSEL3_Pos) /*!< 0x00008000 */ +#define TAMP_ATCR2_ATOSEL3_2 (0x4UL << TAMP_ATCR2_ATOSEL3_Pos) /*!< 0x00010000 */ +#define TAMP_ATCR2_ATOSEL4_Pos (17U) +#define TAMP_ATCR2_ATOSEL4_Msk (0x7UL << TAMP_ATCR2_ATOSEL4_Pos) /*!< 0x000E0000 */ +#define TAMP_ATCR2_ATOSEL4 TAMP_ATCR2_ATOSEL4_Msk +#define TAMP_ATCR2_ATOSEL4_0 (0x1UL << TAMP_ATCR2_ATOSEL4_Pos) /*!< 0x00020000 */ +#define TAMP_ATCR2_ATOSEL4_1 (0x2UL << TAMP_ATCR2_ATOSEL4_Pos) /*!< 0x00040000 */ +#define TAMP_ATCR2_ATOSEL4_2 (0x4UL << TAMP_ATCR2_ATOSEL4_Pos) /*!< 0x00080000 */ +#define TAMP_ATCR2_ATOSEL5_Pos (20U) +#define TAMP_ATCR2_ATOSEL5_Msk (0x7UL << TAMP_ATCR2_ATOSEL5_Pos) /*!< 0x00700000 */ +#define TAMP_ATCR2_ATOSEL5 TAMP_ATCR2_ATOSEL5_Msk +#define TAMP_ATCR2_ATOSEL5_0 (0x1UL << TAMP_ATCR2_ATOSEL5_Pos) /*!< 0x00100000 */ +#define TAMP_ATCR2_ATOSEL5_1 (0x2UL << TAMP_ATCR2_ATOSEL5_Pos) /*!< 0x00200000 */ +#define TAMP_ATCR2_ATOSEL5_2 (0x4UL << TAMP_ATCR2_ATOSEL5_Pos) /*!< 0x00400000 */ +#define TAMP_ATCR2_ATOSEL6_Pos (23U) +#define TAMP_ATCR2_ATOSEL6_Msk (0x7UL << TAMP_ATCR2_ATOSEL6_Pos) /*!< 0x03800000 */ +#define TAMP_ATCR2_ATOSEL6 TAMP_ATCR2_ATOSEL6_Msk +#define TAMP_ATCR2_ATOSEL6_0 (0x1UL << TAMP_ATCR2_ATOSEL6_Pos) /*!< 0x00800000 */ +#define TAMP_ATCR2_ATOSEL6_1 (0x2UL << TAMP_ATCR2_ATOSEL6_Pos) /*!< 0x01000000 */ +#define TAMP_ATCR2_ATOSEL6_2 (0x4UL << TAMP_ATCR2_ATOSEL6_Pos) /*!< 0x02000000 */ +#define TAMP_ATCR2_ATOSEL7_Pos (26U) +#define TAMP_ATCR2_ATOSEL7_Msk (0x7UL << TAMP_ATCR2_ATOSEL7_Pos) /*!< 0x1C000000 */ +#define TAMP_ATCR2_ATOSEL7 TAMP_ATCR2_ATOSEL7_Msk +#define TAMP_ATCR2_ATOSEL7_0 (0x1UL << TAMP_ATCR2_ATOSEL7_Pos) /*!< 0x04000000 */ +#define TAMP_ATCR2_ATOSEL7_1 (0x2UL << TAMP_ATCR2_ATOSEL7_Pos) /*!< 0x08000000 */ +#define TAMP_ATCR2_ATOSEL7_2 (0x4UL << TAMP_ATCR2_ATOSEL7_Pos) /*!< 0x10000000 */ +#define TAMP_ATCR2_ATOSEL8_Pos (29U) +#define TAMP_ATCR2_ATOSEL8_Msk (0x7UL << TAMP_ATCR2_ATOSEL8_Pos) /*!< 0xE0000000 */ +#define TAMP_ATCR2_ATOSEL8 TAMP_ATCR2_ATOSEL8_Msk +#define TAMP_ATCR2_ATOSEL8_0 (0x1UL << TAMP_ATCR2_ATOSEL8_Pos) /*!< 0x20000000 */ +#define TAMP_ATCR2_ATOSEL8_1 (0x2UL << TAMP_ATCR2_ATOSEL8_Pos) /*!< 0x40000000 */ +#define TAMP_ATCR2_ATOSEL8_2 (0x4UL << TAMP_ATCR2_ATOSEL8_Pos) /*!< 0x80000000 */ + +/******************** Bits definition for TAMP_SECCFGR register *************/ +#define TAMP_SECCFGR_BKPRWSEC_Pos (0U) +#define TAMP_SECCFGR_BKPRWSEC_Msk (0xFFUL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x000000FF */ +#define TAMP_SECCFGR_BKPRWSEC TAMP_SECCFGR_BKPRWSEC_Msk +#define TAMP_SECCFGR_BKPRWSEC_0 (0x1UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000001 */ +#define TAMP_SECCFGR_BKPRWSEC_1 (0x2UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000002 */ +#define TAMP_SECCFGR_BKPRWSEC_2 (0x4UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000004 */ +#define TAMP_SECCFGR_BKPRWSEC_3 (0x8UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000008 */ +#define TAMP_SECCFGR_BKPRWSEC_4 (0x10UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000010 */ +#define TAMP_SECCFGR_BKPRWSEC_5 (0x20UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000020 */ +#define TAMP_SECCFGR_BKPRWSEC_6 (0x40UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000040 */ +#define TAMP_SECCFGR_BKPRWSEC_7 (0x80UL << TAMP_SECCFGR_BKPRWSEC_Pos) /*!< 0x00000080 */ +#define TAMP_SECCFGR_CNT1SEC_Pos (15U) +#define TAMP_SECCFGR_CNT1SEC_Msk (0x1UL << TAMP_SECCFGR_CNT1SEC_Pos) /*!< 0x00008000 */ +#define TAMP_SECCFGR_CNT1SEC TAMP_SECCFGR_CNT1SEC_Msk +#define TAMP_SECCFGR_BKPWSEC_Pos (16U) +#define TAMP_SECCFGR_BKPWSEC_Msk (0xFFUL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00FF0000 */ +#define TAMP_SECCFGR_BKPWSEC TAMP_SECCFGR_BKPWSEC_Msk +#define TAMP_SECCFGR_BKPWSEC_0 (0x1UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00010000 */ +#define TAMP_SECCFGR_BKPWSEC_1 (0x2UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00020000 */ +#define TAMP_SECCFGR_BKPWSEC_2 (0x4UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00040000 */ +#define TAMP_SECCFGR_BKPWSEC_3 (0x8UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00080000 */ +#define TAMP_SECCFGR_BKPWSEC_4 (0x10UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00100000 */ +#define TAMP_SECCFGR_BKPWSEC_5 (0x20UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00200000 */ +#define TAMP_SECCFGR_BKPWSEC_6 (0x40UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00400000 */ +#define TAMP_SECCFGR_BKPWSEC_7 (0x80UL << TAMP_SECCFGR_BKPWSEC_Pos) /*!< 0x00800000 */ +#define TAMP_SECCFGR_BHKLOCK_Pos (30U) +#define TAMP_SECCFGR_BHKLOCK_Msk (0x1UL << TAMP_SECCFGR_BHKLOCK_Pos) /*!< 0x40000000 */ +#define TAMP_SECCFGR_BHKLOCK TAMP_SECCFGR_BHKLOCK_Msk +#define TAMP_SECCFGR_TAMPSEC_Pos (31U) +#define TAMP_SECCFGR_TAMPSEC_Msk (0x1UL << TAMP_SECCFGR_TAMPSEC_Pos) /*!< 0x80000000 */ +#define TAMP_SECCFGR_TAMPSEC TAMP_SECCFGR_TAMPSEC_Msk + +/******************** Bits definition for TAMP_PRIVCFGR register ************/ +#define TAMP_PRIVCFGR_CNT1PRIV_Pos (15U) +#define TAMP_PRIVCFGR_CNT1PRIV_Msk (0x1UL << TAMP_PRIVCFGR_CNT1PRIV_Pos) /*!< 0x20000000 */ +#define TAMP_PRIVCFGR_CNT1PRIV TAMP_PRIVCFGR_CNT1PRIV_Msk +#define TAMP_PRIVCFGR_BKPRWPRIV_Pos (29U) +#define TAMP_PRIVCFGR_BKPRWPRIV_Msk (0x1UL << TAMP_PRIVCFGR_BKPRWPRIV_Pos) /*!< 0x20000000 */ +#define TAMP_PRIVCFGR_BKPRWPRIV TAMP_PRIVCFGR_BKPRWPRIV_Msk +#define TAMP_PRIVCFGR_BKPWPRIV_Pos (30U) +#define TAMP_PRIVCFGR_BKPWPRIV_Msk (0x1UL << TAMP_PRIVCFGR_BKPWPRIV_Pos) /*!< 0x40000000 */ +#define TAMP_PRIVCFGR_BKPWPRIV TAMP_PRIVCFGR_BKPWPRIV_Msk +#define TAMP_PRIVCFGR_TAMPPRIV_Pos (31U) +#define TAMP_PRIVCFGR_TAMPPRIV_Msk (0x1UL << TAMP_PRIVCFGR_TAMPPRIV_Pos) /*!< 0x80000000 */ +#define TAMP_PRIVCFGR_TAMPPRIV TAMP_PRIVCFGR_TAMPPRIV_Msk + +/******************** Bits definition for TAMP_IER register *****************/ +#define TAMP_IER_TAMP1IE_Pos (0U) +#define TAMP_IER_TAMP1IE_Msk (0x1UL << TAMP_IER_TAMP1IE_Pos) /*!< 0x00000001 */ +#define TAMP_IER_TAMP1IE TAMP_IER_TAMP1IE_Msk +#define TAMP_IER_TAMP2IE_Pos (1U) +#define TAMP_IER_TAMP2IE_Msk (0x1UL << TAMP_IER_TAMP2IE_Pos) /*!< 0x00000002 */ +#define TAMP_IER_TAMP2IE TAMP_IER_TAMP2IE_Msk +#define TAMP_IER_TAMP3IE_Pos (2U) +#define TAMP_IER_TAMP3IE_Msk (0x1UL << TAMP_IER_TAMP3IE_Pos) /*!< 0x00000004 */ +#define TAMP_IER_TAMP3IE TAMP_IER_TAMP3IE_Msk +#define TAMP_IER_TAMP4IE_Pos (3U) +#define TAMP_IER_TAMP4IE_Msk (0x1UL << TAMP_IER_TAMP4IE_Pos) /*!< 0x00000008 */ +#define TAMP_IER_TAMP4IE TAMP_IER_TAMP4IE_Msk +#define TAMP_IER_TAMP5IE_Pos (4U) +#define TAMP_IER_TAMP5IE_Msk (0x1UL << TAMP_IER_TAMP5IE_Pos) /*!< 0x00000010 */ +#define TAMP_IER_TAMP5IE TAMP_IER_TAMP5IE_Msk +#define TAMP_IER_TAMP6IE_Pos (5U) +#define TAMP_IER_TAMP6IE_Msk (0x1UL << TAMP_IER_TAMP6IE_Pos) /*!< 0x00000020 */ +#define TAMP_IER_TAMP6IE TAMP_IER_TAMP6IE_Msk +#define TAMP_IER_TAMP7IE_Pos (6U) +#define TAMP_IER_TAMP7IE_Msk (0x1UL << TAMP_IER_TAMP7IE_Pos) /*!< 0x00000040 */ +#define TAMP_IER_TAMP7IE TAMP_IER_TAMP7IE_Msk +#define TAMP_IER_TAMP8IE_Pos (7U) +#define TAMP_IER_TAMP8IE_Msk (0x1UL << TAMP_IER_TAMP8IE_Pos) /*!< 0x00000080 */ +#define TAMP_IER_TAMP8IE TAMP_IER_TAMP8IE_Msk +#define TAMP_IER_ITAMP1IE_Pos (16U) +#define TAMP_IER_ITAMP1IE_Msk (0x1UL << TAMP_IER_ITAMP1IE_Pos) /*!< 0x00010000 */ +#define TAMP_IER_ITAMP1IE TAMP_IER_ITAMP1IE_Msk +#define TAMP_IER_ITAMP2IE_Pos (17U) +#define TAMP_IER_ITAMP2IE_Msk (0x1UL << TAMP_IER_ITAMP2IE_Pos) /*!< 0x00020000 */ +#define TAMP_IER_ITAMP2IE TAMP_IER_ITAMP2IE_Msk +#define TAMP_IER_ITAMP3IE_Pos (18U) +#define TAMP_IER_ITAMP3IE_Msk (0x1UL << TAMP_IER_ITAMP3IE_Pos) /*!< 0x00040000 */ +#define TAMP_IER_ITAMP3IE TAMP_IER_ITAMP3IE_Msk +#define TAMP_IER_ITAMP4IE_Pos (19U) +#define TAMP_IER_ITAMP4IE_Msk (0x1UL << TAMP_IER_ITAMP4IE_Pos) /*!< 0x00080000 */ +#define TAMP_IER_ITAMP4IE TAMP_IER_ITAMP4IE_Msk +#define TAMP_IER_ITAMP5IE_Pos (20U) +#define TAMP_IER_ITAMP5IE_Msk (0x1UL << TAMP_IER_ITAMP5IE_Pos) /*!< 0x00100000 */ +#define TAMP_IER_ITAMP5IE TAMP_IER_ITAMP5IE_Msk +#define TAMP_IER_ITAMP6IE_Pos (21U) +#define TAMP_IER_ITAMP6IE_Msk (0x1UL << TAMP_IER_ITAMP6IE_Pos) /*!< 0x00200000 */ +#define TAMP_IER_ITAMP6IE TAMP_IER_ITAMP6IE_Msk +#define TAMP_IER_ITAMP7IE_Pos (22U) +#define TAMP_IER_ITAMP7IE_Msk (0x1UL << TAMP_IER_ITAMP7IE_Pos) /*!< 0x00400000 */ +#define TAMP_IER_ITAMP7IE TAMP_IER_ITAMP7IE_Msk +#define TAMP_IER_ITAMP8IE_Pos (23U) +#define TAMP_IER_ITAMP8IE_Msk (0x1UL << TAMP_IER_ITAMP8IE_Pos) /*!< 0x00800000 */ +#define TAMP_IER_ITAMP8IE TAMP_IER_ITAMP8IE_Msk +#define TAMP_IER_ITAMP9IE_Pos (24U) +#define TAMP_IER_ITAMP9IE_Msk (0x1UL << TAMP_IER_ITAMP9IE_Pos) /*!< 0x01000000 */ +#define TAMP_IER_ITAMP9IE TAMP_IER_ITAMP9IE_Msk +#define TAMP_IER_ITAMP11IE_Pos (26U) +#define TAMP_IER_ITAMP11IE_Msk (0x1UL << TAMP_IER_ITAMP11IE_Pos) /*!< 0x04000000 */ +#define TAMP_IER_ITAMP11IE TAMP_IER_ITAMP11IE_Msk +#define TAMP_IER_ITAMP12IE_Pos (27U) +#define TAMP_IER_ITAMP12IE_Msk (0x1UL << TAMP_IER_ITAMP12IE_Pos) /*!< 0x08000000 */ +#define TAMP_IER_ITAMP12IE TAMP_IER_ITAMP12IE_Msk +#define TAMP_IER_ITAMP13IE_Pos (28U) +#define TAMP_IER_ITAMP13IE_Msk (0x1UL << TAMP_IER_ITAMP13IE_Pos) /*!< 0x10000000 */ +#define TAMP_IER_ITAMP13IE TAMP_IER_ITAMP13IE_Msk +#define TAMP_IER_ITAMP15IE_Pos (30U) +#define TAMP_IER_ITAMP15IE_Msk (0x1UL << TAMP_IER_ITAMP15IE_Pos) /*!< 0x40000000 */ +#define TAMP_IER_ITAMP15IE TAMP_IER_ITAMP15IE_Msk + +/******************** Bits definition for TAMP_SR register *****************/ +#define TAMP_SR_TAMP1F_Pos (0U) +#define TAMP_SR_TAMP1F_Msk (0x1UL << TAMP_SR_TAMP1F_Pos) /*!< 0x00000001 */ +#define TAMP_SR_TAMP1F TAMP_SR_TAMP1F_Msk +#define TAMP_SR_TAMP2F_Pos (1U) +#define TAMP_SR_TAMP2F_Msk (0x1UL << TAMP_SR_TAMP2F_Pos) /*!< 0x00000002 */ +#define TAMP_SR_TAMP2F TAMP_SR_TAMP2F_Msk +#define TAMP_SR_TAMP3F_Pos (2U) +#define TAMP_SR_TAMP3F_Msk (0x1UL << TAMP_SR_TAMP3F_Pos) /*!< 0x00000004 */ +#define TAMP_SR_TAMP3F TAMP_SR_TAMP3F_Msk +#define TAMP_SR_TAMP4F_Pos (3U) +#define TAMP_SR_TAMP4F_Msk (0x1UL << TAMP_SR_TAMP4F_Pos) /*!< 0x00000008 */ +#define TAMP_SR_TAMP4F TAMP_SR_TAMP4F_Msk +#define TAMP_SR_TAMP5F_Pos (4U) +#define TAMP_SR_TAMP5F_Msk (0x1UL << TAMP_SR_TAMP5F_Pos) /*!< 0x00000010 */ +#define TAMP_SR_TAMP5F TAMP_SR_TAMP5F_Msk +#define TAMP_SR_TAMP6F_Pos (5U) +#define TAMP_SR_TAMP6F_Msk (0x1UL << TAMP_SR_TAMP6F_Pos) /*!< 0x00000020 */ +#define TAMP_SR_TAMP6F TAMP_SR_TAMP6F_Msk +#define TAMP_SR_TAMP7F_Pos (6U) +#define TAMP_SR_TAMP7F_Msk (0x1UL << TAMP_SR_TAMP7F_Pos) /*!< 0x00000040 */ +#define TAMP_SR_TAMP7F TAMP_SR_TAMP7F_Msk +#define TAMP_SR_TAMP8F_Pos (7U) +#define TAMP_SR_TAMP8F_Msk (0x1UL << TAMP_SR_TAMP8F_Pos) /*!< 0x00000080 */ +#define TAMP_SR_TAMP8F TAMP_SR_TAMP8F_Msk +#define TAMP_SR_ITAMP1F_Pos (16U) +#define TAMP_SR_ITAMP1F_Msk (0x1UL << TAMP_SR_ITAMP1F_Pos) /*!< 0x00010000 */ +#define TAMP_SR_ITAMP1F TAMP_SR_ITAMP1F_Msk +#define TAMP_SR_ITAMP2F_Pos (17U) +#define TAMP_SR_ITAMP2F_Msk (0x1UL << TAMP_SR_ITAMP2F_Pos) /*!< 0x00020000 */ +#define TAMP_SR_ITAMP2F TAMP_SR_ITAMP2F_Msk +#define TAMP_SR_ITAMP3F_Pos (18U) +#define TAMP_SR_ITAMP3F_Msk (0x1UL << TAMP_SR_ITAMP3F_Pos) /*!< 0x00040000 */ +#define TAMP_SR_ITAMP3F TAMP_SR_ITAMP3F_Msk +#define TAMP_SR_ITAMP4F_Pos (19U) +#define TAMP_SR_ITAMP4F_Msk (0x1UL << TAMP_SR_ITAMP4F_Pos) /*!< 0x00080000 */ +#define TAMP_SR_ITAMP4F TAMP_SR_ITAMP4F_Msk +#define TAMP_SR_ITAMP5F_Pos (20U) +#define TAMP_SR_ITAMP5F_Msk (0x1UL << TAMP_SR_ITAMP5F_Pos) /*!< 0x00100000 */ +#define TAMP_SR_ITAMP5F TAMP_SR_ITAMP5F_Msk +#define TAMP_SR_ITAMP6F_Pos (21U) +#define TAMP_SR_ITAMP6F_Msk (0x1UL << TAMP_SR_ITAMP6F_Pos) /*!< 0x00200000 */ +#define TAMP_SR_ITAMP6F TAMP_SR_ITAMP6F_Msk +#define TAMP_SR_ITAMP7F_Pos (22U) +#define TAMP_SR_ITAMP7F_Msk (0x1UL << TAMP_SR_ITAMP7F_Pos) /*!< 0x00400000 */ +#define TAMP_SR_ITAMP7F TAMP_SR_ITAMP7F_Msk +#define TAMP_SR_ITAMP8F_Pos (23U) +#define TAMP_SR_ITAMP8F_Msk (0x1UL << TAMP_SR_ITAMP8F_Pos) /*!< 0x00800000 */ +#define TAMP_SR_ITAMP8F TAMP_SR_ITAMP8F_Msk +#define TAMP_SR_ITAMP9F_Pos (24U) +#define TAMP_SR_ITAMP9F_Msk (0x1UL << TAMP_SR_ITAMP9F_Pos) /*!< 0x01000000 */ +#define TAMP_SR_ITAMP9F TAMP_SR_ITAMP9F_Msk +#define TAMP_SR_ITAMP11F_Pos (26U) +#define TAMP_SR_ITAMP11F_Msk (0x1UL << TAMP_SR_ITAMP11F_Pos) /*!< 0x04000000 */ +#define TAMP_SR_ITAMP11F TAMP_SR_ITAMP11F_Msk +#define TAMP_SR_ITAMP12F_Pos (27U) +#define TAMP_SR_ITAMP12F_Msk (0x1UL << TAMP_SR_ITAMP12F_Pos) /*!< 0x08000000 */ +#define TAMP_SR_ITAMP12F TAMP_SR_ITAMP12F_Msk +#define TAMP_SR_ITAMP13F_Pos (28U) +#define TAMP_SR_ITAMP13F_Msk (0x1UL << TAMP_SR_ITAMP13F_Pos) /*!< 0x10000000 */ +#define TAMP_SR_ITAMP13F TAMP_SR_ITAMP13F_Msk +#define TAMP_SR_ITAMP15F_Pos (30U) +#define TAMP_SR_ITAMP15F_Msk (0x1UL << TAMP_SR_ITAMP15F_Pos) /*!< 0x40000000 */ +#define TAMP_SR_ITAMP15F TAMP_SR_ITAMP15F_Msk + +/******************** Bits definition for TAMP_MISR register ****************/ +#define TAMP_MISR_TAMP1MF_Pos (0U) +#define TAMP_MISR_TAMP1MF_Msk (0x1UL << TAMP_MISR_TAMP1MF_Pos) /*!< 0x00000001 */ +#define TAMP_MISR_TAMP1MF TAMP_MISR_TAMP1MF_Msk +#define TAMP_MISR_TAMP2MF_Pos (1U) +#define TAMP_MISR_TAMP2MF_Msk (0x1UL << TAMP_MISR_TAMP2MF_Pos) /*!< 0x00000002 */ +#define TAMP_MISR_TAMP2MF TAMP_MISR_TAMP2MF_Msk +#define TAMP_MISR_TAMP3MF_Pos (2U) +#define TAMP_MISR_TAMP3MF_Msk (0x1UL << TAMP_MISR_TAMP3MF_Pos) /*!< 0x00000004 */ +#define TAMP_MISR_TAMP3MF TAMP_MISR_TAMP3MF_Msk +#define TAMP_MISR_TAMP4MF_Pos (3U) +#define TAMP_MISR_TAMP4MF_Msk (0x1UL << TAMP_MISR_TAMP4MF_Pos) /*!< 0x00000008 */ +#define TAMP_MISR_TAMP4MF TAMP_MISR_TAMP4MF_Msk +#define TAMP_MISR_TAMP5MF_Pos (4U) +#define TAMP_MISR_TAMP5MF_Msk (0x1UL << TAMP_MISR_TAMP5MF_Pos) /*!< 0x00000010 */ +#define TAMP_MISR_TAMP5MF TAMP_MISR_TAMP5MF_Msk +#define TAMP_MISR_TAMP6MF_Pos (5U) +#define TAMP_MISR_TAMP6MF_Msk (0x1UL << TAMP_MISR_TAMP6MF_Pos) /*!< 0x00000020 */ +#define TAMP_MISR_TAMP6MF TAMP_MISR_TAMP6MF_Msk +#define TAMP_MISR_TAMP7MF_Pos (6U) +#define TAMP_MISR_TAMP7MF_Msk (0x1UL << TAMP_MISR_TAMP7MF_Pos) /*!< 0x00000040 */ +#define TAMP_MISR_TAMP7MF TAMP_MISR_TAMP7MF_Msk +#define TAMP_MISR_TAMP8MF_Pos (7U) +#define TAMP_MISR_TAMP8MF_Msk (0x1UL << TAMP_MISR_TAMP8MF_Pos) /*!< 0x00000080 */ +#define TAMP_MISR_TAMP8MF TAMP_MISR_TAMP8MF_Msk +#define TAMP_MISR_ITAMP1MF_Pos (16U) +#define TAMP_MISR_ITAMP1MF_Msk (0x1UL << TAMP_MISR_ITAMP1MF_Pos) /*!< 0x00010000 */ +#define TAMP_MISR_ITAMP1MF TAMP_MISR_ITAMP1MF_Msk +#define TAMP_MISR_ITAMP2MF_Pos (17U) +#define TAMP_MISR_ITAMP2MF_Msk (0x1UL << TAMP_MISR_ITAMP2MF_Pos) /*!< 0x00020000 */ +#define TAMP_MISR_ITAMP2MF TAMP_MISR_ITAMP2MF_Msk +#define TAMP_MISR_ITAMP3MF_Pos (18U) +#define TAMP_MISR_ITAMP3MF_Msk (0x1UL << TAMP_MISR_ITAMP3MF_Pos) /*!< 0x00040000 */ +#define TAMP_MISR_ITAMP3MF TAMP_MISR_ITAMP3MF_Msk +#define TAMP_MISR_ITAMP4MF_Pos (19U) +#define TAMP_MISR_ITAMP4MF_Msk (0x1UL << TAMP_MISR_ITAMP4MF_Pos) /*!< 0x00080000 */ +#define TAMP_MISR_ITAMP4MF TAMP_MISR_ITAMP4MF_Msk +#define TAMP_MISR_ITAMP5MF_Pos (20U) +#define TAMP_MISR_ITAMP5MF_Msk (0x1UL << TAMP_MISR_ITAMP5MF_Pos) /*!< 0x00100000 */ +#define TAMP_MISR_ITAMP5MF TAMP_MISR_ITAMP5MF_Msk +#define TAMP_MISR_ITAMP6MF_Pos (21U) +#define TAMP_MISR_ITAMP6MF_Msk (0x1UL << TAMP_MISR_ITAMP6MF_Pos) /*!< 0x00200000 */ +#define TAMP_MISR_ITAMP6MF TAMP_MISR_ITAMP6MF_Msk +#define TAMP_MISR_ITAMP7MF_Pos (22U) +#define TAMP_MISR_ITAMP7MF_Msk (0x1UL << TAMP_MISR_ITAMP7MF_Pos) /*!< 0x00400000 */ +#define TAMP_MISR_ITAMP7MF TAMP_MISR_ITAMP7MF_Msk +#define TAMP_MISR_ITAMP8MF_Pos (23U) +#define TAMP_MISR_ITAMP8MF_Msk (0x1UL << TAMP_MISR_ITAMP8MF_Pos) /*!< 0x00800000 */ +#define TAMP_MISR_ITAMP8MF TAMP_MISR_ITAMP8MF_Msk +#define TAMP_MISR_ITAMP9MF_Pos (24U) +#define TAMP_MISR_ITAMP9MF_Msk (0x1UL << TAMP_MISR_ITAMP9MF_Pos) /*!< 0x01000000 */ +#define TAMP_MISR_ITAMP9MF TAMP_MISR_ITAMP9MF_Msk +#define TAMP_MISR_ITAMP11MF_Pos (26U) +#define TAMP_MISR_ITAMP11MF_Msk (0x1UL << TAMP_MISR_ITAMP11MF_Pos) /*!< 0x04000000 */ +#define TAMP_MISR_ITAMP11MF TAMP_MISR_ITAMP11MF_Msk +#define TAMP_MISR_ITAMP12MF_Pos (27U) +#define TAMP_MISR_ITAMP12MF_Msk (0x1UL << TAMP_MISR_ITAMP12MF_Pos) /*!< 0x08000000 */ +#define TAMP_MISR_ITAMP12MF TAMP_MISR_ITAMP12MF_Msk +#define TAMP_MISR_ITAMP13MF_Pos (28U) +#define TAMP_MISR_ITAMP13MF_Msk (0x1UL << TAMP_MISR_ITAMP13MF_Pos) /*!< 0x10000000 */ +#define TAMP_MISR_ITAMP13MF TAMP_MISR_ITAMP13MF_Msk +#define TAMP_MISR_ITAMP15MF_Pos (30U) +#define TAMP_MISR_ITAMP15MF_Msk (0x1UL << TAMP_MISR_ITAMP15MF_Pos) /*!< 0x40000000 */ +#define TAMP_MISR_ITAMP15MF TAMP_MISR_ITAMP15MF_Msk + +/******************** Bits definition for TAMP_SMISR register ************ *****/ +#define TAMP_SMISR_TAMP1MF_Pos (0U) +#define TAMP_SMISR_TAMP1MF_Msk (0x1UL << TAMP_SMISR_TAMP1MF_Pos) /*!< 0x00000001 */ +#define TAMP_SMISR_TAMP1MF TAMP_SMISR_TAMP1MF_Msk +#define TAMP_SMISR_TAMP2MF_Pos (1U) +#define TAMP_SMISR_TAMP2MF_Msk (0x1UL << TAMP_SMISR_TAMP2MF_Pos) /*!< 0x00000002 */ +#define TAMP_SMISR_TAMP2MF TAMP_SMISR_TAMP2MF_Msk +#define TAMP_SMISR_TAMP3MF_Pos (2U) +#define TAMP_SMISR_TAMP3MF_Msk (0x1UL << TAMP_SMISR_TAMP3MF_Pos) /*!< 0x00000004 */ +#define TAMP_SMISR_TAMP3MF TAMP_SMISR_TAMP3MF_Msk +#define TAMP_SMISR_TAMP4MF_Pos (3U) +#define TAMP_SMISR_TAMP4MF_Msk (0x1UL << TAMP_SMISR_TAMP4MF_Pos) /*!< 0x00000008 */ +#define TAMP_SMISR_TAMP4MF TAMP_SMISR_TAMP4MF_Msk +#define TAMP_SMISR_TAMP5MF_Pos (4U) +#define TAMP_SMISR_TAMP5MF_Msk (0x1UL << TAMP_SMISR_TAMP5MF_Pos) /*!< 0x00000010 */ +#define TAMP_SMISR_TAMP5MF TAMP_SMISR_TAMP5MF_Msk +#define TAMP_SMISR_TAMP6MF_Pos (5U) +#define TAMP_SMISR_TAMP6MF_Msk (0x1UL << TAMP_SMISR_TAMP6MF_Pos) /*!< 0x00000020 */ +#define TAMP_SMISR_TAMP6MF TAMP_SMISR_TAMP6MF_Msk +#define TAMP_SMISR_TAMP7MF_Pos (6U) +#define TAMP_SMISR_TAMP7MF_Msk (0x1UL << TAMP_SMISR_TAMP7MF_Pos) /*!< 0x00000040 */ +#define TAMP_SMISR_TAMP7MF TAMP_SMISR_TAMP7MF_Msk +#define TAMP_SMISR_TAMP8MF_Pos (7U) +#define TAMP_SMISR_TAMP8MF_Msk (0x1UL << TAMP_SMISR_TAMP8MF_Pos) /*!< 0x00000080 */ +#define TAMP_SMISR_TAMP8MF TAMP_SMISR_TAMP8MF_Msk +#define TAMP_SMISR_ITAMP1MF_Pos (16U) +#define TAMP_SMISR_ITAMP1MF_Msk (0x1UL << TAMP_SMISR_ITAMP1MF_Pos) /*!< 0x00010000 */ +#define TAMP_SMISR_ITAMP1MF TAMP_SMISR_ITAMP1MF_Msk +#define TAMP_SMISR_ITAMP2MF_Pos (17U) +#define TAMP_SMISR_ITAMP2MF_Msk (0x1UL << TAMP_SMISR_ITAMP2MF_Pos) /*!< 0x00020000 */ +#define TAMP_SMISR_ITAMP2MF TAMP_SMISR_ITAMP2MF_Msk +#define TAMP_SMISR_ITAMP3MF_Pos (18U) +#define TAMP_SMISR_ITAMP3MF_Msk (0x1UL << TAMP_SMISR_ITAMP3MF_Pos) /*!< 0x00040000 */ +#define TAMP_SMISR_ITAMP3MF TAMP_SMISR_ITAMP3MF_Msk +#define TAMP_SMISR_ITAMP4MF_Pos (19U) +#define TAMP_SMISR_ITAMP4MF_Msk (0x1UL << TAMP_SMISR_ITAMP4MF_Pos) /*!< 0x00080000 */ +#define TAMP_SMISR_ITAMP4MF TAMP_SMISR_ITAMP4MF_Msk +#define TAMP_SMISR_ITAMP5MF_Pos (20U) +#define TAMP_SMISR_ITAMP5MF_Msk (0x1UL << TAMP_SMISR_ITAMP5MF_Pos) /*!< 0x00100000 */ +#define TAMP_SMISR_ITAMP5MF TAMP_SMISR_ITAMP5MF_Msk +#define TAMP_SMISR_ITAMP6MF_Pos (21U) +#define TAMP_SMISR_ITAMP6MF_Msk (0x1UL << TAMP_SMISR_ITAMP6MF_Pos) /*!< 0x00200000 */ +#define TAMP_SMISR_ITAMP6MF TAMP_SMISR_ITAMP6MF_Msk +#define TAMP_SMISR_ITAMP7MF_Pos (22U) +#define TAMP_SMISR_ITAMP7MF_Msk (0x1UL << TAMP_SMISR_ITAMP7MF_Pos) /*!< 0x00400000 */ +#define TAMP_SMISR_ITAMP7MF TAMP_SMISR_ITAMP7MF_Msk +#define TAMP_SMISR_ITAMP8MF_Pos (23U) +#define TAMP_SMISR_ITAMP8MF_Msk (0x1UL << TAMP_SMISR_ITAMP8MF_Pos) /*!< 0x00800000 */ +#define TAMP_SMISR_ITAMP8MF TAMP_SMISR_ITAMP8MF_Msk +#define TAMP_SMISR_ITAMP9MF_Pos (24U) +#define TAMP_SMISR_ITAMP9MF_Msk (0x1UL << TAMP_SMISR_ITAMP9MF_Pos) /*!< 0x00100000 */ +#define TAMP_SMISR_ITAMP9MF TAMP_SMISR_ITAMP9MF_Msk +#define TAMP_SMISR_ITAMP11MF_Pos (26U) +#define TAMP_SMISR_ITAMP11MF_Msk (0x1UL << TAMP_SMISR_ITAMP11MF_Pos) /*!< 0x00400000 */ +#define TAMP_SMISR_ITAMP11MF TAMP_SMISR_ITAMP11MF_Msk +#define TAMP_SMISR_ITAMP12MF_Pos (27U) +#define TAMP_SMISR_ITAMP12MF_Msk (0x1UL << TAMP_SMISR_ITAMP12MF_Pos) /*!< 0x08000000 */ +#define TAMP_SMISR_ITAMP12MF TAMP_SMISR_ITAMP12MF_Msk +#define TAMP_SMISR_ITAMP13MF_Pos (28U) +#define TAMP_SMISR_ITAMP13MF_Msk (0x1UL << TAMP_SMISR_ITAMP13MF_Pos) /*!< 0x10000000 */ +#define TAMP_SMISR_ITAMP13MF TAMP_SMISR_ITAMP13MF_Msk +#define TAMP_SMISR_ITAMP15MF_Pos (30U) +#define TAMP_SMISR_ITAMP15MF_Msk (0x1UL << TAMP_SMISR_ITAMP15MF_Pos) /*!< 0x40000000 */ +#define TAMP_SMISR_ITAMP15MF TAMP_SMISR_ITAMP15MF_Msk + +/******************** Bits definition for TAMP_SCR register *****************/ +#define TAMP_SCR_CTAMP1F_Pos (0U) +#define TAMP_SCR_CTAMP1F_Msk (0x1UL << TAMP_SCR_CTAMP1F_Pos) /*!< 0x00000001 */ +#define TAMP_SCR_CTAMP1F TAMP_SCR_CTAMP1F_Msk +#define TAMP_SCR_CTAMP2F_Pos (1U) +#define TAMP_SCR_CTAMP2F_Msk (0x1UL << TAMP_SCR_CTAMP2F_Pos) /*!< 0x00000002 */ +#define TAMP_SCR_CTAMP2F TAMP_SCR_CTAMP2F_Msk +#define TAMP_SCR_CTAMP3F_Pos (2U) +#define TAMP_SCR_CTAMP3F_Msk (0x1UL << TAMP_SCR_CTAMP3F_Pos) /*!< 0x00000004 */ +#define TAMP_SCR_CTAMP3F TAMP_SCR_CTAMP3F_Msk +#define TAMP_SCR_CTAMP4F_Pos (3U) +#define TAMP_SCR_CTAMP4F_Msk (0x1UL << TAMP_SCR_CTAMP4F_Pos) /*!< 0x00000008 */ +#define TAMP_SCR_CTAMP4F TAMP_SCR_CTAMP4F_Msk +#define TAMP_SCR_CTAMP5F_Pos (4U) +#define TAMP_SCR_CTAMP5F_Msk (0x1UL << TAMP_SCR_CTAMP5F_Pos) /*!< 0x00000010 */ +#define TAMP_SCR_CTAMP5F TAMP_SCR_CTAMP5F_Msk +#define TAMP_SCR_CTAMP6F_Pos (5U) +#define TAMP_SCR_CTAMP6F_Msk (0x1UL << TAMP_SCR_CTAMP6F_Pos) /*!< 0x00000020 */ +#define TAMP_SCR_CTAMP6F TAMP_SCR_CTAMP6F_Msk +#define TAMP_SCR_CTAMP7F_Pos (6U) +#define TAMP_SCR_CTAMP7F_Msk (0x1UL << TAMP_SCR_CTAMP7F_Pos) /*!< 0x00000040 */ +#define TAMP_SCR_CTAMP7F TAMP_SCR_CTAMP7F_Msk +#define TAMP_SCR_CTAMP8F_Pos (7U) +#define TAMP_SCR_CTAMP8F_Msk (0x1UL << TAMP_SCR_CTAMP8F_Pos) /*!< 0x00000080 */ +#define TAMP_SCR_CTAMP8F TAMP_SCR_CTAMP8F_Msk +#define TAMP_SCR_CITAMP1F_Pos (16U) +#define TAMP_SCR_CITAMP1F_Msk (0x1UL << TAMP_SCR_CITAMP1F_Pos) /*!< 0x00010000 */ +#define TAMP_SCR_CITAMP1F TAMP_SCR_CITAMP1F_Msk +#define TAMP_SCR_CITAMP2F_Pos (17U) +#define TAMP_SCR_CITAMP2F_Msk (0x1UL << TAMP_SCR_CITAMP2F_Pos) /*!< 0x00020000 */ +#define TAMP_SCR_CITAMP2F TAMP_SCR_CITAMP2F_Msk +#define TAMP_SCR_CITAMP3F_Pos (18U) +#define TAMP_SCR_CITAMP3F_Msk (0x1UL << TAMP_SCR_CITAMP3F_Pos) /*!< 0x00040000 */ +#define TAMP_SCR_CITAMP3F TAMP_SCR_CITAMP3F_Msk +#define TAMP_SCR_CITAMP4F_Pos (19U) +#define TAMP_SCR_CITAMP4F_Msk (0x1UL << TAMP_SCR_CITAMP4F_Pos) /*!< 0x00080000 */ +#define TAMP_SCR_CITAMP4F TAMP_SCR_CITAMP4F_Msk +#define TAMP_SCR_CITAMP5F_Pos (20U) +#define TAMP_SCR_CITAMP5F_Msk (0x1UL << TAMP_SCR_CITAMP5F_Pos) /*!< 0x00100000 */ +#define TAMP_SCR_CITAMP5F TAMP_SCR_CITAMP5F_Msk +#define TAMP_SCR_CITAMP6F_Pos (21U) +#define TAMP_SCR_CITAMP6F_Msk (0x1UL << TAMP_SCR_CITAMP6F_Pos) /*!< 0x00200000 */ +#define TAMP_SCR_CITAMP6F TAMP_SCR_CITAMP6F_Msk +#define TAMP_SCR_CITAMP7F_Pos (22U) +#define TAMP_SCR_CITAMP7F_Msk (0x1UL << TAMP_SCR_CITAMP7F_Pos) /*!< 0x00400000 */ +#define TAMP_SCR_CITAMP7F TAMP_SCR_CITAMP7F_Msk +#define TAMP_SCR_CITAMP8F_Pos (23U) +#define TAMP_SCR_CITAMP8F_Msk (0x1UL << TAMP_SCR_CITAMP8F_Pos) /*!< 0x00800000 */ +#define TAMP_SCR_CITAMP8F TAMP_SCR_CITAMP8F_Msk +#define TAMP_SCR_CITAMP9F_Pos (24U) +#define TAMP_SCR_CITAMP9F_Msk (0x1UL << TAMP_SCR_CITAMP9F_Pos) /*!< 0x00100000 */ +#define TAMP_SCR_CITAMP9F TAMP_SCR_CITAMP9F_Msk +#define TAMP_SCR_CITAMP11F_Pos (26U) +#define TAMP_SCR_CITAMP11F_Msk (0x1UL << TAMP_SCR_CITAMP11F_Pos) /*!< 0x00400000 */ +#define TAMP_SCR_CITAMP11F TAMP_SCR_CITAMP11F_Msk +#define TAMP_SCR_CITAMP12F_Pos (27U) +#define TAMP_SCR_CITAMP12F_Msk (0x1UL << TAMP_SCR_CITAMP12F_Pos) /*!< 0x08000000 */ +#define TAMP_SCR_CITAMP12F TAMP_SCR_CITAMP12F_Msk +#define TAMP_SCR_CITAMP13F_Pos (28U) +#define TAMP_SCR_CITAMP13F_Msk (0x1UL << TAMP_SCR_CITAMP13F_Pos) /*!< 0x10000000 */ +#define TAMP_SCR_CITAMP13F TAMP_SCR_CITAMP13F_Msk +#define TAMP_SCR_CITAMP15F_Pos (30U) +#define TAMP_SCR_CITAMP15F_Msk (0x1UL << TAMP_SCR_CITAMP15F_Pos) /*!< 0x40000000 */ +#define TAMP_SCR_CITAMP15F TAMP_SCR_CITAMP15F_Msk +/******************** Bits definition for TAMP_COUNT1R register ***************/ +#define TAMP_COUNT1R_COUNT_Pos (0U) +#define TAMP_COUNT1R_COUNT_Msk (0xFFFFFFFFUL << TAMP_COUNT1R_COUNT_Pos)/*!< 0xFFFFFFFF */ +#define TAMP_COUNT1R_COUNT TAMP_COUNT1R_COUNT_Msk + +/******************** Bits definition for TAMP_OR register ***************/ +#define TAMP_OR_OUT3_RMP_Pos (1U) +#define TAMP_OR_OUT3_RMP_Msk (0x2UL << TAMP_OR_OUT3_RMP_Pos) /*!< 0x00000006 */ +#define TAMP_OR_OUT3_RMP TAMP_OR_OUT3_RMP_Msk +#define TAMP_OR_OUT3_RMP_0 (0x1UL << TAMP_OR_OUT3_RMP_Pos) /*!< 0x00100000 */ +#define TAMP_OR_OUT3_RMP_1 (0x2UL << TAMP_OR_OUT3_RMP_Pos) /*!< 0x00200000 */ +#define TAMP_OR_OUT5_RMP_Pos (3U) +#define TAMP_OR_OUT5_RMP_Msk (0x1UL << TAMP_OR_OUT5_RMP_Pos) /*!< 0x00000001 */ +#define TAMP_OR_OUT5_RMP TAMP_OR_OUT5_RMP_Msk +#define TAMP_OR_IN2_RMP_Pos (8U) +#define TAMP_OR_IN2_RMP_Msk (0x1UL << TAMP_OR_IN2_RMP_Pos) /*!< 0x00000001 */ +#define TAMP_OR_IN2_RMP TAMP_OR_IN2_RMP_Msk +#define TAMP_OR_IN3_RMP_Pos (9U) +#define TAMP_OR_IN3_RMP_Msk (0x1UL << TAMP_OR_IN3_RMP_Pos) /*!< 0x00000001 */ +#define TAMP_OR_IN3_RMP TAMP_OR_IN3_RMP_Msk +#define TAMP_OR_IN4_RMP_Pos (10U) +#define TAMP_OR_IN4_RMP_Msk (0x1UL << TAMP_OR_IN4_RMP_Pos) /*!< 0x00000001 */ +#define TAMP_OR_IN4_RMP TAMP_OR_IN4_RMP_Msk + +/******************** Bits definition for TAMP_ERCFG register ***************/ +#define TAMP_ERCFGR_ERCFG0_Pos (0U) +#define TAMP_ERCFGR_ERCFG0_Msk (0x1UL << TAMP_ERCFGR_ERCFG0_Pos) /*!< 0x00000001 */ +#define TAMP_ERCFGR_ERCFG0 TAMP_ERCFGR_ERCFG0_Msk + +/******************** Bits definition for TAMP_BKP0R register ***************/ +#define TAMP_BKP0R_Pos (0U) +#define TAMP_BKP0R_Msk (0xFFFFFFFFUL << TAMP_BKP0R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP0R TAMP_BKP0R_Msk + +/******************** Bits definition for TAMP_BKP1R register ****************/ +#define TAMP_BKP1R_Pos (0U) +#define TAMP_BKP1R_Msk (0xFFFFFFFFUL << TAMP_BKP1R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP1R TAMP_BKP1R_Msk + +/******************** Bits definition for TAMP_BKP2R register ****************/ +#define TAMP_BKP2R_Pos (0U) +#define TAMP_BKP2R_Msk (0xFFFFFFFFUL << TAMP_BKP2R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP2R TAMP_BKP2R_Msk + +/******************** Bits definition for TAMP_BKP3R register ****************/ +#define TAMP_BKP3R_Pos (0U) +#define TAMP_BKP3R_Msk (0xFFFFFFFFUL << TAMP_BKP3R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP3R TAMP_BKP3R_Msk + +/******************** Bits definition for TAMP_BKP4R register ****************/ +#define TAMP_BKP4R_Pos (0U) +#define TAMP_BKP4R_Msk (0xFFFFFFFFUL << TAMP_BKP4R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP4R TAMP_BKP4R_Msk + +/******************** Bits definition for TAMP_BKP5R register ****************/ +#define TAMP_BKP5R_Pos (0U) +#define TAMP_BKP5R_Msk (0xFFFFFFFFUL << TAMP_BKP5R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP5R TAMP_BKP5R_Msk + +/******************** Bits definition for TAMP_BKP6R register ****************/ +#define TAMP_BKP6R_Pos (0U) +#define TAMP_BKP6R_Msk (0xFFFFFFFFUL << TAMP_BKP6R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP6R TAMP_BKP6R_Msk + +/******************** Bits definition for TAMP_BKP7R register ****************/ +#define TAMP_BKP7R_Pos (0U) +#define TAMP_BKP7R_Msk (0xFFFFFFFFUL << TAMP_BKP7R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP7R TAMP_BKP7R_Msk + +/******************** Bits definition for TAMP_BKP8R register ****************/ +#define TAMP_BKP8R_Pos (0U) +#define TAMP_BKP8R_Msk (0xFFFFFFFFUL << TAMP_BKP8R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP8R TAMP_BKP8R_Msk + +/******************** Bits definition for TAMP_BKP9R register ****************/ +#define TAMP_BKP9R_Pos (0U) +#define TAMP_BKP9R_Msk (0xFFFFFFFFUL << TAMP_BKP9R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP9R TAMP_BKP9R_Msk + +/******************** Bits definition for TAMP_BKP10R register ***************/ +#define TAMP_BKP10R_Pos (0U) +#define TAMP_BKP10R_Msk (0xFFFFFFFFUL << TAMP_BKP10R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP10R TAMP_BKP10R_Msk + +/******************** Bits definition for TAMP_BKP11R register ***************/ +#define TAMP_BKP11R_Pos (0U) +#define TAMP_BKP11R_Msk (0xFFFFFFFFUL << TAMP_BKP11R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP11R TAMP_BKP11R_Msk + +/******************** Bits definition for TAMP_BKP12R register ***************/ +#define TAMP_BKP12R_Pos (0U) +#define TAMP_BKP12R_Msk (0xFFFFFFFFUL << TAMP_BKP12R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP12R TAMP_BKP12R_Msk + +/******************** Bits definition for TAMP_BKP13R register ***************/ +#define TAMP_BKP13R_Pos (0U) +#define TAMP_BKP13R_Msk (0xFFFFFFFFUL << TAMP_BKP13R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP13R TAMP_BKP13R_Msk + +/******************** Bits definition for TAMP_BKP14R register ***************/ +#define TAMP_BKP14R_Pos (0U) +#define TAMP_BKP14R_Msk (0xFFFFFFFFUL << TAMP_BKP14R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP14R TAMP_BKP14R_Msk + +/******************** Bits definition for TAMP_BKP15R register ***************/ +#define TAMP_BKP15R_Pos (0U) +#define TAMP_BKP15R_Msk (0xFFFFFFFFUL << TAMP_BKP15R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP15R TAMP_BKP15R_Msk + +/******************** Bits definition for TAMP_BKP16R register ***************/ +#define TAMP_BKP16R_Pos (0U) +#define TAMP_BKP16R_Msk (0xFFFFFFFFUL << TAMP_BKP16R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP16R TAMP_BKP16R_Msk + +/******************** Bits definition for TAMP_BKP17R register ***************/ +#define TAMP_BKP17R_Pos (0U) +#define TAMP_BKP17R_Msk (0xFFFFFFFFUL << TAMP_BKP17R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP17R TAMP_BKP17R_Msk + +/******************** Bits definition for TAMP_BKP18R register ***************/ +#define TAMP_BKP18R_Pos (0U) +#define TAMP_BKP18R_Msk (0xFFFFFFFFUL << TAMP_BKP18R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP18R TAMP_BKP18R_Msk + +/******************** Bits definition for TAMP_BKP19R register ***************/ +#define TAMP_BKP19R_Pos (0U) +#define TAMP_BKP19R_Msk (0xFFFFFFFFUL << TAMP_BKP19R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP19R TAMP_BKP19R_Msk + +/******************** Bits definition for TAMP_BKP20R register ***************/ +#define TAMP_BKP20R_Pos (0U) +#define TAMP_BKP20R_Msk (0xFFFFFFFFUL << TAMP_BKP20R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP20R TAMP_BKP20R_Msk + +/******************** Bits definition for TAMP_BKP21R register ***************/ +#define TAMP_BKP21R_Pos (0U) +#define TAMP_BKP21R_Msk (0xFFFFFFFFUL << TAMP_BKP21R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP21R TAMP_BKP21R_Msk + +/******************** Bits definition for TAMP_BKP22R register ***************/ +#define TAMP_BKP22R_Pos (0U) +#define TAMP_BKP22R_Msk (0xFFFFFFFFUL << TAMP_BKP22R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP22R TAMP_BKP22R_Msk + +/******************** Bits definition for TAMP_BKP23R register ***************/ +#define TAMP_BKP23R_Pos (0U) +#define TAMP_BKP23R_Msk (0xFFFFFFFFUL << TAMP_BKP23R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP23R TAMP_BKP23R_Msk + +/******************** Bits definition for TAMP_BKP24R register ***************/ +#define TAMP_BKP24R_Pos (0U) +#define TAMP_BKP24R_Msk (0xFFFFFFFFUL << TAMP_BKP24R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP24R TAMP_BKP24R_Msk + +/******************** Bits definition for TAMP_BKP25R register ***************/ +#define TAMP_BKP25R_Pos (0U) +#define TAMP_BKP25R_Msk (0xFFFFFFFFUL << TAMP_BKP25R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP25R TAMP_BKP25R_Msk + +/******************** Bits definition for TAMP_BKP26R register ***************/ +#define TAMP_BKP26R_Pos (0U) +#define TAMP_BKP26R_Msk (0xFFFFFFFFUL << TAMP_BKP26R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP26R TAMP_BKP26R_Msk + +/******************** Bits definition for TAMP_BKP27R register ***************/ +#define TAMP_BKP27R_Pos (0U) +#define TAMP_BKP27R_Msk (0xFFFFFFFFUL << TAMP_BKP27R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP27R TAMP_BKP27R_Msk + +/******************** Bits definition for TAMP_BKP28R register ***************/ +#define TAMP_BKP28R_Pos (0U) +#define TAMP_BKP28R_Msk (0xFFFFFFFFUL << TAMP_BKP28R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP28R TAMP_BKP28R_Msk + +/******************** Bits definition for TAMP_BKP29R register ***************/ +#define TAMP_BKP29R_Pos (0U) +#define TAMP_BKP29R_Msk (0xFFFFFFFFUL << TAMP_BKP29R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP29R TAMP_BKP29R_Msk + +/******************** Bits definition for TAMP_BKP30R register ***************/ +#define TAMP_BKP30R_Pos (0U) +#define TAMP_BKP30R_Msk (0xFFFFFFFFUL << TAMP_BKP30R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP30R TAMP_BKP30R_Msk + +/******************** Bits definition for TAMP_BKP31R register ***************/ +#define TAMP_BKP31R_Pos (0U) +#define TAMP_BKP31R_Msk (0xFFFFFFFFUL << TAMP_BKP31R_Pos) /*!< 0xFFFFFFFF */ +#define TAMP_BKP31R TAMP_BKP31R_Msk + +/******************************************************************************/ +/* */ +/* Serial Audio Interface */ +/* */ +/******************************************************************************/ +/******************** Bit definition for SAI_GCR register *******************/ +#define SAI_GCR_SYNCIN_Pos (0U) +#define SAI_GCR_SYNCIN_Msk (0x3UL << SAI_GCR_SYNCIN_Pos) /*!< 0x00000003 */ +#define SAI_GCR_SYNCIN SAI_GCR_SYNCIN_Msk /*!>2) /*!< Input modulus number of bits */ +#define PKA_MONTGOMERY_PARAM_IN_MODULUS ((0x1088UL - PKA_RAM_OFFSET)>>2) /*!< Input modulus */ + +/* Compute Montgomery parameter output data */ +#define PKA_MONTGOMERY_PARAM_OUT_PARAMETER ((0x0620UL - PKA_RAM_OFFSET)>>2) /*!< Output Montgomery parameter */ + +/* Compute modular exponentiation input data */ +#define PKA_MODULAR_EXP_IN_EXP_NB_BITS ((0x0400UL - PKA_RAM_OFFSET)>>2) /*!< Input exponent number of bits */ +#define PKA_MODULAR_EXP_IN_OP_NB_BITS ((0x0408UL - PKA_RAM_OFFSET)>>2) /*!< Input operand number of bits */ +#define PKA_MODULAR_EXP_IN_MONTGOMERY_PARAM ((0x0620UL - PKA_RAM_OFFSET)>>2) /*!< Input storage area for Montgomery parameter */ +#define PKA_MODULAR_EXP_IN_EXPONENT_BASE ((0x0C68UL - PKA_RAM_OFFSET)>>2) /*!< Input base of the exponentiation */ +#define PKA_MODULAR_EXP_IN_EXPONENT ((0x0E78UL - PKA_RAM_OFFSET)>>2) /*!< Input exponent to process */ +#define PKA_MODULAR_EXP_IN_MODULUS ((0x1088UL - PKA_RAM_OFFSET)>>2) /*!< Input modulus */ +#define PKA_MODULAR_EXP_PROTECT_IN_EXPONENT_BASE ((0x16C8UL - PKA_RAM_OFFSET)>>2) /*!< Input base of the protected exponentiation */ +#define PKA_MODULAR_EXP_PROTECT_IN_EXPONENT ((0x14B8UL - PKA_RAM_OFFSET)>>2) /*!< Input exponent to process protected exponentiation*/ +#define PKA_MODULAR_EXP_PROTECT_IN_MODULUS ((0x0838UL - PKA_RAM_OFFSET)>>2) /*!< Input modulus to process protected exponentiation */ +#define PKA_MODULAR_EXP_PROTECT_IN_PHI ((0x0C68UL - PKA_RAM_OFFSET)>>2) /*!< Input phi to process protected exponentiation */ + +/* Compute modular exponentiation output data */ +#define PKA_MODULAR_EXP_OUT_RESULT ((0x0838UL - PKA_RAM_OFFSET)>>2) /*!< Output result of the exponentiation */ +#define PKA_MODULAR_EXP_OUT_ERROR ((0x1298UL - PKA_RAM_OFFSET)>>2) /*!< Output error of the exponentiation */ +#define PKA_MODULAR_EXP_OUT_MONTGOMERY_PARAM ((0x0620UL - PKA_RAM_OFFSET)>>2) /*!< Output storage area for Montgomery parameter */ +#define PKA_MODULAR_EXP_OUT_EXPONENT_BASE ((0x0C68UL - PKA_RAM_OFFSET)>>2) /*!< Output base of the exponentiation */ + +/* Compute ECC scalar multiplication input data */ +#define PKA_ECC_SCALAR_MUL_IN_EXP_NB_BITS ((0x0400UL - PKA_RAM_OFFSET)>>2) /*!< Input curve prime order n number of bits */ +#define PKA_ECC_SCALAR_MUL_IN_OP_NB_BITS ((0x0408UL - PKA_RAM_OFFSET)>>2) /*!< Input modulus number of bits */ +#define PKA_ECC_SCALAR_MUL_IN_A_COEFF_SIGN ((0x0410UL - PKA_RAM_OFFSET)>>2) /*!< Input sign of the 'a' coefficient */ +#define PKA_ECC_SCALAR_MUL_IN_A_COEFF ((0x0418UL - PKA_RAM_OFFSET)>>2) /*!< Input ECC curve 'a' coefficient */ +#define PKA_ECC_SCALAR_MUL_IN_B_COEFF ((0x0520UL - PKA_RAM_OFFSET)>>2) /*!< Input ECC curve 'b' coefficient */ +#define PKA_ECC_SCALAR_MUL_IN_MOD_GF ((0x1088UL - PKA_RAM_OFFSET)>>2) /*!< Input modulus GF(p) */ +#define PKA_ECC_SCALAR_MUL_IN_K ((0x12A0UL - PKA_RAM_OFFSET)>>2) /*!< Input 'k' of KP */ +#define PKA_ECC_SCALAR_MUL_IN_INITIAL_POINT_X ((0x0578UL - PKA_RAM_OFFSET)>>2) /*!< Input initial point P X coordinate */ +#define PKA_ECC_SCALAR_MUL_IN_INITIAL_POINT_Y ((0x0470UL - PKA_RAM_OFFSET)>>2) /*!< Input initial point P Y coordinate */ +#define PKA_ECC_SCALAR_MUL_IN_N_PRIME_ORDER ((0x0F88UL - PKA_RAM_OFFSET)>>2) /*!< Input prime order n */ + +/* Compute ECC scalar multiplication output data */ +#define PKA_ECC_SCALAR_MUL_OUT_RESULT_X ((0x0578UL - PKA_RAM_OFFSET)>>2) /*!< Output result X coordinate */ +#define PKA_ECC_SCALAR_MUL_OUT_RESULT_Y ((0x05D0UL - PKA_RAM_OFFSET)>>2) /*!< Output result Y coordinate */ +#define PKA_ECC_SCALAR_MUL_OUT_ERROR ((0x0680UL - PKA_RAM_OFFSET)>>2) /*!< Output result error */ + +/* Point check input data */ +#define PKA_POINT_CHECK_IN_MOD_NB_BITS ((0x0408UL - PKA_RAM_OFFSET)>>2) /*!< Input modulus number of bits */ +#define PKA_POINT_CHECK_IN_A_COEFF_SIGN ((0x0410UL - PKA_RAM_OFFSET)>>2) /*!< Input sign of the 'a' coefficient */ +#define PKA_POINT_CHECK_IN_A_COEFF ((0x0418UL - PKA_RAM_OFFSET)>>2) /*!< Input ECC curve 'a' coefficient */ +#define PKA_POINT_CHECK_IN_B_COEFF ((0x0520UL - PKA_RAM_OFFSET)>>2) /*!< Input ECC curve 'b' coefficient */ +#define PKA_POINT_CHECK_IN_MOD_GF ((0x0470UL - PKA_RAM_OFFSET)>>2) /*!< Input modulus GF(p) */ +#define PKA_POINT_CHECK_IN_INITIAL_POINT_X ((0x0578UL - PKA_RAM_OFFSET)>>2) /*!< Input initial point P X coordinate */ +#define PKA_POINT_CHECK_IN_INITIAL_POINT_Y ((0x05D0UL - PKA_RAM_OFFSET)>>2) /*!< Input initial point P Y coordinate */ +#define PKA_POINT_CHECK_IN_MONTGOMERY_PARAM ((0x04C8UL - PKA_RAM_OFFSET)>>2) /*!< Input storage area for Montgomery parameter */ + +/* Point check output data */ +#define PKA_POINT_CHECK_OUT_ERROR ((0x0680UL - PKA_RAM_OFFSET)>>2) /*!< Output error */ + +/* ECDSA signature input data */ +#define PKA_ECDSA_SIGN_IN_ORDER_NB_BITS ((0x0400UL - PKA_RAM_OFFSET)>>2) /*!< Input order number of bits */ +#define PKA_ECDSA_SIGN_IN_MOD_NB_BITS ((0x0408UL - PKA_RAM_OFFSET)>>2) /*!< Input modulus number of bits */ +#define PKA_ECDSA_SIGN_IN_A_COEFF_SIGN ((0x0410UL - PKA_RAM_OFFSET)>>2) /*!< Input sign of the 'a' coefficient */ +#define PKA_ECDSA_SIGN_IN_A_COEFF ((0x0418UL - PKA_RAM_OFFSET)>>2) /*!< Input ECC curve 'a' coefficient */ +#define PKA_ECDSA_SIGN_IN_B_COEFF ((0x0520UL - PKA_RAM_OFFSET)>>2) /*!< Input ECC curve 'b' coefficient */ +#define PKA_ECDSA_SIGN_IN_MOD_GF ((0x1088UL - PKA_RAM_OFFSET)>>2) /*!< Input modulus GF(p) */ +#define PKA_ECDSA_SIGN_IN_K ((0x12A0UL - PKA_RAM_OFFSET)>>2) /*!< Input k value of the ECDSA */ +#define PKA_ECDSA_SIGN_IN_INITIAL_POINT_X ((0x0578UL - PKA_RAM_OFFSET)>>2) /*!< Input initial point P X coordinate */ +#define PKA_ECDSA_SIGN_IN_INITIAL_POINT_Y ((0x0470UL - PKA_RAM_OFFSET)>>2) /*!< Input initial point P Y coordinate */ +#define PKA_ECDSA_SIGN_IN_HASH_E ((0x0FE8UL - PKA_RAM_OFFSET)>>2) /*!< Input e, hash of the message */ +#define PKA_ECDSA_SIGN_IN_PRIVATE_KEY_D ((0x0F28UL - PKA_RAM_OFFSET)>>2) /*!< Input d, private key */ +#define PKA_ECDSA_SIGN_IN_ORDER_N ((0x0F88UL - PKA_RAM_OFFSET)>>2) /*!< Input n, order of the curve */ + +/* ECDSA signature output data */ +#define PKA_ECDSA_SIGN_OUT_ERROR ((0x0FE0UL - PKA_RAM_OFFSET)>>2) /*!< Output error */ +#define PKA_ECDSA_SIGN_OUT_SIGNATURE_R ((0x0730UL - PKA_RAM_OFFSET)>>2) /*!< Output signature r */ +#define PKA_ECDSA_SIGN_OUT_SIGNATURE_S ((0x0788UL - PKA_RAM_OFFSET)>>2) /*!< Output signature s */ +#define PKA_ECDSA_SIGN_OUT_FINAL_POINT_X ((0x1400UL - PKA_RAM_OFFSET)>>2) /*!< Extended output result point X coordinate */ +#define PKA_ECDSA_SIGN_OUT_FINAL_POINT_Y ((0x1458UL - PKA_RAM_OFFSET)>>2) /*!< Extended output result point Y coordinate */ + + +/* ECDSA verification input data */ +#define PKA_ECDSA_VERIF_IN_ORDER_NB_BITS ((0x0408UL - PKA_RAM_OFFSET)>>2) /*!< Input order number of bits */ +#define PKA_ECDSA_VERIF_IN_MOD_NB_BITS ((0x04C8UL - PKA_RAM_OFFSET)>>2) /*!< Input modulus number of bits */ +#define PKA_ECDSA_VERIF_IN_A_COEFF_SIGN ((0x0468UL - PKA_RAM_OFFSET)>>2) /*!< Input sign of the 'a' coefficient */ +#define PKA_ECDSA_VERIF_IN_A_COEFF ((0x0470UL - PKA_RAM_OFFSET)>>2) /*!< Input ECC curve 'a' coefficient */ +#define PKA_ECDSA_VERIF_IN_MOD_GF ((0x04D0UL - PKA_RAM_OFFSET)>>2) /*!< Input modulus GF(p) */ +#define PKA_ECDSA_VERIF_IN_INITIAL_POINT_X ((0x0678UL - PKA_RAM_OFFSET)>>2) /*!< Input initial point P X coordinate */ +#define PKA_ECDSA_VERIF_IN_INITIAL_POINT_Y ((0x06D0UL - PKA_RAM_OFFSET)>>2) /*!< Input initial point P Y coordinate */ +#define PKA_ECDSA_VERIF_IN_PUBLIC_KEY_POINT_X ((0x12F8UL - PKA_RAM_OFFSET)>>2) /*!< Input public key point X coordinate */ +#define PKA_ECDSA_VERIF_IN_PUBLIC_KEY_POINT_Y ((0x1350UL - PKA_RAM_OFFSET)>>2) /*!< Input public key point Y coordinate */ +#define PKA_ECDSA_VERIF_IN_SIGNATURE_R ((0x10E0UL - PKA_RAM_OFFSET)>>2) /*!< Input r, part of the signature */ +#define PKA_ECDSA_VERIF_IN_SIGNATURE_S ((0x0C68UL - PKA_RAM_OFFSET)>>2) /*!< Input s, part of the signature */ +#define PKA_ECDSA_VERIF_IN_HASH_E ((0x13A8UL - PKA_RAM_OFFSET)>>2) /*!< Input e, hash of the message */ +#define PKA_ECDSA_VERIF_IN_ORDER_N ((0x1088UL - PKA_RAM_OFFSET)>>2) /*!< Input n, order of the curve */ + +/* ECDSA verification output data */ +#define PKA_ECDSA_VERIF_OUT_RESULT ((0x05D0UL - PKA_RAM_OFFSET)>>2) /*!< Output result */ + +/* RSA CRT exponentiation input data */ +#define PKA_RSA_CRT_EXP_IN_MOD_NB_BITS ((0x0408UL - PKA_RAM_OFFSET)>>2) /*!< Input operands number of bits */ +#define PKA_RSA_CRT_EXP_IN_DP_CRT ((0x0730UL - PKA_RAM_OFFSET)>>2) /*!< Input Dp CRT parameter */ +#define PKA_RSA_CRT_EXP_IN_DQ_CRT ((0x0E78UL - PKA_RAM_OFFSET)>>2) /*!< Input Dq CRT parameter */ +#define PKA_RSA_CRT_EXP_IN_QINV_CRT ((0x0948UL - PKA_RAM_OFFSET)>>2) /*!< Input qInv CRT parameter */ +#define PKA_RSA_CRT_EXP_IN_PRIME_P ((0x0B60UL - PKA_RAM_OFFSET)>>2) /*!< Input Prime p */ +#define PKA_RSA_CRT_EXP_IN_PRIME_Q ((0x1088UL - PKA_RAM_OFFSET)>>2) /*!< Input Prime q */ +#define PKA_RSA_CRT_EXP_IN_EXPONENT_BASE ((0x12A0UL - PKA_RAM_OFFSET)>>2) /*!< Input base of the exponentiation */ + +/* RSA CRT exponentiation output data */ +#define PKA_RSA_CRT_EXP_OUT_RESULT ((0x0838UL - PKA_RAM_OFFSET)>>2) /*!< Output result */ + +/* Modular reduction input data */ +#define PKA_MODULAR_REDUC_IN_OP_LENGTH ((0x0400UL - PKA_RAM_OFFSET)>>2) /*!< Input operand length */ +#define PKA_MODULAR_REDUC_IN_MOD_LENGTH ((0x0408UL - PKA_RAM_OFFSET)>>2) /*!< Input modulus length */ +#define PKA_MODULAR_REDUC_IN_OPERAND ((0x0A50UL - PKA_RAM_OFFSET)>>2) /*!< Input operand */ +#define PKA_MODULAR_REDUC_IN_MODULUS ((0x0C68UL - PKA_RAM_OFFSET)>>2) /*!< Input modulus */ + +/* Modular reduction output data */ +#define PKA_MODULAR_REDUC_OUT_RESULT ((0xE78UL - PKA_RAM_OFFSET)>>2) /*!< Output result */ + +/* Arithmetic addition input data */ +#define PKA_ARITHMETIC_ADD_IN_OP_NB_BITS ((0x0408UL - PKA_RAM_OFFSET)>>2) /*!< Input operand number of bits */ +#define PKA_ARITHMETIC_ADD_IN_OP1 ((0x0A50UL - PKA_RAM_OFFSET)>>2) /*!< Input operand op1 */ +#define PKA_ARITHMETIC_ADD_IN_OP2 ((0x0C68UL - PKA_RAM_OFFSET)>>2) /*!< Input operand op2 */ + +/* Arithmetic addition output data */ +#define PKA_ARITHMETIC_ADD_OUT_RESULT ((0x0E78UL - PKA_RAM_OFFSET)>>2) /*!< Output result */ + +/* Arithmetic subtraction input data */ +#define PKA_ARITHMETIC_SUB_IN_OP_NB_BITS ((0x0408UL - PKA_RAM_OFFSET)>>2) /*!< Input operand number of bits */ +#define PKA_ARITHMETIC_SUB_IN_OP1 ((0x0A50UL - PKA_RAM_OFFSET)>>2) /*!< Input operand op1 */ +#define PKA_ARITHMETIC_SUB_IN_OP2 ((0x0C68UL - PKA_RAM_OFFSET)>>2) /*!< Input operand op2 */ + +/* Arithmetic subtraction output data */ +#define PKA_ARITHMETIC_SUB_OUT_RESULT ((0x0E78UL - PKA_RAM_OFFSET)>>2) /*!< Output result */ + +/* Arithmetic multiplication input data */ +#define PKA_ARITHMETIC_MUL_NB_BITS ((0x0408UL - PKA_RAM_OFFSET)>>2) /*!< Input operand number of bits */ +#define PKA_ARITHMETIC_MUL_IN_OP1 ((0x0A50UL - PKA_RAM_OFFSET)>>2) /*!< Input operand op1 */ +#define PKA_ARITHMETIC_MUL_IN_OP2 ((0x0C68UL - PKA_RAM_OFFSET)>>2) /*!< Input operand op2 */ + +/* Arithmetic multiplication output data */ +#define PKA_ARITHMETIC_MUL_OUT_RESULT ((0x0E78UL - PKA_RAM_OFFSET)>>2) /*!< Output result */ + +/* Comparison input data */ +#define PKA_COMPARISON_IN_OP_NB_BITS ((0x0408UL - PKA_RAM_OFFSET)>>2) /*!< Input operand number of bits */ +#define PKA_COMPARISON_IN_OP1 ((0x0A50UL - PKA_RAM_OFFSET)>>2) /*!< Input operand op1 */ +#define PKA_COMPARISON_IN_OP2 ((0x0C68UL - PKA_RAM_OFFSET)>>2) /*!< Input operand op2 */ + +/* Comparison output data */ +#define PKA_COMPARISON_OUT_RESULT ((0x0E78UL - PKA_RAM_OFFSET)>>2) /*!< Output result */ + +/* Modular addition input data */ +#define PKA_MODULAR_ADD_NB_BITS ((0x0408UL - PKA_RAM_OFFSET)>>2) /*!< Input operand number of bits */ +#define PKA_MODULAR_ADD_IN_OP1 ((0x0A50UL - PKA_RAM_OFFSET)>>2) /*!< Input operand op1 */ +#define PKA_MODULAR_ADD_IN_OP2 ((0x0C68UL - PKA_RAM_OFFSET)>>2) /*!< Input operand op2 */ +#define PKA_MODULAR_ADD_IN_OP3_MOD ((0x1088UL - PKA_RAM_OFFSET)>>2) /*!< Input operand op3 (modulus) */ + +/* Modular addition output data */ +#define PKA_MODULAR_ADD_OUT_RESULT ((0x0E78UL - PKA_RAM_OFFSET)>>2) /*!< Output result */ + +/* Modular inversion input data */ +#define PKA_MODULAR_INV_NB_BITS ((0x0408UL - PKA_RAM_OFFSET)>>2) /*!< Input operand number of bits */ +#define PKA_MODULAR_INV_IN_OP1 ((0x0A50UL - PKA_RAM_OFFSET)>>2) /*!< Input operand op1 */ +#define PKA_MODULAR_INV_IN_OP2_MOD ((0x0C68UL - PKA_RAM_OFFSET)>>2) /*!< Input operand op2 (modulus) */ + +/* Modular inversion output data */ +#define PKA_MODULAR_INV_OUT_RESULT ((0x0E78UL - PKA_RAM_OFFSET)>>2) /*!< Output result */ + +/* Modular subtraction input data */ +#define PKA_MODULAR_SUB_IN_OP_NB_BITS ((0x0408UL - PKA_RAM_OFFSET)>>2) /*!< Input operand number of bits */ +#define PKA_MODULAR_SUB_IN_OP1 ((0x0A50UL - PKA_RAM_OFFSET)>>2) /*!< Input operand op1 */ +#define PKA_MODULAR_SUB_IN_OP2 ((0x0C68UL - PKA_RAM_OFFSET)>>2) /*!< Input operand op2 */ +#define PKA_MODULAR_SUB_IN_OP3_MOD ((0x1088UL - PKA_RAM_OFFSET)>>2) /*!< Input operand op3 */ + +/* Modular subtraction output data */ +#define PKA_MODULAR_SUB_OUT_RESULT ((0x0E78UL - PKA_RAM_OFFSET)>>2) /*!< Output result */ + +/* Montgomery multiplication input data */ +#define PKA_MONTGOMERY_MUL_IN_OP_NB_BITS ((0x0408UL - PKA_RAM_OFFSET)>>2) /*!< Input operand number of bits */ +#define PKA_MONTGOMERY_MUL_IN_OP1 ((0x0A50UL - PKA_RAM_OFFSET)>>2) /*!< Input operand op1 */ +#define PKA_MONTGOMERY_MUL_IN_OP2 ((0x0C68UL - PKA_RAM_OFFSET)>>2) /*!< Input operand op2 */ +#define PKA_MONTGOMERY_MUL_IN_OP3_MOD ((0x1088UL - PKA_RAM_OFFSET)>>2) /*!< Input modulus */ + +/* Montgomery multiplication output data */ +#define PKA_MONTGOMERY_MUL_OUT_RESULT ((0x0E78UL - PKA_RAM_OFFSET)>>2) /*!< Output result */ + +/* Generic Arithmetic input data */ +#define PKA_ARITHMETIC_ALL_OPS_NB_BITS ((0x0408UL - PKA_RAM_OFFSET)>>2) /*!< Input operand number of bits */ +#define PKA_ARITHMETIC_ALL_OPS_IN_OP1 ((0x0A50UL - PKA_RAM_OFFSET)>>2) /*!< Input operand op1 */ +#define PKA_ARITHMETIC_ALL_OPS_IN_OP2 ((0x0C68UL - PKA_RAM_OFFSET)>>2) /*!< Input operand op2 */ +#define PKA_ARITHMETIC_ALL_OPS_IN_OP3 ((0x1088UL - PKA_RAM_OFFSET)>>2) /*!< Input operand op2 */ + +/* Generic Arithmetic output data */ +#define PKA_ARITHMETIC_ALL_OPS_OUT_RESULT ((0x0E78UL - PKA_RAM_OFFSET)>>2) /*!< Output result for arithmetic operations */ + +/* Compute ECC complete addition input data */ +#define PKA_ECC_COMPLETE_ADD_IN_MOD_NB_BITS ((0x0408UL - PKA_RAM_OFFSET)>>2) /*!< Input Modulus number of bits */ +#define PKA_ECC_COMPLETE_ADD_IN_A_COEFF_SIGN ((0x0410UL - PKA_RAM_OFFSET)>>2) /*!< Input sign of the 'a' coefficient */ +#define PKA_ECC_COMPLETE_ADD_IN_A_COEFF ((0x0418UL - PKA_RAM_OFFSET)>>2) /*!< Input ECC curve '|a|' coefficient */ +#define PKA_ECC_COMPLETE_ADD_IN_MOD_P ((0x0470UL - PKA_RAM_OFFSET)>>2) /*!< Input modulus GF(p) */ +#define PKA_ECC_COMPLETE_ADD_IN_POINT1_X ((0x0628UL - PKA_RAM_OFFSET)>>2) /*!< Input initial point P X coordinate */ +#define PKA_ECC_COMPLETE_ADD_IN_POINT1_Y ((0x0680UL - PKA_RAM_OFFSET)>>2) /*!< Input initial point P Y coordinate */ +#define PKA_ECC_COMPLETE_ADD_IN_POINT1_Z ((0x06D8UL - PKA_RAM_OFFSET)>>2) /*!< Input initial point P Z coordinate */ +#define PKA_ECC_COMPLETE_ADD_IN_POINT2_X ((0x0730UL - PKA_RAM_OFFSET)>>2) /*!< Input initial point Q X coordinate */ +#define PKA_ECC_COMPLETE_ADD_IN_POINT2_Y ((0x0788UL - PKA_RAM_OFFSET)>>2) /*!< Input initial point Q Y coordinate */ +#define PKA_ECC_COMPLETE_ADD_IN_POINT2_Z ((0x07E0UL - PKA_RAM_OFFSET)>>2) /*!< Input initial point Q Z coordinate */ + +/* Compute ECC complete addition output data */ +#define PKA_ECC_COMPLETE_ADD_OUT_RESULT_X ((0x0D60UL - PKA_RAM_OFFSET)>>2) /*!< Output result X coordinate */ +#define PKA_ECC_COMPLETE_ADD_OUT_RESULT_Y ((0x0DB8UL - PKA_RAM_OFFSET)>>2) /*!< Output result Y coordinate */ +#define PKA_ECC_COMPLETE_ADD_OUT_RESULT_Z ((0x0E10UL - PKA_RAM_OFFSET)>>2) /*!< Output result Z coordinate */ + +/* Compute ECC double base ladder input data */ +#define PKA_ECC_DOUBLE_LADDER_IN_PRIME_ORDER_NB_BITS ((0x0400UL - PKA_RAM_OFFSET)>>2) /*!< Input n, order of the curve */ +#define PKA_ECC_DOUBLE_LADDER_IN_MOD_NB_BITS ((0x0408UL - PKA_RAM_OFFSET)>>2) /*!< Input Modulus number of bits */ +#define PKA_ECC_DOUBLE_LADDER_IN_A_COEFF_SIGN ((0x0410UL - PKA_RAM_OFFSET)>>2) /*!< Input sign of the 'a' coefficient */ +#define PKA_ECC_DOUBLE_LADDER_IN_A_COEFF ((0x0418UL - PKA_RAM_OFFSET)>>2) /*!< Input ECC curve '|a|' coefficient */ +#define PKA_ECC_DOUBLE_LADDER_IN_MOD_P ((0x0470UL - PKA_RAM_OFFSET)>>2) /*!< Input modulus GF(p) */ +#define PKA_ECC_DOUBLE_LADDER_IN_K_INTEGER ((0x0520UL - PKA_RAM_OFFSET)>>2) /*!< Input 'k' integer coefficient */ +#define PKA_ECC_DOUBLE_LADDER_IN_M_INTEGER ((0x0578UL - PKA_RAM_OFFSET)>>2) /*!< Input 'm' integer coefficient */ +#define PKA_ECC_DOUBLE_LADDER_IN_POINT1_X ((0x0628UL - PKA_RAM_OFFSET)>>2) /*!< Input initial point P X coordinate */ +#define PKA_ECC_DOUBLE_LADDER_IN_POINT1_Y ((0x0680UL - PKA_RAM_OFFSET)>>2) /*!< Input initial point P Y coordinate */ +#define PKA_ECC_DOUBLE_LADDER_IN_POINT1_Z ((0x06D8UL - PKA_RAM_OFFSET)>>2) /*!< Input initial point P Z coordinate */ +#define PKA_ECC_DOUBLE_LADDER_IN_POINT2_X ((0x0730UL - PKA_RAM_OFFSET)>>2) /*!< Input initial point Q X coordinate */ +#define PKA_ECC_DOUBLE_LADDER_IN_POINT2_Y ((0x0788UL - PKA_RAM_OFFSET)>>2) /*!< Input initial point Q Y coordinate */ +#define PKA_ECC_DOUBLE_LADDER_IN_POINT2_Z ((0x07E0UL - PKA_RAM_OFFSET)>>2) /*!< Input initial point Q Z coordinate */ + +/* Compute ECC double base ladder output data */ +#define PKA_ECC_DOUBLE_LADDER_OUT_RESULT_X ((0x0578UL - PKA_RAM_OFFSET)>>2) /*!< Output result X coordinate (affine coordinate) */ +#define PKA_ECC_DOUBLE_LADDER_OUT_RESULT_Y ((0x05D0UL - PKA_RAM_OFFSET)>>2) /*!< Output result Y coordinate (affine coordinate) */ +#define PKA_ECC_DOUBLE_LADDER_OUT_ERROR ((0x0520UL - PKA_RAM_OFFSET)>>2) /*!< Output result error */ + +/* Compute ECC projective to affine conversion input data */ +#define PKA_ECC_PROJECTIVE_AFF_IN_MOD_NB_BITS ((0x0408UL - PKA_RAM_OFFSET)>>2) /*!< Input Modulus number of bits */ +#define PKA_ECC_PROJECTIVE_AFF_IN_MOD_P ((0x0470UL - PKA_RAM_OFFSET)>>2) /*!< Input modulus GF(p) */ +#define PKA_ECC_PROJECTIVE_AFF_IN_POINT_X ((0x0D60UL - PKA_RAM_OFFSET)>>2) /*!< Input initial projective point P X coordinate */ +#define PKA_ECC_PROJECTIVE_AFF_IN_POINT_Y ((0x0DB8UL - PKA_RAM_OFFSET)>>2) /*!< Input initial projective point P Y coordinate */ +#define PKA_ECC_PROJECTIVE_AFF_IN_POINT_Z ((0x0E10UL - PKA_RAM_OFFSET)>>2) /*!< Input initial projective point P Z coordinate */ +#define PKA_ECC_PROJECTIVE_AFF_IN_MONTGOMERY_PARAM_R2 ((0x04C8UL - PKA_RAM_OFFSET)>>2) /*!< Input storage area for Montgomery parameter */ + +/* Compute ECC projective to affine conversion output data */ +#define PKA_ECC_PROJECTIVE_AFF_OUT_RESULT_X ((0x0578UL - PKA_RAM_OFFSET)>>2) /*!< Output result x affine coordinate */ +#define PKA_ECC_PROJECTIVE_AFF_OUT_RESULT_Y ((0x05D0UL - PKA_RAM_OFFSET)>>2) /*!< Output result y affine coordinate */ +#define PKA_ECC_PROJECTIVE_AFF_OUT_ERROR ((0x0680UL - PKA_RAM_OFFSET)>>2) /*!< Output result error */ + + +/** @addtogroup STM32H5xx_Peripheral_Exported_macros + * @{ + */ + +/******************************* ADC Instances ********************************/ +#define IS_ADC_ALL_INSTANCE(INSTANCE) (((INSTANCE) == ADC1_NS) || \ + ((INSTANCE) == ADC1_S)|| \ + ((INSTANCE) == ADC2_NS)|| \ + ((INSTANCE) == ADC2_S)) + +#define IS_ADC_MULTIMODE_MASTER_INSTANCE(INSTANCE) (((INSTANCE) == ADC1_NS) || \ + ((INSTANCE) == ADC1_S)) + + +#define IS_ADC_COMMON_INSTANCE(INSTANCE) (((INSTANCE) == ADC12_COMMON_NS) || \ + ((INSTANCE) == ADC12_COMMON_S)) +/******************************* AES Instances ********************************/ +#define IS_AES_ALL_INSTANCE(INSTANCE) (((INSTANCE) == AES_NS) || ((INSTANCE) == AES_S)) + +/******************************* PKA Instances ********************************/ +#define IS_PKA_ALL_INSTANCE(INSTANCE) (((INSTANCE) == PKA_NS) || ((INSTANCE) == PKA_S)) + + +/******************************* CORDIC Instances *****************************/ +#define IS_CORDIC_ALL_INSTANCE(INSTANCE) (((INSTANCE) == CORDIC_NS) || ((INSTANCE) == CORDIC_S)) + +/******************************* CRC Instances ********************************/ +#define IS_CRC_ALL_INSTANCE(INSTANCE) (((INSTANCE) == CRC_NS) || ((INSTANCE) == CRC_S)) + +/******************************* DAC Instances ********************************/ +#define IS_DAC_ALL_INSTANCE(INSTANCE) (((INSTANCE) == DAC1_NS) || ((INSTANCE) == DAC1_S)) + +/******************************* DCACHE Instances *****************************/ +#define IS_DCACHE_ALL_INSTANCE(INSTANCE) (((INSTANCE) == DCACHE1_NS) || ((INSTANCE) == DCACHE1_S)) + +/******************************* DELAYBLOCK Instances *******************************/ +#define IS_DLYB_ALL_INSTANCE(INSTANCE) (((INSTANCE) == DLYB_SDMMC1_NS) || \ + ((INSTANCE) == DLYB_SDMMC2_NS) || \ + ((INSTANCE) == DLYB_SDMMC1_S) || \ + ((INSTANCE) == DLYB_SDMMC2_S) || \ + ((INSTANCE) == DLYB_OCTOSPI1_NS) || \ + ((INSTANCE) == DLYB_OCTOSPI1_S )) +/******************************** DMA Instances *******************************/ +#define IS_DMA_ALL_INSTANCE(INSTANCE) (((INSTANCE) == GPDMA1_Channel0_NS) || ((INSTANCE) == GPDMA1_Channel0_S) || \ + ((INSTANCE) == GPDMA1_Channel1_NS) || ((INSTANCE) == GPDMA1_Channel1_S) || \ + ((INSTANCE) == GPDMA1_Channel2_NS) || ((INSTANCE) == GPDMA1_Channel2_S) || \ + ((INSTANCE) == GPDMA1_Channel3_NS) || ((INSTANCE) == GPDMA1_Channel3_S) || \ + ((INSTANCE) == GPDMA1_Channel4_NS) || ((INSTANCE) == GPDMA1_Channel4_S) || \ + ((INSTANCE) == GPDMA1_Channel5_NS) || ((INSTANCE) == GPDMA1_Channel5_S) || \ + ((INSTANCE) == GPDMA1_Channel6_NS) || ((INSTANCE) == GPDMA1_Channel6_S) || \ + ((INSTANCE) == GPDMA1_Channel7_NS) || ((INSTANCE) == GPDMA1_Channel7_S) || \ + ((INSTANCE) == GPDMA2_Channel0_NS) || ((INSTANCE) == GPDMA2_Channel0_S) || \ + ((INSTANCE) == GPDMA2_Channel1_NS) || ((INSTANCE) == GPDMA2_Channel1_S) || \ + ((INSTANCE) == GPDMA2_Channel2_NS) || ((INSTANCE) == GPDMA2_Channel2_S) || \ + ((INSTANCE) == GPDMA2_Channel3_NS) || ((INSTANCE) == GPDMA2_Channel3_S) || \ + ((INSTANCE) == GPDMA2_Channel4_NS) || ((INSTANCE) == GPDMA2_Channel4_S) || \ + ((INSTANCE) == GPDMA2_Channel5_NS) || ((INSTANCE) == GPDMA2_Channel5_S) || \ + ((INSTANCE) == GPDMA2_Channel6_NS) || ((INSTANCE) == GPDMA2_Channel6_S) || \ + ((INSTANCE) == GPDMA2_Channel7_NS) || ((INSTANCE) == GPDMA2_Channel7_S)) + +#define IS_GPDMA_INSTANCE(INSTANCE) IS_DMA_ALL_INSTANCE(INSTANCE) + +#define IS_DMA_2D_ADDRESSING_INSTANCE(INSTANCE) (((INSTANCE) == GPDMA1_Channel6_NS) || ((INSTANCE) == GPDMA1_Channel6_S) || \ + ((INSTANCE) == GPDMA1_Channel7_NS) || ((INSTANCE) == GPDMA1_Channel7_S) || \ + ((INSTANCE) == GPDMA2_Channel6_NS) || ((INSTANCE) == GPDMA2_Channel6_S) || \ + ((INSTANCE) == GPDMA2_Channel7_NS) || ((INSTANCE) == GPDMA2_Channel7_S)) + +/****************************** OTFDEC Instances ********************************/ +#define IS_OTFDEC_ALL_INSTANCE(INSTANCE) (((INSTANCE) == OTFDEC1_NS) || ((INSTANCE) == OTFDEC1_S)) + +/****************************** RAMCFG Instances ********************************/ +#define IS_RAMCFG_ALL_INSTANCE(INSTANCE) (((INSTANCE) == RAMCFG_SRAM1_NS) || ((INSTANCE) == RAMCFG_SRAM1_S) || \ + ((INSTANCE) == RAMCFG_SRAM2_NS) || ((INSTANCE) == RAMCFG_SRAM2_S) || \ + ((INSTANCE) == RAMCFG_SRAM3_NS) || ((INSTANCE) == RAMCFG_SRAM3_S) || \ + ((INSTANCE) == RAMCFG_BKPRAM_NS) || ((INSTANCE) == RAMCFG_BKPRAM_S)) + +/***************************** RAMCFG ECC Instances *****************************/ +#define IS_RAMCFG_ECC_INSTANCE(INSTANCE) (((INSTANCE) == RAMCFG_SRAM2_NS) || ((INSTANCE) == RAMCFG_SRAM2_S) || \ + ((INSTANCE) == RAMCFG_SRAM3_NS) || ((INSTANCE) == RAMCFG_SRAM3_S) || \ + ((INSTANCE) == RAMCFG_BKPRAM_NS) || ((INSTANCE) == RAMCFG_BKPRAM_S)) + +/************************ RAMCFG Write Protection Instances *********************/ +#define IS_RAMCFG_WP_INSTANCE(INSTANCE) (((INSTANCE) == RAMCFG_SRAM2_NS) || ((INSTANCE) == RAMCFG_SRAM2_S)) + + +/******************************** FMAC Instances ******************************/ +#define IS_FMAC_ALL_INSTANCE(INSTANCE) (((INSTANCE) == FMAC_NS) || ((INSTANCE) == FMAC_S)) + +/******************************* GPIO Instances *******************************/ +#define IS_GPIO_ALL_INSTANCE(INSTANCE) (((INSTANCE) == GPIOA_NS) || ((INSTANCE) == GPIOA_S) || \ + ((INSTANCE) == GPIOB_NS) || ((INSTANCE) == GPIOB_S) || \ + ((INSTANCE) == GPIOC_NS) || ((INSTANCE) == GPIOC_S) || \ + ((INSTANCE) == GPIOD_NS) || ((INSTANCE) == GPIOD_S) || \ + ((INSTANCE) == GPIOE_NS) || ((INSTANCE) == GPIOE_S) || \ + ((INSTANCE) == GPIOF_NS) || ((INSTANCE) == GPIOF_S) || \ + ((INSTANCE) == GPIOG_NS) || ((INSTANCE) == GPIOG_S) || \ + ((INSTANCE) == GPIOH_NS) || ((INSTANCE) == GPIOH_S) || \ + ((INSTANCE) == GPIOI_NS) || ((INSTANCE) == GPIOI_S)) + +/******************************* DCMI Instances *******************************/ +#define IS_DCMI_ALL_INSTANCE(__INSTANCE__) (((__INSTANCE__) == DCMI_NS) || ((__INSTANCE__) == DCMI_S)) + +/******************************* PSSI Instances *******************************/ +#define IS_PSSI_ALL_INSTANCE(__INSTANCE__) (((__INSTANCE__) == PSSI_NS) || ((__INSTANCE__) == PSSI_S)) + +/******************************* DTS Instances *******************************/ +#define IS_DTS_ALL_INSTANCE(__INSTANCE__) (((__INSTANCE__) == DTS_NS) || ((__INSTANCE__) == DTS_S)) + +/******************************* GPIO AF Instances ****************************/ +/* On H5, all GPIO Bank support AF */ +#define IS_GPIO_AF_INSTANCE(INSTANCE) IS_GPIO_ALL_INSTANCE(INSTANCE) + +/**************************** GPIO Lock Instances *****************************/ +/* On H5, all GPIO Bank support the Lock mechanism */ +#define IS_GPIO_LOCK_INSTANCE(INSTANCE) IS_GPIO_ALL_INSTANCE(INSTANCE) + +/******************************** I2C Instances *******************************/ +#define IS_I2C_ALL_INSTANCE(INSTANCE) (((INSTANCE) == I2C1_NS) || ((INSTANCE) == I2C1_S) || \ + ((INSTANCE) == I2C2_NS) || ((INSTANCE) == I2C2_S) || \ + ((INSTANCE) == I2C3_NS) || ((INSTANCE) == I2C3_S) || \ + ((INSTANCE) == I2C4_NS) || ((INSTANCE) == I2C4_S)) + +/****************** I2C Instances : wakeup capability from stop modes *********/ +#define IS_I2C_WAKEUP_FROMSTOP_INSTANCE(INSTANCE) IS_I2C_ALL_INSTANCE(INSTANCE) + +/******************************** I3C Instances *******************************/ +#define IS_I3C_ALL_INSTANCE(INSTANCE) (((INSTANCE) == I3C1_NS) || ((INSTANCE) == I3C1_S)) + +/******************************* OSPI Instances *******************************/ +#define IS_OSPI_ALL_INSTANCE(INSTANCE) (((INSTANCE) == OCTOSPI1_NS) || ((INSTANCE) == OCTOSPI1_S)) + +/******************************* RNG Instances ********************************/ +#define IS_RNG_ALL_INSTANCE(INSTANCE) (((INSTANCE) == RNG_NS) || ((INSTANCE) == RNG_S)) + +/****************************** RTC Instances *********************************/ +#define IS_RTC_ALL_INSTANCE(INSTANCE) (((INSTANCE) == RTC_NS) || ((INSTANCE) == RTC_S)) + +/******************************** SAI Instances *******************************/ +#define IS_SAI_ALL_INSTANCE(INSTANCE) (((INSTANCE) == SAI1_Block_A_NS) || ((INSTANCE) == SAI1_Block_A_S) || \ + ((INSTANCE) == SAI1_Block_B_NS) || ((INSTANCE) == SAI1_Block_B_S) || \ + ((INSTANCE) == SAI2_Block_A_NS) || ((INSTANCE) == SAI2_Block_A_S) || \ + ((INSTANCE) == SAI2_Block_B_NS) || ((INSTANCE) == SAI2_Block_B_S)) + +/****************************** SDMMC Instances *******************************/ +#define IS_SDMMC_ALL_INSTANCE(INSTANCE) (((INSTANCE) == SDMMC1_NS) || ((INSTANCE) == SDMMC1_S) || \ + ((INSTANCE) == SDMMC2_NS) || ((INSTANCE) == SDMMC2_S)) + +/****************************** FDCAN Instances *******************************/ +#define IS_FDCAN_ALL_INSTANCE(INSTANCE) (((INSTANCE) == FDCAN1_NS) || ((INSTANCE) == FDCAN1_S) || \ + ((INSTANCE) == FDCAN2_NS) || ((INSTANCE) == FDCAN2_S)) + +/****************************** SMBUS Instances *******************************/ +#define IS_SMBUS_ALL_INSTANCE(INSTANCE) (((INSTANCE) == I2C1_NS) || ((INSTANCE) == I2C1_S) || \ + ((INSTANCE) == I2C2_NS) || ((INSTANCE) == I2C2_S) || \ + ((INSTANCE) == I2C3_NS) || ((INSTANCE) == I2C3_S) || \ + ((INSTANCE) == I2C4_NS) || ((INSTANCE) == I2C4_S)) + +/******************************** SPI Instances *******************************/ +#define IS_SPI_ALL_INSTANCE(INSTANCE) (((INSTANCE) == SPI1_NS) || ((INSTANCE) == SPI1_S) || \ + ((INSTANCE) == SPI2_NS) || ((INSTANCE) == SPI2_S) || \ + ((INSTANCE) == SPI3_NS) || ((INSTANCE) == SPI3_S) || \ + ((INSTANCE) == SPI4_NS) || ((INSTANCE) == SPI4_S) || \ + ((INSTANCE) == SPI5_NS) || ((INSTANCE) == SPI5_S) || \ + ((INSTANCE) == SPI6_NS) || ((INSTANCE) == SPI6_S)) + +#define IS_SPI_LIMITED_INSTANCE(INSTANCE) (((INSTANCE) == SPI4_NS) || ((INSTANCE) == SPI4_S) || \ + ((INSTANCE) == SPI5_NS) || ((INSTANCE) == SPI5_S) || \ + ((INSTANCE) == SPI6_NS) || ((INSTANCE) == SPI6_S)) + +#define IS_SPI_FULL_INSTANCE(INSTANCE) (((INSTANCE) == SPI1_NS) || ((INSTANCE) == SPI1_S) || \ + ((INSTANCE) == SPI2_NS) || ((INSTANCE) == SPI2_S) || \ + ((INSTANCE) == SPI3_NS) || ((INSTANCE) == SPI3_S)) + +/****************** LPTIM Instances : All supported instances *****************/ +#define IS_LPTIM_INSTANCE(INSTANCE) (((INSTANCE) == LPTIM1_NS) || ((INSTANCE) == LPTIM1_S) ||\ + ((INSTANCE) == LPTIM2_NS) || ((INSTANCE) == LPTIM2_S) ||\ + ((INSTANCE) == LPTIM3_NS) || ((INSTANCE) == LPTIM3_S) ||\ + ((INSTANCE) == LPTIM4_NS) || ((INSTANCE) == LPTIM4_S) ||\ + ((INSTANCE) == LPTIM5_NS) || ((INSTANCE) == LPTIM5_S) ||\ + ((INSTANCE) == LPTIM6_NS) || ((INSTANCE) == LPTIM6_S)) + +/****************** LPTIM Instances : DMA supported instances *****************/ +#define IS_LPTIM_DMA_INSTANCE(INSTANCE) (((INSTANCE) == LPTIM1_NS) || ((INSTANCE) == LPTIM1_S) ||\ + ((INSTANCE) == LPTIM2_NS) || ((INSTANCE) == LPTIM2_S) ||\ + ((INSTANCE) == LPTIM3_NS) || ((INSTANCE) == LPTIM3_S) ||\ + ((INSTANCE) == LPTIM5_NS) || ((INSTANCE) == LPTIM5_S) ||\ + ((INSTANCE) == LPTIM6_NS) || ((INSTANCE) == LPTIM6_S)) + +/************* LPTIM Instances : at least 1 capture/compare channel ***********/ +#define IS_LPTIM_CC1_INSTANCE(INSTANCE) (((INSTANCE) == LPTIM1_NS) || ((INSTANCE) == LPTIM1_S) ||\ + ((INSTANCE) == LPTIM2_NS) || ((INSTANCE) == LPTIM2_S) ||\ + ((INSTANCE) == LPTIM3_NS) || ((INSTANCE) == LPTIM3_S) ||\ + ((INSTANCE) == LPTIM4_NS) || ((INSTANCE) == LPTIM4_S) ||\ + ((INSTANCE) == LPTIM5_NS) || ((INSTANCE) == LPTIM5_S) ||\ + ((INSTANCE) == LPTIM6_NS) || ((INSTANCE) == LPTIM6_S)) + +/************* LPTIM Instances : at least 2 capture/compare channel ***********/ +#define IS_LPTIM_CC2_INSTANCE(INSTANCE) (((INSTANCE) == LPTIM1_NS) || ((INSTANCE) == LPTIM1_S) ||\ + ((INSTANCE) == LPTIM2_NS) || ((INSTANCE) == LPTIM2_S) ||\ + ((INSTANCE) == LPTIM3_NS) || ((INSTANCE) == LPTIM3_S) ||\ + ((INSTANCE) == LPTIM5_NS) || ((INSTANCE) == LPTIM5_S) ||\ + ((INSTANCE) == LPTIM6_NS) || ((INSTANCE) == LPTIM6_S)) + +/****************** LPTIM Instances : supporting encoder interface **************/ +#define IS_LPTIM_ENCODER_INTERFACE_INSTANCE(INSTANCE) (((INSTANCE) == LPTIM1_NS) || ((INSTANCE) == LPTIM1_S) ||\ + ((INSTANCE) == LPTIM2_NS) || ((INSTANCE) == LPTIM2_S) ||\ + ((INSTANCE) == LPTIM3_NS) || ((INSTANCE) == LPTIM3_S) ||\ + ((INSTANCE) == LPTIM5_NS) || ((INSTANCE) == LPTIM5_S) ||\ + ((INSTANCE) == LPTIM6_NS) || ((INSTANCE) == LPTIM6_S)) + +/****************** LPTIM Instances : supporting Input Capture **************/ +#define IS_LPTIM_INPUT_CAPTURE_INSTANCE(INSTANCE) (((INSTANCE) == LPTIM1_NS) || ((INSTANCE) == LPTIM1_S) ||\ + ((INSTANCE) == LPTIM2_NS) || ((INSTANCE) == LPTIM2_S) ||\ + ((INSTANCE) == LPTIM3_NS) || ((INSTANCE) == LPTIM3_S) ||\ + ((INSTANCE) == LPTIM5_NS) || ((INSTANCE) == LPTIM5_S) ||\ + ((INSTANCE) == LPTIM6_NS) || ((INSTANCE) == LPTIM6_S)) + +/****************** TIM Instances : All supported instances *******************/ +#define IS_TIM_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM2_NS) || ((INSTANCE) == TIM2_S) || \ + ((INSTANCE) == TIM3_NS) || ((INSTANCE) == TIM3_S) || \ + ((INSTANCE) == TIM4_NS) || ((INSTANCE) == TIM4_S) || \ + ((INSTANCE) == TIM5_NS) || ((INSTANCE) == TIM5_S) || \ + ((INSTANCE) == TIM6_NS) || ((INSTANCE) == TIM6_S) || \ + ((INSTANCE) == TIM7_NS) || ((INSTANCE) == TIM7_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S) || \ + ((INSTANCE) == TIM12_NS) || ((INSTANCE) == TIM12_S) || \ + ((INSTANCE) == TIM13_NS) || ((INSTANCE) == TIM13_S) || \ + ((INSTANCE) == TIM14_NS) || ((INSTANCE) == TIM14_S) || \ + ((INSTANCE) == TIM15_NS) || ((INSTANCE) == TIM15_S) || \ + ((INSTANCE) == TIM16_NS) || ((INSTANCE) == TIM16_S) || \ + ((INSTANCE) == TIM17_NS) || ((INSTANCE) == TIM17_S)) + +/****************** TIM Instances : supporting 32 bits counter ****************/ +#define IS_TIM_32B_COUNTER_INSTANCE(INSTANCE) (((INSTANCE) == TIM2_NS) || ((INSTANCE) == TIM2_S) || \ + ((INSTANCE) == TIM5_NS) || ((INSTANCE) == TIM5_S)) + +/****************** TIM Instances : supporting the break function *************/ +#define IS_TIM_BREAK_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S) || \ + ((INSTANCE) == TIM15_NS) || ((INSTANCE) == TIM15_S) || \ + ((INSTANCE) == TIM16_NS) || ((INSTANCE) == TIM16_S) || \ + ((INSTANCE) == TIM17_NS) || ((INSTANCE) == TIM17_S)) + +/************** TIM Instances : supporting Break source selection *************/ +#define IS_TIM_BREAKSOURCE_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S) || \ + ((INSTANCE) == TIM15_NS) || ((INSTANCE) == TIM15_S) || \ + ((INSTANCE) == TIM16_NS) || ((INSTANCE) == TIM16_S) || \ + ((INSTANCE) == TIM17_NS) || ((INSTANCE) == TIM17_S)) + +/****************** TIM Instances : supporting 2 break inputs *****************/ +#define IS_TIM_BKIN2_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S)) + +/************* TIM Instances : at least 1 capture/compare channel *************/ +#define IS_TIM_CC1_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM2_NS) || ((INSTANCE) == TIM2_S) || \ + ((INSTANCE) == TIM3_NS) || ((INSTANCE) == TIM3_S) || \ + ((INSTANCE) == TIM4_NS) || ((INSTANCE) == TIM4_S) || \ + ((INSTANCE) == TIM5_NS) || ((INSTANCE) == TIM5_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S) || \ + ((INSTANCE) == TIM12_NS) || ((INSTANCE) == TIM12_S) || \ + ((INSTANCE) == TIM13_NS) || ((INSTANCE) == TIM13_S) || \ + ((INSTANCE) == TIM14_NS) || ((INSTANCE) == TIM14_S) || \ + ((INSTANCE) == TIM15_NS) || ((INSTANCE) == TIM15_S) || \ + ((INSTANCE) == TIM16_NS) || ((INSTANCE) == TIM16_S) || \ + ((INSTANCE) == TIM17_NS) || ((INSTANCE) == TIM17_S)) + +/************ TIM Instances : at least 2 capture/compare channels *************/ +#define IS_TIM_CC2_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM2_NS) || ((INSTANCE) == TIM2_S) || \ + ((INSTANCE) == TIM3_NS) || ((INSTANCE) == TIM3_S) || \ + ((INSTANCE) == TIM4_NS) || ((INSTANCE) == TIM4_S) || \ + ((INSTANCE) == TIM5_NS) || ((INSTANCE) == TIM5_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S) || \ + ((INSTANCE) == TIM12_NS) || ((INSTANCE) == TIM12_S) || \ + ((INSTANCE) == TIM15_NS) || ((INSTANCE) == TIM15_S)) + +/************ TIM Instances : at least 3 capture/compare channels *************/ +#define IS_TIM_CC3_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM2_NS) || ((INSTANCE) == TIM2_S) || \ + ((INSTANCE) == TIM3_NS) || ((INSTANCE) == TIM3_S) || \ + ((INSTANCE) == TIM4_NS) || ((INSTANCE) == TIM4_S) || \ + ((INSTANCE) == TIM5_NS) || ((INSTANCE) == TIM5_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S)) + +/************ TIM Instances : at least 4 capture/compare channels *************/ +#define IS_TIM_CC4_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM2_NS) || ((INSTANCE) == TIM2_S) || \ + ((INSTANCE) == TIM3_NS) || ((INSTANCE) == TIM3_S) || \ + ((INSTANCE) == TIM4_NS) || ((INSTANCE) == TIM4_S) || \ + ((INSTANCE) == TIM5_NS) || ((INSTANCE) == TIM5_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S)) + +/****************** TIM Instances : at least 5 capture/compare channels *******/ +#define IS_TIM_CC5_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S)) + +/****************** TIM Instances : at least 6 capture/compare channels *******/ +#define IS_TIM_CC6_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S)) + +/****************** TIM Instances : DMA requests generation (TIMx_DIER.UDE) ***/ +#define IS_TIM_DMA_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM2_NS) || ((INSTANCE) == TIM2_S) || \ + ((INSTANCE) == TIM3_NS) || ((INSTANCE) == TIM3_S) || \ + ((INSTANCE) == TIM4_NS) || ((INSTANCE) == TIM4_S) || \ + ((INSTANCE) == TIM5_NS) || ((INSTANCE) == TIM5_S) || \ + ((INSTANCE) == TIM6_NS) || ((INSTANCE) == TIM6_S) || \ + ((INSTANCE) == TIM7_NS) || ((INSTANCE) == TIM7_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S) || \ + ((INSTANCE) == TIM15_NS) || ((INSTANCE) == TIM15_S) || \ + ((INSTANCE) == TIM16_NS) || ((INSTANCE) == TIM16_S) || \ + ((INSTANCE) == TIM17_NS) || ((INSTANCE) == TIM17_S)) + +/************ TIM Instances : DMA requests generation (TIMx_DIER.CCxDE) *******/ +#define IS_TIM_DMA_CC_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM2_NS) || ((INSTANCE) == TIM2_S) || \ + ((INSTANCE) == TIM3_NS) || ((INSTANCE) == TIM3_S) || \ + ((INSTANCE) == TIM4_NS) || ((INSTANCE) == TIM4_S) || \ + ((INSTANCE) == TIM5_NS) || ((INSTANCE) == TIM5_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S) || \ + ((INSTANCE) == TIM15_NS) || ((INSTANCE) == TIM15_S) || \ + ((INSTANCE) == TIM16_NS) || ((INSTANCE) == TIM16_S) || \ + ((INSTANCE) == TIM17_NS) || ((INSTANCE) == TIM17_S)) + +/******************** TIM Instances : DMA burst feature ***********************/ +#define IS_TIM_DMABURST_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM2_NS) || ((INSTANCE) == TIM2_S) || \ + ((INSTANCE) == TIM3_NS) || ((INSTANCE) == TIM3_S) || \ + ((INSTANCE) == TIM4_NS) || ((INSTANCE) == TIM4_S) || \ + ((INSTANCE) == TIM5_NS) || ((INSTANCE) == TIM5_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S) || \ + ((INSTANCE) == TIM15_NS) || ((INSTANCE) == TIM15_S) || \ + ((INSTANCE) == TIM16_NS) || ((INSTANCE) == TIM16_S) || \ + ((INSTANCE) == TIM17_NS) || ((INSTANCE) == TIM17_S)) + +/******************* TIM Instances : output(s) available **********************/ +#define IS_TIM_CCX_INSTANCE(INSTANCE, CHANNEL) \ + (((((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S)) && \ + (((CHANNEL) == TIM_CHANNEL_1) || \ + ((CHANNEL) == TIM_CHANNEL_2) || \ + ((CHANNEL) == TIM_CHANNEL_3) || \ + ((CHANNEL) == TIM_CHANNEL_4) || \ + ((CHANNEL) == TIM_CHANNEL_5) || \ + ((CHANNEL) == TIM_CHANNEL_6))) \ + || \ + ((((INSTANCE) == TIM2_NS) || ((INSTANCE) == TIM2_S)) && \ + (((CHANNEL) == TIM_CHANNEL_1) || \ + ((CHANNEL) == TIM_CHANNEL_2) || \ + ((CHANNEL) == TIM_CHANNEL_3) || \ + ((CHANNEL) == TIM_CHANNEL_4))) \ + || \ + ((((INSTANCE) == TIM3_NS) || ((INSTANCE) == TIM3_S)) && \ + (((CHANNEL) == TIM_CHANNEL_1) || \ + ((CHANNEL) == TIM_CHANNEL_2) || \ + ((CHANNEL) == TIM_CHANNEL_3) || \ + ((CHANNEL) == TIM_CHANNEL_4))) \ + || \ + ((((INSTANCE) == TIM4_NS) || ((INSTANCE) == TIM4_S)) && \ + (((CHANNEL) == TIM_CHANNEL_1) || \ + ((CHANNEL) == TIM_CHANNEL_2) || \ + ((CHANNEL) == TIM_CHANNEL_3) || \ + ((CHANNEL) == TIM_CHANNEL_4))) \ + || \ + ((((INSTANCE) == TIM5_NS) || ((INSTANCE) == TIM5_S)) && \ + (((CHANNEL) == TIM_CHANNEL_1) || \ + ((CHANNEL) == TIM_CHANNEL_2) || \ + ((CHANNEL) == TIM_CHANNEL_3) || \ + ((CHANNEL) == TIM_CHANNEL_4))) \ + || \ + ((((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S)) && \ + (((CHANNEL) == TIM_CHANNEL_1) || \ + ((CHANNEL) == TIM_CHANNEL_2) || \ + ((CHANNEL) == TIM_CHANNEL_3) || \ + ((CHANNEL) == TIM_CHANNEL_4) || \ + ((CHANNEL) == TIM_CHANNEL_5) || \ + ((CHANNEL) == TIM_CHANNEL_6))) \ + || \ + ((((INSTANCE) == TIM12_NS) || ((INSTANCE) == TIM12_S)) && \ + (((CHANNEL) == TIM_CHANNEL_1) || \ + ((CHANNEL) == TIM_CHANNEL_2))) \ + || \ + ((((INSTANCE) == TIM13_NS) || ((INSTANCE) == TIM13_S)) && \ + (((CHANNEL) == TIM_CHANNEL_1))) \ + || \ + ((((INSTANCE) == TIM14_NS) || ((INSTANCE) == TIM14_S)) && \ + (((CHANNEL) == TIM_CHANNEL_1))) \ + || \ + ((((INSTANCE) == TIM15_NS) || ((INSTANCE) == TIM15_S)) && \ + (((CHANNEL) == TIM_CHANNEL_1) || \ + ((CHANNEL) == TIM_CHANNEL_2))) \ + || \ + ((((INSTANCE) == TIM16_NS) || ((INSTANCE) == TIM16_S)) && \ + (((CHANNEL) == TIM_CHANNEL_1))) \ + || \ + ((((INSTANCE) == TIM17_NS) || ((INSTANCE) == TIM17_S)) && \ + (((CHANNEL) == TIM_CHANNEL_1)))) + +/****************** TIM Instances : supporting complementary output(s) ********/ +#define IS_TIM_CCXN_INSTANCE(INSTANCE, CHANNEL) \ + (((((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S)) && \ + (((CHANNEL) == TIM_CHANNEL_1) || \ + ((CHANNEL) == TIM_CHANNEL_2) || \ + ((CHANNEL) == TIM_CHANNEL_3) || \ + ((CHANNEL) == TIM_CHANNEL_4))) \ + || \ + ((((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S)) && \ + (((CHANNEL) == TIM_CHANNEL_1) || \ + ((CHANNEL) == TIM_CHANNEL_2) || \ + ((CHANNEL) == TIM_CHANNEL_3) || \ + ((CHANNEL) == TIM_CHANNEL_4))) \ + || \ + ((((INSTANCE) == TIM15_NS) || ((INSTANCE) == TIM15_S)) && \ + ((CHANNEL) == TIM_CHANNEL_1)) \ + || \ + ((((INSTANCE) == TIM16_NS) || ((INSTANCE) == TIM16_S)) && \ + ((CHANNEL) == TIM_CHANNEL_1)) \ + || \ + ((((INSTANCE) == TIM17_NS) || ((INSTANCE) == TIM17_S)) && \ + ((CHANNEL) == TIM_CHANNEL_1))) + +/****************** TIM Instances : supporting clock division *****************/ +#define IS_TIM_CLOCK_DIVISION_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM2_NS) || ((INSTANCE) == TIM2_S) || \ + ((INSTANCE) == TIM3_NS) || ((INSTANCE) == TIM3_S) || \ + ((INSTANCE) == TIM4_NS) || ((INSTANCE) == TIM4_S) || \ + ((INSTANCE) == TIM5_NS) || ((INSTANCE) == TIM5_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S) || \ + ((INSTANCE) == TIM12_NS) || ((INSTANCE) == TIM12_S) || \ + ((INSTANCE) == TIM13_NS) || ((INSTANCE) == TIM13_S) || \ + ((INSTANCE) == TIM14_NS) || ((INSTANCE) == TIM14_S) || \ + ((INSTANCE) == TIM15_NS) || ((INSTANCE) == TIM15_S) || \ + ((INSTANCE) == TIM16_NS) || ((INSTANCE) == TIM16_S) || \ + ((INSTANCE) == TIM17_NS) || ((INSTANCE) == TIM17_S)) + +/****** TIM Instances : supporting external clock mode 1 for ETRF input *******/ +#define IS_TIM_CLOCKSOURCE_ETRMODE1_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM2_NS) || ((INSTANCE) == TIM2_S) || \ + ((INSTANCE) == TIM3_NS) || ((INSTANCE) == TIM3_S) || \ + ((INSTANCE) == TIM4_NS) || ((INSTANCE) == TIM4_S) || \ + ((INSTANCE) == TIM5_NS) || ((INSTANCE) == TIM5_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S)) + +/****** TIM Instances : supporting external clock mode 2 for ETRF input *******/ +#define IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM2_NS) || ((INSTANCE) == TIM2_S) || \ + ((INSTANCE) == TIM3_NS) || ((INSTANCE) == TIM3_S) || \ + ((INSTANCE) == TIM4_NS) || ((INSTANCE) == TIM4_S) || \ + ((INSTANCE) == TIM5_NS) || ((INSTANCE) == TIM5_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S)) + +/****************** TIM Instances : supporting external clock mode 1 for TIX inputs*/ +#define IS_TIM_CLOCKSOURCE_TIX_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM2_NS) || ((INSTANCE) == TIM2_S) || \ + ((INSTANCE) == TIM3_NS) || ((INSTANCE) == TIM3_S) || \ + ((INSTANCE) == TIM4_NS) || ((INSTANCE) == TIM4_S) || \ + ((INSTANCE) == TIM5_NS) || ((INSTANCE) == TIM5_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S) || \ + ((INSTANCE) == TIM12_NS) || ((INSTANCE) == TIM12_S) || \ + ((INSTANCE) == TIM15_NS) || ((INSTANCE) == TIM15_S)) + +/****************** TIM Instances : supporting internal trigger inputs(ITRX) *******/ +#define IS_TIM_CLOCKSOURCE_ITRX_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM2_NS) || ((INSTANCE) == TIM2_S) || \ + ((INSTANCE) == TIM3_NS) || ((INSTANCE) == TIM3_S) || \ + ((INSTANCE) == TIM4_NS) || ((INSTANCE) == TIM4_S) || \ + ((INSTANCE) == TIM5_NS) || ((INSTANCE) == TIM5_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S) || \ + ((INSTANCE) == TIM12_NS) || ((INSTANCE) == TIM12_S) || \ + ((INSTANCE) == TIM13_NS) || ((INSTANCE) == TIM13_S) || \ + ((INSTANCE) == TIM14_NS) || ((INSTANCE) == TIM14_S) || \ + ((INSTANCE) == TIM15_NS) || ((INSTANCE) == TIM15_S)) + +/****************** TIM Instances : supporting combined 3-phase PWM mode ******/ +#define IS_TIM_COMBINED3PHASEPWM_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S)) + +/****************** TIM Instances : supporting commutation event generation ***/ +#define IS_TIM_COMMUTATION_EVENT_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S) || \ + ((INSTANCE) == TIM15_NS) || ((INSTANCE) == TIM15_S) || \ + ((INSTANCE) == TIM16_NS) || ((INSTANCE) == TIM16_S) || \ + ((INSTANCE) == TIM17_NS) || ((INSTANCE) == TIM17_S)) + +/****************** TIM Instances : supporting counting mode selection ********/ +#define IS_TIM_COUNTER_MODE_SELECT_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM2_NS) || ((INSTANCE) == TIM2_S) || \ + ((INSTANCE) == TIM3_NS) || ((INSTANCE) == TIM3_S) || \ + ((INSTANCE) == TIM4_NS) || ((INSTANCE) == TIM4_S) || \ + ((INSTANCE) == TIM5_NS) || ((INSTANCE) == TIM5_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S)) + +/****************** TIM Instances : supporting encoder interface **************/ +#define IS_TIM_ENCODER_INTERFACE_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM2_NS) || ((INSTANCE) == TIM2_S) || \ + ((INSTANCE) == TIM3_NS) || ((INSTANCE) == TIM3_S) || \ + ((INSTANCE) == TIM4_NS) || ((INSTANCE) == TIM4_S) || \ + ((INSTANCE) == TIM5_NS) || ((INSTANCE) == TIM5_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S)) + +/****************** TIM Instances : supporting Hall sensor interface **********/ +#define IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM2_NS) || ((INSTANCE) == TIM2_S) || \ + ((INSTANCE) == TIM3_NS) || ((INSTANCE) == TIM3_S) || \ + ((INSTANCE) == TIM4_NS) || ((INSTANCE) == TIM4_S) || \ + ((INSTANCE) == TIM5_NS) || ((INSTANCE) == TIM5_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S)) + +/**************** TIM Instances : external trigger input available ************/ +#define IS_TIM_ETR_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM2_NS) || ((INSTANCE) == TIM2_S) || \ + ((INSTANCE) == TIM3_NS) || ((INSTANCE) == TIM3_S) || \ + ((INSTANCE) == TIM4_NS) || ((INSTANCE) == TIM4_S) || \ + ((INSTANCE) == TIM5_NS) || ((INSTANCE) == TIM5_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S)) + +/************* TIM Instances : supporting ETR source selection ***************/ +#define IS_TIM_ETRSEL_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM2_NS) || ((INSTANCE) == TIM2_S) || \ + ((INSTANCE) == TIM3_NS) || ((INSTANCE) == TIM3_S) || \ + ((INSTANCE) == TIM4_NS) || ((INSTANCE) == TIM4_S) || \ + ((INSTANCE) == TIM5_NS) || ((INSTANCE) == TIM5_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S)) + +/****** TIM Instances : Master mode available (TIMx_CR2.MMS available )********/ +#define IS_TIM_MASTER_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM2_NS) || ((INSTANCE) == TIM2_S) || \ + ((INSTANCE) == TIM3_NS) || ((INSTANCE) == TIM3_S) || \ + ((INSTANCE) == TIM4_NS) || ((INSTANCE) == TIM4_S) || \ + ((INSTANCE) == TIM5_NS) || ((INSTANCE) == TIM5_S) || \ + ((INSTANCE) == TIM6_NS) || ((INSTANCE) == TIM6_S) || \ + ((INSTANCE) == TIM7_NS) || ((INSTANCE) == TIM7_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S) || \ + ((INSTANCE) == TIM12_NS) || ((INSTANCE) == TIM12_S) || \ + ((INSTANCE) == TIM15_NS) || ((INSTANCE) == TIM15_S)) + +/*********** TIM Instances : Slave mode available (TIMx_SMCR available )*******/ +#define IS_TIM_SLAVE_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM2_NS) || ((INSTANCE) == TIM2_S) || \ + ((INSTANCE) == TIM3_NS) || ((INSTANCE) == TIM3_S) || \ + ((INSTANCE) == TIM4_NS) || ((INSTANCE) == TIM4_S) || \ + ((INSTANCE) == TIM5_NS) || ((INSTANCE) == TIM5_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S) || \ + ((INSTANCE) == TIM12_NS) || ((INSTANCE) == TIM12_S) || \ + ((INSTANCE) == TIM15_NS) || ((INSTANCE) == TIM15_S)) + +/****************** TIM Instances : supporting OCxREF clear *******************/ +#define IS_TIM_OCXREF_CLEAR_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM2_NS) || ((INSTANCE) == TIM2_S) || \ + ((INSTANCE) == TIM3_NS) || ((INSTANCE) == TIM3_S) || \ + ((INSTANCE) == TIM4_NS) || ((INSTANCE) == TIM4_S) || \ + ((INSTANCE) == TIM5_NS) || ((INSTANCE) == TIM5_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S) || \ + ((INSTANCE) == TIM15_NS) || ((INSTANCE) == TIM15_S) || \ + ((INSTANCE) == TIM16_NS) || ((INSTANCE) == TIM16_S) || \ + ((INSTANCE) == TIM17_NS) || ((INSTANCE) == TIM17_S)) + +/****************** TIM Instances : remapping capability **********************/ +#define IS_TIM_REMAP_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM2_NS) || ((INSTANCE) == TIM2_S) || \ + ((INSTANCE) == TIM3_NS) || ((INSTANCE) == TIM3_S) || \ + ((INSTANCE) == TIM4_NS) || ((INSTANCE) == TIM4_S) || \ + ((INSTANCE) == TIM5_NS) || ((INSTANCE) == TIM5_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S)) + +/****************** TIM Instances : supporting repetition counter *************/ +#define IS_TIM_REPETITION_COUNTER_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S) || \ + ((INSTANCE) == TIM15_NS) || ((INSTANCE) == TIM15_S) || \ + ((INSTANCE) == TIM16_NS) || ((INSTANCE) == TIM16_S) || \ + ((INSTANCE) == TIM17_NS) || ((INSTANCE) == TIM17_S)) + +/****************** TIM Instances : supporting ADC triggering through TRGO2 ***/ +#define IS_TIM_TRGO2_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S)) + +/******************* TIM Instances : Timer input XOR function *****************/ +#define IS_TIM_XOR_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM2_NS) || ((INSTANCE) == TIM2_S) || \ + ((INSTANCE) == TIM3_NS) || ((INSTANCE) == TIM3_S) || \ + ((INSTANCE) == TIM4_NS) || ((INSTANCE) == TIM4_S) || \ + ((INSTANCE) == TIM5_NS) || ((INSTANCE) == TIM5_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S) || \ + ((INSTANCE) == TIM15_NS) || ((INSTANCE) == TIM15_S)) + +/******************* TIM Instances : Timer input selection ********************/ +#define IS_TIM_TISEL_INSTANCE(INSTANCE) (((INSTANCE) == TIM2_NS) || ((INSTANCE) == TIM2_S) || \ + ((INSTANCE) == TIM3_NS) || ((INSTANCE) == TIM3_S) || \ + ((INSTANCE) == TIM12_NS) || ((INSTANCE) == TIM12_S)|| \ + ((INSTANCE) == TIM15_NS) || ((INSTANCE) == TIM15_S)|| \ + ((INSTANCE) == TIM16_NS) || ((INSTANCE) == TIM16_S)|| \ + ((INSTANCE) == TIM17_NS) || ((INSTANCE) == TIM17_S)) + +/****************** TIM Instances : Advanced timer instances *******************/ +#define IS_TIM_ADVANCED_INSTANCE(INSTANCE) (((INSTANCE) == TIM1_NS) || ((INSTANCE) == TIM1_S) || \ + ((INSTANCE) == TIM8_NS) || ((INSTANCE) == TIM8_S)) + +/****************** TIM Instances : supporting synchronization ****************/ +#define IS_TIM_SYNCHRO_INSTANCE(__INSTANCE__) (((__INSTANCE__) == TIM1_NS) || ((__INSTANCE__) == TIM1_S) || \ + ((__INSTANCE__) == TIM2_NS) || ((__INSTANCE__) == TIM2_S) || \ + ((__INSTANCE__) == TIM3_NS) || ((__INSTANCE__) == TIM3_S) || \ + ((__INSTANCE__) == TIM4_NS) || ((__INSTANCE__) == TIM4_S) || \ + ((__INSTANCE__) == TIM5_NS) || ((__INSTANCE__) == TIM5_S) || \ + ((__INSTANCE__) == TIM6_NS) || ((__INSTANCE__) == TIM6_S) || \ + ((__INSTANCE__) == TIM7_NS) || ((__INSTANCE__) == TIM7_S) || \ + ((__INSTANCE__) == TIM8_NS) || ((__INSTANCE__) == TIM8_S) || \ + ((__INSTANCE__) == TIM12_NS) || ((__INSTANCE__) == TIM12_S)|| \ + ((__INSTANCE__) == TIM15_NS) || ((__INSTANCE__) == TIM15_S)) + +/******************** USART Instances : Synchronous mode **********************/ +#define IS_USART_INSTANCE(INSTANCE) (((INSTANCE) == USART1_NS) || ((INSTANCE) == USART1_S) || \ + ((INSTANCE) == USART2_NS) || ((INSTANCE) == USART2_S) || \ + ((INSTANCE) == USART3_NS) || ((INSTANCE) == USART3_S) || \ + ((INSTANCE) == USART6_NS) || ((INSTANCE) == USART6_S) || \ + ((INSTANCE) == USART10_NS) || ((INSTANCE) == USART10_S) || \ + ((INSTANCE) == USART11_NS) || ((INSTANCE) == USART11_S)) + +/******************** UART Instances : Asynchronous mode **********************/ +#define IS_UART_INSTANCE(INSTANCE) (((INSTANCE) == USART1_NS) || ((INSTANCE) == USART1_S) || \ + ((INSTANCE) == USART2_NS) || ((INSTANCE) == USART2_S) || \ + ((INSTANCE) == USART3_NS) || ((INSTANCE) == USART3_S) || \ + ((INSTANCE) == UART4_NS) || ((INSTANCE) == UART4_S) || \ + ((INSTANCE) == UART5_NS) || ((INSTANCE) == UART5_S) || \ + ((INSTANCE) == USART6_NS) || ((INSTANCE) == USART6_S) || \ + ((INSTANCE) == UART7_NS) || ((INSTANCE) == UART7_S) || \ + ((INSTANCE) == UART8_NS) || ((INSTANCE) == UART8_S) || \ + ((INSTANCE) == UART9_NS) || ((INSTANCE) == UART9_S) || \ + ((INSTANCE) == USART10_NS) || ((INSTANCE) == USART10_S) || \ + ((INSTANCE) == USART11_NS) || ((INSTANCE) == USART11_S) || \ + ((INSTANCE) == UART12_NS) || ((INSTANCE) == UART12_S)) + +/*********************** UART Instances : FIFO mode ***************************/ +#define IS_UART_FIFO_INSTANCE(INSTANCE) (((INSTANCE) == USART1_NS) || ((INSTANCE) == USART1_S) || \ + ((INSTANCE) == USART2_NS) || ((INSTANCE) == USART2_S) || \ + ((INSTANCE) == USART3_NS) || ((INSTANCE) == USART3_S) || \ + ((INSTANCE) == UART4_NS) || ((INSTANCE) == UART4_S) || \ + ((INSTANCE) == UART5_NS) || ((INSTANCE) == UART5_S) || \ + ((INSTANCE) == USART6_NS) || ((INSTANCE) == USART6_S) || \ + ((INSTANCE) == UART7_NS) || ((INSTANCE) == UART7_S) || \ + ((INSTANCE) == UART8_NS) || ((INSTANCE) == UART8_S) || \ + ((INSTANCE) == UART9_NS) || ((INSTANCE) == UART9_S) || \ + ((INSTANCE) == USART10_NS) || ((INSTANCE) == USART10_S) || \ + ((INSTANCE) == USART11_NS) || ((INSTANCE) == USART11_S) || \ + ((INSTANCE) == UART12_NS) || ((INSTANCE) == UART12_S) || \ + ((INSTANCE) == LPUART1_NS) || ((INSTANCE) == LPUART1_S)) + +/*********************** UART Instances : SPI Slave mode **********************/ +#define IS_UART_SPI_SLAVE_INSTANCE(INSTANCE) (((INSTANCE) == USART1_NS) || ((INSTANCE) == USART1_S) || \ + ((INSTANCE) == USART2_NS) || ((INSTANCE) == USART2_S) || \ + ((INSTANCE) == USART3_NS) || ((INSTANCE) == USART3_S) || \ + ((INSTANCE) == USART6_NS) || ((INSTANCE) == USART6_S) || \ + ((INSTANCE) == USART10_NS) || ((INSTANCE) == USART10_S) || \ + ((INSTANCE) == USART11_NS) || ((INSTANCE) == USART11_S)) + +/******************************** I2S Instances *******************************/ +#define IS_I2S_ALL_INSTANCE(INSTANCE) (((INSTANCE) == SPI1) || \ + ((INSTANCE) == SPI2) || \ + ((INSTANCE) == SPI3)) + +/****************** UART Instances : Auto Baud Rate detection ****************/ +#define IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(INSTANCE) (((INSTANCE) == USART1_NS) || ((INSTANCE) == USART1_S) || \ + ((INSTANCE) == USART2_NS) || ((INSTANCE) == USART2_S) || \ + ((INSTANCE) == USART3_NS) || ((INSTANCE) == USART3_S) || \ + ((INSTANCE) == UART4_NS) || ((INSTANCE) == UART4_S) || \ + ((INSTANCE) == UART5_NS) || ((INSTANCE) == UART5_S) || \ + ((INSTANCE) == USART6_NS) || ((INSTANCE) == USART6_S) || \ + ((INSTANCE) == UART7_NS) || ((INSTANCE) == UART7_S) || \ + ((INSTANCE) == UART8_NS) || ((INSTANCE) == UART8_S) || \ + ((INSTANCE) == UART9_NS) || ((INSTANCE) == UART9_S) || \ + ((INSTANCE) == USART10_NS) || ((INSTANCE) == USART10_S) || \ + ((INSTANCE) == USART11_NS) || ((INSTANCE) == USART11_S) || \ + ((INSTANCE) == UART12_NS) || ((INSTANCE) == UART12_S)) + +/****************** UART Instances : Driver Enable *****************/ +#define IS_UART_DRIVER_ENABLE_INSTANCE(INSTANCE) (((INSTANCE) == USART1_NS) || ((INSTANCE) == USART1_S) || \ + ((INSTANCE) == USART2_NS) || ((INSTANCE) == USART2_S) || \ + ((INSTANCE) == USART3_NS) || ((INSTANCE) == USART3_S) || \ + ((INSTANCE) == UART4_NS) || ((INSTANCE) == UART4_S) || \ + ((INSTANCE) == UART5_NS) || ((INSTANCE) == UART5_S) || \ + ((INSTANCE) == USART6_NS) || ((INSTANCE) == USART6_S) || \ + ((INSTANCE) == UART7_NS) || ((INSTANCE) == UART7_S) || \ + ((INSTANCE) == UART8_NS) || ((INSTANCE) == UART8_S) || \ + ((INSTANCE) == UART9_NS) || ((INSTANCE) == UART9_S) || \ + ((INSTANCE) == USART10_NS) || ((INSTANCE) == USART10_S) || \ + ((INSTANCE) == USART11_NS) || ((INSTANCE) == USART11_S) || \ + ((INSTANCE) == UART12_NS) || ((INSTANCE) == UART12_S) || \ + ((INSTANCE) == LPUART1_NS) || ((INSTANCE) == LPUART1_S)) + +/******************** UART Instances : Half-Duplex mode **********************/ +#define IS_UART_HALFDUPLEX_INSTANCE(INSTANCE) (((INSTANCE) == USART1_NS) || ((INSTANCE) == USART1_S) || \ + ((INSTANCE) == USART2_NS) || ((INSTANCE) == USART2_S) || \ + ((INSTANCE) == USART3_NS) || ((INSTANCE) == USART3_S) || \ + ((INSTANCE) == UART4_NS) || ((INSTANCE) == UART4_S) || \ + ((INSTANCE) == UART5_NS) || ((INSTANCE) == UART5_S) || \ + ((INSTANCE) == USART6_NS) || ((INSTANCE) == USART6_S) || \ + ((INSTANCE) == UART7_NS) || ((INSTANCE) == UART7_S) || \ + ((INSTANCE) == UART8_NS) || ((INSTANCE) == UART8_S) || \ + ((INSTANCE) == UART9_NS) || ((INSTANCE) == UART9_S) || \ + ((INSTANCE) == USART10_NS) || ((INSTANCE) == USART10_S) || \ + ((INSTANCE) == USART11_NS) || ((INSTANCE) == USART11_S) || \ + ((INSTANCE) == UART12_NS) || ((INSTANCE) == UART12_S) || \ + ((INSTANCE) == LPUART1_NS) || ((INSTANCE) == LPUART1_S)) + +/****************** UART Instances : Hardware Flow control ********************/ +#define IS_UART_HWFLOW_INSTANCE(INSTANCE) (((INSTANCE) == USART1_NS) || ((INSTANCE) == USART1_S) || \ + ((INSTANCE) == USART2_NS) || ((INSTANCE) == USART2_S) || \ + ((INSTANCE) == USART3_NS) || ((INSTANCE) == USART3_S) || \ + ((INSTANCE) == UART4_NS) || ((INSTANCE) == UART4_S) || \ + ((INSTANCE) == UART5_NS) || ((INSTANCE) == UART5_S) || \ + ((INSTANCE) == USART6_NS) || ((INSTANCE) == USART6_S) || \ + ((INSTANCE) == UART7_NS) || ((INSTANCE) == UART7_S) || \ + ((INSTANCE) == UART8_NS) || ((INSTANCE) == UART8_S) || \ + ((INSTANCE) == UART9_NS) || ((INSTANCE) == UART9_S) || \ + ((INSTANCE) == USART10_NS) || ((INSTANCE) == USART10_S) || \ + ((INSTANCE) == USART11_NS) || ((INSTANCE) == USART11_S) || \ + ((INSTANCE) == UART12_NS) || ((INSTANCE) == UART12_S) || \ + ((INSTANCE) == LPUART1_NS) || ((INSTANCE) == LPUART1_S)) + +/******************** UART Instances : LIN mode **********************/ +#define IS_UART_LIN_INSTANCE(INSTANCE) (((INSTANCE) == USART1_NS) || ((INSTANCE) == USART1_S) || \ + ((INSTANCE) == USART2_NS) || ((INSTANCE) == USART2_S) || \ + ((INSTANCE) == USART3_NS) || ((INSTANCE) == USART3_S) || \ + ((INSTANCE) == UART4_NS) || ((INSTANCE) == UART4_S) || \ + ((INSTANCE) == UART5_NS) || ((INSTANCE) == UART5_S) || \ + ((INSTANCE) == USART6_NS) || ((INSTANCE) == USART6_S) || \ + ((INSTANCE) == UART7_NS) || ((INSTANCE) == UART7_S) || \ + ((INSTANCE) == UART8_NS) || ((INSTANCE) == UART8_S) || \ + ((INSTANCE) == UART9_NS) || ((INSTANCE) == UART9_S) || \ + ((INSTANCE) == USART10_NS) || ((INSTANCE) == USART10_S) || \ + ((INSTANCE) == USART11_NS) || ((INSTANCE) == USART11_S) || \ + ((INSTANCE) == UART12_NS) || ((INSTANCE) == UART12_S)) + +/******************** UART Instances : Wake-up from Stop mode **********************/ +#define IS_UART_WAKEUP_FROMSTOP_INSTANCE(INSTANCE) (((INSTANCE) == USART1_NS) || ((INSTANCE) == USART1_S) || \ + ((INSTANCE) == USART2_NS) || ((INSTANCE) == USART2_S) || \ + ((INSTANCE) == USART3_NS) || ((INSTANCE) == USART3_S) || \ + ((INSTANCE) == UART4_NS) || ((INSTANCE) == UART4_S) || \ + ((INSTANCE) == UART5_NS) || ((INSTANCE) == UART5_S) || \ + ((INSTANCE) == USART6_NS) || ((INSTANCE) == USART6_S) || \ + ((INSTANCE) == UART7_NS) || ((INSTANCE) == UART7_S) || \ + ((INSTANCE) == UART8_NS) || ((INSTANCE) == UART8_S) || \ + ((INSTANCE) == UART9_NS) || ((INSTANCE) == UART9_S) || \ + ((INSTANCE) == USART10_NS) || ((INSTANCE) == USART10_S) || \ + ((INSTANCE) == USART11_NS) || ((INSTANCE) == USART11_S) || \ + ((INSTANCE) == UART12_NS) || ((INSTANCE) == UART12_S) || \ + ((INSTANCE) == LPUART1_NS) || ((INSTANCE) == LPUART1_S)) + +/*********************** UART Instances : IRDA mode ***************************/ +#define IS_IRDA_INSTANCE(INSTANCE) (((INSTANCE) == USART1_NS) || ((INSTANCE) == USART1_S) || \ + ((INSTANCE) == USART2_NS) || ((INSTANCE) == USART2_S) || \ + ((INSTANCE) == USART3_NS) || ((INSTANCE) == USART3_S) || \ + ((INSTANCE) == UART4_NS) || ((INSTANCE) == UART4_S) || \ + ((INSTANCE) == UART5_NS) || ((INSTANCE) == UART5_S) || \ + ((INSTANCE) == USART6_NS) || ((INSTANCE) == USART6_S) || \ + ((INSTANCE) == UART7_NS) || ((INSTANCE) == UART7_S) || \ + ((INSTANCE) == UART8_NS) || ((INSTANCE) == UART8_S) || \ + ((INSTANCE) == UART9_NS) || ((INSTANCE) == UART9_S) || \ + ((INSTANCE) == USART10_NS) || ((INSTANCE) == USART10_S) || \ + ((INSTANCE) == USART11_NS) || ((INSTANCE) == USART11_S) || \ + ((INSTANCE) == UART12_NS) || ((INSTANCE) == UART12_S)) + +/********************* USART Instances : Smard card mode ***********************/ +#define IS_SMARTCARD_INSTANCE(INSTANCE) (((INSTANCE) == USART1_NS) || ((INSTANCE) == USART1_S) || \ + ((INSTANCE) == USART2_NS) || ((INSTANCE) == USART2_S) || \ + ((INSTANCE) == USART3_NS) || ((INSTANCE) == USART3_S) || \ + ((INSTANCE) == USART6_NS) || ((INSTANCE) == USART6_S) || \ + ((INSTANCE) == USART10_NS) || ((INSTANCE) == USART10_S) || \ + ((INSTANCE) == USART11_NS) || ((INSTANCE) == USART11_S)) + +/******************** LPUART Instance *****************************************/ +#define IS_LPUART_INSTANCE(INSTANCE) (((INSTANCE) == LPUART1_NS) || ((INSTANCE) == LPUART1_S)) + +/******************** CEC Instance *****************************************/ +#define IS_CEC_ALL_INSTANCE(INSTANCE) (((INSTANCE) == CEC_NS) || ((INSTANCE) == CEC_S)) + +/****************************** IWDG Instances ********************************/ +#define IS_IWDG_ALL_INSTANCE(INSTANCE) (((INSTANCE) == IWDG_NS) || ((INSTANCE) == IWDG_S)) + +/****************************** WWDG Instances ********************************/ +#define IS_WWDG_ALL_INSTANCE(INSTANCE) (((INSTANCE) == WWDG_NS) || ((INSTANCE) == WWDG_S)) + +/****************************** UCPD Instances ********************************/ +#define IS_UCPD_ALL_INSTANCE(INSTANCE) (((INSTANCE) == UCPD1_NS) || ((INSTANCE) == UCPD1_S)) + +/******************************* USB DRD FS HCD Instances *************************/ +#define IS_HCD_ALL_INSTANCE(INSTANCE) (((INSTANCE) == USB_DRD_FS_NS) || ((INSTANCE) == USB_DRD_FS_S)) + +/******************************* USB DRD FS PCD Instances *************************/ +#define IS_PCD_ALL_INSTANCE(INSTANCE) (((INSTANCE) == USB_DRD_FS_NS) || ((INSTANCE) == USB_DRD_FS_S)) + + +/** @} */ /* End of group STM32H5xx_Peripheral_Exported_macros */ + +/** @} */ /* End of group STM32H573xx */ + +/** @} */ /* End of group ST */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H573xx_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/stm32h5xx.h b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/stm32h5xx.h new file mode 100644 index 0000000000..7f33f62459 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/stm32h5xx.h @@ -0,0 +1,238 @@ +/** + ****************************************************************************** + * @file stm32h5xx.h + * @author MCD Application Team + * @brief CMSIS STM32H5xx Device Peripheral Access Layer Header File. + * + * The file is the unique include file that the application programmer + * is using in the C source code, usually in main.c. This file contains: + * - Configuration section that allows to select: + * - The STM32H5xx device used in the target application + * - To use or not the peripherals drivers in application code(i.e. + * code will be based on direct access to peripherals registers + * rather than drivers API), this option is controlled by + * "#define USE_HAL_DRIVER" + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32h5xx + * @{ + */ + +#ifndef STM32H5xx_H +#define STM32H5xx_H +#include "math.h" + +#ifdef __cplusplus + extern "C" { +#endif /* __cplusplus */ + +/** @addtogroup Library_configuration_section + * @{ + */ + +/** + * @brief STM32 Family + */ +#if !defined (STM32H5) +#define STM32H5 +#endif /* STM32H5 */ + +/* Uncomment the line below according to the target STM32H5 device used in your + application + */ + +#if !defined (STM32H573xx) && !defined (STM32H563xx) \ + && !defined (STM32H562xx) && !defined (STM32H503xx) + /* #define STM32H573xx */ /*!< STM32H5753xx Devices */ + /* #define STM32H563xx */ /*!< STM32H563xx Devices */ + /* #define STM32H562xx */ /*!< STM32H562xx Devices */ + /* #define STM32H503xx */ /*!< STM32H503xx Devices */ +#endif + +/* Tip: To avoid modifying this file each time you need to switch between these + devices, you can define the device in your toolchain compiler preprocessor. + */ +#if !defined (USE_HAL_DRIVER) +/** + * @brief Comment the line below if you will not use the peripherals drivers. + In this case, these drivers will not be included and the application code will + be based on direct access to peripherals registers + */ + /*#define USE_HAL_DRIVER */ +#endif /* USE_HAL_DRIVER */ + +/** + * @brief CMSIS Device version number 1.1.0 + */ +#define __STM32H5_CMSIS_VERSION_MAIN (0x01) /*!< [31:24] main version */ +#define __STM32H5_CMSIS_VERSION_SUB1 (0x01) /*!< [23:16] sub1 version */ +#define __STM32H5_CMSIS_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */ +#define __STM32H5_CMSIS_VERSION_RC (0x00) /*!< [7:0] release candidate */ +#define __STM32H5_CMSIS_VERSION ((__STM32H5_CMSIS_VERSION_MAIN << 24U)\ + |(__STM32H5_CMSIS_VERSION_SUB1 << 16U)\ + |(__STM32H5_CMSIS_VERSION_SUB2 << 8U )\ + |(__STM32H5_CMSIS_VERSION_RC)) + +/** + * @} + */ + +/** @addtogroup Device_Included + * @{ + */ + +#if defined(STM32H573xx) + #include "stm32h573xx.h" +#elif defined(STM32H563xx) + #include "stm32h563xx.h" +#elif defined(STM32H562xx) + #include "stm32h562xx.h" +#elif defined(STM32H503xx) + #include "stm32h503xx.h" +#else + #error "Please select first the target STM32H5xx device used in your application (in stm32h5xx.h file)" +#endif + + +/** + * @} + */ + +/** @addtogroup Exported_types + * @{ + */ +typedef enum +{ + RESET = 0, + SET = !RESET +} FlagStatus, ITStatus; + +typedef enum +{ + DISABLE = 0, + ENABLE = !DISABLE +} FunctionalState; +#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE)) + +typedef enum +{ + SUCCESS = 0, + ERROR = !SUCCESS +} ErrorStatus; + +/** + * @} + */ + + +/** @addtogroup Exported_macros + * @{ + */ +#define SET_BIT(REG, BIT) ((REG) |= (BIT)) + +#define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT)) + +#define READ_BIT(REG, BIT) ((REG) & (BIT)) + +#define CLEAR_REG(REG) ((REG) = (0x0)) + +#define WRITE_REG(REG, VAL) ((REG) = (VAL)) + +#define READ_REG(REG) ((REG)) + +#define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK))) + +/* Use of CMSIS compiler intrinsics for register exclusive access */ +/* Atomic 32-bit register access macro to set one or several bits */ +#define ATOMIC_SET_BIT(REG, BIT) \ + do { \ + uint32_t val; \ + do { \ + val = __LDREXW((__IO uint32_t *)&(REG)) | (BIT); \ + } while ((__STREXW(val,(__IO uint32_t *)&(REG))) != 0U); \ + } while(0) + +/* Atomic 32-bit register access macro to clear one or several bits */ +#define ATOMIC_CLEAR_BIT(REG, BIT) \ + do { \ + uint32_t val; \ + do { \ + val = __LDREXW((__IO uint32_t *)&(REG)) & ~(BIT); \ + } while ((__STREXW(val,(__IO uint32_t *)&(REG))) != 0U); \ + } while(0) + +/* Atomic 32-bit register access macro to clear and set one or several bits */ +#define ATOMIC_MODIFY_REG(REG, CLEARMSK, SETMASK) \ + do { \ + uint32_t val; \ + do { \ + val = (__LDREXW((__IO uint32_t *)&(REG)) & ~(CLEARMSK)) | (SETMASK); \ + } while ((__STREXW(val,(__IO uint32_t *)&(REG))) != 0U); \ + } while(0) + +/* Atomic 16-bit register access macro to set one or several bits */ +#define ATOMIC_SETH_BIT(REG, BIT) \ + do { \ + uint16_t val; \ + do { \ + val = __LDREXH((__IO uint16_t *)&(REG)) | (BIT); \ + } while ((__STREXH(val,(__IO uint16_t *)&(REG))) != 0U); \ + } while(0) + +/* Atomic 16-bit register access macro to clear one or several bits */ +#define ATOMIC_CLEARH_BIT(REG, BIT) \ + do { \ + uint16_t val; \ + do { \ + val = __LDREXH((__IO uint16_t *)&(REG)) & ~(BIT); \ + } while ((__STREXH(val,(__IO uint16_t *)&(REG))) != 0U); \ + } while(0) + +/* Atomic 16-bit register access macro to clear and set one or several bits */ +#define ATOMIC_MODIFYH_REG(REG, CLEARMSK, SETMASK) \ + do { \ + uint16_t val; \ + do { \ + val = (__LDREXH((__IO uint16_t *)&(REG)) & ~(CLEARMSK)) | (SETMASK); \ + } while ((__STREXH(val,(__IO uint16_t *)&(REG))) != 0U); \ + } while(0) + +#define POSITION_VAL(VAL) (__CLZ(__RBIT(VAL))) + + +/** + * @} + */ + +#if defined (USE_HAL_DRIVER) + #include "stm32h5xx_hal.h" +#endif /* USE_HAL_DRIVER */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* STM32H5xx_H */ +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/system_stm32h5xx.h b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/system_stm32h5xx.h new file mode 100644 index 0000000000..a7a5a751fc --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Include/system_stm32h5xx.h @@ -0,0 +1,107 @@ +/** + ****************************************************************************** + * @file system_stm32h5xx.h + * @author MCD Application Team + * @brief CMSIS Cortex-M33 Device System Source File for STM32H5xx devices. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32h5xx_system + * @{ + */ + +#ifndef SYSTEM_STM32H5XX_H +#define SYSTEM_STM32H5XX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup STM32H5xx_System_Includes + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32H5xx_System_Exported_Variables + * @{ + */ + /* The SystemCoreClock variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetSysClockFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency + Note: If you use this function to configure the system clock; then there + is no need to call the 2 first functions listed above, since SystemCoreClock + variable is updated automatically. + */ +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ + +extern const uint8_t AHBPrescTable[16]; /*!< AHB prescalers table values */ +extern const uint8_t APBPrescTable[8]; /*!< APB prescalers table values */ + +/** + * @} + */ + + +/** @addtogroup STM32H5xx_System_Exported_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system. + * + * Initialize the System and update the SystemCoreClock variable. + */ +extern void SystemInit (void); + + +/** + * @brief Update SystemCoreClock variable. + * + * Updates the SystemCoreClock with current core Clock retrieved from cpu registers. + */ +extern void SystemCoreClockUpdate (void); + + +/** + * @brief Update SystemCoreClock variable from secure application and return its value + * when security is implemented in the system (Non-secure callable function). + * + * Returns the SystemCoreClock value with current core Clock retrieved from cpu registers. + */ +extern uint32_t SECURE_SystemCoreClockUpdate(void); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_STM32H5XX_H */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/LICENSE.txt b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/LICENSE.txt new file mode 100644 index 0000000000..872e82b467 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/LICENSE.txt @@ -0,0 +1,6 @@ +This software component is provided to you as part of a software package and +applicable license terms are in the Package_license file. If you received this +software component outside of a package or without applicable license terms, +the terms of the Apache-2.0 license shall apply. +You may obtain a copy of the Apache-2.0 at: +https://opensource.org/licenses/Apache-2.0 diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/arm/startup_stm32h503xx.s b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/arm/startup_stm32h503xx.s new file mode 100644 index 0000000000..3c646307e4 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/arm/startup_stm32h503xx.s @@ -0,0 +1,479 @@ +;******************************************************************************* +;* File Name : startup_stm32h503xx.s +;* Author : MCD Application Team +;* Description : STM32H503xx Non Crypto devices vector table for MDK-ARM toolchain. +;* This module performs: +;* - Set the initial SP +;* - Set the initial PC == Reset_Handler +;* - Set the vector table entries with the exceptions ISR address +;* - Branches to __main in the C library (which eventually +;* calls main()). +;* After Reset the Cortex-M33 processor is in Thread mode, +;* priority is Privileged, and the Stack is set to Main. +;******************************************************************************* +;* @attention +;* +;* Copyright (c) 2023 STMicroelectronics. +;* All rights reserved. +;* +;* This software is licensed under terms that can be found in the LICENSE file +;* in the root directory of this software component. +;* If no LICENSE file comes with this software, it is provided AS-IS. +;* +;******************************************************************************* +;* <<< Use Configuration Wizard in Context Menu >>> +; +; Amount of memory (in bytes) allocated for Stack +; Tailor this value to your application needs +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Stack_Size EQU 0x00000400 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + + +; Heap Configuration +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Heap_Size EQU 0x00000200 + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + + +; Vector Table Mapped to Address 0 at Reset + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + ; External Interrupts + DCD WWDG_IRQHandler ; Window WatchDog + DCD PVD_AVD_IRQHandler ; PVD/AVD through EXTI Line detection Interrupt + DCD RTC_IRQHandler ; RTC non-secure interrupt + DCD 0 ; Reserved + DCD TAMP_IRQHandler ; Tamper non-secure interrupt + DCD RAMCFG_IRQHandler ; RAMCFG global + DCD FLASH_IRQHandler ; FLASH non-secure global interrupt + DCD 0 ; Reserved + DCD GTZC_IRQHandler ; Global TrustZone Controller interrupt + DCD RCC_IRQHandler ; RCC non-secure global interrupt + DCD 0 ; Reserved + DCD EXTI0_IRQHandler ; EXTI Line0 interrupt + DCD EXTI1_IRQHandler ; EXTI Line1 interrupt + DCD EXTI2_IRQHandler ; EXTI Line2 interrupt + DCD EXTI3_IRQHandler ; EXTI Line3 interrupt + DCD EXTI4_IRQHandler ; EXTI Line4 interrupt + DCD EXTI5_IRQHandler ; EXTI Line5 interrupt + DCD EXTI6_IRQHandler ; EXTI Line6 interrupt + DCD EXTI7_IRQHandler ; EXTI Line7 interrupt + DCD EXTI8_IRQHandler ; EXTI Line8 interrupt + DCD EXTI9_IRQHandler ; EXTI Line9 interrupt + DCD EXTI10_IRQHandler ; EXTI Line10 interrupt + DCD EXTI11_IRQHandler ; EXTI Line11 interrupt + DCD EXTI12_IRQHandler ; EXTI Line12 interrupt + DCD EXTI13_IRQHandler ; EXTI Line13 interrupt + DCD EXTI14_IRQHandler ; EXTI Line14 interrupt + DCD EXTI15_IRQHandler ; EXTI Line15 interrupt + DCD GPDMA1_Channel0_IRQHandler ; GPDMA1 Channel 0 global interrupt + DCD GPDMA1_Channel1_IRQHandler ; GPDMA1 Channel 1 global interrupt + DCD GPDMA1_Channel2_IRQHandler ; GPDMA1 Channel 2 global interrupt + DCD GPDMA1_Channel3_IRQHandler ; GPDMA1 Channel 3 global interrupt + DCD GPDMA1_Channel4_IRQHandler ; GPDMA1 Channel 4 global interrupt + DCD GPDMA1_Channel5_IRQHandler ; GPDMA1 Channel 5 global interrupt + DCD GPDMA1_Channel6_IRQHandler ; GPDMA1 Channel 6 global interrupt + DCD GPDMA1_Channel7_IRQHandler ; GPDMA1 Channel 7 global interrupt + DCD IWDG_IRQHandler ; IWDG global interrupt + DCD 0 ; Reserved + DCD ADC1_IRQHandler ; ADC1 global interrupt + DCD DAC1_IRQHandler ; DAC1 global interrupt + DCD FDCAN1_IT0_IRQHandler ; FDCAN1 interrupt 0 + DCD FDCAN1_IT1_IRQHandler ; FDCAN1 interrupt 1 + DCD TIM1_BRK_IRQHandler ; TIM1 Break interrupt + DCD TIM1_UP_IRQHandler ; TIM1 Update interrupt + DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation interrupt + DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare interrupt + DCD TIM2_IRQHandler ; TIM2 global interrupt + DCD TIM3_IRQHandler ; TIM3 global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD TIM6_IRQHandler ; TIM6 global interrupt + DCD TIM7_IRQHandler ; TIM7 global interrupt + DCD I2C1_EV_IRQHandler ; I2C1 Event interrupt + DCD I2C1_ER_IRQHandler ; I2C1 Error interrupt + DCD I2C2_EV_IRQHandler ; I2C2 Event interrupt + DCD I2C2_ER_IRQHandler ; I2C2 Error interrupt + DCD SPI1_IRQHandler ; SPI1 global interrupt + DCD SPI2_IRQHandler ; SPI2 global interrupt + DCD SPI3_IRQHandler ; SPI3 global interrupt + DCD USART1_IRQHandler ; USART1 global interrupt + DCD USART2_IRQHandler ; USART2 global interrupt + DCD USART3_IRQHandler ; USART3 global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD LPUART1_IRQHandler ; LPUART1 global interrupt + DCD LPTIM1_IRQHandler ; LPTIM1 global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD LPTIM2_IRQHandler ; LPTIM2 global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD USB_DRD_FS_IRQHandler ; USB DRD FS global interrupt + DCD CRS_IRQHandler ; CRS global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD GPDMA2_Channel0_IRQHandler ; GPDMA2 Channel 0 global interrupt + DCD GPDMA2_Channel1_IRQHandler ; GPDMA2 Channel 1 global interrupt + DCD GPDMA2_Channel2_IRQHandler ; GPDMA2 Channel 2 global interrupt + DCD GPDMA2_Channel3_IRQHandler ; GPDMA2 Channel 3 global interrupt + DCD GPDMA2_Channel4_IRQHandler ; GPDMA2 Channel 4 global interrupt + DCD GPDMA2_Channel5_IRQHandler ; GPDMA2 Channel 5 global interrupt + DCD GPDMA2_Channel6_IRQHandler ; GPDMA2 Channel 6 global interrupt + DCD GPDMA2_Channel7_IRQHandler ; GPDMA2 Channel 7 global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD FPU_IRQHandler ; FPU global interrupt + DCD ICACHE_IRQHandler ; Instruction cache global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD DTS_IRQHandler ; DTS global interrupt + DCD RNG_IRQHandler ; RNG global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD HASH_IRQHandler ; HASH global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD I3C1_EV_IRQHandler ; I3C1 Event interrupt + DCD I3C1_ER_IRQHandler ; I3C1 Error interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD I3C2_EV_IRQHandler ; I3C2 Event interrupt + DCD I3C2_ER_IRQHandler ; I3C2 Error interrupt + DCD COMP1_IRQHandler ; COMP1 global interrupt + + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + + +; Reset Handler + +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler\ + PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemManage_Handler\ + PROC + EXPORT MemManage_Handler [WEAK] + B . + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SecureFault_Handler\ + PROC + EXPORT SecureFault_Handler [WEAK] + B . + ENDP +SVC_Handler\ + PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP +PendSV_Handler\ + PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler\ + PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + + EXPORT WWDG_IRQHandler [WEAK] + EXPORT PVD_AVD_IRQHandler [WEAK] + EXPORT RTC_IRQHandler [WEAK] + EXPORT TAMP_IRQHandler [WEAK] + EXPORT RAMCFG_IRQHandler [WEAK] + EXPORT FLASH_IRQHandler [WEAK] + EXPORT GTZC_IRQHandler [WEAK] + EXPORT RCC_IRQHandler [WEAK] + EXPORT EXTI0_IRQHandler [WEAK] + EXPORT EXTI1_IRQHandler [WEAK] + EXPORT EXTI2_IRQHandler [WEAK] + EXPORT EXTI3_IRQHandler [WEAK] + EXPORT EXTI4_IRQHandler [WEAK] + EXPORT EXTI5_IRQHandler [WEAK] + EXPORT EXTI6_IRQHandler [WEAK] + EXPORT EXTI7_IRQHandler [WEAK] + EXPORT EXTI8_IRQHandler [WEAK] + EXPORT EXTI9_IRQHandler [WEAK] + EXPORT EXTI10_IRQHandler [WEAK] + EXPORT EXTI11_IRQHandler [WEAK] + EXPORT EXTI12_IRQHandler [WEAK] + EXPORT EXTI13_IRQHandler [WEAK] + EXPORT EXTI14_IRQHandler [WEAK] + EXPORT EXTI15_IRQHandler [WEAK] + EXPORT GPDMA1_Channel0_IRQHandler [WEAK] + EXPORT GPDMA1_Channel1_IRQHandler [WEAK] + EXPORT GPDMA1_Channel2_IRQHandler [WEAK] + EXPORT GPDMA1_Channel3_IRQHandler [WEAK] + EXPORT GPDMA1_Channel4_IRQHandler [WEAK] + EXPORT GPDMA1_Channel5_IRQHandler [WEAK] + EXPORT GPDMA1_Channel6_IRQHandler [WEAK] + EXPORT GPDMA1_Channel7_IRQHandler [WEAK] + EXPORT IWDG_IRQHandler [WEAK] + EXPORT ADC1_IRQHandler [WEAK] + EXPORT DAC1_IRQHandler [WEAK] + EXPORT FDCAN1_IT0_IRQHandler [WEAK] + EXPORT FDCAN1_IT1_IRQHandler [WEAK] + EXPORT TIM1_BRK_IRQHandler [WEAK] + EXPORT TIM1_UP_IRQHandler [WEAK] + EXPORT TIM1_TRG_COM_IRQHandler [WEAK] + EXPORT TIM1_CC_IRQHandler [WEAK] + EXPORT TIM2_IRQHandler [WEAK] + EXPORT TIM3_IRQHandler [WEAK] + EXPORT TIM6_IRQHandler [WEAK] + EXPORT TIM7_IRQHandler [WEAK] + EXPORT I2C1_EV_IRQHandler [WEAK] + EXPORT I2C1_ER_IRQHandler [WEAK] + EXPORT I2C2_EV_IRQHandler [WEAK] + EXPORT I2C2_ER_IRQHandler [WEAK] + EXPORT SPI1_IRQHandler [WEAK] + EXPORT SPI2_IRQHandler [WEAK] + EXPORT SPI3_IRQHandler [WEAK] + EXPORT USART1_IRQHandler [WEAK] + EXPORT USART2_IRQHandler [WEAK] + EXPORT USART3_IRQHandler [WEAK] + EXPORT LPUART1_IRQHandler [WEAK] + EXPORT LPTIM1_IRQHandler [WEAK] + EXPORT LPTIM2_IRQHandler [WEAK] + EXPORT USB_DRD_FS_IRQHandler [WEAK] + EXPORT CRS_IRQHandler [WEAK] + EXPORT GPDMA2_Channel0_IRQHandler [WEAK] + EXPORT GPDMA2_Channel1_IRQHandler [WEAK] + EXPORT GPDMA2_Channel2_IRQHandler [WEAK] + EXPORT GPDMA2_Channel3_IRQHandler [WEAK] + EXPORT GPDMA2_Channel4_IRQHandler [WEAK] + EXPORT GPDMA2_Channel5_IRQHandler [WEAK] + EXPORT GPDMA2_Channel6_IRQHandler [WEAK] + EXPORT GPDMA2_Channel7_IRQHandler [WEAK] + EXPORT COMP1_IRQHandler [WEAK] + EXPORT I3C2_EV_IRQHandler [WEAK] + EXPORT I3C2_ER_IRQHandler [WEAK] + EXPORT FPU_IRQHandler [WEAK] + EXPORT ICACHE_IRQHandler [WEAK] + EXPORT DTS_IRQHandler [WEAK] + EXPORT RNG_IRQHandler [WEAK] + EXPORT HASH_IRQHandler [WEAK] + EXPORT I3C1_EV_IRQHandler [WEAK] + EXPORT I3C1_ER_IRQHandler [WEAK] + +WWDG_IRQHandler +PVD_AVD_IRQHandler +RTC_IRQHandler +TAMP_IRQHandler +RAMCFG_IRQHandler +FLASH_IRQHandler +GTZC_IRQHandler +RCC_IRQHandler +EXTI0_IRQHandler +EXTI1_IRQHandler +EXTI2_IRQHandler +EXTI3_IRQHandler +EXTI4_IRQHandler +EXTI5_IRQHandler +EXTI6_IRQHandler +EXTI7_IRQHandler +EXTI8_IRQHandler +EXTI9_IRQHandler +EXTI10_IRQHandler +EXTI11_IRQHandler +EXTI12_IRQHandler +EXTI13_IRQHandler +EXTI14_IRQHandler +EXTI15_IRQHandler +GPDMA1_Channel0_IRQHandler +GPDMA1_Channel1_IRQHandler +GPDMA1_Channel2_IRQHandler +GPDMA1_Channel3_IRQHandler +GPDMA1_Channel4_IRQHandler +GPDMA1_Channel5_IRQHandler +GPDMA1_Channel6_IRQHandler +GPDMA1_Channel7_IRQHandler +IWDG_IRQHandler +ADC1_IRQHandler +DAC1_IRQHandler +FDCAN1_IT0_IRQHandler +FDCAN1_IT1_IRQHandler +TIM1_BRK_IRQHandler +TIM1_UP_IRQHandler +TIM1_TRG_COM_IRQHandler +TIM1_CC_IRQHandler +TIM2_IRQHandler +TIM3_IRQHandler +TIM6_IRQHandler +TIM7_IRQHandler +I2C1_EV_IRQHandler +I2C1_ER_IRQHandler +I2C2_EV_IRQHandler +I2C2_ER_IRQHandler +SPI1_IRQHandler +SPI2_IRQHandler +SPI3_IRQHandler +USART1_IRQHandler +USART2_IRQHandler +USART3_IRQHandler +LPUART1_IRQHandler +LPTIM1_IRQHandler +LPTIM2_IRQHandler +USB_DRD_FS_IRQHandler +CRS_IRQHandler +GPDMA2_Channel0_IRQHandler +GPDMA2_Channel1_IRQHandler +GPDMA2_Channel2_IRQHandler +GPDMA2_Channel3_IRQHandler +GPDMA2_Channel4_IRQHandler +GPDMA2_Channel5_IRQHandler +GPDMA2_Channel6_IRQHandler +GPDMA2_Channel7_IRQHandler +COMP1_IRQHandler +I3C2_EV_IRQHandler +I3C2_ER_IRQHandler +FPU_IRQHandler +ICACHE_IRQHandler +DTS_IRQHandler +RNG_IRQHandler +HASH_IRQHandler +I3C1_EV_IRQHandler +I3C1_ER_IRQHandler + + B . + + ENDP + + ALIGN + +;******************************************************************************* +; User Stack and Heap initialization +;******************************************************************************* + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap PROC + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + ENDP + + ALIGN + + ENDIF + + END + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/arm/startup_stm32h562xx.s b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/arm/startup_stm32h562xx.s new file mode 100644 index 0000000000..d4dcc14c8c --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/arm/startup_stm32h562xx.s @@ -0,0 +1,563 @@ +;******************************************************************************* +;* File Name : startup_stm32h562xx.s +;* Author : MCD Application Team +;* Description : STM32H562xx Non Crypto devices vector table for MDK-ARM toolchain. +;* This module performs: +;* - Set the initial SP +;* - Set the initial PC == Reset_Handler +;* - Set the vector table entries with the exceptions ISR address +;* - Branches to __main in the C library (which eventually +;* calls main()). +;* After Reset the Cortex-M33 processor is in Thread mode, +;* priority is Privileged, and the Stack is set to Main. +;******************************************************************************* +;* @attention +;* +;* Copyright (c) 2023 STMicroelectronics. +;* All rights reserved. +;* +;* This software is licensed under terms that can be found in the LICENSE file +;* in the root directory of this software component. +;* If no LICENSE file comes with this software, it is provided AS-IS. +;* +;******************************************************************************* +;* <<< Use Configuration Wizard in Context Menu >>> +; +; Amount of memory (in bytes) allocated for Stack +; Tailor this value to your application needs +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Stack_Size EQU 0x00000400 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + + +; Heap Configuration +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Heap_Size EQU 0x00000200 + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + + +; Vector Table Mapped to Address 0 at Reset + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD SecureFault_Handler ; Secure Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + ; External Interrupts + DCD WWDG_IRQHandler ; Window WatchDog + DCD PVD_AVD_IRQHandler ; PVD/AVD through EXTI Line detection Interrupt + DCD RTC_IRQHandler ; RTC non-secure interrupt + DCD RTC_S_IRQHandler ; RTC secure interrupt + DCD TAMP_IRQHandler ; Tamper non-secure interrupt + DCD RAMCFG_IRQHandler ; RAMCFG global + DCD FLASH_IRQHandler ; FLASH non-secure global interrupt + DCD FLASH_S_IRQHandler ; FLASH secure global interrupt + DCD GTZC_IRQHandler ; Global TrustZone Controller interrupt + DCD RCC_IRQHandler ; RCC non-secure global interrupt + DCD RCC_S_IRQHandler ; RCC secure global interrupt + DCD EXTI0_IRQHandler ; EXTI Line0 interrupt + DCD EXTI1_IRQHandler ; EXTI Line1 interrupt + DCD EXTI2_IRQHandler ; EXTI Line2 interrupt + DCD EXTI3_IRQHandler ; EXTI Line3 interrupt + DCD EXTI4_IRQHandler ; EXTI Line4 interrupt + DCD EXTI5_IRQHandler ; EXTI Line5 interrupt + DCD EXTI6_IRQHandler ; EXTI Line6 interrupt + DCD EXTI7_IRQHandler ; EXTI Line7 interrupt + DCD EXTI8_IRQHandler ; EXTI Line8 interrupt + DCD EXTI9_IRQHandler ; EXTI Line9 interrupt + DCD EXTI10_IRQHandler ; EXTI Line10 interrupt + DCD EXTI11_IRQHandler ; EXTI Line11 interrupt + DCD EXTI12_IRQHandler ; EXTI Line12 interrupt + DCD EXTI13_IRQHandler ; EXTI Line13 interrupt + DCD EXTI14_IRQHandler ; EXTI Line14 interrupt + DCD EXTI15_IRQHandler ; EXTI Line15 interrupt + DCD GPDMA1_Channel0_IRQHandler ; GPDMA1 Channel 0 global interrupt + DCD GPDMA1_Channel1_IRQHandler ; GPDMA1 Channel 1 global interrupt + DCD GPDMA1_Channel2_IRQHandler ; GPDMA1 Channel 2 global interrupt + DCD GPDMA1_Channel3_IRQHandler ; GPDMA1 Channel 3 global interrupt + DCD GPDMA1_Channel4_IRQHandler ; GPDMA1 Channel 4 global interrupt + DCD GPDMA1_Channel5_IRQHandler ; GPDMA1 Channel 5 global interrupt + DCD GPDMA1_Channel6_IRQHandler ; GPDMA1 Channel 6 global interrupt + DCD GPDMA1_Channel7_IRQHandler ; GPDMA1 Channel 7 global interrupt + DCD IWDG_IRQHandler ; IWDG global interrupt + DCD 0 ; Reserved + DCD ADC1_IRQHandler ; ADC1 global interrupt + DCD DAC1_IRQHandler ; DAC1 global interrupt + DCD FDCAN1_IT0_IRQHandler ; FDCAN1 interrupt 0 + DCD FDCAN1_IT1_IRQHandler ; FDCAN1 interrupt 1 + DCD TIM1_BRK_IRQHandler ; TIM1 Break interrupt + DCD TIM1_UP_IRQHandler ; TIM1 Update interrupt + DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation interrupt + DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare interrupt + DCD TIM2_IRQHandler ; TIM2 global interrupt + DCD TIM3_IRQHandler ; TIM3 global interrupt + DCD TIM4_IRQHandler ; TIM4 global interrupt + DCD TIM5_IRQHandler ; TIM5 global interrupt + DCD TIM6_IRQHandler ; TIM6 global interrupt + DCD TIM7_IRQHandler ; TIM7 global interrupt + DCD I2C1_EV_IRQHandler ; I2C1 Event interrupt + DCD I2C1_ER_IRQHandler ; I2C1 Error interrupt + DCD I2C2_EV_IRQHandler ; I2C2 Event interrupt + DCD I2C2_ER_IRQHandler ; I2C2 Error interrupt + DCD SPI1_IRQHandler ; SPI1 global interrupt + DCD SPI2_IRQHandler ; SPI2 global interrupt + DCD SPI3_IRQHandler ; SPI3 global interrupt + DCD USART1_IRQHandler ; USART1 global interrupt + DCD USART2_IRQHandler ; USART2 global interrupt + DCD USART3_IRQHandler ; USART3 global interrupt + DCD UART4_IRQHandler ; UART4 global interrupt + DCD UART5_IRQHandler ; UART5 global interrupt + DCD LPUART1_IRQHandler ; LPUART1 global interrupt + DCD LPTIM1_IRQHandler ; LPTIM1 global interrupt + DCD TIM8_BRK_IRQHandler ; TIM8 Break interrupt + DCD TIM8_UP_IRQHandler ; TIM8 Update interrupt + DCD TIM8_TRG_COM_IRQHandler ; TIM8 Trigger and Commutation interrupt + DCD TIM8_CC_IRQHandler ; TIM8 Capture Compare interrupt + DCD ADC2_IRQHandler ; ADC2 global interrupt + DCD LPTIM2_IRQHandler ; LPTIM2 global interrupt + DCD TIM15_IRQHandler ; TIM15 global interrupt + DCD TIM16_IRQHandler ; TIM16 global interrupt + DCD TIM17_IRQHandler ; TIM17 global interrupt + DCD USB_DRD_FS_IRQHandler ; USB DRD FS global interrupt + DCD CRS_IRQHandler ; CRS global interrupt + DCD UCPD1_IRQHandler ; UCPD1 global interrupt + DCD FMC_IRQHandler ; FMC global interrupt + DCD OCTOSPI1_IRQHandler ; OctoSPI1 global interrupt + DCD SDMMC1_IRQHandler ; SDMMC1 global interrupt + DCD I2C3_EV_IRQHandler ; I2C2 Event interrupt + DCD I2C3_ER_IRQHandler ; I2C2 Error interrupt + DCD SPI4_IRQHandler ; SPI4 global interrupt + DCD SPI5_IRQHandler ; SPI5 global interrupt + DCD SPI6_IRQHandler ; SPI6 global interrupt + DCD USART6_IRQHandler ; USART6 global interrupt + DCD USART10_IRQHandler ; USART10 global interrupt + DCD USART11_IRQHandler ; USART11 global interrupt + DCD SAI1_IRQHandler ; Serial Audio Interface 1 global interrupt + DCD SAI2_IRQHandler ; Serial Audio Interface 2 global interrupt + DCD GPDMA2_Channel0_IRQHandler ; GPDMA2 Channel 0 global interrupt + DCD GPDMA2_Channel1_IRQHandler ; GPDMA2 Channel 1 global interrupt + DCD GPDMA2_Channel2_IRQHandler ; GPDMA2 Channel 2 global interrupt + DCD GPDMA2_Channel3_IRQHandler ; GPDMA2 Channel 3 global interrupt + DCD GPDMA2_Channel4_IRQHandler ; GPDMA2 Channel 4 global interrupt + DCD GPDMA2_Channel5_IRQHandler ; GPDMA2 Channel 5 global interrupt + DCD GPDMA2_Channel6_IRQHandler ; GPDMA2 Channel 6 global interrupt + DCD GPDMA2_Channel7_IRQHandler ; GPDMA2 Channel 7 global interrupt + DCD UART7_IRQHandler ; UART7 global interrupt + DCD UART8_IRQHandler ; UART8 global interrupt + DCD UART9_IRQHandler ; UART9 global interrupt + DCD UART12_IRQHandler ; UART12 global interrupt + DCD 0 ; Reserved + DCD FPU_IRQHandler ; FPU global interrupt + DCD ICACHE_IRQHandler ; Instruction cache global interrupt + DCD DCACHE1_IRQHandler ; DCACHE1 global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD DCMI_PSSI_IRQHandler ; DCMI PSSI global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD CORDIC_IRQHandler ; CORDIC global interrupt + DCD FMAC_IRQHandler ; FMAC global interrupt + DCD DTS_IRQHandler ; DTS global interrupt + DCD RNG_IRQHandler ; RNG global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD HASH_IRQHandler ; HASH global interrupt + DCD 0 ; Reserved + DCD CEC_IRQHandler ; CEC global interrupt + DCD TIM12_IRQHandler ; TIM12 global interrupt + DCD TIM13_IRQHandler ; TIM13 global interrupt + DCD TIM14_IRQHandler ; TIM14 global interrupt + DCD I3C1_EV_IRQHandler ; I3C1 Event interrupt + DCD I3C1_ER_IRQHandler ; I3C1 Error interrupt + DCD I2C4_EV_IRQHandler ; I2C4 Event interrupt + DCD I2C4_ER_IRQHandler ; I2C4 Error interrupt + DCD LPTIM3_IRQHandler ; LPTIM3 global interrupt + DCD LPTIM4_IRQHandler ; LPTIM4 global interrupt + DCD LPTIM5_IRQHandler ; LPTIM5 global interrupt + DCD LPTIM6_IRQHandler ; LPTIM6 global interrupt + + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + + +; Reset Handler + +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler\ + PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemManage_Handler\ + PROC + EXPORT MemManage_Handler [WEAK] + B . + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SecureFault_Handler\ + PROC + EXPORT SecureFault_Handler [WEAK] + B . + ENDP +SVC_Handler\ + PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP +PendSV_Handler\ + PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler\ + PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + + EXPORT WWDG_IRQHandler [WEAK] + EXPORT PVD_AVD_IRQHandler [WEAK] + EXPORT RTC_IRQHandler [WEAK] + EXPORT RTC_S_IRQHandler [WEAK] + EXPORT TAMP_IRQHandler [WEAK] + EXPORT RAMCFG_IRQHandler [WEAK] + EXPORT FLASH_IRQHandler [WEAK] + EXPORT FLASH_S_IRQHandler [WEAK] + EXPORT GTZC_IRQHandler [WEAK] + EXPORT RCC_IRQHandler [WEAK] + EXPORT RCC_S_IRQHandler [WEAK] + EXPORT EXTI0_IRQHandler [WEAK] + EXPORT EXTI1_IRQHandler [WEAK] + EXPORT EXTI2_IRQHandler [WEAK] + EXPORT EXTI3_IRQHandler [WEAK] + EXPORT EXTI4_IRQHandler [WEAK] + EXPORT EXTI5_IRQHandler [WEAK] + EXPORT EXTI6_IRQHandler [WEAK] + EXPORT EXTI7_IRQHandler [WEAK] + EXPORT EXTI8_IRQHandler [WEAK] + EXPORT EXTI9_IRQHandler [WEAK] + EXPORT EXTI10_IRQHandler [WEAK] + EXPORT EXTI11_IRQHandler [WEAK] + EXPORT EXTI12_IRQHandler [WEAK] + EXPORT EXTI13_IRQHandler [WEAK] + EXPORT EXTI14_IRQHandler [WEAK] + EXPORT EXTI15_IRQHandler [WEAK] + EXPORT GPDMA1_Channel0_IRQHandler [WEAK] + EXPORT GPDMA1_Channel1_IRQHandler [WEAK] + EXPORT GPDMA1_Channel2_IRQHandler [WEAK] + EXPORT GPDMA1_Channel3_IRQHandler [WEAK] + EXPORT GPDMA1_Channel4_IRQHandler [WEAK] + EXPORT GPDMA1_Channel5_IRQHandler [WEAK] + EXPORT GPDMA1_Channel6_IRQHandler [WEAK] + EXPORT GPDMA1_Channel7_IRQHandler [WEAK] + EXPORT IWDG_IRQHandler [WEAK] + EXPORT ADC1_IRQHandler [WEAK] + EXPORT DAC1_IRQHandler [WEAK] + EXPORT FDCAN1_IT0_IRQHandler [WEAK] + EXPORT FDCAN1_IT1_IRQHandler [WEAK] + EXPORT TIM1_BRK_IRQHandler [WEAK] + EXPORT TIM1_UP_IRQHandler [WEAK] + EXPORT TIM1_TRG_COM_IRQHandler [WEAK] + EXPORT TIM1_CC_IRQHandler [WEAK] + EXPORT TIM2_IRQHandler [WEAK] + EXPORT TIM3_IRQHandler [WEAK] + EXPORT TIM4_IRQHandler [WEAK] + EXPORT TIM5_IRQHandler [WEAK] + EXPORT TIM6_IRQHandler [WEAK] + EXPORT TIM7_IRQHandler [WEAK] + EXPORT I2C1_EV_IRQHandler [WEAK] + EXPORT I2C1_ER_IRQHandler [WEAK] + EXPORT I2C2_EV_IRQHandler [WEAK] + EXPORT I2C2_ER_IRQHandler [WEAK] + EXPORT SPI1_IRQHandler [WEAK] + EXPORT SPI2_IRQHandler [WEAK] + EXPORT SPI3_IRQHandler [WEAK] + EXPORT USART1_IRQHandler [WEAK] + EXPORT USART2_IRQHandler [WEAK] + EXPORT USART3_IRQHandler [WEAK] + EXPORT UART4_IRQHandler [WEAK] + EXPORT UART5_IRQHandler [WEAK] + EXPORT LPUART1_IRQHandler [WEAK] + EXPORT LPTIM1_IRQHandler [WEAK] + EXPORT TIM8_BRK_IRQHandler [WEAK] + EXPORT TIM8_UP_IRQHandler [WEAK] + EXPORT TIM8_TRG_COM_IRQHandler [WEAK] + EXPORT TIM8_CC_IRQHandler [WEAK] + EXPORT ADC2_IRQHandler [WEAK] + EXPORT LPTIM2_IRQHandler [WEAK] + EXPORT TIM15_IRQHandler [WEAK] + EXPORT TIM16_IRQHandler [WEAK] + EXPORT TIM17_IRQHandler [WEAK] + EXPORT USB_DRD_FS_IRQHandler [WEAK] + EXPORT CRS_IRQHandler [WEAK] + EXPORT UCPD1_IRQHandler [WEAK] + EXPORT FMC_IRQHandler [WEAK] + EXPORT OCTOSPI1_IRQHandler [WEAK] + EXPORT SDMMC1_IRQHandler [WEAK] + EXPORT I2C3_EV_IRQHandler [WEAK] + EXPORT I2C3_ER_IRQHandler [WEAK] + EXPORT SPI4_IRQHandler [WEAK] + EXPORT SPI5_IRQHandler [WEAK] + EXPORT SPI6_IRQHandler [WEAK] + EXPORT USART6_IRQHandler [WEAK] + EXPORT USART10_IRQHandler [WEAK] + EXPORT USART11_IRQHandler [WEAK] + EXPORT SAI1_IRQHandler [WEAK] + EXPORT SAI2_IRQHandler [WEAK] + EXPORT GPDMA2_Channel0_IRQHandler [WEAK] + EXPORT GPDMA2_Channel1_IRQHandler [WEAK] + EXPORT GPDMA2_Channel2_IRQHandler [WEAK] + EXPORT GPDMA2_Channel3_IRQHandler [WEAK] + EXPORT GPDMA2_Channel4_IRQHandler [WEAK] + EXPORT GPDMA2_Channel5_IRQHandler [WEAK] + EXPORT GPDMA2_Channel6_IRQHandler [WEAK] + EXPORT GPDMA2_Channel7_IRQHandler [WEAK] + EXPORT UART7_IRQHandler [WEAK] + EXPORT UART8_IRQHandler [WEAK] + EXPORT UART9_IRQHandler [WEAK] + EXPORT UART12_IRQHandler [WEAK] + EXPORT FPU_IRQHandler [WEAK] + EXPORT ICACHE_IRQHandler [WEAK] + EXPORT DCACHE1_IRQHandler [WEAK] + EXPORT DCMI_PSSI_IRQHandler [WEAK] + EXPORT CORDIC_IRQHandler [WEAK] + EXPORT FMAC_IRQHandler [WEAK] + EXPORT DTS_IRQHandler [WEAK] + EXPORT RNG_IRQHandler [WEAK] + EXPORT HASH_IRQHandler [WEAK] + EXPORT CEC_IRQHandler [WEAK] + EXPORT TIM12_IRQHandler [WEAK] + EXPORT TIM13_IRQHandler [WEAK] + EXPORT TIM14_IRQHandler [WEAK] + EXPORT I3C1_EV_IRQHandler [WEAK] + EXPORT I3C1_ER_IRQHandler [WEAK] + EXPORT I2C4_EV_IRQHandler [WEAK] + EXPORT I2C4_ER_IRQHandler [WEAK] + EXPORT LPTIM3_IRQHandler [WEAK] + EXPORT LPTIM4_IRQHandler [WEAK] + EXPORT LPTIM5_IRQHandler [WEAK] + EXPORT LPTIM6_IRQHandler [WEAK] + +WWDG_IRQHandler +PVD_AVD_IRQHandler +RTC_IRQHandler +RTC_S_IRQHandler +TAMP_IRQHandler +RAMCFG_IRQHandler +FLASH_IRQHandler +FLASH_S_IRQHandler +GTZC_IRQHandler +RCC_IRQHandler +RCC_S_IRQHandler +EXTI0_IRQHandler +EXTI1_IRQHandler +EXTI2_IRQHandler +EXTI3_IRQHandler +EXTI4_IRQHandler +EXTI5_IRQHandler +EXTI6_IRQHandler +EXTI7_IRQHandler +EXTI8_IRQHandler +EXTI9_IRQHandler +EXTI10_IRQHandler +EXTI11_IRQHandler +EXTI12_IRQHandler +EXTI13_IRQHandler +EXTI14_IRQHandler +EXTI15_IRQHandler +GPDMA1_Channel0_IRQHandler +GPDMA1_Channel1_IRQHandler +GPDMA1_Channel2_IRQHandler +GPDMA1_Channel3_IRQHandler +GPDMA1_Channel4_IRQHandler +GPDMA1_Channel5_IRQHandler +GPDMA1_Channel6_IRQHandler +GPDMA1_Channel7_IRQHandler +IWDG_IRQHandler +ADC1_IRQHandler +DAC1_IRQHandler +FDCAN1_IT0_IRQHandler +FDCAN1_IT1_IRQHandler +TIM1_BRK_IRQHandler +TIM1_UP_IRQHandler +TIM1_TRG_COM_IRQHandler +TIM1_CC_IRQHandler +TIM2_IRQHandler +TIM3_IRQHandler +TIM4_IRQHandler +TIM5_IRQHandler +TIM6_IRQHandler +TIM7_IRQHandler +I2C1_EV_IRQHandler +I2C1_ER_IRQHandler +I2C2_EV_IRQHandler +I2C2_ER_IRQHandler +SPI1_IRQHandler +SPI2_IRQHandler +SPI3_IRQHandler +USART1_IRQHandler +USART2_IRQHandler +USART3_IRQHandler +UART4_IRQHandler +UART5_IRQHandler +LPUART1_IRQHandler +LPTIM1_IRQHandler +TIM8_BRK_IRQHandler +TIM8_UP_IRQHandler +TIM8_TRG_COM_IRQHandler +TIM8_CC_IRQHandler +ADC2_IRQHandler +LPTIM2_IRQHandler +TIM15_IRQHandler +TIM16_IRQHandler +TIM17_IRQHandler +USB_DRD_FS_IRQHandler +CRS_IRQHandler +UCPD1_IRQHandler +FMC_IRQHandler +OCTOSPI1_IRQHandler +SDMMC1_IRQHandler +I2C3_EV_IRQHandler +I2C3_ER_IRQHandler +SPI4_IRQHandler +SPI5_IRQHandler +SPI6_IRQHandler +USART6_IRQHandler +USART10_IRQHandler +USART11_IRQHandler +SAI1_IRQHandler +SAI2_IRQHandler +GPDMA2_Channel0_IRQHandler +GPDMA2_Channel1_IRQHandler +GPDMA2_Channel2_IRQHandler +GPDMA2_Channel3_IRQHandler +GPDMA2_Channel4_IRQHandler +GPDMA2_Channel5_IRQHandler +GPDMA2_Channel6_IRQHandler +GPDMA2_Channel7_IRQHandler +UART7_IRQHandler +UART8_IRQHandler +UART9_IRQHandler +UART12_IRQHandler +FPU_IRQHandler +ICACHE_IRQHandler +DCACHE1_IRQHandler +DCMI_PSSI_IRQHandler +CORDIC_IRQHandler +FMAC_IRQHandler +DTS_IRQHandler +RNG_IRQHandler +HASH_IRQHandler +CEC_IRQHandler +TIM12_IRQHandler +TIM13_IRQHandler +TIM14_IRQHandler +I3C1_EV_IRQHandler +I3C1_ER_IRQHandler +I2C4_EV_IRQHandler +I2C4_ER_IRQHandler +LPTIM3_IRQHandler +LPTIM4_IRQHandler +LPTIM5_IRQHandler +LPTIM6_IRQHandler + + B . + + ENDP + + ALIGN + +;******************************************************************************* +; User Stack and Heap initialization +;******************************************************************************* + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap PROC + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + ENDP + + ALIGN + + ENDIF + + END diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/arm/startup_stm32h563xx.s b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/arm/startup_stm32h563xx.s new file mode 100644 index 0000000000..044c5ad332 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/arm/startup_stm32h563xx.s @@ -0,0 +1,573 @@ +;******************************************************************************* +;* File Name : startup_stm32h563xx.s +;* Author : MCD Application Team +;* Description : STM32H563xx Non Crypto devices vector table for MDK-ARM toolchain. +;* This module performs: +;* - Set the initial SP +;* - Set the initial PC == Reset_Handler +;* - Set the vector table entries with the exceptions ISR address +;* - Branches to __main in the C library (which eventually +;* calls main()). +;* After Reset the Cortex-M33 processor is in Thread mode, +;* priority is Privileged, and the Stack is set to Main. +;******************************************************************************* +;* @attention +;* +;* Copyright (c) 2023 STMicroelectronics. +;* All rights reserved. +;* +;* This software is licensed under terms that can be found in the LICENSE file +;* in the root directory of this software component. +;* If no LICENSE file comes with this software, it is provided AS-IS. +;* +;******************************************************************************* +;* <<< Use Configuration Wizard in Context Menu >>> +; +; Amount of memory (in bytes) allocated for Stack +; Tailor this value to your application needs +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Stack_Size EQU 0x00000400 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + + +; Heap Configuration +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Heap_Size EQU 0x00000200 + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + + +; Vector Table Mapped to Address 0 at Reset + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD SecureFault_Handler ; Secure Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + ; External Interrupts + DCD WWDG_IRQHandler ; Window WatchDog + DCD PVD_AVD_IRQHandler ; PVD/AVD through EXTI Line detection Interrupt + DCD RTC_IRQHandler ; RTC non-secure interrupt + DCD RTC_S_IRQHandler ; RTC secure interrupt + DCD TAMP_IRQHandler ; Tamper non-secure interrupt + DCD RAMCFG_IRQHandler ; RAMCFG global + DCD FLASH_IRQHandler ; FLASH non-secure global interrupt + DCD FLASH_S_IRQHandler ; FLASH secure global interrupt + DCD GTZC_IRQHandler ; Global TrustZone Controller interrupt + DCD RCC_IRQHandler ; RCC non-secure global interrupt + DCD RCC_S_IRQHandler ; RCC secure global interrupt + DCD EXTI0_IRQHandler ; EXTI Line0 interrupt + DCD EXTI1_IRQHandler ; EXTI Line1 interrupt + DCD EXTI2_IRQHandler ; EXTI Line2 interrupt + DCD EXTI3_IRQHandler ; EXTI Line3 interrupt + DCD EXTI4_IRQHandler ; EXTI Line4 interrupt + DCD EXTI5_IRQHandler ; EXTI Line5 interrupt + DCD EXTI6_IRQHandler ; EXTI Line6 interrupt + DCD EXTI7_IRQHandler ; EXTI Line7 interrupt + DCD EXTI8_IRQHandler ; EXTI Line8 interrupt + DCD EXTI9_IRQHandler ; EXTI Line9 interrupt + DCD EXTI10_IRQHandler ; EXTI Line10 interrupt + DCD EXTI11_IRQHandler ; EXTI Line11 interrupt + DCD EXTI12_IRQHandler ; EXTI Line12 interrupt + DCD EXTI13_IRQHandler ; EXTI Line13 interrupt + DCD EXTI14_IRQHandler ; EXTI Line14 interrupt + DCD EXTI15_IRQHandler ; EXTI Line15 interrupt + DCD GPDMA1_Channel0_IRQHandler ; GPDMA1 Channel 0 global interrupt + DCD GPDMA1_Channel1_IRQHandler ; GPDMA1 Channel 1 global interrupt + DCD GPDMA1_Channel2_IRQHandler ; GPDMA1 Channel 2 global interrupt + DCD GPDMA1_Channel3_IRQHandler ; GPDMA1 Channel 3 global interrupt + DCD GPDMA1_Channel4_IRQHandler ; GPDMA1 Channel 4 global interrupt + DCD GPDMA1_Channel5_IRQHandler ; GPDMA1 Channel 5 global interrupt + DCD GPDMA1_Channel6_IRQHandler ; GPDMA1 Channel 6 global interrupt + DCD GPDMA1_Channel7_IRQHandler ; GPDMA1 Channel 7 global interrupt + DCD IWDG_IRQHandler ; IWDG global interrupt + DCD 0 ; Reserved + DCD ADC1_IRQHandler ; ADC1 global interrupt + DCD DAC1_IRQHandler ; DAC1 global interrupt + DCD FDCAN1_IT0_IRQHandler ; FDCAN1 interrupt 0 + DCD FDCAN1_IT1_IRQHandler ; FDCAN1 interrupt 1 + DCD TIM1_BRK_IRQHandler ; TIM1 Break interrupt + DCD TIM1_UP_IRQHandler ; TIM1 Update interrupt + DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation interrupt + DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare interrupt + DCD TIM2_IRQHandler ; TIM2 global interrupt + DCD TIM3_IRQHandler ; TIM3 global interrupt + DCD TIM4_IRQHandler ; TIM4 global interrupt + DCD TIM5_IRQHandler ; TIM5 global interrupt + DCD TIM6_IRQHandler ; TIM6 global interrupt + DCD TIM7_IRQHandler ; TIM7 global interrupt + DCD I2C1_EV_IRQHandler ; I2C1 Event interrupt + DCD I2C1_ER_IRQHandler ; I2C1 Error interrupt + DCD I2C2_EV_IRQHandler ; I2C2 Event interrupt + DCD I2C2_ER_IRQHandler ; I2C2 Error interrupt + DCD SPI1_IRQHandler ; SPI1 global interrupt + DCD SPI2_IRQHandler ; SPI2 global interrupt + DCD SPI3_IRQHandler ; SPI3 global interrupt + DCD USART1_IRQHandler ; USART1 global interrupt + DCD USART2_IRQHandler ; USART2 global interrupt + DCD USART3_IRQHandler ; USART3 global interrupt + DCD UART4_IRQHandler ; UART4 global interrupt + DCD UART5_IRQHandler ; UART5 global interrupt + DCD LPUART1_IRQHandler ; LPUART1 global interrupt + DCD LPTIM1_IRQHandler ; LPTIM1 global interrupt + DCD TIM8_BRK_IRQHandler ; TIM8 Break interrupt + DCD TIM8_UP_IRQHandler ; TIM8 Update interrupt + DCD TIM8_TRG_COM_IRQHandler ; TIM8 Trigger and Commutation interrupt + DCD TIM8_CC_IRQHandler ; TIM8 Capture Compare interrupt + DCD ADC2_IRQHandler ; ADC2 global interrupt + DCD LPTIM2_IRQHandler ; LPTIM2 global interrupt + DCD TIM15_IRQHandler ; TIM15 global interrupt + DCD TIM16_IRQHandler ; TIM16 global interrupt + DCD TIM17_IRQHandler ; TIM17 global interrupt + DCD USB_DRD_FS_IRQHandler ; USB DRD FS global interrupt + DCD CRS_IRQHandler ; CRS global interrupt + DCD UCPD1_IRQHandler ; UCPD1 global interrupt + DCD FMC_IRQHandler ; FMC global interrupt + DCD OCTOSPI1_IRQHandler ; OctoSPI1 global interrupt + DCD SDMMC1_IRQHandler ; SDMMC1 global interrupt + DCD I2C3_EV_IRQHandler ; I2C2 Event interrupt + DCD I2C3_ER_IRQHandler ; I2C2 Error interrupt + DCD SPI4_IRQHandler ; SPI4 global interrupt + DCD SPI5_IRQHandler ; SPI5 global interrupt + DCD SPI6_IRQHandler ; SPI6 global interrupt + DCD USART6_IRQHandler ; USART6 global interrupt + DCD USART10_IRQHandler ; USART10 global interrupt + DCD USART11_IRQHandler ; USART11 global interrupt + DCD SAI1_IRQHandler ; Serial Audio Interface 1 global interrupt + DCD SAI2_IRQHandler ; Serial Audio Interface 2 global interrupt + DCD GPDMA2_Channel0_IRQHandler ; GPDMA2 Channel 0 global interrupt + DCD GPDMA2_Channel1_IRQHandler ; GPDMA2 Channel 1 global interrupt + DCD GPDMA2_Channel2_IRQHandler ; GPDMA2 Channel 2 global interrupt + DCD GPDMA2_Channel3_IRQHandler ; GPDMA2 Channel 3 global interrupt + DCD GPDMA2_Channel4_IRQHandler ; GPDMA2 Channel 4 global interrupt + DCD GPDMA2_Channel5_IRQHandler ; GPDMA2 Channel 5 global interrupt + DCD GPDMA2_Channel6_IRQHandler ; GPDMA2 Channel 6 global interrupt + DCD GPDMA2_Channel7_IRQHandler ; GPDMA2 Channel 7 global interrupt + DCD UART7_IRQHandler ; UART7 global interrupt + DCD UART8_IRQHandler ; UART8 global interrupt + DCD UART9_IRQHandler ; UART9 global interrupt + DCD UART12_IRQHandler ; UART12 global interrupt + DCD SDMMC2_IRQHandler ; SDMMC2 global interrupt + DCD FPU_IRQHandler ; FPU global interrupt + DCD ICACHE_IRQHandler ; Instruction cache global interrupt + DCD DCACHE1_IRQHandler ; DCACHE1 global interrupt + DCD ETH_IRQHandler ; Ethernet global interrupt + DCD ETH_WKUP_IRQHandler ; Ethernet Wakeup global interrupt + DCD DCMI_PSSI_IRQHandler ; DCMI PSSI global interrupt + DCD FDCAN2_IT0_IRQHandler ; FDCAN2 interrupt 0 + DCD FDCAN2_IT1_IRQHandler ; FDCAN2 interrupt 1 + DCD CORDIC_IRQHandler ; CORDIC global interrupt + DCD FMAC_IRQHandler ; FMAC global interrupt + DCD DTS_IRQHandler ; DTS global interrupt + DCD RNG_IRQHandler ; RNG global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD HASH_IRQHandler ; HASH global interrupt + DCD 0 ; Reserved + DCD CEC_IRQHandler ; CEC global interrupt + DCD TIM12_IRQHandler ; TIM12 global interrupt + DCD TIM13_IRQHandler ; TIM13 global interrupt + DCD TIM14_IRQHandler ; TIM14 global interrupt + DCD I3C1_EV_IRQHandler ; I3C1 Event interrupt + DCD I3C1_ER_IRQHandler ; I3C1 Error interrupt + DCD I2C4_EV_IRQHandler ; I2C4 Event interrupt + DCD I2C4_ER_IRQHandler ; I2C4 Error interrupt + DCD LPTIM3_IRQHandler ; LPTIM3 global interrupt + DCD LPTIM4_IRQHandler ; LPTIM4 global interrupt + DCD LPTIM5_IRQHandler ; LPTIM5 global interrupt + DCD LPTIM6_IRQHandler ; LPTIM6 global interrupt + + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + + +; Reset Handler + +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler\ + PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemManage_Handler\ + PROC + EXPORT MemManage_Handler [WEAK] + B . + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SecureFault_Handler\ + PROC + EXPORT SecureFault_Handler [WEAK] + B . + ENDP +SVC_Handler\ + PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP +PendSV_Handler\ + PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler\ + PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + + EXPORT WWDG_IRQHandler [WEAK] + EXPORT PVD_AVD_IRQHandler [WEAK] + EXPORT RTC_IRQHandler [WEAK] + EXPORT RTC_S_IRQHandler [WEAK] + EXPORT TAMP_IRQHandler [WEAK] + EXPORT RAMCFG_IRQHandler [WEAK] + EXPORT FLASH_IRQHandler [WEAK] + EXPORT FLASH_S_IRQHandler [WEAK] + EXPORT GTZC_IRQHandler [WEAK] + EXPORT RCC_IRQHandler [WEAK] + EXPORT RCC_S_IRQHandler [WEAK] + EXPORT EXTI0_IRQHandler [WEAK] + EXPORT EXTI1_IRQHandler [WEAK] + EXPORT EXTI2_IRQHandler [WEAK] + EXPORT EXTI3_IRQHandler [WEAK] + EXPORT EXTI4_IRQHandler [WEAK] + EXPORT EXTI5_IRQHandler [WEAK] + EXPORT EXTI6_IRQHandler [WEAK] + EXPORT EXTI7_IRQHandler [WEAK] + EXPORT EXTI8_IRQHandler [WEAK] + EXPORT EXTI9_IRQHandler [WEAK] + EXPORT EXTI10_IRQHandler [WEAK] + EXPORT EXTI11_IRQHandler [WEAK] + EXPORT EXTI12_IRQHandler [WEAK] + EXPORT EXTI13_IRQHandler [WEAK] + EXPORT EXTI14_IRQHandler [WEAK] + EXPORT EXTI15_IRQHandler [WEAK] + EXPORT GPDMA1_Channel0_IRQHandler [WEAK] + EXPORT GPDMA1_Channel1_IRQHandler [WEAK] + EXPORT GPDMA1_Channel2_IRQHandler [WEAK] + EXPORT GPDMA1_Channel3_IRQHandler [WEAK] + EXPORT GPDMA1_Channel4_IRQHandler [WEAK] + EXPORT GPDMA1_Channel5_IRQHandler [WEAK] + EXPORT GPDMA1_Channel6_IRQHandler [WEAK] + EXPORT GPDMA1_Channel7_IRQHandler [WEAK] + EXPORT IWDG_IRQHandler [WEAK] + EXPORT ADC1_IRQHandler [WEAK] + EXPORT DAC1_IRQHandler [WEAK] + EXPORT FDCAN1_IT0_IRQHandler [WEAK] + EXPORT FDCAN1_IT1_IRQHandler [WEAK] + EXPORT TIM1_BRK_IRQHandler [WEAK] + EXPORT TIM1_UP_IRQHandler [WEAK] + EXPORT TIM1_TRG_COM_IRQHandler [WEAK] + EXPORT TIM1_CC_IRQHandler [WEAK] + EXPORT TIM2_IRQHandler [WEAK] + EXPORT TIM3_IRQHandler [WEAK] + EXPORT TIM4_IRQHandler [WEAK] + EXPORT TIM5_IRQHandler [WEAK] + EXPORT TIM6_IRQHandler [WEAK] + EXPORT TIM7_IRQHandler [WEAK] + EXPORT I2C1_EV_IRQHandler [WEAK] + EXPORT I2C1_ER_IRQHandler [WEAK] + EXPORT I2C2_EV_IRQHandler [WEAK] + EXPORT I2C2_ER_IRQHandler [WEAK] + EXPORT SPI1_IRQHandler [WEAK] + EXPORT SPI2_IRQHandler [WEAK] + EXPORT SPI3_IRQHandler [WEAK] + EXPORT USART1_IRQHandler [WEAK] + EXPORT USART2_IRQHandler [WEAK] + EXPORT USART3_IRQHandler [WEAK] + EXPORT UART4_IRQHandler [WEAK] + EXPORT UART5_IRQHandler [WEAK] + EXPORT LPUART1_IRQHandler [WEAK] + EXPORT LPTIM1_IRQHandler [WEAK] + EXPORT TIM8_BRK_IRQHandler [WEAK] + EXPORT TIM8_UP_IRQHandler [WEAK] + EXPORT TIM8_TRG_COM_IRQHandler [WEAK] + EXPORT TIM8_CC_IRQHandler [WEAK] + EXPORT ADC2_IRQHandler [WEAK] + EXPORT LPTIM2_IRQHandler [WEAK] + EXPORT TIM15_IRQHandler [WEAK] + EXPORT TIM16_IRQHandler [WEAK] + EXPORT TIM17_IRQHandler [WEAK] + EXPORT USB_DRD_FS_IRQHandler [WEAK] + EXPORT CRS_IRQHandler [WEAK] + EXPORT UCPD1_IRQHandler [WEAK] + EXPORT FMC_IRQHandler [WEAK] + EXPORT OCTOSPI1_IRQHandler [WEAK] + EXPORT SDMMC1_IRQHandler [WEAK] + EXPORT I2C3_EV_IRQHandler [WEAK] + EXPORT I2C3_ER_IRQHandler [WEAK] + EXPORT SPI4_IRQHandler [WEAK] + EXPORT SPI5_IRQHandler [WEAK] + EXPORT SPI6_IRQHandler [WEAK] + EXPORT USART6_IRQHandler [WEAK] + EXPORT USART10_IRQHandler [WEAK] + EXPORT USART11_IRQHandler [WEAK] + EXPORT SAI1_IRQHandler [WEAK] + EXPORT SAI2_IRQHandler [WEAK] + EXPORT GPDMA2_Channel0_IRQHandler [WEAK] + EXPORT GPDMA2_Channel1_IRQHandler [WEAK] + EXPORT GPDMA2_Channel2_IRQHandler [WEAK] + EXPORT GPDMA2_Channel3_IRQHandler [WEAK] + EXPORT GPDMA2_Channel4_IRQHandler [WEAK] + EXPORT GPDMA2_Channel5_IRQHandler [WEAK] + EXPORT GPDMA2_Channel6_IRQHandler [WEAK] + EXPORT GPDMA2_Channel7_IRQHandler [WEAK] + EXPORT UART7_IRQHandler [WEAK] + EXPORT UART8_IRQHandler [WEAK] + EXPORT UART9_IRQHandler [WEAK] + EXPORT UART12_IRQHandler [WEAK] + EXPORT SDMMC2_IRQHandler [WEAK] + EXPORT FPU_IRQHandler [WEAK] + EXPORT ICACHE_IRQHandler [WEAK] + EXPORT DCACHE1_IRQHandler [WEAK] + EXPORT ETH_IRQHandler [WEAK] + EXPORT ETH_WKUP_IRQHandler [WEAK] + EXPORT DCMI_PSSI_IRQHandler [WEAK] + EXPORT FDCAN2_IT0_IRQHandler [WEAK] + EXPORT FDCAN2_IT1_IRQHandler [WEAK] + EXPORT CORDIC_IRQHandler [WEAK] + EXPORT FMAC_IRQHandler [WEAK] + EXPORT DTS_IRQHandler [WEAK] + EXPORT RNG_IRQHandler [WEAK] + EXPORT HASH_IRQHandler [WEAK] + EXPORT CEC_IRQHandler [WEAK] + EXPORT TIM12_IRQHandler [WEAK] + EXPORT TIM13_IRQHandler [WEAK] + EXPORT TIM14_IRQHandler [WEAK] + EXPORT I3C1_EV_IRQHandler [WEAK] + EXPORT I3C1_ER_IRQHandler [WEAK] + EXPORT I2C4_EV_IRQHandler [WEAK] + EXPORT I2C4_ER_IRQHandler [WEAK] + EXPORT LPTIM3_IRQHandler [WEAK] + EXPORT LPTIM4_IRQHandler [WEAK] + EXPORT LPTIM5_IRQHandler [WEAK] + EXPORT LPTIM6_IRQHandler [WEAK] + +WWDG_IRQHandler +PVD_AVD_IRQHandler +RTC_IRQHandler +RTC_S_IRQHandler +TAMP_IRQHandler +RAMCFG_IRQHandler +FLASH_IRQHandler +FLASH_S_IRQHandler +GTZC_IRQHandler +RCC_IRQHandler +RCC_S_IRQHandler +EXTI0_IRQHandler +EXTI1_IRQHandler +EXTI2_IRQHandler +EXTI3_IRQHandler +EXTI4_IRQHandler +EXTI5_IRQHandler +EXTI6_IRQHandler +EXTI7_IRQHandler +EXTI8_IRQHandler +EXTI9_IRQHandler +EXTI10_IRQHandler +EXTI11_IRQHandler +EXTI12_IRQHandler +EXTI13_IRQHandler +EXTI14_IRQHandler +EXTI15_IRQHandler +GPDMA1_Channel0_IRQHandler +GPDMA1_Channel1_IRQHandler +GPDMA1_Channel2_IRQHandler +GPDMA1_Channel3_IRQHandler +GPDMA1_Channel4_IRQHandler +GPDMA1_Channel5_IRQHandler +GPDMA1_Channel6_IRQHandler +GPDMA1_Channel7_IRQHandler +IWDG_IRQHandler +ADC1_IRQHandler +DAC1_IRQHandler +FDCAN1_IT0_IRQHandler +FDCAN1_IT1_IRQHandler +TIM1_BRK_IRQHandler +TIM1_UP_IRQHandler +TIM1_TRG_COM_IRQHandler +TIM1_CC_IRQHandler +TIM2_IRQHandler +TIM3_IRQHandler +TIM4_IRQHandler +TIM5_IRQHandler +TIM6_IRQHandler +TIM7_IRQHandler +I2C1_EV_IRQHandler +I2C1_ER_IRQHandler +I2C2_EV_IRQHandler +I2C2_ER_IRQHandler +SPI1_IRQHandler +SPI2_IRQHandler +SPI3_IRQHandler +USART1_IRQHandler +USART2_IRQHandler +USART3_IRQHandler +UART4_IRQHandler +UART5_IRQHandler +LPUART1_IRQHandler +LPTIM1_IRQHandler +TIM8_BRK_IRQHandler +TIM8_UP_IRQHandler +TIM8_TRG_COM_IRQHandler +TIM8_CC_IRQHandler +ADC2_IRQHandler +LPTIM2_IRQHandler +TIM15_IRQHandler +TIM16_IRQHandler +TIM17_IRQHandler +USB_DRD_FS_IRQHandler +CRS_IRQHandler +UCPD1_IRQHandler +FMC_IRQHandler +OCTOSPI1_IRQHandler +SDMMC1_IRQHandler +I2C3_EV_IRQHandler +I2C3_ER_IRQHandler +SPI4_IRQHandler +SPI5_IRQHandler +SPI6_IRQHandler +USART6_IRQHandler +USART10_IRQHandler +USART11_IRQHandler +SAI1_IRQHandler +SAI2_IRQHandler +GPDMA2_Channel0_IRQHandler +GPDMA2_Channel1_IRQHandler +GPDMA2_Channel2_IRQHandler +GPDMA2_Channel3_IRQHandler +GPDMA2_Channel4_IRQHandler +GPDMA2_Channel5_IRQHandler +GPDMA2_Channel6_IRQHandler +GPDMA2_Channel7_IRQHandler +UART7_IRQHandler +UART8_IRQHandler +UART9_IRQHandler +UART12_IRQHandler +SDMMC2_IRQHandler +FPU_IRQHandler +ICACHE_IRQHandler +DCACHE1_IRQHandler +ETH_IRQHandler +ETH_WKUP_IRQHandler +DCMI_PSSI_IRQHandler +FDCAN2_IT0_IRQHandler +FDCAN2_IT1_IRQHandler +CORDIC_IRQHandler +FMAC_IRQHandler +DTS_IRQHandler +RNG_IRQHandler +HASH_IRQHandler +CEC_IRQHandler +TIM12_IRQHandler +TIM13_IRQHandler +TIM14_IRQHandler +I3C1_EV_IRQHandler +I3C1_ER_IRQHandler +I2C4_EV_IRQHandler +I2C4_ER_IRQHandler +LPTIM3_IRQHandler +LPTIM4_IRQHandler +LPTIM5_IRQHandler +LPTIM6_IRQHandler + + B . + + ENDP + + ALIGN + +;******************************************************************************* +; User Stack and Heap initialization +;******************************************************************************* + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap PROC + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + ENDP + + ALIGN + + ENDIF + + END diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/arm/startup_stm32h573xx.s b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/arm/startup_stm32h573xx.s new file mode 100644 index 0000000000..8af4daa022 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/arm/startup_stm32h573xx.s @@ -0,0 +1,581 @@ +;******************************************************************************* +;* File Name : startup_stm32h573xx.s +;* Author : MCD Application Team +;* Description : STM32H573xx Crypto devices vector table for MDK-ARM toolchain. +;* This module performs: +;* - Set the initial SP +;* - Set the initial PC == Reset_Handler +;* - Set the vector table entries with the exceptions ISR address +;* - Branches to __main in the C library (which eventually +;* calls main()). +;* After Reset the Cortex-M33 processor is in Thread mode, +;* priority is Privileged, and the Stack is set to Main. +;******************************************************************************* +;* @attention +;* +;* Copyright (c) 2023 STMicroelectronics. +;* All rights reserved. +;* +;* This software is licensed under terms that can be found in the LICENSE file +;* in the root directory of this software component. +;* If no LICENSE file comes with this software, it is provided AS-IS. +;* +;******************************************************************************* +;* <<< Use Configuration Wizard in Context Menu >>> +; +; Amount of memory (in bytes) allocated for Stack +; Tailor this value to your application needs +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Stack_Size EQU 0x00000400 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + + +; Heap Configuration +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Heap_Size EQU 0x00000200 + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + + +; Vector Table Mapped to Address 0 at Reset + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD SecureFault_Handler ; Secure Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + ; External Interrupts + DCD WWDG_IRQHandler ; Window WatchDog + DCD PVD_AVD_IRQHandler ; PVD/AVD through EXTI Line detection Interrupt + DCD RTC_IRQHandler ; RTC non-secure interrupt + DCD RTC_S_IRQHandler ; RTC secure interrupt + DCD TAMP_IRQHandler ; Tamper non-secure interrupt + DCD RAMCFG_IRQHandler ; RAMCFG global + DCD FLASH_IRQHandler ; FLASH non-secure global interrupt + DCD FLASH_S_IRQHandler ; FLASH secure global interrupt + DCD GTZC_IRQHandler ; Global TrustZone Controller interrupt + DCD RCC_IRQHandler ; RCC non-secure global interrupt + DCD RCC_S_IRQHandler ; RCC secure global interrupt + DCD EXTI0_IRQHandler ; EXTI Line0 interrupt + DCD EXTI1_IRQHandler ; EXTI Line1 interrupt + DCD EXTI2_IRQHandler ; EXTI Line2 interrupt + DCD EXTI3_IRQHandler ; EXTI Line3 interrupt + DCD EXTI4_IRQHandler ; EXTI Line4 interrupt + DCD EXTI5_IRQHandler ; EXTI Line5 interrupt + DCD EXTI6_IRQHandler ; EXTI Line6 interrupt + DCD EXTI7_IRQHandler ; EXTI Line7 interrupt + DCD EXTI8_IRQHandler ; EXTI Line8 interrupt + DCD EXTI9_IRQHandler ; EXTI Line9 interrupt + DCD EXTI10_IRQHandler ; EXTI Line10 interrupt + DCD EXTI11_IRQHandler ; EXTI Line11 interrupt + DCD EXTI12_IRQHandler ; EXTI Line12 interrupt + DCD EXTI13_IRQHandler ; EXTI Line13 interrupt + DCD EXTI14_IRQHandler ; EXTI Line14 interrupt + DCD EXTI15_IRQHandler ; EXTI Line15 interrupt + DCD GPDMA1_Channel0_IRQHandler ; GPDMA1 Channel 0 global interrupt + DCD GPDMA1_Channel1_IRQHandler ; GPDMA1 Channel 1 global interrupt + DCD GPDMA1_Channel2_IRQHandler ; GPDMA1 Channel 2 global interrupt + DCD GPDMA1_Channel3_IRQHandler ; GPDMA1 Channel 3 global interrupt + DCD GPDMA1_Channel4_IRQHandler ; GPDMA1 Channel 4 global interrupt + DCD GPDMA1_Channel5_IRQHandler ; GPDMA1 Channel 5 global interrupt + DCD GPDMA1_Channel6_IRQHandler ; GPDMA1 Channel 6 global interrupt + DCD GPDMA1_Channel7_IRQHandler ; GPDMA1 Channel 7 global interrupt + DCD IWDG_IRQHandler ; IWDG global interrupt + DCD SAES_IRQHandler ; SAES global interrupt + DCD ADC1_IRQHandler ; ADC1 global interrupt + DCD DAC1_IRQHandler ; DAC1 global interrupt + DCD FDCAN1_IT0_IRQHandler ; FDCAN1 interrupt 0 + DCD FDCAN1_IT1_IRQHandler ; FDCAN1 interrupt 1 + DCD TIM1_BRK_IRQHandler ; TIM1 Break interrupt + DCD TIM1_UP_IRQHandler ; TIM1 Update interrupt + DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation interrupt + DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare interrupt + DCD TIM2_IRQHandler ; TIM2 global interrupt + DCD TIM3_IRQHandler ; TIM3 global interrupt + DCD TIM4_IRQHandler ; TIM4 global interrupt + DCD TIM5_IRQHandler ; TIM5 global interrupt + DCD TIM6_IRQHandler ; TIM6 global interrupt + DCD TIM7_IRQHandler ; TIM7 global interrupt + DCD I2C1_EV_IRQHandler ; I2C1 Event interrupt + DCD I2C1_ER_IRQHandler ; I2C1 Error interrupt + DCD I2C2_EV_IRQHandler ; I2C2 Event interrupt + DCD I2C2_ER_IRQHandler ; I2C2 Error interrupt + DCD SPI1_IRQHandler ; SPI1 global interrupt + DCD SPI2_IRQHandler ; SPI2 global interrupt + DCD SPI3_IRQHandler ; SPI3 global interrupt + DCD USART1_IRQHandler ; USART1 global interrupt + DCD USART2_IRQHandler ; USART2 global interrupt + DCD USART3_IRQHandler ; USART3 global interrupt + DCD UART4_IRQHandler ; UART4 global interrupt + DCD UART5_IRQHandler ; UART5 global interrupt + DCD LPUART1_IRQHandler ; LPUART1 global interrupt + DCD LPTIM1_IRQHandler ; LPTIM1 global interrupt + DCD TIM8_BRK_IRQHandler ; TIM8 Break interrupt + DCD TIM8_UP_IRQHandler ; TIM8 Update interrupt + DCD TIM8_TRG_COM_IRQHandler ; TIM8 Trigger and Commutation interrupt + DCD TIM8_CC_IRQHandler ; TIM8 Capture Compare interrupt + DCD ADC2_IRQHandler ; ADC2 global interrupt + DCD LPTIM2_IRQHandler ; LPTIM2 global interrupt + DCD TIM15_IRQHandler ; TIM15 global interrupt + DCD TIM16_IRQHandler ; TIM16 global interrupt + DCD TIM17_IRQHandler ; TIM17 global interrupt + DCD USB_DRD_FS_IRQHandler ; USB DRD FS global interrupt + DCD CRS_IRQHandler ; CRS global interrupt + DCD UCPD1_IRQHandler ; UCPD1 global interrupt + DCD FMC_IRQHandler ; FMC global interrupt + DCD OCTOSPI1_IRQHandler ; OctoSPI1 global interrupt + DCD SDMMC1_IRQHandler ; SDMMC1 global interrupt + DCD I2C3_EV_IRQHandler ; I2C2 Event interrupt + DCD I2C3_ER_IRQHandler ; I2C2 Error interrupt + DCD SPI4_IRQHandler ; SPI4 global interrupt + DCD SPI5_IRQHandler ; SPI5 global interrupt + DCD SPI6_IRQHandler ; SPI6 global interrupt + DCD USART6_IRQHandler ; USART6 global interrupt + DCD USART10_IRQHandler ; USART10 global interrupt + DCD USART11_IRQHandler ; USART11 global interrupt + DCD SAI1_IRQHandler ; Serial Audio Interface 1 global interrupt + DCD SAI2_IRQHandler ; Serial Audio Interface 2 global interrupt + DCD GPDMA2_Channel0_IRQHandler ; GPDMA2 Channel 0 global interrupt + DCD GPDMA2_Channel1_IRQHandler ; GPDMA2 Channel 1 global interrupt + DCD GPDMA2_Channel2_IRQHandler ; GPDMA2 Channel 2 global interrupt + DCD GPDMA2_Channel3_IRQHandler ; GPDMA2 Channel 3 global interrupt + DCD GPDMA2_Channel4_IRQHandler ; GPDMA2 Channel 4 global interrupt + DCD GPDMA2_Channel5_IRQHandler ; GPDMA2 Channel 5 global interrupt + DCD GPDMA2_Channel6_IRQHandler ; GPDMA2 Channel 6 global interrupt + DCD GPDMA2_Channel7_IRQHandler ; GPDMA2 Channel 7 global interrupt + DCD UART7_IRQHandler ; UART7 global interrupt + DCD UART8_IRQHandler ; UART8 global interrupt + DCD UART9_IRQHandler ; UART9 global interrupt + DCD UART12_IRQHandler ; UART12 global interrupt + DCD SDMMC2_IRQHandler ; SDMMC2 global interrupt + DCD FPU_IRQHandler ; FPU global interrupt + DCD ICACHE_IRQHandler ; Instruction cache global interrupt + DCD DCACHE1_IRQHandler ; DCACHE1 global interrupt + DCD ETH_IRQHandler ; Ethernet global interrupt + DCD ETH_WKUP_IRQHandler ; Ethernet Wakeup global interrupt + DCD DCMI_PSSI_IRQHandler ; DCMI PSSI global interrupt + DCD FDCAN2_IT0_IRQHandler ; FDCAN2 interrupt 0 + DCD FDCAN2_IT1_IRQHandler ; FDCAN2 interrupt 1 + DCD CORDIC_IRQHandler ; CORDIC global interrupt + DCD FMAC_IRQHandler ; FMAC global interrupt + DCD DTS_IRQHandler ; DTS global interrupt + DCD RNG_IRQHandler ; RNG global interrupt + DCD OTFDEC1_IRQHandler ; OTFDEC1 global interrupt + DCD AES_IRQHandler ; AES global interrupt + DCD HASH_IRQHandler ; HASH global interrupt + DCD PKA_IRQHandler ; PKA global interrupt + DCD CEC_IRQHandler ; CEC global interrupt + DCD TIM12_IRQHandler ; TIM12 global interrupt + DCD TIM13_IRQHandler ; TIM13 global interrupt + DCD TIM14_IRQHandler ; TIM14 global interrupt + DCD I3C1_EV_IRQHandler ; I3C1 Event interrupt + DCD I3C1_ER_IRQHandler ; I3C1 Error interrupt + DCD I2C4_EV_IRQHandler ; I2C4 Event interrupt + DCD I2C4_ER_IRQHandler ; I2C4 Error interrupt + DCD LPTIM3_IRQHandler ; LPTIM3 global interrupt + DCD LPTIM4_IRQHandler ; LPTIM4 global interrupt + DCD LPTIM5_IRQHandler ; LPTIM5 global interrupt + DCD LPTIM6_IRQHandler ; LPTIM6 global interrupt + + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + + +; Reset Handler + +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler\ + PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemManage_Handler\ + PROC + EXPORT MemManage_Handler [WEAK] + B . + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SecureFault_Handler\ + PROC + EXPORT SecureFault_Handler [WEAK] + B . + ENDP +SVC_Handler\ + PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP +PendSV_Handler\ + PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler\ + PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + + EXPORT WWDG_IRQHandler [WEAK] + EXPORT PVD_AVD_IRQHandler [WEAK] + EXPORT RTC_IRQHandler [WEAK] + EXPORT RTC_S_IRQHandler [WEAK] + EXPORT TAMP_IRQHandler [WEAK] + EXPORT RAMCFG_IRQHandler [WEAK] + EXPORT FLASH_IRQHandler [WEAK] + EXPORT FLASH_S_IRQHandler [WEAK] + EXPORT GTZC_IRQHandler [WEAK] + EXPORT RCC_IRQHandler [WEAK] + EXPORT RCC_S_IRQHandler [WEAK] + EXPORT EXTI0_IRQHandler [WEAK] + EXPORT EXTI1_IRQHandler [WEAK] + EXPORT EXTI2_IRQHandler [WEAK] + EXPORT EXTI3_IRQHandler [WEAK] + EXPORT EXTI4_IRQHandler [WEAK] + EXPORT EXTI5_IRQHandler [WEAK] + EXPORT EXTI6_IRQHandler [WEAK] + EXPORT EXTI7_IRQHandler [WEAK] + EXPORT EXTI8_IRQHandler [WEAK] + EXPORT EXTI9_IRQHandler [WEAK] + EXPORT EXTI10_IRQHandler [WEAK] + EXPORT EXTI11_IRQHandler [WEAK] + EXPORT EXTI12_IRQHandler [WEAK] + EXPORT EXTI13_IRQHandler [WEAK] + EXPORT EXTI14_IRQHandler [WEAK] + EXPORT EXTI15_IRQHandler [WEAK] + EXPORT GPDMA1_Channel0_IRQHandler [WEAK] + EXPORT GPDMA1_Channel1_IRQHandler [WEAK] + EXPORT GPDMA1_Channel2_IRQHandler [WEAK] + EXPORT GPDMA1_Channel3_IRQHandler [WEAK] + EXPORT GPDMA1_Channel4_IRQHandler [WEAK] + EXPORT GPDMA1_Channel5_IRQHandler [WEAK] + EXPORT GPDMA1_Channel6_IRQHandler [WEAK] + EXPORT GPDMA1_Channel7_IRQHandler [WEAK] + EXPORT IWDG_IRQHandler [WEAK] + EXPORT SAES_IRQHandler [WEAK] + EXPORT ADC1_IRQHandler [WEAK] + EXPORT DAC1_IRQHandler [WEAK] + EXPORT FDCAN1_IT0_IRQHandler [WEAK] + EXPORT FDCAN1_IT1_IRQHandler [WEAK] + EXPORT TIM1_BRK_IRQHandler [WEAK] + EXPORT TIM1_UP_IRQHandler [WEAK] + EXPORT TIM1_TRG_COM_IRQHandler [WEAK] + EXPORT TIM1_CC_IRQHandler [WEAK] + EXPORT TIM2_IRQHandler [WEAK] + EXPORT TIM3_IRQHandler [WEAK] + EXPORT TIM4_IRQHandler [WEAK] + EXPORT TIM5_IRQHandler [WEAK] + EXPORT TIM6_IRQHandler [WEAK] + EXPORT TIM7_IRQHandler [WEAK] + EXPORT I2C1_EV_IRQHandler [WEAK] + EXPORT I2C1_ER_IRQHandler [WEAK] + EXPORT I2C2_EV_IRQHandler [WEAK] + EXPORT I2C2_ER_IRQHandler [WEAK] + EXPORT SPI1_IRQHandler [WEAK] + EXPORT SPI2_IRQHandler [WEAK] + EXPORT SPI3_IRQHandler [WEAK] + EXPORT USART1_IRQHandler [WEAK] + EXPORT USART2_IRQHandler [WEAK] + EXPORT USART3_IRQHandler [WEAK] + EXPORT UART4_IRQHandler [WEAK] + EXPORT UART5_IRQHandler [WEAK] + EXPORT LPUART1_IRQHandler [WEAK] + EXPORT LPTIM1_IRQHandler [WEAK] + EXPORT TIM8_BRK_IRQHandler [WEAK] + EXPORT TIM8_UP_IRQHandler [WEAK] + EXPORT TIM8_TRG_COM_IRQHandler [WEAK] + EXPORT TIM8_CC_IRQHandler [WEAK] + EXPORT ADC2_IRQHandler [WEAK] + EXPORT LPTIM2_IRQHandler [WEAK] + EXPORT TIM15_IRQHandler [WEAK] + EXPORT TIM16_IRQHandler [WEAK] + EXPORT TIM17_IRQHandler [WEAK] + EXPORT USB_DRD_FS_IRQHandler [WEAK] + EXPORT CRS_IRQHandler [WEAK] + EXPORT UCPD1_IRQHandler [WEAK] + EXPORT FMC_IRQHandler [WEAK] + EXPORT OCTOSPI1_IRQHandler [WEAK] + EXPORT SDMMC1_IRQHandler [WEAK] + EXPORT I2C3_EV_IRQHandler [WEAK] + EXPORT I2C3_ER_IRQHandler [WEAK] + EXPORT SPI4_IRQHandler [WEAK] + EXPORT SPI5_IRQHandler [WEAK] + EXPORT SPI6_IRQHandler [WEAK] + EXPORT USART6_IRQHandler [WEAK] + EXPORT USART10_IRQHandler [WEAK] + EXPORT USART11_IRQHandler [WEAK] + EXPORT SAI1_IRQHandler [WEAK] + EXPORT SAI2_IRQHandler [WEAK] + EXPORT GPDMA2_Channel0_IRQHandler [WEAK] + EXPORT GPDMA2_Channel1_IRQHandler [WEAK] + EXPORT GPDMA2_Channel2_IRQHandler [WEAK] + EXPORT GPDMA2_Channel3_IRQHandler [WEAK] + EXPORT GPDMA2_Channel4_IRQHandler [WEAK] + EXPORT GPDMA2_Channel5_IRQHandler [WEAK] + EXPORT GPDMA2_Channel6_IRQHandler [WEAK] + EXPORT GPDMA2_Channel7_IRQHandler [WEAK] + EXPORT UART7_IRQHandler [WEAK] + EXPORT UART8_IRQHandler [WEAK] + EXPORT UART9_IRQHandler [WEAK] + EXPORT UART12_IRQHandler [WEAK] + EXPORT SDMMC2_IRQHandler [WEAK] + EXPORT FPU_IRQHandler [WEAK] + EXPORT ICACHE_IRQHandler [WEAK] + EXPORT DCACHE1_IRQHandler [WEAK] + EXPORT ETH_IRQHandler [WEAK] + EXPORT ETH_WKUP_IRQHandler [WEAK] + EXPORT DCMI_PSSI_IRQHandler [WEAK] + EXPORT FDCAN2_IT0_IRQHandler [WEAK] + EXPORT FDCAN2_IT1_IRQHandler [WEAK] + EXPORT CORDIC_IRQHandler [WEAK] + EXPORT FMAC_IRQHandler [WEAK] + EXPORT DTS_IRQHandler [WEAK] + EXPORT RNG_IRQHandler [WEAK] + EXPORT OTFDEC1_IRQHandler [WEAK] + EXPORT AES_IRQHandler [WEAK] + EXPORT HASH_IRQHandler [WEAK] + EXPORT PKA_IRQHandler [WEAK] + EXPORT CEC_IRQHandler [WEAK] + EXPORT TIM12_IRQHandler [WEAK] + EXPORT TIM13_IRQHandler [WEAK] + EXPORT TIM14_IRQHandler [WEAK] + EXPORT I3C1_EV_IRQHandler [WEAK] + EXPORT I3C1_ER_IRQHandler [WEAK] + EXPORT I2C4_EV_IRQHandler [WEAK] + EXPORT I2C4_ER_IRQHandler [WEAK] + EXPORT LPTIM3_IRQHandler [WEAK] + EXPORT LPTIM4_IRQHandler [WEAK] + EXPORT LPTIM5_IRQHandler [WEAK] + EXPORT LPTIM6_IRQHandler [WEAK] + +WWDG_IRQHandler +PVD_AVD_IRQHandler +RTC_IRQHandler +RTC_S_IRQHandler +TAMP_IRQHandler +RAMCFG_IRQHandler +FLASH_IRQHandler +FLASH_S_IRQHandler +GTZC_IRQHandler +RCC_IRQHandler +RCC_S_IRQHandler +EXTI0_IRQHandler +EXTI1_IRQHandler +EXTI2_IRQHandler +EXTI3_IRQHandler +EXTI4_IRQHandler +EXTI5_IRQHandler +EXTI6_IRQHandler +EXTI7_IRQHandler +EXTI8_IRQHandler +EXTI9_IRQHandler +EXTI10_IRQHandler +EXTI11_IRQHandler +EXTI12_IRQHandler +EXTI13_IRQHandler +EXTI14_IRQHandler +EXTI15_IRQHandler +GPDMA1_Channel0_IRQHandler +GPDMA1_Channel1_IRQHandler +GPDMA1_Channel2_IRQHandler +GPDMA1_Channel3_IRQHandler +GPDMA1_Channel4_IRQHandler +GPDMA1_Channel5_IRQHandler +GPDMA1_Channel6_IRQHandler +GPDMA1_Channel7_IRQHandler +IWDG_IRQHandler +SAES_IRQHandler +ADC1_IRQHandler +DAC1_IRQHandler +FDCAN1_IT0_IRQHandler +FDCAN1_IT1_IRQHandler +TIM1_BRK_IRQHandler +TIM1_UP_IRQHandler +TIM1_TRG_COM_IRQHandler +TIM1_CC_IRQHandler +TIM2_IRQHandler +TIM3_IRQHandler +TIM4_IRQHandler +TIM5_IRQHandler +TIM6_IRQHandler +TIM7_IRQHandler +I2C1_EV_IRQHandler +I2C1_ER_IRQHandler +I2C2_EV_IRQHandler +I2C2_ER_IRQHandler +SPI1_IRQHandler +SPI2_IRQHandler +SPI3_IRQHandler +USART1_IRQHandler +USART2_IRQHandler +USART3_IRQHandler +UART4_IRQHandler +UART5_IRQHandler +LPUART1_IRQHandler +LPTIM1_IRQHandler +TIM8_BRK_IRQHandler +TIM8_UP_IRQHandler +TIM8_TRG_COM_IRQHandler +TIM8_CC_IRQHandler +ADC2_IRQHandler +LPTIM2_IRQHandler +TIM15_IRQHandler +TIM16_IRQHandler +TIM17_IRQHandler +USB_DRD_FS_IRQHandler +CRS_IRQHandler +UCPD1_IRQHandler +FMC_IRQHandler +OCTOSPI1_IRQHandler +SDMMC1_IRQHandler +I2C3_EV_IRQHandler +I2C3_ER_IRQHandler +SPI4_IRQHandler +SPI5_IRQHandler +SPI6_IRQHandler +USART6_IRQHandler +USART10_IRQHandler +USART11_IRQHandler +SAI1_IRQHandler +SAI2_IRQHandler +GPDMA2_Channel0_IRQHandler +GPDMA2_Channel1_IRQHandler +GPDMA2_Channel2_IRQHandler +GPDMA2_Channel3_IRQHandler +GPDMA2_Channel4_IRQHandler +GPDMA2_Channel5_IRQHandler +GPDMA2_Channel6_IRQHandler +GPDMA2_Channel7_IRQHandler +UART7_IRQHandler +UART8_IRQHandler +UART9_IRQHandler +UART12_IRQHandler +SDMMC2_IRQHandler +FPU_IRQHandler +ICACHE_IRQHandler +DCACHE1_IRQHandler +ETH_IRQHandler +ETH_WKUP_IRQHandler +DCMI_PSSI_IRQHandler +FDCAN2_IT0_IRQHandler +FDCAN2_IT1_IRQHandler +CORDIC_IRQHandler +FMAC_IRQHandler +DTS_IRQHandler +RNG_IRQHandler +OTFDEC1_IRQHandler +AES_IRQHandler +HASH_IRQHandler +PKA_IRQHandler +CEC_IRQHandler +TIM12_IRQHandler +TIM13_IRQHandler +TIM14_IRQHandler +I3C1_EV_IRQHandler +I3C1_ER_IRQHandler +I2C4_EV_IRQHandler +I2C4_ER_IRQHandler +LPTIM3_IRQHandler +LPTIM4_IRQHandler +LPTIM5_IRQHandler +LPTIM6_IRQHandler + + B . + + ENDP + + ALIGN + +;******************************************************************************* +; User Stack and Heap initialization +;******************************************************************************* + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap PROC + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + ENDP + + ALIGN + + ENDIF + + END diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/gcc/startup_stm32h503xx.s b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/gcc/startup_stm32h503xx.s new file mode 100644 index 0000000000..6038f5bdce --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/gcc/startup_stm32h503xx.s @@ -0,0 +1,547 @@ +/** + ****************************************************************************** + * @file startup_stm32h503xx.s + * @author MCD Application Team + * @brief STM32H503xx devices vector table GCC toolchain. + * This module performs: + * - Set the initial SP + * - Set the initial PC == Reset_Handler, + * - Set the vector table entries with the exceptions ISR address, + * - Configure the clock system + * - Branches to main in the C library (which eventually + * calls main()). + * After Reset the Cortex-M33 processor is in Thread mode, + * priority is Privileged, and the Stack is set to Main. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + + .syntax unified + .cpu cortex-m33 + .fpu softvfp + .thumb + +.global g_pfnVectors +.global Default_Handler + +/* start address for the initialization values of the .data section. +defined in linker script */ +.word _sidata +/* start address for the .data section. defined in linker script */ +.word _sdata +/* end address for the .data section. defined in linker script */ +.word _edata +/* start address for the .bss section. defined in linker script */ +.word _sbss +/* end address for the .bss section. defined in linker script */ +.word _ebss + +.equ BootRAM, 0xF1E0F85F +/** + * @brief This is the code that gets called when the processor first + * starts execution following a reset event. Only the absolutely + * necessary set is performed, after which the application + * supplied main() routine is called. + * @param None + * @retval : None + */ + + .section .text.Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + ldr sp, =_estack /* set stack pointer */ + +/* Copy the data segment initializers from flash to SRAM */ + movs r1, #0 + b LoopCopyDataInit + +CopyDataInit: + ldr r3, =_sidata + ldr r3, [r3, r1] + str r3, [r0, r1] + adds r1, r1, #4 + +LoopCopyDataInit: + ldr r0, =_sdata + ldr r3, =_edata + adds r2, r0, r1 + cmp r2, r3 + bcc CopyDataInit + ldr r2, =_sbss + b LoopFillZerobss +/* Zero fill the bss segment. */ +FillZerobss: + movs r3, #0 + str r3, [r2], #4 + +LoopFillZerobss: + ldr r3, = _ebss + cmp r2, r3 + bcc FillZerobss + +/* Call the clock system initialization function.*/ + bl SystemInit +/* Call static constructors */ + bl __libc_init_array +/* Call the application's entry point.*/ + bl main + +LoopForever: + b LoopForever + +.size Reset_Handler, .-Reset_Handler + +/** + * @brief This is the code that gets called when the processor receives an + * unexpected interrupt. This simply enters an infinite loop, preserving + * the system state for examination by a debugger. + * + * @param None + * @retval : None +*/ + .section .text.Default_Handler,"ax",%progbits +Default_Handler: +Infinite_Loop: + b Infinite_Loop + .size Default_Handler, .-Default_Handler +/****************************************************************************** +* +* The minimal vector table for a Cortex-M33. Note that the proper constructs +* must be placed on this to ensure that it ends up at physical address +* 0x0000.0000. +* +******************************************************************************/ + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + .size g_pfnVectors, .-g_pfnVectors + + +g_pfnVectors: + .word _estack + .word Reset_Handler + .word NMI_Handler + .word HardFault_Handler + .word MemManage_Handler + .word BusFault_Handler + .word UsageFault_Handler + .word 0 + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word DebugMon_Handler + .word 0 + .word PendSV_Handler + .word SysTick_Handler + .word WWDG_IRQHandler + .word PVD_AVD_IRQHandler + .word RTC_IRQHandler + .word 0 + .word TAMP_IRQHandler + .word RAMCFG_IRQHandler + .word FLASH_IRQHandler + .word 0 + .word GTZC_IRQHandler + .word RCC_IRQHandler + .word 0 + .word EXTI0_IRQHandler + .word EXTI1_IRQHandler + .word EXTI2_IRQHandler + .word EXTI3_IRQHandler + .word EXTI4_IRQHandler + .word EXTI5_IRQHandler + .word EXTI6_IRQHandler + .word EXTI7_IRQHandler + .word EXTI8_IRQHandler + .word EXTI9_IRQHandler + .word EXTI10_IRQHandler + .word EXTI11_IRQHandler + .word EXTI12_IRQHandler + .word EXTI13_IRQHandler + .word EXTI14_IRQHandler + .word EXTI15_IRQHandler + .word GPDMA1_Channel0_IRQHandler + .word GPDMA1_Channel1_IRQHandler + .word GPDMA1_Channel2_IRQHandler + .word GPDMA1_Channel3_IRQHandler + .word GPDMA1_Channel4_IRQHandler + .word GPDMA1_Channel5_IRQHandler + .word GPDMA1_Channel6_IRQHandler + .word GPDMA1_Channel7_IRQHandler + .word IWDG_IRQHandler + .word 0 + .word ADC1_IRQHandler + .word DAC1_IRQHandler + .word FDCAN1_IT0_IRQHandler + .word FDCAN1_IT1_IRQHandler + .word TIM1_BRK_IRQHandler + .word TIM1_UP_IRQHandler + .word TIM1_TRG_COM_IRQHandler + .word TIM1_CC_IRQHandler + .word TIM2_IRQHandler + .word TIM3_IRQHandler + .word 0 + .word 0 + .word TIM6_IRQHandler + .word TIM7_IRQHandler + .word I2C1_EV_IRQHandler + .word I2C1_ER_IRQHandler + .word I2C2_EV_IRQHandler + .word I2C2_ER_IRQHandler + .word SPI1_IRQHandler + .word SPI2_IRQHandler + .word SPI3_IRQHandler + .word USART1_IRQHandler + .word USART2_IRQHandler + .word USART3_IRQHandler + .word 0 + .word 0 + .word LPUART1_IRQHandler + .word LPTIM1_IRQHandler + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word LPTIM2_IRQHandler + .word 0 + .word 0 + .word 0 + .word USB_DRD_FS_IRQHandler + .word CRS_IRQHandler + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word GPDMA2_Channel0_IRQHandler + .word GPDMA2_Channel1_IRQHandler + .word GPDMA2_Channel2_IRQHandler + .word GPDMA2_Channel3_IRQHandler + .word GPDMA2_Channel4_IRQHandler + .word GPDMA2_Channel5_IRQHandler + .word GPDMA2_Channel6_IRQHandler + .word GPDMA2_Channel7_IRQHandler + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word FPU_IRQHandler + .word ICACHE_IRQHandler + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word DTS_IRQHandler + .word RNG_IRQHandler + .word 0 + .word 0 + .word HASH_IRQHandler + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word I3C1_EV_IRQHandler + .word I3C1_ER_IRQHandler + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word I3C2_EV_IRQHandler + .word I3C2_ER_IRQHandler + .word COMP1_IRQHandler + +/******************************************************************************* +* +* Provide weak aliases for each Exception handler to the Default_Handler. +* As they are weak aliases, any function with the same name will override +* this definition. +* +*******************************************************************************/ + + .weak NMI_Handler + .thumb_set NMI_Handler,Default_Handler + + .weak HardFault_Handler + .thumb_set HardFault_Handler,Default_Handler + + .weak MemManage_Handler + .thumb_set MemManage_Handler,Default_Handler + + .weak BusFault_Handler + .thumb_set BusFault_Handler,Default_Handler + + .weak UsageFault_Handler + .thumb_set UsageFault_Handler,Default_Handler + + .weak SVC_Handler + .thumb_set SVC_Handler,Default_Handler + + .weak DebugMon_Handler + .thumb_set DebugMon_Handler,Default_Handler + + .weak PendSV_Handler + .thumb_set PendSV_Handler,Default_Handler + + .weak SysTick_Handler + .thumb_set SysTick_Handler,Default_Handler + + .weak WWDG_IRQHandler + .thumb_set WWDG_IRQHandler,Default_Handler + + .weak PVD_AVD_IRQHandler + .thumb_set PVD_AVD_IRQHandler,Default_Handler + + .weak RTC_IRQHandler + .thumb_set RTC_IRQHandler,Default_Handler + + .weak TAMP_IRQHandler + .thumb_set TAMP_IRQHandler,Default_Handler + + .weak RAMCFG_IRQHandler + .thumb_set RAMCFG_IRQHandler,Default_Handler + + .weak FLASH_IRQHandler + .thumb_set FLASH_IRQHandler,Default_Handler + + .weak GTZC_IRQHandler + .thumb_set GTZC_IRQHandler,Default_Handler + + .weak RCC_IRQHandler + .thumb_set RCC_IRQHandler,Default_Handler + + .weak EXTI0_IRQHandler + .thumb_set EXTI0_IRQHandler,Default_Handler + + .weak EXTI1_IRQHandler + .thumb_set EXTI1_IRQHandler,Default_Handler + + .weak EXTI2_IRQHandler + .thumb_set EXTI2_IRQHandler,Default_Handler + + .weak EXTI3_IRQHandler + .thumb_set EXTI3_IRQHandler,Default_Handler + + .weak EXTI4_IRQHandler + .thumb_set EXTI4_IRQHandler,Default_Handler + + .weak EXTI5_IRQHandler + .thumb_set EXTI5_IRQHandler,Default_Handler + + .weak EXTI6_IRQHandler + .thumb_set EXTI6_IRQHandler,Default_Handler + + .weak EXTI7_IRQHandler + .thumb_set EXTI7_IRQHandler,Default_Handler + + .weak EXTI8_IRQHandler + .thumb_set EXTI8_IRQHandler,Default_Handler + + .weak EXTI9_IRQHandler + .thumb_set EXTI9_IRQHandler,Default_Handler + + .weak EXTI10_IRQHandler + .thumb_set EXTI10_IRQHandler,Default_Handler + + .weak EXTI11_IRQHandler + .thumb_set EXTI11_IRQHandler,Default_Handler + + .weak EXTI12_IRQHandler + .thumb_set EXTI12_IRQHandler,Default_Handler + + .weak EXTI13_IRQHandler + .thumb_set EXTI13_IRQHandler,Default_Handler + + .weak EXTI14_IRQHandler + .thumb_set EXTI14_IRQHandler,Default_Handler + + .weak EXTI15_IRQHandler + .thumb_set EXTI15_IRQHandler,Default_Handler + + .weak GPDMA1_Channel0_IRQHandler + .thumb_set GPDMA1_Channel0_IRQHandler,Default_Handler + + .weak GPDMA1_Channel1_IRQHandler + .thumb_set GPDMA1_Channel1_IRQHandler,Default_Handler + + .weak GPDMA1_Channel2_IRQHandler + .thumb_set GPDMA1_Channel2_IRQHandler,Default_Handler + + .weak GPDMA1_Channel3_IRQHandler + .thumb_set GPDMA1_Channel3_IRQHandler,Default_Handler + + .weak GPDMA1_Channel4_IRQHandler + .thumb_set GPDMA1_Channel4_IRQHandler,Default_Handler + + .weak GPDMA1_Channel5_IRQHandler + .thumb_set GPDMA1_Channel5_IRQHandler,Default_Handler + + .weak GPDMA1_Channel6_IRQHandler + .thumb_set GPDMA1_Channel6_IRQHandler,Default_Handler + + .weak GPDMA1_Channel7_IRQHandler + .thumb_set GPDMA1_Channel7_IRQHandler,Default_Handler + + .weak IWDG_IRQHandler + .thumb_set IWDG_IRQHandler,Default_Handler + + .weak ADC1_IRQHandler + .thumb_set ADC1_IRQHandler,Default_Handler + + .weak DAC1_IRQHandler + .thumb_set DAC1_IRQHandler,Default_Handler + + .weak FDCAN1_IT0_IRQHandler + .thumb_set FDCAN1_IT0_IRQHandler,Default_Handler + + .weak FDCAN1_IT1_IRQHandler + .thumb_set FDCAN1_IT1_IRQHandler,Default_Handler + + .weak TIM1_BRK_IRQHandler + .thumb_set TIM1_BRK_IRQHandler,Default_Handler + + .weak TIM1_UP_IRQHandler + .thumb_set TIM1_UP_IRQHandler,Default_Handler + + .weak TIM1_TRG_COM_IRQHandler + .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler + + .weak TIM1_CC_IRQHandler + .thumb_set TIM1_CC_IRQHandler,Default_Handler + + .weak TIM2_IRQHandler + .thumb_set TIM2_IRQHandler,Default_Handler + + .weak TIM3_IRQHandler + .thumb_set TIM3_IRQHandler,Default_Handler + + .weak TIM6_IRQHandler + .thumb_set TIM6_IRQHandler,Default_Handler + + .weak TIM7_IRQHandler + .thumb_set TIM7_IRQHandler,Default_Handler + + .weak I2C1_EV_IRQHandler + .thumb_set I2C1_EV_IRQHandler,Default_Handler + + .weak I2C1_ER_IRQHandler + .thumb_set I2C1_ER_IRQHandler,Default_Handler + + .weak I2C2_EV_IRQHandler + .thumb_set I2C2_EV_IRQHandler,Default_Handler + + .weak I2C2_ER_IRQHandler + .thumb_set I2C2_ER_IRQHandler,Default_Handler + + .weak SPI1_IRQHandler + .thumb_set SPI1_IRQHandler,Default_Handler + + .weak SPI2_IRQHandler + .thumb_set SPI2_IRQHandler,Default_Handler + + .weak SPI3_IRQHandler + .thumb_set SPI3_IRQHandler,Default_Handler + + .weak USART1_IRQHandler + .thumb_set USART1_IRQHandler,Default_Handler + + .weak USART2_IRQHandler + .thumb_set USART2_IRQHandler,Default_Handler + + .weak USART3_IRQHandler + .thumb_set USART3_IRQHandler,Default_Handler + + .weak LPUART1_IRQHandler + .thumb_set LPUART1_IRQHandler,Default_Handler + + .weak LPTIM1_IRQHandler + .thumb_set LPTIM1_IRQHandler,Default_Handler + + .weak LPTIM2_IRQHandler + .thumb_set LPTIM2_IRQHandler,Default_Handler + + .weak USB_DRD_FS_IRQHandler + .thumb_set USB_DRD_FS_IRQHandler,Default_Handler + + .weak CRS_IRQHandler + .thumb_set CRS_IRQHandler,Default_Handler + + .weak GPDMA2_Channel0_IRQHandler + .thumb_set GPDMA2_Channel0_IRQHandler,Default_Handler + + .weak GPDMA2_Channel1_IRQHandler + .thumb_set GPDMA2_Channel1_IRQHandler,Default_Handler + + .weak GPDMA2_Channel2_IRQHandler + .thumb_set GPDMA2_Channel2_IRQHandler,Default_Handler + + .weak GPDMA2_Channel3_IRQHandler + .thumb_set GPDMA2_Channel3_IRQHandler,Default_Handler + + .weak GPDMA2_Channel4_IRQHandler + .thumb_set GPDMA2_Channel4_IRQHandler,Default_Handler + + .weak GPDMA2_Channel5_IRQHandler + .thumb_set GPDMA2_Channel5_IRQHandler,Default_Handler + + .weak GPDMA2_Channel6_IRQHandler + .thumb_set GPDMA2_Channel6_IRQHandler,Default_Handler + + .weak GPDMA2_Channel7_IRQHandler + .thumb_set GPDMA2_Channel7_IRQHandler,Default_Handler + + .weak FPU_IRQHandler + .thumb_set FPU_IRQHandler,Default_Handler + .weak ICACHE_IRQHandler + .thumb_set ICACHE_IRQHandler,Default_Handler + + .weak DTS_IRQHandler + .thumb_set DTS_IRQHandler,Default_Handler + + .weak RNG_IRQHandler + .thumb_set RNG_IRQHandler,Default_Handler + + .weak HASH_IRQHandler + .thumb_set HASH_IRQHandler,Default_Handler + + .weak I3C1_EV_IRQHandler + .thumb_set I3C1_EV_IRQHandler,Default_Handler + + .weak I3C1_ER_IRQHandler + .thumb_set I3C1_ER_IRQHandler,Default_Handler + + .weak I3C2_EV_IRQHandler + .thumb_set I3C2_EV_IRQHandler,Default_Handler + + .weak I3C2_ER_IRQHandler + .thumb_set I3C2_ER_IRQHandler,Default_Handler + + .weak COMP1_IRQHandler + .thumb_set COMP1_IRQHandler,Default_Handler diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/gcc/startup_stm32h562xx.s b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/gcc/startup_stm32h562xx.s new file mode 100644 index 0000000000..faa4e1e800 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/gcc/startup_stm32h562xx.s @@ -0,0 +1,680 @@ +/** + ****************************************************************************** + * @file startup_stm32h573xx.s + * @author MCD Application Team + * @brief STM32H563xx devices vector table GCC toolchain. + * This module performs: + * - Set the initial SP + * - Set the initial PC == Reset_Handler, + * - Set the vector table entries with the exceptions ISR address, + * - Configure the clock system + * - Branches to main in the C library (which eventually + * calls main()). + * After Reset the Cortex-M33 processor is in Thread mode, + * priority is Privileged, and the Stack is set to Main. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + + .syntax unified + .cpu cortex-m33 + .fpu softvfp + .thumb + +.global g_pfnVectors +.global Default_Handler + +/* start address for the initialization values of the .data section. +defined in linker script */ +.word _sidata +/* start address for the .data section. defined in linker script */ +.word _sdata +/* end address for the .data section. defined in linker script */ +.word _edata +/* start address for the .bss section. defined in linker script */ +.word _sbss +/* end address for the .bss section. defined in linker script */ +.word _ebss + +.equ BootRAM, 0xF1E0F85F +/** + * @brief This is the code that gets called when the processor first + * starts execution following a reset event. Only the absolutely + * necessary set is performed, after which the application + * supplied main() routine is called. + * @param None + * @retval : None + */ + + .section .text.Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + ldr sp, =_estack /* set stack pointer */ + +/* Copy the data segment initializers from flash to SRAM */ + movs r1, #0 + b LoopCopyDataInit + +CopyDataInit: + ldr r3, =_sidata + ldr r3, [r3, r1] + str r3, [r0, r1] + adds r1, r1, #4 + +LoopCopyDataInit: + ldr r0, =_sdata + ldr r3, =_edata + adds r2, r0, r1 + cmp r2, r3 + bcc CopyDataInit + ldr r2, =_sbss + b LoopFillZerobss +/* Zero fill the bss segment. */ +FillZerobss: + movs r3, #0 + str r3, [r2], #4 + +LoopFillZerobss: + ldr r3, = _ebss + cmp r2, r3 + bcc FillZerobss + +/* Call the clock system initialization function.*/ + bl SystemInit +/* Call static constructors */ + bl __libc_init_array +/* Call the application's entry point.*/ + bl main + +LoopForever: + b LoopForever + +.size Reset_Handler, .-Reset_Handler + +/** + * @brief This is the code that gets called when the processor receives an + * unexpected interrupt. This simply enters an infinite loop, preserving + * the system state for examination by a debugger. + * + * @param None + * @retval : None +*/ + .section .text.Default_Handler,"ax",%progbits +Default_Handler: +Infinite_Loop: + b Infinite_Loop + .size Default_Handler, .-Default_Handler +/****************************************************************************** +* +* The minimal vector table for a Cortex-M33. Note that the proper constructs +* must be placed on this to ensure that it ends up at physical address +* 0x0000.0000. +* +******************************************************************************/ + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + .size g_pfnVectors, .-g_pfnVectors + + +g_pfnVectors: + .word _estack + .word Reset_Handler + .word NMI_Handler + .word HardFault_Handler + .word MemManage_Handler + .word BusFault_Handler + .word UsageFault_Handler + .word SecureFault_Handler + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word DebugMon_Handler + .word 0 + .word PendSV_Handler + .word SysTick_Handler + .word WWDG_IRQHandler + .word PVD_AVD_IRQHandler + .word RTC_IRQHandler + .word RTC_S_IRQHandler + .word TAMP_IRQHandler + .word RAMCFG_IRQHandler + .word FLASH_IRQHandler + .word FLASH_S_IRQHandler + .word GTZC_IRQHandler + .word RCC_IRQHandler + .word RCC_S_IRQHandler + .word EXTI0_IRQHandler + .word EXTI1_IRQHandler + .word EXTI2_IRQHandler + .word EXTI3_IRQHandler + .word EXTI4_IRQHandler + .word EXTI5_IRQHandler + .word EXTI6_IRQHandler + .word EXTI7_IRQHandler + .word EXTI8_IRQHandler + .word EXTI9_IRQHandler + .word EXTI10_IRQHandler + .word EXTI11_IRQHandler + .word EXTI12_IRQHandler + .word EXTI13_IRQHandler + .word EXTI14_IRQHandler + .word EXTI15_IRQHandler + .word GPDMA1_Channel0_IRQHandler + .word GPDMA1_Channel1_IRQHandler + .word GPDMA1_Channel2_IRQHandler + .word GPDMA1_Channel3_IRQHandler + .word GPDMA1_Channel4_IRQHandler + .word GPDMA1_Channel5_IRQHandler + .word GPDMA1_Channel6_IRQHandler + .word GPDMA1_Channel7_IRQHandler + .word IWDG_IRQHandler + .word 0 + .word ADC1_IRQHandler + .word DAC1_IRQHandler + .word FDCAN1_IT0_IRQHandler + .word FDCAN1_IT1_IRQHandler + .word TIM1_BRK_IRQHandler + .word TIM1_UP_IRQHandler + .word TIM1_TRG_COM_IRQHandler + .word TIM1_CC_IRQHandler + .word TIM2_IRQHandler + .word TIM3_IRQHandler + .word TIM4_IRQHandler + .word TIM5_IRQHandler + .word TIM6_IRQHandler + .word TIM7_IRQHandler + .word I2C1_EV_IRQHandler + .word I2C1_ER_IRQHandler + .word I2C2_EV_IRQHandler + .word I2C2_ER_IRQHandler + .word SPI1_IRQHandler + .word SPI2_IRQHandler + .word SPI3_IRQHandler + .word USART1_IRQHandler + .word USART2_IRQHandler + .word USART3_IRQHandler + .word UART4_IRQHandler + .word UART5_IRQHandler + .word LPUART1_IRQHandler + .word LPTIM1_IRQHandler + .word TIM8_BRK_IRQHandler + .word TIM8_UP_IRQHandler + .word TIM8_TRG_COM_IRQHandler + .word TIM8_CC_IRQHandler + .word ADC2_IRQHandler + .word LPTIM2_IRQHandler + .word TIM15_IRQHandler + .word TIM16_IRQHandler + .word TIM17_IRQHandler + .word USB_DRD_FS_IRQHandler + .word CRS_IRQHandler + .word UCPD1_IRQHandler + .word FMC_IRQHandler + .word OCTOSPI1_IRQHandler + .word SDMMC1_IRQHandler + .word I2C3_EV_IRQHandler + .word I2C3_ER_IRQHandler + .word SPI4_IRQHandler + .word SPI5_IRQHandler + .word SPI6_IRQHandler + .word USART6_IRQHandler + .word USART10_IRQHandler + .word USART11_IRQHandler + .word SAI1_IRQHandler + .word SAI2_IRQHandler + .word GPDMA2_Channel0_IRQHandler + .word GPDMA2_Channel1_IRQHandler + .word GPDMA2_Channel2_IRQHandler + .word GPDMA2_Channel3_IRQHandler + .word GPDMA2_Channel4_IRQHandler + .word GPDMA2_Channel5_IRQHandler + .word GPDMA2_Channel6_IRQHandler + .word GPDMA2_Channel7_IRQHandler + .word UART7_IRQHandler + .word UART8_IRQHandler + .word UART9_IRQHandler + .word UART12_IRQHandler + .word 0 + .word FPU_IRQHandler + .word ICACHE_IRQHandler + .word DCACHE1_IRQHandler + .word 0 + .word 0 + .word DCMI_PSSI_IRQHandler + .word 0 + .word 0 + .word CORDIC_IRQHandler + .word FMAC_IRQHandler + .word DTS_IRQHandler + .word RNG_IRQHandler + .word 0 + .word 0 + .word HASH_IRQHandler + .word 0 + .word CEC_IRQHandler + .word TIM12_IRQHandler + .word TIM13_IRQHandler + .word TIM14_IRQHandler + .word I3C1_EV_IRQHandler + .word I3C1_ER_IRQHandler + .word I2C4_EV_IRQHandler + .word I2C4_ER_IRQHandler + .word LPTIM3_IRQHandler + .word LPTIM4_IRQHandler + .word LPTIM5_IRQHandler + .word LPTIM6_IRQHandler + +/******************************************************************************* +* +* Provide weak aliases for each Exception handler to the Default_Handler. +* As they are weak aliases, any function with the same name will override +* this definition. +* +*******************************************************************************/ + + .weak NMI_Handler + .thumb_set NMI_Handler,Default_Handler + + .weak HardFault_Handler + .thumb_set HardFault_Handler,Default_Handler + + .weak MemManage_Handler + .thumb_set MemManage_Handler,Default_Handler + + .weak BusFault_Handler + .thumb_set BusFault_Handler,Default_Handler + + .weak UsageFault_Handler + .thumb_set UsageFault_Handler,Default_Handler + + .weak SecureFault_Handler + .thumb_set SecureFault_Handler,Default_Handler + + .weak SVC_Handler + .thumb_set SVC_Handler,Default_Handler + + .weak DebugMon_Handler + .thumb_set DebugMon_Handler,Default_Handler + + .weak PendSV_Handler + .thumb_set PendSV_Handler,Default_Handler + + .weak SysTick_Handler + .thumb_set SysTick_Handler,Default_Handler + + .weak WWDG_IRQHandler + .thumb_set WWDG_IRQHandler,Default_Handler + + .weak PVD_AVD_IRQHandler + .thumb_set PVD_AVD_IRQHandler,Default_Handler + + .weak RTC_IRQHandler + .thumb_set RTC_IRQHandler,Default_Handler + + .weak RTC_S_IRQHandler + .thumb_set RTC_S_IRQHandler,Default_Handler + + .weak TAMP_IRQHandler + .thumb_set TAMP_IRQHandler,Default_Handler + + .weak RAMCFG_IRQHandler + .thumb_set RAMCFG_IRQHandler,Default_Handler + + .weak FLASH_IRQHandler + .thumb_set FLASH_IRQHandler,Default_Handler + + .weak FLASH_S_IRQHandler + .thumb_set FLASH_S_IRQHandler,Default_Handler + + .weak GTZC_IRQHandler + .thumb_set GTZC_IRQHandler,Default_Handler + + .weak RCC_IRQHandler + .thumb_set RCC_IRQHandler,Default_Handler + + .weak RCC_S_IRQHandler + .thumb_set RCC_S_IRQHandler,Default_Handler + + .weak EXTI0_IRQHandler + .thumb_set EXTI0_IRQHandler,Default_Handler + + .weak EXTI1_IRQHandler + .thumb_set EXTI1_IRQHandler,Default_Handler + + .weak EXTI2_IRQHandler + .thumb_set EXTI2_IRQHandler,Default_Handler + + .weak EXTI3_IRQHandler + .thumb_set EXTI3_IRQHandler,Default_Handler + + .weak EXTI4_IRQHandler + .thumb_set EXTI4_IRQHandler,Default_Handler + + .weak EXTI5_IRQHandler + .thumb_set EXTI5_IRQHandler,Default_Handler + + .weak EXTI6_IRQHandler + .thumb_set EXTI6_IRQHandler,Default_Handler + + .weak EXTI7_IRQHandler + .thumb_set EXTI7_IRQHandler,Default_Handler + + .weak EXTI8_IRQHandler + .thumb_set EXTI8_IRQHandler,Default_Handler + + .weak EXTI9_IRQHandler + .thumb_set EXTI9_IRQHandler,Default_Handler + + .weak EXTI10_IRQHandler + .thumb_set EXTI10_IRQHandler,Default_Handler + + .weak EXTI11_IRQHandler + .thumb_set EXTI11_IRQHandler,Default_Handler + + .weak EXTI12_IRQHandler + .thumb_set EXTI12_IRQHandler,Default_Handler + + .weak EXTI13_IRQHandler + .thumb_set EXTI13_IRQHandler,Default_Handler + + .weak EXTI14_IRQHandler + .thumb_set EXTI14_IRQHandler,Default_Handler + + .weak EXTI15_IRQHandler + .thumb_set EXTI15_IRQHandler,Default_Handler + + .weak GPDMA1_Channel0_IRQHandler + .thumb_set GPDMA1_Channel0_IRQHandler,Default_Handler + + .weak GPDMA1_Channel1_IRQHandler + .thumb_set GPDMA1_Channel1_IRQHandler,Default_Handler + + .weak GPDMA1_Channel2_IRQHandler + .thumb_set GPDMA1_Channel2_IRQHandler,Default_Handler + + .weak GPDMA1_Channel3_IRQHandler + .thumb_set GPDMA1_Channel3_IRQHandler,Default_Handler + + .weak GPDMA1_Channel4_IRQHandler + .thumb_set GPDMA1_Channel4_IRQHandler,Default_Handler + + .weak GPDMA1_Channel5_IRQHandler + .thumb_set GPDMA1_Channel5_IRQHandler,Default_Handler + + .weak GPDMA1_Channel6_IRQHandler + .thumb_set GPDMA1_Channel6_IRQHandler,Default_Handler + + .weak GPDMA1_Channel7_IRQHandler + .thumb_set GPDMA1_Channel7_IRQHandler,Default_Handler + + .weak IWDG_IRQHandler + .thumb_set IWDG_IRQHandler,Default_Handler + + .weak ADC1_IRQHandler + .thumb_set ADC1_IRQHandler,Default_Handler + + .weak DAC1_IRQHandler + .thumb_set DAC1_IRQHandler,Default_Handler + + .weak FDCAN1_IT0_IRQHandler + .thumb_set FDCAN1_IT0_IRQHandler,Default_Handler + + .weak FDCAN1_IT1_IRQHandler + .thumb_set FDCAN1_IT1_IRQHandler,Default_Handler + + .weak TIM1_BRK_IRQHandler + .thumb_set TIM1_BRK_IRQHandler,Default_Handler + + .weak TIM1_UP_IRQHandler + .thumb_set TIM1_UP_IRQHandler,Default_Handler + + .weak TIM1_TRG_COM_IRQHandler + .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler + + .weak TIM1_CC_IRQHandler + .thumb_set TIM1_CC_IRQHandler,Default_Handler + + .weak TIM2_IRQHandler + .thumb_set TIM2_IRQHandler,Default_Handler + + .weak TIM3_IRQHandler + .thumb_set TIM3_IRQHandler,Default_Handler + + .weak TIM4_IRQHandler + .thumb_set TIM4_IRQHandler,Default_Handler + + .weak TIM5_IRQHandler + .thumb_set TIM5_IRQHandler,Default_Handler + + .weak TIM6_IRQHandler + .thumb_set TIM6_IRQHandler,Default_Handler + + .weak TIM7_IRQHandler + .thumb_set TIM7_IRQHandler,Default_Handler + + .weak I2C1_EV_IRQHandler + .thumb_set I2C1_EV_IRQHandler,Default_Handler + + .weak I2C1_ER_IRQHandler + .thumb_set I2C1_ER_IRQHandler,Default_Handler + + .weak I2C2_EV_IRQHandler + .thumb_set I2C2_EV_IRQHandler,Default_Handler + + .weak I2C2_ER_IRQHandler + .thumb_set I2C2_ER_IRQHandler,Default_Handler + + .weak SPI1_IRQHandler + .thumb_set SPI1_IRQHandler,Default_Handler + + .weak SPI2_IRQHandler + .thumb_set SPI2_IRQHandler,Default_Handler + + .weak SPI3_IRQHandler + .thumb_set SPI3_IRQHandler,Default_Handler + + .weak USART1_IRQHandler + .thumb_set USART1_IRQHandler,Default_Handler + + .weak USART2_IRQHandler + .thumb_set USART2_IRQHandler,Default_Handler + + .weak USART3_IRQHandler + .thumb_set USART3_IRQHandler,Default_Handler + + .weak UART4_IRQHandler + .thumb_set UART4_IRQHandler,Default_Handler + + .weak UART5_IRQHandler + .thumb_set UART5_IRQHandler,Default_Handler + + .weak LPUART1_IRQHandler + .thumb_set LPUART1_IRQHandler,Default_Handler + + .weak LPTIM1_IRQHandler + .thumb_set LPTIM1_IRQHandler,Default_Handler + + .weak TIM8_BRK_IRQHandler + .thumb_set TIM8_BRK_IRQHandler,Default_Handler + + .weak TIM8_UP_IRQHandler + .thumb_set TIM8_UP_IRQHandler,Default_Handler + + .weak TIM8_TRG_COM_IRQHandler + .thumb_set TIM8_TRG_COM_IRQHandler,Default_Handler + + .weak TIM8_CC_IRQHandler + .thumb_set TIM8_CC_IRQHandler,Default_Handler + + .weak ADC2_IRQHandler + .thumb_set ADC2_IRQHandler,Default_Handler + + .weak LPTIM2_IRQHandler + .thumb_set LPTIM2_IRQHandler,Default_Handler + + .weak TIM15_IRQHandler + .thumb_set TIM15_IRQHandler,Default_Handler + + .weak TIM16_IRQHandler + .thumb_set TIM16_IRQHandler,Default_Handler + + .weak TIM17_IRQHandler + .thumb_set TIM17_IRQHandler,Default_Handler + + .weak USB_DRD_FS_IRQHandler + .thumb_set USB_DRD_FS_IRQHandler,Default_Handler + + .weak CRS_IRQHandler + .thumb_set CRS_IRQHandler,Default_Handler + + .weak UCPD1_IRQHandler + .thumb_set UCPD1_IRQHandler,Default_Handler + + .weak FMC_IRQHandler + .thumb_set FMC_IRQHandler,Default_Handler + + .weak OCTOSPI1_IRQHandler + .thumb_set OCTOSPI1_IRQHandler,Default_Handler + + .weak SDMMC1_IRQHandler + .thumb_set SDMMC1_IRQHandler,Default_Handler + + .weak I2C3_EV_IRQHandler + .thumb_set I2C3_EV_IRQHandler,Default_Handler + + .weak I2C3_ER_IRQHandler + .thumb_set I2C3_ER_IRQHandler,Default_Handler + + .weak SPI4_IRQHandler + .thumb_set SPI4_IRQHandler,Default_Handler + + .weak SPI5_IRQHandler + .thumb_set SPI5_IRQHandler,Default_Handler + + .weak SPI6_IRQHandler + .thumb_set SPI6_IRQHandler,Default_Handler + + .weak USART6_IRQHandler + .thumb_set USART6_IRQHandler,Default_Handler + + .weak USART10_IRQHandler + .thumb_set USART10_IRQHandler,Default_Handler + + .weak USART11_IRQHandler + .thumb_set USART11_IRQHandler,Default_Handler + + .weak SAI1_IRQHandler + .thumb_set SAI1_IRQHandler,Default_Handler + + .weak SAI2_IRQHandler + .thumb_set SAI2_IRQHandler,Default_Handler + + .weak GPDMA2_Channel0_IRQHandler + .thumb_set GPDMA2_Channel0_IRQHandler,Default_Handler + + .weak GPDMA2_Channel1_IRQHandler + .thumb_set GPDMA2_Channel1_IRQHandler,Default_Handler + + .weak GPDMA2_Channel2_IRQHandler + .thumb_set GPDMA2_Channel2_IRQHandler,Default_Handler + + .weak GPDMA2_Channel3_IRQHandler + .thumb_set GPDMA2_Channel3_IRQHandler,Default_Handler + + .weak GPDMA2_Channel4_IRQHandler + .thumb_set GPDMA2_Channel4_IRQHandler,Default_Handler + + .weak GPDMA2_Channel5_IRQHandler + .thumb_set GPDMA2_Channel5_IRQHandler,Default_Handler + + .weak GPDMA2_Channel6_IRQHandler + .thumb_set GPDMA2_Channel6_IRQHandler,Default_Handler + + .weak GPDMA2_Channel7_IRQHandler + .thumb_set GPDMA2_Channel7_IRQHandler,Default_Handler + + .weak UART7_IRQHandler + .thumb_set UART7_IRQHandler,Default_Handler + + .weak UART8_IRQHandler + .thumb_set UART8_IRQHandler,Default_Handler + + .weak UART9_IRQHandler + .thumb_set UART9_IRQHandler,Default_Handler + + .weak UART12_IRQHandler + .thumb_set UART12_IRQHandler,Default_Handler + + .weak FPU_IRQHandler + .thumb_set FPU_IRQHandler,Default_Handler + + .weak ICACHE_IRQHandler + .thumb_set ICACHE_IRQHandler,Default_Handler + + .weak DCACHE1_IRQHandler + .thumb_set DCACHE1_IRQHandler,Default_Handler + + .weak DCMI_PSSI_IRQHandler + .thumb_set DCMI_PSSI_IRQHandler,Default_Handler + + .weak CORDIC_IRQHandler + .thumb_set CORDIC_IRQHandler,Default_Handler + + .weak FMAC_IRQHandler + .thumb_set FMAC_IRQHandler,Default_Handler + + .weak DTS_IRQHandler + .thumb_set DTS_IRQHandler,Default_Handler + + .weak RNG_IRQHandler + .thumb_set RNG_IRQHandler,Default_Handler + + .weak HASH_IRQHandler + .thumb_set HASH_IRQHandler,Default_Handler + + .weak CEC_IRQHandler + .thumb_set CEC_IRQHandler,Default_Handler + + .weak TIM12_IRQHandler + .thumb_set TIM12_IRQHandler,Default_Handler + + .weak TIM13_IRQHandler + .thumb_set TIM13_IRQHandler,Default_Handler + + .weak TIM14_IRQHandler + .thumb_set TIM14_IRQHandler,Default_Handler + + .weak I3C1_EV_IRQHandler + .thumb_set I3C1_EV_IRQHandler,Default_Handler + + .weak I3C1_ER_IRQHandler + .thumb_set I3C1_ER_IRQHandler,Default_Handler + + .weak I2C4_EV_IRQHandler + .thumb_set I2C4_EV_IRQHandler,Default_Handler + + .weak I2C4_ER_IRQHandler + .thumb_set I2C4_ER_IRQHandler,Default_Handler + + .weak LPTIM3_IRQHandler + .thumb_set LPTIM3_IRQHandler,Default_Handler + + .weak LPTIM4_IRQHandler + .thumb_set LPTIM4_IRQHandler,Default_Handler + + .weak LPTIM5_IRQHandler + .thumb_set LPTIM5_IRQHandler,Default_Handler + + .weak LPTIM6_IRQHandler + .thumb_set LPTIM6_IRQHandler,Default_Handler \ No newline at end of file diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/gcc/startup_stm32h563xx.s b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/gcc/startup_stm32h563xx.s new file mode 100644 index 0000000000..02da8187ff --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/gcc/startup_stm32h563xx.s @@ -0,0 +1,696 @@ +/** + ****************************************************************************** + * @file startup_stm32h563xx.s + * @author MCD Application Team + * @brief STM32H563xx devices vector table GCC toolchain. + * This module performs: + * - Set the initial SP + * - Set the initial PC == Reset_Handler, + * - Set the vector table entries with the exceptions ISR address, + * - Configure the clock system + * - Branches to main in the C library (which eventually + * calls main()). + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + + .syntax unified + .cpu cortex-m33 + .fpu softvfp + .thumb + +.global g_pfnVectors +.global Default_Handler + +/* start address for the initialization values of the .data section. +defined in linker script */ +.word _sidata +/* start address for the .data section. defined in linker script */ +.word _sdata +/* end address for the .data section. defined in linker script */ +.word _edata +/* start address for the .bss section. defined in linker script */ +.word _sbss +/* end address for the .bss section. defined in linker script */ +.word _ebss + +/** + * @brief This is the code that gets called when the processor first + * starts execution following a reset event. Only the absolutely + * necessary set is performed, after which the application + * supplied main() routine is called. + * @param None + * @retval : None + */ + + .section .text.Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + ldr r0, =_estack + mov sp, r0 /* set stack pointer */ +/* Call the clock system initialization function.*/ + bl SystemInit + +/* Copy the data segment initializers from flash to SRAM */ + ldr r0, =_sdata + ldr r1, =_edata + ldr r2, =_sidata + movs r3, #0 + b LoopCopyDataInit + +CopyDataInit: + ldr r4, [r2, r3] + str r4, [r0, r3] + adds r3, r3, #4 + +LoopCopyDataInit: + adds r4, r0, r3 + cmp r4, r1 + bcc CopyDataInit + +/* Zero fill the bss segment. */ + ldr r2, =_sbss + ldr r4, =_ebss + movs r3, #0 + b LoopFillZerobss + +FillZerobss: + str r3, [r2] + adds r2, r2, #4 + +LoopFillZerobss: + cmp r2, r4 + bcc FillZerobss + +/* Call static constructors */ + bl __libc_init_array +/* Call the application's entry point.*/ + bl main + +LoopForever: + b LoopForever + + .size Reset_Handler, .-Reset_Handler + +/** + * @brief This is the code that gets called when the processor receives an + * unexpected interrupt. This simply enters an infinite loop, preserving + * the system state for examination by a debugger. + * + * @param None + * @retval : None +*/ + .section .text.Default_Handler,"ax",%progbits +Default_Handler: +Infinite_Loop: + b Infinite_Loop + .size Default_Handler, .-Default_Handler + +/****************************************************************************** +* +* The STM32H563xx vector table. Note that the proper constructs +* must be placed on this to ensure that it ends up at physical address +* 0x0000.0000. +* +******************************************************************************/ + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + .size g_pfnVectors, .-g_pfnVectors + +g_pfnVectors: + .word _estack + .word Reset_Handler + .word NMI_Handler + .word HardFault_Handler + .word MemManage_Handler + .word BusFault_Handler + .word UsageFault_Handler + .word SecureFault_Handler + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word DebugMon_Handler + .word 0 + .word PendSV_Handler + .word SysTick_Handler + .word WWDG_IRQHandler + .word PVD_AVD_IRQHandler + .word RTC_IRQHandler + .word RTC_S_IRQHandler + .word TAMP_IRQHandler + .word RAMCFG_IRQHandler + .word FLASH_IRQHandler + .word FLASH_S_IRQHandler + .word GTZC_IRQHandler + .word RCC_IRQHandler + .word RCC_S_IRQHandler + .word EXTI0_IRQHandler + .word EXTI1_IRQHandler + .word EXTI2_IRQHandler + .word EXTI3_IRQHandler + .word EXTI4_IRQHandler + .word EXTI5_IRQHandler + .word EXTI6_IRQHandler + .word EXTI7_IRQHandler + .word EXTI8_IRQHandler + .word EXTI9_IRQHandler + .word EXTI10_IRQHandler + .word EXTI11_IRQHandler + .word EXTI12_IRQHandler + .word EXTI13_IRQHandler + .word EXTI14_IRQHandler + .word EXTI15_IRQHandler + .word GPDMA1_Channel0_IRQHandler + .word GPDMA1_Channel1_IRQHandler + .word GPDMA1_Channel2_IRQHandler + .word GPDMA1_Channel3_IRQHandler + .word GPDMA1_Channel4_IRQHandler + .word GPDMA1_Channel5_IRQHandler + .word GPDMA1_Channel6_IRQHandler + .word GPDMA1_Channel7_IRQHandler + .word IWDG_IRQHandler + .word 0 + .word ADC1_IRQHandler + .word DAC1_IRQHandler + .word FDCAN1_IT0_IRQHandler + .word FDCAN1_IT1_IRQHandler + .word TIM1_BRK_IRQHandler + .word TIM1_UP_IRQHandler + .word TIM1_TRG_COM_IRQHandler + .word TIM1_CC_IRQHandler + .word TIM2_IRQHandler + .word TIM3_IRQHandler + .word TIM4_IRQHandler + .word TIM5_IRQHandler + .word TIM6_IRQHandler + .word TIM7_IRQHandler + .word I2C1_EV_IRQHandler + .word I2C1_ER_IRQHandler + .word I2C2_EV_IRQHandler + .word I2C2_ER_IRQHandler + .word SPI1_IRQHandler + .word SPI2_IRQHandler + .word SPI3_IRQHandler + .word USART1_IRQHandler + .word USART2_IRQHandler + .word USART3_IRQHandler + .word UART4_IRQHandler + .word UART5_IRQHandler + .word LPUART1_IRQHandler + .word LPTIM1_IRQHandler + .word TIM8_BRK_IRQHandler + .word TIM8_UP_IRQHandler + .word TIM8_TRG_COM_IRQHandler + .word TIM8_CC_IRQHandler + .word ADC2_IRQHandler + .word LPTIM2_IRQHandler + .word TIM15_IRQHandler + .word TIM16_IRQHandler + .word TIM17_IRQHandler + .word USB_DRD_FS_IRQHandler + .word CRS_IRQHandler + .word UCPD1_IRQHandler + .word FMC_IRQHandler + .word OCTOSPI1_IRQHandler + .word SDMMC1_IRQHandler + .word I2C3_EV_IRQHandler + .word I2C3_ER_IRQHandler + .word SPI4_IRQHandler + .word SPI5_IRQHandler + .word SPI6_IRQHandler + .word USART6_IRQHandler + .word USART10_IRQHandler + .word USART11_IRQHandler + .word SAI1_IRQHandler + .word SAI2_IRQHandler + .word GPDMA2_Channel0_IRQHandler + .word GPDMA2_Channel1_IRQHandler + .word GPDMA2_Channel2_IRQHandler + .word GPDMA2_Channel3_IRQHandler + .word GPDMA2_Channel4_IRQHandler + .word GPDMA2_Channel5_IRQHandler + .word GPDMA2_Channel6_IRQHandler + .word GPDMA2_Channel7_IRQHandler + .word UART7_IRQHandler + .word UART8_IRQHandler + .word UART9_IRQHandler + .word UART12_IRQHandler + .word SDMMC2_IRQHandler + .word FPU_IRQHandler + .word ICACHE_IRQHandler + .word DCACHE1_IRQHandler + .word ETH_IRQHandler + .word ETH_WKUP_IRQHandler + .word DCMI_PSSI_IRQHandler + .word FDCAN2_IT0_IRQHandler + .word FDCAN2_IT1_IRQHandler + .word CORDIC_IRQHandler + .word FMAC_IRQHandler + .word DTS_IRQHandler + .word RNG_IRQHandler + .word 0 + .word 0 + .word HASH_IRQHandler + .word 0 + .word CEC_IRQHandler + .word TIM12_IRQHandler + .word TIM13_IRQHandler + .word TIM14_IRQHandler + .word I3C1_EV_IRQHandler + .word I3C1_ER_IRQHandler + .word I2C4_EV_IRQHandler + .word I2C4_ER_IRQHandler + .word LPTIM3_IRQHandler + .word LPTIM4_IRQHandler + .word LPTIM5_IRQHandler + .word LPTIM6_IRQHandler + +/******************************************************************************* +* +* Provide weak aliases for each Exception handler to the Default_Handler. +* As they are weak aliases, any function with the same name will override +* this definition. +* +*******************************************************************************/ + + .weak NMI_Handler + .thumb_set NMI_Handler,Default_Handler + + .weak HardFault_Handler + .thumb_set HardFault_Handler,Default_Handler + + .weak MemManage_Handler + .thumb_set MemManage_Handler,Default_Handler + + .weak BusFault_Handler + .thumb_set BusFault_Handler,Default_Handler + + .weak UsageFault_Handler + .thumb_set UsageFault_Handler,Default_Handler + + .weak SecureFault_Handler + .thumb_set SecureFault_Handler,Default_Handler + + .weak SVC_Handler + .thumb_set SVC_Handler,Default_Handler + + .weak DebugMon_Handler + .thumb_set DebugMon_Handler,Default_Handler + + .weak PendSV_Handler + .thumb_set PendSV_Handler,Default_Handler + + .weak SysTick_Handler + .thumb_set SysTick_Handler,Default_Handler + + .weak WWDG_IRQHandler + .thumb_set WWDG_IRQHandler,Default_Handler + + .weak PVD_AVD_IRQHandler + .thumb_set PVD_AVD_IRQHandler,Default_Handler + + .weak RTC_IRQHandler + .thumb_set RTC_IRQHandler,Default_Handler + + .weak RTC_S_IRQHandler + .thumb_set RTC_S_IRQHandler,Default_Handler + + .weak TAMP_IRQHandler + .thumb_set TAMP_IRQHandler,Default_Handler + + .weak RAMCFG_IRQHandler + .thumb_set RAMCFG_IRQHandler,Default_Handler + + .weak FLASH_IRQHandler + .thumb_set FLASH_IRQHandler,Default_Handler + + .weak FLASH_S_IRQHandler + .thumb_set FLASH_S_IRQHandler,Default_Handler + + .weak GTZC_IRQHandler + .thumb_set GTZC_IRQHandler,Default_Handler + + .weak RCC_IRQHandler + .thumb_set RCC_IRQHandler,Default_Handler + + .weak RCC_S_IRQHandler + .thumb_set RCC_S_IRQHandler,Default_Handler + + .weak EXTI0_IRQHandler + .thumb_set EXTI0_IRQHandler,Default_Handler + + .weak EXTI1_IRQHandler + .thumb_set EXTI1_IRQHandler,Default_Handler + + .weak EXTI2_IRQHandler + .thumb_set EXTI2_IRQHandler,Default_Handler + + .weak EXTI3_IRQHandler + .thumb_set EXTI3_IRQHandler,Default_Handler + + .weak EXTI4_IRQHandler + .thumb_set EXTI4_IRQHandler,Default_Handler + + .weak EXTI5_IRQHandler + .thumb_set EXTI5_IRQHandler,Default_Handler + + .weak EXTI6_IRQHandler + .thumb_set EXTI6_IRQHandler,Default_Handler + + .weak EXTI7_IRQHandler + .thumb_set EXTI7_IRQHandler,Default_Handler + + .weak EXTI8_IRQHandler + .thumb_set EXTI8_IRQHandler,Default_Handler + + .weak EXTI9_IRQHandler + .thumb_set EXTI9_IRQHandler,Default_Handler + + .weak EXTI10_IRQHandler + .thumb_set EXTI10_IRQHandler,Default_Handler + + .weak EXTI11_IRQHandler + .thumb_set EXTI11_IRQHandler,Default_Handler + + .weak EXTI12_IRQHandler + .thumb_set EXTI12_IRQHandler,Default_Handler + + .weak EXTI13_IRQHandler + .thumb_set EXTI13_IRQHandler,Default_Handler + + .weak EXTI14_IRQHandler + .thumb_set EXTI14_IRQHandler,Default_Handler + + .weak EXTI15_IRQHandler + .thumb_set EXTI15_IRQHandler,Default_Handler + + .weak GPDMA1_Channel0_IRQHandler + .thumb_set GPDMA1_Channel0_IRQHandler,Default_Handler + + .weak GPDMA1_Channel1_IRQHandler + .thumb_set GPDMA1_Channel1_IRQHandler,Default_Handler + + .weak GPDMA1_Channel2_IRQHandler + .thumb_set GPDMA1_Channel2_IRQHandler,Default_Handler + + .weak GPDMA1_Channel3_IRQHandler + .thumb_set GPDMA1_Channel3_IRQHandler,Default_Handler + + .weak GPDMA1_Channel4_IRQHandler + .thumb_set GPDMA1_Channel4_IRQHandler,Default_Handler + + .weak GPDMA1_Channel5_IRQHandler + .thumb_set GPDMA1_Channel5_IRQHandler,Default_Handler + + .weak GPDMA1_Channel6_IRQHandler + .thumb_set GPDMA1_Channel6_IRQHandler,Default_Handler + + .weak GPDMA1_Channel7_IRQHandler + .thumb_set GPDMA1_Channel7_IRQHandler,Default_Handler + + .weak IWDG_IRQHandler + .thumb_set IWDG_IRQHandler,Default_Handler + + .weak ADC1_IRQHandler + .thumb_set ADC1_IRQHandler,Default_Handler + + .weak DAC1_IRQHandler + .thumb_set DAC1_IRQHandler,Default_Handler + + .weak FDCAN1_IT0_IRQHandler + .thumb_set FDCAN1_IT0_IRQHandler,Default_Handler + + .weak FDCAN1_IT1_IRQHandler + .thumb_set FDCAN1_IT1_IRQHandler,Default_Handler + + .weak TIM1_BRK_IRQHandler + .thumb_set TIM1_BRK_IRQHandler,Default_Handler + + .weak TIM1_UP_IRQHandler + .thumb_set TIM1_UP_IRQHandler,Default_Handler + + .weak TIM1_TRG_COM_IRQHandler + .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler + + .weak TIM1_CC_IRQHandler + .thumb_set TIM1_CC_IRQHandler,Default_Handler + + .weak TIM2_IRQHandler + .thumb_set TIM2_IRQHandler,Default_Handler + + .weak TIM3_IRQHandler + .thumb_set TIM3_IRQHandler,Default_Handler + + .weak TIM4_IRQHandler + .thumb_set TIM4_IRQHandler,Default_Handler + + .weak TIM5_IRQHandler + .thumb_set TIM5_IRQHandler,Default_Handler + + .weak TIM6_IRQHandler + .thumb_set TIM6_IRQHandler,Default_Handler + + .weak TIM7_IRQHandler + .thumb_set TIM7_IRQHandler,Default_Handler + + .weak I2C1_EV_IRQHandler + .thumb_set I2C1_EV_IRQHandler,Default_Handler + + .weak I2C1_ER_IRQHandler + .thumb_set I2C1_ER_IRQHandler,Default_Handler + + .weak I2C2_EV_IRQHandler + .thumb_set I2C2_EV_IRQHandler,Default_Handler + + .weak I2C2_ER_IRQHandler + .thumb_set I2C2_ER_IRQHandler,Default_Handler + + .weak SPI1_IRQHandler + .thumb_set SPI1_IRQHandler,Default_Handler + + .weak SPI2_IRQHandler + .thumb_set SPI2_IRQHandler,Default_Handler + + .weak SPI3_IRQHandler + .thumb_set SPI3_IRQHandler,Default_Handler + + .weak USART1_IRQHandler + .thumb_set USART1_IRQHandler,Default_Handler + + .weak USART2_IRQHandler + .thumb_set USART2_IRQHandler,Default_Handler + + .weak USART3_IRQHandler + .thumb_set USART3_IRQHandler,Default_Handler + + .weak UART4_IRQHandler + .thumb_set UART4_IRQHandler,Default_Handler + + .weak UART5_IRQHandler + .thumb_set UART5_IRQHandler,Default_Handler + + .weak LPUART1_IRQHandler + .thumb_set LPUART1_IRQHandler,Default_Handler + + .weak LPTIM1_IRQHandler + .thumb_set LPTIM1_IRQHandler,Default_Handler + + .weak TIM8_BRK_IRQHandler + .thumb_set TIM8_BRK_IRQHandler,Default_Handler + + .weak TIM8_UP_IRQHandler + .thumb_set TIM8_UP_IRQHandler,Default_Handler + + .weak TIM8_TRG_COM_IRQHandler + .thumb_set TIM8_TRG_COM_IRQHandler,Default_Handler + + .weak TIM8_CC_IRQHandler + .thumb_set TIM8_CC_IRQHandler,Default_Handler + + .weak ADC2_IRQHandler + .thumb_set ADC2_IRQHandler,Default_Handler + + .weak LPTIM2_IRQHandler + .thumb_set LPTIM2_IRQHandler,Default_Handler + + .weak TIM15_IRQHandler + .thumb_set TIM15_IRQHandler,Default_Handler + + .weak TIM16_IRQHandler + .thumb_set TIM16_IRQHandler,Default_Handler + + .weak TIM17_IRQHandler + .thumb_set TIM17_IRQHandler,Default_Handler + + .weak USB_DRD_FS_IRQHandler + .thumb_set USB_DRD_FS_IRQHandler,Default_Handler + + .weak CRS_IRQHandler + .thumb_set CRS_IRQHandler,Default_Handler + + .weak UCPD1_IRQHandler + .thumb_set UCPD1_IRQHandler,Default_Handler + + .weak FMC_IRQHandler + .thumb_set FMC_IRQHandler,Default_Handler + + .weak OCTOSPI1_IRQHandler + .thumb_set OCTOSPI1_IRQHandler,Default_Handler + + .weak SDMMC1_IRQHandler + .thumb_set SDMMC1_IRQHandler,Default_Handler + + .weak I2C3_EV_IRQHandler + .thumb_set I2C3_EV_IRQHandler,Default_Handler + + .weak I2C3_ER_IRQHandler + .thumb_set I2C3_ER_IRQHandler,Default_Handler + + .weak SPI4_IRQHandler + .thumb_set SPI4_IRQHandler,Default_Handler + + .weak SPI5_IRQHandler + .thumb_set SPI5_IRQHandler,Default_Handler + + .weak SPI6_IRQHandler + .thumb_set SPI6_IRQHandler,Default_Handler + + .weak USART6_IRQHandler + .thumb_set USART6_IRQHandler,Default_Handler + + .weak USART10_IRQHandler + .thumb_set USART10_IRQHandler,Default_Handler + + .weak USART11_IRQHandler + .thumb_set USART11_IRQHandler,Default_Handler + + .weak SAI1_IRQHandler + .thumb_set SAI1_IRQHandler,Default_Handler + + .weak SAI2_IRQHandler + .thumb_set SAI2_IRQHandler,Default_Handler + + .weak GPDMA2_Channel0_IRQHandler + .thumb_set GPDMA2_Channel0_IRQHandler,Default_Handler + + .weak GPDMA2_Channel1_IRQHandler + .thumb_set GPDMA2_Channel1_IRQHandler,Default_Handler + + .weak GPDMA2_Channel2_IRQHandler + .thumb_set GPDMA2_Channel2_IRQHandler,Default_Handler + + .weak GPDMA2_Channel3_IRQHandler + .thumb_set GPDMA2_Channel3_IRQHandler,Default_Handler + + .weak GPDMA2_Channel4_IRQHandler + .thumb_set GPDMA2_Channel4_IRQHandler,Default_Handler + + .weak GPDMA2_Channel5_IRQHandler + .thumb_set GPDMA2_Channel5_IRQHandler,Default_Handler + + .weak GPDMA2_Channel6_IRQHandler + .thumb_set GPDMA2_Channel6_IRQHandler,Default_Handler + + .weak GPDMA2_Channel7_IRQHandler + .thumb_set GPDMA2_Channel7_IRQHandler,Default_Handler + + .weak UART7_IRQHandler + .thumb_set UART7_IRQHandler,Default_Handler + + .weak UART8_IRQHandler + .thumb_set UART8_IRQHandler,Default_Handler + + .weak UART9_IRQHandler + .thumb_set UART9_IRQHandler,Default_Handler + + .weak UART12_IRQHandler + .thumb_set UART12_IRQHandler,Default_Handler + + .weak SDMMC2_IRQHandler + .thumb_set SDMMC2_IRQHandler,Default_Handler + + .weak FPU_IRQHandler + .thumb_set FPU_IRQHandler,Default_Handler + + .weak ICACHE_IRQHandler + .thumb_set ICACHE_IRQHandler,Default_Handler + + .weak DCACHE1_IRQHandler + .thumb_set DCACHE1_IRQHandler,Default_Handler + + .weak ETH_IRQHandler + .thumb_set ETH_IRQHandler,Default_Handler + + .weak ETH_WKUP_IRQHandler + .thumb_set ETH_WKUP_IRQHandler,Default_Handler + + .weak DCMI_PSSI_IRQHandler + .thumb_set DCMI_PSSI_IRQHandler,Default_Handler + + .weak FDCAN2_IT0_IRQHandler + .thumb_set FDCAN2_IT0_IRQHandler,Default_Handler + + .weak FDCAN2_IT1_IRQHandler + .thumb_set FDCAN2_IT1_IRQHandler,Default_Handler + + .weak CORDIC_IRQHandler + .thumb_set CORDIC_IRQHandler,Default_Handler + + .weak FMAC_IRQHandler + .thumb_set FMAC_IRQHandler,Default_Handler + + .weak DTS_IRQHandler + .thumb_set DTS_IRQHandler,Default_Handler + + .weak RNG_IRQHandler + .thumb_set RNG_IRQHandler,Default_Handler + + .weak HASH_IRQHandler + .thumb_set HASH_IRQHandler,Default_Handler + + .weak CEC_IRQHandler + .thumb_set CEC_IRQHandler,Default_Handler + + .weak TIM12_IRQHandler + .thumb_set TIM12_IRQHandler,Default_Handler + + .weak TIM13_IRQHandler + .thumb_set TIM13_IRQHandler,Default_Handler + + .weak TIM14_IRQHandler + .thumb_set TIM14_IRQHandler,Default_Handler + + .weak I3C1_EV_IRQHandler + .thumb_set I3C1_EV_IRQHandler,Default_Handler + + .weak I3C1_ER_IRQHandler + .thumb_set I3C1_ER_IRQHandler,Default_Handler + + .weak I2C4_EV_IRQHandler + .thumb_set I2C4_EV_IRQHandler,Default_Handler + + .weak I2C4_ER_IRQHandler + .thumb_set I2C4_ER_IRQHandler,Default_Handler + + .weak LPTIM3_IRQHandler + .thumb_set LPTIM3_IRQHandler,Default_Handler + + .weak LPTIM4_IRQHandler + .thumb_set LPTIM4_IRQHandler,Default_Handler + + .weak LPTIM5_IRQHandler + .thumb_set LPTIM5_IRQHandler,Default_Handler + + .weak LPTIM6_IRQHandler + .thumb_set LPTIM6_IRQHandler,Default_Handler \ No newline at end of file diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/gcc/startup_stm32h573xx.s b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/gcc/startup_stm32h573xx.s new file mode 100644 index 0000000000..05adc1384a --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/gcc/startup_stm32h573xx.s @@ -0,0 +1,712 @@ +/** + ****************************************************************************** + * @file startup_stm32h573xx.s + * @author MCD Application Team + * @brief STM32H573xx devices vector table GCC toolchain. + * This module performs: + * - Set the initial SP + * - Set the initial PC == Reset_Handler, + * - Set the vector table entries with the exceptions ISR address, + * - Configure the clock system + * - Branches to main in the C library (which eventually + * calls main()). + * After Reset the Cortex-M33 processor is in Thread mode, + * priority is Privileged, and the Stack is set to Main. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + + .syntax unified + .cpu cortex-m33 + .fpu softvfp + .thumb + +.global g_pfnVectors +.global Default_Handler + +/* start address for the initialization values of the .data section. +defined in linker script */ +.word _sidata +/* start address for the .data section. defined in linker script */ +.word _sdata +/* end address for the .data section. defined in linker script */ +.word _edata +/* start address for the .bss section. defined in linker script */ +.word _sbss +/* end address for the .bss section. defined in linker script */ +.word _ebss + +.equ BootRAM, 0xF1E0F85F +/** + * @brief This is the code that gets called when the processor first + * starts execution following a reset event. Only the absolutely + * necessary set is performed, after which the application + * supplied main() routine is called. + * @param None + * @retval : None + */ + + .section .text.Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + ldr r0, =_estack + mov sp, r0 /* set stack pointer */ +/* Call the clock system initialization function.*/ + bl SystemInit + +/* Copy the data segment initializers from flash to SRAM */ + ldr r0, =_sdata + ldr r1, =_edata + ldr r2, =_sidata + movs r3, #0 + b LoopCopyDataInit + +CopyDataInit: + ldr r4, [r2, r3] + str r4, [r0, r3] + adds r3, r3, #4 + +LoopCopyDataInit: + adds r4, r0, r3 + cmp r4, r1 + bcc CopyDataInit + +/* Zero fill the bss segment. */ + ldr r2, =_sbss + ldr r4, =_ebss + movs r3, #0 + b LoopFillZerobss + +FillZerobss: + str r3, [r2] + adds r2, r2, #4 + +LoopFillZerobss: + cmp r2, r4 + bcc FillZerobss + +/* Call static constructors */ + bl __libc_init_array +/* Call the application's entry point.*/ + bl main + +LoopForever: + b LoopForever + + .size Reset_Handler, .-Reset_Handler + +/** + * @brief This is the code that gets called when the processor receives an + * unexpected interrupt. This simply enters an infinite loop, preserving + * the system state for examination by a debugger. + * + * @param None + * @retval : None +*/ + .section .text.Default_Handler,"ax",%progbits +Default_Handler: +Infinite_Loop: + b Infinite_Loop + .size Default_Handler, .-Default_Handler + +/****************************************************************************** +* +* The STM32H573xx vector table. Note that the proper constructs +* must be placed on this to ensure that it ends up at physical address +* 0x0000.0000. +* +******************************************************************************/ + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + .size g_pfnVectors, .-g_pfnVectors + + +g_pfnVectors: + .word _estack + .word Reset_Handler + .word NMI_Handler + .word HardFault_Handler + .word MemManage_Handler + .word BusFault_Handler + .word UsageFault_Handler + .word SecureFault_Handler + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word DebugMon_Handler + .word 0 + .word PendSV_Handler + .word SysTick_Handler + .word WWDG_IRQHandler + .word PVD_AVD_IRQHandler + .word RTC_IRQHandler + .word RTC_S_IRQHandler + .word TAMP_IRQHandler + .word RAMCFG_IRQHandler + .word FLASH_IRQHandler + .word FLASH_S_IRQHandler + .word GTZC_IRQHandler + .word RCC_IRQHandler + .word RCC_S_IRQHandler + .word EXTI0_IRQHandler + .word EXTI1_IRQHandler + .word EXTI2_IRQHandler + .word EXTI3_IRQHandler + .word EXTI4_IRQHandler + .word EXTI5_IRQHandler + .word EXTI6_IRQHandler + .word EXTI7_IRQHandler + .word EXTI8_IRQHandler + .word EXTI9_IRQHandler + .word EXTI10_IRQHandler + .word EXTI11_IRQHandler + .word EXTI12_IRQHandler + .word EXTI13_IRQHandler + .word EXTI14_IRQHandler + .word EXTI15_IRQHandler + .word GPDMA1_Channel0_IRQHandler + .word GPDMA1_Channel1_IRQHandler + .word GPDMA1_Channel2_IRQHandler + .word GPDMA1_Channel3_IRQHandler + .word GPDMA1_Channel4_IRQHandler + .word GPDMA1_Channel5_IRQHandler + .word GPDMA1_Channel6_IRQHandler + .word GPDMA1_Channel7_IRQHandler + .word IWDG_IRQHandler + .word SAES_IRQHandler + .word ADC1_IRQHandler + .word DAC1_IRQHandler + .word FDCAN1_IT0_IRQHandler + .word FDCAN1_IT1_IRQHandler + .word TIM1_BRK_IRQHandler + .word TIM1_UP_IRQHandler + .word TIM1_TRG_COM_IRQHandler + .word TIM1_CC_IRQHandler + .word TIM2_IRQHandler + .word TIM3_IRQHandler + .word TIM4_IRQHandler + .word TIM5_IRQHandler + .word TIM6_IRQHandler + .word TIM7_IRQHandler + .word I2C1_EV_IRQHandler + .word I2C1_ER_IRQHandler + .word I2C2_EV_IRQHandler + .word I2C2_ER_IRQHandler + .word SPI1_IRQHandler + .word SPI2_IRQHandler + .word SPI3_IRQHandler + .word USART1_IRQHandler + .word USART2_IRQHandler + .word USART3_IRQHandler + .word UART4_IRQHandler + .word UART5_IRQHandler + .word LPUART1_IRQHandler + .word LPTIM1_IRQHandler + .word TIM8_BRK_IRQHandler + .word TIM8_UP_IRQHandler + .word TIM8_TRG_COM_IRQHandler + .word TIM8_CC_IRQHandler + .word ADC2_IRQHandler + .word LPTIM2_IRQHandler + .word TIM15_IRQHandler + .word TIM16_IRQHandler + .word TIM17_IRQHandler + .word USB_DRD_FS_IRQHandler + .word CRS_IRQHandler + .word UCPD1_IRQHandler + .word FMC_IRQHandler + .word OCTOSPI1_IRQHandler + .word SDMMC1_IRQHandler + .word I2C3_EV_IRQHandler + .word I2C3_ER_IRQHandler + .word SPI4_IRQHandler + .word SPI5_IRQHandler + .word SPI6_IRQHandler + .word USART6_IRQHandler + .word USART10_IRQHandler + .word USART11_IRQHandler + .word SAI1_IRQHandler + .word SAI2_IRQHandler + .word GPDMA2_Channel0_IRQHandler + .word GPDMA2_Channel1_IRQHandler + .word GPDMA2_Channel2_IRQHandler + .word GPDMA2_Channel3_IRQHandler + .word GPDMA2_Channel4_IRQHandler + .word GPDMA2_Channel5_IRQHandler + .word GPDMA2_Channel6_IRQHandler + .word GPDMA2_Channel7_IRQHandler + .word UART7_IRQHandler + .word UART8_IRQHandler + .word UART9_IRQHandler + .word UART12_IRQHandler + .word SDMMC2_IRQHandler + .word FPU_IRQHandler + .word ICACHE_IRQHandler + .word DCACHE1_IRQHandler + .word ETH_IRQHandler + .word ETH_WKUP_IRQHandler + .word DCMI_PSSI_IRQHandler + .word FDCAN2_IT0_IRQHandler + .word FDCAN2_IT1_IRQHandler + .word CORDIC_IRQHandler + .word FMAC_IRQHandler + .word DTS_IRQHandler + .word RNG_IRQHandler + .word OTFDEC1_IRQHandler + .word AES_IRQHandler + .word HASH_IRQHandler + .word PKA_IRQHandler + .word CEC_IRQHandler + .word TIM12_IRQHandler + .word TIM13_IRQHandler + .word TIM14_IRQHandler + .word I3C1_EV_IRQHandler + .word I3C1_ER_IRQHandler + .word I2C4_EV_IRQHandler + .word I2C4_ER_IRQHandler + .word LPTIM3_IRQHandler + .word LPTIM4_IRQHandler + .word LPTIM5_IRQHandler + .word LPTIM6_IRQHandler + +/******************************************************************************* +* +* Provide weak aliases for each Exception handler to the Default_Handler. +* As they are weak aliases, any function with the same name will override +* this definition. +* +*******************************************************************************/ + + .weak NMI_Handler + .thumb_set NMI_Handler,Default_Handler + + .weak HardFault_Handler + .thumb_set HardFault_Handler,Default_Handler + + .weak MemManage_Handler + .thumb_set MemManage_Handler,Default_Handler + + .weak BusFault_Handler + .thumb_set BusFault_Handler,Default_Handler + + .weak UsageFault_Handler + .thumb_set UsageFault_Handler,Default_Handler + + .weak SecureFault_Handler + .thumb_set SecureFault_Handler,Default_Handler + + .weak SVC_Handler + .thumb_set SVC_Handler,Default_Handler + + .weak DebugMon_Handler + .thumb_set DebugMon_Handler,Default_Handler + + .weak PendSV_Handler + .thumb_set PendSV_Handler,Default_Handler + + .weak SysTick_Handler + .thumb_set SysTick_Handler,Default_Handler + + .weak WWDG_IRQHandler + .thumb_set WWDG_IRQHandler,Default_Handler + + .weak PVD_AVD_IRQHandler + .thumb_set PVD_AVD_IRQHandler,Default_Handler + + .weak RTC_IRQHandler + .thumb_set RTC_IRQHandler,Default_Handler + + .weak RTC_S_IRQHandler + .thumb_set RTC_S_IRQHandler,Default_Handler + + .weak TAMP_IRQHandler + .thumb_set TAMP_IRQHandler,Default_Handler + + .weak RAMCFG_IRQHandler + .thumb_set RAMCFG_IRQHandler,Default_Handler + + .weak FLASH_IRQHandler + .thumb_set FLASH_IRQHandler,Default_Handler + + .weak FLASH_S_IRQHandler + .thumb_set FLASH_S_IRQHandler,Default_Handler + + .weak GTZC_IRQHandler + .thumb_set GTZC_IRQHandler,Default_Handler + + .weak RCC_IRQHandler + .thumb_set RCC_IRQHandler,Default_Handler + + .weak RCC_S_IRQHandler + .thumb_set RCC_S_IRQHandler,Default_Handler + + .weak EXTI0_IRQHandler + .thumb_set EXTI0_IRQHandler,Default_Handler + + .weak EXTI1_IRQHandler + .thumb_set EXTI1_IRQHandler,Default_Handler + + .weak EXTI2_IRQHandler + .thumb_set EXTI2_IRQHandler,Default_Handler + + .weak EXTI3_IRQHandler + .thumb_set EXTI3_IRQHandler,Default_Handler + + .weak EXTI4_IRQHandler + .thumb_set EXTI4_IRQHandler,Default_Handler + + .weak EXTI5_IRQHandler + .thumb_set EXTI5_IRQHandler,Default_Handler + + .weak EXTI6_IRQHandler + .thumb_set EXTI6_IRQHandler,Default_Handler + + .weak EXTI7_IRQHandler + .thumb_set EXTI7_IRQHandler,Default_Handler + + .weak EXTI8_IRQHandler + .thumb_set EXTI8_IRQHandler,Default_Handler + + .weak EXTI9_IRQHandler + .thumb_set EXTI9_IRQHandler,Default_Handler + + .weak EXTI10_IRQHandler + .thumb_set EXTI10_IRQHandler,Default_Handler + + .weak EXTI11_IRQHandler + .thumb_set EXTI11_IRQHandler,Default_Handler + + .weak EXTI12_IRQHandler + .thumb_set EXTI12_IRQHandler,Default_Handler + + .weak EXTI13_IRQHandler + .thumb_set EXTI13_IRQHandler,Default_Handler + + .weak EXTI14_IRQHandler + .thumb_set EXTI14_IRQHandler,Default_Handler + + .weak EXTI15_IRQHandler + .thumb_set EXTI15_IRQHandler,Default_Handler + + .weak GPDMA1_Channel0_IRQHandler + .thumb_set GPDMA1_Channel0_IRQHandler,Default_Handler + + .weak GPDMA1_Channel1_IRQHandler + .thumb_set GPDMA1_Channel1_IRQHandler,Default_Handler + + .weak GPDMA1_Channel2_IRQHandler + .thumb_set GPDMA1_Channel2_IRQHandler,Default_Handler + + .weak GPDMA1_Channel3_IRQHandler + .thumb_set GPDMA1_Channel3_IRQHandler,Default_Handler + + .weak GPDMA1_Channel4_IRQHandler + .thumb_set GPDMA1_Channel4_IRQHandler,Default_Handler + + .weak GPDMA1_Channel5_IRQHandler + .thumb_set GPDMA1_Channel5_IRQHandler,Default_Handler + + .weak GPDMA1_Channel6_IRQHandler + .thumb_set GPDMA1_Channel6_IRQHandler,Default_Handler + + .weak GPDMA1_Channel7_IRQHandler + .thumb_set GPDMA1_Channel7_IRQHandler,Default_Handler + + .weak IWDG_IRQHandler + .thumb_set IWDG_IRQHandler,Default_Handler + + .weak SAES_IRQHandler + .thumb_set SAES_IRQHandler,Default_Handler + + .weak ADC1_IRQHandler + .thumb_set ADC1_IRQHandler,Default_Handler + + .weak DAC1_IRQHandler + .thumb_set DAC1_IRQHandler,Default_Handler + + .weak FDCAN1_IT0_IRQHandler + .thumb_set FDCAN1_IT0_IRQHandler,Default_Handler + + .weak FDCAN1_IT1_IRQHandler + .thumb_set FDCAN1_IT1_IRQHandler,Default_Handler + + .weak TIM1_BRK_IRQHandler + .thumb_set TIM1_BRK_IRQHandler,Default_Handler + + .weak TIM1_UP_IRQHandler + .thumb_set TIM1_UP_IRQHandler,Default_Handler + + .weak TIM1_TRG_COM_IRQHandler + .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler + + .weak TIM1_CC_IRQHandler + .thumb_set TIM1_CC_IRQHandler,Default_Handler + + .weak TIM2_IRQHandler + .thumb_set TIM2_IRQHandler,Default_Handler + + .weak TIM3_IRQHandler + .thumb_set TIM3_IRQHandler,Default_Handler + + .weak TIM4_IRQHandler + .thumb_set TIM4_IRQHandler,Default_Handler + + .weak TIM5_IRQHandler + .thumb_set TIM5_IRQHandler,Default_Handler + + .weak TIM6_IRQHandler + .thumb_set TIM6_IRQHandler,Default_Handler + + .weak TIM7_IRQHandler + .thumb_set TIM7_IRQHandler,Default_Handler + + .weak I2C1_EV_IRQHandler + .thumb_set I2C1_EV_IRQHandler,Default_Handler + + .weak I2C1_ER_IRQHandler + .thumb_set I2C1_ER_IRQHandler,Default_Handler + + .weak I2C2_EV_IRQHandler + .thumb_set I2C2_EV_IRQHandler,Default_Handler + + .weak I2C2_ER_IRQHandler + .thumb_set I2C2_ER_IRQHandler,Default_Handler + + .weak SPI1_IRQHandler + .thumb_set SPI1_IRQHandler,Default_Handler + + .weak SPI2_IRQHandler + .thumb_set SPI2_IRQHandler,Default_Handler + + .weak SPI3_IRQHandler + .thumb_set SPI3_IRQHandler,Default_Handler + + .weak USART1_IRQHandler + .thumb_set USART1_IRQHandler,Default_Handler + + .weak USART2_IRQHandler + .thumb_set USART2_IRQHandler,Default_Handler + + .weak USART3_IRQHandler + .thumb_set USART3_IRQHandler,Default_Handler + + .weak UART4_IRQHandler + .thumb_set UART4_IRQHandler,Default_Handler + + .weak UART5_IRQHandler + .thumb_set UART5_IRQHandler,Default_Handler + + .weak LPUART1_IRQHandler + .thumb_set LPUART1_IRQHandler,Default_Handler + + .weak LPTIM1_IRQHandler + .thumb_set LPTIM1_IRQHandler,Default_Handler + + .weak TIM8_BRK_IRQHandler + .thumb_set TIM8_BRK_IRQHandler,Default_Handler + + .weak TIM8_UP_IRQHandler + .thumb_set TIM8_UP_IRQHandler,Default_Handler + + .weak TIM8_TRG_COM_IRQHandler + .thumb_set TIM8_TRG_COM_IRQHandler,Default_Handler + + .weak TIM8_CC_IRQHandler + .thumb_set TIM8_CC_IRQHandler,Default_Handler + + .weak ADC2_IRQHandler + .thumb_set ADC2_IRQHandler,Default_Handler + + .weak LPTIM2_IRQHandler + .thumb_set LPTIM2_IRQHandler,Default_Handler + + .weak TIM15_IRQHandler + .thumb_set TIM15_IRQHandler,Default_Handler + + .weak TIM16_IRQHandler + .thumb_set TIM16_IRQHandler,Default_Handler + + .weak TIM17_IRQHandler + .thumb_set TIM17_IRQHandler,Default_Handler + + .weak USB_DRD_FS_IRQHandler + .thumb_set USB_DRD_FS_IRQHandler,Default_Handler + + .weak CRS_IRQHandler + .thumb_set CRS_IRQHandler,Default_Handler + + .weak UCPD1_IRQHandler + .thumb_set UCPD1_IRQHandler,Default_Handler + + .weak FMC_IRQHandler + .thumb_set FMC_IRQHandler,Default_Handler + + .weak OCTOSPI1_IRQHandler + .thumb_set OCTOSPI1_IRQHandler,Default_Handler + + .weak SDMMC1_IRQHandler + .thumb_set SDMMC1_IRQHandler,Default_Handler + + .weak I2C3_EV_IRQHandler + .thumb_set I2C3_EV_IRQHandler,Default_Handler + + .weak I2C3_ER_IRQHandler + .thumb_set I2C3_ER_IRQHandler,Default_Handler + + .weak SPI4_IRQHandler + .thumb_set SPI4_IRQHandler,Default_Handler + + .weak SPI5_IRQHandler + .thumb_set SPI5_IRQHandler,Default_Handler + + .weak SPI6_IRQHandler + .thumb_set SPI6_IRQHandler,Default_Handler + + .weak USART6_IRQHandler + .thumb_set USART6_IRQHandler,Default_Handler + + .weak USART10_IRQHandler + .thumb_set USART10_IRQHandler,Default_Handler + + .weak USART11_IRQHandler + .thumb_set USART11_IRQHandler,Default_Handler + + .weak SAI1_IRQHandler + .thumb_set SAI1_IRQHandler,Default_Handler + + .weak SAI2_IRQHandler + .thumb_set SAI2_IRQHandler,Default_Handler + + .weak GPDMA2_Channel0_IRQHandler + .thumb_set GPDMA2_Channel0_IRQHandler,Default_Handler + + .weak GPDMA2_Channel1_IRQHandler + .thumb_set GPDMA2_Channel1_IRQHandler,Default_Handler + + .weak GPDMA2_Channel2_IRQHandler + .thumb_set GPDMA2_Channel2_IRQHandler,Default_Handler + + .weak GPDMA2_Channel3_IRQHandler + .thumb_set GPDMA2_Channel3_IRQHandler,Default_Handler + + .weak GPDMA2_Channel4_IRQHandler + .thumb_set GPDMA2_Channel4_IRQHandler,Default_Handler + + .weak GPDMA2_Channel5_IRQHandler + .thumb_set GPDMA2_Channel5_IRQHandler,Default_Handler + + .weak GPDMA2_Channel6_IRQHandler + .thumb_set GPDMA2_Channel6_IRQHandler,Default_Handler + + .weak GPDMA2_Channel7_IRQHandler + .thumb_set GPDMA2_Channel7_IRQHandler,Default_Handler + + .weak UART7_IRQHandler + .thumb_set UART7_IRQHandler,Default_Handler + + .weak UART8_IRQHandler + .thumb_set UART8_IRQHandler,Default_Handler + + .weak UART9_IRQHandler + .thumb_set UART9_IRQHandler,Default_Handler + + .weak UART12_IRQHandler + .thumb_set UART12_IRQHandler,Default_Handler + + .weak SDMMC2_IRQHandler + .thumb_set SDMMC2_IRQHandler,Default_Handler + + .weak FPU_IRQHandler + .thumb_set FPU_IRQHandler,Default_Handler + + .weak ICACHE_IRQHandler + .thumb_set ICACHE_IRQHandler,Default_Handler + + .weak DCACHE1_IRQHandler + .thumb_set DCACHE1_IRQHandler,Default_Handler + + .weak ETH_IRQHandler + .thumb_set ETH_IRQHandler,Default_Handler + + .weak ETH_WKUP_IRQHandler + .thumb_set ETH_WKUP_IRQHandler,Default_Handler + + .weak DCMI_PSSI_IRQHandler + .thumb_set DCMI_PSSI_IRQHandler,Default_Handler + + .weak FDCAN2_IT0_IRQHandler + .thumb_set FDCAN2_IT0_IRQHandler,Default_Handler + + .weak FDCAN2_IT1_IRQHandler + .thumb_set FDCAN2_IT1_IRQHandler,Default_Handler + + .weak CORDIC_IRQHandler + .thumb_set CORDIC_IRQHandler,Default_Handler + + .weak FMAC_IRQHandler + .thumb_set FMAC_IRQHandler,Default_Handler + + .weak DTS_IRQHandler + .thumb_set DTS_IRQHandler,Default_Handler + + .weak RNG_IRQHandler + .thumb_set RNG_IRQHandler,Default_Handler + + .weak OTFDEC1_IRQHandler + .thumb_set OTFDEC1_IRQHandler,Default_Handler + + .weak AES_IRQHandler + .thumb_set AES_IRQHandler,Default_Handler + + .weak HASH_IRQHandler + .thumb_set HASH_IRQHandler,Default_Handler + + .weak PKA_IRQHandler + .thumb_set PKA_IRQHandler,Default_Handler + + .weak CEC_IRQHandler + .thumb_set CEC_IRQHandler,Default_Handler + + .weak TIM12_IRQHandler + .thumb_set TIM12_IRQHandler,Default_Handler + + .weak TIM13_IRQHandler + .thumb_set TIM13_IRQHandler,Default_Handler + + .weak TIM14_IRQHandler + .thumb_set TIM14_IRQHandler,Default_Handler + + .weak I3C1_EV_IRQHandler + .thumb_set I3C1_EV_IRQHandler,Default_Handler + + .weak I3C1_ER_IRQHandler + .thumb_set I3C1_ER_IRQHandler,Default_Handler + + .weak I2C4_EV_IRQHandler + .thumb_set I2C4_EV_IRQHandler,Default_Handler + + .weak I2C4_ER_IRQHandler + .thumb_set I2C4_ER_IRQHandler,Default_Handler + + .weak LPTIM3_IRQHandler + .thumb_set LPTIM3_IRQHandler,Default_Handler + + .weak LPTIM4_IRQHandler + .thumb_set LPTIM4_IRQHandler,Default_Handler + + .weak LPTIM5_IRQHandler + .thumb_set LPTIM5_IRQHandler,Default_Handler + + .weak LPTIM6_IRQHandler + .thumb_set LPTIM6_IRQHandler,Default_Handler \ No newline at end of file diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h503xx_flash.icf b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h503xx_flash.icf new file mode 100644 index 0000000000..f1a9a5b9d9 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h503xx_flash.icf @@ -0,0 +1,33 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x08000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x0801FFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF; + +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x400; +define symbol __ICFEDIT_size_heap__ = 0x200; +/**** End of ICF editor section. ###ICF###*/ + + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; + \ No newline at end of file diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h503xx_sram.icf b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h503xx_sram.icf new file mode 100644 index 0000000000..62f3e453cc --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h503xx_sram.icf @@ -0,0 +1,33 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x20000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x20000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x20003FFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20004000; +define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF; + +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x400; +define symbol __ICFEDIT_size_heap__ = 0x200; +/**** End of ICF editor section. ###ICF###*/ + + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; + \ No newline at end of file diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h562xx_flash.icf b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h562xx_flash.icf new file mode 100644 index 0000000000..51a132f59c --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h562xx_flash.icf @@ -0,0 +1,33 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x08000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x081FFFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x2009FFFF; + +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x400; +define symbol __ICFEDIT_size_heap__ = 0x200; +/**** End of ICF editor section. ###ICF###*/ + + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; + \ No newline at end of file diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h562xx_flash_ns.icf b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h562xx_flash_ns.icf new file mode 100644 index 0000000000..75c6e87756 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h562xx_flash_ns.icf @@ -0,0 +1,32 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x08100000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x08100000; +define symbol __ICFEDIT_region_ROM_end__ = 0x081FFFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20050000; +define symbol __ICFEDIT_region_RAM_end__ = 0x2009FFFF; + +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x400; +define symbol __ICFEDIT_size_heap__ = 0x200; +/**** End of ICF editor section. ###ICF###*/ + + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; \ No newline at end of file diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h562xx_flash_s.icf b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h562xx_flash_s.icf new file mode 100644 index 0000000000..995679caa5 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h562xx_flash_s.icf @@ -0,0 +1,41 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x0C000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x0C000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x0C0FDFFF; +define symbol __ICFEDIT_region_ROM_NSC_start__ = 0x0C0FE000; +define symbol __ICFEDIT_region_ROM_NSC_end__ = 0x0C0FFFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x30000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x3004FFFF; + +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x400; +define symbol __ICFEDIT_size_heap__ = 0x200; +/**** End of ICF editor section. ###ICF###*/ + +define symbol __region_ROM_NS_start__ = 0x08100000; +define symbol __region_ROM_NS_end__ = 0x081FFFFF; + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region ROM_NSC_region = mem:[from __ICFEDIT_region_ROM_NSC_start__ to __ICFEDIT_region_ROM_NSC_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define exported symbol __VTOR_TABLE_start = __ICFEDIT_intvec_start__; +define exported symbol __VTOR_TABLE_NS_start = __region_ROM_NS_start__; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in ROM_NSC_region { section Veneer$$CMSE }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; \ No newline at end of file diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h562xx_sram.icf b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h562xx_sram.icf new file mode 100644 index 0000000000..1ca659615e --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h562xx_sram.icf @@ -0,0 +1,33 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x20000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x20000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x2004FFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20050000; +define symbol __ICFEDIT_region_RAM_end__ = 0x2009FFFF; + +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x400; +define symbol __ICFEDIT_size_heap__ = 0x200; +/**** End of ICF editor section. ###ICF###*/ + + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; + \ No newline at end of file diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h562xx_sram_ns.icf b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h562xx_sram_ns.icf new file mode 100644 index 0000000000..4cafb1c154 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h562xx_sram_ns.icf @@ -0,0 +1,33 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x20060000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x20050000; +define symbol __ICFEDIT_region_ROM_end__ = 0x2007FFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20080000; +define symbol __ICFEDIT_region_RAM_end__ = 0x2009FFFF; + +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x400; +define symbol __ICFEDIT_size_heap__ = 0x200; +/**** End of ICF editor section. ###ICF###*/ + + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; + \ No newline at end of file diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h562xx_sram_s.icf b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h562xx_sram_s.icf new file mode 100644 index 0000000000..d0ef55cdf2 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h562xx_sram_s.icf @@ -0,0 +1,40 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x30000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x30000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x30037FFF; +define symbol __ICFEDIT_region_ROM_NSC_start__ = 0x30038000; +define symbol __ICFEDIT_region_ROM_NSC_end__ = 0x3003FFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x30040000; +define symbol __ICFEDIT_region_RAM_end__ = 0x3004FFFF; + +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x400; +define symbol __ICFEDIT_size_heap__ = 0x200; +/**** End of ICF editor section. ###ICF###*/ + +define symbol __region_RAM_NS_start__ = 0x20050000; +define symbol __region_RAM_NS_end__ = 0x2009FFFF; + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region ROM_NSC_region = mem:[from __ICFEDIT_region_ROM_NSC_start__ to __ICFEDIT_region_ROM_NSC_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; +define exported symbol __VTOR_TABLE_start = __ICFEDIT_intvec_start__; +define exported symbol __VTOR_TABLE_NS_start = __region_RAM_NS_start__; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in ROM_NSC_region { section Veneer$$CMSE }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h563xx_flash.icf b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h563xx_flash.icf new file mode 100644 index 0000000000..51a132f59c --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h563xx_flash.icf @@ -0,0 +1,33 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x08000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x081FFFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x2009FFFF; + +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x400; +define symbol __ICFEDIT_size_heap__ = 0x200; +/**** End of ICF editor section. ###ICF###*/ + + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; + \ No newline at end of file diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h563xx_flash_ns.icf b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h563xx_flash_ns.icf new file mode 100644 index 0000000000..75c6e87756 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h563xx_flash_ns.icf @@ -0,0 +1,32 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x08100000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x08100000; +define symbol __ICFEDIT_region_ROM_end__ = 0x081FFFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20050000; +define symbol __ICFEDIT_region_RAM_end__ = 0x2009FFFF; + +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x400; +define symbol __ICFEDIT_size_heap__ = 0x200; +/**** End of ICF editor section. ###ICF###*/ + + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; \ No newline at end of file diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h563xx_flash_s.icf b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h563xx_flash_s.icf new file mode 100644 index 0000000000..995679caa5 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h563xx_flash_s.icf @@ -0,0 +1,41 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x0C000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x0C000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x0C0FDFFF; +define symbol __ICFEDIT_region_ROM_NSC_start__ = 0x0C0FE000; +define symbol __ICFEDIT_region_ROM_NSC_end__ = 0x0C0FFFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x30000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x3004FFFF; + +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x400; +define symbol __ICFEDIT_size_heap__ = 0x200; +/**** End of ICF editor section. ###ICF###*/ + +define symbol __region_ROM_NS_start__ = 0x08100000; +define symbol __region_ROM_NS_end__ = 0x081FFFFF; + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region ROM_NSC_region = mem:[from __ICFEDIT_region_ROM_NSC_start__ to __ICFEDIT_region_ROM_NSC_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define exported symbol __VTOR_TABLE_start = __ICFEDIT_intvec_start__; +define exported symbol __VTOR_TABLE_NS_start = __region_ROM_NS_start__; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in ROM_NSC_region { section Veneer$$CMSE }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; \ No newline at end of file diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h563xx_sram.icf b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h563xx_sram.icf new file mode 100644 index 0000000000..1ca659615e --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h563xx_sram.icf @@ -0,0 +1,33 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x20000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x20000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x2004FFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20050000; +define symbol __ICFEDIT_region_RAM_end__ = 0x2009FFFF; + +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x400; +define symbol __ICFEDIT_size_heap__ = 0x200; +/**** End of ICF editor section. ###ICF###*/ + + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; + \ No newline at end of file diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h563xx_sram_ns.icf b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h563xx_sram_ns.icf new file mode 100644 index 0000000000..4cafb1c154 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h563xx_sram_ns.icf @@ -0,0 +1,33 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x20060000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x20050000; +define symbol __ICFEDIT_region_ROM_end__ = 0x2007FFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20080000; +define symbol __ICFEDIT_region_RAM_end__ = 0x2009FFFF; + +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x400; +define symbol __ICFEDIT_size_heap__ = 0x200; +/**** End of ICF editor section. ###ICF###*/ + + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; + \ No newline at end of file diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h563xx_sram_s.icf b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h563xx_sram_s.icf new file mode 100644 index 0000000000..d0ef55cdf2 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h563xx_sram_s.icf @@ -0,0 +1,40 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x30000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x30000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x30037FFF; +define symbol __ICFEDIT_region_ROM_NSC_start__ = 0x30038000; +define symbol __ICFEDIT_region_ROM_NSC_end__ = 0x3003FFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x30040000; +define symbol __ICFEDIT_region_RAM_end__ = 0x3004FFFF; + +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x400; +define symbol __ICFEDIT_size_heap__ = 0x200; +/**** End of ICF editor section. ###ICF###*/ + +define symbol __region_RAM_NS_start__ = 0x20050000; +define symbol __region_RAM_NS_end__ = 0x2009FFFF; + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region ROM_NSC_region = mem:[from __ICFEDIT_region_ROM_NSC_start__ to __ICFEDIT_region_ROM_NSC_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; +define exported symbol __VTOR_TABLE_start = __ICFEDIT_intvec_start__; +define exported symbol __VTOR_TABLE_NS_start = __region_RAM_NS_start__; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in ROM_NSC_region { section Veneer$$CMSE }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h573xx_flash.icf b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h573xx_flash.icf new file mode 100644 index 0000000000..51a132f59c --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h573xx_flash.icf @@ -0,0 +1,33 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x08000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x081FFFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x2009FFFF; + +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x400; +define symbol __ICFEDIT_size_heap__ = 0x200; +/**** End of ICF editor section. ###ICF###*/ + + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; + \ No newline at end of file diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h573xx_flash_ns.icf b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h573xx_flash_ns.icf new file mode 100644 index 0000000000..75c6e87756 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h573xx_flash_ns.icf @@ -0,0 +1,32 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x08100000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x08100000; +define symbol __ICFEDIT_region_ROM_end__ = 0x081FFFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20050000; +define symbol __ICFEDIT_region_RAM_end__ = 0x2009FFFF; + +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x400; +define symbol __ICFEDIT_size_heap__ = 0x200; +/**** End of ICF editor section. ###ICF###*/ + + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; \ No newline at end of file diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h573xx_flash_s.icf b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h573xx_flash_s.icf new file mode 100644 index 0000000000..995679caa5 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h573xx_flash_s.icf @@ -0,0 +1,41 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x0C000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x0C000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x0C0FDFFF; +define symbol __ICFEDIT_region_ROM_NSC_start__ = 0x0C0FE000; +define symbol __ICFEDIT_region_ROM_NSC_end__ = 0x0C0FFFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x30000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x3004FFFF; + +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x400; +define symbol __ICFEDIT_size_heap__ = 0x200; +/**** End of ICF editor section. ###ICF###*/ + +define symbol __region_ROM_NS_start__ = 0x08100000; +define symbol __region_ROM_NS_end__ = 0x081FFFFF; + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region ROM_NSC_region = mem:[from __ICFEDIT_region_ROM_NSC_start__ to __ICFEDIT_region_ROM_NSC_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define exported symbol __VTOR_TABLE_start = __ICFEDIT_intvec_start__; +define exported symbol __VTOR_TABLE_NS_start = __region_ROM_NS_start__; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in ROM_NSC_region { section Veneer$$CMSE }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; \ No newline at end of file diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h573xx_sram.icf b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h573xx_sram.icf new file mode 100644 index 0000000000..1ca659615e --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h573xx_sram.icf @@ -0,0 +1,33 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x20000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x20000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x2004FFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20050000; +define symbol __ICFEDIT_region_RAM_end__ = 0x2009FFFF; + +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x400; +define symbol __ICFEDIT_size_heap__ = 0x200; +/**** End of ICF editor section. ###ICF###*/ + + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; + \ No newline at end of file diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h573xx_sram_ns.icf b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h573xx_sram_ns.icf new file mode 100644 index 0000000000..4cafb1c154 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h573xx_sram_ns.icf @@ -0,0 +1,33 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x20060000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x20050000; +define symbol __ICFEDIT_region_ROM_end__ = 0x2007FFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20080000; +define symbol __ICFEDIT_region_RAM_end__ = 0x2009FFFF; + +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x400; +define symbol __ICFEDIT_size_heap__ = 0x200; +/**** End of ICF editor section. ###ICF###*/ + + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; + \ No newline at end of file diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h573xx_sram_s.icf b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h573xx_sram_s.icf new file mode 100644 index 0000000000..d0ef55cdf2 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/linker/stm32h573xx_sram_s.icf @@ -0,0 +1,40 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x30000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x30000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x30037FFF; +define symbol __ICFEDIT_region_ROM_NSC_start__ = 0x30038000; +define symbol __ICFEDIT_region_ROM_NSC_end__ = 0x3003FFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x30040000; +define symbol __ICFEDIT_region_RAM_end__ = 0x3004FFFF; + +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x400; +define symbol __ICFEDIT_size_heap__ = 0x200; +/**** End of ICF editor section. ###ICF###*/ + +define symbol __region_RAM_NS_start__ = 0x20050000; +define symbol __region_RAM_NS_end__ = 0x2009FFFF; + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region ROM_NSC_region = mem:[from __ICFEDIT_region_ROM_NSC_start__ to __ICFEDIT_region_ROM_NSC_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; +define exported symbol __VTOR_TABLE_start = __ICFEDIT_intvec_start__; +define exported symbol __VTOR_TABLE_NS_start = __region_RAM_NS_start__; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in ROM_NSC_region { section Veneer$$CMSE }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/startup_stm32h503xx.s b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/startup_stm32h503xx.s new file mode 100644 index 0000000000..fe2f88c5e2 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/startup_stm32h503xx.s @@ -0,0 +1,670 @@ +;******************************************************************************** +;* File Name : startup_stm32h503xx.s +;* Author : MCD Application Team +;* Description : STM32H503xx Non Crypto Devices vector +;* This module performs: +;* - Set the initial SP +;* - Set the initial PC == _iar_program_start, +;* - Set the vector table entries with the exceptions ISR +;* address. +;* - Branches to main in the C library (which eventually +;* calls main()). +;* After Reset the Cortex-M33 processor is in Thread mode, +;* priority is Privileged, and the Stack is set to Main. +;******************************************************************************** +;* @attention +;* +;* Copyright (c) 2023 STMicroelectronics. +;* All rights reserved. +;* +;* This software is licensed under terms that can be found in the LICENSE file +;* in the root directory of this software component. +;* If no LICENSE file comes with this software, it is provided AS-IS. +;* +;******************************************************************************* +; +; +; The modules in this file are included in the libraries, and may be replaced +; by any user-defined modules that define the PUBLIC symbol _program_start or +; a user defined start symbol. +; To override the cstartup defined in the library, simply add your modified +; version to the workbench project. +; +; The vector table is normally located at address 0. +; When debugging in RAM, it can be located in RAM, aligned to at least 2^6. +; The name "__vector_table" has special meaning for C-SPY: +; it is where the SP start value is found, and the NVIC vector +; table register (VTOR) is initialized to this address if != 0. +; +; Cortex-M version +; + + MODULE ?cstartup + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN SystemInit + PUBLIC __vector_table + PUBLIC __Vectors + PUBLIC __Vectors_End + PUBLIC __Vectors_Size + + DATA +__vector_table + DCD sfe(CSTACK) + DCD Reset_Handler ; Reset Handler + + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WWDG_IRQHandler ; Window WatchDog + DCD PVD_AVD_IRQHandler ; PVD/AVD through EXTI Line detection Interrupt + DCD RTC_IRQHandler ; RTC non-secure interrupt + DCD 0 ; Reserved + DCD TAMP_IRQHandler ; Tamper non-secure interrupt + DCD RAMCFG_IRQHandler ; RAMCFG global + DCD FLASH_IRQHandler ; FLASH non-secure global interrupt + DCD 0 ; Reserved + DCD GTZC_IRQHandler ; Global TrustZone Controller interrupt + DCD RCC_IRQHandler ; RCC non-secure global interrupt + DCD 0 ; Reserved + DCD EXTI0_IRQHandler ; EXTI Line0 interrupt + DCD EXTI1_IRQHandler ; EXTI Line1 interrupt + DCD EXTI2_IRQHandler ; EXTI Line2 interrupt + DCD EXTI3_IRQHandler ; EXTI Line3 interrupt + DCD EXTI4_IRQHandler ; EXTI Line4 interrupt + DCD EXTI5_IRQHandler ; EXTI Line5 interrupt + DCD EXTI6_IRQHandler ; EXTI Line6 interrupt + DCD EXTI7_IRQHandler ; EXTI Line7 interrupt + DCD EXTI8_IRQHandler ; EXTI Line8 interrupt + DCD EXTI9_IRQHandler ; EXTI Line9 interrupt + DCD EXTI10_IRQHandler ; EXTI Line10 interrupt + DCD EXTI11_IRQHandler ; EXTI Line11 interrupt + DCD EXTI12_IRQHandler ; EXTI Line12 interrupt + DCD EXTI13_IRQHandler ; EXTI Line13 interrupt + DCD EXTI14_IRQHandler ; EXTI Line14 interrupt + DCD EXTI15_IRQHandler ; EXTI Line15 interrupt + DCD GPDMA1_Channel0_IRQHandler ; GPDMA1 Channel 0 global interrupt + DCD GPDMA1_Channel1_IRQHandler ; GPDMA1 Channel 1 global interrupt + DCD GPDMA1_Channel2_IRQHandler ; GPDMA1 Channel 2 global interrupt + DCD GPDMA1_Channel3_IRQHandler ; GPDMA1 Channel 3 global interrupt + DCD GPDMA1_Channel4_IRQHandler ; GPDMA1 Channel 4 global interrupt + DCD GPDMA1_Channel5_IRQHandler ; GPDMA1 Channel 5 global interrupt + DCD GPDMA1_Channel6_IRQHandler ; GPDMA1 Channel 6 global interrupt + DCD GPDMA1_Channel7_IRQHandler ; GPDMA1 Channel 7 global interrupt + DCD IWDG_IRQHandler ; IWDG global interrupt + DCD 0 ; Reserved + DCD ADC1_IRQHandler ; ADC1 global interrupt + DCD DAC1_IRQHandler ; DAC1 global interrupt + DCD FDCAN1_IT0_IRQHandler ; FDCAN1 interrupt 0 + DCD FDCAN1_IT1_IRQHandler ; FDCAN1 interrupt 1 + DCD TIM1_BRK_IRQHandler ; TIM1 Break interrupt + DCD TIM1_UP_IRQHandler ; TIM1 Update interrupt + DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation interrupt + DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare interrupt + DCD TIM2_IRQHandler ; TIM2 global interrupt + DCD TIM3_IRQHandler ; TIM3 global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD TIM6_IRQHandler ; TIM6 global interrupt + DCD TIM7_IRQHandler ; TIM7 global interrupt + DCD I2C1_EV_IRQHandler ; I2C1 Event interrupt + DCD I2C1_ER_IRQHandler ; I2C1 Error interrupt + DCD I2C2_EV_IRQHandler ; I2C2 Event interrupt + DCD I2C2_ER_IRQHandler ; I2C2 Error interrupt + DCD SPI1_IRQHandler ; SPI1 global interrupt + DCD SPI2_IRQHandler ; SPI2 global interrupt + DCD SPI3_IRQHandler ; SPI3 global interrupt + DCD USART1_IRQHandler ; USART1 global interrupt + DCD USART2_IRQHandler ; USART2 global interrupt + DCD USART3_IRQHandler ; USART3 global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD LPUART1_IRQHandler ; LPUART1 global interrupt + DCD LPTIM1_IRQHandler ; LPTIM1 global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD LPTIM2_IRQHandler ; LPTIM2 global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD USB_DRD_FS_IRQHandler ; USB DRD FS global interrupt + DCD CRS_IRQHandler ; CRS global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD GPDMA2_Channel0_IRQHandler ; GPDMA2 Channel 0 global interrupt + DCD GPDMA2_Channel1_IRQHandler ; GPDMA2 Channel 1 global interrupt + DCD GPDMA2_Channel2_IRQHandler ; GPDMA2 Channel 2 global interrupt + DCD GPDMA2_Channel3_IRQHandler ; GPDMA2 Channel 3 global interrupt + DCD GPDMA2_Channel4_IRQHandler ; GPDMA2 Channel 4 global interrupt + DCD GPDMA2_Channel5_IRQHandler ; GPDMA2 Channel 5 global interrupt + DCD GPDMA2_Channel6_IRQHandler ; GPDMA2 Channel 6 global interrupt + DCD GPDMA2_Channel7_IRQHandler ; GPDMA2 Channel 7 global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD FPU_IRQHandler ; FPU global interrupt + DCD ICACHE_IRQHandler ; Instruction cache global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD DTS_IRQHandler ; DTS global interrupt + DCD RNG_IRQHandler ; RNG global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD HASH_IRQHandler ; HASH global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD I3C1_EV_IRQHandler ; I3C1 Event interrupt + DCD I3C1_ER_IRQHandler ; I3C1 Error interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD I3C2_EV_IRQHandler ; I3C2 Event interrupt + DCD I3C2_ER_IRQHandler ; I3C2 Error interrupt + DCD COMP1_IRQHandler ; COMP1 global interrupt + +__Vectors_End + +__Vectors EQU __vector_table +__Vectors_Size EQU __Vectors_End - __Vectors + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + PUBWEAK Reset_Handler + SECTION .text:CODE:NOROOT:REORDER(2) +Reset_Handler + LDR R0, =SystemInit + BLX R0 + LDR R0, =__iar_program_start + BX R0 + + PUBWEAK NMI_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +NMI_Handler + B NMI_Handler + + PUBWEAK HardFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +HardFault_Handler + B HardFault_Handler + + PUBWEAK MemManage_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +MemManage_Handler + B MemManage_Handler + + PUBWEAK BusFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +BusFault_Handler + B BusFault_Handler + + PUBWEAK UsageFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +UsageFault_Handler + B UsageFault_Handler + + PUBWEAK SecureFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SecureFault_Handler + B SecureFault_Handler + + PUBWEAK SVC_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SVC_Handler + B SVC_Handler + + PUBWEAK DebugMon_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DebugMon_Handler + B DebugMon_Handler + + PUBWEAK PendSV_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +PendSV_Handler + B PendSV_Handler + + PUBWEAK SysTick_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SysTick_Handler + B SysTick_Handler + + PUBWEAK WWDG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +WWDG_IRQHandler + B WWDG_IRQHandler + + PUBWEAK PVD_AVD_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +PVD_AVD_IRQHandler + B PVD_AVD_IRQHandler + + PUBWEAK RTC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_IRQHandler + B RTC_IRQHandler + + PUBWEAK TAMP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TAMP_IRQHandler + B TAMP_IRQHandler + + PUBWEAK RAMCFG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RAMCFG_IRQHandler + B RAMCFG_IRQHandler + + PUBWEAK FLASH_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FLASH_IRQHandler + B FLASH_IRQHandler + + PUBWEAK GTZC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GTZC_IRQHandler + B GTZC_IRQHandler + + PUBWEAK RCC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RCC_IRQHandler + B RCC_IRQHandler + + PUBWEAK EXTI0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI0_IRQHandler + B EXTI0_IRQHandler + + PUBWEAK EXTI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI1_IRQHandler + B EXTI1_IRQHandler + + PUBWEAK EXTI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI2_IRQHandler + B EXTI2_IRQHandler + + PUBWEAK EXTI3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI3_IRQHandler + B EXTI3_IRQHandler + + PUBWEAK EXTI4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI4_IRQHandler + B EXTI4_IRQHandler + + PUBWEAK EXTI5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI5_IRQHandler + B EXTI5_IRQHandler + + PUBWEAK EXTI6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI6_IRQHandler + B EXTI6_IRQHandler + + PUBWEAK EXTI7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI7_IRQHandler + B EXTI7_IRQHandler + + PUBWEAK EXTI8_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI8_IRQHandler + B EXTI8_IRQHandler + + PUBWEAK EXTI9_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI9_IRQHandler + B EXTI9_IRQHandler + + PUBWEAK EXTI10_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI10_IRQHandler + B EXTI10_IRQHandler + + PUBWEAK EXTI11_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI11_IRQHandler + B EXTI11_IRQHandler + + PUBWEAK EXTI12_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI12_IRQHandler + B EXTI12_IRQHandler + + PUBWEAK EXTI13_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI13_IRQHandler + B EXTI13_IRQHandler + + PUBWEAK EXTI14_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI14_IRQHandler + B EXTI14_IRQHandler + + PUBWEAK EXTI15_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI15_IRQHandler + B EXTI15_IRQHandler + + PUBWEAK GPDMA1_Channel0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel0_IRQHandler + B GPDMA1_Channel0_IRQHandler + + PUBWEAK GPDMA1_Channel1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel1_IRQHandler + B GPDMA1_Channel1_IRQHandler + + PUBWEAK GPDMA1_Channel2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel2_IRQHandler + B GPDMA1_Channel2_IRQHandler + + PUBWEAK GPDMA1_Channel3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel3_IRQHandler + B GPDMA1_Channel3_IRQHandler + + PUBWEAK GPDMA1_Channel4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel4_IRQHandler + B GPDMA1_Channel4_IRQHandler + + PUBWEAK GPDMA1_Channel5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel5_IRQHandler + B GPDMA1_Channel5_IRQHandler + + PUBWEAK GPDMA1_Channel6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel6_IRQHandler + B GPDMA1_Channel6_IRQHandler + + PUBWEAK GPDMA1_Channel7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel7_IRQHandler + B GPDMA1_Channel7_IRQHandler + + PUBWEAK IWDG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +IWDG_IRQHandler + B IWDG_IRQHandler + + PUBWEAK ADC1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ADC1_IRQHandler + B ADC1_IRQHandler + + PUBWEAK DAC1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DAC1_IRQHandler + B DAC1_IRQHandler + + PUBWEAK FDCAN1_IT0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FDCAN1_IT0_IRQHandler + B FDCAN1_IT0_IRQHandler + + PUBWEAK FDCAN1_IT1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FDCAN1_IT1_IRQHandler + B FDCAN1_IT1_IRQHandler + + PUBWEAK TIM1_BRK_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_BRK_IRQHandler + B TIM1_BRK_IRQHandler + + PUBWEAK TIM1_UP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_UP_IRQHandler + B TIM1_UP_IRQHandler + + PUBWEAK TIM1_TRG_COM_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_TRG_COM_IRQHandler + B TIM1_TRG_COM_IRQHandler + + PUBWEAK TIM1_CC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_CC_IRQHandler + B TIM1_CC_IRQHandler + + PUBWEAK TIM2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM2_IRQHandler + B TIM2_IRQHandler + + PUBWEAK TIM3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM3_IRQHandler + B TIM3_IRQHandler + + PUBWEAK TIM6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM6_IRQHandler + B TIM6_IRQHandler + + PUBWEAK TIM7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM7_IRQHandler + B TIM7_IRQHandler + + PUBWEAK I2C1_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_EV_IRQHandler + B I2C1_EV_IRQHandler + + PUBWEAK I2C1_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_ER_IRQHandler + B I2C1_ER_IRQHandler + + PUBWEAK I2C2_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C2_EV_IRQHandler + B I2C2_EV_IRQHandler + + PUBWEAK I2C2_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C2_ER_IRQHandler + B I2C2_ER_IRQHandler + + PUBWEAK SPI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI1_IRQHandler + B SPI1_IRQHandler + + PUBWEAK SPI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI2_IRQHandler + B SPI2_IRQHandler + + PUBWEAK SPI3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI3_IRQHandler + B SPI3_IRQHandler + + PUBWEAK USART1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART1_IRQHandler + B USART1_IRQHandler + + PUBWEAK USART2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART2_IRQHandler + B USART2_IRQHandler + + PUBWEAK USART3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART3_IRQHandler + B USART3_IRQHandler + + PUBWEAK LPUART1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPUART1_IRQHandler + B LPUART1_IRQHandler + + PUBWEAK LPTIM1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM1_IRQHandler + B LPTIM1_IRQHandler + + PUBWEAK LPTIM2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM2_IRQHandler + B LPTIM2_IRQHandler + + PUBWEAK USB_DRD_FS_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USB_DRD_FS_IRQHandler + B USB_DRD_FS_IRQHandler + + PUBWEAK CRS_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CRS_IRQHandler + B CRS_IRQHandler + + PUBWEAK GPDMA2_Channel0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel0_IRQHandler + B GPDMA2_Channel0_IRQHandler + + PUBWEAK GPDMA2_Channel1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel1_IRQHandler + B GPDMA2_Channel1_IRQHandler + + PUBWEAK GPDMA2_Channel2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel2_IRQHandler + B GPDMA2_Channel2_IRQHandler + + PUBWEAK GPDMA2_Channel3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel3_IRQHandler + B GPDMA2_Channel3_IRQHandler + + PUBWEAK GPDMA2_Channel4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel4_IRQHandler + B GPDMA2_Channel4_IRQHandler + + PUBWEAK GPDMA2_Channel5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel5_IRQHandler + B GPDMA2_Channel5_IRQHandler + + PUBWEAK GPDMA2_Channel6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel6_IRQHandler + B GPDMA2_Channel6_IRQHandler + + PUBWEAK GPDMA2_Channel7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel7_IRQHandler + B GPDMA2_Channel7_IRQHandler + + PUBWEAK COMP1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +COMP1_IRQHandler + B COMP1_IRQHandler + + PUBWEAK I3C2_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I3C2_EV_IRQHandler + B I3C2_EV_IRQHandler + + PUBWEAK I3C2_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I3C2_ER_IRQHandler + B I3C2_ER_IRQHandler + + PUBWEAK FPU_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FPU_IRQHandler + B FPU_IRQHandler + + PUBWEAK ICACHE_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ICACHE_IRQHandler + B ICACHE_IRQHandler + + PUBWEAK DTS_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DTS_IRQHandler + B DTS_IRQHandler + + PUBWEAK RNG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RNG_IRQHandler + B RNG_IRQHandler + + PUBWEAK HASH_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HASH_IRQHandler + B HASH_IRQHandler + + PUBWEAK I3C1_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I3C1_EV_IRQHandler + B I3C1_EV_IRQHandler + + PUBWEAK I3C1_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I3C1_ER_IRQHandler + B I3C1_ER_IRQHandler + + END diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/startup_stm32h562xx.s b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/startup_stm32h562xx.s new file mode 100644 index 0000000000..5937233004 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/startup_stm32h562xx.s @@ -0,0 +1,887 @@ +;******************************************************************************** +;* File Name : startup_stm32h562xx.s +;* Author : MCD Application Team +;* Description : STM32H562xx Non Crypto Devices vector +;* This module performs: +;* - Set the initial SP +;* - Set the initial PC == _iar_program_start, +;* - Set the vector table entries with the exceptions ISR +;* address. +;* - Branches to main in the C library (which eventually +;* calls main()). +;* After Reset the Cortex-M33 processor is in Thread mode, +;* priority is Privileged, and the Stack is set to Main. +;******************************************************************************** +;* @attention +;* +;* Copyright (c) 2023 STMicroelectronics. +;* All rights reserved. +;* +;* This software is licensed under terms that can be found in the LICENSE file +;* in the root directory of this software component. +;* If no LICENSE file comes with this software, it is provided AS-IS. +;* +;******************************************************************************* +; +; +; The modules in this file are included in the libraries, and may be replaced +; by any user-defined modules that define the PUBLIC symbol _program_start or +; a user defined start symbol. +; To override the cstartup defined in the library, simply add your modified +; version to the workbench project. +; +; The vector table is normally located at address 0. +; When debugging in RAM, it can be located in RAM, aligned to at least 2^6. +; The name "__vector_table" has special meaning for C-SPY: +; it is where the SP start value is found, and the NVIC vector +; table register (VTOR) is initialized to this address if != 0. +; +; Cortex-M version +; + + MODULE ?cstartup + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN SystemInit + PUBLIC __vector_table + PUBLIC __Vectors + PUBLIC __Vectors_End + PUBLIC __Vectors_Size + + DATA +__vector_table + DCD sfe(CSTACK) + DCD Reset_Handler ; Reset Handler + + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD SecureFault_Handler ; Secure Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WWDG_IRQHandler ; Window WatchDog + DCD PVD_AVD_IRQHandler ; PVD/AVD through EXTI Line detection Interrupt + DCD RTC_IRQHandler ; RTC non-secure interrupt + DCD RTC_S_IRQHandler ; RTC secure interrupt + DCD TAMP_IRQHandler ; Tamper non-secure interrupt + DCD RAMCFG_IRQHandler ; RAMCFG global + DCD FLASH_IRQHandler ; FLASH non-secure global interrupt + DCD FLASH_S_IRQHandler ; FLASH secure global interrupt + DCD GTZC_IRQHandler ; Global TrustZone Controller interrupt + DCD RCC_IRQHandler ; RCC non-secure global interrupt + DCD RCC_S_IRQHandler ; RCC secure global interrupt + DCD EXTI0_IRQHandler ; EXTI Line0 interrupt + DCD EXTI1_IRQHandler ; EXTI Line1 interrupt + DCD EXTI2_IRQHandler ; EXTI Line2 interrupt + DCD EXTI3_IRQHandler ; EXTI Line3 interrupt + DCD EXTI4_IRQHandler ; EXTI Line4 interrupt + DCD EXTI5_IRQHandler ; EXTI Line5 interrupt + DCD EXTI6_IRQHandler ; EXTI Line6 interrupt + DCD EXTI7_IRQHandler ; EXTI Line7 interrupt + DCD EXTI8_IRQHandler ; EXTI Line8 interrupt + DCD EXTI9_IRQHandler ; EXTI Line9 interrupt + DCD EXTI10_IRQHandler ; EXTI Line10 interrupt + DCD EXTI11_IRQHandler ; EXTI Line11 interrupt + DCD EXTI12_IRQHandler ; EXTI Line12 interrupt + DCD EXTI13_IRQHandler ; EXTI Line13 interrupt + DCD EXTI14_IRQHandler ; EXTI Line14 interrupt + DCD EXTI15_IRQHandler ; EXTI Line15 interrupt + DCD GPDMA1_Channel0_IRQHandler ; GPDMA1 Channel 0 global interrupt + DCD GPDMA1_Channel1_IRQHandler ; GPDMA1 Channel 1 global interrupt + DCD GPDMA1_Channel2_IRQHandler ; GPDMA1 Channel 2 global interrupt + DCD GPDMA1_Channel3_IRQHandler ; GPDMA1 Channel 3 global interrupt + DCD GPDMA1_Channel4_IRQHandler ; GPDMA1 Channel 4 global interrupt + DCD GPDMA1_Channel5_IRQHandler ; GPDMA1 Channel 5 global interrupt + DCD GPDMA1_Channel6_IRQHandler ; GPDMA1 Channel 6 global interrupt + DCD GPDMA1_Channel7_IRQHandler ; GPDMA1 Channel 7 global interrupt + DCD IWDG_IRQHandler ; IWDG global interrupt + DCD 0 ; Reserved + DCD ADC1_IRQHandler ; ADC1 global interrupt + DCD DAC1_IRQHandler ; DAC1 global interrupt + DCD FDCAN1_IT0_IRQHandler ; FDCAN1 interrupt 0 + DCD FDCAN1_IT1_IRQHandler ; FDCAN1 interrupt 1 + DCD TIM1_BRK_IRQHandler ; TIM1 Break interrupt + DCD TIM1_UP_IRQHandler ; TIM1 Update interrupt + DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation interrupt + DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare interrupt + DCD TIM2_IRQHandler ; TIM2 global interrupt + DCD TIM3_IRQHandler ; TIM3 global interrupt + DCD TIM4_IRQHandler ; TIM4 global interrupt + DCD TIM5_IRQHandler ; TIM5 global interrupt + DCD TIM6_IRQHandler ; TIM6 global interrupt + DCD TIM7_IRQHandler ; TIM7 global interrupt + DCD I2C1_EV_IRQHandler ; I2C1 Event interrupt + DCD I2C1_ER_IRQHandler ; I2C1 Error interrupt + DCD I2C2_EV_IRQHandler ; I2C2 Event interrupt + DCD I2C2_ER_IRQHandler ; I2C2 Error interrupt + DCD SPI1_IRQHandler ; SPI1 global interrupt + DCD SPI2_IRQHandler ; SPI2 global interrupt + DCD SPI3_IRQHandler ; SPI3 global interrupt + DCD USART1_IRQHandler ; USART1 global interrupt + DCD USART2_IRQHandler ; USART2 global interrupt + DCD USART3_IRQHandler ; USART3 global interrupt + DCD UART4_IRQHandler ; UART4 global interrupt + DCD UART5_IRQHandler ; UART5 global interrupt + DCD LPUART1_IRQHandler ; LPUART1 global interrupt + DCD LPTIM1_IRQHandler ; LPTIM1 global interrupt + DCD TIM8_BRK_IRQHandler ; TIM8 Break interrupt + DCD TIM8_UP_IRQHandler ; TIM8 Update interrupt + DCD TIM8_TRG_COM_IRQHandler ; TIM8 Trigger and Commutation interrupt + DCD TIM8_CC_IRQHandler ; TIM8 Capture Compare interrupt + DCD ADC2_IRQHandler ; ADC2 global interrupt + DCD LPTIM2_IRQHandler ; LPTIM2 global interrupt + DCD TIM15_IRQHandler ; TIM15 global interrupt + DCD TIM16_IRQHandler ; TIM16 global interrupt + DCD TIM17_IRQHandler ; TIM17 global interrupt + DCD USB_DRD_FS_IRQHandler ; USB DRD FS global interrupt + DCD CRS_IRQHandler ; CRS global interrupt + DCD UCPD1_IRQHandler ; UCPD1 global interrupt + DCD FMC_IRQHandler ; FMC global interrupt + DCD OCTOSPI1_IRQHandler ; OctoSPI1 global interrupt + DCD SDMMC1_IRQHandler ; SDMMC1 global interrupt + DCD I2C3_EV_IRQHandler ; I2C2 Event interrupt + DCD I2C3_ER_IRQHandler ; I2C2 Error interrupt + DCD SPI4_IRQHandler ; SPI4 global interrupt + DCD SPI5_IRQHandler ; SPI5 global interrupt + DCD SPI6_IRQHandler ; SPI6 global interrupt + DCD USART6_IRQHandler ; USART6 global interrupt + DCD USART10_IRQHandler ; USART10 global interrupt + DCD USART11_IRQHandler ; USART11 global interrupt + DCD SAI1_IRQHandler ; Serial Audio Interface 1 global interrupt + DCD SAI2_IRQHandler ; Serial Audio Interface 2 global interrupt + DCD GPDMA2_Channel0_IRQHandler ; GPDMA2 Channel 0 global interrupt + DCD GPDMA2_Channel1_IRQHandler ; GPDMA2 Channel 1 global interrupt + DCD GPDMA2_Channel2_IRQHandler ; GPDMA2 Channel 2 global interrupt + DCD GPDMA2_Channel3_IRQHandler ; GPDMA2 Channel 3 global interrupt + DCD GPDMA2_Channel4_IRQHandler ; GPDMA2 Channel 4 global interrupt + DCD GPDMA2_Channel5_IRQHandler ; GPDMA2 Channel 5 global interrupt + DCD GPDMA2_Channel6_IRQHandler ; GPDMA2 Channel 6 global interrupt + DCD GPDMA2_Channel7_IRQHandler ; GPDMA2 Channel 7 global interrupt + DCD UART7_IRQHandler ; UART7 global interrupt + DCD UART8_IRQHandler ; UART8 global interrupt + DCD UART9_IRQHandler ; UART9 global interrupt + DCD UART12_IRQHandler ; UART12 global interrupt + DCD 0 ; Reserved + DCD FPU_IRQHandler ; FPU global interrupt + DCD ICACHE_IRQHandler ; Instruction cache global interrupt + DCD DCACHE1_IRQHandler ; DCACHE1 global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD DCMI_PSSI_IRQHandler ; DCMI PSSI global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD CORDIC_IRQHandler ; CORDIC global interrupt + DCD FMAC_IRQHandler ; FMAC global interrupt + DCD DTS_IRQHandler ; DTS global interrupt + DCD RNG_IRQHandler ; RNG global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD HASH_IRQHandler ; HASH global interrupt + DCD 0 ; Reserved + DCD CEC_IRQHandler ; CEC global interrupt + DCD TIM12_IRQHandler ; TIM12 global interrupt + DCD TIM13_IRQHandler ; TIM13 global interrupt + DCD TIM14_IRQHandler ; TIM14 global interrupt + DCD I3C1_EV_IRQHandler ; I3C1 Event interrupt + DCD I3C1_ER_IRQHandler ; I3C1 Error interrupt + DCD I2C4_EV_IRQHandler ; I2C4 Event interrupt + DCD I2C4_ER_IRQHandler ; I2C4 Error interrupt + DCD LPTIM3_IRQHandler ; LPTIM3 global interrupt + DCD LPTIM4_IRQHandler ; LPTIM4 global interrupt + DCD LPTIM5_IRQHandler ; LPTIM5 global interrupt + DCD LPTIM6_IRQHandler ; LPTIM6 global interrupt + +__Vectors_End + +__Vectors EQU __vector_table +__Vectors_Size EQU __Vectors_End - __Vectors + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + PUBWEAK Reset_Handler + SECTION .text:CODE:NOROOT:REORDER(2) +Reset_Handler + LDR R0, =SystemInit + BLX R0 + LDR R0, =__iar_program_start + BX R0 + + PUBWEAK NMI_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +NMI_Handler + B NMI_Handler + + PUBWEAK HardFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +HardFault_Handler + B HardFault_Handler + + PUBWEAK MemManage_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +MemManage_Handler + B MemManage_Handler + + PUBWEAK BusFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +BusFault_Handler + B BusFault_Handler + + PUBWEAK UsageFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +UsageFault_Handler + B UsageFault_Handler + + PUBWEAK SecureFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SecureFault_Handler + B SecureFault_Handler + + PUBWEAK SVC_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SVC_Handler + B SVC_Handler + + PUBWEAK DebugMon_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DebugMon_Handler + B DebugMon_Handler + + PUBWEAK PendSV_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +PendSV_Handler + B PendSV_Handler + + PUBWEAK SysTick_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SysTick_Handler + B SysTick_Handler + + PUBWEAK WWDG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +WWDG_IRQHandler + B WWDG_IRQHandler + + PUBWEAK PVD_AVD_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +PVD_AVD_IRQHandler + B PVD_AVD_IRQHandler + + PUBWEAK RTC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_IRQHandler + B RTC_IRQHandler + + PUBWEAK RTC_S_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_S_IRQHandler + B RTC_S_IRQHandler + + PUBWEAK TAMP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TAMP_IRQHandler + B TAMP_IRQHandler + + PUBWEAK RAMCFG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RAMCFG_IRQHandler + B RAMCFG_IRQHandler + + PUBWEAK FLASH_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FLASH_IRQHandler + B FLASH_IRQHandler + + PUBWEAK FLASH_S_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FLASH_S_IRQHandler + B FLASH_S_IRQHandler + + PUBWEAK GTZC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GTZC_IRQHandler + B GTZC_IRQHandler + + PUBWEAK RCC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RCC_IRQHandler + B RCC_IRQHandler + + PUBWEAK RCC_S_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RCC_S_IRQHandler + B RCC_S_IRQHandler + + PUBWEAK EXTI0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI0_IRQHandler + B EXTI0_IRQHandler + + PUBWEAK EXTI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI1_IRQHandler + B EXTI1_IRQHandler + + PUBWEAK EXTI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI2_IRQHandler + B EXTI2_IRQHandler + + PUBWEAK EXTI3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI3_IRQHandler + B EXTI3_IRQHandler + + PUBWEAK EXTI4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI4_IRQHandler + B EXTI4_IRQHandler + + PUBWEAK EXTI5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI5_IRQHandler + B EXTI5_IRQHandler + + PUBWEAK EXTI6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI6_IRQHandler + B EXTI6_IRQHandler + + PUBWEAK EXTI7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI7_IRQHandler + B EXTI7_IRQHandler + + PUBWEAK EXTI8_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI8_IRQHandler + B EXTI8_IRQHandler + + PUBWEAK EXTI9_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI9_IRQHandler + B EXTI9_IRQHandler + + PUBWEAK EXTI10_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI10_IRQHandler + B EXTI10_IRQHandler + + PUBWEAK EXTI11_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI11_IRQHandler + B EXTI11_IRQHandler + + PUBWEAK EXTI12_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI12_IRQHandler + B EXTI12_IRQHandler + + PUBWEAK EXTI13_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI13_IRQHandler + B EXTI13_IRQHandler + + PUBWEAK EXTI14_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI14_IRQHandler + B EXTI14_IRQHandler + + PUBWEAK EXTI15_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI15_IRQHandler + B EXTI15_IRQHandler + + PUBWEAK GPDMA1_Channel0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel0_IRQHandler + B GPDMA1_Channel0_IRQHandler + + PUBWEAK GPDMA1_Channel1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel1_IRQHandler + B GPDMA1_Channel1_IRQHandler + + PUBWEAK GPDMA1_Channel2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel2_IRQHandler + B GPDMA1_Channel2_IRQHandler + + PUBWEAK GPDMA1_Channel3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel3_IRQHandler + B GPDMA1_Channel3_IRQHandler + + PUBWEAK GPDMA1_Channel4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel4_IRQHandler + B GPDMA1_Channel4_IRQHandler + + PUBWEAK GPDMA1_Channel5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel5_IRQHandler + B GPDMA1_Channel5_IRQHandler + + PUBWEAK GPDMA1_Channel6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel6_IRQHandler + B GPDMA1_Channel6_IRQHandler + + PUBWEAK GPDMA1_Channel7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel7_IRQHandler + B GPDMA1_Channel7_IRQHandler + + PUBWEAK IWDG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +IWDG_IRQHandler + B IWDG_IRQHandler + + PUBWEAK ADC1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ADC1_IRQHandler + B ADC1_IRQHandler + + PUBWEAK DAC1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DAC1_IRQHandler + B DAC1_IRQHandler + + PUBWEAK FDCAN1_IT0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FDCAN1_IT0_IRQHandler + B FDCAN1_IT0_IRQHandler + + PUBWEAK FDCAN1_IT1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FDCAN1_IT1_IRQHandler + B FDCAN1_IT1_IRQHandler + + PUBWEAK TIM1_BRK_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_BRK_IRQHandler + B TIM1_BRK_IRQHandler + + PUBWEAK TIM1_UP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_UP_IRQHandler + B TIM1_UP_IRQHandler + + PUBWEAK TIM1_TRG_COM_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_TRG_COM_IRQHandler + B TIM1_TRG_COM_IRQHandler + + PUBWEAK TIM1_CC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_CC_IRQHandler + B TIM1_CC_IRQHandler + + PUBWEAK TIM2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM2_IRQHandler + B TIM2_IRQHandler + + PUBWEAK TIM3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM3_IRQHandler + B TIM3_IRQHandler + + PUBWEAK TIM4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM4_IRQHandler + B TIM4_IRQHandler + + PUBWEAK TIM5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM5_IRQHandler + B TIM5_IRQHandler + + PUBWEAK TIM6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM6_IRQHandler + B TIM6_IRQHandler + + PUBWEAK TIM7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM7_IRQHandler + B TIM7_IRQHandler + + PUBWEAK I2C1_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_EV_IRQHandler + B I2C1_EV_IRQHandler + + PUBWEAK I2C1_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_ER_IRQHandler + B I2C1_ER_IRQHandler + + PUBWEAK I2C2_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C2_EV_IRQHandler + B I2C2_EV_IRQHandler + + PUBWEAK I2C2_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C2_ER_IRQHandler + B I2C2_ER_IRQHandler + + PUBWEAK SPI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI1_IRQHandler + B SPI1_IRQHandler + + PUBWEAK SPI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI2_IRQHandler + B SPI2_IRQHandler + + PUBWEAK SPI3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI3_IRQHandler + B SPI3_IRQHandler + + PUBWEAK USART1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART1_IRQHandler + B USART1_IRQHandler + + PUBWEAK USART2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART2_IRQHandler + B USART2_IRQHandler + + PUBWEAK USART3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART3_IRQHandler + B USART3_IRQHandler + + PUBWEAK UART4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART4_IRQHandler + B UART4_IRQHandler + + PUBWEAK UART5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART5_IRQHandler + B UART5_IRQHandler + + PUBWEAK LPUART1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPUART1_IRQHandler + B LPUART1_IRQHandler + + PUBWEAK LPTIM1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM1_IRQHandler + B LPTIM1_IRQHandler + + PUBWEAK TIM8_BRK_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM8_BRK_IRQHandler + B TIM8_BRK_IRQHandler + + PUBWEAK TIM8_UP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM8_UP_IRQHandler + B TIM8_UP_IRQHandler + + PUBWEAK TIM8_TRG_COM_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM8_TRG_COM_IRQHandler + B TIM8_TRG_COM_IRQHandler + + PUBWEAK TIM8_CC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM8_CC_IRQHandler + B TIM8_CC_IRQHandler + + PUBWEAK ADC2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ADC2_IRQHandler + B ADC2_IRQHandler + + PUBWEAK LPTIM2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM2_IRQHandler + B LPTIM2_IRQHandler + + PUBWEAK TIM15_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM15_IRQHandler + B TIM15_IRQHandler + + PUBWEAK TIM16_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM16_IRQHandler + B TIM16_IRQHandler + + PUBWEAK TIM17_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM17_IRQHandler + B TIM17_IRQHandler + + PUBWEAK USB_DRD_FS_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USB_DRD_FS_IRQHandler + B USB_DRD_FS_IRQHandler + + PUBWEAK CRS_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CRS_IRQHandler + B CRS_IRQHandler + + PUBWEAK UCPD1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UCPD1_IRQHandler + B UCPD1_IRQHandler + + PUBWEAK FMC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FMC_IRQHandler + B FMC_IRQHandler + + PUBWEAK OCTOSPI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +OCTOSPI1_IRQHandler + B OCTOSPI1_IRQHandler + + PUBWEAK SDMMC1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SDMMC1_IRQHandler + B SDMMC1_IRQHandler + + PUBWEAK I2C3_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C3_EV_IRQHandler + B I2C3_EV_IRQHandler + + PUBWEAK I2C3_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C3_ER_IRQHandler + B I2C3_ER_IRQHandler + + PUBWEAK SPI4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI4_IRQHandler + B SPI4_IRQHandler + + PUBWEAK SPI5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI5_IRQHandler + B SPI5_IRQHandler + + PUBWEAK SPI6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI6_IRQHandler + B SPI6_IRQHandler + + PUBWEAK USART6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART6_IRQHandler + B USART6_IRQHandler + + PUBWEAK USART10_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART10_IRQHandler + B USART10_IRQHandler + + PUBWEAK USART11_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART11_IRQHandler + B USART11_IRQHandler + + PUBWEAK SAI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SAI1_IRQHandler + B SAI1_IRQHandler + + PUBWEAK SAI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SAI2_IRQHandler + B SAI2_IRQHandler + + PUBWEAK GPDMA2_Channel0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel0_IRQHandler + B GPDMA2_Channel0_IRQHandler + + PUBWEAK GPDMA2_Channel1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel1_IRQHandler + B GPDMA2_Channel1_IRQHandler + + PUBWEAK GPDMA2_Channel2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel2_IRQHandler + B GPDMA2_Channel2_IRQHandler + + PUBWEAK GPDMA2_Channel3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel3_IRQHandler + B GPDMA2_Channel3_IRQHandler + + PUBWEAK GPDMA2_Channel4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel4_IRQHandler + B GPDMA2_Channel4_IRQHandler + + PUBWEAK GPDMA2_Channel5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel5_IRQHandler + B GPDMA2_Channel5_IRQHandler + + PUBWEAK GPDMA2_Channel6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel6_IRQHandler + B GPDMA2_Channel6_IRQHandler + + PUBWEAK GPDMA2_Channel7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel7_IRQHandler + B GPDMA2_Channel7_IRQHandler + + PUBWEAK UART7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART7_IRQHandler + B UART7_IRQHandler + + PUBWEAK UART8_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART8_IRQHandler + B UART8_IRQHandler + + PUBWEAK UART9_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART9_IRQHandler + B UART9_IRQHandler + + PUBWEAK UART12_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART12_IRQHandler + B UART12_IRQHandler + + PUBWEAK FPU_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FPU_IRQHandler + B FPU_IRQHandler + + PUBWEAK ICACHE_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ICACHE_IRQHandler + B ICACHE_IRQHandler + + PUBWEAK DCACHE1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DCACHE1_IRQHandler + B DCACHE1_IRQHandler + + PUBWEAK DCMI_PSSI_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DCMI_PSSI_IRQHandler + B DCMI_PSSI_IRQHandler + + PUBWEAK CORDIC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CORDIC_IRQHandler + B CORDIC_IRQHandler + + PUBWEAK FMAC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FMAC_IRQHandler + B FMAC_IRQHandler + + PUBWEAK DTS_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DTS_IRQHandler + B DTS_IRQHandler + + PUBWEAK RNG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RNG_IRQHandler + B RNG_IRQHandler + + PUBWEAK HASH_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HASH_IRQHandler + B HASH_IRQHandler + + PUBWEAK CEC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CEC_IRQHandler + B CEC_IRQHandler + + PUBWEAK TIM12_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM12_IRQHandler + B TIM12_IRQHandler + + PUBWEAK TIM13_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM13_IRQHandler + B TIM13_IRQHandler + + PUBWEAK TIM14_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM14_IRQHandler + B TIM14_IRQHandler + + PUBWEAK I3C1_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I3C1_EV_IRQHandler + B I3C1_EV_IRQHandler + + PUBWEAK I3C1_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I3C1_ER_IRQHandler + B I3C1_ER_IRQHandler + + PUBWEAK I2C4_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C4_EV_IRQHandler + B I2C4_EV_IRQHandler + + PUBWEAK I2C4_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C4_ER_IRQHandler + B I2C4_ER_IRQHandler + + PUBWEAK LPTIM3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM3_IRQHandler + B LPTIM3_IRQHandler + + PUBWEAK LPTIM4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM4_IRQHandler + B LPTIM4_IRQHandler + + PUBWEAK LPTIM5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM5_IRQHandler + B LPTIM5_IRQHandler + + PUBWEAK LPTIM6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM6_IRQHandler + B LPTIM6_IRQHandler + + END diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/startup_stm32h563xx.s b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/startup_stm32h563xx.s new file mode 100644 index 0000000000..449a47b064 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/startup_stm32h563xx.s @@ -0,0 +1,912 @@ +;******************************************************************************** +;* File Name : startup_stm32h563xx.s +;* Author : MCD Application Team +;* Description : STM32H563xx Non Crypto Devices vector +;* This module performs: +;* - Set the initial SP +;* - Set the initial PC == _iar_program_start, +;* - Set the vector table entries with the exceptions ISR +;* address. +;* - Branches to main in the C library (which eventually +;* calls main()). +;* After Reset the Cortex-M33 processor is in Thread mode, +;* priority is Privileged, and the Stack is set to Main. +;******************************************************************************** +;* @attention +;* +;* Copyright (c) 2023 STMicroelectronics. +;* All rights reserved. +;* +;* This software is licensed under terms that can be found in the LICENSE file +;* in the root directory of this software component. +;* If no LICENSE file comes with this software, it is provided AS-IS. +;* +;******************************************************************************* +; +; +; The modules in this file are included in the libraries, and may be replaced +; by any user-defined modules that define the PUBLIC symbol _program_start or +; a user defined start symbol. +; To override the cstartup defined in the library, simply add your modified +; version to the workbench project. +; +; The vector table is normally located at address 0. +; When debugging in RAM, it can be located in RAM, aligned to at least 2^6. +; The name "__vector_table" has special meaning for C-SPY: +; it is where the SP start value is found, and the NVIC vector +; table register (VTOR) is initialized to this address if != 0. +; +; Cortex-M version +; + + MODULE ?cstartup + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN SystemInit + PUBLIC __vector_table + PUBLIC __Vectors + PUBLIC __Vectors_End + PUBLIC __Vectors_Size + + DATA +__vector_table + DCD sfe(CSTACK) + DCD Reset_Handler ; Reset Handler + + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD SecureFault_Handler ; Secure Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WWDG_IRQHandler ; Window WatchDog + DCD PVD_AVD_IRQHandler ; PVD/AVD through EXTI Line detection Interrupt + DCD RTC_IRQHandler ; RTC non-secure interrupt + DCD RTC_S_IRQHandler ; RTC secure interrupt + DCD TAMP_IRQHandler ; Tamper non-secure interrupt + DCD RAMCFG_IRQHandler ; RAMCFG global + DCD FLASH_IRQHandler ; FLASH non-secure global interrupt + DCD FLASH_S_IRQHandler ; FLASH secure global interrupt + DCD GTZC_IRQHandler ; Global TrustZone Controller interrupt + DCD RCC_IRQHandler ; RCC non-secure global interrupt + DCD RCC_S_IRQHandler ; RCC secure global interrupt + DCD EXTI0_IRQHandler ; EXTI Line0 interrupt + DCD EXTI1_IRQHandler ; EXTI Line1 interrupt + DCD EXTI2_IRQHandler ; EXTI Line2 interrupt + DCD EXTI3_IRQHandler ; EXTI Line3 interrupt + DCD EXTI4_IRQHandler ; EXTI Line4 interrupt + DCD EXTI5_IRQHandler ; EXTI Line5 interrupt + DCD EXTI6_IRQHandler ; EXTI Line6 interrupt + DCD EXTI7_IRQHandler ; EXTI Line7 interrupt + DCD EXTI8_IRQHandler ; EXTI Line8 interrupt + DCD EXTI9_IRQHandler ; EXTI Line9 interrupt + DCD EXTI10_IRQHandler ; EXTI Line10 interrupt + DCD EXTI11_IRQHandler ; EXTI Line11 interrupt + DCD EXTI12_IRQHandler ; EXTI Line12 interrupt + DCD EXTI13_IRQHandler ; EXTI Line13 interrupt + DCD EXTI14_IRQHandler ; EXTI Line14 interrupt + DCD EXTI15_IRQHandler ; EXTI Line15 interrupt + DCD GPDMA1_Channel0_IRQHandler ; GPDMA1 Channel 0 global interrupt + DCD GPDMA1_Channel1_IRQHandler ; GPDMA1 Channel 1 global interrupt + DCD GPDMA1_Channel2_IRQHandler ; GPDMA1 Channel 2 global interrupt + DCD GPDMA1_Channel3_IRQHandler ; GPDMA1 Channel 3 global interrupt + DCD GPDMA1_Channel4_IRQHandler ; GPDMA1 Channel 4 global interrupt + DCD GPDMA1_Channel5_IRQHandler ; GPDMA1 Channel 5 global interrupt + DCD GPDMA1_Channel6_IRQHandler ; GPDMA1 Channel 6 global interrupt + DCD GPDMA1_Channel7_IRQHandler ; GPDMA1 Channel 7 global interrupt + DCD IWDG_IRQHandler ; IWDG global interrupt + DCD 0 ; Reserved + DCD ADC1_IRQHandler ; ADC1 global interrupt + DCD DAC1_IRQHandler ; DAC1 global interrupt + DCD FDCAN1_IT0_IRQHandler ; FDCAN1 interrupt 0 + DCD FDCAN1_IT1_IRQHandler ; FDCAN1 interrupt 1 + DCD TIM1_BRK_IRQHandler ; TIM1 Break interrupt + DCD TIM1_UP_IRQHandler ; TIM1 Update interrupt + DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation interrupt + DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare interrupt + DCD TIM2_IRQHandler ; TIM2 global interrupt + DCD TIM3_IRQHandler ; TIM3 global interrupt + DCD TIM4_IRQHandler ; TIM4 global interrupt + DCD TIM5_IRQHandler ; TIM5 global interrupt + DCD TIM6_IRQHandler ; TIM6 global interrupt + DCD TIM7_IRQHandler ; TIM7 global interrupt + DCD I2C1_EV_IRQHandler ; I2C1 Event interrupt + DCD I2C1_ER_IRQHandler ; I2C1 Error interrupt + DCD I2C2_EV_IRQHandler ; I2C2 Event interrupt + DCD I2C2_ER_IRQHandler ; I2C2 Error interrupt + DCD SPI1_IRQHandler ; SPI1 global interrupt + DCD SPI2_IRQHandler ; SPI2 global interrupt + DCD SPI3_IRQHandler ; SPI3 global interrupt + DCD USART1_IRQHandler ; USART1 global interrupt + DCD USART2_IRQHandler ; USART2 global interrupt + DCD USART3_IRQHandler ; USART3 global interrupt + DCD UART4_IRQHandler ; UART4 global interrupt + DCD UART5_IRQHandler ; UART5 global interrupt + DCD LPUART1_IRQHandler ; LPUART1 global interrupt + DCD LPTIM1_IRQHandler ; LPTIM1 global interrupt + DCD TIM8_BRK_IRQHandler ; TIM8 Break interrupt + DCD TIM8_UP_IRQHandler ; TIM8 Update interrupt + DCD TIM8_TRG_COM_IRQHandler ; TIM8 Trigger and Commutation interrupt + DCD TIM8_CC_IRQHandler ; TIM8 Capture Compare interrupt + DCD ADC2_IRQHandler ; ADC2 global interrupt + DCD LPTIM2_IRQHandler ; LPTIM2 global interrupt + DCD TIM15_IRQHandler ; TIM15 global interrupt + DCD TIM16_IRQHandler ; TIM16 global interrupt + DCD TIM17_IRQHandler ; TIM17 global interrupt + DCD USB_DRD_FS_IRQHandler ; USB DRD FS global interrupt + DCD CRS_IRQHandler ; CRS global interrupt + DCD UCPD1_IRQHandler ; UCPD1 global interrupt + DCD FMC_IRQHandler ; FMC global interrupt + DCD OCTOSPI1_IRQHandler ; OctoSPI1 global interrupt + DCD SDMMC1_IRQHandler ; SDMMC1 global interrupt + DCD I2C3_EV_IRQHandler ; I2C2 Event interrupt + DCD I2C3_ER_IRQHandler ; I2C2 Error interrupt + DCD SPI4_IRQHandler ; SPI4 global interrupt + DCD SPI5_IRQHandler ; SPI5 global interrupt + DCD SPI6_IRQHandler ; SPI6 global interrupt + DCD USART6_IRQHandler ; USART6 global interrupt + DCD USART10_IRQHandler ; USART10 global interrupt + DCD USART11_IRQHandler ; USART11 global interrupt + DCD SAI1_IRQHandler ; Serial Audio Interface 1 global interrupt + DCD SAI2_IRQHandler ; Serial Audio Interface 2 global interrupt + DCD GPDMA2_Channel0_IRQHandler ; GPDMA2 Channel 0 global interrupt + DCD GPDMA2_Channel1_IRQHandler ; GPDMA2 Channel 1 global interrupt + DCD GPDMA2_Channel2_IRQHandler ; GPDMA2 Channel 2 global interrupt + DCD GPDMA2_Channel3_IRQHandler ; GPDMA2 Channel 3 global interrupt + DCD GPDMA2_Channel4_IRQHandler ; GPDMA2 Channel 4 global interrupt + DCD GPDMA2_Channel5_IRQHandler ; GPDMA2 Channel 5 global interrupt + DCD GPDMA2_Channel6_IRQHandler ; GPDMA2 Channel 6 global interrupt + DCD GPDMA2_Channel7_IRQHandler ; GPDMA2 Channel 7 global interrupt + DCD UART7_IRQHandler ; UART7 global interrupt + DCD UART8_IRQHandler ; UART8 global interrupt + DCD UART9_IRQHandler ; UART9 global interrupt + DCD UART12_IRQHandler ; UART12 global interrupt + DCD SDMMC2_IRQHandler ; SDMMC2 global interrupt + DCD FPU_IRQHandler ; FPU global interrupt + DCD ICACHE_IRQHandler ; Instruction cache global interrupt + DCD DCACHE1_IRQHandler ; DCACHE1 global interrupt + DCD ETH_IRQHandler ; Ethernet global interrupt + DCD ETH_WKUP_IRQHandler ; Ethernet Wakeup global interrupt + DCD DCMI_PSSI_IRQHandler ; DCMI PSSI global interrupt + DCD FDCAN2_IT0_IRQHandler ; FDCAN2 interrupt 0 + DCD FDCAN2_IT1_IRQHandler ; FDCAN2 interrupt 1 + DCD CORDIC_IRQHandler ; CORDIC global interrupt + DCD FMAC_IRQHandler ; FMAC global interrupt + DCD DTS_IRQHandler ; DTS global interrupt + DCD RNG_IRQHandler ; RNG global interrupt + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD HASH_IRQHandler ; HASH global interrupt + DCD 0 ; Reserved + DCD CEC_IRQHandler ; CEC global interrupt + DCD TIM12_IRQHandler ; TIM12 global interrupt + DCD TIM13_IRQHandler ; TIM13 global interrupt + DCD TIM14_IRQHandler ; TIM14 global interrupt + DCD I3C1_EV_IRQHandler ; I3C1 Event interrupt + DCD I3C1_ER_IRQHandler ; I3C1 Error interrupt + DCD I2C4_EV_IRQHandler ; I2C4 Event interrupt + DCD I2C4_ER_IRQHandler ; I2C4 Error interrupt + DCD LPTIM3_IRQHandler ; LPTIM3 global interrupt + DCD LPTIM4_IRQHandler ; LPTIM4 global interrupt + DCD LPTIM5_IRQHandler ; LPTIM5 global interrupt + DCD LPTIM6_IRQHandler ; LPTIM6 global interrupt + +__Vectors_End + +__Vectors EQU __vector_table +__Vectors_Size EQU __Vectors_End - __Vectors + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + PUBWEAK Reset_Handler + SECTION .text:CODE:NOROOT:REORDER(2) +Reset_Handler + LDR R0, =SystemInit + BLX R0 + LDR R0, =__iar_program_start + BX R0 + + PUBWEAK NMI_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +NMI_Handler + B NMI_Handler + + PUBWEAK HardFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +HardFault_Handler + B HardFault_Handler + + PUBWEAK MemManage_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +MemManage_Handler + B MemManage_Handler + + PUBWEAK BusFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +BusFault_Handler + B BusFault_Handler + + PUBWEAK UsageFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +UsageFault_Handler + B UsageFault_Handler + + PUBWEAK SecureFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SecureFault_Handler + B SecureFault_Handler + + PUBWEAK SVC_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SVC_Handler + B SVC_Handler + + PUBWEAK DebugMon_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DebugMon_Handler + B DebugMon_Handler + + PUBWEAK PendSV_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +PendSV_Handler + B PendSV_Handler + + PUBWEAK SysTick_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SysTick_Handler + B SysTick_Handler + + PUBWEAK WWDG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +WWDG_IRQHandler + B WWDG_IRQHandler + + PUBWEAK PVD_AVD_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +PVD_AVD_IRQHandler + B PVD_AVD_IRQHandler + + PUBWEAK RTC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_IRQHandler + B RTC_IRQHandler + + PUBWEAK RTC_S_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_S_IRQHandler + B RTC_S_IRQHandler + + PUBWEAK TAMP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TAMP_IRQHandler + B TAMP_IRQHandler + + PUBWEAK RAMCFG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RAMCFG_IRQHandler + B RAMCFG_IRQHandler + + PUBWEAK FLASH_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FLASH_IRQHandler + B FLASH_IRQHandler + + PUBWEAK FLASH_S_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FLASH_S_IRQHandler + B FLASH_S_IRQHandler + + PUBWEAK GTZC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GTZC_IRQHandler + B GTZC_IRQHandler + + PUBWEAK RCC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RCC_IRQHandler + B RCC_IRQHandler + + PUBWEAK RCC_S_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RCC_S_IRQHandler + B RCC_S_IRQHandler + + PUBWEAK EXTI0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI0_IRQHandler + B EXTI0_IRQHandler + + PUBWEAK EXTI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI1_IRQHandler + B EXTI1_IRQHandler + + PUBWEAK EXTI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI2_IRQHandler + B EXTI2_IRQHandler + + PUBWEAK EXTI3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI3_IRQHandler + B EXTI3_IRQHandler + + PUBWEAK EXTI4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI4_IRQHandler + B EXTI4_IRQHandler + + PUBWEAK EXTI5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI5_IRQHandler + B EXTI5_IRQHandler + + PUBWEAK EXTI6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI6_IRQHandler + B EXTI6_IRQHandler + + PUBWEAK EXTI7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI7_IRQHandler + B EXTI7_IRQHandler + + PUBWEAK EXTI8_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI8_IRQHandler + B EXTI8_IRQHandler + + PUBWEAK EXTI9_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI9_IRQHandler + B EXTI9_IRQHandler + + PUBWEAK EXTI10_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI10_IRQHandler + B EXTI10_IRQHandler + + PUBWEAK EXTI11_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI11_IRQHandler + B EXTI11_IRQHandler + + PUBWEAK EXTI12_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI12_IRQHandler + B EXTI12_IRQHandler + + PUBWEAK EXTI13_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI13_IRQHandler + B EXTI13_IRQHandler + + PUBWEAK EXTI14_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI14_IRQHandler + B EXTI14_IRQHandler + + PUBWEAK EXTI15_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI15_IRQHandler + B EXTI15_IRQHandler + + PUBWEAK GPDMA1_Channel0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel0_IRQHandler + B GPDMA1_Channel0_IRQHandler + + PUBWEAK GPDMA1_Channel1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel1_IRQHandler + B GPDMA1_Channel1_IRQHandler + + PUBWEAK GPDMA1_Channel2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel2_IRQHandler + B GPDMA1_Channel2_IRQHandler + + PUBWEAK GPDMA1_Channel3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel3_IRQHandler + B GPDMA1_Channel3_IRQHandler + + PUBWEAK GPDMA1_Channel4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel4_IRQHandler + B GPDMA1_Channel4_IRQHandler + + PUBWEAK GPDMA1_Channel5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel5_IRQHandler + B GPDMA1_Channel5_IRQHandler + + PUBWEAK GPDMA1_Channel6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel6_IRQHandler + B GPDMA1_Channel6_IRQHandler + + PUBWEAK GPDMA1_Channel7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel7_IRQHandler + B GPDMA1_Channel7_IRQHandler + + PUBWEAK IWDG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +IWDG_IRQHandler + B IWDG_IRQHandler + + PUBWEAK ADC1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ADC1_IRQHandler + B ADC1_IRQHandler + + PUBWEAK DAC1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DAC1_IRQHandler + B DAC1_IRQHandler + + PUBWEAK FDCAN1_IT0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FDCAN1_IT0_IRQHandler + B FDCAN1_IT0_IRQHandler + + PUBWEAK FDCAN1_IT1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FDCAN1_IT1_IRQHandler + B FDCAN1_IT1_IRQHandler + + PUBWEAK TIM1_BRK_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_BRK_IRQHandler + B TIM1_BRK_IRQHandler + + PUBWEAK TIM1_UP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_UP_IRQHandler + B TIM1_UP_IRQHandler + + PUBWEAK TIM1_TRG_COM_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_TRG_COM_IRQHandler + B TIM1_TRG_COM_IRQHandler + + PUBWEAK TIM1_CC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_CC_IRQHandler + B TIM1_CC_IRQHandler + + PUBWEAK TIM2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM2_IRQHandler + B TIM2_IRQHandler + + PUBWEAK TIM3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM3_IRQHandler + B TIM3_IRQHandler + + PUBWEAK TIM4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM4_IRQHandler + B TIM4_IRQHandler + + PUBWEAK TIM5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM5_IRQHandler + B TIM5_IRQHandler + + PUBWEAK TIM6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM6_IRQHandler + B TIM6_IRQHandler + + PUBWEAK TIM7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM7_IRQHandler + B TIM7_IRQHandler + + PUBWEAK I2C1_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_EV_IRQHandler + B I2C1_EV_IRQHandler + + PUBWEAK I2C1_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_ER_IRQHandler + B I2C1_ER_IRQHandler + + PUBWEAK I2C2_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C2_EV_IRQHandler + B I2C2_EV_IRQHandler + + PUBWEAK I2C2_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C2_ER_IRQHandler + B I2C2_ER_IRQHandler + + PUBWEAK SPI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI1_IRQHandler + B SPI1_IRQHandler + + PUBWEAK SPI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI2_IRQHandler + B SPI2_IRQHandler + + PUBWEAK SPI3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI3_IRQHandler + B SPI3_IRQHandler + + PUBWEAK USART1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART1_IRQHandler + B USART1_IRQHandler + + PUBWEAK USART2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART2_IRQHandler + B USART2_IRQHandler + + PUBWEAK USART3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART3_IRQHandler + B USART3_IRQHandler + + PUBWEAK UART4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART4_IRQHandler + B UART4_IRQHandler + + PUBWEAK UART5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART5_IRQHandler + B UART5_IRQHandler + + PUBWEAK LPUART1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPUART1_IRQHandler + B LPUART1_IRQHandler + + PUBWEAK LPTIM1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM1_IRQHandler + B LPTIM1_IRQHandler + + PUBWEAK TIM8_BRK_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM8_BRK_IRQHandler + B TIM8_BRK_IRQHandler + + PUBWEAK TIM8_UP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM8_UP_IRQHandler + B TIM8_UP_IRQHandler + + PUBWEAK TIM8_TRG_COM_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM8_TRG_COM_IRQHandler + B TIM8_TRG_COM_IRQHandler + + PUBWEAK TIM8_CC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM8_CC_IRQHandler + B TIM8_CC_IRQHandler + + PUBWEAK ADC2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ADC2_IRQHandler + B ADC2_IRQHandler + + PUBWEAK LPTIM2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM2_IRQHandler + B LPTIM2_IRQHandler + + PUBWEAK TIM15_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM15_IRQHandler + B TIM15_IRQHandler + + PUBWEAK TIM16_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM16_IRQHandler + B TIM16_IRQHandler + + PUBWEAK TIM17_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM17_IRQHandler + B TIM17_IRQHandler + + PUBWEAK USB_DRD_FS_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USB_DRD_FS_IRQHandler + B USB_DRD_FS_IRQHandler + + PUBWEAK CRS_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CRS_IRQHandler + B CRS_IRQHandler + + PUBWEAK UCPD1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UCPD1_IRQHandler + B UCPD1_IRQHandler + + PUBWEAK FMC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FMC_IRQHandler + B FMC_IRQHandler + + PUBWEAK OCTOSPI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +OCTOSPI1_IRQHandler + B OCTOSPI1_IRQHandler + + PUBWEAK SDMMC1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SDMMC1_IRQHandler + B SDMMC1_IRQHandler + + PUBWEAK I2C3_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C3_EV_IRQHandler + B I2C3_EV_IRQHandler + + PUBWEAK I2C3_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C3_ER_IRQHandler + B I2C3_ER_IRQHandler + + PUBWEAK SPI4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI4_IRQHandler + B SPI4_IRQHandler + + PUBWEAK SPI5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI5_IRQHandler + B SPI5_IRQHandler + + PUBWEAK SPI6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI6_IRQHandler + B SPI6_IRQHandler + + PUBWEAK USART6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART6_IRQHandler + B USART6_IRQHandler + + PUBWEAK USART10_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART10_IRQHandler + B USART10_IRQHandler + + PUBWEAK USART11_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART11_IRQHandler + B USART11_IRQHandler + + PUBWEAK SAI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SAI1_IRQHandler + B SAI1_IRQHandler + + PUBWEAK SAI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SAI2_IRQHandler + B SAI2_IRQHandler + + PUBWEAK GPDMA2_Channel0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel0_IRQHandler + B GPDMA2_Channel0_IRQHandler + + PUBWEAK GPDMA2_Channel1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel1_IRQHandler + B GPDMA2_Channel1_IRQHandler + + PUBWEAK GPDMA2_Channel2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel2_IRQHandler + B GPDMA2_Channel2_IRQHandler + + PUBWEAK GPDMA2_Channel3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel3_IRQHandler + B GPDMA2_Channel3_IRQHandler + + PUBWEAK GPDMA2_Channel4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel4_IRQHandler + B GPDMA2_Channel4_IRQHandler + + PUBWEAK GPDMA2_Channel5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel5_IRQHandler + B GPDMA2_Channel5_IRQHandler + + PUBWEAK GPDMA2_Channel6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel6_IRQHandler + B GPDMA2_Channel6_IRQHandler + + PUBWEAK GPDMA2_Channel7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel7_IRQHandler + B GPDMA2_Channel7_IRQHandler + + PUBWEAK UART7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART7_IRQHandler + B UART7_IRQHandler + + PUBWEAK UART8_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART8_IRQHandler + B UART8_IRQHandler + + PUBWEAK UART9_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART9_IRQHandler + B UART9_IRQHandler + + PUBWEAK UART12_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART12_IRQHandler + B UART12_IRQHandler + + PUBWEAK SDMMC2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SDMMC2_IRQHandler + B SDMMC2_IRQHandler + + PUBWEAK FPU_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FPU_IRQHandler + B FPU_IRQHandler + + PUBWEAK ICACHE_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ICACHE_IRQHandler + B ICACHE_IRQHandler + + PUBWEAK DCACHE1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DCACHE1_IRQHandler + B DCACHE1_IRQHandler + + PUBWEAK ETH_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ETH_IRQHandler + B ETH_IRQHandler + + PUBWEAK ETH_WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ETH_WKUP_IRQHandler + B ETH_WKUP_IRQHandler + + PUBWEAK DCMI_PSSI_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DCMI_PSSI_IRQHandler + B DCMI_PSSI_IRQHandler + + PUBWEAK FDCAN2_IT0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FDCAN2_IT0_IRQHandler + B FDCAN2_IT0_IRQHandler + + PUBWEAK FDCAN2_IT1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FDCAN2_IT1_IRQHandler + B FDCAN2_IT1_IRQHandler + + PUBWEAK CORDIC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CORDIC_IRQHandler + B CORDIC_IRQHandler + + PUBWEAK FMAC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FMAC_IRQHandler + B FMAC_IRQHandler + + PUBWEAK DTS_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DTS_IRQHandler + B DTS_IRQHandler + + PUBWEAK RNG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RNG_IRQHandler + B RNG_IRQHandler + + PUBWEAK HASH_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HASH_IRQHandler + B HASH_IRQHandler + + PUBWEAK CEC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CEC_IRQHandler + B CEC_IRQHandler + + PUBWEAK TIM12_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM12_IRQHandler + B TIM12_IRQHandler + + PUBWEAK TIM13_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM13_IRQHandler + B TIM13_IRQHandler + + PUBWEAK TIM14_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM14_IRQHandler + B TIM14_IRQHandler + + PUBWEAK I3C1_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I3C1_EV_IRQHandler + B I3C1_EV_IRQHandler + + PUBWEAK I3C1_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I3C1_ER_IRQHandler + B I3C1_ER_IRQHandler + + PUBWEAK I2C4_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C4_EV_IRQHandler + B I2C4_EV_IRQHandler + + PUBWEAK I2C4_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C4_ER_IRQHandler + B I2C4_ER_IRQHandler + + PUBWEAK LPTIM3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM3_IRQHandler + B LPTIM3_IRQHandler + + PUBWEAK LPTIM4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM4_IRQHandler + B LPTIM4_IRQHandler + + PUBWEAK LPTIM5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM5_IRQHandler + B LPTIM5_IRQHandler + + PUBWEAK LPTIM6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM6_IRQHandler + B LPTIM6_IRQHandler + + END diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/startup_stm32h573xx.s b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/startup_stm32h573xx.s new file mode 100644 index 0000000000..92f1de0860 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/startup_stm32h573xx.s @@ -0,0 +1,932 @@ +;******************************************************************************** +;* File Name : startup_stm32h573xx.s +;* Author : MCD Application Team +;* Description : STM32H573xx Crypto Devices vector +;* This module performs: +;* - Set the initial SP +;* - Set the initial PC == _iar_program_start, +;* - Set the vector table entries with the exceptions ISR +;* address. +;* - Branches to main in the C library (which eventually +;* calls main()). +;* After Reset the Cortex-M33 processor is in Thread mode, +;* priority is Privileged, and the Stack is set to Main. +;******************************************************************************** +;* @attention +;* +;* Copyright (c) 2023 STMicroelectronics. +;* All rights reserved. +;* +;* This software is licensed under terms that can be found in the LICENSE file +;* in the root directory of this software component. +;* If no LICENSE file comes with this software, it is provided AS-IS. +;* +;******************************************************************************* +; +; +; The modules in this file are included in the libraries, and may be replaced +; by any user-defined modules that define the PUBLIC symbol _program_start or +; a user defined start symbol. +; To override the cstartup defined in the library, simply add your modified +; version to the workbench project. +; +; The vector table is normally located at address 0. +; When debugging in RAM, it can be located in RAM, aligned to at least 2^6. +; The name "__vector_table" has special meaning for C-SPY: +; it is where the SP start value is found, and the NVIC vector +; table register (VTOR) is initialized to this address if != 0. +; +; Cortex-M version +; + + MODULE ?cstartup + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN SystemInit + PUBLIC __vector_table + PUBLIC __Vectors + PUBLIC __Vectors_End + PUBLIC __Vectors_Size + + DATA +__vector_table + DCD sfe(CSTACK) + DCD Reset_Handler ; Reset Handler + + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD SecureFault_Handler ; Secure Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WWDG_IRQHandler ; Window WatchDog + DCD PVD_AVD_IRQHandler ; PVD/AVD through EXTI Line detection Interrupt + DCD RTC_IRQHandler ; RTC non-secure interrupt + DCD RTC_S_IRQHandler ; RTC secure interrupt + DCD TAMP_IRQHandler ; Tamper non-secure interrupt + DCD RAMCFG_IRQHandler ; RAMCFG global + DCD FLASH_IRQHandler ; FLASH non-secure global interrupt + DCD FLASH_S_IRQHandler ; FLASH secure global interrupt + DCD GTZC_IRQHandler ; Global TrustZone Controller interrupt + DCD RCC_IRQHandler ; RCC non-secure global interrupt + DCD RCC_S_IRQHandler ; RCC secure global interrupt + DCD EXTI0_IRQHandler ; EXTI Line0 interrupt + DCD EXTI1_IRQHandler ; EXTI Line1 interrupt + DCD EXTI2_IRQHandler ; EXTI Line2 interrupt + DCD EXTI3_IRQHandler ; EXTI Line3 interrupt + DCD EXTI4_IRQHandler ; EXTI Line4 interrupt + DCD EXTI5_IRQHandler ; EXTI Line5 interrupt + DCD EXTI6_IRQHandler ; EXTI Line6 interrupt + DCD EXTI7_IRQHandler ; EXTI Line7 interrupt + DCD EXTI8_IRQHandler ; EXTI Line8 interrupt + DCD EXTI9_IRQHandler ; EXTI Line9 interrupt + DCD EXTI10_IRQHandler ; EXTI Line10 interrupt + DCD EXTI11_IRQHandler ; EXTI Line11 interrupt + DCD EXTI12_IRQHandler ; EXTI Line12 interrupt + DCD EXTI13_IRQHandler ; EXTI Line13 interrupt + DCD EXTI14_IRQHandler ; EXTI Line14 interrupt + DCD EXTI15_IRQHandler ; EXTI Line15 interrupt + DCD GPDMA1_Channel0_IRQHandler ; GPDMA1 Channel 0 global interrupt + DCD GPDMA1_Channel1_IRQHandler ; GPDMA1 Channel 1 global interrupt + DCD GPDMA1_Channel2_IRQHandler ; GPDMA1 Channel 2 global interrupt + DCD GPDMA1_Channel3_IRQHandler ; GPDMA1 Channel 3 global interrupt + DCD GPDMA1_Channel4_IRQHandler ; GPDMA1 Channel 4 global interrupt + DCD GPDMA1_Channel5_IRQHandler ; GPDMA1 Channel 5 global interrupt + DCD GPDMA1_Channel6_IRQHandler ; GPDMA1 Channel 6 global interrupt + DCD GPDMA1_Channel7_IRQHandler ; GPDMA1 Channel 7 global interrupt + DCD IWDG_IRQHandler ; IWDG global interrupt + DCD SAES_IRQHandler ; SAES global interrupt + DCD ADC1_IRQHandler ; ADC1 global interrupt + DCD DAC1_IRQHandler ; DAC1 global interrupt + DCD FDCAN1_IT0_IRQHandler ; FDCAN1 interrupt 0 + DCD FDCAN1_IT1_IRQHandler ; FDCAN1 interrupt 1 + DCD TIM1_BRK_IRQHandler ; TIM1 Break interrupt + DCD TIM1_UP_IRQHandler ; TIM1 Update interrupt + DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation interrupt + DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare interrupt + DCD TIM2_IRQHandler ; TIM2 global interrupt + DCD TIM3_IRQHandler ; TIM3 global interrupt + DCD TIM4_IRQHandler ; TIM4 global interrupt + DCD TIM5_IRQHandler ; TIM5 global interrupt + DCD TIM6_IRQHandler ; TIM6 global interrupt + DCD TIM7_IRQHandler ; TIM7 global interrupt + DCD I2C1_EV_IRQHandler ; I2C1 Event interrupt + DCD I2C1_ER_IRQHandler ; I2C1 Error interrupt + DCD I2C2_EV_IRQHandler ; I2C2 Event interrupt + DCD I2C2_ER_IRQHandler ; I2C2 Error interrupt + DCD SPI1_IRQHandler ; SPI1 global interrupt + DCD SPI2_IRQHandler ; SPI2 global interrupt + DCD SPI3_IRQHandler ; SPI3 global interrupt + DCD USART1_IRQHandler ; USART1 global interrupt + DCD USART2_IRQHandler ; USART2 global interrupt + DCD USART3_IRQHandler ; USART3 global interrupt + DCD UART4_IRQHandler ; UART4 global interrupt + DCD UART5_IRQHandler ; UART5 global interrupt + DCD LPUART1_IRQHandler ; LPUART1 global interrupt + DCD LPTIM1_IRQHandler ; LPTIM1 global interrupt + DCD TIM8_BRK_IRQHandler ; TIM8 Break interrupt + DCD TIM8_UP_IRQHandler ; TIM8 Update interrupt + DCD TIM8_TRG_COM_IRQHandler ; TIM8 Trigger and Commutation interrupt + DCD TIM8_CC_IRQHandler ; TIM8 Capture Compare interrupt + DCD ADC2_IRQHandler ; ADC2 global interrupt + DCD LPTIM2_IRQHandler ; LPTIM2 global interrupt + DCD TIM15_IRQHandler ; TIM15 global interrupt + DCD TIM16_IRQHandler ; TIM16 global interrupt + DCD TIM17_IRQHandler ; TIM17 global interrupt + DCD USB_DRD_FS_IRQHandler ; USB DRD FS global interrupt + DCD CRS_IRQHandler ; CRS global interrupt + DCD UCPD1_IRQHandler ; UCPD1 global interrupt + DCD FMC_IRQHandler ; FMC global interrupt + DCD OCTOSPI1_IRQHandler ; OctoSPI1 global interrupt + DCD SDMMC1_IRQHandler ; SDMMC1 global interrupt + DCD I2C3_EV_IRQHandler ; I2C2 Event interrupt + DCD I2C3_ER_IRQHandler ; I2C2 Error interrupt + DCD SPI4_IRQHandler ; SPI4 global interrupt + DCD SPI5_IRQHandler ; SPI5 global interrupt + DCD SPI6_IRQHandler ; SPI6 global interrupt + DCD USART6_IRQHandler ; USART6 global interrupt + DCD USART10_IRQHandler ; USART10 global interrupt + DCD USART11_IRQHandler ; USART11 global interrupt + DCD SAI1_IRQHandler ; Serial Audio Interface 1 global interrupt + DCD SAI2_IRQHandler ; Serial Audio Interface 2 global interrupt + DCD GPDMA2_Channel0_IRQHandler ; GPDMA2 Channel 0 global interrupt + DCD GPDMA2_Channel1_IRQHandler ; GPDMA2 Channel 1 global interrupt + DCD GPDMA2_Channel2_IRQHandler ; GPDMA2 Channel 2 global interrupt + DCD GPDMA2_Channel3_IRQHandler ; GPDMA2 Channel 3 global interrupt + DCD GPDMA2_Channel4_IRQHandler ; GPDMA2 Channel 4 global interrupt + DCD GPDMA2_Channel5_IRQHandler ; GPDMA2 Channel 5 global interrupt + DCD GPDMA2_Channel6_IRQHandler ; GPDMA2 Channel 6 global interrupt + DCD GPDMA2_Channel7_IRQHandler ; GPDMA2 Channel 7 global interrupt + DCD UART7_IRQHandler ; UART7 global interrupt + DCD UART8_IRQHandler ; UART8 global interrupt + DCD UART9_IRQHandler ; UART9 global interrupt + DCD UART12_IRQHandler ; UART12 global interrupt + DCD SDMMC2_IRQHandler ; SDMMC2 global interrupt + DCD FPU_IRQHandler ; FPU global interrupt + DCD ICACHE_IRQHandler ; Instruction cache global interrupt + DCD DCACHE1_IRQHandler ; DCACHE1 global interrupt + DCD ETH_IRQHandler ; Ethernet global interrupt + DCD ETH_WKUP_IRQHandler ; Ethernet Wakeup global interrupt + DCD DCMI_PSSI_IRQHandler ; DCMI PSSI global interrupt + DCD FDCAN2_IT0_IRQHandler ; FDCAN2 interrupt 0 + DCD FDCAN2_IT1_IRQHandler ; FDCAN2 interrupt 1 + DCD CORDIC_IRQHandler ; CORDIC global interrupt + DCD FMAC_IRQHandler ; FMAC global interrupt + DCD DTS_IRQHandler ; DTS global interrupt + DCD RNG_IRQHandler ; RNG global interrupt + DCD OTFDEC1_IRQHandler ; OTFDEC1 global interrupt + DCD AES_IRQHandler ; AES global interrupt + DCD HASH_IRQHandler ; HASH global interrupt + DCD PKA_IRQHandler ; PKA global interrupt + DCD CEC_IRQHandler ; CEC global interrupt + DCD TIM12_IRQHandler ; TIM12 global interrupt + DCD TIM13_IRQHandler ; TIM13 global interrupt + DCD TIM14_IRQHandler ; TIM14 global interrupt + DCD I3C1_EV_IRQHandler ; I3C1 Event interrupt + DCD I3C1_ER_IRQHandler ; I3C1 Error interrupt + DCD I2C4_EV_IRQHandler ; I2C4 Event interrupt + DCD I2C4_ER_IRQHandler ; I2C4 Error interrupt + DCD LPTIM3_IRQHandler ; LPTIM3 global interrupt + DCD LPTIM4_IRQHandler ; LPTIM4 global interrupt + DCD LPTIM5_IRQHandler ; LPTIM5 global interrupt + DCD LPTIM6_IRQHandler ; LPTIM6 global interrupt + +__Vectors_End + +__Vectors EQU __vector_table +__Vectors_Size EQU __Vectors_End - __Vectors + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + PUBWEAK Reset_Handler + SECTION .text:CODE:NOROOT:REORDER(2) +Reset_Handler + LDR R0, =SystemInit + BLX R0 + LDR R0, =__iar_program_start + BX R0 + + PUBWEAK NMI_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +NMI_Handler + B NMI_Handler + + PUBWEAK HardFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +HardFault_Handler + B HardFault_Handler + + PUBWEAK MemManage_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +MemManage_Handler + B MemManage_Handler + + PUBWEAK BusFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +BusFault_Handler + B BusFault_Handler + + PUBWEAK UsageFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +UsageFault_Handler + B UsageFault_Handler + + PUBWEAK SecureFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SecureFault_Handler + B SecureFault_Handler + + PUBWEAK SVC_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SVC_Handler + B SVC_Handler + + PUBWEAK DebugMon_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DebugMon_Handler + B DebugMon_Handler + + PUBWEAK PendSV_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +PendSV_Handler + B PendSV_Handler + + PUBWEAK SysTick_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SysTick_Handler + B SysTick_Handler + + PUBWEAK WWDG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +WWDG_IRQHandler + B WWDG_IRQHandler + + PUBWEAK PVD_AVD_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +PVD_AVD_IRQHandler + B PVD_AVD_IRQHandler + + PUBWEAK RTC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_IRQHandler + B RTC_IRQHandler + + PUBWEAK RTC_S_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_S_IRQHandler + B RTC_S_IRQHandler + + PUBWEAK TAMP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TAMP_IRQHandler + B TAMP_IRQHandler + + PUBWEAK RAMCFG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RAMCFG_IRQHandler + B RAMCFG_IRQHandler + + PUBWEAK FLASH_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FLASH_IRQHandler + B FLASH_IRQHandler + + PUBWEAK FLASH_S_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FLASH_S_IRQHandler + B FLASH_S_IRQHandler + + PUBWEAK GTZC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GTZC_IRQHandler + B GTZC_IRQHandler + + PUBWEAK RCC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RCC_IRQHandler + B RCC_IRQHandler + + PUBWEAK RCC_S_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RCC_S_IRQHandler + B RCC_S_IRQHandler + + PUBWEAK EXTI0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI0_IRQHandler + B EXTI0_IRQHandler + + PUBWEAK EXTI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI1_IRQHandler + B EXTI1_IRQHandler + + PUBWEAK EXTI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI2_IRQHandler + B EXTI2_IRQHandler + + PUBWEAK EXTI3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI3_IRQHandler + B EXTI3_IRQHandler + + PUBWEAK EXTI4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI4_IRQHandler + B EXTI4_IRQHandler + + PUBWEAK EXTI5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI5_IRQHandler + B EXTI5_IRQHandler + + PUBWEAK EXTI6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI6_IRQHandler + B EXTI6_IRQHandler + + PUBWEAK EXTI7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI7_IRQHandler + B EXTI7_IRQHandler + + PUBWEAK EXTI8_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI8_IRQHandler + B EXTI8_IRQHandler + + PUBWEAK EXTI9_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI9_IRQHandler + B EXTI9_IRQHandler + + PUBWEAK EXTI10_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI10_IRQHandler + B EXTI10_IRQHandler + + PUBWEAK EXTI11_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI11_IRQHandler + B EXTI11_IRQHandler + + PUBWEAK EXTI12_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI12_IRQHandler + B EXTI12_IRQHandler + + PUBWEAK EXTI13_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI13_IRQHandler + B EXTI13_IRQHandler + + PUBWEAK EXTI14_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI14_IRQHandler + B EXTI14_IRQHandler + + PUBWEAK EXTI15_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI15_IRQHandler + B EXTI15_IRQHandler + + PUBWEAK GPDMA1_Channel0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel0_IRQHandler + B GPDMA1_Channel0_IRQHandler + + PUBWEAK GPDMA1_Channel1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel1_IRQHandler + B GPDMA1_Channel1_IRQHandler + + PUBWEAK GPDMA1_Channel2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel2_IRQHandler + B GPDMA1_Channel2_IRQHandler + + PUBWEAK GPDMA1_Channel3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel3_IRQHandler + B GPDMA1_Channel3_IRQHandler + + PUBWEAK GPDMA1_Channel4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel4_IRQHandler + B GPDMA1_Channel4_IRQHandler + + PUBWEAK GPDMA1_Channel5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel5_IRQHandler + B GPDMA1_Channel5_IRQHandler + + PUBWEAK GPDMA1_Channel6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel6_IRQHandler + B GPDMA1_Channel6_IRQHandler + + PUBWEAK GPDMA1_Channel7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel7_IRQHandler + B GPDMA1_Channel7_IRQHandler + + PUBWEAK IWDG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +IWDG_IRQHandler + B IWDG_IRQHandler + + PUBWEAK SAES_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SAES_IRQHandler + B SAES_IRQHandler + + PUBWEAK ADC1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ADC1_IRQHandler + B ADC1_IRQHandler + + PUBWEAK DAC1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DAC1_IRQHandler + B DAC1_IRQHandler + + PUBWEAK FDCAN1_IT0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FDCAN1_IT0_IRQHandler + B FDCAN1_IT0_IRQHandler + + PUBWEAK FDCAN1_IT1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FDCAN1_IT1_IRQHandler + B FDCAN1_IT1_IRQHandler + + PUBWEAK TIM1_BRK_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_BRK_IRQHandler + B TIM1_BRK_IRQHandler + + PUBWEAK TIM1_UP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_UP_IRQHandler + B TIM1_UP_IRQHandler + + PUBWEAK TIM1_TRG_COM_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_TRG_COM_IRQHandler + B TIM1_TRG_COM_IRQHandler + + PUBWEAK TIM1_CC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_CC_IRQHandler + B TIM1_CC_IRQHandler + + PUBWEAK TIM2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM2_IRQHandler + B TIM2_IRQHandler + + PUBWEAK TIM3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM3_IRQHandler + B TIM3_IRQHandler + + PUBWEAK TIM4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM4_IRQHandler + B TIM4_IRQHandler + + PUBWEAK TIM5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM5_IRQHandler + B TIM5_IRQHandler + + PUBWEAK TIM6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM6_IRQHandler + B TIM6_IRQHandler + + PUBWEAK TIM7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM7_IRQHandler + B TIM7_IRQHandler + + PUBWEAK I2C1_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_EV_IRQHandler + B I2C1_EV_IRQHandler + + PUBWEAK I2C1_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_ER_IRQHandler + B I2C1_ER_IRQHandler + + PUBWEAK I2C2_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C2_EV_IRQHandler + B I2C2_EV_IRQHandler + + PUBWEAK I2C2_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C2_ER_IRQHandler + B I2C2_ER_IRQHandler + + PUBWEAK SPI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI1_IRQHandler + B SPI1_IRQHandler + + PUBWEAK SPI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI2_IRQHandler + B SPI2_IRQHandler + + PUBWEAK SPI3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI3_IRQHandler + B SPI3_IRQHandler + + PUBWEAK USART1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART1_IRQHandler + B USART1_IRQHandler + + PUBWEAK USART2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART2_IRQHandler + B USART2_IRQHandler + + PUBWEAK USART3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART3_IRQHandler + B USART3_IRQHandler + + PUBWEAK UART4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART4_IRQHandler + B UART4_IRQHandler + + PUBWEAK UART5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART5_IRQHandler + B UART5_IRQHandler + + PUBWEAK LPUART1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPUART1_IRQHandler + B LPUART1_IRQHandler + + PUBWEAK LPTIM1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM1_IRQHandler + B LPTIM1_IRQHandler + + PUBWEAK TIM8_BRK_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM8_BRK_IRQHandler + B TIM8_BRK_IRQHandler + + PUBWEAK TIM8_UP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM8_UP_IRQHandler + B TIM8_UP_IRQHandler + + PUBWEAK TIM8_TRG_COM_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM8_TRG_COM_IRQHandler + B TIM8_TRG_COM_IRQHandler + + PUBWEAK TIM8_CC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM8_CC_IRQHandler + B TIM8_CC_IRQHandler + + PUBWEAK ADC2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ADC2_IRQHandler + B ADC2_IRQHandler + + PUBWEAK LPTIM2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM2_IRQHandler + B LPTIM2_IRQHandler + + PUBWEAK TIM15_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM15_IRQHandler + B TIM15_IRQHandler + + PUBWEAK TIM16_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM16_IRQHandler + B TIM16_IRQHandler + + PUBWEAK TIM17_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM17_IRQHandler + B TIM17_IRQHandler + + PUBWEAK USB_DRD_FS_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USB_DRD_FS_IRQHandler + B USB_DRD_FS_IRQHandler + + PUBWEAK CRS_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CRS_IRQHandler + B CRS_IRQHandler + + PUBWEAK UCPD1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UCPD1_IRQHandler + B UCPD1_IRQHandler + + PUBWEAK FMC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FMC_IRQHandler + B FMC_IRQHandler + + PUBWEAK OCTOSPI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +OCTOSPI1_IRQHandler + B OCTOSPI1_IRQHandler + + PUBWEAK SDMMC1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SDMMC1_IRQHandler + B SDMMC1_IRQHandler + + PUBWEAK I2C3_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C3_EV_IRQHandler + B I2C3_EV_IRQHandler + + PUBWEAK I2C3_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C3_ER_IRQHandler + B I2C3_ER_IRQHandler + + PUBWEAK SPI4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI4_IRQHandler + B SPI4_IRQHandler + + PUBWEAK SPI5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI5_IRQHandler + B SPI5_IRQHandler + + PUBWEAK SPI6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI6_IRQHandler + B SPI6_IRQHandler + + PUBWEAK USART6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART6_IRQHandler + B USART6_IRQHandler + + PUBWEAK USART10_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART10_IRQHandler + B USART10_IRQHandler + + PUBWEAK USART11_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART11_IRQHandler + B USART11_IRQHandler + + PUBWEAK SAI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SAI1_IRQHandler + B SAI1_IRQHandler + + PUBWEAK SAI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SAI2_IRQHandler + B SAI2_IRQHandler + + PUBWEAK GPDMA2_Channel0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel0_IRQHandler + B GPDMA2_Channel0_IRQHandler + + PUBWEAK GPDMA2_Channel1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel1_IRQHandler + B GPDMA2_Channel1_IRQHandler + + PUBWEAK GPDMA2_Channel2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel2_IRQHandler + B GPDMA2_Channel2_IRQHandler + + PUBWEAK GPDMA2_Channel3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel3_IRQHandler + B GPDMA2_Channel3_IRQHandler + + PUBWEAK GPDMA2_Channel4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel4_IRQHandler + B GPDMA2_Channel4_IRQHandler + + PUBWEAK GPDMA2_Channel5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel5_IRQHandler + B GPDMA2_Channel5_IRQHandler + + PUBWEAK GPDMA2_Channel6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel6_IRQHandler + B GPDMA2_Channel6_IRQHandler + + PUBWEAK GPDMA2_Channel7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA2_Channel7_IRQHandler + B GPDMA2_Channel7_IRQHandler + + PUBWEAK UART7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART7_IRQHandler + B UART7_IRQHandler + + PUBWEAK UART8_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART8_IRQHandler + B UART8_IRQHandler + + PUBWEAK UART9_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART9_IRQHandler + B UART9_IRQHandler + + PUBWEAK UART12_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +UART12_IRQHandler + B UART12_IRQHandler + + PUBWEAK SDMMC2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SDMMC2_IRQHandler + B SDMMC2_IRQHandler + + PUBWEAK FPU_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FPU_IRQHandler + B FPU_IRQHandler + + PUBWEAK ICACHE_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ICACHE_IRQHandler + B ICACHE_IRQHandler + + PUBWEAK DCACHE1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DCACHE1_IRQHandler + B DCACHE1_IRQHandler + + PUBWEAK ETH_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ETH_IRQHandler + B ETH_IRQHandler + + PUBWEAK ETH_WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ETH_WKUP_IRQHandler + B ETH_WKUP_IRQHandler + + PUBWEAK DCMI_PSSI_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DCMI_PSSI_IRQHandler + B DCMI_PSSI_IRQHandler + + PUBWEAK FDCAN2_IT0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FDCAN2_IT0_IRQHandler + B FDCAN2_IT0_IRQHandler + + PUBWEAK FDCAN2_IT1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FDCAN2_IT1_IRQHandler + B FDCAN2_IT1_IRQHandler + + PUBWEAK CORDIC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CORDIC_IRQHandler + B CORDIC_IRQHandler + + PUBWEAK FMAC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FMAC_IRQHandler + B FMAC_IRQHandler + + PUBWEAK DTS_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DTS_IRQHandler + B DTS_IRQHandler + + PUBWEAK RNG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RNG_IRQHandler + B RNG_IRQHandler + + PUBWEAK OTFDEC1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +OTFDEC1_IRQHandler + B OTFDEC1_IRQHandler + + PUBWEAK AES_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +AES_IRQHandler + B AES_IRQHandler + + PUBWEAK HASH_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HASH_IRQHandler + B HASH_IRQHandler + + PUBWEAK PKA_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +PKA_IRQHandler + B PKA_IRQHandler + + PUBWEAK CEC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +CEC_IRQHandler + B CEC_IRQHandler + + PUBWEAK TIM12_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM12_IRQHandler + B TIM12_IRQHandler + + PUBWEAK TIM13_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM13_IRQHandler + B TIM13_IRQHandler + + PUBWEAK TIM14_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM14_IRQHandler + B TIM14_IRQHandler + + PUBWEAK I3C1_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I3C1_EV_IRQHandler + B I3C1_EV_IRQHandler + + PUBWEAK I3C1_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I3C1_ER_IRQHandler + B I3C1_ER_IRQHandler + + PUBWEAK I2C4_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C4_EV_IRQHandler + B I2C4_EV_IRQHandler + + PUBWEAK I2C4_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C4_ER_IRQHandler + B I2C4_ER_IRQHandler + + PUBWEAK LPTIM3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM3_IRQHandler + B LPTIM3_IRQHandler + + PUBWEAK LPTIM4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM4_IRQHandler + B LPTIM4_IRQHandler + + PUBWEAK LPTIM5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM5_IRQHandler + B LPTIM5_IRQHandler + + PUBWEAK LPTIM6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM6_IRQHandler + B LPTIM6_IRQHandler + + END diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/system_stm32h5xx.c b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/system_stm32h5xx.c new file mode 100644 index 0000000000..0c74ae7da0 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/system_stm32h5xx.c @@ -0,0 +1,401 @@ +/** + ****************************************************************************** + * @file system_stm32h5xx.c + * @author MCD Application Team + * @brief CMSIS Cortex-M33 Device Peripheral Access Layer System Source File + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + * This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32h5xx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used + * by the user application to setup the SysTick + * timer or configure other parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * After each device reset the HSI (64 MHz) is used as system clock source. + * Then SystemInit() function is called, in "startup_stm32h5xx.s" file, to + * configure the system clock before to branch to main program. + * + * This file configures the system clock as follows: + *============================================================================= + *----------------------------------------------------------------------------- + * System Clock source | HSI + *----------------------------------------------------------------------------- + * SYSCLK(Hz) | 64000000 + *----------------------------------------------------------------------------- + * HCLK(Hz) | 64000000 + *----------------------------------------------------------------------------- + * AHB Prescaler | 1 + *----------------------------------------------------------------------------- + * APB1 Prescaler | 1 + *----------------------------------------------------------------------------- + * APB2 Prescaler | 1 + *----------------------------------------------------------------------------- + * APB3 Prescaler | 1 + *----------------------------------------------------------------------------- + * HSI Division factor | 1 + *----------------------------------------------------------------------------- + * PLL1_SRC | No clock + *----------------------------------------------------------------------------- + * PLL1_M | Prescaler disabled + *----------------------------------------------------------------------------- + * PLL1_N | 129 + *----------------------------------------------------------------------------- + * PLL1_P | 2 + *----------------------------------------------------------------------------- + * PLL1_Q | 2 + *----------------------------------------------------------------------------- + * PLL1_R | 2 + *----------------------------------------------------------------------------- + * PLL1_FRACN | 0 + *----------------------------------------------------------------------------- + * PLL2_SRC | No clock + *----------------------------------------------------------------------------- + * PLL2_M | Prescaler disabled + *----------------------------------------------------------------------------- + * PLL2_N | 129 + *----------------------------------------------------------------------------- + * PLL2_P | 2 + *----------------------------------------------------------------------------- + * PLL2_Q | 2 + *----------------------------------------------------------------------------- + * PLL2_R | 2 + *----------------------------------------------------------------------------- + * PLL2_FRACN | 0 + *----------------------------------------------------------------------------- + * PLL3_SRC | No clock + *----------------------------------------------------------------------------- + * PLL3_M | Prescaler disabled + *----------------------------------------------------------------------------- + * PLL3_N | 129 + *----------------------------------------------------------------------------- + * PLL3_P | 2 + *----------------------------------------------------------------------------- + * PLL3_Q | 2 + *----------------------------------------------------------------------------- + * PLL3_R | 2 + *----------------------------------------------------------------------------- + * PLL3_FRACN | 0 + *----------------------------------------------------------------------------- + *============================================================================= + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup STM32H5xx_system + * @{ + */ + +/** @addtogroup STM32H5xx_System_Private_Includes + * @{ + */ + +#include "stm32h5xx.h" + +/** + * @} + */ + +/** @addtogroup STM32H5xx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32H5xx_System_Private_Defines + * @{ + */ + +#if !defined (HSE_VALUE) + #define HSE_VALUE (25000000UL) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (CSI_VALUE) + #define CSI_VALUE (4000000UL) /*!< Value of the Internal oscillator in Hz*/ +#endif /* CSI_VALUE */ + +#if !defined (HSI_VALUE) + #define HSI_VALUE (64000000UL) /*!< Value of the Internal oscillator in Hz */ +#endif /* HSI_VALUE */ + +/************************* Miscellaneous Configuration ************************/ +/*!< Uncomment the following line if you need to relocate your vector Table in + Internal SRAM. */ +/* #define VECT_TAB_SRAM */ +#define VECT_TAB_OFFSET 0x00U /*!< Vector Table base offset field. + This value must be a multiple of 0x200. */ +/******************************************************************************/ + +/** + * @} + */ + +/** @addtogroup STM32H5xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32H5xx_System_Private_Variables + * @{ + */ + /* The SystemCoreClock variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetHCLKFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency + Note: If you use this function to configure the system clock; then there + is no need to call the 2 first functions listed above, since SystemCoreClock + variable is updated automatically. + */ + uint32_t SystemCoreClock = 64000000U; + + const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U}; + const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U}; +/** + * @} + */ + +/** @addtogroup STM32H5xx_System_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32H5xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system. + * @param None + * @retval None + */ + +void SystemInit(void) +{ + uint32_t reg_opsr; + + /* FPU settings ------------------------------------------------------------*/ + #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + SCB->CPACR |= ((3UL << 20U)|(3UL << 22U)); /* set CP10 and CP11 Full Access */ + #endif + + /* Reset the RCC clock configuration to the default reset state ------------*/ + /* Set HSION bit */ + RCC->CR = RCC_CR_HSION; + + /* Reset CFGR register */ + RCC->CFGR1 = 0U; + RCC->CFGR2 = 0U; + + /* Reset HSEON, HSECSSON, HSEBYP, HSEEXT, HSIDIV, HSIKERON, CSION, CSIKERON, HSI48 and PLLxON bits */ +#if defined(RCC_CR_PLL3ON) + RCC->CR &= ~(RCC_CR_HSEON | RCC_CR_HSECSSON | RCC_CR_HSEBYP | RCC_CR_HSEEXT | RCC_CR_HSIDIV | RCC_CR_HSIKERON | \ + RCC_CR_CSION | RCC_CR_CSIKERON |RCC_CR_HSI48ON | RCC_CR_PLL1ON | RCC_CR_PLL2ON | RCC_CR_PLL3ON); +#else + RCC->CR &= ~(RCC_CR_HSEON | RCC_CR_HSECSSON | RCC_CR_HSEBYP | RCC_CR_HSEEXT | RCC_CR_HSIDIV | RCC_CR_HSIKERON | \ + RCC_CR_CSION | RCC_CR_CSIKERON |RCC_CR_HSI48ON | RCC_CR_PLL1ON | RCC_CR_PLL2ON); +#endif + + /* Reset PLLxCFGR register */ + RCC->PLL1CFGR = 0U; + RCC->PLL2CFGR = 0U; +#if defined(RCC_CR_PLL3ON) + RCC->PLL3CFGR = 0U; +#endif /* RCC_CR_PLL3ON */ + + /* Reset PLL1DIVR register */ + RCC->PLL1DIVR = 0x01010280U; + /* Reset PLL1FRACR register */ + RCC->PLL1FRACR = 0x00000000U; + /* Reset PLL2DIVR register */ + RCC->PLL2DIVR = 0x01010280U; + /* Reset PLL2FRACR register */ + RCC->PLL2FRACR = 0x00000000U; +#if defined(RCC_CR_PLL3ON) + /* Reset PLL3DIVR register */ + RCC->PLL3DIVR = 0x01010280U; + /* Reset PLL3FRACR register */ + RCC->PLL3FRACR = 0x00000000U; +#endif /* RCC_CR_PLL3ON */ + + /* Reset HSEBYP bit */ + RCC->CR &= ~(RCC_CR_HSEBYP); + + /* Disable all interrupts */ + RCC->CIER = 0U; + + /* Configure the Vector Table location add offset address ------------------*/ + #ifdef VECT_TAB_SRAM + SCB->VTOR = SRAM1_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ + #else + SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ + #endif /* VECT_TAB_SRAM */ + + /* Check OPSR register to verify if there is an ongoing swap or option bytes update interrupted by a reset */ + reg_opsr = FLASH->OPSR & FLASH_OPSR_CODE_OP; + if ((reg_opsr == FLASH_OPSR_CODE_OP) || (reg_opsr == (FLASH_OPSR_CODE_OP_2 | FLASH_OPSR_CODE_OP_1))) + { + /* Check FLASH Option Control Register access */ + if ((FLASH->OPTCR & FLASH_OPTCR_OPTLOCK) != 0U) + { + /* Authorizes the Option Byte registers programming */ + FLASH->OPTKEYR = 0x08192A3BU; + FLASH->OPTKEYR = 0x4C5D6E7FU; + } + /* Launch the option bytes change operation */ + FLASH->OPTCR |= FLASH_OPTCR_OPTSTART; + + /* Lock the FLASH Option Control Register access */ + FLASH->OPTCR |= FLASH_OPTCR_OPTLOCK; + } +} + +/** + * @brief Update SystemCoreClock variable according to Clock Register Values. + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any configuration + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is CSI, SystemCoreClock will contain the CSI_VALUE(*) + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***) + * or HSI_VALUE(**) or CSI_VALUE(*) multiplied/divided by the PLL factors. + * + * (*) CSI_VALUE is a constant defined in stm32h5xx_hal.h file (default value + * 4 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (**) HSI_VALUE is a constant defined in stm32h5xx_hal.h file (default value + * 64 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (***) HSE_VALUE is a constant defined in stm32h5xx_hal.h file (default value + * 25 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @param None + * @retval None + */ +void SystemCoreClockUpdate(void) +{ + uint32_t pllp, pllsource, pllm, pllfracen, hsivalue, tmp; + float_t fracn1, pllvco; + + /* Get SYSCLK source -------------------------------------------------------*/ + switch (RCC->CFGR1 & RCC_CFGR1_SWS) + { + case 0x00UL: /* HSI used as system clock source */ + SystemCoreClock = (uint32_t) (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3)); + break; + + case 0x08UL: /* CSI used as system clock source */ + SystemCoreClock = CSI_VALUE; + break; + + case 0x10UL: /* HSE used as system clock source */ + SystemCoreClock = HSE_VALUE; + break; + + case 0x18UL: /* PLL1 used as system clock source */ + /* PLL_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN + SYSCLK = PLL_VCO / PLLR + */ + pllsource = (RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1SRC); + pllm = ((RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1M)>> RCC_PLL1CFGR_PLL1M_Pos); + pllfracen = ((RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1FRACEN)>>RCC_PLL1CFGR_PLL1FRACEN_Pos); + fracn1 = (float_t)(uint32_t)(pllfracen* ((RCC->PLL1FRACR & RCC_PLL1FRACR_PLL1FRACN)>> RCC_PLL1FRACR_PLL1FRACN_Pos)); + + switch (pllsource) + { + case 0x01UL: /* HSI used as PLL clock source */ + hsivalue = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3)) ; + pllvco = ((float_t)hsivalue / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \ + (fracn1/(float_t)0x2000) +(float_t)1 ); + break; + + case 0x02UL: /* CSI used as PLL clock source */ + pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \ + (fracn1/(float_t)0x2000) +(float_t)1 ); + break; + + case 0x03UL: /* HSE used as PLL clock source */ + pllvco = ((float_t)HSE_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \ + (fracn1/(float_t)0x2000) +(float_t)1 ); + break; + + default: /* No clock sent to PLL*/ + pllvco = (float_t) 0U; + break; + } + + pllp = (((RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1P) >>RCC_PLL1DIVR_PLL1P_Pos) + 1U ) ; + SystemCoreClock = (uint32_t)(float_t)(pllvco/(float_t)pllp); + + break; + + default: + SystemCoreClock = HSI_VALUE; + break; + } + /* Compute HCLK clock frequency --------------------------------------------*/ + /* Get HCLK prescaler */ + tmp = AHBPrescTable[((RCC->CFGR2 & RCC_CFGR2_HPRE) >> RCC_CFGR2_HPRE_Pos)]; + /* HCLK clock frequency */ + SystemCoreClock >>= tmp; +} + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/system_stm32h5xx_ns.c b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/system_stm32h5xx_ns.c new file mode 100644 index 0000000000..d200a42b92 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/system_stm32h5xx_ns.c @@ -0,0 +1,208 @@ +/** + ****************************************************************************** + * @file system_stm32h5xx_ns.c + * @author MCD Application Team + * @brief CMSIS Cortex-M33 Device Peripheral Access Layer System Source File + * to be used in non-secure application when the system implements + * the TrustZone-M security. + * + * This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): This function is called at non-secure startup before + * branch to non-secure main program. + * This call is made inside the "startup_stm32h5xx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used + * by the user application to setup the SysTick + * timer or configure other parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * After each device reset the HSI (64 MHz) is used as system clock source. + * Then SystemInit() function is called, in "startup_stm32h5xx.s" file, to + * configure the system clock before to branch to main secure program. + * Later, when non-secure SystemInit() function is called, in "startup_stm32h5xx.s" + * file, the system clock may have been updated from reset value by the main + * secure program. + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup STM32H5xx_system + * @{ + */ + +/** @addtogroup STM32H5xx_System_Private_Includes + * @{ + */ + +#include "stm32h5xx.h" + +/** + * @} + */ + +/** @addtogroup STM32H5xx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32H5xx_System_Private_Defines + * @{ + */ + +#if !defined (HSE_VALUE) + #define HSE_VALUE (25000000UL) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (CSI_VALUE) + #define CSI_VALUE (4000000UL) /*!< Value of the Internal oscillator in Hz*/ +#endif /* CSI_VALUE */ + +#if !defined (HSI_VALUE) + #define HSI_VALUE (64000000UL) /*!< Value of the Internal oscillator in Hz */ +#endif /* HSI_VALUE */ + +/** + * @} + */ + +/** @addtogroup STM32H5xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32H5xx_System_Private_Variables + * @{ + */ + /* The SystemCoreClock variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetHCLKFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency + Note: If you use this function to configure the system clock; then there + is no need to call the 2 first functions listed above, since SystemCoreClock + variable is updated automatically. + */ + uint32_t SystemCoreClock = 64000000U; + + const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U}; + const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U}; +/** + * @} + */ + +/** @addtogroup STM32H5xx_System_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32H5xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system. + * @param None + * @retval None + */ + +void SystemInit(void) +{ + /* Nothing done in non-secure */ + + /* Non-secure main application shall call SystemCoreClockUpdate() to update */ + /* the SystemCoreClock variable to insure non-secure application relies on */ + /* the initial clock reference set by secure application. */ +} + +/** + * @brief Update SystemCoreClock variable according to Clock Register Values. + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note From the non-secure application, the SystemCoreClock value is + * retrieved from the secure domain via a Non-Secure Callable function + * since the RCC peripheral may be protected with security attributes + * that prevent to compute the SystemCoreClock variable from the RCC + * peripheral registers. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any configuration + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is CSI, SystemCoreClock will contain the CSI_VALUE(*) + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***) + * or HSI_VALUE(**) or CSI_VALUE(*) multiplied/divided by the PLL factors. + * + * (*) CSI_VALUE is a constant defined in stm32h5xx_hal.h file (default value + * 4 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (**) HSI_VALUE is a constant defined in stm32h5xx_hal.h file (default value + * 64 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (***) HSE_VALUE is a constant defined in stm32h5xx_hal.h file (default value + * 25 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @retval None + */ +void SystemCoreClockUpdate(void) +{ + /* Get the SystemCoreClock value from the secure domain */ + SystemCoreClock = SECURE_SystemCoreClockUpdate(); +} + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/system_stm32h5xx_s.c b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/system_stm32h5xx_s.c new file mode 100644 index 0000000000..4c762046ad --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/system_stm32h5xx_s.c @@ -0,0 +1,430 @@ +/** + ****************************************************************************** + * @file system_stm32h5xx_s.c + * @author MCD Application Team + * @brief CMSIS Cortex-M33 Device Peripheral Access Layer System Source File + * to be used in secure application when the system implements + * the security. + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + * This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32h5xx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used + * by the user application to setup the SysTick + * timer or configure other parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * - SECURE_SystemCoreClockUpdate(): Non-secure callable function to update + * the variable SystemCoreClock and return + * its value to the non-secure calling + * application. It must be called whenever + * the core clock is changed during program + * execution. + * + * After each device reset the HSI (64 MHz) is used as system clock source. + * Then SystemInit() function is called, in "startup_stm32h5xx.s" file, to + * configure the system clock before to branch to main program. + * + * This file configures the system clock as follows: + *============================================================================= + *----------------------------------------------------------------------------- + * System Clock source | HSI + *----------------------------------------------------------------------------- + * SYSCLK(Hz) | 64000000 + *----------------------------------------------------------------------------- + * HCLK(Hz) | 64000000 + *----------------------------------------------------------------------------- + * AHB Prescaler | 1 + *----------------------------------------------------------------------------- + * APB1 Prescaler | 1 + *----------------------------------------------------------------------------- + * APB2 Prescaler | 1 + *----------------------------------------------------------------------------- + * APB3 Prescaler | 1 + *----------------------------------------------------------------------------- + * HSI Division factor | 1 + *----------------------------------------------------------------------------- + * PLL1_SRC | No clock + *----------------------------------------------------------------------------- + * PLL1_M | Prescaler disabled + *----------------------------------------------------------------------------- + * PLL1_N | 129 + *----------------------------------------------------------------------------- + * PLL1_P | 2 + *----------------------------------------------------------------------------- + * PLL1_Q | 2 + *----------------------------------------------------------------------------- + * PLL1_R | 2 + *----------------------------------------------------------------------------- + * PLL1_FRACN | 0 + *----------------------------------------------------------------------------- + * PLL2_SRC | No clock + *----------------------------------------------------------------------------- + * PLL2_M | Prescaler disabled + *----------------------------------------------------------------------------- + * PLL2_N | 129 + *----------------------------------------------------------------------------- + * PLL2_P | 2 + *----------------------------------------------------------------------------- + * PLL2_Q | 2 + *----------------------------------------------------------------------------- + * PLL2_R | 2 + *----------------------------------------------------------------------------- + * PLL2_FRACN | 0 + *----------------------------------------------------------------------------- + * PLL3_SRC | No clock + *----------------------------------------------------------------------------- + * PLL3_M | Prescaler disabled + *----------------------------------------------------------------------------- + * PLL3_N | 129 + *----------------------------------------------------------------------------- + * PLL3_P | 2 + *----------------------------------------------------------------------------- + * PLL3_Q | 2 + *----------------------------------------------------------------------------- + * PLL3_R | 2 + *----------------------------------------------------------------------------- + * PLL3_FRACN | 0 + *----------------------------------------------------------------------------- + *============================================================================= + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup STM32H5xx_system + * @{ + */ + +/** @addtogroup STM32H5xx_System_Private_Includes + * @{ + */ + +#include "stm32h5xx.h" +#include "partition_stm32h5xx.h" /* Trustzone-M core secure attributes */ + +/** + * @} + */ + +/** @addtogroup STM32H5xx_System_Private_TypesDefinitions + * @{ + */ + +#if defined ( __ICCARM__ ) +# define CMSE_NS_ENTRY __cmse_nonsecure_entry +#else +# define CMSE_NS_ENTRY __attribute((cmse_nonsecure_entry)) +#endif +/** + * @} + */ + +/** @addtogroup STM32H5xx_System_Private_Defines + * @{ + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE (25000000UL) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (CSI_VALUE) + #define CSI_VALUE (4000000UL) /*!< Value of the Internal oscillator in Hz*/ +#endif /* CSI_VALUE */ + +#if !defined (HSI_VALUE) + #define HSI_VALUE (64000000UL) /*!< Value of the Internal oscillator in Hz */ +#endif /* HSI_VALUE */ + +/************************* Miscellaneous Configuration ************************/ +/*!< Uncomment the following line if you need to relocate your vector Table in + Internal SRAM. */ +/* #define VECT_TAB_SRAM */ +#define VECT_TAB_OFFSET 0x00U /*!< Vector Table base offset field. + This value must be a multiple of 0x200. */ +/******************************************************************************/ +/** + * @} + */ + +/** @addtogroup STM32H5xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32H5xx_System_Private_Variables + * @{ + */ + /* The SystemCoreClock variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetHCLKFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency + Note: If you use this function to configure the system clock; then there + is no need to call the 2 first functions listed above, since SystemCoreClock + variable is updated automatically. + */ + uint32_t SystemCoreClock = 64000000U; + + const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U}; + const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U}; +/** + * @} + */ + +/** @addtogroup STM32H5xx_System_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32H5xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system. + * @param None + * @retval None + */ + +void SystemInit(void) +{ + uint32_t reg_opsr; + + /* SAU/IDAU, FPU and Interrupts secure/non-secure allocation settings */ + TZ_SAU_Setup(); + + /* FPU settings ------------------------------------------------------------*/ + #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + SCB->CPACR |= ((3UL << 20U)|(3UL << 22U)); /* set CP10 and CP11 Full Access */ + + SCB_NS->CPACR |= ((3UL << 20U)|(3UL << 22U)); /* set CP10 and CP11 Full Access */ + #endif + + /* Reset the RCC clock configuration to the default reset state ------------*/ + /* Set HSION bit */ + RCC->CR = RCC_CR_HSION; + + /* Reset CFGR register */ + RCC->CFGR1 = 0U; + RCC->CFGR2 = 0U; + + /* Reset HSEON, HSECSSON, HSEBYP, HSEEXT, HSIDIV, HSIKERON, CSION, CSIKERON, HSI48 and PLLxON bits */ + RCC->CR &= ~(RCC_CR_HSEON | RCC_CR_HSECSSON | RCC_CR_HSEBYP | RCC_CR_HSEEXT | RCC_CR_HSIDIV | RCC_CR_HSIKERON | \ + RCC_CR_CSION | RCC_CR_CSIKERON |RCC_CR_HSI48ON | RCC_CR_PLL1ON | RCC_CR_PLL2ON | RCC_CR_PLL3ON); + + /* Reset PLLxCFGR register */ + RCC->PLL1CFGR = 0U; + RCC->PLL2CFGR = 0U; + RCC->PLL3CFGR = 0U; + + /* Reset PLL1DIVR register */ + RCC->PLL1DIVR = 0x01010280U; + /* Reset PLL1FRACR register */ + RCC->PLL1FRACR = 0x00000000U; + /* Reset PLL2DIVR register */ + RCC->PLL2DIVR = 0x01010280U; + /* Reset PLL2FRACR register */ + RCC->PLL2FRACR = 0x00000000U; + /* Reset PLL3DIVR register */ + RCC->PLL3DIVR = 0x01010280U; + /* Reset PLL3FRACR register */ + RCC->PLL3FRACR = 0x00000000U; + + /* Reset HSEBYP bit */ + RCC->CR &= ~(RCC_CR_HSEBYP); + + /* Disable all interrupts */ + RCC->CIER = 0U; + + /* Configure the Vector Table location add offset address ------------------*/ + #ifdef VECT_TAB_SRAM + SCB->VTOR = SRAM1_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ + #else + SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ + #endif /* VECT_TAB_SRAM */ + + /* Check OPSR register to verify if there is an ongoing swap or option bytes update interrupted by a reset */ + reg_opsr = FLASH->OPSR & FLASH_OPSR_CODE_OP; + if ((reg_opsr == FLASH_OPSR_CODE_OP) || (reg_opsr == (FLASH_OPSR_CODE_OP_2 | FLASH_OPSR_CODE_OP_1))) + { + /* Check FLASH Option Control Registers access */ + if ((FLASH->OPTCR & FLASH_OPTCR_OPTLOCK) != 0U) + { + /* Authorizes the Option Byte register programming */ + FLASH->OPTKEYR = 0x08192A3BU; + FLASH->OPTKEYR = 0x4C5D6E7FU; + } + /* Launch the option bytes change operation */ + FLASH->OPTCR |= FLASH_OPTCR_OPTSTART; + + /* Lock the FLASH Option Control Register access */ + FLASH->OPTCR |= FLASH_OPTCR_OPTLOCK; + } +} + +/** + * @brief Update SystemCoreClock variable according to Clock Register Values. + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Depending on secure or non-secure compilation, the adequate RCC peripheral + * memory are is accessed thanks to RCC alias defined in stm32h5xxxx.h device file + * so either from RCC_S peripheral register mapped memory in secure or from + * RCC_NS peripheral register mapped memory in non-secure. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any configuration + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is CSI, SystemCoreClock will contain the CSI_VALUE(*) + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***) + * or HSI_VALUE(**) or CSI_VALUE(*) multiplied/divided by the PLL factors. + * + * (*) CSI_VALUE is a constant defined in stm32h5xx_hal.h file (default value + * 4 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (**) HSI_VALUE is a constant defined in stm32h5xx_hal.h file (default value + * 64 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (***) HSE_VALUE is a constant defined in stm32h5xx_hal.h file (default value + * 25 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @param None + * @retval None + */ +void SystemCoreClockUpdate(void) +{ + uint32_t pllp, pllsource, pllm, pllfracen, hsivalue, tmp; + float_t fracn1, pllvco; + + /* Get SYSCLK source -------------------------------------------------------*/ + switch (RCC->CFGR1 & RCC_CFGR1_SWS) + { + case 0x00UL: /* HSI used as system clock source */ + SystemCoreClock = (uint32_t) (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3)); + break; + + case 0x08UL: /* CSI used as system clock source */ + SystemCoreClock = CSI_VALUE; + break; + + case 0x10UL: /* HSE used as system clock source */ + SystemCoreClock = HSE_VALUE; + break; + + case 0x18UL: /* PLL1 used as system clock source */ + /* PLL_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN + SYSCLK = PLL_VCO / PLLR + */ + pllsource = (RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1SRC); + pllm = ((RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1M)>> RCC_PLL1CFGR_PLL1M_Pos); + pllfracen = ((RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1FRACEN)>>RCC_PLL1CFGR_PLL1FRACEN_Pos); + fracn1 = (float_t)(uint32_t)(pllfracen* ((RCC->PLL1FRACR & RCC_PLL1FRACR_PLL1FRACN)>> RCC_PLL1FRACR_PLL1FRACN_Pos)); + + switch (pllsource) + { + case 0x01UL: /* HSI used as PLL clock source */ + hsivalue = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3)) ; + pllvco = ((float_t)hsivalue / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \ + (fracn1/(float_t)0x2000) +(float_t)1 ); + break; + + case 0x02UL: /* CSI used as PLL clock source */ + pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \ + (fracn1/(float_t)0x2000) +(float_t)1 ); + break; + + case 0x03UL: /* HSE used as PLL clock source */ + pllvco = ((float_t)HSE_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \ + (fracn1/(float_t)0x2000) +(float_t)1 ); + break; + + default: /* No clock sent to PLL*/ + pllvco = (float_t) 0U; + break; + } + + pllp = (((RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1P) >>RCC_PLL1DIVR_PLL1P_Pos) + 1U ) ; + SystemCoreClock = (uint32_t)(float_t)(pllvco/(float_t)pllp); + + break; + + default: + SystemCoreClock = HSI_VALUE; + break; + } + /* Compute HCLK clock frequency --------------------------------------------*/ + /* Get HCLK prescaler */ + tmp = AHBPrescTable[((RCC->CFGR2 & RCC_CFGR2_HPRE) >> RCC_CFGR2_HPRE_Pos)]; + /* HCLK clock frequency */ + SystemCoreClock >>= tmp; + +} + +/** + * @brief Secure Non-Secure-Callable function to return the current + * SystemCoreClock value after SystemCoreClock update. + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * @retval SystemCoreClock value (HCLK) + */ +CMSE_NS_ENTRY uint32_t SECURE_SystemCoreClockUpdate(void) +{ + SystemCoreClockUpdate(); + + return SystemCoreClock; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/SConscript b/bsp/stm32/libraries/STM32H5xx_HAL/SConscript new file mode 100644 index 0000000000..74d70f4d09 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/SConscript @@ -0,0 +1,119 @@ +import rtconfig +from building import * + +# get current directory +cwd = GetCurrentDir() + +# The set of source files associated with this SConscript file. + +src = Split(''' +CMSIS/Device/ST/STM32H5xx/Source/Templates/system_stm32h5xx.c +STM32H5xx_HAL_Driver/Src/stm32h5xx_hal.c +STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_comp.c +STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_cortex.c +STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_crc.c +STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_crc_ex.c +STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_cryp.c +STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_cryp_ex.c +STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dma.c +STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dma_ex.c +STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_exti.c +STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pwr.c +STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pwr_ex.c +STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rcc.c +STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rcc_ex.c +STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rng.c +STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_gpio.c +STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_icache.c +''') + +if GetDepend(['RT_USING_SERIAL']): + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_uart.c'] + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_uart_ex.c'] + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_usart.c'] + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_usart_ex.c'] + +if GetDepend(['RT_USING_I2C']): + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_i2c.c'] + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_i2c_ex.c'] + +if GetDepend(['RT_USING_SPI']): + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_spi.c'] + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_spi_ex.c'] + +if GetDepend(['RT_USING_USB']): + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_hcd.c'] + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pcd.c'] + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pcd_ex.c'] + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_usb.c'] + +if GetDepend(['RT_USING_CAN']): + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_can.c'] + +if GetDepend(['RT_USING_HWTIMER']) or GetDepend(['RT_USING_PWM']): + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_lptim.c'] + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_tim.c'] + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_tim_ex.c'] + +if GetDepend(['RT_USING_ADC']): + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_adc.c'] + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_adc_ex.c'] + +if GetDepend(['RT_USING_DAC']): + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dac.c'] + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dac_ex.c'] + +if GetDepend(['RT_USING_RTC']): + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rtc.c'] + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rtc_ex.c'] + +if GetDepend(['RT_USING_WDT']): + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_iwdg.c'] + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_wwdg.c'] + +if GetDepend(['RT_USING_SDIO']): + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sd.c'] + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sd_ex.c'] + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_sdmmc.c'] + +if GetDepend(['RT_USING_AUDIO']): + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sai.c'] + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sai_ex.c'] + +if GetDepend(['RT_USING_MTD_NOR']): + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_nor.c'] + +if GetDepend(['RT_USING_MTD_NAND']): + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_nand.c'] + +if GetDepend(['RT_USING_PM']): + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_lptim.c'] + +if GetDepend(['BSP_USING_ON_CHIP_FLASH']): + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_flash.c'] + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_flash_ex.c'] + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_flash_ramfunc.c'] + +if GetDepend(['BSP_USING_FMC']): + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_fmc.c'] + +if GetDepend(['BSP_USING_GFXMMU']): + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_gfxmmu.c'] + +if GetDepend(['BSP_USING_DSI']): + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dsi.c'] + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dma2d.c'] + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_dma2d.c'] + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_ltdc.c'] + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_ltdc_ex.c'] + +if GetDepend(['BSP_USING_SRAM']): + src += ['STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sram.c'] + +path = [cwd + '/STM32H5xx_HAL_Driver/Inc', + cwd + '/CMSIS/Device/ST/STM32H5xx/Include'] + +CPPDEFINES = ['USE_HAL_DRIVER'] +group = DefineGroup('Libraries', src, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES) + +Return('group') diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h new file mode 100644 index 0000000000..af2fd25e2a --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h @@ -0,0 +1,4331 @@ +/** + ****************************************************************************** + * @file stm32_hal_legacy.h + * @author MCD Application Team + * @brief This file contains aliases definition for the STM32Cube HAL constants + * macros and functions maintained for legacy purpose. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32_HAL_LEGACY +#define STM32_HAL_LEGACY + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup HAL_AES_Aliased_Defines HAL CRYP Aliased Defines maintained for legacy purpose + * @{ + */ +#define AES_FLAG_RDERR CRYP_FLAG_RDERR +#define AES_FLAG_WRERR CRYP_FLAG_WRERR +#define AES_CLEARFLAG_CCF CRYP_CLEARFLAG_CCF +#define AES_CLEARFLAG_RDERR CRYP_CLEARFLAG_RDERR +#define AES_CLEARFLAG_WRERR CRYP_CLEARFLAG_WRERR +#if defined(STM32H7) || defined(STM32MP1) +#define CRYP_DATATYPE_32B CRYP_NO_SWAP +#define CRYP_DATATYPE_16B CRYP_HALFWORD_SWAP +#define CRYP_DATATYPE_8B CRYP_BYTE_SWAP +#define CRYP_DATATYPE_1B CRYP_BIT_SWAP +#endif /* STM32H7 || STM32MP1 */ +/** + * @} + */ + +/** @defgroup HAL_ADC_Aliased_Defines HAL ADC Aliased Defines maintained for legacy purpose + * @{ + */ +#define ADC_RESOLUTION12b ADC_RESOLUTION_12B +#define ADC_RESOLUTION10b ADC_RESOLUTION_10B +#define ADC_RESOLUTION8b ADC_RESOLUTION_8B +#define ADC_RESOLUTION6b ADC_RESOLUTION_6B +#define OVR_DATA_OVERWRITTEN ADC_OVR_DATA_OVERWRITTEN +#define OVR_DATA_PRESERVED ADC_OVR_DATA_PRESERVED +#define EOC_SINGLE_CONV ADC_EOC_SINGLE_CONV +#define EOC_SEQ_CONV ADC_EOC_SEQ_CONV +#define EOC_SINGLE_SEQ_CONV ADC_EOC_SINGLE_SEQ_CONV +#define REGULAR_GROUP ADC_REGULAR_GROUP +#define INJECTED_GROUP ADC_INJECTED_GROUP +#define REGULAR_INJECTED_GROUP ADC_REGULAR_INJECTED_GROUP +#define AWD_EVENT ADC_AWD_EVENT +#define AWD1_EVENT ADC_AWD1_EVENT +#define AWD2_EVENT ADC_AWD2_EVENT +#define AWD3_EVENT ADC_AWD3_EVENT +#define OVR_EVENT ADC_OVR_EVENT +#define JQOVF_EVENT ADC_JQOVF_EVENT +#define ALL_CHANNELS ADC_ALL_CHANNELS +#define REGULAR_CHANNELS ADC_REGULAR_CHANNELS +#define INJECTED_CHANNELS ADC_INJECTED_CHANNELS +#define SYSCFG_FLAG_SENSOR_ADC ADC_FLAG_SENSOR +#define SYSCFG_FLAG_VREF_ADC ADC_FLAG_VREFINT +#define ADC_CLOCKPRESCALER_PCLK_DIV1 ADC_CLOCK_SYNC_PCLK_DIV1 +#define ADC_CLOCKPRESCALER_PCLK_DIV2 ADC_CLOCK_SYNC_PCLK_DIV2 +#define ADC_CLOCKPRESCALER_PCLK_DIV4 ADC_CLOCK_SYNC_PCLK_DIV4 +#define ADC_CLOCKPRESCALER_PCLK_DIV6 ADC_CLOCK_SYNC_PCLK_DIV6 +#define ADC_CLOCKPRESCALER_PCLK_DIV8 ADC_CLOCK_SYNC_PCLK_DIV8 +#define ADC_EXTERNALTRIG0_T6_TRGO ADC_EXTERNALTRIGCONV_T6_TRGO +#define ADC_EXTERNALTRIG1_T21_CC2 ADC_EXTERNALTRIGCONV_T21_CC2 +#define ADC_EXTERNALTRIG2_T2_TRGO ADC_EXTERNALTRIGCONV_T2_TRGO +#define ADC_EXTERNALTRIG3_T2_CC4 ADC_EXTERNALTRIGCONV_T2_CC4 +#define ADC_EXTERNALTRIG4_T22_TRGO ADC_EXTERNALTRIGCONV_T22_TRGO +#define ADC_EXTERNALTRIG7_EXT_IT11 ADC_EXTERNALTRIGCONV_EXT_IT11 +#define ADC_CLOCK_ASYNC ADC_CLOCK_ASYNC_DIV1 +#define ADC_EXTERNALTRIG_EDGE_NONE ADC_EXTERNALTRIGCONVEDGE_NONE +#define ADC_EXTERNALTRIG_EDGE_RISING ADC_EXTERNALTRIGCONVEDGE_RISING +#define ADC_EXTERNALTRIG_EDGE_FALLING ADC_EXTERNALTRIGCONVEDGE_FALLING +#define ADC_EXTERNALTRIG_EDGE_RISINGFALLING ADC_EXTERNALTRIGCONVEDGE_RISINGFALLING +#define ADC_SAMPLETIME_2CYCLE_5 ADC_SAMPLETIME_2CYCLES_5 + +#define HAL_ADC_STATE_BUSY_REG HAL_ADC_STATE_REG_BUSY +#define HAL_ADC_STATE_BUSY_INJ HAL_ADC_STATE_INJ_BUSY +#define HAL_ADC_STATE_EOC_REG HAL_ADC_STATE_REG_EOC +#define HAL_ADC_STATE_EOC_INJ HAL_ADC_STATE_INJ_EOC +#define HAL_ADC_STATE_ERROR HAL_ADC_STATE_ERROR_INTERNAL +#define HAL_ADC_STATE_BUSY HAL_ADC_STATE_BUSY_INTERNAL +#define HAL_ADC_STATE_AWD HAL_ADC_STATE_AWD1 + +#if defined(STM32H7) +#define ADC_CHANNEL_VBAT_DIV4 ADC_CHANNEL_VBAT +#endif /* STM32H7 */ + +#if defined(STM32U5) +#define ADC_SAMPLETIME_5CYCLE ADC_SAMPLETIME_5CYCLES +#define ADC_SAMPLETIME_391CYCLES_5 ADC_SAMPLETIME_391CYCLES +#define ADC4_SAMPLETIME_160CYCLES_5 ADC4_SAMPLETIME_814CYCLES_5 +#endif /* STM32U5 */ + +#if defined(STM32H5) +#define ADC_CHANNEL_VCORE ADC_CHANNEL_VDDCORE +#endif /* STM32H5 */ +/** + * @} + */ + +/** @defgroup HAL_CEC_Aliased_Defines HAL CEC Aliased Defines maintained for legacy purpose + * @{ + */ + +#define __HAL_CEC_GET_IT __HAL_CEC_GET_FLAG + +/** + * @} + */ + +/** @defgroup HAL_COMP_Aliased_Defines HAL COMP Aliased Defines maintained for legacy purpose + * @{ + */ +#define COMP_WINDOWMODE_DISABLED COMP_WINDOWMODE_DISABLE +#define COMP_WINDOWMODE_ENABLED COMP_WINDOWMODE_ENABLE +#define COMP_EXTI_LINE_COMP1_EVENT COMP_EXTI_LINE_COMP1 +#define COMP_EXTI_LINE_COMP2_EVENT COMP_EXTI_LINE_COMP2 +#define COMP_EXTI_LINE_COMP3_EVENT COMP_EXTI_LINE_COMP3 +#define COMP_EXTI_LINE_COMP4_EVENT COMP_EXTI_LINE_COMP4 +#define COMP_EXTI_LINE_COMP5_EVENT COMP_EXTI_LINE_COMP5 +#define COMP_EXTI_LINE_COMP6_EVENT COMP_EXTI_LINE_COMP6 +#define COMP_EXTI_LINE_COMP7_EVENT COMP_EXTI_LINE_COMP7 +#if defined(STM32L0) +#define COMP_LPTIMCONNECTION_ENABLED ((uint32_t)0x00000003U) /*!< COMPX output generic naming: connected to LPTIM + input 1 for COMP1, LPTIM input 2 for COMP2 */ +#endif +#define COMP_OUTPUT_COMP6TIM2OCREFCLR COMP_OUTPUT_COMP6_TIM2OCREFCLR +#if defined(STM32F373xC) || defined(STM32F378xx) +#define COMP_OUTPUT_TIM3IC1 COMP_OUTPUT_COMP1_TIM3IC1 +#define COMP_OUTPUT_TIM3OCREFCLR COMP_OUTPUT_COMP1_TIM3OCREFCLR +#endif /* STM32F373xC || STM32F378xx */ + +#if defined(STM32L0) || defined(STM32L4) +#define COMP_WINDOWMODE_ENABLE COMP_WINDOWMODE_COMP1_INPUT_PLUS_COMMON + +#define COMP_NONINVERTINGINPUT_IO1 COMP_INPUT_PLUS_IO1 +#define COMP_NONINVERTINGINPUT_IO2 COMP_INPUT_PLUS_IO2 +#define COMP_NONINVERTINGINPUT_IO3 COMP_INPUT_PLUS_IO3 +#define COMP_NONINVERTINGINPUT_IO4 COMP_INPUT_PLUS_IO4 +#define COMP_NONINVERTINGINPUT_IO5 COMP_INPUT_PLUS_IO5 +#define COMP_NONINVERTINGINPUT_IO6 COMP_INPUT_PLUS_IO6 + +#define COMP_INVERTINGINPUT_1_4VREFINT COMP_INPUT_MINUS_1_4VREFINT +#define COMP_INVERTINGINPUT_1_2VREFINT COMP_INPUT_MINUS_1_2VREFINT +#define COMP_INVERTINGINPUT_3_4VREFINT COMP_INPUT_MINUS_3_4VREFINT +#define COMP_INVERTINGINPUT_VREFINT COMP_INPUT_MINUS_VREFINT +#define COMP_INVERTINGINPUT_DAC1_CH1 COMP_INPUT_MINUS_DAC1_CH1 +#define COMP_INVERTINGINPUT_DAC1_CH2 COMP_INPUT_MINUS_DAC1_CH2 +#define COMP_INVERTINGINPUT_DAC1 COMP_INPUT_MINUS_DAC1_CH1 +#define COMP_INVERTINGINPUT_DAC2 COMP_INPUT_MINUS_DAC1_CH2 +#define COMP_INVERTINGINPUT_IO1 COMP_INPUT_MINUS_IO1 +#if defined(STM32L0) +/* Issue fixed on STM32L0 COMP driver: only 2 dedicated IO (IO1 and IO2), */ +/* IO2 was wrongly assigned to IO shared with DAC and IO3 was corresponding */ +/* to the second dedicated IO (only for COMP2). */ +#define COMP_INVERTINGINPUT_IO2 COMP_INPUT_MINUS_DAC1_CH2 +#define COMP_INVERTINGINPUT_IO3 COMP_INPUT_MINUS_IO2 +#else +#define COMP_INVERTINGINPUT_IO2 COMP_INPUT_MINUS_IO2 +#define COMP_INVERTINGINPUT_IO3 COMP_INPUT_MINUS_IO3 +#endif +#define COMP_INVERTINGINPUT_IO4 COMP_INPUT_MINUS_IO4 +#define COMP_INVERTINGINPUT_IO5 COMP_INPUT_MINUS_IO5 + +#define COMP_OUTPUTLEVEL_LOW COMP_OUTPUT_LEVEL_LOW +#define COMP_OUTPUTLEVEL_HIGH COMP_OUTPUT_LEVEL_HIGH + +/* Note: Literal "COMP_FLAG_LOCK" kept for legacy purpose. */ +/* To check COMP lock state, use macro "__HAL_COMP_IS_LOCKED()". */ +#if defined(COMP_CSR_LOCK) +#define COMP_FLAG_LOCK COMP_CSR_LOCK +#elif defined(COMP_CSR_COMP1LOCK) +#define COMP_FLAG_LOCK COMP_CSR_COMP1LOCK +#elif defined(COMP_CSR_COMPxLOCK) +#define COMP_FLAG_LOCK COMP_CSR_COMPxLOCK +#endif + +#if defined(STM32L4) +#define COMP_BLANKINGSRCE_TIM1OC5 COMP_BLANKINGSRC_TIM1_OC5_COMP1 +#define COMP_BLANKINGSRCE_TIM2OC3 COMP_BLANKINGSRC_TIM2_OC3_COMP1 +#define COMP_BLANKINGSRCE_TIM3OC3 COMP_BLANKINGSRC_TIM3_OC3_COMP1 +#define COMP_BLANKINGSRCE_TIM3OC4 COMP_BLANKINGSRC_TIM3_OC4_COMP2 +#define COMP_BLANKINGSRCE_TIM8OC5 COMP_BLANKINGSRC_TIM8_OC5_COMP2 +#define COMP_BLANKINGSRCE_TIM15OC1 COMP_BLANKINGSRC_TIM15_OC1_COMP2 +#define COMP_BLANKINGSRCE_NONE COMP_BLANKINGSRC_NONE +#endif + +#if defined(STM32L0) +#define COMP_MODE_HIGHSPEED COMP_POWERMODE_MEDIUMSPEED +#define COMP_MODE_LOWSPEED COMP_POWERMODE_ULTRALOWPOWER +#else +#define COMP_MODE_HIGHSPEED COMP_POWERMODE_HIGHSPEED +#define COMP_MODE_MEDIUMSPEED COMP_POWERMODE_MEDIUMSPEED +#define COMP_MODE_LOWPOWER COMP_POWERMODE_LOWPOWER +#define COMP_MODE_ULTRALOWPOWER COMP_POWERMODE_ULTRALOWPOWER +#endif + +#endif + +#if defined(STM32U5) +#define __HAL_COMP_COMP1_EXTI_CLEAR_RASING_FLAG __HAL_COMP_COMP1_EXTI_CLEAR_RISING_FLAG +#endif + +/** + * @} + */ + +/** @defgroup HAL_CORTEX_Aliased_Defines HAL CORTEX Aliased Defines maintained for legacy purpose + * @{ + */ +#define __HAL_CORTEX_SYSTICKCLK_CONFIG HAL_SYSTICK_CLKSourceConfig +#if defined(STM32U5) +#define MPU_DEVICE_nGnRnE MPU_DEVICE_NGNRNE +#define MPU_DEVICE_nGnRE MPU_DEVICE_NGNRE +#define MPU_DEVICE_nGRE MPU_DEVICE_NGRE +#endif /* STM32U5 */ +/** + * @} + */ + +/** @defgroup CRC_Aliases CRC API aliases + * @{ + */ +#if defined(STM32H5) || defined(STM32C0) +#else +#define HAL_CRC_Input_Data_Reverse HAL_CRCEx_Input_Data_Reverse /*!< Aliased to HAL_CRCEx_Input_Data_Reverse for + inter STM32 series compatibility */ +#define HAL_CRC_Output_Data_Reverse HAL_CRCEx_Output_Data_Reverse /*!< Aliased to HAL_CRCEx_Output_Data_Reverse for + inter STM32 series compatibility */ +#endif +/** + * @} + */ + +/** @defgroup HAL_CRC_Aliased_Defines HAL CRC Aliased Defines maintained for legacy purpose + * @{ + */ + +#define CRC_OUTPUTDATA_INVERSION_DISABLED CRC_OUTPUTDATA_INVERSION_DISABLE +#define CRC_OUTPUTDATA_INVERSION_ENABLED CRC_OUTPUTDATA_INVERSION_ENABLE + +/** + * @} + */ + +/** @defgroup HAL_DAC_Aliased_Defines HAL DAC Aliased Defines maintained for legacy purpose + * @{ + */ + +#define DAC1_CHANNEL_1 DAC_CHANNEL_1 +#define DAC1_CHANNEL_2 DAC_CHANNEL_2 +#define DAC2_CHANNEL_1 DAC_CHANNEL_1 +#define DAC_WAVE_NONE 0x00000000U +#define DAC_WAVE_NOISE DAC_CR_WAVE1_0 +#define DAC_WAVE_TRIANGLE DAC_CR_WAVE1_1 +#define DAC_WAVEGENERATION_NONE DAC_WAVE_NONE +#define DAC_WAVEGENERATION_NOISE DAC_WAVE_NOISE +#define DAC_WAVEGENERATION_TRIANGLE DAC_WAVE_TRIANGLE + +#if defined(STM32G4) || defined(STM32L5) || defined(STM32H7) || defined (STM32U5) +#define DAC_CHIPCONNECT_DISABLE DAC_CHIPCONNECT_EXTERNAL +#define DAC_CHIPCONNECT_ENABLE DAC_CHIPCONNECT_INTERNAL +#endif + +#if defined(STM32U5) +#define DAC_TRIGGER_STOP_LPTIM1_OUT DAC_TRIGGER_STOP_LPTIM1_CH1 +#define DAC_TRIGGER_STOP_LPTIM3_OUT DAC_TRIGGER_STOP_LPTIM3_CH1 +#define DAC_TRIGGER_LPTIM1_OUT DAC_TRIGGER_LPTIM1_CH1 +#define DAC_TRIGGER_LPTIM3_OUT DAC_TRIGGER_LPTIM3_CH1 +#endif + +#if defined(STM32H5) +#define DAC_TRIGGER_LPTIM1_OUT DAC_TRIGGER_LPTIM1_CH1 +#define DAC_TRIGGER_LPTIM2_OUT DAC_TRIGGER_LPTIM2_CH1 +#endif + +#if defined(STM32L1) || defined(STM32L4) || defined(STM32G0) || defined(STM32L5) || defined(STM32H7) || \ + defined(STM32F4) || defined(STM32G4) +#define HAL_DAC_MSP_INIT_CB_ID HAL_DAC_MSPINIT_CB_ID +#define HAL_DAC_MSP_DEINIT_CB_ID HAL_DAC_MSPDEINIT_CB_ID +#endif + +/** + * @} + */ + +/** @defgroup HAL_DMA_Aliased_Defines HAL DMA Aliased Defines maintained for legacy purpose + * @{ + */ +#define HAL_REMAPDMA_ADC_DMA_CH2 DMA_REMAP_ADC_DMA_CH2 +#define HAL_REMAPDMA_USART1_TX_DMA_CH4 DMA_REMAP_USART1_TX_DMA_CH4 +#define HAL_REMAPDMA_USART1_RX_DMA_CH5 DMA_REMAP_USART1_RX_DMA_CH5 +#define HAL_REMAPDMA_TIM16_DMA_CH4 DMA_REMAP_TIM16_DMA_CH4 +#define HAL_REMAPDMA_TIM17_DMA_CH2 DMA_REMAP_TIM17_DMA_CH2 +#define HAL_REMAPDMA_USART3_DMA_CH32 DMA_REMAP_USART3_DMA_CH32 +#define HAL_REMAPDMA_TIM16_DMA_CH6 DMA_REMAP_TIM16_DMA_CH6 +#define HAL_REMAPDMA_TIM17_DMA_CH7 DMA_REMAP_TIM17_DMA_CH7 +#define HAL_REMAPDMA_SPI2_DMA_CH67 DMA_REMAP_SPI2_DMA_CH67 +#define HAL_REMAPDMA_USART2_DMA_CH67 DMA_REMAP_USART2_DMA_CH67 +#define HAL_REMAPDMA_I2C1_DMA_CH76 DMA_REMAP_I2C1_DMA_CH76 +#define HAL_REMAPDMA_TIM1_DMA_CH6 DMA_REMAP_TIM1_DMA_CH6 +#define HAL_REMAPDMA_TIM2_DMA_CH7 DMA_REMAP_TIM2_DMA_CH7 +#define HAL_REMAPDMA_TIM3_DMA_CH6 DMA_REMAP_TIM3_DMA_CH6 + +#define IS_HAL_REMAPDMA IS_DMA_REMAP +#define __HAL_REMAPDMA_CHANNEL_ENABLE __HAL_DMA_REMAP_CHANNEL_ENABLE +#define __HAL_REMAPDMA_CHANNEL_DISABLE __HAL_DMA_REMAP_CHANNEL_DISABLE + +#if defined(STM32L4) + +#define HAL_DMAMUX1_REQUEST_GEN_EXTI0 HAL_DMAMUX1_REQ_GEN_EXTI0 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI1 HAL_DMAMUX1_REQ_GEN_EXTI1 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI2 HAL_DMAMUX1_REQ_GEN_EXTI2 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI3 HAL_DMAMUX1_REQ_GEN_EXTI3 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI4 HAL_DMAMUX1_REQ_GEN_EXTI4 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI5 HAL_DMAMUX1_REQ_GEN_EXTI5 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI6 HAL_DMAMUX1_REQ_GEN_EXTI6 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI7 HAL_DMAMUX1_REQ_GEN_EXTI7 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI8 HAL_DMAMUX1_REQ_GEN_EXTI8 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI9 HAL_DMAMUX1_REQ_GEN_EXTI9 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI10 HAL_DMAMUX1_REQ_GEN_EXTI10 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI11 HAL_DMAMUX1_REQ_GEN_EXTI11 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI12 HAL_DMAMUX1_REQ_GEN_EXTI12 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI13 HAL_DMAMUX1_REQ_GEN_EXTI13 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI14 HAL_DMAMUX1_REQ_GEN_EXTI14 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI15 HAL_DMAMUX1_REQ_GEN_EXTI15 +#define HAL_DMAMUX1_REQUEST_GEN_DMAMUX1_CH0_EVT HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH0_EVT +#define HAL_DMAMUX1_REQUEST_GEN_DMAMUX1_CH1_EVT HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH1_EVT +#define HAL_DMAMUX1_REQUEST_GEN_DMAMUX1_CH2_EVT HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH2_EVT +#define HAL_DMAMUX1_REQUEST_GEN_DMAMUX1_CH3_EVT HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH3_EVT +#define HAL_DMAMUX1_REQUEST_GEN_LPTIM1_OUT HAL_DMAMUX1_REQ_GEN_LPTIM1_OUT +#define HAL_DMAMUX1_REQUEST_GEN_LPTIM2_OUT HAL_DMAMUX1_REQ_GEN_LPTIM2_OUT +#define HAL_DMAMUX1_REQUEST_GEN_DSI_TE HAL_DMAMUX1_REQ_GEN_DSI_TE +#define HAL_DMAMUX1_REQUEST_GEN_DSI_EOT HAL_DMAMUX1_REQ_GEN_DSI_EOT +#define HAL_DMAMUX1_REQUEST_GEN_DMA2D_EOT HAL_DMAMUX1_REQ_GEN_DMA2D_EOT +#define HAL_DMAMUX1_REQUEST_GEN_LTDC_IT HAL_DMAMUX1_REQ_GEN_LTDC_IT + +#define HAL_DMAMUX_REQUEST_GEN_NO_EVENT HAL_DMAMUX_REQ_GEN_NO_EVENT +#define HAL_DMAMUX_REQUEST_GEN_RISING HAL_DMAMUX_REQ_GEN_RISING +#define HAL_DMAMUX_REQUEST_GEN_FALLING HAL_DMAMUX_REQ_GEN_FALLING +#define HAL_DMAMUX_REQUEST_GEN_RISING_FALLING HAL_DMAMUX_REQ_GEN_RISING_FALLING + +#if defined(STM32L4R5xx) || defined(STM32L4R9xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || \ + defined(STM32L4S7xx) || defined(STM32L4S9xx) +#define DMA_REQUEST_DCMI_PSSI DMA_REQUEST_DCMI +#endif + +#endif /* STM32L4 */ + +#if defined(STM32G0) +#define DMA_REQUEST_DAC1_CHANNEL1 DMA_REQUEST_DAC1_CH1 +#define DMA_REQUEST_DAC1_CHANNEL2 DMA_REQUEST_DAC1_CH2 +#define DMA_REQUEST_TIM16_TRIG_COM DMA_REQUEST_TIM16_COM +#define DMA_REQUEST_TIM17_TRIG_COM DMA_REQUEST_TIM17_COM + +#define LL_DMAMUX_REQ_TIM16_TRIG_COM LL_DMAMUX_REQ_TIM16_COM +#define LL_DMAMUX_REQ_TIM17_TRIG_COM LL_DMAMUX_REQ_TIM17_COM +#endif + +#if defined(STM32H7) + +#define DMA_REQUEST_DAC1 DMA_REQUEST_DAC1_CH1 +#define DMA_REQUEST_DAC2 DMA_REQUEST_DAC1_CH2 + +#define BDMA_REQUEST_LP_UART1_RX BDMA_REQUEST_LPUART1_RX +#define BDMA_REQUEST_LP_UART1_TX BDMA_REQUEST_LPUART1_TX + +#define HAL_DMAMUX1_REQUEST_GEN_DMAMUX1_CH0_EVT HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH0_EVT +#define HAL_DMAMUX1_REQUEST_GEN_DMAMUX1_CH1_EVT HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH1_EVT +#define HAL_DMAMUX1_REQUEST_GEN_DMAMUX1_CH2_EVT HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH2_EVT +#define HAL_DMAMUX1_REQUEST_GEN_LPTIM1_OUT HAL_DMAMUX1_REQ_GEN_LPTIM1_OUT +#define HAL_DMAMUX1_REQUEST_GEN_LPTIM2_OUT HAL_DMAMUX1_REQ_GEN_LPTIM2_OUT +#define HAL_DMAMUX1_REQUEST_GEN_LPTIM3_OUT HAL_DMAMUX1_REQ_GEN_LPTIM3_OUT +#define HAL_DMAMUX1_REQUEST_GEN_EXTI0 HAL_DMAMUX1_REQ_GEN_EXTI0 +#define HAL_DMAMUX1_REQUEST_GEN_TIM12_TRGO HAL_DMAMUX1_REQ_GEN_TIM12_TRGO + +#define HAL_DMAMUX2_REQUEST_GEN_DMAMUX2_CH0_EVT HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH0_EVT +#define HAL_DMAMUX2_REQUEST_GEN_DMAMUX2_CH1_EVT HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH1_EVT +#define HAL_DMAMUX2_REQUEST_GEN_DMAMUX2_CH2_EVT HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH2_EVT +#define HAL_DMAMUX2_REQUEST_GEN_DMAMUX2_CH3_EVT HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH3_EVT +#define HAL_DMAMUX2_REQUEST_GEN_DMAMUX2_CH4_EVT HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH4_EVT +#define HAL_DMAMUX2_REQUEST_GEN_DMAMUX2_CH5_EVT HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH5_EVT +#define HAL_DMAMUX2_REQUEST_GEN_DMAMUX2_CH6_EVT HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH6_EVT +#define HAL_DMAMUX2_REQUEST_GEN_LPUART1_RX_WKUP HAL_DMAMUX2_REQ_GEN_LPUART1_RX_WKUP +#define HAL_DMAMUX2_REQUEST_GEN_LPUART1_TX_WKUP HAL_DMAMUX2_REQ_GEN_LPUART1_TX_WKUP +#define HAL_DMAMUX2_REQUEST_GEN_LPTIM2_WKUP HAL_DMAMUX2_REQ_GEN_LPTIM2_WKUP +#define HAL_DMAMUX2_REQUEST_GEN_LPTIM2_OUT HAL_DMAMUX2_REQ_GEN_LPTIM2_OUT +#define HAL_DMAMUX2_REQUEST_GEN_LPTIM3_WKUP HAL_DMAMUX2_REQ_GEN_LPTIM3_WKUP +#define HAL_DMAMUX2_REQUEST_GEN_LPTIM3_OUT HAL_DMAMUX2_REQ_GEN_LPTIM3_OUT +#define HAL_DMAMUX2_REQUEST_GEN_LPTIM4_WKUP HAL_DMAMUX2_REQ_GEN_LPTIM4_WKUP +#define HAL_DMAMUX2_REQUEST_GEN_LPTIM5_WKUP HAL_DMAMUX2_REQ_GEN_LPTIM5_WKUP +#define HAL_DMAMUX2_REQUEST_GEN_I2C4_WKUP HAL_DMAMUX2_REQ_GEN_I2C4_WKUP +#define HAL_DMAMUX2_REQUEST_GEN_SPI6_WKUP HAL_DMAMUX2_REQ_GEN_SPI6_WKUP +#define HAL_DMAMUX2_REQUEST_GEN_COMP1_OUT HAL_DMAMUX2_REQ_GEN_COMP1_OUT +#define HAL_DMAMUX2_REQUEST_GEN_COMP2_OUT HAL_DMAMUX2_REQ_GEN_COMP2_OUT +#define HAL_DMAMUX2_REQUEST_GEN_RTC_WKUP HAL_DMAMUX2_REQ_GEN_RTC_WKUP +#define HAL_DMAMUX2_REQUEST_GEN_EXTI0 HAL_DMAMUX2_REQ_GEN_EXTI0 +#define HAL_DMAMUX2_REQUEST_GEN_EXTI2 HAL_DMAMUX2_REQ_GEN_EXTI2 +#define HAL_DMAMUX2_REQUEST_GEN_I2C4_IT_EVT HAL_DMAMUX2_REQ_GEN_I2C4_IT_EVT +#define HAL_DMAMUX2_REQUEST_GEN_SPI6_IT HAL_DMAMUX2_REQ_GEN_SPI6_IT +#define HAL_DMAMUX2_REQUEST_GEN_LPUART1_TX_IT HAL_DMAMUX2_REQ_GEN_LPUART1_TX_IT +#define HAL_DMAMUX2_REQUEST_GEN_LPUART1_RX_IT HAL_DMAMUX2_REQ_GEN_LPUART1_RX_IT +#define HAL_DMAMUX2_REQUEST_GEN_ADC3_IT HAL_DMAMUX2_REQ_GEN_ADC3_IT +#define HAL_DMAMUX2_REQUEST_GEN_ADC3_AWD1_OUT HAL_DMAMUX2_REQ_GEN_ADC3_AWD1_OUT +#define HAL_DMAMUX2_REQUEST_GEN_BDMA_CH0_IT HAL_DMAMUX2_REQ_GEN_BDMA_CH0_IT +#define HAL_DMAMUX2_REQUEST_GEN_BDMA_CH1_IT HAL_DMAMUX2_REQ_GEN_BDMA_CH1_IT + +#define HAL_DMAMUX_REQUEST_GEN_NO_EVENT HAL_DMAMUX_REQ_GEN_NO_EVENT +#define HAL_DMAMUX_REQUEST_GEN_RISING HAL_DMAMUX_REQ_GEN_RISING +#define HAL_DMAMUX_REQUEST_GEN_FALLING HAL_DMAMUX_REQ_GEN_FALLING +#define HAL_DMAMUX_REQUEST_GEN_RISING_FALLING HAL_DMAMUX_REQ_GEN_RISING_FALLING + +#define DFSDM_FILTER_EXT_TRIG_LPTIM1 DFSDM_FILTER_EXT_TRIG_LPTIM1_OUT +#define DFSDM_FILTER_EXT_TRIG_LPTIM2 DFSDM_FILTER_EXT_TRIG_LPTIM2_OUT +#define DFSDM_FILTER_EXT_TRIG_LPTIM3 DFSDM_FILTER_EXT_TRIG_LPTIM3_OUT + +#define DAC_TRIGGER_LP1_OUT DAC_TRIGGER_LPTIM1_OUT +#define DAC_TRIGGER_LP2_OUT DAC_TRIGGER_LPTIM2_OUT + +#endif /* STM32H7 */ + +#if defined(STM32U5) +#define GPDMA1_REQUEST_DCMI GPDMA1_REQUEST_DCMI_PSSI +#endif /* STM32U5 */ +/** + * @} + */ + +/** @defgroup HAL_FLASH_Aliased_Defines HAL FLASH Aliased Defines maintained for legacy purpose + * @{ + */ + +#define TYPEPROGRAM_BYTE FLASH_TYPEPROGRAM_BYTE +#define TYPEPROGRAM_HALFWORD FLASH_TYPEPROGRAM_HALFWORD +#define TYPEPROGRAM_WORD FLASH_TYPEPROGRAM_WORD +#define TYPEPROGRAM_DOUBLEWORD FLASH_TYPEPROGRAM_DOUBLEWORD +#define TYPEERASE_SECTORS FLASH_TYPEERASE_SECTORS +#define TYPEERASE_PAGES FLASH_TYPEERASE_PAGES +#define TYPEERASE_PAGEERASE FLASH_TYPEERASE_PAGES +#define TYPEERASE_MASSERASE FLASH_TYPEERASE_MASSERASE +#define WRPSTATE_DISABLE OB_WRPSTATE_DISABLE +#define WRPSTATE_ENABLE OB_WRPSTATE_ENABLE +#define HAL_FLASH_TIMEOUT_VALUE FLASH_TIMEOUT_VALUE +#define OBEX_PCROP OPTIONBYTE_PCROP +#define OBEX_BOOTCONFIG OPTIONBYTE_BOOTCONFIG +#define PCROPSTATE_DISABLE OB_PCROP_STATE_DISABLE +#define PCROPSTATE_ENABLE OB_PCROP_STATE_ENABLE +#define TYPEERASEDATA_BYTE FLASH_TYPEERASEDATA_BYTE +#define TYPEERASEDATA_HALFWORD FLASH_TYPEERASEDATA_HALFWORD +#define TYPEERASEDATA_WORD FLASH_TYPEERASEDATA_WORD +#define TYPEPROGRAMDATA_BYTE FLASH_TYPEPROGRAMDATA_BYTE +#define TYPEPROGRAMDATA_HALFWORD FLASH_TYPEPROGRAMDATA_HALFWORD +#define TYPEPROGRAMDATA_WORD FLASH_TYPEPROGRAMDATA_WORD +#define TYPEPROGRAMDATA_FASTBYTE FLASH_TYPEPROGRAMDATA_FASTBYTE +#define TYPEPROGRAMDATA_FASTHALFWORD FLASH_TYPEPROGRAMDATA_FASTHALFWORD +#define TYPEPROGRAMDATA_FASTWORD FLASH_TYPEPROGRAMDATA_FASTWORD +#define PAGESIZE FLASH_PAGE_SIZE +#define TYPEPROGRAM_FASTBYTE FLASH_TYPEPROGRAM_BYTE +#define TYPEPROGRAM_FASTHALFWORD FLASH_TYPEPROGRAM_HALFWORD +#define TYPEPROGRAM_FASTWORD FLASH_TYPEPROGRAM_WORD +#define VOLTAGE_RANGE_1 FLASH_VOLTAGE_RANGE_1 +#define VOLTAGE_RANGE_2 FLASH_VOLTAGE_RANGE_2 +#define VOLTAGE_RANGE_3 FLASH_VOLTAGE_RANGE_3 +#define VOLTAGE_RANGE_4 FLASH_VOLTAGE_RANGE_4 +#define TYPEPROGRAM_FAST FLASH_TYPEPROGRAM_FAST +#define TYPEPROGRAM_FAST_AND_LAST FLASH_TYPEPROGRAM_FAST_AND_LAST +#define WRPAREA_BANK1_AREAA OB_WRPAREA_BANK1_AREAA +#define WRPAREA_BANK1_AREAB OB_WRPAREA_BANK1_AREAB +#define WRPAREA_BANK2_AREAA OB_WRPAREA_BANK2_AREAA +#define WRPAREA_BANK2_AREAB OB_WRPAREA_BANK2_AREAB +#define IWDG_STDBY_FREEZE OB_IWDG_STDBY_FREEZE +#define IWDG_STDBY_ACTIVE OB_IWDG_STDBY_RUN +#define IWDG_STOP_FREEZE OB_IWDG_STOP_FREEZE +#define IWDG_STOP_ACTIVE OB_IWDG_STOP_RUN +#define FLASH_ERROR_NONE HAL_FLASH_ERROR_NONE +#define FLASH_ERROR_RD HAL_FLASH_ERROR_RD +#define FLASH_ERROR_PG HAL_FLASH_ERROR_PROG +#define FLASH_ERROR_PGP HAL_FLASH_ERROR_PGS +#define FLASH_ERROR_WRP HAL_FLASH_ERROR_WRP +#define FLASH_ERROR_OPTV HAL_FLASH_ERROR_OPTV +#define FLASH_ERROR_OPTVUSR HAL_FLASH_ERROR_OPTVUSR +#define FLASH_ERROR_PROG HAL_FLASH_ERROR_PROG +#define FLASH_ERROR_OP HAL_FLASH_ERROR_OPERATION +#define FLASH_ERROR_PGA HAL_FLASH_ERROR_PGA +#define FLASH_ERROR_SIZE HAL_FLASH_ERROR_SIZE +#define FLASH_ERROR_SIZ HAL_FLASH_ERROR_SIZE +#define FLASH_ERROR_PGS HAL_FLASH_ERROR_PGS +#define FLASH_ERROR_MIS HAL_FLASH_ERROR_MIS +#define FLASH_ERROR_FAST HAL_FLASH_ERROR_FAST +#define FLASH_ERROR_FWWERR HAL_FLASH_ERROR_FWWERR +#define FLASH_ERROR_NOTZERO HAL_FLASH_ERROR_NOTZERO +#define FLASH_ERROR_OPERATION HAL_FLASH_ERROR_OPERATION +#define FLASH_ERROR_ERS HAL_FLASH_ERROR_ERS +#define OB_WDG_SW OB_IWDG_SW +#define OB_WDG_HW OB_IWDG_HW +#define OB_SDADC12_VDD_MONITOR_SET OB_SDACD_VDD_MONITOR_SET +#define OB_SDADC12_VDD_MONITOR_RESET OB_SDACD_VDD_MONITOR_RESET +#define OB_RAM_PARITY_CHECK_SET OB_SRAM_PARITY_SET +#define OB_RAM_PARITY_CHECK_RESET OB_SRAM_PARITY_RESET +#define IS_OB_SDADC12_VDD_MONITOR IS_OB_SDACD_VDD_MONITOR +#define OB_RDP_LEVEL0 OB_RDP_LEVEL_0 +#define OB_RDP_LEVEL1 OB_RDP_LEVEL_1 +#define OB_RDP_LEVEL2 OB_RDP_LEVEL_2 +#if defined(STM32G0) || defined(STM32C0) +#define OB_BOOT_LOCK_DISABLE OB_BOOT_ENTRY_FORCED_NONE +#define OB_BOOT_LOCK_ENABLE OB_BOOT_ENTRY_FORCED_FLASH +#else +#define OB_BOOT_ENTRY_FORCED_NONE OB_BOOT_LOCK_DISABLE +#define OB_BOOT_ENTRY_FORCED_FLASH OB_BOOT_LOCK_ENABLE +#endif +#if defined(STM32H7) +#define FLASH_FLAG_SNECCE_BANK1RR FLASH_FLAG_SNECCERR_BANK1 +#define FLASH_FLAG_DBECCE_BANK1RR FLASH_FLAG_DBECCERR_BANK1 +#define FLASH_FLAG_STRBER_BANK1R FLASH_FLAG_STRBERR_BANK1 +#define FLASH_FLAG_SNECCE_BANK2RR FLASH_FLAG_SNECCERR_BANK2 +#define FLASH_FLAG_DBECCE_BANK2RR FLASH_FLAG_DBECCERR_BANK2 +#define FLASH_FLAG_STRBER_BANK2R FLASH_FLAG_STRBERR_BANK2 +#define FLASH_FLAG_WDW FLASH_FLAG_WBNE +#define OB_WRP_SECTOR_All OB_WRP_SECTOR_ALL +#endif /* STM32H7 */ +#if defined(STM32U5) +#define OB_USER_nRST_STOP OB_USER_NRST_STOP +#define OB_USER_nRST_STDBY OB_USER_NRST_STDBY +#define OB_USER_nRST_SHDW OB_USER_NRST_SHDW +#define OB_USER_nSWBOOT0 OB_USER_NSWBOOT0 +#define OB_USER_nBOOT0 OB_USER_NBOOT0 +#define OB_nBOOT0_RESET OB_NBOOT0_RESET +#define OB_nBOOT0_SET OB_NBOOT0_SET +#define OB_USER_SRAM134_RST OB_USER_SRAM_RST +#define OB_SRAM134_RST_ERASE OB_SRAM_RST_ERASE +#define OB_SRAM134_RST_NOT_ERASE OB_SRAM_RST_NOT_ERASE +#endif /* STM32U5 */ + +/** + * @} + */ + +/** @defgroup HAL_JPEG_Aliased_Macros HAL JPEG Aliased Macros maintained for legacy purpose + * @{ + */ + +#if defined(STM32H7) +#define __HAL_RCC_JPEG_CLK_ENABLE __HAL_RCC_JPGDECEN_CLK_ENABLE +#define __HAL_RCC_JPEG_CLK_DISABLE __HAL_RCC_JPGDECEN_CLK_DISABLE +#define __HAL_RCC_JPEG_FORCE_RESET __HAL_RCC_JPGDECRST_FORCE_RESET +#define __HAL_RCC_JPEG_RELEASE_RESET __HAL_RCC_JPGDECRST_RELEASE_RESET +#define __HAL_RCC_JPEG_CLK_SLEEP_ENABLE __HAL_RCC_JPGDEC_CLK_SLEEP_ENABLE +#define __HAL_RCC_JPEG_CLK_SLEEP_DISABLE __HAL_RCC_JPGDEC_CLK_SLEEP_DISABLE +#endif /* STM32H7 */ + +/** + * @} + */ + +/** @defgroup HAL_SYSCFG_Aliased_Defines HAL SYSCFG Aliased Defines maintained for legacy purpose + * @{ + */ + +#define HAL_SYSCFG_FASTMODEPLUS_I2C_PA9 I2C_FASTMODEPLUS_PA9 +#define HAL_SYSCFG_FASTMODEPLUS_I2C_PA10 I2C_FASTMODEPLUS_PA10 +#define HAL_SYSCFG_FASTMODEPLUS_I2C_PB6 I2C_FASTMODEPLUS_PB6 +#define HAL_SYSCFG_FASTMODEPLUS_I2C_PB7 I2C_FASTMODEPLUS_PB7 +#define HAL_SYSCFG_FASTMODEPLUS_I2C_PB8 I2C_FASTMODEPLUS_PB8 +#define HAL_SYSCFG_FASTMODEPLUS_I2C_PB9 I2C_FASTMODEPLUS_PB9 +#define HAL_SYSCFG_FASTMODEPLUS_I2C1 I2C_FASTMODEPLUS_I2C1 +#define HAL_SYSCFG_FASTMODEPLUS_I2C2 I2C_FASTMODEPLUS_I2C2 +#define HAL_SYSCFG_FASTMODEPLUS_I2C3 I2C_FASTMODEPLUS_I2C3 +#if defined(STM32G4) + +#define HAL_SYSCFG_EnableIOAnalogSwitchBooster HAL_SYSCFG_EnableIOSwitchBooster +#define HAL_SYSCFG_DisableIOAnalogSwitchBooster HAL_SYSCFG_DisableIOSwitchBooster +#define HAL_SYSCFG_EnableIOAnalogSwitchVDD HAL_SYSCFG_EnableIOSwitchVDD +#define HAL_SYSCFG_DisableIOAnalogSwitchVDD HAL_SYSCFG_DisableIOSwitchVDD +#endif /* STM32G4 */ + +#if defined(STM32H5) +#define SYSCFG_IT_FPU_IOC SBS_IT_FPU_IOC +#define SYSCFG_IT_FPU_DZC SBS_IT_FPU_DZC +#define SYSCFG_IT_FPU_UFC SBS_IT_FPU_UFC +#define SYSCFG_IT_FPU_OFC SBS_IT_FPU_OFC +#define SYSCFG_IT_FPU_IDC SBS_IT_FPU_IDC +#define SYSCFG_IT_FPU_IXC SBS_IT_FPU_IXC + +#define SYSCFG_BREAK_FLASH_ECC SBS_BREAK_FLASH_ECC +#define SYSCFG_BREAK_PVD SBS_BREAK_PVD +#define SYSCFG_BREAK_SRAM_ECC SBS_BREAK_SRAM_ECC +#define SYSCFG_BREAK_LOCKUP SBS_BREAK_LOCKUP + +#define SYSCFG_VREFBUF_VOLTAGE_SCALE0 VREFBUF_VOLTAGE_SCALE0 +#define SYSCFG_VREFBUF_VOLTAGE_SCALE1 VREFBUF_VOLTAGE_SCALE1 +#define SYSCFG_VREFBUF_VOLTAGE_SCALE2 VREFBUF_VOLTAGE_SCALE2 +#define SYSCFG_VREFBUF_VOLTAGE_SCALE3 VREFBUF_VOLTAGE_SCALE3 + +#define SYSCFG_VREFBUF_HIGH_IMPEDANCE_DISABLE VREFBUF_HIGH_IMPEDANCE_DISABLE +#define SYSCFG_VREFBUF_HIGH_IMPEDANCE_ENABLE VREFBUF_HIGH_IMPEDANCE_ENABLE + +#define SYSCFG_FASTMODEPLUS_PB6 SBS_FASTMODEPLUS_PB6 +#define SYSCFG_FASTMODEPLUS_PB7 SBS_FASTMODEPLUS_PB7 +#define SYSCFG_FASTMODEPLUS_PB8 SBS_FASTMODEPLUS_PB8 +#define SYSCFG_FASTMODEPLUS_PB9 SBS_FASTMODEPLUS_PB9 + +#define SYSCFG_ETH_MII SBS_ETH_MII +#define SYSCFG_ETH_RMII SBS_ETH_RMII +#define IS_SYSCFG_ETHERNET_CONFIG IS_SBS_ETHERNET_CONFIG + +#define SYSCFG_MEMORIES_ERASE_FLAG_IPMEE SBS_MEMORIES_ERASE_FLAG_IPMEE +#define SYSCFG_MEMORIES_ERASE_FLAG_MCLR SBS_MEMORIES_ERASE_FLAG_MCLR +#define IS_SYSCFG_MEMORIES_ERASE_FLAG IS_SBS_MEMORIES_ERASE_FLAG + +#define IS_SYSCFG_CODE_CONFIG IS_SBS_CODE_CONFIG + +#define SYSCFG_MPU_NSEC SBS_MPU_NSEC +#define SYSCFG_VTOR_NSEC SBS_VTOR_NSEC +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define SYSCFG_SAU SBS_SAU +#define SYSCFG_MPU_SEC SBS_MPU_SEC +#define SYSCFG_VTOR_AIRCR_SEC SBS_VTOR_AIRCR_SEC +#define SYSCFG_LOCK_ALL SBS_LOCK_ALL +#else +#define SYSCFG_LOCK_ALL SBS_LOCK_ALL +#endif /* __ARM_FEATURE_CMSE */ + +#define SYSCFG_CLK SBS_CLK +#define SYSCFG_CLASSB SBS_CLASSB +#define SYSCFG_FPU SBS_FPU +#define SYSCFG_ALL SBS_ALL + +#define SYSCFG_SEC SBS_SEC +#define SYSCFG_NSEC SBS_NSEC + +#define __HAL_SYSCFG_FPU_INTERRUPT_ENABLE __HAL_SBS_FPU_INTERRUPT_ENABLE +#define __HAL_SYSCFG_FPU_INTERRUPT_DISABLE __HAL_SBS_FPU_INTERRUPT_DISABLE + +#define __HAL_SYSCFG_BREAK_ECC_LOCK __HAL_SBS_BREAK_ECC_LOCK +#define __HAL_SYSCFG_BREAK_LOCKUP_LOCK __HAL_SBS_BREAK_LOCKUP_LOCK +#define __HAL_SYSCFG_BREAK_PVD_LOCK __HAL_SBS_BREAK_PVD_LOCK +#define __HAL_SYSCFG_BREAK_SRAM_ECC_LOCK __HAL_SBS_BREAK_SRAM_ECC_LOCK + +#define __HAL_SYSCFG_FASTMODEPLUS_ENABLE __HAL_SBS_FASTMODEPLUS_ENABLE +#define __HAL_SYSCFG_FASTMODEPLUS_DISABLE __HAL_SBS_FASTMODEPLUS_DISABLE + +#define __HAL_SYSCFG_GET_MEMORIES_ERASE_STATUS __HAL_SBS_GET_MEMORIES_ERASE_STATUS +#define __HAL_SYSCFG_CLEAR_MEMORIES_ERASE_STATUS __HAL_SBS_CLEAR_MEMORIES_ERASE_STATUS + +#define IS_SYSCFG_FPU_INTERRUPT IS_SBS_FPU_INTERRUPT +#define IS_SYSCFG_BREAK_CONFIG IS_SBS_BREAK_CONFIG +#define IS_SYSCFG_VREFBUF_VOLTAGE_SCALE IS_VREFBUF_VOLTAGE_SCALE +#define IS_SYSCFG_VREFBUF_HIGH_IMPEDANCE IS_VREFBUF_HIGH_IMPEDANCE +#define IS_SYSCFG_VREFBUF_TRIMMING IS_VREFBUF_TRIMMING +#define IS_SYSCFG_FASTMODEPLUS IS_SBS_FASTMODEPLUS +#define IS_SYSCFG_ITEMS_ATTRIBUTES IS_SBS_ITEMS_ATTRIBUTES +#define IS_SYSCFG_ATTRIBUTES IS_SBS_ATTRIBUTES +#define IS_SYSCFG_LOCK_ITEMS IS_SBS_LOCK_ITEMS + +#define HAL_SYSCFG_VREFBUF_VoltageScalingConfig HAL_VREFBUF_VoltageScalingConfig +#define HAL_SYSCFG_VREFBUF_HighImpedanceConfig HAL_VREFBUF_HighImpedanceConfig +#define HAL_SYSCFG_VREFBUF_TrimmingConfig HAL_VREFBUF_TrimmingConfig +#define HAL_SYSCFG_EnableVREFBUF HAL_EnableVREFBUF +#define HAL_SYSCFG_DisableVREFBUF HAL_DisableVREFBUF + +#define HAL_SYSCFG_EnableIOAnalogSwitchBooster HAL_SBS_EnableIOAnalogSwitchBooster +#define HAL_SYSCFG_DisableIOAnalogSwitchBooster HAL_SBS_DisableIOAnalogSwitchBooster +#define HAL_SYSCFG_ETHInterfaceSelect HAL_SBS_ETHInterfaceSelect + +#define HAL_SYSCFG_Lock HAL_SBS_Lock +#define HAL_SYSCFG_GetLock HAL_SBS_GetLock + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define HAL_SYSCFG_ConfigAttributes HAL_SBS_ConfigAttributes +#define HAL_SYSCFG_GetConfigAttributes HAL_SBS_GetConfigAttributes +#endif /* __ARM_FEATURE_CMSE */ + +#endif /* STM32H5 */ + + +/** + * @} + */ + + +/** @defgroup LL_FMC_Aliased_Defines LL FMC Aliased Defines maintained for compatibility purpose + * @{ + */ +#if defined(STM32L4) || defined(STM32F7) || defined(STM32H7) || defined(STM32G4) +#define FMC_NAND_PCC_WAIT_FEATURE_DISABLE FMC_NAND_WAIT_FEATURE_DISABLE +#define FMC_NAND_PCC_WAIT_FEATURE_ENABLE FMC_NAND_WAIT_FEATURE_ENABLE +#define FMC_NAND_PCC_MEM_BUS_WIDTH_8 FMC_NAND_MEM_BUS_WIDTH_8 +#define FMC_NAND_PCC_MEM_BUS_WIDTH_16 FMC_NAND_MEM_BUS_WIDTH_16 +#elif defined(STM32F1) || defined(STM32F2) || defined(STM32F3) || defined(STM32F4) +#define FMC_NAND_WAIT_FEATURE_DISABLE FMC_NAND_PCC_WAIT_FEATURE_DISABLE +#define FMC_NAND_WAIT_FEATURE_ENABLE FMC_NAND_PCC_WAIT_FEATURE_ENABLE +#define FMC_NAND_MEM_BUS_WIDTH_8 FMC_NAND_PCC_MEM_BUS_WIDTH_8 +#define FMC_NAND_MEM_BUS_WIDTH_16 FMC_NAND_PCC_MEM_BUS_WIDTH_16 +#endif +/** + * @} + */ + +/** @defgroup LL_FSMC_Aliased_Defines LL FSMC Aliased Defines maintained for legacy purpose + * @{ + */ + +#define FSMC_NORSRAM_TYPEDEF FSMC_NORSRAM_TypeDef +#define FSMC_NORSRAM_EXTENDED_TYPEDEF FSMC_NORSRAM_EXTENDED_TypeDef +/** + * @} + */ + +/** @defgroup HAL_GPIO_Aliased_Macros HAL GPIO Aliased Macros maintained for legacy purpose + * @{ + */ +#define GET_GPIO_SOURCE GPIO_GET_INDEX +#define GET_GPIO_INDEX GPIO_GET_INDEX + +#if defined(STM32F4) +#define GPIO_AF12_SDMMC GPIO_AF12_SDIO +#define GPIO_AF12_SDMMC1 GPIO_AF12_SDIO +#endif + +#if defined(STM32F7) +#define GPIO_AF12_SDIO GPIO_AF12_SDMMC1 +#define GPIO_AF12_SDMMC GPIO_AF12_SDMMC1 +#endif + +#if defined(STM32L4) +#define GPIO_AF12_SDIO GPIO_AF12_SDMMC1 +#define GPIO_AF12_SDMMC GPIO_AF12_SDMMC1 +#endif + +#if defined(STM32H7) +#define GPIO_AF7_SDIO1 GPIO_AF7_SDMMC1 +#define GPIO_AF8_SDIO1 GPIO_AF8_SDMMC1 +#define GPIO_AF12_SDIO1 GPIO_AF12_SDMMC1 +#define GPIO_AF9_SDIO2 GPIO_AF9_SDMMC2 +#define GPIO_AF10_SDIO2 GPIO_AF10_SDMMC2 +#define GPIO_AF11_SDIO2 GPIO_AF11_SDMMC2 + +#if defined (STM32H743xx) || defined (STM32H753xx) || defined (STM32H750xx) || defined (STM32H742xx) || \ + defined (STM32H745xx) || defined (STM32H755xx) || defined (STM32H747xx) || defined (STM32H757xx) +#define GPIO_AF10_OTG2_HS GPIO_AF10_OTG2_FS +#define GPIO_AF10_OTG1_FS GPIO_AF10_OTG1_HS +#define GPIO_AF12_OTG2_FS GPIO_AF12_OTG1_FS +#endif /*STM32H743xx || STM32H753xx || STM32H750xx || STM32H742xx || STM32H745xx || STM32H755xx || STM32H747xx || \ + STM32H757xx */ +#endif /* STM32H7 */ + +#define GPIO_AF0_LPTIM GPIO_AF0_LPTIM1 +#define GPIO_AF1_LPTIM GPIO_AF1_LPTIM1 +#define GPIO_AF2_LPTIM GPIO_AF2_LPTIM1 + +#if defined(STM32L0) || defined(STM32L4) || defined(STM32F4) || defined(STM32F2) || defined(STM32F7) || \ + defined(STM32G4) || defined(STM32H7) || defined(STM32WB) || defined(STM32U5) +#define GPIO_SPEED_LOW GPIO_SPEED_FREQ_LOW +#define GPIO_SPEED_MEDIUM GPIO_SPEED_FREQ_MEDIUM +#define GPIO_SPEED_FAST GPIO_SPEED_FREQ_HIGH +#define GPIO_SPEED_HIGH GPIO_SPEED_FREQ_VERY_HIGH +#endif /* STM32L0 || STM32L4 || STM32F4 || STM32F2 || STM32F7 || STM32G4 || STM32H7 || STM32WB || STM32U5*/ + +#if defined(STM32L1) +#define GPIO_SPEED_VERY_LOW GPIO_SPEED_FREQ_LOW +#define GPIO_SPEED_LOW GPIO_SPEED_FREQ_MEDIUM +#define GPIO_SPEED_MEDIUM GPIO_SPEED_FREQ_HIGH +#define GPIO_SPEED_HIGH GPIO_SPEED_FREQ_VERY_HIGH +#endif /* STM32L1 */ + +#if defined(STM32F0) || defined(STM32F3) || defined(STM32F1) +#define GPIO_SPEED_LOW GPIO_SPEED_FREQ_LOW +#define GPIO_SPEED_MEDIUM GPIO_SPEED_FREQ_MEDIUM +#define GPIO_SPEED_HIGH GPIO_SPEED_FREQ_HIGH +#endif /* STM32F0 || STM32F3 || STM32F1 */ + +#define GPIO_AF6_DFSDM GPIO_AF6_DFSDM1 + +#if defined(STM32U5) || defined(STM32H5) +#define GPIO_AF0_RTC_50Hz GPIO_AF0_RTC_50HZ +#endif /* STM32U5 || STM32H5 */ +#if defined(STM32U5) +#define GPIO_AF0_S2DSTOP GPIO_AF0_SRDSTOP +#define GPIO_AF11_LPGPIO GPIO_AF11_LPGPIO1 +#endif /* STM32U5 */ +/** + * @} + */ + +/** @defgroup HAL_GTZC_Aliased_Defines HAL GTZC Aliased Defines maintained for legacy purpose + * @{ + */ +#if defined(STM32U5) +#define GTZC_PERIPH_DCMI GTZC_PERIPH_DCMI_PSSI +#define GTZC_PERIPH_LTDC GTZC_PERIPH_LTDCUSB +#endif /* STM32U5 */ +#if defined(STM32H5) +#define GTZC_PERIPH_DAC12 GTZC_PERIPH_DAC1 +#define GTZC_PERIPH_ADC12 GTZC_PERIPH_ADC +#define GTZC_PERIPH_USBFS GTZC_PERIPH_USB +#endif /* STM32H5 */ +#if defined(STM32H5) || defined(STM32U5) +#define GTZC_MCPBB_NB_VCTR_REG_MAX GTZC_MPCBB_NB_VCTR_REG_MAX +#define GTZC_MCPBB_NB_LCK_VCTR_REG_MAX GTZC_MPCBB_NB_LCK_VCTR_REG_MAX +#define GTZC_MCPBB_SUPERBLOCK_UNLOCKED GTZC_MPCBB_SUPERBLOCK_UNLOCKED +#define GTZC_MCPBB_SUPERBLOCK_LOCKED GTZC_MPCBB_SUPERBLOCK_LOCKED +#define GTZC_MCPBB_BLOCK_NSEC GTZC_MPCBB_BLOCK_NSEC +#define GTZC_MCPBB_BLOCK_SEC GTZC_MPCBB_BLOCK_SEC +#define GTZC_MCPBB_BLOCK_NPRIV GTZC_MPCBB_BLOCK_NPRIV +#define GTZC_MCPBB_BLOCK_PRIV GTZC_MPCBB_BLOCK_PRIV +#define GTZC_MCPBB_LOCK_OFF GTZC_MPCBB_LOCK_OFF +#define GTZC_MCPBB_LOCK_ON GTZC_MPCBB_LOCK_ON +#endif /* STM32H5 || STM32U5 */ +/** + * @} + */ + +/** @defgroup HAL_HRTIM_Aliased_Macros HAL HRTIM Aliased Macros maintained for legacy purpose + * @{ + */ +#define HRTIM_TIMDELAYEDPROTECTION_DISABLED HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DISABLED +#define HRTIM_TIMDELAYEDPROTECTION_DELAYEDOUT1_EEV68 HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DELAYEDOUT1_EEV6 +#define HRTIM_TIMDELAYEDPROTECTION_DELAYEDOUT2_EEV68 HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DELAYEDOUT2_EEV6 +#define HRTIM_TIMDELAYEDPROTECTION_DELAYEDBOTH_EEV68 HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DELAYEDBOTH_EEV6 +#define HRTIM_TIMDELAYEDPROTECTION_BALANCED_EEV68 HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_BALANCED_EEV6 +#define HRTIM_TIMDELAYEDPROTECTION_DELAYEDOUT1_DEEV79 HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DELAYEDOUT1_DEEV7 +#define HRTIM_TIMDELAYEDPROTECTION_DELAYEDOUT2_DEEV79 HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DELAYEDOUT2_DEEV7 +#define HRTIM_TIMDELAYEDPROTECTION_DELAYEDBOTH_EEV79 HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DELAYEDBOTH_EEV7 +#define HRTIM_TIMDELAYEDPROTECTION_BALANCED_EEV79 HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_BALANCED_EEV7 + +#define __HAL_HRTIM_SetCounter __HAL_HRTIM_SETCOUNTER +#define __HAL_HRTIM_GetCounter __HAL_HRTIM_GETCOUNTER +#define __HAL_HRTIM_SetPeriod __HAL_HRTIM_SETPERIOD +#define __HAL_HRTIM_GetPeriod __HAL_HRTIM_GETPERIOD +#define __HAL_HRTIM_SetClockPrescaler __HAL_HRTIM_SETCLOCKPRESCALER +#define __HAL_HRTIM_GetClockPrescaler __HAL_HRTIM_GETCLOCKPRESCALER +#define __HAL_HRTIM_SetCompare __HAL_HRTIM_SETCOMPARE +#define __HAL_HRTIM_GetCompare __HAL_HRTIM_GETCOMPARE + +#if defined(STM32G4) +#define HAL_HRTIM_ExternalEventCounterConfig HAL_HRTIM_ExtEventCounterConfig +#define HAL_HRTIM_ExternalEventCounterEnable HAL_HRTIM_ExtEventCounterEnable +#define HAL_HRTIM_ExternalEventCounterDisable HAL_HRTIM_ExtEventCounterDisable +#define HAL_HRTIM_ExternalEventCounterReset HAL_HRTIM_ExtEventCounterReset +#define HRTIM_TIMEEVENT_A HRTIM_EVENTCOUNTER_A +#define HRTIM_TIMEEVENT_B HRTIM_EVENTCOUNTER_B +#define HRTIM_TIMEEVENTRESETMODE_UNCONDITIONAL HRTIM_EVENTCOUNTER_RSTMODE_UNCONDITIONAL +#define HRTIM_TIMEEVENTRESETMODE_CONDITIONAL HRTIM_EVENTCOUNTER_RSTMODE_CONDITIONAL +#endif /* STM32G4 */ + +#if defined(STM32H7) +#define HRTIM_OUTPUTSET_TIMAEV1_TIMBCMP1 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTSET_TIMAEV2_TIMBCMP2 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTSET_TIMAEV3_TIMCCMP2 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTSET_TIMAEV4_TIMCCMP3 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTSET_TIMAEV5_TIMDCMP1 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTSET_TIMAEV6_TIMDCMP2 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTSET_TIMAEV7_TIMECMP3 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTSET_TIMAEV8_TIMECMP4 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTSET_TIMAEV9_TIMFCMP4 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTSET_TIMBEV1_TIMACMP1 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTSET_TIMBEV2_TIMACMP2 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTSET_TIMBEV3_TIMCCMP3 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTSET_TIMBEV4_TIMCCMP4 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTSET_TIMBEV5_TIMDCMP3 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTSET_TIMBEV6_TIMDCMP4 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTSET_TIMBEV7_TIMECMP1 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTSET_TIMBEV8_TIMECMP2 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTSET_TIMBEV9_TIMFCMP3 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTSET_TIMCEV1_TIMACMP1 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTSET_TIMCEV2_TIMACMP2 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTSET_TIMCEV3_TIMBCMP2 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTSET_TIMCEV4_TIMBCMP3 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTSET_TIMCEV5_TIMDCMP2 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTSET_TIMCEV6_TIMDCMP4 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTSET_TIMCEV7_TIMECMP3 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTSET_TIMCEV8_TIMECMP4 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTSET_TIMCEV9_TIMFCMP2 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTSET_TIMDEV1_TIMACMP1 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTSET_TIMDEV2_TIMACMP4 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTSET_TIMDEV3_TIMBCMP2 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTSET_TIMDEV4_TIMBCMP4 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTSET_TIMDEV5_TIMCCMP4 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTSET_TIMDEV6_TIMECMP1 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTSET_TIMDEV7_TIMECMP4 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTSET_TIMDEV8_TIMFCMP1 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTSET_TIMDEV9_TIMFCMP3 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTSET_TIMEEV1_TIMACMP4 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTSET_TIMEEV2_TIMBCMP3 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTSET_TIMEEV3_TIMBCMP4 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTSET_TIMEEV4_TIMCCMP1 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTSET_TIMEEV5_TIMDCMP2 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTSET_TIMEEV6_TIMDCMP1 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTSET_TIMEEV7_TIMDCMP2 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTSET_TIMEEV8_TIMFCMP3 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTSET_TIMEEV9_TIMFCMP4 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTSET_TIMFEV1_TIMACMP3 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTSET_TIMFEV2_TIMBCMP1 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTSET_TIMFEV3_TIMBCMP4 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTSET_TIMFEV4_TIMCCMP1 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTSET_TIMFEV5_TIMCCMP4 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTSET_TIMFEV6_TIMDCMP3 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTSET_TIMFEV7_TIMDCMP4 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTSET_TIMFEV8_TIMECMP2 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTSET_TIMFEV9_TIMECMP3 HRTIM_OUTPUTSET_TIMEV_9 + +#define HRTIM_OUTPUTRESET_TIMAEV1_TIMBCMP1 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTRESET_TIMAEV2_TIMBCMP2 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTRESET_TIMAEV3_TIMCCMP2 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTRESET_TIMAEV4_TIMCCMP3 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTRESET_TIMAEV5_TIMDCMP1 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTRESET_TIMAEV6_TIMDCMP2 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTRESET_TIMAEV7_TIMECMP3 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTRESET_TIMAEV8_TIMECMP4 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTRESET_TIMAEV9_TIMFCMP4 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTRESET_TIMBEV1_TIMACMP1 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTRESET_TIMBEV2_TIMACMP2 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTRESET_TIMBEV3_TIMCCMP3 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTRESET_TIMBEV4_TIMCCMP4 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTRESET_TIMBEV5_TIMDCMP3 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTRESET_TIMBEV6_TIMDCMP4 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTRESET_TIMBEV7_TIMECMP1 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTRESET_TIMBEV8_TIMECMP2 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTRESET_TIMBEV9_TIMFCMP3 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTRESET_TIMCEV1_TIMACMP1 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTRESET_TIMCEV2_TIMACMP2 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTRESET_TIMCEV3_TIMBCMP2 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTRESET_TIMCEV4_TIMBCMP3 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTRESET_TIMCEV5_TIMDCMP2 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTRESET_TIMCEV6_TIMDCMP4 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTRESET_TIMCEV7_TIMECMP3 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTRESET_TIMCEV8_TIMECMP4 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTRESET_TIMCEV9_TIMFCMP2 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTRESET_TIMDEV1_TIMACMP1 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTRESET_TIMDEV2_TIMACMP4 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTRESET_TIMDEV3_TIMBCMP2 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTRESET_TIMDEV4_TIMBCMP4 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTRESET_TIMDEV5_TIMCCMP4 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTRESET_TIMDEV6_TIMECMP1 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTRESET_TIMDEV7_TIMECMP4 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTRESET_TIMDEV8_TIMFCMP1 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTRESET_TIMDEV9_TIMFCMP3 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTRESET_TIMEEV1_TIMACMP4 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTRESET_TIMEEV2_TIMBCMP3 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTRESET_TIMEEV3_TIMBCMP4 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTRESET_TIMEEV4_TIMCCMP1 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTRESET_TIMEEV5_TIMDCMP2 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTRESET_TIMEEV6_TIMDCMP1 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTRESET_TIMEEV7_TIMDCMP2 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTRESET_TIMEEV8_TIMFCMP3 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTRESET_TIMEEV9_TIMFCMP4 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTRESET_TIMFEV1_TIMACMP3 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTRESET_TIMFEV2_TIMBCMP1 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTRESET_TIMFEV3_TIMBCMP4 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTRESET_TIMFEV4_TIMCCMP1 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTRESET_TIMFEV5_TIMCCMP4 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTRESET_TIMFEV6_TIMDCMP3 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTRESET_TIMFEV7_TIMDCMP4 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTRESET_TIMFEV8_TIMECMP2 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTRESET_TIMFEV9_TIMECMP3 HRTIM_OUTPUTSET_TIMEV_9 +#endif /* STM32H7 */ + +#if defined(STM32F3) +/** @brief Constants defining available sources associated to external events. + */ +#define HRTIM_EVENTSRC_1 (0x00000000U) +#define HRTIM_EVENTSRC_2 (HRTIM_EECR1_EE1SRC_0) +#define HRTIM_EVENTSRC_3 (HRTIM_EECR1_EE1SRC_1) +#define HRTIM_EVENTSRC_4 (HRTIM_EECR1_EE1SRC_1 | HRTIM_EECR1_EE1SRC_0) + +/** @brief Constants defining the DLL calibration periods (in micro seconds) + */ +#define HRTIM_CALIBRATIONRATE_7300 0x00000000U +#define HRTIM_CALIBRATIONRATE_910 (HRTIM_DLLCR_CALRTE_0) +#define HRTIM_CALIBRATIONRATE_114 (HRTIM_DLLCR_CALRTE_1) +#define HRTIM_CALIBRATIONRATE_14 (HRTIM_DLLCR_CALRTE_1 | HRTIM_DLLCR_CALRTE_0) + +#endif /* STM32F3 */ +/** + * @} + */ + +/** @defgroup HAL_I2C_Aliased_Defines HAL I2C Aliased Defines maintained for legacy purpose + * @{ + */ +#define I2C_DUALADDRESS_DISABLED I2C_DUALADDRESS_DISABLE +#define I2C_DUALADDRESS_ENABLED I2C_DUALADDRESS_ENABLE +#define I2C_GENERALCALL_DISABLED I2C_GENERALCALL_DISABLE +#define I2C_GENERALCALL_ENABLED I2C_GENERALCALL_ENABLE +#define I2C_NOSTRETCH_DISABLED I2C_NOSTRETCH_DISABLE +#define I2C_NOSTRETCH_ENABLED I2C_NOSTRETCH_ENABLE +#define I2C_ANALOGFILTER_ENABLED I2C_ANALOGFILTER_ENABLE +#define I2C_ANALOGFILTER_DISABLED I2C_ANALOGFILTER_DISABLE +#if defined(STM32F0) || defined(STM32F1) || defined(STM32F3) || defined(STM32G0) || defined(STM32L4) || \ + defined(STM32L1) || defined(STM32F7) +#define HAL_I2C_STATE_MEM_BUSY_TX HAL_I2C_STATE_BUSY_TX +#define HAL_I2C_STATE_MEM_BUSY_RX HAL_I2C_STATE_BUSY_RX +#define HAL_I2C_STATE_MASTER_BUSY_TX HAL_I2C_STATE_BUSY_TX +#define HAL_I2C_STATE_MASTER_BUSY_RX HAL_I2C_STATE_BUSY_RX +#define HAL_I2C_STATE_SLAVE_BUSY_TX HAL_I2C_STATE_BUSY_TX +#define HAL_I2C_STATE_SLAVE_BUSY_RX HAL_I2C_STATE_BUSY_RX +#endif +/** + * @} + */ + +/** @defgroup HAL_IRDA_Aliased_Defines HAL IRDA Aliased Defines maintained for legacy purpose + * @{ + */ +#define IRDA_ONE_BIT_SAMPLE_DISABLED IRDA_ONE_BIT_SAMPLE_DISABLE +#define IRDA_ONE_BIT_SAMPLE_ENABLED IRDA_ONE_BIT_SAMPLE_ENABLE + +/** + * @} + */ + +/** @defgroup HAL_IWDG_Aliased_Defines HAL IWDG Aliased Defines maintained for legacy purpose + * @{ + */ +#define KR_KEY_RELOAD IWDG_KEY_RELOAD +#define KR_KEY_ENABLE IWDG_KEY_ENABLE +#define KR_KEY_EWA IWDG_KEY_WRITE_ACCESS_ENABLE +#define KR_KEY_DWA IWDG_KEY_WRITE_ACCESS_DISABLE +/** + * @} + */ + +/** @defgroup HAL_LPTIM_Aliased_Defines HAL LPTIM Aliased Defines maintained for legacy purpose + * @{ + */ + +#define LPTIM_CLOCKSAMPLETIME_DIRECTTRANSISTION LPTIM_CLOCKSAMPLETIME_DIRECTTRANSITION +#define LPTIM_CLOCKSAMPLETIME_2TRANSISTIONS LPTIM_CLOCKSAMPLETIME_2TRANSITIONS +#define LPTIM_CLOCKSAMPLETIME_4TRANSISTIONS LPTIM_CLOCKSAMPLETIME_4TRANSITIONS +#define LPTIM_CLOCKSAMPLETIME_8TRANSISTIONS LPTIM_CLOCKSAMPLETIME_8TRANSITIONS + +#define LPTIM_CLOCKPOLARITY_RISINGEDGE LPTIM_CLOCKPOLARITY_RISING +#define LPTIM_CLOCKPOLARITY_FALLINGEDGE LPTIM_CLOCKPOLARITY_FALLING +#define LPTIM_CLOCKPOLARITY_BOTHEDGES LPTIM_CLOCKPOLARITY_RISING_FALLING + +#define LPTIM_TRIGSAMPLETIME_DIRECTTRANSISTION LPTIM_TRIGSAMPLETIME_DIRECTTRANSITION +#define LPTIM_TRIGSAMPLETIME_2TRANSISTIONS LPTIM_TRIGSAMPLETIME_2TRANSITIONS +#define LPTIM_TRIGSAMPLETIME_4TRANSISTIONS LPTIM_TRIGSAMPLETIME_4TRANSITIONS +#define LPTIM_TRIGSAMPLETIME_8TRANSISTIONS LPTIM_TRIGSAMPLETIME_8TRANSITIONS + +/* The following 3 definition have also been present in a temporary version of lptim.h */ +/* They need to be renamed also to the right name, just in case */ +#define LPTIM_TRIGSAMPLETIME_2TRANSITION LPTIM_TRIGSAMPLETIME_2TRANSITIONS +#define LPTIM_TRIGSAMPLETIME_4TRANSITION LPTIM_TRIGSAMPLETIME_4TRANSITIONS +#define LPTIM_TRIGSAMPLETIME_8TRANSITION LPTIM_TRIGSAMPLETIME_8TRANSITIONS + + +/** @defgroup HAL_LPTIM_Aliased_Defines HAL LPTIM Aliased Defines maintained for legacy purpose + * @{ + */ +#define HAL_LPTIM_ReadCompare HAL_LPTIM_ReadCapturedValue +/** + * @} + */ + +#if defined(STM32U5) +#define LPTIM_ISR_CC1 LPTIM_ISR_CC1IF +#define LPTIM_ISR_CC2 LPTIM_ISR_CC2IF +#define LPTIM_CHANNEL_ALL 0x00000000U +#endif /* STM32U5 */ +/** + * @} + */ + +/** @defgroup HAL_NAND_Aliased_Defines HAL NAND Aliased Defines maintained for legacy purpose + * @{ + */ +#define HAL_NAND_Read_Page HAL_NAND_Read_Page_8b +#define HAL_NAND_Write_Page HAL_NAND_Write_Page_8b +#define HAL_NAND_Read_SpareArea HAL_NAND_Read_SpareArea_8b +#define HAL_NAND_Write_SpareArea HAL_NAND_Write_SpareArea_8b + +#define NAND_AddressTypedef NAND_AddressTypeDef + +#define __ARRAY_ADDRESS ARRAY_ADDRESS +#define __ADDR_1st_CYCLE ADDR_1ST_CYCLE +#define __ADDR_2nd_CYCLE ADDR_2ND_CYCLE +#define __ADDR_3rd_CYCLE ADDR_3RD_CYCLE +#define __ADDR_4th_CYCLE ADDR_4TH_CYCLE +/** + * @} + */ + +/** @defgroup HAL_NOR_Aliased_Defines HAL NOR Aliased Defines maintained for legacy purpose + * @{ + */ +#define NOR_StatusTypedef HAL_NOR_StatusTypeDef +#define NOR_SUCCESS HAL_NOR_STATUS_SUCCESS +#define NOR_ONGOING HAL_NOR_STATUS_ONGOING +#define NOR_ERROR HAL_NOR_STATUS_ERROR +#define NOR_TIMEOUT HAL_NOR_STATUS_TIMEOUT + +#define __NOR_WRITE NOR_WRITE +#define __NOR_ADDR_SHIFT NOR_ADDR_SHIFT +/** + * @} + */ + +/** @defgroup HAL_OPAMP_Aliased_Defines HAL OPAMP Aliased Defines maintained for legacy purpose + * @{ + */ + +#define OPAMP_NONINVERTINGINPUT_VP0 OPAMP_NONINVERTINGINPUT_IO0 +#define OPAMP_NONINVERTINGINPUT_VP1 OPAMP_NONINVERTINGINPUT_IO1 +#define OPAMP_NONINVERTINGINPUT_VP2 OPAMP_NONINVERTINGINPUT_IO2 +#define OPAMP_NONINVERTINGINPUT_VP3 OPAMP_NONINVERTINGINPUT_IO3 + +#define OPAMP_SEC_NONINVERTINGINPUT_VP0 OPAMP_SEC_NONINVERTINGINPUT_IO0 +#define OPAMP_SEC_NONINVERTINGINPUT_VP1 OPAMP_SEC_NONINVERTINGINPUT_IO1 +#define OPAMP_SEC_NONINVERTINGINPUT_VP2 OPAMP_SEC_NONINVERTINGINPUT_IO2 +#define OPAMP_SEC_NONINVERTINGINPUT_VP3 OPAMP_SEC_NONINVERTINGINPUT_IO3 + +#define OPAMP_INVERTINGINPUT_VM0 OPAMP_INVERTINGINPUT_IO0 +#define OPAMP_INVERTINGINPUT_VM1 OPAMP_INVERTINGINPUT_IO1 + +#define IOPAMP_INVERTINGINPUT_VM0 OPAMP_INVERTINGINPUT_IO0 +#define IOPAMP_INVERTINGINPUT_VM1 OPAMP_INVERTINGINPUT_IO1 + +#define OPAMP_SEC_INVERTINGINPUT_VM0 OPAMP_SEC_INVERTINGINPUT_IO0 +#define OPAMP_SEC_INVERTINGINPUT_VM1 OPAMP_SEC_INVERTINGINPUT_IO1 + +#define OPAMP_INVERTINGINPUT_VINM OPAMP_SEC_INVERTINGINPUT_IO1 + +#define OPAMP_PGACONNECT_NO OPAMP_PGA_CONNECT_INVERTINGINPUT_NO +#define OPAMP_PGACONNECT_VM0 OPAMP_PGA_CONNECT_INVERTINGINPUT_IO0 +#define OPAMP_PGACONNECT_VM1 OPAMP_PGA_CONNECT_INVERTINGINPUT_IO1 + +#if defined(STM32L1) || defined(STM32L4) || defined(STM32L5) || defined(STM32H7) || defined(STM32G4) || defined(STM32U5) +#define HAL_OPAMP_MSP_INIT_CB_ID HAL_OPAMP_MSPINIT_CB_ID +#define HAL_OPAMP_MSP_DEINIT_CB_ID HAL_OPAMP_MSPDEINIT_CB_ID +#endif + +#if defined(STM32L4) || defined(STM32L5) +#define OPAMP_POWERMODE_NORMAL OPAMP_POWERMODE_NORMALPOWER +#elif defined(STM32G4) +#define OPAMP_POWERMODE_NORMAL OPAMP_POWERMODE_NORMALSPEED +#endif + +/** + * @} + */ + +/** @defgroup HAL_I2S_Aliased_Defines HAL I2S Aliased Defines maintained for legacy purpose + * @{ + */ +#define I2S_STANDARD_PHILLIPS I2S_STANDARD_PHILIPS + +#if defined(STM32H7) +#define I2S_IT_TXE I2S_IT_TXP +#define I2S_IT_RXNE I2S_IT_RXP + +#define I2S_FLAG_TXE I2S_FLAG_TXP +#define I2S_FLAG_RXNE I2S_FLAG_RXP +#endif + +#if defined(STM32F7) +#define I2S_CLOCK_SYSCLK I2S_CLOCK_PLL +#endif +/** + * @} + */ + +/** @defgroup HAL_PCCARD_Aliased_Defines HAL PCCARD Aliased Defines maintained for legacy purpose + * @{ + */ + +/* Compact Flash-ATA registers description */ +#define CF_DATA ATA_DATA +#define CF_SECTOR_COUNT ATA_SECTOR_COUNT +#define CF_SECTOR_NUMBER ATA_SECTOR_NUMBER +#define CF_CYLINDER_LOW ATA_CYLINDER_LOW +#define CF_CYLINDER_HIGH ATA_CYLINDER_HIGH +#define CF_CARD_HEAD ATA_CARD_HEAD +#define CF_STATUS_CMD ATA_STATUS_CMD +#define CF_STATUS_CMD_ALTERNATE ATA_STATUS_CMD_ALTERNATE +#define CF_COMMON_DATA_AREA ATA_COMMON_DATA_AREA + +/* Compact Flash-ATA commands */ +#define CF_READ_SECTOR_CMD ATA_READ_SECTOR_CMD +#define CF_WRITE_SECTOR_CMD ATA_WRITE_SECTOR_CMD +#define CF_ERASE_SECTOR_CMD ATA_ERASE_SECTOR_CMD +#define CF_IDENTIFY_CMD ATA_IDENTIFY_CMD + +#define PCCARD_StatusTypedef HAL_PCCARD_StatusTypeDef +#define PCCARD_SUCCESS HAL_PCCARD_STATUS_SUCCESS +#define PCCARD_ONGOING HAL_PCCARD_STATUS_ONGOING +#define PCCARD_ERROR HAL_PCCARD_STATUS_ERROR +#define PCCARD_TIMEOUT HAL_PCCARD_STATUS_TIMEOUT +/** + * @} + */ + +/** @defgroup HAL_RTC_Aliased_Defines HAL RTC Aliased Defines maintained for legacy purpose + * @{ + */ + +#define FORMAT_BIN RTC_FORMAT_BIN +#define FORMAT_BCD RTC_FORMAT_BCD + +#define RTC_ALARMSUBSECONDMASK_None RTC_ALARMSUBSECONDMASK_NONE +#define RTC_TAMPERERASEBACKUP_DISABLED RTC_TAMPER_ERASE_BACKUP_DISABLE +#define RTC_TAMPERMASK_FLAG_DISABLED RTC_TAMPERMASK_FLAG_DISABLE +#define RTC_TAMPERMASK_FLAG_ENABLED RTC_TAMPERMASK_FLAG_ENABLE + +#define RTC_MASKTAMPERFLAG_DISABLED RTC_TAMPERMASK_FLAG_DISABLE +#define RTC_MASKTAMPERFLAG_ENABLED RTC_TAMPERMASK_FLAG_ENABLE +#define RTC_TAMPERERASEBACKUP_ENABLED RTC_TAMPER_ERASE_BACKUP_ENABLE +#define RTC_TAMPER1_2_INTERRUPT RTC_ALL_TAMPER_INTERRUPT +#define RTC_TAMPER1_2_3_INTERRUPT RTC_ALL_TAMPER_INTERRUPT + +#define RTC_TIMESTAMPPIN_PC13 RTC_TIMESTAMPPIN_DEFAULT +#define RTC_TIMESTAMPPIN_PA0 RTC_TIMESTAMPPIN_POS1 +#define RTC_TIMESTAMPPIN_PI8 RTC_TIMESTAMPPIN_POS1 +#define RTC_TIMESTAMPPIN_PC1 RTC_TIMESTAMPPIN_POS2 + +#define RTC_OUTPUT_REMAP_PC13 RTC_OUTPUT_REMAP_NONE +#define RTC_OUTPUT_REMAP_PB14 RTC_OUTPUT_REMAP_POS1 +#define RTC_OUTPUT_REMAP_PB2 RTC_OUTPUT_REMAP_POS1 + +#define RTC_TAMPERPIN_PC13 RTC_TAMPERPIN_DEFAULT +#define RTC_TAMPERPIN_PA0 RTC_TAMPERPIN_POS1 +#define RTC_TAMPERPIN_PI8 RTC_TAMPERPIN_POS1 + +#if defined(STM32H5) +#define TAMP_SECRETDEVICE_ERASE_NONE TAMP_DEVICESECRETS_ERASE_NONE +#define TAMP_SECRETDEVICE_ERASE_BKP_SRAM TAMP_DEVICESECRETS_ERASE_BKPSRAM +#endif /* STM32H5 */ + +#if defined(STM32WBA) +#define TAMP_SECRETDEVICE_ERASE_NONE TAMP_DEVICESECRETS_ERASE_NONE +#define TAMP_SECRETDEVICE_ERASE_SRAM2 TAMP_DEVICESECRETS_ERASE_SRAM2 +#define TAMP_SECRETDEVICE_ERASE_RHUK TAMP_DEVICESECRETS_ERASE_RHUK +#define TAMP_SECRETDEVICE_ERASE_ICACHE TAMP_DEVICESECRETS_ERASE_ICACHE +#define TAMP_SECRETDEVICE_ERASE_SAES_AES_HASH TAMP_DEVICESECRETS_ERASE_SAES_AES_HASH +#define TAMP_SECRETDEVICE_ERASE_PKA_SRAM TAMP_DEVICESECRETS_ERASE_PKA_SRAM +#define TAMP_SECRETDEVICE_ERASE_ALL TAMP_DEVICESECRETS_ERASE_ALL +#endif /* STM32WBA */ + +#if defined(STM32H5) || defined(STM32WBA) +#define TAMP_SECRETDEVICE_ERASE_DISABLE TAMP_DEVICESECRETS_ERASE_NONE +#define TAMP_SECRETDEVICE_ERASE_ENABLE TAMP_SECRETDEVICE_ERASE_ALL +#endif /* STM32H5 || STM32WBA */ + +#if defined(STM32F7) +#define RTC_TAMPCR_TAMPXE RTC_TAMPER_ENABLE_BITS_MASK +#define RTC_TAMPCR_TAMPXIE RTC_TAMPER_IT_ENABLE_BITS_MASK +#endif /* STM32F7 */ + +#if defined(STM32H7) +#define RTC_TAMPCR_TAMPXE RTC_TAMPER_X +#define RTC_TAMPCR_TAMPXIE RTC_TAMPER_X_INTERRUPT +#endif /* STM32H7 */ + +#if defined(STM32F7) || defined(STM32H7) || defined(STM32L0) +#define RTC_TAMPER1_INTERRUPT RTC_IT_TAMP1 +#define RTC_TAMPER2_INTERRUPT RTC_IT_TAMP2 +#define RTC_TAMPER3_INTERRUPT RTC_IT_TAMP3 +#define RTC_ALL_TAMPER_INTERRUPT RTC_IT_TAMP +#endif /* STM32F7 || STM32H7 || STM32L0 */ + +/** + * @} + */ + + +/** @defgroup HAL_SMARTCARD_Aliased_Defines HAL SMARTCARD Aliased Defines maintained for legacy purpose + * @{ + */ +#define SMARTCARD_NACK_ENABLED SMARTCARD_NACK_ENABLE +#define SMARTCARD_NACK_DISABLED SMARTCARD_NACK_DISABLE + +#define SMARTCARD_ONEBIT_SAMPLING_DISABLED SMARTCARD_ONE_BIT_SAMPLE_DISABLE +#define SMARTCARD_ONEBIT_SAMPLING_ENABLED SMARTCARD_ONE_BIT_SAMPLE_ENABLE +#define SMARTCARD_ONEBIT_SAMPLING_DISABLE SMARTCARD_ONE_BIT_SAMPLE_DISABLE +#define SMARTCARD_ONEBIT_SAMPLING_ENABLE SMARTCARD_ONE_BIT_SAMPLE_ENABLE + +#define SMARTCARD_TIMEOUT_DISABLED SMARTCARD_TIMEOUT_DISABLE +#define SMARTCARD_TIMEOUT_ENABLED SMARTCARD_TIMEOUT_ENABLE + +#define SMARTCARD_LASTBIT_DISABLED SMARTCARD_LASTBIT_DISABLE +#define SMARTCARD_LASTBIT_ENABLED SMARTCARD_LASTBIT_ENABLE +/** + * @} + */ + + +/** @defgroup HAL_SMBUS_Aliased_Defines HAL SMBUS Aliased Defines maintained for legacy purpose + * @{ + */ +#define SMBUS_DUALADDRESS_DISABLED SMBUS_DUALADDRESS_DISABLE +#define SMBUS_DUALADDRESS_ENABLED SMBUS_DUALADDRESS_ENABLE +#define SMBUS_GENERALCALL_DISABLED SMBUS_GENERALCALL_DISABLE +#define SMBUS_GENERALCALL_ENABLED SMBUS_GENERALCALL_ENABLE +#define SMBUS_NOSTRETCH_DISABLED SMBUS_NOSTRETCH_DISABLE +#define SMBUS_NOSTRETCH_ENABLED SMBUS_NOSTRETCH_ENABLE +#define SMBUS_ANALOGFILTER_ENABLED SMBUS_ANALOGFILTER_ENABLE +#define SMBUS_ANALOGFILTER_DISABLED SMBUS_ANALOGFILTER_DISABLE +#define SMBUS_PEC_DISABLED SMBUS_PEC_DISABLE +#define SMBUS_PEC_ENABLED SMBUS_PEC_ENABLE +#define HAL_SMBUS_STATE_SLAVE_LISTEN HAL_SMBUS_STATE_LISTEN +/** + * @} + */ + +/** @defgroup HAL_SPI_Aliased_Defines HAL SPI Aliased Defines maintained for legacy purpose + * @{ + */ +#define SPI_TIMODE_DISABLED SPI_TIMODE_DISABLE +#define SPI_TIMODE_ENABLED SPI_TIMODE_ENABLE + +#define SPI_CRCCALCULATION_DISABLED SPI_CRCCALCULATION_DISABLE +#define SPI_CRCCALCULATION_ENABLED SPI_CRCCALCULATION_ENABLE + +#define SPI_NSS_PULSE_DISABLED SPI_NSS_PULSE_DISABLE +#define SPI_NSS_PULSE_ENABLED SPI_NSS_PULSE_ENABLE + +#if defined(STM32H7) + +#define SPI_FLAG_TXE SPI_FLAG_TXP +#define SPI_FLAG_RXNE SPI_FLAG_RXP + +#define SPI_IT_TXE SPI_IT_TXP +#define SPI_IT_RXNE SPI_IT_RXP + +#define SPI_FRLVL_EMPTY SPI_RX_FIFO_0PACKET +#define SPI_FRLVL_QUARTER_FULL SPI_RX_FIFO_1PACKET +#define SPI_FRLVL_HALF_FULL SPI_RX_FIFO_2PACKET +#define SPI_FRLVL_FULL SPI_RX_FIFO_3PACKET + +#endif /* STM32H7 */ + +/** + * @} + */ + +/** @defgroup HAL_TIM_Aliased_Defines HAL TIM Aliased Defines maintained for legacy purpose + * @{ + */ +#define CCER_CCxE_MASK TIM_CCER_CCxE_MASK +#define CCER_CCxNE_MASK TIM_CCER_CCxNE_MASK + +#define TIM_DMABase_CR1 TIM_DMABASE_CR1 +#define TIM_DMABase_CR2 TIM_DMABASE_CR2 +#define TIM_DMABase_SMCR TIM_DMABASE_SMCR +#define TIM_DMABase_DIER TIM_DMABASE_DIER +#define TIM_DMABase_SR TIM_DMABASE_SR +#define TIM_DMABase_EGR TIM_DMABASE_EGR +#define TIM_DMABase_CCMR1 TIM_DMABASE_CCMR1 +#define TIM_DMABase_CCMR2 TIM_DMABASE_CCMR2 +#define TIM_DMABase_CCER TIM_DMABASE_CCER +#define TIM_DMABase_CNT TIM_DMABASE_CNT +#define TIM_DMABase_PSC TIM_DMABASE_PSC +#define TIM_DMABase_ARR TIM_DMABASE_ARR +#define TIM_DMABase_RCR TIM_DMABASE_RCR +#define TIM_DMABase_CCR1 TIM_DMABASE_CCR1 +#define TIM_DMABase_CCR2 TIM_DMABASE_CCR2 +#define TIM_DMABase_CCR3 TIM_DMABASE_CCR3 +#define TIM_DMABase_CCR4 TIM_DMABASE_CCR4 +#define TIM_DMABase_BDTR TIM_DMABASE_BDTR +#define TIM_DMABase_DCR TIM_DMABASE_DCR +#define TIM_DMABase_DMAR TIM_DMABASE_DMAR +#define TIM_DMABase_OR1 TIM_DMABASE_OR1 +#define TIM_DMABase_CCMR3 TIM_DMABASE_CCMR3 +#define TIM_DMABase_CCR5 TIM_DMABASE_CCR5 +#define TIM_DMABase_CCR6 TIM_DMABASE_CCR6 +#define TIM_DMABase_OR2 TIM_DMABASE_OR2 +#define TIM_DMABase_OR3 TIM_DMABASE_OR3 +#define TIM_DMABase_OR TIM_DMABASE_OR + +#define TIM_EventSource_Update TIM_EVENTSOURCE_UPDATE +#define TIM_EventSource_CC1 TIM_EVENTSOURCE_CC1 +#define TIM_EventSource_CC2 TIM_EVENTSOURCE_CC2 +#define TIM_EventSource_CC3 TIM_EVENTSOURCE_CC3 +#define TIM_EventSource_CC4 TIM_EVENTSOURCE_CC4 +#define TIM_EventSource_COM TIM_EVENTSOURCE_COM +#define TIM_EventSource_Trigger TIM_EVENTSOURCE_TRIGGER +#define TIM_EventSource_Break TIM_EVENTSOURCE_BREAK +#define TIM_EventSource_Break2 TIM_EVENTSOURCE_BREAK2 + +#define TIM_DMABurstLength_1Transfer TIM_DMABURSTLENGTH_1TRANSFER +#define TIM_DMABurstLength_2Transfers TIM_DMABURSTLENGTH_2TRANSFERS +#define TIM_DMABurstLength_3Transfers TIM_DMABURSTLENGTH_3TRANSFERS +#define TIM_DMABurstLength_4Transfers TIM_DMABURSTLENGTH_4TRANSFERS +#define TIM_DMABurstLength_5Transfers TIM_DMABURSTLENGTH_5TRANSFERS +#define TIM_DMABurstLength_6Transfers TIM_DMABURSTLENGTH_6TRANSFERS +#define TIM_DMABurstLength_7Transfers TIM_DMABURSTLENGTH_7TRANSFERS +#define TIM_DMABurstLength_8Transfers TIM_DMABURSTLENGTH_8TRANSFERS +#define TIM_DMABurstLength_9Transfers TIM_DMABURSTLENGTH_9TRANSFERS +#define TIM_DMABurstLength_10Transfers TIM_DMABURSTLENGTH_10TRANSFERS +#define TIM_DMABurstLength_11Transfers TIM_DMABURSTLENGTH_11TRANSFERS +#define TIM_DMABurstLength_12Transfers TIM_DMABURSTLENGTH_12TRANSFERS +#define TIM_DMABurstLength_13Transfers TIM_DMABURSTLENGTH_13TRANSFERS +#define TIM_DMABurstLength_14Transfers TIM_DMABURSTLENGTH_14TRANSFERS +#define TIM_DMABurstLength_15Transfers TIM_DMABURSTLENGTH_15TRANSFERS +#define TIM_DMABurstLength_16Transfers TIM_DMABURSTLENGTH_16TRANSFERS +#define TIM_DMABurstLength_17Transfers TIM_DMABURSTLENGTH_17TRANSFERS +#define TIM_DMABurstLength_18Transfers TIM_DMABURSTLENGTH_18TRANSFERS + +#if defined(STM32L0) +#define TIM22_TI1_GPIO1 TIM22_TI1_GPIO +#define TIM22_TI1_GPIO2 TIM22_TI1_GPIO +#endif + +#if defined(STM32F3) +#define IS_TIM_HALL_INTERFACE_INSTANCE IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE +#endif + +#if defined(STM32H7) +#define TIM_TIM1_ETR_COMP1_OUT TIM_TIM1_ETR_COMP1 +#define TIM_TIM1_ETR_COMP2_OUT TIM_TIM1_ETR_COMP2 +#define TIM_TIM8_ETR_COMP1_OUT TIM_TIM8_ETR_COMP1 +#define TIM_TIM8_ETR_COMP2_OUT TIM_TIM8_ETR_COMP2 +#define TIM_TIM2_ETR_COMP1_OUT TIM_TIM2_ETR_COMP1 +#define TIM_TIM2_ETR_COMP2_OUT TIM_TIM2_ETR_COMP2 +#define TIM_TIM3_ETR_COMP1_OUT TIM_TIM3_ETR_COMP1 +#define TIM_TIM1_TI1_COMP1_OUT TIM_TIM1_TI1_COMP1 +#define TIM_TIM8_TI1_COMP2_OUT TIM_TIM8_TI1_COMP2 +#define TIM_TIM2_TI4_COMP1_OUT TIM_TIM2_TI4_COMP1 +#define TIM_TIM2_TI4_COMP2_OUT TIM_TIM2_TI4_COMP2 +#define TIM_TIM2_TI4_COMP1COMP2_OUT TIM_TIM2_TI4_COMP1_COMP2 +#define TIM_TIM3_TI1_COMP1_OUT TIM_TIM3_TI1_COMP1 +#define TIM_TIM3_TI1_COMP2_OUT TIM_TIM3_TI1_COMP2 +#define TIM_TIM3_TI1_COMP1COMP2_OUT TIM_TIM3_TI1_COMP1_COMP2 +#endif + +#if defined(STM32U5) +#define OCREF_CLEAR_SELECT_Pos OCREF_CLEAR_SELECT_POS +#define OCREF_CLEAR_SELECT_Msk OCREF_CLEAR_SELECT_MSK +#endif +/** + * @} + */ + +/** @defgroup HAL_TSC_Aliased_Defines HAL TSC Aliased Defines maintained for legacy purpose + * @{ + */ +#define TSC_SYNC_POL_FALL TSC_SYNC_POLARITY_FALLING +#define TSC_SYNC_POL_RISE_HIGH TSC_SYNC_POLARITY_RISING +/** + * @} + */ + +/** @defgroup HAL_UART_Aliased_Defines HAL UART Aliased Defines maintained for legacy purpose + * @{ + */ +#define UART_ONEBIT_SAMPLING_DISABLED UART_ONE_BIT_SAMPLE_DISABLE +#define UART_ONEBIT_SAMPLING_ENABLED UART_ONE_BIT_SAMPLE_ENABLE +#define UART_ONE_BIT_SAMPLE_DISABLED UART_ONE_BIT_SAMPLE_DISABLE +#define UART_ONE_BIT_SAMPLE_ENABLED UART_ONE_BIT_SAMPLE_ENABLE + +#define __HAL_UART_ONEBIT_ENABLE __HAL_UART_ONE_BIT_SAMPLE_ENABLE +#define __HAL_UART_ONEBIT_DISABLE __HAL_UART_ONE_BIT_SAMPLE_DISABLE + +#define __DIV_SAMPLING16 UART_DIV_SAMPLING16 +#define __DIVMANT_SAMPLING16 UART_DIVMANT_SAMPLING16 +#define __DIVFRAQ_SAMPLING16 UART_DIVFRAQ_SAMPLING16 +#define __UART_BRR_SAMPLING16 UART_BRR_SAMPLING16 + +#define __DIV_SAMPLING8 UART_DIV_SAMPLING8 +#define __DIVMANT_SAMPLING8 UART_DIVMANT_SAMPLING8 +#define __DIVFRAQ_SAMPLING8 UART_DIVFRAQ_SAMPLING8 +#define __UART_BRR_SAMPLING8 UART_BRR_SAMPLING8 + +#define __DIV_LPUART UART_DIV_LPUART + +#define UART_WAKEUPMETHODE_IDLELINE UART_WAKEUPMETHOD_IDLELINE +#define UART_WAKEUPMETHODE_ADDRESSMARK UART_WAKEUPMETHOD_ADDRESSMARK + +/** + * @} + */ + + +/** @defgroup HAL_USART_Aliased_Defines HAL USART Aliased Defines maintained for legacy purpose + * @{ + */ + +#define USART_CLOCK_DISABLED USART_CLOCK_DISABLE +#define USART_CLOCK_ENABLED USART_CLOCK_ENABLE + +#define USARTNACK_ENABLED USART_NACK_ENABLE +#define USARTNACK_DISABLED USART_NACK_DISABLE +/** + * @} + */ + +/** @defgroup HAL_WWDG_Aliased_Defines HAL WWDG Aliased Defines maintained for legacy purpose + * @{ + */ +#define CFR_BASE WWDG_CFR_BASE + +/** + * @} + */ + +/** @defgroup HAL_CAN_Aliased_Defines HAL CAN Aliased Defines maintained for legacy purpose + * @{ + */ +#define CAN_FilterFIFO0 CAN_FILTER_FIFO0 +#define CAN_FilterFIFO1 CAN_FILTER_FIFO1 +#define CAN_IT_RQCP0 CAN_IT_TME +#define CAN_IT_RQCP1 CAN_IT_TME +#define CAN_IT_RQCP2 CAN_IT_TME +#define INAK_TIMEOUT CAN_TIMEOUT_VALUE +#define SLAK_TIMEOUT CAN_TIMEOUT_VALUE +#define CAN_TXSTATUS_FAILED ((uint8_t)0x00U) +#define CAN_TXSTATUS_OK ((uint8_t)0x01U) +#define CAN_TXSTATUS_PENDING ((uint8_t)0x02U) + +/** + * @} + */ + +/** @defgroup HAL_ETH_Aliased_Defines HAL ETH Aliased Defines maintained for legacy purpose + * @{ + */ + +#define VLAN_TAG ETH_VLAN_TAG +#define MIN_ETH_PAYLOAD ETH_MIN_ETH_PAYLOAD +#define MAX_ETH_PAYLOAD ETH_MAX_ETH_PAYLOAD +#define JUMBO_FRAME_PAYLOAD ETH_JUMBO_FRAME_PAYLOAD +#define MACMIIAR_CR_MASK ETH_MACMIIAR_CR_MASK +#define MACCR_CLEAR_MASK ETH_MACCR_CLEAR_MASK +#define MACFCR_CLEAR_MASK ETH_MACFCR_CLEAR_MASK +#define DMAOMR_CLEAR_MASK ETH_DMAOMR_CLEAR_MASK + +#define ETH_MMCCR 0x00000100U +#define ETH_MMCRIR 0x00000104U +#define ETH_MMCTIR 0x00000108U +#define ETH_MMCRIMR 0x0000010CU +#define ETH_MMCTIMR 0x00000110U +#define ETH_MMCTGFSCCR 0x0000014CU +#define ETH_MMCTGFMSCCR 0x00000150U +#define ETH_MMCTGFCR 0x00000168U +#define ETH_MMCRFCECR 0x00000194U +#define ETH_MMCRFAECR 0x00000198U +#define ETH_MMCRGUFCR 0x000001C4U + +#define ETH_MAC_TXFIFO_FULL 0x02000000U /* Tx FIFO full */ +#define ETH_MAC_TXFIFONOT_EMPTY 0x01000000U /* Tx FIFO not empty */ +#define ETH_MAC_TXFIFO_WRITE_ACTIVE 0x00400000U /* Tx FIFO write active */ +#define ETH_MAC_TXFIFO_IDLE 0x00000000U /* Tx FIFO read status: Idle */ +#define ETH_MAC_TXFIFO_READ 0x00100000U /* Tx FIFO read status: Read (transferring data to + the MAC transmitter) */ +#define ETH_MAC_TXFIFO_WAITING 0x00200000U /* Tx FIFO read status: Waiting for TxStatus from + MAC transmitter */ +#define ETH_MAC_TXFIFO_WRITING 0x00300000U /* Tx FIFO read status: Writing the received TxStatus + or flushing the TxFIFO */ +#define ETH_MAC_TRANSMISSION_PAUSE 0x00080000U /* MAC transmitter in pause */ +#define ETH_MAC_TRANSMITFRAMECONTROLLER_IDLE 0x00000000U /* MAC transmit frame controller: Idle */ +#define ETH_MAC_TRANSMITFRAMECONTROLLER_WAITING 0x00020000U /* MAC transmit frame controller: Waiting for Status + of previous frame or IFG/backoff period to be over */ +#define ETH_MAC_TRANSMITFRAMECONTROLLER_GENRATING_PCF 0x00040000U /* MAC transmit frame controller: Generating and + transmitting a Pause control frame (in full duplex mode) */ +#define ETH_MAC_TRANSMITFRAMECONTROLLER_TRANSFERRING 0x00060000U /* MAC transmit frame controller: Transferring input + frame for transmission */ +#define ETH_MAC_MII_TRANSMIT_ACTIVE 0x00010000U /* MAC MII transmit engine active */ +#define ETH_MAC_RXFIFO_EMPTY 0x00000000U /* Rx FIFO fill level: empty */ +#define ETH_MAC_RXFIFO_BELOW_THRESHOLD 0x00000100U /* Rx FIFO fill level: fill-level below flow-control + de-activate threshold */ +#define ETH_MAC_RXFIFO_ABOVE_THRESHOLD 0x00000200U /* Rx FIFO fill level: fill-level above flow-control + activate threshold */ +#define ETH_MAC_RXFIFO_FULL 0x00000300U /* Rx FIFO fill level: full */ +#if defined(STM32F1) +#else +#define ETH_MAC_READCONTROLLER_IDLE 0x00000000U /* Rx FIFO read controller IDLE state */ +#define ETH_MAC_READCONTROLLER_READING_DATA 0x00000020U /* Rx FIFO read controller Reading frame data */ +#define ETH_MAC_READCONTROLLER_READING_STATUS 0x00000040U /* Rx FIFO read controller Reading frame status + (or time-stamp) */ +#endif +#define ETH_MAC_READCONTROLLER_FLUSHING 0x00000060U /* Rx FIFO read controller Flushing the frame data and + status */ +#define ETH_MAC_RXFIFO_WRITE_ACTIVE 0x00000010U /* Rx FIFO write controller active */ +#define ETH_MAC_SMALL_FIFO_NOTACTIVE 0x00000000U /* MAC small FIFO read / write controllers not active */ +#define ETH_MAC_SMALL_FIFO_READ_ACTIVE 0x00000002U /* MAC small FIFO read controller active */ +#define ETH_MAC_SMALL_FIFO_WRITE_ACTIVE 0x00000004U /* MAC small FIFO write controller active */ +#define ETH_MAC_SMALL_FIFO_RW_ACTIVE 0x00000006U /* MAC small FIFO read / write controllers active */ +#define ETH_MAC_MII_RECEIVE_PROTOCOL_ACTIVE 0x00000001U /* MAC MII receive protocol engine active */ + +/** + * @} + */ + +/** @defgroup HAL_DCMI_Aliased_Defines HAL DCMI Aliased Defines maintained for legacy purpose + * @{ + */ +#define HAL_DCMI_ERROR_OVF HAL_DCMI_ERROR_OVR +#define DCMI_IT_OVF DCMI_IT_OVR +#define DCMI_FLAG_OVFRI DCMI_FLAG_OVRRI +#define DCMI_FLAG_OVFMI DCMI_FLAG_OVRMI + +#define HAL_DCMI_ConfigCROP HAL_DCMI_ConfigCrop +#define HAL_DCMI_EnableCROP HAL_DCMI_EnableCrop +#define HAL_DCMI_DisableCROP HAL_DCMI_DisableCrop + +/** + * @} + */ + +#if defined(STM32L4) || defined(STM32F7) || defined(STM32F427xx) || defined(STM32F437xx) \ + || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F469xx) || defined(STM32F479xx) \ + || defined(STM32H7) +/** @defgroup HAL_DMA2D_Aliased_Defines HAL DMA2D Aliased Defines maintained for legacy purpose + * @{ + */ +#define DMA2D_ARGB8888 DMA2D_OUTPUT_ARGB8888 +#define DMA2D_RGB888 DMA2D_OUTPUT_RGB888 +#define DMA2D_RGB565 DMA2D_OUTPUT_RGB565 +#define DMA2D_ARGB1555 DMA2D_OUTPUT_ARGB1555 +#define DMA2D_ARGB4444 DMA2D_OUTPUT_ARGB4444 + +#define CM_ARGB8888 DMA2D_INPUT_ARGB8888 +#define CM_RGB888 DMA2D_INPUT_RGB888 +#define CM_RGB565 DMA2D_INPUT_RGB565 +#define CM_ARGB1555 DMA2D_INPUT_ARGB1555 +#define CM_ARGB4444 DMA2D_INPUT_ARGB4444 +#define CM_L8 DMA2D_INPUT_L8 +#define CM_AL44 DMA2D_INPUT_AL44 +#define CM_AL88 DMA2D_INPUT_AL88 +#define CM_L4 DMA2D_INPUT_L4 +#define CM_A8 DMA2D_INPUT_A8 +#define CM_A4 DMA2D_INPUT_A4 +/** + * @} + */ +#endif /* STM32L4 || STM32F7 || STM32F4 || STM32H7 */ + +#if defined(STM32L4) || defined(STM32F7) || defined(STM32F427xx) || defined(STM32F437xx) \ + || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F469xx) || defined(STM32F479xx) \ + || defined(STM32H7) || defined(STM32U5) +/** @defgroup DMA2D_Aliases DMA2D API Aliases + * @{ + */ +#define HAL_DMA2D_DisableCLUT HAL_DMA2D_CLUTLoading_Abort /*!< Aliased to HAL_DMA2D_CLUTLoading_Abort + for compatibility with legacy code */ +/** + * @} + */ + +#endif /* STM32L4 || STM32F7 || STM32F4 || STM32H7 || STM32U5 */ + +/** @defgroup HAL_PPP_Aliased_Defines HAL PPP Aliased Defines maintained for legacy purpose + * @{ + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup HAL_CRYP_Aliased_Functions HAL CRYP Aliased Functions maintained for legacy purpose + * @{ + */ +#define HAL_CRYP_ComputationCpltCallback HAL_CRYPEx_ComputationCpltCallback +/** + * @} + */ + +/** @defgroup HAL_DCACHE_Aliased_Functions HAL DCACHE Aliased Functions maintained for legacy purpose + * @{ + */ + +#if defined(STM32U5) +#define HAL_DCACHE_CleanInvalidateByAddr HAL_DCACHE_CleanInvalidByAddr +#define HAL_DCACHE_CleanInvalidateByAddr_IT HAL_DCACHE_CleanInvalidByAddr_IT +#endif /* STM32U5 */ + +/** + * @} + */ + +#if !defined(STM32F2) +/** @defgroup HASH_alias HASH API alias + * @{ + */ +#define HAL_HASHEx_IRQHandler HAL_HASH_IRQHandler /*!< Redirection for compatibility with legacy code */ +/** + * + * @} + */ +#endif /* STM32F2 */ +/** @defgroup HAL_HASH_Aliased_Functions HAL HASH Aliased Functions maintained for legacy purpose + * @{ + */ +#define HAL_HASH_STATETypeDef HAL_HASH_StateTypeDef +#define HAL_HASHPhaseTypeDef HAL_HASH_PhaseTypeDef +#define HAL_HMAC_MD5_Finish HAL_HASH_MD5_Finish +#define HAL_HMAC_SHA1_Finish HAL_HASH_SHA1_Finish +#define HAL_HMAC_SHA224_Finish HAL_HASH_SHA224_Finish +#define HAL_HMAC_SHA256_Finish HAL_HASH_SHA256_Finish + +/*HASH Algorithm Selection*/ + +#define HASH_AlgoSelection_SHA1 HASH_ALGOSELECTION_SHA1 +#define HASH_AlgoSelection_SHA224 HASH_ALGOSELECTION_SHA224 +#define HASH_AlgoSelection_SHA256 HASH_ALGOSELECTION_SHA256 +#define HASH_AlgoSelection_MD5 HASH_ALGOSELECTION_MD5 + +#define HASH_AlgoMode_HASH HASH_ALGOMODE_HASH +#define HASH_AlgoMode_HMAC HASH_ALGOMODE_HMAC + +#define HASH_HMACKeyType_ShortKey HASH_HMAC_KEYTYPE_SHORTKEY +#define HASH_HMACKeyType_LongKey HASH_HMAC_KEYTYPE_LONGKEY + +#if defined(STM32L4) || defined(STM32L5) || defined(STM32F2) || defined(STM32F4) || defined(STM32F7) || defined(STM32H7) + +#define HAL_HASH_MD5_Accumulate HAL_HASH_MD5_Accmlt +#define HAL_HASH_MD5_Accumulate_End HAL_HASH_MD5_Accmlt_End +#define HAL_HASH_MD5_Accumulate_IT HAL_HASH_MD5_Accmlt_IT +#define HAL_HASH_MD5_Accumulate_End_IT HAL_HASH_MD5_Accmlt_End_IT + +#define HAL_HASH_SHA1_Accumulate HAL_HASH_SHA1_Accmlt +#define HAL_HASH_SHA1_Accumulate_End HAL_HASH_SHA1_Accmlt_End +#define HAL_HASH_SHA1_Accumulate_IT HAL_HASH_SHA1_Accmlt_IT +#define HAL_HASH_SHA1_Accumulate_End_IT HAL_HASH_SHA1_Accmlt_End_IT + +#define HAL_HASHEx_SHA224_Accumulate HAL_HASHEx_SHA224_Accmlt +#define HAL_HASHEx_SHA224_Accumulate_End HAL_HASHEx_SHA224_Accmlt_End +#define HAL_HASHEx_SHA224_Accumulate_IT HAL_HASHEx_SHA224_Accmlt_IT +#define HAL_HASHEx_SHA224_Accumulate_End_IT HAL_HASHEx_SHA224_Accmlt_End_IT + +#define HAL_HASHEx_SHA256_Accumulate HAL_HASHEx_SHA256_Accmlt +#define HAL_HASHEx_SHA256_Accumulate_End HAL_HASHEx_SHA256_Accmlt_End +#define HAL_HASHEx_SHA256_Accumulate_IT HAL_HASHEx_SHA256_Accmlt_IT +#define HAL_HASHEx_SHA256_Accumulate_End_IT HAL_HASHEx_SHA256_Accmlt_End_IT + +#endif /* STM32L4 || STM32L5 || STM32F2 || STM32F4 || STM32F7 || STM32H7 */ +/** + * @} + */ + +/** @defgroup HAL_Aliased_Functions HAL Generic Aliased Functions maintained for legacy purpose + * @{ + */ +#define HAL_EnableDBGSleepMode HAL_DBGMCU_EnableDBGSleepMode +#define HAL_DisableDBGSleepMode HAL_DBGMCU_DisableDBGSleepMode +#define HAL_EnableDBGStopMode HAL_DBGMCU_EnableDBGStopMode +#define HAL_DisableDBGStopMode HAL_DBGMCU_DisableDBGStopMode +#define HAL_EnableDBGStandbyMode HAL_DBGMCU_EnableDBGStandbyMode +#define HAL_DisableDBGStandbyMode HAL_DBGMCU_DisableDBGStandbyMode +#define HAL_DBG_LowPowerConfig(Periph, cmd) (((cmd\ + )==ENABLE)? HAL_DBGMCU_DBG_EnableLowPowerConfig(Periph) : \ + HAL_DBGMCU_DBG_DisableLowPowerConfig(Periph)) +#define HAL_VREFINT_OutputSelect HAL_SYSCFG_VREFINT_OutputSelect +#define HAL_Lock_Cmd(cmd) (((cmd)==ENABLE) ? HAL_SYSCFG_Enable_Lock_VREFINT() : HAL_SYSCFG_Disable_Lock_VREFINT()) +#if defined(STM32L0) +#else +#define HAL_VREFINT_Cmd(cmd) (((cmd)==ENABLE)? HAL_SYSCFG_EnableVREFINT() : HAL_SYSCFG_DisableVREFINT()) +#endif +#define HAL_ADC_EnableBuffer_Cmd(cmd) (((cmd)==ENABLE) ? HAL_ADCEx_EnableVREFINT() : HAL_ADCEx_DisableVREFINT()) +#define HAL_ADC_EnableBufferSensor_Cmd(cmd) (((cmd\ + )==ENABLE) ? HAL_ADCEx_EnableVREFINTTempSensor() : \ + HAL_ADCEx_DisableVREFINTTempSensor()) +#if defined(STM32H7A3xx) || defined(STM32H7B3xx) || defined(STM32H7B0xx) || defined(STM32H7A3xxQ) || \ + defined(STM32H7B3xxQ) || defined(STM32H7B0xxQ) +#define HAL_EnableSRDomainDBGStopMode HAL_EnableDomain3DBGStopMode +#define HAL_DisableSRDomainDBGStopMode HAL_DisableDomain3DBGStopMode +#define HAL_EnableSRDomainDBGStandbyMode HAL_EnableDomain3DBGStandbyMode +#define HAL_DisableSRDomainDBGStandbyMode HAL_DisableDomain3DBGStandbyMode +#endif /* STM32H7A3xx || STM32H7B3xx || STM32H7B0xx || STM32H7A3xxQ || STM32H7B3xxQ || STM32H7B0xxQ */ + +/** + * @} + */ + +/** @defgroup HAL_FLASH_Aliased_Functions HAL FLASH Aliased Functions maintained for legacy purpose + * @{ + */ +#define FLASH_HalfPageProgram HAL_FLASHEx_HalfPageProgram +#define FLASH_EnableRunPowerDown HAL_FLASHEx_EnableRunPowerDown +#define FLASH_DisableRunPowerDown HAL_FLASHEx_DisableRunPowerDown +#define HAL_DATA_EEPROMEx_Unlock HAL_FLASHEx_DATAEEPROM_Unlock +#define HAL_DATA_EEPROMEx_Lock HAL_FLASHEx_DATAEEPROM_Lock +#define HAL_DATA_EEPROMEx_Erase HAL_FLASHEx_DATAEEPROM_Erase +#define HAL_DATA_EEPROMEx_Program HAL_FLASHEx_DATAEEPROM_Program + +/** + * @} + */ + +/** @defgroup HAL_I2C_Aliased_Functions HAL I2C Aliased Functions maintained for legacy purpose + * @{ + */ +#define HAL_I2CEx_AnalogFilter_Config HAL_I2CEx_ConfigAnalogFilter +#define HAL_I2CEx_DigitalFilter_Config HAL_I2CEx_ConfigDigitalFilter +#define HAL_FMPI2CEx_AnalogFilter_Config HAL_FMPI2CEx_ConfigAnalogFilter +#define HAL_FMPI2CEx_DigitalFilter_Config HAL_FMPI2CEx_ConfigDigitalFilter + +#define HAL_I2CFastModePlusConfig(SYSCFG_I2CFastModePlus, cmd) ((cmd == ENABLE)? \ + HAL_I2CEx_EnableFastModePlus(SYSCFG_I2CFastModePlus): \ + HAL_I2CEx_DisableFastModePlus(SYSCFG_I2CFastModePlus)) + +#if defined(STM32H7) || defined(STM32WB) || defined(STM32G0) || defined(STM32F0) || defined(STM32F1) || \ + defined(STM32F2) || defined(STM32F3) || defined(STM32F4) || defined(STM32F7) || defined(STM32L0) || \ + defined(STM32L4) || defined(STM32L5) || defined(STM32G4) || defined(STM32L1) +#define HAL_I2C_Master_Sequential_Transmit_IT HAL_I2C_Master_Seq_Transmit_IT +#define HAL_I2C_Master_Sequential_Receive_IT HAL_I2C_Master_Seq_Receive_IT +#define HAL_I2C_Slave_Sequential_Transmit_IT HAL_I2C_Slave_Seq_Transmit_IT +#define HAL_I2C_Slave_Sequential_Receive_IT HAL_I2C_Slave_Seq_Receive_IT +#endif /* STM32H7 || STM32WB || STM32G0 || STM32F0 || STM32F1 || STM32F2 || STM32F3 || STM32F4 || STM32F7 || STM32L0 || + STM32L4 || STM32L5 || STM32G4 || STM32L1 */ +#if defined(STM32H7) || defined(STM32WB) || defined(STM32G0) || defined(STM32F4) || defined(STM32F7) || \ + defined(STM32L0) || defined(STM32L4) || defined(STM32L5) || defined(STM32G4)|| defined(STM32L1) +#define HAL_I2C_Master_Sequential_Transmit_DMA HAL_I2C_Master_Seq_Transmit_DMA +#define HAL_I2C_Master_Sequential_Receive_DMA HAL_I2C_Master_Seq_Receive_DMA +#define HAL_I2C_Slave_Sequential_Transmit_DMA HAL_I2C_Slave_Seq_Transmit_DMA +#define HAL_I2C_Slave_Sequential_Receive_DMA HAL_I2C_Slave_Seq_Receive_DMA +#endif /* STM32H7 || STM32WB || STM32G0 || STM32F4 || STM32F7 || STM32L0 || STM32L4 || STM32L5 || STM32G4 || STM32L1 */ + +#if defined(STM32F4) +#define HAL_FMPI2C_Master_Sequential_Transmit_IT HAL_FMPI2C_Master_Seq_Transmit_IT +#define HAL_FMPI2C_Master_Sequential_Receive_IT HAL_FMPI2C_Master_Seq_Receive_IT +#define HAL_FMPI2C_Slave_Sequential_Transmit_IT HAL_FMPI2C_Slave_Seq_Transmit_IT +#define HAL_FMPI2C_Slave_Sequential_Receive_IT HAL_FMPI2C_Slave_Seq_Receive_IT +#define HAL_FMPI2C_Master_Sequential_Transmit_DMA HAL_FMPI2C_Master_Seq_Transmit_DMA +#define HAL_FMPI2C_Master_Sequential_Receive_DMA HAL_FMPI2C_Master_Seq_Receive_DMA +#define HAL_FMPI2C_Slave_Sequential_Transmit_DMA HAL_FMPI2C_Slave_Seq_Transmit_DMA +#define HAL_FMPI2C_Slave_Sequential_Receive_DMA HAL_FMPI2C_Slave_Seq_Receive_DMA +#endif /* STM32F4 */ +/** + * @} + */ + +/** @defgroup HAL_PWR_Aliased HAL PWR Aliased maintained for legacy purpose + * @{ + */ + +#if defined(STM32G0) +#define HAL_PWR_ConfigPVD HAL_PWREx_ConfigPVD +#define HAL_PWR_EnablePVD HAL_PWREx_EnablePVD +#define HAL_PWR_DisablePVD HAL_PWREx_DisablePVD +#define HAL_PWR_PVD_IRQHandler HAL_PWREx_PVD_IRQHandler +#endif +#define HAL_PWR_PVDConfig HAL_PWR_ConfigPVD +#define HAL_PWR_DisableBkUpReg HAL_PWREx_DisableBkUpReg +#define HAL_PWR_DisableFlashPowerDown HAL_PWREx_DisableFlashPowerDown +#define HAL_PWR_DisableVddio2Monitor HAL_PWREx_DisableVddio2Monitor +#define HAL_PWR_EnableBkUpReg HAL_PWREx_EnableBkUpReg +#define HAL_PWR_EnableFlashPowerDown HAL_PWREx_EnableFlashPowerDown +#define HAL_PWR_EnableVddio2Monitor HAL_PWREx_EnableVddio2Monitor +#define HAL_PWR_PVD_PVM_IRQHandler HAL_PWREx_PVD_PVM_IRQHandler +#define HAL_PWR_PVDLevelConfig HAL_PWR_ConfigPVD +#define HAL_PWR_Vddio2Monitor_IRQHandler HAL_PWREx_Vddio2Monitor_IRQHandler +#define HAL_PWR_Vddio2MonitorCallback HAL_PWREx_Vddio2MonitorCallback +#define HAL_PWREx_ActivateOverDrive HAL_PWREx_EnableOverDrive +#define HAL_PWREx_DeactivateOverDrive HAL_PWREx_DisableOverDrive +#define HAL_PWREx_DisableSDADCAnalog HAL_PWREx_DisableSDADC +#define HAL_PWREx_EnableSDADCAnalog HAL_PWREx_EnableSDADC +#define HAL_PWREx_PVMConfig HAL_PWREx_ConfigPVM + +#define PWR_MODE_NORMAL PWR_PVD_MODE_NORMAL +#define PWR_MODE_IT_RISING PWR_PVD_MODE_IT_RISING +#define PWR_MODE_IT_FALLING PWR_PVD_MODE_IT_FALLING +#define PWR_MODE_IT_RISING_FALLING PWR_PVD_MODE_IT_RISING_FALLING +#define PWR_MODE_EVENT_RISING PWR_PVD_MODE_EVENT_RISING +#define PWR_MODE_EVENT_FALLING PWR_PVD_MODE_EVENT_FALLING +#define PWR_MODE_EVENT_RISING_FALLING PWR_PVD_MODE_EVENT_RISING_FALLING + +#define CR_OFFSET_BB PWR_CR_OFFSET_BB +#define CSR_OFFSET_BB PWR_CSR_OFFSET_BB +#define PMODE_BIT_NUMBER VOS_BIT_NUMBER +#define CR_PMODE_BB CR_VOS_BB + +#define DBP_BitNumber DBP_BIT_NUMBER +#define PVDE_BitNumber PVDE_BIT_NUMBER +#define PMODE_BitNumber PMODE_BIT_NUMBER +#define EWUP_BitNumber EWUP_BIT_NUMBER +#define FPDS_BitNumber FPDS_BIT_NUMBER +#define ODEN_BitNumber ODEN_BIT_NUMBER +#define ODSWEN_BitNumber ODSWEN_BIT_NUMBER +#define MRLVDS_BitNumber MRLVDS_BIT_NUMBER +#define LPLVDS_BitNumber LPLVDS_BIT_NUMBER +#define BRE_BitNumber BRE_BIT_NUMBER + +#define PWR_MODE_EVT PWR_PVD_MODE_NORMAL + +#if defined (STM32U5) +#define PWR_SRAM1_PAGE1_STOP_RETENTION PWR_SRAM1_PAGE1_STOP +#define PWR_SRAM1_PAGE2_STOP_RETENTION PWR_SRAM1_PAGE2_STOP +#define PWR_SRAM1_PAGE3_STOP_RETENTION PWR_SRAM1_PAGE3_STOP +#define PWR_SRAM1_PAGE4_STOP_RETENTION PWR_SRAM1_PAGE4_STOP +#define PWR_SRAM1_PAGE5_STOP_RETENTION PWR_SRAM1_PAGE5_STOP +#define PWR_SRAM1_PAGE6_STOP_RETENTION PWR_SRAM1_PAGE6_STOP +#define PWR_SRAM1_PAGE7_STOP_RETENTION PWR_SRAM1_PAGE7_STOP +#define PWR_SRAM1_PAGE8_STOP_RETENTION PWR_SRAM1_PAGE8_STOP +#define PWR_SRAM1_PAGE9_STOP_RETENTION PWR_SRAM1_PAGE9_STOP +#define PWR_SRAM1_PAGE10_STOP_RETENTION PWR_SRAM1_PAGE10_STOP +#define PWR_SRAM1_PAGE11_STOP_RETENTION PWR_SRAM1_PAGE11_STOP +#define PWR_SRAM1_PAGE12_STOP_RETENTION PWR_SRAM1_PAGE12_STOP +#define PWR_SRAM1_FULL_STOP_RETENTION PWR_SRAM1_FULL_STOP + +#define PWR_SRAM2_PAGE1_STOP_RETENTION PWR_SRAM2_PAGE1_STOP +#define PWR_SRAM2_PAGE2_STOP_RETENTION PWR_SRAM2_PAGE2_STOP +#define PWR_SRAM2_FULL_STOP_RETENTION PWR_SRAM2_FULL_STOP + +#define PWR_SRAM3_PAGE1_STOP_RETENTION PWR_SRAM3_PAGE1_STOP +#define PWR_SRAM3_PAGE2_STOP_RETENTION PWR_SRAM3_PAGE2_STOP +#define PWR_SRAM3_PAGE3_STOP_RETENTION PWR_SRAM3_PAGE3_STOP +#define PWR_SRAM3_PAGE4_STOP_RETENTION PWR_SRAM3_PAGE4_STOP +#define PWR_SRAM3_PAGE5_STOP_RETENTION PWR_SRAM3_PAGE5_STOP +#define PWR_SRAM3_PAGE6_STOP_RETENTION PWR_SRAM3_PAGE6_STOP +#define PWR_SRAM3_PAGE7_STOP_RETENTION PWR_SRAM3_PAGE7_STOP +#define PWR_SRAM3_PAGE8_STOP_RETENTION PWR_SRAM3_PAGE8_STOP +#define PWR_SRAM3_PAGE9_STOP_RETENTION PWR_SRAM3_PAGE9_STOP +#define PWR_SRAM3_PAGE10_STOP_RETENTION PWR_SRAM3_PAGE10_STOP +#define PWR_SRAM3_PAGE11_STOP_RETENTION PWR_SRAM3_PAGE11_STOP +#define PWR_SRAM3_PAGE12_STOP_RETENTION PWR_SRAM3_PAGE12_STOP +#define PWR_SRAM3_PAGE13_STOP_RETENTION PWR_SRAM3_PAGE13_STOP +#define PWR_SRAM3_FULL_STOP_RETENTION PWR_SRAM3_FULL_STOP + +#define PWR_SRAM4_FULL_STOP_RETENTION PWR_SRAM4_FULL_STOP + +#define PWR_SRAM5_PAGE1_STOP_RETENTION PWR_SRAM5_PAGE1_STOP +#define PWR_SRAM5_PAGE2_STOP_RETENTION PWR_SRAM5_PAGE2_STOP +#define PWR_SRAM5_PAGE3_STOP_RETENTION PWR_SRAM5_PAGE3_STOP +#define PWR_SRAM5_PAGE4_STOP_RETENTION PWR_SRAM5_PAGE4_STOP +#define PWR_SRAM5_PAGE5_STOP_RETENTION PWR_SRAM5_PAGE5_STOP +#define PWR_SRAM5_PAGE6_STOP_RETENTION PWR_SRAM5_PAGE6_STOP +#define PWR_SRAM5_PAGE7_STOP_RETENTION PWR_SRAM5_PAGE7_STOP +#define PWR_SRAM5_PAGE8_STOP_RETENTION PWR_SRAM5_PAGE8_STOP +#define PWR_SRAM5_PAGE9_STOP_RETENTION PWR_SRAM5_PAGE9_STOP +#define PWR_SRAM5_PAGE10_STOP_RETENTION PWR_SRAM5_PAGE10_STOP +#define PWR_SRAM5_PAGE11_STOP_RETENTION PWR_SRAM5_PAGE11_STOP +#define PWR_SRAM5_PAGE12_STOP_RETENTION PWR_SRAM5_PAGE12_STOP +#define PWR_SRAM5_PAGE13_STOP_RETENTION PWR_SRAM5_PAGE13_STOP +#define PWR_SRAM5_FULL_STOP_RETENTION PWR_SRAM5_FULL_STOP + +#define PWR_SRAM6_PAGE1_STOP_RETENTION PWR_SRAM6_PAGE1_STOP +#define PWR_SRAM6_PAGE2_STOP_RETENTION PWR_SRAM6_PAGE2_STOP +#define PWR_SRAM6_PAGE3_STOP_RETENTION PWR_SRAM6_PAGE3_STOP +#define PWR_SRAM6_PAGE4_STOP_RETENTION PWR_SRAM6_PAGE4_STOP +#define PWR_SRAM6_PAGE5_STOP_RETENTION PWR_SRAM6_PAGE5_STOP +#define PWR_SRAM6_PAGE6_STOP_RETENTION PWR_SRAM6_PAGE6_STOP +#define PWR_SRAM6_PAGE7_STOP_RETENTION PWR_SRAM6_PAGE7_STOP +#define PWR_SRAM6_PAGE8_STOP_RETENTION PWR_SRAM6_PAGE8_STOP +#define PWR_SRAM6_FULL_STOP_RETENTION PWR_SRAM6_FULL_STOP + + +#define PWR_ICACHE_FULL_STOP_RETENTION PWR_ICACHE_FULL_STOP +#define PWR_DCACHE1_FULL_STOP_RETENTION PWR_DCACHE1_FULL_STOP +#define PWR_DCACHE2_FULL_STOP_RETENTION PWR_DCACHE2_FULL_STOP +#define PWR_DMA2DRAM_FULL_STOP_RETENTION PWR_DMA2DRAM_FULL_STOP +#define PWR_PERIPHRAM_FULL_STOP_RETENTION PWR_PERIPHRAM_FULL_STOP +#define PWR_PKA32RAM_FULL_STOP_RETENTION PWR_PKA32RAM_FULL_STOP +#define PWR_GRAPHICPRAM_FULL_STOP_RETENTION PWR_GRAPHICPRAM_FULL_STOP +#define PWR_DSIRAM_FULL_STOP_RETENTION PWR_DSIRAM_FULL_STOP +#define PWR_JPEGRAM_FULL_STOP_RETENTION PWR_JPEGRAM_FULL_STOP + + +#define PWR_SRAM2_PAGE1_STANDBY_RETENTION PWR_SRAM2_PAGE1_STANDBY +#define PWR_SRAM2_PAGE2_STANDBY_RETENTION PWR_SRAM2_PAGE2_STANDBY +#define PWR_SRAM2_FULL_STANDBY_RETENTION PWR_SRAM2_FULL_STANDBY + +#define PWR_SRAM1_FULL_RUN_RETENTION PWR_SRAM1_FULL_RUN +#define PWR_SRAM2_FULL_RUN_RETENTION PWR_SRAM2_FULL_RUN +#define PWR_SRAM3_FULL_RUN_RETENTION PWR_SRAM3_FULL_RUN +#define PWR_SRAM4_FULL_RUN_RETENTION PWR_SRAM4_FULL_RUN +#define PWR_SRAM5_FULL_RUN_RETENTION PWR_SRAM5_FULL_RUN +#define PWR_SRAM6_FULL_RUN_RETENTION PWR_SRAM6_FULL_RUN + +#define PWR_ALL_RAM_RUN_RETENTION_MASK PWR_ALL_RAM_RUN_MASK +#endif + +/** + * @} + */ + +/** @defgroup HAL_RTC_Aliased_Functions HAL RTC Aliased Functions maintained for legacy purpose + * @{ + */ +#if defined(STM32H5) || defined(STM32WBA) +#define HAL_RTCEx_SetBoothardwareKey HAL_RTCEx_LockBootHardwareKey +#define HAL_RTCEx_BKUPBlock_Enable HAL_RTCEx_BKUPBlock +#define HAL_RTCEx_BKUPBlock_Disable HAL_RTCEx_BKUPUnblock +#define HAL_RTCEx_Erase_SecretDev_Conf HAL_RTCEx_ConfigEraseDeviceSecrets +#endif /* STM32H5 || STM32WBA */ + +/** + * @} + */ + +/** @defgroup HAL_SMBUS_Aliased_Functions HAL SMBUS Aliased Functions maintained for legacy purpose + * @{ + */ +#define HAL_SMBUS_Slave_Listen_IT HAL_SMBUS_EnableListen_IT +#define HAL_SMBUS_SlaveAddrCallback HAL_SMBUS_AddrCallback +#define HAL_SMBUS_SlaveListenCpltCallback HAL_SMBUS_ListenCpltCallback +/** + * @} + */ + +/** @defgroup HAL_SPI_Aliased_Functions HAL SPI Aliased Functions maintained for legacy purpose + * @{ + */ +#define HAL_SPI_FlushRxFifo HAL_SPIEx_FlushRxFifo +/** + * @} + */ + +/** @defgroup HAL_TIM_Aliased_Functions HAL TIM Aliased Functions maintained for legacy purpose + * @{ + */ +#define HAL_TIM_DMADelayPulseCplt TIM_DMADelayPulseCplt +#define HAL_TIM_DMAError TIM_DMAError +#define HAL_TIM_DMACaptureCplt TIM_DMACaptureCplt +#define HAL_TIMEx_DMACommutationCplt TIMEx_DMACommutationCplt +#if defined(STM32H7) || defined(STM32G0) || defined(STM32F0) || defined(STM32F1) || defined(STM32F2) || \ + defined(STM32F3) || defined(STM32F4) || defined(STM32F7) || defined(STM32L0) || defined(STM32L4) +#define HAL_TIM_SlaveConfigSynchronization HAL_TIM_SlaveConfigSynchro +#define HAL_TIM_SlaveConfigSynchronization_IT HAL_TIM_SlaveConfigSynchro_IT +#define HAL_TIMEx_CommutationCallback HAL_TIMEx_CommutCallback +#define HAL_TIMEx_ConfigCommutationEvent HAL_TIMEx_ConfigCommutEvent +#define HAL_TIMEx_ConfigCommutationEvent_IT HAL_TIMEx_ConfigCommutEvent_IT +#define HAL_TIMEx_ConfigCommutationEvent_DMA HAL_TIMEx_ConfigCommutEvent_DMA +#endif /* STM32H7 || STM32G0 || STM32F0 || STM32F1 || STM32F2 || STM32F3 || STM32F4 || STM32F7 || STM32L0 */ +/** + * @} + */ + +/** @defgroup HAL_UART_Aliased_Functions HAL UART Aliased Functions maintained for legacy purpose + * @{ + */ +#define HAL_UART_WakeupCallback HAL_UARTEx_WakeupCallback +/** + * @} + */ + +/** @defgroup HAL_LTDC_Aliased_Functions HAL LTDC Aliased Functions maintained for legacy purpose + * @{ + */ +#define HAL_LTDC_LineEvenCallback HAL_LTDC_LineEventCallback +#define HAL_LTDC_Relaod HAL_LTDC_Reload +#define HAL_LTDC_StructInitFromVideoConfig HAL_LTDCEx_StructInitFromVideoConfig +#define HAL_LTDC_StructInitFromAdaptedCommandConfig HAL_LTDCEx_StructInitFromAdaptedCommandConfig +/** + * @} + */ + + +/** @defgroup HAL_PPP_Aliased_Functions HAL PPP Aliased Functions maintained for legacy purpose + * @{ + */ + +/** + * @} + */ + +/* Exported macros ------------------------------------------------------------*/ + +/** @defgroup HAL_AES_Aliased_Macros HAL CRYP Aliased Macros maintained for legacy purpose + * @{ + */ +#define AES_IT_CC CRYP_IT_CC +#define AES_IT_ERR CRYP_IT_ERR +#define AES_FLAG_CCF CRYP_FLAG_CCF +/** + * @} + */ + +/** @defgroup HAL_Aliased_Macros HAL Generic Aliased Macros maintained for legacy purpose + * @{ + */ +#define __HAL_GET_BOOT_MODE __HAL_SYSCFG_GET_BOOT_MODE +#define __HAL_REMAPMEMORY_FLASH __HAL_SYSCFG_REMAPMEMORY_FLASH +#define __HAL_REMAPMEMORY_SYSTEMFLASH __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH +#define __HAL_REMAPMEMORY_SRAM __HAL_SYSCFG_REMAPMEMORY_SRAM +#define __HAL_REMAPMEMORY_FMC __HAL_SYSCFG_REMAPMEMORY_FMC +#define __HAL_REMAPMEMORY_FMC_SDRAM __HAL_SYSCFG_REMAPMEMORY_FMC_SDRAM +#define __HAL_REMAPMEMORY_FSMC __HAL_SYSCFG_REMAPMEMORY_FSMC +#define __HAL_REMAPMEMORY_QUADSPI __HAL_SYSCFG_REMAPMEMORY_QUADSPI +#define __HAL_FMC_BANK __HAL_SYSCFG_FMC_BANK +#define __HAL_GET_FLAG __HAL_SYSCFG_GET_FLAG +#define __HAL_CLEAR_FLAG __HAL_SYSCFG_CLEAR_FLAG +#define __HAL_VREFINT_OUT_ENABLE __HAL_SYSCFG_VREFINT_OUT_ENABLE +#define __HAL_VREFINT_OUT_DISABLE __HAL_SYSCFG_VREFINT_OUT_DISABLE +#define __HAL_SYSCFG_SRAM2_WRP_ENABLE __HAL_SYSCFG_SRAM2_WRP_0_31_ENABLE + +#define SYSCFG_FLAG_VREF_READY SYSCFG_FLAG_VREFINT_READY +#define SYSCFG_FLAG_RC48 RCC_FLAG_HSI48 +#define IS_SYSCFG_FASTMODEPLUS_CONFIG IS_I2C_FASTMODEPLUS +#define UFB_MODE_BitNumber UFB_MODE_BIT_NUMBER +#define CMP_PD_BitNumber CMP_PD_BIT_NUMBER + +/** + * @} + */ + + +/** @defgroup HAL_ADC_Aliased_Macros HAL ADC Aliased Macros maintained for legacy purpose + * @{ + */ +#define __ADC_ENABLE __HAL_ADC_ENABLE +#define __ADC_DISABLE __HAL_ADC_DISABLE +#define __HAL_ADC_ENABLING_CONDITIONS ADC_ENABLING_CONDITIONS +#define __HAL_ADC_DISABLING_CONDITIONS ADC_DISABLING_CONDITIONS +#define __HAL_ADC_IS_ENABLED ADC_IS_ENABLE +#define __ADC_IS_ENABLED ADC_IS_ENABLE +#define __HAL_ADC_IS_SOFTWARE_START_REGULAR ADC_IS_SOFTWARE_START_REGULAR +#define __HAL_ADC_IS_SOFTWARE_START_INJECTED ADC_IS_SOFTWARE_START_INJECTED +#define __HAL_ADC_IS_CONVERSION_ONGOING_REGULAR_INJECTED ADC_IS_CONVERSION_ONGOING_REGULAR_INJECTED +#define __HAL_ADC_IS_CONVERSION_ONGOING_REGULAR ADC_IS_CONVERSION_ONGOING_REGULAR +#define __HAL_ADC_IS_CONVERSION_ONGOING_INJECTED ADC_IS_CONVERSION_ONGOING_INJECTED +#define __HAL_ADC_IS_CONVERSION_ONGOING ADC_IS_CONVERSION_ONGOING +#define __HAL_ADC_CLEAR_ERRORCODE ADC_CLEAR_ERRORCODE + +#define __HAL_ADC_GET_RESOLUTION ADC_GET_RESOLUTION +#define __HAL_ADC_JSQR_RK ADC_JSQR_RK +#define __HAL_ADC_CFGR_AWD1CH ADC_CFGR_AWD1CH_SHIFT +#define __HAL_ADC_CFGR_AWD23CR ADC_CFGR_AWD23CR +#define __HAL_ADC_CFGR_INJECT_AUTO_CONVERSION ADC_CFGR_INJECT_AUTO_CONVERSION +#define __HAL_ADC_CFGR_INJECT_CONTEXT_QUEUE ADC_CFGR_INJECT_CONTEXT_QUEUE +#define __HAL_ADC_CFGR_INJECT_DISCCONTINUOUS ADC_CFGR_INJECT_DISCCONTINUOUS +#define __HAL_ADC_CFGR_REG_DISCCONTINUOUS ADC_CFGR_REG_DISCCONTINUOUS +#define __HAL_ADC_CFGR_DISCONTINUOUS_NUM ADC_CFGR_DISCONTINUOUS_NUM +#define __HAL_ADC_CFGR_AUTOWAIT ADC_CFGR_AUTOWAIT +#define __HAL_ADC_CFGR_CONTINUOUS ADC_CFGR_CONTINUOUS +#define __HAL_ADC_CFGR_OVERRUN ADC_CFGR_OVERRUN +#define __HAL_ADC_CFGR_DMACONTREQ ADC_CFGR_DMACONTREQ +#define __HAL_ADC_CFGR_EXTSEL ADC_CFGR_EXTSEL_SET +#define __HAL_ADC_JSQR_JEXTSEL ADC_JSQR_JEXTSEL_SET +#define __HAL_ADC_OFR_CHANNEL ADC_OFR_CHANNEL +#define __HAL_ADC_DIFSEL_CHANNEL ADC_DIFSEL_CHANNEL +#define __HAL_ADC_CALFACT_DIFF_SET ADC_CALFACT_DIFF_SET +#define __HAL_ADC_CALFACT_DIFF_GET ADC_CALFACT_DIFF_GET +#define __HAL_ADC_TRX_HIGHTHRESHOLD ADC_TRX_HIGHTHRESHOLD + +#define __HAL_ADC_OFFSET_SHIFT_RESOLUTION ADC_OFFSET_SHIFT_RESOLUTION +#define __HAL_ADC_AWD1THRESHOLD_SHIFT_RESOLUTION ADC_AWD1THRESHOLD_SHIFT_RESOLUTION +#define __HAL_ADC_AWD23THRESHOLD_SHIFT_RESOLUTION ADC_AWD23THRESHOLD_SHIFT_RESOLUTION +#define __HAL_ADC_COMMON_REGISTER ADC_COMMON_REGISTER +#define __HAL_ADC_COMMON_CCR_MULTI ADC_COMMON_CCR_MULTI +#define __HAL_ADC_MULTIMODE_IS_ENABLED ADC_MULTIMODE_IS_ENABLE +#define __ADC_MULTIMODE_IS_ENABLED ADC_MULTIMODE_IS_ENABLE +#define __HAL_ADC_NONMULTIMODE_OR_MULTIMODEMASTER ADC_NONMULTIMODE_OR_MULTIMODEMASTER +#define __HAL_ADC_COMMON_ADC_OTHER ADC_COMMON_ADC_OTHER +#define __HAL_ADC_MULTI_SLAVE ADC_MULTI_SLAVE + +#define __HAL_ADC_SQR1_L ADC_SQR1_L_SHIFT +#define __HAL_ADC_JSQR_JL ADC_JSQR_JL_SHIFT +#define __HAL_ADC_JSQR_RK_JL ADC_JSQR_RK_JL +#define __HAL_ADC_CR1_DISCONTINUOUS_NUM ADC_CR1_DISCONTINUOUS_NUM +#define __HAL_ADC_CR1_SCAN ADC_CR1_SCAN_SET +#define __HAL_ADC_CONVCYCLES_MAX_RANGE ADC_CONVCYCLES_MAX_RANGE +#define __HAL_ADC_CLOCK_PRESCALER_RANGE ADC_CLOCK_PRESCALER_RANGE +#define __HAL_ADC_GET_CLOCK_PRESCALER ADC_GET_CLOCK_PRESCALER + +#define __HAL_ADC_SQR1 ADC_SQR1 +#define __HAL_ADC_SMPR1 ADC_SMPR1 +#define __HAL_ADC_SMPR2 ADC_SMPR2 +#define __HAL_ADC_SQR3_RK ADC_SQR3_RK +#define __HAL_ADC_SQR2_RK ADC_SQR2_RK +#define __HAL_ADC_SQR1_RK ADC_SQR1_RK +#define __HAL_ADC_CR2_CONTINUOUS ADC_CR2_CONTINUOUS +#define __HAL_ADC_CR1_DISCONTINUOUS ADC_CR1_DISCONTINUOUS +#define __HAL_ADC_CR1_SCANCONV ADC_CR1_SCANCONV +#define __HAL_ADC_CR2_EOCSelection ADC_CR2_EOCSelection +#define __HAL_ADC_CR2_DMAContReq ADC_CR2_DMAContReq +#define __HAL_ADC_JSQR ADC_JSQR + +#define __HAL_ADC_CHSELR_CHANNEL ADC_CHSELR_CHANNEL +#define __HAL_ADC_CFGR1_REG_DISCCONTINUOUS ADC_CFGR1_REG_DISCCONTINUOUS +#define __HAL_ADC_CFGR1_AUTOOFF ADC_CFGR1_AUTOOFF +#define __HAL_ADC_CFGR1_AUTOWAIT ADC_CFGR1_AUTOWAIT +#define __HAL_ADC_CFGR1_CONTINUOUS ADC_CFGR1_CONTINUOUS +#define __HAL_ADC_CFGR1_OVERRUN ADC_CFGR1_OVERRUN +#define __HAL_ADC_CFGR1_SCANDIR ADC_CFGR1_SCANDIR +#define __HAL_ADC_CFGR1_DMACONTREQ ADC_CFGR1_DMACONTREQ + +/** + * @} + */ + +/** @defgroup HAL_DAC_Aliased_Macros HAL DAC Aliased Macros maintained for legacy purpose + * @{ + */ +#define __HAL_DHR12R1_ALIGNEMENT DAC_DHR12R1_ALIGNMENT +#define __HAL_DHR12R2_ALIGNEMENT DAC_DHR12R2_ALIGNMENT +#define __HAL_DHR12RD_ALIGNEMENT DAC_DHR12RD_ALIGNMENT +#define IS_DAC_GENERATE_WAVE IS_DAC_WAVE + +/** + * @} + */ + +/** @defgroup HAL_DBGMCU_Aliased_Macros HAL DBGMCU Aliased Macros maintained for legacy purpose + * @{ + */ +#define __HAL_FREEZE_TIM1_DBGMCU __HAL_DBGMCU_FREEZE_TIM1 +#define __HAL_UNFREEZE_TIM1_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM1 +#define __HAL_FREEZE_TIM2_DBGMCU __HAL_DBGMCU_FREEZE_TIM2 +#define __HAL_UNFREEZE_TIM2_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM2 +#define __HAL_FREEZE_TIM3_DBGMCU __HAL_DBGMCU_FREEZE_TIM3 +#define __HAL_UNFREEZE_TIM3_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM3 +#define __HAL_FREEZE_TIM4_DBGMCU __HAL_DBGMCU_FREEZE_TIM4 +#define __HAL_UNFREEZE_TIM4_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM4 +#define __HAL_FREEZE_TIM5_DBGMCU __HAL_DBGMCU_FREEZE_TIM5 +#define __HAL_UNFREEZE_TIM5_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM5 +#define __HAL_FREEZE_TIM6_DBGMCU __HAL_DBGMCU_FREEZE_TIM6 +#define __HAL_UNFREEZE_TIM6_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM6 +#define __HAL_FREEZE_TIM7_DBGMCU __HAL_DBGMCU_FREEZE_TIM7 +#define __HAL_UNFREEZE_TIM7_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM7 +#define __HAL_FREEZE_TIM8_DBGMCU __HAL_DBGMCU_FREEZE_TIM8 +#define __HAL_UNFREEZE_TIM8_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM8 + +#define __HAL_FREEZE_TIM9_DBGMCU __HAL_DBGMCU_FREEZE_TIM9 +#define __HAL_UNFREEZE_TIM9_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM9 +#define __HAL_FREEZE_TIM10_DBGMCU __HAL_DBGMCU_FREEZE_TIM10 +#define __HAL_UNFREEZE_TIM10_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM10 +#define __HAL_FREEZE_TIM11_DBGMCU __HAL_DBGMCU_FREEZE_TIM11 +#define __HAL_UNFREEZE_TIM11_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM11 +#define __HAL_FREEZE_TIM12_DBGMCU __HAL_DBGMCU_FREEZE_TIM12 +#define __HAL_UNFREEZE_TIM12_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM12 +#define __HAL_FREEZE_TIM13_DBGMCU __HAL_DBGMCU_FREEZE_TIM13 +#define __HAL_UNFREEZE_TIM13_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM13 +#define __HAL_FREEZE_TIM14_DBGMCU __HAL_DBGMCU_FREEZE_TIM14 +#define __HAL_UNFREEZE_TIM14_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM14 +#define __HAL_FREEZE_CAN2_DBGMCU __HAL_DBGMCU_FREEZE_CAN2 +#define __HAL_UNFREEZE_CAN2_DBGMCU __HAL_DBGMCU_UNFREEZE_CAN2 + + +#define __HAL_FREEZE_TIM15_DBGMCU __HAL_DBGMCU_FREEZE_TIM15 +#define __HAL_UNFREEZE_TIM15_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM15 +#define __HAL_FREEZE_TIM16_DBGMCU __HAL_DBGMCU_FREEZE_TIM16 +#define __HAL_UNFREEZE_TIM16_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM16 +#define __HAL_FREEZE_TIM17_DBGMCU __HAL_DBGMCU_FREEZE_TIM17 +#define __HAL_UNFREEZE_TIM17_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM17 +#define __HAL_FREEZE_RTC_DBGMCU __HAL_DBGMCU_FREEZE_RTC +#define __HAL_UNFREEZE_RTC_DBGMCU __HAL_DBGMCU_UNFREEZE_RTC +#if defined(STM32H7) +#define __HAL_FREEZE_WWDG_DBGMCU __HAL_DBGMCU_FREEZE_WWDG1 +#define __HAL_UNFREEZE_WWDG_DBGMCU __HAL_DBGMCU_UnFreeze_WWDG1 +#define __HAL_FREEZE_IWDG_DBGMCU __HAL_DBGMCU_FREEZE_IWDG1 +#define __HAL_UNFREEZE_IWDG_DBGMCU __HAL_DBGMCU_UnFreeze_IWDG1 +#else +#define __HAL_FREEZE_WWDG_DBGMCU __HAL_DBGMCU_FREEZE_WWDG +#define __HAL_UNFREEZE_WWDG_DBGMCU __HAL_DBGMCU_UNFREEZE_WWDG +#define __HAL_FREEZE_IWDG_DBGMCU __HAL_DBGMCU_FREEZE_IWDG +#define __HAL_UNFREEZE_IWDG_DBGMCU __HAL_DBGMCU_UNFREEZE_IWDG +#endif /* STM32H7 */ +#define __HAL_FREEZE_I2C1_TIMEOUT_DBGMCU __HAL_DBGMCU_FREEZE_I2C1_TIMEOUT +#define __HAL_UNFREEZE_I2C1_TIMEOUT_DBGMCU __HAL_DBGMCU_UNFREEZE_I2C1_TIMEOUT +#define __HAL_FREEZE_I2C2_TIMEOUT_DBGMCU __HAL_DBGMCU_FREEZE_I2C2_TIMEOUT +#define __HAL_UNFREEZE_I2C2_TIMEOUT_DBGMCU __HAL_DBGMCU_UNFREEZE_I2C2_TIMEOUT +#define __HAL_FREEZE_I2C3_TIMEOUT_DBGMCU __HAL_DBGMCU_FREEZE_I2C3_TIMEOUT +#define __HAL_UNFREEZE_I2C3_TIMEOUT_DBGMCU __HAL_DBGMCU_UNFREEZE_I2C3_TIMEOUT +#define __HAL_FREEZE_CAN1_DBGMCU __HAL_DBGMCU_FREEZE_CAN1 +#define __HAL_UNFREEZE_CAN1_DBGMCU __HAL_DBGMCU_UNFREEZE_CAN1 +#define __HAL_FREEZE_LPTIM1_DBGMCU __HAL_DBGMCU_FREEZE_LPTIM1 +#define __HAL_UNFREEZE_LPTIM1_DBGMCU __HAL_DBGMCU_UNFREEZE_LPTIM1 +#define __HAL_FREEZE_LPTIM2_DBGMCU __HAL_DBGMCU_FREEZE_LPTIM2 +#define __HAL_UNFREEZE_LPTIM2_DBGMCU __HAL_DBGMCU_UNFREEZE_LPTIM2 + +/** + * @} + */ + +/** @defgroup HAL_COMP_Aliased_Macros HAL COMP Aliased Macros maintained for legacy purpose + * @{ + */ +#if defined(STM32F3) +#define COMP_START __HAL_COMP_ENABLE +#define COMP_STOP __HAL_COMP_DISABLE +#define COMP_LOCK __HAL_COMP_LOCK + +#if defined(STM32F301x8) || defined(STM32F302x8) || defined(STM32F318xx) || defined(STM32F303x8) || \ + defined(STM32F334x8) || defined(STM32F328xx) +#define __HAL_COMP_EXTI_RISING_IT_ENABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_ENABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_ENABLE_RISING_EDGE() : \ + __HAL_COMP_COMP6_EXTI_ENABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_RISING_IT_DISABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_DISABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_DISABLE_RISING_EDGE() : \ + __HAL_COMP_COMP6_EXTI_DISABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_ENABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_ENABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_ENABLE_FALLING_EDGE() : \ + __HAL_COMP_COMP6_EXTI_ENABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_DISABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_DISABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_DISABLE_FALLING_EDGE() : \ + __HAL_COMP_COMP6_EXTI_DISABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_ENABLE_IT(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_ENABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_ENABLE_IT() : \ + __HAL_COMP_COMP6_EXTI_ENABLE_IT()) +#define __HAL_COMP_EXTI_DISABLE_IT(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_DISABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_DISABLE_IT() : \ + __HAL_COMP_COMP6_EXTI_DISABLE_IT()) +#define __HAL_COMP_EXTI_GET_FLAG(__FLAG__) (((__FLAG__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_GET_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_GET_FLAG() : \ + __HAL_COMP_COMP6_EXTI_GET_FLAG()) +#define __HAL_COMP_EXTI_CLEAR_FLAG(__FLAG__) (((__FLAG__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_CLEAR_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_CLEAR_FLAG() : \ + __HAL_COMP_COMP6_EXTI_CLEAR_FLAG()) +# endif +# if defined(STM32F302xE) || defined(STM32F302xC) +#define __HAL_COMP_EXTI_RISING_IT_ENABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_ENABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_ENABLE_RISING_EDGE() : \ + __HAL_COMP_COMP6_EXTI_ENABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_RISING_IT_DISABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_DISABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_DISABLE_RISING_EDGE() : \ + __HAL_COMP_COMP6_EXTI_DISABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_ENABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_ENABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_ENABLE_FALLING_EDGE() : \ + __HAL_COMP_COMP6_EXTI_ENABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_DISABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_DISABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_DISABLE_FALLING_EDGE() : \ + __HAL_COMP_COMP6_EXTI_DISABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_ENABLE_IT(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_ENABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_ENABLE_IT() : \ + __HAL_COMP_COMP6_EXTI_ENABLE_IT()) +#define __HAL_COMP_EXTI_DISABLE_IT(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_DISABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_DISABLE_IT() : \ + __HAL_COMP_COMP6_EXTI_DISABLE_IT()) +#define __HAL_COMP_EXTI_GET_FLAG(__FLAG__) (((__FLAG__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_GET_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_GET_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_GET_FLAG() : \ + __HAL_COMP_COMP6_EXTI_GET_FLAG()) +#define __HAL_COMP_EXTI_CLEAR_FLAG(__FLAG__) (((__FLAG__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_CLEAR_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_CLEAR_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_CLEAR_FLAG() : \ + __HAL_COMP_COMP6_EXTI_CLEAR_FLAG()) +# endif +# if defined(STM32F303xE) || defined(STM32F398xx) || defined(STM32F303xC) || defined(STM32F358xx) +#define __HAL_COMP_EXTI_RISING_IT_ENABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_ENABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP3) ? __HAL_COMP_COMP3_EXTI_ENABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_ENABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP5) ? __HAL_COMP_COMP5_EXTI_ENABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP6) ? __HAL_COMP_COMP6_EXTI_ENABLE_RISING_EDGE() : \ + __HAL_COMP_COMP7_EXTI_ENABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_RISING_IT_DISABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_DISABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP3) ? __HAL_COMP_COMP3_EXTI_DISABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_DISABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP5) ? __HAL_COMP_COMP5_EXTI_DISABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP6) ? __HAL_COMP_COMP6_EXTI_DISABLE_RISING_EDGE() : \ + __HAL_COMP_COMP7_EXTI_DISABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_ENABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_ENABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP3) ? __HAL_COMP_COMP3_EXTI_ENABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_ENABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP5) ? __HAL_COMP_COMP5_EXTI_ENABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP6) ? __HAL_COMP_COMP6_EXTI_ENABLE_FALLING_EDGE() : \ + __HAL_COMP_COMP7_EXTI_ENABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_DISABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_DISABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP3) ? __HAL_COMP_COMP3_EXTI_DISABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_DISABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP5) ? __HAL_COMP_COMP5_EXTI_DISABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP6) ? __HAL_COMP_COMP6_EXTI_DISABLE_FALLING_EDGE() : \ + __HAL_COMP_COMP7_EXTI_DISABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_ENABLE_IT(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_ENABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP3) ? __HAL_COMP_COMP3_EXTI_ENABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_ENABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP5) ? __HAL_COMP_COMP5_EXTI_ENABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP6) ? __HAL_COMP_COMP6_EXTI_ENABLE_IT() : \ + __HAL_COMP_COMP7_EXTI_ENABLE_IT()) +#define __HAL_COMP_EXTI_DISABLE_IT(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_DISABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP3) ? __HAL_COMP_COMP3_EXTI_DISABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_DISABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP5) ? __HAL_COMP_COMP5_EXTI_DISABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP6) ? __HAL_COMP_COMP6_EXTI_DISABLE_IT() : \ + __HAL_COMP_COMP7_EXTI_DISABLE_IT()) +#define __HAL_COMP_EXTI_GET_FLAG(__FLAG__) (((__FLAG__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_GET_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_GET_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP3) ? __HAL_COMP_COMP3_EXTI_GET_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_GET_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP5) ? __HAL_COMP_COMP5_EXTI_GET_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP6) ? __HAL_COMP_COMP6_EXTI_GET_FLAG() : \ + __HAL_COMP_COMP7_EXTI_GET_FLAG()) +#define __HAL_COMP_EXTI_CLEAR_FLAG(__FLAG__) (((__FLAG__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_CLEAR_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_CLEAR_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP3) ? __HAL_COMP_COMP3_EXTI_CLEAR_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_CLEAR_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP5) ? __HAL_COMP_COMP5_EXTI_CLEAR_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP6) ? __HAL_COMP_COMP6_EXTI_CLEAR_FLAG() : \ + __HAL_COMP_COMP7_EXTI_CLEAR_FLAG()) +# endif +# if defined(STM32F373xC) ||defined(STM32F378xx) +#define __HAL_COMP_EXTI_RISING_IT_ENABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_RISING_EDGE() : \ + __HAL_COMP_COMP2_EXTI_ENABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_RISING_IT_DISABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_RISING_EDGE() : \ + __HAL_COMP_COMP2_EXTI_DISABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_ENABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_FALLING_EDGE() : \ + __HAL_COMP_COMP2_EXTI_ENABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_DISABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_FALLING_EDGE() : \ + __HAL_COMP_COMP2_EXTI_DISABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_ENABLE_IT(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_IT() : \ + __HAL_COMP_COMP2_EXTI_ENABLE_IT()) +#define __HAL_COMP_EXTI_DISABLE_IT(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_IT() : \ + __HAL_COMP_COMP2_EXTI_DISABLE_IT()) +#define __HAL_COMP_EXTI_GET_FLAG(__FLAG__) (((__FLAG__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_GET_FLAG() : \ + __HAL_COMP_COMP2_EXTI_GET_FLAG()) +#define __HAL_COMP_EXTI_CLEAR_FLAG(__FLAG__) (((__FLAG__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_CLEAR_FLAG() : \ + __HAL_COMP_COMP2_EXTI_CLEAR_FLAG()) +# endif +#else +#define __HAL_COMP_EXTI_RISING_IT_ENABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_RISING_EDGE() : \ + __HAL_COMP_COMP2_EXTI_ENABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_RISING_IT_DISABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_RISING_EDGE() : \ + __HAL_COMP_COMP2_EXTI_DISABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_ENABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_FALLING_EDGE() : \ + __HAL_COMP_COMP2_EXTI_ENABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_DISABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_FALLING_EDGE() : \ + __HAL_COMP_COMP2_EXTI_DISABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_ENABLE_IT(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_IT() : \ + __HAL_COMP_COMP2_EXTI_ENABLE_IT()) +#define __HAL_COMP_EXTI_DISABLE_IT(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_IT() : \ + __HAL_COMP_COMP2_EXTI_DISABLE_IT()) +#define __HAL_COMP_EXTI_GET_FLAG(__FLAG__) (((__FLAG__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_GET_FLAG() : \ + __HAL_COMP_COMP2_EXTI_GET_FLAG()) +#define __HAL_COMP_EXTI_CLEAR_FLAG(__FLAG__) (((__FLAG__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_CLEAR_FLAG() : \ + __HAL_COMP_COMP2_EXTI_CLEAR_FLAG()) +#endif + +#define __HAL_COMP_GET_EXTI_LINE COMP_GET_EXTI_LINE + +#if defined(STM32L0) || defined(STM32L4) +/* Note: On these STM32 families, the only argument of this macro */ +/* is COMP_FLAG_LOCK. */ +/* This macro is replaced by __HAL_COMP_IS_LOCKED with only HAL handle */ +/* argument. */ +#define __HAL_COMP_GET_FLAG(__HANDLE__, __FLAG__) (__HAL_COMP_IS_LOCKED(__HANDLE__)) +#endif +/** + * @} + */ + +#if defined(STM32L0) || defined(STM32L4) +/** @defgroup HAL_COMP_Aliased_Functions HAL COMP Aliased Functions maintained for legacy purpose + * @{ + */ +#define HAL_COMP_Start_IT HAL_COMP_Start /* Function considered as legacy as EXTI event or IT configuration is + done into HAL_COMP_Init() */ +#define HAL_COMP_Stop_IT HAL_COMP_Stop /* Function considered as legacy as EXTI event or IT configuration is + done into HAL_COMP_Init() */ +/** + * @} + */ +#endif + +/** @defgroup HAL_DAC_Aliased_Macros HAL DAC Aliased Macros maintained for legacy purpose + * @{ + */ + +#define IS_DAC_WAVE(WAVE) (((WAVE) == DAC_WAVE_NONE) || \ + ((WAVE) == DAC_WAVE_NOISE)|| \ + ((WAVE) == DAC_WAVE_TRIANGLE)) + +/** + * @} + */ + +/** @defgroup HAL_FLASH_Aliased_Macros HAL FLASH Aliased Macros maintained for legacy purpose + * @{ + */ + +#define IS_WRPAREA IS_OB_WRPAREA +#define IS_TYPEPROGRAM IS_FLASH_TYPEPROGRAM +#define IS_TYPEPROGRAMFLASH IS_FLASH_TYPEPROGRAM +#define IS_TYPEERASE IS_FLASH_TYPEERASE +#define IS_NBSECTORS IS_FLASH_NBSECTORS +#define IS_OB_WDG_SOURCE IS_OB_IWDG_SOURCE + +/** + * @} + */ + +/** @defgroup HAL_I2C_Aliased_Macros HAL I2C Aliased Macros maintained for legacy purpose + * @{ + */ + +#define __HAL_I2C_RESET_CR2 I2C_RESET_CR2 +#define __HAL_I2C_GENERATE_START I2C_GENERATE_START +#if defined(STM32F1) +#define __HAL_I2C_FREQ_RANGE I2C_FREQRANGE +#else +#define __HAL_I2C_FREQ_RANGE I2C_FREQ_RANGE +#endif /* STM32F1 */ +#define __HAL_I2C_RISE_TIME I2C_RISE_TIME +#define __HAL_I2C_SPEED_STANDARD I2C_SPEED_STANDARD +#define __HAL_I2C_SPEED_FAST I2C_SPEED_FAST +#define __HAL_I2C_SPEED I2C_SPEED +#define __HAL_I2C_7BIT_ADD_WRITE I2C_7BIT_ADD_WRITE +#define __HAL_I2C_7BIT_ADD_READ I2C_7BIT_ADD_READ +#define __HAL_I2C_10BIT_ADDRESS I2C_10BIT_ADDRESS +#define __HAL_I2C_10BIT_HEADER_WRITE I2C_10BIT_HEADER_WRITE +#define __HAL_I2C_10BIT_HEADER_READ I2C_10BIT_HEADER_READ +#define __HAL_I2C_MEM_ADD_MSB I2C_MEM_ADD_MSB +#define __HAL_I2C_MEM_ADD_LSB I2C_MEM_ADD_LSB +#define __HAL_I2C_FREQRANGE I2C_FREQRANGE +/** + * @} + */ + +/** @defgroup HAL_I2S_Aliased_Macros HAL I2S Aliased Macros maintained for legacy purpose + * @{ + */ + +#define IS_I2S_INSTANCE IS_I2S_ALL_INSTANCE +#define IS_I2S_INSTANCE_EXT IS_I2S_ALL_INSTANCE_EXT + +#if defined(STM32H7) +#define __HAL_I2S_CLEAR_FREFLAG __HAL_I2S_CLEAR_TIFREFLAG +#endif + +/** + * @} + */ + +/** @defgroup HAL_IRDA_Aliased_Macros HAL IRDA Aliased Macros maintained for legacy purpose + * @{ + */ + +#define __IRDA_DISABLE __HAL_IRDA_DISABLE +#define __IRDA_ENABLE __HAL_IRDA_ENABLE + +#define __HAL_IRDA_GETCLOCKSOURCE IRDA_GETCLOCKSOURCE +#define __HAL_IRDA_MASK_COMPUTATION IRDA_MASK_COMPUTATION +#define __IRDA_GETCLOCKSOURCE IRDA_GETCLOCKSOURCE +#define __IRDA_MASK_COMPUTATION IRDA_MASK_COMPUTATION + +#define IS_IRDA_ONEBIT_SAMPLE IS_IRDA_ONE_BIT_SAMPLE + + +/** + * @} + */ + + +/** @defgroup HAL_IWDG_Aliased_Macros HAL IWDG Aliased Macros maintained for legacy purpose + * @{ + */ +#define __HAL_IWDG_ENABLE_WRITE_ACCESS IWDG_ENABLE_WRITE_ACCESS +#define __HAL_IWDG_DISABLE_WRITE_ACCESS IWDG_DISABLE_WRITE_ACCESS +/** + * @} + */ + + +/** @defgroup HAL_LPTIM_Aliased_Macros HAL LPTIM Aliased Macros maintained for legacy purpose + * @{ + */ + +#define __HAL_LPTIM_ENABLE_INTERRUPT __HAL_LPTIM_ENABLE_IT +#define __HAL_LPTIM_DISABLE_INTERRUPT __HAL_LPTIM_DISABLE_IT +#define __HAL_LPTIM_GET_ITSTATUS __HAL_LPTIM_GET_IT_SOURCE + +/** + * @} + */ + + +/** @defgroup HAL_OPAMP_Aliased_Macros HAL OPAMP Aliased Macros maintained for legacy purpose + * @{ + */ +#define __OPAMP_CSR_OPAXPD OPAMP_CSR_OPAXPD +#define __OPAMP_CSR_S3SELX OPAMP_CSR_S3SELX +#define __OPAMP_CSR_S4SELX OPAMP_CSR_S4SELX +#define __OPAMP_CSR_S5SELX OPAMP_CSR_S5SELX +#define __OPAMP_CSR_S6SELX OPAMP_CSR_S6SELX +#define __OPAMP_CSR_OPAXCAL_L OPAMP_CSR_OPAXCAL_L +#define __OPAMP_CSR_OPAXCAL_H OPAMP_CSR_OPAXCAL_H +#define __OPAMP_CSR_OPAXLPM OPAMP_CSR_OPAXLPM +#define __OPAMP_CSR_ALL_SWITCHES OPAMP_CSR_ALL_SWITCHES +#define __OPAMP_CSR_ANAWSELX OPAMP_CSR_ANAWSELX +#define __OPAMP_CSR_OPAXCALOUT OPAMP_CSR_OPAXCALOUT +#define __OPAMP_OFFSET_TRIM_BITSPOSITION OPAMP_OFFSET_TRIM_BITSPOSITION +#define __OPAMP_OFFSET_TRIM_SET OPAMP_OFFSET_TRIM_SET + +/** + * @} + */ + + +/** @defgroup HAL_PWR_Aliased_Macros HAL PWR Aliased Macros maintained for legacy purpose + * @{ + */ +#define __HAL_PVD_EVENT_DISABLE __HAL_PWR_PVD_EXTI_DISABLE_EVENT +#define __HAL_PVD_EVENT_ENABLE __HAL_PWR_PVD_EXTI_ENABLE_EVENT +#define __HAL_PVD_EXTI_FALLINGTRIGGER_DISABLE __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE +#define __HAL_PVD_EXTI_FALLINGTRIGGER_ENABLE __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE +#define __HAL_PVD_EXTI_RISINGTRIGGER_DISABLE __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE +#define __HAL_PVD_EXTI_RISINGTRIGGER_ENABLE __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE +#define __HAL_PVM_EVENT_DISABLE __HAL_PWR_PVM_EVENT_DISABLE +#define __HAL_PVM_EVENT_ENABLE __HAL_PWR_PVM_EVENT_ENABLE +#define __HAL_PVM_EXTI_FALLINGTRIGGER_DISABLE __HAL_PWR_PVM_EXTI_FALLINGTRIGGER_DISABLE +#define __HAL_PVM_EXTI_FALLINGTRIGGER_ENABLE __HAL_PWR_PVM_EXTI_FALLINGTRIGGER_ENABLE +#define __HAL_PVM_EXTI_RISINGTRIGGER_DISABLE __HAL_PWR_PVM_EXTI_RISINGTRIGGER_DISABLE +#define __HAL_PVM_EXTI_RISINGTRIGGER_ENABLE __HAL_PWR_PVM_EXTI_RISINGTRIGGER_ENABLE +#define __HAL_PWR_INTERNALWAKEUP_DISABLE HAL_PWREx_DisableInternalWakeUpLine +#define __HAL_PWR_INTERNALWAKEUP_ENABLE HAL_PWREx_EnableInternalWakeUpLine +#define __HAL_PWR_PULL_UP_DOWN_CONFIG_DISABLE HAL_PWREx_DisablePullUpPullDownConfig +#define __HAL_PWR_PULL_UP_DOWN_CONFIG_ENABLE HAL_PWREx_EnablePullUpPullDownConfig +#define __HAL_PWR_PVD_EXTI_CLEAR_EGDE_TRIGGER() do { __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE(); \ + __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE(); \ + } while(0) +#define __HAL_PWR_PVD_EXTI_EVENT_DISABLE __HAL_PWR_PVD_EXTI_DISABLE_EVENT +#define __HAL_PWR_PVD_EXTI_EVENT_ENABLE __HAL_PWR_PVD_EXTI_ENABLE_EVENT +#define __HAL_PWR_PVD_EXTI_FALLINGTRIGGER_DISABLE __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE +#define __HAL_PWR_PVD_EXTI_FALLINGTRIGGER_ENABLE __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE +#define __HAL_PWR_PVD_EXTI_RISINGTRIGGER_DISABLE __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE +#define __HAL_PWR_PVD_EXTI_RISINGTRIGGER_ENABLE __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE +#define __HAL_PWR_PVD_EXTI_SET_FALLING_EGDE_TRIGGER __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE +#define __HAL_PWR_PVD_EXTI_SET_RISING_EDGE_TRIGGER __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE +#define __HAL_PWR_PVM_DISABLE() do { HAL_PWREx_DisablePVM1();HAL_PWREx_DisablePVM2(); \ + HAL_PWREx_DisablePVM3();HAL_PWREx_DisablePVM4(); \ + } while(0) +#define __HAL_PWR_PVM_ENABLE() do { HAL_PWREx_EnablePVM1();HAL_PWREx_EnablePVM2(); \ + HAL_PWREx_EnablePVM3();HAL_PWREx_EnablePVM4(); \ + } while(0) +#define __HAL_PWR_SRAM2CONTENT_PRESERVE_DISABLE HAL_PWREx_DisableSRAM2ContentRetention +#define __HAL_PWR_SRAM2CONTENT_PRESERVE_ENABLE HAL_PWREx_EnableSRAM2ContentRetention +#define __HAL_PWR_VDDIO2_DISABLE HAL_PWREx_DisableVddIO2 +#define __HAL_PWR_VDDIO2_ENABLE HAL_PWREx_EnableVddIO2 +#define __HAL_PWR_VDDIO2_EXTI_CLEAR_EGDE_TRIGGER __HAL_PWR_VDDIO2_EXTI_DISABLE_FALLING_EDGE +#define __HAL_PWR_VDDIO2_EXTI_SET_FALLING_EGDE_TRIGGER __HAL_PWR_VDDIO2_EXTI_ENABLE_FALLING_EDGE +#define __HAL_PWR_VDDUSB_DISABLE HAL_PWREx_DisableVddUSB +#define __HAL_PWR_VDDUSB_ENABLE HAL_PWREx_EnableVddUSB + +#if defined (STM32F4) +#define __HAL_PVD_EXTI_ENABLE_IT(PWR_EXTI_LINE_PVD) __HAL_PWR_PVD_EXTI_ENABLE_IT() +#define __HAL_PVD_EXTI_DISABLE_IT(PWR_EXTI_LINE_PVD) __HAL_PWR_PVD_EXTI_DISABLE_IT() +#define __HAL_PVD_EXTI_GET_FLAG(PWR_EXTI_LINE_PVD) __HAL_PWR_PVD_EXTI_GET_FLAG() +#define __HAL_PVD_EXTI_CLEAR_FLAG(PWR_EXTI_LINE_PVD) __HAL_PWR_PVD_EXTI_CLEAR_FLAG() +#define __HAL_PVD_EXTI_GENERATE_SWIT(PWR_EXTI_LINE_PVD) __HAL_PWR_PVD_EXTI_GENERATE_SWIT() +#else +#define __HAL_PVD_EXTI_CLEAR_FLAG __HAL_PWR_PVD_EXTI_CLEAR_FLAG +#define __HAL_PVD_EXTI_DISABLE_IT __HAL_PWR_PVD_EXTI_DISABLE_IT +#define __HAL_PVD_EXTI_ENABLE_IT __HAL_PWR_PVD_EXTI_ENABLE_IT +#define __HAL_PVD_EXTI_GENERATE_SWIT __HAL_PWR_PVD_EXTI_GENERATE_SWIT +#define __HAL_PVD_EXTI_GET_FLAG __HAL_PWR_PVD_EXTI_GET_FLAG +#endif /* STM32F4 */ +/** + * @} + */ + + +/** @defgroup HAL_RCC_Aliased HAL RCC Aliased maintained for legacy purpose + * @{ + */ + +#define RCC_StopWakeUpClock_MSI RCC_STOP_WAKEUPCLOCK_MSI +#define RCC_StopWakeUpClock_HSI RCC_STOP_WAKEUPCLOCK_HSI + +#define HAL_RCC_CCSCallback HAL_RCC_CSSCallback +#define HAL_RC48_EnableBuffer_Cmd(cmd) (((cmd)==ENABLE) ? \ + HAL_RCCEx_EnableHSI48_VREFINT() : HAL_RCCEx_DisableHSI48_VREFINT()) + +#define __ADC_CLK_DISABLE __HAL_RCC_ADC_CLK_DISABLE +#define __ADC_CLK_ENABLE __HAL_RCC_ADC_CLK_ENABLE +#define __ADC_CLK_SLEEP_DISABLE __HAL_RCC_ADC_CLK_SLEEP_DISABLE +#define __ADC_CLK_SLEEP_ENABLE __HAL_RCC_ADC_CLK_SLEEP_ENABLE +#define __ADC_FORCE_RESET __HAL_RCC_ADC_FORCE_RESET +#define __ADC_RELEASE_RESET __HAL_RCC_ADC_RELEASE_RESET +#define __ADC1_CLK_DISABLE __HAL_RCC_ADC1_CLK_DISABLE +#define __ADC1_CLK_ENABLE __HAL_RCC_ADC1_CLK_ENABLE +#define __ADC1_FORCE_RESET __HAL_RCC_ADC1_FORCE_RESET +#define __ADC1_RELEASE_RESET __HAL_RCC_ADC1_RELEASE_RESET +#define __ADC1_CLK_SLEEP_ENABLE __HAL_RCC_ADC1_CLK_SLEEP_ENABLE +#define __ADC1_CLK_SLEEP_DISABLE __HAL_RCC_ADC1_CLK_SLEEP_DISABLE +#define __ADC2_CLK_DISABLE __HAL_RCC_ADC2_CLK_DISABLE +#define __ADC2_CLK_ENABLE __HAL_RCC_ADC2_CLK_ENABLE +#define __ADC2_FORCE_RESET __HAL_RCC_ADC2_FORCE_RESET +#define __ADC2_RELEASE_RESET __HAL_RCC_ADC2_RELEASE_RESET +#define __ADC3_CLK_DISABLE __HAL_RCC_ADC3_CLK_DISABLE +#define __ADC3_CLK_ENABLE __HAL_RCC_ADC3_CLK_ENABLE +#define __ADC3_FORCE_RESET __HAL_RCC_ADC3_FORCE_RESET +#define __ADC3_RELEASE_RESET __HAL_RCC_ADC3_RELEASE_RESET +#define __AES_CLK_DISABLE __HAL_RCC_AES_CLK_DISABLE +#define __AES_CLK_ENABLE __HAL_RCC_AES_CLK_ENABLE +#define __AES_CLK_SLEEP_DISABLE __HAL_RCC_AES_CLK_SLEEP_DISABLE +#define __AES_CLK_SLEEP_ENABLE __HAL_RCC_AES_CLK_SLEEP_ENABLE +#define __AES_FORCE_RESET __HAL_RCC_AES_FORCE_RESET +#define __AES_RELEASE_RESET __HAL_RCC_AES_RELEASE_RESET +#define __CRYP_CLK_SLEEP_ENABLE __HAL_RCC_CRYP_CLK_SLEEP_ENABLE +#define __CRYP_CLK_SLEEP_DISABLE __HAL_RCC_CRYP_CLK_SLEEP_DISABLE +#define __CRYP_CLK_ENABLE __HAL_RCC_CRYP_CLK_ENABLE +#define __CRYP_CLK_DISABLE __HAL_RCC_CRYP_CLK_DISABLE +#define __CRYP_FORCE_RESET __HAL_RCC_CRYP_FORCE_RESET +#define __CRYP_RELEASE_RESET __HAL_RCC_CRYP_RELEASE_RESET +#define __AFIO_CLK_DISABLE __HAL_RCC_AFIO_CLK_DISABLE +#define __AFIO_CLK_ENABLE __HAL_RCC_AFIO_CLK_ENABLE +#define __AFIO_FORCE_RESET __HAL_RCC_AFIO_FORCE_RESET +#define __AFIO_RELEASE_RESET __HAL_RCC_AFIO_RELEASE_RESET +#define __AHB_FORCE_RESET __HAL_RCC_AHB_FORCE_RESET +#define __AHB_RELEASE_RESET __HAL_RCC_AHB_RELEASE_RESET +#define __AHB1_FORCE_RESET __HAL_RCC_AHB1_FORCE_RESET +#define __AHB1_RELEASE_RESET __HAL_RCC_AHB1_RELEASE_RESET +#define __AHB2_FORCE_RESET __HAL_RCC_AHB2_FORCE_RESET +#define __AHB2_RELEASE_RESET __HAL_RCC_AHB2_RELEASE_RESET +#define __AHB3_FORCE_RESET __HAL_RCC_AHB3_FORCE_RESET +#define __AHB3_RELEASE_RESET __HAL_RCC_AHB3_RELEASE_RESET +#define __APB1_FORCE_RESET __HAL_RCC_APB1_FORCE_RESET +#define __APB1_RELEASE_RESET __HAL_RCC_APB1_RELEASE_RESET +#define __APB2_FORCE_RESET __HAL_RCC_APB2_FORCE_RESET +#define __APB2_RELEASE_RESET __HAL_RCC_APB2_RELEASE_RESET +#define __BKP_CLK_DISABLE __HAL_RCC_BKP_CLK_DISABLE +#define __BKP_CLK_ENABLE __HAL_RCC_BKP_CLK_ENABLE +#define __BKP_FORCE_RESET __HAL_RCC_BKP_FORCE_RESET +#define __BKP_RELEASE_RESET __HAL_RCC_BKP_RELEASE_RESET +#define __CAN1_CLK_DISABLE __HAL_RCC_CAN1_CLK_DISABLE +#define __CAN1_CLK_ENABLE __HAL_RCC_CAN1_CLK_ENABLE +#define __CAN1_CLK_SLEEP_DISABLE __HAL_RCC_CAN1_CLK_SLEEP_DISABLE +#define __CAN1_CLK_SLEEP_ENABLE __HAL_RCC_CAN1_CLK_SLEEP_ENABLE +#define __CAN1_FORCE_RESET __HAL_RCC_CAN1_FORCE_RESET +#define __CAN1_RELEASE_RESET __HAL_RCC_CAN1_RELEASE_RESET +#define __CAN_CLK_DISABLE __HAL_RCC_CAN1_CLK_DISABLE +#define __CAN_CLK_ENABLE __HAL_RCC_CAN1_CLK_ENABLE +#define __CAN_FORCE_RESET __HAL_RCC_CAN1_FORCE_RESET +#define __CAN_RELEASE_RESET __HAL_RCC_CAN1_RELEASE_RESET +#define __CAN2_CLK_DISABLE __HAL_RCC_CAN2_CLK_DISABLE +#define __CAN2_CLK_ENABLE __HAL_RCC_CAN2_CLK_ENABLE +#define __CAN2_FORCE_RESET __HAL_RCC_CAN2_FORCE_RESET +#define __CAN2_RELEASE_RESET __HAL_RCC_CAN2_RELEASE_RESET +#define __CEC_CLK_DISABLE __HAL_RCC_CEC_CLK_DISABLE +#define __CEC_CLK_ENABLE __HAL_RCC_CEC_CLK_ENABLE +#define __COMP_CLK_DISABLE __HAL_RCC_COMP_CLK_DISABLE +#define __COMP_CLK_ENABLE __HAL_RCC_COMP_CLK_ENABLE +#define __COMP_FORCE_RESET __HAL_RCC_COMP_FORCE_RESET +#define __COMP_RELEASE_RESET __HAL_RCC_COMP_RELEASE_RESET +#define __COMP_CLK_SLEEP_ENABLE __HAL_RCC_COMP_CLK_SLEEP_ENABLE +#define __COMP_CLK_SLEEP_DISABLE __HAL_RCC_COMP_CLK_SLEEP_DISABLE +#define __CEC_FORCE_RESET __HAL_RCC_CEC_FORCE_RESET +#define __CEC_RELEASE_RESET __HAL_RCC_CEC_RELEASE_RESET +#define __CRC_CLK_DISABLE __HAL_RCC_CRC_CLK_DISABLE +#define __CRC_CLK_ENABLE __HAL_RCC_CRC_CLK_ENABLE +#define __CRC_CLK_SLEEP_DISABLE __HAL_RCC_CRC_CLK_SLEEP_DISABLE +#define __CRC_CLK_SLEEP_ENABLE __HAL_RCC_CRC_CLK_SLEEP_ENABLE +#define __CRC_FORCE_RESET __HAL_RCC_CRC_FORCE_RESET +#define __CRC_RELEASE_RESET __HAL_RCC_CRC_RELEASE_RESET +#define __DAC_CLK_DISABLE __HAL_RCC_DAC_CLK_DISABLE +#define __DAC_CLK_ENABLE __HAL_RCC_DAC_CLK_ENABLE +#define __DAC_FORCE_RESET __HAL_RCC_DAC_FORCE_RESET +#define __DAC_RELEASE_RESET __HAL_RCC_DAC_RELEASE_RESET +#define __DAC1_CLK_DISABLE __HAL_RCC_DAC1_CLK_DISABLE +#define __DAC1_CLK_ENABLE __HAL_RCC_DAC1_CLK_ENABLE +#define __DAC1_CLK_SLEEP_DISABLE __HAL_RCC_DAC1_CLK_SLEEP_DISABLE +#define __DAC1_CLK_SLEEP_ENABLE __HAL_RCC_DAC1_CLK_SLEEP_ENABLE +#define __DAC1_FORCE_RESET __HAL_RCC_DAC1_FORCE_RESET +#define __DAC1_RELEASE_RESET __HAL_RCC_DAC1_RELEASE_RESET +#define __DBGMCU_CLK_ENABLE __HAL_RCC_DBGMCU_CLK_ENABLE +#define __DBGMCU_CLK_DISABLE __HAL_RCC_DBGMCU_CLK_DISABLE +#define __DBGMCU_FORCE_RESET __HAL_RCC_DBGMCU_FORCE_RESET +#define __DBGMCU_RELEASE_RESET __HAL_RCC_DBGMCU_RELEASE_RESET +#define __DFSDM_CLK_DISABLE __HAL_RCC_DFSDM_CLK_DISABLE +#define __DFSDM_CLK_ENABLE __HAL_RCC_DFSDM_CLK_ENABLE +#define __DFSDM_CLK_SLEEP_DISABLE __HAL_RCC_DFSDM_CLK_SLEEP_DISABLE +#define __DFSDM_CLK_SLEEP_ENABLE __HAL_RCC_DFSDM_CLK_SLEEP_ENABLE +#define __DFSDM_FORCE_RESET __HAL_RCC_DFSDM_FORCE_RESET +#define __DFSDM_RELEASE_RESET __HAL_RCC_DFSDM_RELEASE_RESET +#define __DMA1_CLK_DISABLE __HAL_RCC_DMA1_CLK_DISABLE +#define __DMA1_CLK_ENABLE __HAL_RCC_DMA1_CLK_ENABLE +#define __DMA1_CLK_SLEEP_DISABLE __HAL_RCC_DMA1_CLK_SLEEP_DISABLE +#define __DMA1_CLK_SLEEP_ENABLE __HAL_RCC_DMA1_CLK_SLEEP_ENABLE +#define __DMA1_FORCE_RESET __HAL_RCC_DMA1_FORCE_RESET +#define __DMA1_RELEASE_RESET __HAL_RCC_DMA1_RELEASE_RESET +#define __DMA2_CLK_DISABLE __HAL_RCC_DMA2_CLK_DISABLE +#define __DMA2_CLK_ENABLE __HAL_RCC_DMA2_CLK_ENABLE +#define __DMA2_CLK_SLEEP_DISABLE __HAL_RCC_DMA2_CLK_SLEEP_DISABLE +#define __DMA2_CLK_SLEEP_ENABLE __HAL_RCC_DMA2_CLK_SLEEP_ENABLE +#define __DMA2_FORCE_RESET __HAL_RCC_DMA2_FORCE_RESET +#define __DMA2_RELEASE_RESET __HAL_RCC_DMA2_RELEASE_RESET +#define __ETHMAC_CLK_DISABLE __HAL_RCC_ETHMAC_CLK_DISABLE +#define __ETHMAC_CLK_ENABLE __HAL_RCC_ETHMAC_CLK_ENABLE +#define __ETHMAC_FORCE_RESET __HAL_RCC_ETHMAC_FORCE_RESET +#define __ETHMAC_RELEASE_RESET __HAL_RCC_ETHMAC_RELEASE_RESET +#define __ETHMACRX_CLK_DISABLE __HAL_RCC_ETHMACRX_CLK_DISABLE +#define __ETHMACRX_CLK_ENABLE __HAL_RCC_ETHMACRX_CLK_ENABLE +#define __ETHMACTX_CLK_DISABLE __HAL_RCC_ETHMACTX_CLK_DISABLE +#define __ETHMACTX_CLK_ENABLE __HAL_RCC_ETHMACTX_CLK_ENABLE +#define __FIREWALL_CLK_DISABLE __HAL_RCC_FIREWALL_CLK_DISABLE +#define __FIREWALL_CLK_ENABLE __HAL_RCC_FIREWALL_CLK_ENABLE +#define __FLASH_CLK_DISABLE __HAL_RCC_FLASH_CLK_DISABLE +#define __FLASH_CLK_ENABLE __HAL_RCC_FLASH_CLK_ENABLE +#define __FLASH_CLK_SLEEP_DISABLE __HAL_RCC_FLASH_CLK_SLEEP_DISABLE +#define __FLASH_CLK_SLEEP_ENABLE __HAL_RCC_FLASH_CLK_SLEEP_ENABLE +#define __FLASH_FORCE_RESET __HAL_RCC_FLASH_FORCE_RESET +#define __FLASH_RELEASE_RESET __HAL_RCC_FLASH_RELEASE_RESET +#define __FLITF_CLK_DISABLE __HAL_RCC_FLITF_CLK_DISABLE +#define __FLITF_CLK_ENABLE __HAL_RCC_FLITF_CLK_ENABLE +#define __FLITF_FORCE_RESET __HAL_RCC_FLITF_FORCE_RESET +#define __FLITF_RELEASE_RESET __HAL_RCC_FLITF_RELEASE_RESET +#define __FLITF_CLK_SLEEP_ENABLE __HAL_RCC_FLITF_CLK_SLEEP_ENABLE +#define __FLITF_CLK_SLEEP_DISABLE __HAL_RCC_FLITF_CLK_SLEEP_DISABLE +#define __FMC_CLK_DISABLE __HAL_RCC_FMC_CLK_DISABLE +#define __FMC_CLK_ENABLE __HAL_RCC_FMC_CLK_ENABLE +#define __FMC_CLK_SLEEP_DISABLE __HAL_RCC_FMC_CLK_SLEEP_DISABLE +#define __FMC_CLK_SLEEP_ENABLE __HAL_RCC_FMC_CLK_SLEEP_ENABLE +#define __FMC_FORCE_RESET __HAL_RCC_FMC_FORCE_RESET +#define __FMC_RELEASE_RESET __HAL_RCC_FMC_RELEASE_RESET +#define __FSMC_CLK_DISABLE __HAL_RCC_FSMC_CLK_DISABLE +#define __FSMC_CLK_ENABLE __HAL_RCC_FSMC_CLK_ENABLE +#define __GPIOA_CLK_DISABLE __HAL_RCC_GPIOA_CLK_DISABLE +#define __GPIOA_CLK_ENABLE __HAL_RCC_GPIOA_CLK_ENABLE +#define __GPIOA_CLK_SLEEP_DISABLE __HAL_RCC_GPIOA_CLK_SLEEP_DISABLE +#define __GPIOA_CLK_SLEEP_ENABLE __HAL_RCC_GPIOA_CLK_SLEEP_ENABLE +#define __GPIOA_FORCE_RESET __HAL_RCC_GPIOA_FORCE_RESET +#define __GPIOA_RELEASE_RESET __HAL_RCC_GPIOA_RELEASE_RESET +#define __GPIOB_CLK_DISABLE __HAL_RCC_GPIOB_CLK_DISABLE +#define __GPIOB_CLK_ENABLE __HAL_RCC_GPIOB_CLK_ENABLE +#define __GPIOB_CLK_SLEEP_DISABLE __HAL_RCC_GPIOB_CLK_SLEEP_DISABLE +#define __GPIOB_CLK_SLEEP_ENABLE __HAL_RCC_GPIOB_CLK_SLEEP_ENABLE +#define __GPIOB_FORCE_RESET __HAL_RCC_GPIOB_FORCE_RESET +#define __GPIOB_RELEASE_RESET __HAL_RCC_GPIOB_RELEASE_RESET +#define __GPIOC_CLK_DISABLE __HAL_RCC_GPIOC_CLK_DISABLE +#define __GPIOC_CLK_ENABLE __HAL_RCC_GPIOC_CLK_ENABLE +#define __GPIOC_CLK_SLEEP_DISABLE __HAL_RCC_GPIOC_CLK_SLEEP_DISABLE +#define __GPIOC_CLK_SLEEP_ENABLE __HAL_RCC_GPIOC_CLK_SLEEP_ENABLE +#define __GPIOC_FORCE_RESET __HAL_RCC_GPIOC_FORCE_RESET +#define __GPIOC_RELEASE_RESET __HAL_RCC_GPIOC_RELEASE_RESET +#define __GPIOD_CLK_DISABLE __HAL_RCC_GPIOD_CLK_DISABLE +#define __GPIOD_CLK_ENABLE __HAL_RCC_GPIOD_CLK_ENABLE +#define __GPIOD_CLK_SLEEP_DISABLE __HAL_RCC_GPIOD_CLK_SLEEP_DISABLE +#define __GPIOD_CLK_SLEEP_ENABLE __HAL_RCC_GPIOD_CLK_SLEEP_ENABLE +#define __GPIOD_FORCE_RESET __HAL_RCC_GPIOD_FORCE_RESET +#define __GPIOD_RELEASE_RESET __HAL_RCC_GPIOD_RELEASE_RESET +#define __GPIOE_CLK_DISABLE __HAL_RCC_GPIOE_CLK_DISABLE +#define __GPIOE_CLK_ENABLE __HAL_RCC_GPIOE_CLK_ENABLE +#define __GPIOE_CLK_SLEEP_DISABLE __HAL_RCC_GPIOE_CLK_SLEEP_DISABLE +#define __GPIOE_CLK_SLEEP_ENABLE __HAL_RCC_GPIOE_CLK_SLEEP_ENABLE +#define __GPIOE_FORCE_RESET __HAL_RCC_GPIOE_FORCE_RESET +#define __GPIOE_RELEASE_RESET __HAL_RCC_GPIOE_RELEASE_RESET +#define __GPIOF_CLK_DISABLE __HAL_RCC_GPIOF_CLK_DISABLE +#define __GPIOF_CLK_ENABLE __HAL_RCC_GPIOF_CLK_ENABLE +#define __GPIOF_CLK_SLEEP_DISABLE __HAL_RCC_GPIOF_CLK_SLEEP_DISABLE +#define __GPIOF_CLK_SLEEP_ENABLE __HAL_RCC_GPIOF_CLK_SLEEP_ENABLE +#define __GPIOF_FORCE_RESET __HAL_RCC_GPIOF_FORCE_RESET +#define __GPIOF_RELEASE_RESET __HAL_RCC_GPIOF_RELEASE_RESET +#define __GPIOG_CLK_DISABLE __HAL_RCC_GPIOG_CLK_DISABLE +#define __GPIOG_CLK_ENABLE __HAL_RCC_GPIOG_CLK_ENABLE +#define __GPIOG_CLK_SLEEP_DISABLE __HAL_RCC_GPIOG_CLK_SLEEP_DISABLE +#define __GPIOG_CLK_SLEEP_ENABLE __HAL_RCC_GPIOG_CLK_SLEEP_ENABLE +#define __GPIOG_FORCE_RESET __HAL_RCC_GPIOG_FORCE_RESET +#define __GPIOG_RELEASE_RESET __HAL_RCC_GPIOG_RELEASE_RESET +#define __GPIOH_CLK_DISABLE __HAL_RCC_GPIOH_CLK_DISABLE +#define __GPIOH_CLK_ENABLE __HAL_RCC_GPIOH_CLK_ENABLE +#define __GPIOH_CLK_SLEEP_DISABLE __HAL_RCC_GPIOH_CLK_SLEEP_DISABLE +#define __GPIOH_CLK_SLEEP_ENABLE __HAL_RCC_GPIOH_CLK_SLEEP_ENABLE +#define __GPIOH_FORCE_RESET __HAL_RCC_GPIOH_FORCE_RESET +#define __GPIOH_RELEASE_RESET __HAL_RCC_GPIOH_RELEASE_RESET +#define __I2C1_CLK_DISABLE __HAL_RCC_I2C1_CLK_DISABLE +#define __I2C1_CLK_ENABLE __HAL_RCC_I2C1_CLK_ENABLE +#define __I2C1_CLK_SLEEP_DISABLE __HAL_RCC_I2C1_CLK_SLEEP_DISABLE +#define __I2C1_CLK_SLEEP_ENABLE __HAL_RCC_I2C1_CLK_SLEEP_ENABLE +#define __I2C1_FORCE_RESET __HAL_RCC_I2C1_FORCE_RESET +#define __I2C1_RELEASE_RESET __HAL_RCC_I2C1_RELEASE_RESET +#define __I2C2_CLK_DISABLE __HAL_RCC_I2C2_CLK_DISABLE +#define __I2C2_CLK_ENABLE __HAL_RCC_I2C2_CLK_ENABLE +#define __I2C2_CLK_SLEEP_DISABLE __HAL_RCC_I2C2_CLK_SLEEP_DISABLE +#define __I2C2_CLK_SLEEP_ENABLE __HAL_RCC_I2C2_CLK_SLEEP_ENABLE +#define __I2C2_FORCE_RESET __HAL_RCC_I2C2_FORCE_RESET +#define __I2C2_RELEASE_RESET __HAL_RCC_I2C2_RELEASE_RESET +#define __I2C3_CLK_DISABLE __HAL_RCC_I2C3_CLK_DISABLE +#define __I2C3_CLK_ENABLE __HAL_RCC_I2C3_CLK_ENABLE +#define __I2C3_CLK_SLEEP_DISABLE __HAL_RCC_I2C3_CLK_SLEEP_DISABLE +#define __I2C3_CLK_SLEEP_ENABLE __HAL_RCC_I2C3_CLK_SLEEP_ENABLE +#define __I2C3_FORCE_RESET __HAL_RCC_I2C3_FORCE_RESET +#define __I2C3_RELEASE_RESET __HAL_RCC_I2C3_RELEASE_RESET +#define __LCD_CLK_DISABLE __HAL_RCC_LCD_CLK_DISABLE +#define __LCD_CLK_ENABLE __HAL_RCC_LCD_CLK_ENABLE +#define __LCD_CLK_SLEEP_DISABLE __HAL_RCC_LCD_CLK_SLEEP_DISABLE +#define __LCD_CLK_SLEEP_ENABLE __HAL_RCC_LCD_CLK_SLEEP_ENABLE +#define __LCD_FORCE_RESET __HAL_RCC_LCD_FORCE_RESET +#define __LCD_RELEASE_RESET __HAL_RCC_LCD_RELEASE_RESET +#define __LPTIM1_CLK_DISABLE __HAL_RCC_LPTIM1_CLK_DISABLE +#define __LPTIM1_CLK_ENABLE __HAL_RCC_LPTIM1_CLK_ENABLE +#define __LPTIM1_CLK_SLEEP_DISABLE __HAL_RCC_LPTIM1_CLK_SLEEP_DISABLE +#define __LPTIM1_CLK_SLEEP_ENABLE __HAL_RCC_LPTIM1_CLK_SLEEP_ENABLE +#define __LPTIM1_FORCE_RESET __HAL_RCC_LPTIM1_FORCE_RESET +#define __LPTIM1_RELEASE_RESET __HAL_RCC_LPTIM1_RELEASE_RESET +#define __LPTIM2_CLK_DISABLE __HAL_RCC_LPTIM2_CLK_DISABLE +#define __LPTIM2_CLK_ENABLE __HAL_RCC_LPTIM2_CLK_ENABLE +#define __LPTIM2_CLK_SLEEP_DISABLE __HAL_RCC_LPTIM2_CLK_SLEEP_DISABLE +#define __LPTIM2_CLK_SLEEP_ENABLE __HAL_RCC_LPTIM2_CLK_SLEEP_ENABLE +#define __LPTIM2_FORCE_RESET __HAL_RCC_LPTIM2_FORCE_RESET +#define __LPTIM2_RELEASE_RESET __HAL_RCC_LPTIM2_RELEASE_RESET +#define __LPUART1_CLK_DISABLE __HAL_RCC_LPUART1_CLK_DISABLE +#define __LPUART1_CLK_ENABLE __HAL_RCC_LPUART1_CLK_ENABLE +#define __LPUART1_CLK_SLEEP_DISABLE __HAL_RCC_LPUART1_CLK_SLEEP_DISABLE +#define __LPUART1_CLK_SLEEP_ENABLE __HAL_RCC_LPUART1_CLK_SLEEP_ENABLE +#define __LPUART1_FORCE_RESET __HAL_RCC_LPUART1_FORCE_RESET +#define __LPUART1_RELEASE_RESET __HAL_RCC_LPUART1_RELEASE_RESET +#define __OPAMP_CLK_DISABLE __HAL_RCC_OPAMP_CLK_DISABLE +#define __OPAMP_CLK_ENABLE __HAL_RCC_OPAMP_CLK_ENABLE +#define __OPAMP_CLK_SLEEP_DISABLE __HAL_RCC_OPAMP_CLK_SLEEP_DISABLE +#define __OPAMP_CLK_SLEEP_ENABLE __HAL_RCC_OPAMP_CLK_SLEEP_ENABLE +#define __OPAMP_FORCE_RESET __HAL_RCC_OPAMP_FORCE_RESET +#define __OPAMP_RELEASE_RESET __HAL_RCC_OPAMP_RELEASE_RESET +#define __OTGFS_CLK_DISABLE __HAL_RCC_OTGFS_CLK_DISABLE +#define __OTGFS_CLK_ENABLE __HAL_RCC_OTGFS_CLK_ENABLE +#define __OTGFS_CLK_SLEEP_DISABLE __HAL_RCC_OTGFS_CLK_SLEEP_DISABLE +#define __OTGFS_CLK_SLEEP_ENABLE __HAL_RCC_OTGFS_CLK_SLEEP_ENABLE +#define __OTGFS_FORCE_RESET __HAL_RCC_OTGFS_FORCE_RESET +#define __OTGFS_RELEASE_RESET __HAL_RCC_OTGFS_RELEASE_RESET +#define __PWR_CLK_DISABLE __HAL_RCC_PWR_CLK_DISABLE +#define __PWR_CLK_ENABLE __HAL_RCC_PWR_CLK_ENABLE +#define __PWR_CLK_SLEEP_DISABLE __HAL_RCC_PWR_CLK_SLEEP_DISABLE +#define __PWR_CLK_SLEEP_ENABLE __HAL_RCC_PWR_CLK_SLEEP_ENABLE +#define __PWR_FORCE_RESET __HAL_RCC_PWR_FORCE_RESET +#define __PWR_RELEASE_RESET __HAL_RCC_PWR_RELEASE_RESET +#define __QSPI_CLK_DISABLE __HAL_RCC_QSPI_CLK_DISABLE +#define __QSPI_CLK_ENABLE __HAL_RCC_QSPI_CLK_ENABLE +#define __QSPI_CLK_SLEEP_DISABLE __HAL_RCC_QSPI_CLK_SLEEP_DISABLE +#define __QSPI_CLK_SLEEP_ENABLE __HAL_RCC_QSPI_CLK_SLEEP_ENABLE +#define __QSPI_FORCE_RESET __HAL_RCC_QSPI_FORCE_RESET +#define __QSPI_RELEASE_RESET __HAL_RCC_QSPI_RELEASE_RESET + +#if defined(STM32WB) +#define __HAL_RCC_QSPI_CLK_DISABLE __HAL_RCC_QUADSPI_CLK_DISABLE +#define __HAL_RCC_QSPI_CLK_ENABLE __HAL_RCC_QUADSPI_CLK_ENABLE +#define __HAL_RCC_QSPI_CLK_SLEEP_DISABLE __HAL_RCC_QUADSPI_CLK_SLEEP_DISABLE +#define __HAL_RCC_QSPI_CLK_SLEEP_ENABLE __HAL_RCC_QUADSPI_CLK_SLEEP_ENABLE +#define __HAL_RCC_QSPI_FORCE_RESET __HAL_RCC_QUADSPI_FORCE_RESET +#define __HAL_RCC_QSPI_RELEASE_RESET __HAL_RCC_QUADSPI_RELEASE_RESET +#define __HAL_RCC_QSPI_IS_CLK_ENABLED __HAL_RCC_QUADSPI_IS_CLK_ENABLED +#define __HAL_RCC_QSPI_IS_CLK_DISABLED __HAL_RCC_QUADSPI_IS_CLK_DISABLED +#define __HAL_RCC_QSPI_IS_CLK_SLEEP_ENABLED __HAL_RCC_QUADSPI_IS_CLK_SLEEP_ENABLED +#define __HAL_RCC_QSPI_IS_CLK_SLEEP_DISABLED __HAL_RCC_QUADSPI_IS_CLK_SLEEP_DISABLED +#define QSPI_IRQHandler QUADSPI_IRQHandler +#endif /* __HAL_RCC_QUADSPI_CLK_ENABLE */ + +#define __RNG_CLK_DISABLE __HAL_RCC_RNG_CLK_DISABLE +#define __RNG_CLK_ENABLE __HAL_RCC_RNG_CLK_ENABLE +#define __RNG_CLK_SLEEP_DISABLE __HAL_RCC_RNG_CLK_SLEEP_DISABLE +#define __RNG_CLK_SLEEP_ENABLE __HAL_RCC_RNG_CLK_SLEEP_ENABLE +#define __RNG_FORCE_RESET __HAL_RCC_RNG_FORCE_RESET +#define __RNG_RELEASE_RESET __HAL_RCC_RNG_RELEASE_RESET +#define __SAI1_CLK_DISABLE __HAL_RCC_SAI1_CLK_DISABLE +#define __SAI1_CLK_ENABLE __HAL_RCC_SAI1_CLK_ENABLE +#define __SAI1_CLK_SLEEP_DISABLE __HAL_RCC_SAI1_CLK_SLEEP_DISABLE +#define __SAI1_CLK_SLEEP_ENABLE __HAL_RCC_SAI1_CLK_SLEEP_ENABLE +#define __SAI1_FORCE_RESET __HAL_RCC_SAI1_FORCE_RESET +#define __SAI1_RELEASE_RESET __HAL_RCC_SAI1_RELEASE_RESET +#define __SAI2_CLK_DISABLE __HAL_RCC_SAI2_CLK_DISABLE +#define __SAI2_CLK_ENABLE __HAL_RCC_SAI2_CLK_ENABLE +#define __SAI2_CLK_SLEEP_DISABLE __HAL_RCC_SAI2_CLK_SLEEP_DISABLE +#define __SAI2_CLK_SLEEP_ENABLE __HAL_RCC_SAI2_CLK_SLEEP_ENABLE +#define __SAI2_FORCE_RESET __HAL_RCC_SAI2_FORCE_RESET +#define __SAI2_RELEASE_RESET __HAL_RCC_SAI2_RELEASE_RESET +#define __SDIO_CLK_DISABLE __HAL_RCC_SDIO_CLK_DISABLE +#define __SDIO_CLK_ENABLE __HAL_RCC_SDIO_CLK_ENABLE +#define __SDMMC_CLK_DISABLE __HAL_RCC_SDMMC_CLK_DISABLE +#define __SDMMC_CLK_ENABLE __HAL_RCC_SDMMC_CLK_ENABLE +#define __SDMMC_CLK_SLEEP_DISABLE __HAL_RCC_SDMMC_CLK_SLEEP_DISABLE +#define __SDMMC_CLK_SLEEP_ENABLE __HAL_RCC_SDMMC_CLK_SLEEP_ENABLE +#define __SDMMC_FORCE_RESET __HAL_RCC_SDMMC_FORCE_RESET +#define __SDMMC_RELEASE_RESET __HAL_RCC_SDMMC_RELEASE_RESET +#define __SPI1_CLK_DISABLE __HAL_RCC_SPI1_CLK_DISABLE +#define __SPI1_CLK_ENABLE __HAL_RCC_SPI1_CLK_ENABLE +#define __SPI1_CLK_SLEEP_DISABLE __HAL_RCC_SPI1_CLK_SLEEP_DISABLE +#define __SPI1_CLK_SLEEP_ENABLE __HAL_RCC_SPI1_CLK_SLEEP_ENABLE +#define __SPI1_FORCE_RESET __HAL_RCC_SPI1_FORCE_RESET +#define __SPI1_RELEASE_RESET __HAL_RCC_SPI1_RELEASE_RESET +#define __SPI2_CLK_DISABLE __HAL_RCC_SPI2_CLK_DISABLE +#define __SPI2_CLK_ENABLE __HAL_RCC_SPI2_CLK_ENABLE +#define __SPI2_CLK_SLEEP_DISABLE __HAL_RCC_SPI2_CLK_SLEEP_DISABLE +#define __SPI2_CLK_SLEEP_ENABLE __HAL_RCC_SPI2_CLK_SLEEP_ENABLE +#define __SPI2_FORCE_RESET __HAL_RCC_SPI2_FORCE_RESET +#define __SPI2_RELEASE_RESET __HAL_RCC_SPI2_RELEASE_RESET +#define __SPI3_CLK_DISABLE __HAL_RCC_SPI3_CLK_DISABLE +#define __SPI3_CLK_ENABLE __HAL_RCC_SPI3_CLK_ENABLE +#define __SPI3_CLK_SLEEP_DISABLE __HAL_RCC_SPI3_CLK_SLEEP_DISABLE +#define __SPI3_CLK_SLEEP_ENABLE __HAL_RCC_SPI3_CLK_SLEEP_ENABLE +#define __SPI3_FORCE_RESET __HAL_RCC_SPI3_FORCE_RESET +#define __SPI3_RELEASE_RESET __HAL_RCC_SPI3_RELEASE_RESET +#define __SRAM_CLK_DISABLE __HAL_RCC_SRAM_CLK_DISABLE +#define __SRAM_CLK_ENABLE __HAL_RCC_SRAM_CLK_ENABLE +#define __SRAM1_CLK_SLEEP_DISABLE __HAL_RCC_SRAM1_CLK_SLEEP_DISABLE +#define __SRAM1_CLK_SLEEP_ENABLE __HAL_RCC_SRAM1_CLK_SLEEP_ENABLE +#define __SRAM2_CLK_SLEEP_DISABLE __HAL_RCC_SRAM2_CLK_SLEEP_DISABLE +#define __SRAM2_CLK_SLEEP_ENABLE __HAL_RCC_SRAM2_CLK_SLEEP_ENABLE +#define __SWPMI1_CLK_DISABLE __HAL_RCC_SWPMI1_CLK_DISABLE +#define __SWPMI1_CLK_ENABLE __HAL_RCC_SWPMI1_CLK_ENABLE +#define __SWPMI1_CLK_SLEEP_DISABLE __HAL_RCC_SWPMI1_CLK_SLEEP_DISABLE +#define __SWPMI1_CLK_SLEEP_ENABLE __HAL_RCC_SWPMI1_CLK_SLEEP_ENABLE +#define __SWPMI1_FORCE_RESET __HAL_RCC_SWPMI1_FORCE_RESET +#define __SWPMI1_RELEASE_RESET __HAL_RCC_SWPMI1_RELEASE_RESET +#define __SYSCFG_CLK_DISABLE __HAL_RCC_SYSCFG_CLK_DISABLE +#define __SYSCFG_CLK_ENABLE __HAL_RCC_SYSCFG_CLK_ENABLE +#define __SYSCFG_CLK_SLEEP_DISABLE __HAL_RCC_SYSCFG_CLK_SLEEP_DISABLE +#define __SYSCFG_CLK_SLEEP_ENABLE __HAL_RCC_SYSCFG_CLK_SLEEP_ENABLE +#define __SYSCFG_FORCE_RESET __HAL_RCC_SYSCFG_FORCE_RESET +#define __SYSCFG_RELEASE_RESET __HAL_RCC_SYSCFG_RELEASE_RESET +#define __TIM1_CLK_DISABLE __HAL_RCC_TIM1_CLK_DISABLE +#define __TIM1_CLK_ENABLE __HAL_RCC_TIM1_CLK_ENABLE +#define __TIM1_CLK_SLEEP_DISABLE __HAL_RCC_TIM1_CLK_SLEEP_DISABLE +#define __TIM1_CLK_SLEEP_ENABLE __HAL_RCC_TIM1_CLK_SLEEP_ENABLE +#define __TIM1_FORCE_RESET __HAL_RCC_TIM1_FORCE_RESET +#define __TIM1_RELEASE_RESET __HAL_RCC_TIM1_RELEASE_RESET +#define __TIM10_CLK_DISABLE __HAL_RCC_TIM10_CLK_DISABLE +#define __TIM10_CLK_ENABLE __HAL_RCC_TIM10_CLK_ENABLE +#define __TIM10_FORCE_RESET __HAL_RCC_TIM10_FORCE_RESET +#define __TIM10_RELEASE_RESET __HAL_RCC_TIM10_RELEASE_RESET +#define __TIM11_CLK_DISABLE __HAL_RCC_TIM11_CLK_DISABLE +#define __TIM11_CLK_ENABLE __HAL_RCC_TIM11_CLK_ENABLE +#define __TIM11_FORCE_RESET __HAL_RCC_TIM11_FORCE_RESET +#define __TIM11_RELEASE_RESET __HAL_RCC_TIM11_RELEASE_RESET +#define __TIM12_CLK_DISABLE __HAL_RCC_TIM12_CLK_DISABLE +#define __TIM12_CLK_ENABLE __HAL_RCC_TIM12_CLK_ENABLE +#define __TIM12_FORCE_RESET __HAL_RCC_TIM12_FORCE_RESET +#define __TIM12_RELEASE_RESET __HAL_RCC_TIM12_RELEASE_RESET +#define __TIM13_CLK_DISABLE __HAL_RCC_TIM13_CLK_DISABLE +#define __TIM13_CLK_ENABLE __HAL_RCC_TIM13_CLK_ENABLE +#define __TIM13_FORCE_RESET __HAL_RCC_TIM13_FORCE_RESET +#define __TIM13_RELEASE_RESET __HAL_RCC_TIM13_RELEASE_RESET +#define __TIM14_CLK_DISABLE __HAL_RCC_TIM14_CLK_DISABLE +#define __TIM14_CLK_ENABLE __HAL_RCC_TIM14_CLK_ENABLE +#define __TIM14_FORCE_RESET __HAL_RCC_TIM14_FORCE_RESET +#define __TIM14_RELEASE_RESET __HAL_RCC_TIM14_RELEASE_RESET +#define __TIM15_CLK_DISABLE __HAL_RCC_TIM15_CLK_DISABLE +#define __TIM15_CLK_ENABLE __HAL_RCC_TIM15_CLK_ENABLE +#define __TIM15_CLK_SLEEP_DISABLE __HAL_RCC_TIM15_CLK_SLEEP_DISABLE +#define __TIM15_CLK_SLEEP_ENABLE __HAL_RCC_TIM15_CLK_SLEEP_ENABLE +#define __TIM15_FORCE_RESET __HAL_RCC_TIM15_FORCE_RESET +#define __TIM15_RELEASE_RESET __HAL_RCC_TIM15_RELEASE_RESET +#define __TIM16_CLK_DISABLE __HAL_RCC_TIM16_CLK_DISABLE +#define __TIM16_CLK_ENABLE __HAL_RCC_TIM16_CLK_ENABLE +#define __TIM16_CLK_SLEEP_DISABLE __HAL_RCC_TIM16_CLK_SLEEP_DISABLE +#define __TIM16_CLK_SLEEP_ENABLE __HAL_RCC_TIM16_CLK_SLEEP_ENABLE +#define __TIM16_FORCE_RESET __HAL_RCC_TIM16_FORCE_RESET +#define __TIM16_RELEASE_RESET __HAL_RCC_TIM16_RELEASE_RESET +#define __TIM17_CLK_DISABLE __HAL_RCC_TIM17_CLK_DISABLE +#define __TIM17_CLK_ENABLE __HAL_RCC_TIM17_CLK_ENABLE +#define __TIM17_CLK_SLEEP_DISABLE __HAL_RCC_TIM17_CLK_SLEEP_DISABLE +#define __TIM17_CLK_SLEEP_ENABLE __HAL_RCC_TIM17_CLK_SLEEP_ENABLE +#define __TIM17_FORCE_RESET __HAL_RCC_TIM17_FORCE_RESET +#define __TIM17_RELEASE_RESET __HAL_RCC_TIM17_RELEASE_RESET +#define __TIM2_CLK_DISABLE __HAL_RCC_TIM2_CLK_DISABLE +#define __TIM2_CLK_ENABLE __HAL_RCC_TIM2_CLK_ENABLE +#define __TIM2_CLK_SLEEP_DISABLE __HAL_RCC_TIM2_CLK_SLEEP_DISABLE +#define __TIM2_CLK_SLEEP_ENABLE __HAL_RCC_TIM2_CLK_SLEEP_ENABLE +#define __TIM2_FORCE_RESET __HAL_RCC_TIM2_FORCE_RESET +#define __TIM2_RELEASE_RESET __HAL_RCC_TIM2_RELEASE_RESET +#define __TIM3_CLK_DISABLE __HAL_RCC_TIM3_CLK_DISABLE +#define __TIM3_CLK_ENABLE __HAL_RCC_TIM3_CLK_ENABLE +#define __TIM3_CLK_SLEEP_DISABLE __HAL_RCC_TIM3_CLK_SLEEP_DISABLE +#define __TIM3_CLK_SLEEP_ENABLE __HAL_RCC_TIM3_CLK_SLEEP_ENABLE +#define __TIM3_FORCE_RESET __HAL_RCC_TIM3_FORCE_RESET +#define __TIM3_RELEASE_RESET __HAL_RCC_TIM3_RELEASE_RESET +#define __TIM4_CLK_DISABLE __HAL_RCC_TIM4_CLK_DISABLE +#define __TIM4_CLK_ENABLE __HAL_RCC_TIM4_CLK_ENABLE +#define __TIM4_CLK_SLEEP_DISABLE __HAL_RCC_TIM4_CLK_SLEEP_DISABLE +#define __TIM4_CLK_SLEEP_ENABLE __HAL_RCC_TIM4_CLK_SLEEP_ENABLE +#define __TIM4_FORCE_RESET __HAL_RCC_TIM4_FORCE_RESET +#define __TIM4_RELEASE_RESET __HAL_RCC_TIM4_RELEASE_RESET +#define __TIM5_CLK_DISABLE __HAL_RCC_TIM5_CLK_DISABLE +#define __TIM5_CLK_ENABLE __HAL_RCC_TIM5_CLK_ENABLE +#define __TIM5_CLK_SLEEP_DISABLE __HAL_RCC_TIM5_CLK_SLEEP_DISABLE +#define __TIM5_CLK_SLEEP_ENABLE __HAL_RCC_TIM5_CLK_SLEEP_ENABLE +#define __TIM5_FORCE_RESET __HAL_RCC_TIM5_FORCE_RESET +#define __TIM5_RELEASE_RESET __HAL_RCC_TIM5_RELEASE_RESET +#define __TIM6_CLK_DISABLE __HAL_RCC_TIM6_CLK_DISABLE +#define __TIM6_CLK_ENABLE __HAL_RCC_TIM6_CLK_ENABLE +#define __TIM6_CLK_SLEEP_DISABLE __HAL_RCC_TIM6_CLK_SLEEP_DISABLE +#define __TIM6_CLK_SLEEP_ENABLE __HAL_RCC_TIM6_CLK_SLEEP_ENABLE +#define __TIM6_FORCE_RESET __HAL_RCC_TIM6_FORCE_RESET +#define __TIM6_RELEASE_RESET __HAL_RCC_TIM6_RELEASE_RESET +#define __TIM7_CLK_DISABLE __HAL_RCC_TIM7_CLK_DISABLE +#define __TIM7_CLK_ENABLE __HAL_RCC_TIM7_CLK_ENABLE +#define __TIM7_CLK_SLEEP_DISABLE __HAL_RCC_TIM7_CLK_SLEEP_DISABLE +#define __TIM7_CLK_SLEEP_ENABLE __HAL_RCC_TIM7_CLK_SLEEP_ENABLE +#define __TIM7_FORCE_RESET __HAL_RCC_TIM7_FORCE_RESET +#define __TIM7_RELEASE_RESET __HAL_RCC_TIM7_RELEASE_RESET +#define __TIM8_CLK_DISABLE __HAL_RCC_TIM8_CLK_DISABLE +#define __TIM8_CLK_ENABLE __HAL_RCC_TIM8_CLK_ENABLE +#define __TIM8_CLK_SLEEP_DISABLE __HAL_RCC_TIM8_CLK_SLEEP_DISABLE +#define __TIM8_CLK_SLEEP_ENABLE __HAL_RCC_TIM8_CLK_SLEEP_ENABLE +#define __TIM8_FORCE_RESET __HAL_RCC_TIM8_FORCE_RESET +#define __TIM8_RELEASE_RESET __HAL_RCC_TIM8_RELEASE_RESET +#define __TIM9_CLK_DISABLE __HAL_RCC_TIM9_CLK_DISABLE +#define __TIM9_CLK_ENABLE __HAL_RCC_TIM9_CLK_ENABLE +#define __TIM9_FORCE_RESET __HAL_RCC_TIM9_FORCE_RESET +#define __TIM9_RELEASE_RESET __HAL_RCC_TIM9_RELEASE_RESET +#define __TSC_CLK_DISABLE __HAL_RCC_TSC_CLK_DISABLE +#define __TSC_CLK_ENABLE __HAL_RCC_TSC_CLK_ENABLE +#define __TSC_CLK_SLEEP_DISABLE __HAL_RCC_TSC_CLK_SLEEP_DISABLE +#define __TSC_CLK_SLEEP_ENABLE __HAL_RCC_TSC_CLK_SLEEP_ENABLE +#define __TSC_FORCE_RESET __HAL_RCC_TSC_FORCE_RESET +#define __TSC_RELEASE_RESET __HAL_RCC_TSC_RELEASE_RESET +#define __UART4_CLK_DISABLE __HAL_RCC_UART4_CLK_DISABLE +#define __UART4_CLK_ENABLE __HAL_RCC_UART4_CLK_ENABLE +#define __UART4_CLK_SLEEP_DISABLE __HAL_RCC_UART4_CLK_SLEEP_DISABLE +#define __UART4_CLK_SLEEP_ENABLE __HAL_RCC_UART4_CLK_SLEEP_ENABLE +#define __UART4_FORCE_RESET __HAL_RCC_UART4_FORCE_RESET +#define __UART4_RELEASE_RESET __HAL_RCC_UART4_RELEASE_RESET +#define __UART5_CLK_DISABLE __HAL_RCC_UART5_CLK_DISABLE +#define __UART5_CLK_ENABLE __HAL_RCC_UART5_CLK_ENABLE +#define __UART5_CLK_SLEEP_DISABLE __HAL_RCC_UART5_CLK_SLEEP_DISABLE +#define __UART5_CLK_SLEEP_ENABLE __HAL_RCC_UART5_CLK_SLEEP_ENABLE +#define __UART5_FORCE_RESET __HAL_RCC_UART5_FORCE_RESET +#define __UART5_RELEASE_RESET __HAL_RCC_UART5_RELEASE_RESET +#define __USART1_CLK_DISABLE __HAL_RCC_USART1_CLK_DISABLE +#define __USART1_CLK_ENABLE __HAL_RCC_USART1_CLK_ENABLE +#define __USART1_CLK_SLEEP_DISABLE __HAL_RCC_USART1_CLK_SLEEP_DISABLE +#define __USART1_CLK_SLEEP_ENABLE __HAL_RCC_USART1_CLK_SLEEP_ENABLE +#define __USART1_FORCE_RESET __HAL_RCC_USART1_FORCE_RESET +#define __USART1_RELEASE_RESET __HAL_RCC_USART1_RELEASE_RESET +#define __USART2_CLK_DISABLE __HAL_RCC_USART2_CLK_DISABLE +#define __USART2_CLK_ENABLE __HAL_RCC_USART2_CLK_ENABLE +#define __USART2_CLK_SLEEP_DISABLE __HAL_RCC_USART2_CLK_SLEEP_DISABLE +#define __USART2_CLK_SLEEP_ENABLE __HAL_RCC_USART2_CLK_SLEEP_ENABLE +#define __USART2_FORCE_RESET __HAL_RCC_USART2_FORCE_RESET +#define __USART2_RELEASE_RESET __HAL_RCC_USART2_RELEASE_RESET +#define __USART3_CLK_DISABLE __HAL_RCC_USART3_CLK_DISABLE +#define __USART3_CLK_ENABLE __HAL_RCC_USART3_CLK_ENABLE +#define __USART3_CLK_SLEEP_DISABLE __HAL_RCC_USART3_CLK_SLEEP_DISABLE +#define __USART3_CLK_SLEEP_ENABLE __HAL_RCC_USART3_CLK_SLEEP_ENABLE +#define __USART3_FORCE_RESET __HAL_RCC_USART3_FORCE_RESET +#define __USART3_RELEASE_RESET __HAL_RCC_USART3_RELEASE_RESET +#define __USART4_CLK_DISABLE __HAL_RCC_UART4_CLK_DISABLE +#define __USART4_CLK_ENABLE __HAL_RCC_UART4_CLK_ENABLE +#define __USART4_CLK_SLEEP_ENABLE __HAL_RCC_UART4_CLK_SLEEP_ENABLE +#define __USART4_CLK_SLEEP_DISABLE __HAL_RCC_UART4_CLK_SLEEP_DISABLE +#define __USART4_FORCE_RESET __HAL_RCC_UART4_FORCE_RESET +#define __USART4_RELEASE_RESET __HAL_RCC_UART4_RELEASE_RESET +#define __USART5_CLK_DISABLE __HAL_RCC_UART5_CLK_DISABLE +#define __USART5_CLK_ENABLE __HAL_RCC_UART5_CLK_ENABLE +#define __USART5_CLK_SLEEP_ENABLE __HAL_RCC_UART5_CLK_SLEEP_ENABLE +#define __USART5_CLK_SLEEP_DISABLE __HAL_RCC_UART5_CLK_SLEEP_DISABLE +#define __USART5_FORCE_RESET __HAL_RCC_UART5_FORCE_RESET +#define __USART5_RELEASE_RESET __HAL_RCC_UART5_RELEASE_RESET +#define __USART7_CLK_DISABLE __HAL_RCC_UART7_CLK_DISABLE +#define __USART7_CLK_ENABLE __HAL_RCC_UART7_CLK_ENABLE +#define __USART7_FORCE_RESET __HAL_RCC_UART7_FORCE_RESET +#define __USART7_RELEASE_RESET __HAL_RCC_UART7_RELEASE_RESET +#define __USART8_CLK_DISABLE __HAL_RCC_UART8_CLK_DISABLE +#define __USART8_CLK_ENABLE __HAL_RCC_UART8_CLK_ENABLE +#define __USART8_FORCE_RESET __HAL_RCC_UART8_FORCE_RESET +#define __USART8_RELEASE_RESET __HAL_RCC_UART8_RELEASE_RESET +#define __USB_CLK_DISABLE __HAL_RCC_USB_CLK_DISABLE +#define __USB_CLK_ENABLE __HAL_RCC_USB_CLK_ENABLE +#define __USB_FORCE_RESET __HAL_RCC_USB_FORCE_RESET +#define __USB_CLK_SLEEP_ENABLE __HAL_RCC_USB_CLK_SLEEP_ENABLE +#define __USB_CLK_SLEEP_DISABLE __HAL_RCC_USB_CLK_SLEEP_DISABLE +#define __USB_OTG_FS_CLK_DISABLE __HAL_RCC_USB_OTG_FS_CLK_DISABLE +#define __USB_OTG_FS_CLK_ENABLE __HAL_RCC_USB_OTG_FS_CLK_ENABLE +#define __USB_RELEASE_RESET __HAL_RCC_USB_RELEASE_RESET + +#if defined(STM32H7) +#define __HAL_RCC_WWDG_CLK_DISABLE __HAL_RCC_WWDG1_CLK_DISABLE +#define __HAL_RCC_WWDG_CLK_ENABLE __HAL_RCC_WWDG1_CLK_ENABLE +#define __HAL_RCC_WWDG_CLK_SLEEP_DISABLE __HAL_RCC_WWDG1_CLK_SLEEP_DISABLE +#define __HAL_RCC_WWDG_CLK_SLEEP_ENABLE __HAL_RCC_WWDG1_CLK_SLEEP_ENABLE + +#define __HAL_RCC_WWDG_FORCE_RESET ((void)0U) /* Not available on the STM32H7*/ +#define __HAL_RCC_WWDG_RELEASE_RESET ((void)0U) /* Not available on the STM32H7*/ + + +#define __HAL_RCC_WWDG_IS_CLK_ENABLED __HAL_RCC_WWDG1_IS_CLK_ENABLED +#define __HAL_RCC_WWDG_IS_CLK_DISABLED __HAL_RCC_WWDG1_IS_CLK_DISABLED +#define RCC_SPI4CLKSOURCE_D2PCLK1 RCC_SPI4CLKSOURCE_D2PCLK2 +#define RCC_SPI5CLKSOURCE_D2PCLK1 RCC_SPI5CLKSOURCE_D2PCLK2 +#define RCC_SPI45CLKSOURCE_D2PCLK1 RCC_SPI45CLKSOURCE_D2PCLK2 +#define RCC_SPI45CLKSOURCE_CDPCLK1 RCC_SPI45CLKSOURCE_CDPCLK2 +#define RCC_SPI45CLKSOURCE_PCLK1 RCC_SPI45CLKSOURCE_PCLK2 +#endif + +#define __WWDG_CLK_DISABLE __HAL_RCC_WWDG_CLK_DISABLE +#define __WWDG_CLK_ENABLE __HAL_RCC_WWDG_CLK_ENABLE +#define __WWDG_CLK_SLEEP_DISABLE __HAL_RCC_WWDG_CLK_SLEEP_DISABLE +#define __WWDG_CLK_SLEEP_ENABLE __HAL_RCC_WWDG_CLK_SLEEP_ENABLE +#define __WWDG_FORCE_RESET __HAL_RCC_WWDG_FORCE_RESET +#define __WWDG_RELEASE_RESET __HAL_RCC_WWDG_RELEASE_RESET + +#define __TIM21_CLK_ENABLE __HAL_RCC_TIM21_CLK_ENABLE +#define __TIM21_CLK_DISABLE __HAL_RCC_TIM21_CLK_DISABLE +#define __TIM21_FORCE_RESET __HAL_RCC_TIM21_FORCE_RESET +#define __TIM21_RELEASE_RESET __HAL_RCC_TIM21_RELEASE_RESET +#define __TIM21_CLK_SLEEP_ENABLE __HAL_RCC_TIM21_CLK_SLEEP_ENABLE +#define __TIM21_CLK_SLEEP_DISABLE __HAL_RCC_TIM21_CLK_SLEEP_DISABLE +#define __TIM22_CLK_ENABLE __HAL_RCC_TIM22_CLK_ENABLE +#define __TIM22_CLK_DISABLE __HAL_RCC_TIM22_CLK_DISABLE +#define __TIM22_FORCE_RESET __HAL_RCC_TIM22_FORCE_RESET +#define __TIM22_RELEASE_RESET __HAL_RCC_TIM22_RELEASE_RESET +#define __TIM22_CLK_SLEEP_ENABLE __HAL_RCC_TIM22_CLK_SLEEP_ENABLE +#define __TIM22_CLK_SLEEP_DISABLE __HAL_RCC_TIM22_CLK_SLEEP_DISABLE +#define __CRS_CLK_DISABLE __HAL_RCC_CRS_CLK_DISABLE +#define __CRS_CLK_ENABLE __HAL_RCC_CRS_CLK_ENABLE +#define __CRS_CLK_SLEEP_DISABLE __HAL_RCC_CRS_CLK_SLEEP_DISABLE +#define __CRS_CLK_SLEEP_ENABLE __HAL_RCC_CRS_CLK_SLEEP_ENABLE +#define __CRS_FORCE_RESET __HAL_RCC_CRS_FORCE_RESET +#define __CRS_RELEASE_RESET __HAL_RCC_CRS_RELEASE_RESET +#define __RCC_BACKUPRESET_FORCE __HAL_RCC_BACKUPRESET_FORCE +#define __RCC_BACKUPRESET_RELEASE __HAL_RCC_BACKUPRESET_RELEASE + +#define __USB_OTG_FS_FORCE_RESET __HAL_RCC_USB_OTG_FS_FORCE_RESET +#define __USB_OTG_FS_RELEASE_RESET __HAL_RCC_USB_OTG_FS_RELEASE_RESET +#define __USB_OTG_FS_CLK_SLEEP_ENABLE __HAL_RCC_USB_OTG_FS_CLK_SLEEP_ENABLE +#define __USB_OTG_FS_CLK_SLEEP_DISABLE __HAL_RCC_USB_OTG_FS_CLK_SLEEP_DISABLE +#define __USB_OTG_HS_CLK_DISABLE __HAL_RCC_USB_OTG_HS_CLK_DISABLE +#define __USB_OTG_HS_CLK_ENABLE __HAL_RCC_USB_OTG_HS_CLK_ENABLE +#define __USB_OTG_HS_ULPI_CLK_ENABLE __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE +#define __USB_OTG_HS_ULPI_CLK_DISABLE __HAL_RCC_USB_OTG_HS_ULPI_CLK_DISABLE +#define __TIM9_CLK_SLEEP_ENABLE __HAL_RCC_TIM9_CLK_SLEEP_ENABLE +#define __TIM9_CLK_SLEEP_DISABLE __HAL_RCC_TIM9_CLK_SLEEP_DISABLE +#define __TIM10_CLK_SLEEP_ENABLE __HAL_RCC_TIM10_CLK_SLEEP_ENABLE +#define __TIM10_CLK_SLEEP_DISABLE __HAL_RCC_TIM10_CLK_SLEEP_DISABLE +#define __TIM11_CLK_SLEEP_ENABLE __HAL_RCC_TIM11_CLK_SLEEP_ENABLE +#define __TIM11_CLK_SLEEP_DISABLE __HAL_RCC_TIM11_CLK_SLEEP_DISABLE +#define __ETHMACPTP_CLK_SLEEP_ENABLE __HAL_RCC_ETHMACPTP_CLK_SLEEP_ENABLE +#define __ETHMACPTP_CLK_SLEEP_DISABLE __HAL_RCC_ETHMACPTP_CLK_SLEEP_DISABLE +#define __ETHMACPTP_CLK_ENABLE __HAL_RCC_ETHMACPTP_CLK_ENABLE +#define __ETHMACPTP_CLK_DISABLE __HAL_RCC_ETHMACPTP_CLK_DISABLE +#define __HASH_CLK_ENABLE __HAL_RCC_HASH_CLK_ENABLE +#define __HASH_FORCE_RESET __HAL_RCC_HASH_FORCE_RESET +#define __HASH_RELEASE_RESET __HAL_RCC_HASH_RELEASE_RESET +#define __HASH_CLK_SLEEP_ENABLE __HAL_RCC_HASH_CLK_SLEEP_ENABLE +#define __HASH_CLK_SLEEP_DISABLE __HAL_RCC_HASH_CLK_SLEEP_DISABLE +#define __HASH_CLK_DISABLE __HAL_RCC_HASH_CLK_DISABLE +#define __SPI5_CLK_ENABLE __HAL_RCC_SPI5_CLK_ENABLE +#define __SPI5_CLK_DISABLE __HAL_RCC_SPI5_CLK_DISABLE +#define __SPI5_FORCE_RESET __HAL_RCC_SPI5_FORCE_RESET +#define __SPI5_RELEASE_RESET __HAL_RCC_SPI5_RELEASE_RESET +#define __SPI5_CLK_SLEEP_ENABLE __HAL_RCC_SPI5_CLK_SLEEP_ENABLE +#define __SPI5_CLK_SLEEP_DISABLE __HAL_RCC_SPI5_CLK_SLEEP_DISABLE +#define __SPI6_CLK_ENABLE __HAL_RCC_SPI6_CLK_ENABLE +#define __SPI6_CLK_DISABLE __HAL_RCC_SPI6_CLK_DISABLE +#define __SPI6_FORCE_RESET __HAL_RCC_SPI6_FORCE_RESET +#define __SPI6_RELEASE_RESET __HAL_RCC_SPI6_RELEASE_RESET +#define __SPI6_CLK_SLEEP_ENABLE __HAL_RCC_SPI6_CLK_SLEEP_ENABLE +#define __SPI6_CLK_SLEEP_DISABLE __HAL_RCC_SPI6_CLK_SLEEP_DISABLE +#define __LTDC_CLK_ENABLE __HAL_RCC_LTDC_CLK_ENABLE +#define __LTDC_CLK_DISABLE __HAL_RCC_LTDC_CLK_DISABLE +#define __LTDC_FORCE_RESET __HAL_RCC_LTDC_FORCE_RESET +#define __LTDC_RELEASE_RESET __HAL_RCC_LTDC_RELEASE_RESET +#define __LTDC_CLK_SLEEP_ENABLE __HAL_RCC_LTDC_CLK_SLEEP_ENABLE +#define __ETHMAC_CLK_SLEEP_ENABLE __HAL_RCC_ETHMAC_CLK_SLEEP_ENABLE +#define __ETHMAC_CLK_SLEEP_DISABLE __HAL_RCC_ETHMAC_CLK_SLEEP_DISABLE +#define __ETHMACTX_CLK_SLEEP_ENABLE __HAL_RCC_ETHMACTX_CLK_SLEEP_ENABLE +#define __ETHMACTX_CLK_SLEEP_DISABLE __HAL_RCC_ETHMACTX_CLK_SLEEP_DISABLE +#define __ETHMACRX_CLK_SLEEP_ENABLE __HAL_RCC_ETHMACRX_CLK_SLEEP_ENABLE +#define __ETHMACRX_CLK_SLEEP_DISABLE __HAL_RCC_ETHMACRX_CLK_SLEEP_DISABLE +#define __TIM12_CLK_SLEEP_ENABLE __HAL_RCC_TIM12_CLK_SLEEP_ENABLE +#define __TIM12_CLK_SLEEP_DISABLE __HAL_RCC_TIM12_CLK_SLEEP_DISABLE +#define __TIM13_CLK_SLEEP_ENABLE __HAL_RCC_TIM13_CLK_SLEEP_ENABLE +#define __TIM13_CLK_SLEEP_DISABLE __HAL_RCC_TIM13_CLK_SLEEP_DISABLE +#define __TIM14_CLK_SLEEP_ENABLE __HAL_RCC_TIM14_CLK_SLEEP_ENABLE +#define __TIM14_CLK_SLEEP_DISABLE __HAL_RCC_TIM14_CLK_SLEEP_DISABLE +#define __BKPSRAM_CLK_ENABLE __HAL_RCC_BKPSRAM_CLK_ENABLE +#define __BKPSRAM_CLK_DISABLE __HAL_RCC_BKPSRAM_CLK_DISABLE +#define __BKPSRAM_CLK_SLEEP_ENABLE __HAL_RCC_BKPSRAM_CLK_SLEEP_ENABLE +#define __BKPSRAM_CLK_SLEEP_DISABLE __HAL_RCC_BKPSRAM_CLK_SLEEP_DISABLE +#define __CCMDATARAMEN_CLK_ENABLE __HAL_RCC_CCMDATARAMEN_CLK_ENABLE +#define __CCMDATARAMEN_CLK_DISABLE __HAL_RCC_CCMDATARAMEN_CLK_DISABLE +#define __USART6_CLK_ENABLE __HAL_RCC_USART6_CLK_ENABLE +#define __USART6_CLK_DISABLE __HAL_RCC_USART6_CLK_DISABLE +#define __USART6_FORCE_RESET __HAL_RCC_USART6_FORCE_RESET +#define __USART6_RELEASE_RESET __HAL_RCC_USART6_RELEASE_RESET +#define __USART6_CLK_SLEEP_ENABLE __HAL_RCC_USART6_CLK_SLEEP_ENABLE +#define __USART6_CLK_SLEEP_DISABLE __HAL_RCC_USART6_CLK_SLEEP_DISABLE +#define __SPI4_CLK_ENABLE __HAL_RCC_SPI4_CLK_ENABLE +#define __SPI4_CLK_DISABLE __HAL_RCC_SPI4_CLK_DISABLE +#define __SPI4_FORCE_RESET __HAL_RCC_SPI4_FORCE_RESET +#define __SPI4_RELEASE_RESET __HAL_RCC_SPI4_RELEASE_RESET +#define __SPI4_CLK_SLEEP_ENABLE __HAL_RCC_SPI4_CLK_SLEEP_ENABLE +#define __SPI4_CLK_SLEEP_DISABLE __HAL_RCC_SPI4_CLK_SLEEP_DISABLE +#define __GPIOI_CLK_ENABLE __HAL_RCC_GPIOI_CLK_ENABLE +#define __GPIOI_CLK_DISABLE __HAL_RCC_GPIOI_CLK_DISABLE +#define __GPIOI_FORCE_RESET __HAL_RCC_GPIOI_FORCE_RESET +#define __GPIOI_RELEASE_RESET __HAL_RCC_GPIOI_RELEASE_RESET +#define __GPIOI_CLK_SLEEP_ENABLE __HAL_RCC_GPIOI_CLK_SLEEP_ENABLE +#define __GPIOI_CLK_SLEEP_DISABLE __HAL_RCC_GPIOI_CLK_SLEEP_DISABLE +#define __GPIOJ_CLK_ENABLE __HAL_RCC_GPIOJ_CLK_ENABLE +#define __GPIOJ_CLK_DISABLE __HAL_RCC_GPIOJ_CLK_DISABLE +#define __GPIOJ_FORCE_RESET __HAL_RCC_GPIOJ_FORCE_RESET +#define __GPIOJ_RELEASE_RESET __HAL_RCC_GPIOJ_RELEASE_RESET +#define __GPIOJ_CLK_SLEEP_ENABLE __HAL_RCC_GPIOJ_CLK_SLEEP_ENABLE +#define __GPIOJ_CLK_SLEEP_DISABLE __HAL_RCC_GPIOJ_CLK_SLEEP_DISABLE +#define __GPIOK_CLK_ENABLE __HAL_RCC_GPIOK_CLK_ENABLE +#define __GPIOK_CLK_DISABLE __HAL_RCC_GPIOK_CLK_DISABLE +#define __GPIOK_RELEASE_RESET __HAL_RCC_GPIOK_RELEASE_RESET +#define __GPIOK_CLK_SLEEP_ENABLE __HAL_RCC_GPIOK_CLK_SLEEP_ENABLE +#define __GPIOK_CLK_SLEEP_DISABLE __HAL_RCC_GPIOK_CLK_SLEEP_DISABLE +#define __ETH_CLK_ENABLE __HAL_RCC_ETH_CLK_ENABLE +#define __ETH_CLK_DISABLE __HAL_RCC_ETH_CLK_DISABLE +#define __DCMI_CLK_ENABLE __HAL_RCC_DCMI_CLK_ENABLE +#define __DCMI_CLK_DISABLE __HAL_RCC_DCMI_CLK_DISABLE +#define __DCMI_FORCE_RESET __HAL_RCC_DCMI_FORCE_RESET +#define __DCMI_RELEASE_RESET __HAL_RCC_DCMI_RELEASE_RESET +#define __DCMI_CLK_SLEEP_ENABLE __HAL_RCC_DCMI_CLK_SLEEP_ENABLE +#define __DCMI_CLK_SLEEP_DISABLE __HAL_RCC_DCMI_CLK_SLEEP_DISABLE +#define __UART7_CLK_ENABLE __HAL_RCC_UART7_CLK_ENABLE +#define __UART7_CLK_DISABLE __HAL_RCC_UART7_CLK_DISABLE +#define __UART7_RELEASE_RESET __HAL_RCC_UART7_RELEASE_RESET +#define __UART7_FORCE_RESET __HAL_RCC_UART7_FORCE_RESET +#define __UART7_CLK_SLEEP_ENABLE __HAL_RCC_UART7_CLK_SLEEP_ENABLE +#define __UART7_CLK_SLEEP_DISABLE __HAL_RCC_UART7_CLK_SLEEP_DISABLE +#define __UART8_CLK_ENABLE __HAL_RCC_UART8_CLK_ENABLE +#define __UART8_CLK_DISABLE __HAL_RCC_UART8_CLK_DISABLE +#define __UART8_FORCE_RESET __HAL_RCC_UART8_FORCE_RESET +#define __UART8_RELEASE_RESET __HAL_RCC_UART8_RELEASE_RESET +#define __UART8_CLK_SLEEP_ENABLE __HAL_RCC_UART8_CLK_SLEEP_ENABLE +#define __UART8_CLK_SLEEP_DISABLE __HAL_RCC_UART8_CLK_SLEEP_DISABLE +#define __OTGHS_CLK_SLEEP_ENABLE __HAL_RCC_USB_OTG_HS_CLK_SLEEP_ENABLE +#define __OTGHS_CLK_SLEEP_DISABLE __HAL_RCC_USB_OTG_HS_CLK_SLEEP_DISABLE +#define __OTGHS_FORCE_RESET __HAL_RCC_USB_OTG_HS_FORCE_RESET +#define __OTGHS_RELEASE_RESET __HAL_RCC_USB_OTG_HS_RELEASE_RESET +#define __OTGHSULPI_CLK_SLEEP_ENABLE __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_ENABLE +#define __OTGHSULPI_CLK_SLEEP_DISABLE __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_DISABLE +#define __HAL_RCC_OTGHS_CLK_SLEEP_ENABLE __HAL_RCC_USB_OTG_HS_CLK_SLEEP_ENABLE +#define __HAL_RCC_OTGHS_CLK_SLEEP_DISABLE __HAL_RCC_USB_OTG_HS_CLK_SLEEP_DISABLE +#define __HAL_RCC_OTGHS_IS_CLK_SLEEP_ENABLED __HAL_RCC_USB_OTG_HS_IS_CLK_SLEEP_ENABLED +#define __HAL_RCC_OTGHS_IS_CLK_SLEEP_DISABLED __HAL_RCC_USB_OTG_HS_IS_CLK_SLEEP_DISABLED +#define __HAL_RCC_OTGHS_FORCE_RESET __HAL_RCC_USB_OTG_HS_FORCE_RESET +#define __HAL_RCC_OTGHS_RELEASE_RESET __HAL_RCC_USB_OTG_HS_RELEASE_RESET +#define __HAL_RCC_OTGHSULPI_CLK_SLEEP_ENABLE __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_ENABLE +#define __HAL_RCC_OTGHSULPI_CLK_SLEEP_DISABLE __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_DISABLE +#define __HAL_RCC_OTGHSULPI_IS_CLK_SLEEP_ENABLED __HAL_RCC_USB_OTG_HS_ULPI_IS_CLK_SLEEP_ENABLED +#define __HAL_RCC_OTGHSULPI_IS_CLK_SLEEP_DISABLED __HAL_RCC_USB_OTG_HS_ULPI_IS_CLK_SLEEP_DISABLED +#define __SRAM3_CLK_SLEEP_ENABLE __HAL_RCC_SRAM3_CLK_SLEEP_ENABLE +#define __CAN2_CLK_SLEEP_ENABLE __HAL_RCC_CAN2_CLK_SLEEP_ENABLE +#define __CAN2_CLK_SLEEP_DISABLE __HAL_RCC_CAN2_CLK_SLEEP_DISABLE +#define __DAC_CLK_SLEEP_ENABLE __HAL_RCC_DAC_CLK_SLEEP_ENABLE +#define __DAC_CLK_SLEEP_DISABLE __HAL_RCC_DAC_CLK_SLEEP_DISABLE +#define __ADC2_CLK_SLEEP_ENABLE __HAL_RCC_ADC2_CLK_SLEEP_ENABLE +#define __ADC2_CLK_SLEEP_DISABLE __HAL_RCC_ADC2_CLK_SLEEP_DISABLE +#define __ADC3_CLK_SLEEP_ENABLE __HAL_RCC_ADC3_CLK_SLEEP_ENABLE +#define __ADC3_CLK_SLEEP_DISABLE __HAL_RCC_ADC3_CLK_SLEEP_DISABLE +#define __FSMC_FORCE_RESET __HAL_RCC_FSMC_FORCE_RESET +#define __FSMC_RELEASE_RESET __HAL_RCC_FSMC_RELEASE_RESET +#define __FSMC_CLK_SLEEP_ENABLE __HAL_RCC_FSMC_CLK_SLEEP_ENABLE +#define __FSMC_CLK_SLEEP_DISABLE __HAL_RCC_FSMC_CLK_SLEEP_DISABLE +#define __SDIO_FORCE_RESET __HAL_RCC_SDIO_FORCE_RESET +#define __SDIO_RELEASE_RESET __HAL_RCC_SDIO_RELEASE_RESET +#define __SDIO_CLK_SLEEP_DISABLE __HAL_RCC_SDIO_CLK_SLEEP_DISABLE +#define __SDIO_CLK_SLEEP_ENABLE __HAL_RCC_SDIO_CLK_SLEEP_ENABLE +#define __DMA2D_CLK_ENABLE __HAL_RCC_DMA2D_CLK_ENABLE +#define __DMA2D_CLK_DISABLE __HAL_RCC_DMA2D_CLK_DISABLE +#define __DMA2D_FORCE_RESET __HAL_RCC_DMA2D_FORCE_RESET +#define __DMA2D_RELEASE_RESET __HAL_RCC_DMA2D_RELEASE_RESET +#define __DMA2D_CLK_SLEEP_ENABLE __HAL_RCC_DMA2D_CLK_SLEEP_ENABLE +#define __DMA2D_CLK_SLEEP_DISABLE __HAL_RCC_DMA2D_CLK_SLEEP_DISABLE + +/* alias define maintained for legacy */ +#define __HAL_RCC_OTGFS_FORCE_RESET __HAL_RCC_USB_OTG_FS_FORCE_RESET +#define __HAL_RCC_OTGFS_RELEASE_RESET __HAL_RCC_USB_OTG_FS_RELEASE_RESET + +#define __ADC12_CLK_ENABLE __HAL_RCC_ADC12_CLK_ENABLE +#define __ADC12_CLK_DISABLE __HAL_RCC_ADC12_CLK_DISABLE +#define __ADC34_CLK_ENABLE __HAL_RCC_ADC34_CLK_ENABLE +#define __ADC34_CLK_DISABLE __HAL_RCC_ADC34_CLK_DISABLE +#define __DAC2_CLK_ENABLE __HAL_RCC_DAC2_CLK_ENABLE +#define __DAC2_CLK_DISABLE __HAL_RCC_DAC2_CLK_DISABLE +#define __TIM18_CLK_ENABLE __HAL_RCC_TIM18_CLK_ENABLE +#define __TIM18_CLK_DISABLE __HAL_RCC_TIM18_CLK_DISABLE +#define __TIM19_CLK_ENABLE __HAL_RCC_TIM19_CLK_ENABLE +#define __TIM19_CLK_DISABLE __HAL_RCC_TIM19_CLK_DISABLE +#define __TIM20_CLK_ENABLE __HAL_RCC_TIM20_CLK_ENABLE +#define __TIM20_CLK_DISABLE __HAL_RCC_TIM20_CLK_DISABLE +#define __HRTIM1_CLK_ENABLE __HAL_RCC_HRTIM1_CLK_ENABLE +#define __HRTIM1_CLK_DISABLE __HAL_RCC_HRTIM1_CLK_DISABLE +#define __SDADC1_CLK_ENABLE __HAL_RCC_SDADC1_CLK_ENABLE +#define __SDADC2_CLK_ENABLE __HAL_RCC_SDADC2_CLK_ENABLE +#define __SDADC3_CLK_ENABLE __HAL_RCC_SDADC3_CLK_ENABLE +#define __SDADC1_CLK_DISABLE __HAL_RCC_SDADC1_CLK_DISABLE +#define __SDADC2_CLK_DISABLE __HAL_RCC_SDADC2_CLK_DISABLE +#define __SDADC3_CLK_DISABLE __HAL_RCC_SDADC3_CLK_DISABLE + +#define __ADC12_FORCE_RESET __HAL_RCC_ADC12_FORCE_RESET +#define __ADC12_RELEASE_RESET __HAL_RCC_ADC12_RELEASE_RESET +#define __ADC34_FORCE_RESET __HAL_RCC_ADC34_FORCE_RESET +#define __ADC34_RELEASE_RESET __HAL_RCC_ADC34_RELEASE_RESET +#define __DAC2_FORCE_RESET __HAL_RCC_DAC2_FORCE_RESET +#define __DAC2_RELEASE_RESET __HAL_RCC_DAC2_RELEASE_RESET +#define __TIM18_FORCE_RESET __HAL_RCC_TIM18_FORCE_RESET +#define __TIM18_RELEASE_RESET __HAL_RCC_TIM18_RELEASE_RESET +#define __TIM19_FORCE_RESET __HAL_RCC_TIM19_FORCE_RESET +#define __TIM19_RELEASE_RESET __HAL_RCC_TIM19_RELEASE_RESET +#define __TIM20_FORCE_RESET __HAL_RCC_TIM20_FORCE_RESET +#define __TIM20_RELEASE_RESET __HAL_RCC_TIM20_RELEASE_RESET +#define __HRTIM1_FORCE_RESET __HAL_RCC_HRTIM1_FORCE_RESET +#define __HRTIM1_RELEASE_RESET __HAL_RCC_HRTIM1_RELEASE_RESET +#define __SDADC1_FORCE_RESET __HAL_RCC_SDADC1_FORCE_RESET +#define __SDADC2_FORCE_RESET __HAL_RCC_SDADC2_FORCE_RESET +#define __SDADC3_FORCE_RESET __HAL_RCC_SDADC3_FORCE_RESET +#define __SDADC1_RELEASE_RESET __HAL_RCC_SDADC1_RELEASE_RESET +#define __SDADC2_RELEASE_RESET __HAL_RCC_SDADC2_RELEASE_RESET +#define __SDADC3_RELEASE_RESET __HAL_RCC_SDADC3_RELEASE_RESET + +#define __ADC1_IS_CLK_ENABLED __HAL_RCC_ADC1_IS_CLK_ENABLED +#define __ADC1_IS_CLK_DISABLED __HAL_RCC_ADC1_IS_CLK_DISABLED +#define __ADC12_IS_CLK_ENABLED __HAL_RCC_ADC12_IS_CLK_ENABLED +#define __ADC12_IS_CLK_DISABLED __HAL_RCC_ADC12_IS_CLK_DISABLED +#define __ADC34_IS_CLK_ENABLED __HAL_RCC_ADC34_IS_CLK_ENABLED +#define __ADC34_IS_CLK_DISABLED __HAL_RCC_ADC34_IS_CLK_DISABLED +#define __CEC_IS_CLK_ENABLED __HAL_RCC_CEC_IS_CLK_ENABLED +#define __CEC_IS_CLK_DISABLED __HAL_RCC_CEC_IS_CLK_DISABLED +#define __CRC_IS_CLK_ENABLED __HAL_RCC_CRC_IS_CLK_ENABLED +#define __CRC_IS_CLK_DISABLED __HAL_RCC_CRC_IS_CLK_DISABLED +#define __DAC1_IS_CLK_ENABLED __HAL_RCC_DAC1_IS_CLK_ENABLED +#define __DAC1_IS_CLK_DISABLED __HAL_RCC_DAC1_IS_CLK_DISABLED +#define __DAC2_IS_CLK_ENABLED __HAL_RCC_DAC2_IS_CLK_ENABLED +#define __DAC2_IS_CLK_DISABLED __HAL_RCC_DAC2_IS_CLK_DISABLED +#define __DMA1_IS_CLK_ENABLED __HAL_RCC_DMA1_IS_CLK_ENABLED +#define __DMA1_IS_CLK_DISABLED __HAL_RCC_DMA1_IS_CLK_DISABLED +#define __DMA2_IS_CLK_ENABLED __HAL_RCC_DMA2_IS_CLK_ENABLED +#define __DMA2_IS_CLK_DISABLED __HAL_RCC_DMA2_IS_CLK_DISABLED +#define __FLITF_IS_CLK_ENABLED __HAL_RCC_FLITF_IS_CLK_ENABLED +#define __FLITF_IS_CLK_DISABLED __HAL_RCC_FLITF_IS_CLK_DISABLED +#define __FMC_IS_CLK_ENABLED __HAL_RCC_FMC_IS_CLK_ENABLED +#define __FMC_IS_CLK_DISABLED __HAL_RCC_FMC_IS_CLK_DISABLED +#define __GPIOA_IS_CLK_ENABLED __HAL_RCC_GPIOA_IS_CLK_ENABLED +#define __GPIOA_IS_CLK_DISABLED __HAL_RCC_GPIOA_IS_CLK_DISABLED +#define __GPIOB_IS_CLK_ENABLED __HAL_RCC_GPIOB_IS_CLK_ENABLED +#define __GPIOB_IS_CLK_DISABLED __HAL_RCC_GPIOB_IS_CLK_DISABLED +#define __GPIOC_IS_CLK_ENABLED __HAL_RCC_GPIOC_IS_CLK_ENABLED +#define __GPIOC_IS_CLK_DISABLED __HAL_RCC_GPIOC_IS_CLK_DISABLED +#define __GPIOD_IS_CLK_ENABLED __HAL_RCC_GPIOD_IS_CLK_ENABLED +#define __GPIOD_IS_CLK_DISABLED __HAL_RCC_GPIOD_IS_CLK_DISABLED +#define __GPIOE_IS_CLK_ENABLED __HAL_RCC_GPIOE_IS_CLK_ENABLED +#define __GPIOE_IS_CLK_DISABLED __HAL_RCC_GPIOE_IS_CLK_DISABLED +#define __GPIOF_IS_CLK_ENABLED __HAL_RCC_GPIOF_IS_CLK_ENABLED +#define __GPIOF_IS_CLK_DISABLED __HAL_RCC_GPIOF_IS_CLK_DISABLED +#define __GPIOG_IS_CLK_ENABLED __HAL_RCC_GPIOG_IS_CLK_ENABLED +#define __GPIOG_IS_CLK_DISABLED __HAL_RCC_GPIOG_IS_CLK_DISABLED +#define __GPIOH_IS_CLK_ENABLED __HAL_RCC_GPIOH_IS_CLK_ENABLED +#define __GPIOH_IS_CLK_DISABLED __HAL_RCC_GPIOH_IS_CLK_DISABLED +#define __HRTIM1_IS_CLK_ENABLED __HAL_RCC_HRTIM1_IS_CLK_ENABLED +#define __HRTIM1_IS_CLK_DISABLED __HAL_RCC_HRTIM1_IS_CLK_DISABLED +#define __I2C1_IS_CLK_ENABLED __HAL_RCC_I2C1_IS_CLK_ENABLED +#define __I2C1_IS_CLK_DISABLED __HAL_RCC_I2C1_IS_CLK_DISABLED +#define __I2C2_IS_CLK_ENABLED __HAL_RCC_I2C2_IS_CLK_ENABLED +#define __I2C2_IS_CLK_DISABLED __HAL_RCC_I2C2_IS_CLK_DISABLED +#define __I2C3_IS_CLK_ENABLED __HAL_RCC_I2C3_IS_CLK_ENABLED +#define __I2C3_IS_CLK_DISABLED __HAL_RCC_I2C3_IS_CLK_DISABLED +#define __PWR_IS_CLK_ENABLED __HAL_RCC_PWR_IS_CLK_ENABLED +#define __PWR_IS_CLK_DISABLED __HAL_RCC_PWR_IS_CLK_DISABLED +#define __SYSCFG_IS_CLK_ENABLED __HAL_RCC_SYSCFG_IS_CLK_ENABLED +#define __SYSCFG_IS_CLK_DISABLED __HAL_RCC_SYSCFG_IS_CLK_DISABLED +#define __SPI1_IS_CLK_ENABLED __HAL_RCC_SPI1_IS_CLK_ENABLED +#define __SPI1_IS_CLK_DISABLED __HAL_RCC_SPI1_IS_CLK_DISABLED +#define __SPI2_IS_CLK_ENABLED __HAL_RCC_SPI2_IS_CLK_ENABLED +#define __SPI2_IS_CLK_DISABLED __HAL_RCC_SPI2_IS_CLK_DISABLED +#define __SPI3_IS_CLK_ENABLED __HAL_RCC_SPI3_IS_CLK_ENABLED +#define __SPI3_IS_CLK_DISABLED __HAL_RCC_SPI3_IS_CLK_DISABLED +#define __SPI4_IS_CLK_ENABLED __HAL_RCC_SPI4_IS_CLK_ENABLED +#define __SPI4_IS_CLK_DISABLED __HAL_RCC_SPI4_IS_CLK_DISABLED +#define __SDADC1_IS_CLK_ENABLED __HAL_RCC_SDADC1_IS_CLK_ENABLED +#define __SDADC1_IS_CLK_DISABLED __HAL_RCC_SDADC1_IS_CLK_DISABLED +#define __SDADC2_IS_CLK_ENABLED __HAL_RCC_SDADC2_IS_CLK_ENABLED +#define __SDADC2_IS_CLK_DISABLED __HAL_RCC_SDADC2_IS_CLK_DISABLED +#define __SDADC3_IS_CLK_ENABLED __HAL_RCC_SDADC3_IS_CLK_ENABLED +#define __SDADC3_IS_CLK_DISABLED __HAL_RCC_SDADC3_IS_CLK_DISABLED +#define __SRAM_IS_CLK_ENABLED __HAL_RCC_SRAM_IS_CLK_ENABLED +#define __SRAM_IS_CLK_DISABLED __HAL_RCC_SRAM_IS_CLK_DISABLED +#define __TIM1_IS_CLK_ENABLED __HAL_RCC_TIM1_IS_CLK_ENABLED +#define __TIM1_IS_CLK_DISABLED __HAL_RCC_TIM1_IS_CLK_DISABLED +#define __TIM2_IS_CLK_ENABLED __HAL_RCC_TIM2_IS_CLK_ENABLED +#define __TIM2_IS_CLK_DISABLED __HAL_RCC_TIM2_IS_CLK_DISABLED +#define __TIM3_IS_CLK_ENABLED __HAL_RCC_TIM3_IS_CLK_ENABLED +#define __TIM3_IS_CLK_DISABLED __HAL_RCC_TIM3_IS_CLK_DISABLED +#define __TIM4_IS_CLK_ENABLED __HAL_RCC_TIM4_IS_CLK_ENABLED +#define __TIM4_IS_CLK_DISABLED __HAL_RCC_TIM4_IS_CLK_DISABLED +#define __TIM5_IS_CLK_ENABLED __HAL_RCC_TIM5_IS_CLK_ENABLED +#define __TIM5_IS_CLK_DISABLED __HAL_RCC_TIM5_IS_CLK_DISABLED +#define __TIM6_IS_CLK_ENABLED __HAL_RCC_TIM6_IS_CLK_ENABLED +#define __TIM6_IS_CLK_DISABLED __HAL_RCC_TIM6_IS_CLK_DISABLED +#define __TIM7_IS_CLK_ENABLED __HAL_RCC_TIM7_IS_CLK_ENABLED +#define __TIM7_IS_CLK_DISABLED __HAL_RCC_TIM7_IS_CLK_DISABLED +#define __TIM8_IS_CLK_ENABLED __HAL_RCC_TIM8_IS_CLK_ENABLED +#define __TIM8_IS_CLK_DISABLED __HAL_RCC_TIM8_IS_CLK_DISABLED +#define __TIM12_IS_CLK_ENABLED __HAL_RCC_TIM12_IS_CLK_ENABLED +#define __TIM12_IS_CLK_DISABLED __HAL_RCC_TIM12_IS_CLK_DISABLED +#define __TIM13_IS_CLK_ENABLED __HAL_RCC_TIM13_IS_CLK_ENABLED +#define __TIM13_IS_CLK_DISABLED __HAL_RCC_TIM13_IS_CLK_DISABLED +#define __TIM14_IS_CLK_ENABLED __HAL_RCC_TIM14_IS_CLK_ENABLED +#define __TIM14_IS_CLK_DISABLED __HAL_RCC_TIM14_IS_CLK_DISABLED +#define __TIM15_IS_CLK_ENABLED __HAL_RCC_TIM15_IS_CLK_ENABLED +#define __TIM15_IS_CLK_DISABLED __HAL_RCC_TIM15_IS_CLK_DISABLED +#define __TIM16_IS_CLK_ENABLED __HAL_RCC_TIM16_IS_CLK_ENABLED +#define __TIM16_IS_CLK_DISABLED __HAL_RCC_TIM16_IS_CLK_DISABLED +#define __TIM17_IS_CLK_ENABLED __HAL_RCC_TIM17_IS_CLK_ENABLED +#define __TIM17_IS_CLK_DISABLED __HAL_RCC_TIM17_IS_CLK_DISABLED +#define __TIM18_IS_CLK_ENABLED __HAL_RCC_TIM18_IS_CLK_ENABLED +#define __TIM18_IS_CLK_DISABLED __HAL_RCC_TIM18_IS_CLK_DISABLED +#define __TIM19_IS_CLK_ENABLED __HAL_RCC_TIM19_IS_CLK_ENABLED +#define __TIM19_IS_CLK_DISABLED __HAL_RCC_TIM19_IS_CLK_DISABLED +#define __TIM20_IS_CLK_ENABLED __HAL_RCC_TIM20_IS_CLK_ENABLED +#define __TIM20_IS_CLK_DISABLED __HAL_RCC_TIM20_IS_CLK_DISABLED +#define __TSC_IS_CLK_ENABLED __HAL_RCC_TSC_IS_CLK_ENABLED +#define __TSC_IS_CLK_DISABLED __HAL_RCC_TSC_IS_CLK_DISABLED +#define __UART4_IS_CLK_ENABLED __HAL_RCC_UART4_IS_CLK_ENABLED +#define __UART4_IS_CLK_DISABLED __HAL_RCC_UART4_IS_CLK_DISABLED +#define __UART5_IS_CLK_ENABLED __HAL_RCC_UART5_IS_CLK_ENABLED +#define __UART5_IS_CLK_DISABLED __HAL_RCC_UART5_IS_CLK_DISABLED +#define __USART1_IS_CLK_ENABLED __HAL_RCC_USART1_IS_CLK_ENABLED +#define __USART1_IS_CLK_DISABLED __HAL_RCC_USART1_IS_CLK_DISABLED +#define __USART2_IS_CLK_ENABLED __HAL_RCC_USART2_IS_CLK_ENABLED +#define __USART2_IS_CLK_DISABLED __HAL_RCC_USART2_IS_CLK_DISABLED +#define __USART3_IS_CLK_ENABLED __HAL_RCC_USART3_IS_CLK_ENABLED +#define __USART3_IS_CLK_DISABLED __HAL_RCC_USART3_IS_CLK_DISABLED +#define __USB_IS_CLK_ENABLED __HAL_RCC_USB_IS_CLK_ENABLED +#define __USB_IS_CLK_DISABLED __HAL_RCC_USB_IS_CLK_DISABLED +#define __WWDG_IS_CLK_ENABLED __HAL_RCC_WWDG_IS_CLK_ENABLED +#define __WWDG_IS_CLK_DISABLED __HAL_RCC_WWDG_IS_CLK_DISABLED + +#if defined(STM32L1) +#define __HAL_RCC_CRYP_CLK_DISABLE __HAL_RCC_AES_CLK_DISABLE +#define __HAL_RCC_CRYP_CLK_ENABLE __HAL_RCC_AES_CLK_ENABLE +#define __HAL_RCC_CRYP_CLK_SLEEP_DISABLE __HAL_RCC_AES_CLK_SLEEP_DISABLE +#define __HAL_RCC_CRYP_CLK_SLEEP_ENABLE __HAL_RCC_AES_CLK_SLEEP_ENABLE +#define __HAL_RCC_CRYP_FORCE_RESET __HAL_RCC_AES_FORCE_RESET +#define __HAL_RCC_CRYP_RELEASE_RESET __HAL_RCC_AES_RELEASE_RESET +#endif /* STM32L1 */ + +#if defined(STM32F4) +#define __HAL_RCC_SDMMC1_FORCE_RESET __HAL_RCC_SDIO_FORCE_RESET +#define __HAL_RCC_SDMMC1_RELEASE_RESET __HAL_RCC_SDIO_RELEASE_RESET +#define __HAL_RCC_SDMMC1_CLK_SLEEP_ENABLE __HAL_RCC_SDIO_CLK_SLEEP_ENABLE +#define __HAL_RCC_SDMMC1_CLK_SLEEP_DISABLE __HAL_RCC_SDIO_CLK_SLEEP_DISABLE +#define __HAL_RCC_SDMMC1_CLK_ENABLE __HAL_RCC_SDIO_CLK_ENABLE +#define __HAL_RCC_SDMMC1_CLK_DISABLE __HAL_RCC_SDIO_CLK_DISABLE +#define __HAL_RCC_SDMMC1_IS_CLK_ENABLED __HAL_RCC_SDIO_IS_CLK_ENABLED +#define __HAL_RCC_SDMMC1_IS_CLK_DISABLED __HAL_RCC_SDIO_IS_CLK_DISABLED +#define Sdmmc1ClockSelection SdioClockSelection +#define RCC_PERIPHCLK_SDMMC1 RCC_PERIPHCLK_SDIO +#define RCC_SDMMC1CLKSOURCE_CLK48 RCC_SDIOCLKSOURCE_CK48 +#define RCC_SDMMC1CLKSOURCE_SYSCLK RCC_SDIOCLKSOURCE_SYSCLK +#define __HAL_RCC_SDMMC1_CONFIG __HAL_RCC_SDIO_CONFIG +#define __HAL_RCC_GET_SDMMC1_SOURCE __HAL_RCC_GET_SDIO_SOURCE +#endif + +#if defined(STM32F7) || defined(STM32L4) +#define __HAL_RCC_SDIO_FORCE_RESET __HAL_RCC_SDMMC1_FORCE_RESET +#define __HAL_RCC_SDIO_RELEASE_RESET __HAL_RCC_SDMMC1_RELEASE_RESET +#define __HAL_RCC_SDIO_CLK_SLEEP_ENABLE __HAL_RCC_SDMMC1_CLK_SLEEP_ENABLE +#define __HAL_RCC_SDIO_CLK_SLEEP_DISABLE __HAL_RCC_SDMMC1_CLK_SLEEP_DISABLE +#define __HAL_RCC_SDIO_CLK_ENABLE __HAL_RCC_SDMMC1_CLK_ENABLE +#define __HAL_RCC_SDIO_CLK_DISABLE __HAL_RCC_SDMMC1_CLK_DISABLE +#define __HAL_RCC_SDIO_IS_CLK_ENABLED __HAL_RCC_SDMMC1_IS_CLK_ENABLED +#define __HAL_RCC_SDIO_IS_CLK_DISABLED __HAL_RCC_SDMMC1_IS_CLK_DISABLED +#define SdioClockSelection Sdmmc1ClockSelection +#define RCC_PERIPHCLK_SDIO RCC_PERIPHCLK_SDMMC1 +#define __HAL_RCC_SDIO_CONFIG __HAL_RCC_SDMMC1_CONFIG +#define __HAL_RCC_GET_SDIO_SOURCE __HAL_RCC_GET_SDMMC1_SOURCE +#endif + +#if defined(STM32F7) +#define RCC_SDIOCLKSOURCE_CLK48 RCC_SDMMC1CLKSOURCE_CLK48 +#define RCC_SDIOCLKSOURCE_SYSCLK RCC_SDMMC1CLKSOURCE_SYSCLK +#endif + +#if defined(STM32H7) +#define __HAL_RCC_USB_OTG_HS_CLK_ENABLE() __HAL_RCC_USB1_OTG_HS_CLK_ENABLE() +#define __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE() __HAL_RCC_USB1_OTG_HS_ULPI_CLK_ENABLE() +#define __HAL_RCC_USB_OTG_HS_CLK_DISABLE() __HAL_RCC_USB1_OTG_HS_CLK_DISABLE() +#define __HAL_RCC_USB_OTG_HS_ULPI_CLK_DISABLE() __HAL_RCC_USB1_OTG_HS_ULPI_CLK_DISABLE() +#define __HAL_RCC_USB_OTG_HS_FORCE_RESET() __HAL_RCC_USB1_OTG_HS_FORCE_RESET() +#define __HAL_RCC_USB_OTG_HS_RELEASE_RESET() __HAL_RCC_USB1_OTG_HS_RELEASE_RESET() +#define __HAL_RCC_USB_OTG_HS_CLK_SLEEP_ENABLE() __HAL_RCC_USB1_OTG_HS_CLK_SLEEP_ENABLE() +#define __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_ENABLE() __HAL_RCC_USB1_OTG_HS_ULPI_CLK_SLEEP_ENABLE() +#define __HAL_RCC_USB_OTG_HS_CLK_SLEEP_DISABLE() __HAL_RCC_USB1_OTG_HS_CLK_SLEEP_DISABLE() +#define __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_DISABLE() __HAL_RCC_USB1_OTG_HS_ULPI_CLK_SLEEP_DISABLE() + +#define __HAL_RCC_USB_OTG_FS_CLK_ENABLE() __HAL_RCC_USB2_OTG_FS_CLK_ENABLE() +#define __HAL_RCC_USB_OTG_FS_ULPI_CLK_ENABLE() __HAL_RCC_USB2_OTG_FS_ULPI_CLK_ENABLE() +#define __HAL_RCC_USB_OTG_FS_CLK_DISABLE() __HAL_RCC_USB2_OTG_FS_CLK_DISABLE() +#define __HAL_RCC_USB_OTG_FS_ULPI_CLK_DISABLE() __HAL_RCC_USB2_OTG_FS_ULPI_CLK_DISABLE() +#define __HAL_RCC_USB_OTG_FS_FORCE_RESET() __HAL_RCC_USB2_OTG_FS_FORCE_RESET() +#define __HAL_RCC_USB_OTG_FS_RELEASE_RESET() __HAL_RCC_USB2_OTG_FS_RELEASE_RESET() +#define __HAL_RCC_USB_OTG_FS_CLK_SLEEP_ENABLE() __HAL_RCC_USB2_OTG_FS_CLK_SLEEP_ENABLE() +#define __HAL_RCC_USB_OTG_FS_ULPI_CLK_SLEEP_ENABLE() __HAL_RCC_USB2_OTG_FS_ULPI_CLK_SLEEP_ENABLE() +#define __HAL_RCC_USB_OTG_FS_CLK_SLEEP_DISABLE() __HAL_RCC_USB2_OTG_FS_CLK_SLEEP_DISABLE() +#define __HAL_RCC_USB_OTG_FS_ULPI_CLK_SLEEP_DISABLE() __HAL_RCC_USB2_OTG_FS_ULPI_CLK_SLEEP_DISABLE() +#endif + +#define __HAL_RCC_I2SCLK __HAL_RCC_I2S_CONFIG +#define __HAL_RCC_I2SCLK_CONFIG __HAL_RCC_I2S_CONFIG + +#define __RCC_PLLSRC RCC_GET_PLL_OSCSOURCE + +#define IS_RCC_MSIRANGE IS_RCC_MSI_CLOCK_RANGE +#define IS_RCC_RTCCLK_SOURCE IS_RCC_RTCCLKSOURCE +#define IS_RCC_SYSCLK_DIV IS_RCC_HCLK +#define IS_RCC_HCLK_DIV IS_RCC_PCLK +#define IS_RCC_PERIPHCLK IS_RCC_PERIPHCLOCK + +#define RCC_IT_HSI14 RCC_IT_HSI14RDY + +#define RCC_IT_CSSLSE RCC_IT_LSECSS +#define RCC_IT_CSSHSE RCC_IT_CSS + +#define RCC_PLLMUL_3 RCC_PLL_MUL3 +#define RCC_PLLMUL_4 RCC_PLL_MUL4 +#define RCC_PLLMUL_6 RCC_PLL_MUL6 +#define RCC_PLLMUL_8 RCC_PLL_MUL8 +#define RCC_PLLMUL_12 RCC_PLL_MUL12 +#define RCC_PLLMUL_16 RCC_PLL_MUL16 +#define RCC_PLLMUL_24 RCC_PLL_MUL24 +#define RCC_PLLMUL_32 RCC_PLL_MUL32 +#define RCC_PLLMUL_48 RCC_PLL_MUL48 + +#define RCC_PLLDIV_2 RCC_PLL_DIV2 +#define RCC_PLLDIV_3 RCC_PLL_DIV3 +#define RCC_PLLDIV_4 RCC_PLL_DIV4 + +#define IS_RCC_MCOSOURCE IS_RCC_MCO1SOURCE +#define __HAL_RCC_MCO_CONFIG __HAL_RCC_MCO1_CONFIG +#define RCC_MCO_NODIV RCC_MCODIV_1 +#define RCC_MCO_DIV1 RCC_MCODIV_1 +#define RCC_MCO_DIV2 RCC_MCODIV_2 +#define RCC_MCO_DIV4 RCC_MCODIV_4 +#define RCC_MCO_DIV8 RCC_MCODIV_8 +#define RCC_MCO_DIV16 RCC_MCODIV_16 +#define RCC_MCO_DIV32 RCC_MCODIV_32 +#define RCC_MCO_DIV64 RCC_MCODIV_64 +#define RCC_MCO_DIV128 RCC_MCODIV_128 +#define RCC_MCOSOURCE_NONE RCC_MCO1SOURCE_NOCLOCK +#define RCC_MCOSOURCE_LSI RCC_MCO1SOURCE_LSI +#define RCC_MCOSOURCE_LSE RCC_MCO1SOURCE_LSE +#define RCC_MCOSOURCE_SYSCLK RCC_MCO1SOURCE_SYSCLK +#define RCC_MCOSOURCE_HSI RCC_MCO1SOURCE_HSI +#define RCC_MCOSOURCE_HSI14 RCC_MCO1SOURCE_HSI14 +#define RCC_MCOSOURCE_HSI48 RCC_MCO1SOURCE_HSI48 +#define RCC_MCOSOURCE_HSE RCC_MCO1SOURCE_HSE +#define RCC_MCOSOURCE_PLLCLK_DIV1 RCC_MCO1SOURCE_PLLCLK +#define RCC_MCOSOURCE_PLLCLK_NODIV RCC_MCO1SOURCE_PLLCLK +#define RCC_MCOSOURCE_PLLCLK_DIV2 RCC_MCO1SOURCE_PLLCLK_DIV2 + +#if defined(STM32L4) || defined(STM32WB) || defined(STM32G0) || defined(STM32G4) || defined(STM32L5) || \ + defined(STM32WL) || defined(STM32C0) +#define RCC_RTCCLKSOURCE_NO_CLK RCC_RTCCLKSOURCE_NONE +#else +#define RCC_RTCCLKSOURCE_NONE RCC_RTCCLKSOURCE_NO_CLK +#endif + +#define RCC_USBCLK_PLLSAI1 RCC_USBCLKSOURCE_PLLSAI1 +#define RCC_USBCLK_PLL RCC_USBCLKSOURCE_PLL +#define RCC_USBCLK_MSI RCC_USBCLKSOURCE_MSI +#define RCC_USBCLKSOURCE_PLLCLK RCC_USBCLKSOURCE_PLL +#define RCC_USBPLLCLK_DIV1 RCC_USBCLKSOURCE_PLL +#define RCC_USBPLLCLK_DIV1_5 RCC_USBCLKSOURCE_PLL_DIV1_5 +#define RCC_USBPLLCLK_DIV2 RCC_USBCLKSOURCE_PLL_DIV2 +#define RCC_USBPLLCLK_DIV3 RCC_USBCLKSOURCE_PLL_DIV3 + +#define HSION_BitNumber RCC_HSION_BIT_NUMBER +#define HSION_BITNUMBER RCC_HSION_BIT_NUMBER +#define HSEON_BitNumber RCC_HSEON_BIT_NUMBER +#define HSEON_BITNUMBER RCC_HSEON_BIT_NUMBER +#define MSION_BITNUMBER RCC_MSION_BIT_NUMBER +#define CSSON_BitNumber RCC_CSSON_BIT_NUMBER +#define CSSON_BITNUMBER RCC_CSSON_BIT_NUMBER +#define PLLON_BitNumber RCC_PLLON_BIT_NUMBER +#define PLLON_BITNUMBER RCC_PLLON_BIT_NUMBER +#define PLLI2SON_BitNumber RCC_PLLI2SON_BIT_NUMBER +#define I2SSRC_BitNumber RCC_I2SSRC_BIT_NUMBER +#define RTCEN_BitNumber RCC_RTCEN_BIT_NUMBER +#define RTCEN_BITNUMBER RCC_RTCEN_BIT_NUMBER +#define BDRST_BitNumber RCC_BDRST_BIT_NUMBER +#define BDRST_BITNUMBER RCC_BDRST_BIT_NUMBER +#define RTCRST_BITNUMBER RCC_RTCRST_BIT_NUMBER +#define LSION_BitNumber RCC_LSION_BIT_NUMBER +#define LSION_BITNUMBER RCC_LSION_BIT_NUMBER +#define LSEON_BitNumber RCC_LSEON_BIT_NUMBER +#define LSEON_BITNUMBER RCC_LSEON_BIT_NUMBER +#define LSEBYP_BITNUMBER RCC_LSEBYP_BIT_NUMBER +#define PLLSAION_BitNumber RCC_PLLSAION_BIT_NUMBER +#define TIMPRE_BitNumber RCC_TIMPRE_BIT_NUMBER +#define RMVF_BitNumber RCC_RMVF_BIT_NUMBER +#define RMVF_BITNUMBER RCC_RMVF_BIT_NUMBER +#define RCC_CR2_HSI14TRIM_BitNumber RCC_HSI14TRIM_BIT_NUMBER +#define CR_BYTE2_ADDRESS RCC_CR_BYTE2_ADDRESS +#define CIR_BYTE1_ADDRESS RCC_CIR_BYTE1_ADDRESS +#define CIR_BYTE2_ADDRESS RCC_CIR_BYTE2_ADDRESS +#define BDCR_BYTE0_ADDRESS RCC_BDCR_BYTE0_ADDRESS +#define DBP_TIMEOUT_VALUE RCC_DBP_TIMEOUT_VALUE +#define LSE_TIMEOUT_VALUE RCC_LSE_TIMEOUT_VALUE + +#define CR_HSION_BB RCC_CR_HSION_BB +#define CR_CSSON_BB RCC_CR_CSSON_BB +#define CR_PLLON_BB RCC_CR_PLLON_BB +#define CR_PLLI2SON_BB RCC_CR_PLLI2SON_BB +#define CR_MSION_BB RCC_CR_MSION_BB +#define CSR_LSION_BB RCC_CSR_LSION_BB +#define CSR_LSEON_BB RCC_CSR_LSEON_BB +#define CSR_LSEBYP_BB RCC_CSR_LSEBYP_BB +#define CSR_RTCEN_BB RCC_CSR_RTCEN_BB +#define CSR_RTCRST_BB RCC_CSR_RTCRST_BB +#define CFGR_I2SSRC_BB RCC_CFGR_I2SSRC_BB +#define BDCR_RTCEN_BB RCC_BDCR_RTCEN_BB +#define BDCR_BDRST_BB RCC_BDCR_BDRST_BB +#define CR_HSEON_BB RCC_CR_HSEON_BB +#define CSR_RMVF_BB RCC_CSR_RMVF_BB +#define CR_PLLSAION_BB RCC_CR_PLLSAION_BB +#define DCKCFGR_TIMPRE_BB RCC_DCKCFGR_TIMPRE_BB + +#define __HAL_RCC_CRS_ENABLE_FREQ_ERROR_COUNTER __HAL_RCC_CRS_FREQ_ERROR_COUNTER_ENABLE +#define __HAL_RCC_CRS_DISABLE_FREQ_ERROR_COUNTER __HAL_RCC_CRS_FREQ_ERROR_COUNTER_DISABLE +#define __HAL_RCC_CRS_ENABLE_AUTOMATIC_CALIB __HAL_RCC_CRS_AUTOMATIC_CALIB_ENABLE +#define __HAL_RCC_CRS_DISABLE_AUTOMATIC_CALIB __HAL_RCC_CRS_AUTOMATIC_CALIB_DISABLE +#define __HAL_RCC_CRS_CALCULATE_RELOADVALUE __HAL_RCC_CRS_RELOADVALUE_CALCULATE + +#define __HAL_RCC_GET_IT_SOURCE __HAL_RCC_GET_IT + +#define RCC_CRS_SYNCWARM RCC_CRS_SYNCWARN +#define RCC_CRS_TRIMOV RCC_CRS_TRIMOVF + +#define RCC_PERIPHCLK_CK48 RCC_PERIPHCLK_CLK48 +#define RCC_CK48CLKSOURCE_PLLQ RCC_CLK48CLKSOURCE_PLLQ +#define RCC_CK48CLKSOURCE_PLLSAIP RCC_CLK48CLKSOURCE_PLLSAIP +#define RCC_CK48CLKSOURCE_PLLI2SQ RCC_CLK48CLKSOURCE_PLLI2SQ +#define IS_RCC_CK48CLKSOURCE IS_RCC_CLK48CLKSOURCE +#define RCC_SDIOCLKSOURCE_CK48 RCC_SDIOCLKSOURCE_CLK48 + +#define __HAL_RCC_DFSDM_CLK_ENABLE __HAL_RCC_DFSDM1_CLK_ENABLE +#define __HAL_RCC_DFSDM_CLK_DISABLE __HAL_RCC_DFSDM1_CLK_DISABLE +#define __HAL_RCC_DFSDM_IS_CLK_ENABLED __HAL_RCC_DFSDM1_IS_CLK_ENABLED +#define __HAL_RCC_DFSDM_IS_CLK_DISABLED __HAL_RCC_DFSDM1_IS_CLK_DISABLED +#define __HAL_RCC_DFSDM_FORCE_RESET __HAL_RCC_DFSDM1_FORCE_RESET +#define __HAL_RCC_DFSDM_RELEASE_RESET __HAL_RCC_DFSDM1_RELEASE_RESET +#define __HAL_RCC_DFSDM_CLK_SLEEP_ENABLE __HAL_RCC_DFSDM1_CLK_SLEEP_ENABLE +#define __HAL_RCC_DFSDM_CLK_SLEEP_DISABLE __HAL_RCC_DFSDM1_CLK_SLEEP_DISABLE +#define __HAL_RCC_DFSDM_IS_CLK_SLEEP_ENABLED __HAL_RCC_DFSDM1_IS_CLK_SLEEP_ENABLED +#define __HAL_RCC_DFSDM_IS_CLK_SLEEP_DISABLED __HAL_RCC_DFSDM1_IS_CLK_SLEEP_DISABLED +#define DfsdmClockSelection Dfsdm1ClockSelection +#define RCC_PERIPHCLK_DFSDM RCC_PERIPHCLK_DFSDM1 +#define RCC_DFSDMCLKSOURCE_PCLK RCC_DFSDM1CLKSOURCE_PCLK2 +#define RCC_DFSDMCLKSOURCE_SYSCLK RCC_DFSDM1CLKSOURCE_SYSCLK +#define __HAL_RCC_DFSDM_CONFIG __HAL_RCC_DFSDM1_CONFIG +#define __HAL_RCC_GET_DFSDM_SOURCE __HAL_RCC_GET_DFSDM1_SOURCE +#define RCC_DFSDM1CLKSOURCE_PCLK RCC_DFSDM1CLKSOURCE_PCLK2 +#define RCC_SWPMI1CLKSOURCE_PCLK RCC_SWPMI1CLKSOURCE_PCLK1 +#define RCC_LPTIM1CLKSOURCE_PCLK RCC_LPTIM1CLKSOURCE_PCLK1 +#define RCC_LPTIM2CLKSOURCE_PCLK RCC_LPTIM2CLKSOURCE_PCLK1 + +#define RCC_DFSDM1AUDIOCLKSOURCE_I2SAPB1 RCC_DFSDM1AUDIOCLKSOURCE_I2S1 +#define RCC_DFSDM1AUDIOCLKSOURCE_I2SAPB2 RCC_DFSDM1AUDIOCLKSOURCE_I2S2 +#define RCC_DFSDM2AUDIOCLKSOURCE_I2SAPB1 RCC_DFSDM2AUDIOCLKSOURCE_I2S1 +#define RCC_DFSDM2AUDIOCLKSOURCE_I2SAPB2 RCC_DFSDM2AUDIOCLKSOURCE_I2S2 +#define RCC_DFSDM1CLKSOURCE_APB2 RCC_DFSDM1CLKSOURCE_PCLK2 +#define RCC_DFSDM2CLKSOURCE_APB2 RCC_DFSDM2CLKSOURCE_PCLK2 +#define RCC_FMPI2C1CLKSOURCE_APB RCC_FMPI2C1CLKSOURCE_PCLK1 +#if defined(STM32U5) +#define MSIKPLLModeSEL RCC_MSIKPLL_MODE_SEL +#define MSISPLLModeSEL RCC_MSISPLL_MODE_SEL +#define __HAL_RCC_AHB21_CLK_DISABLE __HAL_RCC_AHB2_1_CLK_DISABLE +#define __HAL_RCC_AHB22_CLK_DISABLE __HAL_RCC_AHB2_2_CLK_DISABLE +#define __HAL_RCC_AHB1_CLK_Disable_Clear __HAL_RCC_AHB1_CLK_ENABLE +#define __HAL_RCC_AHB21_CLK_Disable_Clear __HAL_RCC_AHB2_1_CLK_ENABLE +#define __HAL_RCC_AHB22_CLK_Disable_Clear __HAL_RCC_AHB2_2_CLK_ENABLE +#define __HAL_RCC_AHB3_CLK_Disable_Clear __HAL_RCC_AHB3_CLK_ENABLE +#define __HAL_RCC_APB1_CLK_Disable_Clear __HAL_RCC_APB1_CLK_ENABLE +#define __HAL_RCC_APB2_CLK_Disable_Clear __HAL_RCC_APB2_CLK_ENABLE +#define __HAL_RCC_APB3_CLK_Disable_Clear __HAL_RCC_APB3_CLK_ENABLE +#define IS_RCC_MSIPLLModeSelection IS_RCC_MSIPLLMODE_SELECT +#define RCC_PERIPHCLK_CLK48 RCC_PERIPHCLK_ICLK +#define RCC_CLK48CLKSOURCE_HSI48 RCC_ICLK_CLKSOURCE_HSI48 +#define RCC_CLK48CLKSOURCE_PLL2 RCC_ICLK_CLKSOURCE_PLL2 +#define RCC_CLK48CLKSOURCE_PLL1 RCC_ICLK_CLKSOURCE_PLL1 +#define RCC_CLK48CLKSOURCE_MSIK RCC_ICLK_CLKSOURCE_MSIK +#define __HAL_RCC_ADC1_CLK_ENABLE __HAL_RCC_ADC12_CLK_ENABLE +#define __HAL_RCC_ADC1_CLK_DISABLE __HAL_RCC_ADC12_CLK_DISABLE +#define __HAL_RCC_ADC1_IS_CLK_ENABLED __HAL_RCC_ADC12_IS_CLK_ENABLED +#define __HAL_RCC_ADC1_IS_CLK_DISABLED __HAL_RCC_ADC12_IS_CLK_DISABLED +#define __HAL_RCC_ADC1_FORCE_RESET __HAL_RCC_ADC12_FORCE_RESET +#define __HAL_RCC_ADC1_RELEASE_RESET __HAL_RCC_ADC12_RELEASE_RESET +#define __HAL_RCC_ADC1_CLK_SLEEP_ENABLE __HAL_RCC_ADC12_CLK_SLEEP_ENABLE +#define __HAL_RCC_ADC1_CLK_SLEEP_DISABLE __HAL_RCC_ADC12_CLK_SLEEP_DISABLE +#define __HAL_RCC_GET_CLK48_SOURCE __HAL_RCC_GET_ICLK_SOURCE +#define __HAL_RCC_PLLFRACN_ENABLE __HAL_RCC_PLL_FRACN_ENABLE +#define __HAL_RCC_PLLFRACN_DISABLE __HAL_RCC_PLL_FRACN_DISABLE +#define __HAL_RCC_PLLFRACN_CONFIG __HAL_RCC_PLL_FRACN_CONFIG +#define IS_RCC_PLLFRACN_VALUE IS_RCC_PLL_FRACN_VALUE +#endif /* STM32U5 */ + +#if defined(STM32H5) +#define __HAL_RCC_PLLFRACN_ENABLE __HAL_RCC_PLL_FRACN_ENABLE +#define __HAL_RCC_PLLFRACN_DISABLE __HAL_RCC_PLL_FRACN_DISABLE +#define __HAL_RCC_PLLFRACN_CONFIG __HAL_RCC_PLL_FRACN_CONFIG +#define IS_RCC_PLLFRACN_VALUE IS_RCC_PLL_FRACN_VALUE + +#define RCC_PLLSOURCE_NONE RCC_PLL1_SOURCE_NONE +#define RCC_PLLSOURCE_HSI RCC_PLL1_SOURCE_HSI +#define RCC_PLLSOURCE_CSI RCC_PLL1_SOURCE_CSI +#define RCC_PLLSOURCE_HSE RCC_PLL1_SOURCE_HSE +#define RCC_PLLVCIRANGE_0 RCC_PLL1_VCIRANGE_0 +#define RCC_PLLVCIRANGE_1 RCC_PLL1_VCIRANGE_1 +#define RCC_PLLVCIRANGE_2 RCC_PLL1_VCIRANGE_2 +#define RCC_PLLVCIRANGE_3 RCC_PLL1_VCIRANGE_3 +#define RCC_PLL1VCOWIDE RCC_PLL1_VCORANGE_WIDE +#define RCC_PLL1VCOMEDIUM RCC_PLL1_VCORANGE_MEDIUM + +#define IS_RCC_PLLSOURCE IS_RCC_PLL1_SOURCE +#define IS_RCC_PLLRGE_VALUE IS_RCC_PLL1_VCIRGE_VALUE +#define IS_RCC_PLLVCORGE_VALUE IS_RCC_PLL1_VCORGE_VALUE +#define IS_RCC_PLLCLOCKOUT_VALUE IS_RCC_PLL1_CLOCKOUT_VALUE +#define IS_RCC_PLL_FRACN_VALUE IS_RCC_PLL1_FRACN_VALUE +#define IS_RCC_PLLM_VALUE IS_RCC_PLL1_DIVM_VALUE +#define IS_RCC_PLLN_VALUE IS_RCC_PLL1_MULN_VALUE +#define IS_RCC_PLLP_VALUE IS_RCC_PLL1_DIVP_VALUE +#define IS_RCC_PLLQ_VALUE IS_RCC_PLL1_DIVQ_VALUE +#define IS_RCC_PLLR_VALUE IS_RCC_PLL1_DIVR_VALUE + +#define __HAL_RCC_PLL_ENABLE __HAL_RCC_PLL1_ENABLE +#define __HAL_RCC_PLL_DISABLE __HAL_RCC_PLL1_DISABLE +#define __HAL_RCC_PLL_FRACN_ENABLE __HAL_RCC_PLL1_FRACN_ENABLE +#define __HAL_RCC_PLL_FRACN_DISABLE __HAL_RCC_PLL1_FRACN_DISABLE +#define __HAL_RCC_PLL_CONFIG __HAL_RCC_PLL1_CONFIG +#define __HAL_RCC_PLL_PLLSOURCE_CONFIG __HAL_RCC_PLL1_PLLSOURCE_CONFIG +#define __HAL_RCC_PLL_DIVM_CONFIG __HAL_RCC_PLL1_DIVM_CONFIG +#define __HAL_RCC_PLL_FRACN_CONFIG __HAL_RCC_PLL1_FRACN_CONFIG +#define __HAL_RCC_PLL_VCIRANGE __HAL_RCC_PLL1_VCIRANGE +#define __HAL_RCC_PLL_VCORANGE __HAL_RCC_PLL1_VCORANGE +#define __HAL_RCC_GET_PLL_OSCSOURCE __HAL_RCC_GET_PLL1_OSCSOURCE +#define __HAL_RCC_PLLCLKOUT_ENABLE __HAL_RCC_PLL1_CLKOUT_ENABLE +#define __HAL_RCC_PLLCLKOUT_DISABLE __HAL_RCC_PLL1_CLKOUT_DISABLE +#define __HAL_RCC_GET_PLLCLKOUT_CONFIG __HAL_RCC_GET_PLL1_CLKOUT_CONFIG + +#define __HAL_RCC_PLL2FRACN_ENABLE __HAL_RCC_PLL2_FRACN_ENABLE +#define __HAL_RCC_PLL2FRACN_DISABLE __HAL_RCC_PLL2_FRACN_DISABLE +#define __HAL_RCC_PLL2CLKOUT_ENABLE __HAL_RCC_PLL2_CLKOUT_ENABLE +#define __HAL_RCC_PLL2CLKOUT_DISABLE __HAL_RCC_PLL2_CLKOUT_DISABLE +#define __HAL_RCC_PLL2FRACN_CONFIG __HAL_RCC_PLL2_FRACN_CONFIG +#define __HAL_RCC_GET_PLL2CLKOUT_CONFIG __HAL_RCC_GET_PLL2_CLKOUT_CONFIG + +#define __HAL_RCC_PLL3FRACN_ENABLE __HAL_RCC_PLL3_FRACN_ENABLE +#define __HAL_RCC_PLL3FRACN_DISABLE __HAL_RCC_PLL3_FRACN_DISABLE +#define __HAL_RCC_PLL3CLKOUT_ENABLE __HAL_RCC_PLL3_CLKOUT_ENABLE +#define __HAL_RCC_PLL3CLKOUT_DISABLE __HAL_RCC_PLL3_CLKOUT_DISABLE +#define __HAL_RCC_PLL3FRACN_CONFIG __HAL_RCC_PLL3_FRACN_CONFIG +#define __HAL_RCC_GET_PLL3CLKOUT_CONFIG __HAL_RCC_GET_PLL3_CLKOUT_CONFIG + +#define RCC_PLL2VCIRANGE_0 RCC_PLL2_VCIRANGE_0 +#define RCC_PLL2VCIRANGE_1 RCC_PLL2_VCIRANGE_1 +#define RCC_PLL2VCIRANGE_2 RCC_PLL2_VCIRANGE_2 +#define RCC_PLL2VCIRANGE_3 RCC_PLL2_VCIRANGE_3 + +#define RCC_PLL2VCOWIDE RCC_PLL2_VCORANGE_WIDE +#define RCC_PLL2VCOMEDIUM RCC_PLL2_VCORANGE_MEDIUM + +#define RCC_PLL2SOURCE_NONE RCC_PLL2_SOURCE_NONE +#define RCC_PLL2SOURCE_HSI RCC_PLL2_SOURCE_HSI +#define RCC_PLL2SOURCE_CSI RCC_PLL2_SOURCE_CSI +#define RCC_PLL2SOURCE_HSE RCC_PLL2_SOURCE_HSE + +#define RCC_PLL3VCIRANGE_0 RCC_PLL3_VCIRANGE_0 +#define RCC_PLL3VCIRANGE_1 RCC_PLL3_VCIRANGE_1 +#define RCC_PLL3VCIRANGE_2 RCC_PLL3_VCIRANGE_2 +#define RCC_PLL3VCIRANGE_3 RCC_PLL3_VCIRANGE_3 + +#define RCC_PLL3VCOWIDE RCC_PLL3_VCORANGE_WIDE +#define RCC_PLL3VCOMEDIUM RCC_PLL3_VCORANGE_MEDIUM + +#define RCC_PLL3SOURCE_NONE RCC_PLL3_SOURCE_NONE +#define RCC_PLL3SOURCE_HSI RCC_PLL3_SOURCE_HSI +#define RCC_PLL3SOURCE_CSI RCC_PLL3_SOURCE_CSI +#define RCC_PLL3SOURCE_HSE RCC_PLL3_SOURCE_HSE + + +#endif /* STM32H5 */ + +/** + * @} + */ + +/** @defgroup HAL_RNG_Aliased_Macros HAL RNG Aliased Macros maintained for legacy purpose + * @{ + */ +#define HAL_RNG_ReadyCallback(__HANDLE__) HAL_RNG_ReadyDataCallback((__HANDLE__), uint32_t random32bit) + +/** + * @} + */ + +/** @defgroup HAL_RTC_Aliased_Macros HAL RTC Aliased Macros maintained for legacy purpose + * @{ + */ +#if defined (STM32G0) || defined (STM32L5) || defined (STM32L412xx) || defined (STM32L422xx) || \ + defined (STM32L4P5xx)|| defined (STM32L4Q5xx) || defined (STM32G4) || defined (STM32WL) || defined (STM32U5) || \ + defined (STM32WBA) || defined (STM32H5) || defined (STM32C0) +#else +#define __HAL_RTC_CLEAR_FLAG __HAL_RTC_EXTI_CLEAR_FLAG +#endif +#define __HAL_RTC_DISABLE_IT __HAL_RTC_EXTI_DISABLE_IT +#define __HAL_RTC_ENABLE_IT __HAL_RTC_EXTI_ENABLE_IT + +#if defined (STM32F1) +#define __HAL_RTC_EXTI_CLEAR_FLAG(RTC_EXTI_LINE_ALARM_EVENT) __HAL_RTC_ALARM_EXTI_CLEAR_FLAG() + +#define __HAL_RTC_EXTI_ENABLE_IT(RTC_EXTI_LINE_ALARM_EVENT) __HAL_RTC_ALARM_EXTI_ENABLE_IT() + +#define __HAL_RTC_EXTI_DISABLE_IT(RTC_EXTI_LINE_ALARM_EVENT) __HAL_RTC_ALARM_EXTI_DISABLE_IT() + +#define __HAL_RTC_EXTI_GET_FLAG(RTC_EXTI_LINE_ALARM_EVENT) __HAL_RTC_ALARM_EXTI_GET_FLAG() + +#define __HAL_RTC_EXTI_GENERATE_SWIT(RTC_EXTI_LINE_ALARM_EVENT) __HAL_RTC_ALARM_EXTI_GENERATE_SWIT() +#else +#define __HAL_RTC_EXTI_CLEAR_FLAG(__EXTI_LINE__) (((__EXTI_LINE__) == RTC_EXTI_LINE_ALARM_EVENT) ? __HAL_RTC_ALARM_EXTI_CLEAR_FLAG() : \ + (((__EXTI_LINE__) == RTC_EXTI_LINE_WAKEUPTIMER_EVENT) ? __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG() : \ + __HAL_RTC_TAMPER_TIMESTAMP_EXTI_CLEAR_FLAG())) +#define __HAL_RTC_EXTI_ENABLE_IT(__EXTI_LINE__) (((__EXTI_LINE__) == RTC_EXTI_LINE_ALARM_EVENT) ? __HAL_RTC_ALARM_EXTI_ENABLE_IT() : \ + (((__EXTI_LINE__) == RTC_EXTI_LINE_WAKEUPTIMER_EVENT) ? __HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_IT() : \ + __HAL_RTC_TAMPER_TIMESTAMP_EXTI_ENABLE_IT())) +#define __HAL_RTC_EXTI_DISABLE_IT(__EXTI_LINE__) (((__EXTI_LINE__) == RTC_EXTI_LINE_ALARM_EVENT) ? __HAL_RTC_ALARM_EXTI_DISABLE_IT() : \ + (((__EXTI_LINE__) == RTC_EXTI_LINE_WAKEUPTIMER_EVENT) ? __HAL_RTC_WAKEUPTIMER_EXTI_DISABLE_IT() : \ + __HAL_RTC_TAMPER_TIMESTAMP_EXTI_DISABLE_IT())) +#define __HAL_RTC_EXTI_GET_FLAG(__EXTI_LINE__) (((__EXTI_LINE__) == RTC_EXTI_LINE_ALARM_EVENT) ? __HAL_RTC_ALARM_EXTI_GET_FLAG() : \ + (((__EXTI_LINE__) == RTC_EXTI_LINE_WAKEUPTIMER_EVENT) ? __HAL_RTC_WAKEUPTIMER_EXTI_GET_FLAG() : \ + __HAL_RTC_TAMPER_TIMESTAMP_EXTI_GET_FLAG())) +#define __HAL_RTC_EXTI_GENERATE_SWIT(__EXTI_LINE__) (((__EXTI_LINE__) == RTC_EXTI_LINE_ALARM_EVENT) ? __HAL_RTC_ALARM_EXTI_GENERATE_SWIT() : \ + (((__EXTI_LINE__) == RTC_EXTI_LINE_WAKEUPTIMER_EVENT) ? __HAL_RTC_WAKEUPTIMER_EXTI_GENERATE_SWIT() : \ + __HAL_RTC_TAMPER_TIMESTAMP_EXTI_GENERATE_SWIT())) +#endif /* STM32F1 */ + +#if defined (STM32F0) || defined (STM32F2) || defined (STM32F3) || defined (STM32F4) || defined (STM32F7) || \ + defined (STM32H7) || \ + defined (STM32L0) || defined (STM32L1) +#define __HAL_RTC_TAMPER_GET_IT __HAL_RTC_TAMPER_GET_FLAG +#endif + +#define IS_ALARM IS_RTC_ALARM +#define IS_ALARM_MASK IS_RTC_ALARM_MASK +#define IS_TAMPER IS_RTC_TAMPER +#define IS_TAMPER_ERASE_MODE IS_RTC_TAMPER_ERASE_MODE +#define IS_TAMPER_FILTER IS_RTC_TAMPER_FILTER +#define IS_TAMPER_INTERRUPT IS_RTC_TAMPER_INTERRUPT +#define IS_TAMPER_MASKFLAG_STATE IS_RTC_TAMPER_MASKFLAG_STATE +#define IS_TAMPER_PRECHARGE_DURATION IS_RTC_TAMPER_PRECHARGE_DURATION +#define IS_TAMPER_PULLUP_STATE IS_RTC_TAMPER_PULLUP_STATE +#define IS_TAMPER_SAMPLING_FREQ IS_RTC_TAMPER_SAMPLING_FREQ +#define IS_TAMPER_TIMESTAMPONTAMPER_DETECTION IS_RTC_TAMPER_TIMESTAMPONTAMPER_DETECTION +#define IS_TAMPER_TRIGGER IS_RTC_TAMPER_TRIGGER +#define IS_WAKEUP_CLOCK IS_RTC_WAKEUP_CLOCK +#define IS_WAKEUP_COUNTER IS_RTC_WAKEUP_COUNTER + +#define __RTC_WRITEPROTECTION_ENABLE __HAL_RTC_WRITEPROTECTION_ENABLE +#define __RTC_WRITEPROTECTION_DISABLE __HAL_RTC_WRITEPROTECTION_DISABLE + +#if defined (STM32H5) +#define __HAL_RCC_RTCAPB_CLK_ENABLE __HAL_RCC_RTC_CLK_ENABLE +#define __HAL_RCC_RTCAPB_CLK_DISABLE __HAL_RCC_RTC_CLK_DISABLE +#endif /* STM32H5 */ + +/** + * @} + */ + +/** @defgroup HAL_SD_Aliased_Macros HAL SD/MMC Aliased Macros maintained for legacy purpose + * @{ + */ + +#define SD_OCR_CID_CSD_OVERWRIETE SD_OCR_CID_CSD_OVERWRITE +#define SD_CMD_SD_APP_STAUS SD_CMD_SD_APP_STATUS + +#if !defined(STM32F1) && !defined(STM32F2) && !defined(STM32F4) && !defined(STM32L1) +#define eMMC_HIGH_VOLTAGE_RANGE EMMC_HIGH_VOLTAGE_RANGE +#define eMMC_DUAL_VOLTAGE_RANGE EMMC_DUAL_VOLTAGE_RANGE +#define eMMC_LOW_VOLTAGE_RANGE EMMC_LOW_VOLTAGE_RANGE + +#define SDMMC_NSpeed_CLK_DIV SDMMC_NSPEED_CLK_DIV +#define SDMMC_HSpeed_CLK_DIV SDMMC_HSPEED_CLK_DIV +#endif + +#if defined(STM32F4) || defined(STM32F2) +#define SD_SDMMC_DISABLED SD_SDIO_DISABLED +#define SD_SDMMC_FUNCTION_BUSY SD_SDIO_FUNCTION_BUSY +#define SD_SDMMC_FUNCTION_FAILED SD_SDIO_FUNCTION_FAILED +#define SD_SDMMC_UNKNOWN_FUNCTION SD_SDIO_UNKNOWN_FUNCTION +#define SD_CMD_SDMMC_SEN_OP_COND SD_CMD_SDIO_SEN_OP_COND +#define SD_CMD_SDMMC_RW_DIRECT SD_CMD_SDIO_RW_DIRECT +#define SD_CMD_SDMMC_RW_EXTENDED SD_CMD_SDIO_RW_EXTENDED +#define __HAL_SD_SDMMC_ENABLE __HAL_SD_SDIO_ENABLE +#define __HAL_SD_SDMMC_DISABLE __HAL_SD_SDIO_DISABLE +#define __HAL_SD_SDMMC_DMA_ENABLE __HAL_SD_SDIO_DMA_ENABLE +#define __HAL_SD_SDMMC_DMA_DISABLE __HAL_SD_SDIO_DMA_DISABL +#define __HAL_SD_SDMMC_ENABLE_IT __HAL_SD_SDIO_ENABLE_IT +#define __HAL_SD_SDMMC_DISABLE_IT __HAL_SD_SDIO_DISABLE_IT +#define __HAL_SD_SDMMC_GET_FLAG __HAL_SD_SDIO_GET_FLAG +#define __HAL_SD_SDMMC_CLEAR_FLAG __HAL_SD_SDIO_CLEAR_FLAG +#define __HAL_SD_SDMMC_GET_IT __HAL_SD_SDIO_GET_IT +#define __HAL_SD_SDMMC_CLEAR_IT __HAL_SD_SDIO_CLEAR_IT +#define SDMMC_STATIC_FLAGS SDIO_STATIC_FLAGS +#define SDMMC_CMD0TIMEOUT SDIO_CMD0TIMEOUT +#define SD_SDMMC_SEND_IF_COND SD_SDIO_SEND_IF_COND +/* alias CMSIS */ +#define SDMMC1_IRQn SDIO_IRQn +#define SDMMC1_IRQHandler SDIO_IRQHandler +#endif + +#if defined(STM32F7) || defined(STM32L4) +#define SD_SDIO_DISABLED SD_SDMMC_DISABLED +#define SD_SDIO_FUNCTION_BUSY SD_SDMMC_FUNCTION_BUSY +#define SD_SDIO_FUNCTION_FAILED SD_SDMMC_FUNCTION_FAILED +#define SD_SDIO_UNKNOWN_FUNCTION SD_SDMMC_UNKNOWN_FUNCTION +#define SD_CMD_SDIO_SEN_OP_COND SD_CMD_SDMMC_SEN_OP_COND +#define SD_CMD_SDIO_RW_DIRECT SD_CMD_SDMMC_RW_DIRECT +#define SD_CMD_SDIO_RW_EXTENDED SD_CMD_SDMMC_RW_EXTENDED +#define __HAL_SD_SDIO_ENABLE __HAL_SD_SDMMC_ENABLE +#define __HAL_SD_SDIO_DISABLE __HAL_SD_SDMMC_DISABLE +#define __HAL_SD_SDIO_DMA_ENABLE __HAL_SD_SDMMC_DMA_ENABLE +#define __HAL_SD_SDIO_DMA_DISABL __HAL_SD_SDMMC_DMA_DISABLE +#define __HAL_SD_SDIO_ENABLE_IT __HAL_SD_SDMMC_ENABLE_IT +#define __HAL_SD_SDIO_DISABLE_IT __HAL_SD_SDMMC_DISABLE_IT +#define __HAL_SD_SDIO_GET_FLAG __HAL_SD_SDMMC_GET_FLAG +#define __HAL_SD_SDIO_CLEAR_FLAG __HAL_SD_SDMMC_CLEAR_FLAG +#define __HAL_SD_SDIO_GET_IT __HAL_SD_SDMMC_GET_IT +#define __HAL_SD_SDIO_CLEAR_IT __HAL_SD_SDMMC_CLEAR_IT +#define SDIO_STATIC_FLAGS SDMMC_STATIC_FLAGS +#define SDIO_CMD0TIMEOUT SDMMC_CMD0TIMEOUT +#define SD_SDIO_SEND_IF_COND SD_SDMMC_SEND_IF_COND +/* alias CMSIS for compatibilities */ +#define SDIO_IRQn SDMMC1_IRQn +#define SDIO_IRQHandler SDMMC1_IRQHandler +#endif + +#if defined(STM32F7) || defined(STM32F4) || defined(STM32F2) || defined(STM32L4) || defined(STM32H7) +#define HAL_SD_CardCIDTypedef HAL_SD_CardCIDTypeDef +#define HAL_SD_CardCSDTypedef HAL_SD_CardCSDTypeDef +#define HAL_SD_CardStatusTypedef HAL_SD_CardStatusTypeDef +#define HAL_SD_CardStateTypedef HAL_SD_CardStateTypeDef +#endif + +#if defined(STM32H7) || defined(STM32L5) +#define HAL_MMCEx_Read_DMADoubleBuffer0CpltCallback HAL_MMCEx_Read_DMADoubleBuf0CpltCallback +#define HAL_MMCEx_Read_DMADoubleBuffer1CpltCallback HAL_MMCEx_Read_DMADoubleBuf1CpltCallback +#define HAL_MMCEx_Write_DMADoubleBuffer0CpltCallback HAL_MMCEx_Write_DMADoubleBuf0CpltCallback +#define HAL_MMCEx_Write_DMADoubleBuffer1CpltCallback HAL_MMCEx_Write_DMADoubleBuf1CpltCallback +#define HAL_SDEx_Read_DMADoubleBuffer0CpltCallback HAL_SDEx_Read_DMADoubleBuf0CpltCallback +#define HAL_SDEx_Read_DMADoubleBuffer1CpltCallback HAL_SDEx_Read_DMADoubleBuf1CpltCallback +#define HAL_SDEx_Write_DMADoubleBuffer0CpltCallback HAL_SDEx_Write_DMADoubleBuf0CpltCallback +#define HAL_SDEx_Write_DMADoubleBuffer1CpltCallback HAL_SDEx_Write_DMADoubleBuf1CpltCallback +#define HAL_SD_DriveTransciver_1_8V_Callback HAL_SD_DriveTransceiver_1_8V_Callback +#endif +/** + * @} + */ + +/** @defgroup HAL_SMARTCARD_Aliased_Macros HAL SMARTCARD Aliased Macros maintained for legacy purpose + * @{ + */ + +#define __SMARTCARD_ENABLE_IT __HAL_SMARTCARD_ENABLE_IT +#define __SMARTCARD_DISABLE_IT __HAL_SMARTCARD_DISABLE_IT +#define __SMARTCARD_ENABLE __HAL_SMARTCARD_ENABLE +#define __SMARTCARD_DISABLE __HAL_SMARTCARD_DISABLE +#define __SMARTCARD_DMA_REQUEST_ENABLE __HAL_SMARTCARD_DMA_REQUEST_ENABLE +#define __SMARTCARD_DMA_REQUEST_DISABLE __HAL_SMARTCARD_DMA_REQUEST_DISABLE + +#define __HAL_SMARTCARD_GETCLOCKSOURCE SMARTCARD_GETCLOCKSOURCE +#define __SMARTCARD_GETCLOCKSOURCE SMARTCARD_GETCLOCKSOURCE + +#define IS_SMARTCARD_ONEBIT_SAMPLING IS_SMARTCARD_ONE_BIT_SAMPLE + +/** + * @} + */ + +/** @defgroup HAL_SMBUS_Aliased_Macros HAL SMBUS Aliased Macros maintained for legacy purpose + * @{ + */ +#define __HAL_SMBUS_RESET_CR1 SMBUS_RESET_CR1 +#define __HAL_SMBUS_RESET_CR2 SMBUS_RESET_CR2 +#define __HAL_SMBUS_GENERATE_START SMBUS_GENERATE_START +#define __HAL_SMBUS_GET_ADDR_MATCH SMBUS_GET_ADDR_MATCH +#define __HAL_SMBUS_GET_DIR SMBUS_GET_DIR +#define __HAL_SMBUS_GET_STOP_MODE SMBUS_GET_STOP_MODE +#define __HAL_SMBUS_GET_PEC_MODE SMBUS_GET_PEC_MODE +#define __HAL_SMBUS_GET_ALERT_ENABLED SMBUS_GET_ALERT_ENABLED +/** + * @} + */ + +/** @defgroup HAL_SPI_Aliased_Macros HAL SPI Aliased Macros maintained for legacy purpose + * @{ + */ + +#define __HAL_SPI_1LINE_TX SPI_1LINE_TX +#define __HAL_SPI_1LINE_RX SPI_1LINE_RX +#define __HAL_SPI_RESET_CRC SPI_RESET_CRC + +/** + * @} + */ + +/** @defgroup HAL_UART_Aliased_Macros HAL UART Aliased Macros maintained for legacy purpose + * @{ + */ + +#define __HAL_UART_GETCLOCKSOURCE UART_GETCLOCKSOURCE +#define __HAL_UART_MASK_COMPUTATION UART_MASK_COMPUTATION +#define __UART_GETCLOCKSOURCE UART_GETCLOCKSOURCE +#define __UART_MASK_COMPUTATION UART_MASK_COMPUTATION + +#define IS_UART_WAKEUPMETHODE IS_UART_WAKEUPMETHOD + +#define IS_UART_ONEBIT_SAMPLE IS_UART_ONE_BIT_SAMPLE +#define IS_UART_ONEBIT_SAMPLING IS_UART_ONE_BIT_SAMPLE + +/** + * @} + */ + + +/** @defgroup HAL_USART_Aliased_Macros HAL USART Aliased Macros maintained for legacy purpose + * @{ + */ + +#define __USART_ENABLE_IT __HAL_USART_ENABLE_IT +#define __USART_DISABLE_IT __HAL_USART_DISABLE_IT +#define __USART_ENABLE __HAL_USART_ENABLE +#define __USART_DISABLE __HAL_USART_DISABLE + +#define __HAL_USART_GETCLOCKSOURCE USART_GETCLOCKSOURCE +#define __USART_GETCLOCKSOURCE USART_GETCLOCKSOURCE + +#if defined(STM32F0) || defined(STM32F3) || defined(STM32F7) +#define USART_OVERSAMPLING_16 0x00000000U +#define USART_OVERSAMPLING_8 USART_CR1_OVER8 + +#define IS_USART_OVERSAMPLING(__SAMPLING__) (((__SAMPLING__) == USART_OVERSAMPLING_16) || \ + ((__SAMPLING__) == USART_OVERSAMPLING_8)) +#endif /* STM32F0 || STM32F3 || STM32F7 */ +/** + * @} + */ + +/** @defgroup HAL_USB_Aliased_Macros HAL USB Aliased Macros maintained for legacy purpose + * @{ + */ +#define USB_EXTI_LINE_WAKEUP USB_WAKEUP_EXTI_LINE + +#define USB_FS_EXTI_TRIGGER_RISING_EDGE USB_OTG_FS_WAKEUP_EXTI_RISING_EDGE +#define USB_FS_EXTI_TRIGGER_FALLING_EDGE USB_OTG_FS_WAKEUP_EXTI_FALLING_EDGE +#define USB_FS_EXTI_TRIGGER_BOTH_EDGE USB_OTG_FS_WAKEUP_EXTI_RISING_FALLING_EDGE +#define USB_FS_EXTI_LINE_WAKEUP USB_OTG_FS_WAKEUP_EXTI_LINE + +#define USB_HS_EXTI_TRIGGER_RISING_EDGE USB_OTG_HS_WAKEUP_EXTI_RISING_EDGE +#define USB_HS_EXTI_TRIGGER_FALLING_EDGE USB_OTG_HS_WAKEUP_EXTI_FALLING_EDGE +#define USB_HS_EXTI_TRIGGER_BOTH_EDGE USB_OTG_HS_WAKEUP_EXTI_RISING_FALLING_EDGE +#define USB_HS_EXTI_LINE_WAKEUP USB_OTG_HS_WAKEUP_EXTI_LINE + +#define __HAL_USB_EXTI_ENABLE_IT __HAL_USB_WAKEUP_EXTI_ENABLE_IT +#define __HAL_USB_EXTI_DISABLE_IT __HAL_USB_WAKEUP_EXTI_DISABLE_IT +#define __HAL_USB_EXTI_GET_FLAG __HAL_USB_WAKEUP_EXTI_GET_FLAG +#define __HAL_USB_EXTI_CLEAR_FLAG __HAL_USB_WAKEUP_EXTI_CLEAR_FLAG +#define __HAL_USB_EXTI_SET_RISING_EDGE_TRIGGER __HAL_USB_WAKEUP_EXTI_ENABLE_RISING_EDGE +#define __HAL_USB_EXTI_SET_FALLING_EDGE_TRIGGER __HAL_USB_WAKEUP_EXTI_ENABLE_FALLING_EDGE +#define __HAL_USB_EXTI_SET_FALLINGRISING_TRIGGER __HAL_USB_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE + +#define __HAL_USB_FS_EXTI_ENABLE_IT __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_IT +#define __HAL_USB_FS_EXTI_DISABLE_IT __HAL_USB_OTG_FS_WAKEUP_EXTI_DISABLE_IT +#define __HAL_USB_FS_EXTI_GET_FLAG __HAL_USB_OTG_FS_WAKEUP_EXTI_GET_FLAG +#define __HAL_USB_FS_EXTI_CLEAR_FLAG __HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG +#define __HAL_USB_FS_EXTI_SET_RISING_EGDE_TRIGGER __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_RISING_EDGE +#define __HAL_USB_FS_EXTI_SET_FALLING_EGDE_TRIGGER __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_FALLING_EDGE +#define __HAL_USB_FS_EXTI_SET_FALLINGRISING_TRIGGER __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE +#define __HAL_USB_FS_EXTI_GENERATE_SWIT __HAL_USB_OTG_FS_WAKEUP_EXTI_GENERATE_SWIT + +#define __HAL_USB_HS_EXTI_ENABLE_IT __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_IT +#define __HAL_USB_HS_EXTI_DISABLE_IT __HAL_USB_OTG_HS_WAKEUP_EXTI_DISABLE_IT +#define __HAL_USB_HS_EXTI_GET_FLAG __HAL_USB_OTG_HS_WAKEUP_EXTI_GET_FLAG +#define __HAL_USB_HS_EXTI_CLEAR_FLAG __HAL_USB_OTG_HS_WAKEUP_EXTI_CLEAR_FLAG +#define __HAL_USB_HS_EXTI_SET_RISING_EGDE_TRIGGER __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_RISING_EDGE +#define __HAL_USB_HS_EXTI_SET_FALLING_EGDE_TRIGGER __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_FALLING_EDGE +#define __HAL_USB_HS_EXTI_SET_FALLINGRISING_TRIGGER __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE +#define __HAL_USB_HS_EXTI_GENERATE_SWIT __HAL_USB_OTG_HS_WAKEUP_EXTI_GENERATE_SWIT + +#define HAL_PCD_ActiveRemoteWakeup HAL_PCD_ActivateRemoteWakeup +#define HAL_PCD_DeActiveRemoteWakeup HAL_PCD_DeActivateRemoteWakeup + +#define HAL_PCD_SetTxFiFo HAL_PCDEx_SetTxFiFo +#define HAL_PCD_SetRxFiFo HAL_PCDEx_SetRxFiFo +/** + * @} + */ + +/** @defgroup HAL_TIM_Aliased_Macros HAL TIM Aliased Macros maintained for legacy purpose + * @{ + */ +#define __HAL_TIM_SetICPrescalerValue TIM_SET_ICPRESCALERVALUE +#define __HAL_TIM_ResetICPrescalerValue TIM_RESET_ICPRESCALERVALUE + +#define TIM_GET_ITSTATUS __HAL_TIM_GET_IT_SOURCE +#define TIM_GET_CLEAR_IT __HAL_TIM_CLEAR_IT + +#define __HAL_TIM_GET_ITSTATUS __HAL_TIM_GET_IT_SOURCE + +#define __HAL_TIM_DIRECTION_STATUS __HAL_TIM_IS_TIM_COUNTING_DOWN +#define __HAL_TIM_PRESCALER __HAL_TIM_SET_PRESCALER +#define __HAL_TIM_SetCounter __HAL_TIM_SET_COUNTER +#define __HAL_TIM_GetCounter __HAL_TIM_GET_COUNTER +#define __HAL_TIM_SetAutoreload __HAL_TIM_SET_AUTORELOAD +#define __HAL_TIM_GetAutoreload __HAL_TIM_GET_AUTORELOAD +#define __HAL_TIM_SetClockDivision __HAL_TIM_SET_CLOCKDIVISION +#define __HAL_TIM_GetClockDivision __HAL_TIM_GET_CLOCKDIVISION +#define __HAL_TIM_SetICPrescaler __HAL_TIM_SET_ICPRESCALER +#define __HAL_TIM_GetICPrescaler __HAL_TIM_GET_ICPRESCALER +#define __HAL_TIM_SetCompare __HAL_TIM_SET_COMPARE +#define __HAL_TIM_GetCompare __HAL_TIM_GET_COMPARE + +#define TIM_BREAKINPUTSOURCE_DFSDM TIM_BREAKINPUTSOURCE_DFSDM1 +/** + * @} + */ + +/** @defgroup HAL_ETH_Aliased_Macros HAL ETH Aliased Macros maintained for legacy purpose + * @{ + */ + +#define __HAL_ETH_EXTI_ENABLE_IT __HAL_ETH_WAKEUP_EXTI_ENABLE_IT +#define __HAL_ETH_EXTI_DISABLE_IT __HAL_ETH_WAKEUP_EXTI_DISABLE_IT +#define __HAL_ETH_EXTI_GET_FLAG __HAL_ETH_WAKEUP_EXTI_GET_FLAG +#define __HAL_ETH_EXTI_CLEAR_FLAG __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG +#define __HAL_ETH_EXTI_SET_RISING_EGDE_TRIGGER __HAL_ETH_WAKEUP_EXTI_ENABLE_RISING_EDGE_TRIGGER +#define __HAL_ETH_EXTI_SET_FALLING_EGDE_TRIGGER __HAL_ETH_WAKEUP_EXTI_ENABLE_FALLING_EDGE_TRIGGER +#define __HAL_ETH_EXTI_SET_FALLINGRISING_TRIGGER __HAL_ETH_WAKEUP_EXTI_ENABLE_FALLINGRISING_TRIGGER + +#define ETH_PROMISCIOUSMODE_ENABLE ETH_PROMISCUOUS_MODE_ENABLE +#define ETH_PROMISCIOUSMODE_DISABLE ETH_PROMISCUOUS_MODE_DISABLE +#define IS_ETH_PROMISCIOUS_MODE IS_ETH_PROMISCUOUS_MODE +/** + * @} + */ + +/** @defgroup HAL_LTDC_Aliased_Macros HAL LTDC Aliased Macros maintained for legacy purpose + * @{ + */ +#define __HAL_LTDC_LAYER LTDC_LAYER +#define __HAL_LTDC_RELOAD_CONFIG __HAL_LTDC_RELOAD_IMMEDIATE_CONFIG +/** + * @} + */ + +/** @defgroup HAL_SAI_Aliased_Macros HAL SAI Aliased Macros maintained for legacy purpose + * @{ + */ +#define SAI_OUTPUTDRIVE_DISABLED SAI_OUTPUTDRIVE_DISABLE +#define SAI_OUTPUTDRIVE_ENABLED SAI_OUTPUTDRIVE_ENABLE +#define SAI_MASTERDIVIDER_ENABLED SAI_MASTERDIVIDER_ENABLE +#define SAI_MASTERDIVIDER_DISABLED SAI_MASTERDIVIDER_DISABLE +#define SAI_STREOMODE SAI_STEREOMODE +#define SAI_FIFOStatus_Empty SAI_FIFOSTATUS_EMPTY +#define SAI_FIFOStatus_Less1QuarterFull SAI_FIFOSTATUS_LESS1QUARTERFULL +#define SAI_FIFOStatus_1QuarterFull SAI_FIFOSTATUS_1QUARTERFULL +#define SAI_FIFOStatus_HalfFull SAI_FIFOSTATUS_HALFFULL +#define SAI_FIFOStatus_3QuartersFull SAI_FIFOSTATUS_3QUARTERFULL +#define SAI_FIFOStatus_Full SAI_FIFOSTATUS_FULL +#define IS_SAI_BLOCK_MONO_STREO_MODE IS_SAI_BLOCK_MONO_STEREO_MODE +#define SAI_SYNCHRONOUS_EXT SAI_SYNCHRONOUS_EXT_SAI1 +#define SAI_SYNCEXT_IN_ENABLE SAI_SYNCEXT_OUTBLOCKA_ENABLE +/** + * @} + */ + +/** @defgroup HAL_SPDIFRX_Aliased_Macros HAL SPDIFRX Aliased Macros maintained for legacy purpose + * @{ + */ +#if defined(STM32H7) +#define HAL_SPDIFRX_ReceiveControlFlow HAL_SPDIFRX_ReceiveCtrlFlow +#define HAL_SPDIFRX_ReceiveControlFlow_IT HAL_SPDIFRX_ReceiveCtrlFlow_IT +#define HAL_SPDIFRX_ReceiveControlFlow_DMA HAL_SPDIFRX_ReceiveCtrlFlow_DMA +#endif +/** + * @} + */ + +/** @defgroup HAL_HRTIM_Aliased_Functions HAL HRTIM Aliased Functions maintained for legacy purpose + * @{ + */ +#if defined (STM32H7) || defined (STM32G4) || defined (STM32F3) +#define HAL_HRTIM_WaveformCounterStart_IT HAL_HRTIM_WaveformCountStart_IT +#define HAL_HRTIM_WaveformCounterStart_DMA HAL_HRTIM_WaveformCountStart_DMA +#define HAL_HRTIM_WaveformCounterStart HAL_HRTIM_WaveformCountStart +#define HAL_HRTIM_WaveformCounterStop_IT HAL_HRTIM_WaveformCountStop_IT +#define HAL_HRTIM_WaveformCounterStop_DMA HAL_HRTIM_WaveformCountStop_DMA +#define HAL_HRTIM_WaveformCounterStop HAL_HRTIM_WaveformCountStop +#endif +/** + * @} + */ + +/** @defgroup HAL_QSPI_Aliased_Macros HAL QSPI Aliased Macros maintained for legacy purpose + * @{ + */ +#if defined (STM32L4) || defined (STM32F4) || defined (STM32F7) || defined(STM32H7) +#define HAL_QPSI_TIMEOUT_DEFAULT_VALUE HAL_QSPI_TIMEOUT_DEFAULT_VALUE +#endif /* STM32L4 || STM32F4 || STM32F7 */ +/** + * @} + */ + +/** @defgroup HAL_Generic_Aliased_Macros HAL Generic Aliased Macros maintained for legacy purpose + * @{ + */ +#if defined (STM32F7) +#define ART_ACCLERATOR_ENABLE ART_ACCELERATOR_ENABLE +#endif /* STM32F7 */ +/** + * @} + */ + +/** @defgroup HAL_PPP_Aliased_Macros HAL PPP Aliased Macros maintained for legacy purpose + * @{ + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32_HAL_LEGACY */ + + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32_assert_template.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32_assert_template.h new file mode 100644 index 0000000000..a59b9495ff --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32_assert_template.h @@ -0,0 +1,54 @@ +/** + ****************************************************************************** + * @file stm32_assert.h + * @author MCD Application Team + * @brief STM32 assert template file. + * This file should be copied to the application folder and renamed + * to stm32_assert.h. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32_ASSERT_H +#define __STM32_ASSERT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Includes ------------------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ +#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ +void assert_failed(uint8_t *file, uint32_t line); +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_ASSERT_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal.h new file mode 100644 index 0000000000..7cd8a40a77 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal.h @@ -0,0 +1,897 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal.h + * @author MCD Application Team + * @brief This file contains all the functions prototypes for the HAL + * module driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32H5xx_HAL_H +#define __STM32H5xx_HAL_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_conf.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup HAL + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup HAL_Exported_Types HAL Exported Types + * @{ + */ + +/** @defgroup HAL_TICK_FREQ Tick Frequency + * @{ + */ +typedef enum +{ + HAL_TICK_FREQ_10HZ = 100U, + HAL_TICK_FREQ_100HZ = 10U, + HAL_TICK_FREQ_1KHZ = 1U, + HAL_TICK_FREQ_DEFAULT = HAL_TICK_FREQ_1KHZ +} HAL_TickFreqTypeDef; +/** + * @} + */ + +/** + * @} + */ + +/* Exported variables --------------------------------------------------------*/ +/** @defgroup HAL_Exported_Variables HAL Exported Variables + * @{ + */ +extern __IO uint32_t uwTick; +extern uint32_t uwTickPrio; +extern HAL_TickFreqTypeDef uwTickFreq; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup SBS_Exported_Constants SBS Exported Constants + * @{ + */ + +/** @defgroup SBS_FPU_Interrupts FPU Interrupts + * @{ + */ +#define SBS_IT_FPU_IOC SBS_FPUIMR_FPU_IE_0 /*!< Floating Point Unit Invalid operation Interrupt */ +#define SBS_IT_FPU_DZC SBS_FPUIMR_FPU_IE_1 /*!< Floating Point Unit Divide-by-zero Interrupt */ +#define SBS_IT_FPU_UFC SBS_FPUIMR_FPU_IE_2 /*!< Floating Point Unit Underflow Interrupt */ +#define SBS_IT_FPU_OFC SBS_FPUIMR_FPU_IE_3 /*!< Floating Point Unit Overflow Interrupt */ +#define SBS_IT_FPU_IDC SBS_FPUIMR_FPU_IE_4 /*!< Floating Point Unit Input denormal Interrupt */ +#define SBS_IT_FPU_IXC SBS_FPUIMR_FPU_IE_5 /*!< Floating Point Unit Inexact Interrupt */ + +/** + * @} + */ + +/** @defgroup SBS_BREAK_CONFIG SBS Break Config + * @{ + */ +#define SBS_BREAK_FLASH_ECC SBS_CFGR2_ECCL /*!< Enable and lock the FLASH ECC double error with TIM1/8/15/16/17 + Break inputs.*/ +#define SBS_BREAK_PVD SBS_CFGR2_PVDL /*!< Enable and lock the PVD connection with TIM1/8/15/16/17 + Break inputs. */ +#define SBS_BREAK_SRAM_ECC SBS_CFGR2_SEL /*!< Enable and lock the SRAM ECC double error signal with + TIM1/8/15/16/17 Break inputs.*/ +#define SBS_BREAK_LOCKUP SBS_CFGR2_CLL /*!< Enable and lock the connection of Cortex-M33 LOCKUP (hardfault) + output to TIM1/8/15/16/17 Break inputs.*/ + +/** + * @} + */ + +#if defined(VREFBUF) +/** @defgroup VREFBUF_VoltageScale VREFBUF Voltage Scale + * @{ + */ +#define VREFBUF_VOLTAGE_SCALE0 ((uint32_t)0x00000000) /*!< Voltage reference scale 0 (VREF_OUT1) */ +#define VREFBUF_VOLTAGE_SCALE1 VREFBUF_CSR_VRS_0 /*!< Voltage reference scale 1 (VREF_OUT2) */ +#define VREFBUF_VOLTAGE_SCALE2 VREFBUF_CSR_VRS_1 /*!< Voltage reference scale 2 (VREF_OUT3) */ +#define VREFBUF_VOLTAGE_SCALE3 (VREFBUF_CSR_VRS_0 | VREFBUF_CSR_VRS_1) /*!< Voltage reference scale 3 (VREF_OUT4) */ + +/** + * @} + */ + +/** @defgroup VREFBUF_HighImpedance VREFBUF High Impedance + * @{ + */ +#define VREFBUF_HIGH_IMPEDANCE_DISABLE ((uint32_t)0x00000000) /*!< VREF_plus pin is internally connected to + Voltage reference buffer output */ +#define VREFBUF_HIGH_IMPEDANCE_ENABLE VREFBUF_CSR_HIZ /*!< VREF_plus pin is high impedance */ + +/** + * @} + */ +#endif /* VREFBUF */ + +/** @defgroup SBS_FastModePlus_GPIO Fast-mode Plus on GPIO + * @{ + */ + +/** @brief Fast-mode Plus driving capability on a specific GPIO + */ +#define SBS_FASTMODEPLUS_PB6 SBS_PMCR_PB6_FMP /*!< Enable Fast-mode Plus on PB6 */ +#define SBS_FASTMODEPLUS_PB7 SBS_PMCR_PB7_FMP /*!< Enable Fast-mode Plus on PB7 */ +#define SBS_FASTMODEPLUS_PB8 SBS_PMCR_PB8_FMP /*!< Enable Fast-mode Plus on PB8 */ +#if defined(SBS_PMCR_PB9_FMP) +#define SBS_FASTMODEPLUS_PB9 SBS_PMCR_PB9_FMP /*!< Enable Fast-mode Plus on PB9 */ +#endif /* SBS_PMCR_PB9_FMP */ + +/** + * @} + */ + +#if defined(SBS_PMCR_ETH_SEL_PHY) +/** @defgroup SBS_Ethernet_Config Ethernet Config + * @{ + */ +#define SBS_ETH_MII ((uint32_t)0x00000000) /*!< Select the Media Independent Interface (MII) or GMII */ +#define SBS_ETH_RMII SBS_PMCR_ETH_SEL_PHY_2 /*!< Select the Reduced Media Independent Interface (RMII) */ + +#define IS_SBS_ETHERNET_CONFIG(CONFIG) (((CONFIG) == SBS_ETH_MII) || \ + ((CONFIG) == SBS_ETH_RMII)) + +/** + * @} + */ +#endif /* SBS_PMCR_ETH_SEL_PHY */ + +/** @defgroup SBS_Memories_Erase_Flag_Status Memory Erase Flags Status + * @{ + */ +#define SBS_MEMORIES_ERASE_FLAG_IPMEE SBS_MESR_IPMEE /*!< Select the Status of End Of Erase for ICACHE + and PKA RAMs */ +#define SBS_MEMORIES_ERASE_FLAG_MCLR SBS_MESR_MCLR /*!< Select the Status of Erase after Power-on Reset + (SRAM2, BKPRAM, ICACHE, DCACHE, PKA rams) */ + +#define IS_SBS_MEMORIES_ERASE_FLAG(FLAG) (((FLAG) == SBS_MEMORIES_ERASE_FLAG_IPMEE) || \ + ((FLAG) == SBS_MEMORIES_ERASE_FLAG_MCLR)) + +/** + * @} + */ + +/** @defgroup SBS_IOCompenstionCell_Config IOCompenstionCell Config + * @{ + */ +#define SBS_VDD_CELL_CODE ((uint32_t)0x00000000) /*!< Select Code from the cell */ +#define SBS_VDD_REGISTER_CODE SBS_CCCSR_CS1 /*!< Code from the SBS compensation cell code register */ + +#define IS_SBS_VDD_CODE_SELECT(SELECT) (((SELECT) == SBS_VDD_CELL_CODE)|| \ + ((SELECT) == SBS_VDD_REGISTER_CODE)) + +#define SBS_VDDIO_CELL_CODE ((uint32_t)0x00000000) /*!< Select Code from the cell */ +#define SBS_VDDIO_REGISTER_CODE SBS_CCCSR_CS2 /*!< Code from the SBS compensation cell code register */ + +#define IS_SBS_VDDIO_CODE_SELECT(SELECT) (((SELECT) == SBS_VDDIO_CELL_CODE)|| \ + ((SELECT) == SBS_VDDIO_REGISTER_CODE)) + +#define IS_SBS_CODE_CONFIG(CONFIG) ((CONFIG) < (0x10UL)) + +/** + * @} + */ + +#if defined(SBS_EPOCHSELCR_EPOCH_SEL) +/** @defgroup SBS_EPOCH_Selection EPOCH Selection + * @{ + */ +#define SBS_EPOCH_SEL_SECURE 0x0UL /*!< EPOCH secure selected */ +#define SBS_EPOCH_SEL_NONSECURE SBS_EPOCHSELCR_EPOCH_SEL_0 /*!< EPOCH non secure selected */ +#define SBS_EPOCH_SEL_PUFCHECK SBS_EPOCHSELCR_EPOCH_SEL_1 /*!< EPOCH all zeros for PUF integrity check */ + +#define IS_SBS_EPOCH_SELECTION(SELECT) (((SELECT) == SBS_EPOCH_SEL_SECURE) || \ + ((SELECT) == SBS_EPOCH_SEL_NONSECURE) || \ + ((SELECT) == SBS_EPOCH_SEL_PUFCHECK)) +/** + * @} + */ +#endif /* SBS_EPOCHSELCR_EPOCH_SEL */ + +#if defined(SBS_NEXTHDPLCR_NEXTHDPL) +/** @defgroup SBS_NextHDPL_Selection Next HDPL Selection + * @{ + */ +#define SBS_OBKHDPL_INCR_0 0x00U /*!< Index to add to the current HDPL to point (through OBK-HDPL) to the next secure storage areas */ +#define SBS_OBKHDPL_INCR_1 SBS_NEXTHDPLCR_NEXTHDPL_0 /*!< Index to add to the current HDPL to point (through OBK-HDPL) to the next secure storage areas */ +#define SBS_OBKHDPL_INCR_2 SBS_NEXTHDPLCR_NEXTHDPL_1 /*!< Index to add to the current HDPL to point (through OBK-HDPL) to the next secure storage areas */ +#define SBS_OBKHDPL_INCR_3 SBS_NEXTHDPLCR_NEXTHDPL /*!< Index to add to the current HDPL to point (through OBK-HDPL) to the next secure storage areas */ +/** + * @} + */ +#endif /* SBS_NEXTHDPLCR_NEXTHDPL */ + +/** @defgroup SBS_HDPL_Value HDPL Value + * @{ + */ +#define SBS_HDPL_VALUE_0 0x000000B4U /*!< Hide protection level 0 */ +#define SBS_HDPL_VALUE_1 0x00000051U /*!< Hide protection level 0 */ +#define SBS_HDPL_VALUE_2 0x0000008AU /*!< Hide protection level 0 */ +#define SBS_HDPL_VALUE_3 0x0000006FU /*!< Hide protection level 0 */ +/** + * @} + */ + +#if defined(SBS_DBGCR_DBG_AUTH_SEC) +/** @defgroup SBS_DEBUG_SEC_Value Debug sec Value + * @{ + */ +#define SBS_DEBUG_SEC_NSEC 0x000000B4U /*!< Debug opening for secure and non-secure */ +#define SBS_DEBUG_NSEC 0x0000003CU /*!< Debug opening for non-secure only */ +/** + * @} + */ +#endif /* SBS_DBGCR_DBG_AUTH_SEC */ + +/** @defgroup SBS_Lock_items SBS Lock items + * @brief SBS items to set lock on + * @{ + */ +#define SBS_MPU_NSEC SBS_CNSLCKR_LOCKNSMPU /*!< Non-secure MPU lock (privileged secure or + non-secure only) */ +#define SBS_VTOR_NSEC SBS_CNSLCKR_LOCKNSVTOR /*!< Non-secure VTOR lock (privileged secure or + non-secure only) */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define SBS_SAU (SBS_CSLCKR_LOCKSAU << 16U) /*!< SAU lock (privileged secure code only) */ +#define SBS_MPU_SEC (SBS_CSLCKR_LOCKSMPU << 16U) /*!< Secure MPU lock (privileged secure code only) + */ +#define SBS_VTOR_AIRCR_SEC (SBS_CSLCKR_LOCKSVTAIRCR << 16U) /*!< VTOR_S and AIRCR lock (privileged secure + code only) */ +#define SBS_LOCK_ALL (SBS_MPU_NSEC|SBS_VTOR_NSEC|SBS_SAU|SBS_MPU_SEC|SBS_VTOR_AIRCR_SEC) /*!< All */ +#else +#define SBS_LOCK_ALL (SBS_MPU_NSEC|SBS_VTOR_NSEC) /*!< All (privileged secure or non-secure only) */ +#endif /* __ARM_FEATURE_CMSE */ +/** + * @} + */ + +/** @defgroup SBS_Attributes_items SBS Attributes items + * @brief SBS items to configure secure or non-secure attributes on + * @{ + */ +#define SBS_CLK SBS_SECCFGR_SBSSEC /*!< SBS clock control */ +#define SBS_CLASSB SBS_SECCFGR_CLASSBSEC /*!< Class B */ +#define SBS_FPU SBS_SECCFGR_FPUSEC /*!< FPU */ +#define SBS_SMPS SBS_SECCFGR_SDCE_SEC_EN /*!< SMPS */ +#define SBS_ALL (SBS_CLK | SBS_CLASSB | SBS_FPU | SBS_SMPS) /*!< All */ +/** + * @} + */ + +/** @defgroup SBS_attributes SBS attributes + * @brief SBS secure or non-secure attributes + * @{ + */ +#define SBS_SEC 0x00000001U /*!< Secure attribute */ +#define SBS_NSEC 0x00000000U /*!< Non-secure attribute */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ + +/** @defgroup DBGMCU_Exported_Macros DBGMCU Exported Macros + * @{ + */ + +/** @brief Freeze/Unfreeze Peripherals in Debug mode + */ +#if defined(DBGMCU_APB1FZR1_DBG_TIM2_STOP) +#define __HAL_DBGMCU_FREEZE_TIM2() SET_BIT(DBGMCU->APB1FZR1, DBGMCU_APB1FZR1_DBG_TIM2_STOP) +#define __HAL_DBGMCU_UNFREEZE_TIM2() CLEAR_BIT(DBGMCU->APB1FZR1, DBGMCU_APB1FZR1_DBG_TIM2_STOP) +#endif /* DBGMCU_APB1FZR1_DBG_TIM2_STOP */ + +#if defined(DBGMCU_APB1FZR1_DBG_TIM3_STOP) +#define __HAL_DBGMCU_FREEZE_TIM3() SET_BIT(DBGMCU->APB1FZR1, DBGMCU_APB1FZR1_DBG_TIM3_STOP) +#define __HAL_DBGMCU_UNFREEZE_TIM3() CLEAR_BIT(DBGMCU->APB1FZR1, DBGMCU_APB1FZR1_DBG_TIM3_STOP) +#endif /* DBGMCU_APB1FZR1_DBG_TIM3_STOP */ + +#if defined(DBGMCU_APB1FZR1_DBG_TIM4_STOP) +#define __HAL_DBGMCU_FREEZE_TIM4() SET_BIT(DBGMCU->APB1FZR1, DBGMCU_APB1FZR1_DBG_TIM4_STOP) +#define __HAL_DBGMCU_UNFREEZE_TIM4() CLEAR_BIT(DBGMCU->APB1FZR1, DBGMCU_APB1FZR1_DBG_TIM4_STOP) +#endif /* DBGMCU_APB1FZR1_DBG_TIM4_STOP */ + +#if defined(DBGMCU_APB1FZR1_DBG_TIM4_STOP) +#define __HAL_DBGMCU_FREEZE_TIM5() SET_BIT(DBGMCU->APB1FZR1, DBGMCU_APB1FZR1_DBG_TIM5_STOP) +#define __HAL_DBGMCU_UNFREEZE_TIM5() CLEAR_BIT(DBGMCU->APB1FZR1, DBGMCU_APB1FZR1_DBG_TIM5_STOP) +#endif /* DBGMCU_APB1FZR1_DBG_TIM4_STOP */ + +#if defined(DBGMCU_APB1FZR1_DBG_TIM6_STOP) +#define __HAL_DBGMCU_FREEZE_TIM6() SET_BIT(DBGMCU->APB1FZR1, DBGMCU_APB1FZR1_DBG_TIM6_STOP) +#define __HAL_DBGMCU_UNFREEZE_TIM6() CLEAR_BIT(DBGMCU->APB1FZR1, DBGMCU_APB1FZR1_DBG_TIM6_STOP) +#endif /* DBGMCU_APB1FZR1_DBG_TIM6_STOP */ + +#if defined(DBGMCU_APB1FZR1_DBG_TIM7_STOP) +#define __HAL_DBGMCU_FREEZE_TIM7() SET_BIT(DBGMCU->APB1FZR1, DBGMCU_APB1FZR1_DBG_TIM7_STOP) +#define __HAL_DBGMCU_UNFREEZE_TIM7() CLEAR_BIT(DBGMCU->APB1FZR1, DBGMCU_APB1FZR1_DBG_TIM7_STOP) +#endif /* DBGMCU_APB1FZR1_DBG_TIM7_STOP */ + +#if defined(DBGMCU_APB1FZR1_DBG_TIM12_STOP) +#define __HAL_DBGMCU_FREEZE_TIM12() SET_BIT(DBGMCU->APB1FZR1, DBGMCU_APB1FZR1_DBG_TIM12_STOP) +#define __HAL_DBGMCU_UNFREEZE_TIM12() CLEAR_BIT(DBGMCU->APB1FZR1, DBGMCU_APB1FZR1_DBG_TIM12_STOP) +#endif /* DBGMCU_APB1FZR1_DBG_TIM12_STOP */ + +#if defined(DBGMCU_APB1FZR1_DBG_TIM13_STOP) +#define __HAL_DBGMCU_FREEZE_TIM13() SET_BIT(DBGMCU->APB1FZR1, DBGMCU_APB1FZR1_DBG_TIM13_STOP) +#define __HAL_DBGMCU_UNFREEZE_TIM13() CLEAR_BIT(DBGMCU->APB1FZR1, DBGMCU_APB1FZR1_DBG_TIM13_STOP) +#endif /* DBGMCU_APB1FZR1_DBG_TIM13_STOP */ + +#if defined(DBGMCU_APB1FZR1_DBG_TIM14_STOP) +#define __HAL_DBGMCU_FREEZE_TIM14() SET_BIT(DBGMCU->APB1FZR1, DBGMCU_APB1FZR1_DBG_TIM14_STOP) +#define __HAL_DBGMCU_UNFREEZE_TIM14() CLEAR_BIT(DBGMCU->APB1FZR1, DBGMCU_APB1FZR1_DBG_TIM14_STOP) +#endif /* DBGMCU_APB1FZR1_DBG_TIM14_STOP */ + +#if defined(DBGMCU_APB1FZR1_DBG_WWDG_STOP) +#define __HAL_DBGMCU_FREEZE_WWDG() SET_BIT(DBGMCU->APB1FZR1, DBGMCU_APB1FZR1_DBG_WWDG_STOP) +#define __HAL_DBGMCU_UNFREEZE_WWDG() CLEAR_BIT(DBGMCU->APB1FZR1, DBGMCU_APB1FZR1_DBG_WWDG_STOP) +#endif /* DBGMCU_APB1FZR1_DBG_WWDG_STOP */ + +#if defined(DBGMCU_APB1FZR1_DBG_IWDG_STOP) +#define __HAL_DBGMCU_FREEZE_IWDG() SET_BIT(DBGMCU->APB1FZR1, DBGMCU_APB1FZR1_DBG_IWDG_STOP) +#define __HAL_DBGMCU_UNFREEZE_IWDG() CLEAR_BIT(DBGMCU->APB1FZR1, DBGMCU_APB1FZR1_DBG_IWDG_STOP) +#endif /* DBGMCU_APB1FZR1_DBG_IWDG_STOP */ + +#if defined(DBGMCU_APB1FZR1_DBG_I2C1_STOP) +#define __HAL_DBGMCU_FREEZE_I2C1() SET_BIT(DBGMCU->APB1FZR1, DBGMCU_APB1FZR1_DBG_I2C1_STOP) +#define __HAL_DBGMCU_UNFREEZE_I2C1() CLEAR_BIT(DBGMCU->APB1FZR1, DBGMCU_APB1FZR1_DBG_I2C1_STOP) +#endif /* DBGMCU_APB1FZR1_DBG_I2C1_STOP */ + +#if defined(DBGMCU_APB1FZR1_DBG_I2C2_STOP) +#define __HAL_DBGMCU_FREEZE_I2C2() SET_BIT(DBGMCU->APB1FZR1, DBGMCU_APB1FZR1_DBG_I2C2_STOP) +#define __HAL_DBGMCU_UNFREEZE_I2C2() CLEAR_BIT(DBGMCU->APB1FZR1, DBGMCU_APB1FZR1_DBG_I2C2_STOP) +#endif /* DBGMCU_APB1FZR1_DBG_I2C2_STOP */ + +#if defined(DBGMCU_APB1FZR1_DBG_I3C1_STOP) +#define __HAL_DBGMCU_FREEZE_I3C1() SET_BIT(DBGMCU->APB1FZR1, DBGMCU_APB1FZR1_DBG_I3C1_STOP) +#define __HAL_DBGMCU_UNFREEZE_I3C1() CLEAR_BIT(DBGMCU->APB1FZR1, DBGMCU_APB1FZR1_DBG_I3C1_STOP) +#endif /* DBGMCU_APB1FZR1_DBG_I3C1_STOP */ + +#if defined(DBGMCU_APB1FZR2_DBG_LPTIM2_STOP) +#define __HAL_DBGMCU_FREEZE_LPTIM2() SET_BIT(DBGMCU->APB1FZR2, DBGMCU_APB1FZR2_DBG_LPTIM2_STOP) +#define __HAL_DBGMCU_UNFREEZE_LPTIM2() CLEAR_BIT(DBGMCU->APB1FZR2, DBGMCU_APB1FZR2_DBG_LPTIM2_STOP) +#endif /* DBGMCU_APB1FZR2_DBG_LPTIM2_STOP */ + +#if defined(DBGMCU_APB2FZR_DBG_TIM1_STOP) +#define __HAL_DBGMCU_FREEZE_TIM1() SET_BIT(DBGMCU->APB2FZR, DBGMCU_APB2FZR_DBG_TIM1_STOP) +#define __HAL_DBGMCU_UNFREEZE_TIM1() CLEAR_BIT(DBGMCU->APB2FZR, DBGMCU_APB2FZR_DBG_TIM1_STOP) +#endif /* DBGMCU_APB2FZR_DBG_TIM1_STOP */ + +#if defined(DBGMCU_APB2FZR_DBG_TIM8_STOP) +#define __HAL_DBGMCU_FREEZE_TIM8() SET_BIT(DBGMCU->APB2FZR, DBGMCU_APB2FZR_DBG_TIM8_STOP) +#define __HAL_DBGMCU_UNFREEZE_TIM8() CLEAR_BIT(DBGMCU->APB2FZR, DBGMCU_APB2FZR_DBG_TIM8_STOP) +#endif /* DBGMCU_APB2FZR_DBG_TIM8_STOP */ + +#if defined(DBGMCU_APB2FZR_DBG_TIM15_STOP) +#define __HAL_DBGMCU_FREEZE_TIM15() SET_BIT(DBGMCU->APB2FZR, DBGMCU_APB2FZR_DBG_TIM15_STOP) +#define __HAL_DBGMCU_UNFREEZE_TIM15() CLEAR_BIT(DBGMCU->APB2FZR, DBGMCU_APB2FZR_DBG_TIM15_STOP) +#endif /* DBGMCU_APB2FZR_DBG_TIM15_STOP */ + +#if defined(DBGMCU_APB2FZR_DBG_TIM16_STOP) +#define __HAL_DBGMCU_FREEZE_TIM16() SET_BIT(DBGMCU->APB2FZR, DBGMCU_APB2FZR_DBG_TIM16_STOP) +#define __HAL_DBGMCU_UNFREEZE_TIM16() CLEAR_BIT(DBGMCU->APB2FZR, DBGMCU_APB2FZR_DBG_TIM16_STOP) +#endif /* DBGMCU_APB2FZR_DBG_TIM16_STOP */ + +#if defined(DBGMCU_APB2FZR_DBG_TIM17_STOP) +#define __HAL_DBGMCU_FREEZE_TIM17() SET_BIT(DBGMCU->APB2FZR, DBGMCU_APB2FZR_DBG_TIM17_STOP) +#define __HAL_DBGMCU_UNFREEZE_TIM17() CLEAR_BIT(DBGMCU->APB2FZR, DBGMCU_APB2FZR_DBG_TIM17_STOP) +#endif /* DBGMCU_APB2FZR_DBG_TIM17_STOP */ + +#if defined(DBGMCU_APB3FZR_DBG_I2C3_STOP) +#define __HAL_DBGMCU_FREEZE_I2C3() SET_BIT(DBGMCU->APB3FZR, DBGMCU_APB3FZR_DBG_I2C3_STOP) +#define __HAL_DBGMCU_UNFREEZE_I2C3() CLEAR_BIT(DBGMCU->APB3FZR, DBGMCU_APB3FZR_DBG_I2C3_STOP) +#endif /* DBGMCU_APB3FZR_DBG_I2C3_STOP */ + +#if defined(DBGMCU_APB3FZR_DBG_I2C4_STOP) +#define __HAL_DBGMCU_FREEZE_I2C4() SET_BIT(DBGMCU->APB3FZR, DBGMCU_APB3FZR_DBG_I2C4_STOP) +#define __HAL_DBGMCU_UNFREEZE_I2C4() CLEAR_BIT(DBGMCU->APB3FZR, DBGMCU_APB3FZR_DBG_I2C4_STOP) +#endif /* DBGMCU_APB3FZR_DBG_I2C4_STOP */ + +#if defined(DBGMCU_APB3FZR_DBG_I3C2_STOP) +#define __HAL_DBGMCU_FREEZE_I3C2() SET_BIT(DBGMCU->APB3FZR, DBGMCU_APB3FZR_DBG_I3C2_STOP) +#define __HAL_DBGMCU_UNFREEZE_I3C2() CLEAR_BIT(DBGMCU->APB3FZR, DBGMCU_APB3FZR_DBG_I3C2_STOP) +#endif /* DBGMCU_APB3FZR_DBG_I3C2_STOP */ + +#if defined(DBGMCU_APB3FZR_DBG_LPTIM1_STOP) +#define __HAL_DBGMCU_FREEZE_LPTIM1() SET_BIT(DBGMCU->APB3FZR, DBGMCU_APB3FZR_DBG_LPTIM1_STOP) +#define __HAL_DBGMCU_UNFREEZE_LPTIM1() CLEAR_BIT(DBGMCU->APB3FZR, DBGMCU_APB3FZR_DBG_LPTIM1_STOP) +#endif /* DBGMCU_APB3FZR_DBG_LPTIM1_STOP */ + +#if defined(DBGMCU_APB3FZR_DBG_LPTIM3_STOP) +#define __HAL_DBGMCU_FREEZE_LPTIM3() SET_BIT(DBGMCU->APB3FZR, DBGMCU_APB3FZR_DBG_LPTIM3_STOP) +#define __HAL_DBGMCU_UNFREEZE_LPTIM3() CLEAR_BIT(DBGMCU->APB3FZR, DBGMCU_APB3FZR_DBG_LPTIM3_STOP) +#endif /* DBGMCU_APB3FZR_DBG_LPTIM3_STOP */ + +#if defined(DBGMCU_APB3FZR_DBG_LPTIM4_STOP) +#define __HAL_DBGMCU_FREEZE_LPTIM4() SET_BIT(DBGMCU->APB3FZR, DBGMCU_APB3FZR_DBG_LPTIM4_STOP) +#define __HAL_DBGMCU_UNFREEZE_LPTIM4() CLEAR_BIT(DBGMCU->APB3FZR, DBGMCU_APB3FZR_DBG_LPTIM4_STOP) +#endif /* DBGMCU_APB3FZR_DBG_LPTIM4_STOP */ + +#if defined(DBGMCU_APB3FZR_DBG_LPTIM5_STOP) +#define __HAL_DBGMCU_FREEZE_LPTIM5() SET_BIT(DBGMCU->APB3FZR, DBGMCU_APB3FZR_DBG_LPTIM5_STOP) +#define __HAL_DBGMCU_UNFREEZE_LPTIM5() CLEAR_BIT(DBGMCU->APB3FZR, DBGMCU_APB3FZR_DBG_LPTIM5_STOP) +#endif /* DBGMCU_APB3FZR_DBG_LPTIM5_STOP */ + +#if defined(DBGMCU_APB3FZR_DBG_LPTIM6_STOP) +#define __HAL_DBGMCU_FREEZE_LPTIM6() SET_BIT(DBGMCU->APB3FZR, DBGMCU_APB3FZR_DBG_LPTIM6_STOP) +#define __HAL_DBGMCU_UNFREEZE_LPTIM6() CLEAR_BIT(DBGMCU->APB3FZR, DBGMCU_APB3FZR_DBG_LPTIM6_STOP) +#endif /* DBGMCU_APB3FZR_DBG_LPTIM6_STOP */ + +#if defined(DBGMCU_APB3FZR_DBG_RTC_STOP) +#define __HAL_DBGMCU_FREEZE_RTC() SET_BIT(DBGMCU->APB3FZR, DBGMCU_APB3FZR_DBG_RTC_STOP) +#define __HAL_DBGMCU_UNFREEZE_RTC() CLEAR_BIT(DBGMCU->APB3FZR, DBGMCU_APB3FZR_DBG_RTC_STOP) +#endif /* DBGMCU_APB3FZR_DBG_RTC_STOP */ + +#if defined(DBGMCU_AHB1FZR_DBG_GPDMA1_CH0_STOP) +#define __HAL_DBGMCU_FREEZE_GPDMA1_0() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA1_CH0_STOP) +#define __HAL_DBGMCU_UNFREEZE_GPDMA1_0() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA1_CH0_STOP) +#endif /* DBGMCU_AHB1FZR_DBG_GPDMA1_CH0_STOP */ + +#if defined(DBGMCU_AHB1FZR_DBG_GPDMA1_CH1_STOP) +#define __HAL_DBGMCU_FREEZE_GPDMA1_1() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA1_CH1_STOP) +#define __HAL_DBGMCU_UNFREEZE_GPDMA1_1() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA1_CH1_STOP) +#endif /* DBGMCU_AHB1FZR_DBG_GPDMA1_CH1_STOP */ + +#if defined(DBGMCU_AHB1FZR_DBG_GPDMA1_CH2_STOP) +#define __HAL_DBGMCU_FREEZE_GPDMA1_2() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA1_CH2_STOP) +#define __HAL_DBGMCU_UNFREEZE_GPDMA1_2() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA1_CH2_STOP) +#endif /* DBGMCU_AHB1FZR_DBG_GPDMA1_CH2_STOP */ + +#if defined(DBGMCU_AHB1FZR_DBG_GPDMA1_CH3_STOP) +#define __HAL_DBGMCU_FREEZE_GPDMA1_3() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA1_CH3_STOP) +#define __HAL_DBGMCU_UNFREEZE_GPDMA1_3() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA1_CH3_STOP) +#endif /* DBGMCU_AHB1FZR_DBG_GPDMA1_CH3_STOP */ + +#if defined(DBGMCU_AHB1FZR_DBG_GPDMA1_CH4_STOP) +#define __HAL_DBGMCU_FREEZE_GPDMA1_4() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA1_CH4_STOP) +#define __HAL_DBGMCU_UNFREEZE_GPDMA1_4() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA1_CH4_STOP) +#endif /* DBGMCU_AHB1FZR_DBG_GPDMA1_CH4_STOP */ + +#if defined(DBGMCU_AHB1FZR_DBG_GPDMA1_CH5_STOP) +#define __HAL_DBGMCU_FREEZE_GPDMA1_5() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA1_CH5_STOP) +#define __HAL_DBGMCU_UNFREEZE_GPDMA1_5() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA1_CH5_STOP) +#endif /* DBGMCU_AHB1FZR_DBG_GPDMA1_CH5_STOP */ + +#if defined(DBGMCU_AHB1FZR_DBG_GPDMA1_CH6_STOP) +#define __HAL_DBGMCU_FREEZE_GPDMA1_6() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA1_CH6_STOP) +#define __HAL_DBGMCU_UNFREEZE_GPDMA1_6() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA1_CH6_STOP) +#endif /* DBGMCU_AHB1FZR_DBG_GPDMA1_CH6_STOP */ + +#if defined(DBGMCU_AHB1FZR_DBG_GPDMA1_CH7_STOP) +#define __HAL_DBGMCU_FREEZE_GPDMA1_7() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA1_CH7_STOP) +#define __HAL_DBGMCU_UNFREEZE_GPDMA1_7() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA1_CH7_STOP) +#endif /* DBGMCU_AHB1FZR_DBG_GPDMA1_CH7_STOP */ + +#if defined(DBGMCU_AHB1FZR_DBG_GPDMA2_CH0_STOP) +#define __HAL_DBGMCU_FREEZE_GPDMA2_0() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA2_CH0_STOP) +#define __HAL_DBGMCU_UNFREEZE_GPDMA2_0() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA2_CH0_STOP) +#endif /* DBGMCU_AHB1FZR_DBG_GPDMA2_CH0_STOP */ + +#if defined(DBGMCU_AHB1FZR_DBG_GPDMA2_CH1_STOP) +#define __HAL_DBGMCU_FREEZE_GPDMA2_1() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA2_CH1_STOP) +#define __HAL_DBGMCU_UNFREEZE_GPDMA2_1() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA2_CH1_STOP) +#endif /* DBGMCU_AHB1FZR_DBG_GPDMA2_CH1_STOP */ + +#if defined(DBGMCU_AHB1FZR_DBG_GPDMA2_CH2_STOP) +#define __HAL_DBGMCU_FREEZE_GPDMA2_2() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA2_CH2_STOP) +#define __HAL_DBGMCU_UNFREEZE_GPDMA2_2() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA2_CH2_STOP) +#endif /* DBGMCU_AHB1FZR_DBG_GPDMA2_CH2_STOP */ + +#if defined(DBGMCU_AHB1FZR_DBG_GPDMA2_CH3_STOP) +#define __HAL_DBGMCU_FREEZE_GPDMA2_3() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA2_CH3_STOP) +#define __HAL_DBGMCU_UNFREEZE_GPDMA2_3() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA2_CH3_STOP) +#endif /* DBGMCU_AHB1FZR_DBG_GPDMA2_CH3_STOP */ + +#if defined(DBGMCU_AHB1FZR_DBG_GPDMA2_CH4_STOP) +#define __HAL_DBGMCU_FREEZE_GPDMA2_4() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA2_CH4_STOP) +#define __HAL_DBGMCU_UNFREEZE_GPDMA2_4() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA2_CH4_STOP) +#endif /* DBGMCU_AHB1FZR_DBG_GPDMA2_CH4_STOP */ + +#if defined(DBGMCU_AHB1FZR_DBG_GPDMA2_CH5_STOP) +#define __HAL_DBGMCU_FREEZE_GPDMA2_5() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA2_CH5_STOP) +#define __HAL_DBGMCU_UNFREEZE_GPDMA2_5() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA2_CH5_STOP) +#endif /* DBGMCU_AHB1FZR_DBG_GPDMA2_CH5_STOP */ + +#if defined(DBGMCU_AHB1FZR_DBG_GPDMA2_CH6_STOP) +#define __HAL_DBGMCU_FREEZE_GPDMA2_6() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA2_CH6_STOP) +#define __HAL_DBGMCU_UNFREEZE_GPDMA2_6() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA2_CH6_STOP) +#endif /* DBGMCU_AHB1FZR_DBG_GPDMA2_CH6_STOP */ + +#if defined(DBGMCU_AHB1FZR_DBG_GPDMA2_CH7_STOP) +#define __HAL_DBGMCU_FREEZE_GPDMA2_7() SET_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA2_CH7_STOP) +#define __HAL_DBGMCU_UNFREEZE_GPDMA2_7() CLEAR_BIT(DBGMCU->AHB1FZR, DBGMCU_AHB1FZR_DBG_GPDMA2_CH7_STOP) +#endif /* DBGMCU_AHB1FZR_DBG_GPDMA2_CH7_STOP */ + +/** + * @} + */ + +/** @defgroup SBS_Exported_Macros SBS Exported Macros + * @{ + */ + +/** @brief Floating Point Unit interrupt enable/disable macros + * @param __INTERRUPT__: This parameter can be a value of @ref SBS_FPU_Interrupts + */ +#define __HAL_SBS_FPU_INTERRUPT_ENABLE(__INTERRUPT__) do {assert_param(IS_SBS_FPU_INTERRUPT((__INTERRUPT__)));\ + SET_BIT(SBS->FPUIMR, (__INTERRUPT__));\ + }while(0) + +#define __HAL_SBS_FPU_INTERRUPT_DISABLE(__INTERRUPT__) do {assert_param(IS_SBS_FPU_INTERRUPT((__INTERRUPT__)));\ + CLEAR_BIT(SBS->FPUIMR, (__INTERRUPT__));\ + }while(0) + +/** @brief SBS Break ECC lock. + * Enable and lock the connection of Flash ECC error connection to TIM1/8/15/16/17 Break input. + * @note The selected configuration is locked and can be unlocked only by system reset. + */ +#define __HAL_SBS_BREAK_ECC_LOCK() SET_BIT(SBS->CFGR2, SBS_CFGR2_ECCL) + +/** @brief SBS Break Cortex-M33 Lockup lock. + * Enable and lock the connection of Cortex-M33 LOCKUP (Hardfault) output to TIM1/8/15/16/17 Break input. + * @note The selected configuration is locked and can be unlocked only by system reset. + */ +#define __HAL_SBS_BREAK_LOCKUP_LOCK() SET_BIT(SBS->CFGR2, SBS_CFGR2_CLL) + +/** @brief SBS Break PVD lock. + * Enable and lock the PVD connection to Timer1/8/15/16/17 Break input, as well as the PVDE and PLS[2:0] + * in the PWR_CR2 register. + * @note The selected configuration is locked and can be unlocked only by system reset. + */ +#define __HAL_SBS_BREAK_PVD_LOCK() SET_BIT(SBS->CFGR2, SBS_CFGR2_PVDL) + +/** @brief SBS Break SRAM double ECC lock. + * Enable and lock the connection of SRAM double ECC error to TIM1/8/15/16/17 Break input. + * @note The selected configuration is locked and can be unlocked only by system reset. + */ +#define __HAL_SBS_BREAK_SRAM_ECC_LOCK() SET_BIT(SBS->CFGR2, SBS_CFGR2_SEL) + +/** @brief Fast-mode Plus driving capability enable/disable macros + * @param __FASTMODEPLUS__: This parameter can be a value of : + * @arg @ref SBS_FASTMODEPLUS_PB6 Fast-mode Plus driving capability activation on PB6 + * @arg @ref SBS_FASTMODEPLUS_PB7 Fast-mode Plus driving capability activation on PB7 + * @arg @ref SBS_FASTMODEPLUS_PB8 Fast-mode Plus driving capability activation on PB8 + * @arg @ref SBS_FASTMODEPLUS_PB9 Fast-mode Plus driving capability activation on PB9 + */ +#define __HAL_SBS_FASTMODEPLUS_ENABLE(__FASTMODEPLUS__) do {assert_param(IS_SBS_FASTMODEPLUS((__FASTMODEPLUS__)));\ + SET_BIT(SBS->PMCR, (__FASTMODEPLUS__));\ + }while(0) + +#define __HAL_SBS_FASTMODEPLUS_DISABLE(__FASTMODEPLUS__) do {assert_param(IS_SBS_FASTMODEPLUS((__FASTMODEPLUS__)));\ + CLEAR_BIT(SBS->PMCR, (__FASTMODEPLUS__));\ + }while(0) + +/** @brief Check SBS Memories Erase Status Flags. + * @param __FLAG__: specifies the flag to check. + * This parameter can be one of the following values: + * @arg @ref SBS_MEMORIES_ERASE_FLAG_IPMEE Status of End Of Erase for ICACHE and PKA RAMs + * @arg @ref SBS_MEMORIES_ERASE_FLAG_MCLR Status of Erase after Power-on Reset ((SRAM2, BKPRAM, + * ICACHE, DCACHE, PKA RAMs) + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_SBS_GET_MEMORIES_ERASE_STATUS(__FLAG__) ((((SBS->MESR) & (__FLAG__))!= 0) ? 1 : 0) + +/** @brief Clear SBS Memories Erase Status Flags. + * @param __FLAG__: specifies the flag to clear. + * This parameter can be one of the following values: + * @arg @ref SBS_MEMORIES_ERASE_FLAG_IPMEE Status of End Of Erase for ICACHE and PKA RAMs + * @arg @ref SBS_MEMORIES_ERASE_FLAG_MCLR Status of Erase after Power-on Reset ((SRAM2, BKPRAM, + * ICACHE, DCACHE, PKA RAMs) + */ +#define __HAL_SBS_CLEAR_MEMORIES_ERASE_STATUS(__FLAG__) do {assert_param(IS_SBS_MEMORIES_ERASE_FLAG((__FLAG__)));\ + WRITE_REG(SBS->MESR, (__FLAG__));\ + }while(0) + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ + +/** @defgroup SBS_Private_Macros SBS Private Macros + * @{ + */ + +#define IS_SBS_FPU_INTERRUPT(__INTERRUPT__) ((((__INTERRUPT__) & SBS_IT_FPU_IOC) == SBS_IT_FPU_IOC) || \ + (((__INTERRUPT__) & SBS_IT_FPU_DZC) == SBS_IT_FPU_DZC) || \ + (((__INTERRUPT__) & SBS_IT_FPU_UFC) == SBS_IT_FPU_UFC) || \ + (((__INTERRUPT__) & SBS_IT_FPU_OFC) == SBS_IT_FPU_OFC) || \ + (((__INTERRUPT__) & SBS_IT_FPU_IDC) == SBS_IT_FPU_IDC) || \ + (((__INTERRUPT__) & SBS_IT_FPU_IXC) == SBS_IT_FPU_IXC)) + +#define IS_SBS_BREAK_CONFIG(__CONFIG__) (((__CONFIG__) == SBS_BREAK_FLASH_ECC) || \ + ((__CONFIG__) == SBS_BREAK_PVD) || \ + ((__CONFIG__) == SBS_BREAK_SRAM_ECC) || \ + ((__CONFIG__) == SBS_BREAK_LOCKUP)) + +#if defined(VREFBUF) +#define IS_VREFBUF_VOLTAGE_SCALE(__SCALE__) (((__SCALE__) == VREFBUF_VOLTAGE_SCALE0) || \ + ((__SCALE__) == VREFBUF_VOLTAGE_SCALE1) || \ + ((__SCALE__) == VREFBUF_VOLTAGE_SCALE2) || \ + ((__SCALE__) == VREFBUF_VOLTAGE_SCALE3)) + +#define IS_VREFBUF_HIGH_IMPEDANCE(__VALUE__) (((__VALUE__) == VREFBUF_HIGH_IMPEDANCE_DISABLE) || \ + ((__VALUE__) == VREFBUF_HIGH_IMPEDANCE_ENABLE)) + +#define IS_VREFBUF_TRIMMING(__VALUE__) (((__VALUE__) > 0U) && ((__VALUE__) <= VREFBUF_CCR_TRIM)) +#endif /* VREFBUF*/ + +#if defined(SBS_FASTMODEPLUS_PB9) +#define IS_SBS_FASTMODEPLUS(__PIN__) ((((__PIN__) & SBS_FASTMODEPLUS_PB6) == SBS_FASTMODEPLUS_PB6) || \ + (((__PIN__) & SBS_FASTMODEPLUS_PB7) == SBS_FASTMODEPLUS_PB7) || \ + (((__PIN__) & SBS_FASTMODEPLUS_PB8) == SBS_FASTMODEPLUS_PB8) || \ + (((__PIN__) & SBS_FASTMODEPLUS_PB9) == SBS_FASTMODEPLUS_PB9)) +#else +#define IS_SBS_FASTMODEPLUS(__PIN__) ((((__PIN__) & SBS_FASTMODEPLUS_PB6) == SBS_FASTMODEPLUS_PB6) || \ + (((__PIN__) & SBS_FASTMODEPLUS_PB7) == SBS_FASTMODEPLUS_PB7) || \ + (((__PIN__) & SBS_FASTMODEPLUS_PB8) == SBS_FASTMODEPLUS_PB8)) +#endif /* SBS_FASTMODEPLUS_PB9 */ + +#define IS_SBS_HDPL(__LEVEL__) (((__LEVEL__) == SBS_HDPL_VALUE_0) || ((__LEVEL__) == SBS_HDPL_VALUE_1) || \ + ((__LEVEL__) == SBS_HDPL_VALUE_2) || ((__LEVEL__) == SBS_HDPL_VALUE_3)) + +#define IS_SBS_OBKHDPL_SELECTION(__SELECT__) (((__SELECT__) == SBS_OBKHDPL_INCR_0) || \ + ((__SELECT__) == SBS_OBKHDPL_INCR_1) || \ + ((__SELECT__) == SBS_OBKHDPL_INCR_2) || \ + ((__SELECT__) == SBS_OBKHDPL_INCR_3)) + +#define IS_SBS_ITEMS_ATTRIBUTES(__ITEM__) ((((__ITEM__) & SBS_CLK) == SBS_CLK) || \ + (((__ITEM__) & SBS_CLASSB) == SBS_CLASSB) || \ + (((__ITEM__) & SBS_FPU) == SBS_FPU) || \ + (((__ITEM__) & SBS_SMPS) == SBS_SMPS) || \ + (((__ITEM__) & ~(SBS_ALL)) == 0U)) + +#define IS_SBS_ATTRIBUTES(__ATTRIBUTES__) (((__ATTRIBUTES__) == SBS_SEC) ||\ + ((__ATTRIBUTES__) == SBS_NSEC)) + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +#define IS_SBS_LOCK_ITEMS(__ITEM__) ((((__ITEM__) & SBS_MPU_NSEC) == SBS_MPU_NSEC) || \ + (((__ITEM__) & SBS_VTOR_NSEC) == SBS_VTOR_NSEC) || \ + (((__ITEM__) & SBS_SAU) == SBS_SAU) || \ + (((__ITEM__) & SBS_MPU_SEC) == SBS_MPU_SEC) || \ + (((__ITEM__) & SBS_VTOR_AIRCR_SEC) == SBS_VTOR_AIRCR_SEC) || \ + (((__ITEM__) & ~(SBS_LOCK_ALL)) == 0U)) + +#else + +#define IS_SBS_LOCK_ITEMS(__ITEM__) ((((__ITEM__) & SBS_MPU_NSEC) == SBS_MPU_NSEC) || \ + (((__ITEM__) & SBS_VTOR_NSEC) == SBS_VTOR_NSEC) || \ + (((__ITEM__) & ~(SBS_LOCK_ALL)) == 0U)) + + +#endif /* __ARM_FEATURE_CMSE */ +/** + * @} + */ + +/** @defgroup HAL_Private_Macros HAL Private Macros + * @{ + */ +#define IS_TICKFREQ(FREQ) (((FREQ) == HAL_TICK_FREQ_10HZ) || \ + ((FREQ) == HAL_TICK_FREQ_100HZ) || \ + ((FREQ) == HAL_TICK_FREQ_1KHZ)) +/** + * @} + */ +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup HAL_Exported_Functions + * @{ + */ + +/** @addtogroup HAL_Exported_Functions_Group1 + * @{ + */ + +/* Initialization and de-initialization functions ******************************/ +HAL_StatusTypeDef HAL_Init(void); +HAL_StatusTypeDef HAL_DeInit(void); +void HAL_MspInit(void); +void HAL_MspDeInit(void); +HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority); + +/** + * @} + */ + +/** @addtogroup HAL_Exported_Functions_Group2 + * @{ + */ + +/* Peripheral Control functions ************************************************/ +void HAL_IncTick(void); +void HAL_Delay(uint32_t Delay); +uint32_t HAL_GetTick(void); +uint32_t HAL_GetTickPrio(void); +HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq); +HAL_TickFreqTypeDef HAL_GetTickFreq(void); +void HAL_SuspendTick(void); +void HAL_ResumeTick(void); +uint32_t HAL_GetHalVersion(void); +uint32_t HAL_GetREVID(void); +uint32_t HAL_GetDEVID(void); +uint32_t HAL_GetUIDw0(void); +uint32_t HAL_GetUIDw1(void); +uint32_t HAL_GetUIDw2(void); + +/** + * @} + */ + +/** @addtogroup HAL_Exported_Functions_Group3 + * @{ + */ + +/* DBGMCU Peripheral Control functions *****************************************/ +void HAL_DBGMCU_EnableDBGStopMode(void); +void HAL_DBGMCU_DisableDBGStopMode(void); +void HAL_DBGMCU_EnableDBGStandbyMode(void); +void HAL_DBGMCU_DisableDBGStandbyMode(void); + +/** + * @} + */ + +/** @addtogroup HAL_Exported_Functions_Group4 + * @{ + */ + +/* VREFBUF Control functions ****************************************************/ +#if defined(VREFBUF) +void HAL_VREFBUF_VoltageScalingConfig(uint32_t VoltageScaling); +void HAL_VREFBUF_HighImpedanceConfig(uint32_t Mode); +void HAL_VREFBUF_TrimmingConfig(uint32_t TrimmingValue); +HAL_StatusTypeDef HAL_EnableVREFBUF(void); +void HAL_DisableVREFBUF(void); +#endif /* VREFBUF */ + +/** + * @} + */ + +/** @addtogroup HAL_Exported_Functions_Group5 + * @{ + */ + +/* SBS System Configuration functions *******************************************/ +void HAL_SBS_ETHInterfaceSelect(uint32_t SBS_ETHInterface); +void HAL_SBS_EnableVddIO1CompensationCell(void); +void HAL_SBS_DisableVddIO1CompensationCell(void); +void HAL_SBS_EnableVddIO2CompensationCell(void); +void HAL_SBS_DisableVddIO2CompensationCell(void); +void HAL_SBS_VDDCompensationCodeSelect(uint32_t SBS_CompCode); +void HAL_SBS_VDDIOCompensationCodeSelect(uint32_t SBS_CompCode); +uint32_t HAL_SBS_GetVddIO1CompensationCellReadyFlag(void); +uint32_t HAL_SBS_GetVddIO2CompensationCellReadyFlag(void); +void HAL_SBS_VDDCompensationCodeConfig(uint32_t SBS_PMOSCode, uint32_t SBS_NMOSCode); +void HAL_SBS_VDDIOCompensationCodeConfig(uint32_t SBS_PMOSCode, uint32_t SBS_NMOSCode); +uint32_t HAL_SBS_GetNMOSVddCompensationValue(void); +uint32_t HAL_SBS_GetPMOSVddCompensationValue(void); +uint32_t HAL_SBS_GetNMOSVddIO2CompensationValue(void); +uint32_t HAL_SBS_GetPMOSVddIO2CompensationValue(void); +void HAL_SBS_FLASH_EnableECCNMI(void); +void HAL_SBS_FLASH_DisableECCNMI(void); +uint32_t HAL_SBS_FLASH_ECCNMI_IsDisabled(void); + +/** + * @} + */ + +/** @addtogroup HAL_Exported_Functions_Group6 + * @{ + */ + +/* SBS Boot control functions ***************************************************/ +void HAL_SBS_IncrementHDPLValue(void); +uint32_t HAL_SBS_GetHDPLValue(void); + +/** + * @} + */ + +/** @addtogroup HAL_Exported_Functions_Group7 + * @{ + */ + +/* SBS Hardware secure storage control functions ********************************/ +void HAL_SBS_EPOCHSelection(uint32_t Epoch_Selection); +uint32_t HAL_SBS_GetEPOCHSelection(void); +void HAL_SBS_SetOBKHDPL(uint32_t OBKHDPL_Value); +uint32_t HAL_SBS_GetOBKHDPL(void); + +/** + * @} + */ + +/** @addtogroup HAL_Exported_Functions_Group8 + * @{ + */ + +/* SBS Debug control functions ***************************************************/ +void HAL_SBS_OpenAccessPort(void); +void HAL_SBS_OpenDebug(void); +HAL_StatusTypeDef HAL_SBS_ConfigDebugLevel(uint32_t Level); +uint32_t HAL_SBS_GetDebugLevel(void); +void HAL_SBS_LockDebugConfig(void); +void HAL_SBS_ConfigDebugSecurity(uint32_t Security); +uint32_t HAL_SBS_GetDebugSecurity(void); + +/** + * @} + */ + + +/** @addtogroup HAL_Exported_Functions_Group9 + * @{ + */ + +/* SBS Lock functions ********************************************/ +void HAL_SBS_Lock(uint32_t Item); +HAL_StatusTypeDef HAL_SBS_GetLock(uint32_t *pItem); + +/** + * @} + */ + +/** @addtogroup HAL_Exported_Functions_Group10 + * @{ + */ + +/* SBS Attributes functions ********************************************/ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +void HAL_SBS_ConfigAttributes(uint32_t Item, uint32_t Attributes); +HAL_StatusTypeDef HAL_SBS_GetConfigAttributes(uint32_t Item, uint32_t *pAttributes); +#endif /* __ARM_FEATURE_CMSE */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __STM32H5xx_HAL_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_adc.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_adc.h new file mode 100644 index 0000000000..1f02c328a3 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_adc.h @@ -0,0 +1,2029 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_adc.h + * @author MCD Application Team + * @brief Header file of ADC HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_ADC_H +#define STM32H5xx_HAL_ADC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/* Include low level driver */ +#include "stm32h5xx_ll_adc.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup ADC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup ADC_Exported_Types ADC Exported Types + * @{ + */ + +/** + * @brief ADC group regular oversampling structure definition + */ +typedef struct +{ + uint32_t Ratio; /*!< Configures the oversampling ratio. + This parameter can be a value of @ref ADC_HAL_EC_OVS_RATIO */ + + uint32_t RightBitShift; /*!< Configures the division coefficient for the Oversampler. + This parameter can be a value of @ref ADC_HAL_EC_OVS_SHIFT */ + + uint32_t TriggeredMode; /*!< Selects the regular triggered oversampling mode. + This parameter can be a value of @ref ADC_HAL_EC_OVS_DISCONT_MODE */ + + uint32_t OversamplingStopReset; /*!< Selects the regular oversampling mode. + The oversampling is either temporary stopped or reset upon an injected + sequence interruption. + If oversampling is enabled on both regular and injected groups, this + parameter is discarded and forced to setting + "ADC_REGOVERSAMPLING_RESUMED_MODE" (the oversampling buffer is zeroed + during injection sequence). + This parameter can be a value of @ref ADC_HAL_EC_OVS_SCOPE_REG */ + +} ADC_OversamplingTypeDef; + +/** + * @brief Structure definition of ADC instance and ADC group regular. + * @note Parameters of this structure are shared within 2 scopes: + * - Scope entire ADC (affects ADC groups regular and injected): ClockPrescaler, Resolution, DataAlign, + * ScanConvMode, EOCSelection, LowPowerAutoWait. + * - Scope ADC group regular: ContinuousConvMode, NbrOfConversion, DiscontinuousConvMode, NbrOfDiscConversion, + * ExternalTrigConv, ExternalTrigConvEdge, DMAContinuousRequests, Overrun, OversamplingMode, Oversampling, + * SamplingMode. + * @note The setting of these parameters by function HAL_ADC_Init() is conditioned to ADC state. + * ADC state can be either: + * - For all parameters: ADC disabled + * - For all parameters except 'LowPowerAutoWait', 'DMAContinuousRequests' and 'Oversampling': ADC enabled + * without conversion on going on group regular. + * - For parameters 'LowPowerAutoWait' and 'DMAContinuousRequests': ADC enabled without conversion on going + * on groups regular and injected. + * 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 behavior 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 source (synchronous clock derived from APB clock or asynchronous + clock derived from system clock or PLL (Refer to reference manual for list of + clocks available)) and clock prescaler. + This parameter can be a value of @ref ADC_HAL_EC_COMMON_CLOCK_SOURCE. + Note: The ADC clock configuration is common to all ADC instances. + Note: In case of usage of channels on injected group, ADC frequency should be + lower than AHB clock frequency /4 for resolution 12 or 10 bits, + AHB clock frequency /3 for resolution 8 bits, + AHB clock frequency /2 for resolution 6 bits. + Note: In case of synchronous clock mode based on HCLK/1, the configuration must + be enabled only if the system clock has a 50% duty clock cycle (APB + prescaler configured inside RCC must be bypassed and PCLK clock must have + 50% duty cycle). Refer to reference manual for details. + Note: In case of usage of asynchronous clock, the selected clock must be + preliminarily enabled at RCC top level. + Note: This parameter can be modified only if all ADC instances are disabled. */ + + uint32_t Resolution; /*!< Configure the ADC resolution. + This parameter can be a value of @ref ADC_HAL_EC_RESOLUTION */ + + uint32_t DataAlign; /*!< Specify ADC data alignment in conversion data register (right or left). + Refer to reference manual for alignments formats versus resolutions. + This parameter can be a value of @ref ADC_HAL_EC_DATA_ALIGN */ + + uint32_t ScanConvMode; /*!< Configure the sequencer of ADC groups regular and injected. + 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' or 'InjectedNbrOfConversion' and rank of each + channel in sequencer). Scan direction is upward: from rank 1 to + rank 'n'. + This parameter can be a value of @ref ADC_Scan_mode */ + + uint32_t EOCSelection; /*!< Specify which EOC (End Of Conversion) flag is used for conversion by polling and + interruption: end of unitary conversion or end of sequence conversions. + This parameter can be a value of @ref ADC_EOCSelection. */ + + FunctionalState LowPowerAutoWait; /*!< Select the dynamic low power Auto Delay: new conversion start only when the + previous conversion (for ADC group regular) or previous sequence (for ADC group + injected) has been retrieved by user software, using function HAL_ADC_GetValue() + or HAL_ADCEx_InjectedGetValue(). + This feature automatically adapts the frequency of ADC conversions triggers to + the speed of the system that reads the data. Moreover, this avoids risk of + overrun for low frequency applications. + This parameter can be set to ENABLE or DISABLE. + Note: It is not recommended to use with interruption or DMA (HAL_ADC_Start_IT(), + HAL_ADC_Start_DMA()) since these modes have to clear immediately the EOC + flag (by CPU to free the IRQ pending event or by DMA). + Auto wait will work but fort a very short time, discarding its intended + benefit (except specific case of high load of CPU or DMA transfers which + can justify usage of auto wait). + Do use with polling: 1. Start conversion with HAL_ADC_Start(), 2. Later on, + when ADC conversion data is needed: + use HAL_ADC_PollForConversion() to ensure that conversion is completed and + HAL_ADC_GetValue() to retrieve conversion result and trig another + conversion start. (in case of usage of ADC group injected, use the + equivalent functions HAL_ADCExInjected_Start(), + HAL_ADCEx_InjectedGetValue(), ...). */ + + FunctionalState ContinuousConvMode; /*!< Specify whether the conversion is performed in single mode (one conversion) + or continuous mode for ADC group regular, after the first ADC conversion + start trigger occurred (software start or external trigger). This parameter + can be set to ENABLE or DISABLE. */ + + uint32_t NbrOfConversion; /*!< Specify the number of ranks that will be converted within the regular group + sequencer. + This parameter is dependent on ScanConvMode: + - sequencer configured to fully configurable: + Number of ranks in the scan sequence is configurable using this parameter. + Note: After the first call of 'HAL_ADC_Init()', each rank corresponding to + parameter "NbrOfConversion" must be set using 'HAL_ADC_ConfigChannel()'. + Afterwards, when all needed sequencer ranks are set, parameter + 'NbrOfConversion' can be updated without modifying configuration of + sequencer ranks (sequencer ranks above 'NbrOfConversion' are discarded). + - sequencer configured to not fully configurable: + Number of ranks in the scan sequence is defined by number of channels set in + the sequence. This parameter is discarded. + This parameter must be a number between Min_Data = 1 and Max_Data = 8. + Note: This parameter must be modified when no conversion is on going on regular + group (ADC disabled, or ADC enabled without continuous mode or external + trigger that could launch a conversion). */ + + FunctionalState DiscontinuousConvMode; /*!< Specify whether the conversions sequence of ADC group regular 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: On this STM32 series, ADC group regular number of discontinuous + ranks increment is fixed to one-by-one. */ + + uint32_t NbrOfDiscConversion; /*!< Specifies the number of discontinuous conversions in which the main sequence + of ADC group regular (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; /*!< Select the external event source used to trigger ADC group regular conversion + start. + If set to ADC_SOFTWARE_START, external triggers are disabled and software trigger + is used instead. + This parameter can be a value of @ref ADC_regular_external_trigger_source. + Caution: external trigger source is common to all ADC instances. */ + + uint32_t ExternalTrigConvEdge; /*!< Select the external event edge used to trigger ADC group regular conversion start + If trigger source is set to ADC_SOFTWARE_START, this parameter is discarded. + This parameter can be a value of @ref ADC_regular_external_trigger_edge */ + + uint32_t SamplingMode; /*!< Select the sampling mode to be used for ADC group regular conversion. + This parameter can be a value of @ref ADC_regular_sampling_mode */ + + FunctionalState DMAContinuousRequests; /*!< Specify whether the DMA requests are performed in one shot mode (DMA + transfer stops when number of conversions is reached) or in continuous + mode (DMA transfer unlimited, whatever number of conversions). + This parameter can be set to ENABLE or DISABLE. + Note: In continuous mode, DMA must be configured in circular mode. + Otherwise an overrun will be triggered when DMA buffer maximum + pointer is reached. */ + + uint32_t Overrun; /*!< Select the behavior in case of overrun: data overwritten or preserved (default). + This parameter applies to ADC group regular only. + This parameter can be a value of @ref ADC_HAL_EC_REG_OVR_DATA_BEHAVIOR. + Note: In case of overrun set to data preserved and usage with programming model + with interruption (HAL_Start_IT()): ADC IRQ handler has to clear end of + conversion flags, this induces the release of the preserved data. If + needed, this data can be saved in function HAL_ADC_ConvCpltCallback(), + placed in user program code (called before end of conversion flags clear) + Note: Error reporting with respect to the conversion mode: + - Usage with ADC conversion by polling for event or interruption: Error is + reported only if overrun is set to data preserved. If overrun is set to + data overwritten, user can willingly not read all the converted data, + this is not considered as an erroneous case. + - Usage with ADC conversion by DMA: Error is reported whatever overrun + setting (DMA is expected to process all data from data register). */ + + FunctionalState OversamplingMode; /*!< Specify whether the oversampling feature is enabled or disabled. + This parameter can be set to ENABLE or DISABLE. + Note: This parameter can be modified only if there is no conversion is + ongoing on ADC groups regular and injected */ + + ADC_OversamplingTypeDef Oversampling; /*!< Specify the Oversampling parameters. + Caution: this setting overwrites the previous oversampling configuration + if oversampling is already enabled. */ + +} ADC_InitTypeDef; + +/** + * @brief Structure definition of ADC channel for regular group + * @note The setting of these parameters by function HAL_ADC_ConfigChannel() is conditioned to ADC state. + * ADC state can be either: + * - For all parameters: ADC disabled (this is the only possible ADC state to modify parameter 'SingleDiff') + * - For all except parameters 'SamplingTime', 'Offset', 'OffsetNumber': ADC enabled without conversion + * on going on regular group. + * - For parameters 'SamplingTime', 'Offset', 'OffsetNumber': ADC enabled without conversion on going on + * regular and injected groups. + * 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 behavior in case of intended action to update another + * parameter (which fulfills the ADC state condition) on the fly). + */ +typedef struct +{ + uint32_t Channel; /*!< Specify the channel to configure into ADC regular group. + This parameter can be a value of @ref ADC_HAL_EC_CHANNEL + Note: Depending on devices and ADC instances, some channels may not be available + on device package pins. Refer to device datasheet for channels + availability. */ + + uint32_t Rank; /*!< Specify the rank in the regular group sequencer. + This parameter can be a value of @ref ADC_HAL_EC_REG_SEQ_RANKS + Note: 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 adjusted) */ + + 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.5 ADC clock cycles at ADC resolution 12 bits, 10.5 cycles at 10 bits, + 8.5 cycles at 8 bits, 6.5 cycles at 6 bits). + This parameter can be a value of @ref ADC_HAL_EC_CHANNEL_SAMPLINGTIME + Caution: This parameter applies to a channel that can be used into regular + and/or injected group. It overwrites the last setting. + Note: In case of usage of internal measurement channels (VrefInt, Vbat, ...), + 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. */ + + uint32_t SingleDiff; /*!< Select single-ended or differential input. + In differential mode: Differential measurement is carried out between the + selected channel 'i' (positive input) and channel 'i+1' (negative input). + Only channel 'i' has to be configured, channel 'i+1' is configured automatically + This parameter must be a value of @ref ADC_HAL_EC_CHANNEL_SINGLE_DIFF_ENDING + Caution: This parameter applies to a channel that can be used in a regular + and/or injected group. + It overwrites the last setting. + Note: Refer to Reference Manual to ensure the selected channel is available in + differential mode. + Note: When configuring a channel 'i' in differential mode, the channel 'i+1' is + not usable separately. + 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 behavior in case of another parameter + update on the fly) */ + + uint32_t OffsetNumber; /*!< Select the offset number + This parameter can be a value of @ref ADC_HAL_EC_OFFSET_NB + Caution: Only one offset is allowed per channel. This parameter overwrites the + last setting. */ + + uint32_t Offset; /*!< Define the offset to be applied on the raw converted data. + 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. + 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). */ + + uint32_t OffsetSign; /*!< Define if the offset should be subtracted (negative sign) or added (positive + sign) from or to the raw converted data. + This parameter can be a value of @ref ADCEx_OffsetSign. + 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).*/ + FunctionalState OffsetSaturation; /*!< Define if the offset should be saturated upon under or over flow. + This parameter value can be ENABLE or DISABLE. + 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). */ + +} ADC_ChannelConfTypeDef; + +/** + * @brief Structure definition of ADC analog watchdog + * @note The setting of these parameters by function HAL_ADC_AnalogWDGConfig() is conditioned to ADC state. + * ADC state can be either: + * - For all parameters except 'HighThreshold', 'LowThreshold': ADC disabled or ADC enabled without conversion + on going on ADC groups regular and injected. + * - For parameters 'HighThreshold', 'LowThreshold': ADC enabled with conversion on going on regular and + injected groups. + */ +typedef struct +{ + uint32_t WatchdogNumber; /*!< Select which ADC analog watchdog is monitoring the selected channel. + For Analog Watchdog 1: Only 1 channel can be monitored (or overall group of channels + by setting parameter 'WatchdogMode') + For Analog Watchdog 2 and 3: Several channels can be monitored (by successive calls + of 'HAL_ADC_AnalogWDGConfig()' for each channel) + This parameter can be a value of @ref ADC_HAL_EC_AWD_NUMBER. */ + + uint32_t WatchdogMode; /*!< Configure the ADC analog watchdog mode: single/all/none channels. + For Analog Watchdog 1: Configure the ADC analog watchdog mode: single channel or all + channels, ADC groups regular and-or injected. + For Analog Watchdog 2 and 3: Several channels can be monitored by applying + successively the AWD init structure. Channels on ADC + group regular and injected are not differentiated: Set + value 'ADC_ANALOGWATCHDOG_SINGLE_xxx' to monitor 1 + channel, value 'ADC_ANALOGWATCHDOG_ALL_xxx' to monitor + all channels, 'ADC_ANALOGWATCHDOG_NONE' to monitor no + channel. + This parameter can be a value of @ref ADC_analog_watchdog_mode. */ + + uint32_t Channel; /*!< Select which ADC channel to monitor by analog watchdog. + For Analog Watchdog 1: this parameter has an effect only if parameter 'WatchdogMode' + is configured on single channel (only 1 channel can be + monitored). + For Analog Watchdog 2 and 3: Several channels can be monitored. To use this feature, + call successively the function HAL_ADC_AnalogWDGConfig() + for each channel to be added (or removed with value + 'ADC_ANALOGWATCHDOG_NONE'). + This parameter can be a value of @ref ADC_HAL_EC_CHANNEL. */ + + FunctionalState ITMode; /*!< Specify whether the analog watchdog is configured in interrupt or polling mode. + This parameter can be set to ENABLE or DISABLE */ + + uint32_t HighThreshold; /*!< Configure the ADC analog watchdog High threshold value. + 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. + Note: Analog watchdog 2 and 3 are limited to a resolution of 8 bits: if ADC + resolution is 12 bits the 4 LSB are ignored, if ADC resolution is 10 bits the 2 + LSB are ignored. + Note: If ADC oversampling is enabled, ADC analog watchdog thresholds are + impacted: the comparison of analog watchdog thresholds is done on + oversampling final computation (after ratio and shift application): + ADC data register bitfield [15:4] (12 most significant bits). */ + + uint32_t LowThreshold; /*!< Configures the ADC analog watchdog Low threshold value. + 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. + Note: Analog watchdog 2 and 3 are limited to a resolution of 8 bits: if ADC + resolution is 12 bits the 4 LSB are ignored, if ADC resolution is 10 bits the 2 + LSB are ignored. + Note: If ADC oversampling is enabled, ADC analog watchdog thresholds are + impacted: the comparison of analog watchdog thresholds is done on + oversampling final computation (after ratio and shift application): + ADC data register bitfield [15:4] (12 most significant bits).*/ + + uint32_t FilteringConfig; /*!< Specify whether filtering should be use and the number of samples to consider. + Before setting flag or raising interrupt, analog watchdog can wait to have several + consecutive out-of-window samples. This parameter allows to configure this number. + This parameter only applies to Analog watchdog 1. For others, use value + ADC_AWD_FILTERING_NONE. + This parameter can be a value of @ref ADC_analog_watchdog_filtering_config. */ +} ADC_AnalogWDGConfTypeDef; + +/** + * @brief ADC group injected contexts queue configuration + * @note Structure intended to be used only through structure "ADC_HandleTypeDef" + */ +typedef struct +{ + uint32_t ContextQueue; /*!< Injected channel configuration context: build-up over each + HAL_ADCEx_InjectedConfigChannel() call to finally initialize + JSQR register at HAL_ADCEx_InjectedConfigChannel() last call */ + + uint32_t ChannelCount; /*!< Number of channels in the injected sequence */ +} ADC_InjectionConfigTypeDef; + +/** @defgroup ADC_States ADC States + * @{ + */ + +/** + * @brief HAL ADC state machine: ADC states definition (bitfields) + * @note ADC state machine is managed by bitfields, state must be compared + * with bit by bit. + * For example: + * " if ((HAL_ADC_GetState(hadc1) & HAL_ADC_STATE_REG_BUSY) != 0UL) " + * " if ((HAL_ADC_GetState(hadc1) & HAL_ADC_STATE_AWD1) != 0UL) " + */ +/* States of ADC global scope */ +#define HAL_ADC_STATE_RESET (0x00000000UL) /*!< ADC not yet initialized or disabled */ +#define HAL_ADC_STATE_READY (0x00000001UL) /*!< ADC peripheral ready for use */ +#define HAL_ADC_STATE_BUSY_INTERNAL (0x00000002UL) /*!< ADC is busy due to an internal process (initialization, + calibration, ...) */ +#define HAL_ADC_STATE_TIMEOUT (0x00000004UL) /*!< TimeOut occurrence */ + +/* States of ADC errors */ +#define HAL_ADC_STATE_ERROR_INTERNAL (0x00000010UL) /*!< Internal error occurrence */ +#define HAL_ADC_STATE_ERROR_CONFIG (0x00000020UL) /*!< Configuration error occurrence */ +#define HAL_ADC_STATE_ERROR_DMA (0x00000040UL) /*!< DMA error occurrence */ + +/* States of ADC group regular */ +#define HAL_ADC_STATE_REG_BUSY (0x00000100UL) /*!< A conversion on ADC 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 (0x00000200UL) /*!< Conversion data available on group regular */ +#define HAL_ADC_STATE_REG_OVR (0x00000400UL) /*!< Overrun occurrence */ +#define HAL_ADC_STATE_REG_EOSMP (0x00000800UL) /*!< Not available on this STM32 series: End Of Sampling flag + raised */ + +/* States of ADC group injected */ +#define HAL_ADC_STATE_INJ_BUSY (0x00001000UL) /*!< A conversion on ADC 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 (0x00002000UL) /*!< Conversion data available on group injected */ +#define HAL_ADC_STATE_INJ_JQOVF (0x00004000UL) /*!< Injected queue overflow occurrence */ + +/* States of ADC analog watchdogs */ +#define HAL_ADC_STATE_AWD1 (0x00010000UL) /*!< Out-of-window occurrence of ADC analog watchdog 1 */ +#define HAL_ADC_STATE_AWD2 (0x00020000UL) /*!< Out-of-window occurrence of ADC analog watchdog 2 */ +#define HAL_ADC_STATE_AWD3 (0x00040000UL) /*!< Out-of-window occurrence of ADC analog watchdog 3 */ + +/* States of ADC multi-mode */ +#define HAL_ADC_STATE_MULTIMODE_SLAVE (0x00100000UL) /*!< ADC in multimode slave state, controlled by another ADC + master (when feature available) */ + +/** + * @} + */ + +/** + * @brief ADC handle Structure definition + */ +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) +typedef struct __ADC_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ +{ + ADC_TypeDef *Instance; /*!< Register base address */ + ADC_InitTypeDef Init; /*!< ADC initialization parameters and regular + conversions setting */ + DMA_HandleTypeDef *DMA_Handle; /*!< Pointer DMA Handler */ + HAL_LockTypeDef Lock; /*!< ADC locking object */ + __IO uint32_t State; /*!< ADC communication state (bitmap of ADC states) */ + __IO uint32_t ErrorCode; /*!< ADC Error code */ + ADC_InjectionConfigTypeDef InjectionConfig ; /*!< ADC injected channel configuration build-up + structure */ +#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 (* InjectedQueueOverflowCallback)(struct __ADC_HandleTypeDef *hadc); /*!< ADC group injected context queue + overflow callback */ + void (* LevelOutOfWindow2Callback)(struct __ADC_HandleTypeDef *hadc); /*!< ADC analog watchdog 2 callback */ + void (* LevelOutOfWindow3Callback)(struct __ADC_HandleTypeDef *hadc); /*!< ADC analog watchdog 3 callback */ + void (* EndOfSamplingCallback)(struct __ADC_HandleTypeDef *hadc); /*!< ADC end of sampling 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_INJ_QUEUE_OVEFLOW_CB_ID = 0x05U, /*!< ADC group injected context queue overflow callback ID */ + HAL_ADC_LEVEL_OUT_OF_WINDOW_2_CB_ID = 0x06U, /*!< ADC analog watchdog 2 callback ID */ + HAL_ADC_LEVEL_OUT_OF_WINDOW_3_CB_ID = 0x07U, /*!< ADC analog watchdog 3 callback ID */ + HAL_ADC_END_OF_SAMPLING_CB_ID = 0x08U, /*!< ADC end of sampling callback ID */ + HAL_ADC_MSPINIT_CB_ID = 0x09U, /*!< ADC Msp Init callback ID */ + HAL_ADC_MSPDEINIT_CB_ID = 0x0AU /*!< 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 peripheral internal error (problem of clocking, + enable/disable, erroneous state, ...) */ +#define HAL_ADC_ERROR_OVR (0x02U) /*!< Overrun error */ +#define HAL_ADC_ERROR_DMA (0x04U) /*!< DMA transfer error */ +#define HAL_ADC_ERROR_JQOVF (0x08U) /*!< Injected context queue overflow 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_HAL_EC_COMMON_CLOCK_SOURCE ADC common - Clock source + * @{ + */ + +#define ADC_CLOCK_SYNC_PCLK_DIV1 (LL_ADC_CLOCK_SYNC_PCLK_DIV1) /*!< ADC synchronous clock from AHB clock + without prescaler */ +#define ADC_CLOCK_SYNC_PCLK_DIV2 (LL_ADC_CLOCK_SYNC_PCLK_DIV2) /*!< ADC synchronous clock from AHB clock + with prescaler division by 2 */ +#define ADC_CLOCK_SYNC_PCLK_DIV4 (LL_ADC_CLOCK_SYNC_PCLK_DIV4) /*!< ADC synchronous clock from AHB clock + with prescaler division by 4 */ +#define ADC_CLOCK_ASYNC_DIV1 (LL_ADC_CLOCK_ASYNC_DIV1) /*!< ADC asynchronous clock without + prescaler */ +#define ADC_CLOCK_ASYNC_DIV2 (LL_ADC_CLOCK_ASYNC_DIV2) /*!< ADC asynchronous clock with prescaler + division by 2 */ +#define ADC_CLOCK_ASYNC_DIV4 (LL_ADC_CLOCK_ASYNC_DIV4) /*!< ADC asynchronous clock with prescaler + division by 4 */ +#define ADC_CLOCK_ASYNC_DIV6 (LL_ADC_CLOCK_ASYNC_DIV6) /*!< ADC asynchronous clock with prescaler + division by 6 */ +#define ADC_CLOCK_ASYNC_DIV8 (LL_ADC_CLOCK_ASYNC_DIV8) /*!< ADC asynchronous clock with prescaler + division by 8 */ +#define ADC_CLOCK_ASYNC_DIV10 (LL_ADC_CLOCK_ASYNC_DIV10) /*!< ADC asynchronous clock with prescaler + division by 10 */ +#define ADC_CLOCK_ASYNC_DIV12 (LL_ADC_CLOCK_ASYNC_DIV12) /*!< ADC asynchronous clock with prescaler + division by 12 */ +#define ADC_CLOCK_ASYNC_DIV16 (LL_ADC_CLOCK_ASYNC_DIV16) /*!< ADC asynchronous clock with prescaler + division by 16 */ +#define ADC_CLOCK_ASYNC_DIV32 (LL_ADC_CLOCK_ASYNC_DIV32) /*!< ADC asynchronous clock with prescaler + division by 32 */ +#define ADC_CLOCK_ASYNC_DIV64 (LL_ADC_CLOCK_ASYNC_DIV64) /*!< ADC asynchronous clock with prescaler + division by 64 */ +#define ADC_CLOCK_ASYNC_DIV128 (LL_ADC_CLOCK_ASYNC_DIV128) /*!< ADC asynchronous clock with prescaler + division by 128 */ +#define ADC_CLOCK_ASYNC_DIV256 (LL_ADC_CLOCK_ASYNC_DIV256) /*!< ADC asynchronous clock with prescaler + division by 256 */ +/** + * @} + */ + +/** @defgroup ADC_HAL_EC_RESOLUTION ADC instance - Resolution + * @{ + */ +#define ADC_RESOLUTION_12B (LL_ADC_RESOLUTION_12B) /*!< ADC resolution 12 bits */ +#define ADC_RESOLUTION_10B (LL_ADC_RESOLUTION_10B) /*!< ADC resolution 10 bits */ +#define ADC_RESOLUTION_8B (LL_ADC_RESOLUTION_8B) /*!< ADC resolution 8 bits */ +#define ADC_RESOLUTION_6B (LL_ADC_RESOLUTION_6B) /*!< ADC resolution 6 bits */ +/** + * @} + */ + +/** @defgroup ADC_HAL_EC_DATA_ALIGN ADC conversion data alignment + * @{ + */ +#define ADC_DATAALIGN_RIGHT (LL_ADC_DATA_ALIGN_RIGHT) /*!< ADC conversion data alignment: right aligned + (alignment on data register LSB bit 0)*/ +#define ADC_DATAALIGN_LEFT (LL_ADC_DATA_ALIGN_LEFT) /*!< ADC conversion data alignment: left aligned + (alignment on data register MSB bit 15)*/ +/** + * @} + */ + +/** @defgroup ADC_Scan_mode ADC sequencer scan mode + * @{ + */ +#define ADC_SCAN_DISABLE (0x00000000UL) /*!< Scan mode disabled */ +#define ADC_SCAN_ENABLE (0x00000001UL) /*!< Scan mode enabled */ +/** + * @} + */ + +/** @defgroup ADC_regular_external_trigger_source ADC group regular trigger source + * @{ + */ +/* ADC group regular trigger sources for all ADC instances */ +#define ADC_SOFTWARE_START (LL_ADC_REG_TRIG_SOFTWARE) /*!< ADC group regular conversion + trigger software start */ +/* Triggers common to all devices of STM32H5 series */ +#define ADC_EXTERNALTRIG_T1_CC1 (LL_ADC_REG_TRIG_EXT_TIM1_CH1) /*!< ADC group regular conversion + trigger from external peripheral: TIM1 channel 1 event (capture compare). */ +#define ADC_EXTERNALTRIG_T1_CC2 (LL_ADC_REG_TRIG_EXT_TIM1_CH2) /*!< ADC group regular conversion + trigger from external peripheral: TIM1 channel 2 event (capture compare). */ +#define ADC_EXTERNALTRIG_T1_CC3 (LL_ADC_REG_TRIG_EXT_TIM1_CH3) /*!< ADC group regular conversion + trigger from external peripheral: TIM1 channel 3 event (capture compare). */ +#define ADC_EXTERNALTRIG_T2_CC2 (LL_ADC_REG_TRIG_EXT_TIM2_CH2) /*!< ADC group regular conversion + trigger from external peripheral: TIM2 channel 2 event (capture compare). */ +#define ADC_EXTERNALTRIG_T3_TRGO (LL_ADC_REG_TRIG_EXT_TIM3_TRGO) /*!< ADC group regular conversion + trigger from external peripheral: TIM3 TRGO event. */ +#define ADC_EXTERNALTRIG_EXT_IT11 (LL_ADC_REG_TRIG_EXT_EXTI_LINE11) /*!< ADC group regular conversion + trigger from external peripheral: external interrupt line 11 event. */ +#define ADC_EXTERNALTRIG_T1_TRGO (LL_ADC_REG_TRIG_EXT_TIM1_TRGO) /*!< ADC group regular conversion + trigger from external peripheral: TIM1 TRGO event. */ +#define ADC_EXTERNALTRIG_T1_TRGO2 (LL_ADC_REG_TRIG_EXT_TIM1_TRGO2) /*!< ADC group regular conversion + trigger from external peripheral: TIM1 TRGO2 event. */ +#define ADC_EXTERNALTRIG_T2_TRGO (LL_ADC_REG_TRIG_EXT_TIM2_TRGO) /*!< ADC group regular conversion + trigger from external peripheral: TIM2 TRGO event. */ +#define ADC_EXTERNALTRIG_T6_TRGO (LL_ADC_REG_TRIG_EXT_TIM6_TRGO) /*!< ADC group regular conversion + trigger from external peripheral: TIM6 TRGO event. */ +#define ADC_EXTERNALTRIG_T3_CC4 (LL_ADC_REG_TRIG_EXT_TIM3_CH4) /*!< ADC group regular conversion + trigger from external peripheral: TIM3 channel 4 event (capture compare). */ +#define ADC_EXTERNALTRIG_EXT_IT15 (LL_ADC_REG_TRIG_EXT_EXTI_LINE15) /*!< ADC group regular conversion + trigger from external peripheral: external interrupt line 15 event. */ +#define ADC_EXTERNALTRIG_LPTIM1_CH1 (LL_ADC_REG_TRIG_EXT_LPTIM1_CH1) /*!< ADC group regular conversion + trigger from external peripheral: LPTIM1 channel 1 event. */ +#define ADC_EXTERNALTRIG_LPTIM2_CH1 (LL_ADC_REG_TRIG_EXT_LPTIM2_CH1) /*!< ADC group regular conversion + trigger from external peripheral: LPTIM2 channel 1 event. */ + +/* Triggers specific to some devices of STM32H5 series */ +#if defined(TIM8) +/* Devices STM32H563/H573xx */ +#define ADC_EXTERNALTRIG_T4_CC4 (LL_ADC_REG_TRIG_EXT_TIM4_CH4) /*!< ADC group regular conversion + trigger from external peripheral: TIM4 channel 4 event (capture compare). + Specific to devices STM32H563/H573xx. */ +#define ADC_EXTERNALTRIG_T8_TRGO (LL_ADC_REG_TRIG_EXT_TIM8_TRGO) /*!< ADC group regular conversion + trigger from external peripheral: TIM8 TRGO event. + Specific to devices STM32H563/H573xx. */ +#define ADC_EXTERNALTRIG_T8_TRGO2 (LL_ADC_REG_TRIG_EXT_TIM8_TRGO2) /*!< ADC group regular conversion + trigger from external peripheral: TIM8 TRGO2 event. + Specific to devices STM32H563/H573xx. */ +#define ADC_EXTERNALTRIG_T4_TRGO (LL_ADC_REG_TRIG_EXT_TIM4_TRGO) /*!< ADC group regular conversion + trigger from external peripheral: TIM4 TRGO event. + Specific to devices STM32H563/H573xx. */ +#define ADC_EXTERNALTRIG_T15_TRGO (LL_ADC_REG_TRIG_EXT_TIM15_TRGO) /*!< ADC group regular conversion + trigger from external peripheral: TIM15 TRGO event. + Specific to devices STM32H563/H573xx. */ +#else +/* Devices STM32H503xx */ +#define ADC_EXTERNALTRIG_T7_TRGO (LL_ADC_REG_TRIG_EXT_TIM7_TRGO) /*!< ADC group regular conversion + trigger from external peripheral: TIM7 TRGO event. + Specific to devices STM32H503xx. */ +#endif /* Devices STM32H563/H573xx or STM32H503xx */ +/** + * @} + */ + +/** @defgroup ADC_regular_external_trigger_edge ADC group regular trigger edge (when external trigger is selected) + * @{ + */ +#define ADC_EXTERNALTRIGCONVEDGE_NONE (0x00000000UL) /*!< ADC group regular trigger + disabled (SW start)*/ +#define ADC_EXTERNALTRIGCONVEDGE_RISING (LL_ADC_REG_TRIG_EXT_RISING) /*!< ADC group regular conversion + trigger polarity set to rising edge */ +#define ADC_EXTERNALTRIGCONVEDGE_FALLING (LL_ADC_REG_TRIG_EXT_FALLING) /*!< ADC group regular conversion + trigger polarity set to falling edge */ +#define ADC_EXTERNALTRIGCONVEDGE_RISINGFALLING (LL_ADC_REG_TRIG_EXT_RISINGFALLING) /*!< ADC group regular conversion + trigger polarity set to both rising and falling edges */ +/** + * @} + */ + +/** @defgroup ADC_regular_sampling_mode ADC group regular sampling mode + * @{ + */ +#define ADC_SAMPLING_MODE_NORMAL (0x00000000UL) /*!< ADC conversions sampling phase duration is + defined using @ref ADC_HAL_EC_CHANNEL_SAMPLINGTIME */ +#define ADC_SAMPLING_MODE_BULB (ADC_CFGR2_BULB) /*!< ADC conversions sampling phase starts + immediately after end of conversion, and stops upon trigger event. + Note: First conversion is using minimal sampling time + (see @ref ADC_HAL_EC_CHANNEL_SAMPLINGTIME) */ +#define ADC_SAMPLING_MODE_TRIGGER_CONTROLED (ADC_CFGR2_SMPTRIG) /*!< ADC conversions sampling phase is controlled + by trigger events: + Trigger rising edge = start sampling + Trigger falling edge = stop sampling and start conversion */ +/** + * @} + */ + +/** @defgroup ADC_EOCSelection ADC sequencer end of unitary conversion or sequence conversions + * @{ + */ +#define ADC_EOC_SINGLE_CONV (ADC_ISR_EOC) /*!< End of unitary conversion flag */ +#define ADC_EOC_SEQ_CONV (ADC_ISR_EOS) /*!< End of sequence conversions flag */ +/** + * @} + */ + +/** @defgroup ADC_HAL_EC_REG_OVR_DATA_BEHAVIOR ADC group regular - Overrun behavior on conversion data + * @{ + */ +#define ADC_OVR_DATA_PRESERVED (LL_ADC_REG_OVR_DATA_PRESERVED) /*!< ADC group regular behavior in case + of overrun: data preserved */ +#define ADC_OVR_DATA_OVERWRITTEN (LL_ADC_REG_OVR_DATA_OVERWRITTEN) /*!< ADC group regular behavior in case + of overrun: data overwritten */ +/** + * @} + */ + +/** @defgroup ADC_HAL_EC_REG_SEQ_RANKS ADC group regular - Sequencer ranks + * @{ + */ +#define ADC_REGULAR_RANK_1 (LL_ADC_REG_RANK_1) /*!< ADC group regular sequencer rank 1 */ +#define ADC_REGULAR_RANK_2 (LL_ADC_REG_RANK_2) /*!< ADC group regular sequencer rank 2 */ +#define ADC_REGULAR_RANK_3 (LL_ADC_REG_RANK_3) /*!< ADC group regular sequencer rank 3 */ +#define ADC_REGULAR_RANK_4 (LL_ADC_REG_RANK_4) /*!< ADC group regular sequencer rank 4 */ +#define ADC_REGULAR_RANK_5 (LL_ADC_REG_RANK_5) /*!< ADC group regular sequencer rank 5 */ +#define ADC_REGULAR_RANK_6 (LL_ADC_REG_RANK_6) /*!< ADC group regular sequencer rank 6 */ +#define ADC_REGULAR_RANK_7 (LL_ADC_REG_RANK_7) /*!< ADC group regular sequencer rank 7 */ +#define ADC_REGULAR_RANK_8 (LL_ADC_REG_RANK_8) /*!< ADC group regular sequencer rank 8 */ +#define ADC_REGULAR_RANK_9 (LL_ADC_REG_RANK_9) /*!< ADC group regular sequencer rank 9 */ +#define ADC_REGULAR_RANK_10 (LL_ADC_REG_RANK_10) /*!< ADC group regular sequencer rank 10 */ +#define ADC_REGULAR_RANK_11 (LL_ADC_REG_RANK_11) /*!< ADC group regular sequencer rank 11 */ +#define ADC_REGULAR_RANK_12 (LL_ADC_REG_RANK_12) /*!< ADC group regular sequencer rank 12 */ +#define ADC_REGULAR_RANK_13 (LL_ADC_REG_RANK_13) /*!< ADC group regular sequencer rank 13 */ +#define ADC_REGULAR_RANK_14 (LL_ADC_REG_RANK_14) /*!< ADC group regular sequencer rank 14 */ +#define ADC_REGULAR_RANK_15 (LL_ADC_REG_RANK_15) /*!< ADC group regular sequencer rank 15 */ +#define ADC_REGULAR_RANK_16 (LL_ADC_REG_RANK_16) /*!< ADC group regular sequencer rank 16 */ +/** + * @} + */ + +/** @defgroup ADC_HAL_EC_CHANNEL_SAMPLINGTIME Channel - Sampling time + * @{ + */ +#define ADC_SAMPLETIME_2CYCLES_5 (LL_ADC_SAMPLINGTIME_2CYCLES_5) /*!< Sampling time 2.5 ADC clock cycles */ +#define ADC_SAMPLETIME_6CYCLES_5 (LL_ADC_SAMPLINGTIME_6CYCLES_5) /*!< Sampling time 6.5 ADC clock cycles */ +#define ADC_SAMPLETIME_12CYCLES_5 (LL_ADC_SAMPLINGTIME_12CYCLES_5) /*!< Sampling time 12.5 ADC clock cycles */ +#define ADC_SAMPLETIME_24CYCLES_5 (LL_ADC_SAMPLINGTIME_24CYCLES_5) /*!< Sampling time 24.5 ADC clock cycles */ +#define ADC_SAMPLETIME_47CYCLES_5 (LL_ADC_SAMPLINGTIME_47CYCLES_5) /*!< Sampling time 47.5 ADC clock cycles */ +#define ADC_SAMPLETIME_92CYCLES_5 (LL_ADC_SAMPLINGTIME_92CYCLES_5) /*!< Sampling time 92.5 ADC clock cycles */ +#define ADC_SAMPLETIME_247CYCLES_5 (LL_ADC_SAMPLINGTIME_247CYCLES_5) /*!< Sampling time 247.5 ADC clock cycles */ +#define ADC_SAMPLETIME_640CYCLES_5 (LL_ADC_SAMPLINGTIME_640CYCLES_5) /*!< Sampling time 640.5 ADC clock cycles */ +#define ADC_SAMPLETIME_3CYCLES_5 (ADC_SMPR1_SMPPLUS | LL_ADC_SAMPLINGTIME_2CYCLES_5) /*!< Sampling time 3.5 + ADC clock cycles. If selected, this sampling time replaces sampling time + 2.5 ADC clock cycles. These 2 sampling times cannot be used simultaneously. */ +/** + * @} + */ + +/** @defgroup ADC_HAL_EC_CHANNEL ADC instance - Channel number + * @{ + */ +/* Note: VrefInt, TempSensor and Vbat internal channels are not available on */ +/* all ADC instances (refer to Reference Manual). */ +#define ADC_CHANNEL_0 (LL_ADC_CHANNEL_0) /*!< External channel (GPIO pin) ADCx_IN0 */ +#define ADC_CHANNEL_1 (LL_ADC_CHANNEL_1) /*!< External channel (GPIO pin) ADCx_IN1 */ +#define ADC_CHANNEL_2 (LL_ADC_CHANNEL_2) /*!< External channel (GPIO pin) ADCx_IN2 */ +#define ADC_CHANNEL_3 (LL_ADC_CHANNEL_3) /*!< External channel (GPIO pin) ADCx_IN3 */ +#define ADC_CHANNEL_4 (LL_ADC_CHANNEL_4) /*!< External channel (GPIO pin) ADCx_IN4 */ +#define ADC_CHANNEL_5 (LL_ADC_CHANNEL_5) /*!< External channel (GPIO pin) ADCx_IN5 */ +#define ADC_CHANNEL_6 (LL_ADC_CHANNEL_6) /*!< External channel (GPIO pin) ADCx_IN6 */ +#define ADC_CHANNEL_7 (LL_ADC_CHANNEL_7) /*!< External channel (GPIO pin) ADCx_IN7 */ +#define ADC_CHANNEL_8 (LL_ADC_CHANNEL_8) /*!< External channel (GPIO pin) ADCx_IN8 */ +#define ADC_CHANNEL_9 (LL_ADC_CHANNEL_9) /*!< External channel (GPIO pin) ADCx_IN9 */ +#define ADC_CHANNEL_10 (LL_ADC_CHANNEL_10) /*!< External channel (GPIO pin) ADCx_IN10 */ +#define ADC_CHANNEL_11 (LL_ADC_CHANNEL_11) /*!< External channel (GPIO pin) ADCx_IN11 */ +#define ADC_CHANNEL_12 (LL_ADC_CHANNEL_12) /*!< External channel (GPIO pin) ADCx_IN12 */ +#define ADC_CHANNEL_13 (LL_ADC_CHANNEL_13) /*!< External channel (GPIO pin) ADCx_IN13 */ +#define ADC_CHANNEL_14 (LL_ADC_CHANNEL_14) /*!< External channel (GPIO pin) ADCx_IN14 */ +#define ADC_CHANNEL_15 (LL_ADC_CHANNEL_15) /*!< External channel (GPIO pin) ADCx_IN15 */ +#define ADC_CHANNEL_16 (LL_ADC_CHANNEL_16) /*!< External channel (GPIO pin) ADCx_IN16 */ +#define ADC_CHANNEL_17 (LL_ADC_CHANNEL_17) /*!< External channel (GPIO pin) ADCx_IN17 */ +#define ADC_CHANNEL_18 (LL_ADC_CHANNEL_18) /*!< External channel (GPIO pin) ADCx_IN18 */ +#define ADC_CHANNEL_19 (LL_ADC_CHANNEL_19) /*!< External channel (GPIO pin) ADCx_IN19 */ +#define ADC_CHANNEL_VREFINT (LL_ADC_CHANNEL_VREFINT) /*!< Internal channel VrefInt: Internal + voltage reference, channel specific to ADC1. */ +#define ADC_CHANNEL_TEMPSENSOR (LL_ADC_CHANNEL_TEMPSENSOR) /*!< Internal channel Temperature sensor, + channel specific to ADC1. */ +#define ADC_CHANNEL_VBAT (LL_ADC_CHANNEL_VBAT) /*!< Internal channel Vbat/4: Vbat voltage + through a divider ladder of factor 1/4 to have channel voltage always below + Vdda, channel specific to ADC2. */ +#define ADC_CHANNEL_VDDCORE (LL_ADC_CHANNEL_VDDCORE) /*!< Internal channel Vddcore, channel + specific to ADC2. */ +/** + * @} + */ + +/** @defgroup ADC_HAL_EC_AWD_NUMBER Analog watchdog - ADC analog watchdog (AWD) number + * @{ + */ +#define ADC_ANALOGWATCHDOG_1 (LL_ADC_AWD1) /*!< ADC analog watchdog number 1 */ +#define ADC_ANALOGWATCHDOG_2 (LL_ADC_AWD2) /*!< ADC analog watchdog number 2 */ +#define ADC_ANALOGWATCHDOG_3 (LL_ADC_AWD3) /*!< ADC analog watchdog number 3 */ +/** + * @} + */ + +/** @defgroup ADC_analog_watchdog_filtering_config ADC analog watchdog (AWD) filtering configuration + * @{ + */ +#define ADC_AWD_FILTERING_NONE (0x00000000UL) /*!< ADC AWD no filtering, one +out-of-window sample to raise flag or interrupt */ +#define ADC_AWD_FILTERING_2SAMPLES ((ADC_TR1_AWDFILT_0)) /*!< ADC AWD 2 consecutives + out-of-window samples to raise flag or interrupt */ +#define ADC_AWD_FILTERING_3SAMPLES ((ADC_TR1_AWDFILT_1)) /*!< ADC AWD 3 consecutives + out-of-window samples to raise flag or interrupt */ +#define ADC_AWD_FILTERING_4SAMPLES ((ADC_TR1_AWDFILT_1 | ADC_TR1_AWDFILT_0)) /*!< ADC AWD 4 consecutives + out-of-window samples to raise flag or interrupt */ +#define ADC_AWD_FILTERING_5SAMPLES ((ADC_TR1_AWDFILT_2)) /*!< ADC AWD 5 consecutives + out-of-window samples to raise flag or interrupt */ +#define ADC_AWD_FILTERING_6SAMPLES ((ADC_TR1_AWDFILT_2 | ADC_TR1_AWDFILT_0)) /*!< ADC AWD 6 consecutives + out-of-window samples to raise flag or interrupt */ +#define ADC_AWD_FILTERING_7SAMPLES ((ADC_TR1_AWDFILT_2 | ADC_TR1_AWDFILT_1)) /*!< ADC AWD 7 consecutives + out-of-window samples to raise flag or interrupt */ +#define ADC_AWD_FILTERING_8SAMPLES ((ADC_TR1_AWDFILT_2 | ADC_TR1_AWDFILT_1 \ + | ADC_TR1_AWDFILT_0)) /*!< ADC AWD 8 consecutives + out-of-window samples to raise flag or interrupt */ +/** + * @} + */ + +/** @defgroup ADC_analog_watchdog_mode ADC analog watchdog (AWD) mode + * @{ + */ +#define ADC_ANALOGWATCHDOG_NONE (0x00000000UL) /*!< ADC AWD not selected */ +#define ADC_ANALOGWATCHDOG_SINGLE_REG (ADC_CFGR_AWD1SGL | ADC_CFGR_AWD1EN) /*!< ADC AWD applied to a regular + group single channel */ +#define ADC_ANALOGWATCHDOG_SINGLE_INJEC (ADC_CFGR_AWD1SGL | ADC_CFGR_JAWD1EN) /*!< ADC AWD applied to an + injected group single channel */ +#define ADC_ANALOGWATCHDOG_SINGLE_REGINJEC (ADC_CFGR_AWD1SGL | ADC_CFGR_AWD1EN\ + | ADC_CFGR_JAWD1EN) /*!< ADC AWD applied to a regular + and injected groups single channel */ +#define ADC_ANALOGWATCHDOG_ALL_REG (ADC_CFGR_AWD1EN) /*!< ADC AWD applied to regular + group all channels */ +#define ADC_ANALOGWATCHDOG_ALL_INJEC (ADC_CFGR_JAWD1EN) /*!< ADC AWD applied to injected + group all channels */ +#define ADC_ANALOGWATCHDOG_ALL_REGINJEC (ADC_CFGR_AWD1EN | ADC_CFGR_JAWD1EN) /*!< ADC AWD applied to regular + and injected groups all channels */ +/** + * @} + */ + +/** @defgroup ADC_HAL_EC_OVS_RATIO Oversampling - Ratio + * @{ + */ +/** + * @note The oversampling ratio is the number of ADC conversions performed, sum of these conversions data is computed + * to result as the ADC oversampling conversion data (before potential shift) + */ +#define ADC_OVERSAMPLING_RATIO_2 (LL_ADC_OVS_RATIO_2) /*!< ADC oversampling ratio 2 */ +#define ADC_OVERSAMPLING_RATIO_4 (LL_ADC_OVS_RATIO_4) /*!< ADC oversampling ratio 4 */ +#define ADC_OVERSAMPLING_RATIO_8 (LL_ADC_OVS_RATIO_8) /*!< ADC oversampling ratio 8 */ +#define ADC_OVERSAMPLING_RATIO_16 (LL_ADC_OVS_RATIO_16) /*!< ADC oversampling ratio 16 */ +#define ADC_OVERSAMPLING_RATIO_32 (LL_ADC_OVS_RATIO_32) /*!< ADC oversampling ratio 32 */ +#define ADC_OVERSAMPLING_RATIO_64 (LL_ADC_OVS_RATIO_64) /*!< ADC oversampling ratio 64 */ +#define ADC_OVERSAMPLING_RATIO_128 (LL_ADC_OVS_RATIO_128) /*!< ADC oversampling ratio 128 */ +#define ADC_OVERSAMPLING_RATIO_256 (LL_ADC_OVS_RATIO_256) /*!< ADC oversampling ratio 256 */ +/** + * @} + */ + +/** @defgroup ADC_HAL_EC_OVS_SHIFT Oversampling - Data shift + * @{ + */ +/** + * @note The sum of the ADC conversions data is divided by "Rightbitshift" number to result as the ADC oversampling + * conversion data) + */ +#define ADC_RIGHTBITSHIFT_NONE (LL_ADC_OVS_SHIFT_NONE) /*!< ADC oversampling no shift */ +#define ADC_RIGHTBITSHIFT_1 (LL_ADC_OVS_SHIFT_RIGHT_1) /*!< ADC oversampling right shift of 1 ranks */ +#define ADC_RIGHTBITSHIFT_2 (LL_ADC_OVS_SHIFT_RIGHT_2) /*!< ADC oversampling right shift of 2 ranks */ +#define ADC_RIGHTBITSHIFT_3 (LL_ADC_OVS_SHIFT_RIGHT_3) /*!< ADC oversampling right shift of 3 ranks */ +#define ADC_RIGHTBITSHIFT_4 (LL_ADC_OVS_SHIFT_RIGHT_4) /*!< ADC oversampling right shift of 4 ranks */ +#define ADC_RIGHTBITSHIFT_5 (LL_ADC_OVS_SHIFT_RIGHT_5) /*!< ADC oversampling right shift of 5 ranks */ +#define ADC_RIGHTBITSHIFT_6 (LL_ADC_OVS_SHIFT_RIGHT_6) /*!< ADC oversampling right shift of 6 ranks */ +#define ADC_RIGHTBITSHIFT_7 (LL_ADC_OVS_SHIFT_RIGHT_7) /*!< ADC oversampling right shift of 7 ranks */ +#define ADC_RIGHTBITSHIFT_8 (LL_ADC_OVS_SHIFT_RIGHT_8) /*!< ADC oversampling right shift of 8 ranks */ +/** + * @} + */ + +/** @defgroup ADC_HAL_EC_OVS_DISCONT_MODE Oversampling - Discontinuous mode + * @{ + */ +#define ADC_TRIGGEREDMODE_SINGLE_TRIGGER (LL_ADC_OVS_REG_CONT) /*!< ADC oversampling discontinuous mode: + continuous mode (all conversions of OVS ratio are done from 1 trigger) */ +#define ADC_TRIGGEREDMODE_MULTI_TRIGGER (LL_ADC_OVS_REG_DISCONT) /*!< ADC oversampling discontinuous mode: + discontinuous mode (each conversion of OVS ratio needs a trigger) */ +/** + * @} + */ + +/** @defgroup ADC_HAL_EC_OVS_SCOPE_REG Oversampling - Oversampling scope for ADC group regular + * @{ + */ +#define ADC_REGOVERSAMPLING_CONTINUED_MODE (LL_ADC_OVS_GRP_REGULAR_CONTINUED) /*!< Oversampling buffer maintained + during injection sequence */ +#define ADC_REGOVERSAMPLING_RESUMED_MODE (LL_ADC_OVS_GRP_REGULAR_RESUMED) /*!< Oversampling buffer zeroed during + injection sequence */ +/** + * @} + */ + +/** @defgroup ADC_Event_type ADC Event type + * @{ + */ +/** + * @note Analog watchdog 1 is available on all stm32 series + * Analog watchdog 2 and 3 are not available on all series + */ +#define ADC_EOSMP_EVENT (ADC_FLAG_EOSMP) /*!< ADC End of Sampling event */ +#define ADC_AWD1_EVENT (ADC_FLAG_AWD1) /*!< ADC Analog watchdog 1 event (main analog watchdog) */ +#define ADC_AWD2_EVENT (ADC_FLAG_AWD2) /*!< ADC Analog watchdog 2 event (additional analog watchdog) */ +#define ADC_AWD3_EVENT (ADC_FLAG_AWD3) /*!< ADC Analog watchdog 3 event (additional analog watchdog) */ +#define ADC_OVR_EVENT (ADC_FLAG_OVR) /*!< ADC overrun event */ +#define ADC_JQOVF_EVENT (ADC_FLAG_JQOVF) /*!< ADC Injected Context Queue Overflow event */ +/** + * @} + */ +#define ADC_AWD_EVENT ADC_AWD1_EVENT /*!< ADC Analog watchdog 1 event: Naming for compatibility + with other STM32 devices having only one analog watchdog */ + +/** @defgroup ADC_interrupts_definition ADC interrupts definition + * @{ + */ +#define ADC_IT_RDY ADC_IER_ADRDYIE /*!< ADC Ready interrupt source */ +#define ADC_IT_EOSMP ADC_IER_EOSMPIE /*!< ADC End of sampling interrupt source */ +#define ADC_IT_EOC ADC_IER_EOCIE /*!< ADC End of regular conversion interrupt source */ +#define ADC_IT_EOS ADC_IER_EOSIE /*!< ADC End of regular sequence of conversions interrupt source */ +#define ADC_IT_OVR ADC_IER_OVRIE /*!< ADC overrun interrupt source */ +#define ADC_IT_JEOC ADC_IER_JEOCIE /*!< ADC End of injected conversion interrupt source */ +#define ADC_IT_JEOS ADC_IER_JEOSIE /*!< ADC End of injected sequence of conversions interrupt source */ +#define ADC_IT_AWD1 ADC_IER_AWD1IE /*!< ADC Analog watchdog 1 interrupt source (main analog watchdog) */ +#define ADC_IT_AWD2 ADC_IER_AWD2IE /*!< ADC Analog watchdog 2 interrupt source (additional analog + watchdog) */ +#define ADC_IT_AWD3 ADC_IER_AWD3IE /*!< ADC Analog watchdog 3 interrupt source (additional analog + watchdog) */ +#define ADC_IT_JQOVF ADC_IER_JQOVFIE /*!< ADC Injected Context Queue Overflow interrupt source */ + +/** + * @} + */ + +/** @defgroup ADC_flags_definition ADC flags definition + * @{ + */ +#define ADC_FLAG_RDY ADC_ISR_ADRDY /*!< ADC Ready flag */ +#define ADC_FLAG_EOSMP ADC_ISR_EOSMP /*!< ADC End of Sampling flag */ +#define ADC_FLAG_EOC ADC_ISR_EOC /*!< ADC End of Regular Conversion flag */ +#define ADC_FLAG_EOS ADC_ISR_EOS /*!< ADC End of Regular sequence of Conversions flag */ +#define ADC_FLAG_OVR ADC_ISR_OVR /*!< ADC overrun flag */ +#define ADC_FLAG_JEOC ADC_ISR_JEOC /*!< ADC End of Injected Conversion flag */ +#define ADC_FLAG_JEOS ADC_ISR_JEOS /*!< ADC End of Injected sequence of Conversions flag */ +#define ADC_FLAG_AWD1 ADC_ISR_AWD1 /*!< ADC Analog watchdog 1 flag (main analog watchdog) */ +#define ADC_FLAG_AWD2 ADC_ISR_AWD2 /*!< ADC Analog watchdog 2 flag (additional analog watchdog) */ +#define ADC_FLAG_AWD3 ADC_ISR_AWD3 /*!< ADC Analog watchdog 3 flag (additional analog watchdog) */ +#define ADC_FLAG_JQOVF ADC_ISR_JQOVF /*!< ADC Injected Context Queue Overflow flag */ + +/** + * @} + */ + +/** + * @} + */ + +/* 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 Return resolution bits in CFGR register RES[1:0] field. + * @param __HANDLE__ ADC handle + * @retval Value of bitfield RES in CFGR register. + */ +#define ADC_GET_RESOLUTION(__HANDLE__) \ + (LL_ADC_GetResolution((__HANDLE__)->Instance)) + +/** + * @brief Clear ADC error code (set it to no error code "HAL_ADC_ERROR_NONE"). + * @param __HANDLE__ ADC handle + * @retval None + */ +#define ADC_CLEAR_ERRORCODE(__HANDLE__) ((__HANDLE__)->ErrorCode = HAL_ADC_ERROR_NONE) + +/** + * @brief Simultaneously clear and set 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 Verify that a given value is aligned with the ADC resolution range. + * @param __RESOLUTION__ ADC resolution (12, 10, 8 or 6 bits). + * @param __ADC_VALUE__ value checked against the resolution. + * @retval SET (__ADC_VALUE__ in line with __RESOLUTION__) or RESET (__ADC_VALUE__ not in line with __RESOLUTION__) + */ +#define IS_ADC_RANGE(__RESOLUTION__, __ADC_VALUE__) \ + ((__ADC_VALUE__) <= __LL_ADC_DIGITAL_SCALE(__RESOLUTION__)) + +/** + * @brief Verify the length of the scheduled regular conversions group. + * @param __LENGTH__ number of programmed conversions. + * @retval SET (__LENGTH__ is within the maximum number of possible programmable regular conversions) + * or RESET (__LENGTH__ is null or too large) + */ +#define IS_ADC_REGULAR_NB_CONV(__LENGTH__) (((__LENGTH__) >= (1UL)) && ((__LENGTH__) <= (16UL))) + + +/** + * @brief Verify the number of scheduled regular conversions in discontinuous mode. + * @param NUMBER number of scheduled regular conversions in discontinuous mode. + * @retval SET (NUMBER is within the maximum number of regular conversions in discontinuous mode) + * or RESET (NUMBER is null or too large) + */ +#define IS_ADC_REGULAR_DISCONT_NUMBER(NUMBER) (((NUMBER) >= (1UL)) && ((NUMBER) <= (8UL))) + + +/** + * @brief Verify the ADC clock setting. + * @param __ADC_CLOCK__ programmed ADC clock. + * @retval SET (__ADC_CLOCK__ is a valid value) or RESET (__ADC_CLOCK__ is invalid) + */ +#define IS_ADC_CLOCKPRESCALER(__ADC_CLOCK__) (((__ADC_CLOCK__) == ADC_CLOCK_SYNC_PCLK_DIV1) || \ + ((__ADC_CLOCK__) == ADC_CLOCK_SYNC_PCLK_DIV2) || \ + ((__ADC_CLOCK__) == ADC_CLOCK_SYNC_PCLK_DIV4) || \ + ((__ADC_CLOCK__) == ADC_CLOCK_ASYNC_DIV1) || \ + ((__ADC_CLOCK__) == ADC_CLOCK_ASYNC_DIV2) || \ + ((__ADC_CLOCK__) == ADC_CLOCK_ASYNC_DIV4) || \ + ((__ADC_CLOCK__) == ADC_CLOCK_ASYNC_DIV6) || \ + ((__ADC_CLOCK__) == ADC_CLOCK_ASYNC_DIV8) || \ + ((__ADC_CLOCK__) == ADC_CLOCK_ASYNC_DIV10) || \ + ((__ADC_CLOCK__) == ADC_CLOCK_ASYNC_DIV12) || \ + ((__ADC_CLOCK__) == ADC_CLOCK_ASYNC_DIV16) || \ + ((__ADC_CLOCK__) == ADC_CLOCK_ASYNC_DIV32) || \ + ((__ADC_CLOCK__) == ADC_CLOCK_ASYNC_DIV64) || \ + ((__ADC_CLOCK__) == ADC_CLOCK_ASYNC_DIV128) || \ + ((__ADC_CLOCK__) == ADC_CLOCK_ASYNC_DIV256) ) + +/** + * @brief Verify the ADC resolution setting. + * @param __RESOLUTION__ programmed ADC resolution. + * @retval SET (__RESOLUTION__ is a valid value) or RESET (__RESOLUTION__ is invalid) + */ +#define IS_ADC_RESOLUTION(__RESOLUTION__) (((__RESOLUTION__) == ADC_RESOLUTION_12B) || \ + ((__RESOLUTION__) == ADC_RESOLUTION_10B) || \ + ((__RESOLUTION__) == ADC_RESOLUTION_8B) || \ + ((__RESOLUTION__) == ADC_RESOLUTION_6B) ) + +/** + * @brief Verify the ADC resolution setting when limited to 6 or 8 bits. + * @param __RESOLUTION__ programmed ADC resolution when limited to 6 or 8 bits. + * @retval SET (__RESOLUTION__ is a valid value) or RESET (__RESOLUTION__ is invalid) + */ +#define IS_ADC_RESOLUTION_8_6_BITS(__RESOLUTION__) (((__RESOLUTION__) == ADC_RESOLUTION_8B) || \ + ((__RESOLUTION__) == ADC_RESOLUTION_6B) ) + +/** + * @brief Verify the ADC converted data alignment. + * @param __ALIGN__ programmed ADC converted data alignment. + * @retval SET (__ALIGN__ is a valid value) or RESET (__ALIGN__ is invalid) + */ +#define IS_ADC_DATA_ALIGN(__ALIGN__) (((__ALIGN__) == ADC_DATAALIGN_RIGHT) || \ + ((__ALIGN__) == ADC_DATAALIGN_LEFT) ) + +/** + * @brief Verify the ADC scan mode. + * @param __SCAN_MODE__ programmed ADC scan mode. + * @retval SET (__SCAN_MODE__ is valid) or RESET (__SCAN_MODE__ is invalid) + */ +#define IS_ADC_SCAN_MODE(__SCAN_MODE__) (((__SCAN_MODE__) == ADC_SCAN_DISABLE) || \ + ((__SCAN_MODE__) == ADC_SCAN_ENABLE) ) + +/** + * @brief Verify the ADC edge trigger setting for regular group. + * @param __EDGE__ programmed ADC edge trigger setting. + * @retval SET (__EDGE__ is a valid value) or RESET (__EDGE__ is invalid) + */ +#define IS_ADC_EXTTRIG_EDGE(__EDGE__) (((__EDGE__) == ADC_EXTERNALTRIGCONVEDGE_NONE) || \ + ((__EDGE__) == ADC_EXTERNALTRIGCONVEDGE_RISING) || \ + ((__EDGE__) == ADC_EXTERNALTRIGCONVEDGE_FALLING) || \ + ((__EDGE__) == ADC_EXTERNALTRIGCONVEDGE_RISINGFALLING) ) + +/** + * @brief Verify the ADC regular conversions external trigger. + * @param __REGTRIG__ programmed ADC regular conversions external trigger. + * @retval SET (__REGTRIG__ is a valid value) or RESET (__REGTRIG__ is invalid) + */ +#if defined(TIM8) +/* Devices STM32H563/H573xx */ +#define IS_ADC_EXTTRIG(__REGTRIG__) (((__REGTRIG__) == ADC_EXTERNALTRIG_T1_CC1) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_T1_CC2) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_T1_CC3) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_T2_CC2) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_T3_TRGO) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_T4_CC4) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_EXT_IT11) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_T8_TRGO) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_T8_TRGO2) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_T1_TRGO) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_T1_TRGO2) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_T2_TRGO) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_T4_TRGO) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_T6_TRGO) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_T15_TRGO) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_T3_CC4) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_EXT_IT15) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_LPTIM1_CH1) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_LPTIM2_CH1) || \ + ((__REGTRIG__) == ADC_SOFTWARE_START) ) +#else +/* Devices STM32H503xx */ +#define IS_ADC_EXTTRIG(__REGTRIG__) (((__REGTRIG__) == ADC_EXTERNALTRIG_T1_CC1) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_T1_CC2) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_T1_CC3) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_T2_CC2) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_T3_TRGO) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_EXT_IT11) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_T1_TRGO) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_T1_TRGO2) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_T2_TRGO) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_T6_TRGO) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_T3_CC4) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_T7_TRGO) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_LPTIM1_CH1) || \ + ((__REGTRIG__) == ADC_EXTERNALTRIG_LPTIM2_CH1) || \ + ((__REGTRIG__) == ADC_SOFTWARE_START) ) +#endif /* Devices STM32H563/H573xx or STM32H503xx */ + +/** + * @brief Verify the ADC regular conversions external trigger. + * @param __SAMPLINGMODE__ programmed ADC regular conversions external trigger. + * @retval SET (__SAMPLINGMODE__ is a valid value) or RESET (__SAMPLINGMODE__ is invalid) + */ +#define IS_ADC_SAMPLINGMODE(__SAMPLINGMODE__) (((__SAMPLINGMODE__) == ADC_SAMPLING_MODE_NORMAL) || \ + ((__SAMPLINGMODE__) == ADC_SAMPLING_MODE_BULB) || \ + ((__SAMPLINGMODE__) == ADC_SAMPLING_MODE_TRIGGER_CONTROLED) ) + +/** + * @brief Verify the ADC regular conversions check for converted data availability. + * @param __EOC_SELECTION__ converted data availability check. + * @retval SET (__EOC_SELECTION__ is a valid value) or RESET (__EOC_SELECTION__ is invalid) + */ +#define IS_ADC_EOC_SELECTION(__EOC_SELECTION__) (((__EOC_SELECTION__) == ADC_EOC_SINGLE_CONV) || \ + ((__EOC_SELECTION__) == ADC_EOC_SEQ_CONV) ) + +/** + * @brief Verify the ADC regular conversions overrun handling. + * @param __OVR__ ADC regular conversions overrun handling. + * @retval SET (__OVR__ is a valid value) or RESET (__OVR__ is invalid) + */ +#define IS_ADC_OVERRUN(__OVR__) (((__OVR__) == ADC_OVR_DATA_PRESERVED) || \ + ((__OVR__) == ADC_OVR_DATA_OVERWRITTEN) ) + +/** + * @brief Verify the ADC conversions sampling time. + * @param __TIME__ ADC conversions sampling time. + * @retval SET (__TIME__ is a valid value) or RESET (__TIME__ is invalid) + */ +#define IS_ADC_SAMPLE_TIME(__TIME__) (((__TIME__) == ADC_SAMPLETIME_2CYCLES_5) || \ + ((__TIME__) == ADC_SAMPLETIME_3CYCLES_5) || \ + ((__TIME__) == ADC_SAMPLETIME_6CYCLES_5) || \ + ((__TIME__) == ADC_SAMPLETIME_12CYCLES_5) || \ + ((__TIME__) == ADC_SAMPLETIME_24CYCLES_5) || \ + ((__TIME__) == ADC_SAMPLETIME_47CYCLES_5) || \ + ((__TIME__) == ADC_SAMPLETIME_92CYCLES_5) || \ + ((__TIME__) == ADC_SAMPLETIME_247CYCLES_5) || \ + ((__TIME__) == ADC_SAMPLETIME_640CYCLES_5) ) + +/** + * @brief Verify the ADC regular channel setting. + * @param __CHANNEL__ programmed ADC regular channel. + * @retval SET (__CHANNEL__ is valid) or RESET (__CHANNEL__ is invalid) + */ +#define IS_ADC_REGULAR_RANK(__CHANNEL__) (((__CHANNEL__) == ADC_REGULAR_RANK_1 ) || \ + ((__CHANNEL__) == ADC_REGULAR_RANK_2 ) || \ + ((__CHANNEL__) == ADC_REGULAR_RANK_3 ) || \ + ((__CHANNEL__) == ADC_REGULAR_RANK_4 ) || \ + ((__CHANNEL__) == ADC_REGULAR_RANK_5 ) || \ + ((__CHANNEL__) == ADC_REGULAR_RANK_6 ) || \ + ((__CHANNEL__) == ADC_REGULAR_RANK_7 ) || \ + ((__CHANNEL__) == ADC_REGULAR_RANK_8 ) || \ + ((__CHANNEL__) == ADC_REGULAR_RANK_9 ) || \ + ((__CHANNEL__) == ADC_REGULAR_RANK_10) || \ + ((__CHANNEL__) == ADC_REGULAR_RANK_11) || \ + ((__CHANNEL__) == ADC_REGULAR_RANK_12) || \ + ((__CHANNEL__) == ADC_REGULAR_RANK_13) || \ + ((__CHANNEL__) == ADC_REGULAR_RANK_14) || \ + ((__CHANNEL__) == ADC_REGULAR_RANK_15) || \ + ((__CHANNEL__) == ADC_REGULAR_RANK_16) ) + +/** + * @} + */ + + +/* Private constants ---------------------------------------------------------*/ + +/** @defgroup ADC_Private_Constants ADC Private Constants + * @{ + */ + +/* Fixed timeout values for ADC conversion (including sampling time) */ +/* Maximum sampling time is 640.5 ADC clock cycle (SMPx[2:0] = 0b111 */ +/* Maximum conversion time is 12.5 + Maximum sampling time */ +/* or 12.5 + 640.5 = 653 ADC clock cycles */ +/* Minimum ADC Clock frequency is 0.14 MHz */ +/* Maximum conversion time is */ +/* 653 / 0.14 MHz = 4.66 ms */ +#define ADC_STOP_CONVERSION_TIMEOUT ( 5UL) /*!< ADC stop time-out value */ + +/* Delay for temperature sensor stabilization time. */ +/* Maximum delay is 120us (refer device datasheet, parameter tSTART). */ +/* Unit: us */ +#define ADC_TEMPSENSOR_DELAY_US (LL_ADC_DELAY_TEMPSENSOR_STAB_US) + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ + +/** @defgroup ADC_Exported_Macros ADC Exported Macros + * @{ + */ +/* Macro for internal HAL driver usage, and possibly can be used into code of */ +/* final user. */ + +/** @defgroup ADC_HAL_EM_HANDLE_IT_FLAG HAL ADC macro to manage HAL ADC handle, IT and flags. + * @{ + */ + +/** @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 /* USE_HAL_ADC_REGISTER_CALLBACKS */ + +/** + * @brief Enable ADC interrupt. + * @param __HANDLE__ ADC handle + * @param __INTERRUPT__ ADC Interrupt + * This parameter can be one of the following values: + * @arg @ref ADC_IT_RDY ADC Ready interrupt source + * @arg @ref ADC_IT_EOSMP ADC End of Sampling interrupt source + * @arg @ref ADC_IT_EOC ADC End of Regular Conversion interrupt source + * @arg @ref ADC_IT_EOS ADC End of Regular sequence of Conversions interrupt source + * @arg @ref ADC_IT_OVR ADC overrun interrupt source + * @arg @ref ADC_IT_JEOC ADC End of Injected Conversion interrupt source + * @arg @ref ADC_IT_JEOS ADC End of Injected sequence of Conversions interrupt source + * @arg @ref ADC_IT_AWD1 ADC Analog watchdog 1 interrupt source (main analog watchdog) + * @arg @ref ADC_IT_AWD2 ADC Analog watchdog 2 interrupt source (additional analog watchdog) + * @arg @ref ADC_IT_AWD3 ADC Analog watchdog 3 interrupt source (additional analog watchdog) + * @arg @ref ADC_IT_JQOVF ADC Injected Context Queue Overflow interrupt source. + * @retval None + */ +#define __HAL_ADC_ENABLE_IT(__HANDLE__, __INTERRUPT__) \ + (((__HANDLE__)->Instance->IER) |= (__INTERRUPT__)) + +/** + * @brief Disable ADC interrupt. + * @param __HANDLE__ ADC handle + * @param __INTERRUPT__ ADC Interrupt + * This parameter can be one of the following values: + * @arg @ref ADC_IT_RDY ADC Ready interrupt source + * @arg @ref ADC_IT_EOSMP ADC End of Sampling interrupt source + * @arg @ref ADC_IT_EOC ADC End of Regular Conversion interrupt source + * @arg @ref ADC_IT_EOS ADC End of Regular sequence of Conversions interrupt source + * @arg @ref ADC_IT_OVR ADC overrun interrupt source + * @arg @ref ADC_IT_JEOC ADC End of Injected Conversion interrupt source + * @arg @ref ADC_IT_JEOS ADC End of Injected sequence of Conversions interrupt source + * @arg @ref ADC_IT_AWD1 ADC Analog watchdog 1 interrupt source (main analog watchdog) + * @arg @ref ADC_IT_AWD2 ADC Analog watchdog 2 interrupt source (additional analog watchdog) + * @arg @ref ADC_IT_AWD3 ADC Analog watchdog 3 interrupt source (additional analog watchdog) + * @arg @ref ADC_IT_JQOVF ADC Injected Context Queue Overflow interrupt source. + * @retval None + */ +#define __HAL_ADC_DISABLE_IT(__HANDLE__, __INTERRUPT__) \ + (((__HANDLE__)->Instance->IER) &= ~(__INTERRUPT__)) + +/** @brief Checks if the specified ADC interrupt source is enabled or disabled. + * @param __HANDLE__ ADC handle + * @param __INTERRUPT__ ADC interrupt source to check + * This parameter can be one of the following values: + * @arg @ref ADC_IT_RDY ADC Ready interrupt source + * @arg @ref ADC_IT_EOSMP ADC End of Sampling interrupt source + * @arg @ref ADC_IT_EOC ADC End of Regular Conversion interrupt source + * @arg @ref ADC_IT_EOS ADC End of Regular sequence of Conversions interrupt source + * @arg @ref ADC_IT_OVR ADC overrun interrupt source + * @arg @ref ADC_IT_JEOC ADC End of Injected Conversion interrupt source + * @arg @ref ADC_IT_JEOS ADC End of Injected sequence of Conversions interrupt source + * @arg @ref ADC_IT_AWD1 ADC Analog watchdog 1 interrupt source (main analog watchdog) + * @arg @ref ADC_IT_AWD2 ADC Analog watchdog 2 interrupt source (additional analog watchdog) + * @arg @ref ADC_IT_AWD3 ADC Analog watchdog 3 interrupt source (additional analog watchdog) + * @arg @ref ADC_IT_JQOVF ADC Injected Context Queue Overflow interrupt source. + * @retval State of interruption (SET or RESET) + */ +#define __HAL_ADC_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) \ + (((__HANDLE__)->Instance->IER & (__INTERRUPT__)) == (__INTERRUPT__)) + +/** + * @brief Check whether the specified ADC flag is set or not. + * @param __HANDLE__ ADC handle + * @param __FLAG__ ADC flag + * This parameter can be one of the following values: + * @arg @ref ADC_FLAG_RDY ADC Ready flag + * @arg @ref ADC_FLAG_EOSMP ADC End of Sampling flag + * @arg @ref ADC_FLAG_EOC ADC End of Regular Conversion flag + * @arg @ref ADC_FLAG_EOS ADC End of Regular sequence of Conversions flag + * @arg @ref ADC_FLAG_OVR ADC overrun flag + * @arg @ref ADC_FLAG_JEOC ADC End of Injected Conversion flag + * @arg @ref ADC_FLAG_JEOS ADC End of Injected sequence of Conversions flag + * @arg @ref ADC_FLAG_AWD1 ADC Analog watchdog 1 flag (main analog watchdog) + * @arg @ref ADC_FLAG_AWD2 ADC Analog watchdog 2 flag (additional analog watchdog) + * @arg @ref ADC_FLAG_AWD3 ADC Analog watchdog 3 flag (additional analog watchdog) + * @arg @ref ADC_FLAG_JQOVF ADC Injected Context Queue Overflow flag. + * @retval State of flag (TRUE or FALSE). + */ +#define __HAL_ADC_GET_FLAG(__HANDLE__, __FLAG__) \ + ((((__HANDLE__)->Instance->ISR) & (__FLAG__)) == (__FLAG__)) + +/** + * @brief Clear the specified ADC flag. + * @param __HANDLE__ ADC handle + * @param __FLAG__ ADC flag + * This parameter can be one of the following values: + * @arg @ref ADC_FLAG_RDY ADC Ready flag + * @arg @ref ADC_FLAG_EOSMP ADC End of Sampling flag + * @arg @ref ADC_FLAG_EOC ADC End of Regular Conversion flag + * @arg @ref ADC_FLAG_EOS ADC End of Regular sequence of Conversions flag + * @arg @ref ADC_FLAG_OVR ADC overrun flag + * @arg @ref ADC_FLAG_JEOC ADC End of Injected Conversion flag + * @arg @ref ADC_FLAG_JEOS ADC End of Injected sequence of Conversions flag + * @arg @ref ADC_FLAG_AWD1 ADC Analog watchdog 1 flag (main analog watchdog) + * @arg @ref ADC_FLAG_AWD2 ADC Analog watchdog 2 flag (additional analog watchdog) + * @arg @ref ADC_FLAG_AWD3 ADC Analog watchdog 3 flag (additional analog watchdog) + * @arg @ref ADC_FLAG_JQOVF ADC Injected Context Queue Overflow flag. + * @retval None + */ +/* Note: bit cleared bit by writing 1 (writing 0 has no effect on any bit of register ISR) */ +#define __HAL_ADC_CLEAR_FLAG(__HANDLE__, __FLAG__) \ + (((__HANDLE__)->Instance->ISR) = (__FLAG__)) + +/** + * @} + */ + +/** @defgroup ADC_HAL_EM_HELPER_MACRO HAL ADC helper macro + * @{ + */ + +/** + * @brief Helper macro to get ADC channel number in decimal format + * from literals ADC_CHANNEL_x. + * @note Example: + * __HAL_ADC_CHANNEL_TO_DECIMAL_NB(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 ADC_CHANNEL_0 (3) + * @arg @ref ADC_CHANNEL_1 (3) + * @arg @ref ADC_CHANNEL_2 (3) + * @arg @ref ADC_CHANNEL_3 (3) + * @arg @ref ADC_CHANNEL_4 (3) + * @arg @ref ADC_CHANNEL_5 (3) + * @arg @ref ADC_CHANNEL_6 + * @arg @ref ADC_CHANNEL_7 + * @arg @ref ADC_CHANNEL_8 + * @arg @ref ADC_CHANNEL_9 + * @arg @ref ADC_CHANNEL_10 + * @arg @ref ADC_CHANNEL_11 + * @arg @ref ADC_CHANNEL_12 + * @arg @ref ADC_CHANNEL_13 + * @arg @ref ADC_CHANNEL_14 + * @arg @ref ADC_CHANNEL_15 + * @arg @ref ADC_CHANNEL_16 + * @arg @ref ADC_CHANNEL_17 + * @arg @ref ADC_CHANNEL_18 + * @arg @ref ADC_CHANNEL_19 + * @arg @ref ADC_CHANNEL_VREFINT (1) + * @arg @ref ADC_CHANNEL_TEMPSENSOR (1) + * @arg @ref ADC_CHANNEL_VBAT (2) + * @arg @ref ADC_CHANNEL_VDDCORE (2) + * + * (1) On STM32H563xx/573xx, parameter available only on ADC instance: ADC1.\n + * (2) On STM32H563xx/573xx, parameter available only on ADC instance: ADC2.\n + * (3) On STM32H5, fast channel allows: 2.5 (sampling) + 12.5 (conversion 12b) = 15 ADC clock cycles (fADC) + * Other channels are slow channels: 6.5 (sampling) + 12.5 (conversion 12b) = 19 ADC clock cycles (fADC) + * @retval Value between Min_Data=0 and Max_Data=18 + */ +#define __HAL_ADC_CHANNEL_TO_DECIMAL_NB(__CHANNEL__) \ + __LL_ADC_CHANNEL_TO_DECIMAL_NB((__CHANNEL__)) + +/** + * @brief Helper macro to get ADC channel in literal format ADC_CHANNEL_x + * from number in decimal format. + * @note Example: + * __HAL_ADC_DECIMAL_NB_TO_CHANNEL(4) + * will return a data equivalent to "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 ADC_CHANNEL_0 (3) + * @arg @ref ADC_CHANNEL_1 (3) + * @arg @ref ADC_CHANNEL_2 (3) + * @arg @ref ADC_CHANNEL_3 (3) + * @arg @ref ADC_CHANNEL_4 (3) + * @arg @ref ADC_CHANNEL_5 (3) + * @arg @ref ADC_CHANNEL_6 + * @arg @ref ADC_CHANNEL_7 + * @arg @ref ADC_CHANNEL_8 + * @arg @ref ADC_CHANNEL_9 + * @arg @ref ADC_CHANNEL_10 + * @arg @ref ADC_CHANNEL_11 + * @arg @ref ADC_CHANNEL_12 + * @arg @ref ADC_CHANNEL_13 + * @arg @ref ADC_CHANNEL_14 + * @arg @ref ADC_CHANNEL_15 + * @arg @ref ADC_CHANNEL_16 + * @arg @ref ADC_CHANNEL_17 + * @arg @ref ADC_CHANNEL_18 + * @arg @ref ADC_CHANNEL_19 + * @arg @ref ADC_CHANNEL_VREFINT (1)(4) + * @arg @ref ADC_CHANNEL_TEMPSENSOR (1)(4) + * @arg @ref ADC_CHANNEL_VBAT (2)(4) + * @arg @ref ADC_CHANNEL_VDDCORE (2)(4) + * + * (1) On STM32H563xx/573xx, parameter available only on ADC instance: ADC1.\n + * (2) On STM32H563xx/573xx, parameter available only on ADC instance: ADC2.\n + * (3) On STM32H5, fast channel allows: 2.5 (sampling) + 12.5 (conversion 12b) = 15 ADC clock cycles (fADC) + * Other channels are slow channels: 6.5 (sampling) + 12.5 (conversion 12b) = 19 ADC clock cycles (fADC) + * (4) 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 __HAL_ADC_DECIMAL_NB_TO_CHANNEL(__DECIMAL_NB__) \ + __LL_ADC_DECIMAL_NB_TO_CHANNEL((__DECIMAL_NB__)) + +/** + * @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: + * ADC_CHANNEL_VREFINT, ADC_CHANNEL_TEMPSENSOR, ... + * - ADC external channel (channel connected to a GPIO pin): + * ADC_CHANNEL_1, ADC_CHANNEL_2, ... + * @note The channel parameter must be a value defined from literal + * definition of a ADC internal channel (ADC_CHANNEL_VREFINT, + * ADC_CHANNEL_TEMPSENSOR, ...), + * ADC external channel (ADC_CHANNEL_1, 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 ADC_CHANNEL_0 (3) + * @arg @ref ADC_CHANNEL_1 (3) + * @arg @ref ADC_CHANNEL_2 (3) + * @arg @ref ADC_CHANNEL_3 (3) + * @arg @ref ADC_CHANNEL_4 (3) + * @arg @ref ADC_CHANNEL_5 (3) + * @arg @ref ADC_CHANNEL_6 + * @arg @ref ADC_CHANNEL_7 + * @arg @ref ADC_CHANNEL_8 + * @arg @ref ADC_CHANNEL_9 + * @arg @ref ADC_CHANNEL_10 + * @arg @ref ADC_CHANNEL_11 + * @arg @ref ADC_CHANNEL_12 + * @arg @ref ADC_CHANNEL_13 + * @arg @ref ADC_CHANNEL_14 + * @arg @ref ADC_CHANNEL_15 + * @arg @ref ADC_CHANNEL_16 + * @arg @ref ADC_CHANNEL_17 + * @arg @ref ADC_CHANNEL_18 + * @arg @ref ADC_CHANNEL_19 + * @arg @ref ADC_CHANNEL_VREFINT (1) + * @arg @ref ADC_CHANNEL_TEMPSENSOR (1) + * @arg @ref ADC_CHANNEL_VBAT (2) + * @arg @ref ADC_CHANNEL_VDDCORE (2) + * + * (1) On STM32H563xx/573xx, parameter available only on ADC instance: ADC1.\n + * (2) On STM32H563xx/573xx, parameter available only on ADC instance: ADC2.\n + * (3) On STM32H5, fast channel allows: 2.5 (sampling) + 12.5 (conversion 12b) = 15 ADC clock cycles (fADC) + * Other channels are slow channels: 6.5 (sampling) + 12.5 (conversion 12b) = 19 ADC clock cycles (fADC) + * @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 __HAL_ADC_IS_CHANNEL_INTERNAL(__CHANNEL__) \ + __LL_ADC_IS_CHANNEL_INTERNAL((__CHANNEL__)) + +/** + * @brief Helper macro to convert a channel defined from parameter + * definition of a ADC internal channel (ADC_CHANNEL_VREFINT, + * ADC_CHANNEL_TEMPSENSOR, ...), + * to its equivalent parameter definition of a ADC external channel + * (ADC_CHANNEL_1, ADC_CHANNEL_2, ...). + * @note The channel parameter can be, additionally to a value + * defined from parameter definition of a ADC internal channel + * (ADC_CHANNEL_VREFINT, ADC_CHANNEL_TEMPSENSOR, ...), + * a value defined from parameter definition of + * ADC external channel (ADC_CHANNEL_1, 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 ADC_CHANNEL_0 (3) + * @arg @ref ADC_CHANNEL_1 (3) + * @arg @ref ADC_CHANNEL_2 (3) + * @arg @ref ADC_CHANNEL_3 (3) + * @arg @ref ADC_CHANNEL_4 (3) + * @arg @ref ADC_CHANNEL_5 (3) + * @arg @ref ADC_CHANNEL_6 + * @arg @ref ADC_CHANNEL_7 + * @arg @ref ADC_CHANNEL_8 + * @arg @ref ADC_CHANNEL_9 + * @arg @ref ADC_CHANNEL_10 + * @arg @ref ADC_CHANNEL_11 + * @arg @ref ADC_CHANNEL_12 + * @arg @ref ADC_CHANNEL_13 + * @arg @ref ADC_CHANNEL_14 + * @arg @ref ADC_CHANNEL_15 + * @arg @ref ADC_CHANNEL_16 + * @arg @ref ADC_CHANNEL_17 + * @arg @ref ADC_CHANNEL_18 + * @arg @ref ADC_CHANNEL_19 + * @arg @ref ADC_CHANNEL_VREFINT (1) + * @arg @ref ADC_CHANNEL_TEMPSENSOR (1) + * @arg @ref ADC_CHANNEL_VBAT (2) + * @arg @ref ADC_CHANNEL_VDDCORE (2) + * + * (1) On STM32H563xx/573xx, parameter available only on ADC instance: ADC1.\n + * (2) On STM32H563xx/573xx, parameter available only on ADC instance: ADC2.\n + * (3) On STM32H5, fast channel allows: 2.5 (sampling) + 12.5 (conversion 12b) = 15 ADC clock cycles (fADC) + * Other channels are slow channels: 6.5 (sampling) + 12.5 (conversion 12b) = 19 ADC clock cycles (fADC) + * @retval Returned value can be one of the following values: + * @arg @ref ADC_CHANNEL_0 + * @arg @ref ADC_CHANNEL_1 + * @arg @ref ADC_CHANNEL_2 + * @arg @ref ADC_CHANNEL_3 + * @arg @ref ADC_CHANNEL_4 + * @arg @ref ADC_CHANNEL_5 + * @arg @ref ADC_CHANNEL_6 + * @arg @ref ADC_CHANNEL_7 + * @arg @ref ADC_CHANNEL_8 + * @arg @ref ADC_CHANNEL_9 + * @arg @ref ADC_CHANNEL_10 + * @arg @ref ADC_CHANNEL_11 + * @arg @ref ADC_CHANNEL_12 + * @arg @ref ADC_CHANNEL_13 + * @arg @ref ADC_CHANNEL_14 + * @arg @ref ADC_CHANNEL_15 + * @arg @ref ADC_CHANNEL_16 + * @arg @ref ADC_CHANNEL_17 + * @arg @ref ADC_CHANNEL_18 + */ +#define __HAL_ADC_CHANNEL_INTERNAL_TO_EXTERNAL(__CHANNEL__) \ + __LL_ADC_CHANNEL_INTERNAL_TO_EXTERNAL((__CHANNEL__)) + +/** + * @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 (ADC_CHANNEL_VREFINT, + * ADC_CHANNEL_TEMPSENSOR, ...), + * must not be a value defined from parameter definition of + * ADC external channel (ADC_CHANNEL_1, 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 ADC_CHANNEL_VREFINT (1) + * @arg @ref ADC_CHANNEL_TEMPSENSOR (1) + * @arg @ref ADC_CHANNEL_VBAT (2) + * @arg @ref ADC_CHANNEL_VDDCORE (2) + * + * (1) On STM32H563xx/573xx, parameter available only on ADC instance: ADC1. + * (2) On STM32H563xx/573xx, parameter available only on ADC instance: ADC2. + * @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 __HAL_ADC_IS_CHANNEL_INTERNAL_AVAILABLE(__ADC_INSTANCE__, __CHANNEL__) \ + __LL_ADC_IS_CHANNEL_INTERNAL_AVAILABLE((__ADC_INSTANCE__), (__CHANNEL__)) + +#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 __HAL_ADC_MULTI_CONV_DATA_MASTER_SLAVE(__ADC_MULTI_MASTER_SLAVE__, __ADC_MULTI_CONV_DATA__) \ + __LL_ADC_MULTI_CONV_DATA_MASTER_SLAVE((__ADC_MULTI_MASTER_SLAVE__), (__ADC_MULTI_CONV_DATA__)) +#endif /* ADC_MULTIMODE_SUPPORT */ + +/** + * @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 + */ +#define __HAL_ADC_COMMON_INSTANCE(__ADCx__) \ + __LL_ADC_COMMON_INSTANCE((__ADCx__)) + +/** + * @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. + */ +#define __HAL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(__ADCXY_COMMON__) \ + __LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE((__ADCXY_COMMON__)) + +/** + * @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 ADC_RESOLUTION_12B + * @arg @ref ADC_RESOLUTION_10B + * @arg @ref ADC_RESOLUTION_8B + * @arg @ref ADC_RESOLUTION_6B + * @retval ADC conversion data full-scale digital value + */ +#define __HAL_ADC_DIGITAL_SCALE(__ADC_RESOLUTION__) \ + __LL_ADC_DIGITAL_SCALE((__ADC_RESOLUTION__)) + +/** + * @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 ADC_RESOLUTION_12B + * @arg @ref ADC_RESOLUTION_10B + * @arg @ref ADC_RESOLUTION_8B + * @arg @ref ADC_RESOLUTION_6B + * @param __ADC_RESOLUTION_TARGET__ Resolution of the data after conversion + * This parameter can be one of the following values: + * @arg @ref ADC_RESOLUTION_12B + * @arg @ref ADC_RESOLUTION_10B + * @arg @ref ADC_RESOLUTION_8B + * @arg @ref ADC_RESOLUTION_6B + * @retval ADC conversion data to the requested resolution + */ +#define __HAL_ADC_CONVERT_DATA_RESOLUTION(__DATA__,\ + __ADC_RESOLUTION_CURRENT__,\ + __ADC_RESOLUTION_TARGET__) \ +__LL_ADC_CONVERT_DATA_RESOLUTION((__DATA__),\ + (__ADC_RESOLUTION_CURRENT__),\ + (__ADC_RESOLUTION_TARGET__)) + +/** + * @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 ADC_RESOLUTION_12B + * @arg @ref ADC_RESOLUTION_10B + * @arg @ref ADC_RESOLUTION_8B + * @arg @ref ADC_RESOLUTION_6B + * @retval ADC conversion data equivalent voltage value (unit: mVolt) + */ +#define __HAL_ADC_CALC_DATA_TO_VOLTAGE(__VREFANALOG_VOLTAGE__,\ + __ADC_DATA__,\ + __ADC_RESOLUTION__) \ +__LL_ADC_CALC_DATA_TO_VOLTAGE((__VREFANALOG_VOLTAGE__),\ + (__ADC_DATA__),\ + (__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 ADC_RESOLUTION_12B + * @arg @ref ADC_RESOLUTION_10B + * @arg @ref ADC_RESOLUTION_8B + * @arg @ref ADC_RESOLUTION_6B + * @retval Analog reference voltage (unit: mV) + */ +#define __HAL_ADC_CALC_VREFANALOG_VOLTAGE(__VREFINT_ADC_DATA__,\ + __ADC_RESOLUTION__) \ +__LL_ADC_CALC_VREFANALOG_VOLTAGE((__VREFINT_ADC_DATA__),\ + (__ADC_RESOLUTION__)) + +/** + * @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 ADC_RESOLUTION_12B + * @arg @ref ADC_RESOLUTION_10B + * @arg @ref ADC_RESOLUTION_8B + * @arg @ref ADC_RESOLUTION_6B + * @retval Temperature (unit: degree Celsius) + */ +#define __HAL_ADC_CALC_TEMPERATURE(__VREFANALOG_VOLTAGE__,\ + __TEMPSENSOR_ADC_DATA__,\ + __ADC_RESOLUTION__) \ +__LL_ADC_CALC_TEMPERATURE((__VREFANALOG_VOLTAGE__),\ + (__TEMPSENSOR_ADC_DATA__),\ + (__ADC_RESOLUTION__)) + +/** + * @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 this STM32 series, 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 this STM32 series, refer to device datasheet parameter "V30" + * (corresponding to TS_CAL1). + * @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 ADC_RESOLUTION_12B + * @arg @ref ADC_RESOLUTION_10B + * @arg @ref ADC_RESOLUTION_8B + * @arg @ref ADC_RESOLUTION_6B + * @retval Temperature (unit: degree Celsius) + */ +#define __HAL_ADC_CALC_TEMPERATURE_TYP_PARAMS(__TEMPSENSOR_TYP_AVGSLOPE__,\ + __TEMPSENSOR_TYP_CALX_V__,\ + __TEMPSENSOR_CALX_TEMP__,\ + __VREFANALOG_VOLTAGE__,\ + __TEMPSENSOR_ADC_DATA__,\ + __ADC_RESOLUTION__) \ +__LL_ADC_CALC_TEMPERATURE_TYP_PARAMS((__TEMPSENSOR_TYP_AVGSLOPE__),\ + (__TEMPSENSOR_TYP_CALX_V__),\ + (__TEMPSENSOR_CALX_TEMP__),\ + (__VREFANALOG_VOLTAGE__),\ + (__TEMPSENSOR_ADC_DATA__),\ + (__ADC_RESOLUTION__)) + +/** + * @} + */ + +/** + * @} + */ + +/* Include ADC HAL Extended module */ +#include "stm32h5xx_hal_adc_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup ADC_Exported_Functions + * @{ + */ + +/** @addtogroup ADC_Exported_Functions_Group1 + * @brief Initialization and Configuration functions + * @{ + */ +/* Initialization and 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 + * @brief IO operation functions + * @{ + */ +/* IO operation functions *****************************************************/ + +/* Blocking mode: Polling */ +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); + +/* Non-blocking mode: Interruption */ +HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef *hadc); +HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef *hadc); + +/* Non-blocking mode: DMA */ +HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef *hadc, uint32_t *pData, uint32_t Length); +HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef *hadc); + +/* ADC retrieve conversion value intended to be used with polling or interruption */ +uint32_t HAL_ADC_GetValue(const ADC_HandleTypeDef *hadc); + +/* ADC sampling control */ +HAL_StatusTypeDef HAL_ADC_StartSampling(ADC_HandleTypeDef *hadc); +HAL_StatusTypeDef HAL_ADC_StopSampling(ADC_HandleTypeDef *hadc); + +/* ADC IRQHandler and Callbacks used in non-blocking modes (Interruption and DMA) */ +void HAL_ADC_IRQHandler(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 + * @brief Peripheral Control functions + * @{ + */ +/* Peripheral Control functions ***********************************************/ +HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef *hadc, const ADC_ChannelConfTypeDef *pConfig); +HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef *hadc, + const ADC_AnalogWDGConfTypeDef *pAnalogWDGConfig); + +/** + * @} + */ + +/* Peripheral State functions *************************************************/ +/** @addtogroup ADC_Exported_Functions_Group4 + * @{ + */ +uint32_t HAL_ADC_GetState(const ADC_HandleTypeDef *hadc); +uint32_t HAL_ADC_GetError(const ADC_HandleTypeDef *hadc); + +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @addtogroup ADC_Private_Functions ADC Private Functions + * @{ + */ +HAL_StatusTypeDef ADC_ConversionStop(ADC_HandleTypeDef *hadc, uint32_t ConversionGroup); +HAL_StatusTypeDef ADC_Enable(ADC_HandleTypeDef *hadc); +HAL_StatusTypeDef ADC_Disable(ADC_HandleTypeDef *hadc); +void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma); +void ADC_DMAHalfConvCplt(DMA_HandleTypeDef *hdma); +void ADC_DMAError(DMA_HandleTypeDef *hdma); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* STM32H5xx_HAL_ADC_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_adc_ex.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_adc_ex.h new file mode 100644 index 0000000000..c6f496dbd4 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_adc_ex.h @@ -0,0 +1,1216 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_adc_ex.h + * @author MCD Application Team + * @brief Header file of ADC HAL extended module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_ADC_EX_H +#define STM32H5xx_HAL_ADC_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup ADCEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup ADCEx_Exported_Types ADC Extended Exported Types + * @{ + */ + +/** + * @brief ADC Injected Conversion Oversampling structure definition + */ +typedef struct +{ + uint32_t Ratio; /*!< Configures the oversampling ratio. + This parameter can be a value of @ref ADC_HAL_EC_OVS_RATIO */ + + uint32_t RightBitShift; /*!< Configures the division coefficient for the Oversampler. + This parameter can be a value of @ref ADC_HAL_EC_OVS_SHIFT */ +} ADC_InjOversamplingTypeDef; + +/** + * @brief Structure definition of ADC group injected and ADC channel affected to ADC group injected + * @note Parameters of this structure are shared within 2 scopes: + * - Scope channel: InjectedChannel, InjectedRank, InjectedSamplingTime , InjectedSingleDiff, + * InjectedOffsetNumber, InjectedOffset, InjectedOffsetSign, InjectedOffsetSaturation + * - Scope ADC group injected (affects all channels of injected group): InjectedNbrOfConversion, + * InjectedDiscontinuousConvMode, + * AutoInjectedConv, QueueInjectedContext, ExternalTrigInjecConv, ExternalTrigInjecConvEdge, + * InjecOversamplingMode, InjecOversampling. + * @note The setting of these parameters by function HAL_ADCEx_InjectedConfigChannel() is conditioned to ADC state. + * ADC state can be either: + * - For all parameters: ADC disabled (this is the only possible ADC state to modify parameter + * 'InjectedSingleDiff') + * - For parameters 'InjectedDiscontinuousConvMode', 'QueueInjectedContext', 'InjecOversampling': ADC enabled + * without conversion on going on injected group. + * - For parameters 'InjectedSamplingTime', 'InjectedOffset', 'InjectedOffsetNumber', 'InjectedOffsetSign', + * 'InjectedOffsetSaturation', 'AutoInjectedConv': ADC enabled without conversion on going on regular and + * injected groups. + * - For parameters 'InjectedChannel', 'InjectedRank', 'InjectedNbrOfConversion', 'ExternalTrigInjecConv', + * 'ExternalTrigInjecConvEdge': ADC enabled and while conversion on going + * on ADC groups regular and injected. + * 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 behavior in case of intended action to update another + * parameter (which fulfills the ADC state condition) on the fly). + */ +typedef struct +{ + uint32_t InjectedChannel; /*!< Specifies the channel to configure into ADC group injected. + This parameter can be a value of @ref ADC_HAL_EC_CHANNEL + Note: Depending on devices and ADC instances, some channels may not be + available on device package pins. Refer to device datasheet for + channels availability. */ + + uint32_t InjectedRank; /*!< Specifies the rank in the ADC group injected sequencer. + This parameter must be a value of @ref ADC_INJ_SEQ_RANKS. + Note: 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 + 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.5 ADC clock cycles at ADC resolution 12 bits, 10.5 cycles at 10 bits, + 8.5 cycles at 8 bits, 6.5 cycles at 6 bits). + This parameter can be a value of @ref ADC_HAL_EC_CHANNEL_SAMPLINGTIME. + Caution: This parameter applies to a channel that can be used in a + regular and/or injected group. It overwrites the last setting. + Note: In case of usage of internal measurement channels (VrefInt, ...), + 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. */ + + uint32_t InjectedSingleDiff; /*!< Selection of single-ended or differential input. + In differential mode: Differential measurement is between the selected + channel 'i' (positive input) and channel 'i+1' (negative input). + Only channel 'i' has to be configured, channel 'i+1' is configured + automatically. + This parameter must be a value of + @ref ADC_HAL_EC_CHANNEL_SINGLE_DIFF_ENDING. + Caution: This parameter applies to a channel that can be used in a + regular and/or injected group. It overwrites the last setting. + Note: Refer to Reference Manual to ensure the selected channel is + available in differential mode. + Note: When configuring a channel 'i' in differential mode, the channel + 'i+1' is not usable separately. + 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 behavior in case of another + parameter update on the fly) */ + + uint32_t InjectedOffsetNumber; /*!< Selects the offset number. + This parameter can be a value of @ref ADC_HAL_EC_OFFSET_NB. + Caution: Only one offset is allowed per channel. This parameter + overwrites the last setting. */ + + uint32_t InjectedOffset; /*!< Defines the offset to be applied on the raw converted data. + 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. + 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). */ + + uint32_t InjectedOffsetSign; /*!< Define if the offset should be subtracted (negative sign) or added + (positive sign) from or to the raw converted data. + This parameter can be a value of @ref ADCEx_OffsetSign. + 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). */ + FunctionalState InjectedOffsetSaturation; /*!< Define if the offset should be saturated upon under or over flow. + This parameter value can be ENABLE or DISABLE. + 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). */ + + uint32_t InjectedNbrOfConversion; /*!< Specifies the number of ranks that will be converted within the ADC group + injected 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 ADC group injected + 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. + This parameter can be set to ENABLE or DISABLE. + Note: This parameter must be modified when ADC is disabled (before ADC + start conversion or after ADC stop conversion). + Note: For injected group, discontinuous mode converts the sequence + channel by channel (discontinuous length fixed to 1 rank). + 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 group injected automatic 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_INJECTED_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. */ + + FunctionalState QueueInjectedContext; /*!< Specifies whether the context queue feature is enabled. + This parameter can be set to ENABLE or DISABLE. + If context queue is enabled, injected sequencer&channels configurations + are queued on up to 2 contexts. If a + new injected context is set when queue is full, error is triggered by + interruption and through function + 'HAL_ADCEx_InjectedQueueOverflowCallback'. + Caution: This feature request that the sequence is fully configured + before injected conversion start. + Therefore, configure channels with as many calls to + HAL_ADCEx_InjectedConfigChannel() as the + 'InjectedNbrOfConversion' parameter. + 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. + Note: This parameter must be modified when ADC is disabled (before ADC + start conversion or after ADC stop conversion). */ + + 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 + and software trigger is used instead. + This parameter can be a value of + @ref ADC_injected_external_trigger_source. + 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 ADC_injected_external_trigger_edge. + If trigger source 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. */ + + FunctionalState InjecOversamplingMode; /*!< Specifies whether the oversampling feature is enabled or disabled. + This parameter can be set to ENABLE or DISABLE. + Note: This parameter can be modified only if there is no + conversion is ongoing (both ADSTART and JADSTART cleared). */ + + ADC_InjOversamplingTypeDef InjecOversampling; /*!< Specifies the Oversampling parameters. + Caution: this setting overwrites the previous oversampling + configuration if oversampling already enabled. + Note: This parameter can be modified only if there is no + conversion is ongoing (both ADSTART and JADSTART cleared).*/ +} ADC_InjectionConfTypeDef; + +#if defined(ADC_MULTIMODE_SUPPORT) +/** + * @brief Structure definition of ADC multimode + * @note The setting of these parameters by function HAL_ADCEx_MultiModeConfigChannel() is conditioned by ADCs state + * (both Master and Slave ADCs). + * Both Master and Slave ADCs must be disabled. + */ +typedef struct +{ + uint32_t Mode; /*!< Configures the ADC to operate in independent or multimode. + This parameter can be a value of @ref ADC_HAL_EC_MULTI_MODE. */ + + uint32_t DMAAccessMode; /*!< Configures the DMA mode for multimode ADC: + selection whether 2 DMA channels (each ADC uses its own DMA channel) or 1 DMA channel + (one DMA channel for both ADC, DMA of ADC master). + This parameter can be a value of @ref ADC_HAL_EC_MULTI_DMA_TRANSFER_RESOLUTION. */ + + uint32_t TwoSamplingDelay; /*!< Configures the Delay between 2 sampling phases. + This parameter can be a value of @ref ADC_HAL_EC_MULTI_TWOSMP_DELAY. + Delay range depends on selected resolution: + from 1 to 12 clock cycles for 12 bits, from 1 to 10 clock cycles for 10 bits, + from 1 to 8 clock cycles for 8 bits, from 1 to 6 clock cycles for 6 bits. */ +} ADC_MultiModeTypeDef; +#endif /* ADC_MULTIMODE_SUPPORT */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup ADCEx_Exported_Constants ADC Extended Exported Constants + * @{ + */ + +/** @defgroup ADC_injected_external_trigger_source ADC group injected trigger source + * @{ + */ +/* ADC group regular trigger sources for all ADC instances */ +#define ADC_INJECTED_SOFTWARE_START (LL_ADC_INJ_TRIG_SOFTWARE) /*!< ADC group injected conversion + trigger software start */ +/* Triggers common to all devices of STM32H5 series */ +#define ADC_EXTERNALTRIGINJEC_T1_TRGO (LL_ADC_INJ_TRIG_EXT_TIM1_TRGO) /*!< ADC group injected conversion + trigger from external peripheral: TIM1 TRGO event. */ +#define ADC_EXTERNALTRIGINJEC_T1_CC4 (LL_ADC_INJ_TRIG_EXT_TIM1_CH4) /*!< ADC group injected conversion + trigger from external peripheral: TIM1 channel 4 event (capture compare). */ +#define ADC_EXTERNALTRIGINJEC_T2_TRGO (LL_ADC_INJ_TRIG_EXT_TIM2_TRGO) /*!< ADC group injected conversion + trigger from external peripheral: TIM2 TRGO event. */ +#define ADC_EXTERNALTRIGINJEC_T2_CC1 (LL_ADC_INJ_TRIG_EXT_TIM2_CH1) /*!< ADC group injected conversion + trigger from external peripheral: TIM2 channel 1 event (capture compare). */ +#define ADC_EXTERNALTRIGINJEC_T3_CC4 (LL_ADC_INJ_TRIG_EXT_TIM3_CH4) /*!< ADC group injected conversion + trigger from external peripheral: TIM3 channel 4 event (capture compare). */ +#define ADC_EXTERNALTRIGINJEC_EXT_IT15 (LL_ADC_INJ_TRIG_EXT_EXTI_LINE15) /*!< ADC group injected conversion + trigger from external peripheral: external interrupt line 15. */ +#define ADC_EXTERNALTRIGINJEC_T1_TRGO2 (LL_ADC_INJ_TRIG_EXT_TIM1_TRGO2) /*!< ADC group injected conversion + trigger from external peripheral: TIM1 TRGO2 event. */ +#define ADC_EXTERNALTRIGINJEC_T3_CC3 (LL_ADC_INJ_TRIG_EXT_TIM3_CH3) /*!< ADC group injected conversion + trigger from external peripheral: TIM3 channel 3 event (capture compare). */ +#define ADC_EXTERNALTRIGINJEC_T3_TRGO (LL_ADC_INJ_TRIG_EXT_TIM3_TRGO) /*!< ADC group injected conversion + trigger from external peripheral: TIM3 TRGO event. */ +#define ADC_EXTERNALTRIGINJEC_T3_CC1 (LL_ADC_INJ_TRIG_EXT_TIM3_CH1) /*!< ADC group injected conversion + trigger from external peripheral: TIM3 channel 1 event (capture compare). */ +#define ADC_EXTERNALTRIGINJEC_T6_TRGO (LL_ADC_INJ_TRIG_EXT_TIM6_TRGO) /*!< ADC group injected conversion + trigger from external peripheral: TIM6 TRGO event. */ +#define ADC_EXTERNALTRIGINJEC_LPTIM1_CH1 (LL_ADC_INJ_TRIG_EXT_LPTIM1_CH1) /*!< ADC group injected conversion + trigger from external peripheral: LPTIM1 channel 1 event. */ +#define ADC_EXTERNALTRIGINJEC_LPTIM2_CH1 (LL_ADC_INJ_TRIG_EXT_LPTIM2_CH1) /*!< ADC group injected conversion + trigger from external peripheral: LPTIM2 channel 1 event. */ + +/* Triggers specific to some devices of STM32H5 series */ +#if defined(TIM8) +/* Devices STM32H563/H573xx */ +#define ADC_EXTERNALTRIGINJEC_T4_TRGO (LL_ADC_INJ_TRIG_EXT_TIM4_TRGO) /*!< ADC group injected conversion + trigger from external peripheral: TIM4 TRGO event. + Specific to devices STM32H563/H573xx. */ +#define ADC_EXTERNALTRIGINJEC_T8_CC4 (LL_ADC_INJ_TRIG_EXT_TIM8_CH4) /*!< ADC group injected conversion + trigger from external peripheral: TIM8 channel 4 event (capture compare). */ +#define ADC_EXTERNALTRIGINJEC_T8_TRGO (LL_ADC_INJ_TRIG_EXT_TIM8_TRGO) /*!< ADC group injected conversion + trigger from external peripheral: TIM8 TRGO event. + Specific to devices STM32H563/H573xx. */ +#define ADC_EXTERNALTRIGINJEC_T8_TRGO2 (LL_ADC_INJ_TRIG_EXT_TIM8_TRGO2) /*!< ADC group injected conversion + trigger from external peripheral: TIM8 TRGO2 event. + Specific to devices STM32H563/H573xx. */ +#define ADC_EXTERNALTRIGINJEC_T15_TRGO (LL_ADC_INJ_TRIG_EXT_TIM15_TRGO) /*!< ADC group injected conversion + trigger from external peripheral: TIM15 TRGO event. + Specific to devices STM32H563/H573xx. */ +#else +/* Devices STM32H503xx */ +#define ADC_EXTERNALTRIGINJEC_T7_TRGO (LL_ADC_INJ_TRIG_EXT_TIM7_TRGO) /*!< ADC group injected conversion + trigger from external peripheral: TIM7 TRGO event. + Specific to devices STM32H503xx. */ +#endif /* Devices STM32H563/H573xx or STM32H503xx */ +/** + * @} + */ + +/** @defgroup ADC_injected_external_trigger_edge ADC group injected trigger edge (when external trigger is selected) + * @{ + */ +#define ADC_EXTERNALTRIGINJECCONV_EDGE_NONE (0x00000000UL) /*!< Injected conversions trigger + disabled (SW start)*/ +#define ADC_EXTERNALTRIGINJECCONV_EDGE_RISING (ADC_JSQR_JEXTEN_0) /*!< Injected conversions trigger + polarity set to rising edge */ +#define ADC_EXTERNALTRIGINJECCONV_EDGE_FALLING (ADC_JSQR_JEXTEN_1) /*!< Injected conversions trigger + polarity set to falling edge */ +#define ADC_EXTERNALTRIGINJECCONV_EDGE_RISINGFALLING (ADC_JSQR_JEXTEN) /*!< Injected conversions trigger + polarity set to both rising and falling edges */ +/** + * @} + */ + +/** @defgroup ADC_HAL_EC_CHANNEL_SINGLE_DIFF_ENDING Channel - Single or differential ending + * @{ + */ +#define ADC_SINGLE_ENDED (LL_ADC_SINGLE_ENDED) /*!< ADC channel ending set to single ended */ +#define ADC_DIFFERENTIAL_ENDED (LL_ADC_DIFFERENTIAL_ENDED) /*!< ADC channel ending set to differential */ +/** + * @} + */ + +/** @defgroup ADC_HAL_EC_OFFSET_NB ADC instance - Offset number + * @{ + */ +#define ADC_OFFSET_NONE (ADC_OFFSET_4 + 1U) /*!< ADC offset disabled: no offset correction for the selected + ADC channel */ +#define ADC_OFFSET_1 (LL_ADC_OFFSET_1) /*!< ADC offset number 1: ADC channel and offset level to which + the offset programmed will be applied (independently of channel mapped + on ADC group regular or group injected) */ +#define ADC_OFFSET_2 (LL_ADC_OFFSET_2) /*!< ADC offset number 2: ADC channel and offset level to which + the offset programmed will be applied (independently of channel mapped + on ADC group regular or group injected) */ +#define ADC_OFFSET_3 (LL_ADC_OFFSET_3) /*!< ADC offset number 3: ADC channel and offset level to which + the offset programmed will be applied (independently of channel mapped + on ADC group regular or group injected) */ +#define ADC_OFFSET_4 (LL_ADC_OFFSET_4) /*!< ADC offset number 4: ADC channel and offset level to which + the offset programmed will be applied (independently of channel mapped + on ADC group regular or group injected) */ +/** + * @} + */ + +/** @defgroup ADCEx_OffsetSign ADC Extended Offset Sign + * @{ + */ +#define ADC_OFFSET_SIGN_NEGATIVE (0x00000000UL) /*!< Offset sign negative, offset is subtracted */ +#define ADC_OFFSET_SIGN_POSITIVE (ADC_OFR1_OFFSETPOS) /*!< Offset sign positive, offset is added */ +/** + * @} + */ + +/** @defgroup ADC_INJ_SEQ_RANKS ADC group injected - Sequencer ranks + * @{ + */ +#define ADC_INJECTED_RANK_1 (LL_ADC_INJ_RANK_1) /*!< ADC group injected sequencer rank 1 */ +#define ADC_INJECTED_RANK_2 (LL_ADC_INJ_RANK_2) /*!< ADC group injected sequencer rank 2 */ +#define ADC_INJECTED_RANK_3 (LL_ADC_INJ_RANK_3) /*!< ADC group injected sequencer rank 3 */ +#define ADC_INJECTED_RANK_4 (LL_ADC_INJ_RANK_4) /*!< ADC group injected sequencer rank 4 */ +/** + * @} + */ + +#if defined(ADC_MULTIMODE_SUPPORT) +/** @defgroup ADC_HAL_EC_MULTI_MODE Multimode - Mode + * @{ + */ +#define ADC_MODE_INDEPENDENT (LL_ADC_MULTI_INDEPENDENT) /*!< ADC dual mode disabled + (ADC independent mode) */ +#define ADC_DUALMODE_REGSIMULT (LL_ADC_MULTI_DUAL_REG_SIMULT) /*!< ADC dual mode enabled: group regular + simultaneous */ +#define ADC_DUALMODE_INTERL (LL_ADC_MULTI_DUAL_REG_INTERL) /*!< ADC dual mode enabled: Combined + group regular interleaved */ +#define ADC_DUALMODE_INJECSIMULT (LL_ADC_MULTI_DUAL_INJ_SIMULT) /*!< ADC dual mode enabled: group + injected simultaneous */ +#define ADC_DUALMODE_ALTERTRIG (LL_ADC_MULTI_DUAL_INJ_ALTERN) /*!< ADC dual mode enabled: group + injected alternate trigger. Works only with external triggers (not internal + SW start) */ +#define ADC_DUALMODE_REGSIMULT_INJECSIMULT (LL_ADC_MULTI_DUAL_REG_SIM_INJ_SIM) /*!< ADC dual mode enabled: Combined + group regular simultaneous + group injected simultaneous */ +#define ADC_DUALMODE_REGSIMULT_ALTERTRIG (LL_ADC_MULTI_DUAL_REG_SIM_INJ_ALT) /*!< ADC dual mode enabled: Combined + group regular simultaneous + group injected alternate trigger */ +#define ADC_DUALMODE_REGINTERL_INJECSIMULT (LL_ADC_MULTI_DUAL_REG_INT_INJ_SIM) /*!< ADC dual mode enabled: Combined + group regular interleaved + group injected simultaneous */ + +/** @defgroup ADC_HAL_EC_MULTI_DMA_TRANSFER_RESOLUTION Multimode - DMA transfer mode depending on ADC resolution + * @{ + */ +#define ADC_DMAACCESSMODE_DISABLED (0x00000000UL) /*!< DMA multimode disabled: each ADC uses its own + DMA channel */ +#define ADC_DMAACCESSMODE_12_10_BITS (ADC_CCR_MDMA_1) /*!< DMA multimode enabled (one DMA channel for both ADC, + DMA of ADC master) for 12 and 10 bits resolution */ +#define ADC_DMAACCESSMODE_8_6_BITS (ADC_CCR_MDMA) /*!< DMA multimode enabled (one DMA channel for both ADC, + DMA of ADC master) for 8 and 6 bits resolution */ +/** + * @} + */ + +/** @defgroup ADC_HAL_EC_MULTI_TWOSMP_DELAY Multimode - Delay between two sampling phases + * @{ + */ +#define ADC_TWOSAMPLINGDELAY_1CYCLE (LL_ADC_MULTI_TWOSMP_DELAY_1CYCLE) /*!< ADC multimode delay between two + sampling phases: 1 ADC clock cycle */ +#define ADC_TWOSAMPLINGDELAY_2CYCLES (LL_ADC_MULTI_TWOSMP_DELAY_2CYCLES) /*!< ADC multimode delay between two + sampling phases: 2 ADC clock cycles */ +#define ADC_TWOSAMPLINGDELAY_3CYCLES (LL_ADC_MULTI_TWOSMP_DELAY_3CYCLES) /*!< ADC multimode delay between two + sampling phases: 3 ADC clock cycles */ +#define ADC_TWOSAMPLINGDELAY_4CYCLES (LL_ADC_MULTI_TWOSMP_DELAY_4CYCLES) /*!< ADC multimode delay between two + sampling phases: 4 ADC clock cycles */ +#define ADC_TWOSAMPLINGDELAY_5CYCLES (LL_ADC_MULTI_TWOSMP_DELAY_5CYCLES) /*!< ADC multimode delay between two + sampling phases: 5 ADC clock cycles */ +#define ADC_TWOSAMPLINGDELAY_6CYCLES (LL_ADC_MULTI_TWOSMP_DELAY_6CYCLES) /*!< ADC multimode delay between two + sampling phases: 6 ADC clock cycles */ +#define ADC_TWOSAMPLINGDELAY_7CYCLES (LL_ADC_MULTI_TWOSMP_DELAY_7CYCLES) /*!< ADC multimode delay between two + sampling phases: 7 ADC clock cycles */ +#define ADC_TWOSAMPLINGDELAY_8CYCLES (LL_ADC_MULTI_TWOSMP_DELAY_8CYCLES) /*!< ADC multimode delay between two + sampling phases: 8 ADC clock cycles */ +#define ADC_TWOSAMPLINGDELAY_9CYCLES (LL_ADC_MULTI_TWOSMP_DELAY_9CYCLES) /*!< ADC multimode delay between two + sampling phases: 9 ADC clock cycles */ +#define ADC_TWOSAMPLINGDELAY_10CYCLES (LL_ADC_MULTI_TWOSMP_DELAY_10CYCLES) /*!< ADC multimode delay between two + sampling phases: 10 ADC clock cycles */ +#define ADC_TWOSAMPLINGDELAY_11CYCLES (LL_ADC_MULTI_TWOSMP_DELAY_11CYCLES) /*!< ADC multimode delay between two + sampling phases: 11 ADC clock cycles */ +#define ADC_TWOSAMPLINGDELAY_12CYCLES (LL_ADC_MULTI_TWOSMP_DELAY_12CYCLES) /*!< ADC multimode delay between two + sampling phases: 12 ADC clock cycles */ +/** + * @} + */ + +/** + * @} + */ +#endif /* ADC_MULTIMODE_SUPPORT */ + +/** @defgroup ADC_HAL_EC_GROUPS ADC instance - Groups + * @{ + */ +#define ADC_REGULAR_GROUP (LL_ADC_GROUP_REGULAR) /*!< ADC group regular (available on + all STM32 devices) */ +#define ADC_INJECTED_GROUP (LL_ADC_GROUP_INJECTED) /*!< ADC group injected (not available on + all STM32 devices) */ +#define ADC_REGULAR_INJECTED_GROUP (LL_ADC_GROUP_REGULAR_INJECTED) /*!< ADC both groups regular and injected */ +/** + * @} + */ + +/** @defgroup ADC_CFGR_fields ADCx CFGR fields + * @{ + */ +#define ADC_CFGR_FIELDS (ADC_CFGR_AWD1CH | ADC_CFGR_JAUTO | ADC_CFGR_JAWD1EN |\ + ADC_CFGR_AWD1EN | ADC_CFGR_AWD1SGL | ADC_CFGR_JQM |\ + ADC_CFGR_JDISCEN | ADC_CFGR_DISCNUM | ADC_CFGR_DISCEN |\ + ADC_CFGR_AUTDLY | ADC_CFGR_CONT | ADC_CFGR_OVRMOD |\ + ADC_CFGR_EXTEN | ADC_CFGR_EXTSEL | ADC_CFGR_ALIGN |\ + ADC_CFGR_RES | ADC_CFGR_DMACFG | ADC_CFGR_DMAEN ) +/** + * @} + */ + +/** @defgroup ADC_SMPR1_fields ADCx SMPR1 fields + * @{ + */ +#define ADC_SMPR1_FIELDS (ADC_SMPR1_SMP9 | ADC_SMPR1_SMP8 | ADC_SMPR1_SMP7 |\ + ADC_SMPR1_SMP6 | ADC_SMPR1_SMP5 | ADC_SMPR1_SMP4 |\ + ADC_SMPR1_SMP3 | ADC_SMPR1_SMP2 | ADC_SMPR1_SMP1 |\ + ADC_SMPR1_SMP0) +/** + * @} + */ + +/** @defgroup ADC_CFGR_fields_2 ADCx CFGR sub fields + * @{ + */ +/* ADC_CFGR fields of parameters that can be updated when no conversion + (neither regular nor injected) is on-going */ +#define ADC_CFGR_FIELDS_2 ((ADC_CFGR_DMACFG | ADC_CFGR_AUTDLY)) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ + +#if defined(ADC_MULTIMODE_SUPPORT) +/** @defgroup ADCEx_Exported_Macro ADC Extended Exported Macros + * @{ + */ + +/** @brief Force ADC instance in multimode mode independent (multimode disable). + * @note This macro must be used only in case of transition from multimode + * to mode independent and in case of unknown previous state, + * to ensure ADC configuration is in mode independent. + * @note Standard way of multimode configuration change is done from + * HAL ADC handle of ADC master using function + * "HAL_ADCEx_MultiModeConfigChannel(..., ADC_MODE_INDEPENDENT)" )". + * Usage of this macro is not the Standard way of multimode + * configuration and can lead to have HAL ADC handles status + * misaligned. Usage of this macro must be limited to cases + * mentioned above. + * @param __HANDLE__ ADC handle. + * @retval None + */ +#define ADC_FORCE_MODE_INDEPENDENT(__HANDLE__) \ + LL_ADC_SetMultimode(__LL_ADC_COMMON_INSTANCE((__HANDLE__)->Instance), LL_ADC_MULTI_INDEPENDENT) + +/** + * @} + */ +#endif /* ADC_MULTIMODE_SUPPORT */ + +/* Private macros ------------------------------------------------------------*/ + +/** @defgroup ADCEx_Private_Macro_internal_HAL_driver ADC Extended Private Macros + * @{ + */ +/* Macro reserved for internal HAL driver usage, not intended to be used in */ +/* code of final user. */ + +/** + * @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->JSQR & ADC_JSQR_JEXTEN) == 0UL) + +/** + * @brief Check whether or not ADC is independent. + * @param __HANDLE__ ADC handle. + * @note When multimode feature is not available, the macro always returns SET. + * @retval SET (ADC is independent) or RESET (ADC is not). + */ +#define ADC_IS_INDEPENDENT(__HANDLE__) (RESET) + +/** + * @brief Set the selected injected Channel rank. + * @param __CHANNELNB__ Channel number. + * @param __RANKNB__ Rank number. + * @retval None + */ +#define ADC_JSQR_RK(__CHANNELNB__, __RANKNB__) \ + ((((__CHANNELNB__) & ADC_CHANNEL_ID_NUMBER_MASK) >> ADC_CHANNEL_ID_NUMBER_BITOFFSET_POS) \ + << ((__RANKNB__) & ADC_INJ_RANK_ID_JSQR_MASK)) + +/** + * @brief Configure ADC injected context queue + * @param __INJECT_CONTEXT_QUEUE_MODE__ Injected context queue mode. + * @retval None + */ +#define ADC_CFGR_INJECT_CONTEXT_QUEUE(__INJECT_CONTEXT_QUEUE_MODE__) \ + ((__INJECT_CONTEXT_QUEUE_MODE__) << ADC_CFGR_JQM_Pos) + +/** + * @brief Configure ADC discontinuous conversion mode for injected group + * @param __INJECT_DISCONTINUOUS_MODE__ Injected discontinuous mode. + * @retval None + */ +#define ADC_CFGR_INJECT_DISCCONTINUOUS(__INJECT_DISCONTINUOUS_MODE__) \ + ((__INJECT_DISCONTINUOUS_MODE__) << ADC_CFGR_JDISCEN_Pos) + +/** + * @brief Configure ADC discontinuous conversion mode for regular group + * @param __REG_DISCONTINUOUS_MODE__ Regular discontinuous mode. + * @retval None + */ +#define ADC_CFGR_REG_DISCONTINUOUS(__REG_DISCONTINUOUS_MODE__) \ + ((__REG_DISCONTINUOUS_MODE__) << ADC_CFGR_DISCEN_Pos) + +/** + * @brief Configure the number of discontinuous conversions for regular group. + * @param __NBR_DISCONTINUOUS_CONV__ Number of discontinuous conversions. + * @retval None + */ +#define ADC_CFGR_DISCONTINUOUS_NUM(__NBR_DISCONTINUOUS_CONV__) \ + (((__NBR_DISCONTINUOUS_CONV__) - 1UL) << ADC_CFGR_DISCNUM_Pos) + +/** + * @brief Configure the ADC auto delay mode. + * @param __AUTOWAIT__ Auto delay bit enable or disable. + * @retval None + */ +#define ADC_CFGR_AUTOWAIT(__AUTOWAIT__) ((__AUTOWAIT__) << ADC_CFGR_AUTDLY_Pos) + +/** + * @brief Configure ADC continuous conversion mode. + * @param __CONTINUOUS_MODE__ Continuous mode. + * @retval None + */ +#define ADC_CFGR_CONTINUOUS(__CONTINUOUS_MODE__) ((__CONTINUOUS_MODE__) << ADC_CFGR_CONT_Pos) + +/** + * @brief Configure the ADC DMA continuous request. + * @param __DMACONTREQ_MODE__ DMA continuous request mode. + * @retval None + */ +#define ADC_CFGR_DMACONTREQ(__DMACONTREQ_MODE__) ((__DMACONTREQ_MODE__) << ADC_CFGR_DMACFG_Pos) + +#if defined(ADC_MULTIMODE_SUPPORT) +/** + * @brief Configure the ADC DMA continuous request for ADC multimode. + * @param __DMACONTREQ_MODE__ DMA continuous request mode. + * @retval None + */ +#define ADC_CCR_MULTI_DMACONTREQ(__DMACONTREQ_MODE__) ((__DMACONTREQ_MODE__) << ADC_CCR_DMACFG_Pos) +#endif /* ADC_MULTIMODE_SUPPORT */ + +/** + * @brief Shift the offset with respect to the selected ADC resolution. + * @note Offset has to be left-aligned on bit 11, the LSB (right bits) are set to 0. + * If resolution 12 bits, no shift. + * If resolution 10 bits, shift of 2 ranks on the left. + * If resolution 8 bits, shift of 4 ranks on the left. + * If resolution 6 bits, shift of 6 ranks on the left. + * Therefore, shift = (12 - resolution) = 12 - (12- (((RES[1:0]) >> 3)*2)). + * @param __HANDLE__ ADC handle + * @param __OFFSET__ Value to be shifted + * @retval None + */ +#define ADC_OFFSET_SHIFT_RESOLUTION(__HANDLE__, __OFFSET__) \ + ((__OFFSET__) << ((((__HANDLE__)->Instance->CFGR & ADC_CFGR_RES) >> 3UL) * 2UL)) + +/** + * @brief Shift the AWD1 threshold with respect to the selected ADC resolution. + * @note Thresholds have to be left-aligned on bit 11, the LSB (right bits) are set to 0. + * If resolution 12 bits, no shift. + * If resolution 10 bits, shift of 2 ranks on the left. + * If resolution 8 bits, shift of 4 ranks on the left. + * If resolution 6 bits, shift of 6 ranks on the left. + * Therefore, shift = (12 - resolution) = 12 - (12- (((RES[1:0]) >> 3)*2)). + * @param __HANDLE__ ADC handle + * @param __THRESHOLD__ Value to be shifted + * @retval None + */ +#define ADC_AWD1THRESHOLD_SHIFT_RESOLUTION(__HANDLE__, __THRESHOLD__) \ + ((__THRESHOLD__) << ((((__HANDLE__)->Instance->CFGR & ADC_CFGR_RES) >> 3UL) * 2UL)) + +/** + * @brief Shift the AWD2 and AWD3 threshold with respect to the selected ADC resolution. + * @note Thresholds have to be left-aligned on bit 7. + * If resolution 12 bits, shift of 4 ranks on the right (the 4 LSB are discarded). + * If resolution 10 bits, shift of 2 ranks on the right (the 2 LSB are discarded). + * If resolution 8 bits, no shift. + * If resolution 6 bits, shift of 2 ranks on the left (the 2 LSB are set to 0). + * @param __HANDLE__ ADC handle + * @param __THRESHOLD__ Value to be shifted + * @retval None + */ +#define ADC_AWD23THRESHOLD_SHIFT_RESOLUTION(__HANDLE__, __THRESHOLD__) \ + ((((__HANDLE__)->Instance->CFGR & ADC_CFGR_RES) != (ADC_CFGR_RES_1 | ADC_CFGR_RES_0)) ? \ + ((__THRESHOLD__) >> ((4UL - ((((__HANDLE__)->Instance->CFGR & ADC_CFGR_RES) >> 3UL) * 2UL)) & 0x1FUL)) : \ + ((__THRESHOLD__) << 2UL) \ + ) + +/** + * @brief Clear Common Control Register. + * @param __HANDLE__ ADC handle. + * @retval None + */ +#if defined(ADC_MULTIMODE_SUPPORT) +#define ADC_CLEAR_COMMON_CONTROL_REGISTER(__HANDLE__) CLEAR_BIT(__LL_ADC_COMMON_INSTANCE((__HANDLE__)->Instance)->CCR, \ + ADC_CCR_CKMODE | \ + ADC_CCR_PRESC | \ + ADC_CCR_VBATEN | \ + ADC_CCR_TSEN | \ + ADC_CCR_VREFEN | \ + ADC_CCR_MDMA | \ + ADC_CCR_DMACFG | \ + ADC_CCR_DELAY | \ + ADC_CCR_DUAL) +#else +#define ADC_CLEAR_COMMON_CONTROL_REGISTER(__HANDLE__) CLEAR_BIT(__LL_ADC_COMMON_INSTANCE((__HANDLE__)->Instance)->CCR, \ + ADC_CCR_CKMODE | \ + ADC_CCR_PRESC | \ + ADC_CCR_VBATEN | \ + ADC_CCR_TSEN | \ + ADC_CCR_VREFEN) + +#endif /* ADC_MULTIMODE_SUPPORT */ + +/** + * @brief Set handle instance of the ADC slave associated to the ADC master. + * @param __HANDLE_MASTER__ ADC master handle. + * @param __HANDLE_SLAVE__ ADC slave handle. + * @note if __HANDLE_MASTER__ is the handle of a slave ADC (ADC2) or an independent ADC, __HANDLE_SLAVE__ instance is + * set to NULL. + * @retval None + */ +#define ADC_MULTI_SLAVE(__HANDLE_MASTER__, __HANDLE_SLAVE__) \ + ( (((__HANDLE_MASTER__)->Instance == ADC1)) ? \ + ((__HANDLE_SLAVE__)->Instance = ADC2) : ((__HANDLE_SLAVE__)->Instance = NULL) ) + + +/** + * @brief Verify the ADC instance connected to the temperature sensor. + * @param __HANDLE__ ADC handle. + * @retval SET (ADC instance is valid) or RESET (ADC instance is invalid) + */ +#define ADC_TEMPERATURE_SENSOR_INSTANCE(__HANDLE__) (((__HANDLE__)->Instance) == ADC1) + +/** + * @brief Verify the ADC instance connected to the battery voltage VBAT. + * @param __HANDLE__ ADC handle. + * @retval SET (ADC instance is valid) or RESET (ADC instance is invalid) + */ +#if defined(ADC2) +#define ADC_BATTERY_VOLTAGE_INSTANCE(__HANDLE__) (((__HANDLE__)->Instance) == ADC2) +#else +#define ADC_BATTERY_VOLTAGE_INSTANCE(__HANDLE__) (((__HANDLE__)->Instance) == ADC1) +#endif /* ADC2 */ + +/** + * @brief Verify the ADC instance connected to the internal voltage reference VREFINT. + * @param __HANDLE__ ADC handle. + * @retval SET (ADC instance is valid) or RESET (ADC instance is invalid) + */ +#define ADC_VREFINT_INSTANCE(__HANDLE__) (((__HANDLE__)->Instance) == ADC1) + +/** + * @brief Verify the ADC instance connected to the internal voltage reference VDDCORE. + * @param __HANDLE__ ADC handle. + * @retval SET (ADC instance is valid) or RESET (ADC instance is invalid) + */ +/* The internal voltage reference VDDCORE measurement path (channel 0) is available on ADC2 */ +#define ADC_VDDCORE_INSTANCE(__HANDLE__) (((__HANDLE__)->Instance) != ADC1) + +/** + * @brief Verify the length of scheduled injected conversions group. + * @param __LENGTH__ number of programmed conversions. + * @retval SET (__LENGTH__ is within the maximum number of possible programmable injected conversions) + * or RESET (__LENGTH__ is null or too large) + */ +#define IS_ADC_INJECTED_NB_CONV(__LENGTH__) (((__LENGTH__) >= (1U)) && ((__LENGTH__) <= (4U))) + +/** + * @brief Calibration factor size verification (7 bits maximum). + * @param __CALIBRATION_FACTOR__ Calibration factor value. + * @retval SET (__CALIBRATION_FACTOR__ is within the authorized size) or RESET (__CALIBRATION_FACTOR__ is too large) + */ +#define IS_ADC_CALFACT(__CALIBRATION_FACTOR__) ((__CALIBRATION_FACTOR__) <= (0x7FU)) + + +/** + * @brief Verify the ADC channel setting. + * @param __HANDLE__ ADC handle. + * @param __CHANNEL__ programmed ADC channel. + * @retval SET (__CHANNEL__ is valid) or RESET (__CHANNEL__ is invalid) + */ +#define IS_ADC_CHANNEL(__HANDLE__, __CHANNEL__) (((__CHANNEL__) == ADC_CHANNEL_0) || \ + ((__CHANNEL__) == ADC_CHANNEL_1) || \ + ((__CHANNEL__) == ADC_CHANNEL_2) || \ + ((__CHANNEL__) == ADC_CHANNEL_3) || \ + ((__CHANNEL__) == ADC_CHANNEL_4) || \ + ((__CHANNEL__) == ADC_CHANNEL_5) || \ + ((__CHANNEL__) == ADC_CHANNEL_6) || \ + ((__CHANNEL__) == ADC_CHANNEL_7) || \ + ((__CHANNEL__) == ADC_CHANNEL_8) || \ + ((__CHANNEL__) == ADC_CHANNEL_9) || \ + ((__CHANNEL__) == ADC_CHANNEL_10) || \ + ((__CHANNEL__) == ADC_CHANNEL_11) || \ + ((__CHANNEL__) == ADC_CHANNEL_12) || \ + ((__CHANNEL__) == ADC_CHANNEL_13) || \ + ((__CHANNEL__) == ADC_CHANNEL_14) || \ + ((__CHANNEL__) == ADC_CHANNEL_15) || \ + ((__CHANNEL__) == ADC_CHANNEL_16) || \ + ((__CHANNEL__) == ADC_CHANNEL_17) || \ + ((__CHANNEL__) == ADC_CHANNEL_18) || \ + ((__CHANNEL__) == ADC_CHANNEL_19) || \ + ((__CHANNEL__) == ADC_CHANNEL_VREFINT) || \ + ((__CHANNEL__) == ADC_CHANNEL_TEMPSENSOR) || \ + ((__CHANNEL__) == ADC_CHANNEL_VBAT) || \ + ((__CHANNEL__) == ADC_CHANNEL_VDDCORE) ) + +/** + * @brief Verify the ADC channel setting in differential mode. + * @param __HANDLE__ ADC handle. + * @param __CHANNEL__ programmed ADC channel. + * @retval SET (__CHANNEL__ is valid) or RESET (__CHANNEL__ is invalid) + */ +/** + * @brief Verify the ADC channel setting in differential mode for ADCx. + * @param __HANDLE__ ADC instance + * @param __CHANNEL__: programmed ADC channel. + * @retval SET (__CHANNEL__ is valid) or RESET (__CHANNEL__ is invalid) + */ +#define IS_ADC_DIFF_CHANNEL(__HANDLE__, __CHANNEL__) \ + ( ( ((__HANDLE__)->Instance == ADC1) \ + )? \ + (((__CHANNEL__) == ADC_CHANNEL_1) || \ + ((__CHANNEL__) == ADC_CHANNEL_2) || \ + ((__CHANNEL__) == ADC_CHANNEL_3) || \ + ((__CHANNEL__) == ADC_CHANNEL_4) || \ + ((__CHANNEL__) == ADC_CHANNEL_5) || \ + ((__CHANNEL__) == ADC_CHANNEL_10) || \ + ((__CHANNEL__) == ADC_CHANNEL_11) || \ + ((__CHANNEL__) == ADC_CHANNEL_12) || \ + ((__CHANNEL__) == ADC_CHANNEL_18) ) \ + : \ + (((__CHANNEL__) == ADC_CHANNEL_1) || \ + ((__CHANNEL__) == ADC_CHANNEL_2) || \ + ((__CHANNEL__) == ADC_CHANNEL_3) || \ + ((__CHANNEL__) == ADC_CHANNEL_4) || \ + ((__CHANNEL__) == ADC_CHANNEL_5) || \ + ((__CHANNEL__) == ADC_CHANNEL_10) || \ + ((__CHANNEL__) == ADC_CHANNEL_11) || \ + ((__CHANNEL__) == ADC_CHANNEL_12) || \ + ((__CHANNEL__) == ADC_CHANNEL_18) ) \ + ) + +/** + * @brief Verify the ADC single-ended input or differential mode setting. + * @param __SING_DIFF__ programmed channel setting. + * @retval SET (__SING_DIFF__ is valid) or RESET (__SING_DIFF__ is invalid) + */ +#define IS_ADC_SINGLE_DIFFERENTIAL(__SING_DIFF__) (((__SING_DIFF__) == ADC_SINGLE_ENDED) || \ + ((__SING_DIFF__) == ADC_DIFFERENTIAL_ENDED) ) + +/** + * @brief Verify the ADC offset management setting. + * @param __OFFSET_NUMBER__ ADC offset management. + * @retval SET (__OFFSET_NUMBER__ is valid) or RESET (__OFFSET_NUMBER__ is invalid) + */ +#define IS_ADC_OFFSET_NUMBER(__OFFSET_NUMBER__) (((__OFFSET_NUMBER__) == ADC_OFFSET_NONE) || \ + ((__OFFSET_NUMBER__) == ADC_OFFSET_1) || \ + ((__OFFSET_NUMBER__) == ADC_OFFSET_2) || \ + ((__OFFSET_NUMBER__) == ADC_OFFSET_3) || \ + ((__OFFSET_NUMBER__) == ADC_OFFSET_4) ) + +/** + * @brief Verify the ADC offset sign setting. + * @param __OFFSET_SIGN__ ADC offset sign. + * @retval SET (__OFFSET_SIGN__ is valid) or RESET (__OFFSET_SIGN__ is invalid) + */ +#define IS_ADC_OFFSET_SIGN(__OFFSET_SIGN__) (((__OFFSET_SIGN__) == ADC_OFFSET_SIGN_NEGATIVE) || \ + ((__OFFSET_SIGN__) == ADC_OFFSET_SIGN_POSITIVE) ) + +/** + * @brief Verify the ADC injected channel setting. + * @param __CHANNEL__ programmed ADC injected channel. + * @retval SET (__CHANNEL__ is valid) or RESET (__CHANNEL__ is invalid) + */ +#define IS_ADC_INJECTED_RANK(__CHANNEL__) (((__CHANNEL__) == ADC_INJECTED_RANK_1) || \ + ((__CHANNEL__) == ADC_INJECTED_RANK_2) || \ + ((__CHANNEL__) == ADC_INJECTED_RANK_3) || \ + ((__CHANNEL__) == ADC_INJECTED_RANK_4) ) + +/** + * @brief Verify the ADC injected conversions external trigger. + * @param __INJTRIG__ programmed ADC injected conversions external trigger. + * @retval SET (__INJTRIG__ is a valid value) or RESET (__INJTRIG__ is invalid) + */ +#if defined(TIM8) +/* Devices STM32H563/H573xx */ +#define IS_ADC_EXTTRIGINJEC(__INJTRIG__) (((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_T1_TRGO) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_T1_CC4) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_T2_TRGO) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_T2_CC1) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_T3_CC4) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_T4_TRGO) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_EXT_IT15) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_T8_CC4) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_T1_TRGO2) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_T8_TRGO) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_T8_TRGO2) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_T3_CC3) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_T3_TRGO) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_T3_CC1) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_T6_TRGO) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_T15_TRGO) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_LPTIM1_CH1) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_LPTIM2_CH1) || \ + ((__INJTRIG__) == ADC_INJECTED_SOFTWARE_START) ) +#else +/* Devices STM32H503xx */ +#define IS_ADC_EXTTRIGINJEC(__INJTRIG__) (((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_T1_TRGO) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_T1_CC4) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_T2_TRGO) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_T2_CC1) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_T3_CC4) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_EXT_IT15) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_T1_TRGO2) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_T3_CC3) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_T3_TRGO) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_T3_CC1) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_T6_TRGO) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_T7_TRGO) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_LPTIM1_CH1) || \ + ((__INJTRIG__) == ADC_EXTERNALTRIGINJEC_LPTIM2_CH1) || \ + ((__INJTRIG__) == ADC_INJECTED_SOFTWARE_START) ) +#endif /* Devices STM32H563/H573xx or STM32H503xx */ + +/** + * @brief Verify the ADC edge trigger setting for injected group. + * @param __EDGE__ programmed ADC edge trigger setting. + * @retval SET (__EDGE__ is a valid value) or RESET (__EDGE__ is invalid) + */ +#define IS_ADC_EXTTRIGINJEC_EDGE(__EDGE__) (((__EDGE__) == ADC_EXTERNALTRIGINJECCONV_EDGE_NONE) || \ + ((__EDGE__) == ADC_EXTERNALTRIGINJECCONV_EDGE_RISING) || \ + ((__EDGE__) == ADC_EXTERNALTRIGINJECCONV_EDGE_FALLING) || \ + ((__EDGE__) == ADC_EXTERNALTRIGINJECCONV_EDGE_RISINGFALLING) ) + +#if defined(ADC_MULTIMODE_SUPPORT) +/** + * @brief Verify the ADC multimode setting. + * @param __MODE__ programmed ADC multimode setting. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_ADC_MULTIMODE(__MODE__) (((__MODE__) == ADC_MODE_INDEPENDENT) || \ + ((__MODE__) == ADC_DUALMODE_REGSIMULT_INJECSIMULT) || \ + ((__MODE__) == ADC_DUALMODE_REGSIMULT_ALTERTRIG) || \ + ((__MODE__) == ADC_DUALMODE_REGINTERL_INJECSIMULT) || \ + ((__MODE__) == ADC_DUALMODE_INJECSIMULT) || \ + ((__MODE__) == ADC_DUALMODE_REGSIMULT) || \ + ((__MODE__) == ADC_DUALMODE_INTERL) || \ + ((__MODE__) == ADC_DUALMODE_ALTERTRIG) ) + +/** + * @brief Verify the ADC multimode DMA access setting. + * @param __MODE__ programmed ADC multimode DMA access setting. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_ADC_DMA_ACCESS_MULTIMODE(__MODE__) (((__MODE__) == ADC_DMAACCESSMODE_DISABLED) || \ + ((__MODE__) == ADC_DMAACCESSMODE_12_10_BITS) || \ + ((__MODE__) == ADC_DMAACCESSMODE_8_6_BITS) ) + +/** + * @brief Verify the ADC multimode delay setting. + * @param __DELAY__ programmed ADC multimode delay setting. + * @retval SET (__DELAY__ is a valid value) or RESET (__DELAY__ is invalid) + */ +#define IS_ADC_SAMPLING_DELAY(__DELAY__) (((__DELAY__) == ADC_TWOSAMPLINGDELAY_1CYCLE) || \ + ((__DELAY__) == ADC_TWOSAMPLINGDELAY_2CYCLES) || \ + ((__DELAY__) == ADC_TWOSAMPLINGDELAY_3CYCLES) || \ + ((__DELAY__) == ADC_TWOSAMPLINGDELAY_4CYCLES) || \ + ((__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) ) +#endif /* ADC_MULTIMODE_SUPPORT */ + +/** + * @brief Verify the ADC analog watchdog setting. + * @param __WATCHDOG__ programmed ADC analog watchdog setting. + * @retval SET (__WATCHDOG__ is valid) or RESET (__WATCHDOG__ is invalid) + */ +#define IS_ADC_ANALOG_WATCHDOG_NUMBER(__WATCHDOG__) (((__WATCHDOG__) == ADC_ANALOGWATCHDOG_1) || \ + ((__WATCHDOG__) == ADC_ANALOGWATCHDOG_2) || \ + ((__WATCHDOG__) == ADC_ANALOGWATCHDOG_3) ) + +/** + * @brief Verify the ADC analog watchdog mode setting. + * @param __WATCHDOG_MODE__ programmed ADC analog watchdog mode setting. + * @retval SET (__WATCHDOG_MODE__ is valid) or RESET (__WATCHDOG_MODE__ is invalid) + */ +#define IS_ADC_ANALOG_WATCHDOG_MODE(__WATCHDOG_MODE__) (((__WATCHDOG_MODE__) == ADC_ANALOGWATCHDOG_NONE) || \ + ((__WATCHDOG_MODE__) == ADC_ANALOGWATCHDOG_SINGLE_REG) || \ + ((__WATCHDOG_MODE__) == ADC_ANALOGWATCHDOG_SINGLE_INJEC) || \ + ((__WATCHDOG_MODE__) == ADC_ANALOGWATCHDOG_SINGLE_REGINJEC) || \ + ((__WATCHDOG_MODE__) == ADC_ANALOGWATCHDOG_ALL_REG) || \ + ((__WATCHDOG_MODE__) == ADC_ANALOGWATCHDOG_ALL_INJEC) || \ + ((__WATCHDOG_MODE__) == ADC_ANALOGWATCHDOG_ALL_REGINJEC) ) + +/** + * @brief Verify the ADC analog watchdog filtering setting. + * @param __FILTERING_MODE__ programmed ADC analog watchdog mode setting. + * @retval SET (__FILTERING_MODE__ is valid) or RESET (__FILTERING_MODE__ is invalid) + */ +#define IS_ADC_ANALOG_WATCHDOG_FILTERING_MODE(__FILTERING_MODE__) \ + (((__FILTERING_MODE__) == ADC_AWD_FILTERING_NONE) || \ + ((__FILTERING_MODE__) == ADC_AWD_FILTERING_2SAMPLES) || \ + ((__FILTERING_MODE__) == ADC_AWD_FILTERING_3SAMPLES) || \ + ((__FILTERING_MODE__) == ADC_AWD_FILTERING_4SAMPLES) || \ + ((__FILTERING_MODE__) == ADC_AWD_FILTERING_5SAMPLES) || \ + ((__FILTERING_MODE__) == ADC_AWD_FILTERING_6SAMPLES) || \ + ((__FILTERING_MODE__) == ADC_AWD_FILTERING_7SAMPLES) || \ + ((__FILTERING_MODE__) == ADC_AWD_FILTERING_8SAMPLES) ) + + +/** + * @brief Verify the ADC conversion (regular or injected or both). + * @param __CONVERSION__ ADC conversion group. + * @retval SET (__CONVERSION__ is valid) or RESET (__CONVERSION__ is invalid) + */ +#define IS_ADC_CONVERSION_GROUP(__CONVERSION__) (((__CONVERSION__) == ADC_REGULAR_GROUP) || \ + ((__CONVERSION__) == ADC_INJECTED_GROUP) || \ + ((__CONVERSION__) == ADC_REGULAR_INJECTED_GROUP) ) + +/** + * @brief Verify the ADC event type. + * @param __EVENT__ ADC event. + * @retval SET (__EVENT__ is valid) or RESET (__EVENT__ is invalid) + */ +#define IS_ADC_EVENT_TYPE(__EVENT__) (((__EVENT__) == ADC_EOSMP_EVENT) || \ + ((__EVENT__) == ADC_AWD_EVENT) || \ + ((__EVENT__) == ADC_AWD2_EVENT) || \ + ((__EVENT__) == ADC_AWD3_EVENT) || \ + ((__EVENT__) == ADC_OVR_EVENT) || \ + ((__EVENT__) == ADC_JQOVF_EVENT) ) + +/** + * @brief Verify the ADC oversampling ratio. + * @param __RATIO__ programmed ADC oversampling ratio. + * @retval SET (__RATIO__ is a valid value) or RESET (__RATIO__ is invalid) + */ +#define IS_ADC_OVERSAMPLING_RATIO(__RATIO__) (((__RATIO__) == ADC_OVERSAMPLING_RATIO_2 ) || \ + ((__RATIO__) == ADC_OVERSAMPLING_RATIO_4 ) || \ + ((__RATIO__) == ADC_OVERSAMPLING_RATIO_8 ) || \ + ((__RATIO__) == ADC_OVERSAMPLING_RATIO_16 ) || \ + ((__RATIO__) == ADC_OVERSAMPLING_RATIO_32 ) || \ + ((__RATIO__) == ADC_OVERSAMPLING_RATIO_64 ) || \ + ((__RATIO__) == ADC_OVERSAMPLING_RATIO_128 ) || \ + ((__RATIO__) == ADC_OVERSAMPLING_RATIO_256 )) + +/** + * @brief Verify the ADC oversampling shift. + * @param __SHIFT__ programmed ADC oversampling shift. + * @retval SET (__SHIFT__ is a valid value) or RESET (__SHIFT__ is invalid) + */ +#define IS_ADC_RIGHT_BIT_SHIFT(__SHIFT__) (((__SHIFT__) == ADC_RIGHTBITSHIFT_NONE) || \ + ((__SHIFT__) == ADC_RIGHTBITSHIFT_1 ) || \ + ((__SHIFT__) == ADC_RIGHTBITSHIFT_2 ) || \ + ((__SHIFT__) == ADC_RIGHTBITSHIFT_3 ) || \ + ((__SHIFT__) == ADC_RIGHTBITSHIFT_4 ) || \ + ((__SHIFT__) == ADC_RIGHTBITSHIFT_5 ) || \ + ((__SHIFT__) == ADC_RIGHTBITSHIFT_6 ) || \ + ((__SHIFT__) == ADC_RIGHTBITSHIFT_7 ) || \ + ((__SHIFT__) == ADC_RIGHTBITSHIFT_8 )) + +/** + * @brief Verify the ADC oversampling triggered mode. + * @param __MODE__ programmed ADC oversampling triggered mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_ADC_TRIGGERED_OVERSAMPLING_MODE(__MODE__) (((__MODE__) == ADC_TRIGGEREDMODE_SINGLE_TRIGGER) || \ + ((__MODE__) == ADC_TRIGGEREDMODE_MULTI_TRIGGER) ) + +/** + * @brief Verify the ADC oversampling regular conversion resumed or continued mode. + * @param __MODE__ programmed ADC oversampling regular conversion resumed or continued mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_ADC_REGOVERSAMPLING_MODE(__MODE__) (((__MODE__) == ADC_REGOVERSAMPLING_CONTINUED_MODE) || \ + ((__MODE__) == ADC_REGOVERSAMPLING_RESUMED_MODE) ) + +/** + * @brief Verify the DFSDM mode configuration. + * @param __HANDLE__ ADC handle. + * @note When DMSDFM configuration is not supported, the macro systematically reports SET. For + * this reason, the input parameter is the ADC handle and not the configuration parameter + * directly. + * @retval SET (DFSDM mode configuration is valid) or RESET (DFSDM mode configuration is invalid) + */ +#define IS_ADC_DFSDMCFG_MODE(__HANDLE__) (SET) + +/** + * @brief Return the DFSDM configuration mode. + * @param __HANDLE__ ADC handle. + * @note When DMSDFM configuration is not supported, the macro systematically reports 0x0 (i.e disabled). + * For this reason, the input parameter is the ADC handle and not the configuration parameter + * directly. + * @retval DFSDM configuration mode + */ +#define ADC_CFGR_DFSDM(__HANDLE__) (0x0UL) + +/** + * @} + */ + + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup ADCEx_Exported_Functions + * @{ + */ + +/** @addtogroup ADCEx_Exported_Functions_Group1 + * @{ + */ +/* IO operation functions *****************************************************/ + +/* ADC calibration */ +HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef *hadc, uint32_t SingleDiff); +uint32_t HAL_ADCEx_Calibration_GetValue(const ADC_HandleTypeDef *hadc, uint32_t SingleDiff); +HAL_StatusTypeDef HAL_ADCEx_Calibration_SetValue(ADC_HandleTypeDef *hadc, uint32_t SingleDiff, + uint32_t CalibrationFactor); + +/* Blocking mode: Polling */ +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); + +/* Non-blocking mode: Interruption */ +HAL_StatusTypeDef HAL_ADCEx_InjectedStart_IT(ADC_HandleTypeDef *hadc); +HAL_StatusTypeDef HAL_ADCEx_InjectedStop_IT(ADC_HandleTypeDef *hadc); + +#if defined(ADC_MULTIMODE_SUPPORT) +/* ADC multimode */ +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(const ADC_HandleTypeDef *hadc); +#endif /* ADC_MULTIMODE_SUPPORT */ + +/* ADC retrieve conversion value intended to be used with polling or interruption */ +uint32_t HAL_ADCEx_InjectedGetValue(const ADC_HandleTypeDef *hadc, uint32_t InjectedRank); + +/* ADC IRQHandler and Callbacks used in non-blocking modes (Interruption) */ +void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc); +void HAL_ADCEx_InjectedQueueOverflowCallback(ADC_HandleTypeDef *hadc); +void HAL_ADCEx_LevelOutOfWindow2Callback(ADC_HandleTypeDef *hadc); +void HAL_ADCEx_LevelOutOfWindow3Callback(ADC_HandleTypeDef *hadc); +void HAL_ADCEx_EndOfSamplingCallback(ADC_HandleTypeDef *hadc); + +/* ADC group regular conversions stop */ +HAL_StatusTypeDef HAL_ADCEx_RegularStop(ADC_HandleTypeDef *hadc); +HAL_StatusTypeDef HAL_ADCEx_RegularStop_IT(ADC_HandleTypeDef *hadc); +HAL_StatusTypeDef HAL_ADCEx_RegularStop_DMA(ADC_HandleTypeDef *hadc); +#if defined(ADC_MULTIMODE_SUPPORT) +HAL_StatusTypeDef HAL_ADCEx_RegularMultiModeStop_DMA(ADC_HandleTypeDef *hadc); +#endif /* ADC_MULTIMODE_SUPPORT */ + +/** + * @} + */ + +/** @addtogroup ADCEx_Exported_Functions_Group2 + * @{ + */ +/* Peripheral Control functions ***********************************************/ +HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef *hadc, + const ADC_InjectionConfTypeDef *pConfigInjected); +#if defined(ADC_MULTIMODE_SUPPORT) +HAL_StatusTypeDef HAL_ADCEx_MultiModeConfigChannel(ADC_HandleTypeDef *hadc, + const ADC_MultiModeTypeDef *pMultimode); +#endif /* ADC_MULTIMODE_SUPPORT */ + +HAL_StatusTypeDef HAL_ADCEx_EnableInjectedQueue(ADC_HandleTypeDef *hadc); +HAL_StatusTypeDef HAL_ADCEx_DisableInjectedQueue(ADC_HandleTypeDef *hadc); +HAL_StatusTypeDef HAL_ADCEx_DisableVoltageRegulator(ADC_HandleTypeDef *hadc); +HAL_StatusTypeDef HAL_ADCEx_EnterADCDeepPowerDownMode(ADC_HandleTypeDef *hadc); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_ADC_EX_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_cec.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_cec.h new file mode 100644 index 0000000000..d090231c4d --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_cec.h @@ -0,0 +1,804 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_cec.h + * @author MCD Application Team + * @brief Header file of CEC HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_CEC_H +#define STM32H5xx_HAL_CEC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +#if defined (CEC) + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup CEC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup CEC_Exported_Types CEC Exported Types + * @{ + */ + +/** + * @brief CEC Init Structure definition + */ +typedef struct +{ + uint32_t SignalFreeTime; /*!< Set SFT field, specifies the Signal Free Time. + It can be one of CEC_Signal_Free_Time + and belongs to the set {0,...,7} where + 0x0 is the default configuration + else means 0.5 + (SignalFreeTime - 1) nominal data bit periods */ + + uint32_t Tolerance; /*!< Set RXTOL bit, specifies the tolerance accepted on the received waveforms, + it can be a value of CEC_Tolerance : + it is either CEC_STANDARD_TOLERANCE or CEC_EXTENDED_TOLERANCE */ + + uint32_t BRERxStop; /*!< Set BRESTP bit CEC_BRERxStop : specifies whether or not a Bit Rising + Error stops the reception. + CEC_NO_RX_STOP_ON_BRE: reception is not stopped. + CEC_RX_STOP_ON_BRE: reception is stopped. */ + + uint32_t BREErrorBitGen; /*!< Set BREGEN bit CEC_BREErrorBitGen : specifies whether or not an + Error-Bit is generated on the + CEC line upon Bit Rising Error detection. + CEC_BRE_ERRORBIT_NO_GENERATION: no error-bit generation. + CEC_BRE_ERRORBIT_GENERATION: error-bit generation if BRESTP is set. */ + + uint32_t LBPEErrorBitGen; /*!< Set LBPEGEN bit CEC_LBPEErrorBitGen : specifies whether or not an + Error-Bit is generated on the + CEC line upon Long Bit Period Error detection. + CEC_LBPE_ERRORBIT_NO_GENERATION: no error-bit generation. + CEC_LBPE_ERRORBIT_GENERATION: error-bit generation. */ + + uint32_t BroadcastMsgNoErrorBitGen; /*!< Set BRDNOGEN bit CEC_BroadCastMsgErrorBitGen : allows to avoid an + Error-Bit generation on the CEC line + upon an error detected on a broadcast message. + + It supersedes BREGEN and LBPEGEN bits for a broadcast message error + handling. It can take two values: + + 1) CEC_BROADCASTERROR_ERRORBIT_GENERATION. + a) BRE detection: error-bit generation on the CEC line if + BRESTP=CEC_RX_STOP_ON_BRE and BREGEN=CEC_BRE_ERRORBIT_NO_GENERATION. + b) LBPE detection: error-bit generation on the CEC line + if LBPGEN=CEC_LBPE_ERRORBIT_NO_GENERATION. + + 2) CEC_BROADCASTERROR_NO_ERRORBIT_GENERATION. + no error-bit generation in case neither a) nor b) are satisfied. + Additionally, there is no error-bit generation in case of Short Bit + Period Error detection in a broadcast message while LSTN bit is set. */ + + uint32_t SignalFreeTimeOption; /*!< Set SFTOP bit CEC_SFT_Option : specifies when SFT timer starts. + CEC_SFT_START_ON_TXSOM SFT: timer starts when TXSOM is set by software. + CEC_SFT_START_ON_TX_RX_END: SFT timer starts automatically at the end + of message transmission/reception. */ + + uint32_t ListenMode; /*!< Set LSTN bit CEC_Listening_Mode : specifies device listening mode. + It can take two values: + + CEC_REDUCED_LISTENING_MODE: CEC peripheral receives only message addressed + to its own address (OAR). Messages addressed to different destination + are ignored. + Broadcast messages are always received. + + CEC_FULL_LISTENING_MODE: CEC peripheral receives messages addressed to its + own address (OAR) with positive acknowledge. Messages addressed to + different destination are received, but without interfering with the + CEC bus: no acknowledge sent. */ + + uint16_t OwnAddress; /*!< Own addresses configuration + This parameter can be a value of CEC_OWN_ADDRESS */ + + uint8_t *RxBuffer; /*!< CEC Rx buffer pointer */ + + +} CEC_InitTypeDef; + +/** + * @brief HAL CEC State definition + * @note HAL CEC State value is a combination of 2 different substates: gState and RxState + (see CEC_State_Definition). + * - gState contains CEC state information related to global Handle management + * and also information related to Tx operations. + * gState value coding follow below described bitmap : + * b7 (not used) + * x : Should be set to 0 + * b6 Error information + * 0 : No Error + * 1 : Error + * b5 CEC peripheral initialization status + * 0 : Reset (peripheral not initialized) + * 1 : Init done (peripheral initialized. HAL CEC Init function already called) + * b4-b3 (not used) + * xx : Should be set to 00 + * b2 Intrinsic process state + * 0 : Ready + * 1 : Busy (peripheral busy with some configuration or internal operations) + * b1 (not used) + * x : Should be set to 0 + * b0 Tx state + * 0 : Ready (no Tx operation ongoing) + * 1 : Busy (Tx operation ongoing) + * - RxState contains information related to Rx operations. + * RxState value coding follow below described bitmap : + * b7-b6 (not used) + * xx : Should be set to 00 + * b5 CEC peripheral initialization status + * 0 : Reset (peripheral not initialized) + * 1 : Init done (peripheral initialized) + * b4-b2 (not used) + * xxx : Should be set to 000 + * b1 Rx state + * 0 : Ready (no Rx operation ongoing) + * 1 : Busy (Rx operation ongoing) + * b0 (not used) + * x : Should be set to 0. + */ +typedef uint32_t HAL_CEC_StateTypeDef; + +/** + * @brief CEC handle Structure definition + */ +#if (USE_HAL_CEC_REGISTER_CALLBACKS == 1) +typedef struct __CEC_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_CEC_REGISTER_CALLBACKS */ +{ + CEC_TypeDef *Instance; /*!< CEC registers base address */ + + CEC_InitTypeDef Init; /*!< CEC communication parameters */ + + const uint8_t *pTxBuffPtr; /*!< Pointer to CEC Tx transfer Buffer */ + + uint16_t TxXferCount; /*!< CEC Tx Transfer Counter */ + + uint16_t RxXferSize; /*!< CEC Rx Transfer size, 0: header received only */ + + HAL_LockTypeDef Lock; /*!< Locking object */ + + HAL_CEC_StateTypeDef gState; /*!< CEC state information related to global Handle management + and also related to Tx operations. + This parameter can be a value of HAL_CEC_StateTypeDef */ + + HAL_CEC_StateTypeDef RxState; /*!< CEC state information related to Rx operations. + This parameter can be a value of HAL_CEC_StateTypeDef */ + + uint32_t ErrorCode; /*!< For errors handling purposes, copy of ISR register + in case error is reported */ + +#if (USE_HAL_CEC_REGISTER_CALLBACKS == 1) + void (* TxCpltCallback)(struct __CEC_HandleTypeDef + *hcec); /*!< CEC Tx Transfer completed callback */ + void (* RxCpltCallback)(struct __CEC_HandleTypeDef *hcec, + uint32_t RxFrameSize); /*!< CEC Rx Transfer completed callback */ + void (* ErrorCallback)(struct __CEC_HandleTypeDef *hcec); /*!< CEC error callback */ + + void (* MspInitCallback)(struct __CEC_HandleTypeDef *hcec); /*!< CEC Msp Init callback */ + void (* MspDeInitCallback)(struct __CEC_HandleTypeDef *hcec); /*!< CEC Msp DeInit callback */ + +#endif /* (USE_HAL_CEC_REGISTER_CALLBACKS) */ +} CEC_HandleTypeDef; + +#if (USE_HAL_CEC_REGISTER_CALLBACKS == 1) +/** + * @brief HAL CEC Callback ID enumeration definition + */ +typedef enum +{ + HAL_CEC_TX_CPLT_CB_ID = 0x00U, /*!< CEC Tx Transfer completed callback ID */ + HAL_CEC_RX_CPLT_CB_ID = 0x01U, /*!< CEC Rx Transfer completed callback ID */ + HAL_CEC_ERROR_CB_ID = 0x02U, /*!< CEC error callback ID */ + HAL_CEC_MSPINIT_CB_ID = 0x03U, /*!< CEC Msp Init callback ID */ + HAL_CEC_MSPDEINIT_CB_ID = 0x04U /*!< CEC Msp DeInit callback ID */ +} HAL_CEC_CallbackIDTypeDef; + +/** + * @brief HAL CEC Callback pointer definition + */ +typedef void (*pCEC_CallbackTypeDef)(CEC_HandleTypeDef *hcec); /*!< pointer to an CEC callback function */ +typedef void (*pCEC_RxCallbackTypeDef)(CEC_HandleTypeDef *hcec, + uint32_t RxFrameSize); /*!< pointer to an Rx Transfer completed + callback function */ +#endif /* USE_HAL_CEC_REGISTER_CALLBACKS */ +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup CEC_Exported_Constants CEC Exported Constants + * @{ + */ +/** @defgroup CEC_State_Definition CEC State Code Definition + * @{ + */ +#define HAL_CEC_STATE_RESET ((uint32_t)0x00000000) /*!< Peripheral is not yet Initialized + Value is allowed for gState and RxState */ +#define HAL_CEC_STATE_READY ((uint32_t)0x00000020) /*!< Peripheral Initialized and ready for use + Value is allowed for gState and RxState */ +#define HAL_CEC_STATE_BUSY ((uint32_t)0x00000024) /*!< an internal process is ongoing + Value is allowed for gState only */ +#define HAL_CEC_STATE_BUSY_RX ((uint32_t)0x00000022) /*!< Data Reception process is ongoing + Value is allowed for RxState only */ +#define HAL_CEC_STATE_BUSY_TX ((uint32_t)0x00000021) /*!< Data Transmission process is ongoing + Value is allowed for gState only */ +#define HAL_CEC_STATE_BUSY_RX_TX ((uint32_t)0x00000023) /*!< an internal process is ongoing + Value is allowed for gState only */ +#define HAL_CEC_STATE_ERROR ((uint32_t)0x00000050) /*!< Error Value is allowed for gState only */ +/** + * @} + */ +/** @defgroup CEC_Error_Code CEC Error Code + * @{ + */ +#define HAL_CEC_ERROR_NONE (uint32_t) 0x0000U /*!< no error */ +#define HAL_CEC_ERROR_RXOVR CEC_ISR_RXOVR /*!< CEC Rx-Overrun */ +#define HAL_CEC_ERROR_BRE CEC_ISR_BRE /*!< CEC Rx Bit Rising Error */ +#define HAL_CEC_ERROR_SBPE CEC_ISR_SBPE /*!< CEC Rx Short Bit period Error */ +#define HAL_CEC_ERROR_LBPE CEC_ISR_LBPE /*!< CEC Rx Long Bit period Error */ +#define HAL_CEC_ERROR_RXACKE CEC_ISR_RXACKE /*!< CEC Rx Missing Acknowledge */ +#define HAL_CEC_ERROR_ARBLST CEC_ISR_ARBLST /*!< CEC Arbitration Lost */ +#define HAL_CEC_ERROR_TXUDR CEC_ISR_TXUDR /*!< CEC Tx-Buffer Underrun */ +#define HAL_CEC_ERROR_TXERR CEC_ISR_TXERR /*!< CEC Tx-Error */ +#define HAL_CEC_ERROR_TXACKE CEC_ISR_TXACKE /*!< CEC Tx Missing Acknowledge */ +#if (USE_HAL_CEC_REGISTER_CALLBACKS == 1) +#define HAL_CEC_ERROR_INVALID_CALLBACK ((uint32_t)0x00002000U) /*!< Invalid Callback Error */ +#endif /* USE_HAL_CEC_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @defgroup CEC_Signal_Free_Time CEC Signal Free Time setting parameter + * @{ + */ +#define CEC_DEFAULT_SFT ((uint32_t)0x00000000U) +#define CEC_0_5_BITPERIOD_SFT ((uint32_t)0x00000001U) +#define CEC_1_5_BITPERIOD_SFT ((uint32_t)0x00000002U) +#define CEC_2_5_BITPERIOD_SFT ((uint32_t)0x00000003U) +#define CEC_3_5_BITPERIOD_SFT ((uint32_t)0x00000004U) +#define CEC_4_5_BITPERIOD_SFT ((uint32_t)0x00000005U) +#define CEC_5_5_BITPERIOD_SFT ((uint32_t)0x00000006U) +#define CEC_6_5_BITPERIOD_SFT ((uint32_t)0x00000007U) +/** + * @} + */ + +/** @defgroup CEC_Tolerance CEC Receiver Tolerance + * @{ + */ +#define CEC_STANDARD_TOLERANCE ((uint32_t)0x00000000U) +#define CEC_EXTENDED_TOLERANCE ((uint32_t)CEC_CFGR_RXTOL) +/** + * @} + */ + +/** @defgroup CEC_BRERxStop CEC Reception Stop on Error + * @{ + */ +#define CEC_NO_RX_STOP_ON_BRE ((uint32_t)0x00000000U) +#define CEC_RX_STOP_ON_BRE ((uint32_t)CEC_CFGR_BRESTP) +/** + * @} + */ + +/** @defgroup CEC_BREErrorBitGen CEC Error Bit Generation if Bit Rise Error reported + * @{ + */ +#define CEC_BRE_ERRORBIT_NO_GENERATION ((uint32_t)0x00000000U) +#define CEC_BRE_ERRORBIT_GENERATION ((uint32_t)CEC_CFGR_BREGEN) +/** + * @} + */ + +/** @defgroup CEC_LBPEErrorBitGen CEC Error Bit Generation if Long Bit Period Error reported + * @{ + */ +#define CEC_LBPE_ERRORBIT_NO_GENERATION ((uint32_t)0x00000000U) +#define CEC_LBPE_ERRORBIT_GENERATION ((uint32_t)CEC_CFGR_LBPEGEN) +/** + * @} + */ + +/** @defgroup CEC_BroadCastMsgErrorBitGen CEC Error Bit Generation on Broadcast message + * @{ + */ +#define CEC_BROADCASTERROR_ERRORBIT_GENERATION ((uint32_t)0x00000000U) +#define CEC_BROADCASTERROR_NO_ERRORBIT_GENERATION ((uint32_t)CEC_CFGR_BRDNOGEN) +/** + * @} + */ + +/** @defgroup CEC_SFT_Option CEC Signal Free Time start option + * @{ + */ +#define CEC_SFT_START_ON_TXSOM ((uint32_t)0x00000000U) +#define CEC_SFT_START_ON_TX_RX_END ((uint32_t)CEC_CFGR_SFTOPT) +/** + * @} + */ + +/** @defgroup CEC_Listening_Mode CEC Listening mode option + * @{ + */ +#define CEC_REDUCED_LISTENING_MODE ((uint32_t)0x00000000U) +#define CEC_FULL_LISTENING_MODE ((uint32_t)CEC_CFGR_LSTN) +/** + * @} + */ + +/** @defgroup CEC_OAR_Position CEC Device Own Address position in CEC CFGR register + * @{ + */ +#define CEC_CFGR_OAR_LSB_POS ((uint32_t) 16U) +/** + * @} + */ + +/** @defgroup CEC_Initiator_Position CEC Initiator logical address position in message header + * @{ + */ +#define CEC_INITIATOR_LSB_POS ((uint32_t) 4U) +/** + * @} + */ + +/** @defgroup CEC_OWN_ADDRESS CEC Own Address + * @{ + */ +#define CEC_OWN_ADDRESS_NONE ((uint16_t) 0x0000U) /* Reset value */ +#define CEC_OWN_ADDRESS_0 ((uint16_t) 0x0001U) /* Logical Address 0 */ +#define CEC_OWN_ADDRESS_1 ((uint16_t) 0x0002U) /* Logical Address 1 */ +#define CEC_OWN_ADDRESS_2 ((uint16_t) 0x0004U) /* Logical Address 2 */ +#define CEC_OWN_ADDRESS_3 ((uint16_t) 0x0008U) /* Logical Address 3 */ +#define CEC_OWN_ADDRESS_4 ((uint16_t) 0x0010U) /* Logical Address 4 */ +#define CEC_OWN_ADDRESS_5 ((uint16_t) 0x0020U) /* Logical Address 5 */ +#define CEC_OWN_ADDRESS_6 ((uint16_t) 0x0040U) /* Logical Address 6 */ +#define CEC_OWN_ADDRESS_7 ((uint16_t) 0x0080U) /* Logical Address 7 */ +#define CEC_OWN_ADDRESS_8 ((uint16_t) 0x0100U) /* Logical Address 9 */ +#define CEC_OWN_ADDRESS_9 ((uint16_t) 0x0200U) /* Logical Address 10 */ +#define CEC_OWN_ADDRESS_10 ((uint16_t) 0x0400U) /* Logical Address 11 */ +#define CEC_OWN_ADDRESS_11 ((uint16_t) 0x0800U) /* Logical Address 12 */ +#define CEC_OWN_ADDRESS_12 ((uint16_t) 0x1000U) /* Logical Address 13 */ +#define CEC_OWN_ADDRESS_13 ((uint16_t) 0x2000U) /* Logical Address 14 */ +#define CEC_OWN_ADDRESS_14 ((uint16_t) 0x4000U) /* Logical Address 15 */ +/** + * @} + */ + +/** @defgroup CEC_Interrupts_Definitions CEC Interrupts definition + * @{ + */ +#define CEC_IT_TXACKE CEC_IER_TXACKEIE +#define CEC_IT_TXERR CEC_IER_TXERRIE +#define CEC_IT_TXUDR CEC_IER_TXUDRIE +#define CEC_IT_TXEND CEC_IER_TXENDIE +#define CEC_IT_TXBR CEC_IER_TXBRIE +#define CEC_IT_ARBLST CEC_IER_ARBLSTIE +#define CEC_IT_RXACKE CEC_IER_RXACKEIE +#define CEC_IT_LBPE CEC_IER_LBPEIE +#define CEC_IT_SBPE CEC_IER_SBPEIE +#define CEC_IT_BRE CEC_IER_BREIE +#define CEC_IT_RXOVR CEC_IER_RXOVRIE +#define CEC_IT_RXEND CEC_IER_RXENDIE +#define CEC_IT_RXBR CEC_IER_RXBRIE +/** + * @} + */ + +/** @defgroup CEC_Flags_Definitions CEC Flags definition + * @{ + */ +#define CEC_FLAG_TXACKE CEC_ISR_TXACKE +#define CEC_FLAG_TXERR CEC_ISR_TXERR +#define CEC_FLAG_TXUDR CEC_ISR_TXUDR +#define CEC_FLAG_TXEND CEC_ISR_TXEND +#define CEC_FLAG_TXBR CEC_ISR_TXBR +#define CEC_FLAG_ARBLST CEC_ISR_ARBLST +#define CEC_FLAG_RXACKE CEC_ISR_RXACKE +#define CEC_FLAG_LBPE CEC_ISR_LBPE +#define CEC_FLAG_SBPE CEC_ISR_SBPE +#define CEC_FLAG_BRE CEC_ISR_BRE +#define CEC_FLAG_RXOVR CEC_ISR_RXOVR +#define CEC_FLAG_RXEND CEC_ISR_RXEND +#define CEC_FLAG_RXBR CEC_ISR_RXBR +/** + * @} + */ + +/** @defgroup CEC_ALL_ERROR CEC all RX or TX errors flags + * @{ + */ +#define CEC_ISR_ALL_ERROR ((uint32_t)CEC_ISR_RXOVR|CEC_ISR_BRE|CEC_ISR_SBPE|CEC_ISR_LBPE|CEC_ISR_RXACKE|\ + CEC_ISR_ARBLST|CEC_ISR_TXUDR|CEC_ISR_TXERR|CEC_ISR_TXACKE) +/** + * @} + */ + +/** @defgroup CEC_IER_ALL_RX CEC all RX errors interrupts enabling flag + * @{ + */ +#define CEC_IER_RX_ALL_ERR ((uint32_t)CEC_IER_RXACKEIE|CEC_IER_LBPEIE|CEC_IER_SBPEIE|CEC_IER_BREIE|CEC_IER_RXOVRIE) +/** + * @} + */ + +/** @defgroup CEC_IER_ALL_TX CEC all TX errors interrupts enabling flag + * @{ + */ +#define CEC_IER_TX_ALL_ERR ((uint32_t)CEC_IER_TXACKEIE|CEC_IER_TXERRIE|CEC_IER_TXUDRIE|CEC_IER_ARBLSTIE) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup CEC_Exported_Macros CEC Exported Macros + * @{ + */ + +/** @brief Reset CEC handle gstate & RxState + * @param __HANDLE__ CEC handle. + * @retval None + */ +#if (USE_HAL_CEC_REGISTER_CALLBACKS == 1) +#define __HAL_CEC_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->gState = HAL_CEC_STATE_RESET; \ + (__HANDLE__)->RxState = HAL_CEC_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_CEC_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->gState = HAL_CEC_STATE_RESET; \ + (__HANDLE__)->RxState = HAL_CEC_STATE_RESET; \ + } while(0) +#endif /* USE_HAL_CEC_REGISTER_CALLBACKS */ +/** @brief Checks whether or not the specified CEC interrupt flag is set. + * @param __HANDLE__ specifies the CEC Handle. + * @param __FLAG__ specifies the flag to check. + * @arg CEC_FLAG_TXACKE: Tx Missing acknowledge Error + * @arg CEC_FLAG_TXERR: Tx Error. + * @arg CEC_FLAG_TXUDR: Tx-Buffer Underrun. + * @arg CEC_FLAG_TXEND: End of transmission (successful transmission of the last byte). + * @arg CEC_FLAG_TXBR: Tx-Byte Request. + * @arg CEC_FLAG_ARBLST: Arbitration Lost + * @arg CEC_FLAG_RXACKE: Rx-Missing Acknowledge + * @arg CEC_FLAG_LBPE: Rx Long period Error + * @arg CEC_FLAG_SBPE: Rx Short period Error + * @arg CEC_FLAG_BRE: Rx Bit Rising Error + * @arg CEC_FLAG_RXOVR: Rx Overrun. + * @arg CEC_FLAG_RXEND: End Of Reception. + * @arg CEC_FLAG_RXBR: Rx-Byte Received. + * @retval ITStatus + */ +#define __HAL_CEC_GET_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ISR & (__FLAG__)) + +/** @brief Clears the interrupt or status flag when raised (write at 1) + * @param __HANDLE__ specifies the CEC Handle. + * @param __FLAG__ specifies the interrupt/status flag to clear. + * This parameter can be one of the following values: + * @arg CEC_FLAG_TXACKE: Tx Missing acknowledge Error + * @arg CEC_FLAG_TXERR: Tx Error. + * @arg CEC_FLAG_TXUDR: Tx-Buffer Underrun. + * @arg CEC_FLAG_TXEND: End of transmission (successful transmission of the last byte). + * @arg CEC_FLAG_TXBR: Tx-Byte Request. + * @arg CEC_FLAG_ARBLST: Arbitration Lost + * @arg CEC_FLAG_RXACKE: Rx-Missing Acknowledge + * @arg CEC_FLAG_LBPE: Rx Long period Error + * @arg CEC_FLAG_SBPE: Rx Short period Error + * @arg CEC_FLAG_BRE: Rx Bit Rising Error + * @arg CEC_FLAG_RXOVR: Rx Overrun. + * @arg CEC_FLAG_RXEND: End Of Reception. + * @arg CEC_FLAG_RXBR: Rx-Byte Received. + * @retval none + */ +#define __HAL_CEC_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ISR |= (__FLAG__)) + +/** @brief Enables the specified CEC interrupt. + * @param __HANDLE__ specifies the CEC Handle. + * @param __INTERRUPT__ specifies the CEC interrupt to enable. + * This parameter can be one of the following values: + * @arg CEC_IT_TXACKE: Tx Missing acknowledge Error IT Enable + * @arg CEC_IT_TXERR: Tx Error IT Enable + * @arg CEC_IT_TXUDR: Tx-Buffer Underrun IT Enable + * @arg CEC_IT_TXEND: End of transmission IT Enable + * @arg CEC_IT_TXBR: Tx-Byte Request IT Enable + * @arg CEC_IT_ARBLST: Arbitration Lost IT Enable + * @arg CEC_IT_RXACKE: Rx-Missing Acknowledge IT Enable + * @arg CEC_IT_LBPE: Rx Long period Error IT Enable + * @arg CEC_IT_SBPE: Rx Short period Error IT Enable + * @arg CEC_IT_BRE: Rx Bit Rising Error IT Enable + * @arg CEC_IT_RXOVR: Rx Overrun IT Enable + * @arg CEC_IT_RXEND: End Of Reception IT Enable + * @arg CEC_IT_RXBR: Rx-Byte Received IT Enable + * @retval none + */ +#define __HAL_CEC_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IER |= (__INTERRUPT__)) + +/** @brief Disables the specified CEC interrupt. + * @param __HANDLE__ specifies the CEC Handle. + * @param __INTERRUPT__ specifies the CEC interrupt to disable. + * This parameter can be one of the following values: + * @arg CEC_IT_TXACKE: Tx Missing acknowledge Error IT Enable + * @arg CEC_IT_TXERR: Tx Error IT Enable + * @arg CEC_IT_TXUDR: Tx-Buffer Underrun IT Enable + * @arg CEC_IT_TXEND: End of transmission IT Enable + * @arg CEC_IT_TXBR: Tx-Byte Request IT Enable + * @arg CEC_IT_ARBLST: Arbitration Lost IT Enable + * @arg CEC_IT_RXACKE: Rx-Missing Acknowledge IT Enable + * @arg CEC_IT_LBPE: Rx Long period Error IT Enable + * @arg CEC_IT_SBPE: Rx Short period Error IT Enable + * @arg CEC_IT_BRE: Rx Bit Rising Error IT Enable + * @arg CEC_IT_RXOVR: Rx Overrun IT Enable + * @arg CEC_IT_RXEND: End Of Reception IT Enable + * @arg CEC_IT_RXBR: Rx-Byte Received IT Enable + * @retval none + */ +#define __HAL_CEC_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IER &= (~(__INTERRUPT__))) + +/** @brief Checks whether or not the specified CEC interrupt is enabled. + * @param __HANDLE__ specifies the CEC Handle. + * @param __INTERRUPT__ specifies the CEC interrupt to check. + * This parameter can be one of the following values: + * @arg CEC_IT_TXACKE: Tx Missing acknowledge Error IT Enable + * @arg CEC_IT_TXERR: Tx Error IT Enable + * @arg CEC_IT_TXUDR: Tx-Buffer Underrun IT Enable + * @arg CEC_IT_TXEND: End of transmission IT Enable + * @arg CEC_IT_TXBR: Tx-Byte Request IT Enable + * @arg CEC_IT_ARBLST: Arbitration Lost IT Enable + * @arg CEC_IT_RXACKE: Rx-Missing Acknowledge IT Enable + * @arg CEC_IT_LBPE: Rx Long period Error IT Enable + * @arg CEC_IT_SBPE: Rx Short period Error IT Enable + * @arg CEC_IT_BRE: Rx Bit Rising Error IT Enable + * @arg CEC_IT_RXOVR: Rx Overrun IT Enable + * @arg CEC_IT_RXEND: End Of Reception IT Enable + * @arg CEC_IT_RXBR: Rx-Byte Received IT Enable + * @retval FlagStatus + */ +#define __HAL_CEC_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IER & (__INTERRUPT__)) + +/** @brief Enables the CEC device + * @param __HANDLE__ specifies the CEC Handle. + * @retval none + */ +#define __HAL_CEC_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= CEC_CR_CECEN) + +/** @brief Disables the CEC device + * @param __HANDLE__ specifies the CEC Handle. + * @retval none + */ +#define __HAL_CEC_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR &= ~CEC_CR_CECEN) + +/** @brief Set Transmission Start flag + * @param __HANDLE__ specifies the CEC Handle. + * @retval none + */ +#define __HAL_CEC_FIRST_BYTE_TX_SET(__HANDLE__) ((__HANDLE__)->Instance->CR |= CEC_CR_TXSOM) + +/** @brief Set Transmission End flag + * @param __HANDLE__ specifies the CEC Handle. + * @retval none + * If the CEC message consists of only one byte, TXEOM must be set before of TXSOM. + */ +#define __HAL_CEC_LAST_BYTE_TX_SET(__HANDLE__) ((__HANDLE__)->Instance->CR |= CEC_CR_TXEOM) + +/** @brief Get Transmission Start flag + * @param __HANDLE__ specifies the CEC Handle. + * @retval FlagStatus + */ +#define __HAL_CEC_GET_TRANSMISSION_START_FLAG(__HANDLE__) ((__HANDLE__)->Instance->CR & CEC_CR_TXSOM) + +/** @brief Get Transmission End flag + * @param __HANDLE__ specifies the CEC Handle. + * @retval FlagStatus + */ +#define __HAL_CEC_GET_TRANSMISSION_END_FLAG(__HANDLE__) ((__HANDLE__)->Instance->CR & CEC_CR_TXEOM) + +/** @brief Clear OAR register + * @param __HANDLE__ specifies the CEC Handle. + * @retval none + */ +#define __HAL_CEC_CLEAR_OAR(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->CFGR, CEC_CFGR_OAR) + +/** @brief Set OAR register (without resetting previously set address in case of multi-address mode) + * To reset OAR, __HAL_CEC_CLEAR_OAR() needs to be called beforehand + * @param __HANDLE__ specifies the CEC Handle. + * @param __ADDRESS__ Own Address value (CEC logical address is identified by bit position) + * @retval none + */ +#define __HAL_CEC_SET_OAR(__HANDLE__,__ADDRESS__) SET_BIT((__HANDLE__)->Instance->CFGR, \ + (__ADDRESS__)<< CEC_CFGR_OAR_LSB_POS) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup CEC_Exported_Functions + * @{ + */ + +/** @addtogroup CEC_Exported_Functions_Group1 + * @{ + */ +/* Initialization and de-initialization functions ****************************/ +HAL_StatusTypeDef HAL_CEC_Init(CEC_HandleTypeDef *hcec); +HAL_StatusTypeDef HAL_CEC_DeInit(CEC_HandleTypeDef *hcec); +HAL_StatusTypeDef HAL_CEC_SetDeviceAddress(CEC_HandleTypeDef *hcec, uint16_t CEC_OwnAddress); +void HAL_CEC_MspInit(CEC_HandleTypeDef *hcec); +void HAL_CEC_MspDeInit(CEC_HandleTypeDef *hcec); + +#if (USE_HAL_CEC_REGISTER_CALLBACKS == 1) +HAL_StatusTypeDef HAL_CEC_RegisterCallback(CEC_HandleTypeDef *hcec, HAL_CEC_CallbackIDTypeDef CallbackID, + pCEC_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_CEC_UnRegisterCallback(CEC_HandleTypeDef *hcec, HAL_CEC_CallbackIDTypeDef CallbackID); + +HAL_StatusTypeDef HAL_CEC_RegisterRxCpltCallback(CEC_HandleTypeDef *hcec, pCEC_RxCallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_CEC_UnRegisterRxCpltCallback(CEC_HandleTypeDef *hcec); +#endif /* USE_HAL_CEC_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @addtogroup CEC_Exported_Functions_Group2 + * @{ + */ +/* I/O operation functions ***************************************************/ +HAL_StatusTypeDef HAL_CEC_Transmit_IT(CEC_HandleTypeDef *hcec, uint8_t InitiatorAddress, uint8_t DestinationAddress, + const uint8_t *pData, uint32_t Size); +uint32_t HAL_CEC_GetLastReceivedFrameSize(const CEC_HandleTypeDef *hcec); +void HAL_CEC_ChangeRxBuffer(CEC_HandleTypeDef *hcec, uint8_t *Rxbuffer); +void HAL_CEC_IRQHandler(CEC_HandleTypeDef *hcec); +void HAL_CEC_TxCpltCallback(CEC_HandleTypeDef *hcec); +void HAL_CEC_RxCpltCallback(CEC_HandleTypeDef *hcec, uint32_t RxFrameSize); +void HAL_CEC_ErrorCallback(CEC_HandleTypeDef *hcec); +/** + * @} + */ + +/** @addtogroup CEC_Exported_Functions_Group3 + * @{ + */ +/* Peripheral State functions ************************************************/ +HAL_CEC_StateTypeDef HAL_CEC_GetState(const CEC_HandleTypeDef *hcec); +uint32_t HAL_CEC_GetError(const CEC_HandleTypeDef *hcec); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/** @defgroup CEC_Private_Types CEC Private Types + * @{ + */ + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup CEC_Private_Variables CEC Private Variables + * @{ + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup CEC_Private_Constants CEC Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup CEC_Private_Macros CEC Private Macros + * @{ + */ + +#define IS_CEC_SIGNALFREETIME(__SFT__) ((__SFT__) <= CEC_CFGR_SFT) + +#define IS_CEC_TOLERANCE(__RXTOL__) (((__RXTOL__) == CEC_STANDARD_TOLERANCE) || \ + ((__RXTOL__) == CEC_EXTENDED_TOLERANCE)) + +#define IS_CEC_BRERXSTOP(__BRERXSTOP__) (((__BRERXSTOP__) == CEC_NO_RX_STOP_ON_BRE) || \ + ((__BRERXSTOP__) == CEC_RX_STOP_ON_BRE)) + +#define IS_CEC_BREERRORBITGEN(__ERRORBITGEN__) (((__ERRORBITGEN__) == CEC_BRE_ERRORBIT_NO_GENERATION) || \ + ((__ERRORBITGEN__) == CEC_BRE_ERRORBIT_GENERATION)) + +#define IS_CEC_LBPEERRORBITGEN(__ERRORBITGEN__) (((__ERRORBITGEN__) == CEC_LBPE_ERRORBIT_NO_GENERATION) || \ + ((__ERRORBITGEN__) == CEC_LBPE_ERRORBIT_GENERATION)) + +#define IS_CEC_BROADCASTERROR_NO_ERRORBIT_GENERATION(__ERRORBITGEN__) \ + (((__ERRORBITGEN__) == CEC_BROADCASTERROR_ERRORBIT_GENERATION) || \ + ((__ERRORBITGEN__) == CEC_BROADCASTERROR_NO_ERRORBIT_GENERATION)) + +#define IS_CEC_SFTOP(__SFTOP__) (((__SFTOP__) == CEC_SFT_START_ON_TXSOM) || \ + ((__SFTOP__) == CEC_SFT_START_ON_TX_RX_END)) + +#define IS_CEC_LISTENING_MODE(__MODE__) (((__MODE__) == CEC_REDUCED_LISTENING_MODE) || \ + ((__MODE__) == CEC_FULL_LISTENING_MODE)) + +/** @brief Check CEC message size. + * The message size is the payload size: without counting the header, + * it varies from 0 byte (ping operation, one header only, no payload) to + * 15 bytes (1 opcode and up to 14 operands following the header). + * @param __SIZE__ CEC message size. + * @retval Test result (TRUE or FALSE). + */ +#define IS_CEC_MSGSIZE(__SIZE__) ((__SIZE__) <= 0x10U) + +/** @brief Check CEC device Own Address Register (OAR) setting. + * OAR address is written in a 15-bit field within CEC_CFGR register. + * @param __ADDRESS__ CEC own address. + * @retval Test result (TRUE or FALSE). + */ +#define IS_CEC_OWN_ADDRESS(__ADDRESS__) ((__ADDRESS__) <= 0x7FFFU) + +/** @brief Check CEC initiator or destination logical address setting. + * Initiator and destination addresses are coded over 4 bits. + * @param __ADDRESS__ CEC initiator or logical address. + * @retval Test result (TRUE or FALSE). + */ +#define IS_CEC_ADDRESS(__ADDRESS__) ((__ADDRESS__) <= 0xFU) +/** + * @} + */ +/* Private functions ---------------------------------------------------------*/ +/** @defgroup CEC_Private_Functions CEC Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* CEC */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xxHAL_CEC_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_comp.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_comp.h new file mode 100644 index 0000000000..c7ad3a3f65 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_comp.h @@ -0,0 +1,622 @@ +/** + ********************************************************************************************************************** + * @file stm32h5xx_hal_comp.h + * @author MCD Application Team + * @brief Header file of COMP HAL module. + ********************************************************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ********************************************************************************************************************** + */ + +/* Define to prevent recursive inclusion -----------------------------------------------------------------------------*/ +#ifndef STM32H5xx_HAL_COMP_H +#define STM32H5xx_HAL_COMP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ----------------------------------------------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" +#include "stm32h5xx_ll_exti.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ +#if defined (COMP1) + +/** @addtogroup COMP + * @{ + */ + +/* Exported types ----------------------------------------------------------------------------------------------------*/ +/** @defgroup COMP_Exported_Types COMP Exported Types + * @{ + */ + +/** + * @brief COMP Init structure definition + */ +typedef struct +{ + uint32_t Mode; /*!< Set comparator operating mode to adjust power and speed. + Note: For the characteristics of comparator power modes + (propagation delay and power consumption), refer to device datasheet. + This parameter can be a value of @ref COMP_PowerMode */ + + uint32_t InputPlus; /*!< Set comparator input plus (non-inverting input). + This parameter can be a value of @ref COMP_InputPlus */ + + uint32_t InputMinus; /*!< Set comparator input minus (inverting input). + This parameter can be a value of @ref COMP_InputMinus */ + + uint32_t Hysteresis; /*!< Set comparator hysteresis mode of the input minus. + This parameter can be a value of @ref COMP_Hysteresis */ + + uint32_t OutputPol; /*!< Set comparator output polarity. + This parameter can be a value of @ref COMP_OutputPolarity + Note: Specific to comparator of this STM32 series: comparator output + triggers interruption on high level. HAL_COMP_Start_x functions + can change output polarity depending on initial output level. */ + + uint32_t BlankingSrce; /*!< Set comparator blanking source. + This parameter can be a value of @ref COMP_BlankingSrce */ + + uint32_t TriggerMode; /*!< Set the comparator output triggering External Interrupt Line (EXTI). + This parameter can be a value of @ref COMP_EXTI_TriggerMode */ + +} COMP_InitTypeDef; + +/** + * @brief HAL COMP state machine: HAL COMP states definition + */ +#define COMP_STATE_BITFIELD_LOCK (0x10U) +typedef enum +{ + HAL_COMP_STATE_RESET = 0x00, /*!< COMP not yet initialized */ + HAL_COMP_STATE_RESET_LOCKED = (HAL_COMP_STATE_RESET | \ + COMP_STATE_BITFIELD_LOCK), /*!< COMP not yet initialized and configuration is locked */ + HAL_COMP_STATE_READY = 0x01, /*!< COMP initialized and ready for use */ + HAL_COMP_STATE_READY_LOCKED = (HAL_COMP_STATE_READY | \ + COMP_STATE_BITFIELD_LOCK), /*!< COMP initialized but configuration is locked */ + HAL_COMP_STATE_BUSY = 0x02, /*!< COMP is running */ + HAL_COMP_STATE_BUSY_LOCKED = (HAL_COMP_STATE_BUSY | \ + COMP_STATE_BITFIELD_LOCK) /*!< COMP is running and configuration is locked */ + +} HAL_COMP_StateTypeDef; + +/** + * @brief COMP Handle Structure definition + */ +#if (USE_HAL_COMP_REGISTER_CALLBACKS == 1U) +typedef struct __COMP_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_COMP_REGISTER_CALLBACKS */ +{ + COMP_TypeDef *Instance; /*!< Register base address */ + COMP_InitTypeDef Init; /*!< COMP required parameters */ + HAL_LockTypeDef Lock; /*!< Locking object */ + __IO HAL_COMP_StateTypeDef State; /*!< COMP communication state */ + __IO uint32_t ErrorCode; /*!< COMP error code */ +#if (USE_HAL_COMP_REGISTER_CALLBACKS == 1U) + void (* TriggerCallback)(struct __COMP_HandleTypeDef *hcomp); /*!< COMP trigger callback */ + void (* MspInitCallback)(struct __COMP_HandleTypeDef *hcomp); /*!< COMP Msp Init callback */ + void (* MspDeInitCallback)(struct __COMP_HandleTypeDef *hcomp); /*!< COMP Msp DeInit callback */ +#endif /* USE_HAL_COMP_REGISTER_CALLBACKS */ + uint8_t InterruptAutoRearm; /*!< COMP interrupt auto rearm setting */ +} COMP_HandleTypeDef; + +#if (USE_HAL_COMP_REGISTER_CALLBACKS == 1U) +/** + * @brief HAL COMP Callback ID enumeration definition + */ +typedef enum +{ + HAL_COMP_TRIGGER_CB_ID = 0x00U, /*!< COMP trigger callback ID */ + HAL_COMP_MSPINIT_CB_ID = 0x01U, /*!< COMP Msp Init callback ID */ + HAL_COMP_MSPDEINIT_CB_ID = 0x02U /*!< COMP Msp DeInit callback ID */ + +} HAL_COMP_CallbackIDTypeDef; + +/** + * @brief HAL COMP Callback pointer definition + */ +typedef void (*pCOMP_CallbackTypeDef)(COMP_HandleTypeDef *hcomp); /*!< pointer to a COMP callback function */ + +#endif /* USE_HAL_COMP_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/* Exported constants ------------------------------------------------------------------------------------------------*/ +/** @defgroup COMP_Exported_Constants COMP Exported Constants + * @{ + */ + +/** @defgroup COMP_Error_Code COMP Error Code + * @{ + */ +#define HAL_COMP_ERROR_NONE (0x00UL) /*!< No error */ +#if (USE_HAL_COMP_REGISTER_CALLBACKS == 1U) +#define HAL_COMP_ERROR_INVALID_CALLBACK (0x01U) /*!< Invalid Callback error */ +#endif /* USE_HAL_COMP_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @defgroup COMP_PowerMode COMP power mode + * @{ + */ +/* Note: For the characteristics of comparator power modes */ +/* (propagation delay and power consumption), */ +/* refer to device datasheet. */ +#define COMP_POWERMODE_HIGHSPEED (0x00000000UL) /*!< High Speed */ +#define COMP_POWERMODE_MEDIUMSPEED (COMP_CFGR1_PWRMODE_0) /*!< Medium Speed */ +#define COMP_POWERMODE_ULTRALOWPOWER (COMP_CFGR1_PWRMODE) /*!< Ultra-low power mode */ +/** + * @} + */ + +/** @defgroup COMP_InputPlus COMP input plus (non-inverting input) + * @{ + */ +#define COMP_INPUT_PLUS_IO1 (0x00000000UL) /*!< Comparator input plus connected to IO1 (pin PB0) */ +#define COMP_INPUT_PLUS_IO2 (COMP_CFGR2_INPSEL0) /*!< Comparator input plus connected to IO2 (pin PA0) */ +#define COMP_INPUT_PLUS_IO3 (COMP_CFGR1_INPSEL1) /*!< Comparator input plus connected to IO3 (pin PB2) */ +#define COMP_INPUT_PLUS_DAC1_CH1 (COMP_CFGR1_INPSEL2) /*!< Comparator input plus connected to (DAC1_CH1) */ +/** + * @} + */ + +/** @defgroup COMP_InputMinus COMP input minus (inverting input) + * @{ + */ +#define COMP_INPUT_MINUS_1_4VREFINT (COMP_CFGR1_SCALEN |\ + COMP_CFGR1_BRGEN) /*!< Comparator input minus connected to 1/4 VrefInt */ +#define COMP_INPUT_MINUS_1_2VREFINT (COMP_CFGR1_INMSEL_0 |\ + COMP_CFGR1_SCALEN |\ + COMP_CFGR1_BRGEN) /*!< Comparator input minus connected to 1/2 VrefInt */ +#define COMP_INPUT_MINUS_3_4VREFINT (COMP_CFGR1_INMSEL_1 |\ + COMP_CFGR1_SCALEN |\ + COMP_CFGR1_BRGEN) /*!< Comparator input minus connected to 3/4 VrefInt */ +#define COMP_INPUT_MINUS_VREFINT (COMP_CFGR1_INMSEL_1 |\ + COMP_CFGR1_INMSEL_0 |\ + COMP_CFGR1_SCALEN) /*!< Comparator input minus connected to VrefInt */ +#define COMP_INPUT_MINUS_DAC1_CH1 (COMP_CFGR1_INMSEL_2) /*!< Comparator input minus connected to DAC1 channel 1 */ +#define COMP_INPUT_MINUS_IO1 (COMP_CFGR1_INMSEL_2 |\ + COMP_CFGR1_INMSEL_0) /*!< Comparator input minus connected to IO1 (pin PC4) */ +#define COMP_INPUT_MINUS_IO2 (COMP_CFGR1_INMSEL_2 |\ + COMP_CFGR1_INMSEL_1) /*!< Comparator input minus connected to IO2 (pin PB1) */ +#define COMP_INPUT_MINUS_IO3 (COMP_CFGR1_INMSEL_2 |\ + COMP_CFGR1_INMSEL_1 |\ + COMP_CFGR1_INMSEL_0) /*!< Comparator input minus connected to IO3 (pin PA5) */ +#define COMP_INPUT_MINUS_TEMPSENSOR (COMP_CFGR1_INMSEL_3) /*!< Comparator input minus connected to internal + temperature sensor (also accessible through ADC peripheral) */ +#define COMP_INPUT_MINUS_VBAT (COMP_CFGR1_INMSEL_3 |\ + COMP_CFGR1_INMSEL_0) /*!< Comparator input minus connected to Vbat/4: + Vbat voltage through a divider ladder of factor 1/4 to have input voltage + always below Vdda. */ + +/** + * @} + */ + +/** @defgroup COMP_Hysteresis COMP hysteresis + * @{ + */ +#define COMP_HYSTERESIS_NONE (0x00000000UL) /*!< No hysteresis */ +#define COMP_HYSTERESIS_LOW (COMP_CFGR1_HYST_0) /*!< Hysteresis level low */ +#define COMP_HYSTERESIS_MEDIUM (COMP_CFGR1_HYST_1) /*!< Hysteresis level medium */ +#define COMP_HYSTERESIS_HIGH (COMP_CFGR1_HYST_0 | COMP_CFGR1_HYST_1) /*!< Hysteresis level high */ +/** + * @} + */ + +/** @defgroup COMP_OutputPolarity COMP output Polarity + * @{ + */ +#define COMP_OUTPUTPOL_NONINVERTED (0x00000000UL) /*!< COMP output level is not inverted (comparator output + is high when the input plus is at a higher voltage + than the input minus) */ +#define COMP_OUTPUTPOL_INVERTED (COMP_CFGR1_POLARITY) /*!< COMP output level is inverted (comparator output is + low when the input plus is at a higher voltage than + the input minus) */ +/** + * @} + */ + +/** @defgroup COMP_BlankingSrce COMP blanking source + * @{ + */ +#define COMP_BLANKINGSRC_NONE (0x00000000UL) /*!< Comparator output without blanking */ +#define COMP_BLANKINGSRC_TIM1_OC5 (COMP_CFGR1_BLANKING_0) /*!< TIM1 OC5 selected as blanking source */ +#define COMP_BLANKINGSRC_TIM2_OC3 (COMP_CFGR1_BLANKING_1) /*!< TIM2 OC3 selected as blanking source */ +#define COMP_BLANKINGSRC_TIM3_OC3 (COMP_CFGR1_BLANKING_0 |\ + COMP_CFGR1_BLANKING_1) /*!< TIM3 OC3 selected as blanking source */ +#define COMP_BLANKINGSRC_TIM3_OC4 (COMP_CFGR1_BLANKING_2) /*!< TIM3 OC4 selected as blanking source */ +#define COMP_BLANKINGSRC_LPTIM1_OC2 (COMP_CFGR1_BLANKING_2 |\ + COMP_CFGR1_BLANKING_0) /*!< LPTIM1 OC2 selected as blanking source */ +#define COMP_BLANKINGSRC_LPTIM2_OC2 (COMP_CFGR1_BLANKING_2 |\ + COMP_CFGR1_BLANKING_1) /*!< LPTIM2 OC2 selected as blanking source */ +/** + * @} + */ + +/** @defgroup COMP_OutputLevel COMP Output Level + * @{ + */ +/* Note: Comparator output level values are fixed to "0" and "1", */ +/* corresponding COMP register bit is managed by HAL function to match */ +/* with these values (independently of bit position in register). */ + +/* When output polarity is not inverted, comparator output is low when + the input plus is at a lower voltage than the input minus */ +#define COMP_OUTPUT_LEVEL_LOW (0x00000000UL) +/* When output polarity is not inverted, comparator output is high when + the input plus is at a higher voltage than the input minus */ +#define COMP_OUTPUT_LEVEL_HIGH (0x00000001UL) +/** + * @} + */ + +/** @defgroup COMP_EXTI_TriggerMode COMP output to EXTI + * @{ + */ +#define COMP_TRIGGERMODE_NONE (0x00000000UL) /*!< Comparator output triggering no External + Interrupt Line */ +#define COMP_TRIGGERMODE_IT_RISING_FALLING (COMP_EXTI_IT |\ + COMP_EXTI_RISING |\ + COMP_EXTI_FALLING) /*!< Comparator output triggering interrupt + on rising and falling edges. + Note: Specific to comparator of this STM32 series: comparator output + triggers interruption on high level. HAL_COMP_Start_x functions + can change output polarity depending on initial output level. */ +/** + * @} + */ + +/** @defgroup COMP_Flag COMP Flag + * @{ + */ +#define COMP_FLAG_C1I COMP_SR_C1IF /*!< Comparator 1 Interrupt Flag */ +#define COMP_FLAG_LOCK COMP_CFGR1_LOCK /*!< Lock flag */ +/** + * @} + */ + +/** @defgroup COMP_IT_CLEAR_Flags COMP Interruption Clear Flags + * @{ + */ +#define COMP_CLEAR_C1IF COMP_ICFR_CC1IF /*!< Clear Comparator 1 Interrupt Flag */ +/** + * @} + */ + +/** @defgroup COMP_Interrupts_Definitions COMP Interrupts Definitions + * @{ + */ +#define COMP_IT_EN COMP_CFGR1_ITEN +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ----------------------------------------------------------------------------------------------------*/ +/** @defgroup COMP_Exported_Macros COMP Exported Macros + * @{ + */ + +/** @defgroup COMP_Handle_Management COMP Handle Management + * @{ + */ + +/** @brief Reset COMP handle state. + * @param __HANDLE__ COMP handle + * @retval None + */ +#if (USE_HAL_COMP_REGISTER_CALLBACKS == 1U) +#define __HAL_COMP_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->State = HAL_COMP_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_COMP_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_COMP_STATE_RESET) +#endif /* USE_HAL_COMP_REGISTER_CALLBACKS */ + +/** + * @brief Clear COMP error code (set it to no error code "HAL_COMP_ERROR_NONE"). + * @param __HANDLE__ COMP handle + * @retval None + */ +#define COMP_CLEAR_ERRORCODE(__HANDLE__) ((__HANDLE__)->ErrorCode = HAL_COMP_ERROR_NONE) + +/** + * @brief Enable the specified comparator. + * @param __HANDLE__ COMP handle + * @retval None + */ +#define __HAL_COMP_ENABLE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CFGR1, COMP_CFGR1_EN) + +/** + * @brief Disable the specified comparator. + * @param __HANDLE__ COMP handle + * @retval None + */ +#define __HAL_COMP_DISABLE(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->CFGR1, COMP_CFGR1_EN) + +/** + * @brief Lock the specified comparator configuration. + * @note Using this macro induce HAL COMP handle state machine being no + * more in line with COMP instance state. + * To keep HAL COMP handle state machine updated, it is recommended + * to use function "HAL_COMP_Lock')". + * @param __HANDLE__ COMP handle + * @retval None + */ +#define __HAL_COMP_LOCK(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CFGR1, COMP_CFGR1_LOCK) + +/** + * @brief Check whether the specified comparator is locked. + * @param __HANDLE__ COMP handle + * @retval Value 0 if COMP instance is not locked, value 1 if COMP instance is locked + */ +#define __HAL_COMP_IS_LOCKED(__HANDLE__) (READ_BIT((__HANDLE__)->Instance->CFGR1, COMP_CFGR1_LOCK) == COMP_CFGR1_LOCK) + +/** + * @} + */ + +/** @defgroup COMP_Exti_Management COMP external interrupt line management + * @{ + */ + +/** @brief Checks if the specified COMP interrupt source is enabled or disabled. + * @param __HANDLE__ specifies the COMP Handle. + * This parameter can be COMP1. + * @param __INTERRUPT__ specifies the COMP interrupt source to check. + * This parameter can be one of the following values: + * @arg COMP_IT_EN Comparator interrupt enable + * + * @retval State of interruption (TRUE or FALSE) + */ +#define __HAL_COMP_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) \ + ((((__HANDLE__)->Instance->CFGR1 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) + +/** @brief Checks whether the specified COMP flag is set or not. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg COMP_FLAG_C1I Comparator 1 Interrupt Flag + * @retval State of flag (TRUE or FALSE) + */ +#define __HAL_COMP_GET_FLAG(__FLAG__) ((COMP1->SR & (__FLAG__)) == (__FLAG__)) + +/** @brief Clears the specified COMP pending flag. + * @param __FLAG__ specifies the flag to check. + * This parameter can be any combination of the following values: + * @arg COMP_CLEAR_C1IF Clear Comparator 1 Interrupt Flag + * @retval None + */ +#define __HAL_COMP_CLEAR_FLAG(__FLAG__) (COMP1->ICFR = (__FLAG__)) + +/** @brief Clear the COMP C1I flag. + * @retval None + */ +#define __HAL_COMP_CLEAR_C1IFLAG() __HAL_COMP_CLEAR_FLAG( COMP_CLEAR_C1IF) + +/** @brief Enable the specified COMP interrupt. + * @param __HANDLE__ specifies the COMP Handle. + * @param __INTERRUPT__ specifies the COMP interrupt source to enable. + * This parameter can be one of the following values: + * @arg COMP_CFGR1_ITEN Comparator interrupt + * @retval None + */ +#define __HAL_COMP_ENABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->CFGR1) |= (__INTERRUPT__) ) + +/** @brief Disable the specified COMP interrupt. + * @param __HANDLE__ specifies the COMP Handle. + * @param __INTERRUPT__ specifies the COMP interrupt source to enable. + * This parameter can be one of the following values: + * @arg COMP_CFGR1_ITEN Comparator interrupt + * @retval None + */ +#define __HAL_COMP_DISABLE_IT(__HANDLE__,__INTERRUPT__) (((__HANDLE__)->Instance->CFGR1) &= ~(__INTERRUPT__)) + +/** + * @} + */ + +/** + * @} + */ + +/* Private types -----------------------------------------------------------------------------------------------------*/ +/* Private constants -------------------------------------------------------------------------------------------------*/ +/** @defgroup COMP_Private_Constants COMP Private Constants + * @{ + */ + +/** @defgroup COMP_ExtiLine COMP EXTI Lines + * @{ + */ +#define COMP_EXTI_LINE_COMP1 (EXTI_IMR1_IM29) /*!< EXTI line 29 connected to COMP1 output */ +/** + * @} + */ + +/** @defgroup COMP_ExtiLine COMP EXTI Lines + * @{ + */ +#define COMP_EXTI_IT (0x00000001UL) /*!< EXTI line event with interruption */ +#define COMP_EXTI_RISING (0x00000010UL) /*!< EXTI line event on rising edge */ +#define COMP_EXTI_FALLING (0x00000020UL) /*!< EXTI line event on falling edge */ +/** + * @} + */ + +/** + * @} + */ + +/* Private macros ----------------------------------------------------------------------------------------------------*/ +/** @defgroup COMP_Private_Macros COMP Private Macros + * @{ + */ + +/** @defgroup COMP_GET_EXTI_LINE COMP private macros to get EXTI line associated with comparators + * @{ + */ +/** + * @brief Get the specified EXTI line for a comparator instance. + * @param __INSTANCE__ specifies the COMP instance. + * @retval value of @ref COMP_ExtiLine + */ +#define COMP_GET_EXTI_LINE(__INSTANCE__) (COMP_EXTI_LINE_COMP1) +/** + * @} + */ + +/** @defgroup COMP_IS_COMP_Private_Definitions COMP private macros to check input parameters + * @{ + */ +#define IS_COMP_POWERMODE(__POWERMODE__) (((__POWERMODE__) == COMP_POWERMODE_HIGHSPEED) || \ + ((__POWERMODE__) == COMP_POWERMODE_MEDIUMSPEED) || \ + ((__POWERMODE__) == COMP_POWERMODE_ULTRALOWPOWER) ) + +#define IS_COMP_INPUT_PLUS(__COMP_INSTANCE__, __INPUT_PLUS__) (((__INPUT_PLUS__) == COMP_INPUT_PLUS_IO1) || \ + ((__INPUT_PLUS__) == COMP_INPUT_PLUS_IO2) || \ + ((__INPUT_PLUS__) == COMP_INPUT_PLUS_IO3) || \ + ((__INPUT_PLUS__) == COMP_INPUT_PLUS_DAC1_CH1)) + +#define IS_COMP_INPUT_MINUS(__COMP_INSTANCE__, __INPUT_MINUS__) (((__INPUT_MINUS__) == COMP_INPUT_MINUS_1_4VREFINT) || \ + ((__INPUT_MINUS__) == COMP_INPUT_MINUS_1_2VREFINT) || \ + ((__INPUT_MINUS__) == COMP_INPUT_MINUS_3_4VREFINT) || \ + ((__INPUT_MINUS__) == COMP_INPUT_MINUS_VREFINT) || \ + ((__INPUT_MINUS__) == COMP_INPUT_MINUS_DAC1_CH1) || \ + ((__INPUT_MINUS__) == COMP_INPUT_MINUS_IO1) || \ + ((__INPUT_MINUS__) == COMP_INPUT_MINUS_IO2) || \ + ((__INPUT_MINUS__) == COMP_INPUT_MINUS_IO3) || \ + ((__INPUT_MINUS__) == COMP_INPUT_MINUS_TEMPSENSOR) || \ + ((__INPUT_MINUS__) == COMP_INPUT_MINUS_VBAT)) + +#define IS_COMP_HYSTERESIS(__HYSTERESIS__) (((__HYSTERESIS__) == COMP_HYSTERESIS_NONE) || \ + ((__HYSTERESIS__) == COMP_HYSTERESIS_LOW) || \ + ((__HYSTERESIS__) == COMP_HYSTERESIS_MEDIUM) || \ + ((__HYSTERESIS__) == COMP_HYSTERESIS_HIGH)) + +#define IS_COMP_OUTPUTPOL(__POL__) (((__POL__) == COMP_OUTPUTPOL_NONINVERTED) || \ + ((__POL__) == COMP_OUTPUTPOL_INVERTED)) + +#define IS_COMP_BLANKINGSRCE(__SOURCE__) (((__SOURCE__) == COMP_BLANKINGSRC_NONE) || \ + ((__SOURCE__) == COMP_BLANKINGSRC_TIM1_OC5) || \ + ((__SOURCE__) == COMP_BLANKINGSRC_TIM2_OC3) || \ + ((__SOURCE__) == COMP_BLANKINGSRC_TIM3_OC3) || \ + ((__SOURCE__) == COMP_BLANKINGSRC_TIM3_OC4) || \ + ((__SOURCE__) == COMP_BLANKINGSRC_LPTIM1_OC2) || \ + ((__SOURCE__) == COMP_BLANKINGSRC_LPTIM2_OC2)) + + +#define IS_COMP_TRIGGERMODE(__MODE__) (((__MODE__) == COMP_TRIGGERMODE_NONE) || \ + ((__MODE__) == COMP_TRIGGERMODE_IT_RISING_FALLING)) + +#define IS_COMP_OUTPUT_LEVEL(__OUTPUT_LEVEL__) (((__OUTPUT_LEVEL__) == COMP_OUTPUT_LEVEL_LOW) || \ + ((__OUTPUT_LEVEL__) == COMP_OUTPUT_LEVEL_HIGH)) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions ------------------------------------------------------------------------------------------------*/ +/** @addtogroup COMP_Exported_Functions + * @{ + */ + +/** @addtogroup COMP_Exported_Functions_Group1 + * @{ + */ +/* Initialization and de-initialization functions */ +HAL_StatusTypeDef HAL_COMP_Init(COMP_HandleTypeDef *hcomp); +HAL_StatusTypeDef HAL_COMP_DeInit(COMP_HandleTypeDef *hcomp); +void HAL_COMP_MspInit(COMP_HandleTypeDef *hcomp); +void HAL_COMP_MspDeInit(COMP_HandleTypeDef *hcomp); +#if (USE_HAL_COMP_REGISTER_CALLBACKS == 1U) +/* Callbacks Register/UnRegister functions */ +HAL_StatusTypeDef HAL_COMP_RegisterCallback(COMP_HandleTypeDef *hcomp, HAL_COMP_CallbackIDTypeDef CallbackID, + pCOMP_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_COMP_UnRegisterCallback(COMP_HandleTypeDef *hcomp, HAL_COMP_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_COMP_REGISTER_CALLBACKS */ +/** + * @} + */ + +/* IO operation functions */ +/** @addtogroup COMP_Exported_Functions_Group2 + * @{ + */ +HAL_StatusTypeDef HAL_COMP_Start(COMP_HandleTypeDef *hcomp); +HAL_StatusTypeDef HAL_COMP_Stop(COMP_HandleTypeDef *hcomp); +HAL_StatusTypeDef HAL_COMP_Start_IT_OneShot(COMP_HandleTypeDef *hcomp); +HAL_StatusTypeDef HAL_COMP_Start_IT_AutoRearm(COMP_HandleTypeDef *hcomp); +HAL_StatusTypeDef HAL_COMP_Stop_IT(COMP_HandleTypeDef *hcomp); +void HAL_COMP_IRQHandler(COMP_HandleTypeDef *hcomp); + +/** + * @} + */ + +/* Peripheral Control functions */ +/** @addtogroup COMP_Exported_Functions_Group3 + * @{ + */ +HAL_StatusTypeDef HAL_COMP_Lock(COMP_HandleTypeDef *hcomp); +uint32_t HAL_COMP_GetOutputLevel(const COMP_HandleTypeDef *hcomp); +/* Callback in interrupt mode */ +void HAL_COMP_TriggerCallback(COMP_HandleTypeDef *hcomp); +/** + * @} + */ + +/* Peripheral State functions */ +/** @addtogroup COMP_Exported_Functions_Group4 + * @{ + */ +HAL_COMP_StateTypeDef HAL_COMP_GetState(const COMP_HandleTypeDef *hcomp); +uint32_t HAL_COMP_GetError(const COMP_HandleTypeDef *hcomp); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* COMP1 */ +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_COMP_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_conf_template.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_conf_template.h new file mode 100644 index 0000000000..c453c736ee --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_conf_template.h @@ -0,0 +1,488 @@ +/** + ********************************************************************************************************************** + * @file stm32h5xx_hal_conf_template.h + * @author MCD Application Team + * @brief HAL configuration template file. + * This file should be copied to the application folder and renamed + * to stm32h5xx_hal_conf.h. + ********************************************************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ********************************************************************************************************************** + */ + +/* Define to prevent recursive inclusion -----------------------------------------------------------------------------*/ +#ifndef STM32H5xx_HAL_CONF_H +#define STM32H5xx_HAL_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Exported types ----------------------------------------------------------------------------------------------------*/ +/* Exported constants ------------------------------------------------------------------------------------------------*/ + +/* ########################################### Module Selection ##################################################### */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +#define HAL_ADC_MODULE_ENABLED +#define HAL_CEC_MODULE_ENABLED +#define HAL_COMP_MODULE_ENABLED +#define HAL_CORDIC_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED +#define HAL_CRC_MODULE_ENABLED +#define HAL_CRYP_MODULE_ENABLED +#define HAL_DAC_MODULE_ENABLED +#define HAL_DCACHE_MODULE_ENABLED +#define HAL_DCMI_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_DTS_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED +#define HAL_ETH_MODULE_ENABLED +#define HAL_FDCAN_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_FMAC_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_GTZC_MODULE_ENABLED +#define HAL_HASH_MODULE_ENABLED +#define HAL_HCD_MODULE_ENABLED +#define HAL_I2C_MODULE_ENABLED +#define HAL_I2S_MODULE_ENABLED +#define HAL_I3C_MODULE_ENABLED +#define HAL_ICACHE_MODULE_ENABLED +#define HAL_IRDA_MODULE_ENABLED +#define HAL_IWDG_MODULE_ENABLED +#define HAL_LPTIM_MODULE_ENABLED +#define HAL_MMC_MODULE_ENABLED +#define HAL_NAND_MODULE_ENABLED +#define HAL_NOR_MODULE_ENABLED +#define HAL_OTFDEC_MODULE_ENABLED +#define HAL_OPAMP_MODULE_ENABLED +#define HAL_PCD_MODULE_ENABLED +#define HAL_PKA_MODULE_ENABLED +#define HAL_PSSI_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_RAMCFG_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_RNG_MODULE_ENABLED +#define HAL_RTC_MODULE_ENABLED +#define HAL_SAI_MODULE_ENABLED +#define HAL_SD_MODULE_ENABLED +#define HAL_SDRAM_MODULE_ENABLED +#define HAL_SMARTCARD_MODULE_ENABLED +#define HAL_SMBUS_MODULE_ENABLED +#define HAL_SPI_MODULE_ENABLED +#define HAL_SRAM_MODULE_ENABLED +#define HAL_TIM_MODULE_ENABLED +#define HAL_UART_MODULE_ENABLED +#define HAL_USART_MODULE_ENABLED +#define HAL_WWDG_MODULE_ENABLED +#define HAL_XSPI_MODULE_ENABLED + +/* ####################################### Oscillator Values adaptation ##############################################*/ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) +#define HSE_VALUE 25000000UL /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) +#define HSE_STARTUP_TIMEOUT 100UL /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal Core Speed oscillator (CSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when CSI is used as system clock source, directly or through the PLL). + */ +#if !defined (CSI_VALUE) +#define CSI_VALUE 4000000UL /*!< Value of the Internal oscillator in Hz*/ +#endif /* CSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) +#define HSI_VALUE 64000000UL /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI48) value for USB FS, SDMMC and RNG. + * This internal oscillator is mainly dedicated to provide a high precision clock to + * the USB peripheral by means of a special Clock Recovery System (CRS) circuitry. + * When the CRS is not used, the HSI48 RC oscillator runs on it default frequency + * which is subject to manufacturing process variations. + */ +#if !defined (HSI48_VALUE) +#define HSI48_VALUE 48000000UL /*!< Value of the Internal High Speed oscillator for USB FS/SDMMC/RNG in Hz. + The real value my vary depending on manufacturing process variations.*/ +#endif /* HSI48_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) +#define LSI_VALUE 32000UL /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz +The real value may vary depending on the variations +in voltage and temperature.*/ + +#if !defined (LSI_STARTUP_TIME) +#define LSI_STARTUP_TIME 130UL /*!< Time out for LSI start up, in ms */ +#endif /* LSI_STARTUP_TIME */ + +/** + * @brief External Low Speed oscillator (LSE) value. + * This value is used by the UART, RTC HAL module to compute the system frequency + */ +#if !defined (LSE_VALUE) +#define LSE_VALUE 32768UL /*!< Value of the External oscillator in Hz*/ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) +#define LSE_STARTUP_TIMEOUT 5000UL /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + + +/** + * @brief External clock source for SPI/SAI peripheral + * This value is used by the SPI/SAI HAL module to compute the SPI/SAI clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) +#define EXTERNAL_CLOCK_VALUE 12288000UL /*!< Value of the External clock in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ############################################ System Configuration ################################################ */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE 3300UL /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((1UL<<__NVIC_PRIO_BITS) - 1UL) /*!< tick interrupt priority (lowest by default) */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 0U /*!< Enable prefetch */ + +/* ############################################ Assert Selection #################################################### */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ############################################ Register callback feature configuration ############################# */ +/** + * @brief Set below the peripheral configuration to "1U" to add the support + * of HAL callback registration/unregistration feature for the HAL + * driver(s). This allows user application to provide specific callback + * functions thanks to HAL_PPP_RegisterCallback() rather than overwriting + * the default weak callback functions (see each stm32h5xx_hal_ppp.h file + * for possible callback identifiers defined in HAL_PPP_CallbackIDTypeDef + * for each PPP peripheral). + */ +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_COMP_REGISTER_CALLBACKS 0U /* COMP register callback disabled */ +#define USE_HAL_CORDIC_REGISTER_CALLBACKS 0U /* CORDIC register callback disabled */ +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ +#define USE_HAL_DTS_REGISTER_CALLBACKS 0U /* DTS register callback disabled */ +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ +#define USE_HAL_FDCAN_REGISTER_CALLBACKS 0U /* FDCAN register callback disabled */ +#define USE_HAL_FMAC_REGISTER_CALLBACKS 0U /* FMAC register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_I3C_REGISTER_CALLBACKS 0U /* I3C register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_IWDG_REGISTER_CALLBACKS 0U /* IWDG register callback disabled */ +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ +#define USE_HAL_OPAMP_REGISTER_CALLBACKS 0U /* OTFDEC register callback disabled */ +#define USE_HAL_OTFDEC_REGISTER_CALLBACKS 0U /* OPAMP register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_PKA_REGISTER_CALLBACKS 0U /* PKA register callback disabled */ +#define USE_HAL_RAMCFG_REGISTER_CALLBACKS 0U /* RAMCFG register callback disabled */ +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ +#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ +#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ +#define USE_HAL_XSPI_REGISTER_CALLBACKS 0U /* XSPI register callback disabled */ + +/* ############################################ SPI peripheral configuration ######################################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver + * Activated: CRC code is present inside driver + * Deactivated: CRC code cleaned from driver + */ +#define USE_SPI_CRC 1U + + +/* Includes ----------------------------------------------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED +#include "stm32h5xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED +#include "stm32h5xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_ICACHE_MODULE_ENABLED +#include "stm32h5xx_hal_icache.h" +#endif /* HAL_ICACHE_MODULE_ENABLED */ + +#ifdef HAL_DCACHE_MODULE_ENABLED +#include "stm32h5xx_hal_dcache.h" +#endif /* HAL_DCACHE_MODULE_ENABLED */ + +#ifdef HAL_GTZC_MODULE_ENABLED +#include "stm32h5xx_hal_gtzc.h" +#endif /* HAL_GTZC_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED +#include "stm32h5xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_DTS_MODULE_ENABLED +#include "stm32h5xx_hal_dts.h" +#endif /* HAL_DTS_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED +#include "stm32h5xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_PKA_MODULE_ENABLED +#include "stm32h5xx_hal_pka.h" +#endif /* HAL_PKA_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED +#include "stm32h5xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED +#include "stm32h5xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED +#include "stm32h5xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED +#include "stm32h5xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED +#include "stm32h5xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED +#include "stm32h5xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED +#include "stm32h5xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED +#include "stm32h5xx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_MMC_MODULE_ENABLED +#include "stm32h5xx_hal_mmc.h" +#endif /* HAL_MMC_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED +#include "stm32h5xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED +#include "stm32h5xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED +#include "stm32h5xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED +#include "stm32h5xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_I3C_MODULE_ENABLED +#include "stm32h5xx_hal_i3c.h" +#endif /* HAL_I3C_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED +#include "stm32h5xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED +#include "stm32h5xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED +#include "stm32h5xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_XSPI_MODULE_ENABLED +#include "stm32h5xx_hal_xspi.h" +#endif /* HAL_XSPI_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED +#include "stm32h5xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED +#include "stm32h5xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED +#include "stm32h5xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED +#include "stm32h5xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED +#include "stm32h5xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED +#include "stm32h5xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED +#include "stm32h5xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED +#include "stm32h5xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED +#include "stm32h5xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED +#include "stm32h5xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED +#include "stm32h5xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED +#include "stm32h5xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED +#include "stm32h5xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED +#include "stm32h5xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED +#include "stm32h5xx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CORDIC_MODULE_ENABLED +#include "stm32h5xx_hal_cordic.h" +#endif /* HAL_CORDIC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED +#include "stm32h5xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED +#include "stm32h5xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED +#include "stm32h5xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_FDCAN_MODULE_ENABLED +#include "stm32h5xx_hal_fdcan.h" +#endif /* HAL_FDCAN_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED +#include "stm32h5xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_FMAC_MODULE_ENABLED +#include "stm32h5xx_hal_fmac.h" +#endif /* HAL_FMAC_MODULE_ENABLED */ + +#ifdef HAL_OPAMP_MODULE_ENABLED +#include "stm32h5xx_hal_opamp.h" +#endif /* HAL_OPAMP_MODULE_ENABLED */ + +#ifdef HAL_OTFDEC_MODULE_ENABLED +#include "stm32h5xx_hal_otfdec.h" +#endif /* HAL_OTFDEC_MODULE_ENABLED */ + +#ifdef HAL_PSSI_MODULE_ENABLED +#include "stm32h5xx_hal_pssi.h" +#endif /* HAL_PSSI_MODULE_ENABLED */ + +#ifdef HAL_RAMCFG_MODULE_ENABLED +#include "stm32h5xx_hal_ramcfg.h" +#endif /* HAL_RAMCFG_MODULE_ENABLED */ + +/* Exported macro ----------------------------------------------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ +#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ----------------------------------------------------------------------------------------------- */ +void assert_failed(uint8_t *file, uint32_t line); +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_CONF_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_cordic.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_cordic.h new file mode 100644 index 0000000000..652621d6b9 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_cordic.h @@ -0,0 +1,609 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_cordic.h + * @author MCD Application Team + * @brief This file contains all the functions prototypes for the CORDIC firmware + * library. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_CORDIC_H +#define STM32H5xx_HAL_CORDIC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +#if defined(CORDIC) +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup CORDIC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup CORDIC_Exported_Types CORDIC Exported Types + * @{ + */ + +/** + * @brief CORDIC HAL State Structure definition + */ +typedef enum +{ + HAL_CORDIC_STATE_RESET = 0x00U, /*!< CORDIC not yet initialized or disabled */ + HAL_CORDIC_STATE_READY = 0x01U, /*!< CORDIC initialized and ready for use */ + HAL_CORDIC_STATE_BUSY = 0x02U, /*!< CORDIC internal process is ongoing */ + HAL_CORDIC_STATE_ERROR = 0x03U /*!< CORDIC error state */ +} HAL_CORDIC_StateTypeDef; + +/** + * @brief CORDIC Handle Structure definition + */ +#if USE_HAL_CORDIC_REGISTER_CALLBACKS == 1 +typedef struct __CORDIC_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_CORDIC_REGISTER_CALLBACKS */ +{ + CORDIC_TypeDef *Instance; /*!< Register base address */ + + const int32_t *pInBuff; /*!< Pointer to CORDIC input data buffer */ + + int32_t *pOutBuff; /*!< Pointer to CORDIC output data buffer */ + + uint32_t NbCalcToOrder; /*!< Remaining number of calculation to order */ + + uint32_t NbCalcToGet; /*!< Remaining number of calculation result to get */ + + uint32_t DMADirection; /*!< Direction of CORDIC DMA transfers */ + + DMA_HandleTypeDef *hdmaIn; /*!< CORDIC peripheral input data DMA handle parameters */ + + DMA_HandleTypeDef *hdmaOut; /*!< CORDIC peripheral output data DMA handle parameters */ + + HAL_LockTypeDef Lock; /*!< CORDIC locking object */ + + __IO HAL_CORDIC_StateTypeDef State; /*!< CORDIC state */ + + __IO uint32_t ErrorCode; /*!< CORDIC peripheral error code + This parameter can be a value of @ref CORDIC_Error_Code */ + +#if USE_HAL_CORDIC_REGISTER_CALLBACKS == 1 + void (* ErrorCallback)(struct __CORDIC_HandleTypeDef *hcordic); /*!< CORDIC error callback */ + void (* CalculateCpltCallback)(struct __CORDIC_HandleTypeDef *hcordic); /*!< CORDIC calculate complete callback */ + + void (* MspInitCallback)(struct __CORDIC_HandleTypeDef *hcordic); /*!< CORDIC Msp Init callback */ + void (* MspDeInitCallback)(struct __CORDIC_HandleTypeDef *hcordic); /*!< CORDIC Msp DeInit callback */ + +#endif /* (USE_HAL_CORDIC_REGISTER_CALLBACKS) */ + +} CORDIC_HandleTypeDef; + +/** + * @brief CORDIC Config Structure definition + */ +typedef struct +{ + uint32_t Function; /*!< Function + This parameter can be a value of @ref CORDIC_Function */ + + uint32_t Scale; /*!< Scaling factor + This parameter can be a value of @ref CORDIC_Scale */ + + uint32_t InSize; /*!< Width of input data + This parameter can be a value of @ref CORDIC_In_Size */ + + uint32_t OutSize; /*!< Width of output data + This parameter can be a value of @ref CORDIC_Out_Size */ + + uint32_t NbWrite; /*!< Number of 32-bit write expected for one calculation + This parameter can be a value of @ref CORDIC_Nb_Write */ + + uint32_t NbRead; /*!< Number of 32-bit read expected after one calculation + This parameter can be a value of @ref CORDIC_Nb_Read */ + + uint32_t Precision; /*!< Number of cycles for calculation + This parameter can be a value of @ref CORDIC_Precision_In_Cycles_Number */ + +} CORDIC_ConfigTypeDef; + +#if USE_HAL_CORDIC_REGISTER_CALLBACKS == 1 +/** + * @brief HAL CORDIC Callback ID enumeration definition + */ +typedef enum +{ + HAL_CORDIC_ERROR_CB_ID = 0x00U, /*!< CORDIC error callback ID */ + HAL_CORDIC_CALCULATE_CPLT_CB_ID = 0x01U, /*!< CORDIC calculate complete callback ID */ + + HAL_CORDIC_MSPINIT_CB_ID = 0x02U, /*!< CORDIC MspInit callback ID */ + HAL_CORDIC_MSPDEINIT_CB_ID = 0x03U, /*!< CORDIC MspDeInit callback ID */ + +} HAL_CORDIC_CallbackIDTypeDef; + +/** + * @brief HAL CORDIC Callback pointer definition + */ +typedef void (*pCORDIC_CallbackTypeDef)(CORDIC_HandleTypeDef *hcordic); /*!< pointer to a CORDIC callback function */ + +#endif /* USE_HAL_CORDIC_REGISTER_CALLBACKS */ + +/** + * @} + */ + + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup CORDIC_Exported_Constants CORDIC Exported Constants + * @{ + */ + +/** @defgroup CORDIC_Error_Code CORDIC Error code + * @{ + */ +#define HAL_CORDIC_ERROR_NONE ((uint32_t)0x00000000U) /*!< No error */ +#define HAL_CORDIC_ERROR_PARAM ((uint32_t)0x00000001U) /*!< Wrong parameter error */ +#define HAL_CORDIC_ERROR_NOT_READY ((uint32_t)0x00000002U) /*!< Peripheral not ready */ +#define HAL_CORDIC_ERROR_TIMEOUT ((uint32_t)0x00000004U) /*!< Timeout error */ +#define HAL_CORDIC_ERROR_DMA ((uint32_t)0x00000008U) /*!< DMA error */ +#if USE_HAL_CORDIC_REGISTER_CALLBACKS == 1 +#define HAL_CORDIC_ERROR_INVALID_CALLBACK ((uint32_t)0x00000010U) /*!< Invalid Callback error */ +#endif /* USE_HAL_CORDIC_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @defgroup CORDIC_Function CORDIC Function + * @{ + */ +#define CORDIC_FUNCTION_COSINE (0x00000000U) /*!< Cosine */ +#define CORDIC_FUNCTION_SINE ((uint32_t)(CORDIC_CSR_FUNC_0)) /*!< Sine */ +#define CORDIC_FUNCTION_PHASE ((uint32_t)(CORDIC_CSR_FUNC_1)) /*!< Phase */ +#define CORDIC_FUNCTION_MODULUS ((uint32_t)(CORDIC_CSR_FUNC_1 | CORDIC_CSR_FUNC_0)) /*!< Modulus */ +#define CORDIC_FUNCTION_ARCTANGENT ((uint32_t)(CORDIC_CSR_FUNC_2)) /*!< Arctangent */ +#define CORDIC_FUNCTION_HCOSINE ((uint32_t)(CORDIC_CSR_FUNC_2 | CORDIC_CSR_FUNC_0)) /*!< Hyperbolic Cosine */ +#define CORDIC_FUNCTION_HSINE ((uint32_t)(CORDIC_CSR_FUNC_2 | CORDIC_CSR_FUNC_1)) /*!< Hyperbolic Sine */ +#define CORDIC_FUNCTION_HARCTANGENT ((uint32_t)(CORDIC_CSR_FUNC_2 | CORDIC_CSR_FUNC_1 | CORDIC_CSR_FUNC_0))/*!< Hyperbolic Arctangent */ +#define CORDIC_FUNCTION_NATURALLOG ((uint32_t)(CORDIC_CSR_FUNC_3)) /*!< Natural Logarithm */ +#define CORDIC_FUNCTION_SQUAREROOT ((uint32_t)(CORDIC_CSR_FUNC_3 | CORDIC_CSR_FUNC_0)) /*!< Square Root */ +/** + * @} + */ + +/** @defgroup CORDIC_Precision_In_Cycles_Number CORDIC Precision in Cycles Number + * @{ + */ +/* Note: 1 cycle corresponds to 4 algorithm iterations */ +#define CORDIC_PRECISION_1CYCLE ((uint32_t)(CORDIC_CSR_PRECISION_0)) +#define CORDIC_PRECISION_2CYCLES ((uint32_t)(CORDIC_CSR_PRECISION_1)) +#define CORDIC_PRECISION_3CYCLES ((uint32_t)(CORDIC_CSR_PRECISION_1 | CORDIC_CSR_PRECISION_0)) +#define CORDIC_PRECISION_4CYCLES ((uint32_t)(CORDIC_CSR_PRECISION_2)) +#define CORDIC_PRECISION_5CYCLES ((uint32_t)(CORDIC_CSR_PRECISION_2 | CORDIC_CSR_PRECISION_0)) +#define CORDIC_PRECISION_6CYCLES ((uint32_t)(CORDIC_CSR_PRECISION_2 | CORDIC_CSR_PRECISION_1)) +#define CORDIC_PRECISION_7CYCLES ((uint32_t)(CORDIC_CSR_PRECISION_2\ + | CORDIC_CSR_PRECISION_1 | CORDIC_CSR_PRECISION_0)) +#define CORDIC_PRECISION_8CYCLES ((uint32_t)(CORDIC_CSR_PRECISION_3)) +#define CORDIC_PRECISION_9CYCLES ((uint32_t)(CORDIC_CSR_PRECISION_3 | CORDIC_CSR_PRECISION_0)) +#define CORDIC_PRECISION_10CYCLES ((uint32_t)(CORDIC_CSR_PRECISION_3 | CORDIC_CSR_PRECISION_1)) +#define CORDIC_PRECISION_11CYCLES ((uint32_t)(CORDIC_CSR_PRECISION_3\ + | CORDIC_CSR_PRECISION_1 | CORDIC_CSR_PRECISION_0)) +#define CORDIC_PRECISION_12CYCLES ((uint32_t)(CORDIC_CSR_PRECISION_3 | CORDIC_CSR_PRECISION_2)) +#define CORDIC_PRECISION_13CYCLES ((uint32_t)(CORDIC_CSR_PRECISION_3\ + | CORDIC_CSR_PRECISION_2 | CORDIC_CSR_PRECISION_0)) +#define CORDIC_PRECISION_14CYCLES ((uint32_t)(CORDIC_CSR_PRECISION_3\ + | CORDIC_CSR_PRECISION_2 | CORDIC_CSR_PRECISION_1)) +#define CORDIC_PRECISION_15CYCLES ((uint32_t)(CORDIC_CSR_PRECISION_3\ + | CORDIC_CSR_PRECISION_2 | CORDIC_CSR_PRECISION_1\ + |CORDIC_CSR_PRECISION_0)) +/** + * @} + */ + +/** @defgroup CORDIC_Scale CORDIC Scaling factor + * @{ + */ +/* Scale factor value 'n' implies that the input data have been multiplied + by a factor 2exp(-n), and/or the output data need to be multiplied by 2exp(n). */ +#define CORDIC_SCALE_0 (0x00000000U) +#define CORDIC_SCALE_1 ((uint32_t)(CORDIC_CSR_SCALE_0)) +#define CORDIC_SCALE_2 ((uint32_t)(CORDIC_CSR_SCALE_1)) +#define CORDIC_SCALE_3 ((uint32_t)(CORDIC_CSR_SCALE_1 | CORDIC_CSR_SCALE_0)) +#define CORDIC_SCALE_4 ((uint32_t)(CORDIC_CSR_SCALE_2)) +#define CORDIC_SCALE_5 ((uint32_t)(CORDIC_CSR_SCALE_2 | CORDIC_CSR_SCALE_0)) +#define CORDIC_SCALE_6 ((uint32_t)(CORDIC_CSR_SCALE_2 | CORDIC_CSR_SCALE_1)) +#define CORDIC_SCALE_7 ((uint32_t)(CORDIC_CSR_SCALE_2 | CORDIC_CSR_SCALE_1 | CORDIC_CSR_SCALE_0)) +/** + * @} + */ + +/** @defgroup CORDIC_Interrupts_Enable CORDIC Interrupts Enable bit + * @{ + */ +#define CORDIC_IT_IEN CORDIC_CSR_IEN /*!< Result ready interrupt enable */ +/** + * @} + */ + +/** @defgroup CORDIC_DMAR DMA Read Request Enable bit + * @{ + */ +#define CORDIC_DMA_REN CORDIC_CSR_DMAREN /*!< DMA Read requests enable */ +/** + * @} + */ + +/** @defgroup CORDIC_DMAW DMA Write Request Enable bit + * @{ + */ +#define CORDIC_DMA_WEN CORDIC_CSR_DMAWEN /*!< DMA Write channel enable */ +/** + * @} + */ + +/** @defgroup CORDIC_Nb_Write CORDIC Number of 32-bit write required for one calculation + * @{ + */ +#define CORDIC_NBWRITE_1 (0x00000000U) /*!< One 32-bits write containing either only one + 32-bit data input (Q1.31 format), or two 16-bit + data input (Q1.15 format) packed in one 32 bits + Data */ +#define CORDIC_NBWRITE_2 CORDIC_CSR_NARGS /*!< Two 32-bit write containing two 32-bits data input + (Q1.31 format) */ +/** + * @} + */ + +/** @defgroup CORDIC_Nb_Read CORDIC Number of 32-bit read required after one calculation + * @{ + */ +#define CORDIC_NBREAD_1 (0x00000000U) /*!< One 32-bits read containing either only one + 32-bit data output (Q1.31 format), or two 16-bit + data output (Q1.15 format) packed in one 32 bits + Data */ +#define CORDIC_NBREAD_2 CORDIC_CSR_NRES /*!< Two 32-bit Data containing two 32-bits data output + (Q1.31 format) */ +/** + * @} + */ + +/** @defgroup CORDIC_In_Size CORDIC input data size + * @{ + */ +#define CORDIC_INSIZE_32BITS (0x00000000U) /*!< 32 bits input data size (Q1.31 format) */ +#define CORDIC_INSIZE_16BITS CORDIC_CSR_ARGSIZE /*!< 16 bits input data size (Q1.15 format) */ +/** + * @} + */ + +/** @defgroup CORDIC_Out_Size CORDIC Results Size + * @{ + */ +#define CORDIC_OUTSIZE_32BITS (0x00000000U) /*!< 32 bits output data size (Q1.31 format) */ +#define CORDIC_OUTSIZE_16BITS CORDIC_CSR_RESSIZE /*!< 16 bits output data size (Q1.15 format) */ +/** + * @} + */ + +/** @defgroup CORDIC_Flags CORDIC status flags + * @{ + */ +#define CORDIC_FLAG_RRDY CORDIC_CSR_RRDY /*!< Result Ready Flag */ +/** + * @} + */ + +/** @defgroup CORDIC_DMA_Direction CORDIC DMA direction + * @{ + */ +#define CORDIC_DMA_DIR_NONE ((uint32_t)0x00000000U) /*!< DMA direction : none */ +#define CORDIC_DMA_DIR_IN ((uint32_t)0x00000001U) /*!< DMA direction : Input of CORDIC */ +#define CORDIC_DMA_DIR_OUT ((uint32_t)0x00000002U) /*!< DMA direction : Output of CORDIC */ +#define CORDIC_DMA_DIR_IN_OUT ((uint32_t)0x00000003U) /*!< DMA direction : Input and Output of CORDIC */ +/** + * @} + */ + +/** + * @} + */ + + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup CORDIC_Exported_Macros CORDIC Exported Macros + * @{ + */ + +/** @brief Reset CORDIC handle state. + * @param __HANDLE__ CORDIC handle + * @retval None + */ +#if USE_HAL_CORDIC_REGISTER_CALLBACKS == 1 +#define __HAL_CORDIC_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->State = HAL_CORDIC_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_CORDIC_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_CORDIC_STATE_RESET) +#endif /*USE_HAL_CORDIC_REGISTER_CALLBACKS */ + +/** + * @brief Enable the CORDIC interrupt when result is ready + * @param __HANDLE__ CORDIC handle. + * @param __INTERRUPT__ CORDIC Interrupt. + * This parameter can be one of the following values: + * @arg @ref CORDIC_IT_IEN Enable Interrupt + * @retval None + */ +#define __HAL_CORDIC_ENABLE_IT(__HANDLE__, __INTERRUPT__) \ + (((__HANDLE__)->Instance->CSR) |= (__INTERRUPT__)) + +/** + * @brief Disable the CORDIC interrupt + * @param __HANDLE__ CORDIC handle. + * @param __INTERRUPT__ CORDIC Interrupt. + * This parameter can be one of the following values: + * @arg @ref CORDIC_IT_IEN Enable Interrupt + * @retval None + */ +#define __HAL_CORDIC_DISABLE_IT(__HANDLE__, __INTERRUPT__) \ + (((__HANDLE__)->Instance->CSR) &= ~(__INTERRUPT__)) + +/** @brief Check whether the specified CORDIC interrupt occurred or not. + Dummy macro as no interrupt status flag. + * @param __HANDLE__ CORDIC handle. + * @param __INTERRUPT__ CORDIC interrupt to check + * @retval SET (interrupt occurred) or RESET (interrupt did not occurred) + */ +#define __HAL_CORDIC_GET_IT(__HANDLE__, __INTERRUPT__) /* Dummy macro */ + +/** @brief Clear specified CORDIC interrupt status. Dummy macro as no + interrupt status flag. + * @param __HANDLE__ CORDIC handle. + * @param __INTERRUPT__ CORDIC interrupt to clear + * @retval None + */ +#define __HAL_CORDIC_CLEAR_IT(__HANDLE__, __INTERRUPT__) /* Dummy macro */ + +/** @brief Check whether the specified CORDIC status flag is set or not. + * @param __HANDLE__ CORDIC handle. + * @param __FLAG__ CORDIC flag to check + * This parameter can be one of the following values: + * @arg @ref CORDIC_FLAG_RRDY Result Ready Flag + * @retval SET (flag is set) or RESET (flag is reset) + */ +#define __HAL_CORDIC_GET_FLAG(__HANDLE__, __FLAG__) \ + ((((__HANDLE__)->Instance->CSR) & (__FLAG__)) == (__FLAG__)) + +/** @brief Clear specified CORDIC status flag. Dummy macro as no + flag can be cleared. + * @param __HANDLE__ CORDIC handle. + * @param __FLAG__ CORDIC flag to clear + * This parameter can be one of the following values: + * @arg @ref CORDIC_FLAG_RRDY Result Ready Flag + * @retval None + */ +#define __HAL_CORDIC_CLEAR_FLAG(__HANDLE__, __FLAG__) /* Dummy macro */ + +/** @brief Check whether the specified CORDIC interrupt is enabled or not. + * @param __HANDLE__ CORDIC handle. + * @param __INTERRUPT__ CORDIC interrupt to check + * This parameter can be one of the following values: + * @arg @ref CORDIC_IT_IEN Enable Interrupt + * @retval FlagStatus + */ +#define __HAL_CORDIC_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) \ + (((__HANDLE__)->Instance->CSR) & (__INTERRUPT__)) + +/** + * @} + */ + +/* Private macros --------------------------------------------------------*/ +/** @defgroup CORDIC_Private_Macros CORDIC Private Macros + * @{ + */ + +/** + * @brief Verify the CORDIC function. + * @param __FUNCTION__ Name of the function. + * @retval SET (__FUNCTION__ is a valid value) or RESET (__FUNCTION__ is invalid) + */ +#define IS_CORDIC_FUNCTION(__FUNCTION__) (((__FUNCTION__) == CORDIC_FUNCTION_COSINE) || \ + ((__FUNCTION__) == CORDIC_FUNCTION_SINE) || \ + ((__FUNCTION__) == CORDIC_FUNCTION_PHASE) || \ + ((__FUNCTION__) == CORDIC_FUNCTION_MODULUS) || \ + ((__FUNCTION__) == CORDIC_FUNCTION_ARCTANGENT) || \ + ((__FUNCTION__) == CORDIC_FUNCTION_HCOSINE) || \ + ((__FUNCTION__) == CORDIC_FUNCTION_HSINE) || \ + ((__FUNCTION__) == CORDIC_FUNCTION_HARCTANGENT) || \ + ((__FUNCTION__) == CORDIC_FUNCTION_NATURALLOG) || \ + ((__FUNCTION__) == CORDIC_FUNCTION_SQUAREROOT)) + + +/** + * @brief Verify the CORDIC precision. + * @param __PRECISION__ CORDIC Precision in Cycles Number. + * @retval SET (__PRECISION__ is a valid value) or RESET (__PRECISION__ is invalid) + */ +#define IS_CORDIC_PRECISION(__PRECISION__) (((__PRECISION__) == CORDIC_PRECISION_1CYCLE) || \ + ((__PRECISION__) == CORDIC_PRECISION_2CYCLES) || \ + ((__PRECISION__) == CORDIC_PRECISION_3CYCLES) || \ + ((__PRECISION__) == CORDIC_PRECISION_4CYCLES) || \ + ((__PRECISION__) == CORDIC_PRECISION_5CYCLES) || \ + ((__PRECISION__) == CORDIC_PRECISION_6CYCLES) || \ + ((__PRECISION__) == CORDIC_PRECISION_7CYCLES) || \ + ((__PRECISION__) == CORDIC_PRECISION_8CYCLES) || \ + ((__PRECISION__) == CORDIC_PRECISION_9CYCLES) || \ + ((__PRECISION__) == CORDIC_PRECISION_10CYCLES) || \ + ((__PRECISION__) == CORDIC_PRECISION_11CYCLES) || \ + ((__PRECISION__) == CORDIC_PRECISION_12CYCLES) || \ + ((__PRECISION__) == CORDIC_PRECISION_13CYCLES) || \ + ((__PRECISION__) == CORDIC_PRECISION_14CYCLES) || \ + ((__PRECISION__) == CORDIC_PRECISION_15CYCLES)) + +/** + * @brief Verify the CORDIC scaling factor. + * @param __SCALE__ Number of cycles for calculation, 1 cycle corresponding to 4 algorithm iterations. + * @retval SET (__SCALE__ is a valid value) or RESET (__SCALE__ is invalid) + */ +#define IS_CORDIC_SCALE(__SCALE__) (((__SCALE__) == CORDIC_SCALE_0) || \ + ((__SCALE__) == CORDIC_SCALE_1) || \ + ((__SCALE__) == CORDIC_SCALE_2) || \ + ((__SCALE__) == CORDIC_SCALE_3) || \ + ((__SCALE__) == CORDIC_SCALE_4) || \ + ((__SCALE__) == CORDIC_SCALE_5) || \ + ((__SCALE__) == CORDIC_SCALE_6) || \ + ((__SCALE__) == CORDIC_SCALE_7)) + +/** + * @brief Verify the CORDIC number of 32-bits write expected for one calculation. + * @param __NBWRITE__ Number of 32-bits write expected for one calculation. + * @retval SET (__NBWRITE__ is a valid value) or RESET (__NBWRITE__ is invalid) + */ +#define IS_CORDIC_NBWRITE(__NBWRITE__) (((__NBWRITE__) == CORDIC_NBWRITE_1) || \ + ((__NBWRITE__) == CORDIC_NBWRITE_2)) + +/** + * @brief Verify the CORDIC number of 32-bits read expected after one calculation. + * @param __NBREAD__ Number of 32-bits read expected after one calculation. + * @retval SET (__NBREAD__ is a valid value) or RESET (__NBREAD__ is invalid) + */ +#define IS_CORDIC_NBREAD(__NBREAD__) (((__NBREAD__) == CORDIC_NBREAD_1) || \ + ((__NBREAD__) == CORDIC_NBREAD_2)) + +/** + * @brief Verify the CORDIC input data size for one calculation. + * @param __INSIZE__ input data size for one calculation. + * @retval SET (__INSIZE__ is a valid value) or RESET (__INSIZE__ is invalid) + */ +#define IS_CORDIC_INSIZE(__INSIZE__) (((__INSIZE__) == CORDIC_INSIZE_32BITS) || \ + ((__INSIZE__) == CORDIC_INSIZE_16BITS)) + +/** + * @brief Verify the CORDIC output data size for one calculation. + * @param __OUTSIZE__ output data size for one calculation. + * @retval SET (__OUTSIZE__ is a valid value) or RESET (__OUTSIZE__ is invalid) + */ +#define IS_CORDIC_OUTSIZE(__OUTSIZE__) (((__OUTSIZE__) == CORDIC_OUTSIZE_32BITS) || \ + ((__OUTSIZE__) == CORDIC_OUTSIZE_16BITS)) + +/** + * @brief Verify the CORDIC DMA transfer Direction. + * @param __DMADIR__ DMA transfer direction. + * @retval SET (__DMADIR__ is a valid value) or RESET (__DMADIR__ is invalid) + */ +#define IS_CORDIC_DMA_DIRECTION(__DMADIR__) (((__DMADIR__) == CORDIC_DMA_DIR_IN) || \ + ((__DMADIR__) == CORDIC_DMA_DIR_OUT) || \ + ((__DMADIR__) == CORDIC_DMA_DIR_IN_OUT)) + +/** + * @} + */ + +/** @addtogroup CORDIC_Exported_Functions + * @{ + */ +/* Exported functions ------------------------------------------------------- */ + +/** @addtogroup CORDIC_Exported_Functions_Group1 + * @{ + */ +/* Initialization and de-initialization functions ******************************/ +HAL_StatusTypeDef HAL_CORDIC_Init(CORDIC_HandleTypeDef *hcordic); +HAL_StatusTypeDef HAL_CORDIC_DeInit(CORDIC_HandleTypeDef *hcordic); +void HAL_CORDIC_MspInit(CORDIC_HandleTypeDef *hcordic); +void HAL_CORDIC_MspDeInit(CORDIC_HandleTypeDef *hcordic); + +#if USE_HAL_CORDIC_REGISTER_CALLBACKS == 1 +/* Callbacks Register/UnRegister functions ***********************************/ +HAL_StatusTypeDef HAL_CORDIC_RegisterCallback(CORDIC_HandleTypeDef *hcordic, HAL_CORDIC_CallbackIDTypeDef CallbackID, + pCORDIC_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_CORDIC_UnRegisterCallback(CORDIC_HandleTypeDef *hcordic, HAL_CORDIC_CallbackIDTypeDef CallbackID); +/** + * @} + */ + +/** @addtogroup CORDIC_Exported_Functions_Group2 + * @{ + */ +#endif /* USE_HAL_CORDIC_REGISTER_CALLBACKS */ +/* Peripheral Control functions ***********************************************/ +HAL_StatusTypeDef HAL_CORDIC_Configure(CORDIC_HandleTypeDef *hcordic, const CORDIC_ConfigTypeDef *sConfig); +HAL_StatusTypeDef HAL_CORDIC_Calculate(CORDIC_HandleTypeDef *hcordic, const int32_t *pInBuff, int32_t *pOutBuff, + uint32_t NbCalc, uint32_t Timeout); +HAL_StatusTypeDef HAL_CORDIC_CalculateZO(CORDIC_HandleTypeDef *hcordic, const int32_t *pInBuff, int32_t *pOutBuff, + uint32_t NbCalc, uint32_t Timeout); +HAL_StatusTypeDef HAL_CORDIC_Calculate_IT(CORDIC_HandleTypeDef *hcordic, const int32_t *pInBuff, int32_t *pOutBuff, + uint32_t NbCalc); +HAL_StatusTypeDef HAL_CORDIC_Calculate_DMA(CORDIC_HandleTypeDef *hcordic, const int32_t *pInBuff, int32_t *pOutBuff, + uint32_t NbCalc, uint32_t DMADirection); +/** + * @} + */ + +/** @addtogroup CORDIC_Exported_Functions_Group3 + * @{ + */ +/* Callback functions *********************************************************/ +void HAL_CORDIC_ErrorCallback(CORDIC_HandleTypeDef *hcordic); +void HAL_CORDIC_CalculateCpltCallback(CORDIC_HandleTypeDef *hcordic); +/** + * @} + */ + +/** @addtogroup CORDIC_Exported_Functions_Group4 + * @{ + */ +/* IRQ handler management *****************************************************/ +void HAL_CORDIC_IRQHandler(CORDIC_HandleTypeDef *hcordic); +/** + * @} + */ + +/** @addtogroup CORDIC_Exported_Functions_Group5 + * @{ + */ +/* Peripheral State functions *************************************************/ +HAL_CORDIC_StateTypeDef HAL_CORDIC_GetState(const CORDIC_HandleTypeDef *hcordic); +uint32_t HAL_CORDIC_GetError(const CORDIC_HandleTypeDef *hcordic); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* CORDIC */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_CORDIC_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_cortex.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_cortex.h new file mode 100644 index 0000000000..046104f396 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_cortex.h @@ -0,0 +1,411 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_cortex.h + * @author MCD Application Team + * @brief Header file of CORTEX HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32H5xx_HAL_CORTEX_H +#define __STM32H5xx_HAL_CORTEX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup CORTEX CORTEX + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup CORTEX_Exported_Types CORTEX Exported Types + * @{ + */ + +/** @defgroup CORTEX_MPU_Region_Initialization_Structure_definition MPU Region Initialization Structure Definition + * @{ + */ +typedef struct +{ + uint8_t Enable; /*!< Specifies the status of the region. + This parameter can be a value of @ref CORTEX_MPU_Region_Enable */ + uint8_t Number; /*!< Specifies the index of the region to protect. + This parameter can be a value of @ref CORTEX_MPU_Region_Number */ + uint32_t BaseAddress; /*!< Specifies the base address of the region to protect. */ + uint32_t LimitAddress; /*!< Specifies the limit address of the region to protect. */ + uint8_t AttributesIndex; /*!< Specifies the memory attributes index. + This parameter can be a value of @ref CORTEX_MPU_Attributes_Number */ + uint8_t AccessPermission; /*!< Specifies the region access permission type. This parameter + can be a value of @ref CORTEX_MPU_Region_Permission_Attributes */ + uint8_t DisableExec; /*!< Specifies the instruction access status. + This parameter can be a value of @ref CORTEX_MPU_Instruction_Access */ + uint8_t IsShareable; /*!< Specifies the shareability status of the protected region. + This parameter can be a value of @ref CORTEX_MPU_Access_Shareable */ +} MPU_Region_InitTypeDef; +/** + * @} + */ + +/** @defgroup CORTEX_MPU_Attributes_Initialization_Structure_definition MPU Attributes + * Initialization Structure Definition + * @{ + */ +typedef struct +{ + uint8_t Number; /*!< Specifies the number of the memory attributes to configure. + This parameter can be a value of @ref CORTEX_MPU_Attributes_Number */ + + uint8_t Attributes; /*!< Specifies the memory attributes value. Attributes This parameter + can be a combination of @ref CORTEX_MPU_Attributes */ + +} MPU_Attributes_InitTypeDef; +/** + * @} + */ + + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup CORTEX_Exported_Constants CORTEX Exported Constants + * @{ + */ + +/** @defgroup CORTEX_Preemption_Priority_Group CORTEX Preemption Priority Group + * @{ + */ +#define NVIC_PRIORITYGROUP_0 0x7U /*!< 0 bit for pre-emption priority, + 4 bits for subpriority */ +#define NVIC_PRIORITYGROUP_1 0x6U /*!< 1 bit for pre-emption priority, + 3 bits for subpriority */ +#define NVIC_PRIORITYGROUP_2 0x5U /*!< 2 bits for pre-emption priority, + 2 bits for subpriority */ +#define NVIC_PRIORITYGROUP_3 0x4U /*!< 3 bits for pre-emption priority, + 1 bit for subpriority */ +#define NVIC_PRIORITYGROUP_4 0x3U /*!< 4 bits for pre-emption priority, + 0 bit for subpriority */ +/** + * @} + */ + +/** @defgroup CORTEX_SysTick_clock_source CORTEX SysTick clock source + * @{ + */ +#define SYSTICK_CLKSOURCE_HCLK_DIV8 0x0U /*!< AHB clock divided by 8 selected as SysTick clock source */ +#define SYSTICK_CLKSOURCE_LSI 0x1U /*!< LSI clock selected as SysTick clock source */ +#define SYSTICK_CLKSOURCE_LSE 0x2U /*!< LSE clock selected as SysTick clock source */ +#define SYSTICK_CLKSOURCE_HCLK 0x4U /*!< AHB clock selected as SysTick clock source */ +/** + * @} + */ + +/** @defgroup CORTEX_MPU_HFNMI_PRIVDEF_Control CORTEX MPU HFNMI and PRIVILEGED Access control + * @{ + */ +#define MPU_HFNMI_PRIVDEF_NONE 0U /*!< MPU is disabled during HardFault and NMI handlers, + privileged software access to the default memory map is disabled */ +#define MPU_HARDFAULT_NMI 2U /*!< MPU is enabled during HardFault and NMI handlers, + privileged software access to the default memory map is disabled */ +#define MPU_PRIVILEGED_DEFAULT 4U /*!< MPU is disabled during HardFault and NMI handlers, + privileged software access to the default memory map is enabled */ +#define MPU_HFNMI_PRIVDEF 6U /*!< MPU is enabled during HardFault and NMI handlers, + privileged software access to the default memory map is enabled */ +/** + * @} + */ + +/** @defgroup CORTEX_MPU_Region_Enable CORTEX MPU Region Enable + * @{ + */ +#define MPU_REGION_ENABLE 1U /*!< MPU region enabled */ +#define MPU_REGION_DISABLE 0U /*!< MPU region disabled */ +/** + * @} + */ + +/** @defgroup CORTEX_MPU_Instruction_Access CORTEX MPU Instruction Access + * @{ + */ +#define MPU_INSTRUCTION_ACCESS_ENABLE 0U /*!< MPU region execution permitted (if read permitted) */ +#define MPU_INSTRUCTION_ACCESS_DISABLE 1U /*!< MPU region execution not permitted */ +/** + * @} + */ + +/** @defgroup CORTEX_MPU_Access_Shareable CORTEX MPU Instruction Access Shareable + * @{ + */ +#define MPU_ACCESS_NOT_SHAREABLE 0U /*!< MPU region not shareable */ +#define MPU_ACCESS_OUTER_SHAREABLE 1U /*!< MPU region outer shareable */ +#define MPU_ACCESS_INNER_SHAREABLE 3U /*!< MPU region inner shareable */ +/** + * @} + */ + +/** @defgroup CORTEX_MPU_Region_Permission_Attributes CORTEX MPU Region Permission Attributes + * @{ + */ +#define MPU_REGION_PRIV_RW 0U /*!< MPU region Read/write by privileged code only */ +#define MPU_REGION_ALL_RW 1U /*!< MPU region Read/write by any privilege level */ +#define MPU_REGION_PRIV_RO 2U /*!< MPU region Read-only by privileged code only */ +#define MPU_REGION_ALL_RO 3U /*!< MPU region Read-only by any privilege level */ +/** + * @} + */ + +/** @defgroup CORTEX_MPU_Region_Number CORTEX MPU Region Number + * @{ + */ +#define MPU_REGION_NUMBER0 0U /*!< MPU region number 0 */ +#define MPU_REGION_NUMBER1 1U /*!< MPU region number 1 */ +#define MPU_REGION_NUMBER2 2U /*!< MPU region number 2 */ +#define MPU_REGION_NUMBER3 3U /*!< MPU region number 3 */ +#define MPU_REGION_NUMBER4 4U /*!< MPU region number 4 */ +#define MPU_REGION_NUMBER5 5U /*!< MPU region number 5 */ +#define MPU_REGION_NUMBER6 6U /*!< MPU region number 6 */ +#define MPU_REGION_NUMBER7 7U /*!< MPU region number 7 */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define MPU_REGION_NUMBER8 8U /*!< MPU region number 8 */ +#define MPU_REGION_NUMBER9 9U /*!< MPU region number 9 */ +#define MPU_REGION_NUMBER10 10U /*!< MPU region number 10 */ +#define MPU_REGION_NUMBER11 11U /*!< MPU region number 11 */ +#endif /* __ARM_FEATURE_CMSE */ +/** + * @} + */ + +/** @defgroup CORTEX_MPU_Attributes_Number CORTEX MPU Memory Attributes Number + * @{ + */ +#define MPU_ATTRIBUTES_NUMBER0 0U /*!< MPU attribute number 0 */ +#define MPU_ATTRIBUTES_NUMBER1 1U /*!< MPU attribute number 1 */ +#define MPU_ATTRIBUTES_NUMBER2 2U /*!< MPU attribute number 2 */ +#define MPU_ATTRIBUTES_NUMBER3 3U /*!< MPU attribute number 3 */ +#define MPU_ATTRIBUTES_NUMBER4 4U /*!< MPU attribute number 4 */ +#define MPU_ATTRIBUTES_NUMBER5 5U /*!< MPU attribute number 5 */ +#define MPU_ATTRIBUTES_NUMBER6 6U /*!< MPU attribute number 6 */ +#define MPU_ATTRIBUTES_NUMBER7 7U /*!< MPU attribute number 7 */ +/** + * @} + */ + +/** @defgroup CORTEX_MPU_Attributes CORTEX MPU Attributes + * @{ + */ +#define MPU_DEVICE_nGnRnE 0x0U /*!< Device, noGather, noReorder, noEarly acknowledge. */ +#define MPU_DEVICE_nGnRE 0x4U /*!< Device, noGather, noReorder, Early acknowledge. */ +#define MPU_DEVICE_nGRE 0x8U /*!< Device, noGather, Reorder, Early acknowledge. */ +#define MPU_DEVICE_GRE 0xCU /*!< Device, Gather, Reorder, Early acknowledge. */ + +#define MPU_WRITE_THROUGH 0x0U /*!< Normal memory, write-through. */ +#define MPU_NOT_CACHEABLE 0x4U /*!< Normal memory, non-cacheable. */ +#define MPU_WRITE_BACK 0x4U /*!< Normal memory, write-back. */ + +#define MPU_TRANSIENT 0x0U /*!< Normal memory, transient. */ +#define MPU_NON_TRANSIENT 0x8U /*!< Normal memory, non-transient. */ + +#define MPU_NO_ALLOCATE 0x0U /*!< Normal memory, no allocate. */ +#define MPU_W_ALLOCATE 0x1U /*!< Normal memory, write allocate. */ +#define MPU_R_ALLOCATE 0x2U /*!< Normal memory, read allocate. */ +#define MPU_RW_ALLOCATE 0x3U /*!< Normal memory, read/write allocate. */ + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup CORTEX_Exported_Macros CORTEX Exported Macros + * @{ + */ +#define OUTER(__ATTR__) ((__ATTR__) << 4U) +#define INNER_OUTER(__ATTR__) ((__ATTR__) | ((__ATTR__) << 4U)) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup CORTEX_Exported_Functions CORTEX Exported Functions + * @{ + */ + +/** @defgroup CORTEX_Exported_Functions_Group1 NVIC functions + * @brief NVIC functions + * @{ + */ +/* NVIC functions *****************************/ +void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup); +void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority); +void HAL_NVIC_EnableIRQ(IRQn_Type IRQn); +void HAL_NVIC_DisableIRQ(IRQn_Type IRQn); +void HAL_NVIC_SystemReset(void); +uint32_t HAL_NVIC_GetPriorityGrouping(void); +void HAL_NVIC_GetPriority(IRQn_Type IRQn, uint32_t PriorityGroup, uint32_t *const pPreemptPriority, + uint32_t *const pSubPriority); +uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn); +void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn); +void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn); +uint32_t HAL_NVIC_GetActive(IRQn_Type IRQn); +/** + * @} + */ + +/** @defgroup CORTEX_Exported_Functions_Group2 SYSTICK functions + * @brief SYSTICK functions + * @{ + */ +/* SYSTICK functions ***********************************************/ +uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb); +void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource); +void HAL_SYSTICK_IRQHandler(void); +void HAL_SYSTICK_Callback(void); +/** + * @} + */ + +/** @defgroup CORTEX_Exported_Functions_Group3 MPU functions + * @brief MPU functions + * @{ + */ +/* MPU functions ***********************************************/ +void HAL_MPU_Enable(uint32_t MPU_Control); +void HAL_MPU_Disable(void); +void HAL_MPU_ConfigRegion(const MPU_Region_InitTypeDef *const pMPU_RegionInit); +void HAL_MPU_ConfigMemoryAttributes(const MPU_Attributes_InitTypeDef *const pMPU_AttributesInit); +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/* MPU_NS Control functions ***********************************************/ +void HAL_MPU_Enable_NS(uint32_t MPU_Control); +void HAL_MPU_Disable_NS(void); +void HAL_MPU_ConfigRegion_NS(const MPU_Region_InitTypeDef *const pMPU_RegionInit); +void HAL_MPU_ConfigMemoryAttributes_NS(const MPU_Attributes_InitTypeDef *const pMPU_AttributesInit); +#endif /* __ARM_FEATURE_CMSE */ +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup CORTEX_Private_Macros CORTEX Private Macros + * @{ + */ +#define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PRIORITYGROUP_0) || \ + ((GROUP) == NVIC_PRIORITYGROUP_1) || \ + ((GROUP) == NVIC_PRIORITYGROUP_2) || \ + ((GROUP) == NVIC_PRIORITYGROUP_3) || \ + ((GROUP) == NVIC_PRIORITYGROUP_4)) + +#define IS_NVIC_PREEMPTION_PRIORITY(PRIORITY) ((PRIORITY) < (1UL<<__NVIC_PRIO_BITS)) + +#define IS_NVIC_SUB_PRIORITY(PRIORITY) ((PRIORITY) < (1UL<<__NVIC_PRIO_BITS)) + +#define IS_NVIC_DEVICE_IRQ(IRQ) ((IRQ) > SysTick_IRQn) + +#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SYSTICK_CLKSOURCE_LSI) || \ + ((SOURCE) == SYSTICK_CLKSOURCE_LSE) || \ + ((SOURCE) == SYSTICK_CLKSOURCE_HCLK)|| \ + ((SOURCE) == SYSTICK_CLKSOURCE_HCLK_DIV8)) + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define IS_MPU_INSTANCE(INSTANCE) (((INSTANCE) == MPU) || ((INSTANCE) == MPU_NS)) +#endif /* __ARM_FEATURE_CMSE */ + +#define IS_MPU_REGION_ENABLE(STATE) (((STATE) == MPU_REGION_ENABLE) || \ + ((STATE) == MPU_REGION_DISABLE)) + +#define IS_MPU_INSTRUCTION_ACCESS(STATE) (((STATE) == MPU_INSTRUCTION_ACCESS_ENABLE) || \ + ((STATE) == MPU_INSTRUCTION_ACCESS_DISABLE)) + +#define IS_MPU_ACCESS_SHAREABLE(STATE) (((STATE) == MPU_ACCESS_OUTER_SHAREABLE) || \ + ((STATE) == MPU_ACCESS_INNER_SHAREABLE) || \ + ((STATE) == MPU_ACCESS_NOT_SHAREABLE)) + +#define IS_MPU_REGION_PERMISSION_ATTRIBUTE(TYPE) (((TYPE) == MPU_REGION_PRIV_RW) || \ + ((TYPE) == MPU_REGION_ALL_RW) || \ + ((TYPE) == MPU_REGION_PRIV_RO) || \ + ((TYPE) == MPU_REGION_ALL_RO)) + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define IS_MPU_REGION_NUMBER(NUMBER) (((NUMBER) == MPU_REGION_NUMBER0) || \ + ((NUMBER) == MPU_REGION_NUMBER1) || \ + ((NUMBER) == MPU_REGION_NUMBER2) || \ + ((NUMBER) == MPU_REGION_NUMBER3) || \ + ((NUMBER) == MPU_REGION_NUMBER4) || \ + ((NUMBER) == MPU_REGION_NUMBER5) || \ + ((NUMBER) == MPU_REGION_NUMBER6) || \ + ((NUMBER) == MPU_REGION_NUMBER7) || \ + ((NUMBER) == MPU_REGION_NUMBER8) || \ + ((NUMBER) == MPU_REGION_NUMBER9) || \ + ((NUMBER) == MPU_REGION_NUMBER10)|| \ + ((NUMBER) == MPU_REGION_NUMBER11)) +#else +#define IS_MPU_REGION_NUMBER(NUMBER) (((NUMBER) == MPU_REGION_NUMBER0) || \ + ((NUMBER) == MPU_REGION_NUMBER1) || \ + ((NUMBER) == MPU_REGION_NUMBER2) || \ + ((NUMBER) == MPU_REGION_NUMBER3) || \ + ((NUMBER) == MPU_REGION_NUMBER4) || \ + ((NUMBER) == MPU_REGION_NUMBER5) || \ + ((NUMBER) == MPU_REGION_NUMBER6) || \ + ((NUMBER) == MPU_REGION_NUMBER7)) +#endif /* __ARM_FEATURE_CMSE */ + +#define IS_MPU_ATTRIBUTES_NUMBER(NUMBER) (((NUMBER) == MPU_ATTRIBUTES_NUMBER0) || \ + ((NUMBER) == MPU_ATTRIBUTES_NUMBER1) || \ + ((NUMBER) == MPU_ATTRIBUTES_NUMBER2) || \ + ((NUMBER) == MPU_ATTRIBUTES_NUMBER3) || \ + ((NUMBER) == MPU_ATTRIBUTES_NUMBER4) || \ + ((NUMBER) == MPU_ATTRIBUTES_NUMBER5) || \ + ((NUMBER) == MPU_ATTRIBUTES_NUMBER6) || \ + ((NUMBER) == MPU_ATTRIBUTES_NUMBER7)) + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32H5xx_HAL_CORTEX_H */ + + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_crc.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_crc.h new file mode 100644 index 0000000000..1615220867 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_crc.h @@ -0,0 +1,342 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_crc.h + * @author MCD Application Team + * @brief Header file of CRC HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_CRC_H +#define STM32H5xx_HAL_CRC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup CRC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup CRC_Exported_Types CRC Exported Types + * @{ + */ + +/** + * @brief CRC HAL State Structure definition + */ +typedef enum +{ + HAL_CRC_STATE_RESET = 0x00U, /*!< CRC not yet initialized or disabled */ + HAL_CRC_STATE_READY = 0x01U, /*!< CRC initialized and ready for use */ + HAL_CRC_STATE_BUSY = 0x02U, /*!< CRC internal process is ongoing */ + HAL_CRC_STATE_TIMEOUT = 0x03U, /*!< CRC timeout state */ + HAL_CRC_STATE_ERROR = 0x04U /*!< CRC error state */ +} HAL_CRC_StateTypeDef; + +/** + * @brief CRC Init Structure definition + */ +typedef struct +{ + uint8_t DefaultPolynomialUse; /*!< This parameter is a value of @ref CRC_Default_Polynomial and indicates if default polynomial is used. + If set to DEFAULT_POLYNOMIAL_ENABLE, resort to default + X^32 + X^26 + X^23 + X^22 + X^16 + X^12 + X^11 + X^10 +X^8 + X^7 + X^5 + + X^4 + X^2+ X +1. + In that case, there is no need to set GeneratingPolynomial field. + If otherwise set to DEFAULT_POLYNOMIAL_DISABLE, GeneratingPolynomial and + CRCLength fields must be set. */ + + uint8_t DefaultInitValueUse; /*!< This parameter is a value of @ref CRC_Default_InitValue_Use and indicates if default init value is used. + If set to DEFAULT_INIT_VALUE_ENABLE, resort to default + 0xFFFFFFFF value. In that case, there is no need to set InitValue field. If + otherwise set to DEFAULT_INIT_VALUE_DISABLE, InitValue field must be set. */ + + uint32_t GeneratingPolynomial; /*!< Set CRC generating polynomial as a 7, 8, 16 or 32-bit long value for a polynomial degree + respectively equal to 7, 8, 16 or 32. This field is written in normal, + representation e.g., for a polynomial of degree 7, X^7 + X^6 + X^5 + X^2 + 1 + is written 0x65. No need to specify it if DefaultPolynomialUse is set to + DEFAULT_POLYNOMIAL_ENABLE. */ + + uint32_t CRCLength; /*!< This parameter is a value of @ref CRC_Polynomial_Sizes and indicates CRC length. + Value can be either one of + @arg @ref CRC_POLYLENGTH_32B (32-bit CRC), + @arg @ref CRC_POLYLENGTH_16B (16-bit CRC), + @arg @ref CRC_POLYLENGTH_8B (8-bit CRC), + @arg @ref CRC_POLYLENGTH_7B (7-bit CRC). */ + + uint32_t InitValue; /*!< Init value to initiate CRC computation. No need to specify it if DefaultInitValueUse + is set to DEFAULT_INIT_VALUE_ENABLE. */ + + uint32_t InputDataInversionMode; /*!< This parameter is a value of @ref CRCEx_Input_Data_Inversion and specifies input data inversion mode. + Can be either one of the following values + @arg @ref CRC_INPUTDATA_INVERSION_NONE no input data inversion + @arg @ref CRC_INPUTDATA_INVERSION_BYTE byte-wise inversion, 0x1A2B3C4D + becomes 0x58D43CB2 + @arg @ref CRC_INPUTDATA_INVERSION_HALFWORD halfword-wise inversion, + 0x1A2B3C4D becomes 0xD458B23C + @arg @ref CRC_INPUTDATA_INVERSION_WORD word-wise inversion, 0x1A2B3C4D + becomes 0xB23CD458 */ + + uint32_t OutputDataInversionMode; /*!< This parameter is a value of @ref CRCEx_Output_Data_Inversion and specifies output data (i.e. CRC) inversion mode. + Can be either + @arg @ref CRC_OUTPUTDATA_INVERSION_DISABLE no CRC inversion, + @arg @ref CRC_OUTPUTDATA_INVERSION_ENABLE CRC 0x11223344 is converted + into 0x22CC4488 */ +} CRC_InitTypeDef; + +/** + * @brief CRC Handle Structure definition + */ +typedef struct +{ + CRC_TypeDef *Instance; /*!< Register base address */ + + CRC_InitTypeDef Init; /*!< CRC configuration parameters */ + + HAL_LockTypeDef Lock; /*!< CRC Locking object */ + + __IO HAL_CRC_StateTypeDef State; /*!< CRC communication state */ + + uint32_t InputDataFormat; /*!< This parameter is a value of @ref CRC_Input_Buffer_Format and specifies input data format. + Can be either + @arg @ref CRC_INPUTDATA_FORMAT_BYTES input data is a stream of bytes + (8-bit data) + @arg @ref CRC_INPUTDATA_FORMAT_HALFWORDS input data is a stream of + half-words (16-bit data) + @arg @ref CRC_INPUTDATA_FORMAT_WORDS input data is a stream of words + (32-bit data) + + Note that constant CRC_INPUT_FORMAT_UNDEFINED is defined but an initialization + error must occur if InputBufferFormat is not one of the three values listed + above */ +} CRC_HandleTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup CRC_Exported_Constants CRC Exported Constants + * @{ + */ + +/** @defgroup CRC_Default_Polynomial_Value Default CRC generating polynomial + * @{ + */ +#define DEFAULT_CRC32_POLY 0x04C11DB7U /*!< X^32 + X^26 + X^23 + X^22 + X^16 + X^12 + X^11 + X^10 +X^8 + X^7 + X^5 + X^4 + X^2+ X +1 */ +/** + * @} + */ + +/** @defgroup CRC_Default_InitValue Default CRC computation initialization value + * @{ + */ +#define DEFAULT_CRC_INITVALUE 0xFFFFFFFFU /*!< Initial CRC default value */ +/** + * @} + */ + +/** @defgroup CRC_Default_Polynomial Indicates whether or not default polynomial is used + * @{ + */ +#define DEFAULT_POLYNOMIAL_ENABLE ((uint8_t)0x00U) /*!< Enable default generating polynomial 0x04C11DB7 */ +#define DEFAULT_POLYNOMIAL_DISABLE ((uint8_t)0x01U) /*!< Disable default generating polynomial 0x04C11DB7 */ +/** + * @} + */ + +/** @defgroup CRC_Default_InitValue_Use Indicates whether or not default init value is used + * @{ + */ +#define DEFAULT_INIT_VALUE_ENABLE ((uint8_t)0x00U) /*!< Enable initial CRC default value */ +#define DEFAULT_INIT_VALUE_DISABLE ((uint8_t)0x01U) /*!< Disable initial CRC default value */ +/** + * @} + */ + +/** @defgroup CRC_Polynomial_Sizes Polynomial sizes to configure the peripheral + * @{ + */ +#define CRC_POLYLENGTH_32B 0x00000000U /*!< Resort to a 32-bit long generating polynomial */ +#define CRC_POLYLENGTH_16B CRC_CR_POLYSIZE_0 /*!< Resort to a 16-bit long generating polynomial */ +#define CRC_POLYLENGTH_8B CRC_CR_POLYSIZE_1 /*!< Resort to a 8-bit long generating polynomial */ +#define CRC_POLYLENGTH_7B CRC_CR_POLYSIZE /*!< Resort to a 7-bit long generating polynomial */ +/** + * @} + */ + +/** @defgroup CRC_Polynomial_Size_Definitions CRC polynomial possible sizes actual definitions + * @{ + */ +#define HAL_CRC_LENGTH_32B 32U /*!< 32-bit long CRC */ +#define HAL_CRC_LENGTH_16B 16U /*!< 16-bit long CRC */ +#define HAL_CRC_LENGTH_8B 8U /*!< 8-bit long CRC */ +#define HAL_CRC_LENGTH_7B 7U /*!< 7-bit long CRC */ +/** + * @} + */ + +/** @defgroup CRC_Input_Buffer_Format Input Buffer Format + * @{ + */ +/* WARNING: CRC_INPUT_FORMAT_UNDEFINED is created for reference purposes but + * an error is triggered in HAL_CRC_Init() if InputDataFormat field is set + * to CRC_INPUT_FORMAT_UNDEFINED: the format MUST be defined by the user for + * the CRC APIs to provide a correct result */ +#define CRC_INPUTDATA_FORMAT_UNDEFINED 0x00000000U /*!< Undefined input data format */ +#define CRC_INPUTDATA_FORMAT_BYTES 0x00000001U /*!< Input data in byte format */ +#define CRC_INPUTDATA_FORMAT_HALFWORDS 0x00000002U /*!< Input data in half-word format */ +#define CRC_INPUTDATA_FORMAT_WORDS 0x00000003U /*!< Input data in word format */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup CRC_Exported_Macros CRC Exported Macros + * @{ + */ + +/** @brief Reset CRC handle state. + * @param __HANDLE__ CRC handle. + * @retval None + */ +#define __HAL_CRC_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_CRC_STATE_RESET) + +/** + * @brief Reset CRC Data Register. + * @param __HANDLE__ CRC handle + * @retval None + */ +#define __HAL_CRC_DR_RESET(__HANDLE__) ((__HANDLE__)->Instance->CR |= CRC_CR_RESET) + +/** + * @brief Set CRC INIT non-default value + * @param __HANDLE__ CRC handle + * @param __INIT__ 32-bit initial value + * @retval None + */ +#define __HAL_CRC_INITIALCRCVALUE_CONFIG(__HANDLE__, __INIT__) ((__HANDLE__)->Instance->INIT = (__INIT__)) + +/** + * @brief Store data in the Independent Data (ID) register. + * @param __HANDLE__ CRC handle + * @param __VALUE__ Value to be stored in the ID register + * @note Refer to the Reference Manual to get the authorized __VALUE__ length in bits + * @retval None + */ +#define __HAL_CRC_SET_IDR(__HANDLE__, __VALUE__) (WRITE_REG((__HANDLE__)->Instance->IDR, (__VALUE__))) + +/** + * @brief Return the data stored in the Independent Data (ID) register. + * @param __HANDLE__ CRC handle + * @note Refer to the Reference Manual to get the authorized __VALUE__ length in bits + * @retval Value of the ID register + */ +#define __HAL_CRC_GET_IDR(__HANDLE__) (((__HANDLE__)->Instance->IDR) & CRC_IDR_IDR) +/** + * @} + */ + + +/* Private macros --------------------------------------------------------*/ +/** @defgroup CRC_Private_Macros CRC Private Macros + * @{ + */ + +#define IS_DEFAULT_POLYNOMIAL(DEFAULT) (((DEFAULT) == DEFAULT_POLYNOMIAL_ENABLE) || \ + ((DEFAULT) == DEFAULT_POLYNOMIAL_DISABLE)) + +#define IS_DEFAULT_INIT_VALUE(VALUE) (((VALUE) == DEFAULT_INIT_VALUE_ENABLE) || \ + ((VALUE) == DEFAULT_INIT_VALUE_DISABLE)) + +#define IS_CRC_POL_LENGTH(LENGTH) (((LENGTH) == CRC_POLYLENGTH_32B) || \ + ((LENGTH) == CRC_POLYLENGTH_16B) || \ + ((LENGTH) == CRC_POLYLENGTH_8B) || \ + ((LENGTH) == CRC_POLYLENGTH_7B)) + +#define IS_CRC_INPUTDATA_FORMAT(FORMAT) (((FORMAT) == CRC_INPUTDATA_FORMAT_BYTES) || \ + ((FORMAT) == CRC_INPUTDATA_FORMAT_HALFWORDS) || \ + ((FORMAT) == CRC_INPUTDATA_FORMAT_WORDS)) + +/** + * @} + */ + +/* Include CRC HAL Extended module */ +#include "stm32h5xx_hal_crc_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup CRC_Exported_Functions CRC Exported Functions + * @{ + */ + +/* Initialization and de-initialization functions ****************************/ +/** @defgroup CRC_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ +HAL_StatusTypeDef HAL_CRC_Init(CRC_HandleTypeDef *hcrc); +HAL_StatusTypeDef HAL_CRC_DeInit(CRC_HandleTypeDef *hcrc); +void HAL_CRC_MspInit(CRC_HandleTypeDef *hcrc); +void HAL_CRC_MspDeInit(CRC_HandleTypeDef *hcrc); +/** + * @} + */ + +/* Peripheral Control functions ***********************************************/ +/** @defgroup CRC_Exported_Functions_Group2 Peripheral Control functions + * @{ + */ +uint32_t HAL_CRC_Accumulate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength); +uint32_t HAL_CRC_Calculate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength); +/** + * @} + */ + +/* Peripheral State and Error functions ***************************************/ +/** @defgroup CRC_Exported_Functions_Group3 Peripheral State functions + * @{ + */ +HAL_CRC_StateTypeDef HAL_CRC_GetState(const CRC_HandleTypeDef *hcrc); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_CRC_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_crc_ex.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_crc_ex.h new file mode 100644 index 0000000000..e8eea09bf5 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_crc_ex.h @@ -0,0 +1,150 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_crc_ex.h + * @author MCD Application Team + * @brief Header file of CRC HAL extended module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_CRC_EX_H +#define STM32H5xx_HAL_CRC_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup CRCEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup CRCEx_Exported_Constants CRC Extended Exported Constants + * @{ + */ + +/** @defgroup CRCEx_Input_Data_Inversion Input Data Inversion Modes + * @{ + */ +#define CRC_INPUTDATA_INVERSION_NONE 0x00000000U /*!< No input data inversion */ +#define CRC_INPUTDATA_INVERSION_BYTE CRC_CR_REV_IN_0 /*!< Byte-wise input data inversion */ +#define CRC_INPUTDATA_INVERSION_HALFWORD CRC_CR_REV_IN_1 /*!< HalfWord-wise input data inversion */ +#define CRC_INPUTDATA_INVERSION_WORD CRC_CR_REV_IN /*!< Word-wise input data inversion */ +/** + * @} + */ + +/** @defgroup CRCEx_Output_Data_Inversion Output Data Inversion Modes + * @{ + */ +#define CRC_OUTPUTDATA_INVERSION_DISABLE 0x00000000U /*!< No output data inversion */ +#define CRC_OUTPUTDATA_INVERSION_ENABLE CRC_CR_REV_OUT /*!< Bit-wise output data inversion */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup CRCEx_Exported_Macros CRC Extended Exported Macros + * @{ + */ + +/** + * @brief Set CRC output reversal + * @param __HANDLE__ CRC handle + * @retval None + */ +#define __HAL_CRC_OUTPUTREVERSAL_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= CRC_CR_REV_OUT) + +/** + * @brief Unset CRC output reversal + * @param __HANDLE__ CRC handle + * @retval None + */ +#define __HAL_CRC_OUTPUTREVERSAL_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR &= ~(CRC_CR_REV_OUT)) + +/** + * @brief Set CRC non-default polynomial + * @param __HANDLE__ CRC handle + * @param __POLYNOMIAL__ 7, 8, 16 or 32-bit polynomial + * @retval None + */ +#define __HAL_CRC_POLYNOMIAL_CONFIG(__HANDLE__, __POLYNOMIAL__) ((__HANDLE__)->Instance->POL = (__POLYNOMIAL__)) + +/** + * @} + */ + +/* Private macros --------------------------------------------------------*/ +/** @defgroup CRCEx_Private_Macros CRC Extended Private Macros + * @{ + */ + +#define IS_CRC_INPUTDATA_INVERSION_MODE(MODE) (((MODE) == CRC_INPUTDATA_INVERSION_NONE) || \ + ((MODE) == CRC_INPUTDATA_INVERSION_BYTE) || \ + ((MODE) == CRC_INPUTDATA_INVERSION_HALFWORD) || \ + ((MODE) == CRC_INPUTDATA_INVERSION_WORD)) + +#define IS_CRC_OUTPUTDATA_INVERSION_MODE(MODE) (((MODE) == CRC_OUTPUTDATA_INVERSION_DISABLE) || \ + ((MODE) == CRC_OUTPUTDATA_INVERSION_ENABLE)) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup CRCEx_Exported_Functions + * @{ + */ + +/** @addtogroup CRCEx_Exported_Functions_Group1 + * @{ + */ +/* Initialization and de-initialization functions ****************************/ +HAL_StatusTypeDef HAL_CRCEx_Polynomial_Set(CRC_HandleTypeDef *hcrc, uint32_t Pol, uint32_t PolyLength); +HAL_StatusTypeDef HAL_CRCEx_Input_Data_Reverse(CRC_HandleTypeDef *hcrc, uint32_t InputReverseMode); +HAL_StatusTypeDef HAL_CRCEx_Output_Data_Reverse(CRC_HandleTypeDef *hcrc, uint32_t OutputReverseMode); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_CRC_EX_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_cryp.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_cryp.h new file mode 100644 index 0000000000..97297b881b --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_cryp.h @@ -0,0 +1,724 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_cryp.h + * @author MCD Application Team + * @brief Header file of CRYP HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_CRYP_H +#define STM32H5xx_HAL_CRYP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +#if defined(AES) + +/** @defgroup CRYP CRYP + * @brief CRYP HAL module driver. + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup CRYP_Exported_Types CRYP Exported Types + * @{ + */ + +/** + * @brief CRYP Init Structure definition + */ + +typedef struct +{ + uint32_t DataType; /*!< 32-bit data, 16-bit data, 8-bit data or 1-bit string. + This parameter can be a value of @ref CRYP_Data_Type */ + uint32_t KeySize; /*!< Used only in AES mode : 128, 192 or 256 bit key length in CRYP1. + 128 or 256 bit key length in TinyAES This parameter can be a value + of @ref CRYP_Key_Size */ + uint32_t *pKey; /*!< The key used for encryption/decryption */ + uint32_t *pInitVect; /*!< The initialization vector used also as initialization + counter in CTR mode */ + uint32_t Algorithm; /*!< DES/ TDES Algorithm ECB/CBC + AES Algorithm ECB/CBC/CTR/GCM or CCM + This parameter can be a value of @ref CRYP_Algorithm_Mode */ + uint32_t *Header; /*!< used only in AES GCM and CCM Algorithm for authentication, + GCM : also known as Additional Authentication Data + CCM : named B1 composed of the associated data length and Associated Data. */ + uint32_t HeaderSize; /*!< The size of header buffer */ + uint32_t *B0; /*!< B0 is first authentication block used only in AES CCM mode */ + uint32_t DataWidthUnit; /*!< Payload Data Width Unit, this parameter can be value of @ref CRYP_Data_Width_Unit */ + uint32_t HeaderWidthUnit; /*!< Header Width Unit, this parameter can be value of @ref CRYP_Header_Width_Unit */ + uint32_t KeyIVConfigSkip; /*!< CRYP peripheral Key and IV configuration skip, to config Key and Initialization + Vector only once and to skip configuration for consecutive processings. + This parameter can be a value of @ref CRYP_Configuration_Skip */ + uint32_t KeyMode; /*!< Key mode selection, this parameter can be value of @ref CRYP_Key_Mode */ + uint32_t KeySelect; /*!< Only for SAES : Key selection, this parameter can be value of @ref CRYP_Key_Select */ + uint32_t KeyProtection; /*!< Only for SAES : Key protection, this parameter can be value of @ref CRYP_Key_Protection */ + +} CRYP_ConfigTypeDef; + +/** + * @brief CRYP State Structure definition + */ + +typedef enum +{ + HAL_CRYP_STATE_RESET = 0x00U, /*!< CRYP not yet initialized or disabled */ + HAL_CRYP_STATE_READY = 0x01U, /*!< CRYP initialized and ready for use */ + HAL_CRYP_STATE_BUSY = 0x02U, /*!< CRYP BUSY, internal processing is ongoing */ +#if (USE_HAL_CRYP_SUSPEND_RESUME == 1U) + HAL_CRYP_STATE_SUSPENDED = 0x03U, /*!< CRYP suspended */ +#endif /* USE_HAL_CRYP_SUSPEND_RESUME */ +} HAL_CRYP_STATETypeDef; + +/** + * @brief CRYP Context Structure definition + */ + +typedef struct +{ + uint32_t DataType; /*!< This parameter can be a value of @ref CRYP_Data_Type */ + uint32_t KeySize; /*!< This parameter can be a value of @ref CRYP_Key_Size */ + uint32_t *pKey; /*!< The key used for encryption/decryption */ + uint32_t *pInitVect; /*!< The initialization vector, counter with CBC and CTR Algorithm */ + uint32_t Algorithm; /*!< This parameter can be a value of @ref CRYP_Algorithm_Mode */ + uint32_t DataWidthUnit; /*!< This parameter can be value of @ref CRYP_Data_Width_Unit */ + uint32_t KeyIVConfigSkip; /*!< This parameter can be a value of @ref CRYP_Configuration_Skip */ + uint32_t KeyMode; /*!< This parameter can be value of @ref CRYP_Key_Mode */ + uint32_t Phase; /*!< CRYP peripheral phase */ + uint32_t KeyIVConfig; /*!< CRYP peripheral Key and IV configuration flag */ + uint32_t CR_Reg; /*!< CRYP CR register */ + uint32_t IER_Reg; /*!< CRYP IER register */ + uint32_t IVR0_Reg; /*!< CRYP IVR0 register */ + uint32_t IVR1_Reg; /*!< CRYP IVR1 register */ + uint32_t IVR2_Reg; /*!< CRYP IVR2 register */ + uint32_t IVR3_Reg; /*!< CRYP IVR3 register */ + +} CRYP_ContextTypeDef; + +#if (USE_HAL_CRYP_SUSPEND_RESUME == 1U) +/** + * @brief HAL CRYP mode suspend definitions + */ +typedef enum +{ + HAL_CRYP_SUSPEND_NONE = 0x00U, /*!< CRYP processing suspension not requested */ + HAL_CRYP_SUSPEND = 0x01U /*!< CRYP processing suspension requested */ +} HAL_SuspendTypeDef; +#endif /* USE_HAL_CRYP_SUSPEND_RESUME */ + +/** + * @brief CRYP handle Structure definition + */ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) +typedef struct __CRYP_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ +{ + AES_TypeDef *Instance; /*!< AES Register base address */ + + CRYP_ConfigTypeDef Init; /*!< CRYP required parameters */ + uint32_t *pCrypInBuffPtr; /*!< Pointer to CRYP processing (encryption, decryption,...) buffer */ + + uint32_t *pCrypOutBuffPtr; /*!< Pointer to CRYP processing (encryption, decryption,...) buffer */ + + __IO uint16_t CrypHeaderCount; /*!< Counter of header data in words */ + + __IO uint16_t CrypInCount; /*!< Counter of input data in words */ + + __IO uint16_t CrypOutCount; /*!< Counter of output data in words */ + + uint16_t Size; /*!< length of input data in word or in byte, according to DataWidthUnit */ + + uint32_t Phase; /*!< CRYP peripheral phase */ + + DMA_HandleTypeDef *hdmain; /*!< CRYP In DMA handle parameters */ + + DMA_HandleTypeDef *hdmaout; /*!< CRYP Out DMA handle parameters */ + + HAL_LockTypeDef Lock; /*!< CRYP locking object */ + + __IO HAL_CRYP_STATETypeDef State; /*!< CRYP peripheral state */ + + __IO uint32_t ErrorCode; /*!< CRYP peripheral error code */ + + uint32_t KeyIVConfig; /*!< CRYP peripheral Key and IV configuration flag, used when + configuration can be skipped */ + + uint32_t SizesSum; /*!< Sum of successive payloads lengths (in bytes), stored + for a single signature computation after several + messages processing */ + +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + void (*InCpltCallback)(struct __CRYP_HandleTypeDef *hcryp); /*!< CRYP Input FIFO transfer completed callback */ + void (*OutCpltCallback)(struct __CRYP_HandleTypeDef *hcryp); /*!< CRYP Output FIFO transfer completed callback */ + void (*ErrorCallback)(struct __CRYP_HandleTypeDef *hcryp); /*!< CRYP Error callback */ + + void (* MspInitCallback)(struct __CRYP_HandleTypeDef *hcryp); /*!< CRYP Msp Init callback */ + void (* MspDeInitCallback)(struct __CRYP_HandleTypeDef *hcryp); /*!< CRYP Msp DeInit callback */ + +#endif /* (USE_HAL_CRYP_REGISTER_CALLBACKS) */ + +#if (USE_HAL_CRYP_SUSPEND_RESUME == 1U) + + __IO HAL_SuspendTypeDef SuspendRequest; /*!< CRYP peripheral suspension request flag */ + + CRYP_ConfigTypeDef Init_saved; /*!< copy of CRYP required parameters when processing is suspended */ + + uint32_t *pCrypInBuffPtr_saved; /*!< copy of CRYP input pointer when processing is suspended */ + + uint32_t *pCrypOutBuffPtr_saved; /*!< copy of CRYP output pointer when processing is suspended */ + + uint32_t CrypInCount_saved; /*!< copy of CRYP input data counter when processing is suspended */ + + uint32_t CrypOutCount_saved; /*!< copy of CRYP output data counter when processing is suspended */ + + uint32_t Phase_saved; /*!< copy of CRYP authentication phase when processing is suspended */ + + __IO HAL_CRYP_STATETypeDef State_saved; /*!< copy of CRYP peripheral state when processing is suspended */ + + uint32_t IV_saved[4]; /*!< copy of Initialisation Vector registers */ + + uint32_t SUSPxR_saved[8]; /*!< copy of suspension registers */ + + uint32_t CR_saved; /*!< copy of CRYP control register when processing is suspended*/ + + uint32_t Key_saved[8]; /*!< copy of key registers */ + + uint16_t Size_saved; /*!< copy of input buffer size */ + + uint16_t CrypHeaderCount_saved; /*!< copy of CRYP header data counter when processing is suspended */ + + uint32_t SizesSum_saved; /*!< copy of SizesSum when processing is suspended */ + + uint32_t ResumingFlag; /*!< resumption flag to bypass steps already carried out */ +#endif /* USE_HAL_CRYP_SUSPEND_RESUME */ + +} CRYP_HandleTypeDef; + +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + +/** + * @brief HAL CRYP Callback ID enumeration definition + */ +typedef enum +{ + HAL_CRYP_MSPINIT_CB_ID = 0x00U, /*!< CRYP MspInit callback ID */ + HAL_CRYP_MSPDEINIT_CB_ID = 0x01U, /*!< CRYP MspDeInit callback ID */ + HAL_CRYP_INPUT_COMPLETE_CB_ID = 0x02U, /*!< CRYP Input FIFO transfer completed callback ID */ + HAL_CRYP_OUTPUT_COMPLETE_CB_ID = 0x03U, /*!< CRYP Output FIFO transfer completed callback ID */ + HAL_CRYP_ERROR_CB_ID = 0x04U, /*!< CRYP Error callback ID */ +} HAL_CRYP_CallbackIDTypeDef; + +/** + * @brief HAL CRYP Callback pointer definition + */ +typedef void (*pCRYP_CallbackTypeDef)(CRYP_HandleTypeDef *hcryp); /*!< pointer to a common CRYP callback function */ + +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup CRYP_Exported_Constants CRYP Exported Constants + * @{ + */ + +/** @defgroup CRYP_Error_Definition CRYP Error Definition + * @{ + */ +#define HAL_CRYP_ERROR_NONE 0x00000000U /*!< No error */ +#define HAL_CRYP_ERROR_WRITE 0x00000001U /*!< Write error */ +#define HAL_CRYP_ERROR_READ 0x00000002U /*!< Read error */ +#define HAL_CRYP_ERROR_DMA 0x00000004U /*!< DMA error */ +#define HAL_CRYP_ERROR_BUSY 0x00000008U /*!< Busy flag error */ +#define HAL_CRYP_ERROR_TIMEOUT 0x00000010U /*!< Timeout error */ +#define HAL_CRYP_ERROR_NOT_SUPPORTED 0x00000020U /*!< Not supported mode */ +#define HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE 0x00000040U /*!< Sequence are not respected only for GCM or CCM */ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) +#define HAL_CRYP_ERROR_INVALID_CALLBACK ((uint32_t)0x00000080U) /*!< Invalid Callback error */ +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ +#define HAL_CRYP_ERROR_KEY 0x00000100U /*!< Key error */ +#define HAL_CRYP_ERROR_RNG 0x00000200U /*!< Rng error */ +/** + * @} + */ + +/** @defgroup CRYP_Data_Width_Unit CRYP Data Width Unit + * @{ + */ + +#define CRYP_DATAWIDTHUNIT_WORD 0x00000000U /*!< By default, size unit is word */ +#define CRYP_DATAWIDTHUNIT_BYTE 0x00000001U /*!< By default, size unit is byte */ + +/** + * @} + */ + +/** @defgroup CRYP_Header_Width_Unit CRYP Header Width Unit + * @{ + */ + +#define CRYP_HEADERWIDTHUNIT_WORD 0x00000000U /*!< By default, header size unit is word */ +#define CRYP_HEADERWIDTHUNIT_BYTE 0x00000001U /*!< By default, header size unit is byte */ + +/** + * @} + */ + +/** @defgroup CRYP_Algorithm_Mode CRYP Algorithm Mode + * @{ + */ + +#define CRYP_AES_ECB 0x00000000U /*!< Electronic codebook chaining algorithm */ +#define CRYP_AES_CBC AES_CR_CHMOD_0 /*!< Cipher block chaining algorithm */ +#define CRYP_AES_CTR AES_CR_CHMOD_1 /*!< Counter mode chaining algorithm */ +#define CRYP_AES_GCM_GMAC (AES_CR_CHMOD_0 | AES_CR_CHMOD_1) /*!< Galois counter mode - Galois message authentication code */ +#define CRYP_AES_CCM AES_CR_CHMOD_2 /*!< Counter with Cipher Mode */ + +/** + * @} + */ + +/** @defgroup CRYP_Key_Size CRYP Key Size + * @{ + */ + +#define CRYP_KEYSIZE_128B 0x00000000U /*!< 128-bit long key */ +#define CRYP_KEYSIZE_256B AES_CR_KEYSIZE /*!< 256-bit long key */ + +/** + * @} + */ + +/** @defgroup CRYP_Key_Mode CRYP Key Mode + * @{ + */ + +#define CRYP_KEYMODE_NORMAL 0x00000000U /*!< Normal key usage, Key registers are freely usable */ +#define CRYP_KEYMODE_SHARED AES_CR_KMOD_1 /*!< Shared key */ +#define CRYP_KEYMODE_WRAPPED AES_CR_KMOD_0 /*!< Only for SAES, Wrapped key: to encrypt or decrypt AES keys */ + +/** + * @} + */ + +/** @defgroup CRYP_Key_Select CRYP Key Select + * @{ + */ + +#define CRYP_KEYSEL_NORMAL 0x00000000U /*!< Normal key, key registers SAES_KEYx or CRYP_KEYx */ +#define CRYP_KEYSEL_HW AES_CR_KEYSEL_0 /*!< Only for SAES, Hardware key : derived hardware unique key (DHUK 256-bit) */ +#define CRYP_KEYSEL_SW AES_CR_KEYSEL_1 /*!< Only for SAES, Software key : boot hardware key BHK (256-bit) */ +#define CRYP_KEYSEL_HSW AES_CR_KEYSEL_2 /*!< Only for SAES, DHUK XOR BHK Hardware unique key XOR software key */ + +/** + * @} + */ + +/** @defgroup CRYP_Key_ShareID CRYP Key Share ID + * @{ + */ + +#define CRYP_KSHAREID_AES 0x00000000U /*!< Share SAES Key with AES peripheral */ + +/** + * @} + */ + +/** @defgroup CRYP_Key_Protection CRYP Key Protection + * @{ + */ + +#define CRYP_KEYPROT_ENABLE AES_CR_KEYPROT /*!< Only for SAES, Key protection between 2 applications with different security contexts */ +#define CRYP_KEYPROT_DISABLE 0x00000000U /*!< Only for SAES, Key not protected between 2 applications with different security contexts */ +/** + * @} + */ + + +/** @defgroup CRYP_Data_Type CRYP Data Type + * @{ + */ + +#define CRYP_DATATYPE_32B 0x00000000U +#define CRYP_DATATYPE_16B AES_CR_DATATYPE_0 +#define CRYP_DATATYPE_8B AES_CR_DATATYPE_1 +#define CRYP_DATATYPE_1B AES_CR_DATATYPE + +#define CRYP_NO_SWAP CRYP_DATATYPE_32B /*!< 32-bit data type (no swapping) */ +#define CRYP_HALFWORD_SWAP CRYP_DATATYPE_16B /*!< 16-bit data type (half-word swapping) */ +#define CRYP_BYTE_SWAP CRYP_DATATYPE_8B /*!< 8-bit data type (byte swapping) */ +#define CRYP_BIT_SWAP CRYP_DATATYPE_1B /*!< 1-bit data type (bit swapping) */ + +/** + * @} + */ + +/** @defgroup CRYP_Interrupt CRYP Interrupt + * @{ + */ +#define CRYP_IT_CCFIE AES_IER_CCFIE /*!< Computation Complete interrupt enable */ +#define CRYP_IT_RWEIE AES_IER_RWEIE /*!< Read or write Error interrupt enable */ +#define CRYP_IT_KEIE AES_IER_KEIE /*!< Key error interrupt enable */ +#define CRYP_IT_RNGEIE AES_IER_RNGEIE /*!< Rng error interrupt enable */ + +/** + * @} + */ + +/** @defgroup CRYP_Flags CRYP Flags + * @{ + */ + +#define CRYP_FLAG_BUSY AES_SR_BUSY /*!< GCM process suspension forbidden also set when + transferring a shared key from SAES peripheral */ +#define CRYP_FLAG_WRERR (AES_SR_WRERR | 0x80000000U) /*!< Write Error flag */ +#define CRYP_FLAG_RDERR (AES_SR_RDERR | 0x80000000U) /*!< Read error flag */ +#define CRYP_FLAG_CCF AES_ISR_CCF /*!< Computation completed flag as AES_ISR_CCF */ +#define CRYP_FLAG_KEYVALID AES_SR_KEYVALID /*!< Key Valid flag */ +#define CRYP_FLAG_KEIF AES_ISR_KEIF /*!State = HAL_CRYP_STATE_RESET;\ + (__HANDLE__)->MspInitCallback = NULL;\ + (__HANDLE__)->MspDeInitCallback = NULL;\ + }while(0U) +#else +#define __HAL_CRYP_RESET_HANDLE_STATE(__HANDLE__) ( (__HANDLE__)->State = HAL_CRYP_STATE_RESET) +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + +/** + * @brief Enable/Disable the CRYP peripheral. + * @param __HANDLE__ specifies the CRYP handle. + * @retval None + */ + +#define __HAL_CRYP_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= AES_CR_EN) +#define __HAL_CRYP_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR &= ~AES_CR_EN) + + +/** @brief Check whether the specified CRYP status flag is set or not. + * @param __HANDLE__ specifies the CRYP handle. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values for TinyAES: + * @arg @ref CRYP_FLAG_KEYVALID Key valid flag + * @arg @ref CRYP_FLAG_BUSY GCM process suspension forbidden or + * transferring a shared key from SAES IP. + * @arg @ref CRYP_FLAG_WRERR Write Error flag + * @arg @ref CRYP_FLAG_RDERR Read Error flag + * @arg @ref CRYP_FLAG_CCF Computation Complete flag + * @arg @ref CRYP_FLAG_KEIF Key error flag + * @arg @ref CRYP_FLAG_RWEIF Read/write Error flag + + * @retval The state of __FLAG__ (TRUE or FALSE). + */ + +#define __HAL_CRYP_GET_FLAG(__HANDLE__, __FLAG__) (\ + ((__FLAG__) == CRYP_FLAG_KEYVALID )?(((__HANDLE__)->Instance->SR \ + & (CRYP_FLAG_KEYVALID)) == (CRYP_FLAG_KEYVALID)) : \ + ((__FLAG__) == CRYP_FLAG_BUSY )?(((__HANDLE__)->Instance->SR \ + & (CRYP_FLAG_BUSY)) == (CRYP_FLAG_BUSY)) : \ + ((__FLAG__) == CRYP_FLAG_WRERR )?(((__HANDLE__)->Instance->SR \ + & (CRYP_FLAG_WRERR & 0x7FFFFFFFU)) == \ + (CRYP_FLAG_WRERR & 0x7FFFFFFFU)) : \ + ((__FLAG__) == CRYP_FLAG_RDERR )?(((__HANDLE__)->Instance->SR \ + & (CRYP_FLAG_RDERR & 0x7FFFFFFFU)) == \ + (CRYP_FLAG_RDERR & 0x7FFFFFFFU)) : \ + ((__FLAG__) == CRYP_FLAG_KEIF )?(((__HANDLE__)->Instance->ISR \ + & (CRYP_FLAG_KEIF)) == (CRYP_FLAG_KEIF)) : \ + ((__FLAG__) == CRYP_FLAG_RWEIF )?(((__HANDLE__)->Instance->ISR \ + & (CRYP_FLAG_RWEIF)) == (CRYP_FLAG_RWEIF)) : \ + (((__HANDLE__)->Instance->ISR & (CRYP_FLAG_CCF)) == (CRYP_FLAG_CCF))) + +/** @brief Clear the CRYP pending status flag. + * @param __HANDLE__ specifies the CRYP handle. + * @param __FLAG__ specifies the flag to clear. + * This parameter can be one of the following values: + * @arg @ref CRYP_CLEAR_RWEIF Read (RDERR), Write (WRERR) or Read/write (RWEIF) Error Flag Clear + * @arg @ref CRYP_CLEAR_CCF Computation Complete Flag (CCF) Clear + * @arg @ref CRYP_CLEAR_KEIF Key error interrupt flag clear + * @retval None + */ + +#define __HAL_CRYP_CLEAR_FLAG(__HANDLE__, __FLAG__) SET_BIT((__HANDLE__)->Instance->ICR, (__FLAG__)) + + +/** @brief Check whether the specified CRYP interrupt source is enabled or not. + * @param __HANDLE__ specifies the CRYP handle. + * @param __INTERRUPT__ CRYP interrupt source to check + * This parameter can be one of the following values for TinyAES: + * @arg @ref CRYP_IT_RWEIE Error interrupt (used for RDERR and WRERR) + * @arg @ref CRYP_IT_CCFIE Computation Complete interrupt + * @arg @ref CRYP_IT_KEIE Key error interrupt + * @retval State of interruption (TRUE or FALSE). + */ + +#define __HAL_CRYP_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->IER\ + & (__INTERRUPT__)) == (__INTERRUPT__)) + +/** + * @brief Enable the CRYP interrupt. + * @param __HANDLE__ specifies the CRYP handle. + * @param __INTERRUPT__ CRYP Interrupt. + * This parameter can be one of the following values for TinyAES: + * @arg @ref CRYP_IT_RWEIE Error interrupt (used for RDERR and WRERR) + * @arg @ref CRYP_IT_CCFIE Computation Complete interrupt + * @arg @ref CRYP_IT_KEIE Key error interrupt + * @retval None + */ + +#define __HAL_CRYP_ENABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->IER) |= (__INTERRUPT__)) + +/** + * @brief Disable the CRYP interrupt. + * @param __HANDLE__ specifies the CRYP handle. + * @param __INTERRUPT__ CRYP Interrupt. + * This parameter can be one of the following values for TinyAES: + * @arg @ref CRYP_IT_RWEIE Error interrupt (used for RDERR and WRERR) + * @arg @ref CRYP_IT_CCFIE Computation Complete interrupt + * @arg @ref CRYP_IT_KEIE Key error interrupt + * @retval None + */ + +#define __HAL_CRYP_DISABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->IER) &= ~(__INTERRUPT__)) + +/** + * @} + */ + +/* Include CRYP HAL Extended module */ +#include "stm32h5xx_hal_cryp_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup CRYP_Exported_Functions CRYP Exported Functions + * @{ + */ + +/** @addtogroup CRYP_Exported_Functions_Group1 + * @{ + */ +HAL_StatusTypeDef HAL_CRYP_Init(CRYP_HandleTypeDef *hcryp); +HAL_StatusTypeDef HAL_CRYP_DeInit(CRYP_HandleTypeDef *hcryp); +void HAL_CRYP_MspInit(CRYP_HandleTypeDef *hcryp); +void HAL_CRYP_MspDeInit(CRYP_HandleTypeDef *hcryp); +HAL_StatusTypeDef HAL_CRYP_SetConfig(CRYP_HandleTypeDef *hcryp, CRYP_ConfigTypeDef *pConf); +HAL_StatusTypeDef HAL_CRYP_GetConfig(CRYP_HandleTypeDef *hcryp, CRYP_ConfigTypeDef *pConf); +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) +HAL_StatusTypeDef HAL_CRYP_RegisterCallback(CRYP_HandleTypeDef *hcryp, HAL_CRYP_CallbackIDTypeDef CallbackID, + pCRYP_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_CRYP_UnRegisterCallback(CRYP_HandleTypeDef *hcryp, HAL_CRYP_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ +#if (USE_HAL_CRYP_SUSPEND_RESUME == 1U) +void HAL_CRYP_ProcessSuspend(CRYP_HandleTypeDef *hcryp); +HAL_StatusTypeDef HAL_CRYP_Suspend(CRYP_HandleTypeDef *hcryp); +HAL_StatusTypeDef HAL_CRYP_Resume(CRYP_HandleTypeDef *hcryp); +#endif /* defined (USE_HAL_CRYP_SUSPEND_RESUME) */ +HAL_StatusTypeDef HAL_CRYP_SaveContext(CRYP_HandleTypeDef *hcryp, CRYP_ContextTypeDef *pcont); +HAL_StatusTypeDef HAL_CRYP_RestoreContext(CRYP_HandleTypeDef *hcryp, CRYP_ContextTypeDef *pcont); + +/** + * @} + */ + +/** @addtogroup CRYP_Exported_Functions_Group2 + * @{ + */ + +/* encryption/decryption ***********************************/ +HAL_StatusTypeDef HAL_CRYP_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint16_t Size, uint32_t *pOutput, + uint32_t Timeout); +HAL_StatusTypeDef HAL_CRYP_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint16_t Size, uint32_t *pOutput, + uint32_t Timeout); +HAL_StatusTypeDef HAL_CRYP_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint16_t Size, uint32_t *pOutput); +HAL_StatusTypeDef HAL_CRYP_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint16_t Size, uint32_t *pOutput); +HAL_StatusTypeDef HAL_CRYP_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint16_t Size, uint32_t *pOutput); +HAL_StatusTypeDef HAL_CRYP_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint16_t Size, uint32_t *pOutput); + +/** + * @} + */ + + +/** @addtogroup CRYP_Exported_Functions_Group3 + * @{ + */ +/* Interrupt Handler functions **********************************************/ +void HAL_CRYP_IRQHandler(CRYP_HandleTypeDef *hcryp); +HAL_CRYP_STATETypeDef HAL_CRYP_GetState(const CRYP_HandleTypeDef *hcryp); +void HAL_CRYP_InCpltCallback(CRYP_HandleTypeDef *hcryp); +void HAL_CRYP_OutCpltCallback(CRYP_HandleTypeDef *hcryp); +void HAL_CRYP_ErrorCallback(CRYP_HandleTypeDef *hcryp); +uint32_t HAL_CRYP_GetError(const CRYP_HandleTypeDef *hcryp); + +/** + * @} + */ + +/** + * @} + */ + +/* Private macros --------------------------------------------------------*/ +/** @defgroup CRYP_Private_Macros CRYP Private Macros + * @{ + */ + +#define IS_CRYP_INSTANCE(INSTANCE)(((INSTANCE) == AES) || \ + ((INSTANCE) == SAES)) + +#define IS_CRYP_ALGORITHM(ALGORITHM) (((ALGORITHM) == CRYP_AES_ECB) || \ + ((ALGORITHM) == CRYP_AES_CBC) || \ + ((ALGORITHM) == CRYP_AES_CTR) || \ + ((ALGORITHM) == CRYP_AES_GCM_GMAC)|| \ + ((ALGORITHM) == CRYP_AES_CCM)) + + +#define IS_CRYP_KEYSIZE(KEYSIZE)(((KEYSIZE) == CRYP_KEYSIZE_128B) || \ + ((KEYSIZE) == CRYP_KEYSIZE_256B)) + +#define IS_CRYP_DATATYPE(DATATYPE)(((DATATYPE) == CRYP_NO_SWAP) || \ + ((DATATYPE) == CRYP_HALFWORD_SWAP) || \ + ((DATATYPE) == CRYP_BYTE_SWAP) || \ + ((DATATYPE) == CRYP_BIT_SWAP)) + +#define IS_CRYP_INIT(CONFIG)(((CONFIG) == CRYP_KEYIVCONFIG_ALWAYS) || \ + ((CONFIG) == CRYP_KEYNOCONFIG) || \ + ((CONFIG) == CRYP_IVCONFIG_ONCE) || \ + ((CONFIG) == CRYP_KEYIVCONFIG_ONCE)) + +#define IS_CRYP_BUFFERSIZE(ALGO, DATAWIDTH, SIZE) \ + (((((ALGO) == CRYP_AES_CTR)) && \ + ((((DATAWIDTH) == CRYP_DATAWIDTHUNIT_WORD) && (((SIZE) % 4U) == 0U)) || \ + (((DATAWIDTH) == CRYP_DATAWIDTHUNIT_BYTE) && (((SIZE) % 16U) == 0U)))) || \ + (((ALGO) == CRYP_AES_ECB) || ((ALGO) == CRYP_AES_CBC) || \ + ((ALGO)== CRYP_AES_GCM_GMAC) || ((ALGO) == CRYP_AES_CCM))) + + +/** + * @} + */ + + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup CRYP_Private_Constants CRYP Private Constants + * @{ + */ + +/** + * @} + */ +/* Private defines -----------------------------------------------------------*/ +/** @defgroup CRYP_Private_Defines CRYP Private Defines + * @{ + */ + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup CRYP_Private_Variables CRYP Private Variables + * @{ + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup CRYP_Private_Functions CRYP Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* AES */ +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_CRYP_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_cryp_ex.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_cryp_ex.h new file mode 100644 index 0000000000..4b29c963ab --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_cryp_ex.h @@ -0,0 +1,154 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_cryp_ex.h + * @author MCD Application Team + * @brief Header file of CRYPEx HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_CRYP_EX_H +#define STM32H5xx_HAL_CRYP_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +#if defined(AES) + +/** @defgroup CRYPEx CRYPEx + * @brief CRYP Extension HAL module driver. + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup CRYPEx_Exported_Types CRYPEx Exported Types + * @{ + */ + +/** + * @} + */ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup CRYPEx_Exported_Constants CRYPEx Constants + * @{ + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/** @defgroup CRYPEx_Private_Types CRYPEx Private Types + * @{ + */ + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup CRYPEx_Private_Variables CRYPEx Private Variables + * @{ + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup CRYPEx_Private_Constants CRYPEx Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup CRYPEx_Private_Macros CRYPEx Private Macros + * @{ + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup CRYPEx_Private_Functions CRYPEx Private Functions + * @{ + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup CRYPEx_Exported_Functions CRYPEx Exported Functions + * @{ + */ + +/** @addtogroup CRYPEx_Exported_Functions_Group1 Extended AES processing functions + * @{ + */ +HAL_StatusTypeDef HAL_CRYPEx_AESGCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, const uint32_t *pAuthTag, + uint32_t Timeout); +HAL_StatusTypeDef HAL_CRYPEx_AESCCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, const uint32_t *pAuthTag, + uint32_t Timeout); +/** + * @} + */ + +/** @addtogroup CRYPEx_Exported_Functions_Group2 Wrap and Unwrap key functions + * @{ + */ +HAL_StatusTypeDef HAL_CRYPEx_UnwrapKey(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint32_t Timeout); +HAL_StatusTypeDef HAL_CRYPEx_WrapKey(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint32_t *pOutput, uint32_t Timeout); +/** + * @} + */ + +/** @addtogroup CRYPEx_Exported_Functions_Group3 Encrypt and Decrypt Shared key functions + * @{ + */ +HAL_StatusTypeDef HAL_CRYPEx_EncryptSharedKey(CRYP_HandleTypeDef *hcryp, uint32_t *pKey, uint32_t *pOutput, uint32_t ID, + uint32_t Timeout); +HAL_StatusTypeDef HAL_CRYPEx_DecryptSharedKey(CRYP_HandleTypeDef *hcryp, uint32_t *pKey, uint32_t ID, uint32_t Timeout); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* AES */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_CRYP_EX_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_dac.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_dac.h new file mode 100644 index 0000000000..d147af57fb --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_dac.h @@ -0,0 +1,593 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_dac.h + * @author MCD Application Team + * @brief Header file of DAC HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_DAC_H +#define STM32H5xx_HAL_DAC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +#if defined(DAC1) + +/** @addtogroup DAC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup DAC_Exported_Types DAC Exported Types + * @{ + */ + +/** + * @brief HAL State structures definition + */ +typedef enum +{ + HAL_DAC_STATE_RESET = 0x00U, /*!< DAC not yet initialized or disabled */ + HAL_DAC_STATE_READY = 0x01U, /*!< DAC initialized and ready for use */ + HAL_DAC_STATE_BUSY = 0x02U, /*!< DAC internal processing is ongoing */ + HAL_DAC_STATE_TIMEOUT = 0x03U, /*!< DAC timeout state */ + HAL_DAC_STATE_ERROR = 0x04U /*!< DAC error state */ + +} HAL_DAC_StateTypeDef; + +/** + * @brief DAC handle Structure definition + */ +#if (USE_HAL_DAC_REGISTER_CALLBACKS == 1) +typedef struct __DAC_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_DAC_REGISTER_CALLBACKS */ +{ + DAC_TypeDef *Instance; /*!< Register base address */ + + __IO HAL_DAC_StateTypeDef State; /*!< DAC communication state */ + + HAL_LockTypeDef Lock; /*!< DAC locking object */ + + DMA_HandleTypeDef *DMA_Handle1; /*!< Pointer DMA handler for channel 1 */ + + DMA_HandleTypeDef *DMA_Handle2; /*!< Pointer DMA handler for channel 2 */ + + __IO uint32_t ErrorCode; /*!< DAC Error code */ + +#if (USE_HAL_DAC_REGISTER_CALLBACKS == 1) + void (* ConvCpltCallbackCh1)(struct __DAC_HandleTypeDef *hdac); + void (* ConvHalfCpltCallbackCh1)(struct __DAC_HandleTypeDef *hdac); + void (* ErrorCallbackCh1)(struct __DAC_HandleTypeDef *hdac); + void (* DMAUnderrunCallbackCh1)(struct __DAC_HandleTypeDef *hdac); + + void (* ConvCpltCallbackCh2)(struct __DAC_HandleTypeDef *hdac); + void (* ConvHalfCpltCallbackCh2)(struct __DAC_HandleTypeDef *hdac); + void (* ErrorCallbackCh2)(struct __DAC_HandleTypeDef *hdac); + void (* DMAUnderrunCallbackCh2)(struct __DAC_HandleTypeDef *hdac); + + + void (* MspInitCallback)(struct __DAC_HandleTypeDef *hdac); + void (* MspDeInitCallback)(struct __DAC_HandleTypeDef *hdac); +#endif /* USE_HAL_DAC_REGISTER_CALLBACKS */ + +} DAC_HandleTypeDef; + +/** + * @brief DAC Configuration sample and hold Channel structure definition + */ +typedef struct +{ + uint32_t DAC_SampleTime ; /*!< Specifies the Sample time for the selected channel. + This parameter applies when DAC_SampleAndHold is DAC_SAMPLEANDHOLD_ENABLE. + This parameter must be a number between Min_Data = 0 and Max_Data = 1023 */ + + uint32_t DAC_HoldTime ; /*!< Specifies the hold time for the selected channel + This parameter applies when DAC_SampleAndHold is DAC_SAMPLEANDHOLD_ENABLE. + This parameter must be a number between Min_Data = 0 and Max_Data = 1023 */ + + uint32_t DAC_RefreshTime ; /*!< Specifies the refresh time for the selected channel + This parameter applies when DAC_SampleAndHold is DAC_SAMPLEANDHOLD_ENABLE. + This parameter must be a number between Min_Data = 0 and Max_Data = 255 */ +} DAC_SampleAndHoldConfTypeDef; + +/** + * @brief DAC Configuration regular Channel structure definition + */ +typedef struct +{ + uint32_t DAC_HighFrequency; /*!< Specifies the frequency interface mode + This parameter can be a value of @ref DAC_HighFrequency */ + + FunctionalState DAC_DMADoubleDataMode; /*!< Specifies if DMA double data mode should be enabled or not for the selected channel. + This parameter can be ENABLE or DISABLE */ + + FunctionalState DAC_SignedFormat; /*!< Specifies if signed format should be used or not for the selected channel. + This parameter can be ENABLE or DISABLE */ + + uint32_t DAC_SampleAndHold; /*!< Specifies whether the DAC mode. + This parameter can be a value of @ref DAC_SampleAndHold */ + + uint32_t DAC_Trigger; /*!< Specifies the external trigger for the selected DAC channel. + This parameter can be a value of @ref DAC_trigger_selection */ + + uint32_t DAC_OutputBuffer; /*!< Specifies whether the DAC channel output buffer is enabled or disabled. + This parameter can be a value of @ref DAC_output_buffer */ + + uint32_t DAC_ConnectOnChipPeripheral ; /*!< Specifies whether the DAC output is connected or not to on chip peripheral. + This parameter can be a value of @ref DAC_ConnectOnChipPeripheral */ + + uint32_t DAC_UserTrimming; /*!< Specifies the trimming mode + This parameter must be a value of @ref DAC_UserTrimming + DAC_UserTrimming is either factory or user trimming */ + + uint32_t DAC_TrimmingValue; /*!< Specifies the offset trimming value + i.e. when DAC_SampleAndHold is DAC_TRIMMING_USER. + This parameter must be a number between Min_Data = 1 and Max_Data = 31 */ + DAC_SampleAndHoldConfTypeDef DAC_SampleAndHoldConfig; /*!< Sample and Hold settings */ +} DAC_ChannelConfTypeDef; + +#if (USE_HAL_DAC_REGISTER_CALLBACKS == 1) +/** + * @brief HAL DAC Callback ID enumeration definition + */ +typedef enum +{ + HAL_DAC_CH1_COMPLETE_CB_ID = 0x00U, /*!< DAC CH1 Complete Callback ID */ + HAL_DAC_CH1_HALF_COMPLETE_CB_ID = 0x01U, /*!< DAC CH1 half Complete Callback ID */ + HAL_DAC_CH1_ERROR_ID = 0x02U, /*!< DAC CH1 error Callback ID */ + HAL_DAC_CH1_UNDERRUN_CB_ID = 0x03U, /*!< DAC CH1 underrun Callback ID */ + + HAL_DAC_CH2_COMPLETE_CB_ID = 0x04U, /*!< DAC CH2 Complete Callback ID */ + HAL_DAC_CH2_HALF_COMPLETE_CB_ID = 0x05U, /*!< DAC CH2 half Complete Callback ID */ + HAL_DAC_CH2_ERROR_ID = 0x06U, /*!< DAC CH2 error Callback ID */ + HAL_DAC_CH2_UNDERRUN_CB_ID = 0x07U, /*!< DAC CH2 underrun Callback ID */ + + HAL_DAC_MSPINIT_CB_ID = 0x08U, /*!< DAC MspInit Callback ID */ + HAL_DAC_MSPDEINIT_CB_ID = 0x09U, /*!< DAC MspDeInit Callback ID */ + HAL_DAC_ALL_CB_ID = 0x0AU /*!< DAC All ID */ +} HAL_DAC_CallbackIDTypeDef; + +/** + * @brief HAL DAC Callback pointer definition + */ +typedef void (*pDAC_CallbackTypeDef)(DAC_HandleTypeDef *hdac); +#endif /* USE_HAL_DAC_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup DAC_Exported_Constants DAC Exported Constants + * @{ + */ + +/** @defgroup DAC_Error_Code DAC Error Code + * @{ + */ +#define HAL_DAC_ERROR_NONE 0x00U /*!< No error */ +#define HAL_DAC_ERROR_DMAUNDERRUNCH1 0x01U /*!< DAC channel1 DMA underrun error */ +#define HAL_DAC_ERROR_DMAUNDERRUNCH2 0x02U /*!< DAC channel2 DMA underrun error */ +#define HAL_DAC_ERROR_DMA 0x04U /*!< DMA error */ +#define HAL_DAC_ERROR_TIMEOUT 0x08U /*!< Timeout error */ +#if (USE_HAL_DAC_REGISTER_CALLBACKS == 1) +#define HAL_DAC_ERROR_INVALID_CALLBACK 0x10U /*!< Invalid callback error */ +#endif /* USE_HAL_DAC_REGISTER_CALLBACKS */ +#define HAL_DAC_ERROR_INVALID_CONFIG 0x20U /*!< Invalid configuration error */ + +/** + * @} + */ + +/** @defgroup DAC_trigger_selection DAC trigger selection + * @{ + */ +/* Triggers common to all devices of STM32H5 series */ +#define DAC_TRIGGER_NONE 0x00000000UL /*!< conversion is automatic once the DAC_DHRxxxx register has been loaded, and not by external trigger */ +#define DAC_TRIGGER_SOFTWARE ( DAC_CR_TEN1) /*!< conversion started by software trigger for DAC channel */ +#define DAC_TRIGGER_T1_TRGO ( DAC_CR_TSEL1_0 | DAC_CR_TEN1) /*!< TIM1 TRGO selected as external conversion trigger for DAC channel. */ +#define DAC_TRIGGER_T2_TRGO ( DAC_CR_TSEL1_1 | DAC_CR_TEN1) /*!< TIM2 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_TRIGGER_T6_TRGO ( DAC_CR_TSEL1_2 | DAC_CR_TSEL1_0 | DAC_CR_TEN1) /*!< TIM6 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_TRIGGER_T7_TRGO ( DAC_CR_TSEL1_2 | DAC_CR_TSEL1_1 | DAC_CR_TEN1) /*!< TIM7 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_TRIGGER_LPTIM1_CH1 (DAC_CR_TSEL1_3 | DAC_CR_TSEL1_1 | DAC_CR_TSEL1_0 | DAC_CR_TEN1) /*!< LPTIM1 CH1 selected as external conversion trigger for DAC channel */ +#define DAC_TRIGGER_LPTIM2_CH1 (DAC_CR_TSEL1_3 | DAC_CR_TSEL1_2 | DAC_CR_TEN1) /*!< LPTIM2 CH1 selected as external conversion trigger for DAC channel */ +#define DAC_TRIGGER_EXT_IT9 (DAC_CR_TSEL1_3 | DAC_CR_TSEL1_2 | DAC_CR_TSEL1_0 | DAC_CR_TEN1) /*!< EXTI Line9 event selected as external conversion trigger for DAC channel */ + +/* Triggers specific to some devices of STM32H5 series */ +#if defined(TIM8) +/* Devices STM32H563/H573xx */ +#define DAC_TRIGGER_T4_TRGO ( DAC_CR_TSEL1_1 | DAC_CR_TSEL1_0 | DAC_CR_TEN1) /*!< TIM4 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_TRIGGER_T5_TRGO ( DAC_CR_TSEL1_2 | DAC_CR_TEN1) /*!< TIM5 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_TRIGGER_T8_TRGO ( DAC_CR_TSEL1_2 | DAC_CR_TSEL1_1 | DAC_CR_TSEL1_0 | DAC_CR_TEN1) /*!< TIM8 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_TRIGGER_T15_TRGO (DAC_CR_TSEL1_3 | DAC_CR_TEN1) /*!< TIM15 TRGO selected as external conversion trigger for DAC channel */ +#else +/* Devices STM32H503xx */ +#define DAC_TRIGGER_T3_TRGO ( DAC_CR_TSEL1_1 | DAC_CR_TSEL1_0 | DAC_CR_TEN1) /*!< TIM3 TRGO selected as external conversion trigger for DAC channel */ + +#endif /* Devices STM32H563/H573xx or STM32H503xx */ + +/** + * @} + */ + +/** @defgroup DAC_output_buffer DAC output buffer + * @{ + */ +#define DAC_OUTPUTBUFFER_ENABLE 0x00000000U +#define DAC_OUTPUTBUFFER_DISABLE (DAC_MCR_MODE1_1) + +/** + * @} + */ + +/** @defgroup DAC_Channel_selection DAC Channel selection + * @{ + */ +#define DAC_CHANNEL_1 0x00000000U + +#define DAC_CHANNEL_2 0x00000010U + +/** + * @} + */ + +/** @defgroup DAC_data_alignment DAC data alignment + * @{ + */ +#define DAC_ALIGN_12B_R 0x00000000U +#define DAC_ALIGN_12B_L 0x00000004U +#define DAC_ALIGN_8B_R 0x00000008U + +/** + * @} + */ + +/** @defgroup DAC_flags_definition DAC flags definition + * @{ + */ +#define DAC_FLAG_DMAUDR1 (DAC_SR_DMAUDR1) + +#define DAC_FLAG_DMAUDR2 (DAC_SR_DMAUDR2) + +#define DAC_FLAG_DAC1RDY (DAC_SR_DAC1RDY) + +#define DAC_FLAG_DAC2RDY (DAC_SR_DAC2RDY) + + +/** + * @} + */ + +/** @defgroup DAC_IT_definition DAC IT definition + * @{ + */ +#define DAC_IT_DMAUDR1 (DAC_SR_DMAUDR1) + +#define DAC_IT_DMAUDR2 (DAC_SR_DMAUDR2) + + +/** + * @} + */ + +/** @defgroup DAC_ConnectOnChipPeripheral DAC ConnectOnChipPeripheral + * @{ + */ +#define DAC_CHIPCONNECT_EXTERNAL (1UL << 0) +#define DAC_CHIPCONNECT_INTERNAL (1UL << 1) +#define DAC_CHIPCONNECT_BOTH (1UL << 2) + +/** + * @} + */ + +/** @defgroup DAC_UserTrimming DAC User Trimming + * @{ + */ +#define DAC_TRIMMING_FACTORY (0x00000000UL) /*!< Factory trimming */ +#define DAC_TRIMMING_USER (0x00000001UL) /*!< User trimming */ +/** + * @} + */ + +/** @defgroup DAC_SampleAndHold DAC power mode + * @{ + */ +#define DAC_SAMPLEANDHOLD_DISABLE (0x00000000UL) +#define DAC_SAMPLEANDHOLD_ENABLE (DAC_MCR_MODE1_2) + +/** + * @} + */ +/** @defgroup DAC_HighFrequency DAC high frequency interface mode + * @{ + */ +#define DAC_HIGH_FREQUENCY_INTERFACE_MODE_DISABLE 0x00000000UL /*!< High frequency interface mode disabled */ +#define DAC_HIGH_FREQUENCY_INTERFACE_MODE_ABOVE_80MHZ (DAC_MCR_HFSEL_0) /*!< High frequency interface mode compatible to AHB>80MHz enabled */ +#define DAC_HIGH_FREQUENCY_INTERFACE_MODE_ABOVE_160MHZ (DAC_MCR_HFSEL_1) /*!< High frequency interface mode compatible to AHB>160MHz enabled */ +#define DAC_HIGH_FREQUENCY_INTERFACE_MODE_AUTOMATIC 0x00000002UL /*!< High frequency interface mode automatic */ + +/** + * @} + */ + +/** + * @} + */ + +/* Delay for DAC channel voltage settling time from DAC channel startup */ +/* (transition from disable to enable). */ +/* Note: DAC channel startup time depends on board application environment: */ +/* impedance connected to DAC channel output. */ +/* The delay below is specified under conditions: */ +/* - voltage maximum transition (lowest to highest value) */ +/* - until voltage reaches final value +-1LSB */ +/* - DAC channel output buffer enabled */ +/* - load impedance of 5kOhm (min), 50pF (max) */ +/* Literal set to maximum value (refer to device datasheet, */ +/* parameter "tWAKEUP"). */ +/* Unit: us */ +#define DAC_DELAY_STARTUP_US (15UL) /*!< Delay for DAC channel voltage settling time from DAC channel startup (transition from disable to enable) */ + +/* Exported macro ------------------------------------------------------------*/ + +/** @defgroup DAC_Exported_Macros DAC Exported Macros + * @{ + */ + +/** @brief Reset DAC handle state. + * @param __HANDLE__ specifies the DAC handle. + * @retval None + */ +#if (USE_HAL_DAC_REGISTER_CALLBACKS == 1) +#define __HAL_DAC_RESET_HANDLE_STATE(__HANDLE__) do { \ + (__HANDLE__)->State = HAL_DAC_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_DAC_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_DAC_STATE_RESET) +#endif /* USE_HAL_DAC_REGISTER_CALLBACKS */ + +/** @brief Enable the DAC channel. + * @param __HANDLE__ specifies the DAC handle. + * @param __DAC_Channel__ specifies the DAC channel + * @retval None + */ +#define __HAL_DAC_ENABLE(__HANDLE__, __DAC_Channel__) \ + ((__HANDLE__)->Instance->CR |= (DAC_CR_EN1 << ((__DAC_Channel__) & 0x10UL))) + +/** @brief Disable the DAC channel. + * @param __HANDLE__ specifies the DAC handle + * @param __DAC_Channel__ specifies the DAC channel. + * @retval None + */ +#define __HAL_DAC_DISABLE(__HANDLE__, __DAC_Channel__) \ + ((__HANDLE__)->Instance->CR &= ~(DAC_CR_EN1 << ((__DAC_Channel__) & 0x10UL))) + +/** @brief Set DHR12R1 alignment. + * @param __ALIGNMENT__ specifies the DAC alignment + * @retval None + */ +#define DAC_DHR12R1_ALIGNMENT(__ALIGNMENT__) (0x00000008UL + (__ALIGNMENT__)) + + +/** @brief Set DHR12R2 alignment. + * @param __ALIGNMENT__ specifies the DAC alignment + * @retval None + */ +#define DAC_DHR12R2_ALIGNMENT(__ALIGNMENT__) (0x00000014UL + (__ALIGNMENT__)) + + +/** @brief Set DHR12RD alignment. + * @param __ALIGNMENT__ specifies the DAC alignment + * @retval None + */ +#define DAC_DHR12RD_ALIGNMENT(__ALIGNMENT__) (0x00000020UL + (__ALIGNMENT__)) + +/** @brief Enable the DAC interrupt. + * @param __HANDLE__ specifies the DAC handle + * @param __INTERRUPT__ specifies the DAC interrupt. + * This parameter can be any combination of the following values: + * @arg DAC_IT_DMAUDR1 DAC channel 1 DMA underrun interrupt + * @arg DAC_IT_DMAUDR2 DAC channel 2 DMA underrun interrupt + * @retval None + */ +#define __HAL_DAC_ENABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->CR) |= (__INTERRUPT__)) + +/** @brief Disable the DAC interrupt. + * @param __HANDLE__ specifies the DAC handle + * @param __INTERRUPT__ specifies the DAC interrupt. + * This parameter can be any combination of the following values: + * @arg DAC_IT_DMAUDR1 DAC channel 1 DMA underrun interrupt + * @arg DAC_IT_DMAUDR2 DAC channel 2 DMA underrun interrupt + * @retval None + */ +#define __HAL_DAC_DISABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->CR) &= ~(__INTERRUPT__)) + +/** @brief Check whether the specified DAC interrupt source is enabled or not. + * @param __HANDLE__ DAC handle + * @param __INTERRUPT__ DAC interrupt source to check + * This parameter can be any combination of the following values: + * @arg DAC_IT_DMAUDR1 DAC channel 1 DMA underrun interrupt + * @arg DAC_IT_DMAUDR2 DAC channel 2 DMA underrun interrupt + * @retval State of interruption (SET or RESET) + */ +#define __HAL_DAC_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->CR\ + & (__INTERRUPT__)) == (__INTERRUPT__)) + +/** @brief Get the selected DAC's flag status. + * @param __HANDLE__ specifies the DAC handle. + * @param __FLAG__ specifies the DAC flag to get. + * This parameter can be any combination of the following values: + * @arg DAC_FLAG_DMAUDR1 DAC channel 1 DMA underrun flag + * @arg DAC_FLAG_DMAUDR2 DAC channel 2 DMA underrun flag + * @arg DAC_FLAG_DAC1RDY DAC channel 1 ready status flag + * @arg DAC_FLAG_DAC2RDY DAC channel 2 ready status flag + * @retval None + */ +#define __HAL_DAC_GET_FLAG(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->SR) & (__FLAG__)) == (__FLAG__)) + +/** @brief Clear the DAC's flag. + * @param __HANDLE__ specifies the DAC handle. + * @param __FLAG__ specifies the DAC flag to clear. + * This parameter can be any combination of the following values: + * @arg DAC_FLAG_DMAUDR1 DAC channel 1 DMA underrun flag + * @arg DAC_FLAG_DMAUDR2 DAC channel 2 DMA underrun flag + * @retval None + */ +#define __HAL_DAC_CLEAR_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR) = (__FLAG__)) + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ + +/** @defgroup DAC_Private_Macros DAC Private Macros + * @{ + */ +#define IS_DAC_OUTPUT_BUFFER_STATE(STATE) (((STATE) == DAC_OUTPUTBUFFER_ENABLE) || \ + ((STATE) == DAC_OUTPUTBUFFER_DISABLE)) + +#define IS_DAC_CHANNEL(CHANNEL) (((CHANNEL) == DAC_CHANNEL_1) || \ + ((CHANNEL) == DAC_CHANNEL_2)) + +#define IS_DAC_ALIGN(ALIGN) (((ALIGN) == DAC_ALIGN_12B_R) || \ + ((ALIGN) == DAC_ALIGN_12B_L) || \ + ((ALIGN) == DAC_ALIGN_8B_R)) + +#define IS_DAC_DATA(DATA) ((DATA) <= 0xFFF0UL) + +#define IS_DAC_REFRESHTIME(TIME) ((TIME) <= 0x000000FFUL) + +/** + * @} + */ + +/* Include DAC HAL Extended module */ +#include "stm32h5xx_hal_dac_ex.h" + +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup DAC_Exported_Functions + * @{ + */ + +/** @addtogroup DAC_Exported_Functions_Group1 + * @{ + */ +/* Initialization and de-initialization functions *****************************/ +HAL_StatusTypeDef HAL_DAC_Init(DAC_HandleTypeDef *hdac); +HAL_StatusTypeDef HAL_DAC_DeInit(DAC_HandleTypeDef *hdac); +void HAL_DAC_MspInit(DAC_HandleTypeDef *hdac); +void HAL_DAC_MspDeInit(DAC_HandleTypeDef *hdac); + +/** + * @} + */ + +/** @addtogroup DAC_Exported_Functions_Group2 + * @{ + */ +/* IO operation functions *****************************************************/ +HAL_StatusTypeDef HAL_DAC_Start(DAC_HandleTypeDef *hdac, uint32_t Channel); +HAL_StatusTypeDef HAL_DAC_Stop(DAC_HandleTypeDef *hdac, uint32_t Channel); +HAL_StatusTypeDef HAL_DAC_Start_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel, const uint32_t *pData, uint32_t Length, + uint32_t Alignment); +HAL_StatusTypeDef HAL_DAC_Stop_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel); +void HAL_DAC_IRQHandler(DAC_HandleTypeDef *hdac); +HAL_StatusTypeDef HAL_DAC_SetValue(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Alignment, uint32_t Data); + +void HAL_DAC_ConvCpltCallbackCh1(DAC_HandleTypeDef *hdac); +void HAL_DAC_ConvHalfCpltCallbackCh1(DAC_HandleTypeDef *hdac); +void HAL_DAC_ErrorCallbackCh1(DAC_HandleTypeDef *hdac); +void HAL_DAC_DMAUnderrunCallbackCh1(DAC_HandleTypeDef *hdac); + +#if (USE_HAL_DAC_REGISTER_CALLBACKS == 1) +/* DAC callback registering/unregistering */ +HAL_StatusTypeDef HAL_DAC_RegisterCallback(DAC_HandleTypeDef *hdac, HAL_DAC_CallbackIDTypeDef CallbackID, + pDAC_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_DAC_UnRegisterCallback(DAC_HandleTypeDef *hdac, HAL_DAC_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_DAC_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @addtogroup DAC_Exported_Functions_Group3 + * @{ + */ +/* Peripheral Control functions ***********************************************/ +uint32_t HAL_DAC_GetValue(const DAC_HandleTypeDef *hdac, uint32_t Channel); +HAL_StatusTypeDef HAL_DAC_ConfigChannel(DAC_HandleTypeDef *hdac, + const DAC_ChannelConfTypeDef *sConfig, uint32_t Channel); +/** + * @} + */ + +/** @addtogroup DAC_Exported_Functions_Group4 + * @{ + */ +/* Peripheral State and Error functions ***************************************/ +HAL_DAC_StateTypeDef HAL_DAC_GetState(const DAC_HandleTypeDef *hdac); +uint32_t HAL_DAC_GetError(const DAC_HandleTypeDef *hdac); + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup DAC_Private_Functions DAC Private Functions + * @{ + */ +void DAC_DMAConvCpltCh1(DMA_HandleTypeDef *hdma); +void DAC_DMAErrorCh1(DMA_HandleTypeDef *hdma); +void DAC_DMAHalfConvCpltCh1(DMA_HandleTypeDef *hdma); +/** + * @} + */ + +/** + * @} + */ + +#endif /* DAC1 */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* STM32H5xx_HAL_DAC_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_dac_ex.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_dac_ex.h new file mode 100644 index 0000000000..b98351b746 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_dac_ex.h @@ -0,0 +1,256 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_dac_ex.h + * @author MCD Application Team + * @brief Header file of DAC HAL Extended module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_DAC_EX_H +#define STM32H5xx_HAL_DAC_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +#if defined(DAC1) + +/** @addtogroup DACEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief HAL State structures definition + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup DACEx_Exported_Constants DACEx Exported Constants + * @{ + */ + +/** @defgroup DACEx_lfsrunmask_triangleamplitude DACEx lfsrunmask triangle amplitude + * @{ + */ +#define DAC_LFSRUNMASK_BIT0 0x00000000UL /*!< Unmask DAC channel LFSR bit0 for noise wave generation */ +#define DAC_LFSRUNMASK_BITS1_0 ( DAC_CR_MAMP1_0) /*!< Unmask DAC channel LFSR bit[1:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS2_0 ( DAC_CR_MAMP1_1 ) /*!< Unmask DAC channel LFSR bit[2:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS3_0 ( DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Unmask DAC channel LFSR bit[3:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS4_0 ( DAC_CR_MAMP1_2 ) /*!< Unmask DAC channel LFSR bit[4:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS5_0 ( DAC_CR_MAMP1_2 | DAC_CR_MAMP1_0) /*!< Unmask DAC channel LFSR bit[5:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS6_0 ( DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1 ) /*!< Unmask DAC channel LFSR bit[6:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS7_0 ( DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Unmask DAC channel LFSR bit[7:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS8_0 (DAC_CR_MAMP1_3 ) /*!< Unmask DAC channel LFSR bit[8:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS9_0 (DAC_CR_MAMP1_3 | DAC_CR_MAMP1_0) /*!< Unmask DAC channel LFSR bit[9:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS10_0 (DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1 ) /*!< Unmask DAC channel LFSR bit[10:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS11_0 (DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Unmask DAC channel LFSR bit[11:0] for noise wave generation */ +#define DAC_TRIANGLEAMPLITUDE_1 0x00000000UL /*!< Select max triangle amplitude of 1 */ +#define DAC_TRIANGLEAMPLITUDE_3 ( DAC_CR_MAMP1_0) /*!< Select max triangle amplitude of 3 */ +#define DAC_TRIANGLEAMPLITUDE_7 ( DAC_CR_MAMP1_1 ) /*!< Select max triangle amplitude of 7 */ +#define DAC_TRIANGLEAMPLITUDE_15 ( DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Select max triangle amplitude of 15 */ +#define DAC_TRIANGLEAMPLITUDE_31 ( DAC_CR_MAMP1_2 ) /*!< Select max triangle amplitude of 31 */ +#define DAC_TRIANGLEAMPLITUDE_63 ( DAC_CR_MAMP1_2 | DAC_CR_MAMP1_0) /*!< Select max triangle amplitude of 63 */ +#define DAC_TRIANGLEAMPLITUDE_127 ( DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1 ) /*!< Select max triangle amplitude of 127 */ +#define DAC_TRIANGLEAMPLITUDE_255 ( DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Select max triangle amplitude of 255 */ +#define DAC_TRIANGLEAMPLITUDE_511 (DAC_CR_MAMP1_3 ) /*!< Select max triangle amplitude of 511 */ +#define DAC_TRIANGLEAMPLITUDE_1023 (DAC_CR_MAMP1_3 | DAC_CR_MAMP1_0) /*!< Select max triangle amplitude of 1023 */ +#define DAC_TRIANGLEAMPLITUDE_2047 (DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1 ) /*!< Select max triangle amplitude of 2047 */ +#define DAC_TRIANGLEAMPLITUDE_4095 (DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Select max triangle amplitude of 4095 */ + +/** + * @} + */ + + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ + + +/* Private macro -------------------------------------------------------------*/ + +/** @defgroup DACEx_Private_Macros DACEx Private Macros + * @{ + */ +#if defined(TIM8) +/* Devices STM32H563/H573xx */ +#define IS_DAC_TRIGGER(TRIGGER) (((TRIGGER) == DAC_TRIGGER_NONE) || \ + ((TRIGGER) == DAC_TRIGGER_T1_TRGO) || \ + ((TRIGGER) == DAC_TRIGGER_T2_TRGO) || \ + ((TRIGGER) == DAC_TRIGGER_T4_TRGO) || \ + ((TRIGGER) == DAC_TRIGGER_T5_TRGO) || \ + ((TRIGGER) == DAC_TRIGGER_T6_TRGO) || \ + ((TRIGGER) == DAC_TRIGGER_T7_TRGO) || \ + ((TRIGGER) == DAC_TRIGGER_T8_TRGO) || \ + ((TRIGGER) == DAC_TRIGGER_T15_TRGO) || \ + ((TRIGGER) == DAC_TRIGGER_LPTIM1_CH1) || \ + ((TRIGGER) == DAC_TRIGGER_LPTIM2_CH1) || \ + ((TRIGGER) == DAC_TRIGGER_EXT_IT9) || \ + ((TRIGGER) == DAC_TRIGGER_SOFTWARE)) +#else +/* Devices STM32H503xx */ +#define IS_DAC_TRIGGER(TRIGGER) (((TRIGGER) == DAC_TRIGGER_NONE) || \ + ((TRIGGER) == DAC_TRIGGER_T1_TRGO) || \ + ((TRIGGER) == DAC_TRIGGER_T2_TRGO) || \ + ((TRIGGER) == DAC_TRIGGER_T3_TRGO) || \ + ((TRIGGER) == DAC_TRIGGER_T6_TRGO) || \ + ((TRIGGER) == DAC_TRIGGER_T7_TRGO) || \ + ((TRIGGER) == DAC_TRIGGER_LPTIM1_CH1) || \ + ((TRIGGER) == DAC_TRIGGER_LPTIM2_CH1) || \ + ((TRIGGER) == DAC_TRIGGER_EXT_IT9) || \ + ((TRIGGER) == DAC_TRIGGER_SOFTWARE)) +#endif /* Devices STM32H563/H573xx or STM32H503xx */ + +#define IS_DAC_HIGH_FREQUENCY_MODE(MODE) (((MODE) == DAC_HIGH_FREQUENCY_INTERFACE_MODE_DISABLE) || \ + ((MODE) == DAC_HIGH_FREQUENCY_INTERFACE_MODE_ABOVE_80MHZ) || \ + ((MODE) == DAC_HIGH_FREQUENCY_INTERFACE_MODE_ABOVE_160MHZ) || \ + ((MODE) == DAC_HIGH_FREQUENCY_INTERFACE_MODE_AUTOMATIC)) + +#define IS_DAC_SAMPLETIME(TIME) ((TIME) <= 0x000003FFU) + +#define IS_DAC_HOLDTIME(TIME) ((TIME) <= 0x000003FFU) + +#define IS_DAC_SAMPLEANDHOLD(MODE) (((MODE) == DAC_SAMPLEANDHOLD_DISABLE) || \ + ((MODE) == DAC_SAMPLEANDHOLD_ENABLE)) + +#define IS_DAC_TRIMMINGVALUE(TRIMMINGVALUE) ((TRIMMINGVALUE) <= 0x1FU) + +#define IS_DAC_NEWTRIMMINGVALUE(TRIMMINGVALUE) ((TRIMMINGVALUE) <= 0x1FU) + +#define IS_DAC_CHIP_CONNECTION(CONNECT) (((CONNECT) == DAC_CHIPCONNECT_EXTERNAL) || \ + ((CONNECT) == DAC_CHIPCONNECT_INTERNAL) || \ + ((CONNECT) == DAC_CHIPCONNECT_BOTH)) + +#define IS_DAC_TRIMMING(TRIMMING) (((TRIMMING) == DAC_TRIMMING_FACTORY) || \ + ((TRIMMING) == DAC_TRIMMING_USER)) + +#define IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(VALUE) (((VALUE) == DAC_LFSRUNMASK_BIT0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS1_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS2_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS3_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS4_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS5_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS6_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS7_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS8_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS9_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS10_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS11_0) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_1) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_3) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_7) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_15) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_31) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_63) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_127) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_255) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_511) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_1023) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_2047) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_4095)) +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/* Extended features functions ***********************************************/ + +/** @addtogroup DACEx_Exported_Functions + * @{ + */ + +/** @addtogroup DACEx_Exported_Functions_Group2 + * @{ + */ +/* IO operation functions *****************************************************/ + +HAL_StatusTypeDef HAL_DACEx_TriangleWaveGenerate(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Amplitude); +HAL_StatusTypeDef HAL_DACEx_NoiseWaveGenerate(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Amplitude); + +HAL_StatusTypeDef HAL_DACEx_DualStart(DAC_HandleTypeDef *hdac); +HAL_StatusTypeDef HAL_DACEx_DualStop(DAC_HandleTypeDef *hdac); +HAL_StatusTypeDef HAL_DACEx_DualStart_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel, + const uint32_t *pData, uint32_t Length, uint32_t Alignment); +HAL_StatusTypeDef HAL_DACEx_DualStop_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel); +HAL_StatusTypeDef HAL_DACEx_DualSetValue(DAC_HandleTypeDef *hdac, uint32_t Alignment, uint32_t Data1, uint32_t Data2); +uint32_t HAL_DACEx_DualGetValue(const DAC_HandleTypeDef *hdac); + +void HAL_DACEx_ConvCpltCallbackCh2(DAC_HandleTypeDef *hdac); +void HAL_DACEx_ConvHalfCpltCallbackCh2(DAC_HandleTypeDef *hdac); +void HAL_DACEx_ErrorCallbackCh2(DAC_HandleTypeDef *hdac); +void HAL_DACEx_DMAUnderrunCallbackCh2(DAC_HandleTypeDef *hdac); + + +/** + * @} + */ + +/** @addtogroup DACEx_Exported_Functions_Group3 + * @{ + */ +/* Peripheral Control functions ***********************************************/ + +HAL_StatusTypeDef HAL_DACEx_SelfCalibrate(DAC_HandleTypeDef *hdac, DAC_ChannelConfTypeDef *sConfig, uint32_t Channel); +HAL_StatusTypeDef HAL_DACEx_SetUserTrimming(DAC_HandleTypeDef *hdac, DAC_ChannelConfTypeDef *sConfig, uint32_t Channel, + uint32_t NewTrimmingValue); +uint32_t HAL_DACEx_GetTrimOffset(const DAC_HandleTypeDef *hdac, uint32_t Channel); + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup DACEx_Private_Functions + * @{ + */ + +/* DAC_DMAConvCpltCh2 / DAC_DMAErrorCh2 / DAC_DMAHalfConvCpltCh2 */ +/* are called by HAL_DAC_Start_DMA */ +void DAC_DMAConvCpltCh2(DMA_HandleTypeDef *hdma); +void DAC_DMAErrorCh2(DMA_HandleTypeDef *hdma); +void DAC_DMAHalfConvCpltCh2(DMA_HandleTypeDef *hdma); + +/** + * @} + */ + +/** + * @} + */ + +#endif /* DAC1 */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_DAC_EX_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_dcache.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_dcache.h new file mode 100644 index 0000000000..9c9abc6147 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_dcache.h @@ -0,0 +1,355 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_dcache.h + * @author MCD Application Team + * @brief Header file of DCACHE HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion ------------------------------------*/ +#ifndef STM32H5xx_HAL_DCACHE_H +#define STM32H5xx_HAL_DCACHE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes -----------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +#if defined (DCACHE1) + +/** @addtogroup DCACHE + * @{ + */ +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup DCACHE_Exported_Types DCACHE Exported Types + * @{ + */ + +/** + * @brief DCACHE Init structure definition + */ +typedef struct +{ + uint32_t ReadBurstType; /*!< Burst type to be applied for Data Cache + This parameter can be a value of @ref DCACHE_Read_Burst_Type*/ +} DCACHE_InitTypeDef; + +/** + * @brief HAL State structures definition + */ +typedef enum +{ + HAL_DCACHE_STATE_RESET = 0x00U, /*!< DCACHE not yet initialized or disabled */ + HAL_DCACHE_STATE_READY = 0x01U, /*!< Peripheral initialized and ready for use */ + HAL_DCACHE_STATE_BUSY = 0x02U, /*!< An internal process is ongoing */ + HAL_DCACHE_STATE_TIMEOUT = 0x05U, /*!< Timeout state */ + HAL_DCACHE_STATE_ERROR = 0x06U, /*!< DCACHE state error */ +} HAL_DCACHE_StateTypeDef; + +/** @defgroup DCACHE_Configuration_Structure_definition DCACHE Configuration Structure definition + * @brief DCACHE Configuration Structure definition + * @{ + */ +typedef struct __DCACHE_HandleTypeDef +{ + DCACHE_TypeDef *Instance; /*!< DCACHE register base address. */ + DCACHE_InitTypeDef Init; /*!< DCACHE Initialization Structure. */ + + void (* ErrorCallback)(struct __DCACHE_HandleTypeDef *hdcache); + void (* CleanByAddrCallback)(struct __DCACHE_HandleTypeDef *hdcache); + void (* InvalidateByAddrCallback)(struct __DCACHE_HandleTypeDef *hdcache); + void (* InvalidateCompleteCallback)(struct __DCACHE_HandleTypeDef *hdcache); + void (* CleanAndInvalidateByAddrCallback)(struct __DCACHE_HandleTypeDef *hdcache); + + void (* MspInitCallback)(struct __DCACHE_HandleTypeDef *hdcache); + void (* MspDeInitCallback)(struct __DCACHE_HandleTypeDef *hdcache); + + __IO HAL_DCACHE_StateTypeDef State; + __IO uint32_t ErrorCode; +} DCACHE_HandleTypeDef; + +/** + * @brief HAL DCACHE Callback pointer definition + */ +/*!< Pointer to a DCACHE common callback function */ +typedef void (*pDCACHE_CallbackTypeDef)(DCACHE_HandleTypeDef *hdcache); + +/** + * @brief HAL DCACHE Callback ID enumeration definition + */ +typedef enum +{ + HAL_DCACHE_CLEAN_BY_ADDRESS_CB_ID = 0x00U, /*!< DCACHE Clean By Address callback ID */ + HAL_DCACHE_INVALIDATE_BY_ADDRESS_CB_ID = 0x01U, /*!< DCACHE Invalidate By Address callback ID */ + HAL_DCACHE_CLEAN_AND_INVALIDATE_BY_ADDRESS_CB_ID = 0x02U, /*!< DCACHE Clean And Invalidate By Address callback ID */ + HAL_DCACHE_INVALIDATE_COMPLETE_CB_ID = 0x03U, /*!< DCACHE Invalidate Complete ID */ + HAL_DCACHE_ERROR_CB_ID = 0x04U, /*!< DCACHE Error callback ID */ + + HAL_DCACHE_MSPINIT_CB_ID = 0x05U, /*!< DCACHE Msp Init callback ID */ + HAL_DCACHE_MSPDEINIT_CB_ID = 0x06U /*!< DCACHE Msp DeInit callback ID */ +} HAL_DCACHE_CallbackIDTypeDef; + +/** + * @} + */ + +/** + * @} + */ + +/* Exported constants -------------------------------------------------------*/ +/** @defgroup DCACHE_Exported_Constants DCACHE Exported Constants + * @{ + */ + +/** @defgroup DCACHE_Error_Code DCACHE Error Code + * @{ + */ +#define HAL_DCACHE_ERROR_NONE 0x00000000U /*!< No error */ +#define HAL_DCACHE_ERROR_TIMEOUT 0x00000010U /*!< Timeout error */ +#define HAL_DCACHE_ERROR_INVALID_CALLBACK 0x00000020U /*!< Invalid callback error */ +#define HAL_DCACHE_ERROR_EVICTION_CLEAN 0x00000040U /*!< Eviction or clean operation write-back error */ +#define HAL_DCACHE_ERROR_INVALID_OPERATION 0x00000080U /*!< Invalid operation */ + +/** + * @} + */ + +/** @defgroup DCACHE_Monitor_Type Monitor type + * @{ + */ +#define DCACHE_MONITOR_READ_HIT DCACHE_CR_RHITMEN /*!< Read Hit monitoring */ +#define DCACHE_MONITOR_READ_MISS DCACHE_CR_RMISSMEN /*!< Read Miss monitoring */ +#define DCACHE_MONITOR_WRITE_HIT DCACHE_CR_WHITMEN /*!< Write Hit monitoring */ +#define DCACHE_MONITOR_WRITE_MISS DCACHE_CR_WMISSMEN /*!< Write Miss monitoring */ +#define DCACHE_MONITOR_ALL (DCACHE_CR_RHITMEN | DCACHE_CR_RMISSMEN | \ + DCACHE_CR_WHITMEN | DCACHE_CR_WMISSMEN) +/** + * @} + */ + +/** @defgroup DCACHE_Read_Burst_Type Remapped Output burst type + * @{ + */ +#define DCACHE_READ_BURST_WRAP 0U /*!< WRAP */ +#define DCACHE_READ_BURST_INCR DCACHE_CR_HBURST /*!< INCR */ +/** + * @} + */ + +/** @defgroup DCACHE_Interrupts Interrupts + * @{ + */ +#define DCACHE_IT_BUSYEND DCACHE_IER_BSYENDIE /*!< Busy end interrupt */ +#define DCACHE_IT_ERROR DCACHE_IER_ERRIE /*!< Cache error interrupt */ +#define DCACHE_IT_CMDEND DCACHE_IER_CMDENDIE /*!< Command end interrupt */ +/** + * @} + */ + +/** @defgroup DCACHE_Flags Flags + * @{ + */ +#define DCACHE_FLAG_BUSY DCACHE_SR_BUSYF /*!< Busy flag */ +#define DCACHE_FLAG_BUSYEND DCACHE_SR_BSYENDF /*!< Busy end flag */ +#define DCACHE_FLAG_ERROR DCACHE_SR_ERRF /*!< Cache error flag */ +#define DCACHE_FLAG_BUSYCMD DCACHE_SR_BUSYCMDF /*!< Busy command flag */ +#define DCACHE_FLAG_CMDEND DCACHE_SR_CMDENDF /*!< Command end flag */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros ----------------------------------------------------------*/ +/** @defgroup DCACHE_Exported_Macros DCACHE Exported Macros + * @{ + */ + +/** @brief Enable DCACHE interrupts. + * @param __HANDLE__ specifies the DCACHE handle. + * @param __INTERRUPT__ specifies the DCACHE interrupt sources to be enabled. + * This parameter can be any combination of the following values: + * @arg @ref DCACHE_IT_BUSYEND Busy end interrupt + * @arg @ref DCACHE_IT_ERROR Cache error interrupt + * @arg @ref DCACHE_IT_CMDEND Cache Command end interrupt + * @retval None + */ +#define __HAL_DCACHE_ENABLE_IT(__HANDLE__, __INTERRUPT__) SET_BIT((__HANDLE__)->Instance->IER, (__INTERRUPT__)) + +/** @brief Disable DCACHE interrupts. + * @param __HANDLE__ specifies the DCACHE handle. + * @param __INTERRUPT__ specifies the DCACHE interrupt sources to be disabled. + * This parameter can be any combination of the following values: + * @arg @ref DCACHE_IT_BUSYEND Busy end interrupt + * @arg @ref DCACHE_IT_ERROR Cache error interrupt + * @arg @ref DCACHE_IT_CMDEND Cache Command end interrupt + * @retval None + */ +#define __HAL_DCACHE_DISABLE_IT(__HANDLE__, __INTERRUPT__) CLEAR_BIT((__HANDLE__)->Instance->IER, (__INTERRUPT__)) + +/** @brief Check whether the specified DCACHE interrupt source is enabled or not. + * @param __HANDLE__ specifies the DCACHE handle. + * @param __INTERRUPT__ specifies the DCACHE interrupt source to check. + * This parameter can be any combination of the following values: + * @arg @ref DCACHE_IT_BUSYEND Busy end interrupt + * @arg @ref DCACHE_IT_ERROR Cache error interrupt + * @arg @ref DCACHE_IT_CMDEND Cache Command end interrupt + * + * @retval The state of __INTERRUPT__ (SET or RESET). + */ +#define __HAL_DCACHE_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) \ + ((READ_BIT((__HANDLE__)->Instance->IER, (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) + +/** @brief Check whether the selected DCACHE flag is set or not. + * @param __HANDLE__ specifies the DCACHE handle. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg @ref DCACHE_FLAG_BUSY Busy flag + * @arg @ref DCACHE_FLAG_BUSYEND Busy end flag + * @arg @ref DCACHE_FLAG_ERROR Cache error flag + * @arg @ref DCACHE_FLAG_BUSYCMD Cache Busy command flag + * @arg @ref DCACHE_FLAG_CMDEND Cache command end flag + * @retval The state of __FLAG__ (0 or 1). + */ +#define __HAL_DCACHE_GET_FLAG(__HANDLE__, __FLAG__) ((READ_BIT((__HANDLE__)->Instance->SR, (__FLAG__)) != 0U) ? 1U : 0U) + +/** @brief Clear the selected DCACHE flags. + * @param __HANDLE__ specifies the DCACHE handle. + * @param __FLAG__ specifies the DCACHE flags to clear. + * This parameter can be any combination of the following values: + * @arg @ref DCACHE_FLAG_BUSYEND Busy end flag + * @arg @ref DCACHE_FLAG_ERROR Cache error flag + * @arg @ref DCACHE_FLAG_CMDEND Cache command end flag + */ +#define __HAL_DCACHE_CLEAR_FLAG(__HANDLE__, __FLAG__) WRITE_REG((__HANDLE__)->Instance->FCR, (__FLAG__)) + +/** + * @} + */ + +/* Exported functions -------------------------------------------------------*/ +/** @defgroup DCACHE_Exported_Functions DCACHE Exported Functions + * @brief DCACHE Exported functions + * @{ + */ + +/** @defgroup DCACHE_Exported_Functions_Group1 Initialization and De-Initialization Functions + * @brief Initialization and De-Initialization Functions + * @{ + */ +HAL_StatusTypeDef HAL_DCACHE_Init(DCACHE_HandleTypeDef *hdcache); +HAL_StatusTypeDef HAL_DCACHE_DeInit(DCACHE_HandleTypeDef *hdcache); +void HAL_DCACHE_MspInit(DCACHE_HandleTypeDef *hdcache); +void HAL_DCACHE_MspDeInit(DCACHE_HandleTypeDef *hdcache); +/** + * @} + */ + +/** @defgroup DCACHE_Exported_Functions_Group2 I/O Operation Functions + * @brief I/O Operation Functions + * @{ + */ +/* Peripheral Control functions ***/ +HAL_StatusTypeDef HAL_DCACHE_Enable(DCACHE_HandleTypeDef *hdcache); +HAL_StatusTypeDef HAL_DCACHE_Disable(DCACHE_HandleTypeDef *hdcache); +uint32_t HAL_DCACHE_IsEnabled(const DCACHE_HandleTypeDef *hdcache); +HAL_StatusTypeDef HAL_DCACHE_SetReadBurstType(DCACHE_HandleTypeDef *hdcache, uint32_t ReadBurstType); + +/*** Cache maintenance in blocking mode (Polling) ***/ +HAL_StatusTypeDef HAL_DCACHE_Invalidate(DCACHE_HandleTypeDef *hdcache); +HAL_StatusTypeDef HAL_DCACHE_InvalidateByAddr(DCACHE_HandleTypeDef *hdcache, const uint32_t *const pAddr, + uint32_t dSize); +HAL_StatusTypeDef HAL_DCACHE_CleanByAddr(DCACHE_HandleTypeDef *hdcache, const uint32_t *const pAddr, uint32_t dSize); +HAL_StatusTypeDef HAL_DCACHE_CleanInvalidByAddr(DCACHE_HandleTypeDef *hdcache, const uint32_t *const pAddr, + uint32_t dSize); + +/*** Cache maintenance in non-blocking mode (Interrupt) ***/ +HAL_StatusTypeDef HAL_DCACHE_Invalidate_IT(DCACHE_HandleTypeDef *hdcache); +HAL_StatusTypeDef HAL_DCACHE_InvalidateByAddr_IT(DCACHE_HandleTypeDef *hdcache, const uint32_t *const pAddr, + uint32_t dSize); +HAL_StatusTypeDef HAL_DCACHE_CleanByAddr_IT(DCACHE_HandleTypeDef *hdcache, const uint32_t *const pAddr, + uint32_t dSize); +HAL_StatusTypeDef HAL_DCACHE_CleanInvalidByAddr_IT(DCACHE_HandleTypeDef *hdcache, const uint32_t *const pAddr, + uint32_t dSize); + +/*** IRQHandler and Callbacks ***/ +void HAL_DCACHE_IRQHandler(DCACHE_HandleTypeDef *hdcache); +void HAL_DCACHE_ErrorCallback(DCACHE_HandleTypeDef *hdcache); +void HAL_DCACHE_CleanByAddrCallback(DCACHE_HandleTypeDef *hdcache); +void HAL_DCACHE_InvalidateByAddrCallback(DCACHE_HandleTypeDef *hdcache); +void HAL_DCACHE_InvalidateCompleteCallback(DCACHE_HandleTypeDef *hdcache); +void HAL_DCACHE_CleanAndInvalidateByAddrCallback(DCACHE_HandleTypeDef *hdcache); + +/* Callbacks Register/UnRegister functions ***/ +HAL_StatusTypeDef HAL_DCACHE_RegisterCallback(DCACHE_HandleTypeDef *hdcache, HAL_DCACHE_CallbackIDTypeDef CallbackID, + pDCACHE_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_DCACHE_UnRegisterCallback(DCACHE_HandleTypeDef *hdcache, HAL_DCACHE_CallbackIDTypeDef CallbackID); + +/*** Performance instruction cache monitoring functions ***/ +uint32_t HAL_DCACHE_Monitor_GetReadHitValue(const DCACHE_HandleTypeDef *hdcache); +uint32_t HAL_DCACHE_Monitor_GetReadMissValue(const DCACHE_HandleTypeDef *hdcache); +uint32_t HAL_DCACHE_Monitor_GetWriteHitValue(const DCACHE_HandleTypeDef *hdcache); +uint32_t HAL_DCACHE_Monitor_GetWriteMissValue(const DCACHE_HandleTypeDef *hdcache); +HAL_StatusTypeDef HAL_DCACHE_Monitor_Reset(DCACHE_HandleTypeDef *hdcache, uint32_t MonitorType); +HAL_StatusTypeDef HAL_DCACHE_Monitor_Start(DCACHE_HandleTypeDef *hdcache, uint32_t MonitorType); +HAL_StatusTypeDef HAL_DCACHE_Monitor_Stop(DCACHE_HandleTypeDef *hdcache, uint32_t MonitorType); +/** + * @} + */ + +/** @defgroup DCACHE_Exported_Functions_Group3 State and Error Functions + * @brief State and Error Functions + * @{ + */ +HAL_DCACHE_StateTypeDef HAL_DCACHE_GetState(const DCACHE_HandleTypeDef *hdcache); +uint32_t HAL_DCACHE_GetError(const DCACHE_HandleTypeDef *hdcache); +/** + * @} + */ + +/** + * @} + */ + + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** + * @} + */ + +#endif /* DCACHE1 */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_DCACHE_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_dcmi.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_dcmi.h new file mode 100644 index 0000000000..d912c449a6 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_dcmi.h @@ -0,0 +1,698 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_dcmi.h + * @author MCD Application Team + * @brief Header file of DCMI HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_DCMI_H +#define STM32H5xx_HAL_DCMI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +#if defined (DCMI) + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup DCMI DCMI + * @brief DCMI HAL module driver + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup DCMI_Exported_Types DCMI Exported Types + * @{ + */ +/** + * @brief HAL DCMI State structures definition + */ +typedef enum +{ + HAL_DCMI_STATE_RESET = 0x00U, /*!< DCMI not yet initialized or disabled */ + HAL_DCMI_STATE_READY = 0x01U, /*!< DCMI initialized and ready for use */ + HAL_DCMI_STATE_BUSY = 0x02U, /*!< DCMI internal processing is ongoing */ + HAL_DCMI_STATE_TIMEOUT = 0x03U, /*!< DCMI timeout state */ + HAL_DCMI_STATE_ERROR = 0x04U, /*!< DCMI error state */ + HAL_DCMI_STATE_SUSPENDED = 0x05U /*!< DCMI suspend state */ +} HAL_DCMI_StateTypeDef; + +/** + * @brief DCMI Embedded Synchronisation CODE Init structure definition + */ +typedef struct +{ + uint8_t FrameStartCode; /*!< Specifies the code of the frame start delimiter. */ + uint8_t LineStartCode; /*!< Specifies the code of the line start delimiter. */ + uint8_t LineEndCode; /*!< Specifies the code of the line end delimiter. */ + uint8_t FrameEndCode; /*!< Specifies the code of the frame end delimiter. */ +} DCMI_CodesInitTypeDef; + +/** + * @brief DCMI Embedded Synchronisation UNMASK Init structure definition + */ +typedef struct +{ + uint8_t FrameStartUnmask; /*!< Specifies the frame start delimiter unmask. */ + uint8_t LineStartUnmask; /*!< Specifies the line start delimiter unmask. */ + uint8_t LineEndUnmask; /*!< Specifies the line end delimiter unmask. */ + uint8_t FrameEndUnmask; /*!< Specifies the frame end delimiter unmask. */ +} DCMI_SyncUnmaskTypeDef; +/** + * @brief DCMI Init structure definition + */ +typedef struct +{ + uint32_t SynchroMode; /*!< Specifies the Synchronization Mode: Hardware or Embedded. + This parameter can be a value of @ref DCMI_Synchronization_Mode */ + + uint32_t PCKPolarity; /*!< Specifies the Pixel clock polarity: Falling or Rising. + This parameter can be a value of @ref DCMI_PIXCK_Polarity */ + + uint32_t VSPolarity; /*!< Specifies the Vertical synchronization polarity: High or Low. + This parameter can be a value of @ref DCMI_VSYNC_Polarity */ + + uint32_t HSPolarity; /*!< Specifies the Horizontal synchronization polarity: High or Low. + This parameter can be a value of @ref DCMI_HSYNC_Polarity */ + + uint32_t CaptureRate; /*!< Specifies the frequency of frame capture: All, 1/2 or 1/4. + This parameter can be a value of @ref DCMI_Capture_Rate */ + + uint32_t ExtendedDataMode; /*!< Specifies the data width: 8-bit, 10-bit, 12-bit or 14-bit. + This parameter can be a value of @ref DCMI_Extended_Data_Mode */ + + DCMI_CodesInitTypeDef SyncroCode; /*!< Specifies the code of the line/frame start delimiter and the + line/frame end delimiter */ + + uint32_t JPEGMode; /*!< Enable or Disable the JPEG mode. + This parameter can be a value of @ref DCMI_MODE_JPEG */ + + uint32_t ByteSelectMode; /*!< Specifies the data to be captured by the interface + This parameter can be a value of @ref DCMI_Byte_Select_Mode */ + + uint32_t ByteSelectStart; /*!< Specifies if the data to be captured by the interface is even or odd + This parameter can be a value of @ref DCMI_Byte_Select_Start */ + + uint32_t LineSelectMode; /*!< Specifies the line of data to be captured by the interface + This parameter can be a value of @ref DCMI_Line_Select_Mode */ + + uint32_t LineSelectStart; /*!< Specifies if the line of data to be captured by the interface is even or odd + This parameter can be a value of @ref DCMI_Line_Select_Start */ +} DCMI_InitTypeDef; + +/** + * @brief DCMI handle Structure definition + */ +#if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1) +typedef struct __DCMI_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */ +{ + DCMI_TypeDef *Instance; /*!< DCMI Register base address */ + + DCMI_InitTypeDef Init; /*!< DCMI parameters */ + + HAL_LockTypeDef Lock; /*!< DCMI locking object */ + + __IO HAL_DCMI_StateTypeDef State; /*!< DCMI state */ + + __IO uint32_t XferCount; /*!< DMA transfer counter */ + + __IO uint32_t XferSize; /*!< DMA transfer size */ + + uint32_t XferTransferNumber; /*!< DMA transfer number */ + + uint32_t pBuffPtr; /*!< Pointer to DMA output buffer */ + + DMA_HandleTypeDef *DMA_Handle; /*!< Pointer to the DMA handler */ + + __IO uint32_t ErrorCode; /*!< DCMI Error code */ + +#if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1) + void (* FrameEventCallback)(struct __DCMI_HandleTypeDef *hdcmi); /*!< DCMI Frame Event Callback */ + void (* VsyncEventCallback)(struct __DCMI_HandleTypeDef *hdcmi); /*!< DCMI Vsync Event Callback */ + void (* LineEventCallback)(struct __DCMI_HandleTypeDef *hdcmi); /*!< DCMI Line Event Callback */ + void (* ErrorCallback)(struct __DCMI_HandleTypeDef *hdcmi); /*!< DCMI Error Callback */ + void (* MspInitCallback)(struct __DCMI_HandleTypeDef *hdcmi); /*!< DCMI Msp Init callback */ + void (* MspDeInitCallback)(struct __DCMI_HandleTypeDef *hdcmi); /*!< DCMI Msp DeInit callback */ +#endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */ +} DCMI_HandleTypeDef; + +#if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1) +/** + * @brief HAL DCMI Callback ID enumeration definition + */ +typedef enum +{ + HAL_DCMI_FRAME_EVENT_CB_ID = 0x00U, /*!< DCMI Frame Event Callback ID */ + HAL_DCMI_VSYNC_EVENT_CB_ID = 0x01U, /*!< DCMI Vsync Event Callback ID */ + HAL_DCMI_LINE_EVENT_CB_ID = 0x02U, /*!< DCMI Line Event Callback ID */ + HAL_DCMI_ERROR_CB_ID = 0x03U, /*!< DCMI Error Callback ID */ + HAL_DCMI_MSPINIT_CB_ID = 0x04U, /*!< DCMI MspInit callback ID */ + HAL_DCMI_MSPDEINIT_CB_ID = 0x05U /*!< DCMI MspDeInit callback ID */ + +} HAL_DCMI_CallbackIDTypeDef; + +/** + * @brief HAL DCMI Callback pointer definition + */ +typedef void (*pDCMI_CallbackTypeDef)(DCMI_HandleTypeDef *hdcmi); /*!< pointer to a DCMI callback function */ +#endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */ + + +/** + * @} + */ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup DCMI_Exported_Constants DCMI Exported Constants + * @{ + */ + +/** @defgroup DCMI_Error_Code DCMI Error Code + * @{ + */ +#define HAL_DCMI_ERROR_NONE (0x00000000U) /*!< No error */ +#define HAL_DCMI_ERROR_OVR (0x00000001U) /*!< Overrun error */ +#define HAL_DCMI_ERROR_SYNC (0x00000002U) /*!< Synchronization error */ +#define HAL_DCMI_ERROR_TIMEOUT (0x00000020U) /*!< Timeout error */ +#define HAL_DCMI_ERROR_DMA (0x00000040U) /*!< DMA error */ +#if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1) +#define HAL_DCMI_ERROR_INVALID_CALLBACK (0x00000080U) /*!< Invalid callback error */ +#endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @defgroup DCMI_Capture_Mode DCMI Capture Mode + * @{ + */ +#define DCMI_MODE_CONTINUOUS (0x00000000U) /*!< The received data are transferred continuously + into the destination memory through the DMA */ +#define DCMI_MODE_SNAPSHOT ((uint32_t)DCMI_CR_CM) /*!< Once activated, the interface waits for the start of + frame and then transfers a single frame + through the DMA */ +/** + * @} + */ + +/** @defgroup DCMI_Synchronization_Mode DCMI Synchronization Mode + * @{ + */ +#define DCMI_SYNCHRO_HARDWARE (0x00000000U) /*!< Hardware synchronization data capture (frame/line start/stop) + is synchronized with the HSYNC/VSYNC signals */ +#define DCMI_SYNCHRO_EMBEDDED ((uint32_t)DCMI_CR_ESS) /*!< Embedded synchronization data capture is synchronized + with synchronization codes embedded in the data flow */ + +/** + * @} + */ + +/** @defgroup DCMI_PIXCK_Polarity DCMI PIXCK Polarity + * @{ + */ +#define DCMI_PCKPOLARITY_FALLING (0x00000000U) /*!< Pixel clock active on Falling edge */ +#define DCMI_PCKPOLARITY_RISING ((uint32_t)DCMI_CR_PCKPOL) /*!< Pixel clock active on Rising edge */ + +/** + * @} + */ + +/** @defgroup DCMI_VSYNC_Polarity DCMI VSYNC Polarity + * @{ + */ +#define DCMI_VSPOLARITY_LOW (0x00000000U) /*!< Vertical synchronization active Low */ +#define DCMI_VSPOLARITY_HIGH ((uint32_t)DCMI_CR_VSPOL) /*!< Vertical synchronization active High */ + +/** + * @} + */ + +/** @defgroup DCMI_HSYNC_Polarity DCMI HSYNC Polarity + * @{ + */ +#define DCMI_HSPOLARITY_LOW (0x00000000U) /*!< Horizontal synchronization active Low */ +#define DCMI_HSPOLARITY_HIGH ((uint32_t)DCMI_CR_HSPOL) /*!< Horizontal synchronization active High */ + +/** + * @} + */ + +/** @defgroup DCMI_MODE_JPEG DCMI MODE JPEG + * @{ + */ +#define DCMI_JPEG_DISABLE (0x00000000U) /*!< Mode JPEG Disabled */ +#define DCMI_JPEG_ENABLE ((uint32_t)DCMI_CR_JPEG) /*!< Mode JPEG Enabled */ + +/** + * @} + */ + +/** @defgroup DCMI_Capture_Rate DCMI Capture Rate + * @{ + */ +#define DCMI_CR_ALL_FRAME (0x00000000U) /*!< All frames are captured */ +#define DCMI_CR_ALTERNATE_2_FRAME ((uint32_t)DCMI_CR_FCRC_0) /*!< Every alternate frame captured */ +#define DCMI_CR_ALTERNATE_4_FRAME ((uint32_t)DCMI_CR_FCRC_1) /*!< One frame in 4 frames captured */ + +/** + * @} + */ + +/** @defgroup DCMI_Extended_Data_Mode DCMI Extended Data Mode + * @{ + */ +#define DCMI_EXTEND_DATA_8B (0x00000000U) /*!< Interface captures 8-bit data on every pixel clock */ +#define DCMI_EXTEND_DATA_10B ((uint32_t)DCMI_CR_EDM_0) /*!< Interface captures 10-bit data on every pixel clock */ +#define DCMI_EXTEND_DATA_12B ((uint32_t)DCMI_CR_EDM_1) /*!< Interface captures 12-bit data on every pixel clock */ +#define DCMI_EXTEND_DATA_14B ((uint32_t)(DCMI_CR_EDM_0 |\ + DCMI_CR_EDM_1)) /*!< Interface captures 14-bit data on every pixel clock */ + +/** + * @} + */ + +/** @defgroup DCMI_Window_Coordinate DCMI Window Coordinate + * @{ + */ +#define DCMI_WINDOW_COORDINATE (0x3FFFU) /*!< Window coordinate */ + +/** + * @} + */ + +/** @defgroup DCMI_Window_Height DCMI Window Height + * @{ + */ +#define DCMI_WINDOW_HEIGHT (0x1FFFU) /*!< Window Height */ + +/** + * @} + */ + +/** @defgroup DCMI_interrupt_sources DCMI interrupt sources + * @{ + */ +#define DCMI_IT_FRAME ((uint32_t)DCMI_IER_FRAME_IE) /*!< Capture complete interrupt */ +#define DCMI_IT_OVR ((uint32_t)DCMI_IER_OVR_IE) /*!< Overrun interrupt */ +#define DCMI_IT_ERR ((uint32_t)DCMI_IER_ERR_IE) /*!< Synchronization error interrupt */ +#define DCMI_IT_VSYNC ((uint32_t)DCMI_IER_VSYNC_IE) /*!< VSYNC interrupt */ +#define DCMI_IT_LINE ((uint32_t)DCMI_IER_LINE_IE) /*!< Line interrupt */ +/** + * @} + */ + +/** @defgroup DCMI_Flags DCMI Flags + * @{ + */ + +/** + * @brief DCMI SR register + */ +#define DCMI_FLAG_HSYNC ((uint32_t)DCMI_SR_INDEX|DCMI_SR_HSYNC) /*!< HSYNC pin state (active line / synchronization + between lines) */ +#define DCMI_FLAG_VSYNC ((uint32_t)DCMI_SR_INDEX|DCMI_SR_VSYNC) /*!< VSYNC pin state (active frame / synchronization + between frames) */ +#define DCMI_FLAG_FNE ((uint32_t)DCMI_SR_INDEX|DCMI_SR_FNE) /*!< FIFO not empty flag */ +/** + * @brief DCMI RIS register + */ +#define DCMI_FLAG_FRAMERI ((uint32_t)DCMI_RIS_FRAME_RIS) /*!< Frame capture complete interrupt flag */ +#define DCMI_FLAG_OVRRI ((uint32_t)DCMI_RIS_OVR_RIS) /*!< Overrun interrupt flag */ +#define DCMI_FLAG_ERRRI ((uint32_t)DCMI_RIS_ERR_RIS) /*!< Synchronization error interrupt flag */ +#define DCMI_FLAG_VSYNCRI ((uint32_t)DCMI_RIS_VSYNC_RIS) /*!< VSYNC interrupt flag */ +#define DCMI_FLAG_LINERI ((uint32_t)DCMI_RIS_LINE_RIS) /*!< Line interrupt flag */ +/** + * @brief DCMI MIS register + */ +#define DCMI_FLAG_FRAMEMI ((uint32_t)DCMI_MIS_INDEX|DCMI_MIS_FRAME_MIS) /*!< DCMI Frame capture complete masked + interrupt status */ +#define DCMI_FLAG_OVRMI ((uint32_t)DCMI_MIS_INDEX|DCMI_MIS_OVR_MIS ) /*!< DCMI Overrun masked interrupt status */ +#define DCMI_FLAG_ERRMI ((uint32_t)DCMI_MIS_INDEX|DCMI_MIS_ERR_MIS ) /*!< DCMI Synchronization error masked interrupt status */ +#define DCMI_FLAG_VSYNCMI ((uint32_t)DCMI_MIS_INDEX|DCMI_MIS_VSYNC_MIS) /*!< DCMI VSYNC masked interrupt status */ +#define DCMI_FLAG_LINEMI ((uint32_t)DCMI_MIS_INDEX|DCMI_MIS_LINE_MIS ) /*!< DCMI Line masked interrupt status */ +/** + * @} + */ + +/** @defgroup DCMI_Byte_Select_Mode DCMI Byte Select Mode + * @{ + */ +#define DCMI_BSM_ALL (0x00000000U) /*!< Interface captures all received data */ +#define DCMI_BSM_OTHER ((uint32_t)DCMI_CR_BSM_0) /*!< Interface captures every other byte + from the received data */ +#define DCMI_BSM_ALTERNATE_4 ((uint32_t)DCMI_CR_BSM_1) /*!< Interface captures one byte out of four */ +#define DCMI_BSM_ALTERNATE_2 ((uint32_t)(DCMI_CR_BSM_0 |\ + DCMI_CR_BSM_1)) /*!< Interface captures two bytes out of four */ + +/** + * @} + */ + +/** @defgroup DCMI_Byte_Select_Start DCMI Byte Select Start + * @{ + */ +#define DCMI_OEBS_ODD (0x00000000U) /*!< Interface captures first data from the frame/line start, + second one being dropped */ +#define DCMI_OEBS_EVEN ((uint32_t)DCMI_CR_OEBS) /*!< Interface captures second data from + the frame/line start, first one being dropped */ + +/** + * @} + */ + +/** @defgroup DCMI_Line_Select_Mode DCMI Line Select Mode + * @{ + */ +#define DCMI_LSM_ALL (0x00000000U) /*!< Interface captures all received lines */ +#define DCMI_LSM_ALTERNATE_2 ((uint32_t)DCMI_CR_LSM) /*!< Interface captures one line out of two */ + +/** + * @} + */ + +/** @defgroup DCMI_Line_Select_Start DCMI Line Select Start + * @{ + */ +#define DCMI_OELS_ODD (0x00000000U) /*!< Interface captures first line from the frame start, + second one being dropped */ +#define DCMI_OELS_EVEN ((uint32_t)DCMI_CR_OELS) /*!< Interface captures second line from the frame start, + first one being dropped */ + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup DCMI_Exported_Macros DCMI Exported Macros + * @{ + */ + +/** @brief Reset DCMI handle state + * @param __HANDLE__ specifies the DCMI handle. + * @retval None + */ +#if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1) +#define __HAL_DCMI_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->State = HAL_DCMI_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_DCMI_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_DCMI_STATE_RESET) +#endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */ + +/** + * @brief Enable the DCMI. + * @param __HANDLE__ DCMI handle + * @retval None + */ +#define __HAL_DCMI_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= DCMI_CR_ENABLE) + +/** + * @brief Disable the DCMI. + * @param __HANDLE__ DCMI handle + * @retval None + */ +#define __HAL_DCMI_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR &= ~(DCMI_CR_ENABLE)) + +/* Interrupt & Flag management */ +/** + * @brief Get the DCMI pending flag. + * @param __HANDLE__ DCMI handle + * @param __FLAG__ Get the specified flag. + * This parameter can be one of the following values (no combination allowed) + * @arg DCMI_FLAG_HSYNC: HSYNC pin state (active line / synchronization between lines) + * @arg DCMI_FLAG_VSYNC: VSYNC pin state (active frame / synchronization between frames) + * @arg DCMI_FLAG_FNE: FIFO empty flag + * @arg DCMI_FLAG_FRAMERI: Frame capture complete flag mask + * @arg DCMI_FLAG_OVRRI: Overrun flag mask + * @arg DCMI_FLAG_ERRRI: Synchronization error flag mask + * @arg DCMI_FLAG_VSYNCRI: VSYNC flag mask + * @arg DCMI_FLAG_LINERI: Line flag mask + * @arg DCMI_FLAG_FRAMEMI: DCMI Capture complete masked interrupt status + * @arg DCMI_FLAG_OVRMI: DCMI Overrun masked interrupt status + * @arg DCMI_FLAG_ERRMI: DCMI Synchronization error masked interrupt status + * @arg DCMI_FLAG_VSYNCMI: DCMI VSYNC masked interrupt status + * @arg DCMI_FLAG_LINEMI: DCMI Line masked interrupt status + * @retval The state of FLAG. + */ +#define __HAL_DCMI_GET_FLAG(__HANDLE__, __FLAG__)\ + ((((__FLAG__) & (DCMI_SR_INDEX|DCMI_MIS_INDEX)) == 0x0)? ((__HANDLE__)->Instance->RIS & (__FLAG__)) :\ + (((__FLAG__) & DCMI_SR_INDEX) == 0x0)? ((__HANDLE__)->Instance->MIS & (__FLAG__)) :\ + ((__HANDLE__)->Instance->SR & (__FLAG__))) + +/** + * @brief Clear the DCMI pending flags. + * @param __HANDLE__ DCMI handle + * @param __FLAG__ specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg DCMI_FLAG_FRAMERI: Frame capture complete flag mask + * @arg DCMI_FLAG_OVFRI: Overflow flag mask + * @arg DCMI_FLAG_ERRRI: Synchronization error flag mask + * @arg DCMI_FLAG_VSYNCRI: VSYNC flag mask + * @arg DCMI_FLAG_LINERI: Line flag mask + * @retval None + */ +#define __HAL_DCMI_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ICR = (__FLAG__)) + +/** + * @brief Enable the specified DCMI interrupts. + * @param __HANDLE__ DCMI handle + * @param __INTERRUPT__ specifies the DCMI interrupt sources to be enabled. + * This parameter can be any combination of the following values: + * @arg DCMI_IT_FRAME: Frame capture complete interrupt mask + * @arg DCMI_IT_OVF: Overflow interrupt mask + * @arg DCMI_IT_ERR: Synchronization error interrupt mask + * @arg DCMI_IT_VSYNC: VSYNC interrupt mask + * @arg DCMI_IT_LINE: Line interrupt mask + * @retval None + */ +#define __HAL_DCMI_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IER |= (__INTERRUPT__)) + +/** + * @brief Disable the specified DCMI interrupts. + * @param __HANDLE__ DCMI handle + * @param __INTERRUPT__ specifies the DCMI interrupt sources to be enabled. + * This parameter can be any combination of the following values: + * @arg DCMI_IT_FRAME: Frame capture complete interrupt mask + * @arg DCMI_IT_OVF: Overflow interrupt mask + * @arg DCMI_IT_ERR: Synchronization error interrupt mask + * @arg DCMI_IT_VSYNC: VSYNC interrupt mask + * @arg DCMI_IT_LINE: Line interrupt mask + * @retval None + */ +#define __HAL_DCMI_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IER &= ~(__INTERRUPT__)) + +/** + * @brief Check whether the specified DCMI interrupt has occurred or not. + * @param __HANDLE__ DCMI handle + * @param __INTERRUPT__ specifies the DCMI interrupt source to check. + * This parameter can be one of the following values: + * @arg DCMI_IT_FRAME: Frame capture complete interrupt mask + * @arg DCMI_IT_OVF: Overflow interrupt mask + * @arg DCMI_IT_ERR: Synchronization error interrupt mask + * @arg DCMI_IT_VSYNC: VSYNC interrupt mask + * @arg DCMI_IT_LINE: Line interrupt mask + * @retval The state of INTERRUPT. + */ +#define __HAL_DCMI_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->MISR & (__INTERRUPT__)) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup DCMI_Exported_Functions DCMI Exported Functions + * @{ + */ + +/** @addtogroup DCMI_Exported_Functions_Group1 Initialization and Configuration functions + * @{ + */ +/* Initialization and de-initialization functions *****************************/ +HAL_StatusTypeDef HAL_DCMI_Init(DCMI_HandleTypeDef *hdcmi); +HAL_StatusTypeDef HAL_DCMI_DeInit(DCMI_HandleTypeDef *hdcmi); +void HAL_DCMI_MspInit(DCMI_HandleTypeDef *hdcmi); +void HAL_DCMI_MspDeInit(DCMI_HandleTypeDef *hdcmi); + +/* Callbacks Register/UnRegister functions ***********************************/ +#if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1) +HAL_StatusTypeDef HAL_DCMI_RegisterCallback(DCMI_HandleTypeDef *hdcmi, HAL_DCMI_CallbackIDTypeDef CallbackID, + pDCMI_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_DCMI_UnRegisterCallback(DCMI_HandleTypeDef *hdcmi, HAL_DCMI_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @addtogroup DCMI_Exported_Functions_Group2 IO operation functions + * @{ + */ +/* IO operation functions *****************************************************/ +HAL_StatusTypeDef HAL_DCMI_Start_DMA(DCMI_HandleTypeDef *hdcmi, uint32_t DCMI_Mode, uint32_t pData, uint32_t Length); +HAL_StatusTypeDef HAL_DCMI_Stop(DCMI_HandleTypeDef *hdcmi); +HAL_StatusTypeDef HAL_DCMI_Suspend(DCMI_HandleTypeDef *hdcmi); +HAL_StatusTypeDef HAL_DCMI_Resume(DCMI_HandleTypeDef *hdcmi); +void HAL_DCMI_ErrorCallback(DCMI_HandleTypeDef *hdcmi); +void HAL_DCMI_LineEventCallback(DCMI_HandleTypeDef *hdcmi); +void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi); +void HAL_DCMI_VsyncEventCallback(DCMI_HandleTypeDef *hdcmi); +void HAL_DCMI_IRQHandler(DCMI_HandleTypeDef *hdcmi); +/** + * @} + */ + +/** @addtogroup DCMI_Exported_Functions_Group3 Peripheral Control functions + * @{ + */ +/* Peripheral Control functions ***********************************************/ +HAL_StatusTypeDef HAL_DCMI_ConfigCrop(DCMI_HandleTypeDef *hdcmi, uint32_t X0, uint32_t Y0, uint32_t XSize, + uint32_t YSize); +HAL_StatusTypeDef HAL_DCMI_EnableCrop(DCMI_HandleTypeDef *hdcmi); +HAL_StatusTypeDef HAL_DCMI_DisableCrop(DCMI_HandleTypeDef *hdcmi); +HAL_StatusTypeDef HAL_DCMI_ConfigSyncUnmask(DCMI_HandleTypeDef *hdcmi, DCMI_SyncUnmaskTypeDef *SyncUnmask); + +/** + * @} + */ + +/** @addtogroup DCMI_Exported_Functions_Group4 Peripheral State functions + * @{ + */ +/* Peripheral State functions *************************************************/ +HAL_DCMI_StateTypeDef HAL_DCMI_GetState(const DCMI_HandleTypeDef *hdcmi); +uint32_t HAL_DCMI_GetError(const DCMI_HandleTypeDef *hdcmi); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup DCMI_Private_Constants DCMI Private Constants + * @{ + */ +/** @defgroup DCMI_MIS_INDEX DCMI Mis Index + * @{ + */ +#define DCMI_MIS_INDEX ((uint32_t)0x1000) /*!< DCMI MIS register index */ + +/** + * @} + */ + +/** @defgroup DCMI_SR_INDEX DCMI SR Index + * @{ + */ +#define DCMI_SR_INDEX ((uint32_t)0x2000) /*!< DCMI SR register index */ + +/** + * @} + */ + +/** + * @} + */ +/* Private macro -------------------------------------------------------------*/ +/** @defgroup DCMI_Private_Macros DCMI Private Macros + * @{ + */ +#define IS_DCMI_CAPTURE_MODE(MODE)(((MODE) == DCMI_MODE_CONTINUOUS) || \ + ((MODE) == DCMI_MODE_SNAPSHOT)) + +#define IS_DCMI_SYNCHRO(MODE)(((MODE) == DCMI_SYNCHRO_HARDWARE) || \ + ((MODE) == DCMI_SYNCHRO_EMBEDDED)) + +#define IS_DCMI_PCKPOLARITY(POLARITY)(((POLARITY) == DCMI_PCKPOLARITY_FALLING) || \ + ((POLARITY) == DCMI_PCKPOLARITY_RISING)) + +#define IS_DCMI_VSPOLARITY(POLARITY)(((POLARITY) == DCMI_VSPOLARITY_LOW) || \ + ((POLARITY) == DCMI_VSPOLARITY_HIGH)) + +#define IS_DCMI_HSPOLARITY(POLARITY)(((POLARITY) == DCMI_HSPOLARITY_LOW) || \ + ((POLARITY) == DCMI_HSPOLARITY_HIGH)) + +#define IS_DCMI_MODE_JPEG(JPEG_MODE)(((JPEG_MODE) == DCMI_JPEG_DISABLE) || \ + ((JPEG_MODE) == DCMI_JPEG_ENABLE)) + +#define IS_DCMI_CAPTURE_RATE(RATE) (((RATE) == DCMI_CR_ALL_FRAME) || \ + ((RATE) == DCMI_CR_ALTERNATE_2_FRAME) || \ + ((RATE) == DCMI_CR_ALTERNATE_4_FRAME)) + +#define IS_DCMI_EXTENDED_DATA(DATA)(((DATA) == DCMI_EXTEND_DATA_8B) || \ + ((DATA) == DCMI_EXTEND_DATA_10B) || \ + ((DATA) == DCMI_EXTEND_DATA_12B) || \ + ((DATA) == DCMI_EXTEND_DATA_14B)) + +#define IS_DCMI_WINDOW_COORDINATE(COORDINATE) ((COORDINATE) <= DCMI_WINDOW_COORDINATE) + +#define IS_DCMI_WINDOW_HEIGHT(HEIGHT) ((HEIGHT) <= DCMI_WINDOW_HEIGHT) + +#define IS_DCMI_BYTE_SELECT_MODE(MODE)(((MODE) == DCMI_BSM_ALL) || \ + ((MODE) == DCMI_BSM_OTHER) || \ + ((MODE) == DCMI_BSM_ALTERNATE_4) || \ + ((MODE) == DCMI_BSM_ALTERNATE_2)) + +#define IS_DCMI_BYTE_SELECT_START(POLARITY)(((POLARITY) == DCMI_OEBS_ODD) || \ + ((POLARITY) == DCMI_OEBS_EVEN)) + +#define IS_DCMI_LINE_SELECT_MODE(MODE)(((MODE) == DCMI_LSM_ALL) || \ + ((MODE) == DCMI_LSM_ALTERNATE_2)) + +#define IS_DCMI_LINE_SELECT_START(POLARITY)(((POLARITY) == DCMI_OELS_ODD) || \ + ((POLARITY) == DCMI_OELS_EVEN)) + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @addtogroup DCMI_Private_Functions DCMI Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ +/** + * @} + */ +#endif /* DCMI */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_DCMI_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_def.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_def.h new file mode 100644 index 0000000000..58ad1f8423 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_def.h @@ -0,0 +1,231 @@ +/** + ********************************************************************************************************************** + * @file stm32h5xx_hal_def.h + * @author MCD Application Team + * @brief This file contains HAL common defines, enumeration, macros and + * structures definitions. + ********************************************************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ********************************************************************************************************************** + */ + +/* Define to prevent recursive inclusion -----------------------------------------------------------------------------*/ +#ifndef __STM32H5xx_HAL_DEF +#define __STM32H5xx_HAL_DEF + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Includes ----------------------------------------------------------------------------------------------------------*/ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#include +#endif /* __ARM_FEATURE_CMSE */ + +#include "stm32h5xx.h" +#include "Legacy/stm32_hal_legacy.h" /* Aliases file for old names compatibility */ +#include +#include + +/* Exported types ----------------------------------------------------------------------------------------------------*/ + +/** + * @brief HAL Status structures definition + */ +typedef enum +{ + HAL_OK = 0x00, + HAL_ERROR = 0x01, + HAL_BUSY = 0x02, + HAL_TIMEOUT = 0x03 +} HAL_StatusTypeDef; + +/** + * @brief HAL Lock structures definition + */ +typedef enum +{ + HAL_UNLOCKED = 0x00, + HAL_LOCKED = 0x01 +} HAL_LockTypeDef; + +/* Exported macros ---------------------------------------------------------------------------------------------------*/ + +#define HAL_MAX_DELAY 0xFFFFFFFFU +#define ARMCC_MIN_VERSION 6010050 + +#define HAL_IS_BIT_SET(REG, BIT) (((REG) & (BIT)) == (BIT)) +#define HAL_IS_BIT_CLR(REG, BIT) (((REG) & (BIT)) == 0U) + +#define __HAL_LINKDMA(__HANDLE__, __PPP_DMA_FIELD__, __DMA_HANDLE__) \ + do{ \ + (__HANDLE__)->__PPP_DMA_FIELD__ = &(__DMA_HANDLE__); \ + (__DMA_HANDLE__).Parent = (__HANDLE__); \ + } while(0) + +#if !defined(UNUSED) +#define UNUSED(x) ((void)(x)) +#endif /* UNUSED */ + +/** @brief Reset the Handle's State field. + * @param __HANDLE__: specifies the Peripheral Handle. + * @note This macro can be used for the following purpose: + * - When the Handle is declared as local variable; before passing it as parameter + * to HAL_PPP_Init() for the first time, it is mandatory to use this macro + * to set to 0 the Handle's "State" field. + * Otherwise, "State" field may have any random value and the first time the function + * HAL_PPP_Init() is called, the low level hardware initialization will be missed + * (i.e. HAL_PPP_MspInit() will not be executed). + * - When there is a need to reconfigure the low level hardware: instead of calling + * HAL_PPP_DeInit() then HAL_PPP_Init(), user can make a call to this macro then HAL_PPP_Init(). + * In this later function, when the Handle's "State" field is set to 0, it will execute the function + * HAL_PPP_MspInit() which will reconfigure the low level hardware. + * @retval None + */ +#define __HAL_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = 0) + +#if (USE_RTOS == 1) +/* Reserved for future use */ +#error " USE_RTOS should be 0 in the current HAL release " +#else +#define __HAL_LOCK(__HANDLE__) \ + do{ \ + if((__HANDLE__)->Lock == HAL_LOCKED) \ + { \ + return HAL_BUSY; \ + } \ + else \ + { \ + (__HANDLE__)->Lock = HAL_LOCKED; \ + } \ + }while (0) + +#define __HAL_UNLOCK(__HANDLE__) \ + do{ \ + (__HANDLE__)->Lock = HAL_UNLOCKED; \ + }while (0) +#endif /* USE_RTOS */ + +#if defined ( __GNUC__ ) +#ifndef __weak +#define __weak __attribute__((weak)) +#endif /* __weak */ +#ifndef __packed +#define __packed __attribute__((__packed__)) +#endif /* __packed */ +#endif /* __GNUC__ */ + +#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= ARMCC_MIN_VERSION) +#ifndef __weak +#define __weak __WEAK +#endif /* __weak */ +#ifndef __packed +#define __packed __PACKED +#endif /* __packed */ +#endif + +/* Macro to get variable aligned on 4-bytes, for __ICCARM__ the directive "#pragma data_alignment=4" + must be used instead */ +#if defined (__GNUC__) /* GNU Compiler */ +#ifndef __ALIGN_END +#define __ALIGN_END __attribute__ ((aligned (4))) +#endif /* __ALIGN_END */ +#ifndef __ALIGN_BEGIN +#define __ALIGN_BEGIN +#endif /* __ALIGN_BEGIN */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= ARMCC_MIN_VERSION) +#ifndef __ALIGN_END +#define __ALIGN_END __ALIGNED(4) +#endif /* __ALIGN_END */ +#ifndef __ALIGN_BEGIN +#define __ALIGN_BEGIN +#endif /* __ALIGN_BEGIN */ +#else +#ifndef __ALIGN_END +#define __ALIGN_END +#endif /* __ALIGN_END */ +#ifndef __ALIGN_BEGIN +#if defined (__CC_ARM) /* ARM Compiler */ +#define __ALIGN_BEGIN __align(4) +#elif defined (__ICCARM__) /* IAR Compiler */ +#define __ALIGN_BEGIN +#endif /* __CC_ARM */ +#endif /* __ALIGN_BEGIN */ +#endif /* __GNUC__ */ + +/* Macro to get variable aligned on 32-bytes,needed for cache maintenance purpose */ +#if defined (__GNUC__) /* GNU Compiler */ +#define ALIGN_32BYTES(buf) buf __attribute__ ((aligned (32))) +#elif defined (__ICCARM__) /* IAR Compiler */ +#define ALIGN_32BYTES(buf) _Pragma("data_alignment=32") buf +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= ARMCC_MIN_VERSION) +#define ALIGN_32BYTES(buf) __ALIGNED(32) buf +#elif defined (__CC_ARM) /* ARM Compiler */ +#define ALIGN_32BYTES(buf) __align(32) buf +#endif /* __GNUC__ */ + +/** + * @brief __RAM_FUNC definition + */ +#if defined ( __CC_ARM ) || ((__ARMCC_VERSION) && (__ARMCC_VERSION >= ARMCC_MIN_VERSION)) + +/* ARM Compiler + + RAM functions are defined using the toolchain options. + Functions that are executed in RAM should reside in a separate source module. + Using the 'Options for File' dialog you can simply change the 'Code / Const' + area of a module to a memory space in physical RAM. + Available memory areas are declared in the 'Target' tab of the 'Options for Target' + dialog. +*/ +#define __RAM_FUNC HAL_StatusTypeDef + +#elif defined ( __ICCARM__ ) +/* ICCARM Compiler + + RAM functions are defined using a specific toolchain keyword "__ramfunc". +*/ +#define __RAM_FUNC __ramfunc HAL_StatusTypeDef + +#elif defined ( __GNUC__ ) +/* GNU Compiler + + RAM functions are defined using a specific toolchain attribute + "__attribute__((section(".RamFunc")))". +*/ +#define __RAM_FUNC HAL_StatusTypeDef __attribute__((section(".RamFunc"))) + +#endif /* defined ( __CC_ARM ) || ((__ARMCC_VERSION) && (__ARMCC_VERSION >= ARMCC_MIN_VERSION)) */ + +/** + * @brief __NOINLINE definition + */ +#if defined ( __CC_ARM ) || ((__ARMCC_VERSION) && (__ARMCC_VERSION >= ARMCC_MIN_VERSION)) || defined ( __GNUC__ ) +/* ARM & GNUCompiler + +*/ +#define __NOINLINE __attribute__ ( (noinline) ) + +#elif defined ( __ICCARM__ ) +/* ICCARM Compiler + +*/ +#define __NOINLINE _Pragma("optimize = no_inline") + +#endif /* ( __CC_ARM ) || ((__ARMCC_VERSION) && (__ARMCC_VERSION >= ARMCC_MIN_VERSION)) || defined ( __GNUC__ ) */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* ___STM32H5xx_HAL_DEF */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_dma.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_dma.h new file mode 100644 index 0000000000..854dd3d17b --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_dma.h @@ -0,0 +1,1180 @@ +/** + ********************************************************************************************************************** + * @file stm32h5xx_hal_dma.h + * @author MCD Application Team + * @brief Header file of DMA HAL module. + ********************************************************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ********************************************************************************************************************** + */ + +/* Define to prevent recursive inclusion -----------------------------------------------------------------------------*/ +#ifndef STM32H5xx_HAL_DMA_H +#define STM32H5xx_HAL_DMA_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ----------------------------------------------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup DMA + * @{ + */ + + +/* Exported types ----------------------------------------------------------------------------------------------------*/ + +/** @defgroup DMA_Exported_Types DMA Exported Types + * @brief DMA Exported Types + * @{ + */ + +/** + * @brief DMA Transfer Configuration Structure definition. + */ +typedef struct +{ + uint32_t Request; /*!< Specifies the DMA channel request. + This parameter can be a value of @ref DMA_Request_Selection */ + + uint32_t BlkHWRequest; /*!< Specifies the Block hardware request mode for DMA channel. + Block Hardware request feature can be used only with dedicated peripherals. + This parameter can be a value of @ref DMA_Block_Request */ + + uint32_t Direction; /*!< Specifies the transfer direction for DMA channel. + This parameter can be a value of @ref DMA_Transfer_Direction */ + + uint32_t SrcInc; /*!< Specifies the source increment mode for the DMA channel. + This parameter can be a value of @ref DMA_Source_Increment_Mode */ + + uint32_t DestInc; /*!< Specifies the destination increment mode for the DMA channel. + This parameter can be a value of @ref DMA_Destination_Increment_Mode */ + + uint32_t SrcDataWidth; /*!< Specifies the source data width for the DMA channel. + This parameter can be a value of @ref DMA_Source_Data_Width */ + + uint32_t DestDataWidth; /*!< Specifies the destination data width for the DMA channel. + This parameter can be a value of @ref DMA_Destination_Data_Width */ + + uint32_t Priority; /*!< Specifies the priority level for the DMA channel. + This parameter can be a value of @ref DMA_Priority_Level */ + + uint32_t SrcBurstLength; /*!< Specifies the source burst length (number of beats within a burst) for the DMA + channel. + This parameter can be a value between 1 and 64 */ + + uint32_t DestBurstLength; /*!< Specifies the destination burst length (number of beats within a burst) for the + DMA channel. + This parameter can be a value between 1 and 64 */ + + uint32_t TransferAllocatedPort; /*!< Specifies the transfer allocated ports. + This parameter can be a combination of @ref DMA_Transfer_Allocated_Port */ + + uint32_t TransferEventMode; /*!< Specifies the transfer event mode for the DMA channel. + This parameter can be a value of @ref DMA_Transfer_Event_Mode */ + + uint32_t Mode; /*!< Specifies the transfer mode for the DMA channel. + This parameter can be a value of @ref DMA_Transfer_Mode */ + +} DMA_InitTypeDef; + +/** + * @brief DMA Linked-List Configuration Structure Definition. + */ +typedef struct +{ + uint32_t Priority; /*!< Specifies the priority level for the DMA channel. + This parameter can be a value of @ref DMA_Priority_Level */ + + uint32_t LinkStepMode; /*!< Specifies the link step mode for the DMA channel. + This parameter can be a value of @ref DMAEx_Link_Step_Mode */ + + uint32_t LinkAllocatedPort; /*!< Specifies the linked-list allocated port for the DMA channel. + This parameter can be a value of @ref DMAEx_Link_Allocated_Port */ + + uint32_t TransferEventMode; /*!< Specifies the transfer event mode for the DMA channel. + This parameter can be a value of @ref DMA_Transfer_Event_Mode */ + + uint32_t LinkedListMode; /*!< Specifies linked-list transfer mode for the DMA channel. + This parameter can be a value of @ref DMAEx_LinkedList_Mode */ + +} DMA_InitLinkedListTypeDef; + +/** + * @brief HAL DMA State Enumeration Definition. + */ +typedef enum +{ + HAL_DMA_STATE_RESET = 0x00U, /*!< DMA not yet initialized or disabled */ + HAL_DMA_STATE_READY = 0x01U, /*!< DMA initialized and ready for use */ + HAL_DMA_STATE_BUSY = 0x02U, /*!< DMA process is ongoing */ + HAL_DMA_STATE_ERROR = 0x03U, /*!< DMA error state */ + HAL_DMA_STATE_ABORT = 0x04U, /*!< DMA Abort state */ + HAL_DMA_STATE_SUSPEND = 0x05U, /*!< DMA Suspend state */ + +} HAL_DMA_StateTypeDef; + +/** + * @brief HAL DMA Level Complete Enumeration Definition. + */ +typedef enum +{ + HAL_DMA_FULL_TRANSFER = 0x00U, /*!< Full channel transfer */ + HAL_DMA_HALF_TRANSFER = 0x01U, /*!< Half channel transfer */ + +} HAL_DMA_LevelCompleteTypeDef; + +/** + * @brief HAL DMA Callbacks IDs Enumeration Definition. + */ +typedef enum +{ + HAL_DMA_XFER_CPLT_CB_ID = 0x00U, /*!< Complete transfer callback ID */ + HAL_DMA_XFER_HALFCPLT_CB_ID = 0x01U, /*!< Half complete transfer callback ID */ + HAL_DMA_XFER_ERROR_CB_ID = 0x02U, /*!< Error transfer callback ID */ + HAL_DMA_XFER_ABORT_CB_ID = 0x03U, /*!< Abort transfer callback ID */ + HAL_DMA_XFER_SUSPEND_CB_ID = 0x04U, /*!< Suspend transfer callback ID */ + HAL_DMA_XFER_ALL_CB_ID = 0x05U /*!< All callback ID */ + +} HAL_DMA_CallbackIDTypeDef; + +/** + * @brief DMA handle Structure definition + */ +typedef struct __DMA_HandleTypeDef +{ + DMA_Channel_TypeDef *Instance; /*!< Register the DMA channel base address */ + + DMA_InitTypeDef Init; /*!< DMA channel init parameters */ + + DMA_InitLinkedListTypeDef InitLinkedList; /*!< DMA channel linked-list init parameters */ + + HAL_LockTypeDef Lock; /*!< DMA locking object */ + + uint32_t Mode; /*!< DMA transfer mode */ + + __IO HAL_DMA_StateTypeDef State; /*!< DMA transfer state */ + + __IO uint32_t ErrorCode; /*!< DMA error code */ + + void *Parent; /*!< Parent object state */ + + void (* XferCpltCallback)(struct __DMA_HandleTypeDef *hdma); /*!< DMA transfer complete callback */ + + void (* XferHalfCpltCallback)(struct __DMA_HandleTypeDef *hdma); /*!< DMA half transfer complete callback */ + + void (* XferErrorCallback)(struct __DMA_HandleTypeDef *hdma); /*!< DMA transfer error callback */ + + void (* XferAbortCallback)(struct __DMA_HandleTypeDef *hdma); /*!< DMA transfer Abort callback */ + + void (* XferSuspendCallback)(struct __DMA_HandleTypeDef *hdma); /*!< DMA transfer Suspend callback */ + + struct __DMA_QListTypeDef *LinkedListQueue; /*!< DMA linked-list queue */ + +} DMA_HandleTypeDef; +/** + * @} + */ + + +/* Exported constants ------------------------------------------------------------------------------------------------*/ +/** @defgroup DMA_Exported_Constants DMA Exported Constants + * @brief DMA Exported constants + * @{ + */ + +/** @defgroup DMA_Error_Codes DMA Error Codes + * @brief DMA Error Codes + * @{ + */ +#define HAL_DMA_ERROR_NONE (0x0000U) /*!< No error */ +#define HAL_DMA_ERROR_DTE (0x0001U) /*!< Data transfer error */ +#define HAL_DMA_ERROR_ULE (0x0002U) /*!< Update linked-list item error */ +#define HAL_DMA_ERROR_USE (0x0004U) /*!< User setting error */ +#define HAL_DMA_ERROR_TO (0x0008U) /*!< Trigger overrun error */ +#define HAL_DMA_ERROR_TIMEOUT (0x0010U) /*!< Timeout error */ +#define HAL_DMA_ERROR_NO_XFER (0x0020U) /*!< No transfer ongoing error */ +#define HAL_DMA_ERROR_BUSY (0x0040U) /*!< Busy error */ +#define HAL_DMA_ERROR_INVALID_CALLBACK (0x0080U) /*!< Invalid callback error */ +#define HAL_DMA_ERROR_NOT_SUPPORTED (0x0100U) /*!< Not supported mode */ +/** + * @} + */ + +/** @defgroup DMA_Interrupt_Enable_Definition DMA Interrupt Enable Definition + * @brief DMA Interrupt Enable Definition + * @{ + */ +#define DMA_IT_TC DMA_CCR_TCIE /*!< Transfer complete interrupt */ +#define DMA_IT_HT DMA_CCR_HTIE /*!< Half transfer complete interrupt */ +#define DMA_IT_DTE DMA_CCR_DTEIE /*!< Data transfer error interrupt */ +#define DMA_IT_ULE DMA_CCR_ULEIE /*!< Update linked-list item error interrupt */ +#define DMA_IT_USE DMA_CCR_USEIE /*!< User eetting error interrupt */ +#define DMA_IT_SUSP DMA_CCR_SUSPIE /*!< Completed suspension interrupt */ +#define DMA_IT_TO DMA_CCR_TOIE /*!< Trigger overrun interrupt */ +/** + * @} + */ + +/** @defgroup DMA_Flag_Definition DMA Flag Definition + * @brief DMA Flag Definition + * @{ + */ +#define DMA_FLAG_IDLE DMA_CSR_IDLEF /*!< Idle flag */ +#define DMA_FLAG_TC DMA_CSR_TCF /*!< Transfer complete flag */ +#define DMA_FLAG_HT DMA_CSR_HTF /*!< Half transfer complete flag */ +#define DMA_FLAG_DTE DMA_CSR_DTEF /*!< Data transfer error flag */ +#define DMA_FLAG_ULE DMA_CSR_ULEF /*!< Update linked-list item error flag */ +#define DMA_FLAG_USE DMA_CSR_USEF /*!< User setting error flag */ +#define DMA_FLAG_SUSP DMA_CSR_SUSPF /*!< Completed suspension flag */ +#define DMA_FLAG_TO DMA_CSR_TOF /*!< Trigger overrun flag */ +/** + * @} + */ + +/** @defgroup DMA_Request_Selection DMA Request Selection + * @brief DMA Request Selection + * @{ + */ +/* GPDMA1 requests */ +#define GPDMA1_REQUEST_ADC1 0U /*!< GPDMA1 HW request is ADC1 */ +#if defined (ADC2) +#define GPDMA1_REQUEST_ADC2 1U /*!< GPDMA1 HW request is ADC2 */ +#endif /* ADC2 */ +#define GPDMA1_REQUEST_DAC1_CH1 2U /*!< GPDMA1 HW request is DAC1_CH1 */ +#define GPDMA1_REQUEST_DAC1_CH2 3U /*!< GPDMA1 HW request is DAC1_CH2 */ +#define GPDMA1_REQUEST_TIM6_UP 4U /*!< GPDMA1 HW request is TIM6_UP */ +#define GPDMA1_REQUEST_TIM7_UP 5U /*!< GPDMA1 HW request is TIM7_UP */ +#define GPDMA1_REQUEST_SPI1_RX 6U /*!< GPDMA1 HW request is SPI1_RX */ +#define GPDMA1_REQUEST_SPI1_TX 7U /*!< GPDMA1 HW request is SPI1_TX */ +#define GPDMA1_REQUEST_SPI2_RX 8U /*!< GPDMA1 HW request is SPI2_RX */ +#define GPDMA1_REQUEST_SPI2_TX 9U /*!< GPDMA1 HW request is SPI2_TX */ +#define GPDMA1_REQUEST_SPI3_RX 10U /*!< GPDMA1 HW request is SPI3_RX */ +#define GPDMA1_REQUEST_SPI3_TX 11U /*!< GPDMA1 HW request is SPI3_TX */ +#define GPDMA1_REQUEST_I2C1_RX 12U /*!< GPDMA1 HW request is I2C1_RX */ +#define GPDMA1_REQUEST_I2C1_TX 13U /*!< GPDMA1 HW request is I2C1_TX */ +#define GPDMA1_REQUEST_I2C2_RX 15U /*!< GPDMA1 HW request is I2C2_RX */ +#define GPDMA1_REQUEST_I2C2_TX 16U /*!< GPDMA1 HW request is I2C2_TX */ +#if defined (I2C3) +#define GPDMA1_REQUEST_I2C3_RX 18U /*!< GPDMA1 HW request is I2C3_RX */ +#define GPDMA1_REQUEST_I2C3_TX 19U /*!< GPDMA1 HW request is I2C3_TX */ +#endif /* I2C3 */ +#define GPDMA1_REQUEST_USART1_RX 21U /*!< GPDMA1 HW request is USART1_RX */ +#define GPDMA1_REQUEST_USART1_TX 22U /*!< GPDMA1 HW request is USART1_TX */ +#define GPDMA1_REQUEST_USART2_RX 23U /*!< GPDMA1 HW request is USART2_RX */ +#define GPDMA1_REQUEST_USART2_TX 24U /*!< GPDMA1 HW request is USART2_TX */ +#define GPDMA1_REQUEST_USART3_RX 25U /*!< GPDMA1 HW request is USART3_RX */ +#define GPDMA1_REQUEST_USART3_TX 26U /*!< GPDMA1 HW request is USART3_TX */ +#if defined (UART4) +#define GPDMA1_REQUEST_UART4_RX 27U /*!< GPDMA1 HW request is UART4_RX */ +#define GPDMA1_REQUEST_UART4_TX 28U /*!< GPDMA1 HW request is UART4_TX */ +#endif /* UART4 */ +#if defined (UART4) +#define GPDMA1_REQUEST_UART5_RX 29U /*!< GPDMA1 HW request is UART5_RX */ +#define GPDMA1_REQUEST_UART5_TX 30U /*!< GPDMA1 HW request is UART5_TX */ +#endif /* UART5 */ +#if defined (UART4) +#define GPDMA1_REQUEST_USART6_RX 31U /*!< GPDMA1 HW request is USART6_RX */ +#define GPDMA1_REQUEST_USART6_TX 32U /*!< GPDMA1 HW request is USART6_TX */ +#endif /* USART6 */ +#if defined (UART7) +#define GPDMA1_REQUEST_UART7_RX 33U /*!< GPDMA1 HW request is UART7_RX */ +#define GPDMA1_REQUEST_UART7_TX 34U /*!< GPDMA1 HW request is UART7_TX */ +#endif /* UART7 */ +#if defined (UART8) +#define GPDMA1_REQUEST_UART8_RX 35U /*!< GPDMA1 HW request is UART8_RX */ +#define GPDMA1_REQUEST_UART8_TX 36U /*!< GPDMA1 HW request is UART8_TX */ +#endif /* UART8 */ +#if defined (UART9) +#define GPDMA1_REQUEST_UART9_RX 37U /*!< GPDMA1 HW request is UART9_RX */ +#define GPDMA1_REQUEST_UART9_TX 38U /*!< GPDMA1 HW request is UART9_TX */ +#endif /* UART9 */ +#if defined (USART10) +#define GPDMA1_REQUEST_USART10_RX 39U /*!< GPDMA1 HW request is USART10_RX */ +#define GPDMA1_REQUEST_USART10_TX 40U /*!< GPDMA1 HW request is USART10_TX */ +#endif /* USART10 */ +#if defined (USART11) +#define GPDMA1_REQUEST_USART11_RX 41U /*!< GPDMA1 HW request is USART11_RX */ +#define GPDMA1_REQUEST_USART11_TX 42U /*!< GPDMA1 HW request is USART11_TX */ +#endif /* USART11 */ +#if defined (UART12) +#define GPDMA1_REQUEST_UART12_RX 43U /*!< GPDMA1 HW request is UART12_RX */ +#define GPDMA1_REQUEST_UART12_TX 44U /*!< GPDMA1 HW request is UART12_TX */ +#endif /* UART12 */ +#define GPDMA1_REQUEST_LPUART1_RX 45U /*!< GPDMA1 HW request is LPUART1_RX */ +#define GPDMA1_REQUEST_LPUART1_TX 46U /*!< GPDMA1 HW request is LPUART1_TX */ +#if defined (SPI4) +#define GPDMA1_REQUEST_SPI4_RX 47U /*!< GPDMA1 HW request is SPI4_RX */ +#define GPDMA1_REQUEST_SPI4_TX 48U /*!< GPDMA1 HW request is SPI4_TX */ +#endif /* SPI4 */ +#if defined (SPI5) +#define GPDMA1_REQUEST_SPI5_RX 49U /*!< GPDMA1 HW request is SPI5_RX */ +#define GPDMA1_REQUEST_SPI5_TX 50U /*!< GPDMA1 HW request is SPI5_TX */ +#endif /* SPI5 */ +#if defined (SPI6) +#define GPDMA1_REQUEST_SPI6_RX 51U /*!< GPDMA1 HW request is SPI6_RX */ +#define GPDMA1_REQUEST_SPI6_TX 52U /*!< GPDMA1 HW request is SPI6_TX */ +#endif /* SPI6 */ +#if defined (SAI1) +#define GPDMA1_REQUEST_SAI1_A 53U /*!< GPDMA1 HW request is SAI1_A */ +#define GPDMA1_REQUEST_SAI1_B 54U /*!< GPDMA1 HW request is SAI1_B */ +#endif /* SAI1 */ +#if defined (SAI2) +#define GPDMA1_REQUEST_SAI2_A 55U /*!< GPDMA1 HW request is SAI2_A */ +#define GPDMA1_REQUEST_SAI2_B 56U /*!< GPDMA1 HW request is SAI2_B */ +#endif /* SAI2 */ +#if defined (OCTOSPI1) +#define GPDMA1_REQUEST_OCTOSPI1 57U /*!< GPDMA1 HW request is OCTOSPI1 */ +#endif /* OCTOSPI1 */ +#define GPDMA1_REQUEST_TIM1_CH1 58U /*!< GPDMA1 HW request is TIM1_CH1 */ +#define GPDMA1_REQUEST_TIM1_CH2 59U /*!< GPDMA1 HW request is TIM1_CH2 */ +#define GPDMA1_REQUEST_TIM1_CH3 60U /*!< GPDMA1 HW request is TIM1_CH3 */ +#define GPDMA1_REQUEST_TIM1_CH4 61U /*!< GPDMA1 HW request is TIM1_CH4 */ +#define GPDMA1_REQUEST_TIM1_UP 62U /*!< GPDMA1 HW request is TIM1_UP */ +#define GPDMA1_REQUEST_TIM1_TRIG 63U /*!< GPDMA1 HW request is TIM1_TRIG */ +#define GPDMA1_REQUEST_TIM1_COM 64U /*!< GPDMA1 HW request is TIM1_COM */ +#if defined (TIM8) +#define GPDMA1_REQUEST_TIM8_CH1 65U /*!< GPDMA1 HW request is TIM8_CH1 */ +#define GPDMA1_REQUEST_TIM8_CH2 66U /*!< GPDMA1 HW request is TIM8_CH2 */ +#define GPDMA1_REQUEST_TIM8_CH3 67U /*!< GPDMA1 HW request is TIM8_CH3 */ +#define GPDMA1_REQUEST_TIM8_CH4 68U /*!< GPDMA1 HW request is TIM8_CH4 */ +#define GPDMA1_REQUEST_TIM8_UP 69U /*!< GPDMA1 HW request is TIM8_UP */ +#define GPDMA1_REQUEST_TIM8_TRIG 70U /*!< GPDMA1 HW request is TIM8_TRIG */ +#define GPDMA1_REQUEST_TIM8_COM 71U /*!< GPDMA1 HW request is TIM8_COM */ +#endif /* TIM8 */ +#define GPDMA1_REQUEST_TIM2_CH1 72U /*!< GPDMA1 HW request is TIM2_CH1 */ +#define GPDMA1_REQUEST_TIM2_CH2 73U /*!< GPDMA1 HW request is TIM2_CH2 */ +#define GPDMA1_REQUEST_TIM2_CH3 74U /*!< GPDMA1 HW request is TIM2_CH3 */ +#define GPDMA1_REQUEST_TIM2_CH4 75U /*!< GPDMA1 HW request is TIM2_CH4 */ +#define GPDMA1_REQUEST_TIM2_UP 76U /*!< GPDMA1 HW request is TIM2_UP */ +#define GPDMA1_REQUEST_TIM3_CH1 77U /*!< GPDMA1 HW request is TIM3_CH1 */ +#define GPDMA1_REQUEST_TIM3_CH2 78U /*!< GPDMA1 HW request is TIM3_CH2 */ +#define GPDMA1_REQUEST_TIM3_CH3 79U /*!< GPDMA1 HW request is TIM3_CH3 */ +#define GPDMA1_REQUEST_TIM3_CH4 80U /*!< GPDMA1 HW request is TIM3_CH4 */ +#define GPDMA1_REQUEST_TIM3_UP 81U /*!< GPDMA1 HW request is TIM3_UP */ +#define GPDMA1_REQUEST_TIM3_TRIG 82U /*!< GPDMA1 HW request is TIM3_TRIG */ +#if defined (TIM4) +#define GPDMA1_REQUEST_TIM4_CH1 83U /*!< GPDMA1 HW request is TIM4_CH1 */ +#define GPDMA1_REQUEST_TIM4_CH2 84U /*!< GPDMA1 HW request is TIM4_CH2 */ +#define GPDMA1_REQUEST_TIM4_CH3 85U /*!< GPDMA1 HW request is TIM4_CH3 */ +#define GPDMA1_REQUEST_TIM4_CH4 86U /*!< GPDMA1 HW request is TIM4_CH4 */ +#define GPDMA1_REQUEST_TIM4_UP 87U /*!< GPDMA1 HW request is TIM4_UP */ +#endif /* TIM4 */ +#if defined (TIM5) +#define GPDMA1_REQUEST_TIM5_CH1 88U /*!< GPDMA1 HW request is TIM5_CH1 */ +#define GPDMA1_REQUEST_TIM5_CH2 89U /*!< GPDMA1 HW request is TIM5_CH2 */ +#define GPDMA1_REQUEST_TIM5_CH3 90U /*!< GPDMA1 HW request is TIM5_CH3 */ +#define GPDMA1_REQUEST_TIM5_CH4 91U /*!< GPDMA1 HW request is TIM5_CH4 */ +#define GPDMA1_REQUEST_TIM5_UP 92U /*!< GPDMA1 HW request is TIM5_UP */ +#define GPDMA1_REQUEST_TIM5_TRIG 93U /*!< GPDMA1 HW request is TIM5_TRIG */ +#endif /* TIM5 */ +#if defined (TIM15) +#define GPDMA1_REQUEST_TIM15_CH1 94U /*!< GPDMA1 HW request is TIM15_CH1 */ +#define GPDMA1_REQUEST_TIM15_UP 95U /*!< GPDMA1 HW request is TIM15_UP */ +#define GPDMA1_REQUEST_TIM15_TRIG 96U /*!< GPDMA1 HW request is TIM15_TRIG */ +#define GPDMA1_REQUEST_TIM15_COM 97U /*!< GPDMA1 HW request is TIM15_COM */ +#endif /* TIM15 */ +#if defined (TIM16) +#define GPDMA1_REQUEST_TIM16_CH1 98U /*!< GPDMA1 HW request is TIM16_CH1 */ +#define GPDMA1_REQUEST_TIM16_UP 99U /*!< GPDMA1 HW request is TIM16_UP */ +#endif /* TIM16 */ +#if defined (TIM17) +#define GPDMA1_REQUEST_TIM17_CH1 100U /*!< GPDMA1 HW request is TIM17_CH1 */ +#define GPDMA1_REQUEST_TIM17_UP 101U /*!< GPDMA1 HW request is TIM17_UP */ +#endif /* TIM17 */ +#define GPDMA1_REQUEST_LPTIM1_IC1 102U /*!< GPDMA1 HW request is LPTIM1_IC1 */ +#define GPDMA1_REQUEST_LPTIM1_IC2 103U /*!< GPDMA1 HW request is LPTIM1_IC2 */ +#define GPDMA1_REQUEST_LPTIM1_UE 104U /*!< GPDMA1 HW request is LPTIM1_UE */ +#define GPDMA1_REQUEST_LPTIM2_IC1 105U /*!< GPDMA1 HW request is LPTIM2_IC1 */ +#define GPDMA1_REQUEST_LPTIM2_IC2 106U /*!< GPDMA1 HW request is LPTIM2_IC2 */ +#define GPDMA1_REQUEST_LPTIM2_UE 107U /*!< GPDMA1 HW request is LPTIM2_UE */ +#if defined (DCMI) +#define GPDMA1_REQUEST_DCMI 108U /*!< GPDMA1 HW request is DCMI */ +#endif /* DCMI */ +#if defined (AES) +#define GPDMA1_REQUEST_AES_OUT 109U /*!< GPDMA1 HW request is AES_OUT */ +#define GPDMA1_REQUEST_AES_IN 110U /*!< GPDMA1 HW request is AES_IN */ +#endif /* AES */ +#define GPDMA1_REQUEST_HASH_IN 111U /*!< GPDMA1 HW request is HASH_IN */ +#if defined (UCPD1) +#define GPDMA1_REQUEST_UCPD1_RX 112U /*!< GPDMA1 HW request is UCPD1_RX */ +#define GPDMA1_REQUEST_UCPD1_TX 113U /*!< GPDMA1 HW request is UCPD1_TX */ +#endif /* UCPD1 */ +#if defined (CORDIC) +#define GPDMA1_REQUEST_CORDIC_READ 114U /*!< GPDMA1 HW request is CORDIC_READ */ +#define GPDMA1_REQUEST_CORDIC_WRITE 115U /*!< GPDMA1 HW request is CORDIC_WRITE */ +#endif /* CORDIC */ +#if defined (FMAC) +#define GPDMA1_REQUEST_FMAC_READ 116U /*!< GPDMA1 HW request is FMAC_READ */ +#define GPDMA1_REQUEST_FMAC_WRITE 117U /*!< GPDMA1 HW request is FMAC_WRITE */ +#endif /* FMAC */ +#if defined (SAES) +#define GPDMA1_REQUEST_SAES_OUT 118U /*!< GPDMA1 HW request is SAES_OUT */ +#define GPDMA1_REQUEST_SAES_IN 119U /*!< GPDMA1 HW request is SAES_IN */ +#endif /* SAES */ +#define GPDMA1_REQUEST_I3C1_RX 120U /*!< GPDMA1 HW request is I3C1_RX */ +#define GPDMA1_REQUEST_I3C1_TX 121U /*!< GPDMA1 HW request is I3C1_TX */ +#define GPDMA1_REQUEST_I3C1_TC 122U /*!< GPDMA1 HW request is I3C1_TC */ +#define GPDMA1_REQUEST_I3C1_RS 123U /*!< GPDMA1 HW request is I3C1_RS */ +#if defined (I2C4) +#define GPDMA1_REQUEST_I2C4_RX 124U /*!< GPDMA1 HW request is I2C4_RX */ +#define GPDMA1_REQUEST_I2C4_TX 125U /*!< GPDMA1 HW request is I2C4_TX */ +#endif /* I2C4 */ +#if defined (LPTIM3) +#define GPDMA1_REQUEST_LPTIM3_IC1 127U /*!< GPDMA1 HW request is LPTIM3_IC1 */ +#define GPDMA1_REQUEST_LPTIM3_IC2 128U /*!< GPDMA1 HW request is LPTIM3_IC2 */ +#define GPDMA1_REQUEST_LPTIM3_UE 129U /*!< GPDMA1 HW request is LPTIM3_UE */ +#endif /* LPTIM3 */ +#if defined (LPTIM5) +#define GPDMA1_REQUEST_LPTIM5_IC1 130U /*!< GPDMA1 HW request is LPTIM5_IC1 */ +#define GPDMA1_REQUEST_LPTIM5_IC2 131U /*!< GPDMA1 HW request is LPTIM5_IC2 */ +#define GPDMA1_REQUEST_LPTIM5_UE 132U /*!< GPDMA1 HW request is LPTIM5_UE */ +#endif /* LPTIM5 */ +#if defined (LPTIM6) +#define GPDMA1_REQUEST_LPTIM6_IC1 133U /*!< GPDMA1 HW request is LPTIM6_IC1 */ +#define GPDMA1_REQUEST_LPTIM6_IC2 134U /*!< GPDMA1 HW request is LPTIM6_IC2 */ +#define GPDMA1_REQUEST_LPTIM6_UE 135U /*!< GPDMA1 HW request is LPTIM6_UE */ +#endif /* LPTIM6 */ +#if defined (I3C2) +#define GPDMA1_REQUEST_I3C2_RX 136U /*!< GPDMA1 HW request is I3C2_RX */ +#define GPDMA1_REQUEST_I3C2_TX 137U /*!< GPDMA1 HW request is I3C2_TX */ +#define GPDMA1_REQUEST_I3C2_TC 138U /*!< GPDMA1 HW request is I3C2_TC */ +#define GPDMA1_REQUEST_I3C2_RS 139U /*!< GPDMA1 HW request is I3C2_RS */ +#endif /* I3C2 */ + +/* GPDMA2 requests */ +#define GPDMA2_REQUEST_ADC1 0U /*!< GPDMA2 HW request is ADC1 */ +#if defined (ADC2) +#define GPDMA2_REQUEST_ADC2 1U /*!< GPDMA2 HW request is ADC2 */ +#endif /* ADC2 */ +#define GPDMA2_REQUEST_DAC1_CH1 2U /*!< GPDMA2 HW request is DAC1_CH1 */ +#define GPDMA2_REQUEST_DAC1_CH2 3U /*!< GPDMA2 HW request is DAC1_CH2 */ +#define GPDMA2_REQUEST_TIM6_UP 4U /*!< GPDMA2 HW request is TIM6_UP */ +#define GPDMA2_REQUEST_TIM7_UP 5U /*!< GPDMA2 HW request is TIM7_UP */ +#define GPDMA2_REQUEST_SPI1_RX 6U /*!< GPDMA2 HW request is SPI1_RX */ +#define GPDMA2_REQUEST_SPI1_TX 7U /*!< GPDMA2 HW request is SPI1_TX */ +#define GPDMA2_REQUEST_SPI2_RX 8U /*!< GPDMA2 HW request is SPI2_RX */ +#define GPDMA2_REQUEST_SPI2_TX 9U /*!< GPDMA2 HW request is SPI2_TX */ +#define GPDMA2_REQUEST_SPI3_RX 10U /*!< GPDMA2 HW request is SPI3_RX */ +#define GPDMA2_REQUEST_SPI3_TX 11U /*!< GPDMA2 HW request is SPI3_TX */ +#define GPDMA2_REQUEST_I2C1_RX 12U /*!< GPDMA2 HW request is I2C1_RX */ +#define GPDMA2_REQUEST_I2C1_TX 13U /*!< GPDMA2 HW request is I2C1_TX */ +#define GPDMA2_REQUEST_I2C2_RX 15U /*!< GPDMA2 HW request is I2C2_RX */ +#define GPDMA2_REQUEST_I2C2_TX 16U /*!< GPDMA2 HW request is I2C2_TX */ +#if defined (I2C3) +#define GPDMA2_REQUEST_I2C3_RX 18U /*!< GPDMA2 HW request is I2C3_RX */ +#define GPDMA2_REQUEST_I2C3_TX 19U /*!< GPDMA2 HW request is I2C3_TX */ +#endif /* I2C3 */ +#define GPDMA2_REQUEST_USART1_RX 21U /*!< GPDMA2 HW request is USART1_RX */ +#define GPDMA2_REQUEST_USART1_TX 22U /*!< GPDMA2 HW request is USART1_TX */ +#define GPDMA2_REQUEST_USART2_RX 23U /*!< GPDMA2 HW request is USART2_RX */ +#define GPDMA2_REQUEST_USART2_TX 24U /*!< GPDMA2 HW request is USART2_TX */ +#define GPDMA2_REQUEST_USART3_RX 25U /*!< GPDMA2 HW request is USART3_RX */ +#define GPDMA2_REQUEST_USART3_TX 26U /*!< GPDMA2 HW request is USART3_TX */ +#if defined (UART4) +#define GPDMA2_REQUEST_UART4_RX 27U /*!< GPDMA2 HW request is UART4_RX */ +#define GPDMA2_REQUEST_UART4_TX 28U /*!< GPDMA2 HW request is UART4_TX */ +#endif /* UART4 */ +#if defined (UART4) +#define GPDMA2_REQUEST_UART5_RX 29U /*!< GPDMA2 HW request is UART5_RX */ +#define GPDMA2_REQUEST_UART5_TX 30U /*!< GPDMA2 HW request is UART5_TX */ +#endif /* UART5 */ +#if defined (UART4) +#define GPDMA2_REQUEST_USART6_RX 31U /*!< GPDMA2 HW request is USART6_RX */ +#define GPDMA2_REQUEST_USART6_TX 32U /*!< GPDMA2 HW request is USART6_TX */ +#endif /* USART6 */ +#if defined (UART7) +#define GPDMA2_REQUEST_UART7_RX 33U /*!< GPDMA2 HW request is UART7_RX */ +#define GPDMA2_REQUEST_UART7_TX 34U /*!< GPDMA2 HW request is UART7_TX */ +#endif /* UART7 */ +#if defined (UART8) +#define GPDMA2_REQUEST_UART8_RX 35U /*!< GPDMA2 HW request is UART8_RX */ +#define GPDMA2_REQUEST_UART8_TX 36U /*!< GPDMA2 HW request is UART8_TX */ +#endif /* UART8 */ +#if defined (UART9) +#define GPDMA2_REQUEST_UART9_RX 37U /*!< GPDMA2 HW request is UART9_RX */ +#define GPDMA2_REQUEST_UART9_TX 38U /*!< GPDMA2 HW request is UART9_TX */ +#endif /* UART9 */ +#if defined (USART10) +#define GPDMA2_REQUEST_USART10_RX 39U /*!< GPDMA2 HW request is USART10_RX */ +#define GPDMA2_REQUEST_USART10_TX 40U /*!< GPDMA2 HW request is USART10_TX */ +#endif /* USART10 */ +#if defined (USART11) +#define GPDMA2_REQUEST_USART11_RX 41U /*!< GPDMA2 HW request is USART11_RX */ +#define GPDMA2_REQUEST_USART11_TX 42U /*!< GPDMA2 HW request is USART11_TX */ +#endif /* USART11 */ +#if defined (UART12) +#define GPDMA2_REQUEST_UART12_RX 43U /*!< GPDMA2 HW request is UART12_RX */ +#define GPDMA2_REQUEST_UART12_TX 44U /*!< GPDMA2 HW request is UART12_TX */ +#endif /* UART12 */ +#define GPDMA2_REQUEST_LPUART1_RX 45U /*!< GPDMA2 HW request is LPUART1_RX */ +#define GPDMA2_REQUEST_LPUART1_TX 46U /*!< GPDMA2 HW request is LPUART1_TX */ +#if defined (SPI4) +#define GPDMA2_REQUEST_SPI4_RX 47U /*!< GPDMA2 HW request is SPI4_RX */ +#define GPDMA2_REQUEST_SPI4_TX 48U /*!< GPDMA2 HW request is SPI4_TX */ +#endif /* SPI4 */ +#if defined (SPI5) +#define GPDMA2_REQUEST_SPI5_RX 49U /*!< GPDMA2 HW request is SPI5_RX */ +#define GPDMA2_REQUEST_SPI5_TX 50U /*!< GPDMA2 HW request is SPI5_TX */ +#endif /* SPI5 */ +#if defined (SPI6) +#define GPDMA2_REQUEST_SPI6_RX 51U /*!< GPDMA2 HW request is SPI6_RX */ +#define GPDMA2_REQUEST_SPI6_TX 52U /*!< GPDMA2 HW request is SPI6_TX */ +#endif /* SPI6 */ +#if defined (SAI1) +#define GPDMA2_REQUEST_SAI1_A 53U /*!< GPDMA2 HW request is SAI1_A */ +#define GPDMA2_REQUEST_SAI1_B 54U /*!< GPDMA2 HW request is SAI1_B */ +#endif /* SAI1 */ +#if defined (SAI2) +#define GPDMA2_REQUEST_SAI2_A 55U /*!< GPDMA2 HW request is SAI2_A */ +#define GPDMA2_REQUEST_SAI2_B 56U /*!< GPDMA2 HW request is SAI2_B */ +#endif /* SAI2 */ +#if defined (OCTOSPI1) +#define GPDMA2_REQUEST_OCTOSPI1 57U /*!< GPDMA2 HW request is OCTOSPI1 */ +#endif /* OCTOSPI1 */ +#define GPDMA2_REQUEST_TIM1_CH1 58U /*!< GPDMA2 HW request is TIM1_CH1 */ +#define GPDMA2_REQUEST_TIM1_CH2 59U /*!< GPDMA2 HW request is TIM1_CH2 */ +#define GPDMA2_REQUEST_TIM1_CH3 60U /*!< GPDMA2 HW request is TIM1_CH3 */ +#define GPDMA2_REQUEST_TIM1_CH4 61U /*!< GPDMA2 HW request is TIM1_CH4 */ +#define GPDMA2_REQUEST_TIM1_UP 62U /*!< GPDMA2 HW request is TIM1_UP */ +#define GPDMA2_REQUEST_TIM1_TRIG 63U /*!< GPDMA2 HW request is TIM1_TRIG */ +#define GPDMA2_REQUEST_TIM1_COM 64U /*!< GPDMA2 HW request is TIM1_COM */ +#if defined (TIM8) +#define GPDMA2_REQUEST_TIM8_CH1 65U /*!< GPDMA2 HW request is TIM8_CH1 */ +#define GPDMA2_REQUEST_TIM8_CH2 66U /*!< GPDMA2 HW request is TIM8_CH2 */ +#define GPDMA2_REQUEST_TIM8_CH3 67U /*!< GPDMA2 HW request is TIM8_CH3 */ +#define GPDMA2_REQUEST_TIM8_CH4 68U /*!< GPDMA2 HW request is TIM8_CH4 */ +#define GPDMA2_REQUEST_TIM8_UP 69U /*!< GPDMA2 HW request is TIM8_UP */ +#define GPDMA2_REQUEST_TIM8_TRIG 70U /*!< GPDMA2 HW request is TIM8_TRIG */ +#define GPDMA2_REQUEST_TIM8_COM 71U /*!< GPDMA2 HW request is TIM8_COM */ +#endif /* TIM8 */ +#define GPDMA2_REQUEST_TIM2_CH1 72U /*!< GPDMA2 HW request is TIM2_CH1 */ +#define GPDMA2_REQUEST_TIM2_CH2 73U /*!< GPDMA2 HW request is TIM2_CH2 */ +#define GPDMA2_REQUEST_TIM2_CH3 74U /*!< GPDMA2 HW request is TIM2_CH3 */ +#define GPDMA2_REQUEST_TIM2_CH4 75U /*!< GPDMA2 HW request is TIM2_CH4 */ +#define GPDMA2_REQUEST_TIM2_UP 76U /*!< GPDMA2 HW request is TIM2_UP */ +#define GPDMA2_REQUEST_TIM3_CH1 77U /*!< GPDMA2 HW request is TIM3_CH1 */ +#define GPDMA2_REQUEST_TIM3_CH2 78U /*!< GPDMA2 HW request is TIM3_CH2 */ +#define GPDMA2_REQUEST_TIM3_CH3 79U /*!< GPDMA2 HW request is TIM3_CH3 */ +#define GPDMA2_REQUEST_TIM3_CH4 80U /*!< GPDMA2 HW request is TIM3_CH4 */ +#define GPDMA2_REQUEST_TIM3_UP 81U /*!< GPDMA2 HW request is TIM3_UP */ +#define GPDMA2_REQUEST_TIM3_TRIG 82U /*!< GPDMA2 HW request is TIM3_TRIG */ +#if defined (TIM4) +#define GPDMA2_REQUEST_TIM4_CH1 83U /*!< GPDMA2 HW request is TIM4_CH1 */ +#define GPDMA2_REQUEST_TIM4_CH2 84U /*!< GPDMA2 HW request is TIM4_CH2 */ +#define GPDMA2_REQUEST_TIM4_CH3 85U /*!< GPDMA2 HW request is TIM4_CH3 */ +#define GPDMA2_REQUEST_TIM4_CH4 86U /*!< GPDMA2 HW request is TIM4_CH4 */ +#define GPDMA2_REQUEST_TIM4_UP 87U /*!< GPDMA2 HW request is TIM4_UP */ +#endif /* TIM4 */ +#if defined (TIM5) +#define GPDMA2_REQUEST_TIM5_CH1 88U /*!< GPDMA2 HW request is TIM5_CH1 */ +#define GPDMA2_REQUEST_TIM5_CH2 89U /*!< GPDMA2 HW request is TIM5_CH2 */ +#define GPDMA2_REQUEST_TIM5_CH3 90U /*!< GPDMA2 HW request is TIM5_CH3 */ +#define GPDMA2_REQUEST_TIM5_CH4 91U /*!< GPDMA2 HW request is TIM5_CH4 */ +#define GPDMA2_REQUEST_TIM5_UP 92U /*!< GPDMA2 HW request is TIM5_UP */ +#define GPDMA2_REQUEST_TIM5_TRIG 93U /*!< GPDMA2 HW request is TIM5_TRIG */ +#endif /* TIM5 */ +#if defined (TIM15) +#define GPDMA2_REQUEST_TIM15_CH1 94U /*!< GPDMA2 HW request is TIM15_CH1 */ +#define GPDMA2_REQUEST_TIM15_UP 95U /*!< GPDMA2 HW request is TIM15_UP */ +#define GPDMA2_REQUEST_TIM15_TRIG 96U /*!< GPDMA2 HW request is TIM15_TRIG */ +#define GPDMA2_REQUEST_TIM15_COM 97U /*!< GPDMA2 HW request is TIM15_COM */ +#endif /* TIM15 */ +#if defined (TIM16) +#define GPDMA2_REQUEST_TIM16_CH1 98U /*!< GPDMA2 HW request is TIM16_CH1 */ +#define GPDMA2_REQUEST_TIM16_UP 99U /*!< GPDMA2 HW request is TIM16_UP */ +#endif /* TIM16 */ +#if defined (TIM17) +#define GPDMA2_REQUEST_TIM17_CH1 100U /*!< GPDMA2 HW request is TIM17_CH1 */ +#define GPDMA2_REQUEST_TIM17_UP 101U /*!< GPDMA2 HW request is TIM17_UP */ +#endif /* TIM17 */ +#define GPDMA2_REQUEST_LPTIM1_IC1 102U /*!< GPDMA2 HW request is LPTIM1_IC1 */ +#define GPDMA2_REQUEST_LPTIM1_IC2 103U /*!< GPDMA2 HW request is LPTIM1_IC2 */ +#define GPDMA2_REQUEST_LPTIM1_UE 104U /*!< GPDMA2 HW request is LPTIM1_UE */ +#define GPDMA2_REQUEST_LPTIM2_IC1 105U /*!< GPDMA2 HW request is LPTIM2_IC1 */ +#define GPDMA2_REQUEST_LPTIM2_IC2 106U /*!< GPDMA2 HW request is LPTIM2_IC2 */ +#define GPDMA2_REQUEST_LPTIM2_UE 107U /*!< GPDMA2 HW request is LPTIM2_UE */ +#if defined (DCMI) +#define GPDMA2_REQUEST_DCMI 108U /*!< GPDMA2 HW request is DCMI */ +#endif /* DCMI */ +#if defined (AES) +#define GPDMA2_REQUEST_AES_OUT 109U /*!< GPDMA2 HW request is AES_OUT */ +#define GPDMA2_REQUEST_AES_IN 110U /*!< GPDMA2 HW request is AES_IN */ +#endif /* AES */ +#define GPDMA2_REQUEST_HASH_IN 111U /*!< GPDMA2 HW request is HASH_IN */ +#if defined (UCPD1) +#define GPDMA2_REQUEST_UCPD1_RX 112U /*!< GPDMA2 HW request is UCPD1_RX */ +#define GPDMA2_REQUEST_UCPD1_TX 113U /*!< GPDMA2 HW request is UCPD1_TX */ +#endif /* UCPD1 */ +#if defined (CORDIC) +#define GPDMA2_REQUEST_CORDIC_READ 114U /*!< GPDMA2 HW request is CORDIC_READ */ +#define GPDMA2_REQUEST_CORDIC_WRITE 115U /*!< GPDMA2 HW request is CORDIC_WRITE */ +#endif /* CORDIC */ +#if defined (FMAC) +#define GPDMA2_REQUEST_FMAC_READ 116U /*!< GPDMA2 HW request is FMAC_READ */ +#define GPDMA2_REQUEST_FMAC_WRITE 117U /*!< GPDMA2 HW request is FMAC_WRITE */ +#endif /* FMAC */ +#if defined (SAES) +#define GPDMA2_REQUEST_SAES_OUT 118U /*!< GPDMA2 HW request is SAES_OUT */ +#define GPDMA2_REQUEST_SAES_IN 119U /*!< GPDMA2 HW request is SAES_IN */ +#endif /* SAES */ +#define GPDMA2_REQUEST_I3C1_RX 120U /*!< GPDMA2 HW request is I3C1_RX */ +#define GPDMA2_REQUEST_I3C1_TX 121U /*!< GPDMA2 HW request is I3C1_TX */ +#define GPDMA2_REQUEST_I3C1_TC 122U /*!< GPDMA2 HW request is I3C1_TC */ +#define GPDMA2_REQUEST_I3C1_RS 123U /*!< GPDMA2 HW request is I3C1_RS */ +#if defined (I2C4) +#define GPDMA2_REQUEST_I2C4_RX 124U /*!< GPDMA2 HW request is I2C4_RX */ +#define GPDMA2_REQUEST_I2C4_TX 125U /*!< GPDMA2 HW request is I2C4_TX */ +#endif /* I2C4 */ +#if defined (LPTIM3) +#define GPDMA2_REQUEST_LPTIM3_IC1 127U /*!< GPDMA2 HW request is LPTIM3_IC1 */ +#define GPDMA2_REQUEST_LPTIM3_IC2 128U /*!< GPDMA2 HW request is LPTIM3_IC2 */ +#define GPDMA2_REQUEST_LPTIM3_UE 129U /*!< GPDMA2 HW request is LPTIM3_UE */ +#endif /* LPTIM3 */ +#if defined (LPTIM5) +#define GPDMA2_REQUEST_LPTIM5_IC1 130U /*!< GPDMA2 HW request is LPTIM5_IC1 */ +#define GPDMA2_REQUEST_LPTIM5_IC2 131U /*!< GPDMA2 HW request is LPTIM5_IC2 */ +#define GPDMA2_REQUEST_LPTIM5_UE 132U /*!< GPDMA2 HW request is LPTIM5_UE */ +#endif /* LPTIM5 */ +#if defined (LPTIM6) +#define GPDMA2_REQUEST_LPTIM6_IC1 133U /*!< GPDMA2 HW request is LPTIM6_IC1 */ +#define GPDMA2_REQUEST_LPTIM6_IC2 134U /*!< GPDMA2 HW request is LPTIM6_IC2 */ +#define GPDMA2_REQUEST_LPTIM6_UE 135U /*!< GPDMA2 HW request is LPTIM6_UE */ +#endif /* LPTIM6 */ +#if defined (I3C2) +#define GPDMA2_REQUEST_I3C2_RX 136U /*!< GPDMA2 HW request is I3C2_RX */ +#define GPDMA2_REQUEST_I3C2_TX 137U /*!< GPDMA2 HW request is I3C2_TX */ +#define GPDMA2_REQUEST_I3C2_TC 138U /*!< GPDMA2 HW request is I3C2_TC */ +#define GPDMA2_REQUEST_I3C2_RS 139U /*!< GPDMA2 HW request is I3C2_RS */ +#endif /* I3C2 */ + +/* Software request */ +#define DMA_REQUEST_SW DMA_CTR2_SWREQ /*!< DMA SW request */ +/** + * @} + */ + +/** @defgroup DMA_Block_Request DMA Block Request + * @brief DMA Block Request + * @{ + */ +#define DMA_BREQ_SINGLE_BURST 0x00000000U /*!< Hardware request protocol at a single / burst level */ +#define DMA_BREQ_BLOCK DMA_CTR2_BREQ /*!< Hardware request protocol at a block level */ +/** + * @} + */ + +/** @defgroup DMA_Transfer_Direction DMA Transfer Direction + * @brief DMA transfer direction + * @{ + */ +#define DMA_PERIPH_TO_MEMORY 0x00000000U /*!< Peripheral to memory direction */ +#define DMA_MEMORY_TO_PERIPH DMA_CTR2_DREQ /*!< Memory to peripheral direction */ +#define DMA_MEMORY_TO_MEMORY DMA_CTR2_SWREQ /*!< Memory to memory direction */ +/** + * @} + */ + +/** @defgroup DMA_Source_Increment_Mode DMA Source Increment Mode + * @brief DMA Source Increment Mode + * @{ + */ +#define DMA_SINC_FIXED 0x00000000U /*!< Source fixed single / burst */ +#define DMA_SINC_INCREMENTED DMA_CTR1_SINC /*!< Source incremented single / burst */ +/** + * @} + */ + +/** @defgroup DMA_Destination_Increment_Mode DMA Destination Increment Mode + * @brief DMA Destination Increment Mode + * @{ + */ +#define DMA_DINC_FIXED 0x00000000U /*!< Destination fixed single / burst */ +#define DMA_DINC_INCREMENTED DMA_CTR1_DINC /*!< Destination incremented single / burst */ +/** + * @} + */ + +/** @defgroup DMA_Source_Data_Width DMA Source Data Width + * @brief DMA Source Data Width + * @{ + */ +#define DMA_SRC_DATAWIDTH_BYTE 0x00000000U /*!< Source data width : Byte */ +#define DMA_SRC_DATAWIDTH_HALFWORD DMA_CTR1_SDW_LOG2_0 /*!< Source data width : HalfWord */ +#define DMA_SRC_DATAWIDTH_WORD DMA_CTR1_SDW_LOG2_1 /*!< Source data width : Word */ +/** + * @} + */ + +/** @defgroup DMA_Destination_Data_Width DMA destination Data Width + * @brief DMA destination Data Width + * @{ + */ +#define DMA_DEST_DATAWIDTH_BYTE 0x00000000U /*!< Destination data width : Byte */ +#define DMA_DEST_DATAWIDTH_HALFWORD DMA_CTR1_DDW_LOG2_0 /*!< Destination data width : HalfWord */ +#define DMA_DEST_DATAWIDTH_WORD DMA_CTR1_DDW_LOG2_1 /*!< Destination data width : Word */ + +/** + * @} + */ + +/** @defgroup DMA_Priority_Level DMA Priority Level + * @brief DMA Priority Level + * @{ + */ +#define DMA_LOW_PRIORITY_LOW_WEIGHT 0x00000000U /*!< Priority level : Low Priority, Low weight */ +#define DMA_LOW_PRIORITY_MID_WEIGHT DMA_CCR_PRIO_0 /*!< Priority level : Low Priority, Mid weight */ +#define DMA_LOW_PRIORITY_HIGH_WEIGHT DMA_CCR_PRIO_1 /*!< Priority level : Low Priority, High weight */ +#define DMA_HIGH_PRIORITY DMA_CCR_PRIO /*!< Priority level : HIGH Priority */ +/** + * @} + */ + +/** @defgroup DMA_Transfer_Allocated_Port DMA Transfer Allocated Port + * @brief DMA Transfer Allocated Port + * @{ + */ +#define DMA_SRC_ALLOCATED_PORT0 0x00000000U /*!< Source allocated Port 0 */ +#define DMA_SRC_ALLOCATED_PORT1 DMA_CTR1_SAP /*!< Source allocated Port 1 */ +#define DMA_DEST_ALLOCATED_PORT0 0x00000000U /*!< Destination allocated Port 0 */ +#define DMA_DEST_ALLOCATED_PORT1 DMA_CTR1_DAP /*!< Destination allocated Port 1 */ +/** + * @} + */ + +/** @defgroup DMA_Transfer_Event_Mode DMA Transfer Event Mode + * @brief DMA Transfer Event Mode + * @{ + */ +#define DMA_TCEM_BLOCK_TRANSFER 0x00000000U /*!< The TC event is generated at the end of each block and the + HT event is generated at the half of each block */ +#define DMA_TCEM_REPEATED_BLOCK_TRANSFER DMA_CTR2_TCEM_0 /*!< The TC event is generated at the end of the repeated block + and the HT event is generated at the half of the repeated + block */ +#define DMA_TCEM_EACH_LL_ITEM_TRANSFER DMA_CTR2_TCEM_1 /*!< The TC event is generated at the end of each linked-list + item and the HT event is generated at the half of each + linked-list item */ +#define DMA_TCEM_LAST_LL_ITEM_TRANSFER DMA_CTR2_TCEM /*!< The TC event is generated at the end of the last + linked-list item and the HT event is generated at the half + of the last linked-list item */ +/** + * @} + */ + +/** @defgroup DMA_Transfer_Mode DMA Transfer Mode + * @brief DMA Transfer Mode + * @{ + */ +#define DMA_NORMAL (0x00U) /*!< Normal DMA transfer */ +#define DMA_PFCTRL DMA_CTR2_PFREQ /*!< HW request peripheral flow control mode */ +/** + * @} + */ + +/** @defgroup DMA_Channel_Attributes DMA Channel Attributes + * @brief DMA Channel Security and Privilege Attributes + * @note Secure and non-secure attributes are only available from the secure world when TZEN = 1 + * @{ + */ +#define DMA_CHANNEL_PRIV (DMA_CHANNEL_ATTR_PRIV_MASK | 0x01U) /*!< Channel is privileged */ +#define DMA_CHANNEL_NPRIV (DMA_CHANNEL_ATTR_PRIV_MASK) /*!< Channel is unprivileged */ + +#define DMA_CHANNEL_SEC (DMA_CHANNEL_ATTR_SEC_MASK | 0x02U) /*!< Channel is secure */ +#define DMA_CHANNEL_NSEC (DMA_CHANNEL_ATTR_SEC_MASK) /*!< Channel is non-secure */ +#define DMA_CHANNEL_SRC_SEC (DMA_CHANNEL_ATTR_SEC_SRC_MASK | 0x04U) /*!< Channel source is secure */ +#define DMA_CHANNEL_SRC_NSEC (DMA_CHANNEL_ATTR_SEC_SRC_MASK) /*!< Channel source is non-secure */ +#define DMA_CHANNEL_DEST_SEC (DMA_CHANNEL_ATTR_SEC_DEST_MASK | 0x08U) /*!< Channel destination is secure */ +#define DMA_CHANNEL_DEST_NSEC (DMA_CHANNEL_ATTR_SEC_DEST_MASK) /*!< Channel destination is non-secure */ + +#define DMA_CHANNEL_ATTRIBUTE_UNLOCKED (0x00U) /*!< Channel attribute is unlocked */ +#define DMA_CHANNEL_ATTRIBUTE_LOCKED (0x01U) /*!< Channel attribute is locked */ +/** + * @} + */ + + + +/** + * @} + */ + + +/* Exported macro ----------------------------------------------------------------------------------------------------*/ +/** @defgroup DMA_Exported_Macros DMA Exported Macros + * @brief DMA Exported Macros + * @{ + */ + +/** @brief Reset DMA handle state. + * @param __HANDLE__ : DMA handle. + * @retval None. + */ +#define __HAL_DMA_RESET_HANDLE_STATE(__HANDLE__) \ + ((__HANDLE__)->State = HAL_DMA_STATE_RESET) + +/** + * @brief Enable the specified DMA Channel. + * @param __HANDLE__ : DMA handle. + * @retval None + */ +#define __HAL_DMA_ENABLE(__HANDLE__) \ + ((__HANDLE__)->Instance->CCR |= DMA_CCR_EN) + +/** + * @brief Disable the specified DMA Channel. + * @param __HANDLE__ : DMA handle. + * @retval None + */ +#define __HAL_DMA_DISABLE(__HANDLE__) \ + ((__HANDLE__)->Instance->CCR |= (DMA_CCR_SUSP | DMA_CCR_RESET)) + +/** + * @brief Get the DMA channel pending flags. + * @param __HANDLE__ : DMA handle. + * @param __FLAG__ : Get the specified flag. + * This parameter can be any combination of the following values: + * @arg DMA_FLAG_TC : Transfer Complete flag. + * @arg DMA_FLAG_HT : Half Transfer Complete flag. + * @arg DMA_FLAG_DTE : Data Transfer Error flag. + * @arg DMA_FLAG_ULE : Update linked-list Error flag. + * @arg DMA_FLAG_USE : User Setting Error flag. + * @arg DMA_FLAG_TO : Trigger Overrun flag. + * @arg DMA_FLAG_SUSP : Completed Suspension flag. + * @arg DMA_FLAG_IDLEF : Idle flag. + * @retval The state of FLAG (SET or RESET). + */ +#define __HAL_DMA_GET_FLAG(__HANDLE__, __FLAG__) \ + ((__HANDLE__)->Instance->CSR & (__FLAG__)) + +/** + * @brief Clear the DMA Channel pending flags. + * @param __HANDLE__ : DMA handle. + * @param __FLAG__ : Specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg DMA_FLAG_TC : Transfer Complete flag. + * @arg DMA_FLAG_HT : Half Transfer Complete flag. + * @arg DMA_FLAG_DTE : Data Transfer Error flag. + * @arg DMA_FLAG_ULE : Update Linked-List Error flag. + * @arg DMA_FLAG_USE : User Setting Error flag. + * @arg DMA_FLAG_TO : Trigger Overrun flag. + * @arg DMA_FLAG_SUSP : Completed Suspension flag. + * @retval None + */ +#define __HAL_DMA_CLEAR_FLAG(__HANDLE__, __FLAG__) \ + ((__HANDLE__)->Instance->CFCR = (__FLAG__)) + +/** + * @brief Enable the specified DMA Channel interrupts. + * @param __HANDLE__ : DMA handle. + * @param __INTERRUPT__ : Specifies the DMA interrupt sources to be enabled. + * This parameter can be any combination of the following values: + * @arg DMA_IT_TC : Transfer Complete interrupt. + * @arg DMA_IT_HT : Half Transfer Complete interrupt. + * @arg DMA_IT_DTE : Data Transfer Error interrupt. + * @arg DMA_IT_ULE : Update Linked-List Error interrupt. + * @arg DMA_IT_USE : User Setting Error interrupt. + * @arg DMA_IT_TO : Trigger Overrun interrupt. + * @arg DMA_IT_SUSP : Completed Suspension interrupt. + * @retval None + */ +#define __HAL_DMA_ENABLE_IT(__HANDLE__, __INTERRUPT__) \ + ((__HANDLE__)->Instance->CCR |= (__INTERRUPT__)) + +/** + * @brief Disable the specified DMA Channel interrupts. + * @param __HANDLE__ : DMA handle. + * @param __INTERRUPT__ : specifies the DMA interrupt sources to be disabled. + * This parameter can be any combination of the following values: + * @arg DMA_IT_TC : Transfer Complete interrupt. + * @arg DMA_IT_HT : Half Transfer Complete interrupt. + * @arg DMA_IT_DTE : Data Transfer Error interrupt. + * @arg DMA_IT_ULE : Update Linked-List Error interrupt. + * @arg DMA_IT_USE : User Setting Error interrupt. + * @arg DMA_IT_TO : Trigger Overrun interrupt. + * @arg DMA_IT_SUSP : Completed Suspension interrupt. + * @retval None + */ +#define __HAL_DMA_DISABLE_IT(__HANDLE__, __INTERRUPT__) \ + ((__HANDLE__)->Instance->CCR &= ~(__INTERRUPT__)) + +/** + * @brief Checks whether the specified DMA Channel interrupt is enabled or not. + * @param __HANDLE__ : DMA handle. + * @param __INTERRUPT__ : specifies the DMA interrupt source to check. + * @arg DMA_IT_TC : Transfer Complete interrupt. + * @arg DMA_IT_HT : Half Transfer Complete interrupt. + * @arg DMA_IT_DTE : Data Transfer Error interrupt. + * @arg DMA_IT_ULE : Update Linked-List Error interrupt. + * @arg DMA_IT_USE : User Setting Error interrupt. + * @arg DMA_IT_TO : Trigger Overrun interrupt. + * @arg DMA_IT_SUSP : Completed Suspension interrupt. + * @retval The state of DMA_IT (SET or RESET). + */ +#define __HAL_DMA_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) \ + (((__HANDLE__)->Instance->CCR & (__INTERRUPT__))) + +/** + * @brief Writes the block number of bytes to be transferred from the source on the DMA Channel. + * @param __HANDLE__ : DMA handle. + * @param __COUNTER__ : Number of data bytes to be transferred from the source (from 0 to 65535). + */ +#define __HAL_DMA_SET_COUNTER(__HANDLE__, __COUNTER__) \ + MODIFY_REG((__HANDLE__)->Instance->CBR1, DMA_CBR1_BNDT, (__COUNTER__)) + +/** + * @brief Returns the number of remaining data bytes in the current DMA Channel transfer. + * @param __HANDLE__ : DMA handle. + * @retval The number of remaining data units in the current DMA Stream transfer. + */ +#define __HAL_DMA_GET_COUNTER(__HANDLE__) \ + (((__HANDLE__)->Instance->CBR1) & DMA_CBR1_BNDT) +/** + * @} + */ + + +/* Include DMA HAL Extension module */ +#include "stm32h5xx_hal_dma_ex.h" + + +/* Exported functions ------------------------------------------------------------------------------------------------*/ +/** @defgroup DMA_Exported_Functions DMA Exported Functions + * @brief DMA Exported Functions + * @{ + */ + +/** @defgroup DMA_Exported_Functions_Group1 Initialization and De-Initialization Functions + * @brief Initialization and De-Initialization Functions + * @{ + */ +HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *const hdma); +HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *const hdma); +/** + * @} + */ + +/** @defgroup DMA_Exported_Functions_Group2 I/O Operation Functions + * @brief I/O Operation Functions + * @{ + */ +HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *const hdma, + uint32_t SrcAddress, + uint32_t DstAddress, + uint32_t SrcDataSize); +HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *const hdma, + uint32_t SrcAddress, + uint32_t DstAddress, + uint32_t SrcDataSize); +HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *const hdma); +HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *const hdma); +HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *const hdma, + HAL_DMA_LevelCompleteTypeDef CompleteLevel, + uint32_t Timeout); +void HAL_DMA_IRQHandler(DMA_HandleTypeDef *const hdma); +HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *const hdma, + HAL_DMA_CallbackIDTypeDef CallbackID, + void (*const pCallback)(DMA_HandleTypeDef *const _hdma)); +HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *const hdma, + HAL_DMA_CallbackIDTypeDef CallbackID); +/** + * @} + */ + +/** @defgroup DMA_Exported_Functions_Group3 State and Error Functions + * @brief State and Error Functions + * @{ + */ +HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef const *const hdma); +uint32_t HAL_DMA_GetError(DMA_HandleTypeDef const *const hdma); +/** + * @} + */ + +/** @defgroup DMA_Exported_Functions_Group4 DMA Attributes Functions + * @brief DMA Attributes Functions + * @{ + */ + +HAL_StatusTypeDef HAL_DMA_ConfigChannelAttributes(DMA_HandleTypeDef *const hdma, + uint32_t ChannelAttributes); +HAL_StatusTypeDef HAL_DMA_GetConfigChannelAttributes(DMA_HandleTypeDef const *const hdma, + uint32_t *const pChannelAttributes); + +#if defined (DMA_RCFGLOCKR_LOCK0) +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +HAL_StatusTypeDef HAL_DMA_LockChannelAttributes(DMA_HandleTypeDef const *const hdma); +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +HAL_StatusTypeDef HAL_DMA_GetLockChannelAttributes(DMA_HandleTypeDef const *const hdma, + uint32_t *const pLockState); + +#endif /* defined (DMA_RCFGLOCKR_LOCK0) */ + +/** + * @} + */ + +/** + * @} + */ + + +/* Private constants -------------------------------------------------------------------------------------------------*/ +/** @defgroup DMA_Private_Constants DMA Private Constants + * @brief DMA Private Constants + * @{ + */ +#define HAL_TIMEOUT_DMA_ABORT (0x00000005U) /* DMA channel abort timeout 5 milli-second */ +#define HAL_DMA_CHANNEL_START (0x00000050U) /* DMA channel offset */ +#define HAL_DMA_CHANNEL_SIZE (0x00000080U) /* DMA channel size */ +#define HAL_DMA_OFFSET_MASK (0x00000FFFU) /* DMA channel offset mask */ +#define DMA_CHANNEL_ATTR_PRIV_MASK (0x00000010U) /* DMA channel privilege mask */ +#define DMA_CHANNEL_ATTR_SEC_MASK (0x00000020U) /* DMA channel secure mask */ +#define DMA_CHANNEL_ATTR_SEC_SRC_MASK (0x00000040U) /* DMA channel source secure mask */ +#define DMA_CHANNEL_ATTR_SEC_DEST_MASK (0x00000080U) /* DMA channel destination secure mask */ +#define DMA_CHANNEL_ATTR_VALUE_MASK (0x0000000FU) /* DMA channel attributes value mask */ +#define DMA_CHANNEL_ATTR_ITEM_MASK (0x000000F0U) /* DMA channel attributes item mask */ +#define DMA_CHANNEL_BURST_MIN (0x00000001U) /* DMA channel minimum burst size */ +#define DMA_CHANNEL_BURST_MAX (0x00000040U) /* DMA channel maximum burst size */ +/** + * @} + */ + + +/* Private macros ----------------------------------------------------------------------------------------------------*/ +/** @defgroup DMA_Private_Macros DMA Private Macros + * @brief DMA Private Macros + * @{ + */ +#define GET_DMA_INSTANCE(__HANDLE__) \ + ((DMA_TypeDef *)((uint32_t)((__HANDLE__)->Instance) & (~HAL_DMA_OFFSET_MASK))) + +#define GET_DMA_CHANNEL(__HANDLE__) \ + ((((uint32_t)((__HANDLE__)->Instance) & HAL_DMA_OFFSET_MASK) - HAL_DMA_CHANNEL_START) / HAL_DMA_CHANNEL_SIZE) + +#define IS_DMA_MODE(MODE) \ + (((MODE) == DMA_NORMAL) || \ + ((MODE) == DMA_PFCTRL)) + +#define IS_DMA_DIRECTION(DIRECTION) \ + (((DIRECTION) == DMA_PERIPH_TO_MEMORY) || \ + ((DIRECTION) == DMA_MEMORY_TO_PERIPH) || \ + ((DIRECTION) == DMA_MEMORY_TO_MEMORY)) + +#define IS_DMA_LEVEL_COMPLETE(LEVEL) \ + (((LEVEL) == HAL_DMA_FULL_TRANSFER) || \ + ((LEVEL) == HAL_DMA_HALF_TRANSFER)) + +#define IS_DMA_SOURCE_INC(INC) \ + (((INC) == DMA_SINC_FIXED) || \ + ((INC) == DMA_SINC_INCREMENTED)) + +#define IS_DMA_DESTINATION_INC(INC) \ + (((INC) == DMA_DINC_FIXED) || \ + ((INC) == DMA_DINC_INCREMENTED)) + +#define IS_DMA_SOURCE_DATA_WIDTH(WIDTH) \ + (((WIDTH) == DMA_SRC_DATAWIDTH_BYTE) || \ + ((WIDTH) == DMA_SRC_DATAWIDTH_HALFWORD) || \ + ((WIDTH) == DMA_SRC_DATAWIDTH_WORD)) + +#define IS_DMA_DESTINATION_DATA_WIDTH(WIDTH) \ + (((WIDTH) == DMA_DEST_DATAWIDTH_BYTE) || \ + ((WIDTH) == DMA_DEST_DATAWIDTH_HALFWORD) || \ + ((WIDTH) == DMA_DEST_DATAWIDTH_WORD)) + +#define IS_DMA_BURST_LENGTH(LENGTH) \ + (((LENGTH) >= DMA_CHANNEL_BURST_MIN) && \ + ((LENGTH) <= DMA_CHANNEL_BURST_MAX)) + +#define IS_DMA_PRIORITY(PRIORITY) \ + (((PRIORITY) == DMA_LOW_PRIORITY_LOW_WEIGHT) || \ + ((PRIORITY) == DMA_LOW_PRIORITY_MID_WEIGHT) || \ + ((PRIORITY) == DMA_LOW_PRIORITY_HIGH_WEIGHT) || \ + ((PRIORITY) == DMA_HIGH_PRIORITY)) + +#define IS_DMA_TRANSFER_ALLOCATED_PORT(ALLOCATED_PORT) \ + (((ALLOCATED_PORT) & (~(DMA_CTR1_SAP | DMA_CTR1_DAP))) == 0U) + +#if defined (I3C2) +#define IS_DMA_REQUEST(REQUEST) (((REQUEST) == DMA_REQUEST_SW) || ((REQUEST) <= GPDMA1_REQUEST_I3C2_RS)) +#else +#define IS_DMA_REQUEST(REQUEST) (((REQUEST) == DMA_REQUEST_SW) || ((REQUEST) <= GPDMA1_REQUEST_LPTIM6_UE)) +#endif /* I3C2 */ + +#define IS_DMA_BLOCK_HW_REQUEST(MODE) \ + (((MODE) == DMA_BREQ_SINGLE_BURST) || \ + ((MODE) == DMA_BREQ_BLOCK)) + +#define IS_DMA_TCEM_EVENT_MODE(MODE) \ + (((MODE) == DMA_TCEM_BLOCK_TRANSFER) || \ + ((MODE) == DMA_TCEM_REPEATED_BLOCK_TRANSFER) || \ + ((MODE) == DMA_TCEM_EACH_LL_ITEM_TRANSFER) || \ + ((MODE) == DMA_TCEM_LAST_LL_ITEM_TRANSFER)) + +#define IS_DMA_BLOCK_SIZE(SIZE) \ + (((SIZE) > 0U) && ((SIZE) <= DMA_CBR1_BNDT)) + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define IS_DMA_ATTRIBUTES(ATTRIBUTE) \ + (((ATTRIBUTE) != 0U) && (((ATTRIBUTE) & (~(DMA_CHANNEL_ATTR_VALUE_MASK | DMA_CHANNEL_ATTR_ITEM_MASK))) == 0U) && \ + (((((ATTRIBUTE) & DMA_CHANNEL_ATTR_ITEM_MASK) >> 4U) | ((ATTRIBUTE) & DMA_CHANNEL_ATTR_VALUE_MASK)) == \ + (((ATTRIBUTE) & DMA_CHANNEL_ATTR_ITEM_MASK) >> 4U))) +#else +#define IS_DMA_ATTRIBUTES(ATTRIBUTE) \ + (((ATTRIBUTE) == DMA_CHANNEL_PRIV) || \ + ((ATTRIBUTE) == DMA_CHANNEL_NPRIV)) +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define IS_DMA_GLOBAL_ACTIVE_FLAG_S(INSTANCE, GLOBAL_FLAG) \ + (((INSTANCE)->SMISR & (GLOBAL_FLAG))) +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +#define IS_DMA_GLOBAL_ACTIVE_FLAG_NS(INSTANCE, GLOBAL_FLAG) \ + (((INSTANCE)->MISR & (GLOBAL_FLAG))) + +/** + * @} + */ + + +/* Private functions -------------------------------------------------------------------------------------------------*/ +/** @defgroup DMA_Private_Functions DMA Private Functions + * @brief DMA Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_DMA_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_dma_ex.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_dma_ex.h new file mode 100644 index 0000000000..916d610f75 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_dma_ex.h @@ -0,0 +1,737 @@ +/** + ********************************************************************************************************************** + * @file stm32h5xx_hal_dma_ex.h + * @author MCD Application Team + * @brief Header file of DMA HAL extension module. + ********************************************************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ********************************************************************************************************************** + */ + +/* Define to prevent recursive inclusion -----------------------------------------------------------------------------*/ +#ifndef STM32H5xx_HAL_DMA_EX_H +#define STM32H5xx_HAL_DMA_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ----------------------------------------------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup DMAEx + * @{ + */ + +/* Exported types ----------------------------------------------------------------------------------------------------*/ +/** @defgroup DMAEx_Exported_Types DMAEx Exported Types + * @brief DMAEx Exported types + * @{ + */ + +/** + * @brief DMAEx Data Handling Configuration Structure Definition. + */ +typedef struct +{ + uint32_t DataExchange; /*!< Specifies the DMA channel data exchange mode. + This parameter can be a value of @ref DMAEx_Data_Exchange */ + + uint32_t DataAlignment; /*!< Specifies the DMA channel data padding and alignment mode + This parameter can be a value of @ref DMAEx_Data_Alignment */ + +} DMA_DataHandlingConfTypeDef; + +/** + * @brief DMAEx Trigger Configuration Structure Definition. + */ +typedef struct +{ + uint32_t TriggerMode; /*!< Specifies the DMA channel trigger mode. + This parameter can be a value of @ref DMAEx_Trigger_Mode */ + + uint32_t TriggerPolarity; /*!< Specifies the DMA channel trigger event polarity. + This parameter can be a value of @ref DMAEx_Trigger_Polarity */ + + uint32_t TriggerSelection; /*!< Specifies the DMA channel trigger event selection. + This parameter can be a value of @ref DMAEx_Trigger_Selection */ + +} DMA_TriggerConfTypeDef; + +/** + * @brief DMAEx Repeated Block Configuration Structure Definition. + */ +typedef struct +{ + uint32_t RepeatCount; /*!< Specifies the DMA channel repeat count (the number of repetitions of block). + This parameter can be a value between 1 and 2048 */ + + int32_t SrcAddrOffset; /*!< Specifies the DMA channel single/burst source address offset : + This parameter can be a value between -8191 and 8191. + * If source address offset > 0 => Increment the source address by offset from where + the last single/burst transfer ends. + * If source address offset < 0 => Decrement the source address by offset from where + the last single/burst transfer ends. + * If source address offset == 0 => The next single/burst source address starts from + where the last transfer ends */ + + int32_t DestAddrOffset; /*!< Specifies the DMA channel single/burst destination address offset signed value : + This parameter can be a value between -8191 and 8191. + * If destination address offset > 0 => Increment the destination address by offset + from where the last single/burst transfer ends. + * If destination address offset < 0 => Decrement the destination address by offset + from where the last single/burst transfer ends. + * If destination address offset == 0 => The next single/burst destination address + starts from where the last transfer ends. */ + + int32_t BlkSrcAddrOffset; /*!< Specifies the DMA channel block source address offset signed value : + This parameter can be a value between -65535 and 65535. + * If block source address offset > 0 => Increment the block source address by offset + from where the last block ends. + * If block source address offset < 0 => Decrement the next block source address by + offset from where the last block ends. + * If block source address offset == 0 => the next block source address starts from + where the last block ends */ + + int32_t BlkDestAddrOffset; /*!< Specifies the DMA channel block destination address offset signed value : + This parameter can be a value between -65535 and 65535. + * If block destination address offset > 0 => Increment the block destination address + by offset from where the last block ends. + * If block destination address offset < 0 => Decrement the next block destination + address by offset from where the last block ends. + * If block destination address offset == 0 => the next block destination address + starts from where the last block ends */ + +} DMA_RepeatBlockConfTypeDef; + +/** + * @brief DMAEx Queue State Enumeration Definition. + */ +typedef enum +{ + HAL_DMA_QUEUE_STATE_RESET = 0x00U, /*!< DMA queue empty */ + HAL_DMA_QUEUE_STATE_READY = 0x01U, /*!< DMA queue ready for use */ + HAL_DMA_QUEUE_STATE_BUSY = 0x02U /*!< DMA queue execution on going */ + +} HAL_DMA_QStateTypeDef; + +/** + * @brief DMAEx Linked-List Node Configuration Structure Definition. + */ +typedef struct +{ + uint32_t NodeType; /*!< Specifies the DMA channel node type. + This parameter can be a value of @ref DMAEx_Node_Type */ + + DMA_InitTypeDef Init; /*!< Specifies the DMA channel basic configuration */ + + DMA_DataHandlingConfTypeDef DataHandlingConfig; /*!< Specifies the DMA channel data handling channel configuration */ + + DMA_TriggerConfTypeDef TriggerConfig; /*!< Specifies the DMA channel trigger configuration */ + + DMA_RepeatBlockConfTypeDef RepeatBlockConfig; /*!< Specifies the DMA channel repeated block configuration */ + + uint32_t SrcAddress; /*!< Specifies the source memory address */ + uint32_t DstAddress; /*!< Specifies the destination memory address */ + uint32_t DataSize; /*!< Specifies the source data size in bytes */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + uint32_t SrcSecure; /*!< Specifies the source security attribute */ + uint32_t DestSecure; /*!< Specifies the destination security attribute */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +} DMA_NodeConfTypeDef; + +/** + * @brief DMAEx Linked-List Node Structure Definition. + */ +typedef struct +{ + uint32_t LinkRegisters[8U]; /*!< Physical Node register description */ + uint32_t NodeInfo; /*!< Node information */ + +} DMA_NodeTypeDef; + +/** + * @brief DMAEx Linked-List Queue Structure Definition. + */ +typedef struct __DMA_QListTypeDef +{ + DMA_NodeTypeDef *Head; /*!< Specifies the queue head node */ + + DMA_NodeTypeDef *FirstCircularNode; /*!< Specifies the queue first circular node */ + + uint32_t NodeNumber; /*!< Specifies the queue node number */ + + __IO HAL_DMA_QStateTypeDef State; /*!< Specifies the queue state */ + + __IO uint32_t ErrorCode; /*!< Specifies the queue error code */ + + __IO uint32_t Type; /*!< Specifies whether the queue is static or dynamic */ + +} DMA_QListTypeDef; +/** + * @} + */ + +/* Exported constants ------------------------------------------------------------------------------------------------*/ +/** @defgroup DMAEx_Exported_Constants DMAEx Exported Constants + * @brief DMAEx Exported Constants + * @{ + */ + +/** @defgroup Queue_Error_Codes Queue Error Codes + * @brief Queue Error Codes + * @{ + */ +#define HAL_DMA_QUEUE_ERROR_NONE (0x00U) /*!< No error */ +#define HAL_DMA_QUEUE_ERROR_BUSY (0x01U) /*!< Error busy */ +#define HAL_DMA_QUEUE_ERROR_EMPTY (0x02U) /*!< Error unallowed operation for empty queue */ +#define HAL_DMA_QUEUE_ERROR_UNSUPPORTED (0x03U) /*!< Error unsupported feature */ +#define HAL_DMA_QUEUE_ERROR_INVALIDTYPE (0x04U) /*!< Error incompatible node type or circular initialization + and queue circular types are incompatible */ +#define HAL_DMA_QUEUE_ERROR_OUTOFRANGE (0x05U) /*!< Error out of range node memory */ +#define HAL_DMA_QUEUE_ERROR_NOTFOUND (0x06U) /*!< Error node not found in queue */ +/** + * @} + */ + +/** @defgroup DMAEx_LinkedList_Mode DMAEx LinkedList Mode + * @brief DMAEx LinkedList Mode + * @{ + */ +#define DMA_LINKEDLIST_NORMAL DMA_LINKEDLIST /*!< Linear linked-list DMA channel transfer */ +#define DMA_LINKEDLIST_CIRCULAR (DMA_LINKEDLIST | (0x01U)) /*!< Circular linked-list DMA channel transfer */ +/** + * @} + */ + +/** @defgroup DMAEx_Data_Alignment DMAEx Data Alignment + * @brief DMAEx Data Alignment + * @{ + */ +#define DMA_DATA_RIGHTALIGN_ZEROPADDED 0x00000000U /*!< If source data width < destination data width + => Right aligned padded with 0 up to destination data + width */ +#define DMA_DATA_RIGHTALIGN_LEFTTRUNC 0x00000000U /*!< If source data width > destination data width + => Right aligned left Truncated down to destination + data width */ +#define DMA_DATA_RIGHTALIGN_SIGNEXT DMA_CTR1_PAM_0 /*!< If source data width < destination data width + => Right Aligned padded with sign extended up to + destination data width */ +#define DMA_DATA_LEFTALIGN_RIGHTTRUNC DMA_CTR1_PAM_0 /*!< If source data width > destination data width + => Left Aligned Right Truncated down to the + destination data width */ +#define DMA_DATA_PACK DMA_CTR1_PAM_1 /*!< If source data width < destination data width + => Packed at the destination data width + (Available only for GPDMA) */ +#define DMA_DATA_UNPACK DMA_CTR1_PAM_1 /*!< If source data width > destination data width + => Unpacked at the destination data width + (Available only for GPDMA) */ +/** + * @} + */ + +/** @defgroup DMAEx_Data_Exchange DMAEx Data Exchange + * @brief DMAEx Data Exchange + * @{ + */ +#define DMA_EXCHANGE_NONE 0x00000000U /*!< No data exchange */ +#define DMA_EXCHANGE_DEST_BYTE DMA_CTR1_DBX /*!< Destination Byte exchange when destination data width is > Byte */ +#define DMA_EXCHANGE_DEST_HALFWORD DMA_CTR1_DHX /*!< Destination Half-Word exchange when destination data width is > Half-Word */ +#define DMA_EXCHANGE_SRC_BYTE DMA_CTR1_SBX /*!< Source Byte endianness exchange when source data width is word */ +/** + * @} + */ + +/** @defgroup DMAEx_Trigger_Polarity DMAEx Trigger Polarity + * @brief DMAEx Trigger Polarity + * @{ + */ +#define DMA_TRIG_POLARITY_MASKED 0x00000000U /*!< No trigger of the selected DMA request. Masked trigger event */ +#define DMA_TRIG_POLARITY_RISING DMA_CTR2_TRIGPOL_0 /*!< Trigger of the selected DMA request on the rising edge of the selected trigger event input */ +#define DMA_TRIG_POLARITY_FALLING DMA_CTR2_TRIGPOL_1 /*!< Trigger of the selected DMA request on the falling edge of the selected trigger event input */ +/** + * @} + */ + +/** @defgroup DMAEx_Trigger_Mode DMAEx Trigger Mode + * @brief DMAEx Trigger Mode + * @{ + */ +#define DMA_TRIGM_BLOCK_TRANSFER 0x00000000U /*!< A block transfer is conditioned by (at least) one hit trigger */ +#define DMA_TRIGM_REPEATED_BLOCK_TRANSFER DMA_CTR2_TRIGM_0 /*!< A repeated block transfer is conditioned by (at least) one hit trigger */ +#define DMA_TRIGM_LLI_LINK_TRANSFER DMA_CTR2_TRIGM_1 /*!< A LLI link transfer is conditioned by (at least) one hit trigger */ +#define DMA_TRIGM_SINGLE_BURST_TRANSFER DMA_CTR2_TRIGM /*!< A single/burst transfer is conditioned by (at least) one hit trigger */ +/** + * @} + */ + +/** @defgroup DMAEx_Trigger_Selection DMAEx Trigger Selection + * @brief DMAEx Trigger Selection + * @{ + */ +/* GPDMA1 triggers */ +#define GPDMA1_TRIGGER_EXTI_LINE0 0U /*!< GPDMA1 HW Trigger signal is EXTI_LINE0 */ +#define GPDMA1_TRIGGER_EXTI_LINE1 1U /*!< GPDMA1 HW Trigger signal is EXTI_LINE1 */ +#define GPDMA1_TRIGGER_EXTI_LINE2 2U /*!< GPDMA1 HW Trigger signal is EXTI_LINE2 */ +#define GPDMA1_TRIGGER_EXTI_LINE3 3U /*!< GPDMA1 HW Trigger signal is EXTI_LINE3 */ +#define GPDMA1_TRIGGER_EXTI_LINE4 4U /*!< GPDMA1 HW Trigger signal is EXTI_LINE4 */ +#define GPDMA1_TRIGGER_EXTI_LINE5 5U /*!< GPDMA1 HW Trigger signal is EXTI_LINE5 */ +#define GPDMA1_TRIGGER_EXTI_LINE6 6U /*!< GPDMA1 HW Trigger signal is EXTI_LINE6 */ +#define GPDMA1_TRIGGER_EXTI_LINE7 7U /*!< GPDMA1 HW Trigger signal is EXTI_LINE7 */ +#define GPDMA1_TRIGGER_TAMP_TRG1 8U /*!< GPDMA1 HW Trigger signal is TAMP_TRG1 */ +#define GPDMA1_TRIGGER_TAMP_TRG2 9U /*!< GPDMA1 HW Trigger signal is TAMP_TRG2 */ +#if defined (TAMP_CR1_TAMP3E) +#define GPDMA1_TRIGGER_TAMP_TRG3 10U /*!< GPDMA1 HW Trigger signal is TAMP_TRG3 */ +#endif /* TAMP_CR1_TAMP3E */ +#define GPDMA1_TRIGGER_LPTIM1_CH1 11U /*!< GPDMA1 HW Trigger signal is LPTIM1_CH1 */ +#define GPDMA1_TRIGGER_LPTIM1_CH2 12U /*!< GPDMA1 HW Trigger signal is LPTIM1_CH2 */ +#define GPDMA1_TRIGGER_LPTIM2_CH1 13U /*!< GPDMA1 HW Trigger signal is LPTIM2_CH1 */ +#define GPDMA1_TRIGGER_LPTIM2_CH2 14U /*!< GPDMA1 HW Trigger signal is LPTIM2_CH2 */ +#define GPDMA1_TRIGGER_RTC_ALRA_TRG 15U /*!< GPDMA1 HW Trigger signal is RTC_ALRA_TRG */ +#define GPDMA1_TRIGGER_RTC_ALRB_TRG 16U /*!< GPDMA1 HW Trigger signal is RTC_ALRB_TRG */ +#define GPDMA1_TRIGGER_RTC_WUT_TRG 17U /*!< GPDMA1 HW Trigger signal is RTC_WUT_TRG */ +#define GPDMA1_TRIGGER_GPDMA1_CH0_TCF 18U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH0_TCF */ +#define GPDMA1_TRIGGER_GPDMA1_CH1_TCF 19U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH1_TCF */ +#define GPDMA1_TRIGGER_GPDMA1_CH2_TCF 20U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH2_TCF */ +#define GPDMA1_TRIGGER_GPDMA1_CH3_TCF 21U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH3_TCF */ +#define GPDMA1_TRIGGER_GPDMA1_CH4_TCF 22U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH4_TCF */ +#define GPDMA1_TRIGGER_GPDMA1_CH5_TCF 23U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH5_TCF */ +#define GPDMA1_TRIGGER_GPDMA1_CH6_TCF 24U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH6_TCF */ +#define GPDMA1_TRIGGER_GPDMA1_CH7_TCF 25U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH7_TCF */ +#define GPDMA1_TRIGGER_GPDMA2_CH0_TCF 26U /*!< GPDMA1 HW Trigger signal is GPDMA2_CH0_TCF */ +#define GPDMA1_TRIGGER_GPDMA2_CH1_TCF 27U /*!< GPDMA1 HW Trigger signal is GPDMA2_CH1_TCF */ +#define GPDMA1_TRIGGER_GPDMA2_CH2_TCF 28U /*!< GPDMA1 HW Trigger signal is GPDMA2_CH2_TCF */ +#define GPDMA1_TRIGGER_GPDMA2_CH3_TCF 29U /*!< GPDMA1 HW Trigger signal is GPDMA2_CH3_TCF */ +#define GPDMA1_TRIGGER_GPDMA2_CH4_TCF 30U /*!< GPDMA1 HW Trigger signal is GPDMA2_CH4_TCF */ +#define GPDMA1_TRIGGER_GPDMA2_CH5_TCF 31U /*!< GPDMA1 HW Trigger signal is GPDMA2_CH5_TCF */ +#define GPDMA1_TRIGGER_GPDMA2_CH6_TCF 32U /*!< GPDMA1 HW Trigger signal is GPDMA2_CH6_TCF */ +#define GPDMA1_TRIGGER_GPDMA2_CH7_TCF 33U /*!< GPDMA1 HW Trigger signal is GPDMA2_CH7_TCF */ +#define GPDMA1_TRIGGER_TIM2_TRGO 34U /*!< GPDMA1 HW Trigger signal is TIM2_TRGO */ +#if defined (TIM15) +#define GPDMA1_TRIGGER_TIM15_TRGO 35U /*!< GPDMA1 HW Trigger signal is TIM15_TRGO */ +#endif /* TIM15 */ +#if defined (TIM12) +#define GPDMA1_TRIGGER_TIM12_TRGO 36U /*!< GPDMA1 HW Trigger signal is TIM12_TRGO */ +#endif /* TIM12 */ +#if defined (LPTIM3) +#define GPDMA1_TRIGGER_LPTIM3_CH1 37U /*!< GPDMA1 HW Trigger signal is LPTIM3_CH1 */ +#define GPDMA1_TRIGGER_LPTIM3_CH2 38U /*!< GPDMA1 HW Trigger signal is LPTIM3_CH2 */ +#endif /* LPTIM3 */ +#if defined (LPTIM4) +#define GPDMA1_TRIGGER_LPTIM4_AIT 39U /*!< GPDMA1 HW Trigger signal is LPTIM4_AIT */ +#endif /* LPTIM4 */ +#if defined (LPTIM5) +#define GPDMA1_TRIGGER_LPTIM5_CH1 40U /*!< GPDMA1 HW Trigger signal is LPTIM5_CH1 */ +#define GPDMA1_TRIGGER_LPTIM5_CH2 41U /*!< GPDMA1 HW Trigger signal is LPTIM5_CH2 */ +#endif /* LPTIM5 */ +#if defined (LPTIM6) +#define GPDMA1_TRIGGER_LPTIM6_CH1 42U /*!< GPDMA1 HW Trigger signal is LPTIM6_CH1 */ +#define GPDMA1_TRIGGER_LPTIM6_CH2 43U /*!< GPDMA1 HW Trigger signal is LPTIM6_CH2 */ +#endif /* LPTIM6 */ +#if defined (COMP1) +#define GPDMA1_TRIGGER_COMP1_OUT 44U /*!< GPDMA1 HW Trigger signal is COMP1_OUT */ +#endif /* COMP1 */ +#if defined (STM32H503xx) +#define GPDMA1_TRIGGER_EVENTOUT 45U /*!< GPDMA1 HW Trigger signal is COMP1_OUT */ +#endif /* STM32H503xx */ + +/* GPDMA2 triggers */ +#define GPDMA2_TRIGGER_EXTI_LINE0 0U /*!< GPDMA2 HW Trigger signal is EXTI_LINE0 */ +#define GPDMA2_TRIGGER_EXTI_LINE1 1U /*!< GPDMA2 HW Trigger signal is EXTI_LINE1 */ +#define GPDMA2_TRIGGER_EXTI_LINE2 2U /*!< GPDMA2 HW Trigger signal is EXTI_LINE2 */ +#define GPDMA2_TRIGGER_EXTI_LINE3 3U /*!< GPDMA2 HW Trigger signal is EXTI_LINE3 */ +#define GPDMA2_TRIGGER_EXTI_LINE4 4U /*!< GPDMA2 HW Trigger signal is EXTI_LINE4 */ +#define GPDMA2_TRIGGER_EXTI_LINE5 5U /*!< GPDMA2 HW Trigger signal is EXTI_LINE5 */ +#define GPDMA2_TRIGGER_EXTI_LINE6 6U /*!< GPDMA2 HW Trigger signal is EXTI_LINE6 */ +#define GPDMA2_TRIGGER_EXTI_LINE7 7U /*!< GPDMA2 HW Trigger signal is EXTI_LINE7 */ +#define GPDMA2_TRIGGER_TAMP_TRG1 8U /*!< GPDMA2 HW Trigger signal is TAMP_TRG1 */ +#define GPDMA2_TRIGGER_TAMP_TRG2 9U /*!< GPDMA2 HW Trigger signal is TAMP_TRG2 */ +#define GPDMA2_TRIGGER_TAMP_TRG3 10U /*!< GPDMA2 HW Trigger signal is TAMP_TRG3 */ +#define GPDMA2_TRIGGER_LPTIM1_CH1 11U /*!< GPDMA2 HW Trigger signal is LPTIM1_CH1 */ +#define GPDMA2_TRIGGER_LPTIM1_CH2 12U /*!< GPDMA2 HW Trigger signal is LPTIM1_CH2 */ +#define GPDMA2_TRIGGER_LPTIM2_CH1 13U /*!< GPDMA2 HW Trigger signal is LPTIM2_CH1 */ +#define GPDMA2_TRIGGER_LPTIM2_CH2 14U /*!< GPDMA2 HW Trigger signal is LPTIM2_CH2 */ +#define GPDMA2_TRIGGER_RTC_ALRA_TRG 15U /*!< GPDMA2 HW Trigger signal is RTC_ALRA_TRG */ +#define GPDMA2_TRIGGER_RTC_ALRB_TRG 16U /*!< GPDMA2 HW Trigger signal is RTC_ALRB_TRG */ +#define GPDMA2_TRIGGER_RTC_WUT_TRG 17U /*!< GPDMA2 HW Trigger signal is RTC_WUT_TRG */ +#define GPDMA2_TRIGGER_GPDMA1_CH0_TCF 18U /*!< GPDMA2 HW Trigger signal is GPDMA1_CH0_TCF */ +#define GPDMA2_TRIGGER_GPDMA1_CH1_TCF 19U /*!< GPDMA2 HW Trigger signal is GPDMA1_CH1_TCF */ +#define GPDMA2_TRIGGER_GPDMA1_CH2_TCF 20U /*!< GPDMA2 HW Trigger signal is GPDMA1_CH2_TCF */ +#define GPDMA2_TRIGGER_GPDMA1_CH3_TCF 21U /*!< GPDMA2 HW Trigger signal is GPDMA1_CH3_TCF */ +#define GPDMA2_TRIGGER_GPDMA1_CH4_TCF 22U /*!< GPDMA2 HW Trigger signal is GPDMA1_CH4_TCF */ +#define GPDMA2_TRIGGER_GPDMA1_CH5_TCF 23U /*!< GPDMA2 HW Trigger signal is GPDMA1_CH5_TCF */ +#define GPDMA2_TRIGGER_GPDMA1_CH6_TCF 24U /*!< GPDMA2 HW Trigger signal is GPDMA1_CH6_TCF */ +#define GPDMA2_TRIGGER_GPDMA1_CH7_TCF 25U /*!< GPDMA2 HW Trigger signal is GPDMA1_CH7_TCF */ +#define GPDMA2_TRIGGER_GPDMA2_CH0_TCF 26U /*!< GPDMA2 HW Trigger signal is GPDMA2_CH0_TCF */ +#define GPDMA2_TRIGGER_GPDMA2_CH1_TCF 27U /*!< GPDMA2 HW Trigger signal is GPDMA2_CH1_TCF */ +#define GPDMA2_TRIGGER_GPDMA2_CH2_TCF 28U /*!< GPDMA2 HW Trigger signal is GPDMA2_CH2_TCF */ +#define GPDMA2_TRIGGER_GPDMA2_CH3_TCF 29U /*!< GPDMA2 HW Trigger signal is GPDMA2_CH3_TCF */ +#define GPDMA2_TRIGGER_GPDMA2_CH4_TCF 30U /*!< GPDMA2 HW Trigger signal is GPDMA2_CH4_TCF */ +#define GPDMA2_TRIGGER_GPDMA2_CH5_TCF 31U /*!< GPDMA2 HW Trigger signal is GPDMA2_CH5_TCF */ +#define GPDMA2_TRIGGER_GPDMA2_CH6_TCF 32U /*!< GPDMA2 HW Trigger signal is GPDMA2_CH6_TCF */ +#define GPDMA2_TRIGGER_GPDMA2_CH7_TCF 33U /*!< GPDMA2 HW Trigger signal is GPDMA2_CH7_TCF */ +#define GPDMA2_TRIGGER_TIM2_TRGO 34U /*!< GPDMA2 HW Trigger signal is TIM2_TRGO */ +#if defined (TIM15) +#define GPDMA2_TRIGGER_TIM15_TRGO 35U /*!< GPDMA2 HW Trigger signal is TIM15_TRGO */ +#endif /* TIM15 */ +#if defined (TIM12) +#define GPDMA2_TRIGGER_TIM12_TRGO 36U /*!< GPDMA2 HW Trigger signal is TIM12_TRGO */ +#endif /* TIM12 */ +#if defined (LPTIM3) +#define GPDMA2_TRIGGER_LPTIM3_CH1 37U /*!< GPDMA2 HW Trigger signal is LPTIM3_CH1 */ +#define GPDMA2_TRIGGER_LPTIM3_CH2 38U /*!< GPDMA2 HW Trigger signal is LPTIM3_CH2 */ +#endif /* LPTIM3 */ +#if defined (LPTIM4) +#define GPDMA2_TRIGGER_LPTIM4_AIT 39U /*!< GPDMA2 HW Trigger signal is LPTIM4_AIT */ +#endif /* LPTIM4 */ +#if defined (LPTIM5) +#define GPDMA2_TRIGGER_LPTIM5_CH1 40U /*!< GPDMA2 HW Trigger signal is LPTIM5_CH1 */ +#define GPDMA2_TRIGGER_LPTIM5_CH2 41U /*!< GPDMA2 HW Trigger signal is LPTIM5_CH2 */ +#endif /* LPTIM5 */ +#if defined (LPTIM6) +#define GPDMA2_TRIGGER_LPTIM6_CH1 42U /*!< GPDMA2 HW Trigger signal is LPTIM6_CH1 */ +#define GPDMA2_TRIGGER_LPTIM6_CH2 43U /*!< GPDMA2 HW Trigger signal is LPTIM6_CH2 */ +#endif /* LPTIM6 */ +#if defined (COMP1) +#define GPDMA2_TRIGGER_COMP1_OUT 44U /*!< GPDMA2 HW Trigger signal is COMP1_OUT */ +#endif /* COMP1 */ +#if defined (STM32H503xx) +#define GPDMA2_TRIGGER_EVENTOUT 45U /*!< GPDMA2 HW Trigger signal is COMP1_OUT */ +#endif /* STM32H503xx */ +/** + * @} + */ + +/** @defgroup DMAEx_Node_Type DMAEx Node Type + * @brief DMAEx Node Type + * @{ + */ +#define DMA_GPDMA_LINEAR_NODE (DMA_CHANNEL_TYPE_GPDMA | DMA_CHANNEL_TYPE_LINEAR_ADDR) /*!< Defines the GPDMA linear addressing node type */ +#define DMA_GPDMA_2D_NODE (DMA_CHANNEL_TYPE_GPDMA | DMA_CHANNEL_TYPE_2D_ADDR) /*!< Defines the GPDMA 2 dimension addressing node type */ +/** + * @} + */ + +/** @defgroup DMAEx_Link_Allocated_Port DMAEx Linked-List Allocated Port + * @brief DMAEx Linked-List Allocated Port + * @{ + */ +#define DMA_LINK_ALLOCATED_PORT0 0x00000000U /*!< Link allocated port 0 */ +#define DMA_LINK_ALLOCATED_PORT1 DMA_CCR_LAP /*!< Link allocated port 1 */ +/** + * @} + */ + +/** @defgroup DMAEx_Link_Step_Mode DMAEx Link Step Mode + * @brief DMAEx Link Step Mode + * @{ + */ +#define DMA_LSM_FULL_EXECUTION 0x00000000U /*!< Channel is executed for the full linked-list */ +#define DMA_LSM_1LINK_EXECUTION DMA_CCR_LSM /*!< Channel is executed once for the current LLI */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions ------------------------------------------------------------------------------------------------*/ +/** @defgroup DMAEx_Exported_Functions DMAEx Exported Functions + * @brief DMAEx Exported functions + * @{ + */ + +/** @defgroup DMAEx_Exported_Functions_Group1 Linked-List Initialization and De-Initialization Functions + * @brief Linked-List Initialization and De-Initialization Functions + * @{ + */ +HAL_StatusTypeDef HAL_DMAEx_List_Init(DMA_HandleTypeDef *const hdma); +HAL_StatusTypeDef HAL_DMAEx_List_DeInit(DMA_HandleTypeDef *const hdma); +/** + * @} + */ + +/** @defgroup DMAEx_Exported_Functions_Group2 Linked-List IO Operation Functions + * @brief Linked-List IO Operation Functions + * @{ + */ +HAL_StatusTypeDef HAL_DMAEx_List_Start(DMA_HandleTypeDef *const hdma); +HAL_StatusTypeDef HAL_DMAEx_List_Start_IT(DMA_HandleTypeDef *const hdma); +/** + * @} + */ + +/** @defgroup DMAEx_Exported_Functions_Group3 Linked-List Management Functions + * @brief Linked-List Management Functions + * @{ + */ +HAL_StatusTypeDef HAL_DMAEx_List_BuildNode(DMA_NodeConfTypeDef const *const pNodeConfig, + DMA_NodeTypeDef *const pNode); +HAL_StatusTypeDef HAL_DMAEx_List_GetNodeConfig(DMA_NodeConfTypeDef *const pNodeConfig, + DMA_NodeTypeDef const *const pNode); + +HAL_StatusTypeDef HAL_DMAEx_List_InsertNode(DMA_QListTypeDef *const pQList, + DMA_NodeTypeDef *const pPrevNode, + DMA_NodeTypeDef *const pNewNode); +HAL_StatusTypeDef HAL_DMAEx_List_InsertNode_Head(DMA_QListTypeDef *const pQList, + DMA_NodeTypeDef *const pNewNode); +HAL_StatusTypeDef HAL_DMAEx_List_InsertNode_Tail(DMA_QListTypeDef *const pQList, + DMA_NodeTypeDef *const pNewNode); + +HAL_StatusTypeDef HAL_DMAEx_List_RemoveNode(DMA_QListTypeDef *const pQList, + DMA_NodeTypeDef *const pNode); +HAL_StatusTypeDef HAL_DMAEx_List_RemoveNode_Head(DMA_QListTypeDef *const pQList); +HAL_StatusTypeDef HAL_DMAEx_List_RemoveNode_Tail(DMA_QListTypeDef *const pQList); + +HAL_StatusTypeDef HAL_DMAEx_List_ReplaceNode(DMA_QListTypeDef *const pQList, + DMA_NodeTypeDef *const pOldNode, + DMA_NodeTypeDef *const pNewNode); +HAL_StatusTypeDef HAL_DMAEx_List_ReplaceNode_Head(DMA_QListTypeDef *const pQList, + DMA_NodeTypeDef *const pNewNode); +HAL_StatusTypeDef HAL_DMAEx_List_ReplaceNode_Tail(DMA_QListTypeDef *const pQList, + DMA_NodeTypeDef *const pNewNode); + +HAL_StatusTypeDef HAL_DMAEx_List_ResetQ(DMA_QListTypeDef *const pQList); + +HAL_StatusTypeDef HAL_DMAEx_List_InsertQ(DMA_QListTypeDef *const pSrcQList, + DMA_NodeTypeDef const *const pPrevNode, + DMA_QListTypeDef *const pDestQList); +HAL_StatusTypeDef HAL_DMAEx_List_InsertQ_Head(DMA_QListTypeDef *const pSrcQList, + DMA_QListTypeDef *const pDestQList); +HAL_StatusTypeDef HAL_DMAEx_List_InsertQ_Tail(DMA_QListTypeDef *const pSrcQList, + DMA_QListTypeDef *const pDestQList); + +HAL_StatusTypeDef HAL_DMAEx_List_SetCircularModeConfig(DMA_QListTypeDef *const pQList, + DMA_NodeTypeDef *const pFirstCircularNode); +HAL_StatusTypeDef HAL_DMAEx_List_SetCircularMode(DMA_QListTypeDef *const pQList); +HAL_StatusTypeDef HAL_DMAEx_List_ClearCircularMode(DMA_QListTypeDef *const pQList); + +HAL_StatusTypeDef HAL_DMAEx_List_ConvertQToDynamic(DMA_QListTypeDef *const pQList); +HAL_StatusTypeDef HAL_DMAEx_List_ConvertQToStatic(DMA_QListTypeDef *const pQList); + +HAL_StatusTypeDef HAL_DMAEx_List_LinkQ(DMA_HandleTypeDef *const hdma, + DMA_QListTypeDef *const pQList); +HAL_StatusTypeDef HAL_DMAEx_List_UnLinkQ(DMA_HandleTypeDef *const hdma); +/** + * @} + */ + +/** @defgroup DMAEx_Exported_Functions_Group4 Data Handling, Repeated Block and Trigger Configuration Functions + * @brief Data Handling, Repeated Block and Trigger Configuration Functions + * @{ + */ +HAL_StatusTypeDef HAL_DMAEx_ConfigDataHandling(DMA_HandleTypeDef *const hdma, + DMA_DataHandlingConfTypeDef const *const pConfigDataHandling); +HAL_StatusTypeDef HAL_DMAEx_ConfigTrigger(DMA_HandleTypeDef *const hdma, + DMA_TriggerConfTypeDef const *const pConfigTrigger); +HAL_StatusTypeDef HAL_DMAEx_ConfigRepeatBlock(DMA_HandleTypeDef *const hdma, + DMA_RepeatBlockConfTypeDef const *const pConfigRepeatBlock); +/** + * @} + */ + +/** @defgroup DMAEx_Exported_Functions_Group5 Suspend and Resume Operation Functions + * @brief Suspend and Resume Operation Functions + * @{ + */ +HAL_StatusTypeDef HAL_DMAEx_Suspend(DMA_HandleTypeDef *const hdma); +HAL_StatusTypeDef HAL_DMAEx_Suspend_IT(DMA_HandleTypeDef *const hdma); +HAL_StatusTypeDef HAL_DMAEx_Resume(DMA_HandleTypeDef *const hdma); +/** + * @} + */ + +/** @defgroup DMAEx_Exported_Functions_Group6 FIFO Status Function + * @brief FIFO Status Function + * @{ + */ +uint32_t HAL_DMAEx_GetFifoLevel(DMA_HandleTypeDef const *const hdma); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -----------------------------------------------------------------------------------------------------*/ +/** @defgroup DMAEx_Private_Types DMAEx Private Types + * @brief DMAEx Private Types + * @{ + */ + +/** + * @brief DMA Node in Queue Information Structure Definition. + */ +typedef struct +{ + uint32_t cllr_offset; /* CLLR register offset */ + + uint32_t previousnode_addr; /* Previous node address */ + + uint32_t currentnode_pos; /* Current node position */ + + uint32_t currentnode_addr; /* Current node address */ + + uint32_t nextnode_addr; /* Next node address */ + +} DMA_NodeInQInfoTypeDef; +/** + * @} + */ + +/* Private constants -------------------------------------------------------------------------------------------------*/ +/** @defgroup DMAEx_Private_Constants DMAEx Private Constants + * @brief DMAEx Private Constants + * @{ + */ +#define DMA_LINKEDLIST (0x0080U) /* DMA channel linked-list mode */ + +#define DMA_CHANNEL_TYPE_LINEAR_ADDR (0x0001U) /* DMA channel linear addressing mode */ +#define DMA_CHANNEL_TYPE_2D_ADDR (0x0002U) /* DMA channel 2D addressing mode */ +#define DMA_CHANNEL_TYPE_GPDMA (0x0020U) /* GPDMA channel node */ + +#define NODE_TYPE_MASK (0x00FFU) /* DMA channel node type */ +#define NODE_CLLR_IDX (0x0700U) /* DMA channel node CLLR index mask */ +#define NODE_CLLR_IDX_POS (0x0008U) /* DMA channel node CLLR index position */ + +#define NODE_MAXIMUM_SIZE (0x0008U) /* Amount of registers of the node */ + +#define NODE_STATIC_FORMAT (0x0000U) /* DMA channel node static format */ +#define NODE_DYNAMIC_FORMAT (0x0001U) /* DMA channel node dynamic format */ + +#define UPDATE_CLLR_POSITION (0x0000U) /* DMA channel update CLLR position */ +#define UPDATE_CLLR_VALUE (0x0001U) /* DMA channel update CLLR value */ + +#define LASTNODE_ISNOT_CIRCULAR (0x0000U) /* Last node is not first circular node */ +#define LASTNODE_IS_CIRCULAR (0x0001U) /* Last node is first circular node */ + +#define QUEUE_TYPE_STATIC (0x0000U) /* DMA channel static queue */ +#define QUEUE_TYPE_DYNAMIC (0x0001U) /* DMA channel dynamic queue */ + +#define NODE_CTR1_DEFAULT_OFFSET (0x0000U) /* CTR1 default offset */ +#define NODE_CTR2_DEFAULT_OFFSET (0x0001U) /* CTR2 default offset */ +#define NODE_CBR1_DEFAULT_OFFSET (0x0002U) /* CBR1 default offset */ +#define NODE_CSAR_DEFAULT_OFFSET (0x0003U) /* CSAR default offset */ +#define NODE_CDAR_DEFAULT_OFFSET (0x0004U) /* CDAR default offset */ +#define NODE_CTR3_DEFAULT_OFFSET (0x0005U) /* CTR3 2D addressing default offset */ +#define NODE_CBR2_DEFAULT_OFFSET (0x0006U) /* CBR2 2D addressing default offset */ +#define NODE_CLLR_2D_DEFAULT_OFFSET (0x0007U) /* CLLR 2D addressing default offset */ +#define NODE_CLLR_LINEAR_DEFAULT_OFFSET (0x0005U) /* CLLR linear addressing default offset */ + +#define DMA_BURST_ADDR_OFFSET_MIN (-8192L) /* DMA burst minimum address offset */ +#define DMA_BURST_ADDR_OFFSET_MAX (8192L) /* DMA burst maximum address offset */ +#define DMA_BLOCK_ADDR_OFFSET_MIN (-65536L) /* DMA block minimum address offset */ +#define DMA_BLOCK_ADDR_OFFSET_MAX (65536L) /* DMA block maximum address offset */ +/** + * @} + */ + +/* Private macros ----------------------------------------------------------------------------------------------------*/ +/** @defgroup DMAEx_Private_Macros DMAEx Private Macros + * @brief DMAEx Private Macros + * @{ + */ +#define IS_DMA_DATA_ALIGNMENT(ALIGNMENT) \ + (((ALIGNMENT) == DMA_DATA_RIGHTALIGN_ZEROPADDED) || \ + ((ALIGNMENT) == DMA_DATA_RIGHTALIGN_SIGNEXT) || \ + ((ALIGNMENT) == DMA_DATA_PACK)) + +#define IS_DMA_DATA_EXCHANGE(EXCHANGE) \ + (((EXCHANGE) & (~(DMA_EXCHANGE_SRC_BYTE | DMA_EXCHANGE_DEST_BYTE | DMA_EXCHANGE_DEST_HALFWORD))) == 0U) + +#define IS_DMA_REPEAT_COUNT(COUNT) \ + (((COUNT) > 0U) && ((COUNT) <= (DMA_CBR1_BRC >> DMA_CBR1_BRC_Pos))) + +#define IS_DMA_BURST_ADDR_OFFSET(BURST_ADDR_OFFSET) \ + (((BURST_ADDR_OFFSET) > DMA_BURST_ADDR_OFFSET_MIN) && \ + ((BURST_ADDR_OFFSET) < DMA_BURST_ADDR_OFFSET_MAX)) + +#define IS_DMA_BLOCK_ADDR_OFFSET(BLOCK_ADDR_OFFSET) \ + (((BLOCK_ADDR_OFFSET) > DMA_BLOCK_ADDR_OFFSET_MIN) && \ + ((BLOCK_ADDR_OFFSET) < DMA_BLOCK_ADDR_OFFSET_MAX)) + +#define IS_DMA_LINK_ALLOCATED_PORT(LINK_ALLOCATED_PORT) \ + (((LINK_ALLOCATED_PORT) & (~(DMA_CCR_LAP))) == 0U) + +#define IS_DMA_LINK_STEP_MODE(MODE) \ + (((MODE) == DMA_LSM_FULL_EXECUTION) || \ + ((MODE) == DMA_LSM_1LINK_EXECUTION)) + +#define IS_DMA_TRIGGER_MODE(MODE) \ + (((MODE) == DMA_TRIGM_BLOCK_TRANSFER) || \ + ((MODE) == DMA_TRIGM_REPEATED_BLOCK_TRANSFER) || \ + ((MODE) == DMA_TRIGM_LLI_LINK_TRANSFER) || \ + ((MODE) == DMA_TRIGM_SINGLE_BURST_TRANSFER)) + +#define IS_DMA_TCEM_LINKEDLIST_EVENT_MODE(MODE) \ + (((MODE) == DMA_TCEM_BLOCK_TRANSFER) || \ + ((MODE) == DMA_TCEM_REPEATED_BLOCK_TRANSFER) || \ + ((MODE) == DMA_TCEM_EACH_LL_ITEM_TRANSFER) || \ + ((MODE) == DMA_TCEM_LAST_LL_ITEM_TRANSFER)) + +#define IS_DMA_LINKEDLIST_MODE(MODE) \ + (((MODE) == DMA_LINKEDLIST_NORMAL) || \ + ((MODE) == DMA_LINKEDLIST_CIRCULAR)) + +#define IS_DMA_TRIGGER_POLARITY(POLARITY) \ + (((POLARITY) == DMA_TRIG_POLARITY_MASKED) || \ + ((POLARITY) == DMA_TRIG_POLARITY_RISING) || \ + ((POLARITY) == DMA_TRIG_POLARITY_FALLING)) + +#if defined (I3C2) +#define IS_DMA_TRIGGER_SELECTION(TRIGGER) ((TRIGGER) <= GPDMA1_TRIGGER_EVENTOUT) +#else +#define IS_DMA_TRIGGER_SELECTION(TRIGGER) ((TRIGGER) <= GPDMA1_TRIGGER_LPTIM6_CH2) +#endif /* I3C2 */ + +#define IS_DMA_NODE_TYPE(TYPE) \ + (((TYPE) == DMA_GPDMA_LINEAR_NODE) || \ + ((TYPE) == DMA_GPDMA_2D_NODE)) +/** + * @} + */ + + +/* Private functions -------------------------------------------------------------------------------------------------*/ +/** @defgroup DMAEx_Private_Functions DMAEx Private Functions + * @brief DMAEx Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* STM32H5xx_HAL_DMA_EX_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_dts.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_dts.h new file mode 100644 index 0000000000..b94cb30de2 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_dts.h @@ -0,0 +1,551 @@ +/** + ********************************************************************************************************************** + * @file stm32h5xx_hal_dts.h + * @author MCD Application Team + * @brief Header file of DTS HAL module. + ********************************************************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ********************************************************************************************************************** + */ + +/* Define to prevent recursive inclusion -----------------------------------------------------------------------------*/ +#ifndef STM32H5xx_HAL_DTS_H +#define STM32H5xx_HAL_DTS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ----------------------------------------------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" +#if defined(DTS) + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup DTS + * @{ + */ + +/* Exported types ----------------------------------------------------------------------------------------------------*/ +/** @defgroup DTS_Exported_Types DTS Exported Types + * @{ + */ + +/** + * @brief DTS Init structure definition + */ +typedef struct +{ + uint32_t QuickMeasure; /*!< Specifies the quick measure option selection of the DTS sensor. + This parameter can be a value of @ref DTS_Quick_Measurement */ + + uint32_t RefClock; /*!< Specifies the reference clock selection of the DTS sensor. + This parameter can be a value of @ref DTS_Reference_Clock_Selection */ + + uint32_t TriggerInput; /*!< Specifies the trigger input of the DTS sensor. + This parameter can be a value of @ref DTS_TriggerConfig */ + + uint32_t SamplingTime; /*!< Specifies the sampling time configuration. + This parameter can be a value of @ref DTS_Sampling_Time */ + + uint32_t Divider; /*!< Specifies the high speed clock divider ratio. + This parameter can be a value from 0 to 127 */ + + uint32_t HighThreshold; /*!< Specifies the high threshold of the DTS sensor */ + + uint32_t LowThreshold; /*!< Specifies the low threshold of the DTS sensor */ + +} DTS_InitTypeDef; + +/** + * @brief HAL State structures definition + */ +typedef enum +{ + HAL_DTS_STATE_RESET = 0x00UL, /*!< DTS not yet initialized or disabled */ + HAL_DTS_STATE_READY = 0x01UL, /*!< DTS initialized and ready for use */ + HAL_DTS_STATE_BUSY = 0x02UL, /*!< DTS is running */ + HAL_DTS_STATE_TIMEOUT = 0x03UL, /*!< Timeout state */ + HAL_DTS_STATE_ERROR = 0x04UL /*!< Internal Process error */ + +} HAL_DTS_StateTypeDef; + +/** + * @brief DTS Handle Structure definition + */ +#if (USE_HAL_DTS_REGISTER_CALLBACKS == 1U) +typedef struct __DTS_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_DTS_REGISTER_CALLBACKS */ +{ + DTS_TypeDef *Instance; /*!< Register base address */ + DTS_InitTypeDef Init; /*!< DTS required parameters */ + HAL_LockTypeDef Lock; /*!< DTS Locking object */ + __IO HAL_DTS_StateTypeDef State; /*!< DTS peripheral state */ + +#if (USE_HAL_DTS_REGISTER_CALLBACKS == 1U) + void (* MspInitCallback)(struct __DTS_HandleTypeDef *hdts); /*!< DTS Base Msp Init Callback */ + void (* MspDeInitCallback)(struct __DTS_HandleTypeDef *hdts); /*!< DTS Base Msp DeInit Callback */ + void (* EndCallback)(struct __DTS_HandleTypeDef *hdts); /*!< End measure Callback */ + void (* LowCallback)(struct __DTS_HandleTypeDef *hdts); /*!< low threshold Callback */ + void (* HighCallback)(struct __DTS_HandleTypeDef *hdts); /*!< high threshold Callback */ + void (* AsyncEndCallback)(struct __DTS_HandleTypeDef *hdts); /*!< Asynchronous end of measure Callback */ + void (* AsyncLowCallback)(struct __DTS_HandleTypeDef *hdts); /*!< Asynchronous low threshold Callback */ + void (* AsyncHighCallback)(struct __DTS_HandleTypeDef *hdts); /*!< Asynchronous high threshold Callback */ +#endif /* USE_HAL_DTS_REGISTER_CALLBACKS */ +} DTS_HandleTypeDef; + +#if (USE_HAL_DTS_REGISTER_CALLBACKS == 1U) +/** + * @brief DTS callback ID enumeration definition + */ +typedef enum +{ + HAL_DTS_MEAS_COMPLETE_CB_ID = 0x00U, /*!< Measure complete callback ID */ + HAL_DTS_ASYNC_MEAS_COMPLETE_CB_ID = 0x01U, /*!< Asynchronous measure complete callback ID */ + HAL_DTS_LOW_THRESHOLD_CB_ID = 0x02U, /*!< Low threshold detection callback ID */ + HAL_DTS_ASYNC_LOW_THRESHOLD_CB_ID = 0x03U, /*!< Asynchronous low threshold detection callback ID */ + HAL_DTS_HIGH_THRESHOLD_CB_ID = 0x04U, /*!< High threshold detection callback ID */ + HAL_DTS_ASYNC_HIGH_THRESHOLD_CB_ID = 0x05U, /*!< Asynchronous high threshold detection callback ID */ + HAL_DTS_MSPINIT_CB_ID = 0x06U, /*!< MSP init callback ID */ + HAL_DTS_MSPDEINIT_CB_ID = 0x07U /*!< MSP de-init callback ID */ +} HAL_DTS_CallbackIDTypeDef; + +/** + * @brief DTS callback pointers definition + */ +typedef void (*pDTS_CallbackTypeDef)(DTS_HandleTypeDef *hdts); +#endif /* USE_HAL_DTS_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/* Exported constants ------------------------------------------------------------------------------------------------*/ +/** @defgroup DTS_Exported_Constants DTS Exported Constants + * @{ + */ + +/** @defgroup DTS_TriggerConfig DTS Trigger Configuration + * @{ + */ +/* @brief No Hardware trigger detection */ +#define DTS_TRIGGER_HW_NONE (0UL) + +/* @brief External Interrupt Mode with LPTIMER1 trigger detection */ +#define DTS_TRIGGER_LPTIMER1 DTS_CFGR1_TS1_INTRIG_SEL_0 + +/* @brief External Interrupt Mode with LPTIMER2 trigger detection */ +#define DTS_TRIGGER_LPTIMER2 DTS_CFGR1_TS1_INTRIG_SEL_1 + +#if defined(LPTIM3) +/* @brief External Interrupt Mode with LPTIMER3 trigger detection */ +#define DTS_TRIGGER_LPTIMER3 (DTS_CFGR1_TS1_INTRIG_SEL_0 | DTS_CFGR1_TS1_INTRIG_SEL_1) +#endif /* defined(LPTIM3) */ + +/* @brief External Interrupt Mode with EXTI13 trigger detection */ +#define DTS_TRIGGER_EXTI13 DTS_CFGR1_TS1_INTRIG_SEL_2 +/** + * @} + */ + +/** @defgroup DTS_Quick_Measurement DTS Quick Measurement + * @{ + */ +#define DTS_QUICKMEAS_ENABLE DTS_CFGR1_Q_MEAS_OPT /*!< Enable the Quick Measure (Measure without calibration) */ +#define DTS_QUICKMEAS_DISABLE (0x0UL) /*!< Disable the Quick Measure (Measure with calibration) */ +/** + * @} + */ + +/** @defgroup DTS_Reference_Clock_Selection DTS Reference Clock Selection + * @{ + */ +#define DTS_REFCLKSEL_LSE DTS_CFGR1_REFCLK_SEL /*!< Low speed REF clock (LSE) */ +#define DTS_REFCLKSEL_PCLK (0UL) /*!< High speed REF clock (PCLK) */ +/** + * @} + */ + +/** @defgroup DTS_Sampling_Time DTS Sampling Time + * @{ + */ +#define DTS_SMP_TIME_1_CYCLE DTS_CFGR1_TS1_SMP_TIME_0 /*!< 1 clock cycle for the sampling time */ +#define DTS_SMP_TIME_2_CYCLE DTS_CFGR1_TS1_SMP_TIME_1 /*!< 2 clock cycle for the sampling time */ +#define DTS_SMP_TIME_3_CYCLE (DTS_CFGR1_TS1_SMP_TIME_0 |\ + DTS_CFGR1_TS1_SMP_TIME_1) /*!< 3 clock cycle for the sampling time */ +#define DTS_SMP_TIME_4_CYCLE (DTS_CFGR1_TS1_SMP_TIME_2) /*!< 4 clock cycle for the sampling time */ +#define DTS_SMP_TIME_5_CYCLE (DTS_CFGR1_TS1_SMP_TIME_0 |\ + DTS_CFGR1_TS1_SMP_TIME_2) /*!< 5 clock cycle for the sampling time */ +#define DTS_SMP_TIME_6_CYCLE (DTS_CFGR1_TS1_SMP_TIME_1 |\ + DTS_CFGR1_TS1_SMP_TIME_2) /*!< 6 clock cycle for the sampling time */ +#define DTS_SMP_TIME_7_CYCLE (DTS_CFGR1_TS1_SMP_TIME_0 |\ + DTS_CFGR1_TS1_SMP_TIME_1 |\ + DTS_CFGR1_TS1_SMP_TIME_2) /*!< 7 clock cycle for the sampling time */ +#define DTS_SMP_TIME_8_CYCLE (DTS_CFGR1_TS1_SMP_TIME_3) /*!< 8 clock cycle for the sampling time */ +#define DTS_SMP_TIME_9_CYCLE (DTS_CFGR1_TS1_SMP_TIME_0 |\ + DTS_CFGR1_TS1_SMP_TIME_3) /*!< 9 clock cycle for the sampling time */ +#define DTS_SMP_TIME_10_CYCLE (DTS_CFGR1_TS1_SMP_TIME_1 |\ + DTS_CFGR1_TS1_SMP_TIME_3) /*!< 10 clock cycle for the sampling time */ +#define DTS_SMP_TIME_11_CYCLE (DTS_CFGR1_TS1_SMP_TIME_0 |\ + DTS_CFGR1_TS1_SMP_TIME_1 |\ + DTS_CFGR1_TS1_SMP_TIME_3) /*!< 11 clock cycle for the sampling time */ +#define DTS_SMP_TIME_12_CYCLE (DTS_CFGR1_TS1_SMP_TIME_2 |\ + DTS_CFGR1_TS1_SMP_TIME_3) /*!< 12 clock cycle for the sampling time */ +#define DTS_SMP_TIME_13_CYCLE (DTS_CFGR1_TS1_SMP_TIME_0 |\ + DTS_CFGR1_TS1_SMP_TIME_2 |\ + DTS_CFGR1_TS1_SMP_TIME_3) /*!< 13 clock cycle for the sampling time */ +#define DTS_SMP_TIME_14_CYCLE (DTS_CFGR1_TS1_SMP_TIME_1 |\ + DTS_CFGR1_TS1_SMP_TIME_2 |\ + DTS_CFGR1_TS1_SMP_TIME_3) /*!< 14 clock cycle for the sampling time */ +#define DTS_SMP_TIME_15_CYCLE (DTS_CFGR1_TS1_SMP_TIME_0 |\ + DTS_CFGR1_TS1_SMP_TIME_1 |\ + DTS_CFGR1_TS1_SMP_TIME_2 |\ + DTS_CFGR1_TS1_SMP_TIME_3) /*!< 15 clock cycle for the sampling time */ +/** + * @} + */ + +/** @defgroup DTS_Flag_Definitions DTS Flag Definitions + * @{ + */ +#define DTS_FLAG_TS1_ITE DTS_SR_TS1_ITEF /*!< Interrupt flag for end of measure for DTS1 */ +#define DTS_FLAG_TS1_ITL DTS_SR_TS1_ITLF /*!< Interrupt flag for low threshold for DTS1 */ +#define DTS_FLAG_TS1_ITH DTS_SR_TS1_ITHF /*!< Interrupt flag for high threshold for DTS1 */ +#define DTS_FLAG_TS1_AITE DTS_SR_TS1_AITEF /*!< Asynchronous Interrupt flag for end of measure for DTS1 */ +#define DTS_FLAG_TS1_AITL DTS_SR_TS1_AITLF /*!< Asynchronous Interrupt flag for low threshold for DTS1 */ +#define DTS_FLAG_TS1_AITH DTS_SR_TS1_AITHF /*!< Asynchronous Interrupt flag for high threshold for DTS1 */ +#define DTS_FLAG_TS1_RDY DTS_SR_TS1_RDY /*!< Ready flag for DTS1 */ +/** + * @} + */ + +/** @defgroup DTS_Interrupts_Definitions DTS Interrupts Definitions + * @{ + */ +#define DTS_IT_TS1_ITE DTS_ITENR_TS1_ITEEN /*!< Enable interrupt flag for end of measure for DTS1 */ +#define DTS_IT_TS1_ITL DTS_ITENR_TS1_ITLEN /*!< Enable interrupt flag for low threshold for DTS1 */ +#define DTS_IT_TS1_ITH DTS_ITENR_TS1_ITHEN /*!< Enable interrupt flag for high threshold for DTS1 */ +#define DTS_IT_TS1_AITE DTS_ITENR_TS1_AITEEN /*!< Enable asynchronous interrupt flag for end of measure for DTS1 */ +#define DTS_IT_TS1_AITL DTS_ITENR_TS1_AITLEN /*!< Enable asynchronous interrupt flag for low threshold for DTS1 */ +#define DTS_IT_TS1_AITH DTS_ITENR_TS1_AITHEN /*!< Enable asynchronous interrupt flag for high threshold for DTS1 */ +/** + * @} + */ + +/** + * @} + */ +/* Exported macros ---------------------------------------------------------------------------------------------------*/ +/** @defgroup DTS_Exported_Macros DTS Exported Macros + * @{ + */ + +/** @brief Reset DTS handle state + * @param __HANDLE__ DTS handle. + * @retval None + */ +#if (USE_HAL_DTS_REGISTER_CALLBACKS == 1U) +#define __HAL_DTS_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->State = HAL_DTS_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else /* USE_HAL_DTS_REGISTER_CALLBACKS */ +#define __HAL_DTS_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_DTS_STATE_RESET) +#endif /* USE_HAL_DTS_REGISTER_CALLBACKS */ + +/** + * @brief Enable the specified DTS sensor + * @param __HANDLE__ DTS handle. + * @retval None + */ +#define __HAL_DTS_ENABLE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CFGR1, DTS_CFGR1_TS1_EN) + +/** + * @brief Disable the specified DTS sensor + * @param __HANDLE__ DTS handle. + * @retval None + */ +#define __HAL_DTS_DISABLE(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->CFGR1, DTS_CFGR1_TS1_EN) + +/** + * @brief Enable the DTS EXTI line in interrupt mode + * @retval None + */ +#define __HAL_DTS_EXTI_WAKEUP_ENABLE_IT() SET_BIT(EXTI->IMR2, DTS_EXTI_LINE_DTS1) + +/** + * @brief Disable the DTS EXTI line in interrupt mode + * @retval None + */ +#define __HAL_DTS_EXTI_WAKEUP_DISABLE_IT() CLEAR_BIT(EXTI->IMR2, DTS_EXTI_LINE_DTS1) + +/** + * @brief Enable the DTS EXTI Line in event mode + * @retval None + */ +#define __HAL_DTS_EXTI_WAKEUP_ENABLE_EVENT() SET_BIT(EXTI->EMR2, DTS_EXTI_LINE_DTS1) + +/** + * @brief Disable the DTS EXTI Line in event mode + * @retval None + */ +#define __HAL_DTS_EXTI_WAKEUP_DISABLE_EVENT() CLEAR_BIT(EXTI->EMR2, DTS_EXTI_LINE_DTS1) + +/** @brief Checks whether the specified DTS flag is set or not. + * @param __HANDLE__ specifies the DTS Handle. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg DTS_FLAG_TS1_ITE : interrupt flag for end of measure for DTS1 + * @arg DTS_FLAG_TS1_ITL : interrupt flag for low threshold for DTS1 + * @arg DTS_FLAG_TS1_ITH : interrupt flag for high threshold for DTS1 + * @arg DTS_FLAG_TS1_AITE: asynchronous interrupt flag for end of measure for DTS1 + * @arg DTS_FLAG_TS1_AITL: asynchronous interrupt flag for low threshold for DTS1 + * @arg DTS_FLAG_TS1_AITH: asynchronous interrupt flag for high threshold for DTS1 + * @arg DTS_FLAG_TS1_RDY : Ready flag for DTS1 + * @retval The new state of __FLAG__ (SET or RESET). + */ +#define __HAL_DTS_GET_FLAG(__HANDLE__, __FLAG__) \ + (((((__HANDLE__)->Instance->SR &(__FLAG__)) == (__FLAG__)))? SET : RESET) + + +/** @brief Clears the specified DTS pending flag. + * @param __HANDLE__ specifies the DTS Handle. + * @param __FLAG__ specifies the flag to check. + * This parameter can be any combination of the following values: + * @arg DTS_FLAG_TS1_ITE : interrupt flag for end of measure for DTS1 + * @arg DTS_FLAG_TS1_ITL : interrupt flag for low threshold for DTS1 + * @arg DTS_FLAG_TS1_ITH : interrupt flag for high threshold for DTS1 + * @arg DTS_FLAG_TS1_AITE: asynchronous interrupt flag for end of measure for DTS1 + * @arg DTS_FLAG_TS1_AITL: asynchronous interrupt flag for low threshold for DTS1 + * @arg DTS_FLAG_TS1_AITH: asynchronous interrupt flag for high threshold for DTS1 + * @retval None + */ +#define __HAL_DTS_CLEAR_FLAG(__HANDLE__, __FLAG__) \ + ((__HANDLE__)->Instance->ICIFR = (__FLAG__)) + + +/** @brief Enable the specified DTS interrupt. + * @param __HANDLE__ specifies the DTS Handle. + * @param __INTERRUPT__ specifies the DTS interrupt source to enable. + * This parameter can be one of the following values: + * @arg DTS_IT_TS1_ITE : interrupt flag for end of measure for DTS1 + * @arg DTS_IT_TS1_ITL : interrupt flag for low of measure for DTS1 + * @arg DTS_IT_TS1_ITH : interrupt flag for high of measure for DTS1 + * @arg DTS_IT_TS1_AITE : asynchronous interrupt flag for end of measure for DTS1 + * @arg DTS_IT_TS1_AITL : asynchronous interrupt flag for low of measure for DTS1 + * @arg DTS_IT_TS1_AITH : asynchronous interrupt flag for high of measure for DTS1 + * @retval None + */ +#define __HAL_DTS_ENABLE_IT(__HANDLE__, __INTERRUPT__) \ + SET_BIT((__HANDLE__)->Instance->ITENR, __INTERRUPT__) + + +/** @brief Disable the specified DTS interrupt. + * @param __HANDLE__ specifies the DTS Handle. + * @param __INTERRUPT__ specifies the DTS interrupt source to enable. + * This parameter can be one of the following values: + * @arg DTS_IT_TS1_ITE : interrupt flag for end of measure for DTS1 + * @arg DTS_IT_TS1_ITL : interrupt flag for low of measure for DTS1 + * @arg DTS_IT_TS1_ITH : interrupt flag for high of measure for DTS1 + * @arg DTS_IT_TS1_AITE : asynchronous interrupt flag for end of measure for DTS1 + * @arg DTS_IT_TS1_AITL : asynchronous interrupt flag for low of measure for DTS1 + * @arg DTS_IT_TS1_AITH : asynchronous interrupt flag for high of measure for DTS1 + * @retval None + */ +#define __HAL_DTS_DISABLE_IT(__HANDLE__,__INTERRUPT__) \ + CLEAR_BIT((__HANDLE__)->Instance->ITENR, __INTERRUPT__) + + +/** @brief Check whether the specified DTS interrupt source is enabled or not. + * @param __HANDLE__ DTS handle. + * @param __INTERRUPT__ DTS interrupt source to check + * This parameter can be one of the following values: + * @arg DTS_IT_TS1_ITE : interrupt flag for end of measure for DTS1 + * @arg DTS_IT_TS1_ITL : interrupt flag for low of measure for DTS1 + * @arg DTS_IT_TS1_ITH : interrupt flag for high of measure for DTS1 + * @arg DTS_IT_TS1_AITE : asynchronous interrupt flag for end of measure for DTS1 + * @arg DTS_IT_TS1_AITL : asynchronous interrupt flag for low of measure for DTS1 + * @arg DTS_IT_TS1_AITH : asynchronous interrupt flag for high of measure for DTS1 + * @retval State of interruption (SET or RESET) + */ +#define __HAL_DTS_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) \ + (( ((__HANDLE__)->Instance->ITENR & (__INTERRUPT__)) == (__INTERRUPT__))? SET : RESET) + + +/** @brief Check whether the specified DTS REFCLK is selected + * @param __HANDLE__ DTS handle. + * @param __REFCLK__ DTS reference clock to check + * This parameter can be one of the following values: + * @arg DTS_REFCLKSEL_LSE: Low speed REF clock + * @arg DTS_REFCLKSEL_PCLK: High speed REF clock + * @retval State of the REF clock tested (SET or RESET) + */ +#define __HAL_DTS_GET_REFCLK(__HANDLE__, __REFCLK__) \ + ((((__HANDLE__)->Instance->CFGR1 & (__REFCLK__)) == (__REFCLK__))? SET : RESET) + +/** @brief Get Trigger + * @param __HANDLE__ DTS handle. + * @retval One of the following trigger + * DTS_TRIGGER_HW_NONE : No HW trigger (SW trigger) + * DTS_TRIGGER_LPTIMER1: LPTIMER1 trigger + * DTS_TRIGGER_LPTIMER2: LPTIMER2 trigger + * DTS_TRIGGER_LPTIMER3: LPTIMER3 trigger + * DTS_TRIGGER_EXTI13 : EXTI13 trigger + */ +#define __HAL_DTS_GET_TRIGGER(__HANDLE__) ((__HANDLE__)->Instance->CFGR1 & (DTS_CFGR1_TS1_INTRIG_SEL)) +/** + * @} + */ + +/* Exported functions ------------------------------------------------------------------------------------------------*/ +/** @addtogroup DTS_Exported_Functions + * @{ + */ + +/** @addtogroup DTS_Exported_Functions_Group1 + * @{ + */ +/* Initialization and de-initialization functions */ +HAL_StatusTypeDef HAL_DTS_Init(DTS_HandleTypeDef *hdts); +HAL_StatusTypeDef HAL_DTS_DeInit(DTS_HandleTypeDef *hdts); +void HAL_DTS_MspInit(DTS_HandleTypeDef *hdts); +void HAL_DTS_MspDeInit(DTS_HandleTypeDef *hdts); +#if (USE_HAL_DTS_REGISTER_CALLBACKS == 1U) +HAL_StatusTypeDef HAL_DTS_RegisterCallback(DTS_HandleTypeDef *hdts, + HAL_DTS_CallbackIDTypeDef CallbackID, + pDTS_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_DTS_UnRegisterCallback(DTS_HandleTypeDef *hdts, + HAL_DTS_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_DTS_REGISTER_CALLBACKS */ +/** + * @} + */ + + +/** @addtogroup DTS_Exported_Functions_Group2 + * @{ + */ +/* IO operation functions */ +HAL_StatusTypeDef HAL_DTS_Start(DTS_HandleTypeDef *hdts); +HAL_StatusTypeDef HAL_DTS_Stop(DTS_HandleTypeDef *hdts); +HAL_StatusTypeDef HAL_DTS_GetTemperature(DTS_HandleTypeDef *hdts, int32_t *Temperature); +HAL_StatusTypeDef HAL_DTS_Start_IT(DTS_HandleTypeDef *hdts); +HAL_StatusTypeDef HAL_DTS_Stop_IT(DTS_HandleTypeDef *hdts); +void HAL_DTS_IRQHandler(DTS_HandleTypeDef *hdts); +HAL_DTS_StateTypeDef HAL_DTS_GetState(const DTS_HandleTypeDef *hdts); + +/* Callback in Interrupt mode */ +void HAL_DTS_EndCallback(DTS_HandleTypeDef *hdts); +void HAL_DTS_LowCallback(DTS_HandleTypeDef *hdts); +void HAL_DTS_HighCallback(DTS_HandleTypeDef *hdts); +void HAL_DTS_AsyncEndCallback(DTS_HandleTypeDef *hdts); +void HAL_DTS_AsyncLowCallback(DTS_HandleTypeDef *hdts); +void HAL_DTS_AsyncHighCallback(DTS_HandleTypeDef *hdts); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -----------------------------------------------------------------------------------------------------*/ +/* Private constants -------------------------------------------------------------------------------------------------*/ +/** @defgroup DTS_Private_Constants DTS Private Constants + * @{ + */ +/** @defgroup DTS_ExtiLine DTS EXTI Lines + * @{ + */ +#define DTS_EXTI_LINE_DTS1 (EXTI_IMR2_IM50) /*!< EXTI line 50 connected to DTS1 output */ +/** + * @} + */ +/** + * @} + */ + +/* Private macros ----------------------------------------------------------------------------------------------------*/ +/** @defgroup DTS_Private_Macros DTS Private Macros + * @{ + */ + +/** @defgroup DTS_IS_DTS_Definitions DTS Private macros to check input parameters + * @{ + */ +#define IS_DTS_QUICKMEAS(__SEL__) (((__SEL__) == DTS_QUICKMEAS_DISABLE) || \ + ((__SEL__) == DTS_QUICKMEAS_ENABLE)) + +#define IS_DTS_REFCLK(__SEL__) (((__SEL__) == DTS_REFCLKSEL_LSE) || \ + ((__SEL__) == DTS_REFCLKSEL_PCLK)) +#if defined(LPTIM3) +#define IS_DTS_TRIGGERINPUT(__INPUT__) (((__INPUT__) == DTS_TRIGGER_HW_NONE) || \ + ((__INPUT__) == DTS_TRIGGER_LPTIMER1) || \ + ((__INPUT__) == DTS_TRIGGER_LPTIMER2) || \ + ((__INPUT__) == DTS_TRIGGER_LPTIMER3) || \ + ((__INPUT__) == DTS_TRIGGER_EXTI13)) +#else +#define IS_DTS_TRIGGERINPUT(__INPUT__) (((__INPUT__) == DTS_TRIGGER_HW_NONE) || \ + ((__INPUT__) == DTS_TRIGGER_LPTIMER1) || \ + ((__INPUT__) == DTS_TRIGGER_LPTIMER2) || \ + ((__INPUT__) == DTS_TRIGGER_EXTI13)) +#endif /* defined(LPTIM3) */ + +#define IS_DTS_THRESHOLD(__THRESHOLD__) ((__THRESHOLD__) <= 0xFFFFUL) + +#define IS_DTS_DIVIDER_RATIO_NUMBER(__NUMBER__) ((__NUMBER__) <= 127UL) + +#define IS_DTS_SAMPLINGTIME(__CYCLE__) (((__CYCLE__) == DTS_SMP_TIME_1_CYCLE) || \ + ((__CYCLE__) == DTS_SMP_TIME_2_CYCLE) || \ + ((__CYCLE__) == DTS_SMP_TIME_3_CYCLE) || \ + ((__CYCLE__) == DTS_SMP_TIME_4_CYCLE) || \ + ((__CYCLE__) == DTS_SMP_TIME_5_CYCLE) || \ + ((__CYCLE__) == DTS_SMP_TIME_6_CYCLE) || \ + ((__CYCLE__) == DTS_SMP_TIME_7_CYCLE) || \ + ((__CYCLE__) == DTS_SMP_TIME_8_CYCLE) || \ + ((__CYCLE__) == DTS_SMP_TIME_9_CYCLE) || \ + ((__CYCLE__) == DTS_SMP_TIME_10_CYCLE) || \ + ((__CYCLE__) == DTS_SMP_TIME_11_CYCLE) || \ + ((__CYCLE__) == DTS_SMP_TIME_12_CYCLE) || \ + ((__CYCLE__) == DTS_SMP_TIME_13_CYCLE) || \ + ((__CYCLE__) == DTS_SMP_TIME_14_CYCLE) || \ + ((__CYCLE__) == DTS_SMP_TIME_15_CYCLE)) + +/** + * @} + */ + +/** + * @} + */ + +/* Private functions -------------------------------------------------------------------------------------------------*/ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* DTS */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_DTS_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_eth.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_eth.h new file mode 100644 index 0000000000..7cab4dab15 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_eth.h @@ -0,0 +1,1827 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_eth.h + * @author MCD Application Team + * @brief Header file of ETH HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_ETH_H +#define STM32H5xx_HAL_ETH_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +#if defined(ETH) + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup ETH + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +#ifndef ETH_TX_DESC_CNT +#define ETH_TX_DESC_CNT 4U +#endif /* ETH_TX_DESC_CNT */ + +#ifndef ETH_RX_DESC_CNT +#define ETH_RX_DESC_CNT 4U +#endif /* ETH_RX_DESC_CNT */ + +#ifndef ETH_SWRESET_TIMEOUT +#define ETH_SWRESET_TIMEOUT 500U +#endif /* ETH_SWRESET_TIMEOUT */ + +#ifndef ETH_MDIO_BUS_TIMEOUT +#define ETH_MDIO_BUS_TIMEOUT 1000U +#endif /* ETH_MDIO_BUS_TIMEOUT */ + +#ifndef ETH_MAC_US_TICK +#define ETH_MAC_US_TICK 1000000U +#endif /* ETH_MAC_US_TICK */ + +/*********************** Descriptors struct def section ************************/ +/** @defgroup ETH_Exported_Types ETH Exported Types + * @{ + */ + +/** + * @brief ETH DMA Descriptor structure definition + */ +typedef struct +{ + __IO uint32_t DESC0; + __IO uint32_t DESC1; + __IO uint32_t DESC2; + __IO uint32_t DESC3; + uint32_t BackupAddr0; /* used to store rx buffer 1 address */ + uint32_t BackupAddr1; /* used to store rx buffer 2 address */ +} ETH_DMADescTypeDef; +/** + * + */ + +/** + * @brief ETH Buffers List structure definition + */ +typedef struct __ETH_BufferTypeDef +{ + uint8_t *buffer; /*gState = HAL_ETH_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_ETH_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->gState = HAL_ETH_STATE_RESET; \ + } while(0) +#endif /*USE_HAL_ETH_REGISTER_CALLBACKS */ + +/** + * @brief Enables the specified ETHERNET DMA interrupts. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the ETHERNET DMA interrupt sources to be + * enabled @ref ETH_DMA_Interrupts + * @retval None + */ +#define __HAL_ETH_DMA_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DMACIER |= (__INTERRUPT__)) + +/** + * @brief Disables the specified ETHERNET DMA interrupts. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the ETHERNET DMA interrupt sources to be + * disabled. @ref ETH_DMA_Interrupts + * @retval None + */ +#define __HAL_ETH_DMA_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DMACIER &= ~(__INTERRUPT__)) + +/** + * @brief Gets the ETHERNET DMA IT source enabled or disabled. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the interrupt source to get . @ref ETH_DMA_Interrupts + * @retval The ETH DMA IT Source enabled or disabled + */ +#define __HAL_ETH_DMA_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) \ + (((__HANDLE__)->Instance->DMACIER & (__INTERRUPT__)) == (__INTERRUPT__)) + +/** + * @brief Gets the ETHERNET DMA IT pending bit. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the interrupt source to get . @ref ETH_DMA_Interrupts + * @retval The state of ETH DMA IT (SET or RESET) + */ +#define __HAL_ETH_DMA_GET_IT(__HANDLE__, __INTERRUPT__) \ + (((__HANDLE__)->Instance->DMACSR & (__INTERRUPT__)) == (__INTERRUPT__)) + +/** + * @brief Clears the ETHERNET DMA IT pending bit. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the interrupt pending bit to clear. @ref ETH_DMA_Interrupts + * @retval None + */ +#define __HAL_ETH_DMA_CLEAR_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DMACSR = (__INTERRUPT__)) + +/** + * @brief Checks whether the specified ETHERNET DMA flag is set or not. + * @param __HANDLE__: ETH Handle + * @param __FLAG__: specifies the flag to check. @ref ETH_DMA_Status_Flags + * @retval The state of ETH DMA FLAG (SET or RESET). + */ +#define __HAL_ETH_DMA_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->DMACSR &( __FLAG__)) == ( __FLAG__)) + +/** + * @brief Clears the specified ETHERNET DMA flag. + * @param __HANDLE__: ETH Handle + * @param __FLAG__: specifies the flag to check. @ref ETH_DMA_Status_Flags + * @retval The state of ETH DMA FLAG (SET or RESET). + */ +#define __HAL_ETH_DMA_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->DMACSR = ( __FLAG__)) + +/** + * @brief Enables the specified ETHERNET MAC interrupts. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the ETHERNET MAC interrupt sources to be + * enabled @ref ETH_MAC_Interrupts + * @retval None + */ + +#define __HAL_ETH_MAC_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->MACIER |= (__INTERRUPT__)) + +/** + * @brief Disables the specified ETHERNET MAC interrupts. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the ETHERNET MAC interrupt sources to be + * enabled @ref ETH_MAC_Interrupts + * @retval None + */ +#define __HAL_ETH_MAC_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->MACIER &= ~(__INTERRUPT__)) + +/** + * @brief Checks whether the specified ETHERNET MAC flag is set or not. + * @param __HANDLE__: ETH Handle + * @param __INTERRUPT__: specifies the flag to check. @ref ETH_MAC_Interrupts + * @retval The state of ETH MAC IT (SET or RESET). + */ +#define __HAL_ETH_MAC_GET_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->MACISR &\ + ( __INTERRUPT__)) == ( __INTERRUPT__)) + +/*!< External interrupt line 46 Connected to the ETH wakeup EXTI Line */ +#define ETH_WAKEUP_EXTI_LINE 0x00004000U /* !< 46 - 32 = 14 */ + +/** + * @brief Enable the ETH WAKEUP Exti Line. + * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be enabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None. + */ +#define __HAL_ETH_WAKEUP_EXTI_ENABLE_IT(__EXTI_LINE__) (EXTI->IMR2 |= (__EXTI_LINE__)) + +/** + * @brief checks whether the specified ETH WAKEUP Exti interrupt flag is set or not. + * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be cleared. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval EXTI ETH WAKEUP Line Status. + */ +#define __HAL_ETH_WAKEUP_EXTI_GET_FLAG(__EXTI_LINE__) (EXTI->RPR2 & (__EXTI_LINE__)) + +/** + * @brief Clear the ETH WAKEUP Exti flag. + * @param __EXTI_LINE__: specifies the ETH WAKEUP Exti sources to be cleared. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None. + */ +#define __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG(__EXTI_LINE__) (EXTI->RPR2 = (__EXTI_LINE__)) + + +/** + * @brief enable rising edge interrupt on selected EXTI line. + * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None + */ +#define __HAL_ETH_WAKEUP_EXTI_ENABLE_RISING_EDGE(__EXTI_LINE__) (EXTI->FTSR2 &= ~(__EXTI_LINE__)); \ + (EXTI->RTSR2 |= (__EXTI_LINE__)) + +/** + * @brief enable falling edge interrupt on selected EXTI line. + * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None + */ +#define __HAL_ETH_WAKEUP_EXTI_ENABLE_FALLING_EDGE(__EXTI_LINE__) (EXTI->RTSR2 &= ~(__EXTI_LINE__));\ + (EXTI->FTSR2 |= (__EXTI_LINE__)) + +/** + * @brief enable falling edge interrupt on selected EXTI line. + * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None + */ +#define __HAL_ETH_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE(__EXTI_LINE__) (EXTI->RTSR2 |= (__EXTI_LINE__));\ + (EXTI->FTSR2 |= (__EXTI_LINE__)) + +/** + * @brief Generates a Software interrupt on selected EXTI line. + * @param __EXTI_LINE__: specifies the ETH WAKEUP EXTI sources to be disabled. + * @arg ETH_WAKEUP_EXTI_LINE + * @retval None + */ +#define __HAL_ETH_WAKEUP_EXTI_GENERATE_SWIT(__EXTI_LINE__) (EXTI->SWIER2 |= (__EXTI_LINE__)) +#define __HAL_ETH_GET_PTP_CONTROL(__HANDLE__, __FLAG__) (((((__HANDLE__)->Instance->MACTSCR) & \ + (__FLAG__)) == (__FLAG__)) ? SET : RESET) +#define __HAL_ETH_SET_PTP_CONTROL(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->MACTSCR |= (__FLAG__)) + +/** + * @} + */ + +/* Include ETH HAL Extension module */ +#include "stm32h5xx_hal_eth_ex.h" + +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup ETH_Exported_Functions + * @{ + */ + +/** @addtogroup ETH_Exported_Functions_Group1 + * @{ + */ +/* Initialization and de initialization functions **********************************/ +HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth); +HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth); +void HAL_ETH_MspInit(ETH_HandleTypeDef *heth); +void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth); + +/* Callbacks Register/UnRegister functions ***********************************/ +#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) +HAL_StatusTypeDef HAL_ETH_RegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID, + pETH_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_ETH_UnRegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @addtogroup ETH_Exported_Functions_Group2 + * @{ + */ +/* IO operation functions *******************************************************/ +HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth); +HAL_StatusTypeDef HAL_ETH_Start_IT(ETH_HandleTypeDef *heth); +HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth); +HAL_StatusTypeDef HAL_ETH_Stop_IT(ETH_HandleTypeDef *heth); + +HAL_StatusTypeDef HAL_ETH_ReadData(ETH_HandleTypeDef *heth, void **pAppBuff); +HAL_StatusTypeDef HAL_ETH_RegisterRxAllocateCallback(ETH_HandleTypeDef *heth, + pETH_rxAllocateCallbackTypeDef rxAllocateCallback); +HAL_StatusTypeDef HAL_ETH_UnRegisterRxAllocateCallback(ETH_HandleTypeDef *heth); +HAL_StatusTypeDef HAL_ETH_RegisterRxLinkCallback(ETH_HandleTypeDef *heth, pETH_rxLinkCallbackTypeDef rxLinkCallback); +HAL_StatusTypeDef HAL_ETH_UnRegisterRxLinkCallback(ETH_HandleTypeDef *heth); +HAL_StatusTypeDef HAL_ETH_GetRxDataErrorCode(ETH_HandleTypeDef *heth, uint32_t *pErrorCode); +HAL_StatusTypeDef HAL_ETH_RegisterTxFreeCallback(ETH_HandleTypeDef *heth, pETH_txFreeCallbackTypeDef txFreeCallback); +HAL_StatusTypeDef HAL_ETH_UnRegisterTxFreeCallback(ETH_HandleTypeDef *heth); +HAL_StatusTypeDef HAL_ETH_ReleaseTxPacket(ETH_HandleTypeDef *heth); + +#ifdef HAL_ETH_USE_PTP +HAL_StatusTypeDef HAL_ETH_PTP_SetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig); +HAL_StatusTypeDef HAL_ETH_PTP_GetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig); +HAL_StatusTypeDef HAL_ETH_PTP_SetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time); +HAL_StatusTypeDef HAL_ETH_PTP_GetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time); +HAL_StatusTypeDef HAL_ETH_PTP_AddTimeOffset(ETH_HandleTypeDef *heth, ETH_PtpUpdateTypeDef ptpoffsettype, + ETH_TimeTypeDef *timeoffset); +HAL_StatusTypeDef HAL_ETH_PTP_InsertTxTimestamp(ETH_HandleTypeDef *heth); +HAL_StatusTypeDef HAL_ETH_PTP_GetTxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp); +HAL_StatusTypeDef HAL_ETH_PTP_GetRxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp); +HAL_StatusTypeDef HAL_ETH_RegisterTxPtpCallback(ETH_HandleTypeDef *heth, pETH_txPtpCallbackTypeDef txPtpCallback); +HAL_StatusTypeDef HAL_ETH_UnRegisterTxPtpCallback(ETH_HandleTypeDef *heth); +#endif /* HAL_ETH_USE_PTP */ + +HAL_StatusTypeDef HAL_ETH_Transmit(ETH_HandleTypeDef *heth, ETH_TxPacketConfig *pTxConfig, uint32_t Timeout); +HAL_StatusTypeDef HAL_ETH_Transmit_IT(ETH_HandleTypeDef *heth, ETH_TxPacketConfig *pTxConfig); + +HAL_StatusTypeDef HAL_ETH_WritePHYRegister(const ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, + uint32_t RegValue); +HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, + uint32_t *pRegValue); + +void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth); +void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth); +void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth); +void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth); +void HAL_ETH_PMTCallback(ETH_HandleTypeDef *heth); +void HAL_ETH_EEECallback(ETH_HandleTypeDef *heth); +void HAL_ETH_WakeUpCallback(ETH_HandleTypeDef *heth); +void HAL_ETH_RxAllocateCallback(uint8_t **buff); +void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length); +void HAL_ETH_TxFreeCallback(uint32_t *buff); +void HAL_ETH_TxPtpCallback(uint32_t *buff, ETH_TimeStampTypeDef *timestamp); +/** + * @} + */ + +/** @addtogroup ETH_Exported_Functions_Group3 + * @{ + */ +/* Peripheral Control functions **********************************************/ +/* MAC & DMA Configuration APIs **********************************************/ +HAL_StatusTypeDef HAL_ETH_GetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf); +HAL_StatusTypeDef HAL_ETH_GetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf); +HAL_StatusTypeDef HAL_ETH_SetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf); +HAL_StatusTypeDef HAL_ETH_SetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf); +void HAL_ETH_SetMDIOClockRange(ETH_HandleTypeDef *heth); + +/* MAC VLAN Processing APIs ************************************************/ +void HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t ComparisonBits, + uint32_t VLANIdentifier); + +/* MAC L2 Packet Filtering APIs **********************************************/ +HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig(ETH_HandleTypeDef *heth, ETH_MACFilterConfigTypeDef *pFilterConfig); +HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef *heth, const ETH_MACFilterConfigTypeDef *pFilterConfig); +HAL_StatusTypeDef HAL_ETH_SetHashTable(ETH_HandleTypeDef *heth, uint32_t *pHashTable); +HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch(const ETH_HandleTypeDef *heth, uint32_t AddrNbr, + const uint8_t *pMACAddr); + +/* MAC Power Down APIs *****************************************************/ +void HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef *heth, + const ETH_PowerDownConfigTypeDef *pPowerDownConfig); +void HAL_ETH_ExitPowerDownMode(ETH_HandleTypeDef *heth); +HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFilter, uint32_t Count); + +/** + * @} + */ + +/** @addtogroup ETH_Exported_Functions_Group4 + * @{ + */ +/* Peripheral State functions **************************************************/ +HAL_ETH_StateTypeDef HAL_ETH_GetState(const ETH_HandleTypeDef *heth); +uint32_t HAL_ETH_GetError(const ETH_HandleTypeDef *heth); +uint32_t HAL_ETH_GetDMAError(const ETH_HandleTypeDef *heth); +uint32_t HAL_ETH_GetMACError(const ETH_HandleTypeDef *heth); +uint32_t HAL_ETH_GetMACWakeUpSource(const ETH_HandleTypeDef *heth); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* ETH */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_ETH_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_eth_ex.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_eth_ex.h new file mode 100644 index 0000000000..3aab63142b --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_eth_ex.h @@ -0,0 +1,368 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_eth_ex.h + * @author MCD Application Team + * @brief Header file of ETH HAL Extended module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_ETH_EX_H +#define STM32H5xx_HAL_ETH_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(ETH) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup ETHEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup ETHEx_Exported_Types ETHEx Exported Types + * @{ + */ + +/** + * @brief ETH RX VLAN structure definition + */ +typedef struct +{ + FunctionalState InnerVLANTagInStatus; /*!< Enables or disables Inner VLAN Tag in Rx Status */ + + uint32_t StripInnerVLANTag; /*!< Sets the Inner VLAN Tag Stripping on Receive + This parameter can be a value of + @ref ETHEx_Rx_Inner_VLAN_Tag_Stripping */ + + FunctionalState InnerVLANTag; /*!< Enables or disables Inner VLAN Tag */ + + FunctionalState DoubleVLANProcessing; /*!< Enable or Disable double VLAN processing */ + + FunctionalState VLANTagHashTableMatch; /*!< Enable or Disable VLAN Tag Hash Table Match */ + + FunctionalState VLANTagInStatus; /*!< Enable or Disable VLAN Tag in Rx status */ + + uint32_t StripVLANTag; /*!< Set the VLAN Tag Stripping on Receive + This parameter can be a value of @ref ETHEx_Rx_VLAN_Tag_Stripping */ + + uint32_t VLANTypeCheck; /*!< Enable or Disable VLAN Type Check + This parameter can be a value of @ref ETHEx_VLAN_Type_Check */ + + FunctionalState VLANTagInverceMatch; /*!< Enable or disable VLAN Tag Inverse Match */ +} ETH_RxVLANConfigTypeDef; +/** + * + */ + +/** + * @brief ETH TX VLAN structure definition + */ +typedef struct +{ + FunctionalState SourceTxDesc; /*!< Enable or Disable VLAN tag source from DMA tx descriptors */ + + FunctionalState SVLANType; /*!< Enable or Disable insertion of SVLAN type */ + + uint32_t VLANTagControl; /*!< Sets the VLAN tag control in tx packets + This parameter can be a value of @ref ETHEx_VLAN_Tag_Control */ +} ETH_TxVLANConfigTypeDef; +/** + * + */ + +/** + * @brief ETH L3 filter structure definition + */ +typedef struct +{ + uint32_t Protocol; /*!< Sets the L3 filter protocol to IPv4 or IPv6 + This parameter can be a value of @ref ETHEx_L3_Protocol */ + + uint32_t SrcAddrFilterMatch; /*!< Sets the L3 filter source address match + This parameter can be a value of @ref ETHEx_L3_Source_Match */ + + uint32_t DestAddrFilterMatch; /*!< Sets the L3 filter destination address match + This parameter can be a value of @ref ETHEx_L3_Destination_Match */ + + uint32_t SrcAddrHigherBitsMatch; /*!< Sets the L3 filter source address higher bits match + This parameter can be a value from 0 to 31 */ + + uint32_t DestAddrHigherBitsMatch; /*!< Sets the L3 filter destination address higher bits match + This parameter can be a value from 0 to 31 */ + + uint32_t Ip4SrcAddr; /*!< Sets the L3 filter IPv4 source address if IPv4 protocol is used + This parameter can be a value from 0x0 to 0xFFFFFFFF */ + + uint32_t Ip4DestAddr; /*!< Sets the L3 filter IPv4 destination address if IPv4 protocol is used + This parameter can be a value from 0 to 0xFFFFFFFF */ + + uint32_t Ip6Addr[4]; /*!< Sets the L3 filter IPv6 address if IPv6 protocol is used + This parameter must be a table of 4 words (4* 32 bits) */ +} ETH_L3FilterConfigTypeDef; +/** + * + */ + +/** + * @brief ETH L4 filter structure definition + */ +typedef struct +{ + uint32_t Protocol; /*!< Sets the L4 filter protocol to TCP or UDP + This parameter can be a value of @ref ETHEx_L4_Protocol */ + + uint32_t SrcPortFilterMatch; /*!< Sets the L4 filter source port match + This parameter can be a value of @ref ETHEx_L4_Source_Match */ + + uint32_t DestPortFilterMatch; /*!< Sets the L4 filter destination port match + This parameter can be a value of @ref ETHEx_L4_Destination_Match */ + + uint32_t SourcePort; /*!< Sets the L4 filter source port + This parameter must be a value from 0x0 to 0xFFFF */ + + uint32_t DestinationPort; /*!< Sets the L4 filter destination port + This parameter must be a value from 0x0 to 0xFFFF */ +} ETH_L4FilterConfigTypeDef; +/** + * + */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup ETHEx_Exported_Constants ETHEx Exported Constants + * @{ + */ + +/** @defgroup ETHEx_LPI_Event ETHEx LPI Event + * @{ + */ +#define ETH_TX_LPI_ENTRY ETH_MACLCSR_TLPIEN +#define ETH_TX_LPI_EXIT ETH_MACLCSR_TLPIEX +#define ETH_RX_LPI_ENTRY ETH_MACLCSR_RLPIEN +#define ETH_RX_LPI_EXIT ETH_MACLCSR_RLPIEX +/** + * @} + */ + +/** @defgroup ETHEx_L3_Filter ETHEx L3 Filter + * @{ + */ +#define ETH_L3_FILTER_0 0x00000000U +#define ETH_L3_FILTER_1 0x0000000CU +/** + * @} + */ + +/** @defgroup ETHEx_L4_Filter ETHEx L4 Filter + * @{ + */ +#define ETH_L4_FILTER_0 0x00000000U +#define ETH_L4_FILTER_1 0x0000000CU +/** + * @} + */ + +/** @defgroup ETHEx_L3_Protocol ETHEx L3 Protocol + * @{ + */ +#define ETH_L3_IPV6_MATCH ETH_MACL3L4CR_L3PEN +#define ETH_L3_IPV4_MATCH 0x00000000U +/** + * @} + */ + +/** @defgroup ETHEx_L3_Source_Match ETHEx L3 Source Match + * @{ + */ +#define ETH_L3_SRC_ADDR_PERFECT_MATCH_ENABLE ETH_MACL3L4CR_L3SAM +#define ETH_L3_SRC_ADDR_INVERSE_MATCH_ENABLE (ETH_MACL3L4CR_L3SAM | ETH_MACL3L4CR_L3SAIM) +#define ETH_L3_SRC_ADDR_MATCH_DISABLE 0x00000000U +/** + * @} + */ + +/** @defgroup ETHEx_L3_Destination_Match ETHEx L3 Destination Match + * @{ + */ +#define ETH_L3_DEST_ADDR_PERFECT_MATCH_ENABLE ETH_MACL3L4CR_L3DAM +#define ETH_L3_DEST_ADDR_INVERSE_MATCH_ENABLE (ETH_MACL3L4CR_L3DAM | ETH_MACL3L4CR_L3DAIM) +#define ETH_L3_DEST_ADDR_MATCH_DISABLE 0x00000000U +/** + * @} + */ + +/** @defgroup ETHEx_L4_Protocol ETHEx L4 Protocol + * @{ + */ +#define ETH_L4_UDP_MATCH ETH_MACL3L4CR_L4PEN +#define ETH_L4_TCP_MATCH 0x00000000U +/** + * @} + */ + +/** @defgroup ETHEx_L4_Source_Match ETHEx L4 Source Match + * @{ + */ +#define ETH_L4_SRC_PORT_PERFECT_MATCH_ENABLE ETH_MACL3L4CR_L4SPM +#define ETH_L4_SRC_PORT_INVERSE_MATCH_ENABLE (ETH_MACL3L4CR_L4SPM |ETH_MACL3L4CR_L4SPIM) +#define ETH_L4_SRC_PORT_MATCH_DISABLE 0x00000000U +/** + * @} + */ + +/** @defgroup ETHEx_L4_Destination_Match ETHEx L4 Destination Match + * @{ + */ +#define ETH_L4_DEST_PORT_PERFECT_MATCH_ENABLE ETH_MACL3L4CR_L4DPM +#define ETH_L4_DEST_PORT_INVERSE_MATCH_ENABLE (ETH_MACL3L4CR_L4DPM | ETH_MACL3L4CR_L4DPIM) +#define ETH_L4_DEST_PORT_MATCH_DISABLE 0x00000000U +/** + * @} + */ + +/** @defgroup ETHEx_Rx_Inner_VLAN_Tag_Stripping ETHEx Rx Inner VLAN Tag Stripping + * @{ + */ +#define ETH_INNERVLANTAGRXSTRIPPING_NONE ETH_MACVTR_EIVLS_DONOTSTRIP +#define ETH_INNERVLANTAGRXSTRIPPING_IFPASS ETH_MACVTR_EIVLS_STRIPIFPASS +#define ETH_INNERVLANTAGRXSTRIPPING_IFFAILS ETH_MACVTR_EIVLS_STRIPIFFAILS +#define ETH_INNERVLANTAGRXSTRIPPING_ALWAYS ETH_MACVTR_EIVLS_ALWAYSSTRIP +/** + * @} + */ + +/** @defgroup ETHEx_Rx_VLAN_Tag_Stripping ETHEx Rx VLAN Tag Stripping + * @{ + */ +#define ETH_VLANTAGRXSTRIPPING_NONE ETH_MACVTR_EVLS_DONOTSTRIP +#define ETH_VLANTAGRXSTRIPPING_IFPASS ETH_MACVTR_EVLS_STRIPIFPASS +#define ETH_VLANTAGRXSTRIPPING_IFFAILS ETH_MACVTR_EVLS_STRIPIFFAILS +#define ETH_VLANTAGRXSTRIPPING_ALWAYS ETH_MACVTR_EVLS_ALWAYSSTRIP +/** + * @} + */ + +/** @defgroup ETHEx_VLAN_Type_Check ETHEx VLAN Type Check + * @{ + */ +#define ETH_VLANTYPECHECK_DISABLE ETH_MACVTR_DOVLTC +#define ETH_VLANTYPECHECK_SVLAN (ETH_MACVTR_ERSVLM | ETH_MACVTR_ESVL) +#define ETH_VLANTYPECHECK_CVLAN 0x00000000U +/** + * @} + */ + +/** @defgroup ETHEx_VLAN_Tag_Control ETHEx_VLAN_Tag_Control + * @{ + */ +#define ETH_VLANTAGCONTROL_NONE (ETH_MACVIR_VLP | ETH_MACVIR_VLC_NOVLANTAG) +#define ETH_VLANTAGCONTROL_DELETE (ETH_MACVIR_VLP | ETH_MACVIR_VLC_VLANTAGDELETE) +#define ETH_VLANTAGCONTROL_INSERT (ETH_MACVIR_VLP | ETH_MACVIR_VLC_VLANTAGINSERT) +#define ETH_VLANTAGCONTROL_REPLACE (ETH_MACVIR_VLP | ETH_MACVIR_VLC_VLANTAGREPLACE) +/** + * @} + */ + +/** @defgroup ETHEx_Tx_VLAN_Tag ETHEx Tx VLAN Tag + * @{ + */ +#define ETH_INNER_TX_VLANTAG 0x00000001U +#define ETH_OUTER_TX_VLANTAG 0x00000000U +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup ETHEx_Exported_Functions + * @{ + */ + +/** @addtogroup ETHEx_Exported_Functions_Group1 + * @{ + */ +/* MAC ARP Offloading APIs ***************************************************/ +void HAL_ETHEx_EnableARPOffload(ETH_HandleTypeDef *heth); +void HAL_ETHEx_DisableARPOffload(ETH_HandleTypeDef *heth); +void HAL_ETHEx_SetARPAddressMatch(ETH_HandleTypeDef *heth, uint32_t IpAddress); + +/* MAC L3 L4 Filtering APIs ***************************************************/ +void HAL_ETHEx_EnableL3L4Filtering(ETH_HandleTypeDef *heth); +void HAL_ETHEx_DisableL3L4Filtering(ETH_HandleTypeDef *heth); +HAL_StatusTypeDef HAL_ETHEx_GetL3FilterConfig(ETH_HandleTypeDef *heth, uint32_t Filter, + ETH_L3FilterConfigTypeDef *pL3FilterConfig); +HAL_StatusTypeDef HAL_ETHEx_GetL4FilterConfig(ETH_HandleTypeDef *heth, uint32_t Filter, + ETH_L4FilterConfigTypeDef *pL4FilterConfig); +HAL_StatusTypeDef HAL_ETHEx_SetL3FilterConfig(ETH_HandleTypeDef *heth, uint32_t Filter, + ETH_L3FilterConfigTypeDef *pL3FilterConfig); +HAL_StatusTypeDef HAL_ETHEx_SetL4FilterConfig(ETH_HandleTypeDef *heth, uint32_t Filter, + ETH_L4FilterConfigTypeDef *pL4FilterConfig); + +/* MAC VLAN Processing APIs ************************************************/ +void HAL_ETHEx_EnableVLANProcessing(ETH_HandleTypeDef *heth); +void HAL_ETHEx_DisableVLANProcessing(ETH_HandleTypeDef *heth); +HAL_StatusTypeDef HAL_ETHEx_GetRxVLANConfig(ETH_HandleTypeDef *heth, ETH_RxVLANConfigTypeDef *pVlanConfig); +HAL_StatusTypeDef HAL_ETHEx_SetRxVLANConfig(ETH_HandleTypeDef *heth, ETH_RxVLANConfigTypeDef *pVlanConfig); +void HAL_ETHEx_SetVLANHashTable(ETH_HandleTypeDef *heth, uint32_t VLANHashTable); +HAL_StatusTypeDef HAL_ETHEx_GetTxVLANConfig(ETH_HandleTypeDef *heth, uint32_t VLANTag, + ETH_TxVLANConfigTypeDef *pVlanConfig); +HAL_StatusTypeDef HAL_ETHEx_SetTxVLANConfig(ETH_HandleTypeDef *heth, uint32_t VLANTag, + ETH_TxVLANConfigTypeDef *pVlanConfig); +void HAL_ETHEx_SetTxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t VLANTag, uint32_t VLANIdentifier); + +/* Energy Efficient Ethernet APIs *********************************************/ +void HAL_ETHEx_EnterLPIMode(ETH_HandleTypeDef *heth, FunctionalState TxAutomate, + FunctionalState TxClockStop); +void HAL_ETHEx_ExitLPIMode(ETH_HandleTypeDef *heth); +uint32_t HAL_ETHEx_GetMACLPIEvent(const ETH_HandleTypeDef *heth); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* ETH */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_ETH_EX_H */ + + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_exti.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_exti.h new file mode 100644 index 0000000000..0751486d77 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_exti.h @@ -0,0 +1,410 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_exti.h + * @author MCD Application Team + * @brief Header file of EXTI HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_EXTI_H +#define STM32H5xx_HAL_EXTI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup EXTI EXTI + * @brief EXTI HAL module driver + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup EXTI_Exported_Types EXTI Exported Types + * @{ + */ +typedef enum +{ + HAL_EXTI_COMMON_CB_ID = 0x00U, + HAL_EXTI_RISING_CB_ID = 0x01U, + HAL_EXTI_FALLING_CB_ID = 0x02U, +} EXTI_CallbackIDTypeDef; + + +/** + * @brief EXTI Handle structure definition + */ +typedef struct +{ + uint32_t Line; /*!< Exti line number */ + void (* RisingCallback)(void); /*!< Exti rising callback */ + void (* FallingCallback)(void); /*!< Exti falling callback */ +} EXTI_HandleTypeDef; + +/** + * @brief EXTI Configuration structure definition + */ +typedef struct +{ + uint32_t Line; /*!< The Exti line to be configured. This parameter + can be a value of @ref EXTI_Line */ + uint32_t Mode; /*!< The Exit Mode to be configured for a core. + This parameter can be a combination of @ref EXTI_Mode */ + uint32_t Trigger; /*!< The Exti Trigger to be configured. This parameter + can be a value of @ref EXTI_Trigger */ + uint32_t GPIOSel; /*!< The Exti GPIO multiplexer selection to be configured. + This parameter is only possible for line 0 to 15. It + can be a value of @ref EXTI_GPIOSel */ +} EXTI_ConfigTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup EXTI_Exported_Constants EXTI Exported Constants + * @{ + */ + +/** @defgroup EXTI_Line EXTI Line + * @{ + */ +#define EXTI_LINE_0 (EXTI_GPIO | EXTI_REG1 | 0x00U) +#define EXTI_LINE_1 (EXTI_GPIO | EXTI_REG1 | 0x01U) +#define EXTI_LINE_2 (EXTI_GPIO | EXTI_REG1 | 0x02U) +#define EXTI_LINE_3 (EXTI_GPIO | EXTI_REG1 | 0x03U) +#define EXTI_LINE_4 (EXTI_GPIO | EXTI_REG1 | 0x04U) +#define EXTI_LINE_5 (EXTI_GPIO | EXTI_REG1 | 0x05U) +#define EXTI_LINE_6 (EXTI_GPIO | EXTI_REG1 | 0x06U) +#define EXTI_LINE_7 (EXTI_GPIO | EXTI_REG1 | 0x07U) +#define EXTI_LINE_8 (EXTI_GPIO | EXTI_REG1 | 0x08U) +#define EXTI_LINE_9 (EXTI_GPIO | EXTI_REG1 | 0x09U) +#define EXTI_LINE_10 (EXTI_GPIO | EXTI_REG1 | 0x0AU) +#define EXTI_LINE_11 (EXTI_GPIO | EXTI_REG1 | 0x0BU) +#define EXTI_LINE_12 (EXTI_GPIO | EXTI_REG1 | 0x0CU) +#define EXTI_LINE_13 (EXTI_GPIO | EXTI_REG1 | 0x0DU) +#define EXTI_LINE_14 (EXTI_GPIO | EXTI_REG1 | 0x0EU) +#define EXTI_LINE_15 (EXTI_GPIO | EXTI_REG1 | 0x0FU) +#define EXTI_LINE_16 (EXTI_CONFIG | EXTI_REG1 | 0x10U) +#define EXTI_LINE_17 (EXTI_DIRECT | EXTI_REG1 | 0x11U) +#define EXTI_LINE_18 (EXTI_DIRECT | EXTI_REG1 | 0x12U) +#define EXTI_LINE_19 (EXTI_DIRECT | EXTI_REG1 | 0x13U) +#define EXTI_LINE_20 (EXTI_DIRECT | EXTI_REG1 | 0x14U) +#define EXTI_LINE_21 (EXTI_DIRECT | EXTI_REG1 | 0x15U) +#define EXTI_LINE_22 (EXTI_DIRECT | EXTI_REG1 | 0x16U) +#define EXTI_LINE_23 (EXTI_DIRECT | EXTI_REG1 | 0x17U) +#define EXTI_LINE_24 (EXTI_DIRECT | EXTI_REG1 | 0x18U) +#define EXTI_LINE_25 (EXTI_DIRECT | EXTI_REG1 | 0x19U) +#define EXTI_LINE_26 (EXTI_DIRECT | EXTI_REG1 | 0x1AU) +#define EXTI_LINE_27 (EXTI_DIRECT | EXTI_REG1 | 0x1BU) +#define EXTI_LINE_28 (EXTI_DIRECT | EXTI_REG1 | 0x1CU) +#define EXTI_LINE_29 (EXTI_DIRECT | EXTI_REG1 | 0x1DU) +#define EXTI_LINE_30 (EXTI_DIRECT | EXTI_REG1 | 0x1EU) +#define EXTI_LINE_31 (EXTI_DIRECT | EXTI_REG1 | 0x1FU) +#define EXTI_LINE_32 (EXTI_DIRECT | EXTI_REG2 | 0x00U) +#define EXTI_LINE_33 (EXTI_DIRECT | EXTI_REG2 | 0x01U) +#define EXTI_LINE_34 (EXTI_DIRECT | EXTI_REG2 | 0x02U) +#define EXTI_LINE_35 (EXTI_DIRECT | EXTI_REG2 | 0x03U) +#define EXTI_LINE_36 (EXTI_DIRECT | EXTI_REG2 | 0x04U) +#define EXTI_LINE_37 (EXTI_DIRECT | EXTI_REG2 | 0x05U) +#define EXTI_LINE_38 (EXTI_DIRECT | EXTI_REG2 | 0x06U) +#define EXTI_LINE_39 (EXTI_DIRECT | EXTI_REG2 | 0x07U) +#define EXTI_LINE_40 (EXTI_DIRECT | EXTI_REG2 | 0x08U) +#define EXTI_LINE_41 (EXTI_DIRECT | EXTI_REG2 | 0x09U) +#define EXTI_LINE_42 (EXTI_DIRECT | EXTI_REG2 | 0x0AU) +#define EXTI_LINE_43 (EXTI_DIRECT | EXTI_REG2 | 0x0BU) +#define EXTI_LINE_44 (EXTI_DIRECT | EXTI_REG2 | 0x0CU) +#define EXTI_LINE_45 (EXTI_DIRECT | EXTI_REG2 | 0x0DU) +#if defined(ETH) +#define EXTI_LINE_46 (EXTI_CONFIG | EXTI_REG2 | 0x0EU) +#endif /* ETH */ +#define EXTI_LINE_47 (EXTI_DIRECT | EXTI_REG2 | 0x0FU) +#define EXTI_LINE_48 (EXTI_DIRECT | EXTI_REG2 | 0x10U) +#define EXTI_LINE_49 (EXTI_DIRECT | EXTI_REG2 | 0x11U) +#define EXTI_LINE_50 (EXTI_CONFIG | EXTI_REG2 | 0x12U) +#define EXTI_LINE_51 (EXTI_DIRECT | EXTI_REG2 | 0x13U) +#define EXTI_LINE_52 (EXTI_DIRECT | EXTI_REG2 | 0x14U) +#define EXTI_LINE_53 (EXTI_CONFIG | EXTI_REG2 | 0x15U) +#define EXTI_LINE_54 (EXTI_DIRECT | EXTI_REG2 | 0x16U) +#define EXTI_LINE_55 (EXTI_DIRECT | EXTI_REG2 | 0x17U) +#define EXTI_LINE_56 (EXTI_DIRECT | EXTI_REG2 | 0x18U) +#define EXTI_LINE_57 (EXTI_DIRECT | EXTI_REG2 | 0x19U) + +/** + * @} + */ + +/** @defgroup EXTI_Mode EXTI Mode + * @{ + */ +#define EXTI_MODE_NONE 0x00000000U +#define EXTI_MODE_INTERRUPT 0x00000001U +#define EXTI_MODE_EVENT 0x00000002U +/** + * @} + */ + +/** @defgroup EXTI_Trigger EXTI Trigger + * @{ + */ +#define EXTI_TRIGGER_NONE 0x00000000U +#define EXTI_TRIGGER_RISING 0x00000001U +#define EXTI_TRIGGER_FALLING 0x00000002U +#define EXTI_TRIGGER_RISING_FALLING (EXTI_TRIGGER_RISING | EXTI_TRIGGER_FALLING) +/** + * @} + */ + +/** @defgroup EXTI_GPIOSel EXTI GPIOSel + * @brief + * @{ + */ +#define EXTI_GPIOA 0x00000000U +#define EXTI_GPIOB 0x00000001U +#define EXTI_GPIOC 0x00000002U +#define EXTI_GPIOD 0x00000003U +#define EXTI_GPIOE 0x00000004U +#define EXTI_GPIOF 0x00000005U +#define EXTI_GPIOG 0x00000006U +#define EXTI_GPIOH 0x00000007U +#define EXTI_GPIOI 0x00000008U +/** + * @} + */ + +/** @defgroup EXTI_Line_attributes EXTI line attributes + * @brief EXTI line secure or non-secure and privileged or non-privileged attributes + * @note secure and non-secure attributes are only available from secure state when the system + * implement the security (TZEN=1) + * @{ + */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/*!< Secure line attribute */ +#define EXTI_LINE_SEC (EXTI_LINE_ATTR_SEC_MASK | 0x00000001U) +/*!< Non-secure line attribute */ +#define EXTI_LINE_NSEC (EXTI_LINE_ATTR_SEC_MASK | 0x00000000U) +#endif /* __ARM_FEATURE_CMSE */ +/*!< Privileged line attribute */ +#define EXTI_LINE_PRIV (EXTI_LINE_ATTR_PRIV_MASK | 0x00000002U) +/*!< Non-privileged line attribute */ +#define EXTI_LINE_NPRIV (EXTI_LINE_ATTR_PRIV_MASK | 0x00000000U) +/** + * @} + */ +/** @defgroup EXTI_Security_Privilege_Configuration EXTI Security Privilege Configuration + * @brief EXTI security and privilege configurations + * @{ + */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/* Security and privilege configuration open, can be modified */ +#define EXTI_ATTRIBUTES_UNLOCKED 0x00000000U +/* Security and privilege configuration locked, can no longer be modified */ +#define EXTI_ATTRIBUTES_LOCKED 0x00000001U +#endif /* __ARM_FEATURE_CMSE */ +/** + * @} + */ +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup EXTI_Exported_Macros EXTI Exported Macros + * @{ + */ + +/** + * @} + */ + +/* Private constants --------------------------------------------------------*/ +/** @defgroup EXTI_Private_Constants EXTI Private Constants + * @{ + */ +/** + * @brief EXTI Line property definition + */ +#define EXTI_PROPERTY_SHIFT 24U +#define EXTI_DIRECT (0x01U << EXTI_PROPERTY_SHIFT) +#define EXTI_CONFIG (0x02U << EXTI_PROPERTY_SHIFT) +#define EXTI_GPIO ((0x04U << EXTI_PROPERTY_SHIFT) | EXTI_CONFIG) +#define EXTI_RESERVED (0x08U << EXTI_PROPERTY_SHIFT) +#define EXTI_PROPERTY_MASK (EXTI_DIRECT | EXTI_CONFIG | EXTI_GPIO) + +/** + * @brief EXTI Register and bit usage + */ +#define EXTI_REG_SHIFT 16U +#define EXTI_REG1 (0x00U << EXTI_REG_SHIFT) +#define EXTI_REG2 (0x01U << EXTI_REG_SHIFT) +#define EXTI_REG_MASK (EXTI_REG1 | EXTI_REG2) +#define EXTI_PIN_MASK 0x0000001FU + +/** + * @brief EXTI Mask for interrupt & event mode + */ +#define EXTI_MODE_MASK (EXTI_MODE_EVENT | EXTI_MODE_INTERRUPT) + +/** + * @brief EXTI Mask for trigger possibilities + */ +#define EXTI_TRIGGER_MASK (EXTI_TRIGGER_RISING | EXTI_TRIGGER_FALLING) + +/** + * @brief EXTI Line number + */ +#define EXTI_LINE_NB 58U + +/** + * @brief EXTI Mask for secure & privilege attributes + */ +#define EXTI_LINE_ATTR_SEC_MASK 0x100U +#define EXTI_LINE_ATTR_PRIV_MASK 0x200U +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup EXTI_Private_Macros EXTI Private Macros + * @{ + */ +#define IS_EXTI_LINE(__EXTI_LINE__) ((((__EXTI_LINE__) & ~(EXTI_PROPERTY_MASK | \ + EXTI_REG_MASK | EXTI_PIN_MASK)) == 0x00U) \ + &&((((__EXTI_LINE__) & EXTI_PROPERTY_MASK) == EXTI_DIRECT) || \ + (((__EXTI_LINE__) & EXTI_PROPERTY_MASK) == EXTI_CONFIG) || \ + (((__EXTI_LINE__) & EXTI_PROPERTY_MASK) == EXTI_GPIO)) && \ + (((__EXTI_LINE__) & (EXTI_REG_MASK | EXTI_PIN_MASK)) < \ + (((EXTI_LINE_NB / 32U) << EXTI_REG_SHIFT) | (EXTI_LINE_NB % 32U)))) + +#define IS_EXTI_MODE(__EXTI_LINE__) ((((__EXTI_LINE__) & EXTI_MODE_MASK) != 0x00U) && \ + (((__EXTI_LINE__) & ~EXTI_MODE_MASK) == 0x00U)) + +#define IS_EXTI_TRIGGER(__EXTI_LINE__) (((__EXTI_LINE__) & ~EXTI_TRIGGER_MASK) == 0x00U) + +#define IS_EXTI_PENDING_EDGE(__EXTI_LINE__) (((__EXTI_LINE__) == EXTI_TRIGGER_RISING) || \ + ((__EXTI_LINE__) == EXTI_TRIGGER_FALLING)) + +#define IS_EXTI_CONFIG_LINE(__EXTI_LINE__) (((__EXTI_LINE__) & EXTI_CONFIG) != 0x00U) + +#define IS_EXTI_GPIO_PORT(__PORT__) (((__PORT__) == EXTI_GPIOA) || \ + ((__PORT__) == EXTI_GPIOB) || \ + ((__PORT__) == EXTI_GPIOC) || \ + ((__PORT__) == EXTI_GPIOD) || \ + ((__PORT__) == EXTI_GPIOE) || \ + ((__PORT__) == EXTI_GPIOF) || \ + ((__PORT__) == EXTI_GPIOG) || \ + ((__PORT__) == EXTI_GPIOH) || \ + ((__PORT__) == EXTI_GPIOI)) + +#define IS_EXTI_GPIO_PIN(__PIN__) ((__PIN__) < 16U) + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +#define IS_EXTI_LINE_ATTRIBUTES(__ATTRIBUTES__) (((((__ATTRIBUTES__) & EXTI_LINE_SEC) == EXTI_LINE_SEC) || \ + (((__ATTRIBUTES__) & EXTI_LINE_NSEC) == EXTI_LINE_NSEC) || \ + (((__ATTRIBUTES__) & EXTI_LINE_PRIV) == EXTI_LINE_PRIV) || \ + (((__ATTRIBUTES__) & EXTI_LINE_NPRIV) == EXTI_LINE_NPRIV)) && \ + (((__ATTRIBUTES__) & ~(EXTI_LINE_SEC|EXTI_LINE_NSEC|EXTI_LINE_PRIV| \ + EXTI_LINE_NPRIV)) == 0U)) + +#else + +#define IS_EXTI_LINE_ATTRIBUTES(__ATTRIBUTES__) (((((__ATTRIBUTES__) & EXTI_LINE_PRIV) == EXTI_LINE_PRIV) || \ + (((__ATTRIBUTES__) & EXTI_LINE_NPRIV) == EXTI_LINE_NPRIV)) && \ + (((__ATTRIBUTES__) & ~(EXTI_LINE_PRIV|EXTI_LINE_NPRIV)) == 0U)) + +#endif /* __ARM_FEATURE_CMSE */ + +/** + * @} + */ + + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup EXTI_Exported_Functions EXTI Exported Functions + * @brief EXTI Exported Functions + * @{ + */ + +/** @defgroup EXTI_Exported_Functions_Group1 Configuration functions + * @brief Configuration functions + * @{ + */ +/* Configuration functions ****************************************************/ +HAL_StatusTypeDef HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig); +HAL_StatusTypeDef HAL_EXTI_GetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig); +HAL_StatusTypeDef HAL_EXTI_ClearConfigLine(const EXTI_HandleTypeDef *hexti); +HAL_StatusTypeDef HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef *hexti, EXTI_CallbackIDTypeDef CallbackID, + void (*pPendingCbfn)(void)); +HAL_StatusTypeDef HAL_EXTI_GetHandle(EXTI_HandleTypeDef *hexti, uint32_t ExtiLine); +/** + * @} + */ + +/** @defgroup EXTI_Exported_Functions_Group2 IO operation functions + * @brief IO operation functions + * @{ + */ +/* IO operation functions *****************************************************/ +void HAL_EXTI_IRQHandler(const EXTI_HandleTypeDef *hexti); +uint32_t HAL_EXTI_GetPending(const EXTI_HandleTypeDef *hexti, uint32_t Edge); +void HAL_EXTI_ClearPending(const EXTI_HandleTypeDef *hexti, uint32_t Edge); +void HAL_EXTI_GenerateSWI(const EXTI_HandleTypeDef *hexti); + +/** + * @} + */ + +/** @addtogroup EXTI_Exported_Functions_Group3 EXTI line attributes management functions + * @{ + */ + +/* EXTI line attributes management functions **********************************/ +void HAL_EXTI_ConfigLineAttributes(uint32_t ExtiLine, uint32_t LineAttributes); +HAL_StatusTypeDef HAL_EXTI_GetConfigLineAttributes(uint32_t ExtiLine, uint32_t *pLineAttributes); + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +HAL_StatusTypeDef HAL_EXTI_LockConfigAttributes(void); +HAL_StatusTypeDef HAL_EXTI_GetLockConfigAttributes(uint32_t *const pLockState); +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_EXTI_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_fdcan.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_fdcan.h new file mode 100644 index 0000000000..204a38bc02 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_fdcan.h @@ -0,0 +1,1442 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_fdcan.h + * @author MCD Application Team + * @brief Header file of FDCAN HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_FDCAN_H +#define STM32H5xx_HAL_FDCAN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +#if defined(FDCAN1) + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup FDCAN + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup FDCAN_Exported_Types FDCAN Exported Types + * @{ + */ + +/** + * @brief HAL State structures definition + */ +typedef enum +{ + HAL_FDCAN_STATE_RESET = 0x00U, /*!< FDCAN not yet initialized or disabled */ + HAL_FDCAN_STATE_READY = 0x01U, /*!< FDCAN initialized and ready for use */ + HAL_FDCAN_STATE_BUSY = 0x02U, /*!< FDCAN process is ongoing */ + HAL_FDCAN_STATE_ERROR = 0x03U /*!< FDCAN error state */ +} HAL_FDCAN_StateTypeDef; + +/** + * @brief FDCAN Init structure definition + */ +typedef struct +{ + uint32_t ClockDivider; /*!< Specifies the FDCAN kernel clock divider. + The clock is common to all FDCAN instances. + This parameter is applied only at initialisation of + first FDCAN instance. + This parameter can be a value of @ref FDCAN_clock_divider. */ + + uint32_t FrameFormat; /*!< Specifies the FDCAN frame format. + This parameter can be a value of @ref FDCAN_frame_format */ + + uint32_t Mode; /*!< Specifies the FDCAN mode. + This parameter can be a value of @ref FDCAN_operating_mode */ + + FunctionalState AutoRetransmission; /*!< Enable or disable the automatic retransmission mode. + This parameter can be set to ENABLE or DISABLE */ + + FunctionalState TransmitPause; /*!< Enable or disable the Transmit Pause feature. + This parameter can be set to ENABLE or DISABLE */ + + FunctionalState ProtocolException; /*!< Enable or disable the Protocol Exception Handling. + This parameter can be set to ENABLE or DISABLE */ + + uint32_t NominalPrescaler; /*!< Specifies the value by which the oscillator frequency is + divided for generating the nominal bit time quanta. + This parameter must be a number between 1 and 512 */ + + uint32_t NominalSyncJumpWidth; /*!< Specifies the maximum number of time quanta the FDCAN + hardware is allowed to lengthen or shorten a bit to perform + resynchronization. + This parameter must be a number between 1 and 128 */ + + uint32_t NominalTimeSeg1; /*!< Specifies the number of time quanta in Bit Segment 1. + This parameter must be a number between 2 and 256 */ + + uint32_t NominalTimeSeg2; /*!< Specifies the number of time quanta in Bit Segment 2. + This parameter must be a number between 2 and 128 */ + + uint32_t DataPrescaler; /*!< Specifies the value by which the oscillator frequency is + divided for generating the data bit time quanta. + This parameter must be a number between 1 and 32 */ + + uint32_t DataSyncJumpWidth; /*!< Specifies the maximum number of time quanta the FDCAN + hardware is allowed to lengthen or shorten a data bit to + perform resynchronization. + This parameter must be a number between 1 and 16 */ + + uint32_t DataTimeSeg1; /*!< Specifies the number of time quanta in Data Bit Segment 1. + This parameter must be a number between 1 and 32 */ + + uint32_t DataTimeSeg2; /*!< Specifies the number of time quanta in Data Bit Segment 2. + This parameter must be a number between 1 and 16 */ + + uint32_t StdFiltersNbr; /*!< Specifies the number of standard Message ID filters. + This parameter must be a number between 0 and 28 */ + + uint32_t ExtFiltersNbr; /*!< Specifies the number of extended Message ID filters. + This parameter must be a number between 0 and 8 */ + + uint32_t TxFifoQueueMode; /*!< Tx FIFO/Queue Mode selection. + This parameter can be a value of @ref FDCAN_txFifoQueue_Mode */ + +} FDCAN_InitTypeDef; + +/** + * @brief FDCAN filter structure definition + */ +typedef struct +{ + uint32_t IdType; /*!< Specifies the identifier type. + This parameter can be a value of @ref FDCAN_id_type */ + + uint32_t FilterIndex; /*!< Specifies the filter which will be initialized. + This parameter must be a number between: + - 0 and (SRAMCAN_FLS_NBR-1), if IdType is FDCAN_STANDARD_ID + - 0 and (SRAMCAN_FLE_NBR-1), if IdType is FDCAN_EXTENDED_ID */ + + uint32_t FilterType; /*!< Specifies the filter type. + This parameter can be a value of @ref FDCAN_filter_type. + The value FDCAN_FILTER_RANGE_NO_EIDM is permitted + only when IdType is FDCAN_EXTENDED_ID. */ + + uint32_t FilterConfig; /*!< Specifies the filter configuration. + This parameter can be a value of @ref FDCAN_filter_config */ + + uint32_t FilterID1; /*!< Specifies the filter identification 1. + This parameter must be a number between: + - 0 and 0x7FF, if IdType is FDCAN_STANDARD_ID + - 0 and 0x1FFFFFFF, if IdType is FDCAN_EXTENDED_ID */ + + uint32_t FilterID2; /*!< Specifies the filter identification 2. + This parameter must be a number between: + - 0 and 0x7FF, if IdType is FDCAN_STANDARD_ID + - 0 and 0x1FFFFFFF, if IdType is FDCAN_EXTENDED_ID */ + +} FDCAN_FilterTypeDef; + +/** + * @brief FDCAN Tx header structure definition + */ +typedef struct +{ + uint32_t Identifier; /*!< Specifies the identifier. + This parameter must be a number between: + - 0 and 0x7FF, if IdType is FDCAN_STANDARD_ID + - 0 and 0x1FFFFFFF, if IdType is FDCAN_EXTENDED_ID */ + + uint32_t IdType; /*!< Specifies the identifier type for the message that will be + transmitted. + This parameter can be a value of @ref FDCAN_id_type */ + + uint32_t TxFrameType; /*!< Specifies the frame type of the message that will be transmitted. + This parameter can be a value of @ref FDCAN_frame_type */ + + uint32_t DataLength; /*!< Specifies the length of the frame that will be transmitted. + This parameter can be a value of @ref FDCAN_data_length_code */ + + uint32_t ErrorStateIndicator; /*!< Specifies the error state indicator. + This parameter can be a value of @ref FDCAN_error_state_indicator */ + + uint32_t BitRateSwitch; /*!< Specifies whether the Tx frame will be transmitted with or without + bit rate switching. + This parameter can be a value of @ref FDCAN_bit_rate_switching */ + + uint32_t FDFormat; /*!< Specifies whether the Tx frame will be transmitted in classic or + FD format. + This parameter can be a value of @ref FDCAN_format */ + + uint32_t TxEventFifoControl; /*!< Specifies the event FIFO control. + This parameter can be a value of @ref FDCAN_EFC */ + + uint32_t MessageMarker; /*!< Specifies the message marker to be copied into Tx Event FIFO + element for identification of Tx message status. + This parameter must be a number between 0 and 0xFF */ + +} FDCAN_TxHeaderTypeDef; + +/** + * @brief FDCAN Rx header structure definition + */ +typedef struct +{ + uint32_t Identifier; /*!< Specifies the identifier. + This parameter must be a number between: + - 0 and 0x7FF, if IdType is FDCAN_STANDARD_ID + - 0 and 0x1FFFFFFF, if IdType is FDCAN_EXTENDED_ID */ + + uint32_t IdType; /*!< Specifies the identifier type of the received message. + This parameter can be a value of @ref FDCAN_id_type */ + + uint32_t RxFrameType; /*!< Specifies the the received message frame type. + This parameter can be a value of @ref FDCAN_frame_type */ + + uint32_t DataLength; /*!< Specifies the received frame length. + This parameter can be a value of @ref FDCAN_data_length_code */ + + uint32_t ErrorStateIndicator; /*!< Specifies the error state indicator. + This parameter can be a value of @ref FDCAN_error_state_indicator */ + + uint32_t BitRateSwitch; /*!< Specifies whether the Rx frame is received with or without bit + rate switching. + This parameter can be a value of @ref FDCAN_bit_rate_switching */ + + uint32_t FDFormat; /*!< Specifies whether the Rx frame is received in classic or FD + format. + This parameter can be a value of @ref FDCAN_format */ + + uint32_t RxTimestamp; /*!< Specifies the timestamp counter value captured on start of frame + reception. + This parameter must be a number between 0 and 0xFFFF */ + + uint32_t FilterIndex; /*!< Specifies the index of matching Rx acceptance filter element. + This parameter must be a number between: + - 0 and (SRAMCAN_FLS_NBR-1), if IdType is FDCAN_STANDARD_ID + - 0 and (SRAMCAN_FLE_NBR-1), if IdType is FDCAN_EXTENDED_ID + When the frame is a Non-Filter matching frame, this parameter + is unused. */ + + uint32_t IsFilterMatchingFrame; /*!< Specifies whether the accepted frame did not match any Rx filter. + Acceptance of non-matching frames may be enabled via + HAL_FDCAN_ConfigGlobalFilter(). + This parameter takes 0 if the frame matched an Rx filter or + 1 if it did not match any Rx filter */ + +} FDCAN_RxHeaderTypeDef; + +/** + * @brief FDCAN Tx event FIFO structure definition + */ +typedef struct +{ + uint32_t Identifier; /*!< Specifies the identifier. + This parameter must be a number between: + - 0 and 0x7FF, if IdType is FDCAN_STANDARD_ID + - 0 and 0x1FFFFFFF, if IdType is FDCAN_EXTENDED_ID */ + + uint32_t IdType; /*!< Specifies the identifier type for the transmitted message. + This parameter can be a value of @ref FDCAN_id_type */ + + uint32_t TxFrameType; /*!< Specifies the frame type of the transmitted message. + This parameter can be a value of @ref FDCAN_frame_type */ + + uint32_t DataLength; /*!< Specifies the length of the transmitted frame. + This parameter can be a value of @ref FDCAN_data_length_code */ + + uint32_t ErrorStateIndicator; /*!< Specifies the error state indicator. + This parameter can be a value of @ref FDCAN_error_state_indicator */ + + uint32_t BitRateSwitch; /*!< Specifies whether the Tx frame is transmitted with or without bit + rate switching. + This parameter can be a value of @ref FDCAN_bit_rate_switching */ + + uint32_t FDFormat; /*!< Specifies whether the Tx frame is transmitted in classic or FD + format. + This parameter can be a value of @ref FDCAN_format */ + + uint32_t TxTimestamp; /*!< Specifies the timestamp counter value captured on start of frame + transmission. + This parameter must be a number between 0 and 0xFFFF */ + + uint32_t MessageMarker; /*!< Specifies the message marker copied into Tx Event FIFO element + for identification of Tx message status. + This parameter must be a number between 0 and 0xFF */ + + uint32_t EventType; /*!< Specifies the event type. + This parameter can be a value of @ref FDCAN_event_type */ + +} FDCAN_TxEventFifoTypeDef; + +/** + * @brief FDCAN High Priority Message Status structure definition + */ +typedef struct +{ + uint32_t FilterList; /*!< Specifies the filter list of the matching filter element. + This parameter can be: + - 0 : Standard Filter List + - 1 : Extended Filter List */ + + uint32_t FilterIndex; /*!< Specifies the index of matching filter element. + This parameter can be a number between: + - 0 and (SRAMCAN_FLS_NBR-1), if FilterList is 0 (Standard) + - 0 and (SRAMCAN_FLE_NBR-1), if FilterList is 1 (Extended) */ + + uint32_t MessageStorage; /*!< Specifies the HP Message Storage. + This parameter can be a value of @ref FDCAN_hp_msg_storage */ + + uint32_t MessageIndex; /*!< Specifies the Index of Rx FIFO element to which the + message was stored. + This parameter is valid only when MessageStorage is: + FDCAN_HP_STORAGE_RXFIFO0 + or + FDCAN_HP_STORAGE_RXFIFO1 */ + +} FDCAN_HpMsgStatusTypeDef; + +/** + * @brief FDCAN Protocol Status structure definition + */ +typedef struct +{ + uint32_t LastErrorCode; /*!< Specifies the type of the last error that occurred on the FDCAN bus. + This parameter can be a value of @ref FDCAN_protocol_error_code */ + + uint32_t DataLastErrorCode; /*!< Specifies the type of the last error that occurred in the data phase + of a CAN FD format frame with its BRS flag set. + This parameter can be a value of @ref FDCAN_protocol_error_code */ + + uint32_t Activity; /*!< Specifies the FDCAN module communication state. + This parameter can be a value of @ref FDCAN_communication_state */ + + uint32_t ErrorPassive; /*!< Specifies the FDCAN module error status. + This parameter can be: + - 0 : The FDCAN is in Error_Active state + - 1 : The FDCAN is in Error_Passive state */ + + uint32_t Warning; /*!< Specifies the FDCAN module warning status. + This parameter can be: + - 0 : error counters (RxErrorCnt and TxErrorCnt) are below the + Error_Warning limit of 96 + - 1 : at least one of error counters has reached the Error_Warning + limit of 96 */ + + uint32_t BusOff; /*!< Specifies the FDCAN module Bus_Off status. + This parameter can be: + - 0 : The FDCAN is not in Bus_Off state + - 1 : The FDCAN is in Bus_Off state */ + + uint32_t RxESIflag; /*!< Specifies ESI flag of last received CAN FD message. + This parameter can be: + - 0 : Last received CAN FD message did not have its ESI flag set + - 1 : Last received CAN FD message had its ESI flag set */ + + uint32_t RxBRSflag; /*!< Specifies BRS flag of last received CAN FD message. + This parameter can be: + - 0 : Last received CAN FD message did not have its BRS flag set + - 1 : Last received CAN FD message had its BRS flag set */ + + uint32_t RxFDFflag; /*!< Specifies if CAN FD message (FDF flag set) has been received + since last protocol status. + This parameter can be: + - 0 : No CAN FD message received + - 1 : CAN FD message received */ + + uint32_t ProtocolException; /*!< Specifies the FDCAN module Protocol Exception status. + This parameter can be: + - 0 : No protocol exception event occurred since last read access + - 1 : Protocol exception event occurred */ + + uint32_t TDCvalue; /*!< Specifies the Transmitter Delay Compensation Value. + This parameter can be a number between 0 and 127 */ + +} FDCAN_ProtocolStatusTypeDef; + +/** + * @brief FDCAN Error Counters structure definition + */ +typedef struct +{ + uint32_t TxErrorCnt; /*!< Specifies the Transmit Error Counter Value. + This parameter can be a number between 0 and 255 */ + + uint32_t RxErrorCnt; /*!< Specifies the Receive Error Counter Value. + This parameter can be a number between 0 and 127 */ + + uint32_t RxErrorPassive; /*!< Specifies the Receive Error Passive status. + This parameter can be: + - 0 : The Receive Error Counter (RxErrorCnt) is below the error + passive level of 128 + - 1 : The Receive Error Counter (RxErrorCnt) has reached the error + passive level of 128 */ + + uint32_t ErrorLogging; /*!< Specifies the Transmit/Receive error logging counter value. + This parameter can be a number between 0 and 255. + This counter is incremented each time when a FDCAN protocol error causes + the TxErrorCnt or the RxErrorCnt to be incremented. The counter stops at 255; + the next increment of TxErrorCnt or RxErrorCnt sets interrupt flag + FDCAN_FLAG_ERROR_LOGGING_OVERFLOW */ + +} FDCAN_ErrorCountersTypeDef; + +/** + * @brief FDCAN Message RAM blocks + */ +typedef struct +{ + uint32_t StandardFilterSA; /*!< Specifies the Standard Filter List Start Address. + This parameter must be a 32-bit word address */ + + uint32_t ExtendedFilterSA; /*!< Specifies the Extended Filter List Start Address. + This parameter must be a 32-bit word address */ + + uint32_t RxFIFO0SA; /*!< Specifies the Rx FIFO 0 Start Address. + This parameter must be a 32-bit word address */ + + uint32_t RxFIFO1SA; /*!< Specifies the Rx FIFO 1 Start Address. + This parameter must be a 32-bit word address */ + + uint32_t TxEventFIFOSA; /*!< Specifies the Tx Event FIFO Start Address. + This parameter must be a 32-bit word address */ + + uint32_t TxFIFOQSA; /*!< Specifies the Tx FIFO/Queue Start Address. + This parameter must be a 32-bit word address */ + +} FDCAN_MsgRamAddressTypeDef; + +/** + * @brief FDCAN handle structure definition + */ +#if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1 +typedef struct __FDCAN_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */ +{ + FDCAN_GlobalTypeDef *Instance; /*!< Register base address */ + + FDCAN_InitTypeDef Init; /*!< FDCAN required parameters */ + + FDCAN_MsgRamAddressTypeDef msgRam; /*!< FDCAN Message RAM blocks */ + + uint32_t LatestTxFifoQRequest; /*!< FDCAN Tx buffer index + of latest Tx FIFO/Queue request */ + + __IO HAL_FDCAN_StateTypeDef State; /*!< FDCAN communication state */ + + HAL_LockTypeDef Lock; /*!< FDCAN locking object */ + + __IO uint32_t ErrorCode; /*!< FDCAN Error code */ + +#if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1 + void (* TxEventFifoCallback)(struct __FDCAN_HandleTypeDef *hfdcan, uint32_t TxEventFifoITs); /*!< FDCAN Tx Event Fifo callback */ + void (* RxFifo0Callback)(struct __FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs); /*!< FDCAN Rx Fifo 0 callback */ + void (* RxFifo1Callback)(struct __FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo1ITs); /*!< FDCAN Rx Fifo 1 callback */ + void (* TxFifoEmptyCallback)(struct __FDCAN_HandleTypeDef *hfdcan); /*!< FDCAN Tx Fifo Empty callback */ + void (* TxBufferCompleteCallback)(struct __FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes); /*!< FDCAN Tx Buffer complete callback */ + void (* TxBufferAbortCallback)(struct __FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes); /*!< FDCAN Tx Buffer abort callback */ + void (* HighPriorityMessageCallback)(struct __FDCAN_HandleTypeDef *hfdcan); /*!< FDCAN High priority message callback */ + void (* TimestampWraparoundCallback)(struct __FDCAN_HandleTypeDef *hfdcan); /*!< FDCAN Timestamp wraparound callback */ + void (* TimeoutOccurredCallback)(struct __FDCAN_HandleTypeDef *hfdcan); /*!< FDCAN Timeout occurred callback */ + void (* ErrorCallback)(struct __FDCAN_HandleTypeDef *hfdcan); /*!< FDCAN Error callback */ + void (* ErrorStatusCallback)(struct __FDCAN_HandleTypeDef *hfdcan, uint32_t ErrorStatusITs); /*!< FDCAN Error status callback */ + + void (* MspInitCallback)(struct __FDCAN_HandleTypeDef *hfdcan); /*!< FDCAN Msp Init callback */ + void (* MspDeInitCallback)(struct __FDCAN_HandleTypeDef *hfdcan); /*!< FDCAN Msp DeInit callback */ + +#endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */ + +} FDCAN_HandleTypeDef; + +#if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1 +/** + * @brief HAL FDCAN common Callback ID enumeration definition + */ +typedef enum +{ + HAL_FDCAN_TX_FIFO_EMPTY_CB_ID = 0x00U, /*!< FDCAN Tx Fifo Empty callback ID */ + HAL_FDCAN_HIGH_PRIO_MESSAGE_CB_ID = 0x01U, /*!< FDCAN High priority message callback ID */ + HAL_FDCAN_TIMESTAMP_WRAPAROUND_CB_ID = 0x02U, /*!< FDCAN Timestamp wraparound callback ID */ + HAL_FDCAN_TIMEOUT_OCCURRED_CB_ID = 0x03U, /*!< FDCAN Timeout occurred callback ID */ + HAL_FDCAN_ERROR_CALLBACK_CB_ID = 0x04U, /*!< FDCAN Error callback ID */ + + HAL_FDCAN_MSPINIT_CB_ID = 0x05U, /*!< FDCAN MspInit callback ID */ + HAL_FDCAN_MSPDEINIT_CB_ID = 0x06U, /*!< FDCAN MspDeInit callback ID */ + +} HAL_FDCAN_CallbackIDTypeDef; + +/** + * @brief HAL FDCAN Callback pointer definition + */ +typedef void (*pFDCAN_CallbackTypeDef)(FDCAN_HandleTypeDef *hfdcan); /*!< pointer to a common FDCAN callback function */ +typedef void (*pFDCAN_TxEventFifoCallbackTypeDef)(FDCAN_HandleTypeDef *hfdcan, uint32_t TxEventFifoITs); /*!< pointer to Tx event Fifo FDCAN callback function */ +typedef void (*pFDCAN_RxFifo0CallbackTypeDef)(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs); /*!< pointer to Rx Fifo 0 FDCAN callback function */ +typedef void (*pFDCAN_RxFifo1CallbackTypeDef)(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo1ITs); /*!< pointer to Rx Fifo 1 FDCAN callback function */ +typedef void (*pFDCAN_TxBufferCompleteCallbackTypeDef)(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes); /*!< pointer to Tx Buffer complete FDCAN callback function */ +typedef void (*pFDCAN_TxBufferAbortCallbackTypeDef)(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes); /*!< pointer to Tx Buffer abort FDCAN callback function */ +typedef void (*pFDCAN_ErrorStatusCallbackTypeDef)(FDCAN_HandleTypeDef *hfdcan, uint32_t ErrorStatusITs); /*!< pointer to Error Status callback function */ + +#endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup FDCAN_Exported_Constants FDCAN Exported Constants + * @{ + */ + +/** @defgroup HAL_FDCAN_Error_Code HAL FDCAN Error Code + * @{ + */ +#define HAL_FDCAN_ERROR_NONE ((uint32_t)0x00000000U) /*!< No error */ +#define HAL_FDCAN_ERROR_TIMEOUT ((uint32_t)0x00000001U) /*!< Timeout error */ +#define HAL_FDCAN_ERROR_NOT_INITIALIZED ((uint32_t)0x00000002U) /*!< Peripheral not initialized */ +#define HAL_FDCAN_ERROR_NOT_READY ((uint32_t)0x00000004U) /*!< Peripheral not ready */ +#define HAL_FDCAN_ERROR_NOT_STARTED ((uint32_t)0x00000008U) /*!< Peripheral not started */ +#define HAL_FDCAN_ERROR_NOT_SUPPORTED ((uint32_t)0x00000010U) /*!< Mode not supported */ +#define HAL_FDCAN_ERROR_PARAM ((uint32_t)0x00000020U) /*!< Parameter error */ +#define HAL_FDCAN_ERROR_PENDING ((uint32_t)0x00000040U) /*!< Pending operation */ +#define HAL_FDCAN_ERROR_RAM_ACCESS ((uint32_t)0x00000080U) /*!< Message RAM Access Failure */ +#define HAL_FDCAN_ERROR_FIFO_EMPTY ((uint32_t)0x00000100U) /*!< Put element in full FIFO */ +#define HAL_FDCAN_ERROR_FIFO_FULL ((uint32_t)0x00000200U) /*!< Get element from empty FIFO */ +#define HAL_FDCAN_ERROR_LOG_OVERFLOW FDCAN_IR_ELO /*!< Overflow of CAN Error Logging Counter */ +#define HAL_FDCAN_ERROR_RAM_WDG FDCAN_IR_WDI /*!< Message RAM Watchdog event occurred */ +#define HAL_FDCAN_ERROR_PROTOCOL_ARBT FDCAN_IR_PEA /*!< Protocol Error in Arbitration Phase (Nominal Bit Time is used) */ +#define HAL_FDCAN_ERROR_PROTOCOL_DATA FDCAN_IR_PED /*!< Protocol Error in Data Phase (Data Bit Time is used) */ +#define HAL_FDCAN_ERROR_RESERVED_AREA FDCAN_IR_ARA /*!< Access to Reserved Address */ + +#if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1 +#define HAL_FDCAN_ERROR_INVALID_CALLBACK ((uint32_t)0x00000100U) /*!< Invalid Callback error */ +#endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @defgroup FDCAN_frame_format FDCAN Frame Format + * @{ + */ +#define FDCAN_FRAME_CLASSIC ((uint32_t)0x00000000U) /*!< Classic mode */ +#define FDCAN_FRAME_FD_NO_BRS ((uint32_t)FDCAN_CCCR_FDOE) /*!< FD mode without BitRate Switching */ +#define FDCAN_FRAME_FD_BRS ((uint32_t)(FDCAN_CCCR_FDOE | FDCAN_CCCR_BRSE)) /*!< FD mode with BitRate Switching */ +/** + * @} + */ + +/** @defgroup FDCAN_operating_mode FDCAN Operating Mode + * @{ + */ +#define FDCAN_MODE_NORMAL ((uint32_t)0x00000000U) /*!< Normal mode */ +#define FDCAN_MODE_RESTRICTED_OPERATION ((uint32_t)0x00000001U) /*!< Restricted Operation mode */ +#define FDCAN_MODE_BUS_MONITORING ((uint32_t)0x00000002U) /*!< Bus Monitoring mode */ +#define FDCAN_MODE_INTERNAL_LOOPBACK ((uint32_t)0x00000003U) /*!< Internal LoopBack mode */ +#define FDCAN_MODE_EXTERNAL_LOOPBACK ((uint32_t)0x00000004U) /*!< External LoopBack mode */ +/** + * @} + */ + +/** @defgroup FDCAN_clock_divider FDCAN Clock Divider + * @{ + */ +#define FDCAN_CLOCK_DIV1 ((uint32_t)0x00000000U) /*!< Divide kernel clock by 1 */ +#define FDCAN_CLOCK_DIV2 ((uint32_t)0x00000001U) /*!< Divide kernel clock by 2 */ +#define FDCAN_CLOCK_DIV4 ((uint32_t)0x00000002U) /*!< Divide kernel clock by 4 */ +#define FDCAN_CLOCK_DIV6 ((uint32_t)0x00000003U) /*!< Divide kernel clock by 6 */ +#define FDCAN_CLOCK_DIV8 ((uint32_t)0x00000004U) /*!< Divide kernel clock by 8 */ +#define FDCAN_CLOCK_DIV10 ((uint32_t)0x00000005U) /*!< Divide kernel clock by 10 */ +#define FDCAN_CLOCK_DIV12 ((uint32_t)0x00000006U) /*!< Divide kernel clock by 12 */ +#define FDCAN_CLOCK_DIV14 ((uint32_t)0x00000007U) /*!< Divide kernel clock by 14 */ +#define FDCAN_CLOCK_DIV16 ((uint32_t)0x00000008U) /*!< Divide kernel clock by 16 */ +#define FDCAN_CLOCK_DIV18 ((uint32_t)0x00000009U) /*!< Divide kernel clock by 18 */ +#define FDCAN_CLOCK_DIV20 ((uint32_t)0x0000000AU) /*!< Divide kernel clock by 20 */ +#define FDCAN_CLOCK_DIV22 ((uint32_t)0x0000000BU) /*!< Divide kernel clock by 22 */ +#define FDCAN_CLOCK_DIV24 ((uint32_t)0x0000000CU) /*!< Divide kernel clock by 24 */ +#define FDCAN_CLOCK_DIV26 ((uint32_t)0x0000000DU) /*!< Divide kernel clock by 26 */ +#define FDCAN_CLOCK_DIV28 ((uint32_t)0x0000000EU) /*!< Divide kernel clock by 28 */ +#define FDCAN_CLOCK_DIV30 ((uint32_t)0x0000000FU) /*!< Divide kernel clock by 30 */ +/** + * @} + */ + +/** @defgroup FDCAN_txFifoQueue_Mode FDCAN Tx FIFO/Queue Mode + * @{ + */ +#define FDCAN_TX_FIFO_OPERATION ((uint32_t)0x00000000U) /*!< FIFO mode */ +#define FDCAN_TX_QUEUE_OPERATION ((uint32_t)FDCAN_TXBC_TFQM) /*!< Queue mode */ +/** + * @} + */ + +/** @defgroup FDCAN_id_type FDCAN ID Type + * @{ + */ +#define FDCAN_STANDARD_ID ((uint32_t)0x00000000U) /*!< Standard ID element */ +#define FDCAN_EXTENDED_ID ((uint32_t)0x40000000U) /*!< Extended ID element */ +/** + * @} + */ + +/** @defgroup FDCAN_frame_type FDCAN Frame Type + * @{ + */ +#define FDCAN_DATA_FRAME ((uint32_t)0x00000000U) /*!< Data frame */ +#define FDCAN_REMOTE_FRAME ((uint32_t)0x20000000U) /*!< Remote frame */ +/** + * @} + */ + +/** @defgroup FDCAN_data_length_code FDCAN Data Length Code + * @{ + */ +#define FDCAN_DLC_BYTES_0 ((uint32_t)0x00000000U) /*!< 0 bytes data field */ +#define FDCAN_DLC_BYTES_1 ((uint32_t)0x00000001U) /*!< 1 bytes data field */ +#define FDCAN_DLC_BYTES_2 ((uint32_t)0x00000002U) /*!< 2 bytes data field */ +#define FDCAN_DLC_BYTES_3 ((uint32_t)0x00000003U) /*!< 3 bytes data field */ +#define FDCAN_DLC_BYTES_4 ((uint32_t)0x00000004U) /*!< 4 bytes data field */ +#define FDCAN_DLC_BYTES_5 ((uint32_t)0x00000005U) /*!< 5 bytes data field */ +#define FDCAN_DLC_BYTES_6 ((uint32_t)0x00000006U) /*!< 6 bytes data field */ +#define FDCAN_DLC_BYTES_7 ((uint32_t)0x00000007U) /*!< 7 bytes data field */ +#define FDCAN_DLC_BYTES_8 ((uint32_t)0x00000008U) /*!< 8 bytes data field */ +#define FDCAN_DLC_BYTES_12 ((uint32_t)0x00000009U) /*!< 12 bytes data field */ +#define FDCAN_DLC_BYTES_16 ((uint32_t)0x0000000AU) /*!< 16 bytes data field */ +#define FDCAN_DLC_BYTES_20 ((uint32_t)0x0000000BU) /*!< 20 bytes data field */ +#define FDCAN_DLC_BYTES_24 ((uint32_t)0x0000000CU) /*!< 24 bytes data field */ +#define FDCAN_DLC_BYTES_32 ((uint32_t)0x0000000DU) /*!< 32 bytes data field */ +#define FDCAN_DLC_BYTES_48 ((uint32_t)0x0000000EU) /*!< 48 bytes data field */ +#define FDCAN_DLC_BYTES_64 ((uint32_t)0x0000000FU) /*!< 64 bytes data field */ +/** + * @} + */ + +/** @defgroup FDCAN_error_state_indicator FDCAN Error State Indicator + * @{ + */ +#define FDCAN_ESI_ACTIVE ((uint32_t)0x00000000U) /*!< Transmitting node is error active */ +#define FDCAN_ESI_PASSIVE ((uint32_t)0x80000000U) /*!< Transmitting node is error passive */ +/** + * @} + */ + +/** @defgroup FDCAN_bit_rate_switching FDCAN Bit Rate Switching + * @{ + */ +#define FDCAN_BRS_OFF ((uint32_t)0x00000000U) /*!< FDCAN frames transmitted/received without bit rate switching */ +#define FDCAN_BRS_ON ((uint32_t)0x00100000U) /*!< FDCAN frames transmitted/received with bit rate switching */ +/** + * @} + */ + +/** @defgroup FDCAN_format FDCAN format + * @{ + */ +#define FDCAN_CLASSIC_CAN ((uint32_t)0x00000000U) /*!< Frame transmitted/received in Classic CAN format */ +#define FDCAN_FD_CAN ((uint32_t)0x00200000U) /*!< Frame transmitted/received in FDCAN format */ +/** + * @} + */ + +/** @defgroup FDCAN_EFC FDCAN Event FIFO control + * @{ + */ +#define FDCAN_NO_TX_EVENTS ((uint32_t)0x00000000U) /*!< Do not store Tx events */ +#define FDCAN_STORE_TX_EVENTS ((uint32_t)0x00800000U) /*!< Store Tx events */ +/** + * @} + */ + +/** @defgroup FDCAN_filter_type FDCAN Filter Type + * @{ + */ +#define FDCAN_FILTER_RANGE ((uint32_t)0x00000000U) /*!< Range filter from FilterID1 to FilterID2 */ +#define FDCAN_FILTER_DUAL ((uint32_t)0x00000001U) /*!< Dual ID filter for FilterID1 or FilterID2 */ +#define FDCAN_FILTER_MASK ((uint32_t)0x00000002U) /*!< Classic filter: FilterID1 = filter, FilterID2 = mask */ +#define FDCAN_FILTER_RANGE_NO_EIDM ((uint32_t)0x00000003U) /*!< Range filter from FilterID1 to FilterID2, EIDM mask not applied */ +/** + * @} + */ + +/** @defgroup FDCAN_filter_config FDCAN Filter Configuration + * @{ + */ +#define FDCAN_FILTER_DISABLE ((uint32_t)0x00000000U) /*!< Disable filter element */ +#define FDCAN_FILTER_TO_RXFIFO0 ((uint32_t)0x00000001U) /*!< Store in Rx FIFO 0 if filter matches */ +#define FDCAN_FILTER_TO_RXFIFO1 ((uint32_t)0x00000002U) /*!< Store in Rx FIFO 1 if filter matches */ +#define FDCAN_FILTER_REJECT ((uint32_t)0x00000003U) /*!< Reject ID if filter matches */ +#define FDCAN_FILTER_HP ((uint32_t)0x00000004U) /*!< Set high priority if filter matches */ +#define FDCAN_FILTER_TO_RXFIFO0_HP ((uint32_t)0x00000005U) /*!< Set high priority and store in FIFO 0 if filter matches */ +#define FDCAN_FILTER_TO_RXFIFO1_HP ((uint32_t)0x00000006U) /*!< Set high priority and store in FIFO 1 if filter matches */ +/** + * @} + */ + +/** @defgroup FDCAN_Tx_location FDCAN Tx Location + * @{ + */ +#define FDCAN_TX_BUFFER0 ((uint32_t)0x00000001U) /*!< Add message to Tx Buffer 0 */ +#define FDCAN_TX_BUFFER1 ((uint32_t)0x00000002U) /*!< Add message to Tx Buffer 1 */ +#define FDCAN_TX_BUFFER2 ((uint32_t)0x00000004U) /*!< Add message to Tx Buffer 2 */ +/** + * @} + */ + +/** @defgroup FDCAN_Rx_location FDCAN Rx Location + * @{ + */ +#define FDCAN_RX_FIFO0 ((uint32_t)0x00000040U) /*!< Get received message from Rx FIFO 0 */ +#define FDCAN_RX_FIFO1 ((uint32_t)0x00000041U) /*!< Get received message from Rx FIFO 1 */ +/** + * @} + */ + +/** @defgroup FDCAN_event_type FDCAN Event Type + * @{ + */ +#define FDCAN_TX_EVENT ((uint32_t)0x00400000U) /*!< Tx event */ +#define FDCAN_TX_IN_SPITE_OF_ABORT ((uint32_t)0x00800000U) /*!< Transmission in spite of cancellation */ +/** + * @} + */ + +/** @defgroup FDCAN_hp_msg_storage FDCAN High Priority Message Storage + * @{ + */ +#define FDCAN_HP_STORAGE_NO_FIFO ((uint32_t)0x00000000U) /*!< No FIFO selected */ +#define FDCAN_HP_STORAGE_MSG_LOST ((uint32_t)0x00000040U) /*!< FIFO message lost */ +#define FDCAN_HP_STORAGE_RXFIFO0 ((uint32_t)0x00000080U) /*!< Message stored in FIFO 0 */ +#define FDCAN_HP_STORAGE_RXFIFO1 ((uint32_t)0x000000C0U) /*!< Message stored in FIFO 1 */ +/** + * @} + */ + +/** @defgroup FDCAN_protocol_error_code FDCAN protocol error code + * @{ + */ +#define FDCAN_PROTOCOL_ERROR_NONE ((uint32_t)0x00000000U) /*!< No error occurred */ +#define FDCAN_PROTOCOL_ERROR_STUFF ((uint32_t)0x00000001U) /*!< Stuff error */ +#define FDCAN_PROTOCOL_ERROR_FORM ((uint32_t)0x00000002U) /*!< Form error */ +#define FDCAN_PROTOCOL_ERROR_ACK ((uint32_t)0x00000003U) /*!< Acknowledge error */ +#define FDCAN_PROTOCOL_ERROR_BIT1 ((uint32_t)0x00000004U) /*!< Bit 1 (recessive) error */ +#define FDCAN_PROTOCOL_ERROR_BIT0 ((uint32_t)0x00000005U) /*!< Bit 0 (dominant) error */ +#define FDCAN_PROTOCOL_ERROR_CRC ((uint32_t)0x00000006U) /*!< CRC check sum error */ +#define FDCAN_PROTOCOL_ERROR_NO_CHANGE ((uint32_t)0x00000007U) /*!< No change since last read */ +/** + * @} + */ + +/** @defgroup FDCAN_communication_state FDCAN communication state + * @{ + */ +#define FDCAN_COM_STATE_SYNC ((uint32_t)0x00000000U) /*!< Node is synchronizing on CAN communication */ +#define FDCAN_COM_STATE_IDLE ((uint32_t)0x00000008U) /*!< Node is neither receiver nor transmitter */ +#define FDCAN_COM_STATE_RX ((uint32_t)0x00000010U) /*!< Node is operating as receiver */ +#define FDCAN_COM_STATE_TX ((uint32_t)0x00000018U) /*!< Node is operating as transmitter */ +/** + * @} + */ + +/** @defgroup FDCAN_Rx_FIFO_operation_mode FDCAN FIFO operation mode + * @{ + */ +#define FDCAN_RX_FIFO_BLOCKING ((uint32_t)0x00000000U) /*!< Rx FIFO blocking mode */ +#define FDCAN_RX_FIFO_OVERWRITE ((uint32_t)0x00000001U) /*!< Rx FIFO overwrite mode */ +/** + * @} + */ + +/** @defgroup FDCAN_Non_Matching_Frames FDCAN non-matching frames + * @{ + */ +#define FDCAN_ACCEPT_IN_RX_FIFO0 ((uint32_t)0x00000000U) /*!< Accept in Rx FIFO 0 */ +#define FDCAN_ACCEPT_IN_RX_FIFO1 ((uint32_t)0x00000001U) /*!< Accept in Rx FIFO 1 */ +#define FDCAN_REJECT ((uint32_t)0x00000002U) /*!< Reject */ +/** + * @} + */ + +/** @defgroup FDCAN_Reject_Remote_Frames FDCAN reject remote frames + * @{ + */ +#define FDCAN_FILTER_REMOTE ((uint32_t)0x00000000U) /*!< Filter remote frames */ +#define FDCAN_REJECT_REMOTE ((uint32_t)0x00000001U) /*!< Reject all remote frames */ +/** + * @} + */ + +/** @defgroup FDCAN_Interrupt_Line FDCAN interrupt line + * @{ + */ +#define FDCAN_INTERRUPT_LINE0 ((uint32_t)0x00000001U) /*!< Interrupt Line 0 */ +#define FDCAN_INTERRUPT_LINE1 ((uint32_t)0x00000002U) /*!< Interrupt Line 1 */ +/** + * @} + */ + +/** @defgroup FDCAN_Timestamp FDCAN timestamp + * @{ + */ +#define FDCAN_TIMESTAMP_INTERNAL ((uint32_t)0x00000001U) /*!< Timestamp counter value incremented according to TCP */ +#define FDCAN_TIMESTAMP_EXTERNAL ((uint32_t)0x00000002U) /*!< External timestamp counter value used */ +/** + * @} + */ + +/** @defgroup FDCAN_Timestamp_Prescaler FDCAN timestamp prescaler + * @{ + */ +#define FDCAN_TIMESTAMP_PRESC_1 ((uint32_t)0x00000000U) /*!< Timestamp counter time unit in equal to CAN bit time */ +#define FDCAN_TIMESTAMP_PRESC_2 ((uint32_t)0x00010000U) /*!< Timestamp counter time unit in equal to CAN bit time multiplied by 2 */ +#define FDCAN_TIMESTAMP_PRESC_3 ((uint32_t)0x00020000U) /*!< Timestamp counter time unit in equal to CAN bit time multiplied by 3 */ +#define FDCAN_TIMESTAMP_PRESC_4 ((uint32_t)0x00030000U) /*!< Timestamp counter time unit in equal to CAN bit time multiplied by 4 */ +#define FDCAN_TIMESTAMP_PRESC_5 ((uint32_t)0x00040000U) /*!< Timestamp counter time unit in equal to CAN bit time multiplied by 5 */ +#define FDCAN_TIMESTAMP_PRESC_6 ((uint32_t)0x00050000U) /*!< Timestamp counter time unit in equal to CAN bit time multiplied by 6 */ +#define FDCAN_TIMESTAMP_PRESC_7 ((uint32_t)0x00060000U) /*!< Timestamp counter time unit in equal to CAN bit time multiplied by 7 */ +#define FDCAN_TIMESTAMP_PRESC_8 ((uint32_t)0x00070000U) /*!< Timestamp counter time unit in equal to CAN bit time multiplied by 8 */ +#define FDCAN_TIMESTAMP_PRESC_9 ((uint32_t)0x00080000U) /*!< Timestamp counter time unit in equal to CAN bit time multiplied by 9 */ +#define FDCAN_TIMESTAMP_PRESC_10 ((uint32_t)0x00090000U) /*!< Timestamp counter time unit in equal to CAN bit time multiplied by 10 */ +#define FDCAN_TIMESTAMP_PRESC_11 ((uint32_t)0x000A0000U) /*!< Timestamp counter time unit in equal to CAN bit time multiplied by 11 */ +#define FDCAN_TIMESTAMP_PRESC_12 ((uint32_t)0x000B0000U) /*!< Timestamp counter time unit in equal to CAN bit time multiplied by 12 */ +#define FDCAN_TIMESTAMP_PRESC_13 ((uint32_t)0x000C0000U) /*!< Timestamp counter time unit in equal to CAN bit time multiplied by 13 */ +#define FDCAN_TIMESTAMP_PRESC_14 ((uint32_t)0x000D0000U) /*!< Timestamp counter time unit in equal to CAN bit time multiplied by 14 */ +#define FDCAN_TIMESTAMP_PRESC_15 ((uint32_t)0x000E0000U) /*!< Timestamp counter time unit in equal to CAN bit time multiplied by 15 */ +#define FDCAN_TIMESTAMP_PRESC_16 ((uint32_t)0x000F0000U) /*!< Timestamp counter time unit in equal to CAN bit time multiplied by 16 */ +/** + * @} + */ + +/** @defgroup FDCAN_Timeout_Operation FDCAN timeout operation + * @{ + */ +#define FDCAN_TIMEOUT_CONTINUOUS ((uint32_t)0x00000000U) /*!< Timeout continuous operation */ +#define FDCAN_TIMEOUT_TX_EVENT_FIFO ((uint32_t)0x00000002U) /*!< Timeout controlled by Tx Event FIFO */ +#define FDCAN_TIMEOUT_RX_FIFO0 ((uint32_t)0x00000004U) /*!< Timeout controlled by Rx FIFO 0 */ +#define FDCAN_TIMEOUT_RX_FIFO1 ((uint32_t)0x00000006U) /*!< Timeout controlled by Rx FIFO 1 */ +/** + * @} + */ + +/** @defgroup Interrupt_Masks Interrupt masks + * @{ + */ +#define FDCAN_IR_MASK ((uint32_t)0x00FFFFFFU) /*!< FDCAN interrupts mask */ +#define FDCAN_ILS_MASK ((uint32_t)0x0000007FU) /*!< FDCAN interrupts group mask */ +/** + * @} + */ + +/** @defgroup FDCAN_flags FDCAN Flags + * @{ + */ +#define FDCAN_FLAG_TX_COMPLETE FDCAN_IR_TC /*!< Transmission Completed */ +#define FDCAN_FLAG_TX_ABORT_COMPLETE FDCAN_IR_TCF /*!< Transmission Cancellation Finished */ +#define FDCAN_FLAG_TX_FIFO_EMPTY FDCAN_IR_TFE /*!< Tx FIFO Empty */ +#define FDCAN_FLAG_RX_HIGH_PRIORITY_MSG FDCAN_IR_HPM /*!< High priority message received */ +#define FDCAN_FLAG_TX_EVT_FIFO_ELT_LOST FDCAN_IR_TEFL /*!< Tx Event FIFO element lost */ +#define FDCAN_FLAG_TX_EVT_FIFO_FULL FDCAN_IR_TEFF /*!< Tx Event FIFO full */ +#define FDCAN_FLAG_TX_EVT_FIFO_NEW_DATA FDCAN_IR_TEFN /*!< Tx Handler wrote Tx Event FIFO element */ +#define FDCAN_FLAG_RX_FIFO0_MESSAGE_LOST FDCAN_IR_RF0L /*!< Rx FIFO 0 message lost */ +#define FDCAN_FLAG_RX_FIFO0_FULL FDCAN_IR_RF0F /*!< Rx FIFO 0 full */ +#define FDCAN_FLAG_RX_FIFO0_NEW_MESSAGE FDCAN_IR_RF0N /*!< New message written to Rx FIFO 0 */ +#define FDCAN_FLAG_RX_FIFO1_MESSAGE_LOST FDCAN_IR_RF1L /*!< Rx FIFO 1 message lost */ +#define FDCAN_FLAG_RX_FIFO1_FULL FDCAN_IR_RF1F /*!< Rx FIFO 1 full */ +#define FDCAN_FLAG_RX_FIFO1_NEW_MESSAGE FDCAN_IR_RF1N /*!< New message written to Rx FIFO 1 */ +#define FDCAN_FLAG_RAM_ACCESS_FAILURE FDCAN_IR_MRAF /*!< Message RAM access failure occurred */ +#define FDCAN_FLAG_ERROR_LOGGING_OVERFLOW FDCAN_IR_ELO /*!< Overflow of FDCAN Error Logging Counter occurred */ +#define FDCAN_FLAG_ERROR_PASSIVE FDCAN_IR_EP /*!< Error_Passive status changed */ +#define FDCAN_FLAG_ERROR_WARNING FDCAN_IR_EW /*!< Error_Warning status changed */ +#define FDCAN_FLAG_BUS_OFF FDCAN_IR_BO /*!< Bus_Off status changed */ +#define FDCAN_FLAG_RAM_WATCHDOG FDCAN_IR_WDI /*!< Message RAM Watchdog event due to missing READY */ +#define FDCAN_FLAG_ARB_PROTOCOL_ERROR FDCAN_IR_PEA /*!< Protocol error in arbitration phase detected */ +#define FDCAN_FLAG_DATA_PROTOCOL_ERROR FDCAN_IR_PED /*!< Protocol error in data phase detected */ +#define FDCAN_FLAG_RESERVED_ADDRESS_ACCESS FDCAN_IR_ARA /*!< Access to reserved address occurred */ +#define FDCAN_FLAG_TIMESTAMP_WRAPAROUND FDCAN_IR_TSW /*!< Timestamp counter wrapped around */ +#define FDCAN_FLAG_TIMEOUT_OCCURRED FDCAN_IR_TOO /*!< Timeout reached */ +/** + * @} + */ + +/** @defgroup FDCAN_Interrupts FDCAN Interrupts + * @{ + */ + +/** @defgroup FDCAN_Tx_Interrupts FDCAN Tx Interrupts + * @{ + */ +#define FDCAN_IT_TX_COMPLETE FDCAN_IE_TCE /*!< Transmission Completed */ +#define FDCAN_IT_TX_ABORT_COMPLETE FDCAN_IE_TCFE /*!< Transmission Cancellation Finished */ +#define FDCAN_IT_TX_FIFO_EMPTY FDCAN_IE_TFEE /*!< Tx FIFO Empty */ +/** + * @} + */ + +/** @defgroup FDCAN_Rx_Interrupts FDCAN Rx Interrupts + * @{ + */ +#define FDCAN_IT_RX_HIGH_PRIORITY_MSG FDCAN_IE_HPME /*!< High priority message received */ +/** + * @} + */ + +/** @defgroup FDCAN_Counter_Interrupts FDCAN Counter Interrupts + * @{ + */ +#define FDCAN_IT_TIMESTAMP_WRAPAROUND FDCAN_IE_TSWE /*!< Timestamp counter wrapped around */ +#define FDCAN_IT_TIMEOUT_OCCURRED FDCAN_IE_TOOE /*!< Timeout reached */ +/** + * @} + */ + +/** @defgroup FDCAN_Tx_Event_Fifo_Interrupts FDCAN Tx Event FIFO Interrupts + * @{ + */ +#define FDCAN_IT_TX_EVT_FIFO_ELT_LOST FDCAN_IE_TEFLE /*!< Tx Event FIFO element lost */ +#define FDCAN_IT_TX_EVT_FIFO_FULL FDCAN_IE_TEFFE /*!< Tx Event FIFO full */ +#define FDCAN_IT_TX_EVT_FIFO_NEW_DATA FDCAN_IE_TEFNE /*!< Tx Handler wrote Tx Event FIFO element */ +/** + * @} + */ + +/** @defgroup FDCAN_Rx_Fifo0_Interrupts FDCAN Rx FIFO 0 Interrupts + * @{ + */ +#define FDCAN_IT_RX_FIFO0_MESSAGE_LOST FDCAN_IE_RF0LE /*!< Rx FIFO 0 message lost */ +#define FDCAN_IT_RX_FIFO0_FULL FDCAN_IE_RF0FE /*!< Rx FIFO 0 full */ +#define FDCAN_IT_RX_FIFO0_NEW_MESSAGE FDCAN_IE_RF0NE /*!< New message written to Rx FIFO 0 */ +/** + * @} + */ + +/** @defgroup FDCAN_Rx_Fifo1_Interrupts FDCAN Rx FIFO 1 Interrupts + * @{ + */ +#define FDCAN_IT_RX_FIFO1_MESSAGE_LOST FDCAN_IE_RF1LE /*!< Rx FIFO 1 message lost */ +#define FDCAN_IT_RX_FIFO1_FULL FDCAN_IE_RF1FE /*!< Rx FIFO 1 full */ +#define FDCAN_IT_RX_FIFO1_NEW_MESSAGE FDCAN_IE_RF1NE /*!< New message written to Rx FIFO 1 */ +/** + * @} + */ + +/** @defgroup FDCAN_Error_Interrupts FDCAN Error Interrupts + * @{ + */ +#define FDCAN_IT_RAM_ACCESS_FAILURE FDCAN_IE_MRAFE /*!< Message RAM access failure occurred */ +#define FDCAN_IT_ERROR_LOGGING_OVERFLOW FDCAN_IE_ELOE /*!< Overflow of FDCAN Error Logging Counter occurred */ +#define FDCAN_IT_RAM_WATCHDOG FDCAN_IE_WDIE /*!< Message RAM Watchdog event due to missing READY */ +#define FDCAN_IT_ARB_PROTOCOL_ERROR FDCAN_IE_PEAE /*!< Protocol error in arbitration phase detected */ +#define FDCAN_IT_DATA_PROTOCOL_ERROR FDCAN_IE_PEDE /*!< Protocol error in data phase detected */ +#define FDCAN_IT_RESERVED_ADDRESS_ACCESS FDCAN_IE_ARAE /*!< Access to reserved address occurred */ +/** + * @} + */ + +/** @defgroup FDCAN_Error_Status_Interrupts FDCAN Error Status Interrupts + * @{ + */ +#define FDCAN_IT_ERROR_PASSIVE FDCAN_IE_EPE /*!< Error_Passive status changed */ +#define FDCAN_IT_ERROR_WARNING FDCAN_IE_EWE /*!< Error_Warning status changed */ +#define FDCAN_IT_BUS_OFF FDCAN_IE_BOE /*!< Bus_Off status changed */ +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup FDCAN_Interrupts_List FDCAN Interrupts List + * @{ + */ +#define FDCAN_IT_LIST_RX_FIFO0 (FDCAN_IT_RX_FIFO0_MESSAGE_LOST | \ + FDCAN_IT_RX_FIFO0_FULL | \ + FDCAN_IT_RX_FIFO0_NEW_MESSAGE) /*!< RX FIFO 0 Interrupts List */ +#define FDCAN_IT_LIST_RX_FIFO1 (FDCAN_IT_RX_FIFO1_MESSAGE_LOST | \ + FDCAN_IT_RX_FIFO1_FULL | \ + FDCAN_IT_RX_FIFO1_NEW_MESSAGE) /*!< RX FIFO 1 Interrupts List */ +#define FDCAN_IT_LIST_SMSG (FDCAN_IT_TX_ABORT_COMPLETE | \ + FDCAN_IT_TX_COMPLETE | \ + FDCAN_IT_RX_HIGH_PRIORITY_MSG) /*!< Status Message Interrupts List */ +#define FDCAN_IT_LIST_TX_FIFO_ERROR (FDCAN_IT_TX_EVT_FIFO_ELT_LOST | \ + FDCAN_IT_TX_EVT_FIFO_FULL | \ + FDCAN_IT_TX_EVT_FIFO_NEW_DATA | \ + FDCAN_IT_TX_FIFO_EMPTY) /*!< TX FIFO Error Interrupts List */ +#define FDCAN_IT_LIST_MISC (FDCAN_IT_TIMEOUT_OCCURRED | \ + FDCAN_IT_RAM_ACCESS_FAILURE | \ + FDCAN_IT_TIMESTAMP_WRAPAROUND) /*!< Misc. Interrupts List */ +#define FDCAN_IT_LIST_BIT_LINE_ERROR (FDCAN_IT_ERROR_PASSIVE | \ + FDCAN_IT_ERROR_LOGGING_OVERFLOW) /*!< Bit and Line Error Interrupts List */ +#define FDCAN_IT_LIST_PROTOCOL_ERROR (FDCAN_IT_RESERVED_ADDRESS_ACCESS | \ + FDCAN_IT_DATA_PROTOCOL_ERROR | \ + FDCAN_IT_ARB_PROTOCOL_ERROR | \ + FDCAN_IT_RAM_WATCHDOG | \ + FDCAN_IT_BUS_OFF | \ + FDCAN_IT_ERROR_WARNING) /*!< Protocol Error Interrupts List */ +/** + * @} + */ + +/** @defgroup FDCAN_Interrupts_Group FDCAN Interrupts Group + * @{ + */ +#define FDCAN_IT_GROUP_RX_FIFO0 FDCAN_ILS_RXFIFO0 /*!< RX FIFO 0 Interrupts Group: + RF0LL: Rx FIFO 0 Message Lost + RF0FL: Rx FIFO 0 is Full + RF0NL: Rx FIFO 0 Has New Message */ +#define FDCAN_IT_GROUP_RX_FIFO1 FDCAN_ILS_RXFIFO1 /*!< RX FIFO 1 Interrupts Group: + RF1LL: Rx FIFO 1 Message Lost + RF1FL: Rx FIFO 1 is Full + RF1NL: Rx FIFO 1 Has New Message */ +#define FDCAN_IT_GROUP_SMSG FDCAN_ILS_SMSG /*!< Status Message Interrupts Group: + TCFL: Transmission Cancellation Finished + TCL: Transmission Completed + HPML: High Priority Message */ +#define FDCAN_IT_GROUP_TX_FIFO_ERROR FDCAN_ILS_TFERR /*!< TX FIFO Error Interrupts Group: + TEFLL: Tx Event FIFO Element Lost + TEFFL: Tx Event FIFO Full + TEFNL: Tx Event FIFO New Entry + TFEL: Tx FIFO Empty Interrupt Line */ +#define FDCAN_IT_GROUP_MISC FDCAN_ILS_MISC /*!< Misc. Interrupts Group: + TOOL: Timeout Occurred + MRAFL: Message RAM Access Failure + TSWL: Timestamp Wraparound */ +#define FDCAN_IT_GROUP_BIT_LINE_ERROR FDCAN_ILS_BERR /*!< Bit and Line Error Interrupts Group: + EPL: Error Passive + ELOL: Error Logging Overflow */ +#define FDCAN_IT_GROUP_PROTOCOL_ERROR FDCAN_ILS_PERR /*!< Protocol Error Group: + ARAL: Access to Reserved Address Line + PEDL: Protocol Error in Data Phase Line + PEAL: Protocol Error in Arbitration Phase Line + WDIL: Watchdog Interrupt Line + BOL: Bus_Off Status + EWL: Warning Status */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup FDCAN_Exported_Macros FDCAN Exported Macros + * @{ + */ + +/** @brief Reset FDCAN handle state. + * @param __HANDLE__ FDCAN handle. + * @retval None + */ +#if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1 +#define __HAL_FDCAN_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->State = HAL_FDCAN_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_FDCAN_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_FDCAN_STATE_RESET) +#endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */ + +/** + * @brief Enable the specified FDCAN interrupts. + * @param __HANDLE__ FDCAN handle. + * @param __INTERRUPT__ FDCAN interrupt. + * This parameter can be any combination of @arg FDCAN_Interrupts + * @retval None + */ +#define __HAL_FDCAN_ENABLE_IT(__HANDLE__, __INTERRUPT__) \ + (__HANDLE__)->Instance->IE |= (__INTERRUPT__) + +/** + * @brief Disable the specified FDCAN interrupts. + * @param __HANDLE__ FDCAN handle. + * @param __INTERRUPT__ FDCAN interrupt. + * This parameter can be any combination of @arg FDCAN_Interrupts + * @retval None + */ +#define __HAL_FDCAN_DISABLE_IT(__HANDLE__, __INTERRUPT__) \ + ((__HANDLE__)->Instance->IE) &= ~(__INTERRUPT__) + +/** + * @brief Check whether the specified FDCAN interrupt is set or not. + * @param __HANDLE__ FDCAN handle. + * @param __INTERRUPT__ FDCAN interrupt. + * This parameter can be one of @arg FDCAN_Interrupts + * @retval ITStatus + */ +#define __HAL_FDCAN_GET_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IR & (__INTERRUPT__)) + +/** + * @brief Clear the specified FDCAN interrupts. + * @param __HANDLE__ FDCAN handle. + * @param __INTERRUPT__ specifies the interrupts to clear. + * This parameter can be any combination of @arg FDCAN_Interrupts + * @retval None + */ +#define __HAL_FDCAN_CLEAR_IT(__HANDLE__, __INTERRUPT__) \ + ((__HANDLE__)->Instance->IR) = (__INTERRUPT__) + +/** + * @brief Check whether the specified FDCAN flag is set or not. + * @param __HANDLE__ FDCAN handle. + * @param __FLAG__ FDCAN flag. + * This parameter can be one of @arg FDCAN_flags + * @retval FlagStatus + */ +#define __HAL_FDCAN_GET_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->IR & (__FLAG__)) + +/** + * @brief Clear the specified FDCAN flags. + * @param __HANDLE__ FDCAN handle. + * @param __FLAG__ specifies the flags to clear. + * This parameter can be any combination of @arg FDCAN_flags + * @retval None + */ +#define __HAL_FDCAN_CLEAR_FLAG(__HANDLE__, __FLAG__) \ + ((__HANDLE__)->Instance->IR) = (__FLAG__) + +/** @brief Check if the specified FDCAN interrupt source is enabled or disabled. + * @param __HANDLE__ FDCAN handle. + * @param __INTERRUPT__ specifies the FDCAN interrupt source to check. + * This parameter can be a value of @arg FDCAN_Interrupts + * @retval ITStatus + */ +#define __HAL_FDCAN_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IE & (__INTERRUPT__)) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup FDCAN_Exported_Functions + * @{ + */ + +/** @addtogroup FDCAN_Exported_Functions_Group1 + * @{ + */ +/* Initialization and de-initialization functions *****************************/ +HAL_StatusTypeDef HAL_FDCAN_Init(FDCAN_HandleTypeDef *hfdcan); +HAL_StatusTypeDef HAL_FDCAN_DeInit(FDCAN_HandleTypeDef *hfdcan); +void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef *hfdcan); +void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef *hfdcan); +HAL_StatusTypeDef HAL_FDCAN_EnterPowerDownMode(FDCAN_HandleTypeDef *hfdcan); +HAL_StatusTypeDef HAL_FDCAN_ExitPowerDownMode(FDCAN_HandleTypeDef *hfdcan); + +#if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1 +/* Callbacks Register/UnRegister functions ***********************************/ +HAL_StatusTypeDef HAL_FDCAN_RegisterCallback(FDCAN_HandleTypeDef *hfdcan, HAL_FDCAN_CallbackIDTypeDef CallbackID, + pFDCAN_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_FDCAN_UnRegisterCallback(FDCAN_HandleTypeDef *hfdcan, HAL_FDCAN_CallbackIDTypeDef CallbackID); +HAL_StatusTypeDef HAL_FDCAN_RegisterTxEventFifoCallback(FDCAN_HandleTypeDef *hfdcan, + pFDCAN_TxEventFifoCallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_FDCAN_UnRegisterTxEventFifoCallback(FDCAN_HandleTypeDef *hfdcan); +HAL_StatusTypeDef HAL_FDCAN_RegisterRxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, + pFDCAN_RxFifo0CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_FDCAN_UnRegisterRxFifo0Callback(FDCAN_HandleTypeDef *hfdcan); +HAL_StatusTypeDef HAL_FDCAN_RegisterRxFifo1Callback(FDCAN_HandleTypeDef *hfdcan, + pFDCAN_RxFifo1CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_FDCAN_UnRegisterRxFifo1Callback(FDCAN_HandleTypeDef *hfdcan); +HAL_StatusTypeDef HAL_FDCAN_RegisterTxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan, + pFDCAN_TxBufferCompleteCallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_FDCAN_UnRegisterTxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan); +HAL_StatusTypeDef HAL_FDCAN_RegisterTxBufferAbortCallback(FDCAN_HandleTypeDef *hfdcan, + pFDCAN_TxBufferAbortCallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_FDCAN_UnRegisterTxBufferAbortCallback(FDCAN_HandleTypeDef *hfdcan); +HAL_StatusTypeDef HAL_FDCAN_RegisterErrorStatusCallback(FDCAN_HandleTypeDef *hfdcan, + pFDCAN_ErrorStatusCallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_FDCAN_UnRegisterErrorStatusCallback(FDCAN_HandleTypeDef *hfdcan); +#endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @addtogroup FDCAN_Exported_Functions_Group2 + * @{ + */ +/* Configuration functions ****************************************************/ +HAL_StatusTypeDef HAL_FDCAN_ConfigFilter(FDCAN_HandleTypeDef *hfdcan, const FDCAN_FilterTypeDef *sFilterConfig); +HAL_StatusTypeDef HAL_FDCAN_ConfigGlobalFilter(FDCAN_HandleTypeDef *hfdcan, uint32_t NonMatchingStd, + uint32_t NonMatchingExt, uint32_t RejectRemoteStd, + uint32_t RejectRemoteExt); +HAL_StatusTypeDef HAL_FDCAN_ConfigExtendedIdMask(FDCAN_HandleTypeDef *hfdcan, uint32_t Mask); +HAL_StatusTypeDef HAL_FDCAN_ConfigRxFifoOverwrite(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo, uint32_t OperationMode); +HAL_StatusTypeDef HAL_FDCAN_ConfigRamWatchdog(FDCAN_HandleTypeDef *hfdcan, uint32_t CounterStartValue); +HAL_StatusTypeDef HAL_FDCAN_ConfigTimestampCounter(FDCAN_HandleTypeDef *hfdcan, uint32_t TimestampPrescaler); +HAL_StatusTypeDef HAL_FDCAN_EnableTimestampCounter(FDCAN_HandleTypeDef *hfdcan, uint32_t TimestampOperation); +HAL_StatusTypeDef HAL_FDCAN_DisableTimestampCounter(FDCAN_HandleTypeDef *hfdcan); +uint16_t HAL_FDCAN_GetTimestampCounter(const FDCAN_HandleTypeDef *hfdcan); +HAL_StatusTypeDef HAL_FDCAN_ResetTimestampCounter(FDCAN_HandleTypeDef *hfdcan); +HAL_StatusTypeDef HAL_FDCAN_ConfigTimeoutCounter(FDCAN_HandleTypeDef *hfdcan, uint32_t TimeoutOperation, + uint32_t TimeoutPeriod); +HAL_StatusTypeDef HAL_FDCAN_EnableTimeoutCounter(FDCAN_HandleTypeDef *hfdcan); +HAL_StatusTypeDef HAL_FDCAN_DisableTimeoutCounter(FDCAN_HandleTypeDef *hfdcan); +uint16_t HAL_FDCAN_GetTimeoutCounter(const FDCAN_HandleTypeDef *hfdcan); +HAL_StatusTypeDef HAL_FDCAN_ResetTimeoutCounter(FDCAN_HandleTypeDef *hfdcan); +HAL_StatusTypeDef HAL_FDCAN_ConfigTxDelayCompensation(FDCAN_HandleTypeDef *hfdcan, uint32_t TdcOffset, + uint32_t TdcFilter); +HAL_StatusTypeDef HAL_FDCAN_EnableTxDelayCompensation(FDCAN_HandleTypeDef *hfdcan); +HAL_StatusTypeDef HAL_FDCAN_DisableTxDelayCompensation(FDCAN_HandleTypeDef *hfdcan); +HAL_StatusTypeDef HAL_FDCAN_EnableISOMode(FDCAN_HandleTypeDef *hfdcan); +HAL_StatusTypeDef HAL_FDCAN_DisableISOMode(FDCAN_HandleTypeDef *hfdcan); +HAL_StatusTypeDef HAL_FDCAN_EnableEdgeFiltering(FDCAN_HandleTypeDef *hfdcan); +HAL_StatusTypeDef HAL_FDCAN_DisableEdgeFiltering(FDCAN_HandleTypeDef *hfdcan); +/** + * @} + */ + +/** @addtogroup FDCAN_Exported_Functions_Group3 + * @{ + */ +/* Control functions **********************************************************/ +HAL_StatusTypeDef HAL_FDCAN_Start(FDCAN_HandleTypeDef *hfdcan); +HAL_StatusTypeDef HAL_FDCAN_Stop(FDCAN_HandleTypeDef *hfdcan); +HAL_StatusTypeDef HAL_FDCAN_AddMessageToTxFifoQ(FDCAN_HandleTypeDef *hfdcan, const FDCAN_TxHeaderTypeDef *pTxHeader, + const uint8_t *pTxData); +uint32_t HAL_FDCAN_GetLatestTxFifoQRequestBuffer(const FDCAN_HandleTypeDef *hfdcan); +HAL_StatusTypeDef HAL_FDCAN_AbortTxRequest(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndex); +HAL_StatusTypeDef HAL_FDCAN_GetRxMessage(FDCAN_HandleTypeDef *hfdcan, uint32_t RxLocation, + FDCAN_RxHeaderTypeDef *pRxHeader, uint8_t *pRxData); +HAL_StatusTypeDef HAL_FDCAN_GetTxEvent(FDCAN_HandleTypeDef *hfdcan, FDCAN_TxEventFifoTypeDef *pTxEvent); +HAL_StatusTypeDef HAL_FDCAN_GetHighPriorityMessageStatus(const FDCAN_HandleTypeDef *hfdcan, + FDCAN_HpMsgStatusTypeDef *HpMsgStatus); +HAL_StatusTypeDef HAL_FDCAN_GetProtocolStatus(const FDCAN_HandleTypeDef *hfdcan, + FDCAN_ProtocolStatusTypeDef *ProtocolStatus); +HAL_StatusTypeDef HAL_FDCAN_GetErrorCounters(const FDCAN_HandleTypeDef *hfdcan, + FDCAN_ErrorCountersTypeDef *ErrorCounters); +uint32_t HAL_FDCAN_IsTxBufferMessagePending(const FDCAN_HandleTypeDef *hfdcan, uint32_t TxBufferIndex); +uint32_t HAL_FDCAN_GetRxFifoFillLevel(const FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo); +uint32_t HAL_FDCAN_GetTxFifoFreeLevel(const FDCAN_HandleTypeDef *hfdcan); +uint32_t HAL_FDCAN_IsRestrictedOperationMode(const FDCAN_HandleTypeDef *hfdcan); +HAL_StatusTypeDef HAL_FDCAN_ExitRestrictedOperationMode(FDCAN_HandleTypeDef *hfdcan); +/** + * @} + */ + +/** @addtogroup FDCAN_Exported_Functions_Group4 + * @{ + */ +/* Interrupts management ******************************************************/ +HAL_StatusTypeDef HAL_FDCAN_ConfigInterruptLines(FDCAN_HandleTypeDef *hfdcan, uint32_t ITList, uint32_t InterruptLine); +HAL_StatusTypeDef HAL_FDCAN_ActivateNotification(FDCAN_HandleTypeDef *hfdcan, uint32_t ActiveITs, + uint32_t BufferIndexes); +HAL_StatusTypeDef HAL_FDCAN_DeactivateNotification(FDCAN_HandleTypeDef *hfdcan, uint32_t InactiveITs); +void HAL_FDCAN_IRQHandler(FDCAN_HandleTypeDef *hfdcan); +/** + * @} + */ + +/** @addtogroup FDCAN_Exported_Functions_Group5 + * @{ + */ +/* Callback functions *********************************************************/ +void HAL_FDCAN_TxEventFifoCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t TxEventFifoITs); +void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs); +void HAL_FDCAN_RxFifo1Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo1ITs); +void HAL_FDCAN_TxFifoEmptyCallback(FDCAN_HandleTypeDef *hfdcan); +void HAL_FDCAN_TxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes); +void HAL_FDCAN_TxBufferAbortCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes); +void HAL_FDCAN_HighPriorityMessageCallback(FDCAN_HandleTypeDef *hfdcan); +void HAL_FDCAN_TimestampWraparoundCallback(FDCAN_HandleTypeDef *hfdcan); +void HAL_FDCAN_TimeoutOccurredCallback(FDCAN_HandleTypeDef *hfdcan); +void HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef *hfdcan); +void HAL_FDCAN_ErrorStatusCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t ErrorStatusITs); +/** + * @} + */ + +/** @addtogroup FDCAN_Exported_Functions_Group6 + * @{ + */ +/* Peripheral State functions *************************************************/ +uint32_t HAL_FDCAN_GetError(const FDCAN_HandleTypeDef *hfdcan); +HAL_FDCAN_StateTypeDef HAL_FDCAN_GetState(const FDCAN_HandleTypeDef *hfdcan); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/** @defgroup FDCAN_Private_Variables FDCAN Private Variables + * @{ + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup FDCAN_Private_Constants FDCAN Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup FDCAN_Private_Macros FDCAN Private Macros + * @{ + */ +#define IS_FDCAN_FRAME_FORMAT(FORMAT) (((FORMAT) == FDCAN_FRAME_CLASSIC ) || \ + ((FORMAT) == FDCAN_FRAME_FD_NO_BRS) || \ + ((FORMAT) == FDCAN_FRAME_FD_BRS )) +#define IS_FDCAN_MODE(MODE) (((MODE) == FDCAN_MODE_NORMAL ) || \ + ((MODE) == FDCAN_MODE_RESTRICTED_OPERATION) || \ + ((MODE) == FDCAN_MODE_BUS_MONITORING ) || \ + ((MODE) == FDCAN_MODE_INTERNAL_LOOPBACK ) || \ + ((MODE) == FDCAN_MODE_EXTERNAL_LOOPBACK )) +#define IS_FDCAN_CKDIV(CKDIV) (((CKDIV) == FDCAN_CLOCK_DIV1 ) || \ + ((CKDIV) == FDCAN_CLOCK_DIV2 ) || \ + ((CKDIV) == FDCAN_CLOCK_DIV4 ) || \ + ((CKDIV) == FDCAN_CLOCK_DIV6 ) || \ + ((CKDIV) == FDCAN_CLOCK_DIV8 ) || \ + ((CKDIV) == FDCAN_CLOCK_DIV10) || \ + ((CKDIV) == FDCAN_CLOCK_DIV12) || \ + ((CKDIV) == FDCAN_CLOCK_DIV14) || \ + ((CKDIV) == FDCAN_CLOCK_DIV16) || \ + ((CKDIV) == FDCAN_CLOCK_DIV18) || \ + ((CKDIV) == FDCAN_CLOCK_DIV20) || \ + ((CKDIV) == FDCAN_CLOCK_DIV22) || \ + ((CKDIV) == FDCAN_CLOCK_DIV24) || \ + ((CKDIV) == FDCAN_CLOCK_DIV26) || \ + ((CKDIV) == FDCAN_CLOCK_DIV28) || \ + ((CKDIV) == FDCAN_CLOCK_DIV30)) +#define IS_FDCAN_NOMINAL_PRESCALER(PRESCALER) (((PRESCALER) >= 1U) && ((PRESCALER) <= 512U)) +#define IS_FDCAN_NOMINAL_SJW(SJW) (((SJW) >= 1U) && ((SJW) <= 128U)) +#define IS_FDCAN_NOMINAL_TSEG1(TSEG1) (((TSEG1) >= 1U) && ((TSEG1) <= 256U)) +#define IS_FDCAN_NOMINAL_TSEG2(TSEG2) (((TSEG2) >= 1U) && ((TSEG2) <= 128U)) +#define IS_FDCAN_DATA_PRESCALER(PRESCALER) (((PRESCALER) >= 1U) && ((PRESCALER) <= 32U)) +#define IS_FDCAN_DATA_SJW(SJW) (((SJW) >= 1U) && ((SJW) <= 16U)) +#define IS_FDCAN_DATA_TSEG1(TSEG1) (((TSEG1) >= 1U) && ((TSEG1) <= 32U)) +#define IS_FDCAN_DATA_TSEG2(TSEG2) (((TSEG2) >= 1U) && ((TSEG2) <= 16U)) +#define IS_FDCAN_MAX_VALUE(VALUE, _MAX_) ((VALUE) <= (_MAX_)) +#define IS_FDCAN_MIN_VALUE(VALUE, _MIN_) ((VALUE) >= (_MIN_)) +#define IS_FDCAN_TX_FIFO_QUEUE_MODE(MODE) (((MODE) == FDCAN_TX_FIFO_OPERATION ) || \ + ((MODE) == FDCAN_TX_QUEUE_OPERATION)) +#define IS_FDCAN_ID_TYPE(ID_TYPE) (((ID_TYPE) == FDCAN_STANDARD_ID) || \ + ((ID_TYPE) == FDCAN_EXTENDED_ID)) +#define IS_FDCAN_FILTER_CFG(CONFIG) (((CONFIG) == FDCAN_FILTER_DISABLE ) || \ + ((CONFIG) == FDCAN_FILTER_TO_RXFIFO0 ) || \ + ((CONFIG) == FDCAN_FILTER_TO_RXFIFO1 ) || \ + ((CONFIG) == FDCAN_FILTER_REJECT ) || \ + ((CONFIG) == FDCAN_FILTER_HP ) || \ + ((CONFIG) == FDCAN_FILTER_TO_RXFIFO0_HP) || \ + ((CONFIG) == FDCAN_FILTER_TO_RXFIFO1_HP)) +#define IS_FDCAN_TX_LOCATION(LOCATION) (((LOCATION) == FDCAN_TX_BUFFER0 ) || ((LOCATION) == FDCAN_TX_BUFFER1 ) || \ + ((LOCATION) == FDCAN_TX_BUFFER2 )) +#define IS_FDCAN_TX_LOCATION_LIST(LOCATION) (((LOCATION) >= FDCAN_TX_BUFFER0) && \ + ((LOCATION) <= (FDCAN_TX_BUFFER0 | FDCAN_TX_BUFFER1 | FDCAN_TX_BUFFER2))) +#define IS_FDCAN_RX_FIFO(FIFO) (((FIFO) == FDCAN_RX_FIFO0) || \ + ((FIFO) == FDCAN_RX_FIFO1)) +#define IS_FDCAN_RX_FIFO_MODE(MODE) (((MODE) == FDCAN_RX_FIFO_BLOCKING ) || \ + ((MODE) == FDCAN_RX_FIFO_OVERWRITE)) +#define IS_FDCAN_STD_FILTER_TYPE(TYPE) (((TYPE) == FDCAN_FILTER_RANGE) || \ + ((TYPE) == FDCAN_FILTER_DUAL ) || \ + ((TYPE) == FDCAN_FILTER_MASK )) +#define IS_FDCAN_EXT_FILTER_TYPE(TYPE) (((TYPE) == FDCAN_FILTER_RANGE ) || \ + ((TYPE) == FDCAN_FILTER_DUAL ) || \ + ((TYPE) == FDCAN_FILTER_MASK ) || \ + ((TYPE) == FDCAN_FILTER_RANGE_NO_EIDM)) +#define IS_FDCAN_FRAME_TYPE(TYPE) (((TYPE) == FDCAN_DATA_FRAME ) || \ + ((TYPE) == FDCAN_REMOTE_FRAME)) +#define IS_FDCAN_DLC(DLC) (((DLC) == FDCAN_DLC_BYTES_0 ) || \ + ((DLC) == FDCAN_DLC_BYTES_1 ) || \ + ((DLC) == FDCAN_DLC_BYTES_2 ) || \ + ((DLC) == FDCAN_DLC_BYTES_3 ) || \ + ((DLC) == FDCAN_DLC_BYTES_4 ) || \ + ((DLC) == FDCAN_DLC_BYTES_5 ) || \ + ((DLC) == FDCAN_DLC_BYTES_6 ) || \ + ((DLC) == FDCAN_DLC_BYTES_7 ) || \ + ((DLC) == FDCAN_DLC_BYTES_8 ) || \ + ((DLC) == FDCAN_DLC_BYTES_12) || \ + ((DLC) == FDCAN_DLC_BYTES_16) || \ + ((DLC) == FDCAN_DLC_BYTES_20) || \ + ((DLC) == FDCAN_DLC_BYTES_24) || \ + ((DLC) == FDCAN_DLC_BYTES_32) || \ + ((DLC) == FDCAN_DLC_BYTES_48) || \ + ((DLC) == FDCAN_DLC_BYTES_64)) +#define IS_FDCAN_ESI(ESI) (((ESI) == FDCAN_ESI_ACTIVE ) || \ + ((ESI) == FDCAN_ESI_PASSIVE)) +#define IS_FDCAN_BRS(BRS) (((BRS) == FDCAN_BRS_OFF) || \ + ((BRS) == FDCAN_BRS_ON )) +#define IS_FDCAN_FDF(FDF) (((FDF) == FDCAN_CLASSIC_CAN) || \ + ((FDF) == FDCAN_FD_CAN )) +#define IS_FDCAN_EFC(EFC) (((EFC) == FDCAN_NO_TX_EVENTS ) || \ + ((EFC) == FDCAN_STORE_TX_EVENTS)) +#define IS_FDCAN_IT(IT) (((IT) & ~(FDCAN_IR_MASK)) == 0U) +#define IS_FDCAN_IT_GROUP(IT_GROUP) (((IT_GROUP) & ~(FDCAN_ILS_MASK)) == 0U) +#define IS_FDCAN_NON_MATCHING(DESTINATION) (((DESTINATION) == FDCAN_ACCEPT_IN_RX_FIFO0) || \ + ((DESTINATION) == FDCAN_ACCEPT_IN_RX_FIFO1) || \ + ((DESTINATION) == FDCAN_REJECT )) +#define IS_FDCAN_REJECT_REMOTE(DESTINATION) (((DESTINATION) == FDCAN_FILTER_REMOTE) || \ + ((DESTINATION) == FDCAN_REJECT_REMOTE)) +#define IS_FDCAN_IT_LINE(IT_LINE) (((IT_LINE) == FDCAN_INTERRUPT_LINE0) || \ + ((IT_LINE) == FDCAN_INTERRUPT_LINE1)) +#define IS_FDCAN_TIMESTAMP(OPERATION) (((OPERATION) == FDCAN_TIMESTAMP_INTERNAL) || \ + ((OPERATION) == FDCAN_TIMESTAMP_EXTERNAL)) +#define IS_FDCAN_TIMESTAMP_PRESCALER(PRESCALER) (((PRESCALER) == FDCAN_TIMESTAMP_PRESC_1 ) || \ + ((PRESCALER) == FDCAN_TIMESTAMP_PRESC_2 ) || \ + ((PRESCALER) == FDCAN_TIMESTAMP_PRESC_3 ) || \ + ((PRESCALER) == FDCAN_TIMESTAMP_PRESC_4 ) || \ + ((PRESCALER) == FDCAN_TIMESTAMP_PRESC_5 ) || \ + ((PRESCALER) == FDCAN_TIMESTAMP_PRESC_6 ) || \ + ((PRESCALER) == FDCAN_TIMESTAMP_PRESC_7 ) || \ + ((PRESCALER) == FDCAN_TIMESTAMP_PRESC_8 ) || \ + ((PRESCALER) == FDCAN_TIMESTAMP_PRESC_9 ) || \ + ((PRESCALER) == FDCAN_TIMESTAMP_PRESC_10) || \ + ((PRESCALER) == FDCAN_TIMESTAMP_PRESC_11) || \ + ((PRESCALER) == FDCAN_TIMESTAMP_PRESC_12) || \ + ((PRESCALER) == FDCAN_TIMESTAMP_PRESC_13) || \ + ((PRESCALER) == FDCAN_TIMESTAMP_PRESC_14) || \ + ((PRESCALER) == FDCAN_TIMESTAMP_PRESC_15) || \ + ((PRESCALER) == FDCAN_TIMESTAMP_PRESC_16)) +#define IS_FDCAN_TIMEOUT(OPERATION) (((OPERATION) == FDCAN_TIMEOUT_CONTINUOUS ) || \ + ((OPERATION) == FDCAN_TIMEOUT_TX_EVENT_FIFO) || \ + ((OPERATION) == FDCAN_TIMEOUT_RX_FIFO0 ) || \ + ((OPERATION) == FDCAN_TIMEOUT_RX_FIFO1 )) + +#define FDCAN_CHECK_IT_SOURCE(__IE__, __IT__) ((((__IE__) & (__IT__)) == (__IT__)) ? SET : RESET) + +#define FDCAN_CHECK_FLAG(__IR__, __FLAG__) ((((__IR__) & (__FLAG__)) == (__FLAG__)) ? SET : RESET) +/** + * @} + */ + +/* Private functions prototypes ----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** + * @} + */ + +/** + * @} + */ +#endif /* FDCAN1 */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_FDCAN_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_flash.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_flash.h new file mode 100644 index 0000000000..b3d937d341 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_flash.h @@ -0,0 +1,810 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_flash.h + * @author MCD Application Team + * @brief Header file of FLASH HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_FLASH_H +#define STM32H5xx_HAL_FLASH_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup FLASH + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup FLASH_Exported_Types FLASH Exported Types + * @{ + */ + +/** + * @brief FLASH handle Structure definition + */ +typedef struct +{ + HAL_LockTypeDef Lock; /*!< FLASH locking object */ + + uint32_t ErrorCode; /*!< FLASH error code */ + + uint32_t ProcedureOnGoing; /*!< Internal variable to indicate which procedure is ongoing or not + in IT context */ + + uint32_t Address; /*!< Internal variable to save address selected for program */ + + uint32_t Bank; /*!< Internal variable to save current bank selected during erase in + IT context */ + + uint32_t Sector; /*!< Internal variable to define the current sector which is erasing */ + + uint32_t NbSectorsToErase; /*!< Internal variable to save the remaining sectors to erase in + IT context */ + +} FLASH_ProcessTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup FLASH_Exported_Constants FLASH Exported Constants + * @{ + */ + +/** @defgroup FLASH_Flag_definition FLASH Flag definition + * @brief Flag definition + * @{ + */ +#define FLASH_FLAG_BSY FLASH_SR_BSY /*!< FLASH Busy flag */ +#define FLASH_FLAG_WBNE FLASH_SR_WBNE /*!< FLASH Write Buffer Not Empty flag */ +#define FLASH_FLAG_DBNE FLASH_SR_DBNE /*!< FLASH data Buffer Not Empty flag */ +#define FLASH_FLAG_EOP FLASH_SR_EOP /*!< FLASH End Of operation flag */ +#define FLASH_FLAG_WRPERR FLASH_SR_WRPERR /*!< FLASH Write Protection Error flag */ +#define FLASH_FLAG_PGSERR FLASH_SR_PGSERR /*!< FLASH Program Sequence Error flag */ +#define FLASH_FLAG_STRBERR FLASH_SR_STRBERR /*!< FLASH Strobe Error flag */ +#define FLASH_FLAG_INCERR FLASH_SR_INCERR /*!< FLASH Inconsistency Error flag */ +#if defined (FLASH_SR_OBKERR) +#define FLASH_FLAG_OBKERR FLASH_SR_OBKERR /*!< FLASH OBK Error flag */ +#define FLASH_FLAG_OBKWERR FLASH_SR_OBKWERR /*!< FLASH OBK Write Error flag */ +#endif /* FLASH_SR_OBKERR */ +#define FLASH_FLAG_OPTCHANGEERR FLASH_SR_OPTCHANGEERR /*!< FLASH Option Byte change Error flag */ +#define FLASH_FLAG_ECCC FLASH_ECCR_ECCC /*!< FLASH ECC Correction flag */ +#define FLASH_FLAG_ECCD FLASH_ECCR_ECCD /*!< FLASH ECC Detection flag */ + +#if defined (FLASH_SR_OBKERR) +#define FLASH_FLAG_SR_ERRORS (FLASH_SR_WRPERR | FLASH_SR_PGSERR | \ + FLASH_SR_STRBERR | FLASH_SR_INCERR | \ + FLASH_SR_OBKERR | FLASH_SR_OBKWERR | \ + FLASH_SR_OPTCHANGEERR) +#else +#define FLASH_FLAG_SR_ERRORS (FLASH_SR_WRPERR | FLASH_SR_PGSERR | \ + FLASH_SR_STRBERR | FLASH_SR_INCERR | \ + FLASH_SR_OPTCHANGEERR) +#endif /* FLASH_SR_OBKERR */ +#define FLASH_FLAG_ECCR_ERRORS (FLASH_FLAG_ECCC | FLASH_FLAG_ECCD) +#define FLASH_FLAG_ALL_ERRORS (FLASH_FLAG_SR_ERRORS | FLASH_FLAG_ECCR_ERRORS) /*!< All FLASH error flags */ +/** + * @} + */ + +/** @defgroup FLASH_Interrupt_definition FLASH Interrupts definition + * @brief FLASH Interrupt definition + * @{ + */ +#define FLASH_IT_EOP FLASH_CR_EOPIE /*!< End of FLASH Operation interrupt enable */ +#define FLASH_IT_WRPERR FLASH_CR_WRPERRIE /*!< Write Protection Error interrupt enable */ +#define FLASH_IT_PGSERR FLASH_CR_PGSERRIE /*!< Program Sequence Error interrupt enable */ +#define FLASH_IT_STRBERR FLASH_CR_STRBERRIE /*!< Strobe Error interrupt enable */ +#define FLASH_IT_INCERR FLASH_CR_INCERRIE /*!< Inconsistency Error interrupt enable */ +#if defined (FLASH_SR_OBKERR) +#define FLASH_IT_OBKERR FLASH_CR_OBKERRIE /*!< OBK Error interrupt enable */ +#define FLASH_IT_OBKWERR FLASH_CR_OBKWERRIE /*!< OBK Write Error interrupt enable */ +#endif /* FLASH_SR_OBKERR */ +#define FLASH_IT_OPTCHANGEERR FLASH_CR_OPTCHANGEERRIE /*!< Option Byte change Error interrupt enable */ +#define FLASH_IT_ECCC FLASH_ECCR_ECCIE /*!< Single ECC Error Correction interrupt enable */ + +#if defined (FLASH_SR_OBKERR) +#define FLASH_IT_ALL (FLASH_IT_EOP | FLASH_IT_WRPERR | \ + FLASH_IT_PGSERR | FLASH_IT_STRBERR | \ + FLASH_IT_INCERR | FLASH_IT_OBKERR | \ + FLASH_IT_OBKWERR | FLASH_IT_OPTCHANGEERR | \ + FLASH_IT_ECCC) /*!< All Flash interrupt sources */ +#else +#define FLASH_IT_ALL (FLASH_IT_EOP | FLASH_IT_WRPERR | \ + FLASH_IT_PGSERR | FLASH_IT_STRBERR | \ + FLASH_IT_INCERR | FLASH_IT_OPTCHANGEERR | \ + FLASH_IT_ECCC) /*!< All Flash interrupt sources */ +#endif /* FLASH_SR_OBKERR */ + +/** + * @} + */ + +/** @defgroup FLASH_Error_Code FLASH Error Code + * @brief FLASH Error Code + * @{ + */ +#define HAL_FLASH_ERROR_NONE 0x00000000U /*!< No error */ +#define HAL_FLASH_ERROR_WRP FLASH_FLAG_WRPERR /*!< Write Protection Error */ +#define HAL_FLASH_ERROR_PGS FLASH_FLAG_PGSERR /*!< Program Sequence Error */ +#define HAL_FLASH_ERROR_STRB FLASH_FLAG_STRBERR /*!< Strobe Error */ +#define HAL_FLASH_ERROR_INC FLASH_FLAG_INCERR /*!< Inconsistency Error */ +#if defined (FLASH_SR_OBKERR) +#define HAL_FLASH_ERROR_OBK FLASH_FLAG_OBKERR /*!< OBK Error */ +#define HAL_FLASH_ERROR_OBKW FLASH_FLAG_OBKWERR /*!< OBK Write Error */ +#endif /* FLASH_SR_OBKERR */ +#define HAL_FLASH_ERROR_OB_CHANGE FLASH_FLAG_OPTCHANGEERR /*!< Option Byte Change Error */ +#define HAL_FLASH_ERROR_ECCC FLASH_FLAG_ECCC /*!< ECC Single Correction Error */ +#define HAL_FLASH_ERROR_ECCD FLASH_FLAG_ECCD /*!< ECC Double Detection Error */ +/** + * @} + */ + +/** @defgroup FLASH_Type_Program FLASH Program Type + * @{ + */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define FLASH_TYPEPROGRAM_QUADWORD FLASH_CR_PG /*!< Program a quad-word + (128-bit) at a specified secure address */ +#define FLASH_TYPEPROGRAM_QUADWORD_NS (FLASH_CR_PG | FLASH_NON_SECURE_MASK) /*!< Program a quad-word + (128-bit) at a specified non-secure address */ +#if defined (FLASH_SR_OBKERR) +#define FLASH_TYPEPROGRAM_QUADWORD_OBK (FLASH_CR_PG | FLASH_OBK) /*!< Program a quad-word + (128-bit) of OBK to current sector */ +#define FLASH_TYPEPROGRAM_QUADWORD_OBK_ALT (FLASH_CR_PG | FLASH_OBK | FLASH_OBKCFGR_ALT_SECT) /*!< Program a quad-word + (128-bit) of OBK to alternate sector */ +#endif /* FLASH_SR_OBKERR */ +#if defined (FLASH_EDATAR_EDATA_EN) +#define FLASH_TYPEPROGRAM_HALFWORD_EDATA (FLASH_CR_PG | FLASH_EDATA) /*!< Program a flash + high-cycle data half-word (16-bit)at a specified secure address */ +#define FLASH_TYPEPROGRAM_HALFWORD_EDATA_NS (FLASH_CR_PG | FLASH_EDATA | FLASH_NON_SECURE_MASK) /*!< Program a flash + high-cycle data half-word (16-bit)at a specified non-secure address */ +#endif /* FLASH_EDATAR_EDATA_EN */ +#else +#define FLASH_TYPEPROGRAM_QUADWORD FLASH_CR_PG /*!< Program a quad-word + (128-bit) at a specified address */ +#if defined (FLASH_SR_OBKERR) +#define FLASH_TYPEPROGRAM_QUADWORD_OBK (FLASH_CR_PG | FLASH_OBK) /*!< Program a quad-word + (128-bit) of OBK to current sector */ +#define FLASH_TYPEPROGRAM_QUADWORD_OBK_ALT (FLASH_CR_PG | FLASH_OBK | FLASH_OBKCFGR_ALT_SECT) /*!< Program a quad-word + (128-bit) of OBK to alternate sector */ +#endif /* FLASH_SR_OBKERR */ +#if defined (FLASH_EDATAR_EDATA_EN) +#define FLASH_TYPEPROGRAM_HALFWORD_EDATA (FLASH_CR_PG | FLASH_EDATA) /*!< Program a flash + high-cycle data half-word (16-bit)at a specified address */ +#endif /* FLASH_EDATAR_EDATA_EN */ +#endif /* __ARM_FEATURE_CMSE */ +#define FLASH_TYPEPROGRAM_HALFWORD_OTP (FLASH_CR_PG | FLASH_OTP | FLASH_NON_SECURE_MASK) /*!< Program an OTP + half-word (16-bit)at a specified address */ +/** + * @} + */ + +/** @defgroup FLASH_Latency FLASH Latency + * @{ + */ +#define FLASH_LATENCY_0 FLASH_ACR_LATENCY_0WS /*!< FLASH Zero wait cycle */ +#define FLASH_LATENCY_1 FLASH_ACR_LATENCY_1WS /*!< FLASH One wait cycle */ +#define FLASH_LATENCY_2 FLASH_ACR_LATENCY_2WS /*!< FLASH Two wait cycles */ +#define FLASH_LATENCY_3 FLASH_ACR_LATENCY_3WS /*!< FLASH Three wait cycles */ +#define FLASH_LATENCY_4 FLASH_ACR_LATENCY_4WS /*!< FLASH Four wait cycles */ +#define FLASH_LATENCY_5 FLASH_ACR_LATENCY_5WS /*!< FLASH Five wait cycles */ +#define FLASH_LATENCY_6 FLASH_ACR_LATENCY_6WS /*!< FLASH Six wait cycles */ +#define FLASH_LATENCY_7 FLASH_ACR_LATENCY_7WS /*!< FLASH Seven wait cycles */ +#define FLASH_LATENCY_8 FLASH_ACR_LATENCY_8WS /*!< FLASH Eight wait cycle */ +#define FLASH_LATENCY_9 FLASH_ACR_LATENCY_9WS /*!< FLASH Nine wait cycle */ +#define FLASH_LATENCY_10 FLASH_ACR_LATENCY_10WS /*!< FLASH Ten wait cycles */ +#define FLASH_LATENCY_11 FLASH_ACR_LATENCY_11WS /*!< FLASH Eleven wait cycles */ +#define FLASH_LATENCY_12 FLASH_ACR_LATENCY_12WS /*!< FLASH Twelve wait cycles */ +#define FLASH_LATENCY_13 FLASH_ACR_LATENCY_13WS /*!< FLASH Thirteen wait cycles */ +#define FLASH_LATENCY_14 FLASH_ACR_LATENCY_14WS /*!< FLASH Fourteen wait cycles */ +#define FLASH_LATENCY_15 FLASH_ACR_LATENCY_15WS /*!< FLASH Fifteen wait cycles */ +/** + * @} + */ + +/** @defgroup FLASH_Keys FLASH Keys + * @{ + */ +#define FLASH_KEY1 0x45670123U +#define FLASH_KEY2 0xCDEF89ABU +#define FLASH_OPT_KEY1 0x08192A3BU +#define FLASH_OPT_KEY2 0x4C5D6E7FU +#if defined (FLASH_SR_OBKERR) +#define FLASH_OBK_KEY1 0x192A083BU +#define FLASH_OBK_KEY2 0x6E7F4C5DU +#endif /* FLASH_SR_OBKERR */ +/** + * @} + */ + +/** @defgroup FLASH_Sectors FLASH Sectors + * @{ + */ +#define FLASH_SECTOR_0 0U /*!< Sector Number 0 */ +#define FLASH_SECTOR_1 1U /*!< Sector Number 1 */ +#define FLASH_SECTOR_2 2U /*!< Sector Number 2 */ +#define FLASH_SECTOR_3 3U /*!< Sector Number 3 */ +#define FLASH_SECTOR_4 4U /*!< Sector Number 4 */ +#define FLASH_SECTOR_5 5U /*!< Sector Number 5 */ +#define FLASH_SECTOR_6 6U /*!< Sector Number 6 */ +#define FLASH_SECTOR_7 7U /*!< Sector Number 7 */ +#if (FLASH_SECTOR_NB == 128) +#define FLASH_SECTOR_8 8U /*!< Sector Number 8 */ +#define FLASH_SECTOR_9 9U /*!< Sector Number 9 */ +#define FLASH_SECTOR_10 10U /*!< Sector Number 10 */ +#define FLASH_SECTOR_11 11U /*!< Sector Number 11 */ +#define FLASH_SECTOR_12 12U /*!< Sector Number 12 */ +#define FLASH_SECTOR_13 13U /*!< Sector Number 13 */ +#define FLASH_SECTOR_14 14U /*!< Sector Number 14 */ +#define FLASH_SECTOR_15 15U /*!< Sector Number 15 */ +#define FLASH_SECTOR_16 16U /*!< Sector Number 16 */ +#define FLASH_SECTOR_17 17U /*!< Sector Number 17 */ +#define FLASH_SECTOR_18 18U /*!< Sector Number 18 */ +#define FLASH_SECTOR_19 19U /*!< Sector Number 19 */ +#define FLASH_SECTOR_20 20U /*!< Sector Number 20 */ +#define FLASH_SECTOR_21 21U /*!< Sector Number 21 */ +#define FLASH_SECTOR_22 22U /*!< Sector Number 22 */ +#define FLASH_SECTOR_23 23U /*!< Sector Number 23 */ +#define FLASH_SECTOR_24 24U /*!< Sector Number 24 */ +#define FLASH_SECTOR_25 25U /*!< Sector Number 25 */ +#define FLASH_SECTOR_26 26U /*!< Sector Number 26 */ +#define FLASH_SECTOR_27 27U /*!< Sector Number 27 */ +#define FLASH_SECTOR_28 28U /*!< Sector Number 28 */ +#define FLASH_SECTOR_29 29U /*!< Sector Number 29 */ +#define FLASH_SECTOR_30 30U /*!< Sector Number 30 */ +#define FLASH_SECTOR_31 31U /*!< Sector Number 31 */ +#define FLASH_SECTOR_32 32U /*!< Sector Number 32 */ +#define FLASH_SECTOR_33 33U /*!< Sector Number 33 */ +#define FLASH_SECTOR_34 34U /*!< Sector Number 34 */ +#define FLASH_SECTOR_35 35U /*!< Sector Number 35 */ +#define FLASH_SECTOR_36 36U /*!< Sector Number 36 */ +#define FLASH_SECTOR_37 37U /*!< Sector Number 37 */ +#define FLASH_SECTOR_38 38U /*!< Sector Number 38 */ +#define FLASH_SECTOR_39 39U /*!< Sector Number 39 */ +#define FLASH_SECTOR_40 40U /*!< Sector Number 40 */ +#define FLASH_SECTOR_41 41U /*!< Sector Number 41 */ +#define FLASH_SECTOR_42 42U /*!< Sector Number 42 */ +#define FLASH_SECTOR_43 43U /*!< Sector Number 43 */ +#define FLASH_SECTOR_44 44U /*!< Sector Number 44 */ +#define FLASH_SECTOR_45 45U /*!< Sector Number 45 */ +#define FLASH_SECTOR_46 46U /*!< Sector Number 46 */ +#define FLASH_SECTOR_47 47U /*!< Sector Number 47 */ +#define FLASH_SECTOR_48 48U /*!< Sector Number 48 */ +#define FLASH_SECTOR_49 49U /*!< Sector Number 49 */ +#define FLASH_SECTOR_50 50U /*!< Sector Number 50 */ +#define FLASH_SECTOR_51 51U /*!< Sector Number 51 */ +#define FLASH_SECTOR_52 52U /*!< Sector Number 52 */ +#define FLASH_SECTOR_53 53U /*!< Sector Number 53 */ +#define FLASH_SECTOR_54 54U /*!< Sector Number 54 */ +#define FLASH_SECTOR_55 55U /*!< Sector Number 55 */ +#define FLASH_SECTOR_56 56U /*!< Sector Number 56 */ +#define FLASH_SECTOR_57 57U /*!< Sector Number 57 */ +#define FLASH_SECTOR_58 58U /*!< Sector Number 58 */ +#define FLASH_SECTOR_59 59U /*!< Sector Number 59 */ +#define FLASH_SECTOR_60 60U /*!< Sector Number 60 */ +#define FLASH_SECTOR_61 61U /*!< Sector Number 61 */ +#define FLASH_SECTOR_62 62U /*!< Sector Number 62 */ +#define FLASH_SECTOR_63 63U /*!< Sector Number 63 */ +#define FLASH_SECTOR_64 64U /*!< Sector Number 64 */ +#define FLASH_SECTOR_65 65U /*!< Sector Number 65 */ +#define FLASH_SECTOR_66 66U /*!< Sector Number 66 */ +#define FLASH_SECTOR_67 67U /*!< Sector Number 67 */ +#define FLASH_SECTOR_68 68U /*!< Sector Number 68 */ +#define FLASH_SECTOR_69 69U /*!< Sector Number 69 */ +#define FLASH_SECTOR_70 70U /*!< Sector Number 70 */ +#define FLASH_SECTOR_71 71U /*!< Sector Number 71 */ +#define FLASH_SECTOR_72 72U /*!< Sector Number 72 */ +#define FLASH_SECTOR_73 73U /*!< Sector Number 73 */ +#define FLASH_SECTOR_74 74U /*!< Sector Number 74 */ +#define FLASH_SECTOR_75 75U /*!< Sector Number 75 */ +#define FLASH_SECTOR_76 76U /*!< Sector Number 76 */ +#define FLASH_SECTOR_77 77U /*!< Sector Number 77 */ +#define FLASH_SECTOR_78 78U /*!< Sector Number 78 */ +#define FLASH_SECTOR_79 79U /*!< Sector Number 79 */ +#define FLASH_SECTOR_80 80U /*!< Sector Number 80 */ +#define FLASH_SECTOR_81 81U /*!< Sector Number 81 */ +#define FLASH_SECTOR_82 82U /*!< Sector Number 82 */ +#define FLASH_SECTOR_83 83U /*!< Sector Number 83 */ +#define FLASH_SECTOR_84 84U /*!< Sector Number 84 */ +#define FLASH_SECTOR_85 85U /*!< Sector Number 85 */ +#define FLASH_SECTOR_86 86U /*!< Sector Number 86 */ +#define FLASH_SECTOR_87 87U /*!< Sector Number 87 */ +#define FLASH_SECTOR_88 88U /*!< Sector Number 88 */ +#define FLASH_SECTOR_89 89U /*!< Sector Number 89 */ +#define FLASH_SECTOR_90 90U /*!< Sector Number 90 */ +#define FLASH_SECTOR_91 91U /*!< Sector Number 91 */ +#define FLASH_SECTOR_92 92U /*!< Sector Number 92 */ +#define FLASH_SECTOR_93 93U /*!< Sector Number 93 */ +#define FLASH_SECTOR_94 94U /*!< Sector Number 94 */ +#define FLASH_SECTOR_95 95U /*!< Sector Number 95 */ +#define FLASH_SECTOR_96 96U /*!< Sector Number 96 */ +#define FLASH_SECTOR_97 97U /*!< Sector Number 97 */ +#define FLASH_SECTOR_98 98U /*!< Sector Number 98 */ +#define FLASH_SECTOR_99 99U /*!< Sector Number 99 */ +#define FLASH_SECTOR_100 100U /*!< Sector Number 100 */ +#define FLASH_SECTOR_101 101U /*!< Sector Number 101 */ +#define FLASH_SECTOR_102 102U /*!< Sector Number 102 */ +#define FLASH_SECTOR_103 103U /*!< Sector Number 103 */ +#define FLASH_SECTOR_104 104U /*!< Sector Number 104 */ +#define FLASH_SECTOR_105 105U /*!< Sector Number 105 */ +#define FLASH_SECTOR_106 106U /*!< Sector Number 106 */ +#define FLASH_SECTOR_107 107U /*!< Sector Number 107 */ +#define FLASH_SECTOR_108 108U /*!< Sector Number 108 */ +#define FLASH_SECTOR_109 109U /*!< Sector Number 109 */ +#define FLASH_SECTOR_110 110U /*!< Sector Number 110 */ +#define FLASH_SECTOR_111 111U /*!< Sector Number 111 */ +#define FLASH_SECTOR_112 112U /*!< Sector Number 112 */ +#define FLASH_SECTOR_113 113U /*!< Sector Number 113 */ +#define FLASH_SECTOR_114 114U /*!< Sector Number 114 */ +#define FLASH_SECTOR_115 115U /*!< Sector Number 115 */ +#define FLASH_SECTOR_116 116U /*!< Sector Number 116 */ +#define FLASH_SECTOR_117 117U /*!< Sector Number 117 */ +#define FLASH_SECTOR_118 118U /*!< Sector Number 118 */ +#define FLASH_SECTOR_119 119U /*!< Sector Number 119 */ +#define FLASH_SECTOR_120 120U /*!< Sector Number 120 */ +#define FLASH_SECTOR_121 121U /*!< Sector Number 121 */ +#define FLASH_SECTOR_122 122U /*!< Sector Number 122 */ +#define FLASH_SECTOR_123 123U /*!< Sector Number 123 */ +#define FLASH_SECTOR_124 124U /*!< Sector Number 124 */ +#define FLASH_SECTOR_125 125U /*!< Sector Number 125 */ +#define FLASH_SECTOR_126 126U /*!< Sector Number 126 */ +#define FLASH_SECTOR_127 127U /*!< Sector Number 127 */ +#endif /* (FLASH_SECTOR_NB == 128) */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros ------------------------------------------------------------*/ +/** @defgroup FLASH_Exported_Macros FLASH Exported Macros + * @{ + */ +/** + * @brief Set the FLASH Latency. + * @param __LATENCY__: FLASH Latency + * This parameter can be one of the following values : + * @arg FLASH_LATENCY_0: FLASH Zero wait state + * @arg FLASH_LATENCY_1: FLASH One wait state + * @arg FLASH_LATENCY_2: FLASH Two wait states + * @arg FLASH_LATENCY_3: FLASH Three wait states + * @arg FLASH_LATENCY_4: FLASH Four wait states + * @arg FLASH_LATENCY_5: FLASH Five wait states + * @arg FLASH_LATENCY_6: FLASH Six wait states + * @arg FLASH_LATENCY_7: FLASH Seven wait states + * @arg FLASH_LATENCY_8: FLASH Eight wait states + * @arg FLASH_LATENCY_9: FLASH Nine wait states + * @arg FLASH_LATENCY_10: FLASH Ten wait states + * @arg FLASH_LATENCY_11: FLASH Eleven wait states + * @arg FLASH_LATENCY_12: FLASH Twelve wait states + * @arg FLASH_LATENCY_13: FLASH Thirteen wait states + * @arg FLASH_LATENCY_14: FLASH Fourteen wait states + * @arg FLASH_LATENCY_15: FLASH Fifteen wait states + * @retval none + */ +#define __HAL_FLASH_SET_LATENCY(__LATENCY__) MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, (__LATENCY__)) + +/** + * @brief Get the FLASH Latency. + * @retval FLASH Latency + * This return value can be one of the following values : + * @arg FLASH_LATENCY_0: FLASH Zero wait state + * @arg FLASH_LATENCY_1: FLASH One wait state + * @arg FLASH_LATENCY_2: FLASH Two wait states + * @arg FLASH_LATENCY_3: FLASH Three wait states + * @arg FLASH_LATENCY_4: FLASH Four wait states + * @arg FLASH_LATENCY_5: FLASH Five wait states + * @arg FLASH_LATENCY_6: FLASH Six wait states + * @arg FLASH_LATENCY_7: FLASH Seven wait states + * @arg FLASH_LATENCY_8: FLASH Eight wait states + * @arg FLASH_LATENCY_9: FLASH Nine wait states + * @arg FLASH_LATENCY_10: FLASH Ten wait states + * @arg FLASH_LATENCY_11: FLASH Eleven wait states + * @arg FLASH_LATENCY_12: FLASH Twelve wait states + * @arg FLASH_LATENCY_13: FLASH Thirteen wait states + * @arg FLASH_LATENCY_14: FLASH Fourteen wait states + * @arg FLASH_LATENCY_15: FLASH Fifteen wait states + */ +#define __HAL_FLASH_GET_LATENCY() READ_BIT((FLASH->ACR), FLASH_ACR_LATENCY) + +/** + * @brief Enable the specified FLASH interrupt. + * @param __INTERRUPT__ : FLASH interrupt + * This parameter can be any combination of the following values: + * @arg FLASH_IT_EOP : End of FLASH Operation Interrupt + * @arg FLASH_IT_WRPERR : Write Protection Error Interrupt + * @arg FLASH_IT_PGSERR : Program Sequence Error Interrupt + * @arg FLASH_IT_STRBERR : Strobe Error Interrupt + * @arg FLASH_IT_INCERR : Inconsistency Error Interrupt + * @arg FLASH_IT_OBKERR : OBK Error Interrupt + * @arg FLASH_IT_OBKWERR : OBK Write Error Interrupt + * @arg FLASH_IT_OPTCHANGEERR : Option Byte Change Error Interrupt + * @arg FLASH_IT_ECCC : Single ECC Error Correction Interrupt + * @retval none + */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/* Enable secure FLASH interrupts from the secure world */ +#define __HAL_FLASH_ENABLE_IT(__INTERRUPT__) do { if(((__INTERRUPT__) & FLASH_IT_ECCC) != 0U) \ + { SET_BIT(FLASH->ECCCORR, FLASH_IT_ECCC); } \ + if(((__INTERRUPT__) & FLASH_IT_OPTCHANGEERR) != 0U) \ + { SET_BIT(FLASH->NSCR, FLASH_IT_OPTCHANGEERR); } \ + if(((__INTERRUPT__) & (~FLASH_IT_ECCC)) != 0U) \ + { SET_BIT(FLASH->SECCR, ((__INTERRUPT__) & (~(FLASH_IT_ECCC | \ + FLASH_IT_OPTCHANGEERR)))); }\ + } while(0) +/* Enable non-secure FLASH interrupts from the secure world */ +#define __HAL_FLASH_ENABLE_IT_NS(__INTERRUPT__) do { if(((__INTERRUPT__) & FLASH_IT_ECCC) != 0U) \ + { SET_BIT(FLASH->ECCCORR, FLASH_IT_ECCC); } \ + if(((__INTERRUPT__) & (~FLASH_IT_ECCC)) != 0U) \ + { SET_BIT(FLASH->NSCR, ((__INTERRUPT__) & (~FLASH_IT_ECCC))); } \ + } while(0) +#else +/* Enable non-secure FLASH interrupts from the non-secure world */ +#define __HAL_FLASH_ENABLE_IT(__INTERRUPT__) do { if(((__INTERRUPT__) & FLASH_IT_ECCC) != 0U) \ + { SET_BIT(FLASH->ECCCORR, FLASH_IT_ECCC); } \ + if(((__INTERRUPT__) & (~FLASH_IT_ECCC)) != 0U) \ + { SET_BIT(FLASH->NSCR, ((__INTERRUPT__) & (~FLASH_IT_ECCC))); } \ + } while(0) +#endif /* __ARM_FEATURE_CMSE */ + +/** + * @brief Disable the specified FLASH interrupt. + * @param __INTERRUPT__ : FLASH interrupt + * This parameter can be any combination of the following values: + * @arg FLASH_IT_EOP : End of FLASH Operation Interrupt + * @arg FLASH_IT_WRPERR : Write Protection Error Interrupt + * @arg FLASH_IT_PGSERR : Program Sequence Error Interrupt + * @arg FLASH_IT_STRBERR : Strobe Error Interrupt + * @arg FLASH_IT_INCERR : Inconsistency Error Interrupt + * @arg FLASH_IT_OBKERR : OBK Error Interrupt + * @arg FLASH_IT_OBKWERR : OBK Write Error Interrupt + * @arg FLASH_IT_OPTCHANGEERR : Option Byte Change Error Interrupt + * @arg FLASH_IT_ECCC : Single ECC Error Correction Interrupt + * @retval none + */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/* Disable secure FLASH interrupts from the secure world */ +#define __HAL_FLASH_DISABLE_IT(__INTERRUPT__) do { if(((__INTERRUPT__) & FLASH_IT_ECCC) != 0U) \ + { CLEAR_BIT(FLASH->ECCCORR, FLASH_IT_ECCC); } \ + if(((__INTERRUPT__) & FLASH_IT_OPTCHANGEERR) != 0U) \ + { CLEAR_BIT(FLASH->NSCR, FLASH_IT_OPTCHANGEERR); } \ + if(((__INTERRUPT__) & (~(FLASH_IT_ECCC | FLASH_IT_OPTCHANGEERR))) \ + != 0U){ CLEAR_BIT(FLASH->SECCR, ((__INTERRUPT__) & \ + (~(FLASH_IT_ECCC | FLASH_IT_OPTCHANGEERR)))); }\ + } while(0) +/* Disable non-secure FLASH interrupts from the secure world */ +#define __HAL_FLASH_DISABLE_IT_NS(__INTERRUPT__) do { if(((__INTERRUPT__) & FLASH_IT_ECCC) != 0U) { CLEAR_BIT \ + (FLASH->ECCCORR, FLASH_IT_ECCC); } \ + if(((__INTERRUPT__) & (~FLASH_IT_ECCC)) != 0U) \ + { CLEAR_BIT(FLASH->NSCR, ((__INTERRUPT__) & (~FLASH_IT_ECCC)));\ + } \ + } while(0) +#else +/* Disable non-secure FLASH interrupts from the non-secure world */ +#define __HAL_FLASH_DISABLE_IT(__INTERRUPT__) do { if(((__INTERRUPT__) & FLASH_IT_ECCC) != 0U) { CLEAR_BIT \ + (FLASH->ECCCORR, FLASH_IT_ECCC); } \ + if(((__INTERRUPT__) & (~FLASH_IT_ECCC)) != 0U) { CLEAR_BIT \ + (FLASH->NSCR, ((__INTERRUPT__) & (~FLASH_IT_ECCC))); } \ + } while(0) +#endif /* __ARM_FEATURE_CMSE */ + +/** + * @brief Checks whether the specified FLASH flag is set or not. + * @param __FLAG__: specifies the FLASH flag to check. + * This parameter can be one of the following values : + * @arg FLASH_FLAG_BSY : FLASH Busy flag + * @arg FLASH_FLAG_WBNE : Write Buffer Not Empty flag + * @arg FLASH_FLAG_EOP : End Of Operation flag + * @arg FLASH_FLAG_WRPERR : Write Protection Error flag + * @arg FLASH_FLAG_PGSERR : Program Sequence Error flag + * @arg FLASH_FLAG_STRBERR : Strobe Error flag + * @arg FLASH_FLAG_INCERR : Inconsistency Error flag + * @arg FLASH_FLAG_OBKERR : OBK Error flag + * @arg FLASH_FLAG_OBKWERR : OBK Write Error flag + * @arg FLASH_FLAG_OPTCHANGEERR : Option Byte Change Error flag + * @arg FLASH_FLAG_ECCC : Single ECC Error Correction flag + * @arg FLASH_FLAG_ECCD : Double Detection ECC Error flag + * @retval The new state of FLASH_FLAG (SET or RESET). + */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/* Get secure FLASH flags from the secure world */ +#define __HAL_FLASH_GET_FLAG(__FLAG__) ((((__FLAG__) & (FLASH_FLAG_ECCC)) != 0U) ? \ + (READ_BIT(FLASH->ECCCORR, (__FLAG__)) == (__FLAG__)) : \ + (((__FLAG__) & (FLASH_FLAG_ECCD)) != 0U) ? \ + (READ_BIT(FLASH->ECCDETR, (__FLAG__)) == (__FLAG__)) : \ + ((((__FLAG__) & (FLASH_FLAG_OPTCHANGEERR)) != 0U) ? \ + (READ_BIT(FLASH->NSSR, (__FLAG__)) == (__FLAG__)) : \ + (READ_BIT(FLASH->SECSR, (__FLAG__)) == (__FLAG__)))) +/* Get non-secure FLASH flags from the secure world */ +#define __HAL_FLASH_GET_FLAG_NS(__FLAG__) ((((__FLAG__) & (FLASH_FLAG_ECCC)) != 0U) ? \ + (READ_BIT(FLASH->ECCCORR, (__FLAG__)) == (__FLAG__)) : \ + (((__FLAG__) & (FLASH_FLAG_ECCD)) != 0U) ? \ + (READ_BIT(FLASH->ECCDETR, (__FLAG__)) == (__FLAG__)) : \ + (READ_BIT(FLASH->NSSR, (__FLAG__)) == (__FLAG__)))) +#else +/* Get non-secure FLASH flags from the non-secure world */ +#define __HAL_FLASH_GET_FLAG(__FLAG__) ((((__FLAG__) & (FLASH_FLAG_ECCC)) != 0U) ? \ + (READ_BIT(FLASH->ECCCORR, (__FLAG__)) == (__FLAG__)) : \ + (((__FLAG__) & (FLASH_FLAG_ECCD)) != 0U) ? \ + (READ_BIT(FLASH->ECCDETR, (__FLAG__)) == (__FLAG__)) : \ + (READ_BIT(FLASH->NSSR, (__FLAG__)) == (__FLAG__))) +#endif /* __ARM_FEATURE_CMSE */ + +/** + * @brief Clear the specified FLASH flag. + * @param __FLAG__: specifies the FLASH flags to clear. + * This parameter can be one of the following values : + * @arg FLASH_FLAG_BSY : FLASH Busy flag + * @arg FLASH_FLAG_WBNE : Write Buffer Not Empty flag + * @arg FLASH_FLAG_EOP : End Of Operation flag + * @arg FLASH_FLAG_WRPERR : Write Protection Error flag + * @arg FLASH_FLAG_PGSERR : Program Sequence Error flag + * @arg FLASH_FLAG_STRBERR : Strobe Error flag + * @arg FLASH_FLAG_INCERR : Inconsistency Error flag + * @arg FLASH_FLAG_OBKERR : OBK Error flag + * @arg FLASH_FLAG_OBKWERR : OBK Write Error flag + * @arg FLASH_FLAG_OPTCHANGEERR : Option Byte Change Error flag + * @arg FLASH_FLAG_ECCC : Single ECC Error Correction flag + * @arg FLASH_FLAG_ECCD : Double Detection ECC Error flag + * @arg FLASH_FLAG_ALL_ERRORS: All errors flags + * @retval none + */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/* Clear secure FLASH flags from the secure world */ +#define __HAL_FLASH_CLEAR_FLAG(__FLAG__) do { if(((__FLAG__) & FLASH_FLAG_ECCC) != 0U) { SET_BIT(FLASH->ECCCORR,\ + ((__FLAG__) & FLASH_FLAG_ECCC)); } \ + if(((__FLAG__) & FLASH_FLAG_ECCD) != 0U) { SET_BIT(FLASH->ECCDETR,\ + ((__FLAG__) & FLASH_FLAG_ECCD)); } \ + if(((__FLAG__) & FLASH_FLAG_OPTCHANGEERR) != 0U) { SET_BIT \ + (FLASH->NSCCR, ((__FLAG__) & (FLASH_FLAG_OPTCHANGEERR))); } \ + if(((__FLAG__) & ~(FLASH_FLAG_ECCR_ERRORS | \ + FLASH_FLAG_OPTCHANGEERR)) != 0U) { WRITE_REG(FLASH->SECCCR, \ + ((__FLAG__) & ~(FLASH_FLAG_ECCR_ERRORS | \ + FLASH_FLAG_OPTCHANGEERR))); } \ + } while(0) +/* Clear non-secure FLASH flags from the secure world */ +#define __HAL_FLASH_CLEAR_FLAG_NS(__FLAG__) do { if(((__FLAG__) & FLASH_FLAG_ECCC) != 0U) { SET_BIT(FLASH->ECCCORR,\ + ((__FLAG__) & FLASH_FLAG_ECCC)); } \ + if(((__FLAG__) & FLASH_FLAG_ECCD) != 0U) { SET_BIT(FLASH->ECCDETR,\ + ((__FLAG__) & FLASH_FLAG_ECCD)); } \ + if(((__FLAG__) & (~FLASH_FLAG_ECCR_ERRORS)) != 0U) { WRITE_REG \ + (FLASH->NSCCR, ((__FLAG__) & (~FLASH_FLAG_ECCR_ERRORS))); } \ + } while(0) +#else +/* Clear non-secure FLASH flags from the non-secure world */ +#define __HAL_FLASH_CLEAR_FLAG(__FLAG__) do { if(((__FLAG__) & FLASH_FLAG_ECCC) != 0U) { SET_BIT(FLASH->ECCCORR,\ + ((__FLAG__) & FLASH_FLAG_ECCC)); } \ + if(((__FLAG__) & FLASH_FLAG_ECCD) != 0U) { SET_BIT(FLASH->ECCDETR,\ + ((__FLAG__) & FLASH_FLAG_ECCD)); } \ + if(((__FLAG__) & (~FLASH_FLAG_ECCR_ERRORS)) != 0U) { WRITE_REG \ + (FLASH->NSCCR, ((__FLAG__) & (~FLASH_FLAG_ECCR_ERRORS))); } \ + } while(0) +#endif /* __ARM_FEATURE_CMSE */ + +/** + * @} + */ + +/* Include FLASH HAL Extension module */ +#include "stm32h5xx_hal_flash_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup FLASH_Exported_Functions + * @{ + */ +/** @addtogroup FLASH_Exported_Functions_Group1 + * @{ + */ +/* Program operation functions */ +HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress); +HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress); +/* FLASH IRQ handler method */ +void HAL_FLASH_IRQHandler(void); +/* Callbacks in non blocking modes */ +void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue); +void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue); +/** + * @} + */ + +/** @addtogroup FLASH_Exported_Functions_Group2 + * @{ + */ +/* Peripheral Control functions */ +HAL_StatusTypeDef HAL_FLASH_Unlock(void); +HAL_StatusTypeDef HAL_FLASH_Lock(void); +HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void); +HAL_StatusTypeDef HAL_FLASH_OB_Lock(void); +/* Option bytes control */ +HAL_StatusTypeDef HAL_FLASH_OB_Launch(void); +/** + * @} + */ + +/** @addtogroup FLASH_Exported_Functions_Group3 + * @{ + */ +/* Peripheral State functions */ +uint32_t HAL_FLASH_GetError(void); +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/** @defgroup FLASH_Private_Variables FLASH Private Variables + * @{ + */ +extern FLASH_ProcessTypeDef pFlash; +/** + * @} + */ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup FLASH_Private_Constants FLASH Private Constants + * @{ + */ +#define FLASH_TIMEOUT_VALUE 1000U /*!< 1 s */ + +#if defined (FLASH_SR_OBKERR) +#define FLASH_OBK 0x10000000U +#endif /* FLASH_SR_OBKERR */ + +#define FLASH_OTP 0x20000000U + +#if defined (FLASH_EDATAR_EDATA_EN) +#define FLASH_EDATA 0x40000000U +#endif /* FLASH_EDATAR_EDATA_EN */ + +#define FLASH_NON_SECURE_MASK 0x80000000U + +#define FLASH_EDATA_SECTOR_NB 8U /*!< Maximum number of FLASH high-cycle data sectors */ +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup FLASH_Private_Macros FLASH Private Macros + * @{ + */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#if defined (FLASH_SR_OBKERR) && defined (FLASH_EDATAR_EDATA_EN) +#define IS_FLASH_TYPEPROGRAM(VALUE) (((VALUE) == FLASH_TYPEPROGRAM_QUADWORD) || \ + ((VALUE) == FLASH_TYPEPROGRAM_QUADWORD_NS) || \ + ((VALUE) == FLASH_TYPEPROGRAM_HALFWORD_OTP) || \ + ((VALUE) == FLASH_TYPEPROGRAM_HALFWORD_EDATA) || \ + ((VALUE) == FLASH_TYPEPROGRAM_HALFWORD_EDATA_NS) || \ + ((VALUE) == FLASH_TYPEPROGRAM_QUADWORD_OBK) || \ + ((VALUE) == FLASH_TYPEPROGRAM_QUADWORD_OBK_ALT)) +#else +#define IS_FLASH_TYPEPROGRAM(VALUE) (((VALUE) == FLASH_TYPEPROGRAM_QUADWORD) || \ + ((VALUE) == FLASH_TYPEPROGRAM_QUADWORD_NS) || \ + ((VALUE) == FLASH_TYPEPROGRAM_HALFWORD_OTP)) +#endif /* FLASH_SR_OBKERR && FLASH_EDATAR_EDATA_EN */ +#else +#if defined (FLASH_SR_OBKERR) && defined (FLASH_EDATAR_EDATA_EN) +#define IS_FLASH_TYPEPROGRAM(VALUE) (((VALUE) == FLASH_TYPEPROGRAM_QUADWORD) || \ + ((VALUE) == FLASH_TYPEPROGRAM_HALFWORD_OTP) || \ + ((VALUE) == FLASH_TYPEPROGRAM_HALFWORD_EDATA) || \ + ((VALUE) == FLASH_TYPEPROGRAM_QUADWORD_OBK) || \ + ((VALUE) == FLASH_TYPEPROGRAM_QUADWORD_OBK_ALT)) +#else +#define IS_FLASH_TYPEPROGRAM(VALUE) (((VALUE) == FLASH_TYPEPROGRAM_QUADWORD) || \ + ((VALUE) == FLASH_TYPEPROGRAM_HALFWORD_OTP)) +#endif /* FLASH_SR_OBKERR && FLASH_EDATAR_EDATA_EN */ +#endif /* __ARM_FEATURE_CMSE */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define IS_FLASH_USER_MEM_ADDRESS(ADDRESS) ((((ADDRESS) >= FLASH_BASE) && ((ADDRESS) < (FLASH_BASE+FLASH_SIZE))) || \ + (((ADDRESS) >= FLASH_BASE_NS) && ((ADDRESS) < (FLASH_BASE_NS+FLASH_SIZE)))) +#if defined (FLASH_SR_OBKERR) +#define IS_FLASH_OBK_ADDRESS(ADDRESS) ((((ADDRESS) >= FLASH_OBK_BASE) && \ + ((ADDRESS) < (FLASH_OBK_BASE+FLASH_OBK_SIZE))) || \ + (((ADDRESS) >= FLASH_OBK_BASE_NS) && \ + ((ADDRESS) < (FLASH_OBK_BASE_NS+FLASH_OBK_SIZE)))) +#endif /* FLASH_SR_OBKERR */ +#if defined (FLASH_EDATAR_EDATA_EN) +#define IS_FLASH_EDATA_ADDRESS(ADDRESS) ((((ADDRESS) >= FLASH_EDATA_BASE_S) && \ + ((ADDRESS) < (FLASH_EDATA_BASE_S+FLASH_EDATA_SIZE))) || \ + (((ADDRESS) >= FLASH_EDATA_BASE_NS) && \ + ((ADDRESS) < (FLASH_EDATA_BASE_NS+FLASH_EDATA_SIZE)))) +#endif /* FLASH_EDATAR_EDATA_EN */ +#else +#define IS_FLASH_USER_MEM_ADDRESS(ADDRESS) (((ADDRESS) >= FLASH_BASE) && \ + ((ADDRESS) < (FLASH_BASE+FLASH_SIZE))) +#if defined (FLASH_SR_OBKERR) +#define IS_FLASH_OBK_ADDRESS(ADDRESS) (((ADDRESS) >= FLASH_OBK_BASE) && \ + ((ADDRESS) < (FLASH_OBK_BASE + FLASH_OBK_SIZE))) +#endif /* FLASH_SR_OBKERR */ +#if defined (FLASH_EDATAR_EDATA_EN) +#define IS_FLASH_EDATA_ADDRESS(ADDRESS) (((ADDRESS) >= FLASH_EDATA_BASE_NS) && \ + ((ADDRESS) < (FLASH_EDATA_BASE_NS + FLASH_EDATA_SIZE))) +#endif /* FLASH_EDATAR_EDATA_EN */ +#endif /* __ARM_FEATURE_CMSE */ + +#define IS_FLASH_OTP_ADDRESS(ADDRESS) (((ADDRESS) >= FLASH_OTP_BASE) && \ + ((ADDRESS) < (FLASH_OTP_BASE + FLASH_OTP_SIZE))) + +#define IS_FLASH_BANK(BANK) (((BANK) == FLASH_BANK_1) || \ + ((BANK) == FLASH_BANK_2) || \ + ((BANK) == FLASH_BANK_BOTH)) + +#define IS_FLASH_BANK_EXCLUSIVE(BANK) (((BANK) == FLASH_BANK_1) || \ + ((BANK) == FLASH_BANK_2)) + +#define IS_FLASH_SECTOR(SECTOR) ((SECTOR) < FLASH_SECTOR_NB) + +#define IS_FLASH_LATENCY(LATENCY) (((LATENCY) == FLASH_LATENCY_0) || \ + ((LATENCY) == FLASH_LATENCY_1) || \ + ((LATENCY) == FLASH_LATENCY_2) || \ + ((LATENCY) == FLASH_LATENCY_3) || \ + ((LATENCY) == FLASH_LATENCY_4) || \ + ((LATENCY) == FLASH_LATENCY_5) || \ + ((LATENCY) == FLASH_LATENCY_6) || \ + ((LATENCY) == FLASH_LATENCY_7) || \ + ((LATENCY) == FLASH_LATENCY_8) || \ + ((LATENCY) == FLASH_LATENCY_9) || \ + ((LATENCY) == FLASH_LATENCY_10) || \ + ((LATENCY) == FLASH_LATENCY_11) || \ + ((LATENCY) == FLASH_LATENCY_12) || \ + ((LATENCY) == FLASH_LATENCY_13) || \ + ((LATENCY) == FLASH_LATENCY_14) || \ + ((LATENCY) == FLASH_LATENCY_15)) + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define IS_FLASH_SECURE_OPERATION() ((pFlash.ProcedureOnGoing & FLASH_NON_SECURE_MASK) == 0U) +#else +#define IS_FLASH_SECURE_OPERATION() (1U == 0U) +#endif /* __ARM_FEATURE_CMSE */ +/** + * @} + */ +/* Private functions ---------------------------------------------------------*/ +/** @defgroup FLASH_Private_Functions FLASH Private Functions + * @{ + */ +HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_FLASH_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_flash_ex.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_flash_ex.h new file mode 100644 index 0000000000..17e1bf094e --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_flash_ex.h @@ -0,0 +1,998 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_flash_ex.h + * @author MCD Application Team + * @brief Header file of FLASH HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_FLASH_EX_H +#define STM32H5xx_HAL_FLASH_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup FLASHEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup FLASHEx_Exported_Types FLASHEx Exported Types + * @{ + */ + +/** + * @brief FLASH Erase structure definition + */ +typedef struct +{ + uint32_t TypeErase; /*!< Mass erase or sector Erase. + This parameter can be a value of @ref FLASH_Type_Erase */ + + uint32_t Banks; /*!< Select banks to erase when Mass erase is enabled. + This parameter can be a value of @ref FLASH_Banks + (FLASH_BANK_BOTH should be used only for mass erase) */ + + uint32_t Sector; /*!< Initial FLASH sector to erase when Mass erase is disabled + This parameter can be a value of @ref FLASH_Sectors */ + + uint32_t NbSectors; /*!< Number of sectors to be erased. + This parameter can be a value between 1 and (max number of sectors in the bank - + value of initial sector)*/ +} FLASH_EraseInitTypeDef; + + +/** + * @brief FLASH Option Bytes Program structure definition + */ +typedef struct +{ + uint32_t OptionType; /*!< Option byte to be configured. + This parameter can be a value of @ref FLASH_Option_Type */ + + uint32_t ProductState; /*!< Set the product state. + This parameter can be a value of @ref FLASH_OB_Product_State */ + + uint32_t USERType; /*!< Select the User Option Byte(s) to be configured (used for OPTIONBYTE_USER). + This parameter can be a combination of @ref FLASH_OB_USER_Type */ + + uint32_t USERConfig; /*!< Value of the User Option Byte (used for OPTIONBYTE_USER). + This parameter can be a combination of @ref FLASH_OB_USER_BOR_LEVEL, + @ref FLASH_OB_USER_BORH_EN, @ref FLASH_OB_USER_IWDG_SW, + @ref FLASH_OB_USER_WWDG_SW, @ref FLASH_OB_USER_nRST_STOP, + @ref FLASH_OB_USER_nRST_STANDBY, @ref FLASH_OB_USER_IO_VDD_HSLV, + @ref FLASH_OB_USER_IO_VDDIO2_HSLV, @ref FLASH_OB_USER_IWDG_STOP, + @ref FLASH_OB_USER_IWDG_STANDBY, @ref FLASH_OB_USER_BOOT_UBE, + @ref FLASH_OB_USER_SWAP_BANK */ + + uint32_t USERConfig2; /*!< Value of the User Option Byte (used for OPTIONBYTE_USER). + This parameter can be a combination of @ref FLASH_OB_USER_SRAM1_3_RST, + @ref FLASH_OB_USER_SRAM2_RST, @ref FLASH_OB_USER_BKPRAM_ECC, + @ref FLASH_OB_USER_SRAM3_ECC, @ref FLASH_OB_USER_SRAM2_ECC, + @ref FLASH_OB_USER_SRAM1_RST, @ref FLASH_OB_USER_SRAM1_ECC, + @ref FLASH_OB_USER_TZEN */ + + uint32_t Banks; /*!< Select banks for WRP , HDP and secure area configuration. + This parameter must be a value of @ref FLASH_Banks */ + + uint32_t WRPState; /*!< Write protection activation or deactivation. + This parameter can be a value of @ref FLASH_WRP_State */ + + uint32_t WRPSector; /*!< Specifies the sector(s) to be write protected. + The value of this parameter depend on device used within the same series */ + + uint32_t BootConfig; /*!< Specifies if the Boot Address to be configured: secure or non-secure. + This parameter must be a value of @ref FLASH_OB_BOOT_CONFIG enumeration */ + + uint32_t BootAddr; /*!< Boot address (used for OPTIONBYTE_BOOTADDR). + This parameter must be a value between 0x0 and 0xFFFFFF00 */ + + uint32_t BootLock; /*!< Configuration of the boot lock (used for OPTIONBYTE_BOOT_LOCK). + This parameter must be a value of @ref FLASH_OB_BOOT_LOCK */ + + uint32_t OTPBlockLock; /*!< Specifies the OTP block(s) to be locked. + This parameter must be a value of @ref FLASH_OTP_Blocks */ + + uint32_t HDPStartSector; /*!< Start sector of HDP area (used for OPTIONBYTE_HDP). + This parameter must be a value between 0 and (max number of sectors in the bank - 1) */ + + uint32_t HDPEndSector; /*!< End sector of HDP area (used for OPTIONBYTE_HDP). + This parameter must be a value between 0 and (max number of sectors in the bank - 1) */ + + uint32_t EDATASize; /*!< Specifies the number of Flash high-cycle sectors. + This parameter must be a value between 0 and 8 (sectors) */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + uint32_t WMSecStartSector; /*!< Start sector of secure area (used for OPTIONBYTE_WMSEC). + This parameter must be a value between 0 and (max number of sectors in the bank - 1)*/ + uint32_t WMSecEndSector; /*!< End sector of secure area (used for OPTIONBYTE_WMSEC). + This parameter must be a value between 0 and (max number of sectors in the bank - 1)*/ +#endif /* __ARM_FEATURE_CMSE */ + +} FLASH_OBProgramInitTypeDef; + +/** + * @brief FLASHEx Block-based attributes structure definition + */ +typedef struct +{ + uint32_t Bank; /*!< Selection of the associated bank of Block-based Area. + This parameter must be a value of @ref FLASH_Banks */ + uint32_t BBAttributesType; /*!< Block-Based Attributes type. + This parameter must be a value of @ref FLASH_BB_Attributes + */ + uint32_t BBAttributes_array[FLASH_BLOCKBASED_NB_REG]; /*!< Each bit specifies the block-based attribute configuration + of a sector: + 0 means sector non-protected, 1 means sector protected. + Protection (secure or privilege) depends on + BBAttributesType value */ +} FLASH_BBAttributesTypeDef; + +/** + * @brief FLASHEx Operation structure definition + */ +typedef struct +{ + uint32_t OperationType; /*!< Flash operation Type. + This parameter must be a value of @ref FLASH_Operation_Type */ + uint32_t FlashArea; /*!< Flash operation memory area. + This parameter must be a value of @ref FLASH_Operation_Area */ + uint32_t Address; /*!< Flash operation Address offset. + This parameter is given by bank, and must be a value between 0x0 and 0xFFFF0 */ +} FLASH_OperationTypeDef; + +/** + * @brief FLASH HDP Extension structure definition + */ +typedef struct +{ + uint32_t Banks; /*!< Selection of the associated bank of HDP Area. + This parameter must be a value of @ref FLASH_Banks */ + uint32_t NbSectors; /*!< Number of sectors to be HDP extended. + This parameter can be a value between 1 and max number of sectors in the bank */ +} FLASH_HDPExtensionTypeDef; + +/** + * @} + */ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup FLASHEx_Exported_Constants FLASHEx Exported Constants + * @{ + */ + +/** @defgroup FLASH_Type_Erase FLASH Type Erase + * @{ + */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define FLASH_TYPEERASE_SECTORS FLASH_CR_SER /*!< Secure flash sectors + erase activation */ +#define FLASH_TYPEERASE_SECTORS_NS (FLASH_CR_SER | FLASH_NON_SECURE_MASK) /*!< Non-secure flash + sectors erase activation */ +#define FLASH_TYPEERASE_MASSERASE (FLASH_CR_BER | FLASH_CR_MER) /*!< Secure flash mass erase + activation */ +#define FLASH_TYPEERASE_MASSERASE_NS (FLASH_CR_BER | FLASH_CR_MER | FLASH_NON_SECURE_MASK) /*!< Non-secure flash mass + erase activation */ +#if defined (FLASH_SR_OBKERR) +#define FLASH_TYPEERASE_OBK_ALT FLASH_OBKCFGR_ALT_SECT_ERASE /*!< Flash OBK erase + activation */ +#endif /* FLASH_SR_OBKERR */ +#else +#define FLASH_TYPEERASE_SECTORS FLASH_CR_SER /*!< Flash sectors erase + activation */ +#define FLASH_TYPEERASE_MASSERASE (FLASH_CR_BER | FLASH_CR_MER) /*!< Flash mass erase + activation */ +#if defined (FLASH_SR_OBKERR) +#define FLASH_TYPEERASE_OBK_ALT (FLASH_OBKCFGR_ALT_SECT_ERASE | FLASH_NON_SECURE_MASK) /*!< Flash OBK erase + activation */ +#endif /* FLASH_SR_OBKERR */ +#endif /* __ARM_FEATURE_CMSE */ +/** + * @} + */ + +/** @defgroup FLASH_Option_Type FLASH Option Type + * @{ + */ +#define OPTIONBYTE_WRP 0x0001U /*!< WRP option byte configuration */ +#define OPTIONBYTE_PROD_STATE 0x0002U /*!< RDP option byte configuration */ +#define OPTIONBYTE_USER 0x0004U /*!< USER option byte configuration */ +#define OPTIONBYTE_BOOTADDR 0x0008U /*!< BOOT address option byte configuration */ +#define OPTIONBYTE_BOOT_LOCK 0x0010U /*!< Boot lock option byte configuration */ +#define OPTIONBYTE_OTP_LOCK 0x0020U /*!< OTP Lock option byte configuration */ +#define OPTIONBYTE_HDP 0x0040U /*!< Hide Protection area option byte configuration */ +#if defined (FLASH_EDATAR_EDATA_EN) +#define OPTIONBYTE_EDATA 0x0080U /*!< Flash high-cycle data area option byte configuration */ +#endif /* FLASH_EDATAR_EDATA_EN */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define OPTIONBYTE_WMSEC 0x0200U /*!< Watermark-based secure area option byte configuration */ +#endif /* __ARM_FEATURE_CMSE */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define OPTIONBYTE_ALL (OPTIONBYTE_WRP | OPTIONBYTE_PROD_STATE | OPTIONBYTE_USER |\ + OPTIONBYTE_BOOTADDR | OPTIONBYTE_BOOT_LOCK | OPTIONBYTE_OTP_LOCK |\ + OPTIONBYTE_HDP | OPTIONBYTE_EDATA | OPTIONBYTE_WMSEC) /*!< All option +byte configuration */ +#else +#if defined (FLASH_EDATAR_EDATA_EN) +#define OPTIONBYTE_ALL (OPTIONBYTE_WRP | OPTIONBYTE_PROD_STATE | OPTIONBYTE_USER |\ + OPTIONBYTE_BOOTADDR | OPTIONBYTE_BOOT_LOCK | OPTIONBYTE_OTP_LOCK |\ + OPTIONBYTE_HDP | OPTIONBYTE_EDATA) /*!< All option byte configuration */ +#else +#define OPTIONBYTE_ALL (OPTIONBYTE_WRP | OPTIONBYTE_PROD_STATE | OPTIONBYTE_USER |\ + OPTIONBYTE_BOOTADDR | OPTIONBYTE_BOOT_LOCK | OPTIONBYTE_OTP_LOCK |\ + OPTIONBYTE_HDP) /*!< All option byte configuration */ +#endif /* FLASH_EDATAR_EDATA_EN */ +#endif /* __ARM_FEATURE_CMSE */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_Type FLASH OB USER Type + * @{ + */ +#define OB_USER_BOR_LEV 0x00000001U /*!< BOR reset Level */ +#define OB_USER_BORH_EN 0x00000002U /*!< BOR high enable status */ +#define OB_USER_IWDG_SW 0x00000004U /*!< Independent watchdog selection */ +#define OB_USER_WWDG_SW 0x00000008U /*!< Window watchdog selection */ +#define OB_USER_NRST_STOP 0x00000010U /*!< Reset generated when entering the stop mode */ +#define OB_USER_NRST_STDBY 0x00000020U /*!< Reset generated when entering the standby mode */ +#define OB_USER_IO_VDD_HSLV 0x00000040U /*!< High speed IO at low voltage configuration bit */ +#define OB_USER_IO_VDDIO2_HSLV 0x00000080U /*!< High speed IO2 at low voltage configuration bit */ +#define OB_USER_IWDG_STOP 0x00000100U /*!< Independent watchdog counter freeze in stop mode */ +#define OB_USER_IWDG_STDBY 0x00000200U /*!< Independent watchdog counter freeze in standby mode */ +#if defined (FLASH_OPTSR_BOOT_UBE) +#define OB_USER_BOOT_UBE 0x00000400U /*!< Unique Boot entry */ +#endif /* FLASH_OPTSR_BOOT_UBE */ +#define OB_USER_SWAP_BANK 0x00000800U /*!< Swap banks */ + +#if defined (FLASH_OPTSR2_SRAM1_3_RST) +#define OB_USER_SRAM1_3_RST 0x00001000U /*!< SRAM1 and SRAM3 erase upon system reset */ +#endif /* FLASH_OPTSR2_SRAM1_3_RST */ +#if defined (FLASH_OPTSR2_SRAM1_RST) +#define OB_USER_SRAM1_RST 0x00001000U /*!< SRAM1 Erase when system reset */ +#endif /* FLASH_OPTSR2_SRAM1_RST */ +#define OB_USER_SRAM2_RST 0x00002000U /*!< SRAM2 Erase when system reset */ +#define OB_USER_BKPRAM_ECC 0x00004000U /*!< Backup RAM ECC detection and correction enable */ +#define OB_USER_SRAM3_ECC 0x00008000U /*!< SRAM3 ECC detection and correction enable */ +#define OB_USER_SRAM2_ECC 0x00010000U /*!< SRAM2 ECC detection and correction enable */ +#define OB_USER_SRAM1_ECC 0x00020000U /*!< SRAM1 ECC detection and correction enable */ +#if defined (FLASH_OPTSR2_TZEN) +#define OB_USER_TZEN 0x00080000U /*!< Global TrustZone security enable */ +#endif /* FLASH_OPTSR2_TZEN */ + +#if defined (FLASH_OPTSR2_SRAM1_3_RST) && defined (FLASH_OPTSR_BOOT_UBE) +#define OB_USER_ALL (OB_USER_BOR_LEV | OB_USER_BORH_EN | OB_USER_IWDG_SW |\ + OB_USER_WWDG_SW | OB_USER_NRST_STOP | OB_USER_NRST_STDBY |\ + OB_USER_IO_VDD_HSLV | OB_USER_IO_VDDIO2_HSLV | OB_USER_IWDG_STOP |\ + OB_USER_IWDG_STDBY | OB_USER_BOOT_UBE | OB_USER_SWAP_BANK |\ + OB_USER_SRAM1_3_RST | OB_USER_SRAM2_RST | OB_USER_BKPRAM_ECC |\ + OB_USER_SRAM3_ECC | OB_USER_SRAM2_ECC | OB_USER_TZEN) +#else +#define OB_USER_ALL (OB_USER_BOR_LEV | OB_USER_BORH_EN | OB_USER_IWDG_SW |\ + OB_USER_WWDG_SW | OB_USER_NRST_STOP | OB_USER_NRST_STDBY |\ + OB_USER_IO_VDD_HSLV | OB_USER_IO_VDDIO2_HSLV | OB_USER_IWDG_STOP |\ + OB_USER_IWDG_STDBY | OB_USER_SWAP_BANK | OB_USER_SRAM1_RST |\ + OB_USER_SRAM2_RST | OB_USER_BKPRAM_ECC | OB_USER_SRAM3_ECC |\ + OB_USER_SRAM2_ECC | OB_USER_SRAM1_ECC) +#endif /* FLASH_OPTSR2_SRAM1_3_RST && FLASH_OPTSR_BOOT_UBE */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_BOR_LEVEL FLASH BOR Reset Level + * @{ + */ +#define OB_BOR_LEVEL_1 FLASH_OPTSR_BOR_LEV_0 /*!< Reset level 1 threshold */ +#define OB_BOR_LEVEL_2 FLASH_OPTSR_BOR_LEV_1 /*!< Reset level 2 threshold */ +#define OB_BOR_LEVEL_3 (FLASH_OPTSR_BOR_LEV_1 | FLASH_OPTSR_BOR_LEV_0) /*!< Reset level 3 threshold */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_BORH_EN FLASH BOR High Enable Status + * @{ + */ +#define OB_BORH_DISABLE 0x00000000U /*!< BOR high status bit disabled */ +#define OB_BORH_ENABLE FLASH_OPTSR_BORH_EN /*!< BOR high status bit enabled */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_IWDG_SW FLASH Option Bytes User IWDG Type + * @{ + */ +#define OB_IWDG_HW 0x00000000U /*!< Hardware independent watchdog */ +#define OB_IWDG_SW FLASH_OPTSR_IWDG_SW /*!< Software independent watchdog */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_WWDG_SW FLASH Option Bytes User WWDG Type + * @{ + */ +#define OB_WWDG_HW 0x00000000U /*!< Hardware window watchdog */ +#define OB_WWDG_SW FLASH_OPTSR_WWDG_SW /*!< Software window watchdog */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_nRST_STOP FLASH Option Bytes nRST_STOP + * @{ + */ +#define OB_STOP_RST 0x00000000U /*!< Reset generated when entering in stop mode */ +#define OB_STOP_NORST FLASH_OPTSR_NRST_STOP /*!< No reset generated when entering in stop mode */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_nRST_STANDBY FLASH Option Bytes nRST_STDBY + * @{ + */ +#define OB_STANDBY_RST 0x00000000U /*!< Reset generated when entering in standby mode */ +#define OB_STANDBY_NORST FLASH_OPTSR_NRST_STDBY /*!< No reset generated when entering in standby mode */ +/** + * @} + */ + +/** @defgroup FLASH_OB_Product_State FLASH Product State + * @{ + */ +#define OB_PROD_STATE_OPEN (0xEDU << FLASH_OPTSR_PRODUCT_STATE_Pos) +#define OB_PROD_STATE_PROVISIONING (0x17U << FLASH_OPTSR_PRODUCT_STATE_Pos) +#define OB_PROD_STATE_IROT_PROVISIONED (0x2EU << FLASH_OPTSR_PRODUCT_STATE_Pos) +#define OB_PROD_STATE_TZ_CLOSED (0xC6U << FLASH_OPTSR_PRODUCT_STATE_Pos) +#define OB_PROD_STATE_CLOSED (0x72U << FLASH_OPTSR_PRODUCT_STATE_Pos) +#define OB_PROD_STATE_LOCKED (0x5CU << FLASH_OPTSR_PRODUCT_STATE_Pos) +#define OB_PROD_STATE_REGRESSION (0x9AU << FLASH_OPTSR_PRODUCT_STATE_Pos) +#define OB_PROD_STATE_NS_REGRESSION (0xA3U << FLASH_OPTSR_PRODUCT_STATE_Pos) +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_IO_VDD_HSLV FLASH Option Bytes VDD IO HSLV + * @{ + */ +#define OB_IO_VDD_HSLV_DISABLE 0x00000000U /*!< High-speed IO at low VDD voltage feature disabled */ +#define OB_IO_VDD_HSLV_ENABLE FLASH_OPTSR_IO_VDD_HSLV /*!< High-speed IO at low VDD voltage feature enabled */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_IO_VDDIO2_HSLV FLASH Option Bytes VDDIO2 IO HSLV + * @{ + */ +#define OB_IO_VDDIO2_HSLV_DISABLE 0x00000000U /*!< High-speed IO at low VDDIO2 voltage feature + disabled */ +#define OB_IO_VDDIO2_HSLV_ENABLE FLASH_OPTSR_IO_VDDIO2_HSLV /*!< High-speed IO at low VDDIO2 voltage feature + enabled */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_IWDG_STOP FLASH IWDG Counter Freeze in STOP + * @{ + */ +#define OB_IWDG_STOP_FREEZE 0x00000000U /*!< IWDG counter frozen in STOP mode */ +#define OB_IWDG_STOP_ACTIVE FLASH_OPTSR_IWDG_STOP /*!< IWDG counter active in STOP mode */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_IWDG_STANDBY FLASH IWDG Counter Freeze in STANDBY + * @{ + */ +#define OB_IWDG_STDBY_FREEZE 0x00000000U /*!< IWDG counter frozen in STANDBY mode */ +#define OB_IWDG_STDBY_ACTIVE FLASH_OPTSR_IWDG_STDBY /*!< IWDG counter active in STANDBY mode */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_BOOT_UBE FLASH OB Boot UBE + * @{ + */ +#if defined (FLASH_OPTSR_BOOT_UBE) +#define OB_UBE_OEM_IROT (0xB4U << FLASH_OPTSR_BOOT_UBE_Pos) /*!< OEM-iRoT (user flash) selected */ +#define OB_UBE_ST_IROT (0xC3U << FLASH_OPTSR_BOOT_UBE_Pos) /*!< ST-iRoT (system flash) selected */ +#endif /* FLASH_OPTSR_BOOT_UBE */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_SWAP_BANK FLASH OB SWAP BANK + * @{ + */ +#define OB_SWAP_BANK_DISABLE 0x00000000U /*!< Bank swap disabled */ +#define OB_SWAP_BANK_ENABLE FLASH_OPTSR_SWAP_BANK /*!< Bank swap enabled */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_SRAM1_3_RST FLASH Option Bytes SRAM1_3 Erase On Reset + * @{ + */ +#if defined (FLASH_OPTSR2_SRAM1_3_RST) +#define OB_SRAM1_3_RST_ERASE 0x00000000U /*!< SRAM1 and SRAM3 erased when a system reset occurs */ +#define OB_SRAM1_3_RST_NOT_ERASE FLASH_OPTSR2_SRAM1_3_RST /*!< SRAM1 and SRAM3 are not erased when a system reset + occurs */ +#endif /* FLASH_OPTSR2_SRAM1_3_RST */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_SRAM1_RST FLASH Option Bytes SRAM1 Erase On Reset + * @{ + */ +#if defined (FLASH_OPTSR2_SRAM1_RST) +#define OB_SRAM1_RST_ERASE 0x00000000U /*!< SRAM1 erased when a system reset occurs */ +#define OB_SRAM1_RST_NOT_ERASE FLASH_OPTSR2_SRAM1_RST /*!< SRAM1 is not erased when a system reset occurs */ +#endif /* FLASH_OPTSR2_SRAM1_RST */ +/** + * @} + */ + + +/** @defgroup FLASH_OB_USER_SRAM2_RST FLASH Option Bytes SRAM2 Erase On Reset + * @{ + */ +#define OB_SRAM2_RST_ERASE 0x00000000U /*!< SRAM2 erased when a system reset occurs */ +#define OB_SRAM2_RST_NOT_ERASE FLASH_OPTSR2_SRAM2_RST /*!< SRAM2 is not erased when a system reset occurs */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_BKPRAM_ECC FLASH Option Bytes User BKPRAM ECC check + * @{ + */ +#define OB_BKPRAM_ECC_ENABLE 0x00000000U /*!< BKPRAM ECC check enable */ +#define OB_BKPRAM_ECC_DISABLE FLASH_OPTSR2_BKPRAM_ECC /*!< BKPRAM ECC check disable */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_SRAM3_ECC FLASH Option Bytes User SRAM3 ECC check + * @{ + */ +#if defined (FLASH_OPTSR2_SRAM3_ECC) +#define OB_SRAM3_ECC_ENABLE 0x00000000U /*!< SRAM3 ECC check enable */ +#define OB_SRAM3_ECC_DISABLE FLASH_OPTSR2_SRAM3_ECC /*!< SRAM3 ECC check disable */ +#endif /* FLASH_OPTSR2_SRAM3_ECC */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_SRAM2_ECC FLASH Option Bytes User SRAM2 ECC check + * @{ + */ +#define OB_SRAM2_ECC_ENABLE 0x00000000U /*!< SRAM2 ECC check enable */ +#define OB_SRAM2_ECC_DISABLE FLASH_OPTSR2_SRAM2_ECC /*!< SRAM2 ECC check disable */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_SRAM1_ECC FLASH Option Bytes User SRAM1 ECC check + * @{ + */ +#if defined (FLASH_OPTSR2_SRAM1_ECC) +#define OB_SRAM1_ECC_ENABLE 0x00000000U /*!< SRAM1 ECC check enable */ +#define OB_SRAM1_ECC_DISABLE FLASH_OPTSR2_SRAM1_ECC /*!< SRAM1 ECC check disable */ +#endif /* FLASH_OPTSR2_SRAM1_ECC */ +/** + * @} + */ + +/** @defgroup FLASH_OB_USER_TZEN FLASH Option Bytes Global TrustZone + * @{ + */ +#if defined (FLASH_OPTSR2_TZEN) +#define OB_TZEN_DISABLE (0xC3U << FLASH_OPTSR2_TZEN_Pos) /*!< Global TrustZone security disabled */ +#define OB_TZEN_ENABLE (0xB4U << FLASH_OPTSR2_TZEN_Pos) /*!< Global TrustZone security enabled */ +#endif /* FLASH_OPTSR2_TZEN */ +/** + * @} + */ + +/** @defgroup FLASH_Banks FLASH Banks + * @{ + */ +#define FLASH_BANK_1 0x00000001U /*!< Bank 1 */ +#define FLASH_BANK_2 0x00000002U /*!< Bank 2 */ +#define FLASH_BANK_BOTH (FLASH_BANK_1 | FLASH_BANK_2) /*!< Bank1 and Bank2 */ +/** + * @} + */ + +/** @defgroup FLASH_OB_Write_Protection_Sectors FLASH Option Bytes Write Protection Sectors + * @{ + */ +#if (FLASH_SECTOR_NB == 128) +#define OB_WRP_SECTOR_0TO3 0x00000001U /*!< Write protection of Sector0 to Sector3 */ +#define OB_WRP_SECTOR_4TO7 0x00000002U /*!< Write protection of Sector4 to Sector7 */ +#define OB_WRP_SECTOR_8TO11 0x00000004U /*!< Write protection of Sector8 to Sector11 */ +#define OB_WRP_SECTOR_12TO15 0x00000008U /*!< Write protection of Sector12 to Sector15 */ +#define OB_WRP_SECTOR_16TO19 0x00000010U /*!< Write protection of Sector16 to Sector19 */ +#define OB_WRP_SECTOR_20TO23 0x00000020U /*!< Write protection of Sector20 to Sector23 */ +#define OB_WRP_SECTOR_24TO27 0x00000040U /*!< Write protection of Sector24 to Sector27 */ +#define OB_WRP_SECTOR_28TO31 0x00000080U /*!< Write protection of Sector28 to Sector31 */ +#define OB_WRP_SECTOR_32TO35 0x00000100U /*!< Write protection of Sector32 to Sector35 */ +#define OB_WRP_SECTOR_36TO39 0x00000200U /*!< Write protection of Sector36 to Sector39 */ +#define OB_WRP_SECTOR_40TO43 0x00000400U /*!< Write protection of Sector40 to Sector43 */ +#define OB_WRP_SECTOR_44TO47 0x00000800U /*!< Write protection of Sector44 to Sector47 */ +#define OB_WRP_SECTOR_48TO51 0x00001000U /*!< Write protection of Sector48 to Sector51 */ +#define OB_WRP_SECTOR_52TO55 0x00002000U /*!< Write protection of Sector52 to Sector55 */ +#define OB_WRP_SECTOR_56TO59 0x00004000U /*!< Write protection of Sector56 to Sector59 */ +#define OB_WRP_SECTOR_60TO63 0x00008000U /*!< Write protection of Sector60 to Sector63 */ +#define OB_WRP_SECTOR_64TO67 0x00010000U /*!< Write protection of Sector64 to Sector67 */ +#define OB_WRP_SECTOR_68TO71 0x00020000U /*!< Write protection of Sector68 to Sector71 */ +#define OB_WRP_SECTOR_72TO75 0x00040000U /*!< Write protection of Sector72 to Sector75 */ +#define OB_WRP_SECTOR_76TO79 0x00080000U /*!< Write protection of Sector76 to Sector79 */ +#define OB_WRP_SECTOR_80TO83 0x00100000U /*!< Write protection of Sector80 to Sector83 */ +#define OB_WRP_SECTOR_84TO87 0x00200000U /*!< Write protection of Sector84 to Sector87 */ +#define OB_WRP_SECTOR_88TO91 0x00400000U /*!< Write protection of Sector88 to Sector91 */ +#define OB_WRP_SECTOR_92TO95 0x00800000U /*!< Write protection of Sector92 to Sector95 */ +#define OB_WRP_SECTOR_96TO99 0x01000000U /*!< Write protection of Sector96 to Sector99 */ +#define OB_WRP_SECTOR_100TO103 0x02000000U /*!< Write protection of Sector100 to Sector103 */ +#define OB_WRP_SECTOR_104TO107 0x04000000U /*!< Write protection of Sector104 to Sector107 */ +#define OB_WRP_SECTOR_108TO111 0x08000000U /*!< Write protection of Sector108 to Sector111 */ +#define OB_WRP_SECTOR_112TO115 0x10000000U /*!< Write protection of Sector112 to Sector115 */ +#define OB_WRP_SECTOR_116TO119 0x20000000U /*!< Write protection of Sector116 to Sector119 */ +#define OB_WRP_SECTOR_120TO123 0x40000000U /*!< Write protection of Sector120 to Sector123 */ +#define OB_WRP_SECTOR_124TO127 0x80000000U /*!< Write protection of Sector124 to Sector127 */ +#define OB_WRP_SECTOR_ALL 0xFFFFFFFFU /*!< Write protection of all Sectors */ +#else +#define OB_WRP_SECTOR_0 0x00000001U /*!< Write protection of Sector0 */ +#define OB_WRP_SECTOR_1 0x00000002U /*!< Write protection of Sector1 */ +#define OB_WRP_SECTOR_2 0x00000004U /*!< Write protection of Sector2 */ +#define OB_WRP_SECTOR_3 0x00000008U /*!< Write protection of Sector3 */ +#define OB_WRP_SECTOR_4 0x00000010U /*!< Write protection of Sector4 */ +#define OB_WRP_SECTOR_5 0x00000020U /*!< Write protection of Sector5 */ +#define OB_WRP_SECTOR_6 0x00000040U /*!< Write protection of Sector6 */ +#define OB_WRP_SECTOR_7 0x00000080U /*!< Write protection of Sector7 */ +#define OB_WRP_SECTOR_ALL 0x000000FFU /*!< Write protection of all Sectors */ +#endif /* (FLASH_SECTOR_NB == 128) */ +/** + * @} + */ + +/** @defgroup FLASH_Programming_Delay FLASH Programming Delay + * @{ + */ +#define FLASH_PROGRAMMING_DELAY_0 0x00000000U /*!< programming delay set for Flash running at 70 MHz or + below */ +#define FLASH_PROGRAMMING_DELAY_1 FLASH_ACR_WRHIGHFREQ_0 /*!< programming delay set for Flash running between 70 MHz + and 185 MHz */ +#define FLASH_PROGRAMMING_DELAY_2 FLASH_ACR_WRHIGHFREQ_1 /*!< programming delay set for Flash running between 185 MHz + and 225 MHz */ +#define FLASH_PROGRAMMING_DELAY_3 FLASH_ACR_WRHIGHFREQ /*!< programming delay set for Flash at startup */ +/** + * @} + */ + +/** @defgroup FLASH_OTP_Blocks FLASH OTP blocks + * @{ + */ +#define FLASH_OTP_BLOCK_0 0x00000001U /*!< OTP Block0 */ +#define FLASH_OTP_BLOCK_1 0x00000002U /*!< OTP Block1 */ +#define FLASH_OTP_BLOCK_2 0x00000004U /*!< OTP Block2 */ +#define FLASH_OTP_BLOCK_3 0x00000008U /*!< OTP Block3 */ +#define FLASH_OTP_BLOCK_4 0x00000010U /*!< OTP Block4 */ +#define FLASH_OTP_BLOCK_5 0x00000020U /*!< OTP Block5 */ +#define FLASH_OTP_BLOCK_6 0x00000040U /*!< OTP Block6 */ +#define FLASH_OTP_BLOCK_7 0x00000080U /*!< OTP Block7 */ +#define FLASH_OTP_BLOCK_8 0x00000100U /*!< OTP Block8 */ +#define FLASH_OTP_BLOCK_9 0x00000200U /*!< OTP Block9 */ +#define FLASH_OTP_BLOCK_10 0x00000400U /*!< OTP Block10 */ +#define FLASH_OTP_BLOCK_11 0x00000800U /*!< OTP Block11 */ +#define FLASH_OTP_BLOCK_12 0x00001000U /*!< OTP Block12 */ +#define FLASH_OTP_BLOCK_13 0x00002000U /*!< OTP Block13 */ +#define FLASH_OTP_BLOCK_14 0x00004000U /*!< OTP Block14 */ +#define FLASH_OTP_BLOCK_15 0x00008000U /*!< OTP Block15 */ +#define FLASH_OTP_BLOCK_16 0x00010000U /*!< OTP Block16 */ +#define FLASH_OTP_BLOCK_17 0x00020000U /*!< OTP Block17 */ +#define FLASH_OTP_BLOCK_18 0x00040000U /*!< OTP Block18 */ +#define FLASH_OTP_BLOCK_19 0x00080000U /*!< OTP Block19 */ +#define FLASH_OTP_BLOCK_20 0x00100000U /*!< OTP Block20 */ +#define FLASH_OTP_BLOCK_21 0x00200000U /*!< OTP Block21 */ +#define FLASH_OTP_BLOCK_22 0x00400000U /*!< OTP Block22 */ +#define FLASH_OTP_BLOCK_23 0x00800000U /*!< OTP Block23 */ +#define FLASH_OTP_BLOCK_24 0x01000000U /*!< OTP Block24 */ +#define FLASH_OTP_BLOCK_25 0x02000000U /*!< OTP Block25 */ +#define FLASH_OTP_BLOCK_26 0x04000000U /*!< OTP Block26 */ +#define FLASH_OTP_BLOCK_27 0x08000000U /*!< OTP Block27 */ +#define FLASH_OTP_BLOCK_28 0x10000000U /*!< OTP Block28 */ +#define FLASH_OTP_BLOCK_29 0x20000000U /*!< OTP Block29 */ +#define FLASH_OTP_BLOCK_30 0x40000000U /*!< OTP Block30 */ +#define FLASH_OTP_BLOCK_31 0x80000000U /*!< OTP Block31 */ +#define FLASH_OTP_BLOCK_ALL 0xFFFFFFFFU /*!< OTP All Blocks */ +/** + * @} + */ + +/** @defgroup FLASH_WRP_State FLASH WRP State + * @{ + */ +#define OB_WRPSTATE_DISABLE 0x00000000U /*!< Disable the write protection of the desired flash sectors */ +#define OB_WRPSTATE_ENABLE 0x00000001U /*!< Enable the write protection of the desired flash sectors */ +/** + * @} + */ + +/** @defgroup FLASH_OB_BOOT_CONFIG FLASH Option Bytes Boot configuration + * @{ + */ +#define OB_BOOT_NS 0x00000001U /*!< Non-secure boot address */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define OB_BOOT_SEC 0x00000002U /*!< Secure boot address */ +#endif /* __ARM_FEATURE_CMSE */ +/** + * @} + */ + +/** @defgroup FLASH_OB_BOOT_LOCK FLASH Option Bytes Boot Lock + * @{ + */ +#define OB_BOOT_LOCK_DISABLE 0xC3U /*!< Boot lock disable */ +#define OB_BOOT_LOCK_ENABLE 0xB4U /*!< Boot lock enable */ +/** + * @} + */ + +/** @defgroup FLASH_BB_Attributes FLASH Block-Base Attributes + * @{ + */ +#define FLASH_BB_SEC 0x01U /*!< Flash Block-Based Security Attributes */ +#define FLASH_BB_PRIV 0x02U /*!< Flash Block-Based Privilege Attributes */ +/** + * @} + */ + +/** @defgroup FLASH_PRIV_MODE FLASH privilege mode + * @{ + */ +#define FLASH_NSPRIV_GRANTED 0x00000000U /*!< access to non-secure Flash registers is granted to privileged + or unprivileged access */ +#define FLASH_NSPRIV_DENIED FLASH_PRIVCFGR_NSPRIV /*!< access to non-secure Flash registers is denied to + non-privilege access */ + +#define FLASH_SPRIV_GRANTED 0x00000000U /*!< access to secure Flash registers is granted to privileged or + unprivileged access */ +#if defined (FLASH_PRIVCFGR_SPRIV) +#define FLASH_SPRIV_DENIED FLASH_PRIVCFGR_SPRIV /*!< access to secure Flash registers is denied to non-privilege + access */ +#endif /* FLASH_PRIVCFGR_SPRIV */ +/** + * @} + */ + +#if defined (FLASH_SR_OBKERR) +/** @defgroup FLASH_OBK_SWAP_Offset FLASH OBK Swap Offset + * @{ + */ +#define FLASH_OBK_SWAP_OFFSET_NO_DATA 0x000U /*!< No data will be copied from current to alternate OBK */ +#define FLASH_OBK_SWAP_OFFSET_HDPL0 0x010U /*!< HDPL0 data will be copied from current to alternate OBK */ +#define FLASH_OBK_SWAP_OFFSET_HDPL1 0x090U /*!< HDPL0/1 data will be copied from current to alternate OBK */ +#define FLASH_OBK_SWAP_OFFSET_HDPL2 0x0C0U /*!< HDPL0/1/2 data will be copied from current to alternate OBK */ +#define FLASH_OBK_SWAP_OFFSET_HDPL3_S 0x180U /*!< HDPL0/1/2/3_S data will be copied from current to alternate + OBK */ +#define FLASH_OBK_SWAP_OFFSET_ALL 0x1FFU /*!< All OBK data (511) will be copied from current to alternate + OBK */ +/** + * @} + */ +#endif /* FLASH_SR_OBKERR */ + +/** @defgroup FLASH_Operation_Type FLASH Operation Type + * @{ + */ +#define FLASH_OPERATION_TYPE_NONE 00000000U /*!< No Flash operation */ +#define FLASH_OPERATION_TYPE_QUADWORD FLASH_OPSR_CODE_OP_0 /*!< Single write operation */ +#if defined (FLASH_SR_OBKERR) +#define FLASH_OPERATION_TYPE_OBKALTERASE FLASH_OPSR_CODE_OP_1 /*!< OBK alternate sector erase + operation */ +#endif /* FLASH_SR_OBKERR */ +#define FLASH_OPERATION_TYPE_SECTORERASE (FLASH_OPSR_CODE_OP_1 | FLASH_OPSR_CODE_OP_0) /*!< Sector erase operation */ +#define FLASH_OPERATION_TYPE_BANKERASE FLASH_OPSR_CODE_OP_2 /*!< Bank erase operation */ +#define FLASH_OPERATION_TYPE_MASSERASE (FLASH_OPSR_CODE_OP_2 | FLASH_OPSR_CODE_OP_0) /*!< Mass erase operation */ +#define FLASH_OPERATION_TYPE_OPTIONCHANGE (FLASH_OPSR_CODE_OP_2 | FLASH_OPSR_CODE_OP_1) /*!< Option change operation */ +#if defined (FLASH_SR_OBKERR) +#define FLASH_OPERATION_TYPE_OBKSWAP (FLASH_OPSR_CODE_OP_2 | FLASH_OPSR_CODE_OP_1 | FLASH_OPSR_CODE_OP_0) /*!< OBK + swap operation */ +#endif /* FLASH_SR_OBKERR */ +/** + * @} + */ + +/** @defgroup FLASH_Operation_Area FLASH Operation Area + * @{ + */ +#define FLASH_OPERATION_AREA_BANK_1 00000000U /*!< Operation in Flash Bank 1 */ +#define FLASH_OPERATION_AREA_BANK_2 FLASH_OPSR_BK_OP /*!< Operation in Flash Bank 2 */ +#define FLASH_OPERATION_AREA_SYSF FLASH_OPSR_SYSF_OP /*!< Operation in System Flash memory */ +#if defined (FLASH_EDATAR_EDATA_EN) +#define FLASH_OPERATION_AREA_DATA FLASH_OPSR_DATA_OP /*!< Operation in Flash high-cycle data area */ +#endif /* FLASH_EDATAR_EDATA_EN */ +#define FLASH_OPERATION_AREA_OTP FLASH_OPSR_OTP_OP /*!< Operation in Flash OTP area */ +/** + * @} + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** @defgroup SEC_INVERSION_CFG FLASH security inversion configuration + * @{ + */ +#define FLASH_INV_DISABLE 0x00000000U /*!< Security state of Flash is not inverted */ +#define FLASH_INV_ENABLE FLASH_CR_INV /*!< Security state of Flash is inverted */ +/** + * @} + */ +#endif /* __ARM_FEATURE_CMSE */ +/** + * @} + */ +/* Exported macros ------------------------------------------------------------*/ +/** @defgroup FLASHEx_Exported_Macros FLASHEx Exported Macros + * @{ + */ + +/** + * @brief Enable the FLASH prefetch buffer. + * @retval None + */ +#define __HAL_FLASH_PREFETCH_BUFFER_ENABLE() SET_BIT(FLASH->ACR, FLASH_ACR_PRFTEN) + +/** + * @brief Disable the FLASH prefetch buffer. + * @retval None + */ +#define __HAL_FLASH_PREFETCH_BUFFER_DISABLE() CLEAR_BIT(FLASH->ACR, FLASH_ACR_PRFTEN) + +/** + * @brief Enable the FLASH smart prefetch buffer. + * @retval None + */ +#define __HAL_FLASH_SMART_PREFETCH_BUFFER_ENABLE() SET_BIT(FLASH->ACR, FLASH_ACR_S_PRFTEN) + +/** + * @brief Disable the FLASH smart prefetch buffer. + * @retval None + */ +#define __HAL_FLASH_SMART_PREFETCH_BUFFER_DISABLE() CLEAR_BIT(FLASH->ACR, FLASH_ACR_S_PRFTEN) + +/** + * @brief Set the FLASH Programming Delay. + * @param __DELAY__ FLASH Programming Delay + * This parameter can be a value of @ref FLASH_Programming_Delay + * @retval none + */ +#define __HAL_FLASH_SET_PROGRAM_DELAY(__DELAY__) MODIFY_REG(FLASH->ACR, FLASH_ACR_WRHIGHFREQ, (__DELAY__)) + +/** + * @brief Get the FLASH Programming Delay. + * @retval FLASH Programming Delay + * This return value can be a value of @ref FLASH_Programming_Delay + */ +#define __HAL_FLASH_GET_PROGRAM_DELAY() READ_BIT(FLASH->ACR, FLASH_ACR_WRHIGHFREQ) + +/** + * @} + */ +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup FLASHEx_Exported_Functions + * @{ + */ + +/** @addtogroup FLASHEx_Exported_Functions_Group1 + * @{ + */ +/* Extension Erase and OB Program operation functions ******************************/ +HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError); +HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit); +HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit); +void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit); +#if defined (FLASH_SR_OBKERR) +HAL_StatusTypeDef HAL_FLASHEx_OBK_Unlock(void); +HAL_StatusTypeDef HAL_FLASHEx_OBK_Lock(void); +HAL_StatusTypeDef HAL_FLASHEx_OBK_Swap(uint32_t SwapOffset); +#endif /* FLASH_SR_OBKERR */ +void HAL_FLASHEx_GetOperation(FLASH_OperationTypeDef *pFlashOperation); +/** + * @} + */ + +/** @addtogroup FLASHEx_Exported_Functions_Group2 + * @{ + */ +/* Extension Protection configuration functions *************************************/ +HAL_StatusTypeDef HAL_FLASHEx_ConfigBBAttributes(FLASH_BBAttributesTypeDef *pBBAttributes); +void HAL_FLASHEx_GetConfigBBAttributes(FLASH_BBAttributesTypeDef *pBBAttributes); +void HAL_FLASHEx_ConfigPrivMode(uint32_t PrivMode); +uint32_t HAL_FLASHEx_GetPrivMode(void); +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +HAL_StatusTypeDef HAL_FLASHEx_ConfigSecInversion(uint32_t SecInvState); +uint32_t HAL_FLASHEx_GetSecInversion(void); +#endif /* __ARM_FEATURE_CMSE */ +HAL_StatusTypeDef HAL_FLASHEx_ConfigHDPExtension(const FLASH_HDPExtensionTypeDef *pHDPExtension); +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup FLASHEx_Private_Constants FLASHEx Private Constants + * @{ + */ +#define FLASH_TYPEPROGRAM_OB (0x00008000U | FLASH_NON_SECURE_MASK) /*!< Program Option Bytes operation type */ +/** + * @} + */ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup FLASHEx_Private_Macros FLASHEx Private Macros + * @{ + */ + +/** @defgroup FLASHEx_IS_FLASH_Definitions FLASHEx Private macros to check input parameters + * @{ + */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define IS_FLASH_TYPEERASE(VALUE) (((VALUE) == FLASH_TYPEERASE_SECTORS) || \ + ((VALUE) == FLASH_TYPEERASE_SECTORS_NS) || \ + ((VALUE) == FLASH_TYPEERASE_MASSERASE) || \ + ((VALUE) == FLASH_TYPEERASE_MASSERASE_NS) || \ + ((VALUE) == FLASH_TYPEERASE_OBK_ALT)) +#else +#if defined (FLASH_SR_OBKERR) +#define IS_FLASH_TYPEERASE(VALUE) (((VALUE) == FLASH_TYPEERASE_SECTORS) || \ + ((VALUE) == FLASH_TYPEERASE_MASSERASE) || \ + ((VALUE) == FLASH_TYPEERASE_OBK_ALT)) +#else +#define IS_FLASH_TYPEERASE(VALUE) (((VALUE) == FLASH_TYPEERASE_SECTORS) || \ + ((VALUE) == FLASH_TYPEERASE_MASSERASE)) +#endif /* FLASH_SR_OBKERR */ +#endif /* __ARM_FEATURE_CMSE */ + +#define IS_WRPSTATE(VALUE) (((VALUE) == OB_WRPSTATE_DISABLE) || \ + ((VALUE) == OB_WRPSTATE_ENABLE)) + +#define IS_OPTIONBYTE(VALUE) ((((VALUE) & OPTIONBYTE_ALL) != 0U) && \ + (((VALUE) & ~OPTIONBYTE_ALL) == 0U)) + +#define IS_OB_PRODUCT_STATE(STATE) (((STATE) == OB_PROD_STATE_OPEN) || \ + ((STATE) == OB_PROD_STATE_PROVISIONING) || \ + ((STATE) == OB_PROD_STATE_IROT_PROVISIONED) || \ + ((STATE) == OB_PROD_STATE_TZ_CLOSED) || \ + ((STATE) == OB_PROD_STATE_CLOSED) || \ + ((STATE) == OB_PROD_STATE_LOCKED) || \ + ((STATE) == OB_PROD_STATE_REGRESSION) || \ + ((STATE) == OB_PROD_STATE_NS_REGRESSION)) + +#define IS_OB_USER_BOR_LEVEL(LEVEL) (((LEVEL) == OB_BOR_LEVEL_1) || ((LEVEL) == OB_BOR_LEVEL_2) || \ + ((LEVEL) == OB_BOR_LEVEL_3)) + +#define IS_OB_USER_BORH_EN(VALUE) (((VALUE) == OB_BORH_DISABLE) || ((VALUE) == OB_BORH_ENABLE)) + +#define IS_OB_USER_IWDG(VALUE) (((VALUE) == OB_IWDG_HW) || ((VALUE) == OB_IWDG_SW)) + +#define IS_OB_USER_WWDG(VALUE) (((VALUE) == OB_WWDG_HW) || ((VALUE) == OB_WWDG_SW)) + +#define IS_OB_USER_STOP(VALUE) (((VALUE) == OB_STOP_RST) || ((VALUE) == OB_STOP_NORST)) + +#define IS_OB_USER_STANDBY(VALUE) (((VALUE) == OB_STANDBY_RST) || ((VALUE) == OB_STANDBY_NORST)) + +#define IS_OB_USER_IO_VDD_HSLV(VALUE) (((VALUE) == OB_IO_VDD_HSLV_DISABLE) || \ + ((VALUE) == OB_IO_VDD_HSLV_ENABLE)) + +#define IS_OB_USER_IO_VDDIO2_HSLV(VALUE) (((VALUE) == OB_IO_VDDIO2_HSLV_DISABLE) || \ + ((VALUE) == OB_IO_VDDIO2_HSLV_ENABLE)) + +#define IS_OB_USER_IWDG_STOP(VALUE) (((VALUE) == OB_IWDG_STOP_FREEZE) || ((VALUE) == OB_IWDG_STOP_ACTIVE)) + +#define IS_OB_USER_IWDG_STDBY(VALUE) (((VALUE) == OB_IWDG_STDBY_FREEZE) || ((VALUE) == OB_IWDG_STDBY_ACTIVE)) + +#define IS_OB_USER_BOOT_UBE(VALUE) (((VALUE) == OB_UBE_OEM_IROT) || ((VALUE) == OB_UBE_ST_IROT)) + +#define IS_OB_USER_SWAP_BANK(VALUE) (((VALUE) == OB_SWAP_BANK_DISABLE) || ((VALUE) == OB_SWAP_BANK_ENABLE)) + +#if defined (FLASH_OPTSR2_SRAM1_3_RST) +#define IS_OB_USER_SRAM1_3_RST(VALUE) (((VALUE) == OB_SRAM1_3_RST_ERASE) || ((VALUE) == OB_SRAM1_3_RST_NOT_ERASE)) +#endif /* FLASH_OPTSR2_SRAM1_3_RST */ + +#if defined (FLASH_OPTSR2_SRAM1_RST) +#define IS_OB_USER_SRAM1_RST(VALUE) (((VALUE) == OB_SRAM1_RST_ERASE) || ((VALUE) == OB_SRAM1_RST_NOT_ERASE)) +#endif /* FLASH_OPTSR2_SRAM1_RST */ + +#define IS_OB_USER_SRAM2_RST(VALUE) (((VALUE) == OB_SRAM2_RST_ERASE) || ((VALUE) == OB_SRAM2_RST_NOT_ERASE)) + +#define IS_OB_USER_BKPRAM_ECC(VALUE) (((VALUE) == OB_BKPRAM_ECC_ENABLE) || ((VALUE) == OB_BKPRAM_ECC_DISABLE)) + +#if defined (FLASH_OPTSR2_SRAM3_ECC) +#define IS_OB_USER_SRAM3_ECC(VALUE) (((VALUE) == OB_SRAM3_ECC_ENABLE) || ((VALUE) == OB_SRAM3_ECC_DISABLE)) +#endif /* FLASH_OPTSR2_SRAM3_ECC */ + +#if defined (FLASH_OPTSR2_SRAM1_ECC) +#define IS_OB_USER_SRAM1_ECC(VALUE) (((VALUE) == OB_SRAM1_ECC_ENABLE) || ((VALUE) == OB_SRAM1_ECC_DISABLE)) +#endif /* FLASH_OPTSR2_SRAM1_ECC */ + +#define IS_OB_USER_SRAM2_ECC(VALUE) (((VALUE) == OB_SRAM2_ECC_ENABLE) || ((VALUE) == OB_SRAM2_ECC_DISABLE)) + +#define IS_OB_USER_TZEN(VALUE) (((VALUE) == OB_TZEN_DISABLE) || ((VALUE) == OB_TZEN_ENABLE)) + +#define IS_OB_USER_TYPE(TYPE) ((((TYPE) & OB_USER_ALL) != 0U) && \ + (((TYPE) & ~OB_USER_ALL) == 0U)) + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define IS_OB_BOOT_CONFIG(CFG) (((CFG) == OB_BOOT_NS) || ((CFG) == OB_BOOT_SEC)) +#else +#define IS_OB_BOOT_CONFIG(CFG) ((CFG) == OB_BOOT_NS) +#endif /* __ARM_FEATURE_CMSE */ + +#define IS_OB_BOOT_LOCK(VALUE) (((VALUE) == OB_BOOT_LOCK_DISABLE) || ((VALUE) == OB_BOOT_LOCK_ENABLE)) + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define IS_FLASH_BB_EXCLUSIVE(CFG) (((CFG) == FLASH_BB_SEC) || ((CFG) == FLASH_BB_PRIV)) +#else +#define IS_FLASH_BB_EXCLUSIVE(CFG) ((CFG) == FLASH_BB_PRIV) +#endif /* __ARM_FEATURE_CMSE */ + +#define IS_FLASH_CFGPRIVMODE(CFG) (((CFG) & 0xFFFFFFFCU) == 0U) + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define IS_FLASH_CFGSECINV(CFG) (((CFG) == FLASH_INV_DISABLE) || ((CFG) == FLASH_INV_ENABLE)) +#endif /* __ARM_FEATURE_CMSE */ + +#define IS_FLASH_EDATA_SIZE(SECTOR) ((SECTOR) <= FLASH_EDATA_SECTOR_NB) +/** + * @} + */ + +/** + * @} + */ +/* Private functions ---------------------------------------------------------*/ +/** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions + * @{ + */ +void FLASH_Erase_Sector(uint32_t Sector, uint32_t Banks); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_FLASH_EX_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_fmac.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_fmac.h new file mode 100644 index 0000000000..21881e79c5 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_fmac.h @@ -0,0 +1,727 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_fmac.h + * @author MCD Application Team + * @brief Header for stm32h5xx_hal_fmac.c module + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_FMAC_H +#define STM32H5xx_HAL_FMAC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +#if defined(FMAC) +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup FMAC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup FMAC_Exported_Types FMAC Exported Types + * @{ + */ + +/** + * @brief FMAC HAL State Structure definition + */ +typedef enum +{ + HAL_FMAC_STATE_RESET = 0x00U, /*!< FMAC not yet initialized or disabled */ + HAL_FMAC_STATE_READY = 0x20U, /*!< FMAC initialized and ready for use */ + HAL_FMAC_STATE_BUSY = 0x24U, /*!< FMAC internal process is ongoing */ + HAL_FMAC_STATE_BUSY_RD = 0x25U, /*!< FMAC reading configuration is ongoing */ + HAL_FMAC_STATE_BUSY_WR = 0x26U, /*!< FMAC writing configuration is ongoing */ + HAL_FMAC_STATE_TIMEOUT = 0xA0U, /*!< FMAC in Timeout state */ + HAL_FMAC_STATE_ERROR = 0xE0U /*!< FMAC in Error state */ +} HAL_FMAC_StateTypeDef; + +/** + * @brief FMAC Handle Structure definition + */ +#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) +typedef struct __FMAC_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ +{ + FMAC_TypeDef *Instance; /*!< Register base address */ + + uint32_t FilterParam; /*!< Filter configuration (operation and parameters). + Set to 0 if no valid configuration was applied. */ + + uint8_t InputAccess; /*!< Access to the input buffer (internal memory area): + DMA, IT, Polling, None. + This parameter can be a value of @ref FMAC_Buffer_Access. */ + + uint8_t OutputAccess; /*!< Access to the output buffer (internal memory area): + DMA, IT, Polling, None. + This parameter can be a value of @ref FMAC_Buffer_Access. */ + + int16_t *pInput; /*!< Pointer to FMAC input data buffer */ + + uint16_t InputCurrentSize; /*!< Number of the input elements already written into FMAC */ + + uint16_t *pInputSize; /*!< Number of input elements to write (memory allocated to pInput). + In case of early interruption of the filter operation, + its value will be updated. */ + + int16_t *pOutput; /*!< Pointer to FMAC output data buffer */ + + uint16_t OutputCurrentSize; /*!< Number of the output elements already read from FMAC */ + + uint16_t *pOutputSize; /*!< Number of output elements to read (memory allocated to pOutput). + In case of early interruption of the filter operation, + its value will be updated. */ + + DMA_HandleTypeDef *hdmaIn; /*!< FMAC peripheral input data DMA handle parameters */ + + DMA_HandleTypeDef *hdmaOut; /*!< FMAC peripheral output data DMA handle parameters */ + + DMA_HandleTypeDef *hdmaPreload; /*!< FMAC peripheral preloaded data (X1, X2 and Y) DMA handle + parameters */ + +#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) + void (* ErrorCallback)(struct __FMAC_HandleTypeDef *hfmac); /*!< FMAC error callback */ + + void (* HalfGetDataCallback)(struct __FMAC_HandleTypeDef *hfmac); /*!< FMAC get half data callback */ + + void (* GetDataCallback)(struct __FMAC_HandleTypeDef *hfmac); /*!< FMAC get data callback */ + + void (* HalfOutputDataReadyCallback)(struct __FMAC_HandleTypeDef *hfmac); /*!< FMAC half output data ready callback */ + + void (* OutputDataReadyCallback)(struct __FMAC_HandleTypeDef *hfmac); /*!< FMAC output data ready callback */ + + void (* FilterConfigCallback)(struct __FMAC_HandleTypeDef *hfmac); /*!< FMAC filter configuration callback */ + + void (* FilterPreloadCallback)(struct __FMAC_HandleTypeDef *hfmac); /*!< FMAC filter preload callback */ + + void (* MspInitCallback)(struct __FMAC_HandleTypeDef *hfmac); /*!< FMAC Msp Init callback */ + + void (* MspDeInitCallback)(struct __FMAC_HandleTypeDef *hfmac); /*!< FMAC Msp DeInit callback */ + +#endif /* (USE_HAL_FMAC_REGISTER_CALLBACKS) */ + + HAL_LockTypeDef Lock; /*!< FMAC locking object */ + + __IO HAL_FMAC_StateTypeDef State; /*!< FMAC state related to global handle management + This parameter can be a value of @ref HAL_FMAC_StateTypeDef */ + + __IO HAL_FMAC_StateTypeDef RdState; /*!< FMAC state related to read operations (access to Y buffer) + This parameter can be a value of @ref HAL_FMAC_StateTypeDef */ + + __IO HAL_FMAC_StateTypeDef WrState; /*!< FMAC state related to write operations (access to X1 buffer) + This parameter can be a value of @ref HAL_FMAC_StateTypeDef */ + + __IO uint32_t ErrorCode; /*!< FMAC peripheral error code + This parameter can be a value of @ref FMAC_Error_Code */ + +} FMAC_HandleTypeDef; + +#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) +/** + * @brief FMAC Callback ID enumeration definition + */ +typedef enum +{ + HAL_FMAC_ERROR_CB_ID = 0x00U, /*!< FMAC error callback ID */ + HAL_FMAC_HALF_GET_DATA_CB_ID = 0x01U, /*!< FMAC get half data callback ID */ + HAL_FMAC_GET_DATA_CB_ID = 0x02U, /*!< FMAC get data callback ID */ + HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID = 0x03U, /*!< FMAC half output data ready callback ID */ + HAL_FMAC_OUTPUT_DATA_READY_CB_ID = 0x04U, /*!< FMAC output data ready callback ID */ + HAL_FMAC_FILTER_CONFIG_CB_ID = 0x05U, /*!< FMAC filter configuration callback ID */ + HAL_FMAC_FILTER_PRELOAD_CB_ID = 0x06U, /*!< FMAC filter preload callback ID */ + + HAL_FMAC_MSPINIT_CB_ID = 0x07U, /*!< FMAC MspInit callback ID */ + HAL_FMAC_MSPDEINIT_CB_ID = 0x08U, /*!< FMAC MspDeInit callback ID */ +} HAL_FMAC_CallbackIDTypeDef; + +/** + * @brief HAL FMAC Callback pointer definition + */ +typedef void (*pFMAC_CallbackTypeDef)(FMAC_HandleTypeDef *hfmac); /*!< pointer to an FMAC callback function */ + +#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ + +/** + * @brief FMAC Filter Configuration Structure definition + */ +typedef struct +{ + uint8_t InputBaseAddress; /*!< Base address of the input buffer (X1) within the internal memory + (0x00 to 0xFF). Ignored if InputBufferSize is set to 0 + (previous configuration kept). + Note: the buffers can overlap or even coincide exactly. */ + + uint8_t InputBufferSize; /*!< Number of 16-bit words allocated to the input buffer + (including the optional "headroom"). + 0 if a previous configuration should be kept. */ + + uint32_t InputThreshold; /*!< Input threshold: the buffer full flag will be set if the number + of free spaces in the buffer is lower than this threshold. + This parameter can be a value + of @ref FMAC_Data_Buffer_Threshold. */ + + uint8_t CoeffBaseAddress; /*!< Base address of the coefficient buffer (X2) within the internal + memory (0x00 to 0xFF). Ignored if CoeffBufferSize is set to 0 + (previous configuration kept). + Note: the buffers can overlap or even coincide exactly. */ + + uint8_t CoeffBufferSize; /*!< Number of 16-bit words allocated to the coefficient buffer. + 0 if a previous configuration should be kept. */ + + uint8_t OutputBaseAddress; /*!< Base address of the output buffer (Y) within the internal + memory (0x00 to 0xFF). Ignored if OuputBufferSize is set to 0 + (previous configuration kept). + Note: the buffers can overlap or even coincide exactly. */ + + uint8_t OutputBufferSize; /*!< Number of 16-bit words allocated to the output buffer + (including the optional "headroom"). + 0 if a previous configuration should be kept. */ + + uint32_t OutputThreshold; /*!< Output threshold: the buffer empty flag will be set if the number + of unread values in the buffer is lower than this threshold. + This parameter can be a value + of @ref FMAC_Data_Buffer_Threshold. */ + + int16_t *pCoeffA; /*!< [IIR only] Initialization of the coefficient vector A. + If not needed, it should be set to NULL. */ + + uint8_t CoeffASize; /*!< Size of the coefficient vector A. */ + + int16_t *pCoeffB; /*!< Initialization of the coefficient vector B. + If not needed (re-use of a previously loaded buffer), + it should be set to NULL. */ + + uint8_t CoeffBSize; /*!< Size of the coefficient vector B. */ + + uint8_t InputAccess; /*!< Access to the input buffer (internal memory area): + DMA, IT, Polling, None. + This parameter can be a value of @ref FMAC_Buffer_Access. */ + + uint8_t OutputAccess; /*!< Access to the output buffer (internal memory area): + DMA, IT, Polling, None. + This parameter can be a value of @ref FMAC_Buffer_Access. */ + + uint32_t Clip; /*!< Enable or disable the clipping feature. If the q1.15 range + is exceeded, wrapping is done when the clipping feature is disabled + and saturation is done when the clipping feature is enabled. + This parameter can be a value of @ref FMAC_Clip_State. */ + + uint32_t Filter; /*!< Filter type. + This parameter can be a value + of @ref FMAC_Functions (filter related values). */ + + uint8_t P; /*!< Parameter P (vector length, number of filter taps, etc.). */ + + uint8_t Q; /*!< Parameter Q (vector length, etc.). Ignored if not needed. */ + + uint8_t R; /*!< Parameter R (gain, etc.). Ignored if not needed. */ + +} FMAC_FilterConfigTypeDef; + +/** + * @} + */ + + +/* Exported constants --------------------------------------------------------*/ + + +/** @defgroup FMAC_Exported_Constants FMAC Exported Constants + * @{ + */ + +/** @defgroup FMAC_Error_Code FMAC Error code + * @{ + */ +#define HAL_FMAC_ERROR_NONE 0x00000000U /*!< No error */ +#define HAL_FMAC_ERROR_SAT 0x00000001U /*!< Saturation error */ +#define HAL_FMAC_ERROR_UNFL 0x00000002U /*!< Underflow error */ +#define HAL_FMAC_ERROR_OVFL 0x00000004U /*!< Overflow error */ +#define HAL_FMAC_ERROR_DMA 0x00000008U /*!< DMA error */ +#define HAL_FMAC_ERROR_RESET 0x00000010U /*!< Reset error */ +#define HAL_FMAC_ERROR_PARAM 0x00000020U /*!< Parameter error */ +#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) +#define HAL_FMAC_ERROR_INVALID_CALLBACK 0x00000040U /*!< Invalid Callback error */ +#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ +#define HAL_FMAC_ERROR_TIMEOUT 0x00000080U /*!< Timeout error */ + +/** + * @} + */ + +/** @defgroup FMAC_Functions FMAC Functions + * @{ + */ +#define FMAC_FUNC_LOAD_X1 (FMAC_PARAM_FUNC_0) /*!< Load X1 buffer */ +#define FMAC_FUNC_LOAD_X2 (FMAC_PARAM_FUNC_1) /*!< Load X2 buffer */ +#define FMAC_FUNC_LOAD_Y (FMAC_PARAM_FUNC_1 | FMAC_PARAM_FUNC_0) /*!< Load Y buffer */ +#define FMAC_FUNC_CONVO_FIR (FMAC_PARAM_FUNC_3) /*!< Convolution (FIR filter) */ +#define FMAC_FUNC_IIR_DIRECT_FORM_1 (FMAC_PARAM_FUNC_3 | FMAC_PARAM_FUNC_0) /*!< IIR filter (direct form 1) */ +/** + * @} + */ + +/** @defgroup FMAC_Data_Buffer_Threshold FMAC Data Buffer Threshold + * @{ + * @note This parameter sets a watermark for buffer full (input) or buffer empty (output). + */ +#define FMAC_THRESHOLD_1 0x00000000U /*!< Input: Buffer full flag set if the number of free spaces + in the buffer is less than 1. + Output: Buffer empty flag set if the number + of unread values in the buffer is less than 1. */ +#define FMAC_THRESHOLD_2 0x01000000U /*!< Input: Buffer full flag set if the number of free spaces + in the buffer is less than 2. + Output: Buffer empty flag set if the number + of unread values in the buffer is less than 2. */ +#define FMAC_THRESHOLD_4 0x02000000U /*!< Input: Buffer full flag set if the number of free spaces + in the buffer is less than 4. + Output: Buffer empty flag set if the number + of unread values in the buffer is less than 4. */ +#define FMAC_THRESHOLD_8 0x03000000U /*!< Input: Buffer full flag set if the number of free spaces + in the buffer is less than 8. + Output: Buffer empty flag set if the number + of unread values in the buffer is less than 8. */ +#define FMAC_THRESHOLD_NO_VALUE 0xFFFFFFFFU /*!< The configured threshold value shouldn't be changed */ +/** + * @} + */ + +/** @defgroup FMAC_Buffer_Access FMAC Buffer Access + * @{ + */ +#define FMAC_BUFFER_ACCESS_NONE 0x00U /*!< Buffer handled by an external IP (ADC for instance) */ +#define FMAC_BUFFER_ACCESS_DMA 0x01U /*!< Buffer accessed through DMA */ +#define FMAC_BUFFER_ACCESS_POLLING 0x02U /*!< Buffer accessed through polling */ +#define FMAC_BUFFER_ACCESS_IT 0x03U /*!< Buffer accessed through interruptions */ +/** + * @} + */ + +/** @defgroup FMAC_Clip_State FMAC Clip State + * @{ + */ +#define FMAC_CLIP_DISABLED 0x00000000U /*!< Clipping disabled */ +#define FMAC_CLIP_ENABLED FMAC_CR_CLIPEN /*!< Clipping enabled */ +/** + * @} + */ + +/** @defgroup FMAC_Flags FMAC status flags + * @{ + */ +#define FMAC_FLAG_YEMPTY FMAC_SR_YEMPTY /*!< Y Buffer Empty Flag */ +#define FMAC_FLAG_X1FULL FMAC_SR_X1FULL /*!< X1 Buffer Full Flag */ +#define FMAC_FLAG_OVFL FMAC_SR_OVFL /*!< Overflow Error Flag */ +#define FMAC_FLAG_UNFL FMAC_SR_UNFL /*!< Underflow Error Flag */ +#define FMAC_FLAG_SAT FMAC_SR_SAT /*!< Saturation Error Flag + (this helps in debugging a filter) */ +/** + * @} + */ + +/** @defgroup FMAC_Interrupts_Enable FMAC Interrupts Enable bit + * @{ + */ +#define FMAC_IT_RIEN FMAC_CR_RIEN /*!< Read Interrupt Enable */ +#define FMAC_IT_WIEN FMAC_CR_WIEN /*!< Write Interrupt Enable */ +#define FMAC_IT_OVFLIEN FMAC_CR_OVFLIEN /*!< Overflow Error Interrupt Enable */ +#define FMAC_IT_UNFLIEN FMAC_CR_UNFLIEN /*!< Underflow Error Interrupt Enable */ +#define FMAC_IT_SATIEN FMAC_CR_SATIEN /*!< Saturation Error Interrupt Enable + (this helps in debugging a filter) */ +/** + * @} + */ + +/** + * @} + */ + + +/* Exported variables --------------------------------------------------------*/ +/** @defgroup FMAC_Exported_variables FMAC Exported variables + * @{ + */ +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup FMAC_Exported_Macros FMAC Exported Macros + * @{ + */ + +/** + * @brief Reset FMAC handle state. + * @param __HANDLE__ FMAC handle. + * @retval None + */ +#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) +#define __HAL_FMAC_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->State = HAL_FMAC_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0U) +#else +#define __HAL_FMAC_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_FMAC_STATE_RESET) +#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ + +/** + * @brief Enable the specified FMAC interrupt + * @param __HANDLE__ FMAC handle. + * @param __INTERRUPT__ FMAC Interrupt. + * This parameter can be any combination of the following values: + * @arg @ref FMAC_IT_RIEN Read interrupt enable + * @arg @ref FMAC_IT_WIEN Write interrupt enable + * @arg @ref FMAC_IT_OVFLIEN Overflow error interrupt enable + * @arg @ref FMAC_IT_UNFLIEN Underflow error interrupt enable + * @arg @ref FMAC_IT_SATIEN Saturation error interrupt enable (this helps in debugging a filter) + * @retval None + */ +#define __HAL_FMAC_ENABLE_IT(__HANDLE__, __INTERRUPT__) \ + (((__HANDLE__)->Instance->CR) |= (__INTERRUPT__)) + +/** + * @brief Disable the FMAC interrupt + * @param __HANDLE__ FMAC handle. + * @param __INTERRUPT__ FMAC Interrupt. + * This parameter can be any combination of the following values: + * @arg @ref FMAC_IT_RIEN Read interrupt enable + * @arg @ref FMAC_IT_WIEN Write interrupt enable + * @arg @ref FMAC_IT_OVFLIEN Overflow error interrupt enable + * @arg @ref FMAC_IT_UNFLIEN Underflow error interrupt enable + * @arg @ref FMAC_IT_SATIEN Saturation error interrupt enable (this helps in debugging a filter) + * @retval None + */ +#define __HAL_FMAC_DISABLE_IT(__HANDLE__, __INTERRUPT__) \ + (((__HANDLE__)->Instance->CR) &= ~(__INTERRUPT__)) + +/** + * @brief Check whether the specified FMAC interrupt occurred or not. + * @param __HANDLE__ FMAC handle. + * @param __INTERRUPT__ FMAC interrupt to check. + * This parameter can be any combination of the following values: + * @arg @ref FMAC_FLAG_YEMPTY Y Buffer Empty Flag + * @arg @ref FMAC_FLAG_X1FULL X1 Buffer Full Flag + * @arg @ref FMAC_FLAG_OVFL Overflow Error Flag + * @arg @ref FMAC_FLAG_UNFL Underflow Error Flag + * @arg @ref FMAC_FLAG_SAT Saturation Error Flag + * @retval SET (interrupt occurred) or RESET (interrupt did not occurred) + */ +#define __HAL_FMAC_GET_IT(__HANDLE__, __INTERRUPT__) \ + (((__HANDLE__)->Instance->SR) &= ~(__INTERRUPT__)) + +/** + * @brief Clear specified FMAC interrupt status. Dummy macro as the + interrupt status flags are read-only. + * @param __HANDLE__ FMAC handle. + * @param __INTERRUPT__ FMAC interrupt to clear. + * @retval None + */ +#define __HAL_FMAC_CLEAR_IT(__HANDLE__, __INTERRUPT__) /* Dummy macro */ + +/** + * @brief Check whether the specified FMAC status flag is set or not. + * @param __HANDLE__ FMAC handle. + * @param __FLAG__ FMAC flag to check. + * This parameter can be any combination of the following values: + * @arg @ref FMAC_FLAG_YEMPTY Y Buffer Empty Flag + * @arg @ref FMAC_FLAG_X1FULL X1 Buffer Full Flag + * @arg @ref FMAC_FLAG_OVFL Overflow Error Flag + * @arg @ref FMAC_FLAG_UNFL Underflow Error Flag + * @arg @ref FMAC_FLAG_SAT Saturation error Flag + * @retval SET (flag is set) or RESET (flag is reset) + */ +#define __HAL_FMAC_GET_FLAG(__HANDLE__, __FLAG__) \ + ((((__HANDLE__)->Instance->SR) & (__FLAG__)) == (__FLAG__)) + +/** + * @brief Clear specified FMAC status flag. Dummy macro as no + flag can be cleared. + * @param __HANDLE__ FMAC handle. + * @param __FLAG__ FMAC flag to clear. + * @retval None + */ +#define __HAL_FMAC_CLEAR_FLAG(__HANDLE__, __FLAG__) /* Dummy macro */ + +/** + * @brief Check whether the specified FMAC interrupt is enabled or not. + * @param __HANDLE__ FMAC handle. + * @param __INTERRUPT__ FMAC interrupt to check. + * This parameter can be one of the following values: + * @arg @ref FMAC_IT_RIEN Read interrupt enable + * @arg @ref FMAC_IT_WIEN Write interrupt enable + * @arg @ref FMAC_IT_OVFLIEN Overflow error interrupt enable + * @arg @ref FMAC_IT_UNFLIEN Underflow error interrupt enable + * @arg @ref FMAC_IT_SATIEN Saturation error interrupt enable (this helps in debugging a filter) + * @retval FlagStatus + */ +#define __HAL_FMAC_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) \ + (((__HANDLE__)->Instance->CR) & (__INTERRUPT__)) + +/** + * @} + */ + +/* Private defines -----------------------------------------------------------*/ +/** @addtogroup FMAC_Private_Constants + * @{ + */ + +#define FMAC_PARAM_P_MAX_IIR 64U /*!< Maximum value of P parameter with IIR */ +#define FMAC_PARAM_P_MAX_FIR 127U /*!< Maximum value of P parameter with FIR */ +#define FMAC_PARAM_P_MIN 2U /*!< Minimum value of P parameter */ +#define FMAC_PARAM_Q_MAX 63U /*!< Maximum value of Q parameter */ +#define FMAC_PARAM_Q_MIN 1U /*!< Minimum value of Q parameter */ +#define FMAC_PARAM_R_MAX 7U /*!< Maximum value of R parameter */ + +/** + * @} + */ + +/* Private Macros-----------------------------------------------------------*/ +/** @addtogroup FMAC_Private_Macros FMAC Private Macros + * @{ + */ + +/** + * @brief Verify the FMAC function. + * @param __FUNCTION__ ID of the function. + * @retval SET (__FUNCTION__ is a valid value) or RESET (__FUNCTION__ is invalid) + */ +#define IS_FMAC_FUNCTION(__FUNCTION__) (((__FUNCTION__) == FMAC_FUNC_LOAD_X1) || \ + ((__FUNCTION__) == FMAC_FUNC_LOAD_X2) || \ + ((__FUNCTION__) == FMAC_FUNC_LOAD_Y) || \ + ((__FUNCTION__) == FMAC_FUNC_CONVO_FIR) || \ + ((__FUNCTION__) == FMAC_FUNC_IIR_DIRECT_FORM_1)) + +/** + * @brief Verify the FMAC load function used for input data, output data or coefficients. + * @param __FUNCTION__ ID of the load function. + * @retval SET (__FUNCTION__ is a valid value) or RESET (__FUNCTION__ is invalid) + */ +#define IS_FMAC_LOAD_FUNCTION(__FUNCTION__) (((__FUNCTION__) == FMAC_FUNC_LOAD_X1) || \ + ((__FUNCTION__) == FMAC_FUNC_LOAD_X2) || \ + ((__FUNCTION__) == FMAC_FUNC_LOAD_Y)) + +/** + * @brief Verify the FMAC load function used with N values as input or output data. + * @param __FUNCTION__ ID of the load function. + * @retval SET (__FUNCTION__ is a valid value) or RESET (__FUNCTION__ is invalid) + */ +#define IS_FMAC_N_LOAD_FUNCTION(__FUNCTION__) (((__FUNCTION__) == FMAC_FUNC_LOAD_X1) || \ + ((__FUNCTION__) == FMAC_FUNC_LOAD_Y)) + +/** + * @brief Verify the FMAC load function used with N + M values as coefficients. + * @param __FUNCTION__ ID of the load function. + * @retval SET (__FUNCTION__ is a valid value) or RESET (__FUNCTION__ is invalid) + */ +#define IS_FMAC_N_M_LOAD_FUNCTION(__FUNCTION__) ((__FUNCTION__) == FMAC_FUNC_LOAD_X2) + +/** + * @brief Verify the FMAC filter function. + * @param __FUNCTION__ ID of the filter function. + * @retval SET (__FUNCTION__ is a valid value) or RESET (__FUNCTION__ is invalid) + */ +#define IS_FMAC_FILTER_FUNCTION(__FUNCTION__) (((__FUNCTION__) == FMAC_FUNC_CONVO_FIR) || \ + ((__FUNCTION__) == FMAC_FUNC_IIR_DIRECT_FORM_1)) + + +/** + * @brief Verify the FMAC threshold. + * @param __THRESHOLD__ Value of the threshold. + * @retval SET (__THRESHOLD__ is a valid value) or RESET (__THRESHOLD__ is invalid) + */ +#define IS_FMAC_THRESHOLD(__THRESHOLD__) (((__THRESHOLD__) == FMAC_THRESHOLD_1) || \ + ((__THRESHOLD__) == FMAC_THRESHOLD_2) || \ + ((__THRESHOLD__) == FMAC_THRESHOLD_4) || \ + ((__THRESHOLD__) == FMAC_THRESHOLD_NO_VALUE) || \ + ((__THRESHOLD__) == FMAC_THRESHOLD_8)) + +/** + * @brief Verify the FMAC filter parameter P. + * @param __P__ Value of the filter parameter P. + * @param __FUNCTION__ ID of the filter function. + * @retval SET (__P__ is a valid value) or RESET (__P__ is invalid) + */ +#define IS_FMAC_PARAM_P(__FUNCTION__, __P__) ((((__FUNCTION__) == FMAC_FUNC_CONVO_FIR) && \ + (((__P__) >= FMAC_PARAM_P_MIN) && \ + ((__P__) <= FMAC_PARAM_P_MAX_FIR))) || \ + (((__FUNCTION__) == FMAC_FUNC_IIR_DIRECT_FORM_1) && \ + (((__P__) >= FMAC_PARAM_P_MIN) && \ + ((__P__) <= FMAC_PARAM_P_MAX_IIR)))) + +/** + * @brief Verify the FMAC filter parameter Q. + * @param __Q__ Value of the filter parameter Q. + * @param __FUNCTION__ ID of the filter function. + * @retval SET (__Q__ is a valid value) or RESET (__Q__ is invalid) + */ +#define IS_FMAC_PARAM_Q(__FUNCTION__, __Q__) ( ((__FUNCTION__) == FMAC_FUNC_CONVO_FIR) || \ + (((__FUNCTION__) == FMAC_FUNC_IIR_DIRECT_FORM_1) && \ + (((__Q__) >= FMAC_PARAM_Q_MIN) && ((__Q__) <= FMAC_PARAM_Q_MAX))) ) + +/** + * @brief Verify the FMAC filter parameter R. + * @param __R__ Value of the filter parameter. + * @param __FUNCTION__ ID of the filter function. + * @retval SET (__R__ is a valid value) or RESET (__R__ is invalid) + */ +#define IS_FMAC_PARAM_R(__FUNCTION__, __R__) ( (((__FUNCTION__) == FMAC_FUNC_CONVO_FIR) || \ + ((__FUNCTION__) == FMAC_FUNC_IIR_DIRECT_FORM_1)) && \ + ((__R__) <= FMAC_PARAM_R_MAX)) + +/** + * @brief Verify the FMAC buffer access. + * @param __BUFFER_ACCESS__ Type of access. + * @retval SET (__BUFFER_ACCESS__ is a valid value) or RESET (__BUFFER_ACCESS__ is invalid) + */ +#define IS_FMAC_BUFFER_ACCESS(__BUFFER_ACCESS__) (((__BUFFER_ACCESS__) == FMAC_BUFFER_ACCESS_NONE) || \ + ((__BUFFER_ACCESS__) == FMAC_BUFFER_ACCESS_DMA) || \ + ((__BUFFER_ACCESS__) == FMAC_BUFFER_ACCESS_POLLING) || \ + ((__BUFFER_ACCESS__) == FMAC_BUFFER_ACCESS_IT)) + +/** + * @brief Verify the FMAC clip feature. + * @param __CLIP_STATE__ Clip state. + * @retval SET (__CLIP_STATE__ is a valid value) or RESET (__CLIP_STATE__ is invalid) + */ +#define IS_FMAC_CLIP_STATE(__CLIP_STATE__) (((__CLIP_STATE__) == FMAC_CLIP_DISABLED) || \ + ((__CLIP_STATE__) == FMAC_CLIP_ENABLED)) + +/** + * @brief Check whether the threshold is applicable. + * @param __SIZE__ Size of the matching buffer. + * @param __WM__ Watermark value. + * @param __ACCESS__ Access to the buffer (polling, it, dma, none). + * @retval THRESHOLD + */ +#define IS_FMAC_THRESHOLD_APPLICABLE(__SIZE__, __WM__, __ACCESS__) \ + (( (__SIZE__) >= (((__WM__) == FMAC_THRESHOLD_1)? 1U: \ + ((__WM__) == FMAC_THRESHOLD_2)? 2U: \ + ((__WM__) == FMAC_THRESHOLD_4)? 4U:8U))&& \ + ((((__ACCESS__) == FMAC_BUFFER_ACCESS_DMA)&& \ + ((__WM__) == FMAC_THRESHOLD_1))|| \ + ((__ACCESS__ )!= FMAC_BUFFER_ACCESS_DMA))) + +/** + * @} + */ + +/* Exported functions ------------------------------------------------------- */ +/** @addtogroup FMAC_Exported_Functions + * @{ + */ + +/** @addtogroup FMAC_Exported_Functions_Group1 + * @{ + */ +/* Initialization and de-initialization functions ****************************/ +HAL_StatusTypeDef HAL_FMAC_Init(FMAC_HandleTypeDef *hfmac); +HAL_StatusTypeDef HAL_FMAC_DeInit(FMAC_HandleTypeDef *hfmac); +void HAL_FMAC_MspInit(FMAC_HandleTypeDef *hfmac); +void HAL_FMAC_MspDeInit(FMAC_HandleTypeDef *hfmac); + +#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) +/* Callbacks Register/UnRegister functions ***********************************/ +HAL_StatusTypeDef HAL_FMAC_RegisterCallback(FMAC_HandleTypeDef *hfmac, HAL_FMAC_CallbackIDTypeDef CallbackID, + pFMAC_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_FMAC_UnRegisterCallback(FMAC_HandleTypeDef *hfmac, HAL_FMAC_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @addtogroup FMAC_Exported_Functions_Group2 + * @{ + */ +/* Peripheral Control functions ***********************************************/ +HAL_StatusTypeDef HAL_FMAC_FilterConfig(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *pConfig); +HAL_StatusTypeDef HAL_FMAC_FilterConfig_DMA(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *pConfig); +HAL_StatusTypeDef HAL_FMAC_FilterPreload(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize, + int16_t *pOutput, uint8_t OutputSize); +HAL_StatusTypeDef HAL_FMAC_FilterPreload_DMA(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize, + int16_t *pOutput, uint8_t OutputSize); +HAL_StatusTypeDef HAL_FMAC_FilterStart(FMAC_HandleTypeDef *hfmac, int16_t *pOutput, uint16_t *pOutputSize); +HAL_StatusTypeDef HAL_FMAC_AppendFilterData(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint16_t *pInputSize); +HAL_StatusTypeDef HAL_FMAC_ConfigFilterOutputBuffer(FMAC_HandleTypeDef *hfmac, int16_t *pOutput, uint16_t *pOutputSize); +HAL_StatusTypeDef HAL_FMAC_PollFilterData(FMAC_HandleTypeDef *hfmac, uint32_t Timeout); +HAL_StatusTypeDef HAL_FMAC_FilterStop(FMAC_HandleTypeDef *hfmac); +/** + * @} + */ + +/** @addtogroup FMAC_Exported_Functions_Group3 + * @{ + */ +/* Callback functions *********************************************************/ +void HAL_FMAC_ErrorCallback(FMAC_HandleTypeDef *hfmac); +void HAL_FMAC_HalfGetDataCallback(FMAC_HandleTypeDef *hfmac); +void HAL_FMAC_GetDataCallback(FMAC_HandleTypeDef *hfmac); +void HAL_FMAC_HalfOutputDataReadyCallback(FMAC_HandleTypeDef *hfmac); +void HAL_FMAC_OutputDataReadyCallback(FMAC_HandleTypeDef *hfmac); +void HAL_FMAC_FilterConfigCallback(FMAC_HandleTypeDef *hfmac); +void HAL_FMAC_FilterPreloadCallback(FMAC_HandleTypeDef *hfmac); +/** + * @} + */ + +/** @addtogroup FMAC_Exported_Functions_Group4 + * @{ + */ +/* IRQ handler management *****************************************************/ +void HAL_FMAC_IRQHandler(FMAC_HandleTypeDef *hfmac); +/** + * @} + */ + +/** @addtogroup FMAC_Exported_Functions_Group5 + * @{ + */ +/* Peripheral State functions *************************************************/ +HAL_FMAC_StateTypeDef HAL_FMAC_GetState(const FMAC_HandleTypeDef *hfmac); +uint32_t HAL_FMAC_GetError(const FMAC_HandleTypeDef *hfmac); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* FMAC */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_FMAC_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_gpio.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_gpio.h new file mode 100644 index 0000000000..a139c5391f --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_gpio.h @@ -0,0 +1,393 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_gpio.h + * @author MCD Application Team + * @brief Header file of GPIO HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_GPIO_H +#define STM32H5xx_HAL_GPIO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup GPIO GPIO + * @brief GPIO HAL module driver + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup GPIO_Exported_Types GPIO Exported Types + * @{ + */ +/** + * @brief GPIO Init structure definition + */ +typedef struct +{ + uint32_t Pin; /*!< Specifies the GPIO pins to be configured. + This parameter can be a value of @ref GPIO_pins */ + + uint32_t Mode; /*!< Specifies the operating mode for the selected pins. + This parameter can be a value of @ref GPIO_mode */ + + uint32_t Pull; /*!< Specifies the Pull-up or Pull-Down activation for the selected pins. + This parameter can be a value of @ref GPIO_pull */ + + uint32_t Speed; /*!< Specifies the speed for the selected pins. + This parameter can be a value of @ref GPIO_speed */ + + uint32_t Alternate; /*!< Peripheral to be connected to the selected pins + This parameter can be a value of @ref GPIOEx_Alternate_function_selection */ +} GPIO_InitTypeDef; + +/** + * @brief GPIO Bit SET and Bit RESET enumeration + */ +typedef enum +{ + GPIO_PIN_RESET = 0U, + GPIO_PIN_SET +} GPIO_PinState; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup GPIO_Exported_Constants GPIO Exported Constants + * @{ + */ +/** @defgroup GPIO_pins GPIO pins + * @{ + */ +#define GPIO_PIN_0 ((uint16_t)0x0001) /* Pin 0 selected */ +#define GPIO_PIN_1 ((uint16_t)0x0002) /* Pin 1 selected */ +#define GPIO_PIN_2 ((uint16_t)0x0004) /* Pin 2 selected */ +#define GPIO_PIN_3 ((uint16_t)0x0008) /* Pin 3 selected */ +#define GPIO_PIN_4 ((uint16_t)0x0010) /* Pin 4 selected */ +#define GPIO_PIN_5 ((uint16_t)0x0020) /* Pin 5 selected */ +#define GPIO_PIN_6 ((uint16_t)0x0040) /* Pin 6 selected */ +#define GPIO_PIN_7 ((uint16_t)0x0080) /* Pin 7 selected */ +#define GPIO_PIN_8 ((uint16_t)0x0100) /* Pin 8 selected */ +#define GPIO_PIN_9 ((uint16_t)0x0200) /* Pin 9 selected */ +#define GPIO_PIN_10 ((uint16_t)0x0400) /* Pin 10 selected */ +#define GPIO_PIN_11 ((uint16_t)0x0800) /* Pin 11 selected */ +#define GPIO_PIN_12 ((uint16_t)0x1000) /* Pin 12 selected */ +#define GPIO_PIN_13 ((uint16_t)0x2000) /* Pin 13 selected */ +#define GPIO_PIN_14 ((uint16_t)0x4000) /* Pin 14 selected */ +#define GPIO_PIN_15 ((uint16_t)0x8000) /* Pin 15 selected */ +#define GPIO_PIN_ALL ((uint16_t)0xFFFF) /* All pins selected */ + +#define GPIO_PIN_MASK (0x0000FFFFU) /* PIN mask for assert test */ +/** + * @} + */ + +/** @defgroup GPIO_mode GPIO mode + * @brief GPIO Configuration Mode + * Elements values convention: 0xX0yz00YZ + * - X : GPIO mode or EXTI Mode + * - y : External IT or Event trigger detection + * - z : IO configuration on External IT or Event + * - Y : Output type (Push Pull or Open Drain) + * - Z : IO Direction mode (Input, Output, (Alternate or Analog)) + * @{ + */ +/*!< Input Floating Mode */ +#define GPIO_MODE_INPUT (0x00000000U) +/*!< Output Push Pull Mode */ +#define GPIO_MODE_OUTPUT_PP (0x00000001U) +/*!< Output Open Drain Mode */ +#define GPIO_MODE_OUTPUT_OD (0x00000011U) +/*!< Alternate Function Push Pull Mode */ +#define GPIO_MODE_AF_PP (0x00000002U) +/*!< Alternate Function Open Drain Mode */ +#define GPIO_MODE_AF_OD (0x00000012U) +/*!< Analog Mode */ +#define GPIO_MODE_ANALOG (0x00000003U) +/*!< External Interrupt Mode with Rising edge trigger detection */ +#define GPIO_MODE_IT_RISING (0x10110000U) +/*!< External Interrupt Mode with Falling edge trigger detection */ +#define GPIO_MODE_IT_FALLING (0x10210000U) +/*!< External Interrupt Mode with Rising/Falling edge trigger detection */ +#define GPIO_MODE_IT_RISING_FALLING (0x10310000U) +/*!< External Event Mode with Rising edge trigger detection */ +#define GPIO_MODE_EVT_RISING (0x10120000U) +/*!< External Event Mode with Falling edge trigger detection */ +#define GPIO_MODE_EVT_FALLING (0x10220000U) +/*!< External Event Mode with Rising/Falling edge trigger detection */ +#define GPIO_MODE_EVT_RISING_FALLING (0x10320000U) +/** + * @} + */ + +/** @defgroup GPIO_speed GPIO speed + * @brief GPIO Output Maximum frequency + * @{ + */ +#define GPIO_SPEED_FREQ_LOW (0x00000000U) /*!< Low speed */ +#define GPIO_SPEED_FREQ_MEDIUM (0x00000001U) /*!< Medium speed */ +#define GPIO_SPEED_FREQ_HIGH (0x00000002U) /*!< High speed */ +#define GPIO_SPEED_FREQ_VERY_HIGH (0x00000003U) /*!< Very-high speed */ +/** + * @} + */ + +/** @defgroup GPIO_pull GPIO pull + * @brief GPIO Pull-Up or Pull-Down Activation + * @{ + */ +#define GPIO_NOPULL (0x00000000U) /*!< No Pull-up or Pull-down activation */ +#define GPIO_PULLUP (0x00000001U) /*!< Pull-up activation */ +#define GPIO_PULLDOWN (0x00000002U) /*!< Pull-down activation */ +/** + * @} + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** @defgroup GPIO_attributes GPIO attributes + * @brief GPIO pin secure or non-secure attributes + * @{ + */ +#define GPIO_PIN_SEC (0x00000001U) /*!< Secure pin attribute */ +#define GPIO_PIN_NSEC (0x00000000U) /*!< Non-secure pin attribute */ +/** + * @} + */ + +#endif /* __ARM_FEATURE_CMSE */ +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup GPIO_Exported_Macros GPIO Exported Macros + * @{ + */ + +/** + * @brief Check whether the specified EXTI line is rising edge asserted or not. + * @param __EXTI_LINE__: specifies the EXTI line to check. + * This parameter can be GPIO_PIN_x where x can be(0..15) + * @retval The new state of __EXTI_LINE__ (SET or RESET). + */ +#define __HAL_GPIO_EXTI_GET_RISING_IT(__EXTI_LINE__) (EXTI->RPR1 & (__EXTI_LINE__)) + +/** + * @brief Clear the EXTI's line rising pending bits. + * @param __EXTI_LINE__: specifies the EXTI lines to clear. + * This parameter can be any combination of GPIO_PIN_x where x can be (0..15) + * @retval None + */ +#define __HAL_GPIO_EXTI_CLEAR_RISING_IT(__EXTI_LINE__) (EXTI->RPR1 = (__EXTI_LINE__)) + +/** + * @brief Check whether the specified EXTI line is falling edge asserted or not. + * @param __EXTI_LINE__: specifies the EXTI line to check. + * This parameter can be GPIO_PIN_x where x can be(0..15) + * @retval The new state of __EXTI_LINE__ (SET or RESET). + */ +#define __HAL_GPIO_EXTI_GET_FALLING_IT(__EXTI_LINE__) (EXTI->FPR1 & (__EXTI_LINE__)) + +/** + * @brief Clear the EXTI's line falling pending bits. + * @param __EXTI_LINE__: specifies the EXTI lines to clear. + * This parameter can be any combination of GPIO_PIN_x where x can be (0..15) + * @retval None + */ +#define __HAL_GPIO_EXTI_CLEAR_FALLING_IT(__EXTI_LINE__) (EXTI->FPR1 = (__EXTI_LINE__)) + +/** + * @brief Check whether the specified EXTI line is asserted or not. + * @param __EXTI_LINE__: specifies the EXTI line to check. + * This parameter can be GPIO_PIN_x where x can be(0..15) + * @retval The new state of __EXTI_LINE__ (SET or RESET). + */ +#define __HAL_GPIO_EXTI_GET_IT(__EXTI_LINE__) (__HAL_GPIO_EXTI_GET_RISING_IT(__EXTI_LINE__) || \ + __HAL_GPIO_EXTI_GET_FALLING_IT(__EXTI_LINE__)) + +/** + * @brief Clear the EXTI's line pending bits. + * @param __EXTI_LINE__: specifies the EXTI lines to clear. + * This parameter can be any combination of GPIO_PIN_x where x can be (0..15) + * @retval None + */ +#define __HAL_GPIO_EXTI_CLEAR_IT(__EXTI_LINE__) \ + do { \ + __HAL_GPIO_EXTI_CLEAR_RISING_IT(__EXTI_LINE__); \ + __HAL_GPIO_EXTI_CLEAR_FALLING_IT(__EXTI_LINE__); \ + } while(0) + + +/** + * @brief Generate a Software interrupt on selected EXTI line(s). + * @param __EXTI_LINE__: specifies the EXTI line to set. + * This parameter can be any combination of GPIO_PIN_x where x can be (0..15) + * @retval None + */ +#define __HAL_GPIO_EXTI_GENERATE_SWIT(__EXTI_LINE__) (EXTI->SWIER1 = (__EXTI_LINE__)) + +/** + * @brief Check whether the specified EXTI line flag is set or not. + * @param __EXTI_LINE__ specifies the EXTI line flag to check. + * This parameter can be GPIO_PIN_x where x can be(0..15) + * @retval The new state of __EXTI_LINE__ (SET or RESET). + */ +#define __HAL_GPIO_EXTI_GET_FLAG(__EXTI_LINE__) __HAL_GPIO_EXTI_GET_IT(__EXTI_LINE__) + +/** + * @brief Clear the EXTI line pending flags. + * @param __EXTI_LINE__ specifies the EXTI lines flags to clear. + * This parameter can be any combination of GPIO_PIN_x where x can be (0..15) + * @retval None + */ +#define __HAL_GPIO_EXTI_CLEAR_FLAG(__EXTI_LINE__) __HAL_GPIO_EXTI_CLEAR_IT(__EXTI_LINE__) + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup GPIO_Private_Macros GPIO Private Macros + * @{ + */ +#define IS_GPIO_PIN_ACTION(ACTION) (((ACTION) == GPIO_PIN_RESET) || ((ACTION) == GPIO_PIN_SET)) + +#define IS_GPIO_PIN(__PIN__) ((((uint32_t)(__PIN__) & GPIO_PIN_MASK) != 0x00U) &&\ + (((uint32_t)(__PIN__) & ~GPIO_PIN_MASK) == 0x00U)) + +#define IS_GPIO_COMMON_PIN(__RESETMASK__, __SETMASK__) \ + (((uint32_t)(__RESETMASK__) & (uint32_t)(__SETMASK__)) == 0x00u) + +#define IS_GPIO_MODE(__MODE__) (((__MODE__) == GPIO_MODE_INPUT) ||\ + ((__MODE__) == GPIO_MODE_OUTPUT_PP) ||\ + ((__MODE__) == GPIO_MODE_OUTPUT_OD) ||\ + ((__MODE__) == GPIO_MODE_AF_PP) ||\ + ((__MODE__) == GPIO_MODE_AF_OD) ||\ + ((__MODE__) == GPIO_MODE_IT_RISING) ||\ + ((__MODE__) == GPIO_MODE_IT_FALLING) ||\ + ((__MODE__) == GPIO_MODE_IT_RISING_FALLING) ||\ + ((__MODE__) == GPIO_MODE_EVT_RISING) ||\ + ((__MODE__) == GPIO_MODE_EVT_FALLING) ||\ + ((__MODE__) == GPIO_MODE_EVT_RISING_FALLING) ||\ + ((__MODE__) == GPIO_MODE_ANALOG)) + +#define IS_GPIO_SPEED(__SPEED__) (((__SPEED__) == GPIO_SPEED_FREQ_LOW) ||\ + ((__SPEED__) == GPIO_SPEED_FREQ_MEDIUM) ||\ + ((__SPEED__) == GPIO_SPEED_FREQ_HIGH) ||\ + ((__SPEED__) == GPIO_SPEED_FREQ_VERY_HIGH)) + +#define IS_GPIO_PULL(__PULL__) (((__PULL__) == GPIO_NOPULL) ||\ + ((__PULL__) == GPIO_PULLUP) || \ + ((__PULL__) == GPIO_PULLDOWN)) + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +#define IS_GPIO_PIN_ATTRIBUTES(__ATTRIBUTES__) (((__ATTRIBUTES__) == GPIO_PIN_SEC) ||\ + ((__ATTRIBUTES__) == GPIO_PIN_NSEC)) + +#endif /* __ARM_FEATURE_CMSE */ + +/** + * @} + */ + +/* Include GPIO HAL Extended module */ +#include "stm32h5xx_hal_gpio_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup GPIO_Exported_Functions GPIO Exported Functions + * @brief GPIO Exported Functions + * @{ + */ + +/** @addtogroup GPIO_Exported_Functions_Group1 Initialization/de-initialization functions + * @brief Initialization and Configuration functions + * @{ + */ + +/* Initialization and de-initialization functions *****************************/ +void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, const GPIO_InitTypeDef *pGPIO_Init); +void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin); + +/** + * @} + */ + +/** @addtogroup GPIO_Exported_Functions_Group2 IO operation functions + * @brief IO operation functions + * @{ + */ + +/* IO operation functions *****************************************************/ +GPIO_PinState HAL_GPIO_ReadPin(const GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin); +void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState); +void HAL_GPIO_WriteMultipleStatePin(GPIO_TypeDef *GPIOx, uint16_t PinReset, uint16_t PinSet); +void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin); +void HAL_GPIO_EnableHighSPeedLowVoltage(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin); +void HAL_GPIO_DisableHighSPeedLowVoltage(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin); +HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin); +void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin); +void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin); +void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin); + +/** + * @} + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** @addtogroup GPIO_Exported_Functions_Group3 IO attributes management functions + * @{ + */ + +/* IO attributes management functions *****************************************/ +void HAL_GPIO_ConfigPinAttributes(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, uint32_t PinAttributes); +HAL_StatusTypeDef HAL_GPIO_GetConfigPinAttributes(const GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, + uint32_t *pPinAttributes); + +/** + * @} + */ + +#endif /* __ARM_FEATURE_CMSE */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_GPIO_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_gpio_ex.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_gpio_ex.h new file mode 100644 index 0000000000..3e3bd18574 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_gpio_ex.h @@ -0,0 +1,470 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_gpio_ex.h + * @author MCD Application Team + * @brief Header file of GPIO HAL Extended module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_GPIO_EX_H +#define STM32H5xx_HAL_GPIO_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup GPIOEx GPIOEx + * @brief GPIO Extended HAL module driver + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup GPIOEx_Exported_Constants GPIOEx Exported Constants + * @{ + */ + +/** @defgroup GPIOEx_Alternate_function_selection GPIOEx Alternate function selection + * @{ + */ + +/** + * @brief AF 0 selection + */ +#define GPIO_AF0_RTC_50HZ ((uint8_t)0x00) /* RTC_50Hz Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00) /* MCO (MCO1 and MCO2) Alternate Function mapping */ +#define GPIO_AF0_SWJ ((uint8_t)0x00) /* SWJ (SWD and JTAG) Alternate Function mapping */ +#define GPIO_AF0_TRACE ((uint8_t)0x00) /* TRACE Alternate Function mapping */ +#define GPIO_AF0_CSLEEP ((uint8_t)0x00) /* CSLEEP Alternate Function mapping */ +#define GPIO_AF0_CSTOP ((uint8_t)0x00) /* CSTOP Alternate Function mapping */ +#define GPIO_AF0_CRS ((uint8_t)0x00) /* CRS Alternate Function mapping */ + +/** + * @brief AF 1 selection + */ +#define GPIO_AF1_TIM1 ((uint8_t)0x01) /* TIM1 Alternate Function mapping */ +#define GPIO_AF1_TIM2 ((uint8_t)0x01) /* TIM2 Alternate Function mapping */ +#if defined(TIM16) +#define GPIO_AF1_TIM16 ((uint8_t)0x01) /* TIM16 Alternate Function mapping */ +#endif /* TIM16 */ +#if defined(TIM17) +#define GPIO_AF1_TIM17 ((uint8_t)0x01) /* TIM17 Alternate Function mapping */ +#endif /* TIM17 */ +#if (defined(STM32H573xx) || defined(STM32H563xx) || defined(STM32H562xx)) +#define GPIO_AF1_LPTIM1 ((uint8_t)0x01) /* LPTIM1 Alternate Function mapping */ +#endif /* defined(STM32H573xx) || defined(STM32H563xx) || defined(STM32H562xx) */ + +/** + * @brief AF 2 selection + */ +#if defined(STM32H503xx) +#define GPIO_AF2_LPTIM1 ((uint8_t)0x02) /* LPTIM1 Alternate Function mapping */ +#endif /* STM32H503xx */ +#if defined(LPTIM3) +#define GPIO_AF2_LPTIM3 ((uint8_t)0x02) /* LPTIM3 Alternate Function mapping */ +#endif /* LPTIM3 */ +#if defined(SAI1) +#define GPIO_AF2_SAI1 ((uint8_t)0x02) /* SAI1 Alternate Function mapping */ +#endif /* SAI1 */ +#define GPIO_AF2_TIM3 ((uint8_t)0x02) /* TIM3 Alternate Function mapping */ +#if defined(TIM4) +#define GPIO_AF2_TIM4 ((uint8_t)0x02) /* TIM4 Alternate Function mapping */ +#endif /* TIM4 */ +#if defined(TIM5) +#define GPIO_AF2_TIM5 ((uint8_t)0x02) /* TIM5 Alternate Function mapping */ +#endif /* TIM5 */ +#if defined(TIM12) +#define GPIO_AF2_TIM12 ((uint8_t)0x02) /* TIM12 Alternate Function mapping */ +#endif /* TIM12 */ +#if defined(TIM15) +#define GPIO_AF2_TIM15 ((uint8_t)0x02) /* TIM15 Alternate Function mapping */ +#endif /* TIM15 */ +/** + * @brief AF 3 selection + */ +#define GPIO_AF3_I3C1 ((uint8_t)0x03) /* I3C1 Alternate Function mapping */ +#if defined(I3C2) +#define GPIO_AF3_I3C2 ((uint8_t)0x03) /* I3C2 Alternate Function mapping */ +#endif /* I3C2 */ +#define GPIO_AF3_LPTIM2 ((uint8_t)0x03) /* LPTIM2 Alternate Function mapping */ +#if defined(LPTIM3) +#define GPIO_AF3_LPTIM3 ((uint8_t)0x03) /* LPTIM3 Alternate Function mapping */ +#endif /* LPTIM3 */ +#define GPIO_AF3_LPUART1 ((uint8_t)0x03) /* LPUART1 Alternate Function mapping */ +#if defined(OCTOSPI1) +#define GPIO_AF3_OCTOSPI1 ((uint8_t)0x03) /* OCTOSPI1 Alternate Function mapping */ +#endif /* OCTOSPI1 */ +#if (defined(STM32H573xx) || defined(STM32H563xx) || defined(STM32H562xx)) +#define GPIO_AF3_TIM1 ((uint8_t)0x03) /* TIM1 Alternate Function mapping */ +#endif /* defined(STM32H573xx) || defined(STM32H563xx) || defined(STM32H562xx) */ +#if defined(TIM8) +#define GPIO_AF3_TIM8 ((uint8_t)0x03) /* TIM8 Alternate Function mapping */ +#endif /* TIM8 */ + +/** + * @brief AF 4 selection + */ +#if defined(CEC) +#define GPIO_AF4_CEC ((uint8_t)0x04) /* CEC Alternate Function mapping */ +#endif /* CEC */ +#if defined(DCMI) +#define GPIO_AF4_DCMI ((uint8_t)0x04) /* DCMI Alternate Function mapping */ +#define GPIO_AF4_PSSI ((uint8_t)0x04) /* PSSI Alternate Function mapping */ +#endif /* DCMI */ +#define GPIO_AF4_I2C1 ((uint8_t)0x04) /* I2C1 Alternate Function mapping */ +#define GPIO_AF4_I2C2 ((uint8_t)0x04) /* I2C2 Alternate Function mapping */ +#if defined(I2C3) +#define GPIO_AF4_I2C3 ((uint8_t)0x04) /* I2C3 Alternate Function mapping */ +#endif /* I2C3 */ +#if defined(I2C4) +#define GPIO_AF4_I2C4 ((uint8_t)0x04) /* I2C4 Alternate Function mapping */ +#endif /* I2C4 */ +#define GPIO_AF4_LPTIM1 ((uint8_t)0x04) /* LPTIM1 Alternate Function mapping */ +#define GPIO_AF4_LPTIM2 ((uint8_t)0x04) /* LPTIM2 Alternate Function mapping */ +#define GPIO_AF4_SPI1 ((uint8_t)0x04) /* SPI1 Alternate Function mapping */ +#if defined(TIM15) +#define GPIO_AF4_TIM15 ((uint8_t)0x04) /* TIM15 Alternate Function mapping */ +#endif /* TIM15 */ +#define GPIO_AF4_USART1 ((uint8_t)0x04) /* USART1 Alternate Function mapping */ +#if defined(STM32H503xx) +#define GPIO_AF4_USART2 ((uint8_t)0x04) /* USART2 Alternate Function mapping */ +#endif /* STM32H503xx */ + +/** + * @brief AF 5 selection + */ +#if defined(CEC) +#define GPIO_AF5_CEC ((uint8_t)0x05) /* CEC Alternate Function mapping */ +#endif /* CEC */ +#if (defined(STM32H573xx) || defined(STM32H563xx) || defined(STM32H562xx)) +#define GPIO_AF5_I3C1 ((uint8_t)0x05) /* I3C1 Alternate Function mapping */ +#define GPIO_AF5_SPI3 ((uint8_t)0x05) /* SPI3 Alternate Function mapping */ +#endif /* defined(STM32H573xx) || defined(STM32H563xx) || defined(STM32H562xx) */ +#define GPIO_AF5_LPTIM1 ((uint8_t)0x05) /* LPTIM1 Alternate Function mapping */ +#define GPIO_AF5_SPI1 ((uint8_t)0x05) /* SPI1 Alternate Function mapping */ +#define GPIO_AF5_SPI2 ((uint8_t)0x05) /* SPI2 Alternate Function mapping */ +#if defined(SPI4) +#define GPIO_AF5_SPI4 ((uint8_t)0x05) /* SPI4 Alternate Function mapping */ +#endif /* SPI4 */ +#if defined(SPI5) +#define GPIO_AF5_SPI5 ((uint8_t)0x05) /* SPI5 Alternate Function mapping */ +#endif /* SPI5 */ +#if defined(SPI6) +#define GPIO_AF5_SPI6 ((uint8_t)0x05) /* SPI6 Alternate Function mapping */ +#endif /* SPI6 */ + +/** + * @brief AF 6 selection + */ +#if defined(I2C4) +#define GPIO_AF6_I2C4 ((uint8_t)0x06) /* I2C4 Alternate Function mapping */ +#endif /* I2C4 */ +#if defined(OCTOSPI1) +#define GPIO_AF6_OCTOSPI1 ((uint8_t)0x06) /* OCTOSPI1 Alternate Function mapping */ +#endif /* OCTOSPI1 */ +#if defined(SAI1) +#define GPIO_AF6_SAI1 ((uint8_t)0x06) /* SAI1 Alternate Function mapping */ +#endif /* SAI1 */ +#if defined(STM32H503xx) +#define GPIO_AF6_SPI1 ((uint8_t)0x06) /* SPI1 Alternate Function mapping */ +#define GPIO_AF6_SPI2 ((uint8_t)0x06) /* SPI2 Alternate Function mapping */ +#endif /* STM32H503xx */ +#define GPIO_AF6_SPI3 ((uint8_t)0x06) /* SPI3 Alternate Function mapping */ +#if defined(SPI4) +#define GPIO_AF6_SPI4 ((uint8_t)0x06) /* SPI4 Alternate Function mapping */ +#endif /* SPI4 */ +#if defined(UART4) +#define GPIO_AF6_UART4 ((uint8_t)0x06) /* UART4 Alternate Function mapping */ +#endif /* UART4 */ +#if defined(UART12) +#define GPIO_AF6_UART12 ((uint8_t)0x06) /* UART12 Alternate Function mapping */ +#endif /* UART12 */ +#if defined(USART10) +#define GPIO_AF6_USART10 ((uint8_t)0x06) /* USART10 Alternate Function mapping */ +#endif /* USART10 */ +#if defined(UCPD1) +#define GPIO_AF6_UCPD1 ((uint8_t)0x06) /* UCPD1 Alternate Function mapping */ +#endif /* UCPD1 */ + +/** + * @brief AF 7 selection + */ +#if defined(SDMMC1) +#define GPIO_AF7_SDMMC1 ((uint8_t)0x07) /* SDMMC1 Alternate Function mapping */ +#endif /* SDMMC1 */ +#define GPIO_AF7_SPI2 ((uint8_t)0x07) /* SPI2 Alternate Function mapping */ +#define GPIO_AF7_SPI3 ((uint8_t)0x07) /* SPI3 Alternate Function mapping */ +#if defined(SPI6) +#define GPIO_AF7_SPI6 ((uint8_t)0x07) /* SPI6 Alternate Function mapping */ +#endif /* SPI6 */ +#if defined(UART7) +#define GPIO_AF7_UART7 ((uint8_t)0x07) /* UART7 Alternate Function mapping */ +#endif /* UART7 */ +#if defined(UART8) +#define GPIO_AF7_UART8 ((uint8_t)0x07) /* UART8 Alternate Function mapping */ +#endif /* UART8 */ +#if defined(UART12) +#define GPIO_AF7_UART12 ((uint8_t)0x07) /* UART12 Alternate Function mapping */ +#endif /* UART12 */ +#define GPIO_AF7_USART1 ((uint8_t)0x07) /* USART1 Alternate Function mapping */ +#define GPIO_AF7_USART2 ((uint8_t)0x07) /* USART2 Alternate Function mapping */ +#define GPIO_AF7_USART3 ((uint8_t)0x07) /* USART3 Alternate Function mapping */ +#if defined(USART6) +#define GPIO_AF7_USART6 ((uint8_t)0x07) /* USART6 Alternate Function mapping */ +#endif /* USART6 */ +#if defined(USART10) +#define GPIO_AF7_USART10 ((uint8_t)0x07) /* USART10 Alternate Function mapping */ +#endif /* USART10 */ +#if defined(USART11) +#define GPIO_AF7_USART11 ((uint8_t)0x07) /* USART11 Alternate Function mapping */ +#endif /* USART11 */ + +/** + * @brief AF 8 selection + */ +#if defined(STM32H503xx) +#define GPIO_AF8_I2C2 ((uint8_t)0x08) /* I2C2 Alternate Function mapping */ +#define GPIO_AF8_I3C1 ((uint8_t)0x08) /* I3C1 Alternate Function mapping */ +#define GPIO_AF8_USART1 ((uint8_t)0x08) /* USART1 Alternate Function mapping */ +#endif /* STM32H503xx */ +#define GPIO_AF8_LPUART1 ((uint8_t)0x08) /* LPUART1 Alternate Function mapping */ +#if defined(SAI2) +#define GPIO_AF8_SAI2 ((uint8_t)0x08) /* SAI2 Alternate Function mapping */ +#endif /* SAI2 */ +#if defined(SDMMC1) +#define GPIO_AF8_SDMMC1 ((uint8_t)0x08) /* SDMMC1 Alternate Function mapping */ +#endif /* SDMMC1 */ +#if defined(SPI6) +#define GPIO_AF8_SPI6 ((uint8_t)0x08) /* SPI6 Alternate Function mapping */ +#endif /* SPI6 */ +#if defined(UART4) +#define GPIO_AF8_UART4 ((uint8_t)0x08) /* UART4 Alternate Function mapping */ +#endif /* UART4 */ +#if defined(UART5) +#define GPIO_AF8_UART5 ((uint8_t)0x08) /* UART5 Alternate Function mapping */ +#endif /* UART5 */ +#if defined(UART8) +#define GPIO_AF8_UART8 ((uint8_t)0x08) /* UART8 Alternate Function mapping */ +#endif /* UART8 */ + +/** + * @brief AF 9 selection + */ +#define GPIO_AF9_FDCAN1 ((uint8_t)0x09) /* FDCAN1 Alternate Function mapping */ +#if defined(FDCAN2) +#define GPIO_AF9_FDCAN2 ((uint8_t)0x09) /* FDCAN2 Alternate Function mapping */ +#endif /* FDCAN2 */ +#if defined(FMC_BANK1) +#define GPIO_AF9_FMC ((uint8_t)0x09) /* FMC Alternate Function mapping */ +#endif /* FMC_BANK1 */ +#if defined(OCTOSPI1) +#define GPIO_AF9_OCTOSPI1 ((uint8_t)0x09) /* OCTOSPI1 Alternate Function mapping */ +#endif /* OCTOSPI1 */ +#if defined(SDMMC2) +#define GPIO_AF9_SDMMC2 ((uint8_t)0x09) /* SDMMC2 Alternate Function mapping */ +#endif /* SDMMC2 */ +#if defined(TIM13) +#define GPIO_AF9_TIM13 ((uint8_t)0x09) /* TIM13 Alternate Function mapping */ +#endif /* TIM13 */ +#if defined(TIM14) +#define GPIO_AF9_TIM14 ((uint8_t)0x09) /* TIM14 Alternate Function mapping */ +#endif /* TIM14 */ +#if defined(STM32H503xx) +#define GPIO_AF9_USART2 ((uint8_t)0x09) /* USART2 Alternate Function mapping */ +#define GPIO_AF9_USART3 ((uint8_t)0x09) /* USART3 Alternate Function mapping */ +#endif /* STM32H503xx */ + +/** + * @brief AF 10 selection + */ +#define GPIO_AF10_CRS ((uint8_t)0x0A) /* CRS Alternate Function mapping */ +#if defined(STM32H503xx) +#define GPIO_AF10_I3C1 ((uint8_t)0x0A) /* I3C1 Alternate Function mapping */ +#define GPIO_AF10_I3C2 ((uint8_t)0x0A) /* I3C2 Alternate Function mapping */ +#define GPIO_AF10_SPI3 ((uint8_t)0x0A) /* SPI3 Alternate Function mapping */ +#endif /* STM32H503xx */ +#if defined(FMC_BANK1) +#define GPIO_AF10_FMC ((uint8_t)0x0A) /* FMC Alternate Function mapping */ +#endif /* FMC_BANK1 */ +#if defined(OCTOSPI1) +#define GPIO_AF10_OCTOSPI1 ((uint8_t)0x0A) /* OCTOSPI1 Alternate Function mapping */ +#endif /* OCTOSPI1 */ +#if defined(SAI2) +#define GPIO_AF10_SAI2 ((uint8_t)0x0A) /* SAI2 Alternate Function mapping */ +#endif /* SAI2 */ +#if defined(SDMMC2) +#define GPIO_AF10_SDMMC2 ((uint8_t)0x0A) /* SDMMC2 Alternate Function mapping */ +#endif /* SDMMC2 */ +#if defined(TIM8) +#define GPIO_AF10_TIM8 ((uint8_t)0x0A) /* TIM8 Alternate Function mapping */ +#endif /* TIM8 */ +#define GPIO_AF10_USB ((uint8_t)0x0A) /* USB Alternate Function mapping */ + +/** + * @brief AF 11 selection + */ +#if defined(ETH) +#define GPIO_AF11_ETH ((uint8_t)0x0B) /* ETH Alternate Function mapping */ +#endif /* ETH */ +#if defined(FMC_BANK1) +#define GPIO_AF11_FMC ((uint8_t)0x0B) /* FMC Alternate Function mapping */ +#endif /* FMC_BANK1 */ +#if defined(OCTOSPI1) +#define GPIO_AF11_OCTOSPI1 ((uint8_t)0x0B) /* OCTOSPI1 Alternate Function mapping */ +#endif /* OCTOSPI1 */ +#if defined(SDMMC2) +#define GPIO_AF11_SDMMC2 ((uint8_t)0x0B) /* SDMMC2 Alternate Function mapping */ +#endif /* SDMMC2 */ +#if defined(UART7) +#define GPIO_AF11_UART7 ((uint8_t)0x0B) /* UART7 Alternate Function mapping */ +#endif /* UART7 */ +#if defined(UART9) +#define GPIO_AF11_UART9 ((uint8_t)0x0B) /* UART9 Alternate Function mapping */ +#endif /* UART9 */ +#if defined(UCPD1) +#define GPIO_AF11_UCPD1 ((uint8_t)0x0B) /* UCPD1 Alternate Function mapping */ +#endif /* UCPD1 */ +#if defined(STM32H503xx) +#define GPIO_AF11_I2C1 ((uint8_t)0x0B) /* I2C1 Alternate Function mapping */ +#define GPIO_AF11_I2C2 ((uint8_t)0x0B) /* I2C2 Alternate Function mapping */ +#define GPIO_AF11_SPI2 ((uint8_t)0x0B) /* SPI2 Alternate Function mapping */ +#define GPIO_AF11_USART2 ((uint8_t)0x0B) /* USART2 Alternate Function mapping */ +#endif /* STM32H503xx */ + +/** + * @brief AF 12 selection + */ +#if defined(FMC_BANK1) +#define GPIO_AF12_FMC ((uint8_t)0x0C) /* FMC Alternate Function mapping */ +#endif /* FMC_BANK1 */ +#if defined(SDMMC1) +#define GPIO_AF12_SDMMC1 ((uint8_t)0x0C) /* SDMMC1 Alternate Function mapping */ +#endif /* SDMMC1 */ +#if defined(STM32H503xx) +#define GPIO_AF12_COMP1 ((uint8_t)0x0C) /* COMP1 Alternate Function mapping */ +#define GPIO_AF12_SPI1 ((uint8_t)0x0C) /* SPI1 Alternate Function mapping */ +#endif /* STM32H503xx */ + +/** + * @brief AF 13 selection + */ +#if defined(DCMI) +#define GPIO_AF13_DCMI ((uint8_t)0x0D) /* DCMI Alternate Function mapping */ +#define GPIO_AF13_PSSI ((uint8_t)0x0D) /* PSSI Alternate Function mapping */ +#endif /* DCMI */ +#if defined(FMC_BANK1) +#define GPIO_AF13_FMC ((uint8_t)0x0D) /* FMC Alternate Function mapping */ +#endif /* FMC_BANK1 */ +#if defined(LPTIM5) +#define GPIO_AF13_LPTIM5 ((uint8_t)0x0D) /* LPTIM5 Alternate Function mapping */ +#endif /* LPTIM5 */ +#if defined(STM32H503xx) +#define GPIO_AF13_USART2 ((uint8_t)0x0D) /* USART2 Alternate Function mapping */ +#define GPIO_AF13_USART3 ((uint8_t)0x0D) /* USART3 Alternate Function mapping */ +#endif /* STM32H503xx */ + +/** + * @brief AF 14 selection + */ +#if defined(STM32H503xx) +#define GPIO_AF14_LPTIM1 ((uint8_t)0x0E) /* LPTIM1 Alternate Function mapping */ +#define GPIO_AF14_LPTIM2 ((uint8_t)0x0E) /* LPTIM2 Alternate Function mapping */ +#define GPIO_AF14_TIM1 ((uint8_t)0x0E) /* TIM1 Alternate Function mapping */ +#define GPIO_AF14_TIM2 ((uint8_t)0x0E) /* TIM2 Alternate Function mapping */ +#define GPIO_AF14_TIM3 ((uint8_t)0x0E) /* TIM3 Alternate Function mapping */ +#endif /* STM32H503xx */ +#if defined(LPTIM3) +#define GPIO_AF14_LPTIM3 ((uint8_t)0x0E) /* LPTIM3 Alternate Function mapping */ +#endif /* LPTIM3 */ +#if defined(LPTIM4) +#define GPIO_AF14_LPTIM4 ((uint8_t)0x0E) /* LPTIM4 Alternate Function mapping */ +#endif /* LPTIM4 */ +#if defined(LPTIM5) +#define GPIO_AF14_LPTIM5 ((uint8_t)0x0E) /* LPTIM5 Alternate Function mapping */ +#endif /* LPTIM5 */ +#if defined(LPTIM6) +#define GPIO_AF14_LPTIM6 ((uint8_t)0x0E) /* LPTIM6 Alternate Function mapping */ +#endif /* LPTIM6 */ +#if (defined(STM32H573xx) || defined(STM32H563xx) || defined(STM32H562xx)) +#define GPIO_AF14_TIM2 ((uint8_t)0x0E) /* TIM2 Alternate Function mapping */ +#endif /* defined(STM32H573xx) || defined(STM32H563xx) || defined(STM32H562xx) */ +#if defined(UART5) +#define GPIO_AF14_UART5 ((uint8_t)0x0E) /* UART5 Alternate Function mapping */ +#endif /* UART5 */ + +/** + * @brief AF 15 selection + */ +#define GPIO_AF15_EVENTOUT ((uint8_t)0x0F) /* EVENTOUT Alternate Function mapping */ + +#define IS_GPIO_AF(AF) ((AF) <= (uint8_t)0x0F) + + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup GPIOEx_Exported_Macros GPIOEx Exported Macros + * @{ + */ + +/** @defgroup GPIOEx_Get_Port_Index GPIOEx_Get Port Index + * @{ + */ + + +/* GPIO_Peripheral_Memory_Mapping Peripheral Memory Mapping */ + +#if (defined(STM32H573xx) || defined(STM32H563xx) || defined(STM32H562xx) || defined(STM32H503xx)) +#define GPIO_GET_INDEX(__GPIOx__) (((uint32_t )(__GPIOx__) & (~GPIOA_BASE)) >> 10) +#endif /* (defined(STM32H573xx) || defined(STM32H563xx) || defined(STM32H562xx) || defined(STM32H503xx)) */ + + + + +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_GPIO_EX_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_gtzc.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_gtzc.h new file mode 100644 index 0000000000..ddce933a44 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_gtzc.h @@ -0,0 +1,696 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_gtzc.h + * @author MCD Application Team + * @brief Header file of GTZC HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_GTZC_H +#define STM32H5xx_HAL_GTZC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup GTZC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup GTZC_Exported_Types GTZC Exported Types + * @{ + */ + +/*!< Values needed for MPCBB_Attribute_ConfigTypeDef structure sizing */ +#define GTZC_MPCBB_NB_VCTR_REG_MAX (32U) +#define GTZC_MPCBB_NB_LCK_VCTR_REG_MAX (1U) +typedef struct +{ + uint32_t MPCBB_SecConfig_array[GTZC_MPCBB_NB_VCTR_REG_MAX]; /*!< Each element specifies secure access mode for + a super-block. Each bit corresponds to a block + inside the super-block. 0 means non-secure, + 1 means secure */ + uint32_t MPCBB_PrivConfig_array[GTZC_MPCBB_NB_VCTR_REG_MAX]; /*!< Each element specifies privilege access mode for + a super-block. Each bit corresponds to a block + inside the super-block. 0 means non-privilege, + 1 means privilege */ + uint32_t MPCBB_LockConfig_array[GTZC_MPCBB_NB_LCK_VCTR_REG_MAX]; /*!< Each bit specifies the lock configuration of + a super-block (32 blocks). 0 means unlocked, + 1 means locked */ +} MPCBB_Attribute_ConfigTypeDef; + +typedef struct +{ + uint32_t SecureRWIllegalMode; /*!< Secure read/write illegal access + field. It can be a value of @ref GTZC_MPCBB_SecureRWIllegalMode */ + uint32_t InvertSecureState; /*!< Default security state field (can be inverted or not). + It can be a value of @ref GTZC_MPCBB_InvertSecureState */ + MPCBB_Attribute_ConfigTypeDef AttributeConfig; /*!< MPCBB attribute configuration sub-structure */ +} MPCBB_ConfigTypeDef; + +typedef struct +{ + uint32_t AreaId; /*!< Area identifier field. It can be a value of @ref + GTZC_MPCWM_AreaId */ + uint32_t Offset; /*!< Offset of the watermark area, starting from the selected + memory base address. It must aligned on 128KB for FMC + and OCTOSPI memories, and on 32-byte for BKPSRAM */ + uint32_t Length; /*!< Length of the watermark area, starting from the selected + Offset. It must aligned on 128KB for FMC and OCTOSPI + memories, and on 32-byte for BKPSRAM */ + uint32_t Attribute; /*!< Attributes of the watermark area. It can be a value + of @ref GTZC_MPCWM_Attribute */ + uint32_t Lock; /*!< Lock of the watermark area. It can be a value + of @ref GTZC_MPCWM_Lock */ + uint32_t AreaStatus; /*!< Status of the watermark area. It can be set to + ENABLE or DISABLE */ +} MPCWM_ConfigTypeDef; + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ + +/** @defgroup GTZC_Private_Constants GTZC Private Constants + * @{ + */ + +/** @defgroup GTZC_Private_PeriphId_composition GTZC Peripheral identifier composition + * @{ + */ + +/* composition definition for Peripheral identifier parameter (PeriphId) used in + * HAL_GTZC_TZSC_ConfigPeriphAttributes() and HAL_GTZC_TZSC_GetConfigPeriphAttributes() + * functions and also in all HAL_GTZC_TZIC relative functions. + * Bitmap Definition + * bits[31:28] Field "register". Define the register index a peripheral belongs to. + * Each bit is dedicated to a single register. + * bit[5] Field "all peripherals". If this bit is set then the PeriphId targets + * all peripherals within all registers. + * bits[4:0] Field "bit position". Define the bit position within the + * register dedicated to the peripheral, value from 0 to 31. + */ +#define GTZC_PERIPH_REG_SHIFT (28U) +#define GTZC_PERIPH_REG (0xF0000000U) +#define GTZC1_PERIPH_REG1 (0x00000000U) +#define GTZC1_PERIPH_REG2 (0x10000000U) +#define GTZC1_PERIPH_REG3 (0x20000000U) +#if defined (GTZC_TZIC1) +#define GTZC1_PERIPH_REG4 (0x30000000U) +#endif /* defined (GTZC_TZIC1) */ +#define GTZC_PERIPH_BIT_POSITION (0x0000001FU) + +/** + * @} + */ + +/** @defgroup GTZC_Private_Attributes_Msk GTZC Attributes Masks + * @{ + */ +#define GTZC_ATTR_SEC_MASK 0x100U +#define GTZC_ATTR_PRIV_MASK 0x200U + +/** + * @} + */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup GTZC_Exported_Constants GTZC Exported Constants + * @{ + */ + +/** @defgroup GTZC_MPCBB_SecureRWIllegalMode GTZC MPCBB SRWILADIS values + * @{ + */ + +#define GTZC_MPCBB_SRWILADIS_ENABLE (0U) +#define GTZC_MPCBB_SRWILADIS_DISABLE (GTZC_MPCBB_CR_SRWILADIS_Msk) + +/** + * @} + */ + +/** @defgroup GTZC_MPCBB_InvertSecureState GTZC MPCBB INVSECSTATE values + * @{ + */ + +#define GTZC_MPCBB_INVSECSTATE_NOT_INVERTED (0U) +#define GTZC_MPCBB_INVSECSTATE_INVERTED (GTZC_MPCBB_CR_INVSECSTATE_Msk) + +/** + * @} + */ + +/** @defgroup GTZC_MPCWM_AreaId GTZC MPCWM area identifier values + * @{ + */ + +#define GTZC_TZSC_MPCWM_ID1 (0U) +#define GTZC_TZSC_MPCWM_ID2 (1U) + +/** + * @} + */ + +/** @defgroup GTZC_TZSC_TZIC_PeriphId GTZC TZSC and TZIC Peripheral identifier values + * @{ + */ +#define GTZC_PERIPH_TIM2 (GTZC1_PERIPH_REG1 | GTZC_CFGR1_TIM2_Pos) +#define GTZC_PERIPH_TIM3 (GTZC1_PERIPH_REG1 | GTZC_CFGR1_TIM3_Pos) +#if defined (TIM4) +#define GTZC_PERIPH_TIM4 (GTZC1_PERIPH_REG1 | GTZC_CFGR1_TIM4_Pos) +#endif /* defined (TIM4) */ +#if defined (TIM5) +#define GTZC_PERIPH_TIM5 (GTZC1_PERIPH_REG1 | GTZC_CFGR1_TIM5_Pos) +#endif /* defined (TIM5) */ +#define GTZC_PERIPH_TIM6 (GTZC1_PERIPH_REG1 | GTZC_CFGR1_TIM6_Pos) +#define GTZC_PERIPH_TIM7 (GTZC1_PERIPH_REG1 | GTZC_CFGR1_TIM7_Pos) +#if defined (TIM12) +#define GTZC_PERIPH_TIM12 (GTZC1_PERIPH_REG1 | GTZC_CFGR1_TIM12_Pos) +#endif /* defined (TIM12) */ +#if defined (TIM13) +#define GTZC_PERIPH_TIM13 (GTZC1_PERIPH_REG1 | GTZC_CFGR1_TIM13_Pos) +#endif /* defined (TIM13) */ +#if defined (TIM14) +#define GTZC_PERIPH_TIM14 (GTZC1_PERIPH_REG1 | GTZC_CFGR1_TIM14_Pos) +#endif /* defined (TIM14) */ +#define GTZC_PERIPH_WWDG (GTZC1_PERIPH_REG1 | GTZC_CFGR1_WWDG_Pos) +#define GTZC_PERIPH_IWDG (GTZC1_PERIPH_REG1 | GTZC_CFGR1_IWDG_Pos) +#define GTZC_PERIPH_SPI2 (GTZC1_PERIPH_REG1 | GTZC_CFGR1_SPI2_Pos) +#define GTZC_PERIPH_SPI3 (GTZC1_PERIPH_REG1 | GTZC_CFGR1_SPI3_Pos) +#define GTZC_PERIPH_USART2 (GTZC1_PERIPH_REG1 | GTZC_CFGR1_USART2_Pos) +#define GTZC_PERIPH_USART3 (GTZC1_PERIPH_REG1 | GTZC_CFGR1_USART3_Pos) +#if defined (UART4) +#define GTZC_PERIPH_UART4 (GTZC1_PERIPH_REG1 | GTZC_CFGR1_UART4_Pos) +#endif /* defined (UART4) */ +#if defined (UART5) +#define GTZC_PERIPH_UART5 (GTZC1_PERIPH_REG1 | GTZC_CFGR1_UART5_Pos) +#endif /* defined (UART5) */ +#define GTZC_PERIPH_I2C1 (GTZC1_PERIPH_REG1 | GTZC_CFGR1_I2C1_Pos) +#define GTZC_PERIPH_I2C2 (GTZC1_PERIPH_REG1 | GTZC_CFGR1_I2C2_Pos) +#define GTZC_PERIPH_I3C1 (GTZC1_PERIPH_REG1 | GTZC_CFGR1_I3C1_Pos) +#define GTZC_PERIPH_CRS (GTZC1_PERIPH_REG1 | GTZC_CFGR1_CRS_Pos) +#if defined (USART6) +#define GTZC_PERIPH_USART6 (GTZC1_PERIPH_REG1 | GTZC_CFGR1_USART6_Pos) +#endif /* defined (USART6) */ +#if defined (USART10) +#define GTZC_PERIPH_USART10 (GTZC1_PERIPH_REG1 | GTZC_CFGR1_USART10_Pos) +#endif /* defined (USART10) */ +#if defined (USART11) +#define GTZC_PERIPH_USART11 (GTZC1_PERIPH_REG1 | GTZC_CFGR1_USART11_Pos) +#endif /* defined (USART11) */ +#if defined (CEC) +#define GTZC_PERIPH_HDMICEC (GTZC1_PERIPH_REG1 | GTZC_CFGR1_HDMICEC_Pos) +#endif /* defined (CEC) */ +#define GTZC_PERIPH_DAC1 (GTZC1_PERIPH_REG1 | GTZC_CFGR1_DAC1_Pos) +#if defined (UART7) +#define GTZC_PERIPH_UART7 (GTZC1_PERIPH_REG1 | GTZC_CFGR1_UART7_Pos) +#endif /* defined (UART7) */ +#if defined (UART8) +#define GTZC_PERIPH_UART8 (GTZC1_PERIPH_REG1 | GTZC_CFGR1_UART8_Pos) +#endif /* defined (UART8) */ +#if defined (UART9) +#define GTZC_PERIPH_UART9 (GTZC1_PERIPH_REG1 | GTZC_CFGR1_UART9_Pos) +#endif /* defined (UART9) */ +#if defined (UART12) +#define GTZC_PERIPH_UART12 (GTZC1_PERIPH_REG1 | GTZC_CFGR1_UART12_Pos) +#endif /* defined (UART12) */ +#define GTZC_PERIPH_DTS (GTZC1_PERIPH_REG1 | GTZC_CFGR1_DTS_Pos) +#define GTZC_PERIPH_LPTIM2 (GTZC1_PERIPH_REG1 | GTZC_CFGR1_LPTIM2_Pos) + +#define GTZC_PERIPH_FDCAN1 (GTZC1_PERIPH_REG2 | GTZC_CFGR2_FDCAN1_Pos) +#if defined (FDCAN2) +#define GTZC_PERIPH_FDCAN2 (GTZC1_PERIPH_REG2 | GTZC_CFGR2_FDCAN2_Pos) +#endif /* defined (FDCAN2) */ +#if defined (UCPD1) +#define GTZC_PERIPH_UCPD1 (GTZC1_PERIPH_REG2 | GTZC_CFGR2_UCPD1_Pos) +#endif /* defined (UCPD1) */ +#if defined (OPAMP1) +#define GTZC_PERIPH_OPAMP (GTZC1_PERIPH_REG2 | GTZC_CFGR2_OPAMP_Pos) +#endif /* defined (OPAMP1) */ +#if defined (COMP1) +#define GTZC_PERIPH_COMP (GTZC1_PERIPH_REG2 | GTZC_CFGR2_COMP_Pos) +#endif /* defined (COMP1) */ +#define GTZC_PERIPH_TIM1 (GTZC1_PERIPH_REG2 | GTZC_CFGR2_TIM1_Pos) +#define GTZC_PERIPH_SPI1 (GTZC1_PERIPH_REG2 | GTZC_CFGR2_SPI1_Pos) +#if defined (TIM8) +#define GTZC_PERIPH_TIM8 (GTZC1_PERIPH_REG2 | GTZC_CFGR2_TIM8_Pos) +#endif /* defined (TIM8) */ +#define GTZC_PERIPH_USART1 (GTZC1_PERIPH_REG2 | GTZC_CFGR2_USART1_Pos) +#if defined (TIM15) +#define GTZC_PERIPH_TIM15 (GTZC1_PERIPH_REG2 | GTZC_CFGR2_TIM15_Pos) +#endif /* defined (TIM15) */ +#if defined (TIM16) +#define GTZC_PERIPH_TIM16 (GTZC1_PERIPH_REG2 | GTZC_CFGR2_TIM16_Pos) +#endif /* defined (TIM16) */ +#if defined (TIM17) +#define GTZC_PERIPH_TIM17 (GTZC1_PERIPH_REG2 | GTZC_CFGR2_TIM17_Pos) +#endif /* defined (TIM17) */ +#if defined (SPI4) +#define GTZC_PERIPH_SPI4 (GTZC1_PERIPH_REG2 | GTZC_CFGR2_SPI4_Pos) +#endif /* defined (SPI4) */ +#if defined (SPI6) +#define GTZC_PERIPH_SPI6 (GTZC1_PERIPH_REG2 | GTZC_CFGR2_SPI6_Pos) +#endif /* defined (SPI6) */ +#if defined (SAI1) +#define GTZC_PERIPH_SAI1 (GTZC1_PERIPH_REG2 | GTZC_CFGR2_SAI1_Pos) +#endif /* defined (SAI1) */ +#if defined (SAI2) +#define GTZC_PERIPH_SAI2 (GTZC1_PERIPH_REG2 | GTZC_CFGR2_SAI2_Pos) +#endif /* defined (SAI2) */ +#define GTZC_PERIPH_USB (GTZC1_PERIPH_REG2 | GTZC_CFGR2_USB_Pos) +#if defined (SPI5) +#define GTZC_PERIPH_SPI5 (GTZC1_PERIPH_REG2 | GTZC_CFGR2_SPI5_Pos) +#endif /* defined (SPI5) */ +#define GTZC_PERIPH_LPUART1 (GTZC1_PERIPH_REG2 | GTZC_CFGR2_LPUART1_Pos) +#if defined (I2C3) +#define GTZC_PERIPH_I2C3 (GTZC1_PERIPH_REG2 | GTZC_CFGR2_I2C3_Pos) +#endif /* defined (I2C3) */ +#if defined (I2C4) +#define GTZC_PERIPH_I2C4 (GTZC1_PERIPH_REG2 | GTZC_CFGR2_I2C4_Pos) +#endif /* defined (I2C4) */ +#define GTZC_PERIPH_LPTIM1 (GTZC1_PERIPH_REG2 | GTZC_CFGR2_LPTIM1_Pos) +#if defined (LPTIM3) +#define GTZC_PERIPH_LPTIM3 (GTZC1_PERIPH_REG2 | GTZC_CFGR2_LPTIM3_Pos) +#endif /* defined (LPTIM3) */ +#if defined (LPTIM4) +#define GTZC_PERIPH_LPTIM4 (GTZC1_PERIPH_REG2 | GTZC_CFGR2_LPTIM4_Pos) +#endif /* defined (LPTIM4) */ +#if defined (LPTIM5) +#define GTZC_PERIPH_LPTIM5 (GTZC1_PERIPH_REG2 | GTZC_CFGR2_LPTIM5_Pos) +#endif /* defined (LPTIM5) */ + +#if defined (LPTIM6) +#define GTZC_PERIPH_LPTIM6 (GTZC1_PERIPH_REG3 | GTZC_CFGR3_LPTIM6_Pos) +#endif /* defined (LPTIM6) */ +#if defined (VREFBUF) +#define GTZC_PERIPH_VREFBUF (GTZC1_PERIPH_REG3 | GTZC_CFGR3_VREFBUF_Pos) +#endif /* defined (VREFBUF) */ +#if defined (I3C2) +#define GTZC_PERIPH_I3C2 (GTZC1_PERIPH_REG3 | GTZC_CFGR3_I3C2_Pos) +#endif /* defined (I3C2) */ +#define GTZC_PERIPH_CRC (GTZC1_PERIPH_REG3 | GTZC_CFGR3_CRC_Pos) +#if defined (CORDIC) +#define GTZC_PERIPH_CORDIC (GTZC1_PERIPH_REG3 | GTZC_CFGR3_CORDIC_Pos) +#endif /* defined (CORDIC) */ +#if defined (FMAC) +#define GTZC_PERIPH_FMAC (GTZC1_PERIPH_REG3 | GTZC_CFGR3_FMAC_Pos) +#endif /* defined (FMAC) */ +#if defined (ETH) +#define GTZC_PERIPH_ETHERNET (GTZC1_PERIPH_REG3 | GTZC_CFGR3_ETHERNET_Pos) +#endif /* defined (ETH) */ +#define GTZC_PERIPH_ICACHE_REG (GTZC1_PERIPH_REG3 | GTZC_CFGR3_ICACHE_REG_Pos) +#if defined (DCACHE1) +#define GTZC_PERIPH_DCACHE1_REG (GTZC1_PERIPH_REG3 | GTZC_CFGR3_DCACHE1_REG_Pos) +#endif /* defined (DCACHE1) */ +#define GTZC_PERIPH_ADC (GTZC1_PERIPH_REG3 | GTZC_CFGR3_ADC_Pos) +#if defined (DCMI) +#define GTZC_PERIPH_DCMI_PSSI (GTZC1_PERIPH_REG3 | GTZC_CFGR3_DCMI_PSSI_Pos) +#endif /* defined (DCMI) */ +#if defined (AES) +#define GTZC_PERIPH_AES (GTZC1_PERIPH_REG3 | GTZC_CFGR3_AES_Pos) +#endif /* defined (AES) */ +#if defined (HASH) +#define GTZC_PERIPH_HASH (GTZC1_PERIPH_REG3 | GTZC_CFGR3_HASH_Pos) +#endif /* defined (HASH) */ +#define GTZC_PERIPH_RNG (GTZC1_PERIPH_REG3 | GTZC_CFGR3_RNG_Pos) +#if defined (PKA) +#define GTZC_PERIPH_PKA (GTZC1_PERIPH_REG3 | GTZC_CFGR3_PKA_Pos) +#endif /* defined (PKA) */ +#if defined (SAES) +#define GTZC_PERIPH_SAES (GTZC1_PERIPH_REG3 | GTZC_CFGR3_SAES_Pos) +#endif /* defined (SAES) */ +#if defined (SDMMC1) +#define GTZC_PERIPH_SDMMC1 (GTZC1_PERIPH_REG3 | GTZC_CFGR3_SDMMC1_Pos) +#endif /* defined (SDMMC1) */ +#if defined (SDMMC2) +#define GTZC_PERIPH_SDMMC2 (GTZC1_PERIPH_REG3 | GTZC_CFGR3_SDMMC2_Pos) +#endif /* defined (SDMMC2) */ +#if defined (FMC_Bank1_R) +#define GTZC_PERIPH_FMC_REG (GTZC1_PERIPH_REG3 | GTZC_CFGR3_FMC_REG_Pos) +#endif /* defined (FMC_Bank1_R) */ +#if defined (OCTOSPI1) +#define GTZC_PERIPH_OCTOSPI1 (GTZC1_PERIPH_REG3 | GTZC_CFGR3_OCTOSPI1_Pos) +#endif /* defined (OCTOSPI1) */ +#define GTZC_PERIPH_RAMCFG (GTZC1_PERIPH_REG3 | GTZC_CFGR3_RAMCFG_Pos) + +#if defined (GTZC_TZIC1) +#define GTZC_PERIPH_GPDMA1 (GTZC1_PERIPH_REG4 | GTZC_CFGR4_GPDMA1_Pos) +#define GTZC_PERIPH_GPDMA2 (GTZC1_PERIPH_REG4 | GTZC_CFGR4_GPDMA2_Pos) +#define GTZC_PERIPH_FLASH (GTZC1_PERIPH_REG4 | GTZC_CFGR4_FLASH_Pos) +#define GTZC_PERIPH_FLASH_REG (GTZC1_PERIPH_REG4 | GTZC_CFGR4_FLASH_REG_Pos) +#define GTZC_PERIPH_OTFDEC2 (GTZC1_PERIPH_REG4 | GTZC_CFGR4_OTFDEC2_Pos) +#define GTZC_PERIPH_OTFDEC1 (GTZC1_PERIPH_REG4 | GTZC_CFGR4_OTFDEC1_Pos) +#define GTZC_PERIPH_SBS (GTZC1_PERIPH_REG4 | GTZC_CFGR4_SBS_Pos) +#define GTZC_PERIPH_RTC (GTZC1_PERIPH_REG4 | GTZC_CFGR4_RTC_Pos) +#define GTZC_PERIPH_TAMP (GTZC1_PERIPH_REG4 | GTZC_CFGR4_TAMP_Pos) +#define GTZC_PERIPH_PWR (GTZC1_PERIPH_REG4 | GTZC_CFGR4_PWR_Pos) +#define GTZC_PERIPH_RCC (GTZC1_PERIPH_REG4 | GTZC_CFGR4_RCC_Pos) +#define GTZC_PERIPH_EXTI (GTZC1_PERIPH_REG4 | GTZC_CFGR4_EXTI_Pos) +#define GTZC_PERIPH_TZSC (GTZC1_PERIPH_REG4 | GTZC_CFGR4_TZSC_Pos) +#define GTZC_PERIPH_TZIC (GTZC1_PERIPH_REG4 | GTZC_CFGR4_TZIC_Pos) +#define GTZC_PERIPH_OCTOSPI1_MEM (GTZC1_PERIPH_REG4 | GTZC_CFGR4_OCTOSPI1_MEM_Pos) +#define GTZC_PERIPH_FMC_MEM (GTZC1_PERIPH_REG4 | GTZC_CFGR4_FMC_MEM_Pos) +#define GTZC_PERIPH_BKPSRAM (GTZC1_PERIPH_REG4 | GTZC_CFGR4_BKPSRAM_Pos) +#define GTZC_PERIPH_SRAM1 (GTZC1_PERIPH_REG4 | GTZC_CFGR4_SRAM1_Pos) +#define GTZC_PERIPH_MPCBB1_REG (GTZC1_PERIPH_REG4 | GTZC_CFGR4_MPCBB1_REG_Pos) +#define GTZC_PERIPH_SRAM2 (GTZC1_PERIPH_REG4 | GTZC_CFGR4_SRAM2_Pos) +#define GTZC_PERIPH_MPCBB2_REG (GTZC1_PERIPH_REG4 | GTZC_CFGR4_MPCBB2_REG_Pos) +#define GTZC_PERIPH_SRAM3 (GTZC1_PERIPH_REG4 | GTZC_CFGR4_SRAM3_Pos) +#define GTZC_PERIPH_MPCBB3_REG (GTZC1_PERIPH_REG4 | GTZC_CFGR4_MPCBB3_REG_Pos) +#endif /* defined (GTZC_TZIC1) */ + +#define GTZC_PERIPH_ALL (0x00000020U) + +/* Note that two maximum values are also defined here: + * - max number of securable AHB/APB peripherals or masters + * (used in TZSC sub-block) + * - max number of securable and TrustZone-aware AHB/APB peripherals or masters + * (used in TZIC sub-block) + */ +#define GTZC_TZSC_PERIPH_NUMBER (HAL_GTZC_GET_ARRAY_INDEX(GTZC_PERIPH_RAMCFG + 1U)) +#if defined (GTZC_TZIC1) +#define GTZC_TZIC_PERIPH_NUMBER (HAL_GTZC_GET_ARRAY_INDEX(GTZC_PERIPH_MPCBB3_REG + 1U)) +#endif /* defined (GTZC_TZIC1) */ + +/** + * @} + */ + +/** @defgroup GTZC_TZSC_PeriphAttributes GTZC TZSC peripheral attribute values + * @note secure and non-secure attributes are only available from secure state when the system + * implement the security (TZEN=1) + * @{ + */ + +/* user-oriented definitions for attribute parameter (PeriphAttributes) used in + * HAL_GTZC_TZSC_ConfigPeriphAttributes() and HAL_GTZC_TZSC_GetConfigPeriphAttributes() + * functions + */ +#if defined (GTZC_TZIC1) +#define GTZC_TZSC_PERIPH_SEC (GTZC_ATTR_SEC_MASK | 0x00000001U) /*!< Secure attribute */ +#define GTZC_TZSC_PERIPH_NSEC (GTZC_ATTR_SEC_MASK | 0x00000000U) /*!< Non-secure attribute */ +#endif /* (GTZC_TZIC1) */ +#define GTZC_TZSC_PERIPH_PRIV (GTZC_ATTR_PRIV_MASK | 0x00000002U) /*!< Privilege attribute */ +#define GTZC_TZSC_PERIPH_NPRIV (GTZC_ATTR_PRIV_MASK | 0x00000000U) /*!< Non-privilege attribute */ + +/** + * @} + */ + +#if defined (GTZC_TZSC_CR_LCK_Msk) +/** @defgroup GTZC_TZSC_Lock GTZC TZSC lock values + * @{ + */ + +/* user-oriented definitions for HAL_GTZC_TZSC_GetLock() returned value */ +#define GTZC_TZSC_LOCK_OFF (0U) +#define GTZC_TZSC_LOCK_ON GTZC_TZSC_CR_LCK_Msk + +/** + * @} + */ +#endif /* (GTZC_TZSC_CR_LCK_Msk) */ + +/** @defgroup GTZC_MPCWM_Group GTZC MPCWM values + * @{ + */ + +/* user-oriented definitions for TZSC_MPCWM */ +#define GTZC_TZSC_MPCWM_GRANULARITY_1 0x00020000U /* OCTOSPI & FMC granularity: 128 kbytes */ +#define GTZC_TZSC_MPCWM_GRANULARITY_2 0x00000020U /* BKPSRAM granularity: 32 bytes */ + +/** + * @} + */ + +/** @defgroup GTZC_MPCWM_Lock GTZC MPCWM Lock values + * @{ + */ + +/* user-oriented definitions for TZSC_MPCWM */ +#define GTZC_TZSC_MPCWM_LOCK_OFF (0U) +#define GTZC_TZSC_MPCWM_LOCK_ON GTZC_TZSC_MPCWM_CFGR_SRLOCK_Msk + +/** + * @} + */ + +/** @defgroup GTZC_MPCWM_Attribute GTZC MPCWM Attribute values + * @{ + */ + +/* user-oriented definitions for TZSC_MPCWM */ +#define GTZC_TZSC_MPCWM_REGION_NSEC (0U) +#define GTZC_TZSC_MPCWM_REGION_SEC (1U) +#define GTZC_TZSC_MPCWM_REGION_NPRIV (0U) +#define GTZC_TZSC_MPCWM_REGION_PRIV (2U) + +/** + * @} + */ + +/** @defgroup GTZC_MPCBB_Group GTZC MPCBB values + * @{ + */ + +/* user-oriented definitions for MPCBB */ +#define GTZC_MPCBB_BLOCK_SIZE 0x200U /* 512 Bytes */ +#define GTZC_MPCBB_SUPERBLOCK_SIZE (GTZC_MPCBB_BLOCK_SIZE * 32U) /* 16 KBytes */ +#define GTZC_MPCBB_SUPERBLOCK_UNLOCKED (0U) +#define GTZC_MPCBB_SUPERBLOCK_LOCKED (1U) + +#define GTZC_MPCBB_BLOCK_NSEC (GTZC_ATTR_SEC_MASK | 0U) +#define GTZC_MPCBB_BLOCK_SEC (GTZC_ATTR_SEC_MASK | 1U) +#define GTZC_MPCBB_BLOCK_NPRIV (GTZC_ATTR_PRIV_MASK | 0U) +#define GTZC_MPCBB_BLOCK_PRIV (GTZC_ATTR_PRIV_MASK | 2U) + +/* user-oriented definitions for HAL_GTZC_MPCBB_GetLock() returned value */ +#define GTZC_MPCBB_LOCK_OFF (0U) +#define GTZC_MPCBB_LOCK_ON (1U) + +/** + * @} + */ + +/** @defgroup GTZC_TZIC_Flag GTZC TZIC flag values + * @{ + */ + +/* user-oriented definitions for HAL_GTZC_TZIC_GetFlag() flag parameter */ +#define GTZC_TZIC_NO_ILA_EVENT (0U) +#define GTZC_TZIC_ILA_EVENT_PENDING (1U) + +/** + * @} + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ + +/** @defgroup GTZC_Private_Macros GTZC Private Macros + * @{ + */ + +/* retrieve information to access register for a specific PeriphId */ +#define GTZC_GET_REG_INDEX(periph_id)\ + (((periph_id) & GTZC_PERIPH_REG) >> GTZC_PERIPH_REG_SHIFT) + +#define GTZC_GET_PERIPH_POS(periph_id) ((periph_id) & GTZC_PERIPH_BIT_POSITION) + +#if defined (GTZC_TZIC1) +#define IS_GTZC_BASE_ADDRESS(mem, address)\ + ( ( (uint32_t)(address) == (uint32_t)GTZC_BASE_ADDRESS_NS(mem) ) || \ + ( (uint32_t)(address) == (uint32_t)GTZC_BASE_ADDRESS_S(mem) ) ) +#else +#define IS_GTZC_BASE_ADDRESS(mem, address)\ + ( (uint32_t)(address) == (uint32_t)GTZC_BASE_ADDRESS_NS(mem) ) +#endif /* defined (GTZC_TZIC1) */ + +#define GTZC_MEM_SIZE(mem)\ + ( mem ## _SIZE ) + +#if defined (GTZC_TZIC1) +#define GTZC_BASE_ADDRESS_S(mem)\ + ( mem ## _BASE_S ) +#endif /* defined (GTZC_TZIC1) */ + +#define GTZC_BASE_ADDRESS_NS(mem)\ + ( mem ## _BASE_NS ) + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ + +/** @defgroup GTZC_Exported_Macros GTZC Exported Macros + * @{ + */ + +/* user-oriented macro to get array index of a specific PeriphId + * in case of GTZC_PERIPH_ALL usage in the two following functions: + * HAL_GTZC_TZSC_ConfigPeriphAttributes() and HAL_GTZC_TZSC_GetConfigPeriphAttributes() + */ +#define HAL_GTZC_GET_ARRAY_INDEX(periph_id)\ + ( (GTZC_GET_REG_INDEX((periph_id)) * 32U) + GTZC_GET_PERIPH_POS((periph_id)) ) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup GTZC_Exported_Functions + * @{ + */ + +/** @addtogroup GTZC_Exported_Functions_Group1 + * @brief TZSC Initialization and Configuration functions + * @{ + */ + +HAL_StatusTypeDef HAL_GTZC_TZSC_ConfigPeriphAttributes(uint32_t PeriphId, + uint32_t PeriphAttributes); +HAL_StatusTypeDef HAL_GTZC_TZSC_GetConfigPeriphAttributes(uint32_t PeriphId, + uint32_t *PeriphAttributes); + +/** + * @} + */ + +/** @addtogroup GTZC_Exported_Functions_Group2 + * @brief MPCWM Initialization and Configuration functions + * @{ + */ + +HAL_StatusTypeDef HAL_GTZC_TZSC_MPCWM_ConfigMemAttributes(uint32_t MemBaseAddress, + const MPCWM_ConfigTypeDef *pMPCWM_Desc); +HAL_StatusTypeDef HAL_GTZC_TZSC_MPCWM_GetConfigMemAttributes(uint32_t MemBaseAddress, + MPCWM_ConfigTypeDef *pMPCWM_Desc); +/** + * @} + */ + +#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** @addtogroup GTZC_Exported_Functions_Group3 + * @brief TZSC and TZSC-MPCWM Lock functions + * @{ + */ + +void HAL_GTZC_TZSC_Lock(GTZC_TZSC_TypeDef *TZSC_Instance); +uint32_t HAL_GTZC_TZSC_GetLock(const GTZC_TZSC_TypeDef *TZSC_Instance); + +/** + * @} + */ +#endif /* defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/** @addtogroup GTZC_Exported_Functions_Group4 + * @brief MPCBB Initialization and Configuration functions + * @{ + */ + +HAL_StatusTypeDef HAL_GTZC_MPCBB_ConfigMem(uint32_t MemBaseAddress, + const MPCBB_ConfigTypeDef *pMPCBB_desc); +HAL_StatusTypeDef HAL_GTZC_MPCBB_GetConfigMem(uint32_t MemBaseAddress, + MPCBB_ConfigTypeDef *pMPCBB_desc); +HAL_StatusTypeDef HAL_GTZC_MPCBB_ConfigMemAttributes(uint32_t MemAddress, + uint32_t NbBlocks, + const uint32_t *pMemAttributes); +HAL_StatusTypeDef HAL_GTZC_MPCBB_GetConfigMemAttributes(uint32_t MemAddress, + uint32_t NbBlocks, + uint32_t *pMemAttributes); + +#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +HAL_StatusTypeDef HAL_GTZC_MPCBB_LockConfig(uint32_t MemAddress, + uint32_t NbSuperBlocks, + const uint32_t *pLockAttributes); +HAL_StatusTypeDef HAL_GTZC_MPCBB_GetLockConfig(uint32_t MemAddress, + uint32_t NbSuperBlocks, + uint32_t *pLockAttributes); +HAL_StatusTypeDef HAL_GTZC_MPCBB_Lock(uint32_t MemBaseAddress); +HAL_StatusTypeDef HAL_GTZC_MPCBB_GetLock(uint32_t MemBaseAddress, + uint32_t *pLockState); +#endif /* defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/** + * @} + */ + +#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** @addtogroup GTZC_Exported_Functions_Group5 + * @brief TZIC functions + * @{ + */ + +HAL_StatusTypeDef HAL_GTZC_TZIC_DisableIT(uint32_t PeriphId); +HAL_StatusTypeDef HAL_GTZC_TZIC_EnableIT(uint32_t PeriphId); +HAL_StatusTypeDef HAL_GTZC_TZIC_GetFlag(uint32_t PeriphId, uint32_t *pFlag); +HAL_StatusTypeDef HAL_GTZC_TZIC_ClearFlag(uint32_t PeriphId); + +/** + * @} + */ + +/** @addtogroup GTZC_Exported_Functions_Group6 + * @brief IRQ related Functions + * @{ + */ + +void HAL_GTZC_IRQHandler(void); +void HAL_GTZC_TZIC_Callback(uint32_t PeriphId); + +/** + * @} + */ + +#endif /* defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_GTZC_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_hash.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_hash.h new file mode 100644 index 0000000000..feeb1ed66c --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_hash.h @@ -0,0 +1,596 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_hash.h + * @author MCD Application Team + * @brief Header file of HASH HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_HASH_H +#define STM32H5xx_HAL_HASH_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ +#if defined (HASH) +/** @defgroup HASH HASH + * @brief HASH HAL module driver. + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup HASH_Exported_Types HASH Exported Types + * @{ + */ + +/** + * @brief HASH Configuration Structure definition + */ +typedef struct +{ + uint32_t DataType; /*!< no swap (32-bit data), half word swap (16-bit data), byte swap (8-bit data) or bit swap + (1-bit data). This parameter can be a value of @ref HASH_Data_Type. */ + + uint32_t KeySize; /*!< The key size is used only in HMAC operation. */ + + uint8_t *pKey; /*!< The key is used only in HMAC operation. */ + + uint32_t Algorithm; /*!< HASH algorithm MD5, SHA1 or SHA2. + This parameter can be a value of @ref HASH_Algorithm_Selection */ + + +} HASH_ConfigTypeDef; + +/** + * @brief HAL State structure definition + */ +typedef enum +{ + HAL_HASH_STATE_RESET = 0x00U, /*!< Peripheral is not initialized */ + HAL_HASH_STATE_READY = 0x01U, /*!< Peripheral Initialized and ready for use */ + HAL_HASH_STATE_BUSY = 0x02U, /*!< Processing (hashing) is ongoing */ + HAL_HASH_STATE_SUSPENDED = 0x03U /*!< Suspended state */ +} HAL_HASH_StateTypeDef; + +/** + * @brief HAL phase structure definition + */ +typedef enum +{ + HAL_HASH_PHASE_READY = 0x01U, /*!< HASH peripheral is ready to start */ + HAL_HASH_PHASE_PROCESS = 0x02U, /*!< HASH peripheral is in HASH processing phase */ + HAL_HASH_PHASE_HMAC_STEP_1 = 0x03U, /*!< HASH peripheral is in HMAC step 1 processing phase + (step 1 consists in entering the inner hash function key)*/ + HAL_HASH_PHASE_HMAC_STEP_2 = 0x04U, /*!< HASH peripheral is in HMAC step 2 processing phase + (step 2 consists in entering the message text) */ + HAL_HASH_PHASE_HMAC_STEP_3 = 0x05U /*!< HASH peripheral is in HMAC step 3 processing phase + (step 3 consists in entering the outer hash function key)*/ + +} HAL_HASH_PhaseTypeDef; + +#if (USE_HAL_HASH_SUSPEND_RESUME == 1U) +/** + * @brief HAL HASH mode suspend definitions + */ +typedef enum +{ + HAL_HASH_SUSPEND_NONE = 0x00U, /*!< HASH peripheral suspension not requested */ + HAL_HASH_SUSPEND = 0x01U /*!< HASH peripheral suspension is requested */ +} HAL_HASH_SuspendTypeDef; +#endif /* USE_HAL_HASH_SUSPEND_RESUME */ + + +/** + * @brief HASH Handle Structure definition + */ +#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1) +typedef struct __HASH_HandleTypeDef +#else +typedef struct +#endif /* (USE_HAL_HASH_REGISTER_CALLBACKS) */ +{ + HASH_TypeDef *Instance; /*!< HASH Register base address */ + + HASH_ConfigTypeDef Init; /*!< HASH required parameters */ + + uint8_t const *pHashInBuffPtr; /*!< Pointer to input buffer */ + + uint8_t *pHashOutBuffPtr; /*!< Pointer to output buffer (digest) */ + + __IO uint32_t HashInCount; /*!< Counter of inputted data */ + + uint32_t Size; /*!< Size of buffer to be processed in bytes */ + + uint8_t *pHashKeyBuffPtr; /*!< Pointer to key buffer (HMAC only) */ + + HAL_HASH_PhaseTypeDef Phase; /*!< HASH peripheral phase */ + + DMA_HandleTypeDef *hdmain; /*!< HASH In DMA Handle parameters */ + + HAL_LockTypeDef Lock; /*!< Locking object */ + + __IO uint32_t ErrorCode; /*!< HASH Error code */ + + __IO HAL_HASH_StateTypeDef State; /*!< HASH peripheral state */ + + __IO uint32_t Accumulation; /*!< HASH multi buffers accumulation flag */ + +#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1) + void (* InCpltCallback)(struct __HASH_HandleTypeDef *hhash); /*!< HASH input completion callback */ + + void (* DgstCpltCallback)(struct __HASH_HandleTypeDef *hhash); /*!< HASH digest computation complete callback */ + + void (* ErrorCallback)(struct __HASH_HandleTypeDef *hhash); /*!< HASH error callback */ + + void (* MspInitCallback)(struct __HASH_HandleTypeDef *hhash); /*!< HASH Msp Init callback */ + + void (* MspDeInitCallback)(struct __HASH_HandleTypeDef *hhash); /*!< HASH Msp DeInit callback */ + +#endif /* (USE_HAL_HASH_REGISTER_CALLBACKS) */ +#if (USE_HAL_HASH_SUSPEND_RESUME == 1U) + __IO HAL_HASH_SuspendTypeDef SuspendRequest; /*!< HASH peripheral suspension request flag */ + + HASH_ConfigTypeDef Init_saved; /*!< Saved HASH required parameters */ + + uint8_t const *pHashInBuffPtr_saved; /*!< Saved pointer to input buffer */ + + uint8_t *pHashOutBuffPtr_saved; /*!< Saved pointer to output buffer (digest) */ + + __IO uint32_t HashInCount_saved; /*!< Saved counter of inputted data */ + + uint32_t Size_saved; /*!< Saved size of buffer to be processed */ + + uint8_t *pHashKeyBuffPtr_saved; /*!< Saved pointer to key buffer (HMAC only) */ + + HAL_HASH_PhaseTypeDef Phase_saved; /*!< Saved HASH peripheral phase */ +#endif /* USE_HAL_HASH_SUSPEND_RESUME */ + +} HASH_HandleTypeDef; + +#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1U) +/** + * @brief HAL HASH common Callback ID enumeration definition + */ +typedef enum +{ + HAL_HASH_MSPINIT_CB_ID = 0x00U, /*!< HASH MspInit callback ID */ + HAL_HASH_MSPDEINIT_CB_ID = 0x01U, /*!< HASH MspDeInit callback ID */ + HAL_HASH_INPUTCPLT_CB_ID = 0x02U, /*!< HASH input completion callback ID */ + HAL_HASH_DGSTCPLT_CB_ID = 0x03U, /*!< HASH digest computation completion callback ID */ + HAL_HASH_ERROR_CB_ID = 0x04U, /*!< HASH error callback ID */ +} HAL_HASH_CallbackIDTypeDef; + +/** + * @brief HAL HASH Callback pointer definition + */ +typedef void (*pHASH_CallbackTypeDef)(HASH_HandleTypeDef *hhash); /*!< pointer to a HASH common callback functions */ + +#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */ + + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup HASH_Exported_Constants HASH Exported Constants + * @{ + */ + +/** @defgroup HASH_Error_Definition HASH Error Definition + * @{ + */ +#define HAL_HASH_ERROR_NONE 0x00000000U /*!< No error */ +#define HAL_HASH_ERROR_BUSY 0x00000001U /*!< Busy flag error */ +#define HAL_HASH_ERROR_DMA 0x00000002U /*!< DMA-based process error */ +#define HAL_HASH_ERROR_TIMEOUT 0x00000004U /*!< Timeout error */ +#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1U) +#define HAL_HASH_ERROR_INVALID_CALLBACK 0x00000010U /*!< Invalid Callback error */ +#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @defgroup HASH_Algorithm_Selection HASH algorithm selection + * @{ + */ +#define HASH_ALGOSELECTION_SHA1 0x00000000U /*!< HASH function is SHA1 */ +#define HASH_ALGOSELECTION_SHA224 HASH_CR_ALGO_1 /*!< HASH function is SHA224 */ +#define HASH_ALGOSELECTION_SHA256 (HASH_CR_ALGO_0 | HASH_CR_ALGO_1) /*!< HASH function is SHA256 */ +#if defined (HASH_CR_ALGO_2) +#define HASH_ALGOSELECTION_SHA384 (HASH_CR_ALGO_2 | HASH_CR_ALGO_3) /*!< HASH function is SHA384 */ +#define HASH_ALGOSELECTION_SHA512_224 (HASH_CR_ALGO_0 | HASH_CR_ALGO_2 | HASH_CR_ALGO_3) +/*!< HASH function is SHA512_224 */ +#define HASH_ALGOSELECTION_SHA512_256 (HASH_CR_ALGO_1 | HASH_CR_ALGO_2 | HASH_CR_ALGO_3) +/*!< HASH function is SHA512_256 */ +#define HASH_ALGOSELECTION_SHA512 HASH_CR_ALGO /*!< HASH function is SHA512 */ +#endif /* defined (HASH_CR_ALGO_2) */ +/** + * @} + */ + +/** @defgroup HASH_Mode HASH Mode + * @{ + */ +#define HASH_ALGOMODE_HASH 0x00000000U /*!< HASH mode */ +#define HASH_ALGOMODE_HMAC HASH_CR_MODE /*!< HMAC mode */ +/** + * @} + */ + +/** @defgroup HASH_Data_Type HASH Data Type + * @{ + */ +#define HASH_NO_SWAP 0x00000000U /*!< 32-bit data. No swapping */ +#define HASH_HALFWORD_SWAP HASH_CR_DATATYPE_0 /*!< 16-bit data. Each half word is swapped */ +#define HASH_BYTE_SWAP HASH_CR_DATATYPE_1 /*!< 8-bit data. All bytes are swapped */ +#define HASH_BIT_SWAP HASH_CR_DATATYPE /*!< 1-bit data. In the word all bits are swapped */ +/** + * @} + */ + +/** @defgroup HASH_HMAC_KEY key length only for HMAC mode + * @{ + */ +#define HASH_SHORTKEY 0x00000000U /*!< HMAC Key size is <= block size (64 or 128 bytes) */ +#define HASH_LONGKEY HASH_CR_LKEY /*!< HMAC Key size is > block size (64 or 128 bytes) */ +/** + * @} + */ + +/** @defgroup HASH_flags_definition HASH flags definitions + * @{ + */ +#define HASH_FLAG_DINIS HASH_SR_DINIS /*!< 16 locations are free in the DIN : new block can be entered + in the Peripheral */ +#define HASH_FLAG_DCIS HASH_SR_DCIS /*!< Digest calculation complete */ +#define HASH_FLAG_DMAS HASH_SR_DMAS /*!< DMA interface is enabled (DMAE=1) or a transfer is ongoing */ +#define HASH_FLAG_BUSY HASH_SR_BUSY /*!< The hash core is Busy, processing a block of data */ +#define HASH_FLAG_DINNE HASH_CR_DINNE /*!< DIN not empty : input buffer contains at least one word of data*/ +/** + * @} + */ + +/** @defgroup HASH_interrupts_definition HASH interrupts definitions + * @{ + */ +#define HASH_IT_DINI HASH_IMR_DINIE /*!< A new block can be entered into the input buffer (DIN) */ +#define HASH_IT_DCI HASH_IMR_DCIE /*!< Digest calculation complete */ + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup HASH_Exported_Macros HASH Exported Macros + * @{ + */ + +/** @brief Check whether or not the specified HASH flag is set. + * @param __HANDLE__ specifies the HASH handle. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg @ref HASH_FLAG_DINIS A new block can be entered into the input buffer. + * @arg @ref HASH_FLAG_DCIS Digest calculation complete. + * @arg @ref HASH_FLAG_DMAS DMA interface is enabled (DMAE=1) or a transfer is ongoing. + * @arg @ref HASH_FLAG_BUSY The hash core is Busy : processing a block of data. + * @arg @ref HASH_FLAG_DINNE DIN not empty : the input buffer contains at least one word of data. + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_HASH_GET_FLAG(__HANDLE__, __FLAG__) (((__FLAG__) > 8U) ? \ + (((__HANDLE__)->Instance->CR & (__FLAG__)) == (__FLAG__)) :\ + (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__)) ) + +/** @brief Clear the specified HASH flag. + * @param __HANDLE__ specifies the HASH handle. + * @param __FLAG__ specifies the flag to clear. + * This parameter can be one of the following values: + * @arg @ref HASH_FLAG_DINIS A new block can be entered into the input buffer. + * @arg @ref HASH_FLAG_DCIS Digest calculation complete + * @retval None + */ +#define __HAL_HASH_CLEAR_FLAG(__HANDLE__, __FLAG__) CLEAR_BIT((__HANDLE__)->Instance->SR, (__FLAG__)) + +/** @brief Check whether the specified HASH interrupt source is enabled or not. + * @param __HANDLE__ specifies the HASH handle. + * @param __INTERRUPT__ HASH interrupt source to check + * This parameter can be one of the following values : + * @arg @ref HASH_IT_DINI A new block can be entered into the input buffer (DIN) + * @arg @ref HASH_IT_DCI Digest calculation complete + * @retval State of interruption (TRUE or FALSE). + */ +#define __HAL_HASH_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->IMR\ + & (__INTERRUPT__)) == (__INTERRUPT__)) + +/** @brief Enable the specified HASH interrupt. + * @param __HANDLE__ specifies the HASH handle. + * @param __INTERRUPT__ specifies the HASH interrupt source to enable. + * This parameter can be one of the following values: + * @arg @ref HASH_IT_DINI A new block can be entered into the input buffer (DIN) + * @arg @ref HASH_IT_DCI Digest calculation complete + * @retval None + */ +#define __HAL_HASH_ENABLE_IT(__HANDLE__, __INTERRUPT__) SET_BIT((__HANDLE__)->Instance->IMR, (__INTERRUPT__)) + +/** @brief Disable the specified HASH interrupt. + * @param __HANDLE__ specifies the HASH handle. + * @param __INTERRUPT__ specifies the HASH interrupt source to disable. + * This parameter can be one of the following values: + * @arg @ref HASH_IT_DINI A new block can be entered into the input buffer (DIN) + * @arg @ref HASH_IT_DCI Digest calculation complete + * @retval None + */ +#define __HAL_HASH_DISABLE_IT(__HANDLE__, __INTERRUPT__) CLEAR_BIT((__HANDLE__)->Instance->IMR, (__INTERRUPT__)) + +/** @brief Reset HASH handle state. + * @param __HANDLE__ HASH handle. + * @retval None + */ +#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1) +#define __HAL_HASH_RESET_HANDLE_STATE(__HANDLE__) do{\ + (__HANDLE__)->State = HAL_HASH_STATE_RESET;\ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + }while(0) +#else +#define __HAL_HASH_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_HASH_STATE_RESET) +#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */ + +/** + * @brief Enable the multi-buffer DMA transfer mode. + * @note This bit is set when hashing large files when multiple DMA transfers are needed. + * @retval None + */ +#define __HAL_HASH_SET_MDMAT() SET_BIT(HASH->CR, HASH_CR_MDMAT) + +/** + * @brief Disable the multi-buffer DMA transfer mode. + * @retval None + */ +#define __HAL_HASH_RESET_MDMAT() CLEAR_BIT(HASH->CR, HASH_CR_MDMAT) + +/** + * @brief HAL HASH driver version. + * @retval None + */ +#define HAL_HASH_VERSION 200 /*!< HAL HASH driver version 2.0.0*/ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup HASH_Exported_Functions HASH Exported Functions + * @{ + */ + +/** @addtogroup HASH_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ +HAL_StatusTypeDef HAL_HASH_Init(HASH_HandleTypeDef *hhash); +HAL_StatusTypeDef HAL_HASH_DeInit(HASH_HandleTypeDef *hhash); +void HAL_HASH_MspInit(HASH_HandleTypeDef *hhash); +void HAL_HASH_MspDeInit(HASH_HandleTypeDef *hhash); +HAL_StatusTypeDef HAL_HASH_GetConfig(HASH_HandleTypeDef *hhash, HASH_ConfigTypeDef *pConf); +HAL_StatusTypeDef HAL_HASH_SetConfig(HASH_HandleTypeDef *hhash, HASH_ConfigTypeDef *pConf); + +/* Callbacks Register/UnRegister functions ***********************************/ +#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1) +HAL_StatusTypeDef HAL_HASH_RegisterCallback(HASH_HandleTypeDef *hhash, HAL_HASH_CallbackIDTypeDef CallbackID, + pHASH_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_HASH_UnRegisterCallback(HASH_HandleTypeDef *hhash, HAL_HASH_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */ + +HAL_StatusTypeDef HAL_HASH_ProcessSuspend(HASH_HandleTypeDef *hhash); +void HAL_HASH_Resume(HASH_HandleTypeDef *hhash, uint8_t *pMemBuffer); +void HAL_HASH_Suspend(HASH_HandleTypeDef *hhash, uint8_t *pMemBuffer); +/** + * @} + */ + +/** @addtogroup HASH_Exported_Functions_Group2 HASH processing functions + * @{ + */ + +HAL_StatusTypeDef HAL_HASH_Start(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size, + uint8_t *const pOutBuffer, + uint32_t Timeout); +HAL_StatusTypeDef HAL_HASH_Start_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size, + uint8_t *const pOutBuffer); +HAL_StatusTypeDef HAL_HASH_Start_DMA(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size, + uint8_t *const pOutBuffer); + +HAL_StatusTypeDef HAL_HASH_Accumulate(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size, + uint32_t Timeout); +HAL_StatusTypeDef HAL_HASH_AccumulateLast(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size, + uint8_t *const pOutBuffer, + uint32_t Timeout); +HAL_StatusTypeDef HAL_HASH_AccumulateLast_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size, + uint8_t *const pOutBuffer); +HAL_StatusTypeDef HAL_HASH_Accumulate_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size); + +/** + * @} + */ + +/** @addtogroup HASH_Exported_Functions_Group3 HMAC processing functions + * @{ + */ +HAL_StatusTypeDef HAL_HASH_HMAC_Start(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size, + uint8_t *const pOutBuffer, + uint32_t Timeout); +HAL_StatusTypeDef HAL_HASH_HMAC_Start_DMA(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size, + uint8_t *const pOutBuffer); +HAL_StatusTypeDef HAL_HASH_HMAC_Start_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size, + uint8_t *const pOutBuffer); + +HAL_StatusTypeDef HAL_HASH_HMAC_Accumulate(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size, + uint32_t Timeout); +HAL_StatusTypeDef HAL_HASH_HMAC_AccumulateLast(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size, + uint8_t *const pOutBuffer, uint32_t Timeout); +HAL_StatusTypeDef HAL_HASH_HMAC_Accumulate_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size); +HAL_StatusTypeDef HAL_HASH_HMAC_AccumulateLast_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, + uint32_t Size, uint8_t *const pOutBuffer); + +/** + * @} + */ + +/** @addtogroup HASH_Exported_Functions_Group4 HASH IRQ handler management + * @{ + */ +void HAL_HASH_IRQHandler(HASH_HandleTypeDef *hhash); +void HAL_HASH_InCpltCallback(HASH_HandleTypeDef *hhash); +void HAL_HASH_DgstCpltCallback(HASH_HandleTypeDef *hhash); +void HAL_HASH_ErrorCallback(HASH_HandleTypeDef *hhash); +HAL_HASH_StateTypeDef HAL_HASH_GetState(const HASH_HandleTypeDef *hhash); +uint32_t HAL_HASH_GetError(const HASH_HandleTypeDef *hhash); + +/** + * @} + */ + +/** + * @} + */ + +/* Private macros --------------------------------------------------------*/ +/** @defgroup HASH_Private_Macros HASH Private Macros + * @{ + */ + +/** + * @brief Return digest length in bytes. + * @retval Digest length + */ +#if defined(HASH_ALGOSELECTION_SHA512) +#define HASH_DIGEST_LENGTH(__HANDLE__) (((READ_BIT((__HANDLE__)->Instance->CR, HASH_CR_ALGO) \ + == HASH_ALGOSELECTION_SHA1) ? 20U : \ + ((READ_BIT((__HANDLE__)->Instance->CR, HASH_CR_ALGO) \ + == HASH_ALGOSELECTION_SHA224) ? 28U : \ + ((READ_BIT((__HANDLE__)->Instance->CR, HASH_CR_ALGO) \ + == HASH_ALGOSELECTION_SHA256) ? 32U : \ + ((READ_BIT((__HANDLE__)->Instance->CR, HASH_CR_ALGO) \ + == HASH_ALGOSELECTION_SHA384) ? 48U : \ + ((READ_BIT((__HANDLE__)->Instance->CR, HASH_CR_ALGO) \ + == HASH_ALGOSELECTION_SHA512_224) ? 28U : \ + ((READ_BIT((__HANDLE__)->Instance->CR, HASH_CR_ALGO) \ + == HASH_ALGOSELECTION_SHA512_256) ? 32U : \ + ((READ_BIT((__HANDLE__)->Instance->CR, HASH_CR_ALGO) \ + == HASH_ALGOSELECTION_SHA512) ? 64U : 20U ) ) )))))) +#else +#define HASH_DIGEST_LENGTH(__HANDLE__) (((READ_BIT((__HANDLE__)->Instance->CR, HASH_CR_ALGO) \ + == HASH_ALGOSELECTION_SHA1) ? 20U : \ + ((READ_BIT((__HANDLE__)->Instance->CR, HASH_CR_ALGO) \ + == HASH_ALGOSELECTION_SHA224) ? 28U : \ + ((READ_BIT((__HANDLE__)->Instance->CR, HASH_CR_ALGO) \ + == HASH_ALGOSELECTION_SHA256) ? 32U :20U)))) +#endif /* HASH_ALGOSELECTION_SHA512 */ + +/** + * @brief Ensure that HASH input data type is valid. + * @param __DATATYPE__ HASH input data type. + * @retval SET (__DATATYPE__ is valid) or RESET (__DATATYPE__ is invalid) + */ +#define IS_HASH_DATATYPE(__DATATYPE__) (((__DATATYPE__) == HASH_NO_SWAP)|| \ + ((__DATATYPE__) == HASH_HALFWORD_SWAP)|| \ + ((__DATATYPE__) == HASH_BYTE_SWAP) || \ + ((__DATATYPE__) == HASH_BIT_SWAP)) + +/** + * @brief Ensure that HASH input algorithm is valid. + * @param __ALGORITHM__ HASH algorithm. + * @retval SET (__ALGORITHM__ is valid) or RESET (__ALGORITHM__ is invalid) + */ +#if defined(HASH_ALGOSELECTION_SHA512) +#define IS_HASH_ALGORITHM(__ALGORITHM__) (((__ALGORITHM__) == HASH_ALGOSELECTION_SHA1)|| \ + ((__ALGORITHM__) == HASH_ALGOSELECTION_SHA224)|| \ + ((__ALGORITHM__) == HASH_ALGOSELECTION_SHA256)|| \ + ((__ALGORITHM__) == HASH_ALGOSELECTION_SHA384)|| \ + ((__ALGORITHM__) == HASH_ALGOSELECTION_SHA512_224)|| \ + ((__ALGORITHM__) == HASH_ALGOSELECTION_SHA512_256)|| \ + ((__ALGORITHM__) == HASH_ALGOSELECTION_SHA512)) +#else +#define IS_HASH_ALGORITHM(__ALGORITHM__) (((__ALGORITHM__) == HASH_ALGOSELECTION_SHA1)|| \ + ((__ALGORITHM__) == HASH_ALGOSELECTION_SHA224)|| \ + ((__ALGORITHM__) == HASH_ALGOSELECTION_SHA256)) +#endif /* HASH_ALGOSELECTION_SHA512 */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup HASH_Private_Constants HASH Private Constants + * @{ + */ + +/** + * @} + */ +/* Private defines -----------------------------------------------------------*/ +/** @defgroup HASH_Private_Defines HASH Private Defines + * @{ + */ + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup HASH_Private_Variables HASH Private Variables + * @{ + */ + +/** + * @} + */ +/* Private functions -----------------------------------------------------------*/ + +/** @addtogroup HASH_Private_Functions HASH Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* HASH*/ +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + + +#endif /* STM32H5xx_HAL_HASH_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_hcd.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_hcd.h new file mode 100644 index 0000000000..e2854aa655 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_hcd.h @@ -0,0 +1,598 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_hcd.h + * @author MCD Application Team + * @brief Header file of HCD HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_HCD_H +#define STM32H5xx_HAL_HCD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_usb.h" + +#if defined (USB_DRD_FS) +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup HCD HCD + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup HCD_Exported_Types HCD Exported Types + * @{ + */ + +/** @defgroup HCD_Exported_Types_Group1 HCD State Structure definition + * @{ + */ +typedef enum +{ + HAL_HCD_STATE_RESET = 0x00, + HAL_HCD_STATE_READY = 0x01, + HAL_HCD_STATE_ERROR = 0x02, + HAL_HCD_STATE_BUSY = 0x03, + HAL_HCD_STATE_TIMEOUT = 0x04 +} HCD_StateTypeDef; + +typedef USB_DRD_TypeDef HCD_TypeDef; +typedef USB_DRD_CfgTypeDef HCD_InitTypeDef; +typedef USB_DRD_HCTypeDef HCD_HCTypeDef; +typedef USB_DRD_URBStateTypeDef HCD_URBStateTypeDef; +typedef USB_DRD_HCStateTypeDef HCD_HCStateTypeDef; + +typedef enum +{ + HCD_HCD_STATE_DISCONNECTED = 0x00U, + HCD_HCD_STATE_CONNECTED = 0x01U, + HCD_HCD_STATE_RESETED = 0x02U, + HCD_HCD_STATE_RUN = 0x03U, + HCD_HCD_STATE_SUSPEND = 0x04U, + HCD_HCD_STATE_RESUME = 0x05U, +} HCD_HostStateTypeDef; + +/* PMA lookup Table size depending on PMA Size + * 8Bytes each Block 32Bit in each word + */ +#define PMA_BLOCKS ((USB_DRD_PMA_SIZE) / (8U * 32U)) + +/** + * @} + */ + +/** @defgroup HCD_Exported_Types_Group2 HCD Handle Structure definition + * @{ + */ +#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) +typedef struct __HCD_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ +{ + HCD_TypeDef *Instance; /*!< Register base address */ + HCD_InitTypeDef Init; /*!< HCD required parameters */ + HCD_HCTypeDef hc[16]; /*!< Host channels parameters */ + + uint32_t ep0_PmaAllocState; /*!< EP0 PMA allocation State (allocated, virtual Ch, EP0 direction) */ + uint16_t phy_chin_state[8]; /*!< Physical Channel in State (Used/Free) */ + uint16_t phy_chout_state[8]; /*!< Physical Channel out State (Used/Free)*/ + uint32_t PMALookupTable[PMA_BLOCKS]; /*PMA LookUp Table */ + HCD_HostStateTypeDef HostState; /*!< USB current state DICONNECT/CONNECT/RUN/SUSPEND/RESUME */ + + HAL_LockTypeDef Lock; /*!< HCD peripheral status */ + __IO HCD_StateTypeDef State; /*!< HCD communication state */ + __IO uint32_t ErrorCode; /*!< HCD Error code */ + void *pData; /*!< Pointer Stack Handler */ +#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) + void (* SOFCallback)(struct __HCD_HandleTypeDef *hhcd); /*!< USB OTG HCD SOF callback */ + void (* ConnectCallback)(struct __HCD_HandleTypeDef *hhcd); /*!< USB OTG HCD Connect callback */ + void (* DisconnectCallback)(struct __HCD_HandleTypeDef *hhcd); /*!< USB OTG HCD Disconnect callback */ + void (* PortEnabledCallback)(struct __HCD_HandleTypeDef *hhcd); /*!< USB OTG HCD Port Enable callback */ + void (* PortDisabledCallback)(struct __HCD_HandleTypeDef *hhcd); /*!< USB OTG HCD Port Disable callback */ + void (* HC_NotifyURBChangeCallback)(struct __HCD_HandleTypeDef *hhcd, uint8_t chnum, + HCD_URBStateTypeDef urb_state); /*!< USB OTG HCD Host Channel Notify URB Change callback */ + + void (* MspInitCallback)(struct __HCD_HandleTypeDef *hhcd); /*!< USB OTG HCD Msp Init callback */ + void (* MspDeInitCallback)(struct __HCD_HandleTypeDef *hhcd); /*!< USB OTG HCD Msp DeInit callback */ +#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ +} HCD_HandleTypeDef; +/** + * @} + */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup HCD_Exported_Constants HCD Exported Constants + * @{ + */ + +/** @defgroup HCD_Speed HCD Speed + * @{ + */ +#define HCD_SPEED_FULL USBH_FSLS_SPEED +#define HCD_SPEED_LOW USBH_FSLS_SPEED +/** + * @} + */ + +/** @defgroup HCD_Device_Speed HCD Device Speed + * @{ + */ +#define HCD_DEVICE_SPEED_HIGH 0U +#define HCD_DEVICE_SPEED_FULL 1U +#define HCD_DEVICE_SPEED_LOW 2U +/** + * @} + */ + +/** @defgroup HCD_PHY_Module HCD PHY Module + * @{ + */ +#define HCD_PHY_ULPI 1U +#define HCD_PHY_EMBEDDED 2U +/** + * @} + */ + +/** @defgroup HCD_Error_Code_definition HCD Error Code definition + * @brief HCD Error Code definition + * @{ + */ +#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) +#define HAL_HCD_ERROR_INVALID_CALLBACK (0x00000010U) /*!< Invalid Callback error */ +#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup HCD_Exported_Macros HCD Exported Macros + * @brief macros to handle interrupts and specific clock configurations + * @{ + */ +#define __HAL_HCD_ENABLE(__HANDLE__) (void)USB_EnableGlobalInt ((__HANDLE__)->Instance) +#define __HAL_HCD_DISABLE(__HANDLE__) (void)USB_DisableGlobalInt ((__HANDLE__)->Instance) + +#define __HAL_HCD_GET_FLAG(__HANDLE__, __INTERRUPT__) ((USB_ReadInterrupts((__HANDLE__)->Instance)\ + & (__INTERRUPT__)) == (__INTERRUPT__)) +#define __HAL_HCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->ISTR) &= ~(__INTERRUPT__)) +#define __HAL_HCD_IS_INVALID_INTERRUPT(__HANDLE__) (USB_ReadInterrupts((__HANDLE__)->Instance) == 0U) + +#define __HAL_HCD_GET_CHNUM(__HANDLE__) (((__HANDLE__)->Instance->ISTR) & USB_ISTR_IDN) +#define __HAL_HCD_GET_CHDIR(__HANDLE__) (((__HANDLE__)->Instance->ISTR) & USB_ISTR_DIR) +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HCD_Exported_Functions HCD Exported Functions + * @{ + */ + +/** @defgroup HCD_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ +HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd); +HAL_StatusTypeDef HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd); +HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd, uint8_t ch_num, + uint8_t epnum, uint8_t dev_address, + uint8_t speed, uint8_t ep_type, uint16_t mps); + +HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd, uint8_t ch_num); + +HAL_StatusTypeDef HAL_HCD_HC_Close(HCD_HandleTypeDef *hhcd, uint8_t ch_num); + +void HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd); +void HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd); + +#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) +/** @defgroup HAL_HCD_Callback_ID_enumeration_definition HAL USB OTG HCD Callback ID enumeration definition + * @brief HAL USB OTG HCD Callback ID enumeration definition + * @{ + */ +typedef enum +{ + HAL_HCD_SOF_CB_ID = 0x01, /*!< USB HCD SOF callback ID */ + HAL_HCD_CONNECT_CB_ID = 0x02, /*!< USB HCD Connect callback ID */ + HAL_HCD_DISCONNECT_CB_ID = 0x03, /*!< USB HCD Disconnect callback ID */ + HAL_HCD_PORT_ENABLED_CB_ID = 0x04, /*!< USB HCD Port Enable callback ID */ + HAL_HCD_PORT_DISABLED_CB_ID = 0x05, /*!< USB HCD Port Disable callback ID */ + + HAL_HCD_MSPINIT_CB_ID = 0x06, /*!< USB HCD MspInit callback ID */ + HAL_HCD_MSPDEINIT_CB_ID = 0x07 /*!< USB HCD MspDeInit callback ID */ + +} HAL_HCD_CallbackIDTypeDef; +/** + * @} + */ + +/** @defgroup HAL_HCD_Callback_pointer_definition HAL USB OTG HCD Callback pointer definition + * @brief HAL USB OTG HCD Callback pointer definition + * @{ + */ + +typedef void (*pHCD_CallbackTypeDef)(HCD_HandleTypeDef *hhcd); /*!< pointer to a common USB OTG HCD callback function */ +typedef void (*pHCD_HC_NotifyURBChangeCallbackTypeDef)(HCD_HandleTypeDef *hhcd, + uint8_t epnum, + HCD_URBStateTypeDef urb_state); /*!< pointer to USB OTG HCD host channel callback */ +/** + * @} + */ + +HAL_StatusTypeDef HAL_HCD_RegisterCallback(HCD_HandleTypeDef *hhcd, + HAL_HCD_CallbackIDTypeDef CallbackID, + pHCD_CallbackTypeDef pCallback); + +HAL_StatusTypeDef HAL_HCD_UnRegisterCallback(HCD_HandleTypeDef *hhcd, + HAL_HCD_CallbackIDTypeDef CallbackID); + +HAL_StatusTypeDef HAL_HCD_RegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd, + pHCD_HC_NotifyURBChangeCallbackTypeDef pCallback); + +HAL_StatusTypeDef HAL_HCD_UnRegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd); +#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ +/** + * @} + */ + +/* I/O operation functions ***************************************************/ +/** @addtogroup HCD_Exported_Functions_Group2 Input and Output operation functions + * @{ + */ +HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd, uint8_t ch_num, + uint8_t direction, uint8_t ep_type, + uint8_t token, uint8_t *pbuff, + uint16_t length, uint8_t do_ping); + +HAL_StatusTypeDef HAL_HCD_HC_SetHubInfo(HCD_HandleTypeDef *hhcd, uint8_t ch_num, + uint8_t addr, uint8_t PortNbr); + +HAL_StatusTypeDef HAL_HCD_HC_ClearHubInfo(HCD_HandleTypeDef *hhcd, uint8_t ch_num); + +/* Non-Blocking mode: Interrupt */ +void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd); +void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd); +void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd); +void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd); +void HAL_HCD_PortEnabled_Callback(HCD_HandleTypeDef *hhcd); +void HAL_HCD_PortDisabled_Callback(HCD_HandleTypeDef *hhcd); + +void HAL_HCD_SuspendCallback(HCD_HandleTypeDef *hhcd); +void HAL_HCD_ResumeCallback(HCD_HandleTypeDef *hhcd); + +void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, + HCD_URBStateTypeDef urb_state); +/** + * @} + */ + +/* Peripheral Control functions **********************************************/ +/** @addtogroup HCD_Exported_Functions_Group3 Peripheral Control functions + * @{ + */ +HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd); +HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd); +HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd); + +HAL_StatusTypeDef HAL_HCD_Suspend(HCD_HandleTypeDef *hhcd); +HAL_StatusTypeDef HAL_HCD_Resume(HCD_HandleTypeDef *hhcd); +HAL_StatusTypeDef HAL_HCD_ResumePort(HCD_HandleTypeDef *hhcd); + +/** + * @} + */ + +/* Peripheral State functions ************************************************/ +/** @addtogroup HCD_Exported_Functions_Group4 Peripheral State functions + * @{ + */ +HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef const *hhcd); +HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef const *hhcd, uint8_t chnum); +HCD_HCStateTypeDef HAL_HCD_HC_GetState(HCD_HandleTypeDef const *hhcd, uint8_t chnum); +uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef const *hhcd, uint8_t chnum); +uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd); +uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd); + + +/* PMA Allocation functions **********************************************/ +/** @addtogroup PMA Allocation + * @{ + */ +HAL_StatusTypeDef HAL_HCD_PMAlloc(HCD_HandleTypeDef *hhcd, uint8_t ch_num, + uint16_t ch_kind, uint16_t mps); + +HAL_StatusTypeDef HAL_HCD_PMADeAlloc(HCD_HandleTypeDef *hhcd, uint8_t ch_num); +HAL_StatusTypeDef HAL_HCD_PMAReset(HCD_HandleTypeDef *hhcd); + +/** + * @} + */ + + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup HCD_Private_Macros HCD Private Macros + * @{ + */ + +#define HCD_MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define HCD_MAX(a, b) (((a) > (b)) ? (a) : (b)) + +/** @defgroup HCD_LOGICAL_CHANNEL HCD Logical Channel + * @{ + */ +#define HCD_LOGICAL_CH_NOT_OPENED 0xFFU +#define HCD_FREE_CH_NOT_FOUND 0xFFU +/** + * @} + */ + +/** @defgroup HCD_ENDP_Kind HCD Endpoint Kind + * @{ + */ +#define HCD_SNG_BUF 0U +#define HCD_DBL_BUF 1U +/** + * @} + */ + +/* Set Channel */ +#define HCD_SET_CHANNEL USB_DRD_SET_CHEP + +/* Get Channel Register */ +#define HCD_GET_CHANNEL USB_DRD_GET_CHEP + + +/** + * @brief free buffer used from the application realizing it to the line + * toggles bit SW_BUF in the double buffered endpoint register + * @param USBx USB device. + * @param bChNum, bDir + * @retval None + */ +#define HCD_FREE_USER_BUFFER USB_DRD_FREE_USER_BUFFER + +/** + * @brief Set the Setup bit in the corresponding channel, when a Setup + transaction is needed. + * @param USBx USB device. + * @param bChNum + * @retval None + */ +#define HAC_SET_CH_TX_SETUP USB_DRD_CHEP_TX_SETUP + +/** + * @brief sets the status for tx transfer (bits STAT_TX[1:0]). + * @param USBx USB peripheral instance register address. + * @param bChNum Endpoint Number. + * @param wState new state + * @retval None + */ +#define HCD_SET_CH_TX_STATUS USB_DRD_SET_CHEP_TX_STATUS + +/** + * @brief sets the status for rx transfer (bits STAT_TX[1:0]) + * @param USBx USB peripheral instance register address. + * @param bChNum Endpoint Number. + * @param wState new state + * @retval None + */ +#define HCD_SET_CH_RX_STATUS USB_DRD_SET_CHEP_RX_STATUS +/** + * @brief gets the status for tx/rx transfer (bits STAT_TX[1:0] + * /STAT_RX[1:0]) + * @param USBx USB peripheral instance register address. + * @param bChNum Endpoint Number. + * @retval status + */ +#define HCD_GET_CH_TX_STATUS USB_DRD_GET_CHEP_TX_STATUS +#define HCD_GET_CH_RX_STATUS USB_DRD_GET_CHEP_RX_STATUS +/** + * @brief Sets/clears CH_KIND bit in the Channel register. + * @param USBx USB peripheral instance register address. + * @param bChNum Endpoint Number. + * @retval None + */ +#define HCD_SET_CH_KIND USB_DRD_SET_CH_KIND +#define HCD_CLEAR_CH_KIND USB_DRD_CLEAR_CH_KIND +#define HCD_SET_BULK_CH_DBUF HCD_SET_CH_KIND +#define HCD_CLEAR_BULK_CH_DBUF HCD_CLEAR_CH_KIND + +/** + * @brief Clears bit ERR_RX in the Channel register + * @param USBx USB peripheral instance register address. + * @param bChNum Endpoint Number. + * @retval None + */ +#define HCD_CLEAR_RX_CH_ERR USB_DRD_CLEAR_CHEP_RX_ERR + +/** + * @brief Clears bit ERR_TX in the Channel register + * @param USBx USB peripheral instance register address. + * @param bChNum Endpoint Number. + * @retval None + */ +#define HCD_CLEAR_TX_CH_ERR USB_DRD_CLEAR_CHEP_TX_ERR +/** + * @brief Clears bit CTR_RX / CTR_TX in the endpoint register. + * @param USBx USB peripheral instance register address. + * @param bChNum Endpoint Number. + * @retval None + */ +#define HCD_CLEAR_RX_CH_CTR USB_DRD_CLEAR_RX_CHEP_CTR +#define HCD_CLEAR_TX_CH_CTR USB_DRD_CLEAR_TX_CHEP_CTR + +/** + * @brief Toggles DTOG_RX / DTOG_TX bit in the endpoint register. + * @param USBx USB peripheral instance register address. + * @param bChNum Endpoint Number. + * @retval None + */ +#define HCD_RX_DTOG USB_DRD_RX_DTOG +#define HCD_TX_DTOG USB_DRD_TX_DTOG +/** + * @brief Clears DTOG_RX / DTOG_TX bit in the endpoint register. + * @param USBx USB peripheral instance register address. + * @param bChNum Endpoint Number. + * @retval None + */ +#define HCD_CLEAR_RX_DTOG USB_DRD_CLEAR_RX_DTOG +#define HCD_CLEAR_TX_DTOG USB_DRD_CLEAR_TX_DTOG + +/** + * @brief sets counter for the tx/rx buffer. + * @param USBx USB peripheral instance register address. + * @param bChNum Endpoint Number. + * @param wCount Counter value. + * @retval None + */ +#define HCD_SET_CH_TX_CNT USB_DRD_SET_CHEP_TX_CNT +#define HCD_SET_CH_RX_CNT USB_DRD_SET_CHEP_RX_CNT + +/** + * @brief gets counter of the tx buffer. + * @param USBx USB peripheral instance register address. + * @param bChNum channel Number. + * @retval Counter value + */ +#define HCD_GET_CH_TX_CNT USB_DRD_GET_CHEP_TX_CNT + +/** + * @brief gets counter of the rx buffer. + * @param Instance USB peripheral instance register address. + * @param bChNum channel Number. + * @retval Counter value + */ +__STATIC_INLINE uint16_t HCD_GET_CH_RX_CNT(HCD_TypeDef *Instance, uint16_t bChNum) +{ + uint32_t HostCoreSpeed; + __IO uint32_t count = 10U; + + /* Get Host core Speed */ + HostCoreSpeed = USB_GetHostSpeed(Instance); + + /* Count depends on device LS */ + if (HostCoreSpeed == USB_DRD_SPEED_LS) + { + count = (63U * (HAL_RCC_GetHCLKFreq() / 1000000U)) / 100U; + } + + if (count > 15U) + { + count = HCD_MAX(10U, (count - 15U)); + } + + /* WA: few cycles for RX PMA descriptor to update */ + while (count > 0U) + { + count--; + } + + return (uint16_t)USB_DRD_GET_CHEP_RX_CNT((Instance), (bChNum)); +} + +/** + * @brief Gets buffer 0/1 address of a double buffer endpoint. + * @param USBx USB peripheral instance register address. + * @param bChNum Endpoint Number. + * @param bDir endpoint dir EP_DBUF_OUT = OUT + * EP_DBUF_IN = IN + * @param wCount: Counter value + * @retval None + */ +#define HCD_SET_CH_DBUF0_CNT USB_DRD_SET_CHEP_DBUF0_CNT +#define HCD_SET_CH_DBUF1_CNT USB_DRD_SET_CHEP_DBUF1_CNT +#define HCD_SET_CH_DBUF_CNT USB_DRD_SET_CHEP_DBUF_CNT + + +/** + * @brief gets counter of the rx buffer0. + * @param Instance USB peripheral instance register address. + * @param bChNum channel Number. + * @retval Counter value + */ +__STATIC_INLINE uint16_t HCD_GET_CH_DBUF0_CNT(const HCD_TypeDef *Instance, uint16_t bChNum) +{ + UNUSED(Instance); + __IO uint32_t count = 10U; + + /* WA: few cycles for RX PMA descriptor to update */ + while (count > 0U) + { + count--; + } + + return (uint16_t)USB_DRD_GET_CHEP_DBUF0_CNT((Instance), (bChNum)); +} + +/** + * @brief gets counter of the rx buffer1. + * @param Instance USB peripheral instance register address. + * @param bChNum channel Number. + * @retval Counter value + */ +__STATIC_INLINE uint16_t HCD_GET_CH_DBUF1_CNT(const HCD_TypeDef *Instance, uint16_t bChNum) +{ + UNUSED(Instance); + __IO uint32_t count = 10U; + + /* WA: few cycles for RX PMA descriptor to update */ + while (count > 0U) + { + count--; + } + + return (uint16_t)USB_DRD_GET_CHEP_DBUF1_CNT((Instance), (bChNum)); +} + + +/** + * @} + */ +/* Private functions prototypes ----------------------------------------------*/ + +/** + * @} + */ +/** + * @} + */ +/** + * @} + */ +#endif /* defined (USB_DRD_FS) */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_HCD_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_i2c.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_i2c.h new file mode 100644 index 0000000000..692d125dcc --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_i2c.h @@ -0,0 +1,844 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_i2c.h + * @author MCD Application Team + * @brief Header file of I2C HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_I2C_H +#define STM32H5xx_HAL_I2C_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup I2C + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup I2C_Exported_Types I2C Exported Types + * @{ + */ + +/** @defgroup I2C_Configuration_Structure_definition I2C Configuration Structure definition + * @brief I2C Configuration Structure definition + * @{ + */ +typedef struct +{ + uint32_t Timing; /*!< Specifies the I2C_TIMINGR_register value. + This parameter calculated by referring to I2C initialization section + in Reference manual */ + + uint32_t OwnAddress1; /*!< Specifies the first device own address. + This parameter can be a 7-bit or 10-bit address. */ + + uint32_t AddressingMode; /*!< Specifies if 7-bit or 10-bit addressing mode is selected. + This parameter can be a value of @ref I2C_ADDRESSING_MODE */ + + uint32_t DualAddressMode; /*!< Specifies if dual addressing mode is selected. + This parameter can be a value of @ref I2C_DUAL_ADDRESSING_MODE */ + + uint32_t OwnAddress2; /*!< Specifies the second device own address if dual addressing mode is selected + This parameter can be a 7-bit address. */ + + uint32_t OwnAddress2Masks; /*!< Specifies the acknowledge mask address second device own address if dual addressing + mode is selected. + This parameter can be a value of @ref I2C_OWN_ADDRESS2_MASKS */ + + uint32_t GeneralCallMode; /*!< Specifies if general call mode is selected. + This parameter can be a value of @ref I2C_GENERAL_CALL_ADDRESSING_MODE */ + + uint32_t NoStretchMode; /*!< Specifies if nostretch mode is selected. + This parameter can be a value of @ref I2C_NOSTRETCH_MODE */ + +} I2C_InitTypeDef; + +/** + * @} + */ + +/** @defgroup HAL_state_structure_definition HAL state structure definition + * @brief HAL State structure definition + * @note HAL I2C State value coding follow below described bitmap :\n + * b7-b6 Error information\n + * 00 : No Error\n + * 01 : Abort (Abort user request on going)\n + * 10 : Timeout\n + * 11 : Error\n + * b5 Peripheral initialization status\n + * 0 : Reset (peripheral not initialized)\n + * 1 : Init done (peripheral initialized and ready to use. HAL I2C Init function called)\n + * b4 (not used)\n + * x : Should be set to 0\n + * b3\n + * 0 : Ready or Busy (No Listen mode ongoing)\n + * 1 : Listen (peripheral in Address Listen Mode)\n + * b2 Intrinsic process state\n + * 0 : Ready\n + * 1 : Busy (peripheral busy with some configuration or internal operations)\n + * b1 Rx state\n + * 0 : Ready (no Rx operation ongoing)\n + * 1 : Busy (Rx operation ongoing)\n + * b0 Tx state\n + * 0 : Ready (no Tx operation ongoing)\n + * 1 : Busy (Tx operation ongoing) + * @{ + */ +typedef enum +{ + HAL_I2C_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized */ + HAL_I2C_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use */ + HAL_I2C_STATE_BUSY = 0x24U, /*!< An internal process is ongoing */ + HAL_I2C_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing */ + HAL_I2C_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing */ + HAL_I2C_STATE_LISTEN = 0x28U, /*!< Address Listen Mode is ongoing */ + HAL_I2C_STATE_BUSY_TX_LISTEN = 0x29U, /*!< Address Listen Mode and Data Transmission + process is ongoing */ + HAL_I2C_STATE_BUSY_RX_LISTEN = 0x2AU, /*!< Address Listen Mode and Data Reception + process is ongoing */ + HAL_I2C_STATE_ABORT = 0x60U, /*!< Abort user request ongoing */ + HAL_I2C_STATE_TIMEOUT = 0xA0U, /*!< Timeout state */ + HAL_I2C_STATE_ERROR = 0xE0U /*!< Error */ + +} HAL_I2C_StateTypeDef; + +/** + * @} + */ + +/** @defgroup HAL_mode_structure_definition HAL mode structure definition + * @brief HAL Mode structure definition + * @note HAL I2C Mode value coding follow below described bitmap :\n + * b7 (not used)\n + * x : Should be set to 0\n + * b6\n + * 0 : None\n + * 1 : Memory (HAL I2C communication is in Memory Mode)\n + * b5\n + * 0 : None\n + * 1 : Slave (HAL I2C communication is in Slave Mode)\n + * b4\n + * 0 : None\n + * 1 : Master (HAL I2C communication is in Master Mode)\n + * b3-b2-b1-b0 (not used)\n + * xxxx : Should be set to 0000 + * @{ + */ +typedef enum +{ + HAL_I2C_MODE_NONE = 0x00U, /*!< No I2C communication on going */ + HAL_I2C_MODE_MASTER = 0x10U, /*!< I2C communication is in Master Mode */ + HAL_I2C_MODE_SLAVE = 0x20U, /*!< I2C communication is in Slave Mode */ + HAL_I2C_MODE_MEM = 0x40U /*!< I2C communication is in Memory Mode */ + +} HAL_I2C_ModeTypeDef; + +/** + * @} + */ + +/** @defgroup I2C_Error_Code_definition I2C Error Code definition + * @brief I2C Error Code definition + * @{ + */ +#define HAL_I2C_ERROR_NONE (0x00000000U) /*!< No error */ +#define HAL_I2C_ERROR_BERR (0x00000001U) /*!< BERR error */ +#define HAL_I2C_ERROR_ARLO (0x00000002U) /*!< ARLO error */ +#define HAL_I2C_ERROR_AF (0x00000004U) /*!< ACKF error */ +#define HAL_I2C_ERROR_OVR (0x00000008U) /*!< OVR error */ +#define HAL_I2C_ERROR_DMA (0x00000010U) /*!< DMA transfer error */ +#define HAL_I2C_ERROR_TIMEOUT (0x00000020U) /*!< Timeout error */ +#define HAL_I2C_ERROR_SIZE (0x00000040U) /*!< Size Management error */ +#define HAL_I2C_ERROR_DMA_PARAM (0x00000080U) /*!< DMA Parameter Error */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) +#define HAL_I2C_ERROR_INVALID_CALLBACK (0x00000100U) /*!< Invalid Callback error */ +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ +#define HAL_I2C_ERROR_INVALID_PARAM (0x00000200U) /*!< Invalid Parameters error */ +/** + * @} + */ + +/** @defgroup I2C_handle_Structure_definition I2C handle Structure definition + * @brief I2C handle Structure definition + * @{ + */ +typedef struct __I2C_HandleTypeDef +{ + I2C_TypeDef *Instance; /*!< I2C registers base address */ + + I2C_InitTypeDef Init; /*!< I2C communication parameters */ + + uint8_t *pBuffPtr; /*!< Pointer to I2C transfer buffer */ + + uint16_t XferSize; /*!< I2C transfer size */ + + __IO uint16_t XferCount; /*!< I2C transfer counter */ + + __IO uint32_t XferOptions; /*!< I2C sequantial transfer options, this parameter can + be a value of @ref I2C_XFEROPTIONS */ + + __IO uint32_t PreviousState; /*!< I2C communication Previous state */ + + HAL_StatusTypeDef(*XferISR)(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources); + /*!< I2C transfer IRQ handler function pointer */ + +#if defined(HAL_DMA_MODULE_ENABLED) + DMA_HandleTypeDef *hdmatx; /*!< I2C Tx DMA handle parameters */ + + DMA_HandleTypeDef *hdmarx; /*!< I2C Rx DMA handle parameters */ + +#endif /*HAL_DMA_MODULE_ENABLED*/ + + HAL_LockTypeDef Lock; /*!< I2C locking object */ + + __IO HAL_I2C_StateTypeDef State; /*!< I2C communication state */ + + __IO HAL_I2C_ModeTypeDef Mode; /*!< I2C communication mode */ + + __IO uint32_t ErrorCode; /*!< I2C Error code */ + + __IO uint32_t AddrEventCount; /*!< I2C Address Event counter */ + + __IO uint32_t Devaddress; /*!< I2C Target device address */ + + __IO uint32_t Memaddress; /*!< I2C Target memory address */ + +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + void (* MasterTxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); + /*!< I2C Master Tx Transfer completed callback */ + void (* MasterRxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); + /*!< I2C Master Rx Transfer completed callback */ + void (* SlaveTxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); + /*!< I2C Slave Tx Transfer completed callback */ + void (* SlaveRxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); + /*!< I2C Slave Rx Transfer completed callback */ + void (* ListenCpltCallback)(struct __I2C_HandleTypeDef *hi2c); + /*!< I2C Listen Complete callback */ + void (* MemTxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); + /*!< I2C Memory Tx Transfer completed callback */ + void (* MemRxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); + /*!< I2C Memory Rx Transfer completed callback */ + void (* ErrorCallback)(struct __I2C_HandleTypeDef *hi2c); + /*!< I2C Error callback */ + void (* AbortCpltCallback)(struct __I2C_HandleTypeDef *hi2c); + /*!< I2C Abort callback */ + + void (* AddrCallback)(struct __I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode); + /*!< I2C Slave Address Match callback */ + + void (* MspInitCallback)(struct __I2C_HandleTypeDef *hi2c); + /*!< I2C Msp Init callback */ + void (* MspDeInitCallback)(struct __I2C_HandleTypeDef *hi2c); + /*!< I2C Msp DeInit callback */ + +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ +} I2C_HandleTypeDef; + +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) +/** + * @brief HAL I2C Callback ID enumeration definition + */ +typedef enum +{ + HAL_I2C_MASTER_TX_COMPLETE_CB_ID = 0x00U, /*!< I2C Master Tx Transfer completed callback ID */ + HAL_I2C_MASTER_RX_COMPLETE_CB_ID = 0x01U, /*!< I2C Master Rx Transfer completed callback ID */ + HAL_I2C_SLAVE_TX_COMPLETE_CB_ID = 0x02U, /*!< I2C Slave Tx Transfer completed callback ID */ + HAL_I2C_SLAVE_RX_COMPLETE_CB_ID = 0x03U, /*!< I2C Slave Rx Transfer completed callback ID */ + HAL_I2C_LISTEN_COMPLETE_CB_ID = 0x04U, /*!< I2C Listen Complete callback ID */ + HAL_I2C_MEM_TX_COMPLETE_CB_ID = 0x05U, /*!< I2C Memory Tx Transfer callback ID */ + HAL_I2C_MEM_RX_COMPLETE_CB_ID = 0x06U, /*!< I2C Memory Rx Transfer completed callback ID */ + HAL_I2C_ERROR_CB_ID = 0x07U, /*!< I2C Error callback ID */ + HAL_I2C_ABORT_CB_ID = 0x08U, /*!< I2C Abort callback ID */ + + HAL_I2C_MSPINIT_CB_ID = 0x09U, /*!< I2C Msp Init callback ID */ + HAL_I2C_MSPDEINIT_CB_ID = 0x0AU /*!< I2C Msp DeInit callback ID */ + +} HAL_I2C_CallbackIDTypeDef; + +/** + * @brief HAL I2C Callback pointer definition + */ +typedef void (*pI2C_CallbackTypeDef)(I2C_HandleTypeDef *hi2c); +/*!< pointer to an I2C callback function */ +typedef void (*pI2C_AddrCallbackTypeDef)(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, + uint16_t AddrMatchCode); +/*!< pointer to an I2C Address Match callback function */ + +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** + * @} + */ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup I2C_Exported_Constants I2C Exported Constants + * @{ + */ + +/** @defgroup I2C_XFEROPTIONS I2C Sequential Transfer Options + * @{ + */ +#define I2C_FIRST_FRAME ((uint32_t)I2C_SOFTEND_MODE) +#define I2C_FIRST_AND_NEXT_FRAME ((uint32_t)(I2C_RELOAD_MODE | I2C_SOFTEND_MODE)) +#define I2C_NEXT_FRAME ((uint32_t)(I2C_RELOAD_MODE | I2C_SOFTEND_MODE)) +#define I2C_FIRST_AND_LAST_FRAME ((uint32_t)I2C_AUTOEND_MODE) +#define I2C_LAST_FRAME ((uint32_t)I2C_AUTOEND_MODE) +#define I2C_LAST_FRAME_NO_STOP ((uint32_t)I2C_SOFTEND_MODE) + +/* List of XferOptions in usage of : + * 1- Restart condition in all use cases (direction change or not) + */ +#define I2C_OTHER_FRAME (0x000000AAU) +#define I2C_OTHER_AND_LAST_FRAME (0x0000AA00U) +/** + * @} + */ + +/** @defgroup I2C_ADDRESSING_MODE I2C Addressing Mode + * @{ + */ +#define I2C_ADDRESSINGMODE_7BIT (0x00000001U) +#define I2C_ADDRESSINGMODE_10BIT (0x00000002U) +/** + * @} + */ + +/** @defgroup I2C_DUAL_ADDRESSING_MODE I2C Dual Addressing Mode + * @{ + */ +#define I2C_DUALADDRESS_DISABLE (0x00000000U) +#define I2C_DUALADDRESS_ENABLE I2C_OAR2_OA2EN +/** + * @} + */ + +/** @defgroup I2C_OWN_ADDRESS2_MASKS I2C Own Address2 Masks + * @{ + */ +#define I2C_OA2_NOMASK ((uint8_t)0x00U) +#define I2C_OA2_MASK01 ((uint8_t)0x01U) +#define I2C_OA2_MASK02 ((uint8_t)0x02U) +#define I2C_OA2_MASK03 ((uint8_t)0x03U) +#define I2C_OA2_MASK04 ((uint8_t)0x04U) +#define I2C_OA2_MASK05 ((uint8_t)0x05U) +#define I2C_OA2_MASK06 ((uint8_t)0x06U) +#define I2C_OA2_MASK07 ((uint8_t)0x07U) +/** + * @} + */ + +/** @defgroup I2C_GENERAL_CALL_ADDRESSING_MODE I2C General Call Addressing Mode + * @{ + */ +#define I2C_GENERALCALL_DISABLE (0x00000000U) +#define I2C_GENERALCALL_ENABLE I2C_CR1_GCEN +/** + * @} + */ + +/** @defgroup I2C_NOSTRETCH_MODE I2C No-Stretch Mode + * @{ + */ +#define I2C_NOSTRETCH_DISABLE (0x00000000U) +#define I2C_NOSTRETCH_ENABLE I2C_CR1_NOSTRETCH +/** + * @} + */ + +/** @defgroup I2C_MEMORY_ADDRESS_SIZE I2C Memory Address Size + * @{ + */ +#define I2C_MEMADD_SIZE_8BIT (0x00000001U) +#define I2C_MEMADD_SIZE_16BIT (0x00000002U) +/** + * @} + */ + +/** @defgroup I2C_XFERDIRECTION I2C Transfer Direction Master Point of View + * @{ + */ +#define I2C_DIRECTION_TRANSMIT (0x00000000U) +#define I2C_DIRECTION_RECEIVE (0x00000001U) +/** + * @} + */ + +/** @defgroup I2C_RELOAD_END_MODE I2C Reload End Mode + * @{ + */ +#define I2C_RELOAD_MODE I2C_CR2_RELOAD +#define I2C_AUTOEND_MODE I2C_CR2_AUTOEND +#define I2C_SOFTEND_MODE (0x00000000U) +/** + * @} + */ + +/** @defgroup I2C_START_STOP_MODE I2C Start or Stop Mode + * @{ + */ +#define I2C_NO_STARTSTOP (0x00000000U) +#define I2C_GENERATE_STOP (uint32_t)(0x80000000U | I2C_CR2_STOP) +#define I2C_GENERATE_START_READ (uint32_t)(0x80000000U | I2C_CR2_START | I2C_CR2_RD_WRN) +#define I2C_GENERATE_START_WRITE (uint32_t)(0x80000000U | I2C_CR2_START) +/** + * @} + */ + +/** @defgroup I2C_Interrupt_configuration_definition I2C Interrupt configuration definition + * @brief I2C Interrupt definition + * Elements values convention: 0xXXXXXXXX + * - XXXXXXXX : Interrupt control mask + * @{ + */ +#define I2C_IT_ERRI I2C_CR1_ERRIE +#define I2C_IT_TCI I2C_CR1_TCIE +#define I2C_IT_STOPI I2C_CR1_STOPIE +#define I2C_IT_NACKI I2C_CR1_NACKIE +#define I2C_IT_ADDRI I2C_CR1_ADDRIE +#define I2C_IT_RXI I2C_CR1_RXIE +#define I2C_IT_TXI I2C_CR1_TXIE +/** + * @} + */ + +/** @defgroup I2C_Flag_definition I2C Flag definition + * @{ + */ +#define I2C_FLAG_TXE I2C_ISR_TXE +#define I2C_FLAG_TXIS I2C_ISR_TXIS +#define I2C_FLAG_RXNE I2C_ISR_RXNE +#define I2C_FLAG_ADDR I2C_ISR_ADDR +#define I2C_FLAG_AF I2C_ISR_NACKF +#define I2C_FLAG_STOPF I2C_ISR_STOPF +#define I2C_FLAG_TC I2C_ISR_TC +#define I2C_FLAG_TCR I2C_ISR_TCR +#define I2C_FLAG_BERR I2C_ISR_BERR +#define I2C_FLAG_ARLO I2C_ISR_ARLO +#define I2C_FLAG_OVR I2C_ISR_OVR +#define I2C_FLAG_PECERR I2C_ISR_PECERR +#define I2C_FLAG_TIMEOUT I2C_ISR_TIMEOUT +#define I2C_FLAG_ALERT I2C_ISR_ALERT +#define I2C_FLAG_BUSY I2C_ISR_BUSY +#define I2C_FLAG_DIR I2C_ISR_DIR +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ + +/** @defgroup I2C_Exported_Macros I2C Exported Macros + * @{ + */ + +/** @brief Reset I2C handle state. + * @param __HANDLE__ specifies the I2C Handle. + * @retval None + */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) +#define __HAL_I2C_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->State = HAL_I2C_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_I2C_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_I2C_STATE_RESET) +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + +/** @brief Enable the specified I2C interrupt. + * @param __HANDLE__ specifies the I2C Handle. + * @param __INTERRUPT__ specifies the interrupt source to enable. + * This parameter can be one of the following values: + * @arg @ref I2C_IT_ERRI Errors interrupt enable + * @arg @ref I2C_IT_TCI Transfer complete interrupt enable + * @arg @ref I2C_IT_STOPI STOP detection interrupt enable + * @arg @ref I2C_IT_NACKI NACK received interrupt enable + * @arg @ref I2C_IT_ADDRI Address match interrupt enable + * @arg @ref I2C_IT_RXI RX interrupt enable + * @arg @ref I2C_IT_TXI TX interrupt enable + * + * @retval None + */ +#define __HAL_I2C_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR1 |= (__INTERRUPT__)) + +/** @brief Disable the specified I2C interrupt. + * @param __HANDLE__ specifies the I2C Handle. + * @param __INTERRUPT__ specifies the interrupt source to disable. + * This parameter can be one of the following values: + * @arg @ref I2C_IT_ERRI Errors interrupt enable + * @arg @ref I2C_IT_TCI Transfer complete interrupt enable + * @arg @ref I2C_IT_STOPI STOP detection interrupt enable + * @arg @ref I2C_IT_NACKI NACK received interrupt enable + * @arg @ref I2C_IT_ADDRI Address match interrupt enable + * @arg @ref I2C_IT_RXI RX interrupt enable + * @arg @ref I2C_IT_TXI TX interrupt enable + * + * @retval None + */ +#define __HAL_I2C_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR1 &= (~(__INTERRUPT__))) + +/** @brief Check whether the specified I2C interrupt source is enabled or not. + * @param __HANDLE__ specifies the I2C Handle. + * @param __INTERRUPT__ specifies the I2C interrupt source to check. + * This parameter can be one of the following values: + * @arg @ref I2C_IT_ERRI Errors interrupt enable + * @arg @ref I2C_IT_TCI Transfer complete interrupt enable + * @arg @ref I2C_IT_STOPI STOP detection interrupt enable + * @arg @ref I2C_IT_NACKI NACK received interrupt enable + * @arg @ref I2C_IT_ADDRI Address match interrupt enable + * @arg @ref I2C_IT_RXI RX interrupt enable + * @arg @ref I2C_IT_TXI TX interrupt enable + * + * @retval The new state of __INTERRUPT__ (SET or RESET). + */ +#define __HAL_I2C_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CR1 & \ + (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) + +/** @brief Check whether the specified I2C flag is set or not. + * @param __HANDLE__ specifies the I2C Handle. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg @ref I2C_FLAG_TXE Transmit data register empty + * @arg @ref I2C_FLAG_TXIS Transmit interrupt status + * @arg @ref I2C_FLAG_RXNE Receive data register not empty + * @arg @ref I2C_FLAG_ADDR Address matched (slave mode) + * @arg @ref I2C_FLAG_AF Acknowledge failure received flag + * @arg @ref I2C_FLAG_STOPF STOP detection flag + * @arg @ref I2C_FLAG_TC Transfer complete (master mode) + * @arg @ref I2C_FLAG_TCR Transfer complete reload + * @arg @ref I2C_FLAG_BERR Bus error + * @arg @ref I2C_FLAG_ARLO Arbitration lost + * @arg @ref I2C_FLAG_OVR Overrun/Underrun + * @arg @ref I2C_FLAG_PECERR PEC error in reception + * @arg @ref I2C_FLAG_TIMEOUT Timeout or Tlow detection flag + * @arg @ref I2C_FLAG_ALERT SMBus alert + * @arg @ref I2C_FLAG_BUSY Bus busy + * @arg @ref I2C_FLAG_DIR Transfer direction (slave mode) + * + * @retval The new state of __FLAG__ (SET or RESET). + */ +#define I2C_FLAG_MASK (0x0001FFFFU) +#define __HAL_I2C_GET_FLAG(__HANDLE__, __FLAG__) (((((__HANDLE__)->Instance->ISR) & \ + (__FLAG__)) == (__FLAG__)) ? SET : RESET) + +/** @brief Clear the I2C pending flags which are cleared by writing 1 in a specific bit. + * @param __HANDLE__ specifies the I2C Handle. + * @param __FLAG__ specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg @ref I2C_FLAG_TXE Transmit data register empty + * @arg @ref I2C_FLAG_ADDR Address matched (slave mode) + * @arg @ref I2C_FLAG_AF Acknowledge failure received flag + * @arg @ref I2C_FLAG_STOPF STOP detection flag + * @arg @ref I2C_FLAG_BERR Bus error + * @arg @ref I2C_FLAG_ARLO Arbitration lost + * @arg @ref I2C_FLAG_OVR Overrun/Underrun + * @arg @ref I2C_FLAG_PECERR PEC error in reception + * @arg @ref I2C_FLAG_TIMEOUT Timeout or Tlow detection flag + * @arg @ref I2C_FLAG_ALERT SMBus alert + * + * @retval None + */ +#define __HAL_I2C_CLEAR_FLAG(__HANDLE__, __FLAG__) (((__FLAG__) == I2C_FLAG_TXE) ? \ + ((__HANDLE__)->Instance->ISR |= (__FLAG__)) : \ + ((__HANDLE__)->Instance->ICR = (__FLAG__))) + +/** @brief Enable the specified I2C peripheral. + * @param __HANDLE__ specifies the I2C Handle. + * @retval None + */ +#define __HAL_I2C_ENABLE(__HANDLE__) (SET_BIT((__HANDLE__)->Instance->CR1, I2C_CR1_PE)) + +/** @brief Disable the specified I2C peripheral. + * @param __HANDLE__ specifies the I2C Handle. + * @retval None + */ +#define __HAL_I2C_DISABLE(__HANDLE__) (CLEAR_BIT((__HANDLE__)->Instance->CR1, I2C_CR1_PE)) + +/** @brief Generate a Non-Acknowledge I2C peripheral in Slave mode. + * @param __HANDLE__ specifies the I2C Handle. + * @retval None + */ +#define __HAL_I2C_GENERATE_NACK(__HANDLE__) (SET_BIT((__HANDLE__)->Instance->CR2, I2C_CR2_NACK)) +/** + * @} + */ + +/* Include I2C HAL Extended module */ +#include "stm32h5xx_hal_i2c_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup I2C_Exported_Functions + * @{ + */ + +/** @addtogroup I2C_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ +/* Initialization and de-initialization functions******************************/ +HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c); +HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c); +void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c); +void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c); + +/* Callbacks Register/UnRegister functions ***********************************/ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) +HAL_StatusTypeDef HAL_I2C_RegisterCallback(I2C_HandleTypeDef *hi2c, HAL_I2C_CallbackIDTypeDef CallbackID, + pI2C_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_I2C_UnRegisterCallback(I2C_HandleTypeDef *hi2c, HAL_I2C_CallbackIDTypeDef CallbackID); + +HAL_StatusTypeDef HAL_I2C_RegisterAddrCallback(I2C_HandleTypeDef *hi2c, pI2C_AddrCallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_I2C_UnRegisterAddrCallback(I2C_HandleTypeDef *hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @addtogroup I2C_Exported_Functions_Group2 Input and Output operation functions + * @{ + */ +/* IO operation functions ****************************************************/ +/******* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, + uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, + uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, + uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, + uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, + uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, + uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, + uint32_t Timeout); + +/******* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, + uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, + uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, + uint16_t MemAddSize, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, + uint16_t MemAddSize, uint8_t *pData, uint16_t Size); + +HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, + uint16_t Size, uint32_t XferOptions); +HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, + uint16_t Size, uint32_t XferOptions); +HAL_StatusTypeDef HAL_I2C_Slave_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, + uint32_t XferOptions); +HAL_StatusTypeDef HAL_I2C_Slave_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, + uint32_t XferOptions); +HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c); +HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c); +HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress); + +#if defined(HAL_DMA_MODULE_ENABLED) +/******* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, + uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, + uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, + uint16_t MemAddSize, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, + uint16_t MemAddSize, uint8_t *pData, uint16_t Size); + +HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, + uint16_t Size, uint32_t XferOptions); +HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, + uint16_t Size, uint32_t XferOptions); +HAL_StatusTypeDef HAL_I2C_Slave_Seq_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, + uint32_t XferOptions); +HAL_StatusTypeDef HAL_I2C_Slave_Seq_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, + uint32_t XferOptions); +#endif /*HAL_DMA_MODULE_ENABLED*/ +/** + * @} + */ + +/** @addtogroup I2C_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @{ + */ +/******* I2C IRQHandler and Callbacks used in non blocking modes (Interrupt and DMA) */ +void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c); +void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c); +void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode); +void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c); +/** + * @} + */ + +/** @addtogroup I2C_Exported_Functions_Group3 Peripheral State, Mode and Error functions + * @{ + */ +/* Peripheral State, Mode and Error functions *********************************/ +HAL_I2C_StateTypeDef HAL_I2C_GetState(const I2C_HandleTypeDef *hi2c); +HAL_I2C_ModeTypeDef HAL_I2C_GetMode(const I2C_HandleTypeDef *hi2c); +uint32_t HAL_I2C_GetError(const I2C_HandleTypeDef *hi2c); + +/** + * @} + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup I2C_Private_Constants I2C Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup I2C_Private_Macro I2C Private Macros + * @{ + */ + +#define IS_I2C_ADDRESSING_MODE(MODE) (((MODE) == I2C_ADDRESSINGMODE_7BIT) || \ + ((MODE) == I2C_ADDRESSINGMODE_10BIT)) + +#define IS_I2C_DUAL_ADDRESS(ADDRESS) (((ADDRESS) == I2C_DUALADDRESS_DISABLE) || \ + ((ADDRESS) == I2C_DUALADDRESS_ENABLE)) + +#define IS_I2C_OWN_ADDRESS2_MASK(MASK) (((MASK) == I2C_OA2_NOMASK) || \ + ((MASK) == I2C_OA2_MASK01) || \ + ((MASK) == I2C_OA2_MASK02) || \ + ((MASK) == I2C_OA2_MASK03) || \ + ((MASK) == I2C_OA2_MASK04) || \ + ((MASK) == I2C_OA2_MASK05) || \ + ((MASK) == I2C_OA2_MASK06) || \ + ((MASK) == I2C_OA2_MASK07)) + +#define IS_I2C_GENERAL_CALL(CALL) (((CALL) == I2C_GENERALCALL_DISABLE) || \ + ((CALL) == I2C_GENERALCALL_ENABLE)) + +#define IS_I2C_NO_STRETCH(STRETCH) (((STRETCH) == I2C_NOSTRETCH_DISABLE) || \ + ((STRETCH) == I2C_NOSTRETCH_ENABLE)) + +#define IS_I2C_MEMADD_SIZE(SIZE) (((SIZE) == I2C_MEMADD_SIZE_8BIT) || \ + ((SIZE) == I2C_MEMADD_SIZE_16BIT)) + +#define IS_TRANSFER_MODE(MODE) (((MODE) == I2C_RELOAD_MODE) || \ + ((MODE) == I2C_AUTOEND_MODE) || \ + ((MODE) == I2C_SOFTEND_MODE)) + +#define IS_TRANSFER_REQUEST(REQUEST) (((REQUEST) == I2C_GENERATE_STOP) || \ + ((REQUEST) == I2C_GENERATE_START_READ) || \ + ((REQUEST) == I2C_GENERATE_START_WRITE) || \ + ((REQUEST) == I2C_NO_STARTSTOP)) + +#define IS_I2C_TRANSFER_OPTIONS_REQUEST(REQUEST) (((REQUEST) == I2C_FIRST_FRAME) || \ + ((REQUEST) == I2C_FIRST_AND_NEXT_FRAME) || \ + ((REQUEST) == I2C_NEXT_FRAME) || \ + ((REQUEST) == I2C_FIRST_AND_LAST_FRAME) || \ + ((REQUEST) == I2C_LAST_FRAME) || \ + ((REQUEST) == I2C_LAST_FRAME_NO_STOP) || \ + IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(REQUEST)) + +#define IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(REQUEST) (((REQUEST) == I2C_OTHER_FRAME) || \ + ((REQUEST) == I2C_OTHER_AND_LAST_FRAME)) + +#define I2C_RESET_CR2(__HANDLE__) ((__HANDLE__)->Instance->CR2 &= \ + (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_HEAD10R | \ + I2C_CR2_NBYTES | I2C_CR2_RELOAD | \ + I2C_CR2_RD_WRN))) + +#define I2C_GET_ADDR_MATCH(__HANDLE__) ((uint16_t)(((__HANDLE__)->Instance->ISR & I2C_ISR_ADDCODE) \ + >> 16U)) +#define I2C_GET_DIR(__HANDLE__) ((uint8_t)(((__HANDLE__)->Instance->ISR & I2C_ISR_DIR) \ + >> 16U)) +#define I2C_GET_STOP_MODE(__HANDLE__) ((__HANDLE__)->Instance->CR2 & I2C_CR2_AUTOEND) +#define I2C_GET_OWN_ADDRESS1(__HANDLE__) ((uint16_t)((__HANDLE__)->Instance->OAR1 & I2C_OAR1_OA1)) +#define I2C_GET_OWN_ADDRESS2(__HANDLE__) ((uint16_t)((__HANDLE__)->Instance->OAR2 & I2C_OAR2_OA2)) + +#define IS_I2C_OWN_ADDRESS1(ADDRESS1) ((ADDRESS1) <= 0x000003FFU) +#define IS_I2C_OWN_ADDRESS2(ADDRESS2) ((ADDRESS2) <= (uint16_t)0x00FFU) + +#define I2C_MEM_ADD_MSB(__ADDRESS__) ((uint8_t)((uint16_t)(((uint16_t)((__ADDRESS__) & \ + (uint16_t)(0xFF00U))) >> 8U))) +#define I2C_MEM_ADD_LSB(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)(0x00FFU)))) + +#define I2C_GENERATE_START(__ADDMODE__,__ADDRESS__) (((__ADDMODE__) == I2C_ADDRESSINGMODE_7BIT) ? \ + (uint32_t)((((uint32_t)(__ADDRESS__) & (I2C_CR2_SADD)) | \ + (I2C_CR2_START) | (I2C_CR2_AUTOEND)) & \ + (~I2C_CR2_RD_WRN)) : \ + (uint32_t)((((uint32_t)(__ADDRESS__) & (I2C_CR2_SADD)) | \ + (I2C_CR2_ADD10) | (I2C_CR2_START) | \ + (I2C_CR2_AUTOEND)) & (~I2C_CR2_RD_WRN))) + +#define I2C_CHECK_FLAG(__ISR__, __FLAG__) ((((__ISR__) & ((__FLAG__) & I2C_FLAG_MASK)) == \ + ((__FLAG__) & I2C_FLAG_MASK)) ? SET : RESET) +#define I2C_CHECK_IT_SOURCE(__CR1__, __IT__) ((((__CR1__) & (__IT__)) == (__IT__)) ? SET : RESET) +/** + * @} + */ + +/* Private Functions ---------------------------------------------------------*/ +/** @defgroup I2C_Private_Functions I2C Private Functions + * @{ + */ +/* Private functions are defined in stm32h5xx_hal_i2c.c file */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* STM32H5xx_HAL_I2C_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_i2c_ex.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_i2c_ex.h new file mode 100644 index 0000000000..31e0f381ff --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_i2c_ex.h @@ -0,0 +1,156 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_i2c_ex.h + * @author MCD Application Team + * @brief Header file of I2C HAL Extended module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_I2C_EX_H +#define STM32H5xx_HAL_I2C_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup I2CEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup I2CEx_Exported_Constants I2C Extended Exported Constants + * @{ + */ + +/** @defgroup I2CEx_Analog_Filter I2C Extended Analog Filter + * @{ + */ +#define I2C_ANALOGFILTER_ENABLE 0x00000000U +#define I2C_ANALOGFILTER_DISABLE I2C_CR1_ANFOFF +/** + * @} + */ + +/** @defgroup I2CEx_FastModePlus I2C Extended Fast Mode Plus + * @{ + */ +#define I2C_FASTMODEPLUS_ENABLE 0x00000000U /*!< Enable Fast Mode Plus */ +#define I2C_FASTMODEPLUS_DISABLE 0x00000001U /*!< Disable Fast Mode Plus */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup I2CEx_Exported_Macros I2C Extended Exported Macros + * @{ + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup I2CEx_Exported_Functions I2C Extended Exported Functions + * @{ + */ + +/** @addtogroup I2CEx_Exported_Functions_Group1 Filter Mode Functions + * @{ + */ +/* Peripheral Control functions ************************************************/ +HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter); +HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_t DigitalFilter); +/** + * @} + */ + +/** @addtogroup I2CEx_Exported_Functions_Group2 WakeUp Mode Functions + * @{ + */ +HAL_StatusTypeDef HAL_I2CEx_EnableWakeUp(I2C_HandleTypeDef *hi2c); +HAL_StatusTypeDef HAL_I2CEx_DisableWakeUp(I2C_HandleTypeDef *hi2c); +/** + * @} + */ + +/** @addtogroup I2CEx_Exported_Functions_Group3 Fast Mode Plus Functions + * @{ + */ +HAL_StatusTypeDef HAL_I2CEx_ConfigFastModePlus(I2C_HandleTypeDef *hi2c, uint32_t FastModePlus); +/** + * @} + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup I2CEx_Private_Constants I2C Extended Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup I2CEx_Private_Macro I2C Extended Private Macros + * @{ + */ +#define IS_I2C_ANALOG_FILTER(FILTER) (((FILTER) == I2C_ANALOGFILTER_ENABLE) || \ + ((FILTER) == I2C_ANALOGFILTER_DISABLE)) + +#define IS_I2C_DIGITAL_FILTER(FILTER) ((FILTER) <= 0x0000000FU) + +#define IS_I2C_FASTMODEPLUS(__CONFIG__) (((__CONFIG__) == (I2C_FASTMODEPLUS_ENABLE)) || \ + ((__CONFIG__) == (I2C_FASTMODEPLUS_DISABLE))) +/** + * @} + */ + +/* Private Functions ---------------------------------------------------------*/ +/** @defgroup I2CEx_Private_Functions I2C Extended Private Functions + * @{ + */ +/* Private functions are defined in stm32h5xx_hal_i2c_ex.c file */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_I2C_EX_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_i2s.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_i2s.h new file mode 100644 index 0000000000..c49a515274 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_i2s.h @@ -0,0 +1,663 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_i2s.h + * @author MCD Application Team + * @brief Header file of I2S HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_I2S_H +#define STM32H5xx_HAL_I2S_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup I2S + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup I2S_Exported_Types I2S Exported Types + * @{ + */ + +/** + * @brief I2S Init structure definition + */ +typedef struct +{ + uint32_t Mode; /*!< Specifies the I2S operating mode. + This parameter can be a value of @ref I2S_Mode */ + + uint32_t Standard; /*!< Specifies the standard used for the I2S communication. + This parameter can be a value of @ref I2S_Standard */ + + uint32_t DataFormat; /*!< Specifies the data format for the I2S communication. + This parameter can be a value of @ref I2S_Data_Format */ + + uint32_t MCLKOutput; /*!< Specifies whether the I2S MCLK output is enabled or not. + This parameter can be a value of @ref I2S_MCLK_Output */ + + uint32_t AudioFreq; /*!< Specifies the frequency selected for the I2S communication. + This parameter can be a value of @ref I2S_Audio_Frequency */ + + uint32_t CPOL; /*!< Specifies the idle state of the I2S clock. + This parameter can be a value of @ref I2S_Clock_Polarity */ + + uint32_t FirstBit; /*!< Specifies whether data transfers start from MSB or LSB bit. + This parameter can be a value of @ref I2S_MSB_LSB_Transmission */ + + uint32_t WSInversion; /*!< Control the Word Select Inversion. + This parameter can be a value of @ref I2S_WSInversion */ + + uint32_t Data24BitAlignment; /*!< Specifies the Data Padding for 24 bits data length + This parameter can be a value of @ref I2S_Data_24Bit_Alignment */ + + uint32_t MasterKeepIOState; /*!< Control of Alternate function GPIOs state + This parameter can be a value of @ref I2S_Master_Keep_IO_State */ + +} I2S_InitTypeDef; + +/** + * @brief HAL State structures definition + */ +typedef enum +{ + HAL_I2S_STATE_RESET = 0x00UL, /*!< I2S not yet initialized or disabled */ + HAL_I2S_STATE_READY = 0x01UL, /*!< I2S initialized and ready for use */ + HAL_I2S_STATE_BUSY = 0x02UL, /*!< I2S internal process is ongoing */ + HAL_I2S_STATE_BUSY_TX = 0x03UL, /*!< Data Transmission process is ongoing */ + HAL_I2S_STATE_BUSY_RX = 0x04UL, /*!< Data Reception process is ongoing */ + HAL_I2S_STATE_BUSY_TX_RX = 0x05UL, /*!< Data Transmission and Reception process is ongoing */ + HAL_I2S_STATE_TIMEOUT = 0x06UL, /*!< I2S timeout state */ + HAL_I2S_STATE_ERROR = 0x07UL /*!< I2S error state */ +} HAL_I2S_StateTypeDef; + +/** + * @brief I2S handle Structure definition + */ +typedef struct __I2S_HandleTypeDef +{ + SPI_TypeDef *Instance; /*!< I2S registers base address */ + + I2S_InitTypeDef Init; /*!< I2S communication parameters */ + + const uint16_t *pTxBuffPtr; /*!< Pointer to I2S Tx transfer buffer */ + + __IO uint16_t TxXferSize; /*!< I2S Tx transfer size */ + + __IO uint16_t TxXferCount; /*!< I2S Tx transfer Counter */ + + uint16_t *pRxBuffPtr; /*!< Pointer to I2S Rx transfer buffer */ + + __IO uint16_t RxXferSize; /*!< I2S Rx transfer size */ + + __IO uint16_t RxXferCount; /*!< I2S Rx transfer counter + (This field is initialized at the + same value as transfer size at the + beginning of the transfer and + decremented when a sample is received + NbSamplesReceived = RxBufferSize-RxBufferCount) */ + + void (*RxISR)(struct __I2S_HandleTypeDef *hi2s); /*!< function pointer on Rx ISR */ + + void (*TxISR)(struct __I2S_HandleTypeDef *hi2s); /*!< function pointer on Tx ISR */ + + DMA_HandleTypeDef *hdmatx; /*!< I2S Tx DMA handle parameters */ + + DMA_HandleTypeDef *hdmarx; /*!< I2S Rx DMA handle parameters */ + + __IO HAL_LockTypeDef Lock; /*!< I2S locking object */ + + __IO HAL_I2S_StateTypeDef State; /*!< I2S communication state */ + + __IO uint32_t ErrorCode; /*!< I2S Error code + This parameter can be a value of @ref I2S_Error */ + +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U) + void (* TxCpltCallback)(struct __I2S_HandleTypeDef *hi2s); /*!< I2S Tx Completed callback */ + void (* RxCpltCallback)(struct __I2S_HandleTypeDef *hi2s); /*!< I2S Rx Completed callback */ + void (* TxRxCpltCallback)(struct __I2S_HandleTypeDef *hi2s); /*!< I2S TxRx Completed callback */ + void (* TxHalfCpltCallback)(struct __I2S_HandleTypeDef *hi2s); /*!< I2S Tx Half Completed callback */ + void (* RxHalfCpltCallback)(struct __I2S_HandleTypeDef *hi2s); /*!< I2S Rx Half Completed callback */ + void (* TxRxHalfCpltCallback)(struct __I2S_HandleTypeDef *hi2s); /*!< I2S TxRx Half Completed callback */ + void (* ErrorCallback)(struct __I2S_HandleTypeDef *hi2s); /*!< I2S Error callback */ + void (* MspInitCallback)(struct __I2S_HandleTypeDef *hi2s); /*!< I2S Msp Init callback */ + void (* MspDeInitCallback)(struct __I2S_HandleTypeDef *hi2s); /*!< I2S Msp DeInit callback */ + +#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ +} I2S_HandleTypeDef; + +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL) +/** + + * @brief HAL I2S Callback ID enumeration definition + */ +typedef enum +{ + HAL_I2S_TX_COMPLETE_CB_ID = 0x00UL, /*!< I2S Tx Completed callback ID */ + HAL_I2S_RX_COMPLETE_CB_ID = 0x01UL, /*!< I2S Rx Completed callback ID */ + HAL_I2S_TX_RX_COMPLETE_CB_ID = 0x02UL, /*!< I2S TxRx Completed callback ID */ + HAL_I2S_TX_HALF_COMPLETE_CB_ID = 0x03UL, /*!< I2S Tx Half Completed callback ID */ + HAL_I2S_RX_HALF_COMPLETE_CB_ID = 0x04UL, /*!< I2S Rx Half Completed callback ID */ + HAL_I2S_TX_RX_HALF_COMPLETE_CB_ID = 0x05UL, /*!< I2S TxRx Half Completed callback ID */ + HAL_I2S_ERROR_CB_ID = 0x06UL, /*!< I2S Error callback ID */ + HAL_I2S_MSPINIT_CB_ID = 0x07UL, /*!< I2S Msp Init callback ID */ + HAL_I2S_MSPDEINIT_CB_ID = 0x08UL /*!< I2S Msp DeInit callback ID */ + +} HAL_I2S_CallbackIDTypeDef; + +/** + * @brief HAL I2S Callback pointer definition + */ +typedef void (*pI2S_CallbackTypeDef)(I2S_HandleTypeDef *hi2s); /*!< pointer to an I2S callback function */ + +#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup I2S_Exported_Constants I2S Exported Constants + * @{ + */ +/** @defgroup I2S_Error I2S Error + * @{ + */ +#define HAL_I2S_ERROR_NONE (0x00000000UL) /*!< No error */ +#define HAL_I2S_ERROR_TIMEOUT (0x00000001UL) /*!< Timeout error */ +#define HAL_I2S_ERROR_OVR (0x00000002UL) /*!< OVR error */ +#define HAL_I2S_ERROR_UDR (0x00000004UL) /*!< UDR error */ +#define HAL_I2S_ERROR_DMA (0x00000008UL) /*!< DMA transfer error */ +#define HAL_I2S_ERROR_PRESCALER (0x00000010UL) /*!< Prescaler Calculation error */ +#define HAL_I2S_ERROR_FRE (0x00000020UL) /*!< FRE error */ +#define HAL_I2S_ERROR_NO_OGT (0x00000040UL) /*!< No On Going Transfer error */ +#define HAL_I2S_ERROR_NOT_SUPPORTED (0x00000080UL) /*!< Requested operation not supported */ +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL) +#define HAL_I2S_ERROR_INVALID_CALLBACK (0x00000100UL) /*!< Invalid Callback error */ +#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @defgroup I2S_Mode I2S Mode + * @{ + */ +#define I2S_MODE_SLAVE_TX (0x00000000UL) +#define I2S_MODE_SLAVE_RX (SPI_I2SCFGR_I2SCFG_0) +#define I2S_MODE_MASTER_TX (SPI_I2SCFGR_I2SCFG_1) +#define I2S_MODE_MASTER_RX (SPI_I2SCFGR_I2SCFG_0 | SPI_I2SCFGR_I2SCFG_1) +#define I2S_MODE_SLAVE_FULLDUPLEX (SPI_I2SCFGR_I2SCFG_2) +#define I2S_MODE_MASTER_FULLDUPLEX (SPI_I2SCFGR_I2SCFG_2 | SPI_I2SCFGR_I2SCFG_0) +/** + * @} + */ + +/** @defgroup I2S_Standard I2S Standard + * @{ + */ +#define I2S_STANDARD_PHILIPS (0x00000000UL) +#define I2S_STANDARD_MSB (SPI_I2SCFGR_I2SSTD_0) +#define I2S_STANDARD_LSB (SPI_I2SCFGR_I2SSTD_1) +#define I2S_STANDARD_PCM_SHORT (SPI_I2SCFGR_I2SSTD_0 | SPI_I2SCFGR_I2SSTD_1) +#define I2S_STANDARD_PCM_LONG (SPI_I2SCFGR_I2SSTD_0 | SPI_I2SCFGR_I2SSTD_1 | SPI_I2SCFGR_PCMSYNC) +/** + * @} + */ + +/** @defgroup I2S_Data_Format I2S Data Format + * @{ + */ +#define I2S_DATAFORMAT_16B (0x00000000UL) +#define I2S_DATAFORMAT_16B_EXTENDED (SPI_I2SCFGR_CHLEN) +#define I2S_DATAFORMAT_24B (SPI_I2SCFGR_DATLEN_0) +#define I2S_DATAFORMAT_32B (SPI_I2SCFGR_DATLEN_1) +/** + * @} + */ + +/** @defgroup I2S_MCLK_Output I2S MCLK Output + * @{ + */ +#define I2S_MCLKOUTPUT_ENABLE (SPI_I2SCFGR_MCKOE) +#define I2S_MCLKOUTPUT_DISABLE (0x00000000UL) +/** + * @} + */ + +/** @defgroup I2S_Audio_Frequency I2S Audio Frequency + * @{ + */ +#define I2S_AUDIOFREQ_192K (192000UL) +#define I2S_AUDIOFREQ_96K (96000UL) +#define I2S_AUDIOFREQ_48K (48000UL) +#define I2S_AUDIOFREQ_44K (44100UL) +#define I2S_AUDIOFREQ_32K (32000UL) +#define I2S_AUDIOFREQ_22K (22050UL) +#define I2S_AUDIOFREQ_16K (16000UL) +#define I2S_AUDIOFREQ_11K (11025UL) +#define I2S_AUDIOFREQ_8K (8000UL) +#define I2S_AUDIOFREQ_DEFAULT (2UL) +/** + * @} + */ + +/** @defgroup I2S_Clock_Polarity I2S FullDuplex Mode + * @{ + */ +#define I2S_CPOL_LOW (0x00000000UL) +#define I2S_CPOL_HIGH (SPI_I2SCFGR_CKPOL) +/** + * @} + */ + +/** @defgroup I2S_MSB_LSB_Transmission I2S MSB LSB Transmission + * @{ + */ +#define I2S_FIRSTBIT_MSB (0x00000000UL) +#define I2S_FIRSTBIT_LSB SPI_CFG2_LSBFRST +/** + * @} + */ + +/** @defgroup I2S_WSInversion I2S Word Select Inversion + * @{ + */ +#define I2S_WS_INVERSION_DISABLE (0x00000000UL) +#define I2S_WS_INVERSION_ENABLE SPI_I2SCFGR_WSINV +/** + * @} + */ + +/** @defgroup I2S_Data_24Bit_Alignment Data Padding 24Bit + * @{ + */ +#define I2S_DATA_24BIT_ALIGNMENT_RIGHT (0x00000000UL) +#define I2S_DATA_24BIT_ALIGNMENT_LEFT SPI_I2SCFGR_DATFMT +/** + * @} + */ + +/** @defgroup I2S_Master_Keep_IO_State Keep IO State + * @{ + */ +#define I2S_MASTER_KEEP_IO_STATE_DISABLE (0x00000000U) +#define I2S_MASTER_KEEP_IO_STATE_ENABLE SPI_CFG2_AFCNTR +/** + * @} + */ + +/** @defgroup I2S_Interrupts_Definition I2S Interrupts Definition + * @{ + */ +#define I2S_IT_RXP SPI_IER_RXPIE +#define I2S_IT_TXP SPI_IER_TXPIE +#define I2S_IT_DXP SPI_IER_DXPIE +#define I2S_IT_UDR SPI_IER_UDRIE +#define I2S_IT_OVR SPI_IER_OVRIE +#define I2S_IT_FRE SPI_IER_TIFREIE +#define I2S_IT_ERR (SPI_IER_UDRIE | SPI_IER_OVRIE | SPI_IER_TIFREIE) +/** + * @} + */ + +/** @defgroup I2S_Flags_Definition I2S Flags Definition + * @{ + */ +#define I2S_FLAG_RXP SPI_SR_RXP /* I2S status flag : Rx-Packet available flag */ +#define I2S_FLAG_TXP SPI_SR_TXP /* I2S status flag : Tx-Packet space available flag */ +#define I2S_FLAG_DXP SPI_SR_DXP /* I2S status flag : Dx-Packet space available flag */ +#define I2S_FLAG_UDR SPI_SR_UDR /* I2S Error flag : Underrun flag */ +#define I2S_FLAG_OVR SPI_SR_OVR /* I2S Error flag : Overrun flag */ +#define I2S_FLAG_FRE SPI_SR_TIFRE /* I2S Error flag : TI mode frame format error flag */ + +#define I2S_FLAG_MASK (SPI_SR_RXP | SPI_SR_TXP | SPI_SR_DXP |SPI_SR_UDR | SPI_SR_OVR | SPI_SR_TIFRE) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup I2S_Exported_macros I2S Exported Macros + * @{ + */ + +/** @brief Reset I2S handle state + * @param __HANDLE__ specifies the I2S Handle. + * @retval None + */ +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL) +#define __HAL_I2S_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->State = HAL_I2S_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_I2S_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_I2S_STATE_RESET) +#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ + +/** @brief Enable the specified SPI peripheral (in I2S mode). + * @param __HANDLE__ specifies the I2S Handle. + * @retval None + */ +#define __HAL_I2S_ENABLE(__HANDLE__) (SET_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_SPE)) + +/** @brief Disable the specified SPI peripheral (in I2S mode). + * @param __HANDLE__ specifies the I2S Handle. + * @retval None + */ +#define __HAL_I2S_DISABLE(__HANDLE__) (CLEAR_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_SPE)) + +/** @brief Enable the specified I2S interrupts. + * @param __HANDLE__ specifies the I2S Handle. + * This parameter can be I2S where x: 1, 2 or 3 to select the I2S peripheral. + * @param __INTERRUPT__ specifies the interrupt source to enable or disable. + * This parameter can be one of the following values: + * @arg I2S_IT_RXP : Rx-Packet available interrupt + * @arg I2S_IT_TXP : Tx-Packet space available interrupt + * @arg I2S_IT_UDR : Underrun interrupt + * @arg I2S_IT_OVR : Overrun interrupt + * @arg I2S_IT_FRE : TI mode frame format error interrupt + * @arg I2S_IT_ERR : Error interrupt enable + * @retval None + */ +#define __HAL_I2S_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IER |= (__INTERRUPT__)) + +/** @brief Disable the specified I2S interrupts. + * @param __HANDLE__ specifies the I2S Handle. + * This parameter can be I2S where x: 1, 2 or 3 to select the I2S peripheral. + * @param __INTERRUPT__ specifies the interrupt source to enable or disable. + * This parameter can be one of the following values: + * @arg I2S_IT_RXP : Rx-Packet available interrupt + * @arg I2S_IT_TXP : Tx-Packet space available interrupt + * @arg I2S_IT_UDR : Underrun interrupt + * @arg I2S_IT_OVR : Overrun interrupt + * @arg I2S_IT_FRE : TI mode frame format error interrupt + * @arg I2S_IT_ERR : Error interrupt enable + * @retval None + */ +#define __HAL_I2S_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IER &= (~(__INTERRUPT__))) + +/** @brief Check if the specified I2S interrupt source is enabled or disabled. + * @param __HANDLE__ specifies the I2S Handle. + * This parameter can be I2S where x: 1, 2 or 3 to select the I2S peripheral. + * @param __INTERRUPT__ specifies the I2S interrupt source to check. + * This parameter can be one of the following values: + * @arg I2S_IT_RXP : Rx-Packet available interrupt + * @arg I2S_IT_TXP : Tx-Packet space available interrupt + * @arg I2S_IT_DXP : Tx-Packet space available interrupt + * @arg I2S_IT_UDR : Underrun interrupt + * @arg I2S_IT_OVR : Overrun interrupt + * @arg I2S_IT_FRE : TI mode frame format error interrupt + * @arg I2S_IT_ERR : Error interrupt enable + * @retval The new state of __IT__ (TRUE or FALSE). + */ +#define __HAL_I2S_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->IER\ + & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) + +/** @brief Check whether the specified I2S flag is set or not. + * @param __HANDLE__ specifies the I2S Handle. + * This parameter can be I2S where x: 1, 2 or 3 to select the I2S peripheral. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg I2S_FLAG_RXP : Rx-Packet available flag + * @arg I2S_FLAG_TXP : Tx-Packet space available flag + * @arg I2S_FLAG_UDR : Underrun flag + * @arg I2S_FLAG_OVR : Overrun flag + * @arg I2S_FLAG_FRE : TI mode frame format error flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_I2S_GET_FLAG(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->SR) & (__FLAG__)) == (__FLAG__)) + +/** @brief Clear the I2S OVR pending flag. + * @param __HANDLE__ specifies the I2S Handle. + * @retval None + */ +#define __HAL_I2S_CLEAR_OVRFLAG(__HANDLE__) SET_BIT((__HANDLE__)->Instance->IFCR , SPI_IFCR_OVRC) + +/** @brief Clear the I2S UDR pending flag. + * @param __HANDLE__ specifies the I2S Handle. + * @retval None + */ +#define __HAL_I2S_CLEAR_UDRFLAG(__HANDLE__) SET_BIT((__HANDLE__)->Instance->IFCR , SPI_IFCR_UDRC) + +/** @brief Clear the I2S FRE pending flag. + * @param __HANDLE__: specifies the I2S Handle. + * @retval None + */ +#define __HAL_I2S_CLEAR_TIFREFLAG(__HANDLE__) SET_BIT((__HANDLE__)->Instance->IFCR , SPI_IFCR_TIFREC) +/** + * @} + */ + + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup I2S_Exported_Functions + * @{ + */ + +/** @addtogroup I2S_Exported_Functions_Group1 + * @{ + */ +/* Initialization/de-initialization functions ********************************/ +HAL_StatusTypeDef HAL_I2S_Init(I2S_HandleTypeDef *hi2s); +HAL_StatusTypeDef HAL_I2S_DeInit(I2S_HandleTypeDef *hi2s); +void HAL_I2S_MspInit(I2S_HandleTypeDef *hi2s); +void HAL_I2S_MspDeInit(I2S_HandleTypeDef *hi2s); + +/* Callbacks Register/UnRegister functions ***********************************/ +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL) +HAL_StatusTypeDef HAL_I2S_RegisterCallback(I2S_HandleTypeDef *hi2s, HAL_I2S_CallbackIDTypeDef CallbackID, + pI2S_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_I2S_UnRegisterCallback(I2S_HandleTypeDef *hi2s, HAL_I2S_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @addtogroup I2S_Exported_Functions_Group2 + * @{ + */ +/* I/O operation functions ***************************************************/ +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_I2S_Transmit(I2S_HandleTypeDef *hi2s, const uint16_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2S_Receive(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2SEx_TransmitReceive(I2S_HandleTypeDef *hi2s, const uint16_t *pTxData, uint16_t *pRxData, + uint16_t Size, uint32_t Timeout); + +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, const uint16_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2S_Receive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s, const uint16_t *pTxData, uint16_t *pRxData, + uint16_t Size); + +void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s); + +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_I2S_Transmit_DMA(I2S_HandleTypeDef *hi2s, const uint16_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2S_Receive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_DMA(I2S_HandleTypeDef *hi2s, const uint16_t *pTxData, uint16_t *pRxData, + uint16_t Size); + +HAL_StatusTypeDef HAL_I2S_DMAPause(I2S_HandleTypeDef *hi2s); +HAL_StatusTypeDef HAL_I2S_DMAResume(I2S_HandleTypeDef *hi2s); +HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s); + +/* Callbacks used in non blocking modes (Interrupt and DMA) *******************/ +void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s); +void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s); +void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s); +void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s); +void HAL_I2SEx_TxRxHalfCpltCallback(I2S_HandleTypeDef *hi2s); +void HAL_I2SEx_TxRxCpltCallback(I2S_HandleTypeDef *hi2s); +void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s); +/** + * @} + */ + +/** @addtogroup I2S_Exported_Functions_Group3 + * @{ + */ +/* Peripheral Control and State functions ************************************/ +HAL_I2S_StateTypeDef HAL_I2S_GetState(const I2S_HandleTypeDef *hi2s); +uint32_t HAL_I2S_GetError(const I2S_HandleTypeDef *hi2s); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup I2S_Private_Constants I2S Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private Functions ---------------------------------------------------------*/ +/** @defgroup I2S_Private_Functions I2S Private Functions + * @{ + */ +/* Private functions are defined in stm32h7xx_hal_i2S.c file */ +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup I2S_Private_Macros I2S Private Macros + * @{ + */ + +/** @brief Check whether the specified SPI flag is set or not. + * @param __SR__ copy of I2S SR register. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg I2S_FLAG_RXP : Rx-Packet available flag + * @arg I2S_FLAG_TXP : Tx-Packet space available flag + * @arg I2S_FLAG_UDR : Underrun flag + * @arg I2S_FLAG_OVR : Overrun flag + * @arg I2S_FLAG_FRE : TI mode frame format error flag + * @retval SET or RESET. + */ +#define I2S_CHECK_FLAG(__SR__, __FLAG__) ((((__SR__)\ + & ((__FLAG__) & I2S_FLAG_MASK)) == ((__FLAG__) & I2S_FLAG_MASK))\ + ? SET : RESET) + +/** @brief Check whether the specified SPI Interrupt is set or not. + * @param __IER__ copy of I2S IER register. + * @param __INTERRUPT__ specifies the SPI interrupt source to check. + * This parameter can be one of the following values: + * @arg I2S_IT_RXP : Rx-Packet available interrupt + * @arg I2S_IT_TXP : Tx-Packet space available interrupt + * @arg I2S_IT_UDR : Underrun interrupt + * @arg I2S_IT_OVR : Overrun interrupt + * @arg I2S_IT_FRE : TI mode frame format error interrupt + * @arg I2S_IT_ERR : Error interrupt enable + * @retval SET or RESET. + */ +#define I2S_CHECK_IT_SOURCE(__IER__, __INTERRUPT__) ((((__IER__)\ + & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) + +/** @brief Checks if I2S Mode parameter is in allowed range. + * @param __MODE__ specifies the I2S Mode. + * This parameter can be a value of @ref I2S_Mode + * @retval None + */ +#define IS_I2S_MODE(__MODE__) (((__MODE__) == I2S_MODE_SLAVE_TX) || \ + ((__MODE__) == I2S_MODE_SLAVE_RX) || \ + ((__MODE__) == I2S_MODE_MASTER_TX) || \ + ((__MODE__) == I2S_MODE_MASTER_RX) || \ + ((__MODE__) == I2S_MODE_SLAVE_FULLDUPLEX) || \ + ((__MODE__) == I2S_MODE_MASTER_FULLDUPLEX)) + +#define IS_I2S_MASTER(__MODE__) (((__MODE__) == I2S_MODE_MASTER_TX) || \ + ((__MODE__) == I2S_MODE_MASTER_RX) || \ + ((__MODE__) == I2S_MODE_MASTER_FULLDUPLEX)) + +#define IS_I2S_SLAVE(__MODE__) (((__MODE__) == I2S_MODE_SLAVE_TX) || \ + ((__MODE__) == I2S_MODE_SLAVE_RX) || \ + ((__MODE__) == I2S_MODE_SLAVE_FULLDUPLEX)) + +#define IS_I2S_FULLDUPLEX(__MODE__) (((__MODE__) == I2S_MODE_MASTER_FULLDUPLEX) || \ + ((__MODE__) == I2S_MODE_SLAVE_FULLDUPLEX)) + +#define IS_I2S_STANDARD(__STANDARD__) (((__STANDARD__) == I2S_STANDARD_PHILIPS) || \ + ((__STANDARD__) == I2S_STANDARD_MSB) || \ + ((__STANDARD__) == I2S_STANDARD_LSB) || \ + ((__STANDARD__) == I2S_STANDARD_PCM_SHORT) || \ + ((__STANDARD__) == I2S_STANDARD_PCM_LONG)) + +#define IS_I2S_DATA_FORMAT(__FORMAT__) (((__FORMAT__) == I2S_DATAFORMAT_16B) || \ + ((__FORMAT__) == I2S_DATAFORMAT_16B_EXTENDED) || \ + ((__FORMAT__) == I2S_DATAFORMAT_24B) || \ + ((__FORMAT__) == I2S_DATAFORMAT_32B)) + +#define IS_I2S_MCLK_OUTPUT(__OUTPUT__) (((__OUTPUT__) == I2S_MCLKOUTPUT_ENABLE) || \ + ((__OUTPUT__) == I2S_MCLKOUTPUT_DISABLE)) + +#define IS_I2S_AUDIO_FREQ(__FREQ__) ((((__FREQ__) >= I2S_AUDIOFREQ_8K) && \ + ((__FREQ__) <= I2S_AUDIOFREQ_192K)) || \ + ((__FREQ__) == I2S_AUDIOFREQ_DEFAULT)) + +#define IS_I2S_CPOL(__CPOL__) (((__CPOL__) == I2S_CPOL_LOW) || \ + ((__CPOL__) == I2S_CPOL_HIGH)) + +#define IS_I2S_FIRST_BIT(__BIT__) (((__BIT__) == I2S_FIRSTBIT_MSB) || \ + ((__BIT__) == I2S_FIRSTBIT_LSB)) + +#define IS_I2S_WS_INVERSION(__WSINV__) (((__WSINV__) == I2S_WS_INVERSION_DISABLE) || \ + ((__WSINV__) == I2S_WS_INVERSION_ENABLE)) + +#define IS_I2S_DATA_24BIT_ALIGNMENT(__ALIGNMENT__) (((__ALIGNMENT__) == I2S_DATA_24BIT_ALIGNMENT_RIGHT) || \ + ((__ALIGNMENT__) == I2S_DATA_24BIT_ALIGNMENT_LEFT)) + +#define IS_I2S_MASTER_KEEP_IO_STATE(__AFCNTR__) (((__AFCNTR__) == I2S_MASTER_KEEP_IO_STATE_DISABLE) || \ + ((__AFCNTR__) == I2S_MASTER_KEEP_IO_STATE_ENABLE)) + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_I2S_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_i2s_ex.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_i2s_ex.h new file mode 100644 index 0000000000..f5bf619aa1 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_i2s_ex.h @@ -0,0 +1,26 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_i2s_ex.h + * @author MCD Application Team + * @brief Header file of I2S HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/** + ****************************************************************************** + ===== I2S FULL DUPLEX FEATURE ===== + I2S Full Duplex APIs are available in stm32h5xx_hal_i2s.c/.h + ****************************************************************************** + */ + + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_i3c.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_i3c.h new file mode 100644 index 0000000000..1d2fdeccad --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_i3c.h @@ -0,0 +1,1319 @@ +/** + ********************************************************************************************************************** + * @file stm32h5xx_hal_i3c.h + * @author MCD Application Team + * @brief Header file of I3C HAL module. + ********************************************************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ********************************************************************************************************************** + */ + +/* Define to prevent recursive inclusion -----------------------------------------------------------------------------*/ +#ifndef STM32H5xx_HAL_I3C_H +#define STM32H5xx_HAL_I3C_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ----------------------------------------------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" +#include "stm32h5xx_ll_i3c.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup I3C + * @{ + */ + +/* Exported types ----------------------------------------------------------------------------------------------------*/ +/** @defgroup I3C_Exported_Types I3C Exported Types + * @{ + */ +/** @defgroup I3C_Init_Structure_definition I3C Init Structure definition + * @brief I3C Init Structure definition + * @{ + */ +typedef struct +{ + LL_I3C_CtrlBusConfTypeDef CtrlBusCharacteristic; /*!< Specifies the I3C controller bus characteristic configuration + when Controller mode */ + + LL_I3C_TgtBusConfTypeDef TgtBusCharacteristic; /*!< Specifies the I3C target bus characteristic configuration + when Target mode */ + +} I3C_InitTypeDef; +/** + * @} + */ + +/** @defgroup I3C_FIFO_Config_Structure_definition I3C FIFO Configuration Structure definition + * @brief I3C FIFO configuration structure definition + * @{ + */ +typedef struct +{ + uint32_t RxFifoThreshold; /*!< Specifies the I3C Rx FIFO threshold level. + This parameter must be a value of @ref I3C_RX_FIFO_THRESHOLD */ + + uint32_t TxFifoThreshold; /*!< Specifies the I3C Tx FIFO threshold level. + This parameter must be a value of @ref I3C_TX_FIFO_THRESHOLD */ + + uint32_t ControlFifo; /*!< Specifies the I3C control FIFO enable/disable state. + This parameter is configured only with controller mode and it + must be a value of @ref I3C_CONTROL_FIFO_STATE */ + + uint32_t StatusFifo; /*!< Specifies the I3C status FIFO enable/disable state. + This parameter is configured only with controller mode and it + must be a value of @ref I3C_STATUS_FIFO_STATE */ +} I3C_FifoConfTypeDef; +/** + * @} + */ + +/** @defgroup I3C_Controller_Config_Structure_definition I3C Controller Configuration Structure definition + * @brief I3C controller configuration structure definition + * @{ + */ +typedef struct +{ + uint8_t DynamicAddr; /*!< Specifies the dynamic address of the controller when goes in target mode. + This parameter must be a number between Min_Data=0x00 and Max_Data=0x7F */ + + uint8_t StallTime; /*!< Specifies the controller clock stall time in number of kernel clock cycles. + This parameter must be a number between Min_Data=0x00 and Max_Data=0xFF */ + + FunctionalState HotJoinAllowed; /*!< Specifies the Enable/Disable state of the controller Hot Join acknowledgement + when receiving a hot join request from target. + This parameter can be set to ENABLE or DISABLE */ + + FunctionalState ACKStallState; /*!< Specifies the Enable/Disable state of the controller clock stall + on the ACK phase. + This parameter can be set to ENABLE or DISABLE */ + + FunctionalState CCCStallState; /*!< Specifies the Enable/Disable state of the controller clock stall on the + T bit phase of a CCC communication to allow the target to decode command. + This parameter can be set to ENABLE or DISABLE */ + + FunctionalState TxStallState; /*!< Specifies the Enable/Disable state of the controller clock stall on + parity phase of data to allow the target to read received data. + This parameter can be set to ENABLE or DISABLE */ + + FunctionalState RxStallState; /*!< Specifies the Enable/Disable state of the controller clock stall on the T bit + phase of data enable to allow the target to prepare data to be sent. + This parameter can be set to ENABLE or DISABLE */ + + FunctionalState HighKeeperSDA; /*!< Specifies the Enable/Disable state of the controller SDA high keeper. + This parameter can be set to ENABLE or DISABLE */ +} I3C_CtrlConfTypeDef; +/** + * @} + */ + +/** @defgroup I3C_Target_Config_Structure_definition I3C Target Configuration Structure definition + * @brief I3C target configuration structure definition + * @{ + */ +typedef struct +{ + uint8_t Identifier; /*!< Specifies the target characteristic ID (MIPI named reference DCR). + This parameter must be a number between Min_Data=0x00 and Max_Data=0xFF */ + + uint8_t MIPIIdentifier; /*!< Specifies the bits [12-15] of the 48-provisioned ID + (MIPI named reference PID), other 48-provisioned ID are hardcoded. + This parameter must be a number between Min_Data=0x00 and Max_Data=0x0F */ + + FunctionalState CtrlRoleRequest; /*!< Specifies the Enable/Disable state of the target authorization request + for a second master Chip. + This parameter can be set to ENABLE or DISABLE */ + + FunctionalState HotJoinRequest; /*!< Specifies the Enable/Disable state of the target hot join + authorization request. + This parameter can be set to ENABLE or DISABLE */ + + FunctionalState IBIRequest; /*!< Specifies the Enable/Disable state of the target in Band Interrupt + authorization request. + This parameter can be set to ENABLE or DISABLE */ + + FunctionalState IBIPayload; /*!< Specifies the Enable/Disable state of sending data payload after + an accepted IBI. + This parameter can be set to ENABLE or DISABLE */ + + uint32_t IBIPayloadSize; /*!< Specifies the I3C target payload data size. + This parameter must be a value of @ref I3C_PAYLOAD_SIZE */ + + uint16_t MaxReadDataSize; /*!< Specifies the numbers of data bytes that the target can read at maximum. + This parameter must be a number between Min_Data=0x00 and Max_Data=0xFFFF */ + + uint16_t MaxWriteDataSize; /*!< Specifies the numbers of data bytes that the target can write at maximum. + This parameter must be a number between Min_Data=0x00 and Max_Data=0xFFFF */ + + FunctionalState CtrlCapability; /*!< Specifies the Enable/Disable state of the target controller capability. + This parameter can be set to ENABLE or DISABLE */ + + FunctionalState GroupAddrCapability; /*!< Specifies the Enable/Disable state of the target support of group address + after a controller role hand-off. + This parameter can be set to ENABLE or DISABLE */ + + uint32_t DataTurnAroundDuration; /*!< Specifies the I3C target clock-to-data turnaround time. + This parameter must be a value of @ref I3C_TURNAROUND_TIME_TSCO */ + + uint8_t MaxReadTurnAround; /*!< Specifies the target maximum read turnaround byte. + This parameter must be a number between Min_Data=0x00 and Max_Data=0xFF */ + + uint32_t MaxDataSpeed; /*!< Specifies the I3C target returned GETMXDS CCC format. + This parameter must be a value of @ref I3C_GETMXDS_FORMAT */ + + FunctionalState MaxSpeedLimitation; /*!< Specifies the Enable/Disable state of the target max data speed limitation. + This parameter can be set to ENABLE or DISABLE */ + + uint32_t HandOffActivityState; /*!< Specifies the I3C target activity state when becoming controller. + This parameter must be a value of @ref I3C_HANDOFF_ACTIVITY_STATE */ + + FunctionalState HandOffDelay; /*!< Specifies the Enable/Disable state of the target need of delay to process + the controller role hand-off. + This parameter can be set to ENABLE or DISABLE */ + + FunctionalState PendingReadMDB; /*!< Specifies the Enable/Disable state of the transmission of a mandatory + data bytes indicating a pending read notification for GETCAPR CCC command. + This parameter can be set to ENABLE or DISABLE */ +} I3C_TgtConfTypeDef; +/** + * @} + */ + +/** @defgroup I3C_Device_Config_Structure_definition I3C Device Configuration Structure definition + * @brief I3C device configuration structure definition + * @{ + */ +typedef struct +{ + uint8_t DeviceIndex; /*!< Specifies the index value of the device in the DEVRx register. + This parameter must be a number between Min_Data=1 and Max_Data=4 */ + + uint8_t TargetDynamicAddr; /*!< Specifies the dynamic address of the target x (1 to 4) connected on the bus. + This parameter must be a number between Min_Data=0x00 and Max_Data=0x7F */ + + FunctionalState IBIAck; /*!< Specifies the Enable/Disable state of the controller's ACK when receiving + an IBI from a target x (1 to 4) connected on the bus. + This parameter can be set to ENABLE or DISABLE */ + + FunctionalState IBIPayload; /*!< Specifies the Enable/Disable state of the controller's receiving IBI payload + after acknowledging an IBI requested from a target x (1 to 4) connected + on the bus. + This parameter can be set to ENABLE or DISABLE */ + + FunctionalState CtrlRoleReqAck; /*!< Specifies the Enable/Disable state of the controller's ACK when receiving + a control request from a target x (1 to 4) connected on the bus. + This parameter can be set to ENABLE or DISABLE */ + + FunctionalState CtrlStopTransfer; /*!< Specifies the Enable/Disable state of the controller's stop transfer after + receiving an IBI request from a target x (1 to 4) connected on the bus. + This parameter can be set to ENABLE or DISABLE */ + +} I3C_DeviceConfTypeDef; +/** + * @} + */ + +/** @defgroup I3C_mode_structure_definition I3C mode structure definition + * @brief I3C Mode structure definition + * @{ + */ +typedef enum +{ + HAL_I3C_MODE_NONE = 0x00U, /*!< No I3C communication on going */ + HAL_I3C_MODE_CONTROLLER = 0x01U, /*!< I3C communication is in controller Mode */ + HAL_I3C_MODE_TARGET = 0x02U, /*!< I3C communication is in target Mode */ + +} HAL_I3C_ModeTypeDef; +/** + * @} + */ + +/** @defgroup HAL_state_structure_definition HAL state structure definition + * @brief HAL State structure definition + * @{ + */ +typedef enum +{ + HAL_I3C_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized */ + HAL_I3C_STATE_READY = 0x10U, /*!< Peripheral Initialized and ready for use */ + HAL_I3C_STATE_BUSY = 0x20U, /*!< An internal process is ongoing */ + HAL_I3C_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing */ + HAL_I3C_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing */ + HAL_I3C_STATE_BUSY_TX_RX = 0x23U, /*!< Data Multiple Transfer process is ongoing */ + HAL_I3C_STATE_BUSY_DAA = 0x24U, /*!< Dynamic address assignment process is ongoing */ + HAL_I3C_STATE_LISTEN = 0x30U, /*!< Listen process is ongoing */ + HAL_I3C_STATE_ABORT = 0x60U, /*!< Abort user request ongoing */ + HAL_I3C_STATE_ERROR = 0xE0U, /*!< Error */ + +} HAL_I3C_StateTypeDef; +/** + * @} + */ + +/** @defgroup I3C_CCCInfoTypeDef_Structure_definition I3C CCCInfoTypeDef Structure definition + * @brief I3C CCCInfoTypeDef Structure definition + * @{ + */ +typedef struct +{ + uint32_t DynamicAddrValid; /*!< I3C target Dynamic Address Valid (updated during ENTDAA/RSTDAA/SETNEWDA CCC) + This parameter can be Valid=1U or Not Valid=0U */ + uint32_t DynamicAddr; /*!< I3C target Dynamic Address (updated during ENTDAA/RSTDAA/SETNEWDA CCC) */ + uint32_t MaxWriteLength; /*!< I3C target Maximum Write Length (updated during SETMWL CCC) */ + uint32_t MaxReadLength; /*!< I3C target Maximum Read Length (updated during SETMRL CCC) */ + uint32_t ResetAction; /*!< I3C target Reset Action level (updated during RSTACT CCC) */ + uint32_t ActivityState; /*!< I3C target Activity State (updated during ENTASx CCC) */ + uint32_t HotJoinAllowed; /*!< I3C target Hot Join (updated during ENEC/DISEC CCC) + This parameter can be Allowed=1U or Not Allowed=0U */ + uint32_t InBandAllowed; /*!< I3C target In Band Interrupt (updated during ENEC/DISEC CCC) + This parameter can be Allowed=1U or Not Allowed=0U */ + uint32_t CtrlRoleAllowed; /*!< I3C target Controller Role Request (updated during ENEC/DISEC CCC) + This parameter can be Allowed=1U or Not Allowed=0U */ + uint32_t IBICRTgtAddr; /*!< I3C controller receive Target Address during IBI or Controller Role Request event*/ + uint32_t IBITgtNbPayload; /*!< I3C controller get Number of Data Payload after an IBI event */ + uint32_t IBITgtPayload; /*!< I3C controller receive IBI Payload after an IBI event */ + +} I3C_CCCInfoTypeDef; +/** + * @} + */ + +/** @defgroup I3C_ControlTypeDef_Structure_definition I3C ControlTypeDef Structure definition + * @brief I3C ControlTypeDef Structure definition + * @{ + */ +typedef struct +{ + uint32_t *pBuffer; /*!< Pointer to the buffer containing the control or status register values */ + uint32_t Size; /*!< The size of pBuffer in words */ + +} I3C_ControlTypeDef; +/** + * @} + */ + +/** @defgroup I3C_DataTypeDef_Structure_definition I3C DataTypeDef Structure definition + * @brief I3C DataTypeDef Structure definition + * @{ + */ +typedef struct +{ + uint8_t *pBuffer; /*!< Pointer to the buffer containing all data values to transfer */ + uint32_t Size; /*!< The size of pBuffer in bytes */ + +} I3C_DataTypeDef; + +/** + * @} + */ + +/** @defgroup I3C_CCCTypeDef_Structure_definition I3C CCCTypeDef Structure definition + * @brief I3C CCCTypeDef Structure definition + * @{ + */ +typedef struct +{ + uint8_t TargetAddr; /*!< Dynamic or Static target Address */ + uint8_t CCC; /*!< CCC value code */ + I3C_DataTypeDef CCCBuf; /*!< Contain size of associated data and size of defining byte if any. + Contain pointer to CCC associated data */ + uint32_t Direction; /*!< CCC read and/or write direction message */ + +} I3C_CCCTypeDef; +/** + * @} + */ + +/** @defgroup I3C_PrivateTypeDef_Structure_definition I3C PrivateTypeDef Structure definition + * @brief I3C PrivateTypeDef Structure definition + * @{ + */ +typedef struct +{ + uint8_t TargetAddr; /*!< Dynamic or Static target Address */ + I3C_DataTypeDef TxBuf; /*!< Buffer structure containing the data to transmit (little endian) */ + I3C_DataTypeDef RxBuf; /*!< Buffer structure containing the data to receive (little endian) */ + uint32_t Direction; /*!< Read and/or write message */ + +} I3C_PrivateTypeDef; +/** + * @} + */ + +/** @defgroup I3C_XferTypeDef_Structure_definition I3C XferTypeDef Structure definition + * @brief I3C XferTypeDef Structure definition + * @{ + */ +typedef struct +{ + I3C_ControlTypeDef CtrlBuf; /*!< Buffer structure containing the control register values */ + I3C_ControlTypeDef StatusBuf; /*!< Buffer structure containing the status register values */ + I3C_DataTypeDef TxBuf; /*!< Buffer structure containing the data to transmit */ + I3C_DataTypeDef RxBuf; /*!< Buffer structure containing the data to receive */ + +} I3C_XferTypeDef; +/** + * @} + */ + +/** @defgroup I3C_handle_Structure_definition I3C handle Structure definition + * @brief I3C handle Structure definition + * @{ + */ +typedef struct __I3C_HandleTypeDef +{ + I3C_TypeDef *Instance; /*!< I3C registers base address */ + + I3C_InitTypeDef Init; /*!< I3C communication parameters */ + + HAL_I3C_ModeTypeDef Mode; /*!< I3C communication mode. + This parameter must be a value of + @ref I3C_mode_structure_definition */ + + I3C_XferTypeDef *pXferData; /*!< I3C transfer buffers pointer */ + + const I3C_CCCTypeDef *pCCCDesc; /*!< I3C CCC descriptor pointer */ + + const I3C_PrivateTypeDef *pPrivateDesc; /*!< I3C private transfer descriptor pointer */ + + uint32_t ControlXferCount; /*!< I3C counter indicating the remaining + control data bytes to write in + the control register */ + + uint32_t RxXferCount; /*!< I3C counter indicating the remaining + data bytes to receive */ + + uint32_t TxXferCount; /*!< I3C counter indicating the remaining + data bytes to transmit */ + +#if defined(HAL_DMA_MODULE_ENABLED) + DMA_HandleTypeDef *hdmacr; /*!< I3C control DMA handle parameters */ + + DMA_HandleTypeDef *hdmatx; /*!< I3C Tx DMA handle parameters */ + + DMA_HandleTypeDef *hdmarx; /*!< I3C Rx DMA handle parameters */ + + DMA_HandleTypeDef *hdmasr; /*!< I3C status DMA handle parameters */ +#endif /* HAL_DMA_MODULE_ENABLED */ + + HAL_LockTypeDef Lock; /*!< I3C locking object */ + + __IO HAL_I3C_StateTypeDef State; /*!< I3C communication state */ + + __IO HAL_I3C_StateTypeDef PreviousState; /*!< I3C communication previous state */ + + __IO uint32_t ErrorCode; /*!< I3C Error code */ + + HAL_StatusTypeDef(*XferISR)(struct __I3C_HandleTypeDef *hi3c, + uint32_t itFlags, + uint32_t itSources); /*!< I3C transfer IRQ handler function pointer */ + + void(*ptrTxFunc)(struct __I3C_HandleTypeDef *hi3c); /*!< I3C transmit function pointer */ + + void(*ptrRxFunc)(struct __I3C_HandleTypeDef *hi3c); /*!< I3C receive function pointer */ + +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + + void (* CtrlTxCpltCallback)(struct __I3C_HandleTypeDef *hi3c); + /*!< I3C Controller private data and CCC Tx Transfer complete callback */ + + void (* CtrlRxCpltCallback)(struct __I3C_HandleTypeDef *hi3c); + /*!< I3C Controller private data and CCC Rx Transfer completed callback */ + + void (* CtrlMultipleXferCpltCallback)(struct __I3C_HandleTypeDef *hi3c); + /*!< I3C Controller multiple Direct CCC, I3C private or I2C Transfer completed callback */ + + void (* CtrlDAACpltCallback)(struct __I3C_HandleTypeDef *hi3c); + /*!< I3C Controller Dynamic Address Assignment completed callback */ + + void (* TgtReqDynamicAddrCallback)(struct __I3C_HandleTypeDef *hi3c, uint64_t targetPayload); + /*!< I3C Controller request dynamic address callback during Dynamic Address Assignment processus */ + + void (* TgtTxCpltCallback)(struct __I3C_HandleTypeDef *hi3c); + /*!< I3C Target private data Tx Transfer completed callback */ + + void (* TgtRxCpltCallback)(struct __I3C_HandleTypeDef *hi3c); + /*!< I3C Target private data Rx Transfer completed callback */ + + void (* TgtHotJoinCallback)(struct __I3C_HandleTypeDef *hi3c, uint8_t dynamicAddress); + /*!< I3C Target Hot-Join callback */ + + void (* NotifyCallback)(struct __I3C_HandleTypeDef *hi3c, uint32_t eventId); + /*!< I3C Target or Controller asynchronous events callback */ + + void (* ErrorCallback)(struct __I3C_HandleTypeDef *hi3c); + /*!< I3C Error callback */ + + void (* AbortCpltCallback)(struct __I3C_HandleTypeDef *hi3c); + /*!< I3C Abort complete callback */ + + void (* MspInitCallback)(struct __I3C_HandleTypeDef *hi3c); + /*!< I3C Msp Init callback */ + + void (* MspDeInitCallback)(struct __I3C_HandleTypeDef *hi3c); + /*!< I3C Msp DeInit callback */ + +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + +} I3C_HandleTypeDef; +/** + * @} + */ + +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) +/** @defgroup HAL_I3C_Callback_ID_definition I3C callback ID definition + * @brief HAL I3C callback ID definition + * @{ + */ +typedef enum +{ + /*!< I3C Controller Tx Transfer completed callback ID */ + HAL_I3C_CTRL_TX_COMPLETE_CB_ID = 0x00U, + /*!< I3C Controller Rx Transfer completed callback ID */ + HAL_I3C_CTRL_RX_COMPLETE_CB_ID = 0x01U, + /*!< I3C Controller Multiple Transfer completed callback ID */ + HAL_I3C_CTRL_MULTIPLE_XFER_COMPLETE_CB_ID = 0x02U, + /*!< I3C Controller Dynamic Address Assignment completed callback ID */ + HAL_I3C_CTRL_DAA_COMPLETE_CB_ID = 0x03U, + /*!< I3C Controller request dynamic address completed callback ID */ + HAL_I3C_TGT_REQ_DYNAMIC_ADDR_CB_ID = 0x04U, + /*!< I3C Target Tx Transfer completed callback ID */ + HAL_I3C_TGT_TX_COMPLETE_CB_ID = 0x05U, + /*!< I3C Target Rx Transfer completed callback ID */ + HAL_I3C_TGT_RX_COMPLETE_CB_ID = 0x06U, + /*!< I3C Target Hot-join notification callback ID */ + HAL_I3C_TGT_HOTJOIN_CB_ID = 0x07U, + /*!< I3C Target or Controller receive notification callback ID */ + HAL_I3C_NOTIFY_CB_ID = 0x08U, + /*!< I3C Error callback ID */ + HAL_I3C_ERROR_CB_ID = 0x09U, + /*!< I3C Abort callback ID */ + HAL_I3C_ABORT_CB_ID = 0x0AU, + /*!< I3C Msp Init callback ID */ + HAL_I3C_MSPINIT_CB_ID = 0x0BU, + /*!< I3C Msp DeInit callback ID */ + HAL_I3C_MSPDEINIT_CB_ID = 0x0CU + +} HAL_I3C_CallbackIDTypeDef; +/** + * @} + */ + +/** @defgroup HAL_I3C_Callback_Pointer_definition I3C callback Pointer definition + * @brief HAL I3C callback pointer definition + * @{ + */ +typedef void (*pI3C_CallbackTypeDef)(I3C_HandleTypeDef *hi3c); +typedef void (*pI3C_NotifyCallbackTypeDef)(I3C_HandleTypeDef *hi3c, uint32_t notifyId); +typedef void (*pI3C_TgtHotJoinCallbackTypeDef)(I3C_HandleTypeDef *hi3c, uint8_t dynamicAddress); +typedef void (*pI3C_TgtReqDynamicAddrCallbackTypeDef)(I3C_HandleTypeDef *hi3c, uint64_t targetPayload); +/** + * @} + */ +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + +/** + * @} + */ + +/* Exported constants ------------------------------------------------------------------------------------------------*/ +/** @defgroup I3C_Exported_Constants I3C Exported Constants + * @{ + */ + +/** @defgroup HAL_I3C_Notification_ID_definition I3C Notification ID definition + * @brief HAL I3C Notification ID definition + * @{ + */ + +#define EVENT_ID_GETACCCR (0x00000001U) +/*!< I3C target complete controller-role hand-off (direct GETACCR CCC) event */ +#define EVENT_ID_IBIEND (0x00000002U) +/*!< I3C target IBI end process event */ +#define EVENT_ID_DAU (0x00000004U) +/*!< I3C target receive a dynamic address update (ENTDAA/RSTDAA/SETNEWDA CCC) event */ +#define EVENT_ID_GETx (0x00000008U) +/*!< I3C target receive any direct GETxxx CCC event */ +#define EVENT_ID_GETSTATUS (0x00000010U) +/*!< I3C target receive get status command (direct GETSTATUS CCC) event */ +#define EVENT_ID_SETMWL (0x00000020U) +/*!< I3C target receive maximum write length update (direct SETMWL CCC) event */ +#define EVENT_ID_SETMRL (0x00000040U) +/*!< I3C target receive maximum read length update(direct SETMRL CCC) event */ +#define EVENT_ID_RSTACT (0x00000080U) +/*!< I3C target detect reset pattern (broadcast or direct RSTACT CCC) event */ +#define EVENT_ID_ENTASx (0x00000100U) +/*!< I3C target receive activity state update (direct or broadcast ENTASx) event */ +#define EVENT_ID_ENEC_DISEC (0x00000200U) +/*!< I3C target receive a direct or broadcast ENEC/DISEC CCC event */ +#define EVENT_ID_DEFTGTS (0x00000400U) +/*!< I3C target receive a broadcast DEFTGTS CCC event */ +#define EVENT_ID_DEFGRPA (0x00000800U) +/*!< I3C target receive a group addressing (broadcast DEFGRPA CCC) event */ +#define EVENT_ID_WKP (0x00001000U) +/*!< I3C target wakeup event */ +#define EVENT_ID_IBI (0x00002000U) +/*!< I3C controller receive IBI event */ +#define EVENT_ID_CR (0x00004000U) +/*!< I3C controller controller-role request event */ +#define EVENT_ID_HJ (0x00008000U) +/*!< I3C controller hot-join event */ +/** + * @} + */ + +/** @defgroup I3C_OPTION_DEFINITION OPTION DEFINITION + * @note HAL I3C option value coding follow below described bitmap: + * b31 + * 0 : message end type restart + * 1 : message end type stop + * b30-b29-b28-b27 + * 0010 : I3C private message + * 0011 : direct CCC message + * 0110 : broadcast CCC message + * 0100 : I2C private message + * b4 + * 0 : message without arbitration header + * 1 : message with arbitration header + * b0 + * 0 : message without defining byte + * 1 : message with defining byte + * + * other bits (not used) + * @{ + */ +#define I3C_DIRECT_WITH_DEFBYTE_RESTART (0x18000001U) /*!< Restart between each Direct Command then Stop + request for last command. + Each Command have an associated defining byte */ +#define I3C_DIRECT_WITH_DEFBYTE_STOP (0x98000001U) /*!< Stop between each Direct Command. + Each Command have an associated defining byte */ +#define I3C_DIRECT_WITHOUT_DEFBYTE_RESTART (0x18000000U) /*!< Restart between each Direct Command then Stop + request for last command. + Each Command have not an associated defining byte */ +#define I3C_DIRECT_WITHOUT_DEFBYTE_STOP (0x98000000U) /*!< Stop between each Direct Command. + Each Command have not an associated defining byte */ +#define I3C_BROADCAST_WITH_DEFBYTE_RESTART (0x30000001U) /*!< Restart between each Broadcast Command then Stop + request for last command. + Each Command have an associated defining byte */ +#define I3C_BROADCAST_WITH_DEFBYTE_STOP (0xB0000001U) /*!< Stop between each Broadcast Command. + Each Command have an associated defining byte */ +#define I3C_BROADCAST_WITHOUT_DEFBYTE_RESTART (0x30000000U) /*!< Restart between each Broadcast Command then Stop + request for last command. + Each Command have not an associated defining byte */ +#define I3C_BROADCAST_WITHOUT_DEFBYTE_STOP (0xB0000000U) /*!< Stop between each Broadcast Command. + Each Command have not an associated defining byte */ +#define I3C_PRIVATE_WITH_ARB_RESTART (0x10000000U) /*!< Restart between each I3C Private message then Stop + request for last message. + Each Message start with an arbitration header after + start bit condition */ +#define I3C_PRIVATE_WITH_ARB_STOP (0x90000000U) /*!< Stop between each I3C Private message. + Each Message start with an arbitration header after + start bit condition */ +#define I3C_PRIVATE_WITHOUT_ARB_RESTART (0x10000004U) /*!< Restart between each I3C message then Stop request + for last message. + Each Message start with Target address after start + bit condition */ +#define I3C_PRIVATE_WITHOUT_ARB_STOP (0x90000004U) /*!< Stop between each I3C Private message. + Each Message start with Target address after + start bit condition */ +#define I2C_PRIVATE_WITH_ARB_RESTART (0x20000000U) /*!< Restart between each I2C Private message then Stop + request for last message. + Each Message start with an arbitration header after + start bit condition */ +#define I2C_PRIVATE_WITH_ARB_STOP (0xA0000000U) /*!< Stop between each I2C Private message. + Each Message start with an arbitration header after + start bit condition */ +#define I2C_PRIVATE_WITHOUT_ARB_RESTART (0x20000004U) /*!< Restart between each I2C message then Stop request + for last message. + Each Message start with Target address after start + bit condition */ +#define I2C_PRIVATE_WITHOUT_ARB_STOP (0xA0000004U) /*!< Stop between each I2C Private message. + Each Message start with Target address after start + bit condition */ +/** + * @} + */ + +/** @defgroup I3C_DYNAMIC_ADDRESS_OPTION_DEFINITION I3C DYNAMIC ADDRESS OPTION DEFINITION + * @{ + */ +#define I3C_RSTDAA_THEN_ENTDAA (0x00000001U) /*!< Initiate a RSTDAA before a ENTDAA procedure */ +#define I3C_ONLY_ENTDAA (0x00000002U) /*!< Initiate a ENTDAA without RSTDAA */ +/** + * @} + */ + +/** @defgroup I3C_ERROR_CODE_DEFINITION ERROR CODE DEFINITION + * @{ + */ +#define HAL_I3C_ERROR_NONE (0x00000000U) /*!< No error */ + +#define HAL_I3C_ERROR_CE0 (I3C_SER_PERR | LL_I3C_CONTROLLER_ERROR_CE0) /*!< Controller detected an illegally + formatted CCC */ +#define HAL_I3C_ERROR_CE1 (I3C_SER_PERR | LL_I3C_CONTROLLER_ERROR_CE1) /*!< Controller detected that transmitted data + on the bus is different than expected */ +#define HAL_I3C_ERROR_CE2 (I3C_SER_PERR | LL_I3C_CONTROLLER_ERROR_CE2) /*!< Controller detected that broadcast address + 7'h7E has been nacked */ +#define HAL_I3C_ERROR_CE3 (I3C_SER_PERR | LL_I3C_CONTROLLER_ERROR_CE3) /*!< Controller detected that new Controller + did not drive the bus after + Controller-role handoff */ +#define HAL_I3C_ERROR_TE0 (I3C_SER_PERR | LL_I3C_TARGET_ERROR_TE0) /*!< Target detected an invalid broadcast + address */ +#define HAL_I3C_ERROR_TE1 (I3C_SER_PERR | LL_I3C_TARGET_ERROR_TE1) /*!< Target detected an invalid CCC Code */ +#define HAL_I3C_ERROR_TE2 (I3C_SER_PERR | LL_I3C_TARGET_ERROR_TE2) /*!< Target detected a parity error during + a write data */ +#define HAL_I3C_ERROR_TE3 (I3C_SER_PERR | LL_I3C_TARGET_ERROR_TE3) /*!< Target detected a parity error on assigned + address during dynamic address + arbitration */ +#define HAL_I3C_ERROR_TE4 (I3C_SER_PERR | LL_I3C_TARGET_ERROR_TE4) /*!< Target detected 7'h7E missing after Restart + during Dynamic Address Assignment + procedure */ +#define HAL_I3C_ERROR_TE5 (I3C_SER_PERR | LL_I3C_TARGET_ERROR_TE5) /*!< Target detected an illegally + formatted CCC */ +#define HAL_I3C_ERROR_TE6 (I3C_SER_PERR | LL_I3C_TARGET_ERROR_TE6) /*!< Target detected that transmitted data on + the bus is different than expected */ +#define HAL_I3C_ERROR_DATA_HAND_OFF (I3C_SER_DERR) /*!< I3C data error during controller-role hand-off process */ +#define HAL_I3C_ERROR_DATA_NACK (I3C_SER_DNACK) /*!< I3C data not acknowledged error */ +#define HAL_I3C_ERROR_ADDRESS_NACK (I3C_SER_ANACK) /*!< I3C address not acknowledged error */ +#define HAL_I3C_ERROR_COVR (I3C_SER_COVR) /*!< I3C S FIFO Over-Run or C FIFO Under-Run error */ +#define HAL_I3C_ERROR_DOVR (I3C_SER_DOVR) /*!< I3C Rx FIFO Over-Run or Tx FIFO Under-Run error */ +#define HAL_I3C_ERROR_STALL (I3C_SER_STALL) /*!< I3C SCL stall error */ +#define HAL_I3C_ERROR_DMA (0x00010000U) /*!< DMA transfer error */ +#define HAL_I3C_ERROR_TIMEOUT (0x00020000U) /*!< Timeout error */ +#define HAL_I3C_ERROR_DMA_PARAM (0x00040000U) /*!< DMA Parameter Error */ +#define HAL_I3C_ERROR_INVALID_PARAM (0x00080000U) /*!< Invalid Parameters error */ +#define HAL_I3C_ERROR_SIZE (0x00100000U) /*!< I3C size management error */ +#define HAL_I3C_ERROR_NOT_ALLOWED (0x00200000U) /*!< I3C operation is not allowed */ +#define HAL_I3C_ERROR_DYNAMIC_ADDR (0x00400000U) /*!< I3C dynamic address error */ + +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) +#define HAL_I3C_ERROR_INVALID_CALLBACK (0x00800000U) /*!< Invalid Callback error */ +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ +/** + * @} + */ + +/** @defgroup I3C_SDA_HOLD_TIME SDA HOLD TIME + * @{ + */ +#define HAL_I3C_SDA_HOLD_TIME_0_5 LL_I3C_SDA_HOLD_TIME_0_5 /*!< SDA hold time equal to 0.5 x ti3cclk */ +#define HAL_I3C_SDA_HOLD_TIME_1_5 LL_I3C_SDA_HOLD_TIME_1_5 /*!< SDA hold time equal to 1.5 x ti3cclk */ +/** + * @} + */ + +/** @defgroup I3C_OWN_ACTIVITY_STATE OWN ACTIVITY STATE + * @{ + */ +#define HAL_I3C_OWN_ACTIVITY_STATE_0 LL_I3C_OWN_ACTIVITY_STATE_0 /*!< Own Controller Activity state 0 */ +#define HAL_I3C_OWN_ACTIVITY_STATE_1 LL_I3C_OWN_ACTIVITY_STATE_1 /*!< Own Controller Activity state 1 */ +#define HAL_I3C_OWN_ACTIVITY_STATE_2 LL_I3C_OWN_ACTIVITY_STATE_2 /*!< Own Controller Activity state 2 */ +#define HAL_I3C_OWN_ACTIVITY_STATE_3 LL_I3C_OWN_ACTIVITY_STATE_3 /*!< Own Controller Activity state 3 */ +/** + * @} + */ + +/** @defgroup I3C_RX_FIFO_THRESHOLD RX FIFO THRESHOLD + * @{ + */ +#define HAL_I3C_RXFIFO_THRESHOLD_1_4 LL_I3C_RXFIFO_THRESHOLD_1_4 /*!< Rx Fifo Threshold is 1 byte */ +#define HAL_I3C_RXFIFO_THRESHOLD_4_4 LL_I3C_RXFIFO_THRESHOLD_4_4 /*!< Rx Fifo Threshold is 4 bytes */ +/** + * @} + */ + +/** @defgroup I3C_TX_FIFO_THRESHOLD TX FIFO THRESHOLD + * @{ + */ +#define HAL_I3C_TXFIFO_THRESHOLD_1_4 LL_I3C_TXFIFO_THRESHOLD_1_4 /*!< Tx Fifo Threshold is 1 byte */ +#define HAL_I3C_TXFIFO_THRESHOLD_4_4 LL_I3C_TXFIFO_THRESHOLD_4_4 /*!< Tx Fifo Threshold is 4 bytes */ +/** + * @} + */ + +/** @defgroup I3C_CONTROL_FIFO_STATE CONTROL FIFO STATE + * @{ + */ +#define HAL_I3C_CONTROLFIFO_DISABLE 0x00000000U /*!< Control FIFO mode disable */ +#define HAL_I3C_CONTROLFIFO_ENABLE I3C_CFGR_TMODE /*!< Control FIFO mode enable */ +/** + * @} + */ + +/** @defgroup I3C_STATUS_FIFO_STATE STATUS FIFO STATE + * @{ + */ +#define HAL_I3C_STATUSFIFO_DISABLE 0x00000000U /*!< Status FIFO mode disable */ +#define HAL_I3C_STATUSFIFO_ENABLE I3C_CFGR_SMODE /*!< Status FIFO mode enable */ +/** + * @} + */ + +/** @defgroup I3C_DIRECTION DIRECTION + * @{ + */ +#define HAL_I3C_DIRECTION_WRITE LL_I3C_DIRECTION_WRITE /*!< Write transfer */ +#define HAL_I3C_DIRECTION_READ LL_I3C_DIRECTION_READ /*!< Read transfer */ +#define HAL_I3C_DIRECTION_BOTH (LL_I3C_DIRECTION_READ | 1U) /*!< Read and Write transfer */ +/** + * @} + */ + +/** @defgroup I3C_PAYLOAD_SIZE PAYLOAD SIZE + * @{ + */ +#define HAL_I3C_PAYLOAD_EMPTY LL_I3C_PAYLOAD_EMPTY /*!< Empty payload, no additional data after IBI acknowledge */ +#define HAL_I3C_PAYLOAD_1_BYTE LL_I3C_PAYLOAD_1_BYTE /*!< One additional data byte after IBI acknowledge */ +#define HAL_I3C_PAYLOAD_2_BYTES LL_I3C_PAYLOAD_2_BYTES /*!< Two additional data bytes after IBI acknowledge */ +#define HAL_I3C_PAYLOAD_3_BYTES LL_I3C_PAYLOAD_3_BYTES /*!< Three additional data bytes after IBI acknowledge */ +#define HAL_I3C_PAYLOAD_4_BYTES LL_I3C_PAYLOAD_4_BYTES /*!< Four additional data bytes after IBI acknowledge */ +/** + * @} + */ + +/** @defgroup I3C_HANDOFF_ACTIVITY_STATE HANDOFF ACTIVITY STATE + * @{ + */ +#define HAL_I3C_HANDOFF_ACTIVITY_STATE_0 LL_I3C_HANDOFF_ACTIVITY_STATE_0 /*!< Activity state 0 after handoff */ +#define HAL_I3C_HANDOFF_ACTIVITY_STATE_1 LL_I3C_HANDOFF_ACTIVITY_STATE_1 /*!< Activity state 1 after handoff */ +#define HAL_I3C_HANDOFF_ACTIVITY_STATE_2 LL_I3C_HANDOFF_ACTIVITY_STATE_2 /*!< Activity state 2 after handoff */ +#define HAL_I3C_HANDOFF_ACTIVITY_STATE_3 LL_I3C_HANDOFF_ACTIVITY_STATE_3 /*!< Activity state 3 after handoff */ +/** + * @} + */ + +/** @defgroup I3C_GETMXDS_FORMAT GETMXDS FORMAT + * @{ + */ +#define HAL_I3C_GETMXDS_FORMAT_1 LL_I3C_GETMXDS_FORMAT_1 /*!< GETMXDS CCC Format 1 is used, no MaxRdTurn + field in response */ +#define HAL_I3C_GETMXDS_FORMAT_2_LSB LL_I3C_GETMXDS_FORMAT_2_LSB /*!< GETMXDS CCC Format 2 is used, MaxRdTurn field + in response, LSB = RDTURN[7:0] */ +#define HAL_I3C_GETMXDS_FORMAT_2_MID LL_I3C_GETMXDS_FORMAT_2_MID /*!< GETMXDS CCC Format 2 is used, MaxRdTurn field + in response, Middle byte = RDTURN[7:0] */ +#define HAL_I3C_GETMXDS_FORMAT_2_MSB LL_I3C_GETMXDS_FORMAT_2_MSB /*!< GETMXDS CCC Format 2 is used, MaxRdTurn field + in response, MSB = RDTURN[7:0] */ +/** + * @} + */ + +/** @defgroup I3C_TURNAROUND_TIME_TSCO TURNAROUND TIME TSCO + * @{ + */ +#define HAL_I3C_TURNAROUND_TIME_TSCO_LESS_12NS LL_I3C_TURNAROUND_TIME_TSCO_LESS_12NS +/*!< clock-to-data turnaround time tSCO <= 12ns */ +#define HAL_I3C_TURNAROUND_TIME_TSCO_GREATER_12NS LL_I3C_TURNAROUND_TIME_TSCO_GREATER_12NS +/*!< clock-to-data turnaround time tSCO > 12ns */ +/** + * @} + */ + +/** @defgroup I3C_COMMON_INTERRUPT I3C COMMON INTERRUPT + * @{ + */ +#define HAL_I3C_IT_TXFNFIE LL_I3C_IER_TXFNFIE /*!< Tx FIFO not full interrupt enable */ +#define HAL_I3C_IT_RXFNEIE LL_I3C_IER_RXFNEIE /*!< Rx FIFO not empty interrupt enable */ +#define HAL_I3C_IT_FCIE LL_I3C_IER_FCIE /*!< Frame complete interrupt enable */ +#define HAL_I3C_IT_ERRIE LL_I3C_IER_ERRIE /*!< Error interrupt enable */ +#define HAL_I3C_ALL_COMMON_ITS (uint32_t)(LL_I3C_IER_TXFNFIE | LL_I3C_IER_RXFNEIE | \ + LL_I3C_IER_FCIE | LL_I3C_IER_ERRIE) +/** + * @} + */ + +/** @defgroup I3C_TARGET_INTERRUPT I3C TARGET INTERRUPT + * @{ + */ +#define HAL_I3C_IT_IBIENDIE LL_I3C_IER_IBIENDIE /*!< IBI end interrupt enable */ +#define HAL_I3C_IT_CRUPDIE LL_I3C_IER_CRUPDIE /*!< controller-role update interrupt enable */ +#define HAL_I3C_IT_WKPIE LL_I3C_IER_WKPIE /*!< wakeup interrupt enable */ +#define HAL_I3C_IT_GETIE LL_I3C_IER_GETIE /*!< GETxxx CCC interrupt enable */ +#define HAL_I3C_IT_STAIE LL_I3C_IER_STAIE /*!< GETSTATUS CCC interrupt enable */ +#define HAL_I3C_IT_DAUPDIE LL_I3C_IER_DAUPDIE /*!< ENTDAA/RSTDAA/SETNEWDA CCC interrupt enable */ +#define HAL_I3C_IT_MWLUPDIE LL_I3C_IER_MWLUPDIE /*!< SETMWL CCC interrupt enable */ +#define HAL_I3C_IT_MRLUPDIE LL_I3C_IER_MRLUPDIE /*!< SETMRL CCC interrupt enable */ +#define HAL_I3C_IT_RSTIE LL_I3C_IER_RSTIE /*!< reset pattern interrupt enable */ +#define HAL_I3C_IT_ASUPDIE LL_I3C_IER_ASUPDIE /*!< ENTASx CCC interrupt enable */ +#define HAL_I3C_IT_INTUPDIE LL_I3C_IER_INTUPDIE /*!< ENEC/DISEC CCC interrupt enable */ +#define HAL_I3C_IT_DEFIE (LL_I3C_IER_DEFIE | LL_I3C_IER_RXFNEIE) +/*!< DEFTGTS CCC interrupt enable */ +#define HAL_I3C_IT_GRPIE (LL_I3C_IER_GRPIE | LL_I3C_IER_RXFNEIE) +/*!< DEFGRPA CCC interrupt enable */ +#define HAL_I3C_ALL_TGT_ITS (uint32_t)(LL_I3C_IER_IBIENDIE | LL_I3C_IER_CRUPDIE | LL_I3C_IER_WKPIE | \ + LL_I3C_IER_GETIE | LL_I3C_IER_STAIE | LL_I3C_IER_DAUPDIE | \ + LL_I3C_IER_MWLUPDIE | LL_I3C_IER_MRLUPDIE | LL_I3C_IER_RSTIE | \ + LL_I3C_IER_ASUPDIE | LL_I3C_IER_INTUPDIE | LL_I3C_IER_DEFIE | \ + LL_I3C_IER_GRPIE) +/** + * @} + */ + +/** @defgroup I3C_CONTROLLER_INTERRUPT I3C CONTROLLER INTERRUPT + * @{ + */ +#define HAL_I3C_IT_CFNFIE LL_I3C_IER_CFNFIE /*!< Control FIFO not full interrupt enable */ +#define HAL_I3C_IT_SFNEIE LL_I3C_IER_SFNEIE /*!< Status FIFO not empty interrupt enable */ +#define HAL_I3C_IT_HJIE LL_I3C_IER_HJIE /*!< Hot-join interrupt enable */ +#define HAL_I3C_IT_CRIE LL_I3C_IER_CRIE /*!< Controller-role request interrupt enable */ +#define HAL_I3C_IT_IBIIE LL_I3C_IER_IBIIE /*!< IBI request interrupt enable */ +#define HAL_I3C_IT_RXTGTENDIE LL_I3C_IER_RXTGTENDIE /*!< Target-initiated read end interrupt enable */ +#define HAL_I3C_ALL_CTRL_ITS (uint32_t)(LL_I3C_IER_CFNFIE | LL_I3C_IER_SFNEIE | LL_I3C_IER_HJIE | \ + LL_I3C_IER_CRIE | LL_I3C_IER_IBIIE | LL_I3C_IER_RXTGTENDIE) +/** + * @} + */ + +/** @defgroup I3C_FLAGS I3C FLAGS + * @{ + */ +#define HAL_I3C_FLAG_CFEF LL_I3C_EVR_CFEF /*!< Control FIFO not empty flag */ +#define HAL_I3C_FLAG_TXFEF LL_I3C_EVR_TXFEF /*!< Tx FIFO empty flag */ +#define HAL_I3C_FLAG_CFNFF LL_I3C_EVR_CFNFF /*!< Control FIFO not full flag */ +#define HAL_I3C_FLAG_SFNEF LL_I3C_EVR_SFNEF /*!< Status FIFO not empty flag */ +#define HAL_I3C_FLAG_TXFNFF LL_I3C_EVR_TXFNFF /*!< Tx FIFO not full flag */ +#define HAL_I3C_FLAG_RXFNEF LL_I3C_EVR_RXFNEF /*!< Rx FIFO not empty flag */ +#define HAL_I3C_FLAG_RXLASTF LL_I3C_EVR_RXLASTF /*!< Last read data byte/word flag */ +#define HAL_I3C_FLAG_TXLASTF LL_I3C_EVR_TXLASTF /*!< Last written data byte/word flag */ +#define HAL_I3C_FLAG_FCF LL_I3C_EVR_FCF /*!< Frame complete flag */ +#define HAL_I3C_FLAG_RXTGTENDF LL_I3C_EVR_RXTGTENDF /*!< Target-initiated read end flag */ +#define HAL_I3C_FLAG_ERRF LL_I3C_EVR_ERRF /*!< Error flag */ +#define HAL_I3C_FLAG_IBIF LL_I3C_EVR_IBIF /*!< IBI request flag */ +#define HAL_I3C_FLAG_IBIENDF LL_I3C_EVR_IBIENDF /*!< IBI end flag */ +#define HAL_I3C_FLAG_CRF LL_I3C_EVR_CRF /*!< Controller-role request flag */ +#define HAL_I3C_FLAG_CRUPDF LL_I3C_EVR_CRUPDF /*!< Controller-role update flag */ +#define HAL_I3C_FLAG_HJF LL_I3C_EVR_HJF /*!< Hot-join flag */ +#define HAL_I3C_FLAG_WKPF LL_I3C_EVR_WKPF /*!< Wakeup flag */ +#define HAL_I3C_FLAG_GETF LL_I3C_EVR_GETF /*!< GETxxx CCC flag */ +#define HAL_I3C_FLAG_STAF LL_I3C_EVR_STAF /*!< Format 1 GETSTATUS CCC flag */ +#define HAL_I3C_FLAG_DAUPDF LL_I3C_EVR_DAUPDF /*!< ENTDAA/RSTDAA/SETNEWDA CCC flag */ +#define HAL_I3C_FLAG_MWLUPDF LL_I3C_EVR_MWLUPDF /*!< SETMWL CCC flag */ +#define HAL_I3C_FLAG_MRLUPDF LL_I3C_EVR_MRLUPDF /*!< SETMRL CCC flag */ +#define HAL_I3C_FLAG_RSTF LL_I3C_EVR_RSTF /*!< Reset pattern flag */ +#define HAL_I3C_FLAG_ASUPDF LL_I3C_EVR_ASUPDF /*!< ENTASx CCC flag */ +#define HAL_I3C_FLAG_INTUPDF LL_I3C_EVR_INTUPDF /*!< ENEC/DISEC CCC flag */ +#define HAL_I3C_FLAG_DEFF LL_I3C_EVR_DEFF /*!< DEFTGTS CCC flag */ +#define HAL_I3C_FLAG_GRPF LL_I3C_EVR_GRPF /*!< DEFGRPA CCC flag */ +/** + * @} + */ + +/** @defgroup I3C_BCR_IN_PAYLOAD I3C BCR IN PAYLOAD + * @{ + */ +#define HAL_I3C_BCR_IN_PAYLOAD_SHIFT 48 /*!< BCR field in target payload */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros ---------------------------------------------------------------------------------------------------*/ +/** @defgroup I3C_Exported_Macros I3C Exported Macros + * @{ + */ + +/** @brief Reset I3C handle state. + * @param __HANDLE__ specifies the I3C Handle. + * @retval None + */ +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1) +#define __HAL_I3C_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->State = HAL_I3C_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_I3C_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_I3C_STATE_RESET) +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS */ + +/** @brief Enable the specified I3C interrupt. + * @param __HANDLE__ specifies the I3C Handle. + * @param __INTERRUPT__ specifies the interrupt source to enable. + * This parameter can be one value or a combination of the following group's values: + * @arg @ref I3C_CONTROLLER_INTERRUPT + * @arg @ref I3C_TARGET_INTERRUPT + * @arg @ref I3C_COMMON_INTERRUPT + * @retval None + */ +#define __HAL_I3C_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IER |= (__INTERRUPT__)) + +/** @brief Disable the specified I3C interrupt. + * @param __HANDLE__ specifies the I3C Handle. + * @param __INTERRUPT__ specifies the interrupt source to disable. + * This parameter can be one value or a combination of the following group's values: + * @arg @ref I3C_CONTROLLER_INTERRUPT + * @arg @ref I3C_TARGET_INTERRUPT + * @arg @ref I3C_COMMON_INTERRUPT + * @retval None + */ +#define __HAL_I3C_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IER &= (~(__INTERRUPT__))) + +/** @brief Check whether the specified I3C flag is set or not. + * @param __HANDLE__ specifies the I3C Handle. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one value of the group @arg @ref I3C_FLAGS values. + * @retval The new state of __FLAG__ (SET or RESET). + */ +#define __HAL_I3C_GET_FLAG(__HANDLE__, __FLAG__) (((((__HANDLE__)->Instance->EVR) &\ + (__FLAG__)) == (__FLAG__)) ? SET : RESET) + +/** @brief Get Bus Characterics in payload (64bits) receive during ENTDAA procedure. + * @param __PAYLOAD__ specifies the Bus Characteristics capabilities retrieve during ENTDAA procedure. + * This parameter must be a number between Min_Data=0x00(uint64_t) and Max_Data=0xFFFFFFFFFFFFFFFFFF. + * @retval The value of BCR Return value between Min_Data=0x00 and Max_Data=0xFF. + */ +#define __HAL_I3C_GET_BCR(__PAYLOAD__) (((uint32_t)((uint64_t)(__PAYLOAD__) >> HAL_I3C_BCR_IN_PAYLOAD_SHIFT)) & \ + I3C_BCR_BCR) + +/** @brief Check IBI request capabilities. + * @param __BCR__ specifies the Bus Characteristics capabilities retrieve during ENTDAA procedure. + * This parameter must be a number between Min_Data=0x00 and Max_Data=0xFF. + * @retval The state of IBI request capabilities (ENABLE or DISABLE). + */ +#define __HAL_I3C_GET_IBI_CAPABLE(__BCR__) (((((__BCR__) & I3C_BCR_BCR1_Msk) >> I3C_BCR_BCR1_Pos) == 1U) \ + ? ENABLE : DISABLE) + +/** @brief Check IBI additional data byte capabilities. + * @param __BCR__ specifies the Bus Characteristics capabilities retrieve during ENTDAA procedure. + * This parameter must be a number between Min_Data=0x00 and Max_Data=0xFF. + * @retval The state of IBI additional data byte capabilities (ENABLE or DISABLE). + */ +#define __HAL_I3C_GET_IBI_PAYLOAD(__BCR__) (((((__BCR__) & I3C_BCR_BCR2_Msk) >> I3C_BCR_BCR2_Pos) == 1U) \ + ? ENABLE : DISABLE) + +/** @brief Check Controller role request capabilities. + * @param __BCR__ specifies the Bus Characteristics capabilities retrieve during ENTDAA procedure. + * This parameter must be a number between Min_Data=0x00 and Max_Data=0xFF. + * @retval The state of Controller role request capabilities (ENABLE or DISABLE). + */ +#define __HAL_I3C_GET_CR_CAPABLE(__BCR__) (((((__BCR__) & I3C_BCR_BCR6_Msk) >> I3C_BCR_BCR6_Pos) == 1U) \ + ? ENABLE : DISABLE) + +/** + * @} + */ + +/* Exported functions ------------------------------------------------------------------------------------------------*/ +/** @addtogroup I3C_Exported_Functions + * @{ + */ + +/** @addtogroup I3C_Exported_Functions_Group1 Initialization and de-initialization functions. + * @{ + */ +HAL_StatusTypeDef HAL_I3C_Init(I3C_HandleTypeDef *hi3c); +HAL_StatusTypeDef HAL_I3C_DeInit(I3C_HandleTypeDef *hi3c); +void HAL_I3C_MspInit(I3C_HandleTypeDef *hi3c); +void HAL_I3C_MspDeInit(I3C_HandleTypeDef *hi3c); +/** + * @} + */ + +/** @addtogroup I3C_Exported_Functions_Group2 Interrupt and callback functions. + * @{ + */ +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) +HAL_StatusTypeDef HAL_I3C_RegisterCallback(I3C_HandleTypeDef *hi3c, + HAL_I3C_CallbackIDTypeDef callbackID, + pI3C_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_I3C_RegisterNotifyCallback(I3C_HandleTypeDef *hi3c, + pI3C_NotifyCallbackTypeDef pNotifyCallback); +HAL_StatusTypeDef HAL_I3C_RegisterTgtReqDynamicAddrCallback(I3C_HandleTypeDef *hi3c, + pI3C_TgtReqDynamicAddrCallbackTypeDef pTgtReqAddrCallback); +HAL_StatusTypeDef HAL_I3C_RegisterTgtHotJoinCallback(I3C_HandleTypeDef *hi3c, + pI3C_TgtHotJoinCallbackTypeDef pTgtHotJoinCallback); +HAL_StatusTypeDef HAL_I3C_UnRegisterCallback(I3C_HandleTypeDef *hi3c, HAL_I3C_CallbackIDTypeDef callbackID); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + +HAL_StatusTypeDef HAL_I3C_ActivateNotification(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData, + uint32_t interruptMask); +HAL_StatusTypeDef HAL_I3C_DeactivateNotification(I3C_HandleTypeDef *hi3c, uint32_t interruptMask); +void HAL_I3C_CtrlTxCpltCallback(I3C_HandleTypeDef *hi3c); +void HAL_I3C_CtrlRxCpltCallback(I3C_HandleTypeDef *hi3c); +void HAL_I3C_CtrlMultipleXferCpltCallback(I3C_HandleTypeDef *hi3c); +void HAL_I3C_CtrlDAACpltCallback(I3C_HandleTypeDef *hi3c); +void HAL_I3C_TgtReqDynamicAddrCallback(I3C_HandleTypeDef *hi3c, uint64_t targetPayload); +void HAL_I3C_TgtTxCpltCallback(I3C_HandleTypeDef *hi3c); +void HAL_I3C_TgtRxCpltCallback(I3C_HandleTypeDef *hi3c); +void HAL_I3C_TgtHotJoinCallback(I3C_HandleTypeDef *hi3c, uint8_t dynamicAddress); +void HAL_I3C_NotifyCallback(I3C_HandleTypeDef *hi3c, uint32_t eventId); +void HAL_I3C_AbortCpltCallback(I3C_HandleTypeDef *hi3c); +void HAL_I3C_ErrorCallback(I3C_HandleTypeDef *hi3c); +void HAL_I3C_ER_IRQHandler(I3C_HandleTypeDef *hi3c); +void HAL_I3C_EV_IRQHandler(I3C_HandleTypeDef *hi3c); +/** + * @} + */ + +/** @addtogroup I3C_Exported_Functions_Group3 Configuration functions. + * @{ + */ +HAL_StatusTypeDef HAL_I3C_Ctrl_BusCharacteristicConfig(I3C_HandleTypeDef *hi3c, + const LL_I3C_CtrlBusConfTypeDef *pConfig); +HAL_StatusTypeDef HAL_I3C_Tgt_BusCharacteristicConfig(I3C_HandleTypeDef *hi3c, + const LL_I3C_TgtBusConfTypeDef *pConfig); +HAL_StatusTypeDef HAL_I3C_SetConfigFifo(I3C_HandleTypeDef *hi3c, const I3C_FifoConfTypeDef *pConfig); +HAL_StatusTypeDef HAL_I3C_Ctrl_Config(I3C_HandleTypeDef *hi3c, const I3C_CtrlConfTypeDef *pConfig); +HAL_StatusTypeDef HAL_I3C_Tgt_Config(I3C_HandleTypeDef *hi3c, const I3C_TgtConfTypeDef *pConfig); +HAL_StatusTypeDef HAL_I3C_Ctrl_ConfigBusDevices(I3C_HandleTypeDef *hi3c, + const I3C_DeviceConfTypeDef *pDesc, + uint8_t nbDevice); +HAL_StatusTypeDef HAL_I3C_AddDescToFrame(I3C_HandleTypeDef *hi3c, + const I3C_CCCTypeDef *pCCCDesc, + const I3C_PrivateTypeDef *pPrivateDesc, + I3C_XferTypeDef *pXferData, + uint8_t nbFrame, + uint32_t option); +/** + * @} + */ + +/** @addtogroup I3C_Exported_Functions_Group4 FIFO Management functions. + * @{ + */ +HAL_StatusTypeDef HAL_I3C_FlushAllFifo(I3C_HandleTypeDef *hi3c); +HAL_StatusTypeDef HAL_I3C_FlushTxFifo(I3C_HandleTypeDef *hi3c); +HAL_StatusTypeDef HAL_I3C_FlushRxFifo(I3C_HandleTypeDef *hi3c); +HAL_StatusTypeDef HAL_I3C_FlushControlFifo(I3C_HandleTypeDef *hi3c); +HAL_StatusTypeDef HAL_I3C_FlushStatusFifo(I3C_HandleTypeDef *hi3c); +HAL_StatusTypeDef HAL_I3C_ClearConfigFifo(I3C_HandleTypeDef *hi3c); +HAL_StatusTypeDef HAL_I3C_GetConfigFifo(I3C_HandleTypeDef *hi3c, I3C_FifoConfTypeDef *pConfig); +/** + * @} + */ + +/** @addtogroup I3C_Exported_Functions_Group5 Controller operational functions. + * @{ + */ +/* Controller transmit direct write or a broadcast CCC command APIs */ +HAL_StatusTypeDef HAL_I3C_Ctrl_TransmitCCC(I3C_HandleTypeDef *hi3c, + I3C_XferTypeDef *pXferData, + uint32_t timeout); +HAL_StatusTypeDef HAL_I3C_Ctrl_TransmitCCC_IT(I3C_HandleTypeDef *hi3c, + I3C_XferTypeDef *pXferData); +HAL_StatusTypeDef HAL_I3C_Ctrl_TransmitCCC_DMA(I3C_HandleTypeDef *hi3c, + I3C_XferTypeDef *pXferData); + +/* Controller transmit direct read CCC command APIs */ +HAL_StatusTypeDef HAL_I3C_Ctrl_ReceiveCCC(I3C_HandleTypeDef *hi3c, + I3C_XferTypeDef *pXferData, + uint32_t timeout); +HAL_StatusTypeDef HAL_I3C_Ctrl_ReceiveCCC_IT(I3C_HandleTypeDef *hi3c, + I3C_XferTypeDef *pXferData); +HAL_StatusTypeDef HAL_I3C_Ctrl_ReceiveCCC_DMA(I3C_HandleTypeDef *hi3c, + I3C_XferTypeDef *pXferData); + +/* Controller private write APIs */ +HAL_StatusTypeDef HAL_I3C_Ctrl_Transmit(I3C_HandleTypeDef *hi3c, + I3C_XferTypeDef *pXferData, + uint32_t timeout); +HAL_StatusTypeDef HAL_I3C_Ctrl_Transmit_IT(I3C_HandleTypeDef *hi3c, + I3C_XferTypeDef *pXferData); +HAL_StatusTypeDef HAL_I3C_Ctrl_Transmit_DMA(I3C_HandleTypeDef *hi3c, + I3C_XferTypeDef *pXferData); + +/* Controller private read APIs */ +HAL_StatusTypeDef HAL_I3C_Ctrl_Receive(I3C_HandleTypeDef *hi3c, + I3C_XferTypeDef *pXferData, + uint32_t timeout); +HAL_StatusTypeDef HAL_I3C_Ctrl_Receive_IT(I3C_HandleTypeDef *hi3c, + I3C_XferTypeDef *pXferData); +HAL_StatusTypeDef HAL_I3C_Ctrl_Receive_DMA(I3C_HandleTypeDef *hi3c, + I3C_XferTypeDef *pXferData); + +/* Controller multiple Direct CCC Command, I3C private or I2C transfer APIs */ +HAL_StatusTypeDef HAL_I3C_Ctrl_MultipleTransfer_IT(I3C_HandleTypeDef *hi3c, + I3C_XferTypeDef *pXferData); +HAL_StatusTypeDef HAL_I3C_Ctrl_MultipleTransfer_DMA(I3C_HandleTypeDef *hi3c, + I3C_XferTypeDef *pXferData); + +/* Controller assign dynamic address APIs */ +HAL_StatusTypeDef HAL_I3C_Ctrl_SetDynAddr(I3C_HandleTypeDef *hi3c, uint8_t devAddress); +HAL_StatusTypeDef HAL_I3C_Ctrl_DynAddrAssign_IT(I3C_HandleTypeDef *hi3c, uint32_t dynOption); +HAL_StatusTypeDef HAL_I3C_Ctrl_DynAddrAssign(I3C_HandleTypeDef *hi3c, + uint64_t *target_payload, + uint32_t dynOption, + uint32_t timeout); +/* Controller check device ready APIs */ +HAL_StatusTypeDef HAL_I3C_Ctrl_IsDeviceI3C_Ready(I3C_HandleTypeDef *hi3c, + uint8_t devAddress, + uint32_t trials, + uint32_t timeout); +HAL_StatusTypeDef HAL_I3C_Ctrl_IsDeviceI2C_Ready(I3C_HandleTypeDef *hi3c, + uint8_t devAddress, + uint32_t trials, + uint32_t timeout); +/** + * @} + */ + +/** @addtogroup I3C_Exported_Functions_Group6 Target operational functions. + * @{ + */ +HAL_StatusTypeDef HAL_I3C_Tgt_Transmit(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData, uint32_t timeout); +HAL_StatusTypeDef HAL_I3C_Tgt_Transmit_IT(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData); +HAL_StatusTypeDef HAL_I3C_Tgt_Transmit_DMA(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData); +HAL_StatusTypeDef HAL_I3C_Tgt_Receive(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData, uint32_t timeout); +HAL_StatusTypeDef HAL_I3C_Tgt_Receive_IT(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData); +HAL_StatusTypeDef HAL_I3C_Tgt_Receive_DMA(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData); +HAL_StatusTypeDef HAL_I3C_Tgt_ControlRoleReq(I3C_HandleTypeDef *hi3c, uint32_t timeout); +HAL_StatusTypeDef HAL_I3C_Tgt_ControlRoleReq_IT(I3C_HandleTypeDef *hi3c); +HAL_StatusTypeDef HAL_I3C_Tgt_HotJoinReq(I3C_HandleTypeDef *hi3c, uint8_t *pAddress, uint32_t timeout); +HAL_StatusTypeDef HAL_I3C_Tgt_HotJoinReq_IT(I3C_HandleTypeDef *hi3c); +HAL_StatusTypeDef HAL_I3C_Tgt_IBIReq(I3C_HandleTypeDef *hi3c, const uint8_t *pPayload, + uint8_t payloadSize, uint32_t timeout); +HAL_StatusTypeDef HAL_I3C_Tgt_IBIReq_IT(I3C_HandleTypeDef *hi3c, const uint8_t *pPayload, uint8_t payloadSize); +/** + * @} + */ + +/** @addtogroup I3C_Exported_Functions_Group7 Generic and Common functions. + * @{ + */ +HAL_StatusTypeDef HAL_I3C_Abort_IT(I3C_HandleTypeDef *hi3c); +HAL_I3C_StateTypeDef HAL_I3C_GetState(const I3C_HandleTypeDef *hi3c); +HAL_I3C_ModeTypeDef HAL_I3C_GetMode(const I3C_HandleTypeDef *hi3c); +uint32_t HAL_I3C_GetError(const I3C_HandleTypeDef *hi3c); +HAL_StatusTypeDef HAL_I3C_GetCCCInfo(I3C_HandleTypeDef *hi3c, + uint32_t notifyId, + I3C_CCCInfoTypeDef *pCCCInfo); +/** + * @} + */ + +/** + * @} + */ + +/* Private constants -------------------------------------------------------------------------------------------------*/ +/** @defgroup I3C_Private_Constants I3C Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ----------------------------------------------------------------------------------------------------*/ +/** @defgroup I3C_Private_Macro I3C Private Macros + * @{ + */ +#define IS_I3C_MODE(__MODE__) (((__MODE__) == HAL_I3C_MODE_NONE) || \ + ((__MODE__) == HAL_I3C_MODE_CONTROLLER) || \ + ((__MODE__) == HAL_I3C_MODE_TARGET)) + +#define IS_I3C_INTERRUPTMASK(__MODE__, __ITMASK__) (((__MODE__) == HAL_I3C_MODE_CONTROLLER) ? \ + ((((__ITMASK__) & HAL_I3C_ALL_CTRL_ITS) != 0x0U) || \ + (((__ITMASK__) & HAL_I3C_ALL_COMMON_ITS) != 0x0U)) : \ + ((((__ITMASK__) & HAL_I3C_ALL_TGT_ITS) != 0x0U) || \ + (((__ITMASK__) & HAL_I3C_ALL_COMMON_ITS) != 0x0U))) + +#define IS_I3C_ENTDAA_OPTION(__OPTION__) (((__OPTION__) == I3C_RSTDAA_THEN_ENTDAA) || \ + ((__OPTION__) == I3C_ONLY_ENTDAA)) + +#define IS_I3C_SDAHOLDTIME_VALUE(__VALUE__) (((__VALUE__) == HAL_I3C_SDA_HOLD_TIME_0_5) || \ + ((__VALUE__) == HAL_I3C_SDA_HOLD_TIME_1_5)) + +#define IS_I3C_WAITTIME_VALUE(__VALUE__) (((__VALUE__) == HAL_I3C_OWN_ACTIVITY_STATE_0) || \ + ((__VALUE__) == HAL_I3C_OWN_ACTIVITY_STATE_1) || \ + ((__VALUE__) == HAL_I3C_OWN_ACTIVITY_STATE_2) || \ + ((__VALUE__) == HAL_I3C_OWN_ACTIVITY_STATE_3)) + +#define IS_I3C_TXFIFOTHRESHOLD_VALUE(__VALUE__) (((__VALUE__) == HAL_I3C_TXFIFO_THRESHOLD_1_4) || \ + ((__VALUE__) == HAL_I3C_TXFIFO_THRESHOLD_4_4)) + +#define IS_I3C_RXFIFOTHRESHOLD_VALUE(__VALUE__) (((__VALUE__) == HAL_I3C_RXFIFO_THRESHOLD_1_4) || \ + ((__VALUE__) == HAL_I3C_RXFIFO_THRESHOLD_4_4)) + +#define IS_I3C_CONTROLFIFOSTATE_VALUE(__VALUE__) (((__VALUE__) == HAL_I3C_CONTROLFIFO_DISABLE) || \ + ((__VALUE__) == HAL_I3C_CONTROLFIFO_ENABLE)) + +#define IS_I3C_STATUSFIFOSTATE_VALUE(__VALUE__) (((__VALUE__) == HAL_I3C_STATUSFIFO_DISABLE) || \ + ((__VALUE__) == HAL_I3C_STATUSFIFO_ENABLE)) + +#define IS_I3C_DEVICE_VALUE(__VALUE__) (((__VALUE__) >= 1U) && ((__VALUE__) <= 4U)) + +#define IS_I3C_DYNAMICADDRESS_VALUE(__VALUE__) ((__VALUE__) <= 0x7FU) + +#define IS_I3C_FUNCTIONALSTATE_VALUE(__VALUE__) (((__VALUE__) == DISABLE) || \ + ((__VALUE__) == ENABLE)) + +#define IS_I3C_HANDOFFACTIVITYSTATE_VALUE(__VALUE__) (((__VALUE__) == HAL_I3C_HANDOFF_ACTIVITY_STATE_0) || \ + ((__VALUE__) == HAL_I3C_HANDOFF_ACTIVITY_STATE_1) || \ + ((__VALUE__) == HAL_I3C_HANDOFF_ACTIVITY_STATE_2) || \ + ((__VALUE__) == HAL_I3C_HANDOFF_ACTIVITY_STATE_3)) + +#define IS_I3C_TSCOTIME_VALUE(__VALUE__) (((__VALUE__) == HAL_I3C_TURNAROUND_TIME_TSCO_LESS_12NS) || \ + ((__VALUE__) == HAL_I3C_TURNAROUND_TIME_TSCO_GREATER_12NS)) + +#define IS_I3C_MAXSPEEDDATA_VALUE(__VALUE__) (((__VALUE__) == HAL_I3C_GETMXDS_FORMAT_1 ) || \ + ((__VALUE__) == HAL_I3C_GETMXDS_FORMAT_2_LSB) || \ + ((__VALUE__) == HAL_I3C_GETMXDS_FORMAT_2_MID) || \ + ((__VALUE__) == HAL_I3C_GETMXDS_FORMAT_2_MSB)) + +#define IS_I3C_IBIPAYLOADSIZE_VALUE(__VALUE__) (((__VALUE__) == HAL_I3C_PAYLOAD_EMPTY ) || \ + ((__VALUE__) == HAL_I3C_PAYLOAD_1_BYTE ) || \ + ((__VALUE__) == HAL_I3C_PAYLOAD_2_BYTES) || \ + ((__VALUE__) == HAL_I3C_PAYLOAD_3_BYTES) || \ + ((__VALUE__) == HAL_I3C_PAYLOAD_4_BYTES)) + +#define IS_I3C_MIPIIDENTIFIER_VALUE(__VALUE__) ((__VALUE__) <= 0x0FU) + +#define IS_I3C_MAXREADTURNARROUND_VALUE(__VALUE__) ((__VALUE__) <= 0xFFU) + +#define I3C_CHECK_IT_SOURCE(__IER__, __IT__) ((((__IER__) & (__IT__)) == (__IT__)) ? SET : RESET) + +#define I3C_CHECK_FLAG(__ISR__, __FLAG__) ((((__ISR__) & (__FLAG__)) == (__FLAG__)) ? SET : RESET) + +#define IS_I3C_DMASOURCEBYTE_VALUE(__VALUE__) ((__VALUE__) == DMA_SRC_DATAWIDTH_BYTE) + +#define IS_I3C_DMASOURCEWORD_VALUE(__VALUE__) ((__VALUE__) == DMA_SRC_DATAWIDTH_WORD) + +#define IS_I3C_DMADESTINATIONBYTE_VALUE(__VALUE__) ((__VALUE__) == DMA_DEST_DATAWIDTH_BYTE) + +#define IS_I3C_DMADESTINATIONWORD_VALUE(__VALUE__) ((__VALUE__) == DMA_DEST_DATAWIDTH_WORD) + +#define I3C_GET_DMA_REMAIN_DATA(__HANDLE__) (__HAL_DMA_GET_COUNTER(__HANDLE__) + HAL_DMAEx_GetFifoLevel(__HANDLE__)) + +/** + * @} + */ + +/* Private functions -------------------------------------------------------------------------------------------------*/ +/** @defgroup I3C_Private_Functions I3C Private Functions + * @{ + */ +/* Private functions are defined in stm32h5xx_hal_i3c.c file */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_I3C_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_icache.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_icache.h new file mode 100644 index 0000000000..20de95b4fd --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_icache.h @@ -0,0 +1,300 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_icache.h + * @author MCD Application Team + * @brief Header file of ICACHE HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion ------------------------------------*/ +#ifndef STM32H5xx_HAL_ICACHE_H +#define STM32H5xx_HAL_ICACHE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes -----------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +#if defined(ICACHE) +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup ICACHE + * @{ + */ + +/* Exported types -----------------------------------------------------------*/ +#if defined(ICACHE_CRRx_REN) +/** @defgroup ICACHE_Exported_Types ICACHE Exported Types + * @{ + */ + +/** + * @brief HAL ICACHE region configuration structure definition + */ +typedef struct +{ + uint32_t BaseAddress; /*!< Configures the Base address of Region i to be remapped */ + + uint32_t RemapAddress; /*!< Configures the Remap address of Region i to be remapped */ + + uint32_t Size; /*!< Configures the Region size. + This parameter can be a value of @ref ICACHE_Region_Size */ + + uint32_t TrafficRoute; /*!< Selects the traffic route. + This parameter can be a value of @ref ICACHE_Traffic_Route */ + + uint32_t OutputBurstType; /*!< Selects the output burst type. + This parameter can be a value of @ref ICACHE_Output_Burst_Type */ +} ICACHE_RegionConfigTypeDef; +/** + * @} + */ +#endif /* ICACHE_CRRx_REN */ + +/* Exported constants -------------------------------------------------------*/ +/** @defgroup ICACHE_Exported_Constants ICACHE Exported Constants + * @{ + */ + +/** @defgroup ICACHE_WaysSelection Ways selection + * @{ + */ +#define ICACHE_1WAY 0U /*!< 1-way cache (direct mapped cache) */ +#define ICACHE_2WAYS ICACHE_CR_WAYSEL /*!< 2-ways set associative cache (default) */ +/** + * @} + */ + +/** @defgroup ICACHE_Monitor_Type Monitor type + * @{ + */ +#define ICACHE_MONITOR_HIT_MISS (ICACHE_CR_HITMEN | ICACHE_CR_MISSMEN) /*!< Hit & Miss monitoring */ +#define ICACHE_MONITOR_HIT ICACHE_CR_HITMEN /*!< Hit monitoring */ +#define ICACHE_MONITOR_MISS ICACHE_CR_MISSMEN /*!< Miss monitoring */ +/** + * @} + */ + +#if defined(ICACHE_CRRx_REN) +/** @defgroup ICACHE_Region Remapped Region number + * @{ + */ +#define ICACHE_REGION_0 0U /*!< Region 0 */ +#define ICACHE_REGION_1 1U /*!< Region 1 */ +#define ICACHE_REGION_2 2U /*!< Region 2 */ +#define ICACHE_REGION_3 3U /*!< Region 3 */ +/** + * @} + */ + +/** @defgroup ICACHE_Region_Size Remapped Region size + * @{ + */ +#define ICACHE_REGIONSIZE_2MB 1U /*!< Region size 2MB */ +#define ICACHE_REGIONSIZE_4MB 2U /*!< Region size 4MB */ +#define ICACHE_REGIONSIZE_8MB 3U /*!< Region size 8MB */ +#define ICACHE_REGIONSIZE_16MB 4U /*!< Region size 16MB */ +#define ICACHE_REGIONSIZE_32MB 5U /*!< Region size 32MB */ +#define ICACHE_REGIONSIZE_64MB 6U /*!< Region size 64MB */ +#define ICACHE_REGIONSIZE_128MB 7U /*!< Region size 128MB */ +/** + * @} + */ + +/** @defgroup ICACHE_Traffic_Route Remapped Traffic route + * @{ + */ +#define ICACHE_MASTER1_PORT 0U /*!< Master1 port */ +#define ICACHE_MASTER2_PORT ICACHE_CRRx_MSTSEL /*!< Master2 port */ +/** + * @} + */ + +/** @defgroup ICACHE_Output_Burst_Type Remapped Output burst type + * @{ + */ +#define ICACHE_OUTPUT_BURST_WRAP 0U /*!< WRAP */ +#define ICACHE_OUTPUT_BURST_INCR ICACHE_CRRx_HBURST /*!< INCR */ +/** + * @} + */ +#endif /* ICACHE_CRRx_REN */ + +/** @defgroup ICACHE_Interrupts Interrupts + * @{ + */ +#define ICACHE_IT_BUSYEND ICACHE_IER_BSYENDIE /*!< Busy end interrupt */ +#define ICACHE_IT_ERROR ICACHE_IER_ERRIE /*!< Cache error interrupt */ +/** + * @} + */ + +/** @defgroup ICACHE_Flags Flags + * @{ + */ +#define ICACHE_FLAG_BUSY ICACHE_SR_BUSYF /*!< Busy flag */ +#define ICACHE_FLAG_BUSYEND ICACHE_SR_BSYENDF /*!< Busy end flag */ +#define ICACHE_FLAG_ERROR ICACHE_SR_ERRF /*!< Cache error flag */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros ----------------------------------------------------------*/ +/** @defgroup ICACHE_Exported_Macros ICACHE Exported Macros + * @{ + */ + +/** @defgroup ICACHE_Flags_Interrupts_Management Flags and Interrupts Management + * @brief macros to manage the specified ICACHE flags and interrupts. + * @{ + */ + +/** @brief Enable ICACHE interrupts. + * @param __INTERRUPT__ specifies the ICACHE interrupt sources to be enabled. + * This parameter can be any combination of the following values: + * @arg @ref ICACHE_IT_BUSYEND Busy end interrupt + * @arg @ref ICACHE_IT_ERROR Cache error interrupt + */ +#define __HAL_ICACHE_ENABLE_IT(__INTERRUPT__) SET_BIT(ICACHE->IER, (__INTERRUPT__)) + +/** @brief Disable ICACHE interrupts. + * @param __INTERRUPT__ specifies the ICACHE interrupt sources to be disabled. + * This parameter can be any combination of the following values: + * @arg @ref ICACHE_IT_BUSYEND Busy end interrupt + * @arg @ref ICACHE_IT_ERROR Cache error interrupt + */ +#define __HAL_ICACHE_DISABLE_IT(__INTERRUPT__) CLEAR_BIT(ICACHE->IER, (__INTERRUPT__)) + +/** @brief Check whether the specified ICACHE interrupt source is enabled or not. + * @param __INTERRUPT__ specifies the ICACHE interrupt source to check. + * This parameter can be any combination of the following values: + * @arg @ref ICACHE_IT_BUSYEND Busy end interrupt + * @arg @ref ICACHE_IT_ERROR Cache error interrupt + * @retval The state of __INTERRUPT__ (0 or 1). + */ +#define __HAL_ICACHE_GET_IT_SOURCE(__INTERRUPT__) \ + ((READ_BIT(ICACHE->IER, (__INTERRUPT__)) == (__INTERRUPT__)) ? 1U : 0U) + +/** @brief Check whether the selected ICACHE flag is set or not. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg @ref ICACHE_FLAG_BUSY Busy flag + * @arg @ref ICACHE_FLAG_BUSYEND Busy end flag + * @arg @ref ICACHE_FLAG_ERROR Cache error flag + * @retval The state of __FLAG__ (0 or 1). + */ +#define __HAL_ICACHE_GET_FLAG(__FLAG__) ((READ_BIT(ICACHE->SR, (__FLAG__)) != 0U) ? 1U : 0U) + +/** @brief Clear the selected ICACHE flags. + * @param __FLAG__ specifies the ICACHE flags to clear. + * This parameter can be any combination of the following values: + * @arg @ref ICACHE_FLAG_BUSYEND Busy end flag + * @arg @ref ICACHE_FLAG_ERROR Cache error flag + */ +#define __HAL_ICACHE_CLEAR_FLAG(__FLAG__) WRITE_REG(ICACHE->FCR, (__FLAG__)) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions -------------------------------------------------------*/ +/** @addtogroup ICACHE_Exported_Functions + * @{ + */ + +/** @addtogroup ICACHE_Exported_Functions_Group1 + * @brief Initialization and control functions + * @{ + */ +/* Peripheral Control functions **********************************************/ +HAL_StatusTypeDef HAL_ICACHE_Enable(void); +HAL_StatusTypeDef HAL_ICACHE_Disable(void); +uint32_t HAL_ICACHE_IsEnabled(void); +HAL_StatusTypeDef HAL_ICACHE_ConfigAssociativityMode(uint32_t AssociativityMode); +HAL_StatusTypeDef HAL_ICACHE_DeInit(void); + +/******* Invalidate in blocking mode (Polling) */ +HAL_StatusTypeDef HAL_ICACHE_Invalidate(void); +/******* Invalidate in non-blocking mode (Interrupt) */ +HAL_StatusTypeDef HAL_ICACHE_Invalidate_IT(void); +/******* Wait for Invalidate complete in blocking mode (Polling) */ +HAL_StatusTypeDef HAL_ICACHE_WaitForInvalidateComplete(void); + +/******* Performance instruction cache monitoring functions */ +HAL_StatusTypeDef HAL_ICACHE_Monitor_Start(uint32_t MonitorType); +HAL_StatusTypeDef HAL_ICACHE_Monitor_Stop(uint32_t MonitorType); +HAL_StatusTypeDef HAL_ICACHE_Monitor_Reset(uint32_t MonitorType); +uint32_t HAL_ICACHE_Monitor_GetHitValue(void); +uint32_t HAL_ICACHE_Monitor_GetMissValue(void); + +/** + * @} + */ + +/** @addtogroup ICACHE_Exported_Functions_Group2 + * @brief IRQ and callback functions + * @{ + */ +/******* IRQHandler and Callbacks used in non-blocking mode (Interrupt) */ +void HAL_ICACHE_IRQHandler(void); +void HAL_ICACHE_InvalidateCompleteCallback(void); +void HAL_ICACHE_ErrorCallback(void); + +/** + * @} + */ + +#if defined(ICACHE_CRRx_REN) +/** @addtogroup ICACHE_Exported_Functions_Group3 + * @brief Memory remapped regions functions + * @{ + */ +/******* Memory remapped regions functions */ +HAL_StatusTypeDef HAL_ICACHE_EnableRemapRegion(uint32_t Region, const ICACHE_RegionConfigTypeDef *const pRegionConfig); +HAL_StatusTypeDef HAL_ICACHE_DisableRemapRegion(uint32_t Region); + +/** + * @} + */ +#endif /* ICACHE_CRRx_REN */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* ICACHE */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_ICACHE_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_irda.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_irda.h new file mode 100644 index 0000000000..cfb51c0ba4 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_irda.h @@ -0,0 +1,902 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_irda.h + * @author MCD Application Team + * @brief Header file of IRDA HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_IRDA_H +#define STM32H5xx_HAL_IRDA_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup IRDA + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup IRDA_Exported_Types IRDA Exported Types + * @{ + */ + +/** + * @brief IRDA Init Structure definition + */ +typedef struct +{ + uint32_t BaudRate; /*!< This member configures the IRDA communication baud rate. + The baud rate register is computed using the following formula: + Baud Rate Register = ((usart_ker_ckpres) / ((hirda->Init.BaudRate))) + where usart_ker_ckpres is the IRDA input clock divided by a prescaler */ + + uint32_t WordLength; /*!< Specifies the number of data bits transmitted or received in a frame. + This parameter can be a value of @ref IRDAEx_Word_Length */ + + uint32_t Parity; /*!< Specifies the parity mode. + This parameter can be a value of @ref IRDA_Parity + @note When parity is enabled, the computed parity is inserted + at the MSB position of the transmitted data (9th bit when + the word length is set to 9 data bits; 8th bit when the + word length is set to 8 data bits). */ + + uint32_t Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled. + This parameter can be a value of @ref IRDA_Transfer_Mode */ + + uint8_t Prescaler; /*!< Specifies the Prescaler value for dividing the UART/USART source clock + to achieve low-power frequency. + @note Prescaler value 0 is forbidden */ + + uint16_t PowerMode; /*!< Specifies the IRDA power mode. + This parameter can be a value of @ref IRDA_Low_Power */ + + uint32_t ClockPrescaler; /*!< Specifies the prescaler value used to divide the IRDA clock source. + This parameter can be a value of @ref IRDA_ClockPrescaler. */ + +} IRDA_InitTypeDef; + +/** + * @brief HAL IRDA State definition + * @note HAL IRDA State value is a combination of 2 different substates: + * gState and RxState (see @ref IRDA_State_Definition). + * - gState contains IRDA state information related to global Handle management + * and also information related to Tx operations. + * gState value coding follow below described bitmap : + * b7-b6 Error information + * 00 : No Error + * 01 : (Not Used) + * 10 : Timeout + * 11 : Error + * b5 Peripheral initialization status + * 0 : Reset (Peripheral not initialized) + * 1 : Init done (Peripheral initialized. HAL IRDA Init function already called) + * b4-b3 (not used) + * xx : Should be set to 00 + * b2 Intrinsic process state + * 0 : Ready + * 1 : Busy (Peripheral busy with some configuration or internal operations) + * b1 (not used) + * x : Should be set to 0 + * b0 Tx state + * 0 : Ready (no Tx operation ongoing) + * 1 : Busy (Tx operation ongoing) + * - RxState contains information related to Rx operations. + * RxState value coding follow below described bitmap : + * b7-b6 (not used) + * xx : Should be set to 00 + * b5 Peripheral initialization status + * 0 : Reset (Peripheral not initialized) + * 1 : Init done (Peripheral initialized) + * b4-b2 (not used) + * xxx : Should be set to 000 + * b1 Rx state + * 0 : Ready (no Rx operation ongoing) + * 1 : Busy (Rx operation ongoing) + * b0 (not used) + * x : Should be set to 0. + */ +typedef uint32_t HAL_IRDA_StateTypeDef; + +/** + * @brief IRDA clock sources definition + */ +typedef enum +{ + IRDA_CLOCKSOURCE_PLL2Q = 0x14U, /*!< PLL2Q clock source */ +#if defined(RCC_CR_PLL3ON) + IRDA_CLOCKSOURCE_PLL3Q = 0x18U, /*!< PLL3Q clock source */ +#endif /* RCC_CR_PLL3ON */ + IRDA_CLOCKSOURCE_PCLK1 = 0x00U, /*!< PCLK1 clock source */ + IRDA_CLOCKSOURCE_PCLK2 = 0x01U, /*!< PCLK2 clock source */ + IRDA_CLOCKSOURCE_HSI = 0x02U, /*!< HSI clock source */ + IRDA_CLOCKSOURCE_CSI = 0x08U, /*!< CSI clock source */ + IRDA_CLOCKSOURCE_LSE = 0x10U, /*!< LSE clock source */ + IRDA_CLOCKSOURCE_UNDEFINED = 0x20U /*!< Undefined clock source */ +} IRDA_ClockSourceTypeDef; + +/** + * @brief IRDA handle Structure definition + */ +#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) +typedef struct __IRDA_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */ +{ + USART_TypeDef *Instance; /*!< USART registers base address */ + + IRDA_InitTypeDef Init; /*!< IRDA communication parameters */ + + const uint8_t *pTxBuffPtr; /*!< Pointer to IRDA Tx transfer Buffer */ + + uint16_t TxXferSize; /*!< IRDA Tx Transfer size */ + + __IO uint16_t TxXferCount; /*!< IRDA Tx Transfer Counter */ + + uint8_t *pRxBuffPtr; /*!< Pointer to IRDA Rx transfer Buffer */ + + uint16_t RxXferSize; /*!< IRDA Rx Transfer size */ + + __IO uint16_t RxXferCount; /*!< IRDA Rx Transfer Counter */ + + uint16_t Mask; /*!< USART RX RDR register mask */ + +#if defined(HAL_DMA_MODULE_ENABLED) + DMA_HandleTypeDef *hdmatx; /*!< IRDA Tx DMA Handle parameters */ + + DMA_HandleTypeDef *hdmarx; /*!< IRDA Rx DMA Handle parameters */ + +#endif /* HAL_DMA_MODULE_ENABLED */ + HAL_LockTypeDef Lock; /*!< Locking object */ + + __IO HAL_IRDA_StateTypeDef gState; /*!< IRDA state information related to global Handle management + and also related to Tx operations. + This parameter can be a value of @ref HAL_IRDA_StateTypeDef */ + + __IO HAL_IRDA_StateTypeDef RxState; /*!< IRDA state information related to Rx operations. + This parameter can be a value of @ref HAL_IRDA_StateTypeDef */ + + __IO uint32_t ErrorCode; /*!< IRDA Error code */ + +#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) + void (* TxHalfCpltCallback)(struct __IRDA_HandleTypeDef *hirda); /*!< IRDA Tx Half Complete Callback */ + + void (* TxCpltCallback)(struct __IRDA_HandleTypeDef *hirda); /*!< IRDA Tx Complete Callback */ + + void (* RxHalfCpltCallback)(struct __IRDA_HandleTypeDef *hirda); /*!< IRDA Rx Half Complete Callback */ + + void (* RxCpltCallback)(struct __IRDA_HandleTypeDef *hirda); /*!< IRDA Rx Complete Callback */ + + void (* ErrorCallback)(struct __IRDA_HandleTypeDef *hirda); /*!< IRDA Error Callback */ + + void (* AbortCpltCallback)(struct __IRDA_HandleTypeDef *hirda); /*!< IRDA Abort Complete Callback */ + + void (* AbortTransmitCpltCallback)(struct __IRDA_HandleTypeDef *hirda); /*!< IRDA Abort Transmit Complete Callback */ + + void (* AbortReceiveCpltCallback)(struct __IRDA_HandleTypeDef *hirda); /*!< IRDA Abort Receive Complete Callback */ + + + void (* MspInitCallback)(struct __IRDA_HandleTypeDef *hirda); /*!< IRDA Msp Init callback */ + + void (* MspDeInitCallback)(struct __IRDA_HandleTypeDef *hirda); /*!< IRDA Msp DeInit callback */ +#endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */ + +} IRDA_HandleTypeDef; + +#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) +/** + * @brief HAL IRDA Callback ID enumeration definition + */ +typedef enum +{ + HAL_IRDA_TX_HALFCOMPLETE_CB_ID = 0x00U, /*!< IRDA Tx Half Complete Callback ID */ + HAL_IRDA_TX_COMPLETE_CB_ID = 0x01U, /*!< IRDA Tx Complete Callback ID */ + HAL_IRDA_RX_HALFCOMPLETE_CB_ID = 0x02U, /*!< IRDA Rx Half Complete Callback ID */ + HAL_IRDA_RX_COMPLETE_CB_ID = 0x03U, /*!< IRDA Rx Complete Callback ID */ + HAL_IRDA_ERROR_CB_ID = 0x04U, /*!< IRDA Error Callback ID */ + HAL_IRDA_ABORT_COMPLETE_CB_ID = 0x05U, /*!< IRDA Abort Complete Callback ID */ + HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID = 0x06U, /*!< IRDA Abort Transmit Complete Callback ID */ + HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID = 0x07U, /*!< IRDA Abort Receive Complete Callback ID */ + + HAL_IRDA_MSPINIT_CB_ID = 0x08U, /*!< IRDA MspInit callback ID */ + HAL_IRDA_MSPDEINIT_CB_ID = 0x09U /*!< IRDA MspDeInit callback ID */ + +} HAL_IRDA_CallbackIDTypeDef; + +/** + * @brief HAL IRDA Callback pointer definition + */ +typedef void (*pIRDA_CallbackTypeDef)(IRDA_HandleTypeDef *hirda); /*!< pointer to an IRDA callback function */ + +#endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup IRDA_Exported_Constants IRDA Exported Constants + * @{ + */ + +/** @defgroup IRDA_State_Definition IRDA State Code Definition + * @{ + */ +#define HAL_IRDA_STATE_RESET 0x00000000U /*!< Peripheral is not initialized + Value is allowed for gState and RxState */ +#define HAL_IRDA_STATE_READY 0x00000020U /*!< Peripheral Initialized and ready for use + Value is allowed for gState and RxState */ +#define HAL_IRDA_STATE_BUSY 0x00000024U /*!< An internal process is ongoing + Value is allowed for gState only */ +#define HAL_IRDA_STATE_BUSY_TX 0x00000021U /*!< Data Transmission process is ongoing + Value is allowed for gState only */ +#define HAL_IRDA_STATE_BUSY_RX 0x00000022U /*!< Data Reception process is ongoing + Value is allowed for RxState only */ +#define HAL_IRDA_STATE_BUSY_TX_RX 0x00000023U /*!< Data Transmission and Reception process is ongoing + Not to be used for neither gState nor RxState. + Value is result of combination (Or) between + gState and RxState values */ +#define HAL_IRDA_STATE_TIMEOUT 0x000000A0U /*!< Timeout state + Value is allowed for gState only */ +#define HAL_IRDA_STATE_ERROR 0x000000E0U /*!< Error + Value is allowed for gState only */ +/** + * @} + */ + +/** @defgroup IRDA_Error_Definition IRDA Error Code Definition + * @{ + */ +#define HAL_IRDA_ERROR_NONE (0x00000000U) /*!< No error */ +#define HAL_IRDA_ERROR_PE (0x00000001U) /*!< Parity error */ +#define HAL_IRDA_ERROR_NE (0x00000002U) /*!< Noise error */ +#define HAL_IRDA_ERROR_FE (0x00000004U) /*!< frame error */ +#define HAL_IRDA_ERROR_ORE (0x00000008U) /*!< Overrun error */ +#if defined(HAL_DMA_MODULE_ENABLED) +#define HAL_IRDA_ERROR_DMA (0x00000010U) /*!< DMA transfer error */ +#endif /* HAL_DMA_MODULE_ENABLED */ +#define HAL_IRDA_ERROR_BUSY (0x00000020U) /*!< Busy Error */ +#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) +#define HAL_IRDA_ERROR_INVALID_CALLBACK (0x00000040U) /*!< Invalid Callback error */ +#endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @defgroup IRDA_Parity IRDA Parity + * @{ + */ +#define IRDA_PARITY_NONE 0x00000000U /*!< No parity */ +#define IRDA_PARITY_EVEN USART_CR1_PCE /*!< Even parity */ +#define IRDA_PARITY_ODD (USART_CR1_PCE | USART_CR1_PS) /*!< Odd parity */ +/** + * @} + */ + +/** @defgroup IRDA_Transfer_Mode IRDA Transfer Mode + * @{ + */ +#define IRDA_MODE_RX USART_CR1_RE /*!< RX mode */ +#define IRDA_MODE_TX USART_CR1_TE /*!< TX mode */ +#define IRDA_MODE_TX_RX (USART_CR1_TE |USART_CR1_RE) /*!< RX and TX mode */ +/** + * @} + */ + +/** @defgroup IRDA_Low_Power IRDA Low Power + * @{ + */ +#define IRDA_POWERMODE_NORMAL 0x00000000U /*!< IRDA normal power mode */ +#define IRDA_POWERMODE_LOWPOWER USART_CR3_IRLP /*!< IRDA low power mode */ +/** + * @} + */ + +/** @defgroup IRDA_ClockPrescaler IRDA Clock Prescaler + * @{ + */ +#define IRDA_PRESCALER_DIV1 0x00000000U /*!< fclk_pres = fclk */ +#define IRDA_PRESCALER_DIV2 0x00000001U /*!< fclk_pres = fclk/2 */ +#define IRDA_PRESCALER_DIV4 0x00000002U /*!< fclk_pres = fclk/4 */ +#define IRDA_PRESCALER_DIV6 0x00000003U /*!< fclk_pres = fclk/6 */ +#define IRDA_PRESCALER_DIV8 0x00000004U /*!< fclk_pres = fclk/8 */ +#define IRDA_PRESCALER_DIV10 0x00000005U /*!< fclk_pres = fclk/10 */ +#define IRDA_PRESCALER_DIV12 0x00000006U /*!< fclk_pres = fclk/12 */ +#define IRDA_PRESCALER_DIV16 0x00000007U /*!< fclk_pres = fclk/16 */ +#define IRDA_PRESCALER_DIV32 0x00000008U /*!< fclk_pres = fclk/32 */ +#define IRDA_PRESCALER_DIV64 0x00000009U /*!< fclk_pres = fclk/64 */ +#define IRDA_PRESCALER_DIV128 0x0000000AU /*!< fclk_pres = fclk/128 */ +#define IRDA_PRESCALER_DIV256 0x0000000BU /*!< fclk_pres = fclk/256 */ +/** + * @} + */ + +/** @defgroup IRDA_State IRDA State + * @{ + */ +#define IRDA_STATE_DISABLE 0x00000000U /*!< IRDA disabled */ +#define IRDA_STATE_ENABLE USART_CR1_UE /*!< IRDA enabled */ +/** + * @} + */ + +/** @defgroup IRDA_Mode IRDA Mode + * @{ + */ +#define IRDA_MODE_DISABLE 0x00000000U /*!< Associated UART disabled in IRDA mode */ +#define IRDA_MODE_ENABLE USART_CR3_IREN /*!< Associated UART enabled in IRDA mode */ +/** + * @} + */ + +/** @defgroup IRDA_One_Bit IRDA One Bit Sampling + * @{ + */ +#define IRDA_ONE_BIT_SAMPLE_DISABLE 0x00000000U /*!< One-bit sampling disabled */ +#define IRDA_ONE_BIT_SAMPLE_ENABLE USART_CR3_ONEBIT /*!< One-bit sampling enabled */ +/** + * @} + */ + +/** @defgroup IRDA_DMA_Tx IRDA DMA Tx + * @{ + */ +#define IRDA_DMA_TX_DISABLE 0x00000000U /*!< IRDA DMA TX disabled */ +#define IRDA_DMA_TX_ENABLE USART_CR3_DMAT /*!< IRDA DMA TX enabled */ +/** + * @} + */ + +/** @defgroup IRDA_DMA_Rx IRDA DMA Rx + * @{ + */ +#define IRDA_DMA_RX_DISABLE 0x00000000U /*!< IRDA DMA RX disabled */ +#define IRDA_DMA_RX_ENABLE USART_CR3_DMAR /*!< IRDA DMA RX enabled */ +/** + * @} + */ + +/** @defgroup IRDA_Request_Parameters IRDA Request Parameters + * @{ + */ +#define IRDA_AUTOBAUD_REQUEST USART_RQR_ABRRQ /*!< Auto-Baud Rate Request */ +#define IRDA_RXDATA_FLUSH_REQUEST USART_RQR_RXFRQ /*!< Receive Data flush Request */ +#define IRDA_TXDATA_FLUSH_REQUEST USART_RQR_TXFRQ /*!< Transmit data flush Request */ +/** + * @} + */ + +/** @defgroup IRDA_Flags IRDA Flags + * Elements values convention: 0xXXXX + * - 0xXXXX : Flag mask in the ISR register + * @{ + */ +#define IRDA_FLAG_REACK USART_ISR_REACK /*!< IRDA receive enable acknowledge flag */ +#define IRDA_FLAG_TEACK USART_ISR_TEACK /*!< IRDA transmit enable acknowledge flag */ +#define IRDA_FLAG_BUSY USART_ISR_BUSY /*!< IRDA busy flag */ +#define IRDA_FLAG_ABRF USART_ISR_ABRF /*!< IRDA auto Baud rate flag */ +#define IRDA_FLAG_ABRE USART_ISR_ABRE /*!< IRDA auto Baud rate error */ +#define IRDA_FLAG_TXE USART_ISR_TXE_TXFNF /*!< IRDA transmit data register empty */ +#define IRDA_FLAG_TC USART_ISR_TC /*!< IRDA transmission complete */ +#define IRDA_FLAG_RXNE USART_ISR_RXNE_RXFNE /*!< IRDA read data register not empty */ +#define IRDA_FLAG_ORE USART_ISR_ORE /*!< IRDA overrun error */ +#define IRDA_FLAG_NE USART_ISR_NE /*!< IRDA noise error */ +#define IRDA_FLAG_FE USART_ISR_FE /*!< IRDA frame error */ +#define IRDA_FLAG_PE USART_ISR_PE /*!< IRDA parity error */ +/** + * @} + */ + +/** @defgroup IRDA_Interrupt_definition IRDA Interrupts Definition + * Elements values convention: 0000ZZZZ0XXYYYYYb + * - YYYYY : Interrupt source position in the XX register (5bits) + * - XX : Interrupt source register (2bits) + * - 01: CR1 register + * - 10: CR2 register + * - 11: CR3 register + * - ZZZZ : Flag position in the ISR register(4bits) + * @{ + */ +#define IRDA_IT_PE 0x0028U /*!< IRDA Parity error interruption */ +#define IRDA_IT_TXE 0x0727U /*!< IRDA Transmit data register empty interruption */ +#define IRDA_IT_TC 0x0626U /*!< IRDA Transmission complete interruption */ +#define IRDA_IT_RXNE 0x0525U /*!< IRDA Read data register not empty interruption */ +#define IRDA_IT_IDLE 0x0424U /*!< IRDA Idle interruption */ + +/* Elements values convention: 000000000XXYYYYYb + - YYYYY : Interrupt source position in the XX register (5bits) + - XX : Interrupt source register (2bits) + - 01: CR1 register + - 10: CR2 register + - 11: CR3 register */ +#define IRDA_IT_ERR 0x0060U /*!< IRDA Error interruption */ + +/* Elements values convention: 0000ZZZZ00000000b + - ZZZZ : Flag position in the ISR register(4bits) */ +#define IRDA_IT_ORE 0x0300U /*!< IRDA Overrun error interruption */ +#define IRDA_IT_NE 0x0200U /*!< IRDA Noise error interruption */ +#define IRDA_IT_FE 0x0100U /*!< IRDA Frame error interruption */ +/** + * @} + */ + +/** @defgroup IRDA_IT_CLEAR_Flags IRDA Interruption Clear Flags + * @{ + */ +#define IRDA_CLEAR_PEF USART_ICR_PECF /*!< Parity Error Clear Flag */ +#define IRDA_CLEAR_FEF USART_ICR_FECF /*!< Framing Error Clear Flag */ +#define IRDA_CLEAR_NEF USART_ICR_NECF /*!< Noise Error detected Clear Flag */ +#define IRDA_CLEAR_OREF USART_ICR_ORECF /*!< OverRun Error Clear Flag */ +#define IRDA_CLEAR_IDLEF USART_ICR_IDLECF /*!< IDLE line detected Clear Flag */ +#define IRDA_CLEAR_TCF USART_ICR_TCCF /*!< Transmission Complete Clear Flag */ +/** + * @} + */ + +/** @defgroup IRDA_Interruption_Mask IRDA interruptions flags mask + * @{ + */ +#define IRDA_IT_MASK 0x001FU /*!< IRDA Interruptions flags mask */ +#define IRDA_CR_MASK 0x00E0U /*!< IRDA control register mask */ +#define IRDA_CR_POS 5U /*!< IRDA control register position */ +#define IRDA_ISR_MASK 0x1F00U /*!< IRDA ISR register mask */ +#define IRDA_ISR_POS 8U /*!< IRDA ISR register position */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup IRDA_Exported_Macros IRDA Exported Macros + * @{ + */ + +/** @brief Reset IRDA handle state. + * @param __HANDLE__ IRDA handle. + * @retval None + */ +#if USE_HAL_IRDA_REGISTER_CALLBACKS == 1 +#define __HAL_IRDA_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->gState = HAL_IRDA_STATE_RESET; \ + (__HANDLE__)->RxState = HAL_IRDA_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0U) +#else +#define __HAL_IRDA_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->gState = HAL_IRDA_STATE_RESET; \ + (__HANDLE__)->RxState = HAL_IRDA_STATE_RESET; \ + } while(0U) +#endif /*USE_HAL_IRDA_REGISTER_CALLBACKS */ + +/** @brief Flush the IRDA DR register. + * @param __HANDLE__ specifies the IRDA Handle. + * @retval None + */ +#define __HAL_IRDA_FLUSH_DRREGISTER(__HANDLE__) \ + do{ \ + SET_BIT((__HANDLE__)->Instance->RQR, IRDA_RXDATA_FLUSH_REQUEST); \ + SET_BIT((__HANDLE__)->Instance->RQR, IRDA_TXDATA_FLUSH_REQUEST); \ + } while(0U) + +/** @brief Clear the specified IRDA pending flag. + * @param __HANDLE__ specifies the IRDA Handle. + * @param __FLAG__ specifies the flag to check. + * This parameter can be any combination of the following values: + * @arg @ref IRDA_CLEAR_PEF + * @arg @ref IRDA_CLEAR_FEF + * @arg @ref IRDA_CLEAR_NEF + * @arg @ref IRDA_CLEAR_OREF + * @arg @ref IRDA_CLEAR_TCF + * @arg @ref IRDA_CLEAR_IDLEF + * @retval None + */ +#define __HAL_IRDA_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ICR = (__FLAG__)) + +/** @brief Clear the IRDA PE pending flag. + * @param __HANDLE__ specifies the IRDA Handle. + * @retval None + */ +#define __HAL_IRDA_CLEAR_PEFLAG(__HANDLE__) __HAL_IRDA_CLEAR_FLAG((__HANDLE__), IRDA_CLEAR_PEF) + + +/** @brief Clear the IRDA FE pending flag. + * @param __HANDLE__ specifies the IRDA Handle. + * @retval None + */ +#define __HAL_IRDA_CLEAR_FEFLAG(__HANDLE__) __HAL_IRDA_CLEAR_FLAG((__HANDLE__), IRDA_CLEAR_FEF) + +/** @brief Clear the IRDA NE pending flag. + * @param __HANDLE__ specifies the IRDA Handle. + * @retval None + */ +#define __HAL_IRDA_CLEAR_NEFLAG(__HANDLE__) __HAL_IRDA_CLEAR_FLAG((__HANDLE__), IRDA_CLEAR_NEF) + +/** @brief Clear the IRDA ORE pending flag. + * @param __HANDLE__ specifies the IRDA Handle. + * @retval None + */ +#define __HAL_IRDA_CLEAR_OREFLAG(__HANDLE__) __HAL_IRDA_CLEAR_FLAG((__HANDLE__), IRDA_CLEAR_OREF) + +/** @brief Clear the IRDA IDLE pending flag. + * @param __HANDLE__ specifies the IRDA Handle. + * @retval None + */ +#define __HAL_IRDA_CLEAR_IDLEFLAG(__HANDLE__) __HAL_IRDA_CLEAR_FLAG((__HANDLE__), IRDA_CLEAR_IDLEF) + +/** @brief Check whether the specified IRDA flag is set or not. + * @param __HANDLE__ specifies the IRDA Handle. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg @ref IRDA_FLAG_REACK Receive enable acknowledge flag + * @arg @ref IRDA_FLAG_TEACK Transmit enable acknowledge flag + * @arg @ref IRDA_FLAG_BUSY Busy flag + * @arg @ref IRDA_FLAG_ABRF Auto Baud rate detection flag + * @arg @ref IRDA_FLAG_ABRE Auto Baud rate detection error flag + * @arg @ref IRDA_FLAG_TXE Transmit data register empty flag + * @arg @ref IRDA_FLAG_TC Transmission Complete flag + * @arg @ref IRDA_FLAG_RXNE Receive data register not empty flag + * @arg @ref IRDA_FLAG_ORE OverRun Error flag + * @arg @ref IRDA_FLAG_NE Noise Error flag + * @arg @ref IRDA_FLAG_FE Framing Error flag + * @arg @ref IRDA_FLAG_PE Parity Error flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_IRDA_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->ISR & (__FLAG__)) == (__FLAG__)) + + +/** @brief Enable the specified IRDA interrupt. + * @param __HANDLE__ specifies the IRDA Handle. + * @param __INTERRUPT__ specifies the IRDA interrupt source to enable. + * This parameter can be one of the following values: + * @arg @ref IRDA_IT_TXE Transmit Data Register empty interrupt + * @arg @ref IRDA_IT_TC Transmission complete interrupt + * @arg @ref IRDA_IT_RXNE Receive Data register not empty interrupt + * @arg @ref IRDA_IT_IDLE Idle line detection interrupt + * @arg @ref IRDA_IT_PE Parity Error interrupt + * @arg @ref IRDA_IT_ERR Error interrupt(Frame error, noise error, overrun error) + * @retval None + */ +#define __HAL_IRDA_ENABLE_IT(__HANDLE__, __INTERRUPT__) (((((__INTERRUPT__) & IRDA_CR_MASK) >> IRDA_CR_POS) == 1U)? \ + ((__HANDLE__)->Instance->CR1 |= (1U << \ + ((__INTERRUPT__) & IRDA_IT_MASK))):\ + ((((__INTERRUPT__) & IRDA_CR_MASK) >> IRDA_CR_POS) == 2U)? \ + ((__HANDLE__)->Instance->CR2 |= (1U << \ + ((__INTERRUPT__) & IRDA_IT_MASK))):\ + ((__HANDLE__)->Instance->CR3 |= (1U << \ + ((__INTERRUPT__) & IRDA_IT_MASK)))) + +/** @brief Disable the specified IRDA interrupt. + * @param __HANDLE__ specifies the IRDA Handle. + * @param __INTERRUPT__ specifies the IRDA interrupt source to disable. + * This parameter can be one of the following values: + * @arg @ref IRDA_IT_TXE Transmit Data Register empty interrupt + * @arg @ref IRDA_IT_TC Transmission complete interrupt + * @arg @ref IRDA_IT_RXNE Receive Data register not empty interrupt + * @arg @ref IRDA_IT_IDLE Idle line detection interrupt + * @arg @ref IRDA_IT_PE Parity Error interrupt + * @arg @ref IRDA_IT_ERR Error interrupt(Frame error, noise error, overrun error) + * @retval None + */ +#define __HAL_IRDA_DISABLE_IT(__HANDLE__, __INTERRUPT__) (((((__INTERRUPT__) & IRDA_CR_MASK) >> IRDA_CR_POS) == 1U)? \ + ((__HANDLE__)->Instance->CR1 &= ~ (1U << \ + ((__INTERRUPT__) & IRDA_IT_MASK))): \ + ((((__INTERRUPT__) & IRDA_CR_MASK) >> IRDA_CR_POS) == 2U)? \ + ((__HANDLE__)->Instance->CR2 &= ~ (1U << \ + ((__INTERRUPT__) & IRDA_IT_MASK))): \ + ((__HANDLE__)->Instance->CR3 &= ~ (1U << \ + ((__INTERRUPT__) & IRDA_IT_MASK)))) + +/** @brief Check whether the specified IRDA interrupt has occurred or not. + * @param __HANDLE__ specifies the IRDA Handle. + * @param __INTERRUPT__ specifies the IRDA interrupt source to check. + * This parameter can be one of the following values: + * @arg @ref IRDA_IT_TXE Transmit Data Register empty interrupt + * @arg @ref IRDA_IT_TC Transmission complete interrupt + * @arg @ref IRDA_IT_RXNE Receive Data register not empty interrupt + * @arg @ref IRDA_IT_IDLE Idle line detection interrupt + * @arg @ref IRDA_IT_ORE OverRun Error interrupt + * @arg @ref IRDA_IT_NE Noise Error interrupt + * @arg @ref IRDA_IT_FE Framing Error interrupt + * @arg @ref IRDA_IT_PE Parity Error interrupt + * @retval The new state of __IT__ (SET or RESET). + */ +#define __HAL_IRDA_GET_IT(__HANDLE__, __INTERRUPT__) \ + ((((__HANDLE__)->Instance->ISR& (0x01U << (((__INTERRUPT__) & IRDA_ISR_MASK)>>IRDA_ISR_POS))) != 0U) ? SET : RESET) + +/** @brief Check whether the specified IRDA interrupt source is enabled or not. + * @param __HANDLE__ specifies the IRDA Handle. + * @param __INTERRUPT__ specifies the IRDA interrupt source to check. + * This parameter can be one of the following values: + * @arg @ref IRDA_IT_TXE Transmit Data Register empty interrupt + * @arg @ref IRDA_IT_TC Transmission complete interrupt + * @arg @ref IRDA_IT_RXNE Receive Data register not empty interrupt + * @arg @ref IRDA_IT_IDLE Idle line detection interrupt + * @arg @ref IRDA_IT_ERR Framing, overrun or noise error interrupt + * @arg @ref IRDA_IT_PE Parity Error interrupt + * @retval The new state of __IT__ (SET or RESET). + */ +#define __HAL_IRDA_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) \ + ((((((((__INTERRUPT__) & IRDA_CR_MASK) >>IRDA_CR_POS) == 0x01U)? (__HANDLE__)->Instance->CR1 :(((((__INTERRUPT__) \ + & IRDA_CR_MASK) >> IRDA_CR_POS)== 0x02U)? (__HANDLE__)->Instance->CR2 :(__HANDLE__)->Instance->CR3)) \ + & (0x01U <<(((uint16_t)(__INTERRUPT__)) & IRDA_IT_MASK))) != 0U) ? SET : RESET) + +/** @brief Clear the specified IRDA ISR flag, in setting the proper ICR register flag. + * @param __HANDLE__ specifies the IRDA Handle. + * @param __IT_CLEAR__ specifies the interrupt clear register flag that needs to be set + * to clear the corresponding interrupt + * This parameter can be one of the following values: + * @arg @ref IRDA_CLEAR_PEF Parity Error Clear Flag + * @arg @ref IRDA_CLEAR_FEF Framing Error Clear Flag + * @arg @ref IRDA_CLEAR_NEF Noise detected Clear Flag + * @arg @ref IRDA_CLEAR_OREF OverRun Error Clear Flag + * @arg @ref IRDA_CLEAR_TCF Transmission Complete Clear Flag + * @retval None + */ +#define __HAL_IRDA_CLEAR_IT(__HANDLE__, __IT_CLEAR__) ((__HANDLE__)->Instance->ICR = (uint32_t)(__IT_CLEAR__)) + + +/** @brief Set a specific IRDA request flag. + * @param __HANDLE__ specifies the IRDA Handle. + * @param __REQ__ specifies the request flag to set + * This parameter can be one of the following values: + * @arg @ref IRDA_AUTOBAUD_REQUEST Auto-Baud Rate Request + * @arg @ref IRDA_RXDATA_FLUSH_REQUEST Receive Data flush Request + * @arg @ref IRDA_TXDATA_FLUSH_REQUEST Transmit data flush Request + * @retval None + */ +#define __HAL_IRDA_SEND_REQ(__HANDLE__, __REQ__) ((__HANDLE__)->Instance->RQR |= (uint16_t)(__REQ__)) + +/** @brief Enable the IRDA one bit sample method. + * @param __HANDLE__ specifies the IRDA Handle. + * @retval None + */ +#define __HAL_IRDA_ONE_BIT_SAMPLE_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3|= USART_CR3_ONEBIT) + +/** @brief Disable the IRDA one bit sample method. + * @param __HANDLE__ specifies the IRDA Handle. + * @retval None + */ +#define __HAL_IRDA_ONE_BIT_SAMPLE_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3\ + &= (uint32_t)~((uint32_t)USART_CR3_ONEBIT)) + +/** @brief Enable UART/USART associated to IRDA Handle. + * @param __HANDLE__ specifies the IRDA Handle. + * @retval None + */ +#define __HAL_IRDA_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= USART_CR1_UE) + +/** @brief Disable UART/USART associated to IRDA Handle. + * @param __HANDLE__ specifies the IRDA Handle. + * @retval None + */ +#define __HAL_IRDA_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~USART_CR1_UE) + +/** + * @} + */ + +/* Private macros --------------------------------------------------------*/ +/** @addtogroup IRDA_Private_Macros + * @{ + */ + +/** @brief Ensure that IRDA Baud rate is less or equal to maximum value. + * @param __BAUDRATE__ specifies the IRDA Baudrate set by the user. + * @retval True or False + */ +#define IS_IRDA_BAUDRATE(__BAUDRATE__) ((__BAUDRATE__) < 115201U) + +/** @brief Ensure that IRDA prescaler value is strictly larger than 0. + * @param __PRESCALER__ specifies the IRDA prescaler value set by the user. + * @retval True or False + */ +#define IS_IRDA_PRESCALER(__PRESCALER__) ((__PRESCALER__) > 0U) + +/** @brief Ensure that IRDA frame parity is valid. + * @param __PARITY__ IRDA frame parity. + * @retval SET (__PARITY__ is valid) or RESET (__PARITY__ is invalid) + */ +#define IS_IRDA_PARITY(__PARITY__) (((__PARITY__) == IRDA_PARITY_NONE) || \ + ((__PARITY__) == IRDA_PARITY_EVEN) || \ + ((__PARITY__) == IRDA_PARITY_ODD)) + +/** @brief Ensure that IRDA communication mode is valid. + * @param __MODE__ IRDA communication mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_IRDA_TX_RX_MODE(__MODE__) ((((__MODE__)\ + & (~((uint32_t)(IRDA_MODE_TX_RX)))) == 0x00U) && ((__MODE__) != 0x00U)) + +/** @brief Ensure that IRDA power mode is valid. + * @param __MODE__ IRDA power mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_IRDA_POWERMODE(__MODE__) (((__MODE__) == IRDA_POWERMODE_LOWPOWER) || \ + ((__MODE__) == IRDA_POWERMODE_NORMAL)) + +/** @brief Ensure that IRDA clock Prescaler is valid. + * @param __CLOCKPRESCALER__ IRDA clock Prescaler value. + * @retval SET (__CLOCKPRESCALER__ is valid) or RESET (__CLOCKPRESCALER__ is invalid) + */ +#define IS_IRDA_CLOCKPRESCALER(__CLOCKPRESCALER__) (((__CLOCKPRESCALER__) == IRDA_PRESCALER_DIV1) || \ + ((__CLOCKPRESCALER__) == IRDA_PRESCALER_DIV2) || \ + ((__CLOCKPRESCALER__) == IRDA_PRESCALER_DIV4) || \ + ((__CLOCKPRESCALER__) == IRDA_PRESCALER_DIV6) || \ + ((__CLOCKPRESCALER__) == IRDA_PRESCALER_DIV8) || \ + ((__CLOCKPRESCALER__) == IRDA_PRESCALER_DIV10) || \ + ((__CLOCKPRESCALER__) == IRDA_PRESCALER_DIV12) || \ + ((__CLOCKPRESCALER__) == IRDA_PRESCALER_DIV16) || \ + ((__CLOCKPRESCALER__) == IRDA_PRESCALER_DIV32) || \ + ((__CLOCKPRESCALER__) == IRDA_PRESCALER_DIV64) || \ + ((__CLOCKPRESCALER__) == IRDA_PRESCALER_DIV128) || \ + ((__CLOCKPRESCALER__) == IRDA_PRESCALER_DIV256)) + +/** @brief Ensure that IRDA state is valid. + * @param __STATE__ IRDA state mode. + * @retval SET (__STATE__ is valid) or RESET (__STATE__ is invalid) + */ +#define IS_IRDA_STATE(__STATE__) (((__STATE__) == IRDA_STATE_DISABLE) || \ + ((__STATE__) == IRDA_STATE_ENABLE)) + +/** @brief Ensure that IRDA associated UART/USART mode is valid. + * @param __MODE__ IRDA associated UART/USART mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_IRDA_MODE(__MODE__) (((__MODE__) == IRDA_MODE_DISABLE) || \ + ((__MODE__) == IRDA_MODE_ENABLE)) + +/** @brief Ensure that IRDA sampling rate is valid. + * @param __ONEBIT__ IRDA sampling rate. + * @retval SET (__ONEBIT__ is valid) or RESET (__ONEBIT__ is invalid) + */ +#define IS_IRDA_ONE_BIT_SAMPLE(__ONEBIT__) (((__ONEBIT__) == IRDA_ONE_BIT_SAMPLE_DISABLE) || \ + ((__ONEBIT__) == IRDA_ONE_BIT_SAMPLE_ENABLE)) + +/** @brief Ensure that IRDA DMA TX mode is valid. + * @param __DMATX__ IRDA DMA TX mode. + * @retval SET (__DMATX__ is valid) or RESET (__DMATX__ is invalid) + */ +#define IS_IRDA_DMA_TX(__DMATX__) (((__DMATX__) == IRDA_DMA_TX_DISABLE) || \ + ((__DMATX__) == IRDA_DMA_TX_ENABLE)) + +/** @brief Ensure that IRDA DMA RX mode is valid. + * @param __DMARX__ IRDA DMA RX mode. + * @retval SET (__DMARX__ is valid) or RESET (__DMARX__ is invalid) + */ +#define IS_IRDA_DMA_RX(__DMARX__) (((__DMARX__) == IRDA_DMA_RX_DISABLE) || \ + ((__DMARX__) == IRDA_DMA_RX_ENABLE)) + +/** @brief Ensure that IRDA request is valid. + * @param __PARAM__ IRDA request. + * @retval SET (__PARAM__ is valid) or RESET (__PARAM__ is invalid) + */ +#define IS_IRDA_REQUEST_PARAMETER(__PARAM__) (((__PARAM__) == IRDA_AUTOBAUD_REQUEST) || \ + ((__PARAM__) == IRDA_RXDATA_FLUSH_REQUEST) || \ + ((__PARAM__) == IRDA_TXDATA_FLUSH_REQUEST)) +/** + * @} + */ + +/* Include IRDA HAL Extended module */ +#include "stm32h5xx_hal_irda_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup IRDA_Exported_Functions IRDA Exported Functions + * @{ + */ + +/** @addtogroup IRDA_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ + +/* Initialization and de-initialization functions ****************************/ +HAL_StatusTypeDef HAL_IRDA_Init(IRDA_HandleTypeDef *hirda); +HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda); +void HAL_IRDA_MspInit(IRDA_HandleTypeDef *hirda); +void HAL_IRDA_MspDeInit(IRDA_HandleTypeDef *hirda); + +#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) +/* Callbacks Register/UnRegister functions ***********************************/ +HAL_StatusTypeDef HAL_IRDA_RegisterCallback(IRDA_HandleTypeDef *hirda, HAL_IRDA_CallbackIDTypeDef CallbackID, + pIRDA_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_IRDA_UnRegisterCallback(IRDA_HandleTypeDef *hirda, HAL_IRDA_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @addtogroup IRDA_Exported_Functions_Group2 IO operation functions + * @{ + */ + +/* IO operation functions *****************************************************/ +HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, const uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda, const uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_IRDA_Receive_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size); +#if defined(HAL_DMA_MODULE_ENABLED) +HAL_StatusTypeDef HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef *hirda, const uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_IRDA_DMAPause(IRDA_HandleTypeDef *hirda); +HAL_StatusTypeDef HAL_IRDA_DMAResume(IRDA_HandleTypeDef *hirda); +HAL_StatusTypeDef HAL_IRDA_DMAStop(IRDA_HandleTypeDef *hirda); +#endif /* HAL_DMA_MODULE_ENABLED */ +/* Transfer Abort functions */ +HAL_StatusTypeDef HAL_IRDA_Abort(IRDA_HandleTypeDef *hirda); +HAL_StatusTypeDef HAL_IRDA_AbortTransmit(IRDA_HandleTypeDef *hirda); +HAL_StatusTypeDef HAL_IRDA_AbortReceive(IRDA_HandleTypeDef *hirda); +HAL_StatusTypeDef HAL_IRDA_Abort_IT(IRDA_HandleTypeDef *hirda); +HAL_StatusTypeDef HAL_IRDA_AbortTransmit_IT(IRDA_HandleTypeDef *hirda); +HAL_StatusTypeDef HAL_IRDA_AbortReceive_IT(IRDA_HandleTypeDef *hirda); + +void HAL_IRDA_IRQHandler(IRDA_HandleTypeDef *hirda); +void HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef *hirda); +void HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef *hirda); +void HAL_IRDA_TxHalfCpltCallback(IRDA_HandleTypeDef *hirda); +void HAL_IRDA_RxHalfCpltCallback(IRDA_HandleTypeDef *hirda); +void HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef *hirda); +void HAL_IRDA_AbortCpltCallback(IRDA_HandleTypeDef *hirda); +void HAL_IRDA_AbortTransmitCpltCallback(IRDA_HandleTypeDef *hirda); +void HAL_IRDA_AbortReceiveCpltCallback(IRDA_HandleTypeDef *hirda); + +/** + * @} + */ + +/* Peripheral Control functions ************************************************/ + +/** @addtogroup IRDA_Exported_Functions_Group4 Peripheral State and Error functions + * @{ + */ + +/* Peripheral State and Error functions ***************************************/ +HAL_IRDA_StateTypeDef HAL_IRDA_GetState(const IRDA_HandleTypeDef *hirda); +uint32_t HAL_IRDA_GetError(const IRDA_HandleTypeDef *hirda); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_IRDA_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_irda_ex.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_irda_ex.h new file mode 100644 index 0000000000..3ba16b00ce --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_irda_ex.h @@ -0,0 +1,559 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_irda_ex.h + * @author MCD Application Team + * @brief Header file of IRDA HAL Extended module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_IRDA_EX_H +#define STM32H5xx_HAL_IRDA_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup IRDAEx IRDAEx + * @brief IRDA Extended HAL module driver + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup IRDAEx_Extended_Exported_Constants IRDAEx Extended Exported Constants + * @{ + */ + +/** @defgroup IRDAEx_Word_Length IRDAEx Word Length + * @{ + */ +#define IRDA_WORDLENGTH_7B USART_CR1_M1 /*!< 7-bit long frame */ +#define IRDA_WORDLENGTH_8B 0x00000000U /*!< 8-bit long frame */ +#define IRDA_WORDLENGTH_9B USART_CR1_M0 /*!< 9-bit long frame */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ + +/* Private macros ------------------------------------------------------------*/ + +/** @defgroup IRDAEx_Private_Macros IRDAEx Private Macros + * @{ + */ + +/** @brief Report the IRDA clock source. + * @param __HANDLE__ specifies the IRDA Handle. + * @param __CLOCKSOURCE__ output variable. + * @retval IRDA clocking source, written in __CLOCKSOURCE__. + */ +#if (defined(STM32H573xx) || defined(STM32H563xx) || defined(STM32H562xx)) +#define IRDA_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__) \ + do { \ + if((__HANDLE__)->Instance == USART1) \ + { \ + switch(__HAL_RCC_GET_USART1_SOURCE()) \ + { \ + case RCC_USART1CLKSOURCE_PCLK2: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PCLK2; \ + break; \ + case RCC_USART1CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART1CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART1CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_LSE; \ + break; \ + case RCC_USART1CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PLL2Q; \ + break; \ + case RCC_USART1CLKSOURCE_PLL3Q: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PLL3Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == USART2) \ + { \ + switch(__HAL_RCC_GET_USART2_SOURCE()) \ + { \ + case RCC_USART2CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_USART2CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART2CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART2CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_LSE; \ + break; \ + case RCC_USART2CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PLL2Q; \ + break; \ + case RCC_USART2CLKSOURCE_PLL3Q: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PLL3Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == USART3) \ + { \ + switch(__HAL_RCC_GET_USART3_SOURCE()) \ + { \ + case RCC_USART3CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_USART3CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART3CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART3CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_LSE; \ + break; \ + case RCC_USART3CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PLL2Q; \ + break; \ + case RCC_USART3CLKSOURCE_PLL3Q: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PLL3Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == UART4) \ + { \ + switch(__HAL_RCC_GET_UART4_SOURCE()) \ + { \ + case RCC_UART4CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_UART4CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_HSI; \ + break; \ + case RCC_UART4CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_CSI; \ + break; \ + case RCC_UART4CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_LSE; \ + break; \ + case RCC_UART4CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PLL2Q; \ + break; \ + case RCC_UART4CLKSOURCE_PLL3Q: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PLL3Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == UART5) \ + { \ + switch(__HAL_RCC_GET_UART5_SOURCE()) \ + { \ + case RCC_UART5CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_UART5CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_HSI; \ + break; \ + case RCC_UART5CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_CSI; \ + break; \ + case RCC_UART5CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_LSE; \ + break; \ + case RCC_UART5CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PLL2Q; \ + break; \ + case RCC_UART5CLKSOURCE_PLL3Q: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PLL3Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == USART6) \ + { \ + switch(__HAL_RCC_GET_USART6_SOURCE()) \ + { \ + case RCC_USART6CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_USART6CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART6CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART6CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_LSE; \ + break; \ + case RCC_USART6CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PLL2Q; \ + break; \ + case RCC_USART6CLKSOURCE_PLL3Q: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PLL3Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == UART7) \ + { \ + switch(__HAL_RCC_GET_UART7_SOURCE()) \ + { \ + case RCC_UART7CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_UART7CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_HSI; \ + break; \ + case RCC_UART7CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_CSI; \ + break; \ + case RCC_UART7CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_LSE; \ + break; \ + case RCC_UART7CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PLL2Q; \ + break; \ + case RCC_UART7CLKSOURCE_PLL3Q: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PLL3Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == UART8) \ + { \ + switch(__HAL_RCC_GET_UART8_SOURCE()) \ + { \ + case RCC_UART8CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_UART8CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_HSI; \ + break; \ + case RCC_UART8CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_CSI; \ + break; \ + case RCC_UART8CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_LSE; \ + break; \ + case RCC_UART8CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PLL2Q; \ + break; \ + case RCC_UART8CLKSOURCE_PLL3Q: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PLL3Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == UART9) \ + { \ + switch(__HAL_RCC_GET_UART9_SOURCE()) \ + { \ + case RCC_UART9CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_UART9CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_HSI; \ + break; \ + case RCC_UART9CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_CSI; \ + break; \ + case RCC_UART9CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_LSE; \ + break; \ + case RCC_UART9CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PLL2Q; \ + break; \ + case RCC_UART9CLKSOURCE_PLL3Q: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PLL3Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == USART10) \ + { \ + switch(__HAL_RCC_GET_USART10_SOURCE()) \ + { \ + case RCC_USART10CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_USART10CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART10CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART10CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_LSE; \ + break; \ + case RCC_USART10CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PLL2Q; \ + break; \ + case RCC_USART10CLKSOURCE_PLL3Q: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PLL3Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == USART11) \ + { \ + switch(__HAL_RCC_GET_USART11_SOURCE()) \ + { \ + case RCC_USART11CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_USART11CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART11CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART11CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_LSE; \ + break; \ + case RCC_USART11CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PLL2Q; \ + break; \ + case RCC_USART11CLKSOURCE_PLL3Q: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PLL3Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == UART12) \ + { \ + switch(__HAL_RCC_GET_UART12_SOURCE()) \ + { \ + case RCC_UART12CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_UART12CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_HSI; \ + break; \ + case RCC_UART12CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_CSI; \ + break; \ + case RCC_UART12CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_LSE; \ + break; \ + case RCC_UART12CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PLL2Q; \ + break; \ + case RCC_UART12CLKSOURCE_PLL3Q: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PLL3Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else \ + { \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_UNDEFINED; \ + } \ + } while(0U) +#else +#define IRDA_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__) \ + do { \ + if((__HANDLE__)->Instance == USART1) \ + { \ + switch(__HAL_RCC_GET_USART1_SOURCE()) \ + { \ + case RCC_USART1CLKSOURCE_PCLK2: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PCLK2; \ + break; \ + case RCC_USART1CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART1CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART1CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_LSE; \ + break; \ + case RCC_USART1CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PLL2Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == USART2) \ + { \ + switch(__HAL_RCC_GET_USART2_SOURCE()) \ + { \ + case RCC_USART2CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_USART2CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART2CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART2CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_LSE; \ + break; \ + case RCC_USART2CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PLL2Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == USART3) \ + { \ + switch(__HAL_RCC_GET_USART3_SOURCE()) \ + { \ + case RCC_USART3CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_USART3CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART3CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART3CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_LSE; \ + break; \ + case RCC_USART3CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_PLL2Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else \ + { \ + (__CLOCKSOURCE__) = IRDA_CLOCKSOURCE_UNDEFINED; \ + } \ + } while(0U) + +#endif /* (defined(STM32H573xx) || defined(STM32H563xx) || defined(STM32H562xx) */ + +/** @brief Compute the mask to apply to retrieve the received data + * according to the word length and to the parity bits activation. + * @param __HANDLE__ specifies the IRDA Handle. + * @retval None, the mask to apply to the associated UART RDR register is stored in (__HANDLE__)->Mask field. + */ +#define IRDA_MASK_COMPUTATION(__HANDLE__) \ + do { \ + if ((__HANDLE__)->Init.WordLength == IRDA_WORDLENGTH_9B) \ + { \ + if ((__HANDLE__)->Init.Parity == IRDA_PARITY_NONE) \ + { \ + (__HANDLE__)->Mask = 0x01FFU ; \ + } \ + else \ + { \ + (__HANDLE__)->Mask = 0x00FFU ; \ + } \ + } \ + else if ((__HANDLE__)->Init.WordLength == IRDA_WORDLENGTH_8B) \ + { \ + if ((__HANDLE__)->Init.Parity == IRDA_PARITY_NONE) \ + { \ + (__HANDLE__)->Mask = 0x00FFU ; \ + } \ + else \ + { \ + (__HANDLE__)->Mask = 0x007FU ; \ + } \ + } \ + else if ((__HANDLE__)->Init.WordLength == IRDA_WORDLENGTH_7B) \ + { \ + if ((__HANDLE__)->Init.Parity == IRDA_PARITY_NONE) \ + { \ + (__HANDLE__)->Mask = 0x007FU ; \ + } \ + else \ + { \ + (__HANDLE__)->Mask = 0x003FU ; \ + } \ + } \ + else \ + { \ + (__HANDLE__)->Mask = 0x0000U; \ + } \ + } while(0U) + +/** @brief Ensure that IRDA frame length is valid. + * @param __LENGTH__ IRDA frame length. + * @retval SET (__LENGTH__ is valid) or RESET (__LENGTH__ is invalid) + */ +#define IS_IRDA_WORD_LENGTH(__LENGTH__) (((__LENGTH__) == IRDA_WORDLENGTH_7B) || \ + ((__LENGTH__) == IRDA_WORDLENGTH_8B) || \ + ((__LENGTH__) == IRDA_WORDLENGTH_9B)) +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_IRDA_EX_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_iwdg.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_iwdg.h new file mode 100644 index 0000000000..089469c78f --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_iwdg.h @@ -0,0 +1,302 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_iwdg.h + * @author MCD Application Team + * @brief Header file of IWDG HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_IWDG_H +#define STM32H5xx_HAL_IWDG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup IWDG IWDG + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup IWDG_Exported_Types IWDG Exported Types + * @{ + */ + +/** + * @brief IWDG Init structure definition + */ +typedef struct +{ + uint32_t Prescaler; /*!< Select the prescaler of the IWDG. + This parameter can be a value of @ref IWDG_Prescaler */ + + uint32_t Reload; /*!< Specifies the IWDG down-counter reload value. + This parameter must be a number between Min_Data = 0 and Max_Data = 0x0FFF */ + + uint32_t Window; /*!< Specifies the window value to be compared to the down-counter. + This parameter must be a number between Min_Data = 0 and Max_Data = 0x0FFF */ + + uint32_t EWI; /*!< Specifies if IWDG Early Wakeup Interrupt is enable or not and the comparator value. + This parameter must be a number between Min_Data = 0 and Max_Data = 0x0FFF + value 0 means that EWI is disabled */ +} IWDG_InitTypeDef; + +/** + * @brief IWDG Handle Structure definition + */ +#if (USE_HAL_IWDG_REGISTER_CALLBACKS == 1) +typedef struct __IWDG_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_IWDG_REGISTER_CALLBACKS */ +{ + IWDG_TypeDef *Instance; /*!< Register base address */ + + IWDG_InitTypeDef Init; /*!< IWDG required parameters */ + +#if (USE_HAL_IWDG_REGISTER_CALLBACKS == 1) + void (* EwiCallback)(struct __IWDG_HandleTypeDef *hiwdg); /*!< IWDG Early WakeUp Interrupt callback */ + void (* MspInitCallback)(struct __IWDG_HandleTypeDef *hiwdg); /*!< IWDG Msp Init callback */ +#endif /* USE_HAL_IWDG_REGISTER_CALLBACKS */ +} IWDG_HandleTypeDef; + +#if (USE_HAL_IWDG_REGISTER_CALLBACKS == 1) +/** + * @brief HAL IWDG common Callback ID enumeration definition + */ +typedef enum +{ + HAL_IWDG_EWI_CB_ID = 0x00U, /*!< IWDG EWI callback ID */ + HAL_IWDG_MSPINIT_CB_ID = 0x01U, /*!< IWDG MspInit callback ID */ +} HAL_IWDG_CallbackIDTypeDef; + +/** + * @brief HAL IWDG Callback pointer definition + */ +typedef void (*pIWDG_CallbackTypeDef)(IWDG_HandleTypeDef *hppp); /*!< pointer to a IWDG common callback functions */ +#endif /* USE_HAL_IWDG_REGISTER_CALLBACKS */ + + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup IWDG_Exported_Constants IWDG Exported Constants + * @{ + */ + +/** @defgroup IWDG_Prescaler IWDG Prescaler + * @{ + */ +#define IWDG_PRESCALER_4 0x00000000u /*!< IWDG prescaler set to 4 */ +#define IWDG_PRESCALER_8 IWDG_PR_PR_0 /*!< IWDG prescaler set to 8 */ +#define IWDG_PRESCALER_16 IWDG_PR_PR_1 /*!< IWDG prescaler set to 16 */ +#define IWDG_PRESCALER_32 (IWDG_PR_PR_1 | IWDG_PR_PR_0) /*!< IWDG prescaler set to 32 */ +#define IWDG_PRESCALER_64 IWDG_PR_PR_2 /*!< IWDG prescaler set to 64 */ +#define IWDG_PRESCALER_128 (IWDG_PR_PR_2 | IWDG_PR_PR_0) /*!< IWDG prescaler set to 128 */ +#define IWDG_PRESCALER_256 (IWDG_PR_PR_2 | IWDG_PR_PR_1) /*!< IWDG prescaler set to 256 */ +#define IWDG_PRESCALER_512 (IWDG_PR_PR_2 | IWDG_PR_PR_1 | IWDG_PR_PR_0) /*!< IWDG prescaler set to 512 */ +#define IWDG_PRESCALER_1024 IWDG_PR_PR_3 /*!< IWDG prescaler set to 1024 */ +/** + * @} + */ + +/** @defgroup IWDG_Window_option IWDG Window option + * @{ + */ +#define IWDG_WINDOW_DISABLE IWDG_WINR_WIN +/** + * @} + */ + +/** @defgroup IWDG_EWI_Mode IWDG Early Wakeup Interrupt Mode + * @{ + */ +#define IWDG_EWI_DISABLE 0x00000000u /*!< EWI Disable */ +/** + * @} + */ + +/** @defgroup IWDG_Active_Status IWDG Active Status + * @{ + */ +#define IWDG_STATUS_DISABLE 0x00000000u +#define IWDG_STATUS_ENABLE IWDG_SR_ONF +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup IWDG_Exported_Macros IWDG Exported Macros + * @{ + */ + +/** + * @brief Enable the IWDG peripheral. + * @param __HANDLE__ IWDG handle + * @retval None + */ +#define __HAL_IWDG_START(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_ENABLE) + +/** + * @brief Reload IWDG counter with value defined in the reload register + * (write access to IWDG_PR, IWDG_RLR, IWDG_WINR and EWCR registers disabled). + * @param __HANDLE__ IWDG handle + * @retval None + */ +#define __HAL_IWDG_RELOAD_COUNTER(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_RELOAD) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup IWDG_Exported_Functions IWDG Exported Functions + * @{ + */ + +/** @defgroup IWDG_Exported_Functions_Group1 Initialization and Start functions + * @{ + */ +/* Initialization/Start functions ********************************************/ +HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg); +void HAL_IWDG_MspInit(IWDG_HandleTypeDef *hiwdg); +/* Callbacks Register/UnRegister functions ***********************************/ +#if (USE_HAL_IWDG_REGISTER_CALLBACKS == 1) +HAL_StatusTypeDef HAL_IWDG_RegisterCallback(IWDG_HandleTypeDef *hiwdg, HAL_IWDG_CallbackIDTypeDef CallbackID, + pIWDG_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_IWDG_UnRegisterCallback(IWDG_HandleTypeDef *hiwdg, HAL_IWDG_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_IWDG_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @defgroup IWDG_Exported_Functions_Group2 IO operation functions + * @{ + */ +/* I/O operation functions ****************************************************/ +HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg); +uint32_t HAL_IWDG_GetActiveStatus(const IWDG_HandleTypeDef *hiwdg); +void HAL_IWDG_IRQHandler(IWDG_HandleTypeDef *hiwdg); +void HAL_IWDG_EarlyWakeupCallback(IWDG_HandleTypeDef *hiwdg); +/** + * @} + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup IWDG_Private_Constants IWDG Private Constants + * @{ + */ + +/** + * @brief IWDG Key Register BitMask + */ +#define IWDG_KEY_RELOAD 0x0000AAAAu /*!< IWDG Reload Counter Enable */ +#define IWDG_KEY_ENABLE 0x0000CCCCu /*!< IWDG Peripheral Enable */ +#define IWDG_KEY_WRITE_ACCESS_ENABLE 0x00005555u /*!< IWDG KR Write Access Enable */ +#define IWDG_KEY_WRITE_ACCESS_DISABLE 0x00000000u /*!< IWDG KR Write Access Disable */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup IWDG_Private_Macros IWDG Private Macros + * @{ + */ + +/** + * @brief Enable write access to IWDG_PR, IWDG_RLR, IWDG_WINR and EWCR registers. + * @param __HANDLE__ IWDG handle + * @retval None + */ +#define IWDG_ENABLE_WRITE_ACCESS(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_WRITE_ACCESS_ENABLE) + +/** + * @brief Disable write access to IWDG_PR, IWDG_RLR, IWDG_WINR and EWCR registers. + * @param __HANDLE__ IWDG handle + * @retval None + */ +#define IWDG_DISABLE_WRITE_ACCESS(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_WRITE_ACCESS_DISABLE) + +/** + * @brief Check IWDG prescaler value. + * @param __PRESCALER__ IWDG prescaler value + * @retval None + */ +#define IS_IWDG_PRESCALER(__PRESCALER__) (((__PRESCALER__) == IWDG_PRESCALER_4) || \ + ((__PRESCALER__) == IWDG_PRESCALER_8) || \ + ((__PRESCALER__) == IWDG_PRESCALER_16) || \ + ((__PRESCALER__) == IWDG_PRESCALER_32) || \ + ((__PRESCALER__) == IWDG_PRESCALER_64) || \ + ((__PRESCALER__) == IWDG_PRESCALER_128)|| \ + ((__PRESCALER__) == IWDG_PRESCALER_256)|| \ + ((__PRESCALER__) == IWDG_PRESCALER_512)|| \ + ((__PRESCALER__) == IWDG_PRESCALER_1024)) + +/** + * @brief Check IWDG reload value. + * @param __RELOAD__ IWDG reload value + * @retval None + */ +#define IS_IWDG_RELOAD(__RELOAD__) ((__RELOAD__) <= IWDG_RLR_RL) + +/** + * @brief Check IWDG window value. + * @param __WINDOW__ IWDG window value + * @retval None + */ +#define IS_IWDG_WINDOW(__WINDOW__) ((__WINDOW__) <= IWDG_WINR_WIN) + +/** + * @brief Check IWDG ewi value. + * @param __EWI__ IWDG ewi value + * @retval None + */ +#define IS_IWDG_EWI(__EWI__) ((__EWI__) <= IWDG_EWCR_EWIT) + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_IWDG_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_lptim.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_lptim.h new file mode 100644 index 0000000000..1b44d0d088 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_lptim.h @@ -0,0 +1,1285 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_lptim.h + * @author MCD Application Team + * @brief Header file of LPTIM HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_LPTIM_H +#define STM32H5xx_HAL_LPTIM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/* Include low level driver */ +#include "stm32h5xx_ll_lptim.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +#if defined (LPTIM1) || defined (LPTIM2) || defined (LPTIM3) || defined (LPTIM4) || defined (LPTIM5) || defined (LPTIM6) + +/** @addtogroup LPTIM + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup LPTIM_Exported_Types LPTIM Exported Types + * @{ + */ + +/** + * @brief LPTIM Clock configuration definition + */ +typedef struct +{ + uint32_t Source; /*!< Selects the clock source. + This parameter can be a value of @ref LPTIM_Clock_Source */ + + uint32_t Prescaler; /*!< Specifies the counter clock Prescaler. + This parameter can be a value of @ref LPTIM_Clock_Prescaler */ + +} LPTIM_ClockConfigTypeDef; + +/** + * @brief LPTIM Clock configuration definition + */ +typedef struct +{ + uint32_t Polarity; /*!< Selects the polarity of the active edge for the counter unit + if the ULPTIM input is selected. + Note: This parameter is used only when Ultra low power clock source is used. + Note: If the polarity is configured on 'both edges', an auxiliary clock + (one of the Low power oscillator) must be active. + This parameter can be a value of @ref LPTIM_Clock_Polarity */ + + uint32_t SampleTime; /*!< Selects the clock sampling time to configure the clock glitch filter. + Note: This parameter is used only when Ultra low power clock source is used. + This parameter can be a value of @ref LPTIM_Clock_Sample_Time */ + +} LPTIM_ULPClockConfigTypeDef; + +/** + * @brief LPTIM Trigger configuration definition + */ +typedef struct +{ + uint32_t Source; /*!< Selects the Trigger source. + This parameter can be a value of @ref LPTIM_Trigger_Source */ + + uint32_t ActiveEdge; /*!< Selects the Trigger active edge. + Note: This parameter is used only when an external trigger is used. + This parameter can be a value of @ref LPTIM_External_Trigger_Polarity */ + + uint32_t SampleTime; /*!< Selects the trigger sampling time to configure the clock glitch filter. + Note: This parameter is used only when an external trigger is used. + This parameter can be a value of @ref LPTIM_Trigger_Sample_Time */ +} LPTIM_TriggerConfigTypeDef; + +/** + * @brief LPTIM Initialization Structure definition + */ +typedef struct +{ + LPTIM_ClockConfigTypeDef Clock; /*!< Specifies the clock parameters */ + + LPTIM_ULPClockConfigTypeDef UltraLowPowerClock;/*!< Specifies the Ultra Low Power clock parameters */ + + LPTIM_TriggerConfigTypeDef Trigger; /*!< Specifies the Trigger parameters */ + + uint32_t Period; /*!< Specifies the period value to be loaded into the active + Auto-Reload Register at the next update event. + This parameter can be a number between + Min_Data = 0x0001 and Max_Data = 0xFFFF. */ + + uint32_t UpdateMode; /*!< Specifies whether the update of the autoreload and the compare + values is done immediately or after the end of current period. + This parameter can be a value of @ref LPTIM_Updating_Mode */ + + uint32_t CounterSource; /*!< Specifies whether the counter is incremented each internal event + or each external event. + This parameter can be a value of @ref LPTIM_Counter_Source */ + + uint32_t Input1Source; /*!< Specifies source selected for input1 (GPIO or comparator output). + This parameter can be a value of @ref LPTIM_Input1_Source */ + + uint32_t Input2Source; /*!< Specifies source selected for input2 (GPIO or comparator output). + Note: This parameter is used only for encoder feature so is used only + for LPTIM1 instance. + This parameter can be a value of @ref LPTIM_Input2_Source */ + + uint32_t RepetitionCounter;/*!< Specifies the repetition counter value. + Each time the RCR downcounter reaches zero, an update event is + generated and counting restarts from the RCR value (N). + Note: When using repetition counter the UpdateMode field must be + set to LPTIM_UPDATE_ENDOFPERIOD otherwise unpredictable + behavior may occur. + This parameter must be a number between Min_Data = 0x00 and + Max_Data = 0xFF. */ +} LPTIM_InitTypeDef; + +/** + * @brief LPTIM Output Compare Configuration Structure definition + */ +typedef struct +{ + uint32_t Pulse; /*!< Specifies the pulse value to be loaded into the Capture Compare Register. + This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */ + uint32_t OCPolarity; /*!< Specifies the output polarity. + This parameter can be a value of @ref LPTIM_Output_Compare_Polarity */ +} LPTIM_OC_ConfigTypeDef; + +/** + * @brief LPTIM Input Capture Configuration Structure definition + */ +typedef struct +{ + uint32_t ICInputSource; /*!< Specifies source selected for IC channel. + This parameter can be a value of @ref LPTIM_Input_Capture_Source */ + + uint32_t ICPrescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref LPTIM_Input_Capture_Prescaler */ + + uint32_t ICPolarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref LPTIM_Input_Capture_Polarity */ + + uint32_t ICFilter; /*!< Specifies the input capture filter. + This parameter can be a value of @ref LPTIM_Input_Capture_Filter */ +} LPTIM_IC_ConfigTypeDef; + +/** + * @brief HAL LPTIM State structure definition + */ +typedef enum +{ + HAL_LPTIM_STATE_RESET = 0x00U, /*!< Peripheral not yet initialized or disabled */ + HAL_LPTIM_STATE_READY = 0x01U, /*!< Peripheral Initialized and ready for use */ + HAL_LPTIM_STATE_BUSY = 0x02U, /*!< An internal process is ongoing */ + HAL_LPTIM_STATE_TIMEOUT = 0x03U, /*!< Timeout state */ + HAL_LPTIM_STATE_ERROR = 0x04U /*!< Internal Process is ongoing */ +} HAL_LPTIM_StateTypeDef; + +/** + * @brief HAL Active channel structures definition + */ +typedef enum +{ + HAL_LPTIM_ACTIVE_CHANNEL_1 = 0x01U, /*!< The active channel is 1 */ + HAL_LPTIM_ACTIVE_CHANNEL_2 = 0x02U, /*!< The active channel is 2 */ + HAL_LPTIM_ACTIVE_CHANNEL_CLEARED = 0x00U /*!< All active channels cleared */ +} HAL_LPTIM_ActiveChannel; + +/** + * @brief LPTIM Channel States definition + */ +typedef enum +{ + HAL_LPTIM_CHANNEL_STATE_RESET = 0x00U, /*!< LPTIM Channel initial state */ + HAL_LPTIM_CHANNEL_STATE_READY = 0x01U, /*!< LPTIM Channel ready for use */ + HAL_LPTIM_CHANNEL_STATE_BUSY = 0x02U, /*!< An internal process is ongoing on the LPTIM channel */ +} HAL_LPTIM_ChannelStateTypeDef; + +/** + * @brief LPTIM handle Structure definition + */ +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) +typedef struct __LPTIM_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ +{ + LPTIM_TypeDef *Instance; /*!< Register base address */ + + LPTIM_InitTypeDef Init; /*!< LPTIM required parameters */ + + HAL_LPTIM_ActiveChannel Channel; /*!< Active channel */ + + DMA_HandleTypeDef *hdma[3]; /*!< DMA Handlers array, This array is accessed by a @ref LPTIM_DMA_Handle_index */ + + HAL_StatusTypeDef Status; /*!< LPTIM peripheral status */ + + HAL_LockTypeDef Lock; /*!< LPTIM locking object */ + + __IO HAL_LPTIM_StateTypeDef State; /*!< LPTIM peripheral state */ + + __IO HAL_LPTIM_ChannelStateTypeDef ChannelState[2]; /*!< LPTIM channel operation state */ +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) + void (* MspInitCallback)(struct __LPTIM_HandleTypeDef *hlptim); /*!< LPTIM Base Msp Init Callback */ + void (* MspDeInitCallback)(struct __LPTIM_HandleTypeDef *hlptim); /*!< LPTIM Base Msp DeInit Callback */ + void (* CompareMatchCallback)(struct __LPTIM_HandleTypeDef *hlptim); /*!< Compare match Callback */ + void (* AutoReloadMatchCallback)(struct __LPTIM_HandleTypeDef *hlptim); /*!< Auto-reload match Callback */ + void (* TriggerCallback)(struct __LPTIM_HandleTypeDef *hlptim); /*!< External trigger event detection Callback */ + void (* CompareWriteCallback)(struct __LPTIM_HandleTypeDef *hlptim); /*!< Compare register write complete Callback */ + void (* AutoReloadWriteCallback)(struct __LPTIM_HandleTypeDef *hlptim); /*!< Auto-reload register write complete Callback */ + void (* DirectionUpCallback)(struct __LPTIM_HandleTypeDef *hlptim); /*!< Up-counting direction change Callback */ + void (* DirectionDownCallback)(struct __LPTIM_HandleTypeDef *hlptim); /*!< Down-counting direction change Callback */ + void (* UpdateEventCallback)(struct __LPTIM_HandleTypeDef *hlptim); /*!< Update event detection Callback */ + void (* RepCounterWriteCallback)(struct __LPTIM_HandleTypeDef *hlptim); /*!< Repetition counter register write complete Callback */ + void (* UpdateEventHalfCpltCallback)(struct __LPTIM_HandleTypeDef *hlptim);/*!< Update event half complete detection Callback */ + void (* ErrorCallback)(struct __LPTIM_HandleTypeDef *hlptim); /*!< LPTIM Error Callback */ + void (* IC_CaptureCallback)(struct __LPTIM_HandleTypeDef *hlptim); /*!< Input capture Callback */ + void (* IC_CaptureHalfCpltCallback)(struct __LPTIM_HandleTypeDef *htim); /*!< Input Capture half complete Callback */ + void (* IC_OverCaptureCallback)(struct __LPTIM_HandleTypeDef *hlptim); /*!< Over capture Callback */ +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ +} LPTIM_HandleTypeDef; + +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) +/** + * @brief HAL LPTIM Callback ID enumeration definition + */ +typedef enum +{ + HAL_LPTIM_MSPINIT_CB_ID = 0x00U, /*!< LPTIM Base Msp Init Callback ID */ + HAL_LPTIM_MSPDEINIT_CB_ID = 0x01U, /*!< LPTIM Base Msp DeInit Callback ID */ + HAL_LPTIM_COMPARE_MATCH_CB_ID = 0x02U, /*!< Compare match Callback ID */ + HAL_LPTIM_AUTORELOAD_MATCH_CB_ID = 0x03U, /*!< Auto-reload match Callback ID */ + HAL_LPTIM_TRIGGER_CB_ID = 0x04U, /*!< External trigger event detection Callback ID */ + HAL_LPTIM_COMPARE_WRITE_CB_ID = 0x05U, /*!< Compare register write complete Callback ID */ + HAL_LPTIM_AUTORELOAD_WRITE_CB_ID = 0x06U, /*!< Auto-reload register write complete Callback ID */ + HAL_LPTIM_DIRECTION_UP_CB_ID = 0x07U, /*!< Up-counting direction change Callback ID */ + HAL_LPTIM_DIRECTION_DOWN_CB_ID = 0x08U, /*!< Down-counting direction change Callback ID */ + HAL_LPTIM_UPDATE_EVENT_CB_ID = 0x09U, /*!< Update event detection Callback ID */ + HAL_LPTIM_REP_COUNTER_WRITE_CB_ID = 0x0AU, /*!< Repetition counter register write complete Callback ID */ + HAL_LPTIM_UPDATE_EVENT_HALF_CB_ID = 0x0BU, /*!< Update event half complete detection Callback ID */ + HAL_LPTIM_ERROR_CB_ID = 0x0CU, /*!< LPTIM Error Callback ID */ + HAL_LPTIM_IC_CAPTURE_CB_ID = 0x0DU, /*!< Input capture Callback ID */ + HAL_LPTIM_IC_CAPTURE_HALF_CB_ID = 0x0EU, /*!< Input capture half complete Callback ID */ + HAL_LPTIM_OVER_CAPTURE_CB_ID = 0x0FU, /*!< Over capture Callback ID */ +} HAL_LPTIM_CallbackIDTypeDef; + +/** + * @brief HAL TIM Callback pointer definition + */ +typedef void (*pLPTIM_CallbackTypeDef)(LPTIM_HandleTypeDef *hlptim); /*!< pointer to the LPTIM callback function */ + +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup LPTIM_Exported_Constants LPTIM Exported Constants + * @{ + */ + +/** @defgroup LPTIM_Clock_Source LPTIM Clock Source + * @{ + */ +#define LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC 0x00000000U +#define LPTIM_CLOCKSOURCE_ULPTIM LPTIM_CFGR_CKSEL +/** + * @} + */ + +/** @defgroup LPTIM_Clock_Prescaler LPTIM Clock Prescaler + * @{ + */ +#define LPTIM_PRESCALER_DIV1 0x00000000U +#define LPTIM_PRESCALER_DIV2 LPTIM_CFGR_PRESC_0 +#define LPTIM_PRESCALER_DIV4 LPTIM_CFGR_PRESC_1 +#define LPTIM_PRESCALER_DIV8 (LPTIM_CFGR_PRESC_0 | LPTIM_CFGR_PRESC_1) +#define LPTIM_PRESCALER_DIV16 LPTIM_CFGR_PRESC_2 +#define LPTIM_PRESCALER_DIV32 (LPTIM_CFGR_PRESC_0 | LPTIM_CFGR_PRESC_2) +#define LPTIM_PRESCALER_DIV64 (LPTIM_CFGR_PRESC_1 | LPTIM_CFGR_PRESC_2) +#define LPTIM_PRESCALER_DIV128 LPTIM_CFGR_PRESC +/** + * @} + */ + +/** @defgroup LPTIM_Clock_Sample_Time LPTIM Clock Sample Time + * @{ + */ +#define LPTIM_CLOCKSAMPLETIME_DIRECTTRANSITION 0x00000000U +#define LPTIM_CLOCKSAMPLETIME_2TRANSITIONS LPTIM_CFGR_CKFLT_0 +#define LPTIM_CLOCKSAMPLETIME_4TRANSITIONS LPTIM_CFGR_CKFLT_1 +#define LPTIM_CLOCKSAMPLETIME_8TRANSITIONS LPTIM_CFGR_CKFLT +/** + * @} + */ + +/** @defgroup LPTIM_Clock_Polarity LPTIM Clock Polarity + * @{ + */ +#define LPTIM_CLOCKPOLARITY_RISING 0x00000000U +#define LPTIM_CLOCKPOLARITY_FALLING LPTIM_CFGR_CKPOL_0 +#define LPTIM_CLOCKPOLARITY_RISING_FALLING LPTIM_CFGR_CKPOL_1 +/** + * @} + */ + +/** @defgroup LPTIM_Trigger_Source LPTIM Trigger Source + * @{ + */ +#define LPTIM_TRIGSOURCE_SOFTWARE 0x0000FFFFU +#define LPTIM_TRIGSOURCE_0 0x00000000U +#define LPTIM_TRIGSOURCE_1 LPTIM_CFGR_TRIGSEL_0 +#define LPTIM_TRIGSOURCE_2 LPTIM_CFGR_TRIGSEL_1 +#define LPTIM_TRIGSOURCE_3 (LPTIM_CFGR_TRIGSEL_0 | LPTIM_CFGR_TRIGSEL_1) +#define LPTIM_TRIGSOURCE_4 LPTIM_CFGR_TRIGSEL_2 +#define LPTIM_TRIGSOURCE_5 (LPTIM_CFGR_TRIGSEL_0 | LPTIM_CFGR_TRIGSEL_2) +#define LPTIM_TRIGSOURCE_6 (LPTIM_CFGR_TRIGSEL_1 | LPTIM_CFGR_TRIGSEL_2) +#define LPTIM_TRIGSOURCE_7 LPTIM_CFGR_TRIGSEL +/** + * @} + */ + +/** @defgroup LPTIM_External_Trigger_Polarity LPTIM External Trigger Polarity + * @{ + */ +#define LPTIM_ACTIVEEDGE_RISING LPTIM_CFGR_TRIGEN_0 +#define LPTIM_ACTIVEEDGE_FALLING LPTIM_CFGR_TRIGEN_1 +#define LPTIM_ACTIVEEDGE_RISING_FALLING LPTIM_CFGR_TRIGEN +/** + * @} + */ + +/** @defgroup LPTIM_Trigger_Sample_Time LPTIM Trigger Sample Time + * @{ + */ +#define LPTIM_TRIGSAMPLETIME_DIRECTTRANSITION 0x00000000U +#define LPTIM_TRIGSAMPLETIME_2TRANSITIONS LPTIM_CFGR_TRGFLT_0 +#define LPTIM_TRIGSAMPLETIME_4TRANSITIONS LPTIM_CFGR_TRGFLT_1 +#define LPTIM_TRIGSAMPLETIME_8TRANSITIONS LPTIM_CFGR_TRGFLT +/** + * @} + */ + +/** @defgroup LPTIM_Updating_Mode LPTIM Updating Mode + * @{ + */ + +#define LPTIM_UPDATE_IMMEDIATE 0x00000000U +#define LPTIM_UPDATE_ENDOFPERIOD LPTIM_CFGR_PRELOAD +/** + * @} + */ + +/** @defgroup LPTIM_Counter_Source LPTIM Counter Source + * @{ + */ + +#define LPTIM_COUNTERSOURCE_INTERNAL 0x00000000U +#define LPTIM_COUNTERSOURCE_EXTERNAL LPTIM_CFGR_COUNTMODE +/** + * @} + */ + +/** @defgroup LPTIM_Input1_Source LPTIM Input1 Source + * @{ + */ + +#define LPTIM_INPUT1SOURCE_GPIO 0x00000000U /*!< For LPTIM1, LPTIM2, LPTIM3, LPTIM4, LPTIM5 and LPTIM6*/ +#if defined(STM32H503xx) +#define LPTIM_INPUT1SOURCE_COMP1 LPTIM_CFGR2_IN1SEL_0 /*!< For LPTIM1 and LPTIM2 */ +#define LPTIM_INPUT1SOURCE_LPTIM2_CH1 LPTIM_CFGR2_IN1SEL_1 /*!< For LPTIM1 */ +#define LPTIM_INPUT1SOURCE_LPTIM1_CH2 LPTIM_CFGR2_IN1SEL_1 /*!< For LPTIM2 */ +#endif /* STM32H503xx */ +/** + * @} + */ + +/** @defgroup LPTIM_Input2_Source LPTIM Input2 Source + * @{ + */ + +#define LPTIM_INPUT2SOURCE_GPIO 0x00000000U /*!< For LPTIM1, LPTIM2, LPTIM3, LPTIM4, LPTIM5 and LPTIM6 */ +/** + * @} + */ + +/** @defgroup LPTIM_Flag_Definition LPTIM Flags Definition + * @{ + */ + +#define LPTIM_FLAG_CC1O LPTIM_ISR_CC1OF +#define LPTIM_FLAG_CC2O LPTIM_ISR_CC2OF +#define LPTIM_FLAG_CC1 LPTIM_ISR_CC1IF +#define LPTIM_FLAG_CC2 LPTIM_ISR_CC2IF +#define LPTIM_FLAG_CMP1OK LPTIM_ISR_CMP1OK +#define LPTIM_FLAG_CMP2OK LPTIM_ISR_CMP2OK +#define LPTIM_FLAG_DIEROK LPTIM_ISR_DIEROK +#define LPTIM_FLAG_REPOK LPTIM_ISR_REPOK +#define LPTIM_FLAG_UPDATE LPTIM_ISR_UE +#define LPTIM_FLAG_DOWN LPTIM_ISR_DOWN +#define LPTIM_FLAG_UP LPTIM_ISR_UP +#define LPTIM_FLAG_ARROK LPTIM_ISR_ARROK +#define LPTIM_FLAG_EXTTRIG LPTIM_ISR_EXTTRIG +#define LPTIM_FLAG_ARRM LPTIM_ISR_ARRM +/** + * @} + */ + +/** @defgroup LPTIM_DMA_sources LPTIM DMA Sources + * @{ + */ +#define LPTIM_DMA_UPDATE LPTIM_DIER_UEDE /*!< DMA request is triggered by the update event */ +#define LPTIM_DMA_CC1 LPTIM_DIER_CC1DE /*!< DMA request is triggered by the capture 1 event */ +#define LPTIM_DMA_CC2 LPTIM_DIER_CC2DE /*!< DMA request is triggered by the capture 2 event */ + +/** + * @} + */ + +/** @defgroup LPTIM_DMA_Handle_index LPTIM DMA Handle Index + * @{ + */ +#define LPTIM_DMA_ID_UPDATE ((uint16_t) 0x0000) /*!< Index of the DMA handle used for Update DMA requests */ +#define LPTIM_DMA_ID_CC1 ((uint16_t) 0x0001) /*!< Index of the DMA handle used for Capture/Update event 1 DMA request */ +#define LPTIM_DMA_ID_CC2 ((uint16_t) 0x0002) /*!< Index of the DMA handle used for Capture/Update event 2 DMA request */ +/** + * @} + */ + +/** @defgroup LPTIM_Interrupts_Definition LPTIM Interrupts Definition + * @{ + */ +#define LPTIM_IT_CC1O LPTIM_DIER_CC1OIE +#define LPTIM_IT_CC2O LPTIM_DIER_CC2OIE +#define LPTIM_IT_CC1 LPTIM_DIER_CC1IE +#define LPTIM_IT_CC2 LPTIM_DIER_CC2IE +#define LPTIM_IT_CMP1OK LPTIM_DIER_CMP1OKIE +#define LPTIM_IT_CMP2OK LPTIM_DIER_CMP2OKIE +#define LPTIM_IT_REPOK LPTIM_DIER_REPOKIE +#define LPTIM_IT_UPDATE LPTIM_DIER_UEIE +#define LPTIM_IT_DOWN LPTIM_DIER_DOWNIE +#define LPTIM_IT_UP LPTIM_DIER_UPIE +#define LPTIM_IT_ARROK LPTIM_DIER_ARROKIE +#define LPTIM_IT_EXTTRIG LPTIM_DIER_EXTTRIGIE +#define LPTIM_IT_ARRM LPTIM_DIER_ARRMIE +/** + * @} + */ + +/** @defgroup LPTIM_Channel LPTIM Channel + * @{ + */ +#define LPTIM_CHANNEL_1 LL_LPTIM_CHANNEL_CH1 /*!< Capture/compare channel 1 identifier */ +#define LPTIM_CHANNEL_2 LL_LPTIM_CHANNEL_CH2 /*!< Capture/compare channel 2 identifier */ +/** + * @} + */ + +/** @defgroup LPTIM_Output_Compare_Polarity LPTIM Output Compare Polarity + * @{ + */ +#define LPTIM_OCPOLARITY_HIGH 0x00000000U /*!< Capture/Compare output polarity */ +#define LPTIM_OCPOLARITY_LOW 0x00000001U /*!< Capture/Compare output polarity */ +/** + * @} + */ + +/** @defgroup LPTIM_Input_Capture_Prescaler LPTIM Input Capture Prescaler + * @{ + */ +#define LPTIM_ICPSC_DIV1 0x00000000UL /*!< Capture performed each time an edge is detected on the capture input */ +#define LPTIM_ICPSC_DIV2 LPTIM_CCMR1_IC1PSC_0 /*!< Capture performed once every 2 events */ +#define LPTIM_ICPSC_DIV4 LPTIM_CCMR1_IC1PSC_1 /*!< Capture performed once every 4 events */ +#define LPTIM_ICPSC_DIV8 (LPTIM_CCMR1_IC1PSC_0|LPTIM_CCMR1_IC1PSC_1) /*!< Capture performed once every 8 events */ +/** + * @} + */ + +/** @defgroup LPTIM_Input_Capture_Polarity LPTIM Input Capture Polarity + * @{ + */ +#define LPTIM_ICPOLARITY_RISING 0x00000000UL /*!< Capture/Compare input rising polarity */ +#define LPTIM_ICPOLARITY_FALLING LPTIM_CCMR1_CC1P_0 /*!< Capture/Compare input falling polarity */ +#define LPTIM_ICPOLARITY_RISING_FALLING (LPTIM_CCMR1_CC1P_0|LPTIM_CCMR1_CC1P_1) /*!< Capture/Compare input rising and falling polarities */ +/** + * @} + */ + +/** @defgroup LPTIM_Input_Capture_Filter LPTIM Input Capture Filter + * @{ + */ +#define LPTIM_ICFLT_CLOCK_DIV1 0x00000000UL /*!< any external input capture signal level change is considered as a valid transition */ +#define LPTIM_ICFLT_CLOCK_DIV2 LPTIM_CCMR1_IC1F_0 /*!< external input capture signal level change must be stable for at least 2 clock periods before it is considered as valid transition */ +#define LPTIM_ICFLT_CLOCK_DIV4 LPTIM_CCMR1_IC1F_1 /*!< external input capture signal level change must be stable for at least 4 clock periods before it is considered as valid transition */ +#define LPTIM_ICFLT_CLOCK_DIV8 (LPTIM_CCMR1_IC1F_0|LPTIM_CCMR1_IC1F_1) /*!< external input capture signal level change must be stable for at least 8 clock periods before it is considered as valid transition */ +/** + * @} + */ + +/** @defgroup LPTIM_Input_Capture_Source LPTIM Input Capture Source + * @{ + */ +#define LPTIM_IC1SOURCE_GPIO 0x00000000UL /*!< For LPTIM1, LPTIM2, LPTIM3, LPTIM4, LPTIM5 and LPTIM6 */ +#if defined(COMP1) +#define LPTIM_IC1SOURCE_COMP1 LPTIM_CFGR2_IC1SEL_0 /*!< For LPTIM1, LPTIM2, LPTIM3, LPTIM4, LPTIM5 and LPTIM6 */ +#endif /* COMP1 */ +#if defined(STM32H503xx) +#define LPTIM_IC1SOURCE_EVENTOUT LPTIM_CFGR2_IC1SEL_1 /*!< For LPTIM1, LPTIM2, LPTIM3, LPTIM4, LPTIM5 and LPTIM6 */ +#define LPTIM_IC1SOURCE_MCO1 (LPTIM_CFGR2_IC1SEL_0 | LPTIM_CFGR2_IC1SEL_1)/*!< For LPTIM1 */ +#define LPTIM_IC1SOURCE_MCO2 (LPTIM_CFGR2_IC1SEL_0 | LPTIM_CFGR2_IC1SEL_1)/*!< For LPTIM2 */ +#endif /* STM32H503xx*/ + +#define LPTIM_IC2SOURCE_GPIO 0x00000000UL /*!< For LPTIM1, LPTIM2, LPTIM3, LPTIM4, LPTIM5 and LPTIM6 */ +#define LPTIM_IC2SOURCE_LSI LPTIM_CFGR2_IC2SEL_0 /*!< For LPTIM1 */ +#define LPTIM_IC2SOURCE_LSE LPTIM_CFGR2_IC2SEL_1 /*!< For LPTIM1 */ +#if defined(STM32H503xx) +#define LPTIM_IC2SOURCE_HSE_1M (LPTIM_CFGR2_IC2SEL_0 | LPTIM_CFGR2_IC2SEL_1)/*!< For LPTIM1 */ +#endif /* STM32H503xx*/ +#define LPTIM_IC2SOURCE_HSI_1024 LPTIM_CFGR2_IC2SEL_0 /*!< For LPTIM2 */ +#define LPTIM_IC2SOURCE_CSI_128 LPTIM_CFGR2_IC2SEL_1 /*!< For LPTIM2 */ +#define LPTIM_IC2SOURCE_HSI_8 (LPTIM_CFGR2_IC2SEL_0 | LPTIM_CFGR2_IC2SEL_1)/*!< For LPTIM2 */ +/** + * @} + */ +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup LPTIM_Exported_Macros LPTIM Exported Macros + * @{ + */ + +/** @brief Reset LPTIM handle state. + * @param __HANDLE__ LPTIM handle + * @retval None + */ +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) +#define __HAL_LPTIM_RESET_HANDLE_STATE(__HANDLE__) do { \ + (__HANDLE__)->State = HAL_LPTIM_STATE_RESET; \ + (__HANDLE__)->ChannelState[0] = HAL_LPTIM_CHANNEL_STATE_RESET;\ + (__HANDLE__)->ChannelState[1] = HAL_LPTIM_CHANNEL_STATE_RESET;\ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_LPTIM_RESET_HANDLE_STATE(__HANDLE__) do { \ + (__HANDLE__)->State = HAL_LPTIM_STATE_RESET; \ + (__HANDLE__)->ChannelState[0] = HAL_LPTIM_CHANNEL_STATE_RESET;\ + (__HANDLE__)->ChannelState[1] = HAL_LPTIM_CHANNEL_STATE_RESET;\ + } while(0) +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ + +/** + * @brief Enable the LPTIM peripheral. + * @param __HANDLE__ LPTIM handle + * @retval None + */ +#define __HAL_LPTIM_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= (LPTIM_CR_ENABLE)) + +/** + * @brief Disable the LPTIM peripheral. + * @param __HANDLE__ LPTIM handle + * @retval None + */ +#define __HAL_LPTIM_DISABLE(__HANDLE__) \ + do { \ + if (((__HANDLE__)->Instance->CCMR1 & LPTIM_CCMR1_CC1E) == 0UL) \ + { \ + if(((__HANDLE__)->Instance->CCMR1 & LPTIM_CCMR1_CC2E) == 0UL) \ + { \ + (__HANDLE__)->Instance->CR &= ~(LPTIM_CR_ENABLE); \ + } \ + } \ + } while(0) + +/** + * @brief Start the LPTIM peripheral in Continuous mode. + * @param __HANDLE__ LPTIM handle + * @retval None + */ +#define __HAL_LPTIM_START_CONTINUOUS(__HANDLE__) ((__HANDLE__)->Instance->CR |= LPTIM_CR_CNTSTRT) +/** + * @brief Start the LPTIM peripheral in single mode. + * @param __HANDLE__ LPTIM handle + * @retval None + */ +#define __HAL_LPTIM_START_SINGLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= LPTIM_CR_SNGSTRT) + +/** + * @brief Reset the LPTIM Counter register in synchronous mode. + * @param __HANDLE__ LPTIM handle + * @retval None + */ +#define __HAL_LPTIM_RESET_COUNTER(__HANDLE__) ((__HANDLE__)->Instance->CR |= LPTIM_CR_COUNTRST) + +/** + * @brief Reset after read of the LPTIM Counter register in asynchronous mode. + * @param __HANDLE__ LPTIM handle + * @retval None + */ +#define __HAL_LPTIM_RESET_COUNTER_AFTERREAD(__HANDLE__) ((__HANDLE__)->Instance->CR |= LPTIM_CR_RSTARE) + +/** + * @brief Write the passed parameter in the Autoreload register. + * @param __HANDLE__ LPTIM handle + * @param __VALUE__ Autoreload value + * @retval None + * @note The ARR register can only be modified when the LPTIM instance is enabled. + */ +#define __HAL_LPTIM_AUTORELOAD_SET(__HANDLE__ , __VALUE__) ((__HANDLE__)->Instance->ARR = (__VALUE__)) + +/** + * @brief Write the passed parameter in the Compare register. + * @param __HANDLE__ LPTIM handle + * @param __VALUE__ Compare value + * @param __CHANNEL__ TIM Channel to be configured + * @retval None + * @note The CCRx registers can only be modified when the LPTIM instance is enabled. + */ +#define __HAL_LPTIM_COMPARE_SET(__HANDLE__ , __CHANNEL__, __VALUE__) \ + (((__CHANNEL__) == LPTIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCR1 = (__VALUE__)) :\ + ((__CHANNEL__) == LPTIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCR2 = (__VALUE__)) : 0U) + +/** + * @brief Write the passed parameter in the Repetition register. + * @param __HANDLE__ LPTIM handle + * @param __VALUE__ Repetition value + * @retval None + */ +#define __HAL_LPTIM_REPETITIONCOUNTER_SET(__HANDLE__ , __VALUE__) ((__HANDLE__)->Instance->RCR = (__VALUE__)) + +/** + * @brief Return the current Repetition value. + * @param __HANDLE__ LPTIM handle + * @retval Repetition register value + * @note The RCR register can only be modified when the LPTIM instance is enabled. + */ +#define __HAL_LPTIM_REPETITIONCOUNTER_GET(__HANDLE__) ((__HANDLE__)->Instance->RCR) + +/** + * @brief Enable the LPTIM signal input/output on the corresponding pin. + * @param __HANDLE__ LPTIM handle + * @param __CHANNEL__ LPTIM Channels to be enabled. + * This parameter can be one of the following values: + * @arg LPTIM_CHANNEL_1: LPTIM Channel 1 selected + * @arg LPTIM_CHANNEL_2: LPTIM Channel 2 selected + * @retval None + */ +#define __HAL_LPTIM_CAPTURE_COMPARE_ENABLE(__HANDLE__, __CHANNEL__) \ + do { \ + switch (__CHANNEL__) \ + { \ + case LPTIM_CHANNEL_1: \ + ((__HANDLE__)->Instance->CCMR1 |= LPTIM_CCMR1_CC1E); \ + break; \ + case LPTIM_CHANNEL_2: \ + ((__HANDLE__)->Instance->CCMR1 |= LPTIM_CCMR1_CC2E); \ + break; \ + default: \ + break; \ + } \ + } \ + while(0) + +/** + * @brief Disable the LPTIM signal input/output on the corresponding pin. + * @param __HANDLE__ LPTIM handle + * @param __CHANNEL__ LPTIM Channels to be disabled. + * This parameter can be one of the following values: + * @arg LPTIM_CHANNEL_1: LPTIM Channel 1 selected + * @arg LPTIM_CHANNEL_2: LPTIM Channel 2 selected + * @retval None + */ +#define __HAL_LPTIM_CAPTURE_COMPARE_DISABLE(__HANDLE__, __CHANNEL__) \ + do { \ + switch (__CHANNEL__) \ + { \ + case LPTIM_CHANNEL_1: \ + ((__HANDLE__)->Instance->CCMR1 &= ~LPTIM_CCMR1_CC1E); \ + break; \ + case LPTIM_CHANNEL_2: \ + ((__HANDLE__)->Instance->CCMR1 &= ~LPTIM_CCMR1_CC2E); \ + break; \ + default: \ + break; \ + } \ + } \ + while(0) + +/** + * @brief Check whether the specified LPTIM flag is set or not. + * @param __HANDLE__ LPTIM handle + * @param __FLAG__ LPTIM flag to check + * This parameter can be a value of: + * @arg LPTIM_FLAG_REPOK : Repetition register update OK Flag. + * @arg LPTIM_FLAG_UPDATE : Update event Flag. + * @arg LPTIM_FLAG_DOWN : Counter direction change up Flag. + * @arg LPTIM_FLAG_UP : Counter direction change down to up Flag. + * @arg LPTIM_FLAG_ARROK : Autoreload register update OK Flag. + * @arg LPTIM_FLAG_CMP1OK : Compare register 1 update OK Flag. + * @arg LPTIM_FLAG_CMP2OK : Compare register 2 update OK Flag. + * @arg LPTIM_FLAG_EXTTRIG : External trigger edge event Flag. + * @arg LPTIM_FLAG_ARRM : Autoreload match Flag. + * @arg LPTIM_FLAG_CC1 : Capture/Compare 1 interrupt flag. + * @arg LPTIM_FLAG_CC2 : Capture/Compare 2 interrupt flag. + * @arg LPTIM_FLAG_CC1O : Capture/Compare 1 over-capture flag. + * @arg LPTIM_FLAG_CC2O : Capture/Compare 2 over-capture flag. + * @arg LPTIM_FLAG_DIEROK : DMA & interrupt enable update OK flag. + * @retval The state of the specified flag (SET or RESET). + */ +#define __HAL_LPTIM_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->ISR &(__FLAG__)) == (__FLAG__)) + +/** + * @brief Clear the specified LPTIM flag. + * @param __HANDLE__ LPTIM handle. + * @param __FLAG__ LPTIM flag to clear. + * This parameter can be a value of: + * @arg LPTIM_FLAG_REPOK : Repetition register update OK Flag. + * @arg LPTIM_FLAG_UPDATE : Update event Flag. + * @arg LPTIM_FLAG_DOWN : Counter direction change up Flag. + * @arg LPTIM_FLAG_UP : Counter direction change down to up Flag. + * @arg LPTIM_FLAG_ARROK : Autoreload register update OK Flag. + * @arg LPTIM_FLAG_CMP1OK : Compare register 1 update OK Flag. + * @arg LPTIM_FLAG_CMP2OK : Compare register 2 update OK Flag. + * @arg LPTIM_FLAG_EXTTRIG : External trigger edge event Flag. + * @arg LPTIM_FLAG_ARRM : Autoreload match Flag. + * @arg LPTIM_FLAG_CC1 : Capture/Compare 1 interrupt flag. + * @arg LPTIM_FLAG_CC2 : Capture/Compare 2 interrupt flag. + * @arg LPTIM_FLAG_CC1O : Capture/Compare 1 over-capture flag. + * @arg LPTIM_FLAG_CC2O : Capture/Compare 2 over-capture flag. + * @arg LPTIM_FLAG_DIEROK : DMA & interrupt enable update OK flag. + * @retval None. + */ +#define __HAL_LPTIM_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ICR = (__FLAG__)) + +/** + * @brief Enable the specified LPTIM interrupt. + * @param __HANDLE__ LPTIM handle. + * @param __INTERRUPT__ LPTIM interrupt to set. + * This parameter can be a value of: + * @arg LPTIM_IT_REPOK : Repetition register update OK Interrupt. + * @arg LPTIM_IT_UPDATE : Update event register Interrupt. + * @arg LPTIM_IT_DOWN : Counter direction change up Interrupt. + * @arg LPTIM_IT_UP : Counter direction change down to up Interrupt. + * @arg LPTIM_IT_ARROK : Autoreload register update OK Interrupt. + * @arg LPTIM_IT_CMP1OK : Compare register 1 update OK Interrupt. + * @arg LPTIM_IT_CMP2OK : Compare register 2 update OK Interrupt. + * @arg LPTIM_IT_EXTTRIG : External trigger edge event Interrupt. + * @arg LPTIM_IT_ARRM : Autoreload match Interrupt. + * @arg LPTIM_IT_CC1 : Capture/Compare 1 interrupt Interrupt. + * @arg LPTIM_IT_CC2 : Capture/Compare 2 interrupt Interrupt. + * @arg LPTIM_IT_CC1O : Capture/Compare 1 over-capture Interrupt. + * @arg LPTIM_IT_CC2O : Capture/Compare 2 over-capture Interrupt. + * @retval None. + * @note The LPTIM interrupts can only be enabled when the LPTIM instance is enabled. + */ +#define __HAL_LPTIM_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DIER |= (__INTERRUPT__)) + +/** + * @brief Disable the specified LPTIM interrupt. + * @param __HANDLE__ LPTIM handle. + * @param __INTERRUPT__ LPTIM interrupt to set. + * This parameter can be a value of: + * @arg LPTIM_IT_REPOK : Repetition register update OK Interrupt. + * @arg LPTIM_IT_UPDATE : Update event register Interrupt. + * @arg LPTIM_IT_DOWN : Counter direction change up Interrupt. + * @arg LPTIM_IT_UP : Counter direction change down to up Interrupt. + * @arg LPTIM_IT_ARROK : Autoreload register update OK Interrupt. + * @arg LPTIM_IT_CMP1OK : Compare register 1 update OK Interrupt. + * @arg LPTIM_IT_CMP2OK : Compare register 2 update OK Interrupt. + * @arg LPTIM_IT_EXTTRIG : External trigger edge event Interrupt. + * @arg LPTIM_IT_ARRM : Autoreload match Interrupt. + * @arg LPTIM_IT_CC1 : Capture/Compare 1 interrupt Interrupt. + * @arg LPTIM_IT_CC2 : Capture/Compare 2 interrupt Interrupt. + * @arg LPTIM_IT_CC1O : Capture/Compare 1 over-capture Interrupt. + * @arg LPTIM_IT_CC2O : Capture/Compare 2 over-capture Interrupt. + * @retval None. + * @note The LPTIM interrupts can only be disabled when the LPTIM instance is enabled. + */ +#define __HAL_LPTIM_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DIER &= (~(__INTERRUPT__))) + +/** @brief Enable the specified DMA request. + * @param __HANDLE__ specifies the TIM Handle. + * @param __DMA__ specifies the LPTIM DMA request to enable. + * This parameter can be one of the following values: + * @arg LPTIM_DMA_UPDATE: Update DMA request + * @arg LPTIM_DMA_CC1: Capture/Compare 1 DMA request + * @arg LPTIM_DMA_CC2: Capture/Compare 2 DMA request + * @retval None + */ +#define __HAL_LPTIM_ENABLE_DMA(__HANDLE__, __DMA__) ((__HANDLE__)->Instance->DIER |= (__DMA__)) + +/** @brief Disable the specified DMA request. + * @param __HANDLE__ specifies the LPTIM Handle. + * @param __DMA__ specifies the LPTIM DMA request to disable. + * This parameter can be one of the following values: + * @arg LPTIM_DMA_UPDATE: Update DMA request + * @arg LPTIM_DMA_CC1: Capture/Compare 1 DMA request + * @arg LPTIM_DMA_CC2: Capture/Compare 2 DMA request + * @retval None + */ +#define __HAL_LPTIM_DISABLE_DMA(__HANDLE__, __DMA__) ((__HANDLE__)->Instance->DIER &= ~(__DMA__)) + +/** + * @brief Check whether the specified LPTIM interrupt source is enabled or not. + * @param __HANDLE__ LPTIM handle. + * @param __INTERRUPT__ LPTIM interrupt to check. + * This parameter can be a value of: + * @arg LPTIM_IT_REPOK : Repetition register update OK Interrupt. + * @arg LPTIM_IT_UPDATE : Update event register Interrupt. + * @arg LPTIM_IT_DOWN : Counter direction change up Interrupt. + * @arg LPTIM_IT_UP : Counter direction change down to up Interrupt. + * @arg LPTIM_IT_ARROK : Autoreload register update OK Interrupt. + * @arg LPTIM_IT_CMP1OK : Compare register 1 update OK Interrupt. + * @arg LPTIM_IT_CMP2OK : Compare register 2 update OK Interrupt. + * @arg LPTIM_IT_EXTTRIG : External trigger edge event Interrupt. + * @arg LPTIM_IT_ARRM : Autoreload match Interrupt. + * @arg LPTIM_IT_CC1 : Capture/Compare 1 interrupt Interrupt. + * @arg LPTIM_IT_CC2 : Capture/Compare 2 interrupt Interrupt. + * @arg LPTIM_IT_CC1O : Capture/Compare 1 over-capture Interrupt. + * @arg LPTIM_IT_CC2O : Capture/Compare 2 over-capture Interrupt. + * @retval Interrupt status. + */ + +#define __HAL_LPTIM_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->DIER\ + & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup LPTIM_Exported_Functions LPTIM Exported Functions + * @{ + */ + +/** @addtogroup LPTIM_Exported_Functions_Group1 + * @brief Initialization and Configuration functions. + * @{ + */ +/* Initialization/de-initialization functions ********************************/ +HAL_StatusTypeDef HAL_LPTIM_Init(LPTIM_HandleTypeDef *hlptim); +HAL_StatusTypeDef HAL_LPTIM_DeInit(LPTIM_HandleTypeDef *hlptim); + +/* MSP functions *************************************************************/ +void HAL_LPTIM_MspInit(LPTIM_HandleTypeDef *hlptim); +void HAL_LPTIM_MspDeInit(LPTIM_HandleTypeDef *hlptim); +/** + * @} + */ + +/** @addtogroup LPTIM_Exported_Functions_Group2 + * @brief Start-Stop operation functions. + * @{ + */ +/* Config functions **********************************************************/ +HAL_StatusTypeDef HAL_LPTIM_OC_ConfigChannel(LPTIM_HandleTypeDef *hlptim, const LPTIM_OC_ConfigTypeDef *sConfig, + uint32_t Channel); + +/* Start/Stop operation functions *********************************************/ +/* ################################# PWM Mode ################################*/ +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_LPTIM_PWM_Start(LPTIM_HandleTypeDef *hlptim, uint32_t Channel); +HAL_StatusTypeDef HAL_LPTIM_PWM_Stop(LPTIM_HandleTypeDef *hlptim, uint32_t Channel); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_LPTIM_PWM_Start_IT(LPTIM_HandleTypeDef *hlptim, uint32_t Channel); +HAL_StatusTypeDef HAL_LPTIM_PWM_Stop_IT(LPTIM_HandleTypeDef *hlptim, uint32_t Channel); +HAL_StatusTypeDef HAL_LPTIM_PWM_Start_DMA(LPTIM_HandleTypeDef *hlptim, uint32_t Channel, const uint32_t *pData, + uint32_t Length); +HAL_StatusTypeDef HAL_LPTIM_PWM_Stop_DMA(LPTIM_HandleTypeDef *hlptim, uint32_t Channel); + +/* ############################# One Pulse Mode ##############################*/ +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_LPTIM_OnePulse_Start(LPTIM_HandleTypeDef *hlptim, uint32_t Channel); +HAL_StatusTypeDef HAL_LPTIM_OnePulse_Stop(LPTIM_HandleTypeDef *hlptim, uint32_t Channel); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_LPTIM_OnePulse_Start_IT(LPTIM_HandleTypeDef *hlptim, uint32_t Channel); +HAL_StatusTypeDef HAL_LPTIM_OnePulse_Stop_IT(LPTIM_HandleTypeDef *hlptim, uint32_t Channel); + +/* ############################## Set once Mode ##############################*/ +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_LPTIM_SetOnce_Start(LPTIM_HandleTypeDef *hlptim, uint32_t Channel); +HAL_StatusTypeDef HAL_LPTIM_SetOnce_Stop(LPTIM_HandleTypeDef *hlptim, uint32_t Channel); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_LPTIM_SetOnce_Start_IT(LPTIM_HandleTypeDef *hlptim, uint32_t Channel); +HAL_StatusTypeDef HAL_LPTIM_SetOnce_Stop_IT(LPTIM_HandleTypeDef *hlptim, uint32_t Channel); + +/* ############################### Encoder Mode ##############################*/ +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_LPTIM_Encoder_Start(LPTIM_HandleTypeDef *hlptim); +HAL_StatusTypeDef HAL_LPTIM_Encoder_Stop(LPTIM_HandleTypeDef *hlptim); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_LPTIM_Encoder_Start_IT(LPTIM_HandleTypeDef *hlptim); +HAL_StatusTypeDef HAL_LPTIM_Encoder_Stop_IT(LPTIM_HandleTypeDef *hlptim); + +/* ############################# Time out Mode ##############################*/ +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_LPTIM_TimeOut_Start(LPTIM_HandleTypeDef *hlptim, uint32_t Timeout); +HAL_StatusTypeDef HAL_LPTIM_TimeOut_Stop(LPTIM_HandleTypeDef *hlptim); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_LPTIM_TimeOut_Start_IT(LPTIM_HandleTypeDef *hlptim, uint32_t Timeout); +HAL_StatusTypeDef HAL_LPTIM_TimeOut_Stop_IT(LPTIM_HandleTypeDef *hlptim); + +/* ############################## Counter Mode ###############################*/ +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_LPTIM_Counter_Start(LPTIM_HandleTypeDef *hlptim); +HAL_StatusTypeDef HAL_LPTIM_Counter_Stop(LPTIM_HandleTypeDef *hlptim); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_LPTIM_Counter_Start_IT(LPTIM_HandleTypeDef *hlptim); +HAL_StatusTypeDef HAL_LPTIM_Counter_Stop_IT(LPTIM_HandleTypeDef *hlptim); + +/* ############################## Input Capture Mode ###############################*/ +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_LPTIM_IC_ConfigChannel(LPTIM_HandleTypeDef *hlptim, const LPTIM_IC_ConfigTypeDef *sConfig, + uint32_t Channel); +HAL_StatusTypeDef HAL_LPTIM_IC_Start(LPTIM_HandleTypeDef *hlptim, uint32_t Channel); +HAL_StatusTypeDef HAL_LPTIM_IC_Stop(LPTIM_HandleTypeDef *hlptim, uint32_t Channel); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_LPTIM_IC_Start_IT(LPTIM_HandleTypeDef *hlptim, uint32_t Channel); +HAL_StatusTypeDef HAL_LPTIM_IC_Stop_IT(LPTIM_HandleTypeDef *hlptim, uint32_t Channel); +HAL_StatusTypeDef HAL_LPTIM_IC_Start_DMA(LPTIM_HandleTypeDef *hlptim, uint32_t Channel, uint32_t *pData, + uint32_t Length); +HAL_StatusTypeDef HAL_LPTIM_IC_Stop_DMA(LPTIM_HandleTypeDef *hlptim, uint32_t Channel); +/** + * @} + */ + +/** @addtogroup LPTIM_Exported_Functions_Group3 + * @brief Read operation functions. + * @{ + */ +/* Reading operation functions ************************************************/ +uint32_t HAL_LPTIM_ReadCounter(const LPTIM_HandleTypeDef *hlptim); +uint32_t HAL_LPTIM_ReadAutoReload(const LPTIM_HandleTypeDef *hlptim); +uint32_t HAL_LPTIM_ReadCapturedValue(const LPTIM_HandleTypeDef *hlptim, uint32_t Channel); +uint8_t HAL_LPTIM_IC_GetOffset(const LPTIM_HandleTypeDef *hlptim, uint32_t Channel); +/** + * @} + */ + +/** @addtogroup LPTIM_Exported_Functions_Group4 + * @brief LPTIM IRQ handler and callback functions. + * @{ + */ +/* LPTIM IRQ functions *******************************************************/ +void HAL_LPTIM_IRQHandler(LPTIM_HandleTypeDef *hlptim); + +/* CallBack functions ********************************************************/ +void HAL_LPTIM_CompareMatchCallback(LPTIM_HandleTypeDef *hlptim); +void HAL_LPTIM_AutoReloadMatchCallback(LPTIM_HandleTypeDef *hlptim); +void HAL_LPTIM_TriggerCallback(LPTIM_HandleTypeDef *hlptim); +void HAL_LPTIM_CompareWriteCallback(LPTIM_HandleTypeDef *hlptim); +void HAL_LPTIM_AutoReloadWriteCallback(LPTIM_HandleTypeDef *hlptim); +void HAL_LPTIM_DirectionUpCallback(LPTIM_HandleTypeDef *hlptim); +void HAL_LPTIM_DirectionDownCallback(LPTIM_HandleTypeDef *hlptim); +void HAL_LPTIM_ErrorCallback(LPTIM_HandleTypeDef *hlptim); +void HAL_LPTIM_UpdateEventCallback(LPTIM_HandleTypeDef *hlptim); +void HAL_LPTIM_UpdateEventHalfCpltCallback(LPTIM_HandleTypeDef *hlptim); +void HAL_LPTIM_RepCounterWriteCallback(LPTIM_HandleTypeDef *hlptim); +void HAL_LPTIM_IC_CaptureCallback(LPTIM_HandleTypeDef *hlptim); +void HAL_LPTIM_IC_CaptureHalfCpltCallback(LPTIM_HandleTypeDef *hlptim); +void HAL_LPTIM_IC_OverCaptureCallback(LPTIM_HandleTypeDef *hlptim); + +/* Callbacks Register/UnRegister functions ***********************************/ +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) +HAL_StatusTypeDef HAL_LPTIM_RegisterCallback(LPTIM_HandleTypeDef *lphtim, HAL_LPTIM_CallbackIDTypeDef CallbackID, + pLPTIM_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_LPTIM_UnRegisterCallback(LPTIM_HandleTypeDef *lphtim, HAL_LPTIM_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @addtogroup LPTIM_Group5 + * @brief Peripheral State functions. + * @{ + */ +/* Peripheral State functions ************************************************/ +HAL_LPTIM_StateTypeDef HAL_LPTIM_GetState(const LPTIM_HandleTypeDef *hlptim); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/** @defgroup LPTIM_Private_Types LPTIM Private Types + * @{ + */ + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup LPTIM_Private_Variables LPTIM Private Variables + * @{ + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup LPTIM_Private_Constants LPTIM Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup LPTIM_Private_Macros LPTIM Private Macros + * @{ + */ + +#define IS_LPTIM_CLOCK_SOURCE(__SOURCE__) (((__SOURCE__) == LPTIM_CLOCKSOURCE_ULPTIM) || \ + ((__SOURCE__) == LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC)) + + +#define IS_LPTIM_CLOCK_PRESCALER(__PRESCALER__) (((__PRESCALER__) == LPTIM_PRESCALER_DIV1 ) || \ + ((__PRESCALER__) == LPTIM_PRESCALER_DIV2 ) || \ + ((__PRESCALER__) == LPTIM_PRESCALER_DIV4 ) || \ + ((__PRESCALER__) == LPTIM_PRESCALER_DIV8 ) || \ + ((__PRESCALER__) == LPTIM_PRESCALER_DIV16 ) || \ + ((__PRESCALER__) == LPTIM_PRESCALER_DIV32 ) || \ + ((__PRESCALER__) == LPTIM_PRESCALER_DIV64 ) || \ + ((__PRESCALER__) == LPTIM_PRESCALER_DIV128)) + +#define IS_LPTIM_CLOCK_PRESCALERDIV1(__PRESCALER__) ((__PRESCALER__) == LPTIM_PRESCALER_DIV1) +#define IS_LPTIM_CLOCK_SAMPLE_TIME(__SAMPLETIME__) (((__SAMPLETIME__) == LPTIM_CLOCKSAMPLETIME_DIRECTTRANSITION) || \ + ((__SAMPLETIME__) == LPTIM_CLOCKSAMPLETIME_2TRANSITIONS) || \ + ((__SAMPLETIME__) == LPTIM_CLOCKSAMPLETIME_4TRANSITIONS) || \ + ((__SAMPLETIME__) == LPTIM_CLOCKSAMPLETIME_8TRANSITIONS)) + +#define IS_LPTIM_CLOCK_POLARITY(__POLARITY__) (((__POLARITY__) == LPTIM_CLOCKPOLARITY_RISING) || \ + ((__POLARITY__) == LPTIM_CLOCKPOLARITY_FALLING) || \ + ((__POLARITY__) == LPTIM_CLOCKPOLARITY_RISING_FALLING)) + +#define IS_LPTIM_TRG_SOURCE(__TRIG__) (((__TRIG__) == LPTIM_TRIGSOURCE_SOFTWARE) || \ + ((__TRIG__) == LPTIM_TRIGSOURCE_0) || \ + ((__TRIG__) == LPTIM_TRIGSOURCE_1) || \ + ((__TRIG__) == LPTIM_TRIGSOURCE_2) || \ + ((__TRIG__) == LPTIM_TRIGSOURCE_3) || \ + ((__TRIG__) == LPTIM_TRIGSOURCE_4) || \ + ((__TRIG__) == LPTIM_TRIGSOURCE_5) || \ + ((__TRIG__) == LPTIM_TRIGSOURCE_6) || \ + ((__TRIG__) == LPTIM_TRIGSOURCE_7)) + +#define IS_LPTIM_EXT_TRG_POLARITY(__POLARITY__) (((__POLARITY__) == LPTIM_ACTIVEEDGE_RISING ) || \ + ((__POLARITY__) == LPTIM_ACTIVEEDGE_FALLING ) || \ + ((__POLARITY__) == LPTIM_ACTIVEEDGE_RISING_FALLING )) + +#define IS_LPTIM_TRIG_SAMPLE_TIME(__SAMPLETIME__) (((__SAMPLETIME__) == LPTIM_TRIGSAMPLETIME_DIRECTTRANSITION) || \ + ((__SAMPLETIME__) == LPTIM_TRIGSAMPLETIME_2TRANSITIONS ) || \ + ((__SAMPLETIME__) == LPTIM_TRIGSAMPLETIME_4TRANSITIONS ) || \ + ((__SAMPLETIME__) == LPTIM_TRIGSAMPLETIME_8TRANSITIONS )) + +#define IS_LPTIM_UPDATE_MODE(__MODE__) (((__MODE__) == LPTIM_UPDATE_IMMEDIATE) || \ + ((__MODE__) == LPTIM_UPDATE_ENDOFPERIOD)) + +#define IS_LPTIM_COUNTER_SOURCE(__SOURCE__) (((__SOURCE__) == LPTIM_COUNTERSOURCE_INTERNAL) || \ + ((__SOURCE__) == LPTIM_COUNTERSOURCE_EXTERNAL)) + +#define IS_LPTIM_AUTORELOAD(__AUTORELOAD__) ((0x00000001UL <= (__AUTORELOAD__)) &&\ + ((__AUTORELOAD__) <= 0x0000FFFFUL)) + +#define IS_LPTIM_COMPARE(__COMPARE__) ((__COMPARE__) <= 0x0000FFFFUL) + +#define IS_LPTIM_PERIOD(__PERIOD__) ((0x00000001UL <= (__PERIOD__)) &&\ + ((__PERIOD__) <= 0x0000FFFFUL)) + +#define IS_LPTIM_PULSE(__PULSE__) ((__PULSE__) <= 0x0000FFFFUL) + +#define IS_LPTIM_OC_POLARITY(__OCPOLARITY__) (((__OCPOLARITY__) == LPTIM_OCPOLARITY_LOW) || \ + ((__OCPOLARITY__) == LPTIM_OCPOLARITY_HIGH)) +#define IS_LPTIM_IC_PRESCALER(__PRESCALER__) (((__PRESCALER__) == LPTIM_ICPSC_DIV1) ||\ + ((__PRESCALER__) == LPTIM_ICPSC_DIV2) ||\ + ((__PRESCALER__) == LPTIM_ICPSC_DIV4) ||\ + ((__PRESCALER__) == LPTIM_ICPSC_DIV8)) + +#define IS_LPTIM_IC_POLARITY(__POLARITY__) (((__POLARITY__) == LPTIM_ICPOLARITY_RISING) || \ + ((__POLARITY__) == LPTIM_ICPOLARITY_FALLING) ||\ + ((__POLARITY__) == LPTIM_ICPOLARITY_RISING_FALLING)) + +#define IS_LPTIM_IC_FILTER(__FILTER__) (((__FILTER__) == LPTIM_ICFLT_CLOCK_DIV1) ||\ + ((__FILTER__) == LPTIM_ICFLT_CLOCK_DIV2) ||\ + ((__FILTER__) == LPTIM_ICFLT_CLOCK_DIV4) ||\ + ((__FILTER__) == LPTIM_ICFLT_CLOCK_DIV8)) + +#define IS_LPTIM_REPETITION(__REPETITION__) ((__REPETITION__) <= 0x000000FFUL) + +#if defined(STM32H503xx) +#define IS_LPTIM_INPUT1_SOURCE(__INSTANCE__, __SOURCE__) \ + ((((__INSTANCE__) == LPTIM1) && \ + (((__SOURCE__) == LPTIM_INPUT1SOURCE_GPIO) || \ + ((__SOURCE__) == LPTIM_INPUT1SOURCE_COMP1) || \ + ((__SOURCE__) == LPTIM_INPUT1SOURCE_LPTIM2_CH1))) \ + || \ + (((__INSTANCE__) == LPTIM2) && \ + (((__SOURCE__) == LPTIM_INPUT1SOURCE_GPIO) || \ + ((__SOURCE__) == LPTIM_INPUT1SOURCE_COMP1) || \ + ((__SOURCE__) == LPTIM_INPUT1SOURCE_LPTIM1_CH2)))) +#else +#define IS_LPTIM_INPUT1_SOURCE(__INSTANCE__, __SOURCE__) \ + ((((__INSTANCE__) == LPTIM1) || \ + ((__INSTANCE__) == LPTIM2) || \ + ((__INSTANCE__) == LPTIM3) || \ + ((__INSTANCE__) == LPTIM4) || \ + ((__INSTANCE__) == LPTIM5) || \ + ((__INSTANCE__) == LPTIM6)) && \ + (((__SOURCE__) == LPTIM_INPUT1SOURCE_GPIO))) +#endif /* STM32H503xx */ + +#if defined(STM32H503xx) +#define IS_LPTIM_INPUT2_SOURCE(__INSTANCE__, __SOURCE__) \ + ((((__INSTANCE__) == LPTIM1) || \ + ((__INSTANCE__) == LPTIM2)) && \ + (((__SOURCE__) == LPTIM_INPUT2SOURCE_GPIO))) +#else +#define IS_LPTIM_INPUT2_SOURCE(__INSTANCE__, __SOURCE__) \ + ((((__INSTANCE__) == LPTIM1) || \ + ((__INSTANCE__) == LPTIM2) || \ + ((__INSTANCE__) == LPTIM3) || \ + ((__INSTANCE__) == LPTIM5) || \ + ((__INSTANCE__) == LPTIM6)) && \ + (((__SOURCE__) == LPTIM_INPUT2SOURCE_GPIO))) +#endif /* STM32H503xx */ + +#if defined(STM32H503xx) +#define IS_LPTIM_IC1_SOURCE(__INSTANCE__, __SOURCE__) \ + ((((__INSTANCE__) == LPTIM1) && \ + (((__SOURCE__) == LPTIM_IC1SOURCE_GPIO) || \ + ((__SOURCE__) == LPTIM_IC1SOURCE_COMP1) || \ + ((__SOURCE__) == LPTIM_IC1SOURCE_EVENTOUT)|| \ + ((__SOURCE__) == LPTIM_IC1SOURCE_MCO1))) \ + || \ + (((__INSTANCE__) == LPTIM2) && \ + (((__SOURCE__) == LPTIM_IC1SOURCE_GPIO) || \ + ((__SOURCE__) == LPTIM_IC1SOURCE_COMP1) || \ + ((__SOURCE__) == LPTIM_IC1SOURCE_EVENTOUT)|| \ + ((__SOURCE__) == LPTIM_IC1SOURCE_MCO2)))) + +#define IS_LPTIM_IC2_SOURCE(__INSTANCE__, __SOURCE__) \ + ((((__INSTANCE__) == LPTIM1) && \ + (((__SOURCE__) == LPTIM_IC2SOURCE_GPIO) || \ + ((__SOURCE__) == LPTIM_IC2SOURCE_LSI) || \ + ((__SOURCE__) == LPTIM_IC2SOURCE_LSE) || \ + ((__SOURCE__) == LPTIM_IC2SOURCE_HSE_1M))) \ + || \ + (((__INSTANCE__) == LPTIM2) && \ + (((__SOURCE__) == LPTIM_IC2SOURCE_GPIO) || \ + ((__SOURCE__) == LPTIM_IC2SOURCE_HSI_1024) || \ + ((__SOURCE__) == LPTIM_IC2SOURCE_CSI_128) || \ + ((__SOURCE__) == LPTIM_IC2SOURCE_HSI_8)))) +#else +#define IS_LPTIM_IC1_SOURCE(__INSTANCE__, __SOURCE__) \ + ((((__INSTANCE__) == LPTIM1) || \ + ((__INSTANCE__) == LPTIM2) || \ + ((__INSTANCE__) == LPTIM3) || \ + ((__INSTANCE__) == LPTIM5) || \ + ((__INSTANCE__) == LPTIM6)) && \ + (((__SOURCE__) == LPTIM_IC1SOURCE_GPIO))) + +#define IS_LPTIM_IC2_SOURCE(__INSTANCE__, __SOURCE__) \ + ((((__INSTANCE__) == LPTIM1) && \ + (((__SOURCE__) == LPTIM_IC2SOURCE_GPIO) || \ + ((__SOURCE__) == LPTIM_IC2SOURCE_LSI) || \ + ((__SOURCE__) == LPTIM_IC2SOURCE_LSE))) \ + || \ + (((__INSTANCE__) == LPTIM2) && \ + (((__SOURCE__) == LPTIM_IC2SOURCE_GPIO) || \ + ((__SOURCE__) == LPTIM_IC2SOURCE_HSI_1024) || \ + ((__SOURCE__) == LPTIM_IC2SOURCE_CSI_128) || \ + ((__SOURCE__) == LPTIM_IC2SOURCE_HSI_8))) \ + || \ + (((__INSTANCE__) == LPTIM3) && \ + ((__SOURCE__) == LPTIM_IC2SOURCE_GPIO)) \ + || \ + (((__INSTANCE__) == LPTIM5) && \ + ((__SOURCE__) == LPTIM_IC2SOURCE_GPIO)) \ + || \ + (((__INSTANCE__) == LPTIM6) && \ + ((__SOURCE__) == LPTIM_IC2SOURCE_GPIO))) +#endif /* STM32H503xx */ + +#define LPTIM_CHANNEL_STATE_GET(__INSTANCE__, __CHANNEL__)\ + (((__CHANNEL__) == LPTIM_CHANNEL_1) ? (__INSTANCE__)->ChannelState[0] :\ + (__INSTANCE__)->ChannelState[1]) + +#define LPTIM_CHANNEL_STATE_SET(__INSTANCE__, __CHANNEL__, __CHANNEL_STATE__) \ + (((__CHANNEL__) == LPTIM_CHANNEL_1) ? ((__INSTANCE__)->ChannelState[0] = (__CHANNEL_STATE__)) :\ + ((__INSTANCE__)->ChannelState[1] = (__CHANNEL_STATE__))) + +#define LPTIM_CHANNEL_STATE_SET_ALL(__INSTANCE__, __CHANNEL_STATE__) do { \ + (__INSTANCE__)->ChannelState[0] =\ + (__CHANNEL_STATE__); \ + (__INSTANCE__)->ChannelState[1] =\ + (__CHANNEL_STATE__); \ + } while(0) + +#if defined(STM32H503xx) +#define IS_LPTIM_CCX_INSTANCE(__INSTANCE__, __CHANNEL__) \ + ((((__INSTANCE__) == LPTIM1_NS) && \ + (((__CHANNEL__) == LPTIM_CHANNEL_1) || \ + ((__CHANNEL__) == LPTIM_CHANNEL_2))) \ + || \ + (((__INSTANCE__) == LPTIM2_NS) && \ + (((__CHANNEL__) == LPTIM_CHANNEL_1) || \ + ((__CHANNEL__) == LPTIM_CHANNEL_2)))) +#else +#define IS_LPTIM_CCX_INSTANCE(__INSTANCE__, __CHANNEL__) \ + (((((__INSTANCE__) == LPTIM1_NS) || ((__INSTANCE__) == LPTIM1_S)) && \ + (((__CHANNEL__) == LPTIM_CHANNEL_1) || \ + ((__CHANNEL__) == LPTIM_CHANNEL_2))) \ + || \ + ((((__INSTANCE__) == LPTIM2_NS) || ((__INSTANCE__) == LPTIM2_S)) && \ + (((__CHANNEL__) == LPTIM_CHANNEL_1) || \ + ((__CHANNEL__) == LPTIM_CHANNEL_2))) \ + || \ + ((((__INSTANCE__) == LPTIM3_NS) || ((__INSTANCE__) == LPTIM3_S)) && \ + (((__CHANNEL__) == LPTIM_CHANNEL_1) || \ + ((__CHANNEL__) == LPTIM_CHANNEL_2))) \ + || \ + ((((__INSTANCE__) == LPTIM4_NS) || ((__INSTANCE__) == LPTIM4_S)) && \ + ((__CHANNEL__) == LPTIM_CHANNEL_1)) \ + || \ + ((((__INSTANCE__) == LPTIM5_NS) || ((__INSTANCE__) == LPTIM5_S)) && \ + (((__CHANNEL__) == LPTIM_CHANNEL_1) || \ + ((__CHANNEL__) == LPTIM_CHANNEL_2))) \ + || \ + ((((__INSTANCE__) == LPTIM6_NS) || ((__INSTANCE__) == LPTIM6_S)) && \ + (((__CHANNEL__) == LPTIM_CHANNEL_1) || \ + ((__CHANNEL__) == LPTIM_CHANNEL_2)))) +#endif /* STM32H503xx */ +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup LPTIM_Private_Functions LPTIM Private Functions + * @{ + */ +/** + * @} + */ + +/** + * @} + */ + +#endif /* LPTIM1 || LPTIM2 || LPTIM3 || LPTIM4 || LPTIM5 || LPTIM6 */ +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_LPTIM_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_mmc.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_mmc.h new file mode 100644 index 0000000000..959c828c09 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_mmc.h @@ -0,0 +1,823 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_mmc.h + * @author MCD Application Team + * @brief Header file of MMC HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_MMC_H +#define STM32H5xx_HAL_MMC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_sdmmc.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ +#if defined (SDMMC1) || defined (SDMMC2) + +/** @addtogroup MMC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup MMC_Exported_Types MMC Exported Types + * @{ + */ + +/** @defgroup MMC_Exported_Types_Group1 MMC State enumeration structure + * @{ + */ +typedef enum +{ + HAL_MMC_STATE_RESET = ((uint32_t)0x00000000U), /*!< MMC not yet initialized or disabled */ + HAL_MMC_STATE_READY = ((uint32_t)0x00000001U), /*!< MMC initialized and ready for use */ + HAL_MMC_STATE_TIMEOUT = ((uint32_t)0x00000002U), /*!< MMC Timeout state */ + HAL_MMC_STATE_BUSY = ((uint32_t)0x00000003U), /*!< MMC process ongoing */ + HAL_MMC_STATE_PROGRAMMING = ((uint32_t)0x00000004U), /*!< MMC Programming State */ + HAL_MMC_STATE_RECEIVING = ((uint32_t)0x00000005U), /*!< MMC Receinving State */ + HAL_MMC_STATE_TRANSFER = ((uint32_t)0x00000006U), /*!< MMC Transfer State */ + HAL_MMC_STATE_ERROR = ((uint32_t)0x0000000FU) /*!< MMC is in error state */ +} HAL_MMC_StateTypeDef; +/** + * @} + */ + +/** @defgroup MMC_Exported_Types_Group2 MMC Card State enumeration structure + * @{ + */ +typedef uint32_t HAL_MMC_CardStateTypeDef; + +#define HAL_MMC_CARD_IDLE 0x00000000U /*!< Card is in idle state (can't be checked by CMD13) */ +#define HAL_MMC_CARD_READY 0x00000001U /*!< Card state is ready (can't be checked by CMD13) */ +#define HAL_MMC_CARD_IDENTIFICATION 0x00000002U /*!< Card is in identification state (can't be checked by CMD13) */ +#define HAL_MMC_CARD_STANDBY 0x00000003U /*!< Card is in standby state */ +#define HAL_MMC_CARD_TRANSFER 0x00000004U /*!< Card is in transfer state */ +#define HAL_MMC_CARD_SENDING 0x00000005U /*!< Card is sending an operation */ +#define HAL_MMC_CARD_RECEIVING 0x00000006U /*!< Card is receiving operation information */ +#define HAL_MMC_CARD_PROGRAMMING 0x00000007U /*!< Card is in programming state */ +#define HAL_MMC_CARD_DISCONNECTED 0x00000008U /*!< Card is disconnected */ +#define HAL_MMC_CARD_BUSTEST 0x00000009U /*!< Card is in bus test state */ +#define HAL_MMC_CARD_SLEEP 0x0000000AU /*!< Card is in sleep state (can't be checked by CMD13) */ +#define HAL_MMC_CARD_ERROR 0x000000FFU /*!< Card response Error (can't be checked by CMD13) */ +/** + * @} + */ + +/** @defgroup MMC_Exported_Types_Group3 MMC Handle Structure definition + * @{ + */ +#define MMC_InitTypeDef SDMMC_InitTypeDef +#define MMC_TypeDef SDMMC_TypeDef + +/** + * @brief MMC Card Information Structure definition + */ +typedef struct +{ + uint32_t CardType; /*!< Specifies the card Type */ + + uint32_t Class; /*!< Specifies the class of the card class */ + + uint32_t RelCardAdd; /*!< Specifies the Relative Card Address */ + + uint32_t BlockNbr; /*!< Specifies the Card Capacity in blocks */ + + uint32_t BlockSize; /*!< Specifies one block size in bytes */ + + uint32_t LogBlockNbr; /*!< Specifies the Card logical Capacity in blocks */ + + uint32_t LogBlockSize; /*!< Specifies logical block size in bytes */ + +} HAL_MMC_CardInfoTypeDef; + +/** + * @brief MMC handle Structure definition + */ +#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) +typedef struct __MMC_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */ +{ + MMC_TypeDef *Instance; /*!< MMC registers base address */ + + MMC_InitTypeDef Init; /*!< MMC required parameters */ + + HAL_LockTypeDef Lock; /*!< MMC locking object */ + + const uint8_t *pTxBuffPtr; /*!< Pointer to MMC Tx transfer Buffer */ + + uint32_t TxXferSize; /*!< MMC Tx Transfer size */ + + uint8_t *pRxBuffPtr; /*!< Pointer to MMC Rx transfer Buffer */ + + uint32_t RxXferSize; /*!< MMC Rx Transfer size */ + + __IO uint32_t Context; /*!< MMC transfer context */ + + __IO HAL_MMC_StateTypeDef State; /*!< MMC card State */ + + __IO uint32_t ErrorCode; /*!< MMC Card Error codes */ + + HAL_MMC_CardInfoTypeDef MmcCard; /*!< MMC Card information */ + + uint32_t CSD[4U]; /*!< MMC card specific data table */ + + uint32_t CID[4U]; /*!< MMC card identification number table */ + + uint32_t Ext_CSD[128]; + +#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) + void (* TxCpltCallback)(struct __MMC_HandleTypeDef *hmmc); + void (* RxCpltCallback)(struct __MMC_HandleTypeDef *hmmc); + void (* ErrorCallback)(struct __MMC_HandleTypeDef *hmmc); + void (* AbortCpltCallback)(struct __MMC_HandleTypeDef *hmmc); + void (* Read_DMALnkLstBufCpltCallback)(struct __MMC_HandleTypeDef *hmmc); + void (* Write_DMALnkLstBufCpltCallback)(struct __MMC_HandleTypeDef *hmmc); + + void (* MspInitCallback)(struct __MMC_HandleTypeDef *hmmc); + void (* MspDeInitCallback)(struct __MMC_HandleTypeDef *hmmc); +#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */ +} MMC_HandleTypeDef; + + +/** + * @} + */ + +/** @defgroup MMC_Exported_Types_Group4 Card Specific Data: CSD Register + * @{ + */ +typedef struct +{ + __IO uint8_t CSDStruct; /*!< CSD structure */ + __IO uint8_t SysSpecVersion; /*!< System specification version */ + __IO uint8_t Reserved1; /*!< Reserved */ + __IO uint8_t TAAC; /*!< Data read access time 1 */ + __IO uint8_t NSAC; /*!< Data read access time 2 in CLK cycles */ + __IO uint8_t MaxBusClkFrec; /*!< Max. bus clock frequency */ + __IO uint16_t CardComdClasses; /*!< Card command classes */ + __IO uint8_t RdBlockLen; /*!< Max. read data block length */ + __IO uint8_t PartBlockRead; /*!< Partial blocks for read allowed */ + __IO uint8_t WrBlockMisalign; /*!< Write block misalignment */ + __IO uint8_t RdBlockMisalign; /*!< Read block misalignment */ + __IO uint8_t DSRImpl; /*!< DSR implemented */ + __IO uint8_t Reserved2; /*!< Reserved */ + __IO uint32_t DeviceSize; /*!< Device Size */ + __IO uint8_t MaxRdCurrentVDDMin; /*!< Max. read current @ VDD min */ + __IO uint8_t MaxRdCurrentVDDMax; /*!< Max. read current @ VDD max */ + __IO uint8_t MaxWrCurrentVDDMin; /*!< Max. write current @ VDD min */ + __IO uint8_t MaxWrCurrentVDDMax; /*!< Max. write current @ VDD max */ + __IO uint8_t DeviceSizeMul; /*!< Device size multiplier */ + __IO uint8_t EraseGrSize; /*!< Erase group size */ + __IO uint8_t EraseGrMul; /*!< Erase group size multiplier */ + __IO uint8_t WrProtectGrSize; /*!< Write protect group size */ + __IO uint8_t WrProtectGrEnable; /*!< Write protect group enable */ + __IO uint8_t ManDeflECC; /*!< Manufacturer default ECC */ + __IO uint8_t WrSpeedFact; /*!< Write speed factor */ + __IO uint8_t MaxWrBlockLen; /*!< Max. write data block length */ + __IO uint8_t WriteBlockPaPartial; /*!< Partial blocks for write allowed */ + __IO uint8_t Reserved3; /*!< Reserved */ + __IO uint8_t ContentProtectAppli; /*!< Content protection application */ + __IO uint8_t FileFormatGroup; /*!< File format group */ + __IO uint8_t CopyFlag; /*!< Copy flag (OTP) */ + __IO uint8_t PermWrProtect; /*!< Permanent write protection */ + __IO uint8_t TempWrProtect; /*!< Temporary write protection */ + __IO uint8_t FileFormat; /*!< File format */ + __IO uint8_t ECC; /*!< ECC code */ + __IO uint8_t CSD_CRC; /*!< CSD CRC */ + __IO uint8_t Reserved4; /*!< Always 1 */ + +} HAL_MMC_CardCSDTypeDef; +/** + * @} + */ + +/** @defgroup MMC_Exported_Types_Group5 Card Identification Data: CID Register + * @{ + */ +typedef struct +{ + __IO uint8_t ManufacturerID; /*!< Manufacturer ID */ + __IO uint16_t OEM_AppliID; /*!< OEM/Application ID */ + __IO uint32_t ProdName1; /*!< Product Name part1 */ + __IO uint8_t ProdName2; /*!< Product Name part2 */ + __IO uint8_t ProdRev; /*!< Product Revision */ + __IO uint32_t ProdSN; /*!< Product Serial Number */ + __IO uint8_t Reserved1; /*!< Reserved1 */ + __IO uint16_t ManufactDate; /*!< Manufacturing Date */ + __IO uint8_t CID_CRC; /*!< CID CRC */ + __IO uint8_t Reserved2; /*!< Always 1 */ + +} HAL_MMC_CardCIDTypeDef; +/** + * @} + */ + +#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) +/** @defgroup MMC_Exported_Types_Group6 MMC Callback ID enumeration definition + * @{ + */ +typedef enum +{ + HAL_MMC_TX_CPLT_CB_ID = 0x00U, /*!< MMC Tx Complete Callback ID */ + HAL_MMC_RX_CPLT_CB_ID = 0x01U, /*!< MMC Rx Complete Callback ID */ + HAL_MMC_ERROR_CB_ID = 0x02U, /*!< MMC Error Callback ID */ + HAL_MMC_ABORT_CB_ID = 0x03U, /*!< MMC Abort Callback ID */ + HAL_MMC_READ_DMA_LNKLST_BUF_CPLT_CB_ID = 0x04U, /*!< MMC DMA Rx Linked List Node buffer Callback ID */ + HAL_MMC_WRITE_DMA_LNKLST_BUF_CPLT_CB_ID = 0x05U, /*!< MMC DMA Tx Linked List Node buffer Callback ID */ + + HAL_MMC_MSP_INIT_CB_ID = 0x10U, /*!< MMC MspInit Callback ID */ + HAL_MMC_MSP_DEINIT_CB_ID = 0x11U /*!< MMC MspDeInit Callback ID */ +} HAL_MMC_CallbackIDTypeDef; +/** + * @} + */ + +/** @defgroup MMC_Exported_Types_Group7 MMC Callback pointer definition + * @{ + */ +typedef void (*pMMC_CallbackTypeDef)(MMC_HandleTypeDef *hmmc); +/** + * @} + */ +#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */ +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup MMC_Exported_Constants Exported Constants + * @{ + */ + +#define MMC_BLOCKSIZE ((uint32_t)512U) /*!< Block size is 512 bytes */ + +/** @defgroup MMC_Exported_Constansts_Group1 MMC Error status enumeration Structure definition + * @{ + */ +#define HAL_MMC_ERROR_NONE SDMMC_ERROR_NONE /*!< No error */ +#define HAL_MMC_ERROR_CMD_CRC_FAIL SDMMC_ERROR_CMD_CRC_FAIL /*!< Command response received (but CRC check failed) */ +#define HAL_MMC_ERROR_DATA_CRC_FAIL SDMMC_ERROR_DATA_CRC_FAIL /*!< Data block sent/received (CRC check failed) */ +#define HAL_MMC_ERROR_CMD_RSP_TIMEOUT SDMMC_ERROR_CMD_RSP_TIMEOUT /*!< Command response timeout */ +#define HAL_MMC_ERROR_DATA_TIMEOUT SDMMC_ERROR_DATA_TIMEOUT /*!< Data timeout */ +#define HAL_MMC_ERROR_TX_UNDERRUN SDMMC_ERROR_TX_UNDERRUN /*!< Transmit FIFO underrun */ +#define HAL_MMC_ERROR_RX_OVERRUN SDMMC_ERROR_RX_OVERRUN /*!< Receive FIFO overrun */ +#define HAL_MMC_ERROR_ADDR_MISALIGNED SDMMC_ERROR_ADDR_MISALIGNED /*!< Misaligned address */ +#define HAL_MMC_ERROR_BLOCK_LEN_ERR SDMMC_ERROR_BLOCK_LEN_ERR /*!< Transferred block length is not allowed for the card or the */ +/*!< number of transferred bytes does not match the block length */ +#define HAL_MMC_ERROR_ERASE_SEQ_ERR SDMMC_ERROR_ERASE_SEQ_ERR /*!< An error in the sequence of erase command occurs */ +#define HAL_MMC_ERROR_BAD_ERASE_PARAM SDMMC_ERROR_BAD_ERASE_PARAM /*!< An invalid selection for erase groups */ +#define HAL_MMC_ERROR_WRITE_PROT_VIOLATION SDMMC_ERROR_WRITE_PROT_VIOLATION /*!< Attempt to program a write protect block */ +#define HAL_MMC_ERROR_LOCK_UNLOCK_FAILED SDMMC_ERROR_LOCK_UNLOCK_FAILED /*!< Sequence or password error has been detected in unlock */ +/*!< command or if there was an attempt to access a locked card */ +#define HAL_MMC_ERROR_COM_CRC_FAILED SDMMC_ERROR_COM_CRC_FAILED /*!< CRC check of the previous command failed */ +#define HAL_MMC_ERROR_ILLEGAL_CMD SDMMC_ERROR_ILLEGAL_CMD /*!< Command is not legal for the card state */ +#define HAL_MMC_ERROR_CARD_ECC_FAILED SDMMC_ERROR_CARD_ECC_FAILED /*!< Card internal ECC was applied but failed to correct the data */ +#define HAL_MMC_ERROR_CC_ERR SDMMC_ERROR_CC_ERR /*!< Internal card controller error */ +#define HAL_MMC_ERROR_GENERAL_UNKNOWN_ERR SDMMC_ERROR_GENERAL_UNKNOWN_ERR /*!< General or unknown error */ +#define HAL_MMC_ERROR_STREAM_READ_UNDERRUN SDMMC_ERROR_STREAM_READ_UNDERRUN /*!< The card could not sustain data reading in stream rmode */ +#define HAL_MMC_ERROR_STREAM_WRITE_OVERRUN SDMMC_ERROR_STREAM_WRITE_OVERRUN /*!< The card could not sustain data programming in stream mode */ +#define HAL_MMC_ERROR_CID_CSD_OVERWRITE SDMMC_ERROR_CID_CSD_OVERWRITE /*!< CID/CSD overwrite error */ +#define HAL_MMC_ERROR_WP_ERASE_SKIP SDMMC_ERROR_WP_ERASE_SKIP /*!< Only partial address space was erased */ +#define HAL_MMC_ERROR_CARD_ECC_DISABLED SDMMC_ERROR_CARD_ECC_DISABLED /*!< Command has been executed without using internal ECC */ +#define HAL_MMC_ERROR_ERASE_RESET SDMMC_ERROR_ERASE_RESET /*!< Erase sequence was cleared before executing because an out */ +/*!< of erase sequence command was received */ +#define HAL_MMC_ERROR_AKE_SEQ_ERR SDMMC_ERROR_AKE_SEQ_ERR /*!< Error in sequence of authentication */ +#define HAL_MMC_ERROR_INVALID_VOLTRANGE SDMMC_ERROR_INVALID_VOLTRANGE /*!< Error in case of invalid voltage range */ +#define HAL_MMC_ERROR_ADDR_OUT_OF_RANGE SDMMC_ERROR_ADDR_OUT_OF_RANGE /*!< Error when addressed block is out of range */ +#define HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE SDMMC_ERROR_REQUEST_NOT_APPLICABLE /*!< Error when command request is not applicable */ +#define HAL_MMC_ERROR_PARAM SDMMC_ERROR_INVALID_PARAMETER /*!< the used parameter is not valid */ +#define HAL_MMC_ERROR_UNSUPPORTED_FEATURE SDMMC_ERROR_UNSUPPORTED_FEATURE /*!< Error when feature is not insupported */ +#define HAL_MMC_ERROR_BUSY SDMMC_ERROR_BUSY /*!< Error when transfer process is busy */ +#define HAL_MMC_ERROR_DMA SDMMC_ERROR_DMA /*!< Error while DMA transfer */ +#define HAL_MMC_ERROR_TIMEOUT SDMMC_ERROR_TIMEOUT /*!< Timeout error */ + +#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) +#define HAL_MMC_ERROR_INVALID_CALLBACK SDMMC_ERROR_INVALID_PARAMETER /*!< Invalid callback error */ +#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @defgroup MMC_Exported_Constansts_Group2 MMC context enumeration + * @{ + */ +#define MMC_CONTEXT_NONE ((uint32_t)0x00000000U) /*!< None */ +#define MMC_CONTEXT_READ_SINGLE_BLOCK ((uint32_t)0x00000001U) /*!< Read single block operation */ +#define MMC_CONTEXT_READ_MULTIPLE_BLOCK ((uint32_t)0x00000002U) /*!< Read multiple blocks operation */ +#define MMC_CONTEXT_WRITE_SINGLE_BLOCK ((uint32_t)0x00000010U) /*!< Write single block operation */ +#define MMC_CONTEXT_WRITE_MULTIPLE_BLOCK ((uint32_t)0x00000020U) /*!< Write multiple blocks operation */ +#define MMC_CONTEXT_IT ((uint32_t)0x00000008U) /*!< Process in Interrupt mode */ +#define MMC_CONTEXT_DMA ((uint32_t)0x00000080U) /*!< Process in DMA mode */ + +/** + * @} + */ + +/** @defgroup MMC_Exported_Constansts_Group3 MMC Voltage mode + * @{ + */ +/** + * @brief + */ +#define MMC_HIGH_VOLTAGE_RANGE 0x80FF8000U /*!< High voltage in byte mode */ +#define MMC_DUAL_VOLTAGE_RANGE 0x80FF8080U /*!< Dual voltage in byte mode */ +#define MMC_LOW_VOLTAGE_RANGE 0x80000080U /*!< Low voltage in byte mode */ +#define EMMC_HIGH_VOLTAGE_RANGE 0xC0FF8000U /*!< High voltage in sector mode */ +#define EMMC_DUAL_VOLTAGE_RANGE 0xC0FF8080U /*!< Dual voltage in sector mode */ +#define EMMC_LOW_VOLTAGE_RANGE 0xC0000080U /*!< Low voltage in sector mode */ +#define MMC_INVALID_VOLTAGE_RANGE 0x0001FF01U +/** + * @} + */ + +/** @defgroup MMC_Exported_Constansts_Group4 MMC Memory Cards + * @{ + */ +#define MMC_LOW_CAPACITY_CARD ((uint32_t)0x00000000U) /*!< MMC Card Capacity <=2Gbytes */ +#define MMC_HIGH_CAPACITY_CARD ((uint32_t)0x00000001U) /*!< MMC Card Capacity >2Gbytes and <2Tbytes */ + +/** + * @} + */ + +/** @defgroup MMC_Exported_Constansts_Group5 MMC Erase Type + * @{ + */ +#define HAL_MMC_ERASE 0x00000000U /*!< Erase the erase groups identified by CMD35 & 36 */ +#define HAL_MMC_TRIM 0x00000001U /*!< Erase the write blocks identified by CMD35 & 36 */ +#define HAL_MMC_DISCARD 0x00000003U /*!< Discard the write blocks identified by CMD35 & 36 */ +#define HAL_MMC_SECURE_ERASE 0x80000000U /*!< Perform a secure purge according SRT on the erase groups identified by CMD35 & 36 */ +#define HAL_MMC_SECURE_TRIM_STEP1 0x80000001U /*!< Mark the write blocks identified by CMD35 & 36 for secure erase */ +#define HAL_MMC_SECURE_TRIM_STEP2 0x80008000U /*!< Perform a secure purge according SRT on the write blocks previously identified */ + +#define IS_MMC_ERASE_TYPE(TYPE) (((TYPE) == HAL_MMC_ERASE) || \ + ((TYPE) == HAL_MMC_TRIM) || \ + ((TYPE) == HAL_MMC_DISCARD) || \ + ((TYPE) == HAL_MMC_SECURE_ERASE) || \ + ((TYPE) == HAL_MMC_SECURE_TRIM_STEP1) || \ + ((TYPE) == HAL_MMC_SECURE_TRIM_STEP2)) +/** + * @} + */ + +/** @defgroup MMC_Exported_Constansts_Group6 MMC Secure Removal Type + * @{ + */ +#define HAL_MMC_SRT_ERASE 0x00000001U /*!< Information removed by an erase */ +#define HAL_MMC_SRT_WRITE_CHAR_ERASE 0x00000002U /*!< Information removed by an overwriting with a character followed by an erase */ +#define HAL_MMC_SRT_WRITE_CHAR_COMPL_RANDOM 0x00000004U /*!< Information removed by an overwriting with a character, its complement then a random character */ +#define HAL_MMC_SRT_VENDOR_DEFINED 0x00000008U /*!< Information removed using a vendor defined */ + + +#define IS_MMC_SRT_TYPE(TYPE) (((TYPE) == HAL_MMC_SRT_ERASE) || \ + ((TYPE) == HAL_MMC_SRT_WRITE_CHAR_ERASE) || \ + ((TYPE) == HAL_MMC_SRT_WRITE_CHAR_COMPL_RANDOM) || \ + ((TYPE) == HAL_MMC_SRT_VENDOR_DEFINED)) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup MMC_Exported_macros MMC Exported Macros + * @brief macros to handle interrupts and specific clock configurations + * @{ + */ +/** @brief Reset MMC handle state. + * @param __HANDLE__ MMC Handle. + * @retval None + */ +#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) +#define __HAL_MMC_RESET_HANDLE_STATE(__HANDLE__) do { \ + (__HANDLE__)->State = HAL_MMC_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_MMC_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_MMC_STATE_RESET) +#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */ + +/** + * @brief Enable the MMC device interrupt. + * @param __HANDLE__ MMC Handle. + * @param __INTERRUPT__ specifies the SDMMC interrupt sources to be enabled. + * This parameter can be one or a combination of the following values: + * @arg SDMMC_IT_CCRCFAIL: Command response received (CRC check failed) interrupt + * @arg SDMMC_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt + * @arg SDMMC_IT_CTIMEOUT: Command response timeout interrupt + * @arg SDMMC_IT_DTIMEOUT: Data timeout interrupt + * @arg SDMMC_IT_TXUNDERR: Transmit FIFO underrun error interrupt + * @arg SDMMC_IT_RXOVERR: Received FIFO overrun error interrupt + * @arg SDMMC_IT_CMDREND: Command response received (CRC check passed) interrupt + * @arg SDMMC_IT_CMDSENT: Command sent (no response required) interrupt + * @arg SDMMC_IT_DATAEND: Data end (data counter, DATACOUNT, is zero) interrupt + * @arg SDMMC_IT_DHOLD: Data transfer Hold interrupt + * @arg SDMMC_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt + * @arg SDMMC_IT_DABORT: Data transfer aborted by CMD12 interrupt + * @arg SDMMC_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt + * @arg SDMMC_IT_RXFIFOHF: Receive FIFO Half Full interrupt + * @arg SDMMC_IT_RXFIFOF: Receive FIFO full interrupt + * @arg SDMMC_IT_TXFIFOE: Transmit FIFO empty interrupt + * @arg SDMMC_IT_BUSYD0END: End of SDMMC_D0 Busy following a CMD response detected interrupt + * @arg SDMMC_IT_SDIOIT: SD I/O interrupt received interrupt + * @arg SDMMC_IT_ACKFAIL: Boot Acknowledgment received interrupt + * @arg SDMMC_IT_ACKTIMEOUT: Boot Acknowledgment timeout interrupt + * @arg SDMMC_IT_VSWEND: Voltage switch critical timing section completion interrupt + * @arg SDMMC_IT_CKSTOP: SDMMC_CK stopped in Voltage switch procedure interrupt + * @arg SDMMC_IT_IDMABTC: IDMA buffer transfer complete interrupt + * @retval None + */ +#define __HAL_MMC_ENABLE_IT(__HANDLE__, __INTERRUPT__) __SDMMC_ENABLE_IT((__HANDLE__)->Instance, (__INTERRUPT__)) + +/** + * @brief Disable the MMC device interrupt. + * @param __HANDLE__ MMC Handle. + * @param __INTERRUPT__ specifies the SDMMC interrupt sources to be disabled. + * This parameter can be one or a combination of the following values: + * @arg SDMMC_IT_CCRCFAIL: Command response received (CRC check failed) interrupt + * @arg SDMMC_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt + * @arg SDMMC_IT_CTIMEOUT: Command response timeout interrupt + * @arg SDMMC_IT_DTIMEOUT: Data timeout interrupt + * @arg SDMMC_IT_TXUNDERR: Transmit FIFO underrun error interrupt + * @arg SDMMC_IT_RXOVERR: Received FIFO overrun error interrupt + * @arg SDMMC_IT_CMDREND: Command response received (CRC check passed) interrupt + * @arg SDMMC_IT_CMDSENT: Command sent (no response required) interrupt + * @arg SDMMC_IT_DATAEND: Data end (data counter, DATACOUNT, is zero) interrupt + * @arg SDMMC_IT_DHOLD: Data transfer Hold interrupt + * @arg SDMMC_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt + * @arg SDMMC_IT_DABORT: Data transfer aborted by CMD12 interrupt + * @arg SDMMC_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt + * @arg SDMMC_IT_RXFIFOHF: Receive FIFO Half Full interrupt + * @arg SDMMC_IT_RXFIFOF: Receive FIFO full interrupt + * @arg SDMMC_IT_TXFIFOE: Transmit FIFO empty interrupt + * @arg SDMMC_IT_BUSYD0END: End of SDMMC_D0 Busy following a CMD response detected interrupt + * @arg SDMMC_IT_SDIOIT: SD I/O interrupt received interrupt + * @arg SDMMC_IT_ACKFAIL: Boot Acknowledgment received interrupt + * @arg SDMMC_IT_ACKTIMEOUT: Boot Acknowledgment timeout interrupt + * @arg SDMMC_IT_VSWEND: Voltage switch critical timing section completion interrupt + * @arg SDMMC_IT_CKSTOP: SDMMC_CK stopped in Voltage switch procedure interrupt + * @arg SDMMC_IT_IDMABTC: IDMA buffer transfer complete interrupt + * @retval None + */ +#define __HAL_MMC_DISABLE_IT(__HANDLE__, __INTERRUPT__) __SDMMC_DISABLE_IT((__HANDLE__)->Instance, (__INTERRUPT__)) + +/** + * @brief Check whether the specified MMC flag is set or not. + * @param __HANDLE__ MMC Handle. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg SDMMC_FLAG_CCRCFAIL: Command response received (CRC check failed) + * @arg SDMMC_FLAG_DCRCFAIL: Data block sent/received (CRC check failed) + * @arg SDMMC_FLAG_CTIMEOUT: Command response timeout + * @arg SDMMC_FLAG_DTIMEOUT: Data timeout + * @arg SDMMC_FLAG_TXUNDERR: Transmit FIFO underrun error + * @arg SDMMC_FLAG_RXOVERR: Received FIFO overrun error + * @arg SDMMC_FLAG_CMDREND: Command response received (CRC check passed) + * @arg SDMMC_FLAG_CMDSENT: Command sent (no response required) + * @arg SDMMC_FLAG_DATAEND: Data end (data counter, DATACOUNT, is zero) + * @arg SDMMC_FLAG_DHOLD: Data transfer Hold + * @arg SDMMC_FLAG_DBCKEND: Data block sent/received (CRC check passed) + * @arg SDMMC_FLAG_DABORT: Data transfer aborted by CMD12 + * @arg SDMMC_FLAG_DPSMACT: Data path state machine active + * @arg SDMMC_FLAG_CPSMACT: Command path state machine active + * @arg SDMMC_FLAG_TXFIFOHE: Transmit FIFO Half Empty + * @arg SDMMC_FLAG_RXFIFOHF: Receive FIFO Half Full + * @arg SDMMC_FLAG_TXFIFOF: Transmit FIFO full + * @arg SDMMC_FLAG_RXFIFOF: Receive FIFO full + * @arg SDMMC_FLAG_TXFIFOE: Transmit FIFO empty + * @arg SDMMC_FLAG_RXFIFOE: Receive FIFO empty + * @arg SDMMC_FLAG_BUSYD0: Inverted value of SDMMC_D0 line (Busy) + * @arg SDMMC_FLAG_BUSYD0END: End of SDMMC_D0 Busy following a CMD response detected + * @arg SDMMC_FLAG_SDIOIT: SD I/O interrupt received + * @arg SDMMC_FLAG_ACKFAIL: Boot Acknowledgment received + * @arg SDMMC_FLAG_ACKTIMEOUT: Boot Acknowledgment timeout + * @arg SDMMC_FLAG_VSWEND: Voltage switch critical timing section completion + * @arg SDMMC_FLAG_CKSTOP: SDMMC_CK stopped in Voltage switch procedure + * @arg SDMMC_FLAG_IDMATE: IDMA transfer error + * @arg SDMMC_FLAG_IDMABTC: IDMA buffer transfer complete + * @retval The new state of MMC FLAG (SET or RESET). + */ +#define __HAL_MMC_GET_FLAG(__HANDLE__, __FLAG__) __SDMMC_GET_FLAG((__HANDLE__)->Instance, (__FLAG__)) + +/** + * @brief Clear the MMC's pending flags. + * @param __HANDLE__ MMC Handle. + * @param __FLAG__ specifies the flag to clear. + * This parameter can be one or a combination of the following values: + * @arg SDMMC_FLAG_CCRCFAIL: Command response received (CRC check failed) + * @arg SDMMC_FLAG_DCRCFAIL: Data block sent/received (CRC check failed) + * @arg SDMMC_FLAG_CTIMEOUT: Command response timeout + * @arg SDMMC_FLAG_DTIMEOUT: Data timeout + * @arg SDMMC_FLAG_TXUNDERR: Transmit FIFO underrun error + * @arg SDMMC_FLAG_RXOVERR: Received FIFO overrun error + * @arg SDMMC_FLAG_CMDREND: Command response received (CRC check passed) + * @arg SDMMC_FLAG_CMDSENT: Command sent (no response required) + * @arg SDMMC_FLAG_DATAEND: Data end (data counter, DATACOUNT, is zero) + * @arg SDMMC_FLAG_DHOLD: Data transfer Hold + * @arg SDMMC_FLAG_DBCKEND: Data block sent/received (CRC check passed) + * @arg SDMMC_FLAG_DABORT: Data transfer aborted by CMD12 + * @arg SDMMC_FLAG_BUSYD0END: End of SDMMC_D0 Busy following a CMD response detected + * @arg SDMMC_FLAG_SDIOIT: SD I/O interrupt received + * @arg SDMMC_FLAG_ACKFAIL: Boot Acknowledgment received + * @arg SDMMC_FLAG_ACKTIMEOUT: Boot Acknowledgment timeout + * @arg SDMMC_FLAG_VSWEND: Voltage switch critical timing section completion + * @arg SDMMC_FLAG_CKSTOP: SDMMC_CK stopped in Voltage switch procedure + * @arg SDMMC_FLAG_IDMATE: IDMA transfer error + * @arg SDMMC_FLAG_IDMABTC: IDMA buffer transfer complete + * @retval None + */ +#define __HAL_MMC_CLEAR_FLAG(__HANDLE__, __FLAG__) __SDMMC_CLEAR_FLAG((__HANDLE__)->Instance, (__FLAG__)) + +/** + * @brief Check whether the specified MMC interrupt has occurred or not. + * @param __HANDLE__ MMC Handle. + * @param __INTERRUPT__ specifies the SDMMC interrupt source to check. + * This parameter can be one of the following values: + * @arg SDMMC_IT_CCRCFAIL: Command response received (CRC check failed) interrupt + * @arg SDMMC_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt + * @arg SDMMC_IT_CTIMEOUT: Command response timeout interrupt + * @arg SDMMC_IT_DTIMEOUT: Data timeout interrupt + * @arg SDMMC_IT_TXUNDERR: Transmit FIFO underrun error interrupt + * @arg SDMMC_IT_RXOVERR: Received FIFO overrun error interrupt + * @arg SDMMC_IT_CMDREND: Command response received (CRC check passed) interrupt + * @arg SDMMC_IT_CMDSENT: Command sent (no response required) interrupt + * @arg SDMMC_IT_DATAEND: Data end (data counter, DATACOUNT, is zero) interrupt + * @arg SDMMC_IT_DHOLD: Data transfer Hold interrupt + * @arg SDMMC_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt + * @arg SDMMC_IT_DABORT: Data transfer aborted by CMD12 interrupt + * @arg SDMMC_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt + * @arg SDMMC_IT_RXFIFOHF: Receive FIFO Half Full interrupt + * @arg SDMMC_IT_RXFIFOF: Receive FIFO full interrupt + * @arg SDMMC_IT_TXFIFOE: Transmit FIFO empty interrupt + * @arg SDMMC_IT_BUSYD0END: End of SDMMC_D0 Busy following a CMD response detected interrupt + * @arg SDMMC_IT_SDIOIT: SD I/O interrupt received interrupt + * @arg SDMMC_IT_ACKFAIL: Boot Acknowledgment received interrupt + * @arg SDMMC_IT_ACKTIMEOUT: Boot Acknowledgment timeout interrupt + * @arg SDMMC_IT_VSWEND: Voltage switch critical timing section completion interrupt + * @arg SDMMC_IT_CKSTOP: SDMMC_CK stopped in Voltage switch procedure interrupt + * @arg SDMMC_IT_IDMABTC: IDMA buffer transfer complete interrupt + * @retval The new state of MMC IT (SET or RESET). + */ +#define __HAL_MMC_GET_IT(__HANDLE__, __INTERRUPT__) __SDMMC_GET_IT((__HANDLE__)->Instance, (__INTERRUPT__)) + +/** + * @brief Clear the MMC's interrupt pending bits. + * @param __HANDLE__ MMC Handle. + * @param __INTERRUPT__ specifies the interrupt pending bit to clear. + * This parameter can be one or a combination of the following values: + * @arg SDMMC_IT_CCRCFAIL: Command response received (CRC check failed) interrupt + * @arg SDMMC_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt + * @arg SDMMC_IT_CTIMEOUT: Command response timeout interrupt + * @arg SDMMC_IT_DTIMEOUT: Data timeout interrupt + * @arg SDMMC_IT_TXUNDERR: Transmit FIFO underrun error interrupt + * @arg SDMMC_IT_RXOVERR: Received FIFO overrun error interrupt + * @arg SDMMC_IT_CMDREND: Command response received (CRC check passed) interrupt + * @arg SDMMC_IT_CMDSENT: Command sent (no response required) interrupt + * @arg SDMMC_IT_DATAEND: Data end (data counter, DATACOUNT, is zero) interrupt + * @arg SDMMC_IT_DHOLD: Data transfer Hold interrupt + * @arg SDMMC_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt + * @arg SDMMC_IT_DABORT: Data transfer aborted by CMD12 interrupt + * @arg SDMMC_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt + * @arg SDMMC_IT_RXFIFOHF: Receive FIFO Half Full interrupt + * @arg SDMMC_IT_RXFIFOF: Receive FIFO full interrupt + * @arg SDMMC_IT_TXFIFOE: Transmit FIFO empty interrupt + * @arg SDMMC_IT_BUSYD0END: End of SDMMC_D0 Busy following a CMD response detected interrupt + * @arg SDMMC_IT_SDIOIT: SD I/O interrupt received interrupt + * @arg SDMMC_IT_ACKFAIL: Boot Acknowledgment received interrupt + * @arg SDMMC_IT_ACKTIMEOUT: Boot Acknowledgment timeout interrupt + * @arg SDMMC_IT_VSWEND: Voltage switch critical timing section completion interrupt + * @arg SDMMC_IT_CKSTOP: SDMMC_CK stopped in Voltage switch procedure interrupt + * @arg SDMMC_IT_IDMABTC: IDMA buffer transfer complete interrupt + * @retval None + */ +#define __HAL_MMC_CLEAR_IT(__HANDLE__, __INTERRUPT__) __SDMMC_CLEAR_IT((__HANDLE__)->Instance, (__INTERRUPT__)) + +/** + * @} + */ + +/* Include MMC HAL Extension module */ +#include "stm32h5xx_hal_mmc_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup MMC_Exported_Functions MMC Exported Functions + * @{ + */ + +/** @defgroup MMC_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ +HAL_StatusTypeDef HAL_MMC_Init(MMC_HandleTypeDef *hmmc); +HAL_StatusTypeDef HAL_MMC_InitCard(MMC_HandleTypeDef *hmmc); +HAL_StatusTypeDef HAL_MMC_DeInit(MMC_HandleTypeDef *hmmc); +void HAL_MMC_MspInit(MMC_HandleTypeDef *hmmc); +void HAL_MMC_MspDeInit(MMC_HandleTypeDef *hmmc); + +/** + * @} + */ + +/** @defgroup MMC_Exported_Functions_Group2 Input and Output operation functions + * @{ + */ +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_MMC_ReadBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, + uint32_t NumberOfBlocks, + uint32_t Timeout); +HAL_StatusTypeDef HAL_MMC_WriteBlocks(MMC_HandleTypeDef *hmmc, const uint8_t *pData, uint32_t BlockAdd, + uint32_t NumberOfBlocks, uint32_t Timeout); +HAL_StatusTypeDef HAL_MMC_Erase(MMC_HandleTypeDef *hmmc, uint32_t BlockStartAdd, uint32_t BlockEndAdd); +/* Non-Blocking mode: IT */ +HAL_StatusTypeDef HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, + uint32_t NumberOfBlocks); +HAL_StatusTypeDef HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef *hmmc, const uint8_t *pData, uint32_t BlockAdd, + uint32_t NumberOfBlocks); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, + uint32_t NumberOfBlocks); +HAL_StatusTypeDef HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef *hmmc, const uint8_t *pData, uint32_t BlockAdd, + uint32_t NumberOfBlocks); + +void HAL_MMC_IRQHandler(MMC_HandleTypeDef *hmmc); + +/* Callback in non blocking modes (DMA) */ +void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc); +void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc); +void HAL_MMC_ErrorCallback(MMC_HandleTypeDef *hmmc); +void HAL_MMC_AbortCallback(MMC_HandleTypeDef *hmmc); + +#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) +/* MMC callback registering/unregistering */ +HAL_StatusTypeDef HAL_MMC_RegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId, + pMMC_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId); +#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @defgroup MMC_Exported_Functions_Group3 Peripheral Control functions + * @{ + */ +HAL_StatusTypeDef HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef *hmmc, uint32_t WideMode); +HAL_StatusTypeDef HAL_MMC_ConfigSpeedBusOperation(MMC_HandleTypeDef *hmmc, uint32_t SpeedMode); +/** + * @} + */ + +/** @defgroup MMC_Exported_Functions_Group4 MMC card related functions + * @{ + */ +HAL_MMC_CardStateTypeDef HAL_MMC_GetCardState(MMC_HandleTypeDef *hmmc); +HAL_StatusTypeDef HAL_MMC_GetCardCID(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID); +HAL_StatusTypeDef HAL_MMC_GetCardCSD(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCSDTypeDef *pCSD); +HAL_StatusTypeDef HAL_MMC_GetCardInfo(MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo); +HAL_StatusTypeDef HAL_MMC_GetCardExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pExtCSD, uint32_t Timeout); +/** + * @} + */ + +/** @defgroup MMC_Exported_Functions_Group5 Peripheral State and Errors functions + * @{ + */ +HAL_MMC_StateTypeDef HAL_MMC_GetState(const MMC_HandleTypeDef *hmmc); +uint32_t HAL_MMC_GetError(const MMC_HandleTypeDef *hmmc); +/** + * @} + */ + +/** @defgroup MMC_Exported_Functions_Group6 Peripheral Abort management + * @{ + */ +HAL_StatusTypeDef HAL_MMC_Abort(MMC_HandleTypeDef *hmmc); +HAL_StatusTypeDef HAL_MMC_Abort_IT(MMC_HandleTypeDef *hmmc); +/** + * @} + */ + +/** @defgroup MMC_Exported_Functions_Group7 Peripheral Erase management + * @{ + */ +HAL_StatusTypeDef HAL_MMC_EraseSequence(MMC_HandleTypeDef *hmmc, uint32_t EraseType, uint32_t BlockStartAdd, + uint32_t BlockEndAdd); +HAL_StatusTypeDef HAL_MMC_Sanitize(MMC_HandleTypeDef *hmmc); +HAL_StatusTypeDef HAL_MMC_ConfigSecRemovalType(MMC_HandleTypeDef *hmmc, uint32_t SRTMode); +HAL_StatusTypeDef HAL_MMC_GetSupportedSecRemovalType(MMC_HandleTypeDef *hmmc, uint32_t *SupportedSRT); +/** + * @} + */ + +/** @defgroup MMC_Exported_Functions_Group8 Peripheral Sleep management + * @{ + */ +HAL_StatusTypeDef HAL_MMC_SleepDevice(MMC_HandleTypeDef *hmmc); +HAL_StatusTypeDef HAL_MMC_AwakeDevice(MMC_HandleTypeDef *hmmc); +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/** @defgroup MMC_Private_Types MMC Private Types + * @{ + */ + +/** + * @} + */ + +/* Private defines -----------------------------------------------------------*/ +/** @defgroup MMC_Private_Defines MMC Private Defines + * @{ + */ +#define MMC_EXT_CSD_DATA_SEC_SIZE_INDEX 61 +#define MMC_EXT_CSD_DATA_SEC_SIZE_POS 8 +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup MMC_Private_Variables MMC Private Variables + * @{ + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup MMC_Private_Constants MMC Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup MMC_Private_Macros MMC Private Macros + * @{ + */ + +/** + * @} + */ + +/* Private functions prototypes ----------------------------------------------*/ +/** @defgroup MMC_Private_Functions_Prototypes MMC Private Functions Prototypes + * @{ + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup MMC_Private_Functions MMC Private Functions + * @{ + */ + +/** + * @} + */ + + +/** + * @} + */ + +/** + * @} + */ +#endif /* SDMMC1 || SDMMC2 */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* STM32H5xx_HAL_MMC_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_mmc_ex.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_mmc_ex.h new file mode 100644 index 0000000000..e5b17bd399 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_mmc_ex.h @@ -0,0 +1,122 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_mmc_ex.h + * @author MCD Application Team + * @brief Header file of SD HAL extended module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_MMC_EX_H +#define STM32H5xx_HAL_MMC_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ +#if defined (SDMMC1) || defined (SDMMC2) +/** @addtogroup MMCEx + * @brief SD HAL extended module driver + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup MMCEx_Exported_Types MMCEx Exported Types + * @{ + */ + +/** @defgroup MMCEx_Exported_Types_Group1 Linked List Wrapper + * @{ + */ +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* -----------------Linked List Wrapper --------------------------------------*/ + +#define MMC_DMALinkNodeTypeDef SDMMC_DMALinkNodeTypeDef +#define MMC_DMALinkNodeConfTypeDef SDMMC_DMALinkNodeConfTypeDef +#define MMC_DMALinkedListTypeDef SDMMC_DMALinkedListTypeDef +/* ----------------- Linked Aliases ------------------------------------------*/ +#define HAL_MMCx_DMALinkedList_WriteCpltCallback HAL_MMC_TxCpltCallback +#define HAL_MMCx_DMALinkedList_ReadCpltCallback HAL_MMC_RxCpltCallback +/** + * @} + */ + +/** + * @} + */ +/* Exported functions --------------------------------------------------------*/ +/** @defgroup MMCEx_Exported_Functions MMCEx Exported Functions + * @{ + */ + +/** @defgroup MMCEx_Exported_Functions_Group1 MultiBuffer functions + * @{ + */ +HAL_StatusTypeDef HAL_MMCEx_DMALinkedList_ReadBlocks(MMC_HandleTypeDef *hmmc, SDMMC_DMALinkedListTypeDef *pLinkedList, + uint32_t BlockAdd, uint32_t NumberOfBlocks); +HAL_StatusTypeDef HAL_MMCEx_DMALinkedList_WriteBlocks(MMC_HandleTypeDef *hmmc, SDMMC_DMALinkedListTypeDef *pLinkedList, + uint32_t BlockAdd, uint32_t NumberOfBlocks); + +HAL_StatusTypeDef HAL_MMCEx_DMALinkedList_BuildNode(MMC_DMALinkNodeTypeDef *pNode, + MMC_DMALinkNodeConfTypeDef *pNodeConf); +HAL_StatusTypeDef HAL_MMCEx_DMALinkedList_InsertNode(MMC_DMALinkedListTypeDef *pLinkedList, + MMC_DMALinkNodeTypeDef *pPrevNode, + MMC_DMALinkNodeTypeDef *pNewNode); +HAL_StatusTypeDef HAL_MMCEx_DMALinkedList_RemoveNode(MMC_DMALinkedListTypeDef *pLinkedList, + MMC_DMALinkNodeTypeDef *pNode); +HAL_StatusTypeDef HAL_MMCEx_DMALinkedList_LockNode(MMC_DMALinkNodeTypeDef *pNode); +HAL_StatusTypeDef HAL_MMCEx_DMALinkedList_UnlockNode(MMC_DMALinkNodeTypeDef *pNode); +HAL_StatusTypeDef HAL_MMCEx_DMALinkedList_EnableCircularMode(SDMMC_DMALinkedListTypeDef *pLinkedList); +HAL_StatusTypeDef HAL_MMCEx_DMALinkedList_DisableCircularMode(SDMMC_DMALinkedListTypeDef *pLinkedList); + +void HAL_MMCEx_Read_DMALnkLstBufCpltCallback(MMC_HandleTypeDef *hmmc); +void HAL_MMCEx_Write_DMALnkLstBufCpltCallback(MMC_HandleTypeDef *hmmc); + + +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Private functions prototypes ----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** + * @} + */ +#endif /* SDMMC1 || SDMMC2 */ + +/** + * @} + */ +#ifdef __cplusplus +} +#endif + + +#endif /* STM32H5xx_HAL_MMCEx_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_nand.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_nand.h new file mode 100644 index 0000000000..7b9b067abf --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_nand.h @@ -0,0 +1,378 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_nand.h + * @author MCD Application Team + * @brief Header file of NAND HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2022 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 STM32H5xx_HAL_NAND_H +#define STM32H5xx_HAL_NAND_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(FMC_BANK3) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_fmc.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup NAND + * @{ + */ + +/* Exported typedef ----------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/** @defgroup NAND_Exported_Types NAND Exported Types + * @{ + */ + +/** + * @brief HAL NAND State structures definition + */ +typedef enum +{ + HAL_NAND_STATE_RESET = 0x00U, /*!< NAND not yet initialized or disabled */ + HAL_NAND_STATE_READY = 0x01U, /*!< NAND initialized and ready for use */ + HAL_NAND_STATE_BUSY = 0x02U, /*!< NAND internal process is ongoing */ + HAL_NAND_STATE_ERROR = 0x03U /*!< NAND error state */ +} HAL_NAND_StateTypeDef; + +/** + * @brief NAND Memory electronic signature Structure definition + */ +typedef struct +{ + /*State = HAL_NAND_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_NAND_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_NAND_STATE_RESET) +#endif /* USE_HAL_NAND_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup NAND_Exported_Functions NAND Exported Functions + * @{ + */ + +/** @addtogroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ + +/* Initialization/de-initialization functions ********************************/ +HAL_StatusTypeDef HAL_NAND_Init(NAND_HandleTypeDef *hnand, FMC_NAND_PCC_TimingTypeDef *ComSpace_Timing, + FMC_NAND_PCC_TimingTypeDef *AttSpace_Timing); +HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand); + +HAL_StatusTypeDef HAL_NAND_ConfigDevice(NAND_HandleTypeDef *hnand, NAND_DeviceConfigTypeDef *pDeviceConfig); + +HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID); + +void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand); +void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand); +void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand); +void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand); + +/** + * @} + */ + +/** @addtogroup NAND_Exported_Functions_Group2 Input and Output functions + * @{ + */ + +/* IO operation functions ****************************************************/ +HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand); + +HAL_StatusTypeDef HAL_NAND_Read_Page_8b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress, + uint8_t *pBuffer, uint32_t NumPageToRead); +HAL_StatusTypeDef HAL_NAND_Write_Page_8b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress, + const uint8_t *pBuffer, uint32_t NumPageToWrite); +HAL_StatusTypeDef HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress, + uint8_t *pBuffer, uint32_t NumSpareAreaToRead); +HAL_StatusTypeDef HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress, + const uint8_t *pBuffer, uint32_t NumSpareAreaTowrite); + +HAL_StatusTypeDef HAL_NAND_Read_Page_16b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress, + uint16_t *pBuffer, uint32_t NumPageToRead); +HAL_StatusTypeDef HAL_NAND_Write_Page_16b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress, + const uint16_t *pBuffer, uint32_t NumPageToWrite); +HAL_StatusTypeDef HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress, + uint16_t *pBuffer, uint32_t NumSpareAreaToRead); +HAL_StatusTypeDef HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress, + const uint16_t *pBuffer, uint32_t NumSpareAreaTowrite); + +HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress); + +uint32_t HAL_NAND_Address_Inc(const NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress); + +#if (USE_HAL_NAND_REGISTER_CALLBACKS == 1) +/* NAND callback registering/unregistering */ +HAL_StatusTypeDef HAL_NAND_RegisterCallback(NAND_HandleTypeDef *hnand, HAL_NAND_CallbackIDTypeDef CallbackId, + pNAND_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_NAND_UnRegisterCallback(NAND_HandleTypeDef *hnand, HAL_NAND_CallbackIDTypeDef CallbackId); +#endif /* USE_HAL_NAND_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @addtogroup NAND_Exported_Functions_Group3 Peripheral Control functions + * @{ + */ + +/* NAND Control functions ****************************************************/ +HAL_StatusTypeDef HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand); +HAL_StatusTypeDef HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand); +HAL_StatusTypeDef HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout); + +/** + * @} + */ + +/** @addtogroup NAND_Exported_Functions_Group4 Peripheral State functions + * @{ + */ +/* NAND State functions *******************************************************/ +HAL_NAND_StateTypeDef HAL_NAND_GetState(const NAND_HandleTypeDef *hnand); +uint32_t HAL_NAND_Read_Status(const NAND_HandleTypeDef *hnand); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup NAND_Private_Constants NAND Private Constants + * @{ + */ +#define NAND_DEVICE 0x80000000UL +#define NAND_WRITE_TIMEOUT 0x01000000UL + +#define CMD_AREA (1UL<<16U) /* A16 = CLE high */ +#define ADDR_AREA (1UL<<17U) /* A17 = ALE high */ + +#define NAND_CMD_AREA_A ((uint8_t)0x00) +#define NAND_CMD_AREA_B ((uint8_t)0x01) +#define NAND_CMD_AREA_C ((uint8_t)0x50) +#define NAND_CMD_AREA_TRUE1 ((uint8_t)0x30) + +#define NAND_CMD_WRITE0 ((uint8_t)0x80) +#define NAND_CMD_WRITE_TRUE1 ((uint8_t)0x10) +#define NAND_CMD_ERASE0 ((uint8_t)0x60) +#define NAND_CMD_ERASE1 ((uint8_t)0xD0) +#define NAND_CMD_READID ((uint8_t)0x90) +#define NAND_CMD_STATUS ((uint8_t)0x70) +#define NAND_CMD_LOCK_STATUS ((uint8_t)0x7A) +#define NAND_CMD_RESET ((uint8_t)0xFF) + +/* NAND memory status */ +#define NAND_VALID_ADDRESS 0x00000100UL +#define NAND_INVALID_ADDRESS 0x00000200UL +#define NAND_TIMEOUT_ERROR 0x00000400UL +#define NAND_BUSY 0x00000000UL +#define NAND_ERROR 0x00000001UL +#define NAND_READY 0x00000040UL +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup NAND_Private_Macros NAND Private Macros + * @{ + */ + +/** + * @brief NAND memory address computation. + * @param __ADDRESS__ NAND memory address. + * @param __HANDLE__ NAND handle. + * @retval NAND Raw address value + */ +#define ARRAY_ADDRESS(__ADDRESS__ , __HANDLE__) ((__ADDRESS__)->Page + \ + (((__ADDRESS__)->Block + \ + (((__ADDRESS__)->Plane) * \ + ((__HANDLE__)->Config.PlaneSize))) * \ + ((__HANDLE__)->Config.BlockSize))) + +/** + * @brief NAND memory Column address computation. + * @param __HANDLE__ NAND handle. + * @retval NAND Raw address value + */ +#define COLUMN_ADDRESS( __HANDLE__) ((__HANDLE__)->Config.PageSize) + +/** + * @brief NAND memory address cycling. + * @param __ADDRESS__ NAND memory address. + * @retval NAND address cycling value. + */ +#define ADDR_1ST_CYCLE(__ADDRESS__) (uint8_t)(__ADDRESS__) /* 1st addressing cycle */ +#define ADDR_2ND_CYCLE(__ADDRESS__) (uint8_t)((__ADDRESS__) >> 8) /* 2nd addressing cycle */ +#define ADDR_3RD_CYCLE(__ADDRESS__) (uint8_t)((__ADDRESS__) >> 16) /* 3rd addressing cycle */ +#define ADDR_4TH_CYCLE(__ADDRESS__) (uint8_t)((__ADDRESS__) >> 24) /* 4th addressing cycle */ + +/** + * @brief NAND memory Columns cycling. + * @param __ADDRESS__ NAND memory address. + * @retval NAND Column address cycling value. + */ +#define COLUMN_1ST_CYCLE(__ADDRESS__) (uint8_t)((__ADDRESS__) & 0xFFU) /* 1st Column addressing cycle */ +#define COLUMN_2ND_CYCLE(__ADDRESS__) (uint8_t)((__ADDRESS__) >> 8) /* 2nd Column addressing cycle */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* FMC_BANK3 */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_NAND_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_nor.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_nor.h new file mode 100644 index 0000000000..98b2ff9d11 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_nor.h @@ -0,0 +1,326 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_nor.h + * @author MCD Application Team + * @brief Header file of NOR HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2022 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 STM32H5xx_HAL_NOR_H +#define STM32H5xx_HAL_NOR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(FMC_BANK1) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_fmc.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup NOR + * @{ + */ + +/* Exported typedef ----------------------------------------------------------*/ +/** @defgroup NOR_Exported_Types NOR Exported Types + * @{ + */ + +/** + * @brief HAL SRAM State structures definition + */ +typedef enum +{ + HAL_NOR_STATE_RESET = 0x00U, /*!< NOR not yet initialized or disabled */ + HAL_NOR_STATE_READY = 0x01U, /*!< NOR initialized and ready for use */ + HAL_NOR_STATE_BUSY = 0x02U, /*!< NOR internal processing is ongoing */ + HAL_NOR_STATE_ERROR = 0x03U, /*!< NOR error state */ + HAL_NOR_STATE_PROTECTED = 0x04U /*!< NOR NORSRAM device write protected */ +} HAL_NOR_StateTypeDef; + +/** + * @brief FMC NOR Status typedef + */ +typedef enum +{ + HAL_NOR_STATUS_SUCCESS = 0U, + HAL_NOR_STATUS_ONGOING, + HAL_NOR_STATUS_ERROR, + HAL_NOR_STATUS_TIMEOUT +} HAL_NOR_StatusTypeDef; + +/** + * @brief FMC NOR ID typedef + */ +typedef struct +{ + uint16_t Manufacturer_Code; /*!< Defines the device's manufacturer code used to identify the memory */ + + uint16_t Device_Code1; + + uint16_t Device_Code2; + + uint16_t Device_Code3; /*!< Defines the device's codes used to identify the memory. + These codes can be accessed by performing read operations with specific + control signals and addresses set.They can also be accessed by issuing + an Auto Select command */ +} NOR_IDTypeDef; + +/** + * @brief FMC NOR CFI typedef + */ +typedef struct +{ + /*!< Defines the information stored in the memory's Common flash interface + which contains a description of various electrical and timing parameters, + density information and functions supported by the memory */ + + uint16_t CFI_1; + + uint16_t CFI_2; + + uint16_t CFI_3; + + uint16_t CFI_4; +} NOR_CFITypeDef; + +/** + * @brief NOR handle Structure definition + */ +#if (USE_HAL_NOR_REGISTER_CALLBACKS == 1) +typedef struct __NOR_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_NOR_REGISTER_CALLBACKS */ + +{ + FMC_NORSRAM_TypeDef *Instance; /*!< Register base address */ + + FMC_NORSRAM_EXTENDED_TypeDef *Extended; /*!< Extended mode register base address */ + + FMC_NORSRAM_InitTypeDef Init; /*!< NOR device control configuration parameters */ + + HAL_LockTypeDef Lock; /*!< NOR locking object */ + + __IO HAL_NOR_StateTypeDef State; /*!< NOR device access state */ + + uint32_t CommandSet; /*!< NOR algorithm command set and control */ + +#if (USE_HAL_NOR_REGISTER_CALLBACKS == 1) + void (* MspInitCallback)(struct __NOR_HandleTypeDef *hnor); /*!< NOR Msp Init callback */ + void (* MspDeInitCallback)(struct __NOR_HandleTypeDef *hnor); /*!< NOR Msp DeInit callback */ +#endif /* USE_HAL_NOR_REGISTER_CALLBACKS */ +} NOR_HandleTypeDef; + +#if (USE_HAL_NOR_REGISTER_CALLBACKS == 1) +/** + * @brief HAL NOR Callback ID enumeration definition + */ +typedef enum +{ + HAL_NOR_MSP_INIT_CB_ID = 0x00U, /*!< NOR MspInit Callback ID */ + HAL_NOR_MSP_DEINIT_CB_ID = 0x01U /*!< NOR MspDeInit Callback ID */ +} HAL_NOR_CallbackIDTypeDef; + +/** + * @brief HAL NOR Callback pointer definition + */ +typedef void (*pNOR_CallbackTypeDef)(NOR_HandleTypeDef *hnor); +#endif /* USE_HAL_NOR_REGISTER_CALLBACKS */ +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup NOR_Exported_Macros NOR Exported Macros + * @{ + */ +/** @brief Reset NOR handle state + * @param __HANDLE__ specifies the NOR handle. + * @retval None + */ +#if (USE_HAL_NOR_REGISTER_CALLBACKS == 1) +#define __HAL_NOR_RESET_HANDLE_STATE(__HANDLE__) do { \ + (__HANDLE__)->State = HAL_NOR_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_NOR_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_NOR_STATE_RESET) +#endif /* USE_HAL_NOR_REGISTER_CALLBACKS */ +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup NOR_Exported_Functions NOR Exported Functions + * @{ + */ + +/** @addtogroup NOR_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ + +/* Initialization/de-initialization functions ********************************/ +HAL_StatusTypeDef HAL_NOR_Init(NOR_HandleTypeDef *hnor, FMC_NORSRAM_TimingTypeDef *Timing, + FMC_NORSRAM_TimingTypeDef *ExtTiming); +HAL_StatusTypeDef HAL_NOR_DeInit(NOR_HandleTypeDef *hnor); +void HAL_NOR_MspInit(NOR_HandleTypeDef *hnor); +void HAL_NOR_MspDeInit(NOR_HandleTypeDef *hnor); +void HAL_NOR_MspWait(NOR_HandleTypeDef *hnor, uint32_t Timeout); +/** + * @} + */ + +/** @addtogroup NOR_Exported_Functions_Group2 Input and Output functions + * @{ + */ + +/* I/O operation functions ***************************************************/ +HAL_StatusTypeDef HAL_NOR_Read_ID(NOR_HandleTypeDef *hnor, NOR_IDTypeDef *pNOR_ID); +HAL_StatusTypeDef HAL_NOR_ReturnToReadMode(NOR_HandleTypeDef *hnor); +HAL_StatusTypeDef HAL_NOR_Read(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData); +HAL_StatusTypeDef HAL_NOR_Program(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData); + +HAL_StatusTypeDef HAL_NOR_ReadBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData, + uint32_t uwBufferSize); +HAL_StatusTypeDef HAL_NOR_ProgramBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData, + uint32_t uwBufferSize); + +HAL_StatusTypeDef HAL_NOR_Erase_Block(NOR_HandleTypeDef *hnor, uint32_t BlockAddress, uint32_t Address); +HAL_StatusTypeDef HAL_NOR_Erase_Chip(NOR_HandleTypeDef *hnor, uint32_t Address); +HAL_StatusTypeDef HAL_NOR_Read_CFI(NOR_HandleTypeDef *hnor, NOR_CFITypeDef *pNOR_CFI); + +#if (USE_HAL_NOR_REGISTER_CALLBACKS == 1) +/* NOR callback registering/unregistering */ +HAL_StatusTypeDef HAL_NOR_RegisterCallback(NOR_HandleTypeDef *hnor, HAL_NOR_CallbackIDTypeDef CallbackId, + pNOR_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_NOR_UnRegisterCallback(NOR_HandleTypeDef *hnor, HAL_NOR_CallbackIDTypeDef CallbackId); +#endif /* USE_HAL_NOR_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @addtogroup NOR_Exported_Functions_Group3 NOR Control functions + * @{ + */ + +/* NOR Control functions *****************************************************/ +HAL_StatusTypeDef HAL_NOR_WriteOperation_Enable(NOR_HandleTypeDef *hnor); +HAL_StatusTypeDef HAL_NOR_WriteOperation_Disable(NOR_HandleTypeDef *hnor); +/** + * @} + */ + +/** @addtogroup NOR_Exported_Functions_Group4 NOR State functions + * @{ + */ + +/* NOR State functions ********************************************************/ +HAL_NOR_StateTypeDef HAL_NOR_GetState(const NOR_HandleTypeDef *hnor); +HAL_NOR_StatusTypeDef HAL_NOR_GetStatus(NOR_HandleTypeDef *hnor, uint32_t Address, uint32_t Timeout); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup NOR_Private_Constants NOR Private Constants + * @{ + */ +/* NOR device IDs addresses */ +#define MC_ADDRESS ((uint16_t)0x0000) +#define DEVICE_CODE1_ADDR ((uint16_t)0x0001) +#define DEVICE_CODE2_ADDR ((uint16_t)0x000E) +#define DEVICE_CODE3_ADDR ((uint16_t)0x000F) + +/* NOR CFI IDs addresses */ +#define CFI1_ADDRESS ((uint16_t)0x0061) +#define CFI2_ADDRESS ((uint16_t)0x0062) +#define CFI3_ADDRESS ((uint16_t)0x0063) +#define CFI4_ADDRESS ((uint16_t)0x0064) + +/* NOR operation wait timeout */ +#define NOR_TMEOUT ((uint16_t)0xFFFF) + +/* NOR memory data width */ +#define NOR_MEMORY_8B ((uint8_t)0x00) +#define NOR_MEMORY_16B ((uint8_t)0x01) + +/* NOR memory device read/write start address */ +#define NOR_MEMORY_ADRESS1 (0x60000000U) +#define NOR_MEMORY_ADRESS2 (0x64000000U) +#define NOR_MEMORY_ADRESS3 (0x68000000U) +#define NOR_MEMORY_ADRESS4 (0x6C000000U) +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup NOR_Private_Macros NOR Private Macros + * @{ + */ +/** + * @brief NOR memory address shifting. + * @param __NOR_ADDRESS NOR base address + * @param __NOR_MEMORY_WIDTH_ NOR memory width + * @param __ADDRESS__ NOR memory address + * @retval NOR shifted address value + */ +#define NOR_ADDR_SHIFT(__NOR_ADDRESS, __NOR_MEMORY_WIDTH_, __ADDRESS__) \ + ((uint32_t)(((__NOR_MEMORY_WIDTH_) == NOR_MEMORY_16B)? \ + ((uint32_t)((__NOR_ADDRESS) + (2U * (__ADDRESS__)))): \ + ((uint32_t)((__NOR_ADDRESS) + (__ADDRESS__))))) + +/** + * @brief NOR memory write data to specified address. + * @param __ADDRESS__ NOR memory address + * @param __DATA__ Data to write + * @retval None + */ +#define NOR_WRITE(__ADDRESS__, __DATA__) do{ \ + (*(__IO uint16_t *)((uint32_t)(__ADDRESS__)) = (__DATA__)); \ + __DSB(); \ + } while(0) + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* FMC_BANK1 */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_NOR_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_opamp.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_opamp.h new file mode 100644 index 0000000000..45b7a6a0ea --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_opamp.h @@ -0,0 +1,460 @@ +/** + ********************************************************************************************************************** + * @file stm32h5xx_hal_opamp.h + * @author MCD Application Team + * @brief Header file of OPAMP HAL module. + ********************************************************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ********************************************************************************************************************* + */ + +/* Define to prevent recursive inclusion -----------------------------------------------------------------------------*/ +#ifndef STM32H5xx_HAL_OPAMP_H +#define STM32H5xx_HAL_OPAMP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ----------------------------------------------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ +#if defined (OPAMP1) + +/** @addtogroup OPAMP + * @{ + */ + +/* Exported types ----------------------------------------------------------------------------------------------------*/ + +/** @defgroup OPAMP_Exported_Types OPAMP Exported Types + * @{ + */ + +/** + * @brief OPAMP Init structure definition + */ + +typedef struct +{ + + uint32_t PowerMode; /*!< Specifies the power mode Normal or High Speed. + This parameter must be a value of @ref OPAMP_PowerMode */ + + uint32_t Mode; /*!< Specifies the OPAMP mode + This parameter must be a value of @ref OPAMP_Mode + mode is either Standalone, Follower or PGA */ + + uint32_t InvertingInput; /*!< Specifies the inverting input in Standalone & PGA modes. + - In Standalone mode i.e when mode is OPAMP_STANDALONE_MODE + This parameter must be a value of @ref OPAMP_InvertingInput + - In Follower mode i.e when mode is OPAMP_FOLLOWER_MODE + & In PGA mode i.e when mode is OPAMP_PGA_MODE + This parameter is Not Applicable */ + + uint32_t NonInvertingInput; /*!< Specifies the non inverting input of the opamp: + This parameter must be a value of @ref OPAMP_NonInvertingInput */ + + uint32_t PgaGain; /*!< Specifies the gain in PGA mode + i.e. when mode is OPAMP_PGA_MODE. + This parameter must be a value of @ref OPAMP_PgaGain */ + + uint32_t PgaConnect; /*!< Specifies the inverting pin in PGA mode + i.e. when mode is OPAMP_PGA_MODE + This parameter must be a value of @ref OPAMP_PgaConnect + Either: not connected, connected to VINM0, connected to VINM1 + (VINM0 or VINM1 are typically used for external filtering) */ + + uint32_t UserTrimming; /*!< Specifies the trimming mode + This parameter must be a value of @ref OPAMP_UserTrimming + UserTrimming is either factory or user trimming. */ + + uint32_t TrimmingValueP; /*!< Specifies the offset trimming value (PMOS) in Normal Mode + i.e. when UserTrimming is OPAMP_TRIMMING_USER. + This parameter must be a number between Min_Data = 0 and Max_Data = 31. + 16 is typical default value */ + + uint32_t TrimmingValueN; /*!< Specifies the offset trimming value (NMOS) in Normal Mode + i.e. when UserTrimming is OPAMP_TRIMMING_USER. + This parameter must be a number between Min_Data = 0 and Max_Data = 31. + 16 is typical default value */ + + uint32_t TrimmingValuePHighSpeed; /*!< Specifies the offset trimming value (PMOS) in High Speed Mode + i.e. when UserTrimming is OPAMP_TRIMMING_USER. + This parameter must be a number between Min_Data = 0 and Max_Data = 31. + 16 is typical default value */ + + uint32_t TrimmingValueNHighSpeed; /*!< Specifies the offset trimming value (NMOS) in High Speed Mode + i.e. when UserTrimming is OPAMP_TRIMMING_USER. + This parameter must be a number between Min_Data = 0 and Max_Data = 31. + 16 is typical default value */ + +} OPAMP_InitTypeDef; + +/** + * @brief HAL State structures definition + */ + +typedef enum +{ + HAL_OPAMP_STATE_RESET = 0x00000000U, /*!< OPAMP is not yet Initialized */ + HAL_OPAMP_STATE_READY = 0x00000001U, /*!< OPAMP is initialized and ready for use */ + HAL_OPAMP_STATE_CALIBBUSY = 0x00000002U, /*!< OPAMP is enabled in auto calibration mode */ + HAL_OPAMP_STATE_BUSY = 0x00000004U, /*!< OPAMP is enabled and running in normal mode */ + HAL_OPAMP_STATE_BUSYLOCKED = 0x00000005U /*!< OPAMP is locked. Only system reset allows reconfiguring the opamp. */ + +} HAL_OPAMP_StateTypeDef; + +/** + * @brief OPAMP Handle Structure definition + */ +#if (USE_HAL_OPAMP_REGISTER_CALLBACKS == 1U) +typedef struct __OPAMP_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_OPAMP_REGISTER_CALLBACKS */ +{ + OPAMP_TypeDef *Instance; /*!< OPAMP instance's registers base address */ + OPAMP_InitTypeDef Init; /*!< OPAMP required parameters */ + HAL_StatusTypeDef Status; /*!< OPAMP peripheral status */ + HAL_LockTypeDef Lock; /*!< Locking object */ + __IO HAL_OPAMP_StateTypeDef State; /*!< OPAMP communication state */ + +#if (USE_HAL_OPAMP_REGISTER_CALLBACKS == 1U) + void (* MspInitCallback)(struct __OPAMP_HandleTypeDef *hopamp); + void (* MspDeInitCallback)(struct __OPAMP_HandleTypeDef *hopamp); +#endif /* USE_HAL_OPAMP_REGISTER_CALLBACKS */ +} OPAMP_HandleTypeDef; + +/** + * @brief HAl_OPAMP_TrimmingValueTypeDef definition + */ + +typedef uint32_t HAL_OPAMP_TrimmingValueTypeDef; + +/** + * @} + */ + +#if (USE_HAL_OPAMP_REGISTER_CALLBACKS == 1U) +/** + * @brief HAL OPAMP Callback ID enumeration definition + */ +typedef enum +{ + HAL_OPAMP_MSPINIT_CB_ID = 0x01U, /*!< OPAMP MspInit Callback ID */ + HAL_OPAMP_MSPDEINIT_CB_ID = 0x02U, /*!< OPAMP MspDeInit Callback ID */ + HAL_OPAMP_ALL_CB_ID = 0x03U /*!< OPAMP All ID */ + +} HAL_OPAMP_CallbackIDTypeDef; + +/** + * @brief HAL OPAMP Callback pointer definition + */ +typedef void (*pOPAMP_CallbackTypeDef)(OPAMP_HandleTypeDef *hopamp); +#endif /* USE_HAL_OPAMP_REGISTER_CALLBACKS */ + + +/* Exported constants ------------------------------------------------------------------------------------------------*/ +/** @defgroup OPAMP_Exported_Constants OPAMP Exported Constants + * @{ + */ + +/** @defgroup OPAMP_Mode OPAMP Mode + * @{ + */ +#define OPAMP_STANDALONE_MODE 0x00000000U /*!< standalone mode */ +#define OPAMP_PGA_MODE OPAMP_CSR_VMSEL_1 /*!< PGA mode */ +#define OPAMP_FOLLOWER_MODE (OPAMP_CSR_VMSEL_1 | OPAMP_CSR_VMSEL_0) /*!< follower mode */ +/** + * @} + */ + +/** @defgroup OPAMP_NonInvertingInput OPAMP Non Inverting Input + * @{ + */ + +#define OPAMP_NONINVERTINGINPUT_IO0 0x00000000U /*!< OPAMP non inverting input connected to + I/O VINP0 (PB0 for OPAMP1) */ +#define OPAMP_NONINVERTINGINPUT_IO1 OPAMP_CSR_VPSEL_1 /*!< OPAMP non inverting input connected to + I/O VINP0 (PA0 for OPAMP1) */ +#define OPAMP_NONINVERTINGINPUT_DAC_CH OPAMP_CSR_VPSEL_0 /*!< OPAMP non-inverting input connected internally + to DAC channel */ +/** + * @} + */ + +/** @defgroup OPAMP_InvertingInput OPAMP Inverting Input + * @{ + */ +#define OPAMP_INVERTINGINPUT_IO0 0x00000000U /*!< OPAMP inverting input connected to I/O VINM0 + (PC5 for OPAMP1) */ +#define OPAMP_INVERTINGINPUT_IO1 OPAMP_CSR_VMSEL_0 /*!< OPAMP inverting input connected to I/0 VINM1 + (PB1 for OPAMP1) */ +#define OPAMP_INVERTINGINPUT_CONNECT_NO OPAMP_CSR_VMSEL_1 /*!< OPAMP inverting input not externally connected + (intended for OPAMP in mode follower or + PGA with positive gain without bias). + Note: On this STM32 series, this literal + include cases of value 0x11 for mode follower + and value 0x10 for mode PGA. */ +/** + * @} + */ + +/** @defgroup OPAMP_PgaConnect OPAMP Pga Connect + * @{ + */ + +#define OPAMP_PGA_CONNECT_INVERTINGINPUT_NO 0x00000000U /*!< In PGA mode, the inverting input is + not connected */ +#define OPAMP_PGA_CONNECT_INVERTINGINPUT_IO0 OPAMP_CSR_PGGAIN_2 /*!< In PGA mode, the inverting input is + connected to VINM0 */ +#define OPAMP_PGA_CONNECT_INVERTINGINPUT_IO0_BIAS OPAMP_CSR_PGGAIN_3 /*!< In PGA mode, the inverting input is + connected to VINM0 or bias */ +#define OPAMP_PGA_CONNECT_INVERTINGINPUT_IO0_IO1_BIAS (OPAMP_CSR_PGGAIN_2 |\ + OPAMP_CSR_PGGAIN_3) /*!< In PGA mode, the inverting input is + connected to VINM0 or bias , VINM1 + connected for filtering */ + + +/** + * @} + */ + +/** @defgroup OPAMP_PgaGain OPAMP Pga Gain + * @{ + */ + +#define OPAMP_PGA_GAIN_2_OR_MINUS_1 0x00000000U /*!< PGA gain could be 2 or -1 */ +#define OPAMP_PGA_GAIN_4_OR_MINUS_3 OPAMP_CSR_PGGAIN_0 /*!< PGA gain could be 4 or -3 */ +#define OPAMP_PGA_GAIN_8_OR_MINUS_7 OPAMP_CSR_PGGAIN_1 /*!< PGA gain could be 8 or -7 */ +#define OPAMP_PGA_GAIN_16_OR_MINUS_15 (OPAMP_CSR_PGGAIN_0 | OPAMP_CSR_PGGAIN_1) /*!< PGA gain could be 16 or -15 */ + +/** + * @} + */ + +/** @defgroup OPAMP_PowerMode OPAMP PowerMode + * @{ + */ +#define OPAMP_POWERMODE_NORMAL 0x00000000U +#define OPAMP_POWERMODE_HIGHSPEED OPAMP_CSR_OPAHSM + +/** + * @} + */ + + +/** @defgroup OPAMP_VREF OPAMP VREF + * @{ + */ + +#define OPAMP_VREF_3VDDA 0x00000000U /*!< OPAMP Vref = 3.3% VDDA */ +#define OPAMP_VREF_10VDDA OPAMP_CSR_CALSEL_0 /*!< OPAMP Vref = 10% VDDA */ +#define OPAMP_VREF_50VDDA OPAMP_CSR_CALSEL_1 /*!< OPAMP Vref = 50% VDDA */ +#define OPAMP_VREF_90VDDA OPAMP_CSR_CALSEL /*!< OPAMP Vref = 90% VDDA */ + +/** + * @} + */ + +/** @defgroup OPAMP_UserTrimming OPAMP User Trimming + * @{ + */ +#define OPAMP_TRIMMING_FACTORY 0x00000000U /*!< Factory trimming */ +#define OPAMP_TRIMMING_USER OPAMP_CSR_USERTRIM /*!< User trimming */ + + +/** + * @} + */ + +/** @defgroup OPAMP_FactoryTrimming OPAMP Factory Trimming + * @{ + */ +#define OPAMP_FACTORYTRIMMING_DUMMY 0xFFFFFFFFU /*!< Dummy value if trimming value could not be retrieved */ +#define OPAMP_FACTORYTRIMMING_N 0x00000000U /*!< Offset trimming N */ +#define OPAMP_FACTORYTRIMMING_P 0x00000001U /*!< Offset trimming P */ + +/** + * @} + */ + +/** + * @} + */ + +/* Private constants -------------------------------------------------------------------------------------------------*/ +/** @defgroup OPAMP_Private_Constants OPAMP Private Constants + * @brief OPAMP Private constants and defines + * @{ + */ + +/* NONINVERTING bit position in OTR & HSOTR */ +#define OPAMP_INPUT_NONINVERTING (8U) /*!< Non inverting input */ + +/* Offset trimming time: during calibration, minimum time needed between two */ +/* steps to have 1 mV accuracy. */ +/* Refer to datasheet, electrical characteristics: parameter tOFFTRIM Typ=2ms.*/ +/* Unit: ms. */ +#define OPAMP_TRIMMING_DELAY (2U) + +/** + * @} + */ + +/* Exported macros ---------------------------------------------------------------------------------------------------*/ +/** @defgroup OPAMP_Exported_Macros OPAMP Exported Macros + * @{ + */ + +/** @brief Reset OPAMP handle state. + * @param __HANDLE__: OPAMP handle. + * @retval None + */ +#define __HAL_OPAMP_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_OPAMP_STATE_RESET) + +/** + * @} + */ + +/* Private macro -----------------------------------------------------------------------------------------------------*/ + +/** @defgroup OPAMP_Private_Macros OPAMP Private Macros + * @{ + */ + +#define IS_OPAMP_FUNCTIONAL_NORMALMODE(INPUT) (((INPUT) == OPAMP_STANDALONE_MODE) || \ + ((INPUT) == OPAMP_PGA_MODE) || \ + ((INPUT) == OPAMP_FOLLOWER_MODE)) + +#define IS_OPAMP_INVERTING_INPUT_STANDALONE(INPUT) (((INPUT) == OPAMP_INVERTINGINPUT_IO0) || \ + ((INPUT) == OPAMP_INVERTINGINPUT_IO1)) + +#define IS_OPAMP_NONINVERTING_INPUT(INPUT) (((INPUT) == OPAMP_NONINVERTINGINPUT_IO0) || \ + ((INPUT) == OPAMP_NONINVERTINGINPUT_IO1) || \ + ((INPUT) == OPAMP_NONINVERTINGINPUT_DAC_CH)) + +#define IS_OPAMP_PGACONNECT(CONNECT) (((CONNECT) == OPAMP_PGA_CONNECT_INVERTINGINPUT_NO) || \ + ((CONNECT) == OPAMP_PGA_CONNECT_INVERTINGINPUT_IO0) || \ + ((CONNECT) == OPAMP_PGA_CONNECT_INVERTINGINPUT_IO0_BIAS) || \ + ((CONNECT) == OPAMP_PGA_CONNECT_INVERTINGINPUT_IO0_IO1_BIAS)) + +#define IS_OPAMP_PGA_GAIN(GAIN) (((GAIN) == OPAMP_PGA_GAIN_2_OR_MINUS_1) || \ + ((GAIN) == OPAMP_PGA_GAIN_4_OR_MINUS_3) || \ + ((GAIN) == OPAMP_PGA_GAIN_8_OR_MINUS_7) || \ + ((GAIN) == OPAMP_PGA_GAIN_16_OR_MINUS_15)) + + +#define IS_OPAMP_VREF(VREF) (((VREF) == OPAMP_VREF_3VDDA) || \ + ((VREF) == OPAMP_VREF_10VDDA) || \ + ((VREF) == OPAMP_VREF_50VDDA) || \ + ((VREF) == OPAMP_VREF_90VDDA)) + +#define IS_OPAMP_POWERMODE(TRIMMING) (((TRIMMING) == OPAMP_POWERMODE_NORMAL) || \ + ((TRIMMING) == OPAMP_POWERMODE_HIGHSPEED) ) + + +#define IS_OPAMP_TRIMMING(TRIMMING) (((TRIMMING) == OPAMP_TRIMMING_FACTORY) || \ + ((TRIMMING) == OPAMP_TRIMMING_USER)) + + +#define IS_OPAMP_TRIMMINGVALUE(TRIMMINGVALUE) ((TRIMMINGVALUE) <= 0x1FU) + +#define IS_OPAMP_FACTORYTRIMMING(TRIMMING) (((TRIMMING) == OPAMP_FACTORYTRIMMING_N) || \ + ((TRIMMING) == OPAMP_FACTORYTRIMMING_P)) + +/** + * @} + */ + +/* Include OPAMP HAL Extended module */ +#include "stm32h5xx_hal_opamp_ex.h" + +/* Exported functions ------------------------------------------------------------------------------------------------*/ +/** @addtogroup OPAMP_Exported_Functions + * @{ + */ + +/** @addtogroup OPAMP_Exported_Functions_Group1 + * @{ + */ +/* Initialization/de-initialization functions */ +HAL_StatusTypeDef HAL_OPAMP_Init(OPAMP_HandleTypeDef *hopamp); +HAL_StatusTypeDef HAL_OPAMP_DeInit(OPAMP_HandleTypeDef *hopamp); +void HAL_OPAMP_MspInit(OPAMP_HandleTypeDef *hopamp); +void HAL_OPAMP_MspDeInit(OPAMP_HandleTypeDef *hopamp); +/** + * @} + */ + +/** @addtogroup OPAMP_Exported_Functions_Group2 + * @{ + */ + +/* I/O operation functions */ +HAL_StatusTypeDef HAL_OPAMP_Start(OPAMP_HandleTypeDef *hopamp); +HAL_StatusTypeDef HAL_OPAMP_Stop(OPAMP_HandleTypeDef *hopamp); +HAL_StatusTypeDef HAL_OPAMP_SelfCalibrate(OPAMP_HandleTypeDef *hopamp); + +/** + * @} + */ + +/** @addtogroup OPAMP_Exported_Functions_Group3 + * @{ + */ + +/* Peripheral Control functions */ +#if (USE_HAL_OPAMP_REGISTER_CALLBACKS == 1U) +/* OPAMP callback registering/unregistering */ +HAL_StatusTypeDef HAL_OPAMP_RegisterCallback(OPAMP_HandleTypeDef *hopamp, HAL_OPAMP_CallbackIDTypeDef CallbackId, + pOPAMP_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_OPAMP_UnRegisterCallback(OPAMP_HandleTypeDef *hopamp, HAL_OPAMP_CallbackIDTypeDef CallbackId); +#endif /* USE_HAL_OPAMP_REGISTER_CALLBACKS */ +HAL_StatusTypeDef HAL_OPAMP_Lock(OPAMP_HandleTypeDef *hopamp); +HAL_OPAMP_TrimmingValueTypeDef HAL_OPAMP_GetTrimOffset(const OPAMP_HandleTypeDef *hopamp, uint32_t trimmingoffset); + +/** + * @} + */ + +/** @addtogroup OPAMP_Exported_Functions_Group4 + * @{ + */ + +/* Peripheral State functions */ +HAL_OPAMP_StateTypeDef HAL_OPAMP_GetState(const OPAMP_HandleTypeDef *hopamp); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* OPAMP1 */ +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_OPAMP_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_opamp_ex.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_opamp_ex.h new file mode 100644 index 0000000000..d654d4dc01 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_opamp_ex.h @@ -0,0 +1,73 @@ +/** + ********************************************************************************************************************** + * @file stm32h5xx_hal_opamp_ex.h + * @author MCD Application Team + * @brief Header file of OPAMP HAL Extended module. + ********************************************************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ********************************************************************************************************************** + */ + +/* Define to prevent recursive inclusion -----------------------------------------------------------------------------*/ +#ifndef STM32H5xx_HAL_OPAMP_EX_H +#define STM32H5xx_HAL_OPAMP_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ----------------------------------------------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ +#if defined (OPAMP1) + +/** @addtogroup OPAMPEx + * @{ + */ +/* Exported types ----------------------------------------------------------------------------------------------------*/ +/* Exported constants ------------------------------------------------------------------------------------------------*/ +/* Exported macro ----------------------------------------------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------------------------------------------------*/ +/** @addtogroup OPAMPEx_Exported_Functions OPAMPEx Exported Functions + * @{ + */ + +/* Peripheral Control functions */ +/** @addtogroup OPAMPEx_Exported_Functions_Group1 + * @{ + */ +HAL_StatusTypeDef HAL_OPAMPEx_Unlock(OPAMP_HandleTypeDef *hopamp); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* OPAMP1 */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_OPAMP_EX_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_otfdec.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_otfdec.h new file mode 100644 index 0000000000..e717bde396 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_otfdec.h @@ -0,0 +1,487 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_otfdec.h + * @author MCD Application Team + * @brief Header file of OTFDEC HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_OTFDEC_H +#define STM32H5xx_HAL_OTFDEC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +#if defined(OTFDEC1) + +/** @addtogroup OTFDEC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup OTFDEC_Exported_Types OTFDEC Exported Types + * @{ + */ + +/** @defgroup OTFDEC_Exported_Types_Group1 OTFDEC region configuration definitions + * @{ + */ + +/** + * @brief OTFDEC region configuration structure definition + */ +typedef struct +{ + uint32_t Nonce[2]; /*!< OTFDEC region nonce */ + + uint32_t StartAddress; /*!< OTFDEC region start address */ + + uint32_t EndAddress; /*!< OTFDEC region end address */ + + uint16_t Version; /*!< OTFDEC region firmware version */ + +} OTFDEC_RegionConfigTypeDef; + +/** + * @} + */ + +/** @defgroup OTFDEC_Exported_Types_Group2 OTFDEC Peripheral handle definitions + * @{ + */ + +/** + * @brief OTFDEC states structure definition + */ +typedef enum +{ + HAL_OTFDEC_STATE_RESET = 0x00U, /*!< OTFDEC not yet initialized or disabled */ + HAL_OTFDEC_STATE_READY = 0x01U, /*!< OTFDEC initialized and ready for use */ + HAL_OTFDEC_STATE_BUSY = 0x02U, /*!< OTFDEC internal processing is ongoing */ +} HAL_OTFDEC_StateTypeDef; + +/** + * @brief OTFDEC handle structure definition + */ +#if (USE_HAL_OTFDEC_REGISTER_CALLBACKS == 1) +typedef struct __OTFDEC_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_OTFDEC_REGISTER_CALLBACKS */ +{ + OTFDEC_TypeDef *Instance; /*!< OTFDEC registers base address */ + + HAL_OTFDEC_StateTypeDef State; /*!< OTFDEC state */ + + HAL_LockTypeDef Lock; /*!< OTFDEC locking object */ + + __IO uint32_t ErrorCode; /*!< OTFDEC error code */ + +#if (USE_HAL_OTFDEC_REGISTER_CALLBACKS == 1) + void (* ErrorCallback)(struct __OTFDEC_HandleTypeDef *hotfdec); /*!< OTFDEC error callback */ + + void (* MspInitCallback)(struct __OTFDEC_HandleTypeDef *hotfdec); /*!< OTFDEC Msp Init callback */ + + void (* MspDeInitCallback)(struct __OTFDEC_HandleTypeDef *hotfdec); /*!< OTFDEC Msp DeInit callback */ +#endif /* USE_HAL_OTFDEC_REGISTER_CALLBACKS */ + +} OTFDEC_HandleTypeDef; + +#if (USE_HAL_OTFDEC_REGISTER_CALLBACKS == 1) +/** + * @brief HAL OTFDEC Callback ID enumeration definition + */ +typedef enum +{ + HAL_OTFDEC_ERROR_CB_ID = 0x00U, /*!< OTFDEC error callback ID */ + HAL_OTFDEC_MSPINIT_CB_ID = 0x01U, /*!< OTFDEC Msp DeInit callback ID */ + HAL_OTFDEC_MSPDEINIT_CB_ID = 0x02U /*!< OTFDEC Msp DeInit callback ID */ +} HAL_OTFDEC_CallbackIDTypeDef; + +/** + * @brief HAL OTFDEC Callback pointer definition + */ +typedef void (*pOTFDEC_CallbackTypeDef)(OTFDEC_HandleTypeDef *hotfdec); /*!< pointer to a OTFDEC callback function */ + +#endif /* USE_HAL_OTFDEC_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup OTFDEC_Exported_Constants OTFDEC Exported Constants + * @{ + */ + +/** @defgroup OTFDEC_Interrupts OTFDEC Interrupts + * @{ + */ +#define OTFDEC_SEC_ERROR_INT (OTFDEC_IER_SEIE ) /*!< OTFDEC security error interrupt */ +#define OTFDEC_EXE_ERROR_INT ( OTFDEC_IER_XONEIE ) /*!< OTFDEC execution error interrupt */ +#define OTFDEC_KEY_ERROR_INT ( OTFDEC_IER_KEIE) /*!< OTFDEC key error interrupt */ +#define OTFDEC_SEC_EXE_ERROR_INT (OTFDEC_IER_SEIE|OTFDEC_IER_XONEIE ) /*!< OTFDEC security and execution errors interrupts */ +#define OTFDEC_SEC_KEY_ERROR_INT (OTFDEC_IER_SEIE| OTFDEC_IER_KEIE) /*!< OTFDEC security and key errors interrupts */ +#define OTFDEC_EXE_KEY_ERROR_INT ( OTFDEC_IER_XONEIE|OTFDEC_IER_KEIE) /*!< OTFDEC execution and key errors interrupts */ +#define OTFDEC_ALL_INT (OTFDEC_IER_SEIE|OTFDEC_IER_XONEIE|OTFDEC_IER_KEIE) /*!< OTFDEC all interrupts */ +/** + * @} + */ + +/** @defgroup OTFDEC_Region_Enable OTFDEC Region Enable + * @{ + */ +#define OTFDEC_REG_CONFIGR_REG_DISABLE 0x00000000U /*!< OTFDEC region encryption or on-the-fly decryption disable */ +#define OTFDEC_REG_CONFIGR_REG_ENABLE OTFDEC_REG_CONFIGR_REG_EN /*!< OTFDEC region encryption or on-the-fly decryption enable */ +/** + * @} + */ + +/** @defgroup OTFDEC_Region_Configuration_Lock OTFDEC Region Configuration Lock + * @{ + */ +#define OTFDEC_REG_CONFIGR_LOCK_DISABLE 0x00000000U /*!< OTFDEC region configuration lock disable */ +#define OTFDEC_REG_CONFIGR_LOCK_ENABLE OTFDEC_REG_CONFIGR_CONFIGLOCK /*!< OTFDEC region configuration lock enable */ +/** + * @} + */ + +/** @defgroup OTFDEC_Region_Operating_Mode OTFDEC Region Operating Mode + * @{ + */ +#define OTFDEC_REG_MODE_INSTRUCTION_OR_DATA_ACCESSES OTFDEC_REG_CONFIGR_MODE_1 /*!< All read accesses are decrypted */ +#define OTFDEC_REG_MODE_INSTRUCTION_ACCESSES_ONLY_WITH_CIPHER OTFDEC_REG_CONFIGR_MODE /*!< Only instruction accesses are decrypted with proprietary cipher activated */ +/** + * @} + */ + +/** @defgroup OTFDEC_Error_Definition OTFDEC Error Definition + * @{ + */ +#define HAL_OTFDEC_ERROR_NONE ((uint32_t)0x00000000U) /*!< No error */ +#define HAL_OTFDEC_SECURITY_ERROR ((uint32_t)0x00000001U) /*!< Security error */ +#define HAL_OTFDEC_EXECUTE_ERROR ((uint32_t)0x00000002U) /*!< Execute-only Execute-Never error */ +#define HAL_OTFDEC_KEY_ERROR ((uint32_t)0x00000004U) /*!< Key error */ +#if (USE_HAL_OTFDEC_REGISTER_CALLBACKS == 1) +#define HAL_OTFDEC_ERROR_INVALID_CALLBACK ((uint32_t)0x00000008U) /*!< Invalid Callback error */ +#endif /* USE_HAL_OTFDEC_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @defgroup OTFDEC_Regions_Index OTFDEC Regions Index + * @{ + */ +#define OTFDEC_REGION1 ((uint32_t)0x00000000U) /*!< OTFDEC region 1 */ +#define OTFDEC_REGION2 ((uint32_t)0x00000001U) /*!< OTFDEC region 2 */ +#define OTFDEC_REGION3 ((uint32_t)0x00000002U) /*!< OTFDEC region 3 */ +#define OTFDEC_REGION4 ((uint32_t)0x00000003U) /*!< OTFDEC region 4 */ +/** + * @} + */ + +/** @defgroup OTFDEC_Configuration_Attributes OTFDEC Configuration Attributes + * @{ + */ +#define OTFDEC_ATTRIBUTE_NPRIV ((uint32_t)0x00000000U) /*!< Non-privileged access protection */ +#define OTFDEC_ATTRIBUTE_PRIV OTFDEC_PRIVCFGR_PRIV /*!< Privileged access protection */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup OTFDEC_Exported_Macros OTFDEC Exported Macros + * @{ + */ + +/** @brief Reset OTFDEC handle state. + * @param __HANDLE__ pointer to an OTFDEC_HandleTypeDef structure that contains + * the configuration information for OTFDEC module + * @retval None + */ +#if (USE_HAL_OTFDEC_REGISTER_CALLBACKS == 1) +#define __HAL_OTFDEC_RESET_HANDLE_STATE(__HANDLE__) \ + do{ \ + (__HANDLE__)->State = HAL_OTFDEC_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_OTFDEC_RESET_HANDLE_STATE(__HANDLE__) \ + ((__HANDLE__)->State = HAL_OTFDEC_STATE_RESET) +#endif /* USE_HAL_OTFDEC_REGISTER_CALLBACKS */ + +/** + * @brief Enable OTFDEC peripheral interrupts combination + * @param __HANDLE__ pointer to an OTFDEC_HandleTypeDef structure that contains + * the configuration information for OTFDEC module + * @param __INTERRUPT__ mask on enabled interrupts + * This parameter can be one of the following values: + * @arg @ref OTFDEC_SEC_ERROR_INT OTFDEC security error interrupt + * @arg @ref OTFDEC_EXE_ERROR_INT OTFDEC execution error interrupt + * @arg @ref OTFDEC_KEY_ERROR_INT OTFDEC key error interrupt + * @arg @ref OTFDEC_SEC_EXE_ERROR_INT OTFDEC security and execution errors interrupts + * @arg @ref OTFDEC_SEC_KEY_ERROR_INT OTFDEC security and key errors interrupts + * @arg @ref OTFDEC_EXE_KEY_ERROR_INT OTFDEC execution and key errors interrupts + * @arg @ref OTFDEC_ALL_INT OTFDEC all interrupts + * @retval None + */ +#define __HAL_OTFDEC_ENABLE_IT(__HANDLE__, __INTERRUPT__) SET_BIT(((__HANDLE__)->Instance->IER), (__INTERRUPT__)) + +/** + * @brief Disable OTFDEC peripheral interrupts combination + * @param __HANDLE__ pointer to an OTFDEC_HandleTypeDef structure that contains + * the configuration information for OTFDEC module + * @param __INTERRUPT__ mask on disabled interrupts + * This parameter can be one of the following values: + * @arg @ref OTFDEC_SEC_ERROR_INT OTFDEC security error interrupt + * @arg @ref OTFDEC_EXE_ERROR_INT OTFDEC execution error interrupt + * @arg @ref OTFDEC_KEY_ERROR_INT OTFDEC key error interrupt + * @arg @ref OTFDEC_SEC_EXE_ERROR_INT OTFDEC security and execution errors interrupts + * @arg @ref OTFDEC_SEC_KEY_ERROR_INT OTFDEC security and key errors interrupts + * @arg @ref OTFDEC_EXE_KEY_ERROR_INT OTFDEC execution and key errors interrupts + * @arg @ref OTFDEC_ALL_INT OTFDEC all interrupts + * @retval None + */ +#define __HAL_OTFDEC_DISABLE_IT(__HANDLE__, __INTERRUPT__) CLEAR_BIT(((__HANDLE__)->Instance->IER), (__INTERRUPT__)) + +/** @brief Check whether the specified combination of OTFDEC interrupt flags is set or not. + * @param __HANDLE__ pointer to an OTFDEC_HandleTypeDef structure that contains + * the configuration information for OTFDEC module + * @param __FLAG__ mask on combination of interrupts flags + * This parameter can be one of the following values: + * @arg @ref OTFDEC_SEC_ERROR_INT OTFDEC security error interrupt flag + * @arg @ref OTFDEC_EXE_ERROR_INT OTFDEC execution error interrupt flag + * @arg @ref OTFDEC_KEY_ERROR_INT OTFDEC key error interrupt flag + * @arg @ref OTFDEC_SEC_EXE_ERROR_INT OTFDEC security and execution errors interrupts flags + * @arg @ref OTFDEC_SEC_KEY_ERROR_INT OTFDEC security and key errors interrupts flags + * @arg @ref OTFDEC_EXE_KEY_ERROR_INT OTFDEC execution and key errors interrupts flag + * @arg @ref OTFDEC_ALL_INT OTFDEC all interrupts flags + * @retval The state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_OTFDEC_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->ISR & (__FLAG__)) == (__FLAG__)) + +/** @brief Clear the specified combination of OTFDEC interrupt flags. + * @param __HANDLE__ pointer to an OTFDEC_HandleTypeDef structure that contains + * the configuration information for OTFDEC module + * @param __FLAG__ mask on combination of interrupts flags + * This parameter can be one of the following values: + * @arg @ref OTFDEC_SEC_ERROR_INT OTFDEC security error interrupt flag + * @arg @ref OTFDEC_EXE_ERROR_INT OTFDEC execution error interrupt flag + * @arg @ref OTFDEC_KEY_ERROR_INT OTFDEC key error interrupt flag + * @arg @ref OTFDEC_SEC_EXE_ERROR_INT OTFDEC security and execution errors interrupts flags + * @arg @ref OTFDEC_SEC_KEY_ERROR_INT OTFDEC security and key errors interrupts flags + * @arg @ref OTFDEC_EXE_KEY_ERROR_INT OTFDEC execution and key errors interrupts flag + * @arg @ref OTFDEC_ALL_INT OTFDEC all interrupts flags + * @retval None + */ +#define __HAL_OTFDEC_CLEAR_FLAG(__HANDLE__, __FLAG__) SET_BIT((__HANDLE__)->Instance->ICR, (__FLAG__)) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup OTFDEC_Exported_Functions OTFDEC Exported Functions + * @{ + */ + +/** @addtogroup OTFDEC_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ +HAL_StatusTypeDef HAL_OTFDEC_Init(OTFDEC_HandleTypeDef *hotfdec); +HAL_StatusTypeDef HAL_OTFDEC_DeInit(OTFDEC_HandleTypeDef *hotfdec); +void HAL_OTFDEC_MspInit(OTFDEC_HandleTypeDef *hotfdec); +void HAL_OTFDEC_MspDeInit(OTFDEC_HandleTypeDef *hotfdec); + +#if (USE_HAL_OTFDEC_REGISTER_CALLBACKS == 1) +/* Callbacks Register/UnRegister functions ***********************************/ +HAL_StatusTypeDef HAL_OTFDEC_RegisterCallback(OTFDEC_HandleTypeDef *hotfdec, HAL_OTFDEC_CallbackIDTypeDef CallbackID, + pOTFDEC_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_OTFDEC_UnRegisterCallback(OTFDEC_HandleTypeDef *hotfdec, HAL_OTFDEC_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_OTFDEC_REGISTER_CALLBACKS */ +/** + * @} + */ + + +/** @addtogroup OTFDEC_Exported_Functions_Group2 OTFDEC IRQ handler management + * @{ + */ +void HAL_OTFDEC_IRQHandler(OTFDEC_HandleTypeDef *hotfdec); +void HAL_OTFDEC_ErrorCallback(OTFDEC_HandleTypeDef *hotfdec); +/** + * @} + */ + +/** @addtogroup OTFDEC_Exported_Functions_Group3 Peripheral Control functions + * @{ + */ +HAL_StatusTypeDef HAL_OTFDEC_RegionKeyLock(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex); +HAL_StatusTypeDef HAL_OTFDEC_RegionSetKey(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex, uint32_t *pKey); +HAL_StatusTypeDef HAL_OTFDEC_RegionSetMode(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex, uint32_t mode); +HAL_StatusTypeDef HAL_OTFDEC_RegionConfig(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex, + const OTFDEC_RegionConfigTypeDef *Config, uint32_t lock); +uint32_t HAL_OTFDEC_KeyCRCComputation(const uint32_t *pKey); +HAL_StatusTypeDef HAL_OTFDEC_RegionEnable(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex); +HAL_StatusTypeDef HAL_OTFDEC_RegionDisable(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex); +HAL_StatusTypeDef HAL_OTFDEC_ConfigAttributes(OTFDEC_HandleTypeDef *hotfdec, uint32_t Attributes); +HAL_StatusTypeDef HAL_OTFDEC_EnableEnciphering(OTFDEC_HandleTypeDef *hotfdec); +HAL_StatusTypeDef HAL_OTFDEC_DisableEnciphering(OTFDEC_HandleTypeDef *hotfdec); +HAL_StatusTypeDef HAL_OTFDEC_Cipher(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex, const uint32_t *input, + uint32_t *output, uint32_t size, uint32_t start_address); +/** + * @} + */ + +/** @addtogroup @addtogroup OTFDEC_Exported_Functions_Group4 Peripheral State and Status functions + * @{ + */ +HAL_OTFDEC_StateTypeDef HAL_OTFDEC_GetState(const OTFDEC_HandleTypeDef *hotfdec); +HAL_StatusTypeDef HAL_OTFDEC_GetConfigAttributes(OTFDEC_HandleTypeDef *hotfdec, uint32_t *Attributes); +uint32_t HAL_OTFDEC_RegionGetKeyCRC(const OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex); +HAL_StatusTypeDef HAL_OTFDEC_RegionGetConfig(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex, + OTFDEC_RegionConfigTypeDef *Config); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/** @defgroup OTFDEC_Private_Types OTFDEC Private Types + * @{ + */ + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup OTFDEC_Private_Variables OTFDEC Private Variables + * @{ + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup OTFDEC_Private_Constants OTFDEC Private Constants + * @{ + */ +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup OTFDEC_Private_Macros OTFDEC Private Macros + * @{ + */ + +/** + * @brief Verify the OTFDEC peripheral interrupts parameter. + * @param __INT__ OTFDEC peripheral set of interrupts parameter + * @retval SET (__INT__ is valid) or RESET (__INT__ is invalid) + */ +#define IS_OTFDEC_INTERRUPTS(__INT__) (((__INT__) == OTFDEC_SEC_ERROR_INT) || \ + ((__INT__) == OTFDEC_EXE_ERROR_INT) || \ + ((__INT__) == OTFDEC_KEY_ERROR_INT) || \ + ((__INT__) == OTFDEC_SEC_EXE_ERROR_INT) || \ + ((__INT__) == OTFDEC_SEC_KEY_ERROR_INT) || \ + ((__INT__) == OTFDEC_EXE_KEY_ERROR_INT) || \ + ((__INT__) == OTFDEC_ALL_INT) ) + +/** + * @brief Verify the OTFDEC region configuration lock parameter. + * @param __LOCK__ OTFDEC region lock parameter. + * @retval SET (__LOCK__ is valid) or RESET (__LOCK__ is invalid) + */ +#define IS_OTFDEC_REGION_CONFIG_LOCK(__LOCK__) (((__LOCK__) == OTFDEC_REG_CONFIGR_LOCK_DISABLE) || \ + ((__LOCK__) == OTFDEC_REG_CONFIGR_LOCK_ENABLE) ) + +/** + * @brief Verify the OTFDEC region operating mode. + * @param __MODE__ OTFDEC region operating mode parameter. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_OTFDEC_REGION_OPERATING_MODE(__MODE__) \ + (((__MODE__)== OTFDEC_REG_MODE_INSTRUCTION_OR_DATA_ACCESSES) || \ + ((__MODE__) == OTFDEC_REG_MODE_INSTRUCTION_ACCESSES_ONLY_WITH_CIPHER)) + +/** + * @brief Verify the OTFDEC region index. + * @param __INDEX__ OTFDEC region index + * @retval SET (__INDEX__ is valid) or RESET (__INDEX__ is invalid) + */ +#define IS_OTFDEC_REGIONINDEX(__INDEX__) (((__INDEX__) == OTFDEC_REGION1) || \ + ((__INDEX__) == OTFDEC_REGION2) || \ + ((__INDEX__) == OTFDEC_REGION3) || \ + ((__INDEX__) == OTFDEC_REGION4) ) + +/** + * @brief Verify the OTFDEC configuration attributes. + * @param __ATTRIBUTE__ OTFDEC region index + * @retval SET (__ATTRIBUTE__ is valid) or RESET (__ATTRIBUTE__ is invalid) + */ +#define IS_OTFDEC_ATTRIBUTE(__ATTRIBUTE__) (((__ATTRIBUTE__) == OTFDEC_ATTRIBUTE_PRIV) || \ + ((__ATTRIBUTE__) == OTFDEC_ATTRIBUTE_NPRIV) ) + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup OTFDEC_Private_Functions OTFDEC Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* OTFDEC1 */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_OTFDEC_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_pcd.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_pcd.h new file mode 100644 index 0000000000..244606938b --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_pcd.h @@ -0,0 +1,629 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_pcd.h + * @author MCD Application Team + * @brief Header file of PCD HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_PCD_H +#define STM32H5xx_HAL_PCD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_usb.h" + +#if defined (USB_DRD_FS) + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup PCD + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup PCD_Exported_Types PCD Exported Types + * @{ + */ + +/** + * @brief PCD State structure definition + */ +typedef enum +{ + HAL_PCD_STATE_RESET = 0x00, + HAL_PCD_STATE_READY = 0x01, + HAL_PCD_STATE_ERROR = 0x02, + HAL_PCD_STATE_BUSY = 0x03, + HAL_PCD_STATE_TIMEOUT = 0x04 +} PCD_StateTypeDef; + +/* Device LPM suspend state */ +typedef enum +{ + LPM_L0 = 0x00, /* on */ + LPM_L1 = 0x01, /* LPM L1 sleep */ + LPM_L2 = 0x02, /* suspend */ + LPM_L3 = 0x03, /* off */ +} PCD_LPM_StateTypeDef; + +typedef enum +{ + PCD_LPM_L0_ACTIVE = 0x00, /* on */ + PCD_LPM_L1_ACTIVE = 0x01, /* LPM L1 sleep */ +} PCD_LPM_MsgTypeDef; + +typedef enum +{ + PCD_BCD_ERROR = 0xFF, + PCD_BCD_CONTACT_DETECTION = 0xFE, + PCD_BCD_STD_DOWNSTREAM_PORT = 0xFD, + PCD_BCD_CHARGING_DOWNSTREAM_PORT = 0xFC, + PCD_BCD_DEDICATED_CHARGING_PORT = 0xFB, + PCD_BCD_DISCOVERY_COMPLETED = 0x00, + +} PCD_BCD_MsgTypeDef; + +typedef USB_DRD_TypeDef PCD_TypeDef; +typedef USB_DRD_CfgTypeDef PCD_InitTypeDef; +typedef USB_DRD_EPTypeDef PCD_EPTypeDef; + +/** + * @brief PCD Handle Structure definition + */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) +typedef struct __PCD_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ +{ + PCD_TypeDef *Instance; /*!< Register base address */ + PCD_InitTypeDef Init; /*!< PCD required parameters */ + __IO uint8_t USB_Address; /*!< USB Address */ + PCD_EPTypeDef IN_ep[8]; /*!< IN endpoint parameters */ + PCD_EPTypeDef OUT_ep[8]; /*!< OUT endpoint parameters */ + HAL_LockTypeDef Lock; /*!< PCD peripheral status */ + __IO PCD_StateTypeDef State; /*!< PCD communication state */ + __IO uint32_t ErrorCode; /*!< PCD Error code */ + uint32_t Setup[12]; /*!< Setup packet buffer */ + PCD_LPM_StateTypeDef LPM_State; /*!< LPM State */ + uint32_t BESL; + + + uint32_t lpm_active; /*!< Enable or disable the Link Power Management . + This parameter can be set to ENABLE or DISABLE */ + + uint32_t battery_charging_active; /*!< Enable or disable Battery charging. + This parameter can be set to ENABLE or DISABLE */ + void *pData; /*!< Pointer to upper stack Handler */ + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + void (* SOFCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD SOF callback */ + void (* SetupStageCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Setup Stage callback */ + void (* ResetCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Reset callback */ + void (* SuspendCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Suspend callback */ + void (* ResumeCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Resume callback */ + void (* ConnectCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Connect callback */ + void (* DisconnectCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Disconnect callback */ + + void (* DataOutStageCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD Data OUT Stage callback */ + void (* DataInStageCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD Data IN Stage callback */ + void (* ISOOUTIncompleteCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD ISO OUT Incomplete callback */ + void (* ISOINIncompleteCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD ISO IN Incomplete callback */ + void (* BCDCallback)(struct __PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg); /*!< USB OTG PCD BCD callback */ + void (* LPMCallback)(struct __PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg); /*!< USB OTG PCD LPM callback */ + + void (* MspInitCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Msp Init callback */ + void (* MspDeInitCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Msp DeInit callback */ +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ +} PCD_HandleTypeDef; + +/** + * @} + */ + +/* Include PCD HAL Extended module */ +#include "stm32h5xx_hal_pcd_ex.h" + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup PCD_Exported_Constants PCD Exported Constants + * @{ + */ + +/** @defgroup PCD_Speed PCD Speed + * @{ + */ +#define PCD_SPEED_FULL USBD_FS_SPEED +/** + * @} + */ + +/** @defgroup PCD_PHY_Module PCD PHY Module + * @{ + */ +#define PCD_PHY_ULPI 1U +#define PCD_PHY_EMBEDDED 2U +#define PCD_PHY_UTMI 3U +/** + * @} + */ + +/** @defgroup PCD_Error_Code_definition PCD Error Code definition + * @brief PCD Error Code definition + * @{ + */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) +#define HAL_PCD_ERROR_INVALID_CALLBACK (0x00000010U) /*!< Invalid Callback error */ +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup PCD_Exported_Macros PCD Exported Macros + * @brief macros to handle interrupts and specific clock configurations + * @{ + */ +#define __HAL_PCD_ENABLE(__HANDLE__) (void)USB_EnableGlobalInt ((__HANDLE__)->Instance) +#define __HAL_PCD_DISABLE(__HANDLE__) (void)USB_DisableGlobalInt ((__HANDLE__)->Instance) + +#define __HAL_PCD_GET_FLAG(__HANDLE__, __INTERRUPT__) \ + ((USB_ReadInterrupts((__HANDLE__)->Instance) & (__INTERRUPT__)) == (__INTERRUPT__)) + + +#define __HAL_PCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->ISTR)\ + &= (uint16_t)(~(__INTERRUPT__))) + +#define __HAL_USB_WAKEUP_EXTI_ENABLE_IT() EXTI->IMR2 |= USB_WAKEUP_EXTI_LINE +#define __HAL_USB_WAKEUP_EXTI_DISABLE_IT() EXTI->IMR2 &= ~(USB_WAKEUP_EXTI_LINE) + + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup PCD_Exported_Functions PCD Exported Functions + * @{ + */ + +/* Initialization/de-initialization functions ********************************/ +/** @addtogroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ +HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd); +void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd); +void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd); + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) +/** @defgroup HAL_PCD_Callback_ID_enumeration_definition HAL USB OTG PCD Callback ID enumeration definition + * @brief HAL USB OTG PCD Callback ID enumeration definition + * @{ + */ +typedef enum +{ + HAL_PCD_SOF_CB_ID = 0x01, /*!< USB PCD SOF callback ID */ + HAL_PCD_SETUPSTAGE_CB_ID = 0x02, /*!< USB PCD Setup Stage callback ID */ + HAL_PCD_RESET_CB_ID = 0x03, /*!< USB PCD Reset callback ID */ + HAL_PCD_SUSPEND_CB_ID = 0x04, /*!< USB PCD Suspend callback ID */ + HAL_PCD_RESUME_CB_ID = 0x05, /*!< USB PCD Resume callback ID */ + HAL_PCD_CONNECT_CB_ID = 0x06, /*!< USB PCD Connect callback ID */ + HAL_PCD_DISCONNECT_CB_ID = 0x07, /*!< USB PCD Disconnect callback ID */ + + HAL_PCD_MSPINIT_CB_ID = 0x08, /*!< USB PCD MspInit callback ID */ + HAL_PCD_MSPDEINIT_CB_ID = 0x09 /*!< USB PCD MspDeInit callback ID */ + +} HAL_PCD_CallbackIDTypeDef; +/** + * @} + */ + +/** @defgroup HAL_PCD_Callback_pointer_definition HAL USB OTG PCD Callback pointer definition + * @brief HAL USB OTG PCD Callback pointer definition + * @{ + */ + +typedef void (*pPCD_CallbackTypeDef)(PCD_HandleTypeDef *hpcd); /*!< pointer to a common USB OTG PCD callback function */ +typedef void (*pPCD_DataOutStageCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD Data OUT Stage callback */ +typedef void (*pPCD_DataInStageCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD Data IN Stage callback */ +typedef void (*pPCD_IsoOutIncpltCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD ISO OUT Incomplete callback */ +typedef void (*pPCD_IsoInIncpltCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD ISO IN Incomplete callback */ +typedef void (*pPCD_LpmCallbackTypeDef)(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg); /*!< pointer to USB OTG PCD LPM callback */ +typedef void (*pPCD_BcdCallbackTypeDef)(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg); /*!< pointer to USB OTG PCD BCD callback */ + +/** + * @} + */ + +HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID, + pPCD_CallbackTypeDef pCallback); + +HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID); + +HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd, + pPCD_DataOutStageCallbackTypeDef pCallback); + +HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd); + +HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd, + pPCD_DataInStageCallbackTypeDef pCallback); + +HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd); + +HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd, + pPCD_IsoOutIncpltCallbackTypeDef pCallback); + +HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd); + +HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd, + pPCD_IsoInIncpltCallbackTypeDef pCallback); + +HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd); + +HAL_StatusTypeDef HAL_PCD_RegisterBcdCallback(PCD_HandleTypeDef *hpcd, pPCD_BcdCallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_PCD_UnRegisterBcdCallback(PCD_HandleTypeDef *hpcd); + +HAL_StatusTypeDef HAL_PCD_RegisterLpmCallback(PCD_HandleTypeDef *hpcd, pPCD_LpmCallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_PCD_UnRegisterLpmCallback(PCD_HandleTypeDef *hpcd); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ +/** + * @} + */ + +/* I/O operation functions ***************************************************/ +/* Non-Blocking mode: Interrupt */ +/** @addtogroup PCD_Exported_Functions_Group2 Input and Output operation functions + * @{ + */ +HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd); +void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd); + +void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd); +void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd); +void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd); +void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd); +void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd); +void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd); +void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd); + +void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum); +void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum); +void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum); +void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum); +/** + * @} + */ + +/* Peripheral Control functions **********************************************/ +/** @addtogroup PCD_Exported_Functions_Group3 Peripheral Control functions + * @{ + */ +HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address); +HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type); +HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); +HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len); +HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len); +HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); +HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); +HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef const *hpcd, uint8_t ep_addr); +HAL_StatusTypeDef HAL_PCD_EP_Abort(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); +HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd); +uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef const *hpcd, uint8_t ep_addr); +/** + * @} + */ + +/* Peripheral State functions ************************************************/ +/** @addtogroup PCD_Exported_Functions_Group4 Peripheral State functions + * @{ + */ +PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef const *hpcd); +/** + * @} + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup PCD_Private_Constants PCD Private Constants + * @{ + */ +/** @defgroup USB_EXTI_Line_Interrupt USB EXTI line interrupt + * @{ + */ + + +#define USB_WAKEUP_EXTI_LINE (0x1U << 15) /*!< USB FS EXTI Line WakeUp Interrupt */ + + +/** + * @} + */ + +/** @defgroup PCD_EP0_MPS PCD EP0 MPS + * @{ + */ +#define PCD_EP0MPS_64 EP_MPS_64 +#define PCD_EP0MPS_32 EP_MPS_32 +#define PCD_EP0MPS_16 EP_MPS_16 +#define PCD_EP0MPS_08 EP_MPS_8 +/** + * @} + */ + +/** @defgroup PCD_ENDP PCD ENDP + * @{ + */ +#define PCD_ENDP0 0U +#define PCD_ENDP1 1U +#define PCD_ENDP2 2U +#define PCD_ENDP3 3U +#define PCD_ENDP4 4U +#define PCD_ENDP5 5U +#define PCD_ENDP6 6U +#define PCD_ENDP7 7U +/** + * @} + */ + +/** @defgroup PCD_ENDP_Kind PCD Endpoint Kind + * @{ + */ +#define PCD_SNG_BUF 0U +#define PCD_DBL_BUF 1U +/** + * @} + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup PCD_Private_Macros PCD Private Macros + * @{ + */ + +/* PMA RX counter */ +#ifndef PCD_RX_PMA_CNT +#define PCD_RX_PMA_CNT 10U +#endif /* PCD_RX_PMA_CNT */ + +/* SetENDPOINT */ +#define PCD_SET_ENDPOINT USB_DRD_SET_CHEP + +/* GetENDPOINT Register value*/ +#define PCD_GET_ENDPOINT USB_DRD_GET_CHEP + + +/** + * @brief free buffer used from the application realizing it to the line + * toggles bit SW_BUF in the double buffered endpoint register + * @param USBx USB device. + * @param bEpNum, bDir + * @retval None + */ +#define PCD_FREE_USER_BUFFER USB_DRD_FREE_USER_BUFFER + +/** + * @brief sets the status for tx transfer (bits STAT_TX[1:0]). + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @param wState new state + * @retval None + */ +#define PCD_SET_EP_TX_STATUS USB_DRD_SET_CHEP_TX_STATUS + +/** + * @brief sets the status for rx transfer (bits STAT_TX[1:0]) + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @param wState new state + * @retval None + */ +#define PCD_SET_EP_RX_STATUS USB_DRD_SET_CHEP_RX_STATUS + +/** + * @brief Sets/clears directly EP_KIND bit in the endpoint register. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @retval None + */ +#define PCD_SET_EP_KIND USB_DRD_SET_CHEP_KIND +#define PCD_CLEAR_EP_KIND USB_DRD_CLEAR_CHEP_KIND +#define PCD_SET_BULK_EP_DBUF PCD_SET_EP_KIND +#define PCD_CLEAR_BULK_EP_DBUF PCD_CLEAR_EP_KIND + + +/** + * @brief Clears bit CTR_RX / CTR_TX in the endpoint register. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @retval None + */ +#define PCD_CLEAR_RX_EP_CTR USB_DRD_CLEAR_RX_CHEP_CTR +#define PCD_CLEAR_TX_EP_CTR USB_DRD_CLEAR_TX_CHEP_CTR +/** + * @brief Toggles DTOG_RX / DTOG_TX bit in the endpoint register. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @retval None + */ +#define PCD_RX_DTOG USB_DRD_RX_DTOG +#define PCD_TX_DTOG USB_DRD_TX_DTOG +/** + * @brief Clears DTOG_RX / DTOG_TX bit in the endpoint register. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @retval None + */ +#define PCD_CLEAR_RX_DTOG USB_DRD_CLEAR_RX_DTOG +#define PCD_CLEAR_TX_DTOG USB_DRD_CLEAR_TX_DTOG + +/** + * @brief Sets address in an endpoint register. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @param bAddr Address. + * @retval None + */ +#define PCD_SET_EP_ADDRESS USB_DRD_SET_CHEP_ADDRESS + +/** + * @brief sets address of the tx/rx buffer. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @param wAddr address to be set (must be word aligned). + * @retval None + */ +#define PCD_SET_EP_TX_ADDRESS USB_DRD_SET_CHEP_TX_ADDRESS +#define PCD_SET_EP_RX_ADDRESS USB_DRD_SET_CHEP_RX_ADDRESS + +/** + * @brief sets counter for the tx/rx buffer. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @param wCount Counter value. + * @retval None + */ +#define PCD_SET_EP_TX_CNT USB_DRD_SET_CHEP_TX_CNT +#define PCD_SET_EP_RX_CNT USB_DRD_SET_CHEP_RX_CNT + +/** + * @brief gets counter of the tx buffer. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @retval Counter value + */ +#define PCD_GET_EP_TX_CNT USB_DRD_GET_CHEP_TX_CNT + +/** + * @brief gets counter of the rx buffer. + * @param Instance USB peripheral instance register address. + * @param bEpNum channel Number. + * @retval Counter value + */ +__STATIC_INLINE uint16_t PCD_GET_EP_RX_CNT(const PCD_TypeDef *Instance, uint16_t bEpNum) +{ + UNUSED(Instance); + __IO uint32_t count = PCD_RX_PMA_CNT; + + /* WA: few cycles for RX PMA descriptor to update */ + while (count > 0U) + { + count--; + } + + return (uint16_t)USB_DRD_GET_CHEP_RX_CNT((Instance), (bEpNum)); +} + +/** + * @brief Sets addresses in a double buffer endpoint. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @param wBuf0Addr: buffer 0 address. + * @param wBuf1Addr = buffer 1 address. + * @retval None + */ +#define PCD_SET_EP_DBUF_ADDR USB_DRD_SET_CHEP_DBUF_ADDR + +/** + * @brief Gets buffer 0/1 address of a double buffer endpoint. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @param bDir endpoint dir EP_DBUF_OUT = OUT + * EP_DBUF_IN = IN + * @param wCount: Counter value + * @retval None + */ +#define PCD_SET_EP_DBUF0_CNT USB_DRD_SET_CHEP_DBUF0_CNT +#define PCD_SET_EP_DBUF1_CNT USB_DRD_SET_CHEP_DBUF1_CNT +#define PCD_SET_EP_DBUF_CNT USB_DRD_SET_CHEP_DBUF_CNT + +/** + * @brief gets counter of the rx buffer0. + * @param Instance USB peripheral instance register address. + * @param bEpNum channel Number. + * @retval Counter value + */ +__STATIC_INLINE uint16_t PCD_GET_EP_DBUF0_CNT(const PCD_TypeDef *Instance, uint16_t bEpNum) +{ + UNUSED(Instance); + __IO uint32_t count = PCD_RX_PMA_CNT; + + /* WA: few cycles for RX PMA descriptor to update */ + while (count > 0U) + { + count--; + } + + return (uint16_t)USB_DRD_GET_CHEP_DBUF0_CNT((Instance), (bEpNum)); +} + +/** + * @brief gets counter of the rx buffer1. + * @param Instance USB peripheral instance register address. + * @param bEpNum channel Number. + * @retval Counter value + */ +__STATIC_INLINE uint16_t PCD_GET_EP_DBUF1_CNT(const PCD_TypeDef *Instance, uint16_t bEpNum) +{ + UNUSED(Instance); + __IO uint32_t count = PCD_RX_PMA_CNT; + + /* WA: few cycles for RX PMA descriptor to update */ + while (count > 0U) + { + count--; + } + + return (uint16_t)USB_DRD_GET_CHEP_DBUF1_CNT((Instance), (bEpNum)); +} + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* defined (USB_DRD_FS) */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_PCD_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_pcd_ex.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_pcd_ex.h new file mode 100644 index 0000000000..a92987f089 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_pcd_ex.h @@ -0,0 +1,88 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_pcd_ex.h + * @author MCD Application Team + * @brief Header file of PCD HAL Extension module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_PCD_EX_H +#define STM32H5xx_HAL_PCD_EX_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +#if defined (USB_DRD_FS) +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup PCDEx + * @{ + */ +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported macros -----------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup PCDEx_Exported_Functions PCDEx Exported Functions + * @{ + */ +/** @addtogroup PCDEx_Exported_Functions_Group1 Peripheral Control functions + * @{ + */ + + + +HAL_StatusTypeDef HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd, uint16_t ep_addr, + uint16_t ep_kind, uint32_t pmaadress); + + +HAL_StatusTypeDef HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef *hpcd); + + +HAL_StatusTypeDef HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef *hpcd); +void HAL_PCDEx_BCD_VBUSDetect(PCD_HandleTypeDef *hpcd); + +void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg); +void HAL_PCDEx_BCD_Callback(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* defined (USB_DRD_FS) */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* STM32H5xx_HAL_PCD_EX_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_pka.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_pka.h new file mode 100644 index 0000000000..92396b00fa --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_pka.h @@ -0,0 +1,653 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_pka.h + * @author MCD Application Team + * @brief Header file of PKA HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_PKA_H +#define STM32H5xx_HAL_PKA_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +#if defined(PKA) && defined(HAL_PKA_MODULE_ENABLED) + +/** @addtogroup PKA + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup PKA_Exported_Types PKA Exported Types + * @{ + */ + +/** @defgroup HAL_state_structure_definition HAL state structure definition + * @brief HAL State structures definition + * @{ + */ +typedef enum +{ + HAL_PKA_STATE_RESET = 0x00U, /*!< PKA not yet initialized or disabled */ + HAL_PKA_STATE_READY = 0x01U, /*!< PKA initialized and ready for use */ + HAL_PKA_STATE_BUSY = 0x02U, /*!< PKA internal processing is ongoing */ + HAL_PKA_STATE_ERROR = 0x03U, /*!< PKA error state */ +} +HAL_PKA_StateTypeDef; + +/** + * @} + */ + +#if (USE_HAL_PKA_REGISTER_CALLBACKS == 1) +/** @defgroup HAL_callback_id HAL callback ID enumeration + * @{ + */ +typedef enum +{ + HAL_PKA_OPERATION_COMPLETE_CB_ID = 0x00U, /*!< PKA End of operation callback ID */ + HAL_PKA_ERROR_CB_ID = 0x01U, /*!< PKA Error callback ID */ + HAL_PKA_MSPINIT_CB_ID = 0x02U, /*!< PKA Msp Init callback ID */ + HAL_PKA_MSPDEINIT_CB_ID = 0x03U /*!< PKA Msp DeInit callback ID */ +} HAL_PKA_CallbackIDTypeDef; + +/** + * @} + */ + +#endif /* USE_HAL_PKA_REGISTER_CALLBACKS */ + +/** @defgroup PKA_Error_Code_definition PKA Error Code definition + * @brief PKA Error Code definition + * @{ + */ +#define HAL_PKA_ERROR_NONE (0x00000000U) +#define HAL_PKA_ERROR_ADDRERR (0x00000001U) +#define HAL_PKA_ERROR_RAMERR (0x00000002U) +#define HAL_PKA_ERROR_TIMEOUT (0x00000004U) +#define HAL_PKA_ERROR_OPERATION (0x00000008U) +#if (USE_HAL_PKA_REGISTER_CALLBACKS == 1) +#define HAL_PKA_ERROR_INVALID_CALLBACK (0x00000010U) /*!< Invalid Callback error */ +#endif /* USE_HAL_PKA_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup PKA_handle_Structure_definition PKA handle Structure definition + * @brief PKA handle Structure definition + * @{ + */ +#if (USE_HAL_PKA_REGISTER_CALLBACKS == 1) +typedef struct __PKA_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_PKA_REGISTER_CALLBACKS */ +{ + PKA_TypeDef *Instance; /*!< Register base address */ + __IO HAL_PKA_StateTypeDef State; /*!< PKA state */ + __IO uint32_t ErrorCode; /*!< PKA Error code */ +#if (USE_HAL_PKA_REGISTER_CALLBACKS == 1) + void (* OperationCpltCallback)(struct __PKA_HandleTypeDef *hpka); /*!< PKA End of operation callback */ + void (* ErrorCallback)(struct __PKA_HandleTypeDef *hpka); /*!< PKA Error callback */ + void (* MspInitCallback)(struct __PKA_HandleTypeDef *hpka); /*!< PKA Msp Init callback */ + void (* MspDeInitCallback)(struct __PKA_HandleTypeDef *hpka); /*!< PKA Msp DeInit callback */ +#endif /* USE_HAL_PKA_REGISTER_CALLBACKS */ +} PKA_HandleTypeDef; +/** + * @} + */ + +#if (USE_HAL_PKA_REGISTER_CALLBACKS == 1) +/** @defgroup PKA_Callback_definition PKA Callback pointer definition + * @brief PKA Callback pointer definition + * @{ + */ +typedef void (*pPKA_CallbackTypeDef)(PKA_HandleTypeDef *hpka); /*!< Pointer to a PKA callback function */ +/** + * @} + */ +#endif /* USE_HAL_PKA_REGISTER_CALLBACKS */ +/** @defgroup PKA_Operation PKA operation structure definition + * @brief Input and output data definition + * @{ + */ + +typedef struct +{ + uint32_t scalarMulSize; /*!< Number of element in scalarMul array */ + uint32_t modulusSize; /*!< Number of element in modulus, coefA, pointX and pointY arrays */ + uint32_t coefSign; /*!< Curve coefficient a sign */ + const uint8_t *coefA; /*!< Pointer to curve coefficient |a| (Array of modulusSize elements) */ + const uint8_t *coefB; /*!< pointer to curve coefficient b */ + const uint8_t *modulus; /*!< Pointer to curve modulus value p (Array of modulusSize elements) */ + const uint8_t *pointX; /*!< Pointer to point P coordinate xP (Array of modulusSize elements) */ + const uint8_t *pointY; /*!< Pointer to point P coordinate yP (Array of modulusSize elements) */ + const uint8_t *scalarMul; /*!< Pointer to scalar multiplier k (Array of scalarMulSize elements) */ + const uint8_t *primeOrder; /*!< pointer to order of the curve */ +} PKA_ECCMulInTypeDef; + +typedef struct +{ + uint32_t modulusSize; /*!< Number of element in coefA, coefB, modulus, pointX and pointY arrays */ + uint32_t coefSign; /*!< Curve coefficient a sign */ + const uint8_t *coefA; /*!< Pointer to curve coefficient |a| (Array of modulusSize elements) */ + const uint8_t *coefB; /*!< Pointer to curve coefficient b (Array of modulusSize elements) */ + const uint8_t *modulus; /*!< Pointer to curve modulus value p (Array of modulusSize elements) */ + const uint8_t *pointX; /*!< Pointer to point P coordinate xP (Array of modulusSize elements) */ + const uint8_t *pointY; /*!< Pointer to point P coordinate yP (Array of modulusSize elements) */ + const uint32_t *pMontgomeryParam; /*!< pointer to montgomery param R2 (modulus N) */ +} PKA_PointCheckInTypeDef; + +typedef struct +{ + uint32_t size; /*!< Number of element in popA array */ + const uint8_t *pOpDp; /*!< Pointer to operand dP (Array of size/2 elements) */ + const uint8_t *pOpDq; /*!< Pointer to operand dQ (Array of size/2 elements) */ + const uint8_t *pOpQinv; /*!< Pointer to operand qinv (Array of size/2 elements) */ + const uint8_t *pPrimeP; /*!< Pointer to prime p (Array of size/2 elements) */ + const uint8_t *pPrimeQ; /*!< Pointer to prime Q (Array of size/2 elements) */ + const uint8_t *popA; /*!< Pointer to operand A (Array of size elements) */ +} PKA_RSACRTExpInTypeDef; + +typedef struct +{ + uint32_t primeOrderSize; /*!< Number of element in primeOrder array */ + uint32_t modulusSize; /*!< Number of element in modulus array */ + uint32_t coefSign; /*!< Curve coefficient a sign */ + const uint8_t *coef; /*!< Pointer to curve coefficient |a| (Array of modulusSize elements) */ + const uint8_t *modulus; /*!< Pointer to curve modulus value p (Array of modulusSize elements) */ + const uint8_t *basePointX; /*!< Pointer to curve base point xG (Array of modulusSize elements) */ + const uint8_t *basePointY; /*!< Pointer to curve base point yG (Array of modulusSize elements) */ + const uint8_t *pPubKeyCurvePtX; /*!< Pointer to public-key curve point xQ (Array of modulusSize elements) */ + const uint8_t *pPubKeyCurvePtY; /*!< Pointer to public-key curve point yQ (Array of modulusSize elements) */ + const uint8_t *RSign; /*!< Pointer to signature part r (Array of primeOrderSize elements) */ + const uint8_t *SSign; /*!< Pointer to signature part s (Array of primeOrderSize elements) */ + const uint8_t *hash; /*!< Pointer to hash of the message e (Array of primeOrderSize elements) */ + const uint8_t *primeOrder; /*!< Pointer to order of the curve n (Array of primeOrderSize elements) */ +} PKA_ECDSAVerifInTypeDef; + +typedef struct +{ + uint32_t primeOrderSize; /*!< Number of element in primeOrder array */ + uint32_t modulusSize; /*!< Number of element in modulus array */ + uint32_t coefSign; /*!< Curve coefficient a sign */ + const uint8_t *coef; /*!< Pointer to curve coefficient |a| (Array of modulusSize elements) */ + const uint8_t *coefB; /*!< Pointer to B coefficient (Array of modulusSize elements) */ + const uint8_t *modulus; /*!< Pointer to curve modulus value p (Array of modulusSize elements) */ + const uint8_t *integer; /*!< Pointer to random integer k (Array of primeOrderSize elements) */ + const uint8_t *basePointX; /*!< Pointer to curve base point xG (Array of modulusSize elements) */ + const uint8_t *basePointY; /*!< Pointer to curve base point yG (Array of modulusSize elements) */ + const uint8_t *hash; /*!< Pointer to hash of the message (Array of primeOrderSize elements) */ + const uint8_t *privateKey; /*!< Pointer to private key d (Array of primeOrderSize elements) */ + const uint8_t *primeOrder; /*!< Pointer to order of the curve n (Array of primeOrderSize elements) */ +} PKA_ECDSASignInTypeDef; + +typedef struct +{ + uint8_t *RSign; /*!< Pointer to signature part r (Array of modulusSize elements) */ + uint8_t *SSign; /*!< Pointer to signature part s (Array of modulusSize elements) */ +} PKA_ECDSASignOutTypeDef; + +typedef struct +{ + uint8_t *ptX; /*!< Pointer to point P coordinate xP (Array of modulusSize elements) */ + uint8_t *ptY; /*!< Pointer to point P coordinate yP (Array of modulusSize elements) */ +} PKA_ECDSASignOutExtParamTypeDef, PKA_ECCMulOutTypeDef, PKA_ECCProjective2AffineOutTypeDef, +PKA_ECCDoubleBaseLadderOutTypeDef; + +typedef struct +{ + uint8_t *ptX; /*!< pointer to point P coordinate xP */ + uint8_t *ptY; /*!< pointer to point P coordinate yP */ + uint8_t *ptZ; /*!< pointer to point P coordinate zP */ +} PKA_ECCCompleteAdditionOutTypeDef; + +typedef struct +{ + uint32_t expSize; /*!< Number of element in pExp array */ + uint32_t OpSize; /*!< Number of element in pOp1 and pMod arrays */ + const uint8_t *pExp; /*!< Pointer to Exponent (Array of expSize elements) */ + const uint8_t *pOp1; /*!< Pointer to Operand (Array of OpSize elements) */ + const uint8_t *pMod; /*!< Pointer to modulus (Array of OpSize elements) */ +} PKA_ModExpInTypeDef; + +typedef struct +{ + uint32_t expSize; /*!< Size of the operand in bytes */ + uint32_t OpSize; /*!< Size of the operand in bytes */ + const uint8_t *pOp1; /*!< Pointer to Operand 1 */ + const uint8_t *pExp; /*!< Pointer to Exponent */ + const uint8_t *pMod; /*!< Pointer to Operand 1 */ + const uint8_t *pPhi; /*!< Pointer to Phi value */ +} PKA_ModExpProtectModeInTypeDef; + +typedef struct +{ + uint32_t expSize; /*!< Number of element in pExp and pMontgomeryParam arrays */ + uint32_t OpSize; /*!< Number of element in pOp1 and pMod arrays */ + const uint8_t *pExp; /*!< Pointer to Exponent (Array of expSize elements) */ + const uint8_t *pOp1; /*!< Pointer to Operand (Array of OpSize elements) */ + const uint8_t *pMod; /*!< Pointer to modulus (Array of OpSize elements) */ + const uint32_t *pMontgomeryParam; /*!< Pointer to Montgomery parameter (Array of expSize/4 elements) */ +} PKA_ModExpFastModeInTypeDef; + +typedef struct +{ + uint32_t size; /*!< Number of element in pOp1 array */ + const uint8_t *pOp1; /*!< Pointer to Operand (Array of size elements) */ +} PKA_MontgomeryParamInTypeDef; + +typedef struct +{ + uint32_t size; /*!< Number of element in pOp1 and pOp2 arrays */ + const uint32_t *pOp1; /*!< Pointer to Operand 1 (Array of size elements) */ + const uint32_t *pOp2; /*!< Pointer to Operand 2 (Array of size elements) */ +} PKA_AddInTypeDef, PKA_SubInTypeDef, PKA_MulInTypeDef, PKA_CmpInTypeDef; + +typedef struct +{ + uint32_t size; /*!< Number of element in pOp1 array */ + const uint32_t *pOp1; /*!< Pointer to Operand 1 (Array of size elements) */ + const uint8_t *pMod; /*!< Pointer to modulus value n (Array of size*4 elements) */ +} PKA_ModInvInTypeDef; + +typedef struct +{ + uint32_t OpSize; /*!< Number of element in pOp1 array */ + uint32_t modSize; /*!< Number of element in pMod array */ + const uint32_t *pOp1; /*!< Pointer to Operand 1 (Array of OpSize elements) */ + const uint8_t *pMod; /*!< Pointer to modulus value n (Array of modSize elements) */ +} PKA_ModRedInTypeDef; + +typedef struct +{ + uint32_t size; /*!< Number of element in pOp1 and pOp2 arrays */ + const uint32_t *pOp1; /*!< Pointer to Operand 1 (Array of size elements) */ + const uint32_t *pOp2; /*!< Pointer to Operand 2 (Array of size elements) */ + const uint8_t *pOp3; /*!< Pointer to Operand 3 (Array of size*4 elements) */ +} PKA_ModAddInTypeDef, PKA_ModSubInTypeDef, PKA_MontgomeryMulInTypeDef; + +typedef struct +{ + uint32_t primeOrderSize; /*!< curve prime order n length */ + uint32_t modulusSize; /*!< curve modulus p length */ + uint32_t coefSign; /*!< curve coefficient a sign */ + const uint8_t *coefA; /*!< pointer to curve coefficient |a| */ + const uint8_t *modulus; /*!< pointer to curve modulus value p */ + const uint8_t *integerK; /*!< pointer to cryptographically secure random integer k */ + const uint8_t *integerM; /*!< pointer to cryptographically secure random integer m */ + const uint8_t *basePointX1; /*!< pointer to curve base first point coordinate x */ + const uint8_t *basePointY1; /*!< pointer to curve base first point coordinate y */ + const uint8_t *basePointZ1; /*!< pointer to curve base first point coordinate z */ + const uint8_t *basePointX2; /*!< pointer to curve base second point coordinate x */ + const uint8_t *basePointY2; /*!< pointer to curve base second point coordinate y */ + const uint8_t *basePointZ2; /*!< pointer to curve base second point coordinate z */ +} PKA_ECCDoubleBaseLadderInTypeDef; + +typedef struct +{ + uint32_t modulusSize; /*!< curve modulus p length */ + const uint8_t *modulus; /*!< pointer to curve modulus value p */ + const uint8_t *basePointX; /*!< pointer to curve base point coordinate x */ + const uint8_t *basePointY; /*!< pointer to curve base point coordinate y */ + const uint8_t *basePointZ; /*!< pointer to curve base point coordinate z */ + const uint32_t *pMontgomeryParam; /*!< pointer to montgomery parameter R2 modulus n*/ +} PKA_ECCProjective2AffineInTypeDef; + +typedef struct +{ + uint32_t modulusSize; /*!< curve modulus p length */ + uint32_t coefSign; /*!< curve coefficient a sign */ + const uint8_t *modulus; /*!< pointer to curve modulus value p */ + const uint8_t *coefA; /*!< pointer to curve coefficient |a| */ + const uint8_t *basePointX1; /*!< pointer to curve base first point coordinate x */ + const uint8_t *basePointY1; /*!< pointer to curve base first point coordinate y */ + const uint8_t *basePointZ1; /*!< pointer to curve base first point coordinate z */ + const uint8_t *basePointX2; /*!< pointer to curve base second point coordinate x */ + const uint8_t *basePointY2; /*!< pointer to curve base second point coordinate y */ + const uint8_t *basePointZ2; /*!< pointer to curve base second point coordinate z */ +} PKA_ECCCompleteAdditionInTypeDef; +/** + * @} + */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup PKA_Exported_Constants PKA Exported Constants + * @{ + */ + +/** @defgroup PKA_Mode PKA mode + * @{ + */ +#define PKA_MODE_MONTGOMERY_PARAM (0x00000001U) +#define PKA_MODE_MODULAR_EXP (0x00000000U) +#define PKA_MODE_MODULAR_EXP_FAST_MODE (0x00000002U) +#define PKA_MODE_ECC_MUL (0x00000020U) +#define PKA_MODE_ECDSA_SIGNATURE (0x00000024U) +#define PKA_MODE_ECDSA_VERIFICATION (0x00000026U) +#define PKA_MODE_POINT_CHECK (0x00000028U) +#define PKA_MODE_RSA_CRT_EXP (0x00000007U) +#define PKA_MODE_MODULAR_INV (0x00000008U) +#define PKA_MODE_ARITHMETIC_ADD (0x00000009U) +#define PKA_MODE_ARITHMETIC_SUB (0x0000000AU) +#define PKA_MODE_ARITHMETIC_MUL (0x0000000BU) +#define PKA_MODE_COMPARISON (0x0000000CU) +#define PKA_MODE_MODULAR_RED (0x0000000DU) +#define PKA_MODE_MODULAR_ADD (0x0000000EU) +#define PKA_MODE_MODULAR_SUB (0x0000000FU) +#define PKA_MODE_MONTGOMERY_MUL (0x00000010U) +#define PKA_MODE_ECC_PROJECTIVE_AFF (0x0000002FU) +#define PKA_MODE_DOUBLE_BASE_LADDER (0x00000027U) +#define PKA_MODE_ECC_COMPLETE_ADD (0x00000023U) +#define PKA_MODE_MODULAR_EXP_PROTECT (0x00000003U) +/** + * @} + */ + +/** @defgroup PKA_Interrupt_configuration_definition PKA Interrupt configuration definition + * @brief PKA Interrupt definition + * @{ + */ +#define PKA_IT_PROCEND PKA_CR_PROCENDIE +#define PKA_IT_ADDRERR PKA_CR_ADDRERRIE +#define PKA_IT_RAMERR PKA_CR_RAMERRIE +#define PKA_IT_OPERR PKA_CR_OPERRIE + +/** + * @} + */ + +/** @defgroup PKA_Flag_definition PKA Flag definition + * @{ + */ +#define PKA_FLAG_PROCEND PKA_SR_PROCENDF +#define PKA_FLAG_ADDRERR PKA_SR_ADDRERRF +#define PKA_FLAG_RAMERR PKA_SR_RAMERRF +#define PKA_FLAG_OPERR PKA_SR_OPERRF + +/** + * @} + */ + +/** @defgroup PKA_Operation_Status PKA Operation Status + * @{ + */ +#define PKA_NO_ERROR 0xD60DUL +#define PKA_FAILED_COMPUTATION 0xCBC9UL +#define PKA_RPART_SIGNATURE_NULL 0xA3B7UL +#define PKA_SPART_SIGNATURE_NULL 0xF946UL + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ + +/** @defgroup PKA_Exported_Macros PKA Exported Macros + * @{ + */ + +/** @brief Reset PKA handle state. + * @param __HANDLE__ specifies the PKA Handle + * @retval None + */ +#if (USE_HAL_PKA_REGISTER_CALLBACKS == 1) +#define __HAL_PKA_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->State = HAL_PKA_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_PKA_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_PKA_STATE_RESET) +#endif /* USE_HAL_PKA_REGISTER_CALLBACKS */ + +/** @brief Enable the specified PKA interrupt. + * @param __HANDLE__ specifies the PKA Handle + * @param __INTERRUPT__ specifies the interrupt source to enable. + * This parameter can be one of the following values: + * @arg @ref PKA_IT_PROCEND End Of Operation interrupt enable + * @arg @ref PKA_IT_ADDRERR Address error interrupt enable + * @arg @ref PKA_IT_RAMERR RAM error interrupt enable + * @arg @ref PKA_IT_OPERR Operation error interrupt enable + * @retval None + */ +#define __HAL_PKA_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR |= (__INTERRUPT__)) + +/** @brief Disable the specified PKA interrupt. + * @param __HANDLE__ specifies the PKA Handle + * @param __INTERRUPT__ specifies the interrupt source to disable. + * This parameter can be one of the following values: + * @arg @ref PKA_IT_PROCEND End Of Operation interrupt enable + * @arg @ref PKA_IT_ADDRERR Address error interrupt enable + * @arg @ref PKA_IT_RAMERR RAM error interrupt enable + * @arg @ref PKA_IT_OPERR Operation error interrupt enable + * @retval None + */ +#define __HAL_PKA_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR &= (~(__INTERRUPT__))) + +/** @brief Check whether the specified PKA interrupt source is enabled or not. + * @param __HANDLE__ specifies the PKA Handle + * @param __INTERRUPT__ specifies the PKA interrupt source to check. + * This parameter can be one of the following values: + * @arg @ref PKA_IT_PROCEND End Of Operation interrupt enable + * @arg @ref PKA_IT_ADDRERR Address error interrupt enable + * @arg @ref PKA_IT_RAMERR RAM error interrupt enable + * @arg @ref PKA_IT_OPERR Operation error interrupt enable + * @retval The new state of __INTERRUPT__ (SET or RESET) + */ +#define __HAL_PKA_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CR\ + & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) + +/** @brief Check whether the specified PKA flag is set or not. + * @param __HANDLE__ specifies the PKA Handle + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg @ref PKA_FLAG_PROCEND End Of Operation + * @arg @ref PKA_FLAG_ADDRERR Address error + * @arg @ref PKA_FLAG_RAMERR RAM error + * @arg @ref PKA_FLAG_OPERR Operation error + * @retval The new state of __FLAG__ (SET or RESET) + */ +#define __HAL_PKA_GET_FLAG(__HANDLE__, __FLAG__) (((((__HANDLE__)->Instance->SR)\ + & (__FLAG__)) == (__FLAG__)) ? SET : RESET) + +/** @brief Clear the PKA pending flags which are cleared by writing 1 in a specific bit. + * @param __HANDLE__ specifies the PKA Handle + * @param __FLAG__ specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg @ref PKA_FLAG_PROCEND End Of Operation + * @arg @ref PKA_FLAG_ADDRERR Address error + * @arg @ref PKA_FLAG_RAMERR RAM error + * @arg @ref PKA_FLAG_OPERR Operation error + * @retval None + */ +#define __HAL_PKA_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->CLRFR = (__FLAG__)) + +/** @brief Enable the specified PKA peripheral. + * @param __HANDLE__ specifies the PKA Handle + * @retval None + */ +#define __HAL_PKA_ENABLE(__HANDLE__) (SET_BIT((__HANDLE__)->Instance->CR, PKA_CR_EN)) + +/** @brief Disable the specified PKA peripheral. + * @param __HANDLE__ specifies the PKA Handle + * @retval None + */ +#define __HAL_PKA_DISABLE(__HANDLE__) (CLEAR_BIT((__HANDLE__)->Instance->CR, PKA_CR_EN)) + +/** @brief Start a PKA operation. + * @param __HANDLE__ specifies the PKA Handle + * @retval None + */ +#define __HAL_PKA_START(__HANDLE__) (SET_BIT((__HANDLE__)->Instance->CR, PKA_CR_START)) +/** + * @} + */ + +/* Private macros --------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup PKA_Exported_Functions + * @{ + */ + +/** @addtogroup PKA_Exported_Functions_Group1 + * @{ + */ +/* Initialization and de-initialization functions *****************************/ +HAL_StatusTypeDef HAL_PKA_Init(PKA_HandleTypeDef *hpka); +HAL_StatusTypeDef HAL_PKA_DeInit(PKA_HandleTypeDef *hpka); +void HAL_PKA_MspInit(PKA_HandleTypeDef *hpka); +void HAL_PKA_MspDeInit(PKA_HandleTypeDef *hpka); + +#if (USE_HAL_PKA_REGISTER_CALLBACKS == 1) +/* Callbacks Register/UnRegister functions ***********************************/ +HAL_StatusTypeDef HAL_PKA_RegisterCallback(PKA_HandleTypeDef *hpka, HAL_PKA_CallbackIDTypeDef CallbackID, + pPKA_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_PKA_UnRegisterCallback(PKA_HandleTypeDef *hpka, HAL_PKA_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_PKA_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @addtogroup PKA_Exported_Functions_Group2 + * @{ + */ +/* IO operation functions *****************************************************/ +/* High Level Functions *******************************************************/ +HAL_StatusTypeDef HAL_PKA_ModExp(PKA_HandleTypeDef *hpka, PKA_ModExpInTypeDef *in, uint32_t Timeout); +HAL_StatusTypeDef HAL_PKA_ModExp_IT(PKA_HandleTypeDef *hpka, PKA_ModExpInTypeDef *in); +HAL_StatusTypeDef HAL_PKA_ModExpFastMode(PKA_HandleTypeDef *hpka, PKA_ModExpFastModeInTypeDef *in, uint32_t Timeout); +HAL_StatusTypeDef HAL_PKA_ModExpFastMode_IT(PKA_HandleTypeDef *hpka, PKA_ModExpFastModeInTypeDef *in); +HAL_StatusTypeDef HAL_PKA_ModExpProtectMode(PKA_HandleTypeDef *hpka, PKA_ModExpProtectModeInTypeDef *in, + uint32_t Timeout); +HAL_StatusTypeDef HAL_PKA_ModExpProtectMode_IT(PKA_HandleTypeDef *hpka, PKA_ModExpProtectModeInTypeDef *in); +void HAL_PKA_ModExp_GetResult(PKA_HandleTypeDef *hpka, uint8_t *pRes); + +HAL_StatusTypeDef HAL_PKA_ECDSASign(PKA_HandleTypeDef *hpka, PKA_ECDSASignInTypeDef *in, uint32_t Timeout); +HAL_StatusTypeDef HAL_PKA_ECDSASign_IT(PKA_HandleTypeDef *hpka, PKA_ECDSASignInTypeDef *in); +void HAL_PKA_ECDSASign_GetResult(PKA_HandleTypeDef *hpka, PKA_ECDSASignOutTypeDef *out, + PKA_ECDSASignOutExtParamTypeDef *outExt); + +HAL_StatusTypeDef HAL_PKA_ECDSAVerif(PKA_HandleTypeDef *hpka, PKA_ECDSAVerifInTypeDef *in, uint32_t Timeout); +HAL_StatusTypeDef HAL_PKA_ECDSAVerif_IT(PKA_HandleTypeDef *hpka, PKA_ECDSAVerifInTypeDef *in); +uint32_t HAL_PKA_ECDSAVerif_IsValidSignature(PKA_HandleTypeDef const *const hpka); + +HAL_StatusTypeDef HAL_PKA_RSACRTExp(PKA_HandleTypeDef *hpka, PKA_RSACRTExpInTypeDef *in, uint32_t Timeout); +HAL_StatusTypeDef HAL_PKA_RSACRTExp_IT(PKA_HandleTypeDef *hpka, PKA_RSACRTExpInTypeDef *in); +void HAL_PKA_RSACRTExp_GetResult(PKA_HandleTypeDef *hpka, uint8_t *pRes); + +HAL_StatusTypeDef HAL_PKA_PointCheck(PKA_HandleTypeDef *hpka, PKA_PointCheckInTypeDef *in, uint32_t Timeout); +HAL_StatusTypeDef HAL_PKA_PointCheck_IT(PKA_HandleTypeDef *hpka, PKA_PointCheckInTypeDef *in); +uint32_t HAL_PKA_PointCheck_IsOnCurve(PKA_HandleTypeDef const *const hpka); + +HAL_StatusTypeDef HAL_PKA_ECCMul(PKA_HandleTypeDef *hpka, PKA_ECCMulInTypeDef *in, uint32_t Timeout); +HAL_StatusTypeDef HAL_PKA_ECCMul_IT(PKA_HandleTypeDef *hpka, PKA_ECCMulInTypeDef *in); +void HAL_PKA_ECCMul_GetResult(PKA_HandleTypeDef *hpka, PKA_ECCMulOutTypeDef *out); + +HAL_StatusTypeDef HAL_PKA_Add(PKA_HandleTypeDef *hpka, PKA_AddInTypeDef *in, uint32_t Timeout); +HAL_StatusTypeDef HAL_PKA_Add_IT(PKA_HandleTypeDef *hpka, PKA_AddInTypeDef *in); +HAL_StatusTypeDef HAL_PKA_Sub(PKA_HandleTypeDef *hpka, PKA_SubInTypeDef *in, uint32_t Timeout); +HAL_StatusTypeDef HAL_PKA_Sub_IT(PKA_HandleTypeDef *hpka, PKA_SubInTypeDef *in); +HAL_StatusTypeDef HAL_PKA_Cmp(PKA_HandleTypeDef *hpka, PKA_CmpInTypeDef *in, uint32_t Timeout); +HAL_StatusTypeDef HAL_PKA_Cmp_IT(PKA_HandleTypeDef *hpka, PKA_CmpInTypeDef *in); +HAL_StatusTypeDef HAL_PKA_Mul(PKA_HandleTypeDef *hpka, PKA_MulInTypeDef *in, uint32_t Timeout); +HAL_StatusTypeDef HAL_PKA_Mul_IT(PKA_HandleTypeDef *hpka, PKA_MulInTypeDef *in); +HAL_StatusTypeDef HAL_PKA_ModAdd(PKA_HandleTypeDef *hpka, PKA_ModAddInTypeDef *in, uint32_t Timeout); +HAL_StatusTypeDef HAL_PKA_ModAdd_IT(PKA_HandleTypeDef *hpka, PKA_ModAddInTypeDef *in); +HAL_StatusTypeDef HAL_PKA_ModSub(PKA_HandleTypeDef *hpka, PKA_ModSubInTypeDef *in, uint32_t Timeout); +HAL_StatusTypeDef HAL_PKA_ModSub_IT(PKA_HandleTypeDef *hpka, PKA_ModSubInTypeDef *in); +HAL_StatusTypeDef HAL_PKA_ModInv(PKA_HandleTypeDef *hpka, PKA_ModInvInTypeDef *in, uint32_t Timeout); +HAL_StatusTypeDef HAL_PKA_ModInv_IT(PKA_HandleTypeDef *hpka, PKA_ModInvInTypeDef *in); +HAL_StatusTypeDef HAL_PKA_ModRed(PKA_HandleTypeDef *hpka, PKA_ModRedInTypeDef *in, uint32_t Timeout); +HAL_StatusTypeDef HAL_PKA_ModRed_IT(PKA_HandleTypeDef *hpka, PKA_ModRedInTypeDef *in); +HAL_StatusTypeDef HAL_PKA_MontgomeryMul(PKA_HandleTypeDef *hpka, PKA_MontgomeryMulInTypeDef *in, uint32_t Timeout); +HAL_StatusTypeDef HAL_PKA_MontgomeryMul_IT(PKA_HandleTypeDef *hpka, PKA_MontgomeryMulInTypeDef *in); +void HAL_PKA_Arithmetic_GetResult(PKA_HandleTypeDef *hpka, uint32_t *pRes); + +HAL_StatusTypeDef HAL_PKA_MontgomeryParam(PKA_HandleTypeDef *hpka, PKA_MontgomeryParamInTypeDef *in, uint32_t Timeout); +HAL_StatusTypeDef HAL_PKA_MontgomeryParam_IT(PKA_HandleTypeDef *hpka, PKA_MontgomeryParamInTypeDef *in); +void HAL_PKA_MontgomeryParam_GetResult(PKA_HandleTypeDef *hpka, uint32_t *pRes); + +HAL_StatusTypeDef HAL_PKA_ECCDoubleBaseLadder(PKA_HandleTypeDef *hpka, PKA_ECCDoubleBaseLadderInTypeDef *in, + uint32_t Timeout); +HAL_StatusTypeDef HAL_PKA_ECCDoubleBaseLadder_IT(PKA_HandleTypeDef *hpka, PKA_ECCDoubleBaseLadderInTypeDef *in); +void HAL_PKA_ECCDoubleBaseLadder_GetResult(PKA_HandleTypeDef *hpka, PKA_ECCDoubleBaseLadderOutTypeDef *out); + +HAL_StatusTypeDef HAL_PKA_ECCProjective2Affine(PKA_HandleTypeDef *hpka, PKA_ECCProjective2AffineInTypeDef *in, + uint32_t Timeout); +HAL_StatusTypeDef HAL_PKA_ECCProjective2Affine_IT(PKA_HandleTypeDef *hpka, PKA_ECCProjective2AffineInTypeDef *in); +void HAL_PKA_ECCProjective2Affine_GetResult(PKA_HandleTypeDef *hpka, PKA_ECCProjective2AffineOutTypeDef *out); + +HAL_StatusTypeDef HAL_PKA_ECCCompleteAddition(PKA_HandleTypeDef *hpka, PKA_ECCCompleteAdditionInTypeDef *in, + uint32_t Timeout); +HAL_StatusTypeDef HAL_PKA_ECCCompleteAddition_IT(PKA_HandleTypeDef *hpka, PKA_ECCCompleteAdditionInTypeDef *in); +void HAL_PKA_ECCCompleteAddition_GetResult(PKA_HandleTypeDef *hpka, PKA_ECCCompleteAdditionOutTypeDef *out); + +HAL_StatusTypeDef HAL_PKA_Abort(PKA_HandleTypeDef *hpka); +void HAL_PKA_RAMReset(PKA_HandleTypeDef *hpka); +void HAL_PKA_OperationCpltCallback(PKA_HandleTypeDef *hpka); +void HAL_PKA_ErrorCallback(PKA_HandleTypeDef *hpka); +void HAL_PKA_IRQHandler(PKA_HandleTypeDef *hpka); +/** + * @} + */ + +/** @addtogroup PKA_Exported_Functions_Group3 + * @{ + */ +/* Peripheral State and Error functions ***************************************/ +HAL_PKA_StateTypeDef HAL_PKA_GetState(const PKA_HandleTypeDef *hpka); +uint32_t HAL_PKA_GetError(const PKA_HandleTypeDef *hpka); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined(PKA) && defined(HAL_PKA_MODULE_ENABLED) */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_PKA_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_pssi.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_pssi.h new file mode 100644 index 0000000000..57e87bf23c --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_pssi.h @@ -0,0 +1,536 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_pssi.h + * @author MCD Application Team + * @brief Header file of PSSI HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_PSSI_H +#define STM32H5xx_HAL_PSSI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ +#if defined(PSSI) + +#ifndef USE_HAL_PSSI_REGISTER_CALLBACKS +/* For backward compatibility, if USE_HAL_PSSI_REGISTER_CALLBACKS not defined, define it to 1*/ +#define USE_HAL_PSSI_REGISTER_CALLBACKS 0U +#endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */ + +/** @addtogroup PSSI PSSI + * @brief PSSI HAL module driver + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup PSSI_Exported_Types PSSI Exported Types + * @{ + */ + + +/** + * @brief PSSI Init structure definition + */ +typedef struct +{ + uint32_t DataWidth; /* !< Configures the parallel bus width 8 lines or 16 lines */ + uint32_t BusWidth; /* !< Configures the parallel bus width 8 lines or 16 lines */ + uint32_t ControlSignal; /* !< Configures Data enable and Data ready */ + uint32_t ClockPolarity; /* !< Configures the PSSI Input Clock polarity */ + uint32_t DataEnablePolarity; /* !< Configures the PSSI Data Enable polarity */ + uint32_t ReadyPolarity; /* !< Configures the PSSI Ready polarity */ + +} PSSI_InitTypeDef; + + +/** + * @brief HAL PSSI State structures definition + */ +typedef enum +{ + HAL_PSSI_STATE_RESET = 0x00U, /* !< PSSI not yet initialized or disabled */ + HAL_PSSI_STATE_READY = 0x01U, /* !< Peripheral initialized and ready for use */ + HAL_PSSI_STATE_BUSY = 0x02U, /* !< An internal process is ongoing */ + HAL_PSSI_STATE_BUSY_TX = 0x03U, /* !< Transmit process is ongoing */ + HAL_PSSI_STATE_BUSY_RX = 0x04U, /* !< Receive process is ongoing */ + HAL_PSSI_STATE_TIMEOUT = 0x05U, /* !< Timeout state */ + HAL_PSSI_STATE_ERROR = 0x06U, /* !< PSSI state error */ + HAL_PSSI_STATE_ABORT = 0x07U, /* !< PSSI process is aborted */ + +} HAL_PSSI_StateTypeDef; + +/** + * @brief PSSI handle Structure definition + */ +#if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1) +typedef struct __PSSI_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */ +{ + PSSI_TypeDef *Instance; /*!< PSSI register base address. */ + PSSI_InitTypeDef Init; /*!< PSSI Initialization Structure. */ + uint32_t *pBuffPtr; /*!< PSSI Data buffer. */ + uint32_t XferCount; /*!< PSSI transfer count */ + uint32_t XferSize; /*!< PSSI transfer size */ +#if defined(HAL_DMA_MODULE_ENABLED) + DMA_HandleTypeDef *hdmatx; /*!< PSSI Tx DMA Handle parameters */ + DMA_HandleTypeDef *hdmarx; /*!< PSSI Rx DMA Handle parameters */ +#endif /*HAL_DMA_MODULE_ENABLED*/ + +#if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1) + void (* TxCpltCallback)(struct __PSSI_HandleTypeDef *hpssi); /*!< PSSI transfer complete callback. */ + void (* RxCpltCallback)(struct __PSSI_HandleTypeDef *hpssi); /*!< PSSI transfer complete callback. */ + void (* ErrorCallback)(struct __PSSI_HandleTypeDef *hpssi); /*!< PSSI transfer complete callback. */ + void (* AbortCpltCallback)(struct __PSSI_HandleTypeDef *hpssi); /*!< PSSI transfer error callback. */ + + void (* MspInitCallback)(struct __PSSI_HandleTypeDef *hpssi); /*!< PSSI Msp Init callback. */ + void (* MspDeInitCallback)(struct __PSSI_HandleTypeDef *hpssi); /*!< PSSI Msp DeInit callback. */ +#endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */ + + HAL_LockTypeDef Lock; /*!< PSSI lock. */ + __IO HAL_PSSI_StateTypeDef State; /*!< PSSI transfer state. */ + __IO uint32_t ErrorCode; /*!< PSSI error code. */ + +} PSSI_HandleTypeDef; + +#if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1) +/** + * @brief HAL PSSI Callback pointer definition + */ +typedef void (*pPSSI_CallbackTypeDef)(PSSI_HandleTypeDef *hpssi); /*!< Pointer to a PSSI common callback function */ + +/** + * @brief HAL PSSI Callback ID enumeration definition + */ +typedef enum +{ + HAL_PSSI_TX_COMPLETE_CB_ID = 0x00U, /*!< PSSI Tx Transfer completed callback ID */ + HAL_PSSI_RX_COMPLETE_CB_ID = 0x01U, /*!< PSSI Rx Transfer completed callback ID */ + HAL_PSSI_ERROR_CB_ID = 0x03U, /*!< PSSI Error callback ID */ + HAL_PSSI_ABORT_CB_ID = 0x04U, /*!< PSSI Abort callback ID */ + + HAL_PSSI_MSPINIT_CB_ID = 0x05U, /*!< PSSI Msp Init callback ID */ + HAL_PSSI_MSPDEINIT_CB_ID = 0x06U /*!< PSSI Msp DeInit callback ID */ + +} HAL_PSSI_CallbackIDTypeDef; +#endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup PSSI_Exported_Constants PSSI Exported Constants + * @{ + */ + +/** @defgroup PSSI_Error_Code PSSI Error Code + * @{ + */ +#define HAL_PSSI_ERROR_NONE 0x00000000U /*!< No error */ +#define HAL_PSSI_ERROR_NOT_SUPPORTED 0x00000001U /*!< Not supported operation */ +#define HAL_PSSI_ERROR_UNDER_RUN 0x00000002U /*!< FIFO Under-run error */ +#define HAL_PSSI_ERROR_OVER_RUN 0x00000004U /*!< FIFO Over-run error */ +#define HAL_PSSI_ERROR_DMA 0x00000008U /*!< Dma error */ +#define HAL_PSSI_ERROR_TIMEOUT 0x00000010U /*!< Timeout error */ +#if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1) +#define HAL_PSSI_ERROR_INVALID_CALLBACK 0x00000020U /*!< Invalid callback error */ +#endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup PSSI_DATA_WIDTH PSSI Data Width + * @{ + */ + +#define HAL_PSSI_8BITS 0x00000000U /*!< 8 Bits */ +#define HAL_PSSI_16BITS 0x00000001U /*!< 16 Bits */ +#define HAL_PSSI_32BITS 0x00000002U /*!< 32 Bits */ +/** + * @} + */ + +/** @defgroup PSSI_BUS_WIDTH PSSI Bus Width + * @{ + */ + +#define HAL_PSSI_8LINES 0x00000000U /*!< 8 data lines */ +#define HAL_PSSI_16LINES PSSI_CR_EDM /*!< 16 data lines */ +/** + * @} + */ +/** @defgroup PSSI_MODE PSSI mode + * @{ + */ +#define HAL_PSSI_UNIDIRECTIONAL 0x00000000U /*!< Uni-directional mode */ +#define HAL_PSSI_BIDIRECTIONAL 0x00000001U /*!< Bi-directional mode */ +/** + * @} + */ + +/** @defgroup ControlSignal_Configuration ControlSignal Configuration + * @{ + */ +#define HAL_PSSI_DE_RDY_DISABLE (0x0U << PSSI_CR_DERDYCFG_Pos) /*!< Neither DE nor RDY are enabled */ +#define HAL_PSSI_RDY_ENABLE (0x1U << PSSI_CR_DERDYCFG_Pos) /*!< Only RDY enabled */ +#define HAL_PSSI_DE_ENABLE (0x2U << PSSI_CR_DERDYCFG_Pos) /*!< Only DE enabled */ +#define HAL_PSSI_DE_RDY_ALT_ENABLE (0x3U << PSSI_CR_DERDYCFG_Pos) /*!< Both RDY and DE alternate functions enabled */ +#define HAL_PSSI_MAP_RDY_BIDIR_ENABLE (0x4U << PSSI_CR_DERDYCFG_Pos) /*!< Bi-directional on RDY pin */ +#define HAL_PSSI_RDY_MAP_ENABLE (0x5U << PSSI_CR_DERDYCFG_Pos) /*!< Only RDY enabled, mapped to DE pin */ +#define HAL_PSSI_DE_MAP_ENABLE (0x6U << PSSI_CR_DERDYCFG_Pos) /*!< Only DE enabled, mapped to RDY pin */ +#define HAL_PSSI_MAP_DE_BIDIR_ENABLE (0x7U << PSSI_CR_DERDYCFG_Pos) /*!< Bi-directional on DE pin */ + +/** + * @} + */ + + +/** @defgroup Data_Enable_Polarity Data Enable Polarity + * @{ + */ +#define HAL_PSSI_DEPOL_ACTIVE_LOW 0x0U /*!< Active Low */ +#define HAL_PSSI_DEPOL_ACTIVE_HIGH PSSI_CR_DEPOL /*!< Active High */ +/** + * @} + */ +/** @defgroup Reday_Polarity Reday Polarity + * @{ + */ +#define HAL_PSSI_RDYPOL_ACTIVE_LOW 0x0U /*!< Active Low */ +#define HAL_PSSI_RDYPOL_ACTIVE_HIGH PSSI_CR_RDYPOL /*!< Active High */ +/** + * @} + */ + +/** @defgroup Clock_Polarity Clock Polarity + * @{ + */ +#define HAL_PSSI_FALLING_EDGE 0x0U /*!< Fallling Edge */ +#define HAL_PSSI_RISING_EDGE 0x1U /*!< Rising Edge */ + + +/** + * @} + */ + + +/** @defgroup PSSI_DEFINITION PSSI definitions + * @{ + */ + +#define PSSI_MAX_NBYTE_SIZE 0x10000U /* 64 KB */ +#define PSSI_TIMEOUT_TRANSMIT 0x0000FFFFU /*!< Timeout Value */ + +#define PSSI_CR_OUTEN_INPUT 0x00000000U /*!< Input Mode */ +#define PSSI_CR_OUTEN_OUTPUT PSSI_CR_OUTEN /*!< Output Mode */ + +#define PSSI_CR_DMA_ENABLE PSSI_CR_DMAEN /*!< DMA Mode Enable */ +#define PSSI_CR_DMA_DISABLE (~PSSI_CR_DMAEN) /*!< DMA Mode Disable*/ + +#define PSSI_CR_16BITS PSSI_CR_EDM /*!< 16 Lines Mode */ +#define PSSI_CR_8BITS (~PSSI_CR_EDM) /*!< 8 Lines Mode */ + +#define PSSI_FLAG_RTT1B PSSI_SR_RTT1B /*!< 1 Byte Fifo Flag */ +#define PSSI_FLAG_RTT4B PSSI_SR_RTT4B /*!< 4 Bytes Fifo Flag*/ + + + +/** + * @} + */ + +/** @defgroup PSSI_Interrupts PSSI Interrupts + * @{ + */ + +#define PSSI_FLAG_OVR_RIS PSSI_RIS_OVR_RIS /*!< Overrun, Underrun errors flag */ +#define PSSI_FLAG_MASK PSSI_RIS_OVR_RIS_Msk /*!< Overrun, Underrun errors Mask */ +#define PSSI_FLAG_OVR_MIS PSSI_MIS_OVR_MIS /*!< Overrun, Underrun masked errors flag */ +/** + * @} + */ + + + +/** + * @} + */ +/* Exported macros ------------------------------------------------------------*/ +/** @defgroup PSSI_Exported_Macros PSSI Exported Macros + * @{ + */ + +/** @brief Reset PSSI handle state + * @param __HANDLE__ specifies the PSSI handle. + * @retval None + */ +#if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1) +#define HAL_PSSI_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->State = HAL_PSSI_STATE_RESET;\ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + }while(0) +#else +#define HAL_PSSI_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_PSSI_STATE_RESET) +#endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */ + + +/** + * @brief Enable the PSSI. + * @param __HANDLE__ PSSI handle + * @retval None. + */ +#define HAL_PSSI_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= PSSI_CR_ENABLE) +/** + * @brief Disable the PSSI. + * @param __HANDLE__ PSSI handle + * @retval None. + */ +#define HAL_PSSI_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR &= (~PSSI_CR_ENABLE)) + +/* PSSI pripheral STATUS */ +/** + * @brief Get the PSSI pending flags. + * @param __HANDLE__ PSSI handle + * @param __FLAG__ flag to check. + * This parameter can be any combination of the following values: + * @arg PSSI_FLAG_RTT1B: FIFO is ready to transfer one byte + * @arg PSSI_FLAG_RTT4B: FIFO is ready to transfer four bytes + * @retval The state of FLAG. + */ + +#define HAL_PSSI_GET_STATUS(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR & (__FLAG__)) + + + +/* Interrupt & Flag management */ +/** + * @brief Get the PSSI pending flags. + * @param __HANDLE__ PSSI handle + * @param __FLAG__ flag to check. + * This parameter can be any combination of the following values: + * @arg PSSI_FLAG_OVR_RIS: Data Buffer overrun/underrun error flag + * @retval The state of FLAG. + */ +#define HAL_PSSI_GET_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->RIS & (__FLAG__)) + +/** + * @brief Clear the PSSI pending flags. + * @param __HANDLE__ PSSI handle + * @param __FLAG__ specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg PSSI_FLAG_OVR_RIS: Data Buffer overrun/underrun error flag + * @retval None + */ +#define HAL_PSSI_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ICR = (__FLAG__)) + +/** + * @brief Enable the specified PSSI interrupts. + * @param __HANDLE__ PSSI handle + * @param __INTERRUPT__ specifies the PSSI interrupt sources to be enabled. + * This parameter can be any combination of the following values: + * @arg PSSI_FLAG_OVR_RIS: Configuration error mask + * @retval None + */ +#define HAL_PSSI_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IER |= (__INTERRUPT__)) + +/** + * @brief Disable the specified PSSI interrupts. + * @param __HANDLE__ PSSI handle + * @param __INTERRUPT__ specifies the PSSI interrupt sources to be disabled. + * This parameter can be any combination of the following values: + * @arg PSSI_IT_OVR_IE: Configuration error mask + * @retval None + */ +#define HAL_PSSI_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IER &= ~(__INTERRUPT__)) + +/** + * @brief Check whether the specified PSSI interrupt source is enabled or not. + * @param __HANDLE__ PSSI handle + * @param __INTERRUPT__ specifies the PSSI interrupt source to check. + * This parameter can be one of the following values: + * @arg PSSI_IT_OVR_IE: Data Buffer overrun/underrun error interrupt mask + * @retval The state of INTERRUPT source. + */ +#define HAL_PSSI_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IER & (__INTERRUPT__)) + + +/** + * @brief Check whether the PSSI Control signal is valid. + * @param __CONTROL__ Control signals configuration + * @retval Valid or not. + */ + +#define IS_PSSI_CONTROL_SIGNAL(__CONTROL__) (((__CONTROL__) == HAL_PSSI_DE_RDY_DISABLE ) || \ + ((__CONTROL__) == HAL_PSSI_RDY_ENABLE ) || \ + ((__CONTROL__) == HAL_PSSI_DE_ENABLE ) || \ + ((__CONTROL__) == HAL_PSSI_DE_RDY_ALT_ENABLE ) || \ + ((__CONTROL__) == HAL_PSSI_MAP_RDY_BIDIR_ENABLE ) || \ + ((__CONTROL__) == HAL_PSSI_RDY_MAP_ENABLE ) || \ + ((__CONTROL__) == HAL_PSSI_DE_MAP_ENABLE ) || \ + ((__CONTROL__) == HAL_PSSI_MAP_DE_BIDIR_ENABLE )) + + + +/** + * @brief Check whether the PSSI Bus Width is valid. + * @param __BUSWIDTH__ PSSI Bush width + * @retval Valid or not. + */ + +#define IS_PSSI_BUSWIDTH(__BUSWIDTH__) (((__BUSWIDTH__) == HAL_PSSI_8LINES ) || \ + ((__BUSWIDTH__) == HAL_PSSI_16LINES )) + +/** + + * @brief Check whether the PSSI Clock Polarity is valid. + * @param __CLOCKPOL__ PSSI Clock Polarity + * @retval Valid or not. + */ + +#define IS_PSSI_CLOCK_POLARITY(__CLOCKPOL__) (((__CLOCKPOL__) == HAL_PSSI_FALLING_EDGE ) || \ + ((__CLOCKPOL__) == HAL_PSSI_RISING_EDGE )) + + +/** + * @brief Check whether the PSSI Data Enable Polarity is valid. + * @param __DEPOL__ PSSI DE Polarity + * @retval Valid or not. + */ + +#define IS_PSSI_DE_POLARITY(__DEPOL__) (((__DEPOL__) == HAL_PSSI_DEPOL_ACTIVE_LOW ) || \ + ((__DEPOL__) == HAL_PSSI_DEPOL_ACTIVE_HIGH )) + +/** + * @brief Check whether the PSSI Ready Polarity is valid. + * @param __RDYPOL__ PSSI RDY Polarity + * @retval Valid or not. + */ + +#define IS_PSSI_RDY_POLARITY(__RDYPOL__) (((__RDYPOL__) == HAL_PSSI_RDYPOL_ACTIVE_LOW ) || \ + ((__RDYPOL__) == HAL_PSSI_RDYPOL_ACTIVE_HIGH )) +/** + * @} + */ + + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup PSSI_Exported_Functions PSSI Exported Functions + * @{ + */ + +/** @addtogroup PSSI_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ + +/* Initialization and de-initialization functions *******************************/ +HAL_StatusTypeDef HAL_PSSI_Init(PSSI_HandleTypeDef *hpssi); +HAL_StatusTypeDef HAL_PSSI_DeInit(PSSI_HandleTypeDef *hpssi); +void HAL_PSSI_MspInit(PSSI_HandleTypeDef *hpssi); +void HAL_PSSI_MspDeInit(PSSI_HandleTypeDef *hpssi); +/* Callbacks Register/UnRegister functions ***********************************/ +#if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1) +HAL_StatusTypeDef HAL_PSSI_RegisterCallback(PSSI_HandleTypeDef *hpssi, HAL_PSSI_CallbackIDTypeDef CallbackID, + pPSSI_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_PSSI_UnRegisterCallback(PSSI_HandleTypeDef *hpssi, HAL_PSSI_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */ + +/** + * @} + */ + + +/** @addtogroup PSSI_Exported_Functions_Group2 Input and Output operation functions + * @{ + */ + +/* IO operation functions *******************************************************/ +HAL_StatusTypeDef HAL_PSSI_Transmit(PSSI_HandleTypeDef *hpssi, uint8_t *pData, uint32_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_PSSI_Receive(PSSI_HandleTypeDef *hpssi, uint8_t *pData, uint32_t Size, uint32_t Timeout); +#if defined(HAL_DMA_MODULE_ENABLED) +HAL_StatusTypeDef HAL_PSSI_Transmit_DMA(PSSI_HandleTypeDef *hpssi, uint32_t *pData, uint32_t Size); +HAL_StatusTypeDef HAL_PSSI_Receive_DMA(PSSI_HandleTypeDef *hpssi, uint32_t *pData, uint32_t Size); +HAL_StatusTypeDef HAL_PSSI_Abort_DMA(PSSI_HandleTypeDef *hpssi); +#endif /*HAL_DMA_MODULE_ENABLED*/ + +/** + * @} + */ + +/** @addtogroup PSSI_Exported_Functions_Group3 Peripheral State and Error functions + * @{ + */ + +/* Peripheral State functions ***************************************************/ +HAL_PSSI_StateTypeDef HAL_PSSI_GetState(const PSSI_HandleTypeDef *hpssi); +uint32_t HAL_PSSI_GetError(const PSSI_HandleTypeDef *hpssi); + +/** + * @} + */ + +/** @addtogroup PSSI_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @{ + */ + +void HAL_PSSI_IRQHandler(PSSI_HandleTypeDef *hpssi); +void HAL_PSSI_TxCpltCallback(PSSI_HandleTypeDef *hpssi); +void HAL_PSSI_RxCpltCallback(PSSI_HandleTypeDef *hpssi); +void HAL_PSSI_ErrorCallback(PSSI_HandleTypeDef *hpssi); +void HAL_PSSI_AbortCpltCallback(PSSI_HandleTypeDef *hpssi); + +/** + * @} + */ + + + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ + + +/* Private macros ------------------------------------------------------------*/ + + +/** + * @} + */ +#endif /* PSSI */ + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_PSSI_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_pwr.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_pwr.h new file mode 100644 index 0000000000..fb47704993 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_pwr.h @@ -0,0 +1,695 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_pwr.h + * @author MCD Application Team + * @brief Header file of PWR HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_PWR_H +#define STM32H5xx_HAL_PWR_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup PWR + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup PWR_Exported_Types PWR Exported Types + * @{ + */ + +/** + * @brief PWR PVD configuration structure definition + */ +typedef struct +{ + uint32_t PVDLevel; /*!< Specifies the PVD detection level. + This parameter can be a value of + @ref PWR_PVD_Detection_Level. */ + + uint32_t Mode; /*!< Specifies the operating mode for the selected pins. + This parameter can be a value of @ref PWR_PVD_Mode. */ +} PWR_PVDTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup PWR_Exported_Constants PWR Exported Constants + * @{ + */ + +/** @defgroup PWR_PVD_Detection_Level Programmable Voltage Detection Level + * @{ + */ +#define PWR_PVDLEVEL_0 0x00000000UL /*!< PVD threshold around 1.95 V */ +#define PWR_PVDLEVEL_1 (PWR_VMCR_PLS_0) /*!< PVD threshold around 2.1 V */ +#define PWR_PVDLEVEL_2 (PWR_VMCR_PLS_1) /*!< PVD threshold around 2.25 V */ +#define PWR_PVDLEVEL_3 (PWR_VMCR_PLS_0 | PWR_VMCR_PLS_1) /*!< PVD threshold around 2.4 V */ +#define PWR_PVDLEVEL_4 (PWR_VMCR_PLS_2) /*!< PVD threshold around 2.55 V */ +#define PWR_PVDLEVEL_5 (PWR_VMCR_PLS_0 | PWR_VMCR_PLS_2) /*!< PVD threshold around 2.7 V */ +#define PWR_PVDLEVEL_6 (PWR_VMCR_PLS_1 | PWR_VMCR_PLS_2) /*!< PVD threshold around 2.85 V */ +#define PWR_PVDLEVEL_7 (PWR_VMCR_PLS) /*!< External input analog voltage + (compared internally to VREFINT) */ +/** + * @} + */ + +/** @defgroup PWR_PVD_Mode PWR PVD Mode + * @{ + */ +#define PWR_PVD_MODE_NORMAL (0x00U) /*!< Basic Mode is used */ +#define PWR_PVD_MODE_IT_RISING (0x05U) /*!< External Interrupt Mode with Rising edge trigger detection */ +#define PWR_PVD_MODE_IT_FALLING (0x06U) /*!< External Interrupt Mode with Falling + edge trigger detection */ +#define PWR_PVD_MODE_IT_RISING_FALLING (0x07U) /*!< External Interrupt Mode with Rising/Falling + edge trigger detection */ +#define PWR_PVD_MODE_EVENT_RISING (0x09U) /*!< Event Mode with Rising edge trigger detection */ +#define PWR_PVD_MODE_EVENT_FALLING (0x0AU) /*!< Event Mode with Falling edge trigger detection */ +#define PWR_PVD_MODE_EVENT_RISING_FALLING (0x0BU) /*!< Event Mode with Rising/Falling edge trigger detection */ +/** + * @} + */ + +/** @defgroup PWR_Regulator_In_LowPower_Mode PWR Regulator State in SLEEP/STOP Mode + * @{ + */ +#define PWR_MAINREGULATOR_ON (0x00U) /*!< Main Regulator ON in Run Mode */ +#define PWR_LOWPOWERREGULATOR_ON (0x00U) /*!< Main Regulator ON in Low Power Mode */ +/** + * @} + */ + +/** @defgroup PWR_SLEEP_Mode_Entry PWR SLEEP Mode Entry + * @{ + */ +#define PWR_SLEEPENTRY_WFI (0x01U) /*!< Wait For Interruption instruction to enter Sleep mode */ +#define PWR_SLEEPENTRY_WFE (0x02U) /*!< Wait For Event instruction to enter Sleep mode */ +/** + * @} + */ + +/** @defgroup PWR_STOP_Mode_Entry PWR STOP Mode Entry + * @{ + */ +#define PWR_STOPENTRY_WFI (0x01U) /*!< Wait For Interruption instruction to enter Stop mode */ +#define PWR_STOPENTRY_WFE (0x02U) /*!< Wait For Event instruction to enter Stop mode */ +/** + * @} + */ + +/** @defgroup PWR_Flags PWR Flags + * @{ + */ +#define PWR_FLAG_STOPF (0x01U) /*!< STOP flag */ +#define PWR_FLAG_SBF (0x02U) /*!< STANDBY flag */ +#define PWR_FLAG_VOSRDY (0x03U) /*!< Voltage scaling ready flag */ +#define PWR_FLAG_ACTVOSRDY (0x04U) /*!< Currently applied VOS ready flag */ +#define PWR_FLAG_BRR (0x05U) /*!< Backup regulator ready flag */ +#define PWR_FLAG_VBATL (0x06U) /*!< Backup domain voltage level flag (versus low threshold) */ +#define PWR_FLAG_VBATH (0x07U) /*!< Backup domain voltage level flag (versus high threshold) */ +#define PWR_FLAG_TEMPL (0x08U) /*!< Temperature level flag (versus low threshold) */ +#define PWR_FLAG_TEMPH (0x09U) /*!< Temperature level flag (versus high threshold) */ +#define PWR_FLAG_AVDO (0x0AU) /*!< VDDA voltage detector output flag */ +#define PWR_FLAG_VDDIO2RDY (0x0BU) /*!< VDDIO2 voltage detector output flag */ +#define PWR_FLAG_PVDO (0x0CU) /*!< VDD voltage detector output flag */ +#define PWR_FLAG_USB33RDY (0x0DU) /*!< VDDUSB33 ready flag */ + +#define PWR_WAKEUP_FLAG1 (0x10U) /*!< Wake up line 1 flag */ +#define PWR_WAKEUP_FLAG2 (0x20U) /*!< Wake up line 2 flag */ +#define PWR_WAKEUP_FLAG3 (0x30U) /*!< Wake up line 3 flag */ +#define PWR_WAKEUP_FLAG4 (0x40U) /*!< Wake up line 4 flag */ +#define PWR_WAKEUP_FLAG5 (0x50U) /*!< Wake up line 5 flag */ +#define PWR_WAKEUP_FLAG6 (0x60U) /*!< Wake up line 6 flag */ +#define PWR_WAKEUP_FLAG7 (0x70U) /*!< Wake up line 7 flag */ +#define PWR_WAKEUP_FLAG8 (0x80U) /*!< Wake up line 8 flag */ +#define PWR_WAKEUP_ALL_FLAG (0x90U) /*!< Wakeup flag all */ + +/** + * @} + */ + +/** @defgroup PWREx_WakeUp_Pins PWREx Wake-Up Pins + * @{ + */ +/* High level and No pull (default configuration) */ +#define PWR_WAKEUP_PIN1 PWR_WUCR_WUPEN1 +#define PWR_WAKEUP_PIN2 PWR_WUCR_WUPEN2 +#define PWR_WAKEUP_PIN3 PWR_WUCR_WUPEN3 +#define PWR_WAKEUP_PIN4 PWR_WUCR_WUPEN4 +#define PWR_WAKEUP_PIN5 PWR_WUCR_WUPEN5 +#if defined (PWR_WUCR_WUPEN6) +#define PWR_WAKEUP_PIN6 PWR_WUCR_WUPEN6 +#define PWR_WAKEUP_PIN7 PWR_WUCR_WUPEN7 +#define PWR_WAKEUP_PIN8 PWR_WUCR_WUPEN8 +#endif /* PWR_WUCR_WUPEN6 */ + +/* High level and No pull */ +#define PWR_WAKEUP_PIN1_HIGH PWR_WUCR_WUPEN1 +#define PWR_WAKEUP_PIN2_HIGH PWR_WUCR_WUPEN2 +#define PWR_WAKEUP_PIN3_HIGH PWR_WUCR_WUPEN3 +#define PWR_WAKEUP_PIN4_HIGH PWR_WUCR_WUPEN4 +#define PWR_WAKEUP_PIN5_HIGH PWR_WUCR_WUPEN5 +#if defined (PWR_WUCR_WUPEN6) +#define PWR_WAKEUP_PIN6_HIGH PWR_WUCR_WUPEN6 +#define PWR_WAKEUP_PIN7_HIGH PWR_WUCR_WUPEN7 +#define PWR_WAKEUP_PIN8_HIGH PWR_WUCR_WUPEN8 +#endif /* PWR_WUCR_WUPEN6 */ + +/* Low level and No pull */ +#define PWR_WAKEUP_PIN1_LOW (PWR_WUCR_WUPP1 | PWR_WUCR_WUPEN1) +#define PWR_WAKEUP_PIN2_LOW (PWR_WUCR_WUPP2 | PWR_WUCR_WUPEN2) +#define PWR_WAKEUP_PIN3_LOW (PWR_WUCR_WUPP3 | PWR_WUCR_WUPEN3) +#define PWR_WAKEUP_PIN4_LOW (PWR_WUCR_WUPP4 | PWR_WUCR_WUPEN4) +#define PWR_WAKEUP_PIN5_LOW (PWR_WUCR_WUPP5 | PWR_WUCR_WUPEN5) +#if defined (PWR_WUCR_WUPEN6) +#define PWR_WAKEUP_PIN6_LOW (PWR_WUCR_WUPP6 | PWR_WUCR_WUPEN6) +#define PWR_WAKEUP_PIN7_LOW (PWR_WUCR_WUPP7 | PWR_WUCR_WUPEN7) +#define PWR_WAKEUP_PIN8_LOW (PWR_WUCR_WUPP8 | PWR_WUCR_WUPEN8) +#endif /* PWR_WUCR_WUPEN6 */ + +/** + * @} + */ + +/** @defgroup PWR_Items PWR Items + * @{ + */ +#if defined(PWR_SECCFGR_WUP1SEC) +#define PWR_WKUP1 (PWR_SECCFGR_WUP1SEC) /*!< WUP1 secure protection */ +#define PWR_WKUP2 (PWR_SECCFGR_WUP2SEC) /*!< WUP2 secure protection */ +#define PWR_WKUP3 (PWR_SECCFGR_WUP3SEC) /*!< WUP3 secure protection */ +#define PWR_WKUP4 (PWR_SECCFGR_WUP4SEC) /*!< WUP4 secure protection */ +#define PWR_WKUP5 (PWR_SECCFGR_WUP5SEC) /*!< WUP5 secure protection */ +#define PWR_WKUP6 (PWR_SECCFGR_WUP6SEC) /*!< WUP6 secure protection */ +#define PWR_WKUP7 (PWR_SECCFGR_WUP7SEC) /*!< WUP7 secure protection */ +#define PWR_WKUP8 (PWR_SECCFGR_WUP8SEC) /*!< WUP8 secure protection */ +#define PWR_RET (PWR_SECCFGR_RETSEC) /*!< IO Retention secure protection */ +#define PWR_LPM (PWR_SECCFGR_LPMSEC) /*!< Low power modes secure protection */ +#define PWR_SCM (PWR_SECCFGR_SCMSEC) /*!< Voltage detection and monitoring secure protection */ +#define PWR_VB (PWR_SECCFGR_VBSEC) /*!< Backup domain secure protection */ +#define PWR_VUSB (PWR_SECCFGR_VUSBSEC) /*!< Voltage USB secure protection */ +#define PWR_ALL (PWR_WKUP1 | PWR_WKUP2 | PWR_WKUP3 | PWR_WKUP4 | \ + PWR_WKUP5 | PWR_WKUP6 | PWR_WKUP7 | PWR_WKUP8 | \ + PWR_LPM | PWR_SCM | PWR_VB | PWR_VUSB | \ + PWR_RET) +#else +#define PWR_ALL 0xFF /*!< Dummy Value */ +#endif /* PWR_SECCFGR_WUP1SEC */ + +/** + * @} + */ + +/** @defgroup PWR_Attributes PWR Attributes + * @brief PWR Privilege/NPrivilege and Secure/NSecure Attributes + * @{ + */ +#if defined(PWR_PRIVCFGR_NSPRIV) +#define PWR_NSEC_PRIV (PWR_ITEM_ATTR_NSEC_PRIV_MASK | 0x01U) /*!< NSecure and Privileged attribute */ +#define PWR_NSEC_NPRIV (PWR_ITEM_ATTR_NSEC_PRIV_MASK) /*!< NSecure and NPrivileged attribute */ +#else +#define PWR_PRIV (PWR_ITEM_ATTR_NSEC_PRIV_MASK | 0x01U) /*!< Privileged attribute */ +#define PWR_NPRIV (PWR_ITEM_ATTR_NSEC_PRIV_MASK) /*!< NPrivileged attribute */ +#endif /* PWR_PRIVCFGR_NSPRIV */ +#define PWR_SEC_PRIV (PWR_ITEM_ATTR_SEC_PRIV_MASK | 0x02U) /*!< Secure and Privileged attribute */ +#define PWR_SEC_NPRIV (PWR_ITEM_ATTR_SEC_PRIV_MASK) /*!< Secure and NPrivileged attribute */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ + +/** @defgroup PWR_Exported_Macros PWR Exported Macros + * @{ + */ + +/** @brief Check PWR flags are set or not. + * @param __FLAG__ : Specifies the flag to check. + * This parameter can be one of the following values : + * @arg @ref PWR_FLAG_STOPF : Stop flag. + * Indicates that the device was resumed from Stop mode. + * @arg @ref PWR_FLAG_SBF : Standby flag. + * Indicates that the device was resumed from Standby mode. + * @arg @ref PWR_FLAG_VOSRDY : Voltage scaling ready flag. + * Indicates that the Vcore level at or above VOS selected level. + * @arg @ref PWR_FLAG_ACTVOSRDY : Currently applied VOS ready flag. + * Indicates that Vcore is equal to the current + * voltage scaling provided by ACTVOS. + * @arg @ref PWR_FLAG_BRR : Backup regulator ready flag. This bit is not + * reset when the device wakes up from STANDBY + * mode or by a system reset or power-on reset. + * @arg @ref PWR_FLAG_VBATL : Backup domain voltage level flag (versus low threshold). + * Indicates the backup domain voltage + * level is equal or above low threshold. + * @arg @ref PWR_FLAG_VBATH : Backup domain voltage level flag (versus high threshold). + * Indicates the backup domain voltage + * level is equal or above high threshold. + * @arg @ref PWR_FLAG_TEMPL : Temperature level flag (versus low threshold). + * Indicates the temperature is equal or above low threshold. + * @arg @ref PWR_FLAG_TEMPH : Temperature level flag (versus high threshold). + * Indicates the temperature is equal or above high threshold. + * @arg @ref PWR_FLAG_AVDO : Regulator selection flag. + * Indicates the regulator selected. + * @arg @ref PWR_FLAG_VDDIO2RDY : VDDIO2 ready flag (versus 0.9 V threshold). + * Indicates that VDDIO2 is equal or above the threshold + * of the VDDIO2 voltage monitor (around 0.9 V). + * @arg @ref PWR_FLAG_PVDO : Voltage detector output flag. + * Indicates that Vdd is equal or above + * the PVD threshold selected by PVDLS. + * @arg @ref PWR_FLAG_USB33RDY : VDDUSB ready flag (versus 1.2 V threshold). + * Indicates that VDDUSB is equal or above the threshold + * of the VDDUSB voltage monitor (around 1.2 V). + * @arg @ref PWR_WAKEUP_FLAG1 : Wakeup flag 1. + * Indicates that a wakeup event was received from the WKUP line 1. + * @arg @ref PWR_WAKEUP_FLAG2 : Wakeup flag 2. + * Indicates that a wakeup event was received from the WKUP line 2. + * @arg @ref PWR_WAKEUP_FLAG3 : Wakeup flag 3. + * Indicates that a wakeup event was received from the WKUP line 3. + * @arg @ref PWR_WAKEUP_FLAG4 : Wakeup flag 4. + * Indicates that a wakeup event was received from the WKUP line 4. + * @arg @ref PWR_WAKEUP_FLAG5 : Wakeup flag 5. + * Indicates that a wakeup event was received from the WKUP line 5. + * @arg @ref PWR_WAKEUP_FLAG6 : Wakeup flag 6. + * Indicates that a wakeup event was received from the WKUP line 6. + * @arg @ref PWR_WAKEUP_FLAG7 : Wakeup flag 7. + * Indicates that a wakeup event was received from the WKUP line 7. + * @arg @ref PWR_WAKEUP_FLAG8 : Wakeup flag 8. + * Indicates that a wakeup event was received from the WKUP line 8. + * @note The PWR_WAKEUP_FLAG6, PWR_WAKEUP_FLAG7 AND PWR_WAKEUP_FLAG8 are not available for STM32H503xx devices. + * @retval The state of __FLAG__ (TRUE or FALSE). + */ +#if defined (PWR_WUSR_WUF6) +#define __HAL_PWR_GET_FLAG(__FLAG__) \ + (((__FLAG__) == PWR_FLAG_STOPF) ? (READ_BIT(PWR->PMSR, PWR_PMSR_STOPF) == PWR_PMSR_STOPF) : \ + ((__FLAG__) == PWR_FLAG_SBF) ? (READ_BIT(PWR->PMSR, PWR_PMSR_SBF) == PWR_PMSR_SBF) : \ + ((__FLAG__) == PWR_FLAG_VOSRDY) ? (READ_BIT(PWR->VOSSR, PWR_VOSSR_VOSRDY) == PWR_VOSSR_VOSRDY) : \ + ((__FLAG__) == PWR_FLAG_ACTVOSRDY) ? (READ_BIT(PWR->VOSSR, PWR_VOSSR_ACTVOSRDY) == PWR_VOSSR_ACTVOSRDY) : \ + ((__FLAG__) == PWR_FLAG_BRR) ? (READ_BIT(PWR->BDSR, PWR_BDSR_BRRDY) == PWR_BDSR_BRRDY) : \ + ((__FLAG__) == PWR_FLAG_VBATL) ? (READ_BIT(PWR->BDSR, PWR_BDSR_VBATL) == PWR_BDSR_VBATL) : \ + ((__FLAG__) == PWR_FLAG_VBATH) ? (READ_BIT(PWR->BDSR, PWR_BDSR_VBATH) == PWR_BDSR_VBATH) : \ + ((__FLAG__) == PWR_FLAG_TEMPL) ? (READ_BIT(PWR->BDSR, PWR_BDSR_TEMPL) == PWR_BDSR_TEMPL) : \ + ((__FLAG__) == PWR_FLAG_TEMPH) ? (READ_BIT(PWR->BDSR, PWR_BDSR_TEMPH) == PWR_BDSR_TEMPH) : \ + ((__FLAG__) == PWR_FLAG_AVDO) ? (READ_BIT(PWR->VMSR, PWR_VMSR_AVDO) == PWR_VMSR_AVDO) : \ + ((__FLAG__) == PWR_FLAG_VDDIO2RDY) ? (READ_BIT(PWR->VMSR, PWR_VMSR_VDDIO2RDY) == PWR_VMSR_VDDIO2RDY) : \ + ((__FLAG__) == PWR_FLAG_PVDO) ? (READ_BIT(PWR->VMSR, PWR_VMSR_PVDO) == PWR_VMSR_PVDO) : \ + ((__FLAG__) == PWR_FLAG_USB33RDY) ? (READ_BIT(PWR->VMSR, PWR_VMSR_USB33RDY) == PWR_VMSR_USB33RDY) : \ + ((__FLAG__) == PWR_WAKEUP_FLAG1) ? (READ_BIT(PWR->WUSR, PWR_WUSR_WUF1) == PWR_WUSR_WUF1) : \ + ((__FLAG__) == PWR_WAKEUP_FLAG2) ? (READ_BIT(PWR->WUSR, PWR_WUSR_WUF2) == PWR_WUSR_WUF2) : \ + ((__FLAG__) == PWR_WAKEUP_FLAG3) ? (READ_BIT(PWR->WUSR, PWR_WUSR_WUF3) == PWR_WUSR_WUF3) : \ + ((__FLAG__) == PWR_WAKEUP_FLAG4) ? (READ_BIT(PWR->WUSR, PWR_WUSR_WUF4) == PWR_WUSR_WUF4) : \ + ((__FLAG__) == PWR_WAKEUP_FLAG5) ? (READ_BIT(PWR->WUSR, PWR_WUSR_WUF5) == PWR_WUSR_WUF5) : \ + ((__FLAG__) == PWR_WAKEUP_FLAG6) ? (READ_BIT(PWR->WUSR, PWR_WUSR_WUF6) == PWR_WUSR_WUF6) : \ + ((__FLAG__) == PWR_WAKEUP_FLAG7) ? (READ_BIT(PWR->WUSR, PWR_WUSR_WUF7) == PWR_WUSR_WUF7) : \ + (READ_BIT(PWR->WUSR, PWR_WUSR_WUF8) == PWR_WUSR_WUF8)) +#else +#define __HAL_PWR_GET_FLAG(__FLAG__) \ + (((__FLAG__) == PWR_FLAG_STOPF) ? (READ_BIT(PWR->PMSR, PWR_PMSR_STOPF) == PWR_PMSR_STOPF) : \ + ((__FLAG__) == PWR_FLAG_SBF) ? (READ_BIT(PWR->PMSR, PWR_PMSR_SBF) == PWR_PMSR_SBF) : \ + ((__FLAG__) == PWR_FLAG_VOSRDY) ? (READ_BIT(PWR->VOSSR, PWR_VOSSR_VOSRDY) == PWR_VOSSR_VOSRDY) : \ + ((__FLAG__) == PWR_FLAG_ACTVOSRDY) ? (READ_BIT(PWR->VOSSR, PWR_VOSSR_ACTVOSRDY) == PWR_VOSSR_ACTVOSRDY) : \ + ((__FLAG__) == PWR_FLAG_BRR) ? (READ_BIT(PWR->BDSR, PWR_BDSR_BRRDY) == PWR_BDSR_BRRDY) : \ + ((__FLAG__) == PWR_FLAG_VBATL) ? (READ_BIT(PWR->BDSR, PWR_BDSR_VBATL) == PWR_BDSR_VBATL) : \ + ((__FLAG__) == PWR_FLAG_VBATH) ? (READ_BIT(PWR->BDSR, PWR_BDSR_VBATH) == PWR_BDSR_VBATH) : \ + ((__FLAG__) == PWR_FLAG_TEMPL) ? (READ_BIT(PWR->BDSR, PWR_BDSR_TEMPL) == PWR_BDSR_TEMPL) : \ + ((__FLAG__) == PWR_FLAG_TEMPH) ? (READ_BIT(PWR->BDSR, PWR_BDSR_TEMPH) == PWR_BDSR_TEMPH) : \ + ((__FLAG__) == PWR_FLAG_AVDO) ? (READ_BIT(PWR->VMSR, PWR_VMSR_AVDO) == PWR_VMSR_AVDO) : \ + ((__FLAG__) == PWR_FLAG_VDDIO2RDY) ? (READ_BIT(PWR->VMSR, PWR_VMSR_VDDIO2RDY) == PWR_VMSR_VDDIO2RDY) : \ + ((__FLAG__) == PWR_FLAG_PVDO) ? (READ_BIT(PWR->VMSR, PWR_VMSR_PVDO) == PWR_VMSR_PVDO) : \ + ((__FLAG__) == PWR_WAKEUP_FLAG1) ? (READ_BIT(PWR->WUSR, PWR_WUSR_WUF1) == PWR_WUSR_WUF1) : \ + ((__FLAG__) == PWR_WAKEUP_FLAG2) ? (READ_BIT(PWR->WUSR, PWR_WUSR_WUF2) == PWR_WUSR_WUF2) : \ + ((__FLAG__) == PWR_WAKEUP_FLAG3) ? (READ_BIT(PWR->WUSR, PWR_WUSR_WUF3) == PWR_WUSR_WUF3) : \ + ((__FLAG__) == PWR_WAKEUP_FLAG4) ? (READ_BIT(PWR->WUSR, PWR_WUSR_WUF4) == PWR_WUSR_WUF4) : \ + (READ_BIT(PWR->WUSR, PWR_WUSR_WUF5) == PWR_WUSR_WUF5)) +#endif /* PWR_WUSR_WUF6 */ + +/** @brief Clear PWR flags. + * @param __FLAG__ : Specifies the flag to clear. + * This parameter can be one of the following values : + * @arg @ref PWR_FLAG_STOPF : STOP flag. + * Indicates that the device was resumed from STOP mode. + * @arg @ref PWR_FLAG_SBF : STANDBY flag. + * Indicates that the device was resumed from STANDBY mode. + * @arg @ref PWR_WAKEUP_FLAG1 : Wakeup flag 1. + * Indicates that a wakeup event was received from the WKUP line 1. + * @arg @ref PWR_WAKEUP_FLAG2 : Wakeup flag 2. + * Indicates that a wakeup event was received from the WKUP line 2. + * @arg @ref PWR_WAKEUP_FLAG3 : Wakeup flag 3. + * Indicates that a wakeup event was received from the WKUP line 3. + * @arg @ref PWR_WAKEUP_FLAG4 : Wakeup flag 4. + * Indicates that a wakeup event was received from the WKUP line 4. + * @arg @ref PWR_WAKEUP_FLAG5 : Wakeup flag 5. + * Indicates that a wakeup event was received from the WKUP line 5. + * @arg @ref PWR_WAKEUP_FLAG6 : Wakeup flag 6. + * Indicates that a wakeup event was received from the WKUP line 6. + * @arg @ref PWR_WAKEUP_FLAG7 : Wakeup flag 7. + * Indicates that a wakeup event was received from the WKUP line 7. + * @arg @ref PWR_WAKEUP_FLAG8 : Wakeup flag 8. + * Indicates that a wakeup event was received from the WKUP line 8. + * @note The PWR_WAKEUP_FLAG6, PWR_WAKEUP_FLAG7 AND PWR_WAKEUP_FLAG8 are not available for STM32H503xx devices. + * @retval None. + */ +#if defined (PWR_WUSCR_CWUF6) +#define __HAL_PWR_CLEAR_FLAG(__FLAG__) \ + (((__FLAG__) == PWR_FLAG_STOPF) ? (SET_BIT(PWR->PMCR, PWR_PMCR_CSSF)) : \ + ((__FLAG__) == PWR_FLAG_SBF) ? (SET_BIT(PWR->PMCR, PWR_PMCR_CSSF)) : \ + ((__FLAG__) == PWR_WAKEUP_FLAG1) ? (SET_BIT(PWR->WUSCR, PWR_WUSCR_CWUF1)) : \ + ((__FLAG__) == PWR_WAKEUP_FLAG2) ? (SET_BIT(PWR->WUSCR, PWR_WUSCR_CWUF2)) : \ + ((__FLAG__) == PWR_WAKEUP_FLAG3) ? (SET_BIT(PWR->WUSCR, PWR_WUSCR_CWUF3)) : \ + ((__FLAG__) == PWR_WAKEUP_FLAG4) ? (SET_BIT(PWR->WUSCR, PWR_WUSCR_CWUF4)) : \ + ((__FLAG__) == PWR_WAKEUP_FLAG5) ? (SET_BIT(PWR->WUSCR, PWR_WUSCR_CWUF5)) : \ + ((__FLAG__) == PWR_WAKEUP_FLAG6) ? (SET_BIT(PWR->WUSCR, PWR_WUSCR_CWUF6)) : \ + ((__FLAG__) == PWR_WAKEUP_FLAG7) ? (SET_BIT(PWR->WUSCR, PWR_WUSCR_CWUF7)) : \ + ((__FLAG__) == PWR_WAKEUP_FLAG8) ? (SET_BIT(PWR->WUSCR, PWR_WUSCR_CWUF8)) : \ + (SET_BIT(PWR->WUSCR, PWR_WUSCR_CWUF))) +#else +#define __HAL_PWR_CLEAR_FLAG(__FLAG__) \ + (((__FLAG__) == PWR_FLAG_STOPF) ? (SET_BIT(PWR->PMCR, PWR_PMCR_CSSF)) : \ + ((__FLAG__) == PWR_FLAG_SBF) ? (SET_BIT(PWR->PMCR, PWR_PMCR_CSSF)) : \ + ((__FLAG__) == PWR_WAKEUP_FLAG1) ? (SET_BIT(PWR->WUSCR, PWR_WUSCR_CWUF1)) : \ + ((__FLAG__) == PWR_WAKEUP_FLAG2) ? (SET_BIT(PWR->WUSCR, PWR_WUSCR_CWUF2)) : \ + ((__FLAG__) == PWR_WAKEUP_FLAG3) ? (SET_BIT(PWR->WUSCR, PWR_WUSCR_CWUF3)) : \ + ((__FLAG__) == PWR_WAKEUP_FLAG4) ? (SET_BIT(PWR->WUSCR, PWR_WUSCR_CWUF4)) : \ + ((__FLAG__) == PWR_WAKEUP_FLAG5) ? (SET_BIT(PWR->WUSCR, PWR_WUSCR_CWUF5)) : \ + (SET_BIT(PWR->WUSCR, PWR_WUSCR_CWUF))) +#endif /* PWR_WUSCR_CWUF6 */ + +/** + * @brief Enable the PVD Extended Interrupt Line. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_ENABLE_IT() SET_BIT(EXTI->IMR1, PWR_EXTI_LINE_PVD) + +/** + * @brief Disable the PVD Extended Interrupt Line. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_DISABLE_IT() CLEAR_BIT(EXTI->IMR1, PWR_EXTI_LINE_PVD) + +/** + * @brief Enable the PVD Event Line. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_ENABLE_EVENT() SET_BIT(EXTI->EMR1, PWR_EXTI_LINE_PVD) + +/** + * @brief Disable the PVD Event Line. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_DISABLE_EVENT() CLEAR_BIT(EXTI->EMR1, PWR_EXTI_LINE_PVD) + +/** + * @brief Enable the PVD Extended Interrupt Rising Trigger. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE() SET_BIT(EXTI->RTSR1, PWR_EXTI_LINE_PVD) + +/** + * @brief Disable the PVD Extended Interrupt Rising Trigger. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE() CLEAR_BIT(EXTI->RTSR1, PWR_EXTI_LINE_PVD) + +/** + * @brief Enable the PVD Extended Interrupt Falling Trigger. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE() SET_BIT(EXTI->FTSR1, PWR_EXTI_LINE_PVD) + +/** + * @brief Disable the PVD Extended Interrupt Falling Trigger. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE() CLEAR_BIT(EXTI->FTSR1, PWR_EXTI_LINE_PVD) + +/** + * @brief Enable the PVD Extended Interrupt Rising & Falling Trigger. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_ENABLE_RISING_FALLING_EDGE() \ + do \ + { \ + __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE(); \ + __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE(); \ + } while(0) + +/** + * @brief Disable the PVD Extended Interrupt Rising & Falling Trigger. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_DISABLE_RISING_FALLING_EDGE() \ + do \ + { \ + __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE(); \ + __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE(); \ + } while(0) + +/** + * @brief Generate a Software Interrupt on selected EXTI line. + * @retval None + */ +#define __HAL_PWR_PVD_EXTI_GENERATE_SWIT() SET_BIT(EXTI->SWIER1, PWR_EXTI_LINE_PVD) + +/** + * @brief Check whether the specified PVD EXTI Rising interrupt flag is set or not. + * @retval EXTI PVD Line Status. + */ +#define __HAL_PWR_PVD_EXTI_GET_RISING_FLAG() \ + ((READ_BIT(EXTI->RPR1, PWR_EXTI_LINE_PVD) == PWR_EXTI_LINE_PVD) ? 1UL : 0UL) + +/** + * @brief Check whether the specified PVD EXTI Falling interrupt flag is set or not. + * @retval EXTI PVD Line Status. + */ +#define __HAL_PWR_PVD_EXTI_GET_FALLING_FLAG()\ + ((READ_BIT(EXTI->FPR1, PWR_EXTI_LINE_PVD) == PWR_EXTI_LINE_PVD) ? 1UL : 0UL) + +/** + * @brief Clear the PVD EXTI Interrupt Rising flag. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_CLEAR_RISING_FLAG() WRITE_REG(EXTI->RPR1, PWR_EXTI_LINE_PVD); + +/** + * @brief Clear the PVD EXTI Interrupt Falling flag. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_CLEAR_FALLING_FLAG() WRITE_REG(EXTI->FPR1, PWR_EXTI_LINE_PVD); + +/** + * @brief Clear the PVD EXTI Interrupt flag. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_CLEAR_FLAG() \ + do \ + { \ + WRITE_REG(EXTI->RPR1, PWR_EXTI_LINE_PVD); \ + WRITE_REG(EXTI->FPR1, PWR_EXTI_LINE_PVD); \ + } while(0) +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ + +/** @defgroup PWR_Private_Constants PWR Private Constants + * @{ + */ +/* Define PVD extended interrupts and event line */ +#define PWR_EXTI_LINE_PVD EXTI_IMR1_IM16 /*!< PVD EXTI Line */ + +/* Defines wake up lines shift */ +#define PWR_EWUP_MASK (0x0FFF3F3FU) + +/* Defines attribute */ +#define PWR_ITEM_ATTR_NSEC_PRIV_MASK (0x10U) /*!< NSecure Privilege / NPrivilege attribute item mask */ +#define PWR_ITEM_ATTR_SEC_PRIV_MASK (0x20U) /*!< Secure Privilege / NPrivilege attribute item mask */ +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ + +/** @defgroup PWR_Private_Macros PWR Private Macros + * @{ + */ +#if defined(PWR_WUCR_WUPEN6) +/* Check wake up pin parameter */ +#define IS_PWR_WAKEUP_PIN(PIN) \ + (((PIN) == PWR_WAKEUP_PIN1) || ((PIN) == PWR_WAKEUP_PIN2) ||\ + ((PIN) == PWR_WAKEUP_PIN3) || ((PIN) == PWR_WAKEUP_PIN4) ||\ + ((PIN) == PWR_WAKEUP_PIN5) || ((PIN) == PWR_WAKEUP_PIN6) ||\ + ((PIN) == PWR_WAKEUP_PIN7) || ((PIN) == PWR_WAKEUP_PIN8) ||\ + ((PIN) == PWR_WAKEUP_PIN1_HIGH) || ((PIN) == PWR_WAKEUP_PIN2_HIGH) ||\ + ((PIN) == PWR_WAKEUP_PIN3_HIGH) || ((PIN) == PWR_WAKEUP_PIN4_HIGH) ||\ + ((PIN) == PWR_WAKEUP_PIN5_HIGH) || ((PIN) == PWR_WAKEUP_PIN6_HIGH) ||\ + ((PIN) == PWR_WAKEUP_PIN7_HIGH) || ((PIN) == PWR_WAKEUP_PIN8_HIGH) ||\ + ((PIN) == PWR_WAKEUP_PIN1_LOW) || ((PIN) == PWR_WAKEUP_PIN2_LOW) ||\ + ((PIN) == PWR_WAKEUP_PIN3_LOW) || ((PIN) == PWR_WAKEUP_PIN4_LOW) ||\ + ((PIN) == PWR_WAKEUP_PIN5_LOW) || ((PIN) == PWR_WAKEUP_PIN6_LOW) ||\ + ((PIN) == PWR_WAKEUP_PIN7_LOW) || ((PIN) == PWR_WAKEUP_PIN8_LOW)) +#else +/* Check wake up pin parameter */ +#define IS_PWR_WAKEUP_PIN(PIN) \ + (((PIN) == PWR_WAKEUP_PIN1) || ((PIN) == PWR_WAKEUP_PIN2) ||\ + ((PIN) == PWR_WAKEUP_PIN3) || ((PIN) == PWR_WAKEUP_PIN4) ||\ + ((PIN) == PWR_WAKEUP_PIN5) || ((PIN) == PWR_WAKEUP_PIN1_HIGH) ||\ + ((PIN) == PWR_WAKEUP_PIN2_HIGH) || ((PIN) == PWR_WAKEUP_PIN3_HIGH) ||\ + ((PIN) == PWR_WAKEUP_PIN4_HIGH) || ((PIN) == PWR_WAKEUP_PIN5_HIGH) ||\ + ((PIN) == PWR_WAKEUP_PIN1_LOW) || ((PIN) == PWR_WAKEUP_PIN2_LOW) ||\ + ((PIN) == PWR_WAKEUP_PIN3_LOW) || ((PIN) == PWR_WAKEUP_PIN4_LOW) ||\ + ((PIN) == PWR_WAKEUP_PIN5_LOW)) +#endif /* PWR_WUCR_WUPEN6 */ + +/* PVD level check macro */ +#define IS_PWR_PVD_LEVEL(LEVEL) \ + (((LEVEL) == PWR_PVDLEVEL_0) || ((LEVEL) == PWR_PVDLEVEL_1) ||\ + ((LEVEL) == PWR_PVDLEVEL_2) || ((LEVEL) == PWR_PVDLEVEL_3) ||\ + ((LEVEL) == PWR_PVDLEVEL_4) || ((LEVEL) == PWR_PVDLEVEL_5) ||\ + ((LEVEL) == PWR_PVDLEVEL_6) || ((LEVEL) == PWR_PVDLEVEL_7)) + +/* PVD mode check macro */ +#define IS_PWR_PVD_MODE(MODE) \ + (((MODE) == PWR_PVD_MODE_NORMAL) ||\ + ((MODE) == PWR_PVD_MODE_IT_RISING) ||\ + ((MODE) == PWR_PVD_MODE_IT_FALLING) ||\ + ((MODE) == PWR_PVD_MODE_IT_RISING_FALLING) ||\ + ((MODE) == PWR_PVD_MODE_EVENT_RISING) ||\ + ((MODE) == PWR_PVD_MODE_EVENT_FALLING) ||\ + ((MODE) == PWR_PVD_MODE_EVENT_RISING_FALLING)) + +/* SLEEP mode entry check macro */ +#define IS_PWR_SLEEP_ENTRY(ENTRY) (((ENTRY) == PWR_SLEEPENTRY_WFI) || ((ENTRY) == PWR_SLEEPENTRY_WFE)) + +/* STOP mode entry check macro */ +#define IS_PWR_STOP_ENTRY(ENTRY) (((ENTRY) == PWR_STOPENTRY_WFI) || ((ENTRY) == PWR_STOPENTRY_WFE)) + +#if defined (PWR_SECCFGR_WUP1SEC) +/* PWR items check macro */ +#define IS_PWR_ITEMS_ATTRIBUTES(ITEM) ((((ITEM) & (~PWR_ALL)) == 0U) && ((ITEM) != 0U)) +#endif /* PWR_SECCFGR_WUP1SEC */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/* PWR attribute check macro (Secure) */ +#define IS_PWR_ATTRIBUTES(ATTRIBUTES) \ + ((((~(((ATTRIBUTES) & 0xF0U) >> 4U)) &((ATTRIBUTES) & 0x0FU)) == 0U) && (((ATTRIBUTES) & 0xFFFFFFCCU) == 0U)) +#elif defined(PWR_PRIVCFGR_NSPRIV) +/* PWR attribute check macro (NSecure) */ +#define IS_PWR_ATTRIBUTES(ATTRIBUTES) (((ATTRIBUTES) == PWR_NSEC_NPRIV) || ((ATTRIBUTES) == PWR_NSEC_PRIV)) +#else +/* PWR attribute check macro (NSecure) */ +#define IS_PWR_ATTRIBUTES(ATTRIBUTES) (((ATTRIBUTES) == PWR_NPRIV) || ((ATTRIBUTES) == PWR_PRIV)) +#endif /* __ARM_FEATURE_CMSE */ +/** + * @} + */ + +/* Include PWR HAL Extended module */ +#include "stm32h5xx_hal_pwr_ex.h" + +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup PWR_Exported_Functions + * @{ + */ + +/** @addtogroup PWR_Exported_Functions_Group1 + * @{ + */ +/* Initialization and de-initialization functions *****************************/ +void HAL_PWR_DeInit(void); +void HAL_PWR_EnableBkUpAccess(void); +void HAL_PWR_DisableBkUpAccess(void); +/** + * @} + */ + +/** @addtogroup PWR_Exported_Functions_Group2 + * @{ + */ +/* Programmable voltage detector functions ************************************/ +HAL_StatusTypeDef HAL_PWR_ConfigPVD(const PWR_PVDTypeDef *sConfigPVD); +void HAL_PWR_EnablePVD(void); +void HAL_PWR_DisablePVD(void); + +/* Wake up pins configuration functions ***************************************/ +void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinPolarity); +void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx); + +/* Low power modes configuration functions ************************************/ +void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry); +void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry); +void HAL_PWR_EnterSTANDBYMode(void); + +/* Sleep on exit and sev on pending configuration functions *******************/ +void HAL_PWR_EnableSleepOnExit(void); +void HAL_PWR_DisableSleepOnExit(void); +void HAL_PWR_EnableSEVOnPend(void); +void HAL_PWR_DisableSEVOnPend(void); + +/* Interrupt handler functions ************************************************/ +void HAL_PWR_PVD_IRQHandler(void); +void HAL_PWR_PVDCallback(void); +/** + * @} + */ + +/** @addtogroup PWR_Exported_Functions_Group3 + * @{ + */ +/* Privileges and security configuration functions ****************************/ +void HAL_PWR_ConfigAttributes(uint32_t Item, uint32_t Attributes); +HAL_StatusTypeDef HAL_PWR_GetConfigAttributes(uint32_t Item, uint32_t *pAttributes); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* STM32H5xx_HAL_PWR_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_pwr_ex.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_pwr_ex.h new file mode 100644 index 0000000000..c5dc670e04 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_pwr_ex.h @@ -0,0 +1,548 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_pwr_ex.h + * @author MCD Application Team + * @brief Header file of PWR HAL Extended module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_PWR_EX_H +#define STM32H5xx_HAL_PWR_EX_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup PWREx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup PWREx_Exported_Types PWR Extended Exported Types + * @{ + */ + +/** + * @brief PWREx AVD configuration structure definition + */ +typedef struct +{ + uint32_t AVDLevel; /*!< AVDLevel: Specifies the AVD detection level. This + parameter can be a value of @ref + PWREx_AVD_detection_level + */ + + uint32_t Mode; /*!< Mode: Specifies the EXTI operating mode for the AVD + event. This parameter can be a value of @ref + PWREx_AVD_Mode. + */ +} PWREx_AVDTypeDef; + +/** + * @brief PWREx Wakeup pin configuration structure definition + */ +typedef struct +{ + uint32_t WakeUpPin; /*!< WakeUpPin: Specifies the Wake-Up pin to be enabled. + This parameter can be a value of @ref + PWREx_WakeUp_Pins + */ + + uint32_t PinPolarity; /*!< PinPolarity: Specifies the Wake-Up pin polarity. + This parameter can be a value of @ref + PWREx_PIN_Polarity + */ + + uint32_t PinPull; /*!< PinPull: Specifies the Wake-Up pin pull. This + parameter can be a value of @ref + PWREx_PIN_Pull + */ +} PWREx_WakeupPinTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup PWREx_Exported_Constants PWR Extended Exported Constants + * @{ + */ + +/** @defgroup PWREx_Supply_configuration PWREx Supply configuration + * @{ + */ +#define PWR_EXTERNAL_SOURCE_SUPPLY PWR_SCCR_BYPASS /*!< The SMPS disabled and the LDO Bypass. The Core domains + are supplied from an external source */ + +#if defined (SMPS) +#define PWR_SUPPLY_CONFIG_MASK (PWR_SCCR_SMPSEN | PWR_SCCR_LDOEN | PWR_SCCR_BYPASS) +#else +#define PWR_SUPPLY_CONFIG_MASK (PWR_SCCR_LDOEN | PWR_SCCR_BYPASS) +#endif /* defined (SMPS) */ +/** + * @} + */ + +/** @defgroup PWREx_PIN_Polarity PWREx Pin Polarity configuration + * @{ + */ +#define PWR_PIN_POLARITY_HIGH (0x00000000U) +#define PWR_PIN_POLARITY_LOW (0x00000001U) +/** + * @} + */ + +/** @defgroup PWREx_PIN_Pull PWREx Pin Pull configuration + * @{ + */ +#define PWR_PIN_NO_PULL (0x00000000U) +#define PWR_PIN_PULL_UP (0x00000001U) +#define PWR_PIN_PULL_DOWN (0x00000002U) +/** + * @} + */ + +/** @defgroup PWREx_AVD_detection_level PWREx AVD detection level + * @{ + */ +#define PWR_AVDLEVEL_0 (0x00000000U) /*!< Analog voltage detector level 0 selection : 1V7 */ +#define PWR_AVDLEVEL_1 PWR_VMCR_ALS_0 /*!< Analog voltage detector level 1 selection : 2V1 */ +#define PWR_AVDLEVEL_2 PWR_VMCR_ALS_1 /*!< Analog voltage detector level 2 selection : 2V5 */ +#define PWR_AVDLEVEL_3 PWR_VMCR_ALS /*!< Analog voltage detector level 3 selection : 2V8 */ +/** + * @} + */ + +/** @defgroup PWREx_AVD_Mode PWREx AVD Mode + * @{ + */ +#define PWR_AVD_MODE_NORMAL (0x00000000U)/*!< Basic mode is used */ +#define PWR_AVD_MODE_IT_RISING (0x00010001U)/*!< External Interrupt Mode with Rising edge trigger detection*/ +#define PWR_AVD_MODE_IT_FALLING (0x00010002U)/*!< External Interrupt Mode with + Falling edge trigger detection */ +#define PWR_AVD_MODE_IT_RISING_FALLING (0x00010003U)/*!< External Interrupt Mode with + Rising/Falling edge trigger detection */ +#define PWR_AVD_MODE_EVENT_RISING (0x00020001U)/*!< Event Mode with Rising edge trigger detection */ +#define PWR_AVD_MODE_EVENT_FALLING (0x00020002U)/*!< Event Mode with Falling edge trigger detection */ +#define PWR_AVD_MODE_EVENT_RISING_FALLING (0x00020003U)/*!< Event Mode with Rising/Falling edge trigger detection */ +/** + * @} + */ + +/** @defgroup PWREx_Regulator_Voltage_Scale PWREx Regulator Voltage Scale + * @{ + */ +#define PWR_REGULATOR_VOLTAGE_SCALE0 PWR_VOSCR_VOS /*!< Voltage scaling range 0 */ +#define PWR_REGULATOR_VOLTAGE_SCALE1 PWR_VOSCR_VOS_1 /*!< Voltage scaling range 1 */ +#define PWR_REGULATOR_VOLTAGE_SCALE2 PWR_VOSCR_VOS_0 /*!< Voltage scaling range 2 */ +#define PWR_REGULATOR_VOLTAGE_SCALE3 (0U) /*!< Voltage scaling range 3 */ +/** + * @} + */ + +/** @defgroup PWREx_System_Stop_Mode_Voltage_Scale PWREx System Stop Mode Voltage Scale + * @{ + */ +#define PWR_REGULATOR_SVOS_SCALE5 (PWR_PMCR_SVOS_0) +#define PWR_REGULATOR_SVOS_SCALE4 (PWR_PMCR_SVOS_1) +#define PWR_REGULATOR_SVOS_SCALE3 (PWR_PMCR_SVOS_0 | PWR_PMCR_SVOS_1) +/** + * @} + */ + +/** @defgroup PWREx_VBAT_Battery_Charging_Selection PWR Extended Battery Charging Resistor Selection + * @{ + */ +#define PWR_BATTERY_CHARGING_RESISTOR_5 (0U) /*!< VBAT charging through a 5 kOhms resistor */ +#define PWR_BATTERY_CHARGING_RESISTOR_1_5 PWR_BDCR_VBRS /*!< VBAT charging through a 1.5 kOhms resistor */ +/** + * @} + */ + +/** @defgroup PWREx_Memory_Shut_Off Memory shut-off block selection + * @{ + */ +#if defined (PWR_PMCR_SRAM2_16SO) +#define PWR_ETHERNET_MEMORY_BLOCK PWR_PMCR_ETHERNETSO /*!< Ethernet shut-off control in Stop mode */ +#define PWR_RAM3_MEMORY_BLOCK PWR_PMCR_SRAM3SO /*!< RAM3 shut-off control in Stop mode */ +#define PWR_RAM2_16_MEMORY_BLOCK PWR_PMCR_SRAM2_16SO /*!< RAM2 16k byte shut-off control in Stop mode */ +#define PWR_RAM2_48_MEMORY_BLOCK PWR_PMCR_SRAM2_48SO /*!< RAM2 48k byte shut-off control in Stop mode */ +#else +#define PWR_RAM2_MEMORY_BLOCK PWR_PMCR_SRAM2SO /*!< RAM2 48k byte shut-off control in Stop mode */ +#endif /* PWR_PMCR_SRAM2_16SO */ +#define PWR_RAM1_MEMORY_BLOCK PWR_PMCR_SRAM1SO /*!< RAM1 shut-off control in Stop mode */ + +/** + * @} + */ + +/** @defgroup PWREx_AVD_EXTI_Line PWREx AVD EXTI Line 16 + * @{ + */ +#define PWR_EXTI_LINE_AVD EXTI_IMR1_IM16 /*!< External interrupt line 16 + Connected to the AVD EXTI Line */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ + +/** @defgroup PWREx_Exported_Macros PWR Extended Exported Macros + * @{ + */ + +/** + * @brief Enable the AVD EXTI Line 16. + * @retval None. + */ +#define __HAL_PWR_AVD_EXTI_ENABLE_IT() SET_BIT(EXTI->IMR1, PWR_EXTI_LINE_AVD) + +/** + * @brief Disable the AVD EXTI Line 16 + * @retval None. + */ +#define __HAL_PWR_AVD_EXTI_DISABLE_IT() CLEAR_BIT(EXTI->IMR1, PWR_EXTI_LINE_AVD) + +/** + * @brief Enable event on AVD EXTI Line 16. + * @retval None. + */ +#define __HAL_PWR_AVD_EXTI_ENABLE_EVENT() SET_BIT(EXTI->EMR1, PWR_EXTI_LINE_AVD) + +/** + * @brief Disable event on AVD EXTI Line 16. + * @retval None. + */ +#define __HAL_PWR_AVD_EXTI_DISABLE_EVENT() CLEAR_BIT(EXTI->EMR1, PWR_EXTI_LINE_AVD) + +/** + * @brief Enable the AVD Extended Interrupt Rising Trigger. + * @retval None. + */ +#define __HAL_PWR_AVD_EXTI_ENABLE_RISING_EDGE() SET_BIT(EXTI->RTSR1, PWR_EXTI_LINE_AVD) + +/** + * @brief Disable the AVD Extended Interrupt Rising Trigger. + * @retval None. + */ +#define __HAL_PWR_AVD_EXTI_DISABLE_RISING_EDGE() CLEAR_BIT(EXTI->RTSR1, PWR_EXTI_LINE_AVD) + +/** + * @brief Enable the AVD Extended Interrupt Falling Trigger. + * @retval None. + */ +#define __HAL_PWR_AVD_EXTI_ENABLE_FALLING_EDGE() SET_BIT(EXTI->FTSR1, PWR_EXTI_LINE_AVD) + +/** + * @brief Disable the AVD Extended Interrupt Falling Trigger. + * @retval None. + */ +#define __HAL_PWR_AVD_EXTI_DISABLE_FALLING_EDGE() CLEAR_BIT(EXTI->FTSR1, PWR_EXTI_LINE_AVD) + +/** + * @brief Enable the AVD Extended Interrupt Rising and Falling Trigger. + * @retval None. + */ +#define __HAL_PWR_AVD_EXTI_ENABLE_RISING_FALLING_EDGE() \ + do { \ + __HAL_PWR_AVD_EXTI_ENABLE_RISING_EDGE(); \ + __HAL_PWR_AVD_EXTI_ENABLE_FALLING_EDGE(); \ + } while(0); + +/** + * @brief Disable the AVD Extended Interrupt Rising & Falling Trigger. + * @retval None. + */ +#define __HAL_PWR_AVD_EXTI_DISABLE_RISING_FALLING_EDGE() \ + do { \ + __HAL_PWR_AVD_EXTI_DISABLE_RISING_EDGE(); \ + __HAL_PWR_AVD_EXTI_DISABLE_FALLING_EDGE(); \ + } while(0); + +/** + * @brief Check whether the specified AVD EXTI Rising interrupt flag is set or not. + * @retval EXTI AVD Line Status. + */ + +#define __HAL_PWR_PVD_AVD_EXTI_GET_RISING_FLAG() ((READ_BIT(EXTI->RPR1, PWR_EXTI_LINE_AVD)\ + == PWR_EXTI_LINE_AVD) ? 1UL : 0UL) + +/** + * @brief Check whether the specified AVD EXTI Falling interrupt flag is set or not. + * @retval EXTI AVD Line Status. + */ + +#define __HAL_PWR_PVD_AVD_EXTI_GET_FALLING_FLAG() ((READ_BIT(EXTI->FPR1, PWR_EXTI_LINE_AVD)\ + == PWR_EXTI_LINE_AVD) ? 1UL : 0UL) + +/** + * @brief Clear the AVD EXTI flag. + * @retval None. + */ +#define __HAL_PWR_PVD_AVD_EXTI_CLEAR_FLAG() \ + do \ + { \ + WRITE_REG(EXTI->RPR1, PWR_EXTI_LINE_AVD); \ + WRITE_REG(EXTI->FPR1, PWR_EXTI_LINE_AVD); \ + } while(0) + +/** + * @brief Generates a Software interrupt on AVD EXTI line. + * @retval None. + */ +#define __HAL_PWR_AVD_EXTI_GENERATE_SWIT() SET_BIT(EXTI->SWIER1, PWR_EXTI_LINE_AVD) + +/** + * @brief Configure the main internal regulator output voltage. + * @note This macro is similar to HAL_PWREx_ControlVoltageScaling() API but + * doesn't check whether or not VOSREADY flag is set. User may resort + * to __HAL_PWR_GET_FLAG() macro to check VOSF bit state. + * @param __REGULATOR__ : Specifies the regulator output voltage to achieve a + * tradeoff between performance and power consumption. + * This parameter can be one of the following values : + * @arg @ref PWR_REGULATOR_VOLTAGE_SCALE0 : Regulator voltage output scale 0. + * Provides a typical output voltage at 1.2 V. + * Used when system clock frequency is up to 160 MHz. + * @arg @ref PWR_REGULATOR_VOLTAGE_SCALE1 : Regulator voltage output scale 1. + * Provides a typical output voltage at 1.1 V. + * Used when system clock frequency is up to 100 MHz. + * @arg @ref PWR_REGULATOR_VOLTAGE_SCALE2 : Regulator voltage output scale 2. + * Provides a typical output voltage at 1.0 V. + * Used when system clock frequency is up to 50 MHz. + * @arg @ref PWR_REGULATOR_VOLTAGE_SCALE3 : Regulator voltage output scale 3. + * Provides a typical output voltage at 0.9 V. + * Used when system clock frequency is up to 24 MHz. + * @retval None. + */ +#define __HAL_PWR_VOLTAGESCALING_CONFIG(__REGULATOR__) \ + do \ + { \ + __IO uint32_t tmpreg; \ + MODIFY_REG(PWR->VOSCR, PWR_VOSCR_VOS, (__REGULATOR__)); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(PWR->VOSCR, PWR_VOSCR_VOS); \ + UNUSED(tmpreg); \ + } while(0) +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ + +/** @defgroup PWREx_Private_Constants PWR Extended Private Constants + * @{ + */ + +/** @defgroup PWREx_AVD_Mode_Mask PWR Extended AVD Mode Mask + * @{ + */ +#define AVD_MODE_IT (0x00010000U) +#define AVD_MODE_EVT (0x00020000U) +#define AVD_RISING_EDGE (0x00000001U) +#define AVD_FALLING_EDGE (0x00000002U) +#define AVD_RISING_FALLING_EDGE (0x00000003U) +/** + * @} + */ + +/** + * @} + */ + +/* Private macros --------------------------------------------------------*/ + +/** @defgroup PWREx_Private_Macros PWR Extended Private Macros + * @{ + */ +/* Check PWR regulator configuration parameter */ +#define IS_PWR_SUPPLY(PWR_SOURCE) ((PWR_SOURCE) == PWR_EXTERNAL_SOURCE_SUPPLY) + +/* Check wake up pin polarity parameter */ +#define IS_PWR_WAKEUP_PIN_POLARITY(POLARITY) (((POLARITY) == PWR_PIN_POLARITY_HIGH) ||\ + ((POLARITY) == PWR_PIN_POLARITY_LOW)) + +/* Check wake up pin pull configuration parameter */ +#define IS_PWR_WAKEUP_PIN_PULL(PULL) (((PULL) == PWR_PIN_NO_PULL) ||\ + ((PULL) == PWR_PIN_PULL_UP) ||\ + ((PULL) == PWR_PIN_PULL_DOWN)) + +/* Check wake up flag parameter */ +#define IS_PWR_WAKEUP_FLAG(FLAG) (((FLAG) == PWR_WAKEUP_FLAG1) ||\ + ((FLAG) == PWR_WAKEUP_FLAG2) ||\ + ((FLAG) == PWR_WAKEUP_FLAG3) ||\ + ((FLAG) == PWR_WAKEUP_FLAG4) ||\ + ((FLAG) == PWR_WAKEUP_FLAG5) ||\ + ((FLAG) == PWR_WAKEUP_FLAG6) ||\ + ((FLAG) == PWR_WAKEUP_FLAG_ALL)) + +/* Voltage scaling range check macro */ +#define IS_PWR_VOLTAGE_SCALING_RANGE(RANGE) (((RANGE) == PWR_REGULATOR_VOLTAGE_SCALE0) ||\ + ((RANGE) == PWR_REGULATOR_VOLTAGE_SCALE1) ||\ + ((RANGE) == PWR_REGULATOR_VOLTAGE_SCALE2) ||\ + ((RANGE) == PWR_REGULATOR_VOLTAGE_SCALE3)) + +/* Check PWR regulator configuration in STOP mode parameter */ +#define IS_PWR_STOP_MODE_REGULATOR_VOLTAGE(VOLTAGE) (((VOLTAGE) == PWR_REGULATOR_SVOS_SCALE3) ||\ + ((VOLTAGE) == PWR_REGULATOR_SVOS_SCALE4) ||\ + ((VOLTAGE) == PWR_REGULATOR_SVOS_SCALE5)) + +/* Battery charging resistor selection check macro */ +#define IS_PWR_BATTERY_RESISTOR_SELECT(RESISTOR) (((RESISTOR) == PWR_BATTERY_CHARGING_RESISTOR_5) ||\ + ((RESISTOR) == PWR_BATTERY_CHARGING_RESISTOR_1_5)) + +#if defined (PWR_PMCR_SRAM2_16SO) +/* Check memory block parameter */ +#define IS_PWR_MEMORY_BLOCK(BLOCK) (((BLOCK) == PWR_ETHERNET_MEMORY_BLOCK) || \ + ((BLOCK) == PWR_RAM3_MEMORY_BLOCK) || \ + ((BLOCK) == PWR_RAM2_16_MEMORY_BLOCK) || \ + ((BLOCK) == PWR_RAM2_48_MEMORY_BLOCK) || \ + ((BLOCK) == PWR_RAM1_MEMORY_BLOCK)) +#else +#define IS_PWR_MEMORY_BLOCK(BLOCK) (((BLOCK) == PWR_RAM2_MEMORY_BLOCK) || \ + ((BLOCK) == PWR_RAM1_MEMORY_BLOCK)) +#endif /* PWR_PMCR_SRAM2_16SO */ + +/* Check wake up flag parameter */ +#define IS_PWR_AVD_LEVEL(LEVEL) (((LEVEL) == PWR_AVDLEVEL_0) ||\ + ((LEVEL) == PWR_AVDLEVEL_1) ||\ + ((LEVEL) == PWR_AVDLEVEL_2) ||\ + ((LEVEL) == PWR_AVDLEVEL_3)) + +/* Check AVD mode parameter */ +#define IS_PWR_AVD_MODE(MODE) (((MODE) == PWR_AVD_MODE_IT_RISING) ||\ + ((MODE) == PWR_AVD_MODE_IT_FALLING) ||\ + ((MODE) == PWR_AVD_MODE_IT_RISING_FALLING) ||\ + ((MODE) == PWR_AVD_MODE_EVENT_RISING) ||\ + ((MODE) == PWR_AVD_MODE_EVENT_FALLING) ||\ + ((MODE) == PWR_AVD_MODE_NORMAL) ||\ + ((MODE) == PWR_AVD_MODE_EVENT_RISING_FALLING)) +/** + * @} + */ + +/** @addtogroup PWREx_Exported_Functions + * @{ + */ + +/** @addtogroup PWREx_Exported_Functions_Group1 + * @{ + */ +HAL_StatusTypeDef HAL_PWREx_ConfigSupply(uint32_t SupplySource); +uint32_t HAL_PWREx_GetSupplyConfig(void); +HAL_StatusTypeDef HAL_PWREx_ControlVoltageScaling(uint32_t VoltageScaling); +uint32_t HAL_PWREx_GetVoltageRange(void); +HAL_StatusTypeDef HAL_PWREx_ControlStopModeVoltageScaling(uint32_t VoltageScaling); +uint32_t HAL_PWREx_GetStopModeVoltageRange(void); + +/** + * @} + */ + +/** @addtogroup PWREx_Exported_Functions_Group2 + * @{ + */ +void HAL_PWREx_ConfigAVD(const PWREx_AVDTypeDef *sConfigAVD); +void HAL_PWREx_EnableAVD(void); +void HAL_PWREx_DisableAVD(void); +#if defined (PWR_USBSCR_USB33DEN) +void HAL_PWREx_EnableUSBVoltageDetector(void); +void HAL_PWREx_DisableUSBVoltageDetector(void); +void HAL_PWREx_EnableVddUSB(void); +void HAL_PWREx_DisableVddUSB(void); +#endif /* PWR_USBSCR_USB33DEN */ +void HAL_PWREx_EnableMonitoring(void); +void HAL_PWREx_DisableMonitoring(void); +void HAL_PWREx_EnableUCPDStandbyMode(void); +void HAL_PWREx_DisableUCPDStandbyMode(void); +void HAL_PWREx_EnableUCPDDeadBattery(void); +void HAL_PWREx_DisableUCPDDeadBattery(void); +void HAL_PWREx_EnableBatteryCharging(uint32_t ResistorValue); +void HAL_PWREx_DisableBatteryCharging(void); +void HAL_PWREx_EnableAnalogBooster(void); +void HAL_PWREx_DisableAnalogBooster(void); +void HAL_PWREx_PVD_AVD_IRQHandler(void); +void HAL_PWREx_PVD_AVD_Rising_Callback(void); +void HAL_PWREx_PVD_AVD_Falling_Callback(void); + +/** + * @} + */ + +/** @addtogroup PWREx_Exported_Functions_Group3 + * @{ + */ + +void HAL_PWREx_EnableWakeUpPin(const PWREx_WakeupPinTypeDef *sPinParams); +void HAL_PWREx_DisableWakeUpPin(uint32_t WakeUpPinx); + +/** + * @} + */ + +/** @addtogroup PWREx_Exported_Functions_Group4 + * @{ + */ +void HAL_PWREx_EnableFlashPowerDown(void); +void HAL_PWREx_DisableFlashPowerDown(void); +void HAL_PWREx_EnableMemoryShutOff(uint32_t MemoryBlock); +void HAL_PWREx_DisableMemoryShutOff(uint32_t MemoryBlock); +HAL_StatusTypeDef HAL_PWREx_EnableBkupRAMRetention(void); +void HAL_PWREx_DisableBkupRAMRetention(void); + +/** + * @} + */ + +/** @addtogroup PWREx_Exported_Functions_Group5 + * @{ + */ +void HAL_PWREx_EnableStandbyIORetention(void); +void HAL_PWREx_DisableStandbyIORetention(void); +void HAL_PWREx_EnableStandbyJTAGIORetention(void); +void HAL_PWREx_DisableStandbyJTAGIORetention(void); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* STM32H5xx_HAL_PWR_EX_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_ramcfg.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_ramcfg.h new file mode 100644 index 0000000000..ddd267d1de --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_ramcfg.h @@ -0,0 +1,394 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_ramcfg.h + * @author MCD Application Team + * @brief Header file of RAMCFG HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_RAMCFG_H +#define STM32H5xx_HAL_RAMCFG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup RAMCFG + * @{ + */ + + +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup RAMCFG_Exported_Types RAMCFG Exported Types + * @brief RAMCFG Exported Types + * @{ + */ + +/** + * @brief HAL RAMCFG State Enumeration Definition + */ +typedef enum +{ + HAL_RAMCFG_STATE_RESET = 0x00U, /*!< RAMCFG not yet initialized or disabled */ + HAL_RAMCFG_STATE_READY = 0x01U, /*!< RAMCFG initialized and ready for use */ + HAL_RAMCFG_STATE_BUSY = 0x02U, /*!< RAMCFG process is ongoing */ + HAL_RAMCFG_STATE_ERROR = 0x03U, /*!< RAMCFG error state */ +} HAL_RAMCFG_StateTypeDef; + +#if (USE_HAL_RAMCFG_REGISTER_CALLBACKS == 1) +/** + * @brief HAL RAMCFG Callbacks IDs Enumeration Definition + */ +typedef enum +{ + HAL_RAMCFG_MSPINIT_CB_ID = 0x00U, /*!< RAMCFG MSP Init Callback ID */ + HAL_RAMCFG_MSPDEINIT_CB_ID = 0x01U, /*!< RAMCFG MSP DeInit Callback ID */ + HAL_RAMCFG_SE_DETECT_CB_ID = 0x02U, /*!< RAMCFG Single Error Detect Callback ID */ + HAL_RAMCFG_DE_DETECT_CB_ID = 0x03U, /*!< RAMCFG Double Error Detect Callback ID */ + HAL_RAMCFG_ALL_CB_ID = 0x04U, /*!< RAMCFG All callback ID */ +} HAL_RAMCFG_CallbackIDTypeDef; +#endif /* USE_HAL_RAMCFG_REGISTER_CALLBACKS */ + +/** + * @brief RAMCFG Handle Structure Definition + */ +#if (USE_HAL_RAMCFG_REGISTER_CALLBACKS == 1) +typedef struct __RAMCFG_HandleTypeDef +#else +typedef struct +#endif /* (USE_HAL_RAMCFG_REGISTER_CALLBACKS) */ +{ + RAMCFG_TypeDef *Instance; /*!< RAMCFG Register Base Address */ + __IO HAL_RAMCFG_StateTypeDef State; /*!< RAMCFG State */ + __IO uint32_t ErrorCode; /*!< RAMCFG Error Code */ +#if (USE_HAL_RAMCFG_REGISTER_CALLBACKS == 1) + void (* MspInitCallback)(struct __RAMCFG_HandleTypeDef *hramcfg); /*!< RAMCFG MSP Init Callback */ + void (* MspDeInitCallback)(struct __RAMCFG_HandleTypeDef *hramcfg); /*!< RAMCFG MSP DeInit Callback */ + void (* DetectSingleErrorCallback)(struct __RAMCFG_HandleTypeDef *hramcfg);/*!< RAMCFG Single Error Detect Callback */ + void (* DetectDoubleErrorCallback)(struct __RAMCFG_HandleTypeDef *hramcfg);/*!< RAMCFG Double Error Detect Callback */ +#endif /* USE_HAL_RAMCFG_REGISTER_CALLBACKS */ +} RAMCFG_HandleTypeDef; + +/** + * @} + */ + + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup RAMCFG_Exported_Constants RAMCFG Exported Constants + * @brief RAMCFG Exported Constants + * @{ + */ + +/** @defgroup RAMCFG_Error_Codes RAMCFG Error Codes + * @brief RAMCFG Error Codes + * @{ + */ +#define HAL_RAMCFG_ERROR_NONE 0x00000000U /*!< RAMCFG No Error */ +#define HAL_RAMCFG_ERROR_TIMEOUT 0x00000001U /*!< RAMCFG Timeout Error */ +#define HAL_RAMCFG_ERROR_BUSY 0x00000002U /*!< RAMCFG Busy Error */ +#if (USE_HAL_RAMCFG_REGISTER_CALLBACKS == 1) +#define HAL_RAMCFG_ERROR_INVALID_CALLBACK 0x00000003U /*!< Invalid Callback error */ +#endif /* USE_HAL_RAMCFG_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @defgroup RAMCFG_Interrupt RAMCFG Interrupts + * @brief RAMCFG Interrupts + * @{ + */ +#define RAMCFG_IT_SINGLEERR RAMCFG_IER_SEIE /*!< RAMCFG Single Error Interrupt */ +#define RAMCFG_IT_DOUBLEERR RAMCFG_IER_DEIE /*!< RAMCFG Double Error Interrupt */ +#define RAMCFG_IT_NMIERR RAMCFG_IER_ECCNMI /*!< RAMCFG Double Error redirected to NMI Interrupt */ +#define RAMCFG_IT_ALL \ + (RAMCFG_IER_SEIE | RAMCFG_IER_DEIE |RAMCFG_IER_ECCNMI) /*!< RAMCFG All RAMCFG interrupt */ +/** + * @} + */ + +/** @defgroup RAMCFG_FLAG RAMCFG Monitor Flags + * @brief RAMCFG Monitor Flags + * @{ + */ +#define RAMCFG_FLAG_SINGLEERR RAMCFG_ISR_SEDC /*!< RAMCFG Single Error Detected and Corrected Flag */ +#define RAMCFG_FLAG_DOUBLEERR RAMCFG_ISR_DED /*!< RAMCFG Double Error Detected Flag */ +#define RAMCFG_FLAG_SRAMBUSY RAMCFG_ISR_SRAMBUSY /*!< RAMCFG SRAM busy Flag */ +#define RAMCFG_FLAGS_ALL \ + (RAMCFG_ISR_SEDC | RAMCFG_ISR_DED | RAMCFG_ISR_SRAMBUSY) /*!< RAMCFG All Flags */ +/** + * @} + */ + +/** @defgroup RAMCFG_Keys RAMCFG Keys + * @brief RAMCFG Keys + * @{ + */ +#define RAMCFG_ERASE_KEY1 (0xCAU) /*!< RAMCFG launch Erase Key 1 */ +#define RAMCFG_ERASE_KEY2 (0x53U) /*!< RAMCFG launch Erase Key 2 */ + +#define RAMCFG_ECC_KEY1 (0xAEU) /*!< RAMCFG launch ECC Key 1 */ +#define RAMCFG_ECC_KEY2 (0x75U) /*!< RAMCFG launch ECC Key 2 */ +/** + * @} + */ + + +/** + * @} + */ + + +/* Exported macro ------------------------------------------------------------*/ + +/** @defgroup RAMCFG_Exported_Macros RAMCFG Exported Macros + * @brief RAMCFG Exported Macros + * @{ + */ + +/** + * @brief Enable the specified RAMCFG interrupts. + * @param __HANDLE__ : Specifies RAMCFG handle. + * @param __INTERRUPT__: Specifies the RAMCFG interrupt sources to be enabled. + * This parameter can be one of the following values: + * @arg RAMCFG_IT_SINGLEERR : Single Error Interrupt Mask. + * @arg RAMCFG_IT_DOUBLEERR : Double Error Interrupt Mask. + * @arg RAMCFG_IT_NMIERR : Double Error Interrupt redirection to NMI Mask. + * @arg RAMCFG_IT_ALL : All Interrupt Mask. + * @retval None + */ +#define __HAL_RAMCFG_ENABLE_IT(__HANDLE__, __INTERRUPT__) \ + ((__HANDLE__)->Instance->IER |= (__INTERRUPT__)) + +/** + * @brief Disable the specified RAMCFG interrupts. + * @note This macros is used only to disable RAMCFG_IT_SINGLEERR and RAMCFG_IT_DOUBLEERR + * interrupts. RAMCFG_IT_NMIERR interrupt can only be disabled by global peripheral reset or system reset. + * @param __HANDLE__ : Specifies RAMCFG handle. + * @param __INTERRUPT__: Specifies the RAMCFG interrupt sources to be disabled. + * This parameter can be one of the following values: + * @arg RAMCFG_IT_SINGLEERR : Single Error Interrupt Mask. + * @arg RAMCFG_IT_DOUBLEERR : Double Error Interrupt Mask. + * @retval None + */ +#define __HAL_RAMCFG_DISABLE_IT(__HANDLE__, __INTERRUPT__) \ + ((__HANDLE__)->Instance->IER &= ~(__INTERRUPT__)) + +/** + * @brief Check whether the specified RAMCFG interrupt source is enabled or not. + * @param __HANDLE__ : Specifies the RAMCFG Handle. + * @param __INTERRUPT__ : Specifies the RAMCFG interrupt source to check. + * This parameter can be one of the following values: + * @arg RAMCFG_IT_SINGLEERR : Single Error Interrupt Mask. + * @arg RAMCFG_IT_DOUBLEERR : Double Error Interrupt Mask. + * @arg RAMCFG_IT_NMIERR : Double Error Interrupt Redirection to NMI Mask. + * @retval The new state of __INTERRUPT__ (SET or RESET). + */ +#define __HAL_RAMCFG_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) \ + ((((__HANDLE__)->Instance->IER & (__INTERRUPT__)) == (__INTERRUPT__)) ? 1U : 0U) + +/** + * @brief Get the RAMCFG pending flags. + * @param __HANDLE__ : Specifies RAMCFG handle. + * @param __FLAG__ : Specifies the flag to be checked. + * This parameter can be one of the following values: + * @arg RAMCFG_FLAG_SINGLEERR : Single Error Detected and Corrected Flag. + * @arg RAMCFG_FLAG_DOUBLEERR : Double Error Detected Flag. + * @arg RAMCFG_FLAG_SRAMBUSY : SRAM Busy Flag. + * @retval The state of FLAG (SET or RESET). + */ +#define __HAL_RAMCFG_GET_FLAG(__HANDLE__, __FLAG__) \ + (READ_BIT((__HANDLE__)->Instance->ISR, (__FLAG__)) == (__FLAG__)) + +/** + * @brief Clear the RAMCFG pending flags. + * @param __HANDLE__ : Specifies RAMCFG handle. + * @param __FLAG__ : Specifies the flag to be cleared. + * This parameter can be any combination of the following values: + * @arg RAMCFG_FLAG_SINGLEERR : Single Error Detected and Corrected Flag. + * @arg RAMCFG_FLAG_DOUBLEERR : Double Error Detected Flag. + * @retval None. + */ +#define __HAL_RAMCFG_CLEAR_FLAG(__HANDLE__, __FLAG__) \ + ((__HANDLE__)->Instance->ICR |= (__FLAG__)) + +/** @brief Reset the RAMCFG handle state. + * @param __HANDLE__ : Specifies the RAMCFG Handle. + * @retval None. + */ +#if (USE_HAL_RAMCFG_REGISTER_CALLBACKS == 1) +#define __HAL_RAMCFG_RESET_HANDLE_STATE(__HANDLE__) \ + do{\ + (__HANDLE__)->State = HAL_RAMCFG_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + }while(0) +#else +#define __HAL_RAMCFG_RESET_HANDLE_STATE(__HANDLE__) \ + do{\ + (__HANDLE__)->State = HAL_RAMCFG_STATE_RESET; \ + }while(0) +#endif /* USE_HAL_RAMCFG_REGISTER_CALLBACKS */ + +/** + * @} + */ + + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup RAMCFG_Exported_Functions RAMCFG Exported Functions + * @brief RAMCFG Exported Functions + * @{ + */ + +/** @defgroup RAMCFG_Exported_Functions_Group1 Initialization and De-Initialization Functions + * @brief Initialization and De-Initialization Functions + * @{ + */ +HAL_StatusTypeDef HAL_RAMCFG_Init(RAMCFG_HandleTypeDef *hramcfg); +HAL_StatusTypeDef HAL_RAMCFG_DeInit(RAMCFG_HandleTypeDef *hramcfg); +void HAL_RAMCFG_MspInit(RAMCFG_HandleTypeDef *hramcfg); +void HAL_RAMCFG_MspDeInit(RAMCFG_HandleTypeDef *hramcfg); +/** + * @} + */ + +/** @defgroup RAMCFG_Exported_Functions_Group2 ECC Operation Functions + * @brief ECC Operation Functions + * @{ + */ +HAL_StatusTypeDef HAL_RAMCFG_StartECC(RAMCFG_HandleTypeDef *hramcfg); +HAL_StatusTypeDef HAL_RAMCFG_StopECC(RAMCFG_HandleTypeDef *hramcfg); +HAL_StatusTypeDef HAL_RAMCFG_EnableNotification(RAMCFG_HandleTypeDef *hramcfg, uint32_t Notifications); +HAL_StatusTypeDef HAL_RAMCFG_DisableNotification(RAMCFG_HandleTypeDef *hramcfg, uint32_t Notifications); +uint32_t HAL_RAMCFG_IsECCSingleErrorDetected(const RAMCFG_HandleTypeDef *hramcfg); +uint32_t HAL_RAMCFG_IsECCDoubleErrorDetected(const RAMCFG_HandleTypeDef *hramcfg); +uint32_t HAL_RAMCFG_GetSingleErrorAddress(const RAMCFG_HandleTypeDef *hramcfg); +uint32_t HAL_RAMCFG_GetDoubleErrorAddress(const RAMCFG_HandleTypeDef *hramcfg); +/** + * @} + */ + +/** @defgroup RAMCFG_Exported_Functions_Group4 Write Protection Functions + * @brief Write Protection Functions + * @{ + */ +HAL_StatusTypeDef HAL_RAMCFG_EnableWriteProtection(RAMCFG_HandleTypeDef *hramcfg, uint32_t StartPage, uint32_t NbPage); +/** + * @} + */ + +/** @defgroup RAMCFG_Exported_Functions_Group5 Erase Operation Functions + * @brief Erase Operation Functions + * @{ + */ +HAL_StatusTypeDef HAL_RAMCFG_Erase(RAMCFG_HandleTypeDef *hramcfg); +/** + * @} + */ + +/** @defgroup RAMCFG_Exported_Functions_Group6 Handle Interrupt and Callbacks Functions + * @brief Handle Interrupt and Callbacks Functions + * @{ + */ +void HAL_RAMCFG_IRQHandler(RAMCFG_HandleTypeDef *hramcfg); +void HAL_RAMCFG_DetectSingleErrorCallback(RAMCFG_HandleTypeDef *hramcfg); +void HAL_RAMCFG_DetectDoubleErrorCallback(RAMCFG_HandleTypeDef *hramcfg); +#if (USE_HAL_RAMCFG_REGISTER_CALLBACKS == 1) +HAL_StatusTypeDef HAL_RAMCFG_RegisterCallback(RAMCFG_HandleTypeDef *hramcfg, + HAL_RAMCFG_CallbackIDTypeDef CallbackID, + void (* pCallback)(RAMCFG_HandleTypeDef *_hramcfg)); +HAL_StatusTypeDef HAL_RAMCFG_UnRegisterCallback(RAMCFG_HandleTypeDef *hramcfg, HAL_RAMCFG_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_RAMCFG_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @defgroup RAMCFG_Exported_Functions_Group7 State and Error Functions + * @brief State and Error Functions + * @{ + */ +uint32_t HAL_RAMCFG_GetError(const RAMCFG_HandleTypeDef *hramcfg); +HAL_RAMCFG_StateTypeDef HAL_RAMCFG_GetState(const RAMCFG_HandleTypeDef *hramcfg); +/** + * @} + */ + +/** + * @} + */ + + +/* Private Constants ---------------------------------------------------------*/ + +/** @defgroup RAMCFG_Private_Constants RAMCFG Private Defines and Constants + * @brief RAMCFG Private Defines and Constants + * @{ + */ +/** + * @} + */ + + +/* Private macros ------------------------------------------------------------*/ + +/** @defgroup RAMCFG_Private_Macros RAMCFG Private Macros + * @brief RAMCFG Private Macros + * @{ + */ +#define IS_RAMCFG_INTERRUPT(INTERRUPT) \ + (((INTERRUPT) != 0U) && (((INTERRUPT) & ~(RAMCFG_IT_SINGLEERR | RAMCFG_IT_DOUBLEERR | RAMCFG_IT_NMIERR)) == 0U)) + + +#define IS_RAMCFG_WRITEPROTECTION_PAGE(PAGE) ((PAGE) <= 64U) + + +/** + * @} + */ + + +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup RAMCFG_Private_Functions RAMCFG Private Functions + * @brief RAMCFG Private Functions + * @{ + */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_RAMCFG_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_rcc.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_rcc.h new file mode 100644 index 0000000000..928a296f61 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_rcc.h @@ -0,0 +1,5169 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_rcc.h + * @author MCD Application Team + * @brief Header file of RCC HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32H5xx_HAL_RCC_H +#define __STM32H5xx_HAL_RCC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup RCC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup RCC_Exported_Types RCC Exported Types + * @{ + */ + +/** + * @brief RCC PLL1 configuration structure definition + */ +typedef struct +{ + uint32_t PLLState; /*!< PLLState: The new state of the PLL1. + This parameter can be a value of @ref RCC_PLL1_Config */ + + uint32_t PLLSource; /*!< PLLSource: PLL entry clock source. + This parameter must be a value of @ref RCC_PLL1_Clock_Source */ + + uint32_t PLLM; /*!< PLLM: Division factor for PLL1 VCO input clock. + This parameter must be a number between Min_Data = 0 and Max_Data = 63 */ + + uint32_t PLLN; /*!< PLLN: Multiplication factor for PLL1 VCO output clock. + This parameter must be a number between Min_Data = 4 and Max_Data = 512 */ + + uint32_t PLLP; /*!< PLLP: Division factor for system clock. + This parameter must be a number between Min_Data = 2 and Max_Data = 128 + odd division factors are not allowed */ + + uint32_t PLLQ; /*!< PLLQ: Division factor for peripheral clocks. + This parameter must be a number between Min_Data = 1 and Max_Data = 128 */ + + uint32_t PLLR; /*!< PLLR: Division factor for peripheral clocks. + This parameter must be a number between Min_Data = 1 and Max_Data = 128 */ + + uint32_t PLLRGE; /*!< PLLRGE: PLL1 clock Input range + This parameter must be a value of @ref RCC_PLL1_VCI_Range */ + + uint32_t PLLVCOSEL; /*!< PLLVCOSEL: PLL1 clock Output range + This parameter must be a value of @ref RCC_PLL1_VCO_Range */ + + uint32_t PLLFRACN; /*!< PLLFRACN: Specifies Fractional Part Of The Multiplication Factor for + PLL1 VCO It should be a value between 0 and 8191 */ + +} RCC_PLLInitTypeDef; + +/** + * @brief RCC Internal/External Oscillator (HSE, HSI, CSI, LSE and LSI) configuration structure definition + */ +typedef struct +{ + uint32_t OscillatorType; /*!< The oscillators to be configured. + This parameter can be a value of @ref RCC_Oscillator_Type */ + + uint32_t HSEState; /*!< The new state of the HSE. + This parameter can be a value of @ref RCC_HSE_Config */ + + uint32_t LSEState; /*!< The new state of the LSE. + This parameter can be a value of @ref RCC_LSE_Config */ + + uint32_t HSIState; /*!< The new state of the HSI. + This parameter can be a value of @ref RCC_HSI_Config */ + + uint32_t HSIDiv; /*!< The division factor of the HSI. + This parameter can be a value of @ref RCC_HSI_Div */ + + uint32_t HSICalibrationValue; /*!< The calibration trimming value (default is RCC_HSICALIBRATION_DEFAULT). + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0x7F + on the other devices */ + + uint32_t LSIState; /*!< The new state of the LSI. + This parameter can be a value of @ref RCC_LSI_Config */ + + uint32_t CSIState; /*!< The new state of the CSI. + This parameter can be a value of @ref RCC_CSI_Config */ + + uint32_t CSICalibrationValue; /*!< The calibration trimming value (default is RCC_CSICALIBRATION_DEFAULT). + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0x3F */ + + uint32_t HSI48State; /*!< The new state of the HSI48. + This parameter can be a value of @ref RCC_HSI48_Config */ + + RCC_PLLInitTypeDef PLL; /*!< PLL1 structure parameters */ + +} RCC_OscInitTypeDef; + +/** + * @brief RCC System, AHB and APB busses clock configuration structure definition + */ +typedef struct +{ + uint32_t ClockType; /*!< The clock to be configured. + This parameter can be a value of @ref RCC_System_Clock_Type */ + + uint32_t SYSCLKSource; /*!< The clock source used as system clock (SYSCLK). + This parameter can be a value of @ref RCC_System_Clock_Source */ + + uint32_t AHBCLKDivider; /*!< The AHB clock (HCLK) divider. This clock is derived from the system clock (SYSCLK). + This parameter can be a value of @ref RCC_AHB_Clock_Source */ + + uint32_t APB1CLKDivider; /*!< The APB1 clock (PCLK1) divider. This clock is derived from the AHB clock (HCLK). + This parameter can be a value of @ref RCC_APB1_APB2_APB3_Clock_Source */ + + uint32_t APB2CLKDivider; /*!< The APB2 clock (PCLK2) divider. This clock is derived from the AHB clock (HCLK). + This parameter can be a value of @ref RCC_APB1_APB2_APB3_Clock_Source */ + + uint32_t APB3CLKDivider; /*!< The APB3 clock (PCLK3) divider. This clock is derived from the AHB clock (HCLK). + This parameter can be a value of @ref RCC_APB1_APB2_APB3_Clock_Source */ +} RCC_ClkInitTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup RCC_Exported_Constants RCC Exported Constants + * @{ + */ + +/** @defgroup RCC_Peripheral_Memory_Mapping Peripheral Memory Mapping + * @{ + */ + +/** + * @} + */ + +/** @defgroup RCC_Oscillator_Type Oscillator Type + * @{ + */ +#define RCC_OSCILLATORTYPE_NONE (0x00000000U) /*!< Oscillator configuration unchanged */ +#define RCC_OSCILLATORTYPE_HSE (0x00000001U) /*!< HSE to configure */ +#define RCC_OSCILLATORTYPE_HSI (0x00000002U) /*!< HSI to configure */ +#define RCC_OSCILLATORTYPE_LSE (0x00000004U) /*!< LSE to configure */ +#define RCC_OSCILLATORTYPE_LSI (0x00000008U) /*!< LSI to configure */ +#define RCC_OSCILLATORTYPE_CSI (0x00000010U) /*!< CSI to configure */ +#define RCC_OSCILLATORTYPE_HSI48 (0x00000020U) /*!< HSI48 to configure */ +/** + * @} + */ + +/** @defgroup RCC_HSE_Config HSE Config + * @{ + */ +#define RCC_HSE_OFF (0x00000000U) /*!< HSE clock deactivation */ +#define RCC_HSE_ON RCC_CR_HSEON /*!< HSE clock activation */ +#define RCC_HSE_BYPASS ((uint32_t)(RCC_CR_HSEBYP | RCC_CR_HSEON)) /*!< External Analog clock source for HSE clock */ +#define RCC_HSE_BYPASS_DIGITAL ((uint32_t)(RCC_CR_HSEEXT | RCC_CR_HSEBYP | RCC_CR_HSEON)) /*!< External Digital clock source for HSE clock */ +/** + * @} + */ + +/** @defgroup RCC_LSE_Config LSE Config + * @{ + */ +#define RCC_LSE_OFF 0U /*!< LSE clock deactivation */ +#define RCC_LSE_ON RCC_BDCR_LSEON /*!< LSE clock activation */ +#define RCC_LSE_BYPASS ((uint32_t)(RCC_BDCR_LSEBYP | RCC_BDCR_LSEON)) /*!< External Analog clock source for LSE clock */ +#define RCC_LSE_BYPASS_DIGITAL ((uint32_t)(RCC_BDCR_LSEEXT | RCC_BDCR_LSEBYP | RCC_BDCR_LSEON)) /*!< External Digital clock source for LSE clock */ +/** + * @} + */ + +/** @defgroup RCC_HSI_Config HSI Config + * @{ + */ +#define RCC_HSI_OFF 0x00000000U /*!< HSI clock deactivation */ +#define RCC_HSI_ON RCC_CR_HSION /*!< HSI clock activation */ + +#define RCC_HSICALIBRATION_DEFAULT (0x40U) /* Default HSI calibration trimming value */ +/** + * @} + */ + +/** @defgroup RCC_HSI_Div HSI Div + * @{ + */ +#define RCC_HSI_DIV1 0x00000000U /*!< HSI clock is not divided */ +#define RCC_HSI_DIV2 RCC_CR_HSIDIV_0 /*!< HSI clock is divided by 2 */ +#define RCC_HSI_DIV4 RCC_CR_HSIDIV_1 /*!< HSI clock is divided by 4 */ +#define RCC_HSI_DIV8 (RCC_CR_HSIDIV_1|RCC_CR_HSIDIV_0) /*!< HSI clock is divided by 8 */ +/** + * @} + */ + +/** @defgroup RCC_LSI_Config LSI Config + * @{ + */ +#define RCC_LSI_OFF (0x00000000U) /*!< LSI clock deactivation */ +#define RCC_LSI_ON RCC_BDCR_LSION /*!< LSI clock activation */ +/** + * @} + */ + +/** @defgroup RCC_CSI_Config CSI Config + * @{ + */ +#define RCC_CSI_OFF (0x00000000U) /*!< CSI clock deactivation */ +#define RCC_CSI_ON RCC_CR_CSION /*!< CSI clock activation */ + +#define RCC_CSICALIBRATION_DEFAULT (0x20U) /*!< Default CSI calibration trimming value */ +/** + * @} + */ + +/** @defgroup RCC_HSI48_Config HSI48 Config + * @{ + */ +#define RCC_HSI48_OFF (0x00000000U) /*!< HSI48 clock deactivation */ +#define RCC_HSI48_ON RCC_CR_HSI48ON /*!< HSI48 clock activation */ +/** + * @} + */ + +/** @defgroup RCC_PLL1_Config RCC PLL1 Config + * @{ + */ +#define RCC_PLL_NONE (0x00000000U) +#define RCC_PLL_OFF (0x00000001U) +#define RCC_PLL_ON (0x00000002U) +/** + * @} + */ + +/** @defgroup RCC_PLL1_Clock_Output RCC PLL1 Clock Output + * @{ + */ +#define RCC_PLL1_DIVP RCC_PLL1CFGR_PLL1PEN +#define RCC_PLL1_DIVQ RCC_PLL1CFGR_PLL1QEN +#define RCC_PLL1_DIVR RCC_PLL1CFGR_PLL1REN +/** + * @} + */ + +/** @defgroup RCC_PLL1_VCI_Range RCC PLL1 VCI Range + * @{ + */ +#define RCC_PLL1_VCIRANGE_0 (0x00000000U) /*!< Clock range frequency between 1 and 2 MHz */ +#define RCC_PLL1_VCIRANGE_1 RCC_PLL1CFGR_PLL1RGE_0 /*!< Clock range frequency between 2 and 4 MHz */ +#define RCC_PLL1_VCIRANGE_2 RCC_PLL1CFGR_PLL1RGE_1 /*!< Clock range frequency between 4 and 8 MHz */ +#define RCC_PLL1_VCIRANGE_3 (RCC_PLL1CFGR_PLL1RGE_0 | RCC_PLL1CFGR_PLL1RGE_1) /*!< Clock range frequency between 8 and 16 MHz */ +/** + * @} + */ + +/** @defgroup RCC_PLL1_VCO_Range RCC PLL1 VCO Range + * @{ + */ +#define RCC_PLL1_VCORANGE_WIDE (0x00000000U) /*!< Clock range frequency between 192 and 836 MHz */ +#define RCC_PLL1_VCORANGE_MEDIUM RCC_PLL1CFGR_PLL1VCOSEL /*!< Clock range frequency between 150 and 420 MHz */ + +/** + * @} + */ + +/** @defgroup RCC_PLL1_Clock_Source RCC PLL1 Clock Source + * @{ + */ +#define RCC_PLL1_SOURCE_NONE (0x00000000U) +#define RCC_PLL1_SOURCE_HSI RCC_PLL1CFGR_PLL1SRC_0 +#define RCC_PLL1_SOURCE_CSI RCC_PLL1CFGR_PLL1SRC_1 +#define RCC_PLL1_SOURCE_HSE (RCC_PLL1CFGR_PLL1SRC_0 | RCC_PLL1CFGR_PLL1SRC_1) +/** + * @} + */ + + +/** @defgroup RCC_System_Clock_Type System Clock Type + * @{ + */ +#define RCC_CLOCKTYPE_SYSCLK (0x00000001U) /*!< SYSCLK to configure */ +#define RCC_CLOCKTYPE_HCLK (0x00000002U) /*!< HCLK to configure */ +#define RCC_CLOCKTYPE_PCLK1 (0x00000004U) /*!< PCLK1 to configure */ +#define RCC_CLOCKTYPE_PCLK2 (0x00000008U) /*!< PCLK2 to configure */ +#define RCC_CLOCKTYPE_PCLK3 (0x00000010U) /*!< PCLK3 to configure */ +/** + * @} + */ + +/** @defgroup RCC_System_Clock_Source System Clock Source + * @{ + */ +#define RCC_SYSCLKSOURCE_HSI (0x00000000U) /*!< HSI selection as system clock */ +#define RCC_SYSCLKSOURCE_CSI RCC_CFGR1_SW_0 /*!< CSI selection as system clock */ +#define RCC_SYSCLKSOURCE_HSE RCC_CFGR1_SW_1 /*!< HSE selection as system clock */ +#define RCC_SYSCLKSOURCE_PLLCLK (RCC_CFGR1_SW_0 | RCC_CFGR1_SW_1) /*!< PLL1 selection as system clock */ +/** + * @} + */ + +/** @defgroup RCC_System_Clock_Source_Status System Clock Source Status + * @{ + */ +#define RCC_SYSCLKSOURCE_STATUS_HSI (0x00000000U) /*!< HSI used as system clock */ +#define RCC_SYSCLKSOURCE_STATUS_CSI RCC_CFGR1_SWS_0 /*!< CSI used as system clock */ +#define RCC_SYSCLKSOURCE_STATUS_HSE RCC_CFGR1_SWS_1 /*!< HSE used as system clock */ +#define RCC_SYSCLKSOURCE_STATUS_PLLCLK (RCC_CFGR1_SWS_0 | RCC_CFGR1_SWS_1) /*!< PLL1 used as system clock */ +/** + * @} + */ + +/** @defgroup RCC_AHB_Clock_Source AHB Clock Source + * @{ + */ +#define RCC_SYSCLK_DIV1 (0x00000000U) /*!< SYSCLK not divided */ +#define RCC_SYSCLK_DIV2 RCC_CFGR2_HPRE_3 /*!< SYSCLK divided by 2 */ +#define RCC_SYSCLK_DIV4 (RCC_CFGR2_HPRE_0 | RCC_CFGR2_HPRE_3) /*!< SYSCLK divided by 4 */ +#define RCC_SYSCLK_DIV8 (RCC_CFGR2_HPRE_1 | RCC_CFGR2_HPRE_3) /*!< SYSCLK divided by 8 */ +#define RCC_SYSCLK_DIV16 (RCC_CFGR2_HPRE_0 | RCC_CFGR2_HPRE_1 | RCC_CFGR2_HPRE_3) /*!< SYSCLK divided by 16 */ +#define RCC_SYSCLK_DIV64 (RCC_CFGR2_HPRE_2 | RCC_CFGR2_HPRE_3) /*!< SYSCLK divided by 64 */ +#define RCC_SYSCLK_DIV128 (RCC_CFGR2_HPRE_0 | RCC_CFGR2_HPRE_2 | RCC_CFGR2_HPRE_3) /*!< SYSCLK divided by 128 */ +#define RCC_SYSCLK_DIV256 (RCC_CFGR2_HPRE_1 | RCC_CFGR2_HPRE_2 | RCC_CFGR2_HPRE_3) /*!< SYSCLK divided by 256 */ +#define RCC_SYSCLK_DIV512 (RCC_CFGR2_HPRE_0 | RCC_CFGR2_HPRE_1 | RCC_CFGR2_HPRE_2 | RCC_CFGR2_HPRE_3) /*!< SYSCLK divided by 512 */ +/** + * @} + */ + +/** @defgroup RCC_APB1_APB2_APB3_Clock_Source APB1 APB2 APB3 Clock Source + * @{ + */ +#define RCC_HCLK_DIV1 (0x00000000U) /*!< HCLK not divided */ +#define RCC_HCLK_DIV2 RCC_CFGR2_PPRE1_2 /*!< HCLK divided by 2 */ +#define RCC_HCLK_DIV4 (RCC_CFGR2_PPRE1_0 | RCC_CFGR2_PPRE1_2) /*!< HCLK divided by 4 */ +#define RCC_HCLK_DIV8 (RCC_CFGR2_PPRE1_1 | RCC_CFGR2_PPRE1_2) /*!< HCLK divided by 8 */ +#define RCC_HCLK_DIV16 (RCC_CFGR2_PPRE1_0 | RCC_CFGR2_PPRE1_1 | RCC_CFGR2_PPRE1_2) /*!< HCLK divided by 16 */ +/** + * @} + */ + +/** @defgroup RCC_HAL_EC_RTC_HSE_DIV RTC HSE Prescaler + * @{ + */ +#define RCC_RTC_HSE_NOCLOCK (0x00000000U) +#define RCC_RTC_HSE_DIV2 (0x00000200U) +#define RCC_RTC_HSE_DIV3 (0x00000300U) +#define RCC_RTC_HSE_DIV4 (0x00000400U) +#define RCC_RTC_HSE_DIV5 (0x00000500U) +#define RCC_RTC_HSE_DIV6 (0x00000600U) +#define RCC_RTC_HSE_DIV7 (0x00000700U) +#define RCC_RTC_HSE_DIV8 (0x00000800U) +#define RCC_RTC_HSE_DIV9 (0x00000900U) +#define RCC_RTC_HSE_DIV10 (0x00000A00U) +#define RCC_RTC_HSE_DIV11 (0x00000B00U) +#define RCC_RTC_HSE_DIV12 (0x00000C00U) +#define RCC_RTC_HSE_DIV13 (0x00000D00U) +#define RCC_RTC_HSE_DIV14 (0x00000E00U) +#define RCC_RTC_HSE_DIV15 (0x00000F00U) +#define RCC_RTC_HSE_DIV16 (0x00001000U) +#define RCC_RTC_HSE_DIV17 (0x00001100U) +#define RCC_RTC_HSE_DIV18 (0x00001200U) +#define RCC_RTC_HSE_DIV19 (0x00001300U) +#define RCC_RTC_HSE_DIV20 (0x00001400U) +#define RCC_RTC_HSE_DIV21 (0x00001500U) +#define RCC_RTC_HSE_DIV22 (0x00001600U) +#define RCC_RTC_HSE_DIV23 (0x00001700U) +#define RCC_RTC_HSE_DIV24 (0x00001800U) +#define RCC_RTC_HSE_DIV25 (0x00001900U) +#define RCC_RTC_HSE_DIV26 (0x00001A00U) +#define RCC_RTC_HSE_DIV27 (0x00001B00U) +#define RCC_RTC_HSE_DIV28 (0x00001C00U) +#define RCC_RTC_HSE_DIV29 (0x00001D00U) +#define RCC_RTC_HSE_DIV30 (0x00001E00U) +#define RCC_RTC_HSE_DIV31 (0x00001F00U) +#define RCC_RTC_HSE_DIV32 (0x00002000U) +#define RCC_RTC_HSE_DIV33 (0x00002100U) +#define RCC_RTC_HSE_DIV34 (0x00002200U) +#define RCC_RTC_HSE_DIV35 (0x00002300U) +#define RCC_RTC_HSE_DIV36 (0x00002400U) +#define RCC_RTC_HSE_DIV37 (0x00002500U) +#define RCC_RTC_HSE_DIV38 (0x00002600U) +#define RCC_RTC_HSE_DIV39 (0x00002700U) +#define RCC_RTC_HSE_DIV40 (0x00002800U) +#define RCC_RTC_HSE_DIV41 (0x00002900U) +#define RCC_RTC_HSE_DIV42 (0x00002A00U) +#define RCC_RTC_HSE_DIV43 (0x00002B00U) +#define RCC_RTC_HSE_DIV44 (0x00002C00U) +#define RCC_RTC_HSE_DIV45 (0x00002D00U) +#define RCC_RTC_HSE_DIV46 (0x00002E00U) +#define RCC_RTC_HSE_DIV47 (0x00002F00U) +#define RCC_RTC_HSE_DIV48 (0x00003000U) +#define RCC_RTC_HSE_DIV49 (0x00003100U) +#define RCC_RTC_HSE_DIV50 (0x00003200U) +#define RCC_RTC_HSE_DIV51 (0x00003300U) +#define RCC_RTC_HSE_DIV52 (0x00003400U) +#define RCC_RTC_HSE_DIV53 (0x00003500U) +#define RCC_RTC_HSE_DIV54 (0x00003600U) +#define RCC_RTC_HSE_DIV55 (0x00003700U) +#define RCC_RTC_HSE_DIV56 (0x00003800U) +#define RCC_RTC_HSE_DIV57 (0x00003900U) +#define RCC_RTC_HSE_DIV58 (0x00003A00U) +#define RCC_RTC_HSE_DIV59 (0x00003B00U) +#define RCC_RTC_HSE_DIV60 (0x00003C00U) +#define RCC_RTC_HSE_DIV61 (0x00003D00U) +#define RCC_RTC_HSE_DIV62 (0x00003E00U) +#define RCC_RTC_HSE_DIV63 (0x00003F00U) +/** + * @} + */ + +/** @defgroup RCC_RTC_Clock_Source RTC Clock Source + * @{ + */ +#define RCC_RTCCLKSOURCE_NO_CLK (0x00000000U) /*!< No clock used as RTC clock source */ +#define RCC_RTCCLKSOURCE_LSE (0x00000100U) /*!< LSE oscillator clock used as RTC clock source */ +#define RCC_RTCCLKSOURCE_LSI (0x00000200U) /*!< LSI oscillator clock used as RTC clock source */ +#define RCC_RTCCLKSOURCE_HSE_DIVx (0x00000300U) /*!< HSE oscillator clock divided by X used as RTC clock source */ +#define RCC_RTCCLKSOURCE_HSE_DIV2 (0x00002300U) +#define RCC_RTCCLKSOURCE_HSE_DIV3 (0x00003300U) +#define RCC_RTCCLKSOURCE_HSE_DIV4 (0x00004300U) +#define RCC_RTCCLKSOURCE_HSE_DIV5 (0x00005300U) +#define RCC_RTCCLKSOURCE_HSE_DIV6 (0x00006300U) +#define RCC_RTCCLKSOURCE_HSE_DIV7 (0x00007300U) +#define RCC_RTCCLKSOURCE_HSE_DIV8 (0x00008300U) +#define RCC_RTCCLKSOURCE_HSE_DIV9 (0x00009300U) +#define RCC_RTCCLKSOURCE_HSE_DIV10 (0x0000A300U) +#define RCC_RTCCLKSOURCE_HSE_DIV11 (0x0000B300U) +#define RCC_RTCCLKSOURCE_HSE_DIV12 (0x0000C300U) +#define RCC_RTCCLKSOURCE_HSE_DIV13 (0x0000D300U) +#define RCC_RTCCLKSOURCE_HSE_DIV14 (0x0000E300U) +#define RCC_RTCCLKSOURCE_HSE_DIV15 (0x0000F300U) +#define RCC_RTCCLKSOURCE_HSE_DIV16 (0x00010300U) +#define RCC_RTCCLKSOURCE_HSE_DIV17 (0x00011300U) +#define RCC_RTCCLKSOURCE_HSE_DIV18 (0x00012300U) +#define RCC_RTCCLKSOURCE_HSE_DIV19 (0x00013300U) +#define RCC_RTCCLKSOURCE_HSE_DIV20 (0x00014300U) +#define RCC_RTCCLKSOURCE_HSE_DIV21 (0x00015300U) +#define RCC_RTCCLKSOURCE_HSE_DIV22 (0x00016300U) +#define RCC_RTCCLKSOURCE_HSE_DIV23 (0x00017300U) +#define RCC_RTCCLKSOURCE_HSE_DIV24 (0x00018300U) +#define RCC_RTCCLKSOURCE_HSE_DIV25 (0x00019300U) +#define RCC_RTCCLKSOURCE_HSE_DIV26 (0x0001A300U) +#define RCC_RTCCLKSOURCE_HSE_DIV27 (0x0001B300U) +#define RCC_RTCCLKSOURCE_HSE_DIV28 (0x0001C300U) +#define RCC_RTCCLKSOURCE_HSE_DIV29 (0x0001D300U) +#define RCC_RTCCLKSOURCE_HSE_DIV30 (0x0001E300U) +#define RCC_RTCCLKSOURCE_HSE_DIV31 (0x0001F300U) +#define RCC_RTCCLKSOURCE_HSE_DIV32 (0x00020300U) +#define RCC_RTCCLKSOURCE_HSE_DIV33 (0x00021300U) +#define RCC_RTCCLKSOURCE_HSE_DIV34 (0x00022300U) +#define RCC_RTCCLKSOURCE_HSE_DIV35 (0x00023300U) +#define RCC_RTCCLKSOURCE_HSE_DIV36 (0x00024300U) +#define RCC_RTCCLKSOURCE_HSE_DIV37 (0x00025300U) +#define RCC_RTCCLKSOURCE_HSE_DIV38 (0x00026300U) +#define RCC_RTCCLKSOURCE_HSE_DIV39 (0x00027300U) +#define RCC_RTCCLKSOURCE_HSE_DIV40 (0x00028300U) +#define RCC_RTCCLKSOURCE_HSE_DIV41 (0x00029300U) +#define RCC_RTCCLKSOURCE_HSE_DIV42 (0x0002A300U) +#define RCC_RTCCLKSOURCE_HSE_DIV43 (0x0002B300U) +#define RCC_RTCCLKSOURCE_HSE_DIV44 (0x0002C300U) +#define RCC_RTCCLKSOURCE_HSE_DIV45 (0x0002D300U) +#define RCC_RTCCLKSOURCE_HSE_DIV46 (0x0002E300U) +#define RCC_RTCCLKSOURCE_HSE_DIV47 (0x0002F300U) +#define RCC_RTCCLKSOURCE_HSE_DIV48 (0x00030300U) +#define RCC_RTCCLKSOURCE_HSE_DIV49 (0x00031300U) +#define RCC_RTCCLKSOURCE_HSE_DIV50 (0x00032300U) +#define RCC_RTCCLKSOURCE_HSE_DIV51 (0x00033300U) +#define RCC_RTCCLKSOURCE_HSE_DIV52 (0x00034300U) +#define RCC_RTCCLKSOURCE_HSE_DIV53 (0x00035300U) +#define RCC_RTCCLKSOURCE_HSE_DIV54 (0x00036300U) +#define RCC_RTCCLKSOURCE_HSE_DIV55 (0x00037300U) +#define RCC_RTCCLKSOURCE_HSE_DIV56 (0x00038300U) +#define RCC_RTCCLKSOURCE_HSE_DIV57 (0x00039300U) +#define RCC_RTCCLKSOURCE_HSE_DIV58 (0x0003A300U) +#define RCC_RTCCLKSOURCE_HSE_DIV59 (0x0003B300U) +#define RCC_RTCCLKSOURCE_HSE_DIV60 (0x0003C300U) +#define RCC_RTCCLKSOURCE_HSE_DIV61 (0x0003D300U) +#define RCC_RTCCLKSOURCE_HSE_DIV62 (0x0003E300U) +#define RCC_RTCCLKSOURCE_HSE_DIV63 (0x0003F300U) +/** + * @} + */ + +/** @defgroup RCC_MCO_Index MCO Index + * @{ + */ +#define RCC_MCO1 (0x00000000U) +#define RCC_MCO2 (0x00000001U) +/** + * @} + */ + +/** @defgroup RCC_MCO1_Clock_Source RCC MCO1 Clock Source + * @{ + */ +#define RCC_MCO1SOURCE_HSI (0x00000000U) +#define RCC_MCO1SOURCE_LSE RCC_CFGR1_MCO1SEL_0 +#define RCC_MCO1SOURCE_HSE RCC_CFGR1_MCO1SEL_1 +#define RCC_MCO1SOURCE_PLL1Q ((uint32_t)RCC_CFGR1_MCO1SEL_0 | RCC_CFGR1_MCO1SEL_1) +#define RCC_MCO1SOURCE_HSI48 RCC_CFGR1_MCO1SEL_2 + +/** + * @} + */ + +/** @defgroup RCC_MCO2_Clock_Source RCC MCO2 Clock Source + * @{ + */ +#define RCC_MCO2SOURCE_SYSCLK (0x00000000U) +#define RCC_MCO2SOURCE_PLL2P RCC_CFGR1_MCO2SEL_0 +#define RCC_MCO2SOURCE_HSE RCC_CFGR1_MCO2SEL_1 +#define RCC_MCO2SOURCE_PLL1P ((uint32_t)RCC_CFGR1_MCO2SEL_0 | RCC_CFGR1_MCO2SEL_1) +#define RCC_MCO2SOURCE_CSI RCC_CFGR1_MCO2SEL_2 +#define RCC_MCO2SOURCE_LSI ((uint32_t)RCC_CFGR1_MCO2SEL_0 | RCC_CFGR1_MCO2SEL_2) + +/** + * @} + */ + +/** @defgroup RCC_MCOx_Clock_Prescaler MCOx Clock Prescaler + * @{ + */ +#define RCC_MCODIV_1 RCC_CFGR1_MCO1PRE_0 +#define RCC_MCODIV_2 RCC_CFGR1_MCO1PRE_1 +#define RCC_MCODIV_3 ((uint32_t)RCC_CFGR1_MCO1PRE_0 | RCC_CFGR1_MCO1PRE_1) +#define RCC_MCODIV_4 RCC_CFGR1_MCO1PRE_2 +#define RCC_MCODIV_5 ((uint32_t)RCC_CFGR1_MCO1PRE_0 | RCC_CFGR1_MCO1PRE_2) +#define RCC_MCODIV_6 ((uint32_t)RCC_CFGR1_MCO1PRE_1 | RCC_CFGR1_MCO1PRE_2) +#define RCC_MCODIV_7 ((uint32_t)RCC_CFGR1_MCO1PRE_0 | RCC_CFGR1_MCO1PRE_1 | RCC_CFGR1_MCO1PRE_2) +#define RCC_MCODIV_8 RCC_CFGR1_MCO1PRE_3 +#define RCC_MCODIV_9 ((uint32_t)RCC_CFGR1_MCO1PRE_0 | RCC_CFGR1_MCO1PRE_3) +#define RCC_MCODIV_10 ((uint32_t)RCC_CFGR1_MCO1PRE_1 | RCC_CFGR1_MCO1PRE_3) +#define RCC_MCODIV_11 ((uint32_t)RCC_CFGR1_MCO1PRE_0 | RCC_CFGR1_MCO1PRE_1 | RCC_CFGR1_MCO1PRE_3) +#define RCC_MCODIV_12 ((uint32_t)RCC_CFGR1_MCO1PRE_2 | RCC_CFGR1_MCO1PRE_3) +#define RCC_MCODIV_13 ((uint32_t)RCC_CFGR1_MCO1PRE_0 | RCC_CFGR1_MCO1PRE_2 | RCC_CFGR1_MCO1PRE_3) +#define RCC_MCODIV_14 ((uint32_t)RCC_CFGR1_MCO1PRE_1 | RCC_CFGR1_MCO1PRE_2 | RCC_CFGR1_MCO1PRE_3) +#define RCC_MCODIV_15 RCC_CFGR1_MCO1PRE +/** + * @} + */ + +/** @defgroup RCC_Interrupt Interrupts + * @{ + */ +#define RCC_IT_LSIRDY RCC_CIFR_LSIRDYF /*!< LSI Ready Interrupt flag */ +#define RCC_IT_LSERDY RCC_CIFR_LSERDYF /*!< LSE Ready Interrupt flag */ +#define RCC_IT_CSIRDY RCC_CIFR_CSIRDYF /*!< CSI Ready Interrupt flag */ +#define RCC_IT_HSIRDY RCC_CIFR_HSIRDYF /*!< HSI16 Ready Interrupt flag */ +#define RCC_IT_HSERDY RCC_CIFR_HSERDYF /*!< HSE Ready Interrupt flag */ +#define RCC_IT_HSI48RDY RCC_CIFR_HSI48RDYF /*!< HSI48 Ready Interrupt flag */ +#define RCC_IT_PLL1RDY RCC_CIFR_PLL1RDYF /*!< PLL1 Ready Interrupt flag */ +#define RCC_IT_PLL2RDY RCC_CIFR_PLL2RDYF /*!< PLL2 Ready Interrupt flag */ +#if defined(RCC_CR_PLL3ON) +#define RCC_IT_PLL3RDY RCC_CIFR_PLL3RDYF /*!< PLL3 Ready Interrupt flag */ +#endif /* RCC_CR_PLL3ON */ +#define RCC_IT_HSECSS RCC_CIFR_HSECSSF /*!< HSE Clock Security System Interrupt flag */ + +/** + * @} + */ + +/** @defgroup RCC_Flag Flags + * Elements values convention: XXXYYYYYb + * - YYYYY : Flag position in the register + * - XXX : Register index + * - 001: CR register + * - 010: BDCR register + * - 011: RSR register + * @{ + */ +/* Flags in the CR register */ +#define RCC_FLAG_CSIRDY ((uint32_t)((RCC_CR_REG_INDEX << 5U) | RCC_CR_CSIRDY_Pos)) /*!< CSI Ready flag */ +#define RCC_FLAG_HSIRDY ((uint32_t)((RCC_CR_REG_INDEX << 5U) | RCC_CR_HSIRDY_Pos)) /*!< HSI Ready flag */ +#define RCC_FLAG_HSIDIVF ((uint32_t)((RCC_CR_REG_INDEX << 5U) | RCC_CR_HSIDIVF_Pos)) /*!< HSI divider flag */ +#define RCC_FLAG_HSERDY ((uint32_t)((RCC_CR_REG_INDEX << 5U) | RCC_CR_HSERDY_Pos)) /*!< HSE Ready flag */ +#define RCC_FLAG_PLL1RDY ((uint32_t)((RCC_CR_REG_INDEX << 5U) | RCC_CR_PLL1RDY_Pos)) /*!< PLL1 Ready flag */ +#define RCC_FLAG_PLL2RDY ((uint32_t)((RCC_CR_REG_INDEX << 5U) | RCC_CR_PLL2RDY_Pos)) /*!< PLL2 Ready flag */ +#if defined(RCC_CR_PLL3ON) +#define RCC_FLAG_PLL3RDY ((uint32_t)((RCC_CR_REG_INDEX << 5U) | RCC_CR_PLL3RDY_Pos)) /*!< PLL3 Ready flag */ +#endif /* RCC_CR_PLL3ON */ +#define RCC_FLAG_HSI48RDY ((uint32_t)((RCC_CR_REG_INDEX << 5U) | RCC_CR_HSI48RDY_Pos)) /*!< HSI48 Ready flag */ + +/* Flags in the BDCR register */ +#define RCC_FLAG_LSERDY ((uint32_t)((RCC_BDCR_REG_INDEX << 5U) | RCC_BDCR_LSERDY_Pos)) /*!< LSE Ready flag */ +#define RCC_FLAG_LSECSSD ((uint32_t)((RCC_BDCR_REG_INDEX << 5U) | RCC_BDCR_LSECSSD_Pos)) /*!< LSE Clock Security System Interrupt flag */ +#define RCC_FLAG_LSIRDY ((uint32_t)((RCC_BDCR_REG_INDEX << 5U) | RCC_BDCR_LSIRDY_Pos)) /*!< LSI Ready flag */ + +/* Flags in the RSR register */ +#define RCC_FLAG_RMVF ((uint32_t)((RCC_RSR_REG_INDEX << 5U) | RCC_RSR_RMVF_Pos)) /*!< Remove reset flag */ +#define RCC_FLAG_PINRST ((uint32_t)((RCC_RSR_REG_INDEX << 5U) | RCC_RSR_PINRSTF_Pos)) /*!< PIN reset flag */ +#define RCC_FLAG_BORRST ((uint32_t)((RCC_RSR_REG_INDEX << 5U) | RCC_RSR_BORRSTF_Pos)) /*!< BOR reset flag */ +#define RCC_FLAG_SFTRST ((uint32_t)((RCC_RSR_REG_INDEX << 5U) | RCC_RSR_SFTRSTF_Pos)) /*!< Software Reset flag */ +#define RCC_FLAG_IWDGRST ((uint32_t)((RCC_RSR_REG_INDEX << 5U) | RCC_RSR_IWDGRSTF_Pos)) /*!< Independent Watchdog reset flag */ +#define RCC_FLAG_WWDGRST ((uint32_t)((RCC_RSR_REG_INDEX << 5U) | RCC_RSR_WWDGRSTF_Pos)) /*!< Window watchdog reset flag */ +#define RCC_FLAG_LPWRRST ((uint32_t)((RCC_RSR_REG_INDEX << 5U) | RCC_RSR_LPWRRSTF_Pos)) /*!< Low-Power reset flag */ + +/** + * @} + */ + +/** @defgroup RCC_Reset_Flag Reset Flag + * @{ + */ +#define RCC_RESET_FLAG_PIN RCC_RSR_PINRSTF /*!< PIN reset flag */ +#define RCC_RESET_FLAG_PWR RCC_RSR_BORRSTF /*!< BOR or POR/PDR reset flag */ +#define RCC_RESET_FLAG_SW RCC_RSR_SFTRSTF /*!< Software Reset flag */ +#define RCC_RESET_FLAG_IWDG RCC_RSR_IWDGRSTF /*!< Independent Watchdog reset flag */ +#define RCC_RESET_FLAG_WWDG RCC_RSR_WWDGRSTF /*!< Window watchdog reset flag */ +#define RCC_RESET_FLAG_LPWR RCC_RSR_LPWRRSTF /*!< Low power reset flag */ +#define RCC_RESET_FLAG_ALL (RCC_RESET_FLAG_PIN | RCC_RESET_FLAG_PWR | RCC_RESET_FLAG_SW | \ + RCC_RESET_FLAG_IWDG | RCC_RESET_FLAG_WWDG | RCC_RESET_FLAG_LPWR) +/** + * @} + */ + +/** @defgroup RCC_LSEDrive_Config LSE Drive Config + * @{ + */ +#define RCC_LSEDRIVE_LOW (0x00000000U) /*!< LSE low drive capability */ +#define RCC_LSEDRIVE_MEDIUMLOW RCC_BDCR_LSEDRV_0 /*!< LSE medium low drive capability */ +#define RCC_LSEDRIVE_MEDIUMHIGH RCC_BDCR_LSEDRV_1 /*!< LSE medium high drive capability */ +#define RCC_LSEDRIVE_HIGH RCC_BDCR_LSEDRV /*!< LSE high drive capability */ +/** + * @} + */ + +/** @defgroup RCC_Stop_WakeUpClock Wake-Up from STOP Clock + * @{ + */ +#define RCC_STOP_WAKEUPCLOCK_HSI (0x00000000U) /*!< HSI selection after wake-up from STOP */ +#define RCC_STOP_WAKEUPCLOCK_CSI RCC_CFGR1_STOPWUCK /*!< CSI selection after wake-up from STOP */ +/** + * @} + */ + +/** @defgroup RCC_Stop_KernelWakeUpClock RCC Stop KernelWakeUpClock + * @{ + */ +#define RCC_STOP_KERWAKEUPCLOCK_HSI (0x00000000U) /*!< HSI kernel clock selection after wake-up from STOP */ +#define RCC_STOP_KERWAKEUPCLOCK_CSI RCC_CFGR1_STOPKERWUCK /*!< CSI kernel clock selection after wake-up from STOP */ + +/** + * @} + */ + +#if defined(RCC_SECCFGR_HSISEC) +/** @defgroup RCC_items RCC items + * @brief RCC items to configure attributes on + * @{ + */ +#define RCC_HSI RCC_SECCFGR_HSISEC +#define RCC_HSE RCC_SECCFGR_HSESEC +#define RCC_CSI RCC_SECCFGR_CSISEC +#define RCC_LSI RCC_SECCFGR_LSISEC +#define RCC_LSE RCC_SECCFGR_LSESEC +#define RCC_SYSCLK RCC_SECCFGR_SYSCLKSEC +#define RCC_PRESC RCC_SECCFGR_PRESCSEC +#define RCC_PLL1 RCC_SECCFGR_PLL1SEC +#define RCC_PLL2 RCC_SECCFGR_PLL2SEC +#define RCC_PLL3 RCC_SECCFGR_PLL3SEC +#define RCC_HSI48 RCC_SECCFGR_HSI48SEC +#define RCC_RMVF RCC_SECCFGR_RMVFSEC +#define RCC_CKPERSEL RCC_SECCFGR_CKPERSELSEC +#define RCC_ALL (RCC_HSI|RCC_HSE|RCC_CSI|RCC_LSI|RCC_LSE|RCC_HSI48| \ + RCC_SYSCLK|RCC_PRESC|RCC_PLL1|RCC_PLL2| \ + RCC_PLL3|RCC_CKPERSEL|RCC_RMVF) +/** + * @} + */ +#endif /* RCC_SECCFGR_HSISEC */ + +/** @defgroup RCC_attributes RCC attributes + * @brief RCC privilege/non-privilege and secure/non-secure attributes + * @{ + */ +#if defined(RCC_PRIVCFGR_NSPRIV) +#define RCC_NSEC_PRIV 0x00000001U /*!< Non-secure Privilege attribute item */ +#define RCC_NSEC_NPRIV 0x00000002U /*!< Non-secure Non-privilege attribute item */ +#else +#define RCC_PRIV 0x00000001U /*!< Privilege attribute item */ +#define RCC_NPRIV 0x00000002U /*!< Non-privilege attribute item */ +#endif /* RCC_PRIVCFGR_NSPRIV */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define RCC_SEC_PRIV 0x00000010U /*!< Secure Privilege attribute item */ +#define RCC_SEC_NPRIV 0x00000020U /*!< Secure Non-privilege attribute item */ +#endif /* __ARM_FEATURE_CMSE */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ + +/** @defgroup RCC_Exported_Macros RCC Exported Macros + * @{ + */ + +/** @defgroup RCC_AHB1_Peripheral_Clock_Enable_Disable AHB1 Peripheral Clock Enable Disable + * @brief Enable or disable the AHB1 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ + +#define __HAL_RCC_GPDMA1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPDMA1EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPDMA1EN); \ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_GPDMA2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPDMA2EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPDMA2EN); \ + UNUSED(tmpreg); \ + } while(0) + +#if defined(CORDIC) +#define __HAL_RCC_CORDIC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_CORDICEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_CORDICEN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* CORDIC */ + +#if defined(FMAC) +#define __HAL_RCC_FMAC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_FMACEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_FMACEN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* FMAC */ + +#define __HAL_RCC_CRC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_CRCEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_CRCEN); \ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_RAMCFG_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_RAMCFGEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_RAMCFGEN); \ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_FLASH_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_FLITFEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_FLITFEN); \ + UNUSED(tmpreg); \ + } while(0) + +#if defined(ETH) +#define __HAL_RCC_ETH_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHEN);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_ETHTX_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHTXEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHTXEN);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_ETHRX_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHRXEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHRXEN);\ + UNUSED(tmpreg); \ + } while(0) +#endif /*ETH*/ + +#define __HAL_RCC_GTZC1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_TZSC1EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_TZSC1EN); \ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_BKPRAM_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_BKPRAMEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_BKPRAMEN); \ + UNUSED(tmpreg); \ + } while(0) + +#if defined(DCACHE1) +#define __HAL_RCC_DCACHE1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_DCACHE1EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_DCACHE1EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* DCACHE1 */ + +#define __HAL_RCC_SRAM1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_SRAM1EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_SRAM1EN); \ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_GPDMA1_CLK_DISABLE() CLEAR_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPDMA1EN) + +#define __HAL_RCC_GPDMA2_CLK_DISABLE() CLEAR_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPDMA2EN) + +#if defined(CORDIC) +#define __HAL_RCC_CORDIC_CLK_DISABLE() CLEAR_BIT(RCC->AHB1ENR, RCC_AHB1ENR_CORDICEN) +#endif /* CORDIC */ + +#if defined(FMAC) +#define __HAL_RCC_FMAC_CLK_DISABLE() CLEAR_BIT(RCC->AHB1ENR, RCC_AHB1ENR_FMACEN) +#endif /* FMAC */ + +#define __HAL_RCC_FLASH_CLK_DISABLE() CLEAR_BIT(RCC->AHB1ENR, RCC_AHB1ENR_FLITFEN) + +#define __HAL_RCC_CRC_CLK_DISABLE() CLEAR_BIT(RCC->AHB1ENR, RCC_AHB1ENR_CRCEN) + +#define __HAL_RCC_RAMCFG_CLK_DISABLE() CLEAR_BIT(RCC->AHB1ENR, RCC_AHB1ENR_RAMCFGEN) + +#if defined(ETH) +#define __HAL_RCC_ETH_CLK_DISABLE() CLEAR_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHEN) + +#define __HAL_RCC_ETHTX_CLK_DISABLE() CLEAR_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHTXEN) + +#define __HAL_RCC_ETHRX_CLK_DISABLE() CLEAR_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHRXEN) +#endif /*ETH*/ + +#define __HAL_RCC_GTZC1_CLK_DISABLE() CLEAR_BIT(RCC->AHB1ENR, RCC_AHB1ENR_TZSC1EN) + +#define __HAL_RCC_BKPRAM_CLK_DISABLE() CLEAR_BIT(RCC->AHB1ENR, RCC_AHB1ENR_BKPRAMEN) + +#if defined(DCACHE1) +#define __HAL_RCC_DCACHE1_CLK_DISABLE() CLEAR_BIT(RCC->AHB1ENR, RCC_AHB1ENR_DCACHE1EN) +#endif /* DCACHE1 */ + +#define __HAL_RCC_SRAM1_CLK_DISABLE() CLEAR_BIT(RCC->AHB1ENR, RCC_AHB1ENR_SRAM1EN) +/** + * @} + */ + +/** @defgroup RCC_AHB2_Peripheral_Clock_Enable_Disable AHB2 Peripheral Clock Enable Disable + * @brief Enable or disable the AHB2 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ + +#define __HAL_RCC_GPIOA_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOAEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOAEN); \ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_GPIOB_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOBEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOBEN); \ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_GPIOC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOCEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOCEN); \ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_GPIOD_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIODEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIODEN); \ + UNUSED(tmpreg); \ + } while(0) + +#if defined(GPIOE) +#define __HAL_RCC_GPIOE_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOEEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOEEN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* GPIOE */ + +#if defined(GPIOF) +#define __HAL_RCC_GPIOF_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOFEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOFEN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* GPIOF */ + +#if defined(GPIOG) +#define __HAL_RCC_GPIOG_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOGEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOGEN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* GPIOG */ + +#define __HAL_RCC_GPIOH_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOHEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOHEN); \ + UNUSED(tmpreg); \ + } while(0) + +#if defined(GPIOI) +#define __HAL_RCC_GPIOI_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOIEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOIEN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* GPIOI */ + +#define __HAL_RCC_ADC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_ADCEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_ADCEN); \ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_DAC1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_DAC1EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_DAC1EN); \ + UNUSED(tmpreg); \ + } while(0) + +#if defined(DCMI) +#define __HAL_RCC_DCMI_PSSI_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_DCMI_PSSIEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_DCMI_PSSIEN);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_DCMI_CLK_ENABLE() __HAL_RCC_DCMI_PSSI_CLK_ENABLE() /* for API backward compatibility */ +#endif /* DCMI */ + +#if defined(AES) +#define __HAL_RCC_AES_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_AESEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_AESEN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* AES */ + +#if defined(HASH) +#define __HAL_RCC_HASH_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_HASHEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_HASHEN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* HASH */ + +#define __HAL_RCC_RNG_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_RNGEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_RNGEN); \ + UNUSED(tmpreg); \ + } while(0) + +#if defined(PKA) +#define __HAL_RCC_PKA_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_PKAEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_PKAEN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* PKA */ + +#if defined(SAES) +#define __HAL_RCC_SAES_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_SAESEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_SAESEN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* SAES */ + +#define __HAL_RCC_SRAM2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_SRAM2EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_SRAM2EN); \ + UNUSED(tmpreg); \ + } while(0) +#if defined(SRAM3_BASE) +#define __HAL_RCC_SRAM3_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_SRAM3EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_SRAM3EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* SRAM3_BASE */ + +#define __HAL_RCC_GPIOA_CLK_DISABLE() CLEAR_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOAEN) + +#define __HAL_RCC_GPIOB_CLK_DISABLE() CLEAR_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOBEN) + +#define __HAL_RCC_GPIOC_CLK_DISABLE() CLEAR_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOCEN) + +#define __HAL_RCC_GPIOD_CLK_DISABLE() CLEAR_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIODEN) + +#if defined(GPIOE) +#define __HAL_RCC_GPIOE_CLK_DISABLE() CLEAR_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOEEN) +#endif /* GPIOE */ + +#if defined(GPIOF) +#define __HAL_RCC_GPIOF_CLK_DISABLE() CLEAR_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOFEN) +#endif /* GPIOF */ + +#if defined(GPIOG) +#define __HAL_RCC_GPIOG_CLK_DISABLE() CLEAR_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOGEN) +#endif /* GPIOG */ + +#define __HAL_RCC_GPIOH_CLK_DISABLE() CLEAR_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOHEN) + +#if defined(GPIOI) +#define __HAL_RCC_GPIOI_CLK_DISABLE() CLEAR_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOIEN) +#endif /* GPIOI */ + +#define __HAL_RCC_ADC_CLK_DISABLE() CLEAR_BIT(RCC->AHB2ENR, RCC_AHB2ENR_ADCEN) + +#define __HAL_RCC_DAC1_CLK_DISABLE() CLEAR_BIT(RCC->AHB2ENR, RCC_AHB2ENR_DAC1EN) + +#if defined(DCMI) +#define __HAL_RCC_DCMI_PSSI_CLK_DISABLE() CLEAR_BIT(RCC->AHB2ENR, RCC_AHB2ENR_DCMI_PSSIEN) +#define __HAL_RCC_DCMI_CLK_DISABLE() __HAL_RCC_DCMI_PSSI_CLK_DISABLE() /* for API backward compatibility*/ +#endif /* DCMI */ + +#if defined(AES) +#define __HAL_RCC_AES_CLK_DISABLE() CLEAR_BIT(RCC->AHB2ENR, RCC_AHB2ENR_AESEN); +#endif /* AES */ + +#if defined(HASH) +#define __HAL_RCC_HASH_CLK_DISABLE() CLEAR_BIT(RCC->AHB2ENR, RCC_AHB2ENR_HASHEN) +#endif /* HASH */ + +#define __HAL_RCC_RNG_CLK_DISABLE() CLEAR_BIT(RCC->AHB2ENR, RCC_AHB2ENR_RNGEN) + +#if defined(PKA) +#define __HAL_RCC_PKA_CLK_DISABLE() CLEAR_BIT(RCC->AHB2ENR, RCC_AHB2ENR_PKAEN) +#endif /* PKA */ + +#if defined(SAES) +#define __HAL_RCC_SAES_CLK_DISABLE() CLEAR_BIT(RCC->AHB2ENR, RCC_AHB2ENR_SAESEN) +#endif /* SAES */ + +#define __HAL_RCC_SRAM2_CLK_DISABLE() CLEAR_BIT(RCC->AHB2ENR, RCC_AHB2ENR_SRAM2EN) + +#if defined(SRAM3_BASE) +#define __HAL_RCC_SRAM3_CLK_DISABLE() CLEAR_BIT(RCC->AHB2ENR, RCC_AHB2ENR_SRAM3EN) +#endif /* SRAM3_BASE */ +/** + * @} + */ + +/** @defgroup RCC_AHB4_Clock_Enable_Disable AHB4 Peripheral Clock Enable Disable + * @brief Enable or disable the AHB4 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ + +#if defined(OTFDEC1) +#define __HAL_RCC_OTFDEC1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB4ENR, RCC_AHB4ENR_OTFDEC1EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_OTFDEC1EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* OTFDEC1 */ + +#if defined(SDMMC1) +#define __HAL_RCC_SDMMC1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB4ENR, RCC_AHB4ENR_SDMMC1EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_SDMMC1EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* SDMMC1 */ + +#if defined(SDMMC2) +#define __HAL_RCC_SDMMC2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB4ENR, RCC_AHB4ENR_SDMMC2EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_SDMMC2EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* SDMMC2 */ + +#if defined(FMC_BASE) +#define __HAL_RCC_FMC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB4ENR, RCC_AHB4ENR_FMCEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_FMCEN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* FMC_BASE */ + +#if defined(OCTOSPI1) +#define __HAL_RCC_OSPI1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB4ENR, RCC_AHB4ENR_OCTOSPI1EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_OCTOSPI1EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* OCTOSPI1 */ + +#if defined(OTFDEC1) +#define __HAL_RCC_OTFDEC1_CLK_DISABLE() CLEAR_BIT(RCC->AHB4ENR, RCC_AHB4ENR_OTFDEC1EN) +#endif /* OTFDEC1 */ + +#if defined(SDMMC1) +#define __HAL_RCC_SDMMC1_CLK_DISABLE() CLEAR_BIT(RCC->AHB4ENR, RCC_AHB4ENR_SDMMC1EN) +#endif /* SDMMC1 */ + +#if defined(SDMMC2) +#define __HAL_RCC_SDMMC2_CLK_DISABLE() CLEAR_BIT(RCC->AHB4ENR, RCC_AHB4ENR_SDMMC2EN) +#endif /* SDMMC2 */ + +#if defined(FMC_BASE) +#define __HAL_RCC_FMC_CLK_DISABLE() CLEAR_BIT(RCC->AHB4ENR, RCC_AHB4ENR_FMCEN) +#endif /* FMC_BASE */ + +#if defined(OCTOSPI1) +#define __HAL_RCC_OSPI1_CLK_DISABLE() CLEAR_BIT(RCC->AHB4ENR, RCC_AHB4ENR_OCTOSPI1EN) +#endif /* OCTOSPI1 */ + +/** + * @} + */ + + +/** @defgroup RCC_APB1_Clock_Enable_Disable APB1 Peripheral Clock Enable Disable + * @brief Enable or disable the APB1 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ + +#define __HAL_RCC_TIM2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM2EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM2EN); \ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_TIM3_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM3EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM3EN); \ + UNUSED(tmpreg); \ + } while(0) + +#if defined(TIM4) +#define __HAL_RCC_TIM4_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM4EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM4EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* TIM4 */ + +#if defined(TIM5) +#define __HAL_RCC_TIM5_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM5EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM5EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* TIM5 */ + +#define __HAL_RCC_TIM6_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM6EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM6EN); \ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_TIM7_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM7EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM7EN); \ + UNUSED(tmpreg); \ + } while(0) + +#if defined(TIM12) +#define __HAL_RCC_TIM12_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM12EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM12EN); \ + UNUSED(tmpreg); \ + } while(0) + +#endif /* TIM12 */ + +#if defined(TIM13) +#define __HAL_RCC_TIM13_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM13EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM13EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* TIM13 */ + +#if defined(TIM14) +#define __HAL_RCC_TIM14_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM14EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM14EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* TIM14 */ + +#define __HAL_RCC_WWDG_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1LENR, RCC_APB1LENR_WWDGEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1LENR, RCC_APB1LENR_WWDGEN); \ + UNUSED(tmpreg); \ + } while(0) + +#if defined(OPAMP1) +#define __HAL_RCC_OPAMP_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1LENR, RCC_APB1LENR_OPAMPEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1LENR, RCC_APB1LENR_OPAMPEN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* OPAMP1 */ + +#define __HAL_RCC_SPI2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1LENR, RCC_APB1LENR_SPI2EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1LENR, RCC_APB1LENR_SPI2EN); \ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_SPI3_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1LENR, RCC_APB1LENR_SPI3EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1LENR, RCC_APB1LENR_SPI3EN); \ + UNUSED(tmpreg); \ + } while(0) + +#if defined(COMP1) +#define __HAL_RCC_COMP_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1LENR, RCC_APB1LENR_COMPEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1LENR, RCC_APB1LENR_COMPEN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* COMP1 */ + +#define __HAL_RCC_USART2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1LENR, RCC_APB1LENR_USART2EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1LENR, RCC_APB1LENR_USART2EN); \ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_USART3_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1LENR, RCC_APB1LENR_USART3EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1LENR, RCC_APB1LENR_USART3EN); \ + UNUSED(tmpreg); \ + } while(0) + +#if defined(UART4) +#define __HAL_RCC_UART4_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1LENR, RCC_APB1LENR_UART4EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1LENR, RCC_APB1LENR_UART4EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* UART4 */ + +#if defined(UART5) +#define __HAL_RCC_UART5_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1LENR, RCC_APB1LENR_UART5EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1LENR, RCC_APB1LENR_UART5EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* UART5 */ + +#define __HAL_RCC_I2C1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1LENR, RCC_APB1LENR_I2C1EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1LENR, RCC_APB1LENR_I2C1EN); \ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_I2C2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1LENR, RCC_APB1LENR_I2C2EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1LENR, RCC_APB1LENR_I2C2EN); \ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_I3C1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1LENR, RCC_APB1LENR_I3C1EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1LENR, RCC_APB1LENR_I3C1EN); \ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_CRS_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1LENR, RCC_APB1LENR_CRSEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1LENR, RCC_APB1LENR_CRSEN); \ + UNUSED(tmpreg); \ + } while(0) + +#if defined(USART6) +#define __HAL_RCC_USART6_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1LENR, RCC_APB1LENR_USART6EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1LENR, RCC_APB1LENR_USART6EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* USART6 */ + +#if defined(USART10) +#define __HAL_RCC_USART10_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1LENR, RCC_APB1LENR_USART10EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1LENR, RCC_APB1LENR_USART10EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* USART10 */ + +#if defined(USART11) +#define __HAL_RCC_USART11_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1LENR, RCC_APB1LENR_USART11EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1LENR, RCC_APB1LENR_USART11EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* USART11 */ + +#if defined(CEC) +#define __HAL_RCC_CEC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1LENR, RCC_APB1LENR_CECEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1LENR, RCC_APB1LENR_CECEN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* CEC */ + +#if defined(UART7) +#define __HAL_RCC_UART7_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1LENR, RCC_APB1LENR_UART7EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1LENR, RCC_APB1LENR_UART7EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* UART7 */ + +#if defined(UART8) +#define __HAL_RCC_UART8_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1LENR, RCC_APB1LENR_UART8EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1LENR, RCC_APB1LENR_UART8EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* UART8 */ + +#if defined(UART9) +#define __HAL_RCC_UART9_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1HENR, RCC_APB1HENR_UART9EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1HENR, RCC_APB1HENR_UART9EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* UART9 */ + +#if defined(UART12) +#define __HAL_RCC_UART12_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1HENR, RCC_APB1HENR_UART12EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1HENR, RCC_APB1HENR_UART12EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* UART12 */ + +#define __HAL_RCC_DTS_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1HENR, RCC_APB1HENR_DTSEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1HENR, RCC_APB1HENR_DTSEN); \ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_LPTIM2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1HENR, RCC_APB1HENR_LPTIM2EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1HENR, RCC_APB1HENR_LPTIM2EN); \ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_FDCAN_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1HENR, RCC_APB1HENR_FDCANEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1HENR, RCC_APB1HENR_FDCANEN); \ + UNUSED(tmpreg); \ + } while(0) + +#if defined(UCPD1) +#define __HAL_RCC_UCPD1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1HENR, RCC_APB1HENR_UCPD1EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1HENR, RCC_APB1HENR_UCPD1EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* UCPD1 */ + +#define __HAL_RCC_TIM2_CLK_DISABLE() CLEAR_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM2EN) + +#define __HAL_RCC_TIM3_CLK_DISABLE() CLEAR_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM3EN) + +#if defined(TIM4) +#define __HAL_RCC_TIM4_CLK_DISABLE() CLEAR_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM4EN) +#endif /* TIM4 */ + +#if defined(TIM5) +#define __HAL_RCC_TIM5_CLK_DISABLE() CLEAR_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM5EN) +#endif /* TIM5 */ + +#define __HAL_RCC_TIM6_CLK_DISABLE() CLEAR_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM6EN) + +#define __HAL_RCC_TIM7_CLK_DISABLE() CLEAR_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM7EN) + +#if defined(TIM12) +#define __HAL_RCC_TIM12_CLK_DISABLE() CLEAR_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM12EN) +#endif /* TIM12 */ + +#if defined(TIM13) +#define __HAL_RCC_TIM13_CLK_DISABLE() CLEAR_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM13EN) +#endif /* TIM13 */ + +#if defined(TIM14) +#define __HAL_RCC_TIM14_CLK_DISABLE() CLEAR_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM14EN) +#endif /* TIM14 */ + +#define __HAL_RCC_WWDG_CLK_DISABLE() CLEAR_BIT(RCC->APB1LENR, RCC_APB1LENR_WWDGEN) + +#if defined(OPAMP1) +#define __HAL_RCC_OPAMP_CLK_DISABLE() CLEAR_BIT(RCC->APB1LENR, RCC_APB1LENR_OPAMPEN) +#endif /* OPAMP1 */ + +#define __HAL_RCC_SPI2_CLK_DISABLE() CLEAR_BIT(RCC->APB1LENR, RCC_APB1LENR_SPI2EN) + +#define __HAL_RCC_SPI3_CLK_DISABLE() CLEAR_BIT(RCC->APB1LENR, RCC_APB1LENR_SPI3EN) + +#if defined(COMP1) +#define __HAL_RCC_COMP_CLK_DISABLE() CLEAR_BIT(RCC->APB1LENR, RCC_APB1LENR_COMPEN) +#endif /* COMP1 */ + +#define __HAL_RCC_USART2_CLK_DISABLE() CLEAR_BIT(RCC->APB1LENR, RCC_APB1LENR_USART2EN) + +#define __HAL_RCC_USART3_CLK_DISABLE() CLEAR_BIT(RCC->APB1LENR, RCC_APB1LENR_USART3EN) + +#if defined(UART4) +#define __HAL_RCC_UART4_CLK_DISABLE() CLEAR_BIT(RCC->APB1LENR, RCC_APB1LENR_UART4EN) +#endif /* UART4 */ + +#if defined(UART5) +#define __HAL_RCC_UART5_CLK_DISABLE() CLEAR_BIT(RCC->APB1LENR, RCC_APB1LENR_UART5EN) +#endif /* UART5 */ + +#define __HAL_RCC_I2C1_CLK_DISABLE() CLEAR_BIT(RCC->APB1LENR, RCC_APB1LENR_I2C1EN) + +#define __HAL_RCC_I2C2_CLK_DISABLE() CLEAR_BIT(RCC->APB1LENR, RCC_APB1LENR_I2C2EN) + +#define __HAL_RCC_I3C1_CLK_DISABLE() CLEAR_BIT(RCC->APB1LENR, RCC_APB1LENR_I3C1EN) + +#define __HAL_RCC_CRS_CLK_DISABLE() CLEAR_BIT(RCC->APB1LENR, RCC_APB1LENR_CRSEN) + +#if defined(USART6) +#define __HAL_RCC_USART6_CLK_DISABLE() CLEAR_BIT(RCC->APB1LENR, RCC_APB1LENR_USART6EN) +#endif /* USART6 */ + +#if defined(USART10) +#define __HAL_RCC_USART10_CLK_DISABLE() CLEAR_BIT(RCC->APB1LENR, RCC_APB1LENR_USART10EN) +#endif /* USART10 */ + +#if defined(USART11) +#define __HAL_RCC_USART11_CLK_DISABLE() CLEAR_BIT(RCC->APB1LENR, RCC_APB1LENR_USART11EN) +#endif /* USART11 */ + +#if defined(CEC) +#define __HAL_RCC_CEC_CLK_DISABLE() CLEAR_BIT(RCC->APB1LENR, RCC_APB1LENR_CECEN) +#endif /* CEC */ + +#if defined(UART7) +#define __HAL_RCC_UART7_CLK_DISABLE() CLEAR_BIT(RCC->APB1LENR, RCC_APB1LENR_UART7EN) +#endif /* UART7 */ + +#if defined(UART8) +#define __HAL_RCC_UART8_CLK_DISABLE() CLEAR_BIT(RCC->APB1LENR, RCC_APB1LENR_UART8EN) +#endif /* UART8 */ + + +#if defined(UART9) +#define __HAL_RCC_UART9_CLK_DISABLE() CLEAR_BIT(RCC->APB1HENR, RCC_APB1HENR_UART9EN) +#endif /* UART9 */ + +#if defined(UART12) +#define __HAL_RCC_UART12_CLK_DISABLE() CLEAR_BIT(RCC->APB1HENR, RCC_APB1HENR_UART12EN) +#endif /* UART12 */ + +#define __HAL_RCC_DTS_CLK_DISABLE() CLEAR_BIT(RCC->APB1HENR , RCC_APB1HENR_DTSEN) + +#define __HAL_RCC_LPTIM2_CLK_DISABLE() CLEAR_BIT(RCC->APB1HENR, RCC_APB1HENR_LPTIM2EN) + +#define __HAL_RCC_FDCAN_CLK_DISABLE() CLEAR_BIT(RCC->APB1HENR, RCC_APB1HENR_FDCANEN) + +#if defined(UCPD1) +#define __HAL_RCC_UCPD1_CLK_DISABLE() CLEAR_BIT(RCC->APB1HENR, RCC_APB1HENR_UCPD1EN) +#endif /* UCPD1 */ + +/** + * @} + */ + +/** @defgroup RCC_APB2_Clock_Enable_Disable APB2 Peripheral Clock Enable Disable + * @brief Enable or disable the APB2 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ +#define __HAL_RCC_TIM1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM1EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM1EN); \ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_SPI1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI1EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI1EN); \ + UNUSED(tmpreg); \ + } while(0) + +#if defined(TIM8) +#define __HAL_RCC_TIM8_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM8EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM8EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* TIM8 */ + +#define __HAL_RCC_USART1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN); \ + UNUSED(tmpreg); \ + } while(0) + +#if defined(TIM15) +#define __HAL_RCC_TIM15_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM15EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM15EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* TIM15 */ + +#if defined(TIM16) +#define __HAL_RCC_TIM16_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM16EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM16EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* TIM16 */ + +#if defined(TIM17) +#define __HAL_RCC_TIM17_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM17EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM17EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* TIM17 */ + +#if defined(SPI4) +#define __HAL_RCC_SPI4_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI4EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI4EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* SPI4 */ + +#if defined(SPI6) +#define __HAL_RCC_SPI6_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI6EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI6EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* SPI6 */ + +#if defined(SAI1) +#define __HAL_RCC_SAI1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_SAI1EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SAI1EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* SAI1 */ + +#if defined(SAI2) +#define __HAL_RCC_SAI2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_SAI2EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SAI2EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* SAI2 */ + +#define __HAL_RCC_USB_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_USBEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_USBEN); \ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_TIM1_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM1EN) + +#define __HAL_RCC_SPI1_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI1EN) + +#if defined(TIM8) +#define __HAL_RCC_TIM8_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM8EN) +#endif /* TIM8 */ + +#define __HAL_RCC_USART1_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN) + +#if defined(TIM15) +#define __HAL_RCC_TIM15_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM15EN) +#endif /* TIM15 */ + +#if defined(TIM16) +#define __HAL_RCC_TIM16_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM16EN) +#endif /* TIM16 */ + +#if defined(TIM17) +#define __HAL_RCC_TIM17_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM17EN) +#endif /* TIM17 */ + +#if defined(SPI4) +#define __HAL_RCC_SPI4_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI4EN) +#endif /* SPI4 */ + +#if defined(SPI6) +#define __HAL_RCC_SPI6_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI6EN) +#endif /* SPI6 */ + +#if defined(SAI1) +#define __HAL_RCC_SAI1_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, RCC_APB2ENR_SAI1EN) +#endif /* SAI1 */ + +#if defined(SAI2) +#define __HAL_RCC_SAI2_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, RCC_APB2ENR_SAI2EN) +#endif /* SAI2 */ + +#define __HAL_RCC_USB_CLK_DISABLE() CLEAR_BIT(RCC->APB2ENR, RCC_APB2ENR_USBEN) + +/** + * @} + */ + +/** @defgroup RCC_APB3_Clock_Enable_Disable APB3 Peripheral Clock Enable Disable + * @brief Enable or disable the APB3 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ +#define __HAL_RCC_SBS_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB3ENR, RCC_APB3ENR_SBSEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB3ENR, RCC_APB3ENR_SBSEN); \ + UNUSED(tmpreg); \ + } while(0) + +#if defined(SPI5) +#define __HAL_RCC_SPI5_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB3ENR, RCC_APB3ENR_SPI5EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB3ENR, RCC_APB3ENR_SPI5EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* SPI5 */ + +#define __HAL_RCC_LPUART1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB3ENR, RCC_APB3ENR_LPUART1EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB3ENR, RCC_APB3ENR_LPUART1EN); \ + UNUSED(tmpreg); \ + } while(0) + +#if defined(I2C3) +#define __HAL_RCC_I2C3_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB3ENR, RCC_APB3ENR_I2C3EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB3ENR, RCC_APB3ENR_I2C3EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* I2C3 */ + +#if defined(I2C4) +#define __HAL_RCC_I2C4_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB3ENR, RCC_APB3ENR_I2C4EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB3ENR, RCC_APB3ENR_I2C4EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* I2C4 */ + +#if defined(I3C2) +#define __HAL_RCC_I3C2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB3ENR, RCC_APB3ENR_I3C2EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB3ENR, RCC_APB3ENR_I3C2EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* I3C2 */ + +#define __HAL_RCC_LPTIM1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB3ENR, RCC_APB3ENR_LPTIM1EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB3ENR, RCC_APB3ENR_LPTIM1EN); \ + UNUSED(tmpreg); \ + } while(0) + +#if defined(LPTIM3) +#define __HAL_RCC_LPTIM3_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB3ENR, RCC_APB3ENR_LPTIM3EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB3ENR, RCC_APB3ENR_LPTIM3EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* LPTIM3 */ + +#if defined(LPTIM4) +#define __HAL_RCC_LPTIM4_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB3ENR, RCC_APB3ENR_LPTIM4EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB3ENR, RCC_APB3ENR_LPTIM4EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* LPTIM4 */ + +#if defined(LPTIM5) +#define __HAL_RCC_LPTIM5_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB3ENR, RCC_APB3ENR_LPTIM5EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB3ENR, RCC_APB3ENR_LPTIM5EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* LPTIM5 */ + +#if defined(LPTIM6) +#define __HAL_RCC_LPTIM6_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB3ENR, RCC_APB3ENR_LPTIM6EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB3ENR, RCC_APB3ENR_LPTIM6EN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* LPTIM6 */ + +#if defined(VREFBUF) +#define __HAL_RCC_VREF_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB3ENR, RCC_APB3ENR_VREFEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB3ENR, RCC_APB3ENR_VREFEN); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* VREFBUF */ + +#define __HAL_RCC_RTC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB3ENR, RCC_APB3ENR_RTCAPBEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB3ENR, RCC_APB3ENR_RTCAPBEN); \ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_SBS_CLK_DISABLE() CLEAR_BIT(RCC->APB3ENR, RCC_APB3ENR_SBSEN) + +#if defined(SPI5) +#define __HAL_RCC_SPI5_CLK_DISABLE() CLEAR_BIT(RCC->APB3ENR, RCC_APB3ENR_SPI5EN) +#endif /* SPI5 */ + +#define __HAL_RCC_LPUART1_CLK_DISABLE() CLEAR_BIT(RCC->APB3ENR, RCC_APB3ENR_LPUART1EN) + +#if defined(I2C3) +#define __HAL_RCC_I2C3_CLK_DISABLE() CLEAR_BIT(RCC->APB3ENR, RCC_APB3ENR_I2C3EN) +#endif /* I2C3 */ + +#if defined(I2C4) +#define __HAL_RCC_I2C4_CLK_DISABLE() CLEAR_BIT(RCC->APB3ENR, RCC_APB3ENR_I2C4EN) +#endif /* I2C4 */ + +#if defined(I3C2) +#define __HAL_RCC_I3C2_CLK_DISABLE() CLEAR_BIT(RCC->APB3ENR, RCC_APB3ENR_I3C2EN) +#endif /* I3C2 */ + +#define __HAL_RCC_LPTIM1_CLK_DISABLE() CLEAR_BIT(RCC->APB3ENR, RCC_APB3ENR_LPTIM1EN) + +#if defined(LPTIM3) +#define __HAL_RCC_LPTIM3_CLK_DISABLE() CLEAR_BIT(RCC->APB3ENR, RCC_APB3ENR_LPTIM3EN) +#endif /* LPTIM3 */ + +#if defined(LPTIM4) +#define __HAL_RCC_LPTIM4_CLK_DISABLE() CLEAR_BIT(RCC->APB3ENR, RCC_APB3ENR_LPTIM4EN) +#endif /* LPTIM4 */ + +#if defined(LPTIM5) +#define __HAL_RCC_LPTIM5_CLK_DISABLE() CLEAR_BIT(RCC->APB3ENR, RCC_APB3ENR_LPTIM5EN) +#endif /* LPTIM5 */ + +#if defined(LPTIM6) +#define __HAL_RCC_LPTIM6_CLK_DISABLE() CLEAR_BIT(RCC->APB3ENR, RCC_APB3ENR_LPTIM6EN) +#endif /* LPTIM6 */ + +#if defined(VREFBUF) +#define __HAL_RCC_VREF_CLK_DISABLE() CLEAR_BIT(RCC->APB3ENR, RCC_APB3ENR_VREFEN) +#endif /* VREFBUF */ + +#define __HAL_RCC_RTC_CLK_DISABLE() CLEAR_BIT(RCC->APB3ENR, RCC_APB3ENR_RTCAPBEN) + +/** + * @} + */ + +/** @defgroup RCC_AHB_APB_Branch_Clock_Disable AHB APB Branch Clock Disable Clear Disable + * @brief Disable or clear Disable the AHBx/APBx branch clock for all AHBx/APBx peripherals. + * @note It is recommended to disable the clock of all peripherals (by writing 0 in + * the AHBxENR/APBxENR register) before Disabling the corresponding Bus Branch clock. + * Some peripheral bus clocks are not affected by branch clock disabling as IWDG (APB1), + * SRAM2/SRAM3 (AHB2) and FLITF/BKRAM/ICACHE/DCACHE/SRAM1 (AHB1). + * @{ + */ + +#define __HAL_RCC_AHB1_CLK_DISABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->CFGR2, RCC_CFGR2_AHB1DIS); \ + /* Delay after AHB peripherals bus clocks branch disable */ \ + tmpreg = READ_BIT(RCC->CFGR2, RCC_CFGR2_AHB1DIS); \ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_AHB2_CLK_DISABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->CFGR2, RCC_CFGR2_AHB2DIS); \ + /* Delay after AHB peripherals bus clocks branch disable */ \ + tmpreg = READ_BIT(RCC->CFGR2, RCC_CFGR2_AHB2DIS); \ + UNUSED(tmpreg); \ + } while(0) + +#if defined(AHB4PERIPH_BASE) +#define __HAL_RCC_AHB4_CLK_DISABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->CFGR2, RCC_CFGR2_AHB4DIS); \ + /* Delay after AHB peripherals bus clocks branch disable */ \ + tmpreg = READ_BIT(RCC->CFGR2, RCC_CFGR2_AHB4DIS); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* AHB4PERIPH_BASE */ + +#define __HAL_RCC_APB1_CLK_DISABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->CFGR2, RCC_CFGR2_APB1DIS); \ + /* Delay after APB peripherals bus clocks branch disable */ \ + tmpreg = READ_BIT(RCC->CFGR2, RCC_CFGR2_APB1DIS); \ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_APB2_CLK_DISABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->CFGR2, RCC_CFGR2_APB2DIS); \ + /* Delay after APB peripherals bus clocks branch disable */ \ + tmpreg = READ_BIT(RCC->CFGR2, RCC_CFGR2_APB2DIS); \ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_APB3_CLK_DISABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->CFGR2, RCC_CFGR2_APB3DIS); \ + /* Delay after APB peripherals bus clocks branch disable */ \ + tmpreg = READ_BIT(RCC->CFGR2, RCC_CFGR2_APB3DIS); \ + UNUSED(tmpreg); \ + } while(0) + + +#define __HAL_RCC_AHB1_CLK_ENABLE() CLEAR_BIT(RCC->CFGR2, RCC_CFGR2_AHB1DIS) + +#define __HAL_RCC_AHB2_CLK_ENABLE() CLEAR_BIT(RCC->CFGR2, RCC_CFGR2_AHB2DIS) + +#if defined(AHB4PERIPH_BASE) +#define __HAL_RCC_AHB4_CLK_ENABLE() CLEAR_BIT(RCC->CFGR2, RCC_CFGR2_AHB4DIS) +#endif /* AHB4PERIPH_BASE */ + +#define __HAL_RCC_APB1_CLK_ENABLE() CLEAR_BIT(RCC->CFGR2, RCC_CFGR2_APB1DIS) + +#define __HAL_RCC_APB2_CLK_ENABLE() CLEAR_BIT(RCC->CFGR2, RCC_CFGR2_APB2DIS) + +#define __HAL_RCC_APB3_CLK_ENABLE() CLEAR_BIT(RCC->CFGR2, RCC_CFGR2_APB3DIS) + +/** + * @} + */ + +/** @defgroup RCC_AHB1_Peripheral_Clock_Enable_Disable_Status AHB1 Peripheral Clock Enabled or Disabled Status + * @brief Check whether the AHB1 peripheral clock is enabled or not. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ +#define __HAL_RCC_GPDMA1_IS_CLK_ENABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPDMA1EN) != 0U) + +#define __HAL_RCC_GPDMA2_IS_CLK_ENABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPDMA2EN) != 0U) + +#define __HAL_RCC_FLASH_IS_CLK_ENABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_FLITFEN) != 0U) + +#define __HAL_RCC_CRC_IS_CLK_ENABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_CRCEN) != 0U) + +#if defined(CORDIC) +#define __HAL_RCC_CORDIC_IS_CLK_ENABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_CORDICEN) != 0U) +#endif /* CORDIC */ + +#if defined(FMAC) +#define __HAL_RCC_FMAC_IS_CLK_ENABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_FMACEN) != 0U) +#endif /* FMAC */ + +#define __HAL_RCC_RAMCFG_IS_CLK_ENABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_RAMCFGEN) != 0U) + +#if defined(ETH) +#define __HAL_RCC_ETH_IS_CLK_ENABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHEN) != 0U) + +#define __HAL_RCC_ETHTX_IS_CLK_ENABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHTXEN) != 0U) + +#define __HAL_RCC_ETHRX_IS_CLK_ENABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHRXEN) != 0U) +#endif /*ETH*/ + +#define __HAL_RCC_GTZC1_IS_CLK_ENABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_TZSC1EN) != 0U) + +#define __HAL_RCC_BKPRAM_IS_CLK_ENABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_BKPRAMEN) != 0U) + +#if defined(DCACHE1) +#define __HAL_RCC_DCACHE1_IS_CLK_ENABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_DCACHE1EN) != 0U) +#endif /* DCACHE1 */ + +#define __HAL_RCC_SRAM1_IS_CLK_ENABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_SRAM1EN) != 0U) + + +#define __HAL_RCC_GPDMA1_IS_CLK_DISABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPDMA1EN) == 0U) + +#define __HAL_RCC_GPDMA2_IS_CLK_DISABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPDMA2EN) == 0U) + +#define __HAL_RCC_FLASH_IS_CLK_DISABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_FLITFEN) == 0U) + +#define __HAL_RCC_CRC_IS_CLK_DISABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_CRCEN) == 0U) + +#if defined(CORDIC) +#define __HAL_RCC_CORDIC_IS_CLK_DISABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_CORDICEN) == 0U) +#endif /* CORDIC */ + +#if defined(FMAC) +#define __HAL_RCC_FMAC_IS_CLK_DISABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_FMACEN) == 0U) +#endif /* FMAC */ + +#define __HAL_RCC_RAMCFG_IS_CLK_DISABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_RAMCFGEN) == 0U) + +#if defined(ETH) +#define __HAL_RCC_ETH_IS_CLK_DISABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHEN) == 0U) + +#define __HAL_RCC_ETHTX_IS_CLK_DISABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHTXEN) == 0U) + +#define __HAL_RCC_ETHRX_IS_CLK_DISABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHRXEN) == 0U) +#endif /*ETH*/ + +#define __HAL_RCC_GTZC1_IS_CLK_DISABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_TZSC1EN) == 0U) + +#define __HAL_RCC_BKPRAM_IS_CLK_DISABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_BKPRAMEN) == 0U) + +#if defined(DCACHE1) +#define __HAL_RCC_DCACHE1_IS_CLK_DISABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_DCACHE1EN) == 0U) +#endif /* DCACHE1 */ + +#define __HAL_RCC_SRAM1_IS_CLK_DISABLED() (READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_SRAM1EN) == 0U) +/** + * @} + */ + +/** @defgroup RCC_AHB2_Peripheral_Clock_Enable_Disable_Status AHB2 Peripheral Clock Enabled or Disabled Status + * @brief Check whether the AHB2 peripheral clock is enabled or not. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ + +#define __HAL_RCC_GPIOA_IS_CLK_ENABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOAEN) != 0U) + +#define __HAL_RCC_GPIOB_IS_CLK_ENABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOBEN) != 0U) + +#define __HAL_RCC_GPIOC_IS_CLK_ENABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOCEN) != 0U) + +#define __HAL_RCC_GPIOD_IS_CLK_ENABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIODEN) != 0U) + +#if defined(GPIOE) +#define __HAL_RCC_GPIOE_IS_CLK_ENABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOEEN) != 0U) +#endif /* GPIOE */ + +#if defined(GPIOF) +#define __HAL_RCC_GPIOF_IS_CLK_ENABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOFEN) != 0U) +#endif /* GPIOF */ + +#if defined(GPIOG) +#define __HAL_RCC_GPIOG_IS_CLK_ENABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOGEN) != 0U) +#endif /* GPIOG */ + +#define __HAL_RCC_GPIOH_IS_CLK_ENABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOHEN) != 0U) + +#if defined(GPIOI) +#define __HAL_RCC_GPIOI_IS_CLK_ENABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOIEN) != 0U) +#endif /* GPIOI */ + +#define __HAL_RCC_ADC_IS_CLK_ENABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_ADCEN) != 0U) + +#define __HAL_RCC_DAC1_IS_CLK_ENABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_DAC1EN) != 0U) + +#if defined(DCMI) +#define __HAL_RCC_DCMI_PSSI_IS_CLK_ENABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_DCMI_PSSIEN) != 0U) +#define __HAL_RCC_DCMI_IS_CLK_ENABLED() __HAL_RCC_DCMI_PSSI_IS_CLK_ENABLED() /* for API backward compatibility */ +#endif /* DCMI */ + +#if defined(AES) +#define __HAL_RCC_AES_IS_CLK_ENABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_AESEN) != 0U) +#endif /* AES */ + +#if defined(HASH) +#define __HAL_RCC_HASH_IS_CLK_ENABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_HASHEN) != 0U) +#endif /* HASH */ + +#define __HAL_RCC_RNG_IS_CLK_ENABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_RNGEN) != 0U) + +#define __HAL_RCC_PKA_IS_CLK_ENABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_PKAEN) != 0U) + +#if defined(SAES) +#define __HAL_RCC_SAES_IS_CLK_ENABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_SAESEN) != 0U) +#endif /*SAES*/ + +#define __HAL_RCC_SRAM2_IS_CLK_ENABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_SRAM2EN) != 0U) + +#if defined(SRAM3_BASE) +#define __HAL_RCC_SRAM3_IS_CLK_ENABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_SRAM3EN) != 0U) +#endif /* SRAM3_BASE */ + +#define __HAL_RCC_GPIOA_IS_CLK_DISABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOAEN) == 0U) + +#define __HAL_RCC_GPIOB_IS_CLK_DISABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOBEN) == 0U) + +#define __HAL_RCC_GPIOC_IS_CLK_DISABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOCEN) == 0U) + +#define __HAL_RCC_GPIOD_IS_CLK_DISABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIODEN) == 0U) + +#if defined(GPIOE) +#define __HAL_RCC_GPIOE_IS_CLK_DISABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOEEN) == 0U) +#endif /* GPIOE */ + +#if defined(GPIOF) +#define __HAL_RCC_GPIOF_IS_CLK_DISABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOFEN) == 0U) +#endif /* GPIOF */ + +#if defined(GPIOG) +#define __HAL_RCC_GPIOG_IS_CLK_DISABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOGEN) == 0U) +#endif /* GPIOG */ + +#define __HAL_RCC_GPIOH_IS_CLK_DISABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOHEN) == 0U) + +#if defined(GPIOI) +#define __HAL_RCC_GPIOI_IS_CLK_DISABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOIEN) == 0U) +#endif /* GPIOI */ + +#define __HAL_RCC_ADC_IS_CLK_DISABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_ADCEN) == 0U) + +#define __HAL_RCC_DAC1_IS_CLK_DISABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_DAC1EN) == 0U) + +#if defined(DCMI) +#define __HAL_RCC_DCMI_PSSI_IS_CLK_DISABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_DCMI_PSSIEN) == 0U) +#define __HAL_RCC_DCMI_IS_CLK_DISABLED() __HAL_RCC_DCMI_PSSI_IS_CLK_DISABLED() /* for API backward compatibility */ +#endif /* DCMI */ + +#if defined(AES) +#define __HAL_RCC_AES_IS_CLK_DISABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_AESEN) == 0U) +#endif /* AES */ + +#if defined(HASH) +#define __HAL_RCC_HASH_IS_CLK_DISABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_HASHEN) == 0U) +#endif /* HASH */ + +#define __HAL_RCC_RNG_IS_CLK_DISABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_RNGEN) == 0U) + +#define __HAL_RCC_PKA_IS_CLK_DISABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_PKAEN) == 0U) + +#if defined(SAES) +#define __HAL_RCC_SAES_IS_CLK_DISABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_SAESEN) == 0U) +#endif /* SAES */ + +#define __HAL_RCC_SRAM2_IS_CLK_DISABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_SRAM2EN) == 0U) + +#if defined(SRAM3_BASE) +#define __HAL_RCC_SRAM3_IS_CLK_DISABLED() (READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_SRAM3EN) == 0U) +#endif /* SRAM3_BASE */ +/** + * @} + */ + +/** @defgroup RCC_AHB4_Peripheral_Clock_Enable_Disable_Status AHB4 Peripheral Clock Enabled or Disabled Status + * @brief Check whether the AHB4 peripheral clock is enabled or not. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ + +#if defined(OTFDEC1) +#define __HAL_RCC_OTFDEC1_IS_CLK_ENABLED() (READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_OTFDEC1EN) != 0U) +#endif /* OTFDEC1 */ + +#if defined(OCTOSPI1) +#define __HAL_RCC_OSPI1_IS_CLK_ENABLED() (READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_OCTOSPI1EN) != 0U) +#endif /* OCTOSPI1 */ + +#if defined(SDMMC1) +#define __HAL_RCC_SDMMC1_IS_CLK_ENABLED() (READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_SDMMC1EN) != 0U) +#endif /* SDMMC1 */ + +#if defined(SDMMC2) +#define __HAL_RCC_SDMMC2_IS_CLK_ENABLED() (READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_SDMMC2EN) != 0U) +#endif /* SDMMC2 */ + +#if defined(FMC_BASE) +#define __HAL_RCC_FMC_IS_CLK_ENABLED() (READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_FMCEN) != 0U) +#endif /* FMC_BASE */ + + +#if defined(OTFDEC1) +#define __HAL_RCC_OTFDEC1_IS_CLK_DISABLED() (READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_OTFDEC1EN) == 0U) +#endif /* OTFDEC1 */ + +#if defined(OCTOSPI1) +#define __HAL_RCC_OSPI1_IS_CLK_DISABLED() (READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_OCTOSPI1EN) == 0U) +#endif /* OCTOSPI1 */ + +#if defined(SDMMC1) +#define __HAL_RCC_SDMMC1_IS_CLK_DISABLED() (READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_SDMMC1EN) == 0U) +#endif /* SDMMC1 */ + +#if defined(SDMMC2) +#define __HAL_RCC_SDMMC2_IS_CLK_DISABLED() (READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_SDMMC2EN) == 0U) +#endif /* SDMMC2 */ + +#if defined(FMC_BASE) +#define __HAL_RCC_FMC_IS_CLK_DISABLED() (READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_FMCEN) == 0U) +#endif /* FMC_BASE */ + +/** + * @} + */ + + +/** @defgroup RCC_APB1_Peripheral_Clock_Enable_Disable_Status APB1 Peripheral Clock Enabled or Disabled Status + * @brief Check whether the APB1 peripheral clock is enabled or not. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ + + +#define __HAL_RCC_TIM2_IS_CLK_ENABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM2EN) != 0U) + +#define __HAL_RCC_TIM3_IS_CLK_ENABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM3EN) != 0U) + +#if defined(TIM4) +#define __HAL_RCC_TIM4_IS_CLK_ENABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM4EN) != 0U) +#endif /* TIM4 */ + +#if defined(TIM5) +#define __HAL_RCC_TIM5_IS_CLK_ENABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM5EN) != 0U) +#endif /* TIM5 */ + +#define __HAL_RCC_TIM6_IS_CLK_ENABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM6EN) != 0U) + +#define __HAL_RCC_TIM7_IS_CLK_ENABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM7EN) != 0U) + +#if defined(TIM12) +#define __HAL_RCC_TIM12_IS_CLK_ENABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM12EN) != 0U) +#endif /* TIM12 */ + +#if defined(TIM13) +#define __HAL_RCC_TIM13_IS_CLK_ENABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM13EN) != 0U) +#endif /* TIM13 */ + +#if defined(TIM14) +#define __HAL_RCC_TIM14_IS_CLK_ENABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM14EN) != 0U) +#endif /* TIM14 */ + +#define __HAL_RCC_WWDG_IS_CLK_ENABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_WWDGEN) != 0U) + +#if defined(OPAMP1) +#define __HAL_RCC_OPAMP_IS_CLK_ENABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_OPAMPEN) != 0U) +#endif /* OPAMP1 */ + +#define __HAL_RCC_SPI2_IS_CLK_ENABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_SPI2EN) != 0U) + +#define __HAL_RCC_SPI3_IS_CLK_ENABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_SPI3EN) != 0U) + +#if defined(COMP1) +#define __HAL_RCC_COMP_IS_CLK_ENABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_COMPEN) != 0U) +#endif /* COMP1 */ + +#define __HAL_RCC_USART2_IS_CLK_ENABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_USART2EN) != 0U) + +#define __HAL_RCC_USART3_IS_CLK_ENABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_USART3EN) != 0U) + +#if defined(UART4) +#define __HAL_RCC_UART4_IS_CLK_ENABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_UART4EN) != 0U) +#endif /* UART4 */ + +#if defined(UART5) +#define __HAL_RCC_UART5_IS_CLK_ENABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_UART5EN) != 0U) +#endif /* UART5 */ + +#define __HAL_RCC_I2C1_IS_CLK_ENABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_I2C1EN) != 0U) + +#define __HAL_RCC_I2C2_IS_CLK_ENABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_I2C2EN) != 0U) + +#define __HAL_RCC_I3C1_IS_CLK_ENABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_I3C1EN) != 0U) + +#define __HAL_RCC_CRS_IS_CLK_ENABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_CRSEN) != 0U) + +#if defined(USART6) +#define __HAL_RCC_USART6_IS_CLK_ENABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_USART6EN) != 0U) +#endif /* USART6 */ + +#if defined(USART10) +#define __HAL_RCC_USART10_IS_CLK_ENABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_USART10EN) != 0U) +#endif /* USART10 */ + +#if defined(USART11) +#define __HAL_RCC_USART11_IS_CLK_ENABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_USART11EN) != 0U) +#endif /* USART11 */ + +#if defined(CEC) +#define __HAL_RCC_CEC_IS_CLK_ENABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_CECEN) != 0U) +#endif /* CEC */ + +#if defined(UART7) +#define __HAL_RCC_UART7_IS_CLK_ENABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_UART7EN) != 0U) +#endif /* UART7 */ + +#if defined(UART8) +#define __HAL_RCC_UART8_IS_CLK_ENABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_UART8EN) != 0U) +#endif /* UART8 */ + + +#if defined(UART9) +#define __HAL_RCC_UART9_IS_CLK_ENABLED() (READ_BIT(RCC->APB1HENR, RCC_APB1HENR_UART9EN) != 0U) +#endif /* UART9 */ + +#if defined(UART12) +#define __HAL_RCC_UART12_IS_CLK_ENABLED() (READ_BIT(RCC->APB1HENR, RCC_APB1HENR_UART12EN) != 0U) +#endif /* UART12 */ + +#define __HAL_RCC_DTS_IS_CLK_ENABLED() (READ_BIT(RCC->APB1HENR, RCC_APB1HENR_DTSEN) != 0U) + +#define __HAL_RCC_LPTIM2_IS_CLK_ENABLED() (READ_BIT(RCC->APB1HENR, RCC_APB1HENR_LPTIM2EN) != 0U) + +#define __HAL_RCC_FDCAN_IS_CLK_ENABLED() (READ_BIT(RCC->APB1HENR, RCC_APB1HENR_FDCANEN) != 0U) + +#if defined(UCPD1) +#define __HAL_RCC_UCPD1_IS_CLK_ENABLED() (READ_BIT(RCC->APB1HENR, RCC_APB1HENR_UCPD1EN) != 0U) +#endif /* UCPD1 */ + + +#define __HAL_RCC_TIM2_IS_CLK_DISABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM2EN) == 0U) + +#define __HAL_RCC_TIM3_IS_CLK_DISABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM3EN) == 0U) + +#if defined(TIM4) +#define __HAL_RCC_TIM4_IS_CLK_DISABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM4EN) == 0U) +#endif /* TIM4 */ + +#if defined(TIM5) +#define __HAL_RCC_TIM5_IS_CLK_DISABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM5EN) == 0U) +#endif /* TIM5 */ + +#define __HAL_RCC_TIM6_IS_CLK_DISABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM6EN) == 0U) + +#define __HAL_RCC_TIM7_IS_CLK_DISABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM7EN) == 0U) + +#if defined(TIM12) +#define __HAL_RCC_TIM12_IS_CLK_DISABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM12EN) == 0U) +#endif /* TIM12 */ + +#if defined(TIM13) +#define __HAL_RCC_TIM13_IS_CLK_DISABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM13EN) == 0U) +#endif /* TIM13 */ + +#if defined(TIM14) +#define __HAL_RCC_TIM14_IS_CLK_DISABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_TIM14EN) == 0U) +#endif /* TIM14 */ + +#define __HAL_RCC_WWDG_IS_CLK_DISABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_WWDGEN) == 0U) + +#if defined(OPAMP1) +#define __HAL_RCC_OPAMP_IS_CLK_DISABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_OPAMPEN) == 0U) +#endif /* OPAMP1 */ + +#define __HAL_RCC_SPI2_IS_CLK_DISABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_SPI2EN) == 0U) + +#define __HAL_RCC_SPI3_IS_CLK_DISABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_SPI3EN) == 0U) + +#if defined(COMP1) +#define __HAL_RCC_COMP_IS_CLK_DISABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_COMPEN) == 0U) +#endif /* COMP1 */ + +#define __HAL_RCC_USART2_IS_CLK_DISABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_USART2EN) == 0U) + +#define __HAL_RCC_USART3_IS_CLK_DISABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_USART3EN) == 0U) + +#if defined(UART4) +#define __HAL_RCC_UART4_IS_CLK_DISABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_UART4EN) == 0U) +#endif /* UART4 */ + +#if defined(UART5) +#define __HAL_RCC_UART5_IS_CLK_DISABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_UART5EN) == 0U) +#endif /* UART5 */ + +#define __HAL_RCC_I2C1_IS_CLK_DISABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_I2C1EN) == 0U) + +#define __HAL_RCC_I2C2_IS_CLK_DISABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_I2C2EN) == 0U) + +#define __HAL_RCC_I3C1_IS_CLK_DISABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_I3C1EN) == 0U) + +#define __HAL_RCC_CRS_IS_CLK_DISABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_CRSEN) == 0U) + +#if defined(USART6) +#define __HAL_RCC_USART6_IS_CLK_DISABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_USART6EN) == 0U) +#endif /* USART6 */ + +#if defined(USART10) +#define __HAL_RCC_USART10_IS_CLK_DISABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_USART10EN) == 0U) +#endif /* USART10 */ + +#if defined(USART11) +#define __HAL_RCC_USART11_IS_CLK_DISABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_USART11EN) == 0U) +#endif /* USART11 */ + +#if defined(CEC) +#define __HAL_RCC_CEC_IS_CLK_DISABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_CECEN) == 0U) +#endif /* CEC */ + +#if defined(UART7) +#define __HAL_RCC_UART7_IS_CLK_DISABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_UART7EN) == 0U) +#endif /* UART7 */ + +#if defined(UART8) +#define __HAL_RCC_UART8_IS_CLK_DISABLED() (READ_BIT(RCC->APB1LENR, RCC_APB1LENR_UART8EN) == 0U) +#endif /* UART8 */ + + +#if defined(UART9) +#define __HAL_RCC_UART9_IS_CLK_DISABLED() (READ_BIT(RCC->APB1HENR, RCC_APB1HENR_UART9EN) == 0U) +#endif /* UART9 */ + +#if defined(UART12) +#define __HAL_RCC_UART12_IS_CLK_DISABLED() (READ_BIT(RCC->APB1HENR, RCC_APB1HENR_UART12EN) == 0U) +#endif /* UART12 */ + +#define __HAL_RCC_DTS_IS_CLK_DISABLED() (READ_BIT(RCC->APB1HENR, RCC_APB1HENR_DTSEN) == 0U) + +#define __HAL_RCC_LPTIM2_IS_CLK_DISABLED() (READ_BIT(RCC->APB1HENR, RCC_APB1HENR_LPTIM2EN) == 0U) + +#define __HAL_RCC_FDCAN_IS_CLK_DISABLED() (READ_BIT(RCC->APB1HENR, RCC_APB1HENR_FDCANEN) == 0U) + +#if defined(UCPD1) +#define __HAL_RCC_UCPD1_IS_CLK_DISABLED() (READ_BIT(RCC->APB1HENR, RCC_APB1HENR_UCPD1EN) == 0U) +#endif /* UCPD1 */ +/** + * @} + */ + +/** @defgroup RCC_APB2_Peripheral_Clock_Enable_Disable_Status APB2 Peripheral Clock Enabled or Disabled Status + * @brief Check whether the APB2 peripheral clock is enabled or not. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ + +#define __HAL_RCC_TIM1_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM1EN) != 0U) + +#define __HAL_RCC_SPI1_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI1EN) != 0U) + +#if defined(TIM8) +#define __HAL_RCC_TIM8_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM8EN) != 0U) +#endif /* TIM8 */ + +#define __HAL_RCC_USART1_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN) != 0U) + +#if defined(TIM15) +#define __HAL_RCC_TIM15_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM15EN) != 0U) +#endif /* TIM15 */ + +#if defined(TIM16) +#define __HAL_RCC_TIM16_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM16EN) != 0U) +#endif /* TIM16 */ + +#if defined(TIM17) +#define __HAL_RCC_TIM17_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM17EN) != 0U) +#endif /* TIM17 */ + +#if defined(SPI4) +#define __HAL_RCC_SPI4_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI4EN) != 0U) +#endif /* SPI4 */ + +#if defined(SPI6) +#define __HAL_RCC_SPI6_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI6EN) != 0U) +#endif /* SPI6 */ + +#if defined(SAI1) +#define __HAL_RCC_SAI1_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SAI1EN) != 0U) +#endif /* SAI1 */ + +#if defined(SAI2) +#define __HAL_RCC_SAI2_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SAI2EN) != 0U) +#endif /* SAI2 */ + +#define __HAL_RCC_USB_IS_CLK_ENABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_USBEN) != 0U) + + +#define __HAL_RCC_TIM1_IS_CLK_DISABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM1EN) == 0U) + +#define __HAL_RCC_SPI1_IS_CLK_DISABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI1EN) == 0U) + +#if defined(TIM8) +#define __HAL_RCC_TIM8_IS_CLK_DISABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM8EN) == 0U) +#endif /* TIM8 */ + +#define __HAL_RCC_USART1_IS_CLK_DISABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN) == 0U) + +#if defined(TIM15) +#define __HAL_RCC_TIM15_IS_CLK_DISABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM15EN) == 0U) +#endif /* TIM15 */ + +#if defined(TIM16) +#define __HAL_RCC_TIM16_IS_CLK_DISABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM16EN) == 0U) +#endif /* TIM16 */ + +#if defined(TIM17) +#define __HAL_RCC_TIM17_IS_CLK_DISABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM17EN) == 0U) +#endif /* TIM17 */ + +#if defined(SPI4) +#define __HAL_RCC_SPI4_IS_CLK_DISABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI4EN) == 0U) +#endif /* SPI4 */ + +#if defined(SPI6) +#define __HAL_RCC_SPI6_IS_CLK_DISABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI6EN) == 0U) +#endif /* SPI6 */ + +#if defined(SAI1) +#define __HAL_RCC_SAI1_IS_CLK_DISABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SAI1EN) == 0U) +#endif /* SAI1 */ + +#if defined(SAI2) +#define __HAL_RCC_SAI2_IS_CLK_DISABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SAI2EN) == 0U) +#endif /* SAI2 */ + +#define __HAL_RCC_USB_IS_CLK_DISABLED() (READ_BIT(RCC->APB2ENR, RCC_APB2ENR_USBEN) == 0U) +/** + * @} + */ + +/** @defgroup RCC_APB3_Peripheral_Clock_Enable_Disable_Status APB3 Peripheral Clock Enabled or Disabled Status + * @brief Check whether the APB3 peripheral clock is enabled or not. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ + +#define __HAL_RCC_SBS_IS_CLK_ENABLED() (READ_BIT(RCC->APB3ENR, RCC_APB3ENR_SBSEN) != 0U) + +#if defined(SPI5) +#define __HAL_RCC_SPI5_IS_CLK_ENABLED() (READ_BIT(RCC->APB3ENR, RCC_APB3ENR_SPI5EN) != 0U) +#endif /* SPI5 */ + +#define __HAL_RCC_LPUART1_IS_CLK_ENABLED() (READ_BIT(RCC->APB3ENR, RCC_APB3ENR_LPUART1EN) != 0U) + +#if defined(I2C3) +#define __HAL_RCC_I2C3_IS_CLK_ENABLED() (READ_BIT(RCC->APB3ENR, RCC_APB3ENR_I2C3EN) != 0U) +#endif /* I2C3 */ + +#if defined(I2C4) +#define __HAL_RCC_I2C4_IS_CLK_ENABLED() (READ_BIT(RCC->APB3ENR, RCC_APB3ENR_I2C4EN) != 0U) +#endif /* I2C4 */ + +#if defined(I3C2) +#define __HAL_RCC_I3C2_IS_CLK_ENABLED() (READ_BIT(RCC->APB3ENR, RCC_APB3ENR_I3C2EN) != 0U) +#endif /* I3C2 */ + +#define __HAL_RCC_LPTIM1_IS_CLK_ENABLED() (READ_BIT(RCC->APB3ENR, RCC_APB3ENR_LPTIM1EN) != 0U) + +#if defined(LPTIM3) +#define __HAL_RCC_LPTIM3_IS_CLK_ENABLED() (READ_BIT(RCC->APB3ENR, RCC_APB3ENR_LPTIM3EN) != 0U) +#endif /* LPTIM3 */ + +#if defined(LPTIM4) +#define __HAL_RCC_LPTIM4_IS_CLK_ENABLED() (READ_BIT(RCC->APB3ENR, RCC_APB3ENR_LPTIM4EN) != 0U) +#endif /* LPTIM4 */ + +#if defined(LPTIM5) +#define __HAL_RCC_LPTIM5_IS_CLK_ENABLED() (READ_BIT(RCC->APB3ENR, RCC_APB3ENR_LPTIM5EN) != 0U) +#endif /* LPTIM5 */ + +#if defined(LPTIM6) +#define __HAL_RCC_LPTIM6_IS_CLK_ENABLED() (READ_BIT(RCC->APB3ENR, RCC_APB3ENR_LPTIM6EN) != 0U) +#endif /* LPTIM6 */ + +#if defined(VREFBUF) +#define __HAL_RCC_VREF_IS_CLK_ENABLED() (READ_BIT(RCC->APB3ENR, RCC_APB3ENR_VREFEN) != 0U) +#endif /* VREFBUF */ + +#define __HAL_RCC_RTC_IS_CLK_ENABLED() (READ_BIT(RCC->APB3ENR, RCC_APB3ENR_RTCAPBEN) != 0U) + + +#define __HAL_RCC_SBS_IS_CLK_DISABLED() (READ_BIT(RCC->APB3ENR, RCC_APB3ENR_SBSEN) == 0U) + +#if defined(SPI5) +#define __HAL_RCC_SPI5_IS_CLK_DISABLED() (READ_BIT(RCC->APB3ENR, RCC_APB3ENR_SPI5EN) == 0U) +#endif /* SPI5 */ + +#define __HAL_RCC_LPUART1_IS_CLK_DISABLED() (READ_BIT(RCC->APB3ENR, RCC_APB3ENR_LPUART1EN) == 0U) + +#if defined(I2C3) +#define __HAL_RCC_I2C3_IS_CLK_DISABLED() (READ_BIT(RCC->APB3ENR, RCC_APB3ENR_I2C3EN) == 0U) +#endif /* I2C3 */ + +#if defined(I2C4) +#define __HAL_RCC_I2C4_IS_CLK_DISABLED() (READ_BIT(RCC->APB3ENR, RCC_APB3ENR_I2C4EN) == 0U) +#endif /* I2C4 */ + +#if defined(I3C2) +#define __HAL_RCC_I3C2_IS_CLK_DISABLED() (READ_BIT(RCC->APB3ENR, RCC_APB3ENR_I3C2EN) == 0U) +#endif /* I3C2 */ + +#define __HAL_RCC_LPTIM1_IS_CLK_DISABLED() (READ_BIT(RCC->APB3ENR, RCC_APB3ENR_LPTIM1EN) == 0U) + +#if defined(LPTIM3) +#define __HAL_RCC_LPTIM3_IS_CLK_DISABLED() (READ_BIT(RCC->APB3ENR, RCC_APB3ENR_LPTIM3EN) == 0U) +#endif /* LPTIM3 */ + +#if defined(LPTIM4) +#define __HAL_RCC_LPTIM4_IS_CLK_DISABLED() (READ_BIT(RCC->APB3ENR, RCC_APB3ENR_LPTIM4EN) == 0U) +#endif /* LPTIM4 */ + +#if defined(LPTIM5) +#define __HAL_RCC_LPTIM5_IS_CLK_DISABLED() (READ_BIT(RCC->APB3ENR, RCC_APB3ENR_LPTIM5EN) == 0U) +#endif /* LPTIM5 */ + +#if defined(LPTIM6) +#define __HAL_RCC_LPTIM6_IS_CLK_DISABLED() (READ_BIT(RCC->APB3ENR, RCC_APB3ENR_LPTIM6EN) == 0U) +#endif /* LPTIM6 */ + +#if defined(VREFBUF) +#define __HAL_RCC_VREF_IS_CLK_DISABLED() (READ_BIT(RCC->APB3ENR, RCC_APB3ENR_VREFEN) == 0U) +#endif /* VREFBUF */ + +#define __HAL_RCC_RTC_IS_CLK_DISABLED() (READ_BIT(RCC->APB3ENR, RCC_APB3ENR_RTCAPBEN) == 0U) + +/** + * @} + */ + +/** @defgroup RCC_AHB_APB_Branch_Clock_Disable_Status AHB APB Branch Clock Disabled Status + * @brief Check whether the AHBx/APBx branch clock for all AHBx/APBx peripherals is disabled or not. + * @note It is recommended to disable the clock of all peripherals (by writing 0 in + * the AHBxENR/APBxENR register) before Disabling the corresponding Bus Branch clock. + * Some peripheral bus clocks are not affected by branch clock disabling as IWDG (APB1), + * SRAM2/SRAM3 (AHB2) and FLITF/BKRAM/ICACHE/DCACHE/SRAM1 (AHB1). + * @{ + */ + +#define __HAL_RCC_AHB1_IS_CLK_DISABLED() (READ_BIT(RCC->CFGR2, RCC_CFGR2_AHB1DIS) != 0U) + +#define __HAL_RCC_AHB2_IS_CLK_DISABLED() (READ_BIT(RCC->CFGR2, RCC_CFGR2_AHB2DIS) != 0U) + +#if defined(AHB4PERIPH_BASE) +#define __HAL_RCC_AHB4_IS_CLK_DISABLED() (READ_BIT(RCC->CFGR2, RCC_CFGR2_AHB4DIS) != 0U) +#endif /* AHB4PERIPH_BASE */ + +#define __HAL_RCC_APB1_IS_CLK_DISABLED() (READ_BIT(RCC->CFGR2, RCC_CFGR2_APB1DIS) != 0U) + +#define __HAL_RCC_APB2_IS_CLK_DISABLED() (READ_BIT(RCC->CFGR2, RCC_CFGR2_APB2DIS) != 0U) + +#define __HAL_RCC_APB3_IS_CLK_DISABLED() (READ_BIT(RCC->CFGR2, RCC_CFGR2_APB3DIS) != 0U) + +/** + * @} + */ + +/** @defgroup RCC_AHB1_Force_Release_Reset AHB1 Peripheral Force Release Reset + * @brief Force or release AHB1 peripheral reset. + * @{ + */ + +#define __HAL_RCC_AHB1_FORCE_RESET() WRITE_REG(RCC->AHB1RSTR, 0x010AD003U) + +#define __HAL_RCC_GPDMA1_FORCE_RESET() SET_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_GPDMA1RST) + +#define __HAL_RCC_GPDMA2_FORCE_RESET() SET_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_GPDMA2RST) + +#if defined(CORDIC) +#define __HAL_RCC_CORDIC_FORCE_RESET() SET_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_CORDICRST) +#endif /* CORDIC */ + +#if defined(FMAC) +#define __HAL_RCC_FMAC_FORCE_RESET() SET_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_FMACRST) +#endif /* FMAC */ + +#define __HAL_RCC_CRC_FORCE_RESET() SET_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_CRCRST) + +#define __HAL_RCC_RAMCFG_FORCE_RESET() SET_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_RAMCFGRST) + +#if defined(ETH) +#define __HAL_RCC_ETH_FORCE_RESET() SET_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_ETHRST) +#endif /* ETH */ + +#define __HAL_RCC_GTZC1_FORCE_RESET() SET_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_TZSC1RST) + + +#define __HAL_RCC_AHB1_RELEASE_RESET() WRITE_REG(RCC->AHB1RSTR, 0x00000000U) + +#define __HAL_RCC_GPDMA1_RELEASE_RESET() CLEAR_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_GPDMA1RST) + +#define __HAL_RCC_GPDMA2_RELEASE_RESET() CLEAR_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_GPDMA2RST) + +#if defined(CORDIC) +#define __HAL_RCC_CORDIC_RELEASE_RESET() CLEAR_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_CORDICRST) +#endif /* CORDIC */ + +#if defined(FMAC) +#define __HAL_RCC_FMAC_RELEASE_RESET() CLEAR_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_FMACRST) +#endif /* FMAC */ + +#define __HAL_RCC_CRC_RELEASE_RESET() CLEAR_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_CRCRST) + +#define __HAL_RCC_RAMCFG_RELEASE_RESET() CLEAR_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_RAMCFGRST) + +#if defined(ETH) +#define __HAL_RCC_ETH_RELEASE_RESET() CLEAR_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_ETHRST) +#endif /* ETH */ + +#define __HAL_RCC_GTZC1_RELEASE_RESET() CLEAR_BIT(RCC->AHB1RSTR, RCC_AHB1RSTR_TZSC1RST) + +/** + * @} + */ + +/** @defgroup RCC_AHB2_Force_Release_Reset AHB2 Peripheral Force Release Reset + * @brief Force or release AHB2 peripheral reset. + * @{ + */ + +#define __HAL_RCC_AHB2_FORCE_RESET() WRITE_REG(RCC->AHB2RSTR, 0x001F1DFFU) + +#define __HAL_RCC_GPIOA_FORCE_RESET() SET_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_GPIOARST) + +#define __HAL_RCC_GPIOB_FORCE_RESET() SET_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_GPIOBRST) + +#define __HAL_RCC_GPIOC_FORCE_RESET() SET_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_GPIOCRST) + +#define __HAL_RCC_GPIOD_FORCE_RESET() SET_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_GPIODRST) + +#if defined(GPIOE) +#define __HAL_RCC_GPIOE_FORCE_RESET() SET_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_GPIOERST) +#endif /* GPIOE */ + +#if defined(GPIOF) +#define __HAL_RCC_GPIOF_FORCE_RESET() SET_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_GPIOFRST) +#endif /* GPIOF */ + +#if defined(GPIOG) +#define __HAL_RCC_GPIOG_FORCE_RESET() SET_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_GPIOGRST) +#endif /* GPIOG */ + +#define __HAL_RCC_GPIOH_FORCE_RESET() SET_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_GPIOHRST) + +#if defined(GPIOI) +#define __HAL_RCC_GPIOI_FORCE_RESET() SET_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_GPIOIRST) +#endif /* GPIOI */ + +#define __HAL_RCC_ADC_FORCE_RESET() SET_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_ADCRST) + +#define __HAL_RCC_DAC1_FORCE_RESET() SET_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_DAC1RST) + +#if defined(DCMI) +#define __HAL_RCC_DCMI_PSSI_FORCE_RESET() SET_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_DCMI_PSSIRST) +#define __HAL_RCC_DCMI_FORCE_RESET() __HAL_RCC_DCMI_PSSI_FORCE_RESET() /* for API backward compatibility */ +#endif /* DCMI */ + +#if defined(AES) +#define __HAL_RCC_AES_FORCE_RESET() SET_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_AESRST) +#endif /* AES */ + +#if defined(HASH) +#define __HAL_RCC_HASH_FORCE_RESET() SET_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_HASHRST) +#endif /* HASH */ + +#define __HAL_RCC_RNG_FORCE_RESET() SET_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_RNGRST) + +#if defined(PKA) +#define __HAL_RCC_PKA_FORCE_RESET() SET_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_PKARST) +#endif /* PKA */ + +#if defined(SAES) +#define __HAL_RCC_SAES_FORCE_RESET() SET_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_SAESRST) +#endif /* SAES*/ + + +#define __HAL_RCC_AHB2_RELEASE_RESET() WRITE_REG(RCC->AHB2RSTR, 0x00000000U) + +#define __HAL_RCC_GPIOA_RELEASE_RESET() CLEAR_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_GPIOARST) + +#define __HAL_RCC_GPIOB_RELEASE_RESET() CLEAR_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_GPIOBRST) + +#define __HAL_RCC_GPIOC_RELEASE_RESET() CLEAR_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_GPIOCRST) + +#define __HAL_RCC_GPIOD_RELEASE_RESET() CLEAR_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_GPIODRST) + +#if defined(GPIOE) +#define __HAL_RCC_GPIOE_RELEASE_RESET() CLEAR_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_GPIOERST) +#endif /* GPIOE */ + +#if defined(GPIOF) +#define __HAL_RCC_GPIOF_RELEASE_RESET() CLEAR_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_GPIOFRST) +#endif /* GPIOF */ + +#if defined(GPIOG) +#define __HAL_RCC_GPIOG_RELEASE_RESET() CLEAR_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_GPIOGRST) +#endif /* GPIOG */ + +#define __HAL_RCC_GPIOH_RELEASE_RESET() CLEAR_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_GPIOHRST) + +#if defined(GPIOG) +#define __HAL_RCC_GPIOI_RELEASE_RESET() CLEAR_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_GPIOIRST) +#endif /* GPIOI */ + +#define __HAL_RCC_ADC_RELEASE_RESET() CLEAR_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_ADCRST) + +#define __HAL_RCC_DAC1_RELEASE_RESET() CLEAR_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_DAC1RST) + +#if defined(DCMI) +#define __HAL_RCC_DCMI_PSSI_RELEASE_RESET() CLEAR_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_DCMI_PSSIRST) +#define __HAL_RCC_DCMI_RELEASE_RESET() __HAL_RCC_DCMI_PSSI_RELEASE_RESET() /* for API backward compatibility */ +#endif /* DCMI */ + +#if defined(AES) +#define __HAL_RCC_AES_RELEASE_RESET() CLEAR_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_AESRST) +#endif /* AES */ + +#if defined(HASH) +#define __HAL_RCC_HASH_RELEASE_RESET() CLEAR_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_HASHRST) +#endif /* HASH */ + +#define __HAL_RCC_RNG_RELEASE_RESET() CLEAR_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_RNGRST) + +#if defined(PKA) +#define __HAL_RCC_PKA_RELEASE_RESET() CLEAR_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_PKARST) +#endif /* PKA */ + +#if defined(SAES) +#define __HAL_RCC_SAES_RELEASE_RESET() CLEAR_BIT(RCC->AHB2RSTR, RCC_AHB2RSTR_SAESRST) +#endif /* SAES*/ + +/** + * @} + */ + +/** @defgroup RCC_AHB4_Force_Release_Reset AHB4 Peripheral Force Release Reset + * @brief Force or release AHB4 peripheral reset. + * @{ + */ + +#if defined(FMC_BASE) +#define __HAL_RCC_AHB4_FORCE_RESET() WRITE_REG(RCC->AHB4RSTR, 0x00111880U) +#endif /* FMC_BASE */ + +#if defined(OTFDEC1) +#define __HAL_RCC_OTFDEC1_FORCE_RESET() SET_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_OTFDEC1RST) +#endif /* OTFDEC1 */ + +#if defined(SDMMC1) +#define __HAL_RCC_SDMMC1_FORCE_RESET() SET_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_SDMMC1RST) +#endif /* SDMMC1 */ + +#if defined(SDMMC2) +#define __HAL_RCC_SDMMC2_FORCE_RESET() SET_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_SDMMC2RST) +#endif /* SDMMC2 */ + +#if defined(FMC_BASE) +#define __HAL_RCC_FMC_FORCE_RESET() SET_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_FMCRST) +#endif /* FMC_BASE */ + +#if defined(OCTOSPI1) +#define __HAL_RCC_OSPI1_FORCE_RESET() SET_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_OCTOSPI1RST) +#endif /* OCTOSPI1 */ + + +#if defined(FMC_BASE) +#define __HAL_RCC_AHB4_RELEASE_RESET() WRITE_REG(RCC->AHB4RSTR, 0x00000000U) +#endif /* FMC_BASE */ + +#if defined(OTFDEC1) +#define __HAL_RCC_OTFDEC1_RELEASE_RESET() CLEAR_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_OTFDEC1RST) +#endif /* OTFDEC1 */ + +#if defined(SDMMC1) +#define __HAL_RCC_SDMMC1_RELEASE_RESET() CLEAR_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_SDMMC1RST) +#endif /* SDMMC1 */ + +#if defined(SDMMC2) +#define __HAL_RCC_SDMMC2_RELEASE_RESET() CLEAR_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_SDMMC2RST) +#endif /* SDMMC2 */ + +#if defined(FMC_BASE) +#define __HAL_RCC_FMC_RELEASE_RESET() CLEAR_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_FMCRST) +#endif /* FMC_BASE */ + +#if defined(OCTOSPI1) +#define __HAL_RCC_OSPI1_RELEASE_RESET() CLEAR_BIT(RCC->AHB4RSTR, RCC_AHB4RSTR_OCTOSPI1RST) +#endif /* OCTOSPI1 */ + +/** + * @} + */ + + + +/** @defgroup RCC_APB1_Force_Release_Reset APB1 Peripheral Force Release Reset + * @brief Force or release APB1 peripheral reset. + * @{ + */ + +#define __HAL_RCC_APB1_FORCE_RESET() do { \ + WRITE_REG(RCC->APB1LRSTR, 0xDFFEC1FFU); \ + WRITE_REG(RCC->APB1HRSTR, 0x4080062BU); \ + } while(0) + +#define __HAL_RCC_TIM2_FORCE_RESET() SET_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_TIM2RST) + +#define __HAL_RCC_TIM3_FORCE_RESET() SET_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_TIM3RST) + +#if defined(TIM4) +#define __HAL_RCC_TIM4_FORCE_RESET() SET_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_TIM4RST) +#endif /* TIM4 */ + +#if defined(TIM5) +#define __HAL_RCC_TIM5_FORCE_RESET() SET_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_TIM5RST) +#endif /* TIM5 */ + +#define __HAL_RCC_TIM6_FORCE_RESET() SET_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_TIM6RST) + +#define __HAL_RCC_TIM7_FORCE_RESET() SET_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_TIM7RST) + +#if defined(TIM12) +#define __HAL_RCC_TIM12_FORCE_RESET() SET_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_TIM12RST) +#endif /* TIM12 */ + +#if defined(TIM13) +#define __HAL_RCC_TIM13_FORCE_RESET() SET_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_TIM13RST) +#endif /* TIM13 */ + +#if defined(TIM14) +#define __HAL_RCC_TIM14_FORCE_RESET() SET_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_TIM14RST) +#endif /* TIM14 */ + +#if defined(OPAMP1) +#define __HAL_RCC_OPAMP_FORCE_RESET() SET_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_OPAMPRST) +#endif /* OPAMP1 */ + +#define __HAL_RCC_SPI2_FORCE_RESET() SET_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_SPI2RST) + +#define __HAL_RCC_SPI3_FORCE_RESET() SET_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_SPI3RST) + +#if defined(COMP1) +#define __HAL_RCC_COMP_FORCE_RESET() SET_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_COMPRST) +#endif /* COMP1 */ + +#define __HAL_RCC_USART2_FORCE_RESET() SET_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_USART2RST) + +#define __HAL_RCC_USART3_FORCE_RESET() SET_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_USART3RST) + +#if defined(UART4) +#define __HAL_RCC_UART4_FORCE_RESET() SET_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_UART4RST) +#endif /* UART4 */ + +#if defined(UART5) +#define __HAL_RCC_UART5_FORCE_RESET() SET_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_UART5RST) +#endif /* UART5 */ + +#define __HAL_RCC_I2C1_FORCE_RESET() SET_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_I2C1RST) + +#define __HAL_RCC_I2C2_FORCE_RESET() SET_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_I2C2RST) + +#define __HAL_RCC_I3C1_FORCE_RESET() SET_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_I3C1RST) + +#define __HAL_RCC_CRS_FORCE_RESET() SET_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_CRSRST) + +#if defined(USART6) +#define __HAL_RCC_USART6_FORCE_RESET() SET_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_USART6RST) +#endif /* USART6 */ + +#if defined(USART10) +#define __HAL_RCC_USART10_FORCE_RESET() SET_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_USART10RST) +#endif /* USART10 */ + +#if defined(USART11) +#define __HAL_RCC_USART11_FORCE_RESET() SET_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_USART11RST) +#endif /* USART11 */ + +#if defined(CEC) +#define __HAL_RCC_CEC_FORCE_RESET() SET_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_CECRST) +#endif /* CEC */ + +#if defined(UART7) +#define __HAL_RCC_UART7_FORCE_RESET() SET_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_UART7RST) +#endif /* UART7 */ + +#if defined(UART8) +#define __HAL_RCC_UART8_FORCE_RESET() SET_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_UART8RST) +#endif /* UART8 */ + + +#if defined(UART9) +#define __HAL_RCC_UART9_FORCE_RESET() SET_BIT(RCC->APB1HRSTR, RCC_APB1HRSTR_UART9RST) +#endif /* UART9 */ + +#if defined(UART12) +#define __HAL_RCC_UART12_FORCE_RESET() SET_BIT(RCC->APB1HRSTR, RCC_APB1HRSTR_UART12RST) +#endif /* UART12 */ + +#define __HAL_RCC_DTS_FORCE_RESET() SET_BIT(RCC->APB1HRSTR, RCC_APB1HRSTR_DTSRST) + +#define __HAL_RCC_LPTIM2_FORCE_RESET() SET_BIT(RCC->APB1HRSTR, RCC_APB1HRSTR_LPTIM2RST) + +#define __HAL_RCC_FDCAN_FORCE_RESET() SET_BIT(RCC->APB1HRSTR, RCC_APB1HRSTR_FDCANRST) + +#if defined(UCPD1) +#define __HAL_RCC_UCPD1_FORCE_RESET() SET_BIT(RCC->APB1HRSTR, RCC_APB1HRSTR_UCPD1RST) +#endif /* UCPD1 */ + + +#define __HAL_RCC_APB1_RELEASE_RESET() do { \ + WRITE_REG(RCC->APB1LRSTR, 0x00000000U); \ + WRITE_REG(RCC->APB1HRSTR, 0x00000000U); \ + } while(0) + +#define __HAL_RCC_TIM2_RELEASE_RESET() CLEAR_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_TIM2RST) + +#define __HAL_RCC_TIM3_RELEASE_RESET() CLEAR_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_TIM3RST) + +#if defined(TIM4) +#define __HAL_RCC_TIM4_RELEASE_RESET() CLEAR_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_TIM4RST) +#endif /* TIM4 */ + +#if defined(TIM5) +#define __HAL_RCC_TIM5_RELEASE_RESET() CLEAR_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_TIM5RST) +#endif /* TIM5 */ + +#define __HAL_RCC_TIM6_RELEASE_RESET() CLEAR_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_TIM6RST) + +#define __HAL_RCC_TIM7_RELEASE_RESET() CLEAR_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_TIM7RST) + +#if defined(TIM12) +#define __HAL_RCC_TIM12_RELEASE_RESET() CLEAR_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_TIM12RST) +#endif /* TIM12 */ + +#if defined(TIM13) +#define __HAL_RCC_TIM13_RELEASE_RESET() CLEAR_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_TIM13RST) +#endif /* TIM13 */ + +#if defined(TIM14) +#define __HAL_RCC_TIM14_RELEASE_RESET() CLEAR_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_TIM14RST) +#endif /* TIM14 */ + +#if defined(OPAMP1) +#define __HAL_RCC_OPAMP_RELEASE_RESET() CLEAR_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_OPAMPRST) +#endif /* OPAMP1 */ + +#define __HAL_RCC_SPI2_RELEASE_RESET() CLEAR_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_SPI2RST) + +#define __HAL_RCC_SPI3_RELEASE_RESET() CLEAR_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_SPI3RST) + +#if defined(COMP1) +#define __HAL_RCC_COMP_RELEASE_RESET() CLEAR_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_COMPRST) +#endif /* COMP1 */ + +#define __HAL_RCC_USART2_RELEASE_RESET() CLEAR_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_USART2RST) + +#define __HAL_RCC_USART3_RELEASE_RESET() CLEAR_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_USART3RST) + +#if defined(UART4) +#define __HAL_RCC_UART4_RELEASE_RESET() CLEAR_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_UART4RST) +#endif /* UART4 */ + +#if defined(UART5) +#define __HAL_RCC_UART5_RELEASE_RESET() CLEAR_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_UART5RST) +#endif /* UART5 */ + +#define __HAL_RCC_I2C1_RELEASE_RESET() CLEAR_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_I2C1RST) + +#define __HAL_RCC_I2C2_RELEASE_RESET() CLEAR_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_I2C2RST) + +#define __HAL_RCC_I3C1_RELEASE_RESET() CLEAR_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_I3C1RST) + +#define __HAL_RCC_CRS_RELEASE_RESET() CLEAR_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_CRSRST) + +#if defined(USART6) +#define __HAL_RCC_USART6_RELEASE_RESET() CLEAR_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_USART6RST) +#endif /* USART6 */ + +#if defined(USART10) +#define __HAL_RCC_USART10_RELEASE_RESET() CLEAR_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_USART10RST) +#endif /* USART10 */ + +#if defined(USART11) +#define __HAL_RCC_USART11_RELEASE_RESET() CLEAR_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_USART11RST) +#endif /* USART11 */ + +#if defined(CEC) +#define __HAL_RCC_CEC_RELEASE_RESET() CLEAR_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_CECRST) +#endif /* CEC */ + +#if defined(UART7) +#define __HAL_RCC_UART7_RELEASE_RESET() CLEAR_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_UART7RST) +#endif /* UART7 */ + +#if defined(UART8) +#define __HAL_RCC_UART8_RELEASE_RESET() CLEAR_BIT(RCC->APB1LRSTR, RCC_APB1LRSTR_UART8RST) +#endif /* UART8 */ + + +#if defined(UART9) +#define __HAL_RCC_UART9_RELEASE_RESET() CLEAR_BIT(RCC->APB1HRSTR, RCC_APB1HRSTR_UART9RST) +#endif /* UART9 */ + +#if defined(UART12) +#define __HAL_RCC_UART12_RELEASE_RESET() CLEAR_BIT(RCC->APB1HRSTR, RCC_APB1HRSTR_UART12RST) +#endif /* UART12 */ + +#define __HAL_RCC_DTS_RELEASE_RESET() CLEAR_BIT(RCC->APB1HRSTR, RCC_APB1HRSTR_DTSRST) + +#define __HAL_RCC_LPTIM2_RELEASE_RESET() CLEAR_BIT(RCC->APB1HRSTR, RCC_APB1HRSTR_LPTIM2RST) + +#define __HAL_RCC_FDCAN_RELEASE_RESET() CLEAR_BIT(RCC->APB1HRSTR, RCC_APB1HRSTR_FDCANRST) + +#if defined(UCPD1) +#define __HAL_RCC_UCPD1_RELEASE_RESET() CLEAR_BIT(RCC->APB1HRSTR, RCC_APB1HRSTR_UCPD1RST) +#endif /* UCPD1 */ + +/** + * @} + */ + +/** @defgroup RCC_APB2_Force_Release_Reset APB2 Peripheral Force Release Reset + * @brief Force or release APB2 peripheral reset. + * @{ + */ + +#define __HAL_RCC_APB2_FORCE_RESET() WRITE_REG(RCC->APB2RSTR, 0x017F7800U) + +#define __HAL_RCC_TIM1_FORCE_RESET() SET_BIT(RCC->APB2RSTR, RCC_APB2RSTR_TIM1RST) + +#define __HAL_RCC_SPI1_FORCE_RESET() SET_BIT(RCC->APB2RSTR, RCC_APB2RSTR_SPI1RST) + +#if defined(TIM8) +#define __HAL_RCC_TIM8_FORCE_RESET() SET_BIT(RCC->APB2RSTR, RCC_APB2RSTR_TIM8RST) +#endif /* TIM8 */ + +#define __HAL_RCC_USART1_FORCE_RESET() SET_BIT(RCC->APB2RSTR, RCC_APB2RSTR_USART1RST) + +#if defined(TIM15) +#define __HAL_RCC_TIM15_FORCE_RESET() SET_BIT(RCC->APB2RSTR, RCC_APB2RSTR_TIM15RST) +#endif /* TIM15 */ + +#if defined(TIM16) +#define __HAL_RCC_TIM16_FORCE_RESET() SET_BIT(RCC->APB2RSTR, RCC_APB2RSTR_TIM16RST) +#endif /* TIM16 */ + +#if defined(TIM17) +#define __HAL_RCC_TIM17_FORCE_RESET() SET_BIT(RCC->APB2RSTR, RCC_APB2RSTR_TIM17RST) +#endif /* TIM17 */ + +#if defined(SPI4) +#define __HAL_RCC_SPI4_FORCE_RESET() SET_BIT(RCC->APB2RSTR, RCC_APB2RSTR_SPI4RST) +#endif /* SPI4 */ + +#if defined(SPI6) +#define __HAL_RCC_SPI6_FORCE_RESET() SET_BIT(RCC->APB2RSTR, RCC_APB2RSTR_SPI6RST) +#endif /* SPI6 */ + +#if defined(SAI1) +#define __HAL_RCC_SAI1_FORCE_RESET() SET_BIT(RCC->APB2RSTR, RCC_APB2RSTR_SAI1RST) +#endif /* SAI1 */ + +#if defined(SAI2) +#define __HAL_RCC_SAI2_FORCE_RESET() SET_BIT(RCC->APB2RSTR, RCC_APB2RSTR_SAI2RST) +#endif /* SAI2 */ + +#define __HAL_RCC_USB_FORCE_RESET() SET_BIT(RCC->APB2RSTR, RCC_APB2RSTR_USBRST) + + +#define __HAL_RCC_APB2_RELEASE_RESET() WRITE_REG(RCC->APB2RSTR, 0x00000000U) + +#define __HAL_RCC_TIM1_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, RCC_APB2RSTR_TIM1RST) + +#define __HAL_RCC_SPI1_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, RCC_APB2RSTR_SPI1RST) + +#if defined(TIM8) +#define __HAL_RCC_TIM8_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, RCC_APB2RSTR_TIM8RST) +#endif /* TIM8 */ + +#define __HAL_RCC_USART1_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, RCC_APB2RSTR_USART1RST) + +#if defined(TIM15) +#define __HAL_RCC_TIM15_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, RCC_APB2RSTR_TIM15RST) +#endif /* TIM15 */ + +#if defined(TIM16) +#define __HAL_RCC_TIM16_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, RCC_APB2RSTR_TIM16RST) +#endif /* TIM16 */ + +#if defined(TIM17) +#define __HAL_RCC_TIM17_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, RCC_APB2RSTR_TIM17RST) +#endif /* TIM17 */ + +#if defined(SPI4) +#define __HAL_RCC_SPI4_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, RCC_APB2RSTR_SPI4RST) +#endif /* SPI4 */ + +#if defined(SPI6) +#define __HAL_RCC_SPI6_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, RCC_APB2RSTR_SPI6RST) +#endif /* SPI6 */ + +#if defined(SAI1) +#define __HAL_RCC_SAI1_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, RCC_APB2RSTR_SAI1RST) +#endif /* SAI1 */ + +#if defined(SAI2) +#define __HAL_RCC_SAI2_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, RCC_APB2RSTR_SAI2RST) +#endif /* SAI2 */ + +#define __HAL_RCC_USB_RELEASE_RESET() CLEAR_BIT(RCC->APB2RSTR, RCC_APB2RSTR_USBRST) + +/** + * @} + */ + +/** @defgroup RCC_APB3_Force_Release_Reset APB3 Peripheral Force Release Reset + * @brief Force or release APB3 peripheral reset. + * @{ + */ + +#define __HAL_RCC_APB3_FORCE_RESET() WRITE_REG(RCC->APB3RSTR, 0x001008E0U) + +#if defined(SPI5) +#define __HAL_RCC_SPI5_FORCE_RESET() SET_BIT(RCC->APB3RSTR, RCC_APB3RSTR_SPI5RST) +#endif /* SPI5 */ + +#define __HAL_RCC_LPUART1_FORCE_RESET() SET_BIT(RCC->APB3RSTR, RCC_APB3RSTR_LPUART1RST) + +#if defined(I2C3) +#define __HAL_RCC_I2C3_FORCE_RESET() SET_BIT(RCC->APB3RSTR, RCC_APB3RSTR_I2C3RST) +#endif /* I2C3 */ + +#if defined(I2C4) +#define __HAL_RCC_I2C4_FORCE_RESET() SET_BIT(RCC->APB3RSTR, RCC_APB3RSTR_I2C4RST) +#endif /* I2C4 */ + +#if defined(I3C2) +#define __HAL_RCC_I3C2_FORCE_RESET() SET_BIT(RCC->APB3RSTR, RCC_APB3RSTR_I3C2RST) +#endif /* I3C2 */ + +#define __HAL_RCC_LPTIM1_FORCE_RESET() SET_BIT(RCC->APB3RSTR, RCC_APB3RSTR_LPTIM1RST) + +#if defined(LPTIM3) +#define __HAL_RCC_LPTIM3_FORCE_RESET() SET_BIT(RCC->APB3RSTR, RCC_APB3RSTR_LPTIM3RST) +#endif /* LPTIM3 */ + +#if defined(LPTIM4) +#define __HAL_RCC_LPTIM4_FORCE_RESET() SET_BIT(RCC->APB3RSTR, RCC_APB3RSTR_LPTIM4RST) +#endif /* LPTIM4 */ + +#if defined(LPTIM5) +#define __HAL_RCC_LPTIM5_FORCE_RESET() SET_BIT(RCC->APB3RSTR, RCC_APB3RSTR_LPTIM5RST) +#endif /* LPTIM5 */ + +#if defined(LPTIM6) +#define __HAL_RCC_LPTIM6_FORCE_RESET() SET_BIT(RCC->APB3RSTR, RCC_APB3RSTR_LPTIM6RST) +#endif /* LPTIM6 */ + +#if defined(VREFBUF) +#define __HAL_RCC_VREF_FORCE_RESET() SET_BIT(RCC->APB3RSTR, RCC_APB3RSTR_VREFRST) +#endif /* VREFBUF */ + +#define __HAL_RCC_APB3_RELEASE_RESET() WRITE_REG(RCC->APB3RSTR, 0x00000000U) + +#if defined(SPI5) +#define __HAL_RCC_SPI5_RELEASE_RESET() CLEAR_BIT(RCC->APB3RSTR, RCC_APB3RSTR_SPI5RST) +#endif /* SPI5 */ + +#define __HAL_RCC_LPUART1_RELEASE_RESET() CLEAR_BIT(RCC->APB3RSTR, RCC_APB3RSTR_LPUART1RST) + +#if defined(I2C3) +#define __HAL_RCC_I2C3_RELEASE_RESET() CLEAR_BIT(RCC->APB3RSTR, RCC_APB3RSTR_I2C3RST) +#endif /* I2C3 */ + +#if defined(I2C4) +#define __HAL_RCC_I2C4_RELEASE_RESET() CLEAR_BIT(RCC->APB3RSTR, RCC_APB3RSTR_I2C4RST) +#endif /* I2C4 */ + +#if defined(I3C2) +#define __HAL_RCC_I3C2_RELEASE_RESET() CLEAR_BIT(RCC->APB3RSTR, RCC_APB3RSTR_I3C2RST) +#endif /* I3C2 */ + +#define __HAL_RCC_LPTIM1_RELEASE_RESET() CLEAR_BIT(RCC->APB3RSTR, RCC_APB3RSTR_LPTIM1RST) + +#if defined(LPTIM3) +#define __HAL_RCC_LPTIM3_RELEASE_RESET() CLEAR_BIT(RCC->APB3RSTR, RCC_APB3RSTR_LPTIM3RST) +#endif /* LPTIM3 */ + +#if defined(LPTIM4) +#define __HAL_RCC_LPTIM4_RELEASE_RESET() CLEAR_BIT(RCC->APB3RSTR, RCC_APB3RSTR_LPTIM4RST) +#endif /* LPTIM4 */ + +#if defined(LPTIM5) +#define __HAL_RCC_LPTIM5_RELEASE_RESET() CLEAR_BIT(RCC->APB3RSTR, RCC_APB3RSTR_LPTIM5RST) +#endif /* LPTIM5 */ + +#if defined(LPTIM6) +#define __HAL_RCC_LPTIM6_RELEASE_RESET() CLEAR_BIT(RCC->APB3RSTR, RCC_APB3RSTR_LPTIM6RST) +#endif /* LPTIM6 */ + +#if defined(VREFBUF) +#define __HAL_RCC_VREF_RELEASE_RESET() CLEAR_BIT(RCC->APB3RSTR, RCC_APB3RSTR_VREFRST) +#endif /* VREFBUF */ + +/** + * @} + */ + +/** @defgroup RCC_AHB1_Peripheral_Clock_Sleep_Enable_Disable AHB1 Peripheral Clock Sleep Enable Disable + * @brief Enable or disable the AHB1 peripheral clock during Low Power (Sleep) mode. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + * @{ + */ + +#define __HAL_RCC_GPDMA1_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_GPDMA1LPEN) + +#define __HAL_RCC_GPDMA2_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_GPDMA2LPEN) + +#define __HAL_RCC_FLASH_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_FLITFLPEN) + +#define __HAL_RCC_CRC_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_CRCLPEN) + +#if defined(CORDIC) +#define __HAL_RCC_CORDIC_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_CORDICLPEN) +#endif /* CORDIC */ + +#if defined(FMAC) +#define __HAL_RCC_FMAC_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_FMACLPEN) +#endif /* FMAC */ + +#define __HAL_RCC_RAMCFG_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_RAMCFGLPEN) + +#if defined(ETH) +#define __HAL_RCC_ETH_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_ETHLPEN) + +#define __HAL_RCC_ETHTX_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_ETHTXLPEN) + +#define __HAL_RCC_ETHRX_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_ETHRXLPEN) +#endif /* ETH */ + +#define __HAL_RCC_GTZC1_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_TZSC1LPEN) + +#define __HAL_RCC_BKPRAM_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_BKPRAMLPEN) + +#define __HAL_RCC_ICACHE_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_ICACHELPEN) + +#if defined(DCACHE1) +#define __HAL_RCC_DCACHE1_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_DCACHE1LPEN) +#endif /* DCACHE1 */ + +#define __HAL_RCC_SRAM1_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_SRAM1LPEN) + + +#define __HAL_RCC_GPDMA1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_GPDMA1LPEN) + +#define __HAL_RCC_GPDMA2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_GPDMA2LPEN) + +#define __HAL_RCC_FLASH_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_FLITFLPEN) + +#define __HAL_RCC_CRC_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_CRCLPEN) + +#if defined(CORDIC) +#define __HAL_RCC_CORDIC_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_CORDICLPEN) +#endif /* CORDIC */ + +#if defined(FMAC) +#define __HAL_RCC_FMAC_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_FMACLPEN) +#endif /* FMAC */ + +#define __HAL_RCC_RAMCFG_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_RAMCFGLPEN) + +#if defined(ETH) +#define __HAL_RCC_ETH_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_ETHLPEN) + +#define __HAL_RCC_ETHTX_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_ETHTXLPEN) + +#define __HAL_RCC_ETHRX_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_ETHRXLPEN) +#endif /* ETH */ + +#define __HAL_RCC_GTZC1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_TZSC1LPEN) + +#define __HAL_RCC_BKPRAM_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_BKPRAMLPEN) + +#define __HAL_RCC_ICACHE_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_ICACHELPEN) + +#if defined(DCACHE1) +#define __HAL_RCC_DCACHE1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_DCACHE1LPEN) +#endif /* DCACHE1 */ + +#define __HAL_RCC_SRAM1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB1LPENR, RCC_AHB1LPENR_SRAM1LPEN) + +/** + * @} + */ + +/** @defgroup RCC_AHB2_Peripheral_Clock_Sleep_Enable_Disable AHB2 Peripheral Clock Sleep Enable Disable + * @brief Enable or disable the AHB2 peripheral clock during Low Power (Sleep) mode. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + * @{ + */ + +#define __HAL_RCC_GPIOA_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_GPIOALPEN) + +#define __HAL_RCC_GPIOB_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_GPIOBLPEN) + +#define __HAL_RCC_GPIOC_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_GPIOCLPEN) + +#define __HAL_RCC_GPIOD_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_GPIODLPEN) + +#if defined(GPIOE) +#define __HAL_RCC_GPIOE_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_GPIOELPEN) +#endif /* GPIOE */ + +#if defined(GPIOF) +#define __HAL_RCC_GPIOF_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_GPIOFLPEN) +#endif /* GPIOF */ + +#if defined(GPIOG) +#define __HAL_RCC_GPIOG_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_GPIOGLPEN) +#endif /* GPIOG */ + +#define __HAL_RCC_GPIOH_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_GPIOHLPEN) + +#if defined(GPIOI) +#define __HAL_RCC_GPIOI_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_GPIOILPEN) +#endif /* GPIOI */ + +#define __HAL_RCC_ADC_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_ADCLPEN) + +#define __HAL_RCC_DAC1_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_DAC1LPEN) + +#if defined(DCMI) +#define __HAL_RCC_DCMI_PSSI_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_DCMI_PSSILPEN) +#define __HAL_RCC_DCMI_CLK_SLEEP_ENABLE() __HAL_RCC_DCMI_PSSI_CLK_SLEEP_ENABLE() /* for API backward compatibility */ +#endif /* DCMI */ + +#if defined(AES) +#define __HAL_RCC_AES_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_AESLPEN); +#endif /* AES */ + +#if defined(HASH) +#define __HAL_RCC_HASH_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_HASHLPEN) +#endif /* HASH */ + +#define __HAL_RCC_RNG_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_RNGLPEN) + +#if defined(PKA) +#define __HAL_RCC_PKA_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_PKALPEN) +#endif /*PKA*/ + +#if defined(SAES) +#define __HAL_RCC_SAES_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_SAESLPEN) +#endif /* AES */ + +#define __HAL_RCC_SRAM2_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_SRAM2LPEN) + +#if defined(SRAM3_BASE) +#define __HAL_RCC_SRAM3_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_SRAM3LPEN) +#endif /* SRAM3_BASE */ + +#define __HAL_RCC_GPIOA_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_GPIOALPEN) + +#define __HAL_RCC_GPIOB_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_GPIOBLPEN) + +#define __HAL_RCC_GPIOC_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_GPIOCLPEN) + +#define __HAL_RCC_GPIOD_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_GPIODLPEN) + +#if defined(GPIOE) +#define __HAL_RCC_GPIOE_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_GPIOELPEN) +#endif /* GPIOE */ + +#if defined(GPIOF) +#define __HAL_RCC_GPIOF_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_GPIOFLPEN) +#endif /* GPIOF */ + +#if defined(GPIOG) +#define __HAL_RCC_GPIOG_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_GPIOGLPEN) +#endif /* GPIOG */ + +#define __HAL_RCC_GPIOH_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_GPIOHLPEN) + +#if defined(GPIOI) +#define __HAL_RCC_GPIOI_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_GPIOILPEN) +#endif /* GPIOI */ + +#define __HAL_RCC_ADC_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_ADCLPEN) + +#define __HAL_RCC_DAC1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_DAC1LPEN) + +#if defined(DCMI) +#define __HAL_RCC_DCMI_PSSI_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_DCMI_PSSILPEN) +#define __HAL_RCC_DCMI_CLK_SLEEP_DISABLE() __HAL_RCC_DCMI_PSSI_CLK_SLEEP_DISABLE() /* for API backward compatibility */ +#endif /* DCMI */ + +#if defined(AES) +#define __HAL_RCC_AES_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_AESLPEN); +#endif /* AES */ + +#if defined(HASH) +#define __HAL_RCC_HASH_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_HASHLPEN) +#endif /* HASH */ + +#define __HAL_RCC_RNG_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_RNGLPEN) + +#if defined(PKA) +#define __HAL_RCC_PKA_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_PKALPEN) +#endif /*PKA*/ + +#define __HAL_RCC_SAES_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_SAESLPEN) + +#define __HAL_RCC_SRAM2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_SRAM2LPEN) + +#if defined(SRAM3_BASE) +#define __HAL_RCC_SRAM3_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB2LPENR, RCC_AHB2LPENR_SRAM3LPEN) +#endif /* SRAM3_BASE */ +/** + * @} + */ + +/** @defgroup RCC_AHB4_Clock_Sleep_Enable_Disable AHB4 Peripheral Clock Sleep Enable Disable + * @brief Enable or disable the AHB4 peripheral clock during Low Power (Sleep) mode. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + * @{ + */ + +#if defined(OTFDEC1) +#define __HAL_RCC_OTFDEC1_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_OTFDEC1LPEN) +#endif /* OTFDEC1 */ + +#if defined(SDMMC1) +#define __HAL_RCC_SDMMC1_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_SDMMC1LPEN) +#endif /* SDMMC1*/ + +#if defined(SDMMC2) +#define __HAL_RCC_SDMMC2_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_SDMMC2LPEN) +#endif /* SDMMC2*/ + +#if defined(FMC_BASE) +#define __HAL_RCC_FMC_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_FMCLPEN) +#endif /* FMC_BASE */ + +#if defined(OCTOSPI1) +#define __HAL_RCC_OSPI1_CLK_SLEEP_ENABLE() SET_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_OCTOSPI1LPEN) +#endif /* OCTOSPI1 */ + +#if defined(OTFDEC1) +#define __HAL_RCC_OTFDEC1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_OTFDEC1LPEN) +#endif /* OTFDEC1 */ + +#if defined(SDMMC1) +#define __HAL_RCC_SDMMC1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_SDMMC1LPEN) +#endif /* SDMMC1*/ + +#if defined(SDMMC2) +#define __HAL_RCC_SDMMC2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_SDMMC2LPEN) +#endif /* SDMMC2*/ + +#if defined(FMC_BASE) +#define __HAL_RCC_FMC_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_FMCLPEN) +#endif /* FMC_BASE */ + +#if defined(OCTOSPI1) +#define __HAL_RCC_OSPI1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->AHB4LPENR, RCC_AHB4LPENR_OCTOSPI1LPEN) +#endif /* OCTOSPI1 */ + +/** + * @} + */ + +/** @defgroup RCC_APB1_Clock_Sleep_Enable_Disable APB1 Peripheral Clock Sleep Enable Disable + * @brief Enable or disable the APB1 peripheral clock during Low Power (Sleep) mode. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + * @{ + */ + +#define __HAL_RCC_TIM2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_TIM2LPEN) + +#define __HAL_RCC_TIM3_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_TIM3LPEN) + +#if defined(TIM4) +#define __HAL_RCC_TIM4_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_TIM4LPEN) +#endif /* TIM4 */ + +#if defined(TIM5) +#define __HAL_RCC_TIM5_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_TIM5LPEN) +#endif /* TIM5 */ + +#define __HAL_RCC_TIM6_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_TIM6LPEN) + +#define __HAL_RCC_TIM7_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_TIM7LPEN) + +#if defined(TIM12) +#define __HAL_RCC_TIM12_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_TIM12LPEN) +#endif /* TIM12 */ + +#if defined(TIM13) +#define __HAL_RCC_TIM13_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_TIM13LPEN) +#endif /* TIM13 */ + +#if defined(TIM14) +#define __HAL_RCC_TIM14_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_TIM14LPEN) +#endif /* TIM14 */ + +#define __HAL_RCC_WWDG_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_WWDGLPEN) + +#if defined(OPAMP1) +#define __HAL_RCC_OPAMP_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_OPAMPLPEN) +#endif /* OPAMP1 */ + +#define __HAL_RCC_SPI2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_SPI2LPEN) + +#define __HAL_RCC_SPI3_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_SPI3LPEN) + +#if defined(COMP1) +#define __HAL_RCC_COMP_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_COMPLPEN) +#endif /* COMP1 */ + +#define __HAL_RCC_USART2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_USART2LPEN) + +#define __HAL_RCC_USART3_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_USART3LPEN) + +#if defined(UART4) +#define __HAL_RCC_UART4_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_UART4LPEN) +#endif /* UART4 */ + +#if defined(UART5) +#define __HAL_RCC_UART5_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_UART5LPEN) +#endif /* UART5 */ + +#define __HAL_RCC_I2C1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_I2C1LPEN) + +#define __HAL_RCC_I2C2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_I2C2LPEN) + +#define __HAL_RCC_I3C1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_I3C1LPEN) + +#define __HAL_RCC_CRS_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_CRSLPEN) + +#if defined(USART6) +#define __HAL_RCC_USART6_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_USART6LPEN) +#endif /* USART6 */ + +#if defined(USART10) +#define __HAL_RCC_USART10_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_USART10LPEN) +#endif /* USART10 */ + +#if defined(USART11) +#define __HAL_RCC_USART11_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_USART11LPEN) +#endif /* USART11 */ + +#if defined(CEC) +#define __HAL_RCC_CEC_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_CECLPEN) +#endif /* CEC */ + +#if defined(UART7) +#define __HAL_RCC_UART7_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_UART7LPEN) +#endif /* UART7 */ + +#if defined(UART8) +#define __HAL_RCC_UART8_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_UART8LPEN) +#endif /* UART8 */ + + +#if defined(UART9) +#define __HAL_RCC_UART9_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1HLPENR, RCC_APB1HLPENR_UART9LPEN) +#endif /* UART9 */ + +#if defined(UART12) +#define __HAL_RCC_UART12_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1HLPENR, RCC_APB1HLPENR_UART12LPEN) +#endif /* UART12 */ + +#define __HAL_RCC_DTS_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1HLPENR, RCC_APB1HLPENR_DTSLPEN) + +#define __HAL_RCC_LPTIM2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1HLPENR, RCC_APB1HLPENR_LPTIM2LPEN) + +#define __HAL_RCC_FDCAN_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1HLPENR, RCC_APB1HLPENR_FDCANLPEN) + +#if defined(UCPD1) +#define __HAL_RCC_UCPD1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB1HLPENR, RCC_APB1HLPENR_UCPD1LPEN) +#endif /* UCPD1 */ + +#define __HAL_RCC_TIM2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_TIM2LPEN) + +#define __HAL_RCC_TIM3_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_TIM3LPEN) + +#if defined(TIM4) +#define __HAL_RCC_TIM4_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_TIM4LPEN) +#endif /* TIM4 */ + +#if defined(TIM5) +#define __HAL_RCC_TIM5_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_TIM5LPEN) +#endif /* TIM5 */ + +#define __HAL_RCC_TIM6_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_TIM6LPEN) + +#define __HAL_RCC_TIM7_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_TIM7LPEN) + +#if defined(TIM12) +#define __HAL_RCC_TIM12_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_TIM12LPEN) +#endif /* TIM12 */ + +#if defined(TIM13) +#define __HAL_RCC_TIM13_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_TIM13LPEN) +#endif /* TIM12 */ + +#if defined(TIM14) +#define __HAL_RCC_TIM14_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_TIM14LPEN) +#endif /* TIM14 */ + +#define __HAL_RCC_WWDG_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_WWDGLPEN) + +#if defined(OPAMP1) +#define __HAL_RCC_OPAMP_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_OPAMPLPEN) +#endif /* OPAMP1 */ + +#define __HAL_RCC_SPI2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_SPI2LPEN) + +#define __HAL_RCC_SPI3_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_SPI3LPEN) + +#if defined(COMP1) +#define __HAL_RCC_COMP_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_COMPLPEN) +#endif /* COMP1 */ + +#define __HAL_RCC_USART2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_USART2LPEN) + +#define __HAL_RCC_USART3_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_USART3LPEN) + +#if defined(UART4) +#define __HAL_RCC_UART4_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_UART4LPEN) +#endif /* UART4 */ + +#if defined(UART5) +#define __HAL_RCC_UART5_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_UART5LPEN) +#endif /* UART5 */ + +#define __HAL_RCC_I2C1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_I2C1LPEN) + +#define __HAL_RCC_I2C2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_I2C2LPEN) + +#define __HAL_RCC_I3C1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_I3C1LPEN) + +#define __HAL_RCC_CRS_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_CRSLPEN) + +#if defined(USART6) +#define __HAL_RCC_USART6_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_USART6LPEN) +#endif /* USART6 */ + +#if defined(USART10) +#define __HAL_RCC_USART10_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_USART10LPEN) +#endif /* USART10 */ + +#if defined(USART11) +#define __HAL_RCC_USART11_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_USART11LPEN) +#endif /* USART11 */ + +#if defined(CEC) +#define __HAL_RCC_CEC_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_CECLPEN) +#endif /* CEC */ + +#if defined(UART7) +#define __HAL_RCC_UART7_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_UART7LPEN) +#endif /* UART7 */ + +#if defined(UART8) +#define __HAL_RCC_UART8_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1LLPENR, RCC_APB1LLPENR_UART8LPEN) +#endif /* UART8 */ + + +#if defined(UART9) +#define __HAL_RCC_UART9_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1HLPENR, RCC_APB1HLPENR_UART9LPEN) +#endif /* UART9 */ + +#if defined(UART12) +#define __HAL_RCC_UART12_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1HLPENR, RCC_APB1HLPENR_UART12LPEN) +#endif /* UART12 */ + +#define __HAL_RCC_DTS_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1HLPENR, RCC_APB1HLPENR_DTSLPEN) + +#define __HAL_RCC_LPTIM2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1HLPENR, RCC_APB1HLPENR_LPTIM2LPEN) + +#define __HAL_RCC_FDCAN_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1HLPENR, RCC_APB1HLPENR_FDCANLPEN) + +#if defined(UCPD1) +#define __HAL_RCC_UCPD1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB1HLPENR, RCC_APB1HLPENR_UCPD1LPEN) +#endif /* UCPD1 */ + +/** + * @} + */ + +/** @defgroup RCC_APB2_Clock_Sleep_Enable_Disable APB2 Peripheral Clock Sleep Enable Disable + * @brief Enable or disable the APB2 peripheral clock during Low Power (Sleep) mode. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + * @{ + */ +#define __HAL_RCC_TIM1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2LPENR, RCC_APB2LPENR_TIM1LPEN) + +#define __HAL_RCC_SPI1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2LPENR, RCC_APB2LPENR_SPI1LPEN) + +#if defined(TIM8) +#define __HAL_RCC_TIM8_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2LPENR, RCC_APB2LPENR_TIM8LPEN) +#endif /* TIM8 */ + +#define __HAL_RCC_USART1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2LPENR, RCC_APB2LPENR_USART1LPEN) + +#if defined(TIM15) +#define __HAL_RCC_TIM15_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2LPENR, RCC_APB2LPENR_TIM15LPEN) +#endif /* TIM15 */ + +#if defined(TIM16) +#define __HAL_RCC_TIM16_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2LPENR, RCC_APB2LPENR_TIM16LPEN) +#endif /* TIM16 */ + +#if defined(TIM17) +#define __HAL_RCC_TIM17_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2LPENR, RCC_APB2LPENR_TIM17LPEN) +#endif /* TIM17 */ + +#if defined(SPI4) +#define __HAL_RCC_SPI4_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2LPENR, RCC_APB2LPENR_SPI4LPEN) +#endif /* SPI4 */ + +#if defined(SPI6) +#define __HAL_RCC_SPI6_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2LPENR, RCC_APB2LPENR_SPI6LPEN) +#endif /* SPI6 */ + +#if defined(SAI1) +#define __HAL_RCC_SAI1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2LPENR, RCC_APB2LPENR_SAI1LPEN) +#endif /* SAI1 */ + +#if defined(SAI2) +#define __HAL_RCC_SAI2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2LPENR, RCC_APB2LPENR_SAI2LPEN) +#endif /* SAI2 */ + +#define __HAL_RCC_USB_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB2LPENR, RCC_APB2LPENR_USBLPEN) + + +#define __HAL_RCC_TIM1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2LPENR, RCC_APB2LPENR_TIM1LPEN) + +#define __HAL_RCC_SPI1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2LPENR, RCC_APB2LPENR_SPI1LPEN) + +#if defined(TIM8) +#define __HAL_RCC_TIM8_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2LPENR, RCC_APB2LPENR_TIM8LPEN) +#endif /* TIM8 */ + +#define __HAL_RCC_USART1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2LPENR, RCC_APB2LPENR_USART1LPEN) + +#if defined(TIM15) +#define __HAL_RCC_TIM15_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2LPENR, RCC_APB2LPENR_TIM15LPEN) +#endif /* TIM15 */ + +#if defined(TIM16) +#define __HAL_RCC_TIM16_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2LPENR, RCC_APB2LPENR_TIM16LPEN) +#endif /* TIM16 */ + +#if defined(TIM17) +#define __HAL_RCC_TIM17_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2LPENR, RCC_APB2LPENR_TIM17LPEN) +#endif /* TIM17 */ + +#if defined(SPI4) +#define __HAL_RCC_SPI4_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2LPENR, RCC_APB2LPENR_SPI4LPEN) +#endif /* SPI4 */ + +#if defined(SPI6) +#define __HAL_RCC_SPI6_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2LPENR, RCC_APB2LPENR_SPI6LPEN) +#endif /* SPI6 */ + +#if defined(SAI1) +#define __HAL_RCC_SAI1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2LPENR, RCC_APB2LPENR_SAI1LPEN) +#endif /* SAI1 */ + +#if defined(SAI2) +#define __HAL_RCC_SAI2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2LPENR, RCC_APB2LPENR_SAI2LPEN) +#endif /* SAI2 */ + +#define __HAL_RCC_USB_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB2LPENR, RCC_APB2LPENR_USBLPEN) + +/** + * @} + */ + +/** @defgroup RCC_APB3_Clock_Sleep_Enable_Disable APB3 Peripheral Clock Sleep Enable Disable + * @brief Enable or disable the APB3 peripheral clock during Low Power (Sleep) mode. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + * @{ + */ +#define __HAL_RCC_SBS_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB3LPENR, RCC_APB3LPENR_SBSLPEN) + +#if defined(SPI5) +#define __HAL_RCC_SPI5_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB3LPENR, RCC_APB3LPENR_SPI5LPEN) +#endif /* SPI5 */ + +#define __HAL_RCC_LPUART1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB3LPENR, RCC_APB3LPENR_LPUART1LPEN) + +#if defined(I2C3) +#define __HAL_RCC_I2C3_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB3LPENR, RCC_APB3LPENR_I2C3LPEN) +#endif /* I2C3 */ + +#if defined(I2C4) +#define __HAL_RCC_I2C4_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB3LPENR, RCC_APB3LPENR_I2C4LPEN) +#endif /* I2C4 */ + +#if defined(I3C2) +#define __HAL_RCC_I3C2_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB3LPENR, RCC_APB3LPENR_I3C2LPEN) +#endif /* I3C2 */ + +#define __HAL_RCC_LPTIM1_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB3LPENR, RCC_APB3LPENR_LPTIM1LPEN) + +#if defined(LPTIM3) +#define __HAL_RCC_LPTIM3_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB3LPENR, RCC_APB3LPENR_LPTIM3LPEN) +#endif /* LPTIM3 */ + +#if defined(LPTIM4) +#define __HAL_RCC_LPTIM4_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB3LPENR, RCC_APB3LPENR_LPTIM4LPEN) +#endif /* LPTIM4 */ + +#if defined(LPTIM5) +#define __HAL_RCC_LPTIM5_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB3LPENR, RCC_APB3LPENR_LPTIM5LPEN) +#endif /* LPTIM5 */ + +#if defined(LPTIM6) +#define __HAL_RCC_LPTIM6_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB3LPENR, RCC_APB3LPENR_LPTIM6LPEN) +#endif /* LPTIM6 */ + +#if defined(VREFBUF) +#define __HAL_RCC_VREF_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB3LPENR, RCC_APB3LPENR_VREFLPEN) +#endif /* VREFBUF */ + +#define __HAL_RCC_RTC_CLK_SLEEP_ENABLE() SET_BIT(RCC->APB3LPENR, RCC_APB3LPENR_RTCAPBLPEN) + + +#define __HAL_RCC_SBS_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB3LPENR, RCC_APB3LPENR_SBSLPEN) + +#if defined(SPI5) +#define __HAL_RCC_SPI5_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB3LPENR, RCC_APB3LPENR_SPI5LPEN) +#endif /* SPI5 */ + +#define __HAL_RCC_LPUART1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB3LPENR, RCC_APB3LPENR_LPUART1LPEN) + +#if defined(I2C3) +#define __HAL_RCC_I2C3_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB3LPENR, RCC_APB3LPENR_I2C3LPEN) +#endif /* I2C3 */ + +#if defined(I2C4) +#define __HAL_RCC_I2C4_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB3LPENR, RCC_APB3LPENR_I2C4LPEN) +#endif /* I2C4 */ + +#if defined(I3C2) +#define __HAL_RCC_I3C2_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB3LPENR, RCC_APB3LPENR_I3C2LPEN) +#endif /* I3C2 */ + +#define __HAL_RCC_LPTIM1_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB3LPENR, RCC_APB3LPENR_LPTIM1LPEN) + +#if defined(LPTIM3) +#define __HAL_RCC_LPTIM3_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB3LPENR, RCC_APB3LPENR_LPTIM3LPEN) +#endif /* LPTIM3 */ + +#if defined(LPTIM4) +#define __HAL_RCC_LPTIM4_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB3LPENR, RCC_APB3LPENR_LPTIM4LPEN) +#endif /* LPTIM4 */ + +#if defined(LPTIM5) +#define __HAL_RCC_LPTIM5_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB3LPENR, RCC_APB3LPENR_LPTIM5LPEN) +#endif /* LPTIM5 */ + +#if defined(LPTIM6) +#define __HAL_RCC_LPTIM6_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB3LPENR, RCC_APB3LPENR_LPTIM6LPEN) +#endif /* LPTIM6 */ + +#if defined(VREFBUF) +#define __HAL_RCC_VREF_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB3LPENR, RCC_APB3LPENR_VREFLPEN) +#endif /* VREFBUF */ + +#define __HAL_RCC_RTC_CLK_SLEEP_DISABLE() CLEAR_BIT(RCC->APB3LPENR, RCC_APB3LPENR_RTCAPBLPEN) + +/** + * @} + */ + + +/** @defgroup RCC_Backup_Domain_Reset RCC Backup Domain Reset + * @{ + */ + +/** @brief Macros to force or release the Backup domain reset. + * @note This function resets the RTC peripheral (including the backup registers) + * and the RTC clock source selection in RCC_BDCR register. + * @note The BKPSRAM is not affected by this reset. + * @retval None + */ +#define __HAL_RCC_BACKUPRESET_FORCE() SET_BIT(RCC->BDCR, RCC_BDCR_VSWRST) + +#define __HAL_RCC_BACKUPRESET_RELEASE() CLEAR_BIT(RCC->BDCR, RCC_BDCR_VSWRST) + +/** + * @} + */ + +/** @defgroup RCC_RTC_Clock_Configuration RCC RTC Clock Configuration + * @{ + */ + +/** @brief Macros to enable or disable the RTC clock. + * @note As the RTC is in the Backup domain and write access is denied to + * this domain after reset, you have to enable write access using + * HAL_PWR_EnableBkUpAccess() function before to configure the RTC + * (to be done once after reset). + * @note These macros must be used after the RTC clock source was selected. + * @retval None + */ +#define __HAL_RCC_RTC_ENABLE() SET_BIT(RCC->BDCR, RCC_BDCR_RTCEN) + +#define __HAL_RCC_RTC_DISABLE() CLEAR_BIT(RCC->BDCR, RCC_BDCR_RTCEN) + +/** + * @} + */ + +/** @brief Macro to configure the Internal High Speed oscillator (HSI). + * @param __HSIDIV__ specifies the HSI division factor. + * This parameter can be one of the following values: + * @arg RCC_HSI_DIV1 Divide the HSI oscillator clock by 1 (default after reset) + * @arg RCC_HSI_DIV2 Divide the HSI oscillator clock by 2 + * @arg RCC_HSI_DIV4 Divide the HSI oscillator clock by 4 + * @arg RCC_HSI_DIV8 Divide the HSI oscillator clock by 8 + */ +#define __HAL_RCC_HSI_DIVIDER_CONFIG(__HSIDIV__) \ + MODIFY_REG(RCC->CR, RCC_CR_HSIDIV , (uint32_t)(__HSIDIV__)) + + +/** @brief Macro to get the HSI divider. + * @retval The HSI divider. The returned value can be one + * of the following: + * - RCC_HSI_DIV1 HSI oscillator divided by 1 + * - RCC_HSI_DIV2 HSI oscillator divided by 2 + * - RCC_HSI_DIV4 HSI oscillator divided by 4 + * - RCC_HSI_DIV8 HSI oscillator divided by 8 + */ +#define __HAL_RCC_GET_HSI_DIVIDER() ((uint32_t)(READ_BIT(RCC->CR, RCC_CR_HSIDIV))) + +/** @brief Macros to enable or disable the Internal High Speed 64MHz oscillator (HSI). + * @note The HSI is stopped by hardware when entering STOP and STANDBY modes. + * It is used (enabled by hardware) as system clock source after startup + * from Reset, wakeup from STOP and STANDBY mode, or in case of failure + * of the HSE used directly or indirectly as system clock (if the HSE Clock + * Security System HSECSS is enabled). + * @note HSI can not be stopped if it is used as system clock source. In this case, + * you have to select another source of the system clock then stop the HSI. + * @note After enabling the HSI, the application software should wait on HSIRDY + * flag to be set indicating that HSI clock is stable and can be used as + * system clock source. + * This parameter can be: ENABLE or DISABLE. + * @note When the HSI is stopped, HSIRDY flag goes low after 6 HSI oscillator + * clock cycles. + * @retval None + */ +#define __HAL_RCC_HSI_ENABLE() SET_BIT(RCC->CR, RCC_CR_HSION) + +#define __HAL_RCC_HSI_DISABLE() CLEAR_BIT(RCC->CR, RCC_CR_HSION) + +/** @brief Macro to adjust the Internal High Speed 64MHz oscillator (HSI) calibration value. + * @note The calibration is used to compensate for the variations in voltage + * and temperature that influence the frequency of the internal HSI RC. + * @param __HSICALIBRATIONVALUE__: specifies the calibration trimming value + * (default is RCC_HSICALIBRATION_DEFAULT). + * This parameter must be a number between 0 and 0x7F. + * @retval None + */ +#define __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(__HSICALIBRATIONVALUE__) \ + MODIFY_REG(RCC->HSICFGR, RCC_HSICFGR_HSITRIM, (uint32_t)(__HSICALIBRATIONVALUE__) << RCC_HSICFGR_HSITRIM_Pos) + +/** + * @brief Macros to enable or disable the force of the Internal High Speed oscillator (HSI) + * in STOP mode to be quickly available as kernel clock for USARTs, LPUART and I2Cs. + * @note Keeping the HSI ON in STOP mode allows to avoid slowing down the communication + * speed because of the HSI startup time. + * @note The enable of this function has not effect on the HSION bit. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +#define __HAL_RCC_HSISTOP_ENABLE() SET_BIT(RCC->CR, RCC_CR_HSIKERON) + +#define __HAL_RCC_HSISTOP_DISABLE() CLEAR_BIT(RCC->CR, RCC_CR_HSIKERON) + +/** + * @brief Macros to enable or disable the Internal Low-power oscillator (CSI). + * @note The CSI is stopped by hardware when entering STOP and STANDBY modes. + * It is used (enabled by hardware) as system clock source after + * startup from Reset, wakeup from STOP and STANDBY mode, or in case + * of failure of the HSE used directly or indirectly as system clock + * (if the HSE Clock Security System HSECSS is enabled and CSI is selected + * as system clock after wake up from system stop). + * @note CSI can not be stopped if it is used as system clock source. + * In this case, you have to select another source of the system + * clock then stop the CSI. + * @note After enabling the CSI, the application software should wait on + * CSIRDY flag to be set indicating that CSI clock is stable and can + * be used as system clock source. + * @note When the CSI is stopped, CSIRDY flag goes low after 6 CSI oscillator + * clock cycles. + * @retval None + */ +#define __HAL_RCC_CSI_ENABLE() SET_BIT(RCC->CR, RCC_CR_CSION) + +#define __HAL_RCC_CSI_DISABLE() CLEAR_BIT(RCC->CR, RCC_CR_CSION) + +/** @brief Macro Adjusts the Internal oscillator (CSI) calibration value. + * @note The calibration is used to compensate for the variations in voltage + * and temperature that influence the frequency of the internal CSI RC. + * @param __CSICalibrationValue__: specifies the calibration trimming value. + * This parameter must be a number between 0 and 0x3F. + */ +#define __HAL_RCC_CSI_CALIBRATIONVALUE_ADJUST(__CSICalibrationValue__) \ + do { \ + MODIFY_REG(RCC->CSICFGR, RCC_CSICFGR_CSITRIM, (uint32_t)(__CSICalibrationValue__) << RCC_CSICFGR_CSITRIM_Pos); \ + } while(0) + +/** + * @brief Macros to enable or disable the force of the Low-power Internal oscillator (CSI) + * in STOP mode to be quickly available as kernel clock for USARTs and I2Cs. + * @note Keeping the CSI ON in STOP mode allows to avoid slowing down the communication + * speed because of the CSI start-up time. + * @note The enable of this function has not effect on the CSION bit. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +#define __HAL_RCC_CSISTOP_ENABLE() SET_BIT(RCC->CR, RCC_CR_CSIKERON) +#define __HAL_RCC_CSISTOP_DISABLE() CLEAR_BIT(RCC->CR, RCC_CR_CSIKERON) + +/** @brief Macros to enable or disable the Internal Low Speed oscillator (LSI). + * @note After enabling the LSI, the application software should wait on + * LSIRDY flag to be set indicating that LSI clock is stable and can + * be used to clock the IWDG and/or the RTC. + * @note LSI can not be disabled if the IWDG is running. + * @note When the LSI is stopped, LSIRDY flag goes low after 6 LSI oscillator + * clock cycles. + * @retval None + */ +#define __HAL_RCC_LSI_ENABLE() SET_BIT(RCC->BDCR, RCC_BDCR_LSION) + +#define __HAL_RCC_LSI_DISABLE() CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSION) + +/** + * @brief Macro to configure the External High Speed oscillator (HSE). + * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not + * supported by this macro. User should request a transition to HSE Off + * first and then HSE On or HSE Bypass. + * @note After enabling the HSE (RCC_HSE_ON or RCC_HSE_Bypass), the application + * software should wait on HSERDY flag to be set indicating that HSE clock + * is stable and can be used to clock the PLLs and/or system clock. + * @note HSE state can not be changed if it is used directly or through the + * PLL1 as system clock. In this case, you have to select another source + * of the system clock then change the HSE state (ex. disable it). + * @note The HSE is stopped by hardware when entering STOP and STANDBY modes. + * @param __STATE__: specifies the new state of the HSE. + * This parameter can be one of the following values: + * @arg @ref RCC_HSE_OFF Turn OFF the HSE oscillator, HSERDY flag goes low after + * 6 HSE oscillator clock cycles. + * @arg @ref RCC_HSE_ON Turn ON the HSE oscillator. + * @arg @ref RCC_HSE_BYPASS HSE oscillator bypassed with external clock. + * @arg @ref RCC_HSE_BYPASS_DIGITAL HSE oscillator bypassed with digital external clock. + * @retval None + */ +#define __HAL_RCC_HSE_CONFIG(__STATE__) \ + do { \ + if ((__STATE__) == RCC_HSE_ON) \ + { \ + SET_BIT(RCC->CR, RCC_CR_HSEON); \ + } \ + else if ((__STATE__) == RCC_HSE_OFF) \ + { \ + CLEAR_BIT(RCC->CR, RCC_CR_HSEON); \ + CLEAR_BIT(RCC->CR, RCC_CR_HSEEXT); \ + CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP); \ + } \ + else if ((__STATE__) == RCC_HSE_BYPASS) \ + { \ + SET_BIT(RCC->CR, RCC_CR_HSEBYP); \ + CLEAR_BIT(RCC->CR, RCC_CR_HSEEXT); \ + SET_BIT(RCC->CR, RCC_CR_HSEON); \ + } \ + else if((__STATE__) == RCC_HSE_BYPASS_DIGITAL) \ + { \ + SET_BIT(RCC->CR, RCC_CR_HSEBYP); \ + SET_BIT(RCC->CR, RCC_CR_HSEEXT); \ + SET_BIT(RCC->CR, RCC_CR_HSEON); \ + } \ + else \ + { \ + CLEAR_BIT(RCC->CR, RCC_CR_HSEON); \ + CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP); \ + CLEAR_BIT(RCC->CR, RCC_CR_HSEEXT); \ + } \ + } while(0) + +/** + * @brief Macro to configure the External Low Speed oscillator (LSE). + * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not + * supported by this macro. User should request a transition to LSE Off + * first and then LSE On or LSE Bypass. + * @note As the LSE is in the Backup domain and write access is denied to + * this domain after reset, you have to enable write access using + * HAL_PWR_EnableBkUpAccess() function before to configure the LSE + * (to be done once after reset). + * @note After enabling the LSE (RCC_LSE_ON or RCC_LSE_BYPASS), the application + * software should wait on LSERDY flag to be set indicating that LSE clock + * is stable and can be used to clock the RTC. + * @param __STATE__: specifies the new state of the LSE. + * This parameter can be one of the following values: + * @arg @ref RCC_LSE_OFF Turn OFF the LSE oscillator, LSERDY flag goes low after + * 6 LSE oscillator clock cycles. + * @arg @ref RCC_LSE_ON Turn ON the LSE oscillator. + * @arg @ref RCC_LSE_BYPASS LSE oscillator bypassed with external clock. + * @arg @ref RCC_LSE_BYPASS_DIGITAL LSE oscillator bypassed with external digital clock. + * @retval None + */ + +#define __HAL_RCC_LSE_CONFIG(__STATE__) \ + do { \ + if((__STATE__) == RCC_LSE_ON) \ + { \ + SET_BIT(RCC->BDCR, RCC_BDCR_LSEON); \ + } \ + else if((__STATE__) == RCC_LSE_OFF) \ + { \ + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEON); \ + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEEXT); \ + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEBYP); \ + } \ + else if((__STATE__) == RCC_LSE_BYPASS) \ + { \ + SET_BIT(RCC->BDCR, RCC_BDCR_LSEBYP); \ + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEEXT); \ + SET_BIT(RCC->BDCR, RCC_BDCR_LSEON); \ + } \ + else if((__STATE__) == RCC_LSE_BYPASS_DIGITAL) \ + { \ + SET_BIT(RCC->BDCR, RCC_BDCR_LSEBYP); \ + SET_BIT(RCC->BDCR, RCC_BDCR_LSEEXT); \ + SET_BIT(RCC->BDCR, RCC_BDCR_LSEON); \ + } \ + else \ + { \ + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEON); \ + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEBYP); \ + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEEXT); \ + } \ + } while(0) + +/** @brief Macros to enable or disable the Internal High Speed 48MHz oscillator (HSI48). + * @note The HSI48 is stopped by hardware when entering STOP and STANDBY modes. + * @note After enabling the HSI48, the application software should wait on HSI48RDY + * flag to be set indicating that HSI48 clock is stable. + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +#define __HAL_RCC_HSI48_ENABLE() SET_BIT(RCC->CR, RCC_CR_HSI48ON) + +#define __HAL_RCC_HSI48_DISABLE() CLEAR_BIT(RCC->CR, RCC_CR_HSI48ON) + +/** @brief Macros to configure the RTC clock (RTCCLK). + * @note As the RTC clock configuration bits are in the Backup domain and write + * access is denied to this domain after reset, you have to enable write + * access using the Power Backup Access macro before to configure + * the RTC clock source (to be done once after reset). + * @note Once the RTC clock is configured it cannot be changed unless the + * Backup domain is reset using __HAL_RCC_BackupReset_RELEASE() macro, or by + * a Power On Reset (POR). + * @param __RTCCLKSource__: specifies the RTC clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_RTCCLKSOURCE_LSE LSE selected as RTC clock. + * @arg @ref RCC_RTCCLKSOURCE_LSI LSI selected as RTC clock. + * @arg @ref RCC_RTCCLKSOURCE_HSE_DIVx HSE clock divided by x selected + * as RTC clock, where x can be between 2 and 63 + * @note If the LSE or LSI is used as RTC clock source, the RTC continues to + * work in STOP and STANDBY modes, and can be used as wakeup source. + * However, when the HSE clock is used as RTC clock source, the RTC + * cannot be used in STOP and STANDBY modes. + * @note The maximum input clock frequency for RTC is 1MHz (when using HSE as + * RTC clock source). + */ +#define __HAL_RCC_RTC_CLKPRESCALER(__RTCCLKSource__) (((__RTCCLKSource__) & RCC_BDCR_RTCSEL) == RCC_BDCR_RTCSEL) ? \ + MODIFY_REG(RCC->CFGR1, RCC_CFGR1_RTCPRE, \ + (((__RTCCLKSource__) & 0xFFFFCFFU) >> 4)) : CLEAR_BIT(RCC->CFGR1, RCC_CFGR1_RTCPRE) + +#define __HAL_RCC_RTC_CONFIG(__RTCCLKSource__) do { __HAL_RCC_RTC_CLKPRESCALER(__RTCCLKSource__); \ + RCC->BDCR &= ~RCC_BDCR_RTCSEL; \ + RCC->BDCR |= ((__RTCCLKSource__) & 0x00000FFFU); \ + } while (0) + +/** @brief Macro to get the RTC clock source. + * @retval The returned value can be one of the following: + * @arg @ref RCC_RTCCLKSOURCE_NO_CLK No clock selected as RTC clock. + * @arg @ref RCC_RTCCLKSOURCE_LSE LSE selected as RTC clock. + * @arg @ref RCC_RTCCLKSOURCE_LSI LSI selected as RTC clock. + * @arg @ref RCC_RTCCLKSOURCE_HSE_DIVx HSE clock divided by x selected as + * RTC clock, where x can be between 2 and 63 + (x can be retrieved with @ref __HAL_RCC_GET_RTC_HSE_PRESCALER()) + */ +#define __HAL_RCC_GET_RTC_SOURCE() ((uint32_t)(READ_BIT(RCC->BDCR, RCC_BDCR_RTCSEL))) + +/** @brief Macro to get the HSE division factor for RTC clock. + * + * @retval The HSE division factor for RTC clock. The returned value can be one + * of the following: + * @arg @ref RCC_RTC_HSE_NOCLOCK : No HSE Clock selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV2 : HSE Divided by 2 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV3 : HSE Divided by 3 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV4 : HSE Divided by 4 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV5 : HSE Divided by 5 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV6 : HSE Divided by 6 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV7 : HSE Divided by 7 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV8 : HSE Divided by 8 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV9 : HSE Divided by 9 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV10 : HSE Divided by 10 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV11 : HSE Divided by 11 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV12 : HSE Divided by 12 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV13 : HSE Divided by 13 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV14 : HSE Divided by 14 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV15 : HSE Divided by 15 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV16 : HSE Divided by 16 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV17 : HSE Divided by 17 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV18 : HSE Divided by 18 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV19 : HSE Divided by 19 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV20 : HSE Divided by 20 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV21 : HSE Divided by 21 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV22 : HSE Divided by 22 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV23 : HSE Divided by 23 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV24 : HSE Divided by 24 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV25 : HSE Divided by 25 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV26 : HSE Divided by 26 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV27 : HSE Divided by 27 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV28 : HSE Divided by 28 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV29 : HSE Divided by 29 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV30 : HSE Divided by 30 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV31 : HSE Divided by 31 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV32 : HSE Divided by 32 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV33 : HSE Divided by 33 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV34 : HSE Divided by 34 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV35 : HSE Divided by 35 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV36 : HSE Divided by 36 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV37 : HSE Divided by 37 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV38 : HSE Divided by 38 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV39 : HSE Divided by 39 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV40 : HSE Divided by 40 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV41 : HSE Divided by 41 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV42 : HSE Divided by 42 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV43 : HSE Divided by 43 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV44 : HSE Divided by 44 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV45 : HSE Divided by 45 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV46 : HSE Divided by 46 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV47 : HSE Divided by 47 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV48 : HSE Divided by 48 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV49 : HSE Divided by 49 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV50 : HSE Divided by 50 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV51 : HSE Divided by 51 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV52 : HSE Divided by 52 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV53 : HSE Divided by 53 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV54 : HSE Divided by 54 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV55 : HSE Divided by 55 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV56 : HSE Divided by 56 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV57 : HSE Divided by 57 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV58 : HSE Divided by 58 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV59 : HSE Divided by 59 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV60 : HSE Divided by 60 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV61 : HSE Divided by 61 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV62 : HSE Divided by 62 selected as RTC clock + * @arg @ref RCC_RTC_HSE_DIV63 : HSE Divided by 63 selected as RTC clock + */ +#define __HAL_RCC_GET_RTC_HSE_PRESCALER() ((uint32_t)(READ_BIT(RCC->CFGR1, RCC_CFGR1_RTCPRE))) + +/** @brief Macros to enable or disable the main PLL. + * @note After enabling the main PLL, the application software should wait on + * PLLRDY flag to be set indicating that PLL clock is stable and can + * be used as system clock source. + * @note The main PLL can not be disabled if it is used as system clock source + * @note The main PLL is disabled by hardware when entering STOP and STANDBY modes. + */ +#define __HAL_RCC_PLL1_ENABLE() SET_BIT(RCC->CR, RCC_CR_PLL1ON) +#define __HAL_RCC_PLL1_DISABLE() CLEAR_BIT(RCC->CR, RCC_CR_PLL1ON) + +/** + * @brief Enables or disables each clock output (PLL1P_CLK, PLL1Q_CLK, PLL1R_CLK) + * @note Enabling/disabling Those Clocks can be any time without the need to stop the PLL1, + * (except the ck_pll_p of the System PLL that cannot be stopped if used as System + * Clock. This is mainly used to save Power. + * @param __PLL1_CLOCKOUT__: specifies the PLL clock to be outputted + * This parameter can be one of the following values: + * @arg RCC_PLL1_DIVP: This Clock is used to generate the high speed system clock (up to 250MHz) + * @arg RCC_PLL1_DIVQ: This Clock is used to generate the clock for USB (48 MHz), RNG (<=48 MHz), + * OCTOSPI, SPI, SAI and Ethernet + * @arg RCC_PLL1_DIVR: This Clock is used to generate an accurate clock + * @retval None + * + */ +#define __HAL_RCC_PLL1_CLKOUT_ENABLE(__PLL1_CLOCKOUT__) SET_BIT(RCC->PLL1CFGR, (__PLL1_CLOCKOUT__)) + +#define __HAL_RCC_PLL1_CLKOUT_DISABLE(__PLL1_CLOCKOUT__) CLEAR_BIT(RCC->PLL1CFGR, (__PLL1_CLOCKOUT__)) + +/** + * @brief Macro to get the PLL clock output enable status. + * @param __PLL1_CLOCKOUT__ specifies the PLL1 clock to be output. + * This parameter can be one of the following values: + * @arg RCC_PLL1_DIVP: This Clock is used to generate the high speed system clock (up to 250MHz) + * @arg RCC_PLL1_DIVQ: This Clock is used to generate the clock for USB (48 MHz), RNG (<=48 MHz), + * OCTOSPI, SPI, SAI and Ethernet + * @arg RCC_PLL1_DIVR: This Clock is used to generate an accurate clock + * @retval SET / RESET + */ +#define __HAL_RCC_GET_PLL1_CLKOUT_CONFIG(__PLL1_CLOCKOUT__) READ_BIT(RCC->PLL1CFGR, (__PLL1_CLOCKOUT__)) + +/** + * @brief Enables or disables Fractional Part Of The Multiplication Factor of PLL1 VCO + * @note Enabling/disabling Fractional Part can be any time without the need to stop the PLL1 + * @retval None + */ +#define __HAL_RCC_PLL1_FRACN_ENABLE() SET_BIT(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1FRACEN) + +#define __HAL_RCC_PLL1_FRACN_DISABLE() CLEAR_BIT(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1FRACEN) + +/** + * @brief Macro to configures the main PLL (PLL1) clock source, multiplication and division factors. + * @note This function must be used only when the main PLL1 is disabled. + * + * @param __PLL1SOURCE__: specifies the PLL entry clock source. + * This parameter can be one of the following values: + * @arg RCC_PLL1_SOURCE_CSI: CSI oscillator clock selected as PLL1 clock entry + * @arg RCC_PLL1_SOURCE_HSI: HSI oscillator clock selected as PLL1 clock entry + * @arg RCC_PLL1_SOURCE_HSE: HSE oscillator clock selected as PLL1 clock entry + * @note This clock source (__PLL1SOURCE__) is the clock source for PLL1 (main PLL) and is different + from PLL2 & PLL3 clock sources. + * + * @param __PLL1M__: specifies the division factor for PLL VCO input clock + * This parameter must be a number between 1 and 63. + * @note You have to set the PLL1M parameter correctly to ensure that the VCO input + * frequency ranges from 1 to 16 MHz. + * + * @param __PLL1N__: specifies the multiplication factor for PLL VCO output clock + * This parameter must be a number between 4 and 512. + * @note You have to set the PLL1N parameter correctly to ensure that the VCO + * output frequency is between 150 and 420 MHz (when in medium VCO range) or + * between 192 and 836 MHZ (when in wide VCO range) + * + * @param __PLL1P__: specifies the division factor for system clock. + * This parameter must be a number between 2 and 128 (where odd numbers not allowed) + * + * @param __PLL1Q__: specifies the division factor for peripheral kernel clocks + * This parameter must be a number between 1 and 128 + * + * @param __PLL1R__: specifies the division factor for peripheral kernel clocks + * This parameter must be a number between 1 and 128 + * + * @retval None + */ +#define __HAL_RCC_PLL1_CONFIG(__PLL1SOURCE__, __PLL1M__, __PLL1N__, __PLL1P__, __PLL1Q__, __PLL1R__) \ + do{ MODIFY_REG(RCC->PLL1CFGR, (RCC_PLL1CFGR_PLL1SRC | RCC_PLL1CFGR_PLL1M), \ + ((__PLL1SOURCE__) << RCC_PLL1CFGR_PLL1SRC_Pos) | ((__PLL1M__) << RCC_PLL1CFGR_PLL1M_Pos));\ + WRITE_REG(RCC->PLL1DIVR , ( (((__PLL1N__) - 1U ) & RCC_PLL1DIVR_PLL1N) | \ + ((((__PLL1P__) - 1U ) << RCC_PLL1DIVR_PLL1P_Pos) & RCC_PLL1DIVR_PLL1P) | \ + ((((__PLL1Q__) - 1U) << RCC_PLL1DIVR_PLL1Q_Pos) & RCC_PLL1DIVR_PLL1Q) | \ + ((((__PLL1R__) - 1U) << RCC_PLL1DIVR_PLL1R_Pos) & RCC_PLL1DIVR_PLL1R))); \ + } while(0) + +/** @brief Macro to configure the PLL1 clock source. + * @note This function must be used only when PLL1 is disabled. + * @param __PLL1SOURCE__: specifies the PLL1 entry clock source. + * This parameter can be one of the following values: + * @arg RCC_PLL1_SOURCE_CSI: CSI oscillator clock selected as PLL1 clock entry + * @arg RCC_PLL1_SOURCE_HSI: HSI oscillator clock selected as PLL1 clock entry + * @arg RCC_PLL1_SOURCE_HSE: HSE oscillator clock selected as PLL1 clock entry + * + */ +#define __HAL_RCC_PLL1_PLLSOURCE_CONFIG(__PLL1SOURCE__) \ + MODIFY_REG(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1SRC, (__PLL1SOURCE__)) + +/** @brief Macro to configure the PLL1 input clock division factor M. + * + * @note This function must be used only when the PLL1 is disabled. + * @note PLL1 clock source is common with the main PLL (configured through + * __HAL_RCC_PLL1_CONFIG() macro) + * + * @param __PLL1M__ specifies the division factor for PLL1 clock. + * This parameter must be a number between Min_Data = 1 and Max_Data = 63. + * In order to save power when PLL1 is not used, the value of PLL1M must be set to 0. + * + * @retval None + */ +#define __HAL_RCC_PLL1_DIVM_CONFIG(__PLL1M__) \ + MODIFY_REG(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1M, (__PLL1M__) << RCC_PLL1CFGR_PLL1M_Pos) + +/** + * @brief Macro to configures the main PLL clock Fractional Part Of The Multiplication Factor + * + * @note These bits can be written at any time, allowing dynamic fine-tuning of the PLL1 VCO + * + * @param __PLL1FRACN__: specifies Fractional Part Of The Multiplication Factor for PLL1 VCO + * It should be a value between 0 and 8191 + * @note Warning: The software has to set correctly these bits to insure that the VCO + * output frequency is between its valid frequency range, which is: + * 192 to 836 MHz if PLL1VCOSEL = 0 + * 150 to 420 MHz if PLL1VCOSEL = 1. + * + * + * @retval None + */ +#define __HAL_RCC_PLL1_FRACN_CONFIG(__PLL1FRACN__) WRITE_REG(RCC->PLL1FRACR, \ + (uint32_t)(__PLL1FRACN__) << RCC_PLL1FRACR_PLL1FRACN_Pos) + +/** @brief Macro to select the PLL1 reference frequency range. + * @param __PLL1VCIRange__: specifies the PLL1 input frequency range + * This parameter can be one of the following values: + * @arg RCC_PLL1_VCIRANGE_0: Range frequency is between 1 and 2 MHz + * @arg RCC_PLL1_VCIRANGE_1: Range frequency is between 2 and 4 MHz + * @arg RCC_PLL1_VCIRANGE_2: Range frequency is between 4 and 8 MHz + * @arg RCC_PLL1_VCIRANGE_3: Range frequency is between 8 and 16 MHz + * @retval None + */ +#define __HAL_RCC_PLL1_VCIRANGE(__PLL1VCIRange__) \ + MODIFY_REG(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1RGE, (__PLL1VCIRange__)) + +/** @brief Macro to select the PLL1 reference frequency range. + * @param __RCC_PLL1VCORange__: specifies the PLL1 input frequency range + * This parameter can be one of the following values: + * @arg RCC_PLL1_VCORANGE_WIDE: Range frequency is between 192 and 836 MHz + * @arg RCC_PLL1_VCORANGE_MEDIUM: Range frequency is between 150 and 420 MHz + * + * + * @retval None + */ +#define __HAL_RCC_PLL1_VCORANGE(__RCC_PLL1VCORange__) \ + MODIFY_REG(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1VCOSEL, (__RCC_PLL1VCORange__)) + +/** @brief Macro to get the oscillator used as PLL1 clock source. + * @retval The oscillator used as PLL1 clock source. The returned value can be one + * of the following: + * - RCC_PLL1_SOURCE_NONE: No oscillator is used as PLL clock source. + * - RCC_PLL1_SOURCE_CSI: CSI oscillator is used as PLL clock source. + * - RCC_PLL1_SOURCE_HSI: HSI oscillator is used as PLL clock source. + * - RCC_PLL1_SOURCE_HSE: HSE oscillator is used as PLL clock source. + */ +#define __HAL_RCC_GET_PLL1_OSCSOURCE() ((uint32_t)(RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1SRC)) + +/** + * @brief Macro to configure the system clock source. + * @param __SYSCLKSOURCE__: specifies the system clock source. + * This parameter can be one of the following values: + * - RCC_SYSCLKSOURCE_CSI: CSI oscillator is used as system clock source. + * - RCC_SYSCLKSOURCE_HSI: HSI oscillator is used as system clock source. + * - RCC_SYSCLKSOURCE_HSE: HSE oscillator is used as system clock source. + * - RCC_SYSCLKSOURCE_PLL1CLK: PLL1P output is used as system clock source. + * @retval None + */ +#define __HAL_RCC_SYSCLK_CONFIG(__SYSCLKSOURCE__) \ + MODIFY_REG(RCC->CFGR1, RCC_CFGR1_SW, (__SYSCLKSOURCE__)) + +/** @brief Macro to get the clock source used as system clock. + * @retval The clock source used as system clock. The returned value can be one + * of the following: + * - RCC_SYSCLKSOURCE_STATUS_CSI: CSI used as system clock. + * - RCC_SYSCLKSOURCE_STATUS_HSI: HSI used as system clock. + * - RCC_SYSCLKSOURCE_STATUS_HSE: HSE used as system clock. + * - RCC_SYSCLKSOURCE_STATUS_PLL1CLK: PLL1P used as system clock. + */ +#define __HAL_RCC_GET_SYSCLK_SOURCE() ((uint32_t)(RCC->CFGR1 & RCC_CFGR1_SWS)) + +/** + * @brief Macro to configure the External Low Speed oscillator (LSE) drive capability. + * @note As the LSE is in the Backup domain and write access is denied to + * this domain after reset, you have to enable the write access using + * HAL_PWR_EnableBkUpAccess() function before to configure the LSE + * (to be done once after reset). + * @param __LSEDRIVE__: specifies the new state of the LSE drive capability. + * This parameter can be one of the following values: + * @arg @ref RCC_LSEDRIVE_LOW LSE oscillator low drive capability. + * @arg @ref RCC_LSEDRIVE_MEDIUMLOW LSE oscillator medium low drive capability. + * @arg @ref RCC_LSEDRIVE_MEDIUMHIGH LSE oscillator medium high drive capability. + * @arg @ref RCC_LSEDRIVE_HIGH LSE oscillator high drive capability. + * @retval None + */ +#define __HAL_RCC_LSEDRIVE_CONFIG(__LSEDRIVE__) \ + MODIFY_REG(RCC->BDCR, RCC_BDCR_LSEDRV, (uint32_t)(__LSEDRIVE__)) + +/** + * @brief Macro to configure the wake up from stop clock. + * @note The configured clock is also used as emergency clock for the Clock Security System on HSE (HSECSS). + * @param __STOPWUCLK__: specifies the clock source used after wake up from stop. + * This parameter can be one of the following values: + * @arg @ref RCC_STOP_WAKEUPCLOCK_HSI HSI selected as system clock source + * @arg @ref RCC_STOP_WAKEUPCLOCK_CSI CSI selected as system clock source + * @retval None + */ +#define __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(__STOPWUCLK__) \ + MODIFY_REG(RCC->CFGR1, RCC_CFGR1_STOPWUCK, (__STOPWUCLK__)) + +#define __HAL_RCC_HSECSS_RECOVCLK_CONFIG __HAL_RCC_WAKEUPSTOP_CLK_CONFIG + +/** + * @brief Macro to configure the Kernel wake up from stop clock. + * @param __RCC_STOPKERWUCLK__: specifies the Kernel clock source used after wake up from stop + * This parameter can be one of the following values: + * @arg RCC_STOP_KERWAKEUPCLOCK_CSI: CSI selected as Kernel clock source + * @arg RCC_STOP_KERWAKEUPCLOCK_HSI: HSI selected as Kernel clock source + * @retval None + */ +#define __HAL_RCC_KERWAKEUPSTOP_CLK_CONFIG(__RCC_STOPKERWUCLK__) \ + MODIFY_REG(RCC->CFGR1, RCC_CFGR1_STOPKERWUCK, (__RCC_STOPKERWUCLK__)) + +/** @defgroup RCCEx_MCOx_Clock_Config RCC Extended MCOx Clock Config + * @{ + */ + +/** @brief Macro to configure the MCO1 clock. + * @param __MCOCLKSOURCE__ specifies the MCO1 clock source. + * This parameter can be one of the following values: + * @arg RCC_MCO1SOURCE_HSI: HSI clock selected as MCO1 source + * @arg RCC_MCO1SOURCE_LSE: LSE clock selected as MCO1 source + * @arg RCC_MCO1SOURCE_HSE: HSE clock selected as MCO1 source + * @arg RCC_MCO1SOURCE_PLL1QCLK: PLL1Q clock selected as MCO1 source + * @arg RCC_MCO1SOURCE_HSI48: HSI48 (48MHZ) selected as MCO1 source + * @param __MCODIV__ specifies the MCO clock prescaler. + * This parameter can be one of the following values: + * @arg RCC_MCODIV_1 up to RCC_MCODIV_15 : divider applied to MCO1 clock + */ +#define __HAL_RCC_MCO1_CONFIG(__MCOCLKSOURCE__, __MCODIV__) \ + MODIFY_REG(RCC->CFGR1, (RCC_CFGR1_MCO1SEL | RCC_CFGR1_MCO1PRE), ((__MCOCLKSOURCE__) | (__MCODIV__))) + +/** @brief Macro to configure the MCO2 clock. + * @param __MCOCLKSOURCE__ specifies the MCO2 clock source. + * This parameter can be one of the following values: + * @arg RCC_MCO2SOURCE_SYSCLK: System clock (SYSCLK) selected as MCO2 source + * @arg RCC_MCO2SOURCE_PLL2PCLK: PLL2P clock selected as MCO2 source + * @arg RCC_MCO2SOURCE_HSE: HSE clock selected as MCO2 source + * @arg RCC_MCO2SOURCE_PLL1PCLK: PLL1P clock selected as MCO2 source + * @arg RCC_MCO2SOURCE_CSI: CSI clock selected as MCO2 source + * @arg RCC_MCO2SOURCE_LSI: LSI clock selected as MCO2 source + * @param __MCODIV__ specifies the MCO clock prescaler. + * This parameter can be one of the following values: + * @arg RCC_MCODIV_1 up to RCC_MCODIV_15 : divider applied to MCO2 clock + */ +#define __HAL_RCC_MCO2_CONFIG(__MCOCLKSOURCE__, __MCODIV__) \ + MODIFY_REG(RCC->CFGR1, (RCC_CFGR1_MCO2SEL | RCC_CFGR1_MCO2PRE), ((__MCOCLKSOURCE__) | ((__MCODIV__) << 7))); + +/** + * @} + */ + +/** @defgroup RCC_Flags_Interrupts_Management Flags Interrupts Management + * @brief macros to manage the specified RCC Flags and interrupts. + * @{ + */ + +/** @brief Enable RCC interrupt (Perform access to RCC_CIER[8:0] bits to enable + * the selected interrupts). + * @param __INTERRUPT__: specifies the RCC interrupt sources to be enabled. + * This parameter can be any combination of the following values: + * @arg @ref RCC_IT_LSIRDY LSI ready interrupt + * @arg @ref RCC_IT_LSERDY LSE ready interrupt + * @arg @ref RCC_IT_CSIRDY CSI ready interrupt + * @arg @ref RCC_IT_HSIRDY HSI ready interrupt + * @arg @ref RCC_IT_HSERDY HSE ready interrupt + * @arg @ref RCC_IT_PLL1RDY Main PLL ready interrupt + * @arg @ref RCC_IT_PLL2RDY PLL2 ready interrupt + * @arg @ref RCC_IT_PLL3RDY PLL3 ready interrupt (*) + * @arg @ref RCC_IT_HSECSS HSE Clock security system interrupt + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + * @retval None + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + */ +#define __HAL_RCC_ENABLE_IT(__INTERRUPT__) SET_BIT(RCC->CIER, (__INTERRUPT__)) + +/** @brief Disable RCC interrupt (Perform access to RCC_CIER[8:0] bits to disable + * the selected interrupts). + * @param __INTERRUPT__: specifies the RCC interrupt sources to be disabled. + * This parameter can be any combination of the following values: + * @arg @ref RCC_IT_LSIRDY LSI ready interrupt + * @arg @ref RCC_IT_LSERDY LSE ready interrupt + * @arg @ref RCC_IT_CSIRDY CSI ready interrupt + * @arg @ref RCC_IT_HSIRDY HSI ready interrupt + * @arg @ref RCC_IT_HSERDY HSE ready interrupt + * @arg @ref RCC_IT_PLL1RDY Main PLL ready interrupt + * @arg @ref RCC_IT_PLL2RDY PLL2 ready interrupt + * @arg @ref RCC_IT_PLL3RDY PLL3 ready interrupt (*) + * @arg @ref RCC_IT_HSECSS HSE Clock security system interrupt + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + * @retval None + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + */ +#define __HAL_RCC_DISABLE_IT(__INTERRUPT__) CLEAR_BIT(RCC->CIER, (__INTERRUPT__)) + +/** @brief Clear the RCC's interrupt pending bits (Perform Byte access to RCC_CICR[10:0] + * bits to clear the selected interrupt pending bits. + * @param __INTERRUPT__: specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg @ref RCC_IT_LSIRDY LSI ready interrupt + * @arg @ref RCC_IT_LSERDY LSE ready interrupt + * @arg @ref RCC_IT_CSIRDY CSI ready interrupt + * @arg @ref RCC_IT_HSIRDY HSI ready interrupt + * @arg @ref RCC_IT_HSERDY HSE ready interrupt + * @arg @ref RCC_IT_PLL1RDY Main PLL ready interrupt + * @arg @ref RCC_IT_PLL2RDY PLL2 ready interrupt + * @arg @ref RCC_IT_PLL3RDY PLL3 ready interrupt (*) + * @arg @ref RCC_IT_HSECSS HSE Clock security system interrupt + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + * @retval None + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + */ +#define __HAL_RCC_CLEAR_IT(__INTERRUPT__) WRITE_REG(RCC->CICR, (__INTERRUPT__)) + +/** @brief Check whether the RCC interrupt has occurred or not. + * @param __INTERRUPT__: specifies the RCC interrupt source to check. + * This parameter can be one of the following values: + * @arg @ref RCC_IT_LSIRDY LSI ready interrupt + * @arg @ref RCC_IT_LSERDY LSE ready interrupt + * @arg @ref RCC_IT_CSIRDY CSI ready interrupt + * @arg @ref RCC_IT_HSIRDY HSI ready interrupt + * @arg @ref RCC_IT_HSERDY HSE ready interrupt + * @arg @ref RCC_IT_PLL1RDY Main PLL ready interrupt + * @arg @ref RCC_IT_PLL2RDY PLL2 ready interrupt + * @arg @ref RCC_IT_PLL3RDY PLL3 ready interrupt (*) + * @arg @ref RCC_IT_HSECSS HSE Clock security system interrupt + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + * @retval The new state of __INTERRUPT__ (TRUE or FALSE). + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + */ +#define __HAL_RCC_GET_IT(__INTERRUPT__) ((RCC->CIFR & (__INTERRUPT__)) == (__INTERRUPT__)) + +/** @brief Set RMVF bit to clear the reset flags. + * The reset flags are: RCC_FLAG_SFTRST, RCC_FLAG_PINRST, RCC_FLAG_BORRST, + * RCC_FLAG_SFTRST, RCC_FLAG_IWDGRST, RCC_FLAG_WWDGRST and RCC_FLAG_LPWRRST. + * @retval None + */ +#define __HAL_RCC_CLEAR_RESET_FLAGS() (RCC->RSR |= RCC_RSR_RMVF) + +/** @brief Check whether the selected RCC flag is set or not. + * @param __FLAG__: specifies the flag to check. + * This parameter can be one of the following values: + * @arg @ref RCC_FLAG_CSIRDY CSI oscillator clock ready + * @arg @ref RCC_FLAG_HSIRDY HSI oscillator clock ready + * @arg @ref RCC_FLAG_HSERDY HSE oscillator clock ready + * @arg @ref RCC_FLAG_PLL1RDY Main PLL1 clock ready + * @arg @ref RCC_FLAG_PLL2RDY PLL2 clock ready + * @arg @ref RCC_FLAG_PLL3RDY PLL3 clock ready (*) + * @arg @ref RCC_FLAG_HSI48RDY HSI48 clock ready + * @arg @ref RCC_FLAG_LSERDY LSE oscillator clock ready + * @arg @ref RCC_FLAG_LSECSSD Clock security system failure on LSE oscillator detection + * @arg @ref RCC_FLAG_LSIRDY LSI oscillator clock ready + * @arg @ref RCC_FLAG_HSIDIVF HSI Divider + * @arg @ref RCC_FLAG_BORRST BOR reset + * @arg @ref RCC_FLAG_PINRST Pin reset + * @arg @ref RCC_FLAG_RMVF Remove reset Flag + * @arg @ref RCC_FLAG_SFTRST Software reset + * @arg @ref RCC_FLAG_IWDGRST Independent Watchdog reset + * @arg @ref RCC_FLAG_WWDGRST Window Watchdog reset + * @arg @ref RCC_FLAG_LPWRRST Low Power reset + * @retval The new state of __FLAG__ (TRUE or FALSE). + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + */ +#define __HAL_RCC_GET_FLAG(__FLAG__) (((((((__FLAG__) >> 5U) == 1U) ? RCC->CR : \ + ((((__FLAG__) >> 5U) == 2U) ? RCC->BDCR : \ + ((((__FLAG__) >> 5U) == 3U) ? RCC->RSR : RCC->CIFR))) & \ + (1U << ((__FLAG__) & RCC_FLAG_MASK))) != 0U) ? 1U : 0U) +/** + * @} + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup RCC_Private_Constants RCC Private Constants + * @{ + */ + +/** @defgroup RCC_Timeout_Value Timeout Values + * @{ + */ +#define RCC_HSE_TIMEOUT_VALUE HSE_STARTUP_TIMEOUT +#define RCC_HSI_TIMEOUT_VALUE ((uint32_t)2U) /* 2 ms (minimum Tick + 1) */ +#define RCC_CSI_TIMEOUT_VALUE ((uint32_t)2U) /* 2 ms (minimum Tick + 1) */ +#define RCC_DBP_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1) */ +#define RCC_LSE_TIMEOUT_VALUE LSE_STARTUP_TIMEOUT +/** + * @} + */ + +/* Defines used for Flags */ +#define RCC_CR_REG_INDEX (1U) +#define RCC_BDCR_REG_INDEX (2U) +#define RCC_RSR_REG_INDEX (3U) + +#define RCC_FLAG_MASK (0x1FU) + +/* Defines Oscillator Masks */ +#define RCC_OSCILLATORTYPE_ALL (RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSI48 | \ + RCC_OSCILLATORTYPE_CSI | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE) +/*!< All Oscillator to configure */ + + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup RCC_Private_Macros + * @{ + */ + +#define IS_RCC_OSCILLATORTYPE(__OSCILLATOR__) (((__OSCILLATOR__) == RCC_OSCILLATORTYPE_NONE) || \ + (((__OSCILLATOR__) & ~RCC_OSCILLATORTYPE_ALL) == 0x00U)) + + +#define IS_RCC_HSE(__HSE__) (((__HSE__) == RCC_HSE_OFF) || ((__HSE__) == RCC_HSE_ON) || \ + ((__HSE__) == RCC_HSE_BYPASS) || ((__HSE__) == RCC_HSE_BYPASS_DIGITAL)) + +#define IS_RCC_LSE(__LSE__) (((__LSE__) == RCC_LSE_OFF) || ((__LSE__) == RCC_LSE_ON) || \ + ((__LSE__) == RCC_LSE_BYPASS) || ((__LSE__) == RCC_LSE_BYPASS_DIGITAL)) + +#define IS_RCC_HSI(__HSI__) (((__HSI__) == RCC_HSI_OFF) || ((__HSI__) == RCC_HSI_ON)) + +#define IS_RCC_HSIDIV(__DIV__) (((__DIV__) == RCC_HSI_DIV1) || ((__DIV__) == RCC_HSI_DIV2) || \ + ((__DIV__) == RCC_HSI_DIV4) || ((__DIV__) == RCC_HSI_DIV8)) + +#define IS_RCC_HSI_CALIBRATION_VALUE(__VALUE__) ((__VALUE__) \ + <= (uint32_t)( RCC_HSICFGR_HSITRIM >> RCC_HSICFGR_HSITRIM_Pos)) + +#define IS_RCC_LSI(__LSI__) (((__LSI__) == RCC_LSI_OFF) || ((__LSI__) == RCC_LSI_ON)) + +#define IS_RCC_CSI(__CSI__) (((__CSI__) == RCC_CSI_OFF) || ((__CSI__) == RCC_CSI_ON)) + +#define IS_RCC_CSICALIBRATION_VALUE(__VALUE__) ((__VALUE__) \ + <= (uint32_t)( RCC_CSICFGR_CSITRIM >> RCC_CSICFGR_CSITRIM_Pos)) + +#define IS_RCC_HSI48(__HSI48__) (((__HSI48__) == RCC_HSI48_OFF) || ((__HSI48__) == RCC_HSI48_ON)) + +#define IS_RCC_PLL(PLL) (((PLL) == RCC_PLL_NONE) ||((PLL) == RCC_PLL_OFF) || \ + ((PLL) == RCC_PLL_ON)) + +#define IS_RCC_PLL1_SOURCE(SOURCE) (((SOURCE) == RCC_PLL1_SOURCE_CSI) || \ + ((SOURCE) == RCC_PLL1_SOURCE_HSI) || \ + ((SOURCE) == RCC_PLL1_SOURCE_HSE)) + +#define IS_RCC_PLL1_DIVM_VALUE(VALUE) ((1U <= (VALUE)) && ((VALUE) <= 63U)) +#define IS_RCC_PLL1_MULN_VALUE(VALUE) ((4U <= (VALUE)) && ((VALUE) <= 512U)) +#define IS_RCC_PLL1_DIVP_VALUE(VALUE) ((2U <= (VALUE)) && ((VALUE) <= 128U)) +#define IS_RCC_PLL1_DIVQ_VALUE(VALUE) ((1U <= (VALUE)) && ((VALUE) <= 128U)) +#define IS_RCC_PLL1_DIVR_VALUE(VALUE) ((1U <= (VALUE)) && ((VALUE) <= 128U)) + +#define IS_RCC_PLL1_CLOCKOUT_VALUE(VALUE) (((VALUE) == RCC_PLL1_DIVP) || \ + ((VALUE) == RCC_PLL1_DIVQ) || \ + ((VALUE) == RCC_PLL1_DIVR)) + +#define IS_RCC_PLL1_VCIRGE_VALUE(VALUE) (((VALUE) == RCC_PLL1_VCIRANGE_0) || \ + ((VALUE) == RCC_PLL1_VCIRANGE_1) || \ + ((VALUE) == RCC_PLL1_VCIRANGE_2) || \ + ((VALUE) == RCC_PLL1_VCIRANGE_3)) + +#define IS_RCC_PLL1_VCORGE_VALUE(VALUE) (((VALUE) == RCC_PLL1_VCORANGE_WIDE) || ((VALUE) == RCC_PLL1_VCORANGE_MEDIUM)) + +#define IS_RCC_PLL1_FRACN_VALUE(VALUE) ((VALUE) <= 8191U) + +#define IS_RCC_CLOCKTYPE(CLK) ((1U <= (CLK)) && ((CLK) <= 0x1FU)) + +#define IS_RCC_SYSCLKSOURCE(__SOURCE__) (((__SOURCE__) == RCC_SYSCLKSOURCE_CSI) || \ + ((__SOURCE__) == RCC_SYSCLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_SYSCLKSOURCE_HSE) || \ + ((__SOURCE__) == RCC_SYSCLKSOURCE_PLLCLK)) + +#define IS_RCC_HCLK(__HCLK__) (((__HCLK__) == RCC_SYSCLK_DIV1) || ((__HCLK__) == RCC_SYSCLK_DIV2) || \ + ((__HCLK__) == RCC_SYSCLK_DIV4) || ((__HCLK__) == RCC_SYSCLK_DIV8) || \ + ((__HCLK__) == RCC_SYSCLK_DIV16) || ((__HCLK__) == RCC_SYSCLK_DIV64) || \ + ((__HCLK__) == RCC_SYSCLK_DIV128) || ((__HCLK__) == RCC_SYSCLK_DIV256) || \ + ((__HCLK__) == RCC_SYSCLK_DIV512)) + +#define IS_RCC_PCLK(__PCLK__) (((__PCLK__) == RCC_HCLK_DIV1) || ((__PCLK__) == RCC_HCLK_DIV2) || \ + ((__PCLK__) == RCC_HCLK_DIV4) || ((__PCLK__) == RCC_HCLK_DIV8) || \ + ((__PCLK__) == RCC_HCLK_DIV16)) + +#define IS_RCC_RTCCLKSOURCE(SOURCE) \ + (((SOURCE) == RCC_RTCCLKSOURCE_LSE) || ((SOURCE) == RCC_RTCCLKSOURCE_LSI) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV2) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV3) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV4) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV5) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV6) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV7) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV8) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV9) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV10) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV11) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV12) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV13) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV14) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV15) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV16) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV17) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV18) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV19) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV20) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV21) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV22) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV23) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV24) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV25) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV26) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV27) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV28) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV29) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV30) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV31) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV32) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV33) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV34) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV35) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV36) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV37) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV38) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV39) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV40) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV41) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV42) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV43) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV44) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV45) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV46) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV47) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV48) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV49) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV50) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV51) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV52) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV53) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV54) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV55) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV56) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV57) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV58) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV59) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV60) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV61) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV62) || ((SOURCE) == RCC_RTCCLKSOURCE_HSE_DIV63) || \ + ((SOURCE) == RCC_RTCCLKSOURCE_NO_CLK)) + +#define IS_RCC_MCO(MCOx) (((MCOx) == RCC_MCO1) || ((MCOx) == RCC_MCO2)) + +#define IS_RCC_MCO1SOURCE(SOURCE) (((SOURCE) == RCC_MCO1SOURCE_HSI) || ((SOURCE) == RCC_MCO1SOURCE_LSE) || \ + ((SOURCE) == RCC_MCO1SOURCE_HSE) || ((SOURCE) == RCC_MCO1SOURCE_PLL1Q) || \ + ((SOURCE) == RCC_MCO1SOURCE_HSI48)) + +#define IS_RCC_MCO2SOURCE(SOURCE) (((SOURCE) == RCC_MCO2SOURCE_SYSCLK) || ((SOURCE) == RCC_MCO2SOURCE_PLL2P) || \ + ((SOURCE) == RCC_MCO2SOURCE_HSE) || ((SOURCE) == RCC_MCO2SOURCE_PLL1P) || \ + ((SOURCE) == RCC_MCO2SOURCE_CSI) || ((SOURCE) == RCC_MCO2SOURCE_LSI)) + +#define IS_RCC_MCODIV(DIV) (((DIV) == RCC_MCODIV_1) || ((DIV) == RCC_MCODIV_2) || \ + ((DIV) == RCC_MCODIV_3) || ((DIV) == RCC_MCODIV_4) || \ + ((DIV) == RCC_MCODIV_5) || ((DIV) == RCC_MCODIV_6) || \ + ((DIV) == RCC_MCODIV_7) || ((DIV) == RCC_MCODIV_8) || \ + ((DIV) == RCC_MCODIV_9) || ((DIV) == RCC_MCODIV_10) || \ + ((DIV) == RCC_MCODIV_11) || ((DIV) == RCC_MCODIV_12) || \ + ((DIV) == RCC_MCODIV_13) || ((DIV) == RCC_MCODIV_14) || \ + ((DIV) == RCC_MCODIV_15)) + +#define IS_RCC_LSE_DRIVE(__DRIVE__) (((__DRIVE__) == RCC_LSEDRIVE_LOW) || \ + ((__DRIVE__) == RCC_LSEDRIVE_MEDIUMLOW) || \ + ((__DRIVE__) == RCC_LSEDRIVE_MEDIUMHIGH) || \ + ((__DRIVE__) == RCC_LSEDRIVE_HIGH)) + +#define IS_RCC_STOP_WAKEUPCLOCK(__SOURCE__) (((__SOURCE__) == RCC_STOP_WAKEUPCLOCK_CSI) || \ + ((__SOURCE__) == RCC_STOP_WAKEUPCLOCK_HSI)) + +#define IS_RCC_STOP_KERWAKEUPCLOCK(SOURCE) (((SOURCE) == RCC_STOP_KERWAKEUPCLOCK_CSI) || \ + ((SOURCE) == RCC_STOP_KERWAKEUPCLOCK_HSI)) + +#if defined(RCC_SECCFGR_HSISEC) + +#define IS_RCC_ITEM_ATTRIBUTES(ITEM) ((((ITEM) & RCC_ALL) != 0U) && (((ITEM) & ~RCC_ALL) == 0U)) + +#define IS_RCC_SINGLE_ITEM_ATTRIBUTES(ITEM) (((ITEM) == RCC_HSI) || \ + ((ITEM) == RCC_HSE) || \ + ((ITEM) == RCC_CSI) || \ + ((ITEM) == RCC_LSI) || \ + ((ITEM) == RCC_LSE) || \ + ((ITEM) == RCC_SYSCLK) || \ + ((ITEM) == RCC_PRESC) || \ + ((ITEM) == RCC_PLL1) || \ + ((ITEM) == RCC_PLL2) || \ + ((ITEM) == RCC_PLL3) || \ + ((ITEM) == RCC_HSI48) || \ + ((ITEM) == RCC_RMVF) || \ + ((ITEM) == RCC_CKPERSEL)) +#endif /* RCC_SECCFGR_HSISEC */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define IS_RCC_ATTRIBUTES(ATTRIBUTES) (((ATTRIBUTES) == RCC_SEC_PRIV) || \ + ((ATTRIBUTES) == RCC_SEC_NPRIV) || \ + ((ATTRIBUTES) == RCC_NSEC_PRIV) || \ + ((ATTRIBUTES) == RCC_NSEC_NPRIV)) +#elif defined(RCC_PRIVCFGR_NSPRIV) +#define IS_RCC_ATTRIBUTES(ATTRIBUTES) (((ATTRIBUTES) == RCC_NSEC_NPRIV) || ((ATTRIBUTES) == RCC_NSEC_PRIV)) +#else +#define IS_RCC_ATTRIBUTES(ATTRIBUTES) (((ATTRIBUTES) == RCC_NPRIV) || ((ATTRIBUTES) == RCC_PRIV)) +#endif /* __ARM_FEATURE_CMSE */ +/** + * @} + */ + +/* Include RCC HAL Extended module */ +#include "stm32h5xx_hal_rcc_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup RCC_Exported_Functions + * @{ + */ + +/** @addtogroup RCC_Exported_Functions_Group1 + * @{ + */ + +/* Initialization and de-initialization functions ******************************/ +HAL_StatusTypeDef HAL_RCC_DeInit(void); +HAL_StatusTypeDef HAL_RCC_OscConfig(const RCC_OscInitTypeDef *pOscInitStruct); +HAL_StatusTypeDef HAL_RCC_ClockConfig(const RCC_ClkInitTypeDef *pClkInitStruct, uint32_t FLatency); + +/** + * @} + */ + +/** @addtogroup RCC_Exported_Functions_Group2 + * @{ + */ + +/* Peripheral Control functions **********************************************/ +void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv); +void HAL_RCC_EnableCSS(void); +uint32_t HAL_RCC_GetSysClockFreq(void); +uint32_t HAL_RCC_GetHCLKFreq(void); +uint32_t HAL_RCC_GetPCLK1Freq(void); +uint32_t HAL_RCC_GetPCLK2Freq(void); +uint32_t HAL_RCC_GetPCLK3Freq(void); +void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *pOscInitStruct); +void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *pClkInitStruct, uint32_t *pFLatency); +/* CSS NMI IRQ handler */ +void HAL_RCC_NMI_IRQHandler(void); +/* User Callbacks in non blocking mode (IT mode) */ +void HAL_RCC_CSSCallback(void); +uint32_t HAL_RCC_GetResetSource(void); + +/** + * @} + */ + +/** @addtogroup RCC_Exported_Functions_Group3 + * @{ + */ + +/* Attributes management functions ********************************************/ +void HAL_RCC_ConfigAttributes(uint32_t Item, uint32_t Attributes); +HAL_StatusTypeDef HAL_RCC_GetConfigAttributes(uint32_t Item, uint32_t *pAttributes); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32H5xx_HAL_RCC_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_rcc_ex.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_rcc_ex.h new file mode 100644 index 0000000000..6ad18b1f00 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_rcc_ex.h @@ -0,0 +1,3800 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_rcc_ex.h + * @author MCD Application Team + * @brief Header file of RCC HAL Extended module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32H5xx_HAL_RCC_EX_H +#define __STM32H5xx_HAL_RCC_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup RCCEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup RCCEx_Exported_Types RCCEx Exported Types + * @{ + */ + +/** + * @brief PLL2 Clock structure definition + */ +typedef struct +{ + uint32_t PLL2Source; /*!< RCC_PLL2Source: PLL2 entry clock source. + This parameter must be a value of @ref RCC_PLL2_Clock_Source */ + + uint32_t PLL2M; /*!< PLL2M: Division factor for PLL2 VCO input clock. + This parameter must be a number between Min_Data = 1 and Max_Data = 63 */ + + uint32_t PLL2N; /*!< PLL2N: Multiplication factor for PLL2 VCO output clock. + This parameter must be a number between Min_Data = 4 and Max_Data = 512 */ + + uint32_t PLL2P; /*!< PLL2P: Division factor for peripheral clock. + This parameter must be a number between Min_Data = 2 and Max_Data = 128 */ + + uint32_t PLL2Q; /*!< PLL2Q: Division factor for peripheral clocks. + This parameter must be a number between Min_Data = 1 and Max_Data = 128 */ + + uint32_t PLL2R; /*!< PLL2R: Division factor for peripheral clocks. + This parameter must be a number between Min_Data = 1 and Max_Data = 128 + odd division factors are not allowed */ + + uint32_t PLL2RGE; /*!CCIPR1, RCC_CCIPR1_TIMICSEL) /*!< HSI/1024, CSI/128 and HSI/8 generation for Timers 12,15 and LPTimer2 Input capture */ +#define __HAL_RCC_TIMIC_DISABLE() CLEAR_BIT(RCC->CCIPR1, RCC_CCIPR1_TIMICSEL) /*!< No clock available for Timers Input capture */ + +/** @brief Macro to configure the PLL2 clock source. + * @note This function must be used only when all PLL2 is disabled. + * @param __PLL2SOURCE__: specifies the PLL2 entry clock source. + * This parameter can be one of the following values: + * @arg RCC_PLL2_SOURCE_NONE: No oscillator clock selected as PLL2 clock entry + * @arg RCC_PLL2_SOURCE_CSI: CSI oscillator clock selected as PLL2 clock entry + * @arg RCC_PLL2_SOURCE_HSI: HSI oscillator clock selected as PLL2 clock entry + * @arg RCC_PLL2_SOURCE_HSE: HSE oscillator clock selected as PLL2 clock entry + * + */ +#define __HAL_RCC_PLL2_PLLSOURCE_CONFIG(__PLL2SOURCE__) MODIFY_REG(RCC->PLL2CFGR, RCC_PLL2CFGR_PLL2SRC, \ + (__PLL2SOURCE__)) + +/** @brief Macro to get the oscillator used as PLL2 clock source. + * @retval The oscillator used as PLL2 clock source. The returned value can be one + * of the following: + * - RCC_PLL2_SOURCE_NONE: No oscillator is used as PLL clock source. + * - RCC_PLL2_SOURCE_CSI: CSI oscillator is used as PLL clock source. + * - RCC_PLL2_SOURCE_HSI: HSI oscillator is used as PLL clock source. + * - RCC_PLL2_SOURCE_HSE: HSE oscillator is used as PLL clock source. + */ +#define __HAL_RCC_GET_PLL2_OSCSOURCE() ((uint32_t)(RCC->PLL2CFGR & RCC_PLL2CFGR_PLL2SRC)) + +/** + * @brief Macro to configures the PLL2 source, multiplication and division factors. + * @note This function must be used only when PLL2 is disabled. + * + * @param __PLL2SOURCE__: specifies the PLL2 entry clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_PLL2_SOURCE_NONE No clock selected as PLL2 clock entry + * @arg @ref RCC_PLL2_SOURCE_CSI CSI oscillator clock selected as PLL2 clock entry + * @arg @ref RCC_PLL2_SOURCE_HSI HSI oscillator clock selected as PLL2 clock entry + * @arg @ref RCC_PLL2_SOURCE_HSE HSE oscillator clock selected as PLL2 clock entry + * + * @param __PLL2M__ specifies the division factor of PLL2 input clock. + * This parameter must be a number between Min_Data = 1 and Max_Data = 63. + * + * @param __PLL2N__: specifies the multiplication factor for PLL2 VCO output clock + * This parameter must be a number between 4 and 512. + * @note You have to set the PLL2N parameter correctly to ensure that the VCO + * output frequency is between 192 and 836 MHz (Wide range) or 150 and 420 Mhz (Medium range). + * PLL2 clock frequency = f(PLL2) multiplied by PLL2N + * + * @param __PLL2P__: specifies the division factor for peripheral kernel clocks + * This parameter must be a number between 1 and 128 + * + * @param __PLL2Q__: specifies the division factor for peripheral kernel clocks + * This parameter must be a number between 1 and 128 + * + * @param __PLL2R__: specifies the division factor for peripheral kernel clocks + * This parameter must be a number between 1 and 128 + * + * @retval None + */ +#define __HAL_RCC_PLL2_CONFIG(__PLL2SOURCE__, __PLL2M__, __PLL2N__, __PLL2P__, __PLL2Q__, __PLL2R__) \ + do{ \ + MODIFY_REG(RCC->PLL2CFGR, (RCC_PLL2CFGR_PLL2SRC | RCC_PLL2CFGR_PLL2M), \ + ((__PLL2SOURCE__) << RCC_PLL2CFGR_PLL2SRC_Pos) | ((__PLL2M__) << RCC_PLL2CFGR_PLL2M_Pos)); \ + WRITE_REG(RCC->PLL2DIVR , ((((__PLL2N__) - 1U) & RCC_PLL2DIVR_PLL2N) | \ + ((((__PLL2P__) - 1U) << RCC_PLL2DIVR_PLL2P_Pos) & RCC_PLL2DIVR_PLL2P) | \ + ((((__PLL2Q__) - 1U) << RCC_PLL2DIVR_PLL2Q_Pos) & RCC_PLL2DIVR_PLL2Q) | \ + ((((__PLL2R__) - 1U) << RCC_PLL2DIVR_PLL2R_Pos) & RCC_PLL2DIVR_PLL2R))); \ + } while(0) +/** + * @brief Macro to configure the PLL2 clock multiplication factor N. + * + * @note This function must be used only when the PLL2 is disabled. + * @note PLL2 clock source is independent from the main PLL and is configured through + * __HAL_RCC_PLL2_CONFIG() macro. + * + * @param __PLL2N__ specifies the multiplication factor for PLL2 VCO output clock. + * This parameter must be a number between 4 and 512. + * @note You have to set the PLL2N parameter correctly to ensure that the VCO + * output frequency is between 192 and 836 MHz (Wide range) or 150 and 420 Mhz (Medium range). + * PLL2 clock frequency = f(PLL2) multiplied by PLL2N + * + * @retval None + */ +#define __HAL_RCC_PLL2_MULN_CONFIG(__PLL2N__) \ + MODIFY_REG(RCC->PLL2DIVR, RCC_PLL2DIVR_N2, ((__PLL2N__) - 1U) << RCC_PLL2DIVR_N2_Pos) + +/** @brief Macro to configure the PLL2 input clock division factor M. + * + * @note This function must be used only when the PLL2 is disabled. + * @note PLL2 clock source is independent from the main PLL and is configured through + * __HAL_RCC_PLL2_CONFIG() macro. + * + * @param __PLL2M__ specifies the division factor for PLL2 clock. + * This parameter must be a number between Min_Data = 1 and Max_Data = 63. + * In order to save power when PLL2 is not used, the value of PLL2M must be set to 0. + * + * @retval None + */ +#define __HAL_RCC_PLL2_DIVM_CONFIG(__PLL2M__) \ + MODIFY_REG(RCC->PLL2CFGR, RCC_PLL2CFGR_DIVM2, (__PLL2M__) << RCC_PLL2CFGR_DIVM2_Pos) + +/** @brief Macro to configure the PLL2 clock division factor P. + * + * @note This function must be used only when the PLL2 is disabled. + * @note PLL2 clock source is independent from the main PLL and is configured through + * __HAL_RCC_PLL2_CONFIG() macro. + * + * @param __PLL2P__ specifies the division factor for PLL2 output P clock. + * This parameter must be a number in the range (1 to 128). + * Use to set PLL2 output P clock frequency = f(PLL2) / PLL2P + * + * @retval None + */ +#define __HAL_RCC_PLL2_DIVP_CONFIG(__PLL2P__) \ + MODIFY_REG(RCC->PLL2DIVR, RCC_PLL2DIVR_P2, ((__PLL2P__) - 1U) << RCC_PLL2DIVR_P2_Pos) + +/** @brief Macro to configure the PLL2 clock division factor Q. + * + * @note This function must be used only when the PLL2 is disabled. + * @note PLL2 clock source is independent from the main PLL and is configured through + * __HAL_RCC_PLL2_CONFIG() macro. + * + * @param __PLL2Q__ specifies the division factor for PLL2 output Q clock. + * This parameter must be a number in the range (1 to 128). + * Use to set PLL2 output Q clock frequency = f(PLL2) / PLL2Q + * + * @retval None + */ +#define __HAL_RCC_PLL2_DIVQ_CONFIG(__PLL2Q__) \ + MODIFY_REG(RCC->PLL2DIVR, RCC_PLL2DIVR_Q2, ((__PLL2Q__) - 1U) << RCC_PLL2DIVR_Q2_Pos) + +/** @brief Macro to configure the PLL2 clock division factor R. + * + * @note This function must be used only when the PLL2 is disabled. + * @note PLL2 clock source is independent from the main PLL and is configured through + * __HAL_RCC_PLL2_CONFIG() macro. + * + * @param __PLL2R__ specifies the division factor for PLL2 output R clock. + * This parameter must be a number in the range (1 to 128). + * Use to set PLL2 output R clock frequency = f(PLL2) / PLL2R + * + * @retval None + */ +#define __HAL_RCC_PLL2_DIVR_CONFIG(__PLL2R__) \ + MODIFY_REG(RCC->PLL2DIVR, RCC_PLL2DIVR_R2, ((__PLL2R__) - 1U) << RCC_PLL2DIVR_R2_Pos) + +/** @brief Macros to enable or disable the PLL2. + * @note After enabling PLL2, the application software should wait on + * PLL2RDY flag to be set indicating that PLL2 clock is stable and can + * be used as kernel clock source. + * @note The PLL2 is disabled by hardware when entering STOP and STANDBY modes. + * @retval None + */ +#define __HAL_RCC_PLL2_ENABLE() SET_BIT(RCC->CR, RCC_CR_PLL2ON) +#define __HAL_RCC_PLL2_DISABLE() CLEAR_BIT(RCC->CR, RCC_CR_PLL2ON) + +/** + * @brief Enables or disables each clock output (PLL2_P_CLK, PLL2_Q_CLK, PLL2_R_CLK) + * @note Enabling/disabling those clocks can be done at any time without the need to stop the PLL2, + * This is mainly used to save Power. + * @param __PLL2_CLOCKOUT__ specifies the PLL2 clock to be output. + * This parameter can be one or a combination of the following values: + * @arg RCC_PLL2_DIVP: This clock is used to generate an accurate kernel clock to achieve + * high-quality audio performance on SAI interface, SPI/I2S and LPTIM peripherals. + * @arg RCC_PLL2_DIVQ: This clock is used to generate kernel clock for the random number generator RNG + * (<=48 MHz), SPI, FDCAN and UART/USART peripherals. + * @arg RCC_PLL2_DIVR: This clock is used to generate kernel clock for ADC and DAC peripherals. + * @retval None + */ +#define __HAL_RCC_PLL2_CLKOUT_ENABLE(__PLL2_CLOCKOUT__) SET_BIT(RCC->PLL2CFGR, (__PLL2_CLOCKOUT__)) +#define __HAL_RCC_PLL2_CLKOUT_DISABLE(__PLL2_CLOCKOUT__) CLEAR_BIT(RCC->PLL2CFGR, (__PLL2_CLOCKOUT__)) + +/** + * @brief Macro to get the PLL2 clock output enable status. + * @param __PLL2_CLOCKOUT__ specifies the PLL2 clock to be output. + * This parameter can be one or a combination of the following values: + * @arg RCC_PLL2_DIVP: This clock is used to generate an accurate kernel clock to achieve + * high-quality audio performance on SAI interface, SPI/I2S and LPTIM peripherals. + * @arg RCC_PLL2_DIVQ: This clock is used to generate kernel clock for the random number generator RNG + * (<=48 MHz), SPI, FDCAN and UART/USART peripherals. + * @arg RCC_PLL2_DIVR: This clock is used to generate kernel clock for ADC and DAC peripherals. + * @retval SET / RESET + */ +#define __HAL_RCC_GET_PLL2_CLKOUT_CONFIG(__PLL2_CLOCKOUT__) READ_BIT(RCC->PLL2CFGR, (__PLL2_CLOCKOUT__)) + +/** + * @brief Enables or disables Fractional Part Of The Multiplication Factor of PLL2 VCO + * @note Enabling/disabling Fractional Part can be done at any time without the need to stop the PLL2 + * @retval None + */ +#define __HAL_RCC_PLL2_FRACN_ENABLE() SET_BIT(RCC->PLL2CFGR, RCC_PLL2CFGR_PLL2FRACEN) +#define __HAL_RCC_PLL2_FRACN_DISABLE() CLEAR_BIT(RCC->PLL2CFGR, RCC_PLL2CFGR_PLL2FRACEN) + +/** + * @brief Macro to configures PLL2 clock Fractional Part Of The Multiplication Factor + * + * @note These bits can be written at any time, allowing dynamic fine-tuning of the PLL2 VCO + * + * @param __PLL2FRACN__: Specifies Fractional Part Of The Multiplication factor for PLL2 VCO + * It should be a value between 0 and 8191 + * @note Warning: the software has to set correctly these bits to insure that the VCO + * output frequency is between its valid frequency range, which is: + * 192 to 836 MHz if PLL2VCOSEL = 0 + * 150 to 420 MHz if PLL2VCOSEL = 1. + * + * @retval None + */ +#define __HAL_RCC_PLL2_FRACN_CONFIG(__PLL2FRACN__) MODIFY_REG(RCC->PLL2FRACR, RCC_PLL2FRACR_PLL2FRACN, \ + (uint32_t)(__PLL2FRACN__) << RCC_PLL2FRACR_PLL2FRACN_Pos) + +/** @brief Macro to select the PLL2 reference frequency range. + * @param __PLL2VCIRange__: specifies the PLL2 input frequency range + * This parameter can be one of the following values: + * @arg RCC_PLL2_VCIRANGE_0: Range frequency is between 1 and 2 MHz + * @arg RCC_PLL2_VCIRANGE_1: Range frequency is between 2 and 4 MHz + * @arg RCC_PLL2_VCIRANGE_2: Range frequency is between 4 and 8 MHz + * @arg RCC_PLL2_VCIRANGE_3: Range frequency is between 8 and 16 MHz + * @retval None + */ +#define __HAL_RCC_PLL2_VCIRANGE(__PLL2VCIRange__) \ + MODIFY_REG(RCC->PLL2CFGR, RCC_PLL2CFGR_PLL2RGE, (__PLL2VCIRange__)) + +/** @brief Macro to select the PLL2 reference frequency range. + * @param __RCC_PLL2VCORange__: specifies the PLL2 output frequency range + * This parameter can be one of the following values: + * @arg RCC_PLL2_VCORANGE_WIDE: Range frequency is between 192 and 836 MHz + * @arg RCC_PLL2_VCORANGE_MEDIUM: Range frequency is between 150 and 420 MHz + * + * @retval None + */ +#define __HAL_RCC_PLL2_VCORANGE(__RCC_PLL2VCORange__) \ + MODIFY_REG(RCC->PLL2CFGR, RCC_PLL2CFGR_PLL2VCOSEL, (__RCC_PLL2VCORange__)) + +#if defined(RCC_CR_PLL3ON) +/** @brief Macro to configure the PLL3 clock source. + * @note This function must be used only when all PLL3 is disabled. + * @param __PLL3SOURCE__: specifies the PLL3 entry clock source. + * This parameter can be one of the following values: + * @arg RCC_PLL3_SOURCE_NONE: No oscillator clock selected as PLL3 clock entry + * @arg RCC_PLL3_SOURCE_CSI: CSI oscillator clock selected as PLL3 clock entry + * @arg RCC_PLL3_SOURCE_HSI: HSI oscillator clock selected as PLL3 clock entry + * @arg RCC_PLL3_SOURCE_HSE: HSE oscillator clock selected as PLL3 clock entry + * + */ +#define __HAL_RCC_PLL3_PLLSOURCE_CONFIG(__PLL3SOURCE__) MODIFY_REG(RCC->PLL3CFGR, RCC_PLL3CFGR_PLL3SRC, \ + (__PLL3SOURCE__)) + +/** @brief Macro to get the oscillator used as PLL3 clock source. + * @retval The oscillator used as PLL3 clock source. The returned value can be one + * of the following: + * - RCC_PLL3_SOURCE_NONE: No oscillator is used as PLL3 clock source. + * - RCC_PLL3_SOURCE_CSI: CSI oscillator is used as PLL3 clock source. + * - RCC_PLL3_SOURCE_HSI: HSI oscillator is used as PLL3 clock source. + * - RCC_PLL3_SOURCE_HSE: HSE oscillator is used as PLL3 clock source. + */ +#define __HAL_RCC_GET_PLL3_OSCSOURCE() ((uint32_t)(RCC->PLL3CFGR & RCC_PLL3CFGR_PLL3SRC)) + +/** + * @brief Macro to configures the PLL3 source, multiplication and division factors. + * @note This function must be used only when PLL3 is disabled. + * + * @param __PLL3SOURCE__: specifies the PLL3 entry clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_PLL3_SOURCE_NONE No clock selected as PLL3 clock entry + * @arg @ref RCC_PLL3_SOURCE_CSI CSI oscillator clock selected as PLL3 clock entry + * @arg @ref RCC_PLL3_SOURCE_HSI HSI oscillator clock selected as PLL3 clock entry + * @arg @ref RCC_PLL3_SOURCE_HSE HSE oscillator clock selected as PLL3 clock entry + * + * @param __PLL3M__ specifies the division factor of PLL3 input clock. + * This parameter must be a number between Min_Data = 1 and Max_Data = 63. + * + * @param __PLL3N__: specifies the multiplication factor for PLL3 VCO output clock + * This parameter must be a number between 4 and 512. + * @note You have to set the PLL3N parameter correctly to ensure that the VCO + * output frequency is between 150 and 420 MHz (when in medium VCO range) + * or between 192 and 836 MHZ (when in wide VCO range) + * + * @param __PLL3P__: specifies the division factor for peripheral kernel clocks + * This parameter must be a number between 1 and 128 + * + * @param __PLL3Q__: specifies the division factor for peripheral kernel clocks + * This parameter must be a number between 1 and 128 + * + * @param __PLL3R__: specifies the division factor for peripheral kernel clocks + * This parameter must be a number between 1 and 128 + * + * @retval None + */ +#define __HAL_RCC_PLL3_CONFIG(__PLL3SOURCE__, __PLL3M__, __PLL3N__, __PLL3P__, __PLL3Q__, __PLL3R__) \ + do{\ + MODIFY_REG(RCC->PLL3CFGR, (RCC_PLL3CFGR_PLL3SRC | RCC_PLL3CFGR_PLL3M), \ + ((__PLL3SOURCE__) << RCC_PLL3CFGR_PLL3SRC_Pos) | ((__PLL3M__) << RCC_PLL3CFGR_PLL3M_Pos)); \ + WRITE_REG(RCC->PLL3DIVR , ( (((__PLL3N__) - 1U) & RCC_PLL3DIVR_PLL3N) | \ + ((((__PLL3P__) - 1U) << RCC_PLL3DIVR_PLL3P_Pos) & RCC_PLL3DIVR_PLL3P) | \ + ((((__PLL3Q__) - 1U) << RCC_PLL3DIVR_PLL3Q_Pos) & RCC_PLL3DIVR_PLL3Q) | \ + ((((__PLL3R__) - 1U) << RCC_PLL3DIVR_PLL3R_Pos) & RCC_PLL3DIVR_PLL3R))); \ + } while(0) + +/** + * @brief Macro to configure the PLL3 clock multiplication factor N. + * + * @note This function must be used only when the PLL3 is disabled. + * @note PLL3 clock source is independent from the main PLL and is configured through + * __HAL_RCC_PLL3_CONFIG() macro. + * + * @param __PLL3N__ specifies the multiplication factor for PLL3 VCO output clock. + * This parameter must be a number between 8 and 86. + * @note You have to set the PLL3N parameter correctly to ensure that the VCO + * output frequency is between 192 and 836 MHz (Wide range) or 150 and 420 Mhz (Medium range). + * PLL3 clock frequency = f(PLL3) multiplied by PLL3N + * + * @retval None + */ +#define __HAL_RCC_PLL3_MULN_CONFIG(__PLL3N__) \ + MODIFY_REG(RCC->PLL3DIVR, RCC_PLL3DIVR_N3, ((__PLL3N__) - 1U) << RCC_PLL3DIVR_N3_Pos) + +/** @brief Macro to configure the PLL3 input clock division factor M. + * + * @note This function must be used only when the PLL3 is disabled. + * @note PLL3 clock source is independent from the main PLL and is configured through + * __HAL_RCC_PLL3_CONFIG() macro. + * + * @param __PLL3M__ specifies the division factor for PLL3 clock. + * This parameter must be a number between Min_Data = 1 and Max_Data = 63. + * In order to save power when PLL3 is not used, the value of PLL3M must be set to 0. + * + * @retval None + */ +#define __HAL_RCC_PLL3_DIVM_CONFIG(__PLL3M__) \ + MODIFY_REG(RCC->PLL3CFGR, RCC_PLL3CFGR_DIVM3, (__PLL3M__) << RCC_PLL3CFGR_DIVM3_Pos) + +/** @brief Macro to configure the PLL3 clock division factor P. + * + * @note This function must be used only when the PLL3 is disabled. + * @note PLL3 clock source is independent from the main PLL and is configured through + * __HAL_RCC_PLL3_CONFIG() macro. + * + * @param __PLL3P__ specifies the division factor for PLL3 output P clock. + * This parameter must be a number in the range (1 to 128). + * Use to set PLL3 output P clock frequency = f(PLL3) / PLL3P + * + * @retval None + */ +#define __HAL_RCC_PLL3_DIVP_CONFIG(__PLL3P__) \ + MODIFY_REG(RCC->PLL3DIVR, RCC_PLL3DIVR_P3, ((__PLL3P__) - 1U) << RCC_PLL3DIVR_P3_Pos) + +/** @brief Macro to configure the PLL3 clock division factor Q. + * + * @note This function must be used only when the PLL3 is disabled. + * @note PLL3 clock source is independent from the main PLL and is configured through + * __HAL_RCC_PLL3_CONFIG() macro. + * + * @param __PLL3Q__ specifies the division factor for PLL3 output Q clock. + * This parameter must be a number in the range (1 to 128). + * Use to set PLL3 output Q clock frequency = f(PLL3) / PLL3Q + * + * @retval None + */ +#define __HAL_RCC_PLL3_DIVQ_CONFIG(__PLL3Q__) \ + MODIFY_REG(RCC->PLL3DIVR, RCC_PLL3DIVR_Q3, ((__PLL3Q__) - 1U) << RCC_PLL3DIVR_Q3_Pos) + +/** @brief Macro to configure the PLL3 clock division factor R. + * + * @note This function must be used only when the PLL3 is disabled. + * @note PLL3 clock source is independent from the main PLL and is configured through + * __HAL_RCC_PLL3_CONFIG() macro. + * + * @param __PLL3R__ specifies the division factor for PLL3 output R clock. + * This parameter must be a number in the range (1 to 128). + * Use to set PLL3 output R clock frequency = f(PLL3) / PLL3R + * + * @retval None + */ +#define __HAL_RCC_PLL3_DIVR_CONFIG(__PLL3R__) \ + MODIFY_REG(RCC->PLL3DIVR, RCC_PLL3DIVR_R3, ((__PLL3R__) - 1U) << RCC_PLL3DIVR_R3_Pos) + +/** + * @brief Macro to configures PLL3 clock Fractional Part of The Multiplication Factor + * + * @note These bits can be written at any time, allowing dynamic fine-tuning of the PLL3 VCO + * + * @param __PLL3FRACN__: specifies Fractional Part Of The Multiplication Factor for PLL3 VCO + * It should be a value between 0 and 8191 + * @note Warning: the software has to set correctly these bits to insure that the VCO + * output frequency is between its valid frequency range, which is: + * 192 to 836 MHz if PLL3VCOSEL = 0 + * 150 to 420 MHz if PLL3VCOSEL = 1. + * + * @retval None + */ +#define __HAL_RCC_PLL3_FRACN_CONFIG(__PLL3FRACN__) MODIFY_REG(RCC->PLL3FRACR, RCC_PLL3FRACR_PLL3FRACN, \ + (uint32_t)(__PLL3FRACN__) << RCC_PLL3FRACR_PLL3FRACN_Pos) + +/** @brief Macro to select the PLL3 reference frequency range. + * @param __PLL3VCIRange__: specifies the PLL3 input frequency range + * This parameter can be one of the following values: + * @arg RCC_PLL3_VCIRANGE_0: Range frequency is between 1 and 2 MHz + * @arg RCC_PLL3_VCIRANGE_1: Range frequency is between 2 and 4 MHz + * @arg RCC_PLL3_VCIRANGE_2: Range frequency is between 4 and 8 MHz + * @arg RCC_PLL3_VCIRANGE_3: Range frequency is between 8 and 16 MHz + * + * @retval None + */ +#define __HAL_RCC_PLL3_VCIRANGE(__PLL3VCIRange__) \ + MODIFY_REG(RCC->PLL3CFGR, RCC_PLL3CFGR_PLL3RGE, (__PLL3VCIRange__)) + +/** @brief Macro to select the PLL3 reference frequency range. + * @param __RCC_PLL3VCORange__: specifies the PLL3 input frequency range + * This parameter can be one of the following values: + * @arg RCC_PLL3VCOWIDE: Range frequency is between 192 and 836 MHz + * @arg RCC_PLL3VCOMEDIUM: Range frequency is between 150 and 420 MHz + * + * @retval None + */ +#define __HAL_RCC_PLL3_VCORANGE(__RCC_PLL3VCORange__) \ + MODIFY_REG(RCC->PLL3CFGR, RCC_PLL3CFGR_PLL3VCOSEL, (__RCC_PLL3VCORange__)) + +/** + * @brief Macros to enable or disable the PLL3. + * @note The PLL3 is disabled by hardware when entering STOP and STANDBY modes. + * @retval None + */ + +/** @brief Macros to enable or disable the main PLL3. + * @note After enabling PLL3, the application software should wait on + * PLL3RDY flag to be set indicating that PLL3 clock is stable and can + * be used as kernel clock source. + * @note PLL3 is disabled by hardware when entering STOP and STANDBY modes. + */ +#define __HAL_RCC_PLL3_ENABLE() SET_BIT(RCC->CR, RCC_CR_PLL3ON) +#define __HAL_RCC_PLL3_DISABLE() CLEAR_BIT(RCC->CR, RCC_CR_PLL3ON) + +/** + * @brief Enables or disables Fractional Part Of The Multiplication Factor of PLL3 VCO + * @note Enabling/disabling Fractional Part can be done at any time without the need to stop the PLL3 + * @retval None + */ +#define __HAL_RCC_PLL3_FRACN_ENABLE() SET_BIT(RCC->PLL3CFGR, RCC_PLL3CFGR_PLL3FRACEN) +#define __HAL_RCC_PLL3_FRACN_DISABLE() CLEAR_BIT(RCC->PLL3CFGR, RCC_PLL3CFGR_PLL3FRACEN) + +/** + * @brief Enables or disables each clock output (PLL3_P_CLK, PLL3_Q_CLK, PLL3_R_CLK) + * @note Enabling/disabling Those Clocks can be any time without the need to stop the PLL3, + * This is mainly used to save Power. + * @param __PLL3_CLOCKOUT__: specifies the PLL3 clock to be outputted + * This parameter can be one of the following values: + * @arg RCC_PLL3_DIVP: This clock is used to generate an accurate clock to achieve + * high-quality audio performance on SAI and SPI/I2S interfaces. + * @arg RCC_PLL3_DIVQ: This clock is used to generate kernel clock for SPI, LPUART, UART/USART + * and USB peripherals. + * @arg RCC_PLL3_DIVR: This clock is used to generate kernel clock for I2C, I3C and LPTIM peripherals. + * + * @retval None + */ +#define __HAL_RCC_PLL3_CLKOUT_ENABLE(__PLL3_CLOCKOUT__) SET_BIT(RCC->PLL3CFGR, (__PLL3_CLOCKOUT__)) +#define __HAL_RCC_PLL3_CLKOUT_DISABLE(__PLL3_CLOCKOUT__) CLEAR_BIT(RCC->PLL3CFGR, (__PLL3_CLOCKOUT__)) + +/** + * @brief Macro to get clock output enable status (PLL3_SAI2). + * @param __PLL3_CLOCKOUT__ specifies the PLL3 clock to be output. + * This parameter can be one or a combination of the following values: + * @arg RCC_PLL3_DIVP: This clock is used to generate an accurate clock to achieve + * high-quality audio performance on SAI and SPI/I2S interfaces. + * @arg RCC_PLL3_DIVQ: This clock is used to generate kernel clock for SPI, LPUART, UART/USART + * and USB peripherals. + * @arg RCC_PLL3_DIVR: This clock is used to generate kernel clock for I2C, I3C and LPTIM peripherals. + * + * @retval SET / RESET + */ +#define __HAL_RCC_GET_PLL3_CLKOUT_CONFIG(__PLL3_CLOCKOUT__) READ_BIT(RCC->PLL3CFGR, (__PLL3_CLOCKOUT__)) +#endif /* RCC_CR_PLL3ON */ + +/** @brief Macro to configure the ADC and DAC kernel clock source. + * @param __ADCDAC_CLKSOURCE__ specifies the ADC and DAC kernel clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_ADCDACCLKSOURCE_HCLK AHB bus clock selected as ADC and DAC kernel clock + * @arg @ref RCC_ADCDACCLKSOURCE_SYSCLK System clock selected as ADC and DAC kernel clock + * @arg @ref RCC_ADCDACCLKSOURCE_PLL2R PLL2R clock selected as ADC and DAC kernel clock + * @arg @ref RCC_ADCDACCLKSOURCE_HSE HSE clock selected as ADC and DAC kernel clock + * @arg @ref RCC_ADCDACCLKSOURCE_HSI HSI clock selected as ADC and DAC kernel clock + * @arg @ref RCC_ADCDACCLKSOURCE_CSI CSI clock selected as ADC and DAC kernel clock + * @retval None + */ +#define __HAL_RCC_ADCDAC_CONFIG(__ADCDAC_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR5, RCC_CCIPR5_ADCDACSEL, (uint32_t)(__ADCDAC_CLKSOURCE__)) + +/** @brief Macro to get the ADC and DAC kernel clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_ADCDACCLKSOURCE_HCLK AHB Bus clock used as ADC and DAC kernel clock + * @arg @ref RCC_ADCDACCLKSOURCE_SYSCLK System clock used as ADC and DAC kernel clock + * @arg @ref RCC_ADCDACCLKSOURCE_PLL2R PLL2R clock used as ADC and DAC kernel clock + * @arg @ref RCC_ADCDACCLKSOURCE_HSE HSE oscillator used as ADC and DAC kernel clock + * @arg @ref RCC_ADCDACCLKSOURCE_HSI HSI oscillator used as ADC and DAC kernel clock + * @arg @ref RCC_ADCDACCLKSOURCE_CSI CSI oscillator used as ADC and DAC kernel clock + */ +#define __HAL_RCC_GET_ADCDAC_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR5, RCC_CCIPR5_ADCDACSEL))) + +/** @brief Macro to configure the DAC kernel clock source in low-power mode. + * @param __DACLPCLKSOURCE__ specifies the DAC kernel clock source in low-power mode. + * This parameter can be one of the following values: + * @arg @ref RCC_DACLPCLKSOURCE_LSE LSE oscillator selected as DAC kernel clock in low-power mode + * @arg @ref RCC_DACLPCLKSOURCE_LSI LSI oscillator selected as DAC kernel clock in low-power mode + * @retval None + */ +#define __HAL_RCC_DAC_LP_CONFIG(__DACLPCLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR5, RCC_CCIPR5_DACSEL, (uint32_t)(__DACLPCLKSOURCE__)) + +/** @brief Macro to get the DAC kernel clock source in low-power mode. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_DACLPCLKSOURCE_LSE LSE oscillator used as DAC kernel clock in low-power mode + * @arg @ref RCC_DACLPCLKSOURCE_LSI LSI oscillator used as DAC kernel clock in low-power mode + */ +#define __HAL_RCC_GET_DAC_LP_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR5, RCC_CCIPR5_DACSEL))) + +/** @brief Macro to configure the FDCAN kernel clock (FDCANCLK). + * + * @param __FDCAN_CLKSOURCE__ specifies the FDCAN kernel clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_FDCANCLKSOURCE_HSE HSE oscillator selected as FDCAN kernel clock + * @arg @ref RCC_FDCANCLKSOURCE_PLL1Q PLL1Q Clock selected as FDCAN kernel clock + * @arg @ref RCC_FDCANCLKSOURCE_PLL2Q PLL2Q Clock selected as FDCAN kernel clock + * @retval None + */ +#define __HAL_RCC_FDCAN_CONFIG(__FDCAN_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR5, RCC_CCIPR5_FDCANSEL, (uint32_t)(__FDCAN_CLKSOURCE__)) + +/** @brief Macro to get the FDCAN clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_FDCANCLKSOURCE_HSE HSE oscillator selected as FDCAN kernel clock + * @arg @ref RCC_FDCANCLKSOURCE_PLL1Q PLL1Q Clock selected as FDCAN kernel clock + * @arg @ref RCC_FDCANCLKSOURCE_PLL2Q PLL2Q Clock selected as FDCAN kernel clock + */ +#define __HAL_RCC_GET_FDCAN_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR5, RCC_CCIPR5_FDCANSEL))) + +/** @brief Macro to configure the LPTIM1 clock (LPTIM1CLK). + * + * @param __LPTIM1_CLKSOURCE__ specifies the LPTIM1 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_LPTIM1CLKSOURCE_PCLK3 PCLK3 selected as LPTIM1 clock + * @arg @ref RCC_LPTIM1CLKSOURCE_PLL2P PLL2P selected as LPTIM1 clock + * @arg @ref RCC_LPTIM1CLKSOURCE_PLL3R PLL3R selected as LPTIM1 clock (*) + * @arg @ref RCC_LPTIM1CLKSOURCE_LSE LSE selected as LPTIM1 clock + * @arg @ref RCC_LPTIM1CLKSOURCE_LSI LSI selected as LPTIM1 clock + * @arg @ref RCC_LPTIM1CLKSOURCE_CLKP CLKP selected as LPTIM1 clock + * @retval None + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + */ +#define __HAL_RCC_LPTIM1_CONFIG(__LPTIM1_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR2, RCC_CCIPR2_LPTIM1SEL, (uint32_t)(__LPTIM1_CLKSOURCE__)) + +/** @brief Macro to get the LPTIM1 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_LPTIM1CLKSOURCE_PCLK3 PCLK3 selected as LPTIM1 clock + * @arg @ref RCC_LPTIM1CLKSOURCE_PLL2P PLL2P selected as LPTIM1 clock + * @arg @ref RCC_LPTIM1CLKSOURCE_PLL3R PLL3R selected as LPTIM1 clock (*) + * @arg @ref RCC_LPTIM1CLKSOURCE_LSE LSE selected as LPTIM1 clock + * @arg @ref RCC_LPTIM1CLKSOURCE_LSI LSI selected as LPTIM1 clock + * @arg @ref RCC_LPTIM1CLKSOURCE_CLKP CLKP selected as LPTIM1 clock + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + */ +#define __HAL_RCC_GET_LPTIM1_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR2, RCC_CCIPR2_LPTIM1SEL))) + +/** @brief Macro to configure the LPTIM2 clock (LPTIM2CLK). + * + * @param __LPTIM2_CLKSOURCE__ specifies the LPTIM2 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_LPTIM2CLKSOURCE_PCLK1 PCLK1 selected as LPTIM2 clock + * @arg @ref RCC_LPTIM2CLKSOURCE_PLL2P PLL2P selected as LPTIM2 clock + * @arg @ref RCC_LPTIM2CLKSOURCE_PLL3R PLL3R selected as LPTIM2 clock (*) + * @arg @ref RCC_LPTIM2CLKSOURCE_LSE LSE selected as LPTIM2 clock + * @arg @ref RCC_LPTIM2CLKSOURCE_LSI LSI selected as LPTIM2 clock + * @arg @ref RCC_LPTIM2CLKSOURCE_CLKP CLKP selected as LPTIM2 clock + * @retval None + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + */ +#define __HAL_RCC_LPTIM2_CONFIG(__LPTIM2_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR2, RCC_CCIPR2_LPTIM2SEL, (uint32_t)(__LPTIM2_CLKSOURCE__)) + +/** @brief Macro to get the LPTIM2 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_LPTIM2CLKSOURCE_PCLK1 PCLK1 selected as LPTIM2 clock + * @arg @ref RCC_LPTIM2CLKSOURCE_PLL2P PLL2P selected as LPTIM2 clock + * @arg @ref RCC_LPTIM2CLKSOURCE_PLL3R PLL3R selected as LPTIM2 clock (*) + * @arg @ref RCC_LPTIM2CLKSOURCE_LSE LSE selected as LPTIM2 clock + * @arg @ref RCC_LPTIM2CLKSOURCE_LSI LSI selected as LPTIM2 clock + * @arg @ref RCC_LPTIM2CLKSOURCE_CLKP CLKP selected as LPTIM2 clock + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + */ +#define __HAL_RCC_GET_LPTIM2_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR2, RCC_CCIPR2_LPTIM2SEL))) + +#if defined(LPTIM3) +/** @brief Macro to configure the LPTIM3 clock (LPTIM3CLK). + * + * @param __LPTIM3_CLKSOURCE__ specifies the LPTIM3 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_LPTIM3CLKSOURCE_PCLK3 PCLK3 selected as LPTIM3 clock + * @arg @ref RCC_LPTIM3CLKSOURCE_PLL2P PLL2P selected as LPTIM3 clock + * @arg @ref RCC_LPTIM3CLKSOURCE_PLL3R PLL3R selected as LPTIM3 clock + * @arg @ref RCC_LPTIM3CLKSOURCE_LSE LSE selected as LPTIM3 clock + * @arg @ref RCC_LPTIM3CLKSOURCE_LSI LSI selected as LPTIM3 clock + * @arg @ref RCC_LPTIM3CLKSOURCE_CLKP CLKP selected as LPTIM3 clock + * @retval None + */ +#define __HAL_RCC_LPTIM3_CONFIG(__LPTIM3_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR2, RCC_CCIPR2_LPTIM3SEL, (uint32_t)(__LPTIM3_CLKSOURCE__)) + +/** @brief Macro to get the LPTIM3 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_LPTIM3CLKSOURCE_PCLK3 PCLK3 selected as LPTIM3 clock + * @arg @ref RCC_LPTIM3CLKSOURCE_PLL2P PLL2P selected as LPTIM3 clock + * @arg @ref RCC_LPTIM3CLKSOURCE_PLL3R PLL3R selected as LPTIM3 clock + * @arg @ref RCC_LPTIM3CLKSOURCE_LSE LSE selected as LPTIM3 clock + * @arg @ref RCC_LPTIM3CLKSOURCE_LSI LSI selected as LPTIM3 clock + * @arg @ref RCC_LPTIM3CLKSOURCE_CLKP CLKP selected as LPTIM3 clock + */ +#define __HAL_RCC_GET_LPTIM3_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR2, RCC_CCIPR2_LPTIM3SEL))) +#endif /* LPTIM3 */ + +#if defined(LPTIM4) +/** @brief Macro to configure the LPTIM4 clock (LPTIM4CLK). + * + * @param __LPTIM4_CLKSOURCE__ specifies the LPTIM4 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_LPTIM4CLKSOURCE_PCLK3 PCLK3 selected as LPTIM4 clock + * @arg @ref RCC_LPTIM4CLKSOURCE_PLL2P PLL2P selected as LPTIM4 clock + * @arg @ref RCC_LPTIM4CLKSOURCE_PLL3R PLL3R selected as LPTIM4 clock + * @arg @ref RCC_LPTIM4CLKSOURCE_LSE LSE selected as LPTIM4 clock + * @arg @ref RCC_LPTIM4CLKSOURCE_LSI LSI selected as LPTIM4 clock + * @arg @ref RCC_LPTIM4CLKSOURCE_CLKP CLKP selected as LPTIM4 clock + * @retval None + */ +#define __HAL_RCC_LPTIM4_CONFIG(__LPTIM4_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR2, RCC_CCIPR2_LPTIM4SEL, (uint32_t)(__LPTIM4_CLKSOURCE__)) + +/** @brief Macro to get the LPTIM4 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_LPTIM4CLKSOURCE_PCLK3 PCLK3 selected as LPTIM4 clock + * @arg @ref RCC_LPTIM4CLKSOURCE_PLL2P PLL2P selected as LPTIM4 clock + * @arg @ref RCC_LPTIM4CLKSOURCE_PLL3R PLL3R selected as LPTIM4 clock + * @arg @ref RCC_LPTIM4CLKSOURCE_LSE LSE selected as LPTIM4 clock + * @arg @ref RCC_LPTIM4CLKSOURCE_LSI LSI selected as LPTIM4 clock + * @arg @ref RCC_LPTIM4CLKSOURCE_CLKP CLKP selected as LPTIM4 clock + */ +#define __HAL_RCC_GET_LPTIM4_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR2, RCC_CCIPR2_LPTIM4SEL))) +#endif /* LPTIM4 */ + +#if defined(LPTIM5) +/** @brief Macro to configure the LPTIM5 clock (LPTIM5CLK). + * + * @param __LPTIM5_CLKSOURCE__ specifies the LPTIM5 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_LPTIM5CLKSOURCE_PCLK3 PCLK3 selected as LPTIM5 clock + * @arg @ref RCC_LPTIM5CLKSOURCE_PLL2P PLL2P selected as LPTIM5 clock + * @arg @ref RCC_LPTIM5CLKSOURCE_PLL3R PLL3R selected as LPTIM5 clock + * @arg @ref RCC_LPTIM5CLKSOURCE_LSE LSE selected as LPTIM5 clock + * @arg @ref RCC_LPTIM5CLKSOURCE_LSI LSI selected as LPTIM5 clock + * @arg @ref RCC_LPTIM5CLKSOURCE_CLKP CLKP selected as LPTIM5 clock + * @retval None + */ +#define __HAL_RCC_LPTIM5_CONFIG(__LPTIM5_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR2, RCC_CCIPR2_LPTIM5SEL, (uint32_t)(__LPTIM5_CLKSOURCE__)) + +/** @brief Macro to get the LPTIM5 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_LPTIM5CLKSOURCE_PCLK3 PCLK3 selected as LPTIM5 clock + * @arg @ref RCC_LPTIM5CLKSOURCE_PLL2P PLL2P selected as LPTIM5 clock + * @arg @ref RCC_LPTIM5CLKSOURCE_PLL3R PLL3R selected as LPTIM5 clock + * @arg @ref RCC_LPTIM5CLKSOURCE_LSE LSE selected as LPTIM5 clock + * @arg @ref RCC_LPTIM5CLKSOURCE_LSI LSI selected as LPTIM5 clock + * @arg @ref RCC_LPTIM5CLKSOURCE_CLKP CLKP selected as LPTIM5 clock + */ +#define __HAL_RCC_GET_LPTIM5_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR2, RCC_CCIPR2_LPTIM5SEL))) +#endif /* LPTIM5 */ + +#if defined(LPTIM6) +/** @brief Macro to configure the LPTIM6 clock (LPTIM6CLK). + * + * @param __LPTIM6_CLKSOURCE__ specifies the LPTIM6 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_LPTIM6CLKSOURCE_PCLK3 PCLK3 selected as LPTIM6 clock + * @arg @ref RCC_LPTIM6CLKSOURCE_PLL2P PLL2P selected as LPTIM6 clock + * @arg @ref RCC_LPTIM6CLKSOURCE_PLL3R PLL3R selected as LPTIM6 clock + * @arg @ref RCC_LPTIM6CLKSOURCE_LSE LSE selected as LPTIM6 clock + * @arg @ref RCC_LPTIM6CLKSOURCE_LSI LSI selected as LPTIM6 clock + * @arg @ref RCC_LPTIM6CLKSOURCE_CLKP CLKP selected as LPTIM6 clock + * @retval None + */ +#define __HAL_RCC_LPTIM6_CONFIG(__LPTIM6_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR2, RCC_CCIPR2_LPTIM6SEL, (uint32_t)(__LPTIM6_CLKSOURCE__)) + +/** @brief Macro to get the LPTIM6 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_LPTIM6CLKSOURCE_PCLK3 PCLK3 selected as LPTIM6 clock + * @arg @ref RCC_LPTIM6CLKSOURCE_PLL2P PLL2P selected as LPTIM6 clock + * @arg @ref RCC_LPTIM6CLKSOURCE_PLL3R PLL3R selected as LPTIM6 clock + * @arg @ref RCC_LPTIM6CLKSOURCE_LSE LSE selected as LPTIM6 clock + * @arg @ref RCC_LPTIM6CLKSOURCE_LSI LSI selected as LPTIM6 clock + * @arg @ref RCC_LPTIM6CLKSOURCE_CLKP CLKP selected as LPTIM6 clock + */ +#define __HAL_RCC_GET_LPTIM6_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR2, RCC_CCIPR2_LPTIM6SEL))) +#endif /* LPTIM6 */ + +/** @brief macro to configure the SPI1 clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_SPI1CLKSOURCE_PLL1Q PLL1Q selected as SPI1 clock + * @arg RCC_SPI1CLKSOURCE_PLL2P PLL2P selected as SPI1 clock + * @arg RCC_SPI1CLKSOURCE_PLL3P PLL3P selected as SPI1 clock (*) + * @arg RCC_SPI1CLKSOURCE_PIN External Clock selected as SPI1 clock + * @arg RCC_SPI1CLKSOURCE_CLKP CLKP selected as SPI1 clock + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + */ +#define __HAL_RCC_SPI1_CONFIG(__SPI1CLKSource__) \ + MODIFY_REG(RCC->CCIPR3, RCC_CCIPR3_SPI1SEL, (uint32_t)(__SPI1CLKSource__)) + +/** @brief macro to get the SPI1 clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_SPI1CLKSOURCE_PLL1Q PLL1Q selected as SPI1 clock + * @arg RCC_SPI1CLKSOURCE_PLL2P PLL2P selected as SPI1 clock + * @arg RCC_SPI1CLKSOURCE_PLL3P PLL3P selected as SPI1 clock (*) + * @arg RCC_SPI1CLKSOURCE_PIN External Clock selected as SPI1 clock + * @arg RCC_SPI1CLKSOURCE_CLKP CLKP selected as SPI1 clock + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + */ +#define __HAL_RCC_GET_SPI1_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR3, RCC_CCIPR3_SPI1SEL))) + +/** @brief macro to configure the SPI2 clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_SPI2CLKSOURCE_PLL1Q PLL1Q selected as SPI2 clock + * @arg RCC_SPI2CLKSOURCE_PLL2P PLL2P selected as SPI2 clock + * @arg RCC_SPI2CLKSOURCE_PLL3P PLL3P selected as SPI2 clock (*) + * @arg RCC_SPI2CLKSOURCE_PIN External Clock selected as SPI2 clock + * @arg RCC_SPI2CLKSOURCE_CLKP CLKP selected as SPI2 clock + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + */ +#define __HAL_RCC_SPI2_CONFIG(__SPI2CLKSource__) \ + MODIFY_REG(RCC->CCIPR3, RCC_CCIPR3_SPI2SEL, (uint32_t)(__SPI2CLKSource__)) + +/** @brief macro to get the SPI2 clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_SPI2CLKSOURCE_PLL1Q PLL1Q selected as SPI2 clock + * @arg RCC_SPI2CLKSOURCE_PLL2P PLL2P selected as SPI2 clock + * @arg RCC_SPI2CLKSOURCE_PLL3P PLL3P selected as SPI2 clock (*) + * @arg RCC_SPI2CLKSOURCE_PIN External Clock selected as SPI2 clock + * @arg RCC_SPI2CLKSOURCE_CLKP CLKP selected as SPI2 clock + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + */ +#define __HAL_RCC_GET_SPI2_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR3, RCC_CCIPR3_SPI2SEL))) + +/** @brief macro to configure the SPI3 clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_SPI3CLKSOURCE_PLL1Q PLL1Q used as SPI3 clock + * @arg RCC_SPI3CLKSOURCE_PLL2P PLL2P used as SPI3 clock + * @arg RCC_SPI3CLKSOURCE_PLL3P PLL3P used as SPI3 clock (*) + * @arg RCC_SPI3CLKSOURCE_PIN External Clock used as SPI3 clock + * @arg RCC_SPI3CLKSOURCE_CLKP CLKP used as SPI3 clock + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + */ +#define __HAL_RCC_SPI3_CONFIG(__SPI3CLKSource__) \ + MODIFY_REG(RCC->CCIPR3, RCC_CCIPR3_SPI3SEL, (uint32_t)(__SPI3CLKSource__)) + +/** @brief macro to get the SPI3 clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_SPI3CLKSOURCE_PLL1Q PLL1Q used as SPI3 clock + * @arg RCC_SPI3CLKSOURCE_PLL2P PLL2P used as SPI3 clock + * @arg RCC_SPI3CLKSOURCE_PLL3P PLL3P used as SPI3 clock (*) + * @arg RCC_SPI3CLKSOURCE_PIN External Clock used as SPI3 clock + * @arg RCC_SPI3CLKSOURCE_CLKP CLKP used as SPI3 clock + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + */ +#define __HAL_RCC_GET_SPI3_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR3, RCC_CCIPR3_SPI3SEL))) + +#if defined(SPI4) +/** @brief macro to configure the SPI4 clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_SPI4CLKSOURCE_PCLK2 PCLK2 used as SPI4 clock + * @arg RCC_SPI4CLKSOURCE_PLL2Q PLL2Q used as SPI4 clock + * @arg RCC_SPI4CLKSOURCE_PLL3Q PLL3Q used as SPI4 clock + * @arg RCC_SPI4CLKSOURCE_HSI HSI used as SPI4 clock + * @arg RCC_SPI4CLKSOURCE_CSI CSI Clock used as SPI4 clock + * @arg RCC_SPI4CLKSOURCE_HSE HSE Clock used as SPI4 clock + */ +#define __HAL_RCC_SPI4_CONFIG(__SPI4CLKSource__) \ + MODIFY_REG(RCC->CCIPR3, RCC_CCIPR3_SPI4SEL, (uint32_t)(__SPI4CLKSource__)) + +/** @brief macro to get the SPI4 clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_SPI4CLKSOURCE_PCLK2 PCLK2 used as SPI4 clock + * @arg RCC_SPI4CLKSOURCE_PLL2Q PLL2Q used as SPI4 clock + * @arg RCC_SPI4CLKSOURCE_PLL3Q PLL3Q used as SPI4 clock + * @arg RCC_SPI4CLKSOURCE_HSI HSI used as SPI4 clock + * @arg RCC_SPI4CLKSOURCE_CSI CSI used as SPI4 clock + * @arg RCC_SPI4CLKSOURCE_HSE HSE used as SPI4 clock + */ +#define __HAL_RCC_GET_SPI4_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR3, RCC_CCIPR3_SPI4SEL))) +#endif /* SPI4 */ + +#if defined(SPI5) +/** @brief macro to configure the SPI5 clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_SPI5CLKSOURCE_PCLK3 PCLK3 used as SPI5 clock + * @arg RCC_SPI5CLKSOURCE_PLL2Q PLL2Q used as SPI5 clock + * @arg RCC_SPI5CLKSOURCE_PLL3Q PLL3Q used as SPI5 clock + * @arg RCC_SPI5CLKSOURCE_HSI HSI used as SPI5 clock + * @arg RCC_SPI5CLKSOURCE_CSI CSI Clock used as SPI5 clock + * @arg RCC_SPI5CLKSOURCE_HSE HSE Clock used as SPI5 clock + */ +#define __HAL_RCC_SPI5_CONFIG(__SPI5CLKSource__) \ + MODIFY_REG(RCC->CCIPR3, RCC_CCIPR3_SPI5SEL, (uint32_t)(__SPI5CLKSource__)) + +/** @brief macro to get the SPI5 clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_SPI5CLKSOURCE_PCLK3 PCLK3 used as SPI5 clock + * @arg RCC_SPI5CLKSOURCE_PLL2Q PLL2Q used as SPI5 clock + * @arg RCC_SPI5CLKSOURCE_PLL3Q PLL3Q used as SPI5 clock + * @arg RCC_SPI5CLKSOURCE_HSI HSI used as SPI5 clock + * @arg RCC_SPI5CLKSOURCE_CSI CSI used as SPI5 clock + * @arg RCC_SPI5CLKSOURCE_HSE HSE used as SPI5 clock + */ +#define __HAL_RCC_GET_SPI5_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR3, RCC_CCIPR3_SPI5SEL))) +#endif /* SPI5 */ + +#if defined(SPI6) +/** @brief macro to configure the SPI6 clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_SPI6CLKSOURCE_PCLK2 PCLK2 used as SPI6 clock + * @arg RCC_SPI6CLKSOURCE_PLL2Q PLL2Q used as SPI6 clock + * @arg RCC_SPI6CLKSOURCE_PLL3Q PLL3Q used as SPI6 clock + * @arg RCC_SPI6CLKSOURCE_HSI HSI used as SPI6 clock + * @arg RCC_SPI6CLKSOURCE_CSI CSI used as SPI6 clock + * @arg RCC_SPI6CLKSOURCE_HSE HSE used as SPI6 clock + */ +#define __HAL_RCC_SPI6_CONFIG(__SPI6CLKSource__) \ + MODIFY_REG(RCC->CCIPR3, RCC_CCIPR3_SPI6SEL, (uint32_t)(__SPI6CLKSource__)) + +/** @brief macro to get the SPI6 clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_SPI6CLKSOURCE_PCLK2 PCLK2 used as SPI6 clock + * @arg RCC_SPI6CLKSOURCE_PLL2Q PLL2Q used as SPI6 clock + * @arg RCC_SPI6CLKSOURCE_PLL3Q PLL3Q used as SPI6 clock + * @arg RCC_SPI6CLKSOURCE_HSI HSI used as SPI6 clock + * @arg RCC_SPI6CLKSOURCE_CSI CSI used as SPI6 clock + * @arg RCC_SPI6CLKSOURCE_HSE HSE used as SPI6 clock + */ +#define __HAL_RCC_GET_SPI6_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR3, RCC_CCIPR3_SPI6SEL))) +#endif /* SPI6 */ + +/** @brief Macro to configure the I2C1 clock (I2C1CLK). + * + * @param __I2C1_CLKSOURCE__ specifies the I2C1 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_I2C1CLKSOURCE_PCLK1 PCLK1 selected as I2C1 clock + * @arg @ref RCC_I2C1CLKSOURCE_PLL3R PLL3R selected as I2C1 clock (*) + * @arg @ref RCC_I2C1CLKSOURCE_PLL2R PLL2R selected as I2C1 clock (**) + * @arg @ref RCC_I2C1CLKSOURCE_HSI HSI selected as I2C1 clock + * @arg @ref RCC_I2C1CLKSOURCE_CSI CSI selected as I2C1 clock + * @retval None + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + * (**) : For stm32h503xx family line. + */ +#define __HAL_RCC_I2C1_CONFIG(__I2C1_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR4, RCC_CCIPR4_I2C1SEL, (uint32_t)(__I2C1_CLKSOURCE__)) + +/** @brief Macro to get the I2C1 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_I2C1CLKSOURCE_PCLK1 PCLK1 selected as I2C1 clock + * @arg @ref RCC_I2C1CLKSOURCE_PLL3R PLL3R selected as I2C1 clock (*) + * @arg @ref RCC_I2C1CLKSOURCE_PLL2R PLL2R selected as I2C1 clock (**) + * @arg @ref RCC_I2C1CLKSOURCE_HSI HSI selected as I2C1 clock + * @arg @ref RCC_I2C1CLKSOURCE_CSI CSI selected as I2C1 clock + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + * (**) : For stm32h503xx family line. + */ +#define __HAL_RCC_GET_I2C1_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR4, RCC_CCIPR4_I2C1SEL))) + +/** @brief Macro to configure the I2C2 clock (I2C2CLK). + * + * @param __I2C2_CLKSOURCE__ specifies the I2C2 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_I2C2CLKSOURCE_PCLK1 PCLK1 selected as I2C2 clock + * @arg @ref RCC_I2C2CLKSOURCE_PLL3R PLL3R selected as I2C2 clock (*) + * @arg @ref RCC_I2C2CLKSOURCE_PLL2R PLL2R selected as I2C2 clock (**) + * @arg @ref RCC_I2C2CLKSOURCE_HSI HSI selected as I2C2 clock + * @arg @ref RCC_I2C2CLKSOURCE_CSI CSI selected as I2C2 clock + * @retval None + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + * (**) : For stm32h503xx family line. + */ +#define __HAL_RCC_I2C2_CONFIG(__I2C2_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR4, RCC_CCIPR4_I2C2SEL, (uint32_t)(__I2C2_CLKSOURCE__)) + +/** @brief Macro to get the I2C2 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_I2C2CLKSOURCE_PCLK1 PCLK1 selected as I2C2 clock + * @arg @ref RCC_I2C2CLKSOURCE_PLL3R PLL3R selected as I2C2 clock (*) + * @arg @ref RCC_I2C2CLKSOURCE_PLL2R PLL2R selected as I2C2 clock (**) + * @arg @ref RCC_I2C2CLKSOURCE_HSI HSI selected as I2C2 clock + * @arg @ref RCC_I2C2CLKSOURCE_CSI CSI selected as I2C2 clock + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + * (**) : For stm32h503xx family line. + */ +#define __HAL_RCC_GET_I2C2_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR4, RCC_CCIPR4_I2C2SEL))) + +#if defined(I2C3) +/** @brief Macro to configure the I2C3 clock (I2C3CLK). + * + * @param __I2C3_CLKSOURCE__ specifies the I2C3 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_I2C3CLKSOURCE_PCLK3 PCLK3 selected as I2C3 clock + * @arg @ref RCC_I2C3CLKSOURCE_PLL3R PLL3R selected as I2C3 clock + * @arg @ref RCC_I2C3CLKSOURCE_HSI HSI selected as I2C3 clock + * @arg @ref RCC_I2C3CLKSOURCE_CSI CSI selected as I2C3 clock + * @retval None + */ +#define __HAL_RCC_I2C3_CONFIG(__I2C3_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR4, RCC_CCIPR4_I2C3SEL, (uint32_t)(__I2C3_CLKSOURCE__)) + +/** @brief Macro to get the I2C3 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_I2C3CLKSOURCE_PCLK3 PCLK3 selected as I2C3 clock + * @arg @ref RCC_I2C3CLKSOURCE_PLL3R PLL3R selected as I2C3 clock + * @arg @ref RCC_I2C3CLKSOURCE_HSI HSI selected as I2C3 clock + * @arg @ref RCC_I2C3CLKSOURCE_CSI CSI selected as I2C3 clock + */ +#define __HAL_RCC_GET_I2C3_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR4, RCC_CCIPR4_I2C3SEL))) +#endif /* I2C3 */ + +#if defined(I2C4) +/** @brief Macro to configure the I2C4 clock (I2C4CLK). + * + * @param __I2C4_CLKSOURCE__ specifies the I2C4 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_I2C4CLKSOURCE_PCLK3 PCLK3 selected as I2C4 clock + * @arg @ref RCC_I2C4CLKSOURCE_PLL3R PLL3R selected as I2C4 clock + * @arg @ref RCC_I2C4CLKSOURCE_HSI HSI selected as I2C4 clock + * @arg @ref RCC_I2C4CLKSOURCE_CSI CSI selected as I2C4 clock + * @retval None + */ +#define __HAL_RCC_I2C4_CONFIG(__I2C4_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR4, RCC_CCIPR4_I2C4SEL, (uint32_t)(__I2C4_CLKSOURCE__)) + +/** @brief Macro to get the I2C4 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_I2C4CLKSOURCE_PCLK3 PCLK3 selected as I2C4 clock + * @arg @ref RCC_I2C4CLKSOURCE_PLL3R PLL3R selected as I2C4 clock + * @arg @ref RCC_I2C4CLKSOURCE_HSI HSI selected as I2C4 clock + * @arg @ref RCC_I2C4CLKSOURCE_CSI CSI selected as I2C4 clock + */ +#define __HAL_RCC_GET_I2C4_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR4, RCC_CCIPR4_I2C4SEL))) +#endif /* I2C4 */ + +/** @brief Macro to configure the I3C1 clock (I3C1CLK). + * + * @param __I3C1_CLKSOURCE__ specifies the I3C1 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_I3C1CLKSOURCE_PCLK1 PCLK1 selected as I3C1 clock + * @arg @ref RCC_I3C1CLKSOURCE_PLL3R PLL3R selected as I3C1 clock (*) + * @arg @ref RCC_I3C1CLKSOURCE_PLL2R PLL2R selected as I3C1 clock (**) + * @arg @ref RCC_I3C1CLKSOURCE_HSI HSI selected as I3C1 clock + * @retval None + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + * (**) : For stm32h503xx family line. + */ +#define __HAL_RCC_I3C1_CONFIG(__I3C1_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR4, RCC_CCIPR4_I3C1SEL, (uint32_t)(__I3C1_CLKSOURCE__)) + +/** @brief Macro to get the I3C1 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_I3C1CLKSOURCE_PCLK1 PCLK1 selected as I3C1 clock + * @arg @ref RCC_I3C1CLKSOURCE_PLL3R PLL3R selected as I3C1 clock (*) + * @arg @ref RCC_I3C1CLKSOURCE_PLL2R PLL2R selected as I3C1 clock (**) + * @arg @ref RCC_I3C1CLKSOURCE_HSI HSI selected as I3C1 clock + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + * (**) : For stm32h503xx family line. + */ +#define __HAL_RCC_GET_I3C1_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR4, RCC_CCIPR4_I3C1SEL))) + +#if defined(I3C2) +/** @brief Macro to configure the I3C2 clock (I3C2CLK). + * + * @param __I3C2_CLKSOURCE__ specifies the I3C2 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_I3C2CLKSOURCE_PCLK3 PCLK3 selected as I3C2 clock + * @arg @ref RCC_I3C2CLKSOURCE_PLL2R PLL2R selected as I3C2 clock + * @arg @ref RCC_I3C2CLKSOURCE_HSI HSI selected as I3C2 clock + * @retval None + */ +#define __HAL_RCC_I3C2_CONFIG(__I3C2_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR4, RCC_CCIPR4_I3C2SEL, (uint32_t)(__I3C2_CLKSOURCE__)) + +/** @brief Macro to get the I3C2 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_I3C2CLKSOURCE_PCLK3 PCLK3 selected as I3C2 clock + * @arg @ref RCC_I3C2CLKSOURCE_PLL2R PLL2R selected as I3C2 clock + * @arg @ref RCC_I3C2CLKSOURCE_HSI HSI selected as I3C2 clock + */ +#define __HAL_RCC_GET_I3C2_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR4, RCC_CCIPR4_I3C2SEL))) +#endif /* I3C2 */ + +/** @brief Macro to configure the USART1 clock (USART1CLK). + * + * @param __USART1_CLKSOURCE__ specifies the USART1 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_USART1CLKSOURCE_PCLK2 PCLK2 selected as USART1 clock + * @arg @ref RCC_USART1CLKSOURCE_PLL2Q PLL2Q selected as USART1 clock + * @arg @ref RCC_USART1CLKSOURCE_PLL3Q PLL3Q selected as USART1 clock (*) + * @arg @ref RCC_USART1CLKSOURCE_HSI HSI selected as USART1 clock + * @arg @ref RCC_USART1CLKSOURCE_CSI CSI selected as USART1 clock + * @arg @ref RCC_USART1CLKSOURCE_LSE LSE selected as USART1 clock + * @retval None + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + */ +#define __HAL_RCC_USART1_CONFIG(__USART1_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_USART1SEL, (uint32_t)(__USART1_CLKSOURCE__)) + +/** @brief Macro to get the USART1 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_USART1CLKSOURCE_PCLK2 PCLK2 selected as USART1 clock + * @arg @ref RCC_USART1CLKSOURCE_PLL2Q PLL2Q selected as USART1 clock + * @arg @ref RCC_USART1CLKSOURCE_PLL3Q PLL3Q selected as USART1 clock (*) + * @arg @ref RCC_USART1CLKSOURCE_HSI HSI selected as USART1 clock + * @arg @ref RCC_USART1CLKSOURCE_CSI CSI selected as USART1 clock + * @arg @ref RCC_USART1CLKSOURCE_LSE LSE selected as USART1 clock + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + */ +#define __HAL_RCC_GET_USART1_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_USART1SEL))) + +/** @brief Macro to configure the USART2 clock (USART2CLK). + * + * @param __USART2_CLKSOURCE__ specifies the USART2 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_USART2CLKSOURCE_PCLK1 PCLK2 selected as USART2 clock + * @arg @ref RCC_USART2CLKSOURCE_PLL2Q PLL2Q selected as USART2 clock + * @arg @ref RCC_USART2CLKSOURCE_PLL3Q PLL3Q selected as USART2 clock (*) + * @arg @ref RCC_USART2CLKSOURCE_HSI HSI selected as USART2 clock + * @arg @ref RCC_USART2CLKSOURCE_CSI CSI selected as USART2 clock + * @arg @ref RCC_USART2CLKSOURCE_LSE LSE selected as USART2 clock + * @retval None + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + */ +#define __HAL_RCC_USART2_CONFIG(__USART2_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_USART2SEL, (uint32_t)(__USART2_CLKSOURCE__)) + +/** @brief Macro to get the USART2 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_USART2CLKSOURCE_PCLK1 PCLK2 selected as USART2 clock + * @arg @ref RCC_USART2CLKSOURCE_PLL2Q PLL2Q selected as USART2 clock + * @arg @ref RCC_USART2CLKSOURCE_PLL3Q PLL3Q selected as USART2 clock (*) + * @arg @ref RCC_USART2CLKSOURCE_HSI HSI selected as USART2 clock + * @arg @ref RCC_USART2CLKSOURCE_CSI CSI selected as USART2 clock + * @arg @ref RCC_USART2CLKSOURCE_LSE LSE selected as USART2 clock + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + */ +#define __HAL_RCC_GET_USART2_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_USART2SEL))) + +/** @brief Macro to configure the USART3 clock (USART3CLK). + * + * @param __USART3_CLKSOURCE__ specifies the USART3 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_USART3CLKSOURCE_PCLK1 PCLK2 selected as USART3 clock + * @arg @ref RCC_USART3CLKSOURCE_PLL2Q PLL2Q selected as USART3 clock + * @arg @ref RCC_USART3CLKSOURCE_PLL3Q PLL3Q selected as USART3 clock (*) + * @arg @ref RCC_USART3CLKSOURCE_HSI HSI selected as USART3 clock + * @arg @ref RCC_USART3CLKSOURCE_CSI CSI selected as USART3 clock + * @arg @ref RCC_USART3CLKSOURCE_LSE LSE selected as USART3 clock + * @retval None + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + */ +#define __HAL_RCC_USART3_CONFIG(__USART3_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_USART3SEL, (uint32_t)(__USART3_CLKSOURCE__)) + +/** @brief Macro to get the USART3 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_USART3CLKSOURCE_PCLK1 PCLK2 selected as USART3 clock + * @arg @ref RCC_USART3CLKSOURCE_PLL2Q PLL2Q selected as USART3 clock + * @arg @ref RCC_USART3CLKSOURCE_PLL3Q PLL3Q selected as USART3 clock (*) + * @arg @ref RCC_USART3CLKSOURCE_HSI HSI selected as USART3 clock + * @arg @ref RCC_USART3CLKSOURCE_CSI CSI selected as USART3 clock + * @arg @ref RCC_USART3CLKSOURCE_LSE LSE selected as USART3 clock + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + */ +#define __HAL_RCC_GET_USART3_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_USART3SEL))) + +#if defined(UART4) +/** @brief Macro to configure the UART4 clock (UART4CLK). + * + * @param __UART4_CLKSOURCE__ specifies the UART4 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_UART4CLKSOURCE_PCLK1 PCLK1 selected as UART4 clock + * @arg @ref RCC_UART4CLKSOURCE_PLL2Q PLL2Q Clock selected as UART4 clock + * @arg @ref RCC_UART4CLKSOURCE_PLL3Q PLL3Q Clock selected as UART4 clock + * @arg @ref RCC_UART4CLKSOURCE_HSI HSI selected as UART4 clock + * @arg @ref RCC_UART4CLKSOURCE_CSI CSI selected as UART4 clock + * @arg @ref RCC_UART4CLKSOURCE_LSE LSE selected as UART4 clock + * @retval None + */ +#define __HAL_RCC_UART4_CONFIG(__UART4_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_UART4SEL, (uint32_t)(__UART4_CLKSOURCE__)) + +/** @brief Macro to get the UART4 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_UART4CLKSOURCE_PCLK1 PCLK1 selected as UART4 clock + * @arg @ref RCC_UART4CLKSOURCE_PLL2Q PLL2Q Clock selected as UART4 clock + * @arg @ref RCC_UART4CLKSOURCE_PLL3Q PLL3Q Clock selected as UART4 clock + * @arg @ref RCC_UART4CLKSOURCE_HSI HSI selected as UART4 clock + * @arg @ref RCC_UART4CLKSOURCE_CSI CSI selected as UART4 clock + * @arg @ref RCC_UART4CLKSOURCE_LSE LSE selected as UART4 clock + */ +#define __HAL_RCC_GET_UART4_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_UART4SEL))) +#endif /* UART4 */ + +#if defined(UART5) +/** @brief Macro to configure the UART5 clock (UART5CLK). + * + * @param __UART5_CLKSOURCE__ specifies the UART5 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_UART5CLKSOURCE_PCLK1 PCLK1 selected as UART5 clock + * @arg @ref RCC_UART5CLKSOURCE_PLL2Q PLL2Q Clock selected as UART5 clock + * @arg @ref RCC_UART5CLKSOURCE_PLL3Q PLL3Q Clock selected as UART5 clock + * @arg @ref RCC_UART5CLKSOURCE_HSI HSI selected as UART5 clock + * @arg @ref RCC_UART5CLKSOURCE_CSI CSI selected as UART5 clock + * @arg @ref RCC_UART5CLKSOURCE_LSE LSE selected as UART5 clock + * @retval None + */ +#define __HAL_RCC_UART5_CONFIG(__UART5_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_UART5SEL, (uint32_t)(__UART5_CLKSOURCE__)) + +/** @brief Macro to get the UART5 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_UART5CLKSOURCE_PCLK1 PCLK1 selected as UART5 clock + * @arg @ref RCC_UART5CLKSOURCE_PLL2Q PLL2Q Clock selected as UART5 clock + * @arg @ref RCC_UART5CLKSOURCE_PLL3Q PLL3Q Clock selected as UART5 clock + * @arg @ref RCC_UART5CLKSOURCE_HSI HSI selected as UART5 clock + * @arg @ref RCC_UART5CLKSOURCE_CSI CSI selected as UART5 clock + * @arg @ref RCC_UART5CLKSOURCE_LSE LSE selected as UART5 clock + */ +#define __HAL_RCC_GET_UART5_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_UART5SEL))) +#endif /* UART5 */ + +#if defined(USART6) +/** @brief Macro to configure the USART6 clock (USART6CLK). + * + * @param __USART6_CLKSOURCE__ specifies the USART6 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_USART6CLKSOURCE_PCLK1 PCLK2 selected as USART6 clock + * @arg @ref RCC_USART6CLKSOURCE_PLL2Q PLL2Q selected as USART6 clock + * @arg @ref RCC_USART6CLKSOURCE_PLL3Q PLL3Q selected as USART6 clock + * @arg @ref RCC_USART6CLKSOURCE_HSI HSI selected as USART6 clock + * @arg @ref RCC_USART6CLKSOURCE_CSI CSI selected as USART6 clock + * @arg @ref RCC_USART6CLKSOURCE_LSE LSE selected as USART6 clock + * @retval None + */ +#define __HAL_RCC_USART6_CONFIG(__USART6_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_USART6SEL, (uint32_t)(__USART6_CLKSOURCE__)) + +/** @brief Macro to get the USART6 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_USART6CLKSOURCE_PCLK1 PCLK1 selected as USART6 clock + * @arg @ref RCC_USART6CLKSOURCE_PLL2Q PLL2Q selected as USART6 clock + * @arg @ref RCC_USART6CLKSOURCE_PLL3Q PLL3Q selected as USART6 clock + * @arg @ref RCC_USART6CLKSOURCE_HSI HSI selected as USART6 clock + * @arg @ref RCC_USART6CLKSOURCE_CSI CSI selected as USART6 clock + * @arg @ref RCC_USART6CLKSOURCE_LSE LSE selected as USART6 clock + */ +#define __HAL_RCC_GET_USART6_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_USART6SEL))) +#endif /* USART6 */ + +#if defined(UART7) +/** @brief Macro to configure the UART7 clock (UART7CLK). + * + * @param __UART7_CLKSOURCE__ specifies the UART7 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_UART7CLKSOURCE_PCLK1 PCLK1 selected as UART7 clock + * @arg @ref RCC_UART7CLKSOURCE_PLL2Q PLL2Q selected as UART7 clock + * @arg @ref RCC_UART7CLKSOURCE_PLL3Q PLL3Q selected as UART7 clock + * @arg @ref RCC_UART7CLKSOURCE_HSI HSI selected as UART7 clock + * @arg @ref RCC_UART7CLKSOURCE_CSI CSI selected as UART7 clock + * @arg @ref RCC_UART7CLKSOURCE_LSE LSE selected as UART7 clock + * @retval None + */ +#define __HAL_RCC_UART7_CONFIG(__UART7_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_UART7SEL, (uint32_t)(__UART7_CLKSOURCE__)) + +/** @brief Macro to get the UART7 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_UART7CLKSOURCE_PCLK1 PCLK1 selected as UART7 clock + * @arg @ref RCC_UART7CLKSOURCE_PLL2Q PLL2Q selected as UART7 clock + * @arg @ref RCC_UART7CLKSOURCE_PLL3Q PLL3Q selected as UART7 clock + * @arg @ref RCC_UART7CLKSOURCE_HSI HSI selected as UART7 clock + * @arg @ref RCC_UART7CLKSOURCE_CSI CSI selected as UART7 clock + * @arg @ref RCC_UART7CLKSOURCE_LSE LSE selected as UART7 clock + */ +#define __HAL_RCC_GET_UART7_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_UART7SEL))) +#endif /* UART5 */ + +#if defined(UART8) +/** @brief Macro to configure the UART8 clock (UART8CLK). + * + * @param __UART8_CLKSOURCE__ specifies the UART8 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_UART8CLKSOURCE_PCLK1 PCLK1 selected as UART8 clock + * @arg @ref RCC_UART8CLKSOURCE_PLL2Q PLL2Q selected as UART8 clock + * @arg @ref RCC_UART8CLKSOURCE_PLL3Q PLL3Q selected as UART8 clock + * @arg @ref RCC_UART8CLKSOURCE_HSI HSI selected as UART8 clock + * @arg @ref RCC_UART8CLKSOURCE_CSI CSI selected as UART8 clock + * @arg @ref RCC_UART8CLKSOURCE_LSE LSE selected as UART8 clock + * @retval None + */ +#define __HAL_RCC_UART8_CONFIG(__UART8_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_UART8SEL, (uint32_t)(__UART8_CLKSOURCE__)) + +/** @brief Macro to get the UART8 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_UART8CLKSOURCE_PCLK1 PCLK1 selected as UART8 clock + * @arg @ref RCC_UART8CLKSOURCE_PLL2Q PLL2Q selected as UART8 clock + * @arg @ref RCC_UART8CLKSOURCE_PLL3Q PLL3Q selected as UART8 clock + * @arg @ref RCC_UART8CLKSOURCE_HSI HSI selected as UART8 clock + * @arg @ref RCC_UART8CLKSOURCE_CSI CSI selected as UART8 clock + * @arg @ref RCC_UART8CLKSOURCE_LSE LSE selected as UART8 clock + */ +#define __HAL_RCC_GET_UART8_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_UART8SEL))) +#endif /* UART8 */ + +#if defined(UART9) +/** @brief Macro to configure the UART9 clock (UART9CLK). + * + * @param __UART9_CLKSOURCE__ specifies the UART9 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_UART9CLKSOURCE_PCLK1 PCLK1 selected as UART9 clock + * @arg @ref RCC_UART9CLKSOURCE_PLL2Q PLL2Q selected as UART9 clock + * @arg @ref RCC_UART9CLKSOURCE_PLL3Q PLL3Q selected as UART9 clock + * @arg @ref RCC_UART9CLKSOURCE_HSI HSI selected as UART9 clock + * @arg @ref RCC_UART9CLKSOURCE_CSI CSI selected as UART9 clock + * @arg @ref RCC_UART9CLKSOURCE_LSE LSE selected as UART9 clock + * @retval None + */ +#define __HAL_RCC_UART9_CONFIG(__UART9_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_UART9SEL, (uint32_t)(__UART9_CLKSOURCE__)) + +/** @brief Macro to get the UART9 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_UART9CLKSOURCE_PCLK1 PCLK1 selected as UART9 clock + * @arg @ref RCC_UART9CLKSOURCE_PLL2Q PLL2Q selected as UART9 clock + * @arg @ref RCC_UART9CLKSOURCE_PLL3Q PLL3Q selected as UART9 clock + * @arg @ref RCC_UART9CLKSOURCE_HSI HSI selected as UART9 clock + * @arg @ref RCC_UART9CLKSOURCE_CSI CSI selected as UART9 clock + * @arg @ref RCC_UART9CLKSOURCE_LSE LSE selected as UART9 clock + */ +#define __HAL_RCC_GET_UART9_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_UART9SEL))) +#endif /* UART9 */ + +#if defined(USART10) +/** @brief Macro to configure the USART10 clock (USART10CLK). + * + * @param __USART10_CLKSOURCE__ specifies the USART10 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_USART10CLKSOURCE_PCLK1 PCLK1 selected as USART10 clock + * @arg @ref RCC_USART10CLKSOURCE_PLL2Q PLL2Q selected as USART10 clock + * @arg @ref RCC_USART10CLKSOURCE_PLL3Q PLL3Q selected as USART10 clock + * @arg @ref RCC_USART10CLKSOURCE_HSI HSI selected as USART10 clock + * @arg @ref RCC_USART10CLKSOURCE_CSI CSI selected as USART10 clock + * @arg @ref RCC_USART10CLKSOURCE_LSE LSE selected as USART10 clock + * @retval None + */ +#define __HAL_RCC_USART10_CONFIG(__USART10_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR1, RCC_CCIPR1_USART10SEL, (uint32_t)(__USART10_CLKSOURCE__)) + +/** @brief Macro to get the USART10 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_USART10CLKSOURCE_PCLK1 PCLK1 selected as USART10 clock + * @arg @ref RCC_USART10CLKSOURCE_PLL2Q PLL2Q selected as USART10 clock + * @arg @ref RCC_USART10CLKSOURCE_PLL3Q PLL3Q selected as USART10 clock + * @arg @ref RCC_USART10CLKSOURCE_HSI HSI selected as USART10 clock + * @arg @ref RCC_USART10CLKSOURCE_CSI CSI selected as USART10 clock + * @arg @ref RCC_USART10CLKSOURCE_LSE LSE selected as USART10 clock + */ +#define __HAL_RCC_GET_USART10_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR1, RCC_CCIPR1_USART10SEL))) +#endif /* USART10 */ + +#if defined(USART11) +/** @brief Macro to configure the USART11 clock (USART11CLK). + * + * @param __USART11_CLKSOURCE__ specifies the USART11 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_USART11CLKSOURCE_PCLK1 PCLK1 selected as USART11 clock + * @arg @ref RCC_USART11CLKSOURCE_PLL2Q PLL2Q selected as USART11 clock + * @arg @ref RCC_USART11CLKSOURCE_PLL3Q PLL3Q selected as USART11 clock + * @arg @ref RCC_USART11CLKSOURCE_HSI HSI selected as USART11 clock + * @arg @ref RCC_USART11CLKSOURCE_CSI CSI selected as USART11 clock + * @arg @ref RCC_USART11CLKSOURCE_LSE LSE selected as USART11 clock + * @retval None + */ +#define __HAL_RCC_USART11_CONFIG(__USART11_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR2, RCC_CCIPR2_USART11SEL, (uint32_t)(__USART11_CLKSOURCE__)) + +/** @brief Macro to get the USART11 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_USART11CLKSOURCE_PCLK1 PCLK1 selected as USART11 clock + * @arg @ref RCC_USART11CLKSOURCE_PLL2Q PLL2Q selected as USART11 clock + * @arg @ref RCC_USART11CLKSOURCE_PLL3Q PLL3Q selected as USART11 clock + * @arg @ref RCC_USART11CLKSOURCE_HSI HSI selected as USART11 clock + * @arg @ref RCC_USART11CLKSOURCE_CSI CSI selected as USART11 clock + * @arg @ref RCC_USART11CLKSOURCE_LSE LSE selected as USART11 clock + */ +#define __HAL_RCC_GET_USART11_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR2, RCC_CCIPR2_USART11SEL))) +#endif /* USART11 */ + +#if defined(UART12) +/** @brief Macro to configure the UART12 clock (UART12CLK). + * + * @param __UART12_CLKSOURCE__ specifies the UART12 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_UART12CLKSOURCE_PCLK1 PCLK1 selected as UART12 clock + * @arg @ref RCC_UART12CLKSOURCE_PLL2Q PLL2Q selected as UART12 clock + * @arg @ref RCC_UART12CLKSOURCE_PLL3Q PLL3Q selected as UART12 clock + * @arg @ref RCC_UART12CLKSOURCE_HSI HSI selected as UART12 clock + * @arg @ref RCC_UART12CLKSOURCE_CSI CSI selected as UART12 clock + * @arg @ref RCC_UART12CLKSOURCE_LSE LSE selected as UART12 clock + * @retval None + */ +#define __HAL_RCC_UART12_CONFIG(__UART12_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR2, RCC_CCIPR2_UART12SEL, (uint32_t)(__UART12_CLKSOURCE__)) + +/** @brief Macro to get the UART12 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_UART12CLKSOURCE_PCLK1 PCLK1 selected as UART12 clock + * @arg @ref RCC_UART12CLKSOURCE_PLL2Q PLL2Q selected as UART12 clock + * @arg @ref RCC_UART12CLKSOURCE_PLL3Q PLL3Q selected as UART12 clock + * @arg @ref RCC_UART12CLKSOURCE_HSI HSI selected as UART12 clock + * @arg @ref RCC_UART12CLKSOURCE_CSI CSI selected as UART12 clock + * @arg @ref RCC_UART12CLKSOURCE_LSE LSE selected as UART12 clock + */ +#define __HAL_RCC_GET_UART12_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR2, RCC_CCIPR2_UART12SEL))) +#endif /* UART12 */ + +/** @brief Macro to configure the LPUART1 clock (LPUART1CLK). + * + * @param __LPUART1_CLKSOURCE__ specifies the LPUART1 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_LPUART1CLKSOURCE_PCLK3 PCLK3 selected as LPUART1 clock + * @arg @ref RCC_LPUART1CLKSOURCE_PLL2Q PLL2Q selected as LPUART1 clock + * @arg @ref RCC_LPUART1CLKSOURCE_PLL3Q PLL3Q selected as LPUART1 clock (*) + * @arg @ref RCC_LPUART1CLKSOURCE_HSI HSI selected as LPUART1 clock + * @arg @ref RCC_LPUART1CLKSOURCE_CSI CSI selected as LPUART1 clock + * @arg @ref RCC_LPUART1CLKSOURCE_LSE LSE selected as LPUART1 clock + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + * @retval None + */ +#define __HAL_RCC_LPUART1_CONFIG(__LPUART1_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR3, RCC_CCIPR3_LPUART1SEL, (uint32_t)(__LPUART1_CLKSOURCE__)) + +/** @brief Macro to get the LPUART1 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_LPUART1CLKSOURCE_PCLK3 PCLK3 selected as LPUART1 clock + * @arg @ref RCC_LPUART1CLKSOURCE_PLL2Q PLL2Q selected as LPUART1 clock + * @arg @ref RCC_LPUART1CLKSOURCE_PLL3Q PLL3Q selected as LPUART1 clock (*) + * @arg @ref RCC_LPUART1CLKSOURCE_HSI HSI selected as LPUART1 clock + * @arg @ref RCC_LPUART1CLKSOURCE_CSI CSI selected as LPUART1 clock + * @arg @ref RCC_LPUART1CLKSOURCE_LSE LSE selected as LPUART1 clock + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + */ +#define __HAL_RCC_GET_LPUART1_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR3, RCC_CCIPR3_LPUART1SEL))) + +#if defined(OCTOSPI1) +/** @brief Macro to configure the OctoSPI clock. + * @param __OSPI_CLKSOURCE__ specifies the OctoSPI clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_OSPICLKSOURCE_HCLK HCLK selected as OctoSPI clock + * @arg @ref RCC_OSPICLKSOURCE_PLL1Q PLL1Q divider clock selected as OctoSPI clock + * @arg @ref RCC_OSPICLKSOURCE_PLL2R PLL2R divider clock selected as OctoSPI clock + * @arg @ref RCC_OSPICLKSOURCE_CLKP CLKP selected as OctoSPI clock + * @retval None + */ +#define __HAL_RCC_OSPI_CONFIG(__OSPI_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR4, RCC_CCIPR4_OCTOSPISEL, (uint32_t)(__OSPI_CLKSOURCE__)) + +/** @brief Macro to get the OctoSPI clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_OSPICLKSOURCE_HCLK HCLK selected as OctoSPI clock + * @arg @ref RCC_OSPICLKSOURCE_PLL1Q PLL1Q divider clock selected as OctoSPI clock + * @arg @ref RCC_OSPICLKSOURCE_PLL2R PLL2R divider clock selected as OctoSPI clock + * @arg @ref RCC_OSPICLKSOURCE_CLKP CLKP selected as OctoSPI clock + */ +#define __HAL_RCC_GET_OSPI_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR4, RCC_CCIPR4_OCTOSPISEL))) +#endif /* OCTOSPI1 */ + +#if defined(SDMMC1) +/** @brief Macro to configure the SDMMC1 clock (SDMMCCLK). + * + * @param __SDMMC1_CLKSOURCE__: specifies the SDMMC1 clock source. + * This parameter can be one of the following values: + * @arg RCC_SDMMC1CLKSOURCE_PLL1Q PLL1Q selected as SDMMC1 clock + * @arg RCC_SDMMC1CLKSOURCE_PLL2R PLL2R selected as SDMMC1 clock + */ +#define __HAL_RCC_SDMMC1_CONFIG(__SDMMC1_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR4, RCC_CCIPR4_SDMMC1SEL, (uint32_t)(__SDMMC1_CLKSOURCE__)) + +/** @brief macro to get the SDMMC1 clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_SDMMC1CLKSOURCE_PLL1Q PLL1Q selected as SDMMC1 clock + * @arg RCC_SDMMC1CLKSOURCE_PLL2R PLL2R selected as SDMMC1 clock + */ +#define __HAL_RCC_GET_SDMMC1_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR4, RCC_CCIPR4_SDMMC1SEL))) +#endif /* SDMMC1 */ + +#if defined(SDMMC2) +/** @brief Macro to configure the SDMMC2 clock (SDMMCCLK). + * + * @param __SDMMC2_CLKSOURCE__: specifies the SDMMC2 clock source. + * This parameter can be one of the following values: + * @arg RCC_SDMMC2CLKSOURCE_PLL1Q PLL1Q selected as SDMMC2 clock + * @arg RCC_SDMMC2CLKSOURCE_PLL2R PLL2R selected as SDMMC2 clock + */ +#define __HAL_RCC_SDMMC2_CONFIG(__SDMMC2_CLKSOURCE__) \ + MODIFY_REG(RCC->CCIPR4, RCC_CCIPR4_SDMMC2SEL, (uint32_t)(__SDMMC2_CLKSOURCE__)) + +/** @brief macro to get the SDMMC2 clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_SDMMC2CLKSOURCE_PLL1Q PLL1Q selected as SDMMC2 clock + * @arg RCC_SDMMC2CLKSOURCE_PLL2R PLL2R selected as SDMMC2 clock + */ +#define __HAL_RCC_GET_SDMMC2_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR4, RCC_CCIPR4_SDMMC2SEL))) +#endif /*SDMMC2*/ + +/** @brief macro to configure the RNG clock (RNGCLK). + * + * @param __RNGCLKSource__: specifies the RNG clock source. + * This parameter can be one of the following values: + * @arg RCC_RNGCLKSOURCE_HSI48: HSI48 selected as RNG clock + * @arg RCC_RNGCLKSOURCE_PLL1Q: PLL1Q selected as RNG clock + * @arg RCC_RNGCLKSOURCE_LSE: LSE selected as RNG clock + * @arg RCC_RNGCLKSOURCE_LSI: LSI selected as RNG clock + */ +#define __HAL_RCC_RNG_CONFIG(__RNGCLKSource__) \ + MODIFY_REG(RCC->CCIPR5, RCC_CCIPR5_RNGSEL, (uint32_t)(__RNGCLKSource__)) + +/** @brief macro to get the RNG clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_RNGCLKSOURCE_HSI48: HSI48 selected as RNG clock + * @arg RCC_RNGCLKSOURCE_PLL1Q: PLL1Q selected as RNG clock + * @arg RCC_RNGCLKSOURCE_LSE: LSE selected as RNG clock + * @arg RCC_RNGCLKSOURCE_LSI: LSI selected as RNG clock + */ +#define __HAL_RCC_GET_RNG_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR5, RCC_CCIPR5_RNGSEL))) + +#if defined(SAI1) +/** + * @brief Macro to configure the SAI1 clock source. + * @param __SAI1_CLKSOURCE__ defines the SAI1 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_SAI1CLKSOURCE_PLL1Q PLL1Q selected as SAI1 clock + * @arg @ref RCC_SAI1CLKSOURCE_PLL2P PLL2Pselected as SAI1 clock + * @arg @ref RCC_SAI1CLKSOURCE_PLL3P PLL3P selected as SAI1 clock + * @arg @ref RCC_SAI1CLKSOURCE_PIN External clock selected as SAI1 clock + * @arg @ref RCC_SAI1CLKSOURCE_CLKP CLKP selected as SAI1 clock + * @retval None + */ +#define __HAL_RCC_SAI1_CONFIG(__SAI1_CLKSOURCE__)\ + MODIFY_REG(RCC->CCIPR5, RCC_CCIPR5_SAI1SEL, (uint32_t)(__SAI1_CLKSOURCE__)) + +/** @brief Macro to get the SAI1 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_SAI1CLKSOURCE_PLL1Q PLL1Q selected as SAI1 clock + * @arg @ref RCC_SAI1CLKSOURCE_PLL2P PLL2P selected as SAI1 clock + * @arg @ref RCC_SAI1CLKSOURCE_PLL3P PLL3P selected as SAI1 clock + * @arg @ref RCC_SAI1CLKSOURCE_PIN External clock selected as SAI1 clock + * @arg @ref RCC_SAI1CLKSOURCE_CLKP CLKP selected as SAI1 clock + */ +#define __HAL_RCC_GET_SAI1_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR5, RCC_CCIPR5_SAI1SEL))) +#endif /* SAI1 */ + +#if defined(SAI2) +/** + * @brief Macro to configure the SAI2 clock source. + * @param __SAI2_CLKSOURCE__ defines the SAI2 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_SAI2CLKSOURCE_PLL1Q PLL1Q selected as SAI2 clock + * @arg @ref RCC_SAI2CLKSOURCE_PLL2P PLL2P selected as SAI2 clock + * @arg @ref RCC_SAI2CLKSOURCE_PLL3P PLL3P selected as SAI2 clock + * @arg @ref RCC_SAI2CLKSOURCE_PIN External clock selected as SAI2 clock + * @arg @ref RCC_SAI2CLKSOURCE_CLKP CLKP selected as SAI2 clock + * @retval None + */ +#define __HAL_RCC_SAI2_CONFIG(__SAI2_CLKSOURCE__ )\ + MODIFY_REG(RCC->CCIPR5, RCC_CCIPR5_SAI2SEL, (uint32_t)(__SAI2_CLKSOURCE__)) + +/** @brief Macro to get the SAI2 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_SAI2CLKSOURCE_PLL1Q PLL1Q selected as SAI2 clock + * @arg @ref RCC_SAI2CLKSOURCE_PLL2P PLL2P selected as SAI2 clock + * @arg @ref RCC_SAI2CLKSOURCE_PLL3P PLL3P selected as SAI2 clock + * @arg @ref RCC_SAI2CLKSOURCE_PIN External clock selected as SAI2 clock + * @arg @ref RCC_SAI2CLKSOURCE_CLKP CLKP selected as SAI2 clock + */ +#define __HAL_RCC_GET_SAI2_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR5, RCC_CCIPR5_SAI2SEL))) +#endif /* SAI2 */ + +/** @brief Macro to configure the CLKP : Oscillator clock for peripheral + * @param __CLKPSource__ specifies Oscillator clock for peripheral + * This parameter can be one of the following values: + * @arg RCC_CLKPSOURCE_HSI HSI oscillator selected as clock for peripheral + * @arg RCC_CLKPSOURCE_CSI CSI oscillator selected as clock for peripheral + * @arg RCC_CLKPSOURCE_HSE HSE oscillator selected as clock for peripheral + */ +#define __HAL_RCC_CLKP_CONFIG(__CLKPSource__) \ + MODIFY_REG(RCC->CCIPR5, RCC_CCIPR5_CKERPSEL, (uint32_t)(__CLKPSource__)) + +/** @brief Macro to get the oscillator clock for peripheral clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_CLKPSOURCE_HSI HSI selected Oscillator clock for peripheral + * @arg RCC_CLKPSOURCE_CSI CSI selected Oscillator clock for peripheral + * @arg RCC_CLKPSOURCE_HSE HSE selected Oscillator clock for peripheral + */ +#define __HAL_RCC_GET_CLKP_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR5, RCC_CCIPR5_CKERPSEL))) + +#if defined(CEC) +/** @brief Macro to configure the CEC clock (CECCLK) + * @param __CECCLKSource__ specifies the CEC clock source. + * This parameter can be one of the following values: + * @arg RCC_CECCLKSOURCE_LSE LSE selected as CEC clock + * @arg RCC_CECCLKSOURCE_LSI LSI selected as CEC clock + * @arg RCC_CECCLKSOURCE_CSI_DIV122 CSI Divided by 122 selected as CEC clock + */ +#define __HAL_RCC_CEC_CONFIG(__CECCLKSource__) \ + MODIFY_REG(RCC->CCIPR5, RCC_CCIPR5_CECSEL, (uint32_t)(__CECCLKSource__)) + +/** @brief Macro to get the CEC clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_CECCLKSOURCE_LSE: LSE selected as CEC clock + * @arg RCC_CECCLKSOURCE_LSI: LSI selected as CEC clock + * @arg RCC_CECCLKSOURCE_CSI_DIV122: CSI Divided by 122 selected as CEC clock + */ +#define __HAL_RCC_GET_CEC_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR5, RCC_CCIPR5_CECSEL))) +#endif /* CEC */ + +/** @brief Macro to configure the USB clock (USBCLK). + * @param __USBCLKSource__ specifies the USB clock source. + * This parameter can be one of the following values: + * @arg RCC_USBCLKSOURCE_PLL1Q PLL1Q selected as USB clock + * @arg RCC_USBCLKSOURCE_PLL3Q PLL3Q selected as USB clock (*) + * @arg RCC_USBCLKSOURCE_PLL2Q PLL2Q selected as USB clock (**) + * @arg RCC_USBCLKSOURCE_HSI48 HSI48 selected as USB clock + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + * (**) : For stm32h503xx family line. + */ +#define __HAL_RCC_USB_CONFIG(__USBCLKSource__) \ + MODIFY_REG(RCC->CCIPR4, RCC_CCIPR4_USBSEL, (uint32_t)(__USBCLKSource__)) + +/** @brief Macro to get the USB clock source. + * @retval The clock source can be one of the following values: + * @arg RCC_USBCLKSOURCE_PLL1Q PLL1Q selected as USB clock + * @arg RCC_USBCLKSOURCE_PLL3Q PLL3Q selected as USB clock (*) + * @arg RCC_USBCLKSOURCE_PLL2Q PLL2Q selected as USB clock (**) + * @arg RCC_USBCLKSOURCE_HSI48 HSI48 selected as USB clock + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + * (**) : For stm32h503xx family line. + */ +#define __HAL_RCC_GET_USB_SOURCE() ((uint32_t)(READ_BIT(RCC->CCIPR4, RCC_CCIPR4_USBSEL))) + +/** @brief Macro to configure the Timers clocks prescalers + * @param __PRESC__ specifies the Timers clocks prescalers selection + * This parameter can be one of the following values: + * @arg RCC_TIMPRES_DEACTIVATED: The Timers kernels clocks prescaler is + * equal to rcc_hclk1 if PPREx is corresponding to division by 1 or 2, + * else it is equal to 2 x Frcc_pclkx (default after reset) + * @arg RCC_TIMPRES_ACTIVATED: The Timers kernels clocks prescaler is + * equal to rcc_hclk1 if PPREx is corresponding to division by 1, 2 or 4, + * else it is equal to 4 x Frcc_pclkx + */ +#define __HAL_RCC_TIMCLKPRESCALER(__PRESC__) do {RCC->CFGR1 &= ~(RCC_CFGR1_TIMPRE);\ + RCC->CFGR1 |= (__PRESC__); \ + }while(0) + +#if defined(CRS) + +/** + * @brief Enable the specified CRS interrupts. + * @param __INTERRUPT__ specifies the CRS interrupt sources to be enabled. + * This parameter can be any combination of the following values: + * @arg @ref RCC_CRS_IT_SYNCOK SYNC event OK interrupt + * @arg @ref RCC_CRS_IT_SYNCWARN SYNC warning interrupt + * @arg @ref RCC_CRS_IT_ERR Synchronization or trimming error interrupt + * @arg @ref RCC_CRS_IT_ESYNC Expected SYNC interrupt + * @retval None + */ +#define __HAL_RCC_CRS_ENABLE_IT(__INTERRUPT__) SET_BIT(CRS->CR, (__INTERRUPT__)) + +/** + * @brief Disable the specified CRS interrupts. + * @param __INTERRUPT__ specifies the CRS interrupt sources to be disabled. + * This parameter can be any combination of the following values: + * @arg @ref RCC_CRS_IT_SYNCOK SYNC event OK interrupt + * @arg @ref RCC_CRS_IT_SYNCWARN SYNC warning interrupt + * @arg @ref RCC_CRS_IT_ERR Synchronization or trimming error interrupt + * @arg @ref RCC_CRS_IT_ESYNC Expected SYNC interrupt + * @retval None + */ +#define __HAL_RCC_CRS_DISABLE_IT(__INTERRUPT__) CLEAR_BIT(CRS->CR, (__INTERRUPT__)) + +/** @brief Check whether the CRS interrupt has occurred or not. + * @param __INTERRUPT__ specifies the CRS interrupt source to check. + * This parameter can be one of the following values: + * @arg @ref RCC_CRS_IT_SYNCOK SYNC event OK interrupt + * @arg @ref RCC_CRS_IT_SYNCWARN SYNC warning interrupt + * @arg @ref RCC_CRS_IT_ERR Synchronization or trimming error interrupt + * @arg @ref RCC_CRS_IT_ESYNC Expected SYNC interrupt + * @retval The new state of __INTERRUPT__ (0 or 1). + */ +#define __HAL_RCC_CRS_GET_IT_SOURCE(__INTERRUPT__) ((READ_BIT(CRS->CR, (__INTERRUPT__)) != 0U) ? 1U : 0U) + +/** @brief Clear the CRS interrupt pending bits + * @param __INTERRUPT__ specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg @ref RCC_CRS_IT_SYNCOK SYNC event OK interrupt + * @arg @ref RCC_CRS_IT_SYNCWARN SYNC warning interrupt + * @arg @ref RCC_CRS_IT_ERR Synchronization or trimming error interrupt + * @arg @ref RCC_CRS_IT_ESYNC Expected SYNC interrupt + * @arg @ref RCC_CRS_IT_TRIMOVF Trimming overflow or underflow interrupt + * @arg @ref RCC_CRS_IT_SYNCERR SYNC error interrupt + * @arg @ref RCC_CRS_IT_SYNCMISS SYNC missed interrupt + */ +/* CRS IT Error Mask */ +#define RCC_CRS_IT_ERROR_MASK ((uint32_t)(RCC_CRS_IT_TRIMOVF |\ + RCC_CRS_IT_SYNCERR | RCC_CRS_IT_SYNCMISS)) + +#define __HAL_RCC_CRS_CLEAR_IT(__INTERRUPT__) do { \ + if(((__INTERRUPT__) & RCC_CRS_IT_ERROR_MASK) != 0U) \ + { \ + WRITE_REG(CRS->ICR, CRS_ICR_ERRC | \ + ((__INTERRUPT__) & ~RCC_CRS_IT_ERROR_MASK)); \ + } \ + else \ + { \ + WRITE_REG(CRS->ICR, (__INTERRUPT__)); \ + } \ + } while(0) + +/** + * @brief Check whether the specified CRS flag is set or not. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg @ref RCC_CRS_FLAG_SYNCOK SYNC event OK + * @arg @ref RCC_CRS_FLAG_SYNCWARN SYNC warning + * @arg @ref RCC_CRS_FLAG_ERR Error + * @arg @ref RCC_CRS_FLAG_ESYNC Expected SYNC + * @arg @ref RCC_CRS_FLAG_TRIMOVF Trimming overflow or underflow + * @arg @ref RCC_CRS_FLAG_SYNCERR SYNC error + * @arg @ref RCC_CRS_FLAG_SYNCMISS SYNC missed + * @retval The new state of _FLAG_ (TRUE or FALSE). + */ +#define __HAL_RCC_CRS_GET_FLAG(__FLAG__) (READ_BIT(CRS->ISR, (__FLAG__)) == (__FLAG__)) + +/** + * @brief Clear the CRS specified FLAG. + * @param __FLAG__ specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg @ref RCC_CRS_FLAG_SYNCOK SYNC event OK + * @arg @ref RCC_CRS_FLAG_SYNCWARN SYNC warning + * @arg @ref RCC_CRS_FLAG_ERR Error + * @arg @ref RCC_CRS_FLAG_ESYNC Expected SYNC + * @arg @ref RCC_CRS_FLAG_TRIMOVF Trimming overflow or underflow + * @arg @ref RCC_CRS_FLAG_SYNCERR SYNC error + * @arg @ref RCC_CRS_FLAG_SYNCMISS SYNC missed + * @note RCC_CRS_FLAG_ERR clears RCC_CRS_FLAG_TRIMOVF, RCC_CRS_FLAG_SYNCERR, RCC_CRS_FLAG_SYNCMISS + and consequently RCC_CRS_FLAG_ERR + * @retval None + */ + +/* CRS Flag Error Mask */ +#define RCC_CRS_FLAG_ERROR_MASK ((uint32_t)(RCC_CRS_FLAG_TRIMOVF |\ + RCC_CRS_FLAG_SYNCERR | RCC_CRS_FLAG_SYNCMISS)) + +#define __HAL_RCC_CRS_CLEAR_FLAG(__FLAG__) do { \ + if(((__FLAG__) & RCC_CRS_FLAG_ERROR_MASK) != 0U) \ + { \ + WRITE_REG(CRS->ICR, CRS_ICR_ERRC | \ + ((__FLAG__) & ~RCC_CRS_FLAG_ERROR_MASK)); \ + } \ + else \ + { \ + WRITE_REG(CRS->ICR, (__FLAG__)); \ + } \ + } while(0) + +/** + * @} + */ + +/** @defgroup RCCEx_CRS_Extended_Features RCCEx CRS Extended Features + * @{ + */ +/** + * @brief Enable the oscillator clock for frequency error counter. + * @note when the CEN bit is set the CRS_CFGR register becomes write-protected. + * @retval None + */ +#define __HAL_RCC_CRS_FREQ_ERROR_COUNTER_ENABLE() SET_BIT(CRS->CR, CRS_CR_CEN) + +/** + * @brief Disable the oscillator clock for frequency error counter. + * @retval None + */ +#define __HAL_RCC_CRS_FREQ_ERROR_COUNTER_DISABLE() CLEAR_BIT(CRS->CR, CRS_CR_CEN) + +/** + * @brief Enable the automatic hardware adjustment of TRIM bits. + * @note When the AUTOTRIMEN bit is set the CRS_CFGR register becomes write-protected. + * @retval None + */ +#define __HAL_RCC_CRS_AUTOMATIC_CALIB_ENABLE() SET_BIT(CRS->CR, CRS_CR_AUTOTRIMEN) + +/** + * @brief Enable or disable the automatic hardware adjustment of TRIM bits. + * @retval None + */ +#define __HAL_RCC_CRS_AUTOMATIC_CALIB_DISABLE() CLEAR_BIT(CRS->CR, CRS_CR_AUTOTRIMEN) + +/** + * @brief Macro to calculate reload value to be set in CRS register according to target and sync frequencies + * @note The RELOAD value should be selected according to the ratio between the target frequency and the frequency + * of the synchronization source after prescaling. It is then decreased by one in order to + * reach the expected synchronization on the zero value. The formula is the following: + * RELOAD = (fTARGET / fSYNC) -1 + * @param __FTARGET__ Target frequency (value in Hz) + * @param __FSYNC__ Synchronization signal frequency (value in Hz) + * @retval None + */ +#define __HAL_RCC_CRS_RELOADVALUE_CALCULATE(__FTARGET__, __FSYNC__) (((__FTARGET__) / (__FSYNC__)) - 1U) + + +/** + * @} + */ + +#endif /* CRS */ + +/* Private constants ---------------------------------------------------------*/ +/** @addtogroup RCCEx_Private_Constants + * @{ + */ +/* Define used for IS_RCC_* macros below */ +#if defined(SDMMC2) +#define RCC_PERIPHCLOCK_ALL (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | \ + RCC_PERIPHCLK_UART4 | RCC_PERIPHCLK_UART5 | RCC_PERIPHCLK_USART6 | \ + RCC_PERIPHCLK_UART7 | RCC_PERIPHCLK_UART8 | RCC_PERIPHCLK_UART9 | \ + RCC_PERIPHCLK_USART10 | RCC_PERIPHCLK_USART11 | RCC_PERIPHCLK_UART12 | \ + RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | \ + RCC_PERIPHCLK_I2C3 | RCC_PERIPHCLK_I2C4 | RCC_PERIPHCLK_I3C1 | \ + RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | \ + RCC_PERIPHCLK_LPTIM3 | RCC_PERIPHCLK_LPTIM4 | RCC_PERIPHCLK_LPTIM5 | \ + RCC_PERIPHCLK_LPTIM6 | RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI2 | \ + RCC_PERIPHCLK_ADCDAC | RCC_PERIPHCLK_DAC_LP | RCC_PERIPHCLK_RNG | \ + RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_SDMMC1 | RCC_PERIPHCLK_SDMMC2 | \ + RCC_PERIPHCLK_I3C1 | RCC_PERIPHCLK_SPI1 | RCC_PERIPHCLK_SPI2 | \ + RCC_PERIPHCLK_SPI3 | RCC_PERIPHCLK_SPI4 | RCC_PERIPHCLK_SPI5 | \ + RCC_PERIPHCLK_SPI6 | RCC_PERIPHCLK_OSPI | RCC_PERIPHCLK_FDCAN | \ + RCC_PERIPHCLK_CEC | RCC_PERIPHCLK_USB | RCC_PERIPHCLK_CKPER) +#elif defined(RCC_CR_PLL3ON) +#define RCC_PERIPHCLOCK_ALL (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | \ + RCC_PERIPHCLK_UART4 | RCC_PERIPHCLK_UART5 | RCC_PERIPHCLK_USART6 | \ + RCC_PERIPHCLK_UART7 | RCC_PERIPHCLK_UART8 | RCC_PERIPHCLK_UART9 | \ + RCC_PERIPHCLK_USART10 | RCC_PERIPHCLK_USART11 | RCC_PERIPHCLK_UART12 | \ + RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | \ + RCC_PERIPHCLK_I2C3 | RCC_PERIPHCLK_I2C4 | RCC_PERIPHCLK_I3C1 | \ + RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | \ + RCC_PERIPHCLK_LPTIM3 | RCC_PERIPHCLK_LPTIM4 | RCC_PERIPHCLK_LPTIM5 | \ + RCC_PERIPHCLK_LPTIM6 | RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI2 | \ + RCC_PERIPHCLK_ADCDAC | RCC_PERIPHCLK_DAC_LP | RCC_PERIPHCLK_RNG | \ + RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_SDMMC1 | RCC_PERIPHCLK_I3C1 | \ + RCC_PERIPHCLK_SPI1 | RCC_PERIPHCLK_SPI2 | RCC_PERIPHCLK_SPI3 | \ + RCC_PERIPHCLK_SPI4 | RCC_PERIPHCLK_SPI5 | RCC_PERIPHCLK_SPI6 | \ + RCC_PERIPHCLK_OSPI | RCC_PERIPHCLK_FDCAN | RCC_PERIPHCLK_CEC | \ + RCC_PERIPHCLK_USB | RCC_PERIPHCLK_CKPER) +#else +#define RCC_PERIPHCLOCK_ALL (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | \ + RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | \ + RCC_PERIPHCLK_I3C1 | RCC_PERIPHCLK_I3C2 | RCC_PERIPHCLK_TIM | \ + RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_ADCDAC | \ + RCC_PERIPHCLK_DAC_LP | RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_RTC | \ + RCC_PERIPHCLK_I3C1 | RCC_PERIPHCLK_SPI1 | RCC_PERIPHCLK_SPI2 | \ + RCC_PERIPHCLK_SPI3 | RCC_PERIPHCLK_FDCAN | RCC_PERIPHCLK_USB | \ + RCC_PERIPHCLK_CKPER) +#endif /*FDCAN2 && SDMMC2 */ +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup RCCEx_Private_Macros + * @{ + */ + +#define IS_RCC_PLL2_SOURCE(SOURCE) (((SOURCE) == RCC_PLL2_SOURCE_CSI) || \ + ((SOURCE) == RCC_PLL2_SOURCE_HSI) || \ + ((SOURCE) == RCC_PLL2_SOURCE_HSE)) + +#define IS_RCC_PLL2_DIVM_VALUE(VALUE) ((1U <= (VALUE)) && ((VALUE) <= 63U)) +#define IS_RCC_PLL2_MULN_VALUE(VALUE) ((4U <= (VALUE)) && ((VALUE) <= 512U)) +#define IS_RCC_PLL2_DIVP_VALUE(VALUE) ((1U <= (VALUE)) && ((VALUE) <= 128U)) +#define IS_RCC_PLL2_DIVQ_VALUE(VALUE) ((1U <= (VALUE)) && ((VALUE) <= 128U)) +#define IS_RCC_PLL2_DIVR_VALUE(VALUE) ((1U <= (VALUE)) && ((VALUE) <= 128U)) + +#define IS_RCC_PLL2_FRACN_VALUE(VALUE) ((VALUE) <= 8191U) + +#define IS_RCC_PLL2_VCIRGE_VALUE(VALUE) (((VALUE) == RCC_PLL2_VCIRANGE_0) || \ + ((VALUE) == RCC_PLL2_VCIRANGE_1) || \ + ((VALUE) == RCC_PLL2_VCIRANGE_2) || \ + ((VALUE) == RCC_PLL2_VCIRANGE_3)) + +#define IS_RCC_PLL2_VCORGE_VALUE(VALUE) (((VALUE) == RCC_PLL2_VCORANGE_WIDE) || ((VALUE) == RCC_PLL2_VCORANGE_MEDIUM)) + +#define IS_RCC_PLL2_CLOCKOUT_VALUE(VALUE) ((0x00010000U <= (VALUE)) && ((VALUE) <= 0x00070000U)) + +#if defined(RCC_CR_PLL3ON) +#define IS_RCC_PLL3_SOURCE(SOURCE) (((SOURCE) == RCC_PLL3_SOURCE_CSI) || \ + ((SOURCE) == RCC_PLL3_SOURCE_HSI) || \ + ((SOURCE) == RCC_PLL3_SOURCE_HSE)) + +#define IS_RCC_PLL3_VCIRGE_VALUE(VALUE) (((VALUE) == RCC_PLL3_VCIRANGE_0) || \ + ((VALUE) == RCC_PLL3_VCIRANGE_1) || \ + ((VALUE) == RCC_PLL3_VCIRANGE_2) || \ + ((VALUE) == RCC_PLL3_VCIRANGE_3)) + +#define IS_RCC_PLL3_DIVM_VALUE(VALUE) ((1U <= (VALUE)) && ((VALUE) <= 63U)) +#define IS_RCC_PLL3_MULN_VALUE(VALUE) ((4U <= (VALUE)) && ((VALUE) <= 512U)) +#define IS_RCC_PLL3_DIVP_VALUE(VALUE) ((1U <= (VALUE)) && ((VALUE) <= 128U)) +#define IS_RCC_PLL3_DIVQ_VALUE(VALUE) ((1U <= (VALUE)) && ((VALUE) <= 128U)) +#define IS_RCC_PLL3_DIVR_VALUE(VALUE) ((1U <= (VALUE)) && ((VALUE) <= 128U)) + +#define IS_RCC_PLL3_FRACN_VALUE(VALUE) ((VALUE) <= 8191U) + +#define IS_RCC_PLL3_VCORGE_VALUE(VALUE) (((VALUE) == RCC_PLL3_VCORANGE_WIDE) || ((VALUE) == RCC_PLL3_VCORANGE_MEDIUM)) + +#define IS_RCC_PLL3_CLOCKOUT_VALUE(VALUE) ((0x00010000U <= (VALUE)) && ((VALUE) <= 0x00070000U)) + +#endif /* RCC_CR_PLL3ON */ + +#define IS_RCC_LSCOSOURCE(__SOURCE__) (((__SOURCE__) == RCC_LSCOSOURCE_LSI) || \ + ((__SOURCE__) == RCC_LSCOSOURCE_LSE)) + +#define IS_RCC_CLKPSOURCE(SOURCE) (((SOURCE) == RCC_CLKPSOURCE_HSI) || \ + ((SOURCE) == RCC_CLKPSOURCE_CSI) || \ + ((SOURCE) == RCC_CLKPSOURCE_HSE)) + +#define IS_RCC_PERIPHCLOCK(__SELECTION__) ((((__SELECTION__) & RCC_PERIPHCLOCK_ALL) != ((uint64_t)0x00)) && \ + (((__SELECTION__) & ~RCC_PERIPHCLOCK_ALL) == ((uint64_t)0x00))) +#if defined(RCC_CR_PLL3ON) +#define IS_RCC_USART1CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_USART1CLKSOURCE_PCLK2) || \ + ((__SOURCE__) == RCC_USART1CLKSOURCE_PLL2Q) || \ + ((__SOURCE__) == RCC_USART1CLKSOURCE_PLL3Q) || \ + ((__SOURCE__) == RCC_USART1CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_USART1CLKSOURCE_CSI) || \ + ((__SOURCE__) == RCC_USART1CLKSOURCE_LSE)) + +#define IS_RCC_USART2CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_USART2CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_USART2CLKSOURCE_PLL2Q) || \ + ((__SOURCE__) == RCC_USART2CLKSOURCE_PLL3Q) || \ + ((__SOURCE__) == RCC_USART2CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_USART2CLKSOURCE_CSI) || \ + ((__SOURCE__) == RCC_USART2CLKSOURCE_LSE)) + +#define IS_RCC_USART3CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_USART3CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_USART3CLKSOURCE_PLL2Q) || \ + ((__SOURCE__) == RCC_USART3CLKSOURCE_PLL3Q) || \ + ((__SOURCE__) == RCC_USART3CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_USART3CLKSOURCE_CSI) || \ + ((__SOURCE__) == RCC_USART3CLKSOURCE_LSE)) + +#else +#define IS_RCC_USART1CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_USART1CLKSOURCE_PCLK2) || \ + ((__SOURCE__) == RCC_USART1CLKSOURCE_PLL2Q) || \ + ((__SOURCE__) == RCC_USART1CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_USART1CLKSOURCE_CSI) || \ + ((__SOURCE__) == RCC_USART1CLKSOURCE_LSE)) + +#define IS_RCC_USART2CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_USART2CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_USART2CLKSOURCE_PLL2Q) || \ + ((__SOURCE__) == RCC_USART2CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_USART2CLKSOURCE_CSI) || \ + ((__SOURCE__) == RCC_USART2CLKSOURCE_LSE)) + +#define IS_RCC_USART3CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_USART3CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_USART3CLKSOURCE_PLL2Q) || \ + ((__SOURCE__) == RCC_USART3CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_USART3CLKSOURCE_CSI) || \ + ((__SOURCE__) == RCC_USART3CLKSOURCE_LSE)) + +#endif /* RCC_CR_PLL3ON */ + +#if defined(UART4) +#define IS_RCC_UART4CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_UART4CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_UART4CLKSOURCE_PLL2Q) || \ + ((__SOURCE__) == RCC_UART4CLKSOURCE_PLL3Q) || \ + ((__SOURCE__) == RCC_UART4CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_UART4CLKSOURCE_CSI) || \ + ((__SOURCE__) == RCC_UART4CLKSOURCE_LSE)) +#endif /* UART4 */ + +#if defined(UART5) +#define IS_RCC_UART5CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_UART5CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_UART5CLKSOURCE_PLL2Q) || \ + ((__SOURCE__) == RCC_UART5CLKSOURCE_PLL3Q) || \ + ((__SOURCE__) == RCC_UART5CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_UART5CLKSOURCE_CSI) || \ + ((__SOURCE__) == RCC_UART5CLKSOURCE_LSE)) +#endif /* UART5 */ + +#if defined(USART6) +#define IS_RCC_USART6CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_USART6CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_USART6CLKSOURCE_PLL2Q) || \ + ((__SOURCE__) == RCC_USART6CLKSOURCE_PLL3Q) || \ + ((__SOURCE__) == RCC_USART6CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_USART6CLKSOURCE_CSI) || \ + ((__SOURCE__) == RCC_USART6CLKSOURCE_LSE)) +#endif /* USART6 */ + +#if defined(UART7) +#define IS_RCC_UART7CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_UART7CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_UART7CLKSOURCE_PLL2Q) || \ + ((__SOURCE__) == RCC_UART7CLKSOURCE_PLL3Q) || \ + ((__SOURCE__) == RCC_UART7CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_UART7CLKSOURCE_CSI) || \ + ((__SOURCE__) == RCC_UART7CLKSOURCE_LSE)) +#endif /* UART7 */ + +#if defined(UART8) +#define IS_RCC_UART8CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_UART8CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_UART8CLKSOURCE_PLL2Q) || \ + ((__SOURCE__) == RCC_UART8CLKSOURCE_PLL3Q) || \ + ((__SOURCE__) == RCC_UART8CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_UART8CLKSOURCE_CSI) || \ + ((__SOURCE__) == RCC_UART8CLKSOURCE_LSE)) +#endif /* UART8 */ + +#if defined(UART9) +#define IS_RCC_UART9CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_UART9CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_UART9CLKSOURCE_PLL2Q) || \ + ((__SOURCE__) == RCC_UART9CLKSOURCE_PLL3Q) || \ + ((__SOURCE__) == RCC_UART9CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_UART9CLKSOURCE_CSI) || \ + ((__SOURCE__) == RCC_UART9CLKSOURCE_LSE)) +#endif /* UART9 */ + +#if defined(USART10) +#define IS_RCC_USART10CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_USART10CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_USART10CLKSOURCE_PLL2Q) || \ + ((__SOURCE__) == RCC_USART10CLKSOURCE_PLL3Q) || \ + ((__SOURCE__) == RCC_USART10CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_USART10CLKSOURCE_CSI) || \ + ((__SOURCE__) == RCC_USART10CLKSOURCE_LSE)) +#endif /* USART10 */ + +#if defined(USART11) +#define IS_RCC_USART11CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_USART11CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_USART11CLKSOURCE_PLL2Q) || \ + ((__SOURCE__) == RCC_USART11CLKSOURCE_PLL3Q) || \ + ((__SOURCE__) == RCC_USART11CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_USART11CLKSOURCE_CSI) || \ + ((__SOURCE__) == RCC_USART11CLKSOURCE_LSE)) +#endif /* USART11 */ + +#if defined(UART12) +#define IS_RCC_UART12CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_UART12CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_UART12CLKSOURCE_PLL2Q) || \ + ((__SOURCE__) == RCC_UART12CLKSOURCE_PLL3Q) || \ + ((__SOURCE__) == RCC_UART12CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_UART12CLKSOURCE_CSI) || \ + ((__SOURCE__) == RCC_UART12CLKSOURCE_LSE)) +#endif /* UART12 */ + +#if defined(RCC_CR_PLL3ON) +#define IS_RCC_LPUART1CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_LPUART1CLKSOURCE_PCLK3) || \ + ((__SOURCE__) == RCC_LPUART1CLKSOURCE_PLL2Q) || \ + ((__SOURCE__) == RCC_LPUART1CLKSOURCE_PLL3Q) || \ + ((__SOURCE__) == RCC_LPUART1CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_LPUART1CLKSOURCE_LSE) || \ + ((__SOURCE__) == RCC_LPUART1CLKSOURCE_CSI)) + +#else +#define IS_RCC_LPUART1CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_LPUART1CLKSOURCE_PCLK3) || \ + ((__SOURCE__) == RCC_LPUART1CLKSOURCE_PLL2Q) || \ + ((__SOURCE__) == RCC_LPUART1CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_LPUART1CLKSOURCE_LSE) || \ + ((__SOURCE__) == RCC_LPUART1CLKSOURCE_CSI)) + +#endif /* RCC_CR_PLL3ON */ + +#if defined(RCC_CR_PLL3ON) +#define IS_RCC_I2C1CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_I2C1CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_I2C1CLKSOURCE_PLL3R) || \ + ((__SOURCE__) == RCC_I2C1CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_I2C1CLKSOURCE_CSI)) + +#define IS_RCC_I2C2CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_I2C2CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_I2C2CLKSOURCE_PLL3R) || \ + ((__SOURCE__) == RCC_I2C2CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_I2C2CLKSOURCE_CSI)) + +#else +#define IS_RCC_I2C1CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_I2C1CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_I2C1CLKSOURCE_PLL2R) || \ + ((__SOURCE__) == RCC_I2C1CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_I2C1CLKSOURCE_CSI)) + +#define IS_RCC_I2C2CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_I2C2CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_I2C2CLKSOURCE_PLL2R) || \ + ((__SOURCE__) == RCC_I2C2CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_I2C2CLKSOURCE_CSI)) + +#endif /* RCC_CR_PLL3ON */ + + +#if defined(I2C3) +#define IS_RCC_I2C3CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_I2C3CLKSOURCE_PCLK3) || \ + ((__SOURCE__) == RCC_I2C3CLKSOURCE_PLL3R) || \ + ((__SOURCE__) == RCC_I2C3CLKSOURCE_HSI ) || \ + ((__SOURCE__) == RCC_I2C3CLKSOURCE_CSI)) +#endif /* I2C3 */ + +#if defined(I2C4) +#define IS_RCC_I2C4CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_I2C4CLKSOURCE_PCLK3) || \ + ((__SOURCE__) == RCC_I2C4CLKSOURCE_PLL3R) || \ + ((__SOURCE__) == RCC_I2C4CLKSOURCE_HSI ) || \ + ((__SOURCE__) == RCC_I2C4CLKSOURCE_CSI)) +#endif /* I2C4 */ + +#if defined(RCC_CR_PLL3ON) +#define IS_RCC_I3C1CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_I3C1CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_I3C1CLKSOURCE_PLL3R) || \ + ((__SOURCE__) == RCC_I3C1CLKSOURCE_HSI)) + +#else +#define IS_RCC_I3C1CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_I3C1CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_I3C1CLKSOURCE_PLL2R) || \ + ((__SOURCE__) == RCC_I3C1CLKSOURCE_HSI)) + +#endif /* RCC_CR_PLL3ON */ + +#if defined(I3C2) +#define IS_RCC_I3C2CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_I3C2CLKSOURCE_PCLK3) || \ + ((__SOURCE__) == RCC_I3C2CLKSOURCE_PLL2R) || \ + ((__SOURCE__) == RCC_I3C2CLKSOURCE_HSI)) +#endif /* I3C2 */ + +#if defined(SAI1) +#define IS_RCC_SAI1CLK(__SOURCE__) \ + (((__SOURCE__) == RCC_SAI1CLKSOURCE_PLL1Q)|| \ + ((__SOURCE__) == RCC_SAI1CLKSOURCE_PLL2P)|| \ + ((__SOURCE__) == RCC_SAI1CLKSOURCE_PLL3P)|| \ + ((__SOURCE__) == RCC_SAI1CLKSOURCE_PIN) || \ + ((__SOURCE__) == RCC_SAI1CLKSOURCE_CLKP)) + +#endif /* SAI1 */ + +#if defined(SAI2) +#define IS_RCC_SAI2CLK(__SOURCE__) \ + (((__SOURCE__) == RCC_SAI2CLKSOURCE_PLL1Q)|| \ + ((__SOURCE__) == RCC_SAI2CLKSOURCE_PLL2P)|| \ + ((__SOURCE__) == RCC_SAI2CLKSOURCE_PLL3P)|| \ + ((__SOURCE__) == RCC_SAI2CLKSOURCE_PIN) || \ + ((__SOURCE__) == RCC_SAI2CLKSOURCE_CLKP)) +#endif /* SAI2 */ + +#if defined(RCC_CR_PLL3ON) +#define IS_RCC_LPTIM1CLK(__SOURCE__) \ + (((__SOURCE__) == RCC_LPTIM1CLKSOURCE_PCLK3) || \ + ((__SOURCE__) == RCC_LPTIM1CLKSOURCE_PLL2P) || \ + ((__SOURCE__) == RCC_LPTIM1CLKSOURCE_PLL3R) || \ + ((__SOURCE__) == RCC_LPTIM1CLKSOURCE_LSE) || \ + ((__SOURCE__) == RCC_LPTIM1CLKSOURCE_LSI) || \ + ((__SOURCE__) == RCC_LPTIM1CLKSOURCE_CLKP)) + +#define IS_RCC_LPTIM2CLK(__SOURCE__) \ + (((__SOURCE__) == RCC_LPTIM2CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_LPTIM2CLKSOURCE_PLL2P) || \ + ((__SOURCE__) == RCC_LPTIM2CLKSOURCE_PLL3R) || \ + ((__SOURCE__) == RCC_LPTIM2CLKSOURCE_LSE) || \ + ((__SOURCE__) == RCC_LPTIM2CLKSOURCE_LSI) || \ + ((__SOURCE__) == RCC_LPTIM2CLKSOURCE_CLKP)) + +#else +#define IS_RCC_LPTIM1CLK(__SOURCE__) \ + (((__SOURCE__) == RCC_LPTIM1CLKSOURCE_PCLK3) || \ + ((__SOURCE__) == RCC_LPTIM1CLKSOURCE_PLL2P) || \ + ((__SOURCE__) == RCC_LPTIM1CLKSOURCE_LSE) || \ + ((__SOURCE__) == RCC_LPTIM1CLKSOURCE_LSI) || \ + ((__SOURCE__) == RCC_LPTIM1CLKSOURCE_CLKP)) + +#define IS_RCC_LPTIM2CLK(__SOURCE__) \ + (((__SOURCE__) == RCC_LPTIM2CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_LPTIM2CLKSOURCE_PLL2P) || \ + ((__SOURCE__) == RCC_LPTIM2CLKSOURCE_LSE) || \ + ((__SOURCE__) == RCC_LPTIM2CLKSOURCE_LSI) || \ + ((__SOURCE__) == RCC_LPTIM2CLKSOURCE_CLKP)) + +#endif /* RCC_CR_PLL3ON */ + +#if defined(LPTIM3) +#define IS_RCC_LPTIM3CLK(__SOURCE__) \ + (((__SOURCE__) == RCC_LPTIM3CLKSOURCE_PCLK3) || \ + ((__SOURCE__) == RCC_LPTIM3CLKSOURCE_PLL2P) || \ + ((__SOURCE__) == RCC_LPTIM3CLKSOURCE_PLL3R) || \ + ((__SOURCE__) == RCC_LPTIM3CLKSOURCE_LSE) || \ + ((__SOURCE__) == RCC_LPTIM3CLKSOURCE_LSI) || \ + ((__SOURCE__) == RCC_LPTIM3CLKSOURCE_CLKP)) + +#endif /* LPTIM3 */ + +#if defined(LPTIM4) +#define IS_RCC_LPTIM4CLK(__SOURCE__) \ + (((__SOURCE__) == RCC_LPTIM4CLKSOURCE_PCLK3) || \ + ((__SOURCE__) == RCC_LPTIM4CLKSOURCE_PLL2P) || \ + ((__SOURCE__) == RCC_LPTIM4CLKSOURCE_PLL3R) || \ + ((__SOURCE__) == RCC_LPTIM4CLKSOURCE_LSE) || \ + ((__SOURCE__) == RCC_LPTIM4CLKSOURCE_LSI) || \ + ((__SOURCE__) == RCC_LPTIM4CLKSOURCE_CLKP)) + +#endif /* LPTIM4 */ + +#if defined(LPTIM5) +#define IS_RCC_LPTIM5CLK(__SOURCE__) \ + (((__SOURCE__) == RCC_LPTIM5CLKSOURCE_PCLK3) || \ + ((__SOURCE__) == RCC_LPTIM5CLKSOURCE_PLL2P) || \ + ((__SOURCE__) == RCC_LPTIM5CLKSOURCE_PLL3R) || \ + ((__SOURCE__) == RCC_LPTIM5CLKSOURCE_LSE) || \ + ((__SOURCE__) == RCC_LPTIM5CLKSOURCE_LSI) || \ + ((__SOURCE__) == RCC_LPTIM5CLKSOURCE_CLKP)) +#endif /* LPTIM5 */ + +#if defined(LPTIM6) +#define IS_RCC_LPTIM6CLK(__SOURCE__) \ + (((__SOURCE__) == RCC_LPTIM6CLKSOURCE_PCLK3) || \ + ((__SOURCE__) == RCC_LPTIM6CLKSOURCE_PLL2P) || \ + ((__SOURCE__) == RCC_LPTIM6CLKSOURCE_PLL3R) || \ + ((__SOURCE__) == RCC_LPTIM6CLKSOURCE_LSE) || \ + ((__SOURCE__) == RCC_LPTIM6CLKSOURCE_LSI) || \ + ((__SOURCE__) == RCC_LPTIM6CLKSOURCE_CLKP)) +#endif /* LPTIM6 */ + +#define IS_RCC_FDCANCLK(__SOURCE__) \ + (((__SOURCE__) == RCC_FDCANCLKSOURCE_HSE) || \ + ((__SOURCE__) == RCC_FDCANCLKSOURCE_PLL1Q) || \ + ((__SOURCE__) == RCC_FDCANCLKSOURCE_PLL2Q)) + +#if defined(SDMMC1) +#define IS_RCC_SDMMC1CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_SDMMC1CLKSOURCE_PLL1Q) || \ + ((__SOURCE__) == RCC_SDMMC1CLKSOURCE_PLL2R)) +#endif /* SDMMC1 */ + +#if defined(SDMMC2) +#define IS_RCC_SDMMC2CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_SDMMC2CLKSOURCE_PLL1Q) || \ + ((__SOURCE__) == RCC_SDMMC2CLKSOURCE_PLL2R)) +#endif /*SDMMC2*/ + +#define IS_RCC_RNGCLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_RNGCLKSOURCE_HSI48) || \ + ((__SOURCE__) == RCC_RNGCLKSOURCE_PLL1Q) || \ + ((__SOURCE__) == RCC_RNGCLKSOURCE_LSE) || \ + ((__SOURCE__) == RCC_RNGCLKSOURCE_LSI)) + +#define IS_RCC_ADCDACCLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_ADCDACCLKSOURCE_HCLK) || \ + ((__SOURCE__) == RCC_ADCDACCLKSOURCE_SYSCLK) || \ + ((__SOURCE__) == RCC_ADCDACCLKSOURCE_PLL2R) || \ + ((__SOURCE__) == RCC_ADCDACCLKSOURCE_HSE) || \ + ((__SOURCE__) == RCC_ADCDACCLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_ADCDACCLKSOURCE_CSI)) + +#define IS_RCC_DACLPCLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_DACLPCLKSOURCE_LSI) || \ + ((__SOURCE__) == RCC_DACLPCLKSOURCE_LSE)) + +#if defined(OCTOSPI1) +#define IS_RCC_OSPICLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_OSPICLKSOURCE_HCLK) || \ + ((__SOURCE__) == RCC_OSPICLKSOURCE_PLL1Q) || \ + ((__SOURCE__) == RCC_OSPICLKSOURCE_PLL2R) || \ + ((__SOURCE__) == RCC_OSPICLKSOURCE_CLKP)) +#endif /* OCTOSPI1 */ + +#if defined(RCC_CR_PLL3ON) +#define IS_RCC_SPI1CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_SPI1CLKSOURCE_PLL1Q) || \ + ((__SOURCE__) == RCC_SPI1CLKSOURCE_PLL2P) || \ + ((__SOURCE__) == RCC_SPI1CLKSOURCE_PLL3P) || \ + ((__SOURCE__) == RCC_SPI1CLKSOURCE_PIN) || \ + ((__SOURCE__) == RCC_SPI1CLKSOURCE_CLKP)) + +#define IS_RCC_SPI2CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_SPI2CLKSOURCE_PLL1Q) || \ + ((__SOURCE__) == RCC_SPI2CLKSOURCE_PLL2P) || \ + ((__SOURCE__) == RCC_SPI2CLKSOURCE_PLL3P) || \ + ((__SOURCE__) == RCC_SPI2CLKSOURCE_PIN) || \ + ((__SOURCE__) == RCC_SPI2CLKSOURCE_CLKP)) + +#define IS_RCC_SPI3CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_SPI3CLKSOURCE_PLL1Q) || \ + ((__SOURCE__) == RCC_SPI3CLKSOURCE_PLL2P) || \ + ((__SOURCE__) == RCC_SPI3CLKSOURCE_PLL3P) || \ + ((__SOURCE__) == RCC_SPI3CLKSOURCE_PIN) || \ + ((__SOURCE__) == RCC_SPI3CLKSOURCE_CLKP)) +#else +#define IS_RCC_SPI1CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_SPI1CLKSOURCE_PLL1Q) || \ + ((__SOURCE__) == RCC_SPI1CLKSOURCE_PLL2P) || \ + ((__SOURCE__) == RCC_SPI1CLKSOURCE_PIN) || \ + ((__SOURCE__) == RCC_SPI1CLKSOURCE_CLKP)) + +#define IS_RCC_SPI2CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_SPI2CLKSOURCE_PLL1Q) || \ + ((__SOURCE__) == RCC_SPI2CLKSOURCE_PLL2P) || \ + ((__SOURCE__) == RCC_SPI2CLKSOURCE_PIN) || \ + ((__SOURCE__) == RCC_SPI2CLKSOURCE_CLKP)) + +#define IS_RCC_SPI3CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_SPI3CLKSOURCE_PLL1Q) || \ + ((__SOURCE__) == RCC_SPI3CLKSOURCE_PLL2P) || \ + ((__SOURCE__) == RCC_SPI3CLKSOURCE_PIN) || \ + ((__SOURCE__) == RCC_SPI3CLKSOURCE_CLKP)) + +#endif /* RCC_CR_PLL3ON */ + +#if defined(SPI4) +#define IS_RCC_SPI4CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_SPI4CLKSOURCE_PCLK2) || \ + ((__SOURCE__) == RCC_SPI4CLKSOURCE_PLL2Q) || \ + ((__SOURCE__) == RCC_SPI4CLKSOURCE_PLL3Q) || \ + ((__SOURCE__) == RCC_SPI4CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_SPI4CLKSOURCE_CSI) || \ + ((__SOURCE__) == RCC_SPI4CLKSOURCE_HSE)) +#endif /* SPI4 */ + +#if defined(SPI5) +#define IS_RCC_SPI5CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_SPI5CLKSOURCE_PCLK3) || \ + ((__SOURCE__) == RCC_SPI5CLKSOURCE_PLL2Q) || \ + ((__SOURCE__) == RCC_SPI5CLKSOURCE_PLL3Q) || \ + ((__SOURCE__) == RCC_SPI5CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_SPI5CLKSOURCE_CSI) || \ + ((__SOURCE__) == RCC_SPI5CLKSOURCE_HSE)) +#endif /* SPI5 */ + +#if defined(SPI6) +#define IS_RCC_SPI6CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_SPI6CLKSOURCE_PCLK2) || \ + ((__SOURCE__) == RCC_SPI6CLKSOURCE_PLL2Q) || \ + ((__SOURCE__) == RCC_SPI6CLKSOURCE_PLL3Q) || \ + ((__SOURCE__) == RCC_SPI6CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_SPI6CLKSOURCE_CSI) || \ + ((__SOURCE__) == RCC_SPI6CLKSOURCE_HSE)) +#endif /* SPI6 */ + +#if defined(RCC_CR_PLL3ON) +#define IS_RCC_USBCLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_USBCLKSOURCE_PLL1Q) || \ + ((__SOURCE__) == RCC_USBCLKSOURCE_PLL3Q) || \ + ((__SOURCE__) == RCC_USBCLKSOURCE_HSI48)) +#else +#define IS_RCC_USBCLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_USBCLKSOURCE_PLL1Q) || \ + ((__SOURCE__) == RCC_USBCLKSOURCE_PLL2Q) || \ + ((__SOURCE__) == RCC_USBCLKSOURCE_HSI48)) +#endif /* RCC_CR_PLL3ON */ + +#if defined(CEC) +#define IS_RCC_CECCLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_CECCLKSOURCE_LSE) || \ + ((__SOURCE__) == RCC_CECCLKSOURCE_LSI) || \ + ((__SOURCE__) == RCC_CECCLKSOURCE_CSI_DIV122)) +#endif /*CEC*/ + +#define IS_RCC_TIMPRES(VALUE) \ + (((VALUE) == RCC_TIMPRES_DEACTIVATED) || \ + ((VALUE) == RCC_TIMPRES_ACTIVATED)) + +#if defined(CRS) + +#define IS_RCC_CRS_SYNC_SOURCE(__SOURCE__) (((__SOURCE__) == RCC_CRS_SYNC_SOURCE_GPIO) || \ + ((__SOURCE__) == RCC_CRS_SYNC_SOURCE_LSE) || \ + ((__SOURCE__) == RCC_CRS_SYNC_SOURCE_USB)) + +#define IS_RCC_CRS_SYNC_DIV(__DIV__) (((__DIV__) == RCC_CRS_SYNC_DIV1) || ((__DIV__) == RCC_CRS_SYNC_DIV2) || \ + ((__DIV__) == RCC_CRS_SYNC_DIV4) || ((__DIV__) == RCC_CRS_SYNC_DIV8) || \ + ((__DIV__) == RCC_CRS_SYNC_DIV16) || ((__DIV__) == RCC_CRS_SYNC_DIV32) || \ + ((__DIV__) == RCC_CRS_SYNC_DIV64) || ((__DIV__) == RCC_CRS_SYNC_DIV128)) + +#define IS_RCC_CRS_SYNC_POLARITY(__POLARITY__) (((__POLARITY__) == RCC_CRS_SYNC_POLARITY_RISING) || \ + ((__POLARITY__) == RCC_CRS_SYNC_POLARITY_FALLING)) + +#define IS_RCC_CRS_RELOADVALUE(__VALUE__) (((__VALUE__) <= 0xFFFFU)) + +#define IS_RCC_CRS_ERRORLIMIT(__VALUE__) (((__VALUE__) <= 0xFFU)) + +#define IS_RCC_CRS_HSI48CALIBRATION(__VALUE__) (((__VALUE__) <= 0x7FU)) + +#define IS_RCC_CRS_FREQERRORDIR(__DIR__) (((__DIR__) == RCC_CRS_FREQERRORDIR_UP) || \ + ((__DIR__) == RCC_CRS_FREQERRORDIR_DOWN)) + +#endif /* CRS */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup RCCEx_Exported_Functions + * @{ + */ + +/** @addtogroup RCCEx_Exported_Functions_Group1 + * @{ + */ + +HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(const RCC_PeriphCLKInitTypeDef *pPeriphClkInit); +void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *pPeriphClkInit); +uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint64_t PeriphClk); +void HAL_RCCEx_GetPLL1ClockFreq(PLL1_ClocksTypeDef *pPLL1_Clocks); +void HAL_RCCEx_GetPLL2ClockFreq(PLL2_ClocksTypeDef *pPLL2_Clocks); +#if defined(RCC_CR_PLL3ON) +void HAL_RCCEx_GetPLL3ClockFreq(PLL3_ClocksTypeDef *pPLL3_Clocks); +#endif /* RCC_CR_PLL3ON */ +/** + * @} + */ + +/** @addtogroup RCCEx_Exported_Functions_Group2 + * @{ + */ + +HAL_StatusTypeDef HAL_RCCEx_EnablePLL2(RCC_PLL2InitTypeDef *pPLL2Init); +HAL_StatusTypeDef HAL_RCCEx_DisablePLL2(void); +#if defined(RCC_CR_PLL3ON) +HAL_StatusTypeDef HAL_RCCEx_EnablePLL3(RCC_PLL3InitTypeDef *pPLL3Init); +HAL_StatusTypeDef HAL_RCCEx_DisablePLL3(void); +#endif /* RCC_CR_PLL3ON */ + +void HAL_RCCEx_WakeUpStopCLKConfig(uint32_t WakeUpClk); +void HAL_RCCEx_KerWakeUpStopCLKConfig(uint32_t WakeUpClk); +void HAL_RCCEx_EnableLSECSS(void); +void HAL_RCCEx_DisableLSECSS(void); +void HAL_RCCEx_LSECSS_IRQHandler(void); +void HAL_RCCEx_LSECSS_Callback(void); +void HAL_RCCEx_EnableLSCO(uint32_t LSCOSource); +void HAL_RCCEx_DisableLSCO(void); +/** + * @} + */ + +#if defined(CRS) + +/** @addtogroup RCCEx_Exported_Functions_Group3 + * @{ + */ +void HAL_RCCEx_CRSConfig(const RCC_CRSInitTypeDef *pInit); +void HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void); +void HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef *pSynchroInfo); +uint32_t HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout); +void HAL_RCCEx_CRS_IRQHandler(void); +void HAL_RCCEx_CRS_SyncOkCallback(void); +void HAL_RCCEx_CRS_SyncWarnCallback(void); +void HAL_RCCEx_CRS_ExpectedSyncCallback(void); +void HAL_RCCEx_CRS_ErrorCallback(uint32_t Error); +/** + * @} + */ + +#endif /* CRS */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32H5xx_HAL_RCC_EX_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_rng.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_rng.h new file mode 100644 index 0000000000..abdccacd07 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_rng.h @@ -0,0 +1,389 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_rng.h + * @author MCD Application Team + * @brief Header file of RNG HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_RNG_H +#define STM32H5xx_HAL_RNG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +#if defined (RNG) + +/** @defgroup RNG RNG + * @brief RNG HAL module driver + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup RNG_Exported_Types RNG Exported Types + * @{ + */ + +/** @defgroup RNG_Exported_Types_Group1 RNG Init Structure definition + * @{ + */ +typedef struct +{ + uint32_t ClockErrorDetection; /*!< CED Clock error detection */ +} RNG_InitTypeDef; + +/** + * @} + */ + +/** @defgroup RNG_Exported_Types_Group2 RNG State Structure definition + * @{ + */ +typedef enum +{ + HAL_RNG_STATE_RESET = 0x00U, /*!< RNG not yet initialized or disabled */ + HAL_RNG_STATE_READY = 0x01U, /*!< RNG initialized and ready for use */ + HAL_RNG_STATE_BUSY = 0x02U, /*!< RNG internal process is ongoing */ + HAL_RNG_STATE_TIMEOUT = 0x03U, /*!< RNG timeout state */ + HAL_RNG_STATE_ERROR = 0x04U /*!< RNG error state */ + +} HAL_RNG_StateTypeDef; + +/** + * @} + */ + +/** @defgroup RNG_Exported_Types_Group3 RNG Handle Structure definition + * @{ + */ +#if (USE_HAL_RNG_REGISTER_CALLBACKS == 1) +typedef struct __RNG_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_RNG_REGISTER_CALLBACKS */ +{ + RNG_TypeDef *Instance; /*!< Register base address */ + + RNG_InitTypeDef Init; /*!< RNG configuration parameters */ + + HAL_LockTypeDef Lock; /*!< RNG locking object */ + + __IO HAL_RNG_StateTypeDef State; /*!< RNG communication state */ + + __IO uint32_t ErrorCode; /*!< RNG Error code */ + + uint32_t RandomNumber; /*!< Last Generated RNG Data */ + +#if (USE_HAL_RNG_REGISTER_CALLBACKS == 1) + void (* ReadyDataCallback)(struct __RNG_HandleTypeDef *hrng, uint32_t random32bit); /*!< RNG Data Ready Callback */ + void (* ErrorCallback)(struct __RNG_HandleTypeDef *hrng); /*!< RNG Error Callback */ + + void (* MspInitCallback)(struct __RNG_HandleTypeDef *hrng); /*!< RNG Msp Init callback */ + void (* MspDeInitCallback)(struct __RNG_HandleTypeDef *hrng); /*!< RNG Msp DeInit callback */ +#endif /* USE_HAL_RNG_REGISTER_CALLBACKS */ + +} RNG_HandleTypeDef; + +#if (USE_HAL_RNG_REGISTER_CALLBACKS == 1) +/** + * @brief HAL RNG Callback ID enumeration definition + */ +typedef enum +{ + HAL_RNG_ERROR_CB_ID = 0x00U, /*!< RNG Error Callback ID */ + + HAL_RNG_MSPINIT_CB_ID = 0x01U, /*!< RNG MspInit callback ID */ + HAL_RNG_MSPDEINIT_CB_ID = 0x02U /*!< RNG MspDeInit callback ID */ + +} HAL_RNG_CallbackIDTypeDef; + +/** + * @brief HAL RNG Callback pointer definition + */ +typedef void (*pRNG_CallbackTypeDef)(RNG_HandleTypeDef *hrng); /*!< pointer to a common RNG callback function */ +typedef void (*pRNG_ReadyDataCallbackTypeDef)(RNG_HandleTypeDef *hrng, uint32_t random32bit); /*!< pointer to an RNG Data Ready specific callback function */ + +#endif /* USE_HAL_RNG_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup RNG_Exported_Constants RNG Exported Constants + * @{ + */ + +/** @defgroup RNG_Exported_Constants_Group1 RNG Interrupt definition + * @{ + */ +#define RNG_IT_DRDY RNG_SR_DRDY /*!< Data Ready interrupt */ +#define RNG_IT_CEI RNG_SR_CEIS /*!< Clock error interrupt */ +#define RNG_IT_SEI RNG_SR_SEIS /*!< Seed error interrupt */ +/** + * @} + */ + +/** @defgroup RNG_Exported_Constants_Group2 RNG Flag definition + * @{ + */ +#define RNG_FLAG_DRDY RNG_SR_DRDY /*!< Data ready */ +#define RNG_FLAG_CECS RNG_SR_CECS /*!< Clock error current status */ +#define RNG_FLAG_SECS RNG_SR_SECS /*!< Seed error current status */ +/** + * @} + */ + +/** @defgroup RNG_Exported_Constants_Group3 RNG Clock Error Detection + * @{ + */ +#define RNG_CED_ENABLE 0x00000000U /*!< Clock error detection Enabled */ +#define RNG_CED_DISABLE RNG_CR_CED /*!< Clock error detection Disabled */ +/** + * @} + */ + +/** @defgroup RNG_Error_Definition RNG Error Definition + * @{ + */ +#define HAL_RNG_ERROR_NONE 0x00000000U /*!< No error */ +#if (USE_HAL_RNG_REGISTER_CALLBACKS == 1) +#define HAL_RNG_ERROR_INVALID_CALLBACK 0x00000001U /*!< Invalid Callback error */ +#endif /* USE_HAL_RNG_REGISTER_CALLBACKS */ +#define HAL_RNG_ERROR_TIMEOUT 0x00000002U /*!< Timeout error */ +#define HAL_RNG_ERROR_BUSY 0x00000004U /*!< Busy error */ +#define HAL_RNG_ERROR_SEED 0x00000008U /*!< Seed error */ +#define HAL_RNG_ERROR_CLOCK 0x00000010U /*!< Clock error */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup RNG_Exported_Macros RNG Exported Macros + * @{ + */ + +/** @brief Reset RNG handle state + * @param __HANDLE__ RNG Handle + * @retval None + */ +#if (USE_HAL_RNG_REGISTER_CALLBACKS == 1) +#define __HAL_RNG_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->State = HAL_RNG_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0U) +#else +#define __HAL_RNG_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_RNG_STATE_RESET) +#endif /* USE_HAL_RNG_REGISTER_CALLBACKS */ + +/** + * @brief Enables the RNG peripheral. + * @param __HANDLE__ RNG Handle + * @retval None + */ +#define __HAL_RNG_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= RNG_CR_RNGEN) + +/** + * @brief Disables the RNG peripheral. + * @param __HANDLE__ RNG Handle + * @retval None + */ +#define __HAL_RNG_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR &= ~RNG_CR_RNGEN) + +/** + * @brief Check the selected RNG flag status. + * @param __HANDLE__ RNG Handle + * @param __FLAG__ RNG flag + * This parameter can be one of the following values: + * @arg RNG_FLAG_DRDY: Data ready + * @arg RNG_FLAG_CECS: Clock error current status + * @arg RNG_FLAG_SECS: Seed error current status + * @retval The new state of __FLAG__ (SET or RESET). + */ +#define __HAL_RNG_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__)) + +/** + * @brief Clears the selected RNG flag status. + * @param __HANDLE__ RNG handle + * @param __FLAG__ RNG flag to clear + * @note WARNING: This is a dummy macro for HAL code alignment, + * flags RNG_FLAG_DRDY, RNG_FLAG_CECS and RNG_FLAG_SECS are read-only. + * @retval None + */ +#define __HAL_RNG_CLEAR_FLAG(__HANDLE__, __FLAG__) /* dummy macro */ + +/** + * @brief Enables the RNG interrupts. + * @param __HANDLE__ RNG Handle + * @retval None + */ +#define __HAL_RNG_ENABLE_IT(__HANDLE__) ((__HANDLE__)->Instance->CR |= RNG_CR_IE) + +/** + * @brief Disables the RNG interrupts. + * @param __HANDLE__ RNG Handle + * @retval None + */ +#define __HAL_RNG_DISABLE_IT(__HANDLE__) ((__HANDLE__)->Instance->CR &= ~RNG_CR_IE) + +/** + * @brief Checks whether the specified RNG interrupt has occurred or not. + * @param __HANDLE__ RNG Handle + * @param __INTERRUPT__ specifies the RNG interrupt status flag to check. + * This parameter can be one of the following values: + * @arg RNG_IT_DRDY: Data ready interrupt + * @arg RNG_IT_CEI: Clock error interrupt + * @arg RNG_IT_SEI: Seed error interrupt + * @retval The new state of __INTERRUPT__ (SET or RESET). + */ +#define __HAL_RNG_GET_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->SR & (__INTERRUPT__)) == (__INTERRUPT__)) + +/** + * @brief Clear the RNG interrupt status flags. + * @param __HANDLE__ RNG Handle + * @param __INTERRUPT__ specifies the RNG interrupt status flag to clear. + * This parameter can be one of the following values: + * @arg RNG_IT_CEI: Clock error interrupt + * @arg RNG_IT_SEI: Seed error interrupt + * @note RNG_IT_DRDY flag is read-only, reading RNG_DR register automatically clears RNG_IT_DRDY. + * @retval None + */ +#define __HAL_RNG_CLEAR_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->SR) = ~(__INTERRUPT__)) + +/** + * @} + */ + +/* Include RNG HAL Extended module */ +#include "stm32h5xx_hal_rng_ex.h" +/* Exported functions --------------------------------------------------------*/ +/** @defgroup RNG_Exported_Functions RNG Exported Functions + * @{ + */ + +/** @defgroup RNG_Exported_Functions_Group1 Initialization and configuration functions + * @{ + */ +HAL_StatusTypeDef HAL_RNG_Init(RNG_HandleTypeDef *hrng); +HAL_StatusTypeDef HAL_RNG_DeInit(RNG_HandleTypeDef *hrng); +void HAL_RNG_MspInit(RNG_HandleTypeDef *hrng); +void HAL_RNG_MspDeInit(RNG_HandleTypeDef *hrng); + +/* Callbacks Register/UnRegister functions ***********************************/ +#if (USE_HAL_RNG_REGISTER_CALLBACKS == 1) +HAL_StatusTypeDef HAL_RNG_RegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID, + pRNG_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_RNG_UnRegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID); + +HAL_StatusTypeDef HAL_RNG_RegisterReadyDataCallback(RNG_HandleTypeDef *hrng, pRNG_ReadyDataCallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_RNG_UnRegisterReadyDataCallback(RNG_HandleTypeDef *hrng); +#endif /* USE_HAL_RNG_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup RNG_Exported_Functions_Group2 Peripheral Control functions + * @{ + */ +HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef *hrng, uint32_t *random32bit); +HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber_IT(RNG_HandleTypeDef *hrng); +uint32_t HAL_RNG_ReadLastRandomNumber(const RNG_HandleTypeDef *hrng); + +void HAL_RNG_IRQHandler(RNG_HandleTypeDef *hrng); +void HAL_RNG_ErrorCallback(RNG_HandleTypeDef *hrng); +void HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef *hrng, uint32_t random32bit); + +/** + * @} + */ + +/** @defgroup RNG_Exported_Functions_Group3 Peripheral State functions + * @{ + */ +HAL_RNG_StateTypeDef HAL_RNG_GetState(const RNG_HandleTypeDef *hrng); +uint32_t HAL_RNG_GetError(const RNG_HandleTypeDef *hrng); +/** + * @} + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup RNG_Private_Macros RNG Private Macros + * @{ + */ +#define IS_RNG_IT(IT) (((IT) == RNG_IT_CEI) || \ + ((IT) == RNG_IT_SEI)) + +#define IS_RNG_FLAG(FLAG) (((FLAG) == RNG_FLAG_DRDY) || \ + ((FLAG) == RNG_FLAG_CECS) || \ + ((FLAG) == RNG_FLAG_SECS)) + +/** + * @brief Verify the RNG Clock Error Detection mode. + * @param __MODE__ RNG Clock Error Detection mode + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_RNG_CED(__MODE__) (((__MODE__) == RNG_CED_ENABLE) || \ + ((__MODE__) == RNG_CED_DISABLE)) +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup RNG_Private_Functions RNG Private functions + * @{ + */ +HAL_StatusTypeDef RNG_RecoverSeedError(RNG_HandleTypeDef *hrng); +/** + * @} + */ +/** + * @} + */ + +#endif /* RNG */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* STM32H5xx_HAL_RNG_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_rng_ex.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_rng_ex.h new file mode 100644 index 0000000000..5849b71278 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_rng_ex.h @@ -0,0 +1,263 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_rng_ex.h + * @author MCD Application Team + * @brief Header file of RNG HAL Extension module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_RNG_EX_H +#define STM32H5xx_HAL_RNG_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +#if defined(RNG) +#if defined(RNG_CR_CONDRST) + +/** @defgroup RNG_Ex RNG_Ex + * @brief RNG Extension HAL module driver + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup RNG_Ex_Exported_Types RNG_Ex Exported Types + * @brief RNG_Ex Exported types + * @{ + */ + +/** + * @brief RNG_Ex Configuration Structure definition + */ + +typedef struct +{ + uint32_t Config1; /*!< Config1 must be a value between 0 and 0x3F */ + uint32_t Config2; /*!< Config2 must be a value between 0 and 0x7 */ + uint32_t Config3; /*!< Config3 must be a value between 0 and 0xF */ + uint32_t ClockDivider; /*!< Clock Divider factor.This parameter can + be a value of @ref RNG_Ex_Clock_Divider_Factor */ + uint32_t NistCompliance; /*!< NIST compliance.This parameter can be a + value of @ref RNG_Ex_NIST_Compliance */ + uint32_t AutoReset; /*!< automatic reset When a noise source error occurs + value of @ref RNG_Ex_Auto_Reset */ + uint32_t HealthTest; /*!< RNG health test control must be a value + between 0x0FFCABFF and 0x00005200 */ +} RNG_ConfigTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup RNG_Ex_Exported_Constants RNG_Ex Exported Constants + * @{ + */ + +/** @defgroup RNG_Ex_Clock_Divider_Factor Value used to configure an internal + * programmable divider acting on the incoming RNG clock + * @{ + */ +#define RNG_CLKDIV_BY_1 (0x00000000UL) /*!< No clock division */ +#define RNG_CLKDIV_BY_2 (RNG_CR_CLKDIV_0) +/*!< 2 RNG clock cycles per internal RNG clock */ +#define RNG_CLKDIV_BY_4 (RNG_CR_CLKDIV_1) +/*!< 4 RNG clock cycles per internal RNG clock */ +#define RNG_CLKDIV_BY_8 (RNG_CR_CLKDIV_1 | RNG_CR_CLKDIV_0) +/*!< 8 RNG clock cycles per internal RNG clock */ +#define RNG_CLKDIV_BY_16 (RNG_CR_CLKDIV_2) +/*!< 16 RNG clock cycles per internal RNG clock */ +#define RNG_CLKDIV_BY_32 (RNG_CR_CLKDIV_2 | RNG_CR_CLKDIV_0) +/*!< 32 RNG clock cycles per internal RNG clock */ +#define RNG_CLKDIV_BY_64 (RNG_CR_CLKDIV_2 | RNG_CR_CLKDIV_1) +/*!< 64 RNG clock cycles per internal RNG clock */ +#define RNG_CLKDIV_BY_128 (RNG_CR_CLKDIV_2 | RNG_CR_CLKDIV_1 | RNG_CR_CLKDIV_0) +/*!< 128 RNG clock cycles per internal RNG clock */ +#define RNG_CLKDIV_BY_256 (RNG_CR_CLKDIV_3) +/*!< 256 RNG clock cycles per internal RNG clock */ +#define RNG_CLKDIV_BY_512 (RNG_CR_CLKDIV_3 | RNG_CR_CLKDIV_0) +/*!< 512 RNG clock cycles per internal RNG clock */ +#define RNG_CLKDIV_BY_1024 (RNG_CR_CLKDIV_3 | RNG_CR_CLKDIV_1) +/*!< 1024 RNG clock cycles per internal RNG clock */ +#define RNG_CLKDIV_BY_2048 (RNG_CR_CLKDIV_3 | RNG_CR_CLKDIV_1 | RNG_CR_CLKDIV_0) +/*!< 2048 RNG clock cycles per internal RNG clock */ +#define RNG_CLKDIV_BY_4096 (RNG_CR_CLKDIV_3 | RNG_CR_CLKDIV_2) +/*!< 4096 RNG clock cycles per internal RNG clock */ +#define RNG_CLKDIV_BY_8192 (RNG_CR_CLKDIV_3 | RNG_CR_CLKDIV_2 | RNG_CR_CLKDIV_0) +/*!< 8192 RNG clock cycles per internal RNG clock */ +#define RNG_CLKDIV_BY_16384 (RNG_CR_CLKDIV_3 | RNG_CR_CLKDIV_2 | RNG_CR_CLKDIV_1) +/*!< 16384 RNG clock cycles per internal RNG clock */ +#define RNG_CLKDIV_BY_32768 (RNG_CR_CLKDIV_3 | RNG_CR_CLKDIV_2 | RNG_CR_CLKDIV_1 | RNG_CR_CLKDIV_0) +/*!< 32768 RNG clock cycles per internal RNG clock */ +/** + * @} + */ + +/** @defgroup RNG_Ex_NIST_Compliance NIST Compliance configuration + * @{ + */ +#define RNG_NIST_COMPLIANT (0x00000000UL) /*!< NIST compliant configuration*/ +#define RNG_CUSTOM_NIST (RNG_CR_NISTC) /*!< Custom NIST configuration */ + +/** + * @} + */ +/** @defgroup RNG_Ex_Auto_Reset Auto Reset configuration + * @{ + */ +#define RNG_ARDIS_ENABLE (0x00000000UL) /*!< automatic reset after seed error*/ +#define RNG_ARDIS_DISABLE (RNG_CR_ARDIS) /*!< Disable automatic reset after seed error */ + +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/** @defgroup RNG_Ex_Private_Types RNG_Ex Private Types + * @{ + */ + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup RNG_Ex_Private_Variables RNG_Ex Private Variables + * @{ + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup RNG_Ex_Private_Constants RNG_Ex Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup RNG_Ex_Private_Macros RNG_Ex Private Macros + * @{ + */ + +#define IS_RNG_CLOCK_DIVIDER(__CLOCK_DIV__) (((__CLOCK_DIV__) == RNG_CLKDIV_BY_1) || \ + ((__CLOCK_DIV__) == RNG_CLKDIV_BY_2) || \ + ((__CLOCK_DIV__) == RNG_CLKDIV_BY_4) || \ + ((__CLOCK_DIV__) == RNG_CLKDIV_BY_8) || \ + ((__CLOCK_DIV__) == RNG_CLKDIV_BY_16) || \ + ((__CLOCK_DIV__) == RNG_CLKDIV_BY_32) || \ + ((__CLOCK_DIV__) == RNG_CLKDIV_BY_64) || \ + ((__CLOCK_DIV__) == RNG_CLKDIV_BY_128) || \ + ((__CLOCK_DIV__) == RNG_CLKDIV_BY_256) || \ + ((__CLOCK_DIV__) == RNG_CLKDIV_BY_512) || \ + ((__CLOCK_DIV__) == RNG_CLKDIV_BY_1024) || \ + ((__CLOCK_DIV__) == RNG_CLKDIV_BY_2048) || \ + ((__CLOCK_DIV__) == RNG_CLKDIV_BY_4096) || \ + ((__CLOCK_DIV__) == RNG_CLKDIV_BY_8192) || \ + ((__CLOCK_DIV__) == RNG_CLKDIV_BY_16384) || \ + ((__CLOCK_DIV__) == RNG_CLKDIV_BY_32768)) + + +#define IS_RNG_NIST_COMPLIANCE(__NIST_COMPLIANCE__) (((__NIST_COMPLIANCE__) == RNG_NIST_COMPLIANT) || \ + ((__NIST_COMPLIANCE__) == RNG_CUSTOM_NIST)) + +#define IS_RNG_CONFIG1(__CONFIG1__) ((__CONFIG1__) <= 0x3FUL) + +#define IS_RNG_CONFIG2(__CONFIG2__) ((__CONFIG2__) <= 0x07UL) + +#define IS_RNG_CONFIG3(__CONFIG3__) ((__CONFIG3__) <= 0xFUL) +#define IS_RNG_ARDIS(__ARDIS__) (((__ARDIS__) == RNG_ARDIS_ENABLE) || \ + ((__ARDIS__) == RNG_ARDIS_DISABLE)) + + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup RNG_Ex_Private_Functions RNG_Ex Private Functions + * @{ + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup RNG_Ex_Exported_Functions + * @{ + */ + +/** @addtogroup RNG_Ex_Exported_Functions_Group1 + * @{ + */ +HAL_StatusTypeDef HAL_RNGEx_SetConfig(RNG_HandleTypeDef *hrng, const RNG_ConfigTypeDef *pConf); +HAL_StatusTypeDef HAL_RNGEx_GetConfig(RNG_HandleTypeDef *hrng, RNG_ConfigTypeDef *pConf); +HAL_StatusTypeDef HAL_RNGEx_LockConfig(RNG_HandleTypeDef *hrng); + +/** + * @} + */ + +/** @addtogroup RNG_Ex_Exported_Functions_Group2 + * @{ + */ +HAL_StatusTypeDef HAL_RNGEx_RecoverSeedError(RNG_HandleTypeDef *hrng); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* RNG_CR_CONDRST */ +#endif /* RNG */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* STM32H5xx_HAL_RNG_EX_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_rtc.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_rtc.h new file mode 100644 index 0000000000..4ce00c7434 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_rtc.h @@ -0,0 +1,980 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_rtc.h + * @author MCD Application Team + * @brief Header file of RTC HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_RTC_H +#define STM32H5xx_HAL_RTC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup RTC RTC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup RTC_Exported_Types RTC Exported Types + * @{ + */ + +/** + * @brief HAL State structures definition + */ +typedef enum +{ + HAL_RTC_STATE_RESET = 0x00U, /*!< RTC not yet initialized or disabled */ + HAL_RTC_STATE_READY = 0x01U, /*!< RTC initialized and ready for use */ + HAL_RTC_STATE_BUSY = 0x02U, /*!< RTC process is ongoing */ + HAL_RTC_STATE_TIMEOUT = 0x03U, /*!< RTC timeout state */ + HAL_RTC_STATE_ERROR = 0x04U /*!< RTC error state */ + +} HAL_RTCStateTypeDef; + +/** + * @brief RTC Configuration Structure definition + */ +typedef struct +{ + uint32_t HourFormat; /*!< Specifies the RTC Hour Format. + This parameter can be a value of @ref RTC_Hour_Formats */ + + uint32_t AsynchPrediv; /*!< Specifies the RTC Asynchronous Predivider value. + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0x7F */ + + uint32_t SynchPrediv; /*!< Specifies the RTC Synchronous Predivider value. + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0x7FFF */ + + uint32_t OutPut; /*!< Specifies which signal will be routed to the RTC output. + This parameter can be a value of @ref RTCEx_Output_selection_Definitions */ + + uint32_t OutPutRemap; /*!< Specifies the remap for RTC output. + This parameter can be a value of @ref RTC_Output_ALARM_OUT_Remap */ + + uint32_t OutPutPolarity; /*!< Specifies the polarity of the output signal. + This parameter can be a value of @ref RTC_Output_Polarity_Definitions */ + + uint32_t OutPutType; /*!< Specifies the RTC Output Pin mode. + This parameter can be a value of @ref RTC_Output_Type_ALARM_OUT */ + + uint32_t OutPutPullUp; /*!< Specifies the RTC Output Pull-Up mode. + This parameter can be a value of @ref RTC_Output_PullUp_ALARM_OUT */ + + uint32_t BinMode; /*!< Specifies the RTC binary mode. + This parameter can be a value of @ref RTCEx_Binary_Mode */ + + uint32_t BinMixBcdU; /*!< Specifies the BCD calendar update if and only if BinMode = RTC_BINARY_MIX. + This parameter can be a value of @ref RTCEx_Binary_mix_BCDU */ +} RTC_InitTypeDef; + +/** + * @brief RTC Time structure definition + */ +typedef struct +{ + uint8_t Hours; /*!< Specifies the RTC Time Hour. + This parameter must be a number between: + Min_Data = 0 and Max_Data = 12 if the RTC_HOURFORMAT_12 is selected. + This parameter must be a number between: + Min_Data = 0 and Max_Data = 23 if the RTC_HOURFORMAT_24 is selected */ + + uint8_t Minutes; /*!< Specifies the RTC Time Minutes. + This parameter must be a number between Min_Data = 0 and Max_Data = 59 */ + + uint8_t Seconds; /*!< Specifies the RTC Time Seconds. + This parameter must be a number between Min_Data = 0 and Max_Data = 59 */ + + uint8_t TimeFormat; /*!< Specifies the RTC AM/PM Time. + This parameter can be a value of @ref RTC_AM_PM_Definitions */ + + uint32_t SubSeconds; /*!< Specifies the RTC_SSR RTC Sub Second register content. + This field is not used by HAL_RTC_SetTime. + If the free running 32 bit counter is not activated (mode binary none) + - This parameter corresponds to a time unit range + between [0-1] Second with [1 Sec / SecondFraction +1] granularity + else + - This parameter corresponds to the free running 32 bit counter. */ + + uint32_t SecondFraction; /*!< Specifies the range or granularity of Sub Second register content + corresponding to Synchronous pre-scaler factor value (PREDIV_S) + This parameter corresponds to a time unit range between [0-1] Second + with [1 Sec / SecondFraction +1] granularity. + This field will be used only by HAL_RTC_GetTime function */ + + uint32_t DayLightSaving; /*!< This interface is deprecated. + To manage Daylight Saving Time, please use HAL_RTC_DST_xxx functions */ + + uint32_t StoreOperation; /*!< This interface is deprecated. + To manage Daylight Saving Time, please use HAL_RTC_DST_xxx functions */ +} RTC_TimeTypeDef; + +/** + * @brief RTC Date structure definition + */ +typedef struct +{ + uint8_t WeekDay; /*!< Specifies the RTC Date WeekDay. + This parameter can be a value of @ref RTC_WeekDay_Definitions */ + + uint8_t Month; /*!< Specifies the RTC Date Month (in BCD format). + This parameter can be a value of @ref RTC_Month_Date_Definitions */ + + uint8_t Date; /*!< Specifies the RTC Date. + This parameter must be a number between Min_Data = 1 and Max_Data = 31 */ + + uint8_t Year; /*!< Specifies the RTC Date Year. + This parameter must be a number between Min_Data = 0 and Max_Data = 99 */ +} RTC_DateTypeDef; + +/** + * @brief RTC Alarm structure definition + */ +typedef struct +{ + RTC_TimeTypeDef AlarmTime; /*!< Specifies the RTC Alarm Time members */ + + uint32_t AlarmMask; /*!< Specifies the RTC Alarm Masks. + This parameter can be a value of @ref RTC_AlarmMask_Definitions */ + + uint32_t AlarmSubSecondMask; /*!< Specifies the RTC Alarm SubSeconds Masks. + if Binary mode is RTC_BINARY_ONLY or is RTC_BINARY_MIX + This parameter can be a value of + @ref RTCEx_Alarm_Sub_Seconds_binary_Masks_Definitions + else if Binary mode is RTC_BINARY_NONE + This parameter can be a value of + @ref RTC_Alarm_Sub_Seconds_BCD_Masks_Definitions */ + + uint32_t BinaryAutoClr; /*!< Clear synchronously counter (RTC_SSR) on binary alarm. + RTC_ALARMSUBSECONDBIN_AUTOCLR_YES must only be used if Binary mode + is RTC_BINARY_ONLY + This parameter can be a value of + @ref RTCEx_Alarm_Sub_Seconds_binary_Clear_Definitions */ + + uint32_t AlarmDateWeekDaySel; /*!< Specifies the RTC Alarm is on Date or WeekDay. + This parameter can be a value of @ref RTC_AlarmDateWeekDay_Definitions */ + + uint8_t AlarmDateWeekDay; /*!< Specifies the RTC Alarm Date/WeekDay. + If the Alarm Date is selected, this parameter must be set to a value + in the 1-31 range. + If the Alarm WeekDay is selected, this parameter can be a value of + @ref RTC_WeekDay_Definitions */ + + uint32_t FlagAutoClr; /*!< Specifies the alarm trigger generation. This feature is meaningful + to avoid any RTC software execution after configuration. + This parameter can be a value of @ref RTC_ALARM_Flag_AutoClear_Definitions */ + + uint32_t Alarm; /*!< Specifies the alarm. + This parameter can be a value of @ref RTC_Alarms_Definitions */ +} RTC_AlarmTypeDef; + +/** + * @brief RTC Handle Structure definition + */ +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) +typedef struct __RTC_HandleTypeDef +#else +typedef struct +#endif /* (USE_HAL_RTC_REGISTER_CALLBACKS) */ +{ + RTC_TypeDef *Instance; /*!< Legacy register base address. Not used anymore, the driver directly uses cmsis base address */ + + RTC_InitTypeDef Init; /*!< RTC required parameters */ + + HAL_LockTypeDef Lock; /*!< RTC locking object */ + + __IO HAL_RTCStateTypeDef State; /*!< Time communication state */ + +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + void (* AlarmAEventCallback)(struct __RTC_HandleTypeDef *hrtc); /*!< RTC Alarm A Event callback */ + void (* AlarmBEventCallback)(struct __RTC_HandleTypeDef *hrtc); /*!< RTC Alarm B Event callback */ + void (* TimeStampEventCallback)(struct __RTC_HandleTypeDef *hrtc); /*!< RTC TimeStamp Event callback */ + void (* WakeUpTimerEventCallback)(struct __RTC_HandleTypeDef *hrtc); /*!< RTC WakeUpTimer Event callback */ + void (* SSRUEventCallback)(struct __RTC_HandleTypeDef *hrtc); /*!< RTC SSRU Event callback */ + void (* Tamper1EventCallback)(struct __RTC_HandleTypeDef *hrtc); /*!< RTC Tamper 1 Event callback */ + void (* Tamper2EventCallback)(struct __RTC_HandleTypeDef *hrtc); /*!< RTC Tamper 2 Event callback */ + void (* Tamper3EventCallback)(struct __RTC_HandleTypeDef *hrtc); /*!< RTC Tamper 3 Event callback */ + void (* Tamper4EventCallback)(struct __RTC_HandleTypeDef *hrtc); /*!< RTC Tamper 4 Event callback */ + void (* Tamper5EventCallback)(struct __RTC_HandleTypeDef *hrtc); /*!< RTC Tamper 5 Event callback */ + void (* Tamper6EventCallback)(struct __RTC_HandleTypeDef *hrtc); /*!< RTC Tamper 6 Event callback */ + void (* Tamper7EventCallback)(struct __RTC_HandleTypeDef *hrtc); /*!< RTC Tamper 7 Event callback */ + void (* Tamper8EventCallback)(struct __RTC_HandleTypeDef *hrtc); /*!< RTC Tamper 8 Event callback */ + void (* InternalTamper1EventCallback)(struct __RTC_HandleTypeDef *hrtc); /*!< RTC Internal Tamper 1 Event callback */ + void (* InternalTamper2EventCallback)(struct __RTC_HandleTypeDef *hrtc); /*!< RTC Internal Tamper 2 Event callback */ + void (* InternalTamper3EventCallback)(struct __RTC_HandleTypeDef *hrtc); /*!< RTC Internal Tamper 3 Event callback */ + void (* InternalTamper4EventCallback)(struct __RTC_HandleTypeDef *hrtc); /*!< RTC Internal Tamper 4 Event callback */ + void (* InternalTamper5EventCallback)(struct __RTC_HandleTypeDef *hrtc); /*!< RTC Internal Tamper 5 Event callback */ + void (* InternalTamper6EventCallback)(struct __RTC_HandleTypeDef *hrtc); /*!< RTC Internal Tamper 6 Event callback */ + void (* InternalTamper7EventCallback)(struct __RTC_HandleTypeDef *hrtc); /*!< RTC Internal Tamper 7 Event callback */ + void (* InternalTamper8EventCallback)(struct __RTC_HandleTypeDef *hrtc); /*!< RTC Internal Tamper 8 Event callback */ + void (* InternalTamper9EventCallback)(struct __RTC_HandleTypeDef *hrtc); /*!< RTC Internal Tamper 9 Event callback */ + void (* InternalTamper11EventCallback)(struct __RTC_HandleTypeDef *hrtc); /*!< RTC Internal Tamper 11 Event callback */ + void (* InternalTamper12EventCallback)(struct __RTC_HandleTypeDef *hrtc); /*!< RTC Internal Tamper 12 Event callback */ + void (* InternalTamper13EventCallback)(struct __RTC_HandleTypeDef *hrtc); /*!< RTC Internal Tamper 13 Event callback */ + void (* InternalTamper15EventCallback)(struct __RTC_HandleTypeDef *hrtc); /*!< RTC Internal Tamper 15 Event callback */ + void (* MspInitCallback)(struct __RTC_HandleTypeDef *hrtc); /*!< RTC Msp Init callback */ + void (* MspDeInitCallback)(struct __RTC_HandleTypeDef *hrtc); /*!< RTC Msp DeInit callback */ + +#endif /* (USE_HAL_RTC_REGISTER_CALLBACKS) */ + +} RTC_HandleTypeDef; + +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) +/** + * @brief HAL RTC Callback ID enumeration definition + */ +typedef enum +{ + HAL_RTC_ALARM_A_EVENT_CB_ID = 0U, /*!< RTC Alarm A Event Callback ID */ + HAL_RTC_ALARM_B_EVENT_CB_ID = 1U, /*!< RTC Alarm B Event Callback ID */ + HAL_RTC_TIMESTAMP_EVENT_CB_ID = 2U, /*!< RTC TimeStamp Event Callback ID */ + HAL_RTC_WAKEUPTIMER_EVENT_CB_ID = 3U, /*!< RTC WakeUp Timer Event Callback ID */ + HAL_RTC_SSRU_EVENT_CB_ID = 4U, /*!< RTC SSRU Event Callback ID */ + HAL_RTC_TAMPER1_EVENT_CB_ID = 5U, /*!< RTC Tamper 1 Callback ID */ + HAL_RTC_TAMPER2_EVENT_CB_ID = 6U, /*!< RTC Tamper 2 Callback ID */ + HAL_RTC_TAMPER3_EVENT_CB_ID = 7U, /*!< RTC Tamper 3 Callback ID */ + HAL_RTC_TAMPER4_EVENT_CB_ID = 8U, /*!< RTC Tamper 4 Callback ID */ + HAL_RTC_TAMPER5_EVENT_CB_ID = 9U, /*!< RTC Tamper 5 Callback ID */ + HAL_RTC_TAMPER6_EVENT_CB_ID = 10U, /*!< RTC Tamper 6 Callback ID */ + HAL_RTC_TAMPER7_EVENT_CB_ID = 11U, /*!< RTC Tamper 7 Callback ID */ + HAL_RTC_TAMPER8_EVENT_CB_ID = 12U, /*!< RTC Tamper 8 Callback ID */ + HAL_RTC_INTERNAL_TAMPER1_EVENT_CB_ID = 13U, /*!< RTC Internal Tamper 1 Callback ID */ + HAL_RTC_INTERNAL_TAMPER2_EVENT_CB_ID = 14U, /*!< RTC Internal Tamper 2 Callback ID */ + HAL_RTC_INTERNAL_TAMPER3_EVENT_CB_ID = 15U, /*!< RTC Internal Tamper 3 Callback ID */ + HAL_RTC_INTERNAL_TAMPER4_EVENT_CB_ID = 16U, /*!< RTC Internal Tamper 4 Callback ID */ + HAL_RTC_INTERNAL_TAMPER5_EVENT_CB_ID = 17U, /*!< RTC Internal Tamper 5 Callback ID */ + HAL_RTC_INTERNAL_TAMPER6_EVENT_CB_ID = 18U, /*!< RTC Internal Tamper 6 Callback ID */ + HAL_RTC_INTERNAL_TAMPER7_EVENT_CB_ID = 19U, /*!< RTC Internal Tamper 7 Callback ID */ + HAL_RTC_INTERNAL_TAMPER8_EVENT_CB_ID = 20U, /*!< RTC Internal Tamper 8 Callback ID */ + HAL_RTC_INTERNAL_TAMPER9_EVENT_CB_ID = 21U, /*!< RTC Internal Tamper 9 Callback ID */ + HAL_RTC_INTERNAL_TAMPER11_EVENT_CB_ID = 22U, /*!< RTC Internal Tamper 11 Callback ID */ + HAL_RTC_INTERNAL_TAMPER12_EVENT_CB_ID = 23U, /*!< RTC Internal Tamper 12 Callback ID */ + HAL_RTC_INTERNAL_TAMPER13_EVENT_CB_ID = 24U, /*!< RTC Internal Tamper 13 Callback ID */ + HAL_RTC_INTERNAL_TAMPER15_EVENT_CB_ID = 25U, /*!< RTC Internal Tamper 15 Callback ID */ + HAL_RTC_MSPINIT_CB_ID = 26U, /*!< RTC Msp Init callback ID */ + HAL_RTC_MSPDEINIT_CB_ID = 27U /*!< RTC Msp DeInit callback ID */ +} HAL_RTC_CallbackIDTypeDef; + +/** + * @brief HAL RTC Callback pointer definition + */ +typedef void (*pRTC_CallbackTypeDef)(RTC_HandleTypeDef *hrtc); /*!< pointer to an RTC callback function */ +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup RTC_Exported_Constants RTC Exported Constants + * @{ + */ + +/** @defgroup RTC_Hour_Formats RTC Hour Formats + * @{ + */ +#define RTC_HOURFORMAT_24 0U +#define RTC_HOURFORMAT_12 RTC_CR_FMT +/** + * @} + */ + +/** @defgroup RTCEx_Output_selection_Definitions RTCEx Output Selection Definition + * @{ + */ +#define RTC_OUTPUT_DISABLE 0U +#define RTC_OUTPUT_ALARMA RTC_CR_OSEL_0 +#define RTC_OUTPUT_ALARMB RTC_CR_OSEL_1 +#define RTC_OUTPUT_WAKEUP RTC_CR_OSEL +#define RTC_OUTPUT_TAMPER RTC_CR_TAMPOE +/** + * @} + */ + +/** @defgroup RTC_Output_Polarity_Definitions RTC Output Polarity Definitions + * @{ + */ +#define RTC_OUTPUT_POLARITY_HIGH 0U +#define RTC_OUTPUT_POLARITY_LOW RTC_CR_POL +/** + * @} + */ + +/** @defgroup RTC_Output_Type_ALARM_OUT RTC Output Type ALARM OUT + * @{ + */ +#define RTC_OUTPUT_TYPE_PUSHPULL 0U +#define RTC_OUTPUT_TYPE_OPENDRAIN RTC_CR_TAMPALRM_TYPE +/** + * @} + */ + +/** @defgroup RTC_Output_PullUp_ALARM_OUT RTC Output Pull-Up ALARM OUT + * @{ + */ +#define RTC_OUTPUT_PULLUP_NONE 0U +#define RTC_OUTPUT_PULLUP_ON RTC_CR_TAMPALRM_PU +/** + * @} + */ + +#if defined(RTC_CR_OUT2EN) +/** @defgroup RTC_Output_ALARM_OUT_Remap RTC Output ALARM OUT Remap + * @{ + */ +#define RTC_OUTPUT_REMAP_NONE 0U +#define RTC_OUTPUT_REMAP_POS1 RTC_CR_OUT2EN +/** + * @} + */ +#endif /* RTC_CR_OUT2EN */ + +/** @defgroup RTC_AM_PM_Definitions RTC AM PM Definitions + * @{ + */ +#define RTC_HOURFORMAT12_AM 0U +#define RTC_HOURFORMAT12_PM 1U +/** + * @} + */ + +/** @defgroup RTC_DayLightSaving_Definitions RTC DayLightSaving Definitions + * @{ + */ +#define RTC_DAYLIGHTSAVING_SUB1H RTC_CR_SUB1H +#define RTC_DAYLIGHTSAVING_ADD1H RTC_CR_ADD1H +#define RTC_DAYLIGHTSAVING_NONE 0U +/** + * @} + */ + +/** @defgroup RTC_StoreOperation_Definitions RTC StoreOperation Definitions + * @{ + */ +#define RTC_STOREOPERATION_RESET 0U +#define RTC_STOREOPERATION_SET RTC_CR_BKP +/** + * @} + */ + +/** @defgroup RTC_Input_parameter_format_definitions RTC Input Parameter Format Definitions + * @{ + */ +#define RTC_FORMAT_BIN 0U +#define RTC_FORMAT_BCD 1U +/** + * @} + */ + +/** @defgroup RTC_Month_Date_Definitions RTC Month Date Definitions + * @{ + */ + +/* Coded in BCD format */ +#define RTC_MONTH_JANUARY ((uint8_t)0x01U) +#define RTC_MONTH_FEBRUARY ((uint8_t)0x02U) +#define RTC_MONTH_MARCH ((uint8_t)0x03U) +#define RTC_MONTH_APRIL ((uint8_t)0x04U) +#define RTC_MONTH_MAY ((uint8_t)0x05U) +#define RTC_MONTH_JUNE ((uint8_t)0x06U) +#define RTC_MONTH_JULY ((uint8_t)0x07U) +#define RTC_MONTH_AUGUST ((uint8_t)0x08U) +#define RTC_MONTH_SEPTEMBER ((uint8_t)0x09U) +#define RTC_MONTH_OCTOBER ((uint8_t)0x10U) +#define RTC_MONTH_NOVEMBER ((uint8_t)0x11U) +#define RTC_MONTH_DECEMBER ((uint8_t)0x12U) + +/** + * @} + */ + +/** @defgroup RTC_WeekDay_Definitions RTC WeekDay Definitions + * @{ + */ +#define RTC_WEEKDAY_MONDAY ((uint8_t)0x01U) +#define RTC_WEEKDAY_TUESDAY ((uint8_t)0x02U) +#define RTC_WEEKDAY_WEDNESDAY ((uint8_t)0x03U) +#define RTC_WEEKDAY_THURSDAY ((uint8_t)0x04U) +#define RTC_WEEKDAY_FRIDAY ((uint8_t)0x05U) +#define RTC_WEEKDAY_SATURDAY ((uint8_t)0x06U) +#define RTC_WEEKDAY_SUNDAY ((uint8_t)0x07U) + +/** + * @} + */ + +/** @defgroup RTC_AlarmDateWeekDay_Definitions RTC AlarmDateWeekDay Definitions + * @{ + */ +#define RTC_ALARMDATEWEEKDAYSEL_DATE 0U +#define RTC_ALARMDATEWEEKDAYSEL_WEEKDAY RTC_ALRMAR_WDSEL + +/** + * @} + */ + +/** @defgroup RTC_AlarmMask_Definitions RTC AlarmMask Definitions + * @{ + */ +#define RTC_ALARMMASK_NONE 0U +#define RTC_ALARMMASK_DATEWEEKDAY RTC_ALRMAR_MSK4 +#define RTC_ALARMMASK_HOURS RTC_ALRMAR_MSK3 +#define RTC_ALARMMASK_MINUTES RTC_ALRMAR_MSK2 +#define RTC_ALARMMASK_SECONDS RTC_ALRMAR_MSK1 +#define RTC_ALARMMASK_ALL (RTC_ALARMMASK_DATEWEEKDAY | RTC_ALARMMASK_HOURS | \ + RTC_ALARMMASK_MINUTES | RTC_ALARMMASK_SECONDS) + +/** + * @} + */ + +/** @defgroup RTC_Alarms_Definitions RTC Alarms Definitions + * @{ + */ +#define RTC_ALARM_A RTC_CR_ALRAE +#define RTC_ALARM_B RTC_CR_ALRBE + +/** + * @} + */ +/** @defgroup RTC_ALARM_Flag_AutoClear_Definitions RTC Alarms Flag Auto Clear Definitions + * @{ + */ +#define ALARM_FLAG_AUTOCLR_ENABLE 1U +#define ALARM_FLAG_AUTOCLR_DISABLE 0U +/** + * @} + */ + +/** @defgroup RTC_Alarm_Sub_Seconds_BCD_Masks_Definitions RTC Alarm Sub Seconds BCD Masks Definitions + * In BCD mode (BIN=00) the overflow bits of the synchronous counter (bits 31:15) are never compared. + * @{ + */ +#define RTC_ALARMSUBSECONDMASK_ALL 0U /*!< All Alarm SS fields are masked. There is no comparison on sub seconds for Alarm */ +#define RTC_ALARMSUBSECONDMASK_SS14_1 RTC_ALRMASSR_MASKSS_0 /*!< SS[14:1] not used in Alarmcomparison. Only SS[0] is compared */ +#define RTC_ALARMSUBSECONDMASK_SS14_2 RTC_ALRMASSR_MASKSS_1 /*!< SS[14:2] not used in Alarm comparison. Only SS[1:0] are compared */ +#define RTC_ALARMSUBSECONDMASK_SS14_3 (RTC_ALRMASSR_MASKSS_0 | RTC_ALRMASSR_MASKSS_1) /*!< SS[14:3] not used in Alarm comparison. Only SS[2:0] are compared */ +#define RTC_ALARMSUBSECONDMASK_SS14_4 RTC_ALRMASSR_MASKSS_2 /*!< SS[14:4] not used in Alarm comparison. Only SS[3:0] are compared */ +#define RTC_ALARMSUBSECONDMASK_SS14_5 (RTC_ALRMASSR_MASKSS_0 | RTC_ALRMASSR_MASKSS_2) /*!< SS[14:5] not used in Alarm comparison. Only SS[4:0] are compared */ +#define RTC_ALARMSUBSECONDMASK_SS14_6 (RTC_ALRMASSR_MASKSS_1 | RTC_ALRMASSR_MASKSS_2) /*!< SS[14:6] not used in Alarm comparison. Only SS[5:0] are compared */ +#define RTC_ALARMSUBSECONDMASK_SS14_7 (RTC_ALRMASSR_MASKSS_0 | RTC_ALRMASSR_MASKSS_1 | RTC_ALRMASSR_MASKSS_2) /*!< SS[14:7] not used in Alarm comparison. Only SS[6:0] are compared */ +#define RTC_ALARMSUBSECONDMASK_SS14_8 RTC_ALRMASSR_MASKSS_3 /*!< SS[14:8] not used in Alarm comparison. Only SS[7:0] are compared */ +#define RTC_ALARMSUBSECONDMASK_SS14_9 (RTC_ALRMASSR_MASKSS_0 | RTC_ALRMASSR_MASKSS_3) /*!< SS[14:9] not used in Alarm comparison. Only SS[8:0] are compared */ +#define RTC_ALARMSUBSECONDMASK_SS14_10 (RTC_ALRMASSR_MASKSS_1 | RTC_ALRMASSR_MASKSS_3) /*!< SS[14:10] not used in Alarm comparison. Only SS[9:0] are compared */ +#define RTC_ALARMSUBSECONDMASK_SS14_11 (RTC_ALRMASSR_MASKSS_0 | RTC_ALRMASSR_MASKSS_1 | RTC_ALRMASSR_MASKSS_3) /*!< SS[14:11] not used in Alarm comparison. Only SS[10:0] are compared */ +#define RTC_ALARMSUBSECONDMASK_SS14_12 (RTC_ALRMASSR_MASKSS_2 | RTC_ALRMASSR_MASKSS_3) /*!< SS[14:12] not used in Alarm comparison.Only SS[11:0] are compared */ +#define RTC_ALARMSUBSECONDMASK_SS14_13 (RTC_ALRMASSR_MASKSS_0 | RTC_ALRMASSR_MASKSS_2 | RTC_ALRMASSR_MASKSS_3) /*!< SS[14:13] not used in Alarm comparison. Only SS[12:0] are compared */ +#define RTC_ALARMSUBSECONDMASK_SS14 (RTC_ALRMASSR_MASKSS_1 | RTC_ALRMASSR_MASKSS_2 | RTC_ALRMASSR_MASKSS_3) /*!< SS[14] not used in Alarm comparison. Only SS[13:0] are compared */ +#define RTC_ALARMSUBSECONDMASK_NONE RTC_ALRMASSR_MASKSS /*!< SS[14:0] are compared and must match to activate alarm */ +/** + * @} + */ + +/** @defgroup RTC_Interrupts_Definitions RTC Interrupts Definitions + * @{ + */ +#define RTC_IT_TS RTC_CR_TSIE /*!< Enable Timestamp Interrupt */ +#define RTC_IT_WUT RTC_CR_WUTIE /*!< Enable Wakeup timer Interrupt */ +#define RTC_IT_SSRU RTC_CR_SSRUIE /*!< Enable SSR Underflow Interrupt */ +#define RTC_IT_ALRA RTC_CR_ALRAIE /*!< Enable Alarm A Interrupt */ +#define RTC_IT_ALRB RTC_CR_ALRBIE /*!< Enable Alarm B Interrupt */ +/** + * @} + */ + +/** @defgroup RTC_Flag_Mask RTC Flag Mask (5bits) for __HAL_RTC_GET_FLAG() + * @{ + */ +#define RTC_FLAG_MASK 0x001FU /*!< RTC flags mask (5bits) */ +/** + * @} + */ + +/** @defgroup RTC_Flags_Definitions RTC Flags Definitions + * Elements values convention: 000000XX000YYYYYb + * - YYYYY : Interrupt flag position in the XX register (5bits) + * - XX : Interrupt status register (2bits) + * - 01: ICSR register + * - 10: SR or SCR or MISR or SMISR registers + * @{ + */ +#define RTC_FLAG_RECALPF (0x00000100U | RTC_ICSR_RECALPF_Pos) /*!< Recalibration pending flag */ +#define RTC_FLAG_INITF (0x00000100U | RTC_ICSR_INITF_Pos) /*!< Initialization flag */ +#define RTC_FLAG_RSF (0x00000100U | RTC_ICSR_RSF_Pos) /*!< Registers synchronization flag */ +#define RTC_FLAG_INITS (0x00000100U | RTC_ICSR_INITS_Pos) /*!< Initialization status flag */ +#define RTC_FLAG_SHPF (0x00000100U | RTC_ICSR_SHPF_Pos) /*!< Shift operation pending flag */ +#define RTC_FLAG_WUTWF (0x00000100U | RTC_ICSR_WUTWF_Pos) /*!< Wakeup timer write flag */ +#define RTC_FLAG_SSRUF (0x00000200U | RTC_SR_SSRUF_Pos) /*!< Clear SSR underflow flag */ +#define RTC_FLAG_ITSF (0x00000200U | RTC_SR_ITSF_Pos) /*!< Clear Internal Time-stamp flag */ +#define RTC_FLAG_TSOVF (0x00000200U | RTC_SR_TSOVF_Pos) /*!< Clear Time-stamp overflow flag */ +#define RTC_FLAG_TSF (0x00000200U | RTC_SR_TSF_Pos) /*!< Clear Time-stamp flag */ +#define RTC_FLAG_WUTF (0x00000200U | RTC_SR_WUTF_Pos) /*!< Clear Wakeup timer flag */ +#define RTC_FLAG_ALRBF (0x00000200U | RTC_SR_ALRBF_Pos) /*!< Clear Alarm B flag */ +#define RTC_FLAG_ALRAF (0x00000200U | RTC_SR_ALRAF_Pos) /*!< Clear Alarm A flag */ +/** + * @} + */ + +/** @defgroup RTC_Clear_Flags_Definitions RTC Clear Flags Definitions + * @{ + */ +#define RTC_CLEAR_SSRUF RTC_SCR_CSSRUF /*!< Clear SSR underflow flag */ +#define RTC_CLEAR_ITSF RTC_SCR_CITSF /*!< Clear Internal Time-stamp flag */ +#define RTC_CLEAR_TSOVF RTC_SCR_CTSOVF /*!< Clear Time-stamp overflow flag */ +#define RTC_CLEAR_TSF RTC_SCR_CTSF /*!< Clear Time-stamp flag */ +#define RTC_CLEAR_WUTF RTC_SCR_CWUTF /*!< Clear Wakeup timer flag */ +#define RTC_CLEAR_ALRBF RTC_SCR_CALRBF /*!< Clear Alarm B flag */ +#define RTC_CLEAR_ALRAF RTC_SCR_CALRAF /*!< Clear Alarm A flag */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup RTC_Exported_Macros RTC Exported Macros + * @{ + */ + +/** @brief Reset RTC handle state + * @param __HANDLE__ RTC handle. + * @retval None + */ +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) +#define __HAL_RTC_RESET_HANDLE_STATE(__HANDLE__) do{\ + (__HANDLE__)->State = HAL_RTC_STATE_RESET;\ + (__HANDLE__)->MspInitCallback = NULL;\ + (__HANDLE__)->MspDeInitCallback = NULL;\ + }while(0) +#else +#define __HAL_RTC_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_RTC_STATE_RESET) +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + +/** + * @brief Disable the write protection for RTC registers. + * @param __HANDLE__ specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_WRITEPROTECTION_DISABLE(__HANDLE__) \ + do{ \ + RTC->WPR = 0xCAU; \ + RTC->WPR = 0x53U; \ + } while(0U) + +/** + * @brief Enable the write protection for RTC registers. + * @param __HANDLE__ specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_WRITEPROTECTION_ENABLE(__HANDLE__) \ + do{ \ + RTC->WPR = 0xFFU; \ + } while(0U) + +/** + * @brief Add 1 hour (summer time change). + * @note This interface is deprecated. + * To manage Daylight Saving Time, please use HAL_RTC_DST_xxx functions + * @param __HANDLE__ specifies the RTC handle. + * @param __BKP__ Backup + * This parameter can be: + * @arg @ref RTC_STOREOPERATION_RESET + * @arg @ref RTC_STOREOPERATION_SET + * @retval None + */ +#define __HAL_RTC_DAYLIGHT_SAVING_TIME_ADD1H(__HANDLE__, __BKP__) \ + do { \ + __HAL_RTC_WRITEPROTECTION_DISABLE(__HANDLE__); \ + SET_BIT(RTC->CR, RTC_CR_ADD1H); \ + MODIFY_REG(RTC->CR, RTC_CR_BKP , (__BKP__)); \ + __HAL_RTC_WRITEPROTECTION_ENABLE(__HANDLE__); \ + } while(0); + +/** + * @brief Subtract 1 hour (winter time change). + * @note This interface is deprecated. + * To manage Daylight Saving Time, please use HAL_RTC_DST_xxx functions + * @param __HANDLE__ specifies the RTC handle. + * @param __BKP__ Backup + * This parameter can be: + * @arg @ref RTC_STOREOPERATION_RESET + * @arg @ref RTC_STOREOPERATION_SET + * @retval None + */ +#define __HAL_RTC_DAYLIGHT_SAVING_TIME_SUB1H(__HANDLE__, __BKP__) \ + do { \ + __HAL_RTC_WRITEPROTECTION_DISABLE(__HANDLE__); \ + SET_BIT(RTC->CR, RTC_CR_SUB1H); \ + MODIFY_REG(RTC->CR, RTC_CR_BKP , (__BKP__)); \ + __HAL_RTC_WRITEPROTECTION_ENABLE(__HANDLE__); \ + } while(0); + +/** + * @brief Enable the RTC ALARMA peripheral. + * @param __HANDLE__ specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_ALARMA_ENABLE(__HANDLE__) (RTC->CR |= (RTC_CR_ALRAE)) + +/** + * @brief Disable the RTC ALARMA peripheral. + * @param __HANDLE__ specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_ALARMA_DISABLE(__HANDLE__) (RTC->CR &= ~(RTC_CR_ALRAE)) + +/** + * @brief Enable the RTC ALARMB peripheral. + * @param __HANDLE__ specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_ALARMB_ENABLE(__HANDLE__) (RTC->CR |= (RTC_CR_ALRBE)) + +/** + * @brief Disable the RTC ALARMB peripheral. + * @param __HANDLE__ specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_ALARMB_DISABLE(__HANDLE__) (RTC->CR &= ~(RTC_CR_ALRBE)) + +/** + * @brief Enable the RTC Alarm interrupt. + * @param __HANDLE__ specifies the RTC handle. + * @param __INTERRUPT__ specifies the RTC Alarm interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg @ref RTC_IT_ALRA Alarm A interrupt + * @arg @ref RTC_IT_ALRB Alarm B interrupt + * @retval None + */ +#define __HAL_RTC_ALARM_ENABLE_IT(__HANDLE__, __INTERRUPT__) (RTC->CR |= (__INTERRUPT__)) + +/** + * @brief Disable the RTC Alarm interrupt. + * @param __HANDLE__ specifies the RTC handle. + * @param __INTERRUPT__ specifies the RTC Alarm interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg @ref RTC_IT_ALRA Alarm A interrupt + * @arg @ref RTC_IT_ALRB Alarm B interrupt + * @retval None + */ +#define __HAL_RTC_ALARM_DISABLE_IT(__HANDLE__, __INTERRUPT__) (RTC->CR &= ~(__INTERRUPT__)) + +/** + * @brief Check whether the specified RTC Alarm interrupt has occurred or not. + * @param __HANDLE__ specifies the RTC handle. + * @param __INTERRUPT__ specifies the RTC Alarm interrupt sources to check. + * This parameter can be: + * @arg @ref RTC_IT_ALRA Alarm A interrupt + * @arg @ref RTC_IT_ALRB Alarm B interrupt + * @retval None + */ +#define __HAL_RTC_ALARM_GET_IT(__HANDLE__, __INTERRUPT__) ((((RTC->MISR)& ((__INTERRUPT__)>> 12U)) != 0U) \ + ? 1UL : 0UL) + +/** + * @brief Check whether the specified RTC Alarm interrupt has been enabled or not. + * @param __HANDLE__ specifies the RTC handle. + * @param __INTERRUPT__ specifies the RTC Alarm interrupt sources to check. + * This parameter can be: + * @arg @ref RTC_IT_ALRA Alarm A interrupt + * @arg @ref RTC_IT_ALRB Alarm B interrupt + * @retval None + */ +#define __HAL_RTC_ALARM_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((RTC->CR) & (__INTERRUPT__)) != 0U) \ + ? 1UL : 0UL) + +/** + * @brief Get the selected RTC Alarms flag status. + * @param __HANDLE__ specifies the RTC handle. + * @param __FLAG__ specifies the RTC Alarm Flag sources to check. + * This parameter can be: + * @arg @ref RTC_FLAG_ALRAF + * @arg @ref RTC_FLAG_ALRBF + * @retval None + */ +#define __HAL_RTC_ALARM_GET_FLAG(__HANDLE__, __FLAG__) (__HAL_RTC_GET_FLAG((__HANDLE__), (__FLAG__))) + +/** + * @brief Clear the RTC Alarms pending flags. + * @param __HANDLE__ specifies the RTC handle. + * @param __FLAG__ specifies the RTC Alarm Flag sources to clear. + * This parameter can be: + * @arg @ref RTC_FLAG_ALRAF + * @arg @ref RTC_FLAG_ALRBF + * @retval None + */ +#define __HAL_RTC_ALARM_CLEAR_FLAG(__HANDLE__, __FLAG__) (((__FLAG__) == RTC_FLAG_ALRAF) \ + ? ((RTC->SCR = (RTC_CLEAR_ALRAF))) :\ + (RTC->SCR = (RTC_CLEAR_ALRBF))) + +/** + * @brief Check whether if the RTC Calendar is initialized. + * @param __HANDLE__ specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_IS_CALENDAR_INITIALIZED(__HANDLE__) ((((RTC->ICSR) & (RTC_ICSR_INITS)) == RTC_ICSR_INITS) ? 1U : 0U) + +/** + * @} + */ + +/* Include RTC HAL Extended module */ +#include "stm32h5xx_hal_rtc_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup RTC_Exported_Functions RTC Exported Functions + * @{ + */ + +/** @defgroup RTC_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ +/* Initialization and de-initialization functions ****************************/ +HAL_StatusTypeDef HAL_RTC_Init(RTC_HandleTypeDef *hrtc); +HAL_StatusTypeDef HAL_RTC_DeInit(RTC_HandleTypeDef *hrtc); + +void HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc); +void HAL_RTC_MspDeInit(RTC_HandleTypeDef *hrtc); + +/* Callbacks Register/UnRegister functions ***********************************/ +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) +HAL_StatusTypeDef HAL_RTC_RegisterCallback(RTC_HandleTypeDef *hrtc, HAL_RTC_CallbackIDTypeDef CallbackID, + pRTC_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_RTC_UnRegisterCallback(RTC_HandleTypeDef *hrtc, HAL_RTC_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup RTC_Exported_Functions_Group2 RTC Time and Date functions + * @{ + */ +/* RTC Time and Date functions ************************************************/ +HAL_StatusTypeDef HAL_RTC_SetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format); +HAL_StatusTypeDef HAL_RTC_GetTime(const RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format); +HAL_StatusTypeDef HAL_RTC_SetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format); +HAL_StatusTypeDef HAL_RTC_GetDate(const RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format); +void HAL_RTC_DST_Add1Hour(const RTC_HandleTypeDef *hrtc); +void HAL_RTC_DST_Sub1Hour(const RTC_HandleTypeDef *hrtc); +void HAL_RTC_DST_SetStoreOperation(const RTC_HandleTypeDef *hrtc); +void HAL_RTC_DST_ClearStoreOperation(const RTC_HandleTypeDef *hrtc); +uint32_t HAL_RTC_DST_ReadStoreOperation(const RTC_HandleTypeDef *hrtc); +/** + * @} + */ + +/** @defgroup RTC_Exported_Functions_Group3 RTC Alarm functions + * @{ + */ +/* RTC Alarm functions ********************************************************/ +HAL_StatusTypeDef HAL_RTC_SetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format); +HAL_StatusTypeDef HAL_RTC_SetAlarm_IT(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format); +HAL_StatusTypeDef HAL_RTC_DeactivateAlarm(RTC_HandleTypeDef *hrtc, uint32_t Alarm); +HAL_StatusTypeDef HAL_RTC_GetAlarm(const RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Alarm, + uint32_t Format); +void HAL_RTC_AlarmIRQHandler(RTC_HandleTypeDef *hrtc); +HAL_StatusTypeDef HAL_RTC_PollForAlarmAEvent(const RTC_HandleTypeDef *hrtc, uint32_t Timeout); +void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc); + +/** + * @} + */ + +/** @defgroup RTC_Exported_Functions_Group4 Peripheral Control functions + * @{ + */ +/* Peripheral Control functions ***********************************************/ +HAL_StatusTypeDef HAL_RTC_WaitForSynchro(RTC_HandleTypeDef *hrtc); +/** + * @} + */ + +/** @defgroup RTC_Exported_Functions_Group5 Peripheral State functions + * @{ + */ +/* Peripheral State functions *************************************************/ +HAL_RTCStateTypeDef HAL_RTC_GetState(const RTC_HandleTypeDef *hrtc); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup RTC_Private_Constants RTC Private Constants + * @{ + */ +/* Masks Definition */ +#define RTC_TR_RESERVED_MASK (RTC_TR_PM | RTC_TR_HT | RTC_TR_HU | \ + RTC_TR_MNT | RTC_TR_MNU| RTC_TR_ST | \ + RTC_TR_SU) +#define RTC_DR_RESERVED_MASK (RTC_DR_YT | RTC_DR_YU | RTC_DR_WDU | \ + RTC_DR_MT | RTC_DR_MU | RTC_DR_DT | \ + RTC_DR_DU) +#define RTC_INIT_MASK 0xFFFFFFFFU +#define RTC_RSF_MASK (~(RTC_ICSR_INIT | RTC_ICSR_RSF)) + +#define RTC_TIMEOUT_VALUE 1000U + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup RTC_Private_Macros RTC Private Macros + * @{ + */ + +/** @defgroup RTC_IS_RTC_Definitions RTC Private macros to check input parameters + * @{ + */ +#if defined(RTC_CR_OSEL) +#define IS_RTC_OUTPUT(OUTPUT) (((OUTPUT) == RTC_OUTPUT_DISABLE) || \ + ((OUTPUT) == RTC_OUTPUT_ALARMA) || \ + ((OUTPUT) == RTC_OUTPUT_ALARMB) || \ + ((OUTPUT) == RTC_OUTPUT_WAKEUP) || \ + ((OUTPUT) == RTC_OUTPUT_TAMPER)) +#endif /* RTC_CR_OSEL */ + +#define IS_RTC_HOUR_FORMAT(FORMAT) (((FORMAT) == RTC_HOURFORMAT_12) || \ + ((FORMAT) == RTC_HOURFORMAT_24)) + +#define IS_RTC_OUTPUT_POL(POL) (((POL) == RTC_OUTPUT_POLARITY_HIGH) || \ + ((POL) == RTC_OUTPUT_POLARITY_LOW)) + +#define IS_RTC_OUTPUT_TYPE(TYPE) (((TYPE) == RTC_OUTPUT_TYPE_OPENDRAIN) || \ + ((TYPE) == RTC_OUTPUT_TYPE_PUSHPULL)) + +#define IS_RTC_OUTPUT_PULLUP(TYPE) (((TYPE) == RTC_OUTPUT_PULLUP_NONE) || \ + ((TYPE) == RTC_OUTPUT_PULLUP_ON)) + +#if defined(RTC_CR_OUT2EN) +#define IS_RTC_OUTPUT_REMAP(REMAP) (((REMAP) == RTC_OUTPUT_REMAP_NONE) || \ + ((REMAP) == RTC_OUTPUT_REMAP_POS1)) +#endif /* RTC_CR_OUT2EN */ + +#define IS_RTC_HOURFORMAT12(PM) (((PM) == RTC_HOURFORMAT12_AM) || \ + ((PM) == RTC_HOURFORMAT12_PM)) + +#define IS_RTC_DAYLIGHT_SAVING(SAVE) (((SAVE) == RTC_DAYLIGHTSAVING_SUB1H) || \ + ((SAVE) == RTC_DAYLIGHTSAVING_ADD1H) || \ + ((SAVE) == RTC_DAYLIGHTSAVING_NONE)) + +#define IS_RTC_STORE_OPERATION(OPERATION) (((OPERATION) == RTC_STOREOPERATION_RESET) || \ + ((OPERATION) == RTC_STOREOPERATION_SET)) + +#define IS_RTC_FORMAT(FORMAT) (((FORMAT) == RTC_FORMAT_BIN) || \ + ((FORMAT) == RTC_FORMAT_BCD)) + +#define IS_RTC_YEAR(YEAR) ((YEAR) <= 99U) + +#define IS_RTC_MONTH(MONTH) (((MONTH) >= 1U) && ((MONTH) <= 12U)) + +#define IS_RTC_DATE(DATE) (((DATE) >= 1U) && ((DATE) <= 31U)) + +#define IS_RTC_WEEKDAY(WEEKDAY) (((WEEKDAY) == RTC_WEEKDAY_MONDAY) || \ + ((WEEKDAY) == RTC_WEEKDAY_TUESDAY) || \ + ((WEEKDAY) == RTC_WEEKDAY_WEDNESDAY) || \ + ((WEEKDAY) == RTC_WEEKDAY_THURSDAY) || \ + ((WEEKDAY) == RTC_WEEKDAY_FRIDAY) || \ + ((WEEKDAY) == RTC_WEEKDAY_SATURDAY) || \ + ((WEEKDAY) == RTC_WEEKDAY_SUNDAY)) + +#define IS_RTC_ALARM_DATE_WEEKDAY_DATE(DATE) (((DATE) > 0U) && ((DATE) <= 31U)) + +#define IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(WEEKDAY) (((WEEKDAY) == RTC_WEEKDAY_MONDAY) || \ + ((WEEKDAY) == RTC_WEEKDAY_TUESDAY) || \ + ((WEEKDAY) == RTC_WEEKDAY_WEDNESDAY) || \ + ((WEEKDAY) == RTC_WEEKDAY_THURSDAY) || \ + ((WEEKDAY) == RTC_WEEKDAY_FRIDAY) || \ + ((WEEKDAY) == RTC_WEEKDAY_SATURDAY) || \ + ((WEEKDAY) == RTC_WEEKDAY_SUNDAY)) + +#define IS_RTC_ALARM_DATE_WEEKDAY_SEL(SEL) (((SEL) == RTC_ALARMDATEWEEKDAYSEL_DATE) || \ + ((SEL) == RTC_ALARMDATEWEEKDAYSEL_WEEKDAY)) + +#define IS_RTC_ALARM_MASK(MASK) (((MASK) & ~(RTC_ALARMMASK_ALL)) == 0UL) + +#define IS_RTC_ALARM(ALARM) (((ALARM) == RTC_ALARM_A) || \ + ((ALARM) == RTC_ALARM_B)) + +#define IS_RTC_ALARM_SUB_SECOND_VALUE(VALUE) ((VALUE) <= RTC_ALRMASSR_SS) + +#define IS_RTC_ALARM_SUB_SECOND_MASK(MASK) (((MASK) == 0UL) || \ + (((MASK) >= RTC_ALARMSUBSECONDMASK_SS14_1) && \ + ((MASK) <= RTC_ALARMSUBSECONDMASK_NONE))) + +#define IS_RTC_ASYNCH_PREDIV(PREDIV) ((PREDIV) <= (RTC_PRER_PREDIV_A >> RTC_PRER_PREDIV_A_Pos)) + +#define IS_RTC_SYNCH_PREDIV(PREDIV) ((PREDIV) <= (RTC_PRER_PREDIV_S >> RTC_PRER_PREDIV_S_Pos)) + +#define IS_RTC_HOUR12(HOUR) (((HOUR) > 0U) && ((HOUR) <= 12U)) + +#define IS_RTC_HOUR24(HOUR) ((HOUR) <= 23U) + +#define IS_RTC_MINUTES(MINUTES) ((MINUTES) <= 59U) + +#define IS_RTC_SECONDS(SECONDS) ((SECONDS) <= 59U) + +/** + * @} + */ + +/** + * @} + */ + +/* Private functions -------------------------------------------------------------*/ +/** @defgroup RTC_Private_Functions RTC Private Functions + * @{ + */ +HAL_StatusTypeDef RTC_EnterInitMode(RTC_HandleTypeDef *hrtc); +HAL_StatusTypeDef RTC_ExitInitMode(RTC_HandleTypeDef *hrtc); +uint8_t RTC_ByteToBcd2(uint8_t Value); +uint8_t RTC_Bcd2ToByte(uint8_t Value); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_RTC_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_rtc_ex.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_rtc_ex.h new file mode 100644 index 0000000000..67223a2cc5 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_rtc_ex.h @@ -0,0 +1,1890 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_rtc_ex.h + * @author MCD Application Team + * @brief Header file of RTC HAL Extended module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_RTC_EX_H +#define STM32H5xx_HAL_RTC_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup RTCEx RTCEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup RTCEx_Exported_Types RTCEx Exported Types + * @{ + */ + +/** @defgroup RTCEx_Tamper_structure_definition RTCEx Tamper structure definition + * @{ + */ +typedef struct +{ + uint32_t Tamper; /*!< Specifies the Tamper Pin. + This parameter can be a value of @ref RTCEx_Tamper_Pins */ + + uint32_t Trigger; /*!< Specifies the Tamper Trigger. + This parameter can be a value of @ref RTCEx_Tamper_Trigger */ + + uint32_t NoErase; /*!< Specifies the Tamper no erase mode. + This parameter can be a value of @ref RTCEx_Tamper_EraseBackUp */ + + uint32_t MaskFlag; /*!< Specifies the Tamper Flag masking. + This parameter can be a value of @ref RTCEx_Tamper_MaskFlag */ + + uint32_t Filter; /*!< Specifies the TAMP Filter Tamper. + This parameter can be a value of @ref RTCEx_Tamper_Filter */ + + uint32_t SamplingFrequency; /*!< Specifies the sampling frequency. + This parameter can be a value of + @ref RTCEx_Tamper_Sampling_Frequencies */ + + uint32_t PrechargeDuration; /*!< Specifies the Precharge Duration. + This parameter can be a value of + @ref RTCEx_Tamper_Pin_Precharge_Duration */ + + uint32_t TamperPullUp; /*!< Specifies the Tamper PullUp. + This parameter can be a value of @ref RTCEx_Tamper_Pull_UP */ + + uint32_t TimeStampOnTamperDetection; /*!< Specifies the TimeStampOnTamperDetection. + This parameter can be a value of + @ref RTCEx_Tamper_TimeStampOnTamperDetection */ +} RTC_TamperTypeDef; +/** + * @} + */ + + +/** @defgroup RTCEx_Active_Seed_Size Seed size Definitions + * @{ + */ +#define RTC_ATAMP_SEED_NB_UINT32 4U +/** + * @} + */ + + +/** @defgroup RTCEx_ActiveTamper_structures_definition RTCEx Active Tamper structures definitions + * @{ + */ +typedef struct +{ + uint32_t Enable; /*!< Specifies the Tamper input is active. + This parameter can be a value of @ref RTCEx_ActiveTamper_Enable */ + + uint32_t Interrupt; /*!< Specifies the interrupt mode. + This parameter can be a value of @ref RTCEx_ActiveTamper_Interrupt */ + + uint32_t Output; /*!< Specifies the TAMP output to be compared with. + The same output can be used for several tamper inputs. + This parameter can be a value of @ref RTCEx_ActiveTamper_Sel */ + + uint32_t NoErase; /*!< Specifies the Tamper no erase mode. + This parameter can be a value of @ref RTCEx_Tamper_EraseBackUp */ + + uint32_t MaskFlag; /*!< Specifies the Tamper Flag masking. + This parameter can be a value of @ref RTCEx_Tamper_MaskFlag */ + +} RTC_ATampInputTypeDef; + + +typedef struct +{ + uint32_t ActiveFilter; /*!< Specifies the Active tamper filter enable. + This parameter can be a value of @ref RTCEx_ActiveTamper_Filter */ + + uint32_t ActiveAsyncPrescaler; /*!< Specifies the Active Tamper asynchronous Prescaler clock. + This parameter can be a value of + @ref RTCEx_ActiveTamper_Async_prescaler */ + + uint32_t TimeStampOnTamperDetection; /*!< Specifies the timeStamp on tamper detection. + This parameter can be a value of + @ref RTCEx_Tamper_TimeStampOnTamperDetection */ + + uint32_t ActiveOutputChangePeriod; /*!< Specifies the Active Tamper output change period. + This parameter can be a value from 0 to 7 */ + + uint32_t Seed[RTC_ATAMP_SEED_NB_UINT32]; + /*!< Specifies the RNG Seed value. + This parameter is an array of value from 0 to 0xFFFFFFFF */ + + RTC_ATampInputTypeDef TampInput[RTC_TAMP_NB]; + /*!< Specifies configuration of all active tampers. + The index of TampInput[RTC_TAMP_NB] can be a value of RTCEx_ActiveTamper_Sel */ +} RTC_ActiveTampersTypeDef; +/** + * @} + */ + +/** @defgroup RTCEx_Internal_Tamper_structure_definition RTCEx Internal Tamper structure definition + * @{ + */ +typedef struct +{ + uint32_t IntTamper; /*!< Specifies the Internal Tamper Pin. + This parameter can be a value of @ref RTCEx_Internal_Tamper_Pins */ + + uint32_t TimeStampOnTamperDetection; /*!< Specifies the TimeStampOnTamperDetection. + This parameter can be a value of + @ref RTCEx_Tamper_TimeStampOnTamperDetection */ + + uint32_t NoErase; /*!< Specifies the internal Tamper no erase mode. + This parameter can be a value of @ref RTCEx_Tamper_EraseBackUp */ + +} RTC_InternalTamperTypeDef; +/** + * @} + */ + +/** @defgroup RTCEx_Secure_State_structure_definition RTCEx Secure structure definition + * @{ + */ +typedef struct +{ + uint32_t rtcSecureFull; /*!< Specifies If the RTC is fully secure or not. + This parameter can be a value of @ref RTCEx_RTC_Secure_Full */ + + uint32_t rtcNonSecureFeatures; /*!< Specifies the non-secure features. + This parameter is only relevant if RTC is not fully secure + (rtcSecureFull == RTC_SECURE_FULL_NO). + This parameter can be a combination of + @ref RTCEx_RTC_NonSecure_Features */ + + uint32_t tampSecureFull; /*!< Specifies If the TAMP is fully secure or not execpt monotonic counters + and BackUp registers. + This parameter can be a value of @ref RTCEx_TAMP_Secure_Full */ + + uint32_t backupRegisterStartZone2; /*!< Specifies the backup register start zone 2. + Zone 1 : read secure write secure. + Zone 2 : read non-secure write secure. + This parameter can be RTC_BKP_DRx where x can be from 0 to 31 to specify + the register. + Warning : this parameter is shared with RTC_PrivilegeStateTypeDef */ + + uint32_t backupRegisterStartZone3; /*!< Specifies the backup register start zone 3. + Zone 3 : read non-secure write non-secure. + This parameter can be RTC_BKP_DRx where x can be from 0 to 31 to + specify the register. + Warning : this parameter is shared with RTC_PrivilegeStateTypeDef */ + + uint32_t MonotonicCounterSecure; /*!< Specifies If the monotonic counter is secure or not. + This parameter can be a value of + @ref RTCEx_TAMP_Monotonic_Counter_Secure */ +} RTC_SecureStateTypeDef; +/** + * @} + */ + +/** @defgroup RTCEx_Privilege_State_structure_definition RTCEx Privilege structure definition + * @{ + */ +typedef struct +{ + uint32_t rtcPrivilegeFull; /*!< Specifies If the RTC is fully privileged or not. + This parameter can be a value of @ref RTCEx_RTC_Privilege_Full */ + + uint32_t rtcPrivilegeFeatures; /*!< Specifies the privileged features. + This parameter is only relevant if RTC is not fully privileged + (rtcPrivilegeFull == RTC_PRIVILEGE_FULL_NO). + This parameter can be a combination of + @ref RTCEx_RTC_Privilege_Features */ + + uint32_t tampPrivilegeFull; /*!< Specifies If the TAMP is fully privileged or not execpt monotonic + counters and BackUp registers. + This parameter can be a value of @ref RTCEx_TAMP_Privilege_Full */ + + uint32_t backupRegisterPrivZone; /*!< Specifies backup register zone to be privileged. + This parameter can be a combination of + @ref RTCEx_Backup_Reg_Privilege_zone. + Warning : this parameter is writable in secure mode or if trustzone is + disabled */ + + uint32_t backupRegisterStartZone2; /*!< Specifies the backup register start zone 2. + Zone 1 : read secure write secure. + Zone 2 : read non-secure write secure. + This parameter can be RTC_BKP_DRx where x can be from 0 to 31 to specify + the register . + Warning : this parameter is writable in secure mode or if trustzone is + disabled. + Warning : this parameter is shared with RTC_SecureStateTypeDef */ + + uint32_t backupRegisterStartZone3; /*!< Specifies the backup register start zone 3. + Zone 3 : read non-secure write non-secure. + This parameter can be RTC_BKP_DRx where x can be from 0 to 31 to specify + the register. + Warning : this parameter is writable in secure mode or if trustzone is + disabled. + Warning : this parameter is shared with RTC_SecureStateTypeDef */ + + uint32_t MonotonicCounterPrivilege; /*!< Specifies If the monotonic counter is privileged or not. + This parameter can be a value of + @ref RTCEx_TAMP_Monotonic_Counter_Privilege */ +} RTC_PrivilegeStateTypeDef; +/** + * @} + */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup RTCEx_Exported_Constants RTCEx Exported Constants + * @{ + */ + +#if defined(RTC_CR_TSEDGE) +/** @defgroup RTCEx_Time_Stamp_Edges_definitions RTCEx Time Stamp Edges definition + * @{ + */ +#define RTC_TIMESTAMPEDGE_RISING 0U +#define RTC_TIMESTAMPEDGE_FALLING RTC_CR_TSEDGE +/** + * @} + */ +#endif /* RTC_CR_TSEDGE */ + +/** @defgroup RTCEx_TimeStamp_Pin_Selections RTCEx TimeStamp Pin Selection + * @{ + */ +#define RTC_TIMESTAMPPIN_DEFAULT 0U +/** + * @} + */ + +/** @defgroup RTCEx_Wakeup_Timer_Definitions RTCEx Wakeup Timer Definitions + * @{ + */ +#define RTC_WAKEUPCLOCK_RTCCLK_DIV16 0U +#define RTC_WAKEUPCLOCK_RTCCLK_DIV8 RTC_CR_WUCKSEL_0 +#define RTC_WAKEUPCLOCK_RTCCLK_DIV4 RTC_CR_WUCKSEL_1 +#define RTC_WAKEUPCLOCK_RTCCLK_DIV2 (RTC_CR_WUCKSEL_0 | RTC_CR_WUCKSEL_1) +#define RTC_WAKEUPCLOCK_CK_SPRE_16BITS RTC_CR_WUCKSEL_2 +#define RTC_WAKEUPCLOCK_CK_SPRE_17BITS (RTC_CR_WUCKSEL_1 | RTC_CR_WUCKSEL_2) +/** + * @} + */ + +/** @defgroup RTCEx_Smooth_calib_period_Definitions RTCEx Smooth calib period Definitions + * @{ + */ +#define RTC_SMOOTHCALIB_PERIOD_32SEC 0U /*!< If RTCCLK = 32768 Hz, Smooth calibration period + is 32s, else 2exp20 RTCCLK pulses */ +#define RTC_SMOOTHCALIB_PERIOD_16SEC RTC_CALR_CALW16 /*!< If RTCCLK = 32768 Hz, Smooth calibration period + is 16s, else 2exp19 RTCCLK pulses */ +#define RTC_SMOOTHCALIB_PERIOD_8SEC RTC_CALR_CALW8 /*!< If RTCCLK = 32768 Hz, Smooth calibration period + is 8s, else 2exp18 RTCCLK pulses */ +/** + * @} + */ + +/** @defgroup RTCEx_Smooth_calib_Plus_pulses_Definitions RTCEx Smooth calib Plus pulses Definitions + * @{ + */ +#define RTC_SMOOTHCALIB_PLUSPULSES_SET RTC_CALR_CALP /*!< The number of RTCCLK pulses added + during a X -second window = Y - CALM[8:0] + with Y = 512, 256, 128 when X = 32, 16, 8 */ +#define RTC_SMOOTHCALIB_PLUSPULSES_RESET 0U /*!< The number of RTCCLK pulses subbstited + during a 32-second window = CALM[8:0] */ +/** + * @} + */ + +/** @defgroup RTCEx_Smooth_calib_low_power_Definitions RTCEx Smooth calib Low Power Definitions + * @{ + */ +#define RTC_LPCAL_SET RTC_CALR_LPCAL /*!< Calibration window is 2exp20 ck_apre, which is the required configuration for ultra-low consumption mode. */ +#define RTC_LPCAL_RESET 0U /*!< Calibration window is 2exp20 RTCCLK, which is a high-consumption mode. + This mode should be set only when less + than 32s calibration window is required. */ +/** + * @} + */ + +#if defined(RTC_CR_COSEL) +/** @defgroup RTCEx_Calib_Output_selection_Definitions RTCEx Calib Output selection Definitions + * @{ + */ +#define RTC_CALIBOUTPUT_512HZ 0U +#define RTC_CALIBOUTPUT_1HZ RTC_CR_COSEL +/** + * @} + */ +#endif /* RTC_CR_COSEL */ + +/** @defgroup RTCEx_Add_1_Second_Parameter_Definition RTCEx Add 1 Second Parameter Definitions + * @{ + */ +#define RTC_SHIFTADD1S_RESET 0U +#define RTC_SHIFTADD1S_SET RTC_SHIFTR_ADD1S +/** + * @} + */ + +/** @defgroup RTCEx_Tamper_Pins RTCEx Tamper Pins Definition + * @{ + */ +#define RTC_TAMPER_1 TAMP_CR1_TAMP1E +#define RTC_TAMPER_2 TAMP_CR1_TAMP2E +#if (RTC_TAMP_NB == 2U) +#define RTC_TAMPER_ALL (RTC_TAMPER_1 | RTC_TAMPER_2) +#else +#define RTC_TAMPER_3 TAMP_CR1_TAMP3E +#define RTC_TAMPER_4 TAMP_CR1_TAMP4E +#define RTC_TAMPER_5 TAMP_CR1_TAMP5E +#define RTC_TAMPER_6 TAMP_CR1_TAMP6E +#define RTC_TAMPER_7 TAMP_CR1_TAMP7E +#define RTC_TAMPER_8 TAMP_CR1_TAMP8E +#define RTC_TAMPER_ALL (RTC_TAMPER_1 | RTC_TAMPER_2 |\ + RTC_TAMPER_3 | RTC_TAMPER_4 |\ + RTC_TAMPER_5 | RTC_TAMPER_6 |\ + RTC_TAMPER_7 | RTC_TAMPER_8 ) +#endif /* RTC_TAMP_NB */ +/** + * @} + */ + +/** @defgroup RTCEx_Internal_Tamper_Pins RTCEx Internal Tamper Pins Definition + * @{ + */ +#define RTC_INT_TAMPER_1 TAMP_CR1_ITAMP1E +#define RTC_INT_TAMPER_2 TAMP_CR1_ITAMP2E +#define RTC_INT_TAMPER_3 TAMP_CR1_ITAMP3E +#define RTC_INT_TAMPER_4 TAMP_CR1_ITAMP4E +#define RTC_INT_TAMPER_5 TAMP_CR1_ITAMP5E +#define RTC_INT_TAMPER_6 TAMP_CR1_ITAMP6E +#define RTC_INT_TAMPER_7 TAMP_CR1_ITAMP7E +#define RTC_INT_TAMPER_8 TAMP_CR1_ITAMP8E +#define RTC_INT_TAMPER_9 TAMP_CR1_ITAMP9E +#define RTC_INT_TAMPER_11 TAMP_CR1_ITAMP11E +#define RTC_INT_TAMPER_12 TAMP_CR1_ITAMP12E +#define RTC_INT_TAMPER_13 TAMP_CR1_ITAMP13E +#define RTC_INT_TAMPER_15 TAMP_CR1_ITAMP15E +#define RTC_INT_TAMPER_ALL (RTC_INT_TAMPER_1 | RTC_INT_TAMPER_2 |\ + RTC_INT_TAMPER_3 | RTC_INT_TAMPER_4 |\ + RTC_INT_TAMPER_5 | RTC_INT_TAMPER_6 |\ + RTC_INT_TAMPER_7 | RTC_INT_TAMPER_8 |\ + RTC_INT_TAMPER_9 | RTC_INT_TAMPER_11 |\ + RTC_INT_TAMPER_12 | RTC_INT_TAMPER_13 |\ + RTC_INT_TAMPER_15) +/** + * @} + */ + +/** @defgroup RTCEx_Tamper_Trigger RTCEx Tamper Trigger + * @{ + */ +#define RTC_TAMPERTRIGGER_RISINGEDGE 0U /*!< Warning : Filter must be RTC_TAMPERFILTER_DISABLE */ +#define RTC_TAMPERTRIGGER_FALLINGEDGE 1U /*!< Warning : Filter must be RTC_TAMPERFILTER_DISABLE */ +#define RTC_TAMPERTRIGGER_LOWLEVEL 2U /*!< Warning : Filter must not be RTC_TAMPERFILTER_DISABLE */ +#define RTC_TAMPERTRIGGER_HIGHLEVEL 3U /*!< Warning : Filter must not be RTC_TAMPERFILTER_DISABLE */ +/** + * @} + */ + +/** @defgroup RTCEx_Tamper_MaskFlag RTCEx Tamper MaskFlag + * @{ + */ +#define RTC_TAMPERMASK_FLAG_DISABLE 0U +#define RTC_TAMPERMASK_FLAG_ENABLE 1U +/** + * @} + */ + +/** @defgroup RTCEx_Tamper_Maskable_nb RTCEx Tampers maskable number + * @{ + */ +#if (RTC_TAMP_NB == 2U) +#define RTC_TAMPER_MASKABLE_NB 2U +#else +#define RTC_TAMPER_MASKABLE_NB 3U +#endif /* (RTC_TAMP_NB == 2U) */ + +/** + * @} + */ + +/** @defgroup RTCEx_Tamper_EraseBackUp RTCEx Tamper EraseBackUp + * @{ + */ +#define RTC_TAMPER_ERASE_BACKUP_ENABLE 0U +#define RTC_TAMPER_ERASE_BACKUP_DISABLE 1U +/** + * @} + */ + +/** @defgroup RTCEx_Tamper_Filter RTCEx Tamper Filter + * @{ + */ +#define RTC_TAMPERFILTER_DISABLE 0U /*!< Tamper filter is disabled */ +#define RTC_TAMPERFILTER_2SAMPLE TAMP_FLTCR_TAMPFLT_0 /*!< Tamper is activated after 2 consecutive samples at the active level */ +#define RTC_TAMPERFILTER_4SAMPLE TAMP_FLTCR_TAMPFLT_1 /*!< Tamper is activated after 4 consecutive samples at the active level */ +#define RTC_TAMPERFILTER_8SAMPLE TAMP_FLTCR_TAMPFLT /*!< Tamper is activated after 8 consecutive samples at the active level */ +/** + * @} + */ + +/** @defgroup RTCEx_Tamper_Sampling_Frequencies RTCEx Tamper Sampling Frequencies + * @{ + */ +#define RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV32768 0U /*!< Each of the tamper inputs are sampled with a frequency = RTCCLK / 32768 */ +#define RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV16384 TAMP_FLTCR_TAMPFREQ_0 /*!< Each of the tamper inputs are sampled with a frequency = RTCCLK / 16384 */ +#define RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV8192 TAMP_FLTCR_TAMPFREQ_1 /*!< Each of the tamper inputs are sampled with a frequency = RTCCLK / 8192 */ +#define RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV4096 (TAMP_FLTCR_TAMPFREQ_0 | TAMP_FLTCR_TAMPFREQ_1) /*!< Each of the tamper inputs are sampled with a frequency = RTCCLK / 4096 */ +#define RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV2048 TAMP_FLTCR_TAMPFREQ_2 /*!< Each of the tamper inputs are sampled with a frequency = RTCCLK / 2048 */ +#define RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV1024 (TAMP_FLTCR_TAMPFREQ_0 | TAMP_FLTCR_TAMPFREQ_2) /*!< Each of the tamper inputs are sampled with a frequency = RTCCLK / 1024 */ +#define RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV512 (TAMP_FLTCR_TAMPFREQ_1 | TAMP_FLTCR_TAMPFREQ_2) /*!< Each of the tamper inputs are sampled with a frequency = RTCCLK / 512 */ +#define RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV256 (TAMP_FLTCR_TAMPFREQ_0 | TAMP_FLTCR_TAMPFREQ_1 | \ + TAMP_FLTCR_TAMPFREQ_2) /*!< Each of the tamper inputs are sampled with a frequency = RTCCLK / 256 */ +/** + * @} + */ + +/** @defgroup RTCEx_Tamper_Pin_Precharge_Duration RTCEx Tamper Pin Precharge Duration + * @{ + */ +#define RTC_TAMPERPRECHARGEDURATION_1RTCCLK 0U /*!< Tamper pins are pre-charged before sampling during 1 RTCCLK cycle */ +#define RTC_TAMPERPRECHARGEDURATION_2RTCCLK TAMP_FLTCR_TAMPPRCH_0 /*!< Tamper pins are pre-charged before sampling during 2 RTCCLK cycles */ +#define RTC_TAMPERPRECHARGEDURATION_4RTCCLK TAMP_FLTCR_TAMPPRCH_1 /*!< Tamper pins are pre-charged before sampling during 4 RTCCLK cycles */ +#define RTC_TAMPERPRECHARGEDURATION_8RTCCLK (TAMP_FLTCR_TAMPPRCH_0 | TAMP_FLTCR_TAMPPRCH_1) /*!< Tamper pins are pre-charged before sampling during 8 RTCCLK cycles */ +/** + * @} + */ + +/** @defgroup RTCEx_Tamper_Pull_UP RTCEx Tamper Pull UP + * @{ + */ +#define RTC_TAMPER_PULLUP_ENABLE 0U /*!< Tamper pins are pre-charged before sampling */ +#define RTC_TAMPER_PULLUP_DISABLE TAMP_FLTCR_TAMPPUDIS /*!< Tamper pins pre-charge is disabled */ +/** + * @} + */ + +/** @defgroup RTCEx_Tamper_TimeStampOnTamperDetection RTCEx Tamper TimeStamp On Tamper Detection Definitions + * @{ + */ +#define RTC_TIMESTAMPONTAMPERDETECTION_DISABLE 0U /*!< TimeStamp on Tamper Detection event is not saved */ +#define RTC_TIMESTAMPONTAMPERDETECTION_ENABLE RTC_CR_TAMPTS /*!< TimeStamp on Tamper Detection event saved */ +/** + * @} + */ + +/** @defgroup RTCEx_Tamper_Detection_Output RTCEx Tamper detection output Definitions + * @{ + */ +#if defined(RTC_CR_TAMPOE) +#define RTC_TAMPERDETECTIONOUTPUT_DISABLE 0U /*!< Tamper detection output disable on TAMPALRM */ +#define RTC_TAMPERDETECTIONOUTPUT_ENABLE RTC_CR_TAMPOE /*!< Tamper detection output enable on TAMPALRM */ +#endif /* RTC_CR_TAMPOE */ +/** + * @} + */ + + +/** @defgroup RTCEx_Tamper_Interrupt RTCEx Tamper Interrupt + * @{ + */ +#define RTC_IT_TAMP_1 TAMP_IER_TAMP1IE /*!< Tamper 1 Interrupt */ +#define RTC_IT_TAMP_2 TAMP_IER_TAMP2IE /*!< Tamper 2 Interrupt */ +#if (RTC_TAMP_NB == 2U) +#define RTC_IT_TAMP_ALL (RTC_IT_TAMP_1 | RTC_IT_TAMP_2) +#else +#define RTC_IT_TAMP_3 TAMP_IER_TAMP3IE /*!< Tamper 3 Interrupt */ +#define RTC_IT_TAMP_4 TAMP_IER_TAMP4IE /*!< Tamper 4 Interrupt */ +#define RTC_IT_TAMP_5 TAMP_IER_TAMP5IE /*!< Tamper 5 Interrupt */ +#define RTC_IT_TAMP_6 TAMP_IER_TAMP6IE /*!< Tamper 6 Interrupt */ +#define RTC_IT_TAMP_7 TAMP_IER_TAMP7IE /*!< Tamper 7 Interrupt */ +#define RTC_IT_TAMP_8 TAMP_IER_TAMP8IE /*!< Tamper 8 Interrupt */ +#define RTC_IT_TAMP_ALL (RTC_IT_TAMP_1 | RTC_IT_TAMP_2 |\ + RTC_IT_TAMP_3 | RTC_IT_TAMP_4 |\ + RTC_IT_TAMP_5 | RTC_IT_TAMP_6 |\ + RTC_IT_TAMP_7 | RTC_IT_TAMP_8 ) +#endif /* RTC_TAMP_NB */ +/** + * @} + */ + +/** @defgroup RTCEx_Internal_Tamper_Interrupt RTCEx Internal Tamper Interrupt + * @{ + */ +#define RTC_IT_INT_TAMP_1 TAMP_IER_ITAMP1IE /*!< Tamper 1 internal Interrupt */ +#define RTC_IT_INT_TAMP_2 TAMP_IER_ITAMP2IE /*!< Tamper 2 internal Interrupt */ +#define RTC_IT_INT_TAMP_3 TAMP_IER_ITAMP3IE /*!< Tamper 3 internal Interrupt */ +#define RTC_IT_INT_TAMP_4 TAMP_IER_ITAMP4IE /*!< Tamper 4 internal Interrupt */ +#define RTC_IT_INT_TAMP_5 TAMP_IER_ITAMP5IE /*!< Tamper 5 internal Interrupt */ +#define RTC_IT_INT_TAMP_6 TAMP_IER_ITAMP6IE /*!< Tamper 6 internal Interrupt */ +#define RTC_IT_INT_TAMP_7 TAMP_IER_ITAMP7IE /*!< Tamper 7 internal Interrupt */ +#define RTC_IT_INT_TAMP_8 TAMP_IER_ITAMP8IE /*!< Tamper 8 internal Interrupt */ +#define RTC_IT_INT_TAMP_9 TAMP_IER_ITAMP9IE /*!< Tamper 9 internal Interrupt */ +#define RTC_IT_INT_TAMP_11 TAMP_IER_ITAMP11IE /*!< Tamper 11 internal Interrupt */ +#define RTC_IT_INT_TAMP_12 TAMP_IER_ITAMP12IE /*!< Tamper 12 internal Interrupt */ +#define RTC_IT_INT_TAMP_13 TAMP_IER_ITAMP13IE /*!< Tamper 13 internal Interrupt */ +#define RTC_IT_INT_TAMP_15 TAMP_IER_ITAMP15IE /*!< Tamper 15 internal Interrupt */ +#define RTC_IT_INT_TAMP_ALL (RTC_IT_INT_TAMP_1 | RTC_IT_INT_TAMP_2 |\ + RTC_IT_INT_TAMP_3 | RTC_IT_INT_TAMP_4 |\ + RTC_IT_INT_TAMP_5 | RTC_IT_INT_TAMP_6 |\ + RTC_IT_INT_TAMP_7 | RTC_IT_INT_TAMP_8 |\ + RTC_IT_INT_TAMP_9 | RTC_IT_INT_TAMP_11 |\ + RTC_IT_INT_TAMP_12 |RTC_IT_INT_TAMP_13 |\ + RTC_IT_INT_TAMP_15) +/** + * @} + */ + +/** @defgroup RTCEx_Flags RTCEx Flags + * @{ + */ +#define RTC_FLAG_TAMP_1 TAMP_SR_TAMP1F +#define RTC_FLAG_TAMP_2 TAMP_SR_TAMP2F +#if (RTC_TAMP_NB == 2U) +#define RTC_FLAG_TAMP_ALL (TAMP_SR_TAMP1F | TAMP_SR_TAMP2F) +#else +#define RTC_FLAG_TAMP_3 TAMP_SR_TAMP3F +#define RTC_FLAG_TAMP_4 TAMP_SR_TAMP4F +#define RTC_FLAG_TAMP_5 TAMP_SR_TAMP5F +#define RTC_FLAG_TAMP_6 TAMP_SR_TAMP6F +#define RTC_FLAG_TAMP_7 TAMP_SR_TAMP7F +#define RTC_FLAG_TAMP_8 TAMP_SR_TAMP8F +#define RTC_FLAG_TAMP_ALL (RTC_FLAG_TAMP_1 | RTC_FLAG_TAMP_2 | RTC_FLAG_TAMP_3 |\ + RTC_FLAG_TAMP_4 | RTC_FLAG_TAMP_5 | RTC_FLAG_TAMP_6 |\ + RTC_FLAG_TAMP_7 | RTC_FLAG_TAMP_8) +#endif /* RTC_TAMP_NB */ + +#define RTC_FLAG_INT_TAMP_1 TAMP_SR_ITAMP1F +#define RTC_FLAG_INT_TAMP_2 TAMP_SR_ITAMP2F +#define RTC_FLAG_INT_TAMP_3 TAMP_SR_ITAMP3F +#define RTC_FLAG_INT_TAMP_4 TAMP_SR_ITAMP4F +#define RTC_FLAG_INT_TAMP_5 TAMP_SR_ITAMP5F +#define RTC_FLAG_INT_TAMP_6 TAMP_SR_ITAMP6F +#define RTC_FLAG_INT_TAMP_7 TAMP_SR_ITAMP7F +#define RTC_FLAG_INT_TAMP_8 TAMP_SR_ITAMP8F +#define RTC_FLAG_INT_TAMP_9 TAMP_SR_ITAMP9F +#define RTC_FLAG_INT_TAMP_11 TAMP_SR_ITAMP11F +#define RTC_FLAG_INT_TAMP_12 TAMP_SR_ITAMP12F +#define RTC_FLAG_INT_TAMP_13 TAMP_SR_ITAMP13F +#define RTC_FLAG_INT_TAMP_15 TAMP_SR_ITAMP15F +#define RTC_FLAG_INT_TAMP_ALL (RTC_FLAG_INT_TAMP_1 | RTC_FLAG_INT_TAMP_2 |\ + RTC_FLAG_INT_TAMP_3 | RTC_FLAG_INT_TAMP_4 |\ + RTC_FLAG_INT_TAMP_5 | RTC_FLAG_INT_TAMP_6 |\ + RTC_FLAG_INT_TAMP_7 | RTC_FLAG_INT_TAMP_8 |\ + RTC_FLAG_INT_TAMP_9 | RTC_FLAG_INT_TAMP_11 |\ + RTC_FLAG_INT_TAMP_12 | RTC_FLAG_INT_TAMP_13 |\ + RTC_FLAG_INT_TAMP_15) +/** + * @} + */ + + +/** @defgroup RTCEx_ActiveTamper_Enable RTCEx_ActiveTamper_Enable Definitions + * @{ + */ +#define RTC_ATAMP_ENABLE 1U +#define RTC_ATAMP_DISABLE 0U +/** + * @} + */ + +/** @defgroup RTCEx_ActiveTamper_Interrupt RTCEx_ActiveTamper_Interrupt Definitions + * @{ + */ +#define RTC_ATAMP_INTERRUPT_ENABLE 1U +#define RTC_ATAMP_INTERRUPT_DISABLE 0U +/** + * @} + */ + +/** @defgroup RTCEx_ActiveTamper_Filter RTCEx_ActiveTamper_Filter Definitions + * @{ + */ +#define RTC_ATAMP_FILTER_ENABLE TAMP_ATCR1_FLTEN +#define RTC_ATAMP_FILTER_DISABLE 0U +/** + * @} + */ + +/** @defgroup RTCEx_ActiveTamper_Async_prescaler RTCEx Active_Tamper_Asynchronous_Prescaler clock Definitions + * @{ + */ +#define RTC_ATAMP_ASYNCPRES_RTCCLK 0U /*!< RTCCLK */ +#define RTC_ATAMP_ASYNCPRES_RTCCLK_2 TAMP_ATCR1_ATCKSEL_0 /*!< RTCCLK/2 */ +#define RTC_ATAMP_ASYNCPRES_RTCCLK_4 TAMP_ATCR1_ATCKSEL_1 /*!< RTCCLK/4 */ +#define RTC_ATAMP_ASYNCPRES_RTCCLK_8 (TAMP_ATCR1_ATCKSEL_1 | TAMP_ATCR1_ATCKSEL_0) /*!< RTCCLK/8 */ +#define RTC_ATAMP_ASYNCPRES_RTCCLK_16 TAMP_ATCR1_ATCKSEL_2 /*!< RTCCLK/16 */ +#define RTC_ATAMP_ASYNCPRES_RTCCLK_32 (TAMP_ATCR1_ATCKSEL_2 | TAMP_ATCR1_ATCKSEL_0) /*!< RTCCLK/32 */ +#define RTC_ATAMP_ASYNCPRES_RTCCLK_64 (TAMP_ATCR1_ATCKSEL_2 | TAMP_ATCR1_ATCKSEL_1) /*!< RTCCLK/64 */ +#define RTC_ATAMP_ASYNCPRES_RTCCLK_128 (TAMP_ATCR1_ATCKSEL_2 | TAMP_ATCR1_ATCKSEL_1 | TAMP_ATCR1_ATCKSEL_0) /*!< RTCCLK/128 */ +#define RTC_ATAMP_ASYNCPRES_RTCCLK_2048 (TAMP_ATCR1_ATCKSEL_3 | TAMP_ATCR1_ATCKSEL_1 | TAMP_ATCR1_ATCKSEL_0) /*!< RTCCLK/2048 */ +/** + * @} + */ + +/** @defgroup RTCEx_ActiveTamper_Sel RTCEx Active Tamper selection Definition + * @{ + */ +#define RTC_ATAMP_1 0U /*!< Tamper 1 */ +#define RTC_ATAMP_2 1U /*!< Tamper 2 */ +#define RTC_ATAMP_3 2U /*!< Tamper 3 */ +#define RTC_ATAMP_4 3U /*!< Tamper 4 */ +#define RTC_ATAMP_5 4U /*!< Tamper 5 */ +#define RTC_ATAMP_6 5U /*!< Tamper 6 */ +#define RTC_ATAMP_7 6U /*!< Tamper 7 */ +#define RTC_ATAMP_8 7U /*!< Tamper 8 */ +/** + * @} + */ + +/** @defgroup RTCEx_MonotonicCounter_Instance RTCEx Monotonic Counter Instance Definition + * @{ + */ +#define RTC_MONOTONIC_COUNTER_1 0U /*!< Monotonic counter 1 */ +/** + * @} + */ + + +/** @defgroup RTCEx_Backup_Registers RTCEx Backup Registers Definition + * @{ + */ +#define RTC_BKP_NUMBER RTC_BKP_NB +#define RTC_BKP_DR0 0x00U +#define RTC_BKP_DR1 0x01U +#define RTC_BKP_DR2 0x02U +#define RTC_BKP_DR3 0x03U +#define RTC_BKP_DR4 0x04U +#define RTC_BKP_DR5 0x05U +#define RTC_BKP_DR6 0x06U +#define RTC_BKP_DR7 0x07U +#define RTC_BKP_DR8 0x08U +#define RTC_BKP_DR9 0x09U +#define RTC_BKP_DR10 0x0AU +#define RTC_BKP_DR11 0x0BU +#define RTC_BKP_DR12 0x0CU +#define RTC_BKP_DR13 0x0DU +#define RTC_BKP_DR14 0x0EU +#define RTC_BKP_DR15 0x0FU +#define RTC_BKP_DR16 0x10U +#define RTC_BKP_DR17 0x11U +#define RTC_BKP_DR18 0x12U +#define RTC_BKP_DR19 0x13U +#define RTC_BKP_DR20 0x14U +#define RTC_BKP_DR21 0x15U +#define RTC_BKP_DR22 0x16U +#define RTC_BKP_DR23 0x17U +#define RTC_BKP_DR24 0x18U +#define RTC_BKP_DR25 0x19U +#define RTC_BKP_DR26 0x1AU +#define RTC_BKP_DR27 0x1BU +#define RTC_BKP_DR28 0x1CU +#define RTC_BKP_DR29 0x1DU +#define RTC_BKP_DR30 0x1EU +#define RTC_BKP_DR31 0x1FU +/** + * @} + */ + +/** @defgroup RTCEx_Binary_Mode RTC Binary Mode (32-bit free-running counter configuration). + * Warning : It Should not be confused with the Binary format @ref RTC_Input_parameter_format_definitions. + * @{ + */ +#define RTC_BINARY_NONE 0U /*!< Free running BCD calendar mode (Binary mode disabled) */ +#define RTC_BINARY_ONLY RTC_ICSR_BIN_0 /*!< Free running Binary mode (BCD mode disabled) */ +#define RTC_BINARY_MIX RTC_ICSR_BIN_1 /*!< Free running BCD calendar and Binary modes */ +/** + * @} + */ + +/** @defgroup RTCEx_Binary_mix_BCDU If Binary mode is RTC_BINARY_MIX, the BCD calendar second is incremented + * using the SSR Least Significant Bits. + * @{ + */ +#define RTC_BINARY_MIX_BCDU_0 0U /*!< The 1s BCD calendar increment is generated each time SS[7:0] = 0 */ +#define RTC_BINARY_MIX_BCDU_1 (0x1UL << RTC_ICSR_BCDU_Pos) /*!< The 1s BCD calendar increment is generated each time SS[8:0] = 0 */ +#define RTC_BINARY_MIX_BCDU_2 (0x2UL << RTC_ICSR_BCDU_Pos) /*!< The 1s BCD calendar increment is generated each time SS[9:0] = 0 */ +#define RTC_BINARY_MIX_BCDU_3 (0x3UL << RTC_ICSR_BCDU_Pos) /*!< The 1s BCD calendar increment is generated each time SS[10:0] = 0 */ +#define RTC_BINARY_MIX_BCDU_4 (0x4UL << RTC_ICSR_BCDU_Pos) /*!< The 1s BCD calendar increment is generated each time SS[11:0] = 0 */ +#define RTC_BINARY_MIX_BCDU_5 (0x5UL << RTC_ICSR_BCDU_Pos) /*!< The 1s BCD calendar increment is generated each time SS[12:0] = 0 */ +#define RTC_BINARY_MIX_BCDU_6 (0x6UL << RTC_ICSR_BCDU_Pos) /*!< The 1s BCD calendar increment is generated each time SS[13:0] = 0 */ +#define RTC_BINARY_MIX_BCDU_7 (0x7UL << RTC_ICSR_BCDU_Pos) /*!< The 1s BCD calendar increment is generated each time SS[14:0] = 0 */ +/** + * @} + */ + +/** @defgroup RTCEx_Alarm_Sub_Seconds_binary_Masks_Definitions RTC Alarm Sub Seconds with binary or mix mode + * Masks Definitions. + * @{ + */ +#define RTC_ALARMSUBSECONDBINMASK_ALL 0U /*!< All Alarm SS fields are masked.There is no comparison on sub seconds for Alarm */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_1 (1UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:1] are don't care in Alarm comparison. Only SS[0] is compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_2 (2UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:2] are don't care in Alarm comparison. Only SS[1:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_3 (3UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:3] are don't care in Alarm comparison. Only SS[2:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_4 (4UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:4] are don't care in Alarm comparison. Only SS[3:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_5 (5UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:5] are don't care in Alarm comparison. Only SS[4:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_6 (6UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:6] are don't care in Alarm comparison. Only SS[5:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_7 (7UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:7] are don't care in Alarm comparison. Only SS[6:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_8 (8UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:8] are don't care in Alarm comparison. Only SS[7:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_9 (9UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:9] are don't care in Alarm comparison. Only SS[8:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_10 (10UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:10] are don't care in Alarm comparison. Only SS[9:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_11 (11UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:11] are don't care in Alarm comparison. Only SS[10:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_12 (12UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:12] are don't care in Alarm comparison.Only SS[11:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_13 (13UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:13] are don't care in Alarm comparison. Only SS[12:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_14 (14UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:14] are don't care in Alarm comparison. Only SS[13:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_15 (15UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:15] are don't care in Alarm comparison. Only SS[14:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_16 (16UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:16] are don't care in Alarm comparison. Only SS[15:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_17 (17UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:17] are don't care in Alarm comparison. Only SS[16:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_18 (18UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:18] are don't care in Alarm comparison. Only SS[17:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_19 (19UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:19] are don't care in Alarm comparison. Only SS[18:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_20 (20UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:20] are don't care in Alarm comparison. Only SS[19:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_21 (21UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:21] are don't care in Alarm comparison. Only SS[20:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_22 (22UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:22] are don't care in Alarm comparison. Only SS[21:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_23 (23UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:23] are don't care in Alarm comparison. Only SS[22:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_24 (24UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:24] are don't care in Alarm comparison. Only SS[23:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_25 (25UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:25] are don't care in Alarm comparison. Only SS[24:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_26 (26UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:26] are don't care in Alarm comparison. Only SS[25:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_27 (27UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:27] are don't care in Alarm comparison. Only SS[26:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_28 (28UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:28] are don't care in Alarm comparison. Only SS[27:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_29 (29UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:29] are don't care in Alarm comparison. Only SS[28:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31_30 (30UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31:30] are don't care in Alarm comparison. Only SS[29:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_SS31 (31UL << RTC_ALRMASSR_MASKSS_Pos) /*!< SS[31] is don't care in Alarm comparison. Only SS[30:0] are compared */ +#define RTC_ALARMSUBSECONDBINMASK_NONE RTC_ALRMASSR_MASKSS /*!< SS[31:0] are compared and must match to activate alarm */ +/** + * @} + */ + +/** @defgroup RTCEx_Alarm_Sub_Seconds_binary_Clear_Definitions RTC Alarm Sub Seconds + * with binary mode auto clear Definitions + * @{ + */ +#define RTC_ALARMSUBSECONDBIN_AUTOCLR_NO 0UL /*!< The synchronous Binary counter(SS[31:0] in RTC_SSR) is free-running */ +#define RTC_ALARMSUBSECONDBIN_AUTOCLR_YES RTC_ALRMASSR_SSCLR +/*!< The synchronous Binary counter (SS[31:0] in RTC_SSR) is running from 0xFFFF FFFF to RTC_ALRMABINR -> SS[31:0] + value and is automatically reloaded with 0xFFFF FFFF whenreaching RTC_ALRMABINR -> SS[31:0]. */ +/** + * @} + */ + +#ifdef RTC_SECCFGR_SEC +/** @defgroup RTCEx_RTC_Secure_Full RTCEx Secure Definition + * @{ + */ +#define RTC_SECURE_FULL_YES RTC_SECCFGR_SEC /*!< RTC full secure */ +#define RTC_SECURE_FULL_NO 0U /*!< RTC is not full secure, features can be unsecure. See RTCEx_RTC_NonSecure_Features */ +/** + * @} + */ + +/** @defgroup RTCEx_RTC_NonSecure_Features RTCEx Secure Features Definition + * @{ + */ +#define RTC_NONSECURE_FEATURE_NONE 0U +#define RTC_NONSECURE_FEATURE_INIT RTC_SECCFGR_INITSEC /*!< Initialization */ +#define RTC_NONSECURE_FEATURE_CAL RTC_SECCFGR_CALSEC /*!< Calibration */ +#define RTC_NONSECURE_FEATURE_TS RTC_SECCFGR_TSSEC /*!< Time stamp */ +#define RTC_NONSECURE_FEATURE_WUT RTC_SECCFGR_WUTSEC /*!< Wake up timer */ +#define RTC_NONSECURE_FEATURE_ALRA RTC_SECCFGR_ALRASEC /*!< Alarm A */ +#define RTC_NONSECURE_FEATURE_ALRB RTC_SECCFGR_ALRBSEC /*!< Alarm B */ + +#define RTC_NONSECURE_FEATURE_ALL (RTC_SECCFGR_INITSEC | RTC_SECCFGR_CALSEC | \ + RTC_SECCFGR_TSSEC | RTC_SECCFGR_WUTSEC | \ + RTC_SECCFGR_ALRASEC | RTC_SECCFGR_ALRBSEC) +/** + * @} + */ +#endif /* RTC_SECCFGR_SEC */ + +#ifdef TAMP_SECCFGR_TAMPSEC +/** @defgroup RTCEx_TAMP_Secure_Full RTCEx TAMP Secure Definition + * @{ + */ +#define TAMP_SECURE_FULL_YES TAMP_SECCFGR_TAMPSEC /*!< TAMPER full secure */ +#define TAMP_SECURE_FULL_NO 0U /*!< TAMPER is not secure */ +/** + * @} + */ +#endif /* TAMP_SECCFGR_TAMPSEC*/ + +#ifdef TAMP_SECCFGR_CNT1SEC +/** @defgroup RTCEx_TAMP_Monotonic_Counter_Secure RTCEx TAMP Monotonic Counter Secure Definition + * @{ + */ +#define TAMP_MONOTONIC_CNT_SECURE_YES TAMP_SECCFGR_CNT1SEC /*!< TAMPER Monotonic Counter secure */ +#define TAMP_MONOTONIC_CNT_SECURE_NO 0U /*!< TAMPER Monotonic Counter is not secure */ +/** + * @} + */ +#endif /* TAMP_SECCFGR_CNT1SEC */ + +/** @defgroup RTCEx_RTC_Privilege_Full RTCEx Privilege Full Definition + * @{ + */ +#define RTC_PRIVILEGE_FULL_YES RTC_PRIVCFGR_PRIV +#define RTC_PRIVILEGE_FULL_NO 0U +/** + * @} + */ + +/** @defgroup RTCEx_RTC_Privilege_Features RTCEx Privilege Features Definition + * @{ + */ +#define RTC_PRIVILEGE_FEATURE_NONE 0U +#define RTC_PRIVILEGE_FEATURE_INIT RTC_PRIVCFGR_INITPRIV /*!< Initialization */ +#define RTC_PRIVILEGE_FEATURE_CAL RTC_PRIVCFGR_CALPRIV /*!< Calibration */ +#define RTC_PRIVILEGE_FEATURE_TS RTC_PRIVCFGR_TSPRIV /*!< Time stamp */ +#define RTC_PRIVILEGE_FEATURE_WUT RTC_PRIVCFGR_WUTPRIV /*!< Wake up timer */ +#define RTC_PRIVILEGE_FEATURE_ALRA RTC_PRIVCFGR_ALRAPRIV /*!< Alarm A */ +#define RTC_PRIVILEGE_FEATURE_ALRB RTC_PRIVCFGR_ALRBPRIV /*!< Alarm B */ + +#define RTC_PRIVILEGE_FEATURE_ALL (RTC_PRIVCFGR_INITPRIV | RTC_PRIVCFGR_CALPRIV | \ + RTC_PRIVCFGR_TSPRIV | RTC_PRIVCFGR_WUTPRIV | \ + RTC_PRIVCFGR_ALRAPRIV | RTC_PRIVCFGR_ALRBPRIV) +/** + * @} + */ + +/** @defgroup RTCEx_TAMP_Privilege_Full RTCEx TAMP security Definition + * @{ + */ +#define TAMP_PRIVILEGE_FULL_YES TAMP_PRIVCFGR_TAMPPRIV +#define TAMP_PRIVILEGE_FULL_NO 0U +/** + * @} + */ + +/** @defgroup RTCEx_TAMP_Device_Secrets_Erase_Conf RTCEx TAMP Device Secrets Erase Configuration Definition + * @{ + */ +#define TAMP_DEVICESECRETS_ERASE_NONE 0U /*! < No Erase */ +#define TAMP_DEVICESECRETS_ERASE_BKPSRAM TAMP_ERCFGR_ERCFG0 /*!< Backup SRAM */ +/** + * @} + */ + +/** @defgroup RTCEx_TAMP_Monotonic_Counter_Privilege RTCEx TAMP Monotonic Counter Privilege Definition + * @{ + */ +#define TAMP_MONOTONIC_CNT_PRIVILEGE_YES TAMP_PRIVCFGR_CNT1PRIV +#define TAMP_MONOTONIC_CNT_PRIVILEGE_NO 0U +/** + * @} + */ + +/** @defgroup RTCEx_Backup_Reg_Privilege_zone RTCEx Privilege Backup register privilege zone Definition + * @{ + */ +#define RTC_PRIVILEGE_BKUP_ZONE_NONE 0U +#define RTC_PRIVILEGE_BKUP_ZONE_1 TAMP_PRIVCFGR_BKPRWPRIV +#define RTC_PRIVILEGE_BKUP_ZONE_2 TAMP_PRIVCFGR_BKPWPRIV +#define RTC_PRIVILEGE_BKUP_ZONE_ALL (RTC_PRIVILEGE_BKUP_ZONE_1 | RTC_PRIVILEGE_BKUP_ZONE_2) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup RTCEx_Exported_Macros RTCEx Exported Macros + * @{ + */ + +/** @brief Clear the specified RTC pending flag. + * @param __HANDLE__ specifies the RTC Handle. + * @param __FLAG__ specifies the flag to check. + * This parameter can be any combination of the following values: + * @arg @ref RTC_CLEAR_ITSF Clear Internal Time-stamp flag + * @arg @ref RTC_CLEAR_TSOVF Clear Time-stamp overflow flag + * @arg @ref RTC_CLEAR_TSF Clear Time-stamp flag + * @arg @ref RTC_CLEAR_WUTF Clear Wakeup timer flag + * @arg @ref RTC_CLEAR_ALRBF Clear Alarm B flag + * @arg @ref RTC_CLEAR_ALRAF Clear Alarm A flag + * @retval None + */ +#define __HAL_RTC_CLEAR_FLAG(__HANDLE__, __FLAG__) (RTC->SCR = (__FLAG__)) + +/** @brief Check whether the specified RTC flag is set or not. + * @param __HANDLE__ specifies the RTC Handle. + * @param __FLAG__ specifies the flag to check. + * This parameter can be any combination of the following values: + * @arg @ref RTC_FLAG_RECALPF Recalibration pending Flag + * @arg @ref RTC_FLAG_INITF Initialization flag + * @arg @ref RTC_FLAG_RSF Registers synchronization flag + * @arg @ref RTC_FLAG_INITS Initialization status flag + * @arg @ref RTC_FLAG_SHPF Shift operation pending flag + * @arg @ref RTC_FLAG_WUTWF Wakeup timer write flag + * @arg @ref RTC_FLAG_ITSF Internal Time-stamp flag + * @arg @ref RTC_FLAG_TSOVF Time-stamp overflow flag + * @arg @ref RTC_FLAG_TSF Time-stamp flag + * @arg @ref RTC_FLAG_WUTF Wakeup timer flag + * @arg @ref RTC_FLAG_ALRBF Alarm B flag + * @arg @ref RTC_FLAG_ALRAF Alarm A flag + * @retval None + */ +#define __HAL_RTC_GET_FLAG(__HANDLE__, __FLAG__) (((((__FLAG__)) >> 8U) == 1U) ? \ + (RTC->ICSR & (1U << (((uint16_t)(__FLAG__)) & RTC_FLAG_MASK))) : \ + (RTC->SR & (1U << (((uint16_t)(__FLAG__)) & RTC_FLAG_MASK)))) + +/* ---------------------------------WAKEUPTIMER---------------------------------*/ +/** @defgroup RTCEx_WakeUp_Timer RTC WakeUp Timer + * @{ + */ + +/** + * @brief Enable the RTC WakeUp Timer peripheral. + * @param __HANDLE__ specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_WAKEUPTIMER_ENABLE(__HANDLE__) (RTC->CR |= (RTC_CR_WUTE)) + +/** + * @brief Disable the RTC WakeUp Timer peripheral. + * @param __HANDLE__ specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_WAKEUPTIMER_DISABLE(__HANDLE__) (RTC->CR &= ~(RTC_CR_WUTE)) + +/** + * @brief Enable the RTC WakeUpTimer interrupt. + * @param __HANDLE__ specifies the RTC handle. + * @param __INTERRUPT__ specifies the RTC WakeUpTimer interrupt sources to be enabled. + * This parameter can be: + * @arg @ref RTC_IT_WUT WakeUpTimer interrupt + * @retval None + */ +#define __HAL_RTC_WAKEUPTIMER_ENABLE_IT(__HANDLE__, __INTERRUPT__) (RTC->CR |= (__INTERRUPT__)) + +/** + * @brief Disable the RTC WakeUpTimer interrupt. + * @param __HANDLE__ specifies the RTC handle. + * @param __INTERRUPT__ specifies the RTC WakeUpTimer interrupt sources to be disabled. + * This parameter can be: + * @arg @ref RTC_IT_WUT WakeUpTimer interrupt + * @retval None + */ +#define __HAL_RTC_WAKEUPTIMER_DISABLE_IT(__HANDLE__, __INTERRUPT__) (RTC->CR &= ~(__INTERRUPT__)) + +/** + * @brief Check whether the specified RTC WakeUpTimer interrupt has occurred or not. + * @param __HANDLE__ specifies the RTC handle. + * @param __INTERRUPT__ specifies the RTC WakeUpTimer interrupt to check. + * This parameter can be: + * @arg @ref RTC_IT_WUT WakeUpTimer interrupt + * @retval None + */ +#define __HAL_RTC_WAKEUPTIMER_GET_IT(__HANDLE__, __INTERRUPT__) ((((RTC->MISR) & ((__INTERRUPT__)>> 12U)) !=\ + 0UL) ? 1UL : 0UL) + +/** + * @brief Check whether the specified RTC Wake Up timer interrupt has been enabled or not. + * @param __HANDLE__ specifies the RTC handle. + * @param __INTERRUPT__ specifies the RTC Wake Up timer interrupt sources to check. + * This parameter can be: + * @arg @ref RTC_IT_WUT WakeUpTimer interrupt + * @retval None + */ +#define __HAL_RTC_WAKEUPTIMER_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((RTC->CR) & (__INTERRUPT__)) != \ + 0UL) ? 1UL : 0UL) + +/** + * @brief Get the selected RTC WakeUpTimers flag status. + * @param __HANDLE__ specifies the RTC handle. + * @param __FLAG__ specifies the RTC WakeUpTimer Flag is pending or not. + * This parameter can be: + * @arg @ref RTC_FLAG_WUTF + * @arg @ref RTC_FLAG_WUTWF + * @retval None + */ +#define __HAL_RTC_WAKEUPTIMER_GET_FLAG(__HANDLE__, __FLAG__) (__HAL_RTC_GET_FLAG((__HANDLE__), (__FLAG__))) + +/** + * @brief Clear the RTC Wake Up timers pending flags. + * @param __HANDLE__ specifies the RTC handle. + * @param __FLAG__ specifies the RTC WakeUpTimer Flag to clear. + * This parameter can be: + * @arg @ref RTC_FLAG_WUTF + * @retval None + */ +#define __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(__HANDLE__, __FLAG__) (__HAL_RTC_CLEAR_FLAG((__HANDLE__), RTC_CLEAR_WUTF)) +/** + * @} + */ + +/* ---------------------------------TIMESTAMP---------------------------------*/ +/** @defgroup RTCEx_Timestamp RTC Timestamp + * @{ + */ + +/** + * @brief Enable the RTC TimeStamp peripheral. + * @param __HANDLE__ specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_TIMESTAMP_ENABLE(__HANDLE__) (RTC->CR |= (RTC_CR_TSE)) + +/** + * @brief Disable the RTC TimeStamp peripheral. + * @param __HANDLE__ specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_TIMESTAMP_DISABLE(__HANDLE__) (RTC->CR &= ~(RTC_CR_TSE)) + +/** + * @brief Enable the RTC TimeStamp interrupt. + * @param __HANDLE__ specifies the RTC handle. + * @param __INTERRUPT__ specifies the RTC TimeStamp interrupt source to be enabled. + * This parameter can be: + * @arg @ref RTC_IT_TS TimeStamp interrupt + * @retval None + */ +#define __HAL_RTC_TIMESTAMP_ENABLE_IT(__HANDLE__, __INTERRUPT__) (RTC->CR |= (__INTERRUPT__)) + +/** + * @brief Disable the RTC TimeStamp interrupt. + * @param __HANDLE__ specifies the RTC handle. + * @param __INTERRUPT__ specifies the RTC TimeStamp interrupt source to be disabled. + * This parameter can be: + * @arg @ref RTC_IT_TS TimeStamp interrupt + * @retval None + */ +#define __HAL_RTC_TIMESTAMP_DISABLE_IT(__HANDLE__, __INTERRUPT__) (RTC->CR &= ~(__INTERRUPT__)) + +/** + * @brief Check whether the specified RTC TimeStamp interrupt has occurred or not. + * @param __HANDLE__ specifies the RTC handle. + * @param __INTERRUPT__ specifies the RTC TimeStamp interrupt to check. + * This parameter can be: + * @arg @ref RTC_IT_TS TimeStamp interrupt + * @retval None + */ +#define __HAL_RTC_TIMESTAMP_GET_IT(__HANDLE__, __INTERRUPT__) ((((RTC->MISR) & ((__INTERRUPT__)>> 12U)) != \ + 0U) ? 1UL : 0UL) + +/** + * @brief Check whether the specified RTC Time Stamp interrupt has been enabled or not. + * @param __HANDLE__ specifies the RTC handle. + * @param __INTERRUPT__ specifies the RTC Time Stamp interrupt source to check. + * This parameter can be: + * @arg @ref RTC_IT_TS TimeStamp interrupt + * @retval None + */ +#define __HAL_RTC_TIMESTAMP_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((RTC->CR) & (__INTERRUPT__)) != 0U) ?\ + 1UL : 0UL) + +/** + * @brief Get the selected RTC TimeStamps flag status. + * @param __HANDLE__ specifies the RTC handle. + * @param __FLAG__ specifies the RTC TimeStamp Flag is pending or not. + * This parameter can be: + * @arg @ref RTC_FLAG_TSF + * @arg @ref RTC_FLAG_TSOVF + * @retval None + */ +#define __HAL_RTC_TIMESTAMP_GET_FLAG(__HANDLE__, __FLAG__) (__HAL_RTC_GET_FLAG((__HANDLE__),(__FLAG__))) + +/** + * @brief Clear the RTC Time Stamps pending flags. + * @param __HANDLE__ specifies the RTC handle. + * @param __FLAG__ specifies the RTC TimeStamp Flag to clear. + * This parameter can be: + * @arg @ref RTC_FLAG_TSF + * @arg @ref RTC_FLAG_TSOVF + * @retval None + */ +#define __HAL_RTC_TIMESTAMP_CLEAR_FLAG(__HANDLE__, __FLAG__) (__HAL_RTC_CLEAR_FLAG((__HANDLE__), (__FLAG__))) + +/** + * @brief Enable the RTC internal TimeStamp peripheral. + * @param __HANDLE__ specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_INTERNAL_TIMESTAMP_ENABLE(__HANDLE__) (RTC->CR |= (RTC_CR_ITSE)) + +/** + * @brief Disable the RTC internal TimeStamp peripheral. + * @param __HANDLE__ specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_INTERNAL_TIMESTAMP_DISABLE(__HANDLE__) (RTC->CR &= ~(RTC_CR_ITSE)) + +/** + * @brief Get the selected RTC Internal Time Stamps flag status. + * @param __HANDLE__ specifies the RTC handle. + * @param __FLAG__ specifies the RTC Internal Time Stamp Flag is pending or not. + * This parameter can be: + * @arg @ref RTC_FLAG_ITSF + * @retval None + */ +#define __HAL_RTC_INTERNAL_TIMESTAMP_GET_FLAG(__HANDLE__, __FLAG__) (__HAL_RTC_GET_FLAG((__HANDLE__),\ + (__FLAG__))) + +/** + * @brief Clear the RTC Internal Time Stamps pending flags. + * @param __HANDLE__ specifies the RTC handle. + * @param __FLAG__ specifies the RTC Internal Time Stamp Flag source to clear. + * This parameter can be: + * @arg @ref RTC_FLAG_ITSF + * @retval None + */ +#define __HAL_RTC_INTERNAL_TIMESTAMP_CLEAR_FLAG(__HANDLE__, __FLAG__) (__HAL_RTC_CLEAR_FLAG((__HANDLE__),\ + RTC_CLEAR_ITSF)) + +/** + * @brief Enable the RTC TimeStamp on Tamper detection. + * @param __HANDLE__ specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_TAMPTS_ENABLE(__HANDLE__) (RTC->CR |= (RTC_CR_TAMPTS)) + +/** + * @brief Disable the RTC TimeStamp on Tamper detection. + * @param __HANDLE__ specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_TAMPTS_DISABLE(__HANDLE__) (RTC->CR &= ~(RTC_CR_TAMPTS)) + +#if defined(RTC_CR_TAMPOE) +/** + * @brief Enable the RTC Tamper detection output. + * @param __HANDLE__ specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_TAMPOE_ENABLE(__HANDLE__) (RTC->CR |= (RTC_CR_TAMPOE)) + +/** + * @brief Disable the RTC Tamper detection output. + * @param __HANDLE__ specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_TAMPOE_DISABLE(__HANDLE__) (RTC->CR &= ~(RTC_CR_TAMPOE)) + +#endif /* RTC_CR_TAMPOE */ + +/** + * @} + */ + + +/* ------------------------------Calibration----------------------------------*/ +/** @defgroup RTCEx_Calibration RTC Calibration + * @{ + */ + +/** + * @brief Enable the RTC calibration output. + * @param __HANDLE__ specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_CALIBRATION_OUTPUT_ENABLE(__HANDLE__) (RTC->CR |= (RTC_CR_COE)) + +/** + * @brief Disable the calibration output. + * @param __HANDLE__ specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_CALIBRATION_OUTPUT_DISABLE(__HANDLE__) (RTC->CR &= ~(RTC_CR_COE)) + + +/** + * @brief Enable the clock reference detection. + * @param __HANDLE__ specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_CLOCKREF_DETECTION_ENABLE(__HANDLE__) (RTC->CR |= (RTC_CR_REFCKON)) + +/** + * @brief Disable the clock reference detection. + * @param __HANDLE__ specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_CLOCKREF_DETECTION_DISABLE(__HANDLE__) (RTC->CR &= ~(RTC_CR_REFCKON)) + + +/** + * @brief Get the selected RTC shift operations flag status. + * @param __HANDLE__ specifies the RTC handle. + * @param __FLAG__ specifies the RTC shift operation Flag is pending or not. + * This parameter can be: + * @arg @ref RTC_FLAG_SHPF + * @retval None + */ +#define __HAL_RTC_SHIFT_GET_FLAG(__HANDLE__, __FLAG__) (__HAL_RTC_GET_FLAG((__HANDLE__), (__FLAG__))) +/** + * @} + */ + + +/* ------------------------------Tamper----------------------------------*/ +/** @defgroup RTCEx_Tamper RTCEx tamper + * @{ + */ + +/** + * @brief Enable the TAMP Tamper input detection. + * @param __HANDLE__ specifies the RTC handle. + * @param __TAMPER__ specifies the RTC Tamper source to be enabled. + * This parameter can be any combination of the following values: + * @arg RTC_TAMPER_ALL: All tampers + * @arg RTC_TAMPER_1: Tamper1 + * @arg RTC_TAMPER_2: Tamper2 + * @arg RTC_TAMPER_3: Tamper3 + * @arg RTC_TAMPER_4: Tamper4 + * @arg RTC_TAMPER_5: Tamper5 + * @arg RTC_TAMPER_6: Tamper6 + * @arg RTC_TAMPER_7: Tamper7 + * @arg RTC_TAMPER_8: Tamper8 + * @retval None + */ +#define __HAL_RTC_TAMPER_ENABLE(__HANDLE__, __TAMPER__) (TAMP->CR1 |= (__TAMPER__)) + +/** + * @brief Disable the TAMP Tamper input detection. + * @param __HANDLE__ specifies the RTC handle. + * @param __TAMPER__ specifies the RTC Tamper sources to be enabled. + * This parameter can be any combination of the following values: + * @arg RTC_TAMPER_ALL: All tampers + * @arg RTC_TAMPER_1: Tamper1 + * @arg RTC_TAMPER_2: Tamper2 + * @arg RTC_TAMPER_3: Tamper3 + * @arg RTC_TAMPER_4: Tamper4 + * @arg RTC_TAMPER_5: Tamper5 + * @arg RTC_TAMPER_6: Tamper6 + * @arg RTC_TAMPER_7: Tamper7 + * @arg RTC_TAMPER_8: Tamper8 + */ +#define __HAL_RTC_TAMPER_DISABLE(__HANDLE__, __TAMPER__) (TAMP->CR1 &= ~(__TAMPER__)) + + +/**************************************************************************************************/ +/** + * @brief Enable the TAMP Tamper interrupt. + * @param __HANDLE__ specifies the RTC handle. + * @param __INTERRUPT__ specifies the RTC Tamper interrupt sources to be enabled. + * This parameter can be any combination of the following values: + * @arg RTC_IT_TAMP_ALL: All tampers interrupts + * @arg RTC_IT_TAMP_1: Tamper1 interrupt + * @arg RTC_IT_TAMP_2: Tamper2 interrupt + * @arg RTC_IT_TAMP_3: Tamper3 interrupt + * @arg RTC_IT_TAMP_4: Tamper4 interrupt + * @arg RTC_IT_TAMP_5: Tamper5 interrupt + * @arg RTC_IT_TAMP_6: Tamper6 interrupt + * @arg RTC_IT_TAMP_7: Tamper7 interrupt + * @arg RTC_IT_TAMP_8: Tamper8 interrupt + * @retval None + */ +#define __HAL_RTC_TAMPER_ENABLE_IT(__HANDLE__, __INTERRUPT__) (TAMP->IER |= (__INTERRUPT__)) + +/** + * @brief Disable the TAMP Tamper interrupt. + * @param __HANDLE__ specifies the RTC handle. + * @param __INTERRUPT__ specifies the RTC Tamper interrupt sources to be disabled. + * This parameter can be any combination of the following values: + * @arg RTC_IT_TAMP_ALL: All tampers interrupts + * @arg RTC_IT_TAMP_1: Tamper1 interrupt + * @arg RTC_IT_TAMP_2: Tamper2 interrupt + * @arg RTC_IT_TAMP_3: Tamper3 interrupt + * @arg RTC_IT_TAMP_4: Tamper4 interrupt + * @arg RTC_IT_TAMP_5: Tamper5 interrupt + * @arg RTC_IT_TAMP_6: Tamper6 interrupt + * @arg RTC_IT_TAMP_7: Tamper7 interrupt + * @arg RTC_IT_TAMP_8: Tamper8 interrupt + * @retval None + */ +#define __HAL_RTC_TAMPER_DISABLE_IT(__HANDLE__, __INTERRUPT__) (TAMP->IER &= ~(__INTERRUPT__)) + + +/**************************************************************************************************/ +/** + * @brief Check whether the specified RTC Tamper interrupt has occurred or not. + * @param __HANDLE__ specifies the RTC handle. + * @param __INTERRUPT__ specifies the RTC Tamper interrupt to check. + * This parameter can be: + * @arg RTC_IT_TAMP_ALL: All tampers interrupts + * @arg RTC_IT_TAMP_1: Tamper1 interrupt + * @arg RTC_IT_TAMP_2: Tamper2 interrupt + * @arg RTC_IT_TAMP_3: Tamper3 interrupt + * @arg RTC_IT_TAMP_4: Tamper4 interrupt + * @arg RTC_IT_TAMP_5: Tamper5 interrupt + * @arg RTC_IT_TAMP_6: Tamper6 interrupt + * @arg RTC_IT_TAMP_7: Tamper7 interrupt + * @arg RTC_IT_TAMP_8: Tamper8 interrupt + * @arg RTC_IT_INT_TAMP_ALL: All Internal Tamper interrupts + * @arg RTC_IT_INT_TAMP_1: Internal Tamper1 interrupt + * @arg RTC_IT_INT_TAMP_2: Internal Tamper2 interrupt + * @arg RTC_IT_INT_TAMP_3: Internal Tamper3 interrupt + * @arg RTC_IT_INT_TAMP_4: Internal Tamper4 interrupt + * @arg RTC_IT_INT_TAMP_5: Internal Tamper5 interrupt + * @arg RTC_IT_INT_TAMP_6: Internal Tamper6 interrupt + * @arg RTC_IT_INT_TAMP_7: Internal Tamper7 interrupt + * @arg RTC_IT_INT_TAMP_8: Internal Tamper8 interrupt + * @arg RTC_IT_INT_TAMP_9: Internal Tamper9 interrupt + * @arg RTC_IT_INT_TAMP_11: Internal Tamper11 interrupt + * @arg RTC_IT_INT_TAMP_12: Internal Tamper12 interrupt + * @arg RTC_IT_INT_TAMP_13: Internal Tamper13 interrupt + * @arg RTC_IT_INT_TAMP_15: Internal Tamper15 interrupt + * @retval None + */ +#define __HAL_RTC_TAMPER_GET_IT(__HANDLE__, __INTERRUPT__) ((((TAMP->MISR) & (__INTERRUPT__)) != 0U) ? 1UL : 0UL) + +/** + * @brief Check whether the specified RTC Tamper interrupt has been enabled or not. + * @param __HANDLE__ specifies the RTC handle. + * @param __INTERRUPT__ specifies the RTC Tamper interrupt source to check. + * This parameter can be: + * @arg RTC_IT_TAMP_ALL: All tampers interrupts + * @arg RTC_IT_TAMP_1: Tamper1 interrupt + * @arg RTC_IT_TAMP_2: Tamper2 interrupt + * @arg RTC_IT_TAMP_3: Tamper3 interrupt + * @arg RTC_IT_TAMP_4: Tamper4 interrupt + * @arg RTC_IT_TAMP_5: Tamper5 interrupt + * @arg RTC_IT_TAMP_6: Tamper6 interrupt + * @arg RTC_IT_TAMP_7: Tamper7 interrupt + * @arg RTC_IT_TAMP_8: Tamper8 interrupt + * @arg RTC_IT_INT_TAMP_ALL: All internal tampers interrupts + * @arg RTC_IT_INT_TAMP_1: Internal Tamper1 interrupt + * @arg RTC_IT_INT_TAMP_2: Internal Tamper2 interrupt + * @arg RTC_IT_INT_TAMP_3: Internal Tamper3 interrupt + * @arg RTC_IT_INT_TAMP_4: Internal Tamper4 interrupt + * @arg RTC_IT_INT_TAMP_5: Internal Tamper5 interrupt + * @arg RTC_IT_INT_TAMP_6: Internal Tamper6 interrupt + * @arg RTC_IT_INT_TAMP_7: Internal Tamper7 interrupt + * @arg RTC_IT_INT_TAMP_8: Internal Tamper8 interrupt + * @arg RTC_IT_INT_TAMP_9: Internal Tamper9 interrupt + * @arg RTC_IT_INT_TAMP_11: Internal Tamper11 interrupt + * @arg RTC_IT_INT_TAMP_12: Internal Tamper12 interrupt + * @arg RTC_IT_INT_TAMP_13: Internal Tamper13 interrupt + * @arg RTC_IT_INT_TAMP_15: Internal Tamper15 interrupt + * @retval None + */ +#define __HAL_RTC_TAMPER_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((TAMP->IER) & (__INTERRUPT__)) != \ + 0U) ? 1UL : 0UL) + +/** + * @brief Get the selected RTC Tampers flag status. + * @param __HANDLE__ specifies the RTC handle. + * @param __FLAG__ specifies the RTC Tamper Flag is pending or not. + * This parameter can be: + * @arg RTC_FLAG_TAMP_ALL: All tampers flag + * @arg RTC_FLAG_TAMP_1: Tamper1 flag + * @arg RTC_FLAG_TAMP_2: Tamper2 flag + * @arg RTC_FLAG_TAMP_3: Tamper3 flag + * @arg RTC_FLAG_TAMP_4: Tamper4 flag + * @arg RTC_FLAG_TAMP_5: Tamper5 flag + * @arg RTC_FLAG_TAMP_6: Tamper6 flag + * @arg RTC_FLAG_TAMP_7: Tamper7 flag + * @arg RTC_FLAG_TAMP_8: Tamper8 flag + * @arg RTC_FLAG_INT_TAMP_1: Internal Tamper1 flag + * @arg RTC_FLAG_INT_TAMP_2: Internal Tamper2 flag + * @arg RTC_FLAG_INT_TAMP_3: Internal Tamper3 flag + * @arg RTC_FLAG_INT_TAMP_4: Internal Tamper4 flag + * @arg RTC_FLAG_INT_TAMP_5: Internal Tamper5 flag + * @arg RTC_FLAG_INT_TAMP_6: Internal Tamper6 flag + * @arg RTC_FLAG_INT_TAMP_7: Internal Tamper7 flag + * @arg RTC_FLAG_INT_TAMP_8: Internal Tamper8 flag + * @arg RTC_FLAG_INT_TAMP_9: Internal Tamper9 flag + * @arg RTC_FLAG_INT_TAMP_11: Internal Tamper11 flag + * @arg RTC_FLAG_INT_TAMP_12: Internal Tamper12 flag + * @arg RTC_FLAG_INT_TAMP_13: Internal Tamper13 flag + * @arg RTC_FLAG_INT_TAMP_15: Internal Tamper15 flag + * @retval None + */ +#define __HAL_RTC_TAMPER_GET_FLAG(__HANDLE__, __FLAG__) (((TAMP->SR) & (__FLAG__)) != 0U) + +/** + * @brief Clear the RTC Tamper's pending flags. + * @param __HANDLE__ specifies the RTC handle. + * @param __FLAG__ specifies the RTC Tamper Flag to clear. + * This parameter can be: + * @arg RTC_FLAG_TAMP_ALL: All tampers flag + * @arg RTC_FLAG_TAMP_1: Tamper1 flag + * @arg RTC_FLAG_TAMP_2: Tamper2 flag + * @arg RTC_FLAG_TAMP_3: Tamper3 flag + * @arg RTC_FLAG_TAMP_4: Tamper4 flag + * @arg RTC_FLAG_TAMP_5: Tamper5 flag + * @arg RTC_FLAG_TAMP_6: Tamper6 flag + * @arg RTC_FLAG_TAMP_7: Tamper7 flag + * @arg RTC_FLAG_TAMP_8: Tamper8 flag + * @arg RTC_FLAG_INT_TAMP_ALL: All Internal Tamper flags + * @arg RTC_FLAG_INT_TAMP_1: Internal Tamper1 flag + * @arg RTC_FLAG_INT_TAMP_2: Internal Tamper2 flag + * @arg RTC_FLAG_INT_TAMP_3: Internal Tamper3 flag + * @arg RTC_FLAG_INT_TAMP_4: Internal Tamper4 flag + * @arg RTC_FLAG_INT_TAMP_5: Internal Tamper5 flag + * @arg RTC_FLAG_INT_TAMP_6: Internal Tamper6 flag + * @arg RTC_FLAG_INT_TAMP_7: Internal Tamper7 flag + * @arg RTC_FLAG_INT_TAMP_8: Internal Tamper8 flag + * @arg RTC_FLAG_INT_TAMP_9: Internal Tamper9 flag + * @arg RTC_FLAG_INT_TAMP_11: Internal Tamper11 flag + * @arg RTC_FLAG_INT_TAMP_12: Internal Tamper12 flag + * @arg RTC_FLAG_INT_TAMP_13: Internal Tamper13 flag + * @arg RTC_FLAG_INT_TAMP_15: Internal Tamper15 flag + * @retval None + */ +#define __HAL_RTC_TAMPER_CLEAR_FLAG(__HANDLE__, __FLAG__) ((TAMP->SCR) = (__FLAG__)) +/** + * @} + */ + +/* --------------------------------- SSR Underflow ---------------------------------*/ +/** @defgroup RTCEx_SSR_Underflow RTC SSR Underflow + * @{ + */ + +/** + * @brief Enable the RTC SSRU interrupt. + * @param __HANDLE__ specifies the RTC handle. + * @param __INTERRUPT__ specifies the RTC SSRU interrupt sources to be enabled. + * This parameter can be: + * @arg @ref RTC_IT_SSRU SSRU interrupt + * @retval None + */ +#define __HAL_RTC_SSRU_ENABLE_IT(__HANDLE__, __INTERRUPT__) (RTC->CR |= (__INTERRUPT__)) + +/** + * @brief Disable the RTC SSRU interrupt. + * @param __HANDLE__ specifies the RTC handle. + * @param __INTERRUPT__ specifies the RTC SSRU interrupt sources to be disabled. + * This parameter can be: + * @arg @ref RTC_IT_SSRU SSRU interrupt + * @retval None + */ +#define __HAL_RTC_SSRU_DISABLE_IT(__HANDLE__, __INTERRUPT__) (RTC->CR &= ~(__INTERRUPT__)) + + +/** + * @brief Check whether the specified RTC SSRU interrupt has occurred or not. + * @param __HANDLE__ specifies the RTC handle. + * @param __INTERRUPT__ specifies the RTC SSRU interrupt to check. + * This parameter can be: + * @arg @ref RTC_IT_SSRU SSRU interrupt + * @retval None + */ +#define __HAL_RTC_SSRU_GET_IT(__HANDLE__, __INTERRUPT__) (((RTC->MISR) & ((__INTERRUPT__) >> 1) != 0U) \ + ? 1U : 0U) +/** + * @brief Check whether the specified RTC Wake Up timer interrupt has been enabled or not. + * @param __HANDLE__ specifies the RTC handle. + * @param __INTERRUPT__ specifies the RTC Wake Up timer interrupt sources to check. + * This parameter can be: + * @arg @ref RTC_IT_SSRU SSRU interrupt + * @retval None + */ +#define __HAL_RTC_SSRU_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((RTC->CR) & (__INTERRUPT__)) != 0U) ? 1U : 0U) + +/** + * @brief Get the selected RTC SSRU's flag status. + * @param __HANDLE__ specifies the RTC handle. + * @param __FLAG__ specifies the RTC SSRU Flag is pending or not. + * This parameter can be: + * @arg @ref RTC_FLAG_SSRUF + * @retval None + */ +#define __HAL_RTC_SSRU_GET_FLAG(__HANDLE__, __FLAG__) (__HAL_RTC_GET_FLAG((__HANDLE__), (__FLAG__))) + +/** + * @brief Clear the RTC Wake Up timer's pending flags. + * @param __HANDLE__ specifies the RTC handle. + * @param __FLAG__ specifies the RTC SSRU Flag to clear. + * This parameter can be: + * @arg @ref RTC_FLAG_SSRUF + * @retval None + */ +#define __HAL_RTC_SSRU_CLEAR_FLAG(__HANDLE__, __FLAG__) (__HAL_RTC_CLEAR_FLAG((__HANDLE__), RTC_CLEAR_SSRUF)) +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup RTCEx_Exported_Functions RTCEx Exported Functions + * @{ + */ + +/* RTC TimeStamp functions *****************************************/ +/** @defgroup RTCEx_Exported_Functions_Group1 Extended RTC TimeStamp functions + * @{ + */ + +#ifdef RTC_CR_TSE +HAL_StatusTypeDef HAL_RTCEx_SetTimeStamp(RTC_HandleTypeDef *hrtc, uint32_t TimeStampEdge, uint32_t RTC_TimeStampPin); +HAL_StatusTypeDef HAL_RTCEx_SetTimeStamp_IT(RTC_HandleTypeDef *hrtc, uint32_t TimeStampEdge, uint32_t RTC_TimeStampPin); +HAL_StatusTypeDef HAL_RTCEx_DeactivateTimeStamp(RTC_HandleTypeDef *hrtc); +#endif /* RTC_CR_TSE */ +HAL_StatusTypeDef HAL_RTCEx_SetInternalTimeStamp(RTC_HandleTypeDef *hrtc); +HAL_StatusTypeDef HAL_RTCEx_DeactivateInternalTimeStamp(RTC_HandleTypeDef *hrtc); +HAL_StatusTypeDef HAL_RTCEx_GetTimeStamp(const RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTimeStamp, + RTC_DateTypeDef *sTimeStampDate, uint32_t Format); +void HAL_RTCEx_TimeStampIRQHandler(RTC_HandleTypeDef *hrtc); +HAL_StatusTypeDef HAL_RTCEx_PollForTimeStampEvent(const RTC_HandleTypeDef *hrtc, uint32_t Timeout); +void HAL_RTCEx_TimeStampEventCallback(RTC_HandleTypeDef *hrtc); +/** + * @} + */ + + +/* RTC Wake-up functions ******************************************************/ +/** @defgroup RTCEx_Exported_Functions_Group2 Extended RTC Wake-up functions + * @{ + */ + +HAL_StatusTypeDef HAL_RTCEx_SetWakeUpTimer(RTC_HandleTypeDef *hrtc, uint32_t WakeUpCounter, uint32_t WakeUpClock); +HAL_StatusTypeDef HAL_RTCEx_SetWakeUpTimer_IT(RTC_HandleTypeDef *hrtc, uint32_t WakeUpCounter, uint32_t WakeUpClock, + uint32_t WakeUpAutoClr); +HAL_StatusTypeDef HAL_RTCEx_DeactivateWakeUpTimer(RTC_HandleTypeDef *hrtc); +uint32_t HAL_RTCEx_GetWakeUpTimer(const RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_WakeUpTimerIRQHandler(RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc); +HAL_StatusTypeDef HAL_RTCEx_PollForWakeUpTimerEvent(const RTC_HandleTypeDef *hrtc, uint32_t Timeout); +/** + * @} + */ + +/* Extended Control functions ************************************************/ +/** @defgroup RTCEx_Exported_Functions_Group3 Extended Peripheral Control functions + * @{ + */ + +HAL_StatusTypeDef HAL_RTCEx_SetSmoothCalib(RTC_HandleTypeDef *hrtc, uint32_t SmoothCalibPeriod, + uint32_t SmoothCalibPlusPulses, uint32_t SmoothCalibMinusPulsesValue); +HAL_StatusTypeDef HAL_RTCEx_SetLowPowerCalib(RTC_HandleTypeDef *hrtc, uint32_t LowPowerCalib); +HAL_StatusTypeDef HAL_RTCEx_SetSynchroShift(RTC_HandleTypeDef *hrtc, uint32_t ShiftAdd1S, uint32_t ShiftSubFS); +#if defined(RTC_CR_COSEL) +HAL_StatusTypeDef HAL_RTCEx_SetCalibrationOutPut(RTC_HandleTypeDef *hrtc, uint32_t CalibOutput); +HAL_StatusTypeDef HAL_RTCEx_DeactivateCalibrationOutPut(RTC_HandleTypeDef *hrtc); +#endif /* RTC_CR_COSEL */ +#if defined(RTC_CR_REFCKON) +HAL_StatusTypeDef HAL_RTCEx_SetRefClock(RTC_HandleTypeDef *hrtc); +HAL_StatusTypeDef HAL_RTCEx_DeactivateRefClock(RTC_HandleTypeDef *hrtc); +#endif /* RTC_CR_REFCKON */ +HAL_StatusTypeDef HAL_RTCEx_EnableBypassShadow(RTC_HandleTypeDef *hrtc); +HAL_StatusTypeDef HAL_RTCEx_DisableBypassShadow(RTC_HandleTypeDef *hrtc); +HAL_StatusTypeDef HAL_RTCEx_MonotonicCounterIncrement(const RTC_HandleTypeDef *hrtc, uint32_t Instance); +HAL_StatusTypeDef HAL_RTCEx_MonotonicCounterGet(const RTC_HandleTypeDef *hrtc, uint32_t Instance, uint32_t *pValue); +HAL_StatusTypeDef HAL_RTCEx_SetSSRU_IT(RTC_HandleTypeDef *hrtc); +HAL_StatusTypeDef HAL_RTCEx_DeactivateSSRU(RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_SSRUIRQHandler(RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_SSRUEventCallback(RTC_HandleTypeDef *hrtc); + +/** + * @} + */ + +/* Extended RTC features functions *******************************************/ +/** @defgroup RTCEx_Exported_Functions_Group4 Extended features functions + * @{ + */ + +void HAL_RTCEx_AlarmBEventCallback(RTC_HandleTypeDef *hrtc); +HAL_StatusTypeDef HAL_RTCEx_PollForAlarmBEvent(const RTC_HandleTypeDef *hrtc, uint32_t Timeout); +/** + * @} + */ + +/** @defgroup RTCEx_Exported_Functions_Group5 Extended RTC Tamper functions + * @{ + */ +HAL_StatusTypeDef HAL_RTCEx_SetTamper(const RTC_HandleTypeDef *hrtc, const RTC_TamperTypeDef *sTamper); +HAL_StatusTypeDef HAL_RTCEx_SetActiveTampers(RTC_HandleTypeDef *hrtc, const RTC_ActiveTampersTypeDef *sAllTamper); +HAL_StatusTypeDef HAL_RTCEx_SetActiveSeed(RTC_HandleTypeDef *hrtc, const uint32_t *pSeed); +HAL_StatusTypeDef HAL_RTCEx_SetTamper_IT(const RTC_HandleTypeDef *hrtc, const RTC_TamperTypeDef *sTamper); +HAL_StatusTypeDef HAL_RTCEx_DeactivateTamper(const RTC_HandleTypeDef *hrtc, uint32_t Tamper); +HAL_StatusTypeDef HAL_RTCEx_DeactivateActiveTampers(const RTC_HandleTypeDef *hrtc); +HAL_StatusTypeDef HAL_RTCEx_PollForTamperEvent(const RTC_HandleTypeDef *hrtc, uint32_t Tamper, uint32_t Timeout); +HAL_StatusTypeDef HAL_RTCEx_SetInternalTamper(const RTC_HandleTypeDef *hrtc, + const RTC_InternalTamperTypeDef *sIntTamper); +HAL_StatusTypeDef HAL_RTCEx_SetInternalTamper_IT(const RTC_HandleTypeDef *hrtc, + const RTC_InternalTamperTypeDef *sIntTamper); +HAL_StatusTypeDef HAL_RTCEx_DeactivateInternalTamper(const RTC_HandleTypeDef *hrtc, uint32_t IntTamper); +HAL_StatusTypeDef HAL_RTCEx_PollForInternalTamperEvent(const RTC_HandleTypeDef *hrtc, uint32_t IntTamper, + uint32_t Timeout); +#if defined(TAMP_SECCFGR_BHKLOCK) +HAL_StatusTypeDef HAL_RTCEx_LockBootHardwareKey(const RTC_HandleTypeDef *hrtc); +#endif /* TAMP_SECCFGR_BHKLOCK */ +void HAL_RTCEx_TamperIRQHandler(RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_Tamper1EventCallback(RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_Tamper2EventCallback(RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_Tamper3EventCallback(RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_Tamper4EventCallback(RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_Tamper5EventCallback(RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_Tamper6EventCallback(RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_Tamper7EventCallback(RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_Tamper8EventCallback(RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_InternalTamper1EventCallback(RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_InternalTamper2EventCallback(RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_InternalTamper3EventCallback(RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_InternalTamper4EventCallback(RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_InternalTamper5EventCallback(RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_InternalTamper6EventCallback(RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_InternalTamper7EventCallback(RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_InternalTamper8EventCallback(RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_InternalTamper9EventCallback(RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_InternalTamper11EventCallback(RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_InternalTamper12EventCallback(RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_InternalTamper13EventCallback(RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_InternalTamper15EventCallback(RTC_HandleTypeDef *hrtc); +/** + * @} + */ + +/** @defgroup RTCEx_Exported_Functions_Group6 Extended RTC Backup register functions + * @{ + */ +void HAL_RTCEx_BKUPWrite(const RTC_HandleTypeDef *hrtc, uint32_t BackupRegister, uint32_t Data); +uint32_t HAL_RTCEx_BKUPRead(const RTC_HandleTypeDef *hrtc, uint32_t BackupRegister); +void HAL_RTCEx_BKUPErase(const RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_BKUPBlock(const RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_BKUPUnblock(const RTC_HandleTypeDef *hrtc); +#ifdef TAMP_ERCFGR_ERCFG0 +void HAL_RTCEx_ConfigEraseDeviceSecrets(const RTC_HandleTypeDef *hrtc, uint32_t DeviceSecretConf); +#endif /* TAMP_ERCFGR_ERCFG0 */ +/** + * @} + */ + +#if defined(RTC_SECCFGR_SEC) +/** @defgroup RTCEx_Exported_Functions_Group7 Extended RTC secure functions + * @{ + */ +HAL_StatusTypeDef HAL_RTCEx_SecureModeGet(const RTC_HandleTypeDef *hrtc, RTC_SecureStateTypeDef *secureState); +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +HAL_StatusTypeDef HAL_RTCEx_SecureModeSet(const RTC_HandleTypeDef *hrtc, const RTC_SecureStateTypeDef *secureState); +#endif /* #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/** + * @} + */ +#endif /* RTC_SECCFGR_SEC */ + +#if defined(TAMP_PRIVCFGR_TAMPPRIV) +/** @defgroup RTCEx_Exported_Functions_Group8 Extended RTC privilege functions + * @{ + */ +HAL_StatusTypeDef HAL_RTCEx_PrivilegeModeSet(const RTC_HandleTypeDef *hrtc, + const RTC_PrivilegeStateTypeDef *privilegeState); +HAL_StatusTypeDef HAL_RTCEx_PrivilegeModeGet(const RTC_HandleTypeDef *hrtc, RTC_PrivilegeStateTypeDef *privilegeState); +/** + * @} + */ +#endif /* TAMP_PRIVCFGR_TAMPPRIV */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup RTCEx_Private_Macros RTCEx Private Macros + * @{ + */ + +/** @defgroup RTCEx_IS_RTC_Definitions Private macros to check input parameters + * @{ + */ +#if defined(RTC_CR_TSEDGE) +#define IS_TIMESTAMP_EDGE(EDGE) (((EDGE) == RTC_TIMESTAMPEDGE_RISING) || \ + ((EDGE) == RTC_TIMESTAMPEDGE_FALLING)) +#endif /* RTC_CR_TSEDGE */ + +#define IS_RTC_TIMESTAMP_PIN(PIN) (((PIN) == RTC_TIMESTAMPPIN_DEFAULT)) + +#define IS_RTC_TIMESTAMPONTAMPER_DETECTION(DETECTION) (((DETECTION) == RTC_TIMESTAMPONTAMPERDETECTION_ENABLE) || \ + ((DETECTION) == RTC_TIMESTAMPONTAMPERDETECTION_DISABLE)) + +#if defined(RTC_CR_TAMPOE) +#define IS_RTC_TAMPER_TAMPERDETECTIONOUTPUT(MODE) (((MODE) == RTC_TAMPERDETECTIONOUTPUT_ENABLE) || \ + ((MODE) == RTC_TAMPERDETECTIONOUTPUT_DISABLE)) +#endif /* RTC_CR_TAMPOE */ + +#define IS_RTC_WAKEUP_CLOCK(CLOCK) (((CLOCK) == RTC_WAKEUPCLOCK_RTCCLK_DIV16) || \ + ((CLOCK) == RTC_WAKEUPCLOCK_RTCCLK_DIV8) || \ + ((CLOCK) == RTC_WAKEUPCLOCK_RTCCLK_DIV4) || \ + ((CLOCK) == RTC_WAKEUPCLOCK_RTCCLK_DIV2) || \ + ((CLOCK) == RTC_WAKEUPCLOCK_CK_SPRE_16BITS) || \ + ((CLOCK) == RTC_WAKEUPCLOCK_CK_SPRE_17BITS)) + +#define IS_RTC_WAKEUP_COUNTER(COUNTER) ((COUNTER) <= RTC_WUTR_WUT) + +#define IS_RTC_SMOOTH_CALIB_PERIOD(PERIOD) (((PERIOD) == RTC_SMOOTHCALIB_PERIOD_32SEC) || \ + ((PERIOD) == RTC_SMOOTHCALIB_PERIOD_16SEC) || \ + ((PERIOD) == RTC_SMOOTHCALIB_PERIOD_8SEC)) + +#define IS_RTC_SMOOTH_CALIB_PLUS(PLUS) (((PLUS) == RTC_SMOOTHCALIB_PLUSPULSES_SET) || \ + ((PLUS) == RTC_SMOOTHCALIB_PLUSPULSES_RESET)) + +#define IS_RTC_SMOOTH_CALIB_MINUS(VALUE) ((VALUE) <= RTC_CALR_CALM) + +#define IS_RTC_LOW_POWER_CALIB(LPCAL) (((LPCAL) == RTC_LPCAL_SET) || \ + ((LPCAL) == RTC_LPCAL_RESET)) + + +#define IS_RTC_TAMPER(__TAMPER__) ((((__TAMPER__) & RTC_TAMPER_ALL) != 0U) && \ + (((__TAMPER__) & ~RTC_TAMPER_ALL) == 0U)) + +#define IS_RTC_INTERNAL_TAMPER(__INT_TAMPER__) ((((__INT_TAMPER__) & RTC_INT_TAMPER_ALL) != 0U) && \ + (((__INT_TAMPER__) & ~RTC_INT_TAMPER_ALL) == 0U)) + +#define IS_RTC_TAMPER_TRIGGER(__TRIGGER__) (((__TRIGGER__) == RTC_TAMPERTRIGGER_RISINGEDGE) || \ + ((__TRIGGER__) == RTC_TAMPERTRIGGER_FALLINGEDGE) || \ + ((__TRIGGER__) == RTC_TAMPERTRIGGER_LOWLEVEL) || \ + ((__TRIGGER__) == RTC_TAMPERTRIGGER_HIGHLEVEL)) + +#define IS_RTC_TAMPER_ERASE_MODE(__MODE__) (((__MODE__) == RTC_TAMPER_ERASE_BACKUP_ENABLE) || \ + ((__MODE__) == RTC_TAMPER_ERASE_BACKUP_DISABLE)) + +#define IS_RTC_TAMPER_MASKFLAG_STATE(__STATE__) (((__STATE__) == RTC_TAMPERMASK_FLAG_ENABLE) || \ + ((__STATE__) == RTC_TAMPERMASK_FLAG_DISABLE)) + +#define IS_RTC_TAMPER_FILTER(__FILTER__) (((__FILTER__) == RTC_TAMPERFILTER_DISABLE) || \ + ((__FILTER__) == RTC_TAMPERFILTER_2SAMPLE) || \ + ((__FILTER__) == RTC_TAMPERFILTER_4SAMPLE) || \ + ((__FILTER__) == RTC_TAMPERFILTER_8SAMPLE)) + +#define IS_RTC_TAMPER_SAMPLING_FREQ(__FREQ__) (((__FREQ__) == RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV32768)|| \ + ((__FREQ__) == RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV16384)|| \ + ((__FREQ__) == RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV8192) || \ + ((__FREQ__) == RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV4096) || \ + ((__FREQ__) == RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV2048) || \ + ((__FREQ__) == RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV1024) || \ + ((__FREQ__) == RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV512) || \ + ((__FREQ__) == RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV256)) + +#define IS_RTC_TAMPER_PRECHARGE_DURATION(__DURATION__) (((__DURATION__) == RTC_TAMPERPRECHARGEDURATION_1RTCCLK) || \ + ((__DURATION__) == RTC_TAMPERPRECHARGEDURATION_2RTCCLK) || \ + ((__DURATION__) == RTC_TAMPERPRECHARGEDURATION_4RTCCLK) || \ + ((__DURATION__) == RTC_TAMPERPRECHARGEDURATION_8RTCCLK)) + +#define IS_RTC_TAMPER_PULLUP_STATE(__STATE__) (((__STATE__) == RTC_TAMPER_PULLUP_ENABLE) || \ + ((__STATE__) == RTC_TAMPER_PULLUP_DISABLE)) + +#define IS_RTC_TAMPER_TIMESTAMPONTAMPER_DETECTION(DETECTION) \ + (((DETECTION) == RTC_TIMESTAMPONTAMPERDETECTION_ENABLE) || \ + ((DETECTION) == RTC_TIMESTAMPONTAMPERDETECTION_DISABLE)) + +#define IS_RTC_ATAMPER_FILTER(__FILTER__) (((__FILTER__) == RTC_ATAMP_FILTER_ENABLE) || \ + ((__FILTER__) == RTC_ATAMP_FILTER_DISABLE)) + +#define IS_RTC_ATAMPER_OUTPUT_CHANGE_PERIOD(__PERIOD__) ((__PERIOD__) <= 7U) + +#define IS_RTC_ATAMPER_ASYNCPRES_RTCCLK(__PRESCALER__) (((__PRESCALER__) == RTC_ATAMP_ASYNCPRES_RTCCLK) || \ + ((__PRESCALER__) == RTC_ATAMP_ASYNCPRES_RTCCLK_2) || \ + ((__PRESCALER__) == RTC_ATAMP_ASYNCPRES_RTCCLK_4) || \ + ((__PRESCALER__) == RTC_ATAMP_ASYNCPRES_RTCCLK_8) || \ + ((__PRESCALER__) == RTC_ATAMP_ASYNCPRES_RTCCLK_16) || \ + ((__PRESCALER__) == RTC_ATAMP_ASYNCPRES_RTCCLK_32) || \ + ((__PRESCALER__) == RTC_ATAMP_ASYNCPRES_RTCCLK_64) || \ + ((__PRESCALER__) == RTC_ATAMP_ASYNCPRES_RTCCLK_128) || \ + ((__PRESCALER__) == RTC_ATAMP_ASYNCPRES_RTCCLK_2048)) + + +#define IS_RTC_BKP(__BKP__) ((__BKP__) < RTC_BKP_NUMBER) + +#define IS_RTC_SHIFT_ADD1S(SEL) (((SEL) == RTC_SHIFTADD1S_RESET) || \ + ((SEL) == RTC_SHIFTADD1S_SET)) + +#define IS_RTC_SHIFT_SUBFS(FS) ((FS) <= RTC_SHIFTR_SUBFS) + +#if defined(RTC_CR_COSEL) +#define IS_RTC_CALIB_OUTPUT(OUTPUT) (((OUTPUT) == RTC_CALIBOUTPUT_512HZ) || \ + ((OUTPUT) == RTC_CALIBOUTPUT_1HZ)) +#endif /* RTC_CR_COSEL */ + +#define IS_RTC_SECURE_FULL(__STATE__) (((__STATE__) == RTC_SECURE_FULL_YES) || \ + ((__STATE__) == RTC_SECURE_FULL_NO)) + +#define IS_RTC_NONSECURE_FEATURES(__FEATURES__) (((__FEATURES__) & ~RTC_NONSECURE_FEATURE_ALL) == 0U) + +#define IS_TAMP_SECURE_FULL(__STATE__) (((__STATE__) == TAMP_SECURE_FULL_YES) || \ + ((__STATE__) == TAMP_SECURE_FULL_NO)) + +#define IS_TAMP_MONOTONIC_CNT_SECURE(__STATE__) (((__STATE__) == TAMP_MONOTONIC_CNT_SECURE_YES) || \ + ((__STATE__) == TAMP_MONOTONIC_CNT_SECURE_NO)) + +#define IS_RTC_PRIVILEGE_FULL(__STATE__) (((__STATE__) == RTC_PRIVILEGE_FULL_YES) || \ + ((__STATE__) == RTC_PRIVILEGE_FULL_NO)) + +#define IS_RTC_PRIVILEGE_FEATURES(__FEATURES__) (((__FEATURES__) & ~RTC_PRIVILEGE_FEATURE_ALL) == 0U) + +#define IS_TAMP_PRIVILEGE_FULL(__STATE__) (((__STATE__) == TAMP_PRIVILEGE_FULL_YES) || \ + ((__STATE__) == TAMP_PRIVILEGE_FULL_NO)) + +#define IS_TAMP_MONOTONIC_CNT_PRIVILEGE(__STATE__) (((__STATE__) == TAMP_MONOTONIC_CNT_PRIVILEGE_YES) || \ + ((__STATE__) == TAMP_MONOTONIC_CNT_PRIVILEGE_NO)) + +#define IS_RTC_PRIVILEGE_BKUP_ZONE(__ZONES__) (((__ZONES__) & ~RTC_PRIVILEGE_BKUP_ZONE_ALL) == 0U) + +#define IS_RTC_BINARY_MODE(MODE) (((MODE) == RTC_BINARY_NONE) || \ + ((MODE) == RTC_BINARY_ONLY) || \ + ((MODE) == RTC_BINARY_MIX )) + +#define IS_RTC_BINARY_MIX_BCDU(BDCU) (((BDCU) == RTC_BINARY_MIX_BCDU_0) || \ + ((BDCU) == RTC_BINARY_MIX_BCDU_1) || \ + ((BDCU) == RTC_BINARY_MIX_BCDU_2) || \ + ((BDCU) == RTC_BINARY_MIX_BCDU_3) || \ + ((BDCU) == RTC_BINARY_MIX_BCDU_4) || \ + ((BDCU) == RTC_BINARY_MIX_BCDU_5) || \ + ((BDCU) == RTC_BINARY_MIX_BCDU_6) || \ + ((BDCU) == RTC_BINARY_MIX_BCDU_7)) + +#define IS_RTC_ALARM_SUB_SECOND_BINARY_MASK(MASK) (((MASK) == 0U) || \ + (((MASK) >= RTC_ALARMSUBSECONDBINMASK_SS31_1) &&\ + ((MASK) <= RTC_ALARMSUBSECONDBINMASK_NONE))) + +#define IS_RTC_ALARMSUBSECONDBIN_AUTOCLR(SEL) (((SEL) == RTC_ALARMSUBSECONDBIN_AUTOCLR_NO) || \ + ((SEL) == RTC_ALARMSUBSECONDBIN_AUTOCLR_YES)) +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_RTC_EX_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_sai.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_sai.h new file mode 100644 index 0000000000..89652fa4df --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_sai.h @@ -0,0 +1,972 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_sai.h + * @author MCD Application Team + * @brief Header file of SAI HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_SAI_H +#define STM32H5xx_HAL_SAI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +#if defined(SAI1) + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup SAI + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup SAI_Exported_Types SAI Exported Types + * @{ + */ + +/** @defgroup SAI_PDM_Structure_definition SAI PDM Structure definition + * @brief SAI PDM Init structure definition + * @{ + */ +typedef struct +{ + FunctionalState Activation; /*!< Enable/disable PDM interface */ + uint32_t MicPairsNbr; /*!< Specifies the number of microphone pairs used. + This parameter must be a number between Min_Data = 1 and Max_Data = 3. */ + uint32_t ClockEnable; /*!< Specifies which clock must be enabled. + This parameter can be a values combination of @ref SAI_PDM_ClockEnable */ +} SAI_PdmInitTypeDef; +/** + * @} + */ + +/** @defgroup SAI_Init_Structure_definition SAI Init Structure definition + * @brief SAI Init Structure definition + * @{ + */ +typedef struct +{ + uint32_t AudioMode; /*!< Specifies the SAI Block audio Mode. + This parameter can be a value of @ref SAI_Block_Mode */ + + uint32_t Synchro; /*!< Specifies SAI Block synchronization + This parameter can be a value of @ref SAI_Block_Synchronization */ + + uint32_t SynchroExt; /*!< Specifies SAI external output synchronization, this setup is common + for BlockA and BlockB + This parameter can be a value of @ref SAI_Block_SyncExt + @note If both audio blocks of same SAI are used, this parameter has + to be set to the same value for each audio block */ + + uint32_t MckOutput; /*!< Specifies whether master clock output will be generated or not. + This parameter can be a value of @ref SAI_Block_MckOutput */ + + uint32_t OutputDrive; /*!< Specifies when SAI Block outputs are driven. + This parameter can be a value of @ref SAI_Block_Output_Drive + @note This value has to be set before enabling the audio block + but after the audio block configuration. */ + + uint32_t NoDivider; /*!< Specifies whether master clock will be divided or not. + This parameter can be a value of @ref SAI_Block_NoDivider + @note If bit NODIV in the SAI_xCR1 register is cleared, the frame length + should be aligned to a number equal to a power of 2, from 8 to 256. + If bit NODIV in the SAI_xCR1 register is set, the frame length can + take any of the values from 8 to 256. */ + + uint32_t FIFOThreshold; /*!< Specifies SAI Block FIFO threshold. + This parameter can be a value of @ref SAI_Block_Fifo_Threshold */ + + uint32_t AudioFrequency; /*!< Specifies the audio frequency sampling. + This parameter can be a value of @ref SAI_Audio_Frequency */ + + uint32_t Mckdiv; /*!< Specifies the master clock divider. + This parameter must be a number between Min_Data = 0 and Max_Data = 63. + @note This parameter is used only if AudioFrequency is set to + SAI_AUDIO_FREQUENCY_MCKDIV otherwise it is internally computed. */ + + uint32_t MckOverSampling; /*!< Specifies the master clock oversampling. + This parameter can be a value of @ref SAI_Block_Mck_OverSampling */ + + uint32_t MonoStereoMode; /*!< Specifies if the mono or stereo mode is selected. + This parameter can be a value of @ref SAI_Mono_Stereo_Mode */ + + uint32_t CompandingMode; /*!< Specifies the companding mode type. + This parameter can be a value of @ref SAI_Block_Companding_Mode */ + + uint32_t TriState; /*!< Specifies the companding mode type. + This parameter can be a value of @ref SAI_TRIState_Management */ + + SAI_PdmInitTypeDef PdmInit; /*!< Specifies the PDM configuration. */ + + /* This part of the structure is automatically filled if your are using the high level initialisation + function HAL_SAI_InitProtocol */ + + uint32_t Protocol; /*!< Specifies the SAI Block protocol. + This parameter can be a value of @ref SAI_Block_Protocol */ + + uint32_t DataSize; /*!< Specifies the SAI Block data size. + This parameter can be a value of @ref SAI_Block_Data_Size */ + + uint32_t FirstBit; /*!< Specifies whether data transfers start from MSB or LSB bit. + This parameter can be a value of @ref SAI_Block_MSB_LSB_transmission */ + + uint32_t ClockStrobing; /*!< Specifies the SAI Block clock strobing edge sensitivity. + This parameter can be a value of @ref SAI_Block_Clock_Strobing */ +} SAI_InitTypeDef; + +/** + * @brief HAL State structures definition + */ +typedef enum +{ + HAL_SAI_STATE_RESET = 0x00U, /*!< SAI not yet initialized or disabled */ + HAL_SAI_STATE_READY = 0x01U, /*!< SAI initialized and ready for use */ + HAL_SAI_STATE_BUSY = 0x02U, /*!< SAI internal process is ongoing */ + HAL_SAI_STATE_BUSY_TX = 0x12U, /*!< Data transmission process is ongoing */ + HAL_SAI_STATE_BUSY_RX = 0x22U, /*!< Data reception process is ongoing */ +} HAL_SAI_StateTypeDef; + +/** + * @brief SAI Callback prototype + */ +typedef void (*SAIcallback)(void); + +/** + * @} + */ + +/** @defgroup SAI_Frame_Structure_definition SAI Frame Structure definition + * @brief SAI Frame Init structure definition + * @note For SPDIF and AC97 protocol, these parameters are not used (set by hardware). + * @{ + */ +typedef struct +{ + + uint32_t FrameLength; /*!< Specifies the Frame length, the number of SCK clocks for each audio frame. + This parameter must be a number between Min_Data = 8 and Max_Data = 256. + @note If master clock MCLK_x pin is declared as an output, the frame length + should be aligned to a number equal to power of 2 in order to keep + in an audio frame, an integer number of MCLK pulses by bit Clock. */ + + uint32_t ActiveFrameLength; /*!< Specifies the Frame synchronization active level length. + This Parameter specifies the length in number of bit clock (SCK + 1) + of the active level of FS signal in audio frame. + This parameter must be a number between Min_Data = 1 and Max_Data = 128 */ + + uint32_t FSDefinition; /*!< Specifies the Frame synchronization definition. + This parameter can be a value of @ref SAI_Block_FS_Definition */ + + uint32_t FSPolarity; /*!< Specifies the Frame synchronization Polarity. + This parameter can be a value of @ref SAI_Block_FS_Polarity */ + + uint32_t FSOffset; /*!< Specifies the Frame synchronization Offset. + This parameter can be a value of @ref SAI_Block_FS_Offset */ + +} SAI_FrameInitTypeDef; +/** + * @} + */ + +/** @defgroup SAI_Slot_Structure_definition SAI Slot Structure definition + * @brief SAI Block Slot Init Structure definition + * @note For SPDIF protocol, these parameters are not used (set by hardware). + * @note For AC97 protocol, only SlotActive parameter is used (the others are set by hardware). + * @{ + */ +typedef struct +{ + uint32_t FirstBitOffset; /*!< Specifies the position of first data transfer bit in the slot. + This parameter must be a number between Min_Data = 0 and Max_Data = 24 */ + + uint32_t SlotSize; /*!< Specifies the Slot Size. + This parameter can be a value of @ref SAI_Block_Slot_Size */ + + uint32_t SlotNumber; /*!< Specifies the number of slot in the audio frame. + This parameter must be a number between Min_Data = 1 and Max_Data = 16 */ + + uint32_t SlotActive; /*!< Specifies the slots in audio frame that will be activated. + This parameter can be a value of @ref SAI_Block_Slot_Active */ +} SAI_SlotInitTypeDef; +/** + * @} + */ + +/** @defgroup SAI_Handle_Structure_definition SAI Handle Structure definition + * @brief SAI handle Structure definition + * @{ + */ +typedef struct __SAI_HandleTypeDef +{ + SAI_Block_TypeDef *Instance; /*!< SAI Blockx registers base address */ + + SAI_InitTypeDef Init; /*!< SAI communication parameters */ + + SAI_FrameInitTypeDef FrameInit; /*!< SAI Frame configuration parameters */ + + SAI_SlotInitTypeDef SlotInit; /*!< SAI Slot configuration parameters */ + + uint8_t *pBuffPtr; /*!< Pointer to SAI transfer Buffer */ + + uint16_t XferSize; /*!< SAI transfer size */ + + uint16_t XferCount; /*!< SAI transfer counter */ + + DMA_HandleTypeDef *hdmatx; /*!< SAI Tx DMA handle parameters */ + + DMA_HandleTypeDef *hdmarx; /*!< SAI Rx DMA handle parameters */ + + SAIcallback mutecallback; /*!< SAI mute callback */ + + void (*InterruptServiceRoutine)(struct __SAI_HandleTypeDef *hsai); /* function pointer for IRQ handler */ + + HAL_LockTypeDef Lock; /*!< SAI locking object */ + + __IO HAL_SAI_StateTypeDef State; /*!< SAI communication state */ + + __IO uint32_t ErrorCode; /*!< SAI Error code */ + +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) + void (*RxCpltCallback)(struct __SAI_HandleTypeDef *hsai); /*!< SAI receive complete callback */ + void (*RxHalfCpltCallback)(struct __SAI_HandleTypeDef *hsai); /*!< SAI receive half complete callback */ + void (*TxCpltCallback)(struct __SAI_HandleTypeDef *hsai); /*!< SAI transmit complete callback */ + void (*TxHalfCpltCallback)(struct __SAI_HandleTypeDef *hsai); /*!< SAI transmit half complete callback */ + void (*ErrorCallback)(struct __SAI_HandleTypeDef *hsai); /*!< SAI error callback */ + void (*MspInitCallback)(struct __SAI_HandleTypeDef *hsai); /*!< SAI MSP init callback */ + void (*MspDeInitCallback)(struct __SAI_HandleTypeDef *hsai); /*!< SAI MSP de-init callback */ +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ +} SAI_HandleTypeDef; + +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) +/** + * @brief SAI callback ID enumeration definition + */ +typedef enum +{ + HAL_SAI_RX_COMPLETE_CB_ID = 0x00U, /*!< SAI receive complete callback ID */ + HAL_SAI_RX_HALFCOMPLETE_CB_ID = 0x01U, /*!< SAI receive half complete callback ID */ + HAL_SAI_TX_COMPLETE_CB_ID = 0x02U, /*!< SAI transmit complete callback ID */ + HAL_SAI_TX_HALFCOMPLETE_CB_ID = 0x03U, /*!< SAI transmit half complete callback ID */ + HAL_SAI_ERROR_CB_ID = 0x04U, /*!< SAI error callback ID */ + HAL_SAI_MSPINIT_CB_ID = 0x05U, /*!< SAI MSP init callback ID */ + HAL_SAI_MSPDEINIT_CB_ID = 0x06U /*!< SAI MSP de-init callback ID */ +} HAL_SAI_CallbackIDTypeDef; + +/** + * @brief SAI callback pointer definition + */ +typedef void (*pSAI_CallbackTypeDef)(SAI_HandleTypeDef *hsai); +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup SAI_Exported_Constants SAI Exported Constants + * @{ + */ + +/** @defgroup SAI_Error_Code SAI Error Code + * @{ + */ +#define HAL_SAI_ERROR_NONE 0x00000000U /*!< No error */ +#define HAL_SAI_ERROR_OVR 0x00000001U /*!< Overrun Error */ +#define HAL_SAI_ERROR_UDR 0x00000002U /*!< Underrun error */ +#define HAL_SAI_ERROR_AFSDET 0x00000004U /*!< Anticipated Frame synchronisation detection */ +#define HAL_SAI_ERROR_LFSDET 0x00000008U /*!< Late Frame synchronisation detection */ +#define HAL_SAI_ERROR_CNREADY 0x00000010U /*!< codec not ready */ +#define HAL_SAI_ERROR_WCKCFG 0x00000020U /*!< Wrong clock configuration */ +#define HAL_SAI_ERROR_TIMEOUT 0x00000040U /*!< Timeout error */ +#define HAL_SAI_ERROR_DMA 0x00000080U /*!< DMA error */ +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) +#define HAL_SAI_ERROR_INVALID_CALLBACK 0x00000100U /*!< Invalid callback error */ +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @defgroup SAI_Block_SyncExt SAI External synchronisation + * @{ + */ +#define SAI_SYNCEXT_DISABLE 0U +#define SAI_SYNCEXT_OUTBLOCKA_ENABLE 1U +#define SAI_SYNCEXT_OUTBLOCKB_ENABLE 2U +/** + * @} + */ + +/** @defgroup SAI_Block_MckOutput SAI Block Master Clock Output + * @{ + */ +#define SAI_MCK_OUTPUT_DISABLE 0x00000000U +#define SAI_MCK_OUTPUT_ENABLE SAI_xCR1_MCKEN +/** + * @} + */ + +/** @defgroup SAI_Protocol SAI Supported protocol + * @{ + */ +#define SAI_I2S_STANDARD 0U +#define SAI_I2S_MSBJUSTIFIED 1U +#define SAI_I2S_LSBJUSTIFIED 2U +#define SAI_PCM_LONG 3U +#define SAI_PCM_SHORT 4U +/** + * @} + */ + +/** @defgroup SAI_Protocol_DataSize SAI protocol data size + * @{ + */ +#define SAI_PROTOCOL_DATASIZE_16BIT 0U +#define SAI_PROTOCOL_DATASIZE_16BITEXTENDED 1U +#define SAI_PROTOCOL_DATASIZE_24BIT 2U +#define SAI_PROTOCOL_DATASIZE_32BIT 3U +/** + * @} + */ + +/** @defgroup SAI_Audio_Frequency SAI Audio Frequency + * @{ + */ +#define SAI_AUDIO_FREQUENCY_192K 192000U +#define SAI_AUDIO_FREQUENCY_96K 96000U +#define SAI_AUDIO_FREQUENCY_48K 48000U +#define SAI_AUDIO_FREQUENCY_44K 44100U +#define SAI_AUDIO_FREQUENCY_32K 32000U +#define SAI_AUDIO_FREQUENCY_22K 22050U +#define SAI_AUDIO_FREQUENCY_16K 16000U +#define SAI_AUDIO_FREQUENCY_11K 11025U +#define SAI_AUDIO_FREQUENCY_8K 8000U +#define SAI_AUDIO_FREQUENCY_MCKDIV 0U +/** + * @} + */ + +/** @defgroup SAI_Block_Mck_OverSampling SAI Block Master Clock OverSampling + * @{ + */ +#define SAI_MCK_OVERSAMPLING_DISABLE 0x00000000U +#define SAI_MCK_OVERSAMPLING_ENABLE SAI_xCR1_OSR +/** + * @} + */ + +/** @defgroup SAI_PDM_ClockEnable SAI PDM Clock Enable + * @{ + */ +#define SAI_PDM_CLOCK1_ENABLE SAI_PDMCR_CKEN1 +#define SAI_PDM_CLOCK2_ENABLE SAI_PDMCR_CKEN2 +/** + * @} + */ + +/** @defgroup SAI_Block_Mode SAI Block Mode + * @{ + */ +#define SAI_MODEMASTER_TX 0x00000000U +#define SAI_MODEMASTER_RX SAI_xCR1_MODE_0 +#define SAI_MODESLAVE_TX SAI_xCR1_MODE_1 +#define SAI_MODESLAVE_RX (SAI_xCR1_MODE_1 | SAI_xCR1_MODE_0) + +/** + * @} + */ + +/** @defgroup SAI_Block_Protocol SAI Block Protocol + * @{ + */ +#define SAI_FREE_PROTOCOL 0x00000000U +#define SAI_SPDIF_PROTOCOL SAI_xCR1_PRTCFG_0 +#define SAI_AC97_PROTOCOL SAI_xCR1_PRTCFG_1 +/** + * @} + */ + +/** @defgroup SAI_Block_Data_Size SAI Block Data Size + * @{ + */ +#define SAI_DATASIZE_8 SAI_xCR1_DS_1 +#define SAI_DATASIZE_10 (SAI_xCR1_DS_1 | SAI_xCR1_DS_0) +#define SAI_DATASIZE_16 SAI_xCR1_DS_2 +#define SAI_DATASIZE_20 (SAI_xCR1_DS_2 | SAI_xCR1_DS_0) +#define SAI_DATASIZE_24 (SAI_xCR1_DS_2 | SAI_xCR1_DS_1) +#define SAI_DATASIZE_32 (SAI_xCR1_DS_2 | SAI_xCR1_DS_1 | SAI_xCR1_DS_0) +/** + * @} + */ + +/** @defgroup SAI_Block_MSB_LSB_transmission SAI Block MSB LSB transmission + * @{ + */ +#define SAI_FIRSTBIT_MSB 0x00000000U +#define SAI_FIRSTBIT_LSB SAI_xCR1_LSBFIRST +/** + * @} + */ + +/** @defgroup SAI_Block_Clock_Strobing SAI Block Clock Strobing + * @{ + */ +#define SAI_CLOCKSTROBING_FALLINGEDGE 0U +#define SAI_CLOCKSTROBING_RISINGEDGE 1U +/** + * @} + */ + +/** @defgroup SAI_Block_Synchronization SAI Block Synchronization + * @{ + */ +#define SAI_ASYNCHRONOUS 0U /*!< Asynchronous */ +#define SAI_SYNCHRONOUS 1U /*!< Synchronous with other block of same SAI */ +#define SAI_SYNCHRONOUS_EXT_SAI1 2U /*!< Synchronous with other SAI, SAI1 */ +#define SAI_SYNCHRONOUS_EXT_SAI2 3U /*!< Synchronous with other SAI, SAI2 */ +/** + * @} + */ + +/** @defgroup SAI_Block_Output_Drive SAI Block Output Drive + * @{ + */ +#define SAI_OUTPUTDRIVE_DISABLE 0x00000000U +#define SAI_OUTPUTDRIVE_ENABLE SAI_xCR1_OUTDRIV +/** + * @} + */ + +/** @defgroup SAI_Block_NoDivider SAI Block NoDivider + * @{ + */ +#define SAI_MASTERDIVIDER_ENABLE 0x00000000U +#define SAI_MASTERDIVIDER_DISABLE SAI_xCR1_NODIV +/** + * @} + */ + +/** @defgroup SAI_Block_FS_Definition SAI Block FS Definition + * @{ + */ +#define SAI_FS_STARTFRAME 0x00000000U +#define SAI_FS_CHANNEL_IDENTIFICATION SAI_xFRCR_FSDEF +/** + * @} + */ + +/** @defgroup SAI_Block_FS_Polarity SAI Block FS Polarity + * @{ + */ +#define SAI_FS_ACTIVE_LOW 0x00000000U +#define SAI_FS_ACTIVE_HIGH SAI_xFRCR_FSPOL +/** + * @} + */ + +/** @defgroup SAI_Block_FS_Offset SAI Block FS Offset + * @{ + */ +#define SAI_FS_FIRSTBIT 0x00000000U +#define SAI_FS_BEFOREFIRSTBIT SAI_xFRCR_FSOFF +/** + * @} + */ + +/** @defgroup SAI_Block_Slot_Size SAI Block Slot Size + * @{ + */ +#define SAI_SLOTSIZE_DATASIZE 0x00000000U +#define SAI_SLOTSIZE_16B SAI_xSLOTR_SLOTSZ_0 +#define SAI_SLOTSIZE_32B SAI_xSLOTR_SLOTSZ_1 +/** + * @} + */ + +/** @defgroup SAI_Block_Slot_Active SAI Block Slot Active + * @{ + */ +#define SAI_SLOT_NOTACTIVE 0x00000000U +#define SAI_SLOTACTIVE_0 0x00000001U +#define SAI_SLOTACTIVE_1 0x00000002U +#define SAI_SLOTACTIVE_2 0x00000004U +#define SAI_SLOTACTIVE_3 0x00000008U +#define SAI_SLOTACTIVE_4 0x00000010U +#define SAI_SLOTACTIVE_5 0x00000020U +#define SAI_SLOTACTIVE_6 0x00000040U +#define SAI_SLOTACTIVE_7 0x00000080U +#define SAI_SLOTACTIVE_8 0x00000100U +#define SAI_SLOTACTIVE_9 0x00000200U +#define SAI_SLOTACTIVE_10 0x00000400U +#define SAI_SLOTACTIVE_11 0x00000800U +#define SAI_SLOTACTIVE_12 0x00001000U +#define SAI_SLOTACTIVE_13 0x00002000U +#define SAI_SLOTACTIVE_14 0x00004000U +#define SAI_SLOTACTIVE_15 0x00008000U +#define SAI_SLOTACTIVE_ALL 0x0000FFFFU +/** + * @} + */ + +/** @defgroup SAI_Mono_Stereo_Mode SAI Mono Stereo Mode + * @{ + */ +#define SAI_STEREOMODE 0x00000000U +#define SAI_MONOMODE SAI_xCR1_MONO +/** + * @} + */ + +/** @defgroup SAI_TRIState_Management SAI TRIState Management + * @{ + */ +#define SAI_OUTPUT_NOTRELEASED 0x00000000U +#define SAI_OUTPUT_RELEASED SAI_xCR2_TRIS +/** + * @} + */ + +/** @defgroup SAI_Block_Fifo_Threshold SAI Block Fifo Threshold + * @{ + */ +#define SAI_FIFOTHRESHOLD_EMPTY 0x00000000U +#define SAI_FIFOTHRESHOLD_1QF SAI_xCR2_FTH_0 +#define SAI_FIFOTHRESHOLD_HF SAI_xCR2_FTH_1 +#define SAI_FIFOTHRESHOLD_3QF (SAI_xCR2_FTH_1 | SAI_xCR2_FTH_0) +#define SAI_FIFOTHRESHOLD_FULL SAI_xCR2_FTH_2 +/** + * @} + */ + +/** @defgroup SAI_Block_Companding_Mode SAI Block Companding Mode + * @{ + */ +#define SAI_NOCOMPANDING 0x00000000U +#define SAI_ULAW_1CPL_COMPANDING SAI_xCR2_COMP_1 +#define SAI_ALAW_1CPL_COMPANDING (SAI_xCR2_COMP_1 | SAI_xCR2_COMP_0) +#define SAI_ULAW_2CPL_COMPANDING (SAI_xCR2_COMP_1 | SAI_xCR2_CPL) +#define SAI_ALAW_2CPL_COMPANDING (SAI_xCR2_COMP_1 | SAI_xCR2_COMP_0 | SAI_xCR2_CPL) +/** + * @} + */ + +/** @defgroup SAI_Block_Mute_Value SAI Block Mute Value + * @{ + */ +#define SAI_ZERO_VALUE 0x00000000U +#define SAI_LAST_SENT_VALUE SAI_xCR2_MUTEVAL +/** + * @} + */ + +/** @defgroup SAI_Block_Interrupts_Definition SAI Block Interrupts Definition + * @{ + */ +#define SAI_IT_OVRUDR SAI_xIMR_OVRUDRIE +#define SAI_IT_MUTEDET SAI_xIMR_MUTEDETIE +#define SAI_IT_WCKCFG SAI_xIMR_WCKCFGIE +#define SAI_IT_FREQ SAI_xIMR_FREQIE +#define SAI_IT_CNRDY SAI_xIMR_CNRDYIE +#define SAI_IT_AFSDET SAI_xIMR_AFSDETIE +#define SAI_IT_LFSDET SAI_xIMR_LFSDETIE +/** + * @} + */ + +/** @defgroup SAI_Block_Flags_Definition SAI Block Flags Definition + * @{ + */ +#define SAI_FLAG_OVRUDR SAI_xSR_OVRUDR +#define SAI_FLAG_MUTEDET SAI_xSR_MUTEDET +#define SAI_FLAG_WCKCFG SAI_xSR_WCKCFG +#define SAI_FLAG_FREQ SAI_xSR_FREQ +#define SAI_FLAG_CNRDY SAI_xSR_CNRDY +#define SAI_FLAG_AFSDET SAI_xSR_AFSDET +#define SAI_FLAG_LFSDET SAI_xSR_LFSDET +/** + * @} + */ + +/** @defgroup SAI_Block_Fifo_Status_Level SAI Block Fifo Status Level + * @{ + */ +#define SAI_FIFOSTATUS_EMPTY 0x00000000U +#define SAI_FIFOSTATUS_LESS1QUARTERFULL 0x00010000U +#define SAI_FIFOSTATUS_1QUARTERFULL 0x00020000U +#define SAI_FIFOSTATUS_HALFFULL 0x00030000U +#define SAI_FIFOSTATUS_3QUARTERFULL 0x00040000U +#define SAI_FIFOSTATUS_FULL 0x00050000U +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup SAI_Exported_Macros SAI Exported Macros + * @brief macros to handle interrupts and specific configurations + * @{ + */ + +/** @brief Reset SAI handle state. + * @param __HANDLE__ specifies the SAI Handle. + * @retval None + */ +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) +#define __HAL_SAI_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->State = HAL_SAI_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_SAI_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_SAI_STATE_RESET) +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ + +/** @brief Enable the specified SAI interrupts. + * @param __HANDLE__ specifies the SAI Handle. + * @param __INTERRUPT__ specifies the interrupt source to enable or disable. + * This parameter can be one of the following values: + * @arg SAI_IT_OVRUDR: Overrun underrun interrupt enable + * @arg SAI_IT_MUTEDET: Mute detection interrupt enable + * @arg SAI_IT_WCKCFG: Wrong Clock Configuration interrupt enable + * @arg SAI_IT_FREQ: FIFO request interrupt enable + * @arg SAI_IT_CNRDY: Codec not ready interrupt enable + * @arg SAI_IT_AFSDET: Anticipated frame synchronization detection interrupt enable + * @arg SAI_IT_LFSDET: Late frame synchronization detection interrupt enable + * @retval None + */ +#define __HAL_SAI_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IMR |= (__INTERRUPT__)) + +/** @brief Disable the specified SAI interrupts. + * @param __HANDLE__ specifies the SAI Handle. + * @param __INTERRUPT__ specifies the interrupt source to enable or disable. + * This parameter can be one of the following values: + * @arg SAI_IT_OVRUDR: Overrun underrun interrupt enable + * @arg SAI_IT_MUTEDET: Mute detection interrupt enable + * @arg SAI_IT_WCKCFG: Wrong Clock Configuration interrupt enable + * @arg SAI_IT_FREQ: FIFO request interrupt enable + * @arg SAI_IT_CNRDY: Codec not ready interrupt enable + * @arg SAI_IT_AFSDET: Anticipated frame synchronization detection interrupt enable + * @arg SAI_IT_LFSDET: Late frame synchronization detection interrupt enable + * @retval None + */ +#define __HAL_SAI_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IMR &= (~(__INTERRUPT__))) + +/** @brief Check whether the specified SAI interrupt source is enabled or not. + * @param __HANDLE__ specifies the SAI Handle. + * @param __INTERRUPT__ specifies the SAI interrupt source to check. + * This parameter can be one of the following values: + * @arg SAI_IT_OVRUDR: Overrun underrun interrupt enable + * @arg SAI_IT_MUTEDET: Mute detection interrupt enable + * @arg SAI_IT_WCKCFG: Wrong Clock Configuration interrupt enable + * @arg SAI_IT_FREQ: FIFO request interrupt enable + * @arg SAI_IT_CNRDY: Codec not ready interrupt enable + * @arg SAI_IT_AFSDET: Anticipated frame synchronization detection interrupt enable + * @arg SAI_IT_LFSDET: Late frame synchronization detection interrupt enable + * @retval The new state of __INTERRUPT__ (TRUE or FALSE). + */ +#define __HAL_SAI_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->IMR & \ + (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) + +/** @brief Check whether the specified SAI flag is set or not. + * @param __HANDLE__ specifies the SAI Handle. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg SAI_FLAG_OVRUDR: Overrun underrun flag. + * @arg SAI_FLAG_MUTEDET: Mute detection flag. + * @arg SAI_FLAG_WCKCFG: Wrong Clock Configuration flag. + * @arg SAI_FLAG_FREQ: FIFO request flag. + * @arg SAI_FLAG_CNRDY: Codec not ready flag. + * @arg SAI_FLAG_AFSDET: Anticipated frame synchronization detection flag. + * @arg SAI_FLAG_LFSDET: Late frame synchronization detection flag. + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_SAI_GET_FLAG(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->SR) & (__FLAG__)) == (__FLAG__)) + +/** @brief Clear the specified SAI pending flag. + * @param __HANDLE__ specifies the SAI Handle. + * @param __FLAG__ specifies the flag to check. + * This parameter can be any combination of the following values: + * @arg SAI_FLAG_OVRUDR: Clear Overrun underrun + * @arg SAI_FLAG_MUTEDET: Clear Mute detection + * @arg SAI_FLAG_WCKCFG: Clear Wrong Clock Configuration + * @arg SAI_FLAG_FREQ: Clear FIFO request + * @arg SAI_FLAG_CNRDY: Clear Codec not ready + * @arg SAI_FLAG_AFSDET: Clear Anticipated frame synchronization detection + * @arg SAI_FLAG_LFSDET: Clear Late frame synchronization detection + * + * @retval None + */ +#define __HAL_SAI_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->CLRFR = (__FLAG__)) + +/** @brief Enable SAI. + * @param __HANDLE__ specifies the SAI Handle. + * @retval None + */ +#define __HAL_SAI_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= SAI_xCR1_SAIEN) + +/** @brief Disable SAI. + * @param __HANDLE__ specifies the SAI Handle. + * @retval None + */ +#define __HAL_SAI_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~SAI_xCR1_SAIEN) + +/** + * @} + */ + +/* Include SAI HAL Extension module */ +#include "stm32h5xx_hal_sai_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup SAI_Exported_Functions + * @{ + */ + +/* Initialization/de-initialization functions ********************************/ +/** @addtogroup SAI_Exported_Functions_Group1 + * @{ + */ +HAL_StatusTypeDef HAL_SAI_InitProtocol(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot); +HAL_StatusTypeDef HAL_SAI_Init(SAI_HandleTypeDef *hsai); +HAL_StatusTypeDef HAL_SAI_DeInit(SAI_HandleTypeDef *hsai); +void HAL_SAI_MspInit(SAI_HandleTypeDef *hsai); +void HAL_SAI_MspDeInit(SAI_HandleTypeDef *hsai); + +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) +/* SAI callbacks register/unregister functions ********************************/ +HAL_StatusTypeDef HAL_SAI_RegisterCallback(SAI_HandleTypeDef *hsai, + HAL_SAI_CallbackIDTypeDef CallbackID, + pSAI_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_SAI_UnRegisterCallback(SAI_HandleTypeDef *hsai, + HAL_SAI_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ +/** + * @} + */ + +/* I/O operation functions ***************************************************/ +/** @addtogroup SAI_Exported_Functions_Group2 + * @{ + */ +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_SAI_Transmit(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_SAI_Receive(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size, uint32_t Timeout); + +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_SAI_Transmit_IT(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_SAI_Receive_IT(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size); + +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_SAI_Transmit_DMA(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_SAI_Receive_DMA(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_SAI_DMAPause(SAI_HandleTypeDef *hsai); +HAL_StatusTypeDef HAL_SAI_DMAResume(SAI_HandleTypeDef *hsai); +HAL_StatusTypeDef HAL_SAI_DMAStop(SAI_HandleTypeDef *hsai); + +/* Abort function */ +HAL_StatusTypeDef HAL_SAI_Abort(SAI_HandleTypeDef *hsai); + +/* Mute management */ +HAL_StatusTypeDef HAL_SAI_EnableTxMuteMode(SAI_HandleTypeDef *hsai, uint16_t val); +HAL_StatusTypeDef HAL_SAI_DisableTxMuteMode(SAI_HandleTypeDef *hsai); +HAL_StatusTypeDef HAL_SAI_EnableRxMuteMode(SAI_HandleTypeDef *hsai, SAIcallback callback, uint16_t counter); +HAL_StatusTypeDef HAL_SAI_DisableRxMuteMode(SAI_HandleTypeDef *hsai); + +/* SAI IRQHandler and Callbacks used in non blocking modes (Interrupt and DMA) */ +void HAL_SAI_IRQHandler(SAI_HandleTypeDef *hsai); +void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai); +void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai); +void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai); +void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai); +void HAL_SAI_ErrorCallback(SAI_HandleTypeDef *hsai); +/** + * @} + */ + +/** @addtogroup SAI_Exported_Functions_Group3 + * @{ + */ +/* Peripheral State functions ************************************************/ +HAL_SAI_StateTypeDef HAL_SAI_GetState(const SAI_HandleTypeDef *hsai); +uint32_t HAL_SAI_GetError(const SAI_HandleTypeDef *hsai); +/** + * @} + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup SAI_Private_Macros SAI Private Macros + * @{ + */ +#define IS_SAI_BLOCK_SYNCEXT(STATE) (((STATE) == SAI_SYNCEXT_DISABLE) ||\ + ((STATE) == SAI_SYNCEXT_OUTBLOCKA_ENABLE) ||\ + ((STATE) == SAI_SYNCEXT_OUTBLOCKB_ENABLE)) + +#define IS_SAI_SUPPORTED_PROTOCOL(PROTOCOL) (((PROTOCOL) == SAI_I2S_STANDARD) ||\ + ((PROTOCOL) == SAI_I2S_MSBJUSTIFIED) ||\ + ((PROTOCOL) == SAI_I2S_LSBJUSTIFIED) ||\ + ((PROTOCOL) == SAI_PCM_LONG) ||\ + ((PROTOCOL) == SAI_PCM_SHORT)) + +#define IS_SAI_PROTOCOL_DATASIZE(DATASIZE) (((DATASIZE) == SAI_PROTOCOL_DATASIZE_16BIT) ||\ + ((DATASIZE) == SAI_PROTOCOL_DATASIZE_16BITEXTENDED) ||\ + ((DATASIZE) == SAI_PROTOCOL_DATASIZE_24BIT) ||\ + ((DATASIZE) == SAI_PROTOCOL_DATASIZE_32BIT)) + +#define IS_SAI_AUDIO_FREQUENCY(AUDIO) (((AUDIO) == SAI_AUDIO_FREQUENCY_192K) || \ + ((AUDIO) == SAI_AUDIO_FREQUENCY_96K) || \ + ((AUDIO) == SAI_AUDIO_FREQUENCY_48K) || \ + ((AUDIO) == SAI_AUDIO_FREQUENCY_44K) || \ + ((AUDIO) == SAI_AUDIO_FREQUENCY_32K) || \ + ((AUDIO) == SAI_AUDIO_FREQUENCY_22K) || \ + ((AUDIO) == SAI_AUDIO_FREQUENCY_16K) || \ + ((AUDIO) == SAI_AUDIO_FREQUENCY_11K) || \ + ((AUDIO) == SAI_AUDIO_FREQUENCY_8K) || \ + ((AUDIO) == SAI_AUDIO_FREQUENCY_MCKDIV)) + +#define IS_SAI_BLOCK_MCK_OVERSAMPLING(VALUE) (((VALUE) == SAI_MCK_OVERSAMPLING_DISABLE) || \ + ((VALUE) == SAI_MCK_OVERSAMPLING_ENABLE)) + +#define IS_SAI_PDM_MIC_PAIRS_NUMBER(VALUE) ((1U <= (VALUE)) && ((VALUE) <= 3U)) + +#define IS_SAI_PDM_CLOCK_ENABLE(CLOCK) (((CLOCK) != 0U) && \ + (((CLOCK) & ~(SAI_PDM_CLOCK1_ENABLE | SAI_PDM_CLOCK2_ENABLE)) == 0U)) + +#define IS_SAI_BLOCK_MODE(MODE) (((MODE) == SAI_MODEMASTER_TX) || \ + ((MODE) == SAI_MODEMASTER_RX) || \ + ((MODE) == SAI_MODESLAVE_TX) || \ + ((MODE) == SAI_MODESLAVE_RX)) + +#define IS_SAI_BLOCK_PROTOCOL(PROTOCOL) (((PROTOCOL) == SAI_FREE_PROTOCOL) || \ + ((PROTOCOL) == SAI_AC97_PROTOCOL) || \ + ((PROTOCOL) == SAI_SPDIF_PROTOCOL)) + +#define IS_SAI_BLOCK_DATASIZE(DATASIZE) (((DATASIZE) == SAI_DATASIZE_8) || \ + ((DATASIZE) == SAI_DATASIZE_10) || \ + ((DATASIZE) == SAI_DATASIZE_16) || \ + ((DATASIZE) == SAI_DATASIZE_20) || \ + ((DATASIZE) == SAI_DATASIZE_24) || \ + ((DATASIZE) == SAI_DATASIZE_32)) + +#define IS_SAI_BLOCK_FIRST_BIT(BIT) (((BIT) == SAI_FIRSTBIT_MSB) || \ + ((BIT) == SAI_FIRSTBIT_LSB)) + +#define IS_SAI_BLOCK_CLOCK_STROBING(CLOCK) (((CLOCK) == SAI_CLOCKSTROBING_FALLINGEDGE) || \ + ((CLOCK) == SAI_CLOCKSTROBING_RISINGEDGE)) + +#define IS_SAI_BLOCK_SYNCHRO(SYNCHRO) (((SYNCHRO) == SAI_ASYNCHRONOUS) || \ + ((SYNCHRO) == SAI_SYNCHRONOUS) || \ + ((SYNCHRO) == SAI_SYNCHRONOUS_EXT_SAI1) || \ + ((SYNCHRO) == SAI_SYNCHRONOUS_EXT_SAI2)) + +#define IS_SAI_BLOCK_MCK_OUTPUT(VALUE) (((VALUE) == SAI_MCK_OUTPUT_ENABLE) || \ + ((VALUE) == SAI_MCK_OUTPUT_DISABLE)) + +#define IS_SAI_BLOCK_OUTPUT_DRIVE(DRIVE) (((DRIVE) == SAI_OUTPUTDRIVE_DISABLE) || \ + ((DRIVE) == SAI_OUTPUTDRIVE_ENABLE)) + +#define IS_SAI_BLOCK_NODIVIDER(NODIVIDER) (((NODIVIDER) == SAI_MASTERDIVIDER_ENABLE) || \ + ((NODIVIDER) == SAI_MASTERDIVIDER_DISABLE)) + +#define IS_SAI_BLOCK_MUTE_COUNTER(COUNTER) ((COUNTER) <= 63U) + +#define IS_SAI_BLOCK_MUTE_VALUE(VALUE) (((VALUE) == SAI_ZERO_VALUE) || \ + ((VALUE) == SAI_LAST_SENT_VALUE)) + +#define IS_SAI_BLOCK_COMPANDING_MODE(MODE) (((MODE) == SAI_NOCOMPANDING) || \ + ((MODE) == SAI_ULAW_1CPL_COMPANDING) || \ + ((MODE) == SAI_ALAW_1CPL_COMPANDING) || \ + ((MODE) == SAI_ULAW_2CPL_COMPANDING) || \ + ((MODE) == SAI_ALAW_2CPL_COMPANDING)) + +#define IS_SAI_BLOCK_FIFO_THRESHOLD(THRESHOLD) (((THRESHOLD) == SAI_FIFOTHRESHOLD_EMPTY) || \ + ((THRESHOLD) == SAI_FIFOTHRESHOLD_1QF) || \ + ((THRESHOLD) == SAI_FIFOTHRESHOLD_HF) || \ + ((THRESHOLD) == SAI_FIFOTHRESHOLD_3QF) || \ + ((THRESHOLD) == SAI_FIFOTHRESHOLD_FULL)) + +#define IS_SAI_BLOCK_TRISTATE_MANAGEMENT(STATE) (((STATE) == SAI_OUTPUT_NOTRELEASED) ||\ + ((STATE) == SAI_OUTPUT_RELEASED)) + +#define IS_SAI_MONO_STEREO_MODE(MODE) (((MODE) == SAI_MONOMODE) ||\ + ((MODE) == SAI_STEREOMODE)) + +#define IS_SAI_SLOT_ACTIVE(ACTIVE) ((ACTIVE) <= SAI_SLOTACTIVE_ALL) + +#define IS_SAI_BLOCK_SLOT_NUMBER(NUMBER) ((1U <= (NUMBER)) && ((NUMBER) <= 16U)) + +#define IS_SAI_BLOCK_SLOT_SIZE(SIZE) (((SIZE) == SAI_SLOTSIZE_DATASIZE) || \ + ((SIZE) == SAI_SLOTSIZE_16B) || \ + ((SIZE) == SAI_SLOTSIZE_32B)) + +#define IS_SAI_BLOCK_FIRSTBIT_OFFSET(OFFSET) ((OFFSET) <= 24U) + +#define IS_SAI_BLOCK_FS_OFFSET(OFFSET) (((OFFSET) == SAI_FS_FIRSTBIT) || \ + ((OFFSET) == SAI_FS_BEFOREFIRSTBIT)) + +#define IS_SAI_BLOCK_FS_POLARITY(POLARITY) (((POLARITY) == SAI_FS_ACTIVE_LOW) || \ + ((POLARITY) == SAI_FS_ACTIVE_HIGH)) + +#define IS_SAI_BLOCK_FS_DEFINITION(DEFINITION) (((DEFINITION) == SAI_FS_STARTFRAME) || \ + ((DEFINITION) == SAI_FS_CHANNEL_IDENTIFICATION)) + +#define IS_SAI_BLOCK_MASTER_DIVIDER(DIVIDER) ((DIVIDER) <= 63U) + +#define IS_SAI_BLOCK_FRAME_LENGTH(LENGTH) ((8U <= (LENGTH)) && ((LENGTH) <= 256U)) + +#define IS_SAI_BLOCK_ACTIVE_FRAME(LENGTH) ((1U <= (LENGTH)) && ((LENGTH) <= 128U)) + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup SAI_Private_Functions SAI Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* SAI1 */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_SAI_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_sai_ex.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_sai_ex.h new file mode 100644 index 0000000000..6c9225e620 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_sai_ex.h @@ -0,0 +1,107 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_sai_ex.h + * @author MCD Application Team + * @brief Header file of SAI HAL extended module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_SAI_EX_H +#define STM32H5xx_HAL_SAI_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +#if defined(SAI1) + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup SAIEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup SAIEx_Exported_Types SAIEx Exported Types + * @{ + */ + +/** + * @brief PDM microphone delay structure definition + */ +typedef struct +{ + uint32_t MicPair; /*!< Specifies which pair of microphones is selected. + This parameter must be a number between Min_Data = 1 and Max_Data = 3. */ + + uint32_t LeftDelay; /*!< Specifies the delay in PDM clock unit to apply on left microphone. + This parameter must be a number between Min_Data = 0 and Max_Data = 7. */ + + uint32_t RightDelay; /*!< Specifies the delay in PDM clock unit to apply on right microphone. + This parameter must be a number between Min_Data = 0 and Max_Data = 7. */ +} SAIEx_PdmMicDelayParamTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/* Exported macros -----------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup SAIEx_Exported_Functions SAIEx Extended Exported Functions + * @{ + */ + +/** @addtogroup SAIEx_Exported_Functions_Group1 Peripheral Control functions + * @{ + */ +HAL_StatusTypeDef HAL_SAIEx_ConfigPdmMicDelay(const SAI_HandleTypeDef *hsai, + const SAIEx_PdmMicDelayParamTypeDef *pdmMicDelay); +/** + * @} + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup SAIEx_Private_Macros SAIEx Extended Private Macros + * @{ + */ +#define IS_SAI_PDM_MIC_DELAY(VALUE) ((VALUE) <= 7U) +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* SAI1 */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_SAI_EX_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_sd.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_sd.h new file mode 100644 index 0000000000..334b98fa86 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_sd.h @@ -0,0 +1,798 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_sd.h + * @author MCD Application Team + * @brief Header file of SD HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_SD_H +#define STM32H5xx_HAL_SD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_sdmmc.h" +#if defined (DLYB_SDMMC1) || defined (DLYB_SDMMC2) || defined (DLYB_SDMMC3) +#include "stm32h5xx_ll_dlyb.h" +#endif /* (DLYB_SDMMC1) || (DLYB_SDMMC2) */ + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ +#if defined (SDMMC1) || defined (SDMMC2) + +/** @defgroup SD SD + * @brief SD HAL module driver + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup SD_Exported_Types SD Exported Types + * @{ + */ + +/** @defgroup SD_Exported_Types_Group1 SD State enumeration structure + * @{ + */ +typedef enum +{ + HAL_SD_STATE_RESET = ((uint32_t)0x00000000U), /*!< SD not yet initialized or disabled */ + HAL_SD_STATE_READY = ((uint32_t)0x00000001U), /*!< SD initialized and ready for use */ + HAL_SD_STATE_TIMEOUT = ((uint32_t)0x00000002U), /*!< SD Timeout state */ + HAL_SD_STATE_BUSY = ((uint32_t)0x00000003U), /*!< SD process ongoing */ + HAL_SD_STATE_PROGRAMMING = ((uint32_t)0x00000004U), /*!< SD Programming State */ + HAL_SD_STATE_RECEIVING = ((uint32_t)0x00000005U), /*!< SD Receiving State */ + HAL_SD_STATE_TRANSFER = ((uint32_t)0x00000006U), /*!< SD Transfer State */ + HAL_SD_STATE_ERROR = ((uint32_t)0x0000000FU) /*!< SD is in error state */ +} HAL_SD_StateTypeDef; +/** + * @} + */ + +/** @defgroup SD_Exported_Types_Group2 SD Card State enumeration structure + * @{ + */ +typedef uint32_t HAL_SD_CardStateTypeDef; + +#define HAL_SD_CARD_READY 0x00000001U /*!< Card state is ready */ +#define HAL_SD_CARD_IDENTIFICATION 0x00000002U /*!< Card is in identification state */ +#define HAL_SD_CARD_STANDBY 0x00000003U /*!< Card is in standby state */ +#define HAL_SD_CARD_TRANSFER 0x00000004U /*!< Card is in transfer state */ +#define HAL_SD_CARD_SENDING 0x00000005U /*!< Card is sending an operation */ +#define HAL_SD_CARD_RECEIVING 0x00000006U /*!< Card is receiving operation information */ +#define HAL_SD_CARD_PROGRAMMING 0x00000007U /*!< Card is in programming state */ +#define HAL_SD_CARD_DISCONNECTED 0x00000008U /*!< Card is disconnected */ +#define HAL_SD_CARD_ERROR 0x000000FFU /*!< Card response Error */ +/** + * @} + */ + +/** @defgroup SD_Exported_Types_Group3 SD Handle Structure definition + * @{ + */ +#define SD_InitTypeDef SDMMC_InitTypeDef +#define SD_TypeDef SDMMC_TypeDef + +/** + * @brief SD Card Information Structure definition + */ +typedef struct +{ + uint32_t CardType; /*!< Specifies the card Type */ + + uint32_t CardVersion; /*!< Specifies the card version */ + + uint32_t Class; /*!< Specifies the class of the card class */ + + uint32_t RelCardAdd; /*!< Specifies the Relative Card Address */ + + uint32_t BlockNbr; /*!< Specifies the Card Capacity in blocks */ + + uint32_t BlockSize; /*!< Specifies one block size in bytes */ + + uint32_t LogBlockNbr; /*!< Specifies the Card logical Capacity in blocks */ + + uint32_t LogBlockSize; /*!< Specifies logical block size in bytes */ + + uint32_t CardSpeed; /*!< Specifies the card Speed */ + +} HAL_SD_CardInfoTypeDef; + +/** + * @brief SD handle Structure definition + */ +#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U) +typedef struct __SD_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_SD_REGISTER_CALLBACKS */ +{ + SD_TypeDef *Instance; /*!< SD registers base address */ + + SD_InitTypeDef Init; /*!< SD required parameters */ + + HAL_LockTypeDef Lock; /*!< SD locking object */ + + const uint8_t *pTxBuffPtr; /*!< Pointer to SD Tx transfer Buffer */ + + uint32_t TxXferSize; /*!< SD Tx Transfer size */ + + uint8_t *pRxBuffPtr; /*!< Pointer to SD Rx transfer Buffer */ + + uint32_t RxXferSize; /*!< SD Rx Transfer size */ + + __IO uint32_t Context; /*!< SD transfer context */ + + __IO HAL_SD_StateTypeDef State; /*!< SD card State */ + + __IO uint32_t ErrorCode; /*!< SD Card Error codes */ + + HAL_SD_CardInfoTypeDef SdCard; /*!< SD Card information */ + + uint32_t CSD[4]; /*!< SD card specific data table */ + + uint32_t CID[4]; /*!< SD card identification number table */ + +#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U) + void (* TxCpltCallback)(struct __SD_HandleTypeDef *hsd); + void (* RxCpltCallback)(struct __SD_HandleTypeDef *hsd); + void (* ErrorCallback)(struct __SD_HandleTypeDef *hsd); + void (* AbortCpltCallback)(struct __SD_HandleTypeDef *hsd); + void (* Read_DMALnkLstBufCpltCallback)(struct __SD_HandleTypeDef *hsd); + void (* Write_DMALnkLstBufCpltCallback)(struct __SD_HandleTypeDef *hsd); +#if (USE_SD_TRANSCEIVER != 0U) + void (* DriveTransceiver_1_8V_Callback)(FlagStatus status); +#endif /* USE_SD_TRANSCEIVER */ + + void (* MspInitCallback)(struct __SD_HandleTypeDef *hsd); + void (* MspDeInitCallback)(struct __SD_HandleTypeDef *hsd); +#endif /* USE_HAL_SD_REGISTER_CALLBACKS */ +} SD_HandleTypeDef; + +/** + * @} + */ + +/** @defgroup SD_Exported_Types_Group4 Card Specific Data: CSD Register + * @{ + */ +typedef struct +{ + __IO uint8_t CSDStruct; /*!< CSD structure */ + __IO uint8_t SysSpecVersion; /*!< System specification version */ + __IO uint8_t Reserved1; /*!< Reserved */ + __IO uint8_t TAAC; /*!< Data read access time 1 */ + __IO uint8_t NSAC; /*!< Data read access time 2 in CLK cycles */ + __IO uint8_t MaxBusClkFrec; /*!< Max. bus clock frequency */ + __IO uint16_t CardComdClasses; /*!< Card command classes */ + __IO uint8_t RdBlockLen; /*!< Max. read data block length */ + __IO uint8_t PartBlockRead; /*!< Partial blocks for read allowed */ + __IO uint8_t WrBlockMisalign; /*!< Write block misalignment */ + __IO uint8_t RdBlockMisalign; /*!< Read block misalignment */ + __IO uint8_t DSRImpl; /*!< DSR implemented */ + __IO uint8_t Reserved2; /*!< Reserved */ + __IO uint32_t DeviceSize; /*!< Device Size */ + __IO uint8_t MaxRdCurrentVDDMin; /*!< Max. read current @ VDD min */ + __IO uint8_t MaxRdCurrentVDDMax; /*!< Max. read current @ VDD max */ + __IO uint8_t MaxWrCurrentVDDMin; /*!< Max. write current @ VDD min */ + __IO uint8_t MaxWrCurrentVDDMax; /*!< Max. write current @ VDD max */ + __IO uint8_t DeviceSizeMul; /*!< Device size multiplier */ + __IO uint8_t EraseGrSize; /*!< Erase group size */ + __IO uint8_t EraseGrMul; /*!< Erase group size multiplier */ + __IO uint8_t WrProtectGrSize; /*!< Write protect group size */ + __IO uint8_t WrProtectGrEnable; /*!< Write protect group enable */ + __IO uint8_t ManDeflECC; /*!< Manufacturer default ECC */ + __IO uint8_t WrSpeedFact; /*!< Write speed factor */ + __IO uint8_t MaxWrBlockLen; /*!< Max. write data block length */ + __IO uint8_t WriteBlockPaPartial; /*!< Partial blocks for write allowed */ + __IO uint8_t Reserved3; /*!< Reserved */ + __IO uint8_t ContentProtectAppli; /*!< Content protection application */ + __IO uint8_t FileFormatGroup; /*!< File format group */ + __IO uint8_t CopyFlag; /*!< Copy flag (OTP) */ + __IO uint8_t PermWrProtect; /*!< Permanent write protection */ + __IO uint8_t TempWrProtect; /*!< Temporary write protection */ + __IO uint8_t FileFormat; /*!< File format */ + __IO uint8_t ECC; /*!< ECC code */ + __IO uint8_t CSD_CRC; /*!< CSD CRC */ + __IO uint8_t Reserved4; /*!< Always 1 */ +} HAL_SD_CardCSDTypeDef; +/** + * @} + */ + +/** @defgroup SD_Exported_Types_Group5 Card Identification Data: CID Register + * @{ + */ +typedef struct +{ + __IO uint8_t ManufacturerID; /*!< Manufacturer ID */ + __IO uint16_t OEM_AppliID; /*!< OEM/Application ID */ + __IO uint32_t ProdName1; /*!< Product Name part1 */ + __IO uint8_t ProdName2; /*!< Product Name part2 */ + __IO uint8_t ProdRev; /*!< Product Revision */ + __IO uint32_t ProdSN; /*!< Product Serial Number */ + __IO uint8_t Reserved1; /*!< Reserved1 */ + __IO uint16_t ManufactDate; /*!< Manufacturing Date */ + __IO uint8_t CID_CRC; /*!< CID CRC */ + __IO uint8_t Reserved2; /*!< Always 1 */ + +} HAL_SD_CardCIDTypeDef; +/** + * @} + */ + +/** @defgroup SD_Exported_Types_Group6 SD Card Status returned by ACMD13 + * @{ + */ +typedef struct +{ + __IO uint8_t DataBusWidth; /*!< Shows the currently defined data bus width */ + __IO uint8_t SecuredMode; /*!< Card is in secured mode of operation */ + __IO uint16_t CardType; /*!< Carries information about card type */ + __IO uint32_t ProtectedAreaSize; /*!< Carries information about the capacity of protected area */ + __IO uint8_t SpeedClass; /*!< Carries information about the speed class of the card */ + __IO uint8_t PerformanceMove; /*!< Carries information about the card's performance move */ + __IO uint8_t AllocationUnitSize; /*!< Carries information about the card's allocation unit size */ + __IO uint16_t EraseSize; /*!< Determines the number of AUs to be erased in one operation */ + __IO uint8_t EraseTimeout; /*!< Determines the timeout for any number of AU erase */ + __IO uint8_t EraseOffset; /*!< Carries information about the erase offset */ + __IO uint8_t UhsSpeedGrade; /*!< Carries information about the speed grade of UHS card */ + __IO uint8_t UhsAllocationUnitSize; /*!< Carries information about the UHS card's allocation unit size */ + __IO uint8_t VideoSpeedClass; /*!< Carries information about the Video Speed Class of UHS card */ +} HAL_SD_CardStatusTypeDef; +/** + * @} + */ + +#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U) +/** @defgroup SD_Exported_Types_Group7 SD Callback ID enumeration definition + * @{ + */ +typedef enum +{ + HAL_SD_TX_CPLT_CB_ID = 0x00U, /*!< SD Tx Complete Callback ID */ + HAL_SD_RX_CPLT_CB_ID = 0x01U, /*!< SD Rx Complete Callback ID */ + HAL_SD_ERROR_CB_ID = 0x02U, /*!< SD Error Callback ID */ + HAL_SD_ABORT_CB_ID = 0x03U, /*!< SD Abort Callback ID */ + HAL_SD_READ_DMA_LNKLST_BUF_CPLT_CB_ID = 0x04U, /*!< SD DMA Rx Linked List Node buffer Callback ID */ + HAL_SD_WRITE_DMA_LNKLST_BUF_CPLT_CB_ID = 0x05U, /*!< SD DMA Tx Linked List Node buffer Callback ID */ + + HAL_SD_MSP_INIT_CB_ID = 0x10U, /*!< SD MspInit Callback ID */ + HAL_SD_MSP_DEINIT_CB_ID = 0x11U /*!< SD MspDeInit Callback ID */ +} HAL_SD_CallbackIDTypeDef; +/** + * @} + */ + +/** @defgroup SD_Exported_Types_Group8 SD Callback pointer definition + * @{ + */ +typedef void (*pSD_CallbackTypeDef)(SD_HandleTypeDef *hsd); +#if (USE_SD_TRANSCEIVER != 0U) +typedef void (*pSD_TransceiverCallbackTypeDef)(FlagStatus status); +#endif /* USE_SD_TRANSCEIVER */ +/** + * @} + */ +#endif /* USE_HAL_SD_REGISTER_CALLBACKS */ +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup SD_Exported_Constants SD Exported Constants + * @{ + */ + +#define BLOCKSIZE ((uint32_t)512U) /*!< Block size is 512 bytes */ + +/** @defgroup SD_Exported_Constansts_Group1 SD Error status enumeration Structure definition + * @{ + */ +#define HAL_SD_ERROR_NONE SDMMC_ERROR_NONE /*!< No error */ +#define HAL_SD_ERROR_CMD_CRC_FAIL SDMMC_ERROR_CMD_CRC_FAIL /*!< Command response received (but CRC check failed) */ +#define HAL_SD_ERROR_DATA_CRC_FAIL SDMMC_ERROR_DATA_CRC_FAIL /*!< Data block sent/received (CRC check failed) */ +#define HAL_SD_ERROR_CMD_RSP_TIMEOUT SDMMC_ERROR_CMD_RSP_TIMEOUT /*!< Command response timeout */ +#define HAL_SD_ERROR_DATA_TIMEOUT SDMMC_ERROR_DATA_TIMEOUT /*!< Data timeout */ +#define HAL_SD_ERROR_TX_UNDERRUN SDMMC_ERROR_TX_UNDERRUN /*!< Transmit FIFO underrun */ +#define HAL_SD_ERROR_RX_OVERRUN SDMMC_ERROR_RX_OVERRUN /*!< Receive FIFO overrun */ +#define HAL_SD_ERROR_ADDR_MISALIGNED SDMMC_ERROR_ADDR_MISALIGNED /*!< Misaligned address */ +#define HAL_SD_ERROR_BLOCK_LEN_ERR SDMMC_ERROR_BLOCK_LEN_ERR /*!< Transferred block length is not allowed for the card or the */ +/*!< number of transferred bytes does not match the block length */ +#define HAL_SD_ERROR_ERASE_SEQ_ERR SDMMC_ERROR_ERASE_SEQ_ERR /*!< An error in the sequence of erase command occurs */ +#define HAL_SD_ERROR_BAD_ERASE_PARAM SDMMC_ERROR_BAD_ERASE_PARAM /*!< An invalid selection for erase groups */ +#define HAL_SD_ERROR_WRITE_PROT_VIOLATION SDMMC_ERROR_WRITE_PROT_VIOLATION /*!< Attempt to program a write protect block */ +#define HAL_SD_ERROR_LOCK_UNLOCK_FAILED SDMMC_ERROR_LOCK_UNLOCK_FAILED /*!< Sequence or password error has been detected in unlock */ +/*!< command or if there was an attempt to access a locked card */ +#define HAL_SD_ERROR_COM_CRC_FAILED SDMMC_ERROR_COM_CRC_FAILED /*!< CRC check of the previous command failed */ +#define HAL_SD_ERROR_ILLEGAL_CMD SDMMC_ERROR_ILLEGAL_CMD /*!< Command is not legal for the card state */ +#define HAL_SD_ERROR_CARD_ECC_FAILED SDMMC_ERROR_CARD_ECC_FAILED /*!< Card internal ECC was applied but failed to correct the data */ +#define HAL_SD_ERROR_CC_ERR SDMMC_ERROR_CC_ERR /*!< Internal card controller error */ +#define HAL_SD_ERROR_GENERAL_UNKNOWN_ERR SDMMC_ERROR_GENERAL_UNKNOWN_ERR /*!< General or unknown error */ +#define HAL_SD_ERROR_STREAM_READ_UNDERRUN SDMMC_ERROR_STREAM_READ_UNDERRUN /*!< The card could not sustain data reading in stream rmode */ +#define HAL_SD_ERROR_STREAM_WRITE_OVERRUN SDMMC_ERROR_STREAM_WRITE_OVERRUN /*!< The card could not sustain data programming in stream mode */ +#define HAL_SD_ERROR_CID_CSD_OVERWRITE SDMMC_ERROR_CID_CSD_OVERWRITE /*!< CID/CSD overwrite error */ +#define HAL_SD_ERROR_WP_ERASE_SKIP SDMMC_ERROR_WP_ERASE_SKIP /*!< Only partial address space was erased */ +#define HAL_SD_ERROR_CARD_ECC_DISABLED SDMMC_ERROR_CARD_ECC_DISABLED /*!< Command has been executed without using internal ECC */ +#define HAL_SD_ERROR_ERASE_RESET SDMMC_ERROR_ERASE_RESET /*!< Erase sequence was cleared before executing because an out */ +/*!< of erase sequence command was received */ +#define HAL_SD_ERROR_AKE_SEQ_ERR SDMMC_ERROR_AKE_SEQ_ERR /*!< Error in sequence of authentication */ +#define HAL_SD_ERROR_INVALID_VOLTRANGE SDMMC_ERROR_INVALID_VOLTRANGE /*!< Error in case of invalid voltage range */ +#define HAL_SD_ERROR_ADDR_OUT_OF_RANGE SDMMC_ERROR_ADDR_OUT_OF_RANGE /*!< Error when addressed block is out of range */ +#define HAL_SD_ERROR_REQUEST_NOT_APPLICABLE SDMMC_ERROR_REQUEST_NOT_APPLICABLE /*!< Error when command request is not applicable */ +#define HAL_SD_ERROR_PARAM SDMMC_ERROR_INVALID_PARAMETER /*!< the used parameter is not valid */ +#define HAL_SD_ERROR_UNSUPPORTED_FEATURE SDMMC_ERROR_UNSUPPORTED_FEATURE /*!< Error when feature is not insupported */ +#define HAL_SD_ERROR_BUSY SDMMC_ERROR_BUSY /*!< Error when transfer process is busy */ +#define HAL_SD_ERROR_DMA SDMMC_ERROR_DMA /*!< Error while DMA transfer */ +#define HAL_SD_ERROR_TIMEOUT SDMMC_ERROR_TIMEOUT /*!< Timeout error */ + +#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U) +#define HAL_SD_ERROR_INVALID_CALLBACK SDMMC_ERROR_INVALID_PARAMETER /*!< Invalid callback error */ +#endif /* USE_HAL_SD_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @defgroup SD_Exported_Constansts_Group2 SD context enumeration + * @{ + */ +#define SD_CONTEXT_NONE ((uint32_t)0x00000000U) /*!< None */ +#define SD_CONTEXT_READ_SINGLE_BLOCK ((uint32_t)0x00000001U) /*!< Read single block operation */ +#define SD_CONTEXT_READ_MULTIPLE_BLOCK ((uint32_t)0x00000002U) /*!< Read multiple blocks operation */ +#define SD_CONTEXT_WRITE_SINGLE_BLOCK ((uint32_t)0x00000010U) /*!< Write single block operation */ +#define SD_CONTEXT_WRITE_MULTIPLE_BLOCK ((uint32_t)0x00000020U) /*!< Write multiple blocks operation */ +#define SD_CONTEXT_IT ((uint32_t)0x00000008U) /*!< Process in Interrupt mode */ +#define SD_CONTEXT_DMA ((uint32_t)0x00000080U) /*!< Process in DMA mode */ + +/** + * @} + */ + +/** @defgroup SD_Exported_Constansts_Group3 SD Supported Memory Cards + * @{ + */ +#define CARD_NORMAL_SPEED ((uint32_t)0x00000000U) /*!< Normal Speed Card <12.5Mo/s , Spec Version 1.01 */ +#define CARD_HIGH_SPEED ((uint32_t)0x00000100U) /*!< High Speed Card <25Mo/s , Spec version 2.00 */ +#define CARD_ULTRA_HIGH_SPEED ((uint32_t)0x00000200U) /*!< UHS-I SD Card <50Mo/s for SDR50, DDR5 Cards + and <104Mo/s for SDR104, Spec version 3.01 */ + +#define CARD_SDSC ((uint32_t)0x00000000U) /*!< SD Standard Capacity <2Go */ +#define CARD_SDHC_SDXC ((uint32_t)0x00000001U) /*!< SD High Capacity <32Go, SD Extended Capacity <2To */ +#define CARD_SECURED ((uint32_t)0x00000003U) + +/** + * @} + */ + +/** @defgroup SD_Exported_Constansts_Group4 SD Supported Version + * @{ + */ +#define CARD_V1_X ((uint32_t)0x00000000U) +#define CARD_V2_X ((uint32_t)0x00000001U) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup SD_Exported_macros SD Exported Macros + * @brief macros to handle interrupts and specific clock configurations + * @{ + */ +/** @brief Reset SD handle state. + * @param __HANDLE__ SD Handle. + * @retval None + */ +#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U) +#define __HAL_SD_RESET_HANDLE_STATE(__HANDLE__) do { \ + (__HANDLE__)->State = HAL_SD_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_SD_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_SD_STATE_RESET) +#endif /* USE_HAL_SD_REGISTER_CALLBACKS */ + +/** + * @brief Enable the SD device interrupt. + * @param __HANDLE__ SD Handle. + * @param __INTERRUPT__ specifies the SDMMC interrupt sources to be enabled. + * This parameter can be one or a combination of the following values: + * @arg SDMMC_IT_CCRCFAIL: Command response received (CRC check failed) interrupt + * @arg SDMMC_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt + * @arg SDMMC_IT_CTIMEOUT: Command response timeout interrupt + * @arg SDMMC_IT_DTIMEOUT: Data timeout interrupt + * @arg SDMMC_IT_TXUNDERR: Transmit FIFO underrun error interrupt + * @arg SDMMC_IT_RXOVERR: Received FIFO overrun error interrupt + * @arg SDMMC_IT_CMDREND: Command response received (CRC check passed) interrupt + * @arg SDMMC_IT_CMDSENT: Command sent (no response required) interrupt + * @arg SDMMC_IT_DATAEND: Data end (data counter, DATACOUNT, is zero) interrupt + * @arg SDMMC_IT_DHOLD: Data transfer Hold interrupt + * @arg SDMMC_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt + * @arg SDMMC_IT_DABORT: Data transfer aborted by CMD12 interrupt + * @arg SDMMC_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt + * @arg SDMMC_IT_RXFIFOHF: Receive FIFO Half Full interrupt + * @arg SDMMC_IT_RXFIFOF: Receive FIFO full interrupt + * @arg SDMMC_IT_TXFIFOE: Transmit FIFO empty interrupt + * @arg SDMMC_IT_BUSYD0END: End of SDMMC_D0 Busy following a CMD response detected interrupt + * @arg SDMMC_IT_SDIOIT: SDIO interrupt received interrupt + * @arg SDMMC_IT_ACKFAIL: Boot Acknowledgment received interrupt + * @arg SDMMC_IT_ACKTIMEOUT: Boot Acknowledgment timeout interrupt + * @arg SDMMC_IT_VSWEND: Voltage switch critical timing section completion interrupt + * @arg SDMMC_IT_CKSTOP: SDMMC_CK stopped in Voltage switch procedure interrupt + * @arg SDMMC_IT_IDMABTC: IDMA buffer transfer complete interrupt + * @retval None + */ +#define __HAL_SD_ENABLE_IT(__HANDLE__, __INTERRUPT__) __SDMMC_ENABLE_IT((__HANDLE__)->Instance, (__INTERRUPT__)) + +/** + * @brief Disable the SD device interrupt. + * @param __HANDLE__ SD Handle. + * @param __INTERRUPT__ specifies the SDMMC interrupt sources to be disabled. + * This parameter can be one or a combination of the following values: + * @arg SDMMC_IT_CCRCFAIL: Command response received (CRC check failed) interrupt + * @arg SDMMC_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt + * @arg SDMMC_IT_CTIMEOUT: Command response timeout interrupt + * @arg SDMMC_IT_DTIMEOUT: Data timeout interrupt + * @arg SDMMC_IT_TXUNDERR: Transmit FIFO underrun error interrupt + * @arg SDMMC_IT_RXOVERR: Received FIFO overrun error interrupt + * @arg SDMMC_IT_CMDREND: Command response received (CRC check passed) interrupt + * @arg SDMMC_IT_CMDSENT: Command sent (no response required) interrupt + * @arg SDMMC_IT_DATAEND: Data end (data counter, DATACOUNT, is zero) interrupt + * @arg SDMMC_IT_DHOLD: Data transfer Hold interrupt + * @arg SDMMC_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt + * @arg SDMMC_IT_DABORT: Data transfer aborted by CMD12 interrupt + * @arg SDMMC_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt + * @arg SDMMC_IT_RXFIFOHF: Receive FIFO Half Full interrupt + * @arg SDMMC_IT_RXFIFOF: Receive FIFO full interrupt + * @arg SDMMC_IT_TXFIFOE: Transmit FIFO empty interrupt + * @arg SDMMC_IT_BUSYD0END: End of SDMMC_D0 Busy following a CMD response detected interrupt + * @arg SDMMC_IT_SDIOIT: SDIO interrupt received interrupt + * @arg SDMMC_IT_ACKFAIL: Boot Acknowledgment received interrupt + * @arg SDMMC_IT_ACKTIMEOUT: Boot Acknowledgment timeout interrupt + * @arg SDMMC_IT_VSWEND: Voltage switch critical timing section completion interrupt + * @arg SDMMC_IT_CKSTOP: SDMMC_CK stopped in Voltage switch procedure interrupt + * @arg SDMMC_IT_IDMABTC: IDMA buffer transfer complete interrupt + * @retval None + */ +#define __HAL_SD_DISABLE_IT(__HANDLE__, __INTERRUPT__) __SDMMC_DISABLE_IT((__HANDLE__)->Instance, (__INTERRUPT__)) + +/** + * @brief Check whether the specified SD flag is set or not. + * @param __HANDLE__ SD Handle. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg SDMMC_FLAG_CCRCFAIL: Command response received (CRC check failed) + * @arg SDMMC_FLAG_DCRCFAIL: Data block sent/received (CRC check failed) + * @arg SDMMC_FLAG_CTIMEOUT: Command response timeout + * @arg SDMMC_FLAG_DTIMEOUT: Data timeout + * @arg SDMMC_FLAG_TXUNDERR: Transmit FIFO underrun error + * @arg SDMMC_FLAG_RXOVERR: Received FIFO overrun error + * @arg SDMMC_FLAG_CMDREND: Command response received (CRC check passed) + * @arg SDMMC_FLAG_CMDSENT: Command sent (no response required) + * @arg SDMMC_FLAG_DATAEND: Data end (data counter, DATACOUNT, is zero) + * @arg SDMMC_FLAG_DHOLD: Data transfer Hold + * @arg SDMMC_FLAG_DBCKEND: Data block sent/received (CRC check passed) + * @arg SDMMC_FLAG_DABORT: Data transfer aborted by CMD12 + * @arg SDMMC_FLAG_DPSMACT: Data path state machine active + * @arg SDMMC_FLAG_CPSMACT: Command path state machine active + * @arg SDMMC_FLAG_TXFIFOHE: Transmit FIFO Half Empty + * @arg SDMMC_FLAG_RXFIFOHF: Receive FIFO Half Full + * @arg SDMMC_FLAG_TXFIFOF: Transmit FIFO full + * @arg SDMMC_FLAG_RXFIFOF: Receive FIFO full + * @arg SDMMC_FLAG_TXFIFOE: Transmit FIFO empty + * @arg SDMMC_FLAG_RXFIFOE: Receive FIFO empty + * @arg SDMMC_FLAG_BUSYD0: Inverted value of SDMMC_D0 line (Busy) + * @arg SDMMC_FLAG_BUSYD0END: End of SDMMC_D0 Busy following a CMD response detected + * @arg SDMMC_FLAG_SDIOIT: SDIO interrupt received + * @arg SDMMC_FLAG_ACKFAIL: Boot Acknowledgment received + * @arg SDMMC_FLAG_ACKTIMEOUT: Boot Acknowledgment timeout + * @arg SDMMC_FLAG_VSWEND: Voltage switch critical timing section completion + * @arg SDMMC_FLAG_CKSTOP: SDMMC_CK stopped in Voltage switch procedure + * @arg SDMMC_FLAG_IDMATE: IDMA transfer error + * @arg SDMMC_FLAG_IDMABTC: IDMA buffer transfer complete + * @retval The new state of SD FLAG (SET or RESET). + */ +#define __HAL_SD_GET_FLAG(__HANDLE__, __FLAG__) __SDMMC_GET_FLAG((__HANDLE__)->Instance, (__FLAG__)) + +/** + * @brief Clear the SD's pending flags. + * @param __HANDLE__ SD Handle. + * @param __FLAG__ specifies the flag to clear. + * This parameter can be one or a combination of the following values: + * @arg SDMMC_FLAG_CCRCFAIL: Command response received (CRC check failed) + * @arg SDMMC_FLAG_DCRCFAIL: Data block sent/received (CRC check failed) + * @arg SDMMC_FLAG_CTIMEOUT: Command response timeout + * @arg SDMMC_FLAG_DTIMEOUT: Data timeout + * @arg SDMMC_FLAG_TXUNDERR: Transmit FIFO underrun error + * @arg SDMMC_FLAG_RXOVERR: Received FIFO overrun error + * @arg SDMMC_FLAG_CMDREND: Command response received (CRC check passed) + * @arg SDMMC_FLAG_CMDSENT: Command sent (no response required) + * @arg SDMMC_FLAG_DATAEND: Data end (data counter, DATACOUNT, is zero) + * @arg SDMMC_FLAG_DHOLD: Data transfer Hold + * @arg SDMMC_FLAG_DBCKEND: Data block sent/received (CRC check passed) + * @arg SDMMC_FLAG_DABORT: Data transfer aborted by CMD12 + * @arg SDMMC_FLAG_BUSYD0END: End of SDMMC_D0 Busy following a CMD response detected + * @arg SDMMC_FLAG_SDIOIT: SDIO interrupt received + * @arg SDMMC_FLAG_ACKFAIL: Boot Acknowledgment received + * @arg SDMMC_FLAG_ACKTIMEOUT: Boot Acknowledgment timeout + * @arg SDMMC_FLAG_VSWEND: Voltage switch critical timing section completion + * @arg SDMMC_FLAG_CKSTOP: SDMMC_CK stopped in Voltage switch procedure + * @arg SDMMC_FLAG_IDMATE: IDMA transfer error + * @arg SDMMC_FLAG_IDMABTC: IDMA buffer transfer complete + * @retval None + */ +#define __HAL_SD_CLEAR_FLAG(__HANDLE__, __FLAG__) __SDMMC_CLEAR_FLAG((__HANDLE__)->Instance, (__FLAG__)) + +/** + * @brief Check whether the specified SD interrupt has occurred or not. + * @param __HANDLE__ SD Handle. + * @param __INTERRUPT__ specifies the SDMMC interrupt source to check. + * This parameter can be one of the following values: + * @arg SDMMC_IT_CCRCFAIL: Command response received (CRC check failed) interrupt + * @arg SDMMC_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt + * @arg SDMMC_IT_CTIMEOUT: Command response timeout interrupt + * @arg SDMMC_IT_DTIMEOUT: Data timeout interrupt + * @arg SDMMC_IT_TXUNDERR: Transmit FIFO underrun error interrupt + * @arg SDMMC_IT_RXOVERR: Received FIFO overrun error interrupt + * @arg SDMMC_IT_CMDREND: Command response received (CRC check passed) interrupt + * @arg SDMMC_IT_CMDSENT: Command sent (no response required) interrupt + * @arg SDMMC_IT_DATAEND: Data end (data counter, DATACOUNT, is zero) interrupt + * @arg SDMMC_IT_DHOLD: Data transfer Hold interrupt + * @arg SDMMC_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt + * @arg SDMMC_IT_DABORT: Data transfer aborted by CMD12 interrupt + * @arg SDMMC_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt + * @arg SDMMC_IT_RXFIFOHF: Receive FIFO Half Full interrupt + * @arg SDMMC_IT_RXFIFOF: Receive FIFO full interrupt + * @arg SDMMC_IT_TXFIFOE: Transmit FIFO empty interrupt + * @arg SDMMC_IT_BUSYD0END: End of SDMMC_D0 Busy following a CMD response detected interrupt + * @arg SDMMC_IT_SDIOIT: SDIO interrupt received interrupt + * @arg SDMMC_IT_ACKFAIL: Boot Acknowledgment received interrupt + * @arg SDMMC_IT_ACKTIMEOUT: Boot Acknowledgment timeout interrupt + * @arg SDMMC_IT_VSWEND: Voltage switch critical timing section completion interrupt + * @arg SDMMC_IT_CKSTOP: SDMMC_CK stopped in Voltage switch procedure interrupt + * @arg SDMMC_IT_IDMABTC: IDMA buffer transfer complete interrupt + * @retval The new state of SD IT (SET or RESET). + */ +#define __HAL_SD_GET_IT(__HANDLE__, __INTERRUPT__) __SDMMC_GET_IT((__HANDLE__)->Instance, (__INTERRUPT__)) + +/** + * @brief Clear the SD's interrupt pending bits. + * @param __HANDLE__ SD Handle. + * @param __INTERRUPT__ specifies the interrupt pending bit to clear. + * This parameter can be one or a combination of the following values: + * @arg SDMMC_IT_CCRCFAIL: Command response received (CRC check failed) interrupt + * @arg SDMMC_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt + * @arg SDMMC_IT_CTIMEOUT: Command response timeout interrupt + * @arg SDMMC_IT_DTIMEOUT: Data timeout interrupt + * @arg SDMMC_IT_TXUNDERR: Transmit FIFO underrun error interrupt + * @arg SDMMC_IT_RXOVERR: Received FIFO overrun error interrupt + * @arg SDMMC_IT_CMDREND: Command response received (CRC check passed) interrupt + * @arg SDMMC_IT_CMDSENT: Command sent (no response required) interrupt + * @arg SDMMC_IT_DATAEND: Data end (data counter, DATACOUNT, is zero) interrupt + * @arg SDMMC_IT_DHOLD: Data transfer Hold interrupt + * @arg SDMMC_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt + * @arg SDMMC_IT_DABORT: Data transfer aborted by CMD12 interrupt + * @arg SDMMC_IT_BUSYD0END: End of SDMMC_D0 Busy following a CMD response detected interrupt + * @arg SDMMC_IT_SDIOIT: SDIO interrupt received interrupt + * @arg SDMMC_IT_ACKFAIL: Boot Acknowledgment received interrupt + * @arg SDMMC_IT_ACKTIMEOUT: Boot Acknowledgment timeout interrupt + * @arg SDMMC_IT_VSWEND: Voltage switch critical timing section completion interrupt + * @arg SDMMC_IT_CKSTOP: SDMMC_CK stopped in Voltage switch procedure interrupt + * @arg SDMMC_IT_IDMABTC: IDMA buffer transfer complete interrupt + * @retval None + */ +#define __HAL_SD_CLEAR_IT(__HANDLE__, __INTERRUPT__) __SDMMC_CLEAR_IT((__HANDLE__)->Instance, (__INTERRUPT__)) + +/** + * @} + */ + +/* Include SD HAL Extension module */ +#include "stm32h5xx_hal_sd_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup SD_Exported_Functions SD Exported Functions + * @{ + */ + +/** @defgroup SD_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ +HAL_StatusTypeDef HAL_SD_Init(SD_HandleTypeDef *hsd); +HAL_StatusTypeDef HAL_SD_InitCard(SD_HandleTypeDef *hsd); +HAL_StatusTypeDef HAL_SD_DeInit(SD_HandleTypeDef *hsd); +void HAL_SD_MspInit(SD_HandleTypeDef *hsd); +void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd); +/** + * @} + */ + +/** @defgroup SD_Exported_Functions_Group2 Input and Output operation functions + * @{ + */ +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, + uint32_t Timeout); +HAL_StatusTypeDef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, const uint8_t *pData, uint32_t BlockAdd, + uint32_t NumberOfBlocks, uint32_t Timeout); +HAL_StatusTypeDef HAL_SD_Erase(SD_HandleTypeDef *hsd, uint32_t BlockStartAdd, uint32_t BlockEndAdd); +/* Non-Blocking mode: IT */ +HAL_StatusTypeDef HAL_SD_ReadBlocks_IT(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, + uint32_t NumberOfBlocks); +HAL_StatusTypeDef HAL_SD_WriteBlocks_IT(SD_HandleTypeDef *hsd, const uint8_t *pData, uint32_t BlockAdd, + uint32_t NumberOfBlocks); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, + uint32_t NumberOfBlocks); +HAL_StatusTypeDef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, const uint8_t *pData, uint32_t BlockAdd, + uint32_t NumberOfBlocks); + +void HAL_SD_IRQHandler(SD_HandleTypeDef *hsd); + +/* Callback in non blocking modes (DMA) */ +void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd); +void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd); +void HAL_SD_ErrorCallback(SD_HandleTypeDef *hsd); +void HAL_SD_AbortCallback(SD_HandleTypeDef *hsd); + +#if (USE_SD_TRANSCEIVER != 0U) +/* Callback to switch in 1.8V mode */ +void HAL_SD_DriveTransceiver_1_8V_Callback(FlagStatus status); +#endif /* USE_SD_TRANSCEIVER */ + +#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U) +/* SD callback registering/unregistering */ +HAL_StatusTypeDef HAL_SD_RegisterCallback(SD_HandleTypeDef *hsd, HAL_SD_CallbackIDTypeDef CallbackID, + pSD_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_SD_UnRegisterCallback(SD_HandleTypeDef *hsd, HAL_SD_CallbackIDTypeDef CallbackID); + +#if (USE_SD_TRANSCEIVER != 0U) +HAL_StatusTypeDef HAL_SD_RegisterTransceiverCallback(SD_HandleTypeDef *hsd, pSD_TransceiverCallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_SD_UnRegisterTransceiverCallback(SD_HandleTypeDef *hsd); +#endif /* USE_SD_TRANSCEIVER */ +#endif /* USE_HAL_SD_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup SD_Exported_Functions_Group3 Peripheral Control functions + * @{ + */ +HAL_StatusTypeDef HAL_SD_ConfigWideBusOperation(SD_HandleTypeDef *hsd, uint32_t WideMode); +HAL_StatusTypeDef HAL_SD_ConfigSpeedBusOperation(SD_HandleTypeDef *hsd, uint32_t SpeedMode); +/** + * @} + */ + +/** @defgroup SD_Exported_Functions_Group4 SD card related functions + * @{ + */ +HAL_SD_CardStateTypeDef HAL_SD_GetCardState(SD_HandleTypeDef *hsd); +HAL_StatusTypeDef HAL_SD_GetCardCID(SD_HandleTypeDef *hsd, HAL_SD_CardCIDTypeDef *pCID); +HAL_StatusTypeDef HAL_SD_GetCardCSD(SD_HandleTypeDef *hsd, HAL_SD_CardCSDTypeDef *pCSD); +HAL_StatusTypeDef HAL_SD_GetCardStatus(SD_HandleTypeDef *hsd, HAL_SD_CardStatusTypeDef *pStatus); +HAL_StatusTypeDef HAL_SD_GetCardInfo(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypeDef *pCardInfo); +/** + * @} + */ + +/** @defgroup SD_Exported_Functions_Group5 Peripheral State and Errors functions + * @{ + */ +HAL_SD_StateTypeDef HAL_SD_GetState(const SD_HandleTypeDef *hsd); +uint32_t HAL_SD_GetError(const SD_HandleTypeDef *hsd); +/** + * @} + */ + +/** @defgroup SD_Exported_Functions_Group6 Perioheral Abort management + * @{ + */ +HAL_StatusTypeDef HAL_SD_Abort(SD_HandleTypeDef *hsd); +HAL_StatusTypeDef HAL_SD_Abort_IT(SD_HandleTypeDef *hsd); +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/** @defgroup SD_Private_Types SD Private Types + * @{ + */ + +/** + * @} + */ + +/* Private defines -----------------------------------------------------------*/ +/** @defgroup SD_Private_Defines SD Private Defines + * @{ + */ + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup SD_Private_Variables SD Private Variables + * @{ + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup SD_Private_Constants SD Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup SD_Private_Macros SD Private Macros + * @{ + */ + +/** + * @} + */ + +/* Private functions prototypes ----------------------------------------------*/ +/** @defgroup SD_Private_Functions_Prototypes SD Private Functions Prototypes + * @{ + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup SD_Private_Functions SD Private Functions + * @{ + */ + +/** + * @} + */ + + +/** + * @} + */ + +/** + * @} + */ +#endif /* SDMMC1 || SDMMC2 */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* STM32H5xx_HAL_SD_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_sd_ex.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_sd_ex.h new file mode 100644 index 0000000000..8661319be8 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_sd_ex.h @@ -0,0 +1,119 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_sd_ex.h + * @author MCD Application Team + * @brief Header file of SD HAL extended module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_SD_EX_H +#define STM32H5xx_HAL_SD_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ +#if defined (SDMMC1) || defined (SDMMC2) + +/** @addtogroup SDEx + * @brief SD HAL extended module driver + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup SDEx_Exported_Types SDEx Exported Types + * @{ + */ + +/** @defgroup SDEx_Exported_Types_Group1 Linked List Wrapper + * @{ + */ +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* -----------------Linked List Wrapper --------------------------------------*/ + +#define SD_DMALinkNodeTypeDef SDMMC_DMALinkNodeTypeDef +#define SD_DMALinkNodeConfTypeDef SDMMC_DMALinkNodeConfTypeDef +#define SD_DMALinkedListTypeDef SDMMC_DMALinkedListTypeDef +/* ----------------- Linked Aliases ------------------------------------------*/ +#define HAL_SDEx_DMALinkedList_WriteCpltCallback HAL_SD_TxCpltCallback +#define HAL_SDEx_DMALinkedList_ReadCpltCallback HAL_SD_RxCpltCallback +/** + * @} + */ +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup SDEx_Exported_Functions SDEx Exported Functions + * @{ + */ +/** @defgroup SDEx_Exported_Functions_Group1 Linked List functions + * @{ + */ +HAL_StatusTypeDef HAL_SDEx_DMALinkedList_ReadBlocks(SD_HandleTypeDef *hsd, SD_DMALinkedListTypeDef *pLinkedList, + uint32_t BlockAdd, uint32_t NumberOfBlocks); +HAL_StatusTypeDef HAL_SDEx_DMALinkedList_WriteBlocks(SD_HandleTypeDef *hsd, SD_DMALinkedListTypeDef *pLinkedList, + uint32_t BlockAdd, uint32_t NumberOfBlocks); + +HAL_StatusTypeDef HAL_SDEx_DMALinkedList_BuildNode(SD_DMALinkNodeTypeDef *pNode, SD_DMALinkNodeConfTypeDef *pNodeConf); +HAL_StatusTypeDef HAL_SDEx_DMALinkedList_InsertNode(SD_DMALinkedListTypeDef *pLinkedList, + SD_DMALinkNodeTypeDef *pPrevNode, SD_DMALinkNodeTypeDef *pNewNode); +HAL_StatusTypeDef HAL_SDEx_DMALinkedList_RemoveNode(SD_DMALinkedListTypeDef *pLinkedList, SD_DMALinkNodeTypeDef *pNode); +HAL_StatusTypeDef HAL_SDEx_DMALinkedList_LockNode(SD_DMALinkNodeTypeDef *pNode); +HAL_StatusTypeDef HAL_SDEx_DMALinkedList_UnlockNode(SD_DMALinkNodeTypeDef *pNode); +HAL_StatusTypeDef HAL_SDEx_DMALinkedList_EnableCircularMode(SD_DMALinkedListTypeDef *pLinkedList); +HAL_StatusTypeDef HAL_SDEx_DMALinkedList_DisableCircularMode(SD_DMALinkedListTypeDef *pLinkedList); + +void HAL_SDEx_Read_DMALnkLstBufCpltCallback(SD_HandleTypeDef *hsd); +void HAL_SDEx_Write_DMALnkLstBufCpltCallback(SD_HandleTypeDef *hsd); + + +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Private functions prototypes ----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** + * @} + */ +#endif /* SDMMC1 || SDMMC2 */ + +/** + * @} + */ +#ifdef __cplusplus +} +#endif + + +#endif /* stm32h5xx_HAL_SD_EX_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_sdram.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_sdram.h new file mode 100644 index 0000000000..68a51ae328 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_sdram.h @@ -0,0 +1,238 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_sdram.h + * @author MCD Application Team + * @brief Header file of SDRAM HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2022 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 STM32H5xx_HAL_SDRAM_H +#define STM32H5xx_HAL_SDRAM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(FMC_Bank5_6_R) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_fmc.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup SDRAM + * @{ + */ + +/* Exported typedef ----------------------------------------------------------*/ + +/** @defgroup SDRAM_Exported_Types SDRAM Exported Types + * @{ + */ + +/** + * @brief HAL SDRAM State structure definition + */ +typedef enum +{ + HAL_SDRAM_STATE_RESET = 0x00U, /*!< SDRAM not yet initialized or disabled */ + HAL_SDRAM_STATE_READY = 0x01U, /*!< SDRAM initialized and ready for use */ + HAL_SDRAM_STATE_BUSY = 0x02U, /*!< SDRAM internal process is ongoing */ + HAL_SDRAM_STATE_ERROR = 0x03U, /*!< SDRAM error state */ + HAL_SDRAM_STATE_WRITE_PROTECTED = 0x04U, /*!< SDRAM device write protected */ + HAL_SDRAM_STATE_PRECHARGED = 0x05U /*!< SDRAM device precharged */ + +} HAL_SDRAM_StateTypeDef; + +/** + * @brief SDRAM handle Structure definition + */ +#if (USE_HAL_SDRAM_REGISTER_CALLBACKS == 1) +typedef struct __SDRAM_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_SDRAM_REGISTER_CALLBACKS */ +{ + FMC_SDRAM_TypeDef *Instance; /*!< Register base address */ + + FMC_SDRAM_InitTypeDef Init; /*!< SDRAM device configuration parameters */ + + __IO HAL_SDRAM_StateTypeDef State; /*!< SDRAM access state */ + + HAL_LockTypeDef Lock; /*!< SDRAM locking object */ + + DMA_HandleTypeDef *hdma; /*!< Pointer DMA handler */ + +#if (USE_HAL_SDRAM_REGISTER_CALLBACKS == 1) + void (* MspInitCallback)(struct __SDRAM_HandleTypeDef *hsdram); /*!< SDRAM Msp Init callback */ + void (* MspDeInitCallback)(struct __SDRAM_HandleTypeDef *hsdram); /*!< SDRAM Msp DeInit callback */ + void (* RefreshErrorCallback)(struct __SDRAM_HandleTypeDef *hsdram); /*!< SDRAM Refresh Error callback */ + void (* DmaXferCpltCallback)(DMA_HandleTypeDef *hdma); /*!< SDRAM DMA Xfer Complete callback */ + void (* DmaXferErrorCallback)(DMA_HandleTypeDef *hdma); /*!< SDRAM DMA Xfer Error callback */ +#endif /* USE_HAL_SDRAM_REGISTER_CALLBACKS */ +} SDRAM_HandleTypeDef; + +#if (USE_HAL_SDRAM_REGISTER_CALLBACKS == 1) +/** + * @brief HAL SDRAM Callback ID enumeration definition + */ +typedef enum +{ + HAL_SDRAM_MSP_INIT_CB_ID = 0x00U, /*!< SDRAM MspInit Callback ID */ + HAL_SDRAM_MSP_DEINIT_CB_ID = 0x01U, /*!< SDRAM MspDeInit Callback ID */ + HAL_SDRAM_REFRESH_ERR_CB_ID = 0x02U, /*!< SDRAM Refresh Error Callback ID */ + HAL_SDRAM_DMA_XFER_CPLT_CB_ID = 0x03U, /*!< SDRAM DMA Xfer Complete Callback ID */ + HAL_SDRAM_DMA_XFER_ERR_CB_ID = 0x04U /*!< SDRAM DMA Xfer Error Callback ID */ +} HAL_SDRAM_CallbackIDTypeDef; + +/** + * @brief HAL SDRAM Callback pointer definition + */ +typedef void (*pSDRAM_CallbackTypeDef)(SDRAM_HandleTypeDef *hsdram); +typedef void (*pSDRAM_DmaCallbackTypeDef)(DMA_HandleTypeDef *hdma); +#endif /* USE_HAL_SDRAM_REGISTER_CALLBACKS */ +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ + +/** @defgroup SDRAM_Exported_Macros SDRAM Exported Macros + * @{ + */ + +/** @brief Reset SDRAM handle state + * @param __HANDLE__ specifies the SDRAM handle. + * @retval None + */ +#if (USE_HAL_SDRAM_REGISTER_CALLBACKS == 1) +#define __HAL_SDRAM_RESET_HANDLE_STATE(__HANDLE__) do { \ + (__HANDLE__)->State = HAL_SDRAM_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_SDRAM_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_SDRAM_STATE_RESET) +#endif /* USE_HAL_SDRAM_REGISTER_CALLBACKS */ +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup SDRAM_Exported_Functions SDRAM Exported Functions + * @{ + */ + +/** @addtogroup SDRAM_Exported_Functions_Group1 + * @{ + */ + +/* Initialization/de-initialization functions *********************************/ +HAL_StatusTypeDef HAL_SDRAM_Init(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_TimingTypeDef *Timing); +HAL_StatusTypeDef HAL_SDRAM_DeInit(SDRAM_HandleTypeDef *hsdram); +void HAL_SDRAM_MspInit(SDRAM_HandleTypeDef *hsdram); +void HAL_SDRAM_MspDeInit(SDRAM_HandleTypeDef *hsdram); + +void HAL_SDRAM_IRQHandler(SDRAM_HandleTypeDef *hsdram); +void HAL_SDRAM_RefreshErrorCallback(SDRAM_HandleTypeDef *hsdram); +void HAL_SDRAM_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma); +void HAL_SDRAM_DMA_XferErrorCallback(DMA_HandleTypeDef *hdma); + +/** + * @} + */ + +/** @addtogroup SDRAM_Exported_Functions_Group2 + * @{ + */ +/* I/O operation functions ****************************************************/ +HAL_StatusTypeDef HAL_SDRAM_Read_8b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint8_t *pDstBuffer, + uint32_t BufferSize); +HAL_StatusTypeDef HAL_SDRAM_Write_8b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint8_t *pSrcBuffer, + uint32_t BufferSize); +HAL_StatusTypeDef HAL_SDRAM_Read_16b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint16_t *pDstBuffer, + uint32_t BufferSize); +HAL_StatusTypeDef HAL_SDRAM_Write_16b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint16_t *pSrcBuffer, + uint32_t BufferSize); +HAL_StatusTypeDef HAL_SDRAM_Read_32b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint32_t *pDstBuffer, + uint32_t BufferSize); +HAL_StatusTypeDef HAL_SDRAM_Write_32b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint32_t *pSrcBuffer, + uint32_t BufferSize); + +HAL_StatusTypeDef HAL_SDRAM_Read_DMA(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint32_t *pDstBuffer, + uint32_t BufferSize); +HAL_StatusTypeDef HAL_SDRAM_Write_DMA(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint32_t *pSrcBuffer, + uint32_t BufferSize); + +#if (USE_HAL_SDRAM_REGISTER_CALLBACKS == 1) +/* SDRAM callback registering/unregistering */ +HAL_StatusTypeDef HAL_SDRAM_RegisterCallback(SDRAM_HandleTypeDef *hsdram, HAL_SDRAM_CallbackIDTypeDef CallbackId, + pSDRAM_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_SDRAM_UnRegisterCallback(SDRAM_HandleTypeDef *hsdram, HAL_SDRAM_CallbackIDTypeDef CallbackId); +HAL_StatusTypeDef HAL_SDRAM_RegisterDmaCallback(SDRAM_HandleTypeDef *hsdram, HAL_SDRAM_CallbackIDTypeDef CallbackId, + pSDRAM_DmaCallbackTypeDef pCallback); +#endif /* USE_HAL_SDRAM_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @addtogroup SDRAM_Exported_Functions_Group3 + * @{ + */ +/* SDRAM Control functions *****************************************************/ +HAL_StatusTypeDef HAL_SDRAM_WriteProtection_Enable(SDRAM_HandleTypeDef *hsdram); +HAL_StatusTypeDef HAL_SDRAM_WriteProtection_Disable(SDRAM_HandleTypeDef *hsdram); +HAL_StatusTypeDef HAL_SDRAM_SendCommand(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command, + uint32_t Timeout); +HAL_StatusTypeDef HAL_SDRAM_ProgramRefreshRate(SDRAM_HandleTypeDef *hsdram, uint32_t RefreshRate); +HAL_StatusTypeDef HAL_SDRAM_SetAutoRefreshNumber(SDRAM_HandleTypeDef *hsdram, uint32_t AutoRefreshNumber); +uint32_t HAL_SDRAM_GetModeStatus(SDRAM_HandleTypeDef *hsdram); + +/** + * @} + */ + +/** @addtogroup SDRAM_Exported_Functions_Group4 + * @{ + */ +/* SDRAM State functions ********************************************************/ +HAL_SDRAM_StateTypeDef HAL_SDRAM_GetState(SDRAM_HandleTypeDef *hsdram); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* FMC_Bank5_6_R */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_SDRAM_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_smartcard.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_smartcard.h new file mode 100644 index 0000000000..dfae52e7af --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_smartcard.h @@ -0,0 +1,1403 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_smartcard.h + * @author MCD Application Team + * @brief Header file of SMARTCARD HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_SMARTCARD_H +#define STM32H5xx_HAL_SMARTCARD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup SMARTCARD + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup SMARTCARD_Exported_Types SMARTCARD Exported Types + * @{ + */ + +/** + * @brief SMARTCARD Init Structure definition + */ +typedef struct +{ + uint32_t BaudRate; /*!< Configures the SmartCard communication baud rate. + The baud rate register is computed using the following formula: + Baud Rate Register = ((usart_ker_ckpres) / ((hsmartcard->Init.BaudRate))) + where usart_ker_ckpres is the USART input clock divided by a prescaler */ + + uint32_t WordLength; /*!< Specifies the number of data bits transmitted or received in a frame. + This parameter @ref SMARTCARD_Word_Length can only be + set to 9 (8 data + 1 parity bits). */ + + uint32_t StopBits; /*!< Specifies the number of stop bits. + This parameter can be a value of @ref SMARTCARD_Stop_Bits. */ + + uint16_t Parity; /*!< Specifies the parity mode. + This parameter can be a value of @ref SMARTCARD_Parity + @note The parity is enabled by default (PCE is forced to 1). + Since the WordLength is forced to 8 bits + parity, M is + forced to 1 and the parity bit is the 9th bit. */ + + uint16_t Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled. + This parameter can be a value of @ref SMARTCARD_Mode */ + + uint16_t CLKPolarity; /*!< Specifies the steady state of the serial clock. + This parameter can be a value of @ref SMARTCARD_Clock_Polarity */ + + uint16_t CLKPhase; /*!< Specifies the clock transition on which the bit capture is made. + This parameter can be a value of @ref SMARTCARD_Clock_Phase */ + + uint16_t CLKLastBit; /*!< Specifies whether the clock pulse corresponding to the last transmitted + data bit (MSB) has to be output on the SCLK pin in synchronous mode. + This parameter can be a value of @ref SMARTCARD_Last_Bit */ + + uint16_t OneBitSampling; /*!< Specifies whether a single sample or three samples' majority vote + is selected. Selecting the single sample method increases + the receiver tolerance to clock deviations. This parameter can be a value + of @ref SMARTCARD_OneBit_Sampling. */ + + uint8_t Prescaler; /*!< Specifies the SmartCard Prescaler. + This parameter can be any value from 0x01 to 0x1F. Prescaler value is + multiplied by 2 to give the division factor of the source clock frequency */ + + uint8_t GuardTime; /*!< Specifies the SmartCard Guard Time applied after stop bits. */ + + uint16_t NACKEnable; /*!< Specifies whether the SmartCard NACK transmission is enabled + in case of parity error. + This parameter can be a value of @ref SMARTCARD_NACK_Enable */ + + uint32_t TimeOutEnable; /*!< Specifies whether the receiver timeout is enabled. + This parameter can be a value of @ref SMARTCARD_Timeout_Enable*/ + + uint32_t TimeOutValue; /*!< Specifies the receiver time out value in number of baud blocks: + it is used to implement the Character Wait Time (CWT) and + Block Wait Time (BWT). It is coded over 24 bits. */ + + uint8_t BlockLength; /*!< Specifies the SmartCard Block Length in T=1 Reception mode. + This parameter can be any value from 0x0 to 0xFF */ + + uint8_t AutoRetryCount; /*!< Specifies the SmartCard auto-retry count (number of retries in + receive and transmit mode). When set to 0, retransmission is + disabled. Otherwise, its maximum value is 7 (before signalling + an error) */ + + uint32_t ClockPrescaler; /*!< Specifies the prescaler value used to divide the USART clock source. + This parameter can be a value of @ref SMARTCARD_ClockPrescaler. */ + +} SMARTCARD_InitTypeDef; + +/** + * @brief SMARTCARD advanced features initialization structure definition + */ +typedef struct +{ + uint32_t AdvFeatureInit; /*!< Specifies which advanced SMARTCARD features is initialized. Several + advanced features may be initialized at the same time. This parameter + can be a value of @ref SMARTCARDEx_Advanced_Features_Initialization_Type */ + + uint32_t TxPinLevelInvert; /*!< Specifies whether the TX pin active level is inverted. + This parameter can be a value of @ref SMARTCARD_Tx_Inv */ + + uint32_t RxPinLevelInvert; /*!< Specifies whether the RX pin active level is inverted. + This parameter can be a value of @ref SMARTCARD_Rx_Inv */ + + uint32_t DataInvert; /*!< Specifies whether data are inverted (positive/direct logic + vs negative/inverted logic). + This parameter can be a value of @ref SMARTCARD_Data_Inv */ + + uint32_t Swap; /*!< Specifies whether TX and RX pins are swapped. + This parameter can be a value of @ref SMARTCARD_Rx_Tx_Swap */ + + uint32_t OverrunDisable; /*!< Specifies whether the reception overrun detection is disabled. + This parameter can be a value of @ref SMARTCARD_Overrun_Disable */ + + uint32_t DMADisableonRxError; /*!< Specifies whether the DMA is disabled in case of reception error. + This parameter can be a value of @ref SMARTCARD_DMA_Disable_on_Rx_Error */ + + uint32_t MSBFirst; /*!< Specifies whether MSB is sent first on UART line. + This parameter can be a value of @ref SMARTCARD_MSB_First */ + + uint16_t TxCompletionIndication; /*!< Specifies which transmission completion indication is used: before (when + relevant flag is available) or once guard time period has elapsed. + This parameter can be a value + of @ref SMARTCARDEx_Transmission_Completion_Indication. */ +} SMARTCARD_AdvFeatureInitTypeDef; + +/** + * @brief HAL SMARTCARD State definition + * @note HAL SMARTCARD State value is a combination of 2 different substates: + * gState and RxState (see @ref SMARTCARD_State_Definition). + * - gState contains SMARTCARD state information related to global Handle management + * and also information related to Tx operations. + * gState value coding follow below described bitmap : + * b7-b6 Error information + * 00 : No Error + * 01 : (Not Used) + * 10 : Timeout + * 11 : Error + * b5 Peripheral initialization status + * 0 : Reset (Peripheral not initialized) + * 1 : Init done (Peripheral initialized. HAL SMARTCARD Init function already called) + * b4-b3 (not used) + * xx : Should be set to 00 + * b2 Intrinsic process state + * 0 : Ready + * 1 : Busy (Peripheral busy with some configuration or internal operations) + * b1 (not used) + * x : Should be set to 0 + * b0 Tx state + * 0 : Ready (no Tx operation ongoing) + * 1 : Busy (Tx operation ongoing) + * - RxState contains information related to Rx operations. + * RxState value coding follow below described bitmap : + * b7-b6 (not used) + * xx : Should be set to 00 + * b5 Peripheral initialization status + * 0 : Reset (Peripheral not initialized) + * 1 : Init done (Peripheral initialized) + * b4-b2 (not used) + * xxx : Should be set to 000 + * b1 Rx state + * 0 : Ready (no Rx operation ongoing) + * 1 : Busy (Rx operation ongoing) + * b0 (not used) + * x : Should be set to 0. + */ +typedef uint32_t HAL_SMARTCARD_StateTypeDef; + +/** + * @brief SMARTCARD handle Structure definition + */ +typedef struct __SMARTCARD_HandleTypeDef +{ + USART_TypeDef *Instance; /*!< USART registers base address */ + + SMARTCARD_InitTypeDef Init; /*!< SmartCard communication parameters */ + + SMARTCARD_AdvFeatureInitTypeDef AdvancedInit; /*!< SmartCard advanced features initialization parameters */ + + const uint8_t *pTxBuffPtr; /*!< Pointer to SmartCard Tx transfer Buffer */ + + uint16_t TxXferSize; /*!< SmartCard Tx Transfer size */ + + __IO uint16_t TxXferCount; /*!< SmartCard Tx Transfer Counter */ + + uint8_t *pRxBuffPtr; /*!< Pointer to SmartCard Rx transfer Buffer */ + + uint16_t RxXferSize; /*!< SmartCard Rx Transfer size */ + + __IO uint16_t RxXferCount; /*!< SmartCard Rx Transfer Counter */ + + uint16_t NbRxDataToProcess; /*!< Number of data to process during RX ISR execution */ + + uint16_t NbTxDataToProcess; /*!< Number of data to process during TX ISR execution */ + + uint32_t FifoMode; /*!< Specifies if the FIFO mode will be used. + This parameter can be a value of + @ref SMARTCARDEx_FIFO_mode. */ + + void (*RxISR)(struct __SMARTCARD_HandleTypeDef *huart); /*!< Function pointer on Rx IRQ handler */ + + void (*TxISR)(struct __SMARTCARD_HandleTypeDef *huart); /*!< Function pointer on Tx IRQ handler */ + +#if defined(HAL_DMA_MODULE_ENABLED) + DMA_HandleTypeDef *hdmatx; /*!< SmartCard Tx DMA Handle parameters */ + + DMA_HandleTypeDef *hdmarx; /*!< SmartCard Rx DMA Handle parameters */ + +#endif /* HAL_DMA_MODULE_ENABLED */ + HAL_LockTypeDef Lock; /*!< Locking object */ + + __IO HAL_SMARTCARD_StateTypeDef gState; /*!< SmartCard state information related to global + Handle management and also related to Tx operations. + This parameter can be a value + of @ref HAL_SMARTCARD_StateTypeDef */ + + __IO HAL_SMARTCARD_StateTypeDef RxState; /*!< SmartCard state information related to Rx operations. + This parameter can be a value + of @ref HAL_SMARTCARD_StateTypeDef */ + + __IO uint32_t ErrorCode; /*!< SmartCard Error code */ + +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) + void (* TxCpltCallback)(struct __SMARTCARD_HandleTypeDef *hsmartcard); /*!< SMARTCARD Tx Complete Callback */ + + void (* RxCpltCallback)(struct __SMARTCARD_HandleTypeDef *hsmartcard); /*!< SMARTCARD Rx Complete Callback */ + + void (* ErrorCallback)(struct __SMARTCARD_HandleTypeDef *hsmartcard); /*!< SMARTCARD Error Callback */ + + void (* AbortCpltCallback)(struct __SMARTCARD_HandleTypeDef *hsmartcard); /*!< SMARTCARD Abort Complete Callback */ + + void (* AbortTransmitCpltCallback)(struct __SMARTCARD_HandleTypeDef *hsmartcard); /*!< SMARTCARD Abort Transmit Complete Callback */ + + void (* AbortReceiveCpltCallback)(struct __SMARTCARD_HandleTypeDef *hsmartcard); /*!< SMARTCARD Abort Receive Complete Callback */ + + void (* RxFifoFullCallback)(struct __SMARTCARD_HandleTypeDef *hsmartcard); /*!< SMARTCARD Rx Fifo Full Callback */ + + void (* TxFifoEmptyCallback)(struct __SMARTCARD_HandleTypeDef *hsmartcard); /*!< SMARTCARD Tx Fifo Empty Callback */ + + void (* MspInitCallback)(struct __SMARTCARD_HandleTypeDef *hsmartcard); /*!< SMARTCARD Msp Init callback */ + + void (* MspDeInitCallback)(struct __SMARTCARD_HandleTypeDef *hsmartcard); /*!< SMARTCARD Msp DeInit callback */ +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACKS */ + +} SMARTCARD_HandleTypeDef; + +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) +/** + * @brief HAL SMARTCARD Callback ID enumeration definition + */ +typedef enum +{ + HAL_SMARTCARD_TX_COMPLETE_CB_ID = 0x00U, /*!< SMARTCARD Tx Complete Callback ID */ + HAL_SMARTCARD_RX_COMPLETE_CB_ID = 0x01U, /*!< SMARTCARD Rx Complete Callback ID */ + HAL_SMARTCARD_ERROR_CB_ID = 0x02U, /*!< SMARTCARD Error Callback ID */ + HAL_SMARTCARD_ABORT_COMPLETE_CB_ID = 0x03U, /*!< SMARTCARD Abort Complete Callback ID */ + HAL_SMARTCARD_ABORT_TRANSMIT_COMPLETE_CB_ID = 0x04U, /*!< SMARTCARD Abort Transmit Complete Callback ID */ + HAL_SMARTCARD_ABORT_RECEIVE_COMPLETE_CB_ID = 0x05U, /*!< SMARTCARD Abort Receive Complete Callback ID */ + HAL_SMARTCARD_RX_FIFO_FULL_CB_ID = 0x06U, /*!< SMARTCARD Rx Fifo Full Callback ID */ + HAL_SMARTCARD_TX_FIFO_EMPTY_CB_ID = 0x07U, /*!< SMARTCARD Tx Fifo Empty Callback ID */ + + HAL_SMARTCARD_MSPINIT_CB_ID = 0x08U, /*!< SMARTCARD MspInit callback ID */ + HAL_SMARTCARD_MSPDEINIT_CB_ID = 0x09U /*!< SMARTCARD MspDeInit callback ID */ + +} HAL_SMARTCARD_CallbackIDTypeDef; + +/** + * @brief HAL SMARTCARD Callback pointer definition + */ +typedef void (*pSMARTCARD_CallbackTypeDef)(SMARTCARD_HandleTypeDef *hsmartcard); /*!< pointer to an SMARTCARD callback function */ + +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACKS */ + +/** + * @brief SMARTCARD clock sources + */ +typedef enum +{ + SMARTCARD_CLOCKSOURCE_PCLK1 = 0x00U, /*!< PCLK1 clock source */ + SMARTCARD_CLOCKSOURCE_PCLK2 = 0x01U, /*!< PCLK2 clock source */ + SMARTCARD_CLOCKSOURCE_HSI = 0x04U, /*!< HSI clock source */ + SMARTCARD_CLOCKSOURCE_CSI = 0x08U, /*!< CSI clock source */ + SMARTCARD_CLOCKSOURCE_LSE = 0x20U, /*!< LSE clock source */ + SMARTCARD_CLOCKSOURCE_PLL2Q = 0x40U, /*!< PLL2Q clock source */ +#if defined(RCC_CR_PLL3ON) + SMARTCARD_CLOCKSOURCE_PLL3Q = 0x80U, /*!< PLL3Q clock source */ +#endif /* RCC_CR_PLL3ON */ + SMARTCARD_CLOCKSOURCE_UNDEFINED = 0x10U /*!< undefined clock source */ +} SMARTCARD_ClockSourceTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup SMARTCARD_Exported_Constants SMARTCARD Exported Constants + * @{ + */ + +/** @defgroup SMARTCARD_State_Definition SMARTCARD State Code Definition + * @{ + */ +#define HAL_SMARTCARD_STATE_RESET 0x00000000U /*!< Peripheral is not initialized. Value + is allowed for gState and RxState */ +#define HAL_SMARTCARD_STATE_READY 0x00000020U /*!< Peripheral Initialized and ready for + use. Value is allowed for gState + and RxState */ +#define HAL_SMARTCARD_STATE_BUSY 0x00000024U /*!< an internal process is ongoing + Value is allowed for gState only */ +#define HAL_SMARTCARD_STATE_BUSY_TX 0x00000021U /*!< Data Transmission process is ongoing + Value is allowed for gState only */ +#define HAL_SMARTCARD_STATE_BUSY_RX 0x00000022U /*!< Data Reception process is ongoing + Value is allowed for RxState only */ +#define HAL_SMARTCARD_STATE_BUSY_TX_RX 0x00000023U /*!< Data Transmission and Reception + process is ongoing Not to be used for + neither gState nor RxState. + Value is result of combination (Or) + between gState and RxState values */ +#define HAL_SMARTCARD_STATE_TIMEOUT 0x000000A0U /*!< Timeout state + Value is allowed for gState only */ +#define HAL_SMARTCARD_STATE_ERROR 0x000000E0U /*!< Error + Value is allowed for gState only */ +/** + * @} + */ + +/** @defgroup SMARTCARD_Error_Definition SMARTCARD Error Code Definition + * @{ + */ +#define HAL_SMARTCARD_ERROR_NONE (0x00000000U) /*!< No error */ +#define HAL_SMARTCARD_ERROR_PE (0x00000001U) /*!< Parity error */ +#define HAL_SMARTCARD_ERROR_NE (0x00000002U) /*!< Noise error */ +#define HAL_SMARTCARD_ERROR_FE (0x00000004U) /*!< frame error */ +#define HAL_SMARTCARD_ERROR_ORE (0x00000008U) /*!< Overrun error */ +#if defined(HAL_DMA_MODULE_ENABLED) +#define HAL_SMARTCARD_ERROR_DMA (0x00000010U) /*!< DMA transfer error */ +#endif /* HAL_DMA_MODULE_ENABLED */ +#define HAL_SMARTCARD_ERROR_RTO (0x00000020U) /*!< Receiver TimeOut error */ +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) +#define HAL_SMARTCARD_ERROR_INVALID_CALLBACK (0x00000040U) /*!< Invalid Callback error */ +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @defgroup SMARTCARD_Word_Length SMARTCARD Word Length + * @{ + */ +#define SMARTCARD_WORDLENGTH_9B USART_CR1_M0 /*!< SMARTCARD frame length */ +/** + * @} + */ + +/** @defgroup SMARTCARD_Stop_Bits SMARTCARD Number of Stop Bits + * @{ + */ +#define SMARTCARD_STOPBITS_0_5 USART_CR2_STOP_0 /*!< SMARTCARD frame with 0.5 stop bit */ +#define SMARTCARD_STOPBITS_1_5 USART_CR2_STOP /*!< SMARTCARD frame with 1.5 stop bits */ +/** + * @} + */ + +/** @defgroup SMARTCARD_Parity SMARTCARD Parity + * @{ + */ +#define SMARTCARD_PARITY_EVEN USART_CR1_PCE /*!< SMARTCARD frame even parity */ +#define SMARTCARD_PARITY_ODD (USART_CR1_PCE | USART_CR1_PS) /*!< SMARTCARD frame odd parity */ +/** + * @} + */ + +/** @defgroup SMARTCARD_Mode SMARTCARD Transfer Mode + * @{ + */ +#define SMARTCARD_MODE_RX USART_CR1_RE /*!< SMARTCARD RX mode */ +#define SMARTCARD_MODE_TX USART_CR1_TE /*!< SMARTCARD TX mode */ +#define SMARTCARD_MODE_TX_RX (USART_CR1_TE |USART_CR1_RE) /*!< SMARTCARD RX and TX mode */ +/** + * @} + */ + +/** @defgroup SMARTCARD_Clock_Polarity SMARTCARD Clock Polarity + * @{ + */ +#define SMARTCARD_POLARITY_LOW 0x00000000U /*!< SMARTCARD frame low polarity */ +#define SMARTCARD_POLARITY_HIGH USART_CR2_CPOL /*!< SMARTCARD frame high polarity */ +/** + * @} + */ + +/** @defgroup SMARTCARD_Clock_Phase SMARTCARD Clock Phase + * @{ + */ +#define SMARTCARD_PHASE_1EDGE 0x00000000U /*!< SMARTCARD frame phase on first clock transition */ +#define SMARTCARD_PHASE_2EDGE USART_CR2_CPHA /*!< SMARTCARD frame phase on second clock transition */ +/** + * @} + */ + +/** @defgroup SMARTCARD_Last_Bit SMARTCARD Last Bit + * @{ + */ +#define SMARTCARD_LASTBIT_DISABLE 0x00000000U /*!< SMARTCARD frame last data bit clock pulse not output to SCLK pin */ +#define SMARTCARD_LASTBIT_ENABLE USART_CR2_LBCL /*!< SMARTCARD frame last data bit clock pulse output to SCLK pin */ +/** + * @} + */ + +/** @defgroup SMARTCARD_OneBit_Sampling SMARTCARD One Bit Sampling Method + * @{ + */ +#define SMARTCARD_ONE_BIT_SAMPLE_DISABLE 0x00000000U /*!< SMARTCARD frame one-bit sample disabled */ +#define SMARTCARD_ONE_BIT_SAMPLE_ENABLE USART_CR3_ONEBIT /*!< SMARTCARD frame one-bit sample enabled */ +/** + * @} + */ + +/** @defgroup SMARTCARD_NACK_Enable SMARTCARD NACK Enable + * @{ + */ +#define SMARTCARD_NACK_DISABLE 0x00000000U /*!< SMARTCARD NACK transmission disabled */ +#define SMARTCARD_NACK_ENABLE USART_CR3_NACK /*!< SMARTCARD NACK transmission enabled */ +/** + * @} + */ + +/** @defgroup SMARTCARD_Timeout_Enable SMARTCARD Timeout Enable + * @{ + */ +#define SMARTCARD_TIMEOUT_DISABLE 0x00000000U /*!< SMARTCARD receiver timeout disabled */ +#define SMARTCARD_TIMEOUT_ENABLE USART_CR2_RTOEN /*!< SMARTCARD receiver timeout enabled */ +/** + * @} + */ + +/** @defgroup SMARTCARD_ClockPrescaler SMARTCARD Clock Prescaler + * @{ + */ +#define SMARTCARD_PRESCALER_DIV1 0x00000000U /*!< fclk_pres = fclk */ +#define SMARTCARD_PRESCALER_DIV2 0x00000001U /*!< fclk_pres = fclk/2 */ +#define SMARTCARD_PRESCALER_DIV4 0x00000002U /*!< fclk_pres = fclk/4 */ +#define SMARTCARD_PRESCALER_DIV6 0x00000003U /*!< fclk_pres = fclk/6 */ +#define SMARTCARD_PRESCALER_DIV8 0x00000004U /*!< fclk_pres = fclk/8 */ +#define SMARTCARD_PRESCALER_DIV10 0x00000005U /*!< fclk_pres = fclk/10 */ +#define SMARTCARD_PRESCALER_DIV12 0x00000006U /*!< fclk_pres = fclk/12 */ +#define SMARTCARD_PRESCALER_DIV16 0x00000007U /*!< fclk_pres = fclk/16 */ +#define SMARTCARD_PRESCALER_DIV32 0x00000008U /*!< fclk_pres = fclk/32 */ +#define SMARTCARD_PRESCALER_DIV64 0x00000009U /*!< fclk_pres = fclk/64 */ +#define SMARTCARD_PRESCALER_DIV128 0x0000000AU /*!< fclk_pres = fclk/128 */ +#define SMARTCARD_PRESCALER_DIV256 0x0000000BU /*!< fclk_pres = fclk/256 */ +/** + * @} + */ + +/** @defgroup SMARTCARD_Tx_Inv SMARTCARD advanced feature TX pin active level inversion + * @{ + */ +#define SMARTCARD_ADVFEATURE_TXINV_DISABLE 0x00000000U /*!< TX pin active level inversion disable */ +#define SMARTCARD_ADVFEATURE_TXINV_ENABLE USART_CR2_TXINV /*!< TX pin active level inversion enable */ +/** + * @} + */ + +/** @defgroup SMARTCARD_Rx_Inv SMARTCARD advanced feature RX pin active level inversion + * @{ + */ +#define SMARTCARD_ADVFEATURE_RXINV_DISABLE 0x00000000U /*!< RX pin active level inversion disable */ +#define SMARTCARD_ADVFEATURE_RXINV_ENABLE USART_CR2_RXINV /*!< RX pin active level inversion enable */ +/** + * @} + */ + +/** @defgroup SMARTCARD_Data_Inv SMARTCARD advanced feature Binary Data inversion + * @{ + */ +#define SMARTCARD_ADVFEATURE_DATAINV_DISABLE 0x00000000U /*!< Binary data inversion disable */ +#define SMARTCARD_ADVFEATURE_DATAINV_ENABLE USART_CR2_DATAINV /*!< Binary data inversion enable */ +/** + * @} + */ + +/** @defgroup SMARTCARD_Rx_Tx_Swap SMARTCARD advanced feature RX TX pins swap + * @{ + */ +#define SMARTCARD_ADVFEATURE_SWAP_DISABLE 0x00000000U /*!< TX/RX pins swap disable */ +#define SMARTCARD_ADVFEATURE_SWAP_ENABLE USART_CR2_SWAP /*!< TX/RX pins swap enable */ +/** + * @} + */ + +/** @defgroup SMARTCARD_Overrun_Disable SMARTCARD advanced feature Overrun Disable + * @{ + */ +#define SMARTCARD_ADVFEATURE_OVERRUN_ENABLE 0x00000000U /*!< RX overrun enable */ +#define SMARTCARD_ADVFEATURE_OVERRUN_DISABLE USART_CR3_OVRDIS /*!< RX overrun disable */ +/** + * @} + */ + +/** @defgroup SMARTCARD_DMA_Disable_on_Rx_Error SMARTCARD advanced feature DMA Disable on Rx Error + * @{ + */ +#define SMARTCARD_ADVFEATURE_DMA_ENABLEONRXERROR 0x00000000U /*!< DMA enable on Reception Error */ +#define SMARTCARD_ADVFEATURE_DMA_DISABLEONRXERROR USART_CR3_DDRE /*!< DMA disable on Reception Error */ +/** + * @} + */ + +/** @defgroup SMARTCARD_MSB_First SMARTCARD advanced feature MSB first + * @{ + */ +#define SMARTCARD_ADVFEATURE_MSBFIRST_DISABLE 0x00000000U /*!< Most significant bit sent/received first disable */ +#define SMARTCARD_ADVFEATURE_MSBFIRST_ENABLE USART_CR2_MSBFIRST /*!< Most significant bit sent/received first enable */ +/** + * @} + */ + +/** @defgroup SMARTCARD_Request_Parameters SMARTCARD Request Parameters + * @{ + */ +#define SMARTCARD_RXDATA_FLUSH_REQUEST USART_RQR_RXFRQ /*!< Receive data flush request */ +#define SMARTCARD_TXDATA_FLUSH_REQUEST USART_RQR_TXFRQ /*!< Transmit data flush request */ +/** + * @} + */ + +/** @defgroup SMARTCARD_Interruption_Mask SMARTCARD interruptions flags mask + * @{ + */ +#define SMARTCARD_IT_MASK 0x001FU /*!< SMARTCARD interruptions flags mask */ +#define SMARTCARD_CR_MASK 0x00E0U /*!< SMARTCARD control register mask */ +#define SMARTCARD_CR_POS 5U /*!< SMARTCARD control register position */ +#define SMARTCARD_ISR_MASK 0x1F00U /*!< SMARTCARD ISR register mask */ +#define SMARTCARD_ISR_POS 8U /*!< SMARTCARD ISR register position */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup SMARTCARD_Exported_Macros SMARTCARD Exported Macros + * @{ + */ + +/** @brief Reset SMARTCARD handle states. + * @param __HANDLE__ SMARTCARD handle. + * @retval None + */ +#if USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1 +#define __HAL_SMARTCARD_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->gState = HAL_SMARTCARD_STATE_RESET; \ + (__HANDLE__)->RxState = HAL_SMARTCARD_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0U) +#else +#define __HAL_SMARTCARD_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->gState = HAL_SMARTCARD_STATE_RESET; \ + (__HANDLE__)->RxState = HAL_SMARTCARD_STATE_RESET; \ + } while(0U) +#endif /*USE_HAL_SMARTCARD_REGISTER_CALLBACKS */ + +/** @brief Flush the Smartcard Data registers. + * @param __HANDLE__ specifies the SMARTCARD Handle. + * @retval None + */ +#define __HAL_SMARTCARD_FLUSH_DRREGISTER(__HANDLE__) \ + do{ \ + SET_BIT((__HANDLE__)->Instance->RQR, SMARTCARD_RXDATA_FLUSH_REQUEST); \ + SET_BIT((__HANDLE__)->Instance->RQR, SMARTCARD_TXDATA_FLUSH_REQUEST); \ + } while(0U) + +/** @brief Clear the specified SMARTCARD pending flag. + * @param __HANDLE__ specifies the SMARTCARD Handle. + * @param __FLAG__ specifies the flag to check. + * This parameter can be any combination of the following values: + * @arg @ref SMARTCARD_CLEAR_PEF Parity error clear flag + * @arg @ref SMARTCARD_CLEAR_FEF Framing error clear flag + * @arg @ref SMARTCARD_CLEAR_NEF Noise detected clear flag + * @arg @ref SMARTCARD_CLEAR_OREF OverRun error clear flag + * @arg @ref SMARTCARD_CLEAR_IDLEF Idle line detected clear flag + * @arg @ref SMARTCARD_CLEAR_TCF Transmission complete clear flag + * @arg @ref SMARTCARD_CLEAR_TCBGTF Transmission complete before guard time clear flag + * @arg @ref SMARTCARD_CLEAR_RTOF Receiver timeout clear flag + * @arg @ref SMARTCARD_CLEAR_EOBF End of block clear flag + * @arg @ref SMARTCARD_CLEAR_TXFECF TXFIFO empty Clear flag + * @retval None + */ +#define __HAL_SMARTCARD_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ICR = (__FLAG__)) + +/** @brief Clear the SMARTCARD PE pending flag. + * @param __HANDLE__ specifies the SMARTCARD Handle. + * @retval None + */ +#define __HAL_SMARTCARD_CLEAR_PEFLAG(__HANDLE__) __HAL_SMARTCARD_CLEAR_FLAG((__HANDLE__), SMARTCARD_CLEAR_PEF) + +/** @brief Clear the SMARTCARD FE pending flag. + * @param __HANDLE__ specifies the SMARTCARD Handle. + * @retval None + */ +#define __HAL_SMARTCARD_CLEAR_FEFLAG(__HANDLE__) __HAL_SMARTCARD_CLEAR_FLAG((__HANDLE__), SMARTCARD_CLEAR_FEF) + +/** @brief Clear the SMARTCARD NE pending flag. + * @param __HANDLE__ specifies the SMARTCARD Handle. + * @retval None + */ +#define __HAL_SMARTCARD_CLEAR_NEFLAG(__HANDLE__) __HAL_SMARTCARD_CLEAR_FLAG((__HANDLE__), SMARTCARD_CLEAR_NEF) + +/** @brief Clear the SMARTCARD ORE pending flag. + * @param __HANDLE__ specifies the SMARTCARD Handle. + * @retval None + */ +#define __HAL_SMARTCARD_CLEAR_OREFLAG(__HANDLE__) __HAL_SMARTCARD_CLEAR_FLAG((__HANDLE__), SMARTCARD_CLEAR_OREF) + +/** @brief Clear the SMARTCARD IDLE pending flag. + * @param __HANDLE__ specifies the SMARTCARD Handle. + * @retval None + */ +#define __HAL_SMARTCARD_CLEAR_IDLEFLAG(__HANDLE__) __HAL_SMARTCARD_CLEAR_FLAG((__HANDLE__), SMARTCARD_CLEAR_IDLEF) + +/** @brief Check whether the specified Smartcard flag is set or not. + * @param __HANDLE__ specifies the SMARTCARD Handle. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg @ref SMARTCARD_FLAG_TCBGT Transmission complete before guard time flag (when flag available) + * @arg @ref SMARTCARD_FLAG_REACK Receive enable acknowledge flag + * @arg @ref SMARTCARD_FLAG_TEACK Transmit enable acknowledge flag + * @arg @ref SMARTCARD_FLAG_BUSY Busy flag + * @arg @ref SMARTCARD_FLAG_EOBF End of block flag + * @arg @ref SMARTCARD_FLAG_RTOF Receiver timeout flag + * @arg @ref SMARTCARD_FLAG_TXE Transmit data register empty flag + * @arg @ref SMARTCARD_FLAG_TC Transmission complete flag + * @arg @ref SMARTCARD_FLAG_RXNE Receive data register not empty flag + * @arg @ref SMARTCARD_FLAG_IDLE Idle line detection flag + * @arg @ref SMARTCARD_FLAG_ORE Overrun error flag + * @arg @ref SMARTCARD_FLAG_NE Noise error flag + * @arg @ref SMARTCARD_FLAG_FE Framing error flag + * @arg @ref SMARTCARD_FLAG_PE Parity error flag + * @arg @ref SMARTCARD_FLAG_TXFNF TXFIFO not full flag + * @arg @ref SMARTCARD_FLAG_RXFNE RXFIFO not empty flag + * @arg @ref SMARTCARD_FLAG_TXFE TXFIFO Empty flag + * @arg @ref SMARTCARD_FLAG_RXFF RXFIFO Full flag + * @arg @ref SMARTCARD_FLAG_RXFT SMARTCARD RXFIFO threshold flag + * @arg @ref SMARTCARD_FLAG_TXFT SMARTCARD TXFIFO threshold flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_SMARTCARD_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->ISR & (__FLAG__)) == (__FLAG__)) + +/** @brief Enable the specified SmartCard interrupt. + * @param __HANDLE__ specifies the SMARTCARD Handle. + * @param __INTERRUPT__ specifies the SMARTCARD interrupt to enable. + * This parameter can be one of the following values: + * @arg @ref SMARTCARD_IT_EOB End of block interrupt + * @arg @ref SMARTCARD_IT_RTO Receive timeout interrupt + * @arg @ref SMARTCARD_IT_TXE Transmit data register empty interrupt + * @arg @ref SMARTCARD_IT_TC Transmission complete interrupt + * @arg @ref SMARTCARD_IT_TCBGT Transmission complete before + * guard time interrupt (when interruption available) + * @arg @ref SMARTCARD_IT_RXNE Receive data register not empty interrupt + * @arg @ref SMARTCARD_IT_IDLE Idle line detection interrupt + * @arg @ref SMARTCARD_IT_PE Parity error interrupt + * @arg @ref SMARTCARD_IT_ERR Error interrupt(frame error, noise error, overrun error) + * @arg @ref SMARTCARD_IT_TXFNF TX FIFO not full interruption + * @arg @ref SMARTCARD_IT_RXFNE RXFIFO not empty interruption + * @arg @ref SMARTCARD_IT_RXFF RXFIFO full interruption + * @arg @ref SMARTCARD_IT_TXFE TXFIFO empty interruption + * @arg @ref SMARTCARD_IT_RXFT RXFIFO threshold reached interruption + * @arg @ref SMARTCARD_IT_TXFT TXFIFO threshold reached interruption + * @retval None + */ +#define __HAL_SMARTCARD_ENABLE_IT(__HANDLE__, __INTERRUPT__) (((((__INTERRUPT__) & SMARTCARD_CR_MASK) >>\ + SMARTCARD_CR_POS) == 1U)?\ + ((__HANDLE__)->Instance->CR1 |= (1UL <<\ + ((__INTERRUPT__) & SMARTCARD_IT_MASK))):\ + ((((__INTERRUPT__) & SMARTCARD_CR_MASK) >>\ + SMARTCARD_CR_POS) == 2U)?\ + ((__HANDLE__)->Instance->CR2 |= (1UL <<\ + ((__INTERRUPT__) & SMARTCARD_IT_MASK))): \ + ((__HANDLE__)->Instance->CR3 |= (1UL <<\ + ((__INTERRUPT__) & SMARTCARD_IT_MASK)))) + +/** @brief Disable the specified SmartCard interrupt. + * @param __HANDLE__ specifies the SMARTCARD Handle. + * @param __INTERRUPT__ specifies the SMARTCARD interrupt to disable. + * This parameter can be one of the following values: + * @arg @ref SMARTCARD_IT_EOB End of block interrupt + * @arg @ref SMARTCARD_IT_RTO Receive timeout interrupt + * @arg @ref SMARTCARD_IT_TXE Transmit data register empty interrupt + * @arg @ref SMARTCARD_IT_TC Transmission complete interrupt + * @arg @ref SMARTCARD_IT_TCBGT Transmission complete before guard + * time interrupt (when interruption available) + * @arg @ref SMARTCARD_IT_RXNE Receive data register not empty interrupt + * @arg @ref SMARTCARD_IT_IDLE Idle line detection interrupt + * @arg @ref SMARTCARD_IT_PE Parity error interrupt + * @arg @ref SMARTCARD_IT_ERR Error interrupt(frame error, noise error, overrun error) + * @arg @ref SMARTCARD_IT_TXFNF TX FIFO not full interruption + * @arg @ref SMARTCARD_IT_RXFNE RXFIFO not empty interruption + * @arg @ref SMARTCARD_IT_RXFF RXFIFO full interruption + * @arg @ref SMARTCARD_IT_TXFE TXFIFO empty interruption + * @arg @ref SMARTCARD_IT_RXFT RXFIFO threshold reached interruption + * @arg @ref SMARTCARD_IT_TXFT TXFIFO threshold reached interruption + * @retval None + */ +#define __HAL_SMARTCARD_DISABLE_IT(__HANDLE__, __INTERRUPT__) (((((__INTERRUPT__) & SMARTCARD_CR_MASK) >>\ + SMARTCARD_CR_POS) == 1U)?\ + ((__HANDLE__)->Instance->CR1 &= ~ (1U <<\ + ((__INTERRUPT__) & SMARTCARD_IT_MASK))): \ + ((((__INTERRUPT__) & SMARTCARD_CR_MASK) >>\ + SMARTCARD_CR_POS) == 2U)?\ + ((__HANDLE__)->Instance->CR2 &= ~ (1U <<\ + ((__INTERRUPT__) & SMARTCARD_IT_MASK))): \ + ((__HANDLE__)->Instance->CR3 &= ~ (1U <<\ + ((__INTERRUPT__) & SMARTCARD_IT_MASK)))) + +/** @brief Check whether the specified SmartCard interrupt has occurred or not. + * @param __HANDLE__ specifies the SMARTCARD Handle. + * @param __INTERRUPT__ specifies the SMARTCARD interrupt to check. + * This parameter can be one of the following values: + * @arg @ref SMARTCARD_IT_EOB End of block interrupt + * @arg @ref SMARTCARD_IT_RTO Receive timeout interrupt + * @arg @ref SMARTCARD_IT_TXE Transmit data register empty interrupt + * @arg @ref SMARTCARD_IT_TC Transmission complete interrupt + * @arg @ref SMARTCARD_IT_TCBGT Transmission complete before guard time + * interrupt (when interruption available) + * @arg @ref SMARTCARD_IT_RXNE Receive data register not empty interrupt + * @arg @ref SMARTCARD_IT_IDLE Idle line detection interrupt + * @arg @ref SMARTCARD_IT_PE Parity error interrupt + * @arg @ref SMARTCARD_IT_ERR Error interrupt(frame error, noise error, overrun error) + * @arg @ref SMARTCARD_IT_TXFNF TX FIFO not full interruption + * @arg @ref SMARTCARD_IT_RXFNE RXFIFO not empty interruption + * @arg @ref SMARTCARD_IT_RXFF RXFIFO full interruption + * @arg @ref SMARTCARD_IT_TXFE TXFIFO empty interruption + * @arg @ref SMARTCARD_IT_RXFT RXFIFO threshold reached interruption + * @arg @ref SMARTCARD_IT_TXFT TXFIFO threshold reached interruption + * @retval The new state of __INTERRUPT__ (SET or RESET). + */ +#define __HAL_SMARTCARD_GET_IT(__HANDLE__, __INTERRUPT__) (\ + (((__HANDLE__)->Instance->ISR & (0x01UL << (((__INTERRUPT__)\ + & SMARTCARD_ISR_MASK)>> SMARTCARD_ISR_POS)))!= 0U)\ + ? SET : RESET) + +/** @brief Check whether the specified SmartCard interrupt source is enabled or not. + * @param __HANDLE__ specifies the SMARTCARD Handle. + * @param __INTERRUPT__ specifies the SMARTCARD interrupt source to check. + * This parameter can be one of the following values: + * @arg @ref SMARTCARD_IT_EOB End of block interrupt + * @arg @ref SMARTCARD_IT_RTO Receive timeout interrupt + * @arg @ref SMARTCARD_IT_TXE Transmit data register empty interrupt + * @arg @ref SMARTCARD_IT_TC Transmission complete interrupt + * @arg @ref SMARTCARD_IT_TCBGT Transmission complete before guard time + * interrupt (when interruption available) + * @arg @ref SMARTCARD_IT_RXNE Receive data register not empty interrupt + * @arg @ref SMARTCARD_IT_IDLE Idle line detection interrupt + * @arg @ref SMARTCARD_IT_PE Parity error interrupt + * @arg @ref SMARTCARD_IT_ERR Error interrupt(frame error, noise error, overrun error) + * @arg @ref SMARTCARD_IT_TXFNF TX FIFO not full interruption + * @arg @ref SMARTCARD_IT_RXFNE RXFIFO not empty interruption + * @arg @ref SMARTCARD_IT_RXFF RXFIFO full interruption + * @arg @ref SMARTCARD_IT_TXFE TXFIFO empty interruption + * @arg @ref SMARTCARD_IT_RXFT RXFIFO threshold reached interruption + * @arg @ref SMARTCARD_IT_TXFT TXFIFO threshold reached interruption + * @retval The new state of __INTERRUPT__ (SET or RESET). + */ +#define __HAL_SMARTCARD_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((((((__INTERRUPT__) & SMARTCARD_CR_MASK) >>\ + SMARTCARD_CR_POS) == 0x01U)?\ + (__HANDLE__)->Instance->CR1 : \ + (((((__INTERRUPT__) & SMARTCARD_CR_MASK) >>\ + SMARTCARD_CR_POS) == 0x02U)?\ + (__HANDLE__)->Instance->CR2 : \ + (__HANDLE__)->Instance->CR3)) &\ + (0x01UL << (((uint16_t)(__INTERRUPT__))\ + & SMARTCARD_IT_MASK))) != 0U)\ + ? SET : RESET) + +/** @brief Clear the specified SMARTCARD ISR flag, in setting the proper ICR register flag. + * @param __HANDLE__ specifies the SMARTCARD Handle. + * @param __IT_CLEAR__ specifies the interrupt clear register flag that needs to be set + * to clear the corresponding interrupt. + * This parameter can be one of the following values: + * @arg @ref SMARTCARD_CLEAR_PEF Parity error clear flag + * @arg @ref SMARTCARD_CLEAR_FEF Framing error clear flag + * @arg @ref SMARTCARD_CLEAR_NEF Noise detected clear flag + * @arg @ref SMARTCARD_CLEAR_OREF OverRun error clear flag + * @arg @ref SMARTCARD_CLEAR_IDLEF Idle line detection clear flag + * @arg @ref SMARTCARD_CLEAR_TXFECF TXFIFO empty Clear Flag + * @arg @ref SMARTCARD_CLEAR_TCF Transmission complete clear flag + * @arg @ref SMARTCARD_CLEAR_TCBGTF Transmission complete before guard time clear flag (when flag available) + * @arg @ref SMARTCARD_CLEAR_RTOF Receiver timeout clear flag + * @arg @ref SMARTCARD_CLEAR_EOBF End of block clear flag + * @retval None + */ +#define __HAL_SMARTCARD_CLEAR_IT(__HANDLE__, __IT_CLEAR__) ((__HANDLE__)->Instance->ICR |= (uint32_t)(__IT_CLEAR__)) + +/** @brief Set a specific SMARTCARD request flag. + * @param __HANDLE__ specifies the SMARTCARD Handle. + * @param __REQ__ specifies the request flag to set + * This parameter can be one of the following values: + * @arg @ref SMARTCARD_RXDATA_FLUSH_REQUEST Receive data flush Request + * @arg @ref SMARTCARD_TXDATA_FLUSH_REQUEST Transmit data flush Request + * @retval None + */ +#define __HAL_SMARTCARD_SEND_REQ(__HANDLE__, __REQ__) ((__HANDLE__)->Instance->RQR |= (uint16_t)(__REQ__)) + +/** @brief Enable the SMARTCARD one bit sample method. + * @param __HANDLE__ specifies the SMARTCARD Handle. + * @retval None + */ +#define __HAL_SMARTCARD_ONE_BIT_SAMPLE_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3|= USART_CR3_ONEBIT) + +/** @brief Disable the SMARTCARD one bit sample method. + * @param __HANDLE__ specifies the SMARTCARD Handle. + * @retval None + */ +#define __HAL_SMARTCARD_ONE_BIT_SAMPLE_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3\ + &= (uint32_t)~((uint32_t)USART_CR3_ONEBIT)) + +/** @brief Enable the USART associated to the SMARTCARD Handle. + * @param __HANDLE__ specifies the SMARTCARD Handle. + * @retval None + */ +#define __HAL_SMARTCARD_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= USART_CR1_UE) + +/** @brief Disable the USART associated to the SMARTCARD Handle + * @param __HANDLE__ specifies the SMARTCARD Handle. + * @retval None + */ +#define __HAL_SMARTCARD_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~USART_CR1_UE) + +/** + * @} + */ + +/* Private macros -------------------------------------------------------------*/ +/** @defgroup SMARTCARD_Private_Macros SMARTCARD Private Macros + * @{ + */ + +/** @brief Report the SMARTCARD clock source. + * @param __HANDLE__ specifies the SMARTCARD Handle. + * @param __CLOCKSOURCE__ output variable. + * @retval the SMARTCARD clocking source, written in __CLOCKSOURCE__. + */ +#if (defined(STM32H573xx) || defined(STM32H563xx) || defined(STM32H562xx)) +#define SMARTCARD_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__) \ + do { \ + if((__HANDLE__)->Instance == USART1) \ + { \ + switch(__HAL_RCC_GET_USART1_SOURCE()) \ + { \ + case RCC_USART1CLKSOURCE_PCLK2: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PCLK2; \ + break; \ + case RCC_USART1CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART1CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART1CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_LSE; \ + break; \ + case RCC_USART1CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PLL2Q; \ + break; \ + case RCC_USART1CLKSOURCE_PLL3Q: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PLL3Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == USART2) \ + { \ + switch(__HAL_RCC_GET_USART2_SOURCE()) \ + { \ + case RCC_USART2CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_USART2CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART2CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART2CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_LSE; \ + break; \ + case RCC_USART2CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PLL2Q; \ + break; \ + case RCC_USART2CLKSOURCE_PLL3Q: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PLL3Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == USART3) \ + { \ + switch(__HAL_RCC_GET_USART3_SOURCE()) \ + { \ + case RCC_USART3CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_USART3CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART3CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART3CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_LSE; \ + break; \ + case RCC_USART3CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PLL2Q; \ + break; \ + case RCC_USART3CLKSOURCE_PLL3Q: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PLL3Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == USART6) \ + { \ + switch(__HAL_RCC_GET_USART6_SOURCE()) \ + { \ + case RCC_USART6CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_USART6CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART6CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART6CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_LSE; \ + break; \ + case RCC_USART6CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PLL2Q; \ + break; \ + case RCC_USART6CLKSOURCE_PLL3Q: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PLL3Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == USART10) \ + { \ + switch(__HAL_RCC_GET_USART10_SOURCE()) \ + { \ + case RCC_USART10CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_USART10CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART10CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART10CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_LSE; \ + break; \ + case RCC_USART10CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PLL2Q; \ + break; \ + case RCC_USART10CLKSOURCE_PLL3Q: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PLL3Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == USART11) \ + { \ + switch(__HAL_RCC_GET_USART11_SOURCE()) \ + { \ + case RCC_USART11CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_USART11CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART11CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART11CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_LSE; \ + break; \ + case RCC_USART11CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PLL2Q; \ + break; \ + case RCC_USART11CLKSOURCE_PLL3Q: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PLL3Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else \ + { \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_UNDEFINED; \ + } \ + } while(0U) +#else +#define SMARTCARD_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__) \ + do { \ + if((__HANDLE__)->Instance == USART1) \ + { \ + switch(__HAL_RCC_GET_USART1_SOURCE()) \ + { \ + case RCC_USART1CLKSOURCE_PCLK2: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PCLK2; \ + break; \ + case RCC_USART1CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART1CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART1CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_LSE; \ + break; \ + case RCC_USART1CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PLL2Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == USART2) \ + { \ + switch(__HAL_RCC_GET_USART2_SOURCE()) \ + { \ + case RCC_USART2CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_USART2CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART2CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART2CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_LSE; \ + break; \ + case RCC_USART2CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PLL2Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == USART3) \ + { \ + switch(__HAL_RCC_GET_USART3_SOURCE()) \ + { \ + case RCC_USART3CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_USART3CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART3CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART3CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_LSE; \ + break; \ + case RCC_USART3CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_PLL2Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else \ + { \ + (__CLOCKSOURCE__) = SMARTCARD_CLOCKSOURCE_UNDEFINED; \ + } \ + } while(0U) +#endif /* (defined(STM32H573xx) || defined(STM32H563xx) || defined(STM32H562xx) */ + +/** @brief Check the Baud rate range. + * @note The maximum Baud Rate is derived from the maximum clock on H5 (250 MHz) + * divided by the oversampling used on the SMARTCARD (i.e. 16). + * @param __BAUDRATE__ Baud rate set by the configuration function. + * @retval Test result (TRUE or FALSE) + */ +#define IS_SMARTCARD_BAUDRATE(__BAUDRATE__) ((__BAUDRATE__) < 10000000U) + +/** @brief Check the block length range. + * @note The maximum SMARTCARD block length is 0xFF. + * @param __LENGTH__ block length. + * @retval Test result (TRUE or FALSE) + */ +#define IS_SMARTCARD_BLOCKLENGTH(__LENGTH__) ((__LENGTH__) <= 0xFFU) + +/** @brief Check the receiver timeout value. + * @note The maximum SMARTCARD receiver timeout value is 0xFFFFFF. + * @param __TIMEOUTVALUE__ receiver timeout value. + * @retval Test result (TRUE or FALSE) + */ +#define IS_SMARTCARD_TIMEOUT_VALUE(__TIMEOUTVALUE__) ((__TIMEOUTVALUE__) <= 0xFFFFFFU) + +/** @brief Check the SMARTCARD autoretry counter value. + * @note The maximum number of retransmissions is 0x7. + * @param __COUNT__ number of retransmissions. + * @retval Test result (TRUE or FALSE) + */ +#define IS_SMARTCARD_AUTORETRY_COUNT(__COUNT__) ((__COUNT__) <= 0x7U) + +/** @brief Ensure that SMARTCARD frame length is valid. + * @param __LENGTH__ SMARTCARD frame length. + * @retval SET (__LENGTH__ is valid) or RESET (__LENGTH__ is invalid) + */ +#define IS_SMARTCARD_WORD_LENGTH(__LENGTH__) ((__LENGTH__) == SMARTCARD_WORDLENGTH_9B) + +/** @brief Ensure that SMARTCARD frame number of stop bits is valid. + * @param __STOPBITS__ SMARTCARD frame number of stop bits. + * @retval SET (__STOPBITS__ is valid) or RESET (__STOPBITS__ is invalid) + */ +#define IS_SMARTCARD_STOPBITS(__STOPBITS__) (((__STOPBITS__) == SMARTCARD_STOPBITS_0_5) ||\ + ((__STOPBITS__) == SMARTCARD_STOPBITS_1_5)) + +/** @brief Ensure that SMARTCARD frame parity is valid. + * @param __PARITY__ SMARTCARD frame parity. + * @retval SET (__PARITY__ is valid) or RESET (__PARITY__ is invalid) + */ +#define IS_SMARTCARD_PARITY(__PARITY__) (((__PARITY__) == SMARTCARD_PARITY_EVEN) || \ + ((__PARITY__) == SMARTCARD_PARITY_ODD)) + +/** @brief Ensure that SMARTCARD communication mode is valid. + * @param __MODE__ SMARTCARD communication mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_SMARTCARD_MODE(__MODE__) ((((__MODE__) & 0xFFF3U) == 0x00U) && ((__MODE__) != 0x00U)) + +/** @brief Ensure that SMARTCARD frame polarity is valid. + * @param __CPOL__ SMARTCARD frame polarity. + * @retval SET (__CPOL__ is valid) or RESET (__CPOL__ is invalid) + */ +#define IS_SMARTCARD_POLARITY(__CPOL__) (((__CPOL__) == SMARTCARD_POLARITY_LOW)\ + || ((__CPOL__) == SMARTCARD_POLARITY_HIGH)) + +/** @brief Ensure that SMARTCARD frame phase is valid. + * @param __CPHA__ SMARTCARD frame phase. + * @retval SET (__CPHA__ is valid) or RESET (__CPHA__ is invalid) + */ +#define IS_SMARTCARD_PHASE(__CPHA__) (((__CPHA__) == SMARTCARD_PHASE_1EDGE) || ((__CPHA__) == SMARTCARD_PHASE_2EDGE)) + +/** @brief Ensure that SMARTCARD frame last bit clock pulse setting is valid. + * @param __LASTBIT__ SMARTCARD frame last bit clock pulse setting. + * @retval SET (__LASTBIT__ is valid) or RESET (__LASTBIT__ is invalid) + */ +#define IS_SMARTCARD_LASTBIT(__LASTBIT__) (((__LASTBIT__) == SMARTCARD_LASTBIT_DISABLE) || \ + ((__LASTBIT__) == SMARTCARD_LASTBIT_ENABLE)) + +/** @brief Ensure that SMARTCARD frame sampling is valid. + * @param __ONEBIT__ SMARTCARD frame sampling. + * @retval SET (__ONEBIT__ is valid) or RESET (__ONEBIT__ is invalid) + */ +#define IS_SMARTCARD_ONE_BIT_SAMPLE(__ONEBIT__) (((__ONEBIT__) == SMARTCARD_ONE_BIT_SAMPLE_DISABLE) || \ + ((__ONEBIT__) == SMARTCARD_ONE_BIT_SAMPLE_ENABLE)) + +/** @brief Ensure that SMARTCARD NACK transmission setting is valid. + * @param __NACK__ SMARTCARD NACK transmission setting. + * @retval SET (__NACK__ is valid) or RESET (__NACK__ is invalid) + */ +#define IS_SMARTCARD_NACK(__NACK__) (((__NACK__) == SMARTCARD_NACK_ENABLE) || \ + ((__NACK__) == SMARTCARD_NACK_DISABLE)) + +/** @brief Ensure that SMARTCARD receiver timeout setting is valid. + * @param __TIMEOUT__ SMARTCARD receiver timeout setting. + * @retval SET (__TIMEOUT__ is valid) or RESET (__TIMEOUT__ is invalid) + */ +#define IS_SMARTCARD_TIMEOUT(__TIMEOUT__) (((__TIMEOUT__) == SMARTCARD_TIMEOUT_DISABLE) || \ + ((__TIMEOUT__) == SMARTCARD_TIMEOUT_ENABLE)) + +/** @brief Ensure that SMARTCARD clock Prescaler is valid. + * @param __CLOCKPRESCALER__ SMARTCARD clock Prescaler value. + * @retval SET (__CLOCKPRESCALER__ is valid) or RESET (__CLOCKPRESCALER__ is invalid) + */ +#define IS_SMARTCARD_CLOCKPRESCALER(__CLOCKPRESCALER__) (((__CLOCKPRESCALER__) == SMARTCARD_PRESCALER_DIV1) || \ + ((__CLOCKPRESCALER__) == SMARTCARD_PRESCALER_DIV2) || \ + ((__CLOCKPRESCALER__) == SMARTCARD_PRESCALER_DIV4) || \ + ((__CLOCKPRESCALER__) == SMARTCARD_PRESCALER_DIV6) || \ + ((__CLOCKPRESCALER__) == SMARTCARD_PRESCALER_DIV8) || \ + ((__CLOCKPRESCALER__) == SMARTCARD_PRESCALER_DIV10) || \ + ((__CLOCKPRESCALER__) == SMARTCARD_PRESCALER_DIV12) || \ + ((__CLOCKPRESCALER__) == SMARTCARD_PRESCALER_DIV16) || \ + ((__CLOCKPRESCALER__) == SMARTCARD_PRESCALER_DIV32) || \ + ((__CLOCKPRESCALER__) == SMARTCARD_PRESCALER_DIV64) || \ + ((__CLOCKPRESCALER__) == SMARTCARD_PRESCALER_DIV128) || \ + ((__CLOCKPRESCALER__) == SMARTCARD_PRESCALER_DIV256)) + +/** @brief Ensure that SMARTCARD advanced features initialization is valid. + * @param __INIT__ SMARTCARD advanced features initialization. + * @retval SET (__INIT__ is valid) or RESET (__INIT__ is invalid) + */ +#define IS_SMARTCARD_ADVFEATURE_INIT(__INIT__) ((__INIT__) <= (SMARTCARD_ADVFEATURE_NO_INIT | \ + SMARTCARD_ADVFEATURE_TXINVERT_INIT | \ + SMARTCARD_ADVFEATURE_RXINVERT_INIT | \ + SMARTCARD_ADVFEATURE_DATAINVERT_INIT | \ + SMARTCARD_ADVFEATURE_SWAP_INIT | \ + SMARTCARD_ADVFEATURE_RXOVERRUNDISABLE_INIT | \ + SMARTCARD_ADVFEATURE_DMADISABLEONERROR_INIT | \ + SMARTCARD_ADVFEATURE_MSBFIRST_INIT)) + +/** @brief Ensure that SMARTCARD frame TX inversion setting is valid. + * @param __TXINV__ SMARTCARD frame TX inversion setting. + * @retval SET (__TXINV__ is valid) or RESET (__TXINV__ is invalid) + */ +#define IS_SMARTCARD_ADVFEATURE_TXINV(__TXINV__) (((__TXINV__) == SMARTCARD_ADVFEATURE_TXINV_DISABLE) || \ + ((__TXINV__) == SMARTCARD_ADVFEATURE_TXINV_ENABLE)) + +/** @brief Ensure that SMARTCARD frame RX inversion setting is valid. + * @param __RXINV__ SMARTCARD frame RX inversion setting. + * @retval SET (__RXINV__ is valid) or RESET (__RXINV__ is invalid) + */ +#define IS_SMARTCARD_ADVFEATURE_RXINV(__RXINV__) (((__RXINV__) == SMARTCARD_ADVFEATURE_RXINV_DISABLE) || \ + ((__RXINV__) == SMARTCARD_ADVFEATURE_RXINV_ENABLE)) + +/** @brief Ensure that SMARTCARD frame data inversion setting is valid. + * @param __DATAINV__ SMARTCARD frame data inversion setting. + * @retval SET (__DATAINV__ is valid) or RESET (__DATAINV__ is invalid) + */ +#define IS_SMARTCARD_ADVFEATURE_DATAINV(__DATAINV__) (((__DATAINV__) == SMARTCARD_ADVFEATURE_DATAINV_DISABLE) || \ + ((__DATAINV__) == SMARTCARD_ADVFEATURE_DATAINV_ENABLE)) + +/** @brief Ensure that SMARTCARD frame RX/TX pins swap setting is valid. + * @param __SWAP__ SMARTCARD frame RX/TX pins swap setting. + * @retval SET (__SWAP__ is valid) or RESET (__SWAP__ is invalid) + */ +#define IS_SMARTCARD_ADVFEATURE_SWAP(__SWAP__) (((__SWAP__) == SMARTCARD_ADVFEATURE_SWAP_DISABLE) || \ + ((__SWAP__) == SMARTCARD_ADVFEATURE_SWAP_ENABLE)) + +/** @brief Ensure that SMARTCARD frame overrun setting is valid. + * @param __OVERRUN__ SMARTCARD frame overrun setting. + * @retval SET (__OVERRUN__ is valid) or RESET (__OVERRUN__ is invalid) + */ +#define IS_SMARTCARD_OVERRUN(__OVERRUN__) (((__OVERRUN__) == SMARTCARD_ADVFEATURE_OVERRUN_ENABLE) || \ + ((__OVERRUN__) == SMARTCARD_ADVFEATURE_OVERRUN_DISABLE)) + +/** @brief Ensure that SMARTCARD DMA enabling or disabling on error setting is valid. + * @param __DMA__ SMARTCARD DMA enabling or disabling on error setting. + * @retval SET (__DMA__ is valid) or RESET (__DMA__ is invalid) + */ +#define IS_SMARTCARD_ADVFEATURE_DMAONRXERROR(__DMA__) (((__DMA__) == SMARTCARD_ADVFEATURE_DMA_ENABLEONRXERROR) || \ + ((__DMA__) == SMARTCARD_ADVFEATURE_DMA_DISABLEONRXERROR)) + +/** @brief Ensure that SMARTCARD frame MSB first setting is valid. + * @param __MSBFIRST__ SMARTCARD frame MSB first setting. + * @retval SET (__MSBFIRST__ is valid) or RESET (__MSBFIRST__ is invalid) + */ +#define IS_SMARTCARD_ADVFEATURE_MSBFIRST(__MSBFIRST__) (((__MSBFIRST__) == SMARTCARD_ADVFEATURE_MSBFIRST_DISABLE) || \ + ((__MSBFIRST__) == SMARTCARD_ADVFEATURE_MSBFIRST_ENABLE)) + +/** @brief Ensure that SMARTCARD request parameter is valid. + * @param __PARAM__ SMARTCARD request parameter. + * @retval SET (__PARAM__ is valid) or RESET (__PARAM__ is invalid) + */ +#define IS_SMARTCARD_REQUEST_PARAMETER(__PARAM__) (((__PARAM__) == SMARTCARD_RXDATA_FLUSH_REQUEST) || \ + ((__PARAM__) == SMARTCARD_TXDATA_FLUSH_REQUEST)) + +/** + * @} + */ + +/* Include SMARTCARD HAL Extended module */ +#include "stm32h5xx_hal_smartcard_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup SMARTCARD_Exported_Functions + * @{ + */ + +/* Initialization and de-initialization functions ****************************/ +/** @addtogroup SMARTCARD_Exported_Functions_Group1 + * @{ + */ + +HAL_StatusTypeDef HAL_SMARTCARD_Init(SMARTCARD_HandleTypeDef *hsmartcard); +HAL_StatusTypeDef HAL_SMARTCARD_DeInit(SMARTCARD_HandleTypeDef *hsmartcard); +void HAL_SMARTCARD_MspInit(SMARTCARD_HandleTypeDef *hsmartcard); +void HAL_SMARTCARD_MspDeInit(SMARTCARD_HandleTypeDef *hsmartcard); + +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) +/* Callbacks Register/UnRegister functions ***********************************/ +HAL_StatusTypeDef HAL_SMARTCARD_RegisterCallback(SMARTCARD_HandleTypeDef *hsmartcard, + HAL_SMARTCARD_CallbackIDTypeDef CallbackID, + pSMARTCARD_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_SMARTCARD_UnRegisterCallback(SMARTCARD_HandleTypeDef *hsmartcard, + HAL_SMARTCARD_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/* IO operation functions *****************************************************/ +/** @addtogroup SMARTCARD_Exported_Functions_Group2 + * @{ + */ + +HAL_StatusTypeDef HAL_SMARTCARD_Transmit(SMARTCARD_HandleTypeDef *hsmartcard, const uint8_t *pData, uint16_t Size, + uint32_t Timeout); +HAL_StatusTypeDef HAL_SMARTCARD_Receive(SMARTCARD_HandleTypeDef *hsmartcard, uint8_t *pData, uint16_t Size, + uint32_t Timeout); +HAL_StatusTypeDef HAL_SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsmartcard, const uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsmartcard, uint8_t *pData, uint16_t Size); +#if defined(HAL_DMA_MODULE_ENABLED) +HAL_StatusTypeDef HAL_SMARTCARD_Transmit_DMA(SMARTCARD_HandleTypeDef *hsmartcard, const uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_SMARTCARD_Receive_DMA(SMARTCARD_HandleTypeDef *hsmartcard, uint8_t *pData, uint16_t Size); +#endif /* HAL_DMA_MODULE_ENABLED */ +/* Transfer Abort functions */ +HAL_StatusTypeDef HAL_SMARTCARD_Abort(SMARTCARD_HandleTypeDef *hsmartcard); +HAL_StatusTypeDef HAL_SMARTCARD_AbortTransmit(SMARTCARD_HandleTypeDef *hsmartcard); +HAL_StatusTypeDef HAL_SMARTCARD_AbortReceive(SMARTCARD_HandleTypeDef *hsmartcard); +HAL_StatusTypeDef HAL_SMARTCARD_Abort_IT(SMARTCARD_HandleTypeDef *hsmartcard); +HAL_StatusTypeDef HAL_SMARTCARD_AbortTransmit_IT(SMARTCARD_HandleTypeDef *hsmartcard); +HAL_StatusTypeDef HAL_SMARTCARD_AbortReceive_IT(SMARTCARD_HandleTypeDef *hsmartcard); + +void HAL_SMARTCARD_IRQHandler(SMARTCARD_HandleTypeDef *hsmartcard); +void HAL_SMARTCARD_TxCpltCallback(SMARTCARD_HandleTypeDef *hsmartcard); +void HAL_SMARTCARD_RxCpltCallback(SMARTCARD_HandleTypeDef *hsmartcard); +void HAL_SMARTCARD_ErrorCallback(SMARTCARD_HandleTypeDef *hsmartcard); +void HAL_SMARTCARD_AbortCpltCallback(SMARTCARD_HandleTypeDef *hsmartcard); +void HAL_SMARTCARD_AbortTransmitCpltCallback(SMARTCARD_HandleTypeDef *hsmartcard); +void HAL_SMARTCARD_AbortReceiveCpltCallback(SMARTCARD_HandleTypeDef *hsmartcard); + +/** + * @} + */ + +/* Peripheral State and Error functions ***************************************/ +/** @addtogroup SMARTCARD_Exported_Functions_Group4 + * @{ + */ + +HAL_SMARTCARD_StateTypeDef HAL_SMARTCARD_GetState(const SMARTCARD_HandleTypeDef *hsmartcard); +uint32_t HAL_SMARTCARD_GetError(const SMARTCARD_HandleTypeDef *hsmartcard); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_SMARTCARD_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_smartcard_ex.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_smartcard_ex.h new file mode 100644 index 0000000000..1b46af7c0e --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_smartcard_ex.h @@ -0,0 +1,336 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_smartcard_ex.h + * @author MCD Application Team + * @brief Header file of SMARTCARD HAL Extended module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_SMARTCARD_EX_H +#define STM32H5xx_HAL_SMARTCARD_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup SMARTCARDEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @addtogroup SMARTCARDEx_Exported_Constants SMARTCARD Extended Exported Constants + * @{ + */ + +/** @defgroup SMARTCARDEx_Transmission_Completion_Indication SMARTCARD Transmission Completion Indication + * @{ + */ +#define SMARTCARD_TCBGT SMARTCARD_IT_TCBGT /*!< SMARTCARD transmission complete before guard time */ +#define SMARTCARD_TC SMARTCARD_IT_TC /*!< SMARTCARD transmission complete (flag raised when guard time has elapsed) */ +/** + * @} + */ + +/** @defgroup SMARTCARDEx_Advanced_Features_Initialization_Type SMARTCARD advanced feature initialization type + * @{ + */ +#define SMARTCARD_ADVFEATURE_NO_INIT 0x00000000U /*!< No advanced feature initialization */ +#define SMARTCARD_ADVFEATURE_TXINVERT_INIT 0x00000001U /*!< TX pin active level inversion */ +#define SMARTCARD_ADVFEATURE_RXINVERT_INIT 0x00000002U /*!< RX pin active level inversion */ +#define SMARTCARD_ADVFEATURE_DATAINVERT_INIT 0x00000004U /*!< Binary data inversion */ +#define SMARTCARD_ADVFEATURE_SWAP_INIT 0x00000008U /*!< TX/RX pins swap */ +#define SMARTCARD_ADVFEATURE_RXOVERRUNDISABLE_INIT 0x00000010U /*!< RX overrun disable */ +#define SMARTCARD_ADVFEATURE_DMADISABLEONERROR_INIT 0x00000020U /*!< DMA disable on Reception Error */ +#define SMARTCARD_ADVFEATURE_MSBFIRST_INIT 0x00000080U /*!< Most significant bit sent/received first */ +#define SMARTCARD_ADVFEATURE_TXCOMPLETION 0x00000100U /*!< TX completion indication before of after guard time */ +/** + * @} + */ + +/** @defgroup SMARTCARDEx_FIFO_mode SMARTCARD FIFO mode + * @brief SMARTCARD FIFO mode + * @{ + */ +#define SMARTCARD_FIFOMODE_DISABLE 0x00000000U /*!< FIFO mode disable */ +#define SMARTCARD_FIFOMODE_ENABLE USART_CR1_FIFOEN /*!< FIFO mode enable */ +/** + * @} + */ + +/** @defgroup SMARTCARDEx_TXFIFO_threshold_level SMARTCARD TXFIFO threshold level + * @brief SMARTCARD TXFIFO level + * @{ + */ +#define SMARTCARD_TXFIFO_THRESHOLD_1_8 0x00000000U /*!< TXFIFO reaches 1/8 of its depth */ +#define SMARTCARD_TXFIFO_THRESHOLD_1_4 USART_CR3_TXFTCFG_0 /*!< TXFIFO reaches 1/4 of its depth */ +#define SMARTCARD_TXFIFO_THRESHOLD_1_2 USART_CR3_TXFTCFG_1 /*!< TXFIFO reaches 1/2 of its depth */ +#define SMARTCARD_TXFIFO_THRESHOLD_3_4 (USART_CR3_TXFTCFG_0|USART_CR3_TXFTCFG_1) /*!< TXFIFO reaches 3/4 of its depth */ +#define SMARTCARD_TXFIFO_THRESHOLD_7_8 USART_CR3_TXFTCFG_2 /*!< TXFIFO reaches 7/8 of its depth */ +#define SMARTCARD_TXFIFO_THRESHOLD_8_8 (USART_CR3_TXFTCFG_2|USART_CR3_TXFTCFG_0) /*!< TXFIFO becomes empty */ +/** + * @} + */ + +/** @defgroup SMARTCARDEx_RXFIFO_threshold_level SMARTCARD RXFIFO threshold level + * @brief SMARTCARD RXFIFO level + * @{ + */ +#define SMARTCARD_RXFIFO_THRESHOLD_1_8 0x00000000U /*!< RXFIFO FIFO reaches 1/8 of its depth */ +#define SMARTCARD_RXFIFO_THRESHOLD_1_4 USART_CR3_RXFTCFG_0 /*!< RXFIFO FIFO reaches 1/4 of its depth */ +#define SMARTCARD_RXFIFO_THRESHOLD_1_2 USART_CR3_RXFTCFG_1 /*!< RXFIFO FIFO reaches 1/2 of its depth */ +#define SMARTCARD_RXFIFO_THRESHOLD_3_4 (USART_CR3_RXFTCFG_0|USART_CR3_RXFTCFG_1) /*!< RXFIFO FIFO reaches 3/4 of its depth */ +#define SMARTCARD_RXFIFO_THRESHOLD_7_8 USART_CR3_RXFTCFG_2 /*!< RXFIFO FIFO reaches 7/8 of its depth */ +#define SMARTCARD_RXFIFO_THRESHOLD_8_8 (USART_CR3_RXFTCFG_2|USART_CR3_RXFTCFG_0) /*!< RXFIFO FIFO becomes full */ +/** + * @} + */ + +/** @defgroup SMARTCARDEx_Flags SMARTCARD Flags + * Elements values convention: 0xXXXX + * - 0xXXXX : Flag mask in the ISR register + * @{ + */ +#define SMARTCARD_FLAG_TCBGT USART_ISR_TCBGT /*!< SMARTCARD transmission complete before guard time completion */ +#define SMARTCARD_FLAG_REACK USART_ISR_REACK /*!< SMARTCARD receive enable acknowledge flag */ +#define SMARTCARD_FLAG_TEACK USART_ISR_TEACK /*!< SMARTCARD transmit enable acknowledge flag */ +#define SMARTCARD_FLAG_BUSY USART_ISR_BUSY /*!< SMARTCARD busy flag */ +#define SMARTCARD_FLAG_EOBF USART_ISR_EOBF /*!< SMARTCARD end of block flag */ +#define SMARTCARD_FLAG_RTOF USART_ISR_RTOF /*!< SMARTCARD receiver timeout flag */ +#define SMARTCARD_FLAG_TXE USART_ISR_TXE_TXFNF /*!< SMARTCARD transmit data register empty */ +#define SMARTCARD_FLAG_TXFNF USART_ISR_TXE_TXFNF /*!< SMARTCARD TXFIFO not full */ +#define SMARTCARD_FLAG_TC USART_ISR_TC /*!< SMARTCARD transmission complete */ +#define SMARTCARD_FLAG_RXNE USART_ISR_RXNE_RXFNE /*!< SMARTCARD read data register not empty */ +#define SMARTCARD_FLAG_RXFNE USART_ISR_RXNE_RXFNE /*!< SMARTCARD RXFIFO not empty */ +#define SMARTCARD_FLAG_IDLE USART_ISR_IDLE /*!< SMARTCARD idle line detection */ +#define SMARTCARD_FLAG_ORE USART_ISR_ORE /*!< SMARTCARD overrun error */ +#define SMARTCARD_FLAG_NE USART_ISR_NE /*!< SMARTCARD noise error */ +#define SMARTCARD_FLAG_FE USART_ISR_FE /*!< SMARTCARD frame error */ +#define SMARTCARD_FLAG_PE USART_ISR_PE /*!< SMARTCARD parity error */ +#define SMARTCARD_FLAG_TXFE USART_ISR_TXFE /*!< SMARTCARD TXFIFO Empty flag */ +#define SMARTCARD_FLAG_RXFF USART_ISR_RXFF /*!< SMARTCARD RXFIFO Full flag */ +#define SMARTCARD_FLAG_RXFT USART_ISR_RXFT /*!< SMARTCARD RXFIFO threshold flag */ +#define SMARTCARD_FLAG_TXFT USART_ISR_TXFT /*!< SMARTCARD TXFIFO threshold flag */ +/** + * @} + */ + +/** @defgroup SMARTCARDEx_Interrupt_definition SMARTCARD Interrupts Definition + * Elements values convention: 000ZZZZZ0XXYYYYYb + * - YYYYY : Interrupt source position in the XX register (5 bits) + * - XX : Interrupt source register (2 bits) + * - 01: CR1 register + * - 10: CR2 register + * - 11: CR3 register + * - ZZZZZ : Flag position in the ISR register(5 bits) + * @{ + */ +#define SMARTCARD_IT_PE 0x0028U /*!< SMARTCARD parity error interruption */ +#define SMARTCARD_IT_TXE 0x0727U /*!< SMARTCARD transmit data register empty interruption */ +#define SMARTCARD_IT_TXFNF 0x0727U /*!< SMARTCARD TX FIFO not full interruption */ +#define SMARTCARD_IT_TC 0x0626U /*!< SMARTCARD transmission complete interruption */ +#define SMARTCARD_IT_RXNE 0x0525U /*!< SMARTCARD read data register not empty interruption */ +#define SMARTCARD_IT_RXFNE 0x0525U /*!< SMARTCARD RXFIFO not empty interruption */ +#define SMARTCARD_IT_IDLE 0x0424U /*!< SMARTCARD idle line detection interruption */ + +#define SMARTCARD_IT_ERR 0x0060U /*!< SMARTCARD error interruption */ +#define SMARTCARD_IT_ORE 0x0300U /*!< SMARTCARD overrun error interruption */ +#define SMARTCARD_IT_NE 0x0200U /*!< SMARTCARD noise error interruption */ +#define SMARTCARD_IT_FE 0x0100U /*!< SMARTCARD frame error interruption */ + +#define SMARTCARD_IT_EOB 0x0C3BU /*!< SMARTCARD end of block interruption */ +#define SMARTCARD_IT_RTO 0x0B3AU /*!< SMARTCARD receiver timeout interruption */ +#define SMARTCARD_IT_TCBGT 0x1978U /*!< SMARTCARD transmission complete before guard time completion interruption */ + +#define SMARTCARD_IT_RXFF 0x183FU /*!< SMARTCARD RXFIFO full interruption */ +#define SMARTCARD_IT_TXFE 0x173EU /*!< SMARTCARD TXFIFO empty interruption */ +#define SMARTCARD_IT_RXFT 0x1A7CU /*!< SMARTCARD RXFIFO threshold reached interruption */ +#define SMARTCARD_IT_TXFT 0x1B77U /*!< SMARTCARD TXFIFO threshold reached interruption */ +/** + * @} + */ + +/** @defgroup SMARTCARDEx_IT_CLEAR_Flags SMARTCARD Interruption Clear Flags + * @{ + */ +#define SMARTCARD_CLEAR_PEF USART_ICR_PECF /*!< SMARTCARD parity error clear flag */ +#define SMARTCARD_CLEAR_FEF USART_ICR_FECF /*!< SMARTCARD framing error clear flag */ +#define SMARTCARD_CLEAR_NEF USART_ICR_NECF /*!< SMARTCARD noise error detected clear flag */ +#define SMARTCARD_CLEAR_OREF USART_ICR_ORECF /*!< SMARTCARD overrun error clear flag */ +#define SMARTCARD_CLEAR_IDLEF USART_ICR_IDLECF /*!< SMARTCARD idle line detected clear flag */ +#define SMARTCARD_CLEAR_TXFECF USART_ICR_TXFECF /*!< TXFIFO empty Clear Flag */ +#define SMARTCARD_CLEAR_TCF USART_ICR_TCCF /*!< SMARTCARD transmission complete clear flag */ +#define SMARTCARD_CLEAR_TCBGTF USART_ICR_TCBGTCF /*!< SMARTCARD transmission complete before guard time completion clear flag */ +#define SMARTCARD_CLEAR_RTOF USART_ICR_RTOCF /*!< SMARTCARD receiver time out clear flag */ +#define SMARTCARD_CLEAR_EOBF USART_ICR_EOBCF /*!< SMARTCARD end of block clear flag */ +/** + * @} + */ + +/** + * @} + */ +/* Exported macros -----------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup SMARTCARDEx_Private_Macros SMARTCARD Extended Private Macros + * @{ + */ + +/** @brief Set the Transmission Completion flag + * @param __HANDLE__ specifies the SMARTCARD Handle. + * @note If TCBGT (Transmission Complete Before Guard Time) flag is not available or if + * AdvancedInit.TxCompletionIndication is not already filled, the latter is forced + * to SMARTCARD_TC (transmission completion indication when guard time has elapsed). + * @retval None + */ +#define SMARTCARD_TRANSMISSION_COMPLETION_SETTING(__HANDLE__) \ + do { \ + if (HAL_IS_BIT_CLR((__HANDLE__)->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_TXCOMPLETION)) \ + { \ + (__HANDLE__)->AdvancedInit.TxCompletionIndication = SMARTCARD_TC; \ + } \ + else \ + { \ + assert_param(IS_SMARTCARD_TRANSMISSION_COMPLETION((__HANDLE__)->AdvancedInit.TxCompletionIndication)); \ + } \ + } while(0U) + +/** @brief Return the transmission completion flag. + * @param __HANDLE__ specifies the SMARTCARD Handle. + * @note Based on AdvancedInit.TxCompletionIndication setting, return TC or TCBGT flag. + * When TCBGT flag (Transmission Complete Before Guard Time) is not available, TC flag is + * reported. + * @retval Transmission completion flag + */ +#define SMARTCARD_TRANSMISSION_COMPLETION_FLAG(__HANDLE__) \ + (((__HANDLE__)->AdvancedInit.TxCompletionIndication == SMARTCARD_TC) ? (SMARTCARD_FLAG_TC) : (SMARTCARD_FLAG_TCBGT)) + + +/** @brief Ensure that SMARTCARD frame transmission completion used flag is valid. + * @param __TXCOMPLETE__ SMARTCARD frame transmission completion used flag. + * @retval SET (__TXCOMPLETE__ is valid) or RESET (__TXCOMPLETE__ is invalid) + */ +#define IS_SMARTCARD_TRANSMISSION_COMPLETION(__TXCOMPLETE__) (((__TXCOMPLETE__) == SMARTCARD_TCBGT) || \ + ((__TXCOMPLETE__) == SMARTCARD_TC)) + +/** @brief Ensure that SMARTCARD FIFO mode is valid. + * @param __STATE__ SMARTCARD FIFO mode. + * @retval SET (__STATE__ is valid) or RESET (__STATE__ is invalid) + */ +#define IS_SMARTCARD_FIFOMODE_STATE(__STATE__) (((__STATE__) == SMARTCARD_FIFOMODE_DISABLE ) || \ + ((__STATE__) == SMARTCARD_FIFOMODE_ENABLE)) + +/** @brief Ensure that SMARTCARD TXFIFO threshold level is valid. + * @param __THRESHOLD__ SMARTCARD TXFIFO threshold level. + * @retval SET (__THRESHOLD__ is valid) or RESET (__THRESHOLD__ is invalid) + */ +#define IS_SMARTCARD_TXFIFO_THRESHOLD(__THRESHOLD__) (((__THRESHOLD__) == SMARTCARD_TXFIFO_THRESHOLD_1_8) || \ + ((__THRESHOLD__) == SMARTCARD_TXFIFO_THRESHOLD_1_4) || \ + ((__THRESHOLD__) == SMARTCARD_TXFIFO_THRESHOLD_1_2) || \ + ((__THRESHOLD__) == SMARTCARD_TXFIFO_THRESHOLD_3_4) || \ + ((__THRESHOLD__) == SMARTCARD_TXFIFO_THRESHOLD_7_8) || \ + ((__THRESHOLD__) == SMARTCARD_TXFIFO_THRESHOLD_8_8)) + +/** @brief Ensure that SMARTCARD RXFIFO threshold level is valid. + * @param __THRESHOLD__ SMARTCARD RXFIFO threshold level. + * @retval SET (__THRESHOLD__ is valid) or RESET (__THRESHOLD__ is invalid) + */ +#define IS_SMARTCARD_RXFIFO_THRESHOLD(__THRESHOLD__) (((__THRESHOLD__) == SMARTCARD_RXFIFO_THRESHOLD_1_8) || \ + ((__THRESHOLD__) == SMARTCARD_RXFIFO_THRESHOLD_1_4) || \ + ((__THRESHOLD__) == SMARTCARD_RXFIFO_THRESHOLD_1_2) || \ + ((__THRESHOLD__) == SMARTCARD_RXFIFO_THRESHOLD_3_4) || \ + ((__THRESHOLD__) == SMARTCARD_RXFIFO_THRESHOLD_7_8) || \ + ((__THRESHOLD__) == SMARTCARD_RXFIFO_THRESHOLD_8_8)) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup SMARTCARDEx_Exported_Functions + * @{ + */ + +/* Initialization and de-initialization functions ****************************/ +/* IO operation methods *******************************************************/ + +/** @addtogroup SMARTCARDEx_Exported_Functions_Group1 + * @{ + */ + +/* Peripheral Control functions ***********************************************/ +void HAL_SMARTCARDEx_BlockLength_Config(SMARTCARD_HandleTypeDef *hsmartcard, uint8_t BlockLength); +void HAL_SMARTCARDEx_TimeOut_Config(SMARTCARD_HandleTypeDef *hsmartcard, uint32_t TimeOutValue); +HAL_StatusTypeDef HAL_SMARTCARDEx_EnableReceiverTimeOut(SMARTCARD_HandleTypeDef *hsmartcard); +HAL_StatusTypeDef HAL_SMARTCARDEx_DisableReceiverTimeOut(SMARTCARD_HandleTypeDef *hsmartcard); + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup SMARTCARDEx_Exported_Functions_Group2 + * @{ + */ + +/* IO operation functions *****************************************************/ +void HAL_SMARTCARDEx_RxFifoFullCallback(SMARTCARD_HandleTypeDef *hsmartcard); +void HAL_SMARTCARDEx_TxFifoEmptyCallback(SMARTCARD_HandleTypeDef *hsmartcard); + +/** + * @} + */ + +/** @addtogroup SMARTCARDEx_Exported_Functions_Group3 + * @{ + */ + +/* Peripheral Control functions ***********************************************/ +HAL_StatusTypeDef HAL_SMARTCARDEx_EnableFifoMode(SMARTCARD_HandleTypeDef *hsmartcard); +HAL_StatusTypeDef HAL_SMARTCARDEx_DisableFifoMode(SMARTCARD_HandleTypeDef *hsmartcard); +HAL_StatusTypeDef HAL_SMARTCARDEx_SetTxFifoThreshold(SMARTCARD_HandleTypeDef *hsmartcard, uint32_t Threshold); +HAL_StatusTypeDef HAL_SMARTCARDEx_SetRxFifoThreshold(SMARTCARD_HandleTypeDef *hsmartcard, uint32_t Threshold); + +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_SMARTCARD_EX_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_smbus.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_smbus.h new file mode 100644 index 0000000000..bad5113f95 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_smbus.h @@ -0,0 +1,789 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_smbus.h + * @author MCD Application Team + * @brief Header file of SMBUS HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_SMBUS_H +#define STM32H5xx_HAL_SMBUS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup SMBUS + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup SMBUS_Exported_Types SMBUS Exported Types + * @{ + */ + +/** @defgroup SMBUS_Configuration_Structure_definition SMBUS Configuration Structure definition + * @brief SMBUS Configuration Structure definition + * @{ + */ +typedef struct +{ + uint32_t Timing; /*!< Specifies the SMBUS_TIMINGR_register value. + This parameter calculated by referring to SMBUS initialization section + in Reference manual */ + uint32_t AnalogFilter; /*!< Specifies if Analog Filter is enable or not. + This parameter can be a value of @ref SMBUS_Analog_Filter */ + + uint32_t OwnAddress1; /*!< Specifies the first device own address. + This parameter can be a 7-bit address. */ + + uint32_t AddressingMode; /*!< Specifies addressing mode selected. + This parameter can be a value of @ref SMBUS_addressing_mode */ + + uint32_t DualAddressMode; /*!< Specifies if dual addressing mode is selected. + This parameter can be a value of @ref SMBUS_dual_addressing_mode */ + + uint32_t OwnAddress2; /*!< Specifies the second device own address if dual addressing mode is selected + This parameter can be a 7-bit address. */ + + uint32_t OwnAddress2Masks; /*!< Specifies the acknowledge mask address second device own address + if dual addressing mode is selected + This parameter can be a value of @ref SMBUS_own_address2_masks. */ + + uint32_t GeneralCallMode; /*!< Specifies if general call mode is selected. + This parameter can be a value of @ref SMBUS_general_call_addressing_mode. */ + + uint32_t NoStretchMode; /*!< Specifies if nostretch mode is selected. + This parameter can be a value of @ref SMBUS_nostretch_mode */ + + uint32_t PacketErrorCheckMode; /*!< Specifies if Packet Error Check mode is selected. + This parameter can be a value of @ref SMBUS_packet_error_check_mode */ + + uint32_t PeripheralMode; /*!< Specifies which mode of Periphal is selected. + This parameter can be a value of @ref SMBUS_peripheral_mode */ + + uint32_t SMBusTimeout; /*!< Specifies the content of the 32 Bits SMBUS_TIMEOUT_register value. + (Enable bits and different timeout values) + This parameter calculated by referring to SMBUS initialization section + in Reference manual */ +} SMBUS_InitTypeDef; +/** + * @} + */ + +/** @defgroup HAL_state_definition HAL state definition + * @brief HAL State definition + * @{ + */ +#define HAL_SMBUS_STATE_RESET (0x00000000U) /*!< SMBUS not yet initialized or disabled */ +#define HAL_SMBUS_STATE_READY (0x00000001U) /*!< SMBUS initialized and ready for use */ +#define HAL_SMBUS_STATE_BUSY (0x00000002U) /*!< SMBUS internal process is ongoing */ +#define HAL_SMBUS_STATE_MASTER_BUSY_TX (0x00000012U) /*!< Master Data Transmission process is ongoing */ +#define HAL_SMBUS_STATE_MASTER_BUSY_RX (0x00000022U) /*!< Master Data Reception process is ongoing */ +#define HAL_SMBUS_STATE_SLAVE_BUSY_TX (0x00000032U) /*!< Slave Data Transmission process is ongoing */ +#define HAL_SMBUS_STATE_SLAVE_BUSY_RX (0x00000042U) /*!< Slave Data Reception process is ongoing */ +#define HAL_SMBUS_STATE_TIMEOUT (0x00000003U) /*!< Timeout state */ +#define HAL_SMBUS_STATE_ERROR (0x00000004U) /*!< Reception process is ongoing */ +#define HAL_SMBUS_STATE_LISTEN (0x00000008U) /*!< Address Listen Mode is ongoing */ +/** + * @} + */ + +/** @defgroup SMBUS_Error_Code_definition SMBUS Error Code definition + * @brief SMBUS Error Code definition + * @{ + */ +#define HAL_SMBUS_ERROR_NONE (0x00000000U) /*!< No error */ +#define HAL_SMBUS_ERROR_BERR (0x00000001U) /*!< BERR error */ +#define HAL_SMBUS_ERROR_ARLO (0x00000002U) /*!< ARLO error */ +#define HAL_SMBUS_ERROR_ACKF (0x00000004U) /*!< ACKF error */ +#define HAL_SMBUS_ERROR_OVR (0x00000008U) /*!< OVR error */ +#define HAL_SMBUS_ERROR_HALTIMEOUT (0x00000010U) /*!< Timeout error */ +#define HAL_SMBUS_ERROR_BUSTIMEOUT (0x00000020U) /*!< Bus Timeout error */ +#define HAL_SMBUS_ERROR_ALERT (0x00000040U) /*!< Alert error */ +#define HAL_SMBUS_ERROR_PECERR (0x00000080U) /*!< PEC error */ +#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) +#define HAL_SMBUS_ERROR_INVALID_CALLBACK (0x00000100U) /*!< Invalid Callback error */ +#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ +#define HAL_SMBUS_ERROR_INVALID_PARAM (0x00000200U) /*!< Invalid Parameters error */ +/** + * @} + */ + +/** @defgroup SMBUS_handle_Structure_definition SMBUS handle Structure definition + * @brief SMBUS handle Structure definition + * @{ + */ +#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) +typedef struct __SMBUS_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ +{ + I2C_TypeDef *Instance; /*!< SMBUS registers base address */ + + SMBUS_InitTypeDef Init; /*!< SMBUS communication parameters */ + + uint8_t *pBuffPtr; /*!< Pointer to SMBUS transfer buffer */ + + uint16_t XferSize; /*!< SMBUS transfer size */ + + __IO uint16_t XferCount; /*!< SMBUS transfer counter */ + + __IO uint32_t XferOptions; /*!< SMBUS transfer options */ + + __IO uint32_t PreviousState; /*!< SMBUS communication Previous state */ + + HAL_LockTypeDef Lock; /*!< SMBUS locking object */ + + __IO uint32_t State; /*!< SMBUS communication state */ + + __IO uint32_t ErrorCode; /*!< SMBUS Error code */ + +#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) + void (* MasterTxCpltCallback)(struct __SMBUS_HandleTypeDef *hsmbus); + /*!< SMBUS Master Tx Transfer completed callback */ + void (* MasterRxCpltCallback)(struct __SMBUS_HandleTypeDef *hsmbus); + /*!< SMBUS Master Rx Transfer completed callback */ + void (* SlaveTxCpltCallback)(struct __SMBUS_HandleTypeDef *hsmbus); + /*!< SMBUS Slave Tx Transfer completed callback */ + void (* SlaveRxCpltCallback)(struct __SMBUS_HandleTypeDef *hsmbus); + /*!< SMBUS Slave Rx Transfer completed callback */ + void (* ListenCpltCallback)(struct __SMBUS_HandleTypeDef *hsmbus); + /*!< SMBUS Listen Complete callback */ + void (* ErrorCallback)(struct __SMBUS_HandleTypeDef *hsmbus); + /*!< SMBUS Error callback */ + + void (* AddrCallback)(struct __SMBUS_HandleTypeDef *hsmbus, uint8_t TransferDirection, uint16_t AddrMatchCode); + /*!< SMBUS Slave Address Match callback */ + + void (* MspInitCallback)(struct __SMBUS_HandleTypeDef *hsmbus); + /*!< SMBUS Msp Init callback */ + void (* MspDeInitCallback)(struct __SMBUS_HandleTypeDef *hsmbus); + /*!< SMBUS Msp DeInit callback */ + +#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ +} SMBUS_HandleTypeDef; + +#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) +/** + * @brief HAL SMBUS Callback ID enumeration definition + */ +typedef enum +{ + HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID = 0x00U, /*!< SMBUS Master Tx Transfer completed callback ID */ + HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID = 0x01U, /*!< SMBUS Master Rx Transfer completed callback ID */ + HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID = 0x02U, /*!< SMBUS Slave Tx Transfer completed callback ID */ + HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID = 0x03U, /*!< SMBUS Slave Rx Transfer completed callback ID */ + HAL_SMBUS_LISTEN_COMPLETE_CB_ID = 0x04U, /*!< SMBUS Listen Complete callback ID */ + HAL_SMBUS_ERROR_CB_ID = 0x05U, /*!< SMBUS Error callback ID */ + + HAL_SMBUS_MSPINIT_CB_ID = 0x06U, /*!< SMBUS Msp Init callback ID */ + HAL_SMBUS_MSPDEINIT_CB_ID = 0x07U /*!< SMBUS Msp DeInit callback ID */ + +} HAL_SMBUS_CallbackIDTypeDef; + +/** + * @brief HAL SMBUS Callback pointer definition + */ +typedef void (*pSMBUS_CallbackTypeDef)(SMBUS_HandleTypeDef *hsmbus); +/*!< pointer to an SMBUS callback function */ +typedef void (*pSMBUS_AddrCallbackTypeDef)(SMBUS_HandleTypeDef *hsmbus, uint8_t TransferDirection, + uint16_t AddrMatchCode); +/*!< pointer to an SMBUS Address Match callback function */ + +#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** + * @} + */ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup SMBUS_Exported_Constants SMBUS Exported Constants + * @{ + */ + +/** @defgroup SMBUS_Analog_Filter SMBUS Analog Filter + * @{ + */ +#define SMBUS_ANALOGFILTER_ENABLE (0x00000000U) +#define SMBUS_ANALOGFILTER_DISABLE I2C_CR1_ANFOFF +/** + * @} + */ + +/** @defgroup SMBUS_addressing_mode SMBUS addressing mode + * @{ + */ +#define SMBUS_ADDRESSINGMODE_7BIT (0x00000001U) +/** + * @} + */ + +/** @defgroup SMBUS_dual_addressing_mode SMBUS dual addressing mode + * @{ + */ + +#define SMBUS_DUALADDRESS_DISABLE (0x00000000U) +#define SMBUS_DUALADDRESS_ENABLE I2C_OAR2_OA2EN +/** + * @} + */ + +/** @defgroup SMBUS_own_address2_masks SMBUS ownaddress2 masks + * @{ + */ + +#define SMBUS_OA2_NOMASK ((uint8_t)0x00U) +#define SMBUS_OA2_MASK01 ((uint8_t)0x01U) +#define SMBUS_OA2_MASK02 ((uint8_t)0x02U) +#define SMBUS_OA2_MASK03 ((uint8_t)0x03U) +#define SMBUS_OA2_MASK04 ((uint8_t)0x04U) +#define SMBUS_OA2_MASK05 ((uint8_t)0x05U) +#define SMBUS_OA2_MASK06 ((uint8_t)0x06U) +#define SMBUS_OA2_MASK07 ((uint8_t)0x07U) +/** + * @} + */ + + +/** @defgroup SMBUS_general_call_addressing_mode SMBUS general call addressing mode + * @{ + */ +#define SMBUS_GENERALCALL_DISABLE (0x00000000U) +#define SMBUS_GENERALCALL_ENABLE I2C_CR1_GCEN +/** + * @} + */ + +/** @defgroup SMBUS_nostretch_mode SMBUS nostretch mode + * @{ + */ +#define SMBUS_NOSTRETCH_DISABLE (0x00000000U) +#define SMBUS_NOSTRETCH_ENABLE I2C_CR1_NOSTRETCH +/** + * @} + */ + +/** @defgroup SMBUS_packet_error_check_mode SMBUS packet error check mode + * @{ + */ +#define SMBUS_PEC_DISABLE (0x00000000U) +#define SMBUS_PEC_ENABLE I2C_CR1_PECEN +/** + * @} + */ + +/** @defgroup SMBUS_peripheral_mode SMBUS peripheral mode + * @{ + */ +#define SMBUS_PERIPHERAL_MODE_SMBUS_HOST I2C_CR1_SMBHEN +#define SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE (0x00000000U) +#define SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE_ARP I2C_CR1_SMBDEN +/** + * @} + */ + +/** @defgroup SMBUS_ReloadEndMode_definition SMBUS ReloadEndMode definition + * @{ + */ + +#define SMBUS_SOFTEND_MODE (0x00000000U) +#define SMBUS_RELOAD_MODE I2C_CR2_RELOAD +#define SMBUS_AUTOEND_MODE I2C_CR2_AUTOEND +#define SMBUS_SENDPEC_MODE I2C_CR2_PECBYTE +/** + * @} + */ + +/** @defgroup SMBUS_StartStopMode_definition SMBUS StartStopMode definition + * @{ + */ + +#define SMBUS_NO_STARTSTOP (0x00000000U) +#define SMBUS_GENERATE_STOP (uint32_t)(0x80000000U | I2C_CR2_STOP) +#define SMBUS_GENERATE_START_READ (uint32_t)(0x80000000U | I2C_CR2_START | I2C_CR2_RD_WRN) +#define SMBUS_GENERATE_START_WRITE (uint32_t)(0x80000000U | I2C_CR2_START) +/** + * @} + */ + +/** @defgroup SMBUS_XferOptions_definition SMBUS XferOptions definition + * @{ + */ + +/* List of XferOptions in usage of : + * 1- Restart condition when direction change + * 2- No Restart condition in other use cases + */ +#define SMBUS_FIRST_FRAME SMBUS_SOFTEND_MODE +#define SMBUS_NEXT_FRAME ((uint32_t)(SMBUS_RELOAD_MODE | SMBUS_SOFTEND_MODE)) +#define SMBUS_FIRST_AND_LAST_FRAME_NO_PEC SMBUS_AUTOEND_MODE +#define SMBUS_LAST_FRAME_NO_PEC SMBUS_AUTOEND_MODE +#define SMBUS_FIRST_FRAME_WITH_PEC ((uint32_t)(SMBUS_SOFTEND_MODE | SMBUS_SENDPEC_MODE)) +#define SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC ((uint32_t)(SMBUS_AUTOEND_MODE | SMBUS_SENDPEC_MODE)) +#define SMBUS_LAST_FRAME_WITH_PEC ((uint32_t)(SMBUS_AUTOEND_MODE | SMBUS_SENDPEC_MODE)) + +/* List of XferOptions in usage of : + * 1- Restart condition in all use cases (direction change or not) + */ +#define SMBUS_OTHER_FRAME_NO_PEC (0x000000AAU) +#define SMBUS_OTHER_FRAME_WITH_PEC (0x0000AA00U) +#define SMBUS_OTHER_AND_LAST_FRAME_NO_PEC (0x00AA0000U) +#define SMBUS_OTHER_AND_LAST_FRAME_WITH_PEC (0xAA000000U) +/** + * @} + */ + +/** @defgroup SMBUS_Interrupt_configuration_definition SMBUS Interrupt configuration definition + * @brief SMBUS Interrupt definition + * Elements values convention: 0xXXXXXXXX + * - XXXXXXXX : Interrupt control mask + * @{ + */ +#define SMBUS_IT_ERRI I2C_CR1_ERRIE +#define SMBUS_IT_TCI I2C_CR1_TCIE +#define SMBUS_IT_STOPI I2C_CR1_STOPIE +#define SMBUS_IT_NACKI I2C_CR1_NACKIE +#define SMBUS_IT_ADDRI I2C_CR1_ADDRIE +#define SMBUS_IT_RXI I2C_CR1_RXIE +#define SMBUS_IT_TXI I2C_CR1_TXIE +#define SMBUS_IT_TX (SMBUS_IT_ERRI | SMBUS_IT_TCI | SMBUS_IT_STOPI | \ + SMBUS_IT_NACKI | SMBUS_IT_TXI) +#define SMBUS_IT_RX (SMBUS_IT_ERRI | SMBUS_IT_TCI | SMBUS_IT_NACKI | \ + SMBUS_IT_RXI) +#define SMBUS_IT_ALERT (SMBUS_IT_ERRI) +#define SMBUS_IT_ADDR (SMBUS_IT_ADDRI | SMBUS_IT_STOPI | SMBUS_IT_NACKI) +/** + * @} + */ + +/** @defgroup SMBUS_Flag_definition SMBUS Flag definition + * @brief Flag definition + * Elements values convention: 0xXXXXYYYY + * - XXXXXXXX : Flag mask + * @{ + */ + +#define SMBUS_FLAG_TXE I2C_ISR_TXE +#define SMBUS_FLAG_TXIS I2C_ISR_TXIS +#define SMBUS_FLAG_RXNE I2C_ISR_RXNE +#define SMBUS_FLAG_ADDR I2C_ISR_ADDR +#define SMBUS_FLAG_AF I2C_ISR_NACKF +#define SMBUS_FLAG_STOPF I2C_ISR_STOPF +#define SMBUS_FLAG_TC I2C_ISR_TC +#define SMBUS_FLAG_TCR I2C_ISR_TCR +#define SMBUS_FLAG_BERR I2C_ISR_BERR +#define SMBUS_FLAG_ARLO I2C_ISR_ARLO +#define SMBUS_FLAG_OVR I2C_ISR_OVR +#define SMBUS_FLAG_PECERR I2C_ISR_PECERR +#define SMBUS_FLAG_TIMEOUT I2C_ISR_TIMEOUT +#define SMBUS_FLAG_ALERT I2C_ISR_ALERT +#define SMBUS_FLAG_BUSY I2C_ISR_BUSY +#define SMBUS_FLAG_DIR I2C_ISR_DIR +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros ------------------------------------------------------------*/ +/** @defgroup SMBUS_Exported_Macros SMBUS Exported Macros + * @{ + */ + +/** @brief Reset SMBUS handle state. + * @param __HANDLE__ specifies the SMBUS Handle. + * @retval None + */ +#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) +#define __HAL_SMBUS_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->State = HAL_SMBUS_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_SMBUS_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_SMBUS_STATE_RESET) +#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ + +/** @brief Enable the specified SMBUS interrupts. + * @param __HANDLE__ specifies the SMBUS Handle. + * @param __INTERRUPT__ specifies the interrupt source to enable. + * This parameter can be one of the following values: + * @arg @ref SMBUS_IT_ERRI Errors interrupt enable + * @arg @ref SMBUS_IT_TCI Transfer complete interrupt enable + * @arg @ref SMBUS_IT_STOPI STOP detection interrupt enable + * @arg @ref SMBUS_IT_NACKI NACK received interrupt enable + * @arg @ref SMBUS_IT_ADDRI Address match interrupt enable + * @arg @ref SMBUS_IT_RXI RX interrupt enable + * @arg @ref SMBUS_IT_TXI TX interrupt enable + * + * @retval None + */ +#define __HAL_SMBUS_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR1 |= (__INTERRUPT__)) + +/** @brief Disable the specified SMBUS interrupts. + * @param __HANDLE__ specifies the SMBUS Handle. + * @param __INTERRUPT__ specifies the interrupt source to disable. + * This parameter can be one of the following values: + * @arg @ref SMBUS_IT_ERRI Errors interrupt enable + * @arg @ref SMBUS_IT_TCI Transfer complete interrupt enable + * @arg @ref SMBUS_IT_STOPI STOP detection interrupt enable + * @arg @ref SMBUS_IT_NACKI NACK received interrupt enable + * @arg @ref SMBUS_IT_ADDRI Address match interrupt enable + * @arg @ref SMBUS_IT_RXI RX interrupt enable + * @arg @ref SMBUS_IT_TXI TX interrupt enable + * + * @retval None + */ +#define __HAL_SMBUS_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR1 &= (~(__INTERRUPT__))) + +/** @brief Check whether the specified SMBUS interrupt source is enabled or not. + * @param __HANDLE__ specifies the SMBUS Handle. + * @param __INTERRUPT__ specifies the SMBUS interrupt source to check. + * This parameter can be one of the following values: + * @arg @ref SMBUS_IT_ERRI Errors interrupt enable + * @arg @ref SMBUS_IT_TCI Transfer complete interrupt enable + * @arg @ref SMBUS_IT_STOPI STOP detection interrupt enable + * @arg @ref SMBUS_IT_NACKI NACK received interrupt enable + * @arg @ref SMBUS_IT_ADDRI Address match interrupt enable + * @arg @ref SMBUS_IT_RXI RX interrupt enable + * @arg @ref SMBUS_IT_TXI TX interrupt enable + * + * @retval The new state of __IT__ (SET or RESET). + */ +#define __HAL_SMBUS_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) \ + ((((__HANDLE__)->Instance->CR1 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) + +/** @brief Check whether the specified SMBUS flag is set or not. + * @param __HANDLE__ specifies the SMBUS Handle. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg @ref SMBUS_FLAG_TXE Transmit data register empty + * @arg @ref SMBUS_FLAG_TXIS Transmit interrupt status + * @arg @ref SMBUS_FLAG_RXNE Receive data register not empty + * @arg @ref SMBUS_FLAG_ADDR Address matched (slave mode) + * @arg @ref SMBUS_FLAG_AF NACK received flag + * @arg @ref SMBUS_FLAG_STOPF STOP detection flag + * @arg @ref SMBUS_FLAG_TC Transfer complete (master mode) + * @arg @ref SMBUS_FLAG_TCR Transfer complete reload + * @arg @ref SMBUS_FLAG_BERR Bus error + * @arg @ref SMBUS_FLAG_ARLO Arbitration lost + * @arg @ref SMBUS_FLAG_OVR Overrun/Underrun + * @arg @ref SMBUS_FLAG_PECERR PEC error in reception + * @arg @ref SMBUS_FLAG_TIMEOUT Timeout or Tlow detection flag + * @arg @ref SMBUS_FLAG_ALERT SMBus alert + * @arg @ref SMBUS_FLAG_BUSY Bus busy + * @arg @ref SMBUS_FLAG_DIR Transfer direction (slave mode) + * + * @retval The new state of __FLAG__ (SET or RESET). + */ +#define SMBUS_FLAG_MASK (0x0001FFFFU) +#define __HAL_SMBUS_GET_FLAG(__HANDLE__, __FLAG__) \ + (((((__HANDLE__)->Instance->ISR) & ((__FLAG__) & SMBUS_FLAG_MASK)) == \ + ((__FLAG__) & SMBUS_FLAG_MASK)) ? SET : RESET) + +/** @brief Clear the SMBUS pending flags which are cleared by writing 1 in a specific bit. + * @param __HANDLE__ specifies the SMBUS Handle. + * @param __FLAG__ specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg @ref SMBUS_FLAG_TXE Transmit data register empty + * @arg @ref SMBUS_FLAG_ADDR Address matched (slave mode) + * @arg @ref SMBUS_FLAG_AF NACK received flag + * @arg @ref SMBUS_FLAG_STOPF STOP detection flag + * @arg @ref SMBUS_FLAG_BERR Bus error + * @arg @ref SMBUS_FLAG_ARLO Arbitration lost + * @arg @ref SMBUS_FLAG_OVR Overrun/Underrun + * @arg @ref SMBUS_FLAG_PECERR PEC error in reception + * @arg @ref SMBUS_FLAG_TIMEOUT Timeout or Tlow detection flag + * @arg @ref SMBUS_FLAG_ALERT SMBus alert + * + * @retval None + */ +#define __HAL_SMBUS_CLEAR_FLAG(__HANDLE__, __FLAG__) (((__FLAG__) == SMBUS_FLAG_TXE) ? \ + ((__HANDLE__)->Instance->ISR |= (__FLAG__)) : \ + ((__HANDLE__)->Instance->ICR = (__FLAG__))) + +/** @brief Enable the specified SMBUS peripheral. + * @param __HANDLE__ specifies the SMBUS Handle. + * @retval None + */ +#define __HAL_SMBUS_ENABLE(__HANDLE__) (SET_BIT((__HANDLE__)->Instance->CR1, I2C_CR1_PE)) + +/** @brief Disable the specified SMBUS peripheral. + * @param __HANDLE__ specifies the SMBUS Handle. + * @retval None + */ +#define __HAL_SMBUS_DISABLE(__HANDLE__) (CLEAR_BIT((__HANDLE__)->Instance->CR1, I2C_CR1_PE)) + +/** @brief Generate a Non-Acknowledge SMBUS peripheral in Slave mode. + * @param __HANDLE__ specifies the SMBUS Handle. + * @retval None + */ +#define __HAL_SMBUS_GENERATE_NACK(__HANDLE__) (SET_BIT((__HANDLE__)->Instance->CR2, I2C_CR2_NACK)) + +/** + * @} + */ + + +/* Private constants ---------------------------------------------------------*/ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup SMBUS_Private_Macro SMBUS Private Macros + * @{ + */ + +#define IS_SMBUS_ANALOG_FILTER(FILTER) (((FILTER) == SMBUS_ANALOGFILTER_ENABLE) || \ + ((FILTER) == SMBUS_ANALOGFILTER_DISABLE)) + +#define IS_SMBUS_DIGITAL_FILTER(FILTER) ((FILTER) <= 0x0000000FU) + +#define IS_SMBUS_ADDRESSING_MODE(MODE) ((MODE) == SMBUS_ADDRESSINGMODE_7BIT) + +#define IS_SMBUS_DUAL_ADDRESS(ADDRESS) (((ADDRESS) == SMBUS_DUALADDRESS_DISABLE) || \ + ((ADDRESS) == SMBUS_DUALADDRESS_ENABLE)) + +#define IS_SMBUS_OWN_ADDRESS2_MASK(MASK) (((MASK) == SMBUS_OA2_NOMASK) || \ + ((MASK) == SMBUS_OA2_MASK01) || \ + ((MASK) == SMBUS_OA2_MASK02) || \ + ((MASK) == SMBUS_OA2_MASK03) || \ + ((MASK) == SMBUS_OA2_MASK04) || \ + ((MASK) == SMBUS_OA2_MASK05) || \ + ((MASK) == SMBUS_OA2_MASK06) || \ + ((MASK) == SMBUS_OA2_MASK07)) + +#define IS_SMBUS_GENERAL_CALL(CALL) (((CALL) == SMBUS_GENERALCALL_DISABLE) || \ + ((CALL) == SMBUS_GENERALCALL_ENABLE)) + +#define IS_SMBUS_NO_STRETCH(STRETCH) (((STRETCH) == SMBUS_NOSTRETCH_DISABLE) || \ + ((STRETCH) == SMBUS_NOSTRETCH_ENABLE)) + +#define IS_SMBUS_PEC(PEC) (((PEC) == SMBUS_PEC_DISABLE) || \ + ((PEC) == SMBUS_PEC_ENABLE)) + +#define IS_SMBUS_PERIPHERAL_MODE(MODE) (((MODE) == SMBUS_PERIPHERAL_MODE_SMBUS_HOST) || \ + ((MODE) == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE) || \ + ((MODE) == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE_ARP)) + +#define IS_SMBUS_TRANSFER_MODE(MODE) (((MODE) == SMBUS_RELOAD_MODE) || \ + ((MODE) == SMBUS_AUTOEND_MODE) || \ + ((MODE) == SMBUS_SOFTEND_MODE) || \ + ((MODE) == SMBUS_SENDPEC_MODE) || \ + ((MODE) == (SMBUS_RELOAD_MODE | SMBUS_SENDPEC_MODE)) || \ + ((MODE) == (SMBUS_AUTOEND_MODE | SMBUS_SENDPEC_MODE)) || \ + ((MODE) == (SMBUS_AUTOEND_MODE | SMBUS_RELOAD_MODE)) || \ + ((MODE) == (SMBUS_AUTOEND_MODE | SMBUS_SENDPEC_MODE | \ + SMBUS_RELOAD_MODE ))) + + +#define IS_SMBUS_TRANSFER_REQUEST(REQUEST) (((REQUEST) == SMBUS_GENERATE_STOP) || \ + ((REQUEST) == SMBUS_GENERATE_START_READ) || \ + ((REQUEST) == SMBUS_GENERATE_START_WRITE) || \ + ((REQUEST) == SMBUS_NO_STARTSTOP)) + + +#define IS_SMBUS_TRANSFER_OPTIONS_REQUEST(REQUEST) (IS_SMBUS_TRANSFER_OTHER_OPTIONS_REQUEST(REQUEST) || \ + ((REQUEST) == SMBUS_FIRST_FRAME) || \ + ((REQUEST) == SMBUS_NEXT_FRAME) || \ + ((REQUEST) == SMBUS_FIRST_AND_LAST_FRAME_NO_PEC) || \ + ((REQUEST) == SMBUS_LAST_FRAME_NO_PEC) || \ + ((REQUEST) == SMBUS_FIRST_FRAME_WITH_PEC) || \ + ((REQUEST) == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || \ + ((REQUEST) == SMBUS_LAST_FRAME_WITH_PEC)) + +#define IS_SMBUS_TRANSFER_OTHER_OPTIONS_REQUEST(REQUEST) (((REQUEST) == SMBUS_OTHER_FRAME_NO_PEC) || \ + ((REQUEST) == SMBUS_OTHER_AND_LAST_FRAME_NO_PEC) || \ + ((REQUEST) == SMBUS_OTHER_FRAME_WITH_PEC) || \ + ((REQUEST) == SMBUS_OTHER_AND_LAST_FRAME_WITH_PEC)) + +#define SMBUS_RESET_CR1(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= \ + (uint32_t)~((uint32_t)(I2C_CR1_SMBHEN | I2C_CR1_SMBDEN | \ + I2C_CR1_PECEN))) +#define SMBUS_RESET_CR2(__HANDLE__) ((__HANDLE__)->Instance->CR2 &= \ + (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_HEAD10R | \ + I2C_CR2_NBYTES | I2C_CR2_RELOAD | \ + I2C_CR2_RD_WRN))) + +#define SMBUS_GENERATE_START(__ADDMODE__,__ADDRESS__) (((__ADDMODE__) == SMBUS_ADDRESSINGMODE_7BIT) ? \ + (uint32_t)((((uint32_t)(__ADDRESS__) & (I2C_CR2_SADD)) | \ + (I2C_CR2_START) | (I2C_CR2_AUTOEND)) & \ + (~I2C_CR2_RD_WRN)) : \ + (uint32_t)((((uint32_t)(__ADDRESS__) & \ + (I2C_CR2_SADD)) | (I2C_CR2_ADD10) | \ + (I2C_CR2_START)) & (~I2C_CR2_RD_WRN))) + +#define SMBUS_GET_ADDR_MATCH(__HANDLE__) (((__HANDLE__)->Instance->ISR & I2C_ISR_ADDCODE) >> 17U) +#define SMBUS_GET_DIR(__HANDLE__) (((__HANDLE__)->Instance->ISR & I2C_ISR_DIR) >> 16U) +#define SMBUS_GET_STOP_MODE(__HANDLE__) ((__HANDLE__)->Instance->CR2 & I2C_CR2_AUTOEND) +#define SMBUS_GET_PEC_MODE(__HANDLE__) ((__HANDLE__)->Instance->CR2 & I2C_CR2_PECBYTE) +#define SMBUS_GET_ALERT_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CR1 & I2C_CR1_ALERTEN) + +#define SMBUS_CHECK_FLAG(__ISR__, __FLAG__) ((((__ISR__) & ((__FLAG__) & SMBUS_FLAG_MASK)) == \ + ((__FLAG__) & SMBUS_FLAG_MASK)) ? SET : RESET) +#define SMBUS_CHECK_IT_SOURCE(__CR1__, __IT__) ((((__CR1__) & (__IT__)) == (__IT__)) ? SET : RESET) + +#define IS_SMBUS_OWN_ADDRESS1(ADDRESS1) ((ADDRESS1) <= 0x000003FFU) +#define IS_SMBUS_OWN_ADDRESS2(ADDRESS2) ((ADDRESS2) <= (uint16_t)0x00FFU) + +/** + * @} + */ + +/* Include SMBUS HAL Extended module */ +#include "stm32h5xx_hal_smbus_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup SMBUS_Exported_Functions SMBUS Exported Functions + * @{ + */ + +/** @addtogroup SMBUS_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ + +/* Initialization and de-initialization functions ****************************/ +HAL_StatusTypeDef HAL_SMBUS_Init(SMBUS_HandleTypeDef *hsmbus); +HAL_StatusTypeDef HAL_SMBUS_DeInit(SMBUS_HandleTypeDef *hsmbus); +void HAL_SMBUS_MspInit(SMBUS_HandleTypeDef *hsmbus); +void HAL_SMBUS_MspDeInit(SMBUS_HandleTypeDef *hsmbus); +HAL_StatusTypeDef HAL_SMBUS_ConfigAnalogFilter(SMBUS_HandleTypeDef *hsmbus, uint32_t AnalogFilter); +HAL_StatusTypeDef HAL_SMBUS_ConfigDigitalFilter(SMBUS_HandleTypeDef *hsmbus, uint32_t DigitalFilter); + +/* Callbacks Register/UnRegister functions ***********************************/ +#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) +HAL_StatusTypeDef HAL_SMBUS_RegisterCallback(SMBUS_HandleTypeDef *hsmbus, + HAL_SMBUS_CallbackIDTypeDef CallbackID, + pSMBUS_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_SMBUS_UnRegisterCallback(SMBUS_HandleTypeDef *hsmbus, + HAL_SMBUS_CallbackIDTypeDef CallbackID); + +HAL_StatusTypeDef HAL_SMBUS_RegisterAddrCallback(SMBUS_HandleTypeDef *hsmbus, + pSMBUS_AddrCallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_SMBUS_UnRegisterAddrCallback(SMBUS_HandleTypeDef *hsmbus); +#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @addtogroup SMBUS_Exported_Functions_Group2 Input and Output operation functions + * @{ + */ + +/* IO operation functions *****************************************************/ +/** @addtogroup Blocking_mode_Polling Blocking mode Polling + * @{ + */ +/******* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_SMBUS_IsDeviceReady(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint32_t Trials, + uint32_t Timeout); +/** + * @} + */ + +/** @addtogroup Non-Blocking_mode_Interrupt Non-Blocking mode Interrupt + * @{ + */ +/******* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_SMBUS_Master_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, + uint8_t *pData, uint16_t Size, uint32_t XferOptions); +HAL_StatusTypeDef HAL_SMBUS_Master_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, + uint8_t *pData, uint16_t Size, uint32_t XferOptions); +HAL_StatusTypeDef HAL_SMBUS_Master_Abort_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress); +HAL_StatusTypeDef HAL_SMBUS_Slave_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, + uint32_t XferOptions); +HAL_StatusTypeDef HAL_SMBUS_Slave_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, + uint32_t XferOptions); + +HAL_StatusTypeDef HAL_SMBUS_EnableAlert_IT(SMBUS_HandleTypeDef *hsmbus); +HAL_StatusTypeDef HAL_SMBUS_DisableAlert_IT(SMBUS_HandleTypeDef *hsmbus); +HAL_StatusTypeDef HAL_SMBUS_EnableListen_IT(SMBUS_HandleTypeDef *hsmbus); +HAL_StatusTypeDef HAL_SMBUS_DisableListen_IT(SMBUS_HandleTypeDef *hsmbus); +/** + * @} + */ + +/** @addtogroup SMBUS_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @{ + */ +/******* SMBUS IRQHandler and Callbacks used in non blocking modes (Interrupt) */ +void HAL_SMBUS_EV_IRQHandler(SMBUS_HandleTypeDef *hsmbus); +void HAL_SMBUS_ER_IRQHandler(SMBUS_HandleTypeDef *hsmbus); +void HAL_SMBUS_MasterTxCpltCallback(SMBUS_HandleTypeDef *hsmbus); +void HAL_SMBUS_MasterRxCpltCallback(SMBUS_HandleTypeDef *hsmbus); +void HAL_SMBUS_SlaveTxCpltCallback(SMBUS_HandleTypeDef *hsmbus); +void HAL_SMBUS_SlaveRxCpltCallback(SMBUS_HandleTypeDef *hsmbus); +void HAL_SMBUS_AddrCallback(SMBUS_HandleTypeDef *hsmbus, uint8_t TransferDirection, uint16_t AddrMatchCode); +void HAL_SMBUS_ListenCpltCallback(SMBUS_HandleTypeDef *hsmbus); +void HAL_SMBUS_ErrorCallback(SMBUS_HandleTypeDef *hsmbus); + +/** + * @} + */ + +/** @addtogroup SMBUS_Exported_Functions_Group3 Peripheral State and Errors functions + * @{ + */ + +/* Peripheral State and Errors functions **************************************************/ +uint32_t HAL_SMBUS_GetState(const SMBUS_HandleTypeDef *hsmbus); +uint32_t HAL_SMBUS_GetError(const SMBUS_HandleTypeDef *hsmbus); + +/** + * @} + */ + +/** + * @} + */ + +/* Private Functions ---------------------------------------------------------*/ +/** @defgroup SMBUS_Private_Functions SMBUS Private Functions + * @{ + */ +/* Private functions are defined in stm32h5xx_hal_smbus.c file */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* STM32H5xx_HAL_SMBUS_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_smbus_ex.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_smbus_ex.h new file mode 100644 index 0000000000..278666d3f7 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_smbus_ex.h @@ -0,0 +1,133 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_smbus_ex.h + * @author MCD Application Team + * @brief Header file of SMBUS HAL Extended module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_SMBUS_EX_H +#define STM32H5xx_HAL_SMBUS_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup SMBUSEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup SMBUSEx_Exported_Constants SMBUS Extended Exported Constants + * @{ + */ + +/** @defgroup SMBUSEx_FastModePlus SMBUS Extended Fast Mode Plus + * @{ + */ +#define SMBUS_FASTMODEPLUS_ENABLE 0x00000000U /*!< Enable Fast Mode Plus */ +#define SMBUS_FASTMODEPLUS_DISABLE 0x00000001U /*!< Disable Fast Mode Plus */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup SMBUSEx_Exported_Macros SMBUS Extended Exported Macros + * @{ + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup SMBUSEx_Exported_Functions SMBUS Extended Exported Functions + * @{ + */ + +/** @addtogroup SMBUSEx_Exported_Functions_Group2 WakeUp Mode Functions + * @{ + */ +/* Peripheral Control functions ************************************************/ +HAL_StatusTypeDef HAL_SMBUSEx_EnableWakeUp(SMBUS_HandleTypeDef *hsmbus); +HAL_StatusTypeDef HAL_SMBUSEx_DisableWakeUp(SMBUS_HandleTypeDef *hsmbus); +/** + * @} + */ + +/** @addtogroup SMBUSEx_Exported_Functions_Group3 Fast Mode Plus Functions + * @{ + */ +HAL_StatusTypeDef HAL_SMBUSEx_ConfigFastModePlus(SMBUS_HandleTypeDef *hsmbus, uint32_t FastModePlus); +/** + * @} + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup SMBUSEx_Private_Constants SMBUS Extended Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup SMBUSEx_Private_Macro SMBUS Extended Private Macros + * @{ + */ +#define IS_SMBUS_FASTMODEPLUS(__CONFIG__) (((__CONFIG__) == (SMBUS_FASTMODEPLUS_ENABLE)) || \ + ((__CONFIG__) == (SMBUS_FASTMODEPLUS_DISABLE))) +/** + * @} + */ + +/* Private Functions ---------------------------------------------------------*/ +/** @defgroup SMBUSEx_Private_Functions SMBUS Extended Private Functions + * @{ + */ +/* Private functions are defined in stm32h5xx_hal_smbus_ex.c file */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_SMBUS_EX_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_spi.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_spi.h new file mode 100644 index 0000000000..15bf52d9fc --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_spi.h @@ -0,0 +1,1136 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_spi.h + * @author MCD Application Team + * @brief Header file of SPI HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_SPI_H +#define STM32H5xx_HAL_SPI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup SPI + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup SPI_Exported_Types SPI Exported Types + * @{ + */ + +/** + * @brief SPI Configuration Structure definition + */ +typedef struct +{ + uint32_t Mode; /*!< Specifies the SPI operating mode. + This parameter can be a value of @ref SPI_Mode */ + + uint32_t Direction; /*!< Specifies the SPI bidirectional mode state. + This parameter can be a value of @ref SPI_Direction */ + + uint32_t DataSize; /*!< Specifies the SPI data size. + This parameter can be a value of @ref SPI_Data_Size */ + + uint32_t CLKPolarity; /*!< Specifies the serial clock steady state. + This parameter can be a value of @ref SPI_Clock_Polarity */ + + uint32_t CLKPhase; /*!< Specifies the clock active edge for the bit capture. + This parameter can be a value of @ref SPI_Clock_Phase */ + + uint32_t NSS; /*!< Specifies whether the NSS signal is managed by + hardware (NSS pin) or by software using the SSI bit. + This parameter can be a value of + @ref SPI_Slave_Select_Management */ + + uint32_t BaudRatePrescaler; /*!< Specifies the Baud Rate prescaler value which will be + used to configure the transmit and receive SCK clock. + This parameter can be a value of @ref SPI_BaudRate_Prescaler + @note The communication clock is derived from the master + clock. The slave clock does not need to be set. */ + + uint32_t FirstBit; /*!< Specifies whether data transfers start from MSB or LSB bit. + This parameter can be a value of @ref SPI_MSB_LSB_Transmission */ + + uint32_t TIMode; /*!< Specifies if the TI mode is enabled or not. + This parameter can be a value of @ref SPI_TI_Mode */ + + uint32_t CRCCalculation; /*!< Specifies if the CRC calculation is enabled or not. + This parameter can be a value of @ref SPI_CRC_Calculation */ + + uint32_t CRCPolynomial; /*!< Specifies the polynomial used for the CRC calculation. + This parameter must be an odd number between + Min_Data = 0 and Max_Data = 65535 */ + + uint32_t CRCLength; /*!< Specifies the CRC Length used for the CRC calculation. + This parameter can be a value of @ref SPI_CRC_length */ + + uint32_t NSSPMode; /*!< Specifies whether the NSSP signal is enabled or not . + This parameter can be a value of @ref SPI_NSSP_Mode + This mode is activated by the SSOM bit in the SPIx_CR2 register + and it takes effect only if the SPI interface is configured + as Motorola SPI master (FRF=0). */ + + uint32_t NSSPolarity; /*!< Specifies which level of SS input/output external signal + (present on SS pin) is considered as active one. + This parameter can be a value of @ref SPI_NSS_Polarity */ + + uint32_t FifoThreshold; /*!< Specifies the FIFO threshold level. + This parameter can be a value of @ref SPI_Fifo_Threshold */ + + uint32_t TxCRCInitializationPattern; /*!< Specifies the transmitter CRC initialization Pattern used for + the CRC calculation. This parameter can be a value of + @ref SPI_CRC_Calculation_Initialization_Pattern */ + + uint32_t RxCRCInitializationPattern; /*!< Specifies the receiver CRC initialization Pattern used for + the CRC calculation. This parameter can be a value of + @ref SPI_CRC_Calculation_Initialization_Pattern */ + + uint32_t MasterSSIdleness; /*!< Specifies an extra delay, expressed in number of SPI clock cycle + periods, inserted additionally between active edge of SS + and first data transaction start in master mode. + This parameter can be a value of @ref SPI_Master_SS_Idleness */ + + uint32_t MasterInterDataIdleness; /*!< Specifies minimum time delay (expressed in SPI clock cycles periods) + inserted between two consecutive data frames in master mode. + This parameter can be a value of + @ref SPI_Master_InterData_Idleness */ + + uint32_t MasterReceiverAutoSusp; /*!< Control continuous SPI transfer in master receiver mode + and automatic management in order to avoid overrun condition. + This parameter can be a value of @ref SPI_Master_RX_AutoSuspend*/ + + uint32_t MasterKeepIOState; /*!< Control of Alternate function GPIOs state + This parameter can be a value of @ref SPI_Master_Keep_IO_State */ + + uint32_t IOSwap; /*!< Invert MISO/MOSI alternate functions + This parameter can be a value of @ref SPI_IO_Swap */ + + uint32_t ReadyMasterManagement; /*!< Specifies if RDY Signal is managed internally or not. + This parameter can be a value of @ref SPI_RDY_Master_Management */ + + uint32_t ReadyPolarity; /*!< Specifies which level of RDY Signal input (present on RDY pin) + is considered as active one. + This parameter can be a value of @ref SPI_RDY_Polarity */ +} SPI_InitTypeDef; + +/** + * @brief HAL SPI State structure definition + */ +typedef enum +{ + HAL_SPI_STATE_RESET = 0x00UL, /*!< Peripheral not Initialized */ + HAL_SPI_STATE_READY = 0x01UL, /*!< Peripheral Initialized and ready for use */ + HAL_SPI_STATE_BUSY = 0x02UL, /*!< an internal process is ongoing */ + HAL_SPI_STATE_BUSY_TX = 0x03UL, /*!< Data Transmission process is ongoing */ + HAL_SPI_STATE_BUSY_RX = 0x04UL, /*!< Data Reception process is ongoing */ + HAL_SPI_STATE_BUSY_TX_RX = 0x05UL, /*!< Data Transmission and Reception process is ongoing */ + HAL_SPI_STATE_ERROR = 0x06UL, /*!< SPI error state */ + HAL_SPI_STATE_ABORT = 0x07UL /*!< SPI abort is ongoing */ +} HAL_SPI_StateTypeDef; + + +/** + * @brief SPI handle Structure definition + */ +typedef struct __SPI_HandleTypeDef +{ + SPI_TypeDef *Instance; /*!< SPI registers base address */ + + SPI_InitTypeDef Init; /*!< SPI communication parameters */ + + const uint8_t *pTxBuffPtr; /*!< Pointer to SPI Tx transfer Buffer */ + + uint16_t TxXferSize; /*!< SPI Tx Transfer size */ + + __IO uint16_t TxXferCount; /*!< SPI Tx Transfer Counter */ + + uint8_t *pRxBuffPtr; /*!< Pointer to SPI Rx transfer Buffer */ + + uint16_t RxXferSize; /*!< SPI Rx Transfer size */ + + __IO uint16_t RxXferCount; /*!< SPI Rx Transfer Counter */ + + uint32_t CRCSize; /*!< SPI CRC size used for the transfer */ + + void (*RxISR)(struct __SPI_HandleTypeDef *hspi); /*!< function pointer on Rx ISR */ + + void (*TxISR)(struct __SPI_HandleTypeDef *hspi); /*!< function pointer on Tx ISR */ + +#if defined(HAL_DMA_MODULE_ENABLED) + DMA_HandleTypeDef *hdmatx; /*!< SPI Tx DMA Handle parameters */ + + DMA_HandleTypeDef *hdmarx; /*!< SPI Rx DMA Handle parameters */ +#endif /* HAL_DMA_MODULE_ENABLED */ + + HAL_LockTypeDef Lock; /*!< Locking object */ + + __IO HAL_SPI_StateTypeDef State; /*!< SPI communication state */ + + __IO uint32_t ErrorCode; /*!< SPI Error code */ + + +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) + void (* TxCpltCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Tx Completed callback */ + void (* RxCpltCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Rx Completed callback */ + void (* TxRxCpltCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI TxRx Completed callback */ + void (* TxHalfCpltCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Tx Half Completed callback */ + void (* RxHalfCpltCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Rx Half Completed callback */ + void (* TxRxHalfCpltCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI TxRx Half Completed callback */ + void (* ErrorCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Error callback */ + void (* AbortCpltCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Abort callback */ + void (* SuspendCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Suspend callback */ + void (* MspInitCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Msp Init callback */ + void (* MspDeInitCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Msp DeInit callback */ + +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ +} SPI_HandleTypeDef; + +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) +/** + * @brief HAL SPI Callback ID enumeration definition + */ +typedef enum +{ + HAL_SPI_TX_COMPLETE_CB_ID = 0x00UL, /*!< SPI Tx Completed callback ID */ + HAL_SPI_RX_COMPLETE_CB_ID = 0x01UL, /*!< SPI Rx Completed callback ID */ + HAL_SPI_TX_RX_COMPLETE_CB_ID = 0x02UL, /*!< SPI TxRx Completed callback ID */ + HAL_SPI_TX_HALF_COMPLETE_CB_ID = 0x03UL, /*!< SPI Tx Half Completed callback ID */ + HAL_SPI_RX_HALF_COMPLETE_CB_ID = 0x04UL, /*!< SPI Rx Half Completed callback ID */ + HAL_SPI_TX_RX_HALF_COMPLETE_CB_ID = 0x05UL, /*!< SPI TxRx Half Completed callback ID */ + HAL_SPI_ERROR_CB_ID = 0x06UL, /*!< SPI Error callback ID */ + HAL_SPI_ABORT_CB_ID = 0x07UL, /*!< SPI Abort callback ID */ + HAL_SPI_SUSPEND_CB_ID = 0x08UL, /*!< SPI Suspend callback ID */ + HAL_SPI_MSPINIT_CB_ID = 0x09UL, /*!< SPI Msp Init callback ID */ + HAL_SPI_MSPDEINIT_CB_ID = 0x0AUL /*!< SPI Msp DeInit callback ID */ + +} HAL_SPI_CallbackIDTypeDef; + +/** + * @brief HAL SPI Callback pointer definition + */ +typedef void (*pSPI_CallbackTypeDef)(SPI_HandleTypeDef *hspi); /*!< pointer to an SPI callback function */ + +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup SPI_Exported_Constants SPI Exported Constants + * @{ + */ + +/** @defgroup SPI_FIFO_Type SPI FIFO Type + * @{ + */ +#define SPI_LOWEND_FIFO_SIZE 8UL +#define SPI_HIGHEND_FIFO_SIZE 16UL +/** + * @} + */ + +/** @defgroup SPI_Error_Code SPI Error Codes + * @{ + */ +#define HAL_SPI_ERROR_NONE (0x00000000UL) /*!< No error */ +#define HAL_SPI_ERROR_MODF (0x00000001UL) /*!< MODF error */ +#define HAL_SPI_ERROR_CRC (0x00000002UL) /*!< CRC error */ +#define HAL_SPI_ERROR_OVR (0x00000004UL) /*!< OVR error */ +#define HAL_SPI_ERROR_FRE (0x00000008UL) /*!< FRE error */ +#if defined(HAL_DMA_MODULE_ENABLED) +#define HAL_SPI_ERROR_DMA (0x00000010UL) /*!< DMA transfer error */ +#endif /* HAL_DMA_MODULE_ENABLED */ +#define HAL_SPI_ERROR_FLAG (0x00000020UL) /*!< Error on RXP/TXP/DXP/FTLVL/FRLVL Flag */ +#define HAL_SPI_ERROR_ABORT (0x00000040UL) /*!< Error during SPI Abort procedure */ +#define HAL_SPI_ERROR_UDR (0x00000080UL) /*!< Underrun error */ +#define HAL_SPI_ERROR_TIMEOUT (0x00000100UL) /*!< Timeout error */ +#define HAL_SPI_ERROR_UNKNOW (0x00000200UL) /*!< Unknown error */ +#define HAL_SPI_ERROR_NOT_SUPPORTED (0x00000400UL) /*!< Requested operation not supported */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) +#define HAL_SPI_ERROR_INVALID_CALLBACK (0x00001000UL) /*!< Invalid Callback error */ +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @defgroup SPI_Mode SPI Mode + * @{ + */ +#define SPI_MODE_SLAVE (0x00000000UL) +#define SPI_MODE_MASTER SPI_CFG2_MASTER +/** + * @} + */ + +/** @defgroup SPI_Direction SPI Direction Mode + * @{ + */ +#define SPI_DIRECTION_2LINES (0x00000000UL) +#define SPI_DIRECTION_2LINES_TXONLY SPI_CFG2_COMM_0 +#define SPI_DIRECTION_2LINES_RXONLY SPI_CFG2_COMM_1 +#define SPI_DIRECTION_1LINE SPI_CFG2_COMM +/** + * @} + */ + +/** @defgroup SPI_Data_Size SPI Data Size + * @{ + */ +#define SPI_DATASIZE_4BIT (0x00000003UL) +#define SPI_DATASIZE_5BIT (0x00000004UL) +#define SPI_DATASIZE_6BIT (0x00000005UL) +#define SPI_DATASIZE_7BIT (0x00000006UL) +#define SPI_DATASIZE_8BIT (0x00000007UL) +#define SPI_DATASIZE_9BIT (0x00000008UL) +#define SPI_DATASIZE_10BIT (0x00000009UL) +#define SPI_DATASIZE_11BIT (0x0000000AUL) +#define SPI_DATASIZE_12BIT (0x0000000BUL) +#define SPI_DATASIZE_13BIT (0x0000000CUL) +#define SPI_DATASIZE_14BIT (0x0000000DUL) +#define SPI_DATASIZE_15BIT (0x0000000EUL) +#define SPI_DATASIZE_16BIT (0x0000000FUL) +#define SPI_DATASIZE_17BIT (0x00000010UL) +#define SPI_DATASIZE_18BIT (0x00000011UL) +#define SPI_DATASIZE_19BIT (0x00000012UL) +#define SPI_DATASIZE_20BIT (0x00000013UL) +#define SPI_DATASIZE_21BIT (0x00000014UL) +#define SPI_DATASIZE_22BIT (0x00000015UL) +#define SPI_DATASIZE_23BIT (0x00000016UL) +#define SPI_DATASIZE_24BIT (0x00000017UL) +#define SPI_DATASIZE_25BIT (0x00000018UL) +#define SPI_DATASIZE_26BIT (0x00000019UL) +#define SPI_DATASIZE_27BIT (0x0000001AUL) +#define SPI_DATASIZE_28BIT (0x0000001BUL) +#define SPI_DATASIZE_29BIT (0x0000001CUL) +#define SPI_DATASIZE_30BIT (0x0000001DUL) +#define SPI_DATASIZE_31BIT (0x0000001EUL) +#define SPI_DATASIZE_32BIT (0x0000001FUL) +/** + * @} + */ + +/** @defgroup SPI_Clock_Polarity SPI Clock Polarity + * @{ + */ +#define SPI_POLARITY_LOW (0x00000000UL) +#define SPI_POLARITY_HIGH SPI_CFG2_CPOL +/** + * @} + */ + +/** @defgroup SPI_Clock_Phase SPI Clock Phase + * @{ + */ +#define SPI_PHASE_1EDGE (0x00000000UL) +#define SPI_PHASE_2EDGE SPI_CFG2_CPHA +/** + * @} + */ + +/** @defgroup SPI_Slave_Select_Management SPI Slave Select Management + * @{ + */ +#define SPI_NSS_SOFT SPI_CFG2_SSM +#define SPI_NSS_HARD_INPUT (0x00000000UL) +#define SPI_NSS_HARD_OUTPUT SPI_CFG2_SSOE +/** + * @} + */ + +/** @defgroup SPI_NSSP_Mode SPI NSS Pulse Mode + * @{ + */ +#define SPI_NSS_PULSE_DISABLE (0x00000000UL) +#define SPI_NSS_PULSE_ENABLE SPI_CFG2_SSOM +/** + * @} + */ + +/** @defgroup SPI_BaudRate_Prescaler SPI BaudRate Prescaler + * @{ + */ +#define SPI_BAUDRATEPRESCALER_BYPASS (0x80000000UL) +#define SPI_BAUDRATEPRESCALER_2 (0x00000000UL) +#define SPI_BAUDRATEPRESCALER_4 (0x10000000UL) +#define SPI_BAUDRATEPRESCALER_8 (0x20000000UL) +#define SPI_BAUDRATEPRESCALER_16 (0x30000000UL) +#define SPI_BAUDRATEPRESCALER_32 (0x40000000UL) +#define SPI_BAUDRATEPRESCALER_64 (0x50000000UL) +#define SPI_BAUDRATEPRESCALER_128 (0x60000000UL) +#define SPI_BAUDRATEPRESCALER_256 (0x70000000UL) +/** + * @} + */ + +/** @defgroup SPI_MSB_LSB_Transmission SPI MSB LSB Transmission + * @{ + */ +#define SPI_FIRSTBIT_MSB (0x00000000UL) +#define SPI_FIRSTBIT_LSB SPI_CFG2_LSBFRST +/** + * @} + */ + +/** @defgroup SPI_TI_Mode SPI TI Mode + * @{ + */ +#define SPI_TIMODE_DISABLE (0x00000000UL) +#define SPI_TIMODE_ENABLE SPI_CFG2_SP_0 +/** + * @} + */ + +/** @defgroup SPI_CRC_Calculation SPI CRC Calculation + * @{ + */ +#define SPI_CRCCALCULATION_DISABLE (0x00000000UL) +#define SPI_CRCCALCULATION_ENABLE SPI_CFG1_CRCEN +/** + * @} + */ + +/** @defgroup SPI_CRC_length SPI CRC Length + * @{ + */ +#define SPI_CRC_LENGTH_DATASIZE (0x00000000UL) +#define SPI_CRC_LENGTH_4BIT (0x00030000UL) +#define SPI_CRC_LENGTH_5BIT (0x00040000UL) +#define SPI_CRC_LENGTH_6BIT (0x00050000UL) +#define SPI_CRC_LENGTH_7BIT (0x00060000UL) +#define SPI_CRC_LENGTH_8BIT (0x00070000UL) +#define SPI_CRC_LENGTH_9BIT (0x00080000UL) +#define SPI_CRC_LENGTH_10BIT (0x00090000UL) +#define SPI_CRC_LENGTH_11BIT (0x000A0000UL) +#define SPI_CRC_LENGTH_12BIT (0x000B0000UL) +#define SPI_CRC_LENGTH_13BIT (0x000C0000UL) +#define SPI_CRC_LENGTH_14BIT (0x000D0000UL) +#define SPI_CRC_LENGTH_15BIT (0x000E0000UL) +#define SPI_CRC_LENGTH_16BIT (0x000F0000UL) +#define SPI_CRC_LENGTH_17BIT (0x00100000UL) +#define SPI_CRC_LENGTH_18BIT (0x00110000UL) +#define SPI_CRC_LENGTH_19BIT (0x00120000UL) +#define SPI_CRC_LENGTH_20BIT (0x00130000UL) +#define SPI_CRC_LENGTH_21BIT (0x00140000UL) +#define SPI_CRC_LENGTH_22BIT (0x00150000UL) +#define SPI_CRC_LENGTH_23BIT (0x00160000UL) +#define SPI_CRC_LENGTH_24BIT (0x00170000UL) +#define SPI_CRC_LENGTH_25BIT (0x00180000UL) +#define SPI_CRC_LENGTH_26BIT (0x00190000UL) +#define SPI_CRC_LENGTH_27BIT (0x001A0000UL) +#define SPI_CRC_LENGTH_28BIT (0x001B0000UL) +#define SPI_CRC_LENGTH_29BIT (0x001C0000UL) +#define SPI_CRC_LENGTH_30BIT (0x001D0000UL) +#define SPI_CRC_LENGTH_31BIT (0x001E0000UL) +#define SPI_CRC_LENGTH_32BIT (0x001F0000UL) +/** + * @} + */ + +/** @defgroup SPI_Fifo_Threshold SPI Fifo Threshold + * @{ + */ +#define SPI_FIFO_THRESHOLD_01DATA (0x00000000UL) +#define SPI_FIFO_THRESHOLD_02DATA (0x00000020UL) +#define SPI_FIFO_THRESHOLD_03DATA (0x00000040UL) +#define SPI_FIFO_THRESHOLD_04DATA (0x00000060UL) +#define SPI_FIFO_THRESHOLD_05DATA (0x00000080UL) +#define SPI_FIFO_THRESHOLD_06DATA (0x000000A0UL) +#define SPI_FIFO_THRESHOLD_07DATA (0x000000C0UL) +#define SPI_FIFO_THRESHOLD_08DATA (0x000000E0UL) +#define SPI_FIFO_THRESHOLD_09DATA (0x00000100UL) +#define SPI_FIFO_THRESHOLD_10DATA (0x00000120UL) +#define SPI_FIFO_THRESHOLD_11DATA (0x00000140UL) +#define SPI_FIFO_THRESHOLD_12DATA (0x00000160UL) +#define SPI_FIFO_THRESHOLD_13DATA (0x00000180UL) +#define SPI_FIFO_THRESHOLD_14DATA (0x000001A0UL) +#define SPI_FIFO_THRESHOLD_15DATA (0x000001C0UL) +#define SPI_FIFO_THRESHOLD_16DATA (0x000001E0UL) +/** + * @} + */ + +/** @defgroup SPI_CRC_Calculation_Initialization_Pattern SPI CRC Calculation Initialization Pattern + * @{ + */ +#define SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN (0x00000000UL) +#define SPI_CRC_INITIALIZATION_ALL_ONE_PATTERN (0x00000001UL) +/** + * @} + */ + +/** @defgroup SPI_NSS_Polarity SPI NSS Polarity + * @{ + */ +#define SPI_NSS_POLARITY_LOW (0x00000000UL) +#define SPI_NSS_POLARITY_HIGH SPI_CFG2_SSIOP +/** + * @} + */ + +/** @defgroup SPI_Master_Keep_IO_State Keep IO State + * @{ + */ +#define SPI_MASTER_KEEP_IO_STATE_DISABLE (0x00000000UL) +#define SPI_MASTER_KEEP_IO_STATE_ENABLE SPI_CFG2_AFCNTR +/** + * @} + */ + +/** @defgroup SPI_IO_Swap Control SPI IO Swap + * @{ + */ +#define SPI_IO_SWAP_DISABLE (0x00000000UL) +#define SPI_IO_SWAP_ENABLE SPI_CFG2_IOSWP +/** + * @} + */ + +/** @defgroup SPI_Master_SS_Idleness SPI Master SS Idleness + * @{ + */ +#define SPI_MASTER_SS_IDLENESS_00CYCLE (0x00000000UL) +#define SPI_MASTER_SS_IDLENESS_01CYCLE (0x00000001UL) +#define SPI_MASTER_SS_IDLENESS_02CYCLE (0x00000002UL) +#define SPI_MASTER_SS_IDLENESS_03CYCLE (0x00000003UL) +#define SPI_MASTER_SS_IDLENESS_04CYCLE (0x00000004UL) +#define SPI_MASTER_SS_IDLENESS_05CYCLE (0x00000005UL) +#define SPI_MASTER_SS_IDLENESS_06CYCLE (0x00000006UL) +#define SPI_MASTER_SS_IDLENESS_07CYCLE (0x00000007UL) +#define SPI_MASTER_SS_IDLENESS_08CYCLE (0x00000008UL) +#define SPI_MASTER_SS_IDLENESS_09CYCLE (0x00000009UL) +#define SPI_MASTER_SS_IDLENESS_10CYCLE (0x0000000AUL) +#define SPI_MASTER_SS_IDLENESS_11CYCLE (0x0000000BUL) +#define SPI_MASTER_SS_IDLENESS_12CYCLE (0x0000000CUL) +#define SPI_MASTER_SS_IDLENESS_13CYCLE (0x0000000DUL) +#define SPI_MASTER_SS_IDLENESS_14CYCLE (0x0000000EUL) +#define SPI_MASTER_SS_IDLENESS_15CYCLE (0x0000000FUL) +/** + * @} + */ + +/** @defgroup SPI_Master_InterData_Idleness SPI Master Inter-Data Idleness + * @{ + */ +#define SPI_MASTER_INTERDATA_IDLENESS_00CYCLE (0x00000000UL) +#define SPI_MASTER_INTERDATA_IDLENESS_01CYCLE (0x00000010UL) +#define SPI_MASTER_INTERDATA_IDLENESS_02CYCLE (0x00000020UL) +#define SPI_MASTER_INTERDATA_IDLENESS_03CYCLE (0x00000030UL) +#define SPI_MASTER_INTERDATA_IDLENESS_04CYCLE (0x00000040UL) +#define SPI_MASTER_INTERDATA_IDLENESS_05CYCLE (0x00000050UL) +#define SPI_MASTER_INTERDATA_IDLENESS_06CYCLE (0x00000060UL) +#define SPI_MASTER_INTERDATA_IDLENESS_07CYCLE (0x00000070UL) +#define SPI_MASTER_INTERDATA_IDLENESS_08CYCLE (0x00000080UL) +#define SPI_MASTER_INTERDATA_IDLENESS_09CYCLE (0x00000090UL) +#define SPI_MASTER_INTERDATA_IDLENESS_10CYCLE (0x000000A0UL) +#define SPI_MASTER_INTERDATA_IDLENESS_11CYCLE (0x000000B0UL) +#define SPI_MASTER_INTERDATA_IDLENESS_12CYCLE (0x000000C0UL) +#define SPI_MASTER_INTERDATA_IDLENESS_13CYCLE (0x000000D0UL) +#define SPI_MASTER_INTERDATA_IDLENESS_14CYCLE (0x000000E0UL) +#define SPI_MASTER_INTERDATA_IDLENESS_15CYCLE (0x000000F0UL) +/** + * @} + */ + +/** @defgroup SPI_Master_RX_AutoSuspend SPI Master Receiver AutoSuspend + * @{ + */ +#define SPI_MASTER_RX_AUTOSUSP_DISABLE (0x00000000UL) +#define SPI_MASTER_RX_AUTOSUSP_ENABLE SPI_CR1_MASRX +/** + * @} + */ + +/** @defgroup SPI_Underrun_Behaviour SPI Underrun Behavior + * @{ + */ +#define SPI_UNDERRUN_BEHAV_REGISTER_PATTERN (0x00000000UL) +#define SPI_UNDERRUN_BEHAV_LAST_RECEIVED SPI_CFG1_UDRCFG +/** + * @} + */ + +/** @defgroup SPI_RDY_Master_Management SPI RDY Signal Input Master Management + * @{ + */ +#define SPI_RDY_MASTER_MANAGEMENT_INTERNALLY (0x00000000UL) +#define SPI_RDY_MASTER_MANAGEMENT_EXTERNALLY SPI_CFG2_RDIOM +/** + * @} + */ + +/** @defgroup SPI_RDY_Polarity SPI RDY Signal Input/Output Polarity + * @{ + */ +#define SPI_RDY_POLARITY_HIGH (0x00000000UL) +#define SPI_RDY_POLARITY_LOW SPI_CFG2_RDIOP +/** + * @} + */ + +/** @defgroup SPI_Interrupt_definition SPI Interrupt Definition + * @{ + */ +#define SPI_IT_RXP SPI_IER_RXPIE +#define SPI_IT_TXP SPI_IER_TXPIE +#define SPI_IT_DXP SPI_IER_DXPIE +#define SPI_IT_EOT SPI_IER_EOTIE +#define SPI_IT_TXTF SPI_IER_TXTFIE +#define SPI_IT_UDR SPI_IER_UDRIE +#define SPI_IT_OVR SPI_IER_OVRIE +#define SPI_IT_CRCERR SPI_IER_CRCEIE +#define SPI_IT_FRE SPI_IER_TIFREIE +#define SPI_IT_MODF SPI_IER_MODFIE +#define SPI_IT_ERR (SPI_IT_UDR | SPI_IT_OVR | SPI_IT_FRE | SPI_IT_MODF | SPI_IT_CRCERR) +/** + * @} + */ + +/** @defgroup SPI_Flags_definition SPI Flags Definition + * @{ + */ +#define SPI_FLAG_RXP SPI_SR_RXP /* SPI status flag : Rx-Packet available flag */ +#define SPI_FLAG_TXP SPI_SR_TXP /* SPI status flag : Tx-Packet space available flag */ +#define SPI_FLAG_DXP SPI_SR_DXP /* SPI status flag : Duplex Packet flag */ +#define SPI_FLAG_EOT SPI_SR_EOT /* SPI status flag : End of transfer flag */ +#define SPI_FLAG_TXTF SPI_SR_TXTF /* SPI status flag : Transmission Transfer Filled flag */ +#define SPI_FLAG_UDR SPI_SR_UDR /* SPI Error flag : Underrun flag */ +#define SPI_FLAG_OVR SPI_SR_OVR /* SPI Error flag : Overrun flag */ +#define SPI_FLAG_CRCERR SPI_SR_CRCE /* SPI Error flag : CRC error flag */ +#define SPI_FLAG_FRE SPI_SR_TIFRE /* SPI Error flag : TI mode frame format error flag */ +#define SPI_FLAG_MODF SPI_SR_MODF /* SPI Error flag : Mode fault flag */ +#define SPI_FLAG_SUSP SPI_SR_SUSP /* SPI status flag : Transfer suspend complete flag */ +#define SPI_FLAG_TXC SPI_SR_TXC /* SPI status flag : TxFIFO transmission complete flag */ +#define SPI_FLAG_FRLVL SPI_SR_RXPLVL /* SPI status flag : Fifo reception level flag */ +#define SPI_FLAG_RXWNE SPI_SR_RXWNE /* SPI status flag : RxFIFO word not empty flag */ +/** + * @} + */ + +/** @defgroup SPI_reception_fifo_status_level SPI Reception FIFO Status Level + * @{ + */ +#define SPI_RX_FIFO_0PACKET (0x00000000UL) /* 0 or multiple of 4 packets available in the RxFIFO */ +#define SPI_RX_FIFO_1PACKET (SPI_SR_RXPLVL_0) +#define SPI_RX_FIFO_2PACKET (SPI_SR_RXPLVL_1) +#define SPI_RX_FIFO_3PACKET (SPI_SR_RXPLVL_1 | SPI_SR_RXPLVL_0) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup SPI_Exported_Macros SPI Exported Macros + * @{ + */ + +/** @brief Reset SPI handle state. + * @param __HANDLE__: specifies the SPI Handle. + * This parameter can be SPI where x: 1, 2, 3, 4, 5 or 6 to select the SPI peripheral. + * @retval None + */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) +#define __HAL_SPI_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->State = HAL_SPI_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_SPI_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_SPI_STATE_RESET) +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + +/** @brief Enable the specified SPI interrupts. + * @param __HANDLE__: specifies the SPI Handle. + * This parameter can be SPI where x: 1, 2, 3, 4, 5 or 6 to select the SPI peripheral. + * @param __INTERRUPT__: specifies the interrupt source to enable or disable. + * This parameter can be one of the following values: + * @arg SPI_IT_RXP : Rx-Packet available interrupt + * @arg SPI_IT_TXP : Tx-Packet space available interrupt + * @arg SPI_IT_DXP : Duplex Packet interrupt + * @arg SPI_IT_EOT : End of transfer interrupt + * @arg SPI_IT_TXTF : Transmission Transfer Filled interrupt + * @arg SPI_IT_UDR : Underrun interrupt + * @arg SPI_IT_OVR : Overrun interrupt + * @arg SPI_IT_CRCERR : CRC error interrupt + * @arg SPI_IT_FRE : TI mode frame format error interrupt + * @arg SPI_IT_MODF : Mode fault interrupt + * @arg SPI_IT_ERR : Error interrupt + * @retval None + */ +#define __HAL_SPI_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IER |= (__INTERRUPT__)) + +/** @brief Disable the specified SPI interrupts. + * @param __HANDLE__: specifies the SPI Handle. + * This parameter can be SPI where x: 1, 2, 3, 4, 5 or 6 to select the SPI peripheral. + * @param __INTERRUPT__: specifies the interrupt source to enable or disable. + * This parameter can be one of the following values: + * @arg SPI_IT_RXP : Rx-Packet available interrupt + * @arg SPI_IT_TXP : Tx-Packet space available interrupt + * @arg SPI_IT_DXP : Duplex Packet interrupt + * @arg SPI_IT_EOT : End of transfer interrupt + * @arg SPI_IT_TXTF : Transmission Transfer Filled interrupt + * @arg SPI_IT_UDR : Underrun interrupt + * @arg SPI_IT_OVR : Overrun interrupt + * @arg SPI_IT_CRCERR : CRC error interrupt + * @arg SPI_IT_FRE : TI mode frame format error interrupt + * @arg SPI_IT_MODF : Mode fault interrupt + * @arg SPI_IT_ERR : Error interrupt + * @retval None + */ +#define __HAL_SPI_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IER &= (~(__INTERRUPT__))) + +/** @brief Check whether the specified SPI interrupt source is enabled or not. + * @param __HANDLE__: specifies the SPI Handle. + * This parameter can be SPI where x: 1, 2, 3, 4, 5 or 6 to select the SPI peripheral. + * @param __INTERRUPT__: specifies the SPI interrupt source to check. + * This parameter can be one of the following values: + * @arg SPI_IT_RXP : Rx-Packet available interrupt + * @arg SPI_IT_TXP : Tx-Packet space available interrupt + * @arg SPI_IT_DXP : Duplex Packet interrupt + * @arg SPI_IT_EOT : End of transfer interrupt + * @arg SPI_IT_TXTF : Transmission Transfer Filled interrupt + * @arg SPI_IT_UDR : Underrun interrupt + * @arg SPI_IT_OVR : Overrun interrupt + * @arg SPI_IT_CRCERR : CRC error interrupt + * @arg SPI_IT_FRE : TI mode frame format error interrupt + * @arg SPI_IT_MODF : Mode fault interrupt + * @arg SPI_IT_ERR : Error interrupt + * @retval The new state of __IT__ (TRUE or FALSE). + */ +#define __HAL_SPI_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->IER & \ + (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) + +/** @brief Check whether the specified SPI flag is set or not. + * @param __HANDLE__: specifies the SPI Handle. + * This parameter can be SPI where x: 1, 2, 3, 4, 5 or 6 to select the SPI peripheral. + * @param __FLAG__: specifies the flag to check. + * This parameter can be one of the following values: + * @arg SPI_FLAG_RXP : Rx-Packet available flag + * @arg SPI_FLAG_TXP : Tx-Packet space available flag + * @arg SPI_FLAG_DXP : Duplex Packet flag + * @arg SPI_FLAG_EOT : End of transfer flag + * @arg SPI_FLAG_TXTF : Transmission Transfer Filled flag + * @arg SPI_FLAG_UDR : Underrun flag + * @arg SPI_FLAG_OVR : Overrun flag + * @arg SPI_FLAG_CRCERR : CRC error flag + * @arg SPI_FLAG_FRE : TI mode frame format error flag + * @arg SPI_FLAG_MODF : Mode fault flag + * @arg SPI_FLAG_SUSP : Transfer suspend complete flag + * @arg SPI_FLAG_TXC : TxFIFO transmission complete flag + * @arg SPI_FLAG_FRLVL : Fifo reception level flag + * @arg SPI_FLAG_RXWNE : RxFIFO word not empty flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_SPI_GET_FLAG(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->SR) & (__FLAG__)) == (__FLAG__)) + +/** @brief Clear the SPI CRCERR pending flag. + * @param __HANDLE__: specifies the SPI Handle. + * @retval None + */ +#define __HAL_SPI_CLEAR_CRCERRFLAG(__HANDLE__) SET_BIT((__HANDLE__)->Instance->IFCR , SPI_IFCR_CRCEC) + +/** @brief Clear the SPI MODF pending flag. + * @param __HANDLE__: specifies the SPI Handle. + * @retval None + */ +#define __HAL_SPI_CLEAR_MODFFLAG(__HANDLE__) SET_BIT((__HANDLE__)->Instance->IFCR , (uint32_t)(SPI_IFCR_MODFC)); + +/** @brief Clear the SPI OVR pending flag. + * @param __HANDLE__: specifies the SPI Handle. + * @retval None + */ +#define __HAL_SPI_CLEAR_OVRFLAG(__HANDLE__) SET_BIT((__HANDLE__)->Instance->IFCR , SPI_IFCR_OVRC) + +/** @brief Clear the SPI FRE pending flag. + * @param __HANDLE__: specifies the SPI Handle. + * @retval None + */ +#define __HAL_SPI_CLEAR_FREFLAG(__HANDLE__) SET_BIT((__HANDLE__)->Instance->IFCR , SPI_IFCR_TIFREC) + +/** @brief Clear the SPI UDR pending flag. + * @param __HANDLE__: specifies the SPI Handle. + * @retval None + */ +#define __HAL_SPI_CLEAR_UDRFLAG(__HANDLE__) SET_BIT((__HANDLE__)->Instance->IFCR , SPI_IFCR_UDRC) + +/** @brief Clear the SPI EOT pending flag. + * @param __HANDLE__: specifies the SPI Handle. + * @retval None + */ +#define __HAL_SPI_CLEAR_EOTFLAG(__HANDLE__) SET_BIT((__HANDLE__)->Instance->IFCR , SPI_IFCR_EOTC) + +/** @brief Clear the SPI UDR pending flag. + * @param __HANDLE__: specifies the SPI Handle. + * @retval None + */ +#define __HAL_SPI_CLEAR_TXTFFLAG(__HANDLE__) SET_BIT((__HANDLE__)->Instance->IFCR , SPI_IFCR_TXTFC) + +/** @brief Clear the SPI SUSP pending flag. + * @param __HANDLE__: specifies the SPI Handle. + * @retval None + */ +#define __HAL_SPI_CLEAR_SUSPFLAG(__HANDLE__) SET_BIT((__HANDLE__)->Instance->IFCR , SPI_IFCR_SUSPC) + +/** @brief Enable the SPI peripheral. + * @param __HANDLE__: specifies the SPI Handle. + * @retval None + */ +#define __HAL_SPI_ENABLE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CR1 , SPI_CR1_SPE) + +/** @brief Disable the SPI peripheral. + * @param __HANDLE__: specifies the SPI Handle. + * @retval None + */ +#define __HAL_SPI_DISABLE(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->CR1 , SPI_CR1_SPE) +/** + * @} + */ + + +/* Include SPI HAL Extension module */ +#include "stm32h5xx_hal_spi_ex.h" + + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup SPI_Exported_Functions + * @{ + */ + +/** @addtogroup SPI_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ +/* Initialization/de-initialization functions ********************************/ +HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi); +HAL_StatusTypeDef HAL_SPI_DeInit(SPI_HandleTypeDef *hspi); +void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi); +void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi); + +/* Callbacks Register/UnRegister functions ***********************************/ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) +HAL_StatusTypeDef HAL_SPI_RegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID, + pSPI_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_SPI_UnRegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @addtogroup SPI_Exported_Functions_Group2 IO operation functions + * @{ + */ +/* I/O operation functions ***************************************************/ +HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData, + uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData, + uint16_t Size); + +#if defined(HAL_DMA_MODULE_ENABLED) +HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData, + uint16_t Size); +#endif /* HAL_DMA_MODULE_ENABLED */ + + +#if defined(HAL_DMA_MODULE_ENABLED) +HAL_StatusTypeDef HAL_SPI_DMAPause(SPI_HandleTypeDef *hspi); +HAL_StatusTypeDef HAL_SPI_DMAResume(SPI_HandleTypeDef *hspi); +HAL_StatusTypeDef HAL_SPI_DMAStop(SPI_HandleTypeDef *hspi); +#endif /* HAL_DMA_MODULE_ENABLED */ + +/* Transfer Abort functions */ +HAL_StatusTypeDef HAL_SPI_Abort(SPI_HandleTypeDef *hspi); +HAL_StatusTypeDef HAL_SPI_Abort_IT(SPI_HandleTypeDef *hspi); + +void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi); +void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi); +void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi); +void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi); +void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi); +void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi); +void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi); +void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi); +void HAL_SPI_AbortCpltCallback(SPI_HandleTypeDef *hspi); +void HAL_SPI_SuspendCallback(SPI_HandleTypeDef *hspi); +/** + * @} + */ + +/** @addtogroup SPI_Exported_Functions_Group3 Peripheral State and Errors functions + * @{ + */ + +/* Peripheral State and Error functions ***************************************/ +HAL_SPI_StateTypeDef HAL_SPI_GetState(const SPI_HandleTypeDef *hspi); +uint32_t HAL_SPI_GetError(const SPI_HandleTypeDef *hspi); +/** + * @} + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup SPI_Private_Macros SPI Private Macros + * @{ + */ + +/** @brief Set the SPI transmit-only mode in 1Line configuration. + * @param __HANDLE__: specifies the SPI Handle. + * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. + * @retval None + */ +#define SPI_1LINE_TX(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_HDDIR) + +/** @brief Set the SPI receive-only mode in 1Line configuration. + * @param __HANDLE__: specifies the SPI Handle. + * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. + * @retval None + */ +#define SPI_1LINE_RX(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_HDDIR) + +/** @brief Set the SPI transmit-only mode in 2Lines configuration. + * @param __HANDLE__: specifies the SPI Handle. + * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. + * @retval None + */ +#define SPI_2LINES_TX(__HANDLE__) MODIFY_REG((__HANDLE__)->Instance->CFG2, SPI_CFG2_COMM, SPI_CFG2_COMM_0) + +/** @brief Set the SPI receive-only mode in 2Lines configuration. + * @param __HANDLE__: specifies the SPI Handle. + * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. + * @retval None + */ +#define SPI_2LINES_RX(__HANDLE__) MODIFY_REG((__HANDLE__)->Instance->CFG2, SPI_CFG2_COMM, SPI_CFG2_COMM_1) + +/** @brief Set the SPI Transmit-Receive mode in 2Lines configuration. + * @param __HANDLE__: specifies the SPI Handle. + * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. + * @retval None + */ +#define SPI_2LINES(__HANDLE__) MODIFY_REG((__HANDLE__)->Instance->CFG2, SPI_CFG2_COMM, 0x00000000UL) + +#define IS_SPI_MODE(MODE) (((MODE) == SPI_MODE_SLAVE) || \ + ((MODE) == SPI_MODE_MASTER)) + +#define IS_SPI_DIRECTION(MODE) (((MODE) == SPI_DIRECTION_2LINES) || \ + ((MODE) == SPI_DIRECTION_2LINES_RXONLY) || \ + ((MODE) == SPI_DIRECTION_1LINE) || \ + ((MODE) == SPI_DIRECTION_2LINES_TXONLY)) + +#define IS_SPI_DIRECTION_2LINES(MODE) ((MODE) == SPI_DIRECTION_2LINES) + +#define IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_TXONLY(MODE) (((MODE) == SPI_DIRECTION_2LINES)|| \ + ((MODE) == SPI_DIRECTION_1LINE) || \ + ((MODE) == SPI_DIRECTION_2LINES_TXONLY)) + +#define IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_RXONLY(MODE) (((MODE) == SPI_DIRECTION_2LINES)|| \ + ((MODE) == SPI_DIRECTION_1LINE) || \ + ((MODE) == SPI_DIRECTION_2LINES_RXONLY)) + +#define IS_SPI_DATASIZE(DATASIZE) (((DATASIZE) == SPI_DATASIZE_32BIT) || \ + ((DATASIZE) == SPI_DATASIZE_31BIT) || \ + ((DATASIZE) == SPI_DATASIZE_30BIT) || \ + ((DATASIZE) == SPI_DATASIZE_29BIT) || \ + ((DATASIZE) == SPI_DATASIZE_28BIT) || \ + ((DATASIZE) == SPI_DATASIZE_27BIT) || \ + ((DATASIZE) == SPI_DATASIZE_26BIT) || \ + ((DATASIZE) == SPI_DATASIZE_25BIT) || \ + ((DATASIZE) == SPI_DATASIZE_24BIT) || \ + ((DATASIZE) == SPI_DATASIZE_23BIT) || \ + ((DATASIZE) == SPI_DATASIZE_22BIT) || \ + ((DATASIZE) == SPI_DATASIZE_21BIT) || \ + ((DATASIZE) == SPI_DATASIZE_20BIT) || \ + ((DATASIZE) == SPI_DATASIZE_22BIT) || \ + ((DATASIZE) == SPI_DATASIZE_19BIT) || \ + ((DATASIZE) == SPI_DATASIZE_18BIT) || \ + ((DATASIZE) == SPI_DATASIZE_17BIT) || \ + ((DATASIZE) == SPI_DATASIZE_16BIT) || \ + ((DATASIZE) == SPI_DATASIZE_15BIT) || \ + ((DATASIZE) == SPI_DATASIZE_14BIT) || \ + ((DATASIZE) == SPI_DATASIZE_13BIT) || \ + ((DATASIZE) == SPI_DATASIZE_12BIT) || \ + ((DATASIZE) == SPI_DATASIZE_11BIT) || \ + ((DATASIZE) == SPI_DATASIZE_10BIT) || \ + ((DATASIZE) == SPI_DATASIZE_9BIT) || \ + ((DATASIZE) == SPI_DATASIZE_8BIT) || \ + ((DATASIZE) == SPI_DATASIZE_7BIT) || \ + ((DATASIZE) == SPI_DATASIZE_6BIT) || \ + ((DATASIZE) == SPI_DATASIZE_5BIT) || \ + ((DATASIZE) == SPI_DATASIZE_4BIT)) + +/** + * @brief DataSize for limited instance + */ +#define IS_SPI_LIMITED_DATASIZE(DATASIZE) (((DATASIZE) == SPI_DATASIZE_16BIT) || \ + ((DATASIZE) == SPI_DATASIZE_8BIT)) + +#define IS_SPI_FIFOTHRESHOLD(THRESHOLD) (((THRESHOLD) == SPI_FIFO_THRESHOLD_01DATA) || \ + ((THRESHOLD) == SPI_FIFO_THRESHOLD_02DATA) || \ + ((THRESHOLD) == SPI_FIFO_THRESHOLD_03DATA) || \ + ((THRESHOLD) == SPI_FIFO_THRESHOLD_04DATA) || \ + ((THRESHOLD) == SPI_FIFO_THRESHOLD_05DATA) || \ + ((THRESHOLD) == SPI_FIFO_THRESHOLD_06DATA) || \ + ((THRESHOLD) == SPI_FIFO_THRESHOLD_07DATA) || \ + ((THRESHOLD) == SPI_FIFO_THRESHOLD_08DATA) || \ + ((THRESHOLD) == SPI_FIFO_THRESHOLD_09DATA) || \ + ((THRESHOLD) == SPI_FIFO_THRESHOLD_10DATA) || \ + ((THRESHOLD) == SPI_FIFO_THRESHOLD_11DATA) || \ + ((THRESHOLD) == SPI_FIFO_THRESHOLD_12DATA) || \ + ((THRESHOLD) == SPI_FIFO_THRESHOLD_13DATA) || \ + ((THRESHOLD) == SPI_FIFO_THRESHOLD_14DATA) || \ + ((THRESHOLD) == SPI_FIFO_THRESHOLD_15DATA) || \ + ((THRESHOLD) == SPI_FIFO_THRESHOLD_16DATA)) + +/** + * @brief FifoThreshold for limited instance + */ +#define IS_SPI_LIMITED_FIFOTHRESHOLD(THRESHOLD) (((THRESHOLD) == SPI_FIFO_THRESHOLD_01DATA) || \ + ((THRESHOLD) == SPI_FIFO_THRESHOLD_02DATA) || \ + ((THRESHOLD) == SPI_FIFO_THRESHOLD_03DATA) || \ + ((THRESHOLD) == SPI_FIFO_THRESHOLD_04DATA) || \ + ((THRESHOLD) == SPI_FIFO_THRESHOLD_05DATA) || \ + ((THRESHOLD) == SPI_FIFO_THRESHOLD_06DATA) || \ + ((THRESHOLD) == SPI_FIFO_THRESHOLD_07DATA) || \ + ((THRESHOLD) == SPI_FIFO_THRESHOLD_08DATA)) + +#define IS_SPI_CPOL(CPOL) (((CPOL) == SPI_POLARITY_LOW) || \ + ((CPOL) == SPI_POLARITY_HIGH)) + +#define IS_SPI_CPHA(CPHA) (((CPHA) == SPI_PHASE_1EDGE) || \ + ((CPHA) == SPI_PHASE_2EDGE)) + +#define IS_SPI_NSS(NSS) (((NSS) == SPI_NSS_SOFT) || \ + ((NSS) == SPI_NSS_HARD_INPUT) || \ + ((NSS) == SPI_NSS_HARD_OUTPUT)) + +#define IS_SPI_NSSP(NSSP) (((NSSP) == SPI_NSS_PULSE_ENABLE) || \ + ((NSSP) == SPI_NSS_PULSE_DISABLE)) + +#define IS_SPI_BAUDRATE_PRESCALER(PRESCALER) (((PRESCALER) == SPI_BAUDRATEPRESCALER_BYPASS) || \ + ((PRESCALER) == SPI_BAUDRATEPRESCALER_2) || \ + ((PRESCALER) == SPI_BAUDRATEPRESCALER_4) || \ + ((PRESCALER) == SPI_BAUDRATEPRESCALER_8) || \ + ((PRESCALER) == SPI_BAUDRATEPRESCALER_16) || \ + ((PRESCALER) == SPI_BAUDRATEPRESCALER_32) || \ + ((PRESCALER) == SPI_BAUDRATEPRESCALER_64) || \ + ((PRESCALER) == SPI_BAUDRATEPRESCALER_128) || \ + ((PRESCALER) == SPI_BAUDRATEPRESCALER_256)) + +#define IS_SPI_FIRST_BIT(BIT) (((BIT) == SPI_FIRSTBIT_MSB) || \ + ((BIT) == SPI_FIRSTBIT_LSB)) + +#define IS_SPI_TIMODE(MODE) (((MODE) == SPI_TIMODE_DISABLE) || \ + ((MODE) == SPI_TIMODE_ENABLE)) + +#define IS_SPI_CRC_CALCULATION(CALCULATION) (((CALCULATION) == SPI_CRCCALCULATION_DISABLE) || \ + ((CALCULATION) == SPI_CRCCALCULATION_ENABLE)) + +#define IS_SPI_CRC_INITIALIZATION_PATTERN(PATTERN) (((PATTERN) == SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN) || \ + ((PATTERN) == SPI_CRC_INITIALIZATION_ALL_ONE_PATTERN)) + +#define IS_SPI_CRC_LENGTH(LENGTH) (((LENGTH) == SPI_CRC_LENGTH_DATASIZE) || \ + ((LENGTH) == SPI_CRC_LENGTH_32BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_31BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_30BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_29BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_28BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_27BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_26BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_25BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_24BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_23BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_22BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_21BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_20BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_19BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_18BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_17BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_16BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_15BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_14BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_13BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_12BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_11BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_10BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_9BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_8BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_7BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_6BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_5BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_4BIT)) + +/** + * @brief CRC Length for limited instance + */ +#define IS_SPI_LIMITED_CRC_LENGTH(LENGTH) (((LENGTH) == SPI_CRC_LENGTH_8BIT) || \ + ((LENGTH) == SPI_CRC_LENGTH_16BIT)) + + +#define IS_SPI_CRC_POLYNOMIAL(POLYNOMIAL) ((POLYNOMIAL) > 0x0UL) + + + +#define IS_SPI_UNDERRUN_BEHAVIOUR(MODE) (((MODE) == SPI_UNDERRUN_BEHAV_REGISTER_PATTERN) || \ + ((MODE) == SPI_UNDERRUN_BEHAV_LAST_RECEIVED)) + +#define IS_SPI_RDY_MASTER_MANAGEMENT(MANAGEMENT) (((MANAGEMENT) == SPI_RDY_MASTER_MANAGEMENT_INTERNALLY) || \ + ((MANAGEMENT) == SPI_RDY_MASTER_MANAGEMENT_EXTERNALLY)) + +#define IS_SPI_RDY_POLARITY(POLARITY) (((POLARITY) == SPI_RDY_POLARITY_HIGH) || \ + ((POLARITY) == SPI_RDY_POLARITY_LOW)) + +#define IS_SPI_MASTER_RX_AUTOSUSP(MODE) (((MODE) == SPI_MASTER_RX_AUTOSUSP_DISABLE) || \ + ((MODE) == SPI_MASTER_RX_AUTOSUSP_ENABLE)) +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_SPI_H */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_spi_ex.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_spi_ex.h new file mode 100644 index 0000000000..b840f05ee2 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_spi_ex.h @@ -0,0 +1,99 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_spi_ex.h + * @author MCD Application Team + * @brief Header file of SPI HAL Extended module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_SPI_EX_H +#define STM32H5xx_HAL_SPI_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup SPIEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup SPIEx_Exported_Types SPIEx Exported Types + * @{ + */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup SPIEx_Exported_Constants SPIEx Exported Constants + * @{ + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup SPIEx_Exported_Macros SPIEx Extended Exported Macros + * @{ + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup SPIEx_Exported_Functions + * @{ + */ + +/* Initialization and de-initialization functions ****************************/ +/* IO operation functions *****************************************************/ +/** @addtogroup SPIEx_Exported_Functions_Group1 + * @{ + */ +HAL_StatusTypeDef HAL_SPIEx_FlushRxFifo(const SPI_HandleTypeDef *hspi); +HAL_StatusTypeDef HAL_SPIEx_EnableLockConfiguration(SPI_HandleTypeDef *hspi); +HAL_StatusTypeDef HAL_SPIEx_ConfigureUnderrun(SPI_HandleTypeDef *hspi, uint32_t UnderrunDetection, + uint32_t UnderrunBehaviour); +/** + * @} + */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_SPI_EX_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_sram.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_sram.h new file mode 100644 index 0000000000..2f26fb89ee --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_sram.h @@ -0,0 +1,232 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_sram.h + * @author MCD Application Team + * @brief Header file of SRAM HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2022 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 STM32H5xx_HAL_SRAM_H +#define STM32H5xx_HAL_SRAM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(FMC_BANK1) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_fmc.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ +/** @addtogroup SRAM + * @{ + */ + +/* Exported typedef ----------------------------------------------------------*/ + +/** @defgroup SRAM_Exported_Types SRAM Exported Types + * @{ + */ +/** + * @brief HAL SRAM State structures definition + */ +typedef enum +{ + HAL_SRAM_STATE_RESET = 0x00U, /*!< SRAM not yet initialized or disabled */ + HAL_SRAM_STATE_READY = 0x01U, /*!< SRAM initialized and ready for use */ + HAL_SRAM_STATE_BUSY = 0x02U, /*!< SRAM internal process is ongoing */ + HAL_SRAM_STATE_ERROR = 0x03U, /*!< SRAM error state */ + HAL_SRAM_STATE_PROTECTED = 0x04U /*!< SRAM peripheral NORSRAM device write protected */ + +} HAL_SRAM_StateTypeDef; + +/** + * @brief SRAM handle Structure definition + */ +#if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1) +typedef struct __SRAM_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */ +{ + FMC_NORSRAM_TypeDef *Instance; /*!< Register base address */ + + FMC_NORSRAM_EXTENDED_TypeDef *Extended; /*!< Extended mode register base address */ + + FMC_NORSRAM_InitTypeDef Init; /*!< SRAM device control configuration parameters */ + + HAL_LockTypeDef Lock; /*!< SRAM locking object */ + + __IO HAL_SRAM_StateTypeDef State; /*!< SRAM device access state */ + + DMA_HandleTypeDef *hdma; /*!< Pointer DMA handler */ + +#if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1) + void (* MspInitCallback)(struct __SRAM_HandleTypeDef *hsram); /*!< SRAM Msp Init callback */ + void (* MspDeInitCallback)(struct __SRAM_HandleTypeDef *hsram); /*!< SRAM Msp DeInit callback */ + void (* DmaXferCpltCallback)(DMA_HandleTypeDef *hdma); /*!< SRAM DMA Xfer Complete callback */ + void (* DmaXferErrorCallback)(DMA_HandleTypeDef *hdma); /*!< SRAM DMA Xfer Error callback */ +#endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */ +} SRAM_HandleTypeDef; + +#if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1) +/** + * @brief HAL SRAM Callback ID enumeration definition + */ +typedef enum +{ + HAL_SRAM_MSP_INIT_CB_ID = 0x00U, /*!< SRAM MspInit Callback ID */ + HAL_SRAM_MSP_DEINIT_CB_ID = 0x01U, /*!< SRAM MspDeInit Callback ID */ + HAL_SRAM_DMA_XFER_CPLT_CB_ID = 0x02U, /*!< SRAM DMA Xfer Complete Callback ID */ + HAL_SRAM_DMA_XFER_ERR_CB_ID = 0x03U /*!< SRAM DMA Xfer Complete Callback ID */ +} HAL_SRAM_CallbackIDTypeDef; + +/** + * @brief HAL SRAM Callback pointer definition + */ +typedef void (*pSRAM_CallbackTypeDef)(SRAM_HandleTypeDef *hsram); +typedef void (*pSRAM_DmaCallbackTypeDef)(DMA_HandleTypeDef *hdma); +#endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */ +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ + +/** @defgroup SRAM_Exported_Macros SRAM Exported Macros + * @{ + */ + +/** @brief Reset SRAM handle state + * @param __HANDLE__ SRAM handle + * @retval None + */ +#if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1) +#define __HAL_SRAM_RESET_HANDLE_STATE(__HANDLE__) do { \ + (__HANDLE__)->State = HAL_SRAM_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_SRAM_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_SRAM_STATE_RESET) +#endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup SRAM_Exported_Functions SRAM Exported Functions + * @{ + */ + +/** @addtogroup SRAM_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ + +/* Initialization/de-initialization functions ********************************/ +HAL_StatusTypeDef HAL_SRAM_Init(SRAM_HandleTypeDef *hsram, FMC_NORSRAM_TimingTypeDef *Timing, + FMC_NORSRAM_TimingTypeDef *ExtTiming); +HAL_StatusTypeDef HAL_SRAM_DeInit(SRAM_HandleTypeDef *hsram); +void HAL_SRAM_MspInit(SRAM_HandleTypeDef *hsram); +void HAL_SRAM_MspDeInit(SRAM_HandleTypeDef *hsram); + +/** + * @} + */ + +/** @addtogroup SRAM_Exported_Functions_Group2 Input Output and memory control functions + * @{ + */ + +/* I/O operation functions ***************************************************/ +HAL_StatusTypeDef HAL_SRAM_Read_8b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint8_t *pDstBuffer, + uint32_t BufferSize); +HAL_StatusTypeDef HAL_SRAM_Write_8b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint8_t *pSrcBuffer, + uint32_t BufferSize); +HAL_StatusTypeDef HAL_SRAM_Read_16b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint16_t *pDstBuffer, + uint32_t BufferSize); +HAL_StatusTypeDef HAL_SRAM_Write_16b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint16_t *pSrcBuffer, + uint32_t BufferSize); +HAL_StatusTypeDef HAL_SRAM_Read_32b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pDstBuffer, + uint32_t BufferSize); +HAL_StatusTypeDef HAL_SRAM_Write_32b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pSrcBuffer, + uint32_t BufferSize); +HAL_StatusTypeDef HAL_SRAM_Read_DMA(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pDstBuffer, + uint32_t BufferSize); +HAL_StatusTypeDef HAL_SRAM_Write_DMA(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pSrcBuffer, + uint32_t BufferSize); + +void HAL_SRAM_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma); +void HAL_SRAM_DMA_XferErrorCallback(DMA_HandleTypeDef *hdma); + +#if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1) +/* SRAM callback registering/unregistering */ +HAL_StatusTypeDef HAL_SRAM_RegisterCallback(SRAM_HandleTypeDef *hsram, HAL_SRAM_CallbackIDTypeDef CallbackId, + pSRAM_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_SRAM_UnRegisterCallback(SRAM_HandleTypeDef *hsram, HAL_SRAM_CallbackIDTypeDef CallbackId); +HAL_StatusTypeDef HAL_SRAM_RegisterDmaCallback(SRAM_HandleTypeDef *hsram, HAL_SRAM_CallbackIDTypeDef CallbackId, + pSRAM_DmaCallbackTypeDef pCallback); +#endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @addtogroup SRAM_Exported_Functions_Group3 Control functions + * @{ + */ + +/* SRAM Control functions ****************************************************/ +HAL_StatusTypeDef HAL_SRAM_WriteOperation_Enable(SRAM_HandleTypeDef *hsram); +HAL_StatusTypeDef HAL_SRAM_WriteOperation_Disable(SRAM_HandleTypeDef *hsram); + +/** + * @} + */ + +/** @addtogroup SRAM_Exported_Functions_Group4 Peripheral State functions + * @{ + */ + +/* SRAM State functions ******************************************************/ +HAL_SRAM_StateTypeDef HAL_SRAM_GetState(const SRAM_HandleTypeDef *hsram); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* FMC_BANK1 */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_SRAM_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_tim.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_tim.h new file mode 100644 index 0000000000..efaad2c6db --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_tim.h @@ -0,0 +1,2527 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_tim.h + * @author MCD Application Team + * @brief Header file of TIM HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_TIM_H +#define STM32H5xx_HAL_TIM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup TIM + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup TIM_Exported_Types TIM Exported Types + * @{ + */ + +/** + * @brief TIM Time base Configuration Structure definition + */ +typedef struct +{ + uint32_t Prescaler; /*!< Specifies the prescaler value used to divide the TIM clock. + This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF + Macro __HAL_TIM_CALC_PSC() can be used to calculate prescaler value */ + + uint32_t CounterMode; /*!< Specifies the counter mode. + This parameter can be a value of @ref TIM_Counter_Mode */ + + uint32_t Period; /*!< Specifies the period value to be loaded into the active + Auto-Reload Register at the next update event. + This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF + (or 0xFFEF if dithering is activated)Macros __HAL_TIM_CALC_PERIOD(), + __HAL_TIM_CALC_PERIOD_DITHER(),__HAL_TIM_CALC_PERIOD_BY_DELAY(), + __HAL_TIM_CALC_PERIOD_DITHER_BY_DELAY()can be used to calculate Period value */ + + uint32_t ClockDivision; /*!< Specifies the clock division. + This parameter can be a value of @ref TIM_ClockDivision */ + + uint32_t RepetitionCounter; /*!< Specifies the repetition counter value. Each time the RCR downcounter + reaches zero, an update event is generated and counting restarts + from the RCR value (N). + This means in PWM mode that (N+1) corresponds to: + - the number of PWM periods in edge-aligned mode + - the number of half PWM period in center-aligned mode + GP timers: this parameter must be a number between Min_Data = 0x00 and + Max_Data = 0xFF. + Advanced timers: this parameter must be a number between Min_Data = 0x0000 and + Max_Data = 0xFFFF. */ + + uint32_t AutoReloadPreload; /*!< Specifies the auto-reload preload. + This parameter can be a value of @ref TIM_AutoReloadPreload */ +} TIM_Base_InitTypeDef; + +/** + * @brief TIM Output Compare Configuration Structure definition + */ +typedef struct +{ + uint32_t OCMode; /*!< Specifies the TIM mode. + This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */ + + uint32_t Pulse; /*!< Specifies the pulse value to be loaded into the Capture Compare Register. + This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF + (or 0xFFEF if dithering is activated) + Macros __HAL_TIM_CALC_PULSE(), __HAL_TIM_CALC_PULSE_DITHER() can be used to calculate + Pulse value */ + + uint32_t OCPolarity; /*!< Specifies the output polarity. + This parameter can be a value of @ref TIM_Output_Compare_Polarity */ + + uint32_t OCNPolarity; /*!< Specifies the complementary output polarity. + This parameter can be a value of @ref TIM_Output_Compare_N_Polarity + @note This parameter is valid only for timer instances supporting break feature. */ + + uint32_t OCFastMode; /*!< Specifies the Fast mode state. + This parameter can be a value of @ref TIM_Output_Fast_State + @note This parameter is valid only in PWM1 and PWM2 mode. */ + + + uint32_t OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. + This parameter can be a value of @ref TIM_Output_Compare_Idle_State + @note This parameter is valid only for timer instances supporting break feature. */ + + uint32_t OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. + This parameter can be a value of @ref TIM_Output_Compare_N_Idle_State + @note This parameter is valid only for timer instances supporting break feature. */ +} TIM_OC_InitTypeDef; + +/** + * @brief TIM One Pulse Mode Configuration Structure definition + */ +typedef struct +{ + uint32_t OCMode; /*!< Specifies the TIM mode. + This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */ + + uint32_t Pulse; /*!< Specifies the pulse value to be loaded into the Capture Compare Register. + This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF + (or 0xFFEF if dithering is activated) + Macros __HAL_TIM_CALC_PULSE(), __HAL_TIM_CALC_PULSE_DITHER() can be used to calculate + Pulse value */ + + uint32_t OCPolarity; /*!< Specifies the output polarity. + This parameter can be a value of @ref TIM_Output_Compare_Polarity */ + + uint32_t OCNPolarity; /*!< Specifies the complementary output polarity. + This parameter can be a value of @ref TIM_Output_Compare_N_Polarity + @note This parameter is valid only for timer instances supporting break feature. */ + + uint32_t OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. + This parameter can be a value of @ref TIM_Output_Compare_Idle_State + @note This parameter is valid only for timer instances supporting break feature. */ + + uint32_t OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. + This parameter can be a value of @ref TIM_Output_Compare_N_Idle_State + @note This parameter is valid only for timer instances supporting break feature. */ + + uint32_t ICPolarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Input_Capture_Polarity */ + + uint32_t ICSelection; /*!< Specifies the input. + This parameter can be a value of @ref TIM_Input_Capture_Selection */ + + uint32_t ICFilter; /*!< Specifies the input capture filter. + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ +} TIM_OnePulse_InitTypeDef; + +/** + * @brief TIM Input Capture Configuration Structure definition + */ +typedef struct +{ + uint32_t ICPolarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Input_Capture_Polarity */ + + uint32_t ICSelection; /*!< Specifies the input. + This parameter can be a value of @ref TIM_Input_Capture_Selection */ + + uint32_t ICPrescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref TIM_Input_Capture_Prescaler */ + + uint32_t ICFilter; /*!< Specifies the input capture filter. + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ +} TIM_IC_InitTypeDef; + +/** + * @brief TIM Encoder Configuration Structure definition + */ +typedef struct +{ + uint32_t EncoderMode; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Encoder_Mode */ + + uint32_t IC1Polarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Encoder_Input_Polarity */ + + uint32_t IC1Selection; /*!< Specifies the input. + This parameter can be a value of @ref TIM_Input_Capture_Selection */ + + uint32_t IC1Prescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref TIM_Input_Capture_Prescaler */ + + uint32_t IC1Filter; /*!< Specifies the input capture filter. + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ + + uint32_t IC2Polarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Encoder_Input_Polarity */ + + uint32_t IC2Selection; /*!< Specifies the input. + This parameter can be a value of @ref TIM_Input_Capture_Selection */ + + uint32_t IC2Prescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref TIM_Input_Capture_Prescaler */ + + uint32_t IC2Filter; /*!< Specifies the input capture filter. + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ +} TIM_Encoder_InitTypeDef; + +/** + * @brief Clock Configuration Handle Structure definition + */ +typedef struct +{ + uint32_t ClockSource; /*!< TIM clock sources + This parameter can be a value of @ref TIM_Clock_Source */ + uint32_t ClockPolarity; /*!< TIM clock polarity + This parameter can be a value of @ref TIM_Clock_Polarity */ + uint32_t ClockPrescaler; /*!< TIM clock prescaler + This parameter can be a value of @ref TIM_Clock_Prescaler */ + uint32_t ClockFilter; /*!< TIM clock filter + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ +} TIM_ClockConfigTypeDef; + +/** + * @brief TIM Clear Input Configuration Handle Structure definition + */ +typedef struct +{ + uint32_t ClearInputState; /*!< TIM clear Input state + This parameter can be ENABLE or DISABLE */ + uint32_t ClearInputSource; /*!< TIM clear Input sources + This parameter can be a value of @ref TIM_ClearInput_Source */ + uint32_t ClearInputPolarity; /*!< TIM Clear Input polarity + This parameter can be a value of @ref TIM_ClearInput_Polarity */ + uint32_t ClearInputPrescaler; /*!< TIM Clear Input prescaler + This parameter must be 0: When OCRef clear feature is used with ETR source, + ETR prescaler must be off */ + uint32_t ClearInputFilter; /*!< TIM Clear Input filter + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ +} TIM_ClearInputConfigTypeDef; + +/** + * @brief TIM Master configuration Structure definition + * @note Advanced timers provide TRGO2 internal line which is redirected + * to the ADC + */ +typedef struct +{ + uint32_t MasterOutputTrigger; /*!< Trigger output (TRGO) selection + This parameter can be a value of @ref TIM_Master_Mode_Selection */ + uint32_t MasterOutputTrigger2; /*!< Trigger output2 (TRGO2) selection + This parameter can be a value of @ref TIM_Master_Mode_Selection_2 */ + uint32_t MasterSlaveMode; /*!< Master/slave mode selection + This parameter can be a value of @ref TIM_Master_Slave_Mode + @note When the Master/slave mode is enabled, the effect of + an event on the trigger input (TRGI) is delayed to allow a + perfect synchronization between the current timer and its + slaves (through TRGO). It is not mandatory in case of timer + synchronization mode. */ +} TIM_MasterConfigTypeDef; + +/** + * @brief TIM Slave configuration Structure definition + */ +typedef struct +{ + uint32_t SlaveMode; /*!< Slave mode selection + This parameter can be a value of @ref TIM_Slave_Mode */ + uint32_t InputTrigger; /*!< Input Trigger source + This parameter can be a value of @ref TIM_Trigger_Selection */ + uint32_t TriggerPolarity; /*!< Input Trigger polarity + This parameter can be a value of @ref TIM_Trigger_Polarity */ + uint32_t TriggerPrescaler; /*!< Input trigger prescaler + This parameter can be a value of @ref TIM_Trigger_Prescaler */ + uint32_t TriggerFilter; /*!< Input trigger filter + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ + +} TIM_SlaveConfigTypeDef; + +/** + * @brief TIM Break input(s) and Dead time configuration Structure definition + * @note 2 break inputs can be configured (BKIN and BKIN2) with configurable + * filter and polarity. + */ +typedef struct +{ + uint32_t OffStateRunMode; /*!< TIM off state in run mode, This parameter can be a value of @ref TIM_OSSR_Off_State_Selection_for_Run_mode_state */ + + uint32_t OffStateIDLEMode; /*!< TIM off state in IDLE mode, This parameter can be a value of @ref TIM_OSSI_Off_State_Selection_for_Idle_mode_state */ + + uint32_t LockLevel; /*!< TIM Lock level, This parameter can be a value of @ref TIM_Lock_level */ + + uint32_t DeadTime; /*!< TIM dead Time, This parameter can be a number between Min_Data = 0x00 and Max_Data = 0xFF */ + + uint32_t BreakState; /*!< TIM Break State, This parameter can be a value of @ref TIM_Break_Input_enable_disable */ + + uint32_t BreakPolarity; /*!< TIM Break input polarity, This parameter can be a value of @ref TIM_Break_Polarity */ + + uint32_t BreakFilter; /*!< Specifies the break input filter.This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ + + uint32_t BreakAFMode; /*!< Specifies the alternate function mode of the break input.This parameter can be a value of @ref TIM_Break_Input_AF_Mode */ + + uint32_t Break2State; /*!< TIM Break2 State, This parameter can be a value of @ref TIM_Break2_Input_enable_disable */ + + uint32_t Break2Polarity; /*!< TIM Break2 input polarity, This parameter can be a value of @ref TIM_Break2_Polarity */ + + uint32_t Break2Filter; /*!< TIM break2 input filter.This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ + + uint32_t Break2AFMode; /*!< Specifies the alternate function mode of the break2 input.This parameter can be a value of @ref TIM_Break2_Input_AF_Mode */ + + uint32_t AutomaticOutput; /*!< TIM Automatic Output Enable state, This parameter can be a value of @ref TIM_AOE_Bit_Set_Reset */ + +} TIM_BreakDeadTimeConfigTypeDef; + +/** + * @brief HAL State structures definition + */ +typedef enum +{ + HAL_TIM_STATE_RESET = 0x00U, /*!< Peripheral not yet initialized or disabled */ + HAL_TIM_STATE_READY = 0x01U, /*!< Peripheral Initialized and ready for use */ + HAL_TIM_STATE_BUSY = 0x02U, /*!< An internal process is ongoing */ + HAL_TIM_STATE_TIMEOUT = 0x03U, /*!< Timeout state */ + HAL_TIM_STATE_ERROR = 0x04U /*!< Reception process is ongoing */ +} HAL_TIM_StateTypeDef; + +/** + * @brief TIM Channel States definition + */ +typedef enum +{ + HAL_TIM_CHANNEL_STATE_RESET = 0x00U, /*!< TIM Channel initial state */ + HAL_TIM_CHANNEL_STATE_READY = 0x01U, /*!< TIM Channel ready for use */ + HAL_TIM_CHANNEL_STATE_BUSY = 0x02U, /*!< An internal process is ongoing on the TIM channel */ +} HAL_TIM_ChannelStateTypeDef; + +/** + * @brief DMA Burst States definition + */ +typedef enum +{ + HAL_DMA_BURST_STATE_RESET = 0x00U, /*!< DMA Burst initial state */ + HAL_DMA_BURST_STATE_READY = 0x01U, /*!< DMA Burst ready for use */ + HAL_DMA_BURST_STATE_BUSY = 0x02U, /*!< Ongoing DMA Burst */ +} HAL_TIM_DMABurstStateTypeDef; + +/** + * @brief HAL Active channel structures definition + */ +typedef enum +{ + HAL_TIM_ACTIVE_CHANNEL_1 = 0x01U, /*!< The active channel is 1 */ + HAL_TIM_ACTIVE_CHANNEL_2 = 0x02U, /*!< The active channel is 2 */ + HAL_TIM_ACTIVE_CHANNEL_3 = 0x04U, /*!< The active channel is 3 */ + HAL_TIM_ACTIVE_CHANNEL_4 = 0x08U, /*!< The active channel is 4 */ + HAL_TIM_ACTIVE_CHANNEL_5 = 0x10U, /*!< The active channel is 5 */ + HAL_TIM_ACTIVE_CHANNEL_6 = 0x20U, /*!< The active channel is 6 */ + HAL_TIM_ACTIVE_CHANNEL_CLEARED = 0x00U /*!< All active channels cleared */ +} HAL_TIM_ActiveChannel; + +/** + * @brief TIM Time Base Handle Structure definition + */ +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) +typedef struct __TIM_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ +{ + TIM_TypeDef *Instance; /*!< Register base address */ + TIM_Base_InitTypeDef Init; /*!< TIM Time Base required parameters */ + HAL_TIM_ActiveChannel Channel; /*!< Active channel */ + DMA_HandleTypeDef *hdma[7]; /*!< DMA Handlers array + This array is accessed by a @ref DMA_Handle_index */ + HAL_LockTypeDef Lock; /*!< Locking object */ + __IO HAL_TIM_StateTypeDef State; /*!< TIM operation state */ + __IO HAL_TIM_ChannelStateTypeDef ChannelState[6]; /*!< TIM channel operation state */ + __IO HAL_TIM_ChannelStateTypeDef ChannelNState[4]; /*!< TIM complementary channel operation state */ + __IO HAL_TIM_DMABurstStateTypeDef DMABurstState; /*!< DMA burst operation state */ + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + void (* Base_MspInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Base Msp Init Callback */ + void (* Base_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Base Msp DeInit Callback */ + void (* IC_MspInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM IC Msp Init Callback */ + void (* IC_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM IC Msp DeInit Callback */ + void (* OC_MspInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM OC Msp Init Callback */ + void (* OC_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM OC Msp DeInit Callback */ + void (* PWM_MspInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM PWM Msp Init Callback */ + void (* PWM_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM PWM Msp DeInit Callback */ + void (* OnePulse_MspInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM One Pulse Msp Init Callback */ + void (* OnePulse_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM One Pulse Msp DeInit Callback */ + void (* Encoder_MspInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Encoder Msp Init Callback */ + void (* Encoder_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Encoder Msp DeInit Callback */ + void (* HallSensor_MspInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Hall Sensor Msp Init Callback */ + void (* HallSensor_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Hall Sensor Msp DeInit Callback */ + void (* PeriodElapsedCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Period Elapsed Callback */ + void (* PeriodElapsedHalfCpltCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Period Elapsed half complete Callback */ + void (* TriggerCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Trigger Callback */ + void (* TriggerHalfCpltCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Trigger half complete Callback */ + void (* IC_CaptureCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Input Capture Callback */ + void (* IC_CaptureHalfCpltCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Input Capture half complete Callback */ + void (* OC_DelayElapsedCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Output Compare Delay Elapsed Callback */ + void (* PWM_PulseFinishedCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM PWM Pulse Finished Callback */ + void (* PWM_PulseFinishedHalfCpltCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM PWM Pulse Finished half complete Callback */ + void (* ErrorCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Error Callback */ + void (* CommutationCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Commutation Callback */ + void (* CommutationHalfCpltCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Commutation half complete Callback */ + void (* BreakCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Break Callback */ + void (* Break2Callback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Break2 Callback */ + void (* EncoderIndexCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Encoder Index Callback */ + void (* DirectionChangeCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Direction Change Callback */ + void (* IndexErrorCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Index Error Callback */ + void (* TransitionErrorCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Transition Error Callback */ +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ +} TIM_HandleTypeDef; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) +/** + * @brief HAL TIM Callback ID enumeration definition + */ +typedef enum +{ + HAL_TIM_BASE_MSPINIT_CB_ID = 0x00U /*!< TIM Base MspInit Callback ID */ + , HAL_TIM_BASE_MSPDEINIT_CB_ID = 0x01U /*!< TIM Base MspDeInit Callback ID */ + , HAL_TIM_IC_MSPINIT_CB_ID = 0x02U /*!< TIM IC MspInit Callback ID */ + , HAL_TIM_IC_MSPDEINIT_CB_ID = 0x03U /*!< TIM IC MspDeInit Callback ID */ + , HAL_TIM_OC_MSPINIT_CB_ID = 0x04U /*!< TIM OC MspInit Callback ID */ + , HAL_TIM_OC_MSPDEINIT_CB_ID = 0x05U /*!< TIM OC MspDeInit Callback ID */ + , HAL_TIM_PWM_MSPINIT_CB_ID = 0x06U /*!< TIM PWM MspInit Callback ID */ + , HAL_TIM_PWM_MSPDEINIT_CB_ID = 0x07U /*!< TIM PWM MspDeInit Callback ID */ + , HAL_TIM_ONE_PULSE_MSPINIT_CB_ID = 0x08U /*!< TIM One Pulse MspInit Callback ID */ + , HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID = 0x09U /*!< TIM One Pulse MspDeInit Callback ID */ + , HAL_TIM_ENCODER_MSPINIT_CB_ID = 0x0AU /*!< TIM Encoder MspInit Callback ID */ + , HAL_TIM_ENCODER_MSPDEINIT_CB_ID = 0x0BU /*!< TIM Encoder MspDeInit Callback ID */ + , HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID = 0x0CU /*!< TIM Hall Sensor MspDeInit Callback ID */ + , HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID = 0x0DU /*!< TIM Hall Sensor MspDeInit Callback ID */ + , HAL_TIM_PERIOD_ELAPSED_CB_ID = 0x0EU /*!< TIM Period Elapsed Callback ID */ + , HAL_TIM_PERIOD_ELAPSED_HALF_CB_ID = 0x0FU /*!< TIM Period Elapsed half complete Callback ID */ + , HAL_TIM_TRIGGER_CB_ID = 0x10U /*!< TIM Trigger Callback ID */ + , HAL_TIM_TRIGGER_HALF_CB_ID = 0x11U /*!< TIM Trigger half complete Callback ID */ + + , HAL_TIM_IC_CAPTURE_CB_ID = 0x12U /*!< TIM Input Capture Callback ID */ + , HAL_TIM_IC_CAPTURE_HALF_CB_ID = 0x13U /*!< TIM Input Capture half complete Callback ID */ + , HAL_TIM_OC_DELAY_ELAPSED_CB_ID = 0x14U /*!< TIM Output Compare Delay Elapsed Callback ID */ + , HAL_TIM_PWM_PULSE_FINISHED_CB_ID = 0x15U /*!< TIM PWM Pulse Finished Callback ID */ + , HAL_TIM_PWM_PULSE_FINISHED_HALF_CB_ID = 0x16U /*!< TIM PWM Pulse Finished half complete Callback ID */ + , HAL_TIM_ERROR_CB_ID = 0x17U /*!< TIM Error Callback ID */ + , HAL_TIM_COMMUTATION_CB_ID = 0x18U /*!< TIM Commutation Callback ID */ + , HAL_TIM_COMMUTATION_HALF_CB_ID = 0x19U /*!< TIM Commutation half complete Callback ID */ + , HAL_TIM_BREAK_CB_ID = 0x1AU /*!< TIM Break Callback ID */ + , HAL_TIM_BREAK2_CB_ID = 0x1BU /*!< TIM Break2 Callback ID */ + , HAL_TIM_ENCODER_INDEX_CB_ID = 0x1CU /*!< TIM Encoder Index Callback ID */ + , HAL_TIM_DIRECTION_CHANGE_CB_ID = 0x1DU /*!< TIM Direction Change Callback ID */ + , HAL_TIM_INDEX_ERROR_CB_ID = 0x1EU /*!< TIM Index Error Callback ID */ + , HAL_TIM_TRANSITION_ERROR_CB_ID = 0x1FU /*!< TIM Transition Error Callback ID */ +} HAL_TIM_CallbackIDTypeDef; + +/** + * @brief HAL TIM Callback pointer definition + */ +typedef void (*pTIM_CallbackTypeDef)(TIM_HandleTypeDef *htim); /*!< pointer to the TIM callback function */ + +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + +/** + * @} + */ +/* End of exported types -----------------------------------------------------*/ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup TIM_Exported_Constants TIM Exported Constants + * @{ + */ + +/** @defgroup TIM_ClearInput_Source TIM Clear Input Source + * @{ + */ +#define TIM_CLEARINPUTSOURCE_NONE 0x00000000U /*!< OCREF_CLR is disabled */ +#define TIM_CLEARINPUTSOURCE_ETR 0x00000001U /*!< OCREF_CLR is connected to ETRF input */ +#define TIM_CLEARINPUTSOURCE_OCREFCLR 0x00000002U /*!< OCREF_CLR is connected to OCREF_CLR_INT */ +/** + * @} + */ + +/** @defgroup TIM_DMA_Base_address TIM DMA Base Address + * @{ + */ +#define TIM_DMABASE_CR1 0x00000000U +#define TIM_DMABASE_CR2 0x00000001U +#define TIM_DMABASE_SMCR 0x00000002U +#define TIM_DMABASE_DIER 0x00000003U +#define TIM_DMABASE_SR 0x00000004U +#define TIM_DMABASE_EGR 0x00000005U +#define TIM_DMABASE_CCMR1 0x00000006U +#define TIM_DMABASE_CCMR2 0x00000007U +#define TIM_DMABASE_CCER 0x00000008U +#define TIM_DMABASE_CNT 0x00000009U +#define TIM_DMABASE_PSC 0x0000000AU +#define TIM_DMABASE_ARR 0x0000000BU +#define TIM_DMABASE_RCR 0x0000000CU +#define TIM_DMABASE_CCR1 0x0000000DU +#define TIM_DMABASE_CCR2 0x0000000EU +#define TIM_DMABASE_CCR3 0x0000000FU +#define TIM_DMABASE_CCR4 0x00000010U +#define TIM_DMABASE_BDTR 0x00000011U +#define TIM_DMABASE_CCR5 0x00000012U +#define TIM_DMABASE_CCR6 0x00000013U +#define TIM_DMABASE_CCMR3 0x00000014U +#define TIM_DMABASE_DTR2 0x00000015U +#define TIM_DMABASE_ECR 0x00000016U +#define TIM_DMABASE_TISEL 0x00000017U +#define TIM_DMABASE_AF1 0x00000018U +#define TIM_DMABASE_AF2 0x00000019U +/** + * @} + */ + +/** @defgroup TIM_Event_Source TIM Event Source + * @{ + */ +#define TIM_EVENTSOURCE_UPDATE TIM_EGR_UG /*!< Reinitialize the counter and generates an update of the registers */ +#define TIM_EVENTSOURCE_CC1 TIM_EGR_CC1G /*!< A capture/compare event is generated on channel 1 */ +#define TIM_EVENTSOURCE_CC2 TIM_EGR_CC2G /*!< A capture/compare event is generated on channel 2 */ +#define TIM_EVENTSOURCE_CC3 TIM_EGR_CC3G /*!< A capture/compare event is generated on channel 3 */ +#define TIM_EVENTSOURCE_CC4 TIM_EGR_CC4G /*!< A capture/compare event is generated on channel 4 */ +#define TIM_EVENTSOURCE_COM TIM_EGR_COMG /*!< A commutation event is generated */ +#define TIM_EVENTSOURCE_TRIGGER TIM_EGR_TG /*!< A trigger event is generated */ +#define TIM_EVENTSOURCE_BREAK TIM_EGR_BG /*!< A break event is generated */ +#define TIM_EVENTSOURCE_BREAK2 TIM_EGR_B2G /*!< A break 2 event is generated */ +/** + * @} + */ + +/** @defgroup TIM_Input_Channel_Polarity TIM Input Channel polarity + * @{ + */ +#define TIM_INPUTCHANNELPOLARITY_RISING 0x00000000U /*!< Polarity for TIx source */ +#define TIM_INPUTCHANNELPOLARITY_FALLING TIM_CCER_CC1P /*!< Polarity for TIx source */ +#define TIM_INPUTCHANNELPOLARITY_BOTHEDGE (TIM_CCER_CC1P | TIM_CCER_CC1NP) /*!< Polarity for TIx source */ +/** + * @} + */ + +/** @defgroup TIM_ETR_Polarity TIM ETR Polarity + * @{ + */ +#define TIM_ETRPOLARITY_INVERTED TIM_SMCR_ETP /*!< Polarity for ETR source */ +#define TIM_ETRPOLARITY_NONINVERTED 0x00000000U /*!< Polarity for ETR source */ +/** + * @} + */ + +/** @defgroup TIM_ETR_Prescaler TIM ETR Prescaler + * @{ + */ +#define TIM_ETRPRESCALER_DIV1 0x00000000U /*!< No prescaler is used */ +#define TIM_ETRPRESCALER_DIV2 TIM_SMCR_ETPS_0 /*!< ETR input source is divided by 2 */ +#define TIM_ETRPRESCALER_DIV4 TIM_SMCR_ETPS_1 /*!< ETR input source is divided by 4 */ +#define TIM_ETRPRESCALER_DIV8 TIM_SMCR_ETPS /*!< ETR input source is divided by 8 */ +/** + * @} + */ + +/** @defgroup TIM_Counter_Mode TIM Counter Mode + * @{ + */ +#define TIM_COUNTERMODE_UP 0x00000000U /*!< Counter used as up-counter */ +#define TIM_COUNTERMODE_DOWN TIM_CR1_DIR /*!< Counter used as down-counter */ +#define TIM_COUNTERMODE_CENTERALIGNED1 TIM_CR1_CMS_0 /*!< Center-aligned mode 1 */ +#define TIM_COUNTERMODE_CENTERALIGNED2 TIM_CR1_CMS_1 /*!< Center-aligned mode 2 */ +#define TIM_COUNTERMODE_CENTERALIGNED3 TIM_CR1_CMS /*!< Center-aligned mode 3 */ +/** + * @} + */ + +/** @defgroup TIM_Update_Interrupt_Flag_Remap TIM Update Interrupt Flag Remap + * @{ + */ +#define TIM_UIFREMAP_DISABLE 0x00000000U /*!< Update interrupt flag remap disabled */ +#define TIM_UIFREMAP_ENABLE TIM_CR1_UIFREMAP /*!< Update interrupt flag remap enabled */ +/** + * @} + */ + +/** @defgroup TIM_ClockDivision TIM Clock Division + * @{ + */ +#define TIM_CLOCKDIVISION_DIV1 0x00000000U /*!< Clock division: tDTS=tCK_INT */ +#define TIM_CLOCKDIVISION_DIV2 TIM_CR1_CKD_0 /*!< Clock division: tDTS=2*tCK_INT */ +#define TIM_CLOCKDIVISION_DIV4 TIM_CR1_CKD_1 /*!< Clock division: tDTS=4*tCK_INT */ +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_State TIM Output Compare State + * @{ + */ +#define TIM_OUTPUTSTATE_DISABLE 0x00000000U /*!< Capture/Compare 1 output disabled */ +#define TIM_OUTPUTSTATE_ENABLE TIM_CCER_CC1E /*!< Capture/Compare 1 output enabled */ +/** + * @} + */ + +/** @defgroup TIM_AutoReloadPreload TIM Auto-Reload Preload + * @{ + */ +#define TIM_AUTORELOAD_PRELOAD_DISABLE 0x00000000U /*!< TIMx_ARR register is not buffered */ +#define TIM_AUTORELOAD_PRELOAD_ENABLE TIM_CR1_ARPE /*!< TIMx_ARR register is buffered */ + +/** + * @} + */ + +/** @defgroup TIM_Output_Fast_State TIM Output Fast State + * @{ + */ +#define TIM_OCFAST_DISABLE 0x00000000U /*!< Output Compare fast disable */ +#define TIM_OCFAST_ENABLE TIM_CCMR1_OC1FE /*!< Output Compare fast enable */ +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_N_State TIM Complementary Output Compare State + * @{ + */ +#define TIM_OUTPUTNSTATE_DISABLE 0x00000000U /*!< OCxN is disabled */ +#define TIM_OUTPUTNSTATE_ENABLE TIM_CCER_CC1NE /*!< OCxN is enabled */ +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Polarity TIM Output Compare Polarity + * @{ + */ +#define TIM_OCPOLARITY_HIGH 0x00000000U /*!< Capture/Compare output polarity */ +#define TIM_OCPOLARITY_LOW TIM_CCER_CC1P /*!< Capture/Compare output polarity */ +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_N_Polarity TIM Complementary Output Compare Polarity + * @{ + */ +#define TIM_OCNPOLARITY_HIGH 0x00000000U /*!< Capture/Compare complementary output polarity */ +#define TIM_OCNPOLARITY_LOW TIM_CCER_CC1NP /*!< Capture/Compare complementary output polarity */ +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Idle_State TIM Output Compare Idle State + * @{ + */ +#define TIM_OCIDLESTATE_SET TIM_CR2_OIS1 /*!< Output Idle state: OCx=1 when MOE=0 */ +#define TIM_OCIDLESTATE_RESET 0x00000000U /*!< Output Idle state: OCx=0 when MOE=0 */ +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_N_Idle_State TIM Complementary Output Compare Idle State + * @{ + */ +#define TIM_OCNIDLESTATE_SET TIM_CR2_OIS1N /*!< Complementary output Idle state: OCxN=1 when MOE=0 */ +#define TIM_OCNIDLESTATE_RESET 0x00000000U /*!< Complementary output Idle state: OCxN=0 when MOE=0 */ +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Polarity TIM Input Capture Polarity + * @{ + */ +#define TIM_ICPOLARITY_RISING TIM_INPUTCHANNELPOLARITY_RISING /*!< Capture triggered by rising edge on timer input */ +#define TIM_ICPOLARITY_FALLING TIM_INPUTCHANNELPOLARITY_FALLING /*!< Capture triggered by falling edge on timer input */ +#define TIM_ICPOLARITY_BOTHEDGE TIM_INPUTCHANNELPOLARITY_BOTHEDGE /*!< Capture triggered by both rising and falling edges on timer input*/ +/** + * @} + */ + +/** @defgroup TIM_Encoder_Input_Polarity TIM Encoder Input Polarity + * @{ + */ +#define TIM_ENCODERINPUTPOLARITY_RISING TIM_INPUTCHANNELPOLARITY_RISING /*!< Encoder input with rising edge polarity */ +#define TIM_ENCODERINPUTPOLARITY_FALLING TIM_INPUTCHANNELPOLARITY_FALLING /*!< Encoder input with falling edge polarity */ +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Selection TIM Input Capture Selection + * @{ + */ +#define TIM_ICSELECTION_DIRECTTI TIM_CCMR1_CC1S_0 /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to IC1, IC2, IC3 or IC4, respectively */ +#define TIM_ICSELECTION_INDIRECTTI TIM_CCMR1_CC1S_1 /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to IC2, IC1, IC4 or IC3, respectively */ +#define TIM_ICSELECTION_TRC TIM_CCMR1_CC1S /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to TRC */ +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Prescaler TIM Input Capture Prescaler + * @{ + */ +#define TIM_ICPSC_DIV1 0x00000000U /*!< Capture performed each time an edge is detected on the capture input */ +#define TIM_ICPSC_DIV2 TIM_CCMR1_IC1PSC_0 /*!< Capture performed once every 2 events */ +#define TIM_ICPSC_DIV4 TIM_CCMR1_IC1PSC_1 /*!< Capture performed once every 4 events */ +#define TIM_ICPSC_DIV8 TIM_CCMR1_IC1PSC /*!< Capture performed once every 8 events */ +/** + * @} + */ + +/** @defgroup TIM_One_Pulse_Mode TIM One Pulse Mode + * @{ + */ +#define TIM_OPMODE_SINGLE TIM_CR1_OPM /*!< Counter stops counting at the next update event */ +#define TIM_OPMODE_REPETITIVE 0x00000000U /*!< Counter is not stopped at update event */ +/** + * @} + */ + +/** @defgroup TIM_Encoder_Mode TIM Encoder Mode + * @{ + */ +#define TIM_ENCODERMODE_TI1 TIM_SMCR_SMS_0 /*!< Quadrature encoder mode 1, x2 mode, counts up/down on TI1FP1 edge depending on TI2FP2 level */ +#define TIM_ENCODERMODE_TI2 TIM_SMCR_SMS_1 /*!< Quadrature encoder mode 2, x2 mode, counts up/down on TI2FP2 edge depending on TI1FP1 level. */ +#define TIM_ENCODERMODE_TI12 (TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0) /*!< Quadrature encoder mode 3, x4 mode, counts up/down on both TI1FP1 and TI2FP2 edges depending on the level of the other input. */ +#define TIM_ENCODERMODE_CLOCKPLUSDIRECTION_X2 (TIM_SMCR_SMS_3 | TIM_SMCR_SMS_1) /*!< Encoder mode: Clock plus direction, x2 mode */ +#define TIM_ENCODERMODE_CLOCKPLUSDIRECTION_X1 (TIM_SMCR_SMS_3 | TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0) /*!< Encoder mode: Clock plus direction, x1 mode, TI2FP2 edge sensitivity is set by CC2P */ +#define TIM_ENCODERMODE_DIRECTIONALCLOCK_X2 (TIM_SMCR_SMS_3 | TIM_SMCR_SMS_2) /*!< Encoder mode: Directional Clock, x2 mode */ +#define TIM_ENCODERMODE_DIRECTIONALCLOCK_X1_TI12 (TIM_SMCR_SMS_3 | TIM_SMCR_SMS_2 | TIM_SMCR_SMS_0) /*!< Encoder mode: Directional Clock, x1 mode, TI1FP1 and TI2FP2 edge sensitivity is set by CC1P and CC2P */ +#define TIM_ENCODERMODE_X1_TI1 (TIM_SMCR_SMS_3 | TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1) /*!< Quadrature encoder mode: x1 mode, counting on TI1FP1 edges only, edge sensitivity is set by CC1P */ +#define TIM_ENCODERMODE_X1_TI2 (TIM_SMCR_SMS_3 | TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0) /*!< Quadrature encoder mode: x1 mode, counting on TI2FP2 edges only, edge sensitivity is set by CC1P */ +/** + * @} + */ + +/** @defgroup TIM_Interrupt_definition TIM interrupt Definition + * @{ + */ +#define TIM_IT_UPDATE TIM_DIER_UIE /*!< Update interrupt */ +#define TIM_IT_CC1 TIM_DIER_CC1IE /*!< Capture/Compare 1 interrupt */ +#define TIM_IT_CC2 TIM_DIER_CC2IE /*!< Capture/Compare 2 interrupt */ +#define TIM_IT_CC3 TIM_DIER_CC3IE /*!< Capture/Compare 3 interrupt */ +#define TIM_IT_CC4 TIM_DIER_CC4IE /*!< Capture/Compare 4 interrupt */ +#define TIM_IT_COM TIM_DIER_COMIE /*!< Commutation interrupt */ +#define TIM_IT_TRIGGER TIM_DIER_TIE /*!< Trigger interrupt */ +#define TIM_IT_BREAK TIM_DIER_BIE /*!< Break interrupt */ +#define TIM_IT_IDX TIM_DIER_IDXIE /*!< Index interrupt */ +#define TIM_IT_DIR TIM_DIER_DIRIE /*!< Direction change interrupt */ +#define TIM_IT_IERR TIM_DIER_IERRIE /*!< Index error interrupt */ +#define TIM_IT_TERR TIM_DIER_TERRIE /*!< Transition error interrupt */ +/** + * @} + */ + +/** @defgroup TIM_Commutation_Source TIM Commutation Source + * @{ + */ +#define TIM_COMMUTATION_TRGI TIM_CR2_CCUS /*!< When Capture/compare control bits are preloaded, they are updated by setting the COMG bit or when an rising edge occurs on trigger input */ +#define TIM_COMMUTATION_SOFTWARE 0x00000000U /*!< When Capture/compare control bits are preloaded, they are updated by setting the COMG bit */ +/** + * @} + */ + +/** @defgroup TIM_DMA_sources TIM DMA Sources + * @{ + */ +#define TIM_DMA_UPDATE TIM_DIER_UDE /*!< DMA request is triggered by the update event */ +#define TIM_DMA_CC1 TIM_DIER_CC1DE /*!< DMA request is triggered by the capture/compare macth 1 event */ +#define TIM_DMA_CC2 TIM_DIER_CC2DE /*!< DMA request is triggered by the capture/compare macth 2 event event */ +#define TIM_DMA_CC3 TIM_DIER_CC3DE /*!< DMA request is triggered by the capture/compare macth 3 event event */ +#define TIM_DMA_CC4 TIM_DIER_CC4DE /*!< DMA request is triggered by the capture/compare macth 4 event event */ +#define TIM_DMA_COM TIM_DIER_COMDE /*!< DMA request is triggered by the commutation event */ +#define TIM_DMA_TRIGGER TIM_DIER_TDE /*!< DMA request is triggered by the trigger event */ +/** + * @} + */ + +/** @defgroup TIM_CC_DMA_Request CCx DMA request selection + * @{ + */ +#define TIM_CCDMAREQUEST_CC 0x00000000U /*!< CCx DMA request sent when capture or compare match event occurs */ +#define TIM_CCDMAREQUEST_UPDATE TIM_CR2_CCDS /*!< CCx DMA requests sent when update event occurs */ +/** + * @} + */ + +/** @defgroup TIM_Flag_definition TIM Flag Definition + * @{ + */ +#define TIM_FLAG_UPDATE TIM_SR_UIF /*!< Update interrupt flag */ +#define TIM_FLAG_CC1 TIM_SR_CC1IF /*!< Capture/Compare 1 interrupt flag */ +#define TIM_FLAG_CC2 TIM_SR_CC2IF /*!< Capture/Compare 2 interrupt flag */ +#define TIM_FLAG_CC3 TIM_SR_CC3IF /*!< Capture/Compare 3 interrupt flag */ +#define TIM_FLAG_CC4 TIM_SR_CC4IF /*!< Capture/Compare 4 interrupt flag */ +#define TIM_FLAG_CC5 TIM_SR_CC5IF /*!< Capture/Compare 5 interrupt flag */ +#define TIM_FLAG_CC6 TIM_SR_CC6IF /*!< Capture/Compare 6 interrupt flag */ +#define TIM_FLAG_COM TIM_SR_COMIF /*!< Commutation interrupt flag */ +#define TIM_FLAG_TRIGGER TIM_SR_TIF /*!< Trigger interrupt flag */ +#define TIM_FLAG_BREAK TIM_SR_BIF /*!< Break interrupt flag */ +#define TIM_FLAG_BREAK2 TIM_SR_B2IF /*!< Break 2 interrupt flag */ +#define TIM_FLAG_SYSTEM_BREAK TIM_SR_SBIF /*!< System Break interrupt flag */ +#define TIM_FLAG_CC1OF TIM_SR_CC1OF /*!< Capture 1 overcapture flag */ +#define TIM_FLAG_CC2OF TIM_SR_CC2OF /*!< Capture 2 overcapture flag */ +#define TIM_FLAG_CC3OF TIM_SR_CC3OF /*!< Capture 3 overcapture flag */ +#define TIM_FLAG_CC4OF TIM_SR_CC4OF /*!< Capture 4 overcapture flag */ +#define TIM_FLAG_IDX TIM_SR_IDXF /*!< Encoder index flag */ +#define TIM_FLAG_DIR TIM_SR_DIRF /*!< Direction change flag */ +#define TIM_FLAG_IERR TIM_SR_IERRF /*!< Index error flag */ +#define TIM_FLAG_TERR TIM_SR_TERRF /*!< Transition error flag */ +/** + * @} + */ + +/** @defgroup TIM_Channel TIM Channel + * @{ + */ +#define TIM_CHANNEL_1 0x00000000U /*!< Capture/compare channel 1 identifier */ +#define TIM_CHANNEL_2 0x00000004U /*!< Capture/compare channel 2 identifier */ +#define TIM_CHANNEL_3 0x00000008U /*!< Capture/compare channel 3 identifier */ +#define TIM_CHANNEL_4 0x0000000CU /*!< Capture/compare channel 4 identifier */ +#define TIM_CHANNEL_5 0x00000010U /*!< Compare channel 5 identifier */ +#define TIM_CHANNEL_6 0x00000014U /*!< Compare channel 6 identifier */ +#define TIM_CHANNEL_ALL 0x0000003CU /*!< Global Capture/compare channel identifier */ +/** + * @} + */ + +/** @defgroup TIM_Clock_Source TIM Clock Source + * @{ + */ +#define TIM_CLOCKSOURCE_INTERNAL TIM_SMCR_ETPS_0 /*!< Internal clock source */ +#define TIM_CLOCKSOURCE_ETRMODE1 TIM_TS_ETRF /*!< External clock source mode 1 (ETRF) */ +#define TIM_CLOCKSOURCE_ETRMODE2 TIM_SMCR_ETPS_1 /*!< External clock source mode 2 */ +#define TIM_CLOCKSOURCE_TI1ED TIM_TS_TI1F_ED /*!< External clock source mode 1 (TTI1FP1 + edge detect.) */ +#define TIM_CLOCKSOURCE_TI1 TIM_TS_TI1FP1 /*!< External clock source mode 1 (TTI1FP1) */ +#define TIM_CLOCKSOURCE_TI2 TIM_TS_TI2FP2 /*!< External clock source mode 1 (TTI2FP2) */ +#define TIM_CLOCKSOURCE_ITR0 TIM_TS_ITR0 /*!< External clock source mode 1 (ITR0) */ +#define TIM_CLOCKSOURCE_ITR1 TIM_TS_ITR1 /*!< External clock source mode 1 (ITR1) */ +#define TIM_CLOCKSOURCE_ITR2 TIM_TS_ITR2 /*!< External clock source mode 1 (ITR2) */ +#define TIM_CLOCKSOURCE_ITR3 TIM_TS_ITR3 /*!< External clock source mode 1 (ITR3) */ +#define TIM_CLOCKSOURCE_ITR4 TIM_TS_ITR4 /*!< External clock source mode 1 (ITR4) */ +#define TIM_CLOCKSOURCE_ITR5 TIM_TS_ITR5 /*!< External clock source mode 1 (ITR5) */ +#define TIM_CLOCKSOURCE_ITR6 TIM_TS_ITR6 /*!< External clock source mode 1 (ITR6) */ +#define TIM_CLOCKSOURCE_ITR7 TIM_TS_ITR7 /*!< External clock source mode 1 (ITR7) */ +#define TIM_CLOCKSOURCE_ITR8 TIM_TS_ITR8 /*!< External clock source mode 1 (ITR8) */ +#define TIM_CLOCKSOURCE_ITR9 TIM_TS_ITR9 /*!< External clock source mode 1 (ITR9) */ +#define TIM_CLOCKSOURCE_ITR10 TIM_TS_ITR10 /*!< External clock source mode 1 (ITR10) */ +#define TIM_CLOCKSOURCE_ITR11 TIM_TS_ITR11 /*!< External clock source mode 1 (ITR11) */ +#define TIM_CLOCKSOURCE_ITR12 TIM_TS_ITR12 /*!< External clock source mode 1 (ITR12) */ +/** + * @} + */ + +/** @defgroup TIM_Clock_Polarity TIM Clock Polarity + * @{ + */ +#define TIM_CLOCKPOLARITY_INVERTED TIM_ETRPOLARITY_INVERTED /*!< Polarity for ETRx clock sources */ +#define TIM_CLOCKPOLARITY_NONINVERTED TIM_ETRPOLARITY_NONINVERTED /*!< Polarity for ETRx clock sources */ +#define TIM_CLOCKPOLARITY_RISING TIM_INPUTCHANNELPOLARITY_RISING /*!< Polarity for TIx clock sources */ +#define TIM_CLOCKPOLARITY_FALLING TIM_INPUTCHANNELPOLARITY_FALLING /*!< Polarity for TIx clock sources */ +#define TIM_CLOCKPOLARITY_BOTHEDGE TIM_INPUTCHANNELPOLARITY_BOTHEDGE /*!< Polarity for TIx clock sources */ +/** + * @} + */ + +/** @defgroup TIM_Clock_Prescaler TIM Clock Prescaler + * @{ + */ +#define TIM_CLOCKPRESCALER_DIV1 TIM_ETRPRESCALER_DIV1 /*!< No prescaler is used */ +#define TIM_CLOCKPRESCALER_DIV2 TIM_ETRPRESCALER_DIV2 /*!< Prescaler for External ETR Clock: Capture performed once every 2 events. */ +#define TIM_CLOCKPRESCALER_DIV4 TIM_ETRPRESCALER_DIV4 /*!< Prescaler for External ETR Clock: Capture performed once every 4 events. */ +#define TIM_CLOCKPRESCALER_DIV8 TIM_ETRPRESCALER_DIV8 /*!< Prescaler for External ETR Clock: Capture performed once every 8 events. */ +/** + * @} + */ + +/** @defgroup TIM_ClearInput_Polarity TIM Clear Input Polarity + * @{ + */ +#define TIM_CLEARINPUTPOLARITY_INVERTED TIM_ETRPOLARITY_INVERTED /*!< Polarity for ETRx pin */ +#define TIM_CLEARINPUTPOLARITY_NONINVERTED TIM_ETRPOLARITY_NONINVERTED /*!< Polarity for ETRx pin */ +/** + * @} + */ + +/** @defgroup TIM_ClearInput_Prescaler TIM Clear Input Prescaler + * @{ + */ +#define TIM_CLEARINPUTPRESCALER_DIV1 TIM_ETRPRESCALER_DIV1 /*!< No prescaler is used */ +#define TIM_CLEARINPUTPRESCALER_DIV2 TIM_ETRPRESCALER_DIV2 /*!< Prescaler for External ETR pin: Capture performed once every 2 events. */ +#define TIM_CLEARINPUTPRESCALER_DIV4 TIM_ETRPRESCALER_DIV4 /*!< Prescaler for External ETR pin: Capture performed once every 4 events. */ +#define TIM_CLEARINPUTPRESCALER_DIV8 TIM_ETRPRESCALER_DIV8 /*!< Prescaler for External ETR pin: Capture performed once every 8 events. */ +/** + * @} + */ + +/** @defgroup TIM_OSSR_Off_State_Selection_for_Run_mode_state TIM OSSR OffState Selection for Run mode state + * @{ + */ +#define TIM_OSSR_ENABLE TIM_BDTR_OSSR /*!< When inactive, OC/OCN outputs are enabled (still controlled by the timer) */ +#define TIM_OSSR_DISABLE 0x00000000U /*!< When inactive, OC/OCN outputs are disabled (not controlled any longer by the timer) */ +/** + * @} + */ + +/** @defgroup TIM_OSSI_Off_State_Selection_for_Idle_mode_state TIM OSSI OffState Selection for Idle mode state + * @{ + */ +#define TIM_OSSI_ENABLE TIM_BDTR_OSSI /*!< When inactive, OC/OCN outputs are enabled (still controlled by the timer) */ +#define TIM_OSSI_DISABLE 0x00000000U /*!< When inactive, OC/OCN outputs are disabled (not controlled any longer by the timer) */ +/** + * @} + */ +/** @defgroup TIM_Lock_level TIM Lock level + * @{ + */ +#define TIM_LOCKLEVEL_OFF 0x00000000U /*!< LOCK OFF */ +#define TIM_LOCKLEVEL_1 TIM_BDTR_LOCK_0 /*!< LOCK Level 1 */ +#define TIM_LOCKLEVEL_2 TIM_BDTR_LOCK_1 /*!< LOCK Level 2 */ +#define TIM_LOCKLEVEL_3 TIM_BDTR_LOCK /*!< LOCK Level 3 */ +/** + * @} + */ + +/** @defgroup TIM_Break_Input_enable_disable TIM Break Input Enable + * @{ + */ +#define TIM_BREAK_ENABLE TIM_BDTR_BKE /*!< Break input BRK is enabled */ +#define TIM_BREAK_DISABLE 0x00000000U /*!< Break input BRK is disabled */ +/** + * @} + */ + +/** @defgroup TIM_Break_Polarity TIM Break Input Polarity + * @{ + */ +#define TIM_BREAKPOLARITY_LOW 0x00000000U /*!< Break input BRK is active low */ +#define TIM_BREAKPOLARITY_HIGH TIM_BDTR_BKP /*!< Break input BRK is active high */ +/** + * @} + */ + +/** @defgroup TIM_Break_Input_AF_Mode TIM Break Input Alternate Function Mode + * @{ + */ +#define TIM_BREAK_AFMODE_INPUT 0x00000000U /*!< Break input BRK in input mode */ +#define TIM_BREAK_AFMODE_BIDIRECTIONAL TIM_BDTR_BKBID /*!< Break input BRK in bidirectional mode */ +/** + * @} + */ + +/** @defgroup TIM_Break2_Input_enable_disable TIM Break input 2 Enable + * @{ + */ +#define TIM_BREAK2_DISABLE 0x00000000U /*!< Break input BRK2 is disabled */ +#define TIM_BREAK2_ENABLE TIM_BDTR_BK2E /*!< Break input BRK2 is enabled */ +/** + * @} + */ + +/** @defgroup TIM_Break2_Polarity TIM Break Input 2 Polarity + * @{ + */ +#define TIM_BREAK2POLARITY_LOW 0x00000000U /*!< Break input BRK2 is active low */ +#define TIM_BREAK2POLARITY_HIGH TIM_BDTR_BK2P /*!< Break input BRK2 is active high */ +/** + * @} + */ + +/** @defgroup TIM_Break2_Input_AF_Mode TIM Break2 Input Alternate Function Mode + * @{ + */ +#define TIM_BREAK2_AFMODE_INPUT 0x00000000U /*!< Break2 input BRK2 in input mode */ +#define TIM_BREAK2_AFMODE_BIDIRECTIONAL TIM_BDTR_BK2BID /*!< Break2 input BRK2 in bidirectional mode */ +/** + * @} + */ + +/** @defgroup TIM_AOE_Bit_Set_Reset TIM Automatic Output Enable + * @{ + */ +#define TIM_AUTOMATICOUTPUT_DISABLE 0x00000000U /*!< MOE can be set only by software */ +#define TIM_AUTOMATICOUTPUT_ENABLE TIM_BDTR_AOE /*!< MOE can be set by software or automatically at the next update event (if none of the break inputs BRK and BRK2 is active) */ +/** + * @} + */ + +/** @defgroup TIM_Group_Channel5 TIM Group Channel 5 and Channel 1, 2 or 3 + * @{ + */ +#define TIM_GROUPCH5_NONE 0x00000000U /*!< No effect of OC5REF on OC1REFC, OC2REFC and OC3REFC */ +#define TIM_GROUPCH5_OC1REFC TIM_CCR5_GC5C1 /*!< OC1REFC is the logical AND of OC1REFC and OC5REF */ +#define TIM_GROUPCH5_OC2REFC TIM_CCR5_GC5C2 /*!< OC2REFC is the logical AND of OC2REFC and OC5REF */ +#define TIM_GROUPCH5_OC3REFC TIM_CCR5_GC5C3 /*!< OC3REFC is the logical AND of OC3REFC and OC5REF */ +/** + * @} + */ + +/** @defgroup TIM_Master_Mode_Selection TIM Master Mode Selection + * @{ + */ +#define TIM_TRGO_RESET 0x00000000U /*!< TIMx_EGR.UG bit is used as trigger output (TRGO) */ +#define TIM_TRGO_ENABLE TIM_CR2_MMS_0 /*!< TIMx_CR1.CEN bit is used as trigger output (TRGO) */ +#define TIM_TRGO_UPDATE TIM_CR2_MMS_1 /*!< Update event is used as trigger output (TRGO) */ +#define TIM_TRGO_OC1 (TIM_CR2_MMS_1 | TIM_CR2_MMS_0) /*!< Capture or a compare match 1 is used as trigger output (TRGO) */ +#define TIM_TRGO_OC1REF TIM_CR2_MMS_2 /*!< OC1REF signal is used as trigger output (TRGO) */ +#define TIM_TRGO_OC2REF (TIM_CR2_MMS_2 | TIM_CR2_MMS_0) /*!< OC2REF signal is used as trigger output(TRGO) */ +#define TIM_TRGO_OC3REF (TIM_CR2_MMS_2 | TIM_CR2_MMS_1) /*!< OC3REF signal is used as trigger output(TRGO) */ +#define TIM_TRGO_OC4REF (TIM_CR2_MMS_2 | TIM_CR2_MMS_1 | TIM_CR2_MMS_0) /*!< OC4REF signal is used as trigger output(TRGO) */ +#define TIM_TRGO_ENCODER_CLK TIM_CR2_MMS_3 /*!< Encoder clock is used as trigger output(TRGO) */ +/** + * @} + */ + +/** @defgroup TIM_Master_Mode_Selection_2 TIM Master Mode Selection 2 (TRGO2) + * @{ + */ +#define TIM_TRGO2_RESET 0x00000000U /*!< TIMx_EGR.UG bit is used as trigger output (TRGO2) */ +#define TIM_TRGO2_ENABLE TIM_CR2_MMS2_0 /*!< TIMx_CR1.CEN bit is used as trigger output (TRGO2) */ +#define TIM_TRGO2_UPDATE TIM_CR2_MMS2_1 /*!< Update event is used as trigger output (TRGO2) */ +#define TIM_TRGO2_OC1 (TIM_CR2_MMS2_1 | TIM_CR2_MMS2_0) /*!< Capture or a compare match 1 is used as trigger output (TRGO2) */ +#define TIM_TRGO2_OC1REF TIM_CR2_MMS2_2 /*!< OC1REF signal is used as trigger output (TRGO2) */ +#define TIM_TRGO2_OC2REF (TIM_CR2_MMS2_2 | TIM_CR2_MMS2_0) /*!< OC2REF signal is used as trigger output (TRGO2) */ +#define TIM_TRGO2_OC3REF (TIM_CR2_MMS2_2 | TIM_CR2_MMS2_1) /*!< OC3REF signal is used as trigger output (TRGO2) */ +#define TIM_TRGO2_OC4REF (TIM_CR2_MMS2_2 | TIM_CR2_MMS2_1 | TIM_CR2_MMS2_0) /*!< OC4REF signal is used as trigger output (TRGO2) */ +#define TIM_TRGO2_OC5REF TIM_CR2_MMS2_3 /*!< OC5REF signal is used as trigger output (TRGO2) */ +#define TIM_TRGO2_OC6REF (TIM_CR2_MMS2_3 | TIM_CR2_MMS2_0) /*!< OC6REF signal is used as trigger output (TRGO2) */ +#define TIM_TRGO2_OC4REF_RISINGFALLING (TIM_CR2_MMS2_3 | TIM_CR2_MMS2_1) /*!< OC4REF rising or falling edges generate pulses on TRGO2 */ +#define TIM_TRGO2_OC6REF_RISINGFALLING (TIM_CR2_MMS2_3 | TIM_CR2_MMS2_1 | TIM_CR2_MMS2_0) /*!< OC6REF rising or falling edges generate pulses on TRGO2 */ +#define TIM_TRGO2_OC4REF_RISING_OC6REF_RISING (TIM_CR2_MMS2_3 | TIM_CR2_MMS2_2) /*!< OC4REF or OC6REF rising edges generate pulses on TRGO2 */ +#define TIM_TRGO2_OC4REF_RISING_OC6REF_FALLING (TIM_CR2_MMS2_3 | TIM_CR2_MMS2_2 | TIM_CR2_MMS2_0) /*!< OC4REF rising or OC6REF falling edges generate pulses on TRGO2 */ +#define TIM_TRGO2_OC5REF_RISING_OC6REF_RISING (TIM_CR2_MMS2_3 | TIM_CR2_MMS2_2 |TIM_CR2_MMS2_1) /*!< OC5REF or OC6REF rising edges generate pulses on TRGO2 */ +#define TIM_TRGO2_OC5REF_RISING_OC6REF_FALLING (TIM_CR2_MMS2_3 | TIM_CR2_MMS2_2 | TIM_CR2_MMS2_1 | TIM_CR2_MMS2_0) /*!< OC5REF or OC6REF rising edges generate pulses on TRGO2 */ +/** + * @} + */ + +/** @defgroup TIM_Master_Slave_Mode TIM Master/Slave Mode + * @{ + */ +#define TIM_MASTERSLAVEMODE_ENABLE TIM_SMCR_MSM /*!< No action */ +#define TIM_MASTERSLAVEMODE_DISABLE 0x00000000U /*!< Master/slave mode is selected */ +/** + * @} + */ + +/** @defgroup TIM_Slave_Mode TIM Slave mode + * @{ + */ +#define TIM_SLAVEMODE_DISABLE 0x00000000U /*!< Slave mode disabled */ +#define TIM_SLAVEMODE_RESET TIM_SMCR_SMS_2 /*!< Reset Mode */ +#define TIM_SLAVEMODE_GATED (TIM_SMCR_SMS_2 | TIM_SMCR_SMS_0) /*!< Gated Mode */ +#define TIM_SLAVEMODE_TRIGGER (TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1) /*!< Trigger Mode */ +#define TIM_SLAVEMODE_EXTERNAL1 (TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0) /*!< External Clock Mode 1 */ +#define TIM_SLAVEMODE_COMBINED_RESETTRIGGER TIM_SMCR_SMS_3 /*!< Combined reset + trigger mode */ +#define TIM_SLAVEMODE_COMBINED_GATEDRESET (TIM_SMCR_SMS_3 | TIM_SMCR_SMS_0) /*!< Combined gated + reset mode */ +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_and_PWM_modes TIM Output Compare and PWM Modes + * @{ + */ +#define TIM_OCMODE_TIMING 0x00000000U /*!< Frozen */ +#define TIM_OCMODE_ACTIVE TIM_CCMR1_OC1M_0 /*!< Set channel to active level on match */ +#define TIM_OCMODE_INACTIVE TIM_CCMR1_OC1M_1 /*!< Set channel to inactive level on match */ +#define TIM_OCMODE_TOGGLE (TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0) /*!< Toggle */ +#define TIM_OCMODE_PWM1 (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1) /*!< PWM mode 1 */ +#define TIM_OCMODE_PWM2 (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0) /*!< PWM mode 2 */ +#define TIM_OCMODE_FORCED_ACTIVE (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0) /*!< Force active level */ +#define TIM_OCMODE_FORCED_INACTIVE TIM_CCMR1_OC1M_2 /*!< Force inactive level */ +#define TIM_OCMODE_RETRIGERRABLE_OPM1 TIM_CCMR1_OC1M_3 /*!< Retrigerrable OPM mode 1 */ +#define TIM_OCMODE_RETRIGERRABLE_OPM2 (TIM_CCMR1_OC1M_3 | TIM_CCMR1_OC1M_0) /*!< Retrigerrable OPM mode 2 */ +#define TIM_OCMODE_COMBINED_PWM1 (TIM_CCMR1_OC1M_3 | TIM_CCMR1_OC1M_2) /*!< Combined PWM mode 1 */ +#define TIM_OCMODE_COMBINED_PWM2 (TIM_CCMR1_OC1M_3 | TIM_CCMR1_OC1M_0 | TIM_CCMR1_OC1M_2) /*!< Combined PWM mode 2 */ +#define TIM_OCMODE_ASSYMETRIC_PWM1 (TIM_CCMR1_OC1M_3 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2) /*!< Asymmetric PWM mode 1 */ +#define TIM_OCMODE_ASSYMETRIC_PWM2 TIM_CCMR1_OC1M /*!< Asymmetric PWM mode 2 */ +#define TIM_OCMODE_PULSE_ON_COMPARE (TIM_CCMR2_OC3M_3 | TIM_CCMR2_OC3M_1) /*!< Pulse on compare (CH3&CH4 only) */ +#define TIM_OCMODE_DIRECTION_OUTPUT (TIM_CCMR2_OC3M_3 | TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_0) /*!< Direction output (CH3&CH4 only) */ +/** + * @} + */ + +/** @defgroup TIM_Trigger_Selection TIM Trigger Selection + * @{ + */ +#define TIM_TS_ITR0 0x00000000U /*!< Internal Trigger 0 (ITR0) */ +#define TIM_TS_ITR1 TIM_SMCR_TS_0 /*!< Internal Trigger 1 (ITR1) */ +#define TIM_TS_ITR2 TIM_SMCR_TS_1 /*!< Internal Trigger 2 (ITR2) */ +#define TIM_TS_ITR3 (TIM_SMCR_TS_0 | TIM_SMCR_TS_1) /*!< Internal Trigger 3 (ITR3) */ +#define TIM_TS_ITR4 (TIM_SMCR_TS_3) /*!< Internal Trigger 4 (ITR4) */ +#define TIM_TS_ITR5 (TIM_SMCR_TS_0 | TIM_SMCR_TS_3) /*!< Internal Trigger 5 (ITR5) */ +#define TIM_TS_ITR6 (TIM_SMCR_TS_1 | TIM_SMCR_TS_3) /*!< Internal Trigger 6 (ITR6) */ +#define TIM_TS_ITR7 (TIM_SMCR_TS_0 | TIM_SMCR_TS_1 | TIM_SMCR_TS_3) /*!< Internal Trigger 7 (ITR7) */ +#define TIM_TS_ITR8 (TIM_SMCR_TS_2 | TIM_SMCR_TS_3) /*!< Internal Trigger 8 (ITR8) */ +#define TIM_TS_ITR9 (TIM_SMCR_TS_0 | TIM_SMCR_TS_2 | TIM_SMCR_TS_3) /*!< Internal Trigger 9 (ITR9) */ +#define TIM_TS_ITR10 (TIM_SMCR_TS_1 | TIM_SMCR_TS_2 | TIM_SMCR_TS_3) /*!< Internal Trigger 10 (ITR10) */ +#define TIM_TS_ITR11 (TIM_SMCR_TS_0 | TIM_SMCR_TS_1 | TIM_SMCR_TS_2 | TIM_SMCR_TS_3) /*!< Internal Trigger 11 (ITR11) */ +#define TIM_TS_ITR12 (TIM_SMCR_TS_4) /*!< Internal Trigger 12 (ITR12) */ +#define TIM_TS_TI1F_ED TIM_SMCR_TS_2 /*!< TI1 Edge Detector (TI1F_ED) */ +#define TIM_TS_TI1FP1 (TIM_SMCR_TS_0 | TIM_SMCR_TS_2) /*!< Filtered Timer Input 1 (TI1FP1) */ +#define TIM_TS_TI2FP2 (TIM_SMCR_TS_1 | TIM_SMCR_TS_2) /*!< Filtered Timer Input 2 (TI2FP2) */ +#define TIM_TS_ETRF (TIM_SMCR_TS_0 | TIM_SMCR_TS_1 | TIM_SMCR_TS_2) /*!< Filtered External Trigger input (ETRF) */ +#define TIM_TS_NONE 0x0000FFFFU /*!< No trigger selected */ +/** + * @} + */ + +/** @defgroup TIM_Trigger_Polarity TIM Trigger Polarity + * @{ + */ +#define TIM_TRIGGERPOLARITY_INVERTED TIM_ETRPOLARITY_INVERTED /*!< Polarity for ETRx trigger sources */ +#define TIM_TRIGGERPOLARITY_NONINVERTED TIM_ETRPOLARITY_NONINVERTED /*!< Polarity for ETRx trigger sources */ +#define TIM_TRIGGERPOLARITY_RISING TIM_INPUTCHANNELPOLARITY_RISING /*!< Polarity for TIxFPx or TI1_ED trigger sources */ +#define TIM_TRIGGERPOLARITY_FALLING TIM_INPUTCHANNELPOLARITY_FALLING /*!< Polarity for TIxFPx or TI1_ED trigger sources */ +#define TIM_TRIGGERPOLARITY_BOTHEDGE TIM_INPUTCHANNELPOLARITY_BOTHEDGE /*!< Polarity for TIxFPx or TI1_ED trigger sources */ +/** + * @} + */ + +/** @defgroup TIM_Trigger_Prescaler TIM Trigger Prescaler + * @{ + */ +#define TIM_TRIGGERPRESCALER_DIV1 TIM_ETRPRESCALER_DIV1 /*!< No prescaler is used */ +#define TIM_TRIGGERPRESCALER_DIV2 TIM_ETRPRESCALER_DIV2 /*!< Prescaler for External ETR Trigger: Capture performed once every 2 events. */ +#define TIM_TRIGGERPRESCALER_DIV4 TIM_ETRPRESCALER_DIV4 /*!< Prescaler for External ETR Trigger: Capture performed once every 4 events. */ +#define TIM_TRIGGERPRESCALER_DIV8 TIM_ETRPRESCALER_DIV8 /*!< Prescaler for External ETR Trigger: Capture performed once every 8 events. */ +/** + * @} + */ + +/** @defgroup TIM_TI1_Selection TIM TI1 Input Selection + * @{ + */ +#define TIM_TI1SELECTION_CH1 0x00000000U /*!< The TIMx_CH1 pin is connected to TI1 input */ +#define TIM_TI1SELECTION_XORCOMBINATION TIM_CR2_TI1S /*!< The TIMx_CH1, CH2 and CH3 pins are connected to the TI1 input (XOR combination) */ +/** + * @} + */ + +/** @defgroup TIM_DMA_Burst_Length TIM DMA Burst Length + * @{ + */ +#define TIM_DMABURSTLENGTH_1TRANSFER 0x00000000U /*!< The transfer is done to 1 register starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_2TRANSFERS 0x00000100U /*!< The transfer is done to 2 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_3TRANSFERS 0x00000200U /*!< The transfer is done to 3 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_4TRANSFERS 0x00000300U /*!< The transfer is done to 4 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_5TRANSFERS 0x00000400U /*!< The transfer is done to 5 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_6TRANSFERS 0x00000500U /*!< The transfer is done to 6 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_7TRANSFERS 0x00000600U /*!< The transfer is done to 7 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_8TRANSFERS 0x00000700U /*!< The transfer is done to 8 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_9TRANSFERS 0x00000800U /*!< The transfer is done to 9 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_10TRANSFERS 0x00000900U /*!< The transfer is done to 10 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_11TRANSFERS 0x00000A00U /*!< The transfer is done to 11 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_12TRANSFERS 0x00000B00U /*!< The transfer is done to 12 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_13TRANSFERS 0x00000C00U /*!< The transfer is done to 13 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_14TRANSFERS 0x00000D00U /*!< The transfer is done to 14 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_15TRANSFERS 0x00000E00U /*!< The transfer is done to 15 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_16TRANSFERS 0x00000F00U /*!< The transfer is done to 16 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_17TRANSFERS 0x00001000U /*!< The transfer is done to 17 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_18TRANSFERS 0x00001100U /*!< The transfer is done to 18 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_19TRANSFERS 0x00001200U /*!< The transfer is done to 19 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_20TRANSFERS 0x00001300U /*!< The transfer is done to 20 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_21TRANSFERS 0x00001400U /*!< The transfer is done to 21 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_22TRANSFERS 0x00001500U /*!< The transfer is done to 22 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_23TRANSFERS 0x00001600U /*!< The transfer is done to 23 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_24TRANSFERS 0x00001700U /*!< The transfer is done to 24 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_25TRANSFERS 0x00001800U /*!< The transfer is done to 25 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_26TRANSFERS 0x00001900U /*!< The transfer is done to 26 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +/** + * @} + */ + +/** @defgroup DMA_Handle_index TIM DMA Handle Index + * @{ + */ +#define TIM_DMA_ID_UPDATE ((uint16_t) 0x0000) /*!< Index of the DMA handle used for Update DMA requests */ +#define TIM_DMA_ID_CC1 ((uint16_t) 0x0001) /*!< Index of the DMA handle used for Capture/Compare 1 DMA requests */ +#define TIM_DMA_ID_CC2 ((uint16_t) 0x0002) /*!< Index of the DMA handle used for Capture/Compare 2 DMA requests */ +#define TIM_DMA_ID_CC3 ((uint16_t) 0x0003) /*!< Index of the DMA handle used for Capture/Compare 3 DMA requests */ +#define TIM_DMA_ID_CC4 ((uint16_t) 0x0004) /*!< Index of the DMA handle used for Capture/Compare 4 DMA requests */ +#define TIM_DMA_ID_COMMUTATION ((uint16_t) 0x0005) /*!< Index of the DMA handle used for Commutation DMA requests */ +#define TIM_DMA_ID_TRIGGER ((uint16_t) 0x0006) /*!< Index of the DMA handle used for Trigger DMA requests */ +/** + * @} + */ + +/** @defgroup Channel_CC_State TIM Capture/Compare Channel State + * @{ + */ +#define TIM_CCx_ENABLE 0x00000001U /*!< Input or output channel is enabled */ +#define TIM_CCx_DISABLE 0x00000000U /*!< Input or output channel is disabled */ +#define TIM_CCxN_ENABLE 0x00000004U /*!< Complementary output channel is enabled */ +#define TIM_CCxN_DISABLE 0x00000000U /*!< Complementary output channel is enabled */ +/** + * @} + */ + +/** @defgroup TIM_Break_System TIM Break System + * @{ + */ +#define TIM_BREAK_SYSTEM_ECC SBS_CFGR2_ECCL /*!< Enables and locks the ECC error signal with Break Input of TIM1/8/15/16/17/20 */ +#define TIM_BREAK_SYSTEM_PVD SBS_CFGR2_PVDL /*!< Enables and locks the PVD connection with TIM1/8/15/16/17/20 Break Input and also the PVDE and PLS bits of the Power Control Interface */ +#define TIM_BREAK_SYSTEM_SRAM_PARITY_ERROR SBS_CFGR2_SEL /*!< Enables and locks the SRAM_PARITY error signal with Break Input of TIM1/8/15/16/17/20 */ +#define TIM_BREAK_SYSTEM_LOCKUP SBS_CFGR2_CLL /*!< Enables and locks the LOCKUP output of CortexM4 with Break Input of TIM1/8/15/16/17/20 */ +/** + * @} + */ + +/** + * @} + */ +/* End of exported constants -------------------------------------------------*/ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup TIM_Exported_Macros TIM Exported Macros + * @{ + */ + +/** @brief Reset TIM handle state. + * @param __HANDLE__ TIM handle. + * @retval None + */ +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) +#define __HAL_TIM_RESET_HANDLE_STATE(__HANDLE__) do { \ + (__HANDLE__)->State = HAL_TIM_STATE_RESET; \ + (__HANDLE__)->ChannelState[0] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelState[1] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelState[2] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelState[3] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelState[4] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelState[5] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelNState[0] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelNState[1] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelNState[2] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelNState[3] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->DMABurstState = HAL_DMA_BURST_STATE_RESET; \ + (__HANDLE__)->Base_MspInitCallback = NULL; \ + (__HANDLE__)->Base_MspDeInitCallback = NULL; \ + (__HANDLE__)->IC_MspInitCallback = NULL; \ + (__HANDLE__)->IC_MspDeInitCallback = NULL; \ + (__HANDLE__)->OC_MspInitCallback = NULL; \ + (__HANDLE__)->OC_MspDeInitCallback = NULL; \ + (__HANDLE__)->PWM_MspInitCallback = NULL; \ + (__HANDLE__)->PWM_MspDeInitCallback = NULL; \ + (__HANDLE__)->OnePulse_MspInitCallback = NULL; \ + (__HANDLE__)->OnePulse_MspDeInitCallback = NULL; \ + (__HANDLE__)->Encoder_MspInitCallback = NULL; \ + (__HANDLE__)->Encoder_MspDeInitCallback = NULL; \ + (__HANDLE__)->HallSensor_MspInitCallback = NULL; \ + (__HANDLE__)->HallSensor_MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_TIM_RESET_HANDLE_STATE(__HANDLE__) do { \ + (__HANDLE__)->State = HAL_TIM_STATE_RESET; \ + (__HANDLE__)->ChannelState[0] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelState[1] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelState[2] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelState[3] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelState[4] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelState[5] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelNState[0] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelNState[1] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelNState[2] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelNState[3] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->DMABurstState = HAL_DMA_BURST_STATE_RESET; \ + } while(0) +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + +/** + * @brief Enable the TIM peripheral. + * @param __HANDLE__ TIM handle + * @retval None + */ +#define __HAL_TIM_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1|=(TIM_CR1_CEN)) + +/** + * @brief Enable the TIM main Output. + * @param __HANDLE__ TIM handle + * @retval None + */ +#define __HAL_TIM_MOE_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->BDTR|=(TIM_BDTR_MOE)) + +/** + * @brief Disable the TIM peripheral. + * @param __HANDLE__ TIM handle + * @retval None + */ +#define __HAL_TIM_DISABLE(__HANDLE__) \ + do { \ + if (((__HANDLE__)->Instance->CCER & TIM_CCER_CCxE_MASK) == 0UL) \ + { \ + if(((__HANDLE__)->Instance->CCER & TIM_CCER_CCxNE_MASK) == 0UL) \ + { \ + (__HANDLE__)->Instance->CR1 &= ~(TIM_CR1_CEN); \ + } \ + } \ + } while(0) + +/** + * @brief Disable the TIM main Output. + * @param __HANDLE__ TIM handle + * @retval None + * @note The Main Output Enable of a timer instance is disabled only if all the CCx and CCxN channels have been + * disabled + */ +#define __HAL_TIM_MOE_DISABLE(__HANDLE__) \ + do { \ + if (((__HANDLE__)->Instance->CCER & TIM_CCER_CCxE_MASK) == 0UL) \ + { \ + if(((__HANDLE__)->Instance->CCER & TIM_CCER_CCxNE_MASK) == 0UL) \ + { \ + (__HANDLE__)->Instance->BDTR &= ~(TIM_BDTR_MOE); \ + } \ + } \ + } while(0) + +/** + * @brief Disable the TIM main Output. + * @param __HANDLE__ TIM handle + * @retval None + * @note The Main Output Enable of a timer instance is disabled unconditionally + */ +#define __HAL_TIM_MOE_DISABLE_UNCONDITIONALLY(__HANDLE__) (__HANDLE__)->Instance->BDTR &= ~(TIM_BDTR_MOE) + +/** @brief Enable the specified TIM interrupt. + * @param __HANDLE__ specifies the TIM Handle. + * @param __INTERRUPT__ specifies the TIM interrupt source to enable. + * This parameter can be one of the following values: + * @arg TIM_IT_UPDATE: Update interrupt + * @arg TIM_IT_CC1: Capture/Compare 1 interrupt + * @arg TIM_IT_CC2: Capture/Compare 2 interrupt + * @arg TIM_IT_CC3: Capture/Compare 3 interrupt + * @arg TIM_IT_CC4: Capture/Compare 4 interrupt + * @arg TIM_IT_COM: Commutation interrupt + * @arg TIM_IT_TRIGGER: Trigger interrupt + * @arg TIM_IT_BREAK: Break interrupt + * @arg TIM_IT_IDX: Index interrupt + * @arg TIM_IT_DIR: Direction change interrupt + * @arg TIM_IT_IERR: Index error interrupt + * @arg TIM_IT_TERR: Transition error interrupt + * @retval None + */ +#define __HAL_TIM_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DIER |= (__INTERRUPT__)) + +/** @brief Disable the specified TIM interrupt. + * @param __HANDLE__ specifies the TIM Handle. + * @param __INTERRUPT__ specifies the TIM interrupt source to disable. + * This parameter can be one of the following values: + * @arg TIM_IT_UPDATE: Update interrupt + * @arg TIM_IT_CC1: Capture/Compare 1 interrupt + * @arg TIM_IT_CC2: Capture/Compare 2 interrupt + * @arg TIM_IT_CC3: Capture/Compare 3 interrupt + * @arg TIM_IT_CC4: Capture/Compare 4 interrupt + * @arg TIM_IT_COM: Commutation interrupt + * @arg TIM_IT_TRIGGER: Trigger interrupt + * @arg TIM_IT_BREAK: Break interrupt + * @arg TIM_IT_IDX: Index interrupt + * @arg TIM_IT_DIR: Direction change interrupt + * @arg TIM_IT_IERR: Index error interrupt + * @arg TIM_IT_TERR: Transition error interrupt + * @retval None + */ +#define __HAL_TIM_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DIER &= ~(__INTERRUPT__)) + +/** @brief Enable the specified DMA request. + * @param __HANDLE__ specifies the TIM Handle. + * @param __DMA__ specifies the TIM DMA request to enable. + * This parameter can be one of the following values: + * @arg TIM_DMA_UPDATE: Update DMA request + * @arg TIM_DMA_CC1: Capture/Compare 1 DMA request + * @arg TIM_DMA_CC2: Capture/Compare 2 DMA request + * @arg TIM_DMA_CC3: Capture/Compare 3 DMA request + * @arg TIM_DMA_CC4: Capture/Compare 4 DMA request + * @arg TIM_DMA_COM: Commutation DMA request + * @arg TIM_DMA_TRIGGER: Trigger DMA request + * @retval None + */ +#define __HAL_TIM_ENABLE_DMA(__HANDLE__, __DMA__) ((__HANDLE__)->Instance->DIER |= (__DMA__)) + +/** @brief Disable the specified DMA request. + * @param __HANDLE__ specifies the TIM Handle. + * @param __DMA__ specifies the TIM DMA request to disable. + * This parameter can be one of the following values: + * @arg TIM_DMA_UPDATE: Update DMA request + * @arg TIM_DMA_CC1: Capture/Compare 1 DMA request + * @arg TIM_DMA_CC2: Capture/Compare 2 DMA request + * @arg TIM_DMA_CC3: Capture/Compare 3 DMA request + * @arg TIM_DMA_CC4: Capture/Compare 4 DMA request + * @arg TIM_DMA_COM: Commutation DMA request + * @arg TIM_DMA_TRIGGER: Trigger DMA request + * @retval None + */ +#define __HAL_TIM_DISABLE_DMA(__HANDLE__, __DMA__) ((__HANDLE__)->Instance->DIER &= ~(__DMA__)) + +/** @brief Check whether the specified TIM interrupt flag is set or not. + * @param __HANDLE__ specifies the TIM Handle. + * @param __FLAG__ specifies the TIM interrupt flag to check. + * This parameter can be one of the following values: + * @arg TIM_FLAG_UPDATE: Update interrupt flag + * @arg TIM_FLAG_CC1: Capture/Compare 1 interrupt flag + * @arg TIM_FLAG_CC2: Capture/Compare 2 interrupt flag + * @arg TIM_FLAG_CC3: Capture/Compare 3 interrupt flag + * @arg TIM_FLAG_CC4: Capture/Compare 4 interrupt flag + * @arg TIM_FLAG_CC5: Compare 5 interrupt flag + * @arg TIM_FLAG_CC6: Compare 6 interrupt flag + * @arg TIM_FLAG_COM: Commutation interrupt flag + * @arg TIM_FLAG_TRIGGER: Trigger interrupt flag + * @arg TIM_FLAG_BREAK: Break interrupt flag + * @arg TIM_FLAG_BREAK2: Break 2 interrupt flag + * @arg TIM_FLAG_SYSTEM_BREAK: System Break interrupt flag + * @arg TIM_FLAG_CC1OF: Capture/Compare 1 overcapture flag + * @arg TIM_FLAG_CC2OF: Capture/Compare 2 overcapture flag + * @arg TIM_FLAG_CC3OF: Capture/Compare 3 overcapture flag + * @arg TIM_FLAG_CC4OF: Capture/Compare 4 overcapture flag + * @arg TIM_FLAG_IDX: Index interrupt flag + * @arg TIM_FLAG_DIR: Direction change interrupt flag + * @arg TIM_FLAG_IERR: Index error interrupt flag + * @arg TIM_FLAG_TERR: Transition error interrupt flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_TIM_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR &(__FLAG__)) == (__FLAG__)) + +/** @brief Clear the specified TIM interrupt flag. + * @param __HANDLE__ specifies the TIM Handle. + * @param __FLAG__ specifies the TIM interrupt flag to clear. + * This parameter can be one of the following values: + * @arg TIM_FLAG_UPDATE: Update interrupt flag + * @arg TIM_FLAG_CC1: Capture/Compare 1 interrupt flag + * @arg TIM_FLAG_CC2: Capture/Compare 2 interrupt flag + * @arg TIM_FLAG_CC3: Capture/Compare 3 interrupt flag + * @arg TIM_FLAG_CC4: Capture/Compare 4 interrupt flag + * @arg TIM_FLAG_CC5: Compare 5 interrupt flag + * @arg TIM_FLAG_CC6: Compare 6 interrupt flag + * @arg TIM_FLAG_COM: Commutation interrupt flag + * @arg TIM_FLAG_TRIGGER: Trigger interrupt flag + * @arg TIM_FLAG_BREAK: Break interrupt flag + * @arg TIM_FLAG_BREAK2: Break 2 interrupt flag + * @arg TIM_FLAG_SYSTEM_BREAK: System Break interrupt flag + * @arg TIM_FLAG_CC1OF: Capture/Compare 1 overcapture flag + * @arg TIM_FLAG_CC2OF: Capture/Compare 2 overcapture flag + * @arg TIM_FLAG_CC3OF: Capture/Compare 3 overcapture flag + * @arg TIM_FLAG_CC4OF: Capture/Compare 4 overcapture flag + * @arg TIM_FLAG_IDX: Index interrupt flag + * @arg TIM_FLAG_DIR: Direction change interrupt flag + * @arg TIM_FLAG_IERR: Index error interrupt flag + * @arg TIM_FLAG_TERR: Transition error interrupt flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_TIM_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR = ~(__FLAG__)) + +/** + * @brief Check whether the specified TIM interrupt source is enabled or not. + * @param __HANDLE__ TIM handle + * @param __INTERRUPT__ specifies the TIM interrupt source to check. + * This parameter can be one of the following values: + * @arg TIM_IT_UPDATE: Update interrupt + * @arg TIM_IT_CC1: Capture/Compare 1 interrupt + * @arg TIM_IT_CC2: Capture/Compare 2 interrupt + * @arg TIM_IT_CC3: Capture/Compare 3 interrupt + * @arg TIM_IT_CC4: Capture/Compare 4 interrupt + * @arg TIM_IT_COM: Commutation interrupt + * @arg TIM_IT_TRIGGER: Trigger interrupt + * @arg TIM_IT_BREAK: Break interrupt + * @arg TIM_IT_IDX: Index interrupt + * @arg TIM_IT_DIR: Direction change interrupt + * @arg TIM_IT_IERR: Index error interrupt + * @arg TIM_IT_TERR: Transition error interrupt + * @retval The state of TIM_IT (SET or RESET). + */ +#define __HAL_TIM_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->DIER & (__INTERRUPT__)) \ + == (__INTERRUPT__)) ? SET : RESET) + +/** @brief Clear the TIM interrupt pending bits. + * @param __HANDLE__ TIM handle + * @param __INTERRUPT__ specifies the interrupt pending bit to clear. + * This parameter can be one of the following values: + * @arg TIM_IT_UPDATE: Update interrupt + * @arg TIM_IT_CC1: Capture/Compare 1 interrupt + * @arg TIM_IT_CC2: Capture/Compare 2 interrupt + * @arg TIM_IT_CC3: Capture/Compare 3 interrupt + * @arg TIM_IT_CC4: Capture/Compare 4 interrupt + * @arg TIM_IT_COM: Commutation interrupt + * @arg TIM_IT_TRIGGER: Trigger interrupt + * @arg TIM_IT_BREAK: Break interrupt + * @arg TIM_IT_IDX: Index interrupt + * @arg TIM_IT_DIR: Direction change interrupt + * @arg TIM_IT_IERR: Index error interrupt + * @arg TIM_IT_TERR: Transition error interrupt + * @retval None + */ +#define __HAL_TIM_CLEAR_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->SR = ~(__INTERRUPT__)) + +/** + * @brief Force a continuous copy of the update interrupt flag (UIF) into the timer counter register (bit 31). + * @note This allows both the counter value and a potential roll-over condition signalled by the UIFCPY flag to be read + * in an atomic way. + * @param __HANDLE__ TIM handle. + * @retval None +mode. + */ +#define __HAL_TIM_UIFREMAP_ENABLE(__HANDLE__) (((__HANDLE__)->Instance->CR1 |= TIM_CR1_UIFREMAP)) + +/** + * @brief Disable update interrupt flag (UIF) remapping. + * @param __HANDLE__ TIM handle. + * @retval None +mode. + */ +#define __HAL_TIM_UIFREMAP_DISABLE(__HANDLE__) (((__HANDLE__)->Instance->CR1 &= ~TIM_CR1_UIFREMAP)) + +/** + * @brief Get update interrupt flag (UIF) copy status. + * @param __COUNTER__ Counter value. + * @retval The state of UIFCPY (TRUE or FALSE). +mode. + */ +#define __HAL_TIM_GET_UIFCPY(__COUNTER__) (((__COUNTER__) & (TIM_CNT_UIFCPY)) == (TIM_CNT_UIFCPY)) + +/** + * @brief Indicates whether or not the TIM Counter is used as downcounter. + * @param __HANDLE__ TIM handle. + * @retval False (Counter used as upcounter) or True (Counter used as downcounter) + * @note This macro is particularly useful to get the counting mode when the timer operates in Center-aligned mode + * or Encoder mode. + */ +#define __HAL_TIM_IS_TIM_COUNTING_DOWN(__HANDLE__) (((__HANDLE__)->Instance->CR1 &(TIM_CR1_DIR)) == (TIM_CR1_DIR)) + +/** + * @brief Set the TIM Prescaler on runtime. + * @param __HANDLE__ TIM handle. + * @param __PRESC__ specifies the Prescaler new value. + * @retval None + */ +#define __HAL_TIM_SET_PRESCALER(__HANDLE__, __PRESC__) ((__HANDLE__)->Instance->PSC = (__PRESC__)) + +/** + * @brief Set the TIM Counter Register value on runtime. + * Note Please check if the bit 31 of CNT register is used as UIF copy or not, this may affect the counter range in + * case of 32 bits counter TIM instance. + * Bit 31 of CNT can be enabled/disabled using __HAL_TIM_UIFREMAP_ENABLE()/__HAL_TIM_UIFREMAP_DISABLE() macros. + * @param __HANDLE__ TIM handle. + * @param __COUNTER__ specifies the Counter register new value. + * @retval None + */ +#define __HAL_TIM_SET_COUNTER(__HANDLE__, __COUNTER__) ((__HANDLE__)->Instance->CNT = (__COUNTER__)) + +/** + * @brief Get the TIM Counter Register value on runtime. + * @param __HANDLE__ TIM handle. + * @retval 16-bit or 32-bit value of the timer counter register (TIMx_CNT) + */ +#define __HAL_TIM_GET_COUNTER(__HANDLE__) ((__HANDLE__)->Instance->CNT) + +/** + * @brief Set the TIM Autoreload Register value on runtime without calling another time any Init function. + * @param __HANDLE__ TIM handle. + * @param __AUTORELOAD__ specifies the Counter register new value. + * @retval None + */ +#define __HAL_TIM_SET_AUTORELOAD(__HANDLE__, __AUTORELOAD__) \ + do{ \ + (__HANDLE__)->Instance->ARR = (__AUTORELOAD__); \ + (__HANDLE__)->Init.Period = (__AUTORELOAD__); \ + } while(0) + +/** + * @brief Get the TIM Autoreload Register value on runtime. + * @param __HANDLE__ TIM handle. + * @retval 16-bit or 32-bit value of the timer auto-reload register(TIMx_ARR) + */ +#define __HAL_TIM_GET_AUTORELOAD(__HANDLE__) ((__HANDLE__)->Instance->ARR) + +/** + * @brief Set the TIM Clock Division value on runtime without calling another time any Init function. + * @param __HANDLE__ TIM handle. + * @param __CKD__ specifies the clock division value. + * This parameter can be one of the following value: + * @arg TIM_CLOCKDIVISION_DIV1: tDTS=tCK_INT + * @arg TIM_CLOCKDIVISION_DIV2: tDTS=2*tCK_INT + * @arg TIM_CLOCKDIVISION_DIV4: tDTS=4*tCK_INT + * @retval None + */ +#define __HAL_TIM_SET_CLOCKDIVISION(__HANDLE__, __CKD__) \ + do{ \ + (__HANDLE__)->Instance->CR1 &= (~TIM_CR1_CKD); \ + (__HANDLE__)->Instance->CR1 |= (__CKD__); \ + (__HANDLE__)->Init.ClockDivision = (__CKD__); \ + } while(0) + +/** + * @brief Get the TIM Clock Division value on runtime. + * @param __HANDLE__ TIM handle. + * @retval The clock division can be one of the following values: + * @arg TIM_CLOCKDIVISION_DIV1: tDTS=tCK_INT + * @arg TIM_CLOCKDIVISION_DIV2: tDTS=2*tCK_INT + * @arg TIM_CLOCKDIVISION_DIV4: tDTS=4*tCK_INT + */ +#define __HAL_TIM_GET_CLOCKDIVISION(__HANDLE__) ((__HANDLE__)->Instance->CR1 & TIM_CR1_CKD) + +/** + * @brief Set the TIM Input Capture prescaler on runtime without calling another time HAL_TIM_IC_ConfigChannel() + * function. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param __ICPSC__ specifies the Input Capture4 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_DIV1: no prescaler + * @arg TIM_ICPSC_DIV2: capture is done once every 2 events + * @arg TIM_ICPSC_DIV4: capture is done once every 4 events + * @arg TIM_ICPSC_DIV8: capture is done once every 8 events + * @retval None + */ +#define __HAL_TIM_SET_ICPRESCALER(__HANDLE__, __CHANNEL__, __ICPSC__) \ + do{ \ + TIM_RESET_ICPRESCALERVALUE((__HANDLE__), (__CHANNEL__)); \ + TIM_SET_ICPRESCALERVALUE((__HANDLE__), (__CHANNEL__), (__ICPSC__)); \ + } while(0) + +/** + * @brief Get the TIM Input Capture prescaler on runtime. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: get input capture 1 prescaler value + * @arg TIM_CHANNEL_2: get input capture 2 prescaler value + * @arg TIM_CHANNEL_3: get input capture 3 prescaler value + * @arg TIM_CHANNEL_4: get input capture 4 prescaler value + * @retval The input capture prescaler can be one of the following values: + * @arg TIM_ICPSC_DIV1: no prescaler + * @arg TIM_ICPSC_DIV2: capture is done once every 2 events + * @arg TIM_ICPSC_DIV4: capture is done once every 4 events + * @arg TIM_ICPSC_DIV8: capture is done once every 8 events + */ +#define __HAL_TIM_GET_ICPRESCALER(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 & TIM_CCMR1_IC1PSC) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? (((__HANDLE__)->Instance->CCMR1 & TIM_CCMR1_IC2PSC) >> 8U) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 & TIM_CCMR2_IC3PSC) :\ + (((__HANDLE__)->Instance->CCMR2 & TIM_CCMR2_IC4PSC)) >> 8U) + +/** + * @brief Set the TIM Capture Compare Register value on runtime without calling another time ConfigChannel function. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @arg TIM_CHANNEL_5: TIM Channel 5 selected + * @arg TIM_CHANNEL_6: TIM Channel 6 selected + * @param __COMPARE__ specifies the Capture Compare register new value. + * @retval None + */ +#define __HAL_TIM_SET_COMPARE(__HANDLE__, __CHANNEL__, __COMPARE__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCR1 = (__COMPARE__)) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCR2 = (__COMPARE__)) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCR3 = (__COMPARE__)) :\ + ((__CHANNEL__) == TIM_CHANNEL_4) ? ((__HANDLE__)->Instance->CCR4 = (__COMPARE__)) :\ + ((__CHANNEL__) == TIM_CHANNEL_5) ? ((__HANDLE__)->Instance->CCR5 = (__COMPARE__)) :\ + ((__HANDLE__)->Instance->CCR6 = (__COMPARE__))) + +/** + * @brief Get the TIM Capture Compare Register value on runtime. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channel associated with the capture compare register + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: get capture/compare 1 register value + * @arg TIM_CHANNEL_2: get capture/compare 2 register value + * @arg TIM_CHANNEL_3: get capture/compare 3 register value + * @arg TIM_CHANNEL_4: get capture/compare 4 register value + * @arg TIM_CHANNEL_5: get capture/compare 5 register value + * @arg TIM_CHANNEL_6: get capture/compare 6 register value + * @retval 16-bit or 32-bit value of the capture/compare register (TIMx_CCRy) + */ +#define __HAL_TIM_GET_COMPARE(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCR1) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCR2) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCR3) :\ + ((__CHANNEL__) == TIM_CHANNEL_4) ? ((__HANDLE__)->Instance->CCR4) :\ + ((__CHANNEL__) == TIM_CHANNEL_5) ? ((__HANDLE__)->Instance->CCR5) :\ + ((__HANDLE__)->Instance->CCR6)) + +/** + * @brief Set the TIM Output compare preload. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @arg TIM_CHANNEL_5: TIM Channel 5 selected + * @arg TIM_CHANNEL_6: TIM Channel 6 selected + * @retval None + */ +#define __HAL_TIM_ENABLE_OCxPRELOAD(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 |= TIM_CCMR1_OC1PE) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 |= TIM_CCMR1_OC2PE) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 |= TIM_CCMR2_OC3PE) :\ + ((__CHANNEL__) == TIM_CHANNEL_4) ? ((__HANDLE__)->Instance->CCMR2 |= TIM_CCMR2_OC4PE) :\ + ((__CHANNEL__) == TIM_CHANNEL_5) ? ((__HANDLE__)->Instance->CCMR3 |= TIM_CCMR3_OC5PE) :\ + ((__HANDLE__)->Instance->CCMR3 |= TIM_CCMR3_OC6PE)) + +/** + * @brief Reset the TIM Output compare preload. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @arg TIM_CHANNEL_5: TIM Channel 5 selected + * @arg TIM_CHANNEL_6: TIM Channel 6 selected + * @retval None + */ +#define __HAL_TIM_DISABLE_OCxPRELOAD(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_OC1PE) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_OC2PE) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_OC3PE) :\ + ((__CHANNEL__) == TIM_CHANNEL_4) ? ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_OC4PE) :\ + ((__CHANNEL__) == TIM_CHANNEL_5) ? ((__HANDLE__)->Instance->CCMR3 &= ~TIM_CCMR3_OC5PE) :\ + ((__HANDLE__)->Instance->CCMR3 &= ~TIM_CCMR3_OC6PE)) + +/** + * @brief Enable fast mode for a given channel. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @arg TIM_CHANNEL_5: TIM Channel 5 selected + * @arg TIM_CHANNEL_6: TIM Channel 6 selected + * @note When fast mode is enabled an active edge on the trigger input acts + * like a compare match on CCx output. Delay to sample the trigger + * input and to activate CCx output is reduced to 3 clock cycles. + * @note Fast mode acts only if the channel is configured in PWM1 or PWM2 mode. + * @retval None + */ +#define __HAL_TIM_ENABLE_OCxFAST(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 |= TIM_CCMR1_OC1FE) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 |= TIM_CCMR1_OC2FE) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 |= TIM_CCMR2_OC3FE) :\ + ((__CHANNEL__) == TIM_CHANNEL_4) ? ((__HANDLE__)->Instance->CCMR2 |= TIM_CCMR2_OC4FE) :\ + ((__CHANNEL__) == TIM_CHANNEL_5) ? ((__HANDLE__)->Instance->CCMR3 |= TIM_CCMR3_OC5FE) :\ + ((__HANDLE__)->Instance->CCMR3 |= TIM_CCMR3_OC6FE)) + +/** + * @brief Disable fast mode for a given channel. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @arg TIM_CHANNEL_5: TIM Channel 5 selected + * @arg TIM_CHANNEL_6: TIM Channel 6 selected + * @note When fast mode is disabled CCx output behaves normally depending + * on counter and CCRx values even when the trigger is ON. The minimum + * delay to activate CCx output when an active edge occurs on the + * trigger input is 5 clock cycles. + * @retval None + */ +#define __HAL_TIM_DISABLE_OCxFAST(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_OC1FE) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_OC2FE) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_OC3FE) :\ + ((__CHANNEL__) == TIM_CHANNEL_4) ? ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_OC4FE) :\ + ((__CHANNEL__) == TIM_CHANNEL_5) ? ((__HANDLE__)->Instance->CCMR3 &= ~TIM_CCMR3_OC5FE) :\ + ((__HANDLE__)->Instance->CCMR3 &= ~TIM_CCMR3_OC6FE)) + +/** + * @brief Set the Update Request Source (URS) bit of the TIMx_CR1 register. + * @param __HANDLE__ TIM handle. + * @note When the URS bit of the TIMx_CR1 register is set, only counter + * overflow/underflow generates an update interrupt or DMA request (if + * enabled) + * @retval None + */ +#define __HAL_TIM_URS_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1|= TIM_CR1_URS) + +/** + * @brief Reset the Update Request Source (URS) bit of the TIMx_CR1 register. + * @param __HANDLE__ TIM handle. + * @note When the URS bit of the TIMx_CR1 register is reset, any of the + * following events generate an update interrupt or DMA request (if + * enabled): + * _ Counter overflow underflow + * _ Setting the UG bit + * _ Update generation through the slave mode controller + * @retval None + */ +#define __HAL_TIM_URS_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1&=~TIM_CR1_URS) + +/** + * @brief Set the TIM Capture x input polarity on runtime. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param __POLARITY__ Polarity for TIx source + * @arg TIM_INPUTCHANNELPOLARITY_RISING: Rising Edge + * @arg TIM_INPUTCHANNELPOLARITY_FALLING: Falling Edge + * @arg TIM_INPUTCHANNELPOLARITY_BOTHEDGE: Rising and Falling Edge + * @retval None + */ +#define __HAL_TIM_SET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__, __POLARITY__) \ + do{ \ + TIM_RESET_CAPTUREPOLARITY((__HANDLE__), (__CHANNEL__)); \ + TIM_SET_CAPTUREPOLARITY((__HANDLE__), (__CHANNEL__), (__POLARITY__)); \ + }while(0) + +/** @brief Select the Capture/compare DMA request source. + * @param __HANDLE__ specifies the TIM Handle. + * @param __CCDMA__ specifies Capture/compare DMA request source + * This parameter can be one of the following values: + * @arg TIM_CCDMAREQUEST_CC: CCx DMA request generated on Capture/Compare event + * @arg TIM_CCDMAREQUEST_UPDATE: CCx DMA request generated on Update event + * @retval None + */ +#define __HAL_TIM_SELECT_CCDMAREQUEST(__HANDLE__, __CCDMA__) \ + MODIFY_REG((__HANDLE__)->Instance->CR2, TIM_CR2_CCDS, (__CCDMA__)) + +/** + * @} + */ +/* End of exported macros ----------------------------------------------------*/ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup TIM_Private_Constants TIM Private Constants + * @{ + */ +/* The counter of a timer instance is disabled only if all the CCx and CCxN + channels have been disabled */ +#define TIM_CCER_CCxE_MASK ((uint32_t)(TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC4E)) +#define TIM_CCER_CCxNE_MASK ((uint32_t)(TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE | TIM_CCER_CC4NE)) +/** + * @} + */ +/* End of private constants --------------------------------------------------*/ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup TIM_Private_Macros TIM Private Macros + * @{ + */ +#define IS_TIM_CLEARINPUT_SOURCE(__MODE__) (((__MODE__) == TIM_CLEARINPUTSOURCE_NONE) || \ + ((__MODE__) == TIM_CLEARINPUTSOURCE_ETR) || \ + ((__MODE__) == TIM_CLEARINPUTSOURCE_OCREFCLR)) + +#define IS_TIM_DMA_BASE(__BASE__) (((__BASE__) == TIM_DMABASE_CR1) || \ + ((__BASE__) == TIM_DMABASE_CR2) || \ + ((__BASE__) == TIM_DMABASE_SMCR) || \ + ((__BASE__) == TIM_DMABASE_DIER) || \ + ((__BASE__) == TIM_DMABASE_SR) || \ + ((__BASE__) == TIM_DMABASE_EGR) || \ + ((__BASE__) == TIM_DMABASE_CCMR1) || \ + ((__BASE__) == TIM_DMABASE_CCMR2) || \ + ((__BASE__) == TIM_DMABASE_CCER) || \ + ((__BASE__) == TIM_DMABASE_CNT) || \ + ((__BASE__) == TIM_DMABASE_PSC) || \ + ((__BASE__) == TIM_DMABASE_ARR) || \ + ((__BASE__) == TIM_DMABASE_RCR) || \ + ((__BASE__) == TIM_DMABASE_CCR1) || \ + ((__BASE__) == TIM_DMABASE_CCR2) || \ + ((__BASE__) == TIM_DMABASE_CCR3) || \ + ((__BASE__) == TIM_DMABASE_CCR4) || \ + ((__BASE__) == TIM_DMABASE_BDTR) || \ + ((__BASE__) == TIM_DMABASE_CCMR3) || \ + ((__BASE__) == TIM_DMABASE_CCR5) || \ + ((__BASE__) == TIM_DMABASE_CCR6) || \ + ((__BASE__) == TIM_DMABASE_AF1) || \ + ((__BASE__) == TIM_DMABASE_AF2) || \ + ((__BASE__) == TIM_DMABASE_TISEL) || \ + ((__BASE__) == TIM_DMABASE_DTR2) || \ + ((__BASE__) == TIM_DMABASE_ECR)) + +#define IS_TIM_EVENT_SOURCE(__SOURCE__) ((((__SOURCE__) & 0xFFFFFE00U) == 0x00000000U) && ((__SOURCE__) != 0x00000000U)) + +#define IS_TIM_COUNTER_MODE(__MODE__) (((__MODE__) == TIM_COUNTERMODE_UP) || \ + ((__MODE__) == TIM_COUNTERMODE_DOWN) || \ + ((__MODE__) == TIM_COUNTERMODE_CENTERALIGNED1) || \ + ((__MODE__) == TIM_COUNTERMODE_CENTERALIGNED2) || \ + ((__MODE__) == TIM_COUNTERMODE_CENTERALIGNED3)) + +#define IS_TIM_UIFREMAP_MODE(__MODE__) (((__MODE__) == TIM_UIFREMAP_DISABLE) || \ + ((__MODE__) == TIM_UIFREMAP_ENABLE)) + +#define IS_TIM_CLOCKDIVISION_DIV(__DIV__) (((__DIV__) == TIM_CLOCKDIVISION_DIV1) || \ + ((__DIV__) == TIM_CLOCKDIVISION_DIV2) || \ + ((__DIV__) == TIM_CLOCKDIVISION_DIV4)) + +#define IS_TIM_AUTORELOAD_PRELOAD(PRELOAD) (((PRELOAD) == TIM_AUTORELOAD_PRELOAD_DISABLE) || \ + ((PRELOAD) == TIM_AUTORELOAD_PRELOAD_ENABLE)) + +#define IS_TIM_FAST_STATE(__STATE__) (((__STATE__) == TIM_OCFAST_DISABLE) || \ + ((__STATE__) == TIM_OCFAST_ENABLE)) + +#define IS_TIM_OC_POLARITY(__POLARITY__) (((__POLARITY__) == TIM_OCPOLARITY_HIGH) || \ + ((__POLARITY__) == TIM_OCPOLARITY_LOW)) + +#define IS_TIM_OCN_POLARITY(__POLARITY__) (((__POLARITY__) == TIM_OCNPOLARITY_HIGH) || \ + ((__POLARITY__) == TIM_OCNPOLARITY_LOW)) + +#define IS_TIM_OCIDLE_STATE(__STATE__) (((__STATE__) == TIM_OCIDLESTATE_SET) || \ + ((__STATE__) == TIM_OCIDLESTATE_RESET)) + +#define IS_TIM_OCNIDLE_STATE(__STATE__) (((__STATE__) == TIM_OCNIDLESTATE_SET) || \ + ((__STATE__) == TIM_OCNIDLESTATE_RESET)) + +#define IS_TIM_ENCODERINPUT_POLARITY(__POLARITY__) (((__POLARITY__) == TIM_ENCODERINPUTPOLARITY_RISING) || \ + ((__POLARITY__) == TIM_ENCODERINPUTPOLARITY_FALLING)) + +#define IS_TIM_IC_POLARITY(__POLARITY__) (((__POLARITY__) == TIM_ICPOLARITY_RISING) || \ + ((__POLARITY__) == TIM_ICPOLARITY_FALLING) || \ + ((__POLARITY__) == TIM_ICPOLARITY_BOTHEDGE)) + +#define IS_TIM_IC_SELECTION(__SELECTION__) (((__SELECTION__) == TIM_ICSELECTION_DIRECTTI) || \ + ((__SELECTION__) == TIM_ICSELECTION_INDIRECTTI) || \ + ((__SELECTION__) == TIM_ICSELECTION_TRC)) + +#define IS_TIM_IC_PRESCALER(__PRESCALER__) (((__PRESCALER__) == TIM_ICPSC_DIV1) || \ + ((__PRESCALER__) == TIM_ICPSC_DIV2) || \ + ((__PRESCALER__) == TIM_ICPSC_DIV4) || \ + ((__PRESCALER__) == TIM_ICPSC_DIV8)) + +#define IS_TIM_CCX_CHANNEL(__INSTANCE__, __CHANNEL__) (IS_TIM_CCX_INSTANCE(__INSTANCE__, __CHANNEL__) && \ + ((__CHANNEL__) != (TIM_CHANNEL_5)) && \ + ((__CHANNEL__) != (TIM_CHANNEL_6))) + +#define IS_TIM_OPM_MODE(__MODE__) (((__MODE__) == TIM_OPMODE_SINGLE) || \ + ((__MODE__) == TIM_OPMODE_REPETITIVE)) + +#define IS_TIM_ENCODER_MODE(__MODE__) (((__MODE__) == TIM_ENCODERMODE_TI1) || \ + ((__MODE__) == TIM_ENCODERMODE_TI2) || \ + ((__MODE__) == TIM_ENCODERMODE_TI12) || \ + ((__MODE__) == TIM_ENCODERMODE_CLOCKPLUSDIRECTION_X2) || \ + ((__MODE__) == TIM_ENCODERMODE_CLOCKPLUSDIRECTION_X1) || \ + ((__MODE__) == TIM_ENCODERMODE_DIRECTIONALCLOCK_X2) || \ + ((__MODE__) == TIM_ENCODERMODE_DIRECTIONALCLOCK_X1_TI12) || \ + ((__MODE__) == TIM_ENCODERMODE_X1_TI1) || \ + ((__MODE__) == TIM_ENCODERMODE_X1_TI2)) + +#define IS_TIM_DMA_SOURCE(__SOURCE__) ((((__SOURCE__) & 0xFFFF80FFU) == 0x00000000U) && ((__SOURCE__) != 0x00000000U)) + +#define IS_TIM_CHANNELS(__CHANNEL__) (((__CHANNEL__) == TIM_CHANNEL_1) || \ + ((__CHANNEL__) == TIM_CHANNEL_2) || \ + ((__CHANNEL__) == TIM_CHANNEL_3) || \ + ((__CHANNEL__) == TIM_CHANNEL_4) || \ + ((__CHANNEL__) == TIM_CHANNEL_5) || \ + ((__CHANNEL__) == TIM_CHANNEL_6) || \ + ((__CHANNEL__) == TIM_CHANNEL_ALL)) + +#define IS_TIM_OPM_CHANNELS(__CHANNEL__) (((__CHANNEL__) == TIM_CHANNEL_1) || \ + ((__CHANNEL__) == TIM_CHANNEL_2)) + +#define IS_TIM_PERIOD(__HANDLE__, __PERIOD__) \ + ((IS_TIM_32B_COUNTER_INSTANCE(((__HANDLE__)->Instance)) == 0U) ? (((__PERIOD__) > 0U) && ((__PERIOD__) <= 0x0000FFFFU)) : ((__PERIOD__) > 0U)) + +#define IS_TIM_COMPLEMENTARY_CHANNELS(__CHANNEL__) (((__CHANNEL__) == TIM_CHANNEL_1) || \ + ((__CHANNEL__) == TIM_CHANNEL_2) || \ + ((__CHANNEL__) == TIM_CHANNEL_3) || \ + ((__CHANNEL__) == TIM_CHANNEL_4)) + +#define IS_TIM_CLOCKSOURCE(__CLOCK__) (((__CLOCK__) == TIM_CLOCKSOURCE_INTERNAL) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1ED) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR0) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR3) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR4) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR5) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR6) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR7) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR8) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR9) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR10) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR11) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR12)) + +#define IS_TIM_CLOCKPOLARITY(__POLARITY__) (((__POLARITY__) == TIM_CLOCKPOLARITY_INVERTED) || \ + ((__POLARITY__) == TIM_CLOCKPOLARITY_NONINVERTED) || \ + ((__POLARITY__) == TIM_CLOCKPOLARITY_RISING) || \ + ((__POLARITY__) == TIM_CLOCKPOLARITY_FALLING) || \ + ((__POLARITY__) == TIM_CLOCKPOLARITY_BOTHEDGE)) + +#define IS_TIM_CLOCKPRESCALER(__PRESCALER__) (((__PRESCALER__) == TIM_CLOCKPRESCALER_DIV1) || \ + ((__PRESCALER__) == TIM_CLOCKPRESCALER_DIV2) || \ + ((__PRESCALER__) == TIM_CLOCKPRESCALER_DIV4) || \ + ((__PRESCALER__) == TIM_CLOCKPRESCALER_DIV8)) + +#define IS_TIM_CLOCKFILTER(__ICFILTER__) ((__ICFILTER__) <= 0xFU) + +#define IS_TIM_CLEARINPUT_POLARITY(__POLARITY__) (((__POLARITY__) == TIM_CLEARINPUTPOLARITY_INVERTED) || \ + ((__POLARITY__) == TIM_CLEARINPUTPOLARITY_NONINVERTED)) + +#define IS_TIM_CLEARINPUT_PRESCALER(__PRESCALER__) (((__PRESCALER__) == TIM_CLEARINPUTPRESCALER_DIV1) || \ + ((__PRESCALER__) == TIM_CLEARINPUTPRESCALER_DIV2) || \ + ((__PRESCALER__) == TIM_CLEARINPUTPRESCALER_DIV4) || \ + ((__PRESCALER__) == TIM_CLEARINPUTPRESCALER_DIV8)) + +#define IS_TIM_CLEARINPUT_FILTER(__ICFILTER__) ((__ICFILTER__) <= 0xFU) + +#define IS_TIM_OSSR_STATE(__STATE__) (((__STATE__) == TIM_OSSR_ENABLE) || \ + ((__STATE__) == TIM_OSSR_DISABLE)) + +#define IS_TIM_OSSI_STATE(__STATE__) (((__STATE__) == TIM_OSSI_ENABLE) || \ + ((__STATE__) == TIM_OSSI_DISABLE)) + +#define IS_TIM_LOCK_LEVEL(__LEVEL__) (((__LEVEL__) == TIM_LOCKLEVEL_OFF) || \ + ((__LEVEL__) == TIM_LOCKLEVEL_1) || \ + ((__LEVEL__) == TIM_LOCKLEVEL_2) || \ + ((__LEVEL__) == TIM_LOCKLEVEL_3)) + +#define IS_TIM_BREAK_FILTER(__BRKFILTER__) ((__BRKFILTER__) <= 0xFUL) + + +#define IS_TIM_BREAK_STATE(__STATE__) (((__STATE__) == TIM_BREAK_ENABLE) || \ + ((__STATE__) == TIM_BREAK_DISABLE)) + +#define IS_TIM_BREAK_POLARITY(__POLARITY__) (((__POLARITY__) == TIM_BREAKPOLARITY_LOW) || \ + ((__POLARITY__) == TIM_BREAKPOLARITY_HIGH)) + +#define IS_TIM_BREAK_AFMODE(__AFMODE__) (((__AFMODE__) == TIM_BREAK_AFMODE_INPUT) || \ + ((__AFMODE__) == TIM_BREAK_AFMODE_BIDIRECTIONAL)) + + +#define IS_TIM_BREAK2_STATE(__STATE__) (((__STATE__) == TIM_BREAK2_ENABLE) || \ + ((__STATE__) == TIM_BREAK2_DISABLE)) + +#define IS_TIM_BREAK2_POLARITY(__POLARITY__) (((__POLARITY__) == TIM_BREAK2POLARITY_LOW) || \ + ((__POLARITY__) == TIM_BREAK2POLARITY_HIGH)) + +#define IS_TIM_BREAK2_AFMODE(__AFMODE__) (((__AFMODE__) == TIM_BREAK2_AFMODE_INPUT) || \ + ((__AFMODE__) == TIM_BREAK2_AFMODE_BIDIRECTIONAL)) + + +#define IS_TIM_AUTOMATIC_OUTPUT_STATE(__STATE__) (((__STATE__) == TIM_AUTOMATICOUTPUT_ENABLE) || \ + ((__STATE__) == TIM_AUTOMATICOUTPUT_DISABLE)) + +#define IS_TIM_GROUPCH5(__OCREF__) ((((__OCREF__) & 0x1FFFFFFFU) == 0x00000000U)) + +#define IS_TIM_TRGO_SOURCE(__SOURCE__) (((__SOURCE__) == TIM_TRGO_RESET) || \ + ((__SOURCE__) == TIM_TRGO_ENABLE) || \ + ((__SOURCE__) == TIM_TRGO_UPDATE) || \ + ((__SOURCE__) == TIM_TRGO_OC1) || \ + ((__SOURCE__) == TIM_TRGO_OC1REF) || \ + ((__SOURCE__) == TIM_TRGO_OC2REF) || \ + ((__SOURCE__) == TIM_TRGO_OC3REF) || \ + ((__SOURCE__) == TIM_TRGO_OC4REF) || \ + ((__SOURCE__) == TIM_TRGO_ENCODER_CLK)) + +#define IS_TIM_TRGO2_SOURCE(__SOURCE__) (((__SOURCE__) == TIM_TRGO2_RESET) || \ + ((__SOURCE__) == TIM_TRGO2_ENABLE) || \ + ((__SOURCE__) == TIM_TRGO2_UPDATE) || \ + ((__SOURCE__) == TIM_TRGO2_OC1) || \ + ((__SOURCE__) == TIM_TRGO2_OC1REF) || \ + ((__SOURCE__) == TIM_TRGO2_OC2REF) || \ + ((__SOURCE__) == TIM_TRGO2_OC3REF) || \ + ((__SOURCE__) == TIM_TRGO2_OC3REF) || \ + ((__SOURCE__) == TIM_TRGO2_OC4REF) || \ + ((__SOURCE__) == TIM_TRGO2_OC5REF) || \ + ((__SOURCE__) == TIM_TRGO2_OC6REF) || \ + ((__SOURCE__) == TIM_TRGO2_OC4REF_RISINGFALLING) || \ + ((__SOURCE__) == TIM_TRGO2_OC6REF_RISINGFALLING) || \ + ((__SOURCE__) == TIM_TRGO2_OC4REF_RISING_OC6REF_RISING) || \ + ((__SOURCE__) == TIM_TRGO2_OC4REF_RISING_OC6REF_FALLING) || \ + ((__SOURCE__) == TIM_TRGO2_OC5REF_RISING_OC6REF_RISING) || \ + ((__SOURCE__) == TIM_TRGO2_OC5REF_RISING_OC6REF_FALLING)) + +#define IS_TIM_MSM_STATE(__STATE__) (((__STATE__) == TIM_MASTERSLAVEMODE_ENABLE) || \ + ((__STATE__) == TIM_MASTERSLAVEMODE_DISABLE)) + +#define IS_TIM_SLAVE_MODE(__MODE__) (((__MODE__) == TIM_SLAVEMODE_DISABLE) || \ + ((__MODE__) == TIM_SLAVEMODE_RESET) || \ + ((__MODE__) == TIM_SLAVEMODE_GATED) || \ + ((__MODE__) == TIM_SLAVEMODE_TRIGGER) || \ + ((__MODE__) == TIM_SLAVEMODE_EXTERNAL1) || \ + ((__MODE__) == TIM_SLAVEMODE_COMBINED_RESETTRIGGER) || \ + ((__MODE__) == TIM_SLAVEMODE_COMBINED_GATEDRESET)) + +#define IS_TIM_PWM_MODE(__MODE__) (((__MODE__) == TIM_OCMODE_PWM1) || \ + ((__MODE__) == TIM_OCMODE_PWM2) || \ + ((__MODE__) == TIM_OCMODE_COMBINED_PWM1) || \ + ((__MODE__) == TIM_OCMODE_COMBINED_PWM2) || \ + ((__MODE__) == TIM_OCMODE_ASSYMETRIC_PWM1) || \ + ((__MODE__) == TIM_OCMODE_ASSYMETRIC_PWM2)) + +#define IS_TIM_OC_MODE(__MODE__) (((__MODE__) == TIM_OCMODE_TIMING) || \ + ((__MODE__) == TIM_OCMODE_ACTIVE) || \ + ((__MODE__) == TIM_OCMODE_INACTIVE) || \ + ((__MODE__) == TIM_OCMODE_TOGGLE) || \ + ((__MODE__) == TIM_OCMODE_FORCED_ACTIVE) || \ + ((__MODE__) == TIM_OCMODE_FORCED_INACTIVE) || \ + ((__MODE__) == TIM_OCMODE_RETRIGERRABLE_OPM1) || \ + ((__MODE__) == TIM_OCMODE_RETRIGERRABLE_OPM2) || \ + ((__MODE__) == TIM_OCMODE_DIRECTION_OUTPUT) || \ + ((__MODE__) == TIM_OCMODE_PULSE_ON_COMPARE)) + +#define IS_TIM_TRIGGERPOLARITY(__POLARITY__) (((__POLARITY__) == TIM_TRIGGERPOLARITY_INVERTED ) || \ + ((__POLARITY__) == TIM_TRIGGERPOLARITY_NONINVERTED) || \ + ((__POLARITY__) == TIM_TRIGGERPOLARITY_RISING ) || \ + ((__POLARITY__) == TIM_TRIGGERPOLARITY_FALLING ) || \ + ((__POLARITY__) == TIM_TRIGGERPOLARITY_BOTHEDGE )) + +#define IS_TIM_TRIGGERPRESCALER(__PRESCALER__) (((__PRESCALER__) == TIM_TRIGGERPRESCALER_DIV1) || \ + ((__PRESCALER__) == TIM_TRIGGERPRESCALER_DIV2) || \ + ((__PRESCALER__) == TIM_TRIGGERPRESCALER_DIV4) || \ + ((__PRESCALER__) == TIM_TRIGGERPRESCALER_DIV8)) + +#define IS_TIM_TRIGGERFILTER(__ICFILTER__) ((__ICFILTER__) <= 0xFU) + +#define IS_TIM_TI1SELECTION(__TI1SELECTION__) (((__TI1SELECTION__) == TIM_TI1SELECTION_CH1) || \ + ((__TI1SELECTION__) == TIM_TI1SELECTION_XORCOMBINATION)) + +#define IS_TIM_DMA_LENGTH(__LENGTH__) (((__LENGTH__) == TIM_DMABURSTLENGTH_1TRANSFER) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_2TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_3TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_4TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_5TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_6TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_7TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_8TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_9TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_10TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_11TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_12TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_13TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_14TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_15TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_16TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_17TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_18TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_19TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_20TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_21TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_22TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_23TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_24TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_25TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_26TRANSFERS)) + +#define IS_TIM_DMA_DATA_LENGTH(LENGTH) (((LENGTH) >= 0x1U) && ((LENGTH) < 0x10000U)) + +#define IS_TIM_IC_FILTER(__ICFILTER__) ((__ICFILTER__) <= 0xFU) + +#define IS_TIM_DEADTIME(__DEADTIME__) ((__DEADTIME__) <= 0xFFU) + +#define IS_TIM_BREAK_SYSTEM(__CONFIG__) (((__CONFIG__) == TIM_BREAK_SYSTEM_ECC) || \ + ((__CONFIG__) == TIM_BREAK_SYSTEM_PVD) || \ + ((__CONFIG__) == TIM_BREAK_SYSTEM_SRAM_PARITY_ERROR) || \ + ((__CONFIG__) == TIM_BREAK_SYSTEM_LOCKUP)) + +#define IS_TIM_SLAVEMODE_TRIGGER_ENABLED(__TRIGGER__) (((__TRIGGER__) == TIM_SLAVEMODE_TRIGGER) || \ + ((__TRIGGER__) == TIM_SLAVEMODE_COMBINED_RESETTRIGGER)) + +#define TIM_SET_ICPRESCALERVALUE(__HANDLE__, __CHANNEL__, __ICPSC__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 |= (__ICPSC__)) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 |= ((__ICPSC__) << 8U)) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 |= (__ICPSC__)) :\ + ((__HANDLE__)->Instance->CCMR2 |= ((__ICPSC__) << 8U))) + +#define TIM_RESET_ICPRESCALERVALUE(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_IC2PSC) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_IC3PSC) :\ + ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_IC4PSC)) + +#define TIM_SET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__, __POLARITY__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCER |= (__POLARITY__)) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCER |= ((__POLARITY__) << 4U)) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCER |= ((__POLARITY__) << 8U)) :\ + ((__HANDLE__)->Instance->CCER |= (((__POLARITY__) << 12U)))) + +#define TIM_RESET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC1P | TIM_CCER_CC1NP)) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC2P | TIM_CCER_CC2NP)) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC3P | TIM_CCER_CC3NP)) :\ + ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC4P | TIM_CCER_CC4NP))) + +#define TIM_CHANNEL_STATE_GET(__HANDLE__, __CHANNEL__)\ + (((__CHANNEL__) == TIM_CHANNEL_1) ? (__HANDLE__)->ChannelState[0] :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? (__HANDLE__)->ChannelState[1] :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? (__HANDLE__)->ChannelState[2] :\ + ((__CHANNEL__) == TIM_CHANNEL_4) ? (__HANDLE__)->ChannelState[3] :\ + ((__CHANNEL__) == TIM_CHANNEL_5) ? (__HANDLE__)->ChannelState[4] :\ + (__HANDLE__)->ChannelState[5]) + +#define TIM_CHANNEL_STATE_SET(__HANDLE__, __CHANNEL__, __CHANNEL_STATE__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->ChannelState[0] = (__CHANNEL_STATE__)) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->ChannelState[1] = (__CHANNEL_STATE__)) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->ChannelState[2] = (__CHANNEL_STATE__)) :\ + ((__CHANNEL__) == TIM_CHANNEL_4) ? ((__HANDLE__)->ChannelState[3] = (__CHANNEL_STATE__)) :\ + ((__CHANNEL__) == TIM_CHANNEL_5) ? ((__HANDLE__)->ChannelState[4] = (__CHANNEL_STATE__)) :\ + ((__HANDLE__)->ChannelState[5] = (__CHANNEL_STATE__))) + +#define TIM_CHANNEL_STATE_SET_ALL(__HANDLE__, __CHANNEL_STATE__) do { \ + (__HANDLE__)->ChannelState[0] = \ + (__CHANNEL_STATE__); \ + (__HANDLE__)->ChannelState[1] = \ + (__CHANNEL_STATE__); \ + (__HANDLE__)->ChannelState[2] = \ + (__CHANNEL_STATE__); \ + (__HANDLE__)->ChannelState[3] = \ + (__CHANNEL_STATE__); \ + (__HANDLE__)->ChannelState[4] = \ + (__CHANNEL_STATE__); \ + (__HANDLE__)->ChannelState[5] = \ + (__CHANNEL_STATE__); \ + } while(0) + +#define TIM_CHANNEL_N_STATE_GET(__HANDLE__, __CHANNEL__)\ + (((__CHANNEL__) == TIM_CHANNEL_1) ? (__HANDLE__)->ChannelNState[0] :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? (__HANDLE__)->ChannelNState[1] :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? (__HANDLE__)->ChannelNState[2] :\ + (__HANDLE__)->ChannelNState[3]) + +#define TIM_CHANNEL_N_STATE_SET(__HANDLE__, __CHANNEL__, __CHANNEL_STATE__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->ChannelNState[0] = (__CHANNEL_STATE__)) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->ChannelNState[1] = (__CHANNEL_STATE__)) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->ChannelNState[2] = (__CHANNEL_STATE__)) :\ + ((__HANDLE__)->ChannelNState[3] = (__CHANNEL_STATE__))) + +#define TIM_CHANNEL_N_STATE_SET_ALL(__HANDLE__, __CHANNEL_STATE__) do { \ + (__HANDLE__)->ChannelNState[0] = \ + (__CHANNEL_STATE__); \ + (__HANDLE__)->ChannelNState[1] = \ + (__CHANNEL_STATE__); \ + (__HANDLE__)->ChannelNState[2] = \ + (__CHANNEL_STATE__); \ + (__HANDLE__)->ChannelNState[3] = \ + (__CHANNEL_STATE__); \ + } while(0) + +/** + * @} + */ +/* End of private macros -----------------------------------------------------*/ + +/* Include TIM HAL Extended module */ +#include "stm32h5xx_hal_tim_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup TIM_Exported_Functions TIM Exported Functions + * @{ + */ + +/** @addtogroup TIM_Exported_Functions_Group1 TIM Time Base functions + * @brief Time Base functions + * @{ + */ +/* Time Base functions ********************************************************/ +HAL_StatusTypeDef HAL_TIM_Base_Init(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIM_Base_DeInit(TIM_HandleTypeDef *htim); +void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim); +void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef *htim); +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIM_Base_Start(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIM_Base_Stop(TIM_HandleTypeDef *htim); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIM_Base_Stop_IT(TIM_HandleTypeDef *htim); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIM_Base_Start_DMA(TIM_HandleTypeDef *htim, const uint32_t *pData, uint16_t Length); +HAL_StatusTypeDef HAL_TIM_Base_Stop_DMA(TIM_HandleTypeDef *htim); +/** + * @} + */ + +/** @addtogroup TIM_Exported_Functions_Group2 TIM Output Compare functions + * @brief TIM Output Compare functions + * @{ + */ +/* Timer Output Compare functions *********************************************/ +HAL_StatusTypeDef HAL_TIM_OC_Init(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIM_OC_DeInit(TIM_HandleTypeDef *htim); +void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim); +void HAL_TIM_OC_MspDeInit(TIM_HandleTypeDef *htim); +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIM_OC_Start(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_OC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIM_OC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_OC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIM_OC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData, + uint16_t Length); +HAL_StatusTypeDef HAL_TIM_OC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); +/** + * @} + */ + +/** @addtogroup TIM_Exported_Functions_Group3 TIM PWM functions + * @brief TIM PWM functions + * @{ + */ +/* Timer PWM functions ********************************************************/ +HAL_StatusTypeDef HAL_TIM_PWM_Init(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIM_PWM_DeInit(TIM_HandleTypeDef *htim); +void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim); +void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef *htim); +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_PWM_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIM_PWM_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_PWM_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIM_PWM_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData, + uint16_t Length); +HAL_StatusTypeDef HAL_TIM_PWM_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); +/** + * @} + */ + +/** @addtogroup TIM_Exported_Functions_Group4 TIM Input Capture functions + * @brief TIM Input Capture functions + * @{ + */ +/* Timer Input Capture functions **********************************************/ +HAL_StatusTypeDef HAL_TIM_IC_Init(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIM_IC_DeInit(TIM_HandleTypeDef *htim); +void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim); +void HAL_TIM_IC_MspDeInit(TIM_HandleTypeDef *htim); +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIM_IC_Start(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_IC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIM_IC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_IC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIM_IC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length); +HAL_StatusTypeDef HAL_TIM_IC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); +/** + * @} + */ + +/** @addtogroup TIM_Exported_Functions_Group5 TIM One Pulse functions + * @brief TIM One Pulse functions + * @{ + */ +/* Timer One Pulse functions **************************************************/ +HAL_StatusTypeDef HAL_TIM_OnePulse_Init(TIM_HandleTypeDef *htim, uint32_t OnePulseMode); +HAL_StatusTypeDef HAL_TIM_OnePulse_DeInit(TIM_HandleTypeDef *htim); +void HAL_TIM_OnePulse_MspInit(TIM_HandleTypeDef *htim); +void HAL_TIM_OnePulse_MspDeInit(TIM_HandleTypeDef *htim); +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIM_OnePulse_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel); +HAL_StatusTypeDef HAL_TIM_OnePulse_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIM_OnePulse_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel); +HAL_StatusTypeDef HAL_TIM_OnePulse_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel); +/** + * @} + */ + +/** @addtogroup TIM_Exported_Functions_Group6 TIM Encoder functions + * @brief TIM Encoder functions + * @{ + */ +/* Timer Encoder functions ****************************************************/ +HAL_StatusTypeDef HAL_TIM_Encoder_Init(TIM_HandleTypeDef *htim, const TIM_Encoder_InitTypeDef *sConfig); +HAL_StatusTypeDef HAL_TIM_Encoder_DeInit(TIM_HandleTypeDef *htim); +void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim); +void HAL_TIM_Encoder_MspDeInit(TIM_HandleTypeDef *htim); +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIM_Encoder_Start(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_Encoder_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIM_Encoder_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_Encoder_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIM_Encoder_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData1, + uint32_t *pData2, uint16_t Length); +HAL_StatusTypeDef HAL_TIM_Encoder_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); +/** + * @} + */ + +/** @addtogroup TIM_Exported_Functions_Group7 TIM IRQ handler management + * @brief IRQ handler management + * @{ + */ +/* Interrupt Handler functions ***********************************************/ +void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim); +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group8 TIM Peripheral Control functions + * @brief Peripheral Control functions + * @{ + */ +/* Control functions *********************************************************/ +HAL_StatusTypeDef HAL_TIM_OC_ConfigChannel(TIM_HandleTypeDef *htim, const TIM_OC_InitTypeDef *sConfig, + uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_PWM_ConfigChannel(TIM_HandleTypeDef *htim, const TIM_OC_InitTypeDef *sConfig, + uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_IC_ConfigChannel(TIM_HandleTypeDef *htim, const TIM_IC_InitTypeDef *sConfig, + uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_OnePulse_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OnePulse_InitTypeDef *sConfig, + uint32_t OutputChannel, uint32_t InputChannel); +HAL_StatusTypeDef HAL_TIM_ConfigOCrefClear(TIM_HandleTypeDef *htim, + const TIM_ClearInputConfigTypeDef *sClearInputConfig, + uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_ConfigClockSource(TIM_HandleTypeDef *htim, const TIM_ClockConfigTypeDef *sClockSourceConfig); +HAL_StatusTypeDef HAL_TIM_ConfigTI1Input(TIM_HandleTypeDef *htim, uint32_t TI1_Selection); +HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchro(TIM_HandleTypeDef *htim, const TIM_SlaveConfigTypeDef *sSlaveConfig); +HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchro_IT(TIM_HandleTypeDef *htim, const TIM_SlaveConfigTypeDef *sSlaveConfig); +HAL_StatusTypeDef HAL_TIM_DMABurst_WriteStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, + uint32_t BurstRequestSrc, const uint32_t *BurstBuffer, uint32_t BurstLength); +HAL_StatusTypeDef HAL_TIM_DMABurst_MultiWriteStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, + uint32_t BurstRequestSrc, const uint32_t *BurstBuffer, + uint32_t BurstLength, uint32_t DataLength); +HAL_StatusTypeDef HAL_TIM_DMABurst_WriteStop(TIM_HandleTypeDef *htim, uint32_t BurstRequestSrc); +HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, + uint32_t BurstRequestSrc, uint32_t *BurstBuffer, uint32_t BurstLength); +HAL_StatusTypeDef HAL_TIM_DMABurst_MultiReadStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, + uint32_t BurstRequestSrc, uint32_t *BurstBuffer, + uint32_t BurstLength, uint32_t DataLength); +HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStop(TIM_HandleTypeDef *htim, uint32_t BurstRequestSrc); +HAL_StatusTypeDef HAL_TIM_GenerateEvent(TIM_HandleTypeDef *htim, uint32_t EventSource); +uint32_t HAL_TIM_ReadCapturedValue(const TIM_HandleTypeDef *htim, uint32_t Channel); +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group9 TIM Callbacks functions + * @brief TIM Callbacks functions + * @{ + */ +/* Callback in non blocking modes (Interrupt and DMA) *************************/ +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_PeriodElapsedHalfCpltCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_IC_CaptureHalfCpltCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_PWM_PulseFinishedHalfCpltCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_TriggerCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_TriggerHalfCpltCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_ErrorCallback(TIM_HandleTypeDef *htim); + +/* Callbacks Register/UnRegister functions ***********************************/ +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) +HAL_StatusTypeDef HAL_TIM_RegisterCallback(TIM_HandleTypeDef *htim, HAL_TIM_CallbackIDTypeDef CallbackID, + pTIM_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_TIM_UnRegisterCallback(TIM_HandleTypeDef *htim, HAL_TIM_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group10 TIM Peripheral State functions + * @brief Peripheral State functions + * @{ + */ +/* Peripheral State functions ************************************************/ +HAL_TIM_StateTypeDef HAL_TIM_Base_GetState(const TIM_HandleTypeDef *htim); +HAL_TIM_StateTypeDef HAL_TIM_OC_GetState(const TIM_HandleTypeDef *htim); +HAL_TIM_StateTypeDef HAL_TIM_PWM_GetState(const TIM_HandleTypeDef *htim); +HAL_TIM_StateTypeDef HAL_TIM_IC_GetState(const TIM_HandleTypeDef *htim); +HAL_TIM_StateTypeDef HAL_TIM_OnePulse_GetState(const TIM_HandleTypeDef *htim); +HAL_TIM_StateTypeDef HAL_TIM_Encoder_GetState(const TIM_HandleTypeDef *htim); + +/* Peripheral Channel state functions ************************************************/ +HAL_TIM_ActiveChannel HAL_TIM_GetActiveChannel(const TIM_HandleTypeDef *htim); +HAL_TIM_ChannelStateTypeDef HAL_TIM_GetChannelState(const TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_TIM_DMABurstStateTypeDef HAL_TIM_DMABurstState(const TIM_HandleTypeDef *htim); +/** + * @} + */ + +/** + * @} + */ +/* End of exported functions -------------------------------------------------*/ + +/* Private functions----------------------------------------------------------*/ +/** @defgroup TIM_Private_Functions TIM Private Functions + * @{ + */ +void TIM_Base_SetConfig(TIM_TypeDef *TIMx, const TIM_Base_InitTypeDef *Structure); +void TIM_TI1_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, uint32_t TIM_ICFilter); +void TIM_OC2_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config); +void TIM_ETR_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ExtTRGPrescaler, + uint32_t TIM_ExtTRGPolarity, uint32_t ExtTRGFilter); + +void TIM_DMADelayPulseHalfCplt(DMA_HandleTypeDef *hdma); +void TIM_DMAError(DMA_HandleTypeDef *hdma); +void TIM_DMACaptureCplt(DMA_HandleTypeDef *hdma); +void TIM_DMACaptureHalfCplt(DMA_HandleTypeDef *hdma); +void TIM_CCxChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelState); +HAL_StatusTypeDef TIM_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t src, uint32_t dst, + uint32_t length); + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) +void TIM_ResetCallback(TIM_HandleTypeDef *htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + +/** + * @} + */ +/* End of private functions --------------------------------------------------*/ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_TIM_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_tim_ex.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_tim_ex.h new file mode 100644 index 0000000000..e81d82f316 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_tim_ex.h @@ -0,0 +1,1247 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_tim_ex.h + * @author MCD Application Team + * @brief Header file of TIM HAL Extended module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_TIM_EX_H +#define STM32H5xx_HAL_TIM_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup TIMEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup TIMEx_Exported_Types TIM Extended Exported Types + * @{ + */ + +/** + * @brief TIM Hall sensor Configuration Structure definition + */ + +typedef struct +{ + uint32_t IC1Polarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Input_Capture_Polarity */ + + uint32_t IC1Prescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref TIM_Input_Capture_Prescaler */ + + uint32_t IC1Filter; /*!< Specifies the input capture filter. + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ + + uint32_t Commutation_Delay; /*!< Specifies the pulse value to be loaded into the Capture Compare Register. + This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */ +} TIM_HallSensor_InitTypeDef; + +/** + * @brief TIM Break/Break2 input configuration + */ +typedef struct +{ + uint32_t Source; /*!< Specifies the source of the timer break input. + This parameter can be a value of @ref TIMEx_Break_Input_Source */ + uint32_t Enable; /*!< Specifies whether or not the break input source is enabled. + This parameter can be a value of @ref TIMEx_Break_Input_Source_Enable */ + uint32_t Polarity; /*!< Specifies the break input source polarity. + This parameter can be a value of @ref TIMEx_Break_Input_Source_Polarity */ +} TIMEx_BreakInputConfigTypeDef; + +/** + * @brief TIM Encoder index configuration + */ +typedef struct +{ + uint32_t Polarity; /*!< TIM Encoder index polarity.This parameter can be a value of @ref TIMEx_Encoder_Index_Polarity */ + + uint32_t Prescaler; /*!< TIM Encoder index prescaler.This parameter can be a value of @ref TIMEx_Encoder_Index_Prescaler */ + + uint32_t Filter; /*!< TIM Encoder index filter.This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ + + uint32_t Blanking; /*!< Specifies whether or not the encoder index event is conditioned by TI3 or TI4 input.This parameter can be a value of @ref TIMEx_Encoder_Index_Blanking */ + + FunctionalState FirstIndexEnable; /*!< Specifies whether or not the encoder first index is enabled.This parameter value can be ENABLE or DISABLE. */ + + uint32_t Position; /*!< Specifies in which AB input configuration the index event resets the counter.This parameter can be a value of @ref TIMEx_Encoder_Index_Position */ + + uint32_t Direction; /*!< Specifies in which counter direction the index event resets the counter.This parameter can be a value of @ref TIMEx_Encoder_Index_Direction */ + +} TIMEx_EncoderIndexConfigTypeDef; + +/** + * @} + */ +/* End of exported types -----------------------------------------------------*/ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup TIMEx_Exported_Constants TIM Extended Exported Constants + * @{ + */ + +/** @defgroup TIMEx_Remap TIM Extended Remapping + * @{ + */ +#define TIM_TIM1_ETR_GPIO 0x00000000UL /*!< TIM1_ETR is not connected to I/O */ +#if defined(COMP1) +#define TIM_TIM1_ETR_COMP1 TIM1_AF1_ETRSEL_0 /*!< TIM1_ETR is connected to COMP1 output */ +#endif /* COMP1 */ +#define TIM_TIM1_ETR_ADC1_AWD1 (TIM1_AF1_ETRSEL_1 | TIM1_AF1_ETRSEL_0) /*!< TIM1_ETR is connected to ADC1 AWD1 */ +#define TIM_TIM1_ETR_ADC1_AWD2 TIM1_AF1_ETRSEL_2 /*!< TIM1_ETR is connected to ADC1 AWD2 */ +#define TIM_TIM1_ETR_ADC1_AWD3 (TIM1_AF1_ETRSEL_2 | TIM1_AF1_ETRSEL_0) /*!< TIM1_ETR is connected to ADC1 AWD3 */ + +#define TIM_TIM2_ETR_GPIO 0x00000000UL /*!< TIM2_ETR is not connected to I/O */ +#if defined(COMP1) +#define TIM_TIM2_ETR_COMP1 TIM1_AF1_ETRSEL_0 /*!< TIM2_ETR is connected to COMP1 output */ +#endif /* COMP1 */ +#define TIM_TIM2_ETR_LSE (TIM1_AF1_ETRSEL_0 | TIM1_AF1_ETRSEL_1) /*!< TIM2_ETR is connected to LSE */ +#if defined(SAI1) +#define TIM_TIM2_ETR_SAI1_FSA TIM1_AF1_ETRSEL_2 /*!< TIM2_ETR is connected to SAI1 FS_A */ +#define TIM_TIM2_ETR_SAI1_FSB (TIM1_AF1_ETRSEL_0 | TIM1_AF1_ETRSEL_2) /*!< TIM2_ETR is connected to SAI1 */ +#endif /* SAI1 */ +#define TIM_TIM2_ETR_TIM3_ETR (TIM1_AF1_ETRSEL_0 | TIM1_AF1_ETRSEL_3) /*!< TIM2_ETR is connected to TIM3 ETR */ +#if defined(TIM4) +#define TIM_TIM2_ETR_TIM4_ETR (TIM1_AF1_ETRSEL_1 | TIM1_AF1_ETRSEL_3) /*!< TIM2_ETR is connected to TIM4 ETR */ +#endif /* TIM4 */ +#if defined(TIM5) +#define TIM_TIM2_ETR_TIM5_ETR (TIM1_AF1_ETRSEL_0 | TIM1_AF1_ETRSEL_1| TIM1_AF1_ETRSEL_3 ) /*!< TIM2_ETR is connected to TIM5 ETR */ +#endif /* TIM5 */ +#if defined(ETH_NS) +#define TIM_TIM2_ETR_ETH_PPS (TIM1_AF1_ETRSEL_1| TIM1_AF1_ETRSEL_2 | TIM1_AF1_ETRSEL_3 ) /*!< TIM2_ETR is connected to ETH PPS */ +#endif /* ETH_NS */ + +#define TIM_TIM3_ETR_GPIO 0x00000000UL /*!< TIM3_ETR is not connected to I/O */ +#if defined(COMP1) +#define TIM_TIM3_ETR_COMP1 TIM1_AF1_ETRSEL_0 /*!< TIM3_ETR is connected to COMP1 output */ +#endif /* COMP1 */ +#define TIM_TIM3_ETR_TIM2_ETR TIM1_AF1_ETRSEL_3 /*!< TIM3_ETR is connected to TIM2 ETR */ +#if defined(TIM4) +#define TIM_TIM3_ETR_TIM4_ETR (TIM1_AF1_ETRSEL_3 | TIM1_AF1_ETRSEL_1) /*!< TIM3_ETR is connected to TIM4 ETR */ +#endif /* TIM4 */ +#if defined(TIM5) +#define TIM_TIM3_ETR_TIM5_ETR (TIM1_AF1_ETRSEL_3 | TIM1_AF1_ETRSEL_1| TIM1_AF1_ETRSEL_0) /*!< TIM3_ETR is connected to TIM5 ETR */ +#endif /* TIM5 */ +#if defined(ETH_NS) +#define TIM_TIM3_ETR_ETH_PPS (TIM1_AF1_ETRSEL_1| TIM1_AF1_ETRSEL_2 | TIM1_AF1_ETRSEL_3 ) /*!< TIM3_ETR is connected to ETH PPS */ +#endif /* ETH_NS */ + +#if defined(TIM4) +#define TIM_TIM4_ETR_GPIO 0x00000000UL /*!< TIM4_ETR is not connected to I/O */ +#define TIM_TIM4_ETR_TIM2_ETR TIM1_AF1_ETRSEL_3 /*!< TIM4_ETR is connected to TIM2 ETR */ +#define TIM_TIM4_ETR_TIM3_ETR (TIM1_AF1_ETRSEL_3 | TIM1_AF1_ETRSEL_0) /*!< TIM4_ETR is connected to TIM3 ETR */ +#define TIM_TIM4_ETR_TIM5_ETR (TIM1_AF1_ETRSEL_3 | TIM1_AF1_ETRSEL_1| TIM1_AF1_ETRSEL_0) /*!< TIM4_ETR is connected to TIM5 ETR */ +#endif /* TIM4 */ + +#if defined(TIM5) +#define TIM_TIM5_ETR_GPIO 0x00000000UL /*!< TIM5_ETR is not connected to I/O */ +#define TIM_TIM5_ETR_SAI2_FSA TIM1_AF1_ETRSEL_0 /*!< TIM5_ETR is connected to SAI2 */ +#define TIM_TIM5_ETR_SAI2_FSB TIM1_AF1_ETRSEL_1 /*!< TIM5_ETR is connected to SAI2 */ +#define TIM_TIM5_ETR_TIM2_ETR TIM1_AF1_ETRSEL_3 /*!< TIM5_ETR is connected to TIM2 ETR */ +#define TIM_TIM5_ETR_TIM3_ETR (TIM1_AF1_ETRSEL_3 | TIM1_AF1_ETRSEL_0) /*!< TIM5_ETR is connected to TIM3 ETR */ +#define TIM_TIM5_ETR_TIM4_ETR (TIM1_AF1_ETRSEL_3 | TIM1_AF1_ETRSEL_1) /*!< TIM5_ETR is connected to TIM4 ETR */ +#endif /* TIM5 */ + +#if defined(TIM8) +#define TIM_TIM8_ETR_GPIO 0x00000000UL /*!< TIM8_ETR is not connected to I/O */ +#define TIM_TIM8_ETR_ADC2_AWD1 (TIM1_AF1_ETRSEL_1 | TIM1_AF1_ETRSEL_0) /*!< TIM8_ETR is connected to ADC1 AWD1 */ +#define TIM_TIM8_ETR_ADC2_AWD2 TIM1_AF1_ETRSEL_2 /*!< TIM8_ETR is connected to ADC1 AWD2 */ +#define TIM_TIM8_ETR_ADC2_AWD3 (TIM1_AF1_ETRSEL_2 | TIM1_AF1_ETRSEL_0) /*!< TIM8_ETR is connected to ADC1 AWD3 */ +#endif /* TIM8 */ +/** + * @} + */ + +/** @defgroup TIMEx_Break_Input TIM Extended Break input + * @{ + */ +#define TIM_BREAKINPUT_BRK 0x00000001U /*!< Timer break input */ +#define TIM_BREAKINPUT_BRK2 0x00000002U /*!< Timer break2 input */ +/** + * @} + */ + +/** @defgroup TIMEx_Break_Input_Source TIM Extended Break input source + * @{ + */ +#define TIM_BREAKINPUTSOURCE_BKIN 0x00000001U /*!< An external source (GPIO) is connected to the BKIN pin */ +#if defined(COMP1) +#define TIM_BREAKINPUTSOURCE_COMP1 0x00000002U /*!< The COMP1 output is connected to the break input */ +#endif /* COMP1 */ +/** + * @} + */ + +/** @defgroup TIMEx_Break_Input_Source_Enable TIM Extended Break input source enabling + * @{ + */ +#define TIM_BREAKINPUTSOURCE_DISABLE 0x00000000U /*!< Break input source is disabled */ +#define TIM_BREAKINPUTSOURCE_ENABLE 0x00000001U /*!< Break input source is enabled */ +/** + * @} + */ + +/** @defgroup TIMEx_Break_Input_Source_Polarity TIM Extended Break input polarity + * @{ + */ +#define TIM_BREAKINPUTSOURCE_POLARITY_LOW 0x00000001U /*!< Break input source is active low */ +#define TIM_BREAKINPUTSOURCE_POLARITY_HIGH 0x00000000U /*!< Break input source is active_high */ +/** + * @} + */ + +/** @defgroup TIMEx_Timer_Input_Selection TIM Extended Timer input selection + * @{ + */ +#define TIM_TIM1_TI1_GPIO 0x00000000UL /*!< TIM1_TI1 is connected to GPIO */ +#if defined(COMP1) +#define TIM_TIM1_TI1_COMP1 TIM_TISEL_TI1SEL_0 /*!< TIM1_TI1 is connected to COMP1 OUT */ +#endif /* COMP1 */ +#define TIM_TIM1_TI2_GPIO 0x00000000UL /*!< TIM1_TI2 is connected to GPIO */ +#define TIM_TIM1_TI3_GPIO 0x00000000UL /*!< TIM1_TI3 is connected to GPIO */ +#define TIM_TIM1_TI4_GPIO 0x00000000UL /*!< TIM1_TI4 is connected to GPIO */ + +#define TIM_TIM2_TI1_GPIO 0x00000000UL /*!< TIM2_TI1 is connected to GPIO */ +#if defined(STM32H503xx) +#define TIM_TIM2_TI1_LSI TIM_TISEL_TI1SEL_0 /*!< TIM2_TI1 is connected to LSI */ +#define TIM_TIM2_TI1_LSE TIM_TISEL_TI1SEL_1 /*!< TIM2_TI1 is connected to LSE */ +#define TIM_TIM2_TI1_RTC_WKUP (TIM_TISEL_TI1SEL_1 | TIM_TISEL_TI1SEL_0) /*!< TIM2_TI1 is connected to RTC */ +#define TIM_TIM2_TI1_TIM3_TI1 TIM_TISEL_TI1SEL_2 /*!< TIM2_TI1 is connected to TIM3 TI1 */ +#endif /* STM32H503xx */ +#if defined(ETH_NS) +#define TIM_TIM2_TI1_ETH_PPS TIM_TISEL_TI1SEL_0 /*!< TIM2_TI1 is connected to ETH PPS */ +#endif /* ETH_NS */ +#define TIM_TIM2_TI2_GPIO 0x00000000UL /*!< TIM2_TI2 is connected to GPIO */ +#if defined(STM32H503xx) +#define TIM_TIM2_TI2_HSI_1024 TIM_TISEL_TI2SEL_0 /*!< TIM2_TI2 is connected to HSI_1024 */ +#define TIM_TIM2_TI2_CSI_128 TIM_TISEL_TI2SEL_1 /*!< TIM2_TI2 is connected to CSI_128 */ +#define TIM_TIM2_TI2_MCO2 (TIM_TISEL_TI2SEL_1 |TIM_TISEL_TI2SEL_0) /*!< TIM2_TI2 is connected to MCO2 */ +#define TIM_TIM2_TI2_MCO1 TIM_TISEL_TI2SEL_2 /*!< TIM2_TI2 is connected to MCO1 */ +#endif /* STM32H503xx */ +#define TIM_TIM2_TI3_GPIO 0x00000000UL /*!< TIM2_TI3 is connected to GPIO */ +#define TIM_TIM2_TI4_GPIO 0x00000000UL /*!< TIM2_TI4 is connected to GPIO */ +#if defined(COMP1) +#define TIM_TIM2_TI4_COMP1 TIM_TISEL_TI4SEL_0 /*!< TIM2_TI4 is connected to COMP1 */ +#endif /* COMP1 */ + +#define TIM_TIM3_TI1_GPIO 0x00000000UL /*!< TIM3_TI1 is connected to GPIO */ +#if defined(STM32H503xx) +#define TIM_TIM3_TI1_COMP1 TIM_TISEL_TI1SEL_0 /*!< TIM3_TI1 is connected to COMP1 */ +#define TIM_TIM3_TI1_MCO1 TIM_TISEL_TI1SEL_1 /*!< TIM3_TI1 is connected to MCO1 */ +#define TIM_TIM3_TI1_TIM2_TI1 (TIM_TISEL_TI1SEL_1 | TIM_TISEL_TI1SEL_0) /*!< TIM3_TI1 is connected to TIM2 TI1 */ +#define TIM_TIM3_TI1_HSE_1MHZ TIM_TISEL_TI1SEL_2 /*!< TIM3_TI1 is connected to HSE 1MHZ */ +#endif /* STM32H503xx */ +#if defined(ETH_NS) +#define TIM_TIM3_TI1_ETH_PPS TIM_TISEL_TI1SEL_0 /*!< TIM3_TI1 is connected to ETH PPS */ +#endif /* ETH_NS */ +#define TIM_TIM3_TI2_GPIO 0x00000000UL /*!< TIM3_TI2 is connected to GPIO */ +#if defined(STM32H503xx) +#define TIM_TIM3_TI2_CSI_128 TIM_TISEL_TI2SEL_0 /*!< TIM3_TI2 is connected to CSI 128 */ +#define TIM_TIM3_TI2_MCO2 TIM_TISEL_TI2SEL_1 /*!< TIM3_TI2 is connected to MCO2 */ +#define TIM_TIM3_TI2_HSI_1024 (TIM_TISEL_TI2SEL_1 |TIM_TISEL_TI2SEL_0) /*!< TIM3_TI2 is connected to HSI 1024 */ +#endif /* STM32H503xx */ +#define TIM_TIM3_TI3_GPIO 0x00000000UL /*!< TIM3_TI3 is connected to GPIO */ +#define TIM_TIM3_TI4_GPIO 0x00000000UL /*!< TIM3_TI4 is connected to GPIO */ + +#if defined(TIM4) +#define TIM_TIM4_TI1_GPIO 0x00000000UL /*!< TIM4_TI1 is connected to GPIO */ +#define TIM_TIM4_TI2_GPIO 0x00000000UL /*!< TIM4_TI2 is connected to GPIO */ +#define TIM_TIM4_TI3_GPIO 0x00000000UL /*!< TIM4_TI3 is connected to GPIO */ +#define TIM_TIM4_TI4_GPIO 0x00000000UL /*!< TIM4_TI4 is connected to GPIO */ +#endif /* TIM4 */ + +#if defined(TIM5) +#define TIM_TIM5_TI1_GPIO 0x00000000UL /*!< TIM5_TI1 is connected to GPIO */ +#define TIM_TIM5_TI2_GPIO 0x00000000UL /*!< TIM5_TI2 is connected to GPIO */ +#define TIM_TIM5_TI3_GPIO 0x00000000UL /*!< TIM5_TI3 is connected to GPIO */ +#define TIM_TIM5_TI4_GPIO 0x00000000UL /*!< TIM5_TI4 is connected to GPIO */ +#endif /* TIM5 */ + +#if defined(TIM8) +#define TIM_TIM8_TI1_GPIO 0x00000000UL /*!< TIM8_TI1 is connected to GPIO */ +#define TIM_TIM8_TI2_GPIO 0x00000000UL /*!< TIM8_TI2 is connected to GPIO */ +#define TIM_TIM8_TI3_GPIO 0x00000000UL /*!< TIM8_TI3 is connected to GPIO */ +#define TIM_TIM8_TI4_GPIO 0x00000000UL /*!< TIM8_TI4 is connected to GPIO */ +#endif /* TIM8 */ + +#if defined(TIM12) +#define TIM_TIM12_TI1_GPIO 0x00000000UL /*!< TIM12_TI1 is connected to GPIO */ +#define TIM_TIM12_TI1_HSI_1024 TIM_TISEL_TI1SEL_2 /*!< TIM12_TI1 is connected to HSI 1024 */ +#define TIM_TIM12_TI1_CSI_128 (TIM_TISEL_TI1SEL_2 |TIM_TISEL_TI1SEL_0) /*!< TIM12_TI1 is connected to CSI 128 */ +#endif /* TIM12 */ + +#if defined(TIM13) +#define TIM_TIM13_TI1_GPIO 0x00000000UL /*!< TIM13_TI1 is connected to GPIO */ +#endif /* TIM13 */ + +#if defined(TIM14) +#define TIM_TIM14_TI1_GPIO 0x00000000UL /*!< TIM14_TI1 is connected to GPIO */ +#endif /* TIM14 */ + +#if defined(TIM15) +#define TIM_TIM15_TI1_GPIO 0x00000000UL /*!< TIM15_TI1 is connected to GPIO */ +#define TIM_TIM15_TI1_TIM2 TIM_TISEL_TI1SEL_0 /*!< TIM15_TI1 is connected to TIM2 */ +#define TIM_TIM15_TI1_TIM3 TIM_TISEL_TI1SEL_1 /*!< TIM15_TI1 is connected to TIM3 */ +#define TIM_TIM15_TI1_TIM4 (TIM_TISEL_TI1SEL_1 | TIM_TISEL_TI1SEL_0) /*!< TIM15_TI1 is connected to TIM4 */ +#define TIM_TIM15_TI1_LSE TIM_TISEL_TI1SEL_2 /*!< TIM15_TI1 is connected to LSE */ +#define TIM_TIM15_TI1_CSI_128 (TIM_TISEL_TI1SEL_2 |TIM_TISEL_TI1SEL_0) /*!< TIM15_TI1 is connected to CSI 128*/ +#define TIM_TIM15_TI1_MCO2 (TIM_TISEL_TI1SEL_2 |TIM_TISEL_TI1SEL_1) /*!< TIM15_TI1 is connected to MCO2 */ +#define TIM_TIM15_TI2_GPIO 0x00000000UL /*!< TIM15_TI1 is connected to GPIO */ +#define TIM_TIM15_TI2_TIM2 TIM_TISEL_TI2SEL_0 /*!< TIM15_TI2 is connected to TIM2 */ +#define TIM_TIM15_TI2_TIM3 TIM_TISEL_TI2SEL_1 /*!< TIM15_TI2 is connected to TIM3 */ +#define TIM_TIM15_TI2_TIM4 (TIM_TISEL_TI2SEL_1 | TIM_TISEL_TI2SEL_0) /*!< TIM15_TI2 is connected to TIM4 */ +#endif /* TIM15 */ + +#if defined(TIM16) +#define TIM_TIM16_TI1_GPIO 0x00000000UL /*!< TIM16_TI1 is connected to GPIO */ +#define TIM_TIM16_TI1_LSI TIM_TISEL_TI1SEL_0 /*!< TIM16_TI1 is connected to LSI */ +#define TIM_TIM16_TI1_LSE TIM_TISEL_TI1SEL_1 /*!< TIM16_TI1 is connected to LSE */ +#define TIM_TIM16_TI1_RTC_WKUP (TIM_TISEL_TI1SEL_1 | TIM_TISEL_TI1SEL_0) /*!< TIM16_TI1 is connected to RTC */ +#endif /* TIM16 */ + +#if defined(TIM17) +#define TIM_TIM17_TI1_GPIO 0x00000000UL /*!< TIM17_TI1 is connected to GPIO */ +#define TIM_TIM17_TI1_HSE_1MHZ TIM_TISEL_TI1SEL_1 /*!< TIM17_TI1 is connected to HSE 1MHZ */ +#define TIM_TIM17_TI1_MCO1 (TIM_TISEL_TI1SEL_1 | TIM_TISEL_TI1SEL_0) /*!< TIM17_TI1 is connected to MCO1 */ +#endif /* TIM17 */ +/** + * @} + */ + +/** @defgroup TIMEx_SMS_Preload_Enable TIM Extended Bitfield SMS preload enabling + * @{ + */ +#define TIM_SMS_PRELOAD_SOURCE_UPDATE 0x00000000U /*!< Prelaod of SMS bitfield is disabled */ +#define TIM_SMS_PRELOAD_SOURCE_INDEX TIM_SMCR_SMSPS /*!< Preload of SMS bitfield is enabled */ +/** + * @} + */ + +/** @defgroup TIMEx_Encoder_Index_Blanking TIM Extended Encoder index blanking + * @{ + */ +#define TIM_ENCODERINDEX_BLANKING_DISABLE 0x00000000U /*!< Encoder index blanking is disabled */ +#define TIM_ENCODERINDEX_BLANKING_TI3 TIM_ECR_IBLK_0 /*!< Encoder index blanking is enabled on TI3 */ +#define TIM_ENCODERINDEX_BLANKING_TI4 TIM_ECR_IBLK_1 /*!< Encoder index blanking is enabled on TI4 */ + +/** + * @} + */ + +/** @defgroup TIMEx_Encoder_Index_Position TIM Extended Encoder index position + * @{ + */ +#define TIM_ENCODERINDEX_POSITION_00 0x00000000U /*!< Encoder index position is AB=00 */ +#define TIM_ENCODERINDEX_POSITION_01 TIM_ECR_IPOS_0 /*!< Encoder index position is AB=01 */ +#define TIM_ENCODERINDEX_POSITION_10 TIM_ECR_IPOS_1 /*!< Encoder index position is AB=10 */ +#define TIM_ENCODERINDEX_POSITION_11 (TIM_ECR_IPOS_1 | TIM_ECR_IPOS_0) /*!< Encoder index position is AB=11 */ +#define TIM_ENCODERINDEX_POSITION_0 0x00000000U /*!< In directional clock mode or clock plus direction mode, index resets the counter when clock is 0 */ +#define TIM_ENCODERINDEX_POSITION_1 TIM_ECR_IPOS_0 /*!< In directional clock mode or clock plus direction mode, index resets the counter when clock is 1 */ +/** + * @} + */ + +/** @defgroup TIMEx_Encoder_Index_Direction TIM Extended Encoder index direction + * @{ + */ +#define TIM_ENCODERINDEX_DIRECTION_UP_DOWN 0x00000000U /*!< Index resets the counter whatever the direction */ +#define TIM_ENCODERINDEX_DIRECTION_UP TIM_ECR_IDIR_0 /*!< Index resets the counter when up-counting only */ +#define TIM_ENCODERINDEX_DIRECTION_DOWN TIM_ECR_IDIR_1 /*!< Index resets the counter when down-counting only */ +/** + * @} + */ + +/** @defgroup TIMEx_Encoder_Index_Polarity TIM Extended Encoder index polarity + * @{ + */ +#define TIM_ENCODERINDEX_POLARITY_INVERTED TIM_ETRPOLARITY_INVERTED /*!< Polarity for ETRx pin */ +#define TIM_ENCODERINDEX_POLARITY_NONINVERTED TIM_ETRPOLARITY_NONINVERTED /*!< Polarity for ETRx pin */ +/** + * @} + */ + +/** @defgroup TIMEx_Encoder_Index_Prescaler TIM Extended Encodder index prescaler + * @{ + */ +#define TIM_ENCODERINDEX_PRESCALER_DIV1 TIM_ETRPRESCALER_DIV1 /*!< No prescaler is used */ +#define TIM_ENCODERINDEX_PRESCALER_DIV2 TIM_ETRPRESCALER_DIV2 /*!< Prescaler for External ETR pin: Capture performed once every 2 events. */ +#define TIM_ENCODERINDEX_PRESCALER_DIV4 TIM_ETRPRESCALER_DIV4 /*!< Prescaler for External ETR pin: Capture performed once every 4 events. */ +#define TIM_ENCODERINDEX_PRESCALER_DIV8 TIM_ETRPRESCALER_DIV8 /*!< Prescaler for External ETR pin: Capture performed once every 8 events. */ +/** + * @} + */ + +/** + * @} + */ +/* End of exported constants -------------------------------------------------*/ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup TIMEx_Exported_Macros TIM Extended Exported Macros + * @{ + */ + +/** + * @brief HELPER macro calculating the prescaler value to achieve the required counter clock frequency. + * @note ex: @ref __HAL_TIM_CALC_PSC(80000000, 1000000); + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __CNTCLK__ counter clock frequency (in Hz) + * @retval Prescaler value (between Min_Data=0 and Max_Data=65535) + */ +#define __HAL_TIM_CALC_PSC(__TIMCLK__, __CNTCLK__) \ + ((__TIMCLK__) >= (__CNTCLK__)) ? (uint32_t)((__TIMCLK__)/(__CNTCLK__) - 1U) : 0U + +/** + * @brief HELPER macro calculating the auto-reload value to achieve the required output signal frequency. + * @note ex: @ref __HAL_TIM_CALC_PERIOD(1000000, 0, 10000); + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __PSC__ prescaler + * @param __FREQ__ output signal frequency (in Hz) + * @retval Auto-reload value (between Min_Data=0 and Max_Data=65535) + */ +#define __HAL_TIM_CALC_PERIOD(__TIMCLK__, __PSC__, __FREQ__) \ + (((__TIMCLK__)/((__PSC__) + 1U)) >= (__FREQ__)) ? ((__TIMCLK__)/((__FREQ__) * ((__PSC__) + 1U)) - 1U) : 0U + +/** + * @brief HELPER macro calculating the auto-reload value, with dithering feature enabled, to achieve the required + * output signal frequency. + * @note ex: @ref __HAL_TIM_CALC_PERIOD_DITHER(1000000, 0, 10000); + * @note This macro should be used only if dithering is already enabled + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __PSC__ prescaler + * @param __FREQ__ output signal frequency (in Hz) + * @retval Auto-reload value (between Min_Data=0 and Max_Data=65519) + */ +#define __HAL_TIM_CALC_PERIOD_DITHER(__TIMCLK__, __PSC__, __FREQ__) \ + (((__TIMCLK__)/((__PSC__) + 1U)) >= (__FREQ__)) ? \ + (uint32_t)(((uint64_t)(__TIMCLK__)*16/((__FREQ__) * ((__PSC__) + 1U)) - 16U)) : 0U + +/** + * @brief HELPER macro calculating the compare value required to achieve the required timer output compare + * active/inactive delay. + * @note ex: @ref __HAL_TIM_CALC_PULSE(1000000, 0, 10); + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __PSC__ prescaler + * @param __DELAY__ timer output compare active/inactive delay (in us) + * @retval Compare value (between Min_Data=0 and Max_Data=65535) + */ +#define __HAL_TIM_CALC_PULSE(__TIMCLK__, __PSC__, __DELAY__) \ + ((uint32_t)(((uint64_t)(__TIMCLK__) * (uint64_t)(__DELAY__)) \ + / ((uint64_t)1000000U * (uint64_t)((__PSC__) + 1U)))) + +/** + * @brief HELPER macro calculating the compare value, with dithering feature enabled, to achieve the required timer + * output compare active/inactive delay. + * @note ex: @ref __HAL_TIM_CALC_PULSE_DITHER(1000000, 0, 10); + * @note This macro should be used only if dithering is already enabled + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __PSC__ prescaler + * @param __DELAY__ timer output compare active/inactive delay (in us) + * @retval Compare value (between Min_Data=0 and Max_Data=65519) + */ +#define __HAL_TIM_CALC_PULSE_DITHER(__TIMCLK__, __PSC__, __DELAY__) \ + ((uint32_t)(((uint64_t)(__TIMCLK__) * (uint64_t)(__DELAY__) * 16U) \ + / ((uint64_t)1000000U * (uint64_t)((__PSC__) + 1U)))) + +/** + * @brief HELPER macro calculating the auto-reload value to achieve the required pulse duration + * (when the timer operates in one pulse mode). + * @note ex: @ref __HAL_TIM_CALC_PERIOD_BY_DELAY(1000000, 0, 10, 20); + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __PSC__ prescaler + * @param __DELAY__ timer output compare active/inactive delay (in us) + * @param __PULSE__ pulse duration (in us) + * @retval Auto-reload value (between Min_Data=0 and Max_Data=65535) + */ +#define __HAL_TIM_CALC_PERIOD_BY_DELAY(__TIMCLK__, __PSC__, __DELAY__, __PULSE__) \ + ((uint32_t)(__HAL_TIM_CALC_PULSE((__TIMCLK__), (__PSC__), (__PULSE__)) \ + + __HAL_TIM_CALC_PULSE((__TIMCLK__), (__PSC__), (__DELAY__)))) + +/** + * @brief HELPER macro calculating the auto-reload value, with dithering feature enabled, to achieve the required + * pulse duration (when the timer operates in one pulse mode). + * @note ex: @ref __HAL_TIM_CALC_PERIOD_DITHER_BY_DELAY(1000000, 0, 10, 20); + * @note This macro should be used only if dithering is already enabled + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __PSC__ prescaler + * @param __DELAY__ timer output compare active/inactive delay (in us) + * @param __PULSE__ pulse duration (in us) + * @retval Auto-reload value (between Min_Data=0 and Max_Data=65519) + */ +#define __HAL_TIM_CALC_PERIOD_DITHER_BY_DELAY(__TIMCLK__, __PSC__, __DELAY__, __PULSE__) \ + ((uint32_t)(__HAL_TIM_CALC_PULSE_DITHER((__TIMCLK__), (__PSC__), (__PULSE__)) \ + + __HAL_TIM_CALC_PULSE_DITHER((__TIMCLK__), (__PSC__), (__DELAY__)))) + +/** + * @} + */ +/* End of exported macro -----------------------------------------------------*/ + +/* Private macro -------------------------------------------------------------*/ +/** @defgroup TIMEx_Private_Macros TIM Extended Private Macros + * @{ + */ +#define IS_TIM_REMAP(__REMAP__) ((((__REMAP__) & 0xFFFC3FFFU) == 0x00000000U)) +#define IS_TIM_BREAKINPUT(__BREAKINPUT__) (((__BREAKINPUT__) == TIM_BREAKINPUT_BRK) || \ + ((__BREAKINPUT__) == TIM_BREAKINPUT_BRK2)) +#if defined(COMP1) +#define IS_TIM_BREAKINPUTSOURCE(__SOURCE__) (((__SOURCE__) == TIM_BREAKINPUTSOURCE_BKIN) || \ + ((__SOURCE__) == TIM_BREAKINPUTSOURCE_COMP1)) +#else +#define IS_TIM_BREAKINPUTSOURCE(__SOURCE__) ((__SOURCE__) == TIM_BREAKINPUTSOURCE_BKIN) +#endif /* COMP1 */ + +#define IS_TIM_BREAKINPUTSOURCE_STATE(__STATE__) (((__STATE__) == TIM_BREAKINPUTSOURCE_DISABLE) || \ + ((__STATE__) == TIM_BREAKINPUTSOURCE_ENABLE)) + +#define IS_TIM_BREAKINPUTSOURCE_POLARITY(__POLARITY__) (((__POLARITY__) == TIM_BREAKINPUTSOURCE_POLARITY_LOW) || \ + ((__POLARITY__) == TIM_BREAKINPUTSOURCE_POLARITY_HIGH)) + +#define IS_TIM_TISEL(__TISEL__) ((((__TISEL__) & 0xF0F0F0F0U) == 0x00000000U)) + +#define IS_TIM_TISEL_TIX_INSTANCE(INSTANCE, CHANNEL) \ + (IS_TIM_CCX_INSTANCE(INSTANCE, CHANNEL) && ((CHANNEL) < TIM_CHANNEL_5)) +#if defined(STM32H503xx) +#define IS_TIM_CLOCKSOURCE_INSTANCE(INSTANCE, __CLOCK__) \ + ((((INSTANCE) == TIM1) && \ + (((__CLOCK__) == TIM_CLOCKSOURCE_INTERNAL) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1ED) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI2))) \ + || \ + (((INSTANCE) == TIM2) && \ + (((__CLOCK__) == TIM_CLOCKSOURCE_INTERNAL) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR0) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR12) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1ED) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI2))) \ + || \ + (((INSTANCE) == TIM3) && \ + (((__CLOCK__) == TIM_CLOCKSOURCE_INTERNAL) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR0) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1ED) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI2)))) + +#define IS_TIM_TRIGGER_INSTANCE(INSTANCE, __SELECTION__) \ + ((((INSTANCE) == TIM1) && \ + (((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_ITR2) || \ + ((__SELECTION__) == TIM_TS_TI1F_ED) || \ + ((__SELECTION__) == TIM_TS_TI1FP1) || \ + ((__SELECTION__) == TIM_TS_TI2FP2) || \ + ((__SELECTION__) == TIM_TS_ETRF))) \ + || \ + (((INSTANCE) == TIM2) && \ + (((__SELECTION__) == TIM_TS_ITR0) || \ + ((__SELECTION__) == TIM_TS_ITR2) || \ + ((__SELECTION__) == TIM_TS_ITR12) || \ + ((__SELECTION__) == TIM_TS_TI1F_ED) || \ + ((__SELECTION__) == TIM_TS_TI1FP1) || \ + ((__SELECTION__) == TIM_TS_TI2FP2) || \ + ((__SELECTION__) == TIM_TS_ETRF))) \ + || \ + (((INSTANCE) == TIM3) && \ + (((__SELECTION__) == TIM_TS_ITR0) || \ + ((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_TI1F_ED) || \ + ((__SELECTION__) == TIM_TS_TI1FP1) || \ + ((__SELECTION__) == TIM_TS_TI2FP2) || \ + ((__SELECTION__) == TIM_TS_ETRF)))) + +#define IS_TIM_INTERNAL_TRIGGEREVENT_INSTANCE(INSTANCE, __SELECTION__) \ + ((((INSTANCE) == TIM1) && \ + (((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_ITR2) || \ + ((__SELECTION__) == TIM_TS_NONE))) \ + || \ + (((INSTANCE) == TIM2) && \ + (((__SELECTION__) == TIM_TS_ITR0) || \ + ((__SELECTION__) == TIM_TS_ITR2) || \ + ((__SELECTION__) == TIM_TS_ITR12) || \ + ((__SELECTION__) == TIM_TS_NONE))) \ + || \ + (((INSTANCE) == TIM3) && \ + (((__SELECTION__) == TIM_TS_ITR0) || \ + ((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_NONE)))) +#else +#define IS_TIM_CLOCKSOURCE_INSTANCE(INSTANCE, __CLOCK__) \ + ((((INSTANCE) == TIM1) && \ + (((__CLOCK__) == TIM_CLOCKSOURCE_INTERNAL) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1ED) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR3) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR4) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR5) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR6) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR7) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR8) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR9) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR10) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR11))) \ + || \ + (((INSTANCE) == TIM2) && \ + (((__CLOCK__) == TIM_CLOCKSOURCE_INTERNAL) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1ED) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR0) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR3) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR4) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR5) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR6) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR7) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR8) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR9) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR10) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR11) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR12))) \ + || \ + (((INSTANCE) == TIM3) && \ + (((__CLOCK__) == TIM_CLOCKSOURCE_INTERNAL) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1ED) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR0) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR3) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR4) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR5) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR6) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR7) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR8) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR9) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR10) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR11))) \ + || \ + (((INSTANCE) == TIM4) && \ + (((__CLOCK__) == TIM_CLOCKSOURCE_INTERNAL) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1ED) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR0) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR4) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR5) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR6) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR7) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR8) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR9) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR10) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR11))) \ + || \ + (((INSTANCE) == TIM5) && \ + (((__CLOCK__) == TIM_CLOCKSOURCE_INTERNAL) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1ED) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR0) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR3) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR5) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR6) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR7) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR8) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR9) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR10) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR11) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR12))) \ + || \ + (((INSTANCE) == TIM8) && \ + (((__CLOCK__) == TIM_CLOCKSOURCE_INTERNAL) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1ED) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR0) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR3) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR4) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR6) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR7) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR8) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR9) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR10) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR11))) \ + || \ + (((INSTANCE) == TIM12) && \ + (((__CLOCK__) == TIM_CLOCKSOURCE_INTERNAL) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1ED) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR0) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR3) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR4) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR5) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR7) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR8) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR9) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR10) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR11))) \ + || \ + (((INSTANCE) == TIM15) && \ + (((__CLOCK__) == TIM_CLOCKSOURCE_INTERNAL) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1ED) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR0) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR3) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR4) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR5) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR6) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR7) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR8) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR10) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR11)))) + +#define IS_TIM_TRIGGER_INSTANCE(INSTANCE, __SELECTION__) \ + ((((INSTANCE) == TIM1) && \ + (((__SELECTION__) == TIM_TS_TI1F_ED) || \ + ((__SELECTION__) == TIM_TS_TI1FP1) || \ + ((__SELECTION__) == TIM_TS_TI2FP2) || \ + ((__SELECTION__) == TIM_TS_ETRF) || \ + ((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_ITR2) || \ + ((__SELECTION__) == TIM_TS_ITR3) || \ + ((__SELECTION__) == TIM_TS_ITR4) || \ + ((__SELECTION__) == TIM_TS_ITR5) || \ + ((__SELECTION__) == TIM_TS_ITR6) || \ + ((__SELECTION__) == TIM_TS_ITR7) || \ + ((__SELECTION__) == TIM_TS_ITR8) || \ + ((__SELECTION__) == TIM_TS_ITR9) || \ + ((__SELECTION__) == TIM_TS_ITR10) || \ + ((__SELECTION__) == TIM_TS_ITR11))) \ + || \ + (((INSTANCE) == TIM2) && \ + (((__SELECTION__) == TIM_TS_TI1F_ED) || \ + ((__SELECTION__) == TIM_TS_TI1FP1) || \ + ((__SELECTION__) == TIM_TS_TI2FP2) || \ + ((__SELECTION__) == TIM_TS_ETRF) || \ + ((__SELECTION__) == TIM_TS_ITR0) || \ + ((__SELECTION__) == TIM_TS_ITR2) || \ + ((__SELECTION__) == TIM_TS_ITR3) || \ + ((__SELECTION__) == TIM_TS_ITR4) || \ + ((__SELECTION__) == TIM_TS_ITR5) || \ + ((__SELECTION__) == TIM_TS_ITR6) || \ + ((__SELECTION__) == TIM_TS_ITR7) || \ + ((__SELECTION__) == TIM_TS_ITR8) || \ + ((__SELECTION__) == TIM_TS_ITR9) || \ + ((__SELECTION__) == TIM_TS_ITR10) || \ + ((__SELECTION__) == TIM_TS_ITR11) || \ + ((__SELECTION__) == TIM_TS_ITR12))) \ + || \ + (((INSTANCE) == TIM3) && \ + (((__SELECTION__) == TIM_TS_TI1F_ED) || \ + ((__SELECTION__) == TIM_TS_TI1FP1) || \ + ((__SELECTION__) == TIM_TS_TI2FP2) || \ + ((__SELECTION__) == TIM_TS_ETRF) || \ + ((__SELECTION__) == TIM_TS_ITR0) || \ + ((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_ITR3) || \ + ((__SELECTION__) == TIM_TS_ITR4) || \ + ((__SELECTION__) == TIM_TS_ITR5) || \ + ((__SELECTION__) == TIM_TS_ITR6) || \ + ((__SELECTION__) == TIM_TS_ITR7) || \ + ((__SELECTION__) == TIM_TS_ITR8) || \ + ((__SELECTION__) == TIM_TS_ITR9) || \ + ((__SELECTION__) == TIM_TS_ITR10) || \ + ((__SELECTION__) == TIM_TS_ITR11))) \ + || \ + (((INSTANCE) == TIM4) && \ + (((__SELECTION__) == TIM_TS_TI1F_ED) || \ + ((__SELECTION__) == TIM_TS_TI1FP1) || \ + ((__SELECTION__) == TIM_TS_TI2FP2) || \ + ((__SELECTION__) == TIM_TS_ETRF) || \ + ((__SELECTION__) == TIM_TS_ITR0) || \ + ((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_ITR2) || \ + ((__SELECTION__) == TIM_TS_ITR4) || \ + ((__SELECTION__) == TIM_TS_ITR5) || \ + ((__SELECTION__) == TIM_TS_ITR6) || \ + ((__SELECTION__) == TIM_TS_ITR7) || \ + ((__SELECTION__) == TIM_TS_ITR8) || \ + ((__SELECTION__) == TIM_TS_ITR9) || \ + ((__SELECTION__) == TIM_TS_ITR10) || \ + ((__SELECTION__) == TIM_TS_ITR11))) \ + || \ + (((INSTANCE) == TIM5) && \ + (((__SELECTION__) == TIM_TS_TI1F_ED) || \ + ((__SELECTION__) == TIM_TS_TI1FP1) || \ + ((__SELECTION__) == TIM_TS_TI2FP2) || \ + ((__SELECTION__) == TIM_TS_ETRF) || \ + ((__SELECTION__) == TIM_TS_ITR0) || \ + ((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_ITR2) || \ + ((__SELECTION__) == TIM_TS_ITR3) || \ + ((__SELECTION__) == TIM_TS_ITR5) || \ + ((__SELECTION__) == TIM_TS_ITR6) || \ + ((__SELECTION__) == TIM_TS_ITR7) || \ + ((__SELECTION__) == TIM_TS_ITR8) || \ + ((__SELECTION__) == TIM_TS_ITR9) || \ + ((__SELECTION__) == TIM_TS_ITR10) || \ + ((__SELECTION__) == TIM_TS_ITR11) || \ + ((__SELECTION__) == TIM_TS_ITR12))) \ + || \ + (((INSTANCE) == TIM8) && \ + (((__SELECTION__) == TIM_TS_TI1F_ED) || \ + ((__SELECTION__) == TIM_TS_TI1FP1) || \ + ((__SELECTION__) == TIM_TS_TI2FP2) || \ + ((__SELECTION__) == TIM_TS_ETRF) || \ + ((__SELECTION__) == TIM_TS_ITR0) || \ + ((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_ITR2) || \ + ((__SELECTION__) == TIM_TS_ITR3) || \ + ((__SELECTION__) == TIM_TS_ITR4) || \ + ((__SELECTION__) == TIM_TS_ITR6) || \ + ((__SELECTION__) == TIM_TS_ITR7) || \ + ((__SELECTION__) == TIM_TS_ITR8) || \ + ((__SELECTION__) == TIM_TS_ITR9) || \ + ((__SELECTION__) == TIM_TS_ITR10) || \ + ((__SELECTION__) == TIM_TS_ITR11))) \ + || \ + (((INSTANCE) == TIM12) && \ + (((__SELECTION__) == TIM_TS_TI1F_ED) || \ + ((__SELECTION__) == TIM_TS_TI1FP1) || \ + ((__SELECTION__) == TIM_TS_TI2FP2) || \ + ((__SELECTION__) == TIM_TS_ETRF) || \ + ((__SELECTION__) == TIM_TS_ITR0) || \ + ((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_ITR2) || \ + ((__SELECTION__) == TIM_TS_ITR3) || \ + ((__SELECTION__) == TIM_TS_ITR4) || \ + ((__SELECTION__) == TIM_TS_ITR5) || \ + ((__SELECTION__) == TIM_TS_ITR7) || \ + ((__SELECTION__) == TIM_TS_ITR8) || \ + ((__SELECTION__) == TIM_TS_ITR9) || \ + ((__SELECTION__) == TIM_TS_ITR10) || \ + ((__SELECTION__) == TIM_TS_ITR11))) \ + || \ + (((INSTANCE) == TIM15) && \ + (((__SELECTION__) == TIM_TS_TI1F_ED) || \ + ((__SELECTION__) == TIM_TS_TI1FP1) || \ + ((__SELECTION__) == TIM_TS_TI2FP2) || \ + ((__SELECTION__) == TIM_TS_ITR0) || \ + ((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_ITR2) || \ + ((__SELECTION__) == TIM_TS_ITR3) || \ + ((__SELECTION__) == TIM_TS_ITR4) || \ + ((__SELECTION__) == TIM_TS_ITR5) || \ + ((__SELECTION__) == TIM_TS_ITR6) || \ + ((__SELECTION__) == TIM_TS_ITR7) || \ + ((__SELECTION__) == TIM_TS_ITR8) || \ + ((__SELECTION__) == TIM_TS_ITR10) || \ + ((__SELECTION__) == TIM_TS_ITR11)))) + +#define IS_TIM_INTERNAL_TRIGGEREVENT_INSTANCE(INSTANCE, __SELECTION__) \ + ((((INSTANCE) == TIM1) && \ + (((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_ITR2) || \ + ((__SELECTION__) == TIM_TS_ITR3) || \ + ((__SELECTION__) == TIM_TS_ITR4) || \ + ((__SELECTION__) == TIM_TS_ITR5) || \ + ((__SELECTION__) == TIM_TS_ITR6) || \ + ((__SELECTION__) == TIM_TS_ITR7) || \ + ((__SELECTION__) == TIM_TS_ITR8) || \ + ((__SELECTION__) == TIM_TS_ITR9) || \ + ((__SELECTION__) == TIM_TS_ITR10)|| \ + ((__SELECTION__) == TIM_TS_ITR11)|| \ + ((__SELECTION__) == TIM_TS_NONE))) \ + || \ + (((INSTANCE) == TIM2) && \ + (((__SELECTION__) == TIM_TS_ITR0) || \ + ((__SELECTION__) == TIM_TS_ITR2) || \ + ((__SELECTION__) == TIM_TS_ITR3) || \ + ((__SELECTION__) == TIM_TS_ITR4) || \ + ((__SELECTION__) == TIM_TS_ITR5) || \ + ((__SELECTION__) == TIM_TS_ITR6) || \ + ((__SELECTION__) == TIM_TS_ITR7) || \ + ((__SELECTION__) == TIM_TS_ITR8) || \ + ((__SELECTION__) == TIM_TS_ITR9) || \ + ((__SELECTION__) == TIM_TS_ITR10)|| \ + ((__SELECTION__) == TIM_TS_ITR11)|| \ + ((__SELECTION__) == TIM_TS_ITR12)|| \ + ((__SELECTION__) == TIM_TS_NONE))) \ + || \ + (((INSTANCE) == TIM3) && \ + (((__SELECTION__) == TIM_TS_ITR0) || \ + ((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_ITR3) || \ + ((__SELECTION__) == TIM_TS_ITR4) || \ + ((__SELECTION__) == TIM_TS_ITR5) || \ + ((__SELECTION__) == TIM_TS_ITR6) || \ + ((__SELECTION__) == TIM_TS_ITR7) || \ + ((__SELECTION__) == TIM_TS_ITR8) || \ + ((__SELECTION__) == TIM_TS_ITR9) || \ + ((__SELECTION__) == TIM_TS_ITR10)|| \ + ((__SELECTION__) == TIM_TS_ITR11)|| \ + ((__SELECTION__) == TIM_TS_NONE))) \ + || \ + (((INSTANCE) == TIM4) && \ + (((__SELECTION__) == TIM_TS_ITR0) || \ + ((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_ITR2) || \ + ((__SELECTION__) == TIM_TS_ITR4) || \ + ((__SELECTION__) == TIM_TS_ITR5) || \ + ((__SELECTION__) == TIM_TS_ITR6) || \ + ((__SELECTION__) == TIM_TS_ITR7) || \ + ((__SELECTION__) == TIM_TS_ITR8) || \ + ((__SELECTION__) == TIM_TS_ITR9) || \ + ((__SELECTION__) == TIM_TS_ITR10)|| \ + ((__SELECTION__) == TIM_TS_ITR11)|| \ + ((__SELECTION__) == TIM_TS_NONE))) \ + || \ + (((INSTANCE) == TIM5) && \ + (((__SELECTION__) == TIM_TS_ITR0) || \ + ((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_ITR2) || \ + ((__SELECTION__) == TIM_TS_ITR3) || \ + ((__SELECTION__) == TIM_TS_ITR5) || \ + ((__SELECTION__) == TIM_TS_ITR6) || \ + ((__SELECTION__) == TIM_TS_ITR7) || \ + ((__SELECTION__) == TIM_TS_ITR8) || \ + ((__SELECTION__) == TIM_TS_ITR9) || \ + ((__SELECTION__) == TIM_TS_ITR10)|| \ + ((__SELECTION__) == TIM_TS_ITR11)|| \ + ((__SELECTION__) == TIM_TS_ITR12)|| \ + ((__SELECTION__) == TIM_TS_NONE))) \ + || \ + (((INSTANCE) == TIM8) && \ + (((__SELECTION__) == TIM_TS_ITR0) || \ + ((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_ITR2) || \ + ((__SELECTION__) == TIM_TS_ITR3) || \ + ((__SELECTION__) == TIM_TS_ITR4) || \ + ((__SELECTION__) == TIM_TS_ITR6) || \ + ((__SELECTION__) == TIM_TS_ITR7) || \ + ((__SELECTION__) == TIM_TS_ITR8) || \ + ((__SELECTION__) == TIM_TS_ITR9) || \ + ((__SELECTION__) == TIM_TS_ITR10)|| \ + ((__SELECTION__) == TIM_TS_ITR11)|| \ + ((__SELECTION__) == TIM_TS_NONE))) \ + || \ + (((INSTANCE) == TIM12) && \ + (((__SELECTION__) == TIM_TS_ITR0) || \ + ((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_ITR2) || \ + ((__SELECTION__) == TIM_TS_ITR3) || \ + ((__SELECTION__) == TIM_TS_ITR4) || \ + ((__SELECTION__) == TIM_TS_ITR5) || \ + ((__SELECTION__) == TIM_TS_ITR7) || \ + ((__SELECTION__) == TIM_TS_ITR8) || \ + ((__SELECTION__) == TIM_TS_ITR9) || \ + ((__SELECTION__) == TIM_TS_ITR10)|| \ + ((__SELECTION__) == TIM_TS_ITR11)|| \ + ((__SELECTION__) == TIM_TS_NONE))) \ + || \ + (((INSTANCE) == TIM15) && \ + (((__SELECTION__) == TIM_TS_ITR0) || \ + ((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_ITR2) || \ + ((__SELECTION__) == TIM_TS_ITR3) || \ + ((__SELECTION__) == TIM_TS_ITR4) || \ + ((__SELECTION__) == TIM_TS_ITR5) || \ + ((__SELECTION__) == TIM_TS_ITR6) || \ + ((__SELECTION__) == TIM_TS_ITR7) || \ + ((__SELECTION__) == TIM_TS_ITR8) || \ + ((__SELECTION__) == TIM_TS_ITR10)|| \ + ((__SELECTION__) == TIM_TS_ITR11)|| \ + ((__SELECTION__) == TIM_TS_NONE)))) +#endif /* STM32H503xx */ + +#define IS_TIM_OC_CHANNEL_MODE(__MODE__, __CHANNEL__) \ + (IS_TIM_OC_MODE(__MODE__) \ + && ((((__MODE__) == TIM_OCMODE_DIRECTION_OUTPUT) || ((__MODE__) == TIM_OCMODE_PULSE_ON_COMPARE)) \ + ? (((__CHANNEL__) == TIM_CHANNEL_3) || ((__CHANNEL__) == TIM_CHANNEL_4)) : (1 == 1))) + +#define IS_TIM_PULSEONCOMPARE_CHANNEL(__CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_3) || \ + ((__CHANNEL__) == TIM_CHANNEL_4)) + +#define IS_TIM_PULSEONCOMPARE_INSTANCE(INSTANCE) IS_TIM_CC3_INSTANCE(INSTANCE) + +#define IS_TIM_PULSEONCOMPARE_WIDTH(__WIDTH__) ((__WIDTH__) <= 0xFFU) + +#define IS_TIM_PULSEONCOMPARE_WIDTHPRESCALER(__PRESCALER__) ((__PRESCALER__) <= 0x7U) + +#define IS_TIM_SLAVE_PRELOAD_SOURCE(__SOURCE__) (((__SOURCE__) == TIM_SMS_PRELOAD_SOURCE_UPDATE) \ + || ((__SOURCE__) == TIM_SMS_PRELOAD_SOURCE_INDEX)) + +#define IS_TIM_ENCODERINDEX_POLARITY(__POLARITY__) (((__POLARITY__) == TIM_ENCODERINDEX_POLARITY_INVERTED) || \ + ((__POLARITY__) == TIM_ENCODERINDEX_POLARITY_NONINVERTED)) + +#define IS_TIM_ENCODERINDEX_PRESCALER(__PRESCALER__) (((__PRESCALER__) == TIM_ENCODERINDEX_PRESCALER_DIV1) || \ + ((__PRESCALER__) == TIM_ENCODERINDEX_PRESCALER_DIV2) || \ + ((__PRESCALER__) == TIM_ENCODERINDEX_PRESCALER_DIV4) || \ + ((__PRESCALER__) == TIM_ENCODERINDEX_PRESCALER_DIV8)) + +#define IS_TIM_ENCODERINDEX_FILTER(__FILTER__) ((__FILTER__) <= 0xFUL) + +#define IS_TIM_ENCODERINDEX_POSITION(__POSITION__) (((__POSITION__) == TIM_ENCODERINDEX_POSITION_00) || \ + ((__POSITION__) == TIM_ENCODERINDEX_POSITION_01) || \ + ((__POSITION__) == TIM_ENCODERINDEX_POSITION_10) || \ + ((__POSITION__) == TIM_ENCODERINDEX_POSITION_11) || \ + ((__POSITION__) == TIM_ENCODERINDEX_POSITION_0) || \ + ((__POSITION__) == TIM_ENCODERINDEX_POSITION_1)) + +#define IS_TIM_ENCODERINDEX_DIRECTION(__DIRECTION__) (((__DIRECTION__) == TIM_ENCODERINDEX_DIRECTION_UP_DOWN) || \ + ((__DIRECTION__) == TIM_ENCODERINDEX_DIRECTION_UP) || \ + ((__DIRECTION__) == TIM_ENCODERINDEX_DIRECTION_DOWN)) + +#define IS_TIM_ENCODERINDEX_BLANKING(__BLANKING__) (((__BLANKING__) == TIM_ENCODERINDEX_BLANKING_DISABLE) || \ + ((__BLANKING__) == TIM_ENCODERINDEX_BLANKING_TI3) || \ + ((__BLANKING__) == TIM_ENCODERINDEX_BLANKING_TI4)) + +/** + * @} + */ +/* End of private macro ------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup TIMEx_Exported_Functions TIM Extended Exported Functions + * @{ + */ + +/** @addtogroup TIMEx_Exported_Functions_Group1 Extended Timer Hall Sensor functions + * @brief Timer Hall Sensor functions + * @{ + */ +/* Timer Hall Sensor functions **********************************************/ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Init(TIM_HandleTypeDef *htim, const TIM_HallSensor_InitTypeDef *sConfig); +HAL_StatusTypeDef HAL_TIMEx_HallSensor_DeInit(TIM_HandleTypeDef *htim); + +void HAL_TIMEx_HallSensor_MspInit(TIM_HandleTypeDef *htim); +void HAL_TIMEx_HallSensor_MspDeInit(TIM_HandleTypeDef *htim); + +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop(TIM_HandleTypeDef *htim); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_IT(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_IT(TIM_HandleTypeDef *htim); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length); +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_DMA(TIM_HandleTypeDef *htim); +/** + * @} + */ + +/** @addtogroup TIMEx_Exported_Functions_Group2 Extended Timer Complementary Output Compare functions + * @brief Timer Complementary Output Compare functions + * @{ + */ +/* Timer Complementary Output Compare functions *****************************/ +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Start(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIMEx_OCN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); + +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); + +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData, + uint16_t Length); +HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); +/** + * @} + */ + +/** @addtogroup TIMEx_Exported_Functions_Group3 Extended Timer Complementary PWM functions + * @brief Timer Complementary PWM functions + * @{ + */ +/* Timer Complementary PWM functions ****************************************/ +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); + +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData, + uint16_t Length); +HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); +/** + * @} + */ + +/** @addtogroup TIMEx_Exported_Functions_Group4 Extended Timer Complementary One Pulse functions + * @brief Timer Complementary One Pulse functions + * @{ + */ +/* Timer Complementary One Pulse functions **********************************/ +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel); +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel); + +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel); +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel); +/** + * @} + */ + +/** @addtogroup TIMEx_Exported_Functions_Group5 Extended Peripheral Control functions + * @brief Peripheral Control functions + * @{ + */ +/* Extended Control functions ************************************************/ +HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent(TIM_HandleTypeDef *htim, uint32_t InputTrigger, + uint32_t CommutationSource); +HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_IT(TIM_HandleTypeDef *htim, uint32_t InputTrigger, + uint32_t CommutationSource); +HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_DMA(TIM_HandleTypeDef *htim, uint32_t InputTrigger, + uint32_t CommutationSource); +HAL_StatusTypeDef HAL_TIMEx_MasterConfigSynchronization(TIM_HandleTypeDef *htim, + const TIM_MasterConfigTypeDef *sMasterConfig); +HAL_StatusTypeDef HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef *htim, + const TIM_BreakDeadTimeConfigTypeDef *sBreakDeadTimeConfig); +HAL_StatusTypeDef HAL_TIMEx_ConfigBreakInput(TIM_HandleTypeDef *htim, uint32_t BreakInput, + const TIMEx_BreakInputConfigTypeDef *sBreakInputConfig); +HAL_StatusTypeDef HAL_TIMEx_GroupChannel5(TIM_HandleTypeDef *htim, uint32_t Channels); +HAL_StatusTypeDef HAL_TIMEx_RemapConfig(TIM_HandleTypeDef *htim, uint32_t Remap); +HAL_StatusTypeDef HAL_TIMEx_TISelection(TIM_HandleTypeDef *htim, uint32_t TISelection, uint32_t Channel); + +HAL_StatusTypeDef HAL_TIMEx_DisarmBreakInput(TIM_HandleTypeDef *htim, uint32_t BreakInput); +HAL_StatusTypeDef HAL_TIMEx_ReArmBreakInput(const TIM_HandleTypeDef *htim, uint32_t BreakInput); +HAL_StatusTypeDef HAL_TIMEx_DitheringEnable(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIMEx_DitheringDisable(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIMEx_OC_ConfigPulseOnCompare(TIM_HandleTypeDef *htim, uint32_t PulseWidthPrescaler, + uint32_t PulseWidth); +HAL_StatusTypeDef HAL_TIMEx_ConfigSlaveModePreload(TIM_HandleTypeDef *htim, uint32_t Source); +HAL_StatusTypeDef HAL_TIMEx_EnableSlaveModePreload(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIMEx_DisableSlaveModePreload(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIMEx_EnableDeadTimePreload(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIMEx_DisableDeadTimePreload(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIMEx_ConfigDeadTime(TIM_HandleTypeDef *htim, uint32_t Deadtime); +HAL_StatusTypeDef HAL_TIMEx_ConfigAsymmetricalDeadTime(TIM_HandleTypeDef *htim, uint32_t FallingDeadtime); +HAL_StatusTypeDef HAL_TIMEx_EnableAsymmetricalDeadTime(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIMEx_DisableAsymmetricalDeadTime(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIMEx_ConfigEncoderIndex(TIM_HandleTypeDef *htim, + TIMEx_EncoderIndexConfigTypeDef *sEncoderIndexConfig); +HAL_StatusTypeDef HAL_TIMEx_EnableEncoderIndex(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIMEx_DisableEncoderIndex(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIMEx_EnableEncoderFirstIndex(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIMEx_DisableEncoderFirstIndex(TIM_HandleTypeDef *htim); +/** + * @} + */ + +/** @addtogroup TIMEx_Exported_Functions_Group6 Extended Callbacks functions + * @brief Extended Callbacks functions + * @{ + */ +/* Extended Callback **********************************************************/ +void HAL_TIMEx_CommutCallback(TIM_HandleTypeDef *htim); +void HAL_TIMEx_CommutHalfCpltCallback(TIM_HandleTypeDef *htim); +void HAL_TIMEx_BreakCallback(TIM_HandleTypeDef *htim); +void HAL_TIMEx_Break2Callback(TIM_HandleTypeDef *htim); +void HAL_TIMEx_EncoderIndexCallback(TIM_HandleTypeDef *htim); +void HAL_TIMEx_DirectionChangeCallback(TIM_HandleTypeDef *htim); +void HAL_TIMEx_IndexErrorCallback(TIM_HandleTypeDef *htim); +void HAL_TIMEx_TransitionErrorCallback(TIM_HandleTypeDef *htim); +/** + * @} + */ + +/** @addtogroup TIMEx_Exported_Functions_Group7 Extended Peripheral State functions + * @brief Extended Peripheral State functions + * @{ + */ +/* Extended Peripheral State functions ***************************************/ +HAL_TIM_StateTypeDef HAL_TIMEx_HallSensor_GetState(const TIM_HandleTypeDef *htim); +HAL_TIM_ChannelStateTypeDef HAL_TIMEx_GetChannelNState(const TIM_HandleTypeDef *htim, uint32_t ChannelN); +/** + * @} + */ + +/** + * @} + */ +/* End of exported functions -------------------------------------------------*/ + +/* Private functions----------------------------------------------------------*/ +/** @addtogroup TIMEx_Private_Functions TIM Extended Private Functions + * @{ + */ +void TIMEx_DMACommutationCplt(DMA_HandleTypeDef *hdma); +void TIMEx_DMACommutationHalfCplt(DMA_HandleTypeDef *hdma); +/** + * @} + */ +/* End of private functions --------------------------------------------------*/ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* STM32H5xx_HAL_TIM_EX_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_uart.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_uart.h new file mode 100644 index 0000000000..0d55af7ff5 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_uart.h @@ -0,0 +1,1778 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_uart.h + * @author MCD Application Team + * @brief Header file of UART HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_UART_H +#define STM32H5xx_HAL_UART_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup UART + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup UART_Exported_Types UART Exported Types + * @{ + */ + +/** + * @brief UART Init Structure definition + */ +typedef struct +{ + uint32_t BaudRate; /*!< This member configures the UART communication baud rate. + The baud rate register is computed using the following formula: + LPUART: + ======= + Baud Rate Register = ((256 * lpuart_ker_ckpres) / ((huart->Init.BaudRate))) + where lpuart_ker_ck_pres is the UART input clock divided by a prescaler + UART: + ===== + - If oversampling is 16 or in LIN mode, + Baud Rate Register = ((uart_ker_ckpres) / ((huart->Init.BaudRate))) + - If oversampling is 8, + Baud Rate Register[15:4] = ((2 * uart_ker_ckpres) / + ((huart->Init.BaudRate)))[15:4] + Baud Rate Register[3] = 0 + Baud Rate Register[2:0] = (((2 * uart_ker_ckpres) / + ((huart->Init.BaudRate)))[3:0]) >> 1 + where uart_ker_ck_pres is the UART input clock divided by a prescaler */ + + uint32_t WordLength; /*!< Specifies the number of data bits transmitted or received in a frame. + This parameter can be a value of @ref UARTEx_Word_Length. */ + + uint32_t StopBits; /*!< Specifies the number of stop bits transmitted. + This parameter can be a value of @ref UART_Stop_Bits. */ + + uint32_t Parity; /*!< Specifies the parity mode. + This parameter can be a value of @ref UART_Parity + @note When parity is enabled, the computed parity is inserted + at the MSB position of the transmitted data (9th bit when + the word length is set to 9 data bits; 8th bit when the + word length is set to 8 data bits). */ + + uint32_t Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled. + This parameter can be a value of @ref UART_Mode. */ + + uint32_t HwFlowCtl; /*!< Specifies whether the hardware flow control mode is enabled + or disabled. + This parameter can be a value of @ref UART_Hardware_Flow_Control. */ + + uint32_t OverSampling; /*!< Specifies whether the Over sampling 8 is enabled or disabled, + to achieve higher speed (up to f_PCLK/8). + This parameter can be a value of @ref UART_Over_Sampling. */ + + uint32_t OneBitSampling; /*!< Specifies whether a single sample or three samples' majority vote is selected. + Selecting the single sample method increases the receiver tolerance to clock + deviations. This parameter can be a value of @ref UART_OneBit_Sampling. */ + + uint32_t ClockPrescaler; /*!< Specifies the prescaler value used to divide the UART clock source. + This parameter can be a value of @ref UART_ClockPrescaler. */ + +} UART_InitTypeDef; + +/** + * @brief UART Advanced Features initialization structure definition + */ +typedef struct +{ + uint32_t AdvFeatureInit; /*!< Specifies which advanced UART features is initialized. Several + Advanced Features may be initialized at the same time . + This parameter can be a value of + @ref UART_Advanced_Features_Initialization_Type. */ + + uint32_t TxPinLevelInvert; /*!< Specifies whether the TX pin active level is inverted. + This parameter can be a value of @ref UART_Tx_Inv. */ + + uint32_t RxPinLevelInvert; /*!< Specifies whether the RX pin active level is inverted. + This parameter can be a value of @ref UART_Rx_Inv. */ + + uint32_t DataInvert; /*!< Specifies whether data are inverted (positive/direct logic + vs negative/inverted logic). + This parameter can be a value of @ref UART_Data_Inv. */ + + uint32_t Swap; /*!< Specifies whether TX and RX pins are swapped. + This parameter can be a value of @ref UART_Rx_Tx_Swap. */ + + uint32_t OverrunDisable; /*!< Specifies whether the reception overrun detection is disabled. + This parameter can be a value of @ref UART_Overrun_Disable. */ + +#if defined(HAL_DMA_MODULE_ENABLED) + uint32_t DMADisableonRxError; /*!< Specifies whether the DMA is disabled in case of reception error. + This parameter can be a value of @ref UART_DMA_Disable_on_Rx_Error. */ + +#endif /* HAL_DMA_MODULE_ENABLED */ + uint32_t AutoBaudRateEnable; /*!< Specifies whether auto Baud rate detection is enabled. + This parameter can be a value of @ref UART_AutoBaudRate_Enable. */ + + uint32_t AutoBaudRateMode; /*!< If auto Baud rate detection is enabled, specifies how the rate + detection is carried out. + This parameter can be a value of @ref UART_AutoBaud_Rate_Mode. */ + + uint32_t MSBFirst; /*!< Specifies whether MSB is sent first on UART line. + This parameter can be a value of @ref UART_MSB_First. */ +} UART_AdvFeatureInitTypeDef; + +/** + * @brief HAL UART State definition + * @note HAL UART State value is a combination of 2 different substates: + * gState and RxState (see @ref UART_State_Definition). + * - gState contains UART state information related to global Handle management + * and also information related to Tx operations. + * gState value coding follow below described bitmap : + * b7-b6 Error information + * 00 : No Error + * 01 : (Not Used) + * 10 : Timeout + * 11 : Error + * b5 Peripheral initialization status + * 0 : Reset (Peripheral not initialized) + * 1 : Init done (Peripheral initialized. HAL UART Init function already called) + * b4-b3 (not used) + * xx : Should be set to 00 + * b2 Intrinsic process state + * 0 : Ready + * 1 : Busy (Peripheral busy with some configuration or internal operations) + * b1 (not used) + * x : Should be set to 0 + * b0 Tx state + * 0 : Ready (no Tx operation ongoing) + * 1 : Busy (Tx operation ongoing) + * - RxState contains information related to Rx operations. + * RxState value coding follow below described bitmap : + * b7-b6 (not used) + * xx : Should be set to 00 + * b5 Peripheral initialization status + * 0 : Reset (Peripheral not initialized) + * 1 : Init done (Peripheral initialized) + * b4-b2 (not used) + * xxx : Should be set to 000 + * b1 Rx state + * 0 : Ready (no Rx operation ongoing) + * 1 : Busy (Rx operation ongoing) + * b0 (not used) + * x : Should be set to 0. + */ +typedef uint32_t HAL_UART_StateTypeDef; + +/** + * @brief UART clock sources definition + */ +typedef enum +{ + UART_CLOCKSOURCE_PCLK1 = 0x00U, /*!< PCLK1 clock source */ + UART_CLOCKSOURCE_PLL2Q = 0x01U, /*!< PLL2Q clock source */ + UART_CLOCKSOURCE_PLL3Q = 0x02U, /*!< PLL3Q clock source */ + UART_CLOCKSOURCE_HSI = 0x04U, /*!< HSI clock source */ + UART_CLOCKSOURCE_CSI = 0x08U, /*!< CSI clock source */ + UART_CLOCKSOURCE_LSE = 0x10U, /*!< LSE clock source */ + UART_CLOCKSOURCE_UNDEFINED = 0x20U /*!< Undefined clock source */ +} UART_ClockSourceTypeDef; + +/** + * @brief HAL UART Reception type definition + * @note HAL UART Reception type value aims to identify which type of Reception is ongoing. + * This parameter can be a value of @ref UART_Reception_Type_Values : + * HAL_UART_RECEPTION_STANDARD = 0x00U, + * HAL_UART_RECEPTION_TOIDLE = 0x01U, + * HAL_UART_RECEPTION_TORTO = 0x02U, + * HAL_UART_RECEPTION_TOCHARMATCH = 0x03U, + */ +typedef uint32_t HAL_UART_RxTypeTypeDef; + +/** + * @brief HAL UART Rx Event type definition + * @note HAL UART Rx Event type value aims to identify which type of Event has occurred + * leading to call of the RxEvent callback. + * This parameter can be a value of @ref UART_RxEvent_Type_Values : + * HAL_UART_RXEVENT_TC = 0x00U, + * HAL_UART_RXEVENT_HT = 0x01U, + * HAL_UART_RXEVENT_IDLE = 0x02U, + */ +typedef uint32_t HAL_UART_RxEventTypeTypeDef; + +/** + * @brief UART handle Structure definition + */ +typedef struct __UART_HandleTypeDef +{ + USART_TypeDef *Instance; /*!< UART registers base address */ + + UART_InitTypeDef Init; /*!< UART communication parameters */ + + UART_AdvFeatureInitTypeDef AdvancedInit; /*!< UART Advanced Features initialization parameters */ + + const uint8_t *pTxBuffPtr; /*!< Pointer to UART Tx transfer Buffer */ + + uint16_t TxXferSize; /*!< UART Tx Transfer size */ + + __IO uint16_t TxXferCount; /*!< UART Tx Transfer Counter */ + + uint8_t *pRxBuffPtr; /*!< Pointer to UART Rx transfer Buffer */ + + uint16_t RxXferSize; /*!< UART Rx Transfer size */ + + __IO uint16_t RxXferCount; /*!< UART Rx Transfer Counter */ + + uint16_t Mask; /*!< UART Rx RDR register mask */ + + uint32_t FifoMode; /*!< Specifies if the FIFO mode is being used. + This parameter can be a value of @ref UARTEx_FIFO_mode. */ + + uint16_t NbRxDataToProcess; /*!< Number of data to process during RX ISR execution */ + + uint16_t NbTxDataToProcess; /*!< Number of data to process during TX ISR execution */ + + __IO HAL_UART_RxTypeTypeDef ReceptionType; /*!< Type of ongoing reception */ + + __IO HAL_UART_RxEventTypeTypeDef RxEventType; /*!< Type of Rx Event */ + + void (*RxISR)(struct __UART_HandleTypeDef *huart); /*!< Function pointer on Rx IRQ handler */ + + void (*TxISR)(struct __UART_HandleTypeDef *huart); /*!< Function pointer on Tx IRQ handler */ + +#if defined(HAL_DMA_MODULE_ENABLED) + DMA_HandleTypeDef *hdmatx; /*!< UART Tx DMA Handle parameters */ + + DMA_HandleTypeDef *hdmarx; /*!< UART Rx DMA Handle parameters */ + +#endif /* HAL_DMA_MODULE_ENABLED */ + HAL_LockTypeDef Lock; /*!< Locking object */ + + __IO HAL_UART_StateTypeDef gState; /*!< UART state information related to global Handle management + and also related to Tx operations. This parameter + can be a value of @ref HAL_UART_StateTypeDef */ + + __IO HAL_UART_StateTypeDef RxState; /*!< UART state information related to Rx operations. This + parameter can be a value of @ref HAL_UART_StateTypeDef */ + + __IO uint32_t ErrorCode; /*!< UART Error code */ + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + void (* TxHalfCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Tx Half Complete Callback */ + void (* TxCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Tx Complete Callback */ + void (* RxHalfCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Rx Half Complete Callback */ + void (* RxCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Rx Complete Callback */ + void (* ErrorCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Error Callback */ + void (* AbortCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Abort Complete Callback */ + void (* AbortTransmitCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Abort Transmit Complete Callback */ + void (* AbortReceiveCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Abort Receive Complete Callback */ + void (* WakeupCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Wakeup Callback */ + void (* RxFifoFullCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Rx Fifo Full Callback */ + void (* TxFifoEmptyCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Tx Fifo Empty Callback */ + void (* RxEventCallback)(struct __UART_HandleTypeDef *huart, uint16_t Pos); /*!< UART Reception Event Callback */ + + void (* MspInitCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Msp Init callback */ + void (* MspDeInitCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Msp DeInit callback */ +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + +} UART_HandleTypeDef; + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) +/** + * @brief HAL UART Callback ID enumeration definition + */ +typedef enum +{ + HAL_UART_TX_HALFCOMPLETE_CB_ID = 0x00U, /*!< UART Tx Half Complete Callback ID */ + HAL_UART_TX_COMPLETE_CB_ID = 0x01U, /*!< UART Tx Complete Callback ID */ + HAL_UART_RX_HALFCOMPLETE_CB_ID = 0x02U, /*!< UART Rx Half Complete Callback ID */ + HAL_UART_RX_COMPLETE_CB_ID = 0x03U, /*!< UART Rx Complete Callback ID */ + HAL_UART_ERROR_CB_ID = 0x04U, /*!< UART Error Callback ID */ + HAL_UART_ABORT_COMPLETE_CB_ID = 0x05U, /*!< UART Abort Complete Callback ID */ + HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID = 0x06U, /*!< UART Abort Transmit Complete Callback ID */ + HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID = 0x07U, /*!< UART Abort Receive Complete Callback ID */ + HAL_UART_WAKEUP_CB_ID = 0x08U, /*!< UART Wakeup Callback ID */ + HAL_UART_RX_FIFO_FULL_CB_ID = 0x09U, /*!< UART Rx Fifo Full Callback ID */ + HAL_UART_TX_FIFO_EMPTY_CB_ID = 0x0AU, /*!< UART Tx Fifo Empty Callback ID */ + + HAL_UART_MSPINIT_CB_ID = 0x0BU, /*!< UART MspInit callback ID */ + HAL_UART_MSPDEINIT_CB_ID = 0x0CU /*!< UART MspDeInit callback ID */ + +} HAL_UART_CallbackIDTypeDef; + +/** + * @brief HAL UART Callback pointer definition + */ +typedef void (*pUART_CallbackTypeDef)(UART_HandleTypeDef *huart); /*!< pointer to an UART callback function */ +typedef void (*pUART_RxEventCallbackTypeDef) +(struct __UART_HandleTypeDef *huart, uint16_t Pos); /*!< pointer to a UART Rx Event specific callback function */ + +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup UART_Exported_Constants UART Exported Constants + * @{ + */ + +/** @defgroup UART_State_Definition UART State Code Definition + * @{ + */ +#define HAL_UART_STATE_RESET 0x00000000U /*!< Peripheral is not initialized + Value is allowed for gState and RxState */ +#define HAL_UART_STATE_READY 0x00000020U /*!< Peripheral Initialized and ready for use + Value is allowed for gState and RxState */ +#define HAL_UART_STATE_BUSY 0x00000024U /*!< an internal process is ongoing + Value is allowed for gState only */ +#define HAL_UART_STATE_BUSY_TX 0x00000021U /*!< Data Transmission process is ongoing + Value is allowed for gState only */ +#define HAL_UART_STATE_BUSY_RX 0x00000022U /*!< Data Reception process is ongoing + Value is allowed for RxState only */ +#define HAL_UART_STATE_BUSY_TX_RX 0x00000023U /*!< Data Transmission and Reception process is ongoing + Not to be used for neither gState nor RxState.Value is result + of combination (Or) between gState and RxState values */ +#define HAL_UART_STATE_TIMEOUT 0x000000A0U /*!< Timeout state + Value is allowed for gState only */ +#define HAL_UART_STATE_ERROR 0x000000E0U /*!< Error + Value is allowed for gState only */ +/** + * @} + */ + +/** @defgroup UART_Error_Definition UART Error Definition + * @{ + */ +#define HAL_UART_ERROR_NONE (0x00000000U) /*!< No error */ +#define HAL_UART_ERROR_PE (0x00000001U) /*!< Parity error */ +#define HAL_UART_ERROR_NE (0x00000002U) /*!< Noise error */ +#define HAL_UART_ERROR_FE (0x00000004U) /*!< Frame error */ +#define HAL_UART_ERROR_ORE (0x00000008U) /*!< Overrun error */ +#if defined(HAL_DMA_MODULE_ENABLED) +#define HAL_UART_ERROR_DMA (0x00000010U) /*!< DMA transfer error */ +#endif /* HAL_DMA_MODULE_ENABLED */ +#define HAL_UART_ERROR_RTO (0x00000020U) /*!< Receiver Timeout error */ + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) +#define HAL_UART_ERROR_INVALID_CALLBACK (0x00000040U) /*!< Invalid Callback error */ +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @defgroup UART_Stop_Bits UART Number of Stop Bits + * @{ + */ +#define UART_STOPBITS_0_5 USART_CR2_STOP_0 /*!< UART frame with 0.5 stop bit */ +#define UART_STOPBITS_1 0x00000000U /*!< UART frame with 1 stop bit */ +#define UART_STOPBITS_1_5 (USART_CR2_STOP_0 | USART_CR2_STOP_1) /*!< UART frame with 1.5 stop bits */ +#define UART_STOPBITS_2 USART_CR2_STOP_1 /*!< UART frame with 2 stop bits */ +/** + * @} + */ + +/** @defgroup UART_Parity UART Parity + * @{ + */ +#define UART_PARITY_NONE 0x00000000U /*!< No parity */ +#define UART_PARITY_EVEN USART_CR1_PCE /*!< Even parity */ +#define UART_PARITY_ODD (USART_CR1_PCE | USART_CR1_PS) /*!< Odd parity */ +/** + * @} + */ + +/** @defgroup UART_Hardware_Flow_Control UART Hardware Flow Control + * @{ + */ +#define UART_HWCONTROL_NONE 0x00000000U /*!< No hardware control */ +#define UART_HWCONTROL_RTS USART_CR3_RTSE /*!< Request To Send */ +#define UART_HWCONTROL_CTS USART_CR3_CTSE /*!< Clear To Send */ +#define UART_HWCONTROL_RTS_CTS (USART_CR3_RTSE | USART_CR3_CTSE) /*!< Request and Clear To Send */ +/** + * @} + */ + +/** @defgroup UART_Mode UART Transfer Mode + * @{ + */ +#define UART_MODE_RX USART_CR1_RE /*!< RX mode */ +#define UART_MODE_TX USART_CR1_TE /*!< TX mode */ +#define UART_MODE_TX_RX (USART_CR1_TE |USART_CR1_RE) /*!< RX and TX mode */ +/** + * @} + */ + +/** @defgroup UART_State UART State + * @{ + */ +#define UART_STATE_DISABLE 0x00000000U /*!< UART disabled */ +#define UART_STATE_ENABLE USART_CR1_UE /*!< UART enabled */ +/** + * @} + */ + +/** @defgroup UART_Over_Sampling UART Over Sampling + * @{ + */ +#define UART_OVERSAMPLING_16 0x00000000U /*!< Oversampling by 16 */ +#define UART_OVERSAMPLING_8 USART_CR1_OVER8 /*!< Oversampling by 8 */ +/** + * @} + */ + +/** @defgroup UART_OneBit_Sampling UART One Bit Sampling Method + * @{ + */ +#define UART_ONE_BIT_SAMPLE_DISABLE 0x00000000U /*!< One-bit sampling disable */ +#define UART_ONE_BIT_SAMPLE_ENABLE USART_CR3_ONEBIT /*!< One-bit sampling enable */ +/** + * @} + */ + +/** @defgroup UART_ClockPrescaler UART Clock Prescaler + * @{ + */ +#define UART_PRESCALER_DIV1 0x00000000U /*!< fclk_pres = fclk */ +#define UART_PRESCALER_DIV2 0x00000001U /*!< fclk_pres = fclk/2 */ +#define UART_PRESCALER_DIV4 0x00000002U /*!< fclk_pres = fclk/4 */ +#define UART_PRESCALER_DIV6 0x00000003U /*!< fclk_pres = fclk/6 */ +#define UART_PRESCALER_DIV8 0x00000004U /*!< fclk_pres = fclk/8 */ +#define UART_PRESCALER_DIV10 0x00000005U /*!< fclk_pres = fclk/10 */ +#define UART_PRESCALER_DIV12 0x00000006U /*!< fclk_pres = fclk/12 */ +#define UART_PRESCALER_DIV16 0x00000007U /*!< fclk_pres = fclk/16 */ +#define UART_PRESCALER_DIV32 0x00000008U /*!< fclk_pres = fclk/32 */ +#define UART_PRESCALER_DIV64 0x00000009U /*!< fclk_pres = fclk/64 */ +#define UART_PRESCALER_DIV128 0x0000000AU /*!< fclk_pres = fclk/128 */ +#define UART_PRESCALER_DIV256 0x0000000BU /*!< fclk_pres = fclk/256 */ +/** + * @} + */ + +/** @defgroup UART_AutoBaud_Rate_Mode UART Advanced Feature AutoBaud Rate Mode + * @{ + */ +#define UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT 0x00000000U /*!< Auto Baud rate detection + on start bit */ +#define UART_ADVFEATURE_AUTOBAUDRATE_ONFALLINGEDGE USART_CR2_ABRMODE_0 /*!< Auto Baud rate detection + on falling edge */ +#define UART_ADVFEATURE_AUTOBAUDRATE_ON0X7FFRAME USART_CR2_ABRMODE_1 /*!< Auto Baud rate detection + on 0x7F frame detection */ +#define UART_ADVFEATURE_AUTOBAUDRATE_ON0X55FRAME USART_CR2_ABRMODE /*!< Auto Baud rate detection + on 0x55 frame detection */ +/** + * @} + */ + +/** @defgroup UART_Receiver_Timeout UART Receiver Timeout + * @{ + */ +#define UART_RECEIVER_TIMEOUT_DISABLE 0x00000000U /*!< UART Receiver Timeout disable */ +#define UART_RECEIVER_TIMEOUT_ENABLE USART_CR2_RTOEN /*!< UART Receiver Timeout enable */ +/** + * @} + */ + +/** @defgroup UART_LIN UART Local Interconnection Network mode + * @{ + */ +#define UART_LIN_DISABLE 0x00000000U /*!< Local Interconnect Network disable */ +#define UART_LIN_ENABLE USART_CR2_LINEN /*!< Local Interconnect Network enable */ +/** + * @} + */ + +/** @defgroup UART_LIN_Break_Detection UART LIN Break Detection + * @{ + */ +#define UART_LINBREAKDETECTLENGTH_10B 0x00000000U /*!< LIN 10-bit break detection length */ +#define UART_LINBREAKDETECTLENGTH_11B USART_CR2_LBDL /*!< LIN 11-bit break detection length */ +/** + * @} + */ + +#if defined(HAL_DMA_MODULE_ENABLED) +/** @defgroup UART_DMA_Tx UART DMA Tx + * @{ + */ +#define UART_DMA_TX_DISABLE 0x00000000U /*!< UART DMA TX disabled */ +#define UART_DMA_TX_ENABLE USART_CR3_DMAT /*!< UART DMA TX enabled */ +/** + * @} + */ + +/** @defgroup UART_DMA_Rx UART DMA Rx + * @{ + */ +#define UART_DMA_RX_DISABLE 0x00000000U /*!< UART DMA RX disabled */ +#define UART_DMA_RX_ENABLE USART_CR3_DMAR /*!< UART DMA RX enabled */ +/** + * @} + */ +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** @defgroup UART_Half_Duplex_Selection UART Half Duplex Selection + * @{ + */ +#define UART_HALF_DUPLEX_DISABLE 0x00000000U /*!< UART half-duplex disabled */ +#define UART_HALF_DUPLEX_ENABLE USART_CR3_HDSEL /*!< UART half-duplex enabled */ +/** + * @} + */ + +/** @defgroup UART_WakeUp_Methods UART WakeUp Methods + * @{ + */ +#define UART_WAKEUPMETHOD_IDLELINE 0x00000000U /*!< UART wake-up on idle line */ +#define UART_WAKEUPMETHOD_ADDRESSMARK USART_CR1_WAKE /*!< UART wake-up on address mark */ +/** + * @} + */ + +/** @defgroup UART_Request_Parameters UART Request Parameters + * @{ + */ +#define UART_AUTOBAUD_REQUEST USART_RQR_ABRRQ /*!< Auto-Baud Rate Request */ +#define UART_SENDBREAK_REQUEST USART_RQR_SBKRQ /*!< Send Break Request */ +#define UART_MUTE_MODE_REQUEST USART_RQR_MMRQ /*!< Mute Mode Request */ +#define UART_RXDATA_FLUSH_REQUEST USART_RQR_RXFRQ /*!< Receive Data flush Request */ +#define UART_TXDATA_FLUSH_REQUEST USART_RQR_TXFRQ /*!< Transmit data flush Request */ +/** + * @} + */ + +/** @defgroup UART_Advanced_Features_Initialization_Type UART Advanced Feature Initialization Type + * @{ + */ +#define UART_ADVFEATURE_NO_INIT 0x00000000U /*!< No advanced feature initialization */ +#define UART_ADVFEATURE_TXINVERT_INIT 0x00000001U /*!< TX pin active level inversion */ +#define UART_ADVFEATURE_RXINVERT_INIT 0x00000002U /*!< RX pin active level inversion */ +#define UART_ADVFEATURE_DATAINVERT_INIT 0x00000004U /*!< Binary data inversion */ +#define UART_ADVFEATURE_SWAP_INIT 0x00000008U /*!< TX/RX pins swap */ +#define UART_ADVFEATURE_RXOVERRUNDISABLE_INIT 0x00000010U /*!< RX overrun disable */ +#if defined(HAL_DMA_MODULE_ENABLED) +#define UART_ADVFEATURE_DMADISABLEONERROR_INIT 0x00000020U /*!< DMA disable on Reception Error */ +#endif /* HAL_DMA_MODULE_ENABLED */ +#define UART_ADVFEATURE_AUTOBAUDRATE_INIT 0x00000040U /*!< Auto Baud rate detection initialization */ +#define UART_ADVFEATURE_MSBFIRST_INIT 0x00000080U /*!< Most significant bit sent/received first */ +/** + * @} + */ + +/** @defgroup UART_Tx_Inv UART Advanced Feature TX Pin Active Level Inversion + * @{ + */ +#define UART_ADVFEATURE_TXINV_DISABLE 0x00000000U /*!< TX pin active level inversion disable */ +#define UART_ADVFEATURE_TXINV_ENABLE USART_CR2_TXINV /*!< TX pin active level inversion enable */ +/** + * @} + */ + +/** @defgroup UART_Rx_Inv UART Advanced Feature RX Pin Active Level Inversion + * @{ + */ +#define UART_ADVFEATURE_RXINV_DISABLE 0x00000000U /*!< RX pin active level inversion disable */ +#define UART_ADVFEATURE_RXINV_ENABLE USART_CR2_RXINV /*!< RX pin active level inversion enable */ +/** + * @} + */ + +/** @defgroup UART_Data_Inv UART Advanced Feature Binary Data Inversion + * @{ + */ +#define UART_ADVFEATURE_DATAINV_DISABLE 0x00000000U /*!< Binary data inversion disable */ +#define UART_ADVFEATURE_DATAINV_ENABLE USART_CR2_DATAINV /*!< Binary data inversion enable */ +/** + * @} + */ + +/** @defgroup UART_Rx_Tx_Swap UART Advanced Feature RX TX Pins Swap + * @{ + */ +#define UART_ADVFEATURE_SWAP_DISABLE 0x00000000U /*!< TX/RX pins swap disable */ +#define UART_ADVFEATURE_SWAP_ENABLE USART_CR2_SWAP /*!< TX/RX pins swap enable */ +/** + * @} + */ + +/** @defgroup UART_Overrun_Disable UART Advanced Feature Overrun Disable + * @{ + */ +#define UART_ADVFEATURE_OVERRUN_ENABLE 0x00000000U /*!< RX overrun enable */ +#define UART_ADVFEATURE_OVERRUN_DISABLE USART_CR3_OVRDIS /*!< RX overrun disable */ +/** + * @} + */ + +/** @defgroup UART_AutoBaudRate_Enable UART Advanced Feature Auto BaudRate Enable + * @{ + */ +#define UART_ADVFEATURE_AUTOBAUDRATE_DISABLE 0x00000000U /*!< RX Auto Baud rate detection enable */ +#define UART_ADVFEATURE_AUTOBAUDRATE_ENABLE USART_CR2_ABREN /*!< RX Auto Baud rate detection disable */ +/** + * @} + */ + +#if defined(HAL_DMA_MODULE_ENABLED) +/** @defgroup UART_DMA_Disable_on_Rx_Error UART Advanced Feature DMA Disable On Rx Error + * @{ + */ +#define UART_ADVFEATURE_DMA_ENABLEONRXERROR 0x00000000U /*!< DMA enable on Reception Error */ +#define UART_ADVFEATURE_DMA_DISABLEONRXERROR USART_CR3_DDRE /*!< DMA disable on Reception Error */ +/** + * @} + */ +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** @defgroup UART_MSB_First UART Advanced Feature MSB First + * @{ + */ +#define UART_ADVFEATURE_MSBFIRST_DISABLE 0x00000000U /*!< Most significant bit sent/received + first disable */ +#define UART_ADVFEATURE_MSBFIRST_ENABLE USART_CR2_MSBFIRST /*!< Most significant bit sent/received + first enable */ +/** + * @} + */ + +/** @defgroup UART_Stop_Mode_Enable UART Advanced Feature Stop Mode Enable + * @{ + */ +#define UART_ADVFEATURE_STOPMODE_DISABLE 0x00000000U /*!< UART stop mode disable */ +#define UART_ADVFEATURE_STOPMODE_ENABLE USART_CR1_UESM /*!< UART stop mode enable */ +/** + * @} + */ + +/** @defgroup UART_Mute_Mode UART Advanced Feature Mute Mode Enable + * @{ + */ +#define UART_ADVFEATURE_MUTEMODE_DISABLE 0x00000000U /*!< UART mute mode disable */ +#define UART_ADVFEATURE_MUTEMODE_ENABLE USART_CR1_MME /*!< UART mute mode enable */ +/** + * @} + */ + +/** @defgroup UART_CR2_ADDRESS_LSB_POS UART Address-matching LSB Position In CR2 Register + * @{ + */ +#define UART_CR2_ADDRESS_LSB_POS 24U /*!< UART address-matching LSB position in CR2 register */ +/** + * @} + */ + +/** @defgroup UART_WakeUp_from_Stop_Selection UART WakeUp From Stop Selection + * @{ + */ +#define UART_WAKEUP_ON_ADDRESS 0x00000000U /*!< UART wake-up on address */ +#define UART_WAKEUP_ON_STARTBIT USART_CR3_WUS_1 /*!< UART wake-up on start bit */ +#define UART_WAKEUP_ON_READDATA_NONEMPTY USART_CR3_WUS /*!< UART wake-up on receive data register + not empty or RXFIFO is not empty */ +/** + * @} + */ + +/** @defgroup UART_DriverEnable_Polarity UART DriverEnable Polarity + * @{ + */ +#define UART_DE_POLARITY_HIGH 0x00000000U /*!< Driver enable signal is active high */ +#define UART_DE_POLARITY_LOW USART_CR3_DEP /*!< Driver enable signal is active low */ +/** + * @} + */ + +/** @defgroup UART_CR1_DEAT_ADDRESS_LSB_POS UART Driver Enable Assertion Time LSB Position In CR1 Register + * @{ + */ +#define UART_CR1_DEAT_ADDRESS_LSB_POS 21U /*!< UART Driver Enable assertion time LSB + position in CR1 register */ +/** + * @} + */ + +/** @defgroup UART_CR1_DEDT_ADDRESS_LSB_POS UART Driver Enable DeAssertion Time LSB Position In CR1 Register + * @{ + */ +#define UART_CR1_DEDT_ADDRESS_LSB_POS 16U /*!< UART Driver Enable de-assertion time LSB + position in CR1 register */ +/** + * @} + */ + +/** @defgroup UART_Interruption_Mask UART Interruptions Flag Mask + * @{ + */ +#define UART_IT_MASK 0x001FU /*!< UART interruptions flags mask */ +/** + * @} + */ + +/** @defgroup UART_TimeOut_Value UART polling-based communications time-out value + * @{ + */ +#define HAL_UART_TIMEOUT_VALUE 0x1FFFFFFU /*!< UART polling-based communications time-out value */ +/** + * @} + */ + +/** @defgroup UART_Flags UART Status Flags + * Elements values convention: 0xXXXX + * - 0xXXXX : Flag mask in the ISR register + * @{ + */ +#define UART_FLAG_TXFT USART_ISR_TXFT /*!< UART TXFIFO threshold flag */ +#define UART_FLAG_RXFT USART_ISR_RXFT /*!< UART RXFIFO threshold flag */ +#define UART_FLAG_RXFF USART_ISR_RXFF /*!< UART RXFIFO Full flag */ +#define UART_FLAG_TXFE USART_ISR_TXFE /*!< UART TXFIFO Empty flag */ +#define UART_FLAG_REACK USART_ISR_REACK /*!< UART receive enable acknowledge flag */ +#define UART_FLAG_TEACK USART_ISR_TEACK /*!< UART transmit enable acknowledge flag */ +#define UART_FLAG_WUF USART_ISR_WUF /*!< UART wake-up from stop mode flag */ +#define UART_FLAG_RWU USART_ISR_RWU /*!< UART receiver wake-up from mute mode flag */ +#define UART_FLAG_SBKF USART_ISR_SBKF /*!< UART send break flag */ +#define UART_FLAG_CMF USART_ISR_CMF /*!< UART character match flag */ +#define UART_FLAG_BUSY USART_ISR_BUSY /*!< UART busy flag */ +#define UART_FLAG_ABRF USART_ISR_ABRF /*!< UART auto Baud rate flag */ +#define UART_FLAG_ABRE USART_ISR_ABRE /*!< UART auto Baud rate error */ +#define UART_FLAG_RTOF USART_ISR_RTOF /*!< UART receiver timeout flag */ +#define UART_FLAG_CTS USART_ISR_CTS /*!< UART clear to send flag */ +#define UART_FLAG_CTSIF USART_ISR_CTSIF /*!< UART clear to send interrupt flag */ +#define UART_FLAG_LBDF USART_ISR_LBDF /*!< UART LIN break detection flag */ +#define UART_FLAG_TXE USART_ISR_TXE_TXFNF /*!< UART transmit data register empty */ +#define UART_FLAG_TXFNF USART_ISR_TXE_TXFNF /*!< UART TXFIFO not full */ +#define UART_FLAG_TC USART_ISR_TC /*!< UART transmission complete */ +#define UART_FLAG_RXNE USART_ISR_RXNE_RXFNE /*!< UART read data register not empty */ +#define UART_FLAG_RXFNE USART_ISR_RXNE_RXFNE /*!< UART RXFIFO not empty */ +#define UART_FLAG_IDLE USART_ISR_IDLE /*!< UART idle flag */ +#define UART_FLAG_ORE USART_ISR_ORE /*!< UART overrun error */ +#define UART_FLAG_NE USART_ISR_NE /*!< UART noise error */ +#define UART_FLAG_FE USART_ISR_FE /*!< UART frame error */ +#define UART_FLAG_PE USART_ISR_PE /*!< UART parity error */ +/** + * @} + */ + +/** @defgroup UART_Interrupt_definition UART Interrupts Definition + * Elements values convention: 000ZZZZZ0XXYYYYYb + * - YYYYY : Interrupt source position in the XX register (5bits) + * - XX : Interrupt source register (2bits) + * - 01: CR1 register + * - 10: CR2 register + * - 11: CR3 register + * - ZZZZZ : Flag position in the ISR register(5bits) + * Elements values convention: 000000000XXYYYYYb + * - YYYYY : Interrupt source position in the XX register (5bits) + * - XX : Interrupt source register (2bits) + * - 01: CR1 register + * - 10: CR2 register + * - 11: CR3 register + * Elements values convention: 0000ZZZZ00000000b + * - ZZZZ : Flag position in the ISR register(4bits) + * @{ + */ +#define UART_IT_PE 0x0028U /*!< UART parity error interruption */ +#define UART_IT_TXE 0x0727U /*!< UART transmit data register empty interruption */ +#define UART_IT_TXFNF 0x0727U /*!< UART TX FIFO not full interruption */ +#define UART_IT_TC 0x0626U /*!< UART transmission complete interruption */ +#define UART_IT_RXNE 0x0525U /*!< UART read data register not empty interruption */ +#define UART_IT_RXFNE 0x0525U /*!< UART RXFIFO not empty interruption */ +#define UART_IT_IDLE 0x0424U /*!< UART idle interruption */ +#define UART_IT_LBD 0x0846U /*!< UART LIN break detection interruption */ +#define UART_IT_CTS 0x096AU /*!< UART CTS interruption */ +#define UART_IT_CM 0x112EU /*!< UART character match interruption */ +#define UART_IT_WUF 0x1476U /*!< UART wake-up from stop mode interruption */ +#define UART_IT_RXFF 0x183FU /*!< UART RXFIFO full interruption */ +#define UART_IT_TXFE 0x173EU /*!< UART TXFIFO empty interruption */ +#define UART_IT_RXFT 0x1A7CU /*!< UART RXFIFO threshold reached interruption */ +#define UART_IT_TXFT 0x1B77U /*!< UART TXFIFO threshold reached interruption */ +#define UART_IT_RTO 0x0B3AU /*!< UART receiver timeout interruption */ + +#define UART_IT_ERR 0x0060U /*!< UART error interruption */ + +#define UART_IT_ORE 0x0300U /*!< UART overrun error interruption */ +#define UART_IT_NE 0x0200U /*!< UART noise error interruption */ +#define UART_IT_FE 0x0100U /*!< UART frame error interruption */ +/** + * @} + */ + +/** @defgroup UART_IT_CLEAR_Flags UART Interruption Clear Flags + * @{ + */ +#define UART_CLEAR_PEF USART_ICR_PECF /*!< Parity Error Clear Flag */ +#define UART_CLEAR_FEF USART_ICR_FECF /*!< Framing Error Clear Flag */ +#define UART_CLEAR_NEF USART_ICR_NECF /*!< Noise Error detected Clear Flag */ +#define UART_CLEAR_OREF USART_ICR_ORECF /*!< Overrun Error Clear Flag */ +#define UART_CLEAR_IDLEF USART_ICR_IDLECF /*!< IDLE line detected Clear Flag */ +#define UART_CLEAR_TXFECF USART_ICR_TXFECF /*!< TXFIFO empty clear flag */ +#define UART_CLEAR_TCF USART_ICR_TCCF /*!< Transmission Complete Clear Flag */ +#define UART_CLEAR_LBDF USART_ICR_LBDCF /*!< LIN Break Detection Clear Flag */ +#define UART_CLEAR_CTSF USART_ICR_CTSCF /*!< CTS Interrupt Clear Flag */ +#define UART_CLEAR_CMF USART_ICR_CMCF /*!< Character Match Clear Flag */ +#define UART_CLEAR_WUF USART_ICR_WUCF /*!< Wake Up from stop mode Clear Flag */ +#define UART_CLEAR_RTOF USART_ICR_RTOCF /*!< UART receiver timeout clear flag */ +/** + * @} + */ + +/** @defgroup UART_Reception_Type_Values UART Reception type values + * @{ + */ +#define HAL_UART_RECEPTION_STANDARD (0x00000000U) /*!< Standard reception */ +#define HAL_UART_RECEPTION_TOIDLE (0x00000001U) /*!< Reception till completion or IDLE event */ +#define HAL_UART_RECEPTION_TORTO (0x00000002U) /*!< Reception till completion or RTO event */ +#define HAL_UART_RECEPTION_TOCHARMATCH (0x00000003U) /*!< Reception till completion or CM event */ +/** + * @} + */ + +/** @defgroup UART_RxEvent_Type_Values UART RxEvent type values + * @{ + */ +#define HAL_UART_RXEVENT_TC (0x00000000U) /*!< RxEvent linked to Transfer Complete event */ +#define HAL_UART_RXEVENT_HT (0x00000001U) /*!< RxEvent linked to Half Transfer event */ +#define HAL_UART_RXEVENT_IDLE (0x00000002U) /*!< RxEvent linked to IDLE event */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup UART_Exported_Macros UART Exported Macros + * @{ + */ + +/** @brief Reset UART handle states. + * @param __HANDLE__ UART handle. + * @retval None + */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) +#define __HAL_UART_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->gState = HAL_UART_STATE_RESET; \ + (__HANDLE__)->RxState = HAL_UART_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0U) +#else +#define __HAL_UART_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->gState = HAL_UART_STATE_RESET; \ + (__HANDLE__)->RxState = HAL_UART_STATE_RESET; \ + } while(0U) +#endif /*USE_HAL_UART_REGISTER_CALLBACKS */ + +/** @brief Flush the UART Data registers. + * @param __HANDLE__ specifies the UART Handle. + * @retval None + */ +#define __HAL_UART_FLUSH_DRREGISTER(__HANDLE__) \ + do{ \ + SET_BIT((__HANDLE__)->Instance->RQR, UART_RXDATA_FLUSH_REQUEST); \ + SET_BIT((__HANDLE__)->Instance->RQR, UART_TXDATA_FLUSH_REQUEST); \ + } while(0U) + +/** @brief Clear the specified UART pending flag. + * @param __HANDLE__ specifies the UART Handle. + * @param __FLAG__ specifies the flag to check. + * This parameter can be any combination of the following values: + * @arg @ref UART_CLEAR_PEF Parity Error Clear Flag + * @arg @ref UART_CLEAR_FEF Framing Error Clear Flag + * @arg @ref UART_CLEAR_NEF Noise detected Clear Flag + * @arg @ref UART_CLEAR_OREF Overrun Error Clear Flag + * @arg @ref UART_CLEAR_IDLEF IDLE line detected Clear Flag + * @arg @ref UART_CLEAR_TXFECF TXFIFO empty clear Flag + * @arg @ref UART_CLEAR_TCF Transmission Complete Clear Flag + * @arg @ref UART_CLEAR_RTOF Receiver Timeout clear flag + * @arg @ref UART_CLEAR_LBDF LIN Break Detection Clear Flag + * @arg @ref UART_CLEAR_CTSF CTS Interrupt Clear Flag + * @arg @ref UART_CLEAR_CMF Character Match Clear Flag + * @arg @ref UART_CLEAR_WUF Wake Up from stop mode Clear Flag + * @retval None + */ +#define __HAL_UART_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ICR = (__FLAG__)) + +/** @brief Clear the UART PE pending flag. + * @param __HANDLE__ specifies the UART Handle. + * @retval None + */ +#define __HAL_UART_CLEAR_PEFLAG(__HANDLE__) __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_PEF) + +/** @brief Clear the UART FE pending flag. + * @param __HANDLE__ specifies the UART Handle. + * @retval None + */ +#define __HAL_UART_CLEAR_FEFLAG(__HANDLE__) __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_FEF) + +/** @brief Clear the UART NE pending flag. + * @param __HANDLE__ specifies the UART Handle. + * @retval None + */ +#define __HAL_UART_CLEAR_NEFLAG(__HANDLE__) __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_NEF) + +/** @brief Clear the UART ORE pending flag. + * @param __HANDLE__ specifies the UART Handle. + * @retval None + */ +#define __HAL_UART_CLEAR_OREFLAG(__HANDLE__) __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_OREF) + +/** @brief Clear the UART IDLE pending flag. + * @param __HANDLE__ specifies the UART Handle. + * @retval None + */ +#define __HAL_UART_CLEAR_IDLEFLAG(__HANDLE__) __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_IDLEF) + +/** @brief Clear the UART TX FIFO empty clear flag. + * @param __HANDLE__ specifies the UART Handle. + * @retval None + */ +#define __HAL_UART_CLEAR_TXFECF(__HANDLE__) __HAL_UART_CLEAR_FLAG((__HANDLE__), UART_CLEAR_TXFECF) + +/** @brief Check whether the specified UART flag is set or not. + * @param __HANDLE__ specifies the UART Handle. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg @ref UART_FLAG_TXFT TXFIFO threshold flag + * @arg @ref UART_FLAG_RXFT RXFIFO threshold flag + * @arg @ref UART_FLAG_RXFF RXFIFO Full flag + * @arg @ref UART_FLAG_TXFE TXFIFO Empty flag + * @arg @ref UART_FLAG_REACK Receive enable acknowledge flag + * @arg @ref UART_FLAG_TEACK Transmit enable acknowledge flag + * @arg @ref UART_FLAG_WUF Wake up from stop mode flag + * @arg @ref UART_FLAG_RWU Receiver wake up flag (if the UART in mute mode) + * @arg @ref UART_FLAG_SBKF Send Break flag + * @arg @ref UART_FLAG_CMF Character match flag + * @arg @ref UART_FLAG_BUSY Busy flag + * @arg @ref UART_FLAG_ABRF Auto Baud rate detection flag + * @arg @ref UART_FLAG_ABRE Auto Baud rate detection error flag + * @arg @ref UART_FLAG_CTS CTS Change flag + * @arg @ref UART_FLAG_LBDF LIN Break detection flag + * @arg @ref UART_FLAG_TXE Transmit data register empty flag + * @arg @ref UART_FLAG_TXFNF UART TXFIFO not full flag + * @arg @ref UART_FLAG_TC Transmission Complete flag + * @arg @ref UART_FLAG_RXNE Receive data register not empty flag + * @arg @ref UART_FLAG_RXFNE UART RXFIFO not empty flag + * @arg @ref UART_FLAG_RTOF Receiver Timeout flag + * @arg @ref UART_FLAG_IDLE Idle Line detection flag + * @arg @ref UART_FLAG_ORE Overrun Error flag + * @arg @ref UART_FLAG_NE Noise Error flag + * @arg @ref UART_FLAG_FE Framing Error flag + * @arg @ref UART_FLAG_PE Parity Error flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_UART_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->ISR & (__FLAG__)) == (__FLAG__)) + +/** @brief Enable the specified UART interrupt. + * @param __HANDLE__ specifies the UART Handle. + * @param __INTERRUPT__ specifies the UART interrupt source to enable. + * This parameter can be one of the following values: + * @arg @ref UART_IT_RXFF RXFIFO Full interrupt + * @arg @ref UART_IT_TXFE TXFIFO Empty interrupt + * @arg @ref UART_IT_RXFT RXFIFO threshold interrupt + * @arg @ref UART_IT_TXFT TXFIFO threshold interrupt + * @arg @ref UART_IT_WUF Wakeup from stop mode interrupt + * @arg @ref UART_IT_CM Character match interrupt + * @arg @ref UART_IT_CTS CTS change interrupt + * @arg @ref UART_IT_LBD LIN Break detection interrupt + * @arg @ref UART_IT_TXE Transmit Data Register empty interrupt + * @arg @ref UART_IT_TXFNF TX FIFO not full interrupt + * @arg @ref UART_IT_TC Transmission complete interrupt + * @arg @ref UART_IT_RXNE Receive Data register not empty interrupt + * @arg @ref UART_IT_RXFNE RXFIFO not empty interrupt + * @arg @ref UART_IT_RTO Receive Timeout interrupt + * @arg @ref UART_IT_IDLE Idle line detection interrupt + * @arg @ref UART_IT_PE Parity Error interrupt + * @arg @ref UART_IT_ERR Error interrupt (frame error, noise error, overrun error) + * @retval None + */ +#define __HAL_UART_ENABLE_IT(__HANDLE__, __INTERRUPT__) (\ + ((((uint8_t)(__INTERRUPT__)) >> 5U) == 1U)?\ + ((__HANDLE__)->Instance->CR1 |= (1U <<\ + ((__INTERRUPT__) & UART_IT_MASK))): \ + ((((uint8_t)(__INTERRUPT__)) >> 5U) == 2U)?\ + ((__HANDLE__)->Instance->CR2 |= (1U <<\ + ((__INTERRUPT__) & UART_IT_MASK))): \ + ((__HANDLE__)->Instance->CR3 |= (1U <<\ + ((__INTERRUPT__) & UART_IT_MASK)))) + +/** @brief Disable the specified UART interrupt. + * @param __HANDLE__ specifies the UART Handle. + * @param __INTERRUPT__ specifies the UART interrupt source to disable. + * This parameter can be one of the following values: + * @arg @ref UART_IT_RXFF RXFIFO Full interrupt + * @arg @ref UART_IT_TXFE TXFIFO Empty interrupt + * @arg @ref UART_IT_RXFT RXFIFO threshold interrupt + * @arg @ref UART_IT_TXFT TXFIFO threshold interrupt + * @arg @ref UART_IT_WUF Wakeup from stop mode interrupt + * @arg @ref UART_IT_CM Character match interrupt + * @arg @ref UART_IT_CTS CTS change interrupt + * @arg @ref UART_IT_LBD LIN Break detection interrupt + * @arg @ref UART_IT_TXE Transmit Data Register empty interrupt + * @arg @ref UART_IT_TXFNF TX FIFO not full interrupt + * @arg @ref UART_IT_TC Transmission complete interrupt + * @arg @ref UART_IT_RXNE Receive Data register not empty interrupt + * @arg @ref UART_IT_RXFNE RXFIFO not empty interrupt + * @arg @ref UART_IT_RTO Receive Timeout interrupt + * @arg @ref UART_IT_IDLE Idle line detection interrupt + * @arg @ref UART_IT_PE Parity Error interrupt + * @arg @ref UART_IT_ERR Error interrupt (Frame error, noise error, overrun error) + * @retval None + */ +#define __HAL_UART_DISABLE_IT(__HANDLE__, __INTERRUPT__) (\ + ((((uint8_t)(__INTERRUPT__)) >> 5U) == 1U)?\ + ((__HANDLE__)->Instance->CR1 &= ~ (1U <<\ + ((__INTERRUPT__) & UART_IT_MASK))): \ + ((((uint8_t)(__INTERRUPT__)) >> 5U) == 2U)?\ + ((__HANDLE__)->Instance->CR2 &= ~ (1U <<\ + ((__INTERRUPT__) & UART_IT_MASK))): \ + ((__HANDLE__)->Instance->CR3 &= ~ (1U <<\ + ((__INTERRUPT__) & UART_IT_MASK)))) + +/** @brief Check whether the specified UART interrupt has occurred or not. + * @param __HANDLE__ specifies the UART Handle. + * @param __INTERRUPT__ specifies the UART interrupt to check. + * This parameter can be one of the following values: + * @arg @ref UART_IT_RXFF RXFIFO Full interrupt + * @arg @ref UART_IT_TXFE TXFIFO Empty interrupt + * @arg @ref UART_IT_RXFT RXFIFO threshold interrupt + * @arg @ref UART_IT_TXFT TXFIFO threshold interrupt + * @arg @ref UART_IT_WUF Wakeup from stop mode interrupt + * @arg @ref UART_IT_CM Character match interrupt + * @arg @ref UART_IT_CTS CTS change interrupt + * @arg @ref UART_IT_LBD LIN Break detection interrupt + * @arg @ref UART_IT_TXE Transmit Data Register empty interrupt + * @arg @ref UART_IT_TXFNF TX FIFO not full interrupt + * @arg @ref UART_IT_TC Transmission complete interrupt + * @arg @ref UART_IT_RXNE Receive Data register not empty interrupt + * @arg @ref UART_IT_RXFNE RXFIFO not empty interrupt + * @arg @ref UART_IT_RTO Receive Timeout interrupt + * @arg @ref UART_IT_IDLE Idle line detection interrupt + * @arg @ref UART_IT_PE Parity Error interrupt + * @arg @ref UART_IT_ERR Error interrupt (Frame error, noise error, overrun error) + * @retval The new state of __INTERRUPT__ (SET or RESET). + */ +#define __HAL_UART_GET_IT(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->ISR\ + & (1U << ((__INTERRUPT__)>> 8U))) != RESET) ? SET : RESET) + +/** @brief Check whether the specified UART interrupt source is enabled or not. + * @param __HANDLE__ specifies the UART Handle. + * @param __INTERRUPT__ specifies the UART interrupt source to check. + * This parameter can be one of the following values: + * @arg @ref UART_IT_RXFF RXFIFO Full interrupt + * @arg @ref UART_IT_TXFE TXFIFO Empty interrupt + * @arg @ref UART_IT_RXFT RXFIFO threshold interrupt + * @arg @ref UART_IT_TXFT TXFIFO threshold interrupt + * @arg @ref UART_IT_WUF Wakeup from stop mode interrupt + * @arg @ref UART_IT_CM Character match interrupt + * @arg @ref UART_IT_CTS CTS change interrupt + * @arg @ref UART_IT_LBD LIN Break detection interrupt + * @arg @ref UART_IT_TXE Transmit Data Register empty interrupt + * @arg @ref UART_IT_TXFNF TX FIFO not full interrupt + * @arg @ref UART_IT_TC Transmission complete interrupt + * @arg @ref UART_IT_RXNE Receive Data register not empty interrupt + * @arg @ref UART_IT_RXFNE RXFIFO not empty interrupt + * @arg @ref UART_IT_RTO Receive Timeout interrupt + * @arg @ref UART_IT_IDLE Idle line detection interrupt + * @arg @ref UART_IT_PE Parity Error interrupt + * @arg @ref UART_IT_ERR Error interrupt (Frame error, noise error, overrun error) + * @retval The new state of __INTERRUPT__ (SET or RESET). + */ +#define __HAL_UART_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((((((uint8_t)(__INTERRUPT__)) >> 5U) == 1U) ?\ + (__HANDLE__)->Instance->CR1 : \ + (((((uint8_t)(__INTERRUPT__)) >> 5U) == 2U) ?\ + (__HANDLE__)->Instance->CR2 : \ + (__HANDLE__)->Instance->CR3)) & (1U <<\ + (((uint16_t)(__INTERRUPT__)) &\ + UART_IT_MASK))) != RESET) ? SET : RESET) + +/** @brief Clear the specified UART ISR flag, in setting the proper ICR register flag. + * @param __HANDLE__ specifies the UART Handle. + * @param __IT_CLEAR__ specifies the interrupt clear register flag that needs to be set + * to clear the corresponding interrupt + * This parameter can be one of the following values: + * @arg @ref UART_CLEAR_PEF Parity Error Clear Flag + * @arg @ref UART_CLEAR_FEF Framing Error Clear Flag + * @arg @ref UART_CLEAR_NEF Noise detected Clear Flag + * @arg @ref UART_CLEAR_OREF Overrun Error Clear Flag + * @arg @ref UART_CLEAR_IDLEF IDLE line detected Clear Flag + * @arg @ref UART_CLEAR_RTOF Receiver timeout clear flag + * @arg @ref UART_CLEAR_TXFECF TXFIFO empty Clear Flag + * @arg @ref UART_CLEAR_TCF Transmission Complete Clear Flag + * @arg @ref UART_CLEAR_LBDF LIN Break Detection Clear Flag + * @arg @ref UART_CLEAR_CTSF CTS Interrupt Clear Flag + * @arg @ref UART_CLEAR_CMF Character Match Clear Flag + * @arg @ref UART_CLEAR_WUF Wake Up from stop mode Clear Flag + * @retval None + */ +#define __HAL_UART_CLEAR_IT(__HANDLE__, __IT_CLEAR__) ((__HANDLE__)->Instance->ICR = (uint32_t)(__IT_CLEAR__)) + +/** @brief Set a specific UART request flag. + * @param __HANDLE__ specifies the UART Handle. + * @param __REQ__ specifies the request flag to set + * This parameter can be one of the following values: + * @arg @ref UART_AUTOBAUD_REQUEST Auto-Baud Rate Request + * @arg @ref UART_SENDBREAK_REQUEST Send Break Request + * @arg @ref UART_MUTE_MODE_REQUEST Mute Mode Request + * @arg @ref UART_RXDATA_FLUSH_REQUEST Receive Data flush Request + * @arg @ref UART_TXDATA_FLUSH_REQUEST Transmit data flush Request + * @retval None + */ +#define __HAL_UART_SEND_REQ(__HANDLE__, __REQ__) ((__HANDLE__)->Instance->RQR |= (uint16_t)(__REQ__)) + +/** @brief Enable the UART one bit sample method. + * @param __HANDLE__ specifies the UART Handle. + * @retval None + */ +#define __HAL_UART_ONE_BIT_SAMPLE_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3|= USART_CR3_ONEBIT) + +/** @brief Disable the UART one bit sample method. + * @param __HANDLE__ specifies the UART Handle. + * @retval None + */ +#define __HAL_UART_ONE_BIT_SAMPLE_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3 &= ~USART_CR3_ONEBIT) + +/** @brief Enable UART. + * @param __HANDLE__ specifies the UART Handle. + * @retval None + */ +#define __HAL_UART_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= USART_CR1_UE) + +/** @brief Disable UART. + * @param __HANDLE__ specifies the UART Handle. + * @retval None + */ +#define __HAL_UART_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~USART_CR1_UE) + +/** @brief Enable CTS flow control. + * @note This macro allows to enable CTS hardware flow control for a given UART instance, + * without need to call HAL_UART_Init() function. + * As involving direct access to UART registers, usage of this macro should be fully endorsed by user. + * @note As macro is expected to be used for modifying CTS Hw flow control feature activation, without need + * for USART instance Deinit/Init, following conditions for macro call should be fulfilled : + * - UART instance should have already been initialised (through call of HAL_UART_Init() ) + * - macro could only be called when corresponding UART instance is disabled + * (i.e. __HAL_UART_DISABLE(__HANDLE__)) and should be followed by an Enable + * macro (i.e. __HAL_UART_ENABLE(__HANDLE__)). + * @param __HANDLE__ specifies the UART Handle. + * @retval None + */ +#define __HAL_UART_HWCONTROL_CTS_ENABLE(__HANDLE__) \ + do{ \ + ATOMIC_SET_BIT((__HANDLE__)->Instance->CR3, USART_CR3_CTSE); \ + (__HANDLE__)->Init.HwFlowCtl |= USART_CR3_CTSE; \ + } while(0U) + +/** @brief Disable CTS flow control. + * @note This macro allows to disable CTS hardware flow control for a given UART instance, + * without need to call HAL_UART_Init() function. + * As involving direct access to UART registers, usage of this macro should be fully endorsed by user. + * @note As macro is expected to be used for modifying CTS Hw flow control feature activation, without need + * for USART instance Deinit/Init, following conditions for macro call should be fulfilled : + * - UART instance should have already been initialised (through call of HAL_UART_Init() ) + * - macro could only be called when corresponding UART instance is disabled + * (i.e. __HAL_UART_DISABLE(__HANDLE__)) and should be followed by an Enable + * macro (i.e. __HAL_UART_ENABLE(__HANDLE__)). + * @param __HANDLE__ specifies the UART Handle. + * @retval None + */ +#define __HAL_UART_HWCONTROL_CTS_DISABLE(__HANDLE__) \ + do{ \ + ATOMIC_CLEAR_BIT((__HANDLE__)->Instance->CR3, USART_CR3_CTSE); \ + (__HANDLE__)->Init.HwFlowCtl &= ~(USART_CR3_CTSE); \ + } while(0U) + +/** @brief Enable RTS flow control. + * @note This macro allows to enable RTS hardware flow control for a given UART instance, + * without need to call HAL_UART_Init() function. + * As involving direct access to UART registers, usage of this macro should be fully endorsed by user. + * @note As macro is expected to be used for modifying RTS Hw flow control feature activation, without need + * for USART instance Deinit/Init, following conditions for macro call should be fulfilled : + * - UART instance should have already been initialised (through call of HAL_UART_Init() ) + * - macro could only be called when corresponding UART instance is disabled + * (i.e. __HAL_UART_DISABLE(__HANDLE__)) and should be followed by an Enable + * macro (i.e. __HAL_UART_ENABLE(__HANDLE__)). + * @param __HANDLE__ specifies the UART Handle. + * @retval None + */ +#define __HAL_UART_HWCONTROL_RTS_ENABLE(__HANDLE__) \ + do{ \ + ATOMIC_SET_BIT((__HANDLE__)->Instance->CR3, USART_CR3_RTSE); \ + (__HANDLE__)->Init.HwFlowCtl |= USART_CR3_RTSE; \ + } while(0U) + +/** @brief Disable RTS flow control. + * @note This macro allows to disable RTS hardware flow control for a given UART instance, + * without need to call HAL_UART_Init() function. + * As involving direct access to UART registers, usage of this macro should be fully endorsed by user. + * @note As macro is expected to be used for modifying RTS Hw flow control feature activation, without need + * for USART instance Deinit/Init, following conditions for macro call should be fulfilled : + * - UART instance should have already been initialised (through call of HAL_UART_Init() ) + * - macro could only be called when corresponding UART instance is disabled + * (i.e. __HAL_UART_DISABLE(__HANDLE__)) and should be followed by an Enable + * macro (i.e. __HAL_UART_ENABLE(__HANDLE__)). + * @param __HANDLE__ specifies the UART Handle. + * @retval None + */ +#define __HAL_UART_HWCONTROL_RTS_DISABLE(__HANDLE__) \ + do{ \ + ATOMIC_CLEAR_BIT((__HANDLE__)->Instance->CR3, USART_CR3_RTSE);\ + (__HANDLE__)->Init.HwFlowCtl &= ~(USART_CR3_RTSE); \ + } while(0U) +/** + * @} + */ + +/* Private macros --------------------------------------------------------*/ +/** @defgroup UART_Private_Macros UART Private Macros + * @{ + */ +/** @brief Get UART clok division factor from clock prescaler value. + * @param __CLOCKPRESCALER__ UART prescaler value. + * @retval UART clock division factor + */ +#define UART_GET_DIV_FACTOR(__CLOCKPRESCALER__) \ + (((__CLOCKPRESCALER__) == UART_PRESCALER_DIV1) ? 1U : \ + ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV2) ? 2U : \ + ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV4) ? 4U : \ + ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV6) ? 6U : \ + ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV8) ? 8U : \ + ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV10) ? 10U : \ + ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV12) ? 12U : \ + ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV16) ? 16U : \ + ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV32) ? 32U : \ + ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV64) ? 64U : \ + ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV128) ? 128U : \ + ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV256) ? 256U : 1U) + +/** @brief BRR division operation to set BRR register with LPUART. + * @param __PCLK__ LPUART clock. + * @param __BAUD__ Baud rate set by the user. + * @param __CLOCKPRESCALER__ UART prescaler value. + * @retval Division result + */ +#define UART_DIV_LPUART(__PCLK__, __BAUD__, __CLOCKPRESCALER__) \ + ((uint32_t)((((((uint64_t)(__PCLK__))/(UARTPrescTable[(__CLOCKPRESCALER__)]))*256U)+ \ + (uint32_t)((__BAUD__)/2U)) / (__BAUD__)) \ + ) + +/** @brief BRR division operation to set BRR register in 8-bit oversampling mode. + * @param __PCLK__ UART clock. + * @param __BAUD__ Baud rate set by the user. + * @param __CLOCKPRESCALER__ UART prescaler value. + * @retval Division result + */ +#define UART_DIV_SAMPLING8(__PCLK__, __BAUD__, __CLOCKPRESCALER__) \ + (((((__PCLK__)/UARTPrescTable[(__CLOCKPRESCALER__)])*2U) + ((__BAUD__)/2U)) / (__BAUD__)) + +/** @brief BRR division operation to set BRR register in 16-bit oversampling mode. + * @param __PCLK__ UART clock. + * @param __BAUD__ Baud rate set by the user. + * @param __CLOCKPRESCALER__ UART prescaler value. + * @retval Division result + */ +#define UART_DIV_SAMPLING16(__PCLK__, __BAUD__, __CLOCKPRESCALER__) \ + ((((__PCLK__)/UARTPrescTable[(__CLOCKPRESCALER__)]) + ((__BAUD__)/2U)) / (__BAUD__)) + +/** @brief Check whether or not UART instance is Low Power UART. + * @param __HANDLE__ specifies the UART Handle. + * @retval SET (instance is LPUART) or RESET (instance isn't LPUART) + */ +#define UART_INSTANCE_LOWPOWER(__HANDLE__) (IS_LPUART_INSTANCE((__HANDLE__)->Instance)) + +/** @brief Check UART Baud rate. + * @param __BAUDRATE__ Baudrate specified by the user. + * The maximum Baud Rate is derived from the maximum clock on H5 (i.e. 250 MHz) + * divided by the smallest oversampling used on the USART (i.e. 8) + * @retval SET (__BAUDRATE__ is valid) or RESET (__BAUDRATE__ is invalid) + */ +#define IS_UART_BAUDRATE(__BAUDRATE__) ((__BAUDRATE__) < 20000000U) + +/** @brief Check UART assertion time. + * @param __TIME__ 5-bit value assertion time. + * @retval Test result (TRUE or FALSE). + */ +#define IS_UART_ASSERTIONTIME(__TIME__) ((__TIME__) <= 0x1FU) + +/** @brief Check UART deassertion time. + * @param __TIME__ 5-bit value deassertion time. + * @retval Test result (TRUE or FALSE). + */ +#define IS_UART_DEASSERTIONTIME(__TIME__) ((__TIME__) <= 0x1FU) + +/** + * @brief Ensure that UART frame number of stop bits is valid. + * @param __STOPBITS__ UART frame number of stop bits. + * @retval SET (__STOPBITS__ is valid) or RESET (__STOPBITS__ is invalid) + */ +#define IS_UART_STOPBITS(__STOPBITS__) (((__STOPBITS__) == UART_STOPBITS_0_5) || \ + ((__STOPBITS__) == UART_STOPBITS_1) || \ + ((__STOPBITS__) == UART_STOPBITS_1_5) || \ + ((__STOPBITS__) == UART_STOPBITS_2)) + +/** + * @brief Ensure that LPUART frame number of stop bits is valid. + * @param __STOPBITS__ LPUART frame number of stop bits. + * @retval SET (__STOPBITS__ is valid) or RESET (__STOPBITS__ is invalid) + */ +#define IS_LPUART_STOPBITS(__STOPBITS__) (((__STOPBITS__) == UART_STOPBITS_1) || \ + ((__STOPBITS__) == UART_STOPBITS_2)) + +/** + * @brief Ensure that UART frame parity is valid. + * @param __PARITY__ UART frame parity. + * @retval SET (__PARITY__ is valid) or RESET (__PARITY__ is invalid) + */ +#define IS_UART_PARITY(__PARITY__) (((__PARITY__) == UART_PARITY_NONE) || \ + ((__PARITY__) == UART_PARITY_EVEN) || \ + ((__PARITY__) == UART_PARITY_ODD)) + +/** + * @brief Ensure that UART hardware flow control is valid. + * @param __CONTROL__ UART hardware flow control. + * @retval SET (__CONTROL__ is valid) or RESET (__CONTROL__ is invalid) + */ +#define IS_UART_HARDWARE_FLOW_CONTROL(__CONTROL__)\ + (((__CONTROL__) == UART_HWCONTROL_NONE) || \ + ((__CONTROL__) == UART_HWCONTROL_RTS) || \ + ((__CONTROL__) == UART_HWCONTROL_CTS) || \ + ((__CONTROL__) == UART_HWCONTROL_RTS_CTS)) + +/** + * @brief Ensure that UART communication mode is valid. + * @param __MODE__ UART communication mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_UART_MODE(__MODE__) ((((__MODE__) & (~((uint32_t)(UART_MODE_TX_RX)))) == 0x00U) && ((__MODE__) != 0x00U)) + +/** + * @brief Ensure that UART state is valid. + * @param __STATE__ UART state. + * @retval SET (__STATE__ is valid) or RESET (__STATE__ is invalid) + */ +#define IS_UART_STATE(__STATE__) (((__STATE__) == UART_STATE_DISABLE) || \ + ((__STATE__) == UART_STATE_ENABLE)) + +/** + * @brief Ensure that UART oversampling is valid. + * @param __SAMPLING__ UART oversampling. + * @retval SET (__SAMPLING__ is valid) or RESET (__SAMPLING__ is invalid) + */ +#define IS_UART_OVERSAMPLING(__SAMPLING__) (((__SAMPLING__) == UART_OVERSAMPLING_16) || \ + ((__SAMPLING__) == UART_OVERSAMPLING_8)) + +/** + * @brief Ensure that UART frame sampling is valid. + * @param __ONEBIT__ UART frame sampling. + * @retval SET (__ONEBIT__ is valid) or RESET (__ONEBIT__ is invalid) + */ +#define IS_UART_ONE_BIT_SAMPLE(__ONEBIT__) (((__ONEBIT__) == UART_ONE_BIT_SAMPLE_DISABLE) || \ + ((__ONEBIT__) == UART_ONE_BIT_SAMPLE_ENABLE)) + +/** + * @brief Ensure that UART auto Baud rate detection mode is valid. + * @param __MODE__ UART auto Baud rate detection mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(__MODE__) (((__MODE__) == UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT) || \ + ((__MODE__) == UART_ADVFEATURE_AUTOBAUDRATE_ONFALLINGEDGE) || \ + ((__MODE__) == UART_ADVFEATURE_AUTOBAUDRATE_ON0X7FFRAME) || \ + ((__MODE__) == UART_ADVFEATURE_AUTOBAUDRATE_ON0X55FRAME)) + +/** + * @brief Ensure that UART receiver timeout setting is valid. + * @param __TIMEOUT__ UART receiver timeout setting. + * @retval SET (__TIMEOUT__ is valid) or RESET (__TIMEOUT__ is invalid) + */ +#define IS_UART_RECEIVER_TIMEOUT(__TIMEOUT__) (((__TIMEOUT__) == UART_RECEIVER_TIMEOUT_DISABLE) || \ + ((__TIMEOUT__) == UART_RECEIVER_TIMEOUT_ENABLE)) + +/** @brief Check the receiver timeout value. + * @note The maximum UART receiver timeout value is 0xFFFFFF. + * @param __TIMEOUTVALUE__ receiver timeout value. + * @retval Test result (TRUE or FALSE) + */ +#define IS_UART_RECEIVER_TIMEOUT_VALUE(__TIMEOUTVALUE__) ((__TIMEOUTVALUE__) <= 0xFFFFFFU) + +/** + * @brief Ensure that UART LIN state is valid. + * @param __LIN__ UART LIN state. + * @retval SET (__LIN__ is valid) or RESET (__LIN__ is invalid) + */ +#define IS_UART_LIN(__LIN__) (((__LIN__) == UART_LIN_DISABLE) || \ + ((__LIN__) == UART_LIN_ENABLE)) + +/** + * @brief Ensure that UART LIN break detection length is valid. + * @param __LENGTH__ UART LIN break detection length. + * @retval SET (__LENGTH__ is valid) or RESET (__LENGTH__ is invalid) + */ +#define IS_UART_LIN_BREAK_DETECT_LENGTH(__LENGTH__) (((__LENGTH__) == UART_LINBREAKDETECTLENGTH_10B) || \ + ((__LENGTH__) == UART_LINBREAKDETECTLENGTH_11B)) + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief Ensure that UART DMA TX state is valid. + * @param __DMATX__ UART DMA TX state. + * @retval SET (__DMATX__ is valid) or RESET (__DMATX__ is invalid) + */ +#define IS_UART_DMA_TX(__DMATX__) (((__DMATX__) == UART_DMA_TX_DISABLE) || \ + ((__DMATX__) == UART_DMA_TX_ENABLE)) + +/** + * @brief Ensure that UART DMA RX state is valid. + * @param __DMARX__ UART DMA RX state. + * @retval SET (__DMARX__ is valid) or RESET (__DMARX__ is invalid) + */ +#define IS_UART_DMA_RX(__DMARX__) (((__DMARX__) == UART_DMA_RX_DISABLE) || \ + ((__DMARX__) == UART_DMA_RX_ENABLE)) + +#endif /* HAL_DMA_MODULE_ENABLED */ +/** + * @brief Ensure that UART half-duplex state is valid. + * @param __HDSEL__ UART half-duplex state. + * @retval SET (__HDSEL__ is valid) or RESET (__HDSEL__ is invalid) + */ +#define IS_UART_HALF_DUPLEX(__HDSEL__) (((__HDSEL__) == UART_HALF_DUPLEX_DISABLE) || \ + ((__HDSEL__) == UART_HALF_DUPLEX_ENABLE)) + +/** + * @brief Ensure that UART wake-up method is valid. + * @param __WAKEUP__ UART wake-up method . + * @retval SET (__WAKEUP__ is valid) or RESET (__WAKEUP__ is invalid) + */ +#define IS_UART_WAKEUPMETHOD(__WAKEUP__) (((__WAKEUP__) == UART_WAKEUPMETHOD_IDLELINE) || \ + ((__WAKEUP__) == UART_WAKEUPMETHOD_ADDRESSMARK)) + +/** + * @brief Ensure that UART request parameter is valid. + * @param __PARAM__ UART request parameter. + * @retval SET (__PARAM__ is valid) or RESET (__PARAM__ is invalid) + */ +#define IS_UART_REQUEST_PARAMETER(__PARAM__) (((__PARAM__) == UART_AUTOBAUD_REQUEST) || \ + ((__PARAM__) == UART_SENDBREAK_REQUEST) || \ + ((__PARAM__) == UART_MUTE_MODE_REQUEST) || \ + ((__PARAM__) == UART_RXDATA_FLUSH_REQUEST) || \ + ((__PARAM__) == UART_TXDATA_FLUSH_REQUEST)) + +/** + * @brief Ensure that UART advanced features initialization is valid. + * @param __INIT__ UART advanced features initialization. + * @retval SET (__INIT__ is valid) or RESET (__INIT__ is invalid) + */ +#if defined(HAL_DMA_MODULE_ENABLED) +#define IS_UART_ADVFEATURE_INIT(__INIT__) ((__INIT__) <= (UART_ADVFEATURE_NO_INIT | \ + UART_ADVFEATURE_TXINVERT_INIT | \ + UART_ADVFEATURE_RXINVERT_INIT | \ + UART_ADVFEATURE_DATAINVERT_INIT | \ + UART_ADVFEATURE_SWAP_INIT | \ + UART_ADVFEATURE_RXOVERRUNDISABLE_INIT | \ + UART_ADVFEATURE_DMADISABLEONERROR_INIT | \ + UART_ADVFEATURE_AUTOBAUDRATE_INIT | \ + UART_ADVFEATURE_MSBFIRST_INIT)) +#else +#define IS_UART_ADVFEATURE_INIT(__INIT__) ((__INIT__) <= (UART_ADVFEATURE_NO_INIT | \ + UART_ADVFEATURE_TXINVERT_INIT | \ + UART_ADVFEATURE_RXINVERT_INIT | \ + UART_ADVFEATURE_DATAINVERT_INIT | \ + UART_ADVFEATURE_SWAP_INIT | \ + UART_ADVFEATURE_RXOVERRUNDISABLE_INIT | \ + UART_ADVFEATURE_AUTOBAUDRATE_INIT | \ + UART_ADVFEATURE_MSBFIRST_INIT)) +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Ensure that UART frame TX inversion setting is valid. + * @param __TXINV__ UART frame TX inversion setting. + * @retval SET (__TXINV__ is valid) or RESET (__TXINV__ is invalid) + */ +#define IS_UART_ADVFEATURE_TXINV(__TXINV__) (((__TXINV__) == UART_ADVFEATURE_TXINV_DISABLE) || \ + ((__TXINV__) == UART_ADVFEATURE_TXINV_ENABLE)) + +/** + * @brief Ensure that UART frame RX inversion setting is valid. + * @param __RXINV__ UART frame RX inversion setting. + * @retval SET (__RXINV__ is valid) or RESET (__RXINV__ is invalid) + */ +#define IS_UART_ADVFEATURE_RXINV(__RXINV__) (((__RXINV__) == UART_ADVFEATURE_RXINV_DISABLE) || \ + ((__RXINV__) == UART_ADVFEATURE_RXINV_ENABLE)) + +/** + * @brief Ensure that UART frame data inversion setting is valid. + * @param __DATAINV__ UART frame data inversion setting. + * @retval SET (__DATAINV__ is valid) or RESET (__DATAINV__ is invalid) + */ +#define IS_UART_ADVFEATURE_DATAINV(__DATAINV__) (((__DATAINV__) == UART_ADVFEATURE_DATAINV_DISABLE) || \ + ((__DATAINV__) == UART_ADVFEATURE_DATAINV_ENABLE)) + +/** + * @brief Ensure that UART frame RX/TX pins swap setting is valid. + * @param __SWAP__ UART frame RX/TX pins swap setting. + * @retval SET (__SWAP__ is valid) or RESET (__SWAP__ is invalid) + */ +#define IS_UART_ADVFEATURE_SWAP(__SWAP__) (((__SWAP__) == UART_ADVFEATURE_SWAP_DISABLE) || \ + ((__SWAP__) == UART_ADVFEATURE_SWAP_ENABLE)) + +/** + * @brief Ensure that UART frame overrun setting is valid. + * @param __OVERRUN__ UART frame overrun setting. + * @retval SET (__OVERRUN__ is valid) or RESET (__OVERRUN__ is invalid) + */ +#define IS_UART_OVERRUN(__OVERRUN__) (((__OVERRUN__) == UART_ADVFEATURE_OVERRUN_ENABLE) || \ + ((__OVERRUN__) == UART_ADVFEATURE_OVERRUN_DISABLE)) + +/** + * @brief Ensure that UART auto Baud rate state is valid. + * @param __AUTOBAUDRATE__ UART auto Baud rate state. + * @retval SET (__AUTOBAUDRATE__ is valid) or RESET (__AUTOBAUDRATE__ is invalid) + */ +#define IS_UART_ADVFEATURE_AUTOBAUDRATE(__AUTOBAUDRATE__) (((__AUTOBAUDRATE__) == \ + UART_ADVFEATURE_AUTOBAUDRATE_DISABLE) || \ + ((__AUTOBAUDRATE__) == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE)) + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief Ensure that UART DMA enabling or disabling on error setting is valid. + * @param __DMA__ UART DMA enabling or disabling on error setting. + * @retval SET (__DMA__ is valid) or RESET (__DMA__ is invalid) + */ +#define IS_UART_ADVFEATURE_DMAONRXERROR(__DMA__) (((__DMA__) == UART_ADVFEATURE_DMA_ENABLEONRXERROR) || \ + ((__DMA__) == UART_ADVFEATURE_DMA_DISABLEONRXERROR)) +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Ensure that UART frame MSB first setting is valid. + * @param __MSBFIRST__ UART frame MSB first setting. + * @retval SET (__MSBFIRST__ is valid) or RESET (__MSBFIRST__ is invalid) + */ +#define IS_UART_ADVFEATURE_MSBFIRST(__MSBFIRST__) (((__MSBFIRST__) == UART_ADVFEATURE_MSBFIRST_DISABLE) || \ + ((__MSBFIRST__) == UART_ADVFEATURE_MSBFIRST_ENABLE)) + +/** + * @brief Ensure that UART stop mode state is valid. + * @param __STOPMODE__ UART stop mode state. + * @retval SET (__STOPMODE__ is valid) or RESET (__STOPMODE__ is invalid) + */ +#define IS_UART_ADVFEATURE_STOPMODE(__STOPMODE__) (((__STOPMODE__) == UART_ADVFEATURE_STOPMODE_DISABLE) || \ + ((__STOPMODE__) == UART_ADVFEATURE_STOPMODE_ENABLE)) + +/** + * @brief Ensure that UART mute mode state is valid. + * @param __MUTE__ UART mute mode state. + * @retval SET (__MUTE__ is valid) or RESET (__MUTE__ is invalid) + */ +#define IS_UART_MUTE_MODE(__MUTE__) (((__MUTE__) == UART_ADVFEATURE_MUTEMODE_DISABLE) || \ + ((__MUTE__) == UART_ADVFEATURE_MUTEMODE_ENABLE)) + +/** + * @brief Ensure that UART wake-up selection is valid. + * @param __WAKE__ UART wake-up selection. + * @retval SET (__WAKE__ is valid) or RESET (__WAKE__ is invalid) + */ +#define IS_UART_WAKEUP_SELECTION(__WAKE__) (((__WAKE__) == UART_WAKEUP_ON_ADDRESS) || \ + ((__WAKE__) == UART_WAKEUP_ON_STARTBIT) || \ + ((__WAKE__) == UART_WAKEUP_ON_READDATA_NONEMPTY)) + +/** + * @brief Ensure that UART driver enable polarity is valid. + * @param __POLARITY__ UART driver enable polarity. + * @retval SET (__POLARITY__ is valid) or RESET (__POLARITY__ is invalid) + */ +#define IS_UART_DE_POLARITY(__POLARITY__) (((__POLARITY__) == UART_DE_POLARITY_HIGH) || \ + ((__POLARITY__) == UART_DE_POLARITY_LOW)) + +/** + * @brief Ensure that UART Prescaler is valid. + * @param __CLOCKPRESCALER__ UART Prescaler value. + * @retval SET (__CLOCKPRESCALER__ is valid) or RESET (__CLOCKPRESCALER__ is invalid) + */ +#define IS_UART_PRESCALER(__CLOCKPRESCALER__) (((__CLOCKPRESCALER__) == UART_PRESCALER_DIV1) || \ + ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV2) || \ + ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV4) || \ + ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV6) || \ + ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV8) || \ + ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV10) || \ + ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV12) || \ + ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV16) || \ + ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV32) || \ + ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV64) || \ + ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV128) || \ + ((__CLOCKPRESCALER__) == UART_PRESCALER_DIV256)) + +/** + * @} + */ + +/* Include UART HAL Extended module */ +#include "stm32h5xx_hal_uart_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup UART_Exported_Functions UART Exported Functions + * @{ + */ + +/** @addtogroup UART_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ + +/* Initialization and de-initialization functions ****************************/ +HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength); +HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod); +HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart); +void HAL_UART_MspInit(UART_HandleTypeDef *huart); +void HAL_UART_MspDeInit(UART_HandleTypeDef *huart); + +/* Callbacks Register/UnRegister functions ***********************************/ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) +HAL_StatusTypeDef HAL_UART_RegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID, + pUART_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_UART_UnRegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID); + +HAL_StatusTypeDef HAL_UART_RegisterRxEventCallback(UART_HandleTypeDef *huart, pUART_RxEventCallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_UART_UnRegisterRxEventCallback(UART_HandleTypeDef *huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @addtogroup UART_Exported_Functions_Group2 IO operation functions + * @{ + */ + +/* IO operation functions *****************************************************/ +HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); +#if defined(HAL_DMA_MODULE_ENABLED) +HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart); +#endif /* HAL_DMA_MODULE_ENABLED */ +/* Transfer Abort functions */ +HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart); + +void HAL_UART_IRQHandler(UART_HandleTypeDef *huart); +void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart); +void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart); +void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart); +void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart); +void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart); +void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart); +void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart); +void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart); + +void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size); + +/** + * @} + */ + +/** @addtogroup UART_Exported_Functions_Group3 Peripheral Control functions + * @{ + */ + +/* Peripheral Control functions ************************************************/ +void HAL_UART_ReceiverTimeout_Config(UART_HandleTypeDef *huart, uint32_t TimeoutValue); +HAL_StatusTypeDef HAL_UART_EnableReceiverTimeout(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_UART_DisableReceiverTimeout(UART_HandleTypeDef *huart); + +HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef *huart); +void HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart); + +/** + * @} + */ + +/** @addtogroup UART_Exported_Functions_Group4 Peripheral State and Error functions + * @{ + */ + +/* Peripheral State and Errors functions **************************************************/ +HAL_UART_StateTypeDef HAL_UART_GetState(const UART_HandleTypeDef *huart); +uint32_t HAL_UART_GetError(const UART_HandleTypeDef *huart); + +/** + * @} + */ + +/** + * @} + */ + +/* Private functions -----------------------------------------------------------*/ +/** @addtogroup UART_Private_Functions UART Private Functions + * @{ + */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) +void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ +HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart); +HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart); +HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, + uint32_t Tickstart, uint32_t Timeout); +void UART_AdvFeatureConfig(UART_HandleTypeDef *huart); +HAL_StatusTypeDef UART_Start_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); +#if defined(HAL_DMA_MODULE_ENABLED) +HAL_StatusTypeDef UART_Start_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @} + */ + +/* Private variables -----------------------------------------------------------*/ +/** @defgroup UART_Private_variables UART Private variables + * @{ + */ +/* Prescaler Table used in BRR computation macros. + Declared as extern here to allow use of private UART macros, outside of HAL UART functions */ +extern const uint16_t UARTPrescTable[12]; +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_UART_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_uart_ex.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_uart_ex.h new file mode 100644 index 0000000000..1eb530fa3f --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_uart_ex.h @@ -0,0 +1,401 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_uart_ex.h + * @author MCD Application Team + * @brief Header file of UART HAL Extended module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_UART_EX_H +#define STM32H5xx_HAL_UART_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup UARTEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup UARTEx_Exported_Types UARTEx Exported Types + * @{ + */ + +/** + * @brief UART wake up from stop mode parameters + */ +typedef struct +{ + uint32_t WakeUpEvent; /*!< Specifies which event will activate the Wakeup from Stop mode flag (WUF). + This parameter can be a value of @ref UART_WakeUp_from_Stop_Selection. + If set to UART_WAKEUP_ON_ADDRESS, the two other fields below must + be filled up. */ + + uint16_t AddressLength; /*!< Specifies whether the address is 4 or 7-bit long. + This parameter can be a value of @ref UARTEx_WakeUp_Address_Length. */ + + uint8_t Address; /*!< UART/USART node address (7-bit long max). */ +} UART_WakeUpTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup UARTEx_Exported_Constants UARTEx Exported Constants + * @{ + */ + +/** @defgroup UARTEx_Word_Length UARTEx Word Length + * @{ + */ +#define UART_WORDLENGTH_7B USART_CR1_M1 /*!< 7-bit long UART frame */ +#define UART_WORDLENGTH_8B 0x00000000U /*!< 8-bit long UART frame */ +#define UART_WORDLENGTH_9B USART_CR1_M0 /*!< 9-bit long UART frame */ +/** + * @} + */ + +/** @defgroup UARTEx_WakeUp_Address_Length UARTEx WakeUp Address Length + * @{ + */ +#define UART_ADDRESS_DETECT_4B 0x00000000U /*!< 4-bit long wake-up address */ +#define UART_ADDRESS_DETECT_7B USART_CR2_ADDM7 /*!< 7-bit long wake-up address */ +/** + * @} + */ + +/** @defgroup UARTEx_FIFO_mode UARTEx FIFO mode + * @brief UART FIFO mode + * @{ + */ +#define UART_FIFOMODE_DISABLE 0x00000000U /*!< FIFO mode disable */ +#define UART_FIFOMODE_ENABLE USART_CR1_FIFOEN /*!< FIFO mode enable */ +/** + * @} + */ + +/** @defgroup UARTEx_TXFIFO_threshold_level UARTEx TXFIFO threshold level + * @brief UART TXFIFO threshold level + * @{ + */ +#define UART_TXFIFO_THRESHOLD_1_8 0x00000000U /*!< TX FIFO reaches 1/8 of its depth */ +#define UART_TXFIFO_THRESHOLD_1_4 USART_CR3_TXFTCFG_0 /*!< TX FIFO reaches 1/4 of its depth */ +#define UART_TXFIFO_THRESHOLD_1_2 USART_CR3_TXFTCFG_1 /*!< TX FIFO reaches 1/2 of its depth */ +#define UART_TXFIFO_THRESHOLD_3_4 (USART_CR3_TXFTCFG_0|USART_CR3_TXFTCFG_1) /*!< TX FIFO reaches 3/4 of its depth */ +#define UART_TXFIFO_THRESHOLD_7_8 USART_CR3_TXFTCFG_2 /*!< TX FIFO reaches 7/8 of its depth */ +#define UART_TXFIFO_THRESHOLD_8_8 (USART_CR3_TXFTCFG_2|USART_CR3_TXFTCFG_0) /*!< TX FIFO becomes empty */ +/** + * @} + */ + +/** @defgroup UARTEx_RXFIFO_threshold_level UARTEx RXFIFO threshold level + * @brief UART RXFIFO threshold level + * @{ + */ +#define UART_RXFIFO_THRESHOLD_1_8 0x00000000U /*!< RX FIFO reaches 1/8 of its depth */ +#define UART_RXFIFO_THRESHOLD_1_4 USART_CR3_RXFTCFG_0 /*!< RX FIFO reaches 1/4 of its depth */ +#define UART_RXFIFO_THRESHOLD_1_2 USART_CR3_RXFTCFG_1 /*!< RX FIFO reaches 1/2 of its depth */ +#define UART_RXFIFO_THRESHOLD_3_4 (USART_CR3_RXFTCFG_0|USART_CR3_RXFTCFG_1) /*!< RX FIFO reaches 3/4 of its depth */ +#define UART_RXFIFO_THRESHOLD_7_8 USART_CR3_RXFTCFG_2 /*!< RX FIFO reaches 7/8 of its depth */ +#define UART_RXFIFO_THRESHOLD_8_8 (USART_CR3_RXFTCFG_2|USART_CR3_RXFTCFG_0) /*!< RX FIFO becomes full */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup UARTEx_Exported_Functions + * @{ + */ + +/** @addtogroup UARTEx_Exported_Functions_Group1 + * @{ + */ + +/* Initialization and de-initialization functions ****************************/ +HAL_StatusTypeDef HAL_RS485Ex_Init(UART_HandleTypeDef *huart, uint32_t Polarity, uint32_t AssertionTime, + uint32_t DeassertionTime); + +/** + * @} + */ + +/** @addtogroup UARTEx_Exported_Functions_Group2 + * @{ + */ + +void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart); + +void HAL_UARTEx_RxFifoFullCallback(UART_HandleTypeDef *huart); +void HAL_UARTEx_TxFifoEmptyCallback(UART_HandleTypeDef *huart); + +/** + * @} + */ + +/** @addtogroup UARTEx_Exported_Functions_Group3 + * @{ + */ + +/* Peripheral Control functions **********************************************/ +HAL_StatusTypeDef HAL_UARTEx_StopModeWakeUpSourceConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection); +HAL_StatusTypeDef HAL_UARTEx_EnableStopMode(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_UARTEx_DisableStopMode(UART_HandleTypeDef *huart); + +HAL_StatusTypeDef HAL_MultiProcessorEx_AddressLength_Set(UART_HandleTypeDef *huart, uint32_t AddressLength); + +HAL_StatusTypeDef HAL_UARTEx_EnableFifoMode(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_UARTEx_DisableFifoMode(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_UARTEx_SetTxFifoThreshold(UART_HandleTypeDef *huart, uint32_t Threshold); +HAL_StatusTypeDef HAL_UARTEx_SetRxFifoThreshold(UART_HandleTypeDef *huart, uint32_t Threshold); + +HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen, + uint32_t Timeout); +HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); +#if defined(HAL_DMA_MODULE_ENABLED) +HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); +#endif /* HAL_DMA_MODULE_ENABLED */ + +HAL_UART_RxEventTypeTypeDef HAL_UARTEx_GetRxEventType(const UART_HandleTypeDef *huart); + + +/** + * @} + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup UARTEx_Private_Macros UARTEx Private Macros + * @{ + */ + +/** @brief Report the UART clock source. + * @param __HANDLE__ specifies the UART Handle. + * @param __CLOCKSOURCE__ output variable. + * @retval UART clocking source, written in __CLOCKSOURCE__. + */ +#if (defined(STM32H573xx) || defined(STM32H563xx) || defined(STM32H562xx)) +#define UART_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__) \ + do { \ + if((__HANDLE__)->Instance == USART1) \ + { \ + (__CLOCKSOURCE__) = (uint32_t)RCC_PERIPHCLK_USART1; \ + } \ + else if((__HANDLE__)->Instance == USART2) \ + { \ + (__CLOCKSOURCE__) = (uint32_t)RCC_PERIPHCLK_USART2; \ + } \ + else if((__HANDLE__)->Instance == USART3) \ + { \ + (__CLOCKSOURCE__) = (uint32_t)RCC_PERIPHCLK_USART3; \ + } \ + else if((__HANDLE__)->Instance == UART4) \ + { \ + (__CLOCKSOURCE__) = (uint32_t)RCC_PERIPHCLK_UART4; \ + } \ + else if((__HANDLE__)->Instance == UART5) \ + { \ + (__CLOCKSOURCE__) = (uint32_t)RCC_PERIPHCLK_UART5; \ + } \ + else if((__HANDLE__)->Instance == USART6) \ + { \ + (__CLOCKSOURCE__) = (uint32_t)RCC_PERIPHCLK_USART6; \ + } \ + else if((__HANDLE__)->Instance == UART7) \ + { \ + (__CLOCKSOURCE__) = (uint32_t)RCC_PERIPHCLK_UART7; \ + } \ + else if((__HANDLE__)->Instance == UART8) \ + { \ + (__CLOCKSOURCE__) = (uint32_t)RCC_PERIPHCLK_UART8; \ + } \ + else if((__HANDLE__)->Instance == UART9) \ + { \ + (__CLOCKSOURCE__) = (uint32_t)RCC_PERIPHCLK_UART9; \ + } \ + else if((__HANDLE__)->Instance == USART10) \ + { \ + (__CLOCKSOURCE__) = (uint32_t)RCC_PERIPHCLK_USART10; \ + } \ + else if((__HANDLE__)->Instance == USART11) \ + { \ + (__CLOCKSOURCE__) = (uint32_t)RCC_PERIPHCLK_USART11; \ + } \ + else if((__HANDLE__)->Instance == UART12) \ + { \ + (__CLOCKSOURCE__) = (uint32_t)RCC_PERIPHCLK_UART12; \ + } \ + else if((__HANDLE__)->Instance == LPUART1) \ + { \ + (__CLOCKSOURCE__) = (uint32_t)RCC_PERIPHCLK_LPUART1; \ + } \ + else \ + { \ + (__CLOCKSOURCE__) = 0U; \ + } \ + } while(0U) +#else +#define UART_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__) \ + do { \ + if((__HANDLE__)->Instance == USART1) \ + { \ + (__CLOCKSOURCE__) = (uint32_t)RCC_PERIPHCLK_USART1; \ + } \ + else if((__HANDLE__)->Instance == USART2) \ + { \ + (__CLOCKSOURCE__) = (uint32_t)RCC_PERIPHCLK_USART2; \ + } \ + else if((__HANDLE__)->Instance == USART3) \ + { \ + (__CLOCKSOURCE__) = (uint32_t)RCC_PERIPHCLK_USART3; \ + } \ + else if((__HANDLE__)->Instance == LPUART1) \ + { \ + (__CLOCKSOURCE__) = (uint32_t)RCC_PERIPHCLK_LPUART1; \ + } \ + else \ + { \ + (__CLOCKSOURCE__) = 0U; \ + } \ + } while(0U) +#endif /* (defined(STM32H573xx) || defined(STM32H563xx) || defined(STM32H562xx) */ + + +/** @brief Report the UART mask to apply to retrieve the received data + * according to the word length and to the parity bits activation. + * @note If PCE = 1, the parity bit is not included in the data extracted + * by the reception API(). + * This masking operation is not carried out in the case of + * DMA transfers. + * @param __HANDLE__ specifies the UART Handle. + * @retval None, the mask to apply to UART RDR register is stored in (__HANDLE__)->Mask field. + */ +#define UART_MASK_COMPUTATION(__HANDLE__) \ + do { \ + if ((__HANDLE__)->Init.WordLength == UART_WORDLENGTH_9B) \ + { \ + if ((__HANDLE__)->Init.Parity == UART_PARITY_NONE) \ + { \ + (__HANDLE__)->Mask = 0x01FFU ; \ + } \ + else \ + { \ + (__HANDLE__)->Mask = 0x00FFU ; \ + } \ + } \ + else if ((__HANDLE__)->Init.WordLength == UART_WORDLENGTH_8B) \ + { \ + if ((__HANDLE__)->Init.Parity == UART_PARITY_NONE) \ + { \ + (__HANDLE__)->Mask = 0x00FFU ; \ + } \ + else \ + { \ + (__HANDLE__)->Mask = 0x007FU ; \ + } \ + } \ + else if ((__HANDLE__)->Init.WordLength == UART_WORDLENGTH_7B) \ + { \ + if ((__HANDLE__)->Init.Parity == UART_PARITY_NONE) \ + { \ + (__HANDLE__)->Mask = 0x007FU ; \ + } \ + else \ + { \ + (__HANDLE__)->Mask = 0x003FU ; \ + } \ + } \ + else \ + { \ + (__HANDLE__)->Mask = 0x0000U; \ + } \ + } while(0U) + +/** + * @brief Ensure that UART frame length is valid. + * @param __LENGTH__ UART frame length. + * @retval SET (__LENGTH__ is valid) or RESET (__LENGTH__ is invalid) + */ +#define IS_UART_WORD_LENGTH(__LENGTH__) (((__LENGTH__) == UART_WORDLENGTH_7B) || \ + ((__LENGTH__) == UART_WORDLENGTH_8B) || \ + ((__LENGTH__) == UART_WORDLENGTH_9B)) + +/** + * @brief Ensure that UART wake-up address length is valid. + * @param __ADDRESS__ UART wake-up address length. + * @retval SET (__ADDRESS__ is valid) or RESET (__ADDRESS__ is invalid) + */ +#define IS_UART_ADDRESSLENGTH_DETECT(__ADDRESS__) (((__ADDRESS__) == UART_ADDRESS_DETECT_4B) || \ + ((__ADDRESS__) == UART_ADDRESS_DETECT_7B)) + +/** + * @brief Ensure that UART TXFIFO threshold level is valid. + * @param __THRESHOLD__ UART TXFIFO threshold level. + * @retval SET (__THRESHOLD__ is valid) or RESET (__THRESHOLD__ is invalid) + */ +#define IS_UART_TXFIFO_THRESHOLD(__THRESHOLD__) (((__THRESHOLD__) == UART_TXFIFO_THRESHOLD_1_8) || \ + ((__THRESHOLD__) == UART_TXFIFO_THRESHOLD_1_4) || \ + ((__THRESHOLD__) == UART_TXFIFO_THRESHOLD_1_2) || \ + ((__THRESHOLD__) == UART_TXFIFO_THRESHOLD_3_4) || \ + ((__THRESHOLD__) == UART_TXFIFO_THRESHOLD_7_8) || \ + ((__THRESHOLD__) == UART_TXFIFO_THRESHOLD_8_8)) + +/** + * @brief Ensure that UART RXFIFO threshold level is valid. + * @param __THRESHOLD__ UART RXFIFO threshold level. + * @retval SET (__THRESHOLD__ is valid) or RESET (__THRESHOLD__ is invalid) + */ +#define IS_UART_RXFIFO_THRESHOLD(__THRESHOLD__) (((__THRESHOLD__) == UART_RXFIFO_THRESHOLD_1_8) || \ + ((__THRESHOLD__) == UART_RXFIFO_THRESHOLD_1_4) || \ + ((__THRESHOLD__) == UART_RXFIFO_THRESHOLD_1_2) || \ + ((__THRESHOLD__) == UART_RXFIFO_THRESHOLD_3_4) || \ + ((__THRESHOLD__) == UART_RXFIFO_THRESHOLD_7_8) || \ + ((__THRESHOLD__) == UART_RXFIFO_THRESHOLD_8_8)) + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_UART_EX_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_usart.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_usart.h new file mode 100644 index 0000000000..a1b5b42f11 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_usart.h @@ -0,0 +1,1175 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_usart.h + * @author MCD Application Team + * @brief Header file of USART HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_USART_H +#define STM32H5xx_HAL_USART_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup USART + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup USART_Exported_Types USART Exported Types + * @{ + */ + +/** + * @brief USART Init Structure definition + */ +typedef struct +{ + uint32_t BaudRate; /*!< This member configures the Usart communication baud rate. + The baud rate is computed using the following formula: + Baud Rate Register[15:4] = ((2 * fclk_pres) / + ((huart->Init.BaudRate)))[15:4] + Baud Rate Register[3] = 0 + Baud Rate Register[2:0] = (((2 * fclk_pres) / + ((huart->Init.BaudRate)))[3:0]) >> 1 + where fclk_pres is the USART input clock frequency (fclk) + divided by a prescaler. + @note Oversampling by 8 is systematically applied to + achieve high baud rates. */ + + uint32_t WordLength; /*!< Specifies the number of data bits transmitted or received in a frame. + This parameter can be a value of @ref USARTEx_Word_Length. */ + + uint32_t StopBits; /*!< Specifies the number of stop bits transmitted. + This parameter can be a value of @ref USART_Stop_Bits. */ + + uint32_t Parity; /*!< Specifies the parity mode. + This parameter can be a value of @ref USART_Parity + @note When parity is enabled, the computed parity is inserted + at the MSB position of the transmitted data (9th bit when + the word length is set to 9 data bits; 8th bit when the + word length is set to 8 data bits). */ + + uint32_t Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled. + This parameter can be a value of @ref USART_Mode. */ + + uint32_t CLKPolarity; /*!< Specifies the steady state of the serial clock. + This parameter can be a value of @ref USART_Clock_Polarity. */ + + uint32_t CLKPhase; /*!< Specifies the clock transition on which the bit capture is made. + This parameter can be a value of @ref USART_Clock_Phase. */ + + uint32_t CLKLastBit; /*!< Specifies whether the clock pulse corresponding to the last transmitted + data bit (MSB) has to be output on the SCLK pin in synchronous mode. + This parameter can be a value of @ref USART_Last_Bit. */ + + uint32_t ClockPrescaler; /*!< Specifies the prescaler value used to divide the USART clock source. + This parameter can be a value of @ref USART_ClockPrescaler. */ +} USART_InitTypeDef; + +/** + * @brief HAL USART State structures definition + */ +typedef enum +{ + HAL_USART_STATE_RESET = 0x00U, /*!< Peripheral is not initialized */ + HAL_USART_STATE_READY = 0x01U, /*!< Peripheral Initialized and ready for use */ + HAL_USART_STATE_BUSY = 0x02U, /*!< an internal process is ongoing */ + HAL_USART_STATE_BUSY_TX = 0x12U, /*!< Data Transmission process is ongoing */ + HAL_USART_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing */ + HAL_USART_STATE_BUSY_TX_RX = 0x32U, /*!< Data Transmission Reception process is ongoing */ + HAL_USART_STATE_TIMEOUT = 0x03U, /*!< Timeout state */ + HAL_USART_STATE_ERROR = 0x04U /*!< Error */ +} HAL_USART_StateTypeDef; + +/** + * @brief USART clock sources definitions + */ +typedef enum +{ + USART_CLOCKSOURCE_PCLK1 = 0x00U, /*!< PCLK1 clock source */ + USART_CLOCKSOURCE_PCLK2 = 0x01U, /*!< PCLK2 clock source */ + USART_CLOCKSOURCE_HSI = 0x02U, /*!< HSI clock source */ + USART_CLOCKSOURCE_CSI = 0x04U, /*!< CSI clock source */ + USART_CLOCKSOURCE_LSE = 0x08U, /*!< LSE clock source */ + USART_CLOCKSOURCE_PLL2Q = 0x10U, /*!< PLL2 clock source */ + USART_CLOCKSOURCE_PLL3Q = 0x20U, /*!< PLL3 clock source */ + USART_CLOCKSOURCE_UNDEFINED = 0x40U /*!< Undefined clock source */ +} USART_ClockSourceTypeDef; + +/** + * @brief USART handle Structure definition + */ +typedef struct __USART_HandleTypeDef +{ + USART_TypeDef *Instance; /*!< USART registers base address */ + + USART_InitTypeDef Init; /*!< USART communication parameters */ + + const uint8_t *pTxBuffPtr; /*!< Pointer to USART Tx transfer Buffer */ + + uint16_t TxXferSize; /*!< USART Tx Transfer size */ + + __IO uint16_t TxXferCount; /*!< USART Tx Transfer Counter */ + + uint8_t *pRxBuffPtr; /*!< Pointer to USART Rx transfer Buffer */ + + uint16_t RxXferSize; /*!< USART Rx Transfer size */ + + __IO uint16_t RxXferCount; /*!< USART Rx Transfer Counter */ + + uint16_t Mask; /*!< USART Rx RDR register mask */ + + uint16_t NbRxDataToProcess; /*!< Number of data to process during RX ISR execution */ + + uint16_t NbTxDataToProcess; /*!< Number of data to process during TX ISR execution */ + + uint32_t SlaveMode; /*!< Enable/Disable USART SPI Slave Mode. This parameter can be a value + of @ref USARTEx_Slave_Mode */ + + uint32_t FifoMode; /*!< Specifies if the FIFO mode will be used. This parameter can be a value + of @ref USARTEx_FIFO_mode. */ + + void (*RxISR)(struct __USART_HandleTypeDef *husart); /*!< Function pointer on Rx IRQ handler */ + + void (*TxISR)(struct __USART_HandleTypeDef *husart); /*!< Function pointer on Tx IRQ handler */ + +#if defined(HAL_DMA_MODULE_ENABLED) + DMA_HandleTypeDef *hdmatx; /*!< USART Tx DMA Handle parameters */ + + DMA_HandleTypeDef *hdmarx; /*!< USART Rx DMA Handle parameters */ + +#endif /* HAL_DMA_MODULE_ENABLED */ + HAL_LockTypeDef Lock; /*!< Locking object */ + + __IO HAL_USART_StateTypeDef State; /*!< USART communication state */ + + __IO uint32_t ErrorCode; /*!< USART Error code */ + +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + void (* TxHalfCpltCallback)(struct __USART_HandleTypeDef *husart); /*!< USART Tx Half Complete Callback */ + void (* TxCpltCallback)(struct __USART_HandleTypeDef *husart); /*!< USART Tx Complete Callback */ + void (* RxHalfCpltCallback)(struct __USART_HandleTypeDef *husart); /*!< USART Rx Half Complete Callback */ + void (* RxCpltCallback)(struct __USART_HandleTypeDef *husart); /*!< USART Rx Complete Callback */ + void (* TxRxCpltCallback)(struct __USART_HandleTypeDef *husart); /*!< USART Tx Rx Complete Callback */ + void (* ErrorCallback)(struct __USART_HandleTypeDef *husart); /*!< USART Error Callback */ + void (* AbortCpltCallback)(struct __USART_HandleTypeDef *husart); /*!< USART Abort Complete Callback */ + void (* RxFifoFullCallback)(struct __USART_HandleTypeDef *husart); /*!< USART Rx Fifo Full Callback */ + void (* TxFifoEmptyCallback)(struct __USART_HandleTypeDef *husart); /*!< USART Tx Fifo Empty Callback */ + + void (* MspInitCallback)(struct __USART_HandleTypeDef *husart); /*!< USART Msp Init callback */ + void (* MspDeInitCallback)(struct __USART_HandleTypeDef *husart); /*!< USART Msp DeInit callback */ +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + +} USART_HandleTypeDef; + +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) +/** + * @brief HAL USART Callback ID enumeration definition + */ +typedef enum +{ + HAL_USART_TX_HALFCOMPLETE_CB_ID = 0x00U, /*!< USART Tx Half Complete Callback ID */ + HAL_USART_TX_COMPLETE_CB_ID = 0x01U, /*!< USART Tx Complete Callback ID */ + HAL_USART_RX_HALFCOMPLETE_CB_ID = 0x02U, /*!< USART Rx Half Complete Callback ID */ + HAL_USART_RX_COMPLETE_CB_ID = 0x03U, /*!< USART Rx Complete Callback ID */ + HAL_USART_TX_RX_COMPLETE_CB_ID = 0x04U, /*!< USART Tx Rx Complete Callback ID */ + HAL_USART_ERROR_CB_ID = 0x05U, /*!< USART Error Callback ID */ + HAL_USART_ABORT_COMPLETE_CB_ID = 0x06U, /*!< USART Abort Complete Callback ID */ + HAL_USART_RX_FIFO_FULL_CB_ID = 0x07U, /*!< USART Rx Fifo Full Callback ID */ + HAL_USART_TX_FIFO_EMPTY_CB_ID = 0x08U, /*!< USART Tx Fifo Empty Callback ID */ + + HAL_USART_MSPINIT_CB_ID = 0x09U, /*!< USART MspInit callback ID */ + HAL_USART_MSPDEINIT_CB_ID = 0x0AU /*!< USART MspDeInit callback ID */ + +} HAL_USART_CallbackIDTypeDef; + +/** + * @brief HAL USART Callback pointer definition + */ +typedef void (*pUSART_CallbackTypeDef)(USART_HandleTypeDef *husart); /*!< pointer to an USART callback function */ + +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup USART_Exported_Constants USART Exported Constants + * @{ + */ + +/** @defgroup USART_Error_Definition USART Error Definition + * @{ + */ +#define HAL_USART_ERROR_NONE (0x00000000U) /*!< No error */ +#define HAL_USART_ERROR_PE (0x00000001U) /*!< Parity error */ +#define HAL_USART_ERROR_NE (0x00000002U) /*!< Noise error */ +#define HAL_USART_ERROR_FE (0x00000004U) /*!< Frame error */ +#define HAL_USART_ERROR_ORE (0x00000008U) /*!< Overrun error */ +#if defined(HAL_DMA_MODULE_ENABLED) +#define HAL_USART_ERROR_DMA (0x00000010U) /*!< DMA transfer error */ +#endif /* HAL_DMA_MODULE_ENABLED */ +#define HAL_USART_ERROR_UDR (0x00000020U) /*!< SPI slave underrun error */ +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) +#define HAL_USART_ERROR_INVALID_CALLBACK (0x00000040U) /*!< Invalid Callback error */ +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ +#define HAL_USART_ERROR_RTO (0x00000080U) /*!< Receiver Timeout error */ +/** + * @} + */ + +/** @defgroup USART_Stop_Bits USART Number of Stop Bits + * @{ + */ +#define USART_STOPBITS_0_5 USART_CR2_STOP_0 /*!< USART frame with 0.5 stop bit */ +#define USART_STOPBITS_1 0x00000000U /*!< USART frame with 1 stop bit */ +#define USART_STOPBITS_1_5 (USART_CR2_STOP_0 | USART_CR2_STOP_1) /*!< USART frame with 1.5 stop bits */ +#define USART_STOPBITS_2 USART_CR2_STOP_1 /*!< USART frame with 2 stop bits */ +/** + * @} + */ + +/** @defgroup USART_Parity USART Parity + * @{ + */ +#define USART_PARITY_NONE 0x00000000U /*!< No parity */ +#define USART_PARITY_EVEN USART_CR1_PCE /*!< Even parity */ +#define USART_PARITY_ODD (USART_CR1_PCE | USART_CR1_PS) /*!< Odd parity */ +/** + * @} + */ + +/** @defgroup USART_Mode USART Mode + * @{ + */ +#define USART_MODE_RX USART_CR1_RE /*!< RX mode */ +#define USART_MODE_TX USART_CR1_TE /*!< TX mode */ +#define USART_MODE_TX_RX (USART_CR1_TE |USART_CR1_RE) /*!< RX and TX mode */ +/** + * @} + */ + +/** @defgroup USART_Clock USART Clock + * @{ + */ +#define USART_CLOCK_DISABLE 0x00000000U /*!< USART clock disable */ +#define USART_CLOCK_ENABLE USART_CR2_CLKEN /*!< USART clock enable */ +/** + * @} + */ + +/** @defgroup USART_Clock_Polarity USART Clock Polarity + * @{ + */ +#define USART_POLARITY_LOW 0x00000000U /*!< Driver enable signal is active high */ +#define USART_POLARITY_HIGH USART_CR2_CPOL /*!< Driver enable signal is active low */ +/** + * @} + */ + +/** @defgroup USART_Clock_Phase USART Clock Phase + * @{ + */ +#define USART_PHASE_1EDGE 0x00000000U /*!< USART frame phase on first clock transition */ +#define USART_PHASE_2EDGE USART_CR2_CPHA /*!< USART frame phase on second clock transition */ +/** + * @} + */ + +/** @defgroup USART_Last_Bit USART Last Bit + * @{ + */ +#define USART_LASTBIT_DISABLE 0x00000000U /*!< USART frame last data bit clock pulse not output to SCLK pin */ +#define USART_LASTBIT_ENABLE USART_CR2_LBCL /*!< USART frame last data bit clock pulse output to SCLK pin */ +/** + * @} + */ + +/** @defgroup USART_ClockPrescaler USART Clock Prescaler + * @{ + */ +#define USART_PRESCALER_DIV1 0x00000000U /*!< fclk_pres = fclk */ +#define USART_PRESCALER_DIV2 0x00000001U /*!< fclk_pres = fclk/2 */ +#define USART_PRESCALER_DIV4 0x00000002U /*!< fclk_pres = fclk/4 */ +#define USART_PRESCALER_DIV6 0x00000003U /*!< fclk_pres = fclk/6 */ +#define USART_PRESCALER_DIV8 0x00000004U /*!< fclk_pres = fclk/8 */ +#define USART_PRESCALER_DIV10 0x00000005U /*!< fclk_pres = fclk/10 */ +#define USART_PRESCALER_DIV12 0x00000006U /*!< fclk_pres = fclk/12 */ +#define USART_PRESCALER_DIV16 0x00000007U /*!< fclk_pres = fclk/16 */ +#define USART_PRESCALER_DIV32 0x00000008U /*!< fclk_pres = fclk/32 */ +#define USART_PRESCALER_DIV64 0x00000009U /*!< fclk_pres = fclk/64 */ +#define USART_PRESCALER_DIV128 0x0000000AU /*!< fclk_pres = fclk/128 */ +#define USART_PRESCALER_DIV256 0x0000000BU /*!< fclk_pres = fclk/256 */ + +/** + * @} + */ + +/** @defgroup USART_Request_Parameters USART Request Parameters + * @{ + */ +#define USART_RXDATA_FLUSH_REQUEST USART_RQR_RXFRQ /*!< Receive Data flush Request */ +#define USART_TXDATA_FLUSH_REQUEST USART_RQR_TXFRQ /*!< Transmit data flush Request */ +/** + * @} + */ + +/** @defgroup USART_Flags USART Flags + * Elements values convention: 0xXXXX + * - 0xXXXX : Flag mask in the ISR register + * @{ + */ +#define USART_FLAG_TXFT USART_ISR_TXFT /*!< USART TXFIFO threshold flag */ +#define USART_FLAG_RXFT USART_ISR_RXFT /*!< USART RXFIFO threshold flag */ +#define USART_FLAG_RXFF USART_ISR_RXFF /*!< USART RXFIFO Full flag */ +#define USART_FLAG_TXFE USART_ISR_TXFE /*!< USART TXFIFO Empty flag */ +#define USART_FLAG_REACK USART_ISR_REACK /*!< USART receive enable acknowledge flag */ +#define USART_FLAG_TEACK USART_ISR_TEACK /*!< USART transmit enable acknowledge flag */ +#define USART_FLAG_BUSY USART_ISR_BUSY /*!< USART busy flag */ +#define USART_FLAG_UDR USART_ISR_UDR /*!< SPI slave underrun error flag */ +#define USART_FLAG_TXE USART_ISR_TXE_TXFNF /*!< USART transmit data register empty */ +#define USART_FLAG_TXFNF USART_ISR_TXE_TXFNF /*!< USART TXFIFO not full */ +#define USART_FLAG_RTOF USART_ISR_RTOF /*!< USART receiver timeout flag */ +#define USART_FLAG_TC USART_ISR_TC /*!< USART transmission complete */ +#define USART_FLAG_RXNE USART_ISR_RXNE_RXFNE /*!< USART read data register not empty */ +#define USART_FLAG_RXFNE USART_ISR_RXNE_RXFNE /*!< USART RXFIFO not empty */ +#define USART_FLAG_IDLE USART_ISR_IDLE /*!< USART idle flag */ +#define USART_FLAG_ORE USART_ISR_ORE /*!< USART overrun error */ +#define USART_FLAG_NE USART_ISR_NE /*!< USART noise error */ +#define USART_FLAG_FE USART_ISR_FE /*!< USART frame error */ +#define USART_FLAG_PE USART_ISR_PE /*!< USART parity error */ +/** + * @} + */ + +/** @defgroup USART_Interrupt_definition USART Interrupts Definition + * Elements values convention: 0000ZZZZ0XXYYYYYb + * - YYYYY : Interrupt source position in the XX register (5bits) + * - XX : Interrupt source register (2bits) + * - 01: CR1 register + * - 10: CR2 register + * - 11: CR3 register + * - ZZZZ : Flag position in the ISR register(4bits) + * @{ + */ + +#define USART_IT_PE 0x0028U /*!< USART parity error interruption */ +#define USART_IT_TXE 0x0727U /*!< USART transmit data register empty interruption */ +#define USART_IT_TXFNF 0x0727U /*!< USART TX FIFO not full interruption */ +#define USART_IT_TC 0x0626U /*!< USART transmission complete interruption */ +#define USART_IT_RXNE 0x0525U /*!< USART read data register not empty interruption */ +#define USART_IT_RXFNE 0x0525U /*!< USART RXFIFO not empty interruption */ +#define USART_IT_IDLE 0x0424U /*!< USART idle interruption */ +#define USART_IT_ERR 0x0060U /*!< USART error interruption */ +#define USART_IT_ORE 0x0300U /*!< USART overrun error interruption */ +#define USART_IT_NE 0x0200U /*!< USART noise error interruption */ +#define USART_IT_FE 0x0100U /*!< USART frame error interruption */ +#define USART_IT_RXFF 0x183FU /*!< USART RXFIFO full interruption */ +#define USART_IT_TXFE 0x173EU /*!< USART TXFIFO empty interruption */ +#define USART_IT_RXFT 0x1A7CU /*!< USART RXFIFO threshold reached interruption */ +#define USART_IT_TXFT 0x1B77U /*!< USART TXFIFO threshold reached interruption */ + +/** + * @} + */ + +/** @defgroup USART_IT_CLEAR_Flags USART Interruption Clear Flags + * @{ + */ +#define USART_CLEAR_PEF USART_ICR_PECF /*!< Parity Error Clear Flag */ +#define USART_CLEAR_FEF USART_ICR_FECF /*!< Framing Error Clear Flag */ +#define USART_CLEAR_NEF USART_ICR_NECF /*!< Noise Error detected Clear Flag */ +#define USART_CLEAR_OREF USART_ICR_ORECF /*!< OverRun Error Clear Flag */ +#define USART_CLEAR_IDLEF USART_ICR_IDLECF /*!< IDLE line detected Clear Flag */ +#define USART_CLEAR_TCF USART_ICR_TCCF /*!< Transmission Complete Clear Flag */ +#define USART_CLEAR_UDRF USART_ICR_UDRCF /*!< SPI slave underrun error Clear Flag */ +#define USART_CLEAR_TXFECF USART_ICR_TXFECF /*!< TXFIFO Empty Clear Flag */ +#define USART_CLEAR_RTOF USART_ICR_RTOCF /*!< USART receiver timeout clear flag */ +/** + * @} + */ + +/** @defgroup USART_Interruption_Mask USART Interruption Flags Mask + * @{ + */ +#define USART_IT_MASK 0x001FU /*!< USART interruptions flags mask */ +#define USART_CR_MASK 0x00E0U /*!< USART control register mask */ +#define USART_CR_POS 5U /*!< USART control register position */ +#define USART_ISR_MASK 0x1F00U /*!< USART ISR register mask */ +#define USART_ISR_POS 8U /*!< USART ISR register position */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup USART_Exported_Macros USART Exported Macros + * @{ + */ + +/** @brief Reset USART handle state. + * @param __HANDLE__ USART handle. + * @retval None + */ +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) +#define __HAL_USART_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->State = HAL_USART_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0U) +#else +#define __HAL_USART_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_USART_STATE_RESET) +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + +/** @brief Check whether the specified USART flag is set or not. + * @param __HANDLE__ specifies the USART Handle + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg @ref USART_FLAG_TXFT TXFIFO threshold flag + * @arg @ref USART_FLAG_RXFT RXFIFO threshold flag + * @arg @ref USART_FLAG_RXFF RXFIFO Full flag + * @arg @ref USART_FLAG_TXFE TXFIFO Empty flag + * @arg @ref USART_FLAG_REACK Receive enable acknowledge flag + * @arg @ref USART_FLAG_TEACK Transmit enable acknowledge flag + * @arg @ref USART_FLAG_BUSY Busy flag + * @arg @ref USART_FLAG_UDR SPI slave underrun error flag + * @arg @ref USART_FLAG_TXE Transmit data register empty flag + * @arg @ref USART_FLAG_TXFNF TXFIFO not full flag + * @arg @ref USART_FLAG_TC Transmission Complete flag + * @arg @ref USART_FLAG_RXNE Receive data register not empty flag + * @arg @ref USART_FLAG_RXFNE RXFIFO not empty flag + * @arg @ref USART_FLAG_RTOF Receiver Timeout flag + * @arg @ref USART_FLAG_IDLE Idle Line detection flag + * @arg @ref USART_FLAG_ORE OverRun Error flag + * @arg @ref USART_FLAG_NE Noise Error flag + * @arg @ref USART_FLAG_FE Framing Error flag + * @arg @ref USART_FLAG_PE Parity Error flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_USART_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->ISR & (__FLAG__)) == (__FLAG__)) + +/** @brief Clear the specified USART pending flag. + * @param __HANDLE__ specifies the USART Handle. + * @param __FLAG__ specifies the flag to check. + * This parameter can be any combination of the following values: + * @arg @ref USART_CLEAR_PEF Parity Error Clear Flag + * @arg @ref USART_CLEAR_FEF Framing Error Clear Flag + * @arg @ref USART_CLEAR_NEF Noise detected Clear Flag + * @arg @ref USART_CLEAR_OREF Overrun Error Clear Flag + * @arg @ref USART_CLEAR_IDLEF IDLE line detected Clear Flag + * @arg @ref USART_CLEAR_TXFECF TXFIFO empty clear Flag + * @arg @ref USART_CLEAR_TCF Transmission Complete Clear Flag + * @arg @ref USART_CLEAR_RTOF Receiver Timeout clear flag + * @arg @ref USART_CLEAR_UDRF SPI slave underrun error Clear Flag + * @retval None + */ +#define __HAL_USART_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ICR = (__FLAG__)) + +/** @brief Clear the USART PE pending flag. + * @param __HANDLE__ specifies the USART Handle. + * @retval None + */ +#define __HAL_USART_CLEAR_PEFLAG(__HANDLE__) __HAL_USART_CLEAR_FLAG((__HANDLE__), USART_CLEAR_PEF) + +/** @brief Clear the USART FE pending flag. + * @param __HANDLE__ specifies the USART Handle. + * @retval None + */ +#define __HAL_USART_CLEAR_FEFLAG(__HANDLE__) __HAL_USART_CLEAR_FLAG((__HANDLE__), USART_CLEAR_FEF) + +/** @brief Clear the USART NE pending flag. + * @param __HANDLE__ specifies the USART Handle. + * @retval None + */ +#define __HAL_USART_CLEAR_NEFLAG(__HANDLE__) __HAL_USART_CLEAR_FLAG((__HANDLE__), USART_CLEAR_NEF) + +/** @brief Clear the USART ORE pending flag. + * @param __HANDLE__ specifies the USART Handle. + * @retval None + */ +#define __HAL_USART_CLEAR_OREFLAG(__HANDLE__) __HAL_USART_CLEAR_FLAG((__HANDLE__), USART_CLEAR_OREF) + +/** @brief Clear the USART IDLE pending flag. + * @param __HANDLE__ specifies the USART Handle. + * @retval None + */ +#define __HAL_USART_CLEAR_IDLEFLAG(__HANDLE__) __HAL_USART_CLEAR_FLAG((__HANDLE__), USART_CLEAR_IDLEF) + +/** @brief Clear the USART TX FIFO empty clear flag. + * @param __HANDLE__ specifies the USART Handle. + * @retval None + */ +#define __HAL_USART_CLEAR_TXFECF(__HANDLE__) __HAL_USART_CLEAR_FLAG((__HANDLE__), USART_CLEAR_TXFECF) + +/** @brief Clear SPI slave underrun error flag. + * @param __HANDLE__ specifies the USART Handle. + * @retval None + */ +#define __HAL_USART_CLEAR_UDRFLAG(__HANDLE__) __HAL_USART_CLEAR_FLAG((__HANDLE__), USART_CLEAR_UDRF) + +/** @brief Enable the specified USART interrupt. + * @param __HANDLE__ specifies the USART Handle. + * @param __INTERRUPT__ specifies the USART interrupt source to enable. + * This parameter can be one of the following values: + * @arg @ref USART_IT_RXFF RXFIFO Full interrupt + * @arg @ref USART_IT_TXFE TXFIFO Empty interrupt + * @arg @ref USART_IT_RXFT RXFIFO threshold interrupt + * @arg @ref USART_IT_TXFT TXFIFO threshold interrupt + * @arg @ref USART_IT_TXE Transmit Data Register empty interrupt + * @arg @ref USART_IT_TXFNF TX FIFO not full interrupt + * @arg @ref USART_IT_TC Transmission complete interrupt + * @arg @ref USART_IT_RXNE Receive Data register not empty interrupt + * @arg @ref USART_IT_RXFNE RXFIFO not empty interrupt + * @arg @ref USART_IT_IDLE Idle line detection interrupt + * @arg @ref USART_IT_PE Parity Error interrupt + * @arg @ref USART_IT_ERR Error interrupt(Frame error, noise error, overrun error) + * @retval None + */ +#define __HAL_USART_ENABLE_IT(__HANDLE__, __INTERRUPT__)\ + (((((__INTERRUPT__) & USART_CR_MASK) >> USART_CR_POS) == 1U)?\ + ((__HANDLE__)->Instance->CR1 |= (1U << ((__INTERRUPT__) & USART_IT_MASK))): \ + ((((__INTERRUPT__) & USART_CR_MASK) >> USART_CR_POS) == 2U)?\ + ((__HANDLE__)->Instance->CR2 |= (1U << ((__INTERRUPT__) & USART_IT_MASK))): \ + ((__HANDLE__)->Instance->CR3 |= (1U << ((__INTERRUPT__) & USART_IT_MASK)))) + +/** @brief Disable the specified USART interrupt. + * @param __HANDLE__ specifies the USART Handle. + * @param __INTERRUPT__ specifies the USART interrupt source to disable. + * This parameter can be one of the following values: + * @arg @ref USART_IT_RXFF RXFIFO Full interrupt + * @arg @ref USART_IT_TXFE TXFIFO Empty interrupt + * @arg @ref USART_IT_RXFT RXFIFO threshold interrupt + * @arg @ref USART_IT_TXFT TXFIFO threshold interrupt + * @arg @ref USART_IT_TXE Transmit Data Register empty interrupt + * @arg @ref USART_IT_TXFNF TX FIFO not full interrupt + * @arg @ref USART_IT_TC Transmission complete interrupt + * @arg @ref USART_IT_RXNE Receive Data register not empty interrupt + * @arg @ref USART_IT_RXFNE RXFIFO not empty interrupt + * @arg @ref USART_IT_IDLE Idle line detection interrupt + * @arg @ref USART_IT_PE Parity Error interrupt + * @arg @ref USART_IT_ERR Error interrupt(Frame error, noise error, overrun error) + * @retval None + */ +#define __HAL_USART_DISABLE_IT(__HANDLE__, __INTERRUPT__)\ + (((((__INTERRUPT__) & USART_CR_MASK) >> USART_CR_POS) == 1U)?\ + ((__HANDLE__)->Instance->CR1 &= ~ (1U << ((__INTERRUPT__) & USART_IT_MASK))): \ + ((((__INTERRUPT__) & USART_CR_MASK) >> USART_CR_POS) == 2U)?\ + ((__HANDLE__)->Instance->CR2 &= ~ (1U << ((__INTERRUPT__) & USART_IT_MASK))): \ + ((__HANDLE__)->Instance->CR3 &= ~ (1U << ((__INTERRUPT__) & USART_IT_MASK)))) + +/** @brief Check whether the specified USART interrupt has occurred or not. + * @param __HANDLE__ specifies the USART Handle. + * @param __INTERRUPT__ specifies the USART interrupt source to check. + * This parameter can be one of the following values: + * @arg @ref USART_IT_RXFF RXFIFO Full interrupt + * @arg @ref USART_IT_TXFE TXFIFO Empty interrupt + * @arg @ref USART_IT_RXFT RXFIFO threshold interrupt + * @arg @ref USART_IT_TXFT TXFIFO threshold interrupt + * @arg @ref USART_IT_TXE Transmit Data Register empty interrupt + * @arg @ref USART_IT_TXFNF TX FIFO not full interrupt + * @arg @ref USART_IT_TC Transmission complete interrupt + * @arg @ref USART_IT_RXNE Receive Data register not empty interrupt + * @arg @ref USART_IT_RXFNE RXFIFO not empty interrupt + * @arg @ref USART_IT_IDLE Idle line detection interrupt + * @arg @ref USART_IT_ORE OverRun Error interrupt + * @arg @ref USART_IT_NE Noise Error interrupt + * @arg @ref USART_IT_FE Framing Error interrupt + * @arg @ref USART_IT_PE Parity Error interrupt + * @retval The new state of __INTERRUPT__ (SET or RESET). + */ +#define __HAL_USART_GET_IT(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->ISR\ + & (0x01U << (((__INTERRUPT__) & USART_ISR_MASK)>>\ + USART_ISR_POS))) != 0U) ? SET : RESET) + +/** @brief Check whether the specified USART interrupt source is enabled or not. + * @param __HANDLE__ specifies the USART Handle. + * @param __INTERRUPT__ specifies the USART interrupt source to check. + * This parameter can be one of the following values: + * @arg @ref USART_IT_RXFF RXFIFO Full interrupt + * @arg @ref USART_IT_TXFE TXFIFO Empty interrupt + * @arg @ref USART_IT_RXFT RXFIFO threshold interrupt + * @arg @ref USART_IT_TXFT TXFIFO threshold interrupt + * @arg @ref USART_IT_TXE Transmit Data Register empty interrupt + * @arg @ref USART_IT_TXFNF TX FIFO not full interrupt + * @arg @ref USART_IT_TC Transmission complete interrupt + * @arg @ref USART_IT_RXNE Receive Data register not empty interrupt + * @arg @ref USART_IT_RXFNE RXFIFO not empty interrupt + * @arg @ref USART_IT_IDLE Idle line detection interrupt + * @arg @ref USART_IT_ORE OverRun Error interrupt + * @arg @ref USART_IT_NE Noise Error interrupt + * @arg @ref USART_IT_FE Framing Error interrupt + * @arg @ref USART_IT_PE Parity Error interrupt + * @retval The new state of __INTERRUPT__ (SET or RESET). + */ +#define __HAL_USART_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((((((uint8_t)(__INTERRUPT__)) >> 0x05U) == 0x01U) ?\ + (__HANDLE__)->Instance->CR1 : \ + (((((uint8_t)(__INTERRUPT__)) >> 0x05U) == 0x02U) ?\ + (__HANDLE__)->Instance->CR2 : \ + (__HANDLE__)->Instance->CR3)) & (0x01U <<\ + (((uint16_t)(__INTERRUPT__)) &\ + USART_IT_MASK))) != 0U) ? SET : RESET) + +/** @brief Clear the specified USART ISR flag, in setting the proper ICR register flag. + * @param __HANDLE__ specifies the USART Handle. + * @param __IT_CLEAR__ specifies the interrupt clear register flag that needs to be set + * to clear the corresponding interrupt. + * This parameter can be one of the following values: + * @arg @ref USART_CLEAR_PEF Parity Error Clear Flag + * @arg @ref USART_CLEAR_FEF Framing Error Clear Flag + * @arg @ref USART_CLEAR_NEF Noise detected Clear Flag + * @arg @ref USART_CLEAR_OREF Overrun Error Clear Flag + * @arg @ref USART_CLEAR_IDLEF IDLE line detected Clear Flag + * @arg @ref USART_CLEAR_RTOF Receiver timeout clear flag + * @arg @ref USART_CLEAR_TXFECF TXFIFO empty clear Flag + * @arg @ref USART_CLEAR_TCF Transmission Complete Clear Flag + * @retval None + */ +#define __HAL_USART_CLEAR_IT(__HANDLE__, __IT_CLEAR__) ((__HANDLE__)->Instance->ICR = (uint32_t)(__IT_CLEAR__)) + +/** @brief Set a specific USART request flag. + * @param __HANDLE__ specifies the USART Handle. + * @param __REQ__ specifies the request flag to set. + * This parameter can be one of the following values: + * @arg @ref USART_RXDATA_FLUSH_REQUEST Receive Data flush Request + * @arg @ref USART_TXDATA_FLUSH_REQUEST Transmit data flush Request + * + * @retval None + */ +#define __HAL_USART_SEND_REQ(__HANDLE__, __REQ__) ((__HANDLE__)->Instance->RQR |= (uint16_t)(__REQ__)) + +/** @brief Enable the USART one bit sample method. + * @param __HANDLE__ specifies the USART Handle. + * @retval None + */ +#define __HAL_USART_ONE_BIT_SAMPLE_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3|= USART_CR3_ONEBIT) + +/** @brief Disable the USART one bit sample method. + * @param __HANDLE__ specifies the USART Handle. + * @retval None + */ +#define __HAL_USART_ONE_BIT_SAMPLE_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3 &= ~USART_CR3_ONEBIT) + +/** @brief Enable USART. + * @param __HANDLE__ specifies the USART Handle. + * @retval None + */ +#define __HAL_USART_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= USART_CR1_UE) + +/** @brief Disable USART. + * @param __HANDLE__ specifies the USART Handle. + * @retval None + */ +#define __HAL_USART_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~USART_CR1_UE) + +/** + * @} + */ + +/* Private macros --------------------------------------------------------*/ +/** @defgroup USART_Private_Macros USART Private Macros + * @{ + */ + +/** @brief Get USART clock division factor from clock prescaler value. + * @param __CLOCKPRESCALER__ USART prescaler value. + * @retval USART clock division factor + */ +#define USART_GET_DIV_FACTOR(__CLOCKPRESCALER__) \ + (((__CLOCKPRESCALER__) == USART_PRESCALER_DIV1) ? 1U : \ + ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV2) ? 2U : \ + ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV4) ? 4U : \ + ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV6) ? 6U : \ + ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV8) ? 8U : \ + ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV10) ? 10U : \ + ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV12) ? 12U : \ + ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV16) ? 16U : \ + ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV32) ? 32U : \ + ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV64) ? 64U : \ + ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV128) ? 128U : \ + ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV256) ? 256U : 1U) + +/** @brief BRR division operation to set BRR register in 8-bit oversampling mode. + * @param __PCLK__ USART clock. + * @param __BAUD__ Baud rate set by the user. + * @param __CLOCKPRESCALER__ USART prescaler value. + * @retval Division result + */ +#define USART_DIV_SAMPLING8(__PCLK__, __BAUD__, __CLOCKPRESCALER__)\ + (((((__PCLK__)/USART_GET_DIV_FACTOR(__CLOCKPRESCALER__))*2U)\ + + ((__BAUD__)/2U)) / (__BAUD__)) + +/** @brief Report the USART clock source. + * @param __HANDLE__ specifies the USART Handle. + * @param __CLOCKSOURCE__ output variable. + * @retval the USART clocking source, written in __CLOCKSOURCE__. + */ +#if (defined(STM32H573xx) || defined(STM32H563xx) || defined(STM32H562xx)) +#define USART_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__) \ + do { \ + if((__HANDLE__)->Instance == USART1) \ + { \ + switch(__HAL_RCC_GET_USART1_SOURCE()) \ + { \ + case RCC_USART1CLKSOURCE_PCLK2: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PCLK2; \ + break; \ + case RCC_USART1CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART1CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART1CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_LSE; \ + break; \ + case RCC_USART1CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PLL2Q; \ + break; \ + case RCC_USART1CLKSOURCE_PLL3Q: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PLL3Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == USART2) \ + { \ + switch(__HAL_RCC_GET_USART2_SOURCE()) \ + { \ + case RCC_USART2CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_USART2CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART2CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART2CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_LSE; \ + break; \ + case RCC_USART2CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PLL2Q; \ + break; \ + case RCC_USART2CLKSOURCE_PLL3Q: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PLL3Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == USART3) \ + { \ + switch(__HAL_RCC_GET_USART3_SOURCE()) \ + { \ + case RCC_USART3CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_USART3CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART3CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART3CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_LSE; \ + break; \ + case RCC_USART3CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PLL2Q; \ + break; \ + case RCC_USART3CLKSOURCE_PLL3Q: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PLL3Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == USART6) \ + { \ + switch(__HAL_RCC_GET_USART6_SOURCE()) \ + { \ + case RCC_USART6CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_USART6CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART6CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART6CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_LSE; \ + break; \ + case RCC_USART6CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PLL2Q; \ + break; \ + case RCC_USART6CLKSOURCE_PLL3Q: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PLL3Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == USART10) \ + { \ + switch(__HAL_RCC_GET_USART10_SOURCE()) \ + { \ + case RCC_USART10CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_USART10CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART10CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART10CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_LSE; \ + break; \ + case RCC_USART10CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PLL2Q; \ + break; \ + case RCC_USART10CLKSOURCE_PLL3Q: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PLL3Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == USART11) \ + { \ + switch(__HAL_RCC_GET_USART11_SOURCE()) \ + { \ + case RCC_USART11CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_USART11CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART11CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART11CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_LSE; \ + break; \ + case RCC_USART11CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PLL2Q; \ + break; \ + case RCC_USART11CLKSOURCE_PLL3Q: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PLL3Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else \ + { \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_UNDEFINED; \ + } \ + } while(0U) +#else +#define USART_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__) \ + do { \ + if((__HANDLE__)->Instance == USART1) \ + { \ + switch(__HAL_RCC_GET_USART1_SOURCE()) \ + { \ + case RCC_USART1CLKSOURCE_PCLK2: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PCLK2; \ + break; \ + case RCC_USART1CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART1CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART1CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_LSE; \ + break; \ + case RCC_USART1CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PLL2Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == USART2) \ + { \ + switch(__HAL_RCC_GET_USART2_SOURCE()) \ + { \ + case RCC_USART2CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_USART2CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART2CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART2CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_LSE; \ + break; \ + case RCC_USART2CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PLL2Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else if((__HANDLE__)->Instance == USART3) \ + { \ + switch(__HAL_RCC_GET_USART3_SOURCE()) \ + { \ + case RCC_USART3CLKSOURCE_PCLK1: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PCLK1; \ + break; \ + case RCC_USART3CLKSOURCE_CSI: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_CSI; \ + break; \ + case RCC_USART3CLKSOURCE_HSI: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_HSI; \ + break; \ + case RCC_USART3CLKSOURCE_LSE: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_LSE; \ + break; \ + case RCC_USART3CLKSOURCE_PLL2Q: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_PLL2Q; \ + break; \ + default: \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_UNDEFINED; \ + break; \ + } \ + } \ + else \ + { \ + (__CLOCKSOURCE__) = USART_CLOCKSOURCE_UNDEFINED; \ + } \ + } while(0U) + +#endif /* (defined(STM32H573xx) || defined(STM32H563xx) || defined(STM32H562xx) */ + +/** @brief Check USART Baud rate. + * @param __BAUDRATE__ Baudrate specified by the user. + * The maximum Baud Rate is derived from the maximum clock on H5 (i.e. 250 MHz) + * divided by the smallest oversampling used on the USART (i.e. 8) + * @retval SET (__BAUDRATE__ is valid) or RESET (__BAUDRATE__ is invalid) */ +#define IS_USART_BAUDRATE(__BAUDRATE__) ((__BAUDRATE__) <= 20000000U) + +/** + * @brief Ensure that USART frame number of stop bits is valid. + * @param __STOPBITS__ USART frame number of stop bits. + * @retval SET (__STOPBITS__ is valid) or RESET (__STOPBITS__ is invalid) + */ +#define IS_USART_STOPBITS(__STOPBITS__) (((__STOPBITS__) == USART_STOPBITS_0_5) || \ + ((__STOPBITS__) == USART_STOPBITS_1) || \ + ((__STOPBITS__) == USART_STOPBITS_1_5) || \ + ((__STOPBITS__) == USART_STOPBITS_2)) + +/** + * @brief Ensure that USART frame parity is valid. + * @param __PARITY__ USART frame parity. + * @retval SET (__PARITY__ is valid) or RESET (__PARITY__ is invalid) + */ +#define IS_USART_PARITY(__PARITY__) (((__PARITY__) == USART_PARITY_NONE) || \ + ((__PARITY__) == USART_PARITY_EVEN) || \ + ((__PARITY__) == USART_PARITY_ODD)) + +/** + * @brief Ensure that USART communication mode is valid. + * @param __MODE__ USART communication mode. + * @retval SET (__MODE__ is valid) or RESET (__MODE__ is invalid) + */ +#define IS_USART_MODE(__MODE__) ((((__MODE__) & 0xFFFFFFF3U) == 0x00U) && ((__MODE__) != 0x00U)) + +/** + * @brief Ensure that USART clock state is valid. + * @param __CLOCK__ USART clock state. + * @retval SET (__CLOCK__ is valid) or RESET (__CLOCK__ is invalid) + */ +#define IS_USART_CLOCK(__CLOCK__) (((__CLOCK__) == USART_CLOCK_DISABLE) || \ + ((__CLOCK__) == USART_CLOCK_ENABLE)) + +/** + * @brief Ensure that USART frame polarity is valid. + * @param __CPOL__ USART frame polarity. + * @retval SET (__CPOL__ is valid) or RESET (__CPOL__ is invalid) + */ +#define IS_USART_POLARITY(__CPOL__) (((__CPOL__) == USART_POLARITY_LOW) || ((__CPOL__) == USART_POLARITY_HIGH)) + +/** + * @brief Ensure that USART frame phase is valid. + * @param __CPHA__ USART frame phase. + * @retval SET (__CPHA__ is valid) or RESET (__CPHA__ is invalid) + */ +#define IS_USART_PHASE(__CPHA__) (((__CPHA__) == USART_PHASE_1EDGE) || ((__CPHA__) == USART_PHASE_2EDGE)) + +/** + * @brief Ensure that USART frame last bit clock pulse setting is valid. + * @param __LASTBIT__ USART frame last bit clock pulse setting. + * @retval SET (__LASTBIT__ is valid) or RESET (__LASTBIT__ is invalid) + */ +#define IS_USART_LASTBIT(__LASTBIT__) (((__LASTBIT__) == USART_LASTBIT_DISABLE) || \ + ((__LASTBIT__) == USART_LASTBIT_ENABLE)) + +/** + * @brief Ensure that USART request parameter is valid. + * @param __PARAM__ USART request parameter. + * @retval SET (__PARAM__ is valid) or RESET (__PARAM__ is invalid) + */ +#define IS_USART_REQUEST_PARAMETER(__PARAM__) (((__PARAM__) == USART_RXDATA_FLUSH_REQUEST) || \ + ((__PARAM__) == USART_TXDATA_FLUSH_REQUEST)) + +/** + * @brief Ensure that USART Prescaler is valid. + * @param __CLOCKPRESCALER__ USART Prescaler value. + * @retval SET (__CLOCKPRESCALER__ is valid) or RESET (__CLOCKPRESCALER__ is invalid) + */ +#define IS_USART_PRESCALER(__CLOCKPRESCALER__) (((__CLOCKPRESCALER__) == USART_PRESCALER_DIV1) || \ + ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV2) || \ + ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV4) || \ + ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV6) || \ + ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV8) || \ + ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV10) || \ + ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV12) || \ + ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV16) || \ + ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV32) || \ + ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV64) || \ + ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV128) || \ + ((__CLOCKPRESCALER__) == USART_PRESCALER_DIV256)) + +/** + * @} + */ + +/* Include USART HAL Extended module */ +#include "stm32h5xx_hal_usart_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup USART_Exported_Functions USART Exported Functions + * @{ + */ + +/** @addtogroup USART_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ + +/* Initialization and de-initialization functions ****************************/ +HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart); +HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart); +void HAL_USART_MspInit(USART_HandleTypeDef *husart); +void HAL_USART_MspDeInit(USART_HandleTypeDef *husart); + +/* Callbacks Register/UnRegister functions ***********************************/ +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) +HAL_StatusTypeDef HAL_USART_RegisterCallback(USART_HandleTypeDef *husart, HAL_USART_CallbackIDTypeDef CallbackID, + pUSART_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_USART_UnRegisterCallback(USART_HandleTypeDef *husart, HAL_USART_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @addtogroup USART_Exported_Functions_Group2 IO operation functions + * @{ + */ + +/* IO operation functions *****************************************************/ +HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint16_t Size, + uint32_t Timeout); +HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint8_t *pRxData, + uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint16_t Size); +HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size); +HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint8_t *pRxData, + uint16_t Size); +#if defined(HAL_DMA_MODULE_ENABLED) +HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint16_t Size); +HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size); +HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint8_t *pRxData, + uint16_t Size); +HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart); +HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart); +HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart); +#endif /* HAL_DMA_MODULE_ENABLED */ +/* Transfer Abort functions */ +HAL_StatusTypeDef HAL_USART_Abort(USART_HandleTypeDef *husart); +HAL_StatusTypeDef HAL_USART_Abort_IT(USART_HandleTypeDef *husart); + +void HAL_USART_IRQHandler(USART_HandleTypeDef *husart); +void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart); +void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart); +void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart); +void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart); +void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart); +void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart); +void HAL_USART_AbortCpltCallback(USART_HandleTypeDef *husart); + +/** + * @} + */ + +/** @addtogroup USART_Exported_Functions_Group4 Peripheral State and Error functions + * @{ + */ + +/* Peripheral State and Error functions ***************************************/ +HAL_USART_StateTypeDef HAL_USART_GetState(const USART_HandleTypeDef *husart); +uint32_t HAL_USART_GetError(const USART_HandleTypeDef *husart); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_USART_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_usart_ex.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_usart_ex.h new file mode 100644 index 0000000000..6055a3bd75 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_usart_ex.h @@ -0,0 +1,282 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_usart_ex.h + * @author MCD Application Team + * @brief Header file of USART HAL Extended module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_USART_EX_H +#define STM32H5xx_HAL_USART_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup USARTEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup USARTEx_Exported_Constants USARTEx Exported Constants + * @{ + */ + +/** @defgroup USARTEx_Word_Length USARTEx Word Length + * @{ + */ +#define USART_WORDLENGTH_7B (USART_CR1_M1) /*!< 7-bit long USART frame */ +#define USART_WORDLENGTH_8B (0x00000000U) /*!< 8-bit long USART frame */ +#define USART_WORDLENGTH_9B (USART_CR1_M0) /*!< 9-bit long USART frame */ +/** + * @} + */ + +/** @defgroup USARTEx_Slave_Select_management USARTEx Slave Select Management + * @{ + */ +#define USART_NSS_HARD 0x00000000U /*!< SPI slave selection depends on NSS input pin */ +#define USART_NSS_SOFT USART_CR2_DIS_NSS /*!< SPI slave is always selected and NSS input pin is ignored */ +/** + * @} + */ + + +/** @defgroup USARTEx_Slave_Mode USARTEx Synchronous Slave mode enable + * @brief USART SLAVE mode + * @{ + */ +#define USART_SLAVEMODE_DISABLE 0x00000000U /*!< USART SPI Slave Mode Enable */ +#define USART_SLAVEMODE_ENABLE USART_CR2_SLVEN /*!< USART SPI Slave Mode Disable */ +/** + * @} + */ + +/** @defgroup USARTEx_FIFO_mode USARTEx FIFO mode + * @brief USART FIFO mode + * @{ + */ +#define USART_FIFOMODE_DISABLE 0x00000000U /*!< FIFO mode disable */ +#define USART_FIFOMODE_ENABLE USART_CR1_FIFOEN /*!< FIFO mode enable */ +/** + * @} + */ + +/** @defgroup USARTEx_TXFIFO_threshold_level USARTEx TXFIFO threshold level + * @brief USART TXFIFO level + * @{ + */ +#define USART_TXFIFO_THRESHOLD_1_8 0x00000000U /*!< TXFIFO reaches 1/8 of its depth */ +#define USART_TXFIFO_THRESHOLD_1_4 USART_CR3_TXFTCFG_0 /*!< TXFIFO reaches 1/4 of its depth */ +#define USART_TXFIFO_THRESHOLD_1_2 USART_CR3_TXFTCFG_1 /*!< TXFIFO reaches 1/2 of its depth */ +#define USART_TXFIFO_THRESHOLD_3_4 (USART_CR3_TXFTCFG_0|USART_CR3_TXFTCFG_1) /*!< TXFIFO reaches 3/4 of its depth */ +#define USART_TXFIFO_THRESHOLD_7_8 USART_CR3_TXFTCFG_2 /*!< TXFIFO reaches 7/8 of its depth */ +#define USART_TXFIFO_THRESHOLD_8_8 (USART_CR3_TXFTCFG_2|USART_CR3_TXFTCFG_0) /*!< TXFIFO becomes empty */ +/** + * @} + */ + +/** @defgroup USARTEx_RXFIFO_threshold_level USARTEx RXFIFO threshold level + * @brief USART RXFIFO level + * @{ + */ +#define USART_RXFIFO_THRESHOLD_1_8 0x00000000U /*!< RXFIFO FIFO reaches 1/8 of its depth */ +#define USART_RXFIFO_THRESHOLD_1_4 USART_CR3_RXFTCFG_0 /*!< RXFIFO FIFO reaches 1/4 of its depth */ +#define USART_RXFIFO_THRESHOLD_1_2 USART_CR3_RXFTCFG_1 /*!< RXFIFO FIFO reaches 1/2 of its depth */ +#define USART_RXFIFO_THRESHOLD_3_4 (USART_CR3_RXFTCFG_0|USART_CR3_RXFTCFG_1) /*!< RXFIFO FIFO reaches 3/4 of its depth */ +#define USART_RXFIFO_THRESHOLD_7_8 USART_CR3_RXFTCFG_2 /*!< RXFIFO FIFO reaches 7/8 of its depth */ +#define USART_RXFIFO_THRESHOLD_8_8 (USART_CR3_RXFTCFG_2|USART_CR3_RXFTCFG_0) /*!< RXFIFO FIFO becomes full */ +/** + * @} + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup USARTEx_Private_Macros USARTEx Private Macros + * @{ + */ + +/** @brief Compute the USART mask to apply to retrieve the received data + * according to the word length and to the parity bits activation. + * @note If PCE = 1, the parity bit is not included in the data extracted + * by the reception API(). + * This masking operation is not carried out in the case of + * DMA transfers. + * @param __HANDLE__ specifies the USART Handle. + * @retval None, the mask to apply to USART RDR register is stored in (__HANDLE__)->Mask field. + */ +#define USART_MASK_COMPUTATION(__HANDLE__) \ + do { \ + if ((__HANDLE__)->Init.WordLength == USART_WORDLENGTH_9B) \ + { \ + if ((__HANDLE__)->Init.Parity == USART_PARITY_NONE) \ + { \ + (__HANDLE__)->Mask = 0x01FFU; \ + } \ + else \ + { \ + (__HANDLE__)->Mask = 0x00FFU; \ + } \ + } \ + else if ((__HANDLE__)->Init.WordLength == USART_WORDLENGTH_8B) \ + { \ + if ((__HANDLE__)->Init.Parity == USART_PARITY_NONE) \ + { \ + (__HANDLE__)->Mask = 0x00FFU; \ + } \ + else \ + { \ + (__HANDLE__)->Mask = 0x007FU; \ + } \ + } \ + else if ((__HANDLE__)->Init.WordLength == USART_WORDLENGTH_7B) \ + { \ + if ((__HANDLE__)->Init.Parity == USART_PARITY_NONE) \ + { \ + (__HANDLE__)->Mask = 0x007FU; \ + } \ + else \ + { \ + (__HANDLE__)->Mask = 0x003FU; \ + } \ + } \ + else \ + { \ + (__HANDLE__)->Mask = 0x0000U; \ + } \ + } while(0U) + +/** + * @brief Ensure that USART frame length is valid. + * @param __LENGTH__ USART frame length. + * @retval SET (__LENGTH__ is valid) or RESET (__LENGTH__ is invalid) + */ +#define IS_USART_WORD_LENGTH(__LENGTH__) (((__LENGTH__) == USART_WORDLENGTH_7B) || \ + ((__LENGTH__) == USART_WORDLENGTH_8B) || \ + ((__LENGTH__) == USART_WORDLENGTH_9B)) + +/** + * @brief Ensure that USART Negative Slave Select (NSS) pin management is valid. + * @param __NSS__ USART Negative Slave Select pin management. + * @retval SET (__NSS__ is valid) or RESET (__NSS__ is invalid) + */ +#define IS_USART_NSS(__NSS__) (((__NSS__) == USART_NSS_HARD) || \ + ((__NSS__) == USART_NSS_SOFT)) + +/** + * @brief Ensure that USART Slave Mode is valid. + * @param __STATE__ USART Slave Mode. + * @retval SET (__STATE__ is valid) or RESET (__STATE__ is invalid) + */ +#define IS_USART_SLAVEMODE(__STATE__) (((__STATE__) == USART_SLAVEMODE_DISABLE ) || \ + ((__STATE__) == USART_SLAVEMODE_ENABLE)) + +/** + * @brief Ensure that USART FIFO mode is valid. + * @param __STATE__ USART FIFO mode. + * @retval SET (__STATE__ is valid) or RESET (__STATE__ is invalid) + */ +#define IS_USART_FIFO_MODE_STATE(__STATE__) (((__STATE__) == USART_FIFOMODE_DISABLE ) || \ + ((__STATE__) == USART_FIFOMODE_ENABLE)) + +/** + * @brief Ensure that USART TXFIFO threshold level is valid. + * @param __THRESHOLD__ USART TXFIFO threshold level. + * @retval SET (__THRESHOLD__ is valid) or RESET (__THRESHOLD__ is invalid) + */ +#define IS_USART_TXFIFO_THRESHOLD(__THRESHOLD__) (((__THRESHOLD__) == USART_TXFIFO_THRESHOLD_1_8) || \ + ((__THRESHOLD__) == USART_TXFIFO_THRESHOLD_1_4) || \ + ((__THRESHOLD__) == USART_TXFIFO_THRESHOLD_1_2) || \ + ((__THRESHOLD__) == USART_TXFIFO_THRESHOLD_3_4) || \ + ((__THRESHOLD__) == USART_TXFIFO_THRESHOLD_7_8) || \ + ((__THRESHOLD__) == USART_TXFIFO_THRESHOLD_8_8)) + +/** + * @brief Ensure that USART RXFIFO threshold level is valid. + * @param __THRESHOLD__ USART RXFIFO threshold level. + * @retval SET (__THRESHOLD__ is valid) or RESET (__THRESHOLD__ is invalid) + */ +#define IS_USART_RXFIFO_THRESHOLD(__THRESHOLD__) (((__THRESHOLD__) == USART_RXFIFO_THRESHOLD_1_8) || \ + ((__THRESHOLD__) == USART_RXFIFO_THRESHOLD_1_4) || \ + ((__THRESHOLD__) == USART_RXFIFO_THRESHOLD_1_2) || \ + ((__THRESHOLD__) == USART_RXFIFO_THRESHOLD_3_4) || \ + ((__THRESHOLD__) == USART_RXFIFO_THRESHOLD_7_8) || \ + ((__THRESHOLD__) == USART_RXFIFO_THRESHOLD_8_8)) +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup USARTEx_Exported_Functions + * @{ + */ + +/** @addtogroup USARTEx_Exported_Functions_Group1 + * @{ + */ + +/* IO operation functions *****************************************************/ +void HAL_USARTEx_RxFifoFullCallback(USART_HandleTypeDef *husart); +void HAL_USARTEx_TxFifoEmptyCallback(USART_HandleTypeDef *husart); + +/** + * @} + */ + +/** @addtogroup USARTEx_Exported_Functions_Group2 + * @{ + */ + +/* Peripheral Control functions ***********************************************/ +HAL_StatusTypeDef HAL_USARTEx_EnableSlaveMode(USART_HandleTypeDef *husart); +HAL_StatusTypeDef HAL_USARTEx_DisableSlaveMode(USART_HandleTypeDef *husart); +HAL_StatusTypeDef HAL_USARTEx_ConfigNSS(USART_HandleTypeDef *husart, uint32_t NSSConfig); +HAL_StatusTypeDef HAL_USARTEx_EnableFifoMode(USART_HandleTypeDef *husart); +HAL_StatusTypeDef HAL_USARTEx_DisableFifoMode(USART_HandleTypeDef *husart); +HAL_StatusTypeDef HAL_USARTEx_SetTxFifoThreshold(USART_HandleTypeDef *husart, uint32_t Threshold); +HAL_StatusTypeDef HAL_USARTEx_SetRxFifoThreshold(USART_HandleTypeDef *husart, uint32_t Threshold); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_USART_EX_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_wwdg.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_wwdg.h new file mode 100644 index 0000000000..3ed2304e32 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_wwdg.h @@ -0,0 +1,306 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_wwdg.h + * @author MCD Application Team + * @brief Header file of WWDG HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_WWDG_H +#define STM32H5xx_HAL_WWDG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup WWDG + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup WWDG_Exported_Types WWDG Exported Types + * @{ + */ + +/** + * @brief WWDG Init structure definition + */ +typedef struct +{ + uint32_t Prescaler; /*!< Specifies the prescaler value of the WWDG. + This parameter can be a value of @ref WWDG_Prescaler */ + + uint32_t Window; /*!< Specifies the WWDG window value to be compared to the downcounter. + This parameter must be a number Min_Data = 0x40 and Max_Data = 0x7F */ + + uint32_t Counter; /*!< Specifies the WWDG free-running downcounter value. + This parameter must be a number between Min_Data = 0x40 and Max_Data = 0x7F */ + + uint32_t EWIMode ; /*!< Specifies if WWDG Early Wakeup Interrupt is enable or not. + This parameter can be a value of @ref WWDG_EWI_Mode */ + +} WWDG_InitTypeDef; + +/** + * @brief WWDG handle Structure definition + */ +#if (USE_HAL_WWDG_REGISTER_CALLBACKS == 1) +typedef struct __WWDG_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_WWDG_REGISTER_CALLBACKS */ +{ + WWDG_TypeDef *Instance; /*!< Register base address */ + + WWDG_InitTypeDef Init; /*!< WWDG required parameters */ + +#if (USE_HAL_WWDG_REGISTER_CALLBACKS == 1) + void (* EwiCallback)(struct __WWDG_HandleTypeDef *hwwdg); /*!< WWDG Early WakeUp Interrupt callback */ + + void (* MspInitCallback)(struct __WWDG_HandleTypeDef *hwwdg); /*!< WWDG Msp Init callback */ +#endif /* USE_HAL_WWDG_REGISTER_CALLBACKS */ +} WWDG_HandleTypeDef; + +#if (USE_HAL_WWDG_REGISTER_CALLBACKS == 1) +/** + * @brief HAL WWDG common Callback ID enumeration definition + */ +typedef enum +{ + HAL_WWDG_EWI_CB_ID = 0x00U, /*!< WWDG EWI callback ID */ + HAL_WWDG_MSPINIT_CB_ID = 0x01U, /*!< WWDG MspInit callback ID */ +} HAL_WWDG_CallbackIDTypeDef; + +/** + * @brief HAL WWDG Callback pointer definition + */ +typedef void (*pWWDG_CallbackTypeDef)(WWDG_HandleTypeDef *hppp); /*!< pointer to a WWDG common callback functions */ + +#endif /* USE_HAL_WWDG_REGISTER_CALLBACKS */ +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup WWDG_Exported_Constants WWDG Exported Constants + * @{ + */ + +/** @defgroup WWDG_Interrupt_definition WWDG Interrupt definition + * @{ + */ +#define WWDG_IT_EWI WWDG_CFR_EWI /*!< Early wakeup interrupt */ +/** + * @} + */ + +/** @defgroup WWDG_Flag_definition WWDG Flag definition + * @brief WWDG Flag definition + * @{ + */ +#define WWDG_FLAG_EWIF WWDG_SR_EWIF /*!< Early wakeup interrupt flag */ +/** + * @} + */ + +/** @defgroup WWDG_Prescaler WWDG Prescaler + * @{ + */ +#define WWDG_PRESCALER_1 0x00000000u /*!< WWDG counter clock = (PCLK1/4096)/1 */ +#define WWDG_PRESCALER_2 WWDG_CFR_WDGTB_0 /*!< WWDG counter clock = (PCLK1/4096)/2 */ +#define WWDG_PRESCALER_4 WWDG_CFR_WDGTB_1 /*!< WWDG counter clock = (PCLK1/4096)/4 */ +#define WWDG_PRESCALER_8 (WWDG_CFR_WDGTB_1 | WWDG_CFR_WDGTB_0) /*!< WWDG counter clock = (PCLK1/4096)/8 */ +#define WWDG_PRESCALER_16 WWDG_CFR_WDGTB_2 /*!< WWDG counter clock = (PCLK1/4096)/16 */ +#define WWDG_PRESCALER_32 (WWDG_CFR_WDGTB_2 | WWDG_CFR_WDGTB_0) /*!< WWDG counter clock = (PCLK1/4096)/32 */ +#define WWDG_PRESCALER_64 (WWDG_CFR_WDGTB_2 | WWDG_CFR_WDGTB_1) /*!< WWDG counter clock = (PCLK1/4096)/64 */ +#define WWDG_PRESCALER_128 WWDG_CFR_WDGTB /*!< WWDG counter clock = (PCLK1/4096)/128 */ +/** + * @} + */ + +/** @defgroup WWDG_EWI_Mode WWDG Early Wakeup Interrupt Mode + * @{ + */ +#define WWDG_EWI_DISABLE 0x00000000u /*!< EWI Disable */ +#define WWDG_EWI_ENABLE WWDG_CFR_EWI /*!< EWI Enable */ +/** + * @} + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ + +/** @defgroup WWDG_Private_Macros WWDG Private Macros + * @{ + */ +#define IS_WWDG_PRESCALER(__PRESCALER__) (((__PRESCALER__) == WWDG_PRESCALER_1) || \ + ((__PRESCALER__) == WWDG_PRESCALER_2) || \ + ((__PRESCALER__) == WWDG_PRESCALER_4) || \ + ((__PRESCALER__) == WWDG_PRESCALER_8) || \ + ((__PRESCALER__) == WWDG_PRESCALER_16) || \ + ((__PRESCALER__) == WWDG_PRESCALER_32) || \ + ((__PRESCALER__) == WWDG_PRESCALER_64) || \ + ((__PRESCALER__) == WWDG_PRESCALER_128)) + +#define IS_WWDG_WINDOW(__WINDOW__) (((__WINDOW__) >= WWDG_CFR_W_6) && ((__WINDOW__) <= WWDG_CFR_W)) + +#define IS_WWDG_COUNTER(__COUNTER__) (((__COUNTER__) >= WWDG_CR_T_6) && ((__COUNTER__) <= WWDG_CR_T)) + +#define IS_WWDG_EWI_MODE(__MODE__) (((__MODE__) == WWDG_EWI_ENABLE) || \ + ((__MODE__) == WWDG_EWI_DISABLE)) +/** + * @} + */ + + +/* Exported macros ------------------------------------------------------------*/ + +/** @defgroup WWDG_Exported_Macros WWDG Exported Macros + * @{ + */ + +/** + * @brief Enable the WWDG peripheral. + * @param __HANDLE__ WWDG handle + * @retval None + */ +#define __HAL_WWDG_ENABLE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CR, WWDG_CR_WDGA) + +/** + * @brief Enable the WWDG early wakeup interrupt. + * @param __HANDLE__ WWDG handle + * @param __INTERRUPT__ specifies the interrupt to enable. + * This parameter can be one of the following values: + * @arg WWDG_IT_EWI: Early wakeup interrupt + * @note Once enabled this interrupt cannot be disabled except by a system reset. + * @retval None + */ +#define __HAL_WWDG_ENABLE_IT(__HANDLE__, __INTERRUPT__) SET_BIT((__HANDLE__)->Instance->CFR, (__INTERRUPT__)) + +/** + * @brief Check whether the selected WWDG interrupt has occurred or not. + * @param __HANDLE__ WWDG handle + * @param __INTERRUPT__ specifies the it to check. + * This parameter can be one of the following values: + * @arg WWDG_FLAG_EWIF: Early wakeup interrupt IT + * @retval The new state of WWDG_FLAG (SET or RESET). + */ +#define __HAL_WWDG_GET_IT(__HANDLE__, __INTERRUPT__) __HAL_WWDG_GET_FLAG((__HANDLE__),(__INTERRUPT__)) + +/** @brief Clear the WWDG interrupt pending bits. + * bits to clear the selected interrupt pending bits. + * @param __HANDLE__ WWDG handle + * @param __INTERRUPT__ specifies the interrupt pending bit to clear. + * This parameter can be one of the following values: + * @arg WWDG_FLAG_EWIF: Early wakeup interrupt flag + */ +#define __HAL_WWDG_CLEAR_IT(__HANDLE__, __INTERRUPT__) __HAL_WWDG_CLEAR_FLAG((__HANDLE__), (__INTERRUPT__)) + +/** + * @brief Check whether the specified WWDG flag is set or not. + * @param __HANDLE__ WWDG handle + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg WWDG_FLAG_EWIF: Early wakeup interrupt flag + * @retval The new state of WWDG_FLAG (SET or RESET). + */ +#define __HAL_WWDG_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__)) + +/** + * @brief Clear the WWDG's pending flags. + * @param __HANDLE__ WWDG handle + * @param __FLAG__ specifies the flag to clear. + * This parameter can be one of the following values: + * @arg WWDG_FLAG_EWIF: Early wakeup interrupt flag + * @retval None + */ +#define __HAL_WWDG_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR = ~(__FLAG__)) + +/** @brief Check whether the specified WWDG interrupt source is enabled or not. + * @param __HANDLE__ WWDG Handle. + * @param __INTERRUPT__ specifies the WWDG interrupt source to check. + * This parameter can be one of the following values: + * @arg WWDG_IT_EWI: Early Wakeup Interrupt + * @retval state of __INTERRUPT__ (TRUE or FALSE). + */ +#define __HAL_WWDG_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->CFR\ + & (__INTERRUPT__)) == (__INTERRUPT__)) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup WWDG_Exported_Functions + * @{ + */ + +/** @addtogroup WWDG_Exported_Functions_Group1 + * @{ + */ +/* Initialization/de-initialization functions **********************************/ +HAL_StatusTypeDef HAL_WWDG_Init(WWDG_HandleTypeDef *hwwdg); +void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg); +/* Callbacks Register/UnRegister functions ***********************************/ +#if (USE_HAL_WWDG_REGISTER_CALLBACKS == 1) +HAL_StatusTypeDef HAL_WWDG_RegisterCallback(WWDG_HandleTypeDef *hwwdg, HAL_WWDG_CallbackIDTypeDef CallbackID, + pWWDG_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_WWDG_UnRegisterCallback(WWDG_HandleTypeDef *hwwdg, HAL_WWDG_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_WWDG_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @addtogroup WWDG_Exported_Functions_Group2 + * @{ + */ +/* I/O operation functions ******************************************************/ +HAL_StatusTypeDef HAL_WWDG_Refresh(WWDG_HandleTypeDef *hwwdg); +void HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg); +void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_WWDG_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_xspi.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_xspi.h new file mode 100644 index 0000000000..e4f1f3fc9e --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_hal_xspi.h @@ -0,0 +1,1172 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_xspi.h + * @author MCD Application Team + * @brief Header file of XSPI HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_XSPI_H +#define STM32H5xx_HAL_XSPI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" +#include "stm32h5xx_ll_dlyb.h" + +#if defined(HSPI) || defined(HSPI1) || defined(HSPI2)|| defined(OCTOSPI) || defined(OCTOSPI1)|| defined(OCTOSPI2) + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup XSPI + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup XSPI_Exported_Types XSPI Exported Types + * @{ + */ +#define HAL_XSPI_DLYB_CfgTypeDef LL_DLYB_CfgTypeDef + +/** + * @brief XSPI Init structure definition + */ +typedef struct +{ + uint32_t FifoThresholdByte; /*!< This is the threshold used by the Peripheral to generate the interrupt + indicating that data are available in reception or free place + is available in transmission. + For OCTOSPI, this parameter can be a value between 1 and 32 */ + uint32_t MemoryMode; /*!< It Specifies the memory mode. + This parameter can be a value of @ref XSPI_MemoryMode */ + uint32_t MemoryType; /*!< It indicates the external device type connected to the XSPI. + This parameter can be a value of @ref XSPI_MemoryType */ + uint32_t MemorySize; /*!< It defines the size of the external device connected to the XSPI, + it corresponds to the number of address bits required to access + the external device. + This parameter can be a value of @ref XSPI_MemorySize*/ + uint32_t ChipSelectHighTimeCycle; /*!< It defines the minimum number of clocks which the chip select + must remain high between commands. + This parameter can be a value between 1 and 64U */ + uint32_t FreeRunningClock; /*!< It enables or not the free running clock. + This parameter can be a value of @ref XSPI_FreeRunningClock */ + uint32_t ClockMode; /*!< It indicates the level of clock when the chip select is released. + This parameter can be a value of @ref XSPI_ClockMode */ + uint32_t WrapSize; /*!< It indicates the wrap-size corresponding the external device configuration. + This parameter can be a value of @ref XSPI_WrapSize */ + uint32_t ClockPrescaler; /*!< It specifies the prescaler factor used for generating + the external clock based on the AHB clock. + This parameter can be a value between 0 and 255U */ + uint32_t SampleShifting; /*!< It allows to delay to 1/2 cycle the data sampling in order + to take in account external signal delays. + This parameter can be a value of @ref XSPI_SampleShifting */ + uint32_t DelayHoldQuarterCycle; /*!< It allows to hold to 1/4 cycle the data. + This parameter can be a value of @ref XSPI_DelayHoldQuarterCycle */ + uint32_t ChipSelectBoundary; /*!< It enables the transaction boundary feature and + defines the boundary of bytes to release the chip select. + This parameter can be a value of @ref XSPI_ChipSelectBoundary */ + uint32_t DelayBlockBypass; /*!< It enables the delay block bypass, so the sampling is not affected + by the delay block. + This parameter can be a value of @ref XSPI_DelayBlockBypass */ + uint32_t Refresh; /*!< It enables the refresh rate feature. The chip select is released every + Refresh+1 clock cycles. + This parameter can be a value between 0 and 0xFFFFFFFF */ +} XSPI_InitTypeDef; + +/** + * @brief HAL XSPI Handle Structure definition + */ +#if defined(USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) +typedef struct __XSPI_HandleTypeDef +#else +typedef struct +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */ +{ + XSPI_TypeDef *Instance; /*!< XSPI registers base address */ + XSPI_InitTypeDef Init; /*!< XSPI initialization parameters */ + uint8_t *pBuffPtr; /*!< Address of the XSPI buffer for transfer */ + __IO uint32_t XferSize; /*!< Number of data to transfer */ + __IO uint32_t XferCount; /*!< Counter of data transferred */ + DMA_HandleTypeDef *hdmatx; /*!< Handle of the DMA channel used for transmit */ + DMA_HandleTypeDef *hdmarx; /*!< Handle of the DMA channel used for receive */ + __IO uint32_t State; /*!< Internal state of the XSPI HAL driver */ + __IO uint32_t ErrorCode; /*!< Error code in case of HAL driver internal error */ + uint32_t Timeout; /*!< Timeout used for the XSPI external device access */ +#if defined(USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) + void (* ErrorCallback)(struct __XSPI_HandleTypeDef *hxspi); + void (* AbortCpltCallback)(struct __XSPI_HandleTypeDef *hxspi); + void (* FifoThresholdCallback)(struct __XSPI_HandleTypeDef *hxspi); + void (* CmdCpltCallback)(struct __XSPI_HandleTypeDef *hxspi); + void (* RxCpltCallback)(struct __XSPI_HandleTypeDef *hxspi); + void (* TxCpltCallback)(struct __XSPI_HandleTypeDef *hxspi); + void (* RxHalfCpltCallback)(struct __XSPI_HandleTypeDef *hxspi); + void (* TxHalfCpltCallback)(struct __XSPI_HandleTypeDef *hxspi); + void (* StatusMatchCallback)(struct __XSPI_HandleTypeDef *hxspi); + void (* TimeOutCallback)(struct __XSPI_HandleTypeDef *hxspi); + + void (* MspInitCallback)(struct __XSPI_HandleTypeDef *hxspi); + void (* MspDeInitCallback)(struct __XSPI_HandleTypeDef *hxspi); +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */ +} XSPI_HandleTypeDef; + +/** + * @brief HAL XSPI Regular Command Structure definition + */ +typedef struct +{ + uint32_t OperationType; /*!< It indicates if the configuration applies to the common registers or + to the registers for the write operation (these registers are only + used for memory-mapped mode). + This parameter can be a value of @ref XSPI_OperationType */ + uint32_t IOSelect; /*!< It indicates the IOs used to exchange data with external memory. + This parameter can be a value of @ref XSPI_IOSelect */ + uint32_t Instruction; /*!< It contains the instruction to be sent to the device. + This parameter can be a value between 0 and 0xFFFFFFFFU */ + uint32_t InstructionMode; /*!< It indicates the mode of the instruction. + This parameter can be a value of @ref XSPI_InstructionMode */ + uint32_t InstructionWidth; /*!< It indicates the width of the instruction. + This parameter can be a value of @ref XSPI_InstructionWidth */ + uint32_t InstructionDTRMode; /*!< It enables or not the DTR mode for the instruction phase. + This parameter can be a value of @ref XSPI_InstructionDTRMode */ + uint32_t Address; /*!< It contains the address to be sent to the device. + This parameter can be a value between 0 and 0xFFFFFFFF */ + uint32_t AddressMode; /*!< It indicates the address mode. Address mode precises number of lines + for address (except no address). + This parameter can be a value of @ref XSPI_AddressMode */ + uint32_t AddressWidth; /*!< It indicates the width of the address. + This parameter can be a value of @ref XSPI_AddressWidth */ + uint32_t AddressDTRMode; /*!< It enables or not the DTR mode for the address phase. + This parameter can be a value of @ref XSPI_AddressDTRMode */ + uint32_t AlternateBytes; /*!< It contains the alternate bytes to be sent to the device. + This parameter can be a value between 0 and 0xFFFFFFFF */ + uint32_t AlternateBytesMode; /*!< It indicates the mode of the alternate bytes. + This parameter can be a value of @ref XSPI_AlternateBytesMode */ + uint32_t AlternateBytesWidth; /*!< It indicates the width of the alternate bytes. + This parameter can be a value of @ref XSPI_AlternateBytesWidth */ + uint32_t AlternateBytesDTRMode; /*!< It enables or not the DTR mode for the alternate bytes phase. + This parameter can be a value of @ref XSPI_AlternateBytesDTRMode */ + uint32_t DataMode; /*!< It indicates the data mode. Data mode precises number of lines + for data exchange (except no data). + This parameter can be a value of @ref XSPI_DataMode */ + uint32_t DataLength; /*!< It indicates the number of data transferred with this command. + This field is only used for indirect mode. + This parameter can be a value between 1 and 0xFFFFFFFFU */ + uint32_t DataDTRMode; /*!< It enables or not the DTR mode for the data phase. + This parameter can be a value of @ref XSPI_DataDTRMode */ + uint32_t DummyCycles; /*!< It indicates the number of dummy cycles inserted before data phase. + This parameter can be a value between 0 and 31U */ + uint32_t DQSMode; /*!< It enables or not the data strobe management. + This parameter can be a value of @ref XSPI_DQSMode */ + uint32_t SIOOMode; /*!< It enables or not the SIOO mode. When SIOO mode enabled, + instruction will be sent only once. + This parameter can be a value of @ref XSPI_SIOOMode */ +} XSPI_RegularCmdTypeDef; +/** + * @brief HAL XSPI Hyperbus Configuration Structure definition + */ +typedef struct +{ + uint32_t RWRecoveryTimeCycle; /*!< It indicates the number of cycles for the device read write recovery time. + This parameter can be a value between 0 and 255U */ + uint32_t AccessTimeCycle; /*!< It indicates the number of cycles for the device access time. + This parameter can be a value between 0 and 255U */ + uint32_t WriteZeroLatency; /*!< It enables or not the latency for the write access. + This parameter can be a value of @ref XSPI_WriteZeroLatency */ + uint32_t LatencyMode; /*!< It configures the latency mode. + This parameter can be a value of @ref XSPI_LatencyMode */ +} XSPI_HyperbusCfgTypeDef; + +/** + * @brief HAL XSPI Hyperbus Command Structure definition + */ +typedef struct +{ + uint32_t AddressSpace; /*!< It indicates the address space accessed by the command. + This parameter can be a value of @ref XSPI_AddressSpace */ + uint32_t Address; /*!< It contains the address to be sent to the device. + This parameter can be a value between 0 and 0xFFFFFFFF */ + uint32_t AddressWidth; /*!< It indicates the width of the address. + This parameter can be a value of @ref XSPI_AddressWidth */ + uint32_t DataLength; /*!< It indicates the number of data transferred with this command. + This field is only used for indirect mode. + This parameter can be a value between 1 and 0xFFFFFFFF + In case of autopolling mode, this parameter can be + any value between 1 and 4 */ + uint32_t DQSMode; /*!< It enables or not the data strobe management. + This parameter can be a value of @ref XSPI_DQSMode */ +} XSPI_HyperbusCmdTypeDef; + +/** + * @brief HAL XSPI Auto Polling mode configuration structure definition + */ +typedef struct +{ + uint32_t MatchValue; /*!< Specifies the value to be compared with the masked status register to get + a match. + This parameter can be any value between 0 and 0xFFFFFFFFU */ + uint32_t MatchMask; /*!< Specifies the mask to be applied to the status bytes received. + This parameter can be any value between 0 and 0xFFFFFFFFU */ + uint32_t MatchMode; /*!< Specifies the method used for determining a match. + This parameter can be a value of @ref XSPI_MatchMode */ + uint32_t AutomaticStop; /*!< Specifies if automatic polling is stopped after a match. + This parameter can be a value of @ref XSPI_AutomaticStop */ + uint32_t IntervalTime; /*!< Specifies the number of clock cycles between two read during automatic + polling phases. + This parameter can be any value between 0 and 0xFFFFU */ +} XSPI_AutoPollingTypeDef; + +/** + * @brief HAL XSPI Memory Mapped mode configuration structure definition + */ +typedef struct +{ + uint32_t TimeOutActivation; /*!< Specifies if the timeout counter is enabled to release the chip select. + This parameter can be a value of @ref XSPI_TimeOutActivation */ + uint32_t TimeoutPeriodClock; /*!< Specifies the number of clock to wait when the FIFO is full before to + release the chip select. + This parameter can be any value between 0 and 0xFFFFU */ +} XSPI_MemoryMappedTypeDef; + +#if defined(USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) +/** + * @brief HAL XSPI Callback ID enumeration definition + */ +typedef enum +{ + HAL_XSPI_ERROR_CB_ID = 0x00U, /*!< XSPI Error Callback ID */ + HAL_XSPI_ABORT_CB_ID = 0x01U, /*!< XSPI Abort Callback ID */ + HAL_XSPI_FIFO_THRESHOLD_CB_ID = 0x02U, /*!< XSPI FIFO Threshold Callback ID */ + HAL_XSPI_CMD_CPLT_CB_ID = 0x03U, /*!< XSPI Command Complete Callback ID */ + HAL_XSPI_RX_CPLT_CB_ID = 0x04U, /*!< XSPI Rx Complete Callback ID */ + HAL_XSPI_TX_CPLT_CB_ID = 0x05U, /*!< XSPI Tx Complete Callback ID */ + HAL_XSPI_RX_HALF_CPLT_CB_ID = 0x06U, /*!< XSPI Rx Half Complete Callback ID */ + HAL_XSPI_TX_HALF_CPLT_CB_ID = 0x07U, /*!< XSPI Tx Half Complete Callback ID */ + HAL_XSPI_STATUS_MATCH_CB_ID = 0x08U, /*!< XSPI Status Match Callback ID */ + HAL_XSPI_TIMEOUT_CB_ID = 0x09U, /*!< XSPI Timeout Callback ID */ + HAL_XSPI_MSP_INIT_CB_ID = 0x0AU, /*!< XSPI MspInit Callback ID */ + HAL_XSPI_MSP_DEINIT_CB_ID = 0x0BU /*!< XSPI MspDeInit Callback ID */ +} HAL_XSPI_CallbackIDTypeDef; + +/** + * @brief HAL XSPI Callback pointer definition + */ +typedef void (*pXSPI_CallbackTypeDef)(XSPI_HandleTypeDef *hxspi); + +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */ +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup XSPI_Exported_Constants XSPI Exported Constants + * @{ + */ + +/** @defgroup XSPI_State XSPI State + * @{ + */ +#define HAL_XSPI_STATE_RESET (0x00000000U) /*!< Initial state */ +#define HAL_XSPI_STATE_READY (0x00000002U) /*!< Driver ready to be used */ +#define HAL_XSPI_STATE_HYPERBUS_INIT (0x00000001U) /*!< Initialization done in hyperbus mode but timing configuration not done */ +#define HAL_XSPI_STATE_CMD_CFG (0x00000004U) /*!< Command (regular or hyperbus) configured, ready for an action */ +#define HAL_XSPI_STATE_READ_CMD_CFG (0x00000014U) /*!< Read command configuration done, not the write command configuration */ +#define HAL_XSPI_STATE_WRITE_CMD_CFG (0x00000024U) /*!< Write command configuration done, not the read command configuration */ +#define HAL_XSPI_STATE_BUSY_CMD (0x00000008U) /*!< Command without data on-going */ +#define HAL_XSPI_STATE_BUSY_TX (0x00000018U) /*!< Indirect Tx on-going */ +#define HAL_XSPI_STATE_BUSY_RX (0x00000028U) /*!< Indirect Rx on-going */ +#define HAL_XSPI_STATE_BUSY_AUTO_POLLING (0x00000048U) /*!< Auto-polling on-going */ +#define HAL_XSPI_STATE_BUSY_MEM_MAPPED (0x00000088U) /*!< Memory-mapped on-going */ +#define HAL_XSPI_STATE_ABORT (0x00000100U) /*!< Abort on-going */ +#define HAL_XSPI_STATE_ERROR (0x00000200U) /*!< Blocking error, driver should be re-initialized */ +/** + * @} + */ + +/** @defgroup XSPI_ErrorCode XSPI Error Code + * @{ + */ +#define HAL_XSPI_ERROR_NONE (0x00000000U) /*!< No error */ +#define HAL_XSPI_ERROR_TIMEOUT (0x00000001U) /*!< Timeout error */ +#define HAL_XSPI_ERROR_TRANSFER (0x00000002U) /*!< Transfer error */ +#define HAL_XSPI_ERROR_DMA (0x00000004U) /*!< DMA transfer error */ +#define HAL_XSPI_ERROR_INVALID_PARAM (0x00000008U) /*!< Invalid parameters error */ +#define HAL_XSPI_ERROR_INVALID_SEQUENCE (0x00000010U) /*!< Sequence is incorrect */ +#if defined(USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) +#define HAL_XSPI_ERROR_INVALID_CALLBACK (0x00000020U) /*!< Invalid callback error */ +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */ +/** + * @} + */ + +/** @defgroup XSPI_MemoryMode XSPI Memory Mode + * @{ + */ +#define HAL_XSPI_SINGLE_MEM (0x00000000U) /*!< Dual-memory mode disabled */ +#define HAL_XSPI_DUAL_MEM (XSPI_CR_DMM) /*!< Dual mode enabled */ + +/** + * @} + */ + +/** @defgroup XSPI_MemoryType XSPI Memory Type + * @{ + */ +#define HAL_XSPI_MEMTYPE_MICRON (0x00000000U) /*!< Micron mode */ +#define HAL_XSPI_MEMTYPE_MACRONIX (XSPI_DCR1_MTYP_0) /*!< Macronix mode */ +#define HAL_XSPI_MEMTYPE_APMEM (XSPI_DCR1_MTYP_1) /*!< AP Memory mode */ +#define HAL_XSPI_MEMTYPE_MACRONIX_RAM ((XSPI_DCR1_MTYP_1 | XSPI_DCR1_MTYP_0)) /*!< Macronix RAM mode*/ +#define HAL_XSPI_MEMTYPE_HYPERBUS (XSPI_DCR1_MTYP_2) /*!< Hyperbus mode */ +#define HAL_XSPI_MEMTYPE_APMEM_16BITS ((XSPI_DCR1_MTYP_2 | XSPI_DCR1_MTYP_1)) /*!< AP Memory mode */ + +/** + * @} + */ + +/** @defgroup XSPI_MemorySize XSPI Memory Size + * @{ + */ +#define HAL_XSPI_SIZE_16B (0x00000000U) /*!< 16 bits ( 2 Byte = 2^( 0+1)) */ +#define HAL_XSPI_SIZE_32B (0x00000001U) /*!< 32 bits ( 4 Byte = 2^( 1+1)) */ +#define HAL_XSPI_SIZE_64B (0x00000002U) /*!< 64 bits ( 8 Byte = 2^( 2+1)) */ +#define HAL_XSPI_SIZE_128B (0x00000003U) /*!< 128 bits ( 16 Byte = 2^( 3+1)) */ +#define HAL_XSPI_SIZE_256B (0x00000004U) /*!< 256 bits ( 32 Byte = 2^( 4+1)) */ +#define HAL_XSPI_SIZE_512B (0x00000005U) /*!< 512 bits ( 64 Byte = 2^( 5+1)) */ +#define HAL_XSPI_SIZE_1KB (0x00000006U) /*!< 1 Kbits (128 Byte = 2^( 6+1)) */ +#define HAL_XSPI_SIZE_2KB (0x00000007U) /*!< 2 Kbits (256 Byte = 2^( 7+1)) */ +#define HAL_XSPI_SIZE_4KB (0x00000008U) /*!< 4 Kbits (512 Byte = 2^( 8+1)) */ +#define HAL_XSPI_SIZE_8KB (0x00000009U) /*!< 8 Kbits ( 1 KByte = 2^( 9+1)) */ +#define HAL_XSPI_SIZE_16KB (0x0000000AU) /*!< 16 Kbits ( 2 KByte = 2^(10+1)) */ +#define HAL_XSPI_SIZE_32KB (0x0000000BU) /*!< 32 Kbits ( 4 KByte = 2^(11+1)) */ +#define HAL_XSPI_SIZE_64KB (0x0000000CU) /*!< 64 Kbits ( 8 KByte = 2^(12+1)) */ +#define HAL_XSPI_SIZE_128KB (0x0000000DU) /*!< 128 Kbits ( 16 KByte = 2^(13+1)) */ +#define HAL_XSPI_SIZE_256KB (0x0000000EU) /*!< 256 Kbits ( 32 KByte = 2^(14+1)) */ +#define HAL_XSPI_SIZE_512KB (0x0000000FU) /*!< 512 Kbits ( 64 KByte = 2^(15+1)) */ +#define HAL_XSPI_SIZE_1MB (0x00000010U) /*!< 1 Mbits (128 KByte = 2^(16+1)) */ +#define HAL_XSPI_SIZE_2MB (0x00000011U) /*!< 2 Mbits (256 KByte = 2^(17+1)) */ +#define HAL_XSPI_SIZE_4MB (0x00000012U) /*!< 4 Mbits (512 KByte = 2^(18+1)) */ +#define HAL_XSPI_SIZE_8MB (0x00000013U) /*!< 8 Mbits ( 1 MByte = 2^(19+1)) */ +#define HAL_XSPI_SIZE_16MB (0x00000014U) /*!< 16 Mbits ( 2 MByte = 2^(20+1)) */ +#define HAL_XSPI_SIZE_32MB (0x00000015U) /*!< 32 Mbits ( 4 MByte = 2^(21+1)) */ +#define HAL_XSPI_SIZE_64MB (0x00000016U) /*!< 64 Mbits ( 8 MByte = 2^(22+1)) */ +#define HAL_XSPI_SIZE_128MB (0x00000017U) /*!< 128 Mbits ( 16 MByte = 2^(23+1)) */ +#define HAL_XSPI_SIZE_256MB (0x00000018U) /*!< 256 Mbits ( 32 MByte = 2^(24+1)) */ +#define HAL_XSPI_SIZE_512MB (0x00000019U) /*!< 512 Mbits ( 64 MByte = 2^(25+1)) */ +#define HAL_XSPI_SIZE_1GB (0x0000001AU) /*!< 1 Gbits (128 MByte = 2^(26+1)) */ +#define HAL_XSPI_SIZE_2GB (0x0000001BU) /*!< 2 Gbits (256 MByte = 2^(27+1)) */ +#define HAL_XSPI_SIZE_4GB (0x0000001CU) /*!< 4 Gbits (256 MByte = 2^(28+1)) */ +#define HAL_XSPI_SIZE_8GB (0x0000001DU) /*!< 8 Gbits (256 MByte = 2^(29+1)) */ +#define HAL_XSPI_SIZE_16GB (0x0000001EU) /*!< 16 Gbits (256 MByte = 2^(30+1)) */ +#define HAL_XSPI_SIZE_32GB (0x0000001FU) /*!< 32 Gbits (256 MByte = 2^(31+1)) */ +/** + * @} + */ + +/** @defgroup XSPI_FreeRunningClock XSPI Free Running Clock + * @{ + */ +#define HAL_XSPI_FREERUNCLK_DISABLE (0x00000000U) /*!< CLK is not free running */ +#define HAL_XSPI_FREERUNCLK_ENABLE ((uint32_t)XSPI_DCR1_FRCK) /*!< CLK is always provided (running) */ +/** + * @} + */ + +/** @defgroup XSPI_ClockMode XSPI Clock Mode + * @{ + */ +#define HAL_XSPI_CLOCK_MODE_0 (0x00000000U) /*!< CLK must stay low while nCS is high */ +#define HAL_XSPI_CLOCK_MODE_3 ((uint32_t)XSPI_DCR1_CKMODE) /*!< CLK must stay high while nCS is high */ +/** + * @} + */ + +/** @defgroup XSPI_WrapSize XSPI Wrap-Size + * @{ + */ +#define HAL_XSPI_WRAP_NOT_SUPPORTED (0x00000000U) /*!< wrapped reads are not supported by the memory */ +#define HAL_XSPI_WRAP_16_BYTES ((uint32_t)XSPI_DCR2_WRAPSIZE_1) /*!< external memory supports wrap size of 16 bytes */ +#define HAL_XSPI_WRAP_32_BYTES ((uint32_t)(XSPI_DCR2_WRAPSIZE_0 | XSPI_DCR2_WRAPSIZE_1)) /*!< external memory supports wrap size of 32 bytes */ +#define HAL_XSPI_WRAP_64_BYTES ((uint32_t)XSPI_DCR2_WRAPSIZE_2) /*!< external memory supports wrap size of 64 bytes */ +#define HAL_XSPI_WRAP_128_BYTES ((uint32_t)(XSPI_DCR2_WRAPSIZE_0 | XSPI_DCR2_WRAPSIZE_2)) /*!< external memory supports wrap size of 128 bytes */ +/** + * @} + */ + +/** @defgroup XSPI_SampleShifting XSPI Sample Shifting + * @{ + */ +#define HAL_XSPI_SAMPLE_SHIFT_NONE (0x00000000U) /*!< No shift */ +#define HAL_XSPI_SAMPLE_SHIFT_HALFCYCLE ((uint32_t)XSPI_TCR_SSHIFT) /*!< 1/2 cycle shift */ +/** + * @} + */ + +/** @defgroup XSPI_DelayHoldQuarterCycle XSPI Delay Hold Quarter Cycle + * @{ + */ +#define HAL_XSPI_DHQC_DISABLE (0x00000000U) /*!< No Delay */ +#define HAL_XSPI_DHQC_ENABLE ((uint32_t)XSPI_TCR_DHQC) /*!< Delay Hold 1/4 cycle */ +/** + * @} + */ + +/** @defgroup XSPI_ChipSelectBoundary XSPI Chip Select Boundary + * @{ + */ +#define HAL_XSPI_BONDARYOF_NONE (0x00000000U) /*! CS boundary disabled */ +#define HAL_XSPI_BONDARYOF_16B (0x00000001U) /*!< 16 bits ( 2 Byte = 2^(1)) */ +#define HAL_XSPI_BONDARYOF_32B (0x00000002U) /*!< 32 bits ( 4 Byte = 2^(2)) */ +#define HAL_XSPI_BONDARYOF_64B (0x00000003U) /*!< 64 bits ( 8 Byte = 2^(3)) */ +#define HAL_XSPI_BONDARYOF_128B (0x00000004U) /*!< 128 bits ( 16 Byte = 2^(4)) */ +#define HAL_XSPI_BONDARYOF_256B (0x00000005U) /*!< 256 bits ( 32 Byte = 2^(5)) */ +#define HAL_XSPI_BONDARYOF_512B (0x00000006U) /*!< 512 bits ( 64 Byte = 2^(6)) */ +#define HAL_XSPI_BONDARYOF_1KB (0x00000007U) /*!< 1 Kbits (128 Byte = 2^(7)) */ +#define HAL_XSPI_BONDARYOF_2KB (0x00000008U) /*!< 2 Kbits (256 Byte = 2^(8)) */ +#define HAL_XSPI_BONDARYOF_4KB (0x00000009U) /*!< 4 Kbits (512 Byte = 2^(9)) */ +#define HAL_XSPI_BONDARYOF_8KB (0x0000000AU) /*!< 8 Kbits ( 1 KByte = 2^(10)) */ +#define HAL_XSPI_BONDARYOF_16KB (0x0000000BU) /*!< 16 Kbits ( 2 KByte = 2^(11)) */ +#define HAL_XSPI_BONDARYOF_32KB (0x0000000CU) /*!< 32 Kbits ( 4 KByte = 2^(12)) */ +#define HAL_XSPI_BONDARYOF_64KB (0x0000000DU) /*!< 64 Kbits ( 8 KByte = 2^(13)) */ +#define HAL_XSPI_BONDARYOF_128KB (0x0000000EU) /*!< 128 Kbits ( 16 KByte = 2^(14)) */ +#define HAL_XSPI_BONDARYOF_256KB (0x0000000FU) /*!< 256 Kbits ( 32 KByte = 2^(15)) */ +#define HAL_XSPI_BONDARYOF_512KB (0x00000010U) /*!< 512 Kbits ( 64 KByte = 2^(16)) */ +#define HAL_XSPI_BONDARYOF_1MB (0x00000011U) /*!< 1 Mbits (128 KByte = 2^(17)) */ +#define HAL_XSPI_BONDARYOF_2MB (0x00000012U) /*!< 2 Mbits (256 KByte = 2^(18)) */ +#define HAL_XSPI_BONDARYOF_4MB (0x00000013U) /*!< 4 Mbits (512 KByte = 2^(19)) */ +#define HAL_XSPI_BONDARYOF_8MB (0x00000014U) /*!< 8 Mbits ( 1 MByte = 2^(20)) */ +#define HAL_XSPI_BONDARYOF_16MB (0x00000015U) /*!< 16 Mbits ( 2 MByte = 2^(21)) */ +#define HAL_XSPI_BONDARYOF_32MB (0x00000016U) /*!< 32 Mbits ( 4 MByte = 2^(22)) */ +#define HAL_XSPI_BONDARYOF_64MB (0x00000017U) /*!< 64 Mbits ( 8 MByte = 2^(23)) */ +#define HAL_XSPI_BONDARYOF_128MB (0x00000018U) /*!< 128 Mbits ( 16 MByte = 2^(24)) */ +#define HAL_XSPI_BONDARYOF_256MB (0x00000019U) /*!< 256 Mbits ( 32 MByte = 2^(25)) */ +#define HAL_XSPI_BONDARYOF_512MB (0x0000001AU) /*!< 512 Mbits ( 64 MByte = 2^(26)) */ +#define HAL_XSPI_BONDARYOF_1GB (0x0000001BU) /*!< 1 Gbits (128 MByte = 2^(27)) */ +#define HAL_XSPI_BONDARYOF_2GB (0x0000001CU) /*!< 2 Gbits (256 MByte = 2^(28)) */ +#define HAL_XSPI_BONDARYOF_4GB (0x0000001DU) /*!< 4 Gbits (512 MByte = 2^(29)) */ +#define HAL_XSPI_BONDARYOF_8GB (0x0000001EU) /*!< 8 Gbits ( 1 GByte = 2^(30)) */ +#define HAL_XSPI_BONDARYOF_16GB (0x0000001FU) /*!< 16 Gbits ( 2 GByte = 2^(31)) */ +/** + * @} + */ + +/** @defgroup XSPI_DelayBlockBypass XSPI Delay Block Bypaas + * @{ + */ +#define HAL_XSPI_DELAY_BLOCK_ON (0x00000000U) /*!< Sampling clock is delayed by the delay block */ +#define HAL_XSPI_DELAY_BLOCK_BYPASS ((uint32_t)OCTOSPI_DCR1_DLYBYP) /*!< Delay block is bypassed */ +/** + * @} + */ + +/** @defgroup XSPI_OperationType XSPI Operation Type + * @{ + */ +#define HAL_XSPI_OPTYPE_COMMON_CFG (0x00000000U) /*!< Common configuration (indirect or auto-polling mode) */ +#define HAL_XSPI_OPTYPE_READ_CFG (0x00000001U) /*!< Read configuration (memory-mapped mode) */ +#define HAL_XSPI_OPTYPE_WRITE_CFG (0x00000002U) /*!< Write configuration (memory-mapped mode) */ +#define HAL_XSPI_OPTYPE_WRAP_CFG (0x00000003U) /*!< Wrap configuration (memory-mapped mode) */ + +/** + * @} + */ + +/** @defgroup XSPI_IOSelect XSPI IO Select + * @{ + */ +#define HAL_XSPI_SELECT_IO_3_0 (0x00000000U) /*!< Data exchanged over IO[3:0] */ +#define HAL_XSPI_SELECT_IO_7_4 ((uint32_t)OCTOSPI_CR_MSEL) /*!< Data exchanged over IO[7:4] */ +#define HAL_XSPI_SELECT_IO_7_0 (0x00000000U) /*!< Data exchanged over IO[7:0] */ +/** + * @} + */ + +/** @defgroup XSPI_InstructionMode XSPI Instruction Mode + * @{ + */ +#define HAL_XSPI_INSTRUCTION_NONE (0x00000000U) /*!< No instruction */ +#define HAL_XSPI_INSTRUCTION_1_LINE ((uint32_t)XSPI_CCR_IMODE_0) /*!< Instruction on a single line */ +#define HAL_XSPI_INSTRUCTION_2_LINES ((uint32_t)XSPI_CCR_IMODE_1) /*!< Instruction on two lines */ +#define HAL_XSPI_INSTRUCTION_4_LINES ((uint32_t)(XSPI_CCR_IMODE_0 | XSPI_CCR_IMODE_1)) /*!< Instruction on four lines */ +#define HAL_XSPI_INSTRUCTION_8_LINES ((uint32_t)XSPI_CCR_IMODE_2) /*!< Instruction on eight lines */ +/** + * @} + */ + +/** @defgroup XSPI_InstructionWidth XSPI Instruction Width + * @{ + */ +#define HAL_XSPI_INSTRUCTION_8_BITS (0x00000000U) /*!< 8-bit instruction */ +#define HAL_XSPI_INSTRUCTION_16_BITS ((uint32_t)XSPI_CCR_ISIZE_0) /*!< 16-bit instruction */ +#define HAL_XSPI_INSTRUCTION_24_BITS ((uint32_t)XSPI_CCR_ISIZE_1) /*!< 24-bit instruction */ +#define HAL_XSPI_INSTRUCTION_32_BITS ((uint32_t)XSPI_CCR_ISIZE) /*!< 32-bit instruction */ +/** + * @} + */ + +/** @defgroup XSPI_InstructionDTRMode XSPI Instruction DTR Mode + * @{ + */ +#define HAL_XSPI_INSTRUCTION_DTR_DISABLE (0x00000000U) /*!< DTR mode disabled for instruction phase */ +#define HAL_XSPI_INSTRUCTION_DTR_ENABLE ((uint32_t)XSPI_CCR_IDTR) /*!< DTR mode enabled for instruction phase */ +/** + * @} + */ + +/** @defgroup XSPI_AddressMode XSPI Address Mode + * @{ + */ +#define HAL_XSPI_ADDRESS_NONE (0x00000000U) /*!< No address */ +#define HAL_XSPI_ADDRESS_1_LINE ((uint32_t)XSPI_CCR_ADMODE_0) /*!< Address on a single line */ +#define HAL_XSPI_ADDRESS_2_LINES ((uint32_t)XSPI_CCR_ADMODE_1) /*!< Address on two lines */ +#define HAL_XSPI_ADDRESS_4_LINES ((uint32_t)(XSPI_CCR_ADMODE_0 | XSPI_CCR_ADMODE_1)) /*!< Address on four lines */ +#define HAL_XSPI_ADDRESS_8_LINES ((uint32_t)XSPI_CCR_ADMODE_2) /*!< Address on eight lines */ +/** + * @} + */ + +/** @defgroup XSPI_AddressWidth XSPI Address width + * @{ + */ +#define HAL_XSPI_ADDRESS_8_BITS (0x00000000U) /*!< 8-bit address */ +#define HAL_XSPI_ADDRESS_16_BITS ((uint32_t)XSPI_CCR_ADSIZE_0) /*!< 16-bit address */ +#define HAL_XSPI_ADDRESS_24_BITS ((uint32_t)XSPI_CCR_ADSIZE_1) /*!< 24-bit address */ +#define HAL_XSPI_ADDRESS_32_BITS ((uint32_t)XSPI_CCR_ADSIZE) /*!< 32-bit address */ +/** + * @} + */ + +/** @defgroup XSPI_AddressDTRMode XSPI Address DTR Mode + * @{ + */ +#define HAL_XSPI_ADDRESS_DTR_DISABLE (0x00000000U) /*!< DTR mode disabled for address phase */ +#define HAL_XSPI_ADDRESS_DTR_ENABLE ((uint32_t)XSPI_CCR_ADDTR) /*!< DTR mode enabled for address phase */ +/** + * @} + */ + +/** @defgroup XSPI_AlternateBytesMode XSPI Alternate Bytes Mode + * @{ + */ +#define HAL_XSPI_ALT_BYTES_NONE (0x00000000U) /*!< No alternate bytes */ +#define HAL_XSPI_ALT_BYTES_1_LINE ((uint32_t)XSPI_CCR_ABMODE_0) /*!< Alternate bytes on a single line */ +#define HAL_XSPI_ALT_BYTES_2_LINES ((uint32_t)XSPI_CCR_ABMODE_1) /*!< Alternate bytes on two lines */ +#define HAL_XSPI_ALT_BYTES_4_LINES ((uint32_t)(XSPI_CCR_ABMODE_0 | XSPI_CCR_ABMODE_1)) /*!< Alternate bytes on four lines */ +#define HAL_XSPI_ALT_BYTES_8_LINES ((uint32_t)XSPI_CCR_ABMODE_2) /*!< Alternate bytes on eight lines */ +/** + * @} + */ + +/** @defgroup XSPI_AlternateBytesWidth XSPI Alternate Bytes Width + * @{ + */ +#define HAL_XSPI_ALT_BYTES_8_BITS (0x00000000U) /*!< 8-bit alternate bytes */ +#define HAL_XSPI_ALT_BYTES_16_BITS ((uint32_t)XSPI_CCR_ABSIZE_0) /*!< 16-bit alternate bytes */ +#define HAL_XSPI_ALT_BYTES_24_BITS ((uint32_t)XSPI_CCR_ABSIZE_1) /*!< 24-bit alternate bytes */ +#define HAL_XSPI_ALT_BYTES_32_BITS ((uint32_t)XSPI_CCR_ABSIZE) /*!< 32-bit alternate bytes */ +/** + * @} + */ + +/** @defgroup XSPI_AlternateBytesDTRMode XSPI Alternate Bytes DTR Mode + * @{ + */ +#define HAL_XSPI_ALT_BYTES_DTR_DISABLE (0x00000000U) /*!< DTR mode disabled for alternate bytes phase */ +#define HAL_XSPI_ALT_BYTES_DTR_ENABLE ((uint32_t)XSPI_CCR_ABDTR) /*!< DTR mode enabled for alternate bytes phase */ +/** + * @} + */ + +/** @defgroup XSPI_DataMode XSPI Data Mode + * @{ + */ +#define HAL_XSPI_DATA_NONE (0x00000000U) /*!< No data */ +#define HAL_XSPI_DATA_1_LINE ((uint32_t)XSPI_CCR_DMODE_0) /*!< Data on a single line */ +#define HAL_XSPI_DATA_2_LINES ((uint32_t)XSPI_CCR_DMODE_1) /*!< Data on two lines */ +#define HAL_XSPI_DATA_4_LINES ((uint32_t)(XSPI_CCR_DMODE_0 | XSPI_CCR_DMODE_1)) /*!< Data on four lines */ +#define HAL_XSPI_DATA_8_LINES ((uint32_t)XSPI_CCR_DMODE_2) /*!< Data on eight lines */ +/** + * @} + */ + +/** @defgroup XSPI_DataDTRMode XSPI Data DTR Mode + * @{ + */ +#define HAL_XSPI_DATA_DTR_DISABLE (0x00000000U) /*!< DTR mode disabled for data phase */ +#define HAL_XSPI_DATA_DTR_ENABLE ((uint32_t)XSPI_CCR_DDTR) /*!< DTR mode enabled for data phase */ +/** + * @} + */ + +/** @defgroup XSPI_DQSMode XSPI DQS Mode + * @{ + */ +#define HAL_XSPI_DQS_DISABLE (0x00000000U) /*!< DQS disabled */ +#define HAL_XSPI_DQS_ENABLE ((uint32_t)XSPI_CCR_DQSE) /*!< DQS enabled */ +/** + * @} + */ + +/** @defgroup XSPI_SIOOMode XSPI SIOO Mode + * @{ + */ +#define HAL_XSPI_SIOO_INST_EVERY_CMD (0x00000000U) /*!< Send instruction on every transaction */ +#define HAL_XSPI_SIOO_INST_ONLY_FIRST_CMD ((uint32_t)XSPI_CCR_SIOO) /*!< Send instruction only for the first command */ +/** + * @} + */ + +/** @defgroup XSPI_WriteZeroLatency XSPI Hyperbus Write Zero Latency Activation + * @{ + */ +#define HAL_XSPI_LATENCY_ON_WRITE (0x00000000U) /*!< Latency on write accesses */ +#define HAL_XSPI_NO_LATENCY_ON_WRITE ((uint32_t)XSPI_HLCR_WZL) /*!< No latency on write accesses */ +/** + * @} + */ + +/** @defgroup XSPI_LatencyMode XSPI Hyperbus Latency Mode + * @{ + */ +#define HAL_XSPI_VARIABLE_LATENCY (0x00000000U) /*!< Variable initial latency */ +#define HAL_XSPI_FIXED_LATENCY ((uint32_t)XSPI_HLCR_LM) /*!< Fixed latency */ +/** + * @} + */ + +/** @defgroup XSPI_AddressSpace XSPI Hyperbus Address Space + * @{ + */ +#define HAL_XSPI_MEMORY_ADDRESS_SPACE (0x00000000U) /*!< HyperBus memory mode */ +#define HAL_XSPI_REGISTER_ADDRESS_SPACE ((uint32_t)XSPI_DCR1_MTYP_0) /*!< HyperBus register mode */ +/** + * @} + */ + +/** @defgroup XSPI_MatchMode XSPI Match Mode + * @{ + */ +#define HAL_XSPI_MATCH_MODE_AND (0x00000000U) /*!< AND match mode between unmasked bits */ +#define HAL_XSPI_MATCH_MODE_OR ((uint32_t)XSPI_CR_PMM) /*!< OR match mode between unmasked bits */ +/** + * @} + */ + +/** @defgroup XSPI_AutomaticStop XSPI Automatic Stop + * @{ + */ +#define HAL_XSPI_AUTOMATIC_STOP_DISABLE (0x00000000U) /*!< AutoPolling stops only with abort or XSPI disabling */ +#define HAL_XSPI_AUTOMATIC_STOP_ENABLE ((uint32_t)XSPI_CR_APMS) /*!< AutoPolling stops as soon as there is a match */ +/** + * @} + */ + +/** @defgroup XSPI_TimeOutActivation XSPI Timeout Activation + * @{ + */ +#define HAL_XSPI_TIMEOUT_COUNTER_DISABLE (0x00000000U) /*!< Timeout counter disabled, nCS remains active */ +#define HAL_XSPI_TIMEOUT_COUNTER_ENABLE ((uint32_t)XSPI_CR_TCEN) /*!< Timeout counter enabled, nCS released when timeout expires */ +/** + * @} + */ + +/** @defgroup XSPI_Flags XSPI Flags + * @{ + */ +#define HAL_XSPI_FLAG_BUSY XSPI_SR_BUSY /*!< Busy flag: operation is ongoing */ +#define HAL_XSPI_FLAG_TO XSPI_SR_TOF /*!< Timeout flag: timeout occurs in memory-mapped mode */ +#define HAL_XSPI_FLAG_SM XSPI_SR_SMF /*!< Status match flag: received data matches in autopolling mode */ +#define HAL_XSPI_FLAG_FT XSPI_SR_FTF /*!< Fifo threshold flag: Fifo threshold reached or data left after read from memory is complete */ +#define HAL_XSPI_FLAG_TC XSPI_SR_TCF /*!< Transfer complete flag: programmed number of data have been transferred or the transfer has been aborted */ +#define HAL_XSPI_FLAG_TE XSPI_SR_TEF /*!< Transfer error flag: invalid address is being accessed */ +/** + * @} + */ + +/** @defgroup XSPI_Interrupts XSPI Interrupts + * @{ + */ +#define HAL_XSPI_IT_TO XSPI_CR_TOIE /*!< Interrupt on the timeout flag */ +#define HAL_XSPI_IT_SM XSPI_CR_SMIE /*!< Interrupt on the status match flag */ +#define HAL_XSPI_IT_FT XSPI_CR_FTIE /*!< Interrupt on the fifo threshold flag */ +#define HAL_XSPI_IT_TC XSPI_CR_TCIE /*!< Interrupt on the transfer complete flag */ +#define HAL_XSPI_IT_TE XSPI_CR_TEIE /*!< Interrupt on the transfer error flag */ +/** + * @} + */ + +/** @defgroup XSPI_Timeout_definition XSPI Timeout definition + * @{ + */ +#define HAL_XSPI_TIMEOUT_DEFAULT_VALUE (5000U) /* 5 s */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup XSPI_Exported_Macros XSPI Exported Macros + * @{ + */ +/** @brief Reset XSPI handle state. + * @param __HANDLE__ specifies the XSPI Handle. + * @retval None + */ +#if defined(USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) +#define HAL_XSPI_RESET_HANDLE_STATE(__HANDLE__) do { \ + (__HANDLE__)->State = HAL_XSPI_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define HAL_XSPI_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_XSPI_STATE_RESET) +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */ + +/** @brief Enable the XSPI peripheral. + * @param __HANDLE__ specifies the XSPI Handle. + * @retval None + */ +#define HAL_XSPI_ENABLE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CR, XSPI_CR_EN) + +/** @brief Disable the XSPI peripheral. + * @param __HANDLE__ specifies the XSPI Handle. + * @retval None + */ +#define HAL_XSPI_DISABLE(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->CR, XSPI_CR_EN) + +/** @brief Enable the specified XSPI interrupt. + * @param __HANDLE__ specifies the XSPI Handle. + * @param __INTERRUPT__ specifies the XSPI interrupt source to enable. + * This parameter can be one of the following values: + * @arg HAL_XSPI_IT_TO: XSPI Timeout interrupt + * @arg HAL_XSPI_IT_SM: XSPI Status match interrupt + * @arg HAL_XSPI_IT_FT: XSPI FIFO threshold interrupt + * @arg HAL_XSPI_IT_TC: XSPI Transfer complete interrupt + * @arg HAL_XSPI_IT_TE: XSPI Transfer error interrupt + * @retval None + */ +#define HAL_XSPI_ENABLE_IT(__HANDLE__, __INTERRUPT__) SET_BIT((__HANDLE__)->Instance->CR, (__INTERRUPT__)) + +/** @brief Disable the specified XSPI interrupt. + * @param __HANDLE__ specifies the XSPI Handle. + * @param __INTERRUPT__ specifies the XSPI interrupt source to disable. + * This parameter can be one of the following values: + * @arg HAL_XSPI_IT_TO: XSPI Timeout interrupt + * @arg HAL_XSPI_IT_SM: XSPI Status match interrupt + * @arg HAL_XSPI_IT_FT: XSPI FIFO threshold interrupt + * @arg HAL_XSPI_IT_TC: XSPI Transfer complete interrupt + * @arg HAL_XSPI_IT_TE: XSPI Transfer error interrupt + * @retval None + */ +#define HAL_XSPI_DISABLE_IT(__HANDLE__, __INTERRUPT__) CLEAR_BIT((__HANDLE__)->Instance->CR, (__INTERRUPT__)) + +/** @brief Check whether the specified XSPI interrupt source is enabled or not. + * @param __HANDLE__ specifies the XSPI Handle. + * @param __INTERRUPT__ specifies the XSPI interrupt source to check. + * This parameter can be one of the following values: + * @arg HAL_XSPI_IT_TO: XSPI Timeout interrupt + * @arg HAL_XSPI_IT_SM: XSPI Status match interrupt + * @arg HAL_XSPI_IT_FT: XSPI FIFO threshold interrupt + * @arg HAL_XSPI_IT_TC: XSPI Transfer complete interrupt + * @arg HAL_XSPI_IT_TE: XSPI Transfer error interrupt + * @retval The new state of __INTERRUPT__ (TRUE or FALSE). + */ +#define HAL_XSPI_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (READ_BIT((__HANDLE__)->Instance->CR, (__INTERRUPT__))\ + == (__INTERRUPT__)) + +/** + * @brief Check whether the selected XSPI flag is set or not. + * @param __HANDLE__ specifies the XSPI Handle. + * @param __FLAG__ specifies the XSPI flag to check. + * This parameter can be one of the following values: + * @arg HAL_XSPI_FLAG_BUSY: XSPI Busy flag + * @arg HAL_XSPI_FLAG_TO: XSPI Timeout flag + * @arg HAL_XSPI_FLAG_SM: XSPI Status match flag + * @arg HAL_XSPI_FLAG_FT: XSPI FIFO threshold flag + * @arg HAL_XSPI_FLAG_TC: XSPI Transfer complete flag + * @arg HAL_XSPI_FLAG_TE: XSPI Transfer error flag + * @retval None + */ +#define HAL_XSPI_GET_FLAG(__HANDLE__, __FLAG__) ((READ_BIT((__HANDLE__)->Instance->SR, (__FLAG__)) \ + != 0U) ? SET : RESET) + +/** @brief Clears the specified XSPI's flag status. + * @param __HANDLE__ specifies the XSPI Handle. + * @param __FLAG__ specifies the XSPI clear register flag that needs to be set + * This parameter can be one of the following values: + * @arg HAL_XSPI_FLAG_TO: XSPI Timeout flag + * @arg HAL_XSPI_FLAG_SM: XSPI Status match flag + * @arg HAL_XSPI_FLAG_TC: XSPI Transfer complete flag + * @arg HAL_XSPI_FLAG_TE: XSPI Transfer error flag + * @retval None + */ +#define HAL_XSPI_CLEAR_FLAG(__HANDLE__, __FLAG__) WRITE_REG((__HANDLE__)->Instance->FCR, (__FLAG__)) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup XSPI_Exported_Functions + * @{ + */ + +/* Initialization/de-initialization functions ********************************/ +/** @addtogroup XSPI_Exported_Functions_Group1 + * @{ + */ +HAL_StatusTypeDef HAL_XSPI_Init(XSPI_HandleTypeDef *hxspi); +void HAL_XSPI_MspInit(XSPI_HandleTypeDef *hxspi); +HAL_StatusTypeDef HAL_XSPI_DeInit(XSPI_HandleTypeDef *hxspi); +void HAL_XSPI_MspDeInit(XSPI_HandleTypeDef *hxspi); + +/** + * @} + */ + +/* IO operation functions *****************************************************/ +/** @addtogroup XSPI_Exported_Functions_Group2 + * @{ + */ +/* XSPI IRQ handler function */ +void HAL_XSPI_IRQHandler(XSPI_HandleTypeDef *hxspi); + +/* XSPI command configuration functions */ +HAL_StatusTypeDef HAL_XSPI_Command(XSPI_HandleTypeDef *hxspi, XSPI_RegularCmdTypeDef *const pCmd, + uint32_t Timeout); +HAL_StatusTypeDef HAL_XSPI_Command_IT(XSPI_HandleTypeDef *hxspi, XSPI_RegularCmdTypeDef *const pCmd); +HAL_StatusTypeDef HAL_XSPI_HyperbusCfg(XSPI_HandleTypeDef *hxspi, XSPI_HyperbusCfgTypeDef *const pCfg, + uint32_t Timeout); +HAL_StatusTypeDef HAL_XSPI_HyperbusCmd(XSPI_HandleTypeDef *hxspi, XSPI_HyperbusCmdTypeDef *const pCmd, + uint32_t Timeout); + +/* XSPI indirect mode functions */ +HAL_StatusTypeDef HAL_XSPI_Transmit(XSPI_HandleTypeDef *hxspi, uint8_t *const pData, uint32_t Timeout); +HAL_StatusTypeDef HAL_XSPI_Receive(XSPI_HandleTypeDef *hxspi, uint8_t *const pData, uint32_t Timeout); +HAL_StatusTypeDef HAL_XSPI_Transmit_IT(XSPI_HandleTypeDef *hxspi, uint8_t *const pData); +HAL_StatusTypeDef HAL_XSPI_Receive_IT(XSPI_HandleTypeDef *hxspi, uint8_t *const pData); +HAL_StatusTypeDef HAL_XSPI_Transmit_DMA(XSPI_HandleTypeDef *hxspi, uint8_t *const pData); +HAL_StatusTypeDef HAL_XSPI_Receive_DMA(XSPI_HandleTypeDef *hxspi, uint8_t *const pData); + +/* XSPI status flag polling mode functions */ +HAL_StatusTypeDef HAL_XSPI_AutoPolling(XSPI_HandleTypeDef *hxspi, XSPI_AutoPollingTypeDef *const pCfg, + uint32_t Timeout); +HAL_StatusTypeDef HAL_XSPI_AutoPolling_IT(XSPI_HandleTypeDef *hxspi, XSPI_AutoPollingTypeDef *const pCfg); + +/* XSPI memory-mapped mode functions */ +HAL_StatusTypeDef HAL_XSPI_MemoryMapped(XSPI_HandleTypeDef *hxspi, XSPI_MemoryMappedTypeDef *const pCfg); + +/* Callback functions in non-blocking modes ***********************************/ +void HAL_XSPI_ErrorCallback(XSPI_HandleTypeDef *hxspi); +void HAL_XSPI_AbortCpltCallback(XSPI_HandleTypeDef *hxspi); +void HAL_XSPI_FifoThresholdCallback(XSPI_HandleTypeDef *hxspi); + +/* XSPI indirect mode Callback functions */ +void HAL_XSPI_CmdCpltCallback(XSPI_HandleTypeDef *hxspi); +void HAL_XSPI_RxCpltCallback(XSPI_HandleTypeDef *hxspi); +void HAL_XSPI_TxCpltCallback(XSPI_HandleTypeDef *hxspi); +void HAL_XSPI_RxHalfCpltCallback(XSPI_HandleTypeDef *hxspi); +void HAL_XSPI_TxHalfCpltCallback(XSPI_HandleTypeDef *hxspi); + +/* XSPI status flag polling mode functions */ +void HAL_XSPI_StatusMatchCallback(XSPI_HandleTypeDef *hxspi); + +/* XSPI memory-mapped mode functions */ +void HAL_XSPI_TimeOutCallback(XSPI_HandleTypeDef *hxspi); + +#if defined(USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) +/* XSPI callback registering/unregistering */ +HAL_StatusTypeDef HAL_XSPI_RegisterCallback(XSPI_HandleTypeDef *hxspi, HAL_XSPI_CallbackIDTypeDef CallbackID, + pXSPI_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_XSPI_UnRegisterCallback(XSPI_HandleTypeDef *hxspi, HAL_XSPI_CallbackIDTypeDef CallbackID); +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */ + +/** + * @} + */ + +/* Peripheral Control and State functions ************************************/ +/** @addtogroup XSPI_Exported_Functions_Group3 + * @{ + */ +HAL_StatusTypeDef HAL_XSPI_Abort(XSPI_HandleTypeDef *hxspi); +HAL_StatusTypeDef HAL_XSPI_Abort_IT(XSPI_HandleTypeDef *hxspi); +HAL_StatusTypeDef HAL_XSPI_SetFifoThreshold(XSPI_HandleTypeDef *hxspi, uint32_t Threshold); +uint32_t HAL_XSPI_GetFifoThreshold(const XSPI_HandleTypeDef *hxspi); +HAL_StatusTypeDef HAL_XSPI_SetMemoryType(XSPI_HandleTypeDef *hxspi, uint32_t Type); +HAL_StatusTypeDef HAL_XSPI_SetDeviceSize(XSPI_HandleTypeDef *hxspi, uint32_t Size); +HAL_StatusTypeDef HAL_XSPI_SetClockPrescaler(XSPI_HandleTypeDef *hxspi, uint32_t Prescaler); +HAL_StatusTypeDef HAL_XSPI_SetTimeout(XSPI_HandleTypeDef *hxspi, uint32_t Timeout); +uint32_t HAL_XSPI_GetError(const XSPI_HandleTypeDef *hxspi); +uint32_t HAL_XSPI_GetState(const XSPI_HandleTypeDef *hxspi); + +/** + * @} + */ + +/* XSPI Delay Block functions ************************************/ +/** @addtogroup XSPI_Exported_Functions_Group4 + * @{ + */ + +HAL_StatusTypeDef HAL_XSPI_DLYB_SetConfig(XSPI_HandleTypeDef *hxspi, HAL_XSPI_DLYB_CfgTypeDef *const pdlyb_cfg); +HAL_StatusTypeDef HAL_XSPI_DLYB_GetConfig(XSPI_HandleTypeDef *hxspi, HAL_XSPI_DLYB_CfgTypeDef *const pdlyb_cfg); +HAL_StatusTypeDef HAL_XSPI_DLYB_GetClockPeriod(XSPI_HandleTypeDef *hxspi, + HAL_XSPI_DLYB_CfgTypeDef *const pdlyb_cfg); + +/** + * @} + */ + +/** + * @} + */ +/* End of exported functions -------------------------------------------------*/ + +/* Private macros ------------------------------------------------------------*/ +/** + @cond 0 + */ +#define IS_XSPI_FIFO_THRESHOLD_BYTE(THRESHOLD) (((THRESHOLD) >= 1U) &&\ + ((THRESHOLD) <= ((XSPI_CR_FTHRES >> XSPI_CR_FTHRES_Pos)+1U))) +#define IS_XSPI_MEMORY_MODE(MODE) (((MODE) == HAL_XSPI_SINGLE_MEM) || \ + ((MODE) == HAL_XSPI_DUAL_MEM)) + +#define IS_XSPI_MEMORY_TYPE(TYPE) (((TYPE) == HAL_XSPI_MEMTYPE_MICRON) || \ + ((TYPE) == HAL_XSPI_MEMTYPE_MACRONIX) || \ + ((TYPE) == HAL_XSPI_MEMTYPE_APMEM) || \ + ((TYPE) == HAL_XSPI_MEMTYPE_MACRONIX_RAM) || \ + ((TYPE) == HAL_XSPI_MEMTYPE_HYPERBUS) || \ + ((TYPE) == HAL_XSPI_MEMTYPE_APMEM_16BITS)) + +#define IS_XSPI_MEMORY_SIZE(SIZE) (((SIZE) == HAL_XSPI_SIZE_16B) || \ + ((SIZE) == HAL_XSPI_SIZE_32B) || \ + ((SIZE) == HAL_XSPI_SIZE_64B) || \ + ((SIZE) == HAL_XSPI_SIZE_128B) || \ + ((SIZE) == HAL_XSPI_SIZE_256B) || \ + ((SIZE) == HAL_XSPI_SIZE_512B) || \ + ((SIZE) == HAL_XSPI_SIZE_1KB) || \ + ((SIZE) == HAL_XSPI_SIZE_2KB) || \ + ((SIZE) == HAL_XSPI_SIZE_4KB) || \ + ((SIZE) == HAL_XSPI_SIZE_8KB) || \ + ((SIZE) == HAL_XSPI_SIZE_16KB) || \ + ((SIZE) == HAL_XSPI_SIZE_32KB) || \ + ((SIZE) == HAL_XSPI_SIZE_64KB) || \ + ((SIZE) == HAL_XSPI_SIZE_128KB) || \ + ((SIZE) == HAL_XSPI_SIZE_256KB) || \ + ((SIZE) == HAL_XSPI_SIZE_512KB) || \ + ((SIZE) == HAL_XSPI_SIZE_1MB) || \ + ((SIZE) == HAL_XSPI_SIZE_2MB) || \ + ((SIZE) == HAL_XSPI_SIZE_4MB) || \ + ((SIZE) == HAL_XSPI_SIZE_8MB) || \ + ((SIZE) == HAL_XSPI_SIZE_16MB) || \ + ((SIZE) == HAL_XSPI_SIZE_32MB) || \ + ((SIZE) == HAL_XSPI_SIZE_64MB) || \ + ((SIZE) == HAL_XSPI_SIZE_128MB) || \ + ((SIZE) == HAL_XSPI_SIZE_256MB) || \ + ((SIZE) == HAL_XSPI_SIZE_512MB) || \ + ((SIZE) == HAL_XSPI_SIZE_1GB) || \ + ((SIZE) == HAL_XSPI_SIZE_2GB) || \ + ((SIZE) == HAL_XSPI_SIZE_4GB) || \ + ((SIZE) == HAL_XSPI_SIZE_8GB) || \ + ((SIZE) == HAL_XSPI_SIZE_16GB) || \ + ((SIZE) == HAL_XSPI_SIZE_32GB)) + +#define IS_XSPI_CS_HIGH_TIME_CYCLE(TIME) (((TIME) >= 1U) && ((TIME) <= 64U)) + +#define IS_XSPI_FREE_RUN_CLK(CLK) (((CLK) == HAL_XSPI_FREERUNCLK_DISABLE) || \ + ((CLK) == HAL_XSPI_FREERUNCLK_ENABLE)) + +#define IS_XSPI_CLOCK_MODE(MODE) (((MODE) == HAL_XSPI_CLOCK_MODE_0) || \ + ((MODE) == HAL_XSPI_CLOCK_MODE_3)) + +#define IS_XSPI_WRAP_SIZE(SIZE) (((SIZE) == HAL_XSPI_WRAP_NOT_SUPPORTED) || \ + ((SIZE) == HAL_XSPI_WRAP_16_BYTES) || \ + ((SIZE) == HAL_XSPI_WRAP_32_BYTES) || \ + ((SIZE) == HAL_XSPI_WRAP_64_BYTES) || \ + ((SIZE) == HAL_XSPI_WRAP_128_BYTES)) + +#define IS_XSPI_CLK_PRESCALER(PRESCALER) ((PRESCALER) <= 255U) + +#define IS_XSPI_SAMPLE_SHIFTING(CYCLE) (((CYCLE) == HAL_XSPI_SAMPLE_SHIFT_NONE) || \ + ((CYCLE) == HAL_XSPI_SAMPLE_SHIFT_HALFCYCLE)) + +#define IS_XSPI_DHQC(CYCLE) (((CYCLE) == HAL_XSPI_DHQC_DISABLE) || \ + ((CYCLE) == HAL_XSPI_DHQC_ENABLE)) + +#define IS_XSPI_CS_BOUND(SIZE) (((SIZE) == HAL_XSPI_BONDARYOF_NONE) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_16B) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_32B) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_64B) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_128B) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_256B) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_512B) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_1KB) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_2KB) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_4KB) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_8KB) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_16KB) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_32KB) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_64KB) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_128KB) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_256KB) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_512KB) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_1MB) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_2MB) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_4MB) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_8MB) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_16MB) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_32MB) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_64MB) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_128MB) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_256MB) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_512MB) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_1GB) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_2GB) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_4GB) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_8GB) || \ + ((SIZE) == HAL_XSPI_BONDARYOF_16GB)) + +#define IS_XSPI_DLYB_BYPASS(DLYB) (((DLYB) == HAL_XSPI_DELAY_BLOCK_ON) || \ + ((DLYB) == HAL_XSPI_DELAY_BLOCK_BYPASS)) + + + +#define IS_XSPI_OPERATION_TYPE(TYPE) (((TYPE) == HAL_XSPI_OPTYPE_COMMON_CFG) || \ + ((TYPE) == HAL_XSPI_OPTYPE_READ_CFG) || \ + ((TYPE) == HAL_XSPI_OPTYPE_WRITE_CFG) || \ + ((TYPE) == HAL_XSPI_OPTYPE_WRAP_CFG)) + +#define IS_XSPI_IO_SELECT(MEMSEL) (((MEMSEL) == HAL_XSPI_SELECT_IO_3_0) || \ + ((MEMSEL) == HAL_XSPI_SELECT_IO_7_4) || \ + ((MEMSEL) == HAL_XSPI_SELECT_IO_7_0)) + +#define IS_XSPI_INSTRUCTION(OPCODE) ((OPCODE) <= 0xFFFFFFFFU) + +#define IS_XSPI_INSTRUCTION_MODE(MODE) (((MODE) == HAL_XSPI_INSTRUCTION_NONE) || \ + ((MODE) == HAL_XSPI_INSTRUCTION_1_LINE) || \ + ((MODE) == HAL_XSPI_INSTRUCTION_2_LINES) || \ + ((MODE) == HAL_XSPI_INSTRUCTION_4_LINES) || \ + ((MODE) == HAL_XSPI_INSTRUCTION_8_LINES)) + +#define IS_XSPI_INSTRUCTION_WIDTH(WIDTH) (((WIDTH) == HAL_XSPI_INSTRUCTION_8_BITS) || \ + ((WIDTH) == HAL_XSPI_INSTRUCTION_16_BITS) || \ + ((WIDTH) == HAL_XSPI_INSTRUCTION_24_BITS) || \ + ((WIDTH) == HAL_XSPI_INSTRUCTION_32_BITS)) + +#define IS_XSPI_INSTRUCTION_DTR_MODE(MODE) (((MODE) == HAL_XSPI_INSTRUCTION_DTR_DISABLE) || \ + ((MODE) == HAL_XSPI_INSTRUCTION_DTR_ENABLE)) + +#define IS_XSPI_ADDRESS_MODE(MODE) (((MODE) == HAL_XSPI_ADDRESS_NONE) || \ + ((MODE) == HAL_XSPI_ADDRESS_1_LINE) || \ + ((MODE) == HAL_XSPI_ADDRESS_2_LINES) || \ + ((MODE) == HAL_XSPI_ADDRESS_4_LINES) || \ + ((MODE) == HAL_XSPI_ADDRESS_8_LINES)) + +#define IS_XSPI_ADDRESS_WIDTH(WIDTH) (((WIDTH) == HAL_XSPI_ADDRESS_8_BITS) || \ + ((WIDTH) == HAL_XSPI_ADDRESS_16_BITS) || \ + ((WIDTH) == HAL_XSPI_ADDRESS_24_BITS) || \ + ((WIDTH) == HAL_XSPI_ADDRESS_32_BITS)) + +#define IS_XSPI_ADDRESS_DTR_MODE(MODE) (((MODE) == HAL_XSPI_ADDRESS_DTR_DISABLE) || \ + ((MODE) == HAL_XSPI_ADDRESS_DTR_ENABLE)) + +#define IS_XSPI_ALT_BYTES_MODE(MODE) (((MODE) == HAL_XSPI_ALT_BYTES_NONE) || \ + ((MODE) == HAL_XSPI_ALT_BYTES_1_LINE) || \ + ((MODE) == HAL_XSPI_ALT_BYTES_2_LINES) || \ + ((MODE) == HAL_XSPI_ALT_BYTES_4_LINES) || \ + ((MODE) == HAL_XSPI_ALT_BYTES_8_LINES)) + +#define IS_XSPI_ALT_BYTES_WIDTH(WIDTH) (((WIDTH) == HAL_XSPI_ALT_BYTES_8_BITS) || \ + ((WIDTH) == HAL_XSPI_ALT_BYTES_16_BITS) || \ + ((WIDTH) == HAL_XSPI_ALT_BYTES_24_BITS) || \ + ((WIDTH) == HAL_XSPI_ALT_BYTES_32_BITS)) + +#define IS_XSPI_ALT_BYTES_DTR_MODE(MODE) (((MODE) == HAL_XSPI_ALT_BYTES_DTR_DISABLE) || \ + ((MODE) == HAL_XSPI_ALT_BYTES_DTR_ENABLE)) + +#define IS_XSPI_DATA_MODE(MODE) (((MODE) == HAL_XSPI_DATA_NONE) || \ + ((MODE) == HAL_XSPI_DATA_1_LINE) || \ + ((MODE) == HAL_XSPI_DATA_2_LINES) || \ + ((MODE) == HAL_XSPI_DATA_4_LINES) || \ + ((MODE) == HAL_XSPI_DATA_8_LINES)) + +#define IS_XSPI_DATA_LENGTH(NUMBER) ((NUMBER) >= 1U) + +#define IS_XSPI_DATA_DTR_MODE(MODE) (((MODE) == HAL_XSPI_DATA_DTR_DISABLE) || \ + ((MODE) == HAL_XSPI_DATA_DTR_ENABLE)) + +#define IS_XSPI_DUMMY_CYCLES(NUMBER) ((NUMBER) <= 31U) + +#define IS_XSPI_DQS_MODE(MODE) (((MODE) == HAL_XSPI_DQS_DISABLE) || \ + ((MODE) == HAL_XSPI_DQS_ENABLE)) + +#define IS_XSPI_SIOO_MODE(MODE) (((MODE) == HAL_XSPI_SIOO_INST_EVERY_CMD) || \ + ((MODE) == HAL_XSPI_SIOO_INST_ONLY_FIRST_CMD)) + +#define IS_XSPI_RW_RECOVERY_TIME_CYCLE(CYCLE) ((CYCLE) <= 255U) + +#define IS_XSPI_ACCESS_TIME_CYCLE(CYCLE) ((CYCLE) <= 255U) + +#define IS_XSPI_WRITE_ZERO_LATENCY(MODE) (((MODE) == HAL_XSPI_LATENCY_ON_WRITE) || \ + ((MODE) == HAL_XSPI_NO_LATENCY_ON_WRITE)) + +#define IS_XSPI_LATENCY_MODE(MODE) (((MODE) == HAL_XSPI_VARIABLE_LATENCY) || \ + ((MODE) == HAL_XSPI_FIXED_LATENCY)) + +#define IS_XSPI_ADDRESS_SPACE(SPACE) (((SPACE) == HAL_XSPI_MEMORY_ADDRESS_SPACE) || \ + ((SPACE) == HAL_XSPI_REGISTER_ADDRESS_SPACE)) + +#define IS_XSPI_MATCH_MODE(MODE) (((MODE) == HAL_XSPI_MATCH_MODE_AND) || \ + ((MODE) == HAL_XSPI_MATCH_MODE_OR)) + +#define IS_XSPI_AUTOMATIC_STOP(MODE) (((MODE) == HAL_XSPI_AUTOMATIC_STOP_ENABLE) || \ + ((MODE) == HAL_XSPI_AUTOMATIC_STOP_DISABLE)) + +#define IS_XSPI_INTERVAL(INTERVAL) ((INTERVAL) <= 0xFFFFU) + +#define IS_XSPI_STATUS_BYTES_SIZE(SIZE) (((SIZE) >= 1U) && ((SIZE) <= 4U)) + +#define IS_XSPI_TIMEOUT_ACTIVATION(MODE) (((MODE) == HAL_XSPI_TIMEOUT_COUNTER_DISABLE) || \ + ((MODE) == HAL_XSPI_TIMEOUT_COUNTER_ENABLE)) + +#define IS_XSPI_TIMEOUT_PERIOD(PERIOD) ((PERIOD) <= 0xFFFFU) + +/** + @endcond + */ + +/* End of private macros -----------------------------------------------------*/ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HSPI || HSPI1 || HSPI2 || OCTOSPI || OCTOSPI1 || OCTOSPI2 */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_XSPI_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_adc.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_adc.h new file mode 100644 index 0000000000..968068d28f --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_adc.h @@ -0,0 +1,8316 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_adc.h + * @author MCD Application Team + * @brief Header file of ADC LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_LL_ADC_H +#define STM32H5xx_LL_ADC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (ADC1) || defined (ADC2) + +/** @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_SQRX_REGOFFSET_POS (8UL) /* Position of bits ADC_SQRx_REGOFFSET in ADC_REG_SQRX_REGOFFSET_MASK*/ +#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 (ADC_SQR1_SQ1_Pos) +#define ADC_REG_RANK_2_SQRX_BITOFFSET_POS (ADC_SQR1_SQ2_Pos) +#define ADC_REG_RANK_3_SQRX_BITOFFSET_POS (ADC_SQR1_SQ3_Pos) +#define ADC_REG_RANK_4_SQRX_BITOFFSET_POS (ADC_SQR1_SQ4_Pos) +#define ADC_REG_RANK_5_SQRX_BITOFFSET_POS (ADC_SQR2_SQ5_Pos) +#define ADC_REG_RANK_6_SQRX_BITOFFSET_POS (ADC_SQR2_SQ6_Pos) +#define ADC_REG_RANK_7_SQRX_BITOFFSET_POS (ADC_SQR2_SQ7_Pos) +#define ADC_REG_RANK_8_SQRX_BITOFFSET_POS (ADC_SQR2_SQ8_Pos) +#define ADC_REG_RANK_9_SQRX_BITOFFSET_POS (ADC_SQR2_SQ9_Pos) +#define ADC_REG_RANK_10_SQRX_BITOFFSET_POS (ADC_SQR3_SQ10_Pos) +#define ADC_REG_RANK_11_SQRX_BITOFFSET_POS (ADC_SQR3_SQ11_Pos) +#define ADC_REG_RANK_12_SQRX_BITOFFSET_POS (ADC_SQR3_SQ12_Pos) +#define ADC_REG_RANK_13_SQRX_BITOFFSET_POS (ADC_SQR3_SQ13_Pos) +#define ADC_REG_RANK_14_SQRX_BITOFFSET_POS (ADC_SQR3_SQ14_Pos) +#define ADC_REG_RANK_15_SQRX_BITOFFSET_POS (ADC_SQR4_SQ15_Pos) +#define ADC_REG_RANK_16_SQRX_BITOFFSET_POS (ADC_SQR4_SQ16_Pos) + + + +/* Internal mask for ADC group injected sequencer: */ +/* To select into literal LL_ADC_INJ_RANK_x the relevant bits for: */ +/* - data 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) + +#define ADC_INJ_JDRX_REGOFFSET_MASK (ADC_JDR1_REGOFFSET | ADC_JDR2_REGOFFSET \ + | ADC_JDR3_REGOFFSET | ADC_JDR4_REGOFFSET) +#define ADC_INJ_RANK_ID_JSQR_MASK (ADC_CHANNEL_ID_NUMBER_MASK_POSBIT0) +#define ADC_JDRX_REGOFFSET_POS (8UL) /* Position of bits ADC_JDRx_REGOFFSET in ADC_INJ_JDRX_REGOFFSET_MASK*/ + +/* Definition of ADC group injected sequencer bits information to be inserted */ +/* into ADC group injected sequencer ranks literals definition. */ +#define ADC_INJ_RANK_1_JSQR_BITOFFSET_POS (ADC_JSQR_JSQ1_Pos) +#define ADC_INJ_RANK_2_JSQR_BITOFFSET_POS (ADC_JSQR_JSQ2_Pos) +#define ADC_INJ_RANK_3_JSQR_BITOFFSET_POS (ADC_JSQR_JSQ3_Pos) +#define ADC_INJ_RANK_4_JSQR_BITOFFSET_POS (ADC_JSQR_JSQ4_Pos) + + + +/* 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_CFGR_EXTEN_0) /* Trigger edge set to rising edge (default setting for + compatibility with some ADC on other STM32 series + 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_CFGR_EXTSEL) << (4U * 0UL)) | \ + ((ADC_CFGR_EXTSEL) << (4U * 1UL)) | \ + ((ADC_CFGR_EXTSEL) << (4U * 2UL)) | \ + ((ADC_CFGR_EXTSEL) << (4U * 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_CFGR_EXTEN) << (4U * 0UL)) | \ + ((ADC_REG_TRIG_EXT_EDGE_DEFAULT) << (4U * 1UL)) | \ + ((ADC_REG_TRIG_EXT_EDGE_DEFAULT) << (4U * 2UL)) | \ + ((ADC_REG_TRIG_EXT_EDGE_DEFAULT) << (4U * 3UL)) ) + +/* Definition of ADC group regular trigger bits information. */ +#define ADC_REG_TRIG_EXTSEL_BITOFFSET_POS (ADC_CFGR_EXTSEL_Pos) +#define ADC_REG_TRIG_EXTEN_BITOFFSET_POS (ADC_CFGR_EXTEN_Pos) + + + +/* 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_JSQR_JEXTEN_0) /* Trigger edge set to rising edge (default setting for + compatibility with some ADC on other STM32 series + 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_INJ_TRIG_SOFTWARE & ADC_JSQR_JEXTSEL) << (4U * 0UL)) | \ + ((ADC_JSQR_JEXTSEL) << (4U * 1UL)) | \ + ((ADC_JSQR_JEXTSEL) << (4U * 2UL)) | \ + ((ADC_JSQR_JEXTSEL) << (4U * 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_JSQR_JEXTEN) << (4U * 0UL)) | \ + ((ADC_INJ_TRIG_EXT_EDGE_DEFAULT) << (4U * 1UL)) | \ + ((ADC_INJ_TRIG_EXT_EDGE_DEFAULT) << (4U * 2UL)) | \ + ((ADC_INJ_TRIG_EXT_EDGE_DEFAULT) << (4U * 3UL)) ) + +/* Definition of ADC group injected trigger bits information. */ +#define ADC_INJ_TRIG_EXTSEL_BITOFFSET_POS (ADC_JSQR_JEXTSEL_Pos) +#define ADC_INJ_TRIG_EXTEN_BITOFFSET_POS (ADC_JSQR_JEXTEN_Pos) + + + + + + +/* Internal mask for ADC channel: */ +/* To select into literal LL_ADC_CHANNEL_x the relevant bits for: */ +/* - channel identifier defined by number */ +/* - channel identifier defined by bitfield */ +/* - 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_CFGR_AWD1CH) +#define ADC_CHANNEL_ID_BITFIELD_MASK (ADC_AWD2CR_AWD2CH) +#define ADC_CHANNEL_ID_NUMBER_BITOFFSET_POS (ADC_CFGR_AWD1CH_Pos) +#define ADC_CHANNEL_ID_MASK (ADC_CHANNEL_ID_NUMBER_MASK | ADC_CHANNEL_ID_BITFIELD_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 (ADC_SQR2_SQ5) /* Equivalent to shift: (ADC_CHANNEL_NUMBER_MASK + >> [Position of bitfield "ADC_CHANNEL_NUMBER_MASK" in register]) */ + +/* 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 (0x00080000UL) /* 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_ID_INTERNAL_CH_MASK (ADC_CHANNEL_ID_INTERNAL_CH | ADC_CHANNEL_ID_INTERNAL_CH_2) + +/* 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_SMPRX_REGOFFSET_POS (25UL) /* Position of bits ADC_SMPRx_REGOFFSET + in ADC_CHANNEL_SMPRX_REGOFFSET_MASK */ + +#define ADC_CHANNEL_SMPx_BITOFFSET_MASK (0x01F00000UL) +#define ADC_CHANNEL_SMPx_BITOFFSET_POS (20UL) /* Equivalent to bitfield "ADC_CHANNEL_SMPx_BITOFFSET_MASK" + position in register */ + +/* 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_CFGR_AWD1CH_0) +#define ADC_CHANNEL_2_NUMBER (ADC_CFGR_AWD1CH_1) +#define ADC_CHANNEL_3_NUMBER (ADC_CFGR_AWD1CH_1 | ADC_CFGR_AWD1CH_0) +#define ADC_CHANNEL_4_NUMBER (ADC_CFGR_AWD1CH_2) +#define ADC_CHANNEL_5_NUMBER (ADC_CFGR_AWD1CH_2 | ADC_CFGR_AWD1CH_0) +#define ADC_CHANNEL_6_NUMBER (ADC_CFGR_AWD1CH_2 | ADC_CFGR_AWD1CH_1) +#define ADC_CHANNEL_7_NUMBER (ADC_CFGR_AWD1CH_2 | ADC_CFGR_AWD1CH_1 | ADC_CFGR_AWD1CH_0) +#define ADC_CHANNEL_8_NUMBER (ADC_CFGR_AWD1CH_3) +#define ADC_CHANNEL_9_NUMBER (ADC_CFGR_AWD1CH_3 | ADC_CFGR_AWD1CH_0) +#define ADC_CHANNEL_10_NUMBER (ADC_CFGR_AWD1CH_3 | ADC_CFGR_AWD1CH_1) +#define ADC_CHANNEL_11_NUMBER (ADC_CFGR_AWD1CH_3 | ADC_CFGR_AWD1CH_1 | ADC_CFGR_AWD1CH_0) +#define ADC_CHANNEL_12_NUMBER (ADC_CFGR_AWD1CH_3 | ADC_CFGR_AWD1CH_2) +#define ADC_CHANNEL_13_NUMBER (ADC_CFGR_AWD1CH_3 | ADC_CFGR_AWD1CH_2 | ADC_CFGR_AWD1CH_0) +#define ADC_CHANNEL_14_NUMBER (ADC_CFGR_AWD1CH_3 | ADC_CFGR_AWD1CH_2 | ADC_CFGR_AWD1CH_1) +#define ADC_CHANNEL_15_NUMBER (ADC_CFGR_AWD1CH_3 | ADC_CFGR_AWD1CH_2 | \ + ADC_CFGR_AWD1CH_1 | ADC_CFGR_AWD1CH_0) +#define ADC_CHANNEL_16_NUMBER (ADC_CFGR_AWD1CH_4) +#define ADC_CHANNEL_17_NUMBER (ADC_CFGR_AWD1CH_4 | ADC_CFGR_AWD1CH_0) +#define ADC_CHANNEL_18_NUMBER (ADC_CFGR_AWD1CH_4 | ADC_CFGR_AWD1CH_1) +#define ADC_CHANNEL_19_NUMBER (ADC_CFGR_AWD1CH_4 | ADC_CFGR_AWD1CH_1 | ADC_CFGR_AWD1CH_0) + +/* Definition of channels ID bitfield information to be inserted into */ +/* channels literals definition. */ +#define ADC_CHANNEL_0_BITFIELD (ADC_AWD2CR_AWD2CH_0) +#define ADC_CHANNEL_1_BITFIELD (ADC_AWD2CR_AWD2CH_1) +#define ADC_CHANNEL_2_BITFIELD (ADC_AWD2CR_AWD2CH_2) +#define ADC_CHANNEL_3_BITFIELD (ADC_AWD2CR_AWD2CH_3) +#define ADC_CHANNEL_4_BITFIELD (ADC_AWD2CR_AWD2CH_4) +#define ADC_CHANNEL_5_BITFIELD (ADC_AWD2CR_AWD2CH_5) +#define ADC_CHANNEL_6_BITFIELD (ADC_AWD2CR_AWD2CH_6) +#define ADC_CHANNEL_7_BITFIELD (ADC_AWD2CR_AWD2CH_7) +#define ADC_CHANNEL_8_BITFIELD (ADC_AWD2CR_AWD2CH_8) +#define ADC_CHANNEL_9_BITFIELD (ADC_AWD2CR_AWD2CH_9) +#define ADC_CHANNEL_10_BITFIELD (ADC_AWD2CR_AWD2CH_10) +#define ADC_CHANNEL_11_BITFIELD (ADC_AWD2CR_AWD2CH_11) +#define ADC_CHANNEL_12_BITFIELD (ADC_AWD2CR_AWD2CH_12) +#define ADC_CHANNEL_13_BITFIELD (ADC_AWD2CR_AWD2CH_13) +#define ADC_CHANNEL_14_BITFIELD (ADC_AWD2CR_AWD2CH_14) +#define ADC_CHANNEL_15_BITFIELD (ADC_AWD2CR_AWD2CH_15) +#define ADC_CHANNEL_16_BITFIELD (ADC_AWD2CR_AWD2CH_16) +#define ADC_CHANNEL_17_BITFIELD (ADC_AWD2CR_AWD2CH_17) +#define ADC_CHANNEL_18_BITFIELD (ADC_AWD2CR_AWD2CH_18) +#define ADC_CHANNEL_19_BITFIELD (ADC_AWD2CR_AWD2CH_19) + +/* Definition of channels sampling time information to be inserted into */ +/* channels literals definition. */ +/* Value shifted are equivalent to bitfield "ADC_SMPRx_SMPy" position */ +/* in register. */ +#define ADC_CHANNEL_0_SMP (ADC_SMPR1_REGOFFSET | (( 0UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) +#define ADC_CHANNEL_1_SMP (ADC_SMPR1_REGOFFSET | (( 3UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) +#define ADC_CHANNEL_2_SMP (ADC_SMPR1_REGOFFSET | (( 6UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) +#define ADC_CHANNEL_3_SMP (ADC_SMPR1_REGOFFSET | (( 9UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) +#define ADC_CHANNEL_4_SMP (ADC_SMPR1_REGOFFSET | ((12UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) +#define ADC_CHANNEL_5_SMP (ADC_SMPR1_REGOFFSET | ((15UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) +#define ADC_CHANNEL_6_SMP (ADC_SMPR1_REGOFFSET | ((18UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) +#define ADC_CHANNEL_7_SMP (ADC_SMPR1_REGOFFSET | ((21UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) +#define ADC_CHANNEL_8_SMP (ADC_SMPR1_REGOFFSET | ((24UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) +#define ADC_CHANNEL_9_SMP (ADC_SMPR1_REGOFFSET | ((27UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) +#define ADC_CHANNEL_10_SMP (ADC_SMPR2_REGOFFSET | (( 0UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) +#define ADC_CHANNEL_11_SMP (ADC_SMPR2_REGOFFSET | (( 3UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) +#define ADC_CHANNEL_12_SMP (ADC_SMPR2_REGOFFSET | (( 6UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) +#define ADC_CHANNEL_13_SMP (ADC_SMPR2_REGOFFSET | (( 9UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) +#define ADC_CHANNEL_14_SMP (ADC_SMPR2_REGOFFSET | ((12UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) +#define ADC_CHANNEL_15_SMP (ADC_SMPR2_REGOFFSET | ((15UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) +#define ADC_CHANNEL_16_SMP (ADC_SMPR2_REGOFFSET | ((18UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) +#define ADC_CHANNEL_17_SMP (ADC_SMPR2_REGOFFSET | ((21UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) +#define ADC_CHANNEL_18_SMP (ADC_SMPR2_REGOFFSET | ((24UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) +#define ADC_CHANNEL_19_SMP (ADC_SMPR2_REGOFFSET | ((27UL) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) + + +/* Internal mask for ADC mode single or differential ended: */ +/* To select into literals LL_ADC_SINGLE_ENDED or LL_ADC_SINGLE_DIFFERENTIAL */ +/* the relevant bits for: */ +/* (concatenation of multiple bits used in different registers) */ +/* - ADC calibration: calibration start, calibration factor get or set */ +/* - ADC channels: set each ADC channel ending mode */ +#define ADC_SINGLEDIFF_CALIB_START_MASK (ADC_CR_ADCALDIF) +#define ADC_SINGLEDIFF_CALIB_FACTOR_MASK (ADC_CALFACT_CALFACT_D | ADC_CALFACT_CALFACT_S) +#define ADC_SINGLEDIFF_CHANNEL_MASK (ADC_CHANNEL_ID_BITFIELD_MASK) /* Equivalent to ADC_DIFSEL_DIFSEL */ +#define ADC_SINGLEDIFF_CHANNEL_SHIFT_MASK (ADC_CALFACT_CALFACT_S_4 | ADC_CALFACT_CALFACT_S_3) /* Bits chosen + to perform of shift when single mode is selected, shift value out of + channels bits range. */ +#define ADC_SINGLEDIFF_CALIB_F_BIT_D_MASK (0x00010000UL) /* Selection of 1 bit to discriminate differential mode: + mask of bit */ +#define ADC_SINGLEDIFF_CALIB_F_BIT_D_POS (16UL) /* Selection of 1 bit to discriminate differential mode: + position of bit */ +#define ADC_SINGLEDIFF_CALIB_F_BIT_D_SHIFT4 (ADC_SINGLEDIFF_CALIB_F_BIT_D_POS - 4UL) /* Shift of bit + ADC_SINGLEDIFF_CALIB_F_BIT_D to perform a shift of 4 ranks */ + +/* 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 series)). */ +/* - analog watchdog 1: monitored channel defined by number, */ +/* selection of ADC group (ADC groups regular and-or injected). */ +/* - analog watchdog 2 and 3: monitored channel defined by bitfield, no */ +/* selection on groups. */ + +/* Internal register offset for ADC analog watchdog channel configuration */ +#define ADC_AWD_CR1_REGOFFSET (0x00000000UL) +#define ADC_AWD_CR2_REGOFFSET (0x00100000UL) +#define ADC_AWD_CR3_REGOFFSET (0x00200000UL) + +/* Register offset gap between AWD1 and AWD2-AWD3 configuration registers */ +/* (Set separately as ADC_AWD_CRX_REGOFFSET to spare 32 bits space */ +#define ADC_AWD_CR12_REGOFFSETGAP_MASK (ADC_AWD2CR_AWD2CH_0) +#define ADC_AWD_CR12_REGOFFSETGAP_VAL (0x00000024UL) + +#define ADC_AWD_CRX_REGOFFSET_MASK (ADC_AWD_CR1_REGOFFSET | ADC_AWD_CR2_REGOFFSET | ADC_AWD_CR3_REGOFFSET) + +#define ADC_AWD_CR1_CHANNEL_MASK (ADC_CFGR_AWD1CH | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN | ADC_CFGR_AWD1SGL) +#define ADC_AWD_CR23_CHANNEL_MASK (ADC_AWD2CR_AWD2CH) +#define ADC_AWD_CR_ALL_CHANNEL_MASK (ADC_AWD_CR1_CHANNEL_MASK | ADC_AWD_CR23_CHANNEL_MASK) + +#define ADC_AWD_CRX_REGOFFSET_POS (20UL) /* Position of bits ADC_AWD_CRx_REGOFFSET + in ADC_AWD_CRX_REGOFFSET_MASK */ + +/* Internal register offset for ADC analog watchdog threshold configuration */ +#define ADC_AWD_TR1_REGOFFSET (ADC_AWD_CR1_REGOFFSET) +#define ADC_AWD_TR2_REGOFFSET (ADC_AWD_CR2_REGOFFSET) +#define ADC_AWD_TR3_REGOFFSET (ADC_AWD_CR3_REGOFFSET) +#define ADC_AWD_TRX_REGOFFSET_MASK (ADC_AWD_TR1_REGOFFSET | ADC_AWD_TR2_REGOFFSET | ADC_AWD_TR3_REGOFFSET) +#define ADC_AWD_TRX_REGOFFSET_POS (ADC_AWD_CRX_REGOFFSET_POS) /* Position of bits ADC_SQRx_REGOFFSET + in ADC_AWD_TRX_REGOFFSET_MASK */ +#define ADC_AWD_TRX_BIT_HIGH_MASK (0x00010000UL) /* Selection of 1 bit to discriminate + threshold high: mask of bit */ +#define ADC_AWD_TRX_BIT_HIGH_POS (16UL) /* Selection of 1 bit to discriminate + threshold high: position of bit */ +#define ADC_AWD_TRX_BIT_HIGH_SHIFT4 (ADC_AWD_TRX_BIT_HIGH_POS - 4UL) /* Shift of bit ADC_AWD_TRX_BIT_HIGH to + position to perform a shift of 4 ranks */ + +/* Internal mask for ADC offset: */ +/* Internal register offset for ADC offset instance configuration */ +#define ADC_OFR1_REGOFFSET (0x00000000UL) +#define ADC_OFR2_REGOFFSET (0x00000001UL) +#define ADC_OFR3_REGOFFSET (0x00000002UL) +#define ADC_OFR4_REGOFFSET (0x00000003UL) +#define ADC_OFRx_REGOFFSET_MASK (ADC_OFR1_REGOFFSET | ADC_OFR2_REGOFFSET \ + | ADC_OFR3_REGOFFSET | ADC_OFR4_REGOFFSET) + + +/* ADC registers bits positions */ +#define ADC_CFGR_RES_BITOFFSET_POS (ADC_CFGR_RES_Pos) +#define ADC_CFGR_AWD1SGL_BITOFFSET_POS (ADC_CFGR_AWD1SGL_Pos) +#define ADC_CFGR_AWD1EN_BITOFFSET_POS (ADC_CFGR_AWD1EN_Pos) +#define ADC_CFGR_JAWD1EN_BITOFFSET_POS (ADC_CFGR_JAWD1EN_Pos) +#define ADC_TR1_HT1_BITOFFSET_POS (ADC_TR1_HT1_Pos) + + +/* ADC registers bits groups */ +#define ADC_CR_BITS_PROPERTY_RS (ADC_CR_ADCAL | ADC_CR_ADEN | ADC_CR_ADDIS \ + | ADC_CR_JADSTART | ADC_CR_JADSTP \ + | ADC_CR_ADSTART | ADC_CR_ADSTP) /* ADC register CR bits with + HW property "rs": Software can read as well as set this bit. + Writing '0' has no effect on the bit value. */ + + +/* ADC internal channels related definitions */ +/* Internal voltage reference VrefInt */ +#define VREFINT_CAL_ADDR ((uint16_t*) (0x08FFF810UL)) /* 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 VrefInt has been calibrated in production + (tolerance: +-10 mV) (unit: mV). */ +/* Temperature sensor */ +#define TEMPSENSOR_CAL1_ADDR ((uint16_t*) (0x08FFF814UL)) /* Address of parameter TS_CAL1: On STM32H5, + 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*) (0x08FFF818UL)) /* Address of parameter TS_CAL2: On STM32H5, + temperature sensor ADC raw data acquired at temperature 130 DegC + (tolerance: +-5 DegC), Vref+ = 3.3 V (tolerance: +-10 mV). */ +#define TEMPSENSOR_CAL1_TEMP (30L) /* 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 (130L) /* 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+) value + with which temperature sensor has been calibrated in production + (tolerance +-10 mV) (unit: mV). */ + +/** + * @} + */ + + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup ADC_LL_Private_Macros ADC Private Macros + * @{ + */ + +/** + * @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 + @note On this STM32 series, if ADC group injected is used, some clock ratio + constraints between ADC clock and AHB clock must be respected. + Refer to reference manual. + 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 series). + * 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 series. 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 LowPowerMode; /*!< Set ADC low power mode. + This parameter can be a value of @ref ADC_LL_EC_LP_MODE + This feature can be modified afterwards using unitary function + @ref LL_ADC_SetLowPowerMode(). */ + +} 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 series. 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 peripheral (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 trigger source to external trigger also + set trigger polarity to rising edge(default setting for compatibility + with some ADC on other STM32 series having this setting set by HW + default value). + In case of need to modify trigger edge, use function + @ref LL_ADC_REG_SetTriggerEdge(). + 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 + 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(). */ + + uint32_t Overrun; /*!< Set ADC group regular behavior in case of overrun: + data preserved or overwritten. + This parameter can be a value of @ref ADC_LL_EC_REG_OVR_DATA_BEHAVIOR + This feature can be modified afterwards using unitary function + @ref LL_ADC_REG_SetOverrun(). */ + +} 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 series. 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 peripheral (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 trigger source to external trigger also + set trigger polarity to rising edge (default setting for + compatibility with some ADC on other STM32 series having this + setting set by HW default value). + In case of need to modify trigger edge, use function + @ref LL_ADC_INJ_SetTriggerEdge(). + 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 + 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_ADRDY ADC_ISR_ADRDY /*!< ADC flag ADC instance ready */ +#define LL_ADC_FLAG_EOC ADC_ISR_EOC /*!< ADC flag ADC group regular end of unitary + conversion */ +#define LL_ADC_FLAG_EOS ADC_ISR_EOS /*!< ADC flag ADC group regular end of sequence + conversions */ +#define LL_ADC_FLAG_OVR ADC_ISR_OVR /*!< ADC flag ADC group regular overrun */ +#define LL_ADC_FLAG_EOSMP ADC_ISR_EOSMP /*!< ADC flag ADC group regular end of sampling phase */ +#define LL_ADC_FLAG_JEOC ADC_ISR_JEOC /*!< ADC flag ADC group injected end of unitary + conversion */ +#define LL_ADC_FLAG_JEOS ADC_ISR_JEOS /*!< ADC flag ADC group injected end of sequence + conversions */ +#define LL_ADC_FLAG_JQOVF ADC_ISR_JQOVF /*!< ADC flag ADC group injected contexts queue + overflow */ +#define LL_ADC_FLAG_AWD1 ADC_ISR_AWD1 /*!< ADC flag ADC analog watchdog 1 */ +#define LL_ADC_FLAG_AWD2 ADC_ISR_AWD2 /*!< ADC flag ADC analog watchdog 2 */ +#define LL_ADC_FLAG_AWD3 ADC_ISR_AWD3 /*!< ADC flag ADC analog watchdog 3 */ +#if defined(ADC_MULTIMODE_SUPPORT) +#define LL_ADC_FLAG_ADRDY_MST ADC_CSR_ADRDY_MST /*!< ADC flag ADC multimode master instance ready */ +#define LL_ADC_FLAG_ADRDY_SLV ADC_CSR_ADRDY_SLV /*!< ADC flag ADC multimode slave instance ready */ +#define LL_ADC_FLAG_EOC_MST ADC_CSR_EOC_MST /*!< ADC flag ADC multimode master group regular end of + unitary conversion */ +#define LL_ADC_FLAG_EOC_SLV ADC_CSR_EOC_SLV /*!< ADC flag ADC multimode slave group regular end of + unitary conversion */ +#define LL_ADC_FLAG_EOS_MST ADC_CSR_EOS_MST /*!< ADC flag ADC multimode master group regular end of + sequence conversions */ +#define LL_ADC_FLAG_EOS_SLV ADC_CSR_EOS_SLV /*!< ADC flag ADC multimode slave group regular end of + sequence conversions */ +#define LL_ADC_FLAG_OVR_MST ADC_CSR_OVR_MST /*!< ADC flag ADC multimode master group regular + overrun */ +#define LL_ADC_FLAG_OVR_SLV ADC_CSR_OVR_SLV /*!< ADC flag ADC multimode slave group regular + overrun */ +#define LL_ADC_FLAG_EOSMP_MST ADC_CSR_EOSMP_MST /*!< ADC flag ADC multimode master group regular end of + sampling phase */ +#define LL_ADC_FLAG_EOSMP_SLV ADC_CSR_EOSMP_SLV /*!< ADC flag ADC multimode slave group regular end of + sampling phase */ +#define LL_ADC_FLAG_JEOC_MST ADC_CSR_JEOC_MST /*!< ADC flag ADC multimode master group injected end of + unitary conversion */ +#define LL_ADC_FLAG_JEOC_SLV ADC_CSR_JEOC_SLV /*!< ADC flag ADC multimode slave group injected end of + unitary conversion */ +#define LL_ADC_FLAG_JEOS_MST ADC_CSR_JEOS_MST /*!< ADC flag ADC multimode master group injected end of + sequence conversions */ +#define LL_ADC_FLAG_JEOS_SLV ADC_CSR_JEOS_SLV /*!< ADC flag ADC multimode slave group injected end of + sequence conversions */ +#define LL_ADC_FLAG_JQOVF_MST ADC_CSR_JQOVF_MST /*!< ADC flag ADC multimode master group injected + contexts queue overflow */ +#define LL_ADC_FLAG_JQOVF_SLV ADC_CSR_JQOVF_SLV /*!< ADC flag ADC multimode slave group injected + contexts queue overflow */ +#define LL_ADC_FLAG_AWD1_MST ADC_CSR_AWD1_MST /*!< ADC flag ADC multimode master analog watchdog 1 + of the ADC master */ +#define LL_ADC_FLAG_AWD1_SLV ADC_CSR_AWD1_SLV /*!< ADC flag ADC multimode slave analog watchdog 1 + of the ADC slave */ +#define LL_ADC_FLAG_AWD2_MST ADC_CSR_AWD2_MST /*!< ADC flag ADC multimode master analog watchdog 2 + of the ADC master */ +#define LL_ADC_FLAG_AWD2_SLV ADC_CSR_AWD2_SLV /*!< ADC flag ADC multimode slave analog watchdog 2 + of the ADC slave */ +#define LL_ADC_FLAG_AWD3_MST ADC_CSR_AWD3_MST /*!< ADC flag ADC multimode master analog watchdog 3 + of the ADC master */ +#define LL_ADC_FLAG_AWD3_SLV ADC_CSR_AWD3_SLV /*!< ADC flag ADC multimode slave analog watchdog 3 + of the ADC slave */ +#endif /* ADC_MULTIMODE_SUPPORT */ +/** + * @} + */ + +/** @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_ADRDY ADC_IER_ADRDYIE /*!< ADC interruption ADC instance ready */ +#define LL_ADC_IT_EOC ADC_IER_EOCIE /*!< ADC interruption ADC group regular end of unitary + conversion */ +#define LL_ADC_IT_EOS ADC_IER_EOSIE /*!< ADC interruption ADC group regular end of sequence + conversions */ +#define LL_ADC_IT_OVR ADC_IER_OVRIE /*!< ADC interruption ADC group regular overrun */ +#define LL_ADC_IT_EOSMP ADC_IER_EOSMPIE /*!< ADC interruption ADC group regular end of sampling + phase */ +#define LL_ADC_IT_JEOC ADC_IER_JEOCIE /*!< ADC interruption ADC group injected end of unitary + conversion */ +#define LL_ADC_IT_JEOS ADC_IER_JEOSIE /*!< ADC interruption ADC group injected end of sequence + conversions */ +#define LL_ADC_IT_JQOVF ADC_IER_JQOVFIE /*!< ADC interruption ADC group injected contexts queue + overflow */ +#define LL_ADC_IT_AWD1 ADC_IER_AWD1IE /*!< ADC interruption ADC analog watchdog 1 */ +#define LL_ADC_IT_AWD2 ADC_IER_AWD2IE /*!< ADC interruption ADC analog watchdog 2 */ +#define LL_ADC_IT_AWD3 ADC_IER_AWD3IE /*!< ADC interruption ADC analog watchdog 3 */ +/** + * @} + */ + +/** @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 /* ADC_MULTIMODE_SUPPORT */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_COMMON_CLOCK_SOURCE ADC common - Clock source + * @{ + */ +#define LL_ADC_CLOCK_SYNC_PCLK_DIV1 (ADC_CCR_CKMODE_0) /*!< ADC synchronous clock derived from + AHB clock without prescaler */ +#define LL_ADC_CLOCK_SYNC_PCLK_DIV2 (ADC_CCR_CKMODE_1) /*!< ADC synchronous clock derived from + AHB clock with prescaler division by 2 */ +#define LL_ADC_CLOCK_SYNC_PCLK_DIV4 (ADC_CCR_CKMODE_1 | ADC_CCR_CKMODE_0) /*!< ADC synchronous clock derived from + AHB clock with prescaler division by 4 */ +#define LL_ADC_CLOCK_ASYNC_DIV1 (0x00000000UL) /*!< ADC asynchronous clock without + prescaler */ +#define LL_ADC_CLOCK_ASYNC_DIV2 (ADC_CCR_PRESC_0) /*!< ADC asynchronous clock with + prescaler division by 2 */ +#define LL_ADC_CLOCK_ASYNC_DIV4 (ADC_CCR_PRESC_1) /*!< ADC asynchronous clock with + prescaler division by 4 */ +#define LL_ADC_CLOCK_ASYNC_DIV6 (ADC_CCR_PRESC_1 | ADC_CCR_PRESC_0) /*!< ADC asynchronous clock with + prescaler division by 6 */ +#define LL_ADC_CLOCK_ASYNC_DIV8 (ADC_CCR_PRESC_2) /*!< ADC asynchronous clock with + prescaler division by 8 */ +#define LL_ADC_CLOCK_ASYNC_DIV10 (ADC_CCR_PRESC_2 | ADC_CCR_PRESC_0) /*!< ADC asynchronous clock with + prescaler division by 10 */ +#define LL_ADC_CLOCK_ASYNC_DIV12 (ADC_CCR_PRESC_2 | ADC_CCR_PRESC_1) /*!< ADC asynchronous clock with + prescaler division by 12 */ +#define LL_ADC_CLOCK_ASYNC_DIV16 (ADC_CCR_PRESC_2 | ADC_CCR_PRESC_1 \ + | ADC_CCR_PRESC_0) /*!< ADC asynchronous clock with + prescaler division by 16 */ +#define LL_ADC_CLOCK_ASYNC_DIV32 (ADC_CCR_PRESC_3) /*!< ADC asynchronous clock with + prescaler division by 32 */ +#define LL_ADC_CLOCK_ASYNC_DIV64 (ADC_CCR_PRESC_3 | ADC_CCR_PRESC_0) /*!< ADC asynchronous clock with + prescaler division by 64 */ +#define LL_ADC_CLOCK_ASYNC_DIV128 (ADC_CCR_PRESC_3 | ADC_CCR_PRESC_1) /*!< ADC asynchronous clock with + prescaler division by 128 */ +#define LL_ADC_CLOCK_ASYNC_DIV256 (ADC_CCR_PRESC_3 | ADC_CCR_PRESC_1 \ + | ADC_CCR_PRESC_0) /*!< ADC asynchronous clock with + prescaler division by 256 */ +/** + * @} + */ + +/** @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_VREFEN) /*!< ADC measurement path to internal channel VrefInt */ +#define LL_ADC_PATH_INTERNAL_TEMPSENSOR (ADC_CCR_TSEN) /*!< ADC measurement path to internal channel + temperature sensor */ +#define LL_ADC_PATH_INTERNAL_VBAT (ADC_CCR_VBATEN) /*!< 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_CFGR_RES_0) /*!< ADC resolution 10 bits */ +#define LL_ADC_RESOLUTION_8B (ADC_CFGR_RES_1 ) /*!< ADC resolution 8 bits */ +#define LL_ADC_RESOLUTION_6B (ADC_CFGR_RES_1 | ADC_CFGR_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_CFGR_ALIGN) /*!< ADC conversion data alignment: left aligned + (alignment on data register MSB bit 15)*/ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_LP_MODE ADC instance - Low power mode + * @{ + */ +#define LL_ADC_LP_MODE_NONE (0x00000000UL) /*!< No ADC low power mode activated */ +#define LL_ADC_LP_AUTOWAIT (ADC_CFGR_AUTDLY) /*!< ADC low power mode auto delay: Dynamic low power + mode, ADC conversions are performed only when necessary + (when previous ADC conversion data is read). + See description with function @ref LL_ADC_SetLowPowerMode(). */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_OFFSET_NB ADC instance - Offset instance + * @{ + */ +#define LL_ADC_OFFSET_1 ADC_OFR1_REGOFFSET /*!< ADC offset instance 1: ADC channel and offset level + to which the offset programmed will be applied (independently of channel + mapped on ADC group regular or injected) */ +#define LL_ADC_OFFSET_2 ADC_OFR2_REGOFFSET /*!< ADC offset instance 2: ADC channel and offset level + to which the offset programmed will be applied (independently of channel + mapped on ADC group regular or injected) */ +#define LL_ADC_OFFSET_3 ADC_OFR3_REGOFFSET /*!< ADC offset instance 3: ADC channel and offset level + to which the offset programmed will be applied (independently of channel + mapped on ADC group regular or injected) */ +#define LL_ADC_OFFSET_4 ADC_OFR4_REGOFFSET /*!< ADC offset instance 4: ADC channel and offset level + to which the offset programmed will be applied (independently of channel + mapped on ADC group regular or injected) */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_OFFSET_STATE ADC instance - Offset state + * @{ + */ +#define LL_ADC_OFFSET_DISABLE (0x00000000UL) /*!< ADC offset disabled + (setting offset instance wise) */ +#define LL_ADC_OFFSET_ENABLE (ADC_OFR1_OFFSET1_EN) /*!< ADC offset enabled + (setting offset instance wise) */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_OFFSET_SIGN ADC instance - Offset sign + * @{ + */ +#define LL_ADC_OFFSET_SIGN_NEGATIVE (0x00000000UL) /*!< ADC offset is negative */ +#define LL_ADC_OFFSET_SIGN_POSITIVE (ADC_OFR1_OFFSETPOS) /*!< ADC offset is positive */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_OFFSET_SATURATION ADC instance - Offset saturation mode + * @{ + */ +#define LL_ADC_OFFSET_SATURATION_DISABLE (0x00000000UL) /*!< ADC offset saturation is disabled (among ADC + selected offset instance 1, 2, 3 or 4) */ +#define LL_ADC_OFFSET_SATURATION_ENABLE (ADC_OFR1_SATEN) /*!< ADC offset saturation is enabled (among ADC + selected offset instance 1, 2, 3 or 4) */ +/** + * @} + */ +/** @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_CHANNEL_0_BITFIELD) /*!< ADC channel ADCx_IN0 */ +#define LL_ADC_CHANNEL_1 (ADC_CHANNEL_1_NUMBER | ADC_CHANNEL_1_SMP \ + | ADC_CHANNEL_1_BITFIELD) /*!< ADC channel ADCx_IN1 */ +#define LL_ADC_CHANNEL_2 (ADC_CHANNEL_2_NUMBER | ADC_CHANNEL_2_SMP \ + | ADC_CHANNEL_2_BITFIELD) /*!< ADC channel ADCx_IN2 */ +#define LL_ADC_CHANNEL_3 (ADC_CHANNEL_3_NUMBER | ADC_CHANNEL_3_SMP \ + | ADC_CHANNEL_3_BITFIELD) /*!< ADC channel ADCx_IN3 */ +#define LL_ADC_CHANNEL_4 (ADC_CHANNEL_4_NUMBER | ADC_CHANNEL_4_SMP \ + | ADC_CHANNEL_4_BITFIELD) /*!< ADC channel ADCx_IN4 */ +#define LL_ADC_CHANNEL_5 (ADC_CHANNEL_5_NUMBER | ADC_CHANNEL_5_SMP \ + | ADC_CHANNEL_5_BITFIELD) /*!< ADC channel ADCx_IN5 */ +#define LL_ADC_CHANNEL_6 (ADC_CHANNEL_6_NUMBER | ADC_CHANNEL_6_SMP \ + | ADC_CHANNEL_6_BITFIELD) /*!< ADC channel ADCx_IN6 */ +#define LL_ADC_CHANNEL_7 (ADC_CHANNEL_7_NUMBER | ADC_CHANNEL_7_SMP \ + | ADC_CHANNEL_7_BITFIELD) /*!< ADC channel ADCx_IN7 */ +#define LL_ADC_CHANNEL_8 (ADC_CHANNEL_8_NUMBER | ADC_CHANNEL_8_SMP \ + | ADC_CHANNEL_8_BITFIELD) /*!< ADC channel ADCx_IN8 */ +#define LL_ADC_CHANNEL_9 (ADC_CHANNEL_9_NUMBER | ADC_CHANNEL_9_SMP \ + | ADC_CHANNEL_9_BITFIELD) /*!< ADC channel ADCx_IN9 */ +#define LL_ADC_CHANNEL_10 (ADC_CHANNEL_10_NUMBER | ADC_CHANNEL_10_SMP \ + | ADC_CHANNEL_10_BITFIELD) /*!< ADC channel ADCx_IN10 */ +#define LL_ADC_CHANNEL_11 (ADC_CHANNEL_11_NUMBER | ADC_CHANNEL_11_SMP \ + | ADC_CHANNEL_11_BITFIELD) /*!< ADC channel ADCx_IN11 */ +#define LL_ADC_CHANNEL_12 (ADC_CHANNEL_12_NUMBER | ADC_CHANNEL_12_SMP \ + | ADC_CHANNEL_12_BITFIELD) /*!< ADC channel ADCx_IN12 */ +#define LL_ADC_CHANNEL_13 (ADC_CHANNEL_13_NUMBER | ADC_CHANNEL_13_SMP \ + | ADC_CHANNEL_13_BITFIELD) /*!< ADC channel ADCx_IN13 */ +#define LL_ADC_CHANNEL_14 (ADC_CHANNEL_14_NUMBER | ADC_CHANNEL_14_SMP \ + | ADC_CHANNEL_14_BITFIELD) /*!< ADC channel ADCx_IN14 */ +#define LL_ADC_CHANNEL_15 (ADC_CHANNEL_15_NUMBER | ADC_CHANNEL_15_SMP \ + | ADC_CHANNEL_15_BITFIELD) /*!< ADC channel ADCx_IN15 */ +#define LL_ADC_CHANNEL_16 (ADC_CHANNEL_16_NUMBER | ADC_CHANNEL_16_SMP \ + | ADC_CHANNEL_16_BITFIELD) /*!< ADC channel ADCx_IN16 */ +#define LL_ADC_CHANNEL_17 (ADC_CHANNEL_17_NUMBER | ADC_CHANNEL_17_SMP \ + | ADC_CHANNEL_17_BITFIELD) /*!< ADC channel ADCx_IN17 */ +#define LL_ADC_CHANNEL_18 (ADC_CHANNEL_18_NUMBER | ADC_CHANNEL_18_SMP \ + | ADC_CHANNEL_18_BITFIELD) /*!< ADC channel ADCx_IN18 */ +#define LL_ADC_CHANNEL_19 (ADC_CHANNEL_19_NUMBER | ADC_CHANNEL_19_SMP \ + | ADC_CHANNEL_19_BITFIELD) /*!< ADC channel ADCx_IN19 */ +#if defined (ADC2) +#define LL_ADC_CHANNEL_VREFINT (LL_ADC_CHANNEL_17 | ADC_CHANNEL_ID_INTERNAL_CH) /*!< ADC internal channel + connected to VrefInt: Internal voltage reference. + On STM32H563xx/573xx, ADC channel available only on ADC instance: ADC1. */ +#define LL_ADC_CHANNEL_TEMPSENSOR (LL_ADC_CHANNEL_16 | ADC_CHANNEL_ID_INTERNAL_CH) /*!< ADC internal channel + connected to internal temperature sensor. + On STM32H563xx/573xx, ADC channel available only on ADC instance: ADC1. */ +#define LL_ADC_CHANNEL_VBAT (LL_ADC_CHANNEL_16 | ADC_CHANNEL_ID_INTERNAL_CH_2) /*!< ADC internal channel + connected to Vbat/4: Vbat voltage through a divider ladder of factor 1/4 + to have channel voltage always below Vdda. + On STM32H563xx/573xx, ADC channel available only on ADC instance: ADC2. */ +#define LL_ADC_CHANNEL_VDDCORE (LL_ADC_CHANNEL_17 | ADC_CHANNEL_ID_INTERNAL_CH_2) /*!< ADC internal channel + connected to Vddcore. + On STM32H563xx/573xx, ADC channel available only on ADC instance: ADC2. */ +#else +#define LL_ADC_CHANNEL_VREFINT (LL_ADC_CHANNEL_17 | ADC_CHANNEL_ID_INTERNAL_CH) /*!< ADC internal channel + connected to VrefInt: Internal voltage reference. */ +#define LL_ADC_CHANNEL_TEMPSENSOR (LL_ADC_CHANNEL_16 | ADC_CHANNEL_ID_INTERNAL_CH) /*!< ADC internal channel + connected to internal temperature sensor.*/ +#define LL_ADC_CHANNEL_VBAT (LL_ADC_CHANNEL_2 | ADC_CHANNEL_ID_INTERNAL_CH) /*!< ADC internal channel + connected to Vbat/4: Vbat voltage through a divider ladder of factor 1/4 + to have channel voltage always below Vdda. */ +#define LL_ADC_CHANNEL_VDDCORE (LL_ADC_CHANNEL_6 | ADC_CHANNEL_ID_INTERNAL_CH) /*!< ADC internal channel + connected to Vddcore.*/ +#endif /* ADC2 */ + +/* Definitions for backward compatibility with legacy STM32 series */ +#define LL_ADC_CHANNEL_VCORE LL_ADC_CHANNEL_VDDCORE +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REG_TRIGGER_SOURCE ADC group regular - Trigger source + * @{ + */ +/* Triggers common to all devices of STM32H5 series */ +#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 peripheral: 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_CFGR_EXTSEL_0 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular + conversion trigger from external peripheral: 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_CFGR_EXTSEL_1 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular + conversion trigger from external peripheral: 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_CFGR_EXTSEL_1 | ADC_CFGR_EXTSEL_0 \ + | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular + conversion trigger from external peripheral: 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_TIM3_TRGO (ADC_CFGR_EXTSEL_2 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular + conversion trigger from external peripheral: TIM3 TRGO event. + Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_EXTI_LINE11 (ADC_CFGR_EXTSEL_2 | ADC_CFGR_EXTSEL_1 \ + | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular + conversion trigger from external peripheral: external interrupt line 11 + event. Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM1_TRGO (ADC_CFGR_EXTSEL_3 | ADC_CFGR_EXTSEL_0 \ + | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular + conversion trigger from external peripheral: TIM1 TRGO event. + Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM1_TRGO2 (ADC_CFGR_EXTSEL_3 | ADC_CFGR_EXTSEL_1 \ + | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular + conversion trigger from external peripheral: TIM1 TRGO2 event. + Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM2_TRGO (ADC_CFGR_EXTSEL_3 | ADC_CFGR_EXTSEL_1 \ + | ADC_CFGR_EXTSEL_0 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular + conversion trigger from external peripheral: TIM2 TRGO event. + Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM6_TRGO (ADC_CFGR_EXTSEL_3 | ADC_CFGR_EXTSEL_2 \ + | ADC_CFGR_EXTSEL_0 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular + conversion trigger from external peripheral: TIM6 TRGO event. + Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM3_CH4 (ADC_CFGR_EXTSEL_3 | ADC_CFGR_EXTSEL_2 \ + | ADC_CFGR_EXTSEL_1 | ADC_CFGR_EXTSEL_0 \ + | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular + conversion trigger from external peripheral: TIM3 channel 4 event + (capture compare: input capture or output capture). + Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_EXTI_LINE15 (ADC_CFGR_EXTSEL_4 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular + conversion trigger from external peripheral: LPTIM1 OUT event. + Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_LPTIM1_CH1 (ADC_CFGR_EXTSEL_4 | ADC_CFGR_EXTSEL_1 \ + | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular + conversion trigger from external peripheral: LPTIM2 OUT event. + Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_LPTIM2_CH1 (ADC_CFGR_EXTSEL_4 | ADC_CFGR_EXTSEL_1 \ + | ADC_CFGR_EXTSEL_0 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular + conversion trigger from external peripheral: LPTIM3 event OUT. + Trigger edge set to rising edge (default setting). */ + +/* Triggers specific to some devices of STM32H5 series */ +#if defined(TIM8) +/* Devices STM32H563/H573xx */ +#define LL_ADC_REG_TRIG_EXT_TIM4_CH4 (ADC_CFGR_EXTSEL_2 | ADC_CFGR_EXTSEL_0 \ + | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular + conversion trigger from external peripheral: TIM4 channel 4 event + (capture compare: input capture or output capture). + Trigger edge set to rising edge (default setting). + Specific to devices: STM32H563/H573xx. */ +#define LL_ADC_REG_TRIG_EXT_TIM8_TRGO (ADC_CFGR_EXTSEL_2 | ADC_CFGR_EXTSEL_1 \ + | ADC_CFGR_EXTSEL_0 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular + conversion trigger from external peripheral: TIM12 TRGO event. + Trigger edge set to rising edge (default setting). + Specific to devices: STM32H563/H573xx. */ +#define LL_ADC_REG_TRIG_EXT_TIM8_TRGO2 (ADC_CFGR_EXTSEL_3 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular + conversion trigger from external peripheral: TIM8 TRGO event. + Trigger edge set to rising edge (default setting). + Specific to devices: STM32H563/H573xx. */ +#define LL_ADC_REG_TRIG_EXT_TIM4_TRGO (ADC_CFGR_EXTSEL_3 | ADC_CFGR_EXTSEL_2 \ + | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular + conversion trigger from external peripheral: TIM4 TRGO event. + Trigger edge set to rising edge (default setting). + Specific to devices: STM32H563/H573xx. */ +#define LL_ADC_REG_TRIG_EXT_TIM15_TRGO (ADC_CFGR_EXTSEL_3 | ADC_CFGR_EXTSEL_2 \ + | ADC_CFGR_EXTSEL_1 | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular + conversion trigger from external peripheral: TIM15 TRGO event. + Trigger edge set to rising edge (default setting). + Specific to devices: STM32H563/H573xx. */ +#else +/* Devices STM32H503xx */ +#define LL_ADC_REG_TRIG_EXT_TIM7_TRGO (ADC_CFGR_EXTSEL_4 | ADC_CFGR_EXTSEL_0 \ + | ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular + conversion trigger from external peripheral: TIM7 TRGO event. + Trigger edge set to rising edge (default setting). + Specific to devices: STM32H503xx. */ +#endif /* Devices STM32H563/H573xx or STM32H503xx */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REG_TRIGGER_EDGE ADC group regular - Trigger edge + * @{ + */ +#define LL_ADC_REG_TRIG_EXT_RISING (ADC_CFGR_EXTEN_0) /*!< ADC group regular conversion + trigger polarity set to rising edge */ +#define LL_ADC_REG_TRIG_EXT_FALLING (ADC_CFGR_EXTEN_1) /*!< ADC group regular conversion + trigger polarity set to falling edge */ +#define LL_ADC_REG_TRIG_EXT_RISINGFALLING (ADC_CFGR_EXTEN_1 | ADC_CFGR_EXTEN_0) /*!< ADC group regular conversion + trigger polarity set to both rising and falling edges */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REG_SAMPLING_MODE ADC group regular - Sampling mode + * @{ + */ +#define LL_ADC_REG_SAMPLING_MODE_NORMAL (0x00000000UL) /*!< ADC conversions sampling phase duration + is defined using @ref ADC_LL_EC_CHANNEL_SAMPLINGTIME */ +#define LL_ADC_REG_SAMPLING_MODE_BULB (ADC_CFGR2_BULB) /*!< ADC conversions sampling phase starts + immediately after end of conversion, and stops upon trigger event. + Note: First conversion is using minimal sampling time + (see @ref ADC_LL_EC_CHANNEL_SAMPLINGTIME) */ +#define LL_ADC_REG_SAMPLING_MODE_TRIGGER_CONTROLED (ADC_CFGR2_SMPTRIG) /*!< ADC conversions sampling phase is + controlled by trigger events: trigger rising edge for start sampling, + trigger falling edge for stop sampling and start conversion */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REG_CONTINUOUS_MODE ADC group regular - Continuous mode + * @{ + */ +#define LL_ADC_REG_CONV_SINGLE (0x00000000UL) /*!< ADC conversions performed in single mode: + one conversion per trigger */ +#define LL_ADC_REG_CONV_CONTINUOUS (ADC_CFGR_CONT) /*!< ADC conversions 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_CFGR_DMAEN) /*!< 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_CFGR_DMACFG | ADC_CFGR_DMAEN) /*!< 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. */ +/** + * @} + */ + +#if defined(ADC_SMPR1_SMPPLUS) +/** @defgroup ADC_LL_EC_SAMPLINGTIME_COMMON_CONFIG ADC instance - ADC sampling time common configuration + * @{ + */ +#define LL_ADC_SAMPLINGTIME_COMMON_DEFAULT (0x00000000UL) /*!< ADC sampling time let to default settings. */ +#define LL_ADC_SAMPLINGTIME_COMMON_3C5_REPL_2C5 (ADC_SMPR1_SMPPLUS) /*!< ADC additional sampling time 3.5 ADC clock + cycles replacing 2.5 ADC clock cycles (this applies to all channels mapped + with selection sampling time 2.5 ADC clock cycles, whatever channels mapped + on ADC groups regular or injected). */ +/** + * @} + */ +#endif /* ADC_SMPR1_SMPPLUS */ + +/** @defgroup ADC_LL_EC_REG_OVR_DATA_BEHAVIOR ADC group regular - Overrun behavior on conversion data + * @{ + */ +#define LL_ADC_REG_OVR_DATA_PRESERVED (0x00000000UL) /*!< ADC group regular behavior in case of overrun: + data preserved */ +#define LL_ADC_REG_OVR_DATA_OVERWRITTEN (ADC_CFGR_OVRMOD) /*!< ADC group regular behavior in case of overrun: + data overwritten */ +/** + * @} + */ + +/** @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 sequencerenable + 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_CFGR_DISCEN) /*!< ADC group regular sequencer + discontinuous mode enable with sequence interruption every rank */ +#define LL_ADC_REG_SEQ_DISCONT_2RANKS (ADC_CFGR_DISCNUM_0 | ADC_CFGR_DISCEN) /*!< ADC group regular sequencer + discontinuous mode enabled with sequence interruption every 2 ranks */ +#define LL_ADC_REG_SEQ_DISCONT_3RANKS (ADC_CFGR_DISCNUM_1 | ADC_CFGR_DISCEN) /*!< ADC group regular sequencer + discontinuous mode enable with sequence interruption every 3 ranks */ +#define LL_ADC_REG_SEQ_DISCONT_4RANKS (ADC_CFGR_DISCNUM_1 | ADC_CFGR_DISCNUM_0 \ + | ADC_CFGR_DISCEN) /*!< ADC group regular sequencer + discontinuous mode enable with sequence interruption every 4 ranks */ +#define LL_ADC_REG_SEQ_DISCONT_5RANKS (ADC_CFGR_DISCNUM_2 | ADC_CFGR_DISCEN) /*!< ADC group regular sequencer + discontinuous mode enable with sequence interruption every 5 ranks */ +#define LL_ADC_REG_SEQ_DISCONT_6RANKS (ADC_CFGR_DISCNUM_2 | ADC_CFGR_DISCNUM_0 \ + | ADC_CFGR_DISCEN) /*!< ADC group regular sequencer + discontinuous mode enable with sequence interruption every 6 ranks */ +#define LL_ADC_REG_SEQ_DISCONT_7RANKS (ADC_CFGR_DISCNUM_2 | ADC_CFGR_DISCNUM_1 \ + | ADC_CFGR_DISCEN) /*!< ADC group regular sequencer + discontinuous mode enable with sequence interruption every 7 ranks */ +#define LL_ADC_REG_SEQ_DISCONT_8RANKS (ADC_CFGR_DISCNUM_2 | ADC_CFGR_DISCNUM_1 \ + | ADC_CFGR_DISCNUM_0 | ADC_CFGR_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_SQR1_REGOFFSET | ADC_REG_RANK_1_SQRX_BITOFFSET_POS) /*!< ADC group + regular sequencer rank 1 */ +#define LL_ADC_REG_RANK_2 (ADC_SQR1_REGOFFSET | ADC_REG_RANK_2_SQRX_BITOFFSET_POS) /*!< ADC group + regular sequencer rank 2 */ +#define LL_ADC_REG_RANK_3 (ADC_SQR1_REGOFFSET | ADC_REG_RANK_3_SQRX_BITOFFSET_POS) /*!< ADC group + regular sequencer rank 3 */ +#define LL_ADC_REG_RANK_4 (ADC_SQR1_REGOFFSET | ADC_REG_RANK_4_SQRX_BITOFFSET_POS) /*!< ADC group + regular sequencer rank 4 */ +#define LL_ADC_REG_RANK_5 (ADC_SQR2_REGOFFSET | ADC_REG_RANK_5_SQRX_BITOFFSET_POS) /*!< ADC group + regular sequencer rank 5 */ +#define LL_ADC_REG_RANK_6 (ADC_SQR2_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_SQR3_REGOFFSET | ADC_REG_RANK_10_SQRX_BITOFFSET_POS) /*!< ADC group + regular sequencer rank 10 */ +#define LL_ADC_REG_RANK_11 (ADC_SQR3_REGOFFSET | ADC_REG_RANK_11_SQRX_BITOFFSET_POS) /*!< ADC group + regular sequencer rank 11 */ +#define LL_ADC_REG_RANK_12 (ADC_SQR3_REGOFFSET | ADC_REG_RANK_12_SQRX_BITOFFSET_POS) /*!< ADC group + regular sequencer rank 12 */ +#define LL_ADC_REG_RANK_13 (ADC_SQR3_REGOFFSET | ADC_REG_RANK_13_SQRX_BITOFFSET_POS) /*!< ADC group + regular sequencer rank 13 */ +#define LL_ADC_REG_RANK_14 (ADC_SQR3_REGOFFSET | ADC_REG_RANK_14_SQRX_BITOFFSET_POS) /*!< ADC group + regular sequencer rank 14 */ +#define LL_ADC_REG_RANK_15 (ADC_SQR4_REGOFFSET | ADC_REG_RANK_15_SQRX_BITOFFSET_POS) /*!< ADC group + regular sequencer rank 15 */ +#define LL_ADC_REG_RANK_16 (ADC_SQR4_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 + * @{ + */ +/* Triggers common to all devices of STM32H5 series */ +#define LL_ADC_INJ_TRIG_SOFTWARE (0x00000000UL) /*!< ADC group injected + conversion trigger internal: SW start. */ +#define LL_ADC_INJ_TRIG_EXT_TIM1_TRGO (ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected + conversion trigger from external peripheral: TIM1 TRGO event. Trigger edge + set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM1_CH4 (ADC_JSQR_JEXTSEL_0 | ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected + conversion trigger from external peripheral: 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_TIM2_TRGO (ADC_JSQR_JEXTSEL_1 | ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected + conversion trigger from external peripheral: TIM2 TRGO event. Trigger edge + set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM2_CH1 (ADC_JSQR_JEXTSEL_1 | ADC_JSQR_JEXTSEL_0 \ + | ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected + conversion trigger from external peripheral: 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_TIM3_CH4 (ADC_JSQR_JEXTSEL_2 | ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected + conversion trigger from external peripheral: 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_EXTI_LINE15 (ADC_JSQR_JEXTSEL_2 | ADC_JSQR_JEXTSEL_1 \ + | ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected + conversion trigger from external peripheral: external interrupt line 15. + Trigger edge set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM1_TRGO2 (ADC_JSQR_JEXTSEL_3 | ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected + conversion trigger from external peripheral: TIM1 TRGO2 event. Trigger edge + set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM3_CH3 (ADC_JSQR_JEXTSEL_3 | ADC_JSQR_JEXTSEL_1 \ + | ADC_JSQR_JEXTSEL_0 | ADC_INJ_TRIG_EXT_EDGE_DEFAULT)/*!< ADC group injected + conversion trigger from external peripheral: TIM3 channel 3 event (capture + compare: input capture or output capture). Trigger edge set to rising edge + (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM3_TRGO (ADC_JSQR_JEXTSEL_3 | ADC_JSQR_JEXTSEL_2 \ + | ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected + conversion trigger from external peripheral: TIM3 TRGO event. Trigger edge + set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM3_CH1 (ADC_JSQR_JEXTSEL_3 | ADC_JSQR_JEXTSEL_2 \ + | ADC_JSQR_JEXTSEL_0 | ADC_INJ_TRIG_EXT_EDGE_DEFAULT)/*!< ADC group injected + conversion trigger from external peripheral: TIM3 channel 1 event (capture + compare: input capture or output capture). Trigger edge set to rising edge + (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM6_TRGO (ADC_JSQR_JEXTSEL_3 | ADC_JSQR_JEXTSEL_2 \ + | ADC_JSQR_JEXTSEL_1 | ADC_INJ_TRIG_EXT_EDGE_DEFAULT)/*!< ADC group injected + conversion trigger from external peripheral: TIM6 TRGO event. Trigger edge + set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_LPTIM1_CH1 (ADC_JSQR_JEXTSEL_4 | ADC_JSQR_JEXTSEL_1 \ + | ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected + conversion trigger from external peripheral: LPTIM1 channel 1 event. Trigger + edge set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_LPTIM2_CH1 (ADC_JSQR_JEXTSEL_4 | ADC_JSQR_JEXTSEL_1 \ + | ADC_JSQR_JEXTSEL_0 | ADC_INJ_TRIG_EXT_EDGE_DEFAULT)/*!< ADC group injected + conversion trigger from external peripheral: LPTIM2 channel 1 event. Trigger + edge set to rising edge (default setting). */ + +/* Triggers specific to some devices of STM32H5 series */ +#if defined(TIM8) +/* Devices STM32H563/H573xx */ +#define LL_ADC_INJ_TRIG_EXT_TIM4_TRGO (ADC_JSQR_JEXTSEL_2 | ADC_JSQR_JEXTSEL_0 \ + | ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected + conversion trigger from external peripheral: TIM4 TRGO event. Trigger edge + set to rising edge (default setting). + Specific to devices: STM32H563/H573xx. */ +#define LL_ADC_INJ_TRIG_EXT_TIM8_CH4 (ADC_JSQR_JEXTSEL_2 | ADC_JSQR_JEXTSEL_1 \ + | ADC_JSQR_JEXTSEL_0 | ADC_INJ_TRIG_EXT_EDGE_DEFAULT)/*!< ADC group injected + conversion trigger from external peripheral: TIM9 channel 1 event (capture + compare: input capture or output capture). Trigger edge set to rising edge + (default setting). + Specific to devices: STM32H563/H573xx. */ +#define LL_ADC_INJ_TRIG_EXT_TIM8_TRGO (ADC_JSQR_JEXTSEL_3 | ADC_JSQR_JEXTSEL_0 \ + | ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected + conversion trigger from external peripheral: TIM12 TRGO event. Trigger edge + set to rising edge (default setting). + Specific to devices: STM32H563/H573xx. */ +#define LL_ADC_INJ_TRIG_EXT_TIM8_TRGO2 (ADC_JSQR_JEXTSEL_3 | ADC_JSQR_JEXTSEL_1 \ + | ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected + conversion trigger from external peripheral: TIM9 TRGO event. Trigger edge + set to rising edge (default setting). + Specific to devices: STM32H563/H573xx. */ +#define LL_ADC_INJ_TRIG_EXT_TIM15_TRGO (ADC_JSQR_JEXTSEL_3 | ADC_JSQR_JEXTSEL_2 \ + | ADC_JSQR_JEXTSEL_1 | ADC_JSQR_JEXTSEL_0 \ + | ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected + conversion trigger from external peripheral: TIM15 TRGO event. Trigger edge + set to rising edge (default setting). */ +#else +/* Devices STM32H503xx */ +#define LL_ADC_INJ_TRIG_EXT_TIM7_TRGO (ADC_JSQR_JEXTSEL_4 | ADC_JSQR_JEXTSEL_0 \ + | ADC_INJ_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group injected + conversion trigger from external peripheral: TIM7 TRGO event. Trigger edge + set to rising edge (default setting). */ +#endif /* Devices STM32H563/H573xx or STM32H503xx */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_INJ_TRIGGER_EDGE ADC group injected - Trigger edge + * @{ + */ +#define LL_ADC_INJ_TRIG_EXT_RISING ( ADC_JSQR_JEXTEN_0) /*!< ADC group injected conversion + trigger polarity set to rising edge */ +#define LL_ADC_INJ_TRIG_EXT_FALLING (ADC_JSQR_JEXTEN_1 ) /*!< ADC group injected conversion + trigger polarity set to falling edge */ +#define LL_ADC_INJ_TRIG_EXT_RISINGFALLING (ADC_JSQR_JEXTEN_1 | ADC_JSQR_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_CFGR_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_CONTEXT_QUEUE ADC group injected - Context queue mode + * @{ + */ +#define LL_ADC_INJ_QUEUE_2CONTEXTS_LAST_ACTIVE (0x00000000UL) /* Group injected sequence context queue is enabled + and can contain up to 2 contexts. When all contexts have been processed, + the queue maintains the last context active perpetually. */ +#define LL_ADC_INJ_QUEUE_2CONTEXTS_END_EMPTY (ADC_CFGR_JQM) /* Group injected sequence context queue is enabled + and can contain up to 2 contexts. When all contexts have been processed, + the queue is empty and injected group triggers are disabled. */ +#define LL_ADC_INJ_QUEUE_DISABLE (ADC_CFGR_JQDIS) /* Group injected sequence context queue is disabled: + only 1 sequence can be configured and is active perpetually. */ +/** + * @} + */ + +/** @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_CFGR_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_INJ_RANK_1_JSQR_BITOFFSET_POS) /*!< ADC group inj. sequencer rank 1 */ +#define LL_ADC_INJ_RANK_2 (ADC_JDR2_REGOFFSET \ + | ADC_INJ_RANK_2_JSQR_BITOFFSET_POS) /*!< ADC group inj. sequencer rank 2 */ +#define LL_ADC_INJ_RANK_3 (ADC_JDR3_REGOFFSET \ + | ADC_INJ_RANK_3_JSQR_BITOFFSET_POS) /*!< ADC group inj. sequencer rank 3 */ +#define LL_ADC_INJ_RANK_4 (ADC_JDR4_REGOFFSET \ + | ADC_INJ_RANK_4_JSQR_BITOFFSET_POS) /*!< ADC group inj. sequencer rank 4 */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_CHANNEL_SAMPLINGTIME Channel - Sampling time + * @{ + */ +#define LL_ADC_SAMPLINGTIME_2CYCLES_5 (0x00000000UL) /*!< Sampling time 2.5 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_6CYCLES_5 (ADC_SMPR2_SMP10_0) /*!< Sampling time 6.5 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_12CYCLES_5 (ADC_SMPR2_SMP10_1) /*!< Sampling time 12.5 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_24CYCLES_5 (ADC_SMPR2_SMP10_1 \ + | ADC_SMPR2_SMP10_0) /*!< Sampling time 24.5 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_47CYCLES_5 (ADC_SMPR2_SMP10_2) /*!< Sampling time 47.5 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_92CYCLES_5 (ADC_SMPR2_SMP10_2 \ + | ADC_SMPR2_SMP10_0) /*!< Sampling time 92.5 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_247CYCLES_5 (ADC_SMPR2_SMP10_2 \ + | ADC_SMPR2_SMP10_1) /*!< Sampling time 247.5 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_640CYCLES_5 (ADC_SMPR2_SMP10_2 \ + | ADC_SMPR2_SMP10_1 \ + | ADC_SMPR2_SMP10_0) /*!< Sampling time 640.5 ADC clock cycles */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_CHANNEL_SINGLE_DIFF_ENDING Channel - Single or differential ending + * @{ + */ +#define LL_ADC_SINGLE_ENDED ( ADC_CALFACT_CALFACT_S) /*!< ADC channel ending + set to single ended (literal also used to set calibration mode) */ +#define LL_ADC_DIFFERENTIAL_ENDED (ADC_CR_ADCALDIF | ADC_CALFACT_CALFACT_D) /*!< ADC channel ending + set to differential (literal also used to set calibration mode) */ +#define LL_ADC_BOTH_SINGLE_DIFF_ENDED (LL_ADC_SINGLE_ENDED | LL_ADC_DIFFERENTIAL_ENDED) /*!< ADC channel ending + set to both single ended and differential (literal used only to set + calibration factors) */ +/** + * @} + */ + +/** @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 */ +#define LL_ADC_AWD2 (ADC_AWD_CR23_CHANNEL_MASK \ + | ADC_AWD_CR2_REGOFFSET) /*!< ADC analog watchdog number 2 */ +#define LL_ADC_AWD3 (ADC_AWD_CR23_CHANNEL_MASK \ + | ADC_AWD_CR3_REGOFFSET) /*!< ADC analog watchdog number 3 */ +/** + * @} + */ + +/** @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_AWD_CR23_CHANNEL_MASK \ + | ADC_CFGR_AWD1EN) /*!< ADC analog watchdog monitoring + of all channels, converted by group regular only */ +#define LL_ADC_AWD_ALL_CHANNELS_INJ (ADC_AWD_CR23_CHANNEL_MASK \ + | ADC_CFGR_JAWD1EN) /*!< ADC analog watchdog monitoring + of all channels, converted by group injected only */ +#define LL_ADC_AWD_ALL_CHANNELS_REG_INJ (ADC_AWD_CR23_CHANNEL_MASK \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN) /*!< 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_CFGR_AWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN0, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_0_INJ ((LL_ADC_CHANNEL_0 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN0, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_0_REG_INJ ((LL_ADC_CHANNEL_0 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN \ + | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel 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_CFGR_AWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN1, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_1_INJ ((LL_ADC_CHANNEL_1 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN1, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_1_REG_INJ ((LL_ADC_CHANNEL_1 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN \ + | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel 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_CFGR_AWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN2, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_2_INJ ((LL_ADC_CHANNEL_2 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN2, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_2_REG_INJ ((LL_ADC_CHANNEL_2 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN \ + | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel 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_CFGR_AWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN3, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_3_INJ ((LL_ADC_CHANNEL_3 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN3, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_3_REG_INJ ((LL_ADC_CHANNEL_3 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN \ + | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel 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_CFGR_AWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN4, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_4_INJ ((LL_ADC_CHANNEL_4 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN4, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_4_REG_INJ ((LL_ADC_CHANNEL_4 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN \ + | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel 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_CFGR_AWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN5, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_5_INJ ((LL_ADC_CHANNEL_5 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN5, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_5_REG_INJ ((LL_ADC_CHANNEL_5 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN \ + | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel 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_CFGR_AWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN6, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_6_INJ ((LL_ADC_CHANNEL_6 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN6, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_6_REG_INJ ((LL_ADC_CHANNEL_6 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN \ + | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel 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_CFGR_AWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN7, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_7_INJ ((LL_ADC_CHANNEL_7 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN7, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_7_REG_INJ ((LL_ADC_CHANNEL_7 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN \ + | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel 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_CFGR_AWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN8, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_8_INJ ((LL_ADC_CHANNEL_8 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN8, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_8_REG_INJ ((LL_ADC_CHANNEL_8 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN \ + | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel 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_CFGR_AWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN9, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_9_INJ ((LL_ADC_CHANNEL_9 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN9, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_9_REG_INJ ((LL_ADC_CHANNEL_9 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN \ + | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel 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_CFGR_AWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN10, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_10_INJ ((LL_ADC_CHANNEL_10 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN10, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_10_REG_INJ ((LL_ADC_CHANNEL_10 & ADC_CHANNEL_ID_MASK)\ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN \ + | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel 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_CFGR_AWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN11, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_11_INJ ((LL_ADC_CHANNEL_11 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN11, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_11_REG_INJ ((LL_ADC_CHANNEL_11 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN \ + | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel 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_CFGR_AWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN12, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_12_INJ ((LL_ADC_CHANNEL_12 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN12, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_12_REG_INJ ((LL_ADC_CHANNEL_12 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN \ + | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel 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_CFGR_AWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN13, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_13_INJ ((LL_ADC_CHANNEL_13 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN13, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_13_REG_INJ ((LL_ADC_CHANNEL_13 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN \ + | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel 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_CFGR_AWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN14, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_14_INJ ((LL_ADC_CHANNEL_14 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN14, converted by group only */ +#define LL_ADC_AWD_CHANNEL_14_REG_INJ ((LL_ADC_CHANNEL_14 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN \ + | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel 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_CFGR_AWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + monitoring of ADC channel ADCx_IN15, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_15_INJ ((LL_ADC_CHANNEL_15 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN15, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_15_REG_INJ ((LL_ADC_CHANNEL_15 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN \ + | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel 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_CFGR_AWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN16, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_16_INJ ((LL_ADC_CHANNEL_16 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN16, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_16_REG_INJ ((LL_ADC_CHANNEL_16 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN \ + | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel 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_CFGR_AWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN17, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_17_INJ ((LL_ADC_CHANNEL_17 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN17, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_17_REG_INJ ((LL_ADC_CHANNEL_17 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN \ + | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel 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_CFGR_AWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN18, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_18_INJ ((LL_ADC_CHANNEL_18 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN18, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_18_REG_INJ ((LL_ADC_CHANNEL_18 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN \ + | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN18, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_19_REG ((LL_ADC_CHANNEL_19 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_AWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN19, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_19_INJ ((LL_ADC_CHANNEL_19 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN19, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_19_REG_INJ ((LL_ADC_CHANNEL_19 & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN \ + | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC channel ADCx_IN19, converted by either group regular or injected */ +#define LL_ADC_AWD_CH_VREFINT_REG ((LL_ADC_CHANNEL_VREFINT & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_AWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC internal channel connected to VrefInt: Internal voltage reference, + converted by group regular only. + On STM32H563xx/573xx, ADC channel available only on ADC instance: ADC1. */ +#define LL_ADC_AWD_CH_VREFINT_INJ ((LL_ADC_CHANNEL_VREFINT & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC internal channel connected to VrefInt: Internal voltage reference, + converted by group injected only. + On STM32H563xx/573xx, ADC channel available only on ADC instance: ADC1. */ +#define LL_ADC_AWD_CH_VREFINT_REG_INJ ((LL_ADC_CHANNEL_VREFINT & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN \ + | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC internal channel connected to VrefInt: Internal voltage reference, + converted by either group regular or injected. + On STM32H563xx/573xx, ADC channel available only on ADC instance: ADC1. */ +#define LL_ADC_AWD_CH_TEMPSENSOR_REG ((LL_ADC_CHANNEL_TEMPSENSOR & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_AWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC internal channel connected to internal temperature sensor, + converted by group regular only. + On STM32H563xx/573xx, ADC channel available only on ADC instance: ADC1. */ +#define LL_ADC_AWD_CH_TEMPSENSOR_INJ ((LL_ADC_CHANNEL_TEMPSENSOR & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC internal channel connected to internal temperature sensor, + converted by group injected only. + On STM32H563xx/573xx, ADC channel available only on ADC instance: ADC1. */ +#define LL_ADC_AWD_CH_TEMPSENSOR_REG_INJ ((LL_ADC_CHANNEL_TEMPSENSOR & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN \ + | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC internal channel connected to internal temperature sensor, + converted by either group regular or injected. + On STM32H563xx/573xx, ADC channel available only on ADC instance: ADC1. */ +#define LL_ADC_AWD_CH_VBAT_REG ((LL_ADC_CHANNEL_VBAT & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_AWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC internal channel connected to Vbat/4: Vbat voltage through + a divider ladder of factor 1/4 to have channel voltage always below Vdda, + converted by group regular only. + On STM32H563xx/573xx, ADC channel available only on ADC instance: ADC2. */ +#define LL_ADC_AWD_CH_VBAT_INJ ((LL_ADC_CHANNEL_VBAT & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC internal channel connected to Vbat/4: Vbat voltage through + a divider ladder of factor 1/4 to have channel voltage always below Vdda, + converted by group injected only. + On STM32H563xx/573xx, ADC channel available only on ADC instance: ADC2. */ +#define LL_ADC_AWD_CH_VBAT_REG_INJ ((LL_ADC_CHANNEL_VBAT & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN \ + | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC internal channel connected to Vbat/4: Vbat voltage through + a divider ladder of factor 1/4 to have channel voltage always below Vdda. + On STM32H563xx/573xx, ADC channel available only on ADC instance: ADC2. */ +#define LL_ADC_AWD_CH_VDDCORE_REG ((LL_ADC_CHANNEL_VDDCORE & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_AWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC internal channel connected to Vddcore, converted by group regular only + On STM32H563xx/573xx, ADC channel available only on ADC instance: ADC2. */ +#define LL_ADC_AWD_CH_VDDCORE_INJ ((LL_ADC_CHANNEL_VDDCORE & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC internal channel connected to Vddcore, + converted by group injected only. + On STM32H563xx/573xx, ADC channel available only on ADC instance: ADC2. */ +#define LL_ADC_AWD_CH_VDDCORE_REG_INJ ((LL_ADC_CHANNEL_VDDCORE & ADC_CHANNEL_ID_MASK) \ + | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN \ + | ADC_CFGR_AWD1SGL) /*!< ADC analog watchdog monitoring + of ADC internal channel connected to Vddcore, + converted by either group regular or injected. + On STM32H563xx/573xx, ADC channel available only on ADC instance: ADC2. */ + +/* Definitions for backward compatibility with legacy STM32 series */ +#define LL_ADC_AWD_CH_VCORE_REG LL_ADC_AWD_CH_VDDCORE_REG +#define LL_ADC_AWD_CH_VCORE_INJ LL_ADC_AWD_CH_VDDCORE_INJ +#define LL_ADC_AWD_CH_VCORE_REG_INJ LL_ADC_AWD_CH_VDDCORE_REG_INJ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_AWD_THRESHOLDS Analog watchdog - Thresholds + * @{ + */ +#define LL_ADC_AWD_THRESHOLD_HIGH (ADC_TR1_HT1) /*!< ADC analog watchdog threshold high */ +#define LL_ADC_AWD_THRESHOLD_LOW (ADC_TR1_LT1) /*!< ADC analog watchdog threshold low */ +#define LL_ADC_AWD_THRESHOLDS_HIGH_LOW (ADC_TR1_HT1 \ + | ADC_TR1_LT1) /*!< ADC analog watchdog both thresholds high and low + concatenated into the same data */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_AWD_FILTERING_CONFIG Analog watchdog - filtering config + * @{ + */ +#define LL_ADC_AWD_FILTERING_NONE (0x00000000UL) /*!< ADC analog watchdog no filtering, + one out-of-window sample is needed to raise flag or interrupt */ +#define LL_ADC_AWD_FILTERING_2SAMPLES (ADC_TR1_AWDFILT_0) /*!< ADC analog watchdog 2 + out-of-window samples are needed to raise flag or interrupt */ +#define LL_ADC_AWD_FILTERING_3SAMPLES (ADC_TR1_AWDFILT_1) /*!< ADC analog watchdog 3 + consecutives out-of-window samples are needed to raise flag or interrupt */ +#define LL_ADC_AWD_FILTERING_4SAMPLES (ADC_TR1_AWDFILT_1 | ADC_TR1_AWDFILT_0) /*!< ADC analog watchdog 4 + consecutives out-of-window samples are needed to raise flag or interrupt */ +#define LL_ADC_AWD_FILTERING_5SAMPLES (ADC_TR1_AWDFILT_2) /*!< ADC analog watchdog 5 + consecutives out-of-window samples are needed to raise flag or interrupt */ +#define LL_ADC_AWD_FILTERING_6SAMPLES (ADC_TR1_AWDFILT_2 | ADC_TR1_AWDFILT_0) /*!< ADC analog watchdog 6 + consecutives out-of-window samples are needed to raise flag or interrupt */ +#define LL_ADC_AWD_FILTERING_7SAMPLES (ADC_TR1_AWDFILT_2 | ADC_TR1_AWDFILT_1) /*!< ADC analog watchdog 7 + consecutives out-of-window samples are needed to raise flag or interrupt */ +#define LL_ADC_AWD_FILTERING_8SAMPLES (ADC_TR1_AWDFILT_2 | ADC_TR1_AWDFILT_1 \ + | ADC_TR1_AWDFILT_0) /*!< ADC analog watchdog 8 + consecutives out-of-window samples are needed to raise flag or interrupt */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_OVS_SCOPE Oversampling - Oversampling scope + * @{ + */ +#define LL_ADC_OVS_DISABLE (0x00000000UL) /*!< ADC oversampling disabled. */ +#define LL_ADC_OVS_GRP_REGULAR_CONTINUED (ADC_CFGR2_ROVSE) /*!< ADC oversampling on conversions of + ADC group regular. If group injected interrupts group regular: + when ADC group injected is triggered, the oversampling on ADC group regular + is temporary stopped and continued afterwards. */ +#define LL_ADC_OVS_GRP_REGULAR_RESUMED (ADC_CFGR2_ROVSM | ADC_CFGR2_ROVSE) /*!< ADC oversampling on conversions of + ADC group regular. If group injected interrupts group regular: + when ADC group injected is triggered, the oversampling on ADC group regular + is resumed from start (oversampler buffer reset). */ +#define LL_ADC_OVS_GRP_INJECTED (ADC_CFGR2_JOVSE) /*!< ADC oversampling on conversions of + ADC group injected. */ +#define LL_ADC_OVS_GRP_INJ_REG_RESUMED (ADC_CFGR2_JOVSE | ADC_CFGR2_ROVSE) /*!< ADC oversampling on conversions of + both ADC groups regular and injected. If group injected interrupting group + regular: when ADC group injected is triggered, the oversampling on ADC group + regular is resumed from start (oversampler buffer reset). */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_OVS_DISCONT_MODE Oversampling - Discontinuous mode + * @{ + */ +#define LL_ADC_OVS_REG_CONT (0x00000000UL) /*!< ADC oversampling discontinuous mode: continuous mode +(all conversions of oversampling ratio are done from 1 trigger) */ +#define LL_ADC_OVS_REG_DISCONT (ADC_CFGR2_TROVS) /*!< ADC oversampling discontinuous mode: discontinuous + mode (each conversion of oversampling ratio needs a trigger) */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_OVS_RATIO Oversampling - Ratio + * @{ + */ +#define LL_ADC_OVS_RATIO_2 (0x00000000UL) /*!< ADC oversampling ratio of 2 + (sum of conversions data computed to result as oversampling conversion data + (before potential shift) */ +#define LL_ADC_OVS_RATIO_4 (ADC_CFGR2_OVSR_0) /*!< ADC oversampling ratio of 4 + (sum of conversions data computed to result as oversampling conversion data + (before potential shift) */ +#define LL_ADC_OVS_RATIO_8 (ADC_CFGR2_OVSR_1) /*!< ADC oversampling ratio of 8 + (sum of conversions data computed to result as oversampling conversion data + (before potential shift) */ +#define LL_ADC_OVS_RATIO_16 (ADC_CFGR2_OVSR_1 | ADC_CFGR2_OVSR_0) /*!< ADC oversampling ratio of 16 + (sum of conversions data computed to result as oversampling conversion data + (before potential shift) */ +#define LL_ADC_OVS_RATIO_32 (ADC_CFGR2_OVSR_2) /*!< ADC oversampling ratio of 32 + (sum of conversions data computed to result as oversampling conversion data + (before potential shift) */ +#define LL_ADC_OVS_RATIO_64 (ADC_CFGR2_OVSR_2 | ADC_CFGR2_OVSR_0) /*!< ADC oversampling ratio of 64 + (sum of conversions data computed to result as oversampling conversion data + (before potential shift) */ +#define LL_ADC_OVS_RATIO_128 (ADC_CFGR2_OVSR_2 | ADC_CFGR2_OVSR_1) /*!< ADC oversampling ratio of 128 + (sum of conversions data computed to result as oversampling conversion data + (before potential shift) */ +#define LL_ADC_OVS_RATIO_256 (ADC_CFGR2_OVSR_2 | ADC_CFGR2_OVSR_1 \ + | ADC_CFGR2_OVSR_0) /*!< ADC oversampling ratio of 256 + (sum of conversions data computed to result as oversampling conversion data + (before potential shift) */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_OVS_SHIFT Oversampling - Data right shift + * @{ + */ +#define LL_ADC_OVS_SHIFT_NONE (0x00000000UL) /*!< ADC oversampling no shift + (sum of the ADC conversions data is not divided to result as oversampling + conversion data) */ +#define LL_ADC_OVS_SHIFT_RIGHT_1 (ADC_CFGR2_OVSS_0) /*!< ADC oversampling right shift of 1 + (sum of the ADC conversions data (after OVS ratio) is divided by 2 + to result as oversampling conversion data) */ +#define LL_ADC_OVS_SHIFT_RIGHT_2 (ADC_CFGR2_OVSS_1) /*!< ADC oversampling right shift of 2 + (sum of the ADC conversions data (after OVS ratio) is divided by 4 + to result as oversampling conversion data) */ +#define LL_ADC_OVS_SHIFT_RIGHT_3 (ADC_CFGR2_OVSS_1 | ADC_CFGR2_OVSS_0) /*!< ADC oversampling right shift of 3 + (sum of the ADC conversions data (after OVS ratio) is divided by 8 + to result as oversampling conversion data) */ +#define LL_ADC_OVS_SHIFT_RIGHT_4 (ADC_CFGR2_OVSS_2) /*!< ADC oversampling right shift of 4 + (sum of the ADC conversions data (after OVS ratio) is divided by 16 + to result as oversampling conversion data) */ +#define LL_ADC_OVS_SHIFT_RIGHT_5 (ADC_CFGR2_OVSS_2 | ADC_CFGR2_OVSS_0) /*!< ADC oversampling right shift of 5 + (sum of the ADC conversions data (after OVS ratio) is divided by 32 + to result as oversampling conversion data) */ +#define LL_ADC_OVS_SHIFT_RIGHT_6 (ADC_CFGR2_OVSS_2 | ADC_CFGR2_OVSS_1) /*!< ADC oversampling right shift of 6 + (sum of the ADC conversions data (after OVS ratio) is divided by 64 + to result as oversampling conversion data) */ +#define LL_ADC_OVS_SHIFT_RIGHT_7 (ADC_CFGR2_OVSS_2 | ADC_CFGR2_OVSS_1 \ + | ADC_CFGR2_OVSS_0) /*!< ADC oversampling right shift of 7 + (sum of the ADC conversions data (after OVS ratio) is divided by 128 + to result as oversampling conversion data) */ +#define LL_ADC_OVS_SHIFT_RIGHT_8 (ADC_CFGR2_OVSS_3) /*!< ADC oversampling right shift of 8 + (sum of the ADC conversions data (after OVS ratio) is divided by 256 + to result as oversampling conversion data) */ +/** + * @} + */ + +#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_DUAL_2 | ADC_CCR_DUAL_1) /*!< ADC dual mode enabled: group regular + simultaneous */ +#define LL_ADC_MULTI_DUAL_REG_INTERL (ADC_CCR_DUAL_2 | ADC_CCR_DUAL_1 \ + | ADC_CCR_DUAL_0) /*!< ADC dual mode enabled: Combined group + regular interleaved */ +#define LL_ADC_MULTI_DUAL_INJ_SIMULT (ADC_CCR_DUAL_2 | ADC_CCR_DUAL_0) /*!< ADC dual mode enabled: group injected + simultaneous */ +#define LL_ADC_MULTI_DUAL_INJ_ALTERN (ADC_CCR_DUAL_3 | ADC_CCR_DUAL_0) /*!< ADC dual mode enabled: group injected + alternate trigger. Works only with external triggers (not SW start) */ +#define LL_ADC_MULTI_DUAL_REG_SIM_INJ_SIM (ADC_CCR_DUAL_0) /*!< ADC dual mode enabled: Combined group + regular simultaneous + group injected simultaneous */ +#define LL_ADC_MULTI_DUAL_REG_SIM_INJ_ALT (ADC_CCR_DUAL_1) /*!< ADC dual mode enabled: Combined group + regular simultaneous + group injected alternate trigger */ +#define LL_ADC_MULTI_DUAL_REG_INT_INJ_SIM (ADC_CCR_DUAL_1 | ADC_CCR_DUAL_0) /*!< ADC dual mode enabled: Combined group + regular interleaved + group injected simultaneous */ +/** + * @} + */ + +/** @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_RES12_10B (ADC_CCR_MDMA_1) /*!< ADC multimode group regular + conversions are transferred by DMA, one DMA channel for both ADC(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 for ADC resolution of 12 and 10 bits */ +#define LL_ADC_MULTI_REG_DMA_LIMIT_RES8_6B (ADC_CCR_MDMA_1 | ADC_CCR_MDMA_0) /*!< ADC multimode group regular + conversions are transferred by DMA, one DMA channel for both ADC(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 for ADC resolution of 8 and 6 bits */ +#define LL_ADC_MULTI_REG_DMA_UNLMT_RES12_10B (ADC_CCR_DMACFG | ADC_CCR_MDMA_1) /*!< ADC multimode group regular + conversions are transferred by DMA, one DMA channel for both ADC(DMA of + ADC master), 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. + Setting for ADC resolution of 12 and 10 bits */ +#define LL_ADC_MULTI_REG_DMA_UNLMT_RES8_6B (ADC_CCR_DMACFG | ADC_CCR_MDMA_1 \ + | ADC_CCR_MDMA_0) /*!< ADC multimode group regular + conversions are transferred by DMA, one DMA channel for both ADC (DMA of + ADC master), 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. + Setting for ADC resolution of 8 and 6 bits */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_MULTI_TWOSMP_DELAY Multimode - Delay between two sampling phases + * @{ + */ +#define LL_ADC_MULTI_TWOSMP_DELAY_1CYCLE (0x00000000UL) /*!< ADC multimode delay between two + sampling phases: 1 ADC clock cycle */ +#define LL_ADC_MULTI_TWOSMP_DELAY_2CYCLES (ADC_CCR_DELAY_0) /*!< ADC multimode delay between two + sampling phases: 2 ADC clock cycles */ +#define LL_ADC_MULTI_TWOSMP_DELAY_3CYCLES (ADC_CCR_DELAY_1) /*!< ADC multimode delay between two + sampling phases: 3 ADC clock cycles */ +#define LL_ADC_MULTI_TWOSMP_DELAY_4CYCLES (ADC_CCR_DELAY_1 | ADC_CCR_DELAY_0) /*!< ADC multimode delay between two + sampling phases: 4 ADC clock cycles */ +#define LL_ADC_MULTI_TWOSMP_DELAY_5CYCLES (ADC_CCR_DELAY_2) /*!< ADC multimode delay between two + sampling phases: 5 ADC clock cycles */ +#define LL_ADC_MULTI_TWOSMP_DELAY_6CYCLES (ADC_CCR_DELAY_2 | 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_2 | 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_2 | 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_3) /*!< ADC multimode delay between two + sampling phases: 9 ADC clock cycles */ +#define LL_ADC_MULTI_TWOSMP_DELAY_10CYCLES (ADC_CCR_DELAY_3 | 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_3 | 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_3 | ADC_CCR_DELAY_1 \ + | ADC_CCR_DELAY_0) /*!< ADC multimode delay between two + sampling phases: 12 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_HELPER_MACRO Definitions of constants used by helper macro + * @{ + */ +#define LL_ADC_TEMPERATURE_CALC_ERROR ((int16_t)0x7FFF) /* Temperature calculation error using helper macro + @ref __LL_ADC_CALC_TEMPERATURE(), due to issue on + calibration parameters. This value is coded on 16 bits + (to fit on signed word or double word) and corresponds + to an inconsistent temperature value. */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_HW_DELAYS Definitions of ADC hardware constraints delays + * @note Only ADC peripheral 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 peripheral 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 calibration time: maximum delay is 112/fADC. */ +/* (refer to device datasheet, parameter "tCAL") */ +/* - ADC enable time: maximum delay is 1 conversion cycle. */ +/* (refer to device datasheet, parameter "tSTAB") */ +/* - ADC disable time: maximum delay should be a few ADC clock cycles */ +/* - ADC stop conversion time: maximum delay should be a few ADC clock */ +/* cycles */ +/* - ADC conversion time: duration depending on ADC clock and ADC */ +/* configuration. */ +/* (refer to device reference manual, section "Timing") */ + +/* Delay for ADC stabilization time (ADC voltage regulator start-up time) */ +/* Delay set to maximum value (refer to device datasheet, */ +/* parameter "tADCVREG_STUP"). */ +/* Unit: us */ +#define LL_ADC_DELAY_INTERNAL_REGUL_STAB_US ( 20UL) /*!< Delay for ADC stabilization time (ADC voltage + regulator start-up time) */ + +/* Delay for internal voltage reference stabilization time. */ +/* Delay set to maximum value (refer to device datasheet, */ +/* parameter "tstart_vrefint"). */ +/* Unit: us */ +#define LL_ADC_DELAY_VREFINT_STAB_US ( 12UL) /*!< 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 ( 26UL) /*!< Delay for temperature sensor stabilization time */ +#define LL_ADC_DELAY_TEMPSENSOR_BUFFER_STAB_US ( 26UL) /*!< Delay for temperature sensor buffer stabilization + time (starting from ADC enable, refer to + @ref LL_ADC_Enable()) */ + +/* Delay required between ADC end of calibration and ADC enable. */ +/* Note: On this STM32 series, a minimum number of ADC clock cycles */ +/* are required between ADC end of calibration and ADC enable. */ +/* Wait time can be computed in user application by waiting for the */ +/* equivalent number of CPU cycles, by taking into account */ +/* ratio of CPU clock versus ADC clock prescalers. */ +/* Unit: ADC clock cycles. */ +#define LL_ADC_DELAY_CALIB_ENABLE_ADC_CYCLES ( 4UL) /*!< Delay required between ADC end of calibration + and ADC enable */ + +/** + * @} + */ + +/** + * @} + */ + + +/* 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 (3) + * @arg @ref LL_ADC_CHANNEL_1 (3) + * @arg @ref LL_ADC_CHANNEL_2 (3) + * @arg @ref LL_ADC_CHANNEL_3 (3) + * @arg @ref LL_ADC_CHANNEL_4 (3) + * @arg @ref LL_ADC_CHANNEL_5 (3) + * @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_19 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1) + * @arg @ref LL_ADC_CHANNEL_VBAT (2) + * @arg @ref LL_ADC_CHANNEL_VDDCORE (2) + * + * (1) On STM32H563xx/573xx, parameter available only on ADC instance: ADC1.\n + * (2) On STM32H563xx/573xx, parameter available only on ADC instance: ADC2.\n + * (3) On STM32H5, fast channel allows: 2.5 (sampling) + 12.5 (conversion 12b) = 15 ADC clock cycles (fADC) + * Other channels are slow channels: 6.5 (sampling) + 12.5 (conversion 12b) = 19 ADC clock cycles (fADC) + * @retval Value between Min_Data=0 and Max_Data=18 + */ +#define __LL_ADC_CHANNEL_TO_DECIMAL_NB(__CHANNEL__) \ + ((((__CHANNEL__) & ADC_CHANNEL_ID_BITFIELD_MASK) == 0UL) ? \ + ( \ + ((__CHANNEL__) & ADC_CHANNEL_ID_NUMBER_MASK) >> ADC_CHANNEL_ID_NUMBER_BITOFFSET_POS \ + ) \ + : \ + ( \ + (uint32_t)POSITION_VAL((__CHANNEL__)) \ + ) \ + ) + +/** + * @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 (3) + * @arg @ref LL_ADC_CHANNEL_1 (3) + * @arg @ref LL_ADC_CHANNEL_2 (3) + * @arg @ref LL_ADC_CHANNEL_3 (3) + * @arg @ref LL_ADC_CHANNEL_4 (3) + * @arg @ref LL_ADC_CHANNEL_5 (3) + * @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_19 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1)(4) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1)(4) + * @arg @ref LL_ADC_CHANNEL_VBAT (2)(4) + * @arg @ref LL_ADC_CHANNEL_VDDCORE (2)(4) + * + * (1) On STM32H563xx/573xx, parameter available only on ADC instance: ADC1.\n + * (2) On STM32H563xx/573xx, parameter available only on ADC instance: ADC2.\n + * (3) On STM32H5, fast channel allows: 2.5 (sampling) + 12.5 (conversion 12b) = 15 ADC clock cycles (fADC) + * Other channels are slow channels: 6.5 (sampling) + 12.5 (conversion 12b) = 19 ADC clock cycles (fADC) + * (4) 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_AWD2CR_AWD2CH_0 << (__DECIMAL_NB__)) | \ + (ADC_SMPR1_REGOFFSET | (((3UL * (__DECIMAL_NB__))) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) \ + ) \ + : \ + ( \ + ((__DECIMAL_NB__) << ADC_CHANNEL_ID_NUMBER_BITOFFSET_POS) | \ + (ADC_AWD2CR_AWD2CH_0 << (__DECIMAL_NB__)) | \ + (ADC_SMPR2_REGOFFSET | (((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 (3) + * @arg @ref LL_ADC_CHANNEL_1 (3) + * @arg @ref LL_ADC_CHANNEL_2 (3) + * @arg @ref LL_ADC_CHANNEL_3 (3) + * @arg @ref LL_ADC_CHANNEL_4 (3) + * @arg @ref LL_ADC_CHANNEL_5 (3) + * @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_19 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1) + * @arg @ref LL_ADC_CHANNEL_VBAT (2) + * @arg @ref LL_ADC_CHANNEL_VDDCORE (2) + * + * (1) On STM32H563xx/573xx, parameter available only on ADC instance: ADC1.\n + * (2) On STM32H563xx/573xx, parameter available only on ADC instance: ADC2.\n + * (3) On STM32H5, fast channel allows: 2.5 (sampling) + 12.5 (conversion 12b) = 15 ADC clock cycles (fADC) + * Other channels are slow channels: 6.5 (sampling) + 12.5 (conversion 12b) = 19 ADC clock cycles (fADC) + * @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 (3) + * @arg @ref LL_ADC_CHANNEL_1 (3) + * @arg @ref LL_ADC_CHANNEL_2 (3) + * @arg @ref LL_ADC_CHANNEL_3 (3) + * @arg @ref LL_ADC_CHANNEL_4 (3) + * @arg @ref LL_ADC_CHANNEL_5 (3) + * @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_19 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1) + * @arg @ref LL_ADC_CHANNEL_VBAT (2) + * @arg @ref LL_ADC_CHANNEL_VDDCORE (2) + * + * (1) On STM32H563xx/573xx, parameter available only on ADC instance: ADC1.\n + * (2) On STM32H563xx/573xx, parameter available only on ADC instance: ADC2.\n + * (3) On STM32H5, fast channel allows: 2.5 (sampling) + 12.5 (conversion 12b) = 15 ADC clock cycles (fADC) + * Other channels are slow channels: 6.5 (sampling) + 12.5 (conversion 12b) = 19 ADC clock cycles (fADC) + * @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_19 + */ +#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) + * @arg @ref LL_ADC_CHANNEL_VBAT (2) + * @arg @ref LL_ADC_CHANNEL_VDDCORE (2) + * + * (1) On STM32H563xx/573xx, parameter available only on ADC instance: ADC1. + * (2) On STM32H563xx/573xx, parameter available only on ADC instance: ADC2. + * @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. + */ +#if defined(ADC2) +#define __LL_ADC_IS_CHANNEL_INTERNAL_AVAILABLE(__ADC_INSTANCE__, __CHANNEL__) \ + ((((__ADC_INSTANCE__) == ADC1) \ + &&(((__CHANNEL__) == LL_ADC_CHANNEL_TEMPSENSOR ) || \ + ((__CHANNEL__) == LL_ADC_CHANNEL_VREFINT)) \ + ) \ + || \ + (((__ADC_INSTANCE__) == ADC2) \ + &&(((__CHANNEL__) == LL_ADC_CHANNEL_VBAT) || \ + ((__CHANNEL__) == LL_ADC_CHANNEL_VDDCORE)) \ + ) \ + ) +#else +#define __LL_ADC_IS_CHANNEL_INTERNAL_AVAILABLE(__ADC_INSTANCE__, __CHANNEL__) \ + (((__CHANNEL__) == LL_ADC_CHANNEL_VREFINT) || \ + ((__CHANNEL__) == LL_ADC_CHANNEL_TEMPSENSOR) || \ + ((__CHANNEL__) == LL_ADC_CHANNEL_VDDCORE) || \ + ((__CHANNEL__) == LL_ADC_CHANNEL_VBAT) \ + ) +#endif /* ADC2 */ + +/** + * @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 (3) + * @arg @ref LL_ADC_CHANNEL_1 (3) + * @arg @ref LL_ADC_CHANNEL_2 (3) + * @arg @ref LL_ADC_CHANNEL_3 (3) + * @arg @ref LL_ADC_CHANNEL_4 (3) + * @arg @ref LL_ADC_CHANNEL_5 (3) + * @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_19 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1)(4) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1)(4) + * @arg @ref LL_ADC_CHANNEL_VBAT (2)(4) + * @arg @ref LL_ADC_CHANNEL_VDDCORE (2)(4) + * + * (1) On STM32H563xx/573xx, parameter available only on ADC instance: ADC1.\n + * (2) On STM32H563xx/573xx, parameter available only on ADC instance: ADC2.\n + * (3) On STM32H5, fast channel allows: 2.5 (sampling) + 12.5 (conversion 12b) = 15 ADC clock cycles (fADC) + * Other channels are slow channels: 6.5 (sampling) + 12.5 (conversion 12b) = 19 ADC clock cycles (fADC) + * (4) 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 (0) + * @arg @ref LL_ADC_AWD_ALL_CHANNELS_INJ (0) + * @arg @ref LL_ADC_AWD_ALL_CHANNELS_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_0_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_0_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_0_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_1_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_1_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_1_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_2_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_2_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_2_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_3_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_3_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_3_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_4_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_4_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_4_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_5_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_5_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_5_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_6_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_6_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_6_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_7_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_7_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_7_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_8_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_8_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_8_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_9_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_9_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_9_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_10_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_10_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_10_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_11_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_11_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_11_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_12_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_12_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_12_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_13_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_13_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_13_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_14_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_14_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_14_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_15_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_15_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_15_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_16_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_16_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_16_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_17_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_17_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_17_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_18_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_18_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_18_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_19_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_19_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_19_REG_INJ + * @arg @ref LL_ADC_AWD_CH_VREFINT_REG (0)(1) + * @arg @ref LL_ADC_AWD_CH_VREFINT_INJ (0)(1) + * @arg @ref LL_ADC_AWD_CH_VREFINT_REG_INJ (1) + * @arg @ref LL_ADC_AWD_CH_TEMPSENSOR_REG (0)(1) + * @arg @ref LL_ADC_AWD_CH_TEMPSENSOR_INJ (0)(1) + * @arg @ref LL_ADC_AWD_CH_TEMPSENSOR_REG_INJ (1) + * @arg @ref LL_ADC_AWD_CH_VBAT_REG (0)(2) + * @arg @ref LL_ADC_AWD_CH_VBAT_INJ (0)(2) + * @arg @ref LL_ADC_AWD_CH_VBAT_REG_INJ (2) + * @arg @ref LL_ADC_AWD_CH_VDDCORE_REG (0)(2) + * @arg @ref LL_ADC_AWD_CH_VDDCORE_INJ (0)(2) + * @arg @ref LL_ADC_AWD_CH_VDDCORE_REG_INJ (2) + * + * (0) On STM32H5, parameter available only on analog watchdog number: AWD1.\n + * (1) On STM32H563xx/573xx, parameter available only on ADC instance: ADC1. + * (2) On STM32H563xx/573xx, parameter available only on ADC instance: ADC2. + */ +#define __LL_ADC_ANALOGWD_CHANNEL_GROUP(__CHANNEL__, __GROUP__) \ + (((__GROUP__) == LL_ADC_GROUP_REGULAR) \ + ? (((__CHANNEL__) & ADC_CHANNEL_ID_MASK) | ADC_CFGR_AWD1EN | ADC_CFGR_AWD1SGL) \ + : \ + ((__GROUP__) == LL_ADC_GROUP_INJECTED) \ + ? (((__CHANNEL__) & ADC_CHANNEL_ID_MASK) | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1SGL) \ + : \ + (((__CHANNEL__) & ADC_CHANNEL_ID_MASK) | ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN | ADC_CFGR_AWD1SGL) \ + ) + +/** + * @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_ConfigAnalogWDThresholds() + * or @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_CFGR_RES_BITOFFSET_POS - 1U ))) + +/** + * @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_CFGR_RES_BITOFFSET_POS - 1U ))) + +/** + * @brief Helper macro to get the ADC analog watchdog threshold high + * or low from raw value containing both thresholds concatenated. + * @note To be used with function @ref LL_ADC_GetAnalogWDThresholds(). + * Example, to get analog watchdog threshold high from the register raw value: + * __LL_ADC_ANALOGWD_THRESHOLDS_HIGH_LOW(LL_ADC_AWD_THRESHOLD_HIGH, ); + * @param __AWD_THRESHOLD_TYPE__ This parameter can be one of the following values: + * @arg @ref LL_ADC_AWD_THRESHOLD_HIGH + * @arg @ref LL_ADC_AWD_THRESHOLD_LOW + * @param __AWD_THRESHOLDS__ Value between Min_Data=0x00000000 and Max_Data=0xFFFFFFFF + * @retval Value between Min_Data=0x000 and Max_Data=0xFFF + */ +#define __LL_ADC_ANALOGWD_THRESHOLDS_HIGH_LOW(__AWD_THRESHOLD_TYPE__, __AWD_THRESHOLDS__) \ + (((__AWD_THRESHOLDS__) >> (((__AWD_THRESHOLD_TYPE__) & ADC_AWD_TRX_BIT_HIGH_MASK) >> ADC_AWD_TRX_BIT_HIGH_SHIFT4)) \ + & LL_ADC_AWD_THRESHOLD_LOW) + +/** + * @brief Helper macro to set the ADC calibration value with both single ended + * and differential modes calibration factors concatenated. + * @note To be used with function @ref LL_ADC_SetCalibrationFactor(). + * Example, to set calibration factors single ended to 0x55 + * and differential ended to 0x2A: + * LL_ADC_SetCalibrationFactor( + * ADC1, + * __LL_ADC_CALIB_FACTOR_SINGLE_DIFF(0x55, 0x2A)) + * @param __CALIB_FACTOR_SINGLE_ENDED__ Value between Min_Data=0x00 and Max_Data=0x7F + * @param __CALIB_FACTOR_DIFFERENTIAL__ Value between Min_Data=0x00 and Max_Data=0x7F + * @retval Value between Min_Data=0x00000000 and Max_Data=0xFFFFFFFF + */ +#define __LL_ADC_CALIB_FACTOR_SINGLE_DIFF(__CALIB_FACTOR_SINGLE_ENDED__, __CALIB_FACTOR_DIFFERENTIAL__) \ + (((__CALIB_FACTOR_DIFFERENTIAL__) << ADC_CALFACT_CALFACT_D_Pos) | (__CALIB_FACTOR_SINGLE_ENDED__)) + +#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__) >> ((ADC_CDR_RDATA_SLV_Pos) & ~(__ADC_MULTI_MASTER_SLAVE__))) & ADC_CDR_RDATA_MST) +#endif /* ADC_MULTIMODE_SUPPORT */ + +#if defined(ADC_MULTIMODE_SUPPORT) +/** + * @brief Helper macro to select, from a ADC instance, to which ADC instance + * it has a dependence in multimode (ADC master of the corresponding + * ADC common instance). + * @note In case of device with multimode available and a mix of + * ADC instances compliant and not compliant with multimode feature, + * ADC instances not compliant with multimode feature are + * considered as master instances (do not depend to + * any other ADC instance). + * @param __ADCx__ ADC instance + * @retval __ADCx__ ADC instance master of the corresponding ADC common instance + */ +#define __LL_ADC_MULTI_INSTANCE_MASTER(__ADCx__) \ + ( ( ((__ADCx__) == ADC2) \ + )? \ + (ADC1) \ + : \ + (__ADCx__) \ + ) +#endif /* ADC_MULTIMODE_SUPPORT */ + +/** + * @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 + */ +#define __LL_ADC_COMMON_INSTANCE(__ADCx__) (ADC12_COMMON) +/** + * @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(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 /* ADC2 */ + +/** + * @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 full-scale digital value (unit: digital value of ADC conversion data) + */ +#define __LL_ADC_DIGITAL_SCALE(__ADC_RESOLUTION__) \ + (0xFFFUL >> ((__ADC_RESOLUTION__) >> (ADC_CFGR_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 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_CFGR_RES_BITOFFSET_POS - 1UL))) \ + >> ((__ADC_RESOLUTION_TARGET__) >> (ADC_CFGR_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) \ +) + +/** + * @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) + * In case or error, value LL_ADC_TEMPERATURE_CALC_ERROR is returned (inconsistent temperature value) + */ +#define __LL_ADC_CALC_TEMPERATURE(__VREFANALOG_VOLTAGE__,\ + __TEMPSENSOR_ADC_DATA__,\ + __ADC_RESOLUTION__)\ +((((int32_t)*TEMPSENSOR_CAL2_ADDR - (int32_t)*TEMPSENSOR_CAL1_ADDR) != 0) ? \ + (((( ((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 \ + ) \ + : \ + ((int32_t)LL_ADC_TEMPERATURE_CALC_ERROR) \ +) + +/** + * @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 12 bits + * (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 STM32H5, 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 this STM32 series, refer to datasheet parameter "V30" (corresponding + * to TS_CAL1). + * @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+) value (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_ADC_DATA__) * (__VREFANALOG_VOLTAGE__)) \ + / __LL_ADC_DIGITAL_SCALE(__ADC_RESOLUTION__)) \ + * 1000UL) \ + - \ + (int32_t)(((__TEMPSENSOR_TYP_CALX_V__)) \ + * 1000UL) \ + ) \ + ) / (int32_t)(__TEMPSENSOR_TYP_AVGSLOPE__) \ + ) + (int32_t)(__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; + + 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(const ADC_TypeDef *ADCx, uint32_t Register) +{ + /* Prevent unused argument(s) compilation warning */ + (void)(Register); + + /* Retrieve address of register DR */ + return (uint32_t) &(ADCx->DR); +} +#endif /* ADC_MULTIMODE_SUPPORT */ + +/** + * @} + */ + +/** @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. + * @note On this STM32 series, if ADC group injected is used, some + * clock ratio constraints between ADC clock and AHB clock + * must be respected. + * Refer to reference manual. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * All ADC instances of the ADC common group must be disabled. + * This check can be done with function @ref LL_ADC_IsEnabled() for each + * ADC instance or by using helper macro helper macro + * @ref __LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(). + * @rmtoll CCR CKMODE LL_ADC_SetCommonClock\n + * CCR PRESC 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_DIV1 + * @arg @ref LL_ADC_CLOCK_SYNC_PCLK_DIV2 + * @arg @ref LL_ADC_CLOCK_SYNC_PCLK_DIV4 + * @arg @ref LL_ADC_CLOCK_ASYNC_DIV1 + * @arg @ref LL_ADC_CLOCK_ASYNC_DIV2 + * @arg @ref LL_ADC_CLOCK_ASYNC_DIV4 + * @arg @ref LL_ADC_CLOCK_ASYNC_DIV6 + * @arg @ref LL_ADC_CLOCK_ASYNC_DIV8 + * @arg @ref LL_ADC_CLOCK_ASYNC_DIV10 + * @arg @ref LL_ADC_CLOCK_ASYNC_DIV12 + * @arg @ref LL_ADC_CLOCK_ASYNC_DIV16 + * @arg @ref LL_ADC_CLOCK_ASYNC_DIV32 + * @arg @ref LL_ADC_CLOCK_ASYNC_DIV64 + * @arg @ref LL_ADC_CLOCK_ASYNC_DIV128 + * @arg @ref LL_ADC_CLOCK_ASYNC_DIV256 + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetCommonClock(ADC_Common_TypeDef *ADCxy_COMMON, uint32_t CommonClock) +{ + MODIFY_REG(ADCxy_COMMON->CCR, ADC_CCR_CKMODE | ADC_CCR_PRESC, CommonClock); +} + +/** + * @brief Get parameter common to several ADC: Clock source and prescaler. + * @rmtoll CCR CKMODE LL_ADC_GetCommonClock\n + * CCR PRESC 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_DIV1 + * @arg @ref LL_ADC_CLOCK_SYNC_PCLK_DIV2 + * @arg @ref LL_ADC_CLOCK_SYNC_PCLK_DIV4 + * @arg @ref LL_ADC_CLOCK_ASYNC_DIV1 + * @arg @ref LL_ADC_CLOCK_ASYNC_DIV2 + * @arg @ref LL_ADC_CLOCK_ASYNC_DIV4 + * @arg @ref LL_ADC_CLOCK_ASYNC_DIV6 + * @arg @ref LL_ADC_CLOCK_ASYNC_DIV8 + * @arg @ref LL_ADC_CLOCK_ASYNC_DIV10 + * @arg @ref LL_ADC_CLOCK_ASYNC_DIV12 + * @arg @ref LL_ADC_CLOCK_ASYNC_DIV16 + * @arg @ref LL_ADC_CLOCK_ASYNC_DIV32 + * @arg @ref LL_ADC_CLOCK_ASYNC_DIV64 + * @arg @ref LL_ADC_CLOCK_ASYNC_DIV128 + * @arg @ref LL_ADC_CLOCK_ASYNC_DIV256 + */ +__STATIC_INLINE uint32_t LL_ADC_GetCommonClock(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return (uint32_t)(READ_BIT(ADCxy_COMMON->CCR, ADC_CCR_CKMODE | ADC_CCR_PRESC)); +} + +/** + * @brief Set parameter common to several ADC: measurement path to + * internal channels (VrefInt, temperature sensor, ...). + * Configure all paths (overwrite current configuration). + * @note One or several values can be selected. + * Example: (LL_ADC_PATH_INTERNAL_VREFINT | + * LL_ADC_PATH_INTERNAL_TEMPSENSOR) + * The values not selected are removed from configuration. + * @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 literals @ref LL_ADC_DELAY_TEMPSENSOR_STAB_US, + * @ref LL_ADC_DELAY_TEMPSENSOR_BUFFER_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 VREFEN LL_ADC_SetCommonPathInternalCh\n + * CCR TSEN LL_ADC_SetCommonPathInternalCh\n + * CCR VBATEN 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_VREFEN | ADC_CCR_TSEN | ADC_CCR_VBATEN, PathInternal); +} + +/** + * @brief Set parameter common to several ADC: measurement path to + * internal channels (VrefInt, temperature sensor, ...). + * Add paths to the current configuration. + * @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 literals @ref LL_ADC_DELAY_TEMPSENSOR_STAB_US, + * @ref LL_ADC_DELAY_TEMPSENSOR_BUFFER_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 VREFEN LL_ADC_SetCommonPathInternalChAdd\n + * CCR TSEN LL_ADC_SetCommonPathInternalChAdd\n + * CCR VBATEN LL_ADC_SetCommonPathInternalChAdd + * @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_SetCommonPathInternalChAdd(ADC_Common_TypeDef *ADCxy_COMMON, uint32_t PathInternal) +{ + SET_BIT(ADCxy_COMMON->CCR, PathInternal); +} + +/** + * @brief Set parameter common to several ADC: measurement path to + * internal channels (VrefInt, temperature sensor, ...). + * Remove paths to the current configuration. + * @note One or several values can be selected. + * Example: (LL_ADC_PATH_INTERNAL_VREFINT | + * LL_ADC_PATH_INTERNAL_TEMPSENSOR) + * @rmtoll CCR VREFEN LL_ADC_SetCommonPathInternalChRem\n + * CCR TSEN LL_ADC_SetCommonPathInternalChRem\n + * CCR VBATEN LL_ADC_SetCommonPathInternalChRem + * @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_SetCommonPathInternalChRem(ADC_Common_TypeDef *ADCxy_COMMON, uint32_t PathInternal) +{ + CLEAR_BIT(ADCxy_COMMON->CCR, 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 VREFEN LL_ADC_GetCommonPathInternalCh\n + * CCR TSEN LL_ADC_GetCommonPathInternalCh\n + * CCR VBATEN 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_VREFEN | ADC_CCR_TSEN | ADC_CCR_VBATEN)); +} + +/** + * @} + */ + +/** @defgroup ADC_LL_EF_Configuration_ADC_Instance Configuration of ADC hierarchical scope: ADC instance + * @{ + */ + +#if defined (ADC2) +/** + * @brief Enable VddCore (internal digital core voltage) channel. + * @note On this STM32 series, VddCore channel is controlled via a specific register. + * @note On this STM32 series, VddCore channel is on ADC2 instance only. + * @rmtoll OR OP0 LL_ADC_EnableChannelVDDcore + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_EnableChannelVDDcore(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->OR, ADC_OR_OP0); +} +#else +/** + * @brief Enable VddCore (internal digital core voltage) channel. + * @note On this STM32 series, VddCore channel is controlled via a specific register. + * @rmtoll OR OP1 LL_ADC_EnableChannelVDDcore + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_EnableChannelVDDcore(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->OR, ADC_OR_OP1); +} +#endif /* ADC2 */ + +#if defined (ADC2) +/** + * @brief Disable VddCore (internal digital core voltage) channel. + * @note On this STM32 series, VddCore channel is controlled via a specific register. + * @note On this STM32 series, VddCore channel is on ADC2 instance only. + * @rmtoll OR OP0 LL_ADC_DisableChannelVDDcore + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_DisableChannelVDDcore(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->OR, ADC_OR_OP0); +} +#else +/** + * @brief Disable VddCore (internal digital core voltage) channel. + * @note On this STM32 series, VddCore channel is controlled via a specific register. + * @rmtoll OR OP1 LL_ADC_DisableChannelVDDcore + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_DisableChannelVDDcore(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->OR, ADC_OR_OP1); +} +#endif /* ADC2 */ + +/** + * @brief Enable Channel 0 GPIO switch control. + * @note On this STM32 series, Channel 0 channel connection to GPIO is controlled via specific register. + * @note On this STM32 series, Channel 0 GPIO switch control must be enabled when INP0 is used. + * @rmtoll OR OP0 LL_ADC_EnableChannel0_GPIO + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_EnableChannel0_GPIO(const ADC_TypeDef *ADCx) +{ + /* Prevent unused argument(s) compilation warning */ + (void)(ADCx); + SET_BIT(ADC1->OR, ADC_OR_OP0); +} + +/** + * @brief Disable Channel 0 GPIO switch control. + * @note On this STM32 series, Channel 0 connection to GPIO is controlled via specific register. + * @rmtoll OR OP0 LL_ADC_DisableChannel0_GPIO + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_DisableChannel0_GPIO(const ADC_TypeDef *ADCx) +{ + /* Prevent unused argument(s) compilation warning */ + (void)(ADCx); + CLEAR_BIT(ADC1->OR, ADC_OR_OP0); +} + +/** + * @brief Set ADC calibration factor in the mode single-ended + * or differential (for devices with differential mode available). + * @note This function is intended to set calibration parameters + * without having to perform a new calibration using + * @ref LL_ADC_StartCalibration(). + * @note For devices with differential mode available: + * Calibration of offset is specific to each of + * single-ended and differential modes + * (calibration factor must be specified for each of these + * differential modes, if used afterwards and if the application + * requires their calibration). + * @note In case of setting calibration factors of both modes single ended + * and differential (parameter LL_ADC_BOTH_SINGLE_DIFF_ENDED): + * both calibration factors must be concatenated. + * To perform this processing, use helper macro + * @ref __LL_ADC_CALIB_FACTOR_SINGLE_DIFF(). + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be enabled, without calibration on going, without conversion + * on going on group regular. + * @rmtoll CALFACT CALFACT_S LL_ADC_SetCalibrationFactor\n + * CALFACT CALFACT_D LL_ADC_SetCalibrationFactor + * @param ADCx ADC instance + * @param SingleDiff This parameter can be one of the following values: + * @arg @ref LL_ADC_SINGLE_ENDED + * @arg @ref LL_ADC_DIFFERENTIAL_ENDED + * @arg @ref LL_ADC_BOTH_SINGLE_DIFF_ENDED + * @param CalibrationFactor Value between Min_Data=0x00 and Max_Data=0x7F + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetCalibrationFactor(ADC_TypeDef *ADCx, uint32_t SingleDiff, uint32_t CalibrationFactor) +{ + MODIFY_REG(ADCx->CALFACT, + SingleDiff & ADC_SINGLEDIFF_CALIB_FACTOR_MASK, + CalibrationFactor << (((SingleDiff & ADC_SINGLEDIFF_CALIB_F_BIT_D_MASK) + >> ADC_SINGLEDIFF_CALIB_F_BIT_D_SHIFT4) + & ~(SingleDiff & ADC_CALFACT_CALFACT_S))); +} + +/** + * @brief Get ADC calibration factor in the mode single-ended + * or differential (for devices with differential mode available). + * @note Calibration factors are set by hardware after performing + * a calibration run using function @ref LL_ADC_StartCalibration(). + * @note For devices with differential mode available: + * Calibration of offset is specific to each of + * single-ended and differential modes + * @rmtoll CALFACT CALFACT_S LL_ADC_GetCalibrationFactor\n + * CALFACT CALFACT_D LL_ADC_GetCalibrationFactor + * @param ADCx ADC instance + * @param SingleDiff This parameter can be one of the following values: + * @arg @ref LL_ADC_SINGLE_ENDED + * @arg @ref LL_ADC_DIFFERENTIAL_ENDED + * @retval Value between Min_Data=0x00 and Max_Data=0x7F + */ +__STATIC_INLINE uint32_t LL_ADC_GetCalibrationFactor(const ADC_TypeDef *ADCx, uint32_t SingleDiff) +{ + /* Retrieve bits with position in register depending on parameter */ + /* "SingleDiff". */ + /* Parameter used with mask "ADC_SINGLEDIFF_CALIB_FACTOR_MASK" because */ + /* containing other bits reserved for other purpose. */ + return (uint32_t)(READ_BIT(ADCx->CALFACT, + (SingleDiff & ADC_SINGLEDIFF_CALIB_FACTOR_MASK)) + >> ((SingleDiff & ADC_SINGLEDIFF_CALIB_F_BIT_D_MASK) >> + ADC_SINGLEDIFF_CALIB_F_BIT_D_SHIFT4)); +} + +/** + * @brief Set ADC resolution. + * Refer to reference manual for alignments formats + * dependencies to ADC resolutions. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on either groups regular or injected. + * @rmtoll CFGR 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->CFGR, ADC_CFGR_RES, Resolution); +} + +/** + * @brief Get ADC resolution. + * Refer to reference manual for alignments formats + * dependencies to ADC resolutions. + * @rmtoll CFGR 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->CFGR, ADC_CFGR_RES)); +} + +/** + * @brief Set ADC conversion data alignment. + * @note Refer to reference manual for alignments formats + * dependencies to ADC resolutions. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on either groups regular or injected. + * @rmtoll CFGR 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->CFGR, ADC_CFGR_ALIGN, DataAlignment); +} + +/** + * @brief Get ADC conversion data alignment. + * @note Refer to reference manual for alignments formats + * dependencies to ADC resolutions. + * @rmtoll CFGR ALIGN LL_ADC_GetDataAlignment + * @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->CFGR, ADC_CFGR_ALIGN)); +} + +/** + * @brief Set ADC low power mode. + * @note Description of ADC low power modes: + * - ADC low power mode "auto wait": Dynamic low power mode, + * ADC conversions occurrences are limited to the minimum necessary + * in order to reduce power consumption. + * New ADC conversion starts only when the previous + * unitary conversion data (for ADC group regular) + * or previous sequence conversions data (for ADC group injected) + * has been retrieved by user software. + * In the meantime, ADC remains idle: does not performs any + * other conversion. + * This mode allows to automatically adapt the ADC conversions + * triggers to the speed of the software that reads the data. + * Moreover, this avoids risk of overrun for low frequency + * applications. + * How to use this low power mode: + * - It is not recommended to use with interruption or DMA + * since these modes have to clear immediately the EOC flag + * (by CPU to free the IRQ pending event or by DMA). + * Auto wait will work but fort a very short time, discarding + * its intended benefit (except specific case of high load of CPU + * or DMA transfers which can justify usage of auto wait). + * - Do use with polling: 1. Start conversion, + * 2. Later on, when conversion data is needed: poll for end of + * conversion to ensure that conversion is completed and + * retrieve ADC conversion data. This will trig another + * ADC conversion start. + * @note With ADC low power mode "auto wait", the ADC conversion data read + * is corresponding to previous ADC conversion start, independently + * of delay during which ADC was idle. + * Therefore, the ADC conversion data may be outdated: does not + * correspond to the current voltage level on the selected + * ADC channel. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on either groups regular or injected. + * @rmtoll CFGR AUTDLY LL_ADC_SetLowPowerMode + * @param ADCx ADC instance + * @param LowPowerMode This parameter can be one of the following values: + * @arg @ref LL_ADC_LP_MODE_NONE + * @arg @ref LL_ADC_LP_AUTOWAIT + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetLowPowerMode(ADC_TypeDef *ADCx, uint32_t LowPowerMode) +{ + MODIFY_REG(ADCx->CFGR, ADC_CFGR_AUTDLY, LowPowerMode); +} + +/** + * @brief Get ADC low power mode: + * @note Description of ADC low power modes: + * - ADC low power mode "auto wait": Dynamic low power mode, + * ADC conversions occurrences are limited to the minimum necessary + * in order to reduce power consumption. + * New ADC conversion starts only when the previous + * unitary conversion data (for ADC group regular) + * or previous sequence conversions data (for ADC group injected) + * has been retrieved by user software. + * In the meantime, ADC remains idle: does not performs any + * other conversion. + * This mode allows to automatically adapt the ADC conversions + * triggers to the speed of the software that reads the data. + * Moreover, this avoids risk of overrun for low frequency + * applications. + * How to use this low power mode: + * - It is not recommended to use with interruption or DMA + * since these modes have to clear immediately the EOC flag + * (by CPU to free the IRQ pending event or by DMA). + * Auto wait will work but fort a very short time, discarding + * its intended benefit (except specific case of high load of CPU + * or DMA transfers which can justify usage of auto wait). + * - Do use with polling: 1. Start conversion, + * 2. Later on, when conversion data is needed: poll for end of + * conversion to ensure that conversion is completed and + * retrieve ADC conversion data. This will trig another + * ADC conversion start. + * @note With ADC low power mode "auto wait", the ADC conversion data read + * is corresponding to previous ADC conversion start, independently + * of delay during which ADC was idle. + * Therefore, the ADC conversion data may be outdated: does not + * correspond to the current voltage level on the selected + * ADC channel. + * @rmtoll CFGR AUTDLY LL_ADC_GetLowPowerMode + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_LP_MODE_NONE + * @arg @ref LL_ADC_LP_AUTOWAIT + */ +__STATIC_INLINE uint32_t LL_ADC_GetLowPowerMode(const ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CFGR, ADC_CFGR_AUTDLY)); +} + +/** + * @brief Set ADC selected offset instance 1, 2, 3 or 4. + * @note This function set the 2 items of offset configuration: + * - ADC channel to which the offset programmed will be applied + * (independently of channel mapped on ADC group regular + * or group injected) + * - Offset level (offset to be subtracted from the raw + * converted data). + * @note 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 This function enables the offset, by default. It can be forced + * to disable state using function LL_ADC_SetOffsetState(). + * @note If a channel is mapped on several offsets numbers, only the offset + * with the lowest value is considered for the subtraction. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on either groups regular or injected. + * @note On STM32H5, some fast channels are available: fast analog inputs + * coming from GPIO pads (ADC_IN0..5). + * @rmtoll OFR1 OFFSET1_CH LL_ADC_SetOffset\n + * OFR1 OFFSET1 LL_ADC_SetOffset\n + * OFR1 OFFSET1_EN LL_ADC_SetOffset\n + * OFR2 OFFSET2_CH LL_ADC_SetOffset\n + * OFR2 OFFSET2 LL_ADC_SetOffset\n + * OFR2 OFFSET2_EN LL_ADC_SetOffset\n + * OFR3 OFFSET3_CH LL_ADC_SetOffset\n + * OFR3 OFFSET3 LL_ADC_SetOffset\n + * OFR3 OFFSET3_EN LL_ADC_SetOffset\n + * OFR4 OFFSET4_CH LL_ADC_SetOffset\n + * OFR4 OFFSET4 LL_ADC_SetOffset\n + * OFR4 OFFSET4_EN LL_ADC_SetOffset + * @param ADCx ADC instance + * @param Offsety This parameter can be one of the following values: + * @arg @ref LL_ADC_OFFSET_1 + * @arg @ref LL_ADC_OFFSET_2 + * @arg @ref LL_ADC_OFFSET_3 + * @arg @ref LL_ADC_OFFSET_4 + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 (3) + * @arg @ref LL_ADC_CHANNEL_1 (3) + * @arg @ref LL_ADC_CHANNEL_2 (3) + * @arg @ref LL_ADC_CHANNEL_3 (3) + * @arg @ref LL_ADC_CHANNEL_4 (3) + * @arg @ref LL_ADC_CHANNEL_5 (3) + * @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_19 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1) + * @arg @ref LL_ADC_CHANNEL_VBAT (2) + * @arg @ref LL_ADC_CHANNEL_VDDCORE (2) + * + * (1) On STM32H563xx/573xx, parameter available only on ADC instance: ADC1.\n + * (2) On STM32H563xx/573xx, parameter available only on ADC instance: ADC2.\n + * (3) On STM32H5, fast channel allows: 2.5 (sampling) + 12.5 (conversion 12b) = 15 ADC clock cycles (fADC) + * Other channels are slow channels: 6.5 (sampling) + 12.5 (conversion 12b) = 19 ADC clock cycles (fADC) + * @param OffsetLevel Value between Min_Data=0x000 and Max_Data=0xFFF + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetOffset(ADC_TypeDef *ADCx, uint32_t Offsety, uint32_t Channel, uint32_t OffsetLevel) +{ + __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->OFR1, Offsety); + + MODIFY_REG(*preg, + ADC_OFR1_OFFSET1_EN | ADC_OFR1_OFFSET1_CH | ADC_OFR1_OFFSET1, + ADC_OFR1_OFFSET1_EN | (Channel & ADC_CHANNEL_ID_NUMBER_MASK) | OffsetLevel); +} + +/** + * @brief Get for the ADC selected offset instance 1, 2, 3 or 4: + * Channel to which the offset programmed will be applied + * (independently of channel mapped on ADC group regular + * or group injected) + * @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(). + * @note On STM32H5, some fast channels are available: fast analog inputs + * coming from GPIO pads (ADC_IN0..5). + * @rmtoll OFR1 OFFSET1_CH LL_ADC_GetOffsetChannel\n + * OFR2 OFFSET2_CH LL_ADC_GetOffsetChannel\n + * OFR3 OFFSET3_CH LL_ADC_GetOffsetChannel\n + * OFR4 OFFSET4_CH LL_ADC_GetOffsetChannel + * @param ADCx ADC instance + * @param Offsety This parameter can be one of the following values: + * @arg @ref LL_ADC_OFFSET_1 + * @arg @ref LL_ADC_OFFSET_2 + * @arg @ref LL_ADC_OFFSET_3 + * @arg @ref LL_ADC_OFFSET_4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 (3) + * @arg @ref LL_ADC_CHANNEL_1 (3) + * @arg @ref LL_ADC_CHANNEL_2 (3) + * @arg @ref LL_ADC_CHANNEL_3 (3) + * @arg @ref LL_ADC_CHANNEL_4 (3) + * @arg @ref LL_ADC_CHANNEL_5 (3) + * @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_19 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1)(4) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1)(4) + * @arg @ref LL_ADC_CHANNEL_VBAT (2)(4) + * @arg @ref LL_ADC_CHANNEL_VDDCORE (2)(4) + * + * (1) On STM32H563xx/573xx, parameter available only on ADC instance: ADC1.\n + * (2) On STM32H563xx/573xx, parameter available only on ADC instance: ADC2.\n + * (3) On STM32H5, fast channel allows: 2.5 (sampling) + 12.5 (conversion 12b) = 15 ADC clock cycles (fADC) + * Other channels are slow channels: 6.5 (sampling) + 12.5 (conversion 12b) = 19 ADC clock cycles (fADC) + * (4) 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_GetOffsetChannel(const ADC_TypeDef *ADCx, uint32_t Offsety) +{ + const __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->OFR1, Offsety); + + return (uint32_t) READ_BIT(*preg, ADC_OFR1_OFFSET1_CH); +} + +/** + * @brief Get for the ADC selected offset instance 1, 2, 3 or 4: + * Offset level (offset to be subtracted from the raw + * converted data). + * @note 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 OFR1 OFFSET1 LL_ADC_GetOffsetLevel\n + * OFR2 OFFSET2 LL_ADC_GetOffsetLevel\n + * OFR3 OFFSET3 LL_ADC_GetOffsetLevel\n + * OFR4 OFFSET4 LL_ADC_GetOffsetLevel + * @param ADCx ADC instance + * @param Offsety This parameter can be one of the following values: + * @arg @ref LL_ADC_OFFSET_1 + * @arg @ref LL_ADC_OFFSET_2 + * @arg @ref LL_ADC_OFFSET_3 + * @arg @ref LL_ADC_OFFSET_4 + * @retval Value between Min_Data=0x000 and Max_Data=0xFFF + */ +__STATIC_INLINE uint32_t LL_ADC_GetOffsetLevel(const ADC_TypeDef *ADCx, uint32_t Offsety) +{ + const __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->OFR1, Offsety); + + return (uint32_t) READ_BIT(*preg, ADC_OFR1_OFFSET1); +} + +/** + * @brief Set for the ADC selected offset instance 1, 2, 3 or 4: + * force offset state disable or enable + * without modifying offset channel or offset value. + * @note This function should be needed only in case of offset to be + * enabled-disabled dynamically, and should not be needed in other cases: + * function LL_ADC_SetOffset() automatically enables the offset. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on either groups regular or injected. + * @rmtoll OFR1 OFFSET1_EN LL_ADC_SetOffsetState\n + * OFR2 OFFSET2_EN LL_ADC_SetOffsetState\n + * OFR3 OFFSET3_EN LL_ADC_SetOffsetState\n + * OFR4 OFFSET4_EN LL_ADC_SetOffsetState + * @param ADCx ADC instance + * @param Offsety This parameter can be one of the following values: + * @arg @ref LL_ADC_OFFSET_1 + * @arg @ref LL_ADC_OFFSET_2 + * @arg @ref LL_ADC_OFFSET_3 + * @arg @ref LL_ADC_OFFSET_4 + * @param OffsetState This parameter can be one of the following values: + * @arg @ref LL_ADC_OFFSET_DISABLE + * @arg @ref LL_ADC_OFFSET_ENABLE + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetOffsetState(ADC_TypeDef *ADCx, uint32_t Offsety, uint32_t OffsetState) +{ + __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->OFR1, Offsety); + + MODIFY_REG(*preg, + ADC_OFR1_OFFSET1_EN, + OffsetState); +} + +/** + * @brief Get for the ADC selected offset instance 1, 2, 3 or 4: + * offset state disabled or enabled. + * @rmtoll OFR1 OFFSET1_EN LL_ADC_GetOffsetState\n + * OFR2 OFFSET2_EN LL_ADC_GetOffsetState\n + * OFR3 OFFSET3_EN LL_ADC_GetOffsetState\n + * OFR4 OFFSET4_EN LL_ADC_GetOffsetState + * @param ADCx ADC instance + * @param Offsety This parameter can be one of the following values: + * @arg @ref LL_ADC_OFFSET_1 + * @arg @ref LL_ADC_OFFSET_2 + * @arg @ref LL_ADC_OFFSET_3 + * @arg @ref LL_ADC_OFFSET_4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_OFFSET_DISABLE + * @arg @ref LL_ADC_OFFSET_ENABLE + */ +__STATIC_INLINE uint32_t LL_ADC_GetOffsetState(const ADC_TypeDef *ADCx, uint32_t Offsety) +{ + const __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->OFR1, Offsety); + + return (uint32_t) READ_BIT(*preg, ADC_OFR1_OFFSET1_EN); +} + +/** + * @brief Set for the ADC selected offset instance 1, 2, 3 or 4: + * choose offset sign. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on either groups regular or injected. + * @rmtoll OFR1 OFFSETPOS LL_ADC_SetOffsetSign\n + * OFR2 OFFSETPOS LL_ADC_SetOffsetSign\n + * OFR3 OFFSETPOS LL_ADC_SetOffsetSign\n + * OFR4 OFFSETPOS LL_ADC_SetOffsetSign + * @param ADCx ADC instance + * @param Offsety This parameter can be one of the following values: + * @arg @ref LL_ADC_OFFSET_1 + * @arg @ref LL_ADC_OFFSET_2 + * @arg @ref LL_ADC_OFFSET_3 + * @arg @ref LL_ADC_OFFSET_4 + * @param OffsetSign This parameter can be one of the following values: + * @arg @ref LL_ADC_OFFSET_SIGN_NEGATIVE + * @arg @ref LL_ADC_OFFSET_SIGN_POSITIVE + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetOffsetSign(ADC_TypeDef *ADCx, uint32_t Offsety, uint32_t OffsetSign) +{ + __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->OFR1, Offsety); + + MODIFY_REG(*preg, + ADC_OFR1_OFFSETPOS, + OffsetSign); +} + +/** + * @brief Get for the ADC selected offset instance 1, 2, 3 or 4: + * offset sign if positive or negative. + * @rmtoll OFR1 OFFSETPOS LL_ADC_GetOffsetSign\n + * OFR2 OFFSETPOS LL_ADC_GetOffsetSign\n + * OFR3 OFFSETPOS LL_ADC_GetOffsetSign\n + * OFR4 OFFSETPOS LL_ADC_GetOffsetSign + * @param ADCx ADC instance + * @param Offsety This parameter can be one of the following values: + * @arg @ref LL_ADC_OFFSET_1 + * @arg @ref LL_ADC_OFFSET_2 + * @arg @ref LL_ADC_OFFSET_3 + * @arg @ref LL_ADC_OFFSET_4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_OFFSET_SIGN_NEGATIVE + * @arg @ref LL_ADC_OFFSET_SIGN_POSITIVE + */ +__STATIC_INLINE uint32_t LL_ADC_GetOffsetSign(const ADC_TypeDef *ADCx, uint32_t Offsety) +{ + const __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->OFR1, Offsety); + + return (uint32_t) READ_BIT(*preg, ADC_OFR1_OFFSETPOS); +} + +/** + * @brief Set for the ADC selected offset instance 1, 2, 3 or 4: + * choose offset saturation mode. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on either groups regular or injected. + * @rmtoll OFR1 SATEN LL_ADC_SetOffsetSaturation\n + * OFR2 SATEN LL_ADC_SetOffsetSaturation\n + * OFR3 SATEN LL_ADC_SetOffsetSaturation\n + * OFR4 SATEN LL_ADC_SetOffsetSaturation + * @param ADCx ADC instance + * @param Offsety This parameter can be one of the following values: + * @arg @ref LL_ADC_OFFSET_1 + * @arg @ref LL_ADC_OFFSET_2 + * @arg @ref LL_ADC_OFFSET_3 + * @arg @ref LL_ADC_OFFSET_4 + * @param OffsetSaturation This parameter can be one of the following values: + * @arg @ref LL_ADC_OFFSET_SATURATION_ENABLE + * @arg @ref LL_ADC_OFFSET_SATURATION_DISABLE + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetOffsetSaturation(ADC_TypeDef *ADCx, uint32_t Offsety, uint32_t OffsetSaturation) +{ + __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->OFR1, Offsety); + + MODIFY_REG(*preg, + ADC_OFR1_SATEN, + OffsetSaturation); +} + +/** + * @brief Get for the ADC selected offset instance 1, 2, 3 or 4: + * offset saturation if enabled or disabled. + * @rmtoll OFR1 SATEN LL_ADC_GetOffsetSaturation\n + * OFR2 SATEN LL_ADC_GetOffsetSaturation\n + * OFR3 SATEN LL_ADC_GetOffsetSaturation\n + * OFR4 SATEN LL_ADC_GetOffsetSaturation + * @param ADCx ADC instance + * @param Offsety This parameter can be one of the following values: + * @arg @ref LL_ADC_OFFSET_1 + * @arg @ref LL_ADC_OFFSET_2 + * @arg @ref LL_ADC_OFFSET_3 + * @arg @ref LL_ADC_OFFSET_4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_OFFSET_SATURATION_ENABLE + * @arg @ref LL_ADC_OFFSET_SATURATION_DISABLE + */ +__STATIC_INLINE uint32_t LL_ADC_GetOffsetSaturation(const ADC_TypeDef *ADCx, uint32_t Offsety) +{ + const __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->OFR1, Offsety); + + return (uint32_t) READ_BIT(*preg, ADC_OFR1_SATEN); +} + +#if defined(ADC_SMPR1_SMPPLUS) +/** + * @brief Set ADC sampling time common configuration impacting + * settings of sampling time channel wise. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on either groups regular or injected. + * @rmtoll SMPR1 SMPPLUS LL_ADC_SetSamplingTimeCommonConfig + * @param ADCx ADC instance + * @param SamplingTimeCommonConfig This parameter can be one of the following values: + * @arg @ref LL_ADC_SAMPLINGTIME_COMMON_DEFAULT + * @arg @ref LL_ADC_SAMPLINGTIME_COMMON_3C5_REPL_2C5 + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetSamplingTimeCommonConfig(ADC_TypeDef *ADCx, uint32_t SamplingTimeCommonConfig) +{ + MODIFY_REG(ADCx->SMPR1, ADC_SMPR1_SMPPLUS, SamplingTimeCommonConfig); +} + +/** + * @brief Get ADC sampling time common configuration impacting + * settings of sampling time channel wise. + * @rmtoll SMPR1 SMPPLUS LL_ADC_GetSamplingTimeCommonConfig + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_SAMPLINGTIME_COMMON_DEFAULT + * @arg @ref LL_ADC_SAMPLINGTIME_COMMON_3C5_REPL_2C5 + */ +__STATIC_INLINE uint32_t LL_ADC_GetSamplingTimeCommonConfig(const ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->SMPR1, ADC_SMPR1_SMPPLUS)); +} +#endif /* ADC_SMPR1_SMPPLUS */ + +/** + * @} + */ + +/** @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 peripheral (timer event, + * external interrupt line). + * @note On this STM32 series, setting trigger source to external trigger + * also set trigger polarity to rising edge + * (default setting for compatibility with some ADC on other + * STM32 series having this setting set by HW default value). + * In case of need to modify trigger edge, use + * function @ref LL_ADC_REG_SetTriggerEdge(). + * @note Availability of parameters of trigger sources from timer + * depends on timers availability on the selected device. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on group regular. + * @rmtoll CFGR EXTSEL LL_ADC_REG_SetTriggerSource\n + * CFGR 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_TRGO + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM1_TRGO2 + * @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_TRGO + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM2_CH2 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM3_TRGO + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM3_CH4 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM4_TRGO (1) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM4_CH4 (1) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM6_TRGO + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM7_TRGO (2) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM8_TRGO (1) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM8_TRGO2 (1) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM15_TRGO (1) + * @arg @ref LL_ADC_REG_TRIG_EXT_LPTIM1_CH1 + * @arg @ref LL_ADC_REG_TRIG_EXT_LPTIM2_CH1 + * @arg @ref LL_ADC_REG_TRIG_EXT_EXTI_LINE11 + * @arg @ref LL_ADC_REG_TRIG_EXT_EXTI_LINE15 + * + * (1) On STM32H5 series, parameter specific to devices: STM32H563/H573xx. + * (2) On STM32H5 series, parameter specific to devices: STM32H503xx. + * @retval None + */ +__STATIC_INLINE void LL_ADC_REG_SetTriggerSource(ADC_TypeDef *ADCx, uint32_t TriggerSource) +{ + MODIFY_REG(ADCx->CFGR, ADC_CFGR_EXTEN | ADC_CFGR_EXTSEL, TriggerSource); +} + +/** + * @brief Get ADC group regular conversion trigger source: + * internal (SW start) or from external peripheral (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 CFGR EXTSEL LL_ADC_REG_GetTriggerSource\n + * CFGR 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_TRGO + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM1_TRGO2 + * @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_TRGO + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM2_CH2 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM3_TRGO + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM3_CH4 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM4_TRGO (1) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM4_CH4 (1) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM6_TRGO + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM7_TRGO (2) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM8_TRGO (1) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM8_TRGO2 (1) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM15_TRGO (1) + * @arg @ref LL_ADC_REG_TRIG_EXT_LPTIM1_CH1 + * @arg @ref LL_ADC_REG_TRIG_EXT_LPTIM2_CH1 + * @arg @ref LL_ADC_REG_TRIG_EXT_EXTI_LINE11 + * @arg @ref LL_ADC_REG_TRIG_EXT_EXTI_LINE15 + * + * (1) On STM32H5 series, parameter specific to devices: STM32H563/H573xx. + * (2) On STM32H5 series, parameter specific to devices: STM32H503xx. + */ +__STATIC_INLINE uint32_t LL_ADC_REG_GetTriggerSource(const ADC_TypeDef *ADCx) +{ + __IO uint32_t trigger_source = READ_BIT(ADCx->CFGR, ADC_CFGR_EXTSEL | ADC_CFGR_EXTEN); + + /* Value for shift of {0; 4; 8; 12} depending on value of bitfield */ + /* corresponding to ADC_CFGR_EXTEN {0; 1; 2; 3}. */ + uint32_t shift_exten = ((trigger_source & ADC_CFGR_EXTEN) >> (ADC_REG_TRIG_EXTEN_BITOFFSET_POS - 2UL)); + + /* Set bitfield corresponding to ADC_CFGR_EXTEN and ADC_CFGR_EXTSEL */ + /* to match with triggers literals definition. */ + return ((trigger_source + & (ADC_REG_TRIG_SOURCE_MASK >> shift_exten) & ADC_CFGR_EXTSEL) + | ((ADC_REG_TRIG_EDGE_MASK >> shift_exten) & ADC_CFGR_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 CFGR 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->CFGR, ADC_CFGR_EXTEN) == (LL_ADC_REG_TRIG_SOFTWARE & ADC_CFGR_EXTEN)) ? 1UL : 0UL); +} + +/** + * @brief Set ADC group regular conversion trigger polarity. + * @note Applicable only for trigger source set to external trigger. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on group regular. + * @rmtoll CFGR EXTEN LL_ADC_REG_SetTriggerEdge + * @param ADCx ADC instance + * @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 + * @retval None + */ +__STATIC_INLINE void LL_ADC_REG_SetTriggerEdge(ADC_TypeDef *ADCx, uint32_t ExternalTriggerEdge) +{ + MODIFY_REG(ADCx->CFGR, ADC_CFGR_EXTEN, ExternalTriggerEdge); +} + +/** + * @brief Get ADC group regular conversion trigger polarity. + * @note Applicable only for trigger source set to external trigger. + * @rmtoll CFGR 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->CFGR, ADC_CFGR_EXTEN)); +} + +/** + * @brief Set ADC sampling mode. + * @note This function set the ADC conversion sampling mode + * @note This mode applies to regular group only. + * @note Set sampling mode is applied to all conversion of regular group. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on group regular. + * @rmtoll CFGR2 BULB LL_ADC_REG_SetSamplingMode\n + * CFGR2 SMPTRIG LL_ADC_REG_SetSamplingMode + * @param ADCx ADC instance + * @param SamplingMode This parameter can be one of the following values: + * @arg @ref LL_ADC_REG_SAMPLING_MODE_NORMAL + * @arg @ref LL_ADC_REG_SAMPLING_MODE_BULB + * @arg @ref LL_ADC_REG_SAMPLING_MODE_TRIGGER_CONTROLED + * @retval None + */ +__STATIC_INLINE void LL_ADC_REG_SetSamplingMode(ADC_TypeDef *ADCx, uint32_t SamplingMode) +{ + MODIFY_REG(ADCx->CFGR2, ADC_CFGR2_BULB | ADC_CFGR2_SMPTRIG, SamplingMode); +} + +/** + * @brief Get the ADC sampling mode + * @rmtoll CFGR2 BULB LL_ADC_REG_GetSamplingMode\n + * CFGR2 SMPTRIG LL_ADC_REG_GetSamplingMode + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_REG_SAMPLING_MODE_NORMAL + * @arg @ref LL_ADC_REG_SAMPLING_MODE_BULB + * @arg @ref LL_ADC_REG_SAMPLING_MODE_TRIGGER_CONTROLED + */ +__STATIC_INLINE uint32_t LL_ADC_REG_GetSamplingMode(const ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CFGR2, ADC_CFGR2_BULB | ADC_CFGR2_SMPTRIG)); +} + +/** + * @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 Sequencer disabled is equivalent to sequencer of 1 rank: + * ADC conversion on only 1 channel. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on group regular. + * @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 Sequencer disabled is equivalent to sequencer of 1 rank: + * ADC conversion on only 1 channel. + * @rmtoll SQR1 L LL_ADC_REG_GetSequencerLength + * @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. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on group regular. + * @rmtoll CFGR DISCEN LL_ADC_REG_SetSequencerDiscont\n + * CFGR 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->CFGR, ADC_CFGR_DISCEN | ADC_CFGR_DISCNUM, SeqDiscont); +} + +/** + * @brief Get ADC group regular sequencer discontinuous mode: + * sequence subdivided and scan conversions interrupted every selected + * number of ranks. + * @rmtoll CFGR DISCEN LL_ADC_REG_GetSequencerDiscont\n + * CFGR 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->CFGR, ADC_CFGR_DISCEN | ADC_CFGR_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(). + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on group regular. + * @rmtoll SQR1 SQ1 LL_ADC_REG_SetSequencerRanks\n + * SQR1 SQ2 LL_ADC_REG_SetSequencerRanks\n + * SQR1 SQ3 LL_ADC_REG_SetSequencerRanks\n + * SQR1 SQ4 LL_ADC_REG_SetSequencerRanks\n + * SQR2 SQ5 LL_ADC_REG_SetSequencerRanks\n + * SQR2 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 + * SQR3 SQ10 LL_ADC_REG_SetSequencerRanks\n + * SQR3 SQ11 LL_ADC_REG_SetSequencerRanks\n + * SQR3 SQ12 LL_ADC_REG_SetSequencerRanks\n + * SQR3 SQ13 LL_ADC_REG_SetSequencerRanks\n + * SQR3 SQ14 LL_ADC_REG_SetSequencerRanks\n + * SQR4 SQ15 LL_ADC_REG_SetSequencerRanks\n + * SQR4 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 (3) + * @arg @ref LL_ADC_CHANNEL_1 (3) + * @arg @ref LL_ADC_CHANNEL_2 (3) + * @arg @ref LL_ADC_CHANNEL_3 (3) + * @arg @ref LL_ADC_CHANNEL_4 (3) + * @arg @ref LL_ADC_CHANNEL_5 (3) + * @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_19 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1) + * @arg @ref LL_ADC_CHANNEL_VBAT (2) + * @arg @ref LL_ADC_CHANNEL_VDDCORE (2) + * + * (1) On STM32H563xx/573xx, parameter available only on ADC instance: ADC1.\n + * (2) On STM32H563xx/573xx, parameter available only on ADC instance: ADC2.\n + * (3) On STM32H5, fast channel allows: 2.5 (sampling) + 12.5 (conversion 12b) = 15 ADC clock cycles (fADC) + * Other channels are slow channels: 6.5 (sampling) + 12.5 (conversion 12b) = 19 ADC clock cycles (fADC) + * @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, + ((Rank & ADC_REG_SQRX_REGOFFSET_MASK) >> ADC_SQRX_REGOFFSET_POS)); + + MODIFY_REG(*preg, + ADC_CHANNEL_ID_NUMBER_MASK_POSBIT0 << (Rank & ADC_REG_RANK_ID_SQRX_MASK), + ((Channel & ADC_CHANNEL_ID_NUMBER_MASK) >> ADC_CHANNEL_ID_NUMBER_BITOFFSET_POS) + << (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 SQR1 SQ1 LL_ADC_REG_GetSequencerRanks\n + * SQR1 SQ2 LL_ADC_REG_GetSequencerRanks\n + * SQR1 SQ3 LL_ADC_REG_GetSequencerRanks\n + * SQR1 SQ4 LL_ADC_REG_GetSequencerRanks\n + * SQR2 SQ5 LL_ADC_REG_GetSequencerRanks\n + * SQR2 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 + * SQR3 SQ10 LL_ADC_REG_GetSequencerRanks\n + * SQR3 SQ11 LL_ADC_REG_GetSequencerRanks\n + * SQR3 SQ12 LL_ADC_REG_GetSequencerRanks\n + * SQR3 SQ13 LL_ADC_REG_GetSequencerRanks\n + * SQR3 SQ14 LL_ADC_REG_GetSequencerRanks\n + * SQR4 SQ15 LL_ADC_REG_GetSequencerRanks\n + * SQR4 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 (3) + * @arg @ref LL_ADC_CHANNEL_1 (3) + * @arg @ref LL_ADC_CHANNEL_2 (3) + * @arg @ref LL_ADC_CHANNEL_3 (3) + * @arg @ref LL_ADC_CHANNEL_4 (3) + * @arg @ref LL_ADC_CHANNEL_5 (3) + * @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_19 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1)(4) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1)(4) + * @arg @ref LL_ADC_CHANNEL_VBAT (2)(4) + * @arg @ref LL_ADC_CHANNEL_VDDCORE (2)(4) + * + * (1) On STM32H563xx/573xx, parameter available only on ADC instance: ADC1.\n + * (2) On STM32H563xx/573xx, parameter available only on ADC instance: ADC2.\n + * (3) On STM32H5, fast channel allows: 2.5 (sampling) + 12.5 (conversion 12b) = 15 ADC clock cycles (fADC) + * Other channels are slow channels: 6.5 (sampling) + 12.5 (conversion 12b) = 19 ADC clock cycles (fADC) + * (4) 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) +{ + const __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->SQR1, + ((Rank & ADC_REG_SQRX_REGOFFSET_MASK) >> ADC_SQRX_REGOFFSET_POS)); + + return (uint32_t)((READ_BIT(*preg, + ADC_CHANNEL_ID_NUMBER_MASK_POSBIT0 << (Rank & ADC_REG_RANK_ID_SQRX_MASK)) + >> (Rank & ADC_REG_RANK_ID_SQRX_MASK)) << ADC_CHANNEL_ID_NUMBER_BITOFFSET_POS + ); +} + +/** + * @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. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on group regular. + * @rmtoll CFGR 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->CFGR, ADC_CFGR_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 CFGR 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->CFGR, ADC_CFGR_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(). + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on either groups regular or injected. + * @rmtoll CFGR DMAEN LL_ADC_REG_SetDMATransfer\n + * CFGR DMACFG 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->CFGR, ADC_CFGR_DMAEN | ADC_CFGR_DMACFG, 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 CFGR DMAEN LL_ADC_REG_GetDMATransfer\n + * CFGR DMACFG 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->CFGR, ADC_CFGR_DMAEN | ADC_CFGR_DMACFG)); +} + +/** + * @brief Set ADC group regular behavior in case of overrun: + * data preserved or overwritten. + * @note Compatibility with devices without feature overrun: + * other devices without this feature have a behavior + * equivalent to data overwritten. + * The default setting of overrun is data preserved. + * Therefore, for compatibility with all devices, parameter + * overrun should be set to data overwritten. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on group regular. + * @rmtoll CFGR OVRMOD LL_ADC_REG_SetOverrun + * @param ADCx ADC instance + * @param Overrun This parameter can be one of the following values: + * @arg @ref LL_ADC_REG_OVR_DATA_PRESERVED + * @arg @ref LL_ADC_REG_OVR_DATA_OVERWRITTEN + * @retval None + */ +__STATIC_INLINE void LL_ADC_REG_SetOverrun(ADC_TypeDef *ADCx, uint32_t Overrun) +{ + MODIFY_REG(ADCx->CFGR, ADC_CFGR_OVRMOD, Overrun); +} + +/** + * @brief Get ADC group regular behavior in case of overrun: + * data preserved or overwritten. + * @rmtoll CFGR OVRMOD LL_ADC_REG_GetOverrun + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_REG_OVR_DATA_PRESERVED + * @arg @ref LL_ADC_REG_OVR_DATA_OVERWRITTEN + */ +__STATIC_INLINE uint32_t LL_ADC_REG_GetOverrun(const ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CFGR, ADC_CFGR_OVRMOD)); +} + +/** + * @} + */ + +/** @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 peripheral (timer event, + * external interrupt line). + * @note On this STM32 series, setting trigger source to external trigger + * also set trigger polarity to rising edge + * (default setting for compatibility with some ADC on other + * STM32 series having this setting set by HW default value). + * In case of need to modify trigger edge, use + * function @ref LL_ADC_INJ_SetTriggerEdge(). + * @note Availability of parameters of trigger sources from timer + * depends on timers availability on the selected device. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must not be disabled. Can be enabled with or without conversion + * on going on either groups regular or injected. + * @rmtoll JSQR JEXTSEL LL_ADC_INJ_SetTriggerSource\n + * JSQR 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_TRGO + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM1_TRGO2 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM1_CH4 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM2_TRGO + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM2_CH1 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM3_TRGO + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM3_CH1 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM3_CH3 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM3_CH4 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM4_TRGO (1) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM6_TRGO + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM7_TRGO (2) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM8_TRGO (1) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM8_TRGO2 (1) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM8_CH4 (1) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM15_TRGO (1) + * @arg @ref LL_ADC_INJ_TRIG_EXT_LPTIM1_CH1 + * @arg @ref LL_ADC_INJ_TRIG_EXT_LPTIM2_CH1 + * @arg @ref LL_ADC_INJ_TRIG_EXT_EXTI_LINE15 + * + * (1) On STM32H5 series, parameter specific to devices: STM32H563/H573xx. + * (2) On STM32H5 series, parameter specific to devices: STM32H503xx. + * @retval None + */ +__STATIC_INLINE void LL_ADC_INJ_SetTriggerSource(ADC_TypeDef *ADCx, uint32_t TriggerSource) +{ + MODIFY_REG(ADCx->JSQR, ADC_JSQR_JEXTSEL | ADC_JSQR_JEXTEN, TriggerSource); +} + +/** + * @brief Get ADC group injected conversion trigger source: + * internal (SW start) or from external peripheral (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 JSQR JEXTSEL LL_ADC_INJ_GetTriggerSource\n + * JSQR 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_TRGO + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM1_TRGO2 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM1_CH4 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM2_TRGO + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM2_CH1 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM3_TRGO + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM3_CH1 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM3_CH3 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM3_CH4 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM4_TRGO (1) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM6_TRGO + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM7_TRGO (2) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM8_TRGO (1) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM8_TRGO2 (1) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM8_CH4 (1) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM15_TRGO (1) + * @arg @ref LL_ADC_INJ_TRIG_EXT_LPTIM1_CH1 + * @arg @ref LL_ADC_INJ_TRIG_EXT_LPTIM2_CH1 + * @arg @ref LL_ADC_INJ_TRIG_EXT_EXTI_LINE15 + * + * (1) On STM32H5 series, parameter specific to devices: STM32H563/H573xx. + * (2) On STM32H5 series, parameter specific to devices: STM32H503xx. + */ +__STATIC_INLINE uint32_t LL_ADC_INJ_GetTriggerSource(const ADC_TypeDef *ADCx) +{ + __IO uint32_t trigger_source = READ_BIT(ADCx->JSQR, ADC_JSQR_JEXTSEL | ADC_JSQR_JEXTEN); + + /* Value for shift of {0; 4; 8; 12} depending on value of bitfield */ + /* corresponding to ADC_JSQR_JEXTEN {0; 1; 2; 3}. */ + uint32_t shift_jexten = ((trigger_source & ADC_JSQR_JEXTEN) >> (ADC_INJ_TRIG_EXTEN_BITOFFSET_POS - 2UL)); + + /* Set bitfield corresponding to ADC_JSQR_JEXTEN and ADC_JSQR_JEXTSEL */ + /* to match with triggers literals definition. */ + return ((trigger_source + & (ADC_INJ_TRIG_SOURCE_MASK >> shift_jexten) & ADC_JSQR_JEXTSEL) + | ((ADC_INJ_TRIG_EDGE_MASK >> shift_jexten) & ADC_JSQR_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 JSQR 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->JSQR, ADC_JSQR_JEXTEN) == (LL_ADC_INJ_TRIG_SOFTWARE & ADC_JSQR_JEXTEN)) ? 1UL : 0UL); +} + +/** + * @brief Set ADC group injected conversion trigger polarity. + * Applicable only for trigger source set to external trigger. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must not be disabled. Can be enabled with or without conversion + * on going on either groups regular or injected. + * @rmtoll JSQR JEXTEN LL_ADC_INJ_SetTriggerEdge + * @param ADCx ADC instance + * @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 + * @retval None + */ +__STATIC_INLINE void LL_ADC_INJ_SetTriggerEdge(ADC_TypeDef *ADCx, uint32_t ExternalTriggerEdge) +{ + MODIFY_REG(ADCx->JSQR, ADC_JSQR_JEXTEN, ExternalTriggerEdge); +} + +/** + * @brief Get ADC group injected conversion trigger polarity. + * Applicable only for trigger source set to external trigger. + * @rmtoll JSQR 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->JSQR, ADC_JSQR_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 Sequencer disabled is equivalent to sequencer of 1 rank: + * ADC conversion on only 1 channel. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must not be disabled. Can be enabled with or without conversion + * on going on either groups regular or injected. + * @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 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 CFGR JDISCEN 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->CFGR, ADC_CFGR_JDISCEN, SeqDiscont); +} + +/** + * @brief Get ADC group injected sequencer discontinuous mode: + * sequence subdivided and scan conversions interrupted every selected + * number of ranks. + * @rmtoll CFGR JDISCEN LL_ADC_INJ_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->CFGR, ADC_CFGR_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(). + * @note On STM32H5, some fast channels are available: fast analog inputs + * coming from GPIO pads (ADC_IN0..5). + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must not be disabled. Can be enabled with or without conversion + * on going on either groups regular or injected. + * @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 (3) + * @arg @ref LL_ADC_CHANNEL_1 (3) + * @arg @ref LL_ADC_CHANNEL_2 (3) + * @arg @ref LL_ADC_CHANNEL_3 (3) + * @arg @ref LL_ADC_CHANNEL_4 (3) + * @arg @ref LL_ADC_CHANNEL_5 (3) + * @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_19 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1) + * @arg @ref LL_ADC_CHANNEL_VBAT (2) + * @arg @ref LL_ADC_CHANNEL_VDDCORE (2) + * + * (1) On STM32H563xx/573xx, parameter available only on ADC instance: ADC1.\n + * (2) On STM32H563xx/573xx, parameter available only on ADC instance: ADC2.\n + * (3) On STM32H5, fast channel allows: 2.5 (sampling) + 12.5 (conversion 12b) = 15 ADC clock cycles (fADC) + * Other channels are slow channels: 6.5 (sampling) + 12.5 (conversion 12b) = 19 ADC clock cycles (fADC) + * @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. */ + MODIFY_REG(ADCx->JSQR, + (ADC_CHANNEL_ID_NUMBER_MASK >> ADC_CHANNEL_ID_NUMBER_BITOFFSET_POS) + << (Rank & ADC_INJ_RANK_ID_JSQR_MASK), + ((Channel & ADC_CHANNEL_ID_NUMBER_MASK) >> ADC_CHANNEL_ID_NUMBER_BITOFFSET_POS) + << (Rank & ADC_INJ_RANK_ID_JSQR_MASK)); +} + +/** + * @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_GetSequencerRanks\n + * JSQR JSQ2 LL_ADC_INJ_GetSequencerRanks\n + * JSQR JSQ3 LL_ADC_INJ_GetSequencerRanks\n + * JSQR JSQ4 LL_ADC_INJ_GetSequencerRanks + * @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 (3) + * @arg @ref LL_ADC_CHANNEL_1 (3) + * @arg @ref LL_ADC_CHANNEL_2 (3) + * @arg @ref LL_ADC_CHANNEL_3 (3) + * @arg @ref LL_ADC_CHANNEL_4 (3) + * @arg @ref LL_ADC_CHANNEL_5 (3) + * @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_19 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1)(4) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1)(4) + * @arg @ref LL_ADC_CHANNEL_VBAT (2)(4) + * @arg @ref LL_ADC_CHANNEL_VDDCORE (2)(4) + * + * (1) On STM32H563xx/573xx, parameter available only on ADC instance: ADC1.\n + * (2) On STM32H563xx/573xx, parameter available only on ADC instance: ADC2.\n + * (3) On STM32H5, fast channel allows: 2.5 (sampling) + 12.5 (conversion 12b) = 15 ADC clock cycles (fADC) + * Other channels are slow channels: 6.5 (sampling) + 12.5 (conversion 12b) = 19 ADC clock cycles (fADC) + * (4) 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) +{ + return (uint32_t)((READ_BIT(ADCx->JSQR, + (ADC_CHANNEL_ID_NUMBER_MASK >> ADC_CHANNEL_ID_NUMBER_BITOFFSET_POS) + << (Rank & ADC_INJ_RANK_ID_JSQR_MASK)) + >> (Rank & ADC_INJ_RANK_ID_JSQR_MASK)) << ADC_CHANNEL_ID_NUMBER_BITOFFSET_POS + ); +} + +/** + * @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. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on either groups regular or injected. + * @rmtoll CFGR 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->CFGR, ADC_CFGR_JAUTO, TrigAuto); +} + +/** + * @brief Get ADC group injected conversion trigger: + * independent or from ADC group regular. + * @rmtoll CFGR 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->CFGR, ADC_CFGR_JAUTO)); +} + +/** + * @brief Set ADC group injected contexts queue mode. + * @note A context is a setting of group injected sequencer: + * - group injected trigger + * - sequencer length + * - sequencer ranks + * If contexts queue is disabled: + * - only 1 sequence can be configured + * and is active perpetually. + * If contexts queue is enabled: + * - up to 2 contexts can be queued + * and are checked in and out as a FIFO stack (first-in, first-out). + * - If a new context is set when queues is full, error is triggered + * by interruption "Injected Queue Overflow". + * - Two behaviors are possible when all contexts have been processed: + * the contexts queue can maintain the last context active perpetually + * or can be empty and injected group triggers are disabled. + * - Triggers can be only external (not internal SW start) + * - Caution: The sequence must be fully configured in one time + * (one write of register JSQR makes a check-in of a new context + * into the queue). + * Therefore functions to set separately injected trigger and + * sequencer channels cannot be used, register JSQR must be set + * using function @ref LL_ADC_INJ_ConfigQueueContext(). + * @note This parameter can be modified only when no conversion is on going + * on either groups regular or injected. + * @note A modification of the context mode (bit JQDIS) causes the contexts + * queue to be flushed and the register JSQR is cleared. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on either groups regular or injected. + * @rmtoll CFGR JQM LL_ADC_INJ_SetQueueMode\n + * CFGR JQDIS LL_ADC_INJ_SetQueueMode + * @param ADCx ADC instance + * @param QueueMode This parameter can be one of the following values: + * @arg @ref LL_ADC_INJ_QUEUE_DISABLE + * @arg @ref LL_ADC_INJ_QUEUE_2CONTEXTS_LAST_ACTIVE + * @arg @ref LL_ADC_INJ_QUEUE_2CONTEXTS_END_EMPTY + * @retval None + */ +__STATIC_INLINE void LL_ADC_INJ_SetQueueMode(ADC_TypeDef *ADCx, uint32_t QueueMode) +{ + MODIFY_REG(ADCx->CFGR, ADC_CFGR_JQM | ADC_CFGR_JQDIS, QueueMode); +} + +/** + * @brief Get ADC group injected context queue mode. + * @rmtoll CFGR JQM LL_ADC_INJ_GetQueueMode\n + * CFGR JQDIS LL_ADC_INJ_GetQueueMode + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_INJ_QUEUE_DISABLE + * @arg @ref LL_ADC_INJ_QUEUE_2CONTEXTS_LAST_ACTIVE + * @arg @ref LL_ADC_INJ_QUEUE_2CONTEXTS_END_EMPTY + */ +__STATIC_INLINE uint32_t LL_ADC_INJ_GetQueueMode(const ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CFGR, ADC_CFGR_JQM | ADC_CFGR_JQDIS)); +} + +/** + * @brief Set one context on ADC group injected that will be checked in + * contexts queue. + * @note A context is a setting of group injected sequencer: + * - group injected trigger + * - sequencer length + * - sequencer ranks + * This function is intended to be used when contexts queue is enabled, + * because the sequence must be fully configured in one time + * (functions to set separately injected trigger and sequencer channels + * cannot be used): + * Refer to function @ref LL_ADC_INJ_SetQueueMode(). + * @note In the contexts queue, only the active context can be read. + * The parameters of this function can be read using functions: + * @arg @ref LL_ADC_INJ_GetTriggerSource() + * @arg @ref LL_ADC_INJ_GetTriggerEdge() + * @arg @ref LL_ADC_INJ_GetSequencerRanks() + * @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(). + * @note On STM32H5, some fast channels are available: fast analog inputs + * coming from GPIO pads (ADC_IN0..5). + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must not be disabled. Can be enabled with or without conversion + * on going on either groups regular or injected. + * @rmtoll JSQR JEXTSEL LL_ADC_INJ_ConfigQueueContext\n + * JSQR JEXTEN LL_ADC_INJ_ConfigQueueContext\n + * JSQR JL LL_ADC_INJ_ConfigQueueContext\n + * JSQR JSQ1 LL_ADC_INJ_ConfigQueueContext\n + * JSQR JSQ2 LL_ADC_INJ_ConfigQueueContext\n + * JSQR JSQ3 LL_ADC_INJ_ConfigQueueContext\n + * JSQR JSQ4 LL_ADC_INJ_ConfigQueueContext + * @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_TRGO + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM1_TRGO2 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM1_CH4 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM2_TRGO + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM2_CH1 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM3_TRGO + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM3_CH1 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM3_CH3 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM3_CH4 + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM4_TRGO (1) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM6_TRGO + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM7_TRGO (2) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM8_TRGO (1) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM8_TRGO2 (1) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM8_CH4 (1) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM15_TRGO (1) + * @arg @ref LL_ADC_INJ_TRIG_EXT_LPTIM1_CH1 + * @arg @ref LL_ADC_INJ_TRIG_EXT_LPTIM2_CH1 + * @arg @ref LL_ADC_INJ_TRIG_EXT_EXTI_LINE15 + * + * (1) On STM32H5 series, parameter specific to devices: STM32H563/H573xx. + * (2) On STM32H5 series, parameter specific to devices: STM32H503xx. + * @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 + * + * Note: This parameter is discarded in case of SW start: + * parameter "TriggerSource" set to "LL_ADC_INJ_TRIG_SOFTWARE". + * @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 + * @param Rank1_Channel This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 (3) + * @arg @ref LL_ADC_CHANNEL_1 (3) + * @arg @ref LL_ADC_CHANNEL_2 (3) + * @arg @ref LL_ADC_CHANNEL_3 (3) + * @arg @ref LL_ADC_CHANNEL_4 (3) + * @arg @ref LL_ADC_CHANNEL_5 (3) + * @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_19 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1) + * @arg @ref LL_ADC_CHANNEL_VBAT (2) + * @arg @ref LL_ADC_CHANNEL_VDDCORE (2) + * + * (1) On STM32H563xx/573xx, parameter available only on ADC instance: ADC1.\n + * (2) On STM32H563xx/573xx, parameter available only on ADC instance: ADC2.\n + * (3) On STM32H5, fast channel allows: 2.5 (sampling) + 12.5 (conversion 12b) = 15 ADC clock cycles (fADC) + * Other channels are slow channels: 6.5 (sampling) + 12.5 (conversion 12b) = 19 ADC clock cycles (fADC) + * @param Rank2_Channel This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 (3) + * @arg @ref LL_ADC_CHANNEL_1 (3) + * @arg @ref LL_ADC_CHANNEL_2 (3) + * @arg @ref LL_ADC_CHANNEL_3 (3) + * @arg @ref LL_ADC_CHANNEL_4 (3) + * @arg @ref LL_ADC_CHANNEL_5 (3) + * @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_19 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1) + * @arg @ref LL_ADC_CHANNEL_VBAT (2) + * @arg @ref LL_ADC_CHANNEL_VDDCORE (2) + * + * (1) On STM32H563xx/573xx, parameter available only on ADC instance: ADC1.\n + * (2) On STM32H563xx/573xx, parameter available only on ADC instance: ADC2.\n + * (3) On STM32H5, fast channel allows: 2.5 (sampling) + 12.5 (conversion 12b) = 15 ADC clock cycles (fADC) + * Other channels are slow channels: 6.5 (sampling) + 12.5 (conversion 12b) = 19 ADC clock cycles (fADC) + * @param Rank3_Channel This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 (3) + * @arg @ref LL_ADC_CHANNEL_1 (3) + * @arg @ref LL_ADC_CHANNEL_2 (3) + * @arg @ref LL_ADC_CHANNEL_3 (3) + * @arg @ref LL_ADC_CHANNEL_4 (3) + * @arg @ref LL_ADC_CHANNEL_5 (3) + * @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_19 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1) + * @arg @ref LL_ADC_CHANNEL_VBAT (2) + * @arg @ref LL_ADC_CHANNEL_VDDCORE (2) + * + * (1) On STM32H563xx/573xx, parameter available only on ADC instance: ADC1.\n + * (2) On STM32H563xx/573xx, parameter available only on ADC instance: ADC2.\n + * (3) On STM32H5, fast channel allows: 2.5 (sampling) + 12.5 (conversion 12b) = 15 ADC clock cycles (fADC) + * Other channels are slow channels: 6.5 (sampling) + 12.5 (conversion 12b) = 19 ADC clock cycles (fADC) + * @param Rank4_Channel This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 (3) + * @arg @ref LL_ADC_CHANNEL_1 (3) + * @arg @ref LL_ADC_CHANNEL_2 (3) + * @arg @ref LL_ADC_CHANNEL_3 (3) + * @arg @ref LL_ADC_CHANNEL_4 (3) + * @arg @ref LL_ADC_CHANNEL_5 (3) + * @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_19 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1) + * @arg @ref LL_ADC_CHANNEL_VBAT (2) + * @arg @ref LL_ADC_CHANNEL_VDDCORE (2) + * + * (1) On STM32H563xx/573xx, parameter available only on ADC instance: ADC1.\n + * (2) On STM32H563xx/573xx, parameter available only on ADC instance: ADC2.\n + * (3) On STM32H5, fast channel allows: 2.5 (sampling) + 12.5 (conversion 12b) = 15 ADC clock cycles (fADC) + * Other channels are slow channels: 6.5 (sampling) + 12.5 (conversion 12b) = 19 ADC clock cycles (fADC) + * @retval None + */ +__STATIC_INLINE void LL_ADC_INJ_ConfigQueueContext(ADC_TypeDef *ADCx, + uint32_t TriggerSource, + uint32_t ExternalTriggerEdge, + uint32_t SequencerNbRanks, + uint32_t Rank1_Channel, + uint32_t Rank2_Channel, + uint32_t Rank3_Channel, + uint32_t Rank4_Channel) +{ + /* Set bits with content of parameter "Rankx_Channel" with bits position */ + /* in register depending on literal "LL_ADC_INJ_RANK_x". */ + /* Parameters "Rankx_Channel" and "LL_ADC_INJ_RANK_x" are used with masks */ + /* because containing other bits reserved for other purpose. */ + /* If parameter "TriggerSource" is set to SW start, then parameter */ + /* "ExternalTriggerEdge" is discarded. */ + uint32_t is_trigger_not_sw = (uint32_t)((TriggerSource != LL_ADC_INJ_TRIG_SOFTWARE) ? 1UL : 0UL); + MODIFY_REG(ADCx->JSQR, + ADC_JSQR_JEXTSEL | + ADC_JSQR_JEXTEN | + ADC_JSQR_JSQ4 | + ADC_JSQR_JSQ3 | + ADC_JSQR_JSQ2 | + ADC_JSQR_JSQ1 | + ADC_JSQR_JL, + (TriggerSource & ADC_JSQR_JEXTSEL) | + (ExternalTriggerEdge * (is_trigger_not_sw)) | + (((Rank4_Channel & ADC_CHANNEL_ID_NUMBER_MASK) >> ADC_CHANNEL_ID_NUMBER_BITOFFSET_POS) + << (LL_ADC_INJ_RANK_4 & ADC_INJ_RANK_ID_JSQR_MASK)) | + (((Rank3_Channel & ADC_CHANNEL_ID_NUMBER_MASK) >> ADC_CHANNEL_ID_NUMBER_BITOFFSET_POS) + << (LL_ADC_INJ_RANK_3 & ADC_INJ_RANK_ID_JSQR_MASK)) | + (((Rank2_Channel & ADC_CHANNEL_ID_NUMBER_MASK) >> ADC_CHANNEL_ID_NUMBER_BITOFFSET_POS) + << (LL_ADC_INJ_RANK_2 & ADC_INJ_RANK_ID_JSQR_MASK)) | + (((Rank1_Channel & ADC_CHANNEL_ID_NUMBER_MASK) >> ADC_CHANNEL_ID_NUMBER_BITOFFSET_POS) + << (LL_ADC_INJ_RANK_1 & ADC_INJ_RANK_ID_JSQR_MASK)) | + SequencerNbRanks + ); +} + +/** + * @} + */ + +/** @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. + * On this STM32 series, ADC processing time is: + * - 12.5 ADC clock cycles at ADC resolution 12 bits + * - 10.5 ADC clock cycles at ADC resolution 10 bits + * - 8.5 ADC clock cycles at ADC resolution 8 bits + * - 6.5 ADC clock cycles at ADC resolution 6 bits + * @note In case of ADC conversion of internal channel (VrefInt, + * temperature sensor, ...), a sampling time minimum value + * is required. + * Refer to device datasheet. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on either groups regular or injected. + * @rmtoll SMPR1 SMP0 LL_ADC_SetChannelSamplingTime\n + * SMPR1 SMP1 LL_ADC_SetChannelSamplingTime\n + * SMPR1 SMP2 LL_ADC_SetChannelSamplingTime\n + * SMPR1 SMP3 LL_ADC_SetChannelSamplingTime\n + * SMPR1 SMP4 LL_ADC_SetChannelSamplingTime\n + * SMPR1 SMP5 LL_ADC_SetChannelSamplingTime\n + * SMPR1 SMP6 LL_ADC_SetChannelSamplingTime\n + * SMPR1 SMP7 LL_ADC_SetChannelSamplingTime\n + * SMPR1 SMP8 LL_ADC_SetChannelSamplingTime\n + * SMPR1 SMP9 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP10 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP11 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP12 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP13 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP14 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP15 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP16 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP17 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP18 LL_ADC_SetChannelSamplingTime + * @param ADCx ADC instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 (3) + * @arg @ref LL_ADC_CHANNEL_1 (3) + * @arg @ref LL_ADC_CHANNEL_2 (3) + * @arg @ref LL_ADC_CHANNEL_3 (3) + * @arg @ref LL_ADC_CHANNEL_4 (3) + * @arg @ref LL_ADC_CHANNEL_5 (3) + * @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_19 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1) + * @arg @ref LL_ADC_CHANNEL_VBAT (2) + * @arg @ref LL_ADC_CHANNEL_VDDCORE (2) + * + * (1) On STM32H563xx/573xx, parameter available only on ADC instance: ADC1.\n + * (2) On STM32H563xx/573xx, parameter available only on ADC instance: ADC2.\n + * (3) On STM32H5, fast channel allows: 2.5 (sampling) + 12.5 (conversion 12b) = 15 ADC clock cycles (fADC) + * Other channels are slow channels: 6.5 (sampling) + 12.5 (conversion 12b) = 19 ADC clock cycles (fADC) + * @param SamplingTime This parameter can be one of the following values: + * @arg @ref LL_ADC_SAMPLINGTIME_2CYCLES_5 (1) + * @arg @ref LL_ADC_SAMPLINGTIME_6CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_12CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_24CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_47CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_92CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_247CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_640CYCLES_5 + * + * (1) On some devices, ADC sampling time 2.5 ADC clock cycles + * can be replaced by 3.5 ADC clock cycles. + * Refer to function @ref LL_ADC_SetSamplingTimeCommonConfig(). + * @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, + ((Channel & ADC_CHANNEL_SMPRX_REGOFFSET_MASK) >> ADC_SMPRX_REGOFFSET_POS)); + + MODIFY_REG(*preg, + ADC_SMPR1_SMP0 << ((Channel & ADC_CHANNEL_SMPx_BITOFFSET_MASK) >> ADC_CHANNEL_SMPx_BITOFFSET_POS), + SamplingTime << ((Channel & ADC_CHANNEL_SMPx_BITOFFSET_MASK) >> ADC_CHANNEL_SMPx_BITOFFSET_POS)); +} + +/** + * @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. + * On this STM32 series, ADC processing time is: + * - 12.5 ADC clock cycles at ADC resolution 12 bits + * - 10.5 ADC clock cycles at ADC resolution 10 bits + * - 8.5 ADC clock cycles at ADC resolution 8 bits + * - 6.5 ADC clock cycles at ADC resolution 6 bits + * @rmtoll SMPR1 SMP0 LL_ADC_GetChannelSamplingTime\n + * SMPR1 SMP1 LL_ADC_GetChannelSamplingTime\n + * SMPR1 SMP2 LL_ADC_GetChannelSamplingTime\n + * SMPR1 SMP3 LL_ADC_GetChannelSamplingTime\n + * SMPR1 SMP4 LL_ADC_GetChannelSamplingTime\n + * SMPR1 SMP5 LL_ADC_GetChannelSamplingTime\n + * SMPR1 SMP6 LL_ADC_GetChannelSamplingTime\n + * SMPR1 SMP7 LL_ADC_GetChannelSamplingTime\n + * SMPR1 SMP8 LL_ADC_GetChannelSamplingTime\n + * SMPR1 SMP9 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP10 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP11 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP12 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP13 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP14 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP15 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP16 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP17 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP18 LL_ADC_GetChannelSamplingTime + * @param ADCx ADC instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 (3) + * @arg @ref LL_ADC_CHANNEL_1 (3) + * @arg @ref LL_ADC_CHANNEL_2 (3) + * @arg @ref LL_ADC_CHANNEL_3 (3) + * @arg @ref LL_ADC_CHANNEL_4 (3) + * @arg @ref LL_ADC_CHANNEL_5 (3) + * @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_19 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1) + * @arg @ref LL_ADC_CHANNEL_VBAT (2) + * @arg @ref LL_ADC_CHANNEL_VDDCORE (2) + * + * (1) On STM32H563xx/573xx, parameter available only on ADC instance: ADC1.\n + * (2) On STM32H563xx/573xx, parameter available only on ADC instance: ADC2.\n + * (3) On STM32H5, fast channel allows: 2.5 (sampling) + 12.5 (conversion 12b) = 15 ADC clock cycles (fADC) + * Other channels are slow channels: 6.5 (sampling) + 12.5 (conversion 12b) = 19 ADC clock cycles (fADC) + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_SAMPLINGTIME_2CYCLES_5 (1) + * @arg @ref LL_ADC_SAMPLINGTIME_6CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_12CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_24CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_47CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_92CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_247CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_640CYCLES_5 + * + * (1) On some devices, ADC sampling time 2.5 ADC clock cycles + * can be replaced by 3.5 ADC clock cycles. + * Refer to function @ref LL_ADC_SetSamplingTimeCommonConfig(). + */ +__STATIC_INLINE uint32_t LL_ADC_GetChannelSamplingTime(const ADC_TypeDef *ADCx, uint32_t Channel) +{ + const __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->SMPR1, ((Channel & ADC_CHANNEL_SMPRX_REGOFFSET_MASK) + >> ADC_SMPRX_REGOFFSET_POS)); + + return (uint32_t)(READ_BIT(*preg, + ADC_SMPR1_SMP0 + << ((Channel & ADC_CHANNEL_SMPx_BITOFFSET_MASK) >> ADC_CHANNEL_SMPx_BITOFFSET_POS)) + >> ((Channel & ADC_CHANNEL_SMPx_BITOFFSET_MASK) >> ADC_CHANNEL_SMPx_BITOFFSET_POS) + ); +} + +/** + * @brief Set mode single-ended or differential input of the selected + * ADC channel. + * @note Channel ending is on channel scope: independently of channel mapped + * on ADC group regular or injected. + * In differential mode: Differential measurement is carried out + * between the selected channel 'i' (positive input) and + * channel 'i+1' (negative input). Only channel 'i' has to be + * configured, channel 'i+1' is configured automatically. + * @note Refer to Reference Manual to ensure the selected channel is + * available in differential mode. + * For example, internal channels (VrefInt, TempSensor, ...) are + * not available in differential mode. + * @note When configuring a channel 'i' in differential mode, + * the channel 'i+1' is not usable separately. + * @note For ADC channels configured in differential mode, both inputs + * should be biased at (Vref+)/2 +/-200mV. + * (Vref+ is the analog voltage reference) + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be ADC disabled. + * @note One or several values can be selected. + * Example: (LL_ADC_CHANNEL_4 | LL_ADC_CHANNEL_12 | ...) + * @rmtoll DIFSEL DIFSEL LL_ADC_SetChannelSingleDiff + * @param ADCx ADC instance + * @param Channel This parameter can be one of the following values: + * @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 + * @param SingleDiff This parameter can be a combination of the following values: + * @arg @ref LL_ADC_SINGLE_ENDED + * @arg @ref LL_ADC_DIFFERENTIAL_ENDED + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetChannelSingleDiff(ADC_TypeDef *ADCx, uint32_t Channel, uint32_t SingleDiff) +{ + /* Bits of channels in single or differential mode are set only for */ + /* differential mode (for single mode, mask of bits allowed to be set is */ + /* shifted out of range of bits of channels in single or differential mode. */ + MODIFY_REG(ADCx->DIFSEL, + Channel & ADC_SINGLEDIFF_CHANNEL_MASK, + (Channel & ADC_SINGLEDIFF_CHANNEL_MASK) + & (ADC_DIFSEL_DIFSEL >> (SingleDiff & ADC_SINGLEDIFF_CHANNEL_SHIFT_MASK))); +} + +/** + * @brief Get mode single-ended or differential input of the selected + * ADC channel. + * @note When configuring a channel 'i' in differential mode, + * the channel 'i+1' is not usable separately. + * Therefore, to ensure a channel is configured in single-ended mode, + * the configuration of channel itself and the channel 'i-1' must be + * read back (to ensure that the selected channel channel has not been + * configured in differential mode by the previous channel). + * @note Refer to Reference Manual to ensure the selected channel is + * available in differential mode. + * For example, internal channels (VrefInt, TempSensor, ...) are + * not available in differential mode. + * @note When configuring a channel 'i' in differential mode, + * the channel 'i+1' is not usable separately. + * @note One or several values can be selected. In this case, the value + * returned is null if all channels are in single ended-mode. + * Example: (LL_ADC_CHANNEL_4 | LL_ADC_CHANNEL_12 | ...) + * @rmtoll DIFSEL DIFSEL LL_ADC_GetChannelSingleDiff + * @param ADCx ADC instance + * @param Channel This parameter can be a combination of the following values: + * @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 + * @retval 0: channel in single-ended mode, else: channel in differential mode + */ +__STATIC_INLINE uint32_t LL_ADC_GetChannelSingleDiff(const ADC_TypeDef *ADCx, uint32_t Channel) +{ + return (uint32_t)(READ_BIT(ADCx->DIFSEL, (Channel & ADC_SINGLEDIFF_CHANNEL_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, multiple channels 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 are 2 kinds 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). + * - AWD flexible (instances AWD2, AWD3): + * - channels monitored: flexible on channels monitored, selection is + * channel wise, from from 1 to all channels. + * Specificity of this analog watchdog: Multiple channels can + * be selected. For example: + * (LL_ADC_AWD_CHANNEL4_REG_INJ | LL_ADC_AWD_CHANNEL5_REG_INJ | ...) + * - groups monitored: not selection possible (monitoring on both + * groups regular and injected). + * Channels selected are monitored on groups regular and injected: + * LL_ADC_AWD_CHANNELxx_REG_INJ (do not use parameters + * LL_ADC_AWD_CHANNELxx_REG and LL_ADC_AWD_CHANNELxx_INJ) + * - resolution: resolution is limited to 8 bits: if ADC resolution is + * 12 bits the 4 LSB are ignored, if ADC resolution is 10 bits + * the 2 LSB are ignored. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on either groups regular or injected. + * @rmtoll CFGR AWD1CH LL_ADC_SetAnalogWDMonitChannels\n + * CFGR AWD1SGL LL_ADC_SetAnalogWDMonitChannels\n + * CFGR AWD1EN LL_ADC_SetAnalogWDMonitChannels\n + * CFGR JAWD1EN LL_ADC_SetAnalogWDMonitChannels\n + * AWD2CR AWD2CH LL_ADC_SetAnalogWDMonitChannels\n + * AWD3CR AWD3CH LL_ADC_SetAnalogWDMonitChannels + * @param ADCx ADC instance + * @param AWDy This parameter can be one of the following values: + * @arg @ref LL_ADC_AWD1 + * @arg @ref LL_ADC_AWD2 + * @arg @ref LL_ADC_AWD3 + * @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 (0) + * @arg @ref LL_ADC_AWD_ALL_CHANNELS_INJ (0) + * @arg @ref LL_ADC_AWD_ALL_CHANNELS_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_0_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_0_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_0_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_1_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_1_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_1_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_2_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_2_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_2_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_3_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_3_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_3_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_4_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_4_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_4_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_5_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_5_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_5_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_6_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_6_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_6_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_7_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_7_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_7_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_8_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_8_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_8_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_9_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_9_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_9_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_10_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_10_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_10_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_11_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_11_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_11_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_12_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_12_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_12_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_13_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_13_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_13_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_14_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_14_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_14_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_15_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_15_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_15_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_16_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_16_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_16_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_17_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_17_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_17_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_18_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_18_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_18_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_19_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_19_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_19_REG_INJ + * @arg @ref LL_ADC_AWD_CH_VREFINT_REG (0)(1) + * @arg @ref LL_ADC_AWD_CH_VREFINT_INJ (0)(1) + * @arg @ref LL_ADC_AWD_CH_VREFINT_REG_INJ (1) + * @arg @ref LL_ADC_AWD_CH_TEMPSENSOR_REG (0)(1) + * @arg @ref LL_ADC_AWD_CH_TEMPSENSOR_INJ (0)(1) + * @arg @ref LL_ADC_AWD_CH_TEMPSENSOR_REG_INJ (1) + * @arg @ref LL_ADC_AWD_CH_VBAT_REG (0)(2) + * @arg @ref LL_ADC_AWD_CH_VBAT_INJ (0)(2) + * @arg @ref LL_ADC_AWD_CH_VBAT_REG_INJ (2) + * @arg @ref LL_ADC_AWD_CH_VDDCORE_REG (0)(2) + * @arg @ref LL_ADC_AWD_CH_VDDCORE_INJ (0)(2) + * @arg @ref LL_ADC_AWD_CH_VDDCORE_REG_INJ (2) + * + * (0) On STM32H5, parameter available only on analog watchdog number: AWD1.\n + * (1) On STM32H563xx/573xx, parameter available only on ADC instance: ADC1. + * (2) On STM32H563xx/573xx, parameter available only on ADC instance: ADC2. + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetAnalogWDMonitChannels(ADC_TypeDef *ADCx, uint32_t AWDy, uint32_t AWDChannelGroup) +{ + /* Set bits with content of parameter "AWDChannelGroup" with bits position */ + /* in register and register position depending on parameter "AWDy". */ + /* Parameters "AWDChannelGroup" and "AWDy" are used with masks because */ + /* containing other bits reserved for other purpose. */ + __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->CFGR, + ((AWDy & ADC_AWD_CRX_REGOFFSET_MASK) >> ADC_AWD_CRX_REGOFFSET_POS) + + ((AWDy & ADC_AWD_CR12_REGOFFSETGAP_MASK) + * ADC_AWD_CR12_REGOFFSETGAP_VAL)); + + MODIFY_REG(*preg, + (AWDy & ADC_AWD_CR_ALL_CHANNEL_MASK), + AWDChannelGroup & AWDy); +} + +/** + * @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 are 2 kinds 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). + * - AWD flexible (instances AWD2, AWD3): + * - channels monitored: flexible on channels monitored, selection is + * channel wise, from from 1 to all channels. + * Specificity of this analog watchdog: Multiple channels can + * be selected. For example: + * (LL_ADC_AWD_CHANNEL4_REG_INJ | LL_ADC_AWD_CHANNEL5_REG_INJ | ...) + * - groups monitored: not selection possible (monitoring on both + * groups regular and injected). + * Channels selected are monitored on groups regular and injected: + * LL_ADC_AWD_CHANNELxx_REG_INJ (do not use parameters + * LL_ADC_AWD_CHANNELxx_REG and LL_ADC_AWD_CHANNELxx_INJ) + * - resolution: resolution is limited to 8 bits: if ADC resolution is + * 12 bits the 4 LSB are ignored, if ADC resolution is 10 bits + * the 2 LSB are ignored. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on either groups regular or injected. + * @rmtoll CFGR AWD1CH LL_ADC_GetAnalogWDMonitChannels\n + * CFGR AWD1SGL LL_ADC_GetAnalogWDMonitChannels\n + * CFGR AWD1EN LL_ADC_GetAnalogWDMonitChannels\n + * CFGR JAWD1EN LL_ADC_GetAnalogWDMonitChannels\n + * AWD2CR AWD2CH LL_ADC_GetAnalogWDMonitChannels\n + * AWD3CR AWD3CH LL_ADC_GetAnalogWDMonitChannels + * @param ADCx ADC instance + * @param AWDy This parameter can be one of the following values: + * @arg @ref LL_ADC_AWD1 + * @arg @ref LL_ADC_AWD2 (1) + * @arg @ref LL_ADC_AWD3 (1) + * + * (1) On this AWD number, monitored channel can be retrieved + * if only 1 channel is programmed (or none or all channels). + * This function cannot retrieve monitored channel if + * multiple channels are programmed simultaneously + * by bitfield. + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_AWD_DISABLE + * @arg @ref LL_ADC_AWD_ALL_CHANNELS_REG (0) + * @arg @ref LL_ADC_AWD_ALL_CHANNELS_INJ (0) + * @arg @ref LL_ADC_AWD_ALL_CHANNELS_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_0_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_0_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_0_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_1_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_1_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_1_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_2_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_2_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_2_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_3_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_3_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_3_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_4_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_4_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_4_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_5_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_5_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_5_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_6_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_6_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_6_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_7_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_7_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_7_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_8_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_8_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_8_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_9_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_9_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_9_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_10_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_10_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_10_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_11_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_11_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_11_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_12_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_12_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_12_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_13_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_13_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_13_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_14_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_14_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_14_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_15_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_15_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_15_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_16_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_16_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_16_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_17_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_17_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_17_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_18_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_18_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_18_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_19_REG (0) + * @arg @ref LL_ADC_AWD_CHANNEL_19_INJ (0) + * @arg @ref LL_ADC_AWD_CHANNEL_19_REG_INJ + * + * (0) On STM32H5, parameter available only on analog watchdog number: AWD1. + */ +__STATIC_INLINE uint32_t LL_ADC_GetAnalogWDMonitChannels(const ADC_TypeDef *ADCx, uint32_t AWDy) +{ + const __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->CFGR, + ((AWDy & ADC_AWD_CRX_REGOFFSET_MASK) >> ADC_AWD_CRX_REGOFFSET_POS) + + ((AWDy & ADC_AWD_CR12_REGOFFSETGAP_MASK) + * ADC_AWD_CR12_REGOFFSETGAP_VAL)); + + uint32_t analog_wd_monit_channels = (READ_BIT(*preg, AWDy) & AWDy & ADC_AWD_CR_ALL_CHANNEL_MASK); + + /* If "analog_wd_monit_channels" == 0, then the selected AWD is disabled */ + /* (parameter value LL_ADC_AWD_DISABLE). */ + /* Else, the selected AWD is enabled and is monitoring a group of channels */ + /* or a single channel. */ + if (analog_wd_monit_channels != 0UL) + { + if (AWDy == LL_ADC_AWD1) + { + if ((analog_wd_monit_channels & ADC_CFGR_AWD1SGL) == 0UL) + { + /* AWD monitoring a group of channels */ + analog_wd_monit_channels = ((analog_wd_monit_channels + | (ADC_AWD_CR23_CHANNEL_MASK) + ) + & (~(ADC_CFGR_AWD1CH)) + ); + } + else + { + /* AWD monitoring a single channel */ + analog_wd_monit_channels = (analog_wd_monit_channels + | (ADC_AWD2CR_AWD2CH_0 << (analog_wd_monit_channels >> ADC_CFGR_AWD1CH_Pos)) + ); + } + } + else + { + if ((analog_wd_monit_channels & ADC_AWD_CR23_CHANNEL_MASK) == ADC_AWD_CR23_CHANNEL_MASK) + { + /* AWD monitoring a group of channels */ + analog_wd_monit_channels = (ADC_AWD_CR23_CHANNEL_MASK + | ((ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN)) + ); + } + else + { + /* AWD monitoring a single channel */ + /* AWD monitoring a group of channels */ + analog_wd_monit_channels = (analog_wd_monit_channels + | (ADC_CFGR_JAWD1EN | ADC_CFGR_AWD1EN | ADC_CFGR_AWD1SGL) + | (__LL_ADC_CHANNEL_TO_DECIMAL_NB(analog_wd_monit_channels) << ADC_CFGR_AWD1CH_Pos) + ); + } + } + } + + return analog_wd_monit_channels; +} + +/** + * @brief Set ADC analog watchdog thresholds value of both thresholds + * high and low. + * @note If value of only one threshold high or low must be set, + * use function @ref LL_ADC_SetAnalogWDThresholds(). + * @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 are 2 kinds 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). + * - AWD flexible (instances AWD2, AWD3): + * - channels monitored: flexible on channels monitored, selection is + * channel wise, from from 1 to all channels. + * Specificity of this analog watchdog: Multiple channels can + * be selected. For example: + * (LL_ADC_AWD_CHANNEL4_REG_INJ | LL_ADC_AWD_CHANNEL5_REG_INJ | ...) + * - groups monitored: not selection possible (monitoring on both + * groups regular and injected). + * Channels selected are monitored on groups regular and injected: + * LL_ADC_AWD_CHANNELxx_REG_INJ (do not use parameters + * LL_ADC_AWD_CHANNELxx_REG and LL_ADC_AWD_CHANNELxx_INJ) + * - resolution: resolution is limited to 8 bits: if ADC resolution is + * 12 bits the 4 LSB are ignored, if ADC resolution is 10 bits + * the 2 LSB are ignored. + * @note If ADC oversampling is enabled, ADC analog watchdog thresholds are + * impacted: the comparison of analog watchdog thresholds is done on + * oversampling final computation (after ratio and shift application): + * ADC data register bitfield [15:4] (12 most significant bits). + * Examples: + * - Oversampling ratio and shift selected to have ADC conversion data + * on 12 bits (ratio 16 and shift 4, or ratio 32 and shift 5, ...): + * ADC analog watchdog thresholds must be divided by 16. + * - Oversampling ratio and shift selected to have ADC conversion data + * on 14 bits (ratio 16 and shift 2, or ratio 32 and shift 3, ...): + * ADC analog watchdog thresholds must be divided by 4. + * - Oversampling ratio and shift selected to have ADC conversion data + * on 16 bits (ratio 16 and shift none, or ratio 32 and shift 1, ...): + * ADC analog watchdog thresholds match directly to ADC data register. + * @rmtoll TR1 HT1 LL_ADC_ConfigAnalogWDThresholds\n + * TR2 HT2 LL_ADC_ConfigAnalogWDThresholds\n + * TR3 HT3 LL_ADC_ConfigAnalogWDThresholds\n + * TR1 LT1 LL_ADC_ConfigAnalogWDThresholds\n + * TR2 LT2 LL_ADC_ConfigAnalogWDThresholds\n + * TR3 LT3 LL_ADC_ConfigAnalogWDThresholds + * @param ADCx ADC instance + * @param AWDy This parameter can be one of the following values: + * @arg @ref LL_ADC_AWD1 + * @arg @ref LL_ADC_AWD2 + * @arg @ref LL_ADC_AWD3 + * @param AWDThresholdHighValue Value between Min_Data=0x000 and Max_Data=0xFFF + * @param AWDThresholdLowValue Value between Min_Data=0x000 and Max_Data=0xFFF + * @retval None + */ +__STATIC_INLINE void LL_ADC_ConfigAnalogWDThresholds(ADC_TypeDef *ADCx, uint32_t AWDy, uint32_t AWDThresholdHighValue, + uint32_t AWDThresholdLowValue) +{ + /* Set bits with content of parameter "AWDThresholdxxxValue" with bits */ + /* position in register and register position depending on parameter */ + /* "AWDy". */ + /* Parameters "AWDy" and "AWDThresholdxxxValue" are used with masks because */ + /* containing other bits reserved for other purpose. */ + __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->TR1, + ((AWDy & ADC_AWD_TRX_REGOFFSET_MASK) >> ADC_AWD_TRX_REGOFFSET_POS)); + + MODIFY_REG(*preg, + ADC_TR1_HT1 | ADC_TR1_LT1, + (AWDThresholdHighValue << ADC_TR1_HT1_BITOFFSET_POS) | AWDThresholdLowValue); +} + +/** + * @brief Set ADC analog watchdog threshold value of threshold + * high or low. + * @note If values of both thresholds high or low must be set, + * use function @ref LL_ADC_ConfigAnalogWDThresholds(). + * @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 are 2 kinds 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). + * - AWD flexible (instances AWD2, AWD3): + * - channels monitored: flexible on channels monitored, selection is + * channel wise, from from 1 to all channels. + * Specificity of this analog watchdog: Multiple channels can + * be selected. For example: + * (LL_ADC_AWD_CHANNEL4_REG_INJ | LL_ADC_AWD_CHANNEL5_REG_INJ | ...) + * - groups monitored: not selection possible (monitoring on both + * groups regular and injected). + * Channels selected are monitored on groups regular and injected: + * LL_ADC_AWD_CHANNELxx_REG_INJ (do not use parameters + * LL_ADC_AWD_CHANNELxx_REG and LL_ADC_AWD_CHANNELxx_INJ) + * - resolution: resolution is limited to 8 bits: if ADC resolution is + * 12 bits the 4 LSB are ignored, if ADC resolution is 10 bits + * the 2 LSB are ignored. + * @note If ADC oversampling is enabled, ADC analog watchdog thresholds are + * impacted: the comparison of analog watchdog thresholds is done on + * oversampling final computation (after ratio and shift application): + * ADC data register bitfield [15:4] (12 most significant bits). + * Examples: + * - Oversampling ratio and shift selected to have ADC conversion data + * on 12 bits (ratio 16 and shift 4, or ratio 32 and shift 5, ...): + * ADC analog watchdog thresholds must be divided by 16. + * - Oversampling ratio and shift selected to have ADC conversion data + * on 14 bits (ratio 16 and shift 2, or ratio 32 and shift 3, ...): + * ADC analog watchdog thresholds must be divided by 4. + * - Oversampling ratio and shift selected to have ADC conversion data + * on 16 bits (ratio 16 and shift none, or ratio 32 and shift 1, ...): + * ADC analog watchdog thresholds match directly to ADC data register. + * @note On this STM32 series, setting of this feature is not conditioned to + * ADC state: + * ADC can be disabled, enabled with or without conversion on going + * on either ADC groups regular or injected. + * @rmtoll TR1 HT1 LL_ADC_SetAnalogWDThresholds\n + * TR2 HT2 LL_ADC_SetAnalogWDThresholds\n + * TR3 HT3 LL_ADC_SetAnalogWDThresholds\n + * TR1 LT1 LL_ADC_SetAnalogWDThresholds\n + * TR2 LT2 LL_ADC_SetAnalogWDThresholds\n + * TR3 LT3 LL_ADC_SetAnalogWDThresholds + * @param ADCx ADC instance + * @param AWDy This parameter can be one of the following values: + * @arg @ref LL_ADC_AWD1 + * @arg @ref LL_ADC_AWD2 + * @arg @ref LL_ADC_AWD3 + * @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 AWDy, uint32_t AWDThresholdsHighLow, + uint32_t AWDThresholdValue) +{ + /* Set bits with content of parameter "AWDThresholdValue" with bits */ + /* position in register and register position depending on parameters */ + /* "AWDThresholdsHighLow" and "AWDy". */ + /* Parameters "AWDy" and "AWDThresholdValue" are used with masks because */ + /* containing other bits reserved for other purpose. */ + __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->TR1, + ((AWDy & ADC_AWD_TRX_REGOFFSET_MASK) >> ADC_AWD_TRX_REGOFFSET_POS)); + + MODIFY_REG(*preg, + AWDThresholdsHighLow, + AWDThresholdValue << ((AWDThresholdsHighLow & ADC_AWD_TRX_BIT_HIGH_MASK) >> ADC_AWD_TRX_BIT_HIGH_SHIFT4)); +} + +/** + * @brief Get ADC analog watchdog threshold value of threshold high, + * threshold low or raw data with ADC thresholds high and low + * concatenated. + * @note If raw data with ADC thresholds high and low is retrieved, + * the data of each threshold high or low can be isolated + * using helper macro: + * @ref __LL_ADC_ANALOGWD_THRESHOLDS_HIGH_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 TR1 HT1 LL_ADC_GetAnalogWDThresholds\n + * TR2 HT2 LL_ADC_GetAnalogWDThresholds\n + * TR3 HT3 LL_ADC_GetAnalogWDThresholds\n + * TR1 LT1 LL_ADC_GetAnalogWDThresholds\n + * TR2 LT2 LL_ADC_GetAnalogWDThresholds\n + * TR3 LT3 LL_ADC_GetAnalogWDThresholds + * @param ADCx ADC instance + * @param AWDy This parameter can be one of the following values: + * @arg @ref LL_ADC_AWD1 + * @arg @ref LL_ADC_AWD2 + * @arg @ref LL_ADC_AWD3 + * @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 + * @arg @ref LL_ADC_AWD_THRESHOLDS_HIGH_LOW + * @retval Value between Min_Data=0x000 and Max_Data=0xFFF + */ +__STATIC_INLINE uint32_t LL_ADC_GetAnalogWDThresholds(const ADC_TypeDef *ADCx, + uint32_t AWDy, uint32_t AWDThresholdsHighLow) +{ + const __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->TR1, + ((AWDy & ADC_AWD_TRX_REGOFFSET_MASK) >> ADC_AWD_TRX_REGOFFSET_POS)); + + return (uint32_t)(READ_BIT(*preg, + (AWDThresholdsHighLow | ADC_TR1_LT1)) + >> (((AWDThresholdsHighLow & ADC_AWD_TRX_BIT_HIGH_MASK) >> ADC_AWD_TRX_BIT_HIGH_SHIFT4) + & ~(AWDThresholdsHighLow & ADC_TR1_LT1))); +} + +/** + * @brief Set ADC analog watchdog filtering configuration + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on either groups regular or injected. + * @note On this STM32 series, this feature is only available on first + * analog watchdog (AWD1) + * @rmtoll TR1 AWDFILT LL_ADC_SetAWDFilteringConfiguration + * @param ADCx ADC instance + * @param AWDy This parameter can be one of the following values: + * @arg @ref LL_ADC_AWD1 + * @param FilteringConfig This parameter can be one of the following values: + * @arg @ref LL_ADC_AWD_FILTERING_NONE + * @arg @ref LL_ADC_AWD_FILTERING_2SAMPLES + * @arg @ref LL_ADC_AWD_FILTERING_3SAMPLES + * @arg @ref LL_ADC_AWD_FILTERING_4SAMPLES + * @arg @ref LL_ADC_AWD_FILTERING_5SAMPLES + * @arg @ref LL_ADC_AWD_FILTERING_6SAMPLES + * @arg @ref LL_ADC_AWD_FILTERING_7SAMPLES + * @arg @ref LL_ADC_AWD_FILTERING_8SAMPLES + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetAWDFilteringConfiguration(ADC_TypeDef *ADCx, uint32_t AWDy, uint32_t FilteringConfig) +{ + /* Prevent unused argument(s) compilation warning */ + (void)(AWDy); + MODIFY_REG(ADCx->TR1, ADC_TR1_AWDFILT, FilteringConfig); +} + +/** + * @brief Get ADC analog watchdog filtering configuration + * @note On this STM32 series, this feature is only available on first + * analog watchdog (AWD1) + * @rmtoll TR1 AWDFILT LL_ADC_GetAWDFilteringConfiguration + * @param ADCx ADC instance + * @param AWDy This parameter can be one of the following values: + * @arg @ref LL_ADC_AWD1 + * @retval Returned value can be: + * @arg @ref LL_ADC_AWD_FILTERING_NONE + * @arg @ref LL_ADC_AWD_FILTERING_2SAMPLES + * @arg @ref LL_ADC_AWD_FILTERING_3SAMPLES + * @arg @ref LL_ADC_AWD_FILTERING_4SAMPLES + * @arg @ref LL_ADC_AWD_FILTERING_5SAMPLES + * @arg @ref LL_ADC_AWD_FILTERING_6SAMPLES + * @arg @ref LL_ADC_AWD_FILTERING_7SAMPLES + * @arg @ref LL_ADC_AWD_FILTERING_8SAMPLES + */ +__STATIC_INLINE uint32_t LL_ADC_GetAWDFilteringConfiguration(const ADC_TypeDef *ADCx, uint32_t AWDy) +{ + /* Prevent unused argument(s) compilation warning */ + (void)(AWDy); + return (uint32_t)(READ_BIT(ADCx->TR1, ADC_TR1_AWDFILT)); +} + +/** + * @} + */ + +/** @defgroup ADC_LL_EF_Configuration_ADC_oversampling Configuration of ADC transversal scope: oversampling + * @{ + */ + +/** + * @brief Set ADC oversampling scope: ADC groups regular and-or injected + * (availability of ADC group injected depends on STM32 series). + * @note If both groups regular and injected are selected, + * specify behavior of ADC group injected interrupting + * group regular: when ADC group injected is triggered, + * the oversampling on ADC group regular is either + * temporary stopped and continued, or resumed from start + * (oversampler buffer reset). + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on either groups regular or injected. + * @rmtoll CFGR2 ROVSE LL_ADC_SetOverSamplingScope\n + * CFGR2 JOVSE LL_ADC_SetOverSamplingScope\n + * CFGR2 ROVSM LL_ADC_SetOverSamplingScope + * @param ADCx ADC instance + * @param OvsScope This parameter can be one of the following values: + * @arg @ref LL_ADC_OVS_DISABLE + * @arg @ref LL_ADC_OVS_GRP_REGULAR_CONTINUED + * @arg @ref LL_ADC_OVS_GRP_REGULAR_RESUMED + * @arg @ref LL_ADC_OVS_GRP_INJECTED + * @arg @ref LL_ADC_OVS_GRP_INJ_REG_RESUMED + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetOverSamplingScope(ADC_TypeDef *ADCx, uint32_t OvsScope) +{ + MODIFY_REG(ADCx->CFGR2, ADC_CFGR2_ROVSE | ADC_CFGR2_JOVSE | ADC_CFGR2_ROVSM, OvsScope); +} + +/** + * @brief Get ADC oversampling scope: ADC groups regular and-or injected + * (availability of ADC group injected depends on STM32 series). + * @note If both groups regular and injected are selected, + * specify behavior of ADC group injected interrupting + * group regular: when ADC group injected is triggered, + * the oversampling on ADC group regular is either + * temporary stopped and continued, or resumed from start + * (oversampler buffer reset). + * @rmtoll CFGR2 ROVSE LL_ADC_GetOverSamplingScope\n + * CFGR2 JOVSE LL_ADC_GetOverSamplingScope\n + * CFGR2 ROVSM LL_ADC_GetOverSamplingScope + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_OVS_DISABLE + * @arg @ref LL_ADC_OVS_GRP_REGULAR_CONTINUED + * @arg @ref LL_ADC_OVS_GRP_REGULAR_RESUMED + * @arg @ref LL_ADC_OVS_GRP_INJECTED + * @arg @ref LL_ADC_OVS_GRP_INJ_REG_RESUMED + */ +__STATIC_INLINE uint32_t LL_ADC_GetOverSamplingScope(const ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CFGR2, ADC_CFGR2_ROVSE | ADC_CFGR2_JOVSE | ADC_CFGR2_ROVSM)); +} + +/** + * @brief Set ADC oversampling discontinuous mode (triggered mode) + * on the selected ADC group. + * @note Number of oversampled conversions are done either in: + * - continuous mode (all conversions of oversampling ratio + * are done from 1 trigger) + * - discontinuous mode (each conversion of oversampling ratio + * needs a trigger) + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on group regular. + * @note On this STM32 series, oversampling discontinuous mode + * (triggered mode) can be used only when oversampling is + * set on group regular only and in resumed mode. + * @rmtoll CFGR2 TROVS LL_ADC_SetOverSamplingDiscont + * @param ADCx ADC instance + * @param OverSamplingDiscont This parameter can be one of the following values: + * @arg @ref LL_ADC_OVS_REG_CONT + * @arg @ref LL_ADC_OVS_REG_DISCONT + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetOverSamplingDiscont(ADC_TypeDef *ADCx, uint32_t OverSamplingDiscont) +{ + MODIFY_REG(ADCx->CFGR2, ADC_CFGR2_TROVS, OverSamplingDiscont); +} + +/** + * @brief Get ADC oversampling discontinuous mode (triggered mode) + * on the selected ADC group. + * @note Number of oversampled conversions are done either in: + * - continuous mode (all conversions of oversampling ratio + * are done from 1 trigger) + * - discontinuous mode (each conversion of oversampling ratio + * needs a trigger) + * @rmtoll CFGR2 TROVS LL_ADC_GetOverSamplingDiscont + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_OVS_REG_CONT + * @arg @ref LL_ADC_OVS_REG_DISCONT + */ +__STATIC_INLINE uint32_t LL_ADC_GetOverSamplingDiscont(const ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CFGR2, ADC_CFGR2_TROVS)); +} + +/** + * @brief Set ADC oversampling + * (impacting both ADC groups regular and injected) + * @note This function set the 2 items of oversampling configuration: + * - ratio + * - shift + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on either groups regular or injected. + * @rmtoll CFGR2 OVSS LL_ADC_ConfigOverSamplingRatioShift\n + * CFGR2 OVSR LL_ADC_ConfigOverSamplingRatioShift + * @param ADCx ADC instance + * @param Ratio This parameter can be one of the following values: + * @arg @ref LL_ADC_OVS_RATIO_2 + * @arg @ref LL_ADC_OVS_RATIO_4 + * @arg @ref LL_ADC_OVS_RATIO_8 + * @arg @ref LL_ADC_OVS_RATIO_16 + * @arg @ref LL_ADC_OVS_RATIO_32 + * @arg @ref LL_ADC_OVS_RATIO_64 + * @arg @ref LL_ADC_OVS_RATIO_128 + * @arg @ref LL_ADC_OVS_RATIO_256 + * @param Shift This parameter can be one of the following values: + * @arg @ref LL_ADC_OVS_SHIFT_NONE + * @arg @ref LL_ADC_OVS_SHIFT_RIGHT_1 + * @arg @ref LL_ADC_OVS_SHIFT_RIGHT_2 + * @arg @ref LL_ADC_OVS_SHIFT_RIGHT_3 + * @arg @ref LL_ADC_OVS_SHIFT_RIGHT_4 + * @arg @ref LL_ADC_OVS_SHIFT_RIGHT_5 + * @arg @ref LL_ADC_OVS_SHIFT_RIGHT_6 + * @arg @ref LL_ADC_OVS_SHIFT_RIGHT_7 + * @arg @ref LL_ADC_OVS_SHIFT_RIGHT_8 + * @retval None + */ +__STATIC_INLINE void LL_ADC_ConfigOverSamplingRatioShift(ADC_TypeDef *ADCx, uint32_t Ratio, uint32_t Shift) +{ + MODIFY_REG(ADCx->CFGR2, (ADC_CFGR2_OVSS | ADC_CFGR2_OVSR), (Shift | Ratio)); +} + +/** + * @brief Get ADC oversampling ratio + * (impacting both ADC groups regular and injected) + * @rmtoll CFGR2 OVSR LL_ADC_GetOverSamplingRatio + * @param ADCx ADC instance + * @retval Ratio This parameter can be one of the following values: + * @arg @ref LL_ADC_OVS_RATIO_2 + * @arg @ref LL_ADC_OVS_RATIO_4 + * @arg @ref LL_ADC_OVS_RATIO_8 + * @arg @ref LL_ADC_OVS_RATIO_16 + * @arg @ref LL_ADC_OVS_RATIO_32 + * @arg @ref LL_ADC_OVS_RATIO_64 + * @arg @ref LL_ADC_OVS_RATIO_128 + * @arg @ref LL_ADC_OVS_RATIO_256 + */ +__STATIC_INLINE uint32_t LL_ADC_GetOverSamplingRatio(const ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CFGR2, ADC_CFGR2_OVSR)); +} + +/** + * @brief Get ADC oversampling shift + * (impacting both ADC groups regular and injected) + * @rmtoll CFGR2 OVSS LL_ADC_GetOverSamplingShift + * @param ADCx ADC instance + * @retval Shift This parameter can be one of the following values: + * @arg @ref LL_ADC_OVS_SHIFT_NONE + * @arg @ref LL_ADC_OVS_SHIFT_RIGHT_1 + * @arg @ref LL_ADC_OVS_SHIFT_RIGHT_2 + * @arg @ref LL_ADC_OVS_SHIFT_RIGHT_3 + * @arg @ref LL_ADC_OVS_SHIFT_RIGHT_4 + * @arg @ref LL_ADC_OVS_SHIFT_RIGHT_5 + * @arg @ref LL_ADC_OVS_SHIFT_RIGHT_6 + * @arg @ref LL_ADC_OVS_SHIFT_RIGHT_7 + * @arg @ref LL_ADC_OVS_SHIFT_RIGHT_8 + */ +__STATIC_INLINE uint32_t LL_ADC_GetOverSamplingShift(const ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CFGR2, ADC_CFGR2_OVSS)); +} + +/** + * @} + */ + +/** @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. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * All ADC instances of the ADC common group must be disabled. + * This check can be done with function @ref LL_ADC_IsEnabled() for each + * ADC instance or by using helper macro + * @ref __LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(). + * @rmtoll CCR DUAL 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 + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetMultimode(ADC_Common_TypeDef *ADCxy_COMMON, uint32_t Multimode) +{ + MODIFY_REG(ADCxy_COMMON->CCR, ADC_CCR_DUAL, 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 DUAL 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 + */ +__STATIC_INLINE uint32_t LL_ADC_GetMultimode(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return (uint32_t)(READ_BIT(ADCxy_COMMON->CCR, ADC_CCR_DUAL)); +} + +/** + * @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(). + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * All ADC instances of the ADC common group must be disabled + * or enabled without conversion on going on group regular. + * @rmtoll CCR MDMA LL_ADC_SetMultiDMATransfer\n + * CCR DMACFG 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_RES12_10B + * @arg @ref LL_ADC_MULTI_REG_DMA_LIMIT_RES8_6B + * @arg @ref LL_ADC_MULTI_REG_DMA_UNLMT_RES12_10B + * @arg @ref LL_ADC_MULTI_REG_DMA_UNLMT_RES8_6B + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetMultiDMATransfer(ADC_Common_TypeDef *ADCxy_COMMON, uint32_t MultiDMATransfer) +{ + MODIFY_REG(ADCxy_COMMON->CCR, ADC_CCR_MDMA | ADC_CCR_DMACFG, 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 DMACFG 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_RES12_10B + * @arg @ref LL_ADC_MULTI_REG_DMA_LIMIT_RES8_6B + * @arg @ref LL_ADC_MULTI_REG_DMA_UNLMT_RES12_10B + * @arg @ref LL_ADC_MULTI_REG_DMA_UNLMT_RES8_6B + */ +__STATIC_INLINE uint32_t LL_ADC_GetMultiDMATransfer(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return (uint32_t)(READ_BIT(ADCxy_COMMON->CCR, ADC_CCR_MDMA | ADC_CCR_DMACFG)); +} + +/** + * @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. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * All ADC instances of the ADC common group must be disabled. + * This check can be done with function @ref LL_ADC_IsEnabled() for each + * ADC instance or by using helper macro helper macro + * @ref __LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(). + * @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_1CYCLE + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_2CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_3CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_4CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_5CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_6CYCLES (1) + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_7CYCLES (1) + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_8CYCLES (2) + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_9CYCLES (2) + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_10CYCLES (2) + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_11CYCLES (3) + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_12CYCLES (3) + * + * (1) Parameter available only if ADC resolution is 12, 10 or 8 bits.\n + * (2) Parameter available only if ADC resolution is 12 or 10 bits.\n + * (3) Parameter available only if ADC resolution is 12 bits. + * @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_1CYCLE + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_2CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_3CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_4CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_5CYCLES + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_6CYCLES (1) + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_7CYCLES (1) + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_8CYCLES (2) + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_9CYCLES (2) + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_10CYCLES (2) + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_11CYCLES (3) + * @arg @ref LL_ADC_MULTI_TWOSMP_DELAY_12CYCLES (3) + * + * (1) Parameter available only if ADC resolution is 12, 10 or 8 bits.\n + * (2) Parameter available only if ADC resolution is 12 or 10 bits.\n + * (3) Parameter available only if ADC resolution is 12 bits. + */ +__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 Put ADC instance in deep power down state. + * @note In case of ADC calibration necessary: When ADC is in deep-power-down + * state, the internal analog calibration is lost. After exiting from + * deep power down, calibration must be relaunched or calibration factor + * (preliminarily saved) must be set back into calibration register. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be ADC disabled. + * @rmtoll CR DEEPPWD LL_ADC_EnableDeepPowerDown + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_EnableDeepPowerDown(ADC_TypeDef *ADCx) +{ + /* Note: Write register with some additional bits forced to state reset */ + /* instead of modifying only the selected bit for this function, */ + /* to not interfere with bits with HW property "rs". */ + MODIFY_REG(ADCx->CR, + ADC_CR_BITS_PROPERTY_RS, + ADC_CR_DEEPPWD); +} + +/** + * @brief Disable ADC deep power down mode. + * @note In case of ADC calibration necessary: When ADC is in deep-power-down + * state, the internal analog calibration is lost. After exiting from + * deep power down, calibration must be relaunched or calibration factor + * (preliminarily saved) must be set back into calibration register. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be ADC disabled. + * @rmtoll CR DEEPPWD LL_ADC_DisableDeepPowerDown + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_DisableDeepPowerDown(ADC_TypeDef *ADCx) +{ + /* Note: Write register with some additional bits forced to state reset */ + /* instead of modifying only the selected bit for this function, */ + /* to not interfere with bits with HW property "rs". */ + CLEAR_BIT(ADCx->CR, (ADC_CR_DEEPPWD | ADC_CR_BITS_PROPERTY_RS)); +} + +/** + * @brief Get the selected ADC instance deep power down state. + * @rmtoll CR DEEPPWD LL_ADC_IsDeepPowerDownEnabled + * @param ADCx ADC instance + * @retval 0: deep power down is disabled, 1: deep power down is enabled. + */ +__STATIC_INLINE uint32_t LL_ADC_IsDeepPowerDownEnabled(const ADC_TypeDef *ADCx) +{ + return ((READ_BIT(ADCx->CR, ADC_CR_DEEPPWD) == (ADC_CR_DEEPPWD)) ? 1UL : 0UL); +} + +/** + * @brief Enable ADC instance internal voltage regulator. + * @note On this STM32 series, after ADC internal voltage regulator enable, + * a delay for ADC internal voltage regulator stabilization + * is required before performing a ADC calibration or ADC enable. + * Refer to device datasheet, parameter tADCVREG_STUP. + * Refer to literal @ref LL_ADC_DELAY_INTERNAL_REGUL_STAB_US. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be ADC disabled. + * @rmtoll CR ADVREGEN LL_ADC_EnableInternalRegulator + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_EnableInternalRegulator(ADC_TypeDef *ADCx) +{ + /* Note: Write register with some additional bits forced to state reset */ + /* instead of modifying only the selected bit for this function, */ + /* to not interfere with bits with HW property "rs". */ + MODIFY_REG(ADCx->CR, + ADC_CR_BITS_PROPERTY_RS, + ADC_CR_ADVREGEN); +} + +/** + * @brief Disable ADC internal voltage regulator. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be ADC disabled. + * @rmtoll CR ADVREGEN LL_ADC_DisableInternalRegulator + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_DisableInternalRegulator(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->CR, (ADC_CR_ADVREGEN | ADC_CR_BITS_PROPERTY_RS)); +} + +/** + * @brief Get the selected ADC instance internal voltage regulator state. + * @rmtoll CR ADVREGEN LL_ADC_IsInternalRegulatorEnabled + * @param ADCx ADC instance + * @retval 0: internal regulator is disabled, 1: internal regulator is enabled. + */ +__STATIC_INLINE uint32_t LL_ADC_IsInternalRegulatorEnabled(const ADC_TypeDef *ADCx) +{ + return ((READ_BIT(ADCx->CR, ADC_CR_ADVREGEN) == (ADC_CR_ADVREGEN)) ? 1UL : 0UL); +} + +/** + * @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. + * @note On this STM32 series, flag LL_ADC_FLAG_ADRDY is raised when the ADC + * is enabled and when conversion clock is active. + * (not only core clock: this ADC has a dual clock domain) + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be ADC disabled and ADC internal voltage regulator enabled. + * @rmtoll CR ADEN LL_ADC_Enable + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_Enable(ADC_TypeDef *ADCx) +{ + /* Note: Write register with some additional bits forced to state reset */ + /* instead of modifying only the selected bit for this function, */ + /* to not interfere with bits with HW property "rs". */ + MODIFY_REG(ADCx->CR, + ADC_CR_BITS_PROPERTY_RS, + ADC_CR_ADEN); +} + +/** + * @brief Disable the selected ADC instance. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be not disabled. Must be enabled without conversion on going + * on either groups regular or injected. + * @rmtoll CR ADDIS LL_ADC_Disable + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_Disable(ADC_TypeDef *ADCx) +{ + /* Note: Write register with some additional bits forced to state reset */ + /* instead of modifying only the selected bit for this function, */ + /* to not interfere with bits with HW property "rs". */ + MODIFY_REG(ADCx->CR, + ADC_CR_BITS_PROPERTY_RS, + ADC_CR_ADDIS); +} + +/** + * @brief Get the selected ADC instance enable state. + * @note On this STM32 series, flag LL_ADC_FLAG_ADRDY is raised when the ADC + * is enabled and when conversion clock is active. + * (not only core clock: this ADC has a dual clock domain) + * @rmtoll CR ADEN 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->CR, ADC_CR_ADEN) == (ADC_CR_ADEN)) ? 1UL : 0UL); +} + +/** + * @brief Get the selected ADC instance disable state. + * @rmtoll CR ADDIS LL_ADC_IsDisableOngoing + * @param ADCx ADC instance + * @retval 0: no ADC disable command on going. + */ +__STATIC_INLINE uint32_t LL_ADC_IsDisableOngoing(const ADC_TypeDef *ADCx) +{ + return ((READ_BIT(ADCx->CR, ADC_CR_ADDIS) == (ADC_CR_ADDIS)) ? 1UL : 0UL); +} + +/** + * @brief Start ADC calibration in the mode single-ended + * or differential (for devices with differential mode available). + * @note On this STM32 series, a minimum number of ADC clock cycles + * are required between ADC end of calibration and ADC enable. + * Refer to literal @ref LL_ADC_DELAY_CALIB_ENABLE_ADC_CYCLES. + * @note For devices with differential mode available: + * Calibration of offset is specific to each of + * single-ended and differential modes + * (calibration run must be performed for each of these + * differential modes, if used afterwards and if the application + * requires their calibration). + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be ADC disabled. + * @rmtoll CR ADCAL LL_ADC_StartCalibration\n + * CR ADCALDIF LL_ADC_StartCalibration + * @param ADCx ADC instance + * @param SingleDiff This parameter can be one of the following values: + * @arg @ref LL_ADC_SINGLE_ENDED + * @arg @ref LL_ADC_DIFFERENTIAL_ENDED + * @retval None + */ +__STATIC_INLINE void LL_ADC_StartCalibration(ADC_TypeDef *ADCx, uint32_t SingleDiff) +{ + /* Note: Write register with some additional bits forced to state reset */ + /* instead of modifying only the selected bit for this function, */ + /* to not interfere with bits with HW property "rs". */ + MODIFY_REG(ADCx->CR, + ADC_CR_ADCALDIF | ADC_CR_BITS_PROPERTY_RS, + ADC_CR_ADCAL | (SingleDiff & ADC_SINGLEDIFF_CALIB_START_MASK)); +} + +/** + * @brief Get ADC calibration state. + * @rmtoll CR ADCAL LL_ADC_IsCalibrationOnGoing + * @param ADCx ADC instance + * @retval 0: calibration complete, 1: calibration in progress. + */ +__STATIC_INLINE uint32_t LL_ADC_IsCalibrationOnGoing(const ADC_TypeDef *ADCx) +{ + return ((READ_BIT(ADCx->CR, ADC_CR_ADCAL) == (ADC_CR_ADCAL)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @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 for both + * internal trigger (SW start) and 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 + * will start at next trigger event (on the selected trigger edge) + * following the ADC start conversion command. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be enabled without conversion on going on group regular, + * without conversion stop command on going on group regular, + * without ADC disable command on going. + * @rmtoll CR ADSTART LL_ADC_REG_StartConversion + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_REG_StartConversion(ADC_TypeDef *ADCx) +{ + /* Note: Write register with some additional bits forced to state reset */ + /* instead of modifying only the selected bit for this function, */ + /* to not interfere with bits with HW property "rs". */ + MODIFY_REG(ADCx->CR, + ADC_CR_BITS_PROPERTY_RS, + ADC_CR_ADSTART); +} + +/** + * @brief Stop ADC group regular conversion. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be enabled with conversion on going on group regular, + * without ADC disable command on going. + * @rmtoll CR ADSTP LL_ADC_REG_StopConversion + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_REG_StopConversion(ADC_TypeDef *ADCx) +{ + /* Note: Write register with some additional bits forced to state reset */ + /* instead of modifying only the selected bit for this function, */ + /* to not interfere with bits with HW property "rs". */ + MODIFY_REG(ADCx->CR, + ADC_CR_BITS_PROPERTY_RS, + ADC_CR_ADSTP); +} + +/** + * @brief Get ADC group regular conversion state. + * @rmtoll CR ADSTART LL_ADC_REG_IsConversionOngoing + * @param ADCx ADC instance + * @retval 0: no conversion is on going on ADC group regular. + */ +__STATIC_INLINE uint32_t LL_ADC_REG_IsConversionOngoing(const ADC_TypeDef *ADCx) +{ + return ((READ_BIT(ADCx->CR, ADC_CR_ADSTART) == (ADC_CR_ADSTART)) ? 1UL : 0UL); +} + +/** + * @brief Get ADC group regular command of conversion stop state + * @rmtoll CR ADSTP LL_ADC_REG_IsStopConversionOngoing + * @param ADCx ADC instance + * @retval 0: no command of conversion stop is on going on ADC group regular. + */ +__STATIC_INLINE uint32_t LL_ADC_REG_IsStopConversionOngoing(const ADC_TypeDef *ADCx) +{ + return ((READ_BIT(ADCx->CR, ADC_CR_ADSTP) == (ADC_CR_ADSTP)) ? 1UL : 0UL); +} + +/** + * @brief Start ADC sampling phase for sampling time trigger mode + * @note This function is relevant only when + * - @ref LL_ADC_REG_SAMPLING_MODE_TRIGGER_CONTROLED has been set + * using @ref LL_ADC_REG_SetSamplingMode + * - @ref LL_ADC_REG_TRIG_SOFTWARE is used as trigger source + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be enabled without conversion on going on group regular, + * without conversion stop command on going on group regular, + * without ADC disable command on going. + * @rmtoll CFGR2 SWTRIG LL_ADC_REG_StartSamplingPhase + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_REG_StartSamplingPhase(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->CFGR2, ADC_CFGR2_SWTRIG); +} + +/** + * @brief Stop ADC sampling phase for sampling time trigger mode and start conversion + * @note This function is relevant only when + * - @ref LL_ADC_REG_SAMPLING_MODE_TRIGGER_CONTROLED has been set + * using @ref LL_ADC_REG_SetSamplingMode + * - @ref LL_ADC_REG_TRIG_SOFTWARE is used as trigger source + * - @ref LL_ADC_REG_StartSamplingPhase has been called to start + * the sampling phase + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be enabled without conversion on going on group regular, + * without conversion stop command on going on group regular, + * without ADC disable command on going. + * @rmtoll CFGR2 SWTRIG LL_ADC_REG_StopSamplingPhase + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_REG_StopSamplingPhase(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->CFGR2, ADC_CFGR2_SWTRIG); +} + +/** + * @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 (uint32_t)(READ_BIT(ADCx->DR, ADC_DR_RDATA)); +} + +/** + * @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_RDATA)); +} + +/** + * @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_RDATA)); +} + +/** + * @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_RDATA)); +} + +/** + * @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_RDATA)); +} + +#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 RDATA_MST LL_ADC_REG_ReadMultiConversionData32\n + * CDR RDATA_SLV 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, + ConversionData) + >> (POSITION_VAL(ConversionData) & 0x1FUL) + ); +} +#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 for both + * internal trigger (SW start) and 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 + * will start at next trigger event (on the selected trigger edge) + * following the ADC start conversion command. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be enabled without conversion on going on group injected, + * without conversion stop command on going on group injected, + * without ADC disable command on going. + * @rmtoll CR JADSTART LL_ADC_INJ_StartConversion + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_INJ_StartConversion(ADC_TypeDef *ADCx) +{ + /* Note: Write register with some additional bits forced to state reset */ + /* instead of modifying only the selected bit for this function, */ + /* to not interfere with bits with HW property "rs". */ + MODIFY_REG(ADCx->CR, + ADC_CR_BITS_PROPERTY_RS, + ADC_CR_JADSTART); +} + +/** + * @brief Stop ADC group injected conversion. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be enabled with conversion on going on group injected, + * without ADC disable command on going. + * @rmtoll CR JADSTP LL_ADC_INJ_StopConversion + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_INJ_StopConversion(ADC_TypeDef *ADCx) +{ + /* Note: Write register with some additional bits forced to state reset */ + /* instead of modifying only the selected bit for this function, */ + /* to not interfere with bits with HW property "rs". */ + MODIFY_REG(ADCx->CR, + ADC_CR_BITS_PROPERTY_RS, + ADC_CR_JADSTP); +} + +/** + * @brief Get ADC group injected conversion state. + * @rmtoll CR JADSTART LL_ADC_INJ_IsConversionOngoing + * @param ADCx ADC instance + * @retval 0: no conversion is on going on ADC group injected. + */ +__STATIC_INLINE uint32_t LL_ADC_INJ_IsConversionOngoing(const ADC_TypeDef *ADCx) +{ + return ((READ_BIT(ADCx->CR, ADC_CR_JADSTART) == (ADC_CR_JADSTART)) ? 1UL : 0UL); +} + +/** + * @brief Get ADC group injected command of conversion stop state + * @rmtoll CR JADSTP LL_ADC_INJ_IsStopConversionOngoing + * @param ADCx ADC instance + * @retval 0: no command of conversion stop is on going on ADC group injected. + */ +__STATIC_INLINE uint32_t LL_ADC_INJ_IsStopConversionOngoing(const ADC_TypeDef *ADCx) +{ + return ((READ_BIT(ADCx->CR, ADC_CR_JADSTP) == (ADC_CR_JADSTP)) ? 1UL : 0UL); +} + +/** + * @brief Get ADC group injected 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) +{ + const __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->JDR1, + ((Rank & ADC_INJ_JDRX_REGOFFSET_MASK) >> ADC_JDRX_REGOFFSET_POS)); + + 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) +{ + const __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->JDR1, + ((Rank & ADC_INJ_JDRX_REGOFFSET_MASK) >> ADC_JDRX_REGOFFSET_POS)); + + 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) +{ + const __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->JDR1, + ((Rank & ADC_INJ_JDRX_REGOFFSET_MASK) >> ADC_JDRX_REGOFFSET_POS)); + + 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) +{ + const __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->JDR1, + ((Rank & ADC_INJ_JDRX_REGOFFSET_MASK) >> ADC_JDRX_REGOFFSET_POS)); + + 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) +{ + const __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->JDR1, + ((Rank & ADC_INJ_JDRX_REGOFFSET_MASK) >> ADC_JDRX_REGOFFSET_POS)); + + return (uint8_t)(READ_BIT(*preg, + ADC_JDR1_JDATA) + ); +} + +/** + * @} + */ + +/** @defgroup ADC_LL_EF_FLAG_Management ADC flag management + * @{ + */ + +/** + * @brief Get flag ADC ready. + * @note On this STM32 series, flag LL_ADC_FLAG_ADRDY is raised when the ADC + * is enabled and when conversion clock is active. + * (not only core clock: this ADC has a dual clock domain) + * @rmtoll ISR ADRDY LL_ADC_IsActiveFlag_ADRDY + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_ADRDY(const ADC_TypeDef *ADCx) +{ + return ((READ_BIT(ADCx->ISR, LL_ADC_FLAG_ADRDY) == (LL_ADC_FLAG_ADRDY)) ? 1UL : 0UL); +} + +/** + * @brief Get flag ADC group regular end of unitary conversion. + * @rmtoll ISR EOC LL_ADC_IsActiveFlag_EOC + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_EOC(const ADC_TypeDef *ADCx) +{ + return ((READ_BIT(ADCx->ISR, ADC_ISR_EOC) == (ADC_ISR_EOC)) ? 1UL : 0UL); +} + +/** + * @brief Get flag ADC group regular end of sequence conversions. + * @rmtoll ISR EOS LL_ADC_IsActiveFlag_EOS + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_EOS(const ADC_TypeDef *ADCx) +{ + return ((READ_BIT(ADCx->ISR, LL_ADC_FLAG_EOS) == (LL_ADC_FLAG_EOS)) ? 1UL : 0UL); +} + +/** + * @brief Get flag ADC group regular overrun. + * @rmtoll ISR 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->ISR, LL_ADC_FLAG_OVR) == (LL_ADC_FLAG_OVR)) ? 1UL : 0UL); +} + +/** + * @brief Get flag ADC group regular end of sampling phase. + * @rmtoll ISR EOSMP LL_ADC_IsActiveFlag_EOSMP + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_EOSMP(const ADC_TypeDef *ADCx) +{ + return ((READ_BIT(ADCx->ISR, LL_ADC_FLAG_EOSMP) == (LL_ADC_FLAG_EOSMP)) ? 1UL : 0UL); +} + +/** + * @brief Get flag ADC group injected end of unitary conversion. + * @rmtoll ISR JEOC LL_ADC_IsActiveFlag_JEOC + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_JEOC(const ADC_TypeDef *ADCx) +{ + return ((READ_BIT(ADCx->ISR, LL_ADC_FLAG_JEOC) == (LL_ADC_FLAG_JEOC)) ? 1UL : 0UL); +} + +/** + * @brief Get flag ADC group injected end of sequence conversions. + * @rmtoll ISR JEOS 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) +{ + return ((READ_BIT(ADCx->ISR, LL_ADC_FLAG_JEOS) == (LL_ADC_FLAG_JEOS)) ? 1UL : 0UL); +} + +/** + * @brief Get flag ADC group injected contexts queue overflow. + * @rmtoll ISR JQOVF LL_ADC_IsActiveFlag_JQOVF + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_JQOVF(const ADC_TypeDef *ADCx) +{ + return ((READ_BIT(ADCx->ISR, LL_ADC_FLAG_JQOVF) == (LL_ADC_FLAG_JQOVF)) ? 1UL : 0UL); +} + +/** + * @brief Get flag ADC analog watchdog 1 flag + * @rmtoll ISR AWD1 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->ISR, LL_ADC_FLAG_AWD1) == (LL_ADC_FLAG_AWD1)) ? 1UL : 0UL); +} + +/** + * @brief Get flag ADC analog watchdog 2. + * @rmtoll ISR AWD2 LL_ADC_IsActiveFlag_AWD2 + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_AWD2(const ADC_TypeDef *ADCx) +{ + return ((READ_BIT(ADCx->ISR, LL_ADC_FLAG_AWD2) == (LL_ADC_FLAG_AWD2)) ? 1UL : 0UL); +} + +/** + * @brief Get flag ADC analog watchdog 3. + * @rmtoll ISR AWD3 LL_ADC_IsActiveFlag_AWD3 + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_AWD3(const ADC_TypeDef *ADCx) +{ + return ((READ_BIT(ADCx->ISR, LL_ADC_FLAG_AWD3) == (LL_ADC_FLAG_AWD3)) ? 1UL : 0UL); +} + +/** + * @brief Clear flag ADC ready. + * @note On this STM32 series, flag LL_ADC_FLAG_ADRDY is raised when the ADC + * is enabled and when conversion clock is active. + * (not only core clock: this ADC has a dual clock domain) + * @rmtoll ISR ADRDY LL_ADC_ClearFlag_ADRDY + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_ClearFlag_ADRDY(ADC_TypeDef *ADCx) +{ + WRITE_REG(ADCx->ISR, LL_ADC_FLAG_ADRDY); +} + +/** + * @brief Clear flag ADC group regular end of unitary conversion. + * @rmtoll ISR EOC LL_ADC_ClearFlag_EOC + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_ClearFlag_EOC(ADC_TypeDef *ADCx) +{ + WRITE_REG(ADCx->ISR, LL_ADC_FLAG_EOC); +} + +/** + * @brief Clear flag ADC group regular end of sequence conversions. + * @rmtoll ISR EOS LL_ADC_ClearFlag_EOS + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_ClearFlag_EOS(ADC_TypeDef *ADCx) +{ + WRITE_REG(ADCx->ISR, LL_ADC_FLAG_EOS); +} + +/** + * @brief Clear flag ADC group regular overrun. + * @rmtoll ISR OVR LL_ADC_ClearFlag_OVR + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_ClearFlag_OVR(ADC_TypeDef *ADCx) +{ + WRITE_REG(ADCx->ISR, LL_ADC_FLAG_OVR); +} + +/** + * @brief Clear flag ADC group regular end of sampling phase. + * @rmtoll ISR EOSMP LL_ADC_ClearFlag_EOSMP + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_ClearFlag_EOSMP(ADC_TypeDef *ADCx) +{ + WRITE_REG(ADCx->ISR, LL_ADC_FLAG_EOSMP); +} + +/** + * @brief Clear flag ADC group injected end of unitary conversion. + * @rmtoll ISR JEOC LL_ADC_ClearFlag_JEOC + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_ClearFlag_JEOC(ADC_TypeDef *ADCx) +{ + WRITE_REG(ADCx->ISR, LL_ADC_FLAG_JEOC); +} + +/** + * @brief Clear flag ADC group injected end of sequence conversions. + * @rmtoll ISR JEOS LL_ADC_ClearFlag_JEOS + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_ClearFlag_JEOS(ADC_TypeDef *ADCx) +{ + WRITE_REG(ADCx->ISR, LL_ADC_FLAG_JEOS); +} + +/** + * @brief Clear flag ADC group injected contexts queue overflow. + * @rmtoll ISR JQOVF LL_ADC_ClearFlag_JQOVF + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_ClearFlag_JQOVF(ADC_TypeDef *ADCx) +{ + WRITE_REG(ADCx->ISR, LL_ADC_FLAG_JQOVF); +} + +/** + * @brief Clear flag ADC analog watchdog 1. + * @rmtoll ISR AWD1 LL_ADC_ClearFlag_AWD1 + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_ClearFlag_AWD1(ADC_TypeDef *ADCx) +{ + WRITE_REG(ADCx->ISR, LL_ADC_FLAG_AWD1); +} + +/** + * @brief Clear flag ADC analog watchdog 2. + * @rmtoll ISR AWD2 LL_ADC_ClearFlag_AWD2 + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_ClearFlag_AWD2(ADC_TypeDef *ADCx) +{ + WRITE_REG(ADCx->ISR, LL_ADC_FLAG_AWD2); +} + +/** + * @brief Clear flag ADC analog watchdog 3. + * @rmtoll ISR AWD3 LL_ADC_ClearFlag_AWD3 + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_ClearFlag_AWD3(ADC_TypeDef *ADCx) +{ + WRITE_REG(ADCx->ISR, LL_ADC_FLAG_AWD3); +} + +#if defined(ADC_MULTIMODE_SUPPORT) +/** + * @brief Get flag multimode ADC ready of the ADC master. + * @rmtoll CSR ADRDY_MST LL_ADC_IsActiveFlag_MST_ADRDY + * @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_ADRDY(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return ((READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_ADRDY_MST) == (LL_ADC_FLAG_ADRDY_MST)) ? 1UL : 0UL); +} + +/** + * @brief Get flag multimode ADC ready of the ADC slave. + * @rmtoll CSR ADRDY_SLV LL_ADC_IsActiveFlag_SLV_ADRDY + * @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_SLV_ADRDY(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return ((READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_ADRDY_SLV) == (LL_ADC_FLAG_ADRDY_SLV)) ? 1UL : 0UL); +} + +/** + * @brief Get flag multimode ADC group regular end of unitary conversion of the ADC master. + * @rmtoll CSR EOC_MST LL_ADC_IsActiveFlag_MST_EOC + * @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_EOC(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return ((READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_EOC_SLV) == (LL_ADC_FLAG_EOC_SLV)) ? 1UL : 0UL); +} + +/** + * @brief Get flag multimode ADC group regular end of unitary conversion of the ADC slave. + * @rmtoll CSR EOC_SLV LL_ADC_IsActiveFlag_SLV_EOC + * @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_SLV_EOC(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return ((READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_EOC_SLV) == (LL_ADC_FLAG_EOC_SLV)) ? 1UL : 0UL); +} + +/** + * @brief Get flag multimode ADC group regular end of sequence conversions of the ADC master. + * @rmtoll CSR EOS_MST LL_ADC_IsActiveFlag_MST_EOS + * @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_EOS(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return ((READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_EOS_MST) == (LL_ADC_FLAG_EOS_MST)) ? 1UL : 0UL); +} + +/** + * @brief Get flag multimode ADC group regular end of sequence conversions of the ADC slave. + * @rmtoll CSR EOS_SLV LL_ADC_IsActiveFlag_SLV_EOS + * @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_SLV_EOS(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return ((READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_EOS_SLV) == (LL_ADC_FLAG_EOS_SLV)) ? 1UL : 0UL); +} + +/** + * @brief Get flag multimode ADC group regular overrun of the ADC master. + * @rmtoll CSR OVR_MST 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)) ? 1UL : 0UL); +} + +/** + * @brief Get flag multimode ADC group regular overrun of the ADC slave. + * @rmtoll CSR OVR_SLV LL_ADC_IsActiveFlag_SLV_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_SLV_OVR(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return ((READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_OVR_SLV) == (LL_ADC_FLAG_OVR_SLV)) ? 1UL : 0UL); +} + +/** + * @brief Get flag multimode ADC group regular end of sampling of the ADC master. + * @rmtoll CSR EOSMP_MST LL_ADC_IsActiveFlag_MST_EOSMP + * @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_EOSMP(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return ((READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_EOSMP_MST) == (LL_ADC_FLAG_EOSMP_MST)) ? 1UL : 0UL); +} + +/** + * @brief Get flag multimode ADC group regular end of sampling of the ADC slave. + * @rmtoll CSR EOSMP_SLV LL_ADC_IsActiveFlag_SLV_EOSMP + * @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_SLV_EOSMP(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return ((READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_EOSMP_SLV) == (LL_ADC_FLAG_EOSMP_SLV)) ? 1UL : 0UL); +} + +/** + * @brief Get flag multimode ADC group injected end of unitary conversion of the ADC master. + * @rmtoll CSR JEOC_MST LL_ADC_IsActiveFlag_MST_JEOC + * @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_JEOC(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return ((READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_JEOC_MST) == (LL_ADC_FLAG_JEOC_MST)) ? 1UL : 0UL); +} + +/** + * @brief Get flag multimode ADC group injected end of unitary conversion of the ADC slave. + * @rmtoll CSR JEOC_SLV LL_ADC_IsActiveFlag_SLV_JEOC + * @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_SLV_JEOC(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return ((READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_JEOC_SLV) == (LL_ADC_FLAG_JEOC_SLV)) ? 1UL : 0UL); +} + +/** + * @brief Get flag multimode ADC group injected end of sequence conversions of the ADC master. + * @rmtoll CSR JEOS_MST 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) +{ + return ((READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_JEOS_MST) == (LL_ADC_FLAG_JEOS_MST)) ? 1UL : 0UL); +} + +/** + * @brief Get flag multimode ADC group injected end of sequence conversions of the ADC slave. + * @rmtoll CSR JEOS_SLV LL_ADC_IsActiveFlag_SLV_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_SLV_JEOS(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return ((READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_JEOS_SLV) == (LL_ADC_FLAG_JEOS_SLV)) ? 1UL : 0UL); +} + +/** + * @brief Get flag multimode ADC group injected context queue overflow of the ADC master. + * @rmtoll CSR JQOVF_MST LL_ADC_IsActiveFlag_MST_JQOVF + * @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_JQOVF(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return ((READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_JQOVF_MST) == (LL_ADC_FLAG_JQOVF_MST)) ? 1UL : 0UL); +} + +/** + * @brief Get flag multimode ADC group injected context queue overflow of the ADC slave. + * @rmtoll CSR JQOVF_SLV LL_ADC_IsActiveFlag_SLV_JQOVF + * @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_SLV_JQOVF(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return ((READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_JQOVF_SLV) == (LL_ADC_FLAG_JQOVF_SLV)) ? 1UL : 0UL); +} + +/** + * @brief Get flag multimode ADC analog watchdog 1 of the ADC master. + * @rmtoll CSR AWD1_MST 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)) ? 1UL : 0UL); +} + +/** + * @brief Get flag multimode analog watchdog 1 of the ADC slave. + * @rmtoll CSR AWD1_SLV LL_ADC_IsActiveFlag_SLV_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_SLV_AWD1(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return ((READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_AWD1_SLV) == (LL_ADC_FLAG_AWD1_SLV)) ? 1UL : 0UL); +} + +/** + * @brief Get flag multimode ADC analog watchdog 2 of the ADC master. + * @rmtoll CSR AWD2_MST LL_ADC_IsActiveFlag_MST_AWD2 + * @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_AWD2(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return ((READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_AWD2_MST) == (LL_ADC_FLAG_AWD2_MST)) ? 1UL : 0UL); +} + +/** + * @brief Get flag multimode ADC analog watchdog 2 of the ADC slave. + * @rmtoll CSR AWD2_SLV LL_ADC_IsActiveFlag_SLV_AWD2 + * @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_SLV_AWD2(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return ((READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_AWD2_SLV) == (LL_ADC_FLAG_AWD2_SLV)) ? 1UL : 0UL); +} + +/** + * @brief Get flag multimode ADC analog watchdog 3 of the ADC master. + * @rmtoll CSR AWD3_MST LL_ADC_IsActiveFlag_MST_AWD3 + * @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_AWD3(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return ((READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_AWD3_MST) == (LL_ADC_FLAG_AWD3_MST)) ? 1UL : 0UL); +} + +/** + * @brief Get flag multimode ADC analog watchdog 3 of the ADC slave. + * @rmtoll CSR AWD3_SLV LL_ADC_IsActiveFlag_SLV_AWD3 + * @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_SLV_AWD3(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + return ((READ_BIT(ADCxy_COMMON->CSR, LL_ADC_FLAG_AWD3_SLV) == (LL_ADC_FLAG_AWD3_SLV)) ? 1UL : 0UL); +} +#endif /* ADC_MULTIMODE_SUPPORT */ + +/** + * @} + */ + +/** @defgroup ADC_LL_EF_IT_Management ADC IT management + * @{ + */ + +/** + * @brief Enable ADC ready. + * @rmtoll IER ADRDYIE LL_ADC_EnableIT_ADRDY + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_EnableIT_ADRDY(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->IER, LL_ADC_IT_ADRDY); +} + +/** + * @brief Enable interruption ADC group regular end of unitary conversion. + * @rmtoll IER EOCIE LL_ADC_EnableIT_EOC + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_EnableIT_EOC(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->IER, LL_ADC_IT_EOC); +} + +/** + * @brief Enable interruption ADC group regular end of sequence conversions. + * @rmtoll IER EOSIE LL_ADC_EnableIT_EOS + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_EnableIT_EOS(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->IER, LL_ADC_IT_EOS); +} + +/** + * @brief Enable ADC group regular interruption overrun. + * @rmtoll IER OVRIE LL_ADC_EnableIT_OVR + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_EnableIT_OVR(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->IER, LL_ADC_IT_OVR); +} + +/** + * @brief Enable interruption ADC group regular end of sampling. + * @rmtoll IER EOSMPIE LL_ADC_EnableIT_EOSMP + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_EnableIT_EOSMP(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->IER, LL_ADC_IT_EOSMP); +} + +/** + * @brief Enable interruption ADC group injected end of unitary conversion. + * @rmtoll IER JEOCIE LL_ADC_EnableIT_JEOC + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_EnableIT_JEOC(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->IER, LL_ADC_IT_JEOC); +} + +/** + * @brief Enable interruption ADC group injected end of sequence conversions. + * @rmtoll IER JEOSIE LL_ADC_EnableIT_JEOS + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_EnableIT_JEOS(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->IER, LL_ADC_IT_JEOS); +} + +/** + * @brief Enable interruption ADC group injected context queue overflow. + * @rmtoll IER JQOVFIE LL_ADC_EnableIT_JQOVF + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_EnableIT_JQOVF(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->IER, LL_ADC_IT_JQOVF); +} + +/** + * @brief Enable interruption ADC analog watchdog 1. + * @rmtoll IER AWD1IE LL_ADC_EnableIT_AWD1 + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_EnableIT_AWD1(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->IER, LL_ADC_IT_AWD1); +} + +/** + * @brief Enable interruption ADC analog watchdog 2. + * @rmtoll IER AWD2IE LL_ADC_EnableIT_AWD2 + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_EnableIT_AWD2(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->IER, LL_ADC_IT_AWD2); +} + +/** + * @brief Enable interruption ADC analog watchdog 3. + * @rmtoll IER AWD3IE LL_ADC_EnableIT_AWD3 + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_EnableIT_AWD3(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->IER, LL_ADC_IT_AWD3); +} + +/** + * @brief Disable interruption ADC ready. + * @rmtoll IER ADRDYIE LL_ADC_DisableIT_ADRDY + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_DisableIT_ADRDY(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->IER, LL_ADC_IT_ADRDY); +} + +/** + * @brief Disable interruption ADC group regular end of unitary conversion. + * @rmtoll IER EOCIE LL_ADC_DisableIT_EOC + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_DisableIT_EOC(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->IER, LL_ADC_IT_EOC); +} + +/** + * @brief Disable interruption ADC group regular end of sequence conversions. + * @rmtoll IER EOSIE LL_ADC_DisableIT_EOS + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_DisableIT_EOS(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->IER, LL_ADC_IT_EOS); +} + +/** + * @brief Disable interruption ADC group regular overrun. + * @rmtoll IER OVRIE LL_ADC_DisableIT_OVR + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_DisableIT_OVR(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->IER, LL_ADC_IT_OVR); +} + +/** + * @brief Disable interruption ADC group regular end of sampling. + * @rmtoll IER EOSMPIE LL_ADC_DisableIT_EOSMP + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_DisableIT_EOSMP(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->IER, LL_ADC_IT_EOSMP); +} + +/** + * @brief Disable interruption ADC group regular end of unitary conversion. + * @rmtoll IER JEOCIE LL_ADC_DisableIT_JEOC + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_DisableIT_JEOC(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->IER, LL_ADC_IT_JEOC); +} + +/** + * @brief Disable interruption ADC group injected end of sequence conversions. + * @rmtoll IER JEOSIE LL_ADC_DisableIT_JEOS + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_DisableIT_JEOS(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->IER, LL_ADC_IT_JEOS); +} + +/** + * @brief Disable interruption ADC group injected context queue overflow. + * @rmtoll IER JQOVFIE LL_ADC_DisableIT_JQOVF + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_DisableIT_JQOVF(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->IER, LL_ADC_IT_JQOVF); +} + +/** + * @brief Disable interruption ADC analog watchdog 1. + * @rmtoll IER AWD1IE LL_ADC_DisableIT_AWD1 + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_DisableIT_AWD1(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->IER, LL_ADC_IT_AWD1); +} + +/** + * @brief Disable interruption ADC analog watchdog 2. + * @rmtoll IER AWD2IE LL_ADC_DisableIT_AWD2 + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_DisableIT_AWD2(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->IER, LL_ADC_IT_AWD2); +} + +/** + * @brief Disable interruption ADC analog watchdog 3. + * @rmtoll IER AWD3IE LL_ADC_DisableIT_AWD3 + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_DisableIT_AWD3(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->IER, LL_ADC_IT_AWD3); +} + +/** + * @brief Get state of interruption ADC ready + * (0: interrupt disabled, 1: interrupt enabled). + * @rmtoll IER ADRDYIE LL_ADC_IsEnabledIT_ADRDY + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsEnabledIT_ADRDY(const ADC_TypeDef *ADCx) +{ + return ((READ_BIT(ADCx->IER, LL_ADC_IT_ADRDY) == (LL_ADC_IT_ADRDY)) ? 1UL : 0UL); +} + +/** + * @brief Get state of interruption ADC group regular end of unitary conversion + * (0: interrupt disabled, 1: interrupt enabled). + * @rmtoll IER EOCIE LL_ADC_IsEnabledIT_EOC + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsEnabledIT_EOC(const ADC_TypeDef *ADCx) +{ + return ((READ_BIT(ADCx->IER, LL_ADC_IT_EOC) == (LL_ADC_IT_EOC)) ? 1UL : 0UL); +} + +/** + * @brief Get state of interruption ADC group regular end of sequence conversions + * (0: interrupt disabled, 1: interrupt enabled). + * @rmtoll IER EOSIE LL_ADC_IsEnabledIT_EOS + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsEnabledIT_EOS(const ADC_TypeDef *ADCx) +{ + return ((READ_BIT(ADCx->IER, LL_ADC_IT_EOS) == (LL_ADC_IT_EOS)) ? 1UL : 0UL); +} + +/** + * @brief Get state of interruption ADC group regular overrun + * (0: interrupt disabled, 1: interrupt enabled). + * @rmtoll IER 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->IER, LL_ADC_IT_OVR) == (LL_ADC_IT_OVR)) ? 1UL : 0UL); +} + +/** + * @brief Get state of interruption ADC group regular end of sampling + * (0: interrupt disabled, 1: interrupt enabled). + * @rmtoll IER EOSMPIE LL_ADC_IsEnabledIT_EOSMP + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsEnabledIT_EOSMP(const ADC_TypeDef *ADCx) +{ + return ((READ_BIT(ADCx->IER, LL_ADC_IT_EOSMP) == (LL_ADC_IT_EOSMP)) ? 1UL : 0UL); +} + +/** + * @brief Get state of interruption ADC group injected end of unitary conversion + * (0: interrupt disabled, 1: interrupt enabled). + * @rmtoll IER JEOCIE LL_ADC_IsEnabledIT_JEOC + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsEnabledIT_JEOC(const ADC_TypeDef *ADCx) +{ + return ((READ_BIT(ADCx->IER, LL_ADC_IT_JEOC) == (LL_ADC_IT_JEOC)) ? 1UL : 0UL); +} + +/** + * @brief Get state of interruption ADC group injected end of sequence conversions + * (0: interrupt disabled, 1: interrupt enabled). + * @rmtoll IER JEOSIE LL_ADC_IsEnabledIT_JEOS + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsEnabledIT_JEOS(const ADC_TypeDef *ADCx) +{ + return ((READ_BIT(ADCx->IER, LL_ADC_IT_JEOS) == (LL_ADC_IT_JEOS)) ? 1UL : 0UL); +} + +/** + * @brief Get state of interruption ADC group injected context queue overflow interrupt state + * (0: interrupt disabled, 1: interrupt enabled). + * @rmtoll IER JQOVFIE LL_ADC_IsEnabledIT_JQOVF + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsEnabledIT_JQOVF(const ADC_TypeDef *ADCx) +{ + return ((READ_BIT(ADCx->IER, LL_ADC_IT_JQOVF) == (LL_ADC_IT_JQOVF)) ? 1UL : 0UL); +} + +/** + * @brief Get state of interruption ADC analog watchdog 1 + * (0: interrupt disabled, 1: interrupt enabled). + * @rmtoll IER AWD1IE LL_ADC_IsEnabledIT_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->IER, LL_ADC_IT_AWD1) == (LL_ADC_IT_AWD1)) ? 1UL : 0UL); +} + +/** + * @brief Get state of interruption Get ADC analog watchdog 2 + * (0: interrupt disabled, 1: interrupt enabled). + * @rmtoll IER AWD2IE LL_ADC_IsEnabledIT_AWD2 + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsEnabledIT_AWD2(const ADC_TypeDef *ADCx) +{ + return ((READ_BIT(ADCx->IER, LL_ADC_IT_AWD2) == (LL_ADC_IT_AWD2)) ? 1UL : 0UL); +} + +/** + * @brief Get state of interruption Get ADC analog watchdog 3 + * (0: interrupt disabled, 1: interrupt enabled). + * @rmtoll IER AWD3IE LL_ADC_IsEnabledIT_AWD3 + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsEnabledIT_AWD3(const ADC_TypeDef *ADCx) +{ + return ((READ_BIT(ADCx->IER, LL_ADC_IT_AWD3) == (LL_ADC_IT_AWD3)) ? 1UL : 0UL); +} + +/** + * @} + */ + +#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(const ADC_Common_TypeDef *ADCxy_COMMON); +ErrorStatus LL_ADC_CommonInit(ADC_Common_TypeDef *ADCxy_COMMON, const LL_ADC_CommonInitTypeDef *pADC_CommonInitStruct); +void LL_ADC_CommonStructInit(LL_ADC_CommonInitTypeDef *pADC_CommonInitStruct); + +/* De-initialization of ADC instance, ADC group regular and ADC group injected */ +/* (availability of ADC group injected depends on STM32 series) */ +ErrorStatus LL_ADC_DeInit(ADC_TypeDef *ADCx); + +/* Initialization of some features of ADC instance */ +ErrorStatus LL_ADC_Init(ADC_TypeDef *ADCx, const LL_ADC_InitTypeDef *pADC_InitStruct); +void LL_ADC_StructInit(LL_ADC_InitTypeDef *pADC_InitStruct); + +/* Initialization of some features of ADC instance and ADC group regular */ +ErrorStatus LL_ADC_REG_Init(ADC_TypeDef *ADCx, const LL_ADC_REG_InitTypeDef *pADC_RegInitStruct); +void LL_ADC_REG_StructInit(LL_ADC_REG_InitTypeDef *pADC_RegInitStruct); + +/* Initialization of some features of ADC instance and ADC group injected */ +ErrorStatus LL_ADC_INJ_Init(ADC_TypeDef *ADCx, const LL_ADC_INJ_InitTypeDef *pADC_InjInitStruct); +void LL_ADC_INJ_StructInit(LL_ADC_INJ_InitTypeDef *pADC_InjInitStruct); + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* ADC1 || ADC2 */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_LL_ADC_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_bus.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_bus.h new file mode 100644 index 0000000000..326d2d102f --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_bus.h @@ -0,0 +1,2809 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_bus.h + * @author MCD Application Team + * @brief Header file of BUS LL module. + + @verbatim + ##### RCC Limitations ##### + ============================================================================== + [..] + A delay between an RCC peripheral clock enable and the effective peripheral + enabling should be taken into account in order to manage the peripheral read/write + from/to registers. + (+) This delay depends on the peripheral mapping. + (++) AHB , APB peripherals, 1 dummy read is necessary + + [..] + Workarounds: + (#) For AHB , APB peripherals, a dummy read to the peripheral register has been + inserted in each LL_{BUS}_GRP{x}_EnableClock() function. + + @endverbatim + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32H5xx_LL_BUS_H +#define __STM32H5xx_LL_BUS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined(RCC) + +/** @defgroup BUS_LL BUS + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup BUS_LL_Exported_Constants BUS Exported Constants + * @{ + */ + +/** @defgroup BUS_LL_AHB_BRANCH_CLK_AHBx BRANCH CLK AHBx + * @{ + */ +#define LL_AHB_BRANCH_CLK_AHB1 RCC_CFGR2_AHB1DIS +#define LL_AHB_BRANCH_CLK_AHB2 RCC_CFGR2_AHB2DIS +#if defined(AHB4PERIPH_BASE) +#define LL_AHB_BRANCH_CLK_AHB4 RCC_CFGR2_AHB4DIS +#endif /* AHB4PERIPH_BASE */ +/** + * @} + */ + +/** @defgroup BUS_LL_APB_BRANCH_CLK_APBx BRANCH CLK APBx + * @{ + */ +#define LL_APB_BRANCH_CLK_APB1 RCC_CFGR2_APB1DIS +#define LL_APB_BRANCH_CLK_APB2 RCC_CFGR2_APB2DIS +#define LL_APB_BRANCH_CLK_APB3 RCC_CFGR2_APB3DIS +/** + * @} + */ + +/** @defgroup BUS_LL_EC_AHB1_GRP1_PERIPH AHB1 GRP1 PERIPH + * @{ + */ +#if defined(CORDIC) +#define LL_AHB1_GRP1_PERIPH_ALL 0xF13AD103U +#else +#define LL_AHB1_GRP1_PERIPH_ALL 0x91021103U +#endif /* CORDIC */ +#define LL_AHB1_GRP1_PERIPH_GPDMA1 RCC_AHB1ENR_GPDMA1EN +#define LL_AHB1_GRP1_PERIPH_GPDMA2 RCC_AHB1ENR_GPDMA2EN +#if defined(CORDIC) +#define LL_AHB1_GRP1_PERIPH_CORDIC RCC_AHB1ENR_CORDICEN +#endif /* CORDIC */ +#if defined(FMAC) +#define LL_AHB1_GRP1_PERIPH_FMAC RCC_AHB1ENR_FMACEN +#endif /* FMAC */ +#define LL_AHB1_GRP1_PERIPH_FLASH RCC_AHB1ENR_FLITFEN +#if defined(ETH) +#define LL_AHB1_GRP1_PERIPH_ETH RCC_AHB1ENR_ETHEN +#define LL_AHB1_GRP1_PERIPH_ETHTX RCC_AHB1ENR_ETHTXEN +#define LL_AHB1_GRP1_PERIPH_ETHRX RCC_AHB1ENR_ETHRXEN +#endif /* ETH */ +#define LL_AHB1_GRP1_PERIPH_CRC RCC_AHB1ENR_CRCEN +#define LL_AHB1_GRP1_PERIPH_RAMCFG RCC_AHB1ENR_RAMCFGEN +#define LL_AHB1_GRP1_PERIPH_GTZC1 RCC_AHB1ENR_TZSC1EN +#define LL_AHB1_GRP1_PERIPH_BKPSRAM RCC_AHB1ENR_BKPRAMEN +#define LL_AHB1_GRP1_PERIPH_ICACHE RCC_AHB1LPENR_ICACHELPEN +#if defined(DCACHE1) +#define LL_AHB1_GRP1_PERIPH_DCACHE1 RCC_AHB1ENR_DCACHE1EN +#endif /* DCACHE1 */ +#define LL_AHB1_GRP1_PERIPH_SRAM1 RCC_AHB1ENR_SRAM1EN +/** + * @} + */ + +/** @defgroup BUS_LL_EC_AHB2_GRP1_PERIPH AHB2 GRP1 PERIPH + * @{ + */ +#if defined(GPIOE) +#define LL_AHB2_GRP1_PERIPH_ALL 0xC01F1DFFU +#else +#define LL_AHB2_GRP1_PERIPH_ALL 0x40060C8FU +#endif /* GPIOE */ +#define LL_AHB2_GRP1_PERIPH_GPIOA RCC_AHB2ENR_GPIOAEN +#define LL_AHB2_GRP1_PERIPH_GPIOB RCC_AHB2ENR_GPIOBEN +#define LL_AHB2_GRP1_PERIPH_GPIOC RCC_AHB2ENR_GPIOCEN +#define LL_AHB2_GRP1_PERIPH_GPIOD RCC_AHB2ENR_GPIODEN +#if defined(GPIOE) +#define LL_AHB2_GRP1_PERIPH_GPIOE RCC_AHB2ENR_GPIOEEN +#endif /* GPIOE */ +#if defined(GPIOF) +#define LL_AHB2_GRP1_PERIPH_GPIOF RCC_AHB2ENR_GPIOFEN +#endif /* GPIOF */ +#if defined(GPIOG) +#define LL_AHB2_GRP1_PERIPH_GPIOG RCC_AHB2ENR_GPIOGEN +#endif /* GPIOG */ +#define LL_AHB2_GRP1_PERIPH_GPIOH RCC_AHB2ENR_GPIOHEN +#if defined(GPIOI) +#define LL_AHB2_GRP1_PERIPH_GPIOI RCC_AHB2ENR_GPIOIEN +#endif /* GPIOI */ +#define LL_AHB2_GRP1_PERIPH_ADC RCC_AHB2ENR_ADCEN +#define LL_AHB2_GRP1_PERIPH_DAC1 RCC_AHB2ENR_DAC1EN +#if defined(DCMI) +#define LL_AHB2_GRP1_PERIPH_DCMI_PSSI RCC_AHB2ENR_DCMI_PSSIEN +#endif /* DCMI */ +#if defined(AES) +#define LL_AHB2_GRP1_PERIPH_AES RCC_AHB2ENR_AESEN +#endif /* AES */ +#if defined(HASH) +#define LL_AHB2_GRP1_PERIPH_HASH RCC_AHB2ENR_HASHEN +#endif /* HASH */ +#define LL_AHB2_GRP1_PERIPH_RNG RCC_AHB2ENR_RNGEN +#if defined(PKA) +#define LL_AHB2_GRP1_PERIPH_PKA RCC_AHB2ENR_PKAEN +#endif /* PKA */ +#if defined(SAES) +#define LL_AHB2_GRP1_PERIPH_SAES RCC_AHB2ENR_SAESEN +#endif /* SAES */ +#define LL_AHB2_GRP1_PERIPH_SRAM2 RCC_AHB2ENR_SRAM2EN +#if defined(SRAM3_BASE) +#define LL_AHB2_GRP1_PERIPH_SRAM3 RCC_AHB2ENR_SRAM3EN +#endif /* SRAM3_BASE */ + +/** + * @} + */ +#if defined(AHB4PERIPH_BASE) +/** @defgroup BUS_LL_EC_AHB4_GRP1_PERIPH AHB4 GRP1 PERIPH + * @{ + */ +#define LL_AHB4_GRP1_PERIPH_ALL 0x00111880U +#define LL_AHB4_GRP1_PERIPH_OTFDEC RCC_AHB4ENR_OTFDEC1EN +#define LL_AHB4_GRP1_PERIPH_SDMMC1 RCC_AHB4ENR_SDMMC1EN +#if defined(SDMMC2) +#define LL_AHB4_GRP1_PERIPH_SDMMC2 RCC_AHB4ENR_SDMMC2EN +#endif /* SDMMC2*/ +#define LL_AHB4_GRP1_PERIPH_FMC RCC_AHB4ENR_FMCEN +#define LL_AHB4_GRP1_PERIPH_OSPI1 RCC_AHB4ENR_OCTOSPI1EN +/** + * @} + */ +#endif /* AHB4PERIPH_BASE */ + +/** @defgroup BUS_LL_EC_APB1_GRP1_PERIPH APB1 GRP1 PERIPH + * @{ + */ +#if defined(TIM4) +#define LL_APB1_GRP1_PERIPH_ALL 0xDFFEC9FFU +#else +#define LL_APB1_GRP1_PERIPH_ALL 0x01E7E833U +#endif /* TIM4 */ +#define LL_APB1_GRP1_PERIPH_TIM2 RCC_APB1LENR_TIM2EN +#define LL_APB1_GRP1_PERIPH_TIM3 RCC_APB1LENR_TIM3EN +#if defined(TIM4) +#define LL_APB1_GRP1_PERIPH_TIM4 RCC_APB1LENR_TIM4EN +#endif /* TIM4*/ +#if defined(TIM5) +#define LL_APB1_GRP1_PERIPH_TIM5 RCC_APB1LENR_TIM5EN +#endif /* TIM5*/ +#define LL_APB1_GRP1_PERIPH_TIM6 RCC_APB1LENR_TIM6EN +#define LL_APB1_GRP1_PERIPH_TIM7 RCC_APB1LENR_TIM7EN +#if defined(TIM12) +#define LL_APB1_GRP1_PERIPH_TIM12 RCC_APB1LENR_TIM12EN +#endif /* TIM12*/ +#if defined(TIM13) +#define LL_APB1_GRP1_PERIPH_TIM13 RCC_APB1LENR_TIM13EN +#endif /* TIM13*/ +#if defined(TIM14) +#define LL_APB1_GRP1_PERIPH_TIM14 RCC_APB1LENR_TIM14EN +#endif /* TIM14*/ +#define LL_APB1_GRP1_PERIPH_WWDG RCC_APB1LENR_WWDGEN +#if defined(OPAMP1) +#define LL_APB1_GRP1_PERIPH_OPAMP RCC_APB1LENR_OPAMPEN +#endif /* OPAMP1 */ +#define LL_APB1_GRP1_PERIPH_SPI2 RCC_APB1LENR_SPI2EN +#define LL_APB1_GRP1_PERIPH_SPI3 RCC_APB1LENR_SPI3EN +#if defined(COMP1) +#define LL_APB1_GRP1_PERIPH_COMP RCC_APB1LENR_COMPEN +#endif /* COMP1 */ +#define LL_APB1_GRP1_PERIPH_USART2 RCC_APB1LENR_USART2EN +#define LL_APB1_GRP1_PERIPH_USART3 RCC_APB1LENR_USART3EN +#if defined(UART4) +#define LL_APB1_GRP1_PERIPH_UART4 RCC_APB1LENR_UART4EN +#endif /* UART4*/ +#if defined(UART5) +#define LL_APB1_GRP1_PERIPH_UART5 RCC_APB1LENR_UART5EN +#endif /* UART5*/ +#define LL_APB1_GRP1_PERIPH_I2C1 RCC_APB1LENR_I2C1EN +#define LL_APB1_GRP1_PERIPH_I2C2 RCC_APB1LENR_I2C2EN +#define LL_APB1_GRP1_PERIPH_I3C1 RCC_APB1LENR_I3C1EN +#define LL_APB1_GRP1_PERIPH_CRS RCC_APB1LENR_CRSEN +#if defined(USART6) +#define LL_APB1_GRP1_PERIPH_USART6 RCC_APB1LENR_USART6EN +#endif /* USART6*/ +#if defined(USART10) +#define LL_APB1_GRP1_PERIPH_USART10 RCC_APB1LENR_USART10EN +#endif /* USART10*/ +#if defined(USART11) +#define LL_APB1_GRP1_PERIPH_USART11 RCC_APB1LENR_USART11EN +#endif /* USART11*/ +#if defined(CEC) +#define LL_APB1_GRP1_PERIPH_CEC RCC_APB1LENR_CECEN +#endif /* CEC*/ +#if defined(UART7) +#define LL_APB1_GRP1_PERIPH_UART7 RCC_APB1LENR_UART7EN +#endif /* UART7 */ +#if defined(UART8) +#define LL_APB1_GRP1_PERIPH_UART8 RCC_APB1LENR_UART8EN +#endif /* UART8 */ +/** + * @} + */ + + +/** @defgroup BUS_LL_EC_APB1_GRP2_PERIPH APB1 GRP2 PERIPH + * @{ + */ +#if defined(UART9) +#define LL_APB1_GRP2_PERIPH_ALL 0x0080022BU +#else +#define LL_APB1_GRP2_PERIPH_ALL 0x00000228U +#endif /* UART9 */ +#if defined(UART9) +#define LL_APB1_GRP2_PERIPH_UART9 RCC_APB1HENR_UART9EN +#endif /* UART9 */ +#if defined(UART12) +#define LL_APB1_GRP2_PERIPH_UART12 RCC_APB1HENR_UART12EN +#endif /* UART12*/ +#define LL_APB1_GRP2_PERIPH_DTS RCC_APB1HENR_DTSEN +#define LL_APB1_GRP2_PERIPH_LPTIM2 RCC_APB1HENR_LPTIM2EN +#define LL_APB1_GRP2_PERIPH_FDCAN RCC_APB1HENR_FDCANEN +#if defined(UCPD1) +#define LL_APB1_GRP2_PERIPH_UCPD1 RCC_APB1HENR_UCPD1EN +#endif /* UCPD1 */ +/** + * @} + */ + +/** @defgroup BUS_LL_EC_APB2_GRP1_PERIPH APB2 GRP1 PERIPH + * @{ + */ +#if defined(TIM8) +#define LL_APB2_GRP1_PERIPH_ALL 0x017F7800U +#else +#define LL_APB2_GRP1_PERIPH_ALL 0x01005800U +#endif /* TIM8 */ +#define LL_APB2_GRP1_PERIPH_TIM1 RCC_APB2ENR_TIM1EN +#define LL_APB2_GRP1_PERIPH_SPI1 RCC_APB2ENR_SPI1EN +#if defined(TIM8) +#define LL_APB2_GRP1_PERIPH_TIM8 RCC_APB2ENR_TIM8EN +#endif /* TIM8 */ +#define LL_APB2_GRP1_PERIPH_USART1 RCC_APB2ENR_USART1EN +#if defined(TIM15) +#define LL_APB2_GRP1_PERIPH_TIM15 RCC_APB2ENR_TIM15EN +#endif /* TIM15 */ +#if defined(TIM16) +#define LL_APB2_GRP1_PERIPH_TIM16 RCC_APB2ENR_TIM16EN +#endif /* TIM16 */ +#if defined(TIM17) +#define LL_APB2_GRP1_PERIPH_TIM17 RCC_APB2ENR_TIM17EN +#endif /* TIM17 */ +#if defined(SPI4) +#define LL_APB2_GRP1_PERIPH_SPI4 RCC_APB2ENR_SPI4EN +#endif /* SPI4 */ +#if defined(SPI6) +#define LL_APB2_GRP1_PERIPH_SPI6 RCC_APB2ENR_SPI6EN +#endif /* SPI6 */ +#if defined(SAI1) +#define LL_APB2_GRP1_PERIPH_SAI1 RCC_APB2ENR_SAI1EN +#endif /* SAI1 */ +#if defined(SAI2) +#define LL_APB2_GRP1_PERIPH_SAI2 RCC_APB2ENR_SAI2EN +#endif /* SAI2 */ +#define LL_APB2_GRP1_PERIPH_USB RCC_APB2ENR_USBEN +/** + * @} + */ + +/** @defgroup BUS_LL_EC_APB3_GRP1_PERIPH APB3 GRP1 PERIPH + * @{ + */ +#if defined(SPI5) +#define LL_APB3_GRP1_PERIPH_ALL 0x0030F9E2U +#else +#define LL_APB3_GRP1_PERIPH_ALL 0x00200A42U +#endif /* SPI5 */ +#define LL_APB3_GRP1_PERIPH_SBS RCC_APB3ENR_SBSEN +#if defined(SPI5) +#define LL_APB3_GRP1_PERIPH_SPI5 RCC_APB3ENR_SPI5EN +#endif /* SPI5 */ +#define LL_APB3_GRP1_PERIPH_LPUART1 RCC_APB3ENR_LPUART1EN +#if defined(I2C3) +#define LL_APB3_GRP1_PERIPH_I2C3 RCC_APB3ENR_I2C3EN +#endif /* I2C3 */ +#if defined(I2C4) +#define LL_APB3_GRP1_PERIPH_I2C4 RCC_APB3ENR_I2C4EN +#endif /* I2C4 */ +#if defined(I3C2) +#define LL_APB3_GRP1_PERIPH_I3C2 RCC_APB3ENR_I3C2EN +#endif /* I3C2 */ +#define LL_APB3_GRP1_PERIPH_LPTIM1 RCC_APB3ENR_LPTIM1EN +#if defined(LPTIM3) +#define LL_APB3_GRP1_PERIPH_LPTIM3 RCC_APB3ENR_LPTIM3EN +#endif /* LPTIM3 */ +#if defined(LPTIM4) +#define LL_APB3_GRP1_PERIPH_LPTIM4 RCC_APB3ENR_LPTIM4EN +#endif /* LPTIM4 */ +#if defined(LPTIM5) +#define LL_APB3_GRP1_PERIPH_LPTIM5 RCC_APB3ENR_LPTIM5EN +#endif /* LPTIM5 */ +#if defined(LPTIM6) +#define LL_APB3_GRP1_PERIPH_LPTIM6 RCC_APB3ENR_LPTIM6EN +#endif /* LPTIM6 */ +#define LL_APB3_GRP1_PERIPH_VREF RCC_APB3ENR_VREFEN +#define LL_APB3_GRP1_PERIPH_RTCAPB RCC_APB3ENR_RTCAPBEN +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @defgroup BUS_LL_Exported_Functions BUS Exported Functions + * @{ + */ + +/** @defgroup BUS_LL_EF_AHBx AHBx Branch + * @{ + */ +/** + * @brief Disable of AHBx Clock Branch + * @rmtoll CFGR2 AHB1DIS LL_AHB_DisableClock\n + * CFGR2 AHB2DIS LL_AHB_DisableClock\n + * CFGR2 AHB4DIS LL_AHB_DisableClock + * @param AHBx This parameter can be a combination of the following values: + * @arg @ref LL_AHB_BRANCH_CLK_AHB1 + * @arg @ref LL_AHB_BRANCH_CLK_AHB2 + * @arg @ref LL_AHB_BRANCH_CLK_AHB4 (*) + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_AHB_DisableClock(uint32_t AHBx) +{ + SET_BIT(RCC->CFGR2, AHBx); +} + +/** + * @brief Enable of AHBx Clock Branch + * @rmtoll CFGR2 AHB1DIS LL_AHB_EnableClock\n + * CFGR2 AHB2DIS LL_AHB_EnableClock\n + * CFGR2 AHB4DIS LL_AHB_EnableClock + * @param AHBx This parameter can be a combination of the following values: + * @arg @ref LL_AHB_BRANCH_CLK_AHB1 + * @arg @ref LL_AHB_BRANCH_CLK_AHB2 + * @arg @ref LL_AHB_BRANCH_CLK_AHB4 (*) + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_AHB_EnableClock(uint32_t AHBx) +{ + __IO uint32_t tmpreg; + CLEAR_BIT(RCC->CFGR2, AHBx); + /* Delay after AHBx clock branch enabling */ + tmpreg = READ_BIT(RCC->CFGR2, AHBx); + (void)tmpreg; +} + +/** + * @brief Check if AHBx clock branch is disabled or not + * @rmtoll CFGR2 AHB1DIS LL_AHB_IsDisabledClock\n + * CFGR2 AHB2DIS LL_AHB_IsDisabledClock\n + * CFGR2 AHB4DIS LL_AHB_IsDisabledClock + * @param AHBx This parameter can be a combination of the following values: + * @arg @ref LL_AHB_BRANCH_CLK_AHB1 + * @arg @ref LL_AHB_BRANCH_CLK_AHB2 + * @arg @ref LL_AHB_BRANCH_CLK_AHB4 (*) + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval State of AHBx bus (1 or 0). + */ +__STATIC_INLINE uint32_t LL_AHB_IsDisabledClock(uint32_t AHBx) +{ + return ((READ_BIT(RCC->CFGR2, AHBx) == AHBx) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup BUS_LL_EF_APBx APBx Branch + * @{ + */ +/** + * @brief Disable APBx Clock Branch + * @rmtoll CFGR2 APB1DIS LL_APB_DisableClock\n + * CFGR2 APB2DIS LL_APB_DisableClock\n + * CFGR2 APB3DIS LL_APB_DisableClock + * @param APBx This parameter can be a combination of the following values: + * @arg @ref LL_APB_BRANCH_CLK_APB1 + * @arg @ref LL_APB_BRANCH_CLK_APB2 + * @arg @ref LL_APB_BRANCH_CLK_APB3 + * @retval None + */ +__STATIC_INLINE void LL_APB_DisableClock(uint32_t APBx) +{ + SET_BIT(RCC->CFGR2, APBx); +} + +/** + * @brief Enable of APBx Clock Branch + * @rmtoll CFGR2 APB1DIS LL_APB_EnableClock\n + * CFGR2 APB2DIS LL_APB_EnableClock\n + * CFGR2 APB3DIS LL_APB_EnableClock + * @param APBx This parameter can be a combination of the following values: + * @arg @ref LL_APB_BRANCH_CLK_APB1 + * @arg @ref LL_APB_BRANCH_CLK_APB2 + * @arg @ref LL_APB_BRANCH_CLK_APB3 + * @retval None + */ +__STATIC_INLINE void LL_APB_EnableClock(uint32_t APBx) +{ + __IO uint32_t tmpreg; + CLEAR_BIT(RCC->CFGR2, APBx); + /* Delay after APBx clock branch enabling */ + tmpreg = READ_BIT(RCC->CFGR2, APBx); + (void)tmpreg; +} + +/** + * @brief Check if APBx clock branch is disabled or not + * @rmtoll CFGR2 APB1DIS LL_APB_IsDisabledClock\n + * CFGR2 APB2DIS LL_APB_IsDisabledClock\n + * CFGR2 APB3DIS LL_APB_IsDisabledClock + * @param APBx This parameter can be a combination of the following values: + * @arg @ref LL_APB_BRANCH_CLK_APB1 + * @arg @ref LL_APB_BRANCH_CLK_APB2 + * @arg @ref LL_APB_BRANCH_CLK_APB3 + * @retval State of APBx bus (1 or 0). + */ +__STATIC_INLINE uint32_t LL_APB_IsDisabledClock(uint32_t APBx) +{ + return ((READ_BIT(RCC->CFGR2, APBx) == APBx) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup BUS_LL_EF_AHB1 AHB1 Peripherals + * @{ + */ +/** + * @brief Enable AHB1 peripherals clock. + * @rmtoll AHB1ENR GPDMA1EN LL_AHB1_GRP1_EnableClock\n + * AHB1ENR GPDMA2EN LL_AHB1_GRP1_EnableClock\n + * AHB1ENR FLITFEN LL_AHB1_GRP1_EnableClock\n + * AHB1ENR CRCEN LL_AHB1_GRP1_EnableClock\n + * AHB1ENR CORDICEN LL_AHB1_GRP1_EnableClock\n + * AHB1ENR FMACEN LL_AHB1_GRP1_EnableClock\n + * AHB1ENR RAMCFGEN LL_AHB1_GRP1_EnableClock\n + * AHB1ENR ETHEN LL_AHB1_GRP1_EnableClock\n + * AHB1ENR ETHTXEN LL_AHB1_GRP1_EnableClock\n + * AHB1ENR ETHRXEN LL_AHB1_GRP1_EnableClock\n + * AHB1ENR TZSC1EN LL_AHB1_GRP1_EnableClock\n + * AHB1ENR BKPRAMEN LL_AHB1_GRP1_EnableClock\n + * AHB1ENR DCACHE1EN LL_AHB1_GRP1_EnableClock\n + * AHB1ENR SRAM1EN LL_AHB1_GRP1_EnableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB1_GRP1_PERIPH_ALL + * @arg @ref LL_AHB1_GRP1_PERIPH_GPDMA1 + * @arg @ref LL_AHB1_GRP1_PERIPH_GPDMA2 + * @arg @ref LL_AHB1_GRP1_PERIPH_FLASH + * @arg @ref LL_AHB1_GRP1_PERIPH_CRC + * @arg @ref LL_AHB1_GRP1_PERIPH_CORDIC (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_FMAC + * @arg @ref LL_AHB1_GRP1_PERIPH_RAMCFG + * @arg @ref LL_AHB1_GRP1_PERIPH_ETH (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_ETHTX (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_ETHRX (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_GTZC1 + * @arg @ref LL_AHB1_GRP1_PERIPH_BKPSRAM + * @arg @ref LL_AHB1_GRP1_PERIPH_DCACHE1 (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_SRAM1 + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_AHB1_GRP1_EnableClock(uint32_t Periphs) +{ + __IO uint32_t tmpreg; + SET_BIT(RCC->AHB1ENR, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->AHB1ENR, Periphs); + (void)tmpreg; +} + +/** + * @brief Check if AHB1 peripheral clock is enabled or not + * @rmtoll AHB1ENR GPDMA1EN LL_AHB1_GRP1_IsEnabledClock\n + * AHB1ENR GPDMA2EN LL_AHB1_GRP1_IsEnabledClock\n + * AHB1ENR FLITFEN LL_AHB1_GRP1_IsEnabledClock\n + * AHB1ENR CRCEN LL_AHB1_GRP1_IsEnabledClock\n + * AHB1ENR CORDICEN LL_AHB1_GRP1_IsEnabledClock\n + * AHB1ENR FMACEN LL_AHB1_GRP1_IsEnabledClock\n + * AHB1ENR RAMCFGEN LL_AHB1_GRP1_IsEnabledClock\n + * AHB1ENR ETHEN LL_AHB1_GRP1_IsEnabledClock\n + * AHB1ENR ETHTXEN LL_AHB1_GRP1_IsEnabledClock\n + * AHB1ENR ETHRXEN LL_AHB1_GRP1_IsEnabledClock\n + * AHB1ENR TZSC1EN LL_AHB1_GRP1_IsEnabledClock\n + * AHB1ENR BKPRAMEN LL_AHB1_GRP1_IsEnabledClock\n + * AHB1ENR DCACHE1EN LL_AHB1_GRP1_IsEnabledClock\n + * AHB1ENR SRAM1EN LL_AHB1_GRP1_IsEnabledClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB1_GRP1_PERIPH_ALL + * @arg @ref LL_AHB1_GRP1_PERIPH_GPDMA1 + * @arg @ref LL_AHB1_GRP1_PERIPH_GPDMA2 + * @arg @ref LL_AHB1_GRP1_PERIPH_FLASH + * @arg @ref LL_AHB1_GRP1_PERIPH_CRC + * @arg @ref LL_AHB1_GRP1_PERIPH_CORDIC (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_FMAC (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_RAMCFG + * @arg @ref LL_AHB1_GRP1_PERIPH_ETH (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_ETHTX (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_ETHRX (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_GTZC1 + * @arg @ref LL_AHB1_GRP1_PERIPH_BKPSRAM + * @arg @ref LL_AHB1_GRP1_PERIPH_DCACHE1 (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_SRAM1 + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval State of Periphs (1 or 0). + */ +__STATIC_INLINE uint32_t LL_AHB1_GRP1_IsEnabledClock(uint32_t Periphs) +{ + return ((READ_BIT(RCC->AHB1ENR, Periphs) == Periphs) ? 1UL : 0UL); +} + +/** + * @brief Disable AHB1 peripherals clock. + * @rmtoll AHB1ENR GPDMA1EN LL_AHB1_GRP1_DisableClock\n + * AHB1ENR GPDMA2EN LL_AHB1_GRP1_DisableClock\n + * AHB1ENR FLITFEN LL_AHB1_GRP1_DisableClock\n + * AHB1ENR CRCEN LL_AHB1_GRP1_DisableClock\n + * AHB1ENR CORDICEN LL_AHB1_GRP1_DisableClock\n + * AHB1ENR FMACEN LL_AHB1_GRP1_DisableClock\n + * AHB1ENR RAMCFGEN LL_AHB1_GRP1_DisableClock\n + * AHB1ENR ETHEN LL_AHB1_GRP1_DisableClock\n + * AHB1ENR ETHTXEN LL_AHB1_GRP1_DisableClock\n + * AHB1ENR ETHRXEN LL_AHB1_GRP1_DisableClock\n + * AHB1ENR TZSC1EN LL_AHB1_GRP1_DisableClock\n + * AHB1ENR BKPRAMEN LL_AHB1_GRP1_DisableClock\n + * AHB1ENR DCACHE1EN LL_AHB1_GRP1_DisableClock\n + * AHB1ENR SRAM1EN LL_AHB1_GRP1_DisableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB1_GRP1_PERIPH_ALL + * @arg @ref LL_AHB1_GRP1_PERIPH_GPDMA1 + * @arg @ref LL_AHB1_GRP1_PERIPH_GPDMA2 + * @arg @ref LL_AHB1_GRP1_PERIPH_FLASH + * @arg @ref LL_AHB1_GRP1_PERIPH_CRC + * @arg @ref LL_AHB1_GRP1_PERIPH_CORDIC (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_FMAC (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_RAMCFG + * @arg @ref LL_AHB1_GRP1_PERIPH_ETH (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_ETHTX (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_ETHRX (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_GTZC1 + * @arg @ref LL_AHB1_GRP1_PERIPH_BKPSRAM + * @arg @ref LL_AHB1_GRP1_PERIPH_DCACHE1 (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_SRAM1 + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_AHB1_GRP1_DisableClock(uint32_t Periphs) +{ + CLEAR_BIT(RCC->AHB1ENR, Periphs); +} + +/** + * @brief Force AHB1 peripherals reset. + * @rmtoll AHB1RSTR GPDMA1RST LL_AHB1_GRP1_ForceReset\n + * AHB1RSTR GPDMA2RST LL_AHB1_GRP1_ForceReset\n + * AHB1RSTR CRCRST LL_AHB1_GRP1_ForceReset\n + * AHB1RSTR CORDICRST LL_AHB1_GRP1_ForceReset\n + * AHB1RSTR FMACRST LL_AHB1_GRP1_ForceReset\n + * AHB1RSTR RAMCFGRST LL_AHB1_GRP1_ForceReset\n + * AHB1RSTR ETHRST LL_AHB1_GRP1_ForceReset\n + * AHB1RSTR TZSC1RST LL_AHB1_GRP1_ForceReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB1_GRP1_PERIPH_ALL + * @arg @ref LL_AHB1_GRP1_PERIPH_GPDMA1 + * @arg @ref LL_AHB1_GRP1_PERIPH_GPDMA2 + * @arg @ref LL_AHB1_GRP1_PERIPH_CRC + * @arg @ref LL_AHB1_GRP1_PERIPH_CORDIC (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_FMAC (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_RAMCFG + * @arg @ref LL_AHB1_GRP1_PERIPH_ETH (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_GTZC1 + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_AHB1_GRP1_ForceReset(uint32_t Periphs) +{ + SET_BIT(RCC->AHB1RSTR, Periphs); +} + +/** + * @brief Release AHB1 peripherals reset. + * @rmtoll AHB1RSTR GPDMA1RST LL_AHB1_GRP1_ReleaseReset\n + * AHB1RSTR GPDMA2RST LL_AHB1_GRP1_ReleaseReset\n + * AHB1RSTR CRCRST LL_AHB1_GRP1_ReleaseReset\n + * AHB1RSTR CORDICRST LL_AHB1_GRP1_ReleaseReset\n + * AHB1RSTR FMACRST LL_AHB1_GRP1_ReleaseReset\n + * AHB1RSTR RAMCFGRST LL_AHB1_GRP1_ReleaseReset\n + * AHB1RSTR ETHRST LL_AHB1_GRP1_ReleaseReset\n + * AHB1RSTR TZSC1RST LL_AHB1_GRP1_ReleaseReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB1_GRP1_PERIPH_ALL + * @arg @ref LL_AHB1_GRP1_PERIPH_GPDMA1 + * @arg @ref LL_AHB1_GRP1_PERIPH_GPDMA2 + * @arg @ref LL_AHB1_GRP1_PERIPH_CRC + * @arg @ref LL_AHB1_GRP1_PERIPH_CORDIC (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_FMAC (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_RAMCFG + * @arg @ref LL_AHB1_GRP1_PERIPH_ETH (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_GTZC1 + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_AHB1_GRP1_ReleaseReset(uint32_t Periphs) +{ + CLEAR_BIT(RCC->AHB1RSTR, Periphs); +} + +/** + * @brief Enable AHB1 peripheral clocks in Sleep mode + * @rmtoll AHB1LPENR GPDMA1LPEN LL_AHB1_GRP1_EnableClockSleep\n + * AHB1LPENR GPDMA2LPEN LL_AHB1_GRP1_EnableClockSleep\n + * AHB1LPENR FLITFLPEN LL_AHB1_GRP1_EnableClockSleep\n + * AHB1LPENR CRCLPEN LL_AHB1_GRP1_EnableClockSleep\n + * AHB1LPENR CORDICLPEN LL_AHB1_GRP1_EnableClockSleep\n + * AHB1LPENR FMACLPEN LL_AHB1_GRP1_EnableClockSleep\n + * AHB1LPENR RAMCFGLPEN LL_AHB1_GRP1_EnableClockSleep\n + * AHB1LPENR ETHLPEN LL_AHB1_GRP1_EnableClockSleep\n + * AHB1LPENR ETHTXLPEN LL_AHB1_GRP1_EnableClockSleep\n + * AHB1LPENR ETHRXLPEN LL_AHB1_GRP1_EnableClockSleep\n + * AHB1LPENR TZSC1LPEN LL_AHB1_GRP1_EnableClockSleep\n + * AHB1LPENR BKPRAMLPEN LL_AHB1_GRP1_EnableClockSleep\n + * AHB1LPENR DCACHE1LPEN LL_AHB1_GRP1_EnableClockSleep\n + * AHB1LPENR SRAM1LPEN LL_AHB1_GRP1_EnableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB1_GRP1_PERIPH_ALL + * @arg @ref LL_AHB1_GRP1_PERIPH_GPDMA1 + * @arg @ref LL_AHB1_GRP1_PERIPH_GPDMA2 + * @arg @ref LL_AHB1_GRP1_PERIPH_FLASH + * @arg @ref LL_AHB1_GRP1_PERIPH_CRC + * @arg @ref LL_AHB1_GRP1_PERIPH_CORDIC (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_FMAC (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_RAMCFG + * @arg @ref LL_AHB1_GRP1_PERIPH_ETH (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_ETHTX (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_ETHRX (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_GTZC1 + * @arg @ref LL_AHB1_GRP1_PERIPH_BKPSRAM + * @arg @ref LL_AHB1_GRP1_PERIPH_DCACHE1 (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_SRAM1 + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_AHB1_GRP1_EnableClockSleep(uint32_t Periphs) +{ + __IO uint32_t tmpreg; + SET_BIT(RCC->AHB1LPENR, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->AHB1LPENR, Periphs); + (void)tmpreg; +} + +/** + * @brief Check if AHB1 peripheral clocks in Sleep mode is enabled or not + * @rmtoll AHB1LPENR GPDMA1LPEN LL_AHB1_GRP1_IsEnabledClockSleep\n + * AHB1LPENR GPDMA2LPEN LL_AHB1_GRP1_IsEnabledClockSleep\n + * AHB1LPENR FLITFLPEN LL_AHB1_GRP1_IsEnabledClockSleep\n + * AHB1LPENR CRCLPEN LL_AHB1_GRP1_IsEnabledClockSleep\n + * AHB1LPENR CORDICLPEN LL_AHB1_GRP1_IsEnabledClockSleep\n + * AHB1LPENR FMACLPEN LL_AHB1_GRP1_IsEnabledClockSleep\n + * AHB1LPENR RAMCFGLPEN LL_AHB1_GRP1_IsEnabledClockSleep\n + * AHB1LPENR ETHLPEN LL_AHB1_GRP1_IsEnabledClockSleep\n + * AHB1LPENR ETHTXLPEN LL_AHB1_GRP1_IsEnabledClockSleep\n + * AHB1LPENR ETHRXLPEN LL_AHB1_GRP1_IsEnabledClockSleep\n + * AHB1LPENR TZSC1LPEN LL_AHB1_GRP1_IsEnabledClockSleep\n + * AHB1LPENR BKPRAMLPEN LL_AHB1_GRP1_IsEnabledClockSleep\n + * AHB1LPENR DCACHE1LPEN LL_AHB1_GRP1_IsEnabledClockSleep\n + * AHB1LPENR SRAM1LPEN LL_AHB1_GRP1_IsEnabledClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB1_GRP1_PERIPH_ALL + * @arg @ref LL_AHB1_GRP1_PERIPH_GPDMA1 + * @arg @ref LL_AHB1_GRP1_PERIPH_GPDMA2 + * @arg @ref LL_AHB1_GRP1_PERIPH_FLASH + * @arg @ref LL_AHB1_GRP1_PERIPH_CRC + * @arg @ref LL_AHB1_GRP1_PERIPH_CORDIC (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_FMAC (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_RAMCFG + * @arg @ref LL_AHB1_GRP1_PERIPH_ETH (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_ETHTX (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_ETHRX (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_GTZC1 + * @arg @ref LL_AHB1_GRP1_PERIPH_BKPSRAM + * @arg @ref LL_AHB1_GRP1_PERIPH_DCACHE1 (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_SRAM1 + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval State of Periphs (1 or 0). + */ +__STATIC_INLINE uint32_t LL_AHB1_GRP1_IsEnabledClockSleep(uint32_t Periphs) +{ + return ((READ_BIT(RCC->AHB1LPENR, Periphs) == Periphs) ? 1UL : 0UL); +} + +/** + * @brief Disable AHB1 peripheral clocks in Sleep mode + * @rmtoll AHB1LPENR GPDMA1LPEN LL_AHB1_GRP1_DisableClockSleep\n + * AHB1LPENR GPDMA2LPEN LL_AHB1_GRP1_DisableClockSleep\n + * AHB1LPENR FLITFLPEN LL_AHB1_GRP1_DisableClockSleep\n + * AHB1LPENR CRCLPEN LL_AHB1_GRP1_DisableClockSleep\n + * AHB1LPENR CORDICLPEN LL_AHB1_GRP1_DisableClockSleep\n + * AHB1LPENR FMACLPEN LL_AHB1_GRP1_DisableClockSleep\n + * AHB1LPENR RAMCFGLPEN LL_AHB1_GRP1_DisableClockSleep\n + * AHB1LPENR ETHLPEN LL_AHB1_GRP1_DisableClockSleep\n + * AHB1LPENR ETHTXLPEN LL_AHB1_GRP1_DisableClockSleep\n + * AHB1LPENR ETHRXLPEN LL_AHB1_GRP1_DisableClockSleep\n + * AHB1LPENR TZSC1LPEN LL_AHB1_GRP1_DisableClockSleep\n + * AHB1LPENR BKPRAMLPEN LL_AHB1_GRP1_DisableClockSleep\n + * AHB1LPENR DCACHE1LPEN LL_AHB1_GRP1_DisableClockSleep\n + * AHB1LPENR SRAM1LPEN LL_AHB1_GRP1_DisableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB1_GRP1_PERIPH_ALL + * @arg @ref LL_AHB1_GRP1_PERIPH_GPDMA1 + * @arg @ref LL_AHB1_GRP1_PERIPH_GPDMA2 + * @arg @ref LL_AHB1_GRP1_PERIPH_FLASH + * @arg @ref LL_AHB1_GRP1_PERIPH_CRC + * @arg @ref LL_AHB1_GRP1_PERIPH_CORDIC (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_FMAC (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_RAMCFG + * @arg @ref LL_AHB1_GRP1_PERIPH_ETH (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_ETHTX (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_ETHRX (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_GTZC1 + * @arg @ref LL_AHB1_GRP1_PERIPH_BKPSRAM + * @arg @ref LL_AHB1_GRP1_PERIPH_DCACHE1 (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_SRAM1 + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_AHB1_GRP1_DisableClockSleep(uint32_t Periphs) +{ + CLEAR_BIT(RCC->AHB1LPENR, Periphs); +} + +/** + * @} + */ + +/** @defgroup BUS_LL_EF_AHB2 AHB2 Peripherals + * @{ + */ +/** + * @brief Enable AHB2 peripherals clock. + * @rmtoll AHB2ENR GPIOAEN LL_AHB2_GRP1_EnableClock\n + * AHB2ENR GPIOBEN LL_AHB2_GRP1_EnableClock\n + * AHB2ENR GPIOCEN LL_AHB2_GRP1_EnableClock\n + * AHB2ENR GPIODEN LL_AHB2_GRP1_EnableClock\n + * AHB2ENR GPIOEEN LL_AHB2_GRP1_EnableClock\n + * AHB2ENR GPIOFEN LL_AHB2_GRP1_EnableClock\n + * AHB2ENR GPIOGEN LL_AHB2_GRP1_EnableClock\n + * AHB2ENR GPIOHEN LL_AHB2_GRP1_EnableClock\n + * AHB2ENR GPIOIEN LL_AHB2_GRP1_EnableClock\n + * AHB2ENR ADCEN LL_AHB2_GRP1_EnableClock\n + * AHB2ENR DAC1EN LL_AHB2_GRP1_EnableClock\n + * AHB2ENR DCMI_PSSIEN LL_AHB2_GRP1_EnableClock\n + * AHB2ENR AESEN LL_AHB2_GRP1_EnableClock\n + * AHB2ENR HASHEN LL_AHB2_GRP1_EnableClock\n + * AHB2ENR RNGEN LL_AHB2_GRP1_EnableClock\n + * AHB2ENR PKAEN LL_AHB2_GRP1_EnableClock\n + * AHB2ENR SAESEN LL_AHB2_GRP1_EnableClock\n + * AHB2ENR SRAM2EN LL_AHB2_GRP1_EnableClock\n + * AHB2ENR SRAM3EN LL_AHB2_GRP1_EnableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB2_GRP1_PERIPH_ALL + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOA + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOB + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOC + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOD + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOE (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOF (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOG (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOH + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOI (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_ADC + * @arg @ref LL_AHB2_GRP1_PERIPH_DAC1 + * @arg @ref LL_AHB2_GRP1_PERIPH_DCMI_PSSI (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_AES (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_HASH (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_RNG + * @arg @ref LL_AHB2_GRP1_PERIPH_PKA (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_SAES (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_SRAM2 (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_SRAM3 (*) + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_AHB2_GRP1_EnableClock(uint32_t Periphs) +{ + __IO uint32_t tmpreg; + SET_BIT(RCC->AHB2ENR, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->AHB2ENR, Periphs); + (void)tmpreg; +} + +/** + * @brief Check if AHB2 peripheral clock is enabled or not + * @rmtoll AHB2ENR GPIOAEN LL_AHB2_GRP1_IsEnabledClock\n + * AHB2ENR GPIOBEN LL_AHB2_GRP1_IsEnabledClock\n + * AHB2ENR GPIOCEN LL_AHB2_GRP1_IsEnabledClock\n + * AHB2ENR GPIODEN LL_AHB2_GRP1_IsEnabledClock\n + * AHB2ENR GPIOEEN LL_AHB2_GRP1_IsEnabledClock\n + * AHB2ENR GPIOFEN LL_AHB2_GRP1_IsEnabledClock\n + * AHB2ENR GPIOGEN LL_AHB2_GRP1_IsEnabledClock\n + * AHB2ENR GPIOHEN LL_AHB2_GRP1_IsEnabledClock\n + * AHB2ENR GPIOIEN LL_AHB2_GRP1_IsEnabledClock\n + * AHB2ENR ADCEN LL_AHB2_GRP1_IsEnabledClock\n + * AHB2ENR DAC1EN LL_AHB2_GRP1_IsEnabledClock\n + * AHB2ENR DCMI_PSSIEN LL_AHB2_GRP1_IsEnabledClock\n + * AHB2ENR AESEN LL_AHB2_GRP1_IsEnabledClock\n + * AHB2ENR HASHEN LL_AHB2_GRP1_IsEnabledClock\n + * AHB2ENR RNGEN LL_AHB2_GRP1_IsEnabledClock\n + * AHB2ENR PKAEN LL_AHB2_GRP1_IsEnabledClock\n + * AHB2ENR SAESEN LL_AHB2_GRP1_IsEnabledClock\n + * AHB2ENR SRAM2EN LL_AHB2_GRP1_IsEnabledClock\n + * AHB2ENR SRAM3EN LL_AHB2_GRP1_IsEnabledClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB2_GRP1_PERIPH_ALL + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOA + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOB + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOC + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOD + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOE (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOF (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOG (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOH + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOI (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_ADC + * @arg @ref LL_AHB2_GRP1_PERIPH_DAC1 + * @arg @ref LL_AHB2_GRP1_PERIPH_DCMI_PSSI (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_AES (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_HASH (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_RNG + * @arg @ref LL_AHB2_GRP1_PERIPH_PKA (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_SAES (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_SRAM2 (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_SRAM3 (*) + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval State of Periphs (1 or 0). + */ +__STATIC_INLINE uint32_t LL_AHB2_GRP1_IsEnabledClock(uint32_t Periphs) +{ + return ((READ_BIT(RCC->AHB2ENR, Periphs) == Periphs) ? 1UL : 0UL); +} + +/** + * @brief Disable AHB2 peripherals clock. + * @rmtoll AHB2ENR GPIOAEN LL_AHB2_GRP1_DisableClock\n + * AHB2ENR GPIOBEN LL_AHB2_GRP1_DisableClock\n + * AHB2ENR GPIOCEN LL_AHB2_GRP1_DisableClock\n + * AHB2ENR GPIODEN LL_AHB2_GRP1_DisableClock\n + * AHB2ENR GPIOEEN LL_AHB2_GRP1_DisableClock\n + * AHB2ENR GPIOFEN LL_AHB2_GRP1_DisableClock\n + * AHB2ENR GPIOGEN LL_AHB2_GRP1_DisableClock\n + * AHB2ENR GPIOHEN LL_AHB2_GRP1_DisableClock\n + * AHB2ENR GPIOIEN LL_AHB2_GRP1_DisableClock\n + * AHB2ENR ADCEN LL_AHB2_GRP1_DisableClock\n + * AHB2ENR DAC1EN LL_AHB2_GRP1_DisableClock\n + * AHB2ENR DCMI_PSSIEN LL_AHB2_GRP1_DisableClock\n + * AHB2ENR AESEN LL_AHB2_GRP1_DisableClock\n + * AHB2ENR HASHEN LL_AHB2_GRP1_DisableClock\n + * AHB2ENR RNGEN LL_AHB2_GRP1_DisableClock\n + * AHB2ENR PKAEN LL_AHB2_GRP1_DisableClock\n + * AHB2ENR SAESEN LL_AHB2_GRP1_DisableClock\n + * AHB2ENR SRAM2EN LL_AHB2_GRP1_DisableClock\n + * AHB2ENR SRAM3EN LL_AHB2_GRP1_DisableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB2_GRP1_PERIPH_ALL + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOA + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOB + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOC + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOD + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOE (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOF (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOG (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOH + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOI (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_ADC + * @arg @ref LL_AHB2_GRP1_PERIPH_DAC1 + * @arg @ref LL_AHB2_GRP1_PERIPH_DCMI_PSSI (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_AES (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_HASH (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_RNG + * @arg @ref LL_AHB2_GRP1_PERIPH_PKA (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_SAES (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_SRAM2 (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_SRAM3 (*) + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_AHB2_GRP1_DisableClock(uint32_t Periphs) +{ + CLEAR_BIT(RCC->AHB2ENR, Periphs); +} + +/** + * @brief Force AHB2 peripherals reset. + * @rmtoll AHB2RST GPIOARST LL_AHB2_GRP1_ForceReset\n + * AHB2RST GPIOBRST LL_AHB2_GRP1_ForceReset\n + * AHB2RST GPIOCRST LL_AHB2_GRP1_ForceReset\n + * AHB2RST GPIODRST LL_AHB2_GRP1_ForceReset\n + * AHB2RST GPIOERST LL_AHB2_GRP1_ForceReset\n + * AHB2RST GPIOFRST LL_AHB2_GRP1_ForceReset\n + * AHB2RST GPIOGRST LL_AHB2_GRP1_ForceReset\n + * AHB2RST GPIOHRST LL_AHB2_GRP1_ForceReset\n + * AHB2RST GPIOIRST LL_AHB2_GRP1_ForceReset\n + * AHB2RST ADCRST LL_AHB2_GRP1_ForceReset\n + * AHB2RST DAC1RST LL_AHB2_GRP1_ForceReset\n + * AHB2RST DCMI_PSSIRST LL_AHB2_GRP1_ForceReset\n + * AHB2RST AESRST LL_AHB2_GRP1_ForceReset\n + * AHB2RST HASHRST LL_AHB2_GRP1_ForceReset\n + * AHB2RST RNGRST LL_AHB2_GRP1_ForceReset\n + * AHB2RST PKARST LL_AHB2_GRP1_ForceReset\n + * AHB2RST SAESRST LL_AHB2_GRP1_ForceReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB2_GRP1_PERIPH_ALL + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOA + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOB + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOC + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOD + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOE (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOF (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOG (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOH + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOI (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_ADC + * @arg @ref LL_AHB2_GRP1_PERIPH_DAC1 + * @arg @ref LL_AHB2_GRP1_PERIPH_DCMI_PSSI (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_AES (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_HASH (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_RNG + * @arg @ref LL_AHB2_GRP1_PERIPH_PKA (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_SAES (*) + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_AHB2_GRP1_ForceReset(uint32_t Periphs) +{ + SET_BIT(RCC->AHB2RSTR, Periphs); +} + +/** + * @brief Release AHB2 peripherals reset. + * @rmtoll AHB2RST GPIOARST LL_AHB2_GRP1_ReleaseReset\n + * AHB2RST GPIOBRST LL_AHB2_GRP1_ReleaseReset\n + * AHB2RST GPIOCRST LL_AHB2_GRP1_ReleaseReset\n + * AHB2RST GPIODRST LL_AHB2_GRP1_ReleaseReset\n + * AHB2RST GPIOERST LL_AHB2_GRP1_ReleaseReset\n + * AHB2RST GPIOFRST LL_AHB2_GRP1_ReleaseReset\n + * AHB2RST GPIOGRST LL_AHB2_GRP1_ReleaseReset\n + * AHB2RST GPIOHRST LL_AHB2_GRP1_ReleaseReset\n + * AHB2RST GPIOIRST LL_AHB2_GRP1_ReleaseReset\n + * AHB2RST ADCRST LL_AHB2_GRP1_ReleaseReset\n + * AHB2RST DAC1RST LL_AHB2_GRP1_ReleaseReset\n + * AHB2RST DCMI_PSSIRST LL_AHB2_GRP1_ReleaseReset\n + * AHB2RST AESRST LL_AHB2_GRP1_ReleaseReset\n + * AHB2RST HASHRST LL_AHB2_GRP1_ReleaseReset\n + * AHB2RST RNGRST LL_AHB2_GRP1_ReleaseReset\n + * AHB2RST PKARST LL_AHB2_GRP1_ReleaseReset\n + * AHB2RST SAESRST LL_AHB2_GRP1_ReleaseReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB2_GRP1_PERIPH_ALL + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOA + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOB + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOC + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOD + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOE (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOF (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOG (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOH + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOI (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_ADC + * @arg @ref LL_AHB2_GRP1_PERIPH_DAC1 + * @arg @ref LL_AHB2_GRP1_PERIPH_DCMI_PSSI (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_AES (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_HASH (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_RNG + * @arg @ref LL_AHB2_GRP1_PERIPH_PKA (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_SAES (*) + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_AHB2_GRP1_ReleaseReset(uint32_t Periphs) +{ + CLEAR_BIT(RCC->AHB2RSTR, Periphs); +} + +/** + * @brief Enable AHB2 peripheral clocks in Sleep mode + * @rmtoll AHB2LPENR GPIOALPEN LL_AHB2_GRP1_EnableClockSleep\n + * AHB2LPENR GPIOBLPEN LL_AHB2_GRP1_EnableClockSleep\n + * AHB2LPENR GPIOCLPEN LL_AHB2_GRP1_EnableClockSleep\n + * AHB2LPENR GPIODLPEN LL_AHB2_GRP1_EnableClockSleep\n + * AHB2LPENR GPIOELPEN LL_AHB2_GRP1_EnableClockSleep\n + * AHB2LPENR GPIOFLPEN LL_AHB2_GRP1_EnableClockSleep\n + * AHB2LPENR GPIOGLPEN LL_AHB2_GRP1_EnableClockSleep\n + * AHB2LPENR GPIOHLPEN LL_AHB2_GRP1_EnableClockSleep\n + * AHB2LPENR GPIOILPEN LL_AHB2_GRP1_EnableClockSleep\n + * AHB2LPENR ADCLPEN LL_AHB2_GRP1_EnableClockSleep\n + * AHB2LPENR DAC1LPEN LL_AHB2_GRP1_EnableClockSleep\n + * AHB2LPENR DCMI_PSSILPEN LL_AHB2_GRP1_EnableClockSleep\n + * AHB2LPENR AESLPEN LL_AHB2_GRP1_EnableClockSleep\n + * AHB2LPENR HASHLPEN LL_AHB2_GRP1_EnableClockSleep\n + * AHB2LPENR RNGLPEN LL_AHB2_GRP1_EnableClockSleep\n + * AHB2LPENR PKALPEN LL_AHB2_GRP1_EnableClockSleep\n + * AHB2LPENR SAESLPEN LL_AHB2_GRP1_EnableClockSleep\n + * AHB2LPENR SRAM2LPEN LL_AHB2_GRP1_EnableClockSleep\n + * AHB2LPENR SRAM3LPEN LL_AHB2_GRP1_EnableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB2_GRP1_PERIPH_ALL + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOA + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOB + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOC + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOD + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOE (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOF (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOG (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOH + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOI (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_ADC + * @arg @ref LL_AHB2_GRP1_PERIPH_DAC1 + * @arg @ref LL_AHB2_GRP1_PERIPH_DCMI_PSSI (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_AES (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_HASH (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_RNG + * @arg @ref LL_AHB2_GRP1_PERIPH_PKA (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_SAES (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_SRAM2 (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_SRAM3 (*) + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_AHB2_GRP1_EnableClockSleep(uint32_t Periphs) +{ + __IO uint32_t tmpreg; + SET_BIT(RCC->AHB2LPENR, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->AHB2LPENR, Periphs); + (void)tmpreg; +} + +/** + * @brief Check if AHB2 peripheral clocks in Sleep mode is enabled or not + * @rmtoll AHB2LPENR GPIOALPEN LL_AHB2_GRP1_IsEnabledClockSleep\n + * AHB2LPENR GPIOBLPEN LL_AHB2_GRP1_IsEnabledClockSleep\n + * AHB2LPENR GPIOCLPEN LL_AHB2_GRP1_IsEnabledClockSleep\n + * AHB2LPENR GPIODLPEN LL_AHB2_GRP1_IsEnabledClockSleep\n + * AHB2LPENR GPIOELPEN LL_AHB2_GRP1_IsEnabledClockSleep\n + * AHB2LPENR GPIOFLPEN LL_AHB2_GRP1_IsEnabledClockSleep\n + * AHB2LPENR GPIOGLPEN LL_AHB2_GRP1_IsEnabledClockSleep\n + * AHB2LPENR GPIOHLPEN LL_AHB2_GRP1_IsEnabledClockSleep\n + * AHB2LPENR GPIOILPEN LL_AHB2_GRP1_IsEnabledClockSleep\n + * AHB2LPENR ADCLPEN LL_AHB2_GRP1_IsEnabledClockSleep\n + * AHB2LPENR DAC1LPEN LL_AHB2_GRP1_IsEnabledClockSleep\n + * AHB2LPENR DCMI_PSSILPEN LL_AHB2_GRP1_IsEnabledClockSleep\n + * AHB2LPENR AESLPEN LL_AHB2_GRP1_IsEnabledClockSleep\n + * AHB2LPENR HASHLPEN LL_AHB2_GRP1_IsEnabledClockSleep\n + * AHB2LPENR RNGLPEN LL_AHB2_GRP1_IsEnabledClockSleep\n + * AHB2LPENR PKALPEN LL_AHB2_GRP1_IsEnabledClockSleep\n + * AHB2LPENR SAESLPEN LL_AHB2_GRP1_IsEnabledClockSleep\n + * AHB2LPENR SRAM2LPEN LL_AHB2_GRP1_IsEnabledClockSleep\n + * AHB2LPENR SRAM3LPEN LL_AHB2_GRP1_IsEnabledClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB2_GRP1_PERIPH_ALL + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOA + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOB + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOC + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOD + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOE (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOF (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOG (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOH + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOI (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_ADC + * @arg @ref LL_AHB2_GRP1_PERIPH_DAC1 + * @arg @ref LL_AHB2_GRP1_PERIPH_DCMI_PSSI (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_AES (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_HASH (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_RNG + * @arg @ref LL_AHB2_GRP1_PERIPH_PKA (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_SAES (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_SRAM2 (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_SRAM3 (*) + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval State of Periphs (1 or 0). + */ +__STATIC_INLINE uint32_t LL_AHB2_GRP1_IsEnabledClockSleep(uint32_t Periphs) +{ + return ((READ_BIT(RCC->AHB2LPENR, Periphs) == Periphs) ? 1UL : 0UL); +} + +/** + * @brief Disable AHB2 peripheral clocks in Sleep mode + * @rmtoll AHB2LPENR GPIOALPEN LL_AHB2_GRP1_DisableClockSleep\n + * AHB2LPENR GPIOBLPEN LL_AHB2_GRP1_DisableClockSleep\n + * AHB2LPENR GPIOCLPEN LL_AHB2_GRP1_DisableClockSleep\n + * AHB2LPENR GPIODLPEN LL_AHB2_GRP1_DisableClockSleep\n + * AHB2LPENR GPIOELPEN LL_AHB2_GRP1_DisableClockSleep\n + * AHB2LPENR GPIOFLPEN LL_AHB2_GRP1_DisableClockSleep\n + * AHB2LPENR GPIOGLPEN LL_AHB2_GRP1_DisableClockSleep\n + * AHB2LPENR GPIOHLPEN LL_AHB2_GRP1_DisableClockSleep\n + * AHB2LPENR GPIOILPEN LL_AHB2_GRP1_DisableClockSleep\n + * AHB2LPENR ADCLPEN LL_AHB2_GRP1_DisableClockSleep\n + * AHB2LPENR DAC1LPEN LL_AHB2_GRP1_DisableClockSleep\n + * AHB2LPENR DCMI_PSSILPEN LL_AHB2_GRP1_DisableClockSleep\n + * AHB2LPENR AESLPEN LL_AHB2_GRP1_DisableClockSleep\n + * AHB2LPENR HASHLPEN LL_AHB2_GRP1_DisableClockSleep\n + * AHB2LPENR RNGLPEN LL_AHB2_GRP1_DisableClockSleep\n + * AHB2LPENR PKALPEN LL_AHB2_GRP1_DisableClockSleep\n + * AHB2LPENR SAESLPEN LL_AHB2_GRP1_DisableClockSleep\n + * AHB2LPENR SRAM2LPEN LL_AHB2_GRP1_DisableClockSleep\n + * AHB2LPENR SRAM3LPEN LL_AHB2_GRP1_DisableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB2_GRP1_PERIPH_ALL + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOA + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOB + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOC + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOD + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOE (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOF (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOG (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOH + * @arg @ref LL_AHB2_GRP1_PERIPH_GPIOI (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_ADC + * @arg @ref LL_AHB2_GRP1_PERIPH_DAC1 + * @arg @ref LL_AHB2_GRP1_PERIPH_DCMI_PSSI (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_AES (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_HASH (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_RNG + * @arg @ref LL_AHB2_GRP1_PERIPH_PKA (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_SAES (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_SRAM2 (*) + * @arg @ref LL_AHB2_GRP1_PERIPH_SRAM3 (*) + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_AHB2_GRP1_DisableClockSleep(uint32_t Periphs) +{ + CLEAR_BIT(RCC->AHB2LPENR, Periphs); +} + +/** + * @} + */ + +#if defined(AHB4PERIPH_BASE) +/** @defgroup BUS_LL_EF_AHB4 AHB4 Peripherals + * @{ + */ +/** + * @brief Enable AHB4 peripherals clock. + * @rmtoll AHB4ENR OTFDEC1EN LL_AHB4_GRP1_EnableClock\n + * AHB4ENR SDMMC1EN LL_AHB4_GRP1_EnableClock\n + * AHB4ENR SDMMC2EN LL_AHB4_GRP1_EnableClock\n + * AHB4ENR FMCEN LL_AHB4_GRP1_EnableClock\n + * AHB4ENR OCTOSPI1EN LL_AHB4_GRP1_EnableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB4_GRP1_PERIPH_ALL + * @arg @ref LL_AHB4_GRP1_PERIPH_OTFDEC + * @arg @ref LL_AHB4_GRP1_PERIPH_SDMMC1 + * @arg @ref LL_AHB4_GRP1_PERIPH_SDMMC2 (*) + * @arg @ref LL_AHB4_GRP1_PERIPH_FMC + * @arg @ref LL_AHB4_GRP1_PERIPH_OSPI1 + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_AHB4_GRP1_EnableClock(uint32_t Periphs) +{ + __IO uint32_t tmpreg; + SET_BIT(RCC->AHB4ENR, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->AHB4ENR, Periphs); + (void)tmpreg; +} + +/** + * @brief Check if AHB4 peripheral clock is enabled or not + * @rmtoll AHB4ENR OTFDEC1EN LL_AHB4_GRP1_IsEnabledClock\n + * AHB4ENR SDMMC1EN LL_AHB4_GRP1_IsEnabledClock\n + * AHB4ENR SDMMC2EN LL_AHB4_GRP1_IsEnabledClock\n + * AHB4ENR FMCEN LL_AHB4_GRP1_IsEnabledClock\n + * AHB4ENR OCTOSPI1EN LL_AHB4_GRP1_IsEnabledClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB4_GRP1_PERIPH_ALL + * @arg @ref LL_AHB4_GRP1_PERIPH_OTFDEC + * @arg @ref LL_AHB4_GRP1_PERIPH_SDMMC1 + * @arg @ref LL_AHB4_GRP1_PERIPH_SDMMC2 + * @arg @ref LL_AHB4_GRP1_PERIPH_FMC + * @arg @ref LL_AHB4_GRP1_PERIPH_OSPI1 + * @retval State of Periphs (1 or 0). + */ +__STATIC_INLINE uint32_t LL_AHB4_GRP1_IsEnabledClock(uint32_t Periphs) +{ + return ((READ_BIT(RCC->AHB4ENR, Periphs) == Periphs) ? 1UL : 0UL); +} + +/** + * @brief Disable AHB4 peripherals clock. + * @rmtoll AHB4ENR OTFDEC1EN LL_AHB4_GRP1_DisableClock\n + * AHB4ENR SDMMC1EN LL_AHB4_GRP1_DisableClock\n + * AHB4ENR SDMMC2EN LL_AHB4_GRP1_DisableClock\n + * AHB4ENR FMCEN LL_AHB4_GRP1_DisableClock\n + * AHB4ENR OCTOSPI1EN LL_AHB4_GRP1_DisableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB4_GRP1_PERIPH_ALL + * @arg @ref LL_AHB4_GRP1_PERIPH_OTFDEC + * @arg @ref LL_AHB4_GRP1_PERIPH_SDMMC1 + * @arg @ref LL_AHB4_GRP1_PERIPH_SDMMC2 + * @arg @ref LL_AHB4_GRP1_PERIPH_FMC + * @arg @ref LL_AHB4_GRP1_PERIPH_OSPI1 + * @retval None + */ +__STATIC_INLINE void LL_AHB4_GRP1_DisableClock(uint32_t Periphs) +{ + CLEAR_BIT(RCC->AHB4ENR, Periphs); +} + +/** + * @brief Force AHB4 peripherals reset. + * @rmtoll AHB4RSTR OTFDEC1RST LL_AHB4_GRP1_ForceReset\n + * AHB4RSTR SDMMC1RST LL_AHB4_GRP1_ForceReset\n + * AHB4RSTR SDMMC2RST LL_AHB4_GRP1_ForceReset\n + * AHB4RSTR FMCRST LL_AHB4_GRP1_ForceReset\n + * AHB4RSTR OCTOSPI1RST LL_AHB4_GRP1_ForceReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB4_GRP1_PERIPH_ALL + * @arg @ref LL_AHB4_GRP1_PERIPH_OTFDEC + * @arg @ref LL_AHB4_GRP1_PERIPH_SDMMC1 + * @arg @ref LL_AHB4_GRP1_PERIPH_SDMMC2 + * @arg @ref LL_AHB4_GRP1_PERIPH_FMC + * @arg @ref LL_AHB4_GRP1_PERIPH_OSPI1 + * @retval None + */ +__STATIC_INLINE void LL_AHB4_GRP1_ForceReset(uint32_t Periphs) +{ + SET_BIT(RCC->AHB4RSTR, Periphs); +} + +/** + * @brief Release AHB4 peripherals reset. + * @rmtoll AHB4RSTR OTFDEC1RST LL_AHB4_GRP1_ReleaseReset\n + * AHB4RSTR SDMMC1RST LL_AHB4_GRP1_ReleaseReset\n + * AHB4RSTR SDMMC2RST LL_AHB4_GRP1_ReleaseReset\n + * AHB4RSTR FMCRST LL_AHB4_GRP1_ReleaseReset\n + * AHB4RSTR OCTOSPI1RST LL_AHB4_GRP1_ReleaseReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB4_GRP1_PERIPH_ALL + * @arg @ref LL_AHB4_GRP1_PERIPH_OTFDEC + * @arg @ref LL_AHB4_GRP1_PERIPH_SDMMC1 + * @arg @ref LL_AHB4_GRP1_PERIPH_SDMMC2 + * @arg @ref LL_AHB4_GRP1_PERIPH_FMC + * @arg @ref LL_AHB4_GRP1_PERIPH_OSPI1 + * @retval None + */ +__STATIC_INLINE void LL_AHB4_GRP1_ReleaseReset(uint32_t Periphs) +{ + CLEAR_BIT(RCC->AHB4RSTR, Periphs); +} + +/** + * @brief Enable AHB4 peripheral clocks in Sleep mode + * @rmtoll AHB4LPENR OTFDEC1LPEN LL_AHB4_GRP1_EnableClockSleep\n + * AHB4LPENR SDMMC1LPEN LL_AHB4_GRP1_EnableClockSleep\n + * AHB4LPENR SDMMC2LPEN LL_AHB4_GRP1_EnableClockSleep\n + * AHB4LPENR FMCLPEN LL_AHB4_GRP1_EnableClockSleep\n + * AHB4LPENR OCTOSPI1LPEN LL_AHB4_GRP1_EnableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB4_GRP1_PERIPH_ALL + * @arg @ref LL_AHB4_GRP1_PERIPH_OTFDEC + * @arg @ref LL_AHB4_GRP1_PERIPH_SDMMC1 + * @arg @ref LL_AHB4_GRP1_PERIPH_SDMMC2 + * @arg @ref LL_AHB4_GRP1_PERIPH_FMC + * @arg @ref LL_AHB4_GRP1_PERIPH_OSPI1 + * @retval None + */ +__STATIC_INLINE void LL_AHB4_GRP1_EnableClockSleep(uint32_t Periphs) +{ + __IO uint32_t tmpreg; + SET_BIT(RCC->AHB4LPENR, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->AHB4LPENR, Periphs); + (void)tmpreg; +} + +/** + * @brief Check if AHB4 peripheral clocks in Sleep mode is enabled or not + * @rmtoll AHB4LPENR OTFDEC1LPEN LL_AHB4_GRP1_IsEnabledClockSleep\n + * AHB4LPENR SDMMC1LPEN LL_AHB4_GRP1_IsEnabledClockSleep\n + * AHB4LPENR SDMMC2LPEN LL_AHB4_GRP1_IsEnabledClockSleep\n + * AHB4LPENR FMCLPEN LL_AHB4_GRP1_IsEnabledClockSleep\n + * AHB4LPENR OCTOSPI1LPEN LL_AHB4_GRP1_IsEnabledClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB4_GRP1_PERIPH_ALL + * @arg @ref LL_AHB4_GRP1_PERIPH_OTFDEC + * @arg @ref LL_AHB4_GRP1_PERIPH_SDMMC1 + * @arg @ref LL_AHB4_GRP1_PERIPH_SDMMC2 + * @arg @ref LL_AHB4_GRP1_PERIPH_FMC + * @arg @ref LL_AHB4_GRP1_PERIPH_OSPI1 + * @retval State of Periphs (1 or 0). + */ +__STATIC_INLINE uint32_t LL_AHB4_GRP1_IsEnabledClockSleep(uint32_t Periphs) +{ + return ((READ_BIT(RCC->AHB4LPENR, Periphs) == Periphs) ? 1UL : 0UL); +} + +/** + * @brief Disable AHB4 peripheral clocks in Sleep and Stop modes + * @rmtoll AHB4LPENR OTFDEC1LPEN LL_AHB4_GRP1_DisableClockSleep\n + * AHB4LPENR SDMMC1LPEN LL_AHB4_GRP1_DisableClockSleep\n + * AHB4LPENR SDMMC2LPEN LL_AHB4_GRP1_DisableClockSleep\n + * AHB4LPENR FMCLPEN LL_AHB4_GRP1_DisableClockSleep\n + * AHB4LPENR OCTOSPI1LPEN LL_AHB4_GRP1_DisableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB4_GRP1_PERIPH_ALL + * @arg @ref LL_AHB4_GRP1_PERIPH_OTFDEC + * @arg @ref LL_AHB4_GRP1_PERIPH_SDMMC1 + * @arg @ref LL_AHB4_GRP1_PERIPH_SDMMC2 + * @arg @ref LL_AHB4_GRP1_PERIPH_FMC + * @arg @ref LL_AHB4_GRP1_PERIPH_OSPI1 + * @retval None + */ +__STATIC_INLINE void LL_AHB4_GRP1_DisableClockSleep(uint32_t Periphs) +{ + CLEAR_BIT(RCC->AHB4LPENR, Periphs); +} + +/** + * @} + */ +#endif /* AHB4PERIPH_BASE */ + +/** @defgroup BUS_LL_EF_APB1 APB1 Peripherals + * @{ + */ + +/** + * @brief Enable APB1 peripherals clock. + * @rmtoll APB1LENR TIM2EN LL_APB1_GRP1_EnableClock\n + * APB1LENR TIM3EN LL_APB1_GRP1_EnableClock\n + * APB1LENR TIM4EN LL_APB1_GRP1_EnableClock\n + * APB1LENR TIM5EN LL_APB1_GRP1_EnableClock\n + * APB1LENR TIM6EN LL_APB1_GRP1_EnableClock\n + * APB1LENR TIM7EN LL_APB1_GRP1_EnableClock\n + * APB1LENR TIM12EN LL_APB1_GRP1_EnableClock\n + * APB1LENR TIM13EN LL_APB1_GRP1_EnableClock\n + * APB1LENR TIM14EN LL_APB1_GRP1_EnableClock\n + * APB1LENR WWDGEN LL_APB1_GRP1_EnableClock\n + * APB1LENR SPI2EN LL_APB1_GRP1_EnableClock\n + * APB1LENR SPI3EN LL_APB1_GRP1_EnableClock\n + * APB1LENR USART2EN LL_APB1_GRP1_EnableClock\n + * APB1LENR USART3EN LL_APB1_GRP1_EnableClock\n + * APB1LENR UART4EN LL_APB1_GRP1_EnableClock\n + * APB1LENR UART5EN LL_APB1_GRP1_EnableClock\n + * APB1LENR I2C1EN LL_APB1_GRP1_EnableClock\n + * APB1LENR I2C2EN LL_APB1_GRP1_EnableClock\n + * APB1LENR I3C1EN LL_APB1_GRP1_EnableClock\n + * APB1LENR CRSEN LL_APB1_GRP1_EnableClock\n + * APB1LENR USART6EN LL_APB1_GRP1_EnableClock\n + * APB1LENR USART10EN LL_APB1_GRP1_EnableClock\n + * APB1LENR USART11EN LL_APB1_GRP1_EnableClock\n + * APB1LENR CECEN LL_APB1_GRP1_EnableClock\n + * APB1LENR UART7EN LL_APB1_GRP1_EnableClock\n + * APB1LENR UART8EN LL_APB1_GRP1_EnableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP1_PERIPH_ALL + * @arg @ref LL_APB1_GRP1_PERIPH_TIM2 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM3 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM4 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM5 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM6 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM7 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM12 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM13 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM14 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_WWDG + * @arg @ref LL_APB1_GRP1_PERIPH_SPI2 + * @arg @ref LL_APB1_GRP1_PERIPH_SPI3 + * @arg @ref LL_APB1_GRP1_PERIPH_OPAMP (*) + * @arg @ref LL_APB1_GRP1_PERIPH_COMP (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART2 + * @arg @ref LL_APB1_GRP1_PERIPH_USART3 + * @arg @ref LL_APB1_GRP1_PERIPH_UART4 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_UART5 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_I2C1 + * @arg @ref LL_APB1_GRP1_PERIPH_I2C2 + * @arg @ref LL_APB1_GRP1_PERIPH_I3C1 + * @arg @ref LL_APB1_GRP1_PERIPH_CRS + * @arg @ref LL_APB1_GRP1_PERIPH_USART6 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART10 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART11 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_CEC (*) + * @arg @ref LL_APB1_GRP1_PERIPH_UART7 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_UART8 (*) + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_APB1_GRP1_EnableClock(uint32_t Periphs) +{ + __IO uint32_t tmpreg; + SET_BIT(RCC->APB1LENR, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->APB1LENR, Periphs); + (void)tmpreg; +} + +/** + * @brief Enable APB1 peripherals clock. + * @rmtoll APB1HENR UART9EN LL_APB1_GRP2_EnableClock\n + * APB1HENR UART12EN LL_APB1_GRP2_EnableClock\n + * APB1HENR DTSEN LL_APB1_GRP2_EnableClock\n + * APB1HENR LPTIM2EN LL_APB1_GRP2_EnableClock\n + * APB1HENR FDCANEN LL_APB1_GRP2_EnableClock\n + * APB1HENR FDCANEN LL_APB1_GRP2_EnableClock\n + * APB1HENR UCPD1EN LL_APB1_GRP2_EnableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP2_PERIPH_ALL + * @arg @ref LL_APB1_GRP2_PERIPH_UART9 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_UART12 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_DTS + * @arg @ref LL_APB1_GRP2_PERIPH_LPTIM2 + * @arg @ref LL_APB1_GRP2_PERIPH_FDCAN + * @arg @ref LL_APB1_GRP2_PERIPH_UCPD1 + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_APB1_GRP2_EnableClock(uint32_t Periphs) +{ + __IO uint32_t tmpreg; + SET_BIT(RCC->APB1HENR, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->APB1HENR, Periphs); + (void)tmpreg; +} + +/** + * @brief Check if APB1 peripheral clock is enabled or not + * @rmtoll APB1LENR TIM2EN LL_APB1_GRP1_IsEnabledClock\n + * APB1LENR TIM3EN LL_APB1_GRP1_IsEnabledClock\n + * APB1LENR TIM4EN LL_APB1_GRP1_IsEnabledClock\n + * APB1LENR TIM5EN LL_APB1_GRP1_IsEnabledClock\n + * APB1LENR TIM6EN LL_APB1_GRP1_IsEnabledClock\n + * APB1LENR TIM7EN LL_APB1_GRP1_IsEnabledClock\n + * APB1LENR WWDGEN LL_APB1_GRP1_IsEnabledClock\n + * APB1LENR SPI2EN LL_APB1_GRP1_IsEnabledClock\n + * APB1LENR SPI3EN LL_APB1_GRP1_IsEnabledClock\n + * APB1LENR USART2EN LL_APB1_GRP1_IsEnabledClock\n + * APB1LENR USART3EN LL_APB1_GRP1_IsEnabledClock\n + * APB1LENR UART4EN LL_APB1_GRP1_IsEnabledClock\n + * APB1LENR UART5EN LL_APB1_GRP1_IsEnabledClock\n + * APB1LENR I2C1EN LL_APB1_GRP1_IsEnabledClock\n + * APB1LENR I2C2EN LL_APB1_GRP1_IsEnabledClock\n + * APB1LENR I3C1EN LL_APB1_GRP1_IsEnabledClock\n + * APB1LENR CRSEN LL_APB1_GRP1_IsEnabledClock\n + * APB1LENR USART6EN LL_APB1_GRP1_IsEnabledClock\n + * APB1LENR USART10EN LL_APB1_GRP1_IsEnabledClock\n + * APB1LENR USART11EN LL_APB1_GRP1_IsEnabledClock\n + * APB1LENR CECEN LL_APB1_GRP1_IsEnabledClock\n + * APB1LENR UART7EN LL_APB1_GRP1_IsEnabledClock\n + * APB1LENR UART8EN LL_APB1_GRP1_IsEnabledClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP1_PERIPH_ALL + * @arg @ref LL_APB1_GRP1_PERIPH_TIM2 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM3 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM4 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM5 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM6 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM7 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM12 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM13 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM14 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_WWDG + * @arg @ref LL_APB1_GRP1_PERIPH_SPI2 + * @arg @ref LL_APB1_GRP1_PERIPH_SPI3 + * @arg @ref LL_APB1_GRP1_PERIPH_OPAMP (*) + * @arg @ref LL_APB1_GRP1_PERIPH_COMP (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART2 + * @arg @ref LL_APB1_GRP1_PERIPH_USART3 + * @arg @ref LL_APB1_GRP1_PERIPH_UART4 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_UART5 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_I2C1 + * @arg @ref LL_APB1_GRP1_PERIPH_I2C2 + * @arg @ref LL_APB1_GRP1_PERIPH_I3C1 + * @arg @ref LL_APB1_GRP1_PERIPH_CRS + * @arg @ref LL_APB1_GRP1_PERIPH_USART6 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART10 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART11 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_CEC (*) + * @arg @ref LL_APB1_GRP1_PERIPH_UART7 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_UART8 (*) + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval State of Periphs (1 or 0). + */ +__STATIC_INLINE uint32_t LL_APB1_GRP1_IsEnabledClock(uint32_t Periphs) +{ + return ((READ_BIT(RCC->APB1LENR, Periphs) == Periphs) ? 1UL : 0UL); +} + +/** + * @brief Check if APB1 peripheral clock is enabled or not + * @rmtoll APB1HENR UART9EN LL_APB1_GRP2_IsEnabledClock\n + * APB1HENR UART12EN LL_APB1_GRP2_IsEnabledClock\n + * APB1HENR DTSEN LL_APB1_GRP2_IsEnabledClock\n + * APB1HENR LPTIM2EN LL_APB1_GRP2_IsEnabledClock\n + * APB1HENR FDCANEN LL_APB1_GRP2_IsEnabledClock\n + * APB1HENR UCPD1EN LL_APB1_GRP2_IsEnabledClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP2_PERIPH_ALL + * @arg @ref LL_APB1_GRP2_PERIPH_UART9 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_UART12 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_DTS + * @arg @ref LL_APB1_GRP2_PERIPH_LPTIM2 + * @arg @ref LL_APB1_GRP2_PERIPH_FDCAN + * @arg @ref LL_APB1_GRP2_PERIPH_UCPD1 + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval State of Periphs (1 or 0). + */ +__STATIC_INLINE uint32_t LL_APB1_GRP2_IsEnabledClock(uint32_t Periphs) +{ + return ((READ_BIT(RCC->APB1HENR, Periphs) == Periphs) ? 1UL : 0UL); +} + +/** + * @brief Disable APB1 peripherals clock. + * @rmtoll APB1LENR TIM2EN LL_APB1_GRP1_DisableClock\n + * APB1LENR TIM3EN LL_APB1_GRP1_DisableClock\n + * APB1LENR TIM4EN LL_APB1_GRP1_DisableClock\n + * APB1LENR TIM5EN LL_APB1_GRP1_DisableClock\n + * APB1LENR TIM6EN LL_APB1_GRP1_DisableClock\n + * APB1LENR TIM7EN LL_APB1_GRP1_DisableClock\n + * APB1LENR WWDGEN LL_APB1_GRP1_DisableClock\n + * APB1LENR SPI2EN LL_APB1_GRP1_DisableClock\n + * APB1LENR SPI3EN LL_APB1_GRP1_DisableClock\n + * APB1LENR USART2EN LL_APB1_GRP1_DisableClock\n + * APB1LENR USART3EN LL_APB1_GRP1_DisableClock\n + * APB1LENR UART4EN LL_APB1_GRP1_DisableClock\n + * APB1LENR UART5EN LL_APB1_GRP1_DisableClock\n + * APB1LENR I2C1EN LL_APB1_GRP1_DisableClock\n + * APB1LENR I2C2EN LL_APB1_GRP1_DisableClock\n + * APB1LENR I3C1EN LL_APB1_GRP1_DisableClock\n + * APB1LENR CRSEN LL_APB1_GRP1_DisableClock\n + * APB1LENR USART6EN LL_APB1_GRP1_DisableClock\n + * APB1LENR USART10EN LL_APB1_GRP1_DisableClock\n + * APB1LENR USART11EN LL_APB1_GRP1_DisableClock\n + * APB1LENR CECEN LL_APB1_GRP1_DisableClock\n + * APB1LENR UART7EN LL_APB1_GRP1_DisableClock\n + * APB1LENR UART8EN LL_APB1_GRP1_DisableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP1_PERIPH_ALL + * @arg @ref LL_APB1_GRP1_PERIPH_TIM2 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM3 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM4 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM5 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM6 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM7 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM12 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM13 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM14 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_WWDG + * @arg @ref LL_APB1_GRP1_PERIPH_SPI2 + * @arg @ref LL_APB1_GRP1_PERIPH_SPI3 + * @arg @ref LL_APB1_GRP1_PERIPH_OPAMP (*) + * @arg @ref LL_APB1_GRP1_PERIPH_COMP (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART2 + * @arg @ref LL_APB1_GRP1_PERIPH_USART3 + * @arg @ref LL_APB1_GRP1_PERIPH_UART4 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_UART5 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_I2C1 + * @arg @ref LL_APB1_GRP1_PERIPH_I2C2 + * @arg @ref LL_APB1_GRP1_PERIPH_I3C1 + * @arg @ref LL_APB1_GRP1_PERIPH_CRS + * @arg @ref LL_APB1_GRP1_PERIPH_USART6 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART10 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART11 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_CEC (*) + * @arg @ref LL_APB1_GRP1_PERIPH_UART7 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_UART8 (*) + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_APB1_GRP1_DisableClock(uint32_t Periphs) +{ + CLEAR_BIT(RCC->APB1LENR, Periphs); +} + +/** + * @brief Disable APB1 peripherals clock. + * @rmtoll APB1HENR UART9EN LL_APB1_GRP2_DisableClock\n + * APB1HENR UART12EN LL_APB1_GRP2_DisableClock\n + * APB1HENR DTSEN LL_APB1_GRP2_DisableClock\n + * APB1HENR LPTIM2EN LL_APB1_GRP2_DisableClock\n + * APB1HENR FDCANEN LL_APB1_GRP2_DisableClock\n + * APB1HENR UCPD1EN LL_APB1_GRP2_DisableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP2_PERIPH_ALL + * @arg @ref LL_APB1_GRP2_PERIPH_UART9 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_UART12 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_DTS + * @arg @ref LL_APB1_GRP2_PERIPH_LPTIM2 + * @arg @ref LL_APB1_GRP2_PERIPH_FDCAN + * @arg @ref LL_APB1_GRP2_PERIPH_UCPD1 + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_APB1_GRP2_DisableClock(uint32_t Periphs) +{ + CLEAR_BIT(RCC->APB1HENR, Periphs); +} + +/** + * @brief Force APB1 peripherals reset. + * @rmtoll APB1LRSTR TIM2RST LL_APB1_GRP1_ForceReset\n + * APB1LRSTR TIM3RST LL_APB1_GRP1_ForceReset\n + * APB1LRSTR TIM4RST LL_APB1_GRP1_ForceReset\n + * APB1LRSTR TIM5RST LL_APB1_GRP1_ForceReset\n + * APB1LRSTR TIM6RST LL_APB1_GRP1_ForceReset\n + * APB1LRSTR TIM7RST LL_APB1_GRP1_ForceReset\n + * APB1LRSTR SPI2RST LL_APB1_GRP1_ForceReset\n + * APB1LRSTR SPI3RST LL_APB1_GRP1_ForceReset\n + * APB1LRSTR USART2RST LL_APB1_GRP1_ForceReset\n + * APB1LRSTR USART3RST LL_APB1_GRP1_ForceReset\n + * APB1LRSTR UART4RST LL_APB1_GRP1_ForceReset\n + * APB1LRSTR UART5RST LL_APB1_GRP1_ForceReset\n + * APB1LRSTR I2C1RST LL_APB1_GRP1_ForceReset\n + * APB1LRSTR I2C2RST LL_APB1_GRP1_ForceReset\n + * APB1LRSTR I3C1RST LL_APB1_GRP1_ForceReset\n + * APB1LRSTR CRSRST LL_APB1_GRP1_ForceReset\n + * APB1LRSTR USART6RST LL_APB1_GRP1_ForceReset\n + * APB1LRSTR USART10RST LL_APB1_GRP1_ForceReset\n + * APB1LRSTR USART11RST LL_APB1_GRP1_ForceReset\n + * APB1LRSTR CECRST LL_APB1_GRP1_ForceReset\n + * APB1LRSTR UART7RST LL_APB1_GRP1_ForceReset\n + * APB1LRSTR UART8RST LL_APB1_GRP1_ForceReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP1_PERIPH_ALL + * @arg @ref LL_APB1_GRP1_PERIPH_TIM2 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM3 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM4 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM5 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM6 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM7 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM12 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM13 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM14 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_SPI2 + * @arg @ref LL_APB1_GRP1_PERIPH_SPI3 + * @arg @ref LL_APB1_GRP1_PERIPH_OPAMP (*) + * @arg @ref LL_APB1_GRP1_PERIPH_COMP (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART2 + * @arg @ref LL_APB1_GRP1_PERIPH_USART3 + * @arg @ref LL_APB1_GRP1_PERIPH_UART4 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_UART5 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_I2C1 + * @arg @ref LL_APB1_GRP1_PERIPH_I2C2 + * @arg @ref LL_APB1_GRP1_PERIPH_I3C1 + * @arg @ref LL_APB1_GRP1_PERIPH_CRS + * @arg @ref LL_APB1_GRP1_PERIPH_USART6 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART10 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART11 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_CEC (*) + * @arg @ref LL_APB1_GRP1_PERIPH_UART7 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_UART8 (*) + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_APB1_GRP1_ForceReset(uint32_t Periphs) +{ + SET_BIT(RCC->APB1LRSTR, Periphs); +} + +/** + * @brief Force APB1 peripherals reset. + * @rmtoll APB1HRSTR UART9RST LL_APB1_GRP2_ForceReset\n + * APB1HRSTR UART12RST LL_APB1_GRP2_ForceReset\n + * APB1HRSTR DTSRST LL_APB1_GRP2_ForceReset\n + * APB1HRSTR LPTIM2RST LL_APB1_GRP2_ForceReset\n + * APB1HRSTR FDCANRST LL_APB1_GRP2_ForceReset\n + * APB1HRSTR UCPD1RST LL_APB1_GRP2_ForceReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP2_PERIPH_ALL + * @arg @ref LL_APB1_GRP2_PERIPH_UART9 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_UART12 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_DTS + * @arg @ref LL_APB1_GRP2_PERIPH_LPTIM2 + * @arg @ref LL_APB1_GRP2_PERIPH_FDCAN + * @arg @ref LL_APB1_GRP2_PERIPH_UCPD1 + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_APB1_GRP2_ForceReset(uint32_t Periphs) +{ + SET_BIT(RCC->APB1HRSTR, Periphs); +} + +/** + * @brief Release APB1 peripherals reset. + * @rmtoll APB1LRSTR TIM2RST LL_APB1_GRP1_ReleaseReset\n + * APB1LRSTR TIM3RST LL_APB1_GRP1_ReleaseReset\n + * APB1LRSTR TIM4RST LL_APB1_GRP1_ReleaseReset\n + * APB1LRSTR TIM5RST LL_APB1_GRP1_ReleaseReset\n + * APB1LRSTR TIM6RST LL_APB1_GRP1_ReleaseReset\n + * APB1LRSTR TIM7RST LL_APB1_GRP1_ReleaseReset\n + * APB1LRSTR SPI2RST LL_APB1_GRP1_ReleaseReset\n + * APB1LRSTR SPI3RST LL_APB1_GRP1_ReleaseReset\n + * APB1LRSTR USART2RST LL_APB1_GRP1_ReleaseReset\n + * APB1LRSTR USART3RST LL_APB1_GRP1_ReleaseReset\n + * APB1LRSTR UART4RST LL_APB1_GRP1_ReleaseReset\n + * APB1LRSTR UART5RST LL_APB1_GRP1_ReleaseReset\n + * APB1LRSTR I2C1RST LL_APB1_GRP1_ReleaseReset\n + * APB1LRSTR I2C2RST LL_APB1_GRP1_ReleaseReset\n + * APB1LRSTR I3C1RST LL_APB1_GRP1_ReleaseReset\n + * APB1LRSTR CRSRST LL_APB1_GRP1_ReleaseReset\n + * APB1LRSTR USART6RST LL_APB1_GRP1_ReleaseReset\n + * APB1LRSTR USART10RST LL_APB1_GRP1_ReleaseReset\n + * APB1LRSTR USART11RST LL_APB1_GRP1_ReleaseReset\n + * APB1LRSTR CECRST LL_APB1_GRP1_ReleaseReset\n + * APB1LRSTR UART7RST LL_APB1_GRP1_ReleaseReset\n + * APB1LRSTR UART8RST LL_APB1_GRP1_ReleaseReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP1_PERIPH_ALL + * @arg @ref LL_APB1_GRP1_PERIPH_TIM2 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM3 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM4 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM5 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM6 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM7 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM12 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM13 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM14 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_SPI2 + * @arg @ref LL_APB1_GRP1_PERIPH_SPI3 + * @arg @ref LL_APB1_GRP1_PERIPH_OPAMP (*) + * @arg @ref LL_APB1_GRP1_PERIPH_COMP (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART2 + * @arg @ref LL_APB1_GRP1_PERIPH_USART3 + * @arg @ref LL_APB1_GRP1_PERIPH_UART4 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_UART5 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_I2C1 + * @arg @ref LL_APB1_GRP1_PERIPH_I2C2 + * @arg @ref LL_APB1_GRP1_PERIPH_I3C1 + * @arg @ref LL_APB1_GRP1_PERIPH_CRS + * @arg @ref LL_APB1_GRP1_PERIPH_USART6 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART10 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART11 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_CEC (*) + * @arg @ref LL_APB1_GRP1_PERIPH_UART7 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_UART8 (*) + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_APB1_GRP1_ReleaseReset(uint32_t Periphs) +{ + CLEAR_BIT(RCC->APB1LRSTR, Periphs); +} + +/** + * @brief Release APB1 peripherals reset. + * @rmtoll APB1HRSTR UART9RST LL_APB1_GRP2_ReleaseReset\n + * APB1HRSTR UART12RST LL_APB1_GRP2_ReleaseReset\n + * APB1HRSTR DTSRST LL_APB1_GRP2_ReleaseReset\n + * APB1HRSTR LPTIM2RST LL_APB1_GRP2_ReleaseReset\n + * APB1HRSTR FDCAN LL_APB1_GRP2_ReleaseReset\n + * APB1HRSTR UCPD1RST LL_APB1_GRP2_ReleaseReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP2_PERIPH_ALL + * @arg @ref LL_APB1_GRP2_PERIPH_UART9 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_UART12 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_DTS + * @arg @ref LL_APB1_GRP2_PERIPH_LPTIM2 + * @arg @ref LL_APB1_GRP2_PERIPH_FDCAN + * @arg @ref LL_APB1_GRP2_PERIPH_UCPD1 + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_APB1_GRP2_ReleaseReset(uint32_t Periphs) +{ + CLEAR_BIT(RCC->APB1HRSTR, Periphs); +} + +/** + * @brief Enable APB1 peripheral clocks in Sleep mode + * @rmtoll APB1LLPENR TIM2LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LLPENR TIM3LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LLPENR TIM4LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LLPENR TIM5LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LLPENR TIM6LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LLPENR TIM7LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LLPENR WWDGLPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LLPENR SPI2LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LLPENR SPI3LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LLPENR USART2LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LLPENR USART3LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LLPENR UART4LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LLPENR UART5LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LLPENR I2C1LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LLPENR I2C2LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LLPENR I3C1LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LLPENR CRSLPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LLPENR USART6LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LLPENR USART10LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LLPENR USART11LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LLPENR CECLPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LLPENR UART7LPEN LL_APB1_GRP1_EnableClockSleep\n + * APB1LLPENR UART8LPEN LL_APB1_GRP1_EnableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP1_PERIPH_ALL + * @arg @ref LL_APB1_GRP1_PERIPH_TIM2 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM3 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM4 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM5 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM6 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM7 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM12 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM13 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM14 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_WWDG + * @arg @ref LL_APB1_GRP1_PERIPH_SPI2 + * @arg @ref LL_APB1_GRP1_PERIPH_SPI3 + * @arg @ref LL_APB1_GRP1_PERIPH_OPAMP (*) + * @arg @ref LL_APB1_GRP1_PERIPH_COMP (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART2 + * @arg @ref LL_APB1_GRP1_PERIPH_USART3 + * @arg @ref LL_APB1_GRP1_PERIPH_UART4 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_UART5 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_I2C1 + * @arg @ref LL_APB1_GRP1_PERIPH_I2C2 + * @arg @ref LL_APB1_GRP1_PERIPH_I3C1 + * @arg @ref LL_APB1_GRP1_PERIPH_CRS + * @arg @ref LL_APB1_GRP1_PERIPH_USART6 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART10 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART11 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_CEC (*) + * @arg @ref LL_APB1_GRP1_PERIPH_UART7 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_UART8 (*) + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_APB1_GRP1_EnableClockSleep(uint32_t Periphs) +{ + __IO uint32_t tmpreg; + SET_BIT(RCC->APB1LLPENR, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->APB1LLPENR, Periphs); + (void)tmpreg; +} + +/** + * @brief Check if APB1 peripheral clocks in Sleep mode is enabled or not + * @rmtoll APB1LLPENR TIM2LPEN LL_APB1_GRP1_IsEnabledClockSleep\n + * APB1LLPENR TIM3LPEN LL_APB1_GRP1_IsEnabledClockSleep\n + * APB1LLPENR TIM4LPEN LL_APB1_GRP1_IsEnabledClockSleep\n + * APB1LLPENR TIM5LPEN LL_APB1_GRP1_IsEnabledClockSleep\n + * APB1LLPENR TIM6LPEN LL_APB1_GRP1_IsEnabledClockSleep\n + * APB1LLPENR TIM7LPEN LL_APB1_GRP1_IsEnabledClockSleep\n + * APB1LLPENR WWDGLPEN LL_APB1_GRP1_IsEnabledClockSleep\n + * APB1LLPENR SPI2LPEN LL_APB1_GRP1_IsEnabledClockSleep\n + * APB1LLPENR SPI3LPEN LL_APB1_GRP1_IsEnabledClockSleep\n + * APB1LLPENR USART2LPEN LL_APB1_GRP1_IsEnabledClockSleep\n + * APB1LLPENR USART3LPEN LL_APB1_GRP1_IsEnabledClockSleep\n + * APB1LLPENR UART4LPEN LL_APB1_GRP1_IsEnabledClockSleep\n + * APB1LLPENR UART5LPEN LL_APB1_GRP1_IsEnabledClockSleep\n + * APB1LLPENR I2C1LPEN LL_APB1_GRP1_IsEnabledClockSleep\n + * APB1LLPENR I2C2LPEN LL_APB1_GRP1_IsEnabledClockSleep\n + * APB1LLPENR I3C1LPEN LL_APB1_GRP1_IsEnabledClockSleep\n + * APB1LLPENR CRSLPEN LL_APB1_GRP1_IsEnabledClockSleep\n + * APB1LLPENR USART6LPEN LL_APB1_GRP1_IsEnabledClockSleep\n + * APB1LLPENR USART10LPEN LL_APB1_GRP1_IsEnabledClockSleep\n + * APB1LLPENR USART11LPEN LL_APB1_GRP1_IsEnabledClockSleep\n + * APB1LLPENR CECLPEN LL_APB1_GRP1_IsEnabledClockSleep\n + * APB1LLPENR UART7LPEN LL_APB1_GRP1_IsEnabledClockSleep\n + * APB1LLPENR UART8LPEN LL_APB1_GRP1_IsEnabledClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP1_PERIPH_ALL + * @arg @ref LL_APB1_GRP1_PERIPH_TIM2 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM3 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM4 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM5 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM6 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM7 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM12 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM13 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM14 + * @arg @ref LL_APB1_GRP1_PERIPH_WWDG + * @arg @ref LL_APB1_GRP1_PERIPH_SPI2 + * @arg @ref LL_APB1_GRP1_PERIPH_SPI3 + * @arg @ref LL_APB1_GRP1_PERIPH_OPAMP (*) + * @arg @ref LL_APB1_GRP1_PERIPH_COMP (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART2 + * @arg @ref LL_APB1_GRP1_PERIPH_USART3 + * @arg @ref LL_APB1_GRP1_PERIPH_UART4 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_UART5 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_I2C1 + * @arg @ref LL_APB1_GRP1_PERIPH_I2C2 + * @arg @ref LL_APB1_GRP1_PERIPH_I3C1 + * @arg @ref LL_APB1_GRP1_PERIPH_CRS + * @arg @ref LL_APB1_GRP1_PERIPH_USART6 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART10 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART11 + * @arg @ref LL_APB1_GRP1_PERIPH_CEC (*) + * @arg @ref LL_APB1_GRP1_PERIPH_UART7 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_UART8 (*) + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval State of Periphs (1 or 0). + */ +__STATIC_INLINE uint32_t LL_APB1_GRP1_IsEnabledClockSleep(uint32_t Periphs) +{ + return ((READ_BIT(RCC->APB1LLPENR, Periphs) == Periphs) ? 1UL : 0UL); +} + +/** + * @brief Disable APB1 peripheral clocks in Sleep mode + * @rmtoll APB1LLPENR TIM2LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LLPENR TIM3LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LLPENR TIM4LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LLPENR TIM5LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LLPENR TIM6LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LLPENR TIM7LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LLPENR WWDGLPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LLPENR SPI2LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LLPENR SPI3LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LLPENR USART2LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LLPENR USART3LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LLPENR UART4LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LLPENR UART5LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LLPENR I2C1LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LLPENR I2C2LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LLPENR I3C1LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LLPENR CRSLPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LLPENR USART6LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LLPENR USART10LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LLPENR USART11LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LLPENR CECLPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LLPENR UART7LPEN LL_APB1_GRP1_DisableClockSleep\n + * APB1LLPENR UART8LPEN LL_APB1_GRP1_DisableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP1_PERIPH_ALL + * @arg @ref LL_APB1_GRP1_PERIPH_TIM2 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM3 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM4 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM5 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM6 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM7 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM12 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM13 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM14 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_WWDG + * @arg @ref LL_APB1_GRP1_PERIPH_SPI2 + * @arg @ref LL_APB1_GRP1_PERIPH_SPI3 + * @arg @ref LL_APB1_GRP1_PERIPH_OPAMP (*) + * @arg @ref LL_APB1_GRP1_PERIPH_COMP (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART2 + * @arg @ref LL_APB1_GRP1_PERIPH_USART3 + * @arg @ref LL_APB1_GRP1_PERIPH_UART4 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_UART5 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_I2C1 + * @arg @ref LL_APB1_GRP1_PERIPH_I2C2 + * @arg @ref LL_APB1_GRP1_PERIPH_I3C1 + * @arg @ref LL_APB1_GRP1_PERIPH_CRS + * @arg @ref LL_APB1_GRP1_PERIPH_USART6 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART10 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART11 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_CEC (*) + * @arg @ref LL_APB1_GRP1_PERIPH_UART7 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_UART8 (*) + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_APB1_GRP1_DisableClockSleep(uint32_t Periphs) +{ + CLEAR_BIT(RCC->APB1LLPENR, Periphs); +} + +/** + * @brief Enable APB1 peripheral clocks in Sleep mode + * @rmtoll APB1HLPENR UART9LPEN LL_APB1_GRP2_EnableClockSleep\n + * APB1HLPENR UART12LPEN LL_APB1_GRP2_EnableClockSleep\n + * APB1HLPENR DTSLPEN LL_APB1_GRP2_EnableClockSleep\n + * APB1HLPENR LPTIM2LPEN LL_APB1_GRP2_EnableClockSleep\n + * APB1HLPENR FDCAN12LPEN LL_APB1_GRP2_EnableClockSleep\n + * APB1HLPENR FDCAN1LPEN LL_APB1_GRP2_EnableClockSleep\n + * APB1HLPENR UCPD1LPEN LL_APB1_GRP2_EnableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP2_PERIPH_ALL + * @arg @ref LL_APB1_GRP2_PERIPH_UART9 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_UART12 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_DTS + * @arg @ref LL_APB1_GRP2_PERIPH_LPTIM2 + * @arg @ref LL_APB1_GRP2_PERIPH_FDCAN + * @arg @ref LL_APB1_GRP2_PERIPH_UCPD1 + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_APB1_GRP2_EnableClockSleep(uint32_t Periphs) +{ + __IO uint32_t tmpreg; + SET_BIT(RCC->APB1HLPENR, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->APB1HLPENR, Periphs); + (void)tmpreg; +} + +/** + * @brief Check if APB1 peripheral clocks in Sleep mode is enabled or not + * @rmtoll APB1HLPENR UART9LPEN LL_APB1_GRP2_IsEnabledClockSleep\n + * APB1HLPENR UART12LPEN LL_APB1_GRP2_IsEnabledClockSleep\n + * APB1HLPENR DTSLPEN LL_APB1_GRP2_IsEnabledClockSleep\n + * APB1HLPENR LPTIM2LPEN LL_APB1_GRP2_IsEnabledClockSleep\n + * APB1HLPENR FDCAN12LPEN LL_APB1_GRP2_IsEnabledClockSleep\n + * APB1HLPENR FDCAN1LPEN LL_APB1_GRP2_IsEnabledClockSleep\n + * APB1HLPENR UCPD1LPEN LL_APB1_GRP2_IsEnabledClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP2_PERIPH_ALL + * @arg @ref LL_APB1_GRP2_PERIPH_UART9 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_UART12 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_DTS + * @arg @ref LL_APB1_GRP2_PERIPH_LPTIM2 + * @arg @ref LL_APB1_GRP2_PERIPH_FDCAN + * @arg @ref LL_APB1_GRP2_PERIPH_UCPD1 + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval State of Periphs (1 or 0). + */ +__STATIC_INLINE uint32_t LL_APB1_GRP2_IsEnabledClockSleep(uint32_t Periphs) +{ + return ((READ_BIT(RCC->APB1HLPENR, Periphs) == Periphs) ? 1UL : 0UL); +} + +/** + * @brief Disable APB1 peripheral clocks in Sleep mode + * @rmtoll APB1HLPENR UART9LPEN LL_APB1_GRP2_DisableClockSleep\n + * APB1HLPENR UART12LPEN LL_APB1_GRP2_DisableClockSleep\n + * APB1HLPENR DTSLPEN LL_APB1_GRP2_DisableClockSleep\n + * APB1HLPENR LPTIM2LPEN LL_APB1_GRP2_DisableClockSleep\n + * APB1HLPENR FDCAN12LPEN LL_APB1_GRP2_DisableClockSleep\n + * APB1HLPENR FDCAN1LPEN LL_APB1_GRP2_DisableClockSleep\n + * APB1HLPENR UCPD1LPEN LL_APB1_GRP2_DisableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP2_PERIPH_ALL + * @arg @ref LL_APB1_GRP2_PERIPH_UART9 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_UART12 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_DTS + * @arg @ref LL_APB1_GRP2_PERIPH_LPTIM2 + * @arg @ref LL_APB1_GRP2_PERIPH_FDCAN + * @arg @ref LL_APB1_GRP2_PERIPH_UCPD1 + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_APB1_GRP2_DisableClockSleep(uint32_t Periphs) +{ + CLEAR_BIT(RCC->APB1HLPENR, Periphs); +} + +/** + * @} + */ + +/** @defgroup BUS_LL_EF_APB2 APB2 Peripherals + * @{ + */ + +/** + * @brief Enable APB2 peripherals clock. + * @rmtoll APB2ENR TIM1EN LL_APB2_GRP1_EnableClock\n + * APB2ENR SPI1EN LL_APB2_GRP1_EnableClock\n + * APB2ENR TIM8EN LL_APB2_GRP1_EnableClock\n + * APB2ENR USART1EN LL_APB2_GRP1_EnableClock\n + * APB2ENR TIM15EN LL_APB2_GRP1_EnableClock\n + * APB2ENR TIM16EN LL_APB2_GRP1_EnableClock\n + * APB2ENR TIM17EN LL_APB2_GRP1_EnableClock\n + * APB2ENR SPI4EN LL_APB2_GRP1_EnableClock\n + * APB2ENR SPI6EN LL_APB2_GRP1_EnableClock\n + * APB2ENR SAI1EN LL_APB2_GRP1_EnableClock\n + * APB2ENR SAI2EN LL_APB2_GRP1_EnableClock\n + * APB2ENR USBEN LL_APB2_GRP1_EnableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB2_GRP1_PERIPH_ALL + * @arg @ref LL_APB2_GRP1_PERIPH_TIM1 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI1 + * @arg @ref LL_APB2_GRP1_PERIPH_TIM8 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_USART1 + * @arg @ref LL_APB2_GRP1_PERIPH_TIM15 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_TIM16 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_TIM17 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SPI4 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SPI6 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SAI1 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SAI2 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_USB + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_APB2_GRP1_EnableClock(uint32_t Periphs) +{ + __IO uint32_t tmpreg; + SET_BIT(RCC->APB2ENR, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->APB2ENR, Periphs); + (void)tmpreg; +} + +/** + * @brief Check if APB2 peripheral clock is enabled or not + * @rmtoll APB2ENR TIM1EN LL_APB2_GRP1_IsEnabledClock\n + * APB2ENR SPI1EN LL_APB2_GRP1_IsEnabledClock\n + * APB2ENR TIM8EN LL_APB2_GRP1_IsEnabledClock\n + * APB2ENR USART1EN LL_APB2_GRP1_IsEnabledClock\n + * APB2ENR TIM15EN LL_APB2_GRP1_IsEnabledClock\n + * APB2ENR TIM16EN LL_APB2_GRP1_IsEnabledClock\n + * APB2ENR TIM17EN LL_APB2_GRP1_IsEnabledClock\n + * APB2ENR SPI4EN LL_APB2_GRP1_IsEnabledClock\n + * APB2ENR SPI6EN LL_APB2_GRP1_IsEnabledClock\n + * APB2ENR SAI1EN LL_APB2_GRP1_IsEnabledClock\n + * APB2ENR SAI2EN LL_APB2_GRP1_IsEnabledClock\n + * APB2ENR USBEN LL_APB2_GRP1_IsEnabledClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB2_GRP1_PERIPH_ALL + * @arg @ref LL_APB2_GRP1_PERIPH_TIM1 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI1 + * @arg @ref LL_APB2_GRP1_PERIPH_TIM8 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_USART1 + * @arg @ref LL_APB2_GRP1_PERIPH_TIM15 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_TIM16 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_TIM17 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SPI4 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SPI6 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SAI1 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SAI2 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_USB + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval State of Periphs (1 or 0). + */ +__STATIC_INLINE uint32_t LL_APB2_GRP1_IsEnabledClock(uint32_t Periphs) +{ + return ((READ_BIT(RCC->APB2ENR, Periphs) == Periphs) ? 1UL : 0UL); +} + +/** + * @brief Disable APB2 peripherals clock. + * @rmtoll APB2ENR TIM1EN LL_APB2_GRP1_DisableClock\n + * APB2ENR SPI1EN LL_APB2_GRP1_DisableClock\n + * APB2ENR TIM8EN LL_APB2_GRP1_DisableClock\n + * APB2ENR USART1EN LL_APB2_GRP1_DisableClock\n + * APB2ENR TIM15EN LL_APB2_GRP1_DisableClock\n + * APB2ENR TIM16EN LL_APB2_GRP1_DisableClock\n + * APB2ENR TIM17EN LL_APB2_GRP1_DisableClock\n + * APB2ENR SPI4EN LL_APB2_GRP1_DisableClock\n + * APB2ENR SPI6EN LL_APB2_GRP1_DisableClock\n + * APB2ENR SAI1EN LL_APB2_GRP1_DisableClock\n + * APB2ENR SAI2EN LL_APB2_GRP1_DisableClock\n + * APB2ENR USBEN LL_APB2_GRP1_DisableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB2_GRP1_PERIPH_ALL + * @arg @ref LL_APB2_GRP1_PERIPH_TIM1 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI1 + * @arg @ref LL_APB2_GRP1_PERIPH_TIM8 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_USART1 + * @arg @ref LL_APB2_GRP1_PERIPH_TIM15 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_TIM16 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_TIM17 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SPI4 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SPI6 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SAI1 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SAI2 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_USB + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_APB2_GRP1_DisableClock(uint32_t Periphs) +{ + CLEAR_BIT(RCC->APB2ENR, Periphs); +} + +/** + * @brief Force APB2 peripherals reset. + * @rmtoll APB2RSTR TIM1RST LL_APB2_GRP1_ForceReset\n + * APB2RSTR SPI1RST LL_APB2_GRP1_ForceReset\n + * APB2RSTR TIM8RST LL_APB2_GRP1_ForceReset\n + * APB2RSTR USART1RST LL_APB2_GRP1_ForceReset\n + * APB2RSTR TIM15RST LL_APB2_GRP1_ForceReset\n + * APB2RSTR TIM16RST LL_APB2_GRP1_ForceReset\n + * APB2RSTR TIM17RST LL_APB2_GRP1_ForceReset\n + * APB2RSTR SPI4RST LL_APB2_GRP1_ForceReset\n + * APB2RSTR SPI6RST LL_APB2_GRP1_ForceReset\n + * APB2RSTR SAI1RST LL_APB2_GRP1_ForceReset\n + * APB2RSTR SAI2RST LL_APB2_GRP1_ForceReset\n + * APB2RSTR USBRST LL_APB2_GRP1_ForceReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB2_GRP1_PERIPH_ALL + * @arg @ref LL_APB2_GRP1_PERIPH_TIM1 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI1 + * @arg @ref LL_APB2_GRP1_PERIPH_TIM8 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_USART1 + * @arg @ref LL_APB2_GRP1_PERIPH_TIM15 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_TIM16 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_TIM17 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SPI4 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SPI6 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SAI1 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SAI2 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_USB + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_APB2_GRP1_ForceReset(uint32_t Periphs) +{ + SET_BIT(RCC->APB2RSTR, Periphs); +} + +/** + * @brief Release APB2 peripherals reset. + * @rmtoll APB2RSTR TIM1RST LL_APB2_GRP1_ReleaseReset\n + * APB2RSTR SPI1RST LL_APB2_GRP1_ReleaseReset\n + * APB2RSTR TIM8RST LL_APB2_GRP1_ReleaseReset\n + * APB2RSTR USART1RST LL_APB2_GRP1_ReleaseReset\n + * APB2RSTR TIM15RST LL_APB2_GRP1_ReleaseReset\n + * APB2RSTR TIM16RST LL_APB2_GRP1_ReleaseReset\n + * APB2RSTR TIM17RST LL_APB2_GRP1_ReleaseReset\n + * APB2RSTR SPI4RST LL_APB2_GRP1_ReleaseReset\n + * APB2RSTR SPI6RST LL_APB2_GRP1_ReleaseReset\n + * APB2RSTR SAI1RST LL_APB2_GRP1_ReleaseReset\n + * APB2RSTR SAI2RST LL_APB2_GRP1_ReleaseReset\n + * APB2RSTR USBRST LL_APB2_GRP1_ReleaseReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB2_GRP1_PERIPH_ALL + * @arg @ref LL_APB2_GRP1_PERIPH_TIM1 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI1 + * @arg @ref LL_APB2_GRP1_PERIPH_TIM8 + * @arg @ref LL_APB2_GRP1_PERIPH_USART1 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_TIM15 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_TIM16 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_TIM17 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SPI4 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SPI6 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SAI1 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SAI2 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_USB + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_APB2_GRP1_ReleaseReset(uint32_t Periphs) +{ + CLEAR_BIT(RCC->APB2RSTR, Periphs); +} + +/** + * @brief Enable APB2 peripheral clocks in Sleep mode + * @rmtoll APB2LPENR TIM1LPEN LL_APB2_GRP1_EnableClockSleep\n + * APB2LPENR SPI1LPEN LL_APB2_GRP1_EnableClockSleep\n + * APB2LPENR TIM8LPEN LL_APB2_GRP1_EnableClockSleep\n + * APB2LPENR USART1LPEN LL_APB2_GRP1_EnableClockSleep\n + * APB2LPENR TIM15LPEN LL_APB2_GRP1_EnableClockSleep\n + * APB2LPENR TIM16LPEN LL_APB2_GRP1_EnableClockSleep\n + * APB2LPENR TIM17LPEN LL_APB2_GRP1_EnableClockSleep\n + * APB2LPENR SPI4LPEN LL_APB2_GRP1_EnableClockSleep\n + * APB2LPENR SPI6LPEN LL_APB2_GRP1_EnableClockSleep\n + * APB2LPENR SAI1LPEN LL_APB2_GRP1_EnableClockSleep\n + * APB2LPENR SAI2LPEN LL_APB2_GRP1_EnableClockSleep\n + * APB2LPENR USBLPEN LL_APB2_GRP1_EnableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB2_GRP1_PERIPH_ALL + * @arg @ref LL_APB2_GRP1_PERIPH_TIM1 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI1 + * @arg @ref LL_APB2_GRP1_PERIPH_TIM8 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_USART1 + * @arg @ref LL_APB2_GRP1_PERIPH_TIM15 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_TIM16 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_TIM17 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SPI4 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SPI6 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SAI1 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SAI2 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_USB + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_APB2_GRP1_EnableClockSleep(uint32_t Periphs) +{ + __IO uint32_t tmpreg; + SET_BIT(RCC->APB2LPENR, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->APB2LPENR, Periphs); + (void)tmpreg; +} + + +/** + * @brief Check if APB2 peripheral clocks in Sleep and Stop modes is enabled or not + * @rmtoll APB2LPENR TIM1LPEN LL_APB2_GRP1_IsEnabledClockSleep\n + * APB2LPENR SPI1LPEN LL_APB2_GRP1_IsEnabledClockSleep\n + * APB2LPENR TIM8LPEN LL_APB2_GRP1_IsEnabledClockSleep\n + * APB2LPENR USART1LPEN LL_APB2_GRP1_IsEnabledClockSleep\n + * APB2LPENR TIM15LPEN LL_APB2_GRP1_IsEnabledClockSleep\n + * APB2LPENR TIM16LPEN LL_APB2_GRP1_IsEnabledClockSleep\n + * APB2LPENR TIM17LPEN LL_APB2_GRP1_IsEnabledClockSleep\n + * APB2LPENR SPI4LPEN LL_APB2_GRP1_IsEnabledClockSleep\n + * APB2LPENR SPI6LPEN LL_APB2_GRP1_IsEnabledClockSleep\n + * APB2LPENR SAI1LPEN LL_APB2_GRP1_IsEnabledClockSleep\n + * APB2LPENR SAI2LPEN LL_APB2_GRP1_IsEnabledClockSleep\n + * APB2LPENR USBLPEN LL_APB2_GRP1_IsEnabledClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB2_GRP1_PERIPH_ALL + * @arg @ref LL_APB2_GRP1_PERIPH_TIM1 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI1 + * @arg @ref LL_APB2_GRP1_PERIPH_TIM8 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_USART1 + * @arg @ref LL_APB2_GRP1_PERIPH_TIM15 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_TIM16 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_TIM17 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SPI4 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SPI6 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SAI1 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SAI2 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_USB + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval State of Periphs (1 or 0). + */ +__STATIC_INLINE uint32_t LL_APB2_GRP1_IsEnabledClockSleep(uint32_t Periphs) +{ + return ((READ_BIT(RCC->APB2LPENR, Periphs) == Periphs) ? 1UL : 0UL); +} + +/** + * @brief Disable APB2 peripheral clocks in Sleep mode + * @rmtoll APB2LPENR TIM1LPEN LL_APB2_GRP1_DisableClockSleep\n + * APB2LPENR SPI1LPEN LL_APB2_GRP1_DisableClockSleep\n + * APB2LPENR TIM8LPEN LL_APB2_GRP1_DisableClockSleep\n + * APB2LPENR USART1LPEN LL_APB2_GRP1_DisableClockSleep\n + * APB2LPENR TIM15LPEN LL_APB2_GRP1_DisableClockSleep\n + * APB2LPENR TIM16LPEN LL_APB2_GRP1_DisableClockSleep\n + * APB2LPENR TIM17LPEN LL_APB2_GRP1_DisableClockSleep\n + * APB2LPENR SPI4LPEN LL_APB2_GRP1_DisableClockSleep\n + * APB2LPENR SPI6LPEN LL_APB2_GRP1_DisableClockSleep\n + * APB2LPENR SAI1LPEN LL_APB2_GRP1_DisableClockSleep\n + * APB2LPENR SAI2LPEN LL_APB2_GRP1_DisableClockSleep\n + * APB2LPENR USBLPEN LL_APB2_GRP1_DisableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB2_GRP1_PERIPH_ALL + * @arg @ref LL_APB2_GRP1_PERIPH_TIM1 + * @arg @ref LL_APB2_GRP1_PERIPH_SPI1 + * @arg @ref LL_APB2_GRP1_PERIPH_TIM8 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_USART1 + * @arg @ref LL_APB2_GRP1_PERIPH_TIM15 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_TIM16 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_TIM17 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SPI4 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SPI6 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SAI1 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_SAI2 (*) + * @arg @ref LL_APB2_GRP1_PERIPH_USB + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_APB2_GRP1_DisableClockSleep(uint32_t Periphs) +{ + CLEAR_BIT(RCC->APB2LPENR, Periphs); +} + +/** + * @} + */ + + +/** @defgroup BUS_LL_EF_APB3 APB3 Peripherals + */ + +/** + * @brief Enable APB3 peripherals clock. + * @rmtoll APB3ENR SBSEN LL_APB3_GRP1_EnableClock\n + * APB3ENR SPI5EN LL_APB3_GRP1_EnableClock\n + * APB3ENR LPUART1EN LL_APB3_GRP1_EnableClock\n + * APB3ENR I2C3EN LL_APB3_GRP1_EnableClock\n + * APB3ENR I2C4EN LL_APB3_GRP1_EnableClock\n + * APB3ENR LPTIM1EN LL_APB3_GRP1_EnableClock\n + * APB3ENR LPTIM3EN LL_APB3_GRP1_EnableClock\n + * APB3ENR LPTIM4EN LL_APB3_GRP1_EnableClock\n + * APB3ENR LPTIM5EN LL_APB3_GRP1_EnableClock\n + * APB3ENR LPTIM6EN LL_APB3_GRP1_EnableClock\n + * APB3ENR VREFEN LL_APB3_GRP1_EnableClock\n + * APB3ENR RTCAPBEN LL_APB3_GRP1_EnableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB3_GRP1_PERIPH_ALL + * @arg @ref LL_APB3_GRP1_PERIPH_SBS + * @arg @ref LL_APB3_GRP1_PERIPH_SPI5 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPUART1 + * @arg @ref LL_APB3_GRP1_PERIPH_I2C3 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_I2C4 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_I3C2 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM1 + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM3 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM4 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM5 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM6 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_VREF + * @arg @ref LL_APB3_GRP1_PERIPH_RTCAPB + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_APB3_GRP1_EnableClock(uint32_t Periphs) +{ + __IO uint32_t tmpreg; + SET_BIT(RCC->APB3ENR, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->APB3ENR, Periphs); + (void)tmpreg; +} + +/** + * @brief Check if APB3 peripheral clock is enabled or not + * @rmtoll APB3ENR SBSEN LL_APB3_GRP1_IsEnabledClock\n + * APB3ENR SPI5EN LL_APB3_GRP1_IsEnabledClock\n + * APB3ENR LPUART1EN LL_APB3_GRP1_IsEnabledClock\n + * APB3ENR I2C3EN LL_APB3_GRP1_IsEnabledClock\n + * APB3ENR I2C4EN LL_APB3_GRP1_IsEnabledClock\n + * APB3ENR LPTIM1EN LL_APB3_GRP1_IsEnabledClock\n + * APB3ENR LPTIM3EN LL_APB3_GRP1_IsEnabledClock\n + * APB3ENR LPTIM4EN LL_APB3_GRP1_IsEnabledClock\n + * APB3ENR LPTIM5EN LL_APB3_GRP1_IsEnabledClock\n + * APB3ENR LPTIM6EN LL_APB3_GRP1_IsEnabledClock\n + * APB3ENR VREFEN LL_APB3_GRP1_IsEnabledClock\n + * APB3ENR RTCAPBEN LL_APB3_GRP1_IsEnabledClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB3_GRP1_PERIPH_ALL + * @arg @ref LL_APB3_GRP1_PERIPH_SBS + * @arg @ref LL_APB3_GRP1_PERIPH_SPI5 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPUART1 + * @arg @ref LL_APB3_GRP1_PERIPH_I2C3 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_I2C4 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_I3C2 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM1 + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM3 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM4 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM5 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM6 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_VREF + * @arg @ref LL_APB3_GRP1_PERIPH_RTCAPB + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval State of Periphs (1 or 0). + */ +__STATIC_INLINE uint32_t LL_APB3_GRP1_IsEnabledClock(uint32_t Periphs) +{ + return ((READ_BIT(RCC->APB3ENR, Periphs) == Periphs) ? 1UL : 0UL); +} + +/** + * @brief Disable APB2 peripherals clock. + * @rmtoll APB3ENR SBSEN LL_APB3_GRP1_DisableClock\n + * APB3ENR SPI5EN LL_APB3_GRP1_DisableClock\n + * APB3ENR LPUART1EN LL_APB3_GRP1_DisableClock\n + * APB3ENR I2C3EN LL_APB3_GRP1_DisableClock\n + * APB3ENR I2C4EN LL_APB3_GRP1_DisableClock\n + * APB3ENR LPTIM1EN LL_APB3_GRP1_DisableClock\n + * APB3ENR LPTIM3EN LL_APB3_GRP1_DisableClock\n + * APB3ENR LPTIM4EN LL_APB3_GRP1_DisableClock\n + * APB3ENR LPTIM5EN LL_APB3_GRP1_DisableClock\n + * APB3ENR LPTIM6EN LL_APB3_GRP1_DisableClock\n + * APB3ENR VREFEN LL_APB3_GRP1_DisableClock\n + * APB3ENR RTCAPBEN LL_APB3_GRP1_DisableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB3_GRP1_PERIPH_ALL + * @arg @ref LL_APB3_GRP1_PERIPH_SBS + * @arg @ref LL_APB3_GRP1_PERIPH_SPI5 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPUART1 + * @arg @ref LL_APB3_GRP1_PERIPH_I2C3 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_I2C4 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_I3C2 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM1 + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM3 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM4 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM5 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM6 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_VREF + * @arg @ref LL_APB3_GRP1_PERIPH_RTCAPB + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_APB3_GRP1_DisableClock(uint32_t Periphs) +{ + CLEAR_BIT(RCC->APB3ENR, Periphs); +} + +/** + * @brief Force APB3 peripherals reset. + * @rmtoll APB3RSTR SPI5RST LL_APB3_GRP1_ForceReset\n + * APB3RSTR LPUART1RST LL_APB3_GRP1_ForceReset\n + * APB3RSTR I2C3RST LL_APB3_GRP1_ForceReset\n + * APB3RSTR I2C4RST LL_APB3_GRP1_ForceReset\n + * APB3RSTR LPTIM1RST LL_APB3_GRP1_ForceReset\n + * APB3RSTR LPTIM3RST LL_APB3_GRP1_ForceReset\n + * APB3RSTR LPTIM4RST LL_APB3_GRP1_ForceReset\n + * APB3RSTR LPTIM5RST LL_APB3_GRP1_ForceReset\n + * APB3RSTR LPTIM6RST LL_APB3_GRP1_ForceReset\n + * APB3RSTR VREFRST LL_APB3_GRP1_ForceReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB3_GRP1_PERIPH_ALL + * @arg @ref LL_APB3_GRP1_PERIPH_SBS + * @arg @ref LL_APB3_GRP1_PERIPH_SPI5 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPUART1 + * @arg @ref LL_APB3_GRP1_PERIPH_I2C3 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_I2C4 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_I3C2 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM1 + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM3 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM4 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM5 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM6 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_VREF + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_APB3_GRP1_ForceReset(uint32_t Periphs) +{ + SET_BIT(RCC->APB3RSTR, Periphs); +} + +/** + * @brief Release APB3 peripherals reset. + * @rmtoll APB3RSTR SPI5RST LL_APB3_GRP1_ReleaseReset\n + * APB3RSTR LPUART1RST LL_APB3_GRP1_ReleaseReset\n + * APB3RSTR I2C3RST LL_APB3_GRP1_ReleaseReset\n + * APB3RSTR I2C4RST LL_APB3_GRP1_ReleaseReset\n + * APB3RSTR LPTIM1RST LL_APB3_GRP1_ReleaseReset\n + * APB3RSTR LPTIM3RST LL_APB3_GRP1_ReleaseReset\n + * APB3RSTR LPTIM4RST LL_APB3_GRP1_ReleaseReset\n + * APB3RSTR LPTIM5RST LL_APB3_GRP1_ReleaseReset\n + * APB3RSTR LPTIM6RST LL_APB3_GRP1_ReleaseReset\n + * APB3RSTR VREFRST LL_APB3_GRP1_ReleaseReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB3_GRP1_PERIPH_ALL + * @arg @ref LL_APB3_GRP1_PERIPH_SBS + * @arg @ref LL_APB3_GRP1_PERIPH_SPI5 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPUART1 + * @arg @ref LL_APB3_GRP1_PERIPH_I2C3 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_I2C4 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_I3C2 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM1 + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM3 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM4 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM5 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM6 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_VREF + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_APB3_GRP1_ReleaseReset(uint32_t Periphs) +{ + CLEAR_BIT(RCC->APB3RSTR, Periphs); +} + +/** + * @brief Enable APB3 peripheral clocks in Sleep mode + * @rmtoll APB3LPENR SBSLPEN LL_APB3_GRP1_EnableClockSleep\n + * APB3LPENR SPI5LPEN LL_APB3_GRP1_EnableClockSleep\n + * APB3LPENR LPUART1LPEN LL_APB3_GRP1_EnableClockSleep\n + * APB3LPENR I2C3LPEN LL_APB3_GRP1_EnableClockSleep\n + * APB3LPENR I2C4LPEN LL_APB3_GRP1_EnableClockSleep\n + * APB3LPENR LPTIM1LPEN LL_APB3_GRP1_EnableClockSleep\n + * APB3LPENR LPTIM3LPEN LL_APB3_GRP1_EnableClockSleep\n + * APB3LPENR LPTIM4LPEN LL_APB3_GRP1_EnableClockSleep\n + * APB3LPENR LPTIM5LPEN LL_APB3_GRP1_EnableClockSleep\n + * APB3LPENR LPTIM6LPEN LL_APB3_GRP1_EnableClockSleep\n + * APB3LPENR VREFLPEN LL_APB3_GRP1_EnableClockSleep\n + * APB3LPENR RTCAPBLPEN LL_APB3_GRP1_EnableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB3_GRP1_PERIPH_ALL + * @arg @ref LL_APB3_GRP1_PERIPH_SBS + * @arg @ref LL_APB3_GRP1_PERIPH_SPI5 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPUART1 + * @arg @ref LL_APB3_GRP1_PERIPH_I2C3 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_I2C4 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_I3C2 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM1 + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM3 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM4 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM5 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM6 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_VREF + * @arg @ref LL_APB3_GRP1_PERIPH_RTCAPB + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_APB3_GRP1_EnableClockSleep(uint32_t Periphs) +{ + __IO uint32_t tmpreg; + SET_BIT(RCC->APB3LPENR, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->APB3LPENR, Periphs); + (void)tmpreg; +} + + +/** + * @brief Check if APB3 peripheral clocks in Sleep mode is enabled or not + * @rmtoll APB3LPENR SBSLPEN LL_APB3_GRP1_IsEnabledClockSleep\n + * APB3LPENR SPI5LPEN LL_APB3_GRP1_IsEnabledClockSleep\n + * APB3LPENR LPUART1LPEN LL_APB3_GRP1_IsEnabledClockSleep\n + * APB3LPENR I2C3LPEN LL_APB3_GRP1_IsEnabledClockSleep\n + * APB3LPENR I2C4LPEN LL_APB3_GRP1_IsEnabledClockSleep\n + * APB3LPENR LPTIM1LPEN LL_APB3_GRP1_IsEnabledClockSleep\n + * APB3LPENR LPTIM3LPEN LL_APB3_GRP1_IsEnabledClockSleep\n + * APB3LPENR LPTIM4LPEN LL_APB3_GRP1_IsEnabledClockSleep\n + * APB3LPENR LPTIM5LPEN LL_APB3_GRP1_IsEnabledClockSleep\n + * APB3LPENR LPTIM6LPEN LL_APB3_GRP1_IsEnabledClockSleep\n + * APB3LPENR VREFLPEN LL_APB3_GRP1_IsEnabledClockSleep\n + * APB3LPENR RTCAPBLPEN LL_APB3_GRP1_IsEnabledClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB3_GRP1_PERIPH_ALL + * @arg @ref LL_APB3_GRP1_PERIPH_SBS + * @arg @ref LL_APB3_GRP1_PERIPH_SPI5 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPUART1 + * @arg @ref LL_APB3_GRP1_PERIPH_I2C3 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_I2C4 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_I3C2 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM1 + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM3 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM4 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM5 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM6 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_VREF + * @arg @ref LL_APB3_GRP1_PERIPH_RTCAPB + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval State of Periphs (1 or 0). + */ +__STATIC_INLINE uint32_t LL_APB3_GRP1_IsEnabledClockSleep(uint32_t Periphs) +{ + return ((READ_BIT(RCC->APB3LPENR, Periphs) == Periphs) ? 1UL : 0UL); +} + +/** + * @brief Disable APB3 peripheral clocks in Sleep mode + * @rmtoll APB3LPENR SBSLPEN LL_APB3_GRP1_DisableClockSleep\n + * APB3LPENR SPI5LPEN LL_APB3_GRP1_DisableClockSleep\n + * APB3LPENR LPUART1LPEN LL_APB3_GRP1_DisableClockSleep\n + * APB3LPENR I2C3LPEN LL_APB3_GRP1_DisableClockSleep\n + * APB3LPENR I2C4LPEN LL_APB3_GRP1_DisableClockSleep\n + * APB3LPENR LPTIM1LPEN LL_APB3_GRP1_DisableClockSleep\n + * APB3LPENR LPTIM3LPEN LL_APB3_GRP1_DisableClockSleep\n + * APB3LPENR LPTIM4LPEN LL_APB3_GRP1_DisableClockSleep\n + * APB3LPENR LPTIM5LPEN LL_APB3_GRP1_DisableClockSleep\n + * APB3LPENR LPTIM6LPEN LL_APB3_GRP1_DisableClockSleep\n + * APB3LPENR VREFLPEN LL_APB3_GRP1_DisableClockSleep\n + * APB3LPENR RTCAPBLPEN LL_APB3_GRP1_DisableClockSleep + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB3_GRP1_PERIPH_ALL + * @arg @ref LL_APB3_GRP1_PERIPH_SBS + * @arg @ref LL_APB3_GRP1_PERIPH_SPI5 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPUART1 + * @arg @ref LL_APB3_GRP1_PERIPH_I2C3 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_I2C4 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_I3C2 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM1 + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM3 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM4 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM5 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_LPTIM6 (*) + * @arg @ref LL_APB3_GRP1_PERIPH_VREF + * @arg @ref LL_APB3_GRP1_PERIPH_RTCAPB + * + * (*) : Not available for all stm32h5xxxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_APB3_GRP1_DisableClockSleep(uint32_t Periphs) +{ + CLEAR_BIT(RCC->APB3LPENR, Periphs); +} + +/** + * @} + */ + +/** + * @} + */ +#endif /* defined(RCC) */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32H5xx_LL_BUS_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_comp.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_comp.h new file mode 100644 index 0000000000..8802505c9a --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_comp.h @@ -0,0 +1,801 @@ +/** + ********************************************************************************************************************** + * @file stm32h5xx_ll_comp.h + * @author MCD Application Team + * @brief Header file of COMP LL module. + ********************************************************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ********************************************************************************************************************** + */ + +/* Define to prevent recursive inclusion -----------------------------------------------------------------------------*/ +#ifndef __STM32H5xx_LL_COMP_H +#define __STM32H5xx_LL_COMP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ----------------------------------------------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (COMP1) + +/** @defgroup COMP_LL COMP + * @{ + */ + +/* Private types -----------------------------------------------------------------------------------------------------*/ +/* Private variables -------------------------------------------------------------------------------------------------*/ +/* Private constants -------------------------------------------------------------------------------------------------*/ +/** @defgroup COMP_LL_Private_Constants COMP Private Constants + * @{ + */ + +/* COMP registers bits positions */ +#define LL_COMP_OUTPUT_LEVEL_BITOFFSET_POS (30U) /* Value equivalent to POSITION_VAL(COMP_CSR_VALUE) */ + +/** + * @} + */ + +/* Private macros ----------------------------------------------------------------------------------------------------*/ +/* Exported types ----------------------------------------------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup COMP_LL_ES_INIT COMP Exported Init structure + * @{ + */ + +/** + * @brief Structure definition of some features of COMP instance. + */ +typedef struct +{ + uint32_t PowerMode; /*!< Set comparator operating mode to adjust power and speed. + This parameter can be a value of @ref COMP_LL_EC_POWERMODE + This feature can be modified afterwards using unitary + function @ref LL_COMP_SetPowerMode(). */ + + uint32_t InputPlus; /*!< Set comparator input plus (non-inverting input). + This parameter can be a value of @ref COMP_LL_EC_INPUT_PLUS + This feature can be modified afterwards using unitary + function @ref LL_COMP_SetInputPlus(). */ + + uint32_t InputMinus; /*!< Set comparator input minus (inverting input). + This parameter can be a value of @ref COMP_LL_EC_INPUT_MINUS + This feature can be modified afterwards using unitary + function @ref LL_COMP_SetInputMinus(). */ + + uint32_t InputHysteresis; /*!< Set comparator hysteresis mode of the input minus. + This parameter can be a value of @ref COMP_LL_EC_INPUT_HYSTERESIS + This feature can be modified afterwards using unitary + function @ref LL_COMP_SetInputHysteresis(). */ + + uint32_t OutputPolarity; /*!< Set comparator output polarity. + This parameter can be a value of @ref COMP_LL_EC_OUTPUT_POLARITY + This feature can be modified afterwards using unitary + function @ref LL_COMP_SetOutputPolarity(). */ + + uint32_t OutputBlankingSource; /*!< Set comparator blanking source. + This parameter can be a value of @ref COMP_LL_EC_OUTPUT_BLANKING_SOURCE + This feature can be modified afterwards using unitary + function @ref LL_COMP_SetOutputBlankingSource(). */ +} LL_COMP_InitTypeDef; + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/* Exported constants ------------------------------------------------------------------------------------------------*/ +/** @defgroup COMP_LL_Exported_Constants COMP Exported Constants + * @{ + */ + +/** @defgroup COMP_LL_EC_POWERMODE Comparator modes - Power mode + * @{ + */ +#define LL_COMP_POWERMODE_HIGHSPEED (0x00000000UL) /*!< COMP power mode to high speed */ +#define LL_COMP_POWERMODE_MEDIUMSPEED (COMP_CFGR1_PWRMODE_0) /*!< COMP power mode to medium speed */ +#define LL_COMP_POWERMODE_ULTRALOWPOWER (COMP_CFGR1_PWRMODE_1 |\ + COMP_CFGR1_PWRMODE_0) /*!< COMP power mode to ultra-low power */ +/** + * @} + */ + +/** @defgroup COMP_LL_EC_INPUT_PLUS Comparator inputs - Input plus (input non-inverting) selection + * @{ + */ +#define LL_COMP_INPUT_PLUS_IO1 (0x00000000UL) /*!< Comparator input plus connected to IO1 (pin PB0) */ +#define LL_COMP_INPUT_PLUS_IO2 (COMP_CFGR2_INPSEL0) /*!< Comparator input plus connected to IO2 (pin PA0) */ +#define LL_COMP_INPUT_PLUS_IO3 (COMP_CFGR1_INPSEL1) /*!< Comparator input plus connected to IO3 (pin PB2) */ +#define LL_COMP_INPUT_PLUS_DAC1_CH1 (COMP_CFGR1_INPSEL2) /*!< Comparator input plus connected to DAC1 channel 1 */ +/** + * @} + */ + +/** @defgroup COMP_LL_EC_INPUT_MINUS Comparator inputs - Input minus (input inverting) selection + * @{ + */ +#define LL_COMP_INPUT_MINUS_1_4VREFINT (COMP_CFGR1_SCALEN |\ + COMP_CFGR1_BRGEN) /*!< Comparator input minus connected to 1/4 VrefInt */ +#define LL_COMP_INPUT_MINUS_1_2VREFINT (COMP_CFGR1_INMSEL_0 |\ + COMP_CFGR1_SCALEN |\ + COMP_CFGR1_BRGEN) /*!< Comparator input minus connected to 1/2 VrefInt */ +#define LL_COMP_INPUT_MINUS_3_4VREFINT (COMP_CFGR1_INMSEL_1 |\ + COMP_CFGR1_SCALEN |\ + COMP_CFGR1_BRGEN) /*!< Comparator input minus connected to 3/4 VrefInt */ +#define LL_COMP_INPUT_MINUS_VREFINT (COMP_CFGR1_INMSEL_1 |\ + COMP_CFGR1_INMSEL_0 |\ + COMP_CFGR1_SCALEN) /*!< Comparator input minus connected to VrefInt */ +#define LL_COMP_INPUT_MINUS_DAC1_CH1 (COMP_CFGR1_INMSEL_2) /*!< Comparator input minus connected to DAC1 + channel 1 (DAC_OUT1) */ +#define LL_COMP_INPUT_MINUS_IO1 (COMP_CFGR1_INMSEL_2 |\ + COMP_CFGR1_INMSEL_0) /*!< Comparator input minus connected to pin PC4 */ +#define LL_COMP_INPUT_MINUS_IO2 (COMP_CFGR1_INMSEL_2 |\ + COMP_CFGR1_INMSEL_1) /*!< Comparator input minus connected to pin PB1 */ +#define LL_COMP_INPUT_MINUS_IO3 (COMP_CFGR1_INMSEL_2 |\ + COMP_CFGR1_INMSEL_1 |\ + COMP_CFGR1_INMSEL_0) /*!< Comparator input minus connected to pin PA5 */ +#define LL_COMP_INPUT_MINUS_TEMPSENSOR (COMP_CFGR1_INMSEL_3) /*!< Comparator input minus connected to internal + temperature sensor (also accessible through ADC peripheral) */ +#define LL_COMP_INPUT_MINUS_VBAT (COMP_CFGR1_INMSEL_3 |\ + COMP_CFGR1_INMSEL_0) /*!< Comparator input minus connected to Vbat/4: + Vbat voltage through a divider ladder of factor 1/4 to have input voltage + always below Vdda. */ + +/** + * @} + */ + +/** @defgroup COMP_LL_EC_INPUT_HYSTERESIS Comparator input - Hysteresis + * @{ + */ +#define LL_COMP_HYSTERESIS_NONE (0x00000000UL) /*!< No hysteresis */ +#define LL_COMP_HYSTERESIS_LOW (COMP_CFGR1_HYST_0) /*!< Hysteresis level low */ +#define LL_COMP_HYSTERESIS_MEDIUM (COMP_CFGR1_HYST_1) /*!< Hysteresis level medium */ +#define LL_COMP_HYSTERESIS_HIGH (COMP_CFGR1_HYST_1 | COMP_CFGR1_HYST_0) /*!< Hysteresis level high */ +/** + * @} + */ + +/** @defgroup COMP_LL_EC_OUTPUT_POLARITY Comparator output - Output polarity + * @{ + */ +#define LL_COMP_OUTPUTPOL_NONINVERTED (0x00000000UL) /*!< COMP output polarity is not inverted: comparator + output is high when the plus (non-inverting) input + is at a higher voltage than the + minus (inverting) input */ +#define LL_COMP_OUTPUTPOL_INVERTED (COMP_CFGR1_POLARITY) /*!< COMP output polarity is inverted: comparator output + is low when the plus (non-inverting) input is at a + lower voltage than the minus (inverting) input */ +/** + * @} + */ + +/** @defgroup COMP_LL_EC_OUTPUT_BLANKING_SOURCE Comparator output - Blanking source + * @{ + */ +#define LL_COMP_BLANKINGSRC_NONE ((uint32_t)0x00000000) /*!__REG__, (__VALUE__)) + +/** + * @brief Read a value in COMP register + * @param __INSTANCE__ comparator instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_COMP_ReadReg(__INSTANCE__, __REG__) READ_REG((__INSTANCE__)->__REG__) +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions ------------------------------------------------------------------------------------------------*/ +/** @defgroup COMP_LL_Exported_Functions COMP Exported Functions + * @{ + */ + +/** @defgroup COMP_LL_EF_Configuration_comparator_modes Configuration of comparator modes + * @{ + */ + +/** + * @brief Set comparator instance operating mode to adjust power and speed. + * @rmtoll CFGR1 PWRMODE LL_COMP_SetPowerMode + * @param COMPx Comparator instance + * @param PowerMode This parameter can be one of the following values: + * @arg @ref LL_COMP_POWERMODE_HIGHSPEED + * @arg @ref LL_COMP_POWERMODE_MEDIUMSPEED + * @arg @ref LL_COMP_POWERMODE_ULTRALOWPOWER + * @retval None + */ +__STATIC_INLINE void LL_COMP_SetPowerMode(COMP_TypeDef *COMPx, uint32_t PowerMode) +{ + MODIFY_REG(COMPx->CFGR1, COMP_CFGR1_PWRMODE, PowerMode); +} + +/** + * @brief Get comparator instance operating mode to adjust power and speed. + * @rmtoll CFGR1 PWRMODE LL_COMP_GetPowerMode + * @param COMPx Comparator instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_COMP_POWERMODE_HIGHSPEED + * @arg @ref LL_COMP_POWERMODE_MEDIUMSPEED + * @arg @ref LL_COMP_POWERMODE_ULTRALOWPOWER + */ +__STATIC_INLINE uint32_t LL_COMP_GetPowerMode(const COMP_TypeDef *COMPx) +{ + return (uint32_t)(READ_BIT(COMPx->CFGR1, COMP_CFGR1_PWRMODE)); +} + +/** + * @} + */ + +/** @defgroup COMP_LL_EF_Configuration_comparator_inputs Configuration of comparator inputs + * @{ + */ + +/** + * @brief Set comparator inputs minus (inverting) and plus (non-inverting). + * @note In case of comparator input selected to be connected to IO: + * GPIO pins are specific to each comparator instance. + * Refer to description of parameters or to reference manual. + * @note On this STM32 series, scaler bridge is configurable: + * to optimize power consumption, this function enables the + * voltage scaler bridge only when required + * (when selecting comparator input based on VrefInt: VrefInt or + * subdivision of VrefInt). + * - For scaler bridge power consumption values, + * refer to device datasheet, parameter "IDDA(SCALER)". + * - Voltage scaler requires a delay for voltage stabilization. + * Refer to device datasheet, parameter "tSTART_SCALER". + * - Scaler bridge is common for all comparator instances, + * therefore if at least one of the comparator instance + * is requiring the scaler bridge, it remains enabled. + * @rmtoll CFGR1 INMSEL LL_COMP_ConfigInputs\n + * CFGR1 INPSEL LL_COMP_ConfigInputs\n + * CFGR1 BRGEN LL_COMP_ConfigInputs\n + * CFGR1 SCALEN LL_COMP_ConfigInputs + * @param COMPx Comparator instance + * @param InputMinus This parameter can be one of the following values: + * @arg @ref LL_COMP_INPUT_MINUS_1_4VREFINT + * @arg @ref LL_COMP_INPUT_MINUS_1_2VREFINT + * @arg @ref LL_COMP_INPUT_MINUS_3_4VREFINT + * @arg @ref LL_COMP_INPUT_MINUS_VREFINT + * @arg @ref LL_COMP_INPUT_MINUS_DAC1_CH1 + * @arg @ref LL_COMP_INPUT_MINUS_DAC1_CH2 + * @arg @ref LL_COMP_INPUT_MINUS_IO1 + * @arg @ref LL_COMP_INPUT_MINUS_IO2 + * @arg @ref LL_COMP_INPUT_MINUS_IO3 + * @arg @ref LL_COMP_INPUT_MINUS_TEMPSENSOR + * @arg @ref LL_COMP_INPUT_MINUS_VBAT + * @param InputPlus This parameter can be one of the following values: + * @arg @ref LL_COMP_INPUT_PLUS_IO1 + * @arg @ref LL_COMP_INPUT_PLUS_IO2 + * @arg @ref LL_COMP_INPUT_PLUS_IO3 + * @arg @ref LL_COMP_INPUT_PLUS_DAC1_CH1 + * @retval None + */ +__STATIC_INLINE void LL_COMP_ConfigInputs(COMP_TypeDef *COMPx, uint32_t InputMinus, uint32_t InputPlus) +{ + MODIFY_REG(COMPx->CFGR2, COMP_CFGR2_INPSEL0, ((InputPlus == LL_COMP_INPUT_PLUS_IO2) ? COMP_CFGR2_INPSEL0 : 0U)); + + MODIFY_REG(COMPx->CFGR1, + COMP_CFGR1_INMSEL | COMP_CFGR1_INPSEL1 | COMP_CFGR1_INPSEL2 | COMP_CFGR1_SCALEN | COMP_CFGR1_BRGEN, + InputMinus | InputPlus); +} + +/** + * @brief Set comparator input plus (non-inverting). + * @note In case of comparator input selected to be connected to IO: + * GPIO pins are specific to each comparator instance. + * Refer to description of parameters or to reference manual. + * @rmtoll CFGR1 INPSEL LL_COMP_SetInputPlus + * @param COMPx Comparator instance + * @param InputPlus This parameter can be one of the following values: + * @arg @ref LL_COMP_INPUT_PLUS_IO1 + * @arg @ref LL_COMP_INPUT_PLUS_IO2 + * @arg @ref LL_COMP_INPUT_PLUS_IO3 + * @arg @ref LL_COMP_INPUT_PLUS_DAC1_CH1 + * @retval None + */ +__STATIC_INLINE void LL_COMP_SetInputPlus(COMP_TypeDef *COMPx, uint32_t InputPlus) +{ + MODIFY_REG(COMPx->CFGR2, COMP_CFGR2_INPSEL0, ((InputPlus == LL_COMP_INPUT_PLUS_IO2) ? COMP_CFGR2_INPSEL0 : 0U)); + MODIFY_REG(COMPx->CFGR1, COMP_CFGR1_INPSEL1 | COMP_CFGR1_INPSEL2, InputPlus); +} + +/** + * @brief Get comparator input plus (non-inverting). + * @note In case of comparator input selected to be connected to IO: + * GPIO pins are specific to each comparator instance. + * Refer to description of parameters or to reference manual. + * @rmtoll CFGR1 INPSEL LL_COMP_GetInputPlus + * @param COMPx Comparator instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_COMP_INPUT_PLUS_IO1 + * @arg @ref LL_COMP_INPUT_PLUS_IO2 + * @arg @ref LL_COMP_INPUT_PLUS_IO3 + * @arg @ref LL_COMP_INPUT_PLUS_DAC1_CH1 + */ +__STATIC_INLINE uint32_t LL_COMP_GetInputPlus(const COMP_TypeDef *COMPx) +{ + uint32_t val; + val = (uint32_t)(READ_BIT(COMPx->CFGR1, COMP_CFGR1_INPSEL1 | COMP_CFGR1_INPSEL2)); + val |= (uint32_t)(READ_BIT(COMPx->CFGR2, COMP_CFGR2_INPSEL0)); + + return val; +} + +/** + * @brief Set comparator input minus (inverting). + * @note In case of comparator input selected to be connected to IO: + * GPIO pins are specific to each comparator instance. + * Refer to description of parameters or to reference manual. + * @note On this STM32 series, scaler bridge is configurable: + * to optimize power consumption, this function enables the + * voltage scaler bridge only when required + * (when selecting comparator input based on VrefInt: VrefInt or + * subdivision of VrefInt). + * - For scaler bridge power consumption values, + * refer to device datasheet, parameter "IDDA(SCALER)". + * - Voltage scaler requires a delay for voltage stabilization. + * Refer to device datasheet, parameter "tSTART_SCALER". + * - Scaler bridge is common for all comparator instances, + * therefore if at least one of the comparator instance + * is requiring the scaler bridge, it remains enabled. + * @rmtoll CFGR1 INMSEL LL_COMP_SetInputMinus\n + * CFGR1 BRGEN LL_COMP_SetInputMinus\n + * CFGR1 SCALEN LL_COMP_SetInputMinus + * @param COMPx Comparator instance + * @param InputMinus This parameter can be one of the following values: + * @arg @ref LL_COMP_INPUT_MINUS_1_4VREFINT + * @arg @ref LL_COMP_INPUT_MINUS_1_2VREFINT + * @arg @ref LL_COMP_INPUT_MINUS_3_4VREFINT + * @arg @ref LL_COMP_INPUT_MINUS_VREFINT + * @arg @ref LL_COMP_INPUT_MINUS_DAC1_CH1 + * @arg @ref LL_COMP_INPUT_MINUS_IO1 + * @arg @ref LL_COMP_INPUT_MINUS_IO2 + * @arg @ref LL_COMP_INPUT_MINUS_IO3 + * @arg @ref LL_COMP_INPUT_MINUS_TEMPSENSOR + * @arg @ref LL_COMP_INPUT_MINUS_VBAT + * @retval None + */ +__STATIC_INLINE void LL_COMP_SetInputMinus(COMP_TypeDef *COMPx, uint32_t InputMinus) +{ + MODIFY_REG(COMPx->CFGR1, COMP_CFGR1_INMSEL | COMP_CFGR1_SCALEN | COMP_CFGR1_BRGEN, InputMinus); +} + +/** + * @brief Get comparator input minus (inverting). + * @note In case of comparator input selected to be connected to IO: + * GPIO pins are specific to each comparator instance. + * Refer to description of parameters or to reference manual. + * @rmtoll CFGR1 INMSEL LL_COMP_GetInputMinus\n + * CFGR1 BRGEN LL_COMP_GetInputMinus\n + * CFGR1 SCALEN LL_COMP_GetInputMinus + * @param COMPx Comparator instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_COMP_INPUT_MINUS_1_4VREFINT + * @arg @ref LL_COMP_INPUT_MINUS_1_2VREFINT + * @arg @ref LL_COMP_INPUT_MINUS_3_4VREFINT + * @arg @ref LL_COMP_INPUT_MINUS_VREFINT + * @arg @ref LL_COMP_INPUT_MINUS_DAC1_CH1 + * @arg @ref LL_COMP_INPUT_MINUS_IO1 + * @arg @ref LL_COMP_INPUT_MINUS_IO2 + * @arg @ref LL_COMP_INPUT_MINUS_IO3 + * @arg @ref LL_COMP_INPUT_MINUS_TEMPSENSOR + * @arg @ref LL_COMP_INPUT_MINUS_VBAT + */ +__STATIC_INLINE uint32_t LL_COMP_GetInputMinus(const COMP_TypeDef *COMPx) +{ + return (uint32_t)(READ_BIT(COMPx->CFGR1, COMP_CFGR1_INMSEL | COMP_CFGR1_SCALEN | COMP_CFGR1_BRGEN)); +} + +/** + * @brief Set comparator instance hysteresis mode of the input minus (inverting input). + * @rmtoll CFGR1 HYST LL_COMP_SetInputHysteresis + * @param COMPx Comparator instance + * @param InputHysteresis This parameter can be one of the following values: + * @arg @ref LL_COMP_HYSTERESIS_NONE + * @arg @ref LL_COMP_HYSTERESIS_LOW + * @arg @ref LL_COMP_HYSTERESIS_MEDIUM + * @arg @ref LL_COMP_HYSTERESIS_HIGH + * @retval None + */ +__STATIC_INLINE void LL_COMP_SetInputHysteresis(COMP_TypeDef *COMPx, uint32_t InputHysteresis) +{ + MODIFY_REG(COMPx->CFGR1, COMP_CFGR1_HYST, InputHysteresis); +} + +/** + * @brief Get comparator instance hysteresis mode of the minus (inverting) input. + * @rmtoll CSR HYST LL_COMP_GetInputHysteresis + * @param COMPx Comparator instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_COMP_HYSTERESIS_NONE + * @arg @ref LL_COMP_HYSTERESIS_LOW + * @arg @ref LL_COMP_HYSTERESIS_MEDIUM + * @arg @ref LL_COMP_HYSTERESIS_HIGH + */ +__STATIC_INLINE uint32_t LL_COMP_GetInputHysteresis(const COMP_TypeDef *COMPx) +{ + return (uint32_t)(READ_BIT(COMPx->CFGR1, COMP_CFGR1_HYST)); +} + +/** + * @} + */ + +/** @defgroup COMP_LL_EF_Configuration_comparator_output Configuration of comparator output + * @{ + */ + +/** + * @brief Set comparator instance output polarity. + * @rmtoll CFGR1 POLARITY LL_COMP_SetOutputPolarity + * @param COMPx Comparator instance + * @param OutputPolarity This parameter can be one of the following values: + * @arg @ref LL_COMP_OUTPUTPOL_NONINVERTED + * @arg @ref LL_COMP_OUTPUTPOL_INVERTED + * @retval None + */ +__STATIC_INLINE void LL_COMP_SetOutputPolarity(COMP_TypeDef *COMPx, uint32_t OutputPolarity) +{ + MODIFY_REG(COMPx->CFGR1, COMP_CFGR1_POLARITY, OutputPolarity); +} + +/** + * @brief Get comparator instance output polarity. + * @rmtoll CFGR1 POLARITY LL_COMP_GetOutputPolarity + * @param COMPx Comparator instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_COMP_OUTPUTPOL_NONINVERTED + * @arg @ref LL_COMP_OUTPUTPOL_INVERTED + */ +__STATIC_INLINE uint32_t LL_COMP_GetOutputPolarity(const COMP_TypeDef *COMPx) +{ + return (uint32_t)(READ_BIT(COMPx->CFGR1, COMP_CFGR1_POLARITY)); +} + +/** + * @brief Set comparator instance blanking source. + * @note Blanking source may be specific to each comparator instance. + * Refer to description of parameters or to reference manual. + * @note Availability of parameters of blanking source from timer + * depends on timers availability on the selected device. + * @rmtoll CFGR BLANKING LL_COMP_SetOutputBlankingSource + * @param COMPx Comparator instance + * @param BlankingSource This parameter can be one of the following values: + * @arg @ref LL_COMP_BLANKINGSRC_NONE + * @arg @ref LL_COMP_BLANKINGSRC_TIM1_OC5 + * @arg @ref LL_COMP_BLANKINGSRC_TIM2_OC3 + * @arg @ref LL_COMP_BLANKINGSRC_TIM3_OC3 + * @arg @ref LL_COMP_BLANKINGSRC_TIM3_OC4 + * @arg @ref LL_COMP_BLANKINGSRC_LPTIM1_OC2 + * @arg @ref LL_COMP_BLANKINGSRC_LPTIM2_OC2 + * @retval None + */ +__STATIC_INLINE void LL_COMP_SetOutputBlankingSource(COMP_TypeDef *COMPx, uint32_t BlankingSource) +{ + MODIFY_REG(COMPx->CFGR1, COMP_CFGR1_BLANKING, BlankingSource); +} + +/** + * @brief Get comparator instance blanking source. + * @note Availability of parameters of blanking source from timer + * depends on timers availability on the selected device. + * @note Blanking source may be specific to each comparator instance. + * Refer to description of parameters or to reference manual. + * @rmtoll CFGR BLANKING LL_COMP_GetOutputBlankingSource + * @param COMPx Comparator instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_COMP_BLANKINGSRC_NONE + * @arg @ref LL_COMP_BLANKINGSRC_TIM1_OC5 + * @arg @ref LL_COMP_BLANKINGSRC_TIM2_OC3 + * @arg @ref LL_COMP_BLANKINGSRC_TIM3_OC3 + * @arg @ref LL_COMP_BLANKINGSRC_TIM3_OC4 + * @arg @ref LL_COMP_BLANKINGSRC_LPTIM1_OC2 + * @arg @ref LL_COMP_BLANKINGSRC_LPTIM2_OC2 + */ +__STATIC_INLINE uint32_t LL_COMP_GetOutputBlankingSource(const COMP_TypeDef *COMPx) +{ + return (uint32_t)(READ_BIT(COMPx->CFGR1, COMP_CFGR1_BLANKING)); +} + +/** + * @} + */ + +/** @defgroup COMP_LL_EF_Operation Operation on comparator instance + * @{ + */ + +/** + * @brief Enable comparator instance. + * @note After enable from off state, comparator requires a delay + * to reach reach propagation delay specification. + * Refer to device datasheet, parameter "tSTART". + * @rmtoll CFGR1 EN LL_COMP_Enable + * @param COMPx Comparator instance + * @retval None + */ +__STATIC_INLINE void LL_COMP_Enable(COMP_TypeDef *COMPx) +{ + SET_BIT(COMPx->CFGR1, COMP_CFGR1_EN); +} + +/** + * @brief Disable comparator instance. + * @rmtoll CFGR1 EN LL_COMP_Disable + * @param COMPx Comparator instance + * @retval None + */ +__STATIC_INLINE void LL_COMP_Disable(COMP_TypeDef *COMPx) +{ + CLEAR_BIT(COMPx->CFGR1, COMP_CFGR1_EN); +} + +/** + * @brief Get comparator enable state + * (0: COMP is disabled, 1: COMP is enabled) + * @rmtoll CFGR1 EN LL_COMP_IsEnabled + * @param COMPx Comparator instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_COMP_IsEnabled(const COMP_TypeDef *COMPx) +{ + return ((READ_BIT(COMPx->CFGR1, COMP_CFGR1_EN) == (COMP_CFGR1_EN)) ? 1UL : 0UL); +} + +/** + * @brief Lock comparator instance. + * @note Once locked, comparator configuration can be accessed in read-only. + * @note The only way to unlock the comparator is a device hardware reset. + * @rmtoll CFGR1 LOCK LL_COMP_Lock + * @param COMPx Comparator instance + * @retval None + */ +__STATIC_INLINE void LL_COMP_Lock(COMP_TypeDef *COMPx) +{ + SET_BIT(COMPx->CFGR1, COMP_CFGR1_LOCK); +} + +/** + * @brief Get comparator lock state + * (0: COMP is unlocked, 1: COMP is locked). + * @note Once locked, comparator configuration can be accessed in read-only. + * @note The only way to unlock the comparator is a device hardware reset. + * @rmtoll CFGR1 LOCK LL_COMP_IsLocked + * @param COMPx Comparator instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_COMP_IsLocked(const COMP_TypeDef *COMPx) +{ + return ((READ_BIT(COMPx->CFGR1, COMP_CFGR1_LOCK) == (COMP_CFGR1_LOCK)) ? 1UL : 0UL); +} + +/** + * @brief Read comparator instance output level. + * @note The comparator output level depends on the selected polarity + * (Refer to function @ref LL_COMP_SetOutputPolarity()). + * If the comparator polarity is not inverted: + * - Comparator output is low when the input plus + * is at a lower voltage than the input minus + * - Comparator output is high when the input plus + * is at a higher voltage than the input minus + * If the comparator polarity is inverted: + * - Comparator output is high when the input plus + * is at a lower voltage than the input minus + * - Comparator output is low when the input plus + * is at a higher voltage than the input minus + * @rmtoll CFGR VALUE LL_COMP_ReadOutputLevel + * @param COMPx Comparator instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_COMP_OUTPUT_LEVEL_LOW + * @arg @ref LL_COMP_OUTPUT_LEVEL_HIGH + */ +__STATIC_INLINE uint32_t LL_COMP_ReadOutputLevel(const COMP_TypeDef *COMPx) +{ + return (uint32_t)(READ_BIT(COMPx->SR, COMP_SR_C1VAL)); +} + +/** + * @} + */ + +/** @defgroup COMP_LL_EF_FLAG_Management Comparator flag Management + * @{ + */ + +/** + * @brief Get comparator output trigger flag (latched) + * @rmtoll SR C1IF LL_COMP_IsActiveFlag_OutputTrig + * @param COMPx Comparator instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_COMP_IsActiveFlag_OutputTrig(const COMP_TypeDef *COMPx) +{ + return ((READ_BIT(COMPx->SR, COMP_SR_C1IF) == (COMP_SR_C1IF)) ? 1UL : 0UL); +} + +/** + * @brief Clear comparator comparator output trigger flag (latched) + * @rmtoll ICFR CC1IF LL_COMP_ClearFlag_OutputTrig + * @param COMPx Comparator instance + * @retval None + */ +__STATIC_INLINE void LL_COMP_ClearFlag_OutputTrig(COMP_TypeDef *COMPx) +{ + SET_BIT(COMPx->ICFR, COMP_ICFR_CC1IF); +} + +/** + * @} + */ + +/** @defgroup COMP_LL_EF_IT_Management Comparartor IT management + * @{ + */ + +/** + * @brief Enable comparator output trigger interrupt + * @rmtoll ICFR ITEN LL_COMP_EnableIT_OutputTrig + * @param COMPx Comparator instance + * @retval None + */ +__STATIC_INLINE void LL_COMP_EnableIT_OutputTrig(COMP_TypeDef *COMPx) +{ + SET_BIT(COMPx->CFGR1, COMP_CFGR1_ITEN); +} + +/** + * @brief Disable comparator output trigger interrupt + * @rmtoll ICFR ITEN LL_COMP_DisableIT_OutputTrig + * @param COMPx Comparator instance + * @retval None + */ +__STATIC_INLINE void LL_COMP_DisableIT_OutputTrig(COMP_TypeDef *COMPx) +{ + CLEAR_BIT(COMPx->CFGR1, COMP_CFGR1_ITEN); +} + +/** + * @brief Get comparator output trigger interrupt state + * @rmtoll ICFR ITEN LL_COMP_IsEnabledIT_OutputTrig + * @param COMPx Comparator instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_COMP_IsEnabledIT_OutputTrig(const COMP_TypeDef *COMPx) +{ + return ((READ_BIT(COMPx->CFGR1, COMP_CFGR1_ITEN) == (COMP_CFGR1_ITEN)) ? 1UL : 0UL); +} + +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup COMP_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +ErrorStatus LL_COMP_DeInit(COMP_TypeDef *COMPx); +ErrorStatus LL_COMP_Init(COMP_TypeDef *COMPx, const LL_COMP_InitTypeDef *COMP_InitStruct); +void LL_COMP_StructInit(LL_COMP_InitTypeDef *COMP_InitStruct); + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* COMP1 */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32H5xx_LL_COMP_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_cordic.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_cordic.h new file mode 100644 index 0000000000..d7a99d3eeb --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_cordic.h @@ -0,0 +1,783 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_cordic.h + * @author MCD Application Team + * @brief Header file of CORDIC LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_LL_CORDIC_H +#define STM32H5xx_LL_CORDIC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined(CORDIC) + +/** @defgroup CORDIC_LL CORDIC + * @{ + */ + +/* Private variables ---------------------------------------------------------*/ + +/* Private constants ---------------------------------------------------------*/ + +/* Private macros ------------------------------------------------------------*/ + +/* Exported types ------------------------------------------------------------*/ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup CORDIC_LL_Exported_Constants CORDIC Exported Constants + * @{ + */ + +/** @defgroup CORDIC_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_CORDIC_ReadReg function. + * @{ + */ +#define LL_CORDIC_FLAG_RRDY CORDIC_CSR_RRDY +/** + * @} + */ + +/** @defgroup CORDIC_LL_EC_IT IT Defines + * @brief IT defines which can be used with LL_CORDIC_ReadReg and LL_CORDIC_WriteReg functions. + * @{ + */ +#define LL_CORDIC_IT_IEN CORDIC_CSR_IEN /*!< Result Ready interrupt enable */ +/** + * @} + */ + +/** @defgroup CORDIC_LL_EC_FUNCTION FUNCTION + * @{ + */ +#define LL_CORDIC_FUNCTION_COSINE (0x00000000U) /*!< Cosine */ +#define LL_CORDIC_FUNCTION_SINE ((uint32_t)(CORDIC_CSR_FUNC_0)) /*!< Sine */ +#define LL_CORDIC_FUNCTION_PHASE ((uint32_t)(CORDIC_CSR_FUNC_1)) /*!< Phase */ +#define LL_CORDIC_FUNCTION_MODULUS ((uint32_t)(CORDIC_CSR_FUNC_1 | CORDIC_CSR_FUNC_0)) /*!< Modulus */ +#define LL_CORDIC_FUNCTION_ARCTANGENT ((uint32_t)(CORDIC_CSR_FUNC_2)) /*!< Arctangent */ +#define LL_CORDIC_FUNCTION_HCOSINE ((uint32_t)(CORDIC_CSR_FUNC_2 | CORDIC_CSR_FUNC_0)) /*!< Hyperbolic Cosine */ +#define LL_CORDIC_FUNCTION_HSINE ((uint32_t)(CORDIC_CSR_FUNC_2 | CORDIC_CSR_FUNC_1)) /*!< Hyperbolic Sine */ +#define LL_CORDIC_FUNCTION_HARCTANGENT ((uint32_t)(CORDIC_CSR_FUNC_2 | CORDIC_CSR_FUNC_1 | CORDIC_CSR_FUNC_0))/*!< Hyperbolic Arctangent */ +#define LL_CORDIC_FUNCTION_NATURALLOG ((uint32_t)(CORDIC_CSR_FUNC_3)) /*!< Natural Logarithm */ +#define LL_CORDIC_FUNCTION_SQUAREROOT ((uint32_t)(CORDIC_CSR_FUNC_3 | CORDIC_CSR_FUNC_0)) /*!< Square Root */ +/** + * @} + */ + +/** @defgroup CORDIC_LL_EC_PRECISION PRECISION + * @{ + */ +#define LL_CORDIC_PRECISION_1CYCLE ((uint32_t)(CORDIC_CSR_PRECISION_0)) +#define LL_CORDIC_PRECISION_2CYCLES ((uint32_t)(CORDIC_CSR_PRECISION_1)) +#define LL_CORDIC_PRECISION_3CYCLES ((uint32_t)(CORDIC_CSR_PRECISION_1 | CORDIC_CSR_PRECISION_0)) +#define LL_CORDIC_PRECISION_4CYCLES ((uint32_t)(CORDIC_CSR_PRECISION_2)) +#define LL_CORDIC_PRECISION_5CYCLES ((uint32_t)(CORDIC_CSR_PRECISION_2 | CORDIC_CSR_PRECISION_0)) +#define LL_CORDIC_PRECISION_6CYCLES ((uint32_t)(CORDIC_CSR_PRECISION_2 | CORDIC_CSR_PRECISION_1)) +#define LL_CORDIC_PRECISION_7CYCLES ((uint32_t)(CORDIC_CSR_PRECISION_2\ + | CORDIC_CSR_PRECISION_1 | CORDIC_CSR_PRECISION_0)) +#define LL_CORDIC_PRECISION_8CYCLES ((uint32_t)(CORDIC_CSR_PRECISION_3)) +#define LL_CORDIC_PRECISION_9CYCLES ((uint32_t)(CORDIC_CSR_PRECISION_3 | CORDIC_CSR_PRECISION_0)) +#define LL_CORDIC_PRECISION_10CYCLES ((uint32_t)(CORDIC_CSR_PRECISION_3 | CORDIC_CSR_PRECISION_1)) +#define LL_CORDIC_PRECISION_11CYCLES ((uint32_t)(CORDIC_CSR_PRECISION_3\ + | CORDIC_CSR_PRECISION_1 | CORDIC_CSR_PRECISION_0)) +#define LL_CORDIC_PRECISION_12CYCLES ((uint32_t)(CORDIC_CSR_PRECISION_3 | CORDIC_CSR_PRECISION_2)) +#define LL_CORDIC_PRECISION_13CYCLES ((uint32_t)(CORDIC_CSR_PRECISION_3\ + | CORDIC_CSR_PRECISION_2 | CORDIC_CSR_PRECISION_0)) +#define LL_CORDIC_PRECISION_14CYCLES ((uint32_t)(CORDIC_CSR_PRECISION_3\ + | CORDIC_CSR_PRECISION_2 | CORDIC_CSR_PRECISION_1)) +#define LL_CORDIC_PRECISION_15CYCLES ((uint32_t)(CORDIC_CSR_PRECISION_3\ + | CORDIC_CSR_PRECISION_2 | CORDIC_CSR_PRECISION_1\ + | CORDIC_CSR_PRECISION_0)) +/** + * @} + */ + +/** @defgroup CORDIC_LL_EC_SCALE SCALE + * @{ + */ +#define LL_CORDIC_SCALE_0 (0x00000000U) +#define LL_CORDIC_SCALE_1 ((uint32_t)(CORDIC_CSR_SCALE_0)) +#define LL_CORDIC_SCALE_2 ((uint32_t)(CORDIC_CSR_SCALE_1)) +#define LL_CORDIC_SCALE_3 ((uint32_t)(CORDIC_CSR_SCALE_1 | CORDIC_CSR_SCALE_0)) +#define LL_CORDIC_SCALE_4 ((uint32_t)(CORDIC_CSR_SCALE_2)) +#define LL_CORDIC_SCALE_5 ((uint32_t)(CORDIC_CSR_SCALE_2 | CORDIC_CSR_SCALE_0)) +#define LL_CORDIC_SCALE_6 ((uint32_t)(CORDIC_CSR_SCALE_2 | CORDIC_CSR_SCALE_1)) +#define LL_CORDIC_SCALE_7 ((uint32_t)(CORDIC_CSR_SCALE_2 | CORDIC_CSR_SCALE_1 | CORDIC_CSR_SCALE_0)) +/** + * @} + */ + +/** @defgroup CORDIC_LL_EC_NBWRITE NBWRITE + * @{ + */ +#define LL_CORDIC_NBWRITE_1 (0x00000000U) /*!< One 32-bits write containing either only one + 32-bit data input (Q1.31 format), or two + 16-bit data input (Q1.15 format) packed + in one 32 bits Data */ +#define LL_CORDIC_NBWRITE_2 CORDIC_CSR_NARGS /*!< Two 32-bit write containing two 32-bits data input + (Q1.31 format) */ +/** + * @} + */ + +/** @defgroup CORDIC_LL_EC_NBREAD NBREAD + * @{ + */ +#define LL_CORDIC_NBREAD_1 (0x00000000U) /*!< One 32-bits read containing either only one + 32-bit data output (Q1.31 format), or two + 16-bit data output (Q1.15 format) packed + in one 32 bits Data */ +#define LL_CORDIC_NBREAD_2 CORDIC_CSR_NRES /*!< Two 32-bit Data containing two 32-bits data output + (Q1.31 format) */ +/** + * @} + */ + +/** @defgroup CORDIC_LL_EC_INSIZE INSIZE + * @{ + */ +#define LL_CORDIC_INSIZE_32BITS (0x00000000U) /*!< 32 bits input data size (Q1.31 format) */ +#define LL_CORDIC_INSIZE_16BITS CORDIC_CSR_ARGSIZE /*!< 16 bits input data size (Q1.15 format) */ +/** + * @} + */ + +/** @defgroup CORDIC_LL_EC_OUTSIZE OUTSIZE + * @{ + */ +#define LL_CORDIC_OUTSIZE_32BITS (0x00000000U) /*!< 32 bits output data size (Q1.31 format) */ +#define LL_CORDIC_OUTSIZE_16BITS CORDIC_CSR_RESSIZE /*!< 16 bits output data size (Q1.15 format) */ +/** + * @} + */ + +/** @defgroup CORDIC_LL_EC_DMA_REG_DATA DMA register data + * @{ + */ +#define LL_CORDIC_DMA_REG_DATA_IN (0x00000000U) /*!< Get address of input data register */ +#define LL_CORDIC_DMA_REG_DATA_OUT (0x00000001U) /*!< Get address of output data register */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup CORDIC_LL_Exported_Macros CORDIC Exported Macros + * @{ + */ + +/** @defgroup CORDIC_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in CORDIC register. + * @param __INSTANCE__ CORDIC Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_CORDIC_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in CORDIC register. + * @param __INSTANCE__ CORDIC Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_CORDIC_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) +/** + * @} + */ + +/** + * @} + */ + + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup CORDIC_LL_Exported_Functions CORDIC Exported Functions + * @{ + */ + +/** @defgroup CORDIC_LL_EF_Configuration CORDIC Configuration functions + * @{ + */ + +/** + * @brief Configure the CORDIC processing. + * @note This function set all parameters of CORDIC processing. + * These parameters can also be set individually using + * dedicated functions: + * - @ref LL_CORDIC_SetFunction() + * - @ref LL_CORDIC_SetPrecision() + * - @ref LL_CORDIC_SetScale() + * - @ref LL_CORDIC_SetNbWrite() + * - @ref LL_CORDIC_SetNbRead() + * - @ref LL_CORDIC_SetInSize() + * - @ref LL_CORDIC_SetOutSize() + * @rmtoll CSR FUNC LL_CORDIC_Config\n + * CSR PRECISION LL_CORDIC_Config\n + * CSR SCALE LL_CORDIC_Config\n + * CSR NARGS LL_CORDIC_Config\n + * CSR NRES LL_CORDIC_Config\n + * CSR ARGSIZE LL_CORDIC_Config\n + * CSR RESIZE LL_CORDIC_Config + * @param CORDICx CORDIC instance + * @param Function parameter can be one of the following values: + * @arg @ref LL_CORDIC_FUNCTION_COSINE + * @arg @ref LL_CORDIC_FUNCTION_SINE + * @arg @ref LL_CORDIC_FUNCTION_PHASE + * @arg @ref LL_CORDIC_FUNCTION_MODULUS + * @arg @ref LL_CORDIC_FUNCTION_ARCTANGENT + * @arg @ref LL_CORDIC_FUNCTION_HCOSINE + * @arg @ref LL_CORDIC_FUNCTION_HSINE + * @arg @ref LL_CORDIC_FUNCTION_HARCTANGENT + * @arg @ref LL_CORDIC_FUNCTION_NATURALLOG + * @arg @ref LL_CORDIC_FUNCTION_SQUAREROOT + * @param Precision parameter can be one of the following values: + * @arg @ref LL_CORDIC_PRECISION_1CYCLE + * @arg @ref LL_CORDIC_PRECISION_2CYCLES + * @arg @ref LL_CORDIC_PRECISION_3CYCLES + * @arg @ref LL_CORDIC_PRECISION_4CYCLES + * @arg @ref LL_CORDIC_PRECISION_5CYCLES + * @arg @ref LL_CORDIC_PRECISION_6CYCLES + * @arg @ref LL_CORDIC_PRECISION_7CYCLES + * @arg @ref LL_CORDIC_PRECISION_8CYCLES + * @arg @ref LL_CORDIC_PRECISION_9CYCLES + * @arg @ref LL_CORDIC_PRECISION_10CYCLES + * @arg @ref LL_CORDIC_PRECISION_11CYCLES + * @arg @ref LL_CORDIC_PRECISION_12CYCLES + * @arg @ref LL_CORDIC_PRECISION_13CYCLES + * @arg @ref LL_CORDIC_PRECISION_14CYCLES + * @arg @ref LL_CORDIC_PRECISION_15CYCLES + * @param Scale parameter can be one of the following values: + * @arg @ref LL_CORDIC_SCALE_0 + * @arg @ref LL_CORDIC_SCALE_1 + * @arg @ref LL_CORDIC_SCALE_2 + * @arg @ref LL_CORDIC_SCALE_3 + * @arg @ref LL_CORDIC_SCALE_4 + * @arg @ref LL_CORDIC_SCALE_5 + * @arg @ref LL_CORDIC_SCALE_6 + * @arg @ref LL_CORDIC_SCALE_7 + * @param NbWrite parameter can be one of the following values: + * @arg @ref LL_CORDIC_NBWRITE_1 + * @arg @ref LL_CORDIC_NBWRITE_2 + * @param NbRead parameter can be one of the following values: + * @arg @ref LL_CORDIC_NBREAD_1 + * @arg @ref LL_CORDIC_NBREAD_2 + * @param InSize parameter can be one of the following values: + * @arg @ref LL_CORDIC_INSIZE_32BITS + * @arg @ref LL_CORDIC_INSIZE_16BITS + * @param OutSize parameter can be one of the following values: + * @arg @ref LL_CORDIC_OUTSIZE_32BITS + * @arg @ref LL_CORDIC_OUTSIZE_16BITS + * @retval None + */ +__STATIC_INLINE void LL_CORDIC_Config(CORDIC_TypeDef *CORDICx, uint32_t Function, uint32_t Precision, uint32_t Scale, + uint32_t NbWrite, uint32_t NbRead, uint32_t InSize, uint32_t OutSize) +{ + MODIFY_REG(CORDICx->CSR, + CORDIC_CSR_FUNC | CORDIC_CSR_PRECISION | CORDIC_CSR_SCALE | + CORDIC_CSR_NARGS | CORDIC_CSR_NRES | CORDIC_CSR_ARGSIZE | CORDIC_CSR_RESSIZE, + Function | Precision | Scale | + NbWrite | NbRead | InSize | OutSize); +} + +/** + * @brief Configure function. + * @rmtoll CSR FUNC LL_CORDIC_SetFunction + * @param CORDICx CORDIC Instance + * @param Function parameter can be one of the following values: + * @arg @ref LL_CORDIC_FUNCTION_COSINE + * @arg @ref LL_CORDIC_FUNCTION_SINE + * @arg @ref LL_CORDIC_FUNCTION_PHASE + * @arg @ref LL_CORDIC_FUNCTION_MODULUS + * @arg @ref LL_CORDIC_FUNCTION_ARCTANGENT + * @arg @ref LL_CORDIC_FUNCTION_HCOSINE + * @arg @ref LL_CORDIC_FUNCTION_HSINE + * @arg @ref LL_CORDIC_FUNCTION_HARCTANGENT + * @arg @ref LL_CORDIC_FUNCTION_NATURALLOG + * @arg @ref LL_CORDIC_FUNCTION_SQUAREROOT + * @retval None + */ +__STATIC_INLINE void LL_CORDIC_SetFunction(CORDIC_TypeDef *CORDICx, uint32_t Function) +{ + MODIFY_REG(CORDICx->CSR, CORDIC_CSR_FUNC, Function); +} + +/** + * @brief Return function. + * @rmtoll CSR FUNC LL_CORDIC_GetFunction + * @param CORDICx CORDIC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_CORDIC_FUNCTION_COSINE + * @arg @ref LL_CORDIC_FUNCTION_SINE + * @arg @ref LL_CORDIC_FUNCTION_PHASE + * @arg @ref LL_CORDIC_FUNCTION_MODULUS + * @arg @ref LL_CORDIC_FUNCTION_ARCTANGENT + * @arg @ref LL_CORDIC_FUNCTION_HCOSINE + * @arg @ref LL_CORDIC_FUNCTION_HSINE + * @arg @ref LL_CORDIC_FUNCTION_HARCTANGENT + * @arg @ref LL_CORDIC_FUNCTION_NATURALLOG + * @arg @ref LL_CORDIC_FUNCTION_SQUAREROOT + */ +__STATIC_INLINE uint32_t LL_CORDIC_GetFunction(const CORDIC_TypeDef *CORDICx) +{ + return (uint32_t)(READ_BIT(CORDICx->CSR, CORDIC_CSR_FUNC)); +} + +/** + * @brief Configure precision in cycles number. + * @rmtoll CSR PRECISION LL_CORDIC_SetPrecision + * @param CORDICx CORDIC Instance + * @param Precision parameter can be one of the following values: + * @arg @ref LL_CORDIC_PRECISION_1CYCLE + * @arg @ref LL_CORDIC_PRECISION_2CYCLES + * @arg @ref LL_CORDIC_PRECISION_3CYCLES + * @arg @ref LL_CORDIC_PRECISION_4CYCLES + * @arg @ref LL_CORDIC_PRECISION_5CYCLES + * @arg @ref LL_CORDIC_PRECISION_6CYCLES + * @arg @ref LL_CORDIC_PRECISION_7CYCLES + * @arg @ref LL_CORDIC_PRECISION_8CYCLES + * @arg @ref LL_CORDIC_PRECISION_9CYCLES + * @arg @ref LL_CORDIC_PRECISION_10CYCLES + * @arg @ref LL_CORDIC_PRECISION_11CYCLES + * @arg @ref LL_CORDIC_PRECISION_12CYCLES + * @arg @ref LL_CORDIC_PRECISION_13CYCLES + * @arg @ref LL_CORDIC_PRECISION_14CYCLES + * @arg @ref LL_CORDIC_PRECISION_15CYCLES + * @retval None + */ +__STATIC_INLINE void LL_CORDIC_SetPrecision(CORDIC_TypeDef *CORDICx, uint32_t Precision) +{ + MODIFY_REG(CORDICx->CSR, CORDIC_CSR_PRECISION, Precision); +} + +/** + * @brief Return precision in cycles number. + * @rmtoll CSR PRECISION LL_CORDIC_GetPrecision + * @param CORDICx CORDIC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_CORDIC_PRECISION_1CYCLE + * @arg @ref LL_CORDIC_PRECISION_2CYCLES + * @arg @ref LL_CORDIC_PRECISION_3CYCLES + * @arg @ref LL_CORDIC_PRECISION_4CYCLES + * @arg @ref LL_CORDIC_PRECISION_5CYCLES + * @arg @ref LL_CORDIC_PRECISION_6CYCLES + * @arg @ref LL_CORDIC_PRECISION_7CYCLES + * @arg @ref LL_CORDIC_PRECISION_8CYCLES + * @arg @ref LL_CORDIC_PRECISION_9CYCLES + * @arg @ref LL_CORDIC_PRECISION_10CYCLES + * @arg @ref LL_CORDIC_PRECISION_11CYCLES + * @arg @ref LL_CORDIC_PRECISION_12CYCLES + * @arg @ref LL_CORDIC_PRECISION_13CYCLES + * @arg @ref LL_CORDIC_PRECISION_14CYCLES + * @arg @ref LL_CORDIC_PRECISION_15CYCLES + */ +__STATIC_INLINE uint32_t LL_CORDIC_GetPrecision(const CORDIC_TypeDef *CORDICx) +{ + return (uint32_t)(READ_BIT(CORDICx->CSR, CORDIC_CSR_PRECISION)); +} + +/** + * @brief Configure scaling factor. + * @rmtoll CSR SCALE LL_CORDIC_SetScale + * @param CORDICx CORDIC Instance + * @param Scale parameter can be one of the following values: + * @arg @ref LL_CORDIC_SCALE_0 + * @arg @ref LL_CORDIC_SCALE_1 + * @arg @ref LL_CORDIC_SCALE_2 + * @arg @ref LL_CORDIC_SCALE_3 + * @arg @ref LL_CORDIC_SCALE_4 + * @arg @ref LL_CORDIC_SCALE_5 + * @arg @ref LL_CORDIC_SCALE_6 + * @arg @ref LL_CORDIC_SCALE_7 + * @retval None + */ +__STATIC_INLINE void LL_CORDIC_SetScale(CORDIC_TypeDef *CORDICx, uint32_t Scale) +{ + MODIFY_REG(CORDICx->CSR, CORDIC_CSR_SCALE, Scale); +} + +/** + * @brief Return scaling factor. + * @rmtoll CSR SCALE LL_CORDIC_GetScale + * @param CORDICx CORDIC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_CORDIC_SCALE_0 + * @arg @ref LL_CORDIC_SCALE_1 + * @arg @ref LL_CORDIC_SCALE_2 + * @arg @ref LL_CORDIC_SCALE_3 + * @arg @ref LL_CORDIC_SCALE_4 + * @arg @ref LL_CORDIC_SCALE_5 + * @arg @ref LL_CORDIC_SCALE_6 + * @arg @ref LL_CORDIC_SCALE_7 + */ +__STATIC_INLINE uint32_t LL_CORDIC_GetScale(const CORDIC_TypeDef *CORDICx) +{ + return (uint32_t)(READ_BIT(CORDICx->CSR, CORDIC_CSR_SCALE)); +} + +/** + * @brief Configure number of 32-bit write expected for one calculation. + * @rmtoll CSR NARGS LL_CORDIC_SetNbWrite + * @param CORDICx CORDIC Instance + * @param NbWrite parameter can be one of the following values: + * @arg @ref LL_CORDIC_NBWRITE_1 + * @arg @ref LL_CORDIC_NBWRITE_2 + * @retval None + */ +__STATIC_INLINE void LL_CORDIC_SetNbWrite(CORDIC_TypeDef *CORDICx, uint32_t NbWrite) +{ + MODIFY_REG(CORDICx->CSR, CORDIC_CSR_NARGS, NbWrite); +} + +/** + * @brief Return number of 32-bit write expected for one calculation. + * @rmtoll CSR NARGS LL_CORDIC_GetNbWrite + * @param CORDICx CORDIC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_CORDIC_NBWRITE_1 + * @arg @ref LL_CORDIC_NBWRITE_2 + */ +__STATIC_INLINE uint32_t LL_CORDIC_GetNbWrite(const CORDIC_TypeDef *CORDICx) +{ + return (uint32_t)(READ_BIT(CORDICx->CSR, CORDIC_CSR_NARGS)); +} + +/** + * @brief Configure number of 32-bit read expected after one calculation. + * @rmtoll CSR NRES LL_CORDIC_SetNbRead + * @param CORDICx CORDIC Instance + * @param NbRead parameter can be one of the following values: + * @arg @ref LL_CORDIC_NBREAD_1 + * @arg @ref LL_CORDIC_NBREAD_2 + * @retval None + */ +__STATIC_INLINE void LL_CORDIC_SetNbRead(CORDIC_TypeDef *CORDICx, uint32_t NbRead) +{ + MODIFY_REG(CORDICx->CSR, CORDIC_CSR_NRES, NbRead); +} + +/** + * @brief Return number of 32-bit read expected after one calculation. + * @rmtoll CSR NRES LL_CORDIC_GetNbRead + * @param CORDICx CORDIC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_CORDIC_NBREAD_1 + * @arg @ref LL_CORDIC_NBREAD_2 + */ +__STATIC_INLINE uint32_t LL_CORDIC_GetNbRead(const CORDIC_TypeDef *CORDICx) +{ + return (uint32_t)(READ_BIT(CORDICx->CSR, CORDIC_CSR_NRES)); +} + +/** + * @brief Configure width of input data. + * @rmtoll CSR ARGSIZE LL_CORDIC_SetInSize + * @param CORDICx CORDIC Instance + * @param InSize parameter can be one of the following values: + * @arg @ref LL_CORDIC_INSIZE_32BITS + * @arg @ref LL_CORDIC_INSIZE_16BITS + * @retval None + */ +__STATIC_INLINE void LL_CORDIC_SetInSize(CORDIC_TypeDef *CORDICx, uint32_t InSize) +{ + MODIFY_REG(CORDICx->CSR, CORDIC_CSR_ARGSIZE, InSize); +} + +/** + * @brief Return width of input data. + * @rmtoll CSR ARGSIZE LL_CORDIC_GetInSize + * @param CORDICx CORDIC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_CORDIC_INSIZE_32BITS + * @arg @ref LL_CORDIC_INSIZE_16BITS + */ +__STATIC_INLINE uint32_t LL_CORDIC_GetInSize(const CORDIC_TypeDef *CORDICx) +{ + return (uint32_t)(READ_BIT(CORDICx->CSR, CORDIC_CSR_ARGSIZE)); +} + +/** + * @brief Configure width of output data. + * @rmtoll CSR RESIZE LL_CORDIC_SetOutSize + * @param CORDICx CORDIC Instance + * @param OutSize parameter can be one of the following values: + * @arg @ref LL_CORDIC_OUTSIZE_32BITS + * @arg @ref LL_CORDIC_OUTSIZE_16BITS + * @retval None + */ +__STATIC_INLINE void LL_CORDIC_SetOutSize(CORDIC_TypeDef *CORDICx, uint32_t OutSize) +{ + MODIFY_REG(CORDICx->CSR, CORDIC_CSR_RESSIZE, OutSize); +} + +/** + * @brief Return width of output data. + * @rmtoll CSR RESIZE LL_CORDIC_GetOutSize + * @param CORDICx CORDIC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_CORDIC_OUTSIZE_32BITS + * @arg @ref LL_CORDIC_OUTSIZE_16BITS + */ +__STATIC_INLINE uint32_t LL_CORDIC_GetOutSize(const CORDIC_TypeDef *CORDICx) +{ + return (uint32_t)(READ_BIT(CORDICx->CSR, CORDIC_CSR_RESSIZE)); +} + +/** + * @} + */ + +/** @defgroup CORDIC_LL_EF_IT_Management IT_Management + * @{ + */ + +/** + * @brief Enable CORDIC result ready interrupt + * @rmtoll CSR IEN LL_CORDIC_EnableIT + * @param CORDICx CORDIC Instance + * @retval None + */ +__STATIC_INLINE void LL_CORDIC_EnableIT(CORDIC_TypeDef *CORDICx) +{ + SET_BIT(CORDICx->CSR, CORDIC_CSR_IEN); +} + +/** + * @brief Disable CORDIC result ready interrupt + * @rmtoll CSR IEN LL_CORDIC_DisableIT + * @param CORDICx CORDIC Instance + * @retval None + */ +__STATIC_INLINE void LL_CORDIC_DisableIT(CORDIC_TypeDef *CORDICx) +{ + CLEAR_BIT(CORDICx->CSR, CORDIC_CSR_IEN); +} + +/** + * @brief Check CORDIC result ready interrupt state. + * @rmtoll CSR IEN LL_CORDIC_IsEnabledIT + * @param CORDICx CORDIC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_CORDIC_IsEnabledIT(const CORDIC_TypeDef *CORDICx) +{ + return ((READ_BIT(CORDICx->CSR, CORDIC_CSR_IEN) == (CORDIC_CSR_IEN)) ? 1U : 0U); +} + +/** + * @} + */ + +/** @defgroup CORDIC_LL_EF_DMA_Management DMA_Management + * @{ + */ + +/** + * @brief Enable CORDIC DMA read channel request. + * @rmtoll CSR DMAREN LL_CORDIC_EnableDMAReq_RD + * @param CORDICx CORDIC Instance + * @retval None + */ +__STATIC_INLINE void LL_CORDIC_EnableDMAReq_RD(CORDIC_TypeDef *CORDICx) +{ + SET_BIT(CORDICx->CSR, CORDIC_CSR_DMAREN); +} + +/** + * @brief Disable CORDIC DMA read channel request. + * @rmtoll CSR DMAREN LL_CORDIC_DisableDMAReq_RD + * @param CORDICx CORDIC Instance + * @retval None + */ +__STATIC_INLINE void LL_CORDIC_DisableDMAReq_RD(CORDIC_TypeDef *CORDICx) +{ + CLEAR_BIT(CORDICx->CSR, CORDIC_CSR_DMAREN); +} + +/** + * @brief Check CORDIC DMA read channel request state. + * @rmtoll CSR DMAREN LL_CORDIC_IsEnabledDMAReq_RD + * @param CORDICx CORDIC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_CORDIC_IsEnabledDMAReq_RD(const CORDIC_TypeDef *CORDICx) +{ + return ((READ_BIT(CORDICx->CSR, CORDIC_CSR_DMAREN) == (CORDIC_CSR_DMAREN)) ? 1U : 0U); +} + +/** + * @brief Enable CORDIC DMA write channel request. + * @rmtoll CSR DMAWEN LL_CORDIC_EnableDMAReq_WR + * @param CORDICx CORDIC Instance + * @retval None + */ +__STATIC_INLINE void LL_CORDIC_EnableDMAReq_WR(CORDIC_TypeDef *CORDICx) +{ + SET_BIT(CORDICx->CSR, CORDIC_CSR_DMAWEN); +} + +/** + * @brief Disable CORDIC DMA write channel request. + * @rmtoll CSR DMAWEN LL_CORDIC_DisableDMAReq_WR + * @param CORDICx CORDIC Instance + * @retval None + */ +__STATIC_INLINE void LL_CORDIC_DisableDMAReq_WR(CORDIC_TypeDef *CORDICx) +{ + CLEAR_BIT(CORDICx->CSR, CORDIC_CSR_DMAWEN); +} + +/** + * @brief Check CORDIC DMA write channel request state. + * @rmtoll CSR DMAWEN LL_CORDIC_IsEnabledDMAReq_WR + * @param CORDICx CORDIC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_CORDIC_IsEnabledDMAReq_WR(const CORDIC_TypeDef *CORDICx) +{ + return ((READ_BIT(CORDICx->CSR, CORDIC_CSR_DMAWEN) == (CORDIC_CSR_DMAWEN)) ? 1U : 0U); +} + +/** + * @brief Get the CORDIC data register address used for DMA transfer. + * @rmtoll RDATA RES LL_CORDIC_DMA_GetRegAddr\n + * @rmtoll WDATA ARG LL_CORDIC_DMA_GetRegAddr + * @param CORDICx CORDIC Instance + * @param Direction parameter can be one of the following values: + * @arg @ref LL_CORDIC_DMA_REG_DATA_IN + * @arg @ref LL_CORDIC_DMA_REG_DATA_OUT + * @retval Address of data register + */ +__STATIC_INLINE uint32_t LL_CORDIC_DMA_GetRegAddr(const CORDIC_TypeDef *CORDICx, uint32_t Direction) +{ + uint32_t data_reg_addr; + + if (Direction == LL_CORDIC_DMA_REG_DATA_OUT) + { + /* return address of RDATA register */ + data_reg_addr = (uint32_t) &(CORDICx->RDATA); + } + else + { + /* return address of WDATA register */ + data_reg_addr = (uint32_t) &(CORDICx->WDATA); + } + + return data_reg_addr; +} + +/** + * @} + */ + +/** @defgroup CORDIC_LL_EF_FLAG_Management FLAG_Management + * @{ + */ + +/** + * @brief Check CORDIC result ready flag state. + * @rmtoll CSR RRDY LL_CORDIC_IsActiveFlag_RRDY + * @param CORDICx CORDIC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_CORDIC_IsActiveFlag_RRDY(const CORDIC_TypeDef *CORDICx) +{ + return ((READ_BIT(CORDICx->CSR, CORDIC_CSR_RRDY) == (CORDIC_CSR_RRDY)) ? 1U : 0U); +} + +/** + * @} + */ + +/** @defgroup CORDIC_LL_EF_Data_Management Data_Management + * @{ + */ + +/** + * @brief Write 32-bit input data for the CORDIC processing. + * @rmtoll WDATA ARG LL_CORDIC_WriteData + * @param CORDICx CORDIC Instance + * @param InData 0 .. 0xFFFFFFFF : 32-bit value to be provided as input data for CORDIC processing. + * @retval None + */ +__STATIC_INLINE void LL_CORDIC_WriteData(CORDIC_TypeDef *CORDICx, uint32_t InData) +{ + WRITE_REG(CORDICx->WDATA, InData); +} + +/** + * @brief Return 32-bit output data of CORDIC processing. + * @rmtoll RDATA RES LL_CORDIC_ReadData + * @param CORDICx CORDIC Instance + * @retval 32-bit output data of CORDIC processing. + */ +__STATIC_INLINE uint32_t LL_CORDIC_ReadData(const CORDIC_TypeDef *CORDICx) +{ + return (uint32_t)(READ_REG(CORDICx->RDATA)); +} + +/** + * @} + */ + + + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup CORDIC_LL_EF_Init Initialization and de-initialization functions + * @{ + */ +ErrorStatus LL_CORDIC_DeInit(const CORDIC_TypeDef *CORDICx); + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined(CORDIC) */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_LL_CORDIC_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_cortex.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_cortex.h new file mode 100644 index 0000000000..43eadf556c --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_cortex.h @@ -0,0 +1,1383 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_cortex.h + * @author MCD Application Team + * @brief Header file of CORTEX LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The LL CORTEX driver contains a set of generic APIs that can be + used by user: + (+) SYSTICK configuration used by @ref LL_mDelay and @ref LL_Init1msTick + functions + (+) Low power mode configuration (SCB register of Cortex-MCU) + (+) API to access to MCU info (CPUID register) + (+) API to enable fault handler (SHCSR accesses) + (+) API to enable and disable the MPU secure and non-secure + (+) API to configure the region of MPU secure and non-secure + (+) API to configure the attributes region of MPU secure and non-secure + + @endverbatim + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_LL_CORTEX_H +#define STM32H5xx_LL_CORTEX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +/** @defgroup CORTEX_LL CORTEX + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup CORTEX_LL_EC_REGION_ACCESS CORTEX LL MPU Region Access Attributes + * @{ + */ +/* Register MPU_RBAR (Cortex-M33) : bits [4:0] */ +#define MPU_ACCESS_MSK (MPU_RBAR_SH_Msk|MPU_RBAR_AP_Msk|MPU_RBAR_XN_Msk) +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup CORTEX_LL_Exported_Constants CORTEX LL Exported Constants + * @{ + */ + +/** @defgroup CORTEX_LL_EC_CLKSOURCE_HCLK SYSTICK Clock Source + * @{ + */ +#define LL_SYSTICK_CLKSOURCE_HCLK_DIV8 0x00000000U /*!< AHB clock divided by 8 selected as SysTick + clock source */ +#define LL_SYSTICK_CLKSOURCE_HCLK SysTick_CTRL_CLKSOURCE_Msk /*!< AHB clock selected as SysTick + clock source */ +/** + * @} + */ + +/** @defgroup CORTEX_LL_EC_FAULT Handler Fault type + * @{ + */ +#define LL_HANDLER_FAULT_USG SCB_SHCSR_USGFAULTENA_Msk /*!< Usage fault */ +#define LL_HANDLER_FAULT_BUS SCB_SHCSR_BUSFAULTENA_Msk /*!< Bus fault */ +#define LL_HANDLER_FAULT_MEM SCB_SHCSR_MEMFAULTENA_Msk /*!< Memory management fault */ +#define LL_HANDLER_FAULT_SECURE SCB_SHCSR_SECUREFAULTENA_Msk /*!< Secure fault */ +/** + * @} + */ + +/** @defgroup CORTEX_LL_MPU_HFNMI_PRIVDEF_Control CORTEX LL MPU HFNMI and PRIVILEGED Access control + * @{ + */ +#define LL_MPU_CTRL_HFNMI_PRIVDEF_NONE 0U /*!< MPU is disabled during HardFault and NMI handlers, + privileged software access to the default memory map is disabled */ +#define LL_MPU_CTRL_HARDFAULT_NMI 2U /*!< MPU is enabled during HardFault and NMI handlers, + privileged software access to the default memory map is disabled */ +#define LL_MPU_CTRL_PRIVILEGED_DEFAULT 4U /*!< MPU is disabled during HardFault and NMI handlers, + privileged software access to the default memory map is enabled */ +#define LL_MPU_CTRL_HFNMI_PRIVDEF 6U /*!< MPU is enabled during HardFault and NMI handlers, + privileged software access to the default memory map is enabled */ +/** + * @} + */ + +/** @defgroup CORTEX_LL_MPU_Attributes CORTEX LL MPU Attributes + * @{ + */ +#define LL_MPU_DEVICE_nGnRnE 0x0U /*!< Device, noGather, noReorder, noEarly acknowledge. */ +#define LL_MPU_DEVICE_nGnRE 0x4U /*!< Device, noGather, noReorder, Early acknowledge. */ +#define LL_MPU_DEVICE_nGRE 0x8U /*!< Device, noGather, Reorder, Early acknowledge. */ +#define LL_MPU_DEVICE_GRE 0xCU /*!< Device, Gather, Reorder, Early acknowledge. */ + +#define LL_MPU_WRITE_THROUGH 0x0U /*!< Normal memory, write-through. */ +#define LL_MPU_NOT_CACHEABLE 0x4U /*!< Normal memory, non-cacheable. */ +#define LL_MPU_WRITE_BACK 0x4U /*!< Normal memory, write-back. */ + +#define LL_MPU_TRANSIENT 0x0U /*!< Normal memory, transient. */ +#define LL_MPU_NON_TRANSIENT 0x8U /*!< Normal memory, non-transient. */ + +#define LL_MPU_NO_ALLOCATE 0x0U /*!< Normal memory, no allocate. */ +#define LL_MPU_W_ALLOCATE 0x1U /*!< Normal memory, write allocate. */ +#define LL_MPU_R_ALLOCATE 0x2U /*!< Normal memory, read allocate. */ +#define LL_MPU_RW_ALLOCATE 0x3U /*!< Normal memory, read/write allocate. */ +/** + * @} + */ + +/** @defgroup CORTEX_LL_MPU_Region_Enable CORTEX LL MPU Region Enable + * @{ + */ +#define LL_MPU_REGION_ENABLE 1U /*!< MPU region enabled */ +#define LL_MPU_REGION_DISABLE 0U /*!< MPU region disabled */ +/** + * @} + */ + +/** @defgroup CORTEX_LL_MPU_Instruction_Access CORTEX LL MPU Instruction Access + * @{ + */ +#define LL_MPU_INSTRUCTION_ACCESS_ENABLE (0U << MPU_RBAR_XN_Pos) /*!< MPU region execution permitted + if read permitted */ +#define LL_MPU_INSTRUCTION_ACCESS_DISABLE (1U << MPU_RBAR_XN_Pos) /*!< MPU region execution not permitted */ +/** + * @} + */ + +/** @defgroup CORTEX_LL_MPU_Access_Shareable CORTEX LL MPU Instruction Access Shareable + * @{ + */ +#define LL_MPU_ACCESS_NOT_SHAREABLE (0U << MPU_RBAR_SH_Pos) /*!< MPU region not shareable */ +#define LL_MPU_ACCESS_OUTER_SHAREABLE (1U << MPU_RBAR_SH_Pos) /*!< MPU region outer shareable */ +#define LL_MPU_ACCESS_INNER_SHAREABLE (3U << MPU_RBAR_SH_Pos) /*!< MPU region inner shareable */ +/** + * @} + */ + +/** @defgroup CORTEX_LL_MPU_Region_Permission_Attributes CORTEX LL MPU Region Permission Attributes + * @{ + */ +#define LL_MPU_REGION_PRIV_RW (0U << MPU_RBAR_AP_Pos) /*!< MPU region Read/write by privileged code only */ +#define LL_MPU_REGION_ALL_RW (1U << MPU_RBAR_AP_Pos) /*!< MPU region Read/write by any privilege level */ +#define LL_MPU_REGION_PRIV_RO (2U << MPU_RBAR_AP_Pos) /*!< MPU region Read-only by privileged code only */ +#define LL_MPU_REGION_ALL_RO (3U << MPU_RBAR_AP_Pos) /*!< MPU region Read-only by any privilege level */ +/** + * @} + */ + +/** @defgroup CORTEX_LL_MPU_Region_Index CORTEX LL MPU Region Index + * @{ + */ +#define LL_MPU_REGION_NUMBER0 0U /*!< MPU region number 0 */ +#define LL_MPU_REGION_NUMBER1 1U /*!< MPU region number 1 */ +#define LL_MPU_REGION_NUMBER2 2U /*!< MPU region number 2 */ +#define LL_MPU_REGION_NUMBER3 3U /*!< MPU region number 3 */ +#define LL_MPU_REGION_NUMBER4 4U /*!< MPU region number 4 */ +#define LL_MPU_REGION_NUMBER5 5U /*!< MPU region number 5 */ +#define LL_MPU_REGION_NUMBER6 6U /*!< MPU region number 6 */ +#define LL_MPU_REGION_NUMBER7 7U /*!< MPU region number 7 */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define LL_MPU_REGION_NUMBER8 8U /*!< MPU region number 8 */ +#define LL_MPU_REGION_NUMBER9 9U /*!< MPU region number 9 */ +#define LL_MPU_REGION_NUMBER10 10U /*!< MPU region number 10 */ +#define LL_MPU_REGION_NUMBER11 11U /*!< MPU region number 11 */ +#endif /* __ARM_FEATURE_CMSE */ +/** + * @} + */ + +/** @defgroup CORTEX_LL_MPU_Attributes_Index CORTEX LL MPU Memory Attributes Index + * @{ + */ +#define LL_MPU_ATTRIBUTES_NUMBER0 0U /*!< MPU attribute number 0 */ +#define LL_MPU_ATTRIBUTES_NUMBER1 1U /*!< MPU attribute number 1 */ +#define LL_MPU_ATTRIBUTES_NUMBER2 2U /*!< MPU attribute number 2 */ +#define LL_MPU_ATTRIBUTES_NUMBER3 3U /*!< MPU attribute number 3 */ +#define LL_MPU_ATTRIBUTES_NUMBER4 4U /*!< MPU attribute number 4 */ +#define LL_MPU_ATTRIBUTES_NUMBER5 5U /*!< MPU attribute number 5 */ +#define LL_MPU_ATTRIBUTES_NUMBER6 6U /*!< MPU attribute number 6 */ +#define LL_MPU_ATTRIBUTES_NUMBER7 7U /*!< MPU attribute number 7 */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup CORTEX_LL_Exported_Functions CORTEX LL Exported Functions + * @{ + */ + +/** @defgroup CORTEX_LL_EF_SYSTICK SYSTICK + * @brief CORTEX SYSTICK LL module driver + * @{ + */ + +/** + * @brief This function checks if the Systick counter flag is active or not. + * @note It can be used in timeout function on application side. + * @rmtoll STK_CTRL COUNTFLAG LL_SYSTICK_IsActiveCounterFlag + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SYSTICK_IsActiveCounterFlag(void) +{ + return (((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == (SysTick_CTRL_COUNTFLAG_Msk)) ? 1UL : 0UL); +} + +/** + * @brief Configures the SysTick clock source + * @rmtoll STK_CTRL CLKSOURCE LL_SYSTICK_SetClkSource + * @param Source This parameter can be one of the following values: + * @arg @ref LL_SYSTICK_CLKSOURCE_HCLK_DIV8 + * @arg @ref LL_SYSTICK_CLKSOURCE_HCLK + * @retval None + */ +__STATIC_INLINE void LL_SYSTICK_SetClkSource(uint32_t Source) +{ + if (Source == LL_SYSTICK_CLKSOURCE_HCLK) + { + SET_BIT(SysTick->CTRL, LL_SYSTICK_CLKSOURCE_HCLK); + } + else + { + CLEAR_BIT(SysTick->CTRL, LL_SYSTICK_CLKSOURCE_HCLK); + } +} + +/** + * @brief Get the SysTick clock source + * @rmtoll STK_CTRL CLKSOURCE LL_SYSTICK_GetClkSource + * @retval Returned value can be one of the following values: + * @arg @ref LL_SYSTICK_CLKSOURCE_HCLK_DIV8 + * @arg @ref LL_SYSTICK_CLKSOURCE_HCLK + */ +__STATIC_INLINE uint32_t LL_SYSTICK_GetClkSource(void) +{ + return READ_BIT(SysTick->CTRL, LL_SYSTICK_CLKSOURCE_HCLK); +} + +/** + * @brief Enable SysTick exception request + * @rmtoll STK_CTRL TICKINT LL_SYSTICK_EnableIT + * @retval None + */ +__STATIC_INLINE void LL_SYSTICK_EnableIT(void) +{ + SET_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk); +} + +/** + * @brief Disable SysTick exception request + * @rmtoll STK_CTRL TICKINT LL_SYSTICK_DisableIT + * @retval None + */ +__STATIC_INLINE void LL_SYSTICK_DisableIT(void) +{ + CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk); +} + +/** + * @brief Checks if the SYSTICK interrupt is enabled or disabled. + * @rmtoll STK_CTRL TICKINT LL_SYSTICK_IsEnabledIT + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SYSTICK_IsEnabledIT(void) +{ + return ((READ_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk) == (SysTick_CTRL_TICKINT_Msk)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup CORTEX_LL_EF_LOW_POWER_MODE CORTEX LL LOW POWER MODE + * @{ + */ + +/** + * @brief Processor uses sleep as its low power mode + * @rmtoll SCB_SCR SLEEPDEEP LL_LPM_EnableSleep + * @retval None + */ +__STATIC_INLINE void LL_LPM_EnableSleep(void) +{ + /* Clear SLEEPDEEP bit of Cortex System Control Register */ + CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); +} + +/** + * @brief Processor uses deep sleep as its low power mode + * @rmtoll SCB_SCR SLEEPDEEP LL_LPM_EnableDeepSleep + * @retval None + */ +__STATIC_INLINE void LL_LPM_EnableDeepSleep(void) +{ + /* Set SLEEPDEEP bit of Cortex System Control Register */ + SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); +} + +/** + * @brief Configures sleep-on-exit when returning from Handler mode to Thread mode. + * @note Setting this bit to 1 enables an interrupt-driven application to avoid returning to an + * empty main application. + * @rmtoll SCB_SCR SLEEPONEXIT LL_LPM_EnableSleepOnExit + * @retval None + */ +__STATIC_INLINE void LL_LPM_EnableSleepOnExit(void) +{ + /* Set SLEEPONEXIT bit of Cortex System Control Register */ + SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk)); +} + +/** + * @brief Do not sleep when returning to Thread mode. + * @rmtoll SCB_SCR SLEEPONEXIT LL_LPM_DisableSleepOnExit + * @retval None + */ +__STATIC_INLINE void LL_LPM_DisableSleepOnExit(void) +{ + /* Clear SLEEPONEXIT bit of Cortex System Control Register */ + CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk)); +} + +/** + * @brief Enabled events and all interrupts, including disabled interrupts, can wakeup the + * processor. + * @rmtoll SCB_SCR SEVEONPEND LL_LPM_EnableEventOnPend + * @retval None + */ +__STATIC_INLINE void LL_LPM_EnableEventOnPend(void) +{ + /* Set SEVEONPEND bit of Cortex System Control Register */ + SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk)); +} + +/** + * @brief Only enabled interrupts or events can wakeup the processor, disabled interrupts are + * excluded + * @rmtoll SCB_SCR SEVEONPEND LL_LPM_DisableEventOnPend + * @retval None + */ +__STATIC_INLINE void LL_LPM_DisableEventOnPend(void) +{ + /* Clear SEVEONPEND bit of Cortex System Control Register */ + CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk)); +} + +/** + * @} + */ + +/** @defgroup CORTEX_LL_EF_HANDLER CORTEX LL HANDLER + * @{ + */ + +/** + * @brief Enable a fault in System handler control register (SHCSR) + * @rmtoll SCB_SHCSR USGFAULTENA LL_HANDLER_EnableFault\n + * SCB_SHCSR BUSFAULTENA LL_HANDLER_EnableFault\n + * SCB_SHCSR MEMFAULTENA LL_HANDLER_EnableFault\n + * SCB_SHCSR SECUREFAULTENA LL_HANDLER_EnableFault + * @param Fault This parameter can be a combination of the following values: + * @arg @ref LL_HANDLER_FAULT_USG + * @arg @ref LL_HANDLER_FAULT_BUS + * @arg @ref LL_HANDLER_FAULT_MEM + * @arg @ref LL_HANDLER_FAULT_SECURE (*) + * + * (*) value applicable in secure when the system implements the security. + * @retval None + */ +__STATIC_INLINE void LL_HANDLER_EnableFault(uint32_t Fault) +{ + /* Enable the system handler fault */ + SET_BIT(SCB->SHCSR, Fault); +} + +/** + * @brief Disable a fault in System handler control register (SHCSR) + * @rmtoll SCB_SHCSR USGFAULTENA LL_HANDLER_DisableFault\n + * SCB_SHCSR BUSFAULTENA LL_HANDLER_DisableFault\n + * SCB_SHCSR MEMFAULTENA LL_HANDLER_DisableFault\n + * SCB_SHCSR SECUREFAULTENA LL_HANDLER_DisableFault + * @param Fault This parameter can be a combination of the following values: + * @arg @ref LL_HANDLER_FAULT_USG + * @arg @ref LL_HANDLER_FAULT_BUS + * @arg @ref LL_HANDLER_FAULT_MEM + * @arg @ref LL_HANDLER_FAULT_SECURE (*) + * + * (*) value applicable in secure when the system implements the security. + * @retval None + */ +__STATIC_INLINE void LL_HANDLER_DisableFault(uint32_t Fault) +{ + /* Disable the system handler fault */ + CLEAR_BIT(SCB->SHCSR, Fault); +} + +/** + * @} + */ + +/** @defgroup CORTEX_LL_EF_MCU_INFO CORTEX LL MCU INFO + * @{ + */ + +/** + * @brief Get Implementer code + * @rmtoll SCB_CPUID IMPLEMENTER LL_CPUID_GetImplementer + * @retval Value should be equal to 0x41 for ARM + */ +__STATIC_INLINE uint32_t LL_CPUID_GetImplementer(void) +{ + return (uint32_t)(READ_BIT(SCB->CPUID, SCB_CPUID_IMPLEMENTER_Msk) >> SCB_CPUID_IMPLEMENTER_Pos); +} + +/** + * @brief Get Variant number (The r value in the rnpn product revision identifier) + * @rmtoll SCB_CPUID VARIANT LL_CPUID_GetVariant + * @retval Value between 0 and 255 (0x0: revision 0) + */ +__STATIC_INLINE uint32_t LL_CPUID_GetVariant(void) +{ + return (uint32_t)(READ_BIT(SCB->CPUID, SCB_CPUID_VARIANT_Msk) >> SCB_CPUID_VARIANT_Pos); +} + +/** + * @brief Get Architecture version + * @rmtoll SCB_CPUID ARCHITECTURE LL_CPUID_GetArchitecture + * @retval Value should be equal to 0xF for Cortex-M33 ("ARMv8-M with Main Extension") + */ +__STATIC_INLINE uint32_t LL_CPUID_GetArchitecture(void) +{ + return (uint32_t)(READ_BIT(SCB->CPUID, SCB_CPUID_ARCHITECTURE_Msk) >> SCB_CPUID_ARCHITECTURE_Pos); +} + +/** + * @brief Get Part number + * @rmtoll SCB_CPUID PARTNO LL_CPUID_GetParNo + * @retval Value should be equal to 0xD21 for Cortex-M33 + */ +__STATIC_INLINE uint32_t LL_CPUID_GetParNo(void) +{ + return (uint32_t)(READ_BIT(SCB->CPUID, SCB_CPUID_PARTNO_Msk) >> SCB_CPUID_PARTNO_Pos); +} + +/** + * @brief Get Revision number (The p value in the rnpn product revision identifier, indicates patch release) + * @rmtoll SCB_CPUID REVISION LL_CPUID_GetRevision + * @retval Value between 0 and 255 (0x1: patch 1) + */ +__STATIC_INLINE uint32_t LL_CPUID_GetRevision(void) +{ + return (uint32_t)(READ_BIT(SCB->CPUID, SCB_CPUID_REVISION_Msk) >> SCB_CPUID_REVISION_Pos); +} + +/** + * @} + */ + +/** @defgroup CORTEX_LL_EF_MPU CORTEX LL MPU + * @{ + */ + +/** + * @brief Enable MPU with input options + * @rmtoll MPU_CTRL ENABLE LL_MPU_Enable + * @param MPU_Control This parameter can be one of the following values: + * @arg @ref LL_MPU_CTRL_HFNMI_PRIVDEF_NONE + * @arg @ref LL_MPU_CTRL_HARDFAULT_NMI + * @arg @ref LL_MPU_CTRL_PRIVILEGED_DEFAULT + * @arg @ref LL_MPU_CTRL_HFNMI_PRIVDEF + * @retval None + */ +__STATIC_INLINE void LL_MPU_Enable(uint32_t MPU_Control) +{ + __DMB(); /* Data Memory Barrier operation to force any outstanding writes to memory before enabling the MPU */ + + /* Enable the MPU*/ + MPU->CTRL = MPU_CTRL_ENABLE_Msk | MPU_Control; + + /* Follow ARM recommendation with */ + /* Data Synchronization and Instruction Synchronization Barriers to ensure MPU configuration */ + __DSB(); /* Ensure that the subsequent instruction is executed only after the write to memory */ + __ISB(); /* Flush and refill pipeline with updated MPU configuration settings */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Enable non-secure MPU with input options + * @rmtoll MPU_CTRL ENABLE LL_MPU_Enable + * @param MPU_Control This parameter can be one of the following values: + * @arg @ref LL_MPU_CTRL_HFNMI_PRIVDEF_NONE + * @arg @ref LL_MPU_CTRL_HARDFAULT_NMI + * @arg @ref LL_MPU_CTRL_PRIVILEGED_DEFAULT + * @arg @ref LL_MPU_CTRL_HFNMI_PRIVDEF + * @retval None + */ +__STATIC_INLINE void LL_MPU_Enable_NS(uint32_t MPU_Control) +{ + __DMB(); /* Data Memory Barrier operation to force any outstanding writes to memory before enabling the MPU */ + + /* Enable the MPU*/ + MPU_NS->CTRL = MPU_CTRL_ENABLE_Msk | MPU_Control; + + /* Follow ARM recommendation with */ + /* Data Synchronization and Instruction Synchronization Barriers to ensure MPU configuration */ + __DSB(); /* Ensure that the subsequent instruction is executed only after the write to memory */ + __ISB(); /* Flush and refill pipeline with updated MPU configuration settings */ +} +#endif /* __ARM_FEATURE_CMSE */ + +/** + * @brief Disable MPU + * @rmtoll MPU_CTRL ENABLE LL_MPU_Disable + * @retval None + */ +__STATIC_INLINE void LL_MPU_Disable(void) +{ + __DMB(); /* Data Memory Barrier operation to force any outstanding writes to memory before disabling the MPU */ + + /* Disable MPU */ + WRITE_REG(MPU->CTRL, 0U); + + /* Follow ARM recommendation with */ + /* Data Synchronization and Instruction Synchronization Barriers to ensure MPU configuration */ + __DSB(); /* Ensure that the subsequent instruction is executed only after the write to memory */ + __ISB(); /* Flush and refill pipeline with updated MPU configuration settings */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Disable the non-secure MPU + * @rmtoll MPU_CTRL ENABLE LL_MPU_Disable_NS + * @retval None + */ +__STATIC_INLINE void LL_MPU_Disable_NS(void) +{ + __DMB(); /* Data Memory Barrier operation to force any outstanding writes to memory before disabling the MPU */ + + /* Disable MPU*/ + WRITE_REG(MPU_NS->CTRL, 0U); + + /* Follow ARM recommendation with */ + /* Data Synchronization and Instruction Synchronization Barriers to ensure MPU configuration */ + __DSB(); /* Ensure that the subsequent instruction is executed only after the write to memory */ + __ISB(); /* Flush and refill pipeline with updated MPU configuration settings */ +} +#endif /* __ARM_FEATURE_CMSE */ + + +/** + * @brief Check if MPU is enabled or not + * @rmtoll MPU_CTRL ENABLE LL_MPU_IsEnabled + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_MPU_IsEnabled(void) +{ + return ((READ_BIT(MPU->CTRL, MPU_CTRL_ENABLE_Msk) == (MPU_CTRL_ENABLE_Msk)) ? 1UL : 0UL); +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Check if non-secure MPU is enabled or not + * @rmtoll MPU_CTRL ENABLE LL_MPU_IsEnabled_NS + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_MPU_IsEnabled_NS(void) +{ + return ((READ_BIT(MPU_NS->CTRL, MPU_CTRL_ENABLE_Msk) == (MPU_CTRL_ENABLE_Msk)) ? 1UL : 0UL); +} +#endif /* __ARM_FEATURE_CMSE */ + +/** + * @brief Enable a MPU region + * @rmtoll MPU_RLAR ENABLE LL_MPU_EnableRegion + * @param Region This parameter can be one of the following values: + * @arg @ref LL_MPU_REGION_NUMBER0 + * @arg @ref LL_MPU_REGION_NUMBER1 + * @arg @ref LL_MPU_REGION_NUMBER2 + * @arg @ref LL_MPU_REGION_NUMBER3 + * @arg @ref LL_MPU_REGION_NUMBER4 + * @arg @ref LL_MPU_REGION_NUMBER5 + * @arg @ref LL_MPU_REGION_NUMBER6 + * @arg @ref LL_MPU_REGION_NUMBER7 + * @arg @ref LL_MPU_REGION_NUMBER8 (*) + * @arg @ref LL_MPU_REGION_NUMBER9 (*) + * @arg @ref LL_MPU_REGION_NUMBER10 (*) + * @arg @ref LL_MPU_REGION_NUMBER11 (*) + * @note cortex-M33 supports 12 secure and 8 non secure regions. + * (*) : For MPU_S only + * @retval None + */ +__STATIC_INLINE void LL_MPU_EnableRegion(uint32_t Region) +{ + /* Set Region number */ + WRITE_REG(MPU->RNR, Region); + + /* Enable the MPU region */ + SET_BIT(MPU->RLAR, MPU_RLAR_EN_Msk); +} + +/** + * @brief Check if MPU region is enabled or not + * @rmtoll MPU_RNR ENABLE LL_MPU_IsEnabled_Region + * @param Region This parameter can be one of the following values: + * @arg @ref LL_MPU_REGION_NUMBER0 + * @arg @ref LL_MPU_REGION_NUMBER1 + * @arg @ref LL_MPU_REGION_NUMBER2 + * @arg @ref LL_MPU_REGION_NUMBER3 + * @arg @ref LL_MPU_REGION_NUMBER4 + * @arg @ref LL_MPU_REGION_NUMBER5 + * @arg @ref LL_MPU_REGION_NUMBER6 + * @arg @ref LL_MPU_REGION_NUMBER7 + * @arg @ref LL_MPU_REGION_NUMBER8 (*) + * @arg @ref LL_MPU_REGION_NUMBER9 (*) + * @arg @ref LL_MPU_REGION_NUMBER10 (*) + * @arg @ref LL_MPU_REGION_NUMBER11 (*) + * @note cortex-M33 supports 12 secure and 8 non secure regions. + * (*) : For MPU_S only + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_MPU_IsEnabled_Region(uint32_t Region) +{ + /* Set region index */ + WRITE_REG(MPU->RNR, Region); + + /* Return MPU region status */ + return ((READ_BIT(MPU->RLAR, MPU_RLAR_EN_Msk) == (MPU_RLAR_EN_Msk)) ? 1UL : 0UL); +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Enable a non-secure MPU region + * @rmtoll MPU_RLAR ENABLE LL_MPU_EnableRegion_NS + * @param Region This parameter can be one of the following values: + * @arg @ref LL_MPU_REGION_NUMBER0 + * @arg @ref LL_MPU_REGION_NUMBER1 + * @arg @ref LL_MPU_REGION_NUMBER2 + * @arg @ref LL_MPU_REGION_NUMBER3 + * @arg @ref LL_MPU_REGION_NUMBER4 + * @arg @ref LL_MPU_REGION_NUMBER5 + * @arg @ref LL_MPU_REGION_NUMBER6 + * @arg @ref LL_MPU_REGION_NUMBER7 + * @note cortex-M33 supports 8 non secure regions. + * @retval None + */ +__STATIC_INLINE void LL_MPU_EnableRegion_NS(uint32_t Region) +{ + /* Set Region number */ + WRITE_REG(MPU_NS->RNR, Region); + + /* Enable the MPU region */ + SET_BIT(MPU_NS->RLAR, MPU_RLAR_EN_Msk); +} + +/** + * @brief Check if non-secure MPU region is enabled or not + * @rmtoll MPU_RNR ENABLE LL_MPU_IsEnabled_Region_NS + * @param Region This parameter can be one of the following values: + * @arg @ref LL_MPU_REGION_NUMBER0 + * @arg @ref LL_MPU_REGION_NUMBER1 + * @arg @ref LL_MPU_REGION_NUMBER2 + * @arg @ref LL_MPU_REGION_NUMBER3 + * @arg @ref LL_MPU_REGION_NUMBER4 + * @arg @ref LL_MPU_REGION_NUMBER5 + * @arg @ref LL_MPU_REGION_NUMBER6 + * @arg @ref LL_MPU_REGION_NUMBER7 + * @note cortex-M33 supports 8 non secure regions. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_MPU_IsEnabled_Region_NS(uint32_t Region) +{ + /* Set region index */ + WRITE_REG(MPU_NS->RNR, Region); + + /* Return non-secure MPU region status */ + return ((READ_BIT(MPU_NS->RLAR, MPU_RLAR_EN_Msk) == (MPU_RLAR_EN_Msk)) ? 1UL : 0UL); +} +#endif /* __ARM_FEATURE_CMSE */ + +/** + * @brief Disable a MPU region + * @rmtoll MPU_RNR REGION LL_MPU_DisableRegion\n + * MPU_RLAR ENABLE LL_MPU_DisableRegion + * @param Region This parameter can be one of the following values: + * @arg @ref LL_MPU_REGION_NUMBER0 + * @arg @ref LL_MPU_REGION_NUMBER1 + * @arg @ref LL_MPU_REGION_NUMBER2 + * @arg @ref LL_MPU_REGION_NUMBER3 + * @arg @ref LL_MPU_REGION_NUMBER4 + * @arg @ref LL_MPU_REGION_NUMBER5 + * @arg @ref LL_MPU_REGION_NUMBER6 + * @arg @ref LL_MPU_REGION_NUMBER7 + * @arg @ref LL_MPU_REGION_NUMBER8 (*) + * @arg @ref LL_MPU_REGION_NUMBER9 (*) + * @arg @ref LL_MPU_REGION_NUMBER10 (*) + * @arg @ref LL_MPU_REGION_NUMBER11 (*) + * @note cortex-M33 supports 12 secure and 8 non secure regions. + * (*) : For MPU_S only + * @retval None + */ +__STATIC_INLINE void LL_MPU_DisableRegion(uint32_t Region) +{ + /* Set Region number */ + WRITE_REG(MPU->RNR, Region); + + /* Disable the MPU region */ + CLEAR_BIT(MPU->RLAR, MPU_RLAR_EN_Msk); +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Disable a non-secure MPU region + * @rmtoll MPU_RNR REGION LL_MPU_DisableRegion_NS\n + * MPU_RLAR ENABLE LL_MPU_DisableRegion_NS\n + * @param Region This parameter can be one of the following values: + * @arg @ref LL_MPU_REGION_NUMBER0 + * @arg @ref LL_MPU_REGION_NUMBER1 + * @arg @ref LL_MPU_REGION_NUMBER2 + * @arg @ref LL_MPU_REGION_NUMBER3 + * @arg @ref LL_MPU_REGION_NUMBER4 + * @arg @ref LL_MPU_REGION_NUMBER5 + * @arg @ref LL_MPU_REGION_NUMBER6 + * @arg @ref LL_MPU_REGION_NUMBER7 + * @note cortex-M33 supports 8 non secure regions. + * @retval None + */ +__STATIC_INLINE void LL_MPU_DisableRegion_NS(uint32_t Region) +{ + /* Set Region number */ + WRITE_REG(MPU_NS->RNR, Region); + + /* Disable the MPU region */ + CLEAR_BIT(MPU_NS->RLAR, MPU_RLAR_EN_Msk); +} +#endif /* __ARM_FEATURE_CMSE */ + +/** + * @brief Configure and enable a MPU region + * @rmtoll MPU_RNR REGION LL_MPU_ConfigRegion\n + * MPU_RBAR ADDR LL_MPU_ConfigRegion\n + * MPU_RLAR ADDR LL_MPU_ConfigRegion\n + * MPU_RBAR XN LL_MPU_ConfigRegion\n + * MPU_RBAR AP LL_MPU_ConfigRegion\n + * MPU_RBAR SH LL_MPU_ConfigRegion\n + * MPU_RLAR EN LL_MPU_ConfigRegion\n + * MPU_RLAR AttrIndx LL_MPU_ConfigRegion\n + * @param Region This parameter can be one of the following values: + * @arg @ref LL_MPU_REGION_NUMBER0 + * @arg @ref LL_MPU_REGION_NUMBER1 + * @arg @ref LL_MPU_REGION_NUMBER2 + * @arg @ref LL_MPU_REGION_NUMBER3 + * @arg @ref LL_MPU_REGION_NUMBER4 + * @arg @ref LL_MPU_REGION_NUMBER5 + * @arg @ref LL_MPU_REGION_NUMBER6 + * @arg @ref LL_MPU_REGION_NUMBER7 + * @arg @ref LL_MPU_REGION_NUMBER8 (*) + * @arg @ref LL_MPU_REGION_NUMBER9 (*) + * @arg @ref LL_MPU_REGION_NUMBER10 (*) + * @arg @ref LL_MPU_REGION_NUMBER11 (*) + * @param Attributes This parameter can be a combination of the following values: + * @arg @ref LL_MPU_INSTRUCTION_ACCESS_ENABLE or @ref LL_MPU_INSTRUCTION_ACCESS_DISABLE + * @arg @ref LL_MPU_ACCESS_NOT_SHAREABLE or @ref LL_MPU_ACCESS_OUTER_SHAREABLE + * or @ref LL_MPU_ACCESS_INNER_SHAREABLE + * @arg @ref LL_MPU_REGION_PRIV_RW or @ref LL_MPU_REGION_ALL_RW or @ref LL_MPU_REGION_PRIV_RO + * or @ref LL_MPU_REGION_ALL_RO + * @param AttrIndx This parameter can be one of the following values: + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER0 + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER1 + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER2 + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER3 + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER4 + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER5 + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER6 + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER7 + * @param BaseAddress Value of region base address + * @param LimitAddress Value of region limit address + * @note cortex-M33 supports 12 secure and 8 non secure regions. + * (*) : For MPU_S only + * @retval None + */ +__STATIC_INLINE void LL_MPU_ConfigRegion(uint32_t Region, uint32_t Attributes, uint32_t AttrIndx, uint32_t BaseAddress, + uint32_t LimitAddress) +{ + /* Set region index */ + WRITE_REG(MPU->RNR, Region); + + /* Set base address */ + MPU->RBAR |= Attributes; + + /* Set region base address and region access attributes */ + WRITE_REG(MPU->RBAR, ((BaseAddress & MPU_RBAR_BASE_Msk) | Attributes)); + + /* Set region limit address, memory attributes index and enable region */ + WRITE_REG(MPU->RLAR, ((LimitAddress & MPU_RLAR_LIMIT_Msk) | AttrIndx | MPU_RLAR_EN_Msk)); +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Configure and enable a non-secure MPU region + * @rmtoll MPU_RNR REGION LL_MPU_ConfigRegion_NS\n + * MPU_RBAR ADDR LL_MPU_ConfigRegion_NS\n + * MPU_RLAR ADDR LL_MPU_ConfigRegion_NS\n + * MPU_RBAR XN LL_MPU_ConfigRegion_NS\n + * MPU_RBAR AP LL_MPU_ConfigRegion_NS\n + * MPU_RBAR SH LL_MPU_ConfigRegion_NS\n + * MPU_RLAR EN LL_MPU_ConfigRegion_NS\n + * MPU_RLAR AttrIndx LL_MPU_ConfigRegion_NS\n + * @param Region This parameter can be one of the following values: + * @arg @ref LL_MPU_REGION_NUMBER0 + * @arg @ref LL_MPU_REGION_NUMBER1 + * @arg @ref LL_MPU_REGION_NUMBER2 + * @arg @ref LL_MPU_REGION_NUMBER3 + * @arg @ref LL_MPU_REGION_NUMBER4 + * @arg @ref LL_MPU_REGION_NUMBER5 + * @arg @ref LL_MPU_REGION_NUMBER6 + * @arg @ref LL_MPU_REGION_NUMBER7 + * @param Attributes This parameter can be a combination of the following values: + * @arg @ref LL_MPU_INSTRUCTION_ACCESS_ENABLE or @ref LL_MPU_INSTRUCTION_ACCESS_DISABLE + * @arg @ref LL_MPU_ACCESS_NOT_SHAREABLE or @ref LL_MPU_ACCESS_OUTER_SHAREABLE + * or @ref LL_MPU_ACCESS_INNER_SHAREABLE + * @arg @ref LL_MPU_REGION_PRIV_RW or @ref LL_MPU_REGION_ALL_RW or @ref LL_MPU_REGION_PRIV_RO + * or @ref LL_MPU_REGION_ALL_RO + * @param AttrIndx This parameter can be one of the following values: + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER0 + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER1 + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER2 + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER3 + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER4 + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER5 + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER6 + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER7 + * @param BaseAddress Value of region base address + * @param LimitAddress Value of region limit address + * @note cortex-M33 supports 12 secure and 8 non secure regions. + * @retval None + */ +__STATIC_INLINE void LL_MPU_ConfigRegion_NS(uint32_t Region, uint32_t Attributes, uint32_t AttrIndx, + uint32_t BaseAddress, uint32_t LimitAddress) +{ + /* Set Region number */ + WRITE_REG(MPU_NS->RNR, Region); + + /* Set region base address and region access attributes */ + WRITE_REG(MPU_NS->RBAR, ((BaseAddress & MPU_RBAR_BASE_Msk) | Attributes)); + + /* Set region limit address, memory attributes index and enable region */ + WRITE_REG(MPU_NS->RLAR, ((LimitAddress & MPU_RLAR_LIMIT_Msk) | AttrIndx | MPU_RLAR_EN_Msk)); +} +#endif /* __ARM_FEATURE_CMSE */ + +/** + * @brief Configure a MPU region address range + * @rmtoll MPU_RNR REGION LL_MPU_ConfigRegionAddress\n + * MPU_RBAR ADDR LL_MPU_ConfigRegionAddress\n + * MPU_RLAR ADDR LL_MPU_ConfigRegionAddress\n + * @param Region This parameter can be one of the following values: + * @arg @ref LL_MPU_REGION_NUMBER0 + * @arg @ref LL_MPU_REGION_NUMBER1 + * @arg @ref LL_MPU_REGION_NUMBER2 + * @arg @ref LL_MPU_REGION_NUMBER3 + * @arg @ref LL_MPU_REGION_NUMBER4 + * @arg @ref LL_MPU_REGION_NUMBER5 + * @arg @ref LL_MPU_REGION_NUMBER6 + * @arg @ref LL_MPU_REGION_NUMBER7 + * @arg @ref LL_MPU_REGION_NUMBER8 (*) + * @arg @ref LL_MPU_REGION_NUMBER9 (*) + * @arg @ref LL_MPU_REGION_NUMBER10 (*) + * @arg @ref LL_MPU_REGION_NUMBER11 (*) + * @param BaseAddress Value of region base address + * @param LimitAddress Value of region limit address + * @note cortex-M33 supports 12 secure and 8 non secure regions. + * (*) : For MPU_S only + * @retval None + */ +__STATIC_INLINE void LL_MPU_ConfigRegionAddress(uint32_t Region, uint32_t BaseAddress, uint32_t LimitAddress) +{ + /* Set Region number */ + WRITE_REG(MPU->RNR, Region); + + /* Modify region base address */ + MODIFY_REG(MPU->RBAR, MPU_RBAR_BASE_Msk, (BaseAddress & MPU_RBAR_BASE_Msk)); + + /* Modify region limit address */ + MODIFY_REG(MPU->RLAR, MPU_RLAR_LIMIT_Msk, (LimitAddress & MPU_RLAR_LIMIT_Msk)); +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Configure a non-secure MPU region address range + * @rmtoll MPU_RNR REGION LL_MPU_ConfigRegionAddress_NS\n + * MPU_RBAR ADDR LL_MPU_ConfigRegionAddress_NS\n + * MPU_RLAR ADDR LL_MPU_ConfigRegionAddress_NS\n + * @param Region This parameter can be one of the following values: + * @arg @ref LL_MPU_REGION_NUMBER0 + * @arg @ref LL_MPU_REGION_NUMBER1 + * @arg @ref LL_MPU_REGION_NUMBER2 + * @arg @ref LL_MPU_REGION_NUMBER3 + * @arg @ref LL_MPU_REGION_NUMBER4 + * @arg @ref LL_MPU_REGION_NUMBER5 + * @arg @ref LL_MPU_REGION_NUMBER6 + * @arg @ref LL_MPU_REGION_NUMBER7 + * @param BaseAddress Value of region base address + * @param LimitAddress Value of region limit address + * @note cortex-M33 supports 12 secure and 8 non secure regions. + * @retval None + */ +__STATIC_INLINE void LL_MPU_ConfigRegionAddress_NS(uint32_t Region, uint32_t BaseAddress, uint32_t LimitAddress) +{ + /* Set Region number */ + WRITE_REG(MPU_NS->RNR, Region); + + /* Set base address */ + MODIFY_REG(MPU_NS->RBAR, MPU_RBAR_BASE_Msk, (BaseAddress & MPU_RBAR_BASE_Msk)); + + /* Set limit address */ + MODIFY_REG(MPU_NS->RLAR, MPU_RLAR_LIMIT_Msk, (LimitAddress & MPU_RLAR_LIMIT_Msk)); +} +#endif /* __ARM_FEATURE_CMSE */ + +/** + * @brief Configure a MPU attributes index + * @rmtoll MPU_MAIR0 Attribute LL_MPU_ConfigAttributes\n + * MPU_MAIR1 Attribute LL_MPU_ConfigAttributes\n + * @param AttIndex This parameter can be one of the following values: + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER0 + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER1 + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER2 + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER3 + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER4 + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER5 + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER6 + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER7 + * @param Attributes This parameter can be a combination of @ref CORTEX_LL_MPU_Attributes + * @retval None + */ +__STATIC_INLINE void LL_MPU_ConfigAttributes(uint32_t AttIndex, uint32_t Attributes) +{ + /* When selected index is in range [0;3] */ + if (AttIndex < LL_MPU_ATTRIBUTES_NUMBER4) + { + /* Modify Attr field of MPU_MAIR0 accordingly */ + MODIFY_REG(MPU->MAIR0, (0xFFU << (AttIndex * 8U)), (Attributes << (AttIndex * 8U))); + } + /* When selected index is in range [4;7] */ + else + { + /* Modify Attr field of MPU_MAIR1 accordingly */ + MODIFY_REG(MPU->MAIR1, (0xFFU << ((AttIndex - 4U) * 8U)), (Attributes << ((AttIndex - 4U) * 8U))); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Configure a non-secure MPU attributes index + * @rmtoll MPU_MAIR0 Attribute LL_MPU_ConfigAttributes_NS\n + * MPU_MAIR1 Attribute LL_MPU_ConfigAttributes_NS\n + * @param AttIndex This parameter can be one of the following values: + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER0 + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER1 + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER2 + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER3 + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER4 + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER5 + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER6 + * @arg @ref LL_MPU_ATTRIBUTES_NUMBER7 + * @param Attributes This parameter can be a combination of @ref CORTEX_LL_MPU_Attributes + * @retval None + */ +__STATIC_INLINE void LL_MPU_ConfigAttributes_NS(uint32_t AttIndex, uint32_t Attributes) +{ + /* When selected index is in range [0;3] */ + if (AttIndex < LL_MPU_ATTRIBUTES_NUMBER4) + { + /* Modify Attr field of MPU_MAIR0_NS accordingly */ + MODIFY_REG(MPU_NS->MAIR0, (0xFFU << (AttIndex * 8U)), (Attributes << (AttIndex * 8U))); + } + /* When selected index is in range [4;7] */ + else + { + /* Modify Attr field of MPU_MAIR1_NS accordingly */ + MODIFY_REG(MPU_NS->MAIR1, (0xFFU << ((AttIndex - 4U) * 8U)), (Attributes << ((AttIndex - 4U) * 8U))); + } +} +#endif /* __ARM_FEATURE_CMSE */ + +/** + * @brief Configure a MPU region limit address + * @rmtoll MPU_RNR REGION LL_MPU_SetRegionLimitAddress\n + * MPU_RLAR ADDR LL_MPU_SetRegionLimitAddress\n + * @param Region This parameter can be one of the following values: + * @arg @ref LL_MPU_REGION_NUMBER0 + * @arg @ref LL_MPU_REGION_NUMBER1 + * @arg @ref LL_MPU_REGION_NUMBER2 + * @arg @ref LL_MPU_REGION_NUMBER3 + * @arg @ref LL_MPU_REGION_NUMBER4 + * @arg @ref LL_MPU_REGION_NUMBER5 + * @arg @ref LL_MPU_REGION_NUMBER6 + * @arg @ref LL_MPU_REGION_NUMBER7 + * @arg @ref LL_MPU_REGION_NUMBER8 (*) + * @arg @ref LL_MPU_REGION_NUMBER9 (*) + * @arg @ref LL_MPU_REGION_NUMBER10 (*) + * @arg @ref LL_MPU_REGION_NUMBER11 (*) + * @param LimitAddress Value of region limit address + * @note cortex-M33 supports 12 secure and 8 non secure regions. + * (*) : For MPU_S only + * @retval None + */ +__STATIC_INLINE void LL_MPU_SetRegionLimitAddress(uint32_t Region, uint32_t LimitAddress) +{ + /* Set Region number */ + WRITE_REG(MPU->RNR, Region); + + /* Set limit address */ + MODIFY_REG(MPU->RLAR, MPU_RLAR_LIMIT_Msk, (LimitAddress & MPU_RLAR_LIMIT_Msk)); +} + +/** + * @brief Get a MPU region limit address + * @rmtoll MPU_RNR REGION LL_MPU_GetRegionLimitAddress\n + * @param Region This parameter can be one of the following values: + * @arg @ref LL_MPU_REGION_NUMBER0 + * @arg @ref LL_MPU_REGION_NUMBER1 + * @arg @ref LL_MPU_REGION_NUMBER2 + * @arg @ref LL_MPU_REGION_NUMBER3 + * @arg @ref LL_MPU_REGION_NUMBER4 + * @arg @ref LL_MPU_REGION_NUMBER5 + * @arg @ref LL_MPU_REGION_NUMBER6 + * @arg @ref LL_MPU_REGION_NUMBER7 + * @arg @ref LL_MPU_REGION_NUMBER8 (*) + * @arg @ref LL_MPU_REGION_NUMBER9 (*) + * @arg @ref LL_MPU_REGION_NUMBER10 (*) + * @arg @ref LL_MPU_REGION_NUMBER11 (*) + * (*) : For MPU_S only + * @retval Value of the region limit address + */ +__STATIC_INLINE uint32_t LL_MPU_GetRegionLimitAddress(uint32_t Region) +{ + /* Set Region number */ + WRITE_REG(MPU->RNR, Region); + return (READ_REG(MPU->RLAR & MPU_RLAR_LIMIT_Msk)); +} + +/** + * @brief Configure a MPU region base address + * @rmtoll MPU_RNR REGION LL_MPU_SetRegionBaseAddress\n + * MPU_RBAR ADDR LL_MPU_SetRegionBaseAddress\n + * @param Region This parameter can be one of the following values: + * @arg @ref LL_MPU_REGION_NUMBER0 + * @arg @ref LL_MPU_REGION_NUMBER1 + * @arg @ref LL_MPU_REGION_NUMBER2 + * @arg @ref LL_MPU_REGION_NUMBER3 + * @arg @ref LL_MPU_REGION_NUMBER4 + * @arg @ref LL_MPU_REGION_NUMBER5 + * @arg @ref LL_MPU_REGION_NUMBER6 + * @arg @ref LL_MPU_REGION_NUMBER7 + * @arg @ref LL_MPU_REGION_NUMBER8 (*) + * @arg @ref LL_MPU_REGION_NUMBER9 (*) + * @arg @ref LL_MPU_REGION_NUMBER10 (*) + * @arg @ref LL_MPU_REGION_NUMBER11 (*) + * @param BaseAddress Value of region base address + * @note cortex-M33 supports 12 secure and 8 non secure regions. + * (*) : For MPU_S only + * @retval None + */ +__STATIC_INLINE void LL_MPU_SetRegionBaseAddress(uint32_t Region, uint32_t BaseAddress) +{ + /* Set Region number */ + WRITE_REG(MPU->RNR, Region); + /* Set base address */ + MODIFY_REG(MPU->RBAR, MPU_RBAR_BASE_Msk, (BaseAddress & MPU_RBAR_BASE_Msk)); +} + +/** + * @brief Get a MPU region base address + * @rmtoll MPU_RNR REGION LL_MPU_GetRegionBaseAddress\n + * @param Region This parameter can be one of the following values: + * @arg @ref LL_MPU_REGION_NUMBER0 + * @arg @ref LL_MPU_REGION_NUMBER1 + * @arg @ref LL_MPU_REGION_NUMBER2 + * @arg @ref LL_MPU_REGION_NUMBER3 + * @arg @ref LL_MPU_REGION_NUMBER4 + * @arg @ref LL_MPU_REGION_NUMBER5 + * @arg @ref LL_MPU_REGION_NUMBER6 + * @arg @ref LL_MPU_REGION_NUMBER7 + * @arg @ref LL_MPU_REGION_NUMBER8 (*) + * @arg @ref LL_MPU_REGION_NUMBER9 (*) + * @arg @ref LL_MPU_REGION_NUMBER10 (*) + * @arg @ref LL_MPU_REGION_NUMBER11 (*) + * @note cortex-M33 supports 12 secure and 8 non secure regions. + * (*) : For MPU_S only + * @retval Value of the region base address + */ +__STATIC_INLINE uint32_t LL_MPU_GetRegionBaseAddress(uint32_t Region) +{ + /* Set Region number */ + WRITE_REG(MPU->RNR, Region); + return (READ_REG(MPU->RBAR & MPU_RBAR_BASE_Msk)); +} + +/** + * @brief Configure a MPU region access attributes and enable a region + * @rmtoll MPU_RNR REGION LL_MPU_SetRegionAccess\n + * MPU_RBAR XN LL_MPU_SetRegionAccess\n + * MPU_RBAR AP LL_MPU_SetRegionAccess\n + * MPU_RBAR SH LL_MPU_SetRegionAccess\n + * @param Region This parameter can be one of the following values: + * @arg @ref LL_MPU_REGION_NUMBER0 + * @arg @ref LL_MPU_REGION_NUMBER1 + * @arg @ref LL_MPU_REGION_NUMBER2 + * @arg @ref LL_MPU_REGION_NUMBER3 + * @arg @ref LL_MPU_REGION_NUMBER4 + * @arg @ref LL_MPU_REGION_NUMBER5 + * @arg @ref LL_MPU_REGION_NUMBER6 + * @arg @ref LL_MPU_REGION_NUMBER7 + * @arg @ref LL_MPU_REGION_NUMBER8 (*) + * @arg @ref LL_MPU_REGION_NUMBER9 (*) + * @arg @ref LL_MPU_REGION_NUMBER10 (*) + * @arg @ref LL_MPU_REGION_NUMBER11 (*) + * @param Attributes This parameter can be a combination of the following values: + * @arg @ref LL_MPU_INSTRUCTION_ACCESS_ENABLE or @ref LL_MPU_INSTRUCTION_ACCESS_DISABLE + * @arg @ref LL_MPU_ACCESS_NOT_SHAREABLE or @ref LL_MPU_ACCESS_OUTER_SHAREABLE + * or @ref LL_MPU_ACCESS_INNER_SHAREABLE + * @arg @ref LL_MPU_REGION_PRIV_RW or @ref LL_MPU_REGION_ALL_RW or @ref LL_MPU_REGION_PRIV_RO + * or @ref LL_MPU_REGION_ALL_RO + * @note cortex-M33 supports 12 secure and 8 non secure regions. + * (*) : For MPU_S only + * @retval None + */ +__STATIC_INLINE void LL_MPU_SetRegionAccess(uint32_t Region, uint32_t Attributes) +{ + /* Set Region number */ + WRITE_REG(MPU->RNR, Region); + + /* Set base address */ + MODIFY_REG(MPU->RBAR, MPU_ACCESS_MSK, (Attributes & MPU_ACCESS_MSK)); +} + +/** + * @brief Get a MPU region access attributes + * @rmtoll MPU_RNR REGION LL_MPU_GetRegionAccess\n + * MPU_RBAR XN LL_MPU_GetRegionAccess\n + * MPU_RBAR AP LL_MPU_GetRegionAccess\n + * MPU_RBAR SH LL_MPU_GetRegionAccess\n + * @param Region This parameter can be one of the following values: + * @arg @ref LL_MPU_REGION_NUMBER0 + * @arg @ref LL_MPU_REGION_NUMBER1 + * @arg @ref LL_MPU_REGION_NUMBER2 + * @arg @ref LL_MPU_REGION_NUMBER3 + * @arg @ref LL_MPU_REGION_NUMBER4 + * @arg @ref LL_MPU_REGION_NUMBER5 + * @arg @ref LL_MPU_REGION_NUMBER6 + * @arg @ref LL_MPU_REGION_NUMBER7 + * @arg @ref LL_MPU_REGION_NUMBER8 (*) + * @arg @ref LL_MPU_REGION_NUMBER9 (*) + * @arg @ref LL_MPU_REGION_NUMBER10 (*) + * @arg @ref LL_MPU_REGION_NUMBER11 (*) + * (*) : For MPU_S only + * @retval return a combination of the following values: + * @arg @ref LL_MPU_INSTRUCTION_ACCESS_ENABLE or @ref LL_MPU_INSTRUCTION_ACCESS_DISABLE + * @arg @ref LL_MPU_ACCESS_NOT_SHAREABLE or @ref LL_MPU_ACCESS_OUTER_SHAREABLE + * or @ref LL_MPU_ACCESS_INNER_SHAREABLE + * @arg @ref LL_MPU_REGION_PRIV_RW or @ref LL_MPU_REGION_ALL_RW or @ref LL_MPU_REGION_PRIV_RO + * or @ref LL_MPU_REGION_ALL_RO + */ +__STATIC_INLINE uint32_t LL_MPU_GetRegionAccess(uint32_t Region) +{ + /* Set Region number */ + WRITE_REG(MPU->RNR, Region); + return (READ_REG(MPU->RBAR & (MPU_RBAR_XN_Msk | MPU_RBAR_AP_Msk | MPU_RBAR_SH_Msk))); +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Configure a non-secure MPU region limit address + * @rmtoll MPU_RNR REGION LL_MPU_SetRegionLimitAddress_NS\n + * MPU_RLAR ADDR LL_MPU_SetRegionLimitAddress_NS\n + * @param Region This parameter can be one of the following values: + * @arg @ref LL_MPU_REGION_NUMBER0 + * @arg @ref LL_MPU_REGION_NUMBER1 + * @arg @ref LL_MPU_REGION_NUMBER2 + * @arg @ref LL_MPU_REGION_NUMBER3 + * @arg @ref LL_MPU_REGION_NUMBER4 + * @arg @ref LL_MPU_REGION_NUMBER5 + * @arg @ref LL_MPU_REGION_NUMBER6 + * @arg @ref LL_MPU_REGION_NUMBER7 + * @param LimitAddress Value of region limit address + * @note cortex-M33 supports 8 non secure regions. + * @retval None + */ +__STATIC_INLINE void LL_MPU_SetRegionLimitAddress_NS(uint32_t Region, uint32_t LimitAddress) +{ + /* Set Region number */ + WRITE_REG(MPU_NS->RNR, Region); + + /* Set limit address */ + MODIFY_REG(MPU_NS->RLAR, MPU_RLAR_LIMIT_Msk, (LimitAddress & MPU_RLAR_LIMIT_Msk)); +} + +/** + * @brief Get a non-secure MPU region limit address + * @rmtoll MPU_RNR REGION LL_MPU_GetRegionLimitAddress_NS\n + * @param Region This parameter can be one of the following values: + * @arg @ref LL_MPU_REGION_NUMBER0 + * @arg @ref LL_MPU_REGION_NUMBER1 + * @arg @ref LL_MPU_REGION_NUMBER2 + * @arg @ref LL_MPU_REGION_NUMBER3 + * @arg @ref LL_MPU_REGION_NUMBER4 + * @arg @ref LL_MPU_REGION_NUMBER5 + * @arg @ref LL_MPU_REGION_NUMBER6 + * @arg @ref LL_MPU_REGION_NUMBER7 + * @retval Value of the region limit address. + */ +__STATIC_INLINE uint32_t LL_MPU_GetRegionLimitAddress_NS(uint32_t Region) +{ + /* Set Region number */ + WRITE_REG(MPU_NS->RNR, Region); + return (READ_REG(MPU_NS->RLAR & MPU_RLAR_LIMIT_Msk)); +} + +/** + * @brief Configure a non-secure MPU region base address + * @rmtoll MPU_RNR REGION LL_MPU_SetRegionBaseAddress_NS\n + * MPU_RBAR ADDR LL_MPU_SetRegionBaseAddress_NS\n + * @param Region This parameter can be one of the following values: + * @arg @ref LL_MPU_REGION_NUMBER0 + * @arg @ref LL_MPU_REGION_NUMBER1 + * @arg @ref LL_MPU_REGION_NUMBER2 + * @arg @ref LL_MPU_REGION_NUMBER3 + * @arg @ref LL_MPU_REGION_NUMBER4 + * @arg @ref LL_MPU_REGION_NUMBER5 + * @arg @ref LL_MPU_REGION_NUMBER6 + * @arg @ref LL_MPU_REGION_NUMBER7 + * @param BaseAddress Value of region base address + * @note cortex-M33 supports 8 non secure regions. + * @retval None + */ +__STATIC_INLINE void LL_MPU_SetRegionBaseAddress_NS(uint32_t Region, uint32_t BaseAddress) +{ + /* Set Region number */ + WRITE_REG(MPU_NS->RNR, Region); + + /* Set base address */ + MODIFY_REG(MPU_NS->RBAR, MPU_RBAR_BASE_Msk, (BaseAddress & MPU_RBAR_BASE_Msk)); +} + +/** + * @brief Get a non-secure MPU region base address + * @rmtoll MPU_RNR REGION LL_MPU_GetRegionBaseAddress_NS\n + * @param Region This parameter can be one of the following values: + * @arg @ref LL_MPU_REGION_NUMBER0 + * @arg @ref LL_MPU_REGION_NUMBER1 + * @arg @ref LL_MPU_REGION_NUMBER2 + * @arg @ref LL_MPU_REGION_NUMBER3 + * @arg @ref LL_MPU_REGION_NUMBER4 + * @arg @ref LL_MPU_REGION_NUMBER5 + * @arg @ref LL_MPU_REGION_NUMBER6 + * @arg @ref LL_MPU_REGION_NUMBER7 + * @retval Value of the region base address. + */ +__STATIC_INLINE uint32_t LL_MPU_GetRegionBaseAddress_NS(uint32_t Region) +{ + /* Set Region number */ + WRITE_REG(MPU_NS->RNR, Region); + + return (READ_REG(MPU_NS->RBAR & MPU_RBAR_BASE_Msk)); +} + +/** + * @brief Configure a non-secure MPU region access attributes and enable a region + * @rmtoll MPU_RNR REGION LL_MPU_SetRegionAccess_NS\n + * MPU_RBAR XN LL_MPU_SetRegionAccess_NS\n + * MPU_RBAR AP LL_MPU_SetRegionAccess_NS\n + * MPU_RBAR SH LL_MPU_SetRegionAccess_NS\n + * @param Region This parameter can be one of the following values: + * @arg @ref LL_MPU_REGION_NUMBER0 + * @arg @ref LL_MPU_REGION_NUMBER1 + * @arg @ref LL_MPU_REGION_NUMBER2 + * @arg @ref LL_MPU_REGION_NUMBER3 + * @arg @ref LL_MPU_REGION_NUMBER4 + * @arg @ref LL_MPU_REGION_NUMBER5 + * @arg @ref LL_MPU_REGION_NUMBER6 + * @arg @ref LL_MPU_REGION_NUMBER7 + * @param Attributes This parameter can be a combination of the following values: + * @arg @ref LL_MPU_INSTRUCTION_ACCESS_ENABLE or @ref LL_MPU_INSTRUCTION_ACCESS_DISABLE + * @arg @ref LL_MPU_ACCESS_NOT_SHAREABLE or @ref LL_MPU_ACCESS_OUTER_SHAREABLE + * or @ref LL_MPU_ACCESS_INNER_SHAREABLE + * @arg @ref LL_MPU_REGION_PRIV_RW or @ref LL_MPU_REGION_ALL_RW or @ref LL_MPU_REGION_PRIV_RO + * or @ref LL_MPU_REGION_ALL_RO + * @note cortex-M33 supports 8 non secure regions. + * @retval None + */ +__STATIC_INLINE void LL_MPU_SetRegionAccess_NS(uint32_t Region, uint32_t Attributes) +{ + /* Set Region number */ + WRITE_REG(MPU_NS->RNR, Region); + + /* Set base address Attributes */ + MODIFY_REG(MPU_NS->RBAR, MPU_ACCESS_MSK, (Attributes & MPU_ACCESS_MSK)); +} + +/** + * @brief Get a non-secure MPU region access attributes + * @rmtoll MPU_RNR REGION LL_MPU_GetRegionAccess_NS\n + * MPU_RBAR XN LL_MPU_GetRegionAccess_NS\n + * MPU_RBAR AP LL_MPU_GetRegionAccess_NS\n + * MPU_RBAR SH LL_MPU_GetRegionAccess_NS\n + * @param Region This parameter can be one of the following values: + * @arg @ref LL_MPU_REGION_NUMBER0 + * @arg @ref LL_MPU_REGION_NUMBER1 + * @arg @ref LL_MPU_REGION_NUMBER2 + * @arg @ref LL_MPU_REGION_NUMBER3 + * @arg @ref LL_MPU_REGION_NUMBER4 + * @arg @ref LL_MPU_REGION_NUMBER5 + * @arg @ref LL_MPU_REGION_NUMBER6 + * @arg @ref LL_MPU_REGION_NUMBER7 + * @retval return a combination of the following values: + * @arg @ref LL_MPU_INSTRUCTION_ACCESS_ENABLE or @ref LL_MPU_INSTRUCTION_ACCESS_DISABLE + * @arg @ref LL_MPU_ACCESS_NOT_SHAREABLE or @ref LL_MPU_ACCESS_OUTER_SHAREABLE + * or @ref LL_MPU_ACCESS_INNER_SHAREABLE + * @arg @ref LL_MPU_REGION_PRIV_RW or @ref LL_MPU_REGION_ALL_RW or @ref LL_MPU_REGION_PRIV_RO + * or @ref LL_MPU_REGION_ALL_RO + */ +__STATIC_INLINE uint32_t LL_MPU_GetRegionAccess_NS(uint32_t Region) +{ + /* Set Region number */ + WRITE_REG(MPU_NS->RNR, Region); + + return (READ_REG(MPU_NS->RBAR & (MPU_RBAR_XN_Msk | MPU_RBAR_AP_Msk | MPU_RBAR_SH_Msk))); +} +#endif /* __ARM_FEATURE_CMSE */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_LL_CORTEX_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_crc.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_crc.h new file mode 100644 index 0000000000..3838cd3f56 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_crc.h @@ -0,0 +1,461 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_crc.h + * @author MCD Application Team + * @brief Header file of CRC LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_LL_CRC_H +#define STM32H5xx_LL_CRC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined(CRC) + +/** @defgroup CRC_LL CRC + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup CRC_LL_Exported_Constants CRC Exported Constants + * @{ + */ + +/** @defgroup CRC_LL_EC_POLYLENGTH Polynomial length + * @{ + */ +#define LL_CRC_POLYLENGTH_32B 0x00000000U /*!< 32 bits Polynomial size */ +#define LL_CRC_POLYLENGTH_16B CRC_CR_POLYSIZE_0 /*!< 16 bits Polynomial size */ +#define LL_CRC_POLYLENGTH_8B CRC_CR_POLYSIZE_1 /*!< 8 bits Polynomial size */ +#define LL_CRC_POLYLENGTH_7B (CRC_CR_POLYSIZE_1 | CRC_CR_POLYSIZE_0) /*!< 7 bits Polynomial size */ +/** + * @} + */ + +/** @defgroup CRC_LL_EC_INDATA_REVERSE Input Data Reverse + * @{ + */ +#define LL_CRC_INDATA_REVERSE_NONE 0x00000000U /*!< Input Data bit order not affected */ +#define LL_CRC_INDATA_REVERSE_BYTE CRC_CR_REV_IN_0 /*!< Input Data bit reversal done by byte */ +#define LL_CRC_INDATA_REVERSE_HALFWORD CRC_CR_REV_IN_1 /*!< Input Data bit reversal done by half-word */ +#define LL_CRC_INDATA_REVERSE_WORD (CRC_CR_REV_IN_1 | CRC_CR_REV_IN_0) /*!< Input Data bit reversal done by word */ +/** + * @} + */ + +/** @defgroup CRC_LL_EC_OUTDATA_REVERSE Output Data Reverse + * @{ + */ +#define LL_CRC_OUTDATA_REVERSE_NONE 0x00000000U /*!< Output Data bit order not affected */ +#define LL_CRC_OUTDATA_REVERSE_BIT CRC_CR_REV_OUT /*!< Output Data bit reversal done by bit */ +/** + * @} + */ + +/** @defgroup CRC_LL_EC_Default_Polynomial_Value Default CRC generating polynomial value + * @brief Normal representation of this polynomial value is + * X^32 + X^26 + X^23 + X^22 + X^16 + X^12 + X^11 + X^10 +X^8 + X^7 + X^5 + X^4 + X^2 + X + 1 . + * @{ + */ +#define LL_CRC_DEFAULT_CRC32_POLY 0x04C11DB7U /*!< Default CRC generating polynomial value */ +/** + * @} + */ + +/** @defgroup CRC_LL_EC_Default_InitValue Default CRC computation initialization value + * @{ + */ +#define LL_CRC_DEFAULT_CRC_INITVALUE 0xFFFFFFFFU /*!< Default CRC computation initialization value */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup CRC_LL_Exported_Macros CRC Exported Macros + * @{ + */ + +/** @defgroup CRC_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in CRC register + * @param __INSTANCE__ CRC Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_CRC_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, __VALUE__) + +/** + * @brief Read a value in CRC register + * @param __INSTANCE__ CRC Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_CRC_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) +/** + * @} + */ + +/** + * @} + */ + + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup CRC_LL_Exported_Functions CRC Exported Functions + * @{ + */ + +/** @defgroup CRC_LL_EF_Configuration CRC Configuration functions + * @{ + */ + +/** + * @brief Reset the CRC calculation unit. + * @note If Programmable Initial CRC value feature + * is available, also set the Data Register to the value stored in the + * CRC_INIT register, otherwise, reset Data Register to its default value. + * @rmtoll CR RESET LL_CRC_ResetCRCCalculationUnit + * @param CRCx CRC Instance + * @retval None + */ +__STATIC_INLINE void LL_CRC_ResetCRCCalculationUnit(CRC_TypeDef *CRCx) +{ + SET_BIT(CRCx->CR, CRC_CR_RESET); +} + +/** + * @brief Configure size of the polynomial. + * @rmtoll CR POLYSIZE LL_CRC_SetPolynomialSize + * @param CRCx CRC Instance + * @param PolySize This parameter can be one of the following values: + * @arg @ref LL_CRC_POLYLENGTH_32B + * @arg @ref LL_CRC_POLYLENGTH_16B + * @arg @ref LL_CRC_POLYLENGTH_8B + * @arg @ref LL_CRC_POLYLENGTH_7B + * @retval None + */ +__STATIC_INLINE void LL_CRC_SetPolynomialSize(CRC_TypeDef *CRCx, uint32_t PolySize) +{ + MODIFY_REG(CRCx->CR, CRC_CR_POLYSIZE, PolySize); +} + +/** + * @brief Return size of the polynomial. + * @rmtoll CR POLYSIZE LL_CRC_GetPolynomialSize + * @param CRCx CRC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_CRC_POLYLENGTH_32B + * @arg @ref LL_CRC_POLYLENGTH_16B + * @arg @ref LL_CRC_POLYLENGTH_8B + * @arg @ref LL_CRC_POLYLENGTH_7B + */ +__STATIC_INLINE uint32_t LL_CRC_GetPolynomialSize(const CRC_TypeDef *CRCx) +{ + return (uint32_t)(READ_BIT(CRCx->CR, CRC_CR_POLYSIZE)); +} + +/** + * @brief Configure the reversal of the bit order of the input data + * @rmtoll CR REV_IN LL_CRC_SetInputDataReverseMode + * @param CRCx CRC Instance + * @param ReverseMode This parameter can be one of the following values: + * @arg @ref LL_CRC_INDATA_REVERSE_NONE + * @arg @ref LL_CRC_INDATA_REVERSE_BYTE + * @arg @ref LL_CRC_INDATA_REVERSE_HALFWORD + * @arg @ref LL_CRC_INDATA_REVERSE_WORD + * @retval None + */ +__STATIC_INLINE void LL_CRC_SetInputDataReverseMode(CRC_TypeDef *CRCx, uint32_t ReverseMode) +{ + MODIFY_REG(CRCx->CR, CRC_CR_REV_IN, ReverseMode); +} + +/** + * @brief Return type of reversal for input data bit order + * @rmtoll CR REV_IN LL_CRC_GetInputDataReverseMode + * @param CRCx CRC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_CRC_INDATA_REVERSE_NONE + * @arg @ref LL_CRC_INDATA_REVERSE_BYTE + * @arg @ref LL_CRC_INDATA_REVERSE_HALFWORD + * @arg @ref LL_CRC_INDATA_REVERSE_WORD + */ +__STATIC_INLINE uint32_t LL_CRC_GetInputDataReverseMode(const CRC_TypeDef *CRCx) +{ + return (uint32_t)(READ_BIT(CRCx->CR, CRC_CR_REV_IN)); +} + +/** + * @brief Configure the reversal of the bit order of the Output data + * @rmtoll CR REV_OUT LL_CRC_SetOutputDataReverseMode + * @param CRCx CRC Instance + * @param ReverseMode This parameter can be one of the following values: + * @arg @ref LL_CRC_OUTDATA_REVERSE_NONE + * @arg @ref LL_CRC_OUTDATA_REVERSE_BIT + * @retval None + */ +__STATIC_INLINE void LL_CRC_SetOutputDataReverseMode(CRC_TypeDef *CRCx, uint32_t ReverseMode) +{ + MODIFY_REG(CRCx->CR, CRC_CR_REV_OUT, ReverseMode); +} + +/** + * @brief Return type of reversal of the bit order of the Output data + * @rmtoll CR REV_OUT LL_CRC_GetOutputDataReverseMode + * @param CRCx CRC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_CRC_OUTDATA_REVERSE_NONE + * @arg @ref LL_CRC_OUTDATA_REVERSE_BIT + */ +__STATIC_INLINE uint32_t LL_CRC_GetOutputDataReverseMode(const CRC_TypeDef *CRCx) +{ + return (uint32_t)(READ_BIT(CRCx->CR, CRC_CR_REV_OUT)); +} + +/** + * @brief Initialize the Programmable initial CRC value. + * @note If the CRC size is less than 32 bits, the least significant bits + * are used to write the correct value + * @note LL_CRC_DEFAULT_CRC_INITVALUE could be used as value for InitCrc parameter. + * @rmtoll INIT INIT LL_CRC_SetInitialData + * @param CRCx CRC Instance + * @param InitCrc Value to be programmed in Programmable initial CRC value register + * @retval None + */ +__STATIC_INLINE void LL_CRC_SetInitialData(CRC_TypeDef *CRCx, uint32_t InitCrc) +{ + WRITE_REG(CRCx->INIT, InitCrc); +} + +/** + * @brief Return current Initial CRC value. + * @note If the CRC size is less than 32 bits, the least significant bits + * are used to read the correct value + * @rmtoll INIT INIT LL_CRC_GetInitialData + * @param CRCx CRC Instance + * @retval Value programmed in Programmable initial CRC value register + */ +__STATIC_INLINE uint32_t LL_CRC_GetInitialData(const CRC_TypeDef *CRCx) +{ + return (uint32_t)(READ_REG(CRCx->INIT)); +} + +/** + * @brief Initialize the Programmable polynomial value + * (coefficients of the polynomial to be used for CRC calculation). + * @note LL_CRC_DEFAULT_CRC32_POLY could be used as value for PolynomCoef parameter. + * @note Please check Reference Manual and existing Errata Sheets, + * regarding possible limitations for Polynomial values usage. + * For example, for a polynomial of degree 7, X^7 + X^6 + X^5 + X^2 + 1 is written 0x65 + * @rmtoll POL POL LL_CRC_SetPolynomialCoef + * @param CRCx CRC Instance + * @param PolynomCoef Value to be programmed in Programmable Polynomial value register + * @retval None + */ +__STATIC_INLINE void LL_CRC_SetPolynomialCoef(CRC_TypeDef *CRCx, uint32_t PolynomCoef) +{ + WRITE_REG(CRCx->POL, PolynomCoef); +} + +/** + * @brief Return current Programmable polynomial value + * @note Please check Reference Manual and existing Errata Sheets, + * regarding possible limitations for Polynomial values usage. + * For example, for a polynomial of degree 7, X^7 + X^6 + X^5 + X^2 + 1 is written 0x65 + * @rmtoll POL POL LL_CRC_GetPolynomialCoef + * @param CRCx CRC Instance + * @retval Value programmed in Programmable Polynomial value register + */ +__STATIC_INLINE uint32_t LL_CRC_GetPolynomialCoef(const CRC_TypeDef *CRCx) +{ + return (uint32_t)(READ_REG(CRCx->POL)); +} + +/** + * @} + */ + +/** @defgroup CRC_LL_EF_Data_Management Data_Management + * @{ + */ + +/** + * @brief Write given 32-bit data to the CRC calculator + * @rmtoll DR DR LL_CRC_FeedData32 + * @param CRCx CRC Instance + * @param InData value to be provided to CRC calculator between between Min_Data=0 and Max_Data=0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void LL_CRC_FeedData32(CRC_TypeDef *CRCx, uint32_t InData) +{ + WRITE_REG(CRCx->DR, InData); +} + +/** + * @brief Write given 16-bit data to the CRC calculator + * @rmtoll DR DR LL_CRC_FeedData16 + * @param CRCx CRC Instance + * @param InData 16 bit value to be provided to CRC calculator between between Min_Data=0 and Max_Data=0xFFFF + * @retval None + */ +__STATIC_INLINE void LL_CRC_FeedData16(CRC_TypeDef *CRCx, uint16_t InData) +{ + __IO uint16_t *pReg; + + pReg = (__IO uint16_t *)(__IO void *)(&CRCx->DR); /* Derogation MisraC2012 R.11.5 */ + *pReg = InData; +} + +/** + * @brief Write given 8-bit data to the CRC calculator + * @rmtoll DR DR LL_CRC_FeedData8 + * @param CRCx CRC Instance + * @param InData 8 bit value to be provided to CRC calculator between between Min_Data=0 and Max_Data=0xFF + * @retval None + */ +__STATIC_INLINE void LL_CRC_FeedData8(CRC_TypeDef *CRCx, uint8_t InData) +{ + *(uint8_t __IO *)(&CRCx->DR) = (uint8_t) InData; +} + +/** + * @brief Return current CRC calculation result. 32 bits value is returned. + * @rmtoll DR DR LL_CRC_ReadData32 + * @param CRCx CRC Instance + * @retval Current CRC calculation result as stored in CRC_DR register (32 bits). + */ +__STATIC_INLINE uint32_t LL_CRC_ReadData32(const CRC_TypeDef *CRCx) +{ + return (uint32_t)(READ_REG(CRCx->DR)); +} + +/** + * @brief Return current CRC calculation result. 16 bits value is returned. + * @note This function is expected to be used in a 16 bits CRC polynomial size context. + * @rmtoll DR DR LL_CRC_ReadData16 + * @param CRCx CRC Instance + * @retval Current CRC calculation result as stored in CRC_DR register (16 bits). + */ +__STATIC_INLINE uint16_t LL_CRC_ReadData16(const CRC_TypeDef *CRCx) +{ + return (uint16_t)READ_REG(CRCx->DR); +} + +/** + * @brief Return current CRC calculation result. 8 bits value is returned. + * @note This function is expected to be used in a 8 bits CRC polynomial size context. + * @rmtoll DR DR LL_CRC_ReadData8 + * @param CRCx CRC Instance + * @retval Current CRC calculation result as stored in CRC_DR register (8 bits). + */ +__STATIC_INLINE uint8_t LL_CRC_ReadData8(const CRC_TypeDef *CRCx) +{ + return (uint8_t)READ_REG(CRCx->DR); +} + +/** + * @brief Return current CRC calculation result. 7 bits value is returned. + * @note This function is expected to be used in a 7 bits CRC polynomial size context. + * @rmtoll DR DR LL_CRC_ReadData7 + * @param CRCx CRC Instance + * @retval Current CRC calculation result as stored in CRC_DR register (7 bits). + */ +__STATIC_INLINE uint8_t LL_CRC_ReadData7(const CRC_TypeDef *CRCx) +{ + return (uint8_t)(READ_REG(CRCx->DR) & 0x7FU); +} + +/** + * @brief Return data stored in the Independent Data(IDR) register. + * @note This register can be used as a temporary storage location for one 32-bit long data. + * @rmtoll IDR IDR LL_CRC_Read_IDR + * @param CRCx CRC Instance + * @retval Value stored in CRC_IDR register (General-purpose 32-bit data register). + */ +__STATIC_INLINE uint32_t LL_CRC_Read_IDR(const CRC_TypeDef *CRCx) +{ + return (uint32_t)(READ_REG(CRCx->IDR)); +} + +/** + * @brief Store data in the Independent Data(IDR) register. + * @note This register can be used as a temporary storage location for one 32-bit long data. + * @rmtoll IDR IDR LL_CRC_Write_IDR + * @param CRCx CRC Instance + * @param InData value to be stored in CRC_IDR register (32-bit) between Min_Data=0 and Max_Data=0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void LL_CRC_Write_IDR(CRC_TypeDef *CRCx, uint32_t InData) +{ + *((uint32_t __IO *)(&CRCx->IDR)) = (uint32_t) InData; +} +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup CRC_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +ErrorStatus LL_CRC_DeInit(const CRC_TypeDef *CRCx); + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined(CRC) */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_LL_CRC_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_crs.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_crs.h new file mode 100644 index 0000000000..915e7b5095 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_crs.h @@ -0,0 +1,797 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_crs.h + * @author MCD Application Team + * @brief Header file of CRS LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_LL_CRS_H +#define STM32H5xx_LL_CRS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined(CRS) + +/** @defgroup CRS_LL CRS + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup CRS_LL_Private_Constants CRS Private Constants + * @{ + */ + +/* Defines used for the bit position in the register and perform offsets*/ +#define CRS_POSITION_TRIM (CRS_CR_TRIM_Pos) /* bit position in CR reg */ +#define CRS_POSITION_FECAP (CRS_ISR_FECAP_Pos) /* bit position in ISR reg */ +#define CRS_POSITION_FELIM (CRS_CFGR_FELIM_Pos) /* bit position in CFGR reg */ + + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup CRS_LL_Exported_Constants CRS Exported Constants + * @{ + */ + +/** @defgroup CRS_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_CRS_ReadReg function + * @{ + */ +#define LL_CRS_ISR_SYNCOKF CRS_ISR_SYNCOKF +#define LL_CRS_ISR_SYNCWARNF CRS_ISR_SYNCWARNF +#define LL_CRS_ISR_ERRF CRS_ISR_ERRF +#define LL_CRS_ISR_ESYNCF CRS_ISR_ESYNCF +#define LL_CRS_ISR_SYNCERR CRS_ISR_SYNCERR +#define LL_CRS_ISR_SYNCMISS CRS_ISR_SYNCMISS +#define LL_CRS_ISR_TRIMOVF CRS_ISR_TRIMOVF +/** + * @} + */ + +/** @defgroup CRS_LL_EC_IT IT Defines + * @brief IT defines which can be used with LL_CRS_ReadReg and LL_CRS_WriteReg functions + * @{ + */ +#define LL_CRS_CR_SYNCOKIE CRS_CR_SYNCOKIE +#define LL_CRS_CR_SYNCWARNIE CRS_CR_SYNCWARNIE +#define LL_CRS_CR_ERRIE CRS_CR_ERRIE +#define LL_CRS_CR_ESYNCIE CRS_CR_ESYNCIE +/** + * @} + */ + +/** @defgroup CRS_LL_EC_SYNC_DIV Synchronization Signal Divider + * @{ + */ +#define LL_CRS_SYNC_DIV_1 0x00000000U /*!< Synchro Signal not divided (default) */ +#define LL_CRS_SYNC_DIV_2 CRS_CFGR_SYNCDIV_0 /*!< Synchro Signal divided by 2 */ +#define LL_CRS_SYNC_DIV_4 CRS_CFGR_SYNCDIV_1 /*!< Synchro Signal divided by 4 */ +#define LL_CRS_SYNC_DIV_8 (CRS_CFGR_SYNCDIV_1 | CRS_CFGR_SYNCDIV_0) /*!< Synchro Signal divided by 8 */ +#define LL_CRS_SYNC_DIV_16 CRS_CFGR_SYNCDIV_2 /*!< Synchro Signal divided by 16 */ +#define LL_CRS_SYNC_DIV_32 (CRS_CFGR_SYNCDIV_2 | CRS_CFGR_SYNCDIV_0) /*!< Synchro Signal divided by 32 */ +#define LL_CRS_SYNC_DIV_64 (CRS_CFGR_SYNCDIV_2 | CRS_CFGR_SYNCDIV_1) /*!< Synchro Signal divided by 64 */ +#define LL_CRS_SYNC_DIV_128 CRS_CFGR_SYNCDIV /*!< Synchro Signal divided by 128 */ +/** + * @} + */ + +/** @defgroup CRS_LL_EC_SYNC_SOURCE Synchronization Signal Source + * @{ + */ +#define LL_CRS_SYNC_SOURCE_GPIO 0x00000000U /*!< Synchro Signal source GPIO */ +#define LL_CRS_SYNC_SOURCE_LSE CRS_CFGR_SYNCSRC_0 /*!< Synchro Signal source LSE */ +#define LL_CRS_SYNC_SOURCE_USB CRS_CFGR_SYNCSRC_1 /*!< Synchro Signal source USB SOF (default)*/ +/** + * @} + */ + +/** @defgroup CRS_LL_EC_SYNC_POLARITY Synchronization Signal Polarity + * @{ + */ +#define LL_CRS_SYNC_POLARITY_RISING 0x00000000U /*!< Synchro Active on rising edge (default) */ +#define LL_CRS_SYNC_POLARITY_FALLING CRS_CFGR_SYNCPOL /*!< Synchro Active on falling edge */ +/** + * @} + */ + +/** @defgroup CRS_LL_EC_FREQERRORDIR Frequency Error Direction + * @{ + */ +#define LL_CRS_FREQ_ERROR_DIR_UP 0x00000000U /*!< Upcounting direction, the actual frequency is above the target */ +#define LL_CRS_FREQ_ERROR_DIR_DOWN CRS_ISR_FEDIR /*!< Downcounting direction, the actual frequency is below the target */ +/** + * @} + */ + +/** @defgroup CRS_LL_EC_DEFAULTVALUES Default Values + * @{ + */ +/** + * @brief Reset value of the RELOAD field + * @note The reset value of the RELOAD field corresponds to a target frequency of 48 MHz + * and a synchronization signal frequency of 1 kHz (SOF signal from USB) + */ +#define LL_CRS_RELOADVALUE_DEFAULT 0x0000BB7FU + +/** + * @brief Reset value of Frequency error limit. + */ +#define LL_CRS_ERRORLIMIT_DEFAULT 0x00000022U + +/** + * @brief Reset value of the HSI48 Calibration field + * @note The default value is 32, which corresponds to the middle of the trimming interval. + * The trimming step is specified in the product datasheet. + * A higher TRIM value corresponds to a higher output frequency. + */ +#define LL_CRS_HSI48CALIBRATION_DEFAULT 0x00000020U +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup CRS_LL_Exported_Macros CRS Exported Macros + * @{ + */ + +/** @defgroup CRS_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in CRS register + * @param __INSTANCE__ CRS Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_CRS_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in CRS register + * @param __INSTANCE__ CRS Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_CRS_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) +/** + * @} + */ + +/** @defgroup CRS_LL_EM_Exported_Macros_Calculate_Reload Exported_Macros_Calculate_Reload + * @{ + */ + +/** + * @brief Macro to calculate reload value to be set in CRS register according to target and sync frequencies + * @note The RELOAD value should be selected according to the ratio between + * the target frequency and the frequency of the synchronization source after + * prescaling. It is then decreased by one in order to reach the expected + * synchronization on the zero value. The formula is the following: + * RELOAD = (fTARGET / fSYNC) -1 + * @param __FTARGET__ Target frequency (value in Hz) + * @param __FSYNC__ Synchronization signal frequency (value in Hz) + * @retval Reload value (in Hz) + */ +#define __LL_CRS_CALC_CALCULATE_RELOADVALUE(__FTARGET__, __FSYNC__) (((__FTARGET__) / (__FSYNC__)) - 1U) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup CRS_LL_Exported_Functions CRS Exported Functions + * @{ + */ + +/** @defgroup CRS_LL_EF_Configuration Configuration + * @{ + */ + +/** + * @brief Enable Frequency error counter + * @note When this bit is set, the CRS_CFGR register is write-protected and cannot be modified + * @rmtoll CR CEN LL_CRS_EnableFreqErrorCounter + * @retval None + */ +__STATIC_INLINE void LL_CRS_EnableFreqErrorCounter(void) +{ + SET_BIT(CRS->CR, CRS_CR_CEN); +} + +/** + * @brief Disable Frequency error counter + * @rmtoll CR CEN LL_CRS_DisableFreqErrorCounter + * @retval None + */ +__STATIC_INLINE void LL_CRS_DisableFreqErrorCounter(void) +{ + CLEAR_BIT(CRS->CR, CRS_CR_CEN); +} + +/** + * @brief Check if Frequency error counter is enabled or not + * @rmtoll CR CEN LL_CRS_IsEnabledFreqErrorCounter + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_CRS_IsEnabledFreqErrorCounter(void) +{ + return ((READ_BIT(CRS->CR, CRS_CR_CEN) == (CRS_CR_CEN)) ? 1UL : 0UL); +} + +/** + * @brief Enable Automatic trimming counter + * @rmtoll CR AUTOTRIMEN LL_CRS_EnableAutoTrimming + * @retval None + */ +__STATIC_INLINE void LL_CRS_EnableAutoTrimming(void) +{ + SET_BIT(CRS->CR, CRS_CR_AUTOTRIMEN); +} + +/** + * @brief Disable Automatic trimming counter + * @rmtoll CR AUTOTRIMEN LL_CRS_DisableAutoTrimming + * @retval None + */ +__STATIC_INLINE void LL_CRS_DisableAutoTrimming(void) +{ + CLEAR_BIT(CRS->CR, CRS_CR_AUTOTRIMEN); +} + +/** + * @brief Check if Automatic trimming is enabled or not + * @rmtoll CR AUTOTRIMEN LL_CRS_IsEnabledAutoTrimming + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_CRS_IsEnabledAutoTrimming(void) +{ + return ((READ_BIT(CRS->CR, CRS_CR_AUTOTRIMEN) == (CRS_CR_AUTOTRIMEN)) ? 1UL : 0UL); +} + +/** + * @brief Set HSI48 oscillator smooth trimming + * @note When the AUTOTRIMEN bit is set, this field is controlled by hardware and is read-only + * @rmtoll CR TRIM LL_CRS_SetHSI48SmoothTrimming + * @param Value a number between Min_Data = 0 and Max_Data = 63 + * @note Default value can be set thanks to @ref LL_CRS_HSI48CALIBRATION_DEFAULT + * @retval None + */ +__STATIC_INLINE void LL_CRS_SetHSI48SmoothTrimming(uint32_t Value) +{ + MODIFY_REG(CRS->CR, CRS_CR_TRIM, Value << CRS_POSITION_TRIM); +} + +/** + * @brief Get HSI48 oscillator smooth trimming + * @rmtoll CR TRIM LL_CRS_GetHSI48SmoothTrimming + * @retval a number between Min_Data = 0 and Max_Data = 63 + */ +__STATIC_INLINE uint32_t LL_CRS_GetHSI48SmoothTrimming(void) +{ + return (uint32_t)(READ_BIT(CRS->CR, CRS_CR_TRIM) >> CRS_POSITION_TRIM); +} + +/** + * @brief Set counter reload value + * @rmtoll CFGR RELOAD LL_CRS_SetReloadCounter + * @param Value a number between Min_Data = 0 and Max_Data = 0xFFFF + * @note Default value can be set thanks to @ref LL_CRS_RELOADVALUE_DEFAULT + * Otherwise it can be calculated in using macro @ref __LL_CRS_CALC_CALCULATE_RELOADVALUE (_FTARGET_, _FSYNC_) + * @retval None + */ +__STATIC_INLINE void LL_CRS_SetReloadCounter(uint32_t Value) +{ + MODIFY_REG(CRS->CFGR, CRS_CFGR_RELOAD, Value); +} + +/** + * @brief Get counter reload value + * @rmtoll CFGR RELOAD LL_CRS_GetReloadCounter + * @retval a number between Min_Data = 0 and Max_Data = 0xFFFF + */ +__STATIC_INLINE uint32_t LL_CRS_GetReloadCounter(void) +{ + return (uint32_t)(READ_BIT(CRS->CFGR, CRS_CFGR_RELOAD)); +} + +/** + * @brief Set frequency error limit + * @rmtoll CFGR FELIM LL_CRS_SetFreqErrorLimit + * @param Value a number between Min_Data = 0 and Max_Data = 255 + * @note Default value can be set thanks to @ref LL_CRS_ERRORLIMIT_DEFAULT + * @retval None + */ +__STATIC_INLINE void LL_CRS_SetFreqErrorLimit(uint32_t Value) +{ + MODIFY_REG(CRS->CFGR, CRS_CFGR_FELIM, Value << CRS_POSITION_FELIM); +} + +/** + * @brief Get frequency error limit + * @rmtoll CFGR FELIM LL_CRS_GetFreqErrorLimit + * @retval A number between Min_Data = 0 and Max_Data = 255 + */ +__STATIC_INLINE uint32_t LL_CRS_GetFreqErrorLimit(void) +{ + return (uint32_t)(READ_BIT(CRS->CFGR, CRS_CFGR_FELIM) >> CRS_POSITION_FELIM); +} + +/** + * @brief Set division factor for SYNC signal + * @rmtoll CFGR SYNCDIV LL_CRS_SetSyncDivider + * @param Divider This parameter can be one of the following values: + * @arg @ref LL_CRS_SYNC_DIV_1 + * @arg @ref LL_CRS_SYNC_DIV_2 + * @arg @ref LL_CRS_SYNC_DIV_4 + * @arg @ref LL_CRS_SYNC_DIV_8 + * @arg @ref LL_CRS_SYNC_DIV_16 + * @arg @ref LL_CRS_SYNC_DIV_32 + * @arg @ref LL_CRS_SYNC_DIV_64 + * @arg @ref LL_CRS_SYNC_DIV_128 + * @retval None + */ +__STATIC_INLINE void LL_CRS_SetSyncDivider(uint32_t Divider) +{ + MODIFY_REG(CRS->CFGR, CRS_CFGR_SYNCDIV, Divider); +} + +/** + * @brief Get division factor for SYNC signal + * @rmtoll CFGR SYNCDIV LL_CRS_GetSyncDivider + * @retval Returned value can be one of the following values: + * @arg @ref LL_CRS_SYNC_DIV_1 + * @arg @ref LL_CRS_SYNC_DIV_2 + * @arg @ref LL_CRS_SYNC_DIV_4 + * @arg @ref LL_CRS_SYNC_DIV_8 + * @arg @ref LL_CRS_SYNC_DIV_16 + * @arg @ref LL_CRS_SYNC_DIV_32 + * @arg @ref LL_CRS_SYNC_DIV_64 + * @arg @ref LL_CRS_SYNC_DIV_128 + */ +__STATIC_INLINE uint32_t LL_CRS_GetSyncDivider(void) +{ + return (uint32_t)(READ_BIT(CRS->CFGR, CRS_CFGR_SYNCDIV)); +} + +/** + * @brief Set SYNC signal source + * @rmtoll CFGR SYNCSRC LL_CRS_SetSyncSignalSource + * @param Source This parameter can be one of the following values: + * @arg @ref LL_CRS_SYNC_SOURCE_GPIO + * @arg @ref LL_CRS_SYNC_SOURCE_LSE + * @arg @ref LL_CRS_SYNC_SOURCE_USB + * @retval None + */ +__STATIC_INLINE void LL_CRS_SetSyncSignalSource(uint32_t Source) +{ + MODIFY_REG(CRS->CFGR, CRS_CFGR_SYNCSRC, Source); +} + +/** + * @brief Get SYNC signal source + * @rmtoll CFGR SYNCSRC LL_CRS_GetSyncSignalSource + * @retval Returned value can be one of the following values: + * @arg @ref LL_CRS_SYNC_SOURCE_GPIO + * @arg @ref LL_CRS_SYNC_SOURCE_LSE + * @arg @ref LL_CRS_SYNC_SOURCE_USB + */ +__STATIC_INLINE uint32_t LL_CRS_GetSyncSignalSource(void) +{ + return (uint32_t)(READ_BIT(CRS->CFGR, CRS_CFGR_SYNCSRC)); +} + +/** + * @brief Set input polarity for the SYNC signal source + * @rmtoll CFGR SYNCPOL LL_CRS_SetSyncPolarity + * @param Polarity This parameter can be one of the following values: + * @arg @ref LL_CRS_SYNC_POLARITY_RISING + * @arg @ref LL_CRS_SYNC_POLARITY_FALLING + * @retval None + */ +__STATIC_INLINE void LL_CRS_SetSyncPolarity(uint32_t Polarity) +{ + MODIFY_REG(CRS->CFGR, CRS_CFGR_SYNCPOL, Polarity); +} + +/** + * @brief Get input polarity for the SYNC signal source + * @rmtoll CFGR SYNCPOL LL_CRS_GetSyncPolarity + * @retval Returned value can be one of the following values: + * @arg @ref LL_CRS_SYNC_POLARITY_RISING + * @arg @ref LL_CRS_SYNC_POLARITY_FALLING + */ +__STATIC_INLINE uint32_t LL_CRS_GetSyncPolarity(void) +{ + return (uint32_t)(READ_BIT(CRS->CFGR, CRS_CFGR_SYNCPOL)); +} + +/** + * @brief Configure CRS for the synchronization + * @rmtoll CR TRIM LL_CRS_ConfigSynchronization\n + * CFGR RELOAD LL_CRS_ConfigSynchronization\n + * CFGR FELIM LL_CRS_ConfigSynchronization\n + * CFGR SYNCDIV LL_CRS_ConfigSynchronization\n + * CFGR SYNCSRC LL_CRS_ConfigSynchronization\n + * CFGR SYNCPOL LL_CRS_ConfigSynchronization + * @param HSI48CalibrationValue a number between Min_Data = 0 and Max_Data = 63 + * @param ErrorLimitValue a number between Min_Data = 0 and Max_Data = 0xFFFF + * @param ReloadValue a number between Min_Data = 0 and Max_Data = 255 + * @param Settings This parameter can be a combination of the following values: + * @arg @ref LL_CRS_SYNC_DIV_1 or @ref LL_CRS_SYNC_DIV_2 or @ref LL_CRS_SYNC_DIV_4 or @ref LL_CRS_SYNC_DIV_8 + * or @ref LL_CRS_SYNC_DIV_16 or @ref LL_CRS_SYNC_DIV_32 or @ref LL_CRS_SYNC_DIV_64 + * or @ref LL_CRS_SYNC_DIV_128 + * @arg @ref LL_CRS_SYNC_SOURCE_GPIO or @ref LL_CRS_SYNC_SOURCE_LSE or @ref LL_CRS_SYNC_SOURCE_USB + * @arg @ref LL_CRS_SYNC_POLARITY_RISING or @ref LL_CRS_SYNC_POLARITY_FALLING + * @retval None + */ +__STATIC_INLINE void LL_CRS_ConfigSynchronization(uint32_t HSI48CalibrationValue, uint32_t ErrorLimitValue, + uint32_t ReloadValue, uint32_t Settings) +{ + MODIFY_REG(CRS->CR, CRS_CR_TRIM, HSI48CalibrationValue); + MODIFY_REG(CRS->CFGR, + CRS_CFGR_RELOAD | CRS_CFGR_FELIM | CRS_CFGR_SYNCDIV | CRS_CFGR_SYNCSRC | CRS_CFGR_SYNCPOL, + ReloadValue | (ErrorLimitValue << CRS_POSITION_FELIM) | Settings); +} + +/** + * @} + */ + +/** @defgroup CRS_LL_EF_CRS_Management CRS_Management + * @{ + */ + +/** + * @brief Generate software SYNC event + * @rmtoll CR SWSYNC LL_CRS_GenerateEvent_SWSYNC + * @retval None + */ +__STATIC_INLINE void LL_CRS_GenerateEvent_SWSYNC(void) +{ + SET_BIT(CRS->CR, CRS_CR_SWSYNC); +} + +/** + * @brief Get the frequency error direction latched in the time of the last + * SYNC event + * @rmtoll ISR FEDIR LL_CRS_GetFreqErrorDirection + * @retval Returned value can be one of the following values: + * @arg @ref LL_CRS_FREQ_ERROR_DIR_UP + * @arg @ref LL_CRS_FREQ_ERROR_DIR_DOWN + */ +__STATIC_INLINE uint32_t LL_CRS_GetFreqErrorDirection(void) +{ + return (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FEDIR)); +} + +/** + * @brief Get the frequency error counter value latched in the time of the last SYNC event + * @rmtoll ISR FECAP LL_CRS_GetFreqErrorCapture + * @retval A number between Min_Data = 0x0000 and Max_Data = 0xFFFF + */ +__STATIC_INLINE uint32_t LL_CRS_GetFreqErrorCapture(void) +{ + return (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FECAP) >> CRS_POSITION_FECAP); +} + +/** + * @} + */ + +/** @defgroup CRS_LL_EF_FLAG_Management FLAG_Management + * @{ + */ + +/** + * @brief Check if SYNC event OK signal occurred or not + * @rmtoll ISR SYNCOKF LL_CRS_IsActiveFlag_SYNCOK + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_CRS_IsActiveFlag_SYNCOK(void) +{ + return ((READ_BIT(CRS->ISR, CRS_ISR_SYNCOKF) == (CRS_ISR_SYNCOKF)) ? 1UL : 0UL); +} + +/** + * @brief Check if SYNC warning signal occurred or not + * @rmtoll ISR SYNCWARNF LL_CRS_IsActiveFlag_SYNCWARN + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_CRS_IsActiveFlag_SYNCWARN(void) +{ + return ((READ_BIT(CRS->ISR, CRS_ISR_SYNCWARNF) == (CRS_ISR_SYNCWARNF)) ? 1UL : 0UL); +} + +/** + * @brief Check if Synchronization or trimming error signal occurred or not + * @rmtoll ISR ERRF LL_CRS_IsActiveFlag_ERR + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_CRS_IsActiveFlag_ERR(void) +{ + return ((READ_BIT(CRS->ISR, CRS_ISR_ERRF) == (CRS_ISR_ERRF)) ? 1UL : 0UL); +} + +/** + * @brief Check if Expected SYNC signal occurred or not + * @rmtoll ISR ESYNCF LL_CRS_IsActiveFlag_ESYNC + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_CRS_IsActiveFlag_ESYNC(void) +{ + return ((READ_BIT(CRS->ISR, CRS_ISR_ESYNCF) == (CRS_ISR_ESYNCF)) ? 1UL : 0UL); +} + +/** + * @brief Check if SYNC error signal occurred or not + * @rmtoll ISR SYNCERR LL_CRS_IsActiveFlag_SYNCERR + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_CRS_IsActiveFlag_SYNCERR(void) +{ + return ((READ_BIT(CRS->ISR, CRS_ISR_SYNCERR) == (CRS_ISR_SYNCERR)) ? 1UL : 0UL); +} + +/** + * @brief Check if SYNC missed error signal occurred or not + * @rmtoll ISR SYNCMISS LL_CRS_IsActiveFlag_SYNCMISS + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_CRS_IsActiveFlag_SYNCMISS(void) +{ + return ((READ_BIT(CRS->ISR, CRS_ISR_SYNCMISS) == (CRS_ISR_SYNCMISS)) ? 1UL : 0UL); +} + +/** + * @brief Check if Trimming overflow or underflow occurred or not + * @rmtoll ISR TRIMOVF LL_CRS_IsActiveFlag_TRIMOVF + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_CRS_IsActiveFlag_TRIMOVF(void) +{ + return ((READ_BIT(CRS->ISR, CRS_ISR_TRIMOVF) == (CRS_ISR_TRIMOVF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the SYNC event OK flag + * @rmtoll ICR SYNCOKC LL_CRS_ClearFlag_SYNCOK + * @retval None + */ +__STATIC_INLINE void LL_CRS_ClearFlag_SYNCOK(void) +{ + WRITE_REG(CRS->ICR, CRS_ICR_SYNCOKC); +} + +/** + * @brief Clear the SYNC warning flag + * @rmtoll ICR SYNCWARNC LL_CRS_ClearFlag_SYNCWARN + * @retval None + */ +__STATIC_INLINE void LL_CRS_ClearFlag_SYNCWARN(void) +{ + WRITE_REG(CRS->ICR, CRS_ICR_SYNCWARNC); +} + +/** + * @brief Clear TRIMOVF, SYNCMISS and SYNCERR bits and consequently also + * the ERR flag + * @rmtoll ICR ERRC LL_CRS_ClearFlag_ERR + * @retval None + */ +__STATIC_INLINE void LL_CRS_ClearFlag_ERR(void) +{ + WRITE_REG(CRS->ICR, CRS_ICR_ERRC); +} + +/** + * @brief Clear Expected SYNC flag + * @rmtoll ICR ESYNCC LL_CRS_ClearFlag_ESYNC + * @retval None + */ +__STATIC_INLINE void LL_CRS_ClearFlag_ESYNC(void) +{ + WRITE_REG(CRS->ICR, CRS_ICR_ESYNCC); +} + +/** + * @} + */ + +/** @defgroup CRS_LL_EF_IT_Management IT_Management + * @{ + */ + +/** + * @brief Enable SYNC event OK interrupt + * @rmtoll CR SYNCOKIE LL_CRS_EnableIT_SYNCOK + * @retval None + */ +__STATIC_INLINE void LL_CRS_EnableIT_SYNCOK(void) +{ + SET_BIT(CRS->CR, CRS_CR_SYNCOKIE); +} + +/** + * @brief Disable SYNC event OK interrupt + * @rmtoll CR SYNCOKIE LL_CRS_DisableIT_SYNCOK + * @retval None + */ +__STATIC_INLINE void LL_CRS_DisableIT_SYNCOK(void) +{ + CLEAR_BIT(CRS->CR, CRS_CR_SYNCOKIE); +} + +/** + * @brief Check if SYNC event OK interrupt is enabled or not + * @rmtoll CR SYNCOKIE LL_CRS_IsEnabledIT_SYNCOK + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_CRS_IsEnabledIT_SYNCOK(void) +{ + return ((READ_BIT(CRS->CR, CRS_CR_SYNCOKIE) == (CRS_CR_SYNCOKIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable SYNC warning interrupt + * @rmtoll CR SYNCWARNIE LL_CRS_EnableIT_SYNCWARN + * @retval None + */ +__STATIC_INLINE void LL_CRS_EnableIT_SYNCWARN(void) +{ + SET_BIT(CRS->CR, CRS_CR_SYNCWARNIE); +} + +/** + * @brief Disable SYNC warning interrupt + * @rmtoll CR SYNCWARNIE LL_CRS_DisableIT_SYNCWARN + * @retval None + */ +__STATIC_INLINE void LL_CRS_DisableIT_SYNCWARN(void) +{ + CLEAR_BIT(CRS->CR, CRS_CR_SYNCWARNIE); +} + +/** + * @brief Check if SYNC warning interrupt is enabled or not + * @rmtoll CR SYNCWARNIE LL_CRS_IsEnabledIT_SYNCWARN + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_CRS_IsEnabledIT_SYNCWARN(void) +{ + return ((READ_BIT(CRS->CR, CRS_CR_SYNCWARNIE) == (CRS_CR_SYNCWARNIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable Synchronization or trimming error interrupt + * @rmtoll CR ERRIE LL_CRS_EnableIT_ERR + * @retval None + */ +__STATIC_INLINE void LL_CRS_EnableIT_ERR(void) +{ + SET_BIT(CRS->CR, CRS_CR_ERRIE); +} + +/** + * @brief Disable Synchronization or trimming error interrupt + * @rmtoll CR ERRIE LL_CRS_DisableIT_ERR + * @retval None + */ +__STATIC_INLINE void LL_CRS_DisableIT_ERR(void) +{ + CLEAR_BIT(CRS->CR, CRS_CR_ERRIE); +} + +/** + * @brief Check if Synchronization or trimming error interrupt is enabled or not + * @rmtoll CR ERRIE LL_CRS_IsEnabledIT_ERR + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_CRS_IsEnabledIT_ERR(void) +{ + return ((READ_BIT(CRS->CR, CRS_CR_ERRIE) == (CRS_CR_ERRIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable Expected SYNC interrupt + * @rmtoll CR ESYNCIE LL_CRS_EnableIT_ESYNC + * @retval None + */ +__STATIC_INLINE void LL_CRS_EnableIT_ESYNC(void) +{ + SET_BIT(CRS->CR, CRS_CR_ESYNCIE); +} + +/** + * @brief Disable Expected SYNC interrupt + * @rmtoll CR ESYNCIE LL_CRS_DisableIT_ESYNC + * @retval None + */ +__STATIC_INLINE void LL_CRS_DisableIT_ESYNC(void) +{ + CLEAR_BIT(CRS->CR, CRS_CR_ESYNCIE); +} + +/** + * @brief Check if Expected SYNC interrupt is enabled or not + * @rmtoll CR ESYNCIE LL_CRS_IsEnabledIT_ESYNC + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_CRS_IsEnabledIT_ESYNC(void) +{ + return ((READ_BIT(CRS->CR, CRS_CR_ESYNCIE) == (CRS_CR_ESYNCIE)) ? 1UL : 0UL); +} + +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup CRS_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +ErrorStatus LL_CRS_DeInit(void); + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined(CRS) */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_LL_CRS_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_dac.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_dac.h new file mode 100644 index 0000000000..4cc02a242b --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_dac.h @@ -0,0 +1,2050 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_dac.h + * @author MCD Application Team + * @brief Header file of DAC LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_LL_DAC_H +#define STM32H5xx_LL_DAC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined(DAC1) + +/** @defgroup DAC_LL DAC + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup DAC_LL_Private_Constants DAC Private Constants + * @{ + */ + +/* Internal masks for DAC channels definition */ +/* To select into literal LL_DAC_CHANNEL_x the relevant bits for: */ +/* - channel bits position into registers CR, MCR, CCR, SHHR, SHRR */ +/* - channel bits position into register SWTRIG */ +/* - channel register offset of data holding register DHRx */ +/* - channel register offset of data output register DORx */ +/* - channel register offset of sample-and-hold sample time register SHSRx */ +#define DAC_CR_CH1_BITOFFSET 0UL /* Position of channel bits into registers + CR, MCR, CCR, SHHR, SHRR of channel 1 */ +#define DAC_CR_CH2_BITOFFSET 16UL /* Position of channel bits into registers + CR, MCR, CCR, SHHR, SHRR of channel 2 */ +#define DAC_CR_CHX_BITOFFSET_MASK (DAC_CR_CH1_BITOFFSET | DAC_CR_CH2_BITOFFSET) + +#define DAC_SWTR_CH1 (DAC_SWTRIGR_SWTRIG1) /* Channel bit into register SWTRIGR of channel 1. */ +#define DAC_SWTR_CH2 (DAC_SWTRIGR_SWTRIG2) /* Channel bit into register SWTRIGR of channel 2. */ +#define DAC_SWTR_CHX_MASK (DAC_SWTR_CH1 | DAC_SWTR_CH2) + +#define DAC_REG_DHR12R1_REGOFFSET 0x00000000UL /* Register DHR12Rx channel 1 taken as reference */ +#define DAC_REG_DHR12L1_REGOFFSET 0x00100000UL /* Register offset of DHR12Lx channel 1 versus + DHR12Rx channel 1 (shifted left of 20 bits) */ +#define DAC_REG_DHR8R1_REGOFFSET 0x02000000UL /* Register offset of DHR8Rx channel 1 versus + DHR12Rx channel 1 (shifted left of 24 bits) */ + +#define DAC_REG_DHR12R2_REGOFFSET 0x30000000UL /* Register offset of DHR12Rx channel 2 versus + DHR12Rx channel 1 (shifted left of 28 bits) */ +#define DAC_REG_DHR12L2_REGOFFSET 0x00400000UL /* Register offset of DHR12Lx channel 2 versus + DHR12Rx channel 1 (shifted left of 20 bits) */ +#define DAC_REG_DHR8R2_REGOFFSET 0x05000000UL /* Register offset of DHR8Rx channel 2 versus + DHR12Rx channel 1 (shifted left of 24 bits) */ + +#define DAC_REG_DHR12RX_REGOFFSET_MASK 0xF0000000UL +#define DAC_REG_DHR12LX_REGOFFSET_MASK 0x00F00000UL +#define DAC_REG_DHR8RX_REGOFFSET_MASK 0x0F000000UL +#define DAC_REG_DHRX_REGOFFSET_MASK (DAC_REG_DHR12RX_REGOFFSET_MASK\ + | DAC_REG_DHR12LX_REGOFFSET_MASK | DAC_REG_DHR8RX_REGOFFSET_MASK) + +#define DAC_REG_DOR1_REGOFFSET 0x00000000UL /* Register DORx channel 1 taken as reference */ + +#define DAC_REG_DOR2_REGOFFSET 0x00000020UL /* Register offset of DORx channel 1 versus + DORx channel 2 (shifted left of 5 bits) */ +#define DAC_REG_DORX_REGOFFSET_MASK (DAC_REG_DOR1_REGOFFSET | DAC_REG_DOR2_REGOFFSET) + +#define DAC_REG_SHSR1_REGOFFSET 0x00000000UL /* Register SHSRx channel 1 taken as reference */ +#define DAC_REG_SHSR2_REGOFFSET 0x00000040UL /* Register offset of SHSRx channel 1 versus + SHSRx channel 2 (shifted left of 6 bits) */ +#define DAC_REG_SHSRX_REGOFFSET_MASK (DAC_REG_SHSR1_REGOFFSET | DAC_REG_SHSR2_REGOFFSET) + + +#define DAC_REG_DHR_REGOFFSET_MASK_POSBIT0 0x0000000FUL /* Mask of data hold registers offset (DHR12Rx, + DHR12Lx, DHR8Rx, ...) when shifted to position 0 */ +#define DAC_REG_DORX_REGOFFSET_MASK_POSBIT0 0x00000001UL /* Mask of DORx registers offset when shifted + to position 0 */ +#define DAC_REG_SHSRX_REGOFFSET_MASK_POSBIT0 0x00000001UL /* Mask of SHSRx registers offset when shifted + to position 0 */ + +#define DAC_REG_DHR12RX_REGOFFSET_BITOFFSET_POS 28UL /* Position of bits register offset of DHR12Rx + channel 1 or 2 versus DHR12Rx channel 1 + (shifted left of 28 bits) */ +#define DAC_REG_DHR12LX_REGOFFSET_BITOFFSET_POS 20UL /* Position of bits register offset of DHR12Lx + channel 1 or 2 versus DHR12Rx channel 1 + (shifted left of 20 bits) */ +#define DAC_REG_DHR8RX_REGOFFSET_BITOFFSET_POS 24UL /* Position of bits register offset of DHR8Rx + channel 1 or 2 versus DHR12Rx channel 1 + (shifted left of 24 bits) */ +#define DAC_REG_DORX_REGOFFSET_BITOFFSET_POS 5UL /* Position of bits register offset of DORx + channel 1 or 2 versus DORx channel 1 + (shifted left of 5 bits) */ +#define DAC_REG_SHSRX_REGOFFSET_BITOFFSET_POS 6UL /* Position of bits register offset of SHSRx + channel 1 or 2 versus SHSRx channel 1 + (shifted left of 6 bits) */ + +/* DAC registers bits positions */ +#define DAC_DHR12RD_DACC2DHR_BITOFFSET_POS DAC_DHR12RD_DACC2DHR_Pos +#define DAC_DHR12LD_DACC2DHR_BITOFFSET_POS DAC_DHR12LD_DACC2DHR_Pos +#define DAC_DHR8RD_DACC2DHR_BITOFFSET_POS DAC_DHR8RD_DACC2DHR_Pos + +/* Miscellaneous data */ +#define DAC_DIGITAL_SCALE_12BITS 4095UL /* Full-scale digital value with a resolution of 12 + bits (voltage range determined by analog voltage + references Vref+ and Vref-, refer to reference manual) */ + +/** + * @} + */ + + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup DAC_LL_Private_Macros DAC Private Macros + * @{ + */ + +/** + * @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 __DAC_PTR_REG_OFFSET(__REG__, __REG_OFFFSET__) \ + ((uint32_t *)((uint32_t) ((uint32_t)(&(__REG__)) + ((__REG_OFFFSET__) << 2UL)))) + +/** + * @} + */ + + +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup DAC_LL_ES_INIT DAC Exported Init structure + * @{ + */ + +/** + * @brief Structure definition of some features of DAC instance. + */ +typedef struct +{ + uint32_t TriggerSource; /*!< Set the conversion trigger source for the selected DAC channel: + internal (SW start) or from external peripheral + (timer event, external interrupt line). + This parameter can be a value of @ref DAC_LL_EC_TRIGGER_SOURCE + + This feature can be modified afterwards using unitary + function @ref LL_DAC_SetTriggerSource(). */ + + uint32_t WaveAutoGeneration; /*!< Set the waveform automatic generation mode for the selected DAC channel. + This parameter can be a value of @ref DAC_LL_EC_WAVE_AUTO_GENERATION_MODE + + This feature can be modified afterwards using unitary + function @ref LL_DAC_SetWaveAutoGeneration(). */ + + uint32_t WaveAutoGenerationConfig; /*!< Set the waveform automatic generation mode for the selected DAC channel. + If waveform automatic generation mode is set to noise, this parameter + can be a value of @ref DAC_LL_EC_WAVE_NOISE_LFSR_UNMASK_BITS + If waveform automatic generation mode is set to triangle, + this parameter can be a value of @ref DAC_LL_EC_WAVE_TRIANGLE_AMPLITUDE + @note If waveform automatic generation mode is disabled, + this parameter is discarded. + + This feature can be modified afterwards using unitary + function @ref LL_DAC_SetWaveNoiseLFSR(), + @ref LL_DAC_SetWaveTriangleAmplitude() + depending on the wave automatic generation selected. */ + + uint32_t OutputBuffer; /*!< Set the output buffer for the selected DAC channel. + This parameter can be a value of @ref DAC_LL_EC_OUTPUT_BUFFER + + This feature can be modified afterwards using unitary + function @ref LL_DAC_SetOutputBuffer(). */ + + uint32_t OutputConnection; /*!< Set the output connection for the selected DAC channel. + This parameter can be a value of @ref DAC_LL_EC_OUTPUT_CONNECTION + + This feature can be modified afterwards using unitary + function @ref LL_DAC_SetOutputConnection(). */ + + uint32_t OutputMode; /*!< Set the output mode normal or sample-and-hold for the selected DAC + channel. This parameter can be a value of @ref DAC_LL_EC_OUTPUT_MODE + + This feature can be modified afterwards using unitary + function @ref LL_DAC_SetOutputMode(). */ +} LL_DAC_InitTypeDef; + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup DAC_LL_Exported_Constants DAC Exported Constants + * @{ + */ + +/** @defgroup DAC_LL_EC_GET_FLAG DAC flags + * @brief Flags defines which can be used with LL_DAC_ReadReg function + * @{ + */ +/* DAC channel 1 flags */ +#define LL_DAC_FLAG_DMAUDR1 (DAC_SR_DMAUDR1) /*!< DAC channel 1 flag DMA underrun */ +#define LL_DAC_FLAG_CAL1 (DAC_SR_CAL_FLAG1) /*!< DAC channel 1 flag offset calibration status */ +#define LL_DAC_FLAG_BWST1 (DAC_SR_BWST1) /*!< DAC channel 1 flag busy writing sample time */ +#define LL_DAC_FLAG_DAC1RDY (DAC_SR_DAC1RDY) /*!< DAC channel 1 flag ready */ +#define LL_DAC_FLAG_DORSTAT1 (DAC_SR_DORSTAT1) /*!< DAC channel 1 flag output register */ + +/* DAC channel 2 flags */ +#define LL_DAC_FLAG_DMAUDR2 (DAC_SR_DMAUDR2) /*!< DAC channel 2 flag DMA underrun */ +#define LL_DAC_FLAG_CAL2 (DAC_SR_CAL_FLAG2) /*!< DAC channel 2 flag offset calibration status */ +#define LL_DAC_FLAG_BWST2 (DAC_SR_BWST2) /*!< DAC channel 2 flag busy writing sample time */ +#define LL_DAC_FLAG_DAC2RDY (DAC_SR_DAC2RDY) /*!< DAC channel 2 flag ready */ +#define LL_DAC_FLAG_DORSTAT2 (DAC_SR_DORSTAT2) /*!< DAC channel 2 flag output register */ + +/** + * @} + */ + +/** @defgroup DAC_LL_EC_IT DAC interruptions + * @brief IT defines which can be used with LL_DAC_ReadReg and LL_DAC_WriteReg functions + * @{ + */ +#define LL_DAC_IT_DMAUDRIE1 (DAC_CR_DMAUDRIE1) /*!< DAC channel 1 interruption DMA underrun */ + +#define LL_DAC_IT_DMAUDRIE2 (DAC_CR_DMAUDRIE2) /*!< DAC channel 2 interruption DMA underrun */ + +/** + * @} + */ + +/** @defgroup DAC_LL_EC_CHANNEL DAC channels + * @{ + */ +#define LL_DAC_CHANNEL_1 (DAC_REG_SHSR1_REGOFFSET | DAC_REG_DOR1_REGOFFSET | DAC_REG_DHR12R1_REGOFFSET | DAC_REG_DHR12L1_REGOFFSET | DAC_REG_DHR8R1_REGOFFSET | DAC_CR_CH1_BITOFFSET | DAC_SWTR_CH1) /*!< DAC channel 1 */ +#define LL_DAC_CHANNEL_2 (DAC_REG_SHSR2_REGOFFSET | DAC_REG_DOR2_REGOFFSET | DAC_REG_DHR12R2_REGOFFSET | DAC_REG_DHR12L2_REGOFFSET | DAC_REG_DHR8R2_REGOFFSET | DAC_CR_CH2_BITOFFSET | DAC_SWTR_CH2) /*!< DAC channel 2 */ +/** + * @} + */ + +/** @defgroup DAC_LL_EC_HIGH_FREQUENCY_MODE DAC high frequency interface mode + * @brief High frequency interface mode defines that can be used + * with LL_DAC_SetHighFrequencyMode and LL_DAC_GetHighFrequencyMode + * @{ + */ +#define LL_DAC_HIGH_FREQ_MODE_DISABLE 0x00000000UL /*!< High frequency interface mode disabled */ +#define LL_DAC_HIGH_FREQ_MODE_ABOVE_80MHZ (DAC_MCR_HFSEL_0) /*!< High frequency interface mode compatible to AHB>80MHz enabled */ +#define LL_DAC_HIGH_FREQ_MODE_ABOVE_160MHZ (DAC_MCR_HFSEL_1) /*!< High frequency interface mode compatible to AHB>160MHz enabled */ +/** + * @} + */ + +/** @defgroup DAC_LL_EC_OPERATING_MODE DAC operating mode + * @{ + */ +#define LL_DAC_MODE_NORMAL_OPERATION 0x00000000UL /*!< DAC channel in mode normal operation */ +#define LL_DAC_MODE_CALIBRATION (DAC_CR_CEN1) /*!< DAC channel in mode calibration */ +/** + * @} + */ + +/** @defgroup DAC_LL_EC_TRIGGER_SOURCE DAC trigger source + * @{ + */ +/* Triggers common to all devices of STM32H5 series */ +#define LL_DAC_TRIG_SOFTWARE 0x00000000U /*!< DAC channel conversion trigger internal (SW start) */ +#define LL_DAC_TRIG_EXT_TIM1_TRGO ( DAC_CR_TSEL1_0) /*!< DAC channel conversion trigger from external peripheral: TIM1 TRGO. */ +#define LL_DAC_TRIG_EXT_TIM2_TRGO ( DAC_CR_TSEL1_1 ) /*!< DAC channel conversion trigger from external peripheral: TIM2 TRGO. */ +#define LL_DAC_TRIG_EXT_TIM6_TRGO ( DAC_CR_TSEL1_2 | DAC_CR_TSEL1_0) /*!< DAC channel conversion trigger from external peripheral: TIM6 TRGO. */ +#define LL_DAC_TRIG_EXT_TIM7_TRGO ( DAC_CR_TSEL1_2 | DAC_CR_TSEL1_1 ) /*!< DAC channel conversion trigger from external peripheral: TIM7 TRGO. */ +#define LL_DAC_TRIG_EXT_LPTIM1_CH1 (DAC_CR_TSEL1_3 | DAC_CR_TSEL1_1 | DAC_CR_TSEL1_0) /*!< DAC channel conversion trigger from external peripheral: LPTIM1 CH1. */ +#define LL_DAC_TRIG_EXT_LPTIM2_CH1 (DAC_CR_TSEL1_3 | DAC_CR_TSEL1_2 ) /*!< DAC channel conversion trigger from external peripheral: LPTIM2 CH1. */ +#define LL_DAC_TRIG_EXT_EXTI_LINE9 (DAC_CR_TSEL1_3 | DAC_CR_TSEL1_2 | DAC_CR_TSEL1_0) /*!< DAC channel conversion trigger from external peripheral: external interrupt line 9. */ + +/* Triggers specific to some devices of STM32H5 series */ +#if defined(TIM8) +/* Devices STM32H563/H573xx */ +#define LL_DAC_TRIG_EXT_TIM4_TRGO ( DAC_CR_TSEL1_1 | DAC_CR_TSEL1_0) /*!< DAC channel conversion trigger from external peripheral: TIM4 TRGO. */ +#define LL_DAC_TRIG_EXT_TIM5_TRGO ( DAC_CR_TSEL1_2 ) /*!< DAC channel conversion trigger from external peripheral: TIM5 TRGO. */ +#define LL_DAC_TRIG_EXT_TIM8_TRGO ( DAC_CR_TSEL1_2 | DAC_CR_TSEL1_1 | DAC_CR_TSEL1_0) /*!< DAC channel conversion trigger from external peripheral: TIM8 TRGO. */ +#define LL_DAC_TRIG_EXT_TIM15_TRGO (DAC_CR_TSEL1_3 ) /*!< DAC channel conversion trigger from external peripheral: TIM15 TRGO. */ +#else +/* Devices STM32H503xx */ +#define LL_DAC_TRIG_EXT_TIM3_TRGO ( DAC_CR_TSEL1_1 | DAC_CR_TSEL1_0) /*!< DAC channel conversion trigger from external peripheral: TIM3 TRGO. */ +#endif /* Devices STM32H563/H573xx or STM32H503xx */ + +#define LL_DAC_TRIG_EXT_LPTIM1_OUT LL_DAC_TRIG_EXT_LPTIM1_CH1 /*!< Keep old definition for compatibility */ +#define LL_DAC_TRIG_EXT_LPTIM2_OUT LL_DAC_TRIG_EXT_LPTIM2_CH1 /*!< Keep old definition for compatibility */ +/** + * @} + */ + +/** @defgroup DAC_LL_EC_WAVE_AUTO_GENERATION_MODE DAC waveform automatic generation mode + * @{ + */ +#define LL_DAC_WAVE_AUTO_GENERATION_NONE 0x00000000UL /*!< DAC channel wave auto generation mode disabled. */ +#define LL_DAC_WAVE_AUTO_GENERATION_NOISE ( DAC_CR_WAVE1_0) /*!< DAC channel wave auto generation mode enabled, set generated noise waveform. */ +#define LL_DAC_WAVE_AUTO_GENERATION_TRIANGLE (DAC_CR_WAVE1_1 ) /*!< DAC channel wave auto generation mode enabled, set generated triangle waveform. */ +/** + * @} + */ + +/** @defgroup DAC_LL_EC_WAVE_NOISE_LFSR_UNMASK_BITS DAC wave generation - Noise LFSR unmask bits + * @{ + */ +#define LL_DAC_NOISE_LFSR_UNMASK_BIT0 0x00000000UL /*!< Noise wave generation, unmask LFSR bit0, for the selected DAC channel */ +#define LL_DAC_NOISE_LFSR_UNMASK_BITS1_0 ( DAC_CR_MAMP1_0) /*!< Noise wave generation, unmask LFSR bits[1:0], for the selected DAC channel */ +#define LL_DAC_NOISE_LFSR_UNMASK_BITS2_0 ( DAC_CR_MAMP1_1 ) /*!< Noise wave generation, unmask LFSR bits[2:0], for the selected DAC channel */ +#define LL_DAC_NOISE_LFSR_UNMASK_BITS3_0 ( DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Noise wave generation, unmask LFSR bits[3:0], for the selected DAC channel */ +#define LL_DAC_NOISE_LFSR_UNMASK_BITS4_0 ( DAC_CR_MAMP1_2 ) /*!< Noise wave generation, unmask LFSR bits[4:0], for the selected DAC channel */ +#define LL_DAC_NOISE_LFSR_UNMASK_BITS5_0 ( DAC_CR_MAMP1_2 | DAC_CR_MAMP1_0) /*!< Noise wave generation, unmask LFSR bits[5:0], for the selected DAC channel */ +#define LL_DAC_NOISE_LFSR_UNMASK_BITS6_0 ( DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1 ) /*!< Noise wave generation, unmask LFSR bits[6:0], for the selected DAC channel */ +#define LL_DAC_NOISE_LFSR_UNMASK_BITS7_0 ( DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Noise wave generation, unmask LFSR bits[7:0], for the selected DAC channel */ +#define LL_DAC_NOISE_LFSR_UNMASK_BITS8_0 (DAC_CR_MAMP1_3 ) /*!< Noise wave generation, unmask LFSR bits[8:0], for the selected DAC channel */ +#define LL_DAC_NOISE_LFSR_UNMASK_BITS9_0 (DAC_CR_MAMP1_3 | DAC_CR_MAMP1_0) /*!< Noise wave generation, unmask LFSR bits[9:0], for the selected DAC channel */ +#define LL_DAC_NOISE_LFSR_UNMASK_BITS10_0 (DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1 ) /*!< Noise wave generation, unmask LFSR bits[10:0], for the selected DAC channel */ +#define LL_DAC_NOISE_LFSR_UNMASK_BITS11_0 (DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Noise wave generation, unmask LFSR bits[11:0], for the selected DAC channel */ +/** + * @} + */ + +/** @defgroup DAC_LL_EC_WAVE_TRIANGLE_AMPLITUDE DAC wave generation - Triangle amplitude + * @{ + */ +#define LL_DAC_TRIANGLE_AMPLITUDE_1 0x00000000UL /*!< Triangle wave generation, amplitude of 1 LSB of DAC output range, for the selected DAC channel */ +#define LL_DAC_TRIANGLE_AMPLITUDE_3 ( DAC_CR_MAMP1_0) /*!< Triangle wave generation, amplitude of 3 LSB of DAC output range, for the selected DAC channel */ +#define LL_DAC_TRIANGLE_AMPLITUDE_7 ( DAC_CR_MAMP1_1 ) /*!< Triangle wave generation, amplitude of 7 LSB of DAC output range, for the selected DAC channel */ +#define LL_DAC_TRIANGLE_AMPLITUDE_15 ( DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Triangle wave generation, amplitude of 15 LSB of DAC output range, for the selected DAC channel */ +#define LL_DAC_TRIANGLE_AMPLITUDE_31 ( DAC_CR_MAMP1_2 ) /*!< Triangle wave generation, amplitude of 31 LSB of DAC output range, for the selected DAC channel */ +#define LL_DAC_TRIANGLE_AMPLITUDE_63 ( DAC_CR_MAMP1_2 | DAC_CR_MAMP1_0) /*!< Triangle wave generation, amplitude of 63 LSB of DAC output range, for the selected DAC channel */ +#define LL_DAC_TRIANGLE_AMPLITUDE_127 ( DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1 ) /*!< Triangle wave generation, amplitude of 127 LSB of DAC output range, for the selected DAC channel */ +#define LL_DAC_TRIANGLE_AMPLITUDE_255 ( DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Triangle wave generation, amplitude of 255 LSB of DAC output range, for the selected DAC channel */ +#define LL_DAC_TRIANGLE_AMPLITUDE_511 (DAC_CR_MAMP1_3 ) /*!< Triangle wave generation, amplitude of 512 LSB of DAC output range, for the selected DAC channel */ +#define LL_DAC_TRIANGLE_AMPLITUDE_1023 (DAC_CR_MAMP1_3 | DAC_CR_MAMP1_0) /*!< Triangle wave generation, amplitude of 1023 LSB of DAC output range, for the selected DAC channel */ +#define LL_DAC_TRIANGLE_AMPLITUDE_2047 (DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1 ) /*!< Triangle wave generation, amplitude of 2047 LSB of DAC output range, for the selected DAC channel */ +#define LL_DAC_TRIANGLE_AMPLITUDE_4095 (DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Triangle wave generation, amplitude of 4095 LSB of DAC output range, for the selected DAC channel */ +/** + * @} + */ + +/** @defgroup DAC_LL_EC_OUTPUT_MODE DAC channel output mode + * @{ + */ +#define LL_DAC_OUTPUT_MODE_NORMAL 0x00000000UL /*!< The selected DAC channel output is on mode normal. */ +#define LL_DAC_OUTPUT_MODE_SAMPLE_AND_HOLD (DAC_MCR_MODE1_2) /*!< The selected DAC channel output is on mode sample-and-hold. Mode sample-and-hold requires an external capacitor, refer to description of function @ref LL_DAC_ConfigOutput() or @ref LL_DAC_SetOutputMode(). */ +/** + * @} + */ + +/** @defgroup DAC_LL_EC_OUTPUT_BUFFER DAC channel output buffer + * @{ + */ +#define LL_DAC_OUTPUT_BUFFER_ENABLE 0x00000000UL /*!< The selected DAC channel output is buffered: higher drive current capability, but also higher current consumption */ +#define LL_DAC_OUTPUT_BUFFER_DISABLE (DAC_MCR_MODE1_1) /*!< The selected DAC channel output is not buffered: lower drive current capability, but also lower current consumption */ +/** + * @} + */ + +/** @defgroup DAC_LL_EC_OUTPUT_CONNECTION DAC channel output connection + * @{ + */ +#define LL_DAC_OUTPUT_CONNECT_GPIO 0x00000000UL /*!< The selected DAC channel output is connected to external pin */ +#define LL_DAC_OUTPUT_CONNECT_INTERNAL (DAC_MCR_MODE1_0) /*!< The selected DAC channel output is connected to on-chip peripherals via internal paths. On this STM32 series, output connection depends on output mode (normal or sample and hold) and output buffer state. Refer to comments of function @ref LL_DAC_SetOutputConnection(). */ +/** + * @} + */ + +/** @defgroup DAC_LL_EC_SIGNED_FORMAT DAC channel signed format + * @{ + */ +#define LL_DAC_SIGNED_FORMAT_DISABLE 0x00000000UL /*!< The selected DAC channel data format is not signed */ +#define LL_DAC_SIGNED_FORMAT_ENABLE (DAC_MCR_SINFORMAT1) /*!< The selected DAC channel data format is signed */ +/** + * @} + */ + +/** @defgroup DAC_LL_EC_RESOLUTION DAC channel output resolution + * @{ + */ +#define LL_DAC_RESOLUTION_12B 0x00000000UL /*!< DAC channel resolution 12 bits */ +#define LL_DAC_RESOLUTION_8B 0x00000002UL /*!< DAC channel resolution 8 bits */ +/** + * @} + */ + +/** @defgroup DAC_LL_EC_REGISTERS DAC registers compliant with specific purpose + * @{ + */ +/* List of DAC registers intended to be used (most commonly) with */ +/* DMA transfer. */ +/* Refer to function @ref LL_DAC_DMA_GetRegAddr(). */ +#define LL_DAC_DMA_REG_DATA_12BITS_RIGHT_ALIGNED DAC_REG_DHR12RX_REGOFFSET_BITOFFSET_POS /*!< DAC channel data holding register 12 bits right aligned */ +#define LL_DAC_DMA_REG_DATA_12BITS_LEFT_ALIGNED DAC_REG_DHR12LX_REGOFFSET_BITOFFSET_POS /*!< DAC channel data holding register 12 bits left aligned */ +#define LL_DAC_DMA_REG_DATA_8BITS_RIGHT_ALIGNED DAC_REG_DHR8RX_REGOFFSET_BITOFFSET_POS /*!< DAC channel data holding register 8 bits right aligned */ +/** + * @} + */ + +/** @defgroup DAC_LL_EC_HW_DELAYS Definitions of DAC hardware constraints delays + * @note Only DAC peripheral HW delays are defined in DAC LL driver driver, + * not timeout values. + * For details on delays values, refer to descriptions in source code + * above each literal definition. + * @{ + */ + +/* Delay for DAC channel voltage settling time from DAC channel startup */ +/* (transition from disable to enable). */ +/* Note: DAC channel startup time depends on board application environment: */ +/* impedance connected to DAC channel output. */ +/* The delay below is specified under conditions: */ +/* - voltage maximum transition (lowest to highest value) */ +/* - until voltage reaches final value +-1LSB */ +/* - DAC channel output buffer enabled */ +/* - load impedance of 5kOhm (min), 50pF (max) */ +/* Literal set to maximum value (refer to device datasheet, */ +/* parameter "tWAKEUP"). */ +/* Unit: us */ +#define LL_DAC_DELAY_STARTUP_VOLTAGE_SETTLING_US 8UL /*!< Delay for DAC channel voltage settling time from DAC channel startup (transition from disable to enable) */ + +/* Delay for DAC channel voltage settling time. */ +/* Note: DAC channel startup time depends on board application environment: */ +/* impedance connected to DAC channel output. */ +/* The delay below is specified under conditions: */ +/* - voltage maximum transition (lowest to highest value) */ +/* - until voltage reaches final value +-1LSB */ +/* - DAC channel output buffer enabled */ +/* - load impedance of 5kOhm min, 50pF max */ +/* Literal set to maximum value (refer to device datasheet, */ +/* parameter "tSETTLING"). */ +/* Unit: us */ +#define LL_DAC_DELAY_VOLTAGE_SETTLING_US 3UL /*!< Delay for DAC channel voltage settling time */ + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup DAC_LL_Exported_Macros DAC Exported Macros + * @{ + */ + +/** @defgroup DAC_LL_EM_WRITE_READ Common write and read registers macros + * @{ + */ + +/** + * @brief Write a value in DAC register + * @param __INSTANCE__ DAC Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_DAC_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in DAC register + * @param __INSTANCE__ DAC Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_DAC_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) + +/** + * @} + */ + +/** @defgroup DAC_LL_EM_HELPER_MACRO DAC helper macro + * @{ + */ + +/** + * @brief Helper macro to get DAC channel number in decimal format + * from literals LL_DAC_CHANNEL_x. + * Example: + * __LL_DAC_CHANNEL_TO_DECIMAL_NB(LL_DAC_CHANNEL_1) + * will return decimal number "1". + * @note The input can be a value from functions where a channel + * number is returned. + * @param __CHANNEL__ This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval 1...2 + */ +#define __LL_DAC_CHANNEL_TO_DECIMAL_NB(__CHANNEL__) \ + ((__CHANNEL__) & DAC_SWTR_CHX_MASK) + +/** + * @brief Helper macro to get DAC channel in literal format LL_DAC_CHANNEL_x + * from number in decimal format. + * Example: + * __LL_DAC_DECIMAL_NB_TO_CHANNEL(1) + * will return a data equivalent to "LL_DAC_CHANNEL_1". + * @note If the input parameter does not correspond to a DAC channel, + * this macro returns value '0'. + * @param __DECIMAL_NB__ 1...2 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + */ +#define __LL_DAC_DECIMAL_NB_TO_CHANNEL(__DECIMAL_NB__)\ + (((__DECIMAL_NB__) == 1UL)? (LL_DAC_CHANNEL_1 ):(((__DECIMAL_NB__) == 2UL) ? ( LL_DAC_CHANNEL_2):(0UL))) + +/** + * @brief Helper macro to define the DAC conversion data full-scale digital + * value corresponding to the selected DAC resolution. + * @note DAC conversion data full-scale corresponds to voltage range + * determined by analog voltage references Vref+ and Vref- + * (refer to reference manual). + * @param __DAC_RESOLUTION__ This parameter can be one of the following values: + * @arg @ref LL_DAC_RESOLUTION_12B + * @arg @ref LL_DAC_RESOLUTION_8B + * @retval ADC conversion data equivalent voltage value (unit: mVolt) + */ +#define __LL_DAC_DIGITAL_SCALE(__DAC_RESOLUTION__) \ + ((0x00000FFFUL) >> ((__DAC_RESOLUTION__) << 1UL)) + +/** + * @brief Helper macro to calculate the DAC conversion data (unit: digital + * value) corresponding to a voltage (unit: mVolt). + * @note This helper macro is intended to provide input data in voltage + * rather than digital value, + * to be used with LL DAC functions such as + * @ref LL_DAC_ConvertData12RightAligned(). + * @note Analog reference voltage (Vref+) must be either known from + * user board environment or can be calculated using ADC measurement + * and ADC helper macro __LL_ADC_CALC_VREFANALOG_VOLTAGE(). + * @param __VREFANALOG_VOLTAGE__ Analog reference voltage (unit: mV) + * @param __DAC_VOLTAGE__ Voltage to be generated by DAC channel + * (unit: mVolt). + * @param __DAC_RESOLUTION__ This parameter can be one of the following values: + * @arg @ref LL_DAC_RESOLUTION_12B + * @arg @ref LL_DAC_RESOLUTION_8B + * @retval DAC conversion data (unit: digital value) + */ +#define __LL_DAC_CALC_VOLTAGE_TO_DATA(__VREFANALOG_VOLTAGE__, __DAC_VOLTAGE__, __DAC_RESOLUTION__) \ + ((__DAC_VOLTAGE__) * __LL_DAC_DIGITAL_SCALE(__DAC_RESOLUTION__) \ + / (__VREFANALOG_VOLTAGE__) \ + ) + +/** + * @} + */ + +/** + * @} + */ + + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup DAC_LL_Exported_Functions DAC Exported Functions + * @{ + */ +/** @defgroup DAC_LL_EF_Channel_Configuration Configuration of DAC instance + * @{ + */ +/** + * @brief Set the high frequency interface mode for the selected DAC instance + * @rmtoll MCR HFSEL LL_DAC_SetHighFrequencyMode + * @param DACx DAC instance + * @param HighFreqMode This parameter can be one of the following values: + * @arg @ref LL_DAC_HIGH_FREQ_MODE_DISABLE + * @arg @ref LL_DAC_HIGH_FREQ_MODE_ABOVE_80MHZ + * @arg @ref LL_DAC_HIGH_FREQ_MODE_ABOVE_160MHZ + * @retval None + */ +__STATIC_INLINE void LL_DAC_SetHighFrequencyMode(DAC_TypeDef *DACx, uint32_t HighFreqMode) +{ + MODIFY_REG(DACx->MCR, DAC_MCR_HFSEL, HighFreqMode); +} + +/** + * @brief Get the high frequency interface mode for the selected DAC instance + * @rmtoll MCR HFSEL LL_DAC_GetHighFrequencyMode + * @param DACx DAC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_DAC_HIGH_FREQ_MODE_DISABLE + * @arg @ref LL_DAC_HIGH_FREQ_MODE_ABOVE_80MHZ + * @arg @ref LL_DAC_HIGH_FREQ_MODE_ABOVE_160MHZ + */ +__STATIC_INLINE uint32_t LL_DAC_GetHighFrequencyMode(const DAC_TypeDef *DACx) +{ + return (uint32_t)(READ_BIT(DACx->MCR, DAC_MCR_HFSEL)); +} +/** + * @} + */ + + +/** @defgroup DAC_LL_EF_Configuration Configuration of DAC channels + * @{ + */ + +/** + * @brief Set the operating mode for the selected DAC channel: + * calibration or normal operating mode. + * @rmtoll CR CEN1 LL_DAC_SetMode\n + * CR CEN2 LL_DAC_SetMode + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @param ChannelMode This parameter can be one of the following values: + * @arg @ref LL_DAC_MODE_NORMAL_OPERATION + * @arg @ref LL_DAC_MODE_CALIBRATION + * @retval None + */ +__STATIC_INLINE void LL_DAC_SetMode(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t ChannelMode) +{ + MODIFY_REG(DACx->CR, + DAC_CR_CEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK), + ChannelMode << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); +} + +/** + * @brief Get the operating mode for the selected DAC channel: + * calibration or normal operating mode. + * @rmtoll CR CEN1 LL_DAC_GetMode\n + * CR CEN2 LL_DAC_GetMode + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DAC_MODE_NORMAL_OPERATION + * @arg @ref LL_DAC_MODE_CALIBRATION + */ +__STATIC_INLINE uint32_t LL_DAC_GetMode(const DAC_TypeDef *DACx, uint32_t DAC_Channel) +{ + return (uint32_t)(READ_BIT(DACx->CR, DAC_CR_CEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)) + >> (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK) + ); +} + +/** + * @brief Set the offset trimming value for the selected DAC channel. + * Trimming has an impact when output buffer is enabled + * and is intended to replace factory calibration default values. + * @rmtoll CCR OTRIM1 LL_DAC_SetTrimmingValue\n + * CCR OTRIM2 LL_DAC_SetTrimmingValue + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @param TrimmingValue Value between Min_Data=0x00 and Max_Data=0x1F + * @retval None + */ +__STATIC_INLINE void LL_DAC_SetTrimmingValue(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t TrimmingValue) +{ + MODIFY_REG(DACx->CCR, + DAC_CCR_OTRIM1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK), + TrimmingValue << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); +} + +/** + * @brief Get the offset trimming value for the selected DAC channel. + * Trimming has an impact when output buffer is enabled + * and is intended to replace factory calibration default values. + * @rmtoll CCR OTRIM1 LL_DAC_GetTrimmingValue\n + * CCR OTRIM2 LL_DAC_GetTrimmingValue + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval TrimmingValue Value between Min_Data=0x00 and Max_Data=0x1F + */ +__STATIC_INLINE uint32_t LL_DAC_GetTrimmingValue(const DAC_TypeDef *DACx, uint32_t DAC_Channel) +{ + return (uint32_t)(READ_BIT(DACx->CCR, DAC_CCR_OTRIM1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)) + >> (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK) + ); +} + +/** + * @brief Set the conversion trigger source for the selected DAC channel. + * @note For conversion trigger source to be effective, DAC trigger + * must be enabled using function @ref LL_DAC_EnableTrigger(). + * @note To set conversion trigger source, DAC channel must be disabled. + * Otherwise, the setting is discarded. + * @note Availability of parameters of trigger sources from timer + * depends on timers availability on the selected device. + * @rmtoll CR TSEL1 LL_DAC_SetTriggerSource\n + * CR TSEL2 LL_DAC_SetTriggerSource + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @param TriggerSource This parameter can be one of the following values: + * @arg @ref LL_DAC_TRIG_SOFTWARE + * @arg @ref LL_DAC_TRIG_EXT_TIM1_TRGO + * @arg @ref LL_DAC_TRIG_EXT_TIM2_TRGO + * @arg @ref LL_DAC_TRIG_EXT_TIM3_TRGO (1) + * @arg @ref LL_DAC_TRIG_EXT_TIM4_TRGO (2) + * @arg @ref LL_DAC_TRIG_EXT_TIM5_TRGO (2) + * @arg @ref LL_DAC_TRIG_EXT_TIM6_TRG + * @arg @ref LL_DAC_TRIG_EXT_TIM7_TRGO + * @arg @ref LL_DAC_TRIG_EXT_TIM8_TRGO (2) + * @arg @ref LL_DAC_TRIG_EXT_TIM15_TRGO (2) + * @arg @ref LL_DAC_TRIG_EXT_LPTIM1_CH1 + * @arg @ref LL_DAC_TRIG_EXT_LPTIM2_CH1 + * @arg @ref LL_DAC_TRIG_EXT_EXTI_LINE9 + * + * (1) On this STM32 series, parameter not available on all devices. + * Only available on STM32H503xx (refer to device reference manual for supported features list) + * (2) On this STM32 series, parameter not available on all devices. + * Only available on STM32H563/H573xx (refer to device reference manual for supported features list) + * @retval None + */ +__STATIC_INLINE void LL_DAC_SetTriggerSource(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t TriggerSource) +{ + MODIFY_REG(DACx->CR, + DAC_CR_TSEL1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK), + TriggerSource << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); +} + +/** + * @brief Get the conversion trigger source for the selected DAC channel. + * @note For conversion trigger source to be effective, DAC trigger + * must be enabled using function @ref LL_DAC_EnableTrigger(). + * @note Availability of parameters of trigger sources from timer + * depends on timers availability on the selected device. + * @rmtoll CR TSEL1 LL_DAC_GetTriggerSource\n + * CR TSEL2 LL_DAC_GetTriggerSource + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DAC_TRIG_SOFTWARE + * @arg @ref LL_DAC_TRIG_EXT_TIM1_TRGO + * @arg @ref LL_DAC_TRIG_EXT_TIM2_TRGO + * @arg @ref LL_DAC_TRIG_EXT_TIM3_TRGO (1) + * @arg @ref LL_DAC_TRIG_EXT_TIM4_TRGO (2) + * @arg @ref LL_DAC_TRIG_EXT_TIM5_TRGO (2) + * @arg @ref LL_DAC_TRIG_EXT_TIM6_TRG + * @arg @ref LL_DAC_TRIG_EXT_TIM7_TRGO + * @arg @ref LL_DAC_TRIG_EXT_TIM8_TRGO (2) + * @arg @ref LL_DAC_TRIG_EXT_TIM15_TRGO (2) + * @arg @ref LL_DAC_TRIG_EXT_LPTIM1_CH1 + * @arg @ref LL_DAC_TRIG_EXT_LPTIM2_CH1 + * @arg @ref LL_DAC_TRIG_EXT_EXTI_LINE9 + * + * (1) On this STM32 series, parameter not available on all devices. + * Only available on STM32H503xx (refer to device reference manual for supported features list) + * (2) On this STM32 series, parameter not available on all devices. + * Only available on STM32H563/H573xx (refer to device reference manual for supported features list) + */ +__STATIC_INLINE uint32_t LL_DAC_GetTriggerSource(const DAC_TypeDef *DACx, uint32_t DAC_Channel) +{ + return (uint32_t)(READ_BIT(DACx->CR, DAC_CR_TSEL1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)) + >> (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK) + ); +} + +/** + * @brief Set the waveform automatic generation mode + * for the selected DAC channel. + * @rmtoll CR WAVE1 LL_DAC_SetWaveAutoGeneration\n + * CR WAVE2 LL_DAC_SetWaveAutoGeneration + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @param WaveAutoGeneration This parameter can be one of the following values: + * @arg @ref LL_DAC_WAVE_AUTO_GENERATION_NONE + * @arg @ref LL_DAC_WAVE_AUTO_GENERATION_NOISE + * @arg @ref LL_DAC_WAVE_AUTO_GENERATION_TRIANGLE + * @retval None + */ +__STATIC_INLINE void LL_DAC_SetWaveAutoGeneration(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t WaveAutoGeneration) +{ + MODIFY_REG(DACx->CR, + DAC_CR_WAVE1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK), + WaveAutoGeneration << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); +} + +/** + * @brief Get the waveform automatic generation mode + * for the selected DAC channel. + * @rmtoll CR WAVE1 LL_DAC_GetWaveAutoGeneration\n + * CR WAVE2 LL_DAC_GetWaveAutoGeneration + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DAC_WAVE_AUTO_GENERATION_NONE + * @arg @ref LL_DAC_WAVE_AUTO_GENERATION_NOISE + * @arg @ref LL_DAC_WAVE_AUTO_GENERATION_TRIANGLE + */ +__STATIC_INLINE uint32_t LL_DAC_GetWaveAutoGeneration(const DAC_TypeDef *DACx, uint32_t DAC_Channel) +{ + return (uint32_t)(READ_BIT(DACx->CR, DAC_CR_WAVE1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)) + >> (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK) + ); +} + +/** + * @brief Set the noise waveform generation for the selected DAC channel: + * Noise mode and parameters LFSR (linear feedback shift register). + * @note For wave generation to be effective, DAC channel + * wave generation mode must be enabled using + * function @ref LL_DAC_SetWaveAutoGeneration(). + * @note This setting can be set when the selected DAC channel is disabled + * (otherwise, the setting operation is ignored). + * @rmtoll CR MAMP1 LL_DAC_SetWaveNoiseLFSR\n + * CR MAMP2 LL_DAC_SetWaveNoiseLFSR + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @param NoiseLFSRMask This parameter can be one of the following values: + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BIT0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS1_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS2_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS3_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS4_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS5_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS6_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS7_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS8_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS9_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS10_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS11_0 + * @retval None + */ +__STATIC_INLINE void LL_DAC_SetWaveNoiseLFSR(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t NoiseLFSRMask) +{ + MODIFY_REG(DACx->CR, + DAC_CR_MAMP1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK), + NoiseLFSRMask << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); +} + +/** + * @brief Get the noise waveform generation for the selected DAC channel: + * Noise mode and parameters LFSR (linear feedback shift register). + * @rmtoll CR MAMP1 LL_DAC_GetWaveNoiseLFSR\n + * CR MAMP2 LL_DAC_GetWaveNoiseLFSR + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BIT0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS1_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS2_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS3_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS4_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS5_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS6_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS7_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS8_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS9_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS10_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS11_0 + */ +__STATIC_INLINE uint32_t LL_DAC_GetWaveNoiseLFSR(const DAC_TypeDef *DACx, uint32_t DAC_Channel) +{ + return (uint32_t)(READ_BIT(DACx->CR, DAC_CR_MAMP1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)) + >> (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK) + ); +} + +/** + * @brief Set the triangle waveform generation for the selected DAC channel: + * triangle mode and amplitude. + * @note For wave generation to be effective, DAC channel + * wave generation mode must be enabled using + * function @ref LL_DAC_SetWaveAutoGeneration(). + * @note This setting can be set when the selected DAC channel is disabled + * (otherwise, the setting operation is ignored). + * @rmtoll CR MAMP1 LL_DAC_SetWaveTriangleAmplitude\n + * CR MAMP2 LL_DAC_SetWaveTriangleAmplitude + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @param TriangleAmplitude This parameter can be one of the following values: + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_1 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_3 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_7 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_15 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_31 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_63 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_127 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_255 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_511 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_1023 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_2047 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_4095 + * @retval None + */ +__STATIC_INLINE void LL_DAC_SetWaveTriangleAmplitude(DAC_TypeDef *DACx, uint32_t DAC_Channel, + uint32_t TriangleAmplitude) +{ + MODIFY_REG(DACx->CR, + DAC_CR_MAMP1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK), + TriangleAmplitude << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); +} + +/** + * @brief Get the triangle waveform generation for the selected DAC channel: + * triangle mode and amplitude. + * @rmtoll CR MAMP1 LL_DAC_GetWaveTriangleAmplitude\n + * CR MAMP2 LL_DAC_GetWaveTriangleAmplitude + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_1 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_3 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_7 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_15 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_31 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_63 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_127 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_255 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_511 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_1023 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_2047 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_4095 + */ +__STATIC_INLINE uint32_t LL_DAC_GetWaveTriangleAmplitude(const DAC_TypeDef *DACx, uint32_t DAC_Channel) +{ + return (uint32_t)(READ_BIT(DACx->CR, DAC_CR_MAMP1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)) + >> (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK) + ); +} + +/** + * @brief Set the output for the selected DAC channel. + * @note This function set several features: + * - mode normal or sample-and-hold + * - buffer + * - connection to GPIO or internal path. + * These features can also be set individually using + * dedicated functions: + * - @ref LL_DAC_SetOutputBuffer() + * - @ref LL_DAC_SetOutputMode() + * - @ref LL_DAC_SetOutputConnection() + * @note On this STM32 series, output connection depends on output mode + * (normal or sample and hold) and output buffer state. + * - if output connection is set to internal path and output buffer + * is enabled (whatever output mode): + * output connection is also connected to GPIO pin + * (both connections to GPIO pin and internal path). + * - if output connection is set to GPIO pin, output buffer + * is disabled, output mode set to sample and hold: + * output connection is also connected to internal path + * (both connections to GPIO pin and internal path). + * @note Mode sample-and-hold requires an external capacitor + * to be connected between DAC channel output and ground. + * Capacitor value depends on load on DAC channel output and + * sample-and-hold timings configured. + * As indication, capacitor typical value is 100nF + * (refer to device datasheet, parameter "CSH"). + * @rmtoll CR MODE1 LL_DAC_ConfigOutput\n + * CR MODE2 LL_DAC_ConfigOutput + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @param OutputMode This parameter can be one of the following values: + * @arg @ref LL_DAC_OUTPUT_MODE_NORMAL + * @arg @ref LL_DAC_OUTPUT_MODE_SAMPLE_AND_HOLD + * @param OutputBuffer This parameter can be one of the following values: + * @arg @ref LL_DAC_OUTPUT_BUFFER_ENABLE + * @arg @ref LL_DAC_OUTPUT_BUFFER_DISABLE + * @param OutputConnection This parameter can be one of the following values: + * @arg @ref LL_DAC_OUTPUT_CONNECT_GPIO + * @arg @ref LL_DAC_OUTPUT_CONNECT_INTERNAL + * @retval None + */ +__STATIC_INLINE void LL_DAC_ConfigOutput(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t OutputMode, + uint32_t OutputBuffer, uint32_t OutputConnection) +{ + MODIFY_REG(DACx->MCR, + (DAC_MCR_MODE1_2 | DAC_MCR_MODE1_1 | DAC_MCR_MODE1_0) << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK), + (OutputMode | OutputBuffer | OutputConnection) << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); +} + +/** + * @brief Set the output mode normal or sample-and-hold + * for the selected DAC channel. + * @note Mode sample-and-hold requires an external capacitor + * to be connected between DAC channel output and ground. + * Capacitor value depends on load on DAC channel output and + * sample-and-hold timings configured. + * As indication, capacitor typical value is 100nF + * (refer to device datasheet, parameter "CSH"). + * @rmtoll CR MODE1 LL_DAC_SetOutputMode\n + * CR MODE2 LL_DAC_SetOutputMode + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @param OutputMode This parameter can be one of the following values: + * @arg @ref LL_DAC_OUTPUT_MODE_NORMAL + * @arg @ref LL_DAC_OUTPUT_MODE_SAMPLE_AND_HOLD + * @retval None + */ +__STATIC_INLINE void LL_DAC_SetOutputMode(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t OutputMode) +{ + MODIFY_REG(DACx->MCR, + (uint32_t)DAC_MCR_MODE1_2 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK), + OutputMode << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); +} + +/** + * @brief Get the output mode normal or sample-and-hold for the selected DAC channel. + * @rmtoll CR MODE1 LL_DAC_GetOutputMode\n + * CR MODE2 LL_DAC_GetOutputMode + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DAC_OUTPUT_MODE_NORMAL + * @arg @ref LL_DAC_OUTPUT_MODE_SAMPLE_AND_HOLD + */ +__STATIC_INLINE uint32_t LL_DAC_GetOutputMode(const DAC_TypeDef *DACx, uint32_t DAC_Channel) +{ + return (uint32_t)(READ_BIT(DACx->MCR, (uint32_t)DAC_MCR_MODE1_2 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)) + >> (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK) + ); +} + +/** + * @brief Set the output buffer for the selected DAC channel. + * @note On this STM32 series, when buffer is enabled, its offset can be + * trimmed: factory calibration default values can be + * replaced by user trimming values, using function + * @ref LL_DAC_SetTrimmingValue(). + * @rmtoll CR MODE1 LL_DAC_SetOutputBuffer\n + * CR MODE2 LL_DAC_SetOutputBuffer + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @param OutputBuffer This parameter can be one of the following values: + * @arg @ref LL_DAC_OUTPUT_BUFFER_ENABLE + * @arg @ref LL_DAC_OUTPUT_BUFFER_DISABLE + * @retval None + */ +__STATIC_INLINE void LL_DAC_SetOutputBuffer(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t OutputBuffer) +{ + MODIFY_REG(DACx->MCR, + (uint32_t)DAC_MCR_MODE1_1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK), + OutputBuffer << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); +} + +/** + * @brief Get the output buffer state for the selected DAC channel. + * @rmtoll CR MODE1 LL_DAC_GetOutputBuffer\n + * CR MODE2 LL_DAC_GetOutputBuffer + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DAC_OUTPUT_BUFFER_ENABLE + * @arg @ref LL_DAC_OUTPUT_BUFFER_DISABLE + */ +__STATIC_INLINE uint32_t LL_DAC_GetOutputBuffer(const DAC_TypeDef *DACx, uint32_t DAC_Channel) +{ + return (uint32_t)(READ_BIT(DACx->MCR, (uint32_t)DAC_MCR_MODE1_1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)) + >> (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK) + ); +} + +/** + * @brief Set the output connection for the selected DAC channel. + * @note On this STM32 series, output connection depends on output mode (normal or + * sample and hold) and output buffer state. + * - if output connection is set to internal path and output buffer + * is enabled (whatever output mode): + * output connection is also connected to GPIO pin + * (both connections to GPIO pin and internal path). + * - if output connection is set to GPIO pin, output buffer + * is disabled, output mode set to sample and hold: + * output connection is also connected to internal path + * (both connections to GPIO pin and internal path). + * @rmtoll CR MODE1 LL_DAC_SetOutputConnection\n + * CR MODE2 LL_DAC_SetOutputConnection + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @param OutputConnection This parameter can be one of the following values: + * @arg @ref LL_DAC_OUTPUT_CONNECT_GPIO + * @arg @ref LL_DAC_OUTPUT_CONNECT_INTERNAL + * @retval None + */ +__STATIC_INLINE void LL_DAC_SetOutputConnection(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t OutputConnection) +{ + MODIFY_REG(DACx->MCR, + (uint32_t)DAC_MCR_MODE1_0 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK), + OutputConnection << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); +} + +/** + * @brief Get the output connection for the selected DAC channel. + * @note On this STM32 series, output connection depends on output mode (normal or + * sample and hold) and output buffer state. + * - if output connection is set to internal path and output buffer + * is enabled (whatever output mode): + * output connection is also connected to GPIO pin + * (both connections to GPIO pin and internal path). + * - if output connection is set to GPIO pin, output buffer + * is disabled, output mode set to sample and hold: + * output connection is also connected to internal path + * (both connections to GPIO pin and internal path). + * @rmtoll CR MODE1 LL_DAC_GetOutputConnection\n + * CR MODE2 LL_DAC_GetOutputConnection + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DAC_OUTPUT_CONNECT_GPIO + * @arg @ref LL_DAC_OUTPUT_CONNECT_INTERNAL + */ +__STATIC_INLINE uint32_t LL_DAC_GetOutputConnection(const DAC_TypeDef *DACx, uint32_t DAC_Channel) +{ + return (uint32_t)(READ_BIT(DACx->MCR, (uint32_t)DAC_MCR_MODE1_0 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)) + >> (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK) + ); +} + +/** + * @brief Set the sample-and-hold timing for the selected DAC channel: + * sample time + * @note Sample time must be set when DAC channel is disabled + * or during DAC operation when DAC channel flag BWSTx is reset, + * otherwise the setting is ignored. + * Check BWSTx flag state using function "LL_DAC_IsActiveFlag_BWSTx()". + * @rmtoll SHSR1 TSAMPLE1 LL_DAC_SetSampleAndHoldSampleTime\n + * SHSR2 TSAMPLE2 LL_DAC_SetSampleAndHoldSampleTime + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @param SampleTime Value between Min_Data=0x000 and Max_Data=0x3FF + * @retval None + */ +__STATIC_INLINE void LL_DAC_SetSampleAndHoldSampleTime(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t SampleTime) +{ + __IO uint32_t *preg = __DAC_PTR_REG_OFFSET(DACx->SHSR1, (DAC_Channel >> DAC_REG_SHSRX_REGOFFSET_BITOFFSET_POS) + & DAC_REG_SHSRX_REGOFFSET_MASK_POSBIT0); + + MODIFY_REG(*preg, DAC_SHSR1_TSAMPLE1, SampleTime); +} + +/** + * @brief Get the sample-and-hold timing for the selected DAC channel: + * sample time + * @rmtoll SHSR1 TSAMPLE1 LL_DAC_GetSampleAndHoldSampleTime\n + * SHSR2 TSAMPLE2 LL_DAC_GetSampleAndHoldSampleTime + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval Value between Min_Data=0x000 and Max_Data=0x3FF + */ +__STATIC_INLINE uint32_t LL_DAC_GetSampleAndHoldSampleTime(const DAC_TypeDef *DACx, uint32_t DAC_Channel) +{ + __IO uint32_t const *preg = __DAC_PTR_REG_OFFSET(DACx->SHSR1, (DAC_Channel >> DAC_REG_SHSRX_REGOFFSET_BITOFFSET_POS) + & DAC_REG_SHSRX_REGOFFSET_MASK_POSBIT0); + + return (uint32_t) READ_BIT(*preg, DAC_SHSR1_TSAMPLE1); +} + +/** + * @brief Set the sample-and-hold timing for the selected DAC channel: + * hold time + * @rmtoll SHHR THOLD1 LL_DAC_SetSampleAndHoldHoldTime\n + * SHHR THOLD2 LL_DAC_SetSampleAndHoldHoldTime + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @param HoldTime Value between Min_Data=0x000 and Max_Data=0x3FF + * @retval None + */ +__STATIC_INLINE void LL_DAC_SetSampleAndHoldHoldTime(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t HoldTime) +{ + MODIFY_REG(DACx->SHHR, + DAC_SHHR_THOLD1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK), + HoldTime << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); +} + +/** + * @brief Get the sample-and-hold timing for the selected DAC channel: + * hold time + * @rmtoll SHHR THOLD1 LL_DAC_GetSampleAndHoldHoldTime\n + * SHHR THOLD2 LL_DAC_GetSampleAndHoldHoldTime + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval Value between Min_Data=0x000 and Max_Data=0x3FF + */ +__STATIC_INLINE uint32_t LL_DAC_GetSampleAndHoldHoldTime(const DAC_TypeDef *DACx, uint32_t DAC_Channel) +{ + return (uint32_t)(READ_BIT(DACx->SHHR, DAC_SHHR_THOLD1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)) + >> (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK) + ); +} + +/** + * @brief Set the sample-and-hold timing for the selected DAC channel: + * refresh time + * @rmtoll SHRR TREFRESH1 LL_DAC_SetSampleAndHoldRefreshTime\n + * SHRR TREFRESH2 LL_DAC_SetSampleAndHoldRefreshTime + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @param RefreshTime Value between Min_Data=0x00 and Max_Data=0xFF + * @retval None + */ +__STATIC_INLINE void LL_DAC_SetSampleAndHoldRefreshTime(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t RefreshTime) +{ + MODIFY_REG(DACx->SHRR, + DAC_SHRR_TREFRESH1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK), + RefreshTime << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); +} + +/** + * @brief Get the sample-and-hold timing for the selected DAC channel: + * refresh time + * @rmtoll SHRR TREFRESH1 LL_DAC_GetSampleAndHoldRefreshTime\n + * SHRR TREFRESH2 LL_DAC_GetSampleAndHoldRefreshTime + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval Value between Min_Data=0x00 and Max_Data=0xFF + */ +__STATIC_INLINE uint32_t LL_DAC_GetSampleAndHoldRefreshTime(const DAC_TypeDef *DACx, uint32_t DAC_Channel) +{ + return (uint32_t)(READ_BIT(DACx->SHRR, DAC_SHRR_TREFRESH1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)) + >> (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK) + ); +} + +/** + * @brief Set the signed format for the selected DAC channel. + * @note On this STM32 series, signed format can be used to inject + * Q1.15, Q1.11, Q1.7 signed format data to DAC. + * Ex when using 12bits data format (Q1.11 is used): + * 0x800 will output 0v level + * 0xFFF will output mid-scale level + * 0x000 will output mid-scale level + * 0x7FF will output full-scale level + * @rmtoll MCR SINFORMAT1 LL_DAC_SetSignedFormat\n + * MCR SINFORMAT2 LL_DAC_SetSignedFormat + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @param SignedFormat This parameter can be one of the following values: + * @arg @ref LL_DAC_SIGNED_FORMAT_ENABLE + * @arg @ref LL_DAC_SIGNED_FORMAT_DISABLE + * @retval None + */ +__STATIC_INLINE void LL_DAC_SetSignedFormat(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t SignedFormat) +{ + MODIFY_REG(DACx->MCR, + DAC_MCR_SINFORMAT1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK), + SignedFormat << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); +} + +/** + * @brief Get the signed format state for the selected DAC channel. + * @rmtoll MCR SINFORMAT1 LL_DAC_GetSignedFormat\n + * MCR SINFORMAT2 LL_DAC_GetSignedFormat + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DAC_SIGNED_FORMAT_ENABLE + * @arg @ref LL_DAC_SIGNED_FORMAT_DISABLE + */ +__STATIC_INLINE uint32_t LL_DAC_GetSignedFormat(const DAC_TypeDef *DACx, uint32_t DAC_Channel) +{ + return (uint32_t)(READ_BIT(DACx->MCR, DAC_MCR_SINFORMAT1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)) + >> (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK) + ); +} + +/** + * @} + */ + +/** @defgroup DAC_LL_EF_DMA_Management DMA Management + * @{ + */ + +/** + * @brief Enable DAC DMA transfer request of the selected channel. + * @note To configure DMA source address (peripheral address), + * use function @ref LL_DAC_DMA_GetRegAddr(). + * @rmtoll CR DMAEN1 LL_DAC_EnableDMAReq\n + * CR DMAEN2 LL_DAC_EnableDMAReq + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval None + */ +__STATIC_INLINE void LL_DAC_EnableDMAReq(DAC_TypeDef *DACx, uint32_t DAC_Channel) +{ + SET_BIT(DACx->CR, + DAC_CR_DMAEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); +} + +/** + * @brief Disable DAC DMA transfer request of the selected channel. + * @note To configure DMA source address (peripheral address), + * use function @ref LL_DAC_DMA_GetRegAddr(). + * @rmtoll CR DMAEN1 LL_DAC_DisableDMAReq\n + * CR DMAEN2 LL_DAC_DisableDMAReq + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval None + */ +__STATIC_INLINE void LL_DAC_DisableDMAReq(DAC_TypeDef *DACx, uint32_t DAC_Channel) +{ + CLEAR_BIT(DACx->CR, + DAC_CR_DMAEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); +} + +/** + * @brief Get DAC DMA transfer request state of the selected channel. + * (0: DAC DMA transfer request is disabled, 1: DAC DMA transfer request is enabled) + * @rmtoll CR DMAEN1 LL_DAC_IsDMAReqEnabled\n + * CR DMAEN2 LL_DAC_IsDMAReqEnabled + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DAC_IsDMAReqEnabled(const DAC_TypeDef *DACx, uint32_t DAC_Channel) +{ + return ((READ_BIT(DACx->CR, + DAC_CR_DMAEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)) + == (DAC_CR_DMAEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK))) ? 1UL : 0UL); +} + +/** + * @brief Enable DAC DMA Double data mode of the selected channel. + * @rmtoll MCR DMADOUBLE1 LL_DAC_EnableDMADoubleDataMode\n + * MCR DMADOUBLE2 LL_DAC_EnableDMADoubleDataMode + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval None + */ +__STATIC_INLINE void LL_DAC_EnableDMADoubleDataMode(DAC_TypeDef *DACx, uint32_t DAC_Channel) +{ + SET_BIT(DACx->MCR, + DAC_MCR_DMADOUBLE1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); +} + +/** + * @brief Disable DAC DMA Double data mode of the selected channel. + * @rmtoll MCR DMADOUBLE1 LL_DAC_DisableDMADoubleDataMode\n + * MCR DMADOUBLE2 LL_DAC_DisableDMADoubleDataMode + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval None + */ +__STATIC_INLINE void LL_DAC_DisableDMADoubleDataMode(DAC_TypeDef *DACx, uint32_t DAC_Channel) +{ + CLEAR_BIT(DACx->MCR, + DAC_MCR_DMADOUBLE1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); +} + +/** + * @brief Get DAC DMA double data mode state of the selected channel. + * (0: DAC DMA double data mode is disabled, 1: DAC DMA double data mode is enabled) + * @rmtoll MCR DMADOUBLE1 LL_DAC_IsDMADoubleDataModeEnabled\n + * MCR DMADOUBLE2 LL_DAC_IsDMADoubleDataModeEnabled + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DAC_IsDMADoubleDataModeEnabled(const DAC_TypeDef *DACx, uint32_t DAC_Channel) +{ + return ((READ_BIT(DACx->MCR, + DAC_MCR_DMADOUBLE1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)) + == (DAC_MCR_DMADOUBLE1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK))) ? 1UL : 0UL); +} + +/** + * @brief Function to help to configure DMA transfer to DAC: retrieve the + * DAC register address from DAC instance and a list of DAC registers + * intended to be used (most commonly) with DMA transfer. + * @note These DAC registers are data holding registers: + * when DAC conversion is requested, DAC generates a DMA transfer + * request to have data available in DAC data holding registers. + * @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, + * (uint32_t)&< array or variable >, + * LL_DAC_DMA_GetRegAddr(DAC1, LL_DAC_CHANNEL_1, + * LL_DAC_DMA_REG_DATA_12BITS_RIGHT_ALIGNED), + * LL_DMA_DIRECTION_MEMORY_TO_PERIPH); + * @rmtoll DHR12R1 DACC1DHR LL_DAC_DMA_GetRegAddr\n + * DHR12L1 DACC1DHR LL_DAC_DMA_GetRegAddr\n + * DHR8R1 DACC1DHR LL_DAC_DMA_GetRegAddr\n + * DHR12R2 DACC2DHR LL_DAC_DMA_GetRegAddr\n + * DHR12L2 DACC2DHR LL_DAC_DMA_GetRegAddr\n + * DHR8R2 DACC2DHR LL_DAC_DMA_GetRegAddr + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @param Register This parameter can be one of the following values: + * @arg @ref LL_DAC_DMA_REG_DATA_12BITS_RIGHT_ALIGNED + * @arg @ref LL_DAC_DMA_REG_DATA_12BITS_LEFT_ALIGNED + * @arg @ref LL_DAC_DMA_REG_DATA_8BITS_RIGHT_ALIGNED + * @retval DAC register address + */ +__STATIC_INLINE uint32_t LL_DAC_DMA_GetRegAddr(const DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t Register) +{ + /* Retrieve address of register DHR12Rx, DHR12Lx or DHR8Rx depending on */ + /* DAC channel selected. */ + return ((uint32_t)(__DAC_PTR_REG_OFFSET((DACx)->DHR12R1, ((DAC_Channel >> (Register & 0x1FUL)) + & DAC_REG_DHR_REGOFFSET_MASK_POSBIT0)))); +} +/** + * @} + */ + +/** @defgroup DAC_LL_EF_Operation Operation on DAC channels + * @{ + */ + +/** + * @brief Enable DAC selected channel. + * @rmtoll CR EN1 LL_DAC_Enable\n + * CR EN2 LL_DAC_Enable + * @note After enable from off state, DAC channel requires a delay + * for output voltage to reach accuracy +/- 1 LSB. + * Refer to device datasheet, parameter "tWAKEUP". + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval None + */ +__STATIC_INLINE void LL_DAC_Enable(DAC_TypeDef *DACx, uint32_t DAC_Channel) +{ + SET_BIT(DACx->CR, + DAC_CR_EN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); +} + +/** + * @brief Disable DAC selected channel. + * @rmtoll CR EN1 LL_DAC_Disable\n + * CR EN2 LL_DAC_Disable + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval None + */ +__STATIC_INLINE void LL_DAC_Disable(DAC_TypeDef *DACx, uint32_t DAC_Channel) +{ + CLEAR_BIT(DACx->CR, + DAC_CR_EN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); +} + +/** + * @brief Get DAC enable state of the selected channel. + * (0: DAC channel is disabled, 1: DAC channel is enabled) + * @rmtoll CR EN1 LL_DAC_IsEnabled\n + * CR EN2 LL_DAC_IsEnabled + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DAC_IsEnabled(const DAC_TypeDef *DACx, uint32_t DAC_Channel) +{ + return ((READ_BIT(DACx->CR, + DAC_CR_EN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)) + == (DAC_CR_EN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK))) ? 1UL : 0UL); +} + +/** + * @brief Get DAC ready for conversion state of the selected channel. + * (0: DAC channel is not ready, 1: DAC channel is ready) + * @rmtoll SR DAC1RDY LL_DAC_IsReady\n + * SR DAC2RDY LL_DAC_IsReady + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DAC_IsReady(const DAC_TypeDef *DACx, uint32_t DAC_Channel) +{ + return ((READ_BIT(DACx->SR, + DAC_SR_DAC1RDY << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)) + == (DAC_SR_DAC1RDY << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK))) ? 1UL : 0UL); +} + +/** + * @brief Enable DAC trigger of the selected channel. + * @note - If DAC trigger is disabled, DAC conversion is performed + * automatically once the data holding register is updated, + * using functions "LL_DAC_ConvertData{8; 12}{Right; Left} Aligned()": + * @ref LL_DAC_ConvertData12RightAligned(), ... + * - If DAC trigger is enabled, DAC conversion is performed + * only when a hardware of software trigger event is occurring. + * Select trigger source using + * function @ref LL_DAC_SetTriggerSource(). + * @rmtoll CR TEN1 LL_DAC_EnableTrigger\n + * CR TEN2 LL_DAC_EnableTrigger + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval None + */ +__STATIC_INLINE void LL_DAC_EnableTrigger(DAC_TypeDef *DACx, uint32_t DAC_Channel) +{ + SET_BIT(DACx->CR, + DAC_CR_TEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); +} + +/** + * @brief Disable DAC trigger of the selected channel. + * @rmtoll CR TEN1 LL_DAC_DisableTrigger\n + * CR TEN2 LL_DAC_DisableTrigger + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval None + */ +__STATIC_INLINE void LL_DAC_DisableTrigger(DAC_TypeDef *DACx, uint32_t DAC_Channel) +{ + CLEAR_BIT(DACx->CR, + DAC_CR_TEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); +} + +/** + * @brief Get DAC trigger state of the selected channel. + * (0: DAC trigger is disabled, 1: DAC trigger is enabled) + * @rmtoll CR TEN1 LL_DAC_IsTriggerEnabled\n + * CR TEN2 LL_DAC_IsTriggerEnabled + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DAC_IsTriggerEnabled(const DAC_TypeDef *DACx, uint32_t DAC_Channel) +{ + return ((READ_BIT(DACx->CR, + DAC_CR_TEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)) + == (DAC_CR_TEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK))) ? 1UL : 0UL); +} + +/** + * @brief Trig DAC conversion by software for the selected DAC channel. + * @note Preliminarily, DAC trigger must be set to software trigger + * using function + * @ref LL_DAC_Init() + * @ref LL_DAC_SetTriggerSource() + * with parameter "LL_DAC_TRIGGER_SOFTWARE". + * and DAC trigger must be enabled using + * function @ref LL_DAC_EnableTrigger(). + * @note For devices featuring DAC with 2 channels: this function + * can perform a SW start of both DAC channels simultaneously. + * Two channels can be selected as parameter. + * Example: (LL_DAC_CHANNEL_1 | LL_DAC_CHANNEL_2) + * @rmtoll SWTRIGR SWTRIG1 LL_DAC_TrigSWConversion\n + * SWTRIGR SWTRIG2 LL_DAC_TrigSWConversion + * @param DACx DAC instance + * @param DAC_Channel This parameter can a combination of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval None + */ +__STATIC_INLINE void LL_DAC_TrigSWConversion(DAC_TypeDef *DACx, uint32_t DAC_Channel) +{ + SET_BIT(DACx->SWTRIGR, + (DAC_Channel & DAC_SWTR_CHX_MASK)); +} + +/** + * @brief Set the data to be loaded in the data holding register + * in format 12 bits left alignment (LSB aligned on bit 0), + * for the selected DAC channel. + * @rmtoll DHR12R1 DACC1DHR LL_DAC_ConvertData12RightAligned\n + * DHR12R2 DACC2DHR LL_DAC_ConvertData12RightAligned + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @param Data Value between Min_Data=0x000 and Max_Data=0xFFF + * @retval None + */ +__STATIC_INLINE void LL_DAC_ConvertData12RightAligned(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t Data) +{ + __IO uint32_t *preg = __DAC_PTR_REG_OFFSET(DACx->DHR12R1, (DAC_Channel >> DAC_REG_DHR12RX_REGOFFSET_BITOFFSET_POS) + & DAC_REG_DHR_REGOFFSET_MASK_POSBIT0); + + MODIFY_REG(*preg, DAC_DHR12R1_DACC1DHR, Data); +} + +/** + * @brief Set the data to be loaded in the data holding register + * in format 12 bits left alignment (MSB aligned on bit 15), + * for the selected DAC channel. + * @rmtoll DHR12L1 DACC1DHR LL_DAC_ConvertData12LeftAligned\n + * DHR12L2 DACC2DHR LL_DAC_ConvertData12LeftAligned + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @param Data Value between Min_Data=0x000 and Max_Data=0xFFF + * @retval None + */ +__STATIC_INLINE void LL_DAC_ConvertData12LeftAligned(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t Data) +{ + __IO uint32_t *preg = __DAC_PTR_REG_OFFSET(DACx->DHR12R1, (DAC_Channel >> DAC_REG_DHR12LX_REGOFFSET_BITOFFSET_POS) + & DAC_REG_DHR_REGOFFSET_MASK_POSBIT0); + + MODIFY_REG(*preg, DAC_DHR12L1_DACC1DHR, Data); +} + +/** + * @brief Set the data to be loaded in the data holding register + * in format 8 bits left alignment (LSB aligned on bit 0), + * for the selected DAC channel. + * @rmtoll DHR8R1 DACC1DHR LL_DAC_ConvertData8RightAligned\n + * DHR8R2 DACC2DHR LL_DAC_ConvertData8RightAligned + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @param Data Value between Min_Data=0x00 and Max_Data=0xFF + * @retval None + */ +__STATIC_INLINE void LL_DAC_ConvertData8RightAligned(DAC_TypeDef *DACx, uint32_t DAC_Channel, uint32_t Data) +{ + __IO uint32_t *preg = __DAC_PTR_REG_OFFSET(DACx->DHR12R1, (DAC_Channel >> DAC_REG_DHR8RX_REGOFFSET_BITOFFSET_POS) + & DAC_REG_DHR_REGOFFSET_MASK_POSBIT0); + + MODIFY_REG(*preg, DAC_DHR8R1_DACC1DHR, Data); +} + + +/** + * @brief Set the data to be loaded in the data holding register + * in format 12 bits left alignment (LSB aligned on bit 0), + * for both DAC channels. + * @rmtoll DHR12RD DACC1DHR LL_DAC_ConvertDualData12RightAligned\n + * DHR12RD DACC2DHR LL_DAC_ConvertDualData12RightAligned + * @param DACx DAC instance + * @param DataChannel1 Value between Min_Data=0x000 and Max_Data=0xFFF + * @param DataChannel2 Value between Min_Data=0x000 and Max_Data=0xFFF + * @retval None + */ +__STATIC_INLINE void LL_DAC_ConvertDualData12RightAligned(DAC_TypeDef *DACx, uint32_t DataChannel1, + uint32_t DataChannel2) +{ + MODIFY_REG(DACx->DHR12RD, + (DAC_DHR12RD_DACC2DHR | DAC_DHR12RD_DACC1DHR), + ((DataChannel2 << DAC_DHR12RD_DACC2DHR_BITOFFSET_POS) | DataChannel1)); +} + +/** + * @brief Set the data to be loaded in the data holding register + * in format 12 bits left alignment (MSB aligned on bit 15), + * for both DAC channels. + * @rmtoll DHR12LD DACC1DHR LL_DAC_ConvertDualData12LeftAligned\n + * DHR12LD DACC2DHR LL_DAC_ConvertDualData12LeftAligned + * @param DACx DAC instance + * @param DataChannel1 Value between Min_Data=0x000 and Max_Data=0xFFF + * @param DataChannel2 Value between Min_Data=0x000 and Max_Data=0xFFF + * @retval None + */ +__STATIC_INLINE void LL_DAC_ConvertDualData12LeftAligned(DAC_TypeDef *DACx, uint32_t DataChannel1, + uint32_t DataChannel2) +{ + /* Note: Data of DAC channel 2 shift value subtracted of 4 because */ + /* data on 16 bits and DAC channel 2 bits field is on the 12 MSB, */ + /* the 4 LSB must be taken into account for the shift value. */ + MODIFY_REG(DACx->DHR12LD, + (DAC_DHR12LD_DACC2DHR | DAC_DHR12LD_DACC1DHR), + ((DataChannel2 << (DAC_DHR12LD_DACC2DHR_BITOFFSET_POS - 4U)) | DataChannel1)); +} + +/** + * @brief Set the data to be loaded in the data holding register + * in format 8 bits left alignment (LSB aligned on bit 0), + * for both DAC channels. + * @rmtoll DHR8RD DACC1DHR LL_DAC_ConvertDualData8RightAligned\n + * DHR8RD DACC2DHR LL_DAC_ConvertDualData8RightAligned + * @param DACx DAC instance + * @param DataChannel1 Value between Min_Data=0x00 and Max_Data=0xFF + * @param DataChannel2 Value between Min_Data=0x00 and Max_Data=0xFF + * @retval None + */ +__STATIC_INLINE void LL_DAC_ConvertDualData8RightAligned(DAC_TypeDef *DACx, uint32_t DataChannel1, + uint32_t DataChannel2) +{ + MODIFY_REG(DACx->DHR8RD, + (DAC_DHR8RD_DACC2DHR | DAC_DHR8RD_DACC1DHR), + ((DataChannel2 << DAC_DHR8RD_DACC2DHR_BITOFFSET_POS) | DataChannel1)); +} + + +/** + * @brief Retrieve output data currently generated for the selected DAC channel. + * @note Whatever alignment and resolution settings + * (using functions "LL_DAC_ConvertData{8; 12}{Right; Left} Aligned()": + * @ref LL_DAC_ConvertData12RightAligned(), ...), + * output data format is 12 bits right aligned (LSB aligned on bit 0). + * @rmtoll DOR1 DACC1DOR LL_DAC_RetrieveOutputData\n + * DOR2 DACC2DOR LL_DAC_RetrieveOutputData + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @retval Value between Min_Data=0x000 and Max_Data=0xFFF + */ +__STATIC_INLINE uint32_t LL_DAC_RetrieveOutputData(const DAC_TypeDef *DACx, uint32_t DAC_Channel) +{ + __IO uint32_t const *preg = __DAC_PTR_REG_OFFSET(DACx->DOR1, (DAC_Channel >> DAC_REG_DORX_REGOFFSET_BITOFFSET_POS) + & DAC_REG_DORX_REGOFFSET_MASK_POSBIT0); + + return (uint16_t) READ_BIT(*preg, DAC_DOR1_DACC1DOR); +} + +/** + * @} + */ + +/** @defgroup DAC_LL_EF_FLAG_Management FLAG Management + * @{ + */ + +/** + * @brief Get DAC calibration offset flag for DAC channel 1 + * @rmtoll SR CAL_FLAG1 LL_DAC_IsActiveFlag_CAL1 + * @param DACx DAC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DAC_IsActiveFlag_CAL1(const DAC_TypeDef *DACx) +{ + return ((READ_BIT(DACx->SR, LL_DAC_FLAG_CAL1) == (LL_DAC_FLAG_CAL1)) ? 1UL : 0UL); +} + + +/** + * @brief Get DAC calibration offset flag for DAC channel 2 + * @rmtoll SR CAL_FLAG2 LL_DAC_IsActiveFlag_CAL2 + * @param DACx DAC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DAC_IsActiveFlag_CAL2(const DAC_TypeDef *DACx) +{ + return ((READ_BIT(DACx->SR, LL_DAC_FLAG_CAL2) == (LL_DAC_FLAG_CAL2)) ? 1UL : 0UL); +} + + +/** + * @brief Get DAC busy writing sample time flag for DAC channel 1 + * @rmtoll SR BWST1 LL_DAC_IsActiveFlag_BWST1 + * @param DACx DAC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DAC_IsActiveFlag_BWST1(const DAC_TypeDef *DACx) +{ + return ((READ_BIT(DACx->SR, LL_DAC_FLAG_BWST1) == (LL_DAC_FLAG_BWST1)) ? 1UL : 0UL); +} + +/** + * @brief Get DAC busy writing sample time flag for DAC channel 2 + * @rmtoll SR BWST2 LL_DAC_IsActiveFlag_BWST2 + * @param DACx DAC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DAC_IsActiveFlag_BWST2(const DAC_TypeDef *DACx) +{ + return ((READ_BIT(DACx->SR, LL_DAC_FLAG_BWST2) == (LL_DAC_FLAG_BWST2)) ? 1UL : 0UL); +} + + +/** + * @brief Get DAC ready status flag for DAC channel 1 + * @rmtoll SR DAC1RDY LL_DAC_IsActiveFlag_DAC1RDY + * @param DACx DAC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DAC_IsActiveFlag_DAC1RDY(const DAC_TypeDef *DACx) +{ + return ((READ_BIT(DACx->SR, LL_DAC_FLAG_DAC1RDY) == (LL_DAC_FLAG_DAC1RDY)) ? 1UL : 0UL); +} + + +/** + * @brief Get DAC ready status flag for DAC channel 2 + * @rmtoll SR DAC2RDY LL_DAC_IsActiveFlag_DAC2RDY + * @param DACx DAC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DAC_IsActiveFlag_DAC2RDY(const DAC_TypeDef *DACx) +{ + return ((READ_BIT(DACx->SR, LL_DAC_FLAG_DAC2RDY) == (LL_DAC_FLAG_DAC2RDY)) ? 1UL : 0UL); +} + + +/** + * @brief Get DAC output register status flag for DAC channel 1 + * @rmtoll SR DORSTAT1 LL_DAC_IsActiveFlag_DORSTAT1 + * @param DACx DAC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DAC_IsActiveFlag_DORSTAT1(const DAC_TypeDef *DACx) +{ + return ((READ_BIT(DACx->SR, LL_DAC_FLAG_DORSTAT1) == (LL_DAC_FLAG_DORSTAT1)) ? 1UL : 0UL); +} + + +/** + * @brief Get DAC output register status flag for DAC channel 2 + * @rmtoll SR DORSTAT2 LL_DAC_IsActiveFlag_DORSTAT2 + * @param DACx DAC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DAC_IsActiveFlag_DORSTAT2(const DAC_TypeDef *DACx) +{ + return ((READ_BIT(DACx->SR, LL_DAC_FLAG_DORSTAT2) == (LL_DAC_FLAG_DORSTAT2)) ? 1UL : 0UL); +} + +/** + * @brief Get DAC underrun flag for DAC channel 1 + * @rmtoll SR DMAUDR1 LL_DAC_IsActiveFlag_DMAUDR1 + * @param DACx DAC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DAC_IsActiveFlag_DMAUDR1(const DAC_TypeDef *DACx) +{ + return ((READ_BIT(DACx->SR, LL_DAC_FLAG_DMAUDR1) == (LL_DAC_FLAG_DMAUDR1)) ? 1UL : 0UL); +} + + +/** + * @brief Get DAC underrun flag for DAC channel 2 + * @rmtoll SR DMAUDR2 LL_DAC_IsActiveFlag_DMAUDR2 + * @param DACx DAC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DAC_IsActiveFlag_DMAUDR2(const DAC_TypeDef *DACx) +{ + return ((READ_BIT(DACx->SR, LL_DAC_FLAG_DMAUDR2) == (LL_DAC_FLAG_DMAUDR2)) ? 1UL : 0UL); +} + + +/** + * @brief Clear DAC underrun flag for DAC channel 1 + * @rmtoll SR DMAUDR1 LL_DAC_ClearFlag_DMAUDR1 + * @param DACx DAC instance + * @retval None + */ +__STATIC_INLINE void LL_DAC_ClearFlag_DMAUDR1(DAC_TypeDef *DACx) +{ + WRITE_REG(DACx->SR, LL_DAC_FLAG_DMAUDR1); +} + + +/** + * @brief Clear DAC underrun flag for DAC channel 2 + * @rmtoll SR DMAUDR2 LL_DAC_ClearFlag_DMAUDR2 + * @param DACx DAC instance + * @retval None + */ +__STATIC_INLINE void LL_DAC_ClearFlag_DMAUDR2(DAC_TypeDef *DACx) +{ + WRITE_REG(DACx->SR, LL_DAC_FLAG_DMAUDR2); +} + + +/** + * @} + */ + +/** @defgroup DAC_LL_EF_IT_Management IT management + * @{ + */ + +/** + * @brief Enable DMA underrun interrupt for DAC channel 1 + * @rmtoll CR DMAUDRIE1 LL_DAC_EnableIT_DMAUDR1 + * @param DACx DAC instance + * @retval None + */ +__STATIC_INLINE void LL_DAC_EnableIT_DMAUDR1(DAC_TypeDef *DACx) +{ + SET_BIT(DACx->CR, LL_DAC_IT_DMAUDRIE1); +} + + +/** + * @brief Enable DMA underrun interrupt for DAC channel 2 + * @rmtoll CR DMAUDRIE2 LL_DAC_EnableIT_DMAUDR2 + * @param DACx DAC instance + * @retval None + */ +__STATIC_INLINE void LL_DAC_EnableIT_DMAUDR2(DAC_TypeDef *DACx) +{ + SET_BIT(DACx->CR, LL_DAC_IT_DMAUDRIE2); +} + + +/** + * @brief Disable DMA underrun interrupt for DAC channel 1 + * @rmtoll CR DMAUDRIE1 LL_DAC_DisableIT_DMAUDR1 + * @param DACx DAC instance + * @retval None + */ +__STATIC_INLINE void LL_DAC_DisableIT_DMAUDR1(DAC_TypeDef *DACx) +{ + CLEAR_BIT(DACx->CR, LL_DAC_IT_DMAUDRIE1); +} + + +/** + * @brief Disable DMA underrun interrupt for DAC channel 2 + * @rmtoll CR DMAUDRIE2 LL_DAC_DisableIT_DMAUDR2 + * @param DACx DAC instance + * @retval None + */ +__STATIC_INLINE void LL_DAC_DisableIT_DMAUDR2(DAC_TypeDef *DACx) +{ + CLEAR_BIT(DACx->CR, LL_DAC_IT_DMAUDRIE2); +} + + +/** + * @brief Get DMA underrun interrupt for DAC channel 1 + * @rmtoll CR DMAUDRIE1 LL_DAC_IsEnabledIT_DMAUDR1 + * @param DACx DAC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DAC_IsEnabledIT_DMAUDR1(const DAC_TypeDef *DACx) +{ + return ((READ_BIT(DACx->CR, LL_DAC_IT_DMAUDRIE1) == (LL_DAC_IT_DMAUDRIE1)) ? 1UL : 0UL); +} + + +/** + * @brief Get DMA underrun interrupt for DAC channel 2 + * @rmtoll CR DMAUDRIE2 LL_DAC_IsEnabledIT_DMAUDR2 + * @param DACx DAC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DAC_IsEnabledIT_DMAUDR2(const DAC_TypeDef *DACx) +{ + return ((READ_BIT(DACx->CR, LL_DAC_IT_DMAUDRIE2) == (LL_DAC_IT_DMAUDRIE2)) ? 1UL : 0UL); +} + + +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup DAC_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +ErrorStatus LL_DAC_DeInit(const DAC_TypeDef *DACx); +ErrorStatus LL_DAC_Init(DAC_TypeDef *DACx, uint32_t DAC_Channel, const LL_DAC_InitTypeDef *DAC_InitStruct); +void LL_DAC_StructInit(LL_DAC_InitTypeDef *DAC_InitStruct); + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* DAC1 */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_LL_DAC_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_dcache.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_dcache.h new file mode 100644 index 0000000000..f12262406d --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_dcache.h @@ -0,0 +1,667 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_dcache.h + * @author MCD Application Team + * @brief Header file of DCACHE LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion ------------------------------------*/ +#ifndef STM32H5xx_LL_DCACHE_H +#define STM32H5xx_LL_DCACHE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes -----------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (DCACHE1) + +/** @defgroup DCACHE_LL DCACHE + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup DCACHE_Exported_Constants DCACHE Exported Constants + * @{ + */ +/** @defgroup DCACHE_Command_Operation Command Operation + * @{ + */ +#define LL_DCACHE_COMMAND_NO_OPERATION (0x00000000) +#define LL_DCACHE_COMMAND_CLEAN_BY_ADDR DCACHE_CR_CACHECMD_0 +#define LL_DCACHE_COMMAND_INVALIDATE_BY_ADDR DCACHE_CR_CACHECMD_1 +#define LL_DCACHE_COMMAND_CLEAN_INVALIDATE_BY_ADDR (DCACHE_CR_CACHECMD_0|DCACHE_CR_CACHECMD_1) +/** + * @} + */ + +/** @defgroup DCACHE_Read_Burst_Type Remapped Output burst type + * @{ + */ +#define LL_DCACHE_READ_BURST_WRAP 0U /*!< WRAP */ +#define LL_DCACHE_READ_BURST_INCR DCACHE_CR_HBURST /*!< INCR */ +/** + * @} + */ + +/** @defgroup DCACHE_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_DCACHE_ReadReg function + * @{ + */ +#define LL_DCACHE_SR_ERRF DCACHE_SR_ERRF /*!< Cache error flag */ +#define LL_DCACHE_SR_BUSYF DCACHE_SR_BUSYF /*!< Busy flag */ +#define LL_DCACHE_SR_CMDENDF DCACHE_SR_CMDENDF /*!< Command end flag */ +#define LL_DCACHE_SR_BSYENDF DCACHE_SR_BSYENDF /*!< Full invalidate busy end flag */ +#define LL_DCACHE_SR_BUSYCMDF DCACHE_SR_BUSYCMDF /*!< Command busy flag */ +/** + * @} + */ + +/** @defgroup DCACHE_LL_EC_CLEAR_FLAG Clear Flags Defines + * @brief Flags defines which can be used with LL_DCACHE_WriteReg function + * @{ + */ +#define LL_DCACHE_FCR_CERRF DCACHE_FCR_CERRF /*!< Cache error flag */ +#define LL_DCACHE_FCR_CBSYENDF DCACHE_FCR_CBSYENDF /*!< Full invalidate busy end flag */ +#define LL_DCACHE_FCR_CCMDENDF DCACHE_FCR_CCMDENDF /*!< Command end flag*/ +/** + * @} + */ + +/** @defgroup DCACHE_LL_EC_IT IT Defines + * @brief IT defines which can be used with LL_DCACHE_ReadReg and LL_DCACHE_WriteReg functions + * @{ + */ +#define LL_DCACHE_IER_BSYENDIE DCACHE_IER_BSYENDIE /*!< Busy end interrupt */ +#define LL_DCACHE_IER_ERRIE DCACHE_IER_ERRIE /*!< Cache error interrupt */ +#define LL_DCACHE_IER_CMDENDIE DCACHE_IER_CMDENDIE /*!< Command end interrupt */ +/** + * @} + */ + +/** @defgroup DCACHE_Monitor_Type Monitor type + * @{ + */ +#define LL_DCACHE_MONITOR_READ_HIT DCACHE_CR_RHITMEN /*!< Read Hit monitoring */ +#define LL_DCACHE_MONITOR_READ_MISS DCACHE_CR_RMISSMEN /*!< Read Miss monitoring */ +#define LL_DCACHE_MONITOR_WRITE_HIT DCACHE_CR_WHITMEN /*!< Write Hit monitoring */ +#define LL_DCACHE_MONITOR_WRITE_MISS DCACHE_CR_WMISSMEN /*!< Write Miss monitoring */ +#define LL_DCACHE_MONITOR_ALL (DCACHE_CR_RHITMEN | DCACHE_CR_RMISSMEN \ + | DCACHE_CR_WHITMEN | DCACHE_CR_WMISSMEN) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros --------------------------------------------------------*/ +/** @defgroup DCACHE_LL_Exported_Macros DCACHE Exported Macros + * @{ + */ + +/** @defgroup DCACHE_LL_EM_WRITE_READ Common write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in DCACHE register + * @param __INSTANCE__ DCACHE Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_DCACHE_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in DCACHE register + * @param __INSTANCE__ DCACHE Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_DCACHE_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup DCACHE_LL_Exported_Functions DCACHE Exported Functions + * @{ + */ + +/** @defgroup DCACHE_LL_EF_Configuration Configuration + * @{ + */ + +/** + * @brief Enable the selected DCACHE instance. + * @rmtoll CR EN LL_DCACHE_Enable + * @param DCACHEx DCACHE instance + * @retval None + */ +__STATIC_INLINE void LL_DCACHE_Enable(DCACHE_TypeDef *DCACHEx) +{ + SET_BIT(DCACHEx->CR, DCACHE_CR_EN); +} + +/** + * @brief Disable the selected DCACHE instance. + * @rmtoll CR EN LL_DCACHE_Disable + * @param DCACHEx DCACHE instance + * @retval None + */ +__STATIC_INLINE void LL_DCACHE_Disable(DCACHE_TypeDef *DCACHEx) +{ + CLEAR_BIT(DCACHEx->CR, DCACHE_CR_EN); +} + +/** + * @brief Get the selected DCACHE instance enable state. + * @rmtoll CR EN LL_DCACHE_IsEnabled + * @param DCACHEx DCACHE instance + * @retval 0: DCACHE is disabled, 1: DCACHE is enabled. + */ +__STATIC_INLINE uint32_t LL_DCACHE_IsEnabled(const DCACHE_TypeDef *DCACHEx) +{ + return ((READ_BIT(DCACHEx->CR, DCACHE_CR_EN) == (DCACHE_CR_EN)) ? 1UL : 0UL); +} + +/** + * @brief Set the dcache instance start command address. + * @rmtoll CR CMDRSADDRR LL_DCACHE_SetStartAddress + * @param addr dcache command start address(Clean, Invalidate or Clean and Invalidate). + * @param DCACHEx DCACHE instance + * @retval None + */ +__STATIC_INLINE void LL_DCACHE_SetStartAddress(DCACHE_TypeDef *DCACHEx, uint32_t addr) +{ + WRITE_REG(DCACHEx->CMDRSADDRR, addr); +} + +/** + * @brief Get the dcache command start address. + * @rmtoll CR CMDRSADDRR LL_DCACHE_GetStartAddress + * @param DCACHEx DCACHE instance + * @retval Start address of dcache command + */ +__STATIC_INLINE uint32_t LL_DCACHE_GetStartAddress(const DCACHE_TypeDef *DCACHEx) +{ + return (uint32_t)(READ_REG(DCACHEx->CMDRSADDRR)); +} + +/** + * @brief Set the dcache instance End command address. + * @rmtoll CR CMDREADDRR LL_DCACHE_SetEndAddress + * @param DCACHEx DCACHE instance + * @param addr dcache command end address(Clean, Invalidate or Clean and Invalidate). + * @retval None + */ +__STATIC_INLINE void LL_DCACHE_SetEndAddress(DCACHE_TypeDef *DCACHEx, uint32_t addr) +{ + WRITE_REG(DCACHEx->CMDREADDRR, addr); +} + +/** + * @brief Get the dcache command End address. + * @rmtoll CR CMDREADDRR LL_DCACHE_GetEndAddress + * @param DCACHEx DCACHE instance + * @retval End address of dcache command + */ +__STATIC_INLINE uint32_t LL_DCACHE_GetEndAddress(const DCACHE_TypeDef *DCACHEx) +{ + return (uint32_t)(READ_REG(DCACHEx->CMDREADDRR)); +} + +/** + * @brief Set Dcache command. + * @rmtoll CR CACHECMD LL_DCACHE_SetCommand + * @param DCACHEx DCACHE instance + * @param Command command to be applied for the dcache + * Command can be one of the following values: + * @arg @ref LL_DCACHE_COMMAND_INVALIDATE_BY_ADDR + * @arg @ref LL_DCACHE_COMMAND_CLEAN_BY_ADDR + * @arg @ref LL_DCACHE_COMMAND_CLEAN_INVALIDATE_BY_ADDR + * @arg @ref LL_DCACHE_COMMAND_NO_OPERATION + * @retval None + */ +__STATIC_INLINE void LL_DCACHE_SetCommand(DCACHE_TypeDef *DCACHEx, uint32_t Command) +{ + /* Set dcache command */ + MODIFY_REG(DCACHEx->CR, DCACHE_CR_CACHECMD, Command); +} + +/** + * @brief Set Dcache command. + * @rmtoll CR CACHECMD LL_DCACHE_GetCommand + * @param DCACHEx DCACHE instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_DCACHE_COMMAND_NO_OPERATION + * @arg @ref LL_DCACHE_COMMAND_CLEAN_BY_ADDR + * @arg @ref LL_DCACHE_COMMAND_INVALIDATE_BY_ADDR + * @arg @ref LL_DCACHE_COMMAND_CLEAN_INVALIDATE_BY_ADDR + */ +__STATIC_INLINE uint32_t LL_DCACHE_GetCommand(const DCACHE_TypeDef *DCACHEx) +{ + /*Get Dcache Command */ + return (uint32_t)(READ_BIT(DCACHEx->CR, DCACHE_CR_CACHECMD)); +} + +/** + * @brief Launch Dcache Command. + * @rmtoll CR CACHECMD LL_DCACHE_StartCommand + * @param DCACHEx DCACHE instance + * @retval None + */ +__STATIC_INLINE void LL_DCACHE_StartCommand(DCACHE_TypeDef *DCACHEx) +{ + SET_BIT(DCACHEx->CR, DCACHE_CR_STARTCMD); +} + +/** + * @brief Set requested read burst type. + * @rmtoll CR HBURST LL_DCACHE_SetReadBurstType + * @param DCACHEx DCACHE instance + * @param ReadBurstType Burst type to be applied for Data Cache + * Burst type can be one of the following values: + * @arg @ref LL_DCACHE_READ_BURST_WRAP + * @arg @ref LL_DCACHE_READ_BURST_INCR + * @retval None + */ +__STATIC_INLINE void LL_DCACHE_SetReadBurstType(DCACHE_TypeDef *DCACHEx, uint32_t ReadBurstType) +{ + MODIFY_REG(DCACHEx->CR, DCACHE_CR_HBURST, ReadBurstType); +} + +/** + * @brief Get requested read burst type. + * @rmtoll CR HBURST LL_DCACHE_GetReadBurstType + * @param DCACHEx DCACHE instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_DCACHE_READ_BURST_WRAP + * @arg @ref LL_DCACHE_READ_BURST_INCR + */ +__STATIC_INLINE uint32_t LL_DCACHE_GetReadBurstType(const DCACHE_TypeDef *DCACHEx) +{ + return (uint32_t)(READ_BIT(DCACHEx->CR, DCACHE_CR_HBURST)); +} + +/** + * @brief Invalidate the Data cache. + * @rmtoll CR CACHEINV LL_DCACHE_Invalidate + * @param DCACHEx DCACHE instance + * @retval None + */ +__STATIC_INLINE void LL_DCACHE_Invalidate(DCACHE_TypeDef *DCACHEx) +{ + SET_BIT(DCACHEx->CR, DCACHE_CR_CACHEINV); +} + +/** + * @} + */ + + +/** @defgroup DCACHE_LL_EF_Monitor Monitor + * @{ + */ + +/** + * @brief Enable the hit/miss monitor(s). + * @rmtoll CR (RMISSMEN/RHITMEN/WMISSMEN/WHITMEN) LL_DCACHE_EnableMonitors + * @param DCACHEx DCACHE instance + * @param Monitors This parameter can be one or a combination of the following values: + * @arg LL_DCACHE_MONITOR_READ_HIT + * @arg LL_DCACHE_MONITOR_READ_MISS + * @arg LL_DCACHE_MONITOR_WRITE_HIT + * @arg LL_DCACHE_MONITOR_WRITE_MISS + * @arg LL_DCACHE_MONITOR_ALL + * @retval None + */ +__STATIC_INLINE void LL_DCACHE_EnableMonitors(DCACHE_TypeDef *DCACHEx, uint32_t Monitors) +{ + SET_BIT(DCACHEx->CR, Monitors); +} + +/** + * @brief Disable the hit/miss monitor(s). + * @rmtoll CR (RMISSMEN/RHITMEN/WMISSMEN/WHITMEN) LL_DCACHE_DisableMonitors + * @param DCACHEx DCACHE instance + * @param Monitors This parameter can be one or a combination of the following values: + * @arg LL_DCACHE_MONITOR_READ_HIT + * @arg LL_DCACHE_MONITOR_READ_MISS + * @arg LL_DCACHE_MONITOR_WRITE_HIT + * @arg LL_DCACHE_MONITOR_WRITE_MISS + * @arg LL_DCACHE_MONITOR_ALL + * @retval None + */ +__STATIC_INLINE void LL_DCACHE_DisableMonitors(DCACHE_TypeDef *DCACHEx, uint32_t Monitors) +{ + CLEAR_BIT(DCACHEx->CR, Monitors); +} + +/** + * @brief Return the hit/miss monitor(s) enable state. + * @rmtoll CR (RMISSMEN/RHITMEN/WMISSMEN/WHITMEN) LL_DCACHE_IsEnabledMonitors + * @param DCACHEx DCACHE instance + * @param Monitors This parameter can be one or a combination of the following values: + * @arg LL_DCACHE_MONITOR_READ_HIT + * @arg LL_DCACHE_MONITOR_READ_MISS + * @arg LL_DCACHE_MONITOR_WRITE_HIT + * @arg LL_DCACHE_MONITOR_WRITE_MISS + * @arg LL_DCACHE_MONITOR_ALL + * @retval State of parameter value (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DCACHE_IsEnabledMonitors(const DCACHE_TypeDef *DCACHEx, uint32_t Monitors) +{ + return (((READ_BIT(DCACHEx->CR, (DCACHE_CR_WMISSMEN | DCACHE_CR_WHITMEN | DCACHE_CR_RMISSMEN | DCACHE_CR_RHITMEN))\ + & Monitors) == (Monitors)) ? 1UL : 0UL); +} + +/** + * @brief Reset the Data Cache performance monitoring. + * @rmtoll CR (RHITMRST/RMISSMRST/WHITMRST/WMISSMRST) LL_DCACHE_ResetMonitors + * @param DCACHEx DCACHE instance + * @param Monitors Monitoring type + * This parameter can be a combination of the following values: + * @arg LL_DCACHE_MONITOR_READ_HIT + * @arg LL_DCACHE_MONITOR_READ_MISS + * @arg LL_DCACHE_MONITOR_WRITE_HIT + * @arg LL_DCACHE_MONITOR_WRITE_MISS + * @arg LL_DCACHE_MONITOR_ALL + * @retval None + */ +__STATIC_INLINE void LL_DCACHE_ResetMonitors(DCACHE_TypeDef *DCACHEx, uint32_t Monitors) +{ + /* Reset */ + SET_BIT(DCACHEx->CR, (Monitors << 2U)); + + /* Release reset */ + CLEAR_BIT(DCACHEx->CR, (Monitors << 2U)); +} + +/** + * @brief Get the Read Hit monitor Value + * @rmtoll RHMONR LL_DCACHE_Monitor_GetReadHitValue + * @param DCACHEx DCACHE instance + * @retval Value between Min_Data=0 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_DCACHE_Monitor_GetReadHitValue(DCACHE_TypeDef *DCACHEx) +{ + return DCACHEx->RHMONR; +} + +/** + * @brief Get the Read Miss monitor Value + * @rmtoll RMMONR LL_DCACHE_Monitor_GetReadMissValue + * @param DCACHEx DCACHE instance + * @retval Value between Min_Data=0 and Max_Data=0xFFFF + */ +__STATIC_INLINE uint32_t LL_DCACHE_Monitor_GetReadMissValue(DCACHE_TypeDef *DCACHEx) +{ + return DCACHEx->RMMONR; +} + +/** + * @brief Get the Write Hit monitor Value + * @rmtoll WHMONR LL_DCACHE_Monitor_GetWriteHitValue + * @param DCACHEx DCACHE instance + * @retval Value between Min_Data=0 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_DCACHE_Monitor_GetWriteHitValue(DCACHE_TypeDef *DCACHEx) +{ + return DCACHEx->WHMONR; +} + +/** + * @brief Get the Write Miss monitor Value + * @rmtoll WMMONR LL_DCACHE_Monitor_GetWriteMissValue + * @param DCACHEx DCACHE instance + * @retval Value between Min_Data=0 and Max_Data=0xFFFF + */ +__STATIC_INLINE uint32_t LL_DCACHE_Monitor_GetWriteMissValue(DCACHE_TypeDef *DCACHEx) +{ + return DCACHEx->WMMONR; +} + +/** + * @} + */ + +/** @defgroup DCACHE_LL_EF_IT_Management IT-Management + * @{ + */ + +/** + * @brief Enable BusyEnd interrupt. + * @rmtoll IER BSYENDIE LL_DCACHE_EnableIT_BSYEND + * @param DCACHEx DCACHE instance + * @retval None + */ +__STATIC_INLINE void LL_DCACHE_EnableIT_BSYEND(DCACHE_TypeDef *DCACHEx) +{ + SET_BIT(DCACHEx->IER, DCACHE_IER_BSYENDIE); +} + +/** + * @brief Disable BusyEnd interrupt. + * @rmtoll IER BSYENDIE LL_DCACHE_DisableIT_BSYEND + * @param DCACHEx DCACHE instance + * @retval None + */ +__STATIC_INLINE void LL_DCACHE_DisableIT_BSYEND(DCACHE_TypeDef *DCACHEx) +{ + CLEAR_BIT(DCACHEx->IER, DCACHE_IER_BSYENDIE); +} + +/** + * @brief Indicates whether the Busyend interrupt is enabled. + * @rmtoll IER BSYENDIE LL_DCACHE_IsEnabledIT_BSYEND + * @param DCACHEx DCACHE instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DCACHE_IsEnabledIT_BSYEND(const DCACHE_TypeDef *DCACHEx) +{ + return ((READ_BIT(DCACHEx->IER, DCACHE_IER_BSYENDIE) == (DCACHE_IER_BSYENDIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable Error interrupt. + * @rmtoll IER ERRIE LL_DCACHE_EnableIT_ERR + * @param DCACHEx DCACHE instance + * @retval None + */ +__STATIC_INLINE void LL_DCACHE_EnableIT_ERR(DCACHE_TypeDef *DCACHEx) +{ + SET_BIT(DCACHEx->IER, DCACHE_IER_ERRIE); +} + +/** + * @brief Disable Error interrupt. + * @rmtoll IER ERRIE LL_DCACHE_DisableIT_ERR + * @param DCACHEx DCACHE instance + * @retval None + */ +__STATIC_INLINE void LL_DCACHE_DisableIT_ERR(DCACHE_TypeDef *DCACHEx) +{ + CLEAR_BIT(DCACHEx->IER, DCACHE_IER_ERRIE); +} + +/** + * @brief Indicates whether the Error interrupt is enabled. + * @rmtoll IER ERRIE LL_DCACHE_IsEnabledIT_ERR + * @param DCACHEx DCACHE instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DCACHE_IsEnabledIT_ERR(const DCACHE_TypeDef *DCACHEx) +{ + return ((READ_BIT(DCACHEx->IER, DCACHE_IER_ERRIE) == (DCACHE_IER_ERRIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable command end interrupt. + * @rmtoll IER CMDENDIE LL_DCACHE_EnableIT_CMDEND + * @param DCACHEx DCACHE instance + * @retval None + */ +__STATIC_INLINE void LL_DCACHE_EnableIT_CMDEND(DCACHE_TypeDef *DCACHEx) +{ + SET_BIT(DCACHEx->IER, DCACHE_IER_CMDENDIE); +} + +/** + * @brief Disable command end interrupt. + * @rmtoll IER CMDENDIE LL_DCACHE_DisableIT_CMDEND + * @param DCACHEx DCACHE instance + * @retval None + */ +__STATIC_INLINE void LL_DCACHE_DisableIT_CMDEND(DCACHE_TypeDef *DCACHEx) +{ + CLEAR_BIT(DCACHEx->IER, DCACHE_IER_CMDENDIE); +} + +/** + * @brief Indicates whether the command end interrupt is enabled. + * @rmtoll IER CMDENDIE LL_DCACHE_IsEnabledIT_CMDEND + * @param DCACHEx DCACHE instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DCACHE_IsEnabledIT_CMDEND(const DCACHE_TypeDef *DCACHEx) +{ + return ((READ_BIT(DCACHEx->IER, DCACHE_IER_CMDENDIE) == (DCACHE_IER_CMDENDIE)) ? 1UL : 0UL); +} + +/** + * @brief Clear full invalidate busy end flag. + * @rmtoll FCR CBSYENDF LL_DCACHE_ClearFlag_BSYEND + * @param DCACHEx DCACHE instance + * @retval None + */ +__STATIC_INLINE void LL_DCACHE_ClearFlag_BSYEND(DCACHE_TypeDef *DCACHEx) +{ + WRITE_REG(DCACHEx->FCR, DCACHE_FCR_CBSYENDF); +} + +/** + * @brief Clear cache error flag. + * @rmtoll FCR CERRF LL_DCACHE_ClearFlag_ERR + * @param DCACHEx DCACHE instance + * @retval None + */ +__STATIC_INLINE void LL_DCACHE_ClearFlag_ERR(DCACHE_TypeDef *DCACHEx) +{ + WRITE_REG(DCACHEx->FCR, DCACHE_FCR_CERRF); +} + +/** + * @brief Clear command end flag. + * @rmtoll FCR CCMDENDF LL_DCACHE_ClearFlag_CMDEND + * @param DCACHEx DCACHE instance + * @retval None + */ +__STATIC_INLINE void LL_DCACHE_ClearFlag_CMDEND(DCACHE_TypeDef *DCACHEx) +{ + WRITE_REG(DCACHEx->FCR, DCACHE_FCR_CCMDENDF); +} + +/** + * @brief Get flag Dcache BUSY. + * @rmtoll SR BUSYF LL_DCACHE_IsActiveFlag_BUSY + * @param DCACHEx DCACHE instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DCACHE_IsActiveFlag_BUSY(const DCACHE_TypeDef *DCACHEx) +{ + return ((READ_BIT(DCACHEx->SR, DCACHE_SR_BUSYF) == (DCACHE_SR_BUSYF)) ? 1UL : 0UL); +} + +/** + * @brief Get flag Dcache Busyend. + * @rmtoll SR BSYENDF LL_DCACHE_IsActiveFlag_BSYEND + * @param DCACHEx DCACHE instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DCACHE_IsActiveFlag_BSYEND(const DCACHE_TypeDef *DCACHEx) +{ + return ((READ_BIT(DCACHEx->SR, DCACHE_SR_BSYENDF) == (DCACHE_SR_BSYENDF)) ? 1UL : 0UL); +} + +/** + * @brief Get flag Dcache Error. + * @rmtoll SR ERRF LL_DCACHE_IsActiveFlag_ERR + * @param DCACHEx DCACHE instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DCACHE_IsActiveFlag_ERR(const DCACHE_TypeDef *DCACHEx) +{ + return ((READ_BIT(DCACHEx->SR, DCACHE_SR_ERRF) == (DCACHE_SR_ERRF)) ? 1UL : 0UL); +} + +/** + * @brief Get flag Dcache Busy command. + * @rmtoll SR BUSYCMDF LL_DCACHE_IsActiveFlag_BUSYCMD + * @param DCACHEx DCACHE instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DCACHE_IsActiveFlag_BUSYCMD(const DCACHE_TypeDef *DCACHEx) +{ + return ((READ_BIT(DCACHEx->SR, DCACHE_SR_BUSYCMDF) == (DCACHE_SR_BUSYCMDF)) ? 1UL : 0UL); +} + +/** + * @brief Get flag Dcache command end. + * @rmtoll SR CMDENDF LL_DCACHE_IsActiveFlag_CMDEND + * @param DCACHEx DCACHE instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DCACHE_IsActiveFlag_CMDEND(const DCACHE_TypeDef *DCACHEx) +{ + return ((READ_BIT(DCACHEx->SR, DCACHE_SR_CMDENDF) == (DCACHE_SR_CMDENDF)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* DCACHE1 */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_LL_DCACHE_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_dlyb.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_dlyb.h new file mode 100644 index 0000000000..05dbc07a37 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_dlyb.h @@ -0,0 +1,143 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_dlyb.h + * @author MCD Application Team + * @brief Header file of DelayBlock module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_LL_DLYB_H +#define STM32H5xx_LL_DLYB_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined(HAL_SD_MODULE_ENABLED) || defined(HAL_OSPI_MODULE_ENABLED) || defined(HAL_XSPI_MODULE_ENABLED) +#if defined (DLYB_SDMMC1) || defined (DLYB_SDMMC2) || defined (DLYB_OCTOSPI1) || defined (DLYB_OCTOSPI2) + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup DLYB_LL DLYB + * @{ + */ + +/** + * @brief DLYB Configuration Structure definition + */ + +typedef struct +{ + uint32_t Units; /*!< Specifies the Delay of a unit delay cell. + This parameter can be a value between 0 and DLYB_MAX_UNIT */ + + uint32_t PhaseSel; /*!< Specifies the Phase for the output clock. + This parameter can be a value between 0 and DLYB_MAX_SELECT */ +} LL_DLYB_CfgTypeDef; + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup DLYB_Exported_Constants DLYB Exported Constants + * @{ + */ + +#define DLYB_MAX_UNIT ((uint32_t)0x00000080U) /*!< Max UNIT value (128) */ +#define DLYB_MAX_SELECT ((uint32_t)0x0000000CU) /*!< Max SELECT value (12) */ + +/** + * @} + */ + +/** @defgroup DLYB_LL_Flags DLYB Flags + * @{ + */ + +#define DLYB_FLAG_LNGF DLYB_CFGR_LNGF + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup DLYB_LL_Exported_Functions DLYB Exported Functions + * @{ + */ + +/** @defgroup DLYB_LL_Configuration Configuration functions + * @{ + */ + +/** + * @brief DLYB Enable + * @param DLYBx DLYB Instance + * @retval None + */ + +__STATIC_INLINE void LL_DLYB_Enable(DLYB_TypeDef *DLYBx) +{ + SET_BIT(DLYBx->CR, DLYB_CR_DEN); +} + +/** @brief Disable the DLYB. + * @param DLYBx DLYB Instance. + * @retval None + */ + +__STATIC_INLINE void LL_DLYB_Disable(DLYB_TypeDef *DLYBx) +{ + CLEAR_BIT(DLYBx->CR, DLYB_CR_DEN); +} + +/** + * @} + */ + +/** @defgroup DLYB_Control_Functions DLYB Control functions + * @{ + */ + +void LL_DLYB_SetDelay(DLYB_TypeDef *DLYBx, LL_DLYB_CfgTypeDef *pdlyb_cfg); +void LL_DLYB_GetDelay(DLYB_TypeDef *DLYBx, LL_DLYB_CfgTypeDef *pdlyb_cfg); +uint32_t LL_DLYB_GetClockPeriod(DLYB_TypeDef *DLYBx, LL_DLYB_CfgTypeDef *pdlyb_cfg); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* DLYB_SDMMC1 || DLYB_SDMMC2 || DLYB_OCTOSPI1 || DLYB_OCTOSPI2 */ +#endif /* HAL_SD_MODULE_ENABLED || HAL_OSPI_MODULE_ENABLED || HAL_XSPI_MODULE_ENABLED */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_LL_DLYB_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_dma.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_dma.h new file mode 100644 index 0000000000..9678eb979f --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_dma.h @@ -0,0 +1,6335 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_dma.h + * @author MCD Application Team + * @brief Header file of DMA LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### LL DMA driver acronyms ##### + ============================================================================== + [..] Acronyms table : + ========================================= + || Acronym || || + ========================================= + || SRC || Source || + || DEST || Destination || + || ADDR || Address || + || ADDRS || Addresses || + || INC || Increment / Incremented || + || DEC || Decrement / Decremented || + || BLK || Block || + || RPT || Repeat / Repeated || + || TRIG || Trigger || + ========================================= + @endverbatim + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_LL_DMA_H +#define STM32H5xx_LL_DMA_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (GPDMA1) + +/** @defgroup DMA_LL DMA + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +/** @defgroup DMA_LL_Private_Variables DMA Private Variables + * @{ + */ +#define DMA_CHANNEL0_OFFSET (0x00000050UL) +#define DMA_CHANNEL1_OFFSET (0x000000D0UL) +#define DMA_CHANNEL2_OFFSET (0x00000150UL) +#define DMA_CHANNEL3_OFFSET (0x000001D0UL) +#define DMA_CHANNEL4_OFFSET (0x00000250UL) +#define DMA_CHANNEL5_OFFSET (0x000002D0UL) +#define DMA_CHANNEL6_OFFSET (0x00000350UL) +#define DMA_CHANNEL7_OFFSET (0x000003D0UL) + + +/* Array used to get the DMA Channel register offset versus Channel index LL_DMA_CHANNEL_x */ +static const uint32_t LL_DMA_CH_OFFSET_TAB[] = +{ + DMA_CHANNEL0_OFFSET, DMA_CHANNEL1_OFFSET, DMA_CHANNEL2_OFFSET, DMA_CHANNEL3_OFFSET, + DMA_CHANNEL4_OFFSET, DMA_CHANNEL5_OFFSET, DMA_CHANNEL6_OFFSET, DMA_CHANNEL7_OFFSET, +}; + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ + +#if defined (USE_FULL_LL_DRIVER) +/** @defgroup DMA_LL_ES_INIT DMA Exported Init structure + * @{ + */ + +/** + * @brief LL DMA init structure definition. + */ +typedef struct +{ + uint32_t SrcAddress; /*!< This field specify the data transfer source address. + Programming this field is mandatory for all available DMA channels. + This parameter must be a value between Min_Data = 0 and Max_Data = 0xFFFFFFFF. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetSrcAddress(). */ + + uint32_t DestAddress; /*!< This field specify the data transfer destination address. + Programming this field is mandatory for all available DMA channels. + This parameter must be a value between Min_Data = 0 and Max_Data = 0xFFFFFFFF. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetDestAddress(). */ + + uint32_t Direction; /*!< This field specify the data transfer direction. + Programming this field is mandatory for all available DMA channels. + This parameter can be a value of @ref DMA_LL_EC_TRANSFER_DIRECTION. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetDataTransferDirection(). */ + + uint32_t BlkHWRequest; /*!< This field specify the hardware request unity. + Programming this field is mandatory for all available DMA channels. + This parameter can be a value of @ref DMA_LL_EC_BLKHW_REQUEST. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetBlkHWRequest(). */ + + uint32_t DataAlignment; /*!< This field specify the transfer data alignment. + Programming this field is mandatory for all available DMA channels. + This parameter can be a value of @ref DMA_LL_EC_DATA_ALIGNMENT. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetDataAlignment(). */ + + uint32_t SrcBurstLength; /*!< This field specify the source burst length of transfer in bytes. + Programming this field is mandatory for all available DMA channels. + This parameter must be a value between Min_Data = 1 and Max_Data = 64. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetSrcBurstLength(). */ + + uint32_t DestBurstLength; /*!< This field specify the destination burst length of transfer in bytes. + Programming this field is mandatory for all available DMA channels. + This parameter must be a value between Min_Data = 1 and Max_Data = 64. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetDestBurstLength(). */ + + uint32_t SrcDataWidth; /*!< This field specify the source data width. + Programming this field is mandatory for all available DMA channels. + This parameter can be a value of @ref DMA_LL_EC_SOURCE_DATA_WIDTH. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetSrcDataWidth(). */ + + uint32_t DestDataWidth; /*!< This field specify the destination data width. + Programming this field is mandatory for all available DMA channels. + This parameter can be a value of @ref DMA_LL_EC_DESTINATION_DATA_WIDTH. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetDestDataWidth(). */ + + uint32_t SrcIncMode; /*!< This field specify the source burst increment mode. + Programming this field is mandatory for all available DMA channels. + This parameter can be a value of @ref DMA_LL_EC_SOURCE_INCREMENT_MODE. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetSrcIncMode(). */ + + uint32_t DestIncMode; /*!< This field specify the destination burst increment mode. + Programming this field is mandatory for all available DMA channels. + This parameter can be a value of @ref DMA_LL_EC_DESTINATION_INCREMENT_MODE. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetDestIncMode(). */ + + uint32_t Priority; /*!< This field specify the channel priority level. + Programming this field is mandatory for all available DMA channels. + This parameter can be a value of @ref DMA_LL_EC_PRIORITY_LEVEL. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetChannelPriorityLevel(). */ + + uint32_t BlkDataLength; /*!< This field specify the length of a block transfer in bytes. + Programming this field is mandatory for all available DMA channels. + This parameter must be a value between Min_Data = 0 and Max_Data = 0x0000FFFF. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetBlkDataLength(). */ + + uint32_t BlkRptCount; /*!< This field specify the number of repetitions of the current block. + Programming this field is mandatory only for 2D addressing channels. + This parameter can be a value between 1 and 2048 Min_Data = 0 + and Max_Data = 0x000007FF. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetBlkRptCount(). */ + + uint32_t TriggerMode; /*!< This field specify the trigger mode. + Programming this field is mandatory for all available DMA channels. + This parameter can be a value of @ref DMA_LL_EC_TRIGGER_MODE. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetTriggerMode(). */ + + uint32_t TriggerPolarity; /*!< This field specify the trigger event polarity. + Programming this field is mandatory for all available DMA channels. + This parameter can be a value of @ref DMA_LL_EC_TRIGGER_POLARITY. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetTriggerPolarity(). */ + + uint32_t TriggerSelection; /*!< This field specify the trigger event selection. + Programming this field is mandatory for all available DMA channels. + This parameter can be a value of @ref DMA_LL_EC_TRIGGER_SELECTION. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetHWTrigger(). */ + + uint32_t Request; /*!< This field specify the peripheral request selection. + Programming this field is mandatory for all available DMA channels. + This parameter can be a value of @ref DMA_LL_EC_REQUEST_SELECTION. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetPeriphRequest(). */ + + uint32_t TransferEventMode; /*!< This field specify the transfer event mode. + Programming this field is mandatory for all available DMA channels. + This parameter can be a value of @ref DMA_LL_EC_TRANSFER_EVENT_MODE. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetTransferEventMode(). */ + + uint32_t DestHWordExchange; /*!< This field specify the destination half word exchange. + Programming this field is mandatory for all available DMA channels. + This parameter can be a value of @ref DMA_LL_EC_DEST_HALFWORD_EXCHANGE. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetDestHWordExchange(). */ + + uint32_t DestByteExchange; /*!< This field specify the destination byte exchange. + Programming this field is mandatory for all available DMA channels. + This parameter can be a value of @ref DMA_LL_EC_DEST_BYTE_EXCHANGE. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetDestByteExchange(). */ + + uint32_t SrcByteExchange; /*!< This field specify the source byte exchange. + Programming this field is mandatory for all available DMA channels. + This parameter can be a value of @ref DMA_LL_EC_SRC_BYTE_EXCHANGE. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetSrcByteExchange(). */ + + uint32_t SrcAllocatedPort; /*!< This field specify the source allocated port. + Programming this field is mandatory for all available DMA channels. + This parameter can be a value of @ref DMA_LL_EC_SOURCE_ALLOCATED_PORT. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetSrcAllocatedPort(). */ + + uint32_t DestAllocatedPort; /*!< This field specify the destination allocated port. + Programming this field is mandatory for all available DMA channels. + This parameter can be a value of @ref DMA_LL_EC_DESTINATION_ALLOCATED_PORT. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetDestAllocatedPort(). */ + + uint32_t LinkAllocatedPort; /*!< This field specify the linked-list allocated port. + Programming this field is mandatory for all available DMA channels. + This parameter can be a value of @ref DMA_LL_EC_LINKED_LIST_ALLOCATED_PORT. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetLinkAllocatedPort(). */ + + uint32_t LinkStepMode; /*!< This field specify the link step mode. + Programming this field is mandatory for all available DMA channels. + This parameter can be a value of @ref DMA_LL_EC_LINK_STEP_MODE. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetLinkStepMode(). */ + + uint32_t SrcAddrUpdateMode; /*!< This field specify the source address update mode. + Programming this field is mandatory only for 2D addressing channels. + This parameter can be a value of @ref DMA_LL_EC_SRC_ADDR_UPDATE_MODE. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetSrcAddrUpdate(). */ + + uint32_t DestAddrUpdateMode; /*!< This field specify the destination address update mode. + Programming this field is mandatory only for 2D addressing channels. + This parameter can be a value of @ref DMA_LL_EC_DEST_ADDR_UPDATE_MODE. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetDestAddrUpdate(). */ + + uint32_t SrcAddrOffset; /*!< This field specifies the source address offset. + Programming this field is mandatory only for 2D addressing channels. + This parameter can be a value Between 0 to 0x00001FFF. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetSrcAddrUpdateValue(). */ + + uint32_t DestAddrOffset; /*!< This field specifies the destination address offset. + Programming this field is mandatory only for 2D addressing channels. + This parameter can be a value Between 0 to 0x00001FFF. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetDestAddrUpdateValue(). */ + + uint32_t BlkRptSrcAddrUpdateMode; /*!< This field specifies the block repeat source address update mode. + Programming this field is mandatory only for 2D addressing channels. + This parameter can be a value of @ref DMA_LL_EC_BLK_RPT_SRC_ADDR_UPDATE_MODE. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetBlkRptSrcAddrUpdate(). */ + + uint32_t BlkRptDestAddrUpdateMode; /*!< This field specifies the block repeat destination address update mode. + Programming this field is mandatory only for 2D addressing channels. + This parameter can be a value of @ref DMA_LL_EC_BLK_RPT_DEST_ADDR_UPDATE_MODE. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetBlkRptDestAddrUpdate(). */ + + uint32_t BlkRptSrcAddrOffset; /*!< This field specifies the block repeat source address offset. + Programming this field is mandatory only for 2D addressing channels. + This parameter can be a value Between 0 to 0x0000FFFF. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetBlkRptSrcAddrUpdateValue(). */ + + uint32_t BlkRptDestAddrOffset; /*!< This field specifies the block repeat destination address offset. + Programming this field is mandatory only for 2D addressing channels. + This parameter can be a value Between 0 to 0x0000FFFF. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetBlkRptDestAddrUpdateValue(). */ + + uint32_t LinkedListBaseAddr; /*!< This field specify the linked list base address. + Programming this field is mandatory for all available DMA channels. + This parameter can be a value Between 0 to 0xFFFF0000 (where the 4 first + bytes are always forced to 0). + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetLinkedListBaseAddr(). */ + + uint32_t LinkedListAddrOffset; /*!< Specifies the linked list address offset. + Programming this field is mandatory for all available DMA channels. + This parameter can be a value Between 0 to 0x0000FFFC. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetLinkedListAddrOffset(). */ + + uint32_t Mode; /*!< Specifies the transfer mode for the DMA channel. + This parameter can be a value of @ref DMA_LL_TRANSFER_MODE */ +} LL_DMA_InitTypeDef; + + +/** + * @brief LL DMA init linked list structure definition. + */ +typedef struct +{ + uint32_t Priority; /*!< This field specify the channel priority level. + Programming this field is mandatory for all available DMA channels. + This parameter can be a value of @ref DMA_LL_EC_PRIORITY_LEVEL. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetChannelPriorityLevel(). */ + + uint32_t LinkStepMode; /*!< This field specify the link step mode. + Programming this field is mandatory for all available DMA channels. + This parameter can be a value of @ref DMA_LL_EC_LINK_STEP_MODE. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetLinkStepMode(). */ + + uint32_t LinkAllocatedPort; /*!< This field specify the linked-list allocated port. + Programming this field is mandatory for all available DMA channels. + This parameter can be a value of @ref DMA_LL_EC_LINKED_LIST_ALLOCATED_PORT. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetLinkAllocatedPort(). */ + + uint32_t TransferEventMode; /*!< This field specify the transfer event mode. + Programming this field is mandatory for all available DMA channels. + This parameter can be a value of @ref DMA_LL_EC_TRANSFER_EVENT_MODE. + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetTransferEventMode(). */ +} LL_DMA_InitLinkedListTypeDef; + + +/** + * @brief LL DMA node init structure definition. + */ +typedef struct +{ + /* CTR1 register fields ****************************************************** + If any CTR1 fields need to be updated comparing to previous node, it is + mandatory to update the new value in CTR1 register fields and enable update + CTR1 register in UpdateRegisters fields if it is not enabled in the + previous node. + + */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + uint32_t DestSecure; /*!< This field specify the destination secure. + This parameter can be a value of @ref DMA_LL_EC_DESTINATION_SECURITY_ATTRIBUTE. */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + uint32_t DestAllocatedPort; /*!< This field specify the destination allocated port. + This parameter can be a value of @ref DMA_LL_EC_DESTINATION_ALLOCATED_PORT. */ + + uint32_t DestHWordExchange; /*!< This field specify the destination half word exchange. + This parameter can be a value of @ref DMA_LL_EC_DEST_HALFWORD_EXCHANGE. */ + + uint32_t DestByteExchange; /*!< This field specify the destination byte exchange. + This parameter can be a value of @ref DMA_LL_EC_DEST_BYTE_EXCHANGE. */ + + uint32_t DestBurstLength; /*!< This field specify the destination burst length of transfer in bytes. + This parameter must be a value between Min_Data = 1 and Max_Data = 64. */ + + uint32_t DestIncMode; /*!< This field specify the destination increment mode. + This parameter can be a value of @ref DMA_LL_EC_DESTINATION_INCREMENT_MODE. */ + + uint32_t DestDataWidth; /*!< This field specify the destination data width. + This parameter can be a value of @ref DMA_LL_EC_DESTINATION_DATA_WIDTH. */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + uint32_t SrcSecure; /*!< This field specify the source secure. + This parameter can be a value of @ref DMA_LL_EC_SOURCE_SECURITY_ATTRIBUTE. */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + uint32_t SrcAllocatedPort; /*!< This field specify the source allocated port. + This parameter can be a value of @ref DMA_LL_EC_SOURCE_ALLOCATED_PORT. */ + + uint32_t SrcByteExchange; /*!< This field specify the source byte exchange. + This parameter can be a value of @ref DMA_LL_EC_SRC_BYTE_EXCHANGE. */ + + uint32_t DataAlignment; /*!< This field specify the transfer data alignment. + This parameter can be a value of @ref DMA_LL_EC_DATA_ALIGNMENT. */ + + uint32_t SrcBurstLength; /*!< This field specify the source burst length of transfer in bytes. + This parameter must be a value between Min_Data = 1 and Max_Data = 64. */ + + uint32_t SrcIncMode; /*!< This field specify the source increment mode. + This parameter can be a value of @ref DMA_LL_EC_SOURCE_INCREMENT_MODE. */ + + uint32_t SrcDataWidth; /*!< This field specify the source data width. + This parameter can be a value of @ref DMA_LL_EC_SOURCE_DATA_WIDTH. */ + + + /* CTR2 register fields ****************************************************** + If any CTR2 fields need to be updated comparing to previous node, it is + mandatory to update the new value in CTR2 register fields and enable update + CTR2 register in UpdateRegisters fields if it is not enabled in the + previous node. + + For all node created, filling all fields is mandatory. + */ + uint32_t TransferEventMode; /*!< This field specify the transfer event mode. + This parameter can be a value of @ref DMA_LL_EC_TRANSFER_EVENT_MODE. */ + + uint32_t TriggerPolarity; /*!< This field specify the trigger event polarity. + This parameter can be a value of @ref DMA_LL_EC_TRIGGER_POLARITY. */ + + uint32_t TriggerSelection; /*!< This field specify the trigger event selection. + This parameter can be a value of @ref DMA_LL_EC_TRIGGER_SELECTION. */ + + uint32_t TriggerMode; /*!< This field specify the trigger mode. + This parameter can be a value of @ref DMA_LL_EC_TRIGGER_MODE. */ + + uint32_t BlkHWRequest; /*!< This field specify the hardware request unity. + This parameter can be a value of @ref DMA_LL_EC_BLKHW_REQUEST. */ + + uint32_t Direction; /*!< This field specify the transfer direction. + This parameter can be a value of @ref DMA_LL_EC_TRANSFER_DIRECTION. */ + + uint32_t Request; /*!< This field specify the peripheral request selection. + This parameter can be a value of @ref DMA_LL_EC_REQUEST_SELECTION. */ + + uint32_t Mode; /*!< This field DMA Transfer Mode. + This parameter can be a value of @ref DMA_Transfer_Mode. */ + + /* CBR1 register fields ****************************************************** + If any CBR1 fields need to be updated comparing to previous node, it is + mandatory to update the new value in CBR1 register fields and enable update + CBR1 register in UpdateRegisters fields if it is not enabled in the + previous node. + + If the node to be created is not for 2D addressing channels, there is no + need to fill the following fields for CBR1 register : + - BlkReptDestAddrUpdate. + - BlkRptSrcAddrUpdate. + - DestAddrUpdate. + - SrcAddrUpdate. + - BlkRptCount. + */ + uint32_t BlkRptDestAddrUpdateMode; /*!< This field specifies the block repeat destination address update mode. + This parameter can be a value of + @ref DMA_LL_EC_BLK_RPT_DEST_ADDR_UPDATE_MODE. */ + + uint32_t BlkRptSrcAddrUpdateMode; /*!< This field specifies the block repeat source address update mode. + This parameter can be a value of + @ref DMA_LL_EC_BLK_RPT_SRC_ADDR_UPDATE_MODE. */ + + uint32_t DestAddrUpdateMode; /*!< This field specify the Destination address update mode. + This parameter can be a value of @ref DMA_LL_EC_DEST_ADDR_UPDATE_MODE. */ + + uint32_t SrcAddrUpdateMode; /*!< This field specify the Source address update mode. + This parameter can be a value of @ref DMA_LL_EC_SRC_ADDR_UPDATE_MODE. */ + + uint32_t BlkRptCount; /*!< This field specify the number of repetitions of the current block. + This parameter can be a value between 1 and 2048 Min_Data = 0 + and Max_Data = 0x000007FF. */ + + uint32_t BlkDataLength; /*!< This field specify the length of a block transfer in bytes. + This parameter must be a value between Min_Data = 0 + and Max_Data = 0x0000FFFF. */ + + /* CSAR register fields ****************************************************** + If any CSAR fields need to be updated comparing to previous node, it is + mandatory to update the new value in CSAR register fields and enable update + CSAR register in UpdateRegisters fields if it is not enabled in the + previous node. + + For all node created, filling all fields is mandatory. + */ + uint32_t SrcAddress; /*!< This field specify the transfer source address. + This parameter must be a value between Min_Data = 0 + and Max_Data = 0xFFFFFFFF. */ + + + /* CDAR register fields ****************************************************** + If any CDAR fields need to be updated comparing to previous node, it is + mandatory to update the new value in CDAR register fields and enable update + CDAR register in UpdateRegisters fields if it is not enabled in the + previous node. + + For all node created, filling all fields is mandatory. + */ + uint32_t DestAddress; /*!< This field specify the transfer destination address. + This parameter must be a value between Min_Data = 0 + and Max_Data = 0xFFFFFFFF. */ + + /* CTR3 register fields ****************************************************** + If any CTR3 fields need to be updated comparing to previous node, it is + mandatory to update the new value in CTR3 register fields and enable update + CTR3 register in UpdateRegisters fields if it is not enabled in the + previous node. + + This register is used only for 2D addressing channels. + If used channel is linear addressing, this register will be overwritten by + CLLR register in memory. + When this register is enabled on UpdateRegisters and the selected channel + is linear addressing, LL APIs will discard this register update in memory. + */ + uint32_t DestAddrOffset; /*!< This field specifies the destination address offset. + This parameter can be a value Between 0 to 0x00001FFF. */ + + uint32_t SrcAddrOffset; /*!< This field specifies the source address offset. + This parameter can be a value Between 0 to 0x00001FFF. */ + + + /* CBR2 register fields ****************************************************** + If any CBR2 fields need to be updated comparing to previous node, it is + mandatory to update the new value in CBR2 register fields and enable update + CBR2 register in UpdateRegisters fields if it is not enabled in the + previous node. + + This register is used only for 2D addressing channels. + If used channel is linear addressing, this register will be discarded in + memory. When this register is enabled on UpdateRegisters and the selected + channel is linear addressing, LL APIs will discard this register update in + memory. + */ + uint32_t BlkRptDestAddrOffset; /*!< This field specifies the block repeat destination address offset. + This parameter can be a value Between 0 to 0x0000FFFF. */ + + uint32_t BlkRptSrcAddrOffset; /*!< This field specifies the block repeat source address offset. + This parameter can be a value Between 0 to 0x0000FFFF. */ + + /* CLLR register fields ****************************************************** + If any CLLR fields need to be updated comparing to previous node, it is + mandatory to update the new value in CLLR register fields and enable update + CLLR register in UpdateRegisters fields if it is not enabled in the + previous node. + + If used channel is linear addressing, there is no need to enable/disable + CTR3 and CBR2 register in UpdateRegisters fields as they will be discarded + by LL APIs. + */ + uint32_t UpdateRegisters; /*!< Specifies the linked list register update. + This parameter can be a value of @ref DMA_LL_EC_LINKEDLIST_REGISTER_UPDATE. */ + + /* DMA Node type field ******************************************************* + This parameter defines node types as node size and node content varies + between channels. + Thanks to this fields, linked list queue could be created independently + from channel selection. So, one queue could be executed by all DMA channels. + */ + uint32_t NodeType; /*!< Specifies the node type to be created. + This parameter can be a value of @ref DMA_LL_EC_LINKEDLIST_NODE_TYPE. */ +} LL_DMA_InitNodeTypeDef; + +/** + * @brief LL DMA linked list node structure definition. + * @note For 2D addressing channels, the maximum node size is : + * (4 Bytes * 8 registers = 32 Bytes). + * For GPDMA linear addressing channels, the maximum node size is : + * (4 Bytes * 6 registers = 24 Bytes). + */ +typedef struct +{ + __IO uint32_t LinkRegisters[8]; + +} LL_DMA_LinkNodeTypeDef; +/** + * @} + */ + +#endif /* defined (USE_FULL_LL_DRIVER) */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup DMA_LL_Exported_Constants DMA Exported Constants + * @{ + */ + +/** @defgroup DMA_LL_EC_CHANNEL Channel + * @{ + */ +#define LL_DMA_CHANNEL_0 (0x00U) +#define LL_DMA_CHANNEL_1 (0x01U) +#define LL_DMA_CHANNEL_2 (0x02U) +#define LL_DMA_CHANNEL_3 (0x03U) +#define LL_DMA_CHANNEL_4 (0x04U) +#define LL_DMA_CHANNEL_5 (0x05U) +#define LL_DMA_CHANNEL_6 (0x06U) +#define LL_DMA_CHANNEL_7 (0x07U) +#define LL_DMA_CHANNEL_8 (0x08U) +#define LL_DMA_CHANNEL_9 (0x09U) +#define LL_DMA_CHANNEL_10 (0x0AU) +#define LL_DMA_CHANNEL_11 (0x0BU) +#define LL_DMA_CHANNEL_12 (0x0CU) +#define LL_DMA_CHANNEL_13 (0x0DU) +#define LL_DMA_CHANNEL_14 (0x0EU) +#define LL_DMA_CHANNEL_15 (0x0FU) +#if defined (USE_FULL_LL_DRIVER) +#define LL_DMA_CHANNEL_ALL (0x10U) +#endif /* defined (USE_FULL_LL_DRIVER) */ +/** + * @} + */ + +#if defined (USE_FULL_LL_DRIVER) +/** @defgroup DMA_LL_EC_CLLR_OFFSET CLLR offset + * @{ + */ +#define LL_DMA_CLLR_OFFSET0 (0x00U) +#define LL_DMA_CLLR_OFFSET1 (0x01U) +#define LL_DMA_CLLR_OFFSET2 (0x02U) +#define LL_DMA_CLLR_OFFSET3 (0x03U) +#define LL_DMA_CLLR_OFFSET4 (0x04U) +#define LL_DMA_CLLR_OFFSET5 (0x05U) +#define LL_DMA_CLLR_OFFSET6 (0x06U) +#define LL_DMA_CLLR_OFFSET7 (0x07U) +/** + * @} + */ +#endif /* defined (USE_FULL_LL_DRIVER) */ + +/** @defgroup DMA_LL_EC_PRIORITY_LEVEL Priority Level + * @{ + */ +#define LL_DMA_LOW_PRIORITY_LOW_WEIGHT 0x00000000U /*!< Priority level : Low Priority, Low Weight */ +#define LL_DMA_LOW_PRIORITY_MID_WEIGHT DMA_CCR_PRIO_0 /*!< Priority level : Low Priority, Mid Weight */ +#define LL_DMA_LOW_PRIORITY_HIGH_WEIGHT DMA_CCR_PRIO_1 /*!< Priority level : Low Priority, High Weight */ +#define LL_DMA_HIGH_PRIORITY DMA_CCR_PRIO /*!< Priority level : High Priority */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_LINKED_LIST_ALLOCATED_PORT Linked List Allocated Port + * @{ + */ +#define LL_DMA_LINK_ALLOCATED_PORT0 0x00000000U /*!< Linked List Allocated Port 0 */ +#define LL_DMA_LINK_ALLOCATED_PORT1 DMA_CCR_LAP /*!< Linked List Allocated Port 1 */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_LINK_STEP_MODE Link Step Mode + * @{ + */ +#define LL_DMA_LSM_FULL_EXECUTION 0x00000000U /*!< Channel execute the full linked list */ +#define LL_DMA_LSM_1LINK_EXECUTION DMA_CCR_LSM /*!< Channel execute one node of the linked list */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_DEST_HALFWORD_EXCHANGE Destination Half-Word Exchange + * @{ + */ +#define LL_DMA_DEST_HALFWORD_PRESERVE 0x00000000U /*!< No destination Half-Word exchange when destination data width + is word */ +#define LL_DMA_DEST_HALFWORD_EXCHANGE DMA_CTR1_DHX /*!< Destination Half-Word exchange when destination data width + is word */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_DEST_BYTE_EXCHANGE Destination Byte Exchange + * @{ + */ +#define LL_DMA_DEST_BYTE_PRESERVE 0x00000000U /*!< No destination Byte exchange when destination data width > Byte */ +#define LL_DMA_DEST_BYTE_EXCHANGE DMA_CTR1_DBX /*!< Destination Byte exchange when destination data width > Byte */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_SRC_BYTE_EXCHANGE Source Byte Exchange + * @{ + */ +#define LL_DMA_SRC_BYTE_PRESERVE 0x00000000U /*!< No source Byte exchange when source data width is word */ +#define LL_DMA_SRC_BYTE_EXCHANGE DMA_CTR1_SBX /*!< Source Byte exchange when source data width is word */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_SOURCE_ALLOCATED_PORT Source Allocated Port + * @{ + */ +#define LL_DMA_SRC_ALLOCATED_PORT0 0x00000000U /*!< Source Allocated Port 0 */ +#define LL_DMA_SRC_ALLOCATED_PORT1 DMA_CTR1_SAP /*!< Source Allocated Port 1 */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_DESTINATION_ALLOCATED_PORT Destination Allocated Port + * @{ + */ +#define LL_DMA_DEST_ALLOCATED_PORT0 0x00000000U /*!< Destination Allocated Port 0 */ +#define LL_DMA_DEST_ALLOCATED_PORT1 DMA_CTR1_DAP /*!< Destination Allocated Port 1 */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_DESTINATION_INCREMENT_MODE Destination Increment Mode + * @{ + */ +#define LL_DMA_DEST_FIXED 0x00000000U /*!< Destination fixed single/burst */ +#define LL_DMA_DEST_INCREMENT DMA_CTR1_DINC /*!< Destination incremented single/burst */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_DESTINATION_DATA_WIDTH Destination Data Width + * @{ + */ +#define LL_DMA_DEST_DATAWIDTH_BYTE 0x00000000U /*!< Destination Data Width : Byte */ +#define LL_DMA_DEST_DATAWIDTH_HALFWORD DMA_CTR1_DDW_LOG2_0 /*!< Destination Data Width : HalfWord */ +#define LL_DMA_DEST_DATAWIDTH_WORD DMA_CTR1_DDW_LOG2_1 /*!< Destination Data Width : Word */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_DATA_ALIGNMENT Data Alignment + * @{ + */ +#define LL_DMA_DATA_ALIGN_ZEROPADD 0x00000000U /*!< If src data width < dest data width : + => Right Aligned padded with 0 up to destination + data width. + If src data width > dest data width : + => Right Aligned Left Truncated down to destination + data width. */ +#define LL_DMA_DATA_ALIGN_SIGNEXTPADD DMA_CTR1_PAM_0 /*!< If src data width < dest data width : + => Right Aligned padded with sign extended up to destination + data width. + If src data width > dest data width : + => Left Aligned Right Truncated down to the destination + data width */ +#define LL_DMA_DATA_PACK_UNPACK DMA_CTR1_PAM_1 /*!< If src data width < dest data width : + => Packed at the destination data width + If src data width > dest data width : + => Unpacked at the destination data width */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_SOURCE_INCREMENT_MODE Source Increment Mode + * @{ + */ +#define LL_DMA_SRC_FIXED 0x00000000U /*!< Source fixed single/burst */ +#define LL_DMA_SRC_INCREMENT DMA_CTR1_SINC /*!< Source incremented single/burst */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_SOURCE_DATA_WIDTH Source Data Width + * @{ + */ +#define LL_DMA_SRC_DATAWIDTH_BYTE 0x00000000U /*!< Source Data Width : Byte */ +#define LL_DMA_SRC_DATAWIDTH_HALFWORD DMA_CTR1_SDW_LOG2_0 /*!< Source Data Width : HalfWord */ +#define LL_DMA_SRC_DATAWIDTH_WORD DMA_CTR1_SDW_LOG2_1 /*!< Source Data Width : Word */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_BLKHW_REQUEST Block Hardware Request + * @{ + */ +#define LL_DMA_HWREQUEST_SINGLEBURST 0x00000000U /*!< Hardware request is driven by a peripheral with a hardware + request/acknowledge protocol at a burst level */ +#define LL_DMA_HWREQUEST_BLK DMA_CTR2_BREQ /*!< Hardware request is driven by a peripheral with a hardware + request/acknowledge protocol at a block level */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_TRANSFER_EVENT_MODE Transfer Event Mode + * @{ + */ +#define LL_DMA_TCEM_BLK_TRANSFER 0x00000000U /*!< The TC (and the HT) event is generated at the + (respectively half) end of each block */ +#define LL_DMA_TCEM_RPT_BLK_TRANSFER DMA_CTR2_TCEM_0 /*!< The TC (and the HT) event is generated at the + (respectively half) end of the repeated block */ +#define LL_DMA_TCEM_EACH_LLITEM_TRANSFER DMA_CTR2_TCEM_1 /*!< The TC (and the HT) event is generated at the + (respectively half) end of each linked-list item */ +#define LL_DMA_TCEM_LAST_LLITEM_TRANSFER DMA_CTR2_TCEM /*!< The TC (and the HT) event is generated at the + (respectively half) end of the last linked-list item */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_TRIGGER_POLARITY Trigger Polarity + * @{ + */ +#define LL_DMA_TRIG_POLARITY_MASKED 0x00000000U /*!< No trigger of the selected DMA request. + Masked trigger event */ +#define LL_DMA_TRIG_POLARITY_RISING DMA_CTR2_TRIGPOL_0 /*!< Trigger of the selected DMA request on the rising + edge of the selected trigger event input */ +#define LL_DMA_TRIG_POLARITY_FALLING DMA_CTR2_TRIGPOL_1 /*!< Trigger of the selected DMA request on the falling + edge of the selected trigger event input */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_TRIGGER_MODE Transfer Trigger Mode + * @{ + */ +#define LL_DMA_TRIGM_BLK_TRANSFER 0x00000000U /*!< A block transfer is conditioned by (at least) + one hit trigger */ +#define LL_DMA_TRIGM_RPT_BLK_TRANSFER DMA_CTR2_TRIGM_0 /*!< A repeated block transfer is conditioned by (at least) + one hit trigger */ +#define LL_DMA_TRIGM_LLI_LINK_TRANSFER DMA_CTR2_TRIGM_1 /*!< A LLI link transfer is conditioned by (at least) + one hit trigger */ +#define LL_DMA_TRIGM_SINGLBURST_TRANSFER DMA_CTR2_TRIGM /*!< A Single/Burst transfer is conditioned by (at least) + one hit trigger */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_TRANSFER_DIRECTION Transfer Direction + * @{ + */ +#define LL_DMA_DIRECTION_MEMORY_TO_MEMORY DMA_CTR2_SWREQ /*!< Memory to memory direction */ +#define LL_DMA_DIRECTION_PERIPH_TO_MEMORY 0x00000000U /*!< Peripheral to memory direction */ +#define LL_DMA_DIRECTION_MEMORY_TO_PERIPH DMA_CTR2_DREQ /*!< Memory to peripheral direction */ +/** + * @} + */ + +/** @defgroup DMA_LL_TRANSFER_MODE Transfer Mode + * @{ + */ +#define LL_DMA_NORMAL 0x00000000U /*!< Normal DMA transfer */ +#define LL_DMA_PFCTRL DMA_CTR2_PFREQ /*!< HW request peripheral flow control mode */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_BLK_RPT_SRC_ADDR_UPDATE_MODE Block Repeat Source Address Update Mode + * @{ + */ +#define LL_DMA_BLKRPT_SRC_ADDR_INCREMENT 0x00000000U /*!< Source address pointer is incremented after each block + transfer by source update value */ +#define LL_DMA_BLKRPT_SRC_ADDR_DECREMENT DMA_CBR1_BRSDEC /*!< Source address pointer is decremented after each block + transfer by source update value */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_BLK_RPT_DEST_ADDR_UPDATE_MODE Block Repeat Destination Address Update Mode + * @{ + */ +#define LL_DMA_BLKRPT_DEST_ADDR_INCREMENT 0x00000000U /*!< Destination address is incremented after each block + transfer by destination update value */ +#define LL_DMA_BLKRPT_DEST_ADDR_DECREMENT DMA_CBR1_BRDDEC /*!< Destination address is decremented after each block + transfer by destination update value */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_SRC_ADDR_UPDATE_MODE Burst Source Address Update Mode + * @{ + */ +#define LL_DMA_BURST_SRC_ADDR_INCREMENT 0x00000000U /*!< Source address pointer is incremented after each burst + transfer by source update value */ +#define LL_DMA_BURST_SRC_ADDR_DECREMENT DMA_CBR1_SDEC /*!< Source address pointer is decremented after each burst + transfer by source update value */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_DEST_ADDR_UPDATE_MODE Burst Destination Address Update Mode + * @{ + */ +#define LL_DMA_BURST_DEST_ADDR_INCREMENT 0x00000000U /*!< Destination address pointer is incremented after each + burst transfer by destination update value */ +#define LL_DMA_BURST_DEST_ADDR_DECREMENT DMA_CBR1_DDEC /*!< Destination address pointer is decremented after each + burst transfer by destination update value */ +/** + * @} + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** @defgroup DMA_LL_EC_SOURCE_SECURITY_ATTRIBUTE Source Security Attribute + * @{ + */ +#define LL_DMA_CHANNEL_NSEC 0x00000000U /*!< NSecure channel */ +#define LL_DMA_CHANNEL_SEC 0x00000001U /*!< Secure channel */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_SOURCE_SECURITY_ATTRIBUTE Source Security Attribute + * @{ + */ +#define LL_DMA_CHANNEL_SRC_NSEC 0x00000000U /*!< NSecure transfer from the source */ +#define LL_DMA_CHANNEL_SRC_SEC DMA_CTR1_SSEC /*!< Secure transfer from the source */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_DESTINATION_SECURITY_ATTRIBUTE Destination Security Attribute + * @{ + */ +#define LL_DMA_CHANNEL_DEST_NSEC 0x00000000U /*!< NSecure transfer from the destination */ +#define LL_DMA_CHANNEL_DEST_SEC DMA_CTR1_DSEC /*!< Secure transfer from the destination */ +/** + * @} + */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/** @defgroup DMA_LL_EC_LINKEDLIST_NODE_TYPE Linked list node type + * @{ + */ +#define LL_DMA_GPDMA_LINEAR_NODE 0x01U /*!< GPDMA node : linear addressing node */ +#define LL_DMA_GPDMA_2D_NODE 0x02U /*!< GPDMA node : 2 dimension addressing node */ + +/** + * @} + */ + +/** @defgroup DMA_LL_EC_LINKEDLIST_REGISTER_UPDATE Linked list register update + * @{ + */ +#define LL_DMA_UPDATE_CTR1 DMA_CLLR_UT1 /*!< Update CTR1 register from memory : + available for all DMA channels */ +#define LL_DMA_UPDATE_CTR2 DMA_CLLR_UT2 /*!< Update CTR2 register from memory : + available for all DMA channels */ +#define LL_DMA_UPDATE_CBR1 DMA_CLLR_UB1 /*!< Update CBR1 register from memory : + available for all DMA channels */ +#define LL_DMA_UPDATE_CSAR DMA_CLLR_USA /*!< Update CSAR register from memory : + available for all DMA channels */ +#define LL_DMA_UPDATE_CDAR DMA_CLLR_UDA /*!< Update CDAR register from memory : + available for all DMA channels */ +#define LL_DMA_UPDATE_CTR3 DMA_CLLR_UT3 /*!< Update CTR3 register from memory : + available only for 2D addressing DMA channels */ +#define LL_DMA_UPDATE_CBR2 DMA_CLLR_UB2 /*!< Update CBR2 register from memory : + available only for 2D addressing DMA channels */ +#define LL_DMA_UPDATE_CLLR DMA_CLLR_ULL /*!< Update CLLR register from memory : + available for all DMA channels */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_REQUEST_SELECTION Request Selection + * @{ + */ +/* GPDMA1 Hardware Requests */ +#define LL_GPDMA1_REQUEST_ADC1 0U /*!< GPDMA1 HW request is ADC1 */ +#if defined (ADC2) +#define LL_GPDMA1_REQUEST_ADC2 1U /*!< GPDMA1 HW request is ADC2 */ +#endif /* ADC2 */ +#define LL_GPDMA1_REQUEST_DAC1_CH1 2U /*!< GPDMA1 HW request is DAC1_CH1 */ +#define LL_GPDMA1_REQUEST_DAC1_CH2 3U /*!< GPDMA1 HW request is DAC1_CH2 */ +#define LL_GPDMA1_REQUEST_TIM6_UP 4U /*!< GPDMA1 HW request is TIM6_UP */ +#define LL_GPDMA1_REQUEST_TIM7_UP 5U /*!< GPDMA1 HW request is TIM7_UP */ +#define LL_GPDMA1_REQUEST_SPI1_RX 6U /*!< GPDMA1 HW request is SPI1_RX */ +#define LL_GPDMA1_REQUEST_SPI1_TX 7U /*!< GPDMA1 HW request is SPI1_TX */ +#define LL_GPDMA1_REQUEST_SPI2_RX 8U /*!< GPDMA1 HW request is SPI2_RX */ +#define LL_GPDMA1_REQUEST_SPI2_TX 9U /*!< GPDMA1 HW request is SPI2_TX */ +#define LL_GPDMA1_REQUEST_SPI3_RX 10U /*!< GPDMA1 HW request is SPI3_RX */ +#define LL_GPDMA1_REQUEST_SPI3_TX 11U /*!< GPDMA1 HW request is SPI3_TX */ +#define LL_GPDMA1_REQUEST_I2C1_RX 12U /*!< GPDMA1 HW request is I2C1_RX */ +#define LL_GPDMA1_REQUEST_I2C1_TX 13U /*!< GPDMA1 HW request is I2C1_TX */ +#define LL_GPDMA1_REQUEST_I2C2_RX 15U /*!< GPDMA1 HW request is I2C2_RX */ +#define LL_GPDMA1_REQUEST_I2C2_TX 16U /*!< GPDMA1 HW request is I2C2_TX */ +#if defined (I2C3) +#define LL_GPDMA1_REQUEST_I2C3_RX 18U /*!< GPDMA1 HW request is I2C3_RX */ +#define LL_GPDMA1_REQUEST_I2C3_TX 19U /*!< GPDMA1 HW request is I2C3_TX */ +#endif /* I2C3 */ +#define LL_GPDMA1_REQUEST_USART1_RX 21U /*!< GPDMA1 HW request is USART1_RX */ +#define LL_GPDMA1_REQUEST_USART1_TX 22U /*!< GPDMA1 HW request is USART1_TX */ +#define LL_GPDMA1_REQUEST_USART2_RX 23U /*!< GPDMA1 HW request is USART2_RX */ +#define LL_GPDMA1_REQUEST_USART2_TX 24U /*!< GPDMA1 HW request is USART2_TX */ +#define LL_GPDMA1_REQUEST_USART3_RX 25U /*!< GPDMA1 HW request is USART3_RX */ +#define LL_GPDMA1_REQUEST_USART3_TX 26U /*!< GPDMA1 HW request is USART3_TX */ +#if defined (UART4) +#define LL_GPDMA1_REQUEST_UART4_RX 27U /*!< GPDMA1 HW request is UART4_RX */ +#define LL_GPDMA1_REQUEST_UART4_TX 28U /*!< GPDMA1 HW request is UART4_TX */ +#endif /* UART4 */ +#if defined (UART4) +#define LL_GPDMA1_REQUEST_UART5_RX 29U /*!< GPDMA1 HW request is UART5_RX */ +#define LL_GPDMA1_REQUEST_UART5_TX 30U /*!< GPDMA1 HW request is UART5_TX */ +#endif /* UART5 */ +#if defined (UART4) +#define LL_GPDMA1_REQUEST_USART6_RX 31U /*!< GPDMA1 HW request is USART6_RX */ +#define LL_GPDMA1_REQUEST_USART6_TX 32U /*!< GPDMA1 HW request is USART6_TX */ +#endif /* USART6 */ +#if defined (UART7) +#define LL_GPDMA1_REQUEST_UART7_RX 33U /*!< GPDMA1 HW request is UART7_RX */ +#define LL_GPDMA1_REQUEST_UART7_TX 34U /*!< GPDMA1 HW request is UART7_TX */ +#endif /* UART7 */ +#if defined (UART8) +#define LL_GPDMA1_REQUEST_UART8_RX 35U /*!< GPDMA1 HW request is UART8_RX */ +#define LL_GPDMA1_REQUEST_UART8_TX 36U /*!< GPDMA1 HW request is UART8_TX */ +#endif /* UART8 */ +#if defined (UART9) +#define LL_GPDMA1_REQUEST_UART9_RX 37U /*!< GPDMA1 HW request is UART9_RX */ +#define LL_GPDMA1_REQUEST_UART9_TX 38U /*!< GPDMA1 HW request is UART9_TX */ +#endif /* UART9 */ +#if defined (USART10) +#define LL_GPDMA1_REQUEST_USART10_RX 39U /*!< GPDMA1 HW request is USART10_RX */ +#define LL_GPDMA1_REQUEST_USART10_TX 40U /*!< GPDMA1 HW request is USART10_TX */ +#endif /* USART10 */ +#if defined (USART11) +#define LL_GPDMA1_REQUEST_USART11_RX 41U /*!< GPDMA1 HW request is USART11_RX */ +#define LL_GPDMA1_REQUEST_USART11_TX 42U /*!< GPDMA1 HW request is USART11_TX */ +#endif /* USART11 */ +#if defined (UART12) +#define LL_GPDMA1_REQUEST_UART12_RX 43U /*!< GPDMA1 HW request is UART12_RX */ +#define LL_GPDMA1_REQUEST_UART12_TX 44U /*!< GPDMA1 HW request is UART12_TX */ +#endif /* UART12 */ +#define LL_GPDMA1_REQUEST_LPUART1_RX 45U /*!< GPDMA1 HW request is LPUART1_RX */ +#define LL_GPDMA1_REQUEST_LPUART1_TX 46U /*!< GPDMA1 HW request is LPUART1_TX */ +#if defined (SPI4) +#define LL_GPDMA1_REQUEST_SPI4_RX 47U /*!< GPDMA1 HW request is SPI4_RX */ +#define LL_GPDMA1_REQUEST_SPI4_TX 48U /*!< GPDMA1 HW request is SPI4_TX */ +#endif /* SPI4 */ +#if defined (SPI5) +#define LL_GPDMA1_REQUEST_SPI5_RX 49U /*!< GPDMA1 HW request is SPI5_RX */ +#define LL_GPDMA1_REQUEST_SPI5_TX 50U /*!< GPDMA1 HW request is SPI5_TX */ +#endif /* SPI5 */ +#if defined (SPI6) +#define LL_GPDMA1_REQUEST_SPI6_RX 51U /*!< GPDMA1 HW request is SPI6_RX */ +#define LL_GPDMA1_REQUEST_SPI6_TX 52U /*!< GPDMA1 HW request is SPI6_TX */ +#endif /* SPI6 */ +#if defined (SAI1) +#define LL_GPDMA1_REQUEST_SAI1_A 53U /*!< GPDMA1 HW request is SAI1_A */ +#define LL_GPDMA1_REQUEST_SAI1_B 54U /*!< GPDMA1 HW request is SAI1_B */ +#endif /* SAI1 */ +#if defined (SAI2) +#define LL_GPDMA1_REQUEST_SAI2_A 55U /*!< GPDMA1 HW request is SAI2_A */ +#define LL_GPDMA1_REQUEST_SAI2_B 56U /*!< GPDMA1 HW request is SAI2_B */ +#endif /* SAI2 */ +#if defined (OCTOSPI1) +#define LL_GPDMA1_REQUEST_OCTOSPI1 57U /*!< GPDMA1 HW request is OCTOSPI1 */ +#endif /* OCTOSPI1 */ +#define LL_GPDMA1_REQUEST_TIM1_CH1 58U /*!< GPDMA1 HW request is TIM1_CH1 */ +#define LL_GPDMA1_REQUEST_TIM1_CH2 59U /*!< GPDMA1 HW request is TIM1_CH2 */ +#define LL_GPDMA1_REQUEST_TIM1_CH3 60U /*!< GPDMA1 HW request is TIM1_CH3 */ +#define LL_GPDMA1_REQUEST_TIM1_CH4 61U /*!< GPDMA1 HW request is TIM1_CH4 */ +#define LL_GPDMA1_REQUEST_TIM1_UP 62U /*!< GPDMA1 HW request is TIM1_UP */ +#define LL_GPDMA1_REQUEST_TIM1_TRIG 63U /*!< GPDMA1 HW request is TIM1_TRIG */ +#define LL_GPDMA1_REQUEST_TIM1_COM 64U /*!< GPDMA1 HW request is TIM1_COM */ +#if defined (TIM8) +#define LL_GPDMA1_REQUEST_TIM8_CH1 65U /*!< GPDMA1 HW request is TIM8_CH1 */ +#define LL_GPDMA1_REQUEST_TIM8_CH2 66U /*!< GPDMA1 HW request is TIM8_CH2 */ +#define LL_GPDMA1_REQUEST_TIM8_CH3 67U /*!< GPDMA1 HW request is TIM8_CH3 */ +#define LL_GPDMA1_REQUEST_TIM8_CH4 68U /*!< GPDMA1 HW request is TIM8_CH4 */ +#define LL_GPDMA1_REQUEST_TIM8_UP 69U /*!< GPDMA1 HW request is TIM8_UP */ +#define LL_GPDMA1_REQUEST_TIM8_TRIG 70U /*!< GPDMA1 HW request is TIM8_TRIG */ +#define LL_GPDMA1_REQUEST_TIM8_COM 71U /*!< GPDMA1 HW request is TIM8_COM */ +#endif /* TIM8 */ +#define LL_GPDMA1_REQUEST_TIM2_CH1 72U /*!< GPDMA1 HW request is TIM2_CH1 */ +#define LL_GPDMA1_REQUEST_TIM2_CH2 73U /*!< GPDMA1 HW request is TIM2_CH2 */ +#define LL_GPDMA1_REQUEST_TIM2_CH3 74U /*!< GPDMA1 HW request is TIM2_CH3 */ +#define LL_GPDMA1_REQUEST_TIM2_CH4 75U /*!< GPDMA1 HW request is TIM2_CH4 */ +#define LL_GPDMA1_REQUEST_TIM2_UP 76U /*!< GPDMA1 HW request is TIM2_UP */ +#define LL_GPDMA1_REQUEST_TIM3_CH1 77U /*!< GPDMA1 HW request is TIM3_CH1 */ +#define LL_GPDMA1_REQUEST_TIM3_CH2 78U /*!< GPDMA1 HW request is TIM3_CH2 */ +#define LL_GPDMA1_REQUEST_TIM3_CH3 79U /*!< GPDMA1 HW request is TIM3_CH3 */ +#define LL_GPDMA1_REQUEST_TIM3_CH4 80U /*!< GPDMA1 HW request is TIM3_CH4 */ +#define LL_GPDMA1_REQUEST_TIM3_UP 81U /*!< GPDMA1 HW request is TIM3_UP */ +#define LL_GPDMA1_REQUEST_TIM3_TRIG 82U /*!< GPDMA1 HW request is TIM3_TRIG */ +#if defined (TIM4) +#define LL_GPDMA1_REQUEST_TIM4_CH1 83U /*!< GPDMA1 HW request is TIM4_CH1 */ +#define LL_GPDMA1_REQUEST_TIM4_CH2 84U /*!< GPDMA1 HW request is TIM4_CH2 */ +#define LL_GPDMA1_REQUEST_TIM4_CH3 85U /*!< GPDMA1 HW request is TIM4_CH3 */ +#define LL_GPDMA1_REQUEST_TIM4_CH4 86U /*!< GPDMA1 HW request is TIM4_CH4 */ +#define LL_GPDMA1_REQUEST_TIM4_UP 87U /*!< GPDMA1 HW request is TIM4_UP */ +#endif /* TIM4 */ +#if defined (TIM5) +#define LL_GPDMA1_REQUEST_TIM5_CH1 88U /*!< GPDMA1 HW request is TIM5_CH1 */ +#define LL_GPDMA1_REQUEST_TIM5_CH2 89U /*!< GPDMA1 HW request is TIM5_CH2 */ +#define LL_GPDMA1_REQUEST_TIM5_CH3 90U /*!< GPDMA1 HW request is TIM5_CH3 */ +#define LL_GPDMA1_REQUEST_TIM5_CH4 91U /*!< GPDMA1 HW request is TIM5_CH4 */ +#define LL_GPDMA1_REQUEST_TIM5_UP 92U /*!< GPDMA1 HW request is TIM5_UP */ +#define LL_GPDMA1_REQUEST_TIM5_TRIG 93U /*!< GPDMA1 HW request is TIM5_TRIG */ +#endif /* TIM5 */ +#if defined (TIM15) +#define LL_GPDMA1_REQUEST_TIM15_CH1 94U /*!< GPDMA1 HW request is TIM15_CH1 */ +#define LL_GPDMA1_REQUEST_TIM15_UP 95U /*!< GPDMA1 HW request is TIM15_UP */ +#define LL_GPDMA1_REQUEST_TIM15_TRIG 96U /*!< GPDMA1 HW request is TIM15_TRIG */ +#define LL_GPDMA1_REQUEST_TIM15_COM 97U /*!< GPDMA1 HW request is TIM15_COM */ +#endif /* TIM15 */ +#if defined (TIM16) +#define LL_GPDMA1_REQUEST_TIM16_CH1 98U /*!< GPDMA1 HW request is TIM16_CH1 */ +#define LL_GPDMA1_REQUEST_TIM16_UP 99U /*!< GPDMA1 HW request is TIM16_UP */ +#endif /* TIM16 */ +#if defined (TIM17) +#define LL_GPDMA1_REQUEST_TIM17_CH1 100U /*!< GPDMA1 HW request is TIM17_CH1 */ +#define LL_GPDMA1_REQUEST_TIM17_UP 101U /*!< GPDMA1 HW request is TIM17_UP */ +#endif /* TIM17 */ +#define LL_GPDMA1_REQUEST_LPTIM1_IC1 102U /*!< GPDMA1 HW request is LPTIM1_IC1 */ +#define LL_GPDMA1_REQUEST_LPTIM1_IC2 103U /*!< GPDMA1 HW request is LPTIM1_IC2 */ +#define LL_GPDMA1_REQUEST_LPTIM1_UE 104U /*!< GPDMA1 HW request is LPTIM1_UE */ +#define LL_GPDMA1_REQUEST_LPTIM2_IC1 105U /*!< GPDMA1 HW request is LPTIM2_IC1 */ +#define LL_GPDMA1_REQUEST_LPTIM2_IC2 106U /*!< GPDMA1 HW request is LPTIM2_IC2 */ +#define LL_GPDMA1_REQUEST_LPTIM2_UE 107U /*!< GPDMA1 HW request is LPTIM2_UE */ +#if defined (DCMI) +#define LL_GPDMA1_REQUEST_DCMI 108U /*!< GPDMA1 HW request is DCMI */ +#endif /* DCMI */ +#if defined (AES) +#define LL_GPDMA1_REQUEST_AES_OUT 109U /*!< GPDMA1 HW request is AES_OUT */ +#define LL_GPDMA1_REQUEST_AES_IN 110U /*!< GPDMA1 HW request is AES_IN */ +#endif /* AES */ +#define LL_GPDMA1_REQUEST_HASH_IN 111U /*!< GPDMA1 HW request is HASH_IN */ +#if defined (UCPD1) +#define LL_GPDMA1_REQUEST_UCPD1_RX 112U /*!< GPDMA1 HW request is UCPD1_RX */ +#define LL_GPDMA1_REQUEST_UCPD1_TX 113U /*!< GPDMA1 HW request is UCPD1_TX */ +#endif /* UCPD1 */ +#if defined (CORDIC) +#define LL_GPDMA1_REQUEST_CORDIC_READ 114U /*!< GPDMA1 HW request is CORDIC_READ */ +#define LL_GPDMA1_REQUEST_CORDIC_WRITE 115U /*!< GPDMA1 HW request is CORDIC_WRITE */ +#endif /* CORDIC */ +#if defined (FMAC) +#define LL_GPDMA1_REQUEST_FMAC_READ 116U /*!< GPDMA1 HW request is FMAC_READ */ +#define LL_GPDMA1_REQUEST_FMAC_WRITE 117U /*!< GPDMA1 HW request is FMAC_WRITE */ +#endif /* FMAC */ +#if defined (SAES) +#define LL_GPDMA1_REQUEST_SAES_OUT 118U /*!< GPDMA1 HW request is SAES_OUT */ +#define LL_GPDMA1_REQUEST_SAES_IN 119U /*!< GPDMA1 HW request is SAES_IN */ +#endif /* SAES */ +#define LL_GPDMA1_REQUEST_I3C1_RX 120U /*!< GPDMA1 HW request is I3C1_RX */ +#define LL_GPDMA1_REQUEST_I3C1_TX 121U /*!< GPDMA1 HW request is I3C1_TX */ +#define LL_GPDMA1_REQUEST_I3C1_TC 122U /*!< GPDMA1 HW request is I3C1_TC */ +#define LL_GPDMA1_REQUEST_I3C1_RS 123U /*!< GPDMA1 HW request is I3C1_RS */ +#if defined (I2C4) +#define LL_GPDMA1_REQUEST_I2C4_RX 124U /*!< GPDMA1 HW request is I2C4_RX */ +#define LL_GPDMA1_REQUEST_I2C4_TX 125U /*!< GPDMA1 HW request is I2C4_TX */ +#endif /* I2C4 */ +#if defined (LPTIM3) +#define LL_GPDMA1_REQUEST_LPTIM3_IC1 127U /*!< GPDMA1 HW request is LPTIM3_IC1 */ +#define LL_GPDMA1_REQUEST_LPTIM3_IC2 128U /*!< GPDMA1 HW request is LPTIM3_IC2 */ +#define LL_GPDMA1_REQUEST_LPTIM3_UE 129U /*!< GPDMA1 HW request is LPTIM3_UE */ +#endif /* LPTIM3 */ +#if defined (LPTIM5) +#define LL_GPDMA1_REQUEST_LPTIM5_IC1 130U /*!< GPDMA1 HW request is LPTIM5_IC1 */ +#define LL_GPDMA1_REQUEST_LPTIM5_IC2 131U /*!< GPDMA1 HW request is LPTIM5_IC2 */ +#define LL_GPDMA1_REQUEST_LPTIM5_UE 132U /*!< GPDMA1 HW request is LPTIM5_UE */ +#endif /* LPTIM5 */ +#if defined (LPTIM6) +#define LL_GPDMA1_REQUEST_LPTIM6_IC1 133U /*!< GPDMA1 HW request is LPTIM6_IC1 */ +#define LL_GPDMA1_REQUEST_LPTIM6_IC2 134U /*!< GPDMA1 HW request is LPTIM6_IC2 */ +#define LL_GPDMA1_REQUEST_LPTIM6_UE 135U /*!< GPDMA1 HW request is LPTIM6_UE */ +#endif /* LPTIM6 */ +#if defined (I3C2) +#define LL_GPDMA1_REQUEST_I3C2_RX 136U /*!< GPDMA1 HW request is I3C2_RX */ +#define LL_GPDMA1_REQUEST_I3C2_TX 137U /*!< GPDMA1 HW request is I3C2_TX */ +#define LL_GPDMA1_REQUEST_I3C2_TC 138U /*!< GPDMA1 HW request is I3C2_TC */ +#define LL_GPDMA1_REQUEST_I3C2_RS 139U /*!< GPDMA1 HW request is I3C2_RS */ +#endif /* I3C2 */ + +/* GPDMA2 Hardware Requests */ +#define LL_GPDMA2_REQUEST_ADC1 0U /*!< GPDMA2 HW request is ADC1 */ +#if defined (ADC2) +#define LL_GPDMA2_REQUEST_ADC2 1U /*!< GPDMA2 HW request is ADC2 */ +#endif /* ADC2 */ +#define LL_GPDMA2_REQUEST_DAC1_CH1 2U /*!< GPDMA2 HW request is DAC1_CH1 */ +#define LL_GPDMA2_REQUEST_DAC1_CH2 3U /*!< GPDMA2 HW request is DAC1_CH2 */ +#define LL_GPDMA2_REQUEST_TIM6_UP 4U /*!< GPDMA2 HW request is TIM6_UP */ +#define LL_GPDMA2_REQUEST_TIM7_UP 5U /*!< GPDMA2 HW request is TIM7_UP */ +#define LL_GPDMA2_REQUEST_SPI1_RX 6U /*!< GPDMA2 HW request is SPI1_RX */ +#define LL_GPDMA2_REQUEST_SPI1_TX 7U /*!< GPDMA2 HW request is SPI1_TX */ +#define LL_GPDMA2_REQUEST_SPI2_RX 8U /*!< GPDMA2 HW request is SPI2_RX */ +#define LL_GPDMA2_REQUEST_SPI2_TX 9U /*!< GPDMA2 HW request is SPI2_TX */ +#define LL_GPDMA2_REQUEST_SPI3_RX 10U /*!< GPDMA2 HW request is SPI3_RX */ +#define LL_GPDMA2_REQUEST_SPI3_TX 11U /*!< GPDMA2 HW request is SPI3_TX */ +#define LL_GPDMA2_REQUEST_I2C1_RX 12U /*!< GPDMA2 HW request is I2C1_RX */ +#define LL_GPDMA2_REQUEST_I2C1_TX 13U /*!< GPDMA2 HW request is I2C1_TX */ +#define LL_GPDMA2_REQUEST_I2C2_RX 15U /*!< GPDMA2 HW request is I2C2_RX */ +#define LL_GPDMA2_REQUEST_I2C2_TX 16U /*!< GPDMA2 HW request is I2C2_TX */ +#if defined (I2C3) +#define LL_GPDMA2_REQUEST_I2C3_RX 18U /*!< GPDMA2 HW request is I2C3_RX */ +#define LL_GPDMA2_REQUEST_I2C3_TX 19U /*!< GPDMA2 HW request is I2C3_TX */ +#endif /* I2C3 */ +#define LL_GPDMA2_REQUEST_USART1_RX 21U /*!< GPDMA2 HW request is USART1_RX */ +#define LL_GPDMA2_REQUEST_USART1_TX 22U /*!< GPDMA2 HW request is USART1_TX */ +#define LL_GPDMA2_REQUEST_USART2_RX 23U /*!< GPDMA2 HW request is USART2_RX */ +#define LL_GPDMA2_REQUEST_USART2_TX 24U /*!< GPDMA2 HW request is USART2_TX */ +#define LL_GPDMA2_REQUEST_USART3_RX 25U /*!< GPDMA2 HW request is USART3_RX */ +#define LL_GPDMA2_REQUEST_USART3_TX 26U /*!< GPDMA2 HW request is USART3_TX */ +#if defined (UART4) +#define LL_GPDMA2_REQUEST_UART4_RX 27U /*!< GPDMA2 HW request is UART4_RX */ +#define LL_GPDMA2_REQUEST_UART4_TX 28U /*!< GPDMA2 HW request is UART4_TX */ +#endif /* UART4 */ +#if defined (UART4) +#define LL_GPDMA2_REQUEST_UART5_RX 29U /*!< GPDMA2 HW request is UART5_RX */ +#define LL_GPDMA2_REQUEST_UART5_TX 30U /*!< GPDMA2 HW request is UART5_TX */ +#endif /* UART5 */ +#if defined (UART4) +#define LL_GPDMA2_REQUEST_USART6_RX 31U /*!< GPDMA2 HW request is USART6_RX */ +#define LL_GPDMA2_REQUEST_USART6_TX 32U /*!< GPDMA2 HW request is USART6_TX */ +#endif /* USART6 */ +#if defined (UART7) +#define LL_GPDMA2_REQUEST_UART7_RX 33U /*!< GPDMA2 HW request is UART7_RX */ +#define LL_GPDMA2_REQUEST_UART7_TX 34U /*!< GPDMA2 HW request is UART7_TX */ +#endif /* UART7 */ +#if defined (UART8) +#define LL_GPDMA2_REQUEST_UART8_RX 35U /*!< GPDMA2 HW request is UART8_RX */ +#define LL_GPDMA2_REQUEST_UART8_TX 36U /*!< GPDMA2 HW request is UART8_TX */ +#endif /* UART8 */ +#if defined (UART9) +#define LL_GPDMA2_REQUEST_UART9_RX 37U /*!< GPDMA2 HW request is UART9_RX */ +#define LL_GPDMA2_REQUEST_UART9_TX 38U /*!< GPDMA2 HW request is UART9_TX */ +#endif /* UART9 */ +#if defined (USART10) +#define LL_GPDMA2_REQUEST_USART10_RX 39U /*!< GPDMA2 HW request is USART10_RX */ +#define LL_GPDMA2_REQUEST_USART10_TX 40U /*!< GPDMA2 HW request is USART10_TX */ +#endif /* USART10 */ +#if defined (USART11) +#define LL_GPDMA2_REQUEST_USART11_RX 41U /*!< GPDMA2 HW request is USART11_RX */ +#define LL_GPDMA2_REQUEST_USART11_TX 42U /*!< GPDMA2 HW request is USART11_TX */ +#endif /* USART11 */ +#if defined (UART12) +#define LL_GPDMA2_REQUEST_UART12_RX 43U /*!< GPDMA2 HW request is UART12_RX */ +#define LL_GPDMA2_REQUEST_UART12_TX 44U /*!< GPDMA2 HW request is UART12_TX */ +#endif /* UART12 */ +#define LL_GPDMA2_REQUEST_LPUART1_RX 45U /*!< GPDMA2 HW request is LPUART1_RX */ +#define LL_GPDMA2_REQUEST_LPUART1_TX 46U /*!< GPDMA2 HW request is LPUART1_TX */ +#if defined (SPI4) +#define LL_GPDMA2_REQUEST_SPI4_RX 47U /*!< GPDMA2 HW request is SPI4_RX */ +#define LL_GPDMA2_REQUEST_SPI4_TX 48U /*!< GPDMA2 HW request is SPI4_TX */ +#endif /* SPI4 */ +#if defined (SPI5) +#define LL_GPDMA2_REQUEST_SPI5_RX 49U /*!< GPDMA2 HW request is SPI5_RX */ +#define LL_GPDMA2_REQUEST_SPI5_TX 50U /*!< GPDMA2 HW request is SPI5_TX */ +#endif /* SPI5 */ +#if defined (SPI6) +#define LL_GPDMA2_REQUEST_SPI6_RX 51U /*!< GPDMA2 HW request is SPI6_RX */ +#define LL_GPDMA2_REQUEST_SPI6_TX 52U /*!< GPDMA2 HW request is SPI6_TX */ +#endif /* SPI6 */ +#if defined (SAI1) +#define LL_GPDMA2_REQUEST_SAI1_A 53U /*!< GPDMA2 HW request is SAI1_A */ +#define LL_GPDMA2_REQUEST_SAI1_B 54U /*!< GPDMA2 HW request is SAI1_B */ +#endif /* SAI1 */ +#if defined (SAI2) +#define LL_GPDMA2_REQUEST_SAI2_A 55U /*!< GPDMA2 HW request is SAI2_A */ +#define LL_GPDMA2_REQUEST_SAI2_B 56U /*!< GPDMA2 HW request is SAI2_B */ +#endif /* SAI2 */ +#if defined (OCTOSPI1) +#define LL_GPDMA2_REQUEST_OCTOSPI1 57U /*!< GPDMA2 HW request is OCTOSPI1 */ +#endif /* OCTOSPI1 */ +#define LL_GPDMA2_REQUEST_TIM1_CH1 58U /*!< GPDMA2 HW request is TIM1_CH1 */ +#define LL_GPDMA2_REQUEST_TIM1_CH2 59U /*!< GPDMA2 HW request is TIM1_CH2 */ +#define LL_GPDMA2_REQUEST_TIM1_CH3 60U /*!< GPDMA2 HW request is TIM1_CH3 */ +#define LL_GPDMA2_REQUEST_TIM1_CH4 61U /*!< GPDMA2 HW request is TIM1_CH4 */ +#define LL_GPDMA2_REQUEST_TIM1_UP 62U /*!< GPDMA2 HW request is TIM1_UP */ +#define LL_GPDMA2_REQUEST_TIM1_TRIG 63U /*!< GPDMA2 HW request is TIM1_TRIG */ +#define LL_GPDMA2_REQUEST_TIM1_COM 64U /*!< GPDMA2 HW request is TIM1_COM */ +#if defined (TIM8) +#define LL_GPDMA2_REQUEST_TIM8_CH1 65U /*!< GPDMA2 HW request is TIM8_CH1 */ +#define LL_GPDMA2_REQUEST_TIM8_CH2 66U /*!< GPDMA2 HW request is TIM8_CH2 */ +#define LL_GPDMA2_REQUEST_TIM8_CH3 67U /*!< GPDMA2 HW request is TIM8_CH3 */ +#define LL_GPDMA2_REQUEST_TIM8_CH4 68U /*!< GPDMA2 HW request is TIM8_CH4 */ +#define LL_GPDMA2_REQUEST_TIM8_UP 69U /*!< GPDMA2 HW request is TIM8_UP */ +#define LL_GPDMA2_REQUEST_TIM8_TRIG 70U /*!< GPDMA2 HW request is TIM8_TRIG */ +#define LL_GPDMA2_REQUEST_TIM8_COM 71U /*!< GPDMA2 HW request is TIM8_COM */ +#endif /* TIM8 */ +#define LL_GPDMA2_REQUEST_TIM2_CH1 72U /*!< GPDMA2 HW request is TIM2_CH1 */ +#define LL_GPDMA2_REQUEST_TIM2_CH2 73U /*!< GPDMA2 HW request is TIM2_CH2 */ +#define LL_GPDMA2_REQUEST_TIM2_CH3 74U /*!< GPDMA2 HW request is TIM2_CH3 */ +#define LL_GPDMA2_REQUEST_TIM2_CH4 75U /*!< GPDMA2 HW request is TIM2_CH4 */ +#define LL_GPDMA2_REQUEST_TIM2_UP 76U /*!< GPDMA2 HW request is TIM2_UP */ +#define LL_GPDMA2_REQUEST_TIM3_CH1 77U /*!< GPDMA2 HW request is TIM3_CH1 */ +#define LL_GPDMA2_REQUEST_TIM3_CH2 78U /*!< GPDMA2 HW request is TIM3_CH2 */ +#define LL_GPDMA2_REQUEST_TIM3_CH3 79U /*!< GPDMA2 HW request is TIM3_CH3 */ +#define LL_GPDMA2_REQUEST_TIM3_CH4 80U /*!< GPDMA2 HW request is TIM3_CH4 */ +#define LL_GPDMA2_REQUEST_TIM3_UP 81U /*!< GPDMA2 HW request is TIM3_UP */ +#define LL_GPDMA2_REQUEST_TIM3_TRIG 82U /*!< GPDMA2 HW request is TIM3_TRIG */ +#if defined (TIM4) +#define LL_GPDMA2_REQUEST_TIM4_CH1 83U /*!< GPDMA2 HW request is TIM4_CH1 */ +#define LL_GPDMA2_REQUEST_TIM4_CH2 84U /*!< GPDMA2 HW request is TIM4_CH2 */ +#define LL_GPDMA2_REQUEST_TIM4_CH3 85U /*!< GPDMA2 HW request is TIM4_CH3 */ +#define LL_GPDMA2_REQUEST_TIM4_CH4 86U /*!< GPDMA2 HW request is TIM4_CH4 */ +#define LL_GPDMA2_REQUEST_TIM4_UP 87U /*!< GPDMA2 HW request is TIM4_UP */ +#endif /* TIM4 */ +#if defined (TIM5) +#define LL_GPDMA2_REQUEST_TIM5_CH1 88U /*!< GPDMA2 HW request is TIM5_CH1 */ +#define LL_GPDMA2_REQUEST_TIM5_CH2 89U /*!< GPDMA2 HW request is TIM5_CH2 */ +#define LL_GPDMA2_REQUEST_TIM5_CH3 90U /*!< GPDMA2 HW request is TIM5_CH3 */ +#define LL_GPDMA2_REQUEST_TIM5_CH4 91U /*!< GPDMA2 HW request is TIM5_CH4 */ +#define LL_GPDMA2_REQUEST_TIM5_UP 92U /*!< GPDMA2 HW request is TIM5_UP */ +#define LL_GPDMA2_REQUEST_TIM5_TRIG 93U /*!< GPDMA2 HW request is TIM5_TRIG */ +#endif /* TIM5 */ +#if defined (TIM15) +#define LL_GPDMA2_REQUEST_TIM15_CH1 94U /*!< GPDMA2 HW request is TIM15_CH1 */ +#define LL_GPDMA2_REQUEST_TIM15_UP 95U /*!< GPDMA2 HW request is TIM15_UP */ +#define LL_GPDMA2_REQUEST_TIM15_TRIG 96U /*!< GPDMA2 HW request is TIM15_TRIG */ +#define LL_GPDMA2_REQUEST_TIM15_COM 97U /*!< GPDMA2 HW request is TIM15_COM */ +#endif /* TIM15 */ +#if defined (TIM16) +#define LL_GPDMA2_REQUEST_TIM16_CH1 98U /*!< GPDMA2 HW request is TIM16_CH1 */ +#define LL_GPDMA2_REQUEST_TIM16_UP 99U /*!< GPDMA2 HW request is TIM16_UP */ +#endif /* TIM16 */ +#if defined (TIM17) +#define LL_GPDMA2_REQUEST_TIM17_CH1 100U /*!< GPDMA2 HW request is TIM17_CH1 */ +#define LL_GPDMA2_REQUEST_TIM17_UP 101U /*!< GPDMA2 HW request is TIM17_UP */ +#endif /* TIM17 */ +#define LL_GPDMA2_REQUEST_LPTIM1_IC1 102U /*!< GPDMA2 HW request is LPTIM1_IC1 */ +#define LL_GPDMA2_REQUEST_LPTIM1_IC2 103U /*!< GPDMA2 HW request is LPTIM1_IC2 */ +#define LL_GPDMA2_REQUEST_LPTIM1_UE 104U /*!< GPDMA2 HW request is LPTIM1_UE */ +#define LL_GPDMA2_REQUEST_LPTIM2_IC1 105U /*!< GPDMA2 HW request is LPTIM2_IC1 */ +#define LL_GPDMA2_REQUEST_LPTIM2_IC2 106U /*!< GPDMA2 HW request is LPTIM2_IC2 */ +#define LL_GPDMA2_REQUEST_LPTIM2_UE 107U /*!< GPDMA2 HW request is LPTIM2_UE */ +#if defined (DCMI) +#define LL_GPDMA2_REQUEST_DCMI 108U /*!< GPDMA2 HW request is DCMI */ +#endif /* DCMI */ +#if defined (AES) +#define LL_GPDMA2_REQUEST_AES_OUT 109U /*!< GPDMA2 HW request is AES_OUT */ +#define LL_GPDMA2_REQUEST_AES_IN 110U /*!< GPDMA2 HW request is AES_IN */ +#endif /* AES */ +#define LL_GPDMA2_REQUEST_HASH_IN 111U /*!< GPDMA2 HW request is HASH_IN */ +#if defined (UCPD1) +#define LL_GPDMA2_REQUEST_UCPD1_RX 112U /*!< GPDMA2 HW request is UCPD1_RX */ +#define LL_GPDMA2_REQUEST_UCPD1_TX 113U /*!< GPDMA2 HW request is UCPD1_TX */ +#endif /* UCPD1 */ +#if defined (CORDIC) +#define LL_GPDMA2_REQUEST_CORDIC_READ 114U /*!< GPDMA2 HW request is CORDIC_READ */ +#define LL_GPDMA2_REQUEST_CORDIC_WRITE 115U /*!< GPDMA2 HW request is CORDIC_WRITE */ +#endif /* CORDIC */ +#if defined (FMAC) +#define LL_GPDMA2_REQUEST_FMAC_READ 116U /*!< GPDMA2 HW request is FMAC_READ */ +#define LL_GPDMA2_REQUEST_FMAC_WRITE 117U /*!< GPDMA2 HW request is FMAC_WRITE */ +#endif /* FMAC */ +#if defined (SAES) +#define LL_GPDMA2_REQUEST_SAES_OUT 118U /*!< GPDMA2 HW request is SAES_OUT */ +#define LL_GPDMA2_REQUEST_SAES_IN 119U /*!< GPDMA2 HW request is SAES_IN */ +#endif /* SAES */ +#define LL_GPDMA2_REQUEST_I3C1_RX 120U /*!< GPDMA2 HW request is I3C1_RX */ +#define LL_GPDMA2_REQUEST_I3C1_TX 121U /*!< GPDMA2 HW request is I3C1_TX */ +#define LL_GPDMA2_REQUEST_I3C1_TC 122U /*!< GPDMA2 HW request is I3C1_TC */ +#define LL_GPDMA2_REQUEST_I3C1_RS 123U /*!< GPDMA2 HW request is I3C1_RS */ +#if defined (I2C4) +#define LL_GPDMA2_REQUEST_I2C4_RX 124U /*!< GPDMA2 HW request is I2C4_RX */ +#define LL_GPDMA2_REQUEST_I2C4_TX 125U /*!< GPDMA2 HW request is I2C4_TX */ +#endif /* I2C4 */ +#if defined (LPTIM3) +#define LL_GPDMA2_REQUEST_LPTIM3_IC1 127U /*!< GPDMA2 HW request is LPTIM3_IC1 */ +#define LL_GPDMA2_REQUEST_LPTIM3_IC2 128U /*!< GPDMA2 HW request is LPTIM3_IC2 */ +#define LL_GPDMA2_REQUEST_LPTIM3_UE 129U /*!< GPDMA2 HW request is LPTIM3_UE */ +#endif /* LPTIM3 */ +#if defined (LPTIM5) +#define LL_GPDMA2_REQUEST_LPTIM5_IC1 130U /*!< GPDMA2 HW request is LPTIM5_IC1 */ +#define LL_GPDMA2_REQUEST_LPTIM5_IC2 131U /*!< GPDMA2 HW request is LPTIM5_IC2 */ +#define LL_GPDMA2_REQUEST_LPTIM5_UE 132U /*!< GPDMA2 HW request is LPTIM5_UE */ +#endif /* LPTIM5 */ +#if defined (LPTIM6) +#define LL_GPDMA2_REQUEST_LPTIM6_IC1 133U /*!< GPDMA2 HW request is LPTIM6_IC1 */ +#define LL_GPDMA2_REQUEST_LPTIM6_IC2 134U /*!< GPDMA2 HW request is LPTIM6_IC2 */ +#define LL_GPDMA2_REQUEST_LPTIM6_UE 135U /*!< GPDMA2 HW request is LPTIM6_UE */ +#endif /* LPTIM6 */ +#if defined (I3C2) +#define LL_GPDMA2_REQUEST_I3C2_RX 136U /*!< GPDMA2 HW request is I3C2_RX */ +#define LL_GPDMA2_REQUEST_I3C2_TX 137U /*!< GPDMA2 HW request is I3C2_TX */ +#define LL_GPDMA2_REQUEST_I3C2_TC 138U /*!< GPDMA2 HW request is I3C2_TC */ +#define LL_GPDMA2_REQUEST_I3C2_RS 139U /*!< GPDMA2 HW request is I3C2_RS */ +#endif /* I3C2 */ + +/** + * @} + */ + +/** @defgroup DMA_LL_EC_TRIGGER_SELECTION Trigger Selection + * @{ + */ +/* GPDMA1 Hardware Triggers */ +#define LL_GPDMA1_TRIGGER_EXTI_LINE0 0U /*!< GPDMA1 HW Trigger signal is EXTI_LINE0 */ +#define LL_GPDMA1_TRIGGER_EXTI_LINE1 1U /*!< GPDMA1 HW Trigger signal is EXTI_LINE1 */ +#define LL_GPDMA1_TRIGGER_EXTI_LINE2 2U /*!< GPDMA1 HW Trigger signal is EXTI_LINE2 */ +#define LL_GPDMA1_TRIGGER_EXTI_LINE3 3U /*!< GPDMA1 HW Trigger signal is EXTI_LINE3 */ +#define LL_GPDMA1_TRIGGER_EXTI_LINE4 4U /*!< GPDMA1 HW Trigger signal is EXTI_LINE4 */ +#define LL_GPDMA1_TRIGGER_EXTI_LINE5 5U /*!< GPDMA1 HW Trigger signal is EXTI_LINE5 */ +#define LL_GPDMA1_TRIGGER_EXTI_LINE6 6U /*!< GPDMA1 HW Trigger signal is EXTI_LINE6 */ +#define LL_GPDMA1_TRIGGER_EXTI_LINE7 7U /*!< GPDMA1 HW Trigger signal is EXTI_LINE7 */ +#define LL_GPDMA1_TRIGGER_TAMP_TRG1 8U /*!< GPDMA1 HW Trigger signal is TAMP_TRG1 */ +#define LL_GPDMA1_TRIGGER_TAMP_TRG2 9U /*!< GPDMA1 HW Trigger signal is TAMP_TRG2 */ +#if defined (TAMP_CR1_TAMP3E) +#define LL_GPDMA1_TRIGGER_TAMP_TRG3 10U /*!< GPDMA1 HW Trigger signal is TAMP_TRG3 */ +#endif /* TAMP_CR1_TAMP3E */ +#define LL_GPDMA1_TRIGGER_LPTIM1_CH1 11U /*!< GPDMA1 HW Trigger signal is LPTIM1_CH1 */ +#define LL_GPDMA1_TRIGGER_LPTIM1_CH2 12U /*!< GPDMA1 HW Trigger signal is LPTIM1_CH2 */ +#define LL_GPDMA1_TRIGGER_LPTIM2_CH1 13U /*!< GPDMA1 HW Trigger signal is LPTIM2_CH1 */ +#define LL_GPDMA1_TRIGGER_LPTIM2_CH2 14U /*!< GPDMA1 HW Trigger signal is LPTIM2_CH2 */ +#define LL_GPDMA1_TRIGGER_RTC_ALRA_TRG 15U /*!< GPDMA1 HW Trigger signal is RTC_ALRA_TRG */ +#define LL_GPDMA1_TRIGGER_RTC_ALRB_TRG 16U /*!< GPDMA1 HW Trigger signal is RTC_ALRB_TRG */ +#define LL_GPDMA1_TRIGGER_RTC_WUT_TRG 17U /*!< GPDMA1 HW Trigger signal is RTC_WUT_TRG */ +#define LL_GPDMA1_TRIGGER_GPDMA1_CH0_TCF 18U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH0_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA1_CH1_TCF 19U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH1_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA1_CH2_TCF 20U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH2_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA1_CH3_TCF 21U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH3_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA1_CH4_TCF 22U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH4_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA1_CH5_TCF 23U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH5_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA1_CH6_TCF 24U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH6_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA1_CH7_TCF 25U /*!< GPDMA1 HW Trigger signal is GPDMA1_CH7_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA2_CH0_TCF 26U /*!< GPDMA1 HW Trigger signal is GPDMA2_CH0_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA2_CH1_TCF 27U /*!< GPDMA1 HW Trigger signal is GPDMA2_CH1_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA2_CH2_TCF 28U /*!< GPDMA1 HW Trigger signal is GPDMA2_CH2_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA2_CH3_TCF 29U /*!< GPDMA1 HW Trigger signal is GPDMA2_CH3_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA2_CH4_TCF 30U /*!< GPDMA1 HW Trigger signal is GPDMA2_CH4_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA2_CH5_TCF 31U /*!< GPDMA1 HW Trigger signal is GPDMA2_CH5_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA2_CH6_TCF 32U /*!< GPDMA1 HW Trigger signal is GPDMA2_CH6_TCF */ +#define LL_GPDMA1_TRIGGER_GPDMA2_CH7_TCF 33U /*!< GPDMA1 HW Trigger signal is GPDMA2_CH7_TCF */ +#define LL_GPDMA1_TRIGGER_TIM2_TRGO 34U /*!< GPDMA1 HW Trigger signal is TIM2_TRGO */ +#if defined (TIM15) +#define LL_GPDMA1_TRIGGER_TIM15_TRGO 35U /*!< GPDMA1 HW Trigger signal is TIM15_TRGO */ +#endif /* TIM15 */ +#if defined (TIM12) +#define LL_GPDMA1_TRIGGER_TIM12_TRGO 36U /*!< GPDMA1 HW Trigger signal is TIM12_TRGO */ +#endif /* TIM12 */ +#if defined (LPTIM3) +#define LL_GPDMA1_TRIGGER_LPTIM3_CH1 37U /*!< GPDMA1 HW Trigger signal is LPTIM3_CH1 */ +#define LL_GPDMA1_TRIGGER_LPTIM3_CH2 38U /*!< GPDMA1 HW Trigger signal is LPTIM3_CH2 */ +#endif /* LPTIM3 */ +#if defined (LPTIM4) +#define LL_GPDMA1_TRIGGER_LPTIM4_AIT 39U /*!< GPDMA1 HW Trigger signal is LPTIM4_AIT */ +#endif /* LPTIM4 */ +#if defined (LPTIM5) +#define LL_GPDMA1_TRIGGER_LPTIM5_CH1 40U /*!< GPDMA1 HW Trigger signal is LPTIM5_CH1 */ +#define LL_GPDMA1_TRIGGER_LPTIM5_CH2 41U /*!< GPDMA1 HW Trigger signal is LPTIM5_CH2 */ +#endif /* LPTIM5 */ +#if defined (LPTIM6) +#define LL_GPDMA1_TRIGGER_LPTIM6_CH1 42U /*!< GPDMA1 HW Trigger signal is LPTIM6_CH1 */ +#define LL_GPDMA1_TRIGGER_LPTIM6_CH2 43U /*!< GPDMA1 HW Trigger signal is LPTIM6_CH2 */ +#endif /* LPTIM6 */ +#if defined (COMP1) +#define LL_GPDMA1_TRIGGER_COMP1_OUT 44U /*!< GPDMA1 HW Trigger signal is COMP1_OUT */ +#endif /* COMP1 */ +#if defined (STM32H503xx) +#define LL_GPDMA1_TRIGGER_EVENTOUT 45U /*!< GPDMA1 HW Trigger signal is COMP1_OUT */ +#endif /* STM32H503xx */ + +/* GPDMA2 Hardware Triggers */ +#define LL_GPDMA2_TRIGGER_EXTI_LINE0 0U /*!< GPDMA2 HW Trigger signal is EXTI_LINE0 */ +#define LL_GPDMA2_TRIGGER_EXTI_LINE1 1U /*!< GPDMA2 HW Trigger signal is EXTI_LINE1 */ +#define LL_GPDMA2_TRIGGER_EXTI_LINE2 2U /*!< GPDMA2 HW Trigger signal is EXTI_LINE2 */ +#define LL_GPDMA2_TRIGGER_EXTI_LINE3 3U /*!< GPDMA2 HW Trigger signal is EXTI_LINE3 */ +#define LL_GPDMA2_TRIGGER_EXTI_LINE4 4U /*!< GPDMA2 HW Trigger signal is EXTI_LINE4 */ +#define LL_GPDMA2_TRIGGER_EXTI_LINE5 5U /*!< GPDMA2 HW Trigger signal is EXTI_LINE5 */ +#define LL_GPDMA2_TRIGGER_EXTI_LINE6 6U /*!< GPDMA2 HW Trigger signal is EXTI_LINE6 */ +#define LL_GPDMA2_TRIGGER_EXTI_LINE7 7U /*!< GPDMA2 HW Trigger signal is EXTI_LINE7 */ +#define LL_GPDMA2_TRIGGER_TAMP_TRG1 8U /*!< GPDMA2 HW Trigger signal is TAMP_TRG1 */ +#define LL_GPDMA2_TRIGGER_TAMP_TRG2 9U /*!< GPDMA2 HW Trigger signal is TAMP_TRG2 */ +#define LL_GPDMA2_TRIGGER_TAMP_TRG3 10U /*!< GPDMA2 HW Trigger signal is TAMP_TRG3 */ +#define LL_GPDMA2_TRIGGER_LPTIM1_CH1 11U /*!< GPDMA2 HW Trigger signal is LPTIM1_CH1 */ +#define LL_GPDMA2_TRIGGER_LPTIM1_CH2 12U /*!< GPDMA2 HW Trigger signal is LPTIM1_CH2 */ +#define LL_GPDMA2_TRIGGER_LPTIM2_CH1 13U /*!< GPDMA2 HW Trigger signal is LPTIM2_CH1 */ +#define LL_GPDMA2_TRIGGER_LPTIM2_CH2 14U /*!< GPDMA2 HW Trigger signal is LPTIM2_CH2 */ +#define LL_GPDMA2_TRIGGER_RTC_ALRA_TRG 15U /*!< GPDMA2 HW Trigger signal is RTC_ALRA_TRG */ +#define LL_GPDMA2_TRIGGER_RTC_ALRB_TRG 16U /*!< GPDMA2 HW Trigger signal is RTC_ALRB_TRG */ +#define LL_GPDMA2_TRIGGER_RTC_WUT_TRG 17U /*!< GPDMA2 HW Trigger signal is RTC_WUT_TRG */ +#define LL_GPDMA2_TRIGGER_GPDMA1_CH0_TCF 18U /*!< GPDMA2 HW Trigger signal is GPDMA1_CH0_TCF */ +#define LL_GPDMA2_TRIGGER_GPDMA1_CH1_TCF 19U /*!< GPDMA2 HW Trigger signal is GPDMA1_CH1_TCF */ +#define LL_GPDMA2_TRIGGER_GPDMA1_CH2_TCF 20U /*!< GPDMA2 HW Trigger signal is GPDMA1_CH2_TCF */ +#define LL_GPDMA2_TRIGGER_GPDMA1_CH3_TCF 21U /*!< GPDMA2 HW Trigger signal is GPDMA1_CH3_TCF */ +#define LL_GPDMA2_TRIGGER_GPDMA1_CH4_TCF 22U /*!< GPDMA2 HW Trigger signal is GPDMA1_CH4_TCF */ +#define LL_GPDMA2_TRIGGER_GPDMA1_CH5_TCF 23U /*!< GPDMA2 HW Trigger signal is GPDMA1_CH5_TCF */ +#define LL_GPDMA2_TRIGGER_GPDMA1_CH6_TCF 24U /*!< GPDMA2 HW Trigger signal is GPDMA1_CH6_TCF */ +#define LL_GPDMA2_TRIGGER_GPDMA1_CH7_TCF 25U /*!< GPDMA2 HW Trigger signal is GPDMA1_CH7_TCF */ +#define LL_GPDMA2_TRIGGER_GPDMA2_CH0_TCF 26U /*!< GPDMA2 HW Trigger signal is GPDMA2_CH0_TCF */ +#define LL_GPDMA2_TRIGGER_GPDMA2_CH1_TCF 27U /*!< GPDMA2 HW Trigger signal is GPDMA2_CH1_TCF */ +#define LL_GPDMA2_TRIGGER_GPDMA2_CH2_TCF 28U /*!< GPDMA2 HW Trigger signal is GPDMA2_CH2_TCF */ +#define LL_GPDMA2_TRIGGER_GPDMA2_CH3_TCF 29U /*!< GPDMA2 HW Trigger signal is GPDMA2_CH3_TCF */ +#define LL_GPDMA2_TRIGGER_GPDMA2_CH4_TCF 30U /*!< GPDMA2 HW Trigger signal is GPDMA2_CH4_TCF */ +#define LL_GPDMA2_TRIGGER_GPDMA2_CH5_TCF 31U /*!< GPDMA2 HW Trigger signal is GPDMA2_CH5_TCF */ +#define LL_GPDMA2_TRIGGER_GPDMA2_CH6_TCF 32U /*!< GPDMA2 HW Trigger signal is GPDMA2_CH6_TCF */ +#define LL_GPDMA2_TRIGGER_GPDMA2_CH7_TCF 33U /*!< GPDMA2 HW Trigger signal is GPDMA2_CH7_TCF */ +#define LL_GPDMA2_TRIGGER_TIM2_TRGO 34U /*!< GPDMA2 HW Trigger signal is TIM2_TRGO */ +#if defined (TIM15) +#define LL_GPDMA2_TRIGGER_TIM15_TRGO 35U /*!< GPDMA2 HW Trigger signal is TIM15_TRGO */ +#endif /* TIM15 */ +#if defined (TIM12) +#define LL_GPDMA2_TRIGGER_TIM12_TRGO 36U /*!< GPDMA2 HW Trigger signal is TIM12_TRGO */ +#endif /* TIM12 */ +#if defined (LPTIM3) +#define LL_GPDMA2_TRIGGER_LPTIM3_CH1 37U /*!< GPDMA2 HW Trigger signal is LPTIM3_CH1 */ +#define LL_GPDMA2_TRIGGER_LPTIM3_CH2 38U /*!< GPDMA2 HW Trigger signal is LPTIM3_CH2 */ +#endif /* LPTIM3 */ +#if defined (LPTIM4) +#define LL_GPDMA2_TRIGGER_LPTIM4_AIT 39U /*!< GPDMA2 HW Trigger signal is LPTIM4_AIT */ +#endif /* LPTIM4 */ +#if defined (LPTIM5) +#define LL_GPDMA2_TRIGGER_LPTIM5_CH1 40U /*!< GPDMA2 HW Trigger signal is LPTIM5_CH1 */ +#define LL_GPDMA2_TRIGGER_LPTIM5_CH2 41U /*!< GPDMA2 HW Trigger signal is LPTIM5_CH2 */ +#endif /* LPTIM5 */ +#if defined (LPTIM6) +#define LL_GPDMA2_TRIGGER_LPTIM6_CH1 42U /*!< GPDMA2 HW Trigger signal is LPTIM6_CH1 */ +#define LL_GPDMA2_TRIGGER_LPTIM6_CH2 43U /*!< GPDMA2 HW Trigger signal is LPTIM6_CH2 */ +#endif /* LPTIM6 */ +#if defined (COMP1) +#define LL_GPDMA2_TRIGGER_COMP1_OUT 44U /*!< GPDMA2 HW Trigger signal is COMP1_OUT */ +#endif /* COMP1 */ +#if defined (STM32H503xx) +#define LL_GPDMA2_TRIGGER_EVENTOUT 45U /*!< GPDMA2 HW Trigger signal is COMP1_OUT */ +#endif /* STM32H503xx */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ + +/** @defgroup DMA_LL_Exported_Macros DMA Exported Macros + * @{ + */ + +/** @defgroup DMA_LL_EM_COMMON_WRITE_READ_REGISTERS Common Write and Read Registers macros + * @{ + */ +/** + * @brief Write a value in DMA register. + * @param __INSTANCE__ DMA Instance. + * @param __REG__ Register to be written. + * @param __VALUE__ Value to be written in the register. + * @retval None. + */ +#define LL_DMA_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG((__INSTANCE__)->__REG__, (__VALUE__)) + +/** + * @brief Read a value in DMA register. + * @param __INSTANCE__ DMA Instance. + * @param __REG__ Register to be read. + * @retval Register value. + */ +#define LL_DMA_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) +/** + * @} + */ + +/** @defgroup DMA_LL_EM_CONVERT_DMAxCHANNELy Convert DMAxChannely + * @{ + */ +/** + * @brief Convert DMAx_Channely into DMAx. + * @param __CHANNEL_INSTANCE__ DMAx_Channely. + * @retval DMAx. + */ +#define LL_DMA_GET_INSTANCE(__CHANNEL_INSTANCE__) \ + (((uint32_t)(__CHANNEL_INSTANCE__) > ((uint32_t)GPDMA1_Channel7)) ? GPDMA2 : GPDMA1) + +/** + * @brief Convert DMAx_Channely into LL_DMA_CHANNEL_y. + * @param __CHANNEL_INSTANCE__ DMAx_Channely. + * @retval LL_DMA_CHANNEL_y. + */ +#define LL_DMA_GET_CHANNEL(__CHANNEL_INSTANCE__) \ + (((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA1_Channel0)) ? LL_DMA_CHANNEL_0 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA2_Channel0)) ? LL_DMA_CHANNEL_0 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA1_Channel1)) ? LL_DMA_CHANNEL_1 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA2_Channel1)) ? LL_DMA_CHANNEL_1 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA1_Channel2)) ? LL_DMA_CHANNEL_2 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA2_Channel2)) ? LL_DMA_CHANNEL_2 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA1_Channel3)) ? LL_DMA_CHANNEL_3 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA2_Channel3)) ? LL_DMA_CHANNEL_3 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA1_Channel4)) ? LL_DMA_CHANNEL_4 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA2_Channel4)) ? LL_DMA_CHANNEL_4 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA1_Channel5)) ? LL_DMA_CHANNEL_5 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA2_Channel5)) ? LL_DMA_CHANNEL_5 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA1_Channel6)) ? LL_DMA_CHANNEL_6 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA2_Channel6)) ? LL_DMA_CHANNEL_6 : \ + ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)GPDMA1_Channel7)) ? LL_DMA_CHANNEL_7 : \ + LL_DMA_CHANNEL_7) + +/** + * @brief Convert DMA Instance DMAx and LL_DMA_CHANNEL_y into DMAx_Channely. + * @param __DMA_INSTANCE__ DMAx. + * @param __CHANNEL__ LL_DMA_CHANNEL_y. + * @retval DMAx_Channely. + */ +#define LL_DMA_GET_CHANNEL_INSTANCE(__DMA_INSTANCE__, __CHANNEL__) \ + ((((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_0))) \ + ? GPDMA1_Channel0 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_1))) \ + ? GPDMA1_Channel1 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_2))) \ + ? GPDMA1_Channel2 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_3))) \ + ? GPDMA1_Channel3 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_4))) \ + ? GPDMA1_Channel4 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_5))) \ + ? GPDMA1_Channel5 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_6))) \ + ? GPDMA1_Channel6 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA1)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_7))) \ + ? GPDMA1_Channel7 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA2)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_0))) \ + ? GPDMA2_Channel0 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA2)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_1))) \ + ? GPDMA2_Channel1 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA2)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_2)))\ + ? GPDMA2_Channel2 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA2)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_3)))\ + ? GPDMA2_Channel3 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA2)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_4)))\ + ? GPDMA2_Channel4 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA2)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_5)))\ + ? GPDMA2_Channel5 : \ + (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)GPDMA2)) && ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_6)))\ + ? GPDMA2_Channel6 : GPDMA2_Channel7) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup DMA_LL_Exported_Functions DMA Exported Functions + * @{ + */ + +/** @defgroup DMA_LL_EF_Configuration Configuration + * @{ + */ +/** + * @brief Enable channel. + * @note This API is used for all available DMA channels. + * @rmtoll CCR EN LL_DMA_EnableChannel + * @param DMAx DMAx Instance. + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_EnableChannel(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + SET_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_EN); +} + +/** + * @brief Disable channel. + * @note This API is used for all available DMA channels. + * @rmtoll CCR EN LL_DMA_DisableChannel + * @param DMAx DMAx Instance. + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_DisableChannel(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + SET_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, + (DMA_CCR_SUSP | DMA_CCR_RESET)); +} + +/** + * @brief Check if channel is enabled or disabled. + * @note This API is used for all available DMA channels. + * @rmtoll CCR EN LL_DMA_IsEnabledChannel + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsEnabledChannel(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_EN) + == (DMA_CCR_EN)) ? 1UL : 0UL); +} + +/** + * @brief Reset channel. + * @note This API is used for all available DMA channels. + * @rmtoll CCR RESET LL_DMA_ResetChannel + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_ResetChannel(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + SET_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_RESET); +} + +/** + * @brief Suspend channel. + * @note This API is used for all available DMA channels. + * @rmtoll CCR SUSP LL_DMA_SuspendChannel + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SuspendChannel(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + SET_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_SUSP); +} + +/** + * @brief Resume channel. + * @note This API is used for all available DMA channels. + * @rmtoll CCR SUSP LL_DMA_ResumeChannel + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_ResumeChannel(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + CLEAR_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_SUSP); +} + +/** + * @brief Check if channel is suspended. + * @note This API is used for all available DMA channels. + * @rmtoll CCR SUSP LL_DMA_IsSuspendedChannel + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsSuspendedChannel(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_SUSP) + == (DMA_CCR_SUSP)) ? 1UL : 0UL); +} + +/** + * @brief Set linked-list base address. + * @note This API is used for all available DMA channels. + * @rmtoll CLBAR LBA LL_DMA_SetLinkedListBaseAddr + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param LinkedListBaseAddr Between 0 to 0xFFFF0000 (where the 4 LSB bytes + * are always 0) + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetLinkedListBaseAddr(const DMA_TypeDef *DMAx, uint32_t Channel, + uint32_t LinkedListBaseAddr) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLBAR, DMA_CLBAR_LBA, + (LinkedListBaseAddr & DMA_CLBAR_LBA)); +} + +/** + * @brief Get linked-list base address. + * @note This API is used for all available DMA channels. + * @rmtoll CLBAR LBA LL_DMA_GetLinkedListBaseAddr + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Value between 0 to 0xFFFF0000 (where the 4 LSB bytes are always 0) + */ +__STATIC_INLINE uint32_t LL_DMA_GetLinkedListBaseAddr(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLBAR, DMA_CLBAR_LBA)); +} + +/** + * @brief Configure all parameters linked to channel control. + * @note This API is used for all available DMA channels. + * @rmtoll CCR PRIO LL_DMA_ConfigControl\n + * CCR LAP LL_DMA_ConfigControl\n + * CCR LSM LL_DMA_ConfigControl + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param Configuration This parameter must be a combination of all the following values: + * @arg @ref LL_DMA_LOW_PRIORITY_LOW_WEIGHT or @ref LL_DMA_LOW_PRIORITY_MID_WEIGHT or + * @ref LL_DMA_LOW_PRIORITY_HIGH_WEIGHT or @ref LL_DMA_HIGH_PRIORITY + * @arg @ref LL_DMA_LINK_ALLOCATED_PORT0 or @ref LL_DMA_LINK_ALLOCATED_PORT1 + * @arg @ref LL_DMA_LSM_FULL_EXECUTION or @ref LL_DMA_LSM_1LINK_EXECUTION + *@retval None. + */ +__STATIC_INLINE void LL_DMA_ConfigControl(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t Configuration) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, + (DMA_CCR_PRIO | DMA_CCR_LAP | DMA_CCR_LSM), Configuration); +} + +/** + * @brief Set priority level. + * @note This API is used for all available DMA channels. + * @rmtoll CCR PRIO LL_DMA_SetChannelPriorityLevel + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param Priority This parameter can be one of the following values: + * @arg @ref LL_DMA_LOW_PRIORITY_LOW_WEIGHT + * @arg @ref LL_DMA_LOW_PRIORITY_MID_WEIGHT + * @arg @ref LL_DMA_LOW_PRIORITY_HIGH_WEIGHT + * @arg @ref LL_DMA_HIGH_PRIORITY + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetChannelPriorityLevel(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t Priority) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_PRIO, Priority); +} + +/** + * @brief Get Channel priority level. + * @note This API is used for all available DMA channels. + * @rmtoll CCR PRIO LL_DMA_GetChannelPriorityLevel + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_LOW_PRIORITY_LOW_WEIGHT + * @arg @ref LL_DMA_LOW_PRIORITY_MID_WEIGHT + * @arg @ref LL_DMA_LOW_PRIORITY_HIGH_WEIGHT + * @arg @ref LL_DMA_HIGH_PRIORITY + */ +__STATIC_INLINE uint32_t LL_DMA_GetChannelPriorityLevel(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_PRIO)); +} + +/** + * @brief Set linked-list allocated port. + * @rmtoll CCR LAP LL_DMA_SetLinkAllocatedPort + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param LinkAllocatedPort This parameter can be one of the following values: + * @arg @ref LL_DMA_LINK_ALLOCATED_PORT0 + * @arg @ref LL_DMA_LINK_ALLOCATED_PORT1 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetLinkAllocatedPort(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t LinkAllocatedPort) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, + DMA_CCR_LAP, LinkAllocatedPort); +} + +/** + * @brief Get linked-list allocated port. + * @rmtoll CCR LAP LL_DMA_GetLinkAllocatedPort + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_LINK_ALLOCATED_PORT0 + * @arg @ref LL_DMA_LINK_ALLOCATED_PORT1 + */ +__STATIC_INLINE uint32_t LL_DMA_GetLinkAllocatedPort(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_LAP)); +} + +/** + * @brief Set link step mode. + * @note This API is used for all available DMA channels. + * @rmtoll CCR LSM LL_DMA_SetLinkStepMode + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param LinkStepMode This parameter can be one of the following values: + * @arg @ref LL_DMA_LSM_FULL_EXECUTION + * @arg @ref LL_DMA_LSM_1LINK_EXECUTION + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetLinkStepMode(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t LinkStepMode) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_LSM, LinkStepMode); +} + +/** + * @brief Get Link step mode. + * @note This API is used for all available DMA channels. + * @rmtoll CCR LSM LL_DMA_GetLinkStepMode + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_LSM_FULL_EXECUTION + * @arg @ref LL_DMA_LSM_1LINK_EXECUTION + */ +__STATIC_INLINE uint32_t LL_DMA_GetLinkStepMode(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_LSM)); +} + +/** + * @brief Configure data transfer. + * @note This API is used for all available DMA channels. + * @rmtoll CTR1 DAP LL_DMA_ConfigTransfer\n + * CTR1 DHX LL_DMA_ConfigTransfer\n + * CTR1 DBX LL_DMA_ConfigTransfer\n + * CTR1 DINC LL_DMA_ConfigTransfer\n + * CTR1 SAP LL_DMA_ConfigTransfer\n + * CTR1 SBX LL_DMA_ConfigTransfer\n + * CTR1 PAM LL_DMA_ConfigTransfer\n + * CTR1 SINC LL_DMA_ConfigTransfer + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param Configuration This parameter must be a combination of all the following values: + * @arg @ref LL_DMA_DEST_ALLOCATED_PORT0 or @ref LL_DMA_DEST_ALLOCATED_PORT1 + * @arg @ref LL_DMA_DEST_HALFWORD_PRESERVE or @ref LL_DMA_DEST_HALFWORD_EXCHANGE + * @arg @ref LL_DMA_DEST_BYTE_PRESERVE or @ref LL_DMA_DEST_BYTE_EXCHANGE + * @arg @ref LL_DMA_SRC_BYTE_PRESERVE or @ref LL_DMA_SRC_BYTE_EXCHANGE + * @arg @ref LL_DMA_DEST_FIXED or @ref LL_DMA_DEST_INCREMENT + * @arg @ref LL_DMA_DEST_DATAWIDTH_BYTE or @ref LL_DMA_DEST_DATAWIDTH_HALFWORD or + * @ref LL_DMA_DEST_DATAWIDTH_WORD + * @arg @ref LL_DMA_SRC_ALLOCATED_PORT0 or @ref LL_DMA_SRC_ALLOCATED_PORT1 + * @arg @ref LL_DMA_DATA_ALIGN_ZEROPADD or @ref LL_DMA_DATA_ALIGN_SIGNEXTPADD or + * @ref LL_DMA_DATA_PACK_UNPACK + * @arg @ref LL_DMA_SRC_FIXED or @ref LL_DMA_SRC_INCREMENT + * @arg @ref LL_DMA_SRC_DATAWIDTH_BYTE or @ref LL_DMA_SRC_DATAWIDTH_HALFWORD or + * @ref LL_DMA_SRC_DATAWIDTH_WORD + *@retval None. + */ +__STATIC_INLINE void LL_DMA_ConfigTransfer(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t Configuration) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, + DMA_CTR1_DAP | DMA_CTR1_DHX | DMA_CTR1_DBX | DMA_CTR1_SBX | DMA_CTR1_DINC | DMA_CTR1_SINC | \ + DMA_CTR1_SAP | DMA_CTR1_PAM | DMA_CTR1_DDW_LOG2 | DMA_CTR1_SDW_LOG2, Configuration); +} + +/** + * @brief Configure source and destination burst length. + * @rmtoll CTR1 DBL_1 LL_DMA_SetDestBurstLength\n + * @rmtoll CTR1 SBL_1 LL_DMA_SetDestBurstLength + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param SrcBurstLength Between 1 to 64 + * @param DestBurstLength Between 1 to 64 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_ConfigBurstLength(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t SrcBurstLength, + uint32_t DestBurstLength) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, + (DMA_CTR1_SBL_1 | DMA_CTR1_DBL_1), (((SrcBurstLength - 1U) << DMA_CTR1_SBL_1_Pos) & DMA_CTR1_SBL_1) | \ + (((DestBurstLength - 1U) << DMA_CTR1_DBL_1_Pos) & DMA_CTR1_DBL_1)); +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Configure all secure parameters linked to DMA channel. + * @note This API is used for all available DMA channels. + * @rmtoll SECCFGR SEC LL_DMA_ConfigChannelSecure\n + * @rmtoll CTR1 SSEC LL_DMA_ConfigChannelSecure\n + * @rmtoll CTR1 DSEC LL_DMA_ConfigChannelSecure + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param Configuration This parameter must be a combination of all the following values: + * @arg @ref LL_DMA_CHANNEL_NSEC or @ref LL_DMA_CHANNEL_SEC + * @arg @ref LL_DMA_CHANNEL_SRC_NSEC or @ref LL_DMA_CHANNEL_SRC_SEC + * @arg @ref LL_DMA_CHANNEL_DEST_NSEC or @ref LL_DMA_CHANNEL_DEST_SEC + * @retval None. + */ +__STATIC_INLINE void LL_DMA_ConfigChannelSecure(DMA_TypeDef *DMAx, uint32_t Channel, uint32_t Configuration) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(DMAx->SECCFGR, (DMA_SECCFGR_SEC0 << Channel), ((Configuration & LL_DMA_CHANNEL_SEC) << Channel)); + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, + (DMA_CTR1_DSEC | DMA_CTR1_DSEC), (Configuration & (~LL_DMA_CHANNEL_SEC))); +} + +/** + * @brief Enable security attribute of the DMA transfer to the destination. + * @note This API is used for all available DMA channels. + * @rmtoll CTR1 DSEC LL_DMA_EnableChannelDestSecure + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_EnableChannelDestSecure(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + SET_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, DMA_CTR1_DSEC); +} + +/** + * @brief Disable security attribute of the DMA transfer to the destination. + * @note This API is used for all available DMA channels. + * @rmtoll CTR1 DSEC LL_DMA_DisableChannelDestSecure + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_DisableChannelDestSecure(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + CLEAR_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, DMA_CTR1_DSEC); +} + +/** + * @brief Check security attribute of the DMA transfer to the destination. + * @note This API is used for all available DMA channels. + * @rmtoll CTR1 DSEC LL_DMA_IsEnabledChannelDestSecure + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsEnabledChannelDestSecure(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, DMA_CTR1_DSEC) + == (DMA_CTR1_DSEC)) ? 1UL : 0UL); +} + +/** + * @brief Enable security attribute of the DMA transfer from the source. + * @note This API is used for all available DMA channels. + * @rmtoll CTR1 SSEC LL_DMA_EnableChannelSrcSecure + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_EnableChannelSrcSecure(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + SET_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, DMA_CTR1_SSEC); +} + +/** + * @brief Disable security attribute of the DMA transfer from the source. + * @note This API is used for all available DMA channels. + * @rmtoll CTR1 SSEC LL_DMA_DisableChannelSrcSecure + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_DisableChannelSrcSecure(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + CLEAR_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, DMA_CTR1_SSEC); +} + +/** + * @brief Check security attribute of the DMA transfer from the source. + * @note This API is used for all available DMA channels. + * @rmtoll CTR1 SSEC LL_DMA_IsEnabledChannelSrcSecure + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsEnabledChannelSrcSecure(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, DMA_CTR1_SSEC) + == (DMA_CTR1_SSEC)) ? 1UL : 0UL); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/** + * @brief Set destination allocated port. + * @rmtoll CTR1 DAP LL_DMA_SetDestAllocatedPort + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param DestAllocatedPort This parameter can be one of the following values: + * @arg @ref LL_DMA_DEST_ALLOCATED_PORT0 + * @arg @ref LL_DMA_DEST_ALLOCATED_PORT1 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetDestAllocatedPort(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t DestAllocatedPort) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, DMA_CTR1_DAP, + DestAllocatedPort); +} + +/** + * @brief Get destination allocated port. + * @rmtoll CTR1 DAP LL_DMA_GetDestAllocatedPort + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_DEST_ALLOCATED_PORT0 + * @arg @ref LL_DMA_DEST_ALLOCATED_PORT1 + */ +__STATIC_INLINE uint32_t LL_DMA_GetDestAllocatedPort(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, DMA_CTR1_DAP)); +} + +/** + * @brief Set destination half-word exchange. + * @rmtoll CTR1 DHX LL_DMA_SetDestHWordExchange + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param DestHWordExchange This parameter can be one of the following values: + * @arg @ref LL_DMA_DEST_HALFWORD_PRESERVE + * @arg @ref LL_DMA_DEST_HALFWORD_EXCHANGE + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetDestHWordExchange(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t DestHWordExchange) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, DMA_CTR1_DHX, + DestHWordExchange); +} + +/** + * @brief Get destination half-word exchange. + * @rmtoll CTR1 DHX LL_DMA_GetDestHWordExchange + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_DEST_HALFWORD_PRESERVE + * @arg @ref LL_DMA_DEST_HALFWORD_EXCHANGE + */ +__STATIC_INLINE uint32_t LL_DMA_GetDestHWordExchange(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, DMA_CTR1_DHX)); +} + +/** + * @brief Set destination byte exchange. + * @rmtoll CTR1 DBX LL_DMA_SetDestByteExchange + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param DestByteExchange This parameter can be one of the following values: + * @arg @ref LL_DMA_DEST_BYTE_PRESERVE + * @arg @ref LL_DMA_DEST_BYTE_EXCHANGE + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetDestByteExchange(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t DestByteExchange) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, DMA_CTR1_DBX, + DestByteExchange); +} + +/** + * @brief Get destination byte exchange. + * @rmtoll CTR1 DBX LL_DMA_GetDestByteExchange + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_DEST_BYTE_PRESERVE + * @arg @ref LL_DMA_DEST_BYTE_EXCHANGE + */ +__STATIC_INLINE uint32_t LL_DMA_GetDestByteExchange(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, DMA_CTR1_DBX)); +} + +/** + * @brief Set source byte exchange. + * @rmtoll CTR1 SBX LL_DMA_SetSrcByteExchange + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param SrcByteExchange This parameter can be one of the following values: + * @arg @ref LL_DMA_SRC_BYTE_PRESERVE + * @arg @ref LL_DMA_SRC_BYTE_EXCHANGE + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetSrcByteExchange(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t SrcByteExchange) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, DMA_CTR1_SBX, + SrcByteExchange); +} + +/** + * @brief Get source byte exchange. + * @rmtoll CTR1 SBX LL_DMA_GetSrcByteExchange + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_SRC_BYTE_PRESERVE + * @arg @ref LL_DMA_SRC_BYTE_EXCHANGE + */ +__STATIC_INLINE uint32_t LL_DMA_GetSrcByteExchange(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, DMA_CTR1_SBX)); +} + +/** + * @brief Set destination burst length. + * @rmtoll CTR1 DBL_1 LL_DMA_SetDestBurstLength + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param DestBurstLength Between 1 to 64 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetDestBurstLength(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t DestBurstLength) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, DMA_CTR1_DBL_1, + ((DestBurstLength - 1U) << DMA_CTR1_DBL_1_Pos) & DMA_CTR1_DBL_1); +} + +/** + * @brief Get destination burst length. + * @rmtoll CTR1 DBL_1 LL_DMA_GetDestBurstLength + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Between 1 to 64. + */ +__STATIC_INLINE uint32_t LL_DMA_GetDestBurstLength(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, + DMA_CTR1_DBL_1) >> DMA_CTR1_DBL_1_Pos) + 1U); +} + +/** + * @brief Set destination increment mode. + * @rmtoll CTR1 DINC LL_DMA_SetDestIncMode + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param DestInc This parameter can be one of the following values: + * @arg @ref LL_DMA_DEST_FIXED + * @arg @ref LL_DMA_DEST_INCREMENT + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetDestIncMode(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t DestInc) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, DMA_CTR1_DINC, DestInc); +} + +/** + * @brief Get destination increment mode. + * @note This API is used for all available DMA channels. + * @rmtoll CTR1 DINC LL_DMA_GetDestIncMode + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_DEST_FIXED + * @arg @ref LL_DMA_DEST_INCREMENT + */ +__STATIC_INLINE uint32_t LL_DMA_GetDestIncMode(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, DMA_CTR1_DINC)); +} + +/** + * @brief Set destination data width. + * @note This API is used for all available DMA channels. + * @rmtoll CTR1 DDW_LOG2 LL_DMA_SetDestDataWidth + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param DestDataWidth This parameter can be one of the following values: + * @arg @ref LL_DMA_DEST_DATAWIDTH_BYTE + * @arg @ref LL_DMA_DEST_DATAWIDTH_HALFWORD + * @arg @ref LL_DMA_DEST_DATAWIDTH_WORD + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetDestDataWidth(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t DestDataWidth) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, DMA_CTR1_DDW_LOG2, + DestDataWidth); +} + +/** + * @brief Get destination data width. + * @note This API is used for all available DMA channels. + * @rmtoll CTR1 DDW_LOG2 LL_DMA_GetDestDataWidth + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_DEST_DATAWIDTH_BYTE + * @arg @ref LL_DMA_DEST_DATAWIDTH_HALFWORD + * @arg @ref LL_DMA_DEST_DATAWIDTH_WORD + */ +__STATIC_INLINE uint32_t LL_DMA_GetDestDataWidth(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, DMA_CTR1_DDW_LOG2)); +} + +/** + * @brief Set source allocated port. + * @rmtoll CTR1 SAP LL_DMA_SetSrcAllocatedPort + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param SrcAllocatedPort This parameter can be one of the following values: + * @arg @ref LL_DMA_SRC_ALLOCATED_PORT0 + * @arg @ref LL_DMA_SRC_ALLOCATED_PORT1 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetSrcAllocatedPort(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t SrcAllocatedPort) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, DMA_CTR1_SAP, + SrcAllocatedPort); +} + +/** + * @brief Get source allocated port. + * @rmtoll CTR1 SAP LL_DMA_GetSrcAllocatedPort + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_SRC_ALLOCATED_PORT0 + * @arg @ref LL_DMA_SRC_ALLOCATED_PORT1 + */ +__STATIC_INLINE uint32_t LL_DMA_GetSrcAllocatedPort(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, DMA_CTR1_SAP)); +} + +/** + * @brief Set data alignment mode. + * @note This API is used for all available DMA channels. + * @rmtoll CTR1 PAM LL_DMA_SetDataAlignment + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param DataAlignment This parameter can be one of the following values: + * @arg @ref LL_DMA_DATA_ALIGN_ZEROPADD + * @arg @ref LL_DMA_DATA_ALIGN_SIGNEXTPADD + * @arg @ref LL_DMA_DATA_PACK_UNPACK + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetDataAlignment(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t DataAlignment) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, DMA_CTR1_PAM, + DataAlignment); +} + +/** + * @brief Get data alignment mode. + * @note This API is used for all available DMA channels. + * @rmtoll CTR1 PAM LL_DMA_GetDataAlignment + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_DATA_ALIGN_ZEROPADD + * @arg @ref LL_DMA_DATA_ALIGN_SIGNEXTPADD + * @arg @ref LL_DMA_DATA_PACK_UNPACK + */ +__STATIC_INLINE uint32_t LL_DMA_GetDataAlignment(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, DMA_CTR1_PAM)); +} + +/** + * @brief Set source burst length. + * @rmtoll CTR1 SBL_1 LL_DMA_SetSrcBurstLength + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param SrcBurstLength Between 1 to 64 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetSrcBurstLength(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t SrcBurstLength) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, DMA_CTR1_SBL_1, + ((SrcBurstLength - 1U) << DMA_CTR1_SBL_1_Pos) & DMA_CTR1_SBL_1); +} + +/** + * @brief Get source burst length. + * @rmtoll CTR1 SBL_1 LL_DMA_GetSrcBurstLength + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Between 1 to 64 + * @retval None. + */ +__STATIC_INLINE uint32_t LL_DMA_GetSrcBurstLength(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, + DMA_CTR1_SBL_1) >> DMA_CTR1_SBL_1_Pos) + 1U); +} + +/** + * @brief Set source increment mode. + * @note This API is used for all available DMA channels. + * @rmtoll CTR1 SINC LL_DMA_SetSrcIncMode + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param SrcInc This parameter can be one of the following values: + * @arg @ref LL_DMA_SRC_FIXED + * @arg @ref LL_DMA_SRC_INCREMENT + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetSrcIncMode(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t SrcInc) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, DMA_CTR1_SINC, SrcInc); +} + +/** + * @brief Get source increment mode. + * @note This API is used for all available DMA channels. + * @rmtoll CTR1 SINC LL_DMA_GetSrcIncMode + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_SRC_FIXED + * @arg @ref LL_DMA_SRC_INCREMENT + */ +__STATIC_INLINE uint32_t LL_DMA_GetSrcIncMode(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, DMA_CTR1_SINC)); +} + +/** + * @brief Set source data width. + * @note This API is used for all available DMA channels. + * @rmtoll CTR1 SDW_LOG2 LL_DMA_SetSrcDataWidth + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param SrcDataWidth This parameter can be one of the following values: + * @arg @ref LL_DMA_SRC_DATAWIDTH_BYTE + * @arg @ref LL_DMA_SRC_DATAWIDTH_HALFWORD + * @arg @ref LL_DMA_SRC_DATAWIDTH_WORD + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetSrcDataWidth(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t SrcDataWidth) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, DMA_CTR1_SDW_LOG2, + SrcDataWidth); +} + +/** + * @brief Get Source Data width. + * @note This API is used for all available DMA channels. + * @rmtoll CTR1 SDW_LOG2 LL_DMA_GetSrcDataWidth + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_SRC_DATAWIDTH_BYTE + * @arg @ref LL_DMA_SRC_DATAWIDTH_HALFWORD + * @arg @ref LL_DMA_SRC_DATAWIDTH_WORD + */ +__STATIC_INLINE uint32_t LL_DMA_GetSrcDataWidth(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR1, DMA_CTR1_SDW_LOG2)); +} + +/** + * @brief Configure channel transfer. + * @note This API is used for all available DMA channels. + * @rmtoll CTR2 TCEM LL_DMA_ConfigChannelTransfer\n + * CTR2 TRIGPOL LL_DMA_ConfigChannelTransfer\n + * CTR2 TRIGM LL_DMA_ConfigChannelTransfer\n + * CTR2 BREQ LL_DMA_ConfigChannelTransfer\n + * CTR2 DREQ LL_DMA_ConfigChannelTransfer\n + * CTR2 SWREQ LL_DMA_ConfigChannelTransfer + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param Configuration This parameter must be a combination of all the following values: + * @arg @ref LL_DMA_TCEM_BLK_TRANSFER or @ref LL_DMA_TCEM_RPT_BLK_TRANSFER or + * @ref LL_DMA_TCEM_EACH_LLITEM_TRANSFER or @ref LL_DMA_TCEM_LAST_LLITEM_TRANSFER + * @arg @ref LL_DMA_TRIG_POLARITY_MASKED or @ref LL_DMA_HWREQUEST_BLK + * @arg @ref LL_DMA_HWREQUEST_SINGLEBURST or @ref LL_DMA_TRIG_POLARITY_RISING or + * @ref LL_DMA_TRIG_POLARITY_FALLING + * @arg @ref LL_DMA_TRIGM_BLK_TRANSFER or @ref LL_DMA_TRIGM_RPT_BLK_TRANSFER or + * @ref LL_DMA_TRIGM_LLI_LINK_TRANSFER or @ref LL_DMA_TRIGM_SINGLBURST_TRANSFER + * @arg @ref LL_DMA_DIRECTION_PERIPH_TO_MEMORY or @ref LL_DMA_DIRECTION_MEMORY_TO_PERIPH or + * @ref LL_DMA_DIRECTION_MEMORY_TO_MEMORY + *@retval None. + */ +__STATIC_INLINE void LL_DMA_ConfigChannelTransfer(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t Configuration) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR2, + (DMA_CTR2_TCEM | DMA_CTR2_TRIGPOL | DMA_CTR2_TRIGM | DMA_CTR2_DREQ | DMA_CTR2_SWREQ | DMA_CTR2_BREQ | + DMA_CTR2_PFREQ), Configuration); +} + +/** + * @brief Set transfer event mode. + * @note This API is used for all available DMA channels. + * @rmtoll CTR2 TCEM LL_DMA_SetTransferEventMode + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param TransferEventMode This parameter can be one of the following values: + * @arg @ref LL_DMA_TCEM_BLK_TRANSFER + * @arg @ref LL_DMA_TCEM_RPT_BLK_TRANSFER + * @arg @ref LL_DMA_TCEM_EACH_LLITEM_TRANSFER + * @arg @ref LL_DMA_TCEM_LAST_LLITEM_TRANSFER + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetTransferEventMode(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t TransferEventMode) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR2, DMA_CTR2_TCEM, + TransferEventMode); +} + +/** + * @brief Get transfer event mode. + * @note This API is used for all available DMA channels. + * @rmtoll CTR2 TCEM LL_DMA_GetTransferEventMode + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_TCEM_BLK_TRANSFER + * @arg @ref LL_DMA_TCEM_RPT_BLK_TRANSFER + * @arg @ref LL_DMA_TCEM_EACH_LLITEM_TRANSFER + * @arg @ref LL_DMA_TCEM_LAST_LLITEM_TRANSFER + */ +__STATIC_INLINE uint32_t LL_DMA_GetTransferEventMode(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR2, DMA_CTR2_TCEM)); +} + +/** + * @brief Set trigger polarity. + * @note This API is used for all available DMA channels. + * @rmtoll CTR2 TRIGPOL LL_DMA_SetTriggerPolarity + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param TriggerPolarity This parameter can be one of the following values: + * @arg @ref LL_DMA_TRIG_POLARITY_MASKED + * @arg @ref LL_DMA_TRIG_POLARITY_RISING + * @arg @ref LL_DMA_TRIG_POLARITY_FALLING + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetTriggerPolarity(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t TriggerPolarity) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR2, DMA_CTR2_TRIGPOL, + TriggerPolarity); +} + +/** + * @brief Get trigger polarity. + * @note This API is used for all available DMA channels. + * @rmtoll CTR2 TRIGPOL LL_DMA_GetTriggerPolarity + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_TRIG_POLARITY_MASKED + * @arg @ref LL_DMA_TRIG_POLARITY_RISING + * @arg @ref LL_DMA_TRIG_POLARITY_FALLING + */ +__STATIC_INLINE uint32_t LL_DMA_GetTriggerPolarity(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR2, DMA_CTR2_TRIGPOL)); +} + +/** + * @brief Set trigger Mode. + * @note This API is used for all available DMA channels. + * @rmtoll CTR2 TRIGM LL_DMA_SetTriggerMode + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param TriggerMode This parameter can be one of the following values: + * @arg @ref LL_DMA_TRIGM_BLK_TRANSFER + * @arg @ref LL_DMA_TRIGM_RPT_BLK_TRANSFER (This value is allowed only for 2D addressing channels) + * @arg @ref LL_DMA_TRIGM_LLI_LINK_TRANSFER + * @arg @ref LL_DMA_TRIGM_SINGLBURST_TRANSFER + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetTriggerMode(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t TriggerMode) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR2, DMA_CTR2_TRIGM, + TriggerMode); +} + +/** + * @brief Get trigger Mode. + * @note This API is used for all available DMA channels. + * @rmtoll CTR2 TRIGM LL_DMA_GetTriggerMode + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_TRIGM_BLK_TRANSFER + * @arg @ref LL_DMA_TRIGM_RPT_BLK_TRANSFER (This value is allowed only for 2D addressing channels) + * @arg @ref LL_DMA_TRIGM_LLI_LINK_TRANSFER + * @arg @ref LL_DMA_TRIGM_SINGLBURST_TRANSFER + */ +__STATIC_INLINE uint32_t LL_DMA_GetTriggerMode(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR2, DMA_CTR2_TRIGM)); +} + +/** + * @brief Set destination hardware and software transfer request. + * @note This API is used for all available DMA channels. + * @rmtoll CTR2 DREQ LL_DMA_SetDataTransferDirection\n + * @rmtoll CTR2 SWREQ LL_DMA_SetDataTransferDirection + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param Direction This parameter can be one of the following values: + * @arg @ref LL_DMA_DIRECTION_PERIPH_TO_MEMORY + * @arg @ref LL_DMA_DIRECTION_MEMORY_TO_PERIPH + * @arg @ref LL_DMA_DIRECTION_MEMORY_TO_MEMORY + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetDataTransferDirection(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t Direction) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR2, + DMA_CTR2_DREQ | DMA_CTR2_SWREQ, Direction); +} + +/** + * @brief Get destination hardware and software transfer request. + * @note This API is used for all available DMA channels. + * @rmtoll CTR2 DREQ LL_DMA_GetDataTransferDirection\n + * @rmtoll CTR2 SWREQ LL_DMA_GetDataTransferDirection + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_DIRECTION_PERIPH_TO_MEMORY + * @arg @ref LL_DMA_DIRECTION_MEMORY_TO_PERIPH + * @arg @ref LL_DMA_DIRECTION_MEMORY_TO_MEMORY + */ +__STATIC_INLINE uint32_t LL_DMA_GetDataTransferDirection(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR2, + DMA_CTR2_DREQ | DMA_CTR2_SWREQ)); +} + +/** + * @brief Set block hardware request. + * @note This API is used for all available DMA channels. + * @rmtoll CTR2 BREQ LL_DMA_SetBlkHWRequest\n + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param BlkHWRequest This parameter can be one of the following values: + * @arg @ref LL_DMA_HWREQUEST_SINGLEBURST + * @arg @ref LL_DMA_HWREQUEST_BLK + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetBlkHWRequest(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t BlkHWRequest) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR2, DMA_CTR2_BREQ, + BlkHWRequest); +} + +/** + * @brief Get block hardware request. + * @note This API is used for all available DMA channels. + * @rmtoll CTR2 BREQ LL_DMA_GetBlkHWRequest\n + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_HWREQUEST_SINGLEBURST + * @arg @ref LL_DMA_HWREQUEST_BLK + */ +__STATIC_INLINE uint32_t LL_DMA_GetBlkHWRequest(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR2, DMA_CTR2_BREQ)); +} + +/** + * @brief Set hardware request. + * @note This API is used for all available DMA channels. + * @rmtoll CTR2 REQSEL LL_DMA_SetPeriphRequest + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param Request This parameter can be one of the following values: + * @arg @ref LL_GPDMA1_REQUEST_ADC1 + * @arg @ref LL_GPDMA1_REQUEST_ADC2 (*) + * @arg @ref LL_GPDMA1_REQUEST_DAC1_CH1 + * @arg @ref LL_GPDMA1_REQUEST_DAC1_CH2 + * @arg @ref LL_GPDMA1_REQUEST_TIM6_UP + * @arg @ref LL_GPDMA1_REQUEST_TIM7_UP + * @arg @ref LL_GPDMA1_REQUEST_SPI1_RX + * @arg @ref LL_GPDMA1_REQUEST_SPI1_TX + * @arg @ref LL_GPDMA1_REQUEST_SPI2_RX + * @arg @ref LL_GPDMA1_REQUEST_SPI2_TX + * @arg @ref LL_GPDMA1_REQUEST_SPI3_RX + * @arg @ref LL_GPDMA1_REQUEST_SPI3_TX + * @arg @ref LL_GPDMA1_REQUEST_I2C1_RX + * @arg @ref LL_GPDMA1_REQUEST_I2C1_TX + * @arg @ref LL_GPDMA1_REQUEST_I2C2_RX + * @arg @ref LL_GPDMA1_REQUEST_I2C2_TX + * @arg @ref LL_GPDMA1_REQUEST_I2C3_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_I2C3_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_USART1_RX + * @arg @ref LL_GPDMA1_REQUEST_USART1_TX + * @arg @ref LL_GPDMA1_REQUEST_USART2_RX + * @arg @ref LL_GPDMA1_REQUEST_USART2_TX + * @arg @ref LL_GPDMA1_REQUEST_USART3_RX + * @arg @ref LL_GPDMA1_REQUEST_USART3_TX + * @arg @ref LL_GPDMA1_REQUEST_UART4_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_UART4_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_UART5_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_UART5_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_USART6_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_USART6_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_UART7_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_UART7_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_UART8_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_UART8_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_UART9_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_UART9_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_USART10_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_USART10_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_USART11_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_USART11_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_UART12_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_UART12_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_LPUART1_RX + * @arg @ref LL_GPDMA1_REQUEST_LPUART1_TX + * @arg @ref LL_GPDMA1_REQUEST_SPI4_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_SPI4_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_SPI5_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_SPI5_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_SPI6_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_SPI6_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_SAI1_A (*) + * @arg @ref LL_GPDMA1_REQUEST_SAI1_B (*) + * @arg @ref LL_GPDMA1_REQUEST_SAI2_A (*) + * @arg @ref LL_GPDMA1_REQUEST_SAI2_B (*) + * @arg @ref LL_GPDMA1_REQUEST_OCTOSPI1 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM1_CH1 + * @arg @ref LL_GPDMA1_REQUEST_TIM1_CH2 + * @arg @ref LL_GPDMA1_REQUEST_TIM1_CH3 + * @arg @ref LL_GPDMA1_REQUEST_TIM1_CH4 + * @arg @ref LL_GPDMA1_REQUEST_TIM1_UP + * @arg @ref LL_GPDMA1_REQUEST_TIM1_TRIG + * @arg @ref LL_GPDMA1_REQUEST_TIM1_COM + * @arg @ref LL_GPDMA1_REQUEST_TIM8_CH1 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM8_CH2 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM8_CH3 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM8_CH4 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM8_UP (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM8_TRIG (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM8_COM (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM2_CH1 + * @arg @ref LL_GPDMA1_REQUEST_TIM2_CH2 + * @arg @ref LL_GPDMA1_REQUEST_TIM2_CH3 + * @arg @ref LL_GPDMA1_REQUEST_TIM2_CH4 + * @arg @ref LL_GPDMA1_REQUEST_TIM2_UP + * @arg @ref LL_GPDMA1_REQUEST_TIM3_CH1 + * @arg @ref LL_GPDMA1_REQUEST_TIM3_CH2 + * @arg @ref LL_GPDMA1_REQUEST_TIM3_CH3 + * @arg @ref LL_GPDMA1_REQUEST_TIM3_CH4 + * @arg @ref LL_GPDMA1_REQUEST_TIM3_UP + * @arg @ref LL_GPDMA1_REQUEST_TIM3_TRIG + * @arg @ref LL_GPDMA1_REQUEST_TIM4_CH1 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM4_CH2 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM4_CH3 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM4_CH4 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM4_UP (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM5_CH1 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM5_CH2 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM5_CH3 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM5_CH4 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM5_UP (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM5_TRIG (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM15_CH1 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM15_UP (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM15_TRIG (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM15_COM (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM16_CH1 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM16_UP (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM17_CH1 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM17_UP (*) + * @arg @ref LL_GPDMA1_REQUEST_LPTIM1_IC1 + * @arg @ref LL_GPDMA1_REQUEST_LPTIM1_IC2 + * @arg @ref LL_GPDMA1_REQUEST_LPTIM1_UE + * @arg @ref LL_GPDMA1_REQUEST_LPTIM2_IC1 + * @arg @ref LL_GPDMA1_REQUEST_LPTIM2_IC2 + * @arg @ref LL_GPDMA1_REQUEST_LPTIM2_UE + * @arg @ref LL_GPDMA1_REQUEST_DCMI (*) + * @arg @ref LL_GPDMA1_REQUEST_AES_OUT (*) + * @arg @ref LL_GPDMA1_REQUEST_AES_IN (*) + * @arg @ref LL_GPDMA1_REQUEST_HASH_IN + * @arg @ref LL_GPDMA1_REQUEST_UCPD1_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_UCPD1_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_CORDIC_READ (*) + * @arg @ref LL_GPDMA1_REQUEST_CORDIC_WRITE (*) + * @arg @ref LL_GPDMA1_REQUEST_FMAC_READ (*) + * @arg @ref LL_GPDMA1_REQUEST_FMAC_WRITE (*) + * @arg @ref LL_GPDMA1_REQUEST_SAES_OUT (*) + * @arg @ref LL_GPDMA1_REQUEST_SAES_IN (*) + * @arg @ref LL_GPDMA1_REQUEST_I3C1_RX + * @arg @ref LL_GPDMA1_REQUEST_I3C1_TX + * @arg @ref LL_GPDMA1_REQUEST_I3C1_TC + * @arg @ref LL_GPDMA1_REQUEST_I3C1_RS + * @arg @ref LL_GPDMA1_REQUEST_I2C4_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_I2C4_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_LPTIM3_IC1 (*) + * @arg @ref LL_GPDMA1_REQUEST_LPTIM3_IC2 (*) + * @arg @ref LL_GPDMA1_REQUEST_LPTIM3_UE (*) + * @arg @ref LL_GPDMA1_REQUEST_LPTIM5_IC1 (*) + * @arg @ref LL_GPDMA1_REQUEST_LPTIM5_IC2 (*) + * @arg @ref LL_GPDMA1_REQUEST_LPTIM5_UE (*) + * @arg @ref LL_GPDMA1_REQUEST_LPTIM6_IC1 (*) + * @arg @ref LL_GPDMA1_REQUEST_LPTIM6_IC2 (*) + * @arg @ref LL_GPDMA1_REQUEST_LPTIM6_UE (*) + * @arg @ref LL_GPDMA1_REQUEST_I3C2_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_I3C2_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_I3C2_TC (*) + * @arg @ref LL_GPDMA1_REQUEST_I3C2_RS (*) + * + * @arg @ref LL_GPDMA2_REQUEST_ADC1 + * @arg @ref LL_GPDMA2_REQUEST_ADC2 (*) + * @arg @ref LL_GPDMA2_REQUEST_DAC1_CH1 + * @arg @ref LL_GPDMA2_REQUEST_DAC1_CH2 + * @arg @ref LL_GPDMA2_REQUEST_TIM6_UP + * @arg @ref LL_GPDMA2_REQUEST_TIM7_UP + * @arg @ref LL_GPDMA2_REQUEST_SPI1_RX + * @arg @ref LL_GPDMA2_REQUEST_SPI1_TX + * @arg @ref LL_GPDMA2_REQUEST_SPI2_RX + * @arg @ref LL_GPDMA2_REQUEST_SPI2_TX + * @arg @ref LL_GPDMA2_REQUEST_SPI3_RX + * @arg @ref LL_GPDMA2_REQUEST_SPI3_TX + * @arg @ref LL_GPDMA2_REQUEST_I2C1_RX + * @arg @ref LL_GPDMA2_REQUEST_I2C1_TX + * @arg @ref LL_GPDMA2_REQUEST_I2C2_RX + * @arg @ref LL_GPDMA2_REQUEST_I2C2_TX + * @arg @ref LL_GPDMA2_REQUEST_I2C3_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_I2C3_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_USART1_RX + * @arg @ref LL_GPDMA2_REQUEST_USART1_TX + * @arg @ref LL_GPDMA2_REQUEST_USART2_RX + * @arg @ref LL_GPDMA2_REQUEST_USART2_TX + * @arg @ref LL_GPDMA2_REQUEST_USART3_RX + * @arg @ref LL_GPDMA2_REQUEST_USART3_TX + * @arg @ref LL_GPDMA2_REQUEST_UART4_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_UART4_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_UART5_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_UART5_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_USART6_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_USART6_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_UART7_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_UART7_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_UART8_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_UART8_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_UART9_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_UART9_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_USART10_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_USART10_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_USART11_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_USART11_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_UART12_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_UART12_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_LPUART1_RX + * @arg @ref LL_GPDMA2_REQUEST_LPUART1_TX + * @arg @ref LL_GPDMA2_REQUEST_SPI4_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_SPI4_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_SPI5_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_SPI5_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_SPI6_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_SPI6_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_SAI1_A (*) + * @arg @ref LL_GPDMA2_REQUEST_SAI1_B (*) + * @arg @ref LL_GPDMA2_REQUEST_SAI2_A (*) + * @arg @ref LL_GPDMA2_REQUEST_SAI2_B (*) + * @arg @ref LL_GPDMA2_REQUEST_OCTOSPI1 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM1_CH1 + * @arg @ref LL_GPDMA2_REQUEST_TIM1_CH2 + * @arg @ref LL_GPDMA2_REQUEST_TIM1_CH3 + * @arg @ref LL_GPDMA2_REQUEST_TIM1_CH4 + * @arg @ref LL_GPDMA2_REQUEST_TIM1_UP + * @arg @ref LL_GPDMA2_REQUEST_TIM1_TRIG + * @arg @ref LL_GPDMA2_REQUEST_TIM1_COM + * @arg @ref LL_GPDMA2_REQUEST_TIM8_CH1 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM8_CH2 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM8_CH3 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM8_CH4 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM8_UP (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM8_TRIG (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM8_COM (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM2_CH1 + * @arg @ref LL_GPDMA2_REQUEST_TIM2_CH2 + * @arg @ref LL_GPDMA2_REQUEST_TIM2_CH3 + * @arg @ref LL_GPDMA2_REQUEST_TIM2_CH4 + * @arg @ref LL_GPDMA2_REQUEST_TIM2_UP + * @arg @ref LL_GPDMA2_REQUEST_TIM3_CH1 + * @arg @ref LL_GPDMA2_REQUEST_TIM3_CH2 + * @arg @ref LL_GPDMA2_REQUEST_TIM3_CH3 + * @arg @ref LL_GPDMA2_REQUEST_TIM3_CH4 + * @arg @ref LL_GPDMA2_REQUEST_TIM3_UP + * @arg @ref LL_GPDMA2_REQUEST_TIM3_TRIG + * @arg @ref LL_GPDMA2_REQUEST_TIM4_CH1 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM4_CH2 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM4_CH3 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM4_CH4 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM4_UP (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM5_CH1 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM5_CH2 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM5_CH3 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM5_CH4 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM5_UP (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM5_TRIG (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM15_CH1 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM15_UP (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM15_TRIG (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM15_COM (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM16_CH1 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM16_UP (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM17_CH1 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM17_UP (*) + * @arg @ref LL_GPDMA2_REQUEST_LPTIM1_IC1 + * @arg @ref LL_GPDMA2_REQUEST_LPTIM1_IC2 + * @arg @ref LL_GPDMA2_REQUEST_LPTIM1_UE + * @arg @ref LL_GPDMA2_REQUEST_LPTIM2_IC1 + * @arg @ref LL_GPDMA2_REQUEST_LPTIM2_IC2 + * @arg @ref LL_GPDMA2_REQUEST_LPTIM2_UE + * @arg @ref LL_GPDMA2_REQUEST_DCMI (*) + * @arg @ref LL_GPDMA2_REQUEST_AES_OUT (*) + * @arg @ref LL_GPDMA2_REQUEST_AES_IN (*) + * @arg @ref LL_GPDMA2_REQUEST_HASH_IN + * @arg @ref LL_GPDMA2_REQUEST_UCPD1_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_UCPD1_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_CORDIC_READ (*) + * @arg @ref LL_GPDMA2_REQUEST_CORDIC_WRITE (*) + * @arg @ref LL_GPDMA2_REQUEST_FMAC_READ (*) + * @arg @ref LL_GPDMA2_REQUEST_FMAC_WRITE (*) + * @arg @ref LL_GPDMA2_REQUEST_SAES_OUT (*) + * @arg @ref LL_GPDMA2_REQUEST_SAES_IN (*) + * @arg @ref LL_GPDMA2_REQUEST_I3C1_RX + * @arg @ref LL_GPDMA2_REQUEST_I3C1_TX + * @arg @ref LL_GPDMA2_REQUEST_I3C1_TC + * @arg @ref LL_GPDMA2_REQUEST_I3C1_RS + * @arg @ref LL_GPDMA2_REQUEST_I2C4_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_I2C4_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_LPTIM3_IC1 (*) + * @arg @ref LL_GPDMA2_REQUEST_LPTIM3_IC2 (*) + * @arg @ref LL_GPDMA2_REQUEST_LPTIM3_UE (*) + * @arg @ref LL_GPDMA2_REQUEST_LPTIM5_IC1 (*) + * @arg @ref LL_GPDMA2_REQUEST_LPTIM5_IC2 (*) + * @arg @ref LL_GPDMA2_REQUEST_LPTIM5_UE (*) + * @arg @ref LL_GPDMA2_REQUEST_LPTIM6_IC1 (*) + * @arg @ref LL_GPDMA2_REQUEST_LPTIM6_IC2 (*) + * @arg @ref LL_GPDMA2_REQUEST_LPTIM6_UE (*) + * @arg @ref LL_GPDMA2_REQUEST_I3C2_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_I3C2_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_I3C2_TC (*) + * @arg @ref LL_GPDMA2_REQUEST_I3C2_RS (*) + * + * @note (*) Availability depends on devices. + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetPeriphRequest(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t Request) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR2, DMA_CTR2_REQSEL, Request); +} + +/** + * @brief Get hardware request. + * @note This API is used for all available DMA channels. + * @rmtoll CTR2 REQSEL LL_DMA_GetPeriphRequest + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_GPDMA1_REQUEST_ADC1 + * @arg @ref LL_GPDMA1_REQUEST_ADC2 (*) + * @arg @ref LL_GPDMA1_REQUEST_DAC1_CH1 + * @arg @ref LL_GPDMA1_REQUEST_DAC1_CH2 + * @arg @ref LL_GPDMA1_REQUEST_TIM6_UP + * @arg @ref LL_GPDMA1_REQUEST_TIM7_UP + * @arg @ref LL_GPDMA1_REQUEST_SPI1_RX + * @arg @ref LL_GPDMA1_REQUEST_SPI1_TX + * @arg @ref LL_GPDMA1_REQUEST_SPI2_RX + * @arg @ref LL_GPDMA1_REQUEST_SPI2_TX + * @arg @ref LL_GPDMA1_REQUEST_SPI3_RX + * @arg @ref LL_GPDMA1_REQUEST_SPI3_TX + * @arg @ref LL_GPDMA1_REQUEST_I2C1_RX + * @arg @ref LL_GPDMA1_REQUEST_I2C1_TX + * @arg @ref LL_GPDMA1_REQUEST_I2C2_RX + * @arg @ref LL_GPDMA1_REQUEST_I2C2_TX + * @arg @ref LL_GPDMA1_REQUEST_I2C3_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_I2C3_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_USART1_RX + * @arg @ref LL_GPDMA1_REQUEST_USART1_TX + * @arg @ref LL_GPDMA1_REQUEST_USART2_RX + * @arg @ref LL_GPDMA1_REQUEST_USART2_TX + * @arg @ref LL_GPDMA1_REQUEST_USART3_RX + * @arg @ref LL_GPDMA1_REQUEST_USART3_TX + * @arg @ref LL_GPDMA1_REQUEST_UART4_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_UART4_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_UART5_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_UART5_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_USART6_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_USART6_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_UART7_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_UART7_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_UART8_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_UART8_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_UART9_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_UART9_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_USART10_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_USART10_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_USART11_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_USART11_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_UART12_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_UART12_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_LPUART1_RX + * @arg @ref LL_GPDMA1_REQUEST_LPUART1_TX + * @arg @ref LL_GPDMA1_REQUEST_SPI4_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_SPI4_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_SPI5_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_SPI5_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_SPI6_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_SPI6_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_SAI1_A (*) + * @arg @ref LL_GPDMA1_REQUEST_SAI1_B (*) + * @arg @ref LL_GPDMA1_REQUEST_SAI2_A (*) + * @arg @ref LL_GPDMA1_REQUEST_SAI2_B (*) + * @arg @ref LL_GPDMA1_REQUEST_OCTOSPI1 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM1_CH1 + * @arg @ref LL_GPDMA1_REQUEST_TIM1_CH2 + * @arg @ref LL_GPDMA1_REQUEST_TIM1_CH3 + * @arg @ref LL_GPDMA1_REQUEST_TIM1_CH4 + * @arg @ref LL_GPDMA1_REQUEST_TIM1_UP + * @arg @ref LL_GPDMA1_REQUEST_TIM1_TRIG + * @arg @ref LL_GPDMA1_REQUEST_TIM1_COM + * @arg @ref LL_GPDMA1_REQUEST_TIM8_CH1 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM8_CH2 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM8_CH3 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM8_CH4 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM8_UP (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM8_TRIG (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM8_COM (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM2_CH1 + * @arg @ref LL_GPDMA1_REQUEST_TIM2_CH2 + * @arg @ref LL_GPDMA1_REQUEST_TIM2_CH3 + * @arg @ref LL_GPDMA1_REQUEST_TIM2_CH4 + * @arg @ref LL_GPDMA1_REQUEST_TIM2_UP + * @arg @ref LL_GPDMA1_REQUEST_TIM3_CH1 + * @arg @ref LL_GPDMA1_REQUEST_TIM3_CH2 + * @arg @ref LL_GPDMA1_REQUEST_TIM3_CH3 + * @arg @ref LL_GPDMA1_REQUEST_TIM3_CH4 + * @arg @ref LL_GPDMA1_REQUEST_TIM3_UP + * @arg @ref LL_GPDMA1_REQUEST_TIM3_TRIG + * @arg @ref LL_GPDMA1_REQUEST_TIM4_CH1 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM4_CH2 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM4_CH3 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM4_CH4 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM4_UP (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM5_CH1 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM5_CH2 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM5_CH3 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM5_CH4 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM5_UP (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM5_TRIG (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM15_CH1 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM15_UP (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM15_TRIG (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM15_COM (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM16_CH1 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM16_UP (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM17_CH1 (*) + * @arg @ref LL_GPDMA1_REQUEST_TIM17_UP (*) + * @arg @ref LL_GPDMA1_REQUEST_LPTIM1_IC1 + * @arg @ref LL_GPDMA1_REQUEST_LPTIM1_IC2 + * @arg @ref LL_GPDMA1_REQUEST_LPTIM1_UE + * @arg @ref LL_GPDMA1_REQUEST_LPTIM2_IC1 + * @arg @ref LL_GPDMA1_REQUEST_LPTIM2_IC2 + * @arg @ref LL_GPDMA1_REQUEST_LPTIM2_UE + * @arg @ref LL_GPDMA1_REQUEST_DCMI (*) + * @arg @ref LL_GPDMA1_REQUEST_AES_OUT (*) + * @arg @ref LL_GPDMA1_REQUEST_AES_IN (*) + * @arg @ref LL_GPDMA1_REQUEST_HASH_IN + * @arg @ref LL_GPDMA1_REQUEST_UCPD1_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_UCPD1_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_CORDIC_READ (*) + * @arg @ref LL_GPDMA1_REQUEST_CORDIC_WRITE (*) + * @arg @ref LL_GPDMA1_REQUEST_FMAC_READ (*) + * @arg @ref LL_GPDMA1_REQUEST_FMAC_WRITE (*) + * @arg @ref LL_GPDMA1_REQUEST_SAES_OUT (*) + * @arg @ref LL_GPDMA1_REQUEST_SAES_IN (*) + * @arg @ref LL_GPDMA1_REQUEST_I3C1_RX + * @arg @ref LL_GPDMA1_REQUEST_I3C1_TX + * @arg @ref LL_GPDMA1_REQUEST_I3C1_TC + * @arg @ref LL_GPDMA1_REQUEST_I3C1_RS + * @arg @ref LL_GPDMA1_REQUEST_I2C4_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_I2C4_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_LPTIM3_IC1 (*) + * @arg @ref LL_GPDMA1_REQUEST_LPTIM3_IC2 (*) + * @arg @ref LL_GPDMA1_REQUEST_LPTIM3_UE (*) + * @arg @ref LL_GPDMA1_REQUEST_LPTIM5_IC1 (*) + * @arg @ref LL_GPDMA1_REQUEST_LPTIM5_IC2 (*) + * @arg @ref LL_GPDMA1_REQUEST_LPTIM5_UE (*) + * @arg @ref LL_GPDMA1_REQUEST_LPTIM6_IC1 (*) + * @arg @ref LL_GPDMA1_REQUEST_LPTIM6_IC2 (*) + * @arg @ref LL_GPDMA1_REQUEST_LPTIM6_UE (*) + * @arg @ref LL_GPDMA1_REQUEST_I3C2_RX (*) + * @arg @ref LL_GPDMA1_REQUEST_I3C2_TX (*) + * @arg @ref LL_GPDMA1_REQUEST_I3C2_TC (*) + * @arg @ref LL_GPDMA1_REQUEST_I3C2_RS (*) + * + * @arg @ref LL_GPDMA2_REQUEST_ADC1 + * @arg @ref LL_GPDMA2_REQUEST_ADC2 (*) + * @arg @ref LL_GPDMA2_REQUEST_DAC1_CH1 + * @arg @ref LL_GPDMA2_REQUEST_DAC1_CH2 + * @arg @ref LL_GPDMA2_REQUEST_TIM6_UP + * @arg @ref LL_GPDMA2_REQUEST_TIM7_UP + * @arg @ref LL_GPDMA2_REQUEST_SPI1_RX + * @arg @ref LL_GPDMA2_REQUEST_SPI1_TX + * @arg @ref LL_GPDMA2_REQUEST_SPI2_RX + * @arg @ref LL_GPDMA2_REQUEST_SPI2_TX + * @arg @ref LL_GPDMA2_REQUEST_SPI3_RX + * @arg @ref LL_GPDMA2_REQUEST_SPI3_TX + * @arg @ref LL_GPDMA2_REQUEST_I2C1_RX + * @arg @ref LL_GPDMA2_REQUEST_I2C1_TX + * @arg @ref LL_GPDMA2_REQUEST_I2C2_RX + * @arg @ref LL_GPDMA2_REQUEST_I2C2_TX + * @arg @ref LL_GPDMA2_REQUEST_I2C3_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_I2C3_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_USART1_RX + * @arg @ref LL_GPDMA2_REQUEST_USART1_TX + * @arg @ref LL_GPDMA2_REQUEST_USART2_RX + * @arg @ref LL_GPDMA2_REQUEST_USART2_TX + * @arg @ref LL_GPDMA2_REQUEST_USART3_RX + * @arg @ref LL_GPDMA2_REQUEST_USART3_TX + * @arg @ref LL_GPDMA2_REQUEST_UART4_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_UART4_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_UART5_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_UART5_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_USART6_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_USART6_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_UART7_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_UART7_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_UART8_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_UART8_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_UART9_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_UART9_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_USART10_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_USART10_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_USART11_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_USART11_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_UART12_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_UART12_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_LPUART1_RX + * @arg @ref LL_GPDMA2_REQUEST_LPUART1_TX + * @arg @ref LL_GPDMA2_REQUEST_SPI4_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_SPI4_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_SPI5_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_SPI5_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_SPI6_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_SPI6_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_SAI1_A (*) + * @arg @ref LL_GPDMA2_REQUEST_SAI1_B (*) + * @arg @ref LL_GPDMA2_REQUEST_SAI2_A (*) + * @arg @ref LL_GPDMA2_REQUEST_SAI2_B (*) + * @arg @ref LL_GPDMA2_REQUEST_OCTOSPI1 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM1_CH1 + * @arg @ref LL_GPDMA2_REQUEST_TIM1_CH2 + * @arg @ref LL_GPDMA2_REQUEST_TIM1_CH3 + * @arg @ref LL_GPDMA2_REQUEST_TIM1_CH4 + * @arg @ref LL_GPDMA2_REQUEST_TIM1_UP + * @arg @ref LL_GPDMA2_REQUEST_TIM1_TRIG + * @arg @ref LL_GPDMA2_REQUEST_TIM1_COM + * @arg @ref LL_GPDMA2_REQUEST_TIM8_CH1 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM8_CH2 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM8_CH3 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM8_CH4 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM8_UP (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM8_TRIG (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM8_COM (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM2_CH1 + * @arg @ref LL_GPDMA2_REQUEST_TIM2_CH2 + * @arg @ref LL_GPDMA2_REQUEST_TIM2_CH3 + * @arg @ref LL_GPDMA2_REQUEST_TIM2_CH4 + * @arg @ref LL_GPDMA2_REQUEST_TIM2_UP + * @arg @ref LL_GPDMA2_REQUEST_TIM3_CH1 + * @arg @ref LL_GPDMA2_REQUEST_TIM3_CH2 + * @arg @ref LL_GPDMA2_REQUEST_TIM3_CH3 + * @arg @ref LL_GPDMA2_REQUEST_TIM3_CH4 + * @arg @ref LL_GPDMA2_REQUEST_TIM3_UP + * @arg @ref LL_GPDMA2_REQUEST_TIM3_TRIG + * @arg @ref LL_GPDMA2_REQUEST_TIM4_CH1 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM4_CH2 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM4_CH3 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM4_CH4 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM4_UP (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM5_CH1 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM5_CH2 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM5_CH3 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM5_CH4 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM5_UP (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM5_TRIG (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM15_CH1 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM15_UP (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM15_TRIG (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM15_COM (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM16_CH1 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM16_UP (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM17_CH1 (*) + * @arg @ref LL_GPDMA2_REQUEST_TIM17_UP (*) + * @arg @ref LL_GPDMA2_REQUEST_LPTIM1_IC1 + * @arg @ref LL_GPDMA2_REQUEST_LPTIM1_IC2 + * @arg @ref LL_GPDMA2_REQUEST_LPTIM1_UE + * @arg @ref LL_GPDMA2_REQUEST_LPTIM2_IC1 + * @arg @ref LL_GPDMA2_REQUEST_LPTIM2_IC2 + * @arg @ref LL_GPDMA2_REQUEST_LPTIM2_UE + * @arg @ref LL_GPDMA2_REQUEST_DCMI (*) + * @arg @ref LL_GPDMA2_REQUEST_AES_OUT (*) + * @arg @ref LL_GPDMA2_REQUEST_AES_IN (*) + * @arg @ref LL_GPDMA2_REQUEST_HASH_IN + * @arg @ref LL_GPDMA2_REQUEST_UCPD1_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_UCPD1_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_CORDIC_READ (*) + * @arg @ref LL_GPDMA2_REQUEST_CORDIC_WRITE (*) + * @arg @ref LL_GPDMA2_REQUEST_FMAC_READ (*) + * @arg @ref LL_GPDMA2_REQUEST_FMAC_WRITE (*) + * @arg @ref LL_GPDMA2_REQUEST_SAES_OUT (*) + * @arg @ref LL_GPDMA2_REQUEST_SAES_IN (*) + * @arg @ref LL_GPDMA2_REQUEST_I3C1_RX + * @arg @ref LL_GPDMA2_REQUEST_I3C1_TX + * @arg @ref LL_GPDMA2_REQUEST_I3C1_TC + * @arg @ref LL_GPDMA2_REQUEST_I3C1_RS + * @arg @ref LL_GPDMA2_REQUEST_I2C4_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_I2C4_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_LPTIM3_IC1 (*) + * @arg @ref LL_GPDMA2_REQUEST_LPTIM3_IC2 (*) + * @arg @ref LL_GPDMA2_REQUEST_LPTIM3_UE (*) + * @arg @ref LL_GPDMA2_REQUEST_LPTIM5_IC1 (*) + * @arg @ref LL_GPDMA2_REQUEST_LPTIM5_IC2 (*) + * @arg @ref LL_GPDMA2_REQUEST_LPTIM5_UE (*) + * @arg @ref LL_GPDMA2_REQUEST_LPTIM6_IC1 (*) + * @arg @ref LL_GPDMA2_REQUEST_LPTIM6_IC2 (*) + * @arg @ref LL_GPDMA2_REQUEST_LPTIM6_UE (*) + * @arg @ref LL_GPDMA2_REQUEST_I3C2_RX (*) + * @arg @ref LL_GPDMA2_REQUEST_I3C2_TX (*) + * @arg @ref LL_GPDMA2_REQUEST_I3C2_TC (*) + * @arg @ref LL_GPDMA2_REQUEST_I3C2_RS (*) + * + * @note (*) Availability depends on devices. + */ +__STATIC_INLINE uint32_t LL_DMA_GetPeriphRequest(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR2, DMA_CTR2_REQSEL)); +} + +/** + * @brief Set hardware trigger. + * @note This API is used for all available DMA channels. + * @rmtoll CTR2 TRIGSEL LL_DMA_SetHWTrigger + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param Trigger This parameter can be one of the following values: + * @arg @ref LL_GPDMA1_TRIGGER_EXTI_LINE0 + * @arg @ref LL_GPDMA1_TRIGGER_EXTI_LINE1 + * @arg @ref LL_GPDMA1_TRIGGER_EXTI_LINE2 + * @arg @ref LL_GPDMA1_TRIGGER_EXTI_LINE3 + * @arg @ref LL_GPDMA1_TRIGGER_EXTI_LINE4 + * @arg @ref LL_GPDMA1_TRIGGER_EXTI_LINE5 + * @arg @ref LL_GPDMA1_TRIGGER_EXTI_LINE6 + * @arg @ref LL_GPDMA1_TRIGGER_EXTI_LINE7 + * @arg @ref LL_GPDMA1_TRIGGER_TAMP_TRG1 + * @arg @ref LL_GPDMA1_TRIGGER_TAMP_TRG2 + * @arg @ref LL_GPDMA1_TRIGGER_TAMP_TRG3 (*) + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM1_CH1 + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM1_CH2 + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM2_CH1 + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM2_CH2 + * @arg @ref LL_GPDMA1_TRIGGER_RTC_ALRA_TRG + * @arg @ref LL_GPDMA1_TRIGGER_RTC_ALRB_TRG + * @arg @ref LL_GPDMA1_TRIGGER_RTC_WUT_TRG + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH0_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH1_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH2_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH3_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH4_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH5_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH6_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH7_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA2_CH0_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA2_CH1_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA2_CH2_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA2_CH3_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA2_CH4_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA2_CH5_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA2_CH6_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA2_CH7_TCF + * @arg @ref LL_GPDMA1_TRIGGER_TIM2_TRGO + * @arg @ref LL_GPDMA1_TRIGGER_TIM15_TRGO + * @arg @ref LL_GPDMA1_TRIGGER_TIM12_TRGO + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM3_CH1 + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM3_CH2 + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM4_AIT + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM5_CH1 + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM5_CH2 + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM6_CH1 + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM6_CH2 + * @arg @ref LL_GPDMA1_TRIGGER_TIM15_TRGO (*) + * @arg @ref LL_GPDMA1_TRIGGER_TIM12_TRGO (*) + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM3_CH1 (*) + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM3_CH2 (*) + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM4_AIT (*) + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM5_CH1 (*) + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM5_CH2 (*) + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM6_CH1 (*) + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM6_CH2 (*) + * @arg @ref LL_GPDMA1_TRIGGER_COMP1_OUT (*) + * @arg @ref LL_GPDMA1_TRIGGER_EVENTOUT (*) + * + * @arg @ref LL_GPDMA2_TRIGGER_EXTI_LINE0 + * @arg @ref LL_GPDMA2_TRIGGER_EXTI_LINE1 + * @arg @ref LL_GPDMA2_TRIGGER_EXTI_LINE2 + * @arg @ref LL_GPDMA2_TRIGGER_EXTI_LINE3 + * @arg @ref LL_GPDMA2_TRIGGER_EXTI_LINE4 + * @arg @ref LL_GPDMA2_TRIGGER_EXTI_LINE5 + * @arg @ref LL_GPDMA2_TRIGGER_EXTI_LINE6 + * @arg @ref LL_GPDMA2_TRIGGER_EXTI_LINE7 + * @arg @ref LL_GPDMA2_TRIGGER_TAMP_TRG1 + * @arg @ref LL_GPDMA2_TRIGGER_TAMP_TRG2 + * @arg @ref LL_GPDMA2_TRIGGER_TAMP_TRG3 (*) + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM1_CH1 + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM1_CH2 + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM2_CH1 + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM2_CH2 + * @arg @ref LL_GPDMA2_TRIGGER_RTC_ALRA_TRG + * @arg @ref LL_GPDMA2_TRIGGER_RTC_ALRB_TRG + * @arg @ref LL_GPDMA2_TRIGGER_RTC_WUT_TRG + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA1_CH0_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA1_CH1_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA1_CH2_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA1_CH3_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA1_CH4_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA1_CH5_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA1_CH6_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA1_CH7_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA2_CH0_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA2_CH1_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA2_CH2_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA2_CH3_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA2_CH4_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA2_CH5_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA2_CH6_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA2_CH7_TCF + * @arg @ref LL_GPDMA2_TRIGGER_TIM2_TRGO + * @arg @ref LL_GPDMA2_TRIGGER_TIM15_TRGO + * @arg @ref LL_GPDMA2_TRIGGER_TIM12_TRGO + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM3_CH1 + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM3_CH2 + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM4_AIT + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM5_CH1 + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM5_CH2 + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM6_CH1 + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM6_CH2 + * @arg @ref LL_GPDMA2_TRIGGER_TIM15_TRGO (*) + * @arg @ref LL_GPDMA2_TRIGGER_TIM12_TRGO (*) + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM3_CH1 (*) + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM3_CH2 (*) + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM4_AIT (*) + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM5_CH1 (*) + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM5_CH2 (*) + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM6_CH1 (*) + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM6_CH2 (*) + * @arg @ref LL_GPDMA2_TRIGGER_COMP1_OUT (*) + * @arg @ref LL_GPDMA2_TRIGGER_EVENTOUT (*) + * + * @note (*) Availability depends on devices. + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetHWTrigger(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t Trigger) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR2, DMA_CTR2_TRIGSEL, + (Trigger << DMA_CTR2_TRIGSEL_Pos) & DMA_CTR2_TRIGSEL); +} + +/** + * @brief Get hardware triggers. + * @note This API is used for all available DMA channels. + * @rmtoll CTR2 TRIGSEL LL_DMA_GetHWTrigger + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_GPDMA1_TRIGGER_EXTI_LINE0 + * @arg @ref LL_GPDMA1_TRIGGER_EXTI_LINE1 + * @arg @ref LL_GPDMA1_TRIGGER_EXTI_LINE2 + * @arg @ref LL_GPDMA1_TRIGGER_EXTI_LINE3 + * @arg @ref LL_GPDMA1_TRIGGER_EXTI_LINE4 + * @arg @ref LL_GPDMA1_TRIGGER_EXTI_LINE5 + * @arg @ref LL_GPDMA1_TRIGGER_EXTI_LINE6 + * @arg @ref LL_GPDMA1_TRIGGER_EXTI_LINE7 + * @arg @ref LL_GPDMA1_TRIGGER_TAMP_TRG1 + * @arg @ref LL_GPDMA1_TRIGGER_TAMP_TRG2 + * @arg @ref LL_GPDMA1_TRIGGER_TAMP_TRG3 (*) + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM1_CH1 + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM1_CH2 + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM2_CH1 + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM2_CH2 + * @arg @ref LL_GPDMA1_TRIGGER_RTC_ALRA_TRG + * @arg @ref LL_GPDMA1_TRIGGER_RTC_ALRB_TRG + * @arg @ref LL_GPDMA1_TRIGGER_RTC_WUT_TRG + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH0_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH1_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH2_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH3_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH4_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH5_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH6_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA1_CH7_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA2_CH0_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA2_CH1_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA2_CH2_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA2_CH3_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA2_CH4_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA2_CH5_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA2_CH6_TCF + * @arg @ref LL_GPDMA1_TRIGGER_GPDMA2_CH7_TCF + * @arg @ref LL_GPDMA1_TRIGGER_TIM2_TRGO + * @arg @ref LL_GPDMA1_TRIGGER_TIM15_TRGO + * @arg @ref LL_GPDMA1_TRIGGER_TIM12_TRGO + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM3_CH1 + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM3_CH2 + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM4_AIT + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM5_CH1 + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM5_CH2 + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM6_CH1 + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM6_CH2 + * @arg @ref LL_GPDMA1_TRIGGER_TIM15_TRGO (*) + * @arg @ref LL_GPDMA1_TRIGGER_TIM12_TRGO (*) + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM3_CH1 (*) + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM3_CH2 (*) + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM4_AIT (*) + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM5_CH1 (*) + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM5_CH2 (*) + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM6_CH1 (*) + * @arg @ref LL_GPDMA1_TRIGGER_LPTIM6_CH2 (*) + * @arg @ref LL_GPDMA1_TRIGGER_COMP1_OUT (*) + * @arg @ref LL_GPDMA1_TRIGGER_EVENTOUT (*) + * + * @arg @ref LL_GPDMA2_TRIGGER_EXTI_LINE0 + * @arg @ref LL_GPDMA2_TRIGGER_EXTI_LINE1 + * @arg @ref LL_GPDMA2_TRIGGER_EXTI_LINE2 + * @arg @ref LL_GPDMA2_TRIGGER_EXTI_LINE3 + * @arg @ref LL_GPDMA2_TRIGGER_EXTI_LINE4 + * @arg @ref LL_GPDMA2_TRIGGER_EXTI_LINE5 + * @arg @ref LL_GPDMA2_TRIGGER_EXTI_LINE6 + * @arg @ref LL_GPDMA2_TRIGGER_EXTI_LINE7 + * @arg @ref LL_GPDMA2_TRIGGER_TAMP_TRG1 + * @arg @ref LL_GPDMA2_TRIGGER_TAMP_TRG2 + * @arg @ref LL_GPDMA2_TRIGGER_TAMP_TRG3 (*) + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM1_CH1 + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM1_CH2 + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM2_CH1 + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM2_CH2 + * @arg @ref LL_GPDMA2_TRIGGER_RTC_ALRA_TRG + * @arg @ref LL_GPDMA2_TRIGGER_RTC_ALRB_TRG + * @arg @ref LL_GPDMA2_TRIGGER_RTC_WUT_TRG + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA1_CH0_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA1_CH1_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA1_CH2_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA1_CH3_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA1_CH4_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA1_CH5_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA1_CH6_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA1_CH7_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA2_CH0_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA2_CH1_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA2_CH2_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA2_CH3_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA2_CH4_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA2_CH5_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA2_CH6_TCF + * @arg @ref LL_GPDMA2_TRIGGER_GPDMA2_CH7_TCF + * @arg @ref LL_GPDMA2_TRIGGER_TIM2_TRGO + * @arg @ref LL_GPDMA2_TRIGGER_TIM15_TRGO + * @arg @ref LL_GPDMA2_TRIGGER_TIM12_TRGO + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM3_CH1 + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM3_CH2 + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM4_AIT + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM5_CH1 + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM5_CH2 + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM6_CH1 + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM6_CH2 + * @arg @ref LL_GPDMA2_TRIGGER_TIM15_TRGO (*) + * @arg @ref LL_GPDMA2_TRIGGER_TIM12_TRGO (*) + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM3_CH1 (*) + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM3_CH2 (*) + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM4_AIT (*) + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM5_CH1 (*) + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM5_CH2 (*) + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM6_CH1 (*) + * @arg @ref LL_GPDMA2_TRIGGER_LPTIM6_CH2 (*) + * @arg @ref LL_GPDMA2_TRIGGER_COMP1_OUT (*) + * @arg @ref LL_GPDMA2_TRIGGER_EVENTOUT (*) + * + * @note (*) Availability depends on devices. + */ +__STATIC_INLINE uint32_t LL_DMA_GetHWTrigger(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR2, + DMA_CTR2_TRIGSEL) >> DMA_CTR2_TRIGSEL_Pos); +} + +/** + * @brief Set DMA transfer mode. + * @note This API is used for all available DMA channels. + * @rmtoll CTR2 PFREQ LL_DMA_SetTransferMode + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_7 + * @param Mode This parameter can be one of the following values: + * @arg @ref LL_DMA_NORMAL + * @arg @ref LL_DMA_PFCTRL + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetTransferMode(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t Mode) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR2, DMA_CTR2_PFREQ, + Mode & DMA_CTR2_PFREQ); +} + +/** + * @brief Get DMA transfer mode. + * @note This API is used for all available DMA channels. + * @rmtoll CTR2 TRIGSEL LL_DMA_GetTransferMode + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_NORMAL + * @arg @ref LL_DMA_PFCTRL + */ +__STATIC_INLINE uint32_t LL_DMA_GetTransferMode(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR2, + DMA_CTR2_PFREQ)); +} + +/** + * @brief Configure addresses update. + * @note This API is used only for 2D addressing channels. + * @rmtoll CBR1 BRDDEC LL_DMA_ConfigBlkRptAddrUpdate\n + * CBR1 BRSDEC LL_DMA_ConfigBlkRptAddrUpdate\n + * CBR1 DDEC LL_DMA_ConfigBlkRptAddrUpdate\n + * CBR1 SDEC LL_DMA_ConfigBlkRptAddrUpdate + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param Configuration This parameter must be a combination of all the following values: + * @arg @ref LL_DMA_BLKRPT_DEST_ADDR_INCREMENT or @ref LL_DMA_BLKRPT_DEST_ADDR_DECREMENT + * @arg @ref LL_DMA_BLKRPT_SRC_ADDR_INCREMENT or @ref LL_DMA_BLKRPT_SRC_ADDR_DECREMENT + * @arg @ref LL_DMA_BURST_DEST_ADDR_INCREMENT or @ref LL_DMA_BURST_DEST_ADDR_DECREMENT + * @arg @ref LL_DMA_BURST_SRC_ADDR_INCREMENT or @ref LL_DMA_BURST_SRC_ADDR_DECREMENT + *@retval None. + */ +__STATIC_INLINE void LL_DMA_ConfigBlkRptAddrUpdate(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t Configuration) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CBR1, + DMA_CBR1_BRDDEC | DMA_CBR1_BRSDEC | DMA_CBR1_DDEC | DMA_CBR1_SDEC, Configuration); +} + +/** + * @brief Configure DMA Block number of data and repeat Count. + * @note This API is used only for 2D addressing channels. + * @rmtoll CBR1 BNDT LL_DMA_ConfigBlkCounters\n + * CBR1 BRC LL_DMA_ConfigBlkCounters + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param BlkDataLength Block transfer length + Value between 0 to 0x0000FFFF + * @param BlkRptCount Block repeat counter + * Value between 0 to 0x00000EFF + *@retval None. + */ +__STATIC_INLINE void LL_DMA_ConfigBlkCounters(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t BlkDataLength, + uint32_t BlkRptCount) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CBR1, + (DMA_CBR1_BNDT | DMA_CBR1_BRC), (BlkDataLength | (BlkRptCount << DMA_CBR1_BRC_Pos))); +} + +/** + * @brief Set block repeat destination address update. + * @note This API is used only for 2D addressing channels. + * @rmtoll CBR1 BRDDEC LL_DMA_SetBlkRptDestAddrUpdate + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param BlkRptDestAddrUpdate This parameter can be one of the following values: + * @arg @ref LL_DMA_BLKRPT_DEST_ADDR_INCREMENT + * @arg @ref LL_DMA_BLKRPT_DEST_ADDR_DECREMENT + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetBlkRptDestAddrUpdate(const DMA_TypeDef *DMAx, uint32_t Channel, + uint32_t BlkRptDestAddrUpdate) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CBR1, DMA_CBR1_BRDDEC, + BlkRptDestAddrUpdate); +} + +/** + * @brief Get block repeat destination address update. + * @note This API is used only for 2D addressing channels. + * @rmtoll CBR1 BRDDEC LL_DMA_GetBlkRptDestAddrUpdate + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_BLKRPT_DEST_ADDR_INCREMENT + * @arg @ref LL_DMA_BLKRPT_DEST_ADDR_DECREMENT + */ +__STATIC_INLINE uint32_t LL_DMA_GetBlkRptDestAddrUpdate(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CBR1, DMA_CBR1_BRDDEC)); +} + +/** + * @brief Set block repeat source address update. + * @note This API is used only for 2D addressing channels. + * @rmtoll CBR1 BRSDEC LL_DMA_SetBlkRptSrcAddrUpdate + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param BlkRptSrcAddrUpdate This parameter can be one of the following values: + * @arg @ref LL_DMA_BLKRPT_SRC_ADDR_INCREMENT + * @arg @ref LL_DMA_BLKRPT_SRC_ADDR_DECREMENT + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetBlkRptSrcAddrUpdate(const DMA_TypeDef *DMAx, uint32_t Channel, + uint32_t BlkRptSrcAddrUpdate) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CBR1, DMA_CBR1_BRSDEC, + BlkRptSrcAddrUpdate); +} + +/** + * @brief Get block repeat source address update. + * @note This API is used only for 2D addressing channels. + * @rmtoll CBR1 BRSDEC LL_DMA_GetBlkRptSrcAddrUpdate + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_BLKRPT_SRC_ADDR_INCREMENT + * @arg @ref LL_DMA_BLKRPT_SRC_ADDR_DECREMENT + */ +__STATIC_INLINE uint32_t LL_DMA_GetBlkRptSrcAddrUpdate(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CBR1, DMA_CBR1_BRSDEC)); +} + +/** + * @brief Set destination address update. + * @note This API is used only for 2D addressing channels. + * @rmtoll CBR1 DDEC LL_DMA_SetDestAddrUpdate + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param DestAddrUpdate This parameter can be one of the following values: + * @arg @ref LL_DMA_BURST_DEST_ADDR_INCREMENT + * @arg @ref LL_DMA_BURST_DEST_ADDR_DECREMENT + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetDestAddrUpdate(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t DestAddrUpdate) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CBR1, DMA_CBR1_DDEC, + DestAddrUpdate); +} + +/** + * @brief Get destination address update. + * @note This API is used only for 2D addressing channels. + * @rmtoll CBR1 DDEC LL_DMA_GetDestAddrUpdate + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_BURST_DEST_ADDR_INCREMENT + * @arg @ref LL_DMA_BURST_DEST_ADDR_DECREMENT + */ +__STATIC_INLINE uint32_t LL_DMA_GetDestAddrUpdate(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CBR1, DMA_CBR1_DDEC)); +} + +/** + * @brief Set source address update. + * @note This API is used only for 2D addressing channels. + * @rmtoll CBR1 SDEC LL_DMA_SetSrcAddrUpdate + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param SrcAddrUpdate This parameter can be one of the following values: + * @arg @ref LL_DMA_BURST_SRC_ADDR_INCREMENT + * @arg @ref LL_DMA_BURST_SRC_ADDR_DECREMENT + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetSrcAddrUpdate(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t SrcAddrUpdate) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CBR1, DMA_CBR1_SDEC, + SrcAddrUpdate); +} + +/** + * @brief Get source address update. + * @note This API is used only for 2D addressing channels. + * @rmtoll CBR1 SDEC LL_DMA_GetSrcAddrUpdate + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_BURST_SRC_ADDR_INCREMENT + * @arg @ref LL_DMA_BURST_SRC_ADDR_DECREMENT + */ +__STATIC_INLINE uint32_t LL_DMA_GetSrcAddrUpdate(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CBR1, DMA_CBR1_SDEC)); +} + +/** + * @brief Set block repeat count. + * @note This API is used only for 2D addressing channels. + * @rmtoll CBR1 BRC LL_DMA_SetBlkRptCount + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param BlkRptCount Block repeat counter + * Value between 0 to 0x00000EFF + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetBlkRptCount(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t BlkRptCount) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CBR1, DMA_CBR1_BRC, + (BlkRptCount << DMA_CBR1_BRC_Pos) & DMA_CBR1_BRC); +} + +/** + * @brief Get block repeat count. + * @note This API is used only for 2D addressing channels. + * @rmtoll CBR1 BRC LL_DMA_GetBlkRptCount + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Between 0 to 0x00000EFF + */ +__STATIC_INLINE uint32_t LL_DMA_GetBlkRptCount(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CBR1, + DMA_CBR1_BRC) >> DMA_CBR1_BRC_Pos); +} + +/** + * @brief Set block data length in bytes to transfer. + * @note This API is used for all available DMA channels. + * @rmtoll CBR1 BNDT LL_DMA_SetBlkDataLength + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param BlkDataLength Between 0 to 0x0000FFFF + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetBlkDataLength(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t BlkDataLength) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CBR1, DMA_CBR1_BNDT, + BlkDataLength); +} + +/** + * @brief Get block data length in bytes to transfer. + * @note This API is used for all available DMA channels. + * @rmtoll CBR1 BNDT LL_DMA_GetBlkDataLength + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Between 0 to 0x0000FFFF + */ +__STATIC_INLINE uint32_t LL_DMA_GetBlkDataLength(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CBR1, DMA_CBR1_BNDT)); +} + +/** + * @brief Configure the source and destination addresses. + * @note This API is used for all available DMA channels. + * @note This API must not be called when the DMA Channel is enabled. + * @rmtoll CSAR SA LL_DMA_ConfigAddresses\n + * CDAR DA LL_DMA_ConfigAddresses + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param SrcAddress Between 0 to 0xFFFFFFFF + * @param DestAddress Between 0 to 0xFFFFFFFF + * @retval None. + */ +__STATIC_INLINE void LL_DMA_ConfigAddresses(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t SrcAddress, uint32_t + DestAddress) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + WRITE_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CSAR, SrcAddress); + WRITE_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CDAR, DestAddress); +} + +/** + * @brief Set source address. + * @note This API is used for all available DMA channels. + * @rmtoll CSAR SA LL_DMA_SetSrcAddress + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param SrcAddress Between 0 to 0xFFFFFFFF + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetSrcAddress(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t SrcAddress) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + WRITE_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CSAR, SrcAddress); +} + +/** + * @brief Get source address. + * @note This API is used for all available DMA channels. + * @rmtoll CSAR SA LL_DMA_GetSrcAddress + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Between 0 to 0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_DMA_GetSrcAddress(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CSAR)); +} + +/** + * @brief Set destination address. + * @note This API is used for all available DMA channels. + * @rmtoll CDAR DA LL_DMA_SetDestAddress + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param DestAddress Between 0 to 0xFFFFFFFF + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetDestAddress(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t DestAddress) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + WRITE_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CDAR, DestAddress); +} + +/** + * @brief Get destination address. + * @note This API is used for all available DMA channels. + * @rmtoll CDAR DA LL_DMA_GetDestAddress + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Between 0 to 0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_DMA_GetDestAddress(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CDAR)); +} + +/** + * @brief Configure source and destination addresses offset. + * @note This API is used only for 2D addressing channels. + * @note This API must not be called when the DMA Channel is enabled. + * @rmtoll CTR3 DAO LL_DMA_ConfigAddrUpdateValue\n + * CTR3 SAO LL_DMA_ConfigAddrUpdateValue + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param DestAddrOffset Between 0 to 0x00001FFF + * @param SrcAddrOffset Between 0 to 0x00001FFF + * @retval None. + */ +__STATIC_INLINE void LL_DMA_ConfigAddrUpdateValue(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t SrcAddrOffset, + uint32_t DestAddrOffset) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + WRITE_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR3, + (SrcAddrOffset & DMA_CTR3_SAO) | ((DestAddrOffset << DMA_CTR3_DAO_Pos) & DMA_CTR3_DAO)); +} + +/** + * @brief Set destination address offset. + * @note This API is used only for 2D addressing channels. + * @rmtoll CTR3 DAO LL_DMA_SetDestAddrUpdateValue + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param DestAddrOffset Between 0 to 0x00001FFF + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetDestAddrUpdateValue(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t DestAddrOffset) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR3, DMA_CTR3_DAO, + ((DestAddrOffset << DMA_CTR3_DAO_Pos) & DMA_CTR3_DAO)); +} + +/** + * @brief Get destination address offset. + * @note This API is used only for 2D addressing channels. + * @rmtoll CDAR DAO LL_DMA_GetDestAddrUpdateValue + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Between 0 to 0x00001FFF + */ +__STATIC_INLINE uint32_t LL_DMA_GetDestAddrUpdateValue(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR3, + DMA_CTR3_DAO) >> DMA_CTR3_DAO_Pos); +} + +/** + * @brief Set source address offset. + * @note This API is used only for 2D addressing channels. + * @rmtoll CTR3 SAO LL_DMA_SetSrcAddrUpdateValue + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param SrcAddrOffset Between 0 to 0x00001FFF + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetSrcAddrUpdateValue(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t SrcAddrOffset) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR3, DMA_CTR3_SAO, + SrcAddrOffset & DMA_CTR3_SAO); +} + +/** + * @brief Get source address offset. + * @note This API is used only for 2D addressing channels. + * @rmtoll CTR3 SAO LL_DMA_GetSrcAddrUpdateValue + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Between 0 to 0x00001FFF + */ +__STATIC_INLINE uint32_t LL_DMA_GetSrcAddrUpdateValue(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CTR3, DMA_CTR3_SAO)); +} + +/** + * @brief Configure the block repeated source and destination addresses offset. + * @note This API is used only for 2D addressing channels. + * @note This API must not be called when the DMA Channel is enabled. + * @rmtoll CBR2 BRDAO LL_DMA_ConfigBlkRptAddrUpdateValue\n + * CBR2 BRSAO LL_DMA_ConfigBlkRptAddrUpdateValue + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param BlkRptDestAddrOffset Between 0 to 0x0000FFFF + * @param BlkRptSrcAddrOffset Between 0 to 0x0000FFFF + * @retval None. + */ +__STATIC_INLINE void LL_DMA_ConfigBlkRptAddrUpdateValue(const DMA_TypeDef *DMAx, uint32_t Channel, + uint32_t BlkRptSrcAddrOffset, uint32_t BlkRptDestAddrOffset) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + WRITE_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CBR2, + ((BlkRptDestAddrOffset << DMA_CBR2_BRDAO_Pos) & DMA_CBR2_BRDAO) | (BlkRptSrcAddrOffset & DMA_CBR2_BRSAO)); +} + +/** + * @brief Set block repeated destination address offset. + * @note This API is used only for 2D addressing channels. + * @rmtoll CBR2 BRDAO LL_DMA_SetBlkRptDestAddrUpdateValue + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param BlkRptDestAddrOffset Between 0 to 0x0000FFFF + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetBlkRptDestAddrUpdateValue(const DMA_TypeDef *DMAx, uint32_t Channel, + uint32_t BlkRptDestAddrOffset) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CBR2, DMA_CBR2_BRDAO, + ((BlkRptDestAddrOffset << DMA_CBR2_BRDAO_Pos) & DMA_CBR2_BRDAO)); +} + +/** + * @brief Get block repeated destination address offset. + * @note This API is used only for 2D addressing channels. + * @rmtoll CBR2 BRDAO LL_DMA_GetBlkRptDestAddrUpdateValue + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Between 0 to 0x0000FFFF. + */ +__STATIC_INLINE uint32_t LL_DMA_GetBlkRptDestAddrUpdateValue(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CBR2, + DMA_CBR2_BRDAO) >> DMA_CBR2_BRDAO_Pos); +} + +/** + * @brief Set block repeated source address offset. + * @note This API is used only for 2D addressing channels. + * @rmtoll CBR2 BRSAO LL_DMA_SetBlkRptSrcAddrUpdateValue + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param BlkRptSrcAddrOffset Between 0 to 0x0000FFFF + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetBlkRptSrcAddrUpdateValue(const DMA_TypeDef *DMAx, uint32_t Channel, + uint32_t BlkRptSrcAddrOffset) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CBR2, DMA_CBR2_BRSAO, + BlkRptSrcAddrOffset); +} + +/** + * @brief Get block repeated source address offset. + * @note This API is used only for 2D addressing channels. + * @rmtoll CBR2 BRSAO LL_DMA_GetBlkRptSrcAddrUpdateValue + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Between 0 to 0x0000FFFF + */ +__STATIC_INLINE uint32_t LL_DMA_GetBlkRptSrcAddrUpdateValue(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CBR2, DMA_CBR2_BRSAO)); +} + +/** + * @brief Configure registers update and node address offset during the link transfer. + * @note This API is used for all available DMA channels. + * For linear addressing channels, UT3 and UB2 fields are discarded. + * @rmtoll CLLR UT1 LL_DMA_ConfigLinkUpdate\n + * @rmtoll CLLR UT2 LL_DMA_ConfigLinkUpdate\n + * @rmtoll CLLR UB1 LL_DMA_ConfigLinkUpdate\n + * @rmtoll CLLR USA LL_DMA_ConfigLinkUpdate\n + * @rmtoll CLLR UDA LL_DMA_ConfigLinkUpdate\n + * @rmtoll CLLR UT3 LL_DMA_ConfigLinkUpdate\n + * @rmtoll CLLR UB2 LL_DMA_ConfigLinkUpdate\n + * @rmtoll CLLR ULL LL_DMA_ConfigLinkUpdate + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param RegistersUpdate This parameter must be a combination of all the following values: + * @arg @ref LL_DMA_UPDATE_CTR1 + * @arg @ref LL_DMA_UPDATE_CTR2 + * @arg @ref LL_DMA_UPDATE_CBR1 + * @arg @ref LL_DMA_UPDATE_CSAR + * @arg @ref LL_DMA_UPDATE_CDAR + * @arg @ref LL_DMA_UPDATE_CTR3 (This value is allowed only for 2D addressing channels) + * @arg @ref LL_DMA_UPDATE_CBR2 (This value is allowed only for 2D addressing channels) + * @arg @ref LL_DMA_UPDATE_CLLR + * @param LinkedListAddrOffset Between 0 to 0x0000FFFC + * @retval None. + */ +__STATIC_INLINE void LL_DMA_ConfigLinkUpdate(const DMA_TypeDef *DMAx, uint32_t Channel, uint32_t RegistersUpdate, + uint32_t LinkedListAddrOffset) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLLR, + (DMA_CLLR_UT1 | DMA_CLLR_UT2 | DMA_CLLR_UB1 | DMA_CLLR_USA | DMA_CLLR_UDA | DMA_CLLR_UT3 | \ + DMA_CLLR_UB2 | DMA_CLLR_ULL | DMA_CLLR_LA), (RegistersUpdate | (LinkedListAddrOffset & DMA_CLLR_LA))); +} + +/** + * @brief Enable CTR1 update during the link transfer. + * @note This API is used for all available DMA channels. + * @rmtoll CLLR UT1 LL_DMA_EnableCTR1Update + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_EnableCTR1Update(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + SET_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLLR, DMA_CLLR_UT1); +} + +/** + * @brief Disable CTR1 update during the link transfer. + * @note This API is used for all available DMA channels. + * @rmtoll CLLR UT1 LL_DMA_DisableCTR1Update + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_DisableCTR1Update(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + CLEAR_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLLR, DMA_CLLR_UT1); +} + +/** + * @brief Check if CTR1 update during the link transfer is enabled. + * @note This API is used for all available DMA channels. + * @rmtoll CLLR UT1 LL_DMA_IsEnabledCTR1Update + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsEnabledCTR1Update(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLLR, DMA_CLLR_UT1) + == (DMA_CLLR_UT1)) ? 1UL : 0UL); +} + +/** + * @brief Enable CTR2 update during the link transfer. + * @note This API is used for all available DMA channels. + * @rmtoll CLLR UT2 LL_DMA_EnableCTR2Update + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_EnableCTR2Update(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + SET_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLLR, DMA_CLLR_UT2); +} + +/** + * @brief Disable CTR2 update during the link transfer. + * @note This API is used for all available DMA channels. + * @rmtoll CLLR UT2 LL_DMA_DisableCTR2Update + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_DisableCTR2Update(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + CLEAR_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLLR, DMA_CLLR_UT2); +} + +/** + * @brief Check if CTR2 update during the link transfer is enabled. + * @note This API is used for all available DMA channels. + * @rmtoll CLLR UT2 LL_DMA_IsEnabledCTR2Update + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsEnabledCTR2Update(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLLR, DMA_CLLR_UT2) + == (DMA_CLLR_UT2)) ? 1UL : 0UL); +} + +/** + * @brief Enable CBR1 update during the link transfer. + * @note This API is used for all available DMA channels. + * @rmtoll CLLR UB1 LL_DMA_EnableCBR1Update + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_EnableCBR1Update(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + SET_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLLR, DMA_CLLR_UB1); +} + +/** + * @brief Disable CBR1 update during the link transfer. + * @note This API is used for all available DMA channels. + * @rmtoll CLLR UB1 LL_DMA_DisableCBR1Update + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_DisableCBR1Update(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + CLEAR_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLLR, DMA_CLLR_UB1); +} + +/** + * @brief Check if CBR1 update during the link transfer is enabled. + * @note This API is used for all available DMA channels. + * @rmtoll CLLR UB1 LL_DMA_IsEnabledCBR1Update + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsEnabledCBR1Update(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLLR, DMA_CLLR_UB1) + == (DMA_CLLR_UB1)) ? 1UL : 0UL); +} + +/** + * @brief Enable CSAR update during the link transfer. + * @note This API is used for all available DMA channels. + * @rmtoll CLLR USA LL_DMA_EnableCSARUpdate + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_EnableCSARUpdate(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + SET_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLLR, DMA_CLLR_USA); +} + +/** + * @brief Disable CSAR update during the link transfer. + * @note This API is used for all available DMA channels. + * @rmtoll CLLR USA LL_DMA_DisableCSARUpdate + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_DisableCSARUpdate(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + CLEAR_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLLR, DMA_CLLR_USA); +} + +/** + * @brief Check if CSAR update during the link transfer is enabled. + * @note This API is used for all available DMA channels. + * @rmtoll CLLR USA LL_DMA_IsEnabledCSARUpdate + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsEnabledCSARUpdate(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLLR, DMA_CLLR_USA) + == (DMA_CLLR_USA)) ? 1UL : 0UL); +} + +/** + * @brief Enable CDAR update during the link transfer. + * @note This API is used for all available DMA channels. + * @rmtoll CLLR UDA LL_DMA_EnableCDARUpdate + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_EnableCDARUpdate(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + SET_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLLR, DMA_CLLR_UDA); +} + +/** + * @brief Disable CDAR update during the link transfer. + * @note This API is used for all available DMA channels. + * @rmtoll CLLR UDA LL_DMA_DisableCDARUpdate + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_DisableCDARUpdate(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + CLEAR_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLLR, DMA_CLLR_UDA); +} + +/** + * @brief Check if CDAR update during the link transfer is enabled. + * @note This API is used for all available DMA channels. + * @rmtoll CLLR UDA LL_DMA_IsEnabledCDARUpdate + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsEnabledCDARUpdate(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLLR, DMA_CLLR_UDA) + == (DMA_CLLR_UDA)) ? 1UL : 0UL); +} + +/** + * @brief Enable CTR3 update during the link transfer. + * @note This API is used only for 2D addressing channels. + * @rmtoll CLLR UT3 LL_DMA_EnableCTR3Update + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_EnableCTR3Update(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + SET_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLLR, DMA_CLLR_UT3); +} + +/** + * @brief Disable CTR3 update during the link transfer. + * @note This API is used only for 2D addressing channels. + * @rmtoll CLLR UT3 LL_DMA_DisableCTR3Update + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_DisableCTR3Update(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + CLEAR_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLLR, DMA_CLLR_UT3); +} + +/** + * @brief Check if CTR3 update during the link transfer is enabled. + * @note This API is used only for 2D addressing channels. + * @rmtoll CLLR UT3 LL_DMA_IsEnabledCTR3Update + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsEnabledCTR3Update(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLLR, DMA_CLLR_UT3) + == (DMA_CLLR_UT3)) ? 1UL : 0UL); +} + +/** + * @brief Enable CBR2 update during the link transfer. + * @note This API is used only for 2D addressing channels. + * @rmtoll CLLR UB2 LL_DMA_EnableCBR2Update + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_EnableCBR2Update(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + SET_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLLR, DMA_CLLR_UB2); +} + +/** + * @brief Disable CBR2 update during the link transfer. + * @note This API is used only for 2D addressing channels. + * @rmtoll CLLR UB2 LL_DMA_DisableCBR2Update + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_DisableCBR2Update(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + CLEAR_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLLR, DMA_CLLR_UB2); +} + +/** + * @brief Check if CBR2 update during the link transfer is enabled. + * @note This API is used only for 2D addressing channels. + * @rmtoll CLLR UB2 LL_DMA_IsEnabledCBR2Update + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsEnabledCBR2Update(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLLR, DMA_CLLR_UB2) + == (DMA_CLLR_UB2)) ? 1UL : 0UL); +} + +/** + * @brief Enable CLLR update during the link transfer. + * @note This API is used for all available DMA channels. + * @rmtoll CLLR ULL LL_DMA_EnableCLLRUpdate + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_EnableCLLRUpdate(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + SET_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLLR, DMA_CLLR_ULL); +} + +/** + * @brief Disable CLLR update during the link transfer. + * @note This API is used for all available DMA channels. + * @rmtoll CLLR ULL LL_DMA_DisableCLLRUpdate + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_DisableCLLRUpdate(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + CLEAR_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLLR, DMA_CLLR_ULL); +} + +/** + * @brief Check if CLLR update during the link transfer is enabled. + * @note This API is used for all available DMA channels. + * @rmtoll CLLR ULL LL_DMA_IsEnabledCLLRUpdate + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsEnabledCLLRUpdate(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLLR, DMA_CLLR_ULL) + == (DMA_CLLR_ULL)) ? 1UL : 0UL); +} + +/** + * @brief Set linked list address offset. + * @note This API is used for all available DMA channels. + * @rmtoll CLLR LA LL_DMA_SetLinkedListAddrOffset + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param LinkedListAddrOffset Between 0 to 0x0000FFFC + * @retval None. + */ +__STATIC_INLINE void LL_DMA_SetLinkedListAddrOffset(const DMA_TypeDef *DMAx, uint32_t Channel, + uint32_t LinkedListAddrOffset) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + MODIFY_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLLR, DMA_CLLR_LA, + (LinkedListAddrOffset & DMA_CLLR_LA)); +} + +/** + * @brief Get linked list address offset. + * @note This API is used for all available DMA channels. + * @rmtoll CLLR LA LL_DMA_GetLinkedListAddrOffset + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Between 0 to 0x0000FFFC. + */ +__STATIC_INLINE uint32_t LL_DMA_GetLinkedListAddrOffset(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CLLR, + DMA_CLLR_LA) >> DMA_CLLR_LA_Pos); +} + +/** + * @brief Get FIFO level. + * @rmtoll CSR FIFOL LL_DMA_GetFIFOLevel + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Between 0 to 0x000000FF. + */ +__STATIC_INLINE uint32_t LL_DMA_GetFIFOLevel(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return (READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CSR, + DMA_CSR_FIFOL) >> DMA_CSR_FIFOL_Pos); +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Enable the DMA channel secure attribute. + * @note This API is used for all available DMA channels. + * @rmtoll SECCFGR SECx LL_DMA_EnableChannelSecure + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_EnableChannelSecure(DMA_TypeDef *DMAx, uint32_t Channel) +{ + SET_BIT(DMAx->SECCFGR, (DMA_SECCFGR_SEC0 << (Channel & 0x0000000FU))); +} + +/** + * @brief Disable the DMA channel secure attribute. + * @note This API is used for all available DMA channels. + * @rmtoll SECCFGR SECx LL_DMA_DisableChannelSecure + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_DisableChannelSecure(DMA_TypeDef *DMAx, uint32_t Channel) +{ + CLEAR_BIT(DMAx->SECCFGR, (DMA_SECCFGR_SEC0 << (Channel & 0x0000000FU))); +} + +/** + * @brief Check if DMA channel secure is enabled. + * @note This API is used for all available DMA channels. + * @rmtoll SECCFGR SECx LL_DMA_IsEnabledChannelSecure + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsEnabledChannelSecure(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + return ((READ_BIT(DMAx->SECCFGR, (DMA_SECCFGR_SEC0 << (Channel & 0x0000000FU))) + == (DMA_SECCFGR_SEC0 << (Channel & 0x0000000FU))) ? 1UL : 0UL); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/** + * @brief Enable the DMA channel privilege attribute. + * @note This API is used for all available DMA channels. + * @rmtoll PRIVCFGR PRIVx LL_DMA_EnableChannelPrivilege + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_EnableChannelPrivilege(DMA_TypeDef *DMAx, uint32_t Channel) +{ + SET_BIT(DMAx->PRIVCFGR, (DMA_PRIVCFGR_PRIV0 << (Channel & 0x0000000FU))); +} + +/** + * @brief Disable the DMA channel privilege attribute. + * @note This API is used for all available DMA channels. + * @rmtoll PRIVCFGR PRIVx LL_DMA_DisableChannelPrivilege + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_DisableChannelPrivilege(DMA_TypeDef *DMAx, uint32_t Channel) +{ + CLEAR_BIT(DMAx->PRIVCFGR, (DMA_PRIVCFGR_PRIV0 << (Channel & 0x0000000FU))); +} + +/** + * @brief Check if DMA Channel privilege is enabled. + * @note This API is used for all available DMA channels. + * @rmtoll PRIVCFGR PRIVx LL_DMA_IsEnabledChannelPrivilege + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsEnabledChannelPrivilege(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + return ((READ_BIT(DMAx->PRIVCFGR, (DMA_PRIVCFGR_PRIV0 << (Channel & 0x0000000FU))) + == (DMA_PRIVCFGR_PRIV0 << (Channel & 0x0000000FU))) ? 1UL : 0UL); +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Enable the DMA channel lock attributes. + * @note This API is used for all available DMA channels. + * @rmtoll RCFGLOCKR LOCKx LL_DMA_EnableChannelLockAttribute + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_EnableChannelLockAttribute(DMA_TypeDef *DMAx, uint32_t Channel) +{ + SET_BIT(DMAx->RCFGLOCKR, (DMA_RCFGLOCKR_LOCK0 << (Channel & 0x0000000FU))); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#if defined (DMA_RCFGLOCKR_LOCK0) +/** + * @brief Check if DMA channel attributes are locked. + * @note This API is used for all available DMA channels. + * @rmtoll SECCFGR LOCKx LL_DMA_IsEnabledChannelLockAttribute + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsEnabledChannelLockAttribute(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + return ((READ_BIT(DMAx->RCFGLOCKR, (DMA_RCFGLOCKR_LOCK0 << (Channel & 0x0000000FU))) + == (DMA_RCFGLOCKR_LOCK0 << (Channel & 0x0000000FU))) ? 1UL : 0UL); +} + +#endif /* defined (DMA_RCFGLOCKR_LOCK0) */ +/** + * @} + */ + +/** @defgroup DMA_LL_EF_FLAG_Management Flag Management + * @{ + */ + +/** + * @brief Clear trigger overrun flag. + * @note This API is used for all available DMA channels. + * @rmtoll CFCR TOF LL_DMA_ClearFlag_TO + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_ClearFlag_TO(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + WRITE_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CFCR, DMA_CFCR_TOF); +} + +/** + * @brief Clear suspension flag. + * @note This API is used for all available DMA channels. + * @rmtoll CFCR SUSPF LL_DMA_ClearFlag_SUSP + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_ClearFlag_SUSP(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + WRITE_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CFCR, DMA_CFCR_SUSPF); +} + +/** + * @brief Clear user setting error flag. + * @note This API is used for all available DMA channels. + * @rmtoll CFCR USEF LL_DMA_ClearFlag_USE + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_ClearFlag_USE(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + WRITE_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CFCR, DMA_CFCR_USEF); +} + +/** + * @brief Clear link transfer error flag. + * @note This API is used for all available DMA channels. + * @rmtoll CFCR ULEF LL_DMA_ClearFlag_ULE + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_ClearFlag_ULE(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + WRITE_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CFCR, DMA_CFCR_ULEF); +} + +/** + * @brief Clear data transfer error flag. + * @note This API is used for all available DMA channels. + * @rmtoll CFCR DTEF LL_DMA_ClearFlag_DTE + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_ClearFlag_DTE(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + WRITE_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CFCR, DMA_CFCR_DTEF); +} + +/** + * @brief Clear half transfer flag. + * @note This API is used for all available DMA channels. + * @rmtoll CFCR HTF LL_DMA_ClearFlag_HT + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_ClearFlag_HT(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + WRITE_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CFCR, DMA_CFCR_HTF); +} + +/** + * @brief Clear transfer complete flag. + * @note This API is used for all available DMA channels. + * @rmtoll CFCR TCF LL_DMA_ClearFlag_TC + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_ClearFlag_TC(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + WRITE_REG(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CFCR, DMA_CFCR_TCF); +} + +/** + * @brief Get trigger overrun flag. + * @note This API is used for all available DMA channels. + * @rmtoll CSR TOF LL_DMA_IsActiveFlag_TO + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TO(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CSR, DMA_CSR_TOF) + == (DMA_CSR_TOF)) ? 1UL : 0UL); +} + +/** + * @brief Get suspension flag. + * @note This API is used for all available DMA channels. + * @rmtoll CSR SUSPF LL_DMA_IsActiveFlag_SUSP + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_SUSP(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CSR, DMA_CSR_SUSPF) + == (DMA_CSR_SUSPF)) ? 1UL : 0UL); +} + +/** + * @brief Get user setting error flag. + * @note This API is used for all available DMA channels. + * @rmtoll CSR USEF LL_DMA_IsActiveFlag_USE + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_USE(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CSR, DMA_CSR_USEF) + == (DMA_CSR_USEF)) ? 1UL : 0UL); +} + +/** + * @brief Get user setting error flag. + * @note This API is used for all available DMA channels. + * @rmtoll CSR ULEF LL_DMA_IsActiveFlag_ULE + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_ULE(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CSR, DMA_CSR_ULEF) + == (DMA_CSR_ULEF)) ? 1UL : 0UL); +} + +/** + * @brief Get data transfer error flag. + * @note This API is used for all available DMA channels. + * @rmtoll CSR DTEF LL_DMA_IsActiveFlag_DTE + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_DTE(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CSR, DMA_CSR_DTEF) + == (DMA_CSR_DTEF)) ? 1UL : 0UL); +} + +/** + * @brief Get half transfer flag. + * @note This API is used for all available DMA channels. + * @rmtoll CSR HTF LL_DMA_IsActiveFlag_HT + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_HT(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CSR, DMA_CSR_HTF) + == (DMA_CSR_HTF)) ? 1UL : 0UL); +} + +/** + * @brief Get transfer complete flag. + * @note This API is used for all available DMA channels. + * @rmtoll CSR TCF LL_DMA_IsActiveFlag_TC + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TC(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CSR, DMA_CSR_TCF) + == (DMA_CSR_TCF)) ? 1UL : 0UL); +} + +/** + * @brief Get idle flag. + * @note This API is used for all available DMA channels. + * @rmtoll CSR IDLEF LL_DMA_IsActiveFlag_IDLE + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_IDLE(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CSR, DMA_CSR_IDLEF) + == (DMA_CSR_IDLEF)) ? 1UL : 0UL); +} + +/** + * @brief Check if nsecure masked interrupt is active. + * @note This API is used for all available DMA channels. + * @rmtoll MISR MISx LL_DMA_IsActiveFlag_MIS + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_MIS(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + return ((READ_BIT(DMAx->MISR, (DMA_MISR_MIS0 << (Channel & 0x0FU))) + == (DMA_MISR_MIS0 << (Channel & 0x0FU))) ? 1UL : 0UL); +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Check if secure masked interrupt is active. + * @note This API is used for all available DMA channels. + * @rmtoll SMISR MISx LL_DMA_IsActiveFlag_SMIS + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_SMIS(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + return ((READ_BIT(DMAx->SMISR, (DMA_SMISR_MIS0 << (Channel & 0x0000000FU))) + == (DMA_SMISR_MIS0 << (Channel & 0x0000000FU))) ? 1UL : 0UL); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/** + * @} + */ + +/** @defgroup DMA_LL_EF_IT_Management Interrupt Management + * @{ + */ + +/** + * @brief Enable trigger overrun interrupt. + * @note This API is used for all available DMA channels. + * @rmtoll CCR TOIE LL_DMA_EnableIT_TO + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_EnableIT_TO(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + SET_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_TOIE); +} + +/** + * @brief Enable suspension interrupt. + * @note This API is used for all available DMA channels. + * @rmtoll CCR SUSPIE LL_DMA_EnableIT_SUSP + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_EnableIT_SUSP(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + SET_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_SUSPIE); +} + +/** + * @brief Enable user setting error interrupt. + * @note This API is used for all available DMA channels. + * @rmtoll CCR USEIE LL_DMA_EnableIT_USE + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_EnableIT_USE(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + SET_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_USEIE); +} + +/** + * @brief Enable update link transfer error interrupt. + * @note This API is used for all available DMA channels. + * @rmtoll CCR ULEIE LL_DMA_EnableIT_ULE + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_EnableIT_ULE(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + SET_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_ULEIE); +} + +/** + * @brief Enable data transfer error interrupt. + * @note This API is used for all available DMA channels. + * @rmtoll CCR DTEIE LL_DMA_EnableIT_DTE + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_EnableIT_DTE(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + SET_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_DTEIE); +} + +/** + * @brief Enable half transfer complete interrupt. + * @note This API is used for all available DMA channels. + * @rmtoll CCR HTIE LL_DMA_EnableIT_HT + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_EnableIT_HT(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + SET_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_HTIE); +} + +/** + * @brief Enable transfer complete interrupt. + * @note This API is used for all available DMA channels. + * @rmtoll CCR TCIE LL_DMA_EnableIT_TC + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_EnableIT_TC(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + SET_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_TCIE); +} + +/** + * @brief Disable trigger overrun interrupt. + * @note This API is used for all available DMA channels. + * @rmtoll CCR TOIE LL_DMA_DisableIT_TO + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_DisableIT_TO(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + CLEAR_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_TOIE); +} + +/** + * @brief Disable suspension interrupt. + * @note This API is used for all available DMA channels. + * @rmtoll CCR SUSPIE LL_DMA_DisableIT_SUSP + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_DisableIT_SUSP(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + CLEAR_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_SUSPIE); +} + +/** + * @brief Disable user setting error interrupt. + * @note This API is used for all available DMA channels. + * @rmtoll CCR USEIE LL_DMA_DisableIT_USE + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_DisableIT_USE(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + CLEAR_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_USEIE); +} + +/** + * @brief Disable update link transfer error interrupt. + * @note This API is used for all available DMA channels. + * @rmtoll CCR ULEIE LL_DMA_DisableIT_ULE + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_DisableIT_ULE(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + CLEAR_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_ULEIE); +} + +/** + * @brief Disable data transfer error interrupt. + * @note This API is used for all available DMA channels. + * @rmtoll CCR DTEIE LL_DMA_DisableIT_DTE + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_DisableIT_DTE(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + CLEAR_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_DTEIE); +} + +/** + * @brief Disable half transfer complete interrupt. + * @note This API is used for all available DMA channels. + * @rmtoll CCR HTIE LL_DMA_DisableIT_HT + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_DisableIT_HT(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + CLEAR_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_HTIE); +} + +/** + * @brief Disable transfer complete interrupt. + * @note This API is used for all available DMA channels. + * @rmtoll CCR TCIE LL_DMA_DisableIT_TC + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None. + */ +__STATIC_INLINE void LL_DMA_DisableIT_TC(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + CLEAR_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_TCIE); +} + +/** + * @brief Check if trigger overrun interrupt is enabled. + * @note This API is used for all available DMA channels. + * @rmtoll CCR TOIE LL_DMA_IsEnabledIT_TO + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsEnabledIT_TO(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_TOIE) + == DMA_CCR_TOIE) ? 1UL : 0UL); +} + +/** + * @brief Check if suspension interrupt is enabled. + * @note This API is used for all available DMA channels. + * @rmtoll CCR SUSPIE LL_DMA_IsEnabledIT_SUSP + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsEnabledIT_SUSP(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_SUSPIE) + == DMA_CCR_SUSPIE) ? 1UL : 0UL); +} + +/** + * @brief Check if user setting error interrupt is enabled. + * @note This API is used for all available DMA channels. + * @rmtoll CCR USEIE LL_DMA_IsEnabledIT_USE + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsEnabledIT_USE(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_USEIE) + == DMA_CCR_USEIE) ? 1UL : 0UL); +} + +/** + * @brief Check if update link transfer error interrupt is enabled. + * @note This API is used for all available DMA channels. + * @rmtoll CCR ULEIE LL_DMA_IsEnabledIT_ULE + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsEnabledIT_ULE(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_ULEIE) + == DMA_CCR_ULEIE) ? 1UL : 0UL); +} + +/** + * @brief Check if data transfer error interrupt is enabled. + * @note This API is used for all available DMA channels. + * @rmtoll CCR DTEIE LL_DMA_IsEnabledIT_DTE + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsEnabledIT_DTE(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_DTEIE) + == DMA_CCR_DTEIE) ? 1UL : 0UL); +} + +/** + * @brief Check if half transfer complete interrupt is enabled. + * @note This API is used for all available DMA channels. + * @rmtoll CCR HTIE LL_DMA_IsEnabledIT_HT + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsEnabledIT_HT(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_HTIE) + == DMA_CCR_HTIE) ? 1UL : 0UL); +} + +/** + * @brief Check if transfer complete interrupt is enabled. + * @note This API is used for all available DMA channels. + * @rmtoll CCR TCIE LL_DMA_IsEnabledIT_TC + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DMA_IsEnabledIT_TC(const DMA_TypeDef *DMAx, uint32_t Channel) +{ + uint32_t dma_base_addr = (uint32_t)DMAx; + return ((READ_BIT(((DMA_Channel_TypeDef *)(dma_base_addr + LL_DMA_CH_OFFSET_TAB[Channel]))->CCR, DMA_CCR_TCIE) + == DMA_CCR_TCIE) ? 1UL : 0UL); +} +/** + * @} + */ + +#if defined (USE_FULL_LL_DRIVER) +/** @defgroup DMA_LL_EF_Init Initialization and de-initialization functions + * @{ + */ +uint32_t LL_DMA_Init(DMA_TypeDef *DMAx, uint32_t Channel, LL_DMA_InitTypeDef *DMA_InitStruct); +uint32_t LL_DMA_DeInit(DMA_TypeDef *DMAx, uint32_t Channel); + +void LL_DMA_StructInit(LL_DMA_InitTypeDef *DMA_InitStruct); +void LL_DMA_ListStructInit(LL_DMA_InitLinkedListTypeDef *DMA_InitLinkedListStruct); +void LL_DMA_NodeStructInit(LL_DMA_InitNodeTypeDef *DMA_InitNodeStruct); + +uint32_t LL_DMA_List_Init(DMA_TypeDef *DMAx, uint32_t Channel, + LL_DMA_InitLinkedListTypeDef *DMA_InitLinkedListStruct); +uint32_t LL_DMA_List_DeInit(DMA_TypeDef *DMAx, uint32_t Channel); + +uint32_t LL_DMA_CreateLinkNode(LL_DMA_InitNodeTypeDef *DMA_InitNodeStruct, LL_DMA_LinkNodeTypeDef *pNode); +void LL_DMA_ConnectLinkNode(LL_DMA_LinkNodeTypeDef *pPrevLinkNode, uint32_t PrevNodeCLLRIdx, + LL_DMA_LinkNodeTypeDef *pNewLinkNode, uint32_t NewNodeCLLRIdx); +void LL_DMA_DisconnectNextLinkNode(LL_DMA_LinkNodeTypeDef *pLinkNode, uint32_t LinkNodeCLLRIdx); +/** + * @} + */ +#endif /* defined (USE_FULL_LL_DRIVER) */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined (GPDMA1) */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* STM32H5xx_LL_DMA_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_exti.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_exti.h new file mode 100644 index 0000000000..5ac480d5d3 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_exti.h @@ -0,0 +1,2181 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_exti.h + * @author MCD Application Team + * @brief Header file of EXTI LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_LL_EXTI_H +#define STM32H5xx_LL_EXTI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (EXTI) + +/** @defgroup EXTI_LL EXTI + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +#define LL_EXTI_REGISTER_PINPOS_SHFT 16U /*!< Define used to shift pin position in EXTICR register */ + +/* Private Macros ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup EXTI_LL_Private_Macros EXTI Private Macros + * @{ + */ +/** + * @} + */ +#endif /*USE_FULL_LL_DRIVER*/ +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup EXTI_LL_ES_INIT EXTI Exported Init structure + * @{ + */ +typedef struct +{ + + uint32_t Line_0_31; /*!< Specifies the EXTI lines to be enabled or disabled for Lines in range 0 to 31 + This parameter can be any combination of @ref EXTI_LL_EC_LINE */ + + uint32_t Line_32_63; /*!< Specifies the EXTI lines to be enabled or disabled for Lines in range 32 to 63 + This parameter can be any combination of @ref EXTI_LL_EC_LINE */ + + FunctionalState LineCommand; /*!< Specifies the new state of the selected EXTI lines. + This parameter can be set either to ENABLE or DISABLE */ + + uint8_t Mode; /*!< Specifies the mode for the EXTI lines. + This parameter can be a value of @ref EXTI_LL_EC_MODE. */ + + uint8_t Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines. + This parameter can be a value of @ref EXTI_LL_EC_TRIGGER. */ +} LL_EXTI_InitTypeDef; + +/** + * @} + */ +#endif /*USE_FULL_LL_DRIVER*/ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup EXTI_LL_Exported_Constants EXTI Exported Constants + * @{ + */ + +/** @defgroup EXTI_LL_EC_LINE LINE + * @{ + */ +#define LL_EXTI_LINE_0 EXTI_IMR1_IM0 /*!< Extended line 0 */ +#define LL_EXTI_LINE_1 EXTI_IMR1_IM1 /*!< Extended line 1 */ +#define LL_EXTI_LINE_2 EXTI_IMR1_IM2 /*!< Extended line 2 */ +#define LL_EXTI_LINE_3 EXTI_IMR1_IM3 /*!< Extended line 3 */ +#define LL_EXTI_LINE_4 EXTI_IMR1_IM4 /*!< Extended line 4 */ +#define LL_EXTI_LINE_5 EXTI_IMR1_IM5 /*!< Extended line 5 */ +#define LL_EXTI_LINE_6 EXTI_IMR1_IM6 /*!< Extended line 6 */ +#define LL_EXTI_LINE_7 EXTI_IMR1_IM7 /*!< Extended line 7 */ +#define LL_EXTI_LINE_8 EXTI_IMR1_IM8 /*!< Extended line 8 */ +#define LL_EXTI_LINE_9 EXTI_IMR1_IM9 /*!< Extended line 9 */ +#define LL_EXTI_LINE_10 EXTI_IMR1_IM10 /*!< Extended line 10 */ +#define LL_EXTI_LINE_11 EXTI_IMR1_IM11 /*!< Extended line 11 */ +#define LL_EXTI_LINE_12 EXTI_IMR1_IM12 /*!< Extended line 12 */ +#define LL_EXTI_LINE_13 EXTI_IMR1_IM13 /*!< Extended line 13 */ +#define LL_EXTI_LINE_14 EXTI_IMR1_IM14 /*!< Extended line 14 */ +#define LL_EXTI_LINE_15 EXTI_IMR1_IM15 /*!< Extended line 15 */ +#define LL_EXTI_LINE_16 EXTI_IMR1_IM16 /*!< Extended line 16 */ +#define LL_EXTI_LINE_17 EXTI_IMR1_IM17 /*!< Extended line 17 */ +#define LL_EXTI_LINE_18 EXTI_IMR1_IM18 /*!< Extended line 18 */ +#define LL_EXTI_LINE_19 EXTI_IMR1_IM19 /*!< Extended line 19 */ +#define LL_EXTI_LINE_20 EXTI_IMR1_IM20 /*!< Extended line 20 */ +#define LL_EXTI_LINE_21 EXTI_IMR1_IM21 /*!< Extended line 21 */ +#define LL_EXTI_LINE_22 EXTI_IMR1_IM22 /*!< Extended line 22 */ +#define LL_EXTI_LINE_23 EXTI_IMR1_IM23 /*!< Extended line 23 */ +#define LL_EXTI_LINE_24 EXTI_IMR1_IM24 /*!< Extended line 24 */ +#define LL_EXTI_LINE_25 EXTI_IMR1_IM25 /*!< Extended line 25 */ +#define LL_EXTI_LINE_26 EXTI_IMR1_IM26 /*!< Extended line 26 */ +#define LL_EXTI_LINE_27 EXTI_IMR1_IM27 /*!< Extended line 27 */ +#define LL_EXTI_LINE_28 EXTI_IMR1_IM28 /*!< Extended line 28 */ +#define LL_EXTI_LINE_29 EXTI_IMR1_IM29 /*!< Extended line 29 */ +#define LL_EXTI_LINE_30 EXTI_IMR1_IM30 /*!< Extended line 30 */ +#define LL_EXTI_LINE_31 EXTI_IMR1_IM31 /*!< Extended line 31 */ +#define LL_EXTI_LINE_ALL_0_31 EXTI_IMR1_IM /*!< All Extended line not reserved */ + +#define LL_EXTI_LINE_32 EXTI_IMR2_IM32 /*!< Extended line 32 */ +#define LL_EXTI_LINE_33 EXTI_IMR2_IM33 /*!< Extended line 33 */ +#define LL_EXTI_LINE_34 EXTI_IMR2_IM34 /*!< Extended line 34 */ +#define LL_EXTI_LINE_35 EXTI_IMR2_IM35 /*!< Extended line 35 */ +#define LL_EXTI_LINE_36 EXTI_IMR2_IM36 /*!< Extended line 36 */ +#define LL_EXTI_LINE_37 EXTI_IMR2_IM37 /*!< Extended line 37 */ +#define LL_EXTI_LINE_38 EXTI_IMR2_IM38 /*!< Extended line 38 */ +#define LL_EXTI_LINE_39 EXTI_IMR2_IM39 /*!< Extended line 39 */ +#define LL_EXTI_LINE_40 EXTI_IMR2_IM40 /*!< Extended line 40 */ +#define LL_EXTI_LINE_41 EXTI_IMR2_IM41 /*!< Extended line 41 */ +#define LL_EXTI_LINE_42 EXTI_IMR2_IM42 /*!< Extended line 42 */ +#define LL_EXTI_LINE_43 EXTI_IMR2_IM43 /*!< Extended line 43 */ +#define LL_EXTI_LINE_44 EXTI_IMR2_IM44 /*!< Extended line 44 */ +#define LL_EXTI_LINE_45 EXTI_IMR2_IM45 /*!< Extended line 45 */ +#if defined(ETH) +#define LL_EXTI_LINE_46 EXTI_IMR2_IM46 /*!< Extended line 46 */ +#endif /* ETH */ +#define LL_EXTI_LINE_47 EXTI_IMR2_IM47 /*!< Extended line 47 */ +#define LL_EXTI_LINE_48 EXTI_IMR2_IM48 /*!< Extended line 48 */ +#define LL_EXTI_LINE_49 EXTI_IMR2_IM49 /*!< Extended line 49 */ +#define LL_EXTI_LINE_50 EXTI_IMR2_IM50 /*!< Extended line 50 */ +#define LL_EXTI_LINE_51 EXTI_IMR2_IM51 /*!< Extended line 51 */ +#define LL_EXTI_LINE_52 EXTI_IMR2_IM52 /*!< Extended line 52 */ +#define LL_EXTI_LINE_53 EXTI_IMR2_IM53 /*!< Extended line 53 */ +#define LL_EXTI_LINE_54 EXTI_IMR2_IM54 /*!< Extended line 54 */ +#define LL_EXTI_LINE_55 EXTI_IMR2_IM55 /*!< Extended line 55 */ +#define LL_EXTI_LINE_56 EXTI_IMR2_IM56 /*!< Extended line 56 */ +#define LL_EXTI_LINE_57 EXTI_IMR2_IM57 /*!< Extended line 57 */ +#define LL_EXTI_LINE_ALL_32_63 EXTI_IMR2_IM /*!< ALL Extended line */ + +#define LL_EXTI_LINE_ALL (0xFFFFFFFFU) /*!< All Extended line */ + +#if defined(USE_FULL_LL_DRIVER) +#define LL_EXTI_LINE_NONE 0x00000000U /*!< None Extended line */ +#endif /*USE_FULL_LL_DRIVER*/ + +/** @defgroup SYSTEM_LL_EC_EXTI_PORT EXTI EXTI PORT + * @{ + */ +#define LL_EXTI_EXTI_PORTA 0U /*!< EXTI PORT A */ +#define LL_EXTI_EXTI_PORTB EXTI_EXTICR1_EXTI0_0 /*!< EXTI PORT B */ +#define LL_EXTI_EXTI_PORTC EXTI_EXTICR1_EXTI0_1 /*!< EXTI PORT C */ +#define LL_EXTI_EXTI_PORTD (EXTI_EXTICR1_EXTI0_1|EXTI_EXTICR1_EXTI0_0) /*!< EXTI PORT D */ +#define LL_EXTI_EXTI_PORTE EXTI_EXTICR1_EXTI0_2 /*!< EXTI PORT E */ +#define LL_EXTI_EXTI_PORTF (EXTI_EXTICR1_EXTI0_2|EXTI_EXTICR1_EXTI0_0) /*!< EXTI PORT F */ +#define LL_EXTI_EXTI_PORTG (EXTI_EXTICR1_EXTI0_2|EXTI_EXTICR1_EXTI0_1) /*!< EXTI PORT G */ +#define LL_EXTI_EXTI_PORTH (EXTI_EXTICR1_EXTI0_2|EXTI_EXTICR1_EXTI0_1|EXTI_EXTICR1_EXTI0_0) /*!< EXTI PORT H */ +#define LL_EXTI_EXTI_PORTI EXTI_EXTICR1_EXTI0_3 /*!< EXTI PORT I */ + +/** + * @} + */ + +/** @defgroup SYSTEM_LL_EC_EXTI_LINE EXTI EXTI LINE + * @{ + */ +#define LL_EXTI_EXTI_LINE0 ((0U << LL_EXTI_REGISTER_PINPOS_SHFT) | 0U) /*!< EXTI_POSITION_0 | EXTICR[0] */ +#define LL_EXTI_EXTI_LINE1 ((8U << LL_EXTI_REGISTER_PINPOS_SHFT) | 0U) /*!< EXTI_POSITION_8 | EXTICR[0] */ +#define LL_EXTI_EXTI_LINE2 ((16U << LL_EXTI_REGISTER_PINPOS_SHFT) | 0U) /*!< EXTI_POSITION_16 | EXTICR[0] */ +#define LL_EXTI_EXTI_LINE3 ((24U << LL_EXTI_REGISTER_PINPOS_SHFT) | 0U) /*!< EXTI_POSITION_24 | EXTICR[0] */ +#define LL_EXTI_EXTI_LINE4 ((0U << LL_EXTI_REGISTER_PINPOS_SHFT) | 1U) /*!< EXTI_POSITION_0 | EXTICR[1] */ +#define LL_EXTI_EXTI_LINE5 ((8U << LL_EXTI_REGISTER_PINPOS_SHFT) | 1U) /*!< EXTI_POSITION_8 | EXTICR[1] */ +#define LL_EXTI_EXTI_LINE6 ((16U << LL_EXTI_REGISTER_PINPOS_SHFT) | 1U) /*!< EXTI_POSITION_16 | EXTICR[1] */ +#define LL_EXTI_EXTI_LINE7 ((24U << LL_EXTI_REGISTER_PINPOS_SHFT) | 1U) /*!< EXTI_POSITION_24 | EXTICR[1] */ +#define LL_EXTI_EXTI_LINE8 ((0U << LL_EXTI_REGISTER_PINPOS_SHFT) | 2U) /*!< EXTI_POSITION_0 | EXTICR[2] */ +#define LL_EXTI_EXTI_LINE9 ((8U << LL_EXTI_REGISTER_PINPOS_SHFT) | 2U) /*!< EXTI_POSITION_8 | EXTICR[2] */ +#define LL_EXTI_EXTI_LINE10 ((16U << LL_EXTI_REGISTER_PINPOS_SHFT) | 2U) /*!< EXTI_POSITION_16 | EXTICR[2] */ +#define LL_EXTI_EXTI_LINE11 ((24U << LL_EXTI_REGISTER_PINPOS_SHFT) | 2U) /*!< EXTI_POSITION_24 | EXTICR[2] */ +#define LL_EXTI_EXTI_LINE12 ((0U << LL_EXTI_REGISTER_PINPOS_SHFT) | 3U) /*!< EXTI_POSITION_0 | EXTICR[3] */ +#define LL_EXTI_EXTI_LINE13 ((8U << LL_EXTI_REGISTER_PINPOS_SHFT) | 3U) /*!< EXTI_POSITION_8 | EXTICR[3] */ +#define LL_EXTI_EXTI_LINE14 ((16U << LL_EXTI_REGISTER_PINPOS_SHFT) | 3U) /*!< EXTI_POSITION_16 | EXTICR[3] */ +#define LL_EXTI_EXTI_LINE15 ((24U << LL_EXTI_REGISTER_PINPOS_SHFT) | 3U) /*!< EXTI_POSITION_24 | EXTICR[3] */ +/** + * @} + */ +/** + * @} + */ +#if defined(USE_FULL_LL_DRIVER) + +/** @defgroup EXTI_LL_EC_MODE Mode + * @{ + */ +#define LL_EXTI_MODE_IT ((uint8_t)0x00U) /*!< Interrupt Mode */ +#define LL_EXTI_MODE_EVENT ((uint8_t)0x01U) /*!< Event Mode */ +#define LL_EXTI_MODE_IT_EVENT ((uint8_t)0x02U) /*!< Interrupt & Event Mode */ +/** + * @} + */ + +/** @defgroup EXTI_LL_EC_TRIGGER Edge Trigger + * @{ + */ +#define LL_EXTI_TRIGGER_NONE ((uint8_t)0x00U) /*!< No Trigger Mode */ +#define LL_EXTI_TRIGGER_RISING ((uint8_t)0x01U) /*!< Trigger Rising Mode */ +#define LL_EXTI_TRIGGER_FALLING ((uint8_t)0x02U) /*!< Trigger Falling Mode */ +#define LL_EXTI_TRIGGER_RISING_FALLING ((uint8_t)0x03U) /*!< Trigger Rising & Falling Mode */ + +/** + * @} + */ + + +#endif /*USE_FULL_LL_DRIVER*/ + + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup EXTI_LL_Exported_Macros EXTI Exported Macros + * @{ + */ + +/** @defgroup EXTI_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in EXTI register + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_EXTI_WriteReg(__REG__, __VALUE__) WRITE_REG(EXTI->__REG__, (__VALUE__)) + +/** + * @brief Read a value in EXTI register + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_EXTI_ReadReg(__REG__) READ_REG(EXTI->__REG__) +/** + * @} + */ + + +/** + * @} + */ + + + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup EXTI_LL_Exported_Functions EXTI Exported Functions + * @{ + */ +/** @defgroup EXTI_LL_EF_IT_Management IT_Management + * @{ + */ + +/** + * @brief Enable ExtiLine Interrupt request for Lines in range 0 to 31 + * @note The reset value for the direct or internal lines (see RM) + * is set to 1 in order to enable the interrupt by default. + * Bits are set automatically at Power on. + * @rmtoll IMR1 IMx LL_EXTI_EnableIT_0_31 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @arg @ref LL_EXTI_LINE_17 + * @arg @ref LL_EXTI_LINE_18 + * @arg @ref LL_EXTI_LINE_19 + * @arg @ref LL_EXTI_LINE_20 + * @arg @ref LL_EXTI_LINE_21 + * @arg @ref LL_EXTI_LINE_22 + * @arg @ref LL_EXTI_LINE_23 + * @arg @ref LL_EXTI_LINE_24 + * @arg @ref LL_EXTI_LINE_25 + * @arg @ref LL_EXTI_LINE_26 + * @arg @ref LL_EXTI_LINE_27 + * @arg @ref LL_EXTI_LINE_28 + * @arg @ref LL_EXTI_LINE_29 + * @arg @ref LL_EXTI_LINE_30 + * @arg @ref LL_EXTI_LINE_31 + * @arg @ref LL_EXTI_LINE_ALL_0_31 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ +__STATIC_INLINE void LL_EXTI_EnableIT_0_31(uint32_t ExtiLine) +{ + SET_BIT(EXTI->IMR1, ExtiLine); +} + +/** + * @brief Enable ExtiLine Interrupt request for Lines in range 32 to 63 + * @rmtoll IMR2 IMx LL_EXTI_EnableIT_32_63 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_32 + * @arg @ref LL_EXTI_LINE_33 + * @arg @ref LL_EXTI_LINE_34 + * @arg @ref LL_EXTI_LINE_35 + * @arg @ref LL_EXTI_LINE_36 + * @arg @ref LL_EXTI_LINE_37 + * @arg @ref LL_EXTI_LINE_38 + * @arg @ref LL_EXTI_LINE_39 + * @arg @ref LL_EXTI_LINE_40 + * @arg @ref LL_EXTI_LINE_41 + * @arg @ref LL_EXTI_LINE_42 + * @arg @ref LL_EXTI_LINE_43 + * @arg @ref LL_EXTI_LINE_44 + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_47 + * @arg @ref LL_EXTI_LINE_48 + * @arg @ref LL_EXTI_LINE_49 + * @arg @ref LL_EXTI_LINE_50 + * @arg @ref LL_EXTI_LINE_51 + * @arg @ref LL_EXTI_LINE_52 + * @arg @ref LL_EXTI_LINE_53 + * @arg @ref LL_EXTI_LINE_54 + * @arg @ref LL_EXTI_LINE_55 + * @arg @ref LL_EXTI_LINE_56 + * @arg @ref LL_EXTI_LINE_57 (*) + * @arg @ref LL_EXTI_LINE_ALL_32_63 + * + * (*) value not defined in all devices. + * @retval None + */ +__STATIC_INLINE void LL_EXTI_EnableIT_32_63(uint32_t ExtiLine) +{ + SET_BIT(EXTI->IMR2, ExtiLine); +} + +/** + * @brief Disable ExtiLine Interrupt request for Lines in range 0 to 31 + * @note The reset value for the direct or internal lines (see RM) + * is set to 1 in order to enable the interrupt by default. + * Bits are set automatically at Power on. + * @rmtoll IMR1 IMx LL_EXTI_DisableIT_0_31 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @arg @ref LL_EXTI_LINE_17 + * @arg @ref LL_EXTI_LINE_18 + * @arg @ref LL_EXTI_LINE_19 + * @arg @ref LL_EXTI_LINE_20 + * @arg @ref LL_EXTI_LINE_21 + * @arg @ref LL_EXTI_LINE_22 + * @arg @ref LL_EXTI_LINE_23 + * @arg @ref LL_EXTI_LINE_24 + * @arg @ref LL_EXTI_LINE_25 + * @arg @ref LL_EXTI_LINE_26 + * @arg @ref LL_EXTI_LINE_27 + * @arg @ref LL_EXTI_LINE_28 + * @arg @ref LL_EXTI_LINE_29 + * @arg @ref LL_EXTI_LINE_30 + * @arg @ref LL_EXTI_LINE_31 + * @arg @ref LL_EXTI_LINE_ALL_0_31 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ +__STATIC_INLINE void LL_EXTI_DisableIT_0_31(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->IMR1, ExtiLine); +} + + +/** + * @brief Disable ExtiLine Interrupt request for Lines in range 32 to 63 + * @rmtoll IMR2 IMx LL_EXTI_DisableIT_32_63 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_32 + * @arg @ref LL_EXTI_LINE_33 + * @arg @ref LL_EXTI_LINE_34 + * @arg @ref LL_EXTI_LINE_35 + * @arg @ref LL_EXTI_LINE_36 + * @arg @ref LL_EXTI_LINE_37 + * @arg @ref LL_EXTI_LINE_38 + * @arg @ref LL_EXTI_LINE_39 + * @arg @ref LL_EXTI_LINE_40 + * @arg @ref LL_EXTI_LINE_41 + * @arg @ref LL_EXTI_LINE_42 + * @arg @ref LL_EXTI_LINE_43 + * @arg @ref LL_EXTI_LINE_44 + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_47 + * @arg @ref LL_EXTI_LINE_48 + * @arg @ref LL_EXTI_LINE_49 + * @arg @ref LL_EXTI_LINE_50 + * @arg @ref LL_EXTI_LINE_51 + * @arg @ref LL_EXTI_LINE_52 + * @arg @ref LL_EXTI_LINE_53 + * @arg @ref LL_EXTI_LINE_54 + * @arg @ref LL_EXTI_LINE_55 + * @arg @ref LL_EXTI_LINE_56 + * @arg @ref LL_EXTI_LINE_57 (*) + * @arg @ref LL_EXTI_LINE_ALL_32_63 + * + * (*) value not defined in all devices. + * @retval None + */ +__STATIC_INLINE void LL_EXTI_DisableIT_32_63(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->IMR2, ExtiLine); +} + + +/** + * @brief Indicate if ExtiLine Interrupt request is enabled for Lines in range 0 to 31 + * @note The reset value for the direct or internal lines (see RM) + * is set to 1 in order to enable the interrupt by default. + * Bits are set automatically at Power on. + * @rmtoll IMR1 IMx LL_EXTI_IsEnabledIT_0_31 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @arg @ref LL_EXTI_LINE_17 + * @arg @ref LL_EXTI_LINE_18 + * @arg @ref LL_EXTI_LINE_19 + * @arg @ref LL_EXTI_LINE_20 + * @arg @ref LL_EXTI_LINE_21 + * @arg @ref LL_EXTI_LINE_22 + * @arg @ref LL_EXTI_LINE_23 + * @arg @ref LL_EXTI_LINE_24 + * @arg @ref LL_EXTI_LINE_25 + * @arg @ref LL_EXTI_LINE_26 + * @arg @ref LL_EXTI_LINE_27 + * @arg @ref LL_EXTI_LINE_28 + * @arg @ref LL_EXTI_LINE_29 + * @arg @ref LL_EXTI_LINE_30 + * @arg @ref LL_EXTI_LINE_31 + * @arg @ref LL_EXTI_LINE_ALL_0_31 + * @note Please check each device line mapping for EXTI Line availability + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_EXTI_IsEnabledIT_0_31(uint32_t ExtiLine) +{ + return ((READ_BIT(EXTI->IMR1, ExtiLine) == (ExtiLine)) ? 1UL : 0UL); +} + + +/** + * @brief Indicate if ExtiLine Interrupt request is enabled for Lines in range 32 to 63 + * @rmtoll IMR2 IMx LL_EXTI_IsEnabledIT_32_63 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_32 + * @arg @ref LL_EXTI_LINE_33 + * @arg @ref LL_EXTI_LINE_34 + * @arg @ref LL_EXTI_LINE_35 + * @arg @ref LL_EXTI_LINE_36 + * @arg @ref LL_EXTI_LINE_37 + * @arg @ref LL_EXTI_LINE_38 + * @arg @ref LL_EXTI_LINE_39 + * @arg @ref LL_EXTI_LINE_40 + * @arg @ref LL_EXTI_LINE_41 + * @arg @ref LL_EXTI_LINE_42 + * @arg @ref LL_EXTI_LINE_43 + * @arg @ref LL_EXTI_LINE_44 + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_47 + * @arg @ref LL_EXTI_LINE_48 + * @arg @ref LL_EXTI_LINE_49 + * @arg @ref LL_EXTI_LINE_50 + * @arg @ref LL_EXTI_LINE_51 + * @arg @ref LL_EXTI_LINE_52 + * @arg @ref LL_EXTI_LINE_53 + * @arg @ref LL_EXTI_LINE_54 + * @arg @ref LL_EXTI_LINE_55 + * @arg @ref LL_EXTI_LINE_56 + * @arg @ref LL_EXTI_LINE_57 (*) + * @arg @ref LL_EXTI_LINE_ALL_32_63 + * + * (*) value not defined in all devices. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_EXTI_IsEnabledIT_32_63(uint32_t ExtiLine) +{ + return ((READ_BIT(EXTI->IMR2, ExtiLine) == (ExtiLine)) ? 1U : 0U); +} + +/** + * @} + */ + +/** @defgroup EXTI_LL_EF_Event_Management Event_Management + * @{ + */ + +/** + * @brief Enable ExtiLine Event request for Lines in range 0 to 31 + * @rmtoll EMR1 EMx LL_EXTI_EnableEvent_0_31 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @arg @ref LL_EXTI_LINE_17 + * @arg @ref LL_EXTI_LINE_18 + * @arg @ref LL_EXTI_LINE_19 + * @arg @ref LL_EXTI_LINE_20 + * @arg @ref LL_EXTI_LINE_21 + * @arg @ref LL_EXTI_LINE_22 + * @arg @ref LL_EXTI_LINE_23 + * @arg @ref LL_EXTI_LINE_24 + * @arg @ref LL_EXTI_LINE_25 + * @arg @ref LL_EXTI_LINE_26 + * @arg @ref LL_EXTI_LINE_27 + * @arg @ref LL_EXTI_LINE_28 + * @arg @ref LL_EXTI_LINE_29 + * @arg @ref LL_EXTI_LINE_30 + * @arg @ref LL_EXTI_LINE_31 + * @arg @ref LL_EXTI_LINE_ALL_0_31 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ +__STATIC_INLINE void LL_EXTI_EnableEvent_0_31(uint32_t ExtiLine) +{ + SET_BIT(EXTI->EMR1, ExtiLine); +} + +/** + * @brief Enable ExtiLine Event request for Lines in range 32 to 63 + * @rmtoll EMR2 EMx LL_EXTI_EnableEvent_32_63 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_32 + * @arg @ref LL_EXTI_LINE_33 + * @arg @ref LL_EXTI_LINE_34 + * @arg @ref LL_EXTI_LINE_35 + * @arg @ref LL_EXTI_LINE_36 + * @arg @ref LL_EXTI_LINE_37 + * @arg @ref LL_EXTI_LINE_38 + * @arg @ref LL_EXTI_LINE_39 + * @arg @ref LL_EXTI_LINE_40 + * @arg @ref LL_EXTI_LINE_41 + * @arg @ref LL_EXTI_LINE_42 + * @arg @ref LL_EXTI_LINE_43 + * @arg @ref LL_EXTI_LINE_44 + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_47 + * @arg @ref LL_EXTI_LINE_48 + * @arg @ref LL_EXTI_LINE_49 + * @arg @ref LL_EXTI_LINE_50 + * @arg @ref LL_EXTI_LINE_51 + * @arg @ref LL_EXTI_LINE_52 + * @arg @ref LL_EXTI_LINE_53 + * @arg @ref LL_EXTI_LINE_54 + * @arg @ref LL_EXTI_LINE_55 + * @arg @ref LL_EXTI_LINE_56 + * @arg @ref LL_EXTI_LINE_57 (*) + * @arg @ref LL_EXTI_LINE_ALL_32_63 + * + * (*) value not defined in all devices. + * @retval None + */ +__STATIC_INLINE void LL_EXTI_EnableEvent_32_63(uint32_t ExtiLine) +{ + SET_BIT(EXTI->EMR2, ExtiLine); +} + +/** + * @brief Disable ExtiLine Event request for Lines in range 0 to 31 + * @rmtoll EMR1 EMx LL_EXTI_DisableEvent_0_31 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @arg @ref LL_EXTI_LINE_17 + * @arg @ref LL_EXTI_LINE_18 + * @arg @ref LL_EXTI_LINE_19 + * @arg @ref LL_EXTI_LINE_20 + * @arg @ref LL_EXTI_LINE_21 + * @arg @ref LL_EXTI_LINE_22 + * @arg @ref LL_EXTI_LINE_23 + * @arg @ref LL_EXTI_LINE_24 + * @arg @ref LL_EXTI_LINE_25 + * @arg @ref LL_EXTI_LINE_26 + * @arg @ref LL_EXTI_LINE_27 + * @arg @ref LL_EXTI_LINE_28 + * @arg @ref LL_EXTI_LINE_29 + * @arg @ref LL_EXTI_LINE_30 + * @arg @ref LL_EXTI_LINE_31 + * @arg @ref LL_EXTI_LINE_ALL_0_31 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ +__STATIC_INLINE void LL_EXTI_DisableEvent_0_31(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->EMR1, ExtiLine); +} + +/** + * @brief Disable ExtiLine Event request for Lines in range 32 to 63 + * @rmtoll EMR2 EMx LL_EXTI_DisableEvent_32_63 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_32 + * @arg @ref LL_EXTI_LINE_33 + * @arg @ref LL_EXTI_LINE_34 + * @arg @ref LL_EXTI_LINE_35 + * @arg @ref LL_EXTI_LINE_36 + * @arg @ref LL_EXTI_LINE_37 + * @arg @ref LL_EXTI_LINE_38 + * @arg @ref LL_EXTI_LINE_39 + * @arg @ref LL_EXTI_LINE_40 + * @arg @ref LL_EXTI_LINE_41 + * @arg @ref LL_EXTI_LINE_42 + * @arg @ref LL_EXTI_LINE_43 + * @arg @ref LL_EXTI_LINE_44 (*) + * @arg @ref LL_EXTI_LINE_46 (*) + * @arg @ref LL_EXTI_LINE_47 + * @arg @ref LL_EXTI_LINE_48 + * @arg @ref LL_EXTI_LINE_49 + * @arg @ref LL_EXTI_LINE_50 + * @arg @ref LL_EXTI_LINE_51 + * @arg @ref LL_EXTI_LINE_52 + * @arg @ref LL_EXTI_LINE_53 + * @arg @ref LL_EXTI_LINE_54 + * @arg @ref LL_EXTI_LINE_55 + * @arg @ref LL_EXTI_LINE_56 + * @arg @ref LL_EXTI_LINE_57 (*) + * @arg @ref LL_EXTI_LINE_ALL_32_63 + * + * (*) value not defined in all devices. + * @retval None + */ +__STATIC_INLINE void LL_EXTI_DisableEvent_32_63(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->EMR2, ExtiLine); +} + +/** + * @brief Indicate if ExtiLine Event request is enabled for Lines in range 0 to 31 + * @rmtoll EMR1 EMx LL_EXTI_IsEnabledEvent_0_31 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @arg @ref LL_EXTI_LINE_17 + * @arg @ref LL_EXTI_LINE_18 + * @arg @ref LL_EXTI_LINE_19 + * @arg @ref LL_EXTI_LINE_20 + * @arg @ref LL_EXTI_LINE_21 + * @arg @ref LL_EXTI_LINE_22 + * @arg @ref LL_EXTI_LINE_23 + * @arg @ref LL_EXTI_LINE_24 + * @arg @ref LL_EXTI_LINE_25 + * @arg @ref LL_EXTI_LINE_26 + * @arg @ref LL_EXTI_LINE_27 + * @arg @ref LL_EXTI_LINE_28 + * @arg @ref LL_EXTI_LINE_29 + * @arg @ref LL_EXTI_LINE_30 + * @arg @ref LL_EXTI_LINE_31 + * @arg @ref LL_EXTI_LINE_ALL_0_31 + * @note Please check each device line mapping for EXTI Line availability + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_EXTI_IsEnabledEvent_0_31(uint32_t ExtiLine) +{ + return ((READ_BIT(EXTI->EMR1, ExtiLine) == (ExtiLine)) ? 1UL : 0UL); +} + +/** + * @brief Indicate if ExtiLine Event request is enabled for Lines in range 32 to 63 + * @rmtoll EMR2 EMx LL_EXTI_IsEnabledEvent_32_63 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_32 + * @arg @ref LL_EXTI_LINE_33 + * @arg @ref LL_EXTI_LINE_34 + * @arg @ref LL_EXTI_LINE_35 + * @arg @ref LL_EXTI_LINE_36 + * @arg @ref LL_EXTI_LINE_37 + * @arg @ref LL_EXTI_LINE_38 + * @arg @ref LL_EXTI_LINE_39 + * @arg @ref LL_EXTI_LINE_40 + * @arg @ref LL_EXTI_LINE_41 + * @arg @ref LL_EXTI_LINE_42 + * @arg @ref LL_EXTI_LINE_43 + * @arg @ref LL_EXTI_LINE_44 + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_47 + * @arg @ref LL_EXTI_LINE_48 + * @arg @ref LL_EXTI_LINE_49 + * @arg @ref LL_EXTI_LINE_50 + * @arg @ref LL_EXTI_LINE_51 + * @arg @ref LL_EXTI_LINE_52 + * @arg @ref LL_EXTI_LINE_53 + * @arg @ref LL_EXTI_LINE_54 + * @arg @ref LL_EXTI_LINE_55 + * @arg @ref LL_EXTI_LINE_56 + * @arg @ref LL_EXTI_LINE_57 (*) + * @arg @ref LL_EXTI_LINE_ALL_32_63 + * + * (*) value not defined in all devices. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_EXTI_IsEnabledEvent_32_63(uint32_t ExtiLine) +{ + return ((READ_BIT(EXTI->EMR2, ExtiLine) == (ExtiLine)) ? 1U : 0U); +} + +/** + * @} + */ + +/** @defgroup EXTI_LL_EF_Rising_Trigger_Management Rising_Trigger_Management + * @{ + */ + +/** + * @brief Enable ExtiLine Rising Edge Trigger for Lines in range 0 to 31 + * @note The configurable wakeup lines are edge-triggered. No glitch must be + * generated on these lines. If a rising edge on a configurable interrupt + * line occurs during a write operation in the EXTI_RTSR register, the + * pending bit is not set. + * Rising and falling edge triggers can be set for + * the same interrupt line. In this case, both generate a trigger + * condition. + * @rmtoll RTSR1 RTx LL_EXTI_EnableRisingTrig_0_31 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @retval None + */ +__STATIC_INLINE void LL_EXTI_EnableRisingTrig_0_31(uint32_t ExtiLine) +{ + SET_BIT(EXTI->RTSR1, ExtiLine); + +} + +/** + * @brief Enable ExtiLine Rising Edge Trigger for Lines in range 32 to 63 + * @note The configurable wakeup lines are edge-triggered. No glitch must be + * generated on these lines. If a rising edge on a configurable interrupt + * line occurs during a write operation in the EXTI_RTSR register, the + * pending bit is not set.Rising and falling edge triggers can be set for + * the same interrupt line. In this case, both generate a trigger + * condition. + * @rmtoll RTSR2 RTx LL_EXTI_EnableRisingTrig_32_63 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_50 + * @arg @ref LL_EXTI_LINE_51 + * @retval None + */ +__STATIC_INLINE void LL_EXTI_EnableRisingTrig_32_63(uint32_t ExtiLine) +{ + SET_BIT(EXTI->RTSR2, ExtiLine); +} + +/** + * @brief Disable ExtiLine Rising Edge Trigger for Lines in range 0 to 31 + * @note The configurable wakeup lines are edge-triggered. No glitch must be + * generated on these lines. If a rising edge on a configurable interrupt + * line occurs during a write operation in the EXTI_RTSR register, the + * pending bit is not set. + * Rising and falling edge triggers can be set for + * the same interrupt line. In this case, both generate a trigger + * condition. + * @rmtoll RTSR1 RTx LL_EXTI_DisableRisingTrig_0_31 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @retval None + */ +__STATIC_INLINE void LL_EXTI_DisableRisingTrig_0_31(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->RTSR1, ExtiLine); + +} + +/** + * @brief Disable ExtiLine Rising Edge Trigger for Lines in range 32 to 63 + * @note The configurable wakeup lines are edge-triggered. No glitch must be + * generated on these lines. If a rising edge on a configurable interrupt + * line occurs during a write operation in the EXTI_RTSR register, the + * pending bit is not set. + * Rising and falling edge triggers can be set for + * the same interrupt line. In this case, both generate a trigger + * condition. + * @rmtoll RTSR2 RTx LL_EXTI_DisableRisingTrig_32_63 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_50 + * @arg @ref LL_EXTI_LINE_51 + * @retval None + */ +__STATIC_INLINE void LL_EXTI_DisableRisingTrig_32_63(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->RTSR2, ExtiLine); +} + +/** + * @brief Check if rising edge trigger is enabled for Lines in range 0 to 31 + * @rmtoll RTSR1 RTx LL_EXTI_IsEnabledRisingTrig_0_31 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_EXTI_IsEnabledRisingTrig_0_31(uint32_t ExtiLine) +{ + return ((READ_BIT(EXTI->RTSR1, ExtiLine) == (ExtiLine)) ? 1UL : 0UL); +} + + +/** + * @brief Check if rising edge trigger is enabled for Lines in range 32 to 63 + * @rmtoll RTSR2 RTx LL_EXTI_IsEnabledRisingTrig_32_63 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_50 + * @arg @ref LL_EXTI_LINE_51 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_EXTI_IsEnabledRisingTrig_32_63(uint32_t ExtiLine) +{ + return ((READ_BIT(EXTI->RTSR2, ExtiLine) == (ExtiLine)) ? 1U : 0U); +} + + +/** + * @} + */ + +/** @defgroup EXTI_LL_EF_Falling_Trigger_Management Falling_Trigger_Management + * @{ + */ + +/** + * @brief Enable ExtiLine Falling Edge Trigger for Lines in range 0 to 31 + * @note The configurable wakeup lines are edge-triggered. No glitch must be + * generated on these lines. If a falling edge on a configurable interrupt + * line occurs during a write operation in the EXTI_FTSR register, the + * pending bit is not set. + * Rising and falling edge triggers can be set for + * the same interrupt line. In this case, both generate a trigger + * condition. + * @rmtoll FTSR1 FTx LL_EXTI_EnableFallingTrig_0_31 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ +__STATIC_INLINE void LL_EXTI_EnableFallingTrig_0_31(uint32_t ExtiLine) +{ + SET_BIT(EXTI->FTSR1, ExtiLine); +} + +/** + * @brief Enable ExtiLine Falling Edge Trigger for Lines in range 32 to 63 + * @note The configurable wakeup lines are edge-triggered. No glitch must be + * generated on these lines. If a Falling edge on a configurable interrupt + * line occurs during a write operation in the EXTI_FTSR register, the + * pending bit is not set. + * Rising and falling edge triggers can be set for + * the same interrupt line. In this case, both generate a trigger + * condition. + * @rmtoll FTSR2 FTx LL_EXTI_EnableFallingTrig_32_63 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_50 + * @arg @ref LL_EXTI_LINE_51 + * @retval None + */ +__STATIC_INLINE void LL_EXTI_EnableFallingTrig_32_63(uint32_t ExtiLine) +{ + SET_BIT(EXTI->FTSR2, ExtiLine); +} + + +/** + * @brief Disable ExtiLine Falling Edge Trigger for Lines in range 0 to 31 + * @note The configurable wakeup lines are edge-triggered. No glitch must be + * generated on these lines. If a Falling edge on a configurable interrupt + * line occurs during a write operation in the EXTI_FTSR register, the + * pending bit is not set. + * Rising and falling edge triggers can be set for the same interrupt line. + * In this case, both generate a trigger condition. + * @rmtoll FTSR1 FTx LL_EXTI_DisableFallingTrig_0_31 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ +__STATIC_INLINE void LL_EXTI_DisableFallingTrig_0_31(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->FTSR1, ExtiLine); +} + +/** + * @brief Disable ExtiLine Falling Edge Trigger for Lines in range 32 to 63 + * @note The configurable wakeup lines are edge-triggered. No glitch must be + * generated on these lines. If a Falling edge on a configurable interrupt + * line occurs during a write operation in the EXTI_FTSR register, the + * pending bit is not set. + * Rising and falling edge triggers can be set for the same interrupt line. + * In this case, both generate a trigger condition. + * @rmtoll FTSR2 FTx LL_EXTI_DisableFallingTrig_32_63 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_50 + * @arg @ref LL_EXTI_LINE_51 + * @retval None + */ +__STATIC_INLINE void LL_EXTI_DisableFallingTrig_32_63(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->FTSR2, ExtiLine); +} + + +/** + * @brief Check if falling edge trigger is enabled for Lines in range 0 to 31 + * @rmtoll FTSR1 FTx LL_EXTI_IsEnabledFallingTrig_0_31 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @note Please check each device line mapping for EXTI Line availability + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_EXTI_IsEnabledFallingTrig_0_31(uint32_t ExtiLine) +{ + return ((READ_BIT(EXTI->FTSR1, ExtiLine) == (ExtiLine)) ? 1UL : 0UL); +} + +/** + * @brief Check if falling edge trigger is enabled for Lines in range 32 to 63 + * @rmtoll FTSR2 FTx LL_EXTI_IsEnabledFallingTrig_32_63 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_50 + * @arg @ref LL_EXTI_LINE_51 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_EXTI_IsEnabledFallingTrig_32_63(uint32_t ExtiLine) +{ + return ((READ_BIT(EXTI->FTSR2, ExtiLine) == (ExtiLine)) ? 1U : 0U); +} + + +/** + * @} + */ + +/** @defgroup EXTI_LL_EF_Software_Interrupt_Management Software_Interrupt_Management + * @{ + */ + +/** + * @brief Generate a software Interrupt Event for Lines in range 0 to 31 + * @note If the interrupt is enabled on this line in the EXTI_C1IMR1, writing a 1 to + * this bit when it is at '0' sets the corresponding pending bit in EXTI_PR1 + * resulting in an interrupt request generation. + * This bit is cleared by clearing the corresponding bit in the EXTI_PR1 + * register (by writing a 1 into the bit) + * @rmtoll SWIER1 SWIx LL_EXTI_GenerateSWI_0_31 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ +__STATIC_INLINE void LL_EXTI_GenerateSWI_0_31(uint32_t ExtiLine) +{ + SET_BIT(EXTI->SWIER1, ExtiLine); +} + +/** + * @brief Generate a software Interrupt Event for Lines in range 32 to 63 + * @note If the interrupt is enabled on this line in the EXTI_IMR2, writing a 1 to + * this bit when it is at '0' sets the corresponding pending bit in EXTI_PR2 + * resulting in an interrupt request generation. + * This bit is cleared by clearing the corresponding bit in the EXTI_PR2 + * register (by writing a 1 into the bit) + * @rmtoll SWIER2 SWIx LL_EXTI_GenerateSWI_32_63 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_50 + * @arg @ref LL_EXTI_LINE_51 + * @retval None + */ +__STATIC_INLINE void LL_EXTI_GenerateSWI_32_63(uint32_t ExtiLine) +{ + SET_BIT(EXTI->SWIER2, ExtiLine); +} + + +/** + * @} + */ + +/** @defgroup EXTI_LL_EF_Flag_Management Flag_Management + * @{ + */ + +/** + * @brief Check if the ExtLine Falling Flag is set or not for Lines in range 0 to 31 + * @note This bit is set when the falling edge event arrives on the interrupt + * line. This bit is cleared by writing a 1 to the bit. + * @rmtoll FPR1 FPIFx LL_EXTI_IsActiveFallingFlag_0_31 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @note Please check each device line mapping for EXTI Line availability + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_EXTI_IsActiveFallingFlag_0_31(uint32_t ExtiLine) +{ + return ((READ_BIT(EXTI->FPR1, ExtiLine) == (ExtiLine)) ? 1UL : 0UL); +} + +/** + * @brief Check if the ExtLine Falling Flag is set or not for Lines in range 32 to 63 + * @note This bit is set when the falling edge event arrives on the interrupt + * line. This bit is cleared by writing a 1 to the bit. + * @rmtoll FPR2 FPIFx LL_EXTI_IsActiveFallingFlag_32_63 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_50 + * @arg @ref LL_EXTI_LINE_53 + * @note Please check each device line mapping for EXTI Line availability + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_EXTI_IsActiveFallingFlag_32_63(uint32_t ExtiLine) +{ + return ((READ_BIT(EXTI->FPR2, ExtiLine) == (ExtiLine)) ? 1UL : 0UL); +} + +/** + * @brief Read ExtLine Combination Falling Flag for Lines in range 0 to 31 + * @note This bit is set when the falling edge event arrives on the interrupt + * line. This bit is cleared by writing a 1 to the bit. + * @rmtoll FPR1 FPIFx LL_EXTI_ReadFallingFlag_0_31 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @note Please check each device line mapping for EXTI Line availability + * @retval @note This bit is set when the selected edge event arrives on the interrupt + */ +__STATIC_INLINE uint32_t LL_EXTI_ReadFallingFlag_0_31(uint32_t ExtiLine) +{ + return (uint32_t)(READ_BIT(EXTI->FPR1, ExtiLine)); +} + +/** + * @brief Read ExtLine Combination Falling Flag for Lines in range 32 to 63 + * @note This bit is set when the falling edge event arrives on the interrupt + * line. This bit is cleared by writing a 1 to the bit. + * @rmtoll FPR2 FPIFx LL_EXTI_ReadFallingFlag_32_63 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_50 + * @arg @ref LL_EXTI_LINE_53 + * @note Please check each device line mapping for EXTI Line availability + * @retval @note This bit is set when the selected edge event arrives on the interrupt + */ +__STATIC_INLINE uint32_t LL_EXTI_ReadFallingFlag_32_63(uint32_t ExtiLine) +{ + return (uint32_t)(READ_BIT(EXTI->FPR2, ExtiLine)); +} + +/** + * @brief Clear ExtLine Falling Flags for Lines in range 0 to 31 + * @note This bit is set when the falling edge event arrives on the interrupt + * line. This bit is cleared by writing a 1 to the bit. + * @rmtoll FPR1 FPIFx LL_EXTI_ClearFallingFlag_0_31 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ +__STATIC_INLINE void LL_EXTI_ClearFallingFlag_0_31(uint32_t ExtiLine) +{ + WRITE_REG(EXTI->FPR1, ExtiLine); +} + +/** + * @brief Clear ExtLine Falling Flags for Lines in range 32 to 63 + * @note This bit is set when the falling edge event arrives on the interrupt + * line. This bit is cleared by writing a 1 to the bit. + * @rmtoll FPR2 FPIFx LL_EXTI_ClearFallingFlag_32_63 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_50 + * @arg @ref LL_EXTI_LINE_53 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ +__STATIC_INLINE void LL_EXTI_ClearFallingFlag_32_63(uint32_t ExtiLine) +{ + WRITE_REG(EXTI->FPR2, ExtiLine); +} + + +/** + * @brief Check if the ExtLine Rising Flag is set or not for Lines in range 0 to 31 + * @note This bit is set when the Rising edge event arrives on the interrupt + * line. This bit is cleared by writing a 1 to the bit. + * @rmtoll RPR1 RPIFx LL_EXTI_IsActiveRisingFlag_0_31 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @note Please check each device line mapping for EXTI Line availability + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_EXTI_IsActiveRisingFlag_0_31(uint32_t ExtiLine) +{ + return ((READ_BIT(EXTI->RPR1, ExtiLine) == (ExtiLine)) ? 1UL : 0UL); +} + +/** + * @brief Check if the ExtLine Rising Flag is set or not for Lines in range 32 to 63 + * @note This bit is set when the rising edge event arrives on the interrupt + * line. This bit is cleared by writing a 1 to the bit. + * @rmtoll RPR2 RPIFx LL_EXTI_IsActiveRisingFlag_32_63 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_50 + * @arg @ref LL_EXTI_LINE_53 + * @note Please check each device line mapping for EXTI Line availability + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_EXTI_IsActiveRisingFlag_32_63(uint32_t ExtiLine) +{ + return ((READ_BIT(EXTI->RPR2, ExtiLine) == (ExtiLine)) ? 1UL : 0UL); +} + +/** + * @brief Read ExtLine Combination Rising Flag for Lines in range 0 to 31 + * @note This bit is set when the Rising edge event arrives on the interrupt + * line. This bit is cleared by writing a 1 to the bit. + * @rmtoll RPR1 RPIFx LL_EXTI_ReadRisingFlag_0_31 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @note Please check each device line mapping for EXTI Line availability + * @retval @note This bit is set when the selected edge event arrives on the interrupt + */ +__STATIC_INLINE uint32_t LL_EXTI_ReadRisingFlag_0_31(uint32_t ExtiLine) +{ + return (uint32_t)(READ_BIT(EXTI->RPR1, ExtiLine)); +} + +/** + * @brief Read ExtLine Combination Rising Flag for Lines in range 32 to 63 + * @note This bit is set when the rising edge event arrives on the interrupt + * line. This bit is cleared by writing a 1 to the bit. + * @rmtoll RPR2 RPIFx LL_EXTI_ReadRisingFlag_32_63 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_50 + * @arg @ref LL_EXTI_LINE_53 + * @note Please check each device line mapping for EXTI Line availability + * @retval @note This bit is set when the selected edge event arrives on the interrupt + */ +__STATIC_INLINE uint32_t LL_EXTI_ReadRisingFlag_32_63(uint32_t ExtiLine) +{ + return (uint32_t)(READ_BIT(EXTI->RPR2, ExtiLine)); +} + +/** + * @brief Clear ExtLine Rising Flags for Lines in range 0 to 31 + * @note This bit is set when the Rising edge event arrives on the interrupt + * line. This bit is cleared by writing a 1 to the bit. + * @rmtoll RPR1 RPIFx LL_EXTI_ClearRisingFlag_0_31 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ +__STATIC_INLINE void LL_EXTI_ClearRisingFlag_0_31(uint32_t ExtiLine) +{ + WRITE_REG(EXTI->RPR1, ExtiLine); +} + +/** + * @brief Clear ExtLine Rising Flags for Lines in range 32 to 63 + * @note This bit is set when the rising edge event arrives on the interrupt + * line. This bit is cleared by writing a 1 to the bit. + * @rmtoll RPR2 RPIFx LL_EXTI_ClearRisingFlag_32_63 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_50 + * @arg @ref LL_EXTI_LINE_53 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ +__STATIC_INLINE void LL_EXTI_ClearRisingFlag_32_63(uint32_t ExtiLine) +{ + WRITE_REG(EXTI->RPR2, ExtiLine); +} + +/** + * @} + */ +/** @defgroup EXTI_LL_EF_Config EF configuration functions + * @{ + */ + +/** + * @brief Configure source input for the EXTI external interrupt. + * @rmtoll EXTI_EXTICR1 EXTI0 LL_EXTI_SetEXTISource\n + * EXTI_EXTICR1 EXTI1 LL_EXTI_SetEXTISource\n + * EXTI_EXTICR1 EXTI2 LL_EXTI_SetEXTISource\n + * EXTI_EXTICR1 EXTI3 LL_EXTI_SetEXTISource\n + * EXTI_EXTICR2 EXTI4 LL_EXTI_SetEXTISource\n + * EXTI_EXTICR2 EXTI5 LL_EXTI_SetEXTISource\n + * EXTI_EXTICR2 EXTI6 LL_EXTI_SetEXTISource\n + * EXTI_EXTICR2 EXTI7 LL_EXTI_SetEXTISource\n + * EXTI_EXTICR3 EXTI8 LL_EXTI_SetEXTISource\n + * EXTI_EXTICR3 EXTI9 LL_EXTI_SetEXTISource\n + * EXTI_EXTICR3 EXTI10 LL_EXTI_SetEXTISource\n + * EXTI_EXTICR3 EXTI11 LL_EXTI_SetEXTISource\n + * EXTI_EXTICR4 EXTI12 LL_EXTI_SetEXTISource\n + * EXTI_EXTICR4 EXTI13 LL_EXTI_SetEXTISource\n + * EXTI_EXTICR4 EXTI14 LL_EXTI_SetEXTISource\n + * EXTI_EXTICR4 EXTI15 LL_EXTI_SetEXTISource + * @param Port This parameter can be one of the following values: + * @arg @ref LL_EXTI_EXTI_PORTA + * @arg @ref LL_EXTI_EXTI_PORTB + * @arg @ref LL_EXTI_EXTI_PORTC + * @arg @ref LL_EXTI_EXTI_PORTD + * @arg @ref LL_EXTI_EXTI_PORTE + * @arg @ref LL_EXTI_EXTI_PORTF + * @arg @ref LL_EXTI_EXTI_PORTG + * @arg @ref LL_EXTI_EXTI_PORTH + * @arg @ref LL_EXTI_EXTI_PORTI + * + * (*) value not defined in all devices + * @param Line This parameter can be one of the following values: + * @arg @ref LL_EXTI_EXTI_LINE0 + * @arg @ref LL_EXTI_EXTI_LINE1 + * @arg @ref LL_EXTI_EXTI_LINE2 + * @arg @ref LL_EXTI_EXTI_LINE3 + * @arg @ref LL_EXTI_EXTI_LINE4 + * @arg @ref LL_EXTI_EXTI_LINE5 + * @arg @ref LL_EXTI_EXTI_LINE6 + * @arg @ref LL_EXTI_EXTI_LINE7 + * @arg @ref LL_EXTI_EXTI_LINE8 + * @arg @ref LL_EXTI_EXTI_LINE9 + * @arg @ref LL_EXTI_EXTI_LINE10 + * @arg @ref LL_EXTI_EXTI_LINE11 + * @arg @ref LL_EXTI_EXTI_LINE12 + * @arg @ref LL_EXTI_EXTI_LINE13 + * @arg @ref LL_EXTI_EXTI_LINE14 + * @arg @ref LL_EXTI_EXTI_LINE15 + * @retval None + */ +__STATIC_INLINE void LL_EXTI_SetEXTISource(uint32_t Port, uint32_t Line) +{ + MODIFY_REG(EXTI->EXTICR[Line & 0x03U], EXTI_EXTICR1_EXTI0 << (Line >> LL_EXTI_REGISTER_PINPOS_SHFT), \ + Port << (Line >> LL_EXTI_REGISTER_PINPOS_SHFT)); +} + +/** + * @brief Get the configured defined for specific EXTI Line + * @rmtoll EXTI_EXTICR1 EXTI0 LL_EXTI_GetEXTISource\n + * EXTI_EXTICR1 EXTI1 LL_EXTI_GetEXTISource\n + * EXTI_EXTICR1 EXTI2 LL_EXTI_GetEXTISource\n + * EXTI_EXTICR1 EXTI3 LL_EXTI_GetEXTISource\n + * EXTI_EXTICR2 EXTI4 LL_EXTI_GetEXTISource\n + * EXTI_EXTICR2 EXTI5 LL_EXTI_GetEXTISource\n + * EXTI_EXTICR2 EXTI6 LL_EXTI_GetEXTISource\n + * EXTI_EXTICR2 EXTI7 LL_EXTI_GetEXTISource\n + * EXTI_EXTICR3 EXTI8 LL_EXTI_GetEXTISource\n + * EXTI_EXTICR3 EXTI9 LL_EXTI_GetEXTISource\n + * EXTI_EXTICR3 EXTI10 LL_EXTI_GetEXTISource\n + * EXTI_EXTICR3 EXTI11 LL_EXTI_GetEXTISource\n + * EXTI_EXTICR4 EXTI12 LL_EXTI_GetEXTISource\n + * EXTI_EXTICR4 EXTI13 LL_EXTI_GetEXTISource\n + * EXTI_EXTICR4 EXTI14 LL_EXTI_GetEXTISource\n + * EXTI_EXTICR4 EXTI15 LL_EXTI_GetEXTISource + * @param Line This parameter can be one of the following values: + * @arg @ref LL_EXTI_EXTI_LINE0 + * @arg @ref LL_EXTI_EXTI_LINE1 + * @arg @ref LL_EXTI_EXTI_LINE2 + * @arg @ref LL_EXTI_EXTI_LINE3 + * @arg @ref LL_EXTI_EXTI_LINE4 + * @arg @ref LL_EXTI_EXTI_LINE5 + * @arg @ref LL_EXTI_EXTI_LINE6 + * @arg @ref LL_EXTI_EXTI_LINE7 + * @arg @ref LL_EXTI_EXTI_LINE8 + * @arg @ref LL_EXTI_EXTI_LINE9 + * @arg @ref LL_EXTI_EXTI_LINE10 + * @arg @ref LL_EXTI_EXTI_LINE11 + * @arg @ref LL_EXTI_EXTI_LINE12 + * @arg @ref LL_EXTI_EXTI_LINE13 + * @arg @ref LL_EXTI_EXTI_LINE14 + * @arg @ref LL_EXTI_EXTI_LINE15 + * @retval Returned value can be one of the following values: + * @arg @ref LL_EXTI_EXTI_PORTA + * @arg @ref LL_EXTI_EXTI_PORTB + * @arg @ref LL_EXTI_EXTI_PORTC + * @arg @ref LL_EXTI_EXTI_PORTD + * @arg @ref LL_EXTI_EXTI_PORTE + * @arg @ref LL_EXTI_EXTI_PORTF + * @arg @ref LL_EXTI_EXTI_PORTG + * @arg @ref LL_EXTI_EXTI_PORTH + * @arg @ref LL_EXTI_EXTI_PORTI + */ +__STATIC_INLINE uint32_t LL_EXTI_GetEXTISource(uint32_t Line) +{ + return (uint32_t)(READ_BIT(EXTI->EXTICR[Line & 0x03U], + (EXTI_EXTICR1_EXTI0 << (Line >> LL_EXTI_REGISTER_PINPOS_SHFT))) >> + (Line >> LL_EXTI_REGISTER_PINPOS_SHFT)); +} +/** + * @} + */ + +/** @defgroup EXTI_LL_EF_Secure_Management Secure_Management + * @{ + */ + +#if defined(__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) + +/** + * @brief Enable ExtiLine Secure attribute for Lines in range 0 to 31 + * @rmtoll SECCFGR1 SECx LL_EXTI_EnableSecure_0_31 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @arg @ref LL_EXTI_LINE_17 + * @arg @ref LL_EXTI_LINE_18 + * @arg @ref LL_EXTI_LINE_19 + * @arg @ref LL_EXTI_LINE_20 + * @arg @ref LL_EXTI_LINE_21 + * @arg @ref LL_EXTI_LINE_22 + * @arg @ref LL_EXTI_LINE_23 + * @arg @ref LL_EXTI_LINE_24 + * @arg @ref LL_EXTI_LINE_25 + * @arg @ref LL_EXTI_LINE_26 + * @arg @ref LL_EXTI_LINE_27 + * @arg @ref LL_EXTI_LINE_28 + * @arg @ref LL_EXTI_LINE_29 + * @arg @ref LL_EXTI_LINE_30 + * @arg @ref LL_EXTI_LINE_31 + * @arg @ref LL_EXTI_LINE_ALL_0_31 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ +__STATIC_INLINE void LL_EXTI_EnableSecure_0_31(uint32_t ExtiLine) +{ + SET_BIT(EXTI->SECCFGR1, ExtiLine); +} + +/** + * @brief Enable ExtiLine Secure attribute for Lines in range 32 to 63 + * @rmtoll SECCFGR2 SECx LL_EXTI_EnableSecure_32_63 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_32 + * @arg @ref LL_EXTI_LINE_33 + * @arg @ref LL_EXTI_LINE_34 + * @arg @ref LL_EXTI_LINE_35 + * @arg @ref LL_EXTI_LINE_36 + * @arg @ref LL_EXTI_LINE_37 + * @arg @ref LL_EXTI_LINE_38 + * @arg @ref LL_EXTI_LINE_39 + * @arg @ref LL_EXTI_LINE_40 + * @arg @ref LL_EXTI_LINE_41 + * @arg @ref LL_EXTI_LINE_42 + * @arg @ref LL_EXTI_LINE_43 + * @arg @ref LL_EXTI_LINE_44 + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_47 + * @arg @ref LL_EXTI_LINE_48 + * @arg @ref LL_EXTI_LINE_49 + * @arg @ref LL_EXTI_LINE_50 + * @arg @ref LL_EXTI_LINE_51 + * @arg @ref LL_EXTI_LINE_52 + * @arg @ref LL_EXTI_LINE_53 + * @arg @ref LL_EXTI_LINE_54 + * @arg @ref LL_EXTI_LINE_55 + * @arg @ref LL_EXTI_LINE_56 + * @arg @ref LL_EXTI_LINE_57 (*) + * @arg @ref LL_EXTI_LINE_ALL_32_63 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ +__STATIC_INLINE void LL_EXTI_EnableSecure_32_63(uint32_t ExtiLine) +{ + SET_BIT(EXTI->SECCFGR2, ExtiLine); +} + +/** + * @brief Disable ExtiLine Secure attribute for Lines in range 0 to 31 + * @rmtoll SECCFGR1 SECx LL_EXTI_DisableSecure_0_31 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @arg @ref LL_EXTI_LINE_17 + * @arg @ref LL_EXTI_LINE_18 + * @arg @ref LL_EXTI_LINE_19 + * @arg @ref LL_EXTI_LINE_20 + * @arg @ref LL_EXTI_LINE_21 + * @arg @ref LL_EXTI_LINE_22 + * @arg @ref LL_EXTI_LINE_23 + * @arg @ref LL_EXTI_LINE_24 + * @arg @ref LL_EXTI_LINE_25 + * @arg @ref LL_EXTI_LINE_26 + * @arg @ref LL_EXTI_LINE_27 + * @arg @ref LL_EXTI_LINE_28 + * @arg @ref LL_EXTI_LINE_29 + * @arg @ref LL_EXTI_LINE_30 + * @arg @ref LL_EXTI_LINE_31 + * @arg @ref LL_EXTI_LINE_ALL_0_31 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ +__STATIC_INLINE void LL_EXTI_DisableSecure_0_31(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->SECCFGR1, ExtiLine); +} + +/** + * @brief Disable ExtiLine Secure attribute for Lines in range 32 to 63 + * @rmtoll SECCFGR2 SECx LL_EXTI_DisableSecure_32_63 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_32 + * @arg @ref LL_EXTI_LINE_33 + * @arg @ref LL_EXTI_LINE_34 + * @arg @ref LL_EXTI_LINE_35 + * @arg @ref LL_EXTI_LINE_36 + * @arg @ref LL_EXTI_LINE_37 + * @arg @ref LL_EXTI_LINE_38 + * @arg @ref LL_EXTI_LINE_39 + * @arg @ref LL_EXTI_LINE_40 + * @arg @ref LL_EXTI_LINE_41 + * @arg @ref LL_EXTI_LINE_42 + * @arg @ref LL_EXTI_LINE_43 + * @arg @ref LL_EXTI_LINE_44 + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_47 + * @arg @ref LL_EXTI_LINE_48 + * @arg @ref LL_EXTI_LINE_49 + * @arg @ref LL_EXTI_LINE_50 + * @arg @ref LL_EXTI_LINE_51 + * @arg @ref LL_EXTI_LINE_52 + * @arg @ref LL_EXTI_LINE_53 + * @arg @ref LL_EXTI_LINE_54 + * @arg @ref LL_EXTI_LINE_55 + * @arg @ref LL_EXTI_LINE_56 + * @arg @ref LL_EXTI_LINE_57 (*) + * @arg @ref LL_EXTI_LINE_ALL_32_63 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ +__STATIC_INLINE void LL_EXTI_DisableSecure_32_63(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->SECCFGR2, ExtiLine); +} + +#endif /* __ARM_FEATURE_CMSE */ + +/** + * @brief Indicate if ExtiLine Secure attribute is enabled for Lines in range 0 to 31 + * @rmtoll SECCFGR1 SECx LL_EXTI_IsEnabledSecure_0_31 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @arg @ref LL_EXTI_LINE_17 + * @arg @ref LL_EXTI_LINE_18 + * @arg @ref LL_EXTI_LINE_19 + * @arg @ref LL_EXTI_LINE_20 + * @arg @ref LL_EXTI_LINE_21 + * @arg @ref LL_EXTI_LINE_22 + * @arg @ref LL_EXTI_LINE_23 + * @arg @ref LL_EXTI_LINE_24 + * @arg @ref LL_EXTI_LINE_25 + * @arg @ref LL_EXTI_LINE_26 + * @arg @ref LL_EXTI_LINE_27 + * @arg @ref LL_EXTI_LINE_28 + * @arg @ref LL_EXTI_LINE_29 + * @arg @ref LL_EXTI_LINE_30 + * @arg @ref LL_EXTI_LINE_31 + * @arg @ref LL_EXTI_LINE_ALL_0_31 + * @note Please check each device line mapping for EXTI Line availability + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_EXTI_IsEnabledSecure_0_31(uint32_t ExtiLine) +{ + return ((READ_BIT(EXTI->SECCFGR1, ExtiLine) == (ExtiLine)) ? 1UL : 0UL); +} + +/** + * @brief Indicate if ExtiLine Secure attribute is enabled for Lines in range 32 to 63 + * @rmtoll SECCFGR2 SECx LL_EXTI_IsEnabledSecure_32_63 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_32 + * @arg @ref LL_EXTI_LINE_33 + * @arg @ref LL_EXTI_LINE_34 + * @arg @ref LL_EXTI_LINE_35 + * @arg @ref LL_EXTI_LINE_36 + * @arg @ref LL_EXTI_LINE_37 + * @arg @ref LL_EXTI_LINE_38 + * @arg @ref LL_EXTI_LINE_39 + * @arg @ref LL_EXTI_LINE_40 + * @arg @ref LL_EXTI_LINE_41 + * @arg @ref LL_EXTI_LINE_42 + * @arg @ref LL_EXTI_LINE_43 + * @arg @ref LL_EXTI_LINE_44 + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_47 + * @arg @ref LL_EXTI_LINE_48 + * @arg @ref LL_EXTI_LINE_49 + * @arg @ref LL_EXTI_LINE_50 + * @arg @ref LL_EXTI_LINE_51 + * @arg @ref LL_EXTI_LINE_52 + * @arg @ref LL_EXTI_LINE_53 + * @arg @ref LL_EXTI_LINE_54 + * @arg @ref LL_EXTI_LINE_55 + * @arg @ref LL_EXTI_LINE_56 + * @arg @ref LL_EXTI_LINE_57 (*) + * @arg @ref LL_EXTI_LINE_ALL_32_63 + * @note Please check each device line mapping for EXTI Line availability + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_EXTI_IsEnabledSecure_32_63(uint32_t ExtiLine) +{ + return ((READ_BIT(EXTI->SECCFGR2, ExtiLine) == (ExtiLine)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup EXTI_LL_EF_Privilege_Management Privilege_Management + * @{ + */ + +/** + * @brief Enable ExtiLine Privilege attribute for Lines in range 0 to 31 + * @rmtoll PRIVCFGR1 PRIVx LL_EXTI_EnablePrivilege_0_31 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @arg @ref LL_EXTI_LINE_17 + * @arg @ref LL_EXTI_LINE_18 + * @arg @ref LL_EXTI_LINE_19 + * @arg @ref LL_EXTI_LINE_20 + * @arg @ref LL_EXTI_LINE_21 + * @arg @ref LL_EXTI_LINE_22 + * @arg @ref LL_EXTI_LINE_23 + * @arg @ref LL_EXTI_LINE_24 + * @arg @ref LL_EXTI_LINE_25 + * @arg @ref LL_EXTI_LINE_26 + * @arg @ref LL_EXTI_LINE_27 + * @arg @ref LL_EXTI_LINE_28 + * @arg @ref LL_EXTI_LINE_29 + * @arg @ref LL_EXTI_LINE_30 + * @arg @ref LL_EXTI_LINE_31 + * @arg @ref LL_EXTI_LINE_ALL_0_31 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ +__STATIC_INLINE void LL_EXTI_EnablePrivilege_0_31(uint32_t ExtiLine) +{ + SET_BIT(EXTI->PRIVCFGR1, ExtiLine); +} + +/** + * @brief Enable ExtiLine Privilege attribute for Lines in range 32 to 63 + * @rmtoll PRIVCFGR2 PRIVx LL_EXTI_EnablePrivilege_32_63 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_32 + * @arg @ref LL_EXTI_LINE_33 + * @arg @ref LL_EXTI_LINE_34 + * @arg @ref LL_EXTI_LINE_35 + * @arg @ref LL_EXTI_LINE_36 + * @arg @ref LL_EXTI_LINE_37 + * @arg @ref LL_EXTI_LINE_38 + * @arg @ref LL_EXTI_LINE_39 + * @arg @ref LL_EXTI_LINE_40 + * @arg @ref LL_EXTI_LINE_41 + * @arg @ref LL_EXTI_LINE_42 + * @arg @ref LL_EXTI_LINE_43 + * @arg @ref LL_EXTI_LINE_44 + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_47 + * @arg @ref LL_EXTI_LINE_48 + * @arg @ref LL_EXTI_LINE_49 + * @arg @ref LL_EXTI_LINE_50 + * @arg @ref LL_EXTI_LINE_51 + * @arg @ref LL_EXTI_LINE_52 + * @arg @ref LL_EXTI_LINE_53 + * @arg @ref LL_EXTI_LINE_54 + * @arg @ref LL_EXTI_LINE_55 + * @arg @ref LL_EXTI_LINE_56 + * @arg @ref LL_EXTI_LINE_57 (*) + * @arg @ref LL_EXTI_LINE_ALL_32_63 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ +__STATIC_INLINE void LL_EXTI_EnablePrivilege_32_63(uint32_t ExtiLine) +{ + SET_BIT(EXTI->PRIVCFGR2, ExtiLine); +} + +/** + * @brief Disable ExtiLine Privilege attribute for Lines in range 0 to 31 + * @rmtoll PRIVCFGR1 PRIVx LL_EXTI_DisablePrivilege_0_31 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @arg @ref LL_EXTI_LINE_17 + * @arg @ref LL_EXTI_LINE_18 + * @arg @ref LL_EXTI_LINE_19 + * @arg @ref LL_EXTI_LINE_20 + * @arg @ref LL_EXTI_LINE_21 + * @arg @ref LL_EXTI_LINE_22 + * @arg @ref LL_EXTI_LINE_23 + * @arg @ref LL_EXTI_LINE_24 + * @arg @ref LL_EXTI_LINE_25 + * @arg @ref LL_EXTI_LINE_26 + * @arg @ref LL_EXTI_LINE_27 + * @arg @ref LL_EXTI_LINE_28 + * @arg @ref LL_EXTI_LINE_29 + * @arg @ref LL_EXTI_LINE_30 + * @arg @ref LL_EXTI_LINE_31 + * @arg @ref LL_EXTI_LINE_ALL_0_31 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ +__STATIC_INLINE void LL_EXTI_DisablePrivilege_0_31(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->PRIVCFGR1, ExtiLine); +} + +/** + * @brief Disable ExtiLine Privilege attribute for Lines in range 32 to 63 + * @rmtoll PRIVCFGR2 PRIVx LL_EXTI_EnablePrivilege_32_63 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_32 + * @arg @ref LL_EXTI_LINE_33 + * @arg @ref LL_EXTI_LINE_34 + * @arg @ref LL_EXTI_LINE_35 + * @arg @ref LL_EXTI_LINE_36 + * @arg @ref LL_EXTI_LINE_37 + * @arg @ref LL_EXTI_LINE_38 + * @arg @ref LL_EXTI_LINE_39 + * @arg @ref LL_EXTI_LINE_40 + * @arg @ref LL_EXTI_LINE_41 + * @arg @ref LL_EXTI_LINE_42 + * @arg @ref LL_EXTI_LINE_43 + * @arg @ref LL_EXTI_LINE_44 + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_47 + * @arg @ref LL_EXTI_LINE_48 + * @arg @ref LL_EXTI_LINE_49 + * @arg @ref LL_EXTI_LINE_50 + * @arg @ref LL_EXTI_LINE_51 + * @arg @ref LL_EXTI_LINE_52 + * @arg @ref LL_EXTI_LINE_53 + * @arg @ref LL_EXTI_LINE_54 + * @arg @ref LL_EXTI_LINE_55 + * @arg @ref LL_EXTI_LINE_56 + * @arg @ref LL_EXTI_LINE_57 (*) + * @arg @ref LL_EXTI_LINE_ALL_32_63 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ +__STATIC_INLINE void LL_EXTI_DisablePrivilege_32_63(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->PRIVCFGR2, ExtiLine); +} + +/** + * @brief Indicate if ExtiLine Privilege attribute is enabled for Lines in range 0 to 31 + * @rmtoll PRIVCFGR1 PRIVx LL_EXTI_IsEnabledPrivilege_0_31 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @arg @ref LL_EXTI_LINE_17 + * @arg @ref LL_EXTI_LINE_18 + * @arg @ref LL_EXTI_LINE_19 + * @arg @ref LL_EXTI_LINE_20 + * @arg @ref LL_EXTI_LINE_21 + * @arg @ref LL_EXTI_LINE_22 + * @arg @ref LL_EXTI_LINE_23 + * @arg @ref LL_EXTI_LINE_24 + * @arg @ref LL_EXTI_LINE_25 + * @arg @ref LL_EXTI_LINE_26 + * @arg @ref LL_EXTI_LINE_27 + * @arg @ref LL_EXTI_LINE_28 + * @arg @ref LL_EXTI_LINE_29 + * @arg @ref LL_EXTI_LINE_30 + * @arg @ref LL_EXTI_LINE_31 + * @arg @ref LL_EXTI_LINE_ALL_0_31 + * @note Please check each device line mapping for EXTI Line availability + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_EXTI_IsEnabledPrivilege_0_31(uint32_t ExtiLine) +{ + return ((READ_BIT(EXTI->PRIVCFGR1, ExtiLine) == (ExtiLine)) ? 1UL : 0UL); +} + +/** + * @brief Indicate if ExtiLine Privilege attribute is enabled for Lines in range 32 to 63 + * @rmtoll PRIVCFGR2 PRIVx LL_EXTI_IsEnabledPrivilege_32_63 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_32 + * @arg @ref LL_EXTI_LINE_33 + * @arg @ref LL_EXTI_LINE_34 + * @arg @ref LL_EXTI_LINE_35 + * @arg @ref LL_EXTI_LINE_36 + * @arg @ref LL_EXTI_LINE_37 + * @arg @ref LL_EXTI_LINE_38 + * @arg @ref LL_EXTI_LINE_39 + * @arg @ref LL_EXTI_LINE_40 + * @arg @ref LL_EXTI_LINE_41 + * @arg @ref LL_EXTI_LINE_42 + * @arg @ref LL_EXTI_LINE_43 + * @arg @ref LL_EXTI_LINE_44 + * @arg @ref LL_EXTI_LINE_46 + * @arg @ref LL_EXTI_LINE_47 + * @arg @ref LL_EXTI_LINE_48 + * @arg @ref LL_EXTI_LINE_49 + * @arg @ref LL_EXTI_LINE_50 + * @arg @ref LL_EXTI_LINE_51 + * @arg @ref LL_EXTI_LINE_52 + * @arg @ref LL_EXTI_LINE_53 + * @arg @ref LL_EXTI_LINE_54 + * @arg @ref LL_EXTI_LINE_55 + * @arg @ref LL_EXTI_LINE_56 + * @arg @ref LL_EXTI_LINE_57 (*) + * @arg @ref LL_EXTI_LINE_ALL_32_63 + * @note Please check each device line mapping for EXTI Line availability + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_EXTI_IsEnabledPrivilege_32_63(uint32_t ExtiLine) +{ + return ((READ_BIT(EXTI->PRIVCFGR2, ExtiLine) == (ExtiLine)) ? 1UL : 0UL); +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Enable the EXTI lock attributes. + * @rmtoll LOCKR LOCK LL_EXTI_EnableLockAttribute + * @retval None. + */ +__STATIC_INLINE void LL_EXTI_EnableLockAttribute(void) +{ + SET_BIT(EXTI->LOCKR, EXTI_LOCKR_LOCK); +} + +/** + * @brief Check if EXTI attributes are locked. + * @rmtoll LOCKR LOCK LL_EXTI_IsEnabledLockAttribute + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_EXTI_IsEnabledLockAttribute(void) +{ + return ((READ_BIT(EXTI->LOCKR, EXTI_LOCKR_LOCK) == EXTI_LOCKR_LOCK) ? 1UL : 0UL); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup EXTI_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +ErrorStatus LL_EXTI_Init(LL_EXTI_InitTypeDef *EXTI_InitStruct); +ErrorStatus LL_EXTI_DeInit(void); +void LL_EXTI_StructInit(LL_EXTI_InitTypeDef *EXTI_InitStruct); + + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* EXTI */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_LL_EXTI_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_fmac.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_fmac.h new file mode 100644 index 0000000000..bc5b4edf40 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_fmac.h @@ -0,0 +1,1069 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_fmac.h + * @author MCD Application Team + * @brief Header file of FMAC LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_LL_FMAC_H +#define STM32H5xx_LL_FMAC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined(FMAC) + +/** @defgroup FMAC_LL FMAC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup FMAC_LL_Exported_Constants FMAC Exported Constants + * @{ + */ + +/** @defgroup FMAC_LL_EC_GET_FLAG Get Flag Defines + * @brief Flag defines which can be used with LL_FMAC_ReadReg function + * @{ + */ +#define LL_FMAC_SR_SAT FMAC_SR_SAT /*!< Saturation Error Flag + (this helps in debugging a filter) */ +#define LL_FMAC_SR_UNFL FMAC_SR_UNFL /*!< Underflow Error Flag */ +#define LL_FMAC_SR_OVFL FMAC_SR_OVFL /*!< Overflow Error Flag */ +#define LL_FMAC_SR_X1FULL FMAC_SR_X1FULL /*!< X1 Buffer Full Flag */ +#define LL_FMAC_SR_YEMPTY FMAC_SR_YEMPTY /*!< Y Buffer Empty Flag */ +/** + * @} + */ + +/** @defgroup FMAC_LL_EC_IT IT Defines + * @brief IT defines which can be used with LL_FMAC_ReadReg and LL_FMAC_WriteReg functions + * @{ + */ +#define LL_FMAC_CR_SATIEN FMAC_CR_SATIEN /*!< Saturation Error Interrupt Enable + (this helps in debugging a filter) */ +#define LL_FMAC_CR_UNFLIEN FMAC_CR_UNFLIEN /*!< Underflow Error Interrupt Enable */ +#define LL_FMAC_CR_OVFLIEN FMAC_CR_OVFLIEN /*!< Overflow Error Interrupt Enable */ +#define LL_FMAC_CR_WIEN FMAC_CR_WIEN /*!< Write Interrupt Enable */ +#define LL_FMAC_CR_RIEN FMAC_CR_RIEN /*!< Read Interrupt Enable */ +/** + * @} + */ + +/** @defgroup FMAC_LL_EC_WM FMAC watermarks + * @brief Watermark defines that can be used for buffer full (input) or buffer empty (output) + * @{ + */ +#define LL_FMAC_WM_0_THRESHOLD_1 0x00000000U /*!< Buffer full/empty flag set if there + is less than 1 free/unread space. */ +#define LL_FMAC_WM_1_THRESHOLD_2 0x01000000U /*!< Buffer full/empty flag set if there + are less than 2 free/unread spaces. */ +#define LL_FMAC_WM_2_THRESHOLD_4 0x02000000U /*!< Buffer full/empty flag set if there + are less than 4 free/unread spaces. */ +#define LL_FMAC_WM_3_THRESHOLD_8 0x03000000U /*!< Buffer full/empty flag set if there + are less than 8 free/empty spaces. */ +/** + * @} + */ + +/** @defgroup FMAC_LL_EC_FUNC FMAC functions + * @{ + */ +#define LL_FMAC_FUNC_LOAD_X1 (FMAC_PARAM_FUNC_0) /*!< Load X1 buffer */ +#define LL_FMAC_FUNC_LOAD_X2 (FMAC_PARAM_FUNC_1) /*!< Load X2 buffer */ +#define LL_FMAC_FUNC_LOAD_Y (FMAC_PARAM_FUNC_1 | FMAC_PARAM_FUNC_0) /*!< Load Y buffer */ +#define LL_FMAC_FUNC_CONVO_FIR (FMAC_PARAM_FUNC_3) /*!< Convolution (FIR filter) */ +#define LL_FMAC_FUNC_IIR_DIRECT_FORM_1 (FMAC_PARAM_FUNC_3 | FMAC_PARAM_FUNC_0) /*!< IIR filter (direct form 1) */ +/** + * @} + */ + +/** @defgroup FMAC_LL_EC_PROCESSING FMAC processing + * @{ + */ +#define LL_FMAC_PROCESSING_STOP 0x00U /*!< Stop FMAC Processing */ +#define LL_FMAC_PROCESSING_START 0x01U /*!< Start FMAC Processing */ +/** + * @} + */ + +/** + * @} + */ + +/* External variables --------------------------------------------------------*/ +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup FMAC_LL_Exported_Macros FMAC Exported Macros + * @{ + */ + +/** @defgroup FMAC_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in FMAC register + * @param __INSTANCE__ FMAC Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_FMAC_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in FMAC register + * @param __INSTANCE__ FMAC Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_FMAC_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) +/** + * @} + */ + +/** + * @} + */ + + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup FMAC_LL_Exported_Functions FMAC Exported Functions + * @{ + */ + +/** @defgroup FMAC_LL_EF_Configuration FMAC Configuration functions + * @{ + */ + +/** + * @brief Configure X1 full watermark. + * @rmtoll X1BUFCFG FULL_WM LL_FMAC_SetX1FullWatermark + * @param FMACx FMAC instance + * @param Watermark This parameter can be one of the following values: + * @arg @ref LL_FMAC_WM_0_THRESHOLD_1 + * @arg @ref LL_FMAC_WM_1_THRESHOLD_2 + * @arg @ref LL_FMAC_WM_2_THRESHOLD_4 + * @arg @ref LL_FMAC_WM_3_THRESHOLD_8 + * @retval None + */ +__STATIC_INLINE void LL_FMAC_SetX1FullWatermark(FMAC_TypeDef *FMACx, uint32_t Watermark) +{ + MODIFY_REG(FMACx->X1BUFCFG, FMAC_X1BUFCFG_FULL_WM, Watermark); +} + +/** + * @brief Return X1 full watermark. + * @rmtoll X1BUFCFG FULL_WM LL_FMAC_GetX1FullWatermark + * @param FMACx FMAC instance + * @retval uint32_t Returned value can be one of the following values: + * @arg @ref LL_FMAC_WM_0_THRESHOLD_1 + * @arg @ref LL_FMAC_WM_1_THRESHOLD_2 + * @arg @ref LL_FMAC_WM_2_THRESHOLD_4 + * @arg @ref LL_FMAC_WM_3_THRESHOLD_8 + */ +__STATIC_INLINE uint32_t LL_FMAC_GetX1FullWatermark(const FMAC_TypeDef *FMACx) +{ + return (uint32_t)(READ_BIT(FMACx->X1BUFCFG, FMAC_X1BUFCFG_FULL_WM)); +} + +/** + * @brief Configure X1 buffer size. + * @rmtoll X1BUFCFG X1_BUF_SIZE LL_FMAC_SetX1BufferSize + * @param FMACx FMAC instance + * @param BufferSize Number of 16-bit words allocated to the input buffer (including the optional "headroom"). + * This parameter must be a number between Min_Data=0x01 and Max_Data=0xFF. + * @retval None + */ +__STATIC_INLINE void LL_FMAC_SetX1BufferSize(FMAC_TypeDef *FMACx, uint8_t BufferSize) +{ + MODIFY_REG(FMACx->X1BUFCFG, FMAC_X1BUFCFG_X1_BUF_SIZE, ((uint32_t)BufferSize) << FMAC_X1BUFCFG_X1_BUF_SIZE_Pos); +} + +/** + * @brief Return X1 buffer size. + * @rmtoll X1BUFCFG X1_BUF_SIZE LL_FMAC_GetX1BufferSize + * @param FMACx FMAC instance + * @retval uint8_t Number of 16-bit words allocated to the input buffer + * (including the optional "headroom") (value between Min_Data=0x01 and Max_Data=0xFF). + */ +__STATIC_INLINE uint8_t LL_FMAC_GetX1BufferSize(const FMAC_TypeDef *FMACx) +{ + return (uint8_t)(READ_BIT(FMACx->X1BUFCFG, FMAC_X1BUFCFG_X1_BUF_SIZE) >> FMAC_X1BUFCFG_X1_BUF_SIZE_Pos); +} + +/** + * @brief Configure X1 base. + * @rmtoll X1BUFCFG X1_BASE LL_FMAC_SetX1Base + * @param FMACx FMAC instance + * @param Base Base address of the input buffer (X1) within the internal memory. + * This parameter must be a value between Min_Data=0x00 and Max_Data=0xFF. + * @retval None + */ +__STATIC_INLINE void LL_FMAC_SetX1Base(FMAC_TypeDef *FMACx, uint8_t Base) +{ + MODIFY_REG(FMACx->X1BUFCFG, FMAC_X1BUFCFG_X1_BASE, ((uint32_t)Base) << FMAC_X1BUFCFG_X1_BASE_Pos); +} + +/** + * @brief Return X1 base. + * @rmtoll X1BUFCFG X1_BASE LL_FMAC_GetX1Base + * @param FMACx FMAC instance + * @retval uint8_t Base address of the input buffer (X1) within the internal memory + * (value between Min_Data=0x00 and Max_Data=0xFF). + */ +__STATIC_INLINE uint8_t LL_FMAC_GetX1Base(const FMAC_TypeDef *FMACx) +{ + return (uint8_t)(READ_BIT(FMACx->X1BUFCFG, FMAC_X1BUFCFG_X1_BASE) >> FMAC_X1BUFCFG_X1_BASE_Pos); +} + +/** + * @brief Configure X2 buffer size. + * @rmtoll X2BUFCFG X2_BUF_SIZE LL_FMAC_SetX2BufferSize + * @param FMACx FMAC instance + * @param BufferSize Number of 16-bit words allocated to the coefficient buffer. + * This parameter must be a number between Min_Data=0x01 and Max_Data=0xFF. + * @retval None + */ +__STATIC_INLINE void LL_FMAC_SetX2BufferSize(FMAC_TypeDef *FMACx, uint8_t BufferSize) +{ + MODIFY_REG(FMACx->X2BUFCFG, FMAC_X2BUFCFG_X2_BUF_SIZE, ((uint32_t)BufferSize) << FMAC_X2BUFCFG_X2_BUF_SIZE_Pos); +} + +/** + * @brief Return X2 buffer size. + * @rmtoll X2BUFCFG X2_BUF_SIZE LL_FMAC_GetX2BufferSize + * @param FMACx FMAC instance + * @retval uint8_t Number of 16-bit words allocated to the coefficient buffer + * (value between Min_Data=0x01 and Max_Data=0xFF). + */ +__STATIC_INLINE uint8_t LL_FMAC_GetX2BufferSize(const FMAC_TypeDef *FMACx) +{ + return (uint8_t)(READ_BIT(FMACx->X2BUFCFG, FMAC_X2BUFCFG_X2_BUF_SIZE) >> FMAC_X2BUFCFG_X2_BUF_SIZE_Pos); +} + +/** + * @brief Configure X2 base. + * @rmtoll X2BUFCFG X2_BASE LL_FMAC_SetX2Base + * @param FMACx FMAC instance + * @param Base Base address of the coefficient buffer (X2) within the internal memory. + * This parameter must be a value between Min_Data=0x00 and Max_Data=0xFF. + * @retval None + */ +__STATIC_INLINE void LL_FMAC_SetX2Base(FMAC_TypeDef *FMACx, uint8_t Base) +{ + MODIFY_REG(FMACx->X2BUFCFG, FMAC_X2BUFCFG_X2_BASE, ((uint32_t)Base) << FMAC_X2BUFCFG_X2_BASE_Pos); +} + +/** + * @brief Return X2 base. + * @rmtoll X2BUFCFG X2_BASE LL_FMAC_GetX2Base + * @param FMACx FMAC instance + * @retval uint8_t Base address of the coefficient buffer (X2) within the internal memory + * (value between Min_Data=0x00 and Max_Data=0xFF). + */ +__STATIC_INLINE uint8_t LL_FMAC_GetX2Base(const FMAC_TypeDef *FMACx) +{ + return (uint8_t)(READ_BIT(FMACx->X2BUFCFG, FMAC_X2BUFCFG_X2_BASE) >> FMAC_X2BUFCFG_X2_BASE_Pos); +} + +/** + * @brief Configure Y empty watermark. + * @rmtoll YBUFCFG EMPTY_WM LL_FMAC_SetYEmptyWatermark + * @param FMACx FMAC instance + * @param Watermark This parameter can be one of the following values: + * @arg @ref LL_FMAC_WM_0_THRESHOLD_1 + * @arg @ref LL_FMAC_WM_1_THRESHOLD_2 + * @arg @ref LL_FMAC_WM_2_THRESHOLD_4 + * @arg @ref LL_FMAC_WM_3_THRESHOLD_8 + * @retval None + */ +__STATIC_INLINE void LL_FMAC_SetYEmptyWatermark(FMAC_TypeDef *FMACx, uint32_t Watermark) +{ + MODIFY_REG(FMACx->YBUFCFG, FMAC_YBUFCFG_EMPTY_WM, Watermark); +} + +/** + * @brief Return Y empty watermark. + * @rmtoll YBUFCFG EMPTY_WM LL_FMAC_GetYEmptyWatermark + * @param FMACx FMAC instance + * @retval uint32_t Returned value can be one of the following values: + * @arg @ref LL_FMAC_WM_0_THRESHOLD_1 + * @arg @ref LL_FMAC_WM_1_THRESHOLD_2 + * @arg @ref LL_FMAC_WM_2_THRESHOLD_4 + * @arg @ref LL_FMAC_WM_3_THRESHOLD_8 + */ +__STATIC_INLINE uint32_t LL_FMAC_GetYEmptyWatermark(const FMAC_TypeDef *FMACx) +{ + return (uint32_t)(READ_BIT(FMACx->YBUFCFG, FMAC_YBUFCFG_EMPTY_WM)); +} + +/** + * @brief Configure Y buffer size. + * @rmtoll YBUFCFG Y_BUF_SIZE LL_FMAC_SetYBufferSize + * @param FMACx FMAC instance + * @param BufferSize Number of 16-bit words allocated to the output buffer (including the optional "headroom"). + * This parameter must be a number between Min_Data=0x01 and Max_Data=0xFF. + * @retval None + */ +__STATIC_INLINE void LL_FMAC_SetYBufferSize(FMAC_TypeDef *FMACx, uint8_t BufferSize) +{ + MODIFY_REG(FMACx->YBUFCFG, FMAC_YBUFCFG_Y_BUF_SIZE, ((uint32_t)BufferSize) << FMAC_YBUFCFG_Y_BUF_SIZE_Pos); +} + +/** + * @brief Return Y buffer size. + * @rmtoll YBUFCFG Y_BUF_SIZE LL_FMAC_GetYBufferSize + * @param FMACx FMAC instance + * @retval uint8_t Number of 16-bit words allocated to the output buffer + * (including the optional "headroom" - value between Min_Data=0x01 and Max_Data=0xFF). + */ +__STATIC_INLINE uint8_t LL_FMAC_GetYBufferSize(const FMAC_TypeDef *FMACx) +{ + return (uint8_t)(READ_BIT(FMACx->YBUFCFG, FMAC_YBUFCFG_Y_BUF_SIZE) >> FMAC_YBUFCFG_Y_BUF_SIZE_Pos); +} + +/** + * @brief Configure Y base. + * @rmtoll YBUFCFG Y_BASE LL_FMAC_SetYBase + * @param FMACx FMAC instance + * @param Base Base address of the output buffer (Y) within the internal memory. + * This parameter must be a value between Min_Data=0x00 and Max_Data=0xFF. + * @retval None + */ +__STATIC_INLINE void LL_FMAC_SetYBase(FMAC_TypeDef *FMACx, uint8_t Base) +{ + MODIFY_REG(FMACx->YBUFCFG, FMAC_YBUFCFG_Y_BASE, ((uint32_t)Base) << FMAC_YBUFCFG_Y_BASE_Pos); +} + +/** + * @brief Return Y base. + * @rmtoll YBUFCFG Y_BASE LL_FMAC_GetYBase + * @param FMACx FMAC instance + * @retval uint8_t Base address of the output buffer (Y) within the internal memory + * (value between Min_Data=0x00 and Max_Data=0xFF). + */ +__STATIC_INLINE uint8_t LL_FMAC_GetYBase(const FMAC_TypeDef *FMACx) +{ + return (uint8_t)(READ_BIT(FMACx->YBUFCFG, FMAC_YBUFCFG_Y_BASE) >> FMAC_YBUFCFG_Y_BASE_Pos); +} + +/** + * @brief Start FMAC processing. + * @rmtoll PARAM START LL_FMAC_EnableStart + * @param FMACx FMAC instance + * @retval None + */ +__STATIC_INLINE void LL_FMAC_EnableStart(FMAC_TypeDef *FMACx) +{ + SET_BIT(FMACx->PARAM, FMAC_PARAM_START); +} + +/** + * @brief Stop FMAC processing. + * @rmtoll PARAM START LL_FMAC_DisableStart + * @param FMACx FMAC instance + * @retval None + */ +__STATIC_INLINE void LL_FMAC_DisableStart(FMAC_TypeDef *FMACx) +{ + CLEAR_BIT(FMACx->PARAM, FMAC_PARAM_START); +} + +/** + * @brief Check the state of FMAC processing. + * @rmtoll PARAM START LL_FMAC_IsEnabledStart + * @param FMACx FMAC instance + * @retval uint32_t State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_FMAC_IsEnabledStart(const FMAC_TypeDef *FMACx) +{ + return ((READ_BIT(FMACx->PARAM, FMAC_PARAM_START) == (FMAC_PARAM_START)) ? 1UL : 0UL); +} + +/** + * @brief Configure function. + * @rmtoll PARAM FUNC LL_FMAC_SetFunction + * @param FMACx FMAC instance + * @param Function This parameter can be one of the following values: + * @arg @ref LL_FMAC_FUNC_LOAD_X1 + * @arg @ref LL_FMAC_FUNC_LOAD_X2 + * @arg @ref LL_FMAC_FUNC_LOAD_Y + * @arg @ref LL_FMAC_FUNC_CONVO_FIR + * @arg @ref LL_FMAC_FUNC_IIR_DIRECT_FORM_1 + * @retval None + */ +__STATIC_INLINE void LL_FMAC_SetFunction(FMAC_TypeDef *FMACx, uint32_t Function) +{ + MODIFY_REG(FMACx->PARAM, FMAC_PARAM_FUNC, Function); +} + +/** + * @brief Return function. + * @rmtoll PARAM FUNC LL_FMAC_GetFunction + * @param FMACx FMAC instance + * @retval uint32_t Returned value can be one of the following values: + * @arg @ref LL_FMAC_FUNC_LOAD_X1 + * @arg @ref LL_FMAC_FUNC_LOAD_X2 + * @arg @ref LL_FMAC_FUNC_LOAD_Y + * @arg @ref LL_FMAC_FUNC_CONVO_FIR + * @arg @ref LL_FMAC_FUNC_IIR_DIRECT_FORM_1 + */ +__STATIC_INLINE uint32_t LL_FMAC_GetFunction(const FMAC_TypeDef *FMACx) +{ + return (uint32_t)(READ_BIT(FMACx->PARAM, FMAC_PARAM_FUNC)); +} + +/** + * @brief Configure input parameter R. + * @rmtoll PARAM R LL_FMAC_SetParamR + * @param FMACx FMAC instance + * @param Param Parameter R (gain, etc.). + * This parameter must be a value between Min_Data=0x00 and Max_Data=0xFF. + * @retval None + */ +__STATIC_INLINE void LL_FMAC_SetParamR(FMAC_TypeDef *FMACx, uint8_t Param) +{ + MODIFY_REG(FMACx->PARAM, FMAC_PARAM_R, ((uint32_t)Param) << FMAC_PARAM_R_Pos); +} + +/** + * @brief Return input parameter R. + * @rmtoll PARAM R LL_FMAC_GetParamR + * @param FMACx FMAC instance + * @retval uint8_t Parameter R (gain, etc.) (value between Min_Data=0x00 and Max_Data=0xFF). + */ +__STATIC_INLINE uint8_t LL_FMAC_GetParamR(const FMAC_TypeDef *FMACx) +{ + return (uint8_t)(READ_BIT(FMACx->PARAM, FMAC_PARAM_R) >> FMAC_PARAM_R_Pos); +} + +/** + * @brief Configure input parameter Q. + * @rmtoll PARAM Q LL_FMAC_SetParamQ + * @param FMACx FMAC instance + * @param Param Parameter Q (vector length, etc.). + * This parameter must be a value between Min_Data=0x00 and Max_Data=0xFF. + * @retval None + */ +__STATIC_INLINE void LL_FMAC_SetParamQ(FMAC_TypeDef *FMACx, uint8_t Param) +{ + MODIFY_REG(FMACx->PARAM, FMAC_PARAM_Q, ((uint32_t)Param) << FMAC_PARAM_Q_Pos); +} + +/** + * @brief Return input parameter Q. + * @rmtoll PARAM Q LL_FMAC_GetParamQ + * @param FMACx FMAC instance + * @retval uint8_t Parameter Q (vector length, etc.) (value between Min_Data=0x00 and Max_Data=0xFF). + */ +__STATIC_INLINE uint8_t LL_FMAC_GetParamQ(const FMAC_TypeDef *FMACx) +{ + return (uint8_t)(READ_BIT(FMACx->PARAM, FMAC_PARAM_Q) >> FMAC_PARAM_Q_Pos); +} + +/** + * @brief Configure input parameter P. + * @rmtoll PARAM P LL_FMAC_SetParamP + * @param FMACx FMAC instance + * @param Param Parameter P (vector length, number of filter taps, etc.). + * This parameter must be a value between Min_Data=0x00 and Max_Data=0xFF. + * @retval None + */ +__STATIC_INLINE void LL_FMAC_SetParamP(FMAC_TypeDef *FMACx, uint8_t Param) +{ + MODIFY_REG(FMACx->PARAM, FMAC_PARAM_P, ((uint32_t)Param)); +} + +/** + * @brief Return input parameter P. + * @rmtoll PARAM P LL_FMAC_GetParamP + * @param FMACx FMAC instance + * @retval uint8_t Parameter P (vector length, number of filter taps, etc.) + * (value between Min_Data=0x00 and Max_Data=0xFF). + */ +__STATIC_INLINE uint8_t LL_FMAC_GetParamP(const FMAC_TypeDef *FMACx) +{ + return (uint8_t)(READ_BIT(FMACx->PARAM, FMAC_PARAM_P)); +} + +/** + * @} + */ + +/** @defgroup FMAC_LL_EF_Reset_Management Reset_Management + * @{ + */ + +/** + * @brief Start the FMAC reset. + * @rmtoll CR RESET LL_FMAC_EnableReset + * @param FMACx FMAC instance + * @retval None + */ +__STATIC_INLINE void LL_FMAC_EnableReset(FMAC_TypeDef *FMACx) +{ + SET_BIT(FMACx->CR, FMAC_CR_RESET); +} + +/** + * @brief Check the state of the FMAC reset. + * @rmtoll CR RESET LL_FMAC_IsEnabledReset + * @param FMACx FMAC instance + * @retval uint32_t State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_FMAC_IsEnabledReset(const FMAC_TypeDef *FMACx) +{ + return ((READ_BIT(FMACx->CR, FMAC_CR_RESET) == (FMAC_CR_RESET)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup FMAC_LL_EF_Configuration FMAC Configuration functions + * @{ + */ + +/** + * @brief Enable Clipping. + * @rmtoll CR CLIPEN LL_FMAC_EnableClipping + * @param FMACx FMAC instance + * @retval None + */ +__STATIC_INLINE void LL_FMAC_EnableClipping(FMAC_TypeDef *FMACx) +{ + SET_BIT(FMACx->CR, FMAC_CR_CLIPEN); +} + +/** + * @brief Disable Clipping. + * @rmtoll CR CLIPEN LL_FMAC_DisableClipping + * @param FMACx FMAC instance + * @retval None + */ +__STATIC_INLINE void LL_FMAC_DisableClipping(FMAC_TypeDef *FMACx) +{ + CLEAR_BIT(FMACx->CR, FMAC_CR_CLIPEN); +} + +/** + * @brief Check Clipping State. + * @rmtoll CR CLIPEN LL_FMAC_IsEnabledClipping + * @param FMACx FMAC instance + * @retval uint32_t State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_FMAC_IsEnabledClipping(const FMAC_TypeDef *FMACx) +{ + return ((READ_BIT(FMACx->CR, FMAC_CR_CLIPEN) == (FMAC_CR_CLIPEN)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup FMAC_LL_EF_DMA_Management DMA_Management + * @{ + */ + +/** + * @brief Enable FMAC DMA write channel request. + * @rmtoll CR DMAWEN LL_FMAC_EnableDMAReq_WRITE + * @param FMACx FMAC instance + * @retval None + */ +__STATIC_INLINE void LL_FMAC_EnableDMAReq_WRITE(FMAC_TypeDef *FMACx) +{ + SET_BIT(FMACx->CR, FMAC_CR_DMAWEN); +} + +/** + * @brief Disable FMAC DMA write channel request. + * @rmtoll CR DMAWEN LL_FMAC_DisableDMAReq_WRITE + * @param FMACx FMAC instance + * @retval None + */ +__STATIC_INLINE void LL_FMAC_DisableDMAReq_WRITE(FMAC_TypeDef *FMACx) +{ + CLEAR_BIT(FMACx->CR, FMAC_CR_DMAWEN); +} + +/** + * @brief Check FMAC DMA write channel request state. + * @rmtoll CR DMAWEN LL_FMAC_IsEnabledDMAReq_WRITE + * @param FMACx FMAC instance + * @retval uint32_t State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_FMAC_IsEnabledDMAReq_WRITE(const FMAC_TypeDef *FMACx) +{ + return ((READ_BIT(FMACx->CR, FMAC_CR_DMAWEN) == (FMAC_CR_DMAWEN)) ? 1UL : 0UL); +} + +/** + * @brief Enable FMAC DMA read channel request. + * @rmtoll CR DMAREN LL_FMAC_EnableDMAReq_READ + * @param FMACx FMAC instance + * @retval None + */ +__STATIC_INLINE void LL_FMAC_EnableDMAReq_READ(FMAC_TypeDef *FMACx) +{ + SET_BIT(FMACx->CR, FMAC_CR_DMAREN); +} + +/** + * @brief Disable FMAC DMA read channel request. + * @rmtoll CR DMAREN LL_FMAC_DisableDMAReq_READ + * @param FMACx FMAC instance + * @retval None + */ +__STATIC_INLINE void LL_FMAC_DisableDMAReq_READ(FMAC_TypeDef *FMACx) +{ + CLEAR_BIT(FMACx->CR, FMAC_CR_DMAREN); +} + +/** + * @brief Check FMAC DMA read channel request state. + * @rmtoll CR DMAREN LL_FMAC_IsEnabledDMAReq_READ + * @param FMACx FMAC instance + * @retval uint32_t State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_FMAC_IsEnabledDMAReq_READ(const FMAC_TypeDef *FMACx) +{ + return ((READ_BIT(FMACx->CR, FMAC_CR_DMAREN) == (FMAC_CR_DMAREN)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup FMAC_LL_EF_IT_Management IT_Management + * @{ + */ + +/** + * @brief Enable FMAC saturation error interrupt. + * @rmtoll CR SATIEN LL_FMAC_EnableIT_SAT + * @param FMACx FMAC instance + * @retval None + */ +__STATIC_INLINE void LL_FMAC_EnableIT_SAT(FMAC_TypeDef *FMACx) +{ + SET_BIT(FMACx->CR, FMAC_CR_SATIEN); +} + +/** + * @brief Disable FMAC saturation error interrupt. + * @rmtoll CR SATIEN LL_FMAC_DisableIT_SAT + * @param FMACx FMAC instance + * @retval None + */ +__STATIC_INLINE void LL_FMAC_DisableIT_SAT(FMAC_TypeDef *FMACx) +{ + CLEAR_BIT(FMACx->CR, FMAC_CR_SATIEN); +} + +/** + * @brief Check FMAC saturation error interrupt state. + * @rmtoll CR SATIEN LL_FMAC_IsEnabledIT_SAT + * @param FMACx FMAC instance + * @retval uint32_t State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_FMAC_IsEnabledIT_SAT(const FMAC_TypeDef *FMACx) +{ + return ((READ_BIT(FMACx->CR, FMAC_CR_SATIEN) == (FMAC_CR_SATIEN)) ? 1UL : 0UL); +} + +/** + * @brief Enable FMAC underflow error interrupt. + * @rmtoll CR UNFLIEN LL_FMAC_EnableIT_UNFL + * @param FMACx FMAC instance + * @retval None + */ +__STATIC_INLINE void LL_FMAC_EnableIT_UNFL(FMAC_TypeDef *FMACx) +{ + SET_BIT(FMACx->CR, FMAC_CR_UNFLIEN); +} + +/** + * @brief Disable FMAC underflow error interrupt. + * @rmtoll CR UNFLIEN LL_FMAC_DisableIT_UNFL + * @param FMACx FMAC instance + * @retval None + */ +__STATIC_INLINE void LL_FMAC_DisableIT_UNFL(FMAC_TypeDef *FMACx) +{ + CLEAR_BIT(FMACx->CR, FMAC_CR_UNFLIEN); +} + +/** + * @brief Check FMAC underflow error interrupt state. + * @rmtoll CR UNFLIEN LL_FMAC_IsEnabledIT_UNFL + * @param FMACx FMAC instance + * @retval uint32_t State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_FMAC_IsEnabledIT_UNFL(const FMAC_TypeDef *FMACx) +{ + return ((READ_BIT(FMACx->CR, FMAC_CR_UNFLIEN) == (FMAC_CR_UNFLIEN)) ? 1UL : 0UL); +} + +/** + * @brief Enable FMAC overflow error interrupt. + * @rmtoll CR OVFLIEN LL_FMAC_EnableIT_OVFL + * @param FMACx FMAC instance + * @retval None + */ +__STATIC_INLINE void LL_FMAC_EnableIT_OVFL(FMAC_TypeDef *FMACx) +{ + SET_BIT(FMACx->CR, FMAC_CR_OVFLIEN); +} + +/** + * @brief Disable FMAC overflow error interrupt. + * @rmtoll CR OVFLIEN LL_FMAC_DisableIT_OVFL + * @param FMACx FMAC instance + * @retval None + */ +__STATIC_INLINE void LL_FMAC_DisableIT_OVFL(FMAC_TypeDef *FMACx) +{ + CLEAR_BIT(FMACx->CR, FMAC_CR_OVFLIEN); +} + +/** + * @brief Check FMAC overflow error interrupt state. + * @rmtoll CR OVFLIEN LL_FMAC_IsEnabledIT_OVFL + * @param FMACx FMAC instance + * @retval uint32_t State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_FMAC_IsEnabledIT_OVFL(const FMAC_TypeDef *FMACx) +{ + return ((READ_BIT(FMACx->CR, FMAC_CR_OVFLIEN) == (FMAC_CR_OVFLIEN)) ? 1UL : 0UL); +} + +/** + * @brief Enable FMAC write interrupt. + * @rmtoll CR WIEN LL_FMAC_EnableIT_WR + * @param FMACx FMAC instance + * @retval None + */ +__STATIC_INLINE void LL_FMAC_EnableIT_WR(FMAC_TypeDef *FMACx) +{ + SET_BIT(FMACx->CR, FMAC_CR_WIEN); +} + +/** + * @brief Disable FMAC write interrupt. + * @rmtoll CR WIEN LL_FMAC_DisableIT_WR + * @param FMACx FMAC instance + * @retval None + */ +__STATIC_INLINE void LL_FMAC_DisableIT_WR(FMAC_TypeDef *FMACx) +{ + CLEAR_BIT(FMACx->CR, FMAC_CR_WIEN); +} + +/** + * @brief Check FMAC write interrupt state. + * @rmtoll CR WIEN LL_FMAC_IsEnabledIT_WR + * @param FMACx FMAC instance + * @retval uint32_t State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_FMAC_IsEnabledIT_WR(const FMAC_TypeDef *FMACx) +{ + return ((READ_BIT(FMACx->CR, FMAC_CR_WIEN) == (FMAC_CR_WIEN)) ? 1UL : 0UL); +} + +/** + * @brief Enable FMAC read interrupt. + * @rmtoll CR RIEN LL_FMAC_EnableIT_RD + * @param FMACx FMAC instance + * @retval None + */ +__STATIC_INLINE void LL_FMAC_EnableIT_RD(FMAC_TypeDef *FMACx) +{ + SET_BIT(FMACx->CR, FMAC_CR_RIEN); +} + +/** + * @brief Disable FMAC read interrupt. + * @rmtoll CR RIEN LL_FMAC_DisableIT_RD + * @param FMACx FMAC instance + * @retval None + */ +__STATIC_INLINE void LL_FMAC_DisableIT_RD(FMAC_TypeDef *FMACx) +{ + CLEAR_BIT(FMACx->CR, FMAC_CR_RIEN); +} + +/** + * @brief Check FMAC read interrupt state. + * @rmtoll CR RIEN LL_FMAC_IsEnabledIT_RD + * @param FMACx FMAC instance + * @retval uint32_t State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_FMAC_IsEnabledIT_RD(const FMAC_TypeDef *FMACx) +{ + return ((READ_BIT(FMACx->CR, FMAC_CR_RIEN) == (FMAC_CR_RIEN)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup FMAC_LL_EF_FLAG_Management FLAG_Management + * @{ + */ + +/** + * @brief Check FMAC saturation error flag state. + * @rmtoll SR SAT LL_FMAC_IsActiveFlag_SAT + * @param FMACx FMAC instance + * @retval uint32_t State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_FMAC_IsActiveFlag_SAT(const FMAC_TypeDef *FMACx) +{ + return ((READ_BIT(FMACx->SR, FMAC_SR_SAT) == (FMAC_SR_SAT)) ? 1UL : 0UL); +} + +/** + * @brief Check FMAC underflow error flag state. + * @rmtoll SR UNFL LL_FMAC_IsActiveFlag_UNFL + * @param FMACx FMAC instance + * @retval uint32_t State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_FMAC_IsActiveFlag_UNFL(const FMAC_TypeDef *FMACx) +{ + return ((READ_BIT(FMACx->SR, FMAC_SR_UNFL) == (FMAC_SR_UNFL)) ? 1UL : 0UL); +} + +/** + * @brief Check FMAC overflow error flag state. + * @rmtoll SR OVFL LL_FMAC_IsActiveFlag_OVFL + * @param FMACx FMAC instance + * @retval uint32_t State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_FMAC_IsActiveFlag_OVFL(const FMAC_TypeDef *FMACx) +{ + return ((READ_BIT(FMACx->SR, FMAC_SR_OVFL) == (FMAC_SR_OVFL)) ? 1UL : 0UL); +} + +/** + * @brief Check FMAC X1 buffer full flag state. + * @rmtoll SR X1FULL LL_FMAC_IsActiveFlag_X1FULL + * @param FMACx FMAC instance + * @retval uint32_t State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_FMAC_IsActiveFlag_X1FULL(const FMAC_TypeDef *FMACx) +{ + return ((READ_BIT(FMACx->SR, FMAC_SR_X1FULL) == (FMAC_SR_X1FULL)) ? 1UL : 0UL); +} + +/** + * @brief Check FMAC Y buffer empty flag state. + * @rmtoll SR YEMPTY LL_FMAC_IsActiveFlag_YEMPTY + * @param FMACx FMAC instance + * @retval uint32_t State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_FMAC_IsActiveFlag_YEMPTY(const FMAC_TypeDef *FMACx) +{ + return ((READ_BIT(FMACx->SR, FMAC_SR_YEMPTY) == (FMAC_SR_YEMPTY)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup FMAC_LL_EF_Data_Management Data_Management + * @{ + */ + +/** + * @brief Write 16-bit input data for the FMAC processing. + * @rmtoll WDATA WDATA LL_FMAC_WriteData + * @param FMACx FMAC instance + * @param InData 16-bit value to be provided as input data for FMAC processing. + * This parameter must be a number between Min_Data=0x0000 and Max_Data=0xFFFF. + * @retval None + */ +__STATIC_INLINE void LL_FMAC_WriteData(FMAC_TypeDef *FMACx, uint16_t InData) +{ + WRITE_REG(FMACx->WDATA, InData); +} + +/** + * @brief Return 16-bit output data of FMAC processing. + * @rmtoll RDATA RDATA LL_FMAC_ReadData + * @param FMACx FMAC instance + * @retval uint16_t 16-bit output data of FMAC processing (value between Min_Data=0x0000 and Max_Data=0xFFFF). + */ +__STATIC_INLINE uint16_t LL_FMAC_ReadData(const FMAC_TypeDef *FMACx) +{ + return (uint16_t)(READ_REG(FMACx->RDATA)); +} + +/** + * @} + */ + +/** @defgroup FMAC_LL_EF_Configuration FMAC Configuration functions + * @{ + */ + +/** + * @brief Configure memory for X1 buffer. + * @rmtoll X1BUFCFG FULL_WM LL_FMAC_ConfigX1\n + * X1BUFCFG X1_BASE LL_FMAC_ConfigX1\n + * X1BUFCFG X1_BUF_SIZE LL_FMAC_ConfigX1 + * @param FMACx FMAC instance + * @param Watermark This parameter can be one of the following values: + * @arg @ref LL_FMAC_WM_0_THRESHOLD_1 + * @arg @ref LL_FMAC_WM_1_THRESHOLD_2 + * @arg @ref LL_FMAC_WM_2_THRESHOLD_4 + * @arg @ref LL_FMAC_WM_3_THRESHOLD_8 + * @param Base Base address of the input buffer (X1) within the internal memory. + * This parameter must be a value between Min_Data=0x00 and Max_Data=0xFF. + * @param BufferSize Number of 16-bit words allocated to the input buffer (including the optional "headroom"). + * This parameter must be a number between Min_Data=0x01 and Max_Data=0xFF. + * @retval None + */ +__STATIC_INLINE void LL_FMAC_ConfigX1(FMAC_TypeDef *FMACx, uint32_t Watermark, uint8_t Base, uint8_t BufferSize) +{ + MODIFY_REG(FMACx->X1BUFCFG, FMAC_X1BUFCFG_FULL_WM | FMAC_X1BUFCFG_X1_BASE | FMAC_X1BUFCFG_X1_BUF_SIZE, + Watermark | (((uint32_t)Base) << FMAC_X1BUFCFG_X1_BASE_Pos) | + (((uint32_t)BufferSize) << FMAC_X1BUFCFG_X1_BUF_SIZE_Pos)); +} + +/** + * @brief Configure memory for X2 buffer. + * @rmtoll X2BUFCFG X2_BASE LL_FMAC_ConfigX2\n + * X2BUFCFG X2_BUF_SIZE LL_FMAC_ConfigX2 + * @param FMACx FMAC instance + * @param Base Base address of the coefficient buffer (X2) within the internal memory. + * This parameter must be a value between Min_Data=0x00 and Max_Data=0xFF. + * @param BufferSize Number of 16-bit words allocated to the coefficient buffer. + * This parameter must be a number between Min_Data=0x01 and Max_Data=0xFF. + * @retval None + */ +__STATIC_INLINE void LL_FMAC_ConfigX2(FMAC_TypeDef *FMACx, uint8_t Base, uint8_t BufferSize) +{ + MODIFY_REG(FMACx->X2BUFCFG, FMAC_X2BUFCFG_X2_BASE | FMAC_X2BUFCFG_X2_BUF_SIZE, + (((uint32_t)Base) << FMAC_X2BUFCFG_X2_BASE_Pos) | + (((uint32_t)BufferSize) << FMAC_X2BUFCFG_X2_BUF_SIZE_Pos)); +} + +/** + * @brief Configure memory for Y buffer. + * @rmtoll YBUFCFG EMPTY_WM LL_FMAC_ConfigY\n + * YBUFCFG Y_BASE LL_FMAC_ConfigY\n + * YBUFCFG Y_BUF_SIZE LL_FMAC_ConfigY + * @param FMACx FMAC instance + * @param Watermark This parameter can be one of the following values: + * @arg @ref LL_FMAC_WM_0_THRESHOLD_1 + * @arg @ref LL_FMAC_WM_1_THRESHOLD_2 + * @arg @ref LL_FMAC_WM_2_THRESHOLD_4 + * @arg @ref LL_FMAC_WM_3_THRESHOLD_8 + * @param Base Base address of the output buffer (Y) within the internal memory. + * This parameter must be a value between Min_Data=0x00 and Max_Data=0xFF. + * @param BufferSize Number of 16-bit words allocated to the output buffer (including the optional "headroom"). + * This parameter must be a number between Min_Data=0x01 and Max_Data=0xFF. + * @retval None + */ +__STATIC_INLINE void LL_FMAC_ConfigY(FMAC_TypeDef *FMACx, uint32_t Watermark, uint8_t Base, uint8_t BufferSize) +{ + MODIFY_REG(FMACx->YBUFCFG, FMAC_YBUFCFG_EMPTY_WM | FMAC_YBUFCFG_Y_BASE | FMAC_YBUFCFG_Y_BUF_SIZE, + Watermark | (((uint32_t)Base) << FMAC_YBUFCFG_Y_BASE_Pos) | + (((uint32_t)BufferSize) << FMAC_YBUFCFG_Y_BUF_SIZE_Pos)); +} + +/** + * @brief Configure the FMAC processing. + * @rmtoll PARAM START LL_FMAC_ConfigFunc\n + * PARAM FUNC LL_FMAC_ConfigFunc\n + * PARAM P LL_FMAC_ConfigFunc\n + * PARAM Q LL_FMAC_ConfigFunc\n + * PARAM R LL_FMAC_ConfigFunc + * @param FMACx FMAC instance + * @param Start This parameter can be one of the following values: + * @arg @ref LL_FMAC_PROCESSING_STOP + * @arg @ref LL_FMAC_PROCESSING_START + * @param Function This parameter can be one of the following values: + * @arg @ref LL_FMAC_FUNC_LOAD_X1 + * @arg @ref LL_FMAC_FUNC_LOAD_X2 + * @arg @ref LL_FMAC_FUNC_LOAD_Y + * @arg @ref LL_FMAC_FUNC_CONVO_FIR + * @arg @ref LL_FMAC_FUNC_IIR_DIRECT_FORM_1 + * @param ParamP Parameter P (vector length, number of filter taps, etc.). + * This parameter must be a value between Min_Data=0x00 and Max_Data=0xFF. + * @param ParamQ Parameter Q (vector length, etc.). + * This parameter must be a value between Min_Data=0x00 and Max_Data=0xFF. + * @param ParamR Parameter R (gain, etc.). + * This parameter must be a value between Min_Data=0x00 and Max_Data=0xFF. + * @retval None + */ +__STATIC_INLINE void LL_FMAC_ConfigFunc(FMAC_TypeDef *FMACx, uint8_t Start, uint32_t Function, uint8_t ParamP, + uint8_t ParamQ, uint8_t ParamR) +{ + MODIFY_REG(FMACx->PARAM, FMAC_PARAM_START | FMAC_PARAM_FUNC | FMAC_PARAM_P | FMAC_PARAM_Q | FMAC_PARAM_R, + (((uint32_t)Start) << FMAC_PARAM_START_Pos) | Function | (((uint32_t)ParamP) << FMAC_PARAM_P_Pos) | + (((uint32_t)ParamQ) << FMAC_PARAM_Q_Pos) | (((uint32_t)ParamR) << FMAC_PARAM_R_Pos)); +} + +/** + * @} + */ + + + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup FMAC_LL_EF_Init Initialization and de-initialization functions + * @{ + */ +ErrorStatus LL_FMAC_Init(FMAC_TypeDef *FMACx); +ErrorStatus LL_FMAC_DeInit(const FMAC_TypeDef *FMACx); + + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined(FMAC) */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_LL_FMAC_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_fmc.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_fmc.h new file mode 100644 index 0000000000..e406764d43 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_fmc.h @@ -0,0 +1,1248 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_fmc.h + * @author MCD Application Team + * @brief Header file of FMC HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2022 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 STM32H5xx_LL_FMC_H +#define STM32H5xx_LL_FMC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup FMC_LL + * @{ + */ + +/** @addtogroup FMC_LL_Private_Macros + * @{ + */ +#if defined(FMC_BANK1) + +#define IS_FMC_NORSRAM_BANK(__BANK__) (((__BANK__) == FMC_NORSRAM_BANK1) || \ + ((__BANK__) == FMC_NORSRAM_BANK2) || \ + ((__BANK__) == FMC_NORSRAM_BANK3) || \ + ((__BANK__) == FMC_NORSRAM_BANK4)) +#define IS_FMC_MUX(__MUX__) (((__MUX__) == FMC_DATA_ADDRESS_MUX_DISABLE) || \ + ((__MUX__) == FMC_DATA_ADDRESS_MUX_ENABLE)) +#define IS_FMC_MEMORY(__MEMORY__) (((__MEMORY__) == FMC_MEMORY_TYPE_SRAM) || \ + ((__MEMORY__) == FMC_MEMORY_TYPE_PSRAM)|| \ + ((__MEMORY__) == FMC_MEMORY_TYPE_NOR)) +#define IS_FMC_NORSRAM_MEMORY_WIDTH(__WIDTH__) (((__WIDTH__) == FMC_NORSRAM_MEM_BUS_WIDTH_8) || \ + ((__WIDTH__) == FMC_NORSRAM_MEM_BUS_WIDTH_16) || \ + ((__WIDTH__) == FMC_NORSRAM_MEM_BUS_WIDTH_32)) +#define IS_FMC_PAGESIZE(__SIZE__) (((__SIZE__) == FMC_PAGE_SIZE_NONE) || \ + ((__SIZE__) == FMC_PAGE_SIZE_128) || \ + ((__SIZE__) == FMC_PAGE_SIZE_256) || \ + ((__SIZE__) == FMC_PAGE_SIZE_512) || \ + ((__SIZE__) == FMC_PAGE_SIZE_1024)) +#define IS_FMC_WRITE_FIFO(__FIFO__) (((__FIFO__) == FMC_WRITE_FIFO_DISABLE) || \ + ((__FIFO__) == FMC_WRITE_FIFO_ENABLE)) +#define IS_FMC_ACCESS_MODE(__MODE__) (((__MODE__) == FMC_ACCESS_MODE_A) || \ + ((__MODE__) == FMC_ACCESS_MODE_B) || \ + ((__MODE__) == FMC_ACCESS_MODE_C) || \ + ((__MODE__) == FMC_ACCESS_MODE_D)) +#define IS_FMC_NBL_SETUPTIME(__NBL__) (((__NBL__) == FMC_NBL_SETUPTIME_0) || \ + ((__NBL__) == FMC_NBL_SETUPTIME_1) || \ + ((__NBL__) == FMC_NBL_SETUPTIME_2) || \ + ((__NBL__) == FMC_NBL_SETUPTIME_3)) +#define IS_FMC_BURSTMODE(__STATE__) (((__STATE__) == FMC_BURST_ACCESS_MODE_DISABLE) || \ + ((__STATE__) == FMC_BURST_ACCESS_MODE_ENABLE)) +#define IS_FMC_WAIT_POLARITY(__POLARITY__) (((__POLARITY__) == FMC_WAIT_SIGNAL_POLARITY_LOW) || \ + ((__POLARITY__) == FMC_WAIT_SIGNAL_POLARITY_HIGH)) +#define IS_FMC_WAIT_SIGNAL_ACTIVE(__ACTIVE__) (((__ACTIVE__) == FMC_WAIT_TIMING_BEFORE_WS) || \ + ((__ACTIVE__) == FMC_WAIT_TIMING_DURING_WS)) +#define IS_FMC_WRITE_OPERATION(__OPERATION__) (((__OPERATION__) == FMC_WRITE_OPERATION_DISABLE) || \ + ((__OPERATION__) == FMC_WRITE_OPERATION_ENABLE)) +#define IS_FMC_WAITE_SIGNAL(__SIGNAL__) (((__SIGNAL__) == FMC_WAIT_SIGNAL_DISABLE) || \ + ((__SIGNAL__) == FMC_WAIT_SIGNAL_ENABLE)) +#define IS_FMC_EXTENDED_MODE(__MODE__) (((__MODE__) == FMC_EXTENDED_MODE_DISABLE) || \ + ((__MODE__) == FMC_EXTENDED_MODE_ENABLE)) +#define IS_FMC_ASYNWAIT(__STATE__) (((__STATE__) == FMC_ASYNCHRONOUS_WAIT_DISABLE) || \ + ((__STATE__) == FMC_ASYNCHRONOUS_WAIT_ENABLE)) +#define IS_FMC_DATA_LATENCY(__LATENCY__) (((__LATENCY__) > 1U) && ((__LATENCY__) <= 17U)) +#define IS_FMC_WRITE_BURST(__BURST__) (((__BURST__) == FMC_WRITE_BURST_DISABLE) || \ + ((__BURST__) == FMC_WRITE_BURST_ENABLE)) +#define IS_FMC_CONTINOUS_CLOCK(__CCLOCK__) (((__CCLOCK__) == FMC_CONTINUOUS_CLOCK_SYNC_ONLY) || \ + ((__CCLOCK__) == FMC_CONTINUOUS_CLOCK_SYNC_ASYNC)) +#define IS_FMC_ADDRESS_SETUP_TIME(__TIME__) ((__TIME__) <= 15U) +#define IS_FMC_ADDRESS_HOLD_TIME(__TIME__) (((__TIME__) > 0U) && ((__TIME__) <= 15U)) +#define IS_FMC_DATASETUP_TIME(__TIME__) (((__TIME__) > 0U) && ((__TIME__) <= 255U)) +#define IS_FMC_DATAHOLD_DURATION(__DATAHOLD__) ((__DATAHOLD__) <= 3U) +#define IS_FMC_TURNAROUND_TIME(__TIME__) ((__TIME__) <= 15U) +#define IS_FMC_CLK_DIV(__DIV__) (((__DIV__) > 1U) && ((__DIV__) <= 16U)) +#define IS_FMC_NORSRAM_DEVICE(__INSTANCE__) ((__INSTANCE__) == FMC_NORSRAM_DEVICE) +#define IS_FMC_NORSRAM_EXTENDED_DEVICE(__INSTANCE__) ((__INSTANCE__) == FMC_NORSRAM_EXTENDED_DEVICE) +#define IS_FMC_MAX_CHIP_SELECT_PULSE_TIME(__TIME__) (((__TIME__) >= 1U) && ((__TIME__) <= 65535U)) + +#endif /* FMC_BANK1 */ +#if defined(FMC_BANK3) + +#define IS_FMC_NAND_BANK(__BANK__) ((__BANK__) == FMC_NAND_BANK3) +#define IS_FMC_WAIT_FEATURE(__FEATURE__) (((__FEATURE__) == FMC_NAND_WAIT_FEATURE_DISABLE) || \ + ((__FEATURE__) == FMC_NAND_WAIT_FEATURE_ENABLE)) +#define IS_FMC_NAND_MEMORY_WIDTH(__WIDTH__) (((__WIDTH__) == FMC_NAND_MEM_BUS_WIDTH_8) || \ + ((__WIDTH__) == FMC_NAND_MEM_BUS_WIDTH_16)) +#define IS_FMC_ECC_STATE(__STATE__) (((__STATE__) == FMC_NAND_ECC_DISABLE) || \ + ((__STATE__) == FMC_NAND_ECC_ENABLE)) + +#define IS_FMC_ECCPAGE_SIZE(__SIZE__) (((__SIZE__) == FMC_NAND_ECC_PAGE_SIZE_256BYTE) || \ + ((__SIZE__) == FMC_NAND_ECC_PAGE_SIZE_512BYTE) || \ + ((__SIZE__) == FMC_NAND_ECC_PAGE_SIZE_1024BYTE) || \ + ((__SIZE__) == FMC_NAND_ECC_PAGE_SIZE_2048BYTE) || \ + ((__SIZE__) == FMC_NAND_ECC_PAGE_SIZE_4096BYTE) || \ + ((__SIZE__) == FMC_NAND_ECC_PAGE_SIZE_8192BYTE)) +#define IS_FMC_TCLR_TIME(__TIME__) ((__TIME__) <= 255U) +#define IS_FMC_TAR_TIME(__TIME__) ((__TIME__) <= 255U) +#define IS_FMC_SETUP_TIME(__TIME__) ((__TIME__) <= 254U) +#define IS_FMC_WAIT_TIME(__TIME__) ((__TIME__) <= 254U) +#define IS_FMC_HOLD_TIME(__TIME__) ((__TIME__) <= 254U) +#define IS_FMC_HIZ_TIME(__TIME__) ((__TIME__) <= 254U) +#define IS_FMC_NAND_DEVICE(__INSTANCE__) ((__INSTANCE__) == FMC_NAND_DEVICE) + +#endif /* FMC_BANK3 */ +#if defined(FMC_Bank5_6_R) + +#define IS_FMC_SDMEMORY_WIDTH(__WIDTH__) (((__WIDTH__) == FMC_SDRAM_MEM_BUS_WIDTH_8) || \ + ((__WIDTH__) == FMC_SDRAM_MEM_BUS_WIDTH_16)) +#define IS_FMC_WRITE_PROTECTION(__WRITE__) (((__WRITE__) == FMC_SDRAM_WRITE_PROTECTION_DISABLE) || \ + ((__WRITE__) == FMC_SDRAM_WRITE_PROTECTION_ENABLE)) +#define IS_FMC_SDCLOCK_PERIOD(__PERIOD__) (((__PERIOD__) == FMC_SDRAM_CLOCK_DISABLE) || \ + ((__PERIOD__) == FMC_SDRAM_CLOCK_PERIOD_2) || \ + ((__PERIOD__) == FMC_SDRAM_CLOCK_PERIOD_3)) +#define IS_FMC_READ_BURST(__RBURST__) (((__RBURST__) == FMC_SDRAM_RBURST_DISABLE) || \ + ((__RBURST__) == FMC_SDRAM_RBURST_ENABLE)) +#define IS_FMC_READPIPE_DELAY(__DELAY__) (((__DELAY__) == FMC_SDRAM_RPIPE_DELAY_0) || \ + ((__DELAY__) == FMC_SDRAM_RPIPE_DELAY_1) || \ + ((__DELAY__) == FMC_SDRAM_RPIPE_DELAY_2)) +#define IS_FMC_COMMAND_MODE(__COMMAND__) (((__COMMAND__) == FMC_SDRAM_CMD_NORMAL_MODE) || \ + ((__COMMAND__) == FMC_SDRAM_CMD_CLK_ENABLE) || \ + ((__COMMAND__) == FMC_SDRAM_CMD_PALL) || \ + ((__COMMAND__) == FMC_SDRAM_CMD_AUTOREFRESH_MODE) || \ + ((__COMMAND__) == FMC_SDRAM_CMD_LOAD_MODE) || \ + ((__COMMAND__) == FMC_SDRAM_CMD_SELFREFRESH_MODE) || \ + ((__COMMAND__) == FMC_SDRAM_CMD_POWERDOWN_MODE)) +#define IS_FMC_COMMAND_TARGET(__TARGET__) (((__TARGET__) == FMC_SDRAM_CMD_TARGET_BANK1) || \ + ((__TARGET__) == FMC_SDRAM_CMD_TARGET_BANK2) || \ + ((__TARGET__) == FMC_SDRAM_CMD_TARGET_BANK1_2)) +#define IS_FMC_LOADTOACTIVE_DELAY(__DELAY__) (((__DELAY__) > 0U) && ((__DELAY__) <= 16U)) +#define IS_FMC_EXITSELFREFRESH_DELAY(__DELAY__) (((__DELAY__) > 0U) && ((__DELAY__) <= 16U)) +#define IS_FMC_SELFREFRESH_TIME(__TIME__) (((__TIME__) > 0U) && ((__TIME__) <= 16U)) +#define IS_FMC_ROWCYCLE_DELAY(__DELAY__) (((__DELAY__) > 0U) && ((__DELAY__) <= 16U)) +#define IS_FMC_WRITE_RECOVERY_TIME(__TIME__) (((__TIME__) > 0U) && ((__TIME__) <= 16U)) +#define IS_FMC_RP_DELAY(__DELAY__) (((__DELAY__) > 0U) && ((__DELAY__) <= 16U)) +#define IS_FMC_RCD_DELAY(__DELAY__) (((__DELAY__) > 0U) && ((__DELAY__) <= 16U)) +#define IS_FMC_AUTOREFRESH_NUMBER(__NUMBER__) (((__NUMBER__) > 0U) && ((__NUMBER__) <= 15U)) +#define IS_FMC_MODE_REGISTER(__CONTENT__) ((__CONTENT__) <= 8191U) +#define IS_FMC_REFRESH_RATE(__RATE__) ((__RATE__) <= 8191U) +#define IS_FMC_SDRAM_DEVICE(__INSTANCE__) ((__INSTANCE__) == FMC_SDRAM_DEVICE) +#define IS_FMC_SDRAM_BANK(__BANK__) (((__BANK__) == FMC_SDRAM_BANK1) || \ + ((__BANK__) == FMC_SDRAM_BANK2)) +#define IS_FMC_COLUMNBITS_NUMBER(__COLUMN__) (((__COLUMN__) == FMC_SDRAM_COLUMN_BITS_NUM_8) || \ + ((__COLUMN__) == FMC_SDRAM_COLUMN_BITS_NUM_9) || \ + ((__COLUMN__) == FMC_SDRAM_COLUMN_BITS_NUM_10) || \ + ((__COLUMN__) == FMC_SDRAM_COLUMN_BITS_NUM_11)) +#define IS_FMC_ROWBITS_NUMBER(__ROW__) (((__ROW__) == FMC_SDRAM_ROW_BITS_NUM_11) || \ + ((__ROW__) == FMC_SDRAM_ROW_BITS_NUM_12) || \ + ((__ROW__) == FMC_SDRAM_ROW_BITS_NUM_13)) +#define IS_FMC_INTERNALBANK_NUMBER(__NUMBER__) (((__NUMBER__) == FMC_SDRAM_INTERN_BANKS_NUM_2) || \ + ((__NUMBER__) == FMC_SDRAM_INTERN_BANKS_NUM_4)) +#define IS_FMC_CAS_LATENCY(__LATENCY__) (((__LATENCY__) == FMC_SDRAM_CAS_LATENCY_1) || \ + ((__LATENCY__) == FMC_SDRAM_CAS_LATENCY_2) || \ + ((__LATENCY__) == FMC_SDRAM_CAS_LATENCY_3)) + +#endif /* FMC_Bank5_6_R */ + +/** + * @} + */ + +/* Exported typedef ----------------------------------------------------------*/ + +/** @defgroup FMC_LL_Exported_typedef FMC Low Layer Exported Types + * @{ + */ + +#if defined(FMC_BANK1) +#define FMC_NORSRAM_TypeDef FMC_Bank1_TypeDef +#define FMC_NORSRAM_EXTENDED_TypeDef FMC_Bank1E_TypeDef +#endif /* FMC_BANK1 */ +#if defined(FMC_BANK3) +#define FMC_NAND_TypeDef FMC_Bank3_TypeDef +#endif /* FMC_BANK3 */ +#if defined(FMC_Bank5_6_R) +#define FMC_SDRAM_TypeDef FMC_Bank5_6_TypeDef +#endif /* FMC_Bank5_6_R */ + +#if defined(FMC_BANK1) +#define FMC_NORSRAM_DEVICE FMC_Bank1_R +#define FMC_NORSRAM_EXTENDED_DEVICE FMC_Bank1E_R +#endif /* FMC_BANK1 */ +#if defined(FMC_BANK3) +#define FMC_NAND_DEVICE FMC_Bank3_R +#endif /* FMC_BANK3 */ +#if defined(FMC_Bank5_6_R) +#define FMC_SDRAM_DEVICE FMC_Bank5_6_R +#endif /* FMC_Bank5_6_R */ + +#if defined(FMC_BANK1) +/** + * @brief FMC NORSRAM Configuration Structure definition + */ +typedef struct +{ + uint32_t NSBank; /*!< Specifies the NORSRAM memory device that will be used. + This parameter can be a value of @ref FMC_NORSRAM_Bank */ + + uint32_t DataAddressMux; /*!< Specifies whether the address and data values are + multiplexed on the data bus or not. + This parameter can be a value of @ref FMC_Data_Address_Bus_Multiplexing */ + + uint32_t MemoryType; /*!< Specifies the type of external memory attached to + the corresponding memory device. + This parameter can be a value of @ref FMC_Memory_Type */ + + uint32_t MemoryDataWidth; /*!< Specifies the external memory device width. + This parameter can be a value of @ref FMC_NORSRAM_Data_Width */ + + uint32_t BurstAccessMode; /*!< Enables or disables the burst access mode for Flash memory, + valid only with synchronous burst Flash memories. + This parameter can be a value of @ref FMC_Burst_Access_Mode */ + + uint32_t WaitSignalPolarity; /*!< Specifies the wait signal polarity, valid only when accessing + the Flash memory in burst mode. + This parameter can be a value of @ref FMC_Wait_Signal_Polarity */ + + uint32_t WaitSignalActive; /*!< Specifies if the wait signal is asserted by the memory one + clock cycle before the wait state or during the wait state, + valid only when accessing memories in burst mode. + This parameter can be a value of @ref FMC_Wait_Timing */ + + uint32_t WriteOperation; /*!< Enables or disables the write operation in the selected device by the FMC. + This parameter can be a value of @ref FMC_Write_Operation */ + + uint32_t WaitSignal; /*!< Enables or disables the wait state insertion via wait + signal, valid for Flash memory access in burst mode. + This parameter can be a value of @ref FMC_Wait_Signal */ + + uint32_t ExtendedMode; /*!< Enables or disables the extended mode. + This parameter can be a value of @ref FMC_Extended_Mode */ + + uint32_t AsynchronousWait; /*!< Enables or disables wait signal during asynchronous transfers, + valid only with asynchronous Flash memories. + This parameter can be a value of @ref FMC_AsynchronousWait */ + + uint32_t WriteBurst; /*!< Enables or disables the write burst operation. + This parameter can be a value of @ref FMC_Write_Burst */ + + uint32_t ContinuousClock; /*!< Enables or disables the FMC clock output to external memory devices. + This parameter is only enabled through the FMC_BCR1 register, + and don't care through FMC_BCR2..4 registers. + This parameter can be a value of @ref FMC_Continous_Clock */ + + uint32_t WriteFifo; /*!< Enables or disables the write FIFO used by the FMC controller. + This parameter is only enabled through the FMC_BCR1 register, + and don't care through FMC_BCR2..4 registers. + This parameter can be a value of @ref FMC_Write_FIFO */ + + uint32_t PageSize; /*!< Specifies the memory page size. + This parameter can be a value of @ref FMC_Page_Size */ + + uint32_t NBLSetupTime; /*!< Specifies the NBL setup timing clock cycle number + This parameter can be a value of @ref FMC_Byte_Lane */ + + FunctionalState MaxChipSelectPulse; /*!< Enables or disables the maximum chip select pulse management in this + NSBank for PSRAM refresh. + This parameter can be set to ENABLE or DISABLE */ + + uint32_t MaxChipSelectPulseTime; /*!< Specifies the maximum chip select pulse time in FMC_CLK cycles for + synchronous accesses and in HCLK cycles for asynchronous accesses, + valid only if MaxChipSelectPulse is ENABLE. + This parameter can be a value between Min_Data = 1 and Max_Data = 65535. + @note: This parameter is common to all NSBank. */ +} FMC_NORSRAM_InitTypeDef; + +/** + * @brief FMC NORSRAM Timing parameters structure definition + */ +typedef struct +{ + uint32_t AddressSetupTime; /*!< Defines the number of HCLK cycles to configure + the duration of the address setup time. + This parameter can be a value between Min_Data = 0 and Max_Data = 15. + @note This parameter is not used with synchronous NOR Flash memories. */ + + uint32_t AddressHoldTime; /*!< Defines the number of HCLK cycles to configure + the duration of the address hold time. + This parameter can be a value between Min_Data = 1 and Max_Data = 15. + @note This parameter is not used with synchronous NOR Flash memories. */ + + uint32_t DataSetupTime; /*!< Defines the number of HCLK cycles to configure + the duration of the data setup time. + This parameter can be a value between Min_Data = 1 and Max_Data = 255. + @note This parameter is used for SRAMs, ROMs and asynchronous multiplexed + NOR Flash memories. */ + + uint32_t DataHoldTime; /*!< Defines the number of HCLK cycles to configure + the duration of the data hold time. + This parameter can be a value between Min_Data = 0 and Max_Data = 3. + @note This parameter is used for used in asynchronous accesses. */ + + uint32_t BusTurnAroundDuration; /*!< Defines the number of HCLK cycles to configure + the duration of the bus turnaround. + This parameter can be a value between Min_Data = 0 and Max_Data = 15. + @note This parameter is only used for multiplexed NOR Flash memories. */ + + uint32_t CLKDivision; /*!< Defines the period of CLK clock output signal, expressed in number of + HCLK cycles. This parameter can be a value between Min_Data = 2 and + Max_Data = 16. + @note This parameter is not used for asynchronous NOR Flash, SRAM or ROM + accesses. */ + + uint32_t DataLatency; /*!< Defines the number of memory clock cycles to issue + to the memory before getting the first data. + The parameter value depends on the memory type as shown below: + - It must be set to 0 in case of a CRAM + - It is don't care in asynchronous NOR, SRAM or ROM accesses + - It may assume a value between Min_Data = 2 and Max_Data = 17 + in NOR Flash memories with synchronous burst mode enable */ + + uint32_t AccessMode; /*!< Specifies the asynchronous access mode. + This parameter can be a value of @ref FMC_Access_Mode */ +} FMC_NORSRAM_TimingTypeDef; +#endif /* FMC_BANK1 */ + +#if defined(FMC_BANK3) +/** + * @brief FMC NAND Configuration Structure definition + */ +typedef struct +{ + uint32_t NandBank; /*!< Specifies the NAND memory device that will be used. + This parameter can be a value of @ref FMC_NAND_Bank */ + + uint32_t Waitfeature; /*!< Enables or disables the Wait feature for the NAND Memory device. + This parameter can be any value of @ref FMC_Wait_feature */ + + uint32_t MemoryDataWidth; /*!< Specifies the external memory device width. + This parameter can be any value of @ref FMC_NAND_Data_Width */ + + uint32_t EccComputation; /*!< Enables or disables the ECC computation. + This parameter can be any value of @ref FMC_ECC */ + + uint32_t ECCPageSize; /*!< Defines the page size for the extended ECC. + This parameter can be any value of @ref FMC_ECC_Page_Size */ + + uint32_t TCLRSetupTime; /*!< Defines the number of HCLK cycles to configure the + delay between CLE low and RE low. + This parameter can be a value between Min_Data = 0 and Max_Data = 255 */ + + uint32_t TARSetupTime; /*!< Defines the number of HCLK cycles to configure the + delay between ALE low and RE low. + This parameter can be a number between Min_Data = 0 and Max_Data = 255 */ +} FMC_NAND_InitTypeDef; +#endif /* FMC_BANK3 */ + +#if defined(FMC_BANK3) +/** + * @brief FMC NAND Timing parameters structure definition + */ +typedef struct +{ + uint32_t SetupTime; /*!< Defines the number of HCLK cycles to setup address before + the command assertion for NAND-Flash read or write access + to common/Attribute or I/O memory space (depending on + the memory space timing to be configured). + This parameter can be a value between Min_Data = 0 and Max_Data = 254 */ + + uint32_t WaitSetupTime; /*!< Defines the minimum number of HCLK cycles to assert the + command for NAND-Flash read or write access to + common/Attribute or I/O memory space (depending on the + memory space timing to be configured). + This parameter can be a number between Min_Data = 0 and Max_Data = 254 */ + + uint32_t HoldSetupTime; /*!< Defines the number of HCLK clock cycles to hold address + (and data for write access) after the command de-assertion + for NAND-Flash read or write access to common/Attribute + or I/O memory space (depending on the memory space timing + to be configured). + This parameter can be a number between Min_Data = 0 and Max_Data = 254 */ + + uint32_t HiZSetupTime; /*!< Defines the number of HCLK clock cycles during which the + data bus is kept in HiZ after the start of a NAND-Flash + write access to common/Attribute or I/O memory space (depending + on the memory space timing to be configured). + This parameter can be a number between Min_Data = 0 and Max_Data = 254 */ +} FMC_NAND_PCC_TimingTypeDef; +#endif /* FMC_BANK3 */ + + +#if defined(FMC_Bank5_6_R) +/** + * @brief FMC SDRAM Configuration Structure definition + */ +typedef struct +{ + uint32_t SDBank; /*!< Specifies the SDRAM memory device that will be used. + This parameter can be a value of @ref FMC_SDRAM_Bank */ + + uint32_t ColumnBitsNumber; /*!< Defines the number of bits of column address. + This parameter can be a value of @ref FMC_SDRAM_Column_Bits_number. */ + + uint32_t RowBitsNumber; /*!< Defines the number of bits of column address. + This parameter can be a value of @ref FMC_SDRAM_Row_Bits_number. */ + + uint32_t MemoryDataWidth; /*!< Defines the memory device width. + This parameter can be a value of @ref FMC_SDRAM_Memory_Bus_Width. */ + + uint32_t InternalBankNumber; /*!< Defines the number of the device's internal banks. + This parameter can be of @ref FMC_SDRAM_Internal_Banks_Number. */ + + uint32_t CASLatency; /*!< Defines the SDRAM CAS latency in number of memory clock cycles. + This parameter can be a value of @ref FMC_SDRAM_CAS_Latency. */ + + uint32_t WriteProtection; /*!< Enables the SDRAM device to be accessed in write mode. + This parameter can be a value of @ref FMC_SDRAM_Write_Protection. */ + + uint32_t SDClockPeriod; /*!< Define the SDRAM Clock Period for both SDRAM devices and they allow + to disable the clock before changing frequency. + This parameter can be a value of @ref FMC_SDRAM_Clock_Period. */ + + uint32_t ReadBurst; /*!< This bit enable the SDRAM controller to anticipate the next read + commands during the CAS latency and stores data in the Read FIFO. + This parameter can be a value of @ref FMC_SDRAM_Read_Burst. */ + + uint32_t ReadPipeDelay; /*!< Define the delay in system clock cycles on read data path. + This parameter can be a value of @ref FMC_SDRAM_Read_Pipe_Delay. */ +} FMC_SDRAM_InitTypeDef; + +/** + * @brief FMC SDRAM Timing parameters structure definition + */ +typedef struct +{ + uint32_t LoadToActiveDelay; /*!< Defines the delay between a Load Mode Register command and + an active or Refresh command in number of memory clock cycles. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ + + uint32_t ExitSelfRefreshDelay; /*!< Defines the delay from releasing the self refresh command to + issuing the Activate command in number of memory clock cycles. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ + + uint32_t SelfRefreshTime; /*!< Defines the minimum Self Refresh period in number of memory clock + cycles. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ + + uint32_t RowCycleDelay; /*!< Defines the delay between the Refresh command and the Activate command + and the delay between two consecutive Refresh commands in number of + memory clock cycles. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ + + uint32_t WriteRecoveryTime; /*!< Defines the Write recovery Time in number of memory clock cycles. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ + + uint32_t RPDelay; /*!< Defines the delay between a Precharge Command and an other command + in number of memory clock cycles. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ + + uint32_t RCDDelay; /*!< Defines the delay between the Activate Command and a Read/Write + command in number of memory clock cycles. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ +} FMC_SDRAM_TimingTypeDef; + +/** + * @brief SDRAM command parameters structure definition + */ +typedef struct +{ + uint32_t CommandMode; /*!< Defines the command issued to the SDRAM device. + This parameter can be a value of @ref FMC_SDRAM_Command_Mode. */ + + uint32_t CommandTarget; /*!< Defines which device (1 or 2) the command will be issued to. + This parameter can be a value of @ref FMC_SDRAM_Command_Target. */ + + uint32_t AutoRefreshNumber; /*!< Defines the number of consecutive auto refresh command issued + in auto refresh mode. + This parameter can be a value between Min_Data = 1 and Max_Data = 15 */ + + uint32_t ModeRegisterDefinition; /*!< Defines the SDRAM Mode register content */ +} FMC_SDRAM_CommandTypeDef; +#endif /* FMC_Bank5_6_R */ +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @addtogroup FMC_LL_Exported_Constants FMC Low Layer Exported Constants + * @{ + */ +#if defined(FMC_BANK1) + +/** @defgroup FMC_LL_NOR_SRAM_Controller FMC NOR/SRAM Controller + * @{ + */ + +/** @defgroup FMC_NORSRAM_Bank FMC NOR/SRAM Bank + * @{ + */ +#define FMC_NORSRAM_BANK1 (0x00000000U) +#define FMC_NORSRAM_BANK2 (0x00000002U) +#define FMC_NORSRAM_BANK3 (0x00000004U) +#define FMC_NORSRAM_BANK4 (0x00000006U) +/** + * @} + */ + +/** @defgroup FMC_Data_Address_Bus_Multiplexing FMC Data Address Bus Multiplexing + * @{ + */ +#define FMC_DATA_ADDRESS_MUX_DISABLE (0x00000000U) +#define FMC_DATA_ADDRESS_MUX_ENABLE (0x00000002U) +/** + * @} + */ + +/** @defgroup FMC_Memory_Type FMC Memory Type + * @{ + */ +#define FMC_MEMORY_TYPE_SRAM (0x00000000U) +#define FMC_MEMORY_TYPE_PSRAM (0x00000004U) +#define FMC_MEMORY_TYPE_NOR (0x00000008U) +/** + * @} + */ + +/** @defgroup FMC_NORSRAM_Data_Width FMC NORSRAM Data Width + * @{ + */ +#define FMC_NORSRAM_MEM_BUS_WIDTH_8 (0x00000000U) +#define FMC_NORSRAM_MEM_BUS_WIDTH_16 (0x00000010U) +#define FMC_NORSRAM_MEM_BUS_WIDTH_32 (0x00000020U) +/** + * @} + */ + +/** @defgroup FMC_NORSRAM_Flash_Access FMC NOR/SRAM Flash Access + * @{ + */ +#define FMC_NORSRAM_FLASH_ACCESS_ENABLE (0x00000040U) +#define FMC_NORSRAM_FLASH_ACCESS_DISABLE (0x00000000U) +/** + * @} + */ + +/** @defgroup FMC_Burst_Access_Mode FMC Burst Access Mode + * @{ + */ +#define FMC_BURST_ACCESS_MODE_DISABLE (0x00000000U) +#define FMC_BURST_ACCESS_MODE_ENABLE (0x00000100U) +/** + * @} + */ + +/** @defgroup FMC_Wait_Signal_Polarity FMC Wait Signal Polarity + * @{ + */ +#define FMC_WAIT_SIGNAL_POLARITY_LOW (0x00000000U) +#define FMC_WAIT_SIGNAL_POLARITY_HIGH (0x00000200U) +/** + * @} + */ + +/** @defgroup FMC_Wait_Timing FMC Wait Timing + * @{ + */ +#define FMC_WAIT_TIMING_BEFORE_WS (0x00000000U) +#define FMC_WAIT_TIMING_DURING_WS (0x00000800U) +/** + * @} + */ + +/** @defgroup FMC_Write_Operation FMC Write Operation + * @{ + */ +#define FMC_WRITE_OPERATION_DISABLE (0x00000000U) +#define FMC_WRITE_OPERATION_ENABLE (0x00001000U) +/** + * @} + */ + +/** @defgroup FMC_Wait_Signal FMC Wait Signal + * @{ + */ +#define FMC_WAIT_SIGNAL_DISABLE (0x00000000U) +#define FMC_WAIT_SIGNAL_ENABLE (0x00002000U) +/** + * @} + */ + +/** @defgroup FMC_Extended_Mode FMC Extended Mode + * @{ + */ +#define FMC_EXTENDED_MODE_DISABLE (0x00000000U) +#define FMC_EXTENDED_MODE_ENABLE (0x00004000U) +/** + * @} + */ + +/** @defgroup FMC_AsynchronousWait FMC Asynchronous Wait + * @{ + */ +#define FMC_ASYNCHRONOUS_WAIT_DISABLE (0x00000000U) +#define FMC_ASYNCHRONOUS_WAIT_ENABLE (0x00008000U) +/** + * @} + */ + +/** @defgroup FMC_Page_Size FMC Page Size + * @{ + */ +#define FMC_PAGE_SIZE_NONE (0x00000000U) +#define FMC_PAGE_SIZE_128 FMC_BCRx_CPSIZE_0 +#define FMC_PAGE_SIZE_256 FMC_BCRx_CPSIZE_1 +#define FMC_PAGE_SIZE_512 (FMC_BCRx_CPSIZE_0\ + | FMC_BCRx_CPSIZE_1) +#define FMC_PAGE_SIZE_1024 FMC_BCRx_CPSIZE_2 +/** + * @} + */ + +/** @defgroup FMC_Write_Burst FMC Write Burst + * @{ + */ +#define FMC_WRITE_BURST_DISABLE (0x00000000U) +#define FMC_WRITE_BURST_ENABLE (0x00080000U) +/** + * @} + */ + +/** @defgroup FMC_Continous_Clock FMC Continuous Clock + * @{ + */ +#define FMC_CONTINUOUS_CLOCK_SYNC_ONLY (0x00000000U) +#define FMC_CONTINUOUS_CLOCK_SYNC_ASYNC (0x00100000U) +/** + * @} + */ + +#if defined(FMC_BCR1_WFDIS) +/** @defgroup FMC_Write_FIFO FMC Write FIFO + * @{ + */ +#define FMC_WRITE_FIFO_DISABLE FMC_BCR1_WFDIS +#define FMC_WRITE_FIFO_ENABLE (0x00000000U) +#endif /* FMC_BCR1_WFDIS */ +/** + * @} + */ + +/** @defgroup FMC_Access_Mode FMC Access Mode + * @{ + */ +#define FMC_ACCESS_MODE_A (0x00000000U) +#define FMC_ACCESS_MODE_B (0x10000000U) +#define FMC_ACCESS_MODE_C (0x20000000U) +#define FMC_ACCESS_MODE_D (0x30000000U) +/** + * @} + */ + +/** @defgroup FMC_Byte_Lane FMC Byte Lane(NBL) Setup + * @{ + */ +#define FMC_NBL_SETUPTIME_0 (0x00000000U) +#define FMC_NBL_SETUPTIME_1 (0x00400000U) +#define FMC_NBL_SETUPTIME_2 (0x00800000U) +#define FMC_NBL_SETUPTIME_3 (0x00C00000U) +/** + * @} + */ + +/** + * @} + */ +#endif /* FMC_BANK1 */ + +#if defined(FMC_BANK3) + +/** @defgroup FMC_LL_NAND_Controller FMC NAND Controller + * @{ + */ +/** @defgroup FMC_NAND_Bank FMC NAND Bank + * @{ + */ +#define FMC_NAND_BANK3 (0x00000100U) +/** + * @} + */ + +/** @defgroup FMC_Wait_feature FMC Wait feature + * @{ + */ +#define FMC_NAND_WAIT_FEATURE_DISABLE (0x00000000U) +#define FMC_NAND_WAIT_FEATURE_ENABLE (0x00000002U) +/** + * @} + */ + +/** @defgroup FMC_PCR_Memory_Type FMC PCR Memory Type + * @{ + */ +#define FMC_PCR_MEMORY_TYPE_NAND (0x00000008U) +/** + * @} + */ + +/** @defgroup FMC_NAND_Data_Width FMC NAND Data Width + * @{ + */ +#define FMC_NAND_MEM_BUS_WIDTH_8 (0x00000000U) +#define FMC_NAND_MEM_BUS_WIDTH_16 (0x00000010U) +/** + * @} + */ + +/** @defgroup FMC_ECC FMC ECC + * @{ + */ +#define FMC_NAND_ECC_DISABLE (0x00000000U) +#define FMC_NAND_ECC_ENABLE (0x00000040U) +/** + * @} + */ + +/** @defgroup FMC_ECC_Page_Size FMC ECC Page Size + * @{ + */ +#define FMC_NAND_ECC_PAGE_SIZE_256BYTE (0x00000000U) +#define FMC_NAND_ECC_PAGE_SIZE_512BYTE (0x00020000U) +#define FMC_NAND_ECC_PAGE_SIZE_1024BYTE (0x00040000U) +#define FMC_NAND_ECC_PAGE_SIZE_2048BYTE (0x00060000U) +#define FMC_NAND_ECC_PAGE_SIZE_4096BYTE (0x00080000U) +#define FMC_NAND_ECC_PAGE_SIZE_8192BYTE (0x000A0000U) +/** + * @} + */ + +/** + * @} + */ +#endif /* FMC_BANK3 */ + +#if defined(FMC_Bank5_6_R) +/** @defgroup FMC_LL_SDRAM_Controller FMC SDRAM Controller + * @{ + */ +/** @defgroup FMC_SDRAM_Bank FMC SDRAM Bank + * @{ + */ +#define FMC_SDRAM_BANK1 (0x00000000U) +#define FMC_SDRAM_BANK2 (0x00000001U) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Column_Bits_number FMC SDRAM Column Bits number + * @{ + */ +#define FMC_SDRAM_COLUMN_BITS_NUM_8 (0x00000000U) +#define FMC_SDRAM_COLUMN_BITS_NUM_9 (0x00000001U) +#define FMC_SDRAM_COLUMN_BITS_NUM_10 (0x00000002U) +#define FMC_SDRAM_COLUMN_BITS_NUM_11 (0x00000003U) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Row_Bits_number FMC SDRAM Row Bits number + * @{ + */ +#define FMC_SDRAM_ROW_BITS_NUM_11 (0x00000000U) +#define FMC_SDRAM_ROW_BITS_NUM_12 (0x00000004U) +#define FMC_SDRAM_ROW_BITS_NUM_13 (0x00000008U) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Memory_Bus_Width FMC SDRAM Memory Bus Width + * @{ + */ +#define FMC_SDRAM_MEM_BUS_WIDTH_8 (0x00000000U) +#define FMC_SDRAM_MEM_BUS_WIDTH_16 (0x00000010U) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Internal_Banks_Number FMC SDRAM Internal Banks Number + * @{ + */ +#define FMC_SDRAM_INTERN_BANKS_NUM_2 (0x00000000U) +#define FMC_SDRAM_INTERN_BANKS_NUM_4 (0x00000040U) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_CAS_Latency FMC SDRAM CAS Latency + * @{ + */ +#define FMC_SDRAM_CAS_LATENCY_1 (0x00000080U) +#define FMC_SDRAM_CAS_LATENCY_2 (0x00000100U) +#define FMC_SDRAM_CAS_LATENCY_3 (0x00000180U) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Write_Protection FMC SDRAM Write Protection + * @{ + */ +#define FMC_SDRAM_WRITE_PROTECTION_DISABLE (0x00000000U) +#define FMC_SDRAM_WRITE_PROTECTION_ENABLE (0x00000200U) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Clock_Period FMC SDRAM Clock Period + * @{ + */ +#define FMC_SDRAM_CLOCK_DISABLE (0x00000000U) +#define FMC_SDRAM_CLOCK_PERIOD_2 (0x00000800U) +#define FMC_SDRAM_CLOCK_PERIOD_3 (0x00000C00U) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Read_Burst FMC SDRAM Read Burst + * @{ + */ +#define FMC_SDRAM_RBURST_DISABLE (0x00000000U) +#define FMC_SDRAM_RBURST_ENABLE (0x00001000U) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Read_Pipe_Delay FMC SDRAM Read Pipe Delay + * @{ + */ +#define FMC_SDRAM_RPIPE_DELAY_0 (0x00000000U) +#define FMC_SDRAM_RPIPE_DELAY_1 (0x00002000U) +#define FMC_SDRAM_RPIPE_DELAY_2 (0x00004000U) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Command_Mode FMC SDRAM Command Mode + * @{ + */ +#define FMC_SDRAM_CMD_NORMAL_MODE (0x00000000U) +#define FMC_SDRAM_CMD_CLK_ENABLE (0x00000001U) +#define FMC_SDRAM_CMD_PALL (0x00000002U) +#define FMC_SDRAM_CMD_AUTOREFRESH_MODE (0x00000003U) +#define FMC_SDRAM_CMD_LOAD_MODE (0x00000004U) +#define FMC_SDRAM_CMD_SELFREFRESH_MODE (0x00000005U) +#define FMC_SDRAM_CMD_POWERDOWN_MODE (0x00000006U) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Command_Target FMC SDRAM Command Target + * @{ + */ +#define FMC_SDRAM_CMD_TARGET_BANK2 FMC_SDCMR_CTB2 +#define FMC_SDRAM_CMD_TARGET_BANK1 FMC_SDCMR_CTB1 +#define FMC_SDRAM_CMD_TARGET_BANK1_2 (0x00000018U) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Mode_Status FMC SDRAM Mode Status + * @{ + */ +#define FMC_SDRAM_NORMAL_MODE (0x00000000U) +#define FMC_SDRAM_SELF_REFRESH_MODE FMC_SDSR_MODES1_0 +#define FMC_SDRAM_POWER_DOWN_MODE FMC_SDSR_MODES1_1 +/** + * @} + */ + +/** + * @} + */ + +#endif /* FMC_Bank5_6_R */ + +/** @defgroup FMC_LL_Interrupt_definition FMC Low Layer Interrupt definition + * @{ + */ +#if defined(FMC_BANK3) +#define FMC_IT_RISING_EDGE (0x00000008U) +#define FMC_IT_LEVEL (0x00000010U) +#define FMC_IT_FALLING_EDGE (0x00000020U) +#endif /* FMC_BANK3 */ +#if defined(FMC_Bank5_6_R) +#define FMC_IT_REFRESH_ERROR (0x00004000U) +#endif /* FMC_Bank5_6_R */ +/** + * @} + */ + +/** @defgroup FMC_LL_Flag_definition FMC Low Layer Flag definition + * @{ + */ +#if defined(FMC_BANK3) +#define FMC_FLAG_RISING_EDGE (0x00000001U) +#define FMC_FLAG_LEVEL (0x00000002U) +#define FMC_FLAG_FALLING_EDGE (0x00000004U) +#define FMC_FLAG_FEMPT (0x00000040U) +#endif /* FMC_BANK3 */ +#if defined(FMC_Bank5_6_R) +#define FMC_SDRAM_FLAG_REFRESH_IT FMC_SDSR_RE +#define FMC_SDRAM_FLAG_BUSY FMC_SDSR_BUSY +#define FMC_SDRAM_FLAG_REFRESH_ERROR FMC_SDRTR_CRE +#endif /* FMC_Bank5_6_R */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/** @defgroup FMC_LL_Private_Macros FMC_LL Private Macros + * @{ + */ +/** + * @brief Enable the FMC Peripheral. + * @retval None + */ +#define __FMC_ENABLE() (FMC_Bank1_R->BTCR[0] |= FMC_BCR1_FMCEN) + +/** + * @brief Disable the FMC Peripheral. + * @retval None + */ +#define __FMC_DISABLE() (FMC_Bank1_R->BTCR[0] &= ~FMC_BCR1_FMCEN) +#if defined(FMC_BANK1) +/** @defgroup FMC_LL_NOR_Macros FMC NOR/SRAM Macros + * @brief macros to handle NOR device enable/disable and read/write operations + * @{ + */ + +/** + * @brief Enable the NORSRAM device access. + * @param __INSTANCE__ FMC_NORSRAM Instance + * @param __BANK__ FMC_NORSRAM Bank + * @retval None + */ +#define __FMC_NORSRAM_ENABLE(__INSTANCE__, __BANK__) ((__INSTANCE__)->BTCR[(__BANK__)]\ + |= FMC_BCRx_MBKEN) + +/** + * @brief Disable the NORSRAM device access. + * @param __INSTANCE__ FMC_NORSRAM Instance + * @param __BANK__ FMC_NORSRAM Bank + * @retval None + */ +#define __FMC_NORSRAM_DISABLE(__INSTANCE__, __BANK__) ((__INSTANCE__)->BTCR[(__BANK__)]\ + &= ~FMC_BCRx_MBKEN) + +/** + * @} + */ +#endif /* FMC_BANK1 */ + +#if defined(FMC_BANK3) +/** @defgroup FMC_LL_NAND_Macros FMC NAND Macros + * @brief macros to handle NAND device enable/disable + * @{ + */ + +/** + * @brief Enable the NAND device access. + * @param __INSTANCE__ FMC_NAND Instance + * @retval None + */ +#define __FMC_NAND_ENABLE(__INSTANCE__) ((__INSTANCE__)->PCR |= FMC_PCR_PBKEN) + +/** + * @brief Disable the NAND device access. + * @param __INSTANCE__ FMC_NAND Instance + * @param __BANK__ FMC_NAND Bank + * @retval None + */ +#define __FMC_NAND_DISABLE(__INSTANCE__, __BANK__) CLEAR_BIT((__INSTANCE__)->PCR, FMC_PCR_PBKEN) + +/** + * @} + */ +#endif /* FMC_BANK3 */ + +#if defined(FMC_BANK3) +/** @defgroup FMC_LL_NAND_Interrupt FMC NAND Interrupt + * @brief macros to handle NAND interrupts + * @{ + */ + +/** + * @brief Enable the NAND device interrupt. + * @param __INSTANCE__ FMC_NAND instance + * @param __INTERRUPT__ FMC_NAND interrupt + * This parameter can be any combination of the following values: + * @arg FMC_IT_RISING_EDGE: Interrupt rising edge. + * @arg FMC_IT_LEVEL: Interrupt level. + * @arg FMC_IT_FALLING_EDGE: Interrupt falling edge. + * @retval None + */ +#define __FMC_NAND_ENABLE_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->SR |= (__INTERRUPT__)) + +/** + * @brief Disable the NAND device interrupt. + * @param __INSTANCE__ FMC_NAND Instance + * @param __INTERRUPT__ FMC_NAND interrupt + * This parameter can be any combination of the following values: + * @arg FMC_IT_RISING_EDGE: Interrupt rising edge. + * @arg FMC_IT_LEVEL: Interrupt level. + * @arg FMC_IT_FALLING_EDGE: Interrupt falling edge. + * @retval None + */ +#define __FMC_NAND_DISABLE_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->SR &= ~(__INTERRUPT__)) + +/** + * @brief Get flag status of the NAND device. + * @param __INSTANCE__ FMC_NAND Instance + * @param __BANK__ FMC_NAND Bank + * @param __FLAG__ FMC_NAND flag + * This parameter can be any combination of the following values: + * @arg FMC_FLAG_RISING_EDGE: Interrupt rising edge flag. + * @arg FMC_FLAG_LEVEL: Interrupt level edge flag. + * @arg FMC_FLAG_FALLING_EDGE: Interrupt falling edge flag. + * @arg FMC_FLAG_FEMPT: FIFO empty flag. + * @retval The state of FLAG (SET or RESET). + */ +#define __FMC_NAND_GET_FLAG(__INSTANCE__, __BANK__, __FLAG__) (((__INSTANCE__)->SR &(__FLAG__)) == (__FLAG__)) + +/** + * @brief Clear flag status of the NAND device. + * @param __INSTANCE__ FMC_NAND Instance + * @param __FLAG__ FMC_NAND flag + * This parameter can be any combination of the following values: + * @arg FMC_FLAG_RISING_EDGE: Interrupt rising edge flag. + * @arg FMC_FLAG_LEVEL: Interrupt level edge flag. + * @arg FMC_FLAG_FALLING_EDGE: Interrupt falling edge flag. + * @arg FMC_FLAG_FEMPT: FIFO empty flag. + * @retval None + */ +#define __FMC_NAND_CLEAR_FLAG(__INSTANCE__, __FLAG__) ((__INSTANCE__)->SR &= ~(__FLAG__)) + +/** + * @} + */ +#endif /* FMC_BANK3 */ + + +#if defined(FMC_Bank5_6_R) +/** @defgroup FMC_LL_SDRAM_Interrupt FMC SDRAM Interrupt + * @brief macros to handle SDRAM interrupts + * @{ + */ + +/** + * @brief Enable the SDRAM device interrupt. + * @param __INSTANCE__ FMC_SDRAM instance + * @param __INTERRUPT__ FMC_SDRAM interrupt + * This parameter can be any combination of the following values: + * @arg FMC_IT_REFRESH_ERROR: Interrupt refresh error + * @retval None + */ +#define __FMC_SDRAM_ENABLE_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->SDRTR |= (__INTERRUPT__)) + +/** + * @brief Disable the SDRAM device interrupt. + * @param __INSTANCE__ FMC_SDRAM instance + * @param __INTERRUPT__ FMC_SDRAM interrupt + * This parameter can be any combination of the following values: + * @arg FMC_IT_REFRESH_ERROR: Interrupt refresh error + * @retval None + */ +#define __FMC_SDRAM_DISABLE_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->SDRTR &= ~(__INTERRUPT__)) + +/** + * @brief Get flag status of the SDRAM device. + * @param __INSTANCE__ FMC_SDRAM instance + * @param __FLAG__ FMC_SDRAM flag + * This parameter can be any combination of the following values: + * @arg FMC_SDRAM_FLAG_REFRESH_IT: Interrupt refresh error. + * @arg FMC_SDRAM_FLAG_BUSY: SDRAM busy flag. + * @arg FMC_SDRAM_FLAG_REFRESH_ERROR: Refresh error flag. + * @retval The state of FLAG (SET or RESET). + */ +#define __FMC_SDRAM_GET_FLAG(__INSTANCE__, __FLAG__) (((__INSTANCE__)->SDSR &(__FLAG__)) == (__FLAG__)) + +/** + * @brief Clear flag status of the SDRAM device. + * @param __INSTANCE__ FMC_SDRAM instance + * @param __FLAG__ FMC_SDRAM flag + * This parameter can be any combination of the following values: + * @arg FMC_SDRAM_FLAG_REFRESH_ERROR + * @retval None + */ +#define __FMC_SDRAM_CLEAR_FLAG(__INSTANCE__, __FLAG__) ((__INSTANCE__)->SDRTR |= (__FLAG__)) + +/** + * @} + */ +#endif /* FMC_Bank5_6_R */ +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup FMC_LL_Private_Functions FMC LL Private Functions + * @{ + */ + +#if defined(FMC_BANK1) +/** @defgroup FMC_LL_NORSRAM NOR SRAM + * @{ + */ +/** @defgroup FMC_LL_NORSRAM_Private_Functions_Group1 NOR SRAM Initialization/de-initialization functions + * @{ + */ +HAL_StatusTypeDef FMC_NORSRAM_Init(FMC_NORSRAM_TypeDef *Device, + FMC_NORSRAM_InitTypeDef *Init); +HAL_StatusTypeDef FMC_NORSRAM_Timing_Init(FMC_NORSRAM_TypeDef *Device, + FMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank); +HAL_StatusTypeDef FMC_NORSRAM_Extended_Timing_Init(FMC_NORSRAM_EXTENDED_TypeDef *Device, + FMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank, + uint32_t ExtendedMode); +HAL_StatusTypeDef FMC_NORSRAM_DeInit(FMC_NORSRAM_TypeDef *Device, + FMC_NORSRAM_EXTENDED_TypeDef *ExDevice, uint32_t Bank); +/** + * @} + */ + +/** @defgroup FMC_LL_NORSRAM_Private_Functions_Group2 NOR SRAM Control functions + * @{ + */ +HAL_StatusTypeDef FMC_NORSRAM_WriteOperation_Enable(FMC_NORSRAM_TypeDef *Device, uint32_t Bank); +HAL_StatusTypeDef FMC_NORSRAM_WriteOperation_Disable(FMC_NORSRAM_TypeDef *Device, uint32_t Bank); +/** + * @} + */ +/** + * @} + */ +#endif /* FMC_BANK1 */ + +#if defined(FMC_BANK3) +/** @defgroup FMC_LL_NAND NAND + * @{ + */ +/** @defgroup FMC_LL_NAND_Private_Functions_Group1 NAND Initialization/de-initialization functions + * @{ + */ +HAL_StatusTypeDef FMC_NAND_Init(FMC_NAND_TypeDef *Device, FMC_NAND_InitTypeDef *Init); +HAL_StatusTypeDef FMC_NAND_CommonSpace_Timing_Init(FMC_NAND_TypeDef *Device, + FMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank); +HAL_StatusTypeDef FMC_NAND_AttributeSpace_Timing_Init(FMC_NAND_TypeDef *Device, + FMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank); +HAL_StatusTypeDef FMC_NAND_DeInit(FMC_NAND_TypeDef *Device, uint32_t Bank); +/** + * @} + */ + +/** @defgroup FMC_LL_NAND_Private_Functions_Group2 NAND Control functions + * @{ + */ +HAL_StatusTypeDef FMC_NAND_ECC_Enable(FMC_NAND_TypeDef *Device, uint32_t Bank); +HAL_StatusTypeDef FMC_NAND_ECC_Disable(FMC_NAND_TypeDef *Device, uint32_t Bank); +HAL_StatusTypeDef FMC_NAND_GetECC(FMC_NAND_TypeDef *Device, uint32_t *ECCval, uint32_t Bank, + uint32_t Timeout); +/** + * @} + */ +/** + * @} + */ +#endif /* FMC_BANK3 */ + + +#if defined(FMC_Bank5_6_R) +/** @defgroup FMC_LL_SDRAM SDRAM + * @{ + */ +/** @defgroup FMC_LL_SDRAM_Private_Functions_Group1 SDRAM Initialization/de-initialization functions + * @{ + */ +HAL_StatusTypeDef FMC_SDRAM_Init(FMC_SDRAM_TypeDef *Device, FMC_SDRAM_InitTypeDef *Init); +HAL_StatusTypeDef FMC_SDRAM_Timing_Init(FMC_SDRAM_TypeDef *Device, + FMC_SDRAM_TimingTypeDef *Timing, uint32_t Bank); +HAL_StatusTypeDef FMC_SDRAM_DeInit(FMC_SDRAM_TypeDef *Device, uint32_t Bank); +/** + * @} + */ + +/** @defgroup FMC_LL_SDRAM_Private_Functions_Group2 SDRAM Control functions + * @{ + */ +HAL_StatusTypeDef FMC_SDRAM_WriteProtection_Enable(FMC_SDRAM_TypeDef *Device, uint32_t Bank); +HAL_StatusTypeDef FMC_SDRAM_WriteProtection_Disable(FMC_SDRAM_TypeDef *Device, uint32_t Bank); +HAL_StatusTypeDef FMC_SDRAM_SendCommand(FMC_SDRAM_TypeDef *Device, + FMC_SDRAM_CommandTypeDef *Command, uint32_t Timeout); +HAL_StatusTypeDef FMC_SDRAM_ProgramRefreshRate(FMC_SDRAM_TypeDef *Device, uint32_t RefreshRate); +HAL_StatusTypeDef FMC_SDRAM_SetAutoRefreshNumber(FMC_SDRAM_TypeDef *Device, + uint32_t AutoRefreshNumber); +uint32_t FMC_SDRAM_GetModeStatus(const FMC_SDRAM_TypeDef *Device, uint32_t Bank); +/** + * @} + */ +/** + * @} + */ +#endif /* FMC_Bank5_6_R */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_LL_FMC_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_gpio.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_gpio.h new file mode 100644 index 0000000000..a9c6a159b1 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_gpio.h @@ -0,0 +1,1178 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_gpio.h + * @author MCD Application Team + * @brief Header file of GPIO LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32H5xx_LL_GPIO_H +#define __STM32H5xx_LL_GPIO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (GPIOA) || defined (GPIOB) || defined (GPIOC) || defined (GPIOD) || defined (GPIOE) || defined (GPIOF) || \ + defined (GPIOG) || defined (GPIOH) || defined (GPIOI) + +/** @defgroup GPIO_LL GPIO + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup GPIO_LL_Private_Macros GPIO Private Macros + * @{ + */ + +/** + * @} + */ +#endif /*USE_FULL_LL_DRIVER*/ + +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup GPIO_LL_ES_INIT GPIO Exported Init structures + * @{ + */ + +/** + * @brief LL GPIO Init Structure definition + */ +typedef struct +{ + uint32_t Pin; /*!< Specifies the GPIO pins to be configured. + This parameter can be any value of @ref GPIO_LL_EC_PIN */ + + uint32_t Mode; /*!< Specifies the operating mode for the selected pins. + This parameter can be a value of @ref GPIO_LL_EC_MODE. + + GPIO HW configuration can be modified afterwards using unitary function + @ref LL_GPIO_SetPinMode().*/ + + uint32_t Speed; /*!< Specifies the speed for the selected pins. + This parameter can be a value of @ref GPIO_LL_EC_SPEED. + + GPIO HW configuration can be modified afterwards using unitary function + @ref LL_GPIO_SetPinSpeed().*/ + + uint32_t OutputType; /*!< Specifies the operating output type for the selected pins. + This parameter can be a value of @ref GPIO_LL_EC_OUTPUT. + + GPIO HW configuration can be modified afterwards using unitary function + @ref LL_GPIO_SetPinOutputType().*/ + + uint32_t Pull; /*!< Specifies the operating Pull-up/Pull down for the selected pins. + This parameter can be a value of @ref GPIO_LL_EC_PULL. + + GPIO HW configuration can be modified afterwards using unitary function + @ref LL_GPIO_SetPinPull().*/ + + uint32_t Alternate; /*!< Specifies the Peripheral to be connected to the selected pins. + This parameter can be a value of @ref GPIO_LL_EC_AF. + + GPIO HW configuration can be modified afterwards using unitary function + @ref LL_GPIO_SetAFPin_0_7() and LL_GPIO_SetAFPin_8_15().*/ +} LL_GPIO_InitTypeDef; + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup GPIO_LL_Exported_Constants GPIO Exported Constants + * @{ + */ + +/** @defgroup GPIO_LL_EC_PIN PIN + * @{ + */ +#define LL_GPIO_PIN_0 GPIO_BSRR_BS0 /*!< Select pin 0 */ +#define LL_GPIO_PIN_1 GPIO_BSRR_BS1 /*!< Select pin 1 */ +#define LL_GPIO_PIN_2 GPIO_BSRR_BS2 /*!< Select pin 2 */ +#define LL_GPIO_PIN_3 GPIO_BSRR_BS3 /*!< Select pin 3 */ +#define LL_GPIO_PIN_4 GPIO_BSRR_BS4 /*!< Select pin 4 */ +#define LL_GPIO_PIN_5 GPIO_BSRR_BS5 /*!< Select pin 5 */ +#define LL_GPIO_PIN_6 GPIO_BSRR_BS6 /*!< Select pin 6 */ +#define LL_GPIO_PIN_7 GPIO_BSRR_BS7 /*!< Select pin 7 */ +#define LL_GPIO_PIN_8 GPIO_BSRR_BS8 /*!< Select pin 8 */ +#define LL_GPIO_PIN_9 GPIO_BSRR_BS9 /*!< Select pin 9 */ +#define LL_GPIO_PIN_10 GPIO_BSRR_BS10 /*!< Select pin 10 */ +#define LL_GPIO_PIN_11 GPIO_BSRR_BS11 /*!< Select pin 11 */ +#define LL_GPIO_PIN_12 GPIO_BSRR_BS12 /*!< Select pin 12 */ +#define LL_GPIO_PIN_13 GPIO_BSRR_BS13 /*!< Select pin 13 */ +#define LL_GPIO_PIN_14 GPIO_BSRR_BS14 /*!< Select pin 14 */ +#define LL_GPIO_PIN_15 GPIO_BSRR_BS15 /*!< Select pin 15 */ +#define LL_GPIO_PIN_ALL (GPIO_BSRR_BS0 | GPIO_BSRR_BS1 | GPIO_BSRR_BS2 | \ + GPIO_BSRR_BS3 | GPIO_BSRR_BS4 | GPIO_BSRR_BS5 | \ + GPIO_BSRR_BS6 | GPIO_BSRR_BS7 | GPIO_BSRR_BS8 | \ + GPIO_BSRR_BS9 | GPIO_BSRR_BS10 | GPIO_BSRR_BS11 | \ + GPIO_BSRR_BS12 | GPIO_BSRR_BS13 | GPIO_BSRR_BS14 | \ + GPIO_BSRR_BS15) /*!< Select all pins */ +/** + * @} + */ + +/** @defgroup GPIO_LL_EC_MODE Mode + * @{ + */ +#define LL_GPIO_MODE_INPUT (0x00000000U) /*!< Select input mode */ +#define LL_GPIO_MODE_OUTPUT GPIO_MODER_MODE0_0 /*!< Select output mode */ +#define LL_GPIO_MODE_ALTERNATE GPIO_MODER_MODE0_1 /*!< Select alternate function mode */ +#define LL_GPIO_MODE_ANALOG GPIO_MODER_MODE0 /*!< Select analog mode */ +/** + * @} + */ + +/** @defgroup GPIO_LL_EC_OUTPUT Output Type + * @{ + */ +#define LL_GPIO_OUTPUT_PUSHPULL (0x00000000U) /*!< Select push-pull as output type */ +#define LL_GPIO_OUTPUT_OPENDRAIN GPIO_OTYPER_OT0 /*!< Select open-drain as output type */ +/** + * @} + */ + +/** @defgroup GPIO_LL_EC_SPEED Output Speed + * @{ + */ +#define LL_GPIO_SPEED_FREQ_LOW (0x00000000U) /*!< Select I/O low output speed */ +#define LL_GPIO_SPEED_FREQ_MEDIUM GPIO_OSPEEDR_OSPEED0_0 /*!< Select I/O medium output speed */ +#define LL_GPIO_SPEED_FREQ_HIGH GPIO_OSPEEDR_OSPEED0_1 /*!< Select I/O fast output speed */ +#define LL_GPIO_SPEED_FREQ_VERY_HIGH GPIO_OSPEEDR_OSPEED0 /*!< Select I/O high output speed */ +/** + * @} + */ +#define LL_GPIO_SPEED_LOW LL_GPIO_SPEED_FREQ_LOW +#define LL_GPIO_SPEED_MEDIUM LL_GPIO_SPEED_FREQ_MEDIUM +#define LL_GPIO_SPEED_FAST LL_GPIO_SPEED_FREQ_HIGH +#define LL_GPIO_SPEED_HIGH LL_GPIO_SPEED_FREQ_VERY_HIGH + +/** @defgroup GPIO_LL_EC_PULL Pull Up Pull Down + * @{ + */ +#define LL_GPIO_PULL_NO (0x00000000U) /*!< Select I/O no pull */ +#define LL_GPIO_PULL_UP GPIO_PUPDR_PUPD0_0 /*!< Select I/O pull up */ +#define LL_GPIO_PULL_DOWN GPIO_PUPDR_PUPD0_1 /*!< Select I/O pull down */ +/** + * @} + */ + +/** @defgroup GPIO_LL_EC_AF Alternate Function + * @{ + */ +#define LL_GPIO_AF_0 (0x0000000U) /*!< Select alternate function 0 */ +#define LL_GPIO_AF_1 (0x0000001U) /*!< Select alternate function 1 */ +#define LL_GPIO_AF_2 (0x0000002U) /*!< Select alternate function 2 */ +#define LL_GPIO_AF_3 (0x0000003U) /*!< Select alternate function 3 */ +#define LL_GPIO_AF_4 (0x0000004U) /*!< Select alternate function 4 */ +#define LL_GPIO_AF_5 (0x0000005U) /*!< Select alternate function 5 */ +#define LL_GPIO_AF_6 (0x0000006U) /*!< Select alternate function 6 */ +#define LL_GPIO_AF_7 (0x0000007U) /*!< Select alternate function 7 */ +#define LL_GPIO_AF_8 (0x0000008U) /*!< Select alternate function 8 */ +#define LL_GPIO_AF_9 (0x0000009U) /*!< Select alternate function 9 */ +#define LL_GPIO_AF_10 (0x000000AU) /*!< Select alternate function 10 */ +#define LL_GPIO_AF_11 (0x000000BU) /*!< Select alternate function 11 */ +#define LL_GPIO_AF_12 (0x000000CU) /*!< Select alternate function 12 */ +#define LL_GPIO_AF_13 (0x000000DU) /*!< Select alternate function 13 */ +#define LL_GPIO_AF_14 (0x000000EU) /*!< Select alternate function 14 */ +#define LL_GPIO_AF_15 (0x000000FU) /*!< Select alternate function 15 */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup GPIO_LL_Exported_Macros GPIO Exported Macros + * @{ + */ + +/** @defgroup GPIO_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in GPIO register + * @param __INSTANCE__ GPIO Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_GPIO_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in GPIO register + * @param __INSTANCE__ GPIO Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_GPIO_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup GPIO_LL_Exported_Functions GPIO Exported Functions + * @{ + */ + +/** @defgroup GPIO_LL_EF_Port_Configuration Port Configuration + * @{ + */ + +/** + * @brief Configure gpio mode for a dedicated pin on dedicated port. + * @note I/O mode can be Input mode, General purpose output, Alternate function mode or Analog. + * @note Warning: only one pin can be passed as parameter. + * @rmtoll MODER MODEy LL_GPIO_SetPinMode + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @param Mode This parameter can be one of the following values: + * @arg @ref LL_GPIO_MODE_INPUT + * @arg @ref LL_GPIO_MODE_OUTPUT + * @arg @ref LL_GPIO_MODE_ALTERNATE + * @arg @ref LL_GPIO_MODE_ANALOG + * @retval None + */ +__STATIC_INLINE void LL_GPIO_SetPinMode(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Mode) +{ + MODIFY_REG(GPIOx->MODER, (GPIO_MODER_MODE0 << (POSITION_VAL(Pin) * 2U)), (Mode << (POSITION_VAL(Pin) * 2U))); +} + +/** + * @brief Return gpio mode for a dedicated pin on dedicated port. + * @note I/O mode can be Input mode, General purpose output, Alternate function mode or Analog. + * @note Warning: only one pin can be passed as parameter. + * @rmtoll MODER MODEy LL_GPIO_GetPinMode + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @retval Returned value can be one of the following values: + * @arg @ref LL_GPIO_MODE_INPUT + * @arg @ref LL_GPIO_MODE_OUTPUT + * @arg @ref LL_GPIO_MODE_ALTERNATE + * @arg @ref LL_GPIO_MODE_ANALOG + */ +__STATIC_INLINE uint32_t LL_GPIO_GetPinMode(const GPIO_TypeDef *GPIOx, uint32_t Pin) +{ + return (uint32_t)(READ_BIT(GPIOx->MODER, + (GPIO_MODER_MODE0 << (POSITION_VAL(Pin) * 2U))) >> (POSITION_VAL(Pin) * 2U)); +} + +/** + * @brief Configure gpio output type for several pins on dedicated port. + * @note Output type as to be set when gpio pin is in output or + * alternate modes. Possible type are Push-pull or Open-drain. + * @rmtoll OTYPER OTy LL_GPIO_SetPinOutputType + * @param GPIOx GPIO Port + * @param PinMask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @param OutputType This parameter can be one of the following values: + * @arg @ref LL_GPIO_OUTPUT_PUSHPULL + * @arg @ref LL_GPIO_OUTPUT_OPENDRAIN + * @retval None + */ +__STATIC_INLINE void LL_GPIO_SetPinOutputType(GPIO_TypeDef *GPIOx, uint32_t PinMask, uint32_t OutputType) +{ + MODIFY_REG(GPIOx->OTYPER, PinMask, (PinMask * OutputType)); +} + +/** + * @brief Return gpio output type for several pins on dedicated port. + * @note Output type as to be set when gpio pin is in output or + * alternate modes. Possible type are Push-pull or Open-drain. + * @note Warning: only one pin can be passed as parameter. + * @rmtoll OTYPER OTy LL_GPIO_GetPinOutputType + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval Returned value can be one of the following values: + * @arg @ref LL_GPIO_OUTPUT_PUSHPULL + * @arg @ref LL_GPIO_OUTPUT_OPENDRAIN + */ +__STATIC_INLINE uint32_t LL_GPIO_GetPinOutputType(const GPIO_TypeDef *GPIOx, uint32_t Pin) +{ + return (uint32_t)(READ_BIT(GPIOx->OTYPER, Pin) >> POSITION_VAL(Pin)); +} + +/** + * @brief Configure gpio speed for a dedicated pin on dedicated port. + * @note I/O speed can be Low, Medium, Fast or High speed. + * @note Warning: only one pin can be passed as parameter. + * @note Refer to datasheet for frequency specifications and the power + * supply and load conditions for each speed. + * @rmtoll OSPEEDR OSPEEDy LL_GPIO_SetPinSpeed + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @param Speed This parameter can be one of the following values: + * @arg @ref LL_GPIO_SPEED_FREQ_LOW + * @arg @ref LL_GPIO_SPEED_FREQ_MEDIUM + * @arg @ref LL_GPIO_SPEED_FREQ_HIGH + * @arg @ref LL_GPIO_SPEED_FREQ_VERY_HIGH + * @retval None + */ +__STATIC_INLINE void LL_GPIO_SetPinSpeed(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Speed) +{ + MODIFY_REG(GPIOx->OSPEEDR, (GPIO_OSPEEDR_OSPEED0 << (POSITION_VAL(Pin) * 2U)), + (Speed << (POSITION_VAL(Pin) * 2U))); +} + +/** + * @brief Return gpio speed for a dedicated pin on dedicated port. + * @note I/O speed can be Low, Medium, Fast or High speed. + * @note Warning: only one pin can be passed as parameter. + * @note Refer to datasheet for frequency specifications and the power + * supply and load conditions for each speed. + * @rmtoll OSPEEDR OSPEEDy LL_GPIO_GetPinSpeed + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @retval Returned value can be one of the following values: + * @arg @ref LL_GPIO_SPEED_FREQ_LOW + * @arg @ref LL_GPIO_SPEED_FREQ_MEDIUM + * @arg @ref LL_GPIO_SPEED_FREQ_HIGH + * @arg @ref LL_GPIO_SPEED_FREQ_VERY_HIGH + */ +__STATIC_INLINE uint32_t LL_GPIO_GetPinSpeed(const GPIO_TypeDef *GPIOx, uint32_t Pin) +{ + return (uint32_t)(READ_BIT(GPIOx->OSPEEDR, + (GPIO_OSPEEDR_OSPEED0 << (POSITION_VAL(Pin) * 2U))) >> (POSITION_VAL(Pin) * 2U)); +} + +/** + * @brief Configure gpio pull-up or pull-down for a dedicated pin on a dedicated port. + * @note Warning: only one pin can be passed as parameter. + * @rmtoll PUPDR PUPDy LL_GPIO_SetPinPull + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @param Pull This parameter can be one of the following values: + * @arg @ref LL_GPIO_PULL_NO + * @arg @ref LL_GPIO_PULL_UP + * @arg @ref LL_GPIO_PULL_DOWN + * @retval None + */ +__STATIC_INLINE void LL_GPIO_SetPinPull(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Pull) +{ + MODIFY_REG(GPIOx->PUPDR, (GPIO_PUPDR_PUPD0 << (POSITION_VAL(Pin) * 2U)), (Pull << (POSITION_VAL(Pin) * 2U))); +} + +/** + * @brief Return gpio pull-up or pull-down for a dedicated pin on a dedicated port + * @note Warning: only one pin can be passed as parameter. + * @rmtoll PUPDR PUPDy LL_GPIO_GetPinPull + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @retval Returned value can be one of the following values: + * @arg @ref LL_GPIO_PULL_NO + * @arg @ref LL_GPIO_PULL_UP + * @arg @ref LL_GPIO_PULL_DOWN + */ +__STATIC_INLINE uint32_t LL_GPIO_GetPinPull(const GPIO_TypeDef *GPIOx, uint32_t Pin) +{ + return (uint32_t)(READ_BIT(GPIOx->PUPDR, + (GPIO_PUPDR_PUPD0 << (POSITION_VAL(Pin) * 2U))) >> (POSITION_VAL(Pin) * 2U)); +} + +/** + * @brief Configure gpio alternate function of a dedicated pin from 0 to 7 for a dedicated port. + * @note Possible values are from AF0 to AF15 depending on target. + * @note Warning: only one pin can be passed as parameter. + * @rmtoll AFRL AFSELy LL_GPIO_SetAFPin_0_7 + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @param Alternate This parameter can be one of the following values: + * @arg @ref LL_GPIO_AF_0 + * @arg @ref LL_GPIO_AF_1 + * @arg @ref LL_GPIO_AF_2 + * @arg @ref LL_GPIO_AF_3 + * @arg @ref LL_GPIO_AF_4 + * @arg @ref LL_GPIO_AF_5 + * @arg @ref LL_GPIO_AF_6 + * @arg @ref LL_GPIO_AF_7 + * @arg @ref LL_GPIO_AF_8 + * @arg @ref LL_GPIO_AF_9 + * @arg @ref LL_GPIO_AF_10 + * @arg @ref LL_GPIO_AF_11 + * @arg @ref LL_GPIO_AF_12 + * @arg @ref LL_GPIO_AF_13 + * @arg @ref LL_GPIO_AF_14 + * @arg @ref LL_GPIO_AF_15 + * @retval None + */ +__STATIC_INLINE void LL_GPIO_SetAFPin_0_7(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Alternate) +{ + MODIFY_REG(GPIOx->AFR[0], (GPIO_AFRL_AFSEL0 << (POSITION_VAL(Pin) * 4U)), + (Alternate << (POSITION_VAL(Pin) * 4U))); +} + +/** + * @brief Return gpio alternate function of a dedicated pin from 0 to 7 for a dedicated port. + * @rmtoll AFRL AFSELy LL_GPIO_GetAFPin_0_7 + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_GPIO_AF_0 + * @arg @ref LL_GPIO_AF_1 + * @arg @ref LL_GPIO_AF_2 + * @arg @ref LL_GPIO_AF_3 + * @arg @ref LL_GPIO_AF_4 + * @arg @ref LL_GPIO_AF_5 + * @arg @ref LL_GPIO_AF_6 + * @arg @ref LL_GPIO_AF_7 + * @arg @ref LL_GPIO_AF_8 + * @arg @ref LL_GPIO_AF_9 + * @arg @ref LL_GPIO_AF_10 + * @arg @ref LL_GPIO_AF_11 + * @arg @ref LL_GPIO_AF_12 + * @arg @ref LL_GPIO_AF_13 + * @arg @ref LL_GPIO_AF_14 + * @arg @ref LL_GPIO_AF_15 + */ +__STATIC_INLINE uint32_t LL_GPIO_GetAFPin_0_7(const GPIO_TypeDef *GPIOx, uint32_t Pin) +{ + return (uint32_t)(READ_BIT(GPIOx->AFR[0], + (GPIO_AFRL_AFSEL0 << (POSITION_VAL(Pin) * 4U))) >> (POSITION_VAL(Pin) * 4U)); +} + +/** + * @brief Configure gpio alternate function of a dedicated pin from 8 to 15 for a dedicated port. + * @note Possible values are from AF0 to AF15 depending on target. + * @note Warning: only one pin can be passed as parameter. + * @rmtoll AFRH AFSELy LL_GPIO_SetAFPin_8_15 + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @param Alternate This parameter can be one of the following values: + * @arg @ref LL_GPIO_AF_0 + * @arg @ref LL_GPIO_AF_1 + * @arg @ref LL_GPIO_AF_2 + * @arg @ref LL_GPIO_AF_3 + * @arg @ref LL_GPIO_AF_4 + * @arg @ref LL_GPIO_AF_5 + * @arg @ref LL_GPIO_AF_6 + * @arg @ref LL_GPIO_AF_7 + * @arg @ref LL_GPIO_AF_8 + * @arg @ref LL_GPIO_AF_9 + * @arg @ref LL_GPIO_AF_10 + * @arg @ref LL_GPIO_AF_11 + * @arg @ref LL_GPIO_AF_12 + * @arg @ref LL_GPIO_AF_13 + * @arg @ref LL_GPIO_AF_14 + * @arg @ref LL_GPIO_AF_15 + * @retval None + */ +__STATIC_INLINE void LL_GPIO_SetAFPin_8_15(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Alternate) +{ + MODIFY_REG(GPIOx->AFR[1], (GPIO_AFRH_AFSEL8 << (POSITION_VAL(Pin >> 8U) * 4U)), + (Alternate << (POSITION_VAL(Pin >> 8U) * 4U))); +} + +/** + * @brief Return gpio alternate function of a dedicated pin from 8 to 15 for a dedicated port. + * @note Possible values are from AF0 to AF15 depending on target. + * @rmtoll AFRH AFSELy LL_GPIO_GetAFPin_8_15 + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @retval Returned value can be one of the following values: + * @arg @ref LL_GPIO_AF_0 + * @arg @ref LL_GPIO_AF_1 + * @arg @ref LL_GPIO_AF_2 + * @arg @ref LL_GPIO_AF_3 + * @arg @ref LL_GPIO_AF_4 + * @arg @ref LL_GPIO_AF_5 + * @arg @ref LL_GPIO_AF_6 + * @arg @ref LL_GPIO_AF_7 + * @arg @ref LL_GPIO_AF_8 + * @arg @ref LL_GPIO_AF_9 + * @arg @ref LL_GPIO_AF_10 + * @arg @ref LL_GPIO_AF_11 + * @arg @ref LL_GPIO_AF_12 + * @arg @ref LL_GPIO_AF_13 + * @arg @ref LL_GPIO_AF_14 + * @arg @ref LL_GPIO_AF_15 + */ +__STATIC_INLINE uint32_t LL_GPIO_GetAFPin_8_15(const GPIO_TypeDef *GPIOx, uint32_t Pin) +{ + return (uint32_t)(READ_BIT(GPIOx->AFR[1], + (GPIO_AFRH_AFSEL8 << (POSITION_VAL(Pin >> 8U) * 4U))) >> (POSITION_VAL(Pin >> 8U) * 4U)); +} + +/** + * @brief Lock configuration of several pins for a dedicated port. + * @note When the lock sequence has been applied on a port bit, the + * value of this port bit can no longer be modified until the + * next reset. + * @note Each lock bit freezes a specific configuration register + * (control and alternate function registers). + * @rmtoll LCKR LCKK LL_GPIO_LockPin + * @param GPIOx GPIO Port + * @param PinMask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void LL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint32_t PinMask) +{ + __IO uint32_t temp; + WRITE_REG(GPIOx->LCKR, GPIO_LCKR_LCKK | PinMask); + WRITE_REG(GPIOx->LCKR, PinMask); + WRITE_REG(GPIOx->LCKR, GPIO_LCKR_LCKK | PinMask); + /* Read LCKK register. This read is mandatory to complete key lock sequence */ + temp = READ_REG(GPIOx->LCKR); + (void) temp; +} + +/** + * @brief Return 1 if all pins passed as parameter, of a dedicated port, are locked. else Return 0. + * @rmtoll LCKR LCKy LL_GPIO_IsPinLocked + * @param GPIOx GPIO Port + * @param PinMask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_GPIO_IsPinLocked(const GPIO_TypeDef *GPIOx, uint32_t PinMask) +{ + return ((READ_BIT(GPIOx->LCKR, PinMask) == (PinMask)) ? 1UL : 0UL); +} + +/** + * @brief Return 1 if one of the pin of a dedicated port is locked. else return 0. + * @rmtoll LCKR LCKK LL_GPIO_IsAnyPinLocked + * @param GPIOx GPIO Port + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_GPIO_IsAnyPinLocked(const GPIO_TypeDef *GPIOx) +{ + return ((READ_BIT(GPIOx->LCKR, GPIO_LCKR_LCKK) == (GPIO_LCKR_LCKK)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup GPIO_LL_EF_Data_Access Data Access + * @{ + */ + +/** + * @brief Return full input data register value for a dedicated port. + * @rmtoll IDR IDy LL_GPIO_ReadInputPort + * @param GPIOx GPIO Port + * @retval Input data register value of port + */ +__STATIC_INLINE uint32_t LL_GPIO_ReadInputPort(const GPIO_TypeDef *GPIOx) +{ + return (uint32_t)(READ_REG(GPIOx->IDR)); +} + +/** + * @brief Return if input data level for several pins of dedicated port is high or low. + * @rmtoll IDR IDy LL_GPIO_IsInputPinSet + * @param GPIOx GPIO Port + * @param PinMask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_GPIO_IsInputPinSet(const GPIO_TypeDef *GPIOx, uint32_t PinMask) +{ + return ((READ_BIT(GPIOx->IDR, PinMask) == (PinMask)) ? 1UL : 0UL); +} + +/** + * @brief Write output data register for the port. + * @rmtoll ODR ODy LL_GPIO_WriteOutputPort + * @param GPIOx GPIO Port + * @param PortValue Level value for each pin of the port + * @retval None + */ +__STATIC_INLINE void LL_GPIO_WriteOutputPort(GPIO_TypeDef *GPIOx, uint32_t PortValue) +{ + WRITE_REG(GPIOx->ODR, PortValue); +} + +/** + * @brief Return full output data register value for a dedicated port. + * @rmtoll ODR ODy LL_GPIO_ReadOutputPort + * @param GPIOx GPIO Port + * @retval Output data register value of port + */ +__STATIC_INLINE uint32_t LL_GPIO_ReadOutputPort(const GPIO_TypeDef *GPIOx) +{ + return (uint32_t)(READ_REG(GPIOx->ODR)); +} + +/** + * @brief Return if input data level for several pins of dedicated port is high or low. + * @rmtoll ODR ODy LL_GPIO_IsOutputPinSet + * @param GPIOx GPIO Port + * @param PinMask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_GPIO_IsOutputPinSet(const GPIO_TypeDef *GPIOx, uint32_t PinMask) +{ + return ((READ_BIT(GPIOx->ODR, PinMask) == (PinMask)) ? 1UL : 0UL); +} + +/** + * @brief Set several pins to high level on dedicated gpio port. + * @rmtoll BSRR BSy LL_GPIO_SetOutputPin + * @param GPIOx GPIO Port + * @param PinMask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void LL_GPIO_SetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMask) +{ + WRITE_REG(GPIOx->BSRR, PinMask); +} + +/** + * @brief Set several pins to low level on dedicated gpio port. + * @rmtoll BRR BRy LL_GPIO_ResetOutputPin + * @param GPIOx GPIO Port + * @param PinMask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void LL_GPIO_ResetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMask) +{ + WRITE_REG(GPIOx->BRR, PinMask); +} + +/** + * @brief Toggle data value for several pin of dedicated port. + * @rmtoll ODR ODy LL_GPIO_TogglePin + * @param GPIOx GPIO Port + * @param PinMask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void LL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint32_t PinMask) +{ + uint32_t odr = READ_REG(GPIOx->ODR); + WRITE_REG(GPIOx->BSRR, ((odr & PinMask) << 16u) | (~odr & PinMask)); +} + +/** + * @brief Enable speed optimization for several pin of dedicated port. + * @note Not all I/Os support the HSLV mode. Refer to the I/O structure in the corresponding + * datasheet for the list of I/Os supporting this feature. Other I/Os HSLV configuration must + * be kept at reset value. + * @note It must be used only if the I/O supply voltage is below 2.7 V. + * @rmtoll HSLVR HSLVy LL_GPIO_EnableHighSPeedLowVoltage + * @param GPIOx GPIO Port + * @param PinMask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @retval None + */ +__STATIC_INLINE void LL_GPIO_EnableHighSPeedLowVoltage(GPIO_TypeDef *GPIOx, uint32_t PinMask) +{ + SET_BIT(GPIOx->HSLVR, PinMask); +} + + +/** + * @brief Disable speed optimization for several pin of dedicated port. + * @note Not all I/Os support the HSLV mode. Refer to the I/O structure in the corresponding + * datasheet for the list of I/Os supporting this feature. Other I/Os HSLV configuration must + * be kept at reset value. + * @note It must be used only if the I/O supply voltage is below 2.7 V. + * @rmtoll HSLVR HSLVy LL_GPIO_DisableHighSPeedLowVoltage + * @param GPIOx GPIO Port + * @param PinMask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @retval None + */ +__STATIC_INLINE void LL_GPIO_DisableHighSPeedLowVoltage(GPIO_TypeDef *GPIOx, uint32_t PinMask) +{ + CLEAR_BIT(GPIOx->HSLVR, PinMask); +} + +/** + * @brief Return if speed optimization for several pin of dedicated port is enabled or not. + * @note Not all I/Os support the HSLV mode. Refer to the I/O structure in the corresponding + * datasheet for the list of I/Os supporting this feature. Other I/Os HSLV configuration must + * be kept at reset value. + * @note It must be used only if the I/O supply voltage is below 2.7 V. + * @rmtoll HSLVR HSLVy LL_GPIO_IsEnabledHighSPeedLowVoltage + * @param GPIOx GPIO Port + * @param PinMask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_GPIO_IsEnabledHighSPeedLowVoltage(const GPIO_TypeDef *GPIOx, uint32_t PinMask) +{ + return ((READ_BIT(GPIOx->HSLVR, PinMask) == (PinMask)) ? 1UL : 0UL); +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + * @brief Enable secure write only access for several pin of dedicated port. + * @rmtoll SECCFGR SECy LL_GPIO_EnablePinSecure + * @param GPIOx GPIO Port + * @param PinMask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void LL_GPIO_EnablePinSecure(GPIO_TypeDef *GPIOx, uint32_t PinMask) +{ + SET_BIT(GPIOx->SECCFGR, PinMask); +} + + +/** + * @brief Disable secure write only access for several pin of dedicated port. + * @rmtoll SECCFGR SECy LL_GPIO_DisablePinSecure + * @param GPIOx GPIO Port + * @param PinMask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval None + */ +__STATIC_INLINE void LL_GPIO_DisablePinSecure(GPIO_TypeDef *GPIOx, uint32_t PinMask) +{ + CLEAR_BIT(GPIOx->SECCFGR, PinMask); +} + +#endif /* __ARM_FEATURE_CMSE */ + +/** + * @brief Return if secure write only access for several pin of dedicated port is enabled or not. + * @rmtoll SECCFGR SECy LL_GPIO_IsEnabledPinSecure + * @param GPIOx GPIO Port + * @param PinMask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_GPIO_IsEnabledPinSecure(const GPIO_TypeDef *GPIOx, uint32_t PinMask) +{ + return ((READ_BIT(GPIOx->SECCFGR, PinMask) == (PinMask)) ? 1UL : 0UL); +} + + +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup GPIO_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +ErrorStatus LL_GPIO_DeInit(const GPIO_TypeDef *GPIOx); +ErrorStatus LL_GPIO_Init(GPIO_TypeDef *GPIOx, LL_GPIO_InitTypeDef *GPIO_InitStruct); +void LL_GPIO_StructInit(LL_GPIO_InitTypeDef *GPIO_InitStruct); + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined (GPIOA) || defined (GPIOB) || defined (GPIOC) || defined (GPIOD) || defined (GPIOE) || \ + defined (GPIOF) || defined (GPIOG) || defined (GPIOH) || defined (GPIOI) */ +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_LL_GPIO_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_i2c.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_i2c.h new file mode 100644 index 0000000000..e4b4932e84 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_i2c.h @@ -0,0 +1,2373 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_i2c.h + * @author MCD Application Team + * @brief Header file of I2C LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_LL_I2C_H +#define STM32H5xx_LL_I2C_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (I2C1) || defined (I2C2) || defined (I2C3) || defined (I2C4) + +/** @defgroup I2C_LL I2C + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup I2C_LL_Private_Constants I2C Private Constants + * @{ + */ +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup I2C_LL_Private_Macros I2C Private Macros + * @{ + */ +/** + * @} + */ +#endif /*USE_FULL_LL_DRIVER*/ + +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup I2C_LL_ES_INIT I2C Exported Init structure + * @{ + */ +typedef struct +{ + uint32_t PeripheralMode; /*!< Specifies the peripheral mode. + This parameter can be a value of @ref I2C_LL_EC_PERIPHERAL_MODE. + + This feature can be modified afterwards using unitary function + @ref LL_I2C_SetMode(). */ + + uint32_t Timing; /*!< Specifies the SDA setup, hold time and the SCL high, low period values. + This parameter must be set by referring to the STM32CubeMX Tool and + the helper macro @ref __LL_I2C_CONVERT_TIMINGS(). + + This feature can be modified afterwards using unitary function + @ref LL_I2C_SetTiming(). */ + + uint32_t AnalogFilter; /*!< Enables or disables analog noise filter. + This parameter can be a value of @ref I2C_LL_EC_ANALOGFILTER_SELECTION. + + This feature can be modified afterwards using unitary functions + @ref LL_I2C_EnableAnalogFilter() or LL_I2C_DisableAnalogFilter(). */ + + uint32_t DigitalFilter; /*!< Configures the digital noise filter. + This parameter can be a number between Min_Data = 0x00 and Max_Data = 0x0F. + + This feature can be modified afterwards using unitary function + @ref LL_I2C_SetDigitalFilter(). */ + + uint32_t OwnAddress1; /*!< Specifies the device own address 1. + This parameter must be a value between Min_Data = 0x00 and Max_Data = 0x3FF. + + This feature can be modified afterwards using unitary function + @ref LL_I2C_SetOwnAddress1(). */ + + uint32_t TypeAcknowledge; /*!< Specifies the ACKnowledge or Non ACKnowledge condition after the address receive + match code or next received byte. + This parameter can be a value of @ref I2C_LL_EC_I2C_ACKNOWLEDGE. + + This feature can be modified afterwards using unitary function + @ref LL_I2C_AcknowledgeNextData(). */ + + uint32_t OwnAddrSize; /*!< Specifies the device own address 1 size (7-bit or 10-bit). + This parameter can be a value of @ref I2C_LL_EC_OWNADDRESS1. + + This feature can be modified afterwards using unitary function + @ref LL_I2C_SetOwnAddress1(). */ +} LL_I2C_InitTypeDef; +/** + * @} + */ +#endif /*USE_FULL_LL_DRIVER*/ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup I2C_LL_Exported_Constants I2C Exported Constants + * @{ + */ + +/** @defgroup I2C_LL_EC_CLEAR_FLAG Clear Flags Defines + * @brief Flags defines which can be used with LL_I2C_WriteReg function + * @{ + */ +#define LL_I2C_ICR_ADDRCF I2C_ICR_ADDRCF /*!< Address Matched flag */ +#define LL_I2C_ICR_NACKCF I2C_ICR_NACKCF /*!< Not Acknowledge flag */ +#define LL_I2C_ICR_STOPCF I2C_ICR_STOPCF /*!< Stop detection flag */ +#define LL_I2C_ICR_BERRCF I2C_ICR_BERRCF /*!< Bus error flag */ +#define LL_I2C_ICR_ARLOCF I2C_ICR_ARLOCF /*!< Arbitration Lost flag */ +#define LL_I2C_ICR_OVRCF I2C_ICR_OVRCF /*!< Overrun/Underrun flag */ +#define LL_I2C_ICR_PECCF I2C_ICR_PECCF /*!< PEC error flag */ +#define LL_I2C_ICR_TIMOUTCF I2C_ICR_TIMOUTCF /*!< Timeout detection flag */ +#define LL_I2C_ICR_ALERTCF I2C_ICR_ALERTCF /*!< Alert flag */ +/** + * @} + */ + +/** @defgroup I2C_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_I2C_ReadReg function + * @{ + */ +#define LL_I2C_ISR_TXE I2C_ISR_TXE /*!< Transmit data register empty */ +#define LL_I2C_ISR_TXIS I2C_ISR_TXIS /*!< Transmit interrupt status */ +#define LL_I2C_ISR_RXNE I2C_ISR_RXNE /*!< Receive data register not empty */ +#define LL_I2C_ISR_ADDR I2C_ISR_ADDR /*!< Address matched (slave mode) */ +#define LL_I2C_ISR_NACKF I2C_ISR_NACKF /*!< Not Acknowledge received flag */ +#define LL_I2C_ISR_STOPF I2C_ISR_STOPF /*!< Stop detection flag */ +#define LL_I2C_ISR_TC I2C_ISR_TC /*!< Transfer Complete (master mode) */ +#define LL_I2C_ISR_TCR I2C_ISR_TCR /*!< Transfer Complete Reload */ +#define LL_I2C_ISR_BERR I2C_ISR_BERR /*!< Bus error */ +#define LL_I2C_ISR_ARLO I2C_ISR_ARLO /*!< Arbitration lost */ +#define LL_I2C_ISR_OVR I2C_ISR_OVR /*!< Overrun/Underrun (slave mode) */ +#define LL_I2C_ISR_PECERR I2C_ISR_PECERR /*!< PEC Error in reception (SMBus mode) */ +#define LL_I2C_ISR_TIMEOUT I2C_ISR_TIMEOUT /*!< Timeout detection flag (SMBus mode) */ +#define LL_I2C_ISR_ALERT I2C_ISR_ALERT /*!< SMBus alert (SMBus mode) */ +#define LL_I2C_ISR_BUSY I2C_ISR_BUSY /*!< Bus busy */ +/** + * @} + */ + +/** @defgroup I2C_LL_EC_IT IT Defines + * @brief IT defines which can be used with LL_I2C_ReadReg and LL_I2C_WriteReg functions + * @{ + */ +#define LL_I2C_CR1_TXIE I2C_CR1_TXIE /*!< TX Interrupt enable */ +#define LL_I2C_CR1_RXIE I2C_CR1_RXIE /*!< RX Interrupt enable */ +#define LL_I2C_CR1_ADDRIE I2C_CR1_ADDRIE /*!< Address match Interrupt enable (slave only) */ +#define LL_I2C_CR1_NACKIE I2C_CR1_NACKIE /*!< Not acknowledge received Interrupt enable */ +#define LL_I2C_CR1_STOPIE I2C_CR1_STOPIE /*!< STOP detection Interrupt enable */ +#define LL_I2C_CR1_TCIE I2C_CR1_TCIE /*!< Transfer Complete interrupt enable */ +#define LL_I2C_CR1_ERRIE I2C_CR1_ERRIE /*!< Error interrupts enable */ +/** + * @} + */ + +/** @defgroup I2C_LL_EC_PERIPHERAL_MODE Peripheral Mode + * @{ + */ +#define LL_I2C_MODE_I2C 0x00000000U /*!< I2C Master or Slave mode */ +#define LL_I2C_MODE_SMBUS_HOST I2C_CR1_SMBHEN /*!< SMBus Host address acknowledge */ +#define LL_I2C_MODE_SMBUS_DEVICE 0x00000000U /*!< SMBus Device default mode + (Default address not acknowledge) */ +#define LL_I2C_MODE_SMBUS_DEVICE_ARP I2C_CR1_SMBDEN /*!< SMBus Device Default address acknowledge */ +/** + * @} + */ + +/** @defgroup I2C_LL_EC_ANALOGFILTER_SELECTION Analog Filter Selection + * @{ + */ +#define LL_I2C_ANALOGFILTER_ENABLE 0x00000000U /*!< Analog filter is enabled. */ +#define LL_I2C_ANALOGFILTER_DISABLE I2C_CR1_ANFOFF /*!< Analog filter is disabled. */ +/** + * @} + */ + +/** @defgroup I2C_LL_EC_ADDRESSING_MODE Master Addressing Mode + * @{ + */ +#define LL_I2C_ADDRESSING_MODE_7BIT 0x00000000U /*!< Master operates in 7-bit addressing mode. */ +#define LL_I2C_ADDRESSING_MODE_10BIT I2C_CR2_ADD10 /*!< Master operates in 10-bit addressing mode.*/ +/** + * @} + */ + +/** @defgroup I2C_LL_EC_OWNADDRESS1 Own Address 1 Length + * @{ + */ +#define LL_I2C_OWNADDRESS1_7BIT 0x00000000U /*!< Own address 1 is a 7-bit address. */ +#define LL_I2C_OWNADDRESS1_10BIT I2C_OAR1_OA1MODE /*!< Own address 1 is a 10-bit address.*/ +/** + * @} + */ + +/** @defgroup I2C_LL_EC_OWNADDRESS2 Own Address 2 Masks + * @{ + */ +#define LL_I2C_OWNADDRESS2_NOMASK I2C_OAR2_OA2NOMASK /*!< Own Address2 No mask. */ +#define LL_I2C_OWNADDRESS2_MASK01 I2C_OAR2_OA2MASK01 /*!< Only Address2 bits[7:2] are compared. */ +#define LL_I2C_OWNADDRESS2_MASK02 I2C_OAR2_OA2MASK02 /*!< Only Address2 bits[7:3] are compared. */ +#define LL_I2C_OWNADDRESS2_MASK03 I2C_OAR2_OA2MASK03 /*!< Only Address2 bits[7:4] are compared. */ +#define LL_I2C_OWNADDRESS2_MASK04 I2C_OAR2_OA2MASK04 /*!< Only Address2 bits[7:5] are compared. */ +#define LL_I2C_OWNADDRESS2_MASK05 I2C_OAR2_OA2MASK05 /*!< Only Address2 bits[7:6] are compared. */ +#define LL_I2C_OWNADDRESS2_MASK06 I2C_OAR2_OA2MASK06 /*!< Only Address2 bits[7] are compared. */ +#define LL_I2C_OWNADDRESS2_MASK07 I2C_OAR2_OA2MASK07 /*!< No comparison is done. + All Address2 are acknowledged. */ +/** + * @} + */ + +/** @defgroup I2C_LL_EC_I2C_ACKNOWLEDGE Acknowledge Generation + * @{ + */ +#define LL_I2C_ACK 0x00000000U /*!< ACK is sent after current received byte. */ +#define LL_I2C_NACK I2C_CR2_NACK /*!< NACK is sent after current received byte.*/ +/** + * @} + */ + +/** @defgroup I2C_LL_EC_ADDRSLAVE Slave Address Length + * @{ + */ +#define LL_I2C_ADDRSLAVE_7BIT 0x00000000U /*!< Slave Address in 7-bit. */ +#define LL_I2C_ADDRSLAVE_10BIT I2C_CR2_ADD10 /*!< Slave Address in 10-bit.*/ +/** + * @} + */ + +/** @defgroup I2C_LL_EC_REQUEST Transfer Request Direction + * @{ + */ +#define LL_I2C_REQUEST_WRITE 0x00000000U /*!< Master request a write transfer. */ +#define LL_I2C_REQUEST_READ I2C_CR2_RD_WRN /*!< Master request a read transfer. */ +/** + * @} + */ + +/** @defgroup I2C_LL_EC_MODE Transfer End Mode + * @{ + */ +#define LL_I2C_MODE_RELOAD I2C_CR2_RELOAD /*!< Enable I2C Reload mode. */ +#define LL_I2C_MODE_AUTOEND I2C_CR2_AUTOEND /*!< Enable I2C Automatic end mode + with no HW PEC comparison. */ +#define LL_I2C_MODE_SOFTEND 0x00000000U /*!< Enable I2C Software end mode + with no HW PEC comparison. */ +#define LL_I2C_MODE_SMBUS_RELOAD LL_I2C_MODE_RELOAD /*!< Enable SMBUS Automatic end mode + with HW PEC comparison. */ +#define LL_I2C_MODE_SMBUS_AUTOEND_NO_PEC LL_I2C_MODE_AUTOEND /*!< Enable SMBUS Automatic end mode + with HW PEC comparison. */ +#define LL_I2C_MODE_SMBUS_SOFTEND_NO_PEC LL_I2C_MODE_SOFTEND /*!< Enable SMBUS Software end mode + with HW PEC comparison. */ +#define LL_I2C_MODE_SMBUS_AUTOEND_WITH_PEC (uint32_t)(LL_I2C_MODE_AUTOEND | I2C_CR2_PECBYTE) +/*!< Enable SMBUS Automatic end mode with HW PEC comparison. */ +#define LL_I2C_MODE_SMBUS_SOFTEND_WITH_PEC (uint32_t)(LL_I2C_MODE_SOFTEND | I2C_CR2_PECBYTE) +/*!< Enable SMBUS Software end mode with HW PEC comparison. */ +/** + * @} + */ + +/** @defgroup I2C_LL_EC_GENERATE Start And Stop Generation + * @{ + */ +#define LL_I2C_GENERATE_NOSTARTSTOP 0x00000000U +/*!< Don't Generate Stop and Start condition. */ +#define LL_I2C_GENERATE_STOP (uint32_t)(0x80000000U | I2C_CR2_STOP) +/*!< Generate Stop condition (Size should be set to 0). */ +#define LL_I2C_GENERATE_START_READ (uint32_t)(0x80000000U | I2C_CR2_START | I2C_CR2_RD_WRN) +/*!< Generate Start for read request. */ +#define LL_I2C_GENERATE_START_WRITE (uint32_t)(0x80000000U | I2C_CR2_START) +/*!< Generate Start for write request. */ +#define LL_I2C_GENERATE_RESTART_7BIT_READ (uint32_t)(0x80000000U | I2C_CR2_START | I2C_CR2_RD_WRN) +/*!< Generate Restart for read request, slave 7Bit address. */ +#define LL_I2C_GENERATE_RESTART_7BIT_WRITE (uint32_t)(0x80000000U | I2C_CR2_START) +/*!< Generate Restart for write request, slave 7Bit address. */ +#define LL_I2C_GENERATE_RESTART_10BIT_READ (uint32_t)(0x80000000U | I2C_CR2_START | \ + I2C_CR2_RD_WRN | I2C_CR2_HEAD10R) +/*!< Generate Restart for read request, slave 10Bit address. */ +#define LL_I2C_GENERATE_RESTART_10BIT_WRITE (uint32_t)(0x80000000U | I2C_CR2_START) +/*!< Generate Restart for write request, slave 10Bit address.*/ +/** + * @} + */ + +/** @defgroup I2C_LL_EC_DIRECTION Read Write Direction + * @{ + */ +#define LL_I2C_DIRECTION_WRITE 0x00000000U /*!< Write transfer request by master, + slave enters receiver mode. */ +#define LL_I2C_DIRECTION_READ I2C_ISR_DIR /*!< Read transfer request by master, + slave enters transmitter mode.*/ +/** + * @} + */ + +/** @defgroup I2C_LL_EC_DMA_REG_DATA DMA Register Data + * @{ + */ +#define LL_I2C_DMA_REG_DATA_TRANSMIT 0x00000000U /*!< Get address of data register used for + transmission */ +#define LL_I2C_DMA_REG_DATA_RECEIVE 0x00000001U /*!< Get address of data register used for + reception */ +/** + * @} + */ + +/** @defgroup I2C_LL_EC_SMBUS_TIMEOUTA_MODE SMBus TimeoutA Mode SCL SDA Timeout + * @{ + */ +#define LL_I2C_SMBUS_TIMEOUTA_MODE_SCL_LOW 0x00000000U /*!< TimeoutA is used to detect + SCL low level timeout. */ +#define LL_I2C_SMBUS_TIMEOUTA_MODE_SDA_SCL_HIGH I2C_TIMEOUTR_TIDLE /*!< TimeoutA is used to detect + both SCL and SDA high level timeout.*/ +/** + * @} + */ + +/** @defgroup I2C_LL_EC_SMBUS_TIMEOUT_SELECTION SMBus Timeout Selection + * @{ + */ +#define LL_I2C_SMBUS_TIMEOUTA I2C_TIMEOUTR_TIMOUTEN /*!< TimeoutA enable bit */ +#define LL_I2C_SMBUS_TIMEOUTB I2C_TIMEOUTR_TEXTEN /*!< TimeoutB (extended clock) + enable bit */ +#define LL_I2C_SMBUS_ALL_TIMEOUT (uint32_t)(I2C_TIMEOUTR_TIMOUTEN | \ + I2C_TIMEOUTR_TEXTEN) /*!< TimeoutA and TimeoutB +(extended clock) enable bits */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup I2C_LL_Exported_Macros I2C Exported Macros + * @{ + */ + +/** @defgroup I2C_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in I2C register + * @param __INSTANCE__ I2C Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_I2C_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in I2C register + * @param __INSTANCE__ I2C Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_I2C_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) +/** + * @} + */ + +/** @defgroup I2C_LL_EM_CONVERT_TIMINGS Convert SDA SCL timings + * @{ + */ +/** + * @brief Configure the SDA setup, hold time and the SCL high, low period. + * @param __PRESCALER__ This parameter must be a value between Min_Data=0 and Max_Data=0xF. + * @param __SETUP_TIME__ This parameter must be a value between Min_Data=0 and Max_Data=0xF. + (tscldel = (SCLDEL+1)xtpresc) + * @param __HOLD_TIME__ This parameter must be a value between Min_Data=0 and Max_Data=0xF. + (tsdadel = SDADELxtpresc) + * @param __SCLH_PERIOD__ This parameter must be a value between Min_Data=0 and Max_Data=0xFF. + (tsclh = (SCLH+1)xtpresc) + * @param __SCLL_PERIOD__ This parameter must be a value between Min_Data=0 and Max_Data=0xFF. + (tscll = (SCLL+1)xtpresc) + * @retval Value between Min_Data=0 and Max_Data=0xFFFFFFFF + */ +#define __LL_I2C_CONVERT_TIMINGS(__PRESCALER__, __SETUP_TIME__, __HOLD_TIME__, __SCLH_PERIOD__, __SCLL_PERIOD__) \ + ((((uint32_t)(__PRESCALER__) << I2C_TIMINGR_PRESC_Pos) & I2C_TIMINGR_PRESC) | \ + (((uint32_t)(__SETUP_TIME__) << I2C_TIMINGR_SCLDEL_Pos) & I2C_TIMINGR_SCLDEL) | \ + (((uint32_t)(__HOLD_TIME__) << I2C_TIMINGR_SDADEL_Pos) & I2C_TIMINGR_SDADEL) | \ + (((uint32_t)(__SCLH_PERIOD__) << I2C_TIMINGR_SCLH_Pos) & I2C_TIMINGR_SCLH) | \ + (((uint32_t)(__SCLL_PERIOD__) << I2C_TIMINGR_SCLL_Pos) & I2C_TIMINGR_SCLL)) +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup I2C_LL_Exported_Functions I2C Exported Functions + * @{ + */ + +/** @defgroup I2C_LL_EF_Configuration Configuration + * @{ + */ + +/** + * @brief Enable I2C peripheral (PE = 1). + * @rmtoll CR1 PE LL_I2C_Enable + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_Enable(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CR1, I2C_CR1_PE); +} + +/** + * @brief Disable I2C peripheral (PE = 0). + * @note When PE = 0, the I2C SCL and SDA lines are released. + * Internal state machines and status bits are put back to their reset value. + * When cleared, PE must be kept low for at least 3 APB clock cycles. + * @rmtoll CR1 PE LL_I2C_Disable + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_Disable(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CR1, I2C_CR1_PE); +} + +/** + * @brief Check if the I2C peripheral is enabled or disabled. + * @rmtoll CR1 PE LL_I2C_IsEnabled + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsEnabled(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->CR1, I2C_CR1_PE) == (I2C_CR1_PE)) ? 1UL : 0UL); +} + +/** + * @brief Configure Noise Filters (Analog and Digital). + * @note If the analog filter is also enabled, the digital filter is added to analog filter. + * The filters can only be programmed when the I2C is disabled (PE = 0). + * @rmtoll CR1 ANFOFF LL_I2C_ConfigFilters\n + * CR1 DNF LL_I2C_ConfigFilters + * @param I2Cx I2C Instance. + * @param AnalogFilter This parameter can be one of the following values: + * @arg @ref LL_I2C_ANALOGFILTER_ENABLE + * @arg @ref LL_I2C_ANALOGFILTER_DISABLE + * @param DigitalFilter This parameter must be a value between Min_Data=0x00 (Digital filter disabled) + and Max_Data=0x0F (Digital filter enabled and filtering capability up to 15*ti2cclk). + * This parameter is used to configure the digital noise filter on SDA and SCL input. + * The digital filter will filter spikes with a length of up to DNF[3:0]*ti2cclk. + * @retval None + */ +__STATIC_INLINE void LL_I2C_ConfigFilters(I2C_TypeDef *I2Cx, uint32_t AnalogFilter, uint32_t DigitalFilter) +{ + MODIFY_REG(I2Cx->CR1, I2C_CR1_ANFOFF | I2C_CR1_DNF, AnalogFilter | (DigitalFilter << I2C_CR1_DNF_Pos)); +} + +/** + * @brief Configure Digital Noise Filter. + * @note If the analog filter is also enabled, the digital filter is added to analog filter. + * This filter can only be programmed when the I2C is disabled (PE = 0). + * @rmtoll CR1 DNF LL_I2C_SetDigitalFilter + * @param I2Cx I2C Instance. + * @param DigitalFilter This parameter must be a value between Min_Data=0x00 (Digital filter disabled) + and Max_Data=0x0F (Digital filter enabled and filtering capability up to 15*ti2cclk). + * This parameter is used to configure the digital noise filter on SDA and SCL input. + * The digital filter will filter spikes with a length of up to DNF[3:0]*ti2cclk. + * @retval None + */ +__STATIC_INLINE void LL_I2C_SetDigitalFilter(I2C_TypeDef *I2Cx, uint32_t DigitalFilter) +{ + MODIFY_REG(I2Cx->CR1, I2C_CR1_DNF, DigitalFilter << I2C_CR1_DNF_Pos); +} + +/** + * @brief Get the current Digital Noise Filter configuration. + * @rmtoll CR1 DNF LL_I2C_GetDigitalFilter + * @param I2Cx I2C Instance. + * @retval Value between Min_Data=0x0 and Max_Data=0xF + */ +__STATIC_INLINE uint32_t LL_I2C_GetDigitalFilter(const I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->CR1, I2C_CR1_DNF) >> I2C_CR1_DNF_Pos); +} + +/** + * @brief Enable Analog Noise Filter. + * @note This filter can only be programmed when the I2C is disabled (PE = 0). + * @rmtoll CR1 ANFOFF LL_I2C_EnableAnalogFilter + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_EnableAnalogFilter(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CR1, I2C_CR1_ANFOFF); +} + +/** + * @brief Disable Analog Noise Filter. + * @note This filter can only be programmed when the I2C is disabled (PE = 0). + * @rmtoll CR1 ANFOFF LL_I2C_DisableAnalogFilter + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_DisableAnalogFilter(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CR1, I2C_CR1_ANFOFF); +} + +/** + * @brief Check if Analog Noise Filter is enabled or disabled. + * @rmtoll CR1 ANFOFF LL_I2C_IsEnabledAnalogFilter + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsEnabledAnalogFilter(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->CR1, I2C_CR1_ANFOFF) != (I2C_CR1_ANFOFF)) ? 1UL : 0UL); +} + +/** + * @brief Enable DMA transmission requests. + * @rmtoll CR1 TXDMAEN LL_I2C_EnableDMAReq_TX + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_EnableDMAReq_TX(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CR1, I2C_CR1_TXDMAEN); +} + +/** + * @brief Disable DMA transmission requests. + * @rmtoll CR1 TXDMAEN LL_I2C_DisableDMAReq_TX + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_DisableDMAReq_TX(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CR1, I2C_CR1_TXDMAEN); +} + +/** + * @brief Check if DMA transmission requests are enabled or disabled. + * @rmtoll CR1 TXDMAEN LL_I2C_IsEnabledDMAReq_TX + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsEnabledDMAReq_TX(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->CR1, I2C_CR1_TXDMAEN) == (I2C_CR1_TXDMAEN)) ? 1UL : 0UL); +} + +/** + * @brief Enable DMA reception requests. + * @rmtoll CR1 RXDMAEN LL_I2C_EnableDMAReq_RX + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_EnableDMAReq_RX(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CR1, I2C_CR1_RXDMAEN); +} + +/** + * @brief Disable DMA reception requests. + * @rmtoll CR1 RXDMAEN LL_I2C_DisableDMAReq_RX + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_DisableDMAReq_RX(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CR1, I2C_CR1_RXDMAEN); +} + +/** + * @brief Check if DMA reception requests are enabled or disabled. + * @rmtoll CR1 RXDMAEN LL_I2C_IsEnabledDMAReq_RX + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsEnabledDMAReq_RX(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->CR1, I2C_CR1_RXDMAEN) == (I2C_CR1_RXDMAEN)) ? 1UL : 0UL); +} + +/** + * @brief Get the data register address used for DMA transfer + * @rmtoll TXDR TXDATA LL_I2C_DMA_GetRegAddr\n + * RXDR RXDATA LL_I2C_DMA_GetRegAddr + * @param I2Cx I2C Instance + * @param Direction This parameter can be one of the following values: + * @arg @ref LL_I2C_DMA_REG_DATA_TRANSMIT + * @arg @ref LL_I2C_DMA_REG_DATA_RECEIVE + * @retval Address of data register + */ +__STATIC_INLINE uint32_t LL_I2C_DMA_GetRegAddr(const I2C_TypeDef *I2Cx, uint32_t Direction) +{ + uint32_t data_reg_addr; + + if (Direction == LL_I2C_DMA_REG_DATA_TRANSMIT) + { + /* return address of TXDR register */ + data_reg_addr = (uint32_t) &(I2Cx->TXDR); + } + else + { + /* return address of RXDR register */ + data_reg_addr = (uint32_t) &(I2Cx->RXDR); + } + + return data_reg_addr; +} + +/** + * @brief Enable Clock stretching. + * @note This bit can only be programmed when the I2C is disabled (PE = 0). + * @rmtoll CR1 NOSTRETCH LL_I2C_EnableClockStretching + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_EnableClockStretching(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CR1, I2C_CR1_NOSTRETCH); +} + +/** + * @brief Disable Clock stretching. + * @note This bit can only be programmed when the I2C is disabled (PE = 0). + * @rmtoll CR1 NOSTRETCH LL_I2C_DisableClockStretching + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_DisableClockStretching(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CR1, I2C_CR1_NOSTRETCH); +} + +/** + * @brief Check if Clock stretching is enabled or disabled. + * @rmtoll CR1 NOSTRETCH LL_I2C_IsEnabledClockStretching + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsEnabledClockStretching(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->CR1, I2C_CR1_NOSTRETCH) != (I2C_CR1_NOSTRETCH)) ? 1UL : 0UL); +} + +/** + * @brief Enable hardware byte control in slave mode. + * @rmtoll CR1 SBC LL_I2C_EnableSlaveByteControl + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_EnableSlaveByteControl(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CR1, I2C_CR1_SBC); +} + +/** + * @brief Disable hardware byte control in slave mode. + * @rmtoll CR1 SBC LL_I2C_DisableSlaveByteControl + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_DisableSlaveByteControl(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CR1, I2C_CR1_SBC); +} + +/** + * @brief Check if hardware byte control in slave mode is enabled or disabled. + * @rmtoll CR1 SBC LL_I2C_IsEnabledSlaveByteControl + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsEnabledSlaveByteControl(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->CR1, I2C_CR1_SBC) == (I2C_CR1_SBC)) ? 1UL : 0UL); +} + +/** + * @brief Enable Wakeup from STOP. + * @note The macro IS_I2C_WAKEUP_FROMSTOP_INSTANCE(I2Cx) can be used to check whether or not + * WakeUpFromStop feature is supported by the I2Cx Instance. + * @note This bit can only be programmed when Digital Filter is disabled. + * @rmtoll CR1 WUPEN LL_I2C_EnableWakeUpFromStop + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_EnableWakeUpFromStop(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CR1, I2C_CR1_WUPEN); +} + +/** + * @brief Disable Wakeup from STOP. + * @note The macro IS_I2C_WAKEUP_FROMSTOP_INSTANCE(I2Cx) can be used to check whether or not + * WakeUpFromStop feature is supported by the I2Cx Instance. + * @rmtoll CR1 WUPEN LL_I2C_DisableWakeUpFromStop + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_DisableWakeUpFromStop(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CR1, I2C_CR1_WUPEN); +} + +/** + * @brief Check if Wakeup from STOP is enabled or disabled. + * @note The macro IS_I2C_WAKEUP_FROMSTOP_INSTANCE(I2Cx) can be used to check whether or not + * WakeUpFromStop feature is supported by the I2Cx Instance. + * @rmtoll CR1 WUPEN LL_I2C_IsEnabledWakeUpFromStop + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsEnabledWakeUpFromStop(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->CR1, I2C_CR1_WUPEN) == (I2C_CR1_WUPEN)) ? 1UL : 0UL); +} + +/** + * @brief Enable General Call. + * @note When enabled the Address 0x00 is ACKed. + * @rmtoll CR1 GCEN LL_I2C_EnableGeneralCall + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_EnableGeneralCall(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CR1, I2C_CR1_GCEN); +} + +/** + * @brief Disable General Call. + * @note When disabled the Address 0x00 is NACKed. + * @rmtoll CR1 GCEN LL_I2C_DisableGeneralCall + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_DisableGeneralCall(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CR1, I2C_CR1_GCEN); +} + +/** + * @brief Check if General Call is enabled or disabled. + * @rmtoll CR1 GCEN LL_I2C_IsEnabledGeneralCall + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsEnabledGeneralCall(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->CR1, I2C_CR1_GCEN) == (I2C_CR1_GCEN)) ? 1UL : 0UL); +} + +/** + * @brief Enable I2C Fast Mode Plus (FMP = 1). + * @note 20mA I/O drive enable + * @rmtoll CR1 FMP LL_I2C_EnableFastModePlus + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_EnableFastModePlus(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CR1, I2C_CR1_FMP); +} + +/** + * @brief Disable I2C Fast Mode Plus (FMP = 0). + * @note 20mA I/O drive disable + * @rmtoll CR1 FMP LL_I2C_DisableFastModePlus + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_DisableFastModePlus(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CR1, I2C_CR1_FMP); +} + +/** + * @brief Check if the I2C Fast Mode Plus is enabled or disabled. + * @rmtoll CR1 FMP LL_I2C_IsEnabledFastModePlus + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsEnabledFastModePlus(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->CR1, I2C_CR1_FMP) == (I2C_CR1_FMP)) ? 1UL : 0UL); +} + +/** + * @brief Enable automatic clear of ADDR flag. + * @rmtoll CR1 ADDRACLR LL_I2C_EnableAutoClearFlag_ADDR + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_EnableAutoClearFlag_ADDR(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CR1, I2C_CR1_ADDRACLR); +} + +/** + * @brief Disable automatic clear of ADDR flag. + * @rmtoll CR1 ADDRACLR LL_I2C_DisableAutoClearFlag_ADDR + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_DisableAutoClearFlag_ADDR(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CR1, I2C_CR1_ADDRACLR); +} + +/** + * @brief Check if the automatic clear of ADDR flag is enabled or disabled. + * @rmtoll CR1 ADDRACLR LL_I2C_IsEnabledAutoClearFlag_ADDR + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsEnabledAutoClearFlag_ADDR(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->CR1, I2C_CR1_ADDRACLR) == (I2C_CR1_ADDRACLR)) ? 1UL : 0UL); +} + +/** + * @brief Enable automatic clear of STOP flag. + * @rmtoll CR1 STOPFACLR LL_I2C_EnableAutoClearFlag_STOP + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_EnableAutoClearFlag_STOP(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CR1, I2C_CR1_STOPFACLR); +} + +/** + * @brief Disable automatic clear of STOP flag. + * @rmtoll CR1 STOPFACLR LL_I2C_DisableAutoClearFlag_STOP + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_DisableAutoClearFlag_STOP(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CR1, I2C_CR1_STOPFACLR); +} + +/** + * @brief Check if the automatic clear of STOP flag is enabled or disabled. + * @rmtoll CR1 STOPFACLR LL_I2C_IsEnabledAutoClearFlag_STOP + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsEnabledAutoClearFlag_STOP(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->CR1, I2C_CR1_STOPFACLR) == (I2C_CR1_STOPFACLR)) ? 1UL : 0UL); +} + +/** + * @brief Configure the Master to operate in 7-bit or 10-bit addressing mode. + * @note Changing this bit is not allowed, when the START bit is set. + * @rmtoll CR2 ADD10 LL_I2C_SetMasterAddressingMode + * @param I2Cx I2C Instance. + * @param AddressingMode This parameter can be one of the following values: + * @arg @ref LL_I2C_ADDRESSING_MODE_7BIT + * @arg @ref LL_I2C_ADDRESSING_MODE_10BIT + * @retval None + */ +__STATIC_INLINE void LL_I2C_SetMasterAddressingMode(I2C_TypeDef *I2Cx, uint32_t AddressingMode) +{ + MODIFY_REG(I2Cx->CR2, I2C_CR2_ADD10, AddressingMode); +} + +/** + * @brief Get the Master addressing mode. + * @rmtoll CR2 ADD10 LL_I2C_GetMasterAddressingMode + * @param I2Cx I2C Instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_I2C_ADDRESSING_MODE_7BIT + * @arg @ref LL_I2C_ADDRESSING_MODE_10BIT + */ +__STATIC_INLINE uint32_t LL_I2C_GetMasterAddressingMode(const I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->CR2, I2C_CR2_ADD10)); +} + +/** + * @brief Set the Own Address1. + * @rmtoll OAR1 OA1 LL_I2C_SetOwnAddress1\n + * OAR1 OA1MODE LL_I2C_SetOwnAddress1 + * @param I2Cx I2C Instance. + * @param OwnAddress1 This parameter must be a value between Min_Data=0 and Max_Data=0x3FF. + * @param OwnAddrSize This parameter can be one of the following values: + * @arg @ref LL_I2C_OWNADDRESS1_7BIT + * @arg @ref LL_I2C_OWNADDRESS1_10BIT + * @retval None + */ +__STATIC_INLINE void LL_I2C_SetOwnAddress1(I2C_TypeDef *I2Cx, uint32_t OwnAddress1, uint32_t OwnAddrSize) +{ + MODIFY_REG(I2Cx->OAR1, I2C_OAR1_OA1 | I2C_OAR1_OA1MODE, OwnAddress1 | OwnAddrSize); +} + +/** + * @brief Enable acknowledge on Own Address1 match address. + * @rmtoll OAR1 OA1EN LL_I2C_EnableOwnAddress1 + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_EnableOwnAddress1(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->OAR1, I2C_OAR1_OA1EN); +} + +/** + * @brief Disable acknowledge on Own Address1 match address. + * @rmtoll OAR1 OA1EN LL_I2C_DisableOwnAddress1 + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_DisableOwnAddress1(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->OAR1, I2C_OAR1_OA1EN); +} + +/** + * @brief Check if Own Address1 acknowledge is enabled or disabled. + * @rmtoll OAR1 OA1EN LL_I2C_IsEnabledOwnAddress1 + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsEnabledOwnAddress1(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->OAR1, I2C_OAR1_OA1EN) == (I2C_OAR1_OA1EN)) ? 1UL : 0UL); +} + +/** + * @brief Set the 7bits Own Address2. + * @note This action has no effect if own address2 is enabled. + * @rmtoll OAR2 OA2 LL_I2C_SetOwnAddress2\n + * OAR2 OA2MSK LL_I2C_SetOwnAddress2 + * @param I2Cx I2C Instance. + * @param OwnAddress2 Value between Min_Data=0 and Max_Data=0x7F. + * @param OwnAddrMask This parameter can be one of the following values: + * @arg @ref LL_I2C_OWNADDRESS2_NOMASK + * @arg @ref LL_I2C_OWNADDRESS2_MASK01 + * @arg @ref LL_I2C_OWNADDRESS2_MASK02 + * @arg @ref LL_I2C_OWNADDRESS2_MASK03 + * @arg @ref LL_I2C_OWNADDRESS2_MASK04 + * @arg @ref LL_I2C_OWNADDRESS2_MASK05 + * @arg @ref LL_I2C_OWNADDRESS2_MASK06 + * @arg @ref LL_I2C_OWNADDRESS2_MASK07 + * @retval None + */ +__STATIC_INLINE void LL_I2C_SetOwnAddress2(I2C_TypeDef *I2Cx, uint32_t OwnAddress2, uint32_t OwnAddrMask) +{ + MODIFY_REG(I2Cx->OAR2, I2C_OAR2_OA2 | I2C_OAR2_OA2MSK, OwnAddress2 | OwnAddrMask); +} + +/** + * @brief Enable acknowledge on Own Address2 match address. + * @rmtoll OAR2 OA2EN LL_I2C_EnableOwnAddress2 + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_EnableOwnAddress2(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->OAR2, I2C_OAR2_OA2EN); +} + +/** + * @brief Disable acknowledge on Own Address2 match address. + * @rmtoll OAR2 OA2EN LL_I2C_DisableOwnAddress2 + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_DisableOwnAddress2(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->OAR2, I2C_OAR2_OA2EN); +} + +/** + * @brief Check if Own Address1 acknowledge is enabled or disabled. + * @rmtoll OAR2 OA2EN LL_I2C_IsEnabledOwnAddress2 + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsEnabledOwnAddress2(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->OAR2, I2C_OAR2_OA2EN) == (I2C_OAR2_OA2EN)) ? 1UL : 0UL); +} + +/** + * @brief Configure the SDA setup, hold time and the SCL high, low period. + * @note This bit can only be programmed when the I2C is disabled (PE = 0). + * @rmtoll TIMINGR TIMINGR LL_I2C_SetTiming + * @param I2Cx I2C Instance. + * @param Timing This parameter must be a value between Min_Data=0 and Max_Data=0xFFFFFFFF. + * @note This parameter is computed with the STM32CubeMX Tool. + * @retval None + */ +__STATIC_INLINE void LL_I2C_SetTiming(I2C_TypeDef *I2Cx, uint32_t Timing) +{ + WRITE_REG(I2Cx->TIMINGR, Timing); +} + +/** + * @brief Get the Timing Prescaler setting. + * @rmtoll TIMINGR PRESC LL_I2C_GetTimingPrescaler + * @param I2Cx I2C Instance. + * @retval Value between Min_Data=0x0 and Max_Data=0xF + */ +__STATIC_INLINE uint32_t LL_I2C_GetTimingPrescaler(const I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->TIMINGR, I2C_TIMINGR_PRESC) >> I2C_TIMINGR_PRESC_Pos); +} + +/** + * @brief Get the SCL low period setting. + * @rmtoll TIMINGR SCLL LL_I2C_GetClockLowPeriod + * @param I2Cx I2C Instance. + * @retval Value between Min_Data=0x00 and Max_Data=0xFF + */ +__STATIC_INLINE uint32_t LL_I2C_GetClockLowPeriod(const I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->TIMINGR, I2C_TIMINGR_SCLL) >> I2C_TIMINGR_SCLL_Pos); +} + +/** + * @brief Get the SCL high period setting. + * @rmtoll TIMINGR SCLH LL_I2C_GetClockHighPeriod + * @param I2Cx I2C Instance. + * @retval Value between Min_Data=0x00 and Max_Data=0xFF + */ +__STATIC_INLINE uint32_t LL_I2C_GetClockHighPeriod(const I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->TIMINGR, I2C_TIMINGR_SCLH) >> I2C_TIMINGR_SCLH_Pos); +} + +/** + * @brief Get the SDA hold time. + * @rmtoll TIMINGR SDADEL LL_I2C_GetDataHoldTime + * @param I2Cx I2C Instance. + * @retval Value between Min_Data=0x0 and Max_Data=0xF + */ +__STATIC_INLINE uint32_t LL_I2C_GetDataHoldTime(const I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->TIMINGR, I2C_TIMINGR_SDADEL) >> I2C_TIMINGR_SDADEL_Pos); +} + +/** + * @brief Get the SDA setup time. + * @rmtoll TIMINGR SCLDEL LL_I2C_GetDataSetupTime + * @param I2Cx I2C Instance. + * @retval Value between Min_Data=0x0 and Max_Data=0xF + */ +__STATIC_INLINE uint32_t LL_I2C_GetDataSetupTime(const I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->TIMINGR, I2C_TIMINGR_SCLDEL) >> I2C_TIMINGR_SCLDEL_Pos); +} + +/** + * @brief Configure peripheral mode. + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @rmtoll CR1 SMBHEN LL_I2C_SetMode\n + * CR1 SMBDEN LL_I2C_SetMode + * @param I2Cx I2C Instance. + * @param PeripheralMode This parameter can be one of the following values: + * @arg @ref LL_I2C_MODE_I2C + * @arg @ref LL_I2C_MODE_SMBUS_HOST + * @arg @ref LL_I2C_MODE_SMBUS_DEVICE + * @arg @ref LL_I2C_MODE_SMBUS_DEVICE_ARP + * @retval None + */ +__STATIC_INLINE void LL_I2C_SetMode(I2C_TypeDef *I2Cx, uint32_t PeripheralMode) +{ + MODIFY_REG(I2Cx->CR1, I2C_CR1_SMBHEN | I2C_CR1_SMBDEN, PeripheralMode); +} + +/** + * @brief Get peripheral mode. + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @rmtoll CR1 SMBHEN LL_I2C_GetMode\n + * CR1 SMBDEN LL_I2C_GetMode + * @param I2Cx I2C Instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_I2C_MODE_I2C + * @arg @ref LL_I2C_MODE_SMBUS_HOST + * @arg @ref LL_I2C_MODE_SMBUS_DEVICE + * @arg @ref LL_I2C_MODE_SMBUS_DEVICE_ARP + */ +__STATIC_INLINE uint32_t LL_I2C_GetMode(const I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->CR1, I2C_CR1_SMBHEN | I2C_CR1_SMBDEN)); +} + +/** + * @brief Enable SMBus alert (Host or Device mode) + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @note SMBus Device mode: + * - SMBus Alert pin is drived low and + * Alert Response Address Header acknowledge is enabled. + * SMBus Host mode: + * - SMBus Alert pin management is supported. + * @rmtoll CR1 ALERTEN LL_I2C_EnableSMBusAlert + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_EnableSMBusAlert(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CR1, I2C_CR1_ALERTEN); +} + +/** + * @brief Disable SMBus alert (Host or Device mode) + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @note SMBus Device mode: + * - SMBus Alert pin is not drived (can be used as a standard GPIO) and + * Alert Response Address Header acknowledge is disabled. + * SMBus Host mode: + * - SMBus Alert pin management is not supported. + * @rmtoll CR1 ALERTEN LL_I2C_DisableSMBusAlert + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_DisableSMBusAlert(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CR1, I2C_CR1_ALERTEN); +} + +/** + * @brief Check if SMBus alert (Host or Device mode) is enabled or disabled. + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @rmtoll CR1 ALERTEN LL_I2C_IsEnabledSMBusAlert + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsEnabledSMBusAlert(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->CR1, I2C_CR1_ALERTEN) == (I2C_CR1_ALERTEN)) ? 1UL : 0UL); +} + +/** + * @brief Enable SMBus Packet Error Calculation (PEC). + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @rmtoll CR1 PECEN LL_I2C_EnableSMBusPEC + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_EnableSMBusPEC(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CR1, I2C_CR1_PECEN); +} + +/** + * @brief Disable SMBus Packet Error Calculation (PEC). + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @rmtoll CR1 PECEN LL_I2C_DisableSMBusPEC + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_DisableSMBusPEC(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CR1, I2C_CR1_PECEN); +} + +/** + * @brief Check if SMBus Packet Error Calculation (PEC) is enabled or disabled. + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @rmtoll CR1 PECEN LL_I2C_IsEnabledSMBusPEC + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsEnabledSMBusPEC(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->CR1, I2C_CR1_PECEN) == (I2C_CR1_PECEN)) ? 1UL : 0UL); +} + +/** + * @brief Configure the SMBus Clock Timeout. + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @note This configuration can only be programmed when associated Timeout is disabled (TimeoutA and/orTimeoutB). + * @rmtoll TIMEOUTR TIMEOUTA LL_I2C_ConfigSMBusTimeout\n + * TIMEOUTR TIDLE LL_I2C_ConfigSMBusTimeout\n + * TIMEOUTR TIMEOUTB LL_I2C_ConfigSMBusTimeout + * @param I2Cx I2C Instance. + * @param TimeoutA This parameter must be a value between Min_Data=0 and Max_Data=0xFFF. + * @param TimeoutAMode This parameter can be one of the following values: + * @arg @ref LL_I2C_SMBUS_TIMEOUTA_MODE_SCL_LOW + * @arg @ref LL_I2C_SMBUS_TIMEOUTA_MODE_SDA_SCL_HIGH + * @param TimeoutB + * @retval None + */ +__STATIC_INLINE void LL_I2C_ConfigSMBusTimeout(I2C_TypeDef *I2Cx, uint32_t TimeoutA, uint32_t TimeoutAMode, + uint32_t TimeoutB) +{ + MODIFY_REG(I2Cx->TIMEOUTR, I2C_TIMEOUTR_TIMEOUTA | I2C_TIMEOUTR_TIDLE | I2C_TIMEOUTR_TIMEOUTB, + TimeoutA | TimeoutAMode | (TimeoutB << I2C_TIMEOUTR_TIMEOUTB_Pos)); +} + +/** + * @brief Configure the SMBus Clock TimeoutA (SCL low timeout or SCL and SDA high timeout depends on TimeoutA mode). + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @note These bits can only be programmed when TimeoutA is disabled. + * @rmtoll TIMEOUTR TIMEOUTA LL_I2C_SetSMBusTimeoutA + * @param I2Cx I2C Instance. + * @param TimeoutA This parameter must be a value between Min_Data=0 and Max_Data=0xFFF. + * @retval None + */ +__STATIC_INLINE void LL_I2C_SetSMBusTimeoutA(I2C_TypeDef *I2Cx, uint32_t TimeoutA) +{ + WRITE_REG(I2Cx->TIMEOUTR, TimeoutA); +} + +/** + * @brief Get the SMBus Clock TimeoutA setting. + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @rmtoll TIMEOUTR TIMEOUTA LL_I2C_GetSMBusTimeoutA + * @param I2Cx I2C Instance. + * @retval Value between Min_Data=0 and Max_Data=0xFFF + */ +__STATIC_INLINE uint32_t LL_I2C_GetSMBusTimeoutA(const I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->TIMEOUTR, I2C_TIMEOUTR_TIMEOUTA)); +} + +/** + * @brief Set the SMBus Clock TimeoutA mode. + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @note This bit can only be programmed when TimeoutA is disabled. + * @rmtoll TIMEOUTR TIDLE LL_I2C_SetSMBusTimeoutAMode + * @param I2Cx I2C Instance. + * @param TimeoutAMode This parameter can be one of the following values: + * @arg @ref LL_I2C_SMBUS_TIMEOUTA_MODE_SCL_LOW + * @arg @ref LL_I2C_SMBUS_TIMEOUTA_MODE_SDA_SCL_HIGH + * @retval None + */ +__STATIC_INLINE void LL_I2C_SetSMBusTimeoutAMode(I2C_TypeDef *I2Cx, uint32_t TimeoutAMode) +{ + WRITE_REG(I2Cx->TIMEOUTR, TimeoutAMode); +} + +/** + * @brief Get the SMBus Clock TimeoutA mode. + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @rmtoll TIMEOUTR TIDLE LL_I2C_GetSMBusTimeoutAMode + * @param I2Cx I2C Instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_I2C_SMBUS_TIMEOUTA_MODE_SCL_LOW + * @arg @ref LL_I2C_SMBUS_TIMEOUTA_MODE_SDA_SCL_HIGH + */ +__STATIC_INLINE uint32_t LL_I2C_GetSMBusTimeoutAMode(const I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->TIMEOUTR, I2C_TIMEOUTR_TIDLE)); +} + +/** + * @brief Configure the SMBus Extended Cumulative Clock TimeoutB (Master or Slave mode). + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @note These bits can only be programmed when TimeoutB is disabled. + * @rmtoll TIMEOUTR TIMEOUTB LL_I2C_SetSMBusTimeoutB + * @param I2Cx I2C Instance. + * @param TimeoutB This parameter must be a value between Min_Data=0 and Max_Data=0xFFF. + * @retval None + */ +__STATIC_INLINE void LL_I2C_SetSMBusTimeoutB(I2C_TypeDef *I2Cx, uint32_t TimeoutB) +{ + WRITE_REG(I2Cx->TIMEOUTR, TimeoutB << I2C_TIMEOUTR_TIMEOUTB_Pos); +} + +/** + * @brief Get the SMBus Extended Cumulative Clock TimeoutB setting. + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @rmtoll TIMEOUTR TIMEOUTB LL_I2C_GetSMBusTimeoutB + * @param I2Cx I2C Instance. + * @retval Value between Min_Data=0 and Max_Data=0xFFF + */ +__STATIC_INLINE uint32_t LL_I2C_GetSMBusTimeoutB(const I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->TIMEOUTR, I2C_TIMEOUTR_TIMEOUTB) >> I2C_TIMEOUTR_TIMEOUTB_Pos); +} + +/** + * @brief Enable the SMBus Clock Timeout. + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @rmtoll TIMEOUTR TIMOUTEN LL_I2C_EnableSMBusTimeout\n + * TIMEOUTR TEXTEN LL_I2C_EnableSMBusTimeout + * @param I2Cx I2C Instance. + * @param ClockTimeout This parameter can be one of the following values: + * @arg @ref LL_I2C_SMBUS_TIMEOUTA + * @arg @ref LL_I2C_SMBUS_TIMEOUTB + * @arg @ref LL_I2C_SMBUS_ALL_TIMEOUT + * @retval None + */ +__STATIC_INLINE void LL_I2C_EnableSMBusTimeout(I2C_TypeDef *I2Cx, uint32_t ClockTimeout) +{ + SET_BIT(I2Cx->TIMEOUTR, ClockTimeout); +} + +/** + * @brief Disable the SMBus Clock Timeout. + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @rmtoll TIMEOUTR TIMOUTEN LL_I2C_DisableSMBusTimeout\n + * TIMEOUTR TEXTEN LL_I2C_DisableSMBusTimeout + * @param I2Cx I2C Instance. + * @param ClockTimeout This parameter can be one of the following values: + * @arg @ref LL_I2C_SMBUS_TIMEOUTA + * @arg @ref LL_I2C_SMBUS_TIMEOUTB + * @arg @ref LL_I2C_SMBUS_ALL_TIMEOUT + * @retval None + */ +__STATIC_INLINE void LL_I2C_DisableSMBusTimeout(I2C_TypeDef *I2Cx, uint32_t ClockTimeout) +{ + CLEAR_BIT(I2Cx->TIMEOUTR, ClockTimeout); +} + +/** + * @brief Check if the SMBus Clock Timeout is enabled or disabled. + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @rmtoll TIMEOUTR TIMOUTEN LL_I2C_IsEnabledSMBusTimeout\n + * TIMEOUTR TEXTEN LL_I2C_IsEnabledSMBusTimeout + * @param I2Cx I2C Instance. + * @param ClockTimeout This parameter can be one of the following values: + * @arg @ref LL_I2C_SMBUS_TIMEOUTA + * @arg @ref LL_I2C_SMBUS_TIMEOUTB + * @arg @ref LL_I2C_SMBUS_ALL_TIMEOUT + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsEnabledSMBusTimeout(const I2C_TypeDef *I2Cx, uint32_t ClockTimeout) +{ + return ((READ_BIT(I2Cx->TIMEOUTR, (I2C_TIMEOUTR_TIMOUTEN | I2C_TIMEOUTR_TEXTEN)) == \ + (ClockTimeout)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup I2C_LL_EF_IT_Management IT_Management + * @{ + */ + +/** + * @brief Enable TXIS interrupt. + * @rmtoll CR1 TXIE LL_I2C_EnableIT_TX + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_EnableIT_TX(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CR1, I2C_CR1_TXIE); +} + +/** + * @brief Disable TXIS interrupt. + * @rmtoll CR1 TXIE LL_I2C_DisableIT_TX + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_DisableIT_TX(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CR1, I2C_CR1_TXIE); +} + +/** + * @brief Check if the TXIS Interrupt is enabled or disabled. + * @rmtoll CR1 TXIE LL_I2C_IsEnabledIT_TX + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsEnabledIT_TX(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->CR1, I2C_CR1_TXIE) == (I2C_CR1_TXIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable RXNE interrupt. + * @rmtoll CR1 RXIE LL_I2C_EnableIT_RX + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_EnableIT_RX(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CR1, I2C_CR1_RXIE); +} + +/** + * @brief Disable RXNE interrupt. + * @rmtoll CR1 RXIE LL_I2C_DisableIT_RX + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_DisableIT_RX(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CR1, I2C_CR1_RXIE); +} + +/** + * @brief Check if the RXNE Interrupt is enabled or disabled. + * @rmtoll CR1 RXIE LL_I2C_IsEnabledIT_RX + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsEnabledIT_RX(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->CR1, I2C_CR1_RXIE) == (I2C_CR1_RXIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable Address match interrupt (slave mode only). + * @rmtoll CR1 ADDRIE LL_I2C_EnableIT_ADDR + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_EnableIT_ADDR(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CR1, I2C_CR1_ADDRIE); +} + +/** + * @brief Disable Address match interrupt (slave mode only). + * @rmtoll CR1 ADDRIE LL_I2C_DisableIT_ADDR + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_DisableIT_ADDR(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CR1, I2C_CR1_ADDRIE); +} + +/** + * @brief Check if Address match interrupt is enabled or disabled. + * @rmtoll CR1 ADDRIE LL_I2C_IsEnabledIT_ADDR + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsEnabledIT_ADDR(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->CR1, I2C_CR1_ADDRIE) == (I2C_CR1_ADDRIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable Not acknowledge received interrupt. + * @rmtoll CR1 NACKIE LL_I2C_EnableIT_NACK + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_EnableIT_NACK(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CR1, I2C_CR1_NACKIE); +} + +/** + * @brief Disable Not acknowledge received interrupt. + * @rmtoll CR1 NACKIE LL_I2C_DisableIT_NACK + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_DisableIT_NACK(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CR1, I2C_CR1_NACKIE); +} + +/** + * @brief Check if Not acknowledge received interrupt is enabled or disabled. + * @rmtoll CR1 NACKIE LL_I2C_IsEnabledIT_NACK + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsEnabledIT_NACK(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->CR1, I2C_CR1_NACKIE) == (I2C_CR1_NACKIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable STOP detection interrupt. + * @rmtoll CR1 STOPIE LL_I2C_EnableIT_STOP + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_EnableIT_STOP(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CR1, I2C_CR1_STOPIE); +} + +/** + * @brief Disable STOP detection interrupt. + * @rmtoll CR1 STOPIE LL_I2C_DisableIT_STOP + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_DisableIT_STOP(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CR1, I2C_CR1_STOPIE); +} + +/** + * @brief Check if STOP detection interrupt is enabled or disabled. + * @rmtoll CR1 STOPIE LL_I2C_IsEnabledIT_STOP + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsEnabledIT_STOP(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->CR1, I2C_CR1_STOPIE) == (I2C_CR1_STOPIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable Transfer Complete interrupt. + * @note Any of these events will generate interrupt : + * Transfer Complete (TC) + * Transfer Complete Reload (TCR) + * @rmtoll CR1 TCIE LL_I2C_EnableIT_TC + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_EnableIT_TC(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CR1, I2C_CR1_TCIE); +} + +/** + * @brief Disable Transfer Complete interrupt. + * @note Any of these events will generate interrupt : + * Transfer Complete (TC) + * Transfer Complete Reload (TCR) + * @rmtoll CR1 TCIE LL_I2C_DisableIT_TC + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_DisableIT_TC(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CR1, I2C_CR1_TCIE); +} + +/** + * @brief Check if Transfer Complete interrupt is enabled or disabled. + * @rmtoll CR1 TCIE LL_I2C_IsEnabledIT_TC + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsEnabledIT_TC(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->CR1, I2C_CR1_TCIE) == (I2C_CR1_TCIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable Error interrupts. + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @note Any of these errors will generate interrupt : + * Arbitration Loss (ARLO) + * Bus Error detection (BERR) + * Overrun/Underrun (OVR) + * SMBus Timeout detection (TIMEOUT) + * SMBus PEC error detection (PECERR) + * SMBus Alert pin event detection (ALERT) + * @rmtoll CR1 ERRIE LL_I2C_EnableIT_ERR + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_EnableIT_ERR(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CR1, I2C_CR1_ERRIE); +} + +/** + * @brief Disable Error interrupts. + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @note Any of these errors will generate interrupt : + * Arbitration Loss (ARLO) + * Bus Error detection (BERR) + * Overrun/Underrun (OVR) + * SMBus Timeout detection (TIMEOUT) + * SMBus PEC error detection (PECERR) + * SMBus Alert pin event detection (ALERT) + * @rmtoll CR1 ERRIE LL_I2C_DisableIT_ERR + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_DisableIT_ERR(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CR1, I2C_CR1_ERRIE); +} + +/** + * @brief Check if Error interrupts are enabled or disabled. + * @rmtoll CR1 ERRIE LL_I2C_IsEnabledIT_ERR + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsEnabledIT_ERR(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->CR1, I2C_CR1_ERRIE) == (I2C_CR1_ERRIE)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup I2C_LL_EF_FLAG_management FLAG_management + * @{ + */ + +/** + * @brief Indicate the status of Transmit data register empty flag. + * @note RESET: When next data is written in Transmit data register. + * SET: When Transmit data register is empty. + * @rmtoll ISR TXE LL_I2C_IsActiveFlag_TXE + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_TXE(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->ISR, I2C_ISR_TXE) == (I2C_ISR_TXE)) ? 1UL : 0UL); +} + +/** + * @brief Indicate the status of Transmit interrupt flag. + * @note RESET: When next data is written in Transmit data register. + * SET: When Transmit data register is empty. + * @rmtoll ISR TXIS LL_I2C_IsActiveFlag_TXIS + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_TXIS(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->ISR, I2C_ISR_TXIS) == (I2C_ISR_TXIS)) ? 1UL : 0UL); +} + +/** + * @brief Indicate the status of Receive data register not empty flag. + * @note RESET: When Receive data register is read. + * SET: When the received data is copied in Receive data register. + * @rmtoll ISR RXNE LL_I2C_IsActiveFlag_RXNE + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_RXNE(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->ISR, I2C_ISR_RXNE) == (I2C_ISR_RXNE)) ? 1UL : 0UL); +} + +/** + * @brief Indicate the status of Address matched flag (slave mode). + * @note RESET: Clear default value. + * SET: When the received slave address matched with one of the enabled slave address. + * @rmtoll ISR ADDR LL_I2C_IsActiveFlag_ADDR + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_ADDR(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->ISR, I2C_ISR_ADDR) == (I2C_ISR_ADDR)) ? 1UL : 0UL); +} + +/** + * @brief Indicate the status of Not Acknowledge received flag. + * @note RESET: Clear default value. + * SET: When a NACK is received after a byte transmission. + * @rmtoll ISR NACKF LL_I2C_IsActiveFlag_NACK + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_NACK(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->ISR, I2C_ISR_NACKF) == (I2C_ISR_NACKF)) ? 1UL : 0UL); +} + +/** + * @brief Indicate the status of Stop detection flag. + * @note RESET: Clear default value. + * SET: When a Stop condition is detected. + * @rmtoll ISR STOPF LL_I2C_IsActiveFlag_STOP + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_STOP(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->ISR, I2C_ISR_STOPF) == (I2C_ISR_STOPF)) ? 1UL : 0UL); +} + +/** + * @brief Indicate the status of Transfer complete flag (master mode). + * @note RESET: Clear default value. + * SET: When RELOAD=0, AUTOEND=0 and NBYTES date have been transferred. + * @rmtoll ISR TC LL_I2C_IsActiveFlag_TC + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_TC(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->ISR, I2C_ISR_TC) == (I2C_ISR_TC)) ? 1UL : 0UL); +} + +/** + * @brief Indicate the status of Transfer complete flag (master mode). + * @note RESET: Clear default value. + * SET: When RELOAD=1 and NBYTES date have been transferred. + * @rmtoll ISR TCR LL_I2C_IsActiveFlag_TCR + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_TCR(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->ISR, I2C_ISR_TCR) == (I2C_ISR_TCR)) ? 1UL : 0UL); +} + +/** + * @brief Indicate the status of Bus error flag. + * @note RESET: Clear default value. + * SET: When a misplaced Start or Stop condition is detected. + * @rmtoll ISR BERR LL_I2C_IsActiveFlag_BERR + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_BERR(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->ISR, I2C_ISR_BERR) == (I2C_ISR_BERR)) ? 1UL : 0UL); +} + +/** + * @brief Indicate the status of Arbitration lost flag. + * @note RESET: Clear default value. + * SET: When arbitration lost. + * @rmtoll ISR ARLO LL_I2C_IsActiveFlag_ARLO + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_ARLO(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->ISR, I2C_ISR_ARLO) == (I2C_ISR_ARLO)) ? 1UL : 0UL); +} + +/** + * @brief Indicate the status of Overrun/Underrun flag (slave mode). + * @note RESET: Clear default value. + * SET: When an overrun/underrun error occurs (Clock Stretching Disabled). + * @rmtoll ISR OVR LL_I2C_IsActiveFlag_OVR + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_OVR(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->ISR, I2C_ISR_OVR) == (I2C_ISR_OVR)) ? 1UL : 0UL); +} + +/** + * @brief Indicate the status of SMBus PEC error flag in reception. + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @note RESET: Clear default value. + * SET: When the received PEC does not match with the PEC register content. + * @rmtoll ISR PECERR LL_I2C_IsActiveSMBusFlag_PECERR + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsActiveSMBusFlag_PECERR(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->ISR, I2C_ISR_PECERR) == (I2C_ISR_PECERR)) ? 1UL : 0UL); +} + +/** + * @brief Indicate the status of SMBus Timeout detection flag. + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @note RESET: Clear default value. + * SET: When a timeout or extended clock timeout occurs. + * @rmtoll ISR TIMEOUT LL_I2C_IsActiveSMBusFlag_TIMEOUT + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsActiveSMBusFlag_TIMEOUT(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->ISR, I2C_ISR_TIMEOUT) == (I2C_ISR_TIMEOUT)) ? 1UL : 0UL); +} + +/** + * @brief Indicate the status of SMBus alert flag. + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @note RESET: Clear default value. + * SET: When SMBus host configuration, SMBus alert enabled and + * a falling edge event occurs on SMBA pin. + * @rmtoll ISR ALERT LL_I2C_IsActiveSMBusFlag_ALERT + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsActiveSMBusFlag_ALERT(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->ISR, I2C_ISR_ALERT) == (I2C_ISR_ALERT)) ? 1UL : 0UL); +} + +/** + * @brief Indicate the status of Bus Busy flag. + * @note RESET: Clear default value. + * SET: When a Start condition is detected. + * @rmtoll ISR BUSY LL_I2C_IsActiveFlag_BUSY + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsActiveFlag_BUSY(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->ISR, I2C_ISR_BUSY) == (I2C_ISR_BUSY)) ? 1UL : 0UL); +} + +/** + * @brief Clear Address Matched flag. + * @rmtoll ICR ADDRCF LL_I2C_ClearFlag_ADDR + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_ClearFlag_ADDR(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ICR, I2C_ICR_ADDRCF); +} + +/** + * @brief Clear Not Acknowledge flag. + * @rmtoll ICR NACKCF LL_I2C_ClearFlag_NACK + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_ClearFlag_NACK(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ICR, I2C_ICR_NACKCF); +} + +/** + * @brief Clear Stop detection flag. + * @rmtoll ICR STOPCF LL_I2C_ClearFlag_STOP + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_ClearFlag_STOP(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ICR, I2C_ICR_STOPCF); +} + +/** + * @brief Clear Transmit data register empty flag (TXE). + * @note This bit can be clear by software in order to flush the transmit data register (TXDR). + * @rmtoll ISR TXE LL_I2C_ClearFlag_TXE + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_ClearFlag_TXE(I2C_TypeDef *I2Cx) +{ + WRITE_REG(I2Cx->ISR, I2C_ISR_TXE); +} + +/** + * @brief Clear Bus error flag. + * @rmtoll ICR BERRCF LL_I2C_ClearFlag_BERR + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_ClearFlag_BERR(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ICR, I2C_ICR_BERRCF); +} + +/** + * @brief Clear Arbitration lost flag. + * @rmtoll ICR ARLOCF LL_I2C_ClearFlag_ARLO + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_ClearFlag_ARLO(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ICR, I2C_ICR_ARLOCF); +} + +/** + * @brief Clear Overrun/Underrun flag. + * @rmtoll ICR OVRCF LL_I2C_ClearFlag_OVR + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_ClearFlag_OVR(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ICR, I2C_ICR_OVRCF); +} + +/** + * @brief Clear SMBus PEC error flag. + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @rmtoll ICR PECCF LL_I2C_ClearSMBusFlag_PECERR + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_ClearSMBusFlag_PECERR(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ICR, I2C_ICR_PECCF); +} + +/** + * @brief Clear SMBus Timeout detection flag. + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @rmtoll ICR TIMOUTCF LL_I2C_ClearSMBusFlag_TIMEOUT + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_ClearSMBusFlag_TIMEOUT(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ICR, I2C_ICR_TIMOUTCF); +} + +/** + * @brief Clear SMBus Alert flag. + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @rmtoll ICR ALERTCF LL_I2C_ClearSMBusFlag_ALERT + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_ClearSMBusFlag_ALERT(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->ICR, I2C_ICR_ALERTCF); +} + +/** + * @} + */ + +/** @defgroup I2C_LL_EF_Data_Management Data_Management + * @{ + */ + +/** + * @brief Enable automatic STOP condition generation (master mode). + * @note Automatic end mode : a STOP condition is automatically sent when NBYTES data are transferred. + * This bit has no effect in slave mode or when RELOAD bit is set. + * @rmtoll CR2 AUTOEND LL_I2C_EnableAutoEndMode + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_EnableAutoEndMode(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CR2, I2C_CR2_AUTOEND); +} + +/** + * @brief Disable automatic STOP condition generation (master mode). + * @note Software end mode : TC flag is set when NBYTES data are transferre, stretching SCL low. + * @rmtoll CR2 AUTOEND LL_I2C_DisableAutoEndMode + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_DisableAutoEndMode(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CR2, I2C_CR2_AUTOEND); +} + +/** + * @brief Check if automatic STOP condition is enabled or disabled. + * @rmtoll CR2 AUTOEND LL_I2C_IsEnabledAutoEndMode + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsEnabledAutoEndMode(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->CR2, I2C_CR2_AUTOEND) == (I2C_CR2_AUTOEND)) ? 1UL : 0UL); +} + +/** + * @brief Enable reload mode (master mode). + * @note The transfer is not completed after the NBYTES data transfer, NBYTES will be reloaded when TCR flag is set. + * @rmtoll CR2 RELOAD LL_I2C_EnableReloadMode + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_EnableReloadMode(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CR2, I2C_CR2_RELOAD); +} + +/** + * @brief Disable reload mode (master mode). + * @note The transfer is completed after the NBYTES data transfer(STOP or RESTART will follow). + * @rmtoll CR2 RELOAD LL_I2C_DisableReloadMode + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_DisableReloadMode(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CR2, I2C_CR2_RELOAD); +} + +/** + * @brief Check if reload mode is enabled or disabled. + * @rmtoll CR2 RELOAD LL_I2C_IsEnabledReloadMode + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsEnabledReloadMode(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->CR2, I2C_CR2_RELOAD) == (I2C_CR2_RELOAD)) ? 1UL : 0UL); +} + +/** + * @brief Configure the number of bytes for transfer. + * @note Changing these bits when START bit is set is not allowed. + * @rmtoll CR2 NBYTES LL_I2C_SetTransferSize + * @param I2Cx I2C Instance. + * @param TransferSize This parameter must be a value between Min_Data=0x00 and Max_Data=0xFF. + * @retval None + */ +__STATIC_INLINE void LL_I2C_SetTransferSize(I2C_TypeDef *I2Cx, uint32_t TransferSize) +{ + MODIFY_REG(I2Cx->CR2, I2C_CR2_NBYTES, TransferSize << I2C_CR2_NBYTES_Pos); +} + +/** + * @brief Get the number of bytes configured for transfer. + * @rmtoll CR2 NBYTES LL_I2C_GetTransferSize + * @param I2Cx I2C Instance. + * @retval Value between Min_Data=0x0 and Max_Data=0xFF + */ +__STATIC_INLINE uint32_t LL_I2C_GetTransferSize(const I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->CR2, I2C_CR2_NBYTES) >> I2C_CR2_NBYTES_Pos); +} + +/** + * @brief Prepare the generation of a ACKnowledge or Non ACKnowledge condition after the address receive match code + or next received byte. + * @note Usage in Slave mode only. + * @rmtoll CR2 NACK LL_I2C_AcknowledgeNextData + * @param I2Cx I2C Instance. + * @param TypeAcknowledge This parameter can be one of the following values: + * @arg @ref LL_I2C_ACK + * @arg @ref LL_I2C_NACK + * @retval None + */ +__STATIC_INLINE void LL_I2C_AcknowledgeNextData(I2C_TypeDef *I2Cx, uint32_t TypeAcknowledge) +{ + MODIFY_REG(I2Cx->CR2, I2C_CR2_NACK, TypeAcknowledge); +} + +/** + * @brief Generate a START or RESTART condition + * @note The START bit can be set even if bus is BUSY or I2C is in slave mode. + * This action has no effect when RELOAD is set. + * @rmtoll CR2 START LL_I2C_GenerateStartCondition + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_GenerateStartCondition(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CR2, I2C_CR2_START); +} + +/** + * @brief Generate a STOP condition after the current byte transfer (master mode). + * @rmtoll CR2 STOP LL_I2C_GenerateStopCondition + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_GenerateStopCondition(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CR2, I2C_CR2_STOP); +} + +/** + * @brief Enable automatic RESTART Read request condition for 10bit address header (master mode). + * @note The master sends the complete 10bit slave address read sequence : + * Start + 2 bytes 10bit address in Write direction + Restart + first 7 bits of 10bit address + in Read direction. + * @rmtoll CR2 HEAD10R LL_I2C_EnableAuto10BitRead + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_EnableAuto10BitRead(I2C_TypeDef *I2Cx) +{ + CLEAR_BIT(I2Cx->CR2, I2C_CR2_HEAD10R); +} + +/** + * @brief Disable automatic RESTART Read request condition for 10bit address header (master mode). + * @note The master only sends the first 7 bits of 10bit address in Read direction. + * @rmtoll CR2 HEAD10R LL_I2C_DisableAuto10BitRead + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_DisableAuto10BitRead(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CR2, I2C_CR2_HEAD10R); +} + +/** + * @brief Check if automatic RESTART Read request condition for 10bit address header is enabled or disabled. + * @rmtoll CR2 HEAD10R LL_I2C_IsEnabledAuto10BitRead + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsEnabledAuto10BitRead(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->CR2, I2C_CR2_HEAD10R) != (I2C_CR2_HEAD10R)) ? 1UL : 0UL); +} + +/** + * @brief Configure the transfer direction (master mode). + * @note Changing these bits when START bit is set is not allowed. + * @rmtoll CR2 RD_WRN LL_I2C_SetTransferRequest + * @param I2Cx I2C Instance. + * @param TransferRequest This parameter can be one of the following values: + * @arg @ref LL_I2C_REQUEST_WRITE + * @arg @ref LL_I2C_REQUEST_READ + * @retval None + */ +__STATIC_INLINE void LL_I2C_SetTransferRequest(I2C_TypeDef *I2Cx, uint32_t TransferRequest) +{ + MODIFY_REG(I2Cx->CR2, I2C_CR2_RD_WRN, TransferRequest); +} + +/** + * @brief Get the transfer direction requested (master mode). + * @rmtoll CR2 RD_WRN LL_I2C_GetTransferRequest + * @param I2Cx I2C Instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_I2C_REQUEST_WRITE + * @arg @ref LL_I2C_REQUEST_READ + */ +__STATIC_INLINE uint32_t LL_I2C_GetTransferRequest(const I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->CR2, I2C_CR2_RD_WRN)); +} + +/** + * @brief Configure the slave address for transfer (master mode). + * @note Changing these bits when START bit is set is not allowed. + * @rmtoll CR2 SADD LL_I2C_SetSlaveAddr + * @param I2Cx I2C Instance. + * @param SlaveAddr This parameter must be a value between Min_Data=0x00 and Max_Data=0x3F. + * @retval None + */ +__STATIC_INLINE void LL_I2C_SetSlaveAddr(I2C_TypeDef *I2Cx, uint32_t SlaveAddr) +{ + MODIFY_REG(I2Cx->CR2, I2C_CR2_SADD, SlaveAddr); +} + +/** + * @brief Get the slave address programmed for transfer. + * @rmtoll CR2 SADD LL_I2C_GetSlaveAddr + * @param I2Cx I2C Instance. + * @retval Value between Min_Data=0x0 and Max_Data=0x3F + */ +__STATIC_INLINE uint32_t LL_I2C_GetSlaveAddr(const I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->CR2, I2C_CR2_SADD)); +} + +/** + * @brief Handles I2Cx communication when starting transfer or during transfer (TC or TCR flag are set). + * @rmtoll CR2 SADD LL_I2C_HandleTransfer\n + * CR2 ADD10 LL_I2C_HandleTransfer\n + * CR2 RD_WRN LL_I2C_HandleTransfer\n + * CR2 START LL_I2C_HandleTransfer\n + * CR2 STOP LL_I2C_HandleTransfer\n + * CR2 RELOAD LL_I2C_HandleTransfer\n + * CR2 NBYTES LL_I2C_HandleTransfer\n + * CR2 AUTOEND LL_I2C_HandleTransfer\n + * CR2 HEAD10R LL_I2C_HandleTransfer + * @param I2Cx I2C Instance. + * @param SlaveAddr Specifies the slave address to be programmed. + * @param SlaveAddrSize This parameter can be one of the following values: + * @arg @ref LL_I2C_ADDRSLAVE_7BIT + * @arg @ref LL_I2C_ADDRSLAVE_10BIT + * @param TransferSize Specifies the number of bytes to be programmed. + * This parameter must be a value between Min_Data=0 and Max_Data=255. + * @param EndMode This parameter can be one of the following values: + * @arg @ref LL_I2C_MODE_RELOAD + * @arg @ref LL_I2C_MODE_AUTOEND + * @arg @ref LL_I2C_MODE_SOFTEND + * @arg @ref LL_I2C_MODE_SMBUS_RELOAD + * @arg @ref LL_I2C_MODE_SMBUS_AUTOEND_NO_PEC + * @arg @ref LL_I2C_MODE_SMBUS_SOFTEND_NO_PEC + * @arg @ref LL_I2C_MODE_SMBUS_AUTOEND_WITH_PEC + * @arg @ref LL_I2C_MODE_SMBUS_SOFTEND_WITH_PEC + * @param Request This parameter can be one of the following values: + * @arg @ref LL_I2C_GENERATE_NOSTARTSTOP + * @arg @ref LL_I2C_GENERATE_STOP + * @arg @ref LL_I2C_GENERATE_START_READ + * @arg @ref LL_I2C_GENERATE_START_WRITE + * @arg @ref LL_I2C_GENERATE_RESTART_7BIT_READ + * @arg @ref LL_I2C_GENERATE_RESTART_7BIT_WRITE + * @arg @ref LL_I2C_GENERATE_RESTART_10BIT_READ + * @arg @ref LL_I2C_GENERATE_RESTART_10BIT_WRITE + * @retval None + */ +__STATIC_INLINE void LL_I2C_HandleTransfer(I2C_TypeDef *I2Cx, uint32_t SlaveAddr, uint32_t SlaveAddrSize, + uint32_t TransferSize, uint32_t EndMode, uint32_t Request) +{ + MODIFY_REG(I2Cx->CR2, I2C_CR2_SADD | I2C_CR2_ADD10 | + (I2C_CR2_RD_WRN & (uint32_t)(Request >> (31U - I2C_CR2_RD_WRN_Pos))) | + I2C_CR2_START | I2C_CR2_STOP | I2C_CR2_RELOAD | + I2C_CR2_NBYTES | I2C_CR2_AUTOEND | I2C_CR2_HEAD10R, + SlaveAddr | SlaveAddrSize | (TransferSize << I2C_CR2_NBYTES_Pos) | EndMode | Request); +} + +/** + * @brief Indicate the value of transfer direction (slave mode). + * @note RESET: Write transfer, Slave enters in receiver mode. + * SET: Read transfer, Slave enters in transmitter mode. + * @rmtoll ISR DIR LL_I2C_GetTransferDirection + * @param I2Cx I2C Instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_I2C_DIRECTION_WRITE + * @arg @ref LL_I2C_DIRECTION_READ + */ +__STATIC_INLINE uint32_t LL_I2C_GetTransferDirection(const I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->ISR, I2C_ISR_DIR)); +} + +/** + * @brief Return the slave matched address. + * @rmtoll ISR ADDCODE LL_I2C_GetAddressMatchCode + * @param I2Cx I2C Instance. + * @retval Value between Min_Data=0x00 and Max_Data=0x3F + */ +__STATIC_INLINE uint32_t LL_I2C_GetAddressMatchCode(const I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->ISR, I2C_ISR_ADDCODE) >> I2C_ISR_ADDCODE_Pos << 1); +} + +/** + * @brief Enable internal comparison of the SMBus Packet Error byte (transmission or reception mode). + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @note This feature is cleared by hardware when the PEC byte is transferred, or when a STOP condition + or an Address Matched is received. + * This bit has no effect when RELOAD bit is set. + * This bit has no effect in device mode when SBC bit is not set. + * @rmtoll CR2 PECBYTE LL_I2C_EnableSMBusPECCompare + * @param I2Cx I2C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I2C_EnableSMBusPECCompare(I2C_TypeDef *I2Cx) +{ + SET_BIT(I2Cx->CR2, I2C_CR2_PECBYTE); +} + +/** + * @brief Check if the SMBus Packet Error byte internal comparison is requested or not. + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @rmtoll CR2 PECBYTE LL_I2C_IsEnabledSMBusPECCompare + * @param I2Cx I2C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2C_IsEnabledSMBusPECCompare(const I2C_TypeDef *I2Cx) +{ + return ((READ_BIT(I2Cx->CR2, I2C_CR2_PECBYTE) == (I2C_CR2_PECBYTE)) ? 1UL : 0UL); +} + +/** + * @brief Get the SMBus Packet Error byte calculated. + * @note The macro IS_SMBUS_ALL_INSTANCE(I2Cx) can be used to check whether or not + * SMBus feature is supported by the I2Cx Instance. + * @rmtoll PECR PEC LL_I2C_GetSMBusPEC + * @param I2Cx I2C Instance. + * @retval Value between Min_Data=0x00 and Max_Data=0xFF + */ +__STATIC_INLINE uint32_t LL_I2C_GetSMBusPEC(const I2C_TypeDef *I2Cx) +{ + return (uint32_t)(READ_BIT(I2Cx->PECR, I2C_PECR_PEC)); +} + +/** + * @brief Read Receive Data register. + * @rmtoll RXDR RXDATA LL_I2C_ReceiveData8 + * @param I2Cx I2C Instance. + * @retval Value between Min_Data=0x00 and Max_Data=0xFF + */ +__STATIC_INLINE uint8_t LL_I2C_ReceiveData8(const I2C_TypeDef *I2Cx) +{ + return (uint8_t)(READ_BIT(I2Cx->RXDR, I2C_RXDR_RXDATA)); +} + +/** + * @brief Write in Transmit Data Register . + * @rmtoll TXDR TXDATA LL_I2C_TransmitData8 + * @param I2Cx I2C Instance. + * @param Data Value between Min_Data=0x00 and Max_Data=0xFF + * @retval None + */ +__STATIC_INLINE void LL_I2C_TransmitData8(I2C_TypeDef *I2Cx, uint8_t Data) +{ + WRITE_REG(I2Cx->TXDR, Data); +} + +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup I2C_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +ErrorStatus LL_I2C_Init(I2C_TypeDef *I2Cx, const LL_I2C_InitTypeDef *I2C_InitStruct); +ErrorStatus LL_I2C_DeInit(const I2C_TypeDef *I2Cx); +void LL_I2C_StructInit(LL_I2C_InitTypeDef *I2C_InitStruct); + + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* I2C1 || I2C2 || I2C3 || I2C4 */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_LL_I2C_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_i3c.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_i3c.h new file mode 100644 index 0000000000..b534c071a1 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_i3c.h @@ -0,0 +1,4404 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_i3c.h + * @author MCD Application Team + * @brief Header file of I3C LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_LL_I3C_H +#define STM32H5xx_LL_I3C_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (I3C1) + +/** @defgroup I3C_LL I3C + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +/* Private constants ---------------------------------------------------------*/ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup I3C_LL_Private_Macros I3C Private Macros + * @{ + */ +/** + * @} + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup I3C_LL_ES_CONTROLLER_BUS_CONFIG_STRUCTURE_DEFINITION I3C Controller Bus Configuration Structure definition + * @brief I3C LL Controller Bus Configuration Structure definition + * @{ + */ +typedef struct +{ + uint32_t SDAHoldTime; /*!< Specifies the I3C SDA hold time. + This parameter must be a value of @ref I3C_LL_EC_SDA_HOLD_TIME */ + + uint32_t WaitTime; /*!< Specifies the time that the main and the new controllers should wait before + issuing a start. + This parameter must be a value of @ref I3C_LL_EC_OWN_ACTIVITY_STATE */ + + uint8_t SCLPPLowDuration; /*!< Specifies the I3C SCL low duration in number of kernel clock cycles + in I3C push-pull phases. + This parameter must be a number between Min_Data=0 and Max_Data=0xFF. */ + + uint8_t SCLI3CHighDuration; /*!< Specifies the I3C SCL high duration in number of kernel clock cycles, + used for I3C messages for I3C open-drain and push pull phases. + This parameter must be a number between Min_Data=0 and Max_Data=0xFF. */ + + uint8_t SCLODLowDuration; /*!< Specifies the I3C SCL low duration in number of kernel clock cycles in + open-drain phases, used for legacy I2C commands and for I3C open-drain phases. + This parameter must be a number between Min_Data=0 and Max_Data=0xFF. */ + + uint8_t SCLI2CHighDuration; /*!< Specifies the I3C SCL high duration in number of kernel clock cycles, used + for legacy I2C commands. + This parameter must be a number between Min_Data=0 and Max_Data=0xFF. */ + + uint8_t BusFreeDuration; /*!< Specifies the I3C controller duration in number of kernel clock cycles, after + a stop and before a start. + This parameter must be a number between Min_Data=0 and Max_Data=0xFF. */ + + uint8_t BusIdleDuration; /*!< Specifies the I3C controller duration in number of kernel clock cycles to be + elapsed, after that both SDA and SCL are continuously high and stable + before issuing a hot-join event. + This parameter must be a number between Min_Data=0 and Max_Data=0xFF. */ +} LL_I3C_CtrlBusConfTypeDef; +/** + * @} + */ + +/** @defgroup I3C_LL_ES_TARGET_BUS_CONFIG_STRUCTURE_DEFINITION I3C Target Bus Configuration Structure definition + * @brief I3C LL Target Bus Configuration Structure definition + * @{ + */ +typedef struct +{ + uint8_t BusAvailableDuration; /*!< Specifies the I3C target duration in number of kernel clock cycles, when + the SDA and the SCL are high for at least taval. + This parameter must be a number between Min_Data=0 and Max_Data=0xFF. */ +} LL_I3C_TgtBusConfTypeDef; +/** + * @} + */ +#if defined(USE_FULL_LL_DRIVER) + +/** @defgroup I3C_LL_ES_INIT I3C Exported Init structure + * @brief I3C LL Init Structure definition + * @{ + */ +typedef struct +{ + LL_I3C_CtrlBusConfTypeDef CtrlBusCharacteristic; /*!< Specifies the I3C controller bus characteristic configuration + when Controller mode */ + + LL_I3C_TgtBusConfTypeDef TgtBusCharacteristic; /*!< Specifies the I3C target bus characteristic configuration + when Target mode */ + +} LL_I3C_InitTypeDef; +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup I3C_LL_Exported_Constants I3C Exported Constants + * @{ + */ + +/** @defgroup I3C_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_I3C_ReadReg function + * @{ + */ +#define LL_I3C_EVR_CFEF I3C_EVR_CFEF +#define LL_I3C_EVR_TXFEF I3C_EVR_TXFEF +#define LL_I3C_EVR_CFNFF I3C_EVR_CFNFF +#define LL_I3C_EVR_SFNEF I3C_EVR_SFNEF +#define LL_I3C_EVR_TXFNFF I3C_EVR_TXFNFF +#define LL_I3C_EVR_RXFNEF I3C_EVR_RXFNEF +#define LL_I3C_EVR_RXLASTF I3C_EVR_RXLASTF +#define LL_I3C_EVR_TXLASTF I3C_EVR_TXLASTF +#define LL_I3C_EVR_FCF I3C_EVR_FCF +#define LL_I3C_EVR_RXTGTENDF I3C_EVR_RXTGTENDF +#define LL_I3C_EVR_ERRF I3C_EVR_ERRF +#define LL_I3C_EVR_IBIF I3C_EVR_IBIF +#define LL_I3C_EVR_IBIENDF I3C_EVR_IBIENDF +#define LL_I3C_EVR_CRF I3C_EVR_CRF +#define LL_I3C_EVR_CRUPDF I3C_EVR_CRUPDF +#define LL_I3C_EVR_HJF I3C_EVR_HJF +#define LL_I3C_EVR_WKPF I3C_EVR_WKPF +#define LL_I3C_EVR_GETF I3C_EVR_GETF +#define LL_I3C_EVR_STAF I3C_EVR_STAF +#define LL_I3C_EVR_DAUPDF I3C_EVR_DAUPDF +#define LL_I3C_EVR_MWLUPDF I3C_EVR_MWLUPDF +#define LL_I3C_EVR_MRLUPDF I3C_EVR_MRLUPDF +#define LL_I3C_EVR_RSTF I3C_EVR_RSTF +#define LL_I3C_EVR_ASUPDF I3C_EVR_ASUPDF +#define LL_I3C_EVR_INTUPDF I3C_EVR_INTUPDF +#define LL_I3C_EVR_DEFF I3C_EVR_DEFF +#define LL_I3C_EVR_GRPF I3C_EVR_GRPF +#define LL_I3C_SER_PERR I3C_SER_PERR +#define LL_I3C_SER_STALL I3C_SER_STALL +#define LL_I3C_SER_DOVR I3C_SER_DOVR +#define LL_I3C_SER_COVR I3C_SER_COVR +#define LL_I3C_SER_ANACK I3C_SER_ANACK +#define LL_I3C_SER_DNACK I3C_SER_DNACK +#define LL_I3C_SER_DERR I3C_SER_DERR +/** + * @} + */ + +/** @defgroup I3C_LL_EC_IT IT Defines + * @brief IT defines which can be used with LL_I3C_ReadReg and LL_I3C_WriteReg functions + * @{ + */ +#define LL_I3C_IER_CFNFIE I3C_IER_CFNFIE +#define LL_I3C_IER_SFNEIE I3C_IER_SFNEIE +#define LL_I3C_IER_TXFNFIE I3C_IER_TXFNFIE +#define LL_I3C_IER_RXFNEIE I3C_IER_RXFNEIE +#define LL_I3C_IER_FCIE I3C_IER_FCIE +#define LL_I3C_IER_RXTGTENDIE I3C_IER_RXTGTENDIE +#define LL_I3C_IER_ERRIE I3C_IER_ERRIE +#define LL_I3C_IER_IBIIE I3C_IER_IBIIE +#define LL_I3C_IER_IBIENDIE I3C_IER_IBIENDIE +#define LL_I3C_IER_CRIE I3C_IER_CRIE +#define LL_I3C_IER_CRUPDIE I3C_IER_CRUPDIE +#define LL_I3C_IER_HJIE I3C_IER_HJIE +#define LL_I3C_IER_WKPIE I3C_IER_WKPIE +#define LL_I3C_IER_GETIE I3C_IER_GETIE +#define LL_I3C_IER_STAIE I3C_IER_STAIE +#define LL_I3C_IER_DAUPDIE I3C_IER_DAUPDIE +#define LL_I3C_IER_MWLUPDIE I3C_IER_MWLUPDIE +#define LL_I3C_IER_MRLUPDIE I3C_IER_MRLUPDIE +#define LL_I3C_IER_RSTIE I3C_IER_RSTIE +#define LL_I3C_IER_ASUPDIE I3C_IER_ASUPDIE +#define LL_I3C_IER_INTUPDIE I3C_IER_INTUPDIE +#define LL_I3C_IER_DEFIE I3C_IER_DEFIE +#define LL_I3C_IER_GRPIE I3C_IER_GRPIE +/** + * @} + */ + +/** @defgroup I3C_LL_EC_MODE MODE + * @{ + */ +#define LL_I3C_MODE_CONTROLLER I3C_CFGR_CRINIT /*!< I3C Controller mode */ +#define LL_I3C_MODE_TARGET 0x00000000U /*!< I3C Target (Controller capable) mode */ +/** + * @} + */ + +/** @defgroup I3C_LL_EC_DMA_REG_DATA DMA Register Data + * @{ + */ +#define LL_I3C_DMA_REG_DATA_TRANSMIT_BYTE 0x00000000U /*!< Get address of data register used + for transmission in Byte */ +#define LL_I3C_DMA_REG_DATA_RECEIVE_BYTE 0x00000001U /*!< Get address of data register used + for reception in Byte */ +#define LL_I3C_DMA_REG_DATA_TRANSMIT_WORD 0x00000002U /*!< Get address of data register used for + transmission in Word */ +#define LL_I3C_DMA_REG_DATA_RECEIVE_WORD 0x00000003U /*!< Get address of data register used + for reception in Word */ +#define LL_I3C_DMA_REG_STATUS 0x00000004U /*!< Get address of status register used + for transfer status in Word */ +#define LL_I3C_DMA_REG_CONTROL 0x00000005U /*!< Get address of control register used + for transfer control in Word */ +/** + * @} + */ + +/** @defgroup I3C_LL_EC_RX_THRESHOLD RX THRESHOLD + * @{ + */ +#define LL_I3C_RXFIFO_THRESHOLD_1_4 0x00000000U +/*!< Rx Fifo Threshold is 1 byte in a Fifo depth of 4 bytes */ +#define LL_I3C_RXFIFO_THRESHOLD_4_4 I3C_CFGR_RXTHRES +/*!< Rx Fifo Threshold is 4 bytes in a Fifo depth of 4 bytes */ +/** + * @} + */ + +/** @defgroup I3C_LL_EC_TX_THRESHOLD TX THRESHOLD + * @{ + */ +#define LL_I3C_TXFIFO_THRESHOLD_1_4 0x00000000U +/*!< Tx Fifo Threshold is 1 byte in a Fifo depth of 4 bytes */ +#define LL_I3C_TXFIFO_THRESHOLD_4_4 I3C_CFGR_TXTHRES +/*!< Tx Fifo Threshold is 4 bytes in a Fifo depth of 4 bytes */ +/** + * @} + */ + +/** @defgroup I3C_LL_EC_PAYLOAD PAYLOAD + * @{ + */ +#define LL_I3C_PAYLOAD_EMPTY 0x00000000U +/*!< Empty payload, no additional data after IBI acknowledge */ +#define LL_I3C_PAYLOAD_1_BYTE I3C_MAXRLR_IBIP_0 +/*!< One additional data byte after IBI acknowledge */ +#define LL_I3C_PAYLOAD_2_BYTES I3C_MAXRLR_IBIP_1 +/*!< Two additional data bytes after IBI acknowledge */ +#define LL_I3C_PAYLOAD_3_BYTES (I3C_MAXRLR_IBIP_1 | I3C_MAXRLR_IBIP_0) +/*!< Three additional data bytes after IBI acknowledge */ +#define LL_I3C_PAYLOAD_4_BYTES I3C_MAXRLR_IBIP_2 +/*!< Four additional data bytes after IBI acknowledge */ +/** + * @} + */ + +/** @defgroup I3C_LL_EC_SDA_HOLD_TIME SDA HOLD TIME 0 + * @{ + */ +#define LL_I3C_SDA_HOLD_TIME_0_5 0x00000000U /*!< SDA hold time is 0.5 x ti3cclk */ +#define LL_I3C_SDA_HOLD_TIME_1_5 I3C_TIMINGR1_SDA_HD /*!< SDA hold time is 1.5 x ti3cclk */ +/** + * @} + */ + +/** @defgroup I3C_LL_EC_OWN_ACTIVITY_STATE OWN ACTIVITY STATE + * @{ + */ +#define LL_I3C_OWN_ACTIVITY_STATE_0 0x00000000U +/*!< Own Controller Activity state 0 */ +#define LL_I3C_OWN_ACTIVITY_STATE_1 I3C_TIMINGR1_ASNCR_0 +/*!< Own Controller Activity state 1 */ +#define LL_I3C_OWN_ACTIVITY_STATE_2 I3C_TIMINGR1_ASNCR_1 +/*!< Own Controller Activity state 2 */ +#define LL_I3C_OWN_ACTIVITY_STATE_3 (I3C_TIMINGR1_ASNCR_1 | I3C_TIMINGR1_ASNCR_0) +/*!< Own Controller Activity state 3 */ +/** + * @} + */ + +/** @defgroup I3C_LL_EC_DEVICE_ROLE_AS DEVICE ROLE AS + * @{ + */ +#define LL_I3C_DEVICE_ROLE_AS_TARGET 0x00000000U /*!< I3C Target */ +#define LL_I3C_DEVICE_ROLE_AS_CONTROLLER I3C_BCR_BCR6 /*!< I3C Controller */ +/** + * @} + */ + +/** @defgroup I3C_LL_EC_IBI_NO_ADDITIONAL IBI NO ADDITIONAL + * @{ + */ +#define LL_I3C_IBI_NO_ADDITIONAL_DATA 0x00000000U /*!< No data byte follows the accepted IBI */ +#define LL_I3C_IBI_ADDITIONAL_DATA I3C_BCR_BCR2 /*!< A Mandatory Data Byte (MDB) + follows the accepted IBI */ +/** + * @} + */ + +/** @defgroup I3C_LL_EC_MAX_DATA_SPEED_LIMITATION MAX DATA SPEED LIMITATION + * @{ + */ +#define LL_I3C_NO_DATA_SPEED_LIMITATION 0x00000000U /*!< No max data speed limitation */ +#define LL_I3C_MAX_DATA_SPEED_LIMITATION I3C_BCR_BCR0 /*!< Max data speed limitation */ +/** + * @} + */ + +/** @defgroup I3C_LL_EC_IBI_MDB_READ_NOTIFICATION IBI MDB READ NOTIFICATION + * @{ + */ +#define LL_I3C_MDB_NO_PENDING_READ_NOTIFICATION 0x00000000U +/*!< No support of pending read notification via the IBI MDB[7:0] value */ +#define LL_I3C_MDB_PENDING_READ_NOTIFICATION I3C_GETCAPR_CAPPEND +/*!< Support of pending read notification via the IBI MDB[7:0] value */ +/** + * @} + */ + +/** @defgroup I3C_LL_EC_HANDOFF_GRP_ADDR_NOT HANDOFF GRP ADDR NOT + * @{ + */ +#define LL_I3C_HANDOFF_GRP_ADDR_NOT_SUPPORTED 0x00000000U /*!< Group Address Handoff is not supported */ +#define LL_I3C_HANDOFF_GRP_ADDR_SUPPORTED I3C_CRCAPR_CAPGRP /*!< Group Address Handoff is supported */ +/** + * @} + */ + +/** @defgroup I3C_LL_EC_HANDOFF HANDOFF + * @{ + */ +#define LL_I3C_HANDOFF_NOT_DELAYED 0x00000000U +/*!< Additional time to process controllership handoff is not needed */ +#define LL_I3C_HANDOFF_DELAYED I3C_CRCAPR_CAPDHOFF +/*!< Additional time to process controllership handoff is needed */ +/** + * @} + */ + +/** @defgroup I3C_LL_EC_HANDOFF_ACTIVITY_STATE HANDOFF ACTIVITY STATE + * @{ + */ +#define LL_I3C_HANDOFF_ACTIVITY_STATE_0 0x00000000U +/*!< Indicates that will act according to Activity State 0 after controllership handoff */ +#define LL_I3C_HANDOFF_ACTIVITY_STATE_1 I3C_GETMXDSR_HOFFAS_0 +/*!< Indicates that will act according to Activity State 1 after controllership handoff */ +#define LL_I3C_HANDOFF_ACTIVITY_STATE_2 I3C_GETMXDSR_HOFFAS_1 +/*!< Indicates that will act according to Activity State 2 after controllership handoff */ +#define LL_I3C_HANDOFF_ACTIVITY_STATE_3 (I3C_GETMXDSR_HOFFAS_1 | I3C_GETMXDSR_HOFFAS_0) +/*!< Indicates that will act according to Activity State 3 after controllership handoff */ +/** + * @} + */ + +/** @defgroup I3C_LL_EC_GETMXDS_FORMAT GETMXDS FORMAT + * @{ + */ +#define LL_I3C_GETMXDS_FORMAT_1 0x00000000U +/*!< GETMXDS CCC Format 1 is used, no MaxRdTurn field in response */ +#define LL_I3C_GETMXDS_FORMAT_2_LSB I3C_GETMXDSR_FMT_0 +/*!< GETMXDS CCC Format 2 is used, MaxRdTurn field in response, LSB = RDTURN[7:0] */ +#define LL_I3C_GETMXDS_FORMAT_2_MID I3C_GETMXDSR_FMT_1 +/*!< GETMXDS CCC Format 2 is used, MaxRdTurn field in response, Middle byte = RDTURN[7:0] */ +#define LL_I3C_GETMXDS_FORMAT_2_MSB (I3C_GETMXDSR_FMT_1 | I3C_GETMXDSR_FMT_0) +/*!< GETMXDS CCC Format 2 is used, MaxRdTurn field in response, MSB = RDTURN[7:0] */ +/** + * @} + */ + +/** @defgroup I3C_LL_EC_GETMXDS_TSCO GETMXDS TSCO + * @{ + */ +#define LL_I3C_TURNAROUND_TIME_TSCO_LESS_12NS 0x00000000U /*!< clock-to-data turnaround time tSCO <= 12ns */ +#define LL_I3C_TURNAROUND_TIME_TSCO_GREATER_12NS I3C_GETMXDSR_TSCO /*!< clock-to-data turnaround time tSCO > 12ns */ +/** + * @} + */ + +/** @defgroup I3C_LL_EC_BUS_ACTIVITY_STATE BUS ACTIVITY STATE + * @{ + */ +#define LL_I3C_BUS_ACTIVITY_STATE_0 0x00000000U +/*!< Controller on the Bus Activity State 0 */ +#define LL_I3C_BUS_ACTIVITY_STATE_1 I3C_DEVR0_AS_0 +/*!< Controller on the Bus Activity State 1 */ +#define LL_I3C_BUS_ACTIVITY_STATE_2 I3C_DEVR0_AS_1 +/*!< Controller on the Bus Activity State 2 */ +#define LL_I3C_BUS_ACTIVITY_STATE_3 (I3C_DEVR0_AS_1 | I3C_DEVR0_AS_0) +/*!< Controller on the Bus Activity State 3 */ +/** + * @} + */ + +/** @defgroup I3C_LL_EC_RESET_ACTION RESET ACTION + * @{ + */ +#define LL_I3C_RESET_ACTION_NONE 0x00000000U +/*!< No Reset Action Required */ +#define LL_I3C_RESET_ACTION_PARTIAL I3C_DEVR0_RSTACT_0 +/*!< Reset of some internal registers of the peripheral*/ +#define LL_I3C_RESET_ACTION_FULL I3C_DEVR0_RSTACT_1 +/*!< Reset all internal registers of the peripheral */ +/** + * @} + */ + +/** @defgroup I3C_LL_EC_DIRECTION DIRECTION + * @{ + */ +#define LL_I3C_DIRECTION_WRITE 0x00000000U /*!< Write transfer */ +#define LL_I3C_DIRECTION_READ I3C_CR_RNW /*!< Read transfer */ +/** + * @} + */ + +/** @defgroup I3C_LL_EC_GENERATE GENERATE + * @{ + */ +#define LL_I3C_GENERATE_STOP I3C_CR_MEND +/*!< Generate Stop condition after sending a message */ +#define LL_I3C_GENERATE_RESTART 0x00000000U +/*!< Generate Restart condition after sending a message */ +/** + * @} + */ + +/** @defgroup I3C_LL_EC_CONTROLLER_MTYPE CONTROLLER MTYPE + * @{ + */ +#define LL_I3C_CONTROLLER_MTYPE_RELEASE 0x00000000U +/*!< SCL output clock stops running until next instruction executed */ +#define LL_I3C_CONTROLLER_MTYPE_HEADER I3C_CR_MTYPE_0 +/*!< Header Message */ +#define LL_I3C_CONTROLLER_MTYPE_PRIVATE I3C_CR_MTYPE_1 +/*!< Private Message Type */ +#define LL_I3C_CONTROLLER_MTYPE_DIRECT (I3C_CR_MTYPE_1 | I3C_CR_MTYPE_0) +/*!< Direct Message Type */ +#define LL_I3C_CONTROLLER_MTYPE_LEGACY_I2C I3C_CR_MTYPE_2 +/*!< Legacy I2C Message Type */ +#define LL_I3C_CONTROLLER_MTYPE_CCC (I3C_CR_MTYPE_2 | I3C_CR_MTYPE_1) +/*!< Common Command Code */ +/** + * @} + */ + +/** @defgroup I3C_LL_EC_TARGET_MTYPE_HOT TARGET MTYPE HOT + * @{ + */ +#define LL_I3C_TARGET_MTYPE_HOT_JOIN I3C_CR_MTYPE_3 /*!< Hot Join*/ +#define LL_I3C_TARGET_MTYPE_CONTROLLER_ROLE_REQ (I3C_CR_MTYPE_3 | I3C_CR_MTYPE_0) /*!< Controller-role Request */ +#define LL_I3C_TARGET_MTYPE_IBI (I3C_CR_MTYPE_3 | I3C_CR_MTYPE_1) /*!< In Band Interrupt (IBI) */ +/** + * @} + */ + +/** @defgroup I3C_LL_EC_MESSAGE MESSAGE + * @{ + */ +#define LL_I3C_MESSAGE_ERROR 0x00000000U /*!< An error has been detected in the message */ +#define LL_I3C_MESSAGE_SUCCESS I3C_SR_OK /*!< The message ended with success */ +/** + * @} + */ + +/** @defgroup I3C_LL_EC_MESSAGE_DIRECTION MESSAGE DIRECTION + * @{ + */ +#define LL_I3C_MESSAGE_DIRECTION_WRITE 0x00000000U /*!< Write data or command */ +#define LL_I3C_MESSAGE_DIRECTION_READ I3C_SR_DIR /*!< Read data */ +/** + * @} + */ + +/** @defgroup I3C_LL_EC_CONTROLLER_ERROR CONTROLLER ERROR + * @{ + */ +#define LL_I3C_CONTROLLER_ERROR_CE0 0x00000000U +/*!< Controller detected an illegally formatted CCC */ +#define LL_I3C_CONTROLLER_ERROR_CE1 I3C_SER_CODERR_0 +/*!< Controller detected that transmitted data on the bus is different than expected */ +#define LL_I3C_CONTROLLER_ERROR_CE2 I3C_SER_CODERR_1 +/*!< Controller detected that broadcast address 7'h7E has been nacked */ +#define LL_I3C_CONTROLLER_ERROR_CE3 (I3C_SER_CODERR_1 | I3C_SER_CODERR_0) +/*!< Controller detected that new Controller did not drive the bus after Controller-role handoff */ +/** + * @} + */ + +/** @defgroup I3C_LL_EC_TARGET_ERROR TARGET ERROR + * @{ + */ +#define LL_I3C_TARGET_ERROR_TE0 I3C_SER_CODERR_3 +/*!< Target detected an invalid broadcast address */ +#define LL_I3C_TARGET_ERROR_TE1 (I3C_SER_CODERR_3 | I3C_SER_CODERR_0) +/*!< Target detected an invalid CCC Code */ +#define LL_I3C_TARGET_ERROR_TE2 (I3C_SER_CODERR_3 | I3C_SER_CODERR_1) +/*!< Target detected an invalid write data */ +#define LL_I3C_TARGET_ERROR_TE3 (I3C_SER_CODERR_3 | I3C_SER_CODERR_1 | I3C_SER_CODERR_0) +/*!< Target detected an invalid assigned address during Dynamic Address Assignment procedure */ +#define LL_I3C_TARGET_ERROR_TE4 (I3C_SER_CODERR_3 | I3C_SER_CODERR_2) +/*!< Target detected 7'h7E missing after Restart during Dynamic Address Assignment procedure */ +#define LL_I3C_TARGET_ERROR_TE5 (I3C_SER_CODERR_3 | I3C_SER_CODERR_2 | I3C_SER_CODERR_0) +/*!< Target detected an illegally formatted CCC */ +#define LL_I3C_TARGET_ERROR_TE6 (I3C_SER_CODERR_3 | I3C_SER_CODERR_2 | I3C_SER_CODERR_1) +/*!< Target detected that transmitted data on the bus is different than expected */ +/** + * @} + */ + +/** @defgroup I3C_BCR_IN_PAYLOAD I3C BCR IN PAYLOAD + * @{ + */ +#define LL_I3C_BCR_IN_PAYLOAD_SHIFT 48 /*!< BCR field in target payload */ +/** + * @} + */ + +/** @defgroup I3C_LL_EC_IBI_CAPABILITY IBI CAPABILITY + * @{ + */ +#define LL_I3C_IBI_CAPABILITY I3C_DEVRX_IBIACK +/*!< Controller acknowledge Target In Band Interrupt capable */ +#define LL_I3C_IBI_NO_CAPABILITY 0x00000000U +/*!< Controller no acknowledge Target In Band Interrupt capable */ +/** + * @} + */ + +/** @defgroup I3C_LL_EC_IBI_ADDITIONAL_DATA IBI ADDITIONAL DATA + * @{ + */ +#define LL_I3C_IBI_DATA_ENABLE I3C_DEVRX_IBIDEN +/*!< A mandatory data byte follows the IBI acknowledgement */ +#define LL_I3C_IBI_DATA_DISABLE 0x00000000U +/*!< No mandatory data byte follows the IBI acknowledgement */ +/** + * @} + */ + +/** @defgroup I3C_LL_EC_CR_CAPABILITY CR CAPABILITY + * @{ + */ +#define LL_I3C_CR_CAPABILITY I3C_DEVRX_CRACK +/*!< Controller acknowledge Target Controller Role capable */ +#define LL_I3C_CR_NO_CAPABILITY 0x00000000U +/*!< Controller no acknowledge Target Controller Role capable */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup I3C_LL_Exported_Macros I3C Exported Macros + * @{ + */ + +/** @defgroup I3C_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** @brief Get Bus Characterics in payload (64bits) receive during ENTDAA procedure. + * @param __PAYLOAD__ specifies the Bus Characteristics capabilities retrieve during ENTDAA procedure. + * This parameter must be a number between Min_Data=0x00(uint64_t) and Max_Data=0xFFFFFFFFFFFFFFFFFF. + * @retval The value of BCR Return value between Min_Data=0x00 and Max_Data=0xFF. + */ +#define LL_I3C_GET_BCR(__PAYLOAD__) (((uint32_t)((uint64_t)(__PAYLOAD__) >> LL_I3C_BCR_IN_PAYLOAD_SHIFT)) & \ + I3C_BCR_BCR) + +/** @brief Check IBI request capabilities. + * @param __BCR__ specifies the Bus Characteristics capabilities retrieve during ENTDAA procedure. + * This parameter must be a number between Min_Data=0x00 and Max_Data=0xFF. + * @retval Value of @ref I3C_LL_EC_IBI_CAPABILITY. + */ +#define LL_I3C_GET_IBI_CAPABLE(__BCR__) (((((__BCR__) & I3C_BCR_BCR1_Msk) >> I3C_BCR_BCR1_Pos) == 1U) \ + ? LL_I3C_IBI_CAPABILITY : LL_I3C_IBI_NO_CAPABILITY) + +/** @brief Check IBI additional data byte capabilities. + * @param __BCR__ specifies the Bus Characteristics capabilities retrieve during ENTDAA procedure. + * This parameter must be a number between Min_Data=0x00 and Max_Data=0xFF. + * @retval Value of @ref I3C_LL_EC_IBI_ADDITIONAL_DATA. + */ +#define LL_I3C_GET_IBI_PAYLOAD(__BCR__) (((((__BCR__) & I3C_BCR_BCR2_Msk) >> I3C_BCR_BCR2_Pos) == 1U) \ + ? LL_I3C_IBI_DATA_ENABLE : LL_I3C_IBI_DATA_DISABLE) + +/** @brief Check Controller role request capabilities. + * @param __BCR__ specifies the Bus Characteristics capabilities retrieve during ENTDAA procedure. + * This parameter must be a number between Min_Data=0x00 and Max_Data=0xFF. + * @retval Value of @ref I3C_LL_EC_CR_CAPABILITY. + */ +#define LL_I3C_GET_CR_CAPABLE(__BCR__) (((((__BCR__) & I3C_BCR_BCR6_Msk) >> I3C_BCR_BCR6_Pos) == 1U) \ + ? LL_I3C_CR_CAPABILITY : LL_I3C_CR_NO_CAPABILITY) + +/** + * @brief Write a value in I3C register + * @param __INSTANCE__ I3C Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_I3C_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in I3C register + * @param __INSTANCE__ I3C Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_I3C_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup I3C_LL_Exported_Functions I3C Exported Functions + * @{ + */ + +/** @defgroup I3C_LL_EF_Configuration Configuration + * @{ + */ + +/** + * @brief Enable I3C peripheral (EN = 1). + * @rmtoll CFGR EN LL_I3C_Enable + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_Enable(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->CFGR, I3C_CFGR_EN); +} + +/** + * @brief Disable I3C peripheral (EN = 0). + * @note Controller mode: before clearing EN, all possible target requests must be disabled using DISEC CCC. + * Target mode: software is not expected clearing EN unless a partial reset of the IP is needed + * @rmtoll CFGR EN LL_I3C_Disable + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_Disable(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->CFGR, I3C_CFGR_EN); +} + +/** + * @brief Check if the I3C peripheral is enabled or disabled. + * @rmtoll CFGR EN LL_I3C_IsEnabled + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabled(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->CFGR, I3C_CFGR_EN) == (I3C_CFGR_EN)) ? 1UL : 0UL); +} + +/** + * @brief Check if Reset action is required or not required. + * @note This bit indicates if Reset Action field has been updated by HW upon reception + * of RSTACT during current frame. + * @rmtoll DEVR0 RSTVAL LL_I3C_IsEnabledReset + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledReset(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->DEVR0, I3C_DEVR0_RSTVAL) == (I3C_DEVR0_RSTVAL)) ? 1UL : 0UL); +} + +/** + * @brief Configure peripheral mode. + * @note This bit can only be programmed when the I3C is disabled (EN = 0). + * @rmtoll CFGR CRINIT LL_I3C_SetMode + * @param I3Cx I3C Instance. + * @param PeripheralMode This parameter can be one of the following values: + * @arg @ref LL_I3C_MODE_CONTROLLER + * @arg @ref LL_I3C_MODE_TARGET + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetMode(I3C_TypeDef *I3Cx, uint32_t PeripheralMode) +{ + MODIFY_REG(I3Cx->CFGR, I3C_CFGR_CRINIT, PeripheralMode); +} + +/** + * @brief Get peripheral mode. + * @rmtoll CFGR CRINIT LL_I3C_GetMode + * @param I3Cx I3C Instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_I3C_MODE_CONTROLLER + * @arg @ref LL_I3C_MODE_TARGET + */ +__STATIC_INLINE uint32_t LL_I3C_GetMode(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)((READ_BIT(I3Cx->CFGR, I3C_CFGR_CRINIT) == (I3C_CFGR_CRINIT)) ? 1UL : 0UL); +} + +/** + * @brief An arbitration header (7'h7E) is sent after Start in case of legacy I2C or I3C private transfers. + * @note This bit can be modified only when there is no frame ongoing + * @rmtoll CFGR NOARBH LL_I3C_EnableArbitrationHeader + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableArbitrationHeader(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->CFGR, I3C_CFGR_NOARBH); +} + +/** + * @brief Target address is sent directly after a Start in case of legacy I2C or I3C private transfers. + * @note This bit can be modified only when there is no frame ongoing + * @rmtoll CFGR NOARBH LL_I3C_DisableArbitrationHeader + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableArbitrationHeader(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->CFGR, I3C_CFGR_NOARBH); +} + +/** + * @brief Check if the arbitration header is enabled of disabled. + * @rmtoll CFGR NOARBH LL_I3C_IsEnabledArbitrationHeader + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledArbitrationHeader(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->CFGR, I3C_CFGR_NOARBH) == (I3C_CFGR_NOARBH)) ? 0UL : 1UL); +} + +/** + * @brief A Reset Pattern is inserted before the STOP at the end of a frame when the last CCC + * of the frame was RSTACT CCC. + * @note This bit can be modified only when there is no frame ongoing + * @rmtoll CFGR RSTPTRN LL_I3C_EnableResetPattern + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableResetPattern(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->CFGR, I3C_CFGR_RSTPTRN); +} + +/** + * @brief A single STOP is emitted at the end of a frame. + * @note This bit can be modified only when there is no frame ongoing + * @rmtoll CFGR RSTPTRN LL_I3C_DisableResetPattern + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableResetPattern(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->CFGR, I3C_CFGR_RSTPTRN); +} + +/** + * @brief Check if Reset Pattern is enabled of disabled. + * @rmtoll CFGR RSTPTRN LL_I3C_IsEnabledResetPattern + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledResetPattern(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->CFGR, I3C_CFGR_RSTPTRN) == (I3C_CFGR_RSTPTRN)) ? 1UL : 0UL); +} + +/** + * @brief An Exit Pattern is sent after header (MTYPE = header) to program an escalation fault. + * @note This bit can be modified only when there is no frame ongoing + * @rmtoll CFGR EXITPTRN LL_I3C_EnableExitPattern + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableExitPattern(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->CFGR, I3C_CFGR_EXITPTRN); +} + +/** + * @brief An Exit Pattern is not sent after header (MTYPE = header). + * @note This bit can be modified only when there is no frame ongoing + * @rmtoll CFGR EXITPTRN LL_I3C_DisableExitPattern + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableExitPattern(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->CFGR, I3C_CFGR_EXITPTRN); +} + +/** + * @brief Check if Exit Pattern is enabled or disabled. + * @rmtoll CFGR EXITPTRN LL_I3C_IsEnabledExitPattern + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledExitPattern(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->CFGR, I3C_CFGR_EXITPTRN) == (I3C_CFGR_EXITPTRN)) ? 1UL : 0UL); +} + +/** + * @brief High Keeper is enabled and will be used in place of standard Open drain Pull Up device + * during handoff procedures. + * @note This bit can only be programmed when the I3C is disabled (EN = 0). + * @rmtoll CFGR HKSDAEN LL_I3C_EnableHighKeeperSDA + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableHighKeeperSDA(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->CFGR, I3C_CFGR_HKSDAEN); +} + +/** + * @brief High Keeper is disabled. + * @note This bit can only be programmed when the I3C is disabled (EN = 0). + * @rmtoll CFGR HKSDAEN LL_I3C_DisableHighKeeperSDA + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableHighKeeperSDA(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->CFGR, I3C_CFGR_HKSDAEN); +} + +/** + * @brief Check if High Keeper is enabled or disabled. + * @rmtoll CFGR HKSDAEN LL_I3C_IsEnabledHighKeeperSDA + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledHighKeeperSDA(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->CFGR, I3C_CFGR_HKSDAEN) == (I3C_CFGR_HKSDAEN)) ? 1UL : 0UL); +} + +/** + * @brief Hot Join Request is Acked. Current frame on the bus is continued. + * An Hot Join interrupt is sent through HJF flag. + * @note This bit can be used when I3C is acting as a Controller. + * @rmtoll CFGR HJACK LL_I3C_EnableHJAck + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableHJAck(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->CFGR, I3C_CFGR_HJACK); +} + +/** + * @brief Hot Join Request is Nacked. Current frame on the bus is continued. + * No Hot Join interrupt is generated. + * @note This bit can be used when I3C is acting as a Controller. + * @rmtoll CFGR HJACK LL_I3C_DisableHJAck + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableHJAck(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->CFGR, I3C_CFGR_HJACK); +} + +/** + * @brief Check if Hot Join Request Acknowledgement is enabled or disabled. + * @rmtoll CFGR HJACK LL_I3C_IsEnabledHJAck + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledHJAck(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->CFGR, I3C_CFGR_HJACK) == (I3C_CFGR_HJACK)) ? 1UL : 0UL); +} + +/** + * @brief Get the data register address used for DMA transfer + * @rmtoll TDR TDB0 LL_I3C_DMA_GetRegAddr\n + * TDWR TDWR LL_I3C_DMA_GetRegAddr\n + * RDR RXRB0 LL_I3C_DMA_GetRegAddr\n + * RDWR RDWR LL_I3C_DMA_GetRegAddr\n + * SR SR LL_I3C_DMA_GetRegAddr\n + * CR CR LL_I3C_DMA_GetRegAddr + * @param I3Cx I3C Instance + * @param Direction This parameter can be one of the following values: + * @arg @ref LL_I3C_DMA_REG_DATA_TRANSMIT_BYTE + * @arg @ref LL_I3C_DMA_REG_DATA_RECEIVE_BYTE + * @arg @ref LL_I3C_DMA_REG_DATA_TRANSMIT_WORD + * @arg @ref LL_I3C_DMA_REG_DATA_RECEIVE_WORD + * @arg @ref LL_I3C_DMA_REG_STATUS + * @arg @ref LL_I3C_DMA_REG_CONTROL + * @retval Address of data register + */ +__STATIC_INLINE uint32_t LL_I3C_DMA_GetRegAddr(const I3C_TypeDef *I3Cx, uint32_t Direction) +{ + register uint32_t data_reg_addr; + + if (Direction == LL_I3C_DMA_REG_DATA_TRANSMIT_BYTE) + { + /* return address of TDR register */ + data_reg_addr = (uint32_t) &(I3Cx->TDR); + } + else if (Direction == LL_I3C_DMA_REG_DATA_RECEIVE_BYTE) + { + /* return address of RDR register */ + data_reg_addr = (uint32_t) &(I3Cx->RDR); + } + else if (Direction == LL_I3C_DMA_REG_DATA_TRANSMIT_WORD) + { + /* return address of TDWR register */ + data_reg_addr = (uint32_t) &(I3Cx->TDWR); + } + else if (Direction == LL_I3C_DMA_REG_DATA_RECEIVE_WORD) + { + /* return address of RDWR register */ + data_reg_addr = (uint32_t) &(I3Cx->RDWR); + } + else if (Direction == LL_I3C_DMA_REG_STATUS) + { + /* return address of SR register */ + data_reg_addr = (uint32_t) &(I3Cx->SR); + } + else + { + /* return address of CR register */ + data_reg_addr = (uint32_t) &(I3Cx->CR); + } + + return data_reg_addr; +} + +/** + * @brief Enable DMA FIFO reception requests. + * @rmtoll CFGR RXDMAEN LL_I3C_EnableDMAReq_RX + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableDMAReq_RX(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->CFGR, I3C_CFGR_RXDMAEN); +} + +/** + * @brief Disable DMA FIFO reception requests. + * @rmtoll CFGR RXDMAEN LL_I3C_DisableDMAReq_RX + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableDMAReq_RX(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->CFGR, I3C_CFGR_RXDMAEN); +} + +/** + * @brief Check if DMA FIFO reception requests are enabled or disabled. + * @rmtoll CFGR RXDMAEN LL_I3C_IsEnabledDMAReq_RX + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledDMAReq_RX(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->CFGR, I3C_CFGR_RXDMAEN) == (I3C_CFGR_RXDMAEN)) ? 1UL : 0UL); +} + +/** + * @brief Set the Receive FIFO Threshold level. + * @rmtoll CFGR RXTHRES LL_I3C_SetRxFIFOThreshold + * @param I3Cx I3C Instance. + * @param RxFIFOThreshold This parameter can be one of the following values: + * @arg @ref LL_I3C_RXFIFO_THRESHOLD_1_4 + * @arg @ref LL_I3C_RXFIFO_THRESHOLD_4_4 + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetRxFIFOThreshold(I3C_TypeDef *I3Cx, uint32_t RxFIFOThreshold) +{ + MODIFY_REG(I3Cx->CFGR, I3C_CFGR_RXTHRES, RxFIFOThreshold); +} + +/** + * @brief Get the Receive FIFO Threshold level. + * @rmtoll CFGR RXTHRES LL_I3C_GetRxFIFOThreshold + * @param I3Cx I3C Instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_I3C_RXFIFO_THRESHOLD_1_4 + * @arg @ref LL_I3C_RXFIFO_THRESHOLD_4_4 + */ +__STATIC_INLINE uint32_t LL_I3C_GetRxFIFOThreshold(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->CFGR, I3C_CFGR_RXTHRES)); +} + +/** + * @brief Enable DMA FIFO transmission requests. + * @rmtoll CFGR TXDMAEN LL_I3C_EnableDMAReq_TX + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableDMAReq_TX(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->CFGR, I3C_CFGR_TXDMAEN); +} + +/** + * @brief Disable DMA FIFO transmission requests. + * @rmtoll CFGR TXDMAEN LL_I3C_DisableDMAReq_TX + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableDMAReq_TX(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->CFGR, I3C_CFGR_TXDMAEN); +} + +/** + * @brief Check if DMA FIFO transmission requests are enabled or disabled. + * @rmtoll CFGR TXDMAEN LL_I3C_IsEnabledDMAReq_TX + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledDMAReq_TX(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->CFGR, I3C_CFGR_TXDMAEN) == (I3C_CFGR_TXDMAEN)) ? 1UL : 0UL); +} + +/** + * @brief Set the Transmit FIFO Threshold level. + * @rmtoll CFGR TXTHRES LL_I3C_SetTxFIFOThreshold + * @param I3Cx I3C Instance. + * @param TxFIFOThreshold This parameter can be one of the following values: + * @arg @ref LL_I3C_TXFIFO_THRESHOLD_1_4 + * @arg @ref LL_I3C_TXFIFO_THRESHOLD_4_4 + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetTxFIFOThreshold(I3C_TypeDef *I3Cx, uint32_t TxFIFOThreshold) +{ + MODIFY_REG(I3Cx->CFGR, I3C_CFGR_TXTHRES, TxFIFOThreshold); +} + +/** + * @brief Get the Transmit FIFO Threshold level. + * @rmtoll CFGR TXTHRES LL_I3C_GetTxFIFOThreshold + * @param I3Cx I3C Instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_I3C_TXFIFO_THRESHOLD_1_4 + * @arg @ref LL_I3C_TXFIFO_THRESHOLD_4_4 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_GetTxFIFOThreshold(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->CFGR, I3C_CFGR_TXTHRES)); +} + +/** + * @brief Enable DMA FIFO Status requests. + * @rmtoll CFGR SDMAEN LL_I3C_EnableDMAReq_Status + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableDMAReq_Status(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->CFGR, I3C_CFGR_SDMAEN); +} + +/** + * @brief Disable DMA FIFO Status requests. + * @rmtoll CFGR SDMAEN LL_I3C_DisableDMAReq_Status + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableDMAReq_Status(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->CFGR, I3C_CFGR_SDMAEN); +} + +/** + * @brief Check if DMA FIFO Status requests are enabled or disabled. + * @rmtoll CFGR SDMAEN LL_I3C_IsEnabledDMAReq_Status + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledDMAReq_Status(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->CFGR, I3C_CFGR_SDMAEN) == (I3C_CFGR_SDMAEN)) ? 1UL : 0UL); +} + +/** + * @brief Enable the Status FIFO. + * @note Not applicable in target mode. Status FIFO always disabled in target mode. + * @rmtoll CFGR SMODE LL_I3C_EnableStatusFIFO + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableStatusFIFO(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->CFGR, I3C_CFGR_SMODE); +} + +/** + * @brief Disable the Status FIFO Threshold. + * @rmtoll CFGR SMODE LL_I3C_DisableStatusFIFO + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableStatusFIFO(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->CFGR, I3C_CFGR_SMODE); +} + +/** + * @brief Check if the Status FIFO Threshold is enabled or disabled. + * @rmtoll CFGR SMODE LL_I3C_IsEnabledStatusFIFO + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledStatusFIFO(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->CFGR, I3C_CFGR_SMODE) == (I3C_CFGR_SMODE)) ? 1UL : 0UL); +} + +/** + * @brief Enable the Control and Transmit FIFO preloaded before starting a transfer on I3C bus. + * @note Not applicable in target mode. Control FIFO always disabled in target mode. + * @rmtoll CFGR TMODE LL_I3C_EnableControlFIFO + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableControlFIFO(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->CFGR, I3C_CFGR_TMODE); +} + +/** + * @brief Disable the Control and Transmit FIFO preloaded before starting a transfer on I3C bus. + * @rmtoll CFGR TMODE LL_I3C_DisableControlFIFO + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableControlFIFO(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->CFGR, I3C_CFGR_TMODE); +} + +/** + * @brief Check if the Control and Transmit FIFO preloaded is enabled or disabled. + * @rmtoll CFGR TMODE LL_I3C_IsEnabledControlFIFO + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledControlFIFO(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->CFGR, I3C_CFGR_TMODE) == (I3C_CFGR_TMODE)) ? 1UL : 0UL); +} + +/** + * @brief Enable DMA FIFO Control word transfer requests. + * @rmtoll CFGR CDMAEN LL_I3C_EnableDMAReq_Control + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableDMAReq_Control(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->CFGR, I3C_CFGR_CDMAEN); +} + +/** + * @brief Disable DMA FIFO Control word transfer requests. + * @rmtoll CFGR CDMAEN LL_I3C_DisableDMAReq_Control + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableDMAReq_Control(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->CFGR, I3C_CFGR_CDMAEN); +} + +/** + * @brief Check if DMA FIFO Control word transfer requests are enabled or disabled. + * @rmtoll CFGR CDMAEN LL_I3C_IsEnabledDMAReq_Control + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledDMAReq_Control(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->CFGR, I3C_CFGR_CDMAEN) == (I3C_CFGR_CDMAEN)) ? 1UL : 0UL); +} + +/** + * @brief Set Own Dynamic Address as Valid. + * @rmtoll DEVR0 DAVAL LL_I3C_EnableOwnDynAddress + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableOwnDynAddress(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->DEVR0, I3C_DEVR0_DAVAL); +} + +/** + * @brief Set Own Dynamic Address as Not-Valid. + * @rmtoll DEVR0 DAVAL LL_I3C_DisableOwnDynAddress + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableOwnDynAddress(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->DEVR0, I3C_DEVR0_DAVAL); +} + +/** + * @brief Check if Own Dynamic address is Valid or Not-Valid. + * @rmtoll DEVR0 DAVAL LL_I3C_IsEnabledOwnDynAddress + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledOwnDynAddress(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->DEVR0, I3C_DEVR0_DAVAL) == (I3C_DEVR0_DAVAL)) ? 1UL : 0UL); +} + +/** + * @brief Configure Own Dynamic Address. + * @note This bit can be programmed in controller mode or during Dynamic Address procedure from current controller. + * @rmtoll DEVR0 DA LL_I3C_SetOwnDynamicAddress + * @param I3Cx I3C Instance. + * @param OwnDynamicAddress This parameter must be a value between Min_Data=0 and Max_Data=0x7F + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetOwnDynamicAddress(I3C_TypeDef *I3Cx, uint32_t OwnDynamicAddress) +{ + MODIFY_REG(I3Cx->DEVR0, I3C_DEVR0_DA, (OwnDynamicAddress << I3C_DEVR0_DA_Pos)); +} + +/** + * @brief Get Own Dynamic Address. + * @rmtoll DEVR0 DA LL_I3C_GetOwnDynamicAddress + * @param I3Cx I3C Instance. + * @retval Value between Min_Data=0 and Max_Data=0x7F + */ +__STATIC_INLINE uint8_t LL_I3C_GetOwnDynamicAddress(const I3C_TypeDef *I3Cx) +{ + return (uint8_t)(READ_BIT(I3Cx->DEVR0, I3C_DEVR0_DA) >> I3C_DEVR0_DA_Pos); +} + +/** + * @brief Set IBI procedure allowed (when the I3C is acting as target). + * @note This bit can be programmed when the I3C is disabled (EN = 0) or updated by HW upon reception of DISEC CCC. + * @rmtoll DEVR0 IBIEN LL_I3C_EnableIBI + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableIBI(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->DEVR0, I3C_DEVR0_IBIEN); +} + +/** + * @brief Set IBI procedure not-allowed (when the I3C is acting as target). + * @note This bit can be programmed when the I3C is disabled (EN = 0) or updated by HW upon reception of DISEC CCC. + * @rmtoll DEVR0 IBIEN LL_I3C_DisableIBI + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableIBI(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->DEVR0, I3C_DEVR0_IBIEN); +} + +/** + * @brief Check if IBI procedure is allowed or not allowed. + * @rmtoll DEVR0 IBIEN LL_I3C_IsEnabledIBI + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledIBI(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->DEVR0, I3C_DEVR0_IBIEN) == (I3C_DEVR0_IBIEN)) ? 1UL : 0UL); +} + +/** + * @brief Set Controller-role Request allowed (when the I3C is acting as target). + * @note This bit can be programmed when the I3C is disabled (EN = 0) or updated by HW upon reception of DISEC CCC. + * @rmtoll DEVR0 CREN LL_I3C_EnableControllerRoleReq + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableControllerRoleReq(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->DEVR0, I3C_DEVR0_CREN); +} + +/** + * @brief Set Controller-role Request as not-allowed (when the I3C is acting as target). + * @note This bit can be programmed when the I3C is disabled (EN = 0) or updated by HW upon reception of DISEC CCC. + * @rmtoll DEVR0 CREN LL_I3C_DisableControllerRoleReq + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableControllerRoleReq(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->DEVR0, I3C_DEVR0_CREN); +} + +/** + * @brief Check if Controller-role Request is allowed or not-allowed. + * @rmtoll DEVR0 CREN LL_I3C_IsEnabledControllerRoleReq + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledControllerRoleReq(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->DEVR0, I3C_DEVR0_CREN) == (I3C_DEVR0_CREN)) ? 1UL : 0UL); +} + +/** + * @brief Set Hot Join allowed (when the I3C is acting as target). + * @note This bit can be programmed when the I3C is disabled (EN = 0) or updated by HW upon reception of DISEC CCC. + * @rmtoll DEVR0 HJEN LL_I3C_EnableHotJoin + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableHotJoin(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->DEVR0, I3C_DEVR0_HJEN); +} + +/** + * @brief Set Hot Join as not-allowed (when the I3C is acting as target). + * @note This bit can be programmed when the I3C is disabled (EN = 0) or updated by HW upon reception of DISEC CCC. + * @rmtoll DEVR0 HJEN LL_I3C_DisableHotJoin + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableHotJoin(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->DEVR0, I3C_DEVR0_HJEN); +} + +/** + * @brief Check if Hot Join is allowed or not-allowed. + * @rmtoll DEVR0 HJEN LL_I3C_IsEnabledHotJoin + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledHotJoin(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->DEVR0, I3C_DEVR0_HJEN) == (I3C_DEVR0_HJEN)) ? 1UL : 0UL); +} + +/** + * @brief Configure Maximum Read Length (target mode). + * @note Those bits can be updated by HW upon reception of GETMRL CCC. + * @rmtoll MAXRLR MRL LL_I3C_SetMaxReadLength + * @param I3Cx I3C Instance. + * @param MaxReadLength This parameter must be a value between Min_Data=0x0 and Max_Data=0xFFFF + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetMaxReadLength(I3C_TypeDef *I3Cx, uint16_t MaxReadLength) +{ + MODIFY_REG(I3Cx->MAXRLR, I3C_MAXRLR_MRL, MaxReadLength); +} + +/** + * @brief Return Maximum Read Length (target mode). + * @rmtoll MAXRLR MRL LL_I3C_GetMaxReadLength + * @param I3Cx I3C Instance. + * @retval Value between Min_Data=0x0 and Max_Data=0xFFFFF + */ +__STATIC_INLINE uint32_t LL_I3C_GetMaxReadLength(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->MAXRLR, I3C_MAXRLR_MRL)); +} + +/** + * @brief Configure the number of additional Mandatory Data Byte (MDB) sent to the controller + * after an acknowledge of the IBI (target mode). + * @rmtoll MAXRLR IBIP LL_I3C_ConfigNbIBIAddData + * @param I3Cx I3C Instance. + * @param NbIBIAddData This parameter can be one of the following values: + * @arg @ref LL_I3C_PAYLOAD_EMPTY + * @arg @ref LL_I3C_PAYLOAD_1_BYTE + * @arg @ref LL_I3C_PAYLOAD_2_BYTES + * @arg @ref LL_I3C_PAYLOAD_3_BYTES + * @arg @ref LL_I3C_PAYLOAD_4_BYTES + * @retval None + */ +__STATIC_INLINE void LL_I3C_ConfigNbIBIAddData(I3C_TypeDef *I3Cx, uint32_t NbIBIAddData) +{ + MODIFY_REG(I3Cx->MAXRLR, I3C_MAXRLR_IBIP, NbIBIAddData); +} + +/** + * @brief Return the number of additional Mandatory Data Byte (MDB) sent to the controller + * after an acknowledge of the IBI (target mode). + * @rmtoll MAXRLR IBIP LL_I3C_GetConfigNbIBIAddData + * @param I3Cx I3C Instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_I3C_PAYLOAD_EMPTY + * @arg @ref LL_I3C_PAYLOAD_1_BYTE + * @arg @ref LL_I3C_PAYLOAD_2_BYTES + * @arg @ref LL_I3C_PAYLOAD_3_BYTES + * @arg @ref LL_I3C_PAYLOAD_4_BYTES + */ +__STATIC_INLINE uint32_t LL_I3C_GetConfigNbIBIAddData(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->MAXRLR, I3C_MAXRLR_IBIP)); +} + +/** + * @brief Configure Maximum Write Length (target mode). + * @note Those bits can be updated by HW upon reception of GETMWL CCC. + * @rmtoll MAXWLR MWL LL_I3C_SetMaxWriteLength + * @param I3Cx I3C Instance. + * @param MaxWriteLength This parameter must be a value between Min_Data=0x0 and Max_Data=0xFFFF + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetMaxWriteLength(I3C_TypeDef *I3Cx, uint16_t MaxWriteLength) +{ + MODIFY_REG(I3Cx->MAXWLR, I3C_MAXWLR_MWL, MaxWriteLength); +} + +/** + * @brief Return Maximum Write Length (target mode). + * @rmtoll MAXWLR MWL LL_I3C_GetMaxWriteLength + * @param I3Cx I3C Instance. + * @retval Value between Min_Data=0x0 and Max_Data=0xFFFFF + */ +__STATIC_INLINE uint32_t LL_I3C_GetMaxWriteLength(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->MAXWLR, I3C_MAXWLR_MWL)); +} + +/** + * @brief Configure the SCL clock signal waveform. + * @note This bit can only be programmed when the I3C is disabled (EN = 0). + * + * @note This parameter is computed with the STM32CubeMX Tool. + * @rmtoll TIMINGR0 TIMINGR0 LL_I3C_ConfigClockWaveForm + * @param I3Cx I3C Instance. + * @param ClockWaveForm This parameter must be a value between Min_Data=0 and Max_Data=0xFFFFFFFF. + * @retval None + */ +__STATIC_INLINE void LL_I3C_ConfigClockWaveForm(I3C_TypeDef *I3Cx, uint32_t ClockWaveForm) +{ + WRITE_REG(I3Cx->TIMINGR0, ClockWaveForm); +} + +/** + * @brief Get the SCL clock signal waveform. + * @rmtoll TIMINGR0 TIMINGR0 LL_I3C_GetClockWaveForm + * @param I3Cx I3C Instance. + * @retval Value between Min_Data=0 and Max_Data=0xFFFFFFFF. + */ +__STATIC_INLINE uint32_t LL_I3C_GetClockWaveForm(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_REG(I3Cx->TIMINGR0)); +} + +/** + * @brief Configure the SCL clock low period during I3C push-pull phases. + * @note This bit can only be programmed when the I3C is disabled (EN = 0). + * + * @note This parameter is computed with the STM32CubeMX Tool. + * @rmtoll TIMINGR0 SCLL_PP LL_I3C_SetPeriodClockLowPP + * @param I3Cx I3C Instance. + * @param PeriodClockLowPP This parameter must be a value between Min_Data=0 and Max_Data=0xFF. + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetPeriodClockLowPP(I3C_TypeDef *I3Cx, uint32_t PeriodClockLowPP) +{ + MODIFY_REG(I3Cx->TIMINGR0, I3C_TIMINGR0_SCLL_PP, (PeriodClockLowPP << I3C_TIMINGR0_SCLL_PP_Pos)); +} + +/** + * @brief Get the SCL clock low period during I3C push-pull phases. + * @rmtoll TIMINGR0 SCLL_PP LL_I3C_GetPeriodClockLowPP + * @param I3Cx I3C Instance. + * @retval Value between Min_Data=0 and Max_Data=0xFF. + */ +__STATIC_INLINE uint32_t LL_I3C_GetPeriodClockLowPP(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->TIMINGR0, I3C_TIMINGR0_SCLL_PP) >> I3C_TIMINGR0_SCLL_PP_Pos); +} + +/** + * @brief Configure the SCL clock High period during I3C open drain and push-pull phases. + * @note This bit can only be programmed when the I3C is disabled (EN = 0). + * + * @note This parameter is computed with the STM32CubeMX Tool. + * @rmtoll TIMINGR0 SCLH_I3C LL_I3C_SetPeriodClockHighI3C + * @param I3Cx I3C Instance. + * @param PeriodClockHighI3C This parameter must be a value between Min_Data=0 and Max_Data=0xFF. + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetPeriodClockHighI3C(I3C_TypeDef *I3Cx, uint32_t PeriodClockHighI3C) +{ + MODIFY_REG(I3Cx->TIMINGR0, I3C_TIMINGR0_SCLH_I3C, (PeriodClockHighI3C << I3C_TIMINGR0_SCLH_I3C_Pos)); +} + +/** + * @brief Get the SCL clock high period during I3C open drain and push-pull phases. + * @rmtoll TIMINGR0 SCLH_I3C LL_I3C_GetPeriodClockHighI3C + * @param I3Cx I3C Instance. + * @retval Value between Min_Data=0 and Max_Data=0xFF. + */ +__STATIC_INLINE uint32_t LL_I3C_GetPeriodClockHighI3C(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->TIMINGR0, I3C_TIMINGR0_SCLH_I3C) >> I3C_TIMINGR0_SCLH_I3C_Pos); +} + +/** + * @brief Configure the SCL clock low period during I3C open drain phases. + * @note This bit can only be programmed when the I3C is disabled (EN = 0). + * + * @note This parameter is computed with the STM32CubeMX Tool. + * @rmtoll TIMINGR0 SCLL_OD LL_I3C_SetPeriodClockLowOD + * @param I3Cx I3C Instance. + * @param PeriodClockLowOD This parameter must be a value between Min_Data=0 and Max_Data=0xFF. + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetPeriodClockLowOD(I3C_TypeDef *I3Cx, uint32_t PeriodClockLowOD) +{ + MODIFY_REG(I3Cx->TIMINGR0, I3C_TIMINGR0_SCLL_OD, (PeriodClockLowOD << I3C_TIMINGR0_SCLL_OD_Pos)); +} + +/** + * @brief Get the SCL clock low period during I3C open phases. + * @rmtoll TIMINGR0 SCLL_OD LL_I3C_GetPeriodClockLowOD + * @param I3Cx I3C Instance. + * @retval Value between Min_Data=0 and Max_Data=0xFF. + */ +__STATIC_INLINE uint32_t LL_I3C_GetPeriodClockLowOD(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->TIMINGR0, I3C_TIMINGR0_SCLL_OD) >> I3C_TIMINGR0_SCLL_OD_Pos); +} + +/** + * @brief Configure the SCL clock High period during I2C open drain phases. + * @note This bit can only be programmed when the I3C is disabled (EN = 0). + * + * @note This parameter is computed with the STM32CubeMX Tool. + * @rmtoll TIMINGR0 SCLH_I2C LL_I3C_SetPeriodClockHighI2C + * @param I3Cx I3C Instance. + * @param PeriodClockHighI2C This parameter must be a value between Min_Data=0 and Max_Data=0xFF. + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetPeriodClockHighI2C(I3C_TypeDef *I3Cx, uint32_t PeriodClockHighI2C) +{ + MODIFY_REG(I3Cx->TIMINGR0, I3C_TIMINGR0_SCLH_I2C, PeriodClockHighI2C << I3C_TIMINGR0_SCLH_I2C_Pos); +} + +/** + * @brief Get the SCL clock high period during I2C open drain phases. + * @rmtoll TIMINGR0 SCLH_I2C LL_I3C_GetPeriodClockHighI2C + * @param I3Cx I3C Instance. + * @retval Value between Min_Data=0 and Max_Data=0xFF. + */ +__STATIC_INLINE uint32_t LL_I3C_GetPeriodClockHighI2C(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->TIMINGR0, I3C_TIMINGR0_SCLH_I2C) >> I3C_TIMINGR0_SCLH_I2C_Pos); +} + +/** + * @brief Configure the Controller additional hold time on SDA line. + * @rmtoll TIMINGR1 SDA_HD LL_I3C_SetDataHoldTime + * @param I3Cx I3C Instance. + * @param DataHoldTime This parameter can be one of the following values: + * @arg @ref LL_I3C_SDA_HOLD_TIME_0_5 + * @arg @ref LL_I3C_SDA_HOLD_TIME_1_5 + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetDataHoldTime(I3C_TypeDef *I3Cx, uint32_t DataHoldTime) +{ + MODIFY_REG(I3Cx->TIMINGR1, I3C_TIMINGR1_SDA_HD, DataHoldTime); +} + +/** + * @brief Get the Controller additional hold time on SDA line. + * @rmtoll TIMINGR1 SDA_HD LL_I3C_GetDataHoldTime + * @param I3Cx I3C Instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_I3C_SDA_HOLD_TIME_0_5 + * @arg @ref LL_I3C_SDA_HOLD_TIME_1_5 + */ +__STATIC_INLINE uint32_t LL_I3C_GetDataHoldTime(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->TIMINGR1, I3C_TIMINGR1_SDA_HD)); +} + +/** + * @brief Configure the Idle, Available state. + * @note This bit can only be programmed when the I3C is disabled (EN = 0). + * + * @note This parameter is computed with the STM32CubeMX Tool. + * @rmtoll TIMINGR1 AVAL LL_I3C_SetAvalTiming + * @param I3Cx I3C Instance. + * @param AvalTiming This parameter must be a value between Min_Data=0 and Max_Data=0xFF. + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetAvalTiming(I3C_TypeDef *I3Cx, uint32_t AvalTiming) +{ + MODIFY_REG(I3Cx->TIMINGR1, I3C_TIMINGR1_AVAL, (AvalTiming << I3C_TIMINGR1_AVAL_Pos)); +} + +/** + * @brief Get the Idle, Available integer value state. + * @rmtoll TIMINGR1 AVAL LL_I3C_GetAvalTiming + * @param I3Cx I3C Instance. + * @retval Value between Min_Data=0 and Max_Data=0xFF. + */ +__STATIC_INLINE uint32_t LL_I3C_GetAvalTiming(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->TIMINGR1, I3C_TIMINGR1_AVAL) >> I3C_TIMINGR1_AVAL_Pos); +} + +/** + * @brief Configure the Free state. + * @note This bit can only be programmed when the I3C is disabled (EN = 0). + * + * @note This parameter is computed with the STM32CubeMX Tool. + * @rmtoll TIMINGR1 FREE LL_I3C_SetFreeTiming + * @param I3Cx I3C Instance. + * @param FreeTiming This parameter must be a value between Min_Data=0 and Max_Data=0x3F. + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetFreeTiming(I3C_TypeDef *I3Cx, uint32_t FreeTiming) +{ + MODIFY_REG(I3Cx->TIMINGR1, I3C_TIMINGR1_FREE, (FreeTiming << I3C_TIMINGR1_FREE_Pos)); +} + +/** + * @brief Get the Free integeter value state. + * @rmtoll TIMINGR1 FREE LL_I3C_GetFreeTiming + * @param I3Cx I3C Instance. + * @retval Value between Min_Data=0 and Max_Data=0x3F. + */ +__STATIC_INLINE uint32_t LL_I3C_GetFreeTiming(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->TIMINGR1, I3C_TIMINGR1_FREE) >> I3C_TIMINGR1_FREE_Pos); +} + +/** + * @brief Configure the activity state of the new controller. + * @note Refer to MIPI I3C specification (https:__www.mipi.org_specifications) + * for more details related to Activity State. + * @rmtoll TIMINGR1 ASNCR LL_I3C_SetControllerActivityState + * @param I3Cx I3C Instance. + * @param ControllerActivityState This parameter can be one of the following values: + * @arg @ref LL_I3C_OWN_ACTIVITY_STATE_0 + * @arg @ref LL_I3C_OWN_ACTIVITY_STATE_1 + * @arg @ref LL_I3C_OWN_ACTIVITY_STATE_2 + * @arg @ref LL_I3C_OWN_ACTIVITY_STATE_3 + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetControllerActivityState(I3C_TypeDef *I3Cx, uint32_t ControllerActivityState) +{ + MODIFY_REG(I3Cx->TIMINGR1, I3C_TIMINGR1_ASNCR, ControllerActivityState); +} + +/** + * @brief Get the activity state of the new controller. + * @note Refer to MIPI I3C specification (https:__www.mipi.org_specifications) + * for more details related to Activity State. + * @rmtoll TIMINGR1 ASNCR LL_I3C_GetControllerActivityState + * @param I3Cx I3C Instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_I3C_OWN_ACTIVITY_STATE_0 + * @arg @ref LL_I3C_OWN_ACTIVITY_STATE_1 + * @arg @ref LL_I3C_OWN_ACTIVITY_STATE_2 + * @arg @ref LL_I3C_OWN_ACTIVITY_STATE_3 + */ +__STATIC_INLINE uint32_t LL_I3C_GetControllerActivityState(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->TIMINGR1, I3C_TIMINGR1_ASNCR)); +} + +/** + * @brief Configure the Controller SDA Hold time, Bus Free, Activity state, Idle state. + * @note This bit can only be programmed when the I3C is disabled (EN = 0). + * + * @note This parameter is computed with the STM32CubeMX Tool. + * @rmtoll TIMINGR1 SDA_HD LL_I3C_SetCtrlBusCharacteristic\n + * TIMINGR1 FREE LL_I3C_SetCtrlBusCharacteristic\n + * TIMINGR1 ASNCR LL_I3C_SetCtrlBusCharacteristic\n + * TIMINGR1 IDLE LL_I3C_SetCtrlBusCharacteristic + * @param I3Cx I3C Instance. + * @param CtrlBusCharacteristic This parameter must be a value between Min_Data=0 and Max_Data=0x107F03FF. + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetCtrlBusCharacteristic(I3C_TypeDef *I3Cx, uint32_t CtrlBusCharacteristic) +{ + WRITE_REG(I3Cx->TIMINGR1, CtrlBusCharacteristic); +} + +/** + * @brief Get the Controller SDA Hold time, Bus Free, Activity state, Idle state. + * @rmtoll TIMINGR1 SDA_HD LL_I3C_GetCtrlBusCharacteristic\n + * TIMINGR1 FREE LL_I3C_GetCtrlBusCharacteristic\n + * TIMINGR1 ASNCR LL_I3C_GetCtrlBusCharacteristic\n + * TIMINGR1 IDLE LL_I3C_GetCtrlBusCharacteristic + * @param I3Cx I3C Instance. + * @retval Value between Min_Data=0 and Max_Data=0x107F03FF. + */ +__STATIC_INLINE uint32_t LL_I3C_GetCtrlBusCharacteristic(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_REG(I3Cx->TIMINGR1)); +} + +/** + * @brief Configure the Target Available state. + * @note This bit can only be programmed when the I3C is disabled (EN = 0). + * + * @note This parameter is computed with the STM32CubeMX Tool. + * @rmtoll TIMINGR1 IDLE LL_I3C_SetTgtBusCharacteristic + * @param I3Cx I3C Instance. + * @param TgtBusCharacteristic This parameter must be a value between Min_Data=0 and Max_Data=0xFF. + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetTgtBusCharacteristic(I3C_TypeDef *I3Cx, uint32_t TgtBusCharacteristic) +{ + MODIFY_REG(I3Cx->TIMINGR1, I3C_TIMINGR1_AVAL, (TgtBusCharacteristic & I3C_TIMINGR1_AVAL)); +} + +/** + * @brief Get the Target Available state. + * @rmtoll TIMINGR1 IDLE LL_I3C_GetTgtBusCharacteristic + * @param I3Cx I3C Instance. + * @retval Value between Min_Data=0 and Max_Data=0xFF. + */ +__STATIC_INLINE uint32_t LL_I3C_GetTgtBusCharacteristic(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->TIMINGR1, I3C_TIMINGR1_AVAL)); +} + +/** + * @brief Configure the SCL clock stalling time on I3C Bus (controller mode). + * @note This bit can only be programmed when the I3C is disabled (EN = 0). + * + * @note This parameter is computed with the STM32CubeMX Tool. + * @rmtoll TIMINGR2 STALL LL_I3C_SetStallTime + * @param I3Cx I3C Instance. + * @param ControllerStallTime This parameter must be a value between Min_Data=0 and Max_Data=0xFF. + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetStallTime(I3C_TypeDef *I3Cx, uint32_t ControllerStallTime) +{ + MODIFY_REG(I3Cx->TIMINGR2, I3C_TIMINGR2_STALL, (ControllerStallTime << I3C_TIMINGR2_STALL_Pos)); +} + +/** + * @brief Get the SCL clock stalling time on I3C Bus (controller mode). + * @rmtoll TIMINGR2 STALL LL_I3C_GetStallTime + * @param I3Cx I3C Instance. + * @retval Value between Min_Data=0 and Max_Data=0xFF. + */ +__STATIC_INLINE uint32_t LL_I3C_GetStallTime(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->TIMINGR2, I3C_TIMINGR2_STALL)); +} + +/** + * @brief Set stall on ACK bit (controller mode). + * @note This bit can be programmed when the I3C is disabled (EN = 0). + * @rmtoll TIMINGR2 STALLA LL_I3C_EnableStallACK + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableStallACK(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->TIMINGR2, I3C_TIMINGR2_STALLA); +} + +/** + * @brief Disable stall on ACK bit (controller mode). + * @note This bit can be programmed when the I3C is disabled (EN = 0). + * @rmtoll TIMINGR2 STALLA LL_I3C_DisableStallACK + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableStallACK(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->TIMINGR2, I3C_TIMINGR2_STALLA); +} + +/** + * @brief Check if stall on ACK bit is enabled or disabled (controller mode). + * @rmtoll TIMINGR2 STALLA LL_I3C_IsEnabledStallACK + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledStallACK(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->TIMINGR2, I3C_TIMINGR2_STALLA) == (I3C_TIMINGR2_STALLA)) ? 1UL : 0UL); +} + +/** + * @brief Set stall on Parity bit of Command Code byte (controller mode). + * @note This bit can be programmed when the I3C is disabled (EN = 0). + * @rmtoll TIMINGR2 STALLC LL_I3C_EnableStallParityCCC + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableStallParityCCC(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->TIMINGR2, I3C_TIMINGR2_STALLC); +} + +/** + * @brief Disable stall on Parity bit of Command Code byte (controller mode). + * @note This bit can be programmed when the I3C is disabled (EN = 0). + * @rmtoll TIMINGR2 STALLC LL_I3C_DisableStallParityCCC + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableStallParityCCC(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->TIMINGR2, I3C_TIMINGR2_STALLC); +} + +/** + * @brief Check if stall on Parity bit of Command Code byte is enabled or disabled (controller mode). + * @rmtoll TIMINGR2 STALLC LL_I3C_IsEnabledStallParityCCC + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledStallParityCCC(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->TIMINGR2, I3C_TIMINGR2_STALLC) == (I3C_TIMINGR2_STALLC)) ? 1UL : 0UL); +} + +/** + * @brief Set stall on Parity bit of Data bytes (controller mode). + * @note This bit can be programmed when the I3C is disabled (EN = 0). + * @rmtoll TIMINGR2 STALLD LL_I3C_EnableStallParityData + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableStallParityData(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->TIMINGR2, I3C_TIMINGR2_STALLD); +} + +/** + * @brief Disable stall on Parity bit of Data bytes (controller mode). + * @note This bit can be programmed when the I3C is disabled (EN = 0). + * @rmtoll TIMINGR2 STALLD LL_I3C_DisableStallParityData + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableStallParityData(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->TIMINGR2, I3C_TIMINGR2_STALLD); +} + +/** + * @brief Check if stall on Parity bit of Data bytes is enabled or disabled (controller mode). + * @rmtoll TIMINGR2 STALLD LL_I3C_IsEnabledStallParityData + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledStallParityData(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->TIMINGR2, I3C_TIMINGR2_STALLD) == (I3C_TIMINGR2_STALLD)) ? 1UL : 0UL); +} + +/** + * @brief Set stall on T bit (controller mode). + * @note This bit can be programmed when the I3C is disabled (EN = 0). + * @rmtoll TIMINGR2 STALLT LL_I3C_EnableStallTbit + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableStallTbit(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->TIMINGR2, I3C_TIMINGR2_STALLT); +} + +/** + * @brief Disable stall on T bit (controller mode). + * @note This bit can be programmed when the I3C is disabled (EN = 0). + * @rmtoll TIMINGR2 STALLT LL_I3C_DisableStallTbit + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableStallTbit(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->TIMINGR2, I3C_TIMINGR2_STALLT); +} + +/** + * @brief Check if stall on T bit is enabled or disabled (controller mode). + * @rmtoll TIMINGR2 STALLT LL_I3C_IsEnabledStallTbit + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledStallTbit(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->TIMINGR2, I3C_TIMINGR2_STALLT) == (I3C_TIMINGR2_STALLT)) ? 1UL : 0UL); +} + +/** + * @brief Configure the Device Capability on Bus as Target or Controller (MIPI Bus Characteristics Register BCR6). + * @note Those bits can be programmed when the I3C is disabled (EN = 0). + * @rmtoll BCR BCR6 LL_I3C_SetDeviceCapabilityOnBus + * @param I3Cx I3C Instance. + * @param DeviceCapabilityOnBus This parameter can be one of the following values: + * @arg @ref LL_I3C_DEVICE_ROLE_AS_TARGET + * @arg @ref LL_I3C_DEVICE_ROLE_AS_CONTROLLER + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetDeviceCapabilityOnBus(I3C_TypeDef *I3Cx, uint32_t DeviceCapabilityOnBus) +{ + MODIFY_REG(I3Cx->BCR, I3C_BCR_BCR6, DeviceCapabilityOnBus); +} + +/** + * @brief Get the Device Capability on Bus as Target or Controller (MIPI Bus Characteristics Register BCR6). + * @rmtoll BCR BCR6 LL_I3C_GetDeviceCapabilityOnBus + * @param I3Cx I3C Instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_I3C_DEVICE_ROLE_AS_TARGET + * @arg @ref LL_I3C_DEVICE_ROLE_AS_CONTROLLER + */ +__STATIC_INLINE uint32_t LL_I3C_GetDeviceCapabilityOnBus(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->BCR, I3C_BCR_BCR6)); +} + +/** + * @brief Configure the Device IBI Payload (MIPI Bus Characteristics Register BCR2). + * @note Those bits can be programmed when the I3C is disabled (EN = 0). + * @rmtoll BCR BCR2 LL_I3C_SetDeviceIBIPayload + * @param I3Cx I3C Instance. + * @param DeviceIBIPayload This parameter can be one of the following values: + * @arg @ref LL_I3C_IBI_NO_ADDITIONAL_DATA + * @arg @ref LL_I3C_IBI_ADDITIONAL_DATA + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetDeviceIBIPayload(I3C_TypeDef *I3Cx, uint32_t DeviceIBIPayload) +{ + MODIFY_REG(I3Cx->BCR, I3C_BCR_BCR2, DeviceIBIPayload); +} + +/** + * @brief Get the Device IBI Payload (MIPI Bus Characteristics Register BCR2). + * @rmtoll BCR BCR2 LL_I3C_GetDeviceIBIPayload + * @param I3Cx I3C Instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_I3C_IBI_NO_ADDITIONAL_DATA + * @arg @ref LL_I3C_IBI_ADDITIONAL_DATA + */ +__STATIC_INLINE uint32_t LL_I3C_GetDeviceIBIPayload(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->BCR, I3C_BCR_BCR2)); +} + +/** + * @brief Configure the Data Speed Limitation (limitation, as described by I3C_GETMXDSR). + * @note Those bits can be programmed when the I3C is disabled (EN = 0). + * @rmtoll BCR BCR0 LL_I3C_SetDataSpeedLimitation + * @param I3Cx I3C Instance. + * @param DataSpeedLimitation This parameter can be one of the following values: + * @arg @ref LL_I3C_NO_DATA_SPEED_LIMITATION + * @arg @ref LL_I3C_MAX_DATA_SPEED_LIMITATION + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetDataSpeedLimitation(I3C_TypeDef *I3Cx, uint32_t DataSpeedLimitation) +{ + MODIFY_REG(I3Cx->BCR, I3C_BCR_BCR0, DataSpeedLimitation); +} + +/** + * @brief Get the Data Speed Limitation (limitation, as described by I3C_GETMXDSR). + * @rmtoll BCR BCR0 LL_I3C_GetDataSpeedLimitation + * @param I3Cx I3C Instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_I3C_NO_DATA_SPEED_LIMITATION + * @arg @ref LL_I3C_MAX_DATA_SPEED_LIMITATION + */ +__STATIC_INLINE uint32_t LL_I3C_GetDataSpeedLimitation(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->BCR, I3C_BCR_BCR0)); +} + +/** + * @brief Configure the Device Characteristics Register (DCR). + * @note This bit can only be programmed when the I3C is disabled (EN = 0). + * + * @note Refer MIPI web site for the list of device code available. + * @rmtoll DCR DC LL_I3C_SetDeviceCharacteristics + * @param I3Cx I3C Instance. + * @param DeviceCharacteristics This parameter must be a value between Min_Data=0 and Max_Data=0xFF. + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetDeviceCharacteristics(I3C_TypeDef *I3Cx, uint32_t DeviceCharacteristics) +{ + MODIFY_REG(I3Cx->DCR, I3C_DCR_DCR, DeviceCharacteristics); +} + +/** + * @brief Get the Device Characteristics Register (DCR). + * @note Refer MIPI web site to associated value with the list of device code available. + * @rmtoll DCR DCR LL_I3C_GetDeviceCharacteristics + * @param I3Cx I3C Instance. + * @retval Value between Min_Data=0 and Max_Data=0xFF. + */ +__STATIC_INLINE uint32_t LL_I3C_GetDeviceCharacteristics(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->DCR, I3C_DCR_DCR)); +} + +/** + * @brief Configure IBI MDB support for pending read notification. + * @note Those bits can be programmed when the I3C is disabled (EN = 0). + * @rmtoll GETCAPR CAPPEND LL_I3C_SetPendingReadMDB + * @param I3Cx I3C Instance. + * @param PendingReadMDB This parameter can be one of the following values: + * @arg @ref LL_I3C_MDB_NO_PENDING_READ_NOTIFICATION + * @arg @ref LL_I3C_MDB_PENDING_READ_NOTIFICATION + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetPendingReadMDB(I3C_TypeDef *I3Cx, uint32_t PendingReadMDB) +{ + MODIFY_REG(I3Cx->GETCAPR, I3C_GETCAPR_CAPPEND, PendingReadMDB); +} + +/** + * @brief Get IBI MDB support for pending read notification value. + * @rmtoll GETCAPR CAPPEND LL_I3C_GetPendingReadMDB + * @param I3Cx I3C Instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_I3C_MDB_NO_PENDING_READ_NOTIFICATION + * @arg @ref LL_I3C_MDB_PENDING_READ_NOTIFICATION + */ +__STATIC_INLINE uint32_t LL_I3C_GetPendingReadMDB(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->GETCAPR, I3C_GETCAPR_CAPPEND)); +} + +/** + * @brief Configure the Group Management Support bit of MSTCAP1. + * @note Those bits can be programmed when the I3C is disabled (EN = 0). + * @rmtoll CRCAPR CAPGRP LL_I3C_SetGrpAddrHandoffSupport + * @param I3Cx I3C Instance. + * @param GrpAddrHandoffSupport This parameter can be one of the following values: + * @arg @ref LL_I3C_HANDOFF_GRP_ADDR_NOT_SUPPORTED + * @arg @ref LL_I3C_HANDOFF_GRP_ADDR_SUPPORTED + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetGrpAddrHandoffSupport(I3C_TypeDef *I3Cx, uint32_t GrpAddrHandoffSupport) +{ + MODIFY_REG(I3Cx->CRCAPR, I3C_CRCAPR_CAPGRP, GrpAddrHandoffSupport); +} + +/** + * @brief Get the Group Management Support bit of MSTCAP1. + * @rmtoll CRCAPR CAPGRP LL_I3C_GetGrpAddrHandoffSupport + * @param I3Cx I3C Instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_I3C_HANDOFF_GRP_ADDR_NOT_SUPPORTED + * @arg @ref LL_I3C_HANDOFF_GRP_ADDR_SUPPORTED + */ +__STATIC_INLINE uint32_t LL_I3C_GetGrpAddrHandoffSupport(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->CRCAPR, I3C_CRCAPR_CAPGRP)); +} + +/** + * @brief Configure the Delayed Controller Handoff bit in MSTCAP2. + * @note Those bits can be programmed when the I3C is disabled (EN = 0). + * @rmtoll CRCAPR CAPDHOFF LL_I3C_SetControllerHandoffDelayed + * @param I3Cx I3C Instance. + * @param ControllerHandoffDelayed This parameter can be one of the following values: + * @arg @ref LL_I3C_HANDOFF_NOT_DELAYED + * @arg @ref LL_I3C_HANDOFF_DELAYED + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetControllerHandoffDelayed(I3C_TypeDef *I3Cx, uint32_t ControllerHandoffDelayed) +{ + MODIFY_REG(I3Cx->CRCAPR, I3C_CRCAPR_CAPDHOFF, ControllerHandoffDelayed); +} + +/** + * @brief Get the Delayed Controller Handoff bit in MSTCAP2. + * @rmtoll CRCAPR CAPDHOFF LL_I3C_GetControllerHandoffDelayed + * @param I3Cx I3C Instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_I3C_HANDOFF_NOT_DELAYED + * @arg @ref LL_I3C_HANDOFF_DELAYED + */ +__STATIC_INLINE uint32_t LL_I3C_GetControllerHandoffDelayed(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->CRCAPR, I3C_CRCAPR_CAPDHOFF)); +} + +/** + * @brief Configure the Activity State after controllership handoff. + * @note Those bits can be programmed when the I3C is disabled (EN = 0). + * @rmtoll GETMXDSR HOFFAS LL_I3C_SetHandoffActivityState + * @param I3Cx I3C Instance. + * @param HandoffActivityState This parameter can be one of the following values: + * @arg @ref LL_I3C_HANDOFF_ACTIVITY_STATE_0 + * @arg @ref LL_I3C_HANDOFF_ACTIVITY_STATE_1 + * @arg @ref LL_I3C_HANDOFF_ACTIVITY_STATE_2 + * @arg @ref LL_I3C_HANDOFF_ACTIVITY_STATE_3 + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetHandoffActivityState(I3C_TypeDef *I3Cx, uint32_t HandoffActivityState) +{ + MODIFY_REG(I3Cx->GETMXDSR, I3C_GETMXDSR_HOFFAS, HandoffActivityState); +} + +/** + * @brief Get the Activity State after controllership handoff. + * @rmtoll GETMXDSR HOFFAS LL_I3C_GetHandoffActivityState + * @param I3Cx I3C Instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_I3C_HANDOFF_ACTIVITY_STATE_0 + * @arg @ref LL_I3C_HANDOFF_ACTIVITY_STATE_1 + * @arg @ref LL_I3C_HANDOFF_ACTIVITY_STATE_2 + * @arg @ref LL_I3C_HANDOFF_ACTIVITY_STATE_3 + */ +__STATIC_INLINE uint32_t LL_I3C_GetHandoffActivityState(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->GETMXDSR, I3C_GETMXDSR_HOFFAS)); +} + +/** + * @brief Configure the Max Data Speed Format response for GETMXDS CCC. + * @note Those bits can be programmed when the I3C is disabled (EN = 0). + * @rmtoll GETMXDSR FMT LL_I3C_SetMaxDataSpeedFormat + * @param I3Cx I3C Instance. + * @param MaxDataSpeedFormat This parameter can be one of the following values: + * @arg @ref LL_I3C_GETMXDS_FORMAT_1 + * @arg @ref LL_I3C_GETMXDS_FORMAT_2_LSB + * @arg @ref LL_I3C_GETMXDS_FORMAT_2_MID + * @arg @ref LL_I3C_GETMXDS_FORMAT_2_MSB + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetMaxDataSpeedFormat(I3C_TypeDef *I3Cx, uint32_t MaxDataSpeedFormat) +{ + MODIFY_REG(I3Cx->GETMXDSR, I3C_GETMXDSR_FMT, MaxDataSpeedFormat); +} + +/** + * @brief Get the Max Data Speed Format response for GETMXDS CCC. + * @rmtoll GETMXDSR FMT LL_I3C_GetMaxDataSpeedFormat + * @param I3Cx I3C Instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_I3C_GETMXDS_FORMAT_1 + * @arg @ref LL_I3C_GETMXDS_FORMAT_2_LSB + * @arg @ref LL_I3C_GETMXDS_FORMAT_2_MID + * @arg @ref LL_I3C_GETMXDS_FORMAT_2_MSB + */ +__STATIC_INLINE uint32_t LL_I3C_GetMaxDataSpeedFormat(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->GETMXDSR, I3C_GETMXDSR_FMT)); +} + +/** + * @brief Configure the Middle byte of MaxRdTurn field of GETMXDS CCC Format 2 with turnaround. + * @note Those bits can be programmed when the I3C is disabled (EN = 0). + * @rmtoll GETMXDSR RDTURN LL_I3C_SetMiddleByteTurnAround + * @param I3Cx I3C Instance. + * @param MiddleByteTurnAround This parameter must be a value between Min_Data=0 and Max_Data=0xF. + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetMiddleByteTurnAround(I3C_TypeDef *I3Cx, uint32_t MiddleByteTurnAround) +{ + MODIFY_REG(I3Cx->GETMXDSR, I3C_GETMXDSR_RDTURN, (MiddleByteTurnAround << I3C_GETMXDSR_RDTURN_Pos)); +} + +/** + * @brief Get the value of Middle byte of MaxRdTurn field of GETMXDS CCC Format 2 with turnaround. + * @rmtoll GETMXDSR RDTURN LL_I3C_GetMiddleByteTurnAround + * @param I3Cx I3C Instance. + * @retval Value between Min_Data=0 and Max_Data=0xF. + */ +__STATIC_INLINE uint32_t LL_I3C_GetMiddleByteTurnAround(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->GETMXDSR, I3C_GETMXDSR_RDTURN)); +} + +/** + * @brief Configure clock-to-data turnaround time. + * @note Those bits can be programmed when the I3C is disabled (EN = 0). + * @rmtoll GETMXDSR TSCO LL_I3C_SetDataTurnAroundTime + * @param I3Cx I3C Instance. + * @param DataTurnAroundTime This parameter can be one of the following values: + * @arg @ref LL_I3C_TURNAROUND_TIME_TSCO_LESS_12NS + * @arg @ref LL_I3C_TURNAROUND_TIME_TSCO_GREATER_12NS + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetDataTurnAroundTime(I3C_TypeDef *I3Cx, uint32_t DataTurnAroundTime) +{ + MODIFY_REG(I3Cx->GETMXDSR, I3C_GETMXDSR_TSCO, DataTurnAroundTime); +} + +/** + * @brief Get clock-to-data turnaround time. + * @rmtoll GETMXDSR TSCO LL_I3C_GetDataTurnAroundTime + * @param I3Cx I3C Instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_I3C_TURNAROUND_TIME_TSCO_LESS_12NS + * @arg @ref LL_I3C_TURNAROUND_TIME_TSCO_GREATER_12NS + */ +__STATIC_INLINE uint32_t LL_I3C_GetDataTurnAroundTime(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->GETMXDSR, I3C_GETMXDSR_TSCO)); +} + +/** + * @brief Configure the MIPI Instance ID. + * @note Those bits can be programmed when the I3C is disabled (EN = 0). + * @rmtoll EPIDR MIPIID LL_I3C_SetMIPIInstanceID + * @param I3Cx I3C Instance. + * @param MIPIInstanceID This parameter must be a value between Min_Data=0 and Max_Data=0xF. + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetMIPIInstanceID(I3C_TypeDef *I3Cx, uint32_t MIPIInstanceID) +{ + MODIFY_REG(I3Cx->EPIDR, I3C_EPIDR_MIPIID, (MIPIInstanceID << I3C_EPIDR_MIPIID_Pos)); +} + +/** + * @brief Get the MIPI Instance ID. + * @rmtoll EPIDR MIPIID LL_I3C_GetMIPIInstanceID + * @param I3Cx I3C Instance. + * @retval Value between Min_Data=0 and Max_Data=0xF. + */ +__STATIC_INLINE uint32_t LL_I3C_GetMIPIInstanceID(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->EPIDR, I3C_EPIDR_MIPIID) >> I3C_EPIDR_MIPIID_Pos); +} + +/** + * @brief Get the ID type selector. + * @rmtoll EPIDR IDTSEL LL_I3C_GetIDTypeSelector + * @param I3Cx I3C Instance. + * @retval Value between Min_Data=0x0 and Max_Data=0x1 + */ +__STATIC_INLINE uint32_t LL_I3C_GetIDTypeSelector(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->EPIDR, I3C_EPIDR_IDTSEL) >> I3C_EPIDR_IDTSEL_Pos); +} + +/** + * @brief Get the MIPI Manufacturer ID. + * @rmtoll EPIDR MIPIMID LL_I3C_GetMIPIManufacturerID + * @param I3Cx I3C Instance. + * @retval Value between Min_Data=0 and Max_Data=0x7FFF. + */ +__STATIC_INLINE uint32_t LL_I3C_GetMIPIManufacturerID(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->EPIDR, I3C_EPIDR_MIPIMID) >> I3C_EPIDR_MIPIMID_Pos); +} + +/** + * @} + */ + +/** @defgroup I3C_LL_EF_Data Management + * @{ + */ + +/** + * @brief Request a reception Data FIFO Flush. + * @rmtoll CFGR RXFLUSH LL_I3C_RequestRxFIFOFlush + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_RequestRxFIFOFlush(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->CFGR, I3C_CFGR_RXFLUSH); +} + +/** + * @brief Request a transmission Data FIFO Flush. + * @rmtoll CFGR TXFLUSH LL_I3C_RequestTxFIFOFlush + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_RequestTxFIFOFlush(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->CFGR, I3C_CFGR_TXFLUSH); +} + +/** + * @brief Request a Status Data FIFO Flush. + * @rmtoll CFGR SFLUSH LL_I3C_RequestStatusFIFOFlush + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_RequestStatusFIFOFlush(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->CFGR, I3C_CFGR_SFLUSH); +} + +/** + * @brief Get Activity state of Controller on the I3C Bus (Target only). + * @rmtoll DEVR0 AS LL_I3C_GetActivityState + * @param I3Cx I3C Instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_I3C_BUS_ACTIVITY_STATE_0 + * @arg @ref LL_I3C_BUS_ACTIVITY_STATE_1 + * @arg @ref LL_I3C_BUS_ACTIVITY_STATE_2 + * @arg @ref LL_I3C_BUS_ACTIVITY_STATE_3 + */ +__STATIC_INLINE uint32_t LL_I3C_GetActivityState(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->DEVR0, I3C_DEVR0_AS)); +} + +/** + * @brief Get Reset Action (Target only). + * @rmtoll DEVR0 RSTACT LL_I3C_GetResetAction + * @param I3Cx I3C Instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_I3C_RESET_ACTION_NONE + * @arg @ref LL_I3C_RESET_ACTION_PARTIAL + * @arg @ref LL_I3C_RESET_ACTION_FULL + */ +__STATIC_INLINE uint32_t LL_I3C_GetResetAction(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->DEVR0, I3C_DEVR0_RSTACT)); +} + +/** + * @brief Request a Control word FIFO Flush. + * @rmtoll CFGR CFLUSH LL_I3C_RequestControlFIFOFlush + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_RequestControlFIFOFlush(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->CFGR, I3C_CFGR_CFLUSH); +} + +/** + * @brief Request a Transfer start. + * @note After request, the current instruction in Control Register is executed on I3C Bus. + * @rmtoll CFGR TSFSET LL_I3C_RequestTransfer + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_RequestTransfer(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->CFGR, I3C_CFGR_TSFSET); +} + +/** + * @brief Handles I3C Message content on the I3C Bus as Controller. + * @rmtoll CR ADD LL_I3C_ControllerHandleMessage\n + * CR DCNT LL_I3C_ControllerHandleMessage\n + * CR RNW LL_I3C_ControllerHandleMessage\n + * CR MTYPE LL_I3C_ControllerHandleMessage\n + * CR MEND LL_I3C_ControllerHandleMessage + * @param I3Cx I3C Instance. + * @param TargetAddr Specifies the target address to be programmed. + * This parameter must be a value between Min_Data=0 and Max_Data=0xFF. + * @param TransferSize Specifies the number of bytes to be programmed. + * This parameter must be a value between Min_Data=0 and Max_Data=65535. + * @param Direction This parameter can be one of the following values: + * @arg @ref LL_I3C_DIRECTION_WRITE + * @arg @ref LL_I3C_DIRECTION_READ + * @param MessageType This parameter can be one of the following values: + * @arg @ref LL_I3C_CONTROLLER_MTYPE_RELEASE + * @arg @ref LL_I3C_CONTROLLER_MTYPE_HEADER + * @arg @ref LL_I3C_CONTROLLER_MTYPE_PRIVATE + * @arg @ref LL_I3C_CONTROLLER_MTYPE_DIRECT + * @arg @ref LL_I3C_CONTROLLER_MTYPE_LEGACY_I2C + * @param EndMode This parameter can be one of the following values: + * @arg @ref LL_I3C_GENERATE_STOP + * @arg @ref LL_I3C_GENERATE_RESTART + * @retval None + */ +__STATIC_INLINE void LL_I3C_ControllerHandleMessage(I3C_TypeDef *I3Cx, uint32_t TargetAddr, uint32_t TransferSize, + uint32_t Direction, uint32_t MessageType, uint32_t EndMode) +{ + WRITE_REG(I3Cx->CR, ((TargetAddr << I3C_CR_ADD_Pos) | TransferSize | Direction | MessageType | EndMode) \ + & (I3C_CR_ADD | I3C_CR_DCNT | I3C_CR_RNW | I3C_CR_MTYPE | I3C_CR_MEND)); +} + +/** + * @brief Handles I3C Common Command Code content on the I3C Bus as Controller. + * @rmtoll CR CCC LL_I3C_ControllerHandleCCC\n + * CR DCNT LL_I3C_ControllerHandleCCC\n + * CR MTYPE LL_I3C_ControllerHandleCCC\n + * CR MEND LL_I3C_ControllerHandleCCC + * @param I3Cx I3C Instance. + * @param CCCValue Specifies the Command Code to be programmed. + * This parameter must be a value between Min_Data=0 and Max_Data=0x1FF. + * @param AddByteSize Specifies the number of CCC additional bytes to be programmed. + * This parameter must be a value between Min_Data=0 and Max_Data=65535. + * @param EndMode This parameter can be one of the following values: + * @arg @ref LL_I3C_GENERATE_STOP + * @arg @ref LL_I3C_GENERATE_RESTART + * @retval None + */ +__STATIC_INLINE void LL_I3C_ControllerHandleCCC(I3C_TypeDef *I3Cx, uint32_t CCCValue, + uint32_t AddByteSize, uint32_t EndMode) +{ + WRITE_REG(I3Cx->CR, ((CCCValue << I3C_CR_CCC_Pos) | AddByteSize | EndMode | LL_I3C_CONTROLLER_MTYPE_CCC) \ + & (I3C_CR_CCC | I3C_CR_DCNT | I3C_CR_MTYPE | I3C_CR_MEND)); +} + +/** + * @brief Handles I3C Message content on the I3C Bus as Target. + * @rmtoll CR MTYPE LL_I3C_TargetHandleMessage\n + * CR DCNT LL_I3C_TargetHandleMessage + * @param I3Cx I3C Instance. + * @param MessageType This parameter can be one of the following values: + * @arg @ref LL_I3C_TARGET_MTYPE_HOT_JOIN + * @arg @ref LL_I3C_TARGET_MTYPE_CONTROLLER_ROLE_REQ + * @arg @ref LL_I3C_TARGET_MTYPE_IBI + * @param IBISize Specifies the number of IBI bytes. + * This parameter must be a value between Min_Data=0 and Max_Data=65535. + * @retval None + */ +__STATIC_INLINE void LL_I3C_TargetHandleMessage(I3C_TypeDef *I3Cx, uint32_t MessageType, uint32_t IBISize) +{ + WRITE_REG(I3Cx->CR, (MessageType | IBISize) & (I3C_CR_DCNT | I3C_CR_MTYPE)); +} + +/** + * @} + */ + +/** @defgroup I3C_LL_EF_Data_Management Data_Management + * @{ + */ + +/** + * @brief Read Receive Data Byte register. + * @rmtoll RDR RDB0 LL_I3C_ReceiveData8 + * @param I3Cx I3C Instance. + * @retval Value between Min_Data=0 to Max_Data=0xFF + */ +__STATIC_INLINE uint8_t LL_I3C_ReceiveData8(const I3C_TypeDef *I3Cx) +{ + return (uint8_t)(READ_BIT(I3Cx->RDR, I3C_RDR_RDB0)); +} + +/** + * @brief Write in Transmit Data Byte Register. + * @rmtoll TDR TDB0 LL_I3C_TransmitData8 + * @param I3Cx I3C Instance. + * @param Data This parameter must be a value between Min_Data=0 and Max_Data=0xFF. + * @retval None + */ +__STATIC_INLINE void LL_I3C_TransmitData8(I3C_TypeDef *I3Cx, uint8_t Data) +{ + WRITE_REG(I3Cx->TDR, Data); +} + +/** + * @brief Read Receive Data Word register. + * @note Content of register is filled in Little Endian. + * Mean MSB correspond to last data byte received, + * LSB correspond to first data byte received. + * @rmtoll RDWR RDWR LL_I3C_ReceiveData32 + * @param I3Cx I3C Instance. + * @retval Value between Min_Data=0 to Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_I3C_ReceiveData32(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_REG(I3Cx->RDWR)); +} + +/** + * @brief Write in Transmit Data Word Register. + * @note Content of register is filled in Little Endian. + * Mean MSB correspond to last data byte transmitted, + * LSB correspond to first data byte transmitted. + * @rmtoll TDWR TDWR LL_I3C_TransmitData32 + * @param I3Cx I3C Instance. + * @param Data This parameter must be a value between Min_Data=0 and Max_Data=0xFFFFFFFF. + * @retval None + */ +__STATIC_INLINE void LL_I3C_TransmitData32(I3C_TypeDef *I3Cx, uint32_t Data) +{ + WRITE_REG(I3Cx->TDWR, Data); +} + +/** + * @brief Configure the IBI data payload to be sent during IBI (target mode). + * @note Content of register is filled in Little Endian. + * Mean MSB correspond to last IBI data byte, + * LSB correspond to first IBI data byte. + * @rmtoll IBIDR IBIDR LL_I3C_SetIBIPayload + * @param I3Cx I3C Instance. + * @param OwnIBIPayload This parameter must be a value between Min_Data=0 and Max_Data=0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetIBIPayload(I3C_TypeDef *I3Cx, uint32_t OwnIBIPayload) +{ + WRITE_REG(I3Cx->IBIDR, OwnIBIPayload); +} + +/** + * @brief Get the own IBI data payload (target mode), or get the Target IBI received (controller mode). + * @note Content of register is filled in Little Endian. + * Mean MSB correspond to last IBI data byte, + * LSB correspond to first IBI data byte. + * @rmtoll IBIDR IBIDR LL_I3C_GetIBIPayload + * @param I3Cx I3C Instance. + * @retval Value between Min_Data=0 to Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_I3C_GetIBIPayload(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_REG(I3Cx->IBIDR)); +} + +/** + * @brief Get the number of data bytes received when reading IBI data (controller mode). + * @rmtoll RMR IBIRDCNT LL_I3C_GetNbIBIAddData + * @param I3Cx I3C Instance. + * @retval Value between Min_Data=0 to Max_Data=0x7 + */ +__STATIC_INLINE uint32_t LL_I3C_GetNbIBIAddData(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->RMR, I3C_RMR_IBIRDCNT)); +} + +/** + * @brief Get the target address received during accepted IBI or Controller-role request. + * @rmtoll RMR RADD LL_I3C_GetIBITargetAddr + * @param I3Cx I3C Instance. + * @retval Value between Min_Data=0 to Max_Data=0x3F + */ +__STATIC_INLINE uint32_t LL_I3C_GetIBITargetAddr(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->RMR, I3C_RMR_RADD) >> I3C_RMR_RADD_Pos); +} + +/** + * @brief Set TX FIFO Preload (target mode). + * @note Set high by Software, cleared by hardware when all the bytes to transmit have been loaded to TX FIFO. + * @rmtoll TGTTDR PRELOAD LL_I3C_ConfigTxPreload + * @rmtoll TGTTDR TDCNT LL_I3C_ConfigTxPreload + * @param I3Cx I3C Instance. + * @param TxDataCount This parameter must be a value between Min_Data=0 and Max_Data=0xFFFF + * @retval None + */ +__STATIC_INLINE void LL_I3C_ConfigTxPreload(I3C_TypeDef *I3Cx, uint16_t TxDataCount) +{ + MODIFY_REG(I3Cx->TGTTDR, (I3C_TGTTDR_PRELOAD | I3C_TGTTDR_TGTTDCNT), (I3C_TGTTDR_PRELOAD | TxDataCount)); +} + +/** + * @brief Indicates the status of TX FIFO preload (target mode). + * RESET: No preload of TX FIFO. + * SET: Preload of TX FIFO ongoing. + * @note Set high by Software, cleared by hardware when all the bytes to transmit have been loaded to TX FIFO. + * @rmtoll TGTTDR PRELOAD LL_I3C_IsActiveTxPreload + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveTxPreload(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->TGTTDR, I3C_TGTTDR_PRELOAD) == (I3C_TGTTDR_PRELOAD)) ? 1UL : 0UL); +} + +/** + * @brief Get the number of bytes to transmit (target mode). + * @note The return value correspond to the remaining number of bytes to load in TX FIFO. + * @rmtoll TGTTDR TDCNT LL_I3C_GetTxPreloadDataCount + * @param I3Cx I3C Instance. + * @retval Value between Min_Data=0 to Max_Data=0xFFFF + */ +__STATIC_INLINE uint16_t LL_I3C_GetTxPreloadDataCount(const I3C_TypeDef *I3Cx) +{ + return (uint16_t)(READ_BIT(I3Cx->TGTTDR, I3C_TGTTDR_TGTTDCNT)); +} + +/** + * @brief Get the number of data during a Transfer. + * @note The return value correspond to number of transmitted bytes reported + * during Address Assignment process in Target mode. + * The return value correspond to number of target detected + * during Address Assignment process in Controller mode. + * The return value correspond to number of data bytes read from or sent to the I3C bus + * during the message link to MID current value. + * @rmtoll SR XDCNT LL_I3C_GetXferDataCount + * @param I3Cx I3C Instance. + * @retval Value between Min_Data=0 to Max_Data=0xFFFF + */ +__STATIC_INLINE uint32_t LL_I3C_GetXferDataCount(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->SR, I3C_SR_XDCNT)); +} + +/** + * @brief Indicates if a Target abort a private read command. + * @rmtoll SR ABT LL_I3C_IsTargetAbortPrivateRead + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsTargetAbortPrivateRead(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->SR, I3C_SR_ABT) == (I3C_SR_ABT)) ? 1UL : 0UL); +} + +/** + * @brief Get Direction of the Message. + * @rmtoll SR DIR LL_I3C_GetMessageDirection + * @param I3Cx I3C Instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_I3C_MESSAGE_DIRECTION_WRITE + * @arg @ref LL_I3C_MESSAGE_DIRECTION_READ + */ +__STATIC_INLINE uint32_t LL_I3C_GetMessageDirection(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->SR, I3C_SR_DIR)); +} + +/** + * @brief Get Message identifier. + * @rmtoll SR MID LL_I3C_GetMessageIdentifier + * @param I3Cx I3C Instance. + * @retval Value between Min_Data=0 to Max_Data=0xFF, representing the internal hardware counter value. + */ +__STATIC_INLINE uint32_t LL_I3C_GetMessageIdentifier(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->SR, I3C_SR_MID)); +} + +/** + * @brief Get Message error code. + * @rmtoll SER CODERR LL_I3C_GetMessageErrorCode + * @param I3Cx I3C Instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_I3C_CONTROLLER_ERROR_CE0 + * @arg @ref LL_I3C_CONTROLLER_ERROR_CE1 + * @arg @ref LL_I3C_CONTROLLER_ERROR_CE2 + * @arg @ref LL_I3C_CONTROLLER_ERROR_CE3 + * @arg @ref LL_I3C_TARGET_ERROR_TE0 + * @arg @ref LL_I3C_TARGET_ERROR_TE1 + * @arg @ref LL_I3C_TARGET_ERROR_TE2 + * @arg @ref LL_I3C_TARGET_ERROR_TE3 + * @arg @ref LL_I3C_TARGET_ERROR_TE4 + * @arg @ref LL_I3C_TARGET_ERROR_TE5 + * @arg @ref LL_I3C_TARGET_ERROR_TE6 + */ +__STATIC_INLINE uint32_t LL_I3C_GetMessageErrorCode(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->SER, I3C_SER_CODERR)); +} + +/** + * @brief Get CCC code of received command. + * @rmtoll RMR RCODE LL_I3C_GetReceiveCommandCode + * @param I3Cx I3C Instance. + * @retval Value between Min_Data=0 to Max_Data=0xFF. + */ +__STATIC_INLINE uint32_t LL_I3C_GetReceiveCommandCode(const I3C_TypeDef *I3Cx) +{ + return (uint32_t)(READ_BIT(I3Cx->RMR, I3C_RMR_RCODE) >> I3C_RMR_RCODE_Pos); +} + +/** + * @} + */ + +/** @defgroup I3C_LL_EF_Target Payload + * @{ + */ + +/** + * @brief Set Dynamic Address assigned to target x. + * @rmtoll DEVRX DA LL_I3C_SetTargetDynamicAddress + * @param I3Cx I3C Instance. + * @param TargetId This parameter must be a value between Min_Data=1 and Max_Data=4 + * @param DynamicAddr Value between Min_Data=0 to Max_Data=0x7F + * @retval None + */ +__STATIC_INLINE void LL_I3C_SetTargetDynamicAddress(I3C_TypeDef *I3Cx, uint32_t TargetId, uint32_t DynamicAddr) +{ + MODIFY_REG(I3Cx->DEVRX[TargetId - 1U], I3C_DEVRX_DA, (DynamicAddr << I3C_DEVRX_DA_Pos)); +} + +/** + * @brief Get Dynamic Address assigned to target x. + * @rmtoll DEVRX DA LL_I3C_GetTargetDynamicAddress + * @param I3Cx I3C Instance. + * @param TargetId This parameter must be a value between Min_Data=1 and Max_Data=4 + * @retval Value between Min_Data=0 to Max_Data=0x7F + */ +__STATIC_INLINE uint32_t LL_I3C_GetTargetDynamicAddress(const I3C_TypeDef *I3Cx, uint32_t TargetId) +{ + return (uint32_t)((READ_BIT(I3Cx->DEVRX[TargetId - 1U], I3C_DEVRX_DA)) >> I3C_DEVRX_DA_Pos); +} + +/** + * @brief Enable IBI Acknowledgement from target x(controller mode). + * @note The bit DIS is automatically set when CRACK or IBIACK are set. + * This mean DEVRX register access is not allowed. + * Reset CRACK and IBIACK will reset DIS bit. + * @rmtoll DEVRX IBIACK LL_I3C_EnableTargetIBIAck + * @param I3Cx I3C Instance. + * @param TargetId This parameter must be a value between Min_Data=1 and Max_Data=4 + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableTargetIBIAck(I3C_TypeDef *I3Cx, uint32_t TargetId) +{ + SET_BIT(I3Cx->DEVRX[TargetId - 1U], I3C_DEVRX_IBIACK); +} + +/** + * @brief Disable IBI Acknowledgement from target x (controller mode). + * @rmtoll DEVRX IBIACK LL_I3C_DisableTargetIBIAck + * @param I3Cx I3C Instance. + * @param TargetId This parameter must be a value between Min_Data=1 and Max_Data=4 + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableTargetIBIAck(I3C_TypeDef *I3Cx, uint32_t TargetId) +{ + CLEAR_BIT(I3Cx->DEVRX[TargetId - 1U], I3C_DEVRX_IBIACK); +} + +/** + * @brief Indicates if IBI from target x will be Acknowledged or Not Acknowledged (controller mode). + * RESET: IBI Not Acknowledged. + * SET: IBI Acknowledged. + * @rmtoll DEVRX IBIACK LL_I3C_IsEnabledTargetIBIAck + * @param I3Cx I3C Instance. + * @param TargetId This parameter must be a value between Min_Data=1 and Max_Data=4 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledTargetIBIAck(const I3C_TypeDef *I3Cx, uint32_t TargetId) +{ + return ((READ_BIT(I3Cx->DEVRX[TargetId - 1U], I3C_DEVRX_IBIACK) == I3C_DEVRX_IBIACK) ? 1UL : 0UL); +} + +/** + * @brief Enable Controller-role Request Acknowledgement from target x(controller mode). + * @note The bit DIS is automatically set when CRACK or IBIACK are set. + * This mean DEVRX register access is not allowed. + * Reset CRACK and IBIACK will reset DIS bit. + * @rmtoll DEVRX CRACK LL_I3C_EnableTargetCRAck + * @param I3Cx I3C Instance. + * @param TargetId This parameter must be a value between Min_Data=1 and Max_Data=4 + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableTargetCRAck(I3C_TypeDef *I3Cx, uint32_t TargetId) +{ + SET_BIT(I3Cx->DEVRX[TargetId - 1U], I3C_DEVRX_CRACK); +} + +/** + * @brief Disable Controller-role Request Acknowledgement from target x (controller mode). + * @rmtoll DEVRX CRACK LL_I3C_DisableTargetCRAck + * @param I3Cx I3C Instance. + * @param TargetId This parameter must be a value between Min_Data=1 and Max_Data=4 + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableTargetCRAck(I3C_TypeDef *I3Cx, uint32_t TargetId) +{ + CLEAR_BIT(I3Cx->DEVRX[TargetId - 1U], I3C_DEVRX_CRACK); +} + +/** + * @brief Indicates if Controller-role Request from target x will be + * Acknowledged or Not Acknowledged (controller mode). + * RESET: Controller-role Request Not Acknowledged. + * SET: Controller-role Request Acknowledged. + * @rmtoll DEVRX CRACK LL_I3C_IsEnabledTargetCRAck + * @param I3Cx I3C Instance. + * @param TargetId This parameter must be a value between Min_Data=1 and Max_Data=4 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledTargetCRAck(const I3C_TypeDef *I3Cx, uint32_t TargetId) +{ + return ((READ_BIT(I3Cx->DEVRX[TargetId - 1U], I3C_DEVRX_CRACK) == I3C_DEVRX_CRACK) ? 1UL : 0UL); +} + +/** + * @brief Enable additional Mandatory Data Byte (MDB) follows the accepted IBI from target x. + * @rmtoll DEVRX IBIDEN LL_I3C_EnableIBIAddData + * @param I3Cx I3C Instance. + * @param TargetId This parameter must be a value between Min_Data=1 and Max_Data=4 + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableIBIAddData(I3C_TypeDef *I3Cx, uint32_t TargetId) +{ + SET_BIT(I3Cx->DEVRX[TargetId - 1U], I3C_DEVRX_IBIDEN); +} + +/** + * @brief Disable additional Mandatory Data Byte (MDB) follows the accepted IBI from target x. + * @rmtoll DEVRX IBIDEN LL_I3C_DisableIBIAddData + * @param I3Cx I3C Instance. + * @param TargetId This parameter must be a value between Min_Data=1 and Max_Data=4 + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableIBIAddData(I3C_TypeDef *I3Cx, uint32_t TargetId) +{ + CLEAR_BIT(I3Cx->DEVRX[TargetId - 1U], I3C_DEVRX_IBIDEN); +} + +/** + * @brief Indicates if additional Mandatory Data Byte (MDB) follows the accepted IBI from target x. + * RESET: No Mandatory Data Byte follows IBI. + * SET: Mandatory Data Byte follows IBI. + * @rmtoll DEVRX IBIDEN LL_I3C_IsEnabledIBIAddData + * @param I3Cx I3C Instance. + * @param TargetId This parameter must be a value between Min_Data=1 and Max_Data=4 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledIBIAddData(const I3C_TypeDef *I3Cx, uint32_t TargetId) +{ + return ((READ_BIT(I3Cx->DEVRX[TargetId - 1U], I3C_DEVRX_IBIDEN) == I3C_DEVRX_IBIDEN) ? 1UL : 0UL); +} + +/** + * @brief Enable Suspension of Current transfer during IBI treatment. + * @note When set, this feature will allow controller to send + * a Stop condition and CR FIFO is flushed after IBI treatment. + * Software has to rewrite instructions in Control Register to start a new transfer. + * @rmtoll DEVRX SUSP LL_I3C_EnableFrameSuspend + * @param I3Cx I3C Instance. + * @param TargetId This parameter must be a value between Min_Data=1 and Max_Data=4 + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableFrameSuspend(I3C_TypeDef *I3Cx, uint32_t TargetId) +{ + SET_BIT(I3Cx->DEVRX[TargetId - 1U], I3C_DEVRX_SUSP); +} + +/** + * @brief Disable Suspension of Current transfer during IBI treatment. + * @note When set, this feature will allow controller to continue CR FIFO treatment after IBI treatment. + * @rmtoll DEVRX SUSP LL_I3C_DisableFrameSuspend + * @param I3Cx I3C Instance. + * @param TargetId This parameter must be a value between Min_Data=1 and Max_Data=4 + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableFrameSuspend(I3C_TypeDef *I3Cx, uint32_t TargetId) +{ + CLEAR_BIT(I3Cx->DEVRX[TargetId - 1U], I3C_DEVRX_SUSP); +} + +/** + * @brief Indicates if I3C transfer must be Suspended or not Suspended during IBI treatment from target x. + * RESET: Transfer is not suspended. Instruction in CR FIFO are executed after IBI. + * SET: Transfer is suspended (a Stop condition is sent). CR FIFO is flushed. + * @rmtoll DEVRX SUSP LL_I3C_IsFrameMustBeSuspended + * @param I3Cx I3C Instance. + * @param TargetId This parameter must be a value between Min_Data=1 and Max_Data=4 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsFrameMustBeSuspended(const I3C_TypeDef *I3Cx, uint32_t TargetId) +{ + return ((READ_BIT(I3Cx->DEVRX[TargetId - 1U], I3C_DEVRX_SUSP) == I3C_DEVRX_SUSP) ? 1UL : 0UL); +} + +/** + * @brief Indicates if update of the Device Characteristics Register is Allowed or Not Allowed. + * RESET: Device Characteristics Register update is Not Allowed. + * SET: Device Characteristics Register update is Allowed. + * @note Used to prevent software writing during reception of an IBI or Controller-role Request from target x. + * @rmtoll DEVRX DIS LL_I3C_IsAllowedPayloadUpdate + * @param I3Cx I3C Instance. + * @param TargetId This parameter must be a value between Min_Data=1 and Max_Data=4 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsAllowedPayloadUpdate(const I3C_TypeDef *I3Cx, uint32_t TargetId) +{ + return ((READ_BIT(I3Cx->DEVRX[TargetId - 1U], I3C_DEVRX_DIS) != I3C_DEVRX_DIS) ? 1UL : 0UL); +} + +/** + * @brief Set I3C bus devices configuration. + * @note This function is called only when the I3C instance is initialized as controller. + * This function can be called by the controller application to help the automatic treatment when target have + * capability of IBI and/or Control-Role. + * @rmtoll DEVRX DA LL_I3C_ConfigDeviceCapabilities + * @rmtoll DEVRX IBIACK LL_I3C_ConfigDeviceCapabilities + * @rmtoll DEVRX IBIDEN LL_I3C_ConfigDeviceCapabilities + * @rmtoll DEVRX CRACK LL_I3C_ConfigDeviceCapabilities + * @param I3Cx I3C Instance. + * @param TargetId This parameter must be a value between Min_Data=1 and Max_Data=4 + * @param DynamicAddr Value between Min_Data=0 to Max_Data=0x7F + * @param IBIAck Value This parameter can be one of the following values: + * @arg @ref LL_I3C_IBI_CAPABILITY + * @arg @ref LL_I3C_IBI_NO_CAPABILITY + * @param IBIAddData This parameter can be one of the following values: + * @arg @ref LL_I3C_IBI_DATA_ENABLE + * @arg @ref LL_I3C_IBI_DATA_DISABLE + * @param CRAck This parameter can be one of the following values: + * @arg @ref LL_I3C_CR_CAPABILITY + * @arg @ref LL_I3C_CR_NO_CAPABILITY + * @retval None + */ +__STATIC_INLINE void LL_I3C_ConfigDeviceCapabilities(I3C_TypeDef *I3Cx, + uint32_t TargetId, + uint32_t DynamicAddr, + uint32_t IBIAck, + uint32_t IBIAddData, + uint32_t CRAck) +{ + MODIFY_REG(I3Cx->DEVRX[TargetId - 1U], \ + (I3C_DEVRX_DA | I3C_DEVRX_IBIACK | I3C_DEVRX_CRACK | I3C_DEVRX_IBIDEN), \ + ((DynamicAddr << I3C_DEVRX_DA_Pos) | IBIAck | IBIAddData | CRAck)); +} +/** + * @} + */ + +/** @defgroup I3C_LL_EF_FLAG_management FLAG_management + * @{ + */ + +/** + * @brief Indicates the status of Control FIFO Empty flag. + * RESET: One or more data are available in Control FIFO. + * SET: No more data available in Control FIFO. + * @rmtoll EVR CFEF LL_I3C_IsActiveFlag_CFE + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_CFE(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->EVR, I3C_EVR_CFEF) == (I3C_EVR_CFEF)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of Transmit FIFO Empty flag. + * RESET: One or more data are available in Transmit FIFO. + * SET: No more data available in Transmit FIFO. + * @rmtoll EVR TXFEF LL_I3C_IsActiveFlag_TXFE + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_TXFE(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->EVR, I3C_EVR_TXFEF) == (I3C_EVR_TXFEF)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of Control FIFO Not Full flag. + * RESET: One or more free space available in Control FIFO. + * SET: No more free space available in Control FIFO. + * @note When a transfer is ongoing, the Control FIFO shall not be written unless this flag is set. + * @rmtoll EVR CFNFF LL_I3C_IsActiveFlag_CFNF + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_CFNF(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->EVR, I3C_EVR_CFNFF) == (I3C_EVR_CFNFF)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of Status FIFO Not Empty flag. + * RESET: One or more free space available in Status FIFO. + * SET: No more free space available in Status FIFO. + * @note This flag is updated only when the FIFO is used, mean SMODE = 1. + * @rmtoll EVR SFNEF LL_I3C_IsActiveFlag_SFNE + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_SFNE(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->EVR, I3C_EVR_SFNEF) == (I3C_EVR_SFNEF)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of Transmit FIFO Not Full flag. + * RESET: One or more free space available in Transmit FIFO. + * SET: No more free space available in Transmit FIFO. + * @note When a transfer is ongoing, the Transmit FIFO shall not be written unless this flag is set. + * @rmtoll EVR TXFNFF LL_I3C_IsActiveFlag_TXFNF + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_TXFNF(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->EVR, I3C_EVR_TXFNFF) == (I3C_EVR_TXFNFF)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of Receive FIFO Not Full flag. + * RESET: One or more data are available in Receive FIFO. + * SET: No more data available in Receive FIFO. + * @rmtoll EVR RXFNEF LL_I3C_IsActiveFlag_RXFNE + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_RXFNE(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->EVR, I3C_EVR_RXFNEF) == (I3C_EVR_RXFNEF)) ? 1UL : 0UL); +} + +/** + * @brief Indicates that the last Receive byte is available. + * RESET: Clear default value. + * SET: Last Receive byte ready to read from Receive FIFO. + * @rmtoll EVR RXLASTF LL_I3C_IsActiveFlag_RXLAST + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_RXLAST(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->EVR, I3C_EVR_RXLASTF) == (I3C_EVR_RXLASTF)) ? 1UL : 0UL); +} + +/** + * @brief Indicates that the last Transmit byte is written in FIFO. + * RESET: Transmission is not finalized. + * SET: Last Transmit byte is written in transmit FIFO. + * @rmtoll EVR TXLASTF LL_I3C_IsActiveFlag_TXLAST + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_TXLAST(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->EVR, I3C_EVR_TXLASTF) == (I3C_EVR_TXLASTF)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of Frame Complete flag (controller and target mode). + * RESET: Current Frame transfer is not finalized. + * SET: Current Frame transfer is completed. + * @rmtoll EVR FCF LL_I3C_IsActiveFlag_FC + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_FC(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->EVR, I3C_EVR_FCF) == (I3C_EVR_FCF)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of Reception Target End flag (controller mode). + * RESET: Clear default value. + * SET: Target prematurely ended a Read Command. + * @note This flag is set only when status FIFO is not used, mean SMODE = 0. + * @rmtoll EVR RXTGTENDF LL_I3C_IsActiveFlag_RXTGTEND + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_RXTGTEND(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->EVR, I3C_EVR_RXTGTENDF) == (I3C_EVR_RXTGTENDF)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of Error flag (controller and target mode). + * RESET: Clear default value. + * SET: One or more Errors are detected. + * @rmtoll EVR ERRF LL_I3C_IsActiveFlag_ERR + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_ERR(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->EVR, I3C_EVR_ERRF) == (I3C_EVR_ERRF)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of IBI flag (controller mode). + * RESET: Clear default value. + * SET: An IBI have been received. + * @rmtoll EVR IBIF LL_I3C_IsActiveFlag_IBI + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_IBI(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->EVR, I3C_EVR_IBIF) == (I3C_EVR_IBIF)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of IBI End flag (target mode). + * RESET: Clear default value. + * SET: IBI procedure is finished. + * @rmtoll EVR IBIENDF LL_I3C_IsActiveFlag_IBIEND + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_IBIEND(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->EVR, I3C_EVR_IBIENDF) == (I3C_EVR_IBIENDF)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of Controller-role Request flag (controller mode). + * RESET: Clear default value. + * SET: A Controller-role request procedure have been received. + * @rmtoll EVR CRF LL_I3C_IsActiveFlag_CR + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_CR(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->EVR, I3C_EVR_CRF) == (I3C_EVR_CRF)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of Controller-role Request Update flag (target mode). + * RESET: Clear default value. + * SET: I3C device have gained Controller-role of the I3C Bus. + * @rmtoll EVR BCUPDF LL_I3C_IsActiveFlag_CRUPD + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_CRUPD(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->EVR, I3C_EVR_CRUPDF) == (I3C_EVR_CRUPDF)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of Hot Join flag (controller mode). + * RESET: Clear default value. + * SET: A Hot Join request have been received. + * @rmtoll EVR HJF LL_I3C_IsActiveFlag_HJ + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_HJ(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->EVR, I3C_EVR_HJF) == (I3C_EVR_HJF)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of Wake Up flag (target mode). + * RESET: Clear default value. + * SET: I3C Internal clock not available on time to treat the falling edge on SCL. + * @rmtoll EVR WKPF LL_I3C_IsActiveFlag_WKP + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_WKP(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->EVR, I3C_EVR_WKPF) == (I3C_EVR_WKPF)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of Get flag (target mode). + * RESET: Clear default value. + * SET: A "get" type CCC have been received. + * @rmtoll EVR GETF LL_I3C_IsActiveFlag_GET + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_GET(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->EVR, I3C_EVR_GETF) == (I3C_EVR_GETF)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of Get Status flag (target mode). + * RESET: Clear default value. + * SET: A GETSTATUS Command have been received. + * @rmtoll EVR STAF LL_I3C_IsActiveFlag_STA + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_STA(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->EVR, I3C_EVR_STAF) == (I3C_EVR_STAF)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of Dynamic Address Update flag (target mode). + * RESET: Clear default value. + * SET: Own Dynamic Address have been updated. + * @rmtoll EVR DAUPDF LL_I3C_IsActiveFlag_DAUPD + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_DAUPD(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->EVR, I3C_EVR_DAUPDF) == (I3C_EVR_DAUPDF)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of Max Write Length flag (target mode). + * RESET: Clear default value. + * SET: Max Write Length have been updated. + * @rmtoll EVR MWLUPDF LL_I3C_IsActiveFlag_MWLUPD + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_MWLUPD(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->EVR, I3C_EVR_MWLUPDF) == (I3C_EVR_MWLUPDF)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of Max Read Length flag (target mode). + * RESET: Clear default value. + * SET: Max Read Length have been updated. + * @rmtoll EVR MRLUPDF LL_I3C_IsActiveFlag_MRLUPD + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_MRLUPD(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->EVR, I3C_EVR_MRLUPDF) == (I3C_EVR_MRLUPDF)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of Reset flag (target mode). + * RESET: Clear default value. + * SET: A Reset Pattern have been received. + * @rmtoll EVR RSTF LL_I3C_IsActiveFlag_RST + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_RST(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->EVR, I3C_EVR_RSTF) == (I3C_EVR_RSTF)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of Active State flag (target mode). + * RESET: Clear default value. + * SET: The Activity State have been updated. + * @rmtoll EVR ASUPDF LL_I3C_IsActiveFlag_ASUPD + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_ASUPD(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->EVR, I3C_EVR_ASUPDF) == (I3C_EVR_ASUPDF)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of Interrupt Update flag (target mode). + * RESET: Clear default value. + * SET: One or more Interrupt autorized have been updated. + * @rmtoll EVR INTUPDF LL_I3C_IsActiveFlag_INTUPD + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_INTUPD(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->EVR, I3C_EVR_INTUPDF) == (I3C_EVR_INTUPDF)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of Define List Targets flag (target mode). + * RESET: Clear default value. + * SET: A Define List Targets Command have been received. + * @rmtoll EVR DEFF LL_I3C_IsActiveFlag_DEF + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_DEF(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->EVR, I3C_EVR_DEFF) == (I3C_EVR_DEFF)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of Define List Group Addresses flag. + * RESET: Clear default value. + * SET: A Define List Group Addresses have been received. + * @rmtoll EVR GRPF LL_I3C_IsActiveFlag_GRP + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_GRP(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->EVR, I3C_EVR_GRPF) == (I3C_EVR_GRPF)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of Protocol Error flag. + * RESET: Clear default value. + * SET: Protocol error detected. + * @rmtoll SER PERR LL_I3C_IsActiveFlag_PERR + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_PERR(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->SER, I3C_SER_PERR) == (I3C_SER_PERR)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of SCL Stall Error flag (target mode). + * RESET: Clear default value. + * SET: Target detected that SCL was stable for more than 125us during I3C SDR read. + * @rmtoll SER STALL LL_I3C_IsActiveFlag_STALL + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_STALL(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->SER, I3C_SER_STALL) == (I3C_SER_STALL)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of RX or TX FIFO Overrun flag. + * RESET: Clear default value. + * SET: RX FIFO Full or TX FIFO Empty depending of direction of message. + * @rmtoll SER DOVR LL_I3C_IsActiveFlag_DOVR + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_DOVR(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->SER, I3C_SER_DOVR) == (I3C_SER_DOVR)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of Control or Status FIFO Overrun flag (controller mode). + * RESET: Clear default value. + * SET: Status FIFO Full or Control FIFO Empty after Restart. + * @rmtoll SER COVR LL_I3C_IsActiveFlag_COVR + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_COVR(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->SER, I3C_SER_COVR) == (I3C_SER_COVR)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of Address not acknowledged flag (controller mode). + * RESET: Clear default value. + * SET: Controller detected that Target nacked static or dynamic address. + * @rmtoll SER ANACK LL_I3C_IsActiveFlag_ANACK + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_ANACK(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->SER, I3C_SER_ANACK) == (I3C_SER_ANACK)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of Data not acknowledged flag (controller mode). + * RESET: Clear default value. + * SET: Controller detected that Target nacked Data byte. + * @rmtoll SER DNACK LL_I3C_IsActiveFlag_DNACK + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_DNACK(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->SER, I3C_SER_DNACK) == (I3C_SER_DNACK)) ? 1UL : 0UL); +} + +/** + * @brief Indicates the status of Data error flag (controller mode). + * RESET: Clear default value. + * SET: Controller detected data error during Controller-role handoff process. + * @rmtoll SER DERR LL_I3C_IsActiveFlag_DERR + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsActiveFlag_DERR(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->SER, I3C_SER_DERR) == (I3C_SER_DERR)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup I3C_LL_EF_IT_Management IT_Management + * @{ + */ + +/** + * @brief Enable Control FIFO Not Full interrupt. + * @rmtoll IER CFNFIE LL_I3C_EnableIT_CFNF + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableIT_CFNF(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->IER, I3C_IER_CFNFIE); +} + +/** + * @brief Disable Control FIFO Not Full interrupt. + * @rmtoll IER CFNFIE LL_I3C_DisableIT_CFNF + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableIT_CFNF(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->IER, I3C_IER_CFNFIE); +} + +/** + * @brief Check if Control FIFO Not Full interrupt is enabled or disabled. + * @rmtoll IER CFNFIE LL_I3C_IsEnabledIT_CFNF + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledIT_CFNF(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->IER, I3C_IER_CFNFIE) == (I3C_IER_CFNFIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable Status FIFO Not Empty interrupt. + * @rmtoll IER SFNEIE LL_I3C_EnableIT_SFNE + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableIT_SFNE(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->IER, I3C_IER_SFNEIE); +} + +/** + * @brief Disable Status FIFO Not Empty interrupt. + * @rmtoll IER SFNEIE LL_I3C_DisableIT_SFNE + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableIT_SFNE(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->IER, I3C_IER_SFNEIE); +} + +/** + * @brief Check if Status FIFO Not Empty interrupt is enabled or disabled. + * @rmtoll IER SFNEIE LL_I3C_IsEnabledIT_SFNE + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledIT_SFNE(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->IER, I3C_IER_SFNEIE) == (I3C_IER_SFNEIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable Transmit FIFO Not Full interrupt. + * @rmtoll IER TXFNFIE LL_I3C_EnableIT_TXFNF + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableIT_TXFNF(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->IER, I3C_IER_TXFNFIE); +} + +/** + * @brief Disable Transmit FIFO Not Full interrupt. + * @rmtoll IER TXFNFIE LL_I3C_DisableIT_TXFNF + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableIT_TXFNF(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->IER, I3C_IER_TXFNFIE); +} + +/** + * @brief Check if Transmit FIFO Not Full interrupt is enabled or disabled. + * @rmtoll IER TXFNFIE LL_I3C_IsEnabledIT_TXFNF + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledIT_TXFNF(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->IER, I3C_IER_TXFNFIE) == (I3C_IER_TXFNFIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable Receive FIFO Not Empty interrupt. + * @rmtoll IER RXFNEIE LL_I3C_EnableIT_RXFNE + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableIT_RXFNE(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->IER, I3C_IER_RXFNEIE); +} + +/** + * @brief Disable Receive FIFO Not Empty interrupt. + * @rmtoll IER RXFNEIE LL_I3C_DisableIT_RXFNE + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableIT_RXFNE(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->IER, I3C_IER_RXFNEIE); +} + +/** + * @brief Check if Receive FIFO Not Empty interrupt is enabled or disabled. + * @rmtoll IER RXFNEIE LL_I3C_IsEnabledIT_RXFNE + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledIT_RXFNE(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->IER, I3C_IER_RXFNEIE) == (I3C_IER_RXFNEIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable Frame Complete interrupt. + * @rmtoll IER FCIE LL_I3C_EnableIT_FC + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableIT_FC(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->IER, I3C_IER_FCIE); +} + +/** + * @brief Disable Frame Complete interrupt. + * @rmtoll IER FCIE LL_I3C_DisableIT_FC + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableIT_FC(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->IER, I3C_IER_FCIE); +} + +/** + * @brief Check if Frame Complete interrupt is enabled or disabled. + * @rmtoll IER FCIE LL_I3C_IsEnabledIT_FC + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledIT_FC(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->IER, I3C_IER_FCIE) == (I3C_IER_FCIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable Reception Target End interrupt. + * @rmtoll IER RXTGTENDIE LL_I3C_EnableIT_RXTGTEND + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableIT_RXTGTEND(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->IER, I3C_IER_RXTGTENDIE); +} + +/** + * @brief Disable Reception Target End interrupt. + * @rmtoll IER RXTGTENDIE LL_I3C_DisableIT_RXTGTEND + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableIT_RXTGTEND(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->IER, I3C_IER_RXTGTENDIE); +} + +/** + * @brief Check if Reception Target End interrupt is enabled or disabled. + * @rmtoll IER RXTGTENDIE LL_I3C_IsEnabledIT_RXTGTEND + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledIT_RXTGTEND(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->IER, I3C_IER_RXTGTENDIE) == (I3C_IER_RXTGTENDIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable Error interrupt. + * @rmtoll IER ERRIE LL_I3C_EnableIT_ERR + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableIT_ERR(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->IER, I3C_IER_ERRIE); +} + +/** + * @brief Disable Error interrupt. + * @rmtoll IER ERRIE LL_I3C_DisableIT_ERR + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableIT_ERR(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->IER, I3C_IER_ERRIE); +} + +/** + * @brief Check if Error interrupt is enabled or disabled. + * @rmtoll IER ERRIE LL_I3C_IsEnabledIT_ERR + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledIT_ERR(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->IER, I3C_IER_ERRIE) == (I3C_IER_ERRIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable IBI interrupt. + * @rmtoll IER IBIIE LL_I3C_EnableIT_IBI + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableIT_IBI(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->IER, I3C_IER_IBIIE); +} + +/** + * @brief Disable IBI interrupt. + * @rmtoll IER IBIIE LL_I3C_DisableIT_IBI + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableIT_IBI(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->IER, I3C_IER_IBIIE); +} + +/** + * @brief Check if IBI interrupt is enabled or disabled. + * @rmtoll IER IBIIE LL_I3C_IsEnabledIT_IBI + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledIT_IBI(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->IER, I3C_IER_IBIIE) == (I3C_IER_IBIIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable IBI End interrupt. + * @rmtoll IER IBIENDIE LL_I3C_EnableIT_IBIEND + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableIT_IBIEND(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->IER, I3C_IER_IBIENDIE); +} + +/** + * @brief Disable IBI End interrupt. + * @rmtoll IER IBIENDIE LL_I3C_DisableIT_IBIEND + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableIT_IBIEND(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->IER, I3C_IER_IBIENDIE); +} + +/** + * @brief Check if IBI End interrupt is enabled or disabled. + * @rmtoll IER IBIENDIE LL_I3C_IsEnabledIT_IBIEND + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledIT_IBIEND(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->IER, I3C_IER_IBIENDIE) == (I3C_IER_IBIENDIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable Controller-role interrupt. + * @rmtoll IER CRIE LL_I3C_EnableIT_CR + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableIT_CR(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->IER, I3C_IER_CRIE); +} + +/** + * @brief Disable Controller-role interrupt. + * @rmtoll IER CRIE LL_I3C_DisableIT_CR + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableIT_CR(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->IER, I3C_IER_CRIE); +} + +/** + * @brief Check if Controller-role interrupt is enabled or disabled. + * @rmtoll IER CRIE LL_I3C_IsEnabledIT_CR + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledIT_CR(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->IER, I3C_IER_CRIE) == (I3C_IER_CRIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable Controller-role Update interrupt. + * @rmtoll IER CRUPDIE LL_I3C_EnableIT_CRUPD + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableIT_CRUPD(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->IER, I3C_IER_CRUPDIE); +} + +/** + * @brief Disable Controller-role Update interrupt. + * @rmtoll IER CRUPDIE LL_I3C_DisableIT_CRUPD + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableIT_CRUPD(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->IER, I3C_IER_CRUPDIE); +} + +/** + * @brief Check if Controller-role Update interrupt is enabled or disabled. + * @rmtoll IER CRUPDIE LL_I3C_IsEnabledIT_CRUPD + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledIT_CRUPD(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->IER, I3C_IER_CRUPDIE) == (I3C_IER_CRUPDIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable Hot Join interrupt. + * @rmtoll IER HJIE LL_I3C_EnableIT_HJ + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableIT_HJ(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->IER, I3C_IER_HJIE); +} + +/** + * @brief Disable Hot Join interrupt. + * @rmtoll IER HJIE LL_I3C_DisableIT_HJ + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableIT_HJ(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->IER, I3C_IER_HJIE); +} + +/** + * @brief Check if Hot Join interrupt is enabled or disabled. + * @rmtoll IER HJIE LL_I3C_IsEnabledIT_HJ + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledIT_HJ(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->IER, I3C_IER_HJIE) == (I3C_IER_HJIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable Wake Up interrupt. + * @rmtoll IER WKPIE LL_I3C_EnableIT_WKP + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableIT_WKP(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->IER, I3C_IER_WKPIE); +} + +/** + * @brief Disable Wake Up interrupt. + * @rmtoll IER WKPIE LL_I3C_DisableIT_WKP + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableIT_WKP(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->IER, I3C_IER_WKPIE); +} + +/** + * @brief Check if Wake Up is enabled or disabled. + * @rmtoll IER WKPIE LL_I3C_IsEnabledIT_WKP + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledIT_WKP(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->IER, I3C_IER_WKPIE) == (I3C_IER_WKPIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable Get Command interrupt. + * @rmtoll IER GETIE LL_I3C_EnableIT_GET + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableIT_GET(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->IER, I3C_IER_GETIE); +} + +/** + * @brief Disable Get Command interrupt. + * @rmtoll IER GETIE LL_I3C_DisableIT_GET + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableIT_GET(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->IER, I3C_IER_GETIE); +} + +/** + * @brief Check if Get Command is enabled or disabled. + * @rmtoll IER GETIE LL_I3C_IsEnabledIT_GET + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledIT_GET(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->IER, I3C_IER_GETIE) == (I3C_IER_GETIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable Get Status interrupt. + * @rmtoll IER STAIE LL_I3C_EnableIT_STA + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableIT_STA(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->IER, I3C_IER_STAIE); +} + +/** + * @brief Disable Get Status interrupt. + * @rmtoll IER STAIE LL_I3C_DisableIT_STA + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableIT_STA(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->IER, I3C_IER_STAIE); +} + +/** + * @brief Check if Get Status interrupt is enabled or disabled. + * @rmtoll IER STAIE LL_I3C_IsEnabledIT_STA + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledIT_STA(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->IER, I3C_IER_STAIE) == (I3C_IER_STAIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable Dynamic Address Update interrupt. + * @rmtoll IER DAUPDIE LL_I3C_EnableIT_DAUPD + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableIT_DAUPD(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->IER, I3C_IER_DAUPDIE); +} + +/** + * @brief Disable Dynamic Address Update interrupt. + * @rmtoll IER DAUPDIE LL_I3C_DisableIT_DAUPD + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableIT_DAUPD(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->IER, I3C_IER_DAUPDIE); +} + +/** + * @brief Check if Dynamic Address Update interrupt is enabled or disabled. + * @rmtoll IER DAUPDIE LL_I3C_IsEnabledIT_DAUPD + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledIT_DAUPD(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->IER, I3C_IER_DAUPDIE) == (I3C_IER_DAUPDIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable Max Write Length Update interrupt. + * @rmtoll IER MWLUPDIE LL_I3C_EnableIT_MWLUPD + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableIT_MWLUPD(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->IER, I3C_IER_MWLUPDIE); +} + +/** + * @brief Disable Max Write Length Update interrupt. + * @rmtoll IER MWLUPDIE LL_I3C_DisableIT_MWLUPD + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableIT_MWLUPD(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->IER, I3C_IER_MWLUPDIE); +} + +/** + * @brief Check if Max Write Length Update interrupt is enabled or disabled. + * @rmtoll IER MWLUPDIE LL_I3C_IsEnabledIT_MWLUPD + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledIT_MWLUPD(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->IER, I3C_IER_MWLUPDIE) == (I3C_IER_MWLUPDIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable Max Read Length Update interrupt. + * @rmtoll IER MRLUPDIE LL_I3C_EnableIT_MRLUPD + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableIT_MRLUPD(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->IER, I3C_IER_MRLUPDIE); +} + +/** + * @brief Disable Max Read Length Update interrupt. + * @rmtoll IER MRLUPDIE LL_I3C_DisableIT_MRLUPD + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableIT_MRLUPD(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->IER, I3C_IER_MRLUPDIE); +} + +/** + * @brief Check if Max Read Length Update interrupt is enabled or disabled. + * @rmtoll IER MRLUPDIE LL_I3C_IsEnabledIT_MRLUPD + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledIT_MRLUPD(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->IER, I3C_IER_MRLUPDIE) == (I3C_IER_MRLUPDIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable Reset interrupt. + * @rmtoll IER RSTIE LL_I3C_EnableIT_RST + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableIT_RST(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->IER, I3C_IER_RSTIE); +} + +/** + * @brief Disable Reset interrupt. + * @rmtoll IER RSTIE LL_I3C_DisableIT_RST + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableIT_RST(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->IER, I3C_IER_RSTIE); +} + +/** + * @brief Check if Reset interrupt is enabled or disabled. + * @rmtoll IER RSTIE LL_I3C_IsEnabledIT_RST + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledIT_RST(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->IER, I3C_IER_RSTIE) == (I3C_IER_RSTIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable Activity State Update interrupt. + * @rmtoll IER ASUPDIE LL_I3C_EnableIT_ASUPD + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableIT_ASUPD(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->IER, I3C_IER_ASUPDIE); +} + +/** + * @brief Disable Activity State Update interrupt. + * @rmtoll IER ASUPDIE LL_I3C_DisableIT_ASUPD + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableIT_ASUPD(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->IER, I3C_IER_ASUPDIE); +} + +/** + * @brief Check if Activity State Update interrupt is enabled or disabled. + * @rmtoll IER ASUPDIE LL_I3C_IsEnabledIT_ASUPD + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledIT_ASUPD(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->IER, I3C_IER_ASUPDIE) == (I3C_IER_ASUPDIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable Interrupt Update interrupt. + * @rmtoll IER INTUPDIE LL_I3C_EnableIT_INTUPD + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableIT_INTUPD(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->IER, I3C_IER_INTUPDIE); +} + +/** + * @brief Disable Interrupt Update interrupt. + * @rmtoll IER INTUPDIE LL_I3C_DisableIT_INTUPD + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableIT_INTUPD(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->IER, I3C_IER_INTUPDIE); +} + +/** + * @brief Check if Interrupt Update interrupt is enabled or disabled. + * @rmtoll IER INTUPDIE LL_I3C_IsEnabledIT_INTUPD + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledIT_INTUPD(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->IER, I3C_IER_INTUPDIE) == (I3C_IER_INTUPDIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable Define List Target interrupt. + * @rmtoll IER DEFIE LL_I3C_EnableIT_DEF + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableIT_DEF(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->IER, I3C_IER_DEFIE); +} + +/** + * @brief Disable Define List Target interrupt. + * @rmtoll IER DEFIE LL_I3C_DisableIT_DEF + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableIT_DEF(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->IER, I3C_IER_DEFIE); +} + +/** + * @brief Check if Define List Target interrupt is enabled or disabled. + * @rmtoll IER DEFIE LL_I3C_IsEnabledIT_DEF + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledIT_DEF(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->IER, I3C_IER_DEFIE) == (I3C_IER_DEFIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable Define List Group Addresses interrupt. + * @rmtoll IER GRPIE LL_I3C_EnableIT_GRP + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_EnableIT_GRP(I3C_TypeDef *I3Cx) +{ + SET_BIT(I3Cx->IER, I3C_IER_GRPIE); +} + +/** + * @brief Disable Define List Group Addresses interrupt. + * @rmtoll IER GRPIE LL_I3C_DisableIT_GRP + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_DisableIT_GRP(I3C_TypeDef *I3Cx) +{ + CLEAR_BIT(I3Cx->IER, I3C_IER_GRPIE); +} + +/** + * @brief Check if Define List Group Addresses interrupt is enabled or disabled. + * @rmtoll IER GRPIE LL_I3C_IsEnabledIT_GRP + * @param I3Cx I3C Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I3C_IsEnabledIT_GRP(const I3C_TypeDef *I3Cx) +{ + return ((READ_BIT(I3Cx->IER, I3C_IER_GRPIE) == (I3C_IER_GRPIE)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @addtogroup I3C_LL_EF_FLAG_management FLAG_management + * @{ + */ + +/** + * @brief Clear Frame Complete flag (controller and target mode). + * @rmtoll CEVR CFCF LL_I3C_ClearFlag_FC + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_ClearFlag_FC(I3C_TypeDef *I3Cx) +{ + WRITE_REG(I3Cx->CEVR, I3C_CEVR_CFCF); +} + +/** + * @brief Clear Reception Target End flag (controller mode). + * @rmtoll CEVR CRXTGTENDF LL_I3C_ClearFlag_RXTGTEND + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_ClearFlag_RXTGTEND(I3C_TypeDef *I3Cx) +{ + WRITE_REG(I3Cx->CEVR, I3C_CEVR_CRXTGTENDF); +} + +/** + * @brief Clear Error flag (controller and target mode). + * @rmtoll CEVR CERRF LL_I3C_ClearFlag_ERR + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_ClearFlag_ERR(I3C_TypeDef *I3Cx) +{ + WRITE_REG(I3Cx->CEVR, I3C_CEVR_CERRF); +} + +/** + * @brief Clear IBI flag (controller mode). + * @rmtoll CEVR CIBIF LL_I3C_ClearFlag_IBI + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_ClearFlag_IBI(I3C_TypeDef *I3Cx) +{ + WRITE_REG(I3Cx->CEVR, I3C_CEVR_CIBIF); +} + +/** + * @brief Clear IBI End flag (target mode). + * @rmtoll CEVR CIBIENDF LL_I3C_ClearFlag_IBIEND + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_ClearFlag_IBIEND(I3C_TypeDef *I3Cx) +{ + WRITE_REG(I3Cx->CEVR, I3C_CEVR_CIBIENDF); +} + +/** + * @brief Clear Controller-role Request flag (controller mode). + * @rmtoll CEVR CCRF LL_I3C_ClearFlag_CR + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_ClearFlag_CR(I3C_TypeDef *I3Cx) +{ + WRITE_REG(I3Cx->CEVR, I3C_CEVR_CCRF); +} + +/** + * @brief Clear Controller-role Request Update flag (target mode). + * @rmtoll CEVR CCRUPDF LL_I3C_ClearFlag_CRUPD + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_ClearFlag_CRUPD(I3C_TypeDef *I3Cx) +{ + WRITE_REG(I3Cx->CEVR, I3C_CEVR_CCRUPDF); +} + +/** + * @brief Clear Hot Join flag (controller mode). + * @rmtoll CEVR CHJF LL_I3C_ClearFlag_HJ + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_ClearFlag_HJ(I3C_TypeDef *I3Cx) +{ + WRITE_REG(I3Cx->CEVR, I3C_CEVR_CHJF); +} + +/** + * @brief Clear Wake Up flag (target mode). + * @rmtoll CEVR CWKPF LL_I3C_ClearFlag_WKP + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_ClearFlag_WKP(I3C_TypeDef *I3Cx) +{ + WRITE_REG(I3Cx->CEVR, I3C_CEVR_CWKPF); +} + +/** + * @brief Clear Get flag (target mode). + * @rmtoll CEVR CGETF LL_I3C_ClearFlag_GET + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_ClearFlag_GET(I3C_TypeDef *I3Cx) +{ + WRITE_REG(I3Cx->CEVR, I3C_CEVR_CGETF); +} + +/** + * @brief Clear Get Status flag (target mode). + * @rmtoll CEVR CSTAF LL_I3C_ClearFlag_STA + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_ClearFlag_STA(I3C_TypeDef *I3Cx) +{ + WRITE_REG(I3Cx->CEVR, I3C_CEVR_CSTAF); +} + +/** + * @brief Clear Dynamic Address Update flag (target mode). + * @rmtoll CEVR CDAUPDF LL_I3C_ClearFlag_DAUPD + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_ClearFlag_DAUPD(I3C_TypeDef *I3Cx) +{ + WRITE_REG(I3Cx->CEVR, I3C_CEVR_CDAUPDF); +} + +/** + * @brief Clear Max Write Length flag (target mode). + * @rmtoll CEVR CMWLUPDF LL_I3C_ClearFlag_MWLUPD + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_ClearFlag_MWLUPD(I3C_TypeDef *I3Cx) +{ + WRITE_REG(I3Cx->CEVR, I3C_CEVR_CMWLUPDF); +} + +/** + * @brief Clear Max Read Length flag (target mode). + * @rmtoll CEVR CMRLUPDF LL_I3C_ClearFlag_MRLUPD + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_ClearFlag_MRLUPD(I3C_TypeDef *I3Cx) +{ + WRITE_REG(I3Cx->CEVR, I3C_CEVR_CMRLUPDF); +} + +/** + * @brief Clear Reset flag (target mode). + * @rmtoll CEVR CRSTF LL_I3C_ClearFlag_RST + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_ClearFlag_RST(I3C_TypeDef *I3Cx) +{ + WRITE_REG(I3Cx->CEVR, I3C_CEVR_CRSTF); +} + +/** + * @brief Clear Active State flag (target mode). + * @rmtoll CEVR CASUPDF LL_I3C_ClearFlag_ASUPD + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_ClearFlag_ASUPD(I3C_TypeDef *I3Cx) +{ + WRITE_REG(I3Cx->CEVR, I3C_CEVR_CASUPDF); +} + +/** + * @brief Clear Interrupt Update flag (target mode). + * @rmtoll CEVR CINTUPDF LL_I3C_ClearFlag_INTUPD + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_ClearFlag_INTUPD(I3C_TypeDef *I3Cx) +{ + WRITE_REG(I3Cx->CEVR, I3C_CEVR_CINTUPDF); +} + +/** + * @brief Clear Define List Targets flag (target mode). + * @rmtoll CEVR CDEFF LL_I3C_ClearFlag_DEF + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_ClearFlag_DEF(I3C_TypeDef *I3Cx) +{ + WRITE_REG(I3Cx->CEVR, I3C_CEVR_CDEFF); +} + +/** + * @brief Clear Define List Group Addresses flag. + * @rmtoll CEVR CGRPF LL_I3C_ClearFlag_GRP + * @param I3Cx I3C Instance. + * @retval None + */ +__STATIC_INLINE void LL_I3C_ClearFlag_GRP(I3C_TypeDef *I3Cx) +{ + WRITE_REG(I3Cx->CEVR, I3C_CEVR_CGRPF); +} + +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup I3C_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +ErrorStatus LL_I3C_Init(I3C_TypeDef *I3Cx, LL_I3C_InitTypeDef *I3C_InitStruct, uint32_t Mode); +ErrorStatus LL_I3C_DeInit(const I3C_TypeDef *I3Cx); +void LL_I3C_StructInit(LL_I3C_InitTypeDef *I3C_InitStruct); + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* I3C1 */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32H5xx_LL_I3C_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_icache.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_icache.h new file mode 100644 index 0000000000..13ebce80da --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_icache.h @@ -0,0 +1,784 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_icache.h + * @author MCD Application Team + * @brief Header file of ICACHE LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion ------------------------------------*/ +#ifndef STM32H5xx_LL_ICACHE_H +#define STM32H5xx_LL_ICACHE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes -----------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined(ICACHE) + +/** @defgroup ICACHE_LL ICACHE + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +#if defined(ICACHE_CRRx_REN) +/** @defgroup ICACHE_LL_REGION_CONFIG ICACHE Exported Configuration structure + * @{ + */ + +/** + * @brief LL ICACHE region configuration structure definition + */ +typedef struct +{ + uint32_t BaseAddress; /*!< Configures the C-AHB base address to be remapped */ + + uint32_t RemapAddress; /*!< Configures the remap address to be remapped */ + + uint32_t Size; /*!< Configures the region size. + This parameter can be a value of @ref ICACHE_LL_EC_Region_Size */ + + uint32_t TrafficRoute; /*!< Selects the traffic route. + This parameter can be a value of @ref ICACHE_LL_EC_Traffic_Route */ + + uint32_t OutputBurstType; /*!< Selects the output burst type. + This parameter can be a value of @ref ICACHE_LL_EC_Output_Burst_Type */ +} LL_ICACHE_RegionTypeDef; + +/** + * @} + */ +#endif /* ICACHE_CRRx_REN */ + +/* Exported constants -------------------------------------------------------*/ +/** @defgroup ICACHE_LL_Exported_Constants ICACHE Exported Constants + * @{ + */ + +/** @defgroup ICACHE_LL_EC_WaysSelection Ways selection + * @{ + */ +#define LL_ICACHE_1WAY 0U /*!< 1-way cache (direct mapped cache) */ +#define LL_ICACHE_2WAYS ICACHE_CR_WAYSEL /*!< 2-ways set associative cache (default) */ +/** + * @} + */ + +/** @defgroup ICACHE_LL_EC_Monitor_Type Monitor type + * @{ + */ +#define LL_ICACHE_MONITOR_HIT ICACHE_CR_HITMEN /*!< Hit monitor counter */ +#define LL_ICACHE_MONITOR_MISS ICACHE_CR_MISSMEN /*!< Miss monitor counter */ +#define LL_ICACHE_MONITOR_ALL (ICACHE_CR_HITMEN | ICACHE_CR_MISSMEN) /*!< All monitors counters */ +/** + * @} + */ + +/** @defgroup ICACHE_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_ICACHE_ReadReg function + * @{ + */ +#define LL_ICACHE_SR_BUSYF ICACHE_SR_BUSYF /*!< Busy flag */ +#define LL_ICACHE_SR_BSYENDF ICACHE_SR_BSYENDF /*!< Busy end flag */ +#define LL_ICACHE_SR_ERRF ICACHE_SR_ERRF /*!< Cache error flag */ +/** + * @} + */ + +/** @defgroup ICACHE_LL_EC_CLEAR_FLAG Clear Flags Defines + * @brief Flags defines which can be used with LL_ICACHE_WriteReg function + * @{ + */ +#define LL_ICACHE_FCR_CBSYENDF ICACHE_FCR_CBSYENDF /*!< Busy end flag */ +#define LL_ICACHE_FCR_CERRF ICACHE_FCR_CERRF /*!< Cache error flag */ +/** + * @} + */ + +/** @defgroup ICACHE_LL_EC_IT IT Defines + * @brief IT defines which can be used with LL_ICACHE_ReadReg and LL_ICACHE_WriteReg functions + * @{ + */ +#define LL_ICACHE_IER_BSYENDIE ICACHE_IER_BSYENDIE /*!< Busy end interrupt */ +#define LL_ICACHE_IER_ERRIE ICACHE_IER_ERRIE /*!< Cache error interrupt */ +/** + * @} + */ + +#if defined(ICACHE_CRRx_REN) +/** @defgroup ICACHE_LL_EC_Region Remapped Region number + * @{ + */ +#define LL_ICACHE_REGION_0 0U /*!< Region 0 */ +#define LL_ICACHE_REGION_1 1U /*!< Region 1 */ +#define LL_ICACHE_REGION_2 2U /*!< Region 2 */ +#define LL_ICACHE_REGION_3 3U /*!< Region 3 */ +/** + * @} + */ + +/** @defgroup ICACHE_LL_EC_Region_Size Remapped Region size + * @{ + */ +#define LL_ICACHE_REGIONSIZE_2MB 1U /*!< Region size 2MB */ +#define LL_ICACHE_REGIONSIZE_4MB 2U /*!< Region size 4MB */ +#define LL_ICACHE_REGIONSIZE_8MB 3U /*!< Region size 8MB */ +#define LL_ICACHE_REGIONSIZE_16MB 4U /*!< Region size 16MB */ +#define LL_ICACHE_REGIONSIZE_32MB 5U /*!< Region size 32MB */ +#define LL_ICACHE_REGIONSIZE_64MB 6U /*!< Region size 64MB */ +#define LL_ICACHE_REGIONSIZE_128MB 7U /*!< Region size 128MB */ +/** + * @} + */ + +/** @defgroup ICACHE_LL_EC_Traffic_Route Remapped Traffic route + * @{ + */ +#define LL_ICACHE_MASTER1_PORT 0U /*!< Master1 port */ +#define LL_ICACHE_MASTER2_PORT ICACHE_CRRx_MSTSEL /*!< Master2 port */ +/** + * @} + */ + +/** @defgroup ICACHE_LL_EC_Output_Burst_Type Remapped Output burst type + * @{ + */ +#define LL_ICACHE_OUTPUT_BURST_WRAP 0U /*!< WRAP */ +#define LL_ICACHE_OUTPUT_BURST_INCR ICACHE_CRRx_HBURST /*!< INCR */ +/** + * @} + */ +#endif /* ICACHE_CRRx_REN */ + +/** + * @} + */ + +/* Exported macros ----------------------------------------------------------*/ +/** @defgroup ICACHE_LL_Exported_Macros ICACHE Exported Macros + * @{ + */ + +/** @defgroup ICACHE_LL_EM_WRITE_READ Common write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in ICACHE register + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_ICACHE_WriteReg(__REG__, __VALUE__) WRITE_REG(ICACHE->__REG__, (__VALUE__)) + +/** + * @brief Read a value in ICACHE register + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_ICACHE_ReadReg(__REG__) READ_REG(ICACHE->__REG__) +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup ICACHE_LL_Exported_Functions ICACHE Exported Functions + * @{ + */ + +/** @defgroup ICACHE_LL_EF_Configuration Configuration + * @{ + */ + +/** + * @brief Enable the ICACHE. + * @rmtoll CR EN LL_ICACHE_Enable + * @retval None + */ +__STATIC_INLINE void LL_ICACHE_Enable(void) +{ + SET_BIT(ICACHE->CR, ICACHE_CR_EN); +} + +/** + * @brief Disable the ICACHE. + * @rmtoll CR EN LL_ICACHE_Disable + * @retval None + */ +__STATIC_INLINE void LL_ICACHE_Disable(void) +{ + CLEAR_BIT(ICACHE->CR, ICACHE_CR_EN); +} + +/** + * @brief Return if ICACHE is enabled or not. + * @rmtoll CR EN LL_ICACHE_IsEnabled + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ICACHE_IsEnabled(void) +{ + return ((READ_BIT(ICACHE->CR, ICACHE_CR_EN) == (ICACHE_CR_EN)) ? 1UL : 0UL); +} + +/** + * @brief Select the ICACHE operating mode. + * @rmtoll CR WAYSEL LL_ICACHE_SetMode + * @param Mode This parameter can be one of the following values: + * @arg @ref LL_ICACHE_1WAY + * @arg @ref LL_ICACHE_2WAYS + * @retval None + */ +__STATIC_INLINE void LL_ICACHE_SetMode(uint32_t Mode) +{ + MODIFY_REG(ICACHE->CR, ICACHE_CR_WAYSEL, Mode); +} + +/** + * @brief Get the selected ICACHE operating mode. + * @rmtoll CR WAYSEL LL_ICACHE_GetMode + * @retval Returned value can be one of the following values: + * @arg @ref LL_ICACHE_1WAY + * @arg @ref LL_ICACHE_2WAYS + */ +__STATIC_INLINE uint32_t LL_ICACHE_GetMode(void) +{ + return (READ_BIT(ICACHE->CR, ICACHE_CR_WAYSEL)); +} + +/** + * @brief Invalidate the ICACHE. + * @note Until the BSYEND flag is set, the cache is bypassed. + * @rmtoll CR CACHEINV LL_ICACHE_Invalidate + * @retval None + */ +__STATIC_INLINE void LL_ICACHE_Invalidate(void) +{ + SET_BIT(ICACHE->CR, ICACHE_CR_CACHEINV); +} + +/** + * @} + */ + +/** @defgroup ICACHE_LL_EF_Monitors Monitors + * @{ + */ + +/** + * @brief Enable the hit/miss monitor(s). + * @rmtoll CR HITMEN LL_ICACHE_EnableMonitors + * @rmtoll CR MISSMEN LL_ICACHE_EnableMonitors + * @param Monitors This parameter can be one or a combination of the following values: + * @arg @ref LL_ICACHE_MONITOR_HIT + * @arg @ref LL_ICACHE_MONITOR_MISS + * @arg @ref LL_ICACHE_MONITOR_ALL + * @retval None + */ +__STATIC_INLINE void LL_ICACHE_EnableMonitors(uint32_t Monitors) +{ + SET_BIT(ICACHE->CR, Monitors); +} + +/** + * @brief Disable the hit/miss monitor(s). + * @rmtoll CR HITMEN LL_ICACHE_DisableMonitors + * @rmtoll CR MISSMEN LL_ICACHE_DisableMonitors + * @param Monitors This parameter can be one or a combination of the following values: + * @arg @ref LL_ICACHE_MONITOR_HIT + * @arg @ref LL_ICACHE_MONITOR_MISS + * @arg @ref LL_ICACHE_MONITOR_ALL + * @retval None + */ +__STATIC_INLINE void LL_ICACHE_DisableMonitors(uint32_t Monitors) +{ + CLEAR_BIT(ICACHE->CR, Monitors); +} + +/** + * @brief Check if the monitor(s) is(are) enabled or disabled. + * @rmtoll CR HITMEN LL_ICACHE_IsEnabledMonitors + * @rmtoll CR MISSMEN LL_ICACHE_IsEnabledMonitors + * @param Monitors This parameter can be one or a combination of the following values: + * @arg @ref LL_ICACHE_MONITOR_HIT + * @arg @ref LL_ICACHE_MONITOR_MISS + * @arg @ref LL_ICACHE_MONITOR_ALL + * @retval State of parameter value (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ICACHE_IsEnabledMonitors(uint32_t Monitors) +{ + return ((READ_BIT(ICACHE->CR, Monitors) == (Monitors)) ? 1UL : 0UL); +} + +/** + * @brief Reset the hit/miss monitor(s). + * @rmtoll CR HITMRST LL_ICACHE_ResetMonitors + * @rmtoll CR MISSMRST LL_ICACHE_ResetMonitors + * @param Monitors This parameter can be one or a combination of the following values: + * @arg @ref LL_ICACHE_MONITOR_HIT + * @arg @ref LL_ICACHE_MONITOR_MISS + * @arg @ref LL_ICACHE_MONITOR_ALL + * @retval None + */ +__STATIC_INLINE void LL_ICACHE_ResetMonitors(uint32_t Monitors) +{ + /* Reset */ + SET_BIT(ICACHE->CR, (Monitors << 2U)); + /* Release reset */ + CLEAR_BIT(ICACHE->CR, (Monitors << 2U)); +} + +/** + * @brief Get the Hit monitor. + * @note Upon reaching the 32-bit maximum value, hit monitor does not wrap. + * @rmtoll HMONR HITMON LL_ICACHE_GetHitMonitor + * @retval Value between Min_Data=0 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_ICACHE_GetHitMonitor(void) +{ + return (ICACHE->HMONR); +} + +/** + * @brief Get the Miss monitor. + * @note Upon reaching the 16-bit maximum value, miss monitor does not wrap. + * @rmtoll MMONR MISSMON LL_ICACHE_GetMissMonitor + * @retval Value between Min_Data=0 and Max_Data=0xFFFF + */ +__STATIC_INLINE uint32_t LL_ICACHE_GetMissMonitor(void) +{ + return (ICACHE->MMONR); +} + +/** + * @} + */ + +/** @defgroup ICACHE_LL_EF_IT_Management IT_Management + * @{ + */ + +/** + * @brief Enable BSYEND interrupt. + * @rmtoll IER BSYENDIE LL_ICACHE_EnableIT_BSYEND + * @retval None + */ +__STATIC_INLINE void LL_ICACHE_EnableIT_BSYEND(void) +{ + SET_BIT(ICACHE->IER, ICACHE_IER_BSYENDIE); +} + +/** + * @brief Disable BSYEND interrupt. + * @rmtoll IER BSYENDIE LL_ICACHE_DisableIT_BSYEND + * @retval None + */ +__STATIC_INLINE void LL_ICACHE_DisableIT_BSYEND(void) +{ + CLEAR_BIT(ICACHE->IER, ICACHE_IER_BSYENDIE); +} + +/** + * @brief Check if the BSYEND Interrupt is enabled or disabled. + * @rmtoll IER BSYENDIE LL_ICACHE_IsEnabledIT_BSYEND + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ICACHE_IsEnabledIT_BSYEND(void) +{ + return ((READ_BIT(ICACHE->IER, ICACHE_IER_BSYENDIE) == (ICACHE_IER_BSYENDIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable ERR interrupt. + * @rmtoll IER ERRIE LL_ICACHE_EnableIT_ERR + * @retval None + */ +__STATIC_INLINE void LL_ICACHE_EnableIT_ERR(void) +{ + SET_BIT(ICACHE->IER, ICACHE_IER_ERRIE); +} + +/** + * @brief Disable ERR interrupt. + * @rmtoll IER ERRIE LL_ICACHE_DisableIT_ERR + * @retval None + */ +__STATIC_INLINE void LL_ICACHE_DisableIT_ERR(void) +{ + CLEAR_BIT(ICACHE->IER, ICACHE_IER_ERRIE); +} + +/** + * @brief Check if the ERR Interrupt is enabled or disabled. + * @rmtoll IER ERRIE LL_ICACHE_IsEnabledIT_ERR + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ICACHE_IsEnabledIT_ERR(void) +{ + return ((READ_BIT(ICACHE->IER, ICACHE_IER_ERRIE) == (ICACHE_IER_ERRIE)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup ICACHE_LL_EF_FLAG_Management FLAG_Management + * @{ + */ + +/** + * @brief Indicate the status of an ongoing operation flag. + * @rmtoll SR BUSYF LL_ICACHE_IsActiveFlag_BUSY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ICACHE_IsActiveFlag_BUSY(void) +{ + return ((READ_BIT(ICACHE->SR, ICACHE_SR_BUSYF) == (ICACHE_SR_BUSYF)) ? 1UL : 0UL); +} + +/** + * @brief Indicate the status of an operation end flag. + * @rmtoll SR BSYEND LL_ICACHE_IsActiveFlag_BSYEND + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ICACHE_IsActiveFlag_BSYEND(void) +{ + return ((READ_BIT(ICACHE->SR, ICACHE_SR_BSYENDF) == (ICACHE_SR_BSYENDF)) ? 1UL : 0UL); +} + +/** + * @brief Indicate the status of an error flag. + * @rmtoll SR ERRF LL_ICACHE_IsActiveFlag_ERR + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ICACHE_IsActiveFlag_ERR(void) +{ + return ((READ_BIT(ICACHE->SR, ICACHE_SR_ERRF) == (ICACHE_SR_ERRF)) ? 1UL : 0UL); +} + +/** + * @brief Clear busy end of operation flag. + * @rmtoll FCR CBSYENDF LL_ICACHE_ClearFlag_BSYEND + * @retval None + */ +__STATIC_INLINE void LL_ICACHE_ClearFlag_BSYEND(void) +{ + WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF); +} + +/** + * @brief Clear error flag. + * @rmtoll FCR ERRF LL_ICACHE_ClearFlag_ERR + * @retval None + */ +__STATIC_INLINE void LL_ICACHE_ClearFlag_ERR(void) +{ + WRITE_REG(ICACHE->FCR, ICACHE_FCR_CERRF); +} + +/** + * @} + */ + +#if defined(ICACHE_CRRx_REN) +/** @defgroup ICACHE_LL_EF_REGION_Management REGION_Management + * @{ + */ + +/** + * @brief Enable the remapped memory region. + * @note The region must have been already configured. + * @rmtoll CRRx REN LL_ICACHE_EnableRegion + * @param Region This parameter can be one of the following values: + * @arg @ref LL_ICACHE_REGION_0 + * @arg @ref LL_ICACHE_REGION_1 + * @arg @ref LL_ICACHE_REGION_2 + * @arg @ref LL_ICACHE_REGION_3 + * @retval None + */ +__STATIC_INLINE void LL_ICACHE_EnableRegion(uint32_t Region) +{ + SET_BIT(*((__IO uint32_t *)(&(ICACHE->CRR0) + (1U * Region))), \ + ICACHE_CRRx_REN); +} + +/** + * @brief Disable the remapped memory region. + * @rmtoll CRRx REN LL_ICACHE_DisableRegion + * @param Region This parameter can be one of the following values: + * @arg @ref LL_ICACHE_REGION_0 + * @arg @ref LL_ICACHE_REGION_1 + * @arg @ref LL_ICACHE_REGION_2 + * @arg @ref LL_ICACHE_REGION_3 + * @retval None + */ +__STATIC_INLINE void LL_ICACHE_DisableRegion(uint32_t Region) +{ + CLEAR_BIT(*((__IO uint32_t *)(&(ICACHE->CRR0) + (1U * Region))), \ + ICACHE_CRRx_REN); +} + +/** + * @brief Return if remapped memory region is enabled or not. + * @rmtoll CRRx REN LL_ICACHE_IsEnabledRegion + * @param Region This parameter can be one of the following values: + * @arg @ref LL_ICACHE_REGION_0 + * @arg @ref LL_ICACHE_REGION_1 + * @arg @ref LL_ICACHE_REGION_2 + * @arg @ref LL_ICACHE_REGION_3 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ICACHE_IsEnabledRegion(uint32_t Region) +{ + return ((READ_BIT(*((__IO uint32_t *)(&(ICACHE->CRR0) + (1U * Region))), \ + ICACHE_CRRx_REN) == (ICACHE_CRRx_REN)) ? 1UL : 0UL); +} + +/** + * @brief Select the memory remapped region base address. + * @rmtoll CRRx BASEADDR LL_ICACHE_SetRegionBaseAddress + * @param Region This parameter can be one of the following values: + * @arg @ref LL_ICACHE_REGION_0 + * @arg @ref LL_ICACHE_REGION_1 + * @arg @ref LL_ICACHE_REGION_2 + * @arg @ref LL_ICACHE_REGION_3 + * @param Address Alias address in the Code region + * @retval None + */ +__STATIC_INLINE void LL_ICACHE_SetRegionBaseAddress(uint32_t Region, uint32_t Address) +{ + MODIFY_REG(*((__IO uint32_t *)(&(ICACHE->CRR0) + (1U * Region))), \ + ICACHE_CRRx_BASEADDR, (((Address & 0x1FFFFFFFU) >> 21U) & ICACHE_CRRx_BASEADDR)); +} + +/** + * @brief Get the memory remapped region base address. + * @note The base address is the alias in the Code region. + * @rmtoll CRRx BASEADDR LL_ICACHE_GetRegionBaseAddress + * @param Region This parameter can be one of the following values: + * @arg @ref LL_ICACHE_REGION_0 + * @arg @ref LL_ICACHE_REGION_1 + * @arg @ref LL_ICACHE_REGION_2 + * @arg @ref LL_ICACHE_REGION_3 + * @retval Address Alias address in the Code region + */ +__STATIC_INLINE uint32_t LL_ICACHE_GetRegionBaseAddress(uint32_t Region) +{ + return (READ_BIT(*((__IO uint32_t *)(&(ICACHE->CRR0) + (1U * Region))), \ + ICACHE_CRRx_BASEADDR)); +} + +/** + * @brief Select the memory remapped region remap address. + * @rmtoll CRRx REMAPADDR LL_ICACHE_SetRegionRemapAddress + * @param Region This parameter can be one of the following values: + * @arg @ref LL_ICACHE_REGION_0 + * @arg @ref LL_ICACHE_REGION_1 + * @arg @ref LL_ICACHE_REGION_2 + * @arg @ref LL_ICACHE_REGION_3 + * @param Address External memory address + * @retval None + */ +__STATIC_INLINE void LL_ICACHE_SetRegionRemapAddress(uint32_t Region, uint32_t Address) +{ + MODIFY_REG(*((__IO uint32_t *)(&(ICACHE->CRR0) + (1U * Region))), \ + ICACHE_CRRx_REMAPADDR, ((Address >> 21U) << ICACHE_CRRx_REMAPADDR_Pos)); +} + +/** + * @brief Get the memory remapped region base address. + * @rmtoll CRRx REMAPADDR LL_ICACHE_GetRegionRemapAddress + * @param Region This parameter can be one of the following values: + * @arg @ref LL_ICACHE_REGION_0 + * @arg @ref LL_ICACHE_REGION_1 + * @arg @ref LL_ICACHE_REGION_2 + * @arg @ref LL_ICACHE_REGION_3 + * @retval Address External memory address + */ +__STATIC_INLINE uint32_t LL_ICACHE_GetRegionRemapAddress(uint32_t Region) +{ + return ((READ_BIT(*((__IO uint32_t *)(&(ICACHE->CRR0) + (1U * Region))), \ + ICACHE_CRRx_REMAPADDR) >> ICACHE_CRRx_REMAPADDR_Pos) << 21U); +} + +/** + * @brief Select the memory remapped region size. + * @rmtoll CRRx RSIZE LL_ICACHE_SetRegionSize + * @param Region This parameter can be one of the following values: + * @arg @ref LL_ICACHE_REGION_0 + * @arg @ref LL_ICACHE_REGION_1 + * @arg @ref LL_ICACHE_REGION_2 + * @arg @ref LL_ICACHE_REGION_3 + * @param Size This parameter can be one of the following values: + * @arg @ref LL_ICACHE_REGIONSIZE_2MB + * @arg @ref LL_ICACHE_REGIONSIZE_4MB + * @arg @ref LL_ICACHE_REGIONSIZE_8MB + * @arg @ref LL_ICACHE_REGIONSIZE_16MB + * @arg @ref LL_ICACHE_REGIONSIZE_32MB + * @arg @ref LL_ICACHE_REGIONSIZE_64MB + * @arg @ref LL_ICACHE_REGIONSIZE_128MB + * @retval None + */ +__STATIC_INLINE void LL_ICACHE_SetRegionSize(uint32_t Region, uint32_t Size) +{ + MODIFY_REG(*((__IO uint32_t *)(&(ICACHE->CRR0) + (1U * Region))), \ + ICACHE_CRRx_RSIZE, (Size << ICACHE_CRRx_RSIZE_Pos)); +} + +/** + * @brief Get the selected the memory remapped region size. + * @rmtoll CRRx RSIZE LL_ICACHE_GetRegionSize + * @param Region This parameter can be one of the following values: + * @arg @ref LL_ICACHE_REGION_0 + * @arg @ref LL_ICACHE_REGION_1 + * @arg @ref LL_ICACHE_REGION_2 + * @arg @ref LL_ICACHE_REGION_3 + * @retval Returned value can be one of the following values: + * @arg @ref LL_ICACHE_REGIONSIZE_2MB + * @arg @ref LL_ICACHE_REGIONSIZE_4MB + * @arg @ref LL_ICACHE_REGIONSIZE_8MB + * @arg @ref LL_ICACHE_REGIONSIZE_16MB + * @arg @ref LL_ICACHE_REGIONSIZE_32MB + * @arg @ref LL_ICACHE_REGIONSIZE_64MB + * @arg @ref LL_ICACHE_REGIONSIZE_128MB + */ +__STATIC_INLINE uint32_t LL_ICACHE_GetRegionSize(uint32_t Region) +{ + return (READ_BIT(*((__IO uint32_t *)(&(ICACHE->CRR0) + (1U * Region))), \ + ICACHE_CRRx_RSIZE) >> ICACHE_CRRx_RSIZE_Pos); +} + +/** + * @brief Select the memory remapped region output burst type. + * @rmtoll CRRx HBURST LL_ICACHE_SetRegionOutputBurstType + * @param Region This parameter can be one of the following values: + * @arg @ref LL_ICACHE_REGION_0 + * @arg @ref LL_ICACHE_REGION_1 + * @arg @ref LL_ICACHE_REGION_2 + * @arg @ref LL_ICACHE_REGION_3 + * @param Type This parameter can be one of the following values: + * @arg @ref LL_ICACHE_OUTPUT_BURST_WRAP + * @arg @ref LL_ICACHE_OUTPUT_BURST_INCR + * @retval None + */ +__STATIC_INLINE void LL_ICACHE_SetRegionOutputBurstType(uint32_t Region, uint32_t Type) +{ + MODIFY_REG(*((__IO uint32_t *)(&(ICACHE->CRR0) + (1U * Region))), \ + ICACHE_CRRx_HBURST, Type); +} + +/** + * @brief Get the selected the memory remapped region output burst type. + * @rmtoll CRRx HBURST LL_ICACHE_GetRegionOutputBurstType + * @param Region This parameter can be one of the following values: + * @arg @ref LL_ICACHE_REGION_0 + * @arg @ref LL_ICACHE_REGION_1 + * @arg @ref LL_ICACHE_REGION_2 + * @arg @ref LL_ICACHE_REGION_3 + * @retval Returned value can be one of the following values: + * @arg @ref LL_ICACHE_OUTPUT_BURST_WRAP + * @arg @ref LL_ICACHE_OUTPUT_BURST_INCR + */ +__STATIC_INLINE uint32_t LL_ICACHE_GetRegionOutputBurstType(uint32_t Region) +{ + return (READ_BIT(*((__IO uint32_t *)(&(ICACHE->CRR0) + (1U * Region))), \ + ICACHE_CRRx_HBURST)); +} + +/** + * @brief Select the memory remapped region cache master port. + * @rmtoll CRRx MSTSEL LL_ICACHE_SetRegionMasterPort + * @param Region This parameter can be one of the following values: + * @arg @ref LL_ICACHE_REGION_0 + * @arg @ref LL_ICACHE_REGION_1 + * @arg @ref LL_ICACHE_REGION_2 + * @arg @ref LL_ICACHE_REGION_3 + * @param Port This parameter can be one of the following values: + * @arg @ref LL_ICACHE_MASTER1_PORT + * @arg @ref LL_ICACHE_MASTER2_PORT + * @retval None + */ +__STATIC_INLINE void LL_ICACHE_SetRegionMasterPort(uint32_t Region, uint32_t Port) +{ + MODIFY_REG(*((__IO uint32_t *)(&(ICACHE->CRR0) + (1U * Region))), \ + ICACHE_CRRx_MSTSEL, Port); +} + +/** + * @brief Get the selected the memory remapped region cache master port. + * @rmtoll CRRx MSTSEL LL_ICACHE_GetRegionMasterPort + * @param Region This parameter can be one of the following values: + * @arg @ref LL_ICACHE_REGION_0 + * @arg @ref LL_ICACHE_REGION_1 + * @arg @ref LL_ICACHE_REGION_2 + * @arg @ref LL_ICACHE_REGION_3 + * @retval Returned value can be one of the following values: + * @arg @ref LL_ICACHE_MASTER1_PORT + * @arg @ref LL_ICACHE_MASTER2_PORT + */ +__STATIC_INLINE uint32_t LL_ICACHE_GetRegionMasterPort(uint32_t Region) +{ + return (READ_BIT(*((__IO uint32_t *)(&(ICACHE->CRR0) + (1U * Region))), \ + ICACHE_CRRx_MSTSEL)); +} + +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup ICACHE_LL_EF_REGION_Init Region Initialization functions + * @{ + */ + +void LL_ICACHE_ConfigRegion(uint32_t Region, const LL_ICACHE_RegionTypeDef *const pICACHE_RegionStruct); + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +#endif /* ICACHE_CRRx_REN */ +/** + * @} + */ + +/** + * @} + */ + +#endif /* ICACHE */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_LL_ICACHE_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_iwdg.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_iwdg.h new file mode 100644 index 0000000000..dd94516983 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_iwdg.h @@ -0,0 +1,453 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_iwdg.h + * @author MCD Application Team + * @brief Header file of IWDG LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_LL_IWDG_H +#define STM32H5xx_LL_IWDG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined(IWDG) + +/** @defgroup IWDG_LL IWDG + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup IWDG_LL_Private_Constants IWDG Private Constants + * @{ + */ +#define LL_IWDG_KEY_RELOAD 0x0000AAAAU /*!< IWDG Reload Counter Enable */ +#define LL_IWDG_KEY_ENABLE 0x0000CCCCU /*!< IWDG Peripheral Enable */ +#define LL_IWDG_KEY_WR_ACCESS_ENABLE 0x00005555U /*!< IWDG KR Write Access Enable */ +#define LL_IWDG_KEY_WR_ACCESS_DISABLE 0x00000000U /*!< IWDG KR Write Access Disable */ +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup IWDG_LL_Exported_Constants IWDG Exported Constants + * @{ + */ + +/** @defgroup IWDG_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_IWDG_ReadReg function + * @{ + */ +#define LL_IWDG_SR_PVU IWDG_SR_PVU /*!< Watchdog prescaler value update */ +#define LL_IWDG_SR_RVU IWDG_SR_RVU /*!< Watchdog counter reload value update */ +#define LL_IWDG_SR_WVU IWDG_SR_WVU /*!< Watchdog counter window value update */ +/** + * @} + */ + +/** @defgroup IWDG_LL_EC_PRESCALER Prescaler Divider + * @{ + */ +#define LL_IWDG_PRESCALER_4 0x00000000U /*!< Divider by 4 */ +#define LL_IWDG_PRESCALER_8 (IWDG_PR_PR_0) /*!< Divider by 8 */ +#define LL_IWDG_PRESCALER_16 (IWDG_PR_PR_1) /*!< Divider by 16 */ +#define LL_IWDG_PRESCALER_32 (IWDG_PR_PR_1 | IWDG_PR_PR_0) /*!< Divider by 32 */ +#define LL_IWDG_PRESCALER_64 (IWDG_PR_PR_2) /*!< Divider by 64 */ +#define LL_IWDG_PRESCALER_128 (IWDG_PR_PR_2 | IWDG_PR_PR_0) /*!< Divider by 128 */ +#define LL_IWDG_PRESCALER_256 (IWDG_PR_PR_2 | IWDG_PR_PR_1) /*!< Divider by 256 */ +#define LL_IWDG_PRESCALER_512 (IWDG_PR_PR_2 | IWDG_PR_PR_1 | IWDG_PR_PR_0) /*!< Divider by 512 */ +#define LL_IWDG_PRESCALER_1024 IWDG_PR_PR_3 /*!< Divider by 1024 */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup IWDG_LL_Exported_Macros IWDG Exported Macros + * @{ + */ + +/** @defgroup IWDG_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in IWDG register + * @param __INSTANCE__ IWDG Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_IWDG_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in IWDG register + * @param __INSTANCE__ IWDG Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_IWDG_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) +/** + * @} + */ + +/** + * @} + */ + + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup IWDG_LL_Exported_Functions IWDG Exported Functions + * @{ + */ +/** @defgroup IWDG_LL_EF_Configuration Configuration + * @{ + */ + +/** + * @brief Start the Independent Watchdog + * @note Except if the hardware watchdog option is selected + * @rmtoll KR KEY LL_IWDG_Enable + * @param IWDGx IWDG Instance + * @retval None + */ +__STATIC_INLINE void LL_IWDG_Enable(IWDG_TypeDef *IWDGx) +{ + WRITE_REG(IWDGx->KR, LL_IWDG_KEY_ENABLE); +} + +/** + * @brief Reloads IWDG counter with value defined in the reload register + * @rmtoll KR KEY LL_IWDG_ReloadCounter + * @param IWDGx IWDG Instance + * @retval None + */ +__STATIC_INLINE void LL_IWDG_ReloadCounter(IWDG_TypeDef *IWDGx) +{ + WRITE_REG(IWDGx->KR, LL_IWDG_KEY_RELOAD); +} + +/** + * @brief Enable write access to IWDG_PR, IWDG_RLR and IWDG_WINR registers + * @rmtoll KR KEY LL_IWDG_EnableWriteAccess + * @param IWDGx IWDG Instance + * @retval None + */ +__STATIC_INLINE void LL_IWDG_EnableWriteAccess(IWDG_TypeDef *IWDGx) +{ + WRITE_REG(IWDGx->KR, LL_IWDG_KEY_WR_ACCESS_ENABLE); +} + +/** + * @brief Disable write access to IWDG_PR, IWDG_RLR and IWDG_WINR registers + * @rmtoll KR KEY LL_IWDG_DisableWriteAccess + * @param IWDGx IWDG Instance + * @retval None + */ +__STATIC_INLINE void LL_IWDG_DisableWriteAccess(IWDG_TypeDef *IWDGx) +{ + WRITE_REG(IWDGx->KR, LL_IWDG_KEY_WR_ACCESS_DISABLE); +} + +/** + * @brief Select the prescaler of the IWDG + * @rmtoll PR PR LL_IWDG_SetPrescaler + * @param IWDGx IWDG Instance + * @param Prescaler This parameter can be one of the following values: + * @arg @ref LL_IWDG_PRESCALER_4 + * @arg @ref LL_IWDG_PRESCALER_8 + * @arg @ref LL_IWDG_PRESCALER_16 + * @arg @ref LL_IWDG_PRESCALER_32 + * @arg @ref LL_IWDG_PRESCALER_64 + * @arg @ref LL_IWDG_PRESCALER_128 + * @arg @ref LL_IWDG_PRESCALER_256 + * @arg @ref LL_IWDG_PRESCALER_512 + * @arg @ref LL_IWDG_PRESCALER_1024 + * @retval None + */ +__STATIC_INLINE void LL_IWDG_SetPrescaler(IWDG_TypeDef *IWDGx, uint32_t Prescaler) +{ + WRITE_REG(IWDGx->PR, IWDG_PR_PR & Prescaler); +} + +/** + * @brief Get the selected prescaler of the IWDG + * @rmtoll PR PR LL_IWDG_GetPrescaler + * @param IWDGx IWDG Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_IWDG_PRESCALER_4 + * @arg @ref LL_IWDG_PRESCALER_8 + * @arg @ref LL_IWDG_PRESCALER_16 + * @arg @ref LL_IWDG_PRESCALER_32 + * @arg @ref LL_IWDG_PRESCALER_64 + * @arg @ref LL_IWDG_PRESCALER_128 + * @arg @ref LL_IWDG_PRESCALER_256 + * @arg @ref LL_IWDG_PRESCALER_512 + * @arg @ref LL_IWDG_PRESCALER_1024 + */ +__STATIC_INLINE uint32_t LL_IWDG_GetPrescaler(const IWDG_TypeDef *IWDGx) +{ + return (READ_REG(IWDGx->PR)); +} + +/** + * @brief Specify the IWDG down-counter reload value + * @rmtoll RLR RL LL_IWDG_SetReloadCounter + * @param IWDGx IWDG Instance + * @param Counter Value between Min_Data=0 and Max_Data=0x0FFF + * @retval None + */ +__STATIC_INLINE void LL_IWDG_SetReloadCounter(IWDG_TypeDef *IWDGx, uint32_t Counter) +{ + WRITE_REG(IWDGx->RLR, IWDG_RLR_RL & Counter); +} + +/** + * @brief Get the specified IWDG down-counter reload value + * @rmtoll RLR RL LL_IWDG_GetReloadCounter + * @param IWDGx IWDG Instance + * @retval Value between Min_Data=0 and Max_Data=0x0FFF + */ +__STATIC_INLINE uint32_t LL_IWDG_GetReloadCounter(const IWDG_TypeDef *IWDGx) +{ + return (READ_REG(IWDGx->RLR)); +} + +/** + * @brief Specify high limit of the window value to be compared to the down-counter. + * @rmtoll WINR WIN LL_IWDG_SetWindow + * @param IWDGx IWDG Instance + * @param Window Value between Min_Data=0 and Max_Data=0x0FFF + * @retval None + */ +__STATIC_INLINE void LL_IWDG_SetWindow(IWDG_TypeDef *IWDGx, uint32_t Window) +{ + WRITE_REG(IWDGx->WINR, IWDG_WINR_WIN & Window); +} + +/** + * @brief Get the high limit of the window value specified. + * @rmtoll WINR WIN LL_IWDG_GetWindow + * @param IWDGx IWDG Instance + * @retval Value between Min_Data=0 and Max_Data=0x0FFF + */ +__STATIC_INLINE uint32_t LL_IWDG_GetWindow(const IWDG_TypeDef *IWDGx) +{ + return (READ_REG(IWDGx->WINR)); +} + +/** + * @} + */ + +/** @defgroup IWDG_LL_EF_IT_Management IT_Management + * @{ + */ + +/** + * @brief Specify comparator value that will be used to trig Early Wakeup interrupt + * @rmtoll EWCR EWIT LL_IWDG_SetEwiTime + * @param IWDGx IWDG Instance + * @param Time Value between Min_Data=0 and Max_Data=0x0FFF + * @retval None + */ +__STATIC_INLINE void LL_IWDG_SetEwiTime(IWDG_TypeDef *IWDGx, uint32_t Time) +{ + MODIFY_REG(IWDGx->EWCR, IWDG_EWCR_EWIT, Time); +} + +/** + * @brief Get the Early Wakeup interrupt comparator value + * @rmtoll EWCR EWIT LL_IWDG_GetEwiTime + * @param IWDGx IWDG Instance + * @retval Value between Min_Data=0 and Max_Data=0x0FFF + */ +__STATIC_INLINE uint32_t LL_IWDG_GetEwiTime(const IWDG_TypeDef *IWDGx) +{ + return (READ_BIT(IWDGx->EWCR, IWDG_EWCR_EWIT)); +} + +/** + * @brief Enable Early wakeup interrupt + * @rmtoll EWCR EWIE LL_IWDG_EnableIT_EWI + * @param IWDGx IWDG Instance + * @retval None + */ +__STATIC_INLINE void LL_IWDG_EnableIT_EWI(IWDG_TypeDef *IWDGx) +{ + SET_BIT(IWDGx->EWCR, IWDG_EWCR_EWIE); +} + +/** + * @brief Disable Early wakeup interrupt + * @rmtoll EWCR EWIE LL_IWDG_DisableIT_EWI + * @param IWDGx IWDG Instance + * @retval None + */ +__STATIC_INLINE void LL_IWDG_DisableIT_EWI(IWDG_TypeDef *IWDGx) +{ + CLEAR_BIT(IWDGx->EWCR, IWDG_EWCR_EWIE); +} + +/** + * @brief Indicates whether Early wakeup interrupt is enable + * @rmtoll EWCR EWIE LL_IWDG_IsEnabledIT_EWI + * @param IWDGx IWDG Instance + * @retval None + */ +__STATIC_INLINE uint32_t LL_IWDG_IsEnabledIT_EWI(const IWDG_TypeDef *IWDGx) +{ + return ((READ_BIT(IWDGx->EWCR, IWDG_EWCR_EWIE) == (IWDG_EWCR_EWIE)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup IWDG_LL_EF_FLAG_Management FLAG_Management + * @{ + */ + +/** + * @brief Check if flag Prescaler Value Update is set or not + * @rmtoll SR PVU LL_IWDG_IsActiveFlag_PVU + * @param IWDGx IWDG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_IWDG_IsActiveFlag_PVU(const IWDG_TypeDef *IWDGx) +{ + return ((READ_BIT(IWDGx->SR, IWDG_SR_PVU) == (IWDG_SR_PVU)) ? 1UL : 0UL); +} + +/** + * @brief Check if flag Reload Value Update is set or not + * @rmtoll SR RVU LL_IWDG_IsActiveFlag_RVU + * @param IWDGx IWDG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_IWDG_IsActiveFlag_RVU(const IWDG_TypeDef *IWDGx) +{ + return ((READ_BIT(IWDGx->SR, IWDG_SR_RVU) == (IWDG_SR_RVU)) ? 1UL : 0UL); +} + +/** + * @brief Check if flag Window Value Update is set or not + * @rmtoll SR WVU LL_IWDG_IsActiveFlag_WVU + * @param IWDGx IWDG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_IWDG_IsActiveFlag_WVU(const IWDG_TypeDef *IWDGx) +{ + return ((READ_BIT(IWDGx->SR, IWDG_SR_WVU) == (IWDG_SR_WVU)) ? 1UL : 0UL); +} + +/** + * @brief Check if flag EWI Value Update is set or not + * @rmtoll SR EVU LL_IWDG_IsActiveFlag_EWU + * @param IWDGx IWDG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_IWDG_IsActiveFlag_EWU(const IWDG_TypeDef *IWDGx) +{ + return ((READ_BIT(IWDGx->SR, IWDG_SR_EWU) == (IWDG_SR_EWU)) ? 1UL : 0UL); +} + +/** + * @brief Check if all flags Prescaler, Reload, Window & Early Interrupt Value Update are reset or not + * @rmtoll SR PVU LL_IWDG_IsReady\n + * SR RVU LL_IWDG_IsReady\n + * SR WVU LL_IWDG_IsReady\n + * SR EWU LL_IWDG_IsReady + * @param IWDGx IWDG Instance + * @retval State of bits (1 or 0). + */ +__STATIC_INLINE uint32_t LL_IWDG_IsReady(const IWDG_TypeDef *IWDGx) +{ + return ((READ_BIT(IWDGx->SR, IWDG_SR_PVU | IWDG_SR_RVU | IWDG_SR_WVU | IWDG_SR_EWU) == 0U) ? 1UL : 0UL); +} + +/** + * @brief Check if IWDG has been started or not + * @rmtoll SR ONF LL_IWDG_IsActiveFlag_ONF + * @param IWDGx IWDG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_IWDG_IsActiveFlag_ONF(const IWDG_TypeDef *IWDGx) +{ + return ((READ_BIT(IWDGx->SR, IWDG_SR_ONF) == (IWDG_SR_ONF)) ? 1UL : 0UL); +} + +/** + * @brief Check if Early Wakeup interrupt flag is set or not + * @rmtoll SR EWIF LL_IWDG_IsActiveFlag_EWIF + * @param IWDGx IWDG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_IWDG_IsActiveFlag_EWIF(const IWDG_TypeDef *IWDGx) +{ + return ((READ_BIT(IWDGx->SR, IWDG_SR_EWIF) == (IWDG_SR_EWIF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Early Wakeup interrupt flag + * @rmtoll EWCR EWIC LL_IWDG_ClearFlag_EWIF + * @param IWDGx IWDG Instance + * @retval None + */ +__STATIC_INLINE void LL_IWDG_ClearFlag_EWIF(IWDG_TypeDef *IWDGx) +{ + SET_BIT(IWDGx->EWCR, IWDG_EWCR_EWIC); +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* IWDG */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_LL_IWDG_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_lptim.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_lptim.h new file mode 100644 index 0000000000..15bb66af06 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_lptim.h @@ -0,0 +1,2530 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_lptim.h + * @author MCD Application Team + * @brief Header file of LPTIM LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_LL_LPTIM_H +#define STM32H5xx_LL_LPTIM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (LPTIM1) || defined (LPTIM2) || defined (LPTIM3) || defined (LPTIM4) || defined (LPTIM5) || defined (LPTIM6) + +/** @defgroup LPTIM_LL LPTIM + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/** @defgroup LPTIM_LL_Private_variables LPTIM Private variables + * @{ + */ + +static const uint8_t LL_LPTIM_SHIFT_TAB_CCxP[] = +{ + 0U, /* CC1P */ + 16U /* CC2P */ +}; + +static const uint8_t LL_LPTIM_SHIFT_TAB_ICxF[] = +{ + 0U, /* IC1F */ + 16U /* IC2F */ +}; + +static const uint8_t LL_LPTIM_SHIFT_TAB_ICxPSC[] = +{ + 0U, /* IC1PSC */ + 16U /* IC2PSC */ +}; + +static const uint8_t LL_LPTIM_SHIFT_TAB_CCxSEL[] = +{ + 0U, /* CC1SEL */ + 16U /* CC2SEL */ +}; + +static const uint8_t LL_LPTIM_SHIFT_TAB_CCxE[] = +{ + LPTIM_CCMR1_CC1E_Pos, /* CC1E */ + LPTIM_CCMR1_CC2E_Pos /* CC2E */ +}; + +static const uint8_t LL_LPTIM_OFFSET_TAB_ICx[8][4] = +{ + {2, 7, 9, 13}, + {3, 5, 6, 8}, + {2, 3, 4, 5}, + {2, 2, 3, 3}, + {2, 2, 2, 2}, + {2, 2, 2, 2}, + {2, 2, 2, 2}, + {2, 2, 2, 2} + +}; + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** Legacy definitions for compatibility purpose +@cond 0 + */ +#define LL_LPTIM_SetCompareCH1 LL_LPTIM_OC_SetCompareCH1 +#define LL_LPTIM_SetCompareCH2 LL_LPTIM_OC_SetCompareCH2 +#define LL_LPTIM_GetCompareCH1 LL_LPTIM_OC_GetCompareCH1 +#define LL_LPTIM_GetCompareCH2 LL_LPTIM_OC_GetCompareCH2 +/** +@endcond + */ + +/* Private macros ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup LPTIM_LL_Private_Macros LPTIM Private Macros + * @{ + */ +/** + * @} + */ +#endif /*USE_FULL_LL_DRIVER*/ + +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup LPTIM_LL_ES_INIT LPTIM Exported Init structure + * @{ + */ + +/** + * @brief LPTIM Init structure definition + */ +typedef struct +{ + uint32_t ClockSource; /*!< Specifies the source of the clock used by the LPTIM instance. + This parameter can be a value of @ref LPTIM_LL_EC_CLK_SOURCE. + + This feature can be modified afterwards using unitary + function @ref LL_LPTIM_SetClockSource().*/ + + uint32_t Prescaler; /*!< Specifies the prescaler division ratio. + This parameter can be a value of @ref LPTIM_LL_EC_PRESCALER. + + This feature can be modified afterwards using using unitary + function @ref LL_LPTIM_SetPrescaler().*/ + + uint32_t Waveform; /*!< Specifies the waveform shape. + This parameter can be a value of @ref LPTIM_LL_EC_OUTPUT_WAVEFORM. + + This feature can be modified afterwards using unitary + function @ref LL_LPTIM_SetWaveform().*/ +} LL_LPTIM_InitTypeDef; + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup LPTIM_LL_Exported_Constants LPTIM Exported Constants + * @{ + */ + +/** @defgroup LPTIM_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_LPTIM_ReadReg function + * @{ + */ +#define LL_LPTIM_ISR_CMP1OK LPTIM_ISR_CMP1OK /*!< Compare register 1 update OK */ +#define LL_LPTIM_ISR_CMP2OK LPTIM_ISR_CMP2OK /*!< Compare register 2 update OK */ +#define LL_LPTIM_ISR_CC1IF LPTIM_ISR_CC1IF /*!< Capture/Compare 1 interrupt flag */ +#define LL_LPTIM_ISR_CC2IF LPTIM_ISR_CC2IF /*!< Capture/Compare 2 interrupt flag */ +#define LL_LPTIM_ISR_CC1OF LPTIM_ISR_CC1OF /*!< Capture/Compare 1 over-capture flag */ +#define LL_LPTIM_ISR_CC2OF LPTIM_ISR_CC2OF /*!< Capture/Compare 2 over-capture flag */ +#define LL_LPTIM_ISR_DIEROK LPTIM_ISR_DIEROK /*!< Interrupt enable register update OK */ +#define LL_LPTIM_ISR_ARRM LPTIM_ISR_ARRM /*!< Autoreload match */ +#define LL_LPTIM_ISR_EXTTRIG LPTIM_ISR_EXTTRIG /*!< External trigger edge event */ +#define LL_LPTIM_ISR_ARROK LPTIM_ISR_ARROK /*!< Autoreload register update OK */ +#define LL_LPTIM_ISR_UP LPTIM_ISR_UP /*!< Counter direction change down to up */ +#define LL_LPTIM_ISR_DOWN LPTIM_ISR_DOWN /*!< Counter direction change up to down */ +#define LL_LPTIM_ISR_UE LPTIM_ISR_UE /*!< Update event */ +#define LL_LPTIM_ISR_REPOK LPTIM_ISR_REPOK /*!< Repetition register update OK */ +/** + * @} + */ + +/** @defgroup LPTIM_LL_EC_IT IT Defines + * @brief IT defines which can be used with LL_LPTIM_ReadReg and LL_LPTIM_WriteReg functions + * @{ + */ +#define LL_LPTIM_DIER_CMP1OKIE LPTIM_DIER_CMP1OKIE /*!< Compare register 1 update OK */ +#define LL_LPTIM_DIER_CMP2OKIE LPTIM_DIER_CMP2OKIE /*!< Compare register 2 update OK */ +#define LL_LPTIM_DIER_CC1IFIE LPTIM_DIER_CC1IE /*!< Capture/Compare 1 interrupt flag */ +#define LL_LPTIM_DIER_CC2IFIE LPTIM_DIER_CC2IE /*!< Capture/Compare 2 interrupt flag */ +#define LL_LPTIM_DIER_CC1OFIE LPTIM_DIER_CC1OIE /*!< Capture/Compare 1 over-capture flag */ +#define LL_LPTIM_DIER_CC2OFIE LPTIM_DIER_CC2OIE /*!< Capture/Compare 2 over-capture flag */ +#define LL_LPTIM_DIER_ARRMIE LPTIM_DIER_ARRMIE /*!< Autoreload match */ +#define LL_LPTIM_DIER_EXTTRIGIE LPTIM_DIER_EXTTRIGIE /*!< External trigger edge event */ +#define LL_LPTIM_DIER_ARROKIE LPTIM_DIER_ARROKIE /*!< Autoreload register update OK */ +#define LL_LPTIM_DIER_UPIE LPTIM_DIER_UPIE /*!< Counter direction change down to up */ +#define LL_LPTIM_DIER_DOWNIE LPTIM_DIER_DOWNIE /*!< Counter direction change up to down */ +#define LL_LPTIM_DIER_UEIE LPTIM_DIER_UEIE /*!< Update event */ +#define LL_LPTIM_DIER_REPOKIE LPTIM_DIER_REPOKIE /*!< Repetition register update OK */ +/** + * @} + */ + +/** @defgroup LPTIM_LL_EC_OPERATING_MODE Operating Mode + * @{ + */ +#define LL_LPTIM_OPERATING_MODE_CONTINUOUS LPTIM_CR_CNTSTRT /*!__REG__, (__VALUE__)) + +/** + * @brief Read a value in LPTIM register + * @param __INSTANCE__ LPTIM Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_LPTIM_ReadReg(__INSTANCE__, __REG__) READ_REG((__INSTANCE__)->__REG__) + +/** + * @brief LPTimer Input Capture Get Offset(in counter step unit) + * @note The real capture value corresponding to the input capture trigger can be calculated using + * the formula hereafter : Real capture value = captured(LPTIM_CCRx) - offset + * The Offset value is depending on the glitch filter value for the channel + * and the value of the prescaler for the kernel clock. + * Please check Errata Sheet V1_8 for more details under "variable latency + * on input capture channel" section. + * @param __PSC__ This parameter can be one of the following values: + * @arg @ref LL_LPTIM_PRESCALER_DIV1 + * @arg @ref LL_LPTIM_PRESCALER_DIV2 + * @arg @ref LL_LPTIM_PRESCALER_DIV4 + * @arg @ref LL_LPTIM_PRESCALER_DIV8 + * @arg @ref LL_LPTIM_PRESCALER_DIV16 + * @arg @ref LL_LPTIM_PRESCALER_DIV32 + * @arg @ref LL_LPTIM_PRESCALER_DIV64 + * @arg @ref LL_LPTIM_PRESCALER_DIV128 + * @param __FLT__ This parameter can be one of the following values: + * @arg @ref LL_LPTIM_ICFLT_CLOCK_DIV1 + * @arg @ref LL_LPTIM_ICFLT_CLOCK_DIV2 + * @arg @ref LL_LPTIM_ICFLT_CLOCK_DIV4 + * @arg @ref LL_LPTIM_ICFLT_CLOCK_DIV8 + * @retval offset value + */ +#define LL_LPTIM_IC_GET_OFFSET(__PSC__, __FLT__) LL_LPTIM_OFFSET_TAB_ICx\ + [((__PSC__) & LPTIM_CFGR_PRESC_Msk) >> LPTIM_CFGR_PRESC_Pos]\ + [((__FLT__) & LPTIM_CCMR1_IC1F_Msk) >> LPTIM_CCMR1_IC1F_Pos] +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup LPTIM_LL_Exported_Functions LPTIM Exported Functions + * @{ + */ + +/** Legacy definitions for compatibility purpose +@cond 0 + */ +#define LL_LPTIM_ClearFLAG_CMPM LL_LPTIM_ClearFlag_CMPM +#define LL_LPTIM_ClearFLAG_CC1 LL_LPTIM_ClearFlag_CC1 +#define LL_LPTIM_ClearFLAG_CC2 LL_LPTIM_ClearFlag_CC2 +#define LL_LPTIM_ClearFLAG_CC1O LL_LPTIM_ClearFlag_CC1O +#define LL_LPTIM_ClearFLAG_CC2O LL_LPTIM_ClearFlag_CC2O +#define LL_LPTIM_ClearFLAG_ARRM LL_LPTIM_ClearFlag_ARRM +/** +@endcond + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup LPTIM_LL_EF_Init Initialisation and deinitialisation functions + * @{ + */ + +ErrorStatus LL_LPTIM_DeInit(const LPTIM_TypeDef *LPTIMx); +void LL_LPTIM_StructInit(LL_LPTIM_InitTypeDef *LPTIM_InitStruct); +ErrorStatus LL_LPTIM_Init(LPTIM_TypeDef *LPTIMx, const LL_LPTIM_InitTypeDef *LPTIM_InitStruct); +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** @defgroup LPTIM_LL_EF_LPTIM_Configuration LPTIM Configuration + * @{ + */ + +/** + * @brief Enable the LPTIM instance + * @note After setting the ENABLE bit, a delay of two counter clock is needed + * before the LPTIM instance is actually enabled. + * @rmtoll CR ENABLE LL_LPTIM_Enable + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_Enable(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->CR, LPTIM_CR_ENABLE); +} + +/** + * @brief Disable the LPTIM instance + * @rmtoll CR ENABLE LL_LPTIM_Disable + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_Disable(LPTIM_TypeDef *LPTIMx) +{ + CLEAR_BIT(LPTIMx->CR, LPTIM_CR_ENABLE); +} + +/** + * @brief Indicates whether the LPTIM instance is enabled. + * @rmtoll CR ENABLE LL_LPTIM_IsEnabled + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsEnabled(const LPTIM_TypeDef *LPTIMx) +{ + return (((READ_BIT(LPTIMx->CR, LPTIM_CR_ENABLE) == LPTIM_CR_ENABLE) ? 1UL : 0UL)); +} + +/** + * @brief Starts the LPTIM counter in the desired mode. + * @note LPTIM instance must be enabled before starting the counter. + * @note It is possible to change on the fly from One Shot mode to + * Continuous mode. + * @rmtoll CR CNTSTRT LL_LPTIM_StartCounter\n + * CR SNGSTRT LL_LPTIM_StartCounter + * @param LPTIMx Low-Power Timer instance + * @param OperatingMode This parameter can be one of the following values: + * @arg @ref LL_LPTIM_OPERATING_MODE_CONTINUOUS + * @arg @ref LL_LPTIM_OPERATING_MODE_ONESHOT + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_StartCounter(LPTIM_TypeDef *LPTIMx, uint32_t OperatingMode) +{ + MODIFY_REG(LPTIMx->CR, LPTIM_CR_CNTSTRT | LPTIM_CR_SNGSTRT, OperatingMode); +} + +/** + * @brief Enable reset after read. + * @note After calling this function any read access to LPTIM_CNT + * register will asynchronously reset the LPTIM_CNT register content. + * @rmtoll CR RSTARE LL_LPTIM_EnableResetAfterRead + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_EnableResetAfterRead(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->CR, LPTIM_CR_RSTARE); +} + +/** + * @brief Disable reset after read. + * @rmtoll CR RSTARE LL_LPTIM_DisableResetAfterRead + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_DisableResetAfterRead(LPTIM_TypeDef *LPTIMx) +{ + CLEAR_BIT(LPTIMx->CR, LPTIM_CR_RSTARE); +} + +/** + * @brief Indicate whether the reset after read feature is enabled. + * @rmtoll CR RSTARE LL_LPTIM_IsEnabledResetAfterRead + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsEnabledResetAfterRead(const LPTIM_TypeDef *LPTIMx) +{ + return (((READ_BIT(LPTIMx->CR, LPTIM_CR_RSTARE) == LPTIM_CR_RSTARE) ? 1UL : 0UL)); +} + +/** + * @brief Reset of the LPTIM_CNT counter register (synchronous). + * @note Due to the synchronous nature of this reset, it only takes + * place after a synchronization delay of 3 LPTIM core clock cycles + * (LPTIM core clock may be different from APB clock). + * @note COUNTRST is automatically cleared by hardware + * @rmtoll CR COUNTRST LL_LPTIM_ResetCounter\n + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_ResetCounter(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->CR, LPTIM_CR_COUNTRST); +} + +/** + * @brief Set the LPTIM registers update mode (enable/disable register preload) + * @note This function must be called when the LPTIM instance is disabled. + * @rmtoll CFGR PRELOAD LL_LPTIM_SetUpdateMode + * @param LPTIMx Low-Power Timer instance + * @param UpdateMode This parameter can be one of the following values: + * @arg @ref LL_LPTIM_UPDATE_MODE_IMMEDIATE + * @arg @ref LL_LPTIM_UPDATE_MODE_ENDOFPERIOD + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_SetUpdateMode(LPTIM_TypeDef *LPTIMx, uint32_t UpdateMode) +{ + MODIFY_REG(LPTIMx->CFGR, LPTIM_CFGR_PRELOAD, UpdateMode); +} + +/** + * @brief Get the LPTIM registers update mode + * @rmtoll CFGR PRELOAD LL_LPTIM_GetUpdateMode + * @param LPTIMx Low-Power Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPTIM_UPDATE_MODE_IMMEDIATE + * @arg @ref LL_LPTIM_UPDATE_MODE_ENDOFPERIOD + */ +__STATIC_INLINE uint32_t LL_LPTIM_GetUpdateMode(const LPTIM_TypeDef *LPTIMx) +{ + return (uint32_t)(READ_BIT(LPTIMx->CFGR, LPTIM_CFGR_PRELOAD)); +} + +/** + * @brief Set the auto reload value + * @note The LPTIMx_ARR register content must only be modified when the LPTIM is enabled + * @note After a write to the LPTIMx_ARR register a new write operation to the + * same register can only be performed when the previous write operation + * is completed. Any successive write before the ARROK flag is set, will + * lead to unpredictable results. + * @note autoreload value be strictly greater than the compare value. + * @rmtoll ARR ARR LL_LPTIM_SetAutoReload + * @param LPTIMx Low-Power Timer instance + * @param AutoReload Value between Min_Data=0x0001 and Max_Data=0xFFFF + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_SetAutoReload(LPTIM_TypeDef *LPTIMx, uint32_t AutoReload) +{ + MODIFY_REG(LPTIMx->ARR, LPTIM_ARR_ARR, AutoReload); +} + +/** + * @brief Get actual auto reload value + * @rmtoll ARR ARR LL_LPTIM_GetAutoReload + * @param LPTIMx Low-Power Timer instance + * @retval AutoReload Value between Min_Data=0x0001 and Max_Data=0xFFFF + */ +__STATIC_INLINE uint32_t LL_LPTIM_GetAutoReload(const LPTIM_TypeDef *LPTIMx) +{ + return (uint32_t)(READ_BIT(LPTIMx->ARR, LPTIM_ARR_ARR)); +} + +/** + * @brief Set the repetition value + * @note The LPTIMx_RCR register content must only be modified when the LPTIM is enabled + * @rmtoll RCR REP LL_LPTIM_SetRepetition + * @param LPTIMx Low-Power Timer instance + * @param Repetition Value between Min_Data=0x00 and Max_Data=0xFF + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_SetRepetition(LPTIM_TypeDef *LPTIMx, uint32_t Repetition) +{ + MODIFY_REG(LPTIMx->RCR, LPTIM_RCR_REP, Repetition); +} + +/** + * @brief Get the repetition value + * @rmtoll RCR REP LL_LPTIM_GetRepetition + * @param LPTIMx Low-Power Timer instance + * @retval Repetition Value between Min_Data=0x00 and Max_Data=0xFF + */ +__STATIC_INLINE uint32_t LL_LPTIM_GetRepetition(const LPTIM_TypeDef *LPTIMx) +{ + return (uint32_t)(READ_BIT(LPTIMx->RCR, LPTIM_RCR_REP)); +} + +/** + * @brief Enable capture/compare channel. + * @rmtoll CCMR1 CC1E LL_LPTIM_CC_EnableChannel\n + * CCMR1 CC2E LL_LPTIM_CC_EnableChannel + * @param LPTIMx LPTimer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_LPTIM_CHANNEL_CH1 + * @arg @ref LL_LPTIM_CHANNEL_CH2 + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_CC_EnableChannel(LPTIM_TypeDef *LPTIMx, uint32_t Channel) +{ + SET_BIT(LPTIMx->CCMR1, 0x1UL << LL_LPTIM_SHIFT_TAB_CCxE[Channel]); +} + +/** + * @brief Disable capture/compare channel. + * @rmtoll CCMR1 CC1E LL_LPTIM_CC_DisableChannel\n + * CCMR1 CC2E LL_LPTIM_CC_DisableChannel + * @param LPTIMx LPTimer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_LPTIM_CHANNEL_CH1 + * @arg @ref LL_LPTIM_CHANNEL_CH2 + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_CC_DisableChannel(LPTIM_TypeDef *LPTIMx, uint32_t Channel) +{ + CLEAR_BIT(LPTIMx->CCMR1, 0x1UL << LL_LPTIM_SHIFT_TAB_CCxE[Channel]); +} + +/** + * @brief Indicate whether channel is enabled. + * @rmtoll CCMR1 CC1E LL_LPTIM_CC_IsEnabledChannel\n + * CCMR1 CC2E LL_LPTIM_CC_IsEnabledChannel + * @param LPTIMx LPTimer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_LPTIM_CHANNEL_CH1 + * @arg @ref LL_LPTIM_CHANNEL_CH2 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_CC_IsEnabledChannel(const LPTIM_TypeDef *LPTIMx, uint32_t Channel) +{ + return ((READ_BIT(LPTIMx->CCMR1, 0x1UL << LL_LPTIM_SHIFT_TAB_CCxE[Channel]) == \ + (0x1UL << LL_LPTIM_SHIFT_TAB_CCxE[Channel])) ? 1UL : 0UL); + +} + +/** + * @brief Set the compare value + * @note After a write to the LPTIMx_CCR1 register a new write operation to the + * same register can only be performed when the previous write operation + * is completed. Any successive write before the CMP1OK flag is set, will + * lead to unpredictable results. + * @rmtoll CCR1 CCR1 LL_LPTIM_OC_SetCompareCH1 + * @param LPTIMx Low-Power Timer instance + * @param CompareValue Value between Min_Data=0x00 and Max_Data=0xFFFF + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_OC_SetCompareCH1(LPTIM_TypeDef *LPTIMx, uint32_t CompareValue) +{ + MODIFY_REG(LPTIMx->CCR1, LPTIM_CCR1_CCR1, CompareValue); +} + +/** + * @brief Get actual compare value + * @rmtoll CCR1 CCR1 LL_LPTIM_OC_GetCompareCH1 + * @param LPTIMx Low-Power Timer instance + * @retval CompareValue Value between Min_Data=0x00 and Max_Data=0xFFFF + */ +__STATIC_INLINE uint32_t LL_LPTIM_OC_GetCompareCH1(const LPTIM_TypeDef *LPTIMx) +{ + return (uint32_t)(READ_BIT(LPTIMx->CCR1, LPTIM_CCR1_CCR1)); +} + +/** + * @brief Set the compare value + * @note After a write to the LPTIMx_CCR2 register a new write operation to the + * same register can only be performed when the previous write operation + * is completed. Any successive write before the CMP2OK flag is set, will + * lead to unpredictable results. + * @rmtoll CCR2 CCR2 LL_LPTIM_OC_SetCompareCH2 + * @param LPTIMx Low-Power Timer instance + * @param CompareValue Value between Min_Data=0x00 and Max_Data=0xFFFF + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_OC_SetCompareCH2(LPTIM_TypeDef *LPTIMx, uint32_t CompareValue) +{ + MODIFY_REG(LPTIMx->CCR2, LPTIM_CCR2_CCR2, CompareValue); +} + +/** + * @brief Get actual compare value + * @rmtoll CCR2 CCR2 LL_LPTIM_OC_GetCompareCH2 + * @param LPTIMx Low-Power Timer instance + * @retval CompareValue Value between Min_Data=0x00 and Max_Data=0xFFFF + */ +__STATIC_INLINE uint32_t LL_LPTIM_OC_GetCompareCH2(const LPTIM_TypeDef *LPTIMx) +{ + return (uint32_t)(READ_BIT(LPTIMx->CCR2, LPTIM_CCR2_CCR2)); +} + +/** + * @brief Get actual counter value + * @note When the LPTIM instance is running with an asynchronous clock, reading + * the LPTIMx_CNT register may return unreliable values. So in this case + * it is necessary to perform two consecutive read accesses and verify + * that the two returned values are identical. + * @rmtoll CNT CNT LL_LPTIM_GetCounter + * @param LPTIMx Low-Power Timer instance + * @retval Counter value + */ +__STATIC_INLINE uint32_t LL_LPTIM_GetCounter(const LPTIM_TypeDef *LPTIMx) +{ + return (uint32_t)(READ_BIT(LPTIMx->CNT, LPTIM_CNT_CNT)); +} + +/** + * @brief Set the counter mode (selection of the LPTIM counter clock source). + * @note The counter mode can be set only when the LPTIM instance is disabled. + * @rmtoll CFGR COUNTMODE LL_LPTIM_SetCounterMode + * @param LPTIMx Low-Power Timer instance + * @param CounterMode This parameter can be one of the following values: + * @arg @ref LL_LPTIM_COUNTER_MODE_INTERNAL + * @arg @ref LL_LPTIM_COUNTER_MODE_EXTERNAL + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_SetCounterMode(LPTIM_TypeDef *LPTIMx, uint32_t CounterMode) +{ + MODIFY_REG(LPTIMx->CFGR, LPTIM_CFGR_COUNTMODE, CounterMode); +} + +/** + * @brief Get the counter mode + * @rmtoll CFGR COUNTMODE LL_LPTIM_GetCounterMode + * @param LPTIMx Low-Power Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPTIM_COUNTER_MODE_INTERNAL + * @arg @ref LL_LPTIM_COUNTER_MODE_EXTERNAL + */ +__STATIC_INLINE uint32_t LL_LPTIM_GetCounterMode(const LPTIM_TypeDef *LPTIMx) +{ + return (uint32_t)(READ_BIT(LPTIMx->CFGR, LPTIM_CFGR_COUNTMODE)); +} + +/** + * @brief Set waveform shape + * @rmtoll CFGR WAVE LL_LPTIM_SetWaveform + * @param LPTIMx Low-Power Timer instance + * @param Waveform This parameter can be one of the following values: + * @arg @ref LL_LPTIM_OUTPUT_WAVEFORM_PWM + * @arg @ref LL_LPTIM_OUTPUT_WAVEFORM_SETONCE + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_SetWaveform(LPTIM_TypeDef *LPTIMx, uint32_t Waveform) +{ + MODIFY_REG(LPTIMx->CFGR, LPTIM_CFGR_WAVE, Waveform); +} + +/** + * @brief Get actual waveform shape + * @rmtoll CFGR WAVE LL_LPTIM_GetWaveform + * @param LPTIMx Low-Power Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPTIM_OUTPUT_WAVEFORM_PWM + * @arg @ref LL_LPTIM_OUTPUT_WAVEFORM_SETONCE + */ +__STATIC_INLINE uint32_t LL_LPTIM_GetWaveform(const LPTIM_TypeDef *LPTIMx) +{ + return (uint32_t)(READ_BIT(LPTIMx->CFGR, LPTIM_CFGR_WAVE)); +} + +/** + * @brief Set the polarity of an output channel. + * @rmtoll CCMR1 CC1P LL_LPTIM_OC_SetPolarity\n + * @rmtoll CCMR1 CC2P LL_LPTIM_OC_SetPolarity\n + * @param LPTIMx Low-Power Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_LPTIM_CHANNEL_CH1 + * @arg @ref LL_LPTIM_CHANNEL_CH2 + * @param Polarity This parameter can be one of the following values: + * @arg @ref LL_LPTIM_OUTPUT_POLARITY_REGULAR + * @arg @ref LL_LPTIM_OUTPUT_POLARITY_INVERSE + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_OC_SetPolarity(LPTIM_TypeDef *LPTIMx, uint32_t Channel, uint32_t Polarity) +{ +#if defined(LPTIM4) + if (LPTIMx == LPTIM4) + { + MODIFY_REG(LPTIMx->CFGR, LPTIM_CFGR_WAVPOL, ((Polarity >> LPTIM_CCMR1_CC1P_Pos) << LPTIM_CFGR_WAVPOL_Pos)); + } + else +#endif /* LPTIM4 */ + { + MODIFY_REG(LPTIMx->CCMR1, (LPTIM_CCMR1_CC1P << LL_LPTIM_SHIFT_TAB_CCxP[Channel]), + (Polarity << LL_LPTIM_SHIFT_TAB_CCxP[Channel])); + } +} + +/** + * @brief Get the polarity of an output channel. + * @rmtoll CCMR1 CC1P LL_LPTIM_OC_GetPolarity\n + * @rmtoll CCMR1 CC2P LL_LPTIM_OC_GetPolarity\n + * @param LPTIMx Low-Power Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_LPTIM_CHANNEL_CH1 + * @arg @ref LL_LPTIM_CHANNEL_CH2 + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPTIM_OUTPUT_POLARITY_REGULAR + * @arg @ref LL_LPTIM_OUTPUT_POLARITY_INVERSE + */ +__STATIC_INLINE uint32_t LL_LPTIM_OC_GetPolarity(const LPTIM_TypeDef *LPTIMx, uint32_t Channel) +{ +#if defined(LPTIM4) + if (LPTIMx == LPTIM4) + { + return (uint32_t)((READ_BIT(LPTIMx->CFGR, LPTIM_CFGR_WAVPOL) >> LPTIM_CFGR_WAVPOL_Pos) << LPTIM_CCMR1_CC1P_Pos); + } + else +#endif /* LPTIM4 */ + { + return (uint32_t)(READ_BIT(LPTIMx->CCMR1, LPTIM_CCMR1_CC1P << LL_LPTIM_SHIFT_TAB_CCxP[Channel]) >> \ + LL_LPTIM_SHIFT_TAB_CCxP[Channel]); + } +} + +/** + * @brief Set actual prescaler division ratio. + * @note This function must be called when the LPTIM instance is disabled. + * @note When the LPTIM is configured to be clocked by an internal clock source + * and the LPTIM counter is configured to be updated by active edges + * detected on the LPTIM external Input1, the internal clock provided to + * the LPTIM must be not be prescaled. + * @rmtoll CFGR PRESC LL_LPTIM_SetPrescaler + * @param LPTIMx Low-Power Timer instance + * @param Prescaler This parameter can be one of the following values: + * @arg @ref LL_LPTIM_PRESCALER_DIV1 + * @arg @ref LL_LPTIM_PRESCALER_DIV2 + * @arg @ref LL_LPTIM_PRESCALER_DIV4 + * @arg @ref LL_LPTIM_PRESCALER_DIV8 + * @arg @ref LL_LPTIM_PRESCALER_DIV16 + * @arg @ref LL_LPTIM_PRESCALER_DIV32 + * @arg @ref LL_LPTIM_PRESCALER_DIV64 + * @arg @ref LL_LPTIM_PRESCALER_DIV128 + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_SetPrescaler(LPTIM_TypeDef *LPTIMx, uint32_t Prescaler) +{ + MODIFY_REG(LPTIMx->CFGR, LPTIM_CFGR_PRESC, Prescaler); +} + +/** + * @brief Get actual prescaler division ratio. + * @rmtoll CFGR PRESC LL_LPTIM_GetPrescaler + * @param LPTIMx Low-Power Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPTIM_PRESCALER_DIV1 + * @arg @ref LL_LPTIM_PRESCALER_DIV2 + * @arg @ref LL_LPTIM_PRESCALER_DIV4 + * @arg @ref LL_LPTIM_PRESCALER_DIV8 + * @arg @ref LL_LPTIM_PRESCALER_DIV16 + * @arg @ref LL_LPTIM_PRESCALER_DIV32 + * @arg @ref LL_LPTIM_PRESCALER_DIV64 + * @arg @ref LL_LPTIM_PRESCALER_DIV128 + */ +__STATIC_INLINE uint32_t LL_LPTIM_GetPrescaler(const LPTIM_TypeDef *LPTIMx) +{ + return (uint32_t)(READ_BIT(LPTIMx->CFGR, LPTIM_CFGR_PRESC)); +} + +/** + * @brief Set LPTIM input 1 source (default GPIO). + * @rmtoll CFGR2 IN1SEL LL_LPTIM_SetInput1Src + * @param LPTIMx Low-Power Timer instance + * @param Src This parameter can be one of the following values: + * @arg @ref LL_LPTIM_INPUT1_SRC_GPIO + @if STM32H503xx + * @arg @ref LL_LPTIM_INPUT1_SRC_COMP1 (*) + * @arg @ref LL_LPTIM_INPUT1SOURCE_LPTIM2_CH1 (*) + * @arg @ref LL_LPTIM_INPUT1SOURCE_LPTIM1_CH2 (*) + @endif + * (*) Value not defined for all devices + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_SetInput1Src(LPTIM_TypeDef *LPTIMx, uint32_t Src) +{ + MODIFY_REG(LPTIMx->CFGR2, LPTIM_CFGR2_IN1SEL, Src); +} + +/** + * @brief Set LPTIM input 2 source (default GPIO). + * @rmtoll CFGR2 IN2SEL LL_LPTIM_SetInput2Src + * @param LPTIMx Low-Power Timer instance + * @param Src This parameter can be one of the following values: + * @arg @ref LL_LPTIM_INPUT2_SRC_GPIO + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_SetInput2Src(LPTIM_TypeDef *LPTIMx, uint32_t Src) +{ + MODIFY_REG(LPTIMx->CFGR2, LPTIM_CFGR2_IN2SEL, Src); +} + +/** + * @brief Set LPTIM input source (default GPIO). + * @rmtoll CFGR2 IC1SEL LL_LPTIM_SetRemap + * @rmtoll CFGR2 IC2SEL LL_LPTIM_SetRemap + * @param LPTIMx Low-Power Timer instance + * @param Src This parameter can be one of the following values: + * @arg @ref LL_LPTIM_LPTIM1_IC1_RMP_GPIO + @if STM32H503xx + * @arg @ref LL_LPTIM_LPTIM1_IC1_RMP_COMP1 (*) + * @arg @ref LL_LPTIM_LPTIM1_IC1_RMP_EVENTOUT (*) + * @arg @ref LL_LPTIM_LPTIM1_IC1_RMP_MCO1 (*) + @endif + * @arg @ref LL_LPTIM_LPTIM1_IC2_RMP_GPIO + @if STM32H503xx + * @arg @ref LL_LPTIM_LPTIM1_IC2_RMP_LSI (*) + * @arg @ref LL_LPTIM_LPTIM1_IC2_RMP_LSE (*) + * @arg @ref LL_LPTIM_LPTIM1_IC2_RMP_HSE_1M (*) + @endif + * @arg @ref LL_LPTIM_LPTIM2_IC1_RMP_GPIO + @if STM32H503xx + * @arg @ref LL_LPTIM_LPTIM2_IC1_RMP_COMP1 (*) + * @arg @ref LL_LPTIM_LPTIM2_IC1_RMP_EVENTOUT (*) + * @arg @ref LL_LPTIM_LPTIM2_IC1_RMP_MCO2 (*) + @endif + * @arg @ref LL_LPTIM_LPTIM2_IC2_RMP_GPIO + * @arg @ref LL_LPTIM_LPTIM2_IC2_RMP_HSI_1024 + * @arg @ref LL_LPTIM_LPTIM2_IC2_RMP_CSI_128 + * @arg @ref LL_LPTIM_LPTIM2_IC2_RMP_HSI_8 + * @arg @ref LL_LPTIM_LPTIM3_IC1_RMP_GPIO (*) + * @arg @ref LL_LPTIM_LPTIM3_IC2_RMP_GPIO (*) + * @arg @ref LL_LPTIM_LPTIM5_IC1_RMP_GPIO (*) + * @arg @ref LL_LPTIM_LPTIM5_IC2_RMP_GPIO (*) + * @arg @ref LL_LPTIM_LPTIM6_IC1_RMP_GPIO (*) + * @arg @ref LL_LPTIM_LPTIM6_IC2_RMP_GPIO (*) + * + * (*) Value not defined in all devices. \n + * + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_SetRemap(LPTIM_TypeDef *LPTIMx, uint32_t Src) +{ + MODIFY_REG(LPTIMx->CFGR2, LPTIM_CFGR2_IC1SEL | LPTIM_CFGR2_IC2SEL, Src); +} + +/** + * @brief Set the polarity of IC channel 1. + * @rmtoll CCMR1 CC1P LL_LPTIM_IC_SetPolarity\n + * @rmtoll CCMR1 CC2P LL_LPTIM_IC_SetPolarity\n + * @param LPTIMx Low-Power Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_LPTIM_CHANNEL_CH1 + * @arg @ref LL_LPTIM_CHANNEL_CH2 + * @param Polarity This parameter can be one of the following values: + * @arg @ref LL_LPTIM_ICPOLARITY_RISING + * @arg @ref LL_LPTIM_ICPOLARITY_FALLING + * @arg @ref LL_LPTIM_ICPOLARITY_RISING_FALLING + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_IC_SetPolarity(LPTIM_TypeDef *LPTIMx, uint32_t Channel, uint32_t Polarity) +{ + MODIFY_REG(LPTIMx->CCMR1, LPTIM_CCMR1_CC1P << LL_LPTIM_SHIFT_TAB_CCxP[Channel], + Polarity << LL_LPTIM_SHIFT_TAB_CCxP[Channel]); +} + +/** + * @brief Get the polarity of IC channels. + * @rmtoll CCMR1 CC1P LL_LPTIM_IC_GetPolarity\n + * @rmtoll CCMR1 CC2P LL_LPTIM_IC_GetPolarity\n + * @param LPTIMx Low-Power Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_LPTIM_CHANNEL_CH1 + * @arg @ref LL_LPTIM_CHANNEL_CH2 + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPTIM_ICPOLARITY_RISING + * @arg @ref LL_LPTIM_ICPOLARITY_FALLING + * @arg @ref LL_LPTIM_ICPOLARITY_RISING_FALLING + */ +__STATIC_INLINE uint32_t LL_LPTIM_IC_GetPolarity(const LPTIM_TypeDef *LPTIMx, uint32_t Channel) +{ + return (uint32_t)((READ_BIT(LPTIMx->CCMR1, LPTIM_CCMR1_CC1P << LL_LPTIM_SHIFT_TAB_CCxP[Channel])) >> \ + LL_LPTIM_SHIFT_TAB_CCxP[Channel]); + +} + +/** + * @brief Set the filter of IC channels. + * @rmtoll CCMR1 IC1F LL_LPTIM_IC_SetFilter\n + * @rmtoll CCMR1 IC2F LL_LPTIM_IC_SetFilter\n + * @param LPTIMx Low-Power Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_LPTIM_CHANNEL_CH1 + * @arg @ref LL_LPTIM_CHANNEL_CH2 + * @param Filter This parameter can be one of the following values: + * @arg @ref LL_LPTIM_ICFLT_CLOCK_DIV1 + * @arg @ref LL_LPTIM_ICFLT_CLOCK_DIV2 + * @arg @ref LL_LPTIM_ICFLT_CLOCK_DIV4 + * @arg @ref LL_LPTIM_ICFLT_CLOCK_DIV8 + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_IC_SetFilter(LPTIM_TypeDef *LPTIMx, uint32_t Channel, uint32_t Filter) +{ + MODIFY_REG(LPTIMx->CCMR1, LPTIM_CCMR1_IC1F << LL_LPTIM_SHIFT_TAB_ICxF[Channel], + Filter << LL_LPTIM_SHIFT_TAB_ICxF[Channel]); +} + +/** + * @brief Get the filter of IC channels. + * @rmtoll CCMR1 IC1F LL_LPTIM_IC_GetFilter\n + * @rmtoll CCMR1 IC2F LL_LPTIM_IC_GetFilter\n + * @param LPTIMx Low-Power Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_LPTIM_CHANNEL_CH1 + * @arg @ref LL_LPTIM_CHANNEL_CH2 + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPTIM_ICFLT_CLOCK_DIV1 + * @arg @ref LL_LPTIM_ICFLT_CLOCK_DIV2 + * @arg @ref LL_LPTIM_ICFLT_CLOCK_DIV4 + * @arg @ref LL_LPTIM_ICFLT_CLOCK_DIV8 + */ +__STATIC_INLINE uint32_t LL_LPTIM_IC_GetFilter(const LPTIM_TypeDef *LPTIMx, uint32_t Channel) +{ + return (uint32_t)((READ_BIT(LPTIMx->CCMR1, LPTIM_CCMR1_IC1F << LL_LPTIM_SHIFT_TAB_ICxF[Channel])) >> \ + LL_LPTIM_SHIFT_TAB_ICxF[Channel]); +} + +/** + * @brief Set the prescaler of IC channels. + * @rmtoll CCMR1 IC1PSC LL_LPTIM_IC_SetPrescaler\n + * @rmtoll CCMR1 IC2PSC LL_LPTIM_IC_SetPrescaler\n + * @param LPTIMx Low-Power Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_LPTIM_CHANNEL_CH1 + * @arg @ref LL_LPTIM_CHANNEL_CH2 + * @param Prescaler This parameter can be one of the following values: + * @arg @ref LL_LPTIM_ICPSC_DIV1 + * @arg @ref LL_LPTIM_ICPSC_DIV2 + * @arg @ref LL_LPTIM_ICPSC_DIV4 + * @arg @ref LL_LPTIM_ICPSC_DIV8 + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_IC_SetPrescaler(LPTIM_TypeDef *LPTIMx, uint32_t Channel, uint32_t Prescaler) +{ + MODIFY_REG(LPTIMx->CCMR1, LPTIM_CCMR1_IC1PSC << LL_LPTIM_SHIFT_TAB_ICxPSC[Channel], + Prescaler << LL_LPTIM_SHIFT_TAB_ICxPSC[Channel]); +} + +/** + * @brief Get the prescaler of IC channels. + * @rmtoll CCMR1 IC1PSC LL_LPTIM_IC_GetPrescaler\n + * @rmtoll CCMR1 IC2PSC LL_LPTIM_IC_GetPrescaler\n + * @param LPTIMx Low-Power Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_LPTIM_CHANNEL_CH1 + * @arg @ref LL_LPTIM_CHANNEL_CH2 + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPTIM_ICPSC_DIV1 + * @arg @ref LL_LPTIM_ICPSC_DIV2 + * @arg @ref LL_LPTIM_ICPSC_DIV4 + * @arg @ref LL_LPTIM_ICPSC_DIV8 + */ +__STATIC_INLINE uint32_t LL_LPTIM_IC_GetPrescaler(const LPTIM_TypeDef *LPTIMx, uint32_t Channel) +{ + return (uint32_t)((READ_BIT(LPTIMx->CCMR1, LPTIM_CCMR1_IC1PSC << LL_LPTIM_SHIFT_TAB_ICxPSC[Channel])) >> \ + LL_LPTIM_SHIFT_TAB_ICxPSC[Channel]); +} + +/** + * @brief Set the Channel Mode. + * @rmtoll CCMR1 CC1SEL LL_LPTIM_CC_SetChannelMode\n + * CCMR1 CC2SEL LL_LPTIM_CC_SetChannelMode + * @param LPTIMx Low-Power Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_LPTIM_CHANNEL_CH1 + * @arg @ref LL_LPTIM_CHANNEL_CH2 + * @param CCMode This parameter can be one of the following values: + * @arg @ref LL_LPTIM_CCMODE_OUTPUT_PWM + * @arg @ref LL_LPTIM_CCMODE_INPUTCAPTURE + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_CC_SetChannelMode(LPTIM_TypeDef *LPTIMx, uint32_t Channel, uint32_t CCMode) +{ + SET_BIT(LPTIMx->CCMR1, CCMode << LL_LPTIM_SHIFT_TAB_CCxSEL[Channel]); +} + +/** + * @brief Get the Channel Mode. + * @rmtoll CCMR1 CC1SEL LL_LPTIM_CC_GetChannelMode\n + * CCMR1 CC2SEL LL_LPTIM_CC_GetChannelMode + * @param LPTIMx Low-Power Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_LPTIM_CHANNEL_CH1 + * @arg @ref LL_LPTIM_CHANNEL_CH2 + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPTIM_CCMODE_OUTPUT_PWM + * @arg @ref LL_LPTIM_CCMODE_INPUTCAPTURE + */ +__STATIC_INLINE uint32_t LL_LPTIM_CC_GetChannelMode(const LPTIM_TypeDef *LPTIMx, uint32_t Channel) +{ + return (uint32_t)((READ_BIT(LPTIMx->CCMR1, LPTIM_CCMR1_CC1SEL << LL_LPTIM_SHIFT_TAB_CCxSEL[Channel])) >> \ + LL_LPTIM_SHIFT_TAB_CCxSEL[Channel]); +} + +/** + * @brief Get captured value for input channel 1. + * @rmtoll CCR1 CCR1 LL_LPTIM_IC_GetCaptureCH1 + * @note The real capture value corresponding to the input capture trigger can be calculated using + * the formula hereafter : Real capture value = captured(LPTIM_CCRx) - offset + * where offset can be retrieved by calling @ref LL_LPTIM_IC_GET_OFFSET + * @param LPTIMx Low-Power Timer instance + * @retval CapturedValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_LPTIM_IC_GetCaptureCH1(const LPTIM_TypeDef *LPTIMx) +{ + return (uint32_t)(READ_BIT(LPTIMx->CCR1, LPTIM_CCR1_CCR1)); +} + +/** + * @brief Get captured value for input channel 2. + * @rmtoll CCR2 CCR2 LL_LPTIM_IC_GetCaptureCH2 + * @note The real capture value corresponding to the input capture trigger can be calculated using + * the formula hereafter : Real capture value = captured(LPTIM_CCRx) - offset + * where offset can be retrieved by calling @ref LL_LPTIM_IC_GET_OFFSET + * @param LPTIMx Low-Power Timer instance + * @retval CapturedValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_LPTIM_IC_GetCaptureCH2(const LPTIM_TypeDef *LPTIMx) +{ + return (uint32_t)(READ_BIT(LPTIMx->CCR2, LPTIM_CCR2_CCR2)); +} + +/** + * @} + */ + +/** @defgroup LPTIM_LL_EF_Trigger_Configuration Trigger Configuration + * @{ + */ + +/** + * @brief Enable the timeout function + * @note This function must be called when the LPTIM instance is disabled. + * @note The first trigger event will start the timer, any successive trigger + * event will reset the counter and the timer will restart. + * @note The timeout value corresponds to the compare value; if no trigger + * occurs within the expected time frame, the MCU is waked-up by the + * compare match event. + * @rmtoll CFGR TIMOUT LL_LPTIM_EnableTimeout + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_EnableTimeout(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->CFGR, LPTIM_CFGR_TIMOUT); +} + +/** + * @brief Disable the timeout function + * @note This function must be called when the LPTIM instance is disabled. + * @note A trigger event arriving when the timer is already started will be + * ignored. + * @rmtoll CFGR TIMOUT LL_LPTIM_DisableTimeout + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_DisableTimeout(LPTIM_TypeDef *LPTIMx) +{ + CLEAR_BIT(LPTIMx->CFGR, LPTIM_CFGR_TIMOUT); +} + +/** + * @brief Indicate whether the timeout function is enabled. + * @rmtoll CFGR TIMOUT LL_LPTIM_IsEnabledTimeout + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsEnabledTimeout(const LPTIM_TypeDef *LPTIMx) +{ + return (((READ_BIT(LPTIMx->CFGR, LPTIM_CFGR_TIMOUT) == LPTIM_CFGR_TIMOUT) ? 1UL : 0UL)); +} + +/** + * @brief Start the LPTIM counter + * @note This function must be called when the LPTIM instance is disabled. + * @rmtoll CFGR TRIGEN LL_LPTIM_TrigSw + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_TrigSw(LPTIM_TypeDef *LPTIMx) +{ + CLEAR_BIT(LPTIMx->CFGR, LPTIM_CFGR_TRIGEN); +} + +/** + * @brief Configure the external trigger used as a trigger event for the LPTIM. + * @note This function must be called when the LPTIM instance is disabled. + * @note An internal clock source must be present when a digital filter is + * required for the trigger. + * @rmtoll CFGR TRIGSEL LL_LPTIM_ConfigTrigger\n + * CFGR TRGFLT LL_LPTIM_ConfigTrigger\n + * CFGR TRIGEN LL_LPTIM_ConfigTrigger + * @param LPTIMx Low-Power Timer instance + * @param Source This parameter can be one of the following values: + * @arg @ref LL_LPTIM_TRIG_SOURCE_GPIO + * @arg @ref LL_LPTIM_TRIG_SOURCE_RTCALARMA + * @arg @ref LL_LPTIM_TRIG_SOURCE_RTCALARMB + * @arg @ref LL_LPTIM_TRIG_SOURCE_RTCTAMP1 + * @arg @ref LL_LPTIM_TRIG_SOURCE_RTCTAMP2 + @if STM32H503xx + * @arg @ref LL_LPTIM_TRIG_SOURCE_COMP1 (*) + @endif + * + * (*) Value not defined in all devices. \n + * + * @param Filter This parameter can be one of the following values: + * @arg @ref LL_LPTIM_TRIG_FILTER_NONE + * @arg @ref LL_LPTIM_TRIG_FILTER_2 + * @arg @ref LL_LPTIM_TRIG_FILTER_4 + * @arg @ref LL_LPTIM_TRIG_FILTER_8 + * @param Polarity This parameter can be one of the following values: + * @arg @ref LL_LPTIM_TRIG_POLARITY_RISING + * @arg @ref LL_LPTIM_TRIG_POLARITY_FALLING + * @arg @ref LL_LPTIM_TRIG_POLARITY_RISING_FALLING + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_ConfigTrigger(LPTIM_TypeDef *LPTIMx, uint32_t Source, uint32_t Filter, uint32_t Polarity) +{ + MODIFY_REG(LPTIMx->CFGR, LPTIM_CFGR_TRIGSEL | LPTIM_CFGR_TRGFLT | LPTIM_CFGR_TRIGEN, Source | Filter | Polarity); +} + +/** + * @brief Get actual external trigger source. + * @rmtoll CFGR TRIGSEL LL_LPTIM_GetTriggerSource + * @param LPTIMx Low-Power Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPTIM_TRIG_SOURCE_GPIO + * @arg @ref LL_LPTIM_TRIG_SOURCE_RTCALARMA + * @arg @ref LL_LPTIM_TRIG_SOURCE_RTCALARMB + * @arg @ref LL_LPTIM_TRIG_SOURCE_RTCTAMP1 + * @arg @ref LL_LPTIM_TRIG_SOURCE_RTCTAMP2 + @if STM32H503xx + * @arg @ref LL_LPTIM_TRIG_SOURCE_COMP1 (*) + @endif + * + * (*) Value not defined in all devices. \n + * + */ +__STATIC_INLINE uint32_t LL_LPTIM_GetTriggerSource(const LPTIM_TypeDef *LPTIMx) +{ + return (uint32_t)(READ_BIT(LPTIMx->CFGR, LPTIM_CFGR_TRIGSEL)); +} + +/** + * @brief Get actual external trigger filter. + * @rmtoll CFGR TRGFLT LL_LPTIM_GetTriggerFilter + * @param LPTIMx Low-Power Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPTIM_TRIG_FILTER_NONE + * @arg @ref LL_LPTIM_TRIG_FILTER_2 + * @arg @ref LL_LPTIM_TRIG_FILTER_4 + * @arg @ref LL_LPTIM_TRIG_FILTER_8 + */ +__STATIC_INLINE uint32_t LL_LPTIM_GetTriggerFilter(const LPTIM_TypeDef *LPTIMx) +{ + return (uint32_t)(READ_BIT(LPTIMx->CFGR, LPTIM_CFGR_TRGFLT)); +} + +/** + * @brief Get actual external trigger polarity. + * @rmtoll CFGR TRIGEN LL_LPTIM_GetTriggerPolarity + * @param LPTIMx Low-Power Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPTIM_TRIG_POLARITY_RISING + * @arg @ref LL_LPTIM_TRIG_POLARITY_FALLING + * @arg @ref LL_LPTIM_TRIG_POLARITY_RISING_FALLING + */ +__STATIC_INLINE uint32_t LL_LPTIM_GetTriggerPolarity(const LPTIM_TypeDef *LPTIMx) +{ + return (uint32_t)(READ_BIT(LPTIMx->CFGR, LPTIM_CFGR_TRIGEN)); +} + +/** + * @} + */ + +/** @defgroup LPTIM_LL_EF_Clock_Configuration Clock Configuration + * @{ + */ + +/** + * @brief Set the source of the clock used by the LPTIM instance. + * @note This function must be called when the LPTIM instance is disabled. + * @rmtoll CFGR CKSEL LL_LPTIM_SetClockSource + * @param LPTIMx Low-Power Timer instance + * @param ClockSource This parameter can be one of the following values: + * @arg @ref LL_LPTIM_CLK_SOURCE_INTERNAL + * @arg @ref LL_LPTIM_CLK_SOURCE_EXTERNAL + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_SetClockSource(LPTIM_TypeDef *LPTIMx, uint32_t ClockSource) +{ + MODIFY_REG(LPTIMx->CFGR, LPTIM_CFGR_CKSEL, ClockSource); +} + +/** + * @brief Get actual LPTIM instance clock source. + * @rmtoll CFGR CKSEL LL_LPTIM_GetClockSource + * @param LPTIMx Low-Power Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPTIM_CLK_SOURCE_INTERNAL + * @arg @ref LL_LPTIM_CLK_SOURCE_EXTERNAL + */ +__STATIC_INLINE uint32_t LL_LPTIM_GetClockSource(const LPTIM_TypeDef *LPTIMx) +{ + return (uint32_t)(READ_BIT(LPTIMx->CFGR, LPTIM_CFGR_CKSEL)); +} + +/** + * @brief Configure the active edge or edges used by the counter when + the LPTIM is clocked by an external clock source. + * @note This function must be called when the LPTIM instance is disabled. + * @note When both external clock signal edges are considered active ones, + * the LPTIM must also be clocked by an internal clock source with a + * frequency equal to at least four times the external clock frequency. + * @note An internal clock source must be present when a digital filter is + * required for external clock. + * @rmtoll CFGR CKFLT LL_LPTIM_ConfigClock\n + * CFGR CKPOL LL_LPTIM_ConfigClock + * @param LPTIMx Low-Power Timer instance + * @param ClockFilter This parameter can be one of the following values: + * @arg @ref LL_LPTIM_CLK_FILTER_NONE + * @arg @ref LL_LPTIM_CLK_FILTER_2 + * @arg @ref LL_LPTIM_CLK_FILTER_4 + * @arg @ref LL_LPTIM_CLK_FILTER_8 + * @param ClockPolarity This parameter can be one of the following values: + * @arg @ref LL_LPTIM_CLK_POLARITY_RISING + * @arg @ref LL_LPTIM_CLK_POLARITY_FALLING + * @arg @ref LL_LPTIM_CLK_POLARITY_RISING_FALLING + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_ConfigClock(LPTIM_TypeDef *LPTIMx, uint32_t ClockFilter, uint32_t ClockPolarity) +{ + MODIFY_REG(LPTIMx->CFGR, LPTIM_CFGR_CKFLT | LPTIM_CFGR_CKPOL, ClockFilter | ClockPolarity); +} + +/** + * @brief Get actual clock polarity + * @rmtoll CFGR CKPOL LL_LPTIM_GetClockPolarity + * @param LPTIMx Low-Power Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPTIM_CLK_POLARITY_RISING + * @arg @ref LL_LPTIM_CLK_POLARITY_FALLING + * @arg @ref LL_LPTIM_CLK_POLARITY_RISING_FALLING + */ +__STATIC_INLINE uint32_t LL_LPTIM_GetClockPolarity(const LPTIM_TypeDef *LPTIMx) +{ + return (uint32_t)(READ_BIT(LPTIMx->CFGR, LPTIM_CFGR_CKPOL)); +} + +/** + * @brief Get actual clock digital filter + * @rmtoll CFGR CKFLT LL_LPTIM_GetClockFilter + * @param LPTIMx Low-Power Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPTIM_CLK_FILTER_NONE + * @arg @ref LL_LPTIM_CLK_FILTER_2 + * @arg @ref LL_LPTIM_CLK_FILTER_4 + * @arg @ref LL_LPTIM_CLK_FILTER_8 + */ +__STATIC_INLINE uint32_t LL_LPTIM_GetClockFilter(const LPTIM_TypeDef *LPTIMx) +{ + return (uint32_t)(READ_BIT(LPTIMx->CFGR, LPTIM_CFGR_CKFLT)); +} + +/** + * @} + */ + +/** @defgroup LPTIM_LL_EF_Encoder_Mode Encoder Mode + * @{ + */ + +/** + * @brief Configure the encoder mode. + * @note This function must be called when the LPTIM instance is disabled. + * @rmtoll CFGR CKPOL LL_LPTIM_SetEncoderMode + * @param LPTIMx Low-Power Timer instance + * @param EncoderMode This parameter can be one of the following values: + * @arg @ref LL_LPTIM_ENCODER_MODE_RISING + * @arg @ref LL_LPTIM_ENCODER_MODE_FALLING + * @arg @ref LL_LPTIM_ENCODER_MODE_RISING_FALLING + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_SetEncoderMode(LPTIM_TypeDef *LPTIMx, uint32_t EncoderMode) +{ + MODIFY_REG(LPTIMx->CFGR, LPTIM_CFGR_CKPOL, EncoderMode); +} + +/** + * @brief Get actual encoder mode. + * @rmtoll CFGR CKPOL LL_LPTIM_GetEncoderMode + * @param LPTIMx Low-Power Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPTIM_ENCODER_MODE_RISING + * @arg @ref LL_LPTIM_ENCODER_MODE_FALLING + * @arg @ref LL_LPTIM_ENCODER_MODE_RISING_FALLING + */ +__STATIC_INLINE uint32_t LL_LPTIM_GetEncoderMode(const LPTIM_TypeDef *LPTIMx) +{ + return (uint32_t)(READ_BIT(LPTIMx->CFGR, LPTIM_CFGR_CKPOL)); +} + +/** + * @brief Enable the encoder mode + * @note This function must be called when the LPTIM instance is disabled. + * @note In this mode the LPTIM instance must be clocked by an internal clock + * source. Also, the prescaler division ratio must be equal to 1. + * @note LPTIM instance must be configured in continuous mode prior enabling + * the encoder mode. + * @rmtoll CFGR ENC LL_LPTIM_EnableEncoderMode + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_EnableEncoderMode(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->CFGR, LPTIM_CFGR_ENC); +} + +/** + * @brief Disable the encoder mode + * @note This function must be called when the LPTIM instance is disabled. + * @rmtoll CFGR ENC LL_LPTIM_DisableEncoderMode + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_DisableEncoderMode(LPTIM_TypeDef *LPTIMx) +{ + CLEAR_BIT(LPTIMx->CFGR, LPTIM_CFGR_ENC); +} + +/** + * @brief Indicates whether the LPTIM operates in encoder mode. + * @rmtoll CFGR ENC LL_LPTIM_IsEnabledEncoderMode + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsEnabledEncoderMode(const LPTIM_TypeDef *LPTIMx) +{ + return (((READ_BIT(LPTIMx->CFGR, LPTIM_CFGR_ENC) == LPTIM_CFGR_ENC) ? 1UL : 0UL)); +} + +/** + * @} + */ + +/** @defgroup LPTIM_LL_EF_FLAG_Management FLAG Management + * @{ + */ + +/** + * @brief Clear the compare match flag for channel 1 (CC1CF) + * @rmtoll ICR CC1CF LL_LPTIM_ClearFlag_CC1 + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_ClearFlag_CC1(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->ICR, LPTIM_ICR_CC1CF); +} + +/** + * @brief Inform application whether a capture/compare interrupt has occurred for channel 1. + * @rmtoll ISR CC1IF LL_LPTIM_IsActiveFlag_CC1 + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsActiveFlag_CC1(const LPTIM_TypeDef *LPTIMx) +{ + return (((READ_BIT(LPTIMx->ISR, LPTIM_ISR_CC1IF) == LPTIM_ISR_CC1IF) ? 1UL : 0UL)); +} + +/** + * @brief Clear the compare match flag for channel 2 (CC2CF) + * @rmtoll ICR CC2CF LL_LPTIM_ClearFlag_CC2 + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_ClearFlag_CC2(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->ICR, LPTIM_ICR_CC2CF); +} + +/** + * @brief Inform application whether a capture/compare interrupt has occurred for channel 2. + * @rmtoll ISR CC2IF LL_LPTIM_IsActiveFlag_CC2 + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsActiveFlag_CC2(const LPTIM_TypeDef *LPTIMx) +{ + return (((READ_BIT(LPTIMx->ISR, LPTIM_ISR_CC2IF) == LPTIM_ISR_CC2IF) ? 1UL : 0UL)); +} + +/** + * @brief Clear the Capture/Compare 1 over-capture flag for channel 1 (CC1OCF) + * @rmtoll ICR CC1OCF LL_LPTIM_ClearFlag_CC1O + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_ClearFlag_CC1O(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->ICR, LPTIM_ICR_CC1OCF); +} + +/** + * @brief Inform application whether a Capture/Compare 1 over-capture has occurred for channel 1. + * @rmtoll ISR CC1OF LL_LPTIM_IsActiveFlag_CC1O + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsActiveFlag_CC1O(const LPTIM_TypeDef *LPTIMx) +{ + return (((READ_BIT(LPTIMx->ISR, LPTIM_ISR_CC1OF) == LPTIM_ISR_CC1OF) ? 1UL : 0UL)); +} + +/** + * @brief Clear the Capture/Compare 2 over-capture flag for channel 2 (CC2OCF) + * @rmtoll ICR CC2OCF LL_LPTIM_ClearFlag_CC2O + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_ClearFlag_CC2O(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->ICR, LPTIM_ICR_CC2OCF); +} + +/** + * @brief Inform application whether a Capture/Compare 2 over-capture has occurred for channel 2. + * @rmtoll ISR CC2OF LL_LPTIM_IsActiveFlag_CC2O + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsActiveFlag_CC2O(const LPTIM_TypeDef *LPTIMx) +{ + return (((READ_BIT(LPTIMx->ISR, LPTIM_ISR_CC2OF) == LPTIM_ISR_CC2OF) ? 1UL : 0UL)); +} +/** + * @brief Clear the autoreload match flag (ARRMCF) + * @rmtoll ICR ARRMCF LL_LPTIM_ClearFlag_ARRM + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_ClearFlag_ARRM(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->ICR, LPTIM_ICR_ARRMCF); +} + +/** + * @brief Inform application whether a autoreload match interrupt has occurred. + * @rmtoll ISR ARRM LL_LPTIM_IsActiveFlag_ARRM + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsActiveFlag_ARRM(const LPTIM_TypeDef *LPTIMx) +{ + return (((READ_BIT(LPTIMx->ISR, LPTIM_ISR_ARRM) == LPTIM_ISR_ARRM) ? 1UL : 0UL)); +} + +/** + * @brief Clear the external trigger valid edge flag(EXTTRIGCF). + * @rmtoll ICR EXTTRIGCF LL_LPTIM_ClearFlag_EXTTRIG + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_ClearFlag_EXTTRIG(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->ICR, LPTIM_ICR_EXTTRIGCF); +} + +/** + * @brief Inform application whether a valid edge on the selected external trigger input has occurred. + * @rmtoll ISR EXTTRIG LL_LPTIM_IsActiveFlag_EXTTRIG + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsActiveFlag_EXTTRIG(const LPTIM_TypeDef *LPTIMx) +{ + return (((READ_BIT(LPTIMx->ISR, LPTIM_ISR_EXTTRIG) == LPTIM_ISR_EXTTRIG) ? 1UL : 0UL)); +} + +/** + * @brief Clear the compare register update interrupt flag (CMP1OKCF). + * @rmtoll ICR CMP1OKCF LL_LPTIM_ClearFlag_CMP1OK + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_ClearFlag_CMP1OK(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->ICR, LPTIM_ICR_CMP1OKCF); +} + +/** + * @brief Informs application whether the APB bus write operation to the LPTIMx_CCR1 register has been successfully + completed. If so, a new one can be initiated. + * @rmtoll ISR CMP1OK LL_LPTIM_IsActiveFlag_CMP1OK + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsActiveFlag_CMP1OK(const LPTIM_TypeDef *LPTIMx) +{ + return (((READ_BIT(LPTIMx->ISR, LPTIM_ISR_CMP1OK) == LPTIM_ISR_CMP1OK) ? 1UL : 0UL)); +} + +/** + * @brief Clear the compare register update interrupt flag (CMP2OKCF). + * @rmtoll ICR CMP2OKCF LL_LPTIM_ClearFlag_CMP2OK + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_ClearFlag_CMP2OK(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->ICR, LPTIM_ICR_CMP2OKCF); +} + +/** + * @brief Informs application whether the APB bus write operation to the LPTIMx_CCR2 register has been successfully + completed. If so, a new one can be initiated. + * @rmtoll ISR CMP2OK LL_LPTIM_IsActiveFlag_CMP2OK + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsActiveFlag_CMP2OK(const LPTIM_TypeDef *LPTIMx) +{ + return (((READ_BIT(LPTIMx->ISR, LPTIM_ISR_CMP2OK) == LPTIM_ISR_CMP2OK) ? 1UL : 0UL)); +} + +/** + * @brief Clear the interrupt register update interrupt flag (DIEROKCF). + * @rmtoll ICR DIEROKCF LL_LPTIM_ClearFlag_DIEROK + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_ClearFlag_DIEROK(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->ICR, LPTIM_ICR_DIEROKCF); +} + +/** + * @brief Informs application whether the APB bus write operation to the LPTIMx_DIER register has been successfully + completed. If so, a new one can be initiated. + * @rmtoll ISR DIEROK LL_LPTIM_IsActiveFlag_DIEROK + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsActiveFlag_DIEROK(const LPTIM_TypeDef *LPTIMx) +{ + return ((READ_BIT(LPTIMx->ISR, LPTIM_ISR_DIEROK) == (LPTIM_ISR_DIEROK)) ? 1UL : 0UL); +} + +/** + * @brief Clear the autoreload register update interrupt flag (ARROKCF). + * @rmtoll ICR ARROKCF LL_LPTIM_ClearFlag_ARROK + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_ClearFlag_ARROK(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->ICR, LPTIM_ICR_ARROKCF); +} + +/** + * @brief Informs application whether the APB bus write operation to the LPTIMx_ARR register has been successfully + completed. If so, a new one can be initiated. + * @rmtoll ISR ARROK LL_LPTIM_IsActiveFlag_ARROK + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsActiveFlag_ARROK(const LPTIM_TypeDef *LPTIMx) +{ + return (((READ_BIT(LPTIMx->ISR, LPTIM_ISR_ARROK) == LPTIM_ISR_ARROK) ? 1UL : 0UL)); +} + +/** + * @brief Clear the counter direction change to up interrupt flag (UPCF). + * @rmtoll ICR UPCF LL_LPTIM_ClearFlag_UP + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_ClearFlag_UP(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->ICR, LPTIM_ICR_UPCF); +} + +/** + * @brief Informs the application whether the counter direction has changed from down to up (when the LPTIM instance + operates in encoder mode). + * @rmtoll ISR UP LL_LPTIM_IsActiveFlag_UP + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsActiveFlag_UP(const LPTIM_TypeDef *LPTIMx) +{ + return (((READ_BIT(LPTIMx->ISR, LPTIM_ISR_UP) == LPTIM_ISR_UP) ? 1UL : 0UL)); +} + +/** + * @brief Clear the counter direction change to down interrupt flag (DOWNCF). + * @rmtoll ICR DOWNCF LL_LPTIM_ClearFlag_DOWN + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_ClearFlag_DOWN(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->ICR, LPTIM_ICR_DOWNCF); +} + +/** + * @brief Informs the application whether the counter direction has changed from up to down (when the LPTIM instance + operates in encoder mode). + * @rmtoll ISR DOWN LL_LPTIM_IsActiveFlag_DOWN + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsActiveFlag_DOWN(const LPTIM_TypeDef *LPTIMx) +{ + return (((READ_BIT(LPTIMx->ISR, LPTIM_ISR_DOWN) == LPTIM_ISR_DOWN) ? 1UL : 0UL)); +} + +/** + * @brief Clear the repetition register update interrupt flag (REPOKCF). + * @rmtoll ICR REPOKCF LL_LPTIM_ClearFlag_REPOK + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_ClearFlag_REPOK(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->ICR, LPTIM_ICR_REPOKCF); +} + +/** + * @brief Informs application whether the APB bus write operation to the LPTIMx_RCR register has been successfully + completed; If so, a new one can be initiated. + * @rmtoll ISR REPOK LL_LPTIM_IsActiveFlag_REPOK + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsActiveFlag_REPOK(const LPTIM_TypeDef *LPTIMx) +{ + return ((READ_BIT(LPTIMx->ISR, LPTIM_ISR_REPOK) == (LPTIM_ISR_REPOK)) ? 1UL : 0UL); +} + +/** + * @brief Clear the update event flag (UECF). + * @rmtoll ICR UECF LL_LPTIM_ClearFlag_UE + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_ClearFlag_UE(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->ICR, LPTIM_ICR_UECF); +} + +/** + * @brief Informs application whether the LPTIMx update event has occurred. + * @rmtoll ISR UE LL_LPTIM_IsActiveFlag_UE + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsActiveFlag_UE(const LPTIM_TypeDef *LPTIMx) +{ + return ((READ_BIT(LPTIMx->ISR, LPTIM_ISR_UE) == (LPTIM_ISR_UE)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup LPTIM_LL_EF_IT_Management Interrupt Management + * @{ + */ +/** + * @brief Enable capture/compare 1 interrupt (CC1IE). + * @rmtoll DIER CC1IE LL_LPTIM_EnableIT_CC1 + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_EnableIT_CC1(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->DIER, LPTIM_DIER_CC1IE); +} + +/** + * @brief Disable capture/compare 1 interrupt (CC1IE). + * @rmtoll DIER CC1IE LL_LPTIM_DisableIT_CC1 + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_DisableIT_CC1(LPTIM_TypeDef *LPTIMx) +{ + CLEAR_BIT(LPTIMx->DIER, LPTIM_DIER_CC1IE); +} + +/** + * @brief Indicates whether the capture/compare 1 interrupt (CC1IE) is enabled. + * @rmtoll DIER CC1IE LL_LPTIM_IsEnabledIT_CC1 + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsEnabledIT_CC1(const LPTIM_TypeDef *LPTIMx) +{ + return (((READ_BIT(LPTIMx->DIER, LPTIM_DIER_CC1IE) == LPTIM_DIER_CC1IE) ? 1UL : 0UL)); +} + +/** + * @brief Enable capture/compare 1 interrupt (CC2IE). + * @rmtoll DIER CC2IE LL_LPTIM_EnableIT_CC2 + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_EnableIT_CC2(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->DIER, LPTIM_DIER_CC2IE); +} + +/** + * @brief Disable capture/compare 2 interrupt (CC2IE). + * @rmtoll DIER CC2IE LL_LPTIM_DisableIT_CC2 + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_DisableIT_CC2(LPTIM_TypeDef *LPTIMx) +{ + CLEAR_BIT(LPTIMx->DIER, LPTIM_DIER_CC2IE); +} + +/** + * @brief Indicates whether the capture/compare 2 interrupt (CC2IE) is enabled. + * @rmtoll DIER CC2IE LL_LPTIM_IsEnabledIT_CC2 + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsEnabledIT_CC2(const LPTIM_TypeDef *LPTIMx) +{ + return (((READ_BIT(LPTIMx->DIER, LPTIM_DIER_CC2IE) == LPTIM_DIER_CC2IE) ? 1UL : 0UL)); +} + +/** + * @brief Enable capture/compare 1 over-capture interrupt (CC1OIE). + * @rmtoll DIER CC1OIE LL_LPTIM_EnableIT_CC1O + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_EnableIT_CC1O(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->DIER, LPTIM_DIER_CC1OIE); +} + +/** + * @brief Disable capture/compare 1 over-capture interrupt (CC1OIE). + * @rmtoll DIER CC1OIE LL_LPTIM_DisableIT_CC1O + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_DisableIT_CC1O(LPTIM_TypeDef *LPTIMx) +{ + CLEAR_BIT(LPTIMx->DIER, LPTIM_DIER_CC1OIE); +} + +/** + * @brief Indicates whether the capture/compare 1 over-capture interrupt (CC1OIE) is enabled. + * @rmtoll DIER CC1OIE LL_LPTIM_IsEnabledIT_CC1O + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsEnabledIT_CC1O(const LPTIM_TypeDef *LPTIMx) +{ + return (((READ_BIT(LPTIMx->DIER, LPTIM_DIER_CC1OIE) == LPTIM_DIER_CC1OIE) ? 1UL : 0UL)); +} + +/** + * @brief Enable capture/compare 1 over-capture interrupt (CC2OIE). + * @rmtoll DIER CC2OIE LL_LPTIM_EnableIT_CC2O + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_EnableIT_CC2O(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->DIER, LPTIM_DIER_CC2OIE); +} + +/** + * @brief Disable capture/compare 1 over-capture interrupt (CC2OIE). + * @rmtoll DIER CC2OIE LL_LPTIM_DisableIT_CC2O + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_DisableIT_CC2O(LPTIM_TypeDef *LPTIMx) +{ + CLEAR_BIT(LPTIMx->DIER, LPTIM_DIER_CC2OIE); +} + +/** + * @brief Indicates whether the capture/compare 2 over-capture interrupt (CC2OIE) is enabled. + * @rmtoll DIER CC2OIE LL_LPTIM_IsEnabledIT_CC2O + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsEnabledIT_CC2O(const LPTIM_TypeDef *LPTIMx) +{ + return (((READ_BIT(LPTIMx->DIER, LPTIM_DIER_CC2OIE) == LPTIM_DIER_CC2OIE) ? 1UL : 0UL)); +} + +/** + * @brief Enable autoreload match interrupt (ARRMIE). + * @rmtoll DIER ARRMIE LL_LPTIM_EnableIT_ARRM + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_EnableIT_ARRM(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->DIER, LPTIM_DIER_ARRMIE); +} + +/** + * @brief Disable autoreload match interrupt (ARRMIE). + * @rmtoll DIER ARRMIE LL_LPTIM_DisableIT_ARRM + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_DisableIT_ARRM(LPTIM_TypeDef *LPTIMx) +{ + CLEAR_BIT(LPTIMx->DIER, LPTIM_DIER_ARRMIE); +} + +/** + * @brief Indicates whether the autoreload match interrupt (ARRMIE) is enabled. + * @rmtoll DIER ARRMIE LL_LPTIM_IsEnabledIT_ARRM + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsEnabledIT_ARRM(const LPTIM_TypeDef *LPTIMx) +{ + return (((READ_BIT(LPTIMx->DIER, LPTIM_DIER_ARRMIE) == LPTIM_DIER_ARRMIE) ? 1UL : 0UL)); +} + +/** + * @brief Enable external trigger valid edge interrupt (EXTTRIGIE). + * @rmtoll DIER EXTTRIGIE LL_LPTIM_EnableIT_EXTTRIG + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_EnableIT_EXTTRIG(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->DIER, LPTIM_DIER_EXTTRIGIE); +} + +/** + * @brief Disable external trigger valid edge interrupt (EXTTRIGIE). + * @rmtoll DIER EXTTRIGIE LL_LPTIM_DisableIT_EXTTRIG + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_DisableIT_EXTTRIG(LPTIM_TypeDef *LPTIMx) +{ + CLEAR_BIT(LPTIMx->DIER, LPTIM_DIER_EXTTRIGIE); +} + +/** + * @brief Indicates external trigger valid edge interrupt (EXTTRIGIE) is enabled. + * @rmtoll DIER EXTTRIGIE LL_LPTIM_IsEnabledIT_EXTTRIG + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsEnabledIT_EXTTRIG(const LPTIM_TypeDef *LPTIMx) +{ + return (((READ_BIT(LPTIMx->DIER, LPTIM_DIER_EXTTRIGIE) == LPTIM_DIER_EXTTRIGIE) ? 1UL : 0UL)); +} + +/** + * @brief Enable compare register write completed interrupt (CMP1OKIE). + * @rmtoll IER CMP1OKIE LL_LPTIM_EnableIT_CMP1OK + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_EnableIT_CMP1OK(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->DIER, LPTIM_DIER_CMP1OKIE); +} + +/** + * @brief Disable compare register write completed interrupt (CMP1OKIE). + * @rmtoll IER CMPO1KIE LL_LPTIM_DisableIT_CMP1OK + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_DisableIT_CMP1OK(LPTIM_TypeDef *LPTIMx) +{ + CLEAR_BIT(LPTIMx->DIER, LPTIM_DIER_CMP1OKIE); +} + +/** + * @brief Indicates whether the compare register write completed interrupt (CMP1OKIE) is enabled. + * @rmtoll IER CMP1OKIE LL_LPTIM_IsEnabledIT_CMP1OK + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsEnabledIT_CMP1OK(const LPTIM_TypeDef *LPTIMx) +{ + return (((READ_BIT(LPTIMx->DIER, LPTIM_DIER_CMP1OKIE) == LPTIM_DIER_CMP1OKIE) ? 1UL : 0UL)); +} + +/** + * @brief Enable compare register write completed interrupt (CMP2OKIE). + * @rmtoll IER CMP2OKIE LL_LPTIM_EnableIT_CMP2OK + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_EnableIT_CMP2OK(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->DIER, LPTIM_DIER_CMP2OKIE); +} + +/** + * @brief Disable compare register write completed interrupt (CMP2OKIE). + * @rmtoll IER CMP2OKIE LL_LPTIM_DisableIT_CMP2OK + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_DisableIT_CMP2OK(LPTIM_TypeDef *LPTIMx) +{ + CLEAR_BIT(LPTIMx->DIER, LPTIM_DIER_CMP2OKIE); +} + +/** + * @brief Indicates whether the compare register write completed interrupt (CMP2OKIE) is enabled. + * @rmtoll IER CMP2OKIE LL_LPTIM_IsEnabledIT_CMP2OK + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsEnabledIT_CMP2OK(const LPTIM_TypeDef *LPTIMx) +{ + return (((READ_BIT(LPTIMx->DIER, LPTIM_DIER_CMP2OKIE) == LPTIM_DIER_CMP2OKIE) ? 1UL : 0UL)); +} + +/** + * @brief Enable autoreload register write completed interrupt (ARROKIE). + * @rmtoll DIER ARROKIE LL_LPTIM_EnableIT_ARROK + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_EnableIT_ARROK(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->DIER, LPTIM_DIER_ARROKIE); +} + +/** + * @brief Disable autoreload register write completed interrupt (ARROKIE). + * @rmtoll DIER ARROKIE LL_LPTIM_DisableIT_ARROK + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_DisableIT_ARROK(LPTIM_TypeDef *LPTIMx) +{ + CLEAR_BIT(LPTIMx->DIER, LPTIM_DIER_ARROKIE); +} + +/** + * @brief Indicates whether the autoreload register write completed interrupt (ARROKIE) is enabled. + * @rmtoll DIER ARROKIE LL_LPTIM_IsEnabledIT_ARROK + * @param LPTIMx Low-Power Timer instance + * @retval State of bit(1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsEnabledIT_ARROK(const LPTIM_TypeDef *LPTIMx) +{ + return (((READ_BIT(LPTIMx->DIER, LPTIM_DIER_ARROKIE) == LPTIM_DIER_ARROKIE) ? 1UL : 0UL)); +} + +/** + * @brief Enable direction change to up interrupt (UPIE). + * @rmtoll DIER UPIE LL_LPTIM_EnableIT_UP + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_EnableIT_UP(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->DIER, LPTIM_DIER_UPIE); +} + +/** + * @brief Disable direction change to up interrupt (UPIE). + * @rmtoll DIER UPIE LL_LPTIM_DisableIT_UP + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_DisableIT_UP(LPTIM_TypeDef *LPTIMx) +{ + CLEAR_BIT(LPTIMx->DIER, LPTIM_DIER_UPIE); +} + +/** + * @brief Indicates whether the direction change to up interrupt (UPIE) is enabled. + * @rmtoll DIER UPIE LL_LPTIM_IsEnabledIT_UP + * @param LPTIMx Low-Power Timer instance + * @retval State of bit(1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsEnabledIT_UP(const LPTIM_TypeDef *LPTIMx) +{ + return (((READ_BIT(LPTIMx->DIER, LPTIM_DIER_UPIE) == LPTIM_DIER_UPIE) ? 1UL : 0UL)); +} + +/** + * @brief Enable direction change to down interrupt (DOWNIE). + * @rmtoll DIER DOWNIE LL_LPTIM_EnableIT_DOWN + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_EnableIT_DOWN(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->DIER, LPTIM_DIER_DOWNIE); +} + +/** + * @brief Disable direction change to down interrupt (DOWNIE). + * @rmtoll DIER DOWNIE LL_LPTIM_DisableIT_DOWN + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_DisableIT_DOWN(LPTIM_TypeDef *LPTIMx) +{ + CLEAR_BIT(LPTIMx->DIER, LPTIM_DIER_DOWNIE); +} + +/** + * @brief Indicates whether the direction change to down interrupt (DOWNIE) is enabled. + * @rmtoll DIER DOWNIE LL_LPTIM_IsEnabledIT_DOWN + * @param LPTIMx Low-Power Timer instance + * @retval State of bit(1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsEnabledIT_DOWN(const LPTIM_TypeDef *LPTIMx) +{ + return ((READ_BIT(LPTIMx->DIER, LPTIM_DIER_DOWNIE) == LPTIM_DIER_DOWNIE) ? 1UL : 0UL); +} + +/** + * @brief Enable repetition register update successfully completed interrupt (REPOKIE). + * @rmtoll DIER REPOKIE LL_LPTIM_EnableIT_REPOK + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_EnableIT_REPOK(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->DIER, LPTIM_DIER_REPOKIE); +} + +/** + * @brief Disable repetition register update successfully completed interrupt (REPOKIE). + * @rmtoll DIER REPOKIE LL_LPTIM_DisableIT_REPOK + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_DisableIT_REPOK(LPTIM_TypeDef *LPTIMx) +{ + CLEAR_BIT(LPTIMx->DIER, LPTIM_DIER_REPOKIE); +} + +/** + * @brief Indicates whether the repetition register update successfully completed interrupt (REPOKIE) is enabled. + * @rmtoll DIER REPOKIE LL_LPTIM_IsEnabledIT_REPOK + * @param LPTIMx Low-Power Timer instance + * @retval State of bit(1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsEnabledIT_REPOK(const LPTIM_TypeDef *LPTIMx) +{ + return ((READ_BIT(LPTIMx->DIER, LPTIM_DIER_REPOKIE) == (LPTIM_DIER_REPOKIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable update event interrupt (UEIE). + * @rmtoll DIER UEIE LL_LPTIM_EnableIT_UE + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_EnableIT_UE(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->DIER, LPTIM_DIER_UEIE); +} + +/** + * @brief Disable update event interrupt (UEIE). + * @rmtoll DIER UEIE LL_LPTIM_DisableIT_UE + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_DisableIT_UE(LPTIM_TypeDef *LPTIMx) +{ + CLEAR_BIT(LPTIMx->DIER, LPTIM_DIER_UEIE); +} + +/** + * @brief Indicates whether the update event interrupt (UEIE) is enabled. + * @rmtoll DIER UEIE LL_LPTIM_IsEnabledIT_UE + * @param LPTIMx Low-Power Timer instance + *@ retval State of bit(1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsEnabledIT_UE(const LPTIM_TypeDef *LPTIMx) +{ + return ((READ_BIT(LPTIMx->DIER, LPTIM_DIER_UEIE) == (LPTIM_DIER_UEIE)) ? 1UL : 0UL); +} +/** + * @} + */ + + +/** @defgroup TIM_LL_EF_DMA_Management DMA Management + * @{ + */ +/** + * @brief Enable update DMA request. + * @rmtoll DIER UEDE LL_LPTIM_EnableDMAReq_UPDATE + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_EnableDMAReq_UPDATE(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->DIER, LPTIM_DIER_UEDE); +} + +/** + * @brief Disable update DMA request. + * @rmtoll DIER UEDE LL_LPTIM_DisableDMAReq_UPDATE + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_DisableDMAReq_UPDATE(LPTIM_TypeDef *LPTIMx) +{ + CLEAR_BIT(LPTIMx->DIER, LPTIM_DIER_UEDE); +} + +/** + * @brief Indicates whether the update DMA request is enabled. + * @rmtoll DIER UEDE LL_LPTIM_IsEnabledDMAReq_UPDATE + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsEnabledDMAReq_UPDATE(const LPTIM_TypeDef *LPTIMx) +{ + return ((READ_BIT(LPTIMx->DIER, LPTIM_DIER_UEDE) == (LPTIM_DIER_UEDE)) ? 1UL : 0UL); +} + +/** + * @brief Enable capture/compare 1 DMA request (CC1DE). + * @rmtoll DIER CC1DE LL_LPTIM_EnableDMAReq_CC1 + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_EnableDMAReq_CC1(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->DIER, LPTIM_DIER_CC1DE); +} + +/** + * @brief Disable capture/compare 1 DMA request (CC1DE). + * @rmtoll DIER CC1DE LL_LPTIM_DisableDMAReq_CC1 + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_DisableDMAReq_CC1(LPTIM_TypeDef *LPTIMx) +{ + CLEAR_BIT(LPTIMx->DIER, LPTIM_DIER_CC1DE); +} + +/** + * @brief Indicates whether the capture/compare 1 DMA request (CC1DE) is enabled. + * @rmtoll DIER CC1DE LL_LPTIM_IsEnabledDMAReq_CC1 + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsEnabledDMAReq_CC1(const LPTIM_TypeDef *LPTIMx) +{ + return ((READ_BIT(LPTIMx->DIER, LPTIM_DIER_CC1DE) == (LPTIM_DIER_CC1DE)) ? 1UL : 0UL); +} + +/** + * @brief Enable capture/compare 2 DMA request (CC2DE). + * @rmtoll DIER CC2DE LL_LPTIM_EnableDMAReq_CC2 + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_EnableDMAReq_CC2(LPTIM_TypeDef *LPTIMx) +{ + SET_BIT(LPTIMx->DIER, LPTIM_DIER_CC2DE); +} + +/** + * @brief Disable capture/compare 2 DMA request (CC2DE). + * @rmtoll DIER CC2DE LL_LPTIM_DisableDMAReq_CC2 + * @param LPTIMx Low-Power Timer instance + * @retval None + */ +__STATIC_INLINE void LL_LPTIM_DisableDMAReq_CC2(LPTIM_TypeDef *LPTIMx) +{ + CLEAR_BIT(LPTIMx->DIER, LPTIM_DIER_CC2DE); +} + +/** + * @brief Indicates whether the capture/compare 2 DMA request (CC2DE) is enabled. + * @rmtoll DIER CC2DE LL_LPTIM_IsEnabledDMAReq_CC2 + * @param LPTIMx Low-Power Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPTIM_IsEnabledDMAReq_CC2(const LPTIM_TypeDef *LPTIMx) +{ + return ((READ_BIT(LPTIMx->DIER, LPTIM_DIER_CC2DE) == (LPTIM_DIER_CC2DE)) ? 1UL : 0UL); +} + +/** + * @} + */ +/** + * @} + */ + +/** + * @} + */ + +#endif /* LPTIM1 || LPTIM2 || LPTIM3 || LPTIM4 || LPTIM5 || LPTIM6 */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_LL_LPTIM_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_lpuart.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_lpuart.h new file mode 100644 index 0000000000..f502ae0c37 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_lpuart.h @@ -0,0 +1,2643 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_lpuart.h + * @author MCD Application Team + * @brief Header file of LPUART LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_LL_LPUART_H +#define STM32H5xx_LL_LPUART_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (LPUART1) + +/** @defgroup LPUART_LL LPUART + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/** @defgroup LPUART_LL_Private_Variables LPUART Private Variables + * @{ + */ +/* Array used to get the LPUART prescaler division decimal values versus @ref LPUART_LL_EC_PRESCALER values */ +static const uint16_t LPUART_PRESCALER_TAB[] = +{ + (uint16_t)1, + (uint16_t)2, + (uint16_t)4, + (uint16_t)6, + (uint16_t)8, + (uint16_t)10, + (uint16_t)12, + (uint16_t)16, + (uint16_t)32, + (uint16_t)64, + (uint16_t)128, + (uint16_t)256 +}; +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup LPUART_LL_Private_Constants LPUART Private Constants + * @{ + */ +/* Defines used in Baud Rate related macros and corresponding register setting computation */ +#define LPUART_LPUARTDIV_FREQ_MUL 256U +#define LPUART_BRR_MASK 0x000FFFFFU +#define LPUART_BRR_MIN_VALUE 0x00000300U +/** + * @} + */ + + +/* Private macros ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup LPUART_LL_Private_Macros LPUART Private Macros + * @{ + */ +/** + * @} + */ +#endif /*USE_FULL_LL_DRIVER*/ + +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup LPUART_LL_ES_INIT LPUART Exported Init structures + * @{ + */ + +/** + * @brief LL LPUART Init Structure definition + */ +typedef struct +{ + uint32_t PrescalerValue; /*!< Specifies the Prescaler to compute the communication baud rate. + This parameter can be a value of @ref LPUART_LL_EC_PRESCALER. + + This feature can be modified afterwards using unitary + function @ref LL_LPUART_SetPrescaler().*/ + + uint32_t BaudRate; /*!< This field defines expected LPUART communication baud rate. + + This feature can be modified afterwards using unitary + function @ref LL_LPUART_SetBaudRate().*/ + + uint32_t DataWidth; /*!< Specifies the number of data bits transmitted or received in a frame. + This parameter can be a value of @ref LPUART_LL_EC_DATAWIDTH. + + This feature can be modified afterwards using unitary + function @ref LL_LPUART_SetDataWidth().*/ + + uint32_t StopBits; /*!< Specifies the number of stop bits transmitted. + This parameter can be a value of @ref LPUART_LL_EC_STOPBITS. + + This feature can be modified afterwards using unitary + function @ref LL_LPUART_SetStopBitsLength().*/ + + uint32_t Parity; /*!< Specifies the parity mode. + This parameter can be a value of @ref LPUART_LL_EC_PARITY. + + This feature can be modified afterwards using unitary + function @ref LL_LPUART_SetParity().*/ + + uint32_t TransferDirection; /*!< Specifies whether the Receive and/or Transmit mode is enabled or disabled. + This parameter can be a value of @ref LPUART_LL_EC_DIRECTION. + + This feature can be modified afterwards using unitary + function @ref LL_LPUART_SetTransferDirection().*/ + + uint32_t HardwareFlowControl; /*!< Specifies whether the hardware flow control mode is enabled or disabled. + This parameter can be a value of @ref LPUART_LL_EC_HWCONTROL. + + This feature can be modified afterwards using unitary + function @ref LL_LPUART_SetHWFlowCtrl().*/ + +} LL_LPUART_InitTypeDef; + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup LPUART_LL_Exported_Constants LPUART Exported Constants + * @{ + */ + +/** @defgroup LPUART_LL_EC_CLEAR_FLAG Clear Flags Defines + * @brief Flags defines which can be used with LL_LPUART_WriteReg function + * @{ + */ +#define LL_LPUART_ICR_PECF USART_ICR_PECF /*!< Parity error clear flag */ +#define LL_LPUART_ICR_FECF USART_ICR_FECF /*!< Framing error clear flag */ +#define LL_LPUART_ICR_NCF USART_ICR_NECF /*!< Noise error detected clear flag */ +#define LL_LPUART_ICR_ORECF USART_ICR_ORECF /*!< Overrun error clear flag */ +#define LL_LPUART_ICR_IDLECF USART_ICR_IDLECF /*!< Idle line detected clear flag */ +#define LL_LPUART_ICR_TCCF USART_ICR_TCCF /*!< Transmission complete clear flag */ +#define LL_LPUART_ICR_CTSCF USART_ICR_CTSCF /*!< CTS clear flag */ +#define LL_LPUART_ICR_CMCF USART_ICR_CMCF /*!< Character match clear flag */ +#define LL_LPUART_ICR_WUCF USART_ICR_WUCF /*!< Wakeup from Stop mode clear flag */ +/** + * @} + */ + +/** @defgroup LPUART_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_LPUART_ReadReg function + * @{ + */ +#define LL_LPUART_ISR_PE USART_ISR_PE /*!< Parity error flag */ +#define LL_LPUART_ISR_FE USART_ISR_FE /*!< Framing error flag */ +#define LL_LPUART_ISR_NE USART_ISR_NE /*!< Noise detected flag */ +#define LL_LPUART_ISR_ORE USART_ISR_ORE /*!< Overrun error flag */ +#define LL_LPUART_ISR_IDLE USART_ISR_IDLE /*!< Idle line detected flag */ +#define LL_LPUART_ISR_RXNE_RXFNE USART_ISR_RXNE_RXFNE /*!< Read data register or RX FIFO not empty flag */ +#define LL_LPUART_ISR_TC USART_ISR_TC /*!< Transmission complete flag */ +#define LL_LPUART_ISR_TXE_TXFNF USART_ISR_TXE_TXFNF /*!< Transmit data register empty or TX FIFO Not Full flag*/ +#define LL_LPUART_ISR_CTSIF USART_ISR_CTSIF /*!< CTS interrupt flag */ +#define LL_LPUART_ISR_CTS USART_ISR_CTS /*!< CTS flag */ +#define LL_LPUART_ISR_BUSY USART_ISR_BUSY /*!< Busy flag */ +#define LL_LPUART_ISR_CMF USART_ISR_CMF /*!< Character match flag */ +#define LL_LPUART_ISR_SBKF USART_ISR_SBKF /*!< Send break flag */ +#define LL_LPUART_ISR_RWU USART_ISR_RWU /*!< Receiver wakeup from Mute mode flag */ +#define LL_LPUART_ISR_WUF USART_ISR_WUF /*!< Wakeup from Stop mode flag */ +#define LL_LPUART_ISR_TEACK USART_ISR_TEACK /*!< Transmit enable acknowledge flag */ +#define LL_LPUART_ISR_REACK USART_ISR_REACK /*!< Receive enable acknowledge flag */ +#define LL_LPUART_ISR_TXFE USART_ISR_TXFE /*!< TX FIFO empty flag */ +#define LL_LPUART_ISR_RXFF USART_ISR_RXFF /*!< RX FIFO full flag */ +#define LL_LPUART_ISR_RXFT USART_ISR_RXFT /*!< RX FIFO threshold flag */ +#define LL_LPUART_ISR_TXFT USART_ISR_TXFT /*!< TX FIFO threshold flag */ +/** + * @} + */ + +/** @defgroup LPUART_LL_EC_IT IT Defines + * @brief IT defines which can be used with LL_LPUART_ReadReg and LL_LPUART_WriteReg functions + * @{ + */ +#define LL_LPUART_CR1_IDLEIE USART_CR1_IDLEIE /*!< IDLE interrupt enable */ +#define LL_LPUART_CR1_RXNEIE_RXFNEIE USART_CR1_RXNEIE_RXFNEIE /*!< Read data register and RXFIFO not empty + interrupt enable */ +#define LL_LPUART_CR1_TCIE USART_CR1_TCIE /*!< Transmission complete interrupt enable */ +#define LL_LPUART_CR1_TXEIE_TXFNFIE USART_CR1_TXEIE_TXFNFIE /*!< Transmit data register empty and TX FIFO + not full interrupt enable */ +#define LL_LPUART_CR1_PEIE USART_CR1_PEIE /*!< Parity error */ +#define LL_LPUART_CR1_CMIE USART_CR1_CMIE /*!< Character match interrupt enable */ +#define LL_LPUART_CR1_TXFEIE USART_CR1_TXFEIE /*!< TX FIFO empty interrupt enable */ +#define LL_LPUART_CR1_RXFFIE USART_CR1_RXFFIE /*!< RX FIFO full interrupt enable */ +#define LL_LPUART_CR3_EIE USART_CR3_EIE /*!< Error interrupt enable */ +#define LL_LPUART_CR3_CTSIE USART_CR3_CTSIE /*!< CTS interrupt enable */ +#define LL_LPUART_CR3_WUFIE USART_CR3_WUFIE /*!< Wakeup from Stop mode interrupt enable */ +#define LL_LPUART_CR3_TXFTIE USART_CR3_TXFTIE /*!< TX FIFO threshold interrupt enable */ +#define LL_LPUART_CR3_RXFTIE USART_CR3_RXFTIE /*!< RX FIFO threshold interrupt enable */ +/** + * @} + */ + +/** @defgroup LPUART_LL_EC_FIFOTHRESHOLD FIFO Threshold + * @{ + */ +#define LL_LPUART_FIFOTHRESHOLD_1_8 0x00000000U /*!< FIFO reaches 1/8 of its depth */ +#define LL_LPUART_FIFOTHRESHOLD_1_4 0x00000001U /*!< FIFO reaches 1/4 of its depth */ +#define LL_LPUART_FIFOTHRESHOLD_1_2 0x00000002U /*!< FIFO reaches 1/2 of its depth */ +#define LL_LPUART_FIFOTHRESHOLD_3_4 0x00000003U /*!< FIFO reaches 3/4 of its depth */ +#define LL_LPUART_FIFOTHRESHOLD_7_8 0x00000004U /*!< FIFO reaches 7/8 of its depth */ +#define LL_LPUART_FIFOTHRESHOLD_8_8 0x00000005U /*!< FIFO becomes empty for TX and full for RX */ +/** + * @} + */ + +/** @defgroup LPUART_LL_EC_DIRECTION Direction + * @{ + */ +#define LL_LPUART_DIRECTION_NONE 0x00000000U /*!< Transmitter and Receiver are disabled */ +#define LL_LPUART_DIRECTION_RX USART_CR1_RE /*!< Transmitter is disabled and Receiver is enabled */ +#define LL_LPUART_DIRECTION_TX USART_CR1_TE /*!< Transmitter is enabled and Receiver is disabled */ +#define LL_LPUART_DIRECTION_TX_RX (USART_CR1_TE |USART_CR1_RE) /*!< Transmitter and Receiver are enabled */ +/** + * @} + */ + +/** @defgroup LPUART_LL_EC_PARITY Parity Control + * @{ + */ +#define LL_LPUART_PARITY_NONE 0x00000000U /*!< Parity control disabled */ +#define LL_LPUART_PARITY_EVEN USART_CR1_PCE /*!< Parity control enabled and Even Parity is selected */ +#define LL_LPUART_PARITY_ODD (USART_CR1_PCE | USART_CR1_PS) /*!< Parity control enabled and Odd Parity is selected */ +/** + * @} + */ + +/** @defgroup LPUART_LL_EC_WAKEUP Wakeup + * @{ + */ +#define LL_LPUART_WAKEUP_IDLELINE 0x00000000U /*!< LPUART wake up from Mute mode on Idle Line */ +#define LL_LPUART_WAKEUP_ADDRESSMARK USART_CR1_WAKE /*!< LPUART wake up from Mute mode on Address Mark */ +/** + * @} + */ + +/** @defgroup LPUART_LL_EC_DATAWIDTH Datawidth + * @{ + */ +#define LL_LPUART_DATAWIDTH_7B USART_CR1_M1 /*!< 7 bits word length : Start bit, 7 data bits, n stop bits */ +#define LL_LPUART_DATAWIDTH_8B 0x00000000U /*!< 8 bits word length : Start bit, 8 data bits, n stop bits */ +#define LL_LPUART_DATAWIDTH_9B USART_CR1_M0 /*!< 9 bits word length : Start bit, 9 data bits, n stop bits */ +/** + * @} + */ + +/** @defgroup LPUART_LL_EC_PRESCALER Clock Source Prescaler + * @{ + */ +#define LL_LPUART_PRESCALER_DIV1 0x00000000U /*!< Input clock not divided */ +#define LL_LPUART_PRESCALER_DIV2 (USART_PRESC_PRESCALER_0) /*!< Input clock divided by 2 */ +#define LL_LPUART_PRESCALER_DIV4 (USART_PRESC_PRESCALER_1) /*!< Input clock divided by 4 */ +#define LL_LPUART_PRESCALER_DIV6 (USART_PRESC_PRESCALER_1 |\ + USART_PRESC_PRESCALER_0) /*!< Input clock divided by 6 */ +#define LL_LPUART_PRESCALER_DIV8 (USART_PRESC_PRESCALER_2) /*!< Input clock divided by 8 */ +#define LL_LPUART_PRESCALER_DIV10 (USART_PRESC_PRESCALER_2 |\ + USART_PRESC_PRESCALER_0) /*!< Input clock divided by 10 */ +#define LL_LPUART_PRESCALER_DIV12 (USART_PRESC_PRESCALER_2 |\ + USART_PRESC_PRESCALER_1) /*!< Input clock divided by 12 */ +#define LL_LPUART_PRESCALER_DIV16 (USART_PRESC_PRESCALER_2 |\ + USART_PRESC_PRESCALER_1 |\ + USART_PRESC_PRESCALER_0) /*!< Input clock divided by 16 */ +#define LL_LPUART_PRESCALER_DIV32 (USART_PRESC_PRESCALER_3) /*!< Input clock divided by 32 */ +#define LL_LPUART_PRESCALER_DIV64 (USART_PRESC_PRESCALER_3 |\ + USART_PRESC_PRESCALER_0) /*!< Input clock divided by 64 */ +#define LL_LPUART_PRESCALER_DIV128 (USART_PRESC_PRESCALER_3 |\ + USART_PRESC_PRESCALER_1) /*!< Input clock divided by 128 */ +#define LL_LPUART_PRESCALER_DIV256 (USART_PRESC_PRESCALER_3 |\ + USART_PRESC_PRESCALER_1 |\ + USART_PRESC_PRESCALER_0) /*!< Input clock divided by 256 */ +/** + * @} + */ + +/** @defgroup LPUART_LL_EC_STOPBITS Stop Bits + * @{ + */ +#define LL_LPUART_STOPBITS_1 0x00000000U /*!< 1 stop bit */ +#define LL_LPUART_STOPBITS_2 USART_CR2_STOP_1 /*!< 2 stop bits */ +/** + * @} + */ + +/** @defgroup LPUART_LL_EC_TXRX TX RX Pins Swap + * @{ + */ +#define LL_LPUART_TXRX_STANDARD 0x00000000U /*!< TX/RX pins are used as defined in standard pinout */ +#define LL_LPUART_TXRX_SWAPPED (USART_CR2_SWAP) /*!< TX and RX pins functions are swapped. */ +/** + * @} + */ + +/** @defgroup LPUART_LL_EC_RXPIN_LEVEL RX Pin Active Level Inversion + * @{ + */ +#define LL_LPUART_RXPIN_LEVEL_STANDARD 0x00000000U /*!< RX pin signal works using the standard logic levels */ +#define LL_LPUART_RXPIN_LEVEL_INVERTED (USART_CR2_RXINV) /*!< RX pin signal values are inverted. */ +/** + * @} + */ + +/** @defgroup LPUART_LL_EC_TXPIN_LEVEL TX Pin Active Level Inversion + * @{ + */ +#define LL_LPUART_TXPIN_LEVEL_STANDARD 0x00000000U /*!< TX pin signal works using the standard logic levels */ +#define LL_LPUART_TXPIN_LEVEL_INVERTED (USART_CR2_TXINV) /*!< TX pin signal values are inverted. */ +/** + * @} + */ + +/** @defgroup LPUART_LL_EC_BINARY_LOGIC Binary Data Inversion + * @{ + */ +#define LL_LPUART_BINARY_LOGIC_POSITIVE 0x00000000U /*!< Logical data from the data register are send/received + in positive/direct logic. (1=H, 0=L) */ +#define LL_LPUART_BINARY_LOGIC_NEGATIVE USART_CR2_DATAINV /*!< Logical data from the data register are send/received + in negative/inverse logic. (1=L, 0=H). + The parity bit is also inverted. */ +/** + * @} + */ + +/** @defgroup LPUART_LL_EC_BITORDER Bit Order + * @{ + */ +#define LL_LPUART_BITORDER_LSBFIRST 0x00000000U /*!< data is transmitted/received with data bit 0 first, + following the start bit */ +#define LL_LPUART_BITORDER_MSBFIRST USART_CR2_MSBFIRST /*!< data is transmitted/received with the MSB first, + following the start bit */ +/** + * @} + */ + +/** @defgroup LPUART_LL_EC_ADDRESS_DETECT Address Length Detection + * @{ + */ +#define LL_LPUART_ADDRESS_DETECT_4B 0x00000000U /*!< 4-bit address detection method selected */ +#define LL_LPUART_ADDRESS_DETECT_7B USART_CR2_ADDM7 /*!< 7-bit address detection (in 8-bit data mode) method selected */ +/** + * @} + */ + +/** @defgroup LPUART_LL_EC_HWCONTROL Hardware Control + * @{ + */ +#define LL_LPUART_HWCONTROL_NONE 0x00000000U /*!< CTS and RTS hardware flow control disabled */ +#define LL_LPUART_HWCONTROL_RTS USART_CR3_RTSE /*!< RTS output enabled, data is only requested + when there is space in the receive buffer */ +#define LL_LPUART_HWCONTROL_CTS USART_CR3_CTSE /*!< CTS mode enabled, data is only transmitted + when the nCTS input is asserted (tied to 0)*/ +#define LL_LPUART_HWCONTROL_RTS_CTS (USART_CR3_RTSE | USART_CR3_CTSE) /*!< CTS and RTS hardware flow control enabled */ +/** + * @} + */ + +/** @defgroup LPUART_LL_EC_WAKEUP_ON Wakeup Activation + * @{ + */ +#define LL_LPUART_WAKEUP_ON_ADDRESS 0x00000000U /*!< Wake up active on address match */ +#define LL_LPUART_WAKEUP_ON_STARTBIT USART_CR3_WUS_1 /*!< Wake up active on Start bit detection */ +#define LL_LPUART_WAKEUP_ON_RXNE (USART_CR3_WUS_0 | USART_CR3_WUS_1) /*!< Wake up active on RXNE */ +/** + * @} + */ + +/** @defgroup LPUART_LL_EC_DE_POLARITY Driver Enable Polarity + * @{ + */ +#define LL_LPUART_DE_POLARITY_HIGH 0x00000000U /*!< DE signal is active high */ +#define LL_LPUART_DE_POLARITY_LOW USART_CR3_DEP /*!< DE signal is active low */ +/** + * @} + */ + +/** @defgroup LPUART_LL_EC_DMA_REG_DATA DMA Register Data + * @{ + */ +#define LL_LPUART_DMA_REG_DATA_TRANSMIT 0x00000000U /*!< Get address of data register used for transmission */ +#define LL_LPUART_DMA_REG_DATA_RECEIVE 0x00000001U /*!< Get address of data register used for reception */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup LPUART_LL_Exported_Macros LPUART Exported Macros + * @{ + */ + +/** @defgroup LPUART_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in LPUART register + * @param __INSTANCE__ LPUART Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_LPUART_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in LPUART register + * @param __INSTANCE__ LPUART Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_LPUART_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) +/** + * @} + */ + +/** @defgroup LPUART_LL_EM_Exported_Macros_Helper Helper Macros + * @{ + */ + +/** + * @brief Compute LPUARTDIV value according to Peripheral Clock and + * expected Baud Rate (20-bit value of LPUARTDIV is returned) + * @param __PERIPHCLK__ Peripheral Clock frequency used for LPUART Instance + * @param __PRESCALER__ This parameter can be one of the following values: + * @arg @ref LL_LPUART_PRESCALER_DIV1 + * @arg @ref LL_LPUART_PRESCALER_DIV2 + * @arg @ref LL_LPUART_PRESCALER_DIV4 + * @arg @ref LL_LPUART_PRESCALER_DIV6 + * @arg @ref LL_LPUART_PRESCALER_DIV8 + * @arg @ref LL_LPUART_PRESCALER_DIV10 + * @arg @ref LL_LPUART_PRESCALER_DIV12 + * @arg @ref LL_LPUART_PRESCALER_DIV16 + * @arg @ref LL_LPUART_PRESCALER_DIV32 + * @arg @ref LL_LPUART_PRESCALER_DIV64 + * @arg @ref LL_LPUART_PRESCALER_DIV128 + * @arg @ref LL_LPUART_PRESCALER_DIV256 + * @param __BAUDRATE__ Baud Rate value to achieve + * @retval LPUARTDIV value to be used for BRR register filling + */ +#define __LL_LPUART_DIV(__PERIPHCLK__, __PRESCALER__, __BAUDRATE__) (uint32_t)\ + ((((((uint64_t)(__PERIPHCLK__)/(uint64_t)(LPUART_PRESCALER_TAB[(uint16_t)(__PRESCALER__)]))\ + * LPUART_LPUARTDIV_FREQ_MUL) + (uint32_t)((__BAUDRATE__)/2U))/(__BAUDRATE__)) & LPUART_BRR_MASK) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup LPUART_LL_Exported_Functions LPUART Exported Functions + * @{ + */ + +/** @defgroup LPUART_LL_EF_Configuration Configuration functions + * @{ + */ + +/** + * @brief LPUART Enable + * @rmtoll CR1 UE LL_LPUART_Enable + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_Enable(USART_TypeDef *LPUARTx) +{ + SET_BIT(LPUARTx->CR1, USART_CR1_UE); +} + +/** + * @brief LPUART Disable + * @note When LPUART is disabled, LPUART prescalers and outputs are stopped immediately, + * and current operations are discarded. The configuration of the LPUART is kept, but all the status + * flags, in the LPUARTx_ISR are set to their default values. + * @note In order to go into low-power mode without generating errors on the line, + * the TE bit must be reset before and the software must wait + * for the TC bit in the LPUART_ISR to be set before resetting the UE bit. + * The DMA requests are also reset when UE = 0 so the DMA channel must + * be disabled before resetting the UE bit. + * @rmtoll CR1 UE LL_LPUART_Disable + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_Disable(USART_TypeDef *LPUARTx) +{ + CLEAR_BIT(LPUARTx->CR1, USART_CR1_UE); +} + +/** + * @brief Indicate if LPUART is enabled + * @rmtoll CR1 UE LL_LPUART_IsEnabled + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsEnabled(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->CR1, USART_CR1_UE) == (USART_CR1_UE)) ? 1UL : 0UL); +} + +/** + * @brief FIFO Mode Enable + * @rmtoll CR1 FIFOEN LL_LPUART_EnableFIFO + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_EnableFIFO(USART_TypeDef *LPUARTx) +{ + SET_BIT(LPUARTx->CR1, USART_CR1_FIFOEN); +} + +/** + * @brief FIFO Mode Disable + * @rmtoll CR1 FIFOEN LL_LPUART_DisableFIFO + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_DisableFIFO(USART_TypeDef *LPUARTx) +{ + CLEAR_BIT(LPUARTx->CR1, USART_CR1_FIFOEN); +} + +/** + * @brief Indicate if FIFO Mode is enabled + * @rmtoll CR1 FIFOEN LL_LPUART_IsEnabledFIFO + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsEnabledFIFO(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->CR1, USART_CR1_FIFOEN) == (USART_CR1_FIFOEN)) ? 1UL : 0UL); +} + +/** + * @brief Configure TX FIFO Threshold + * @rmtoll CR3 TXFTCFG LL_LPUART_SetTXFIFOThreshold + * @param LPUARTx LPUART Instance + * @param Threshold This parameter can be one of the following values: + * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_8 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_4 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_2 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_3_4 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_7_8 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_8_8 + * @retval None + */ +__STATIC_INLINE void LL_LPUART_SetTXFIFOThreshold(USART_TypeDef *LPUARTx, uint32_t Threshold) +{ + ATOMIC_MODIFY_REG(LPUARTx->CR3, USART_CR3_TXFTCFG, Threshold << USART_CR3_TXFTCFG_Pos); +} + +/** + * @brief Return TX FIFO Threshold Configuration + * @rmtoll CR3 TXFTCFG LL_LPUART_GetTXFIFOThreshold + * @param LPUARTx LPUART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_8 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_4 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_2 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_3_4 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_7_8 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_8_8 + */ +__STATIC_INLINE uint32_t LL_LPUART_GetTXFIFOThreshold(const USART_TypeDef *LPUARTx) +{ + return (uint32_t)(READ_BIT(LPUARTx->CR3, USART_CR3_TXFTCFG) >> USART_CR3_TXFTCFG_Pos); +} + +/** + * @brief Configure RX FIFO Threshold + * @rmtoll CR3 RXFTCFG LL_LPUART_SetRXFIFOThreshold + * @param LPUARTx LPUART Instance + * @param Threshold This parameter can be one of the following values: + * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_8 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_4 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_2 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_3_4 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_7_8 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_8_8 + * @retval None + */ +__STATIC_INLINE void LL_LPUART_SetRXFIFOThreshold(USART_TypeDef *LPUARTx, uint32_t Threshold) +{ + ATOMIC_MODIFY_REG(LPUARTx->CR3, USART_CR3_RXFTCFG, Threshold << USART_CR3_RXFTCFG_Pos); +} + +/** + * @brief Return RX FIFO Threshold Configuration + * @rmtoll CR3 RXFTCFG LL_LPUART_GetRXFIFOThreshold + * @param LPUARTx LPUART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_8 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_4 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_2 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_3_4 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_7_8 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_8_8 + */ +__STATIC_INLINE uint32_t LL_LPUART_GetRXFIFOThreshold(const USART_TypeDef *LPUARTx) +{ + return (uint32_t)(READ_BIT(LPUARTx->CR3, USART_CR3_RXFTCFG) >> USART_CR3_RXFTCFG_Pos); +} + +/** + * @brief Configure TX and RX FIFOs Threshold + * @rmtoll CR3 TXFTCFG LL_LPUART_ConfigFIFOsThreshold\n + * CR3 RXFTCFG LL_LPUART_ConfigFIFOsThreshold + * @param LPUARTx LPUART Instance + * @param TXThreshold This parameter can be one of the following values: + * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_8 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_4 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_2 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_3_4 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_7_8 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_8_8 + * @param RXThreshold This parameter can be one of the following values: + * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_8 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_4 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_1_2 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_3_4 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_7_8 + * @arg @ref LL_LPUART_FIFOTHRESHOLD_8_8 + * @retval None + */ +__STATIC_INLINE void LL_LPUART_ConfigFIFOsThreshold(USART_TypeDef *LPUARTx, uint32_t TXThreshold, uint32_t RXThreshold) +{ + ATOMIC_MODIFY_REG(LPUARTx->CR3, USART_CR3_TXFTCFG | USART_CR3_RXFTCFG, (TXThreshold << USART_CR3_TXFTCFG_Pos) | \ + (RXThreshold << USART_CR3_RXFTCFG_Pos)); +} + +/** + * @brief LPUART enabled in STOP Mode + * @note When this function is enabled, LPUART is able to wake up the MCU from Stop mode, provided that + * LPUART clock selection is HSI or LSE in RCC. + * @rmtoll CR1 UESM LL_LPUART_EnableInStopMode + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_EnableInStopMode(USART_TypeDef *LPUARTx) +{ + ATOMIC_SET_BIT(LPUARTx->CR1, USART_CR1_UESM); +} + +/** + * @brief LPUART disabled in STOP Mode + * @note When this function is disabled, LPUART is not able to wake up the MCU from Stop mode + * @rmtoll CR1 UESM LL_LPUART_DisableInStopMode + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_DisableInStopMode(USART_TypeDef *LPUARTx) +{ + ATOMIC_CLEAR_BIT(LPUARTx->CR1, USART_CR1_UESM); +} + +/** + * @brief Indicate if LPUART is enabled in STOP Mode + * (able to wake up MCU from Stop mode or not) + * @rmtoll CR1 UESM LL_LPUART_IsEnabledInStopMode + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsEnabledInStopMode(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->CR1, USART_CR1_UESM) == (USART_CR1_UESM)) ? 1UL : 0UL); +} + +/** + * @brief Receiver Enable (Receiver is enabled and begins searching for a start bit) + * @rmtoll CR1 RE LL_LPUART_EnableDirectionRx + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_EnableDirectionRx(USART_TypeDef *LPUARTx) +{ + ATOMIC_SET_BIT(LPUARTx->CR1, USART_CR1_RE); +} + +/** + * @brief Receiver Disable + * @rmtoll CR1 RE LL_LPUART_DisableDirectionRx + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_DisableDirectionRx(USART_TypeDef *LPUARTx) +{ + ATOMIC_CLEAR_BIT(LPUARTx->CR1, USART_CR1_RE); +} + +/** + * @brief Transmitter Enable + * @rmtoll CR1 TE LL_LPUART_EnableDirectionTx + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_EnableDirectionTx(USART_TypeDef *LPUARTx) +{ + ATOMIC_SET_BIT(LPUARTx->CR1, USART_CR1_TE); +} + +/** + * @brief Transmitter Disable + * @rmtoll CR1 TE LL_LPUART_DisableDirectionTx + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_DisableDirectionTx(USART_TypeDef *LPUARTx) +{ + ATOMIC_CLEAR_BIT(LPUARTx->CR1, USART_CR1_TE); +} + +/** + * @brief Configure simultaneously enabled/disabled states + * of Transmitter and Receiver + * @rmtoll CR1 RE LL_LPUART_SetTransferDirection\n + * CR1 TE LL_LPUART_SetTransferDirection + * @param LPUARTx LPUART Instance + * @param TransferDirection This parameter can be one of the following values: + * @arg @ref LL_LPUART_DIRECTION_NONE + * @arg @ref LL_LPUART_DIRECTION_RX + * @arg @ref LL_LPUART_DIRECTION_TX + * @arg @ref LL_LPUART_DIRECTION_TX_RX + * @retval None + */ +__STATIC_INLINE void LL_LPUART_SetTransferDirection(USART_TypeDef *LPUARTx, uint32_t TransferDirection) +{ + ATOMIC_MODIFY_REG(LPUARTx->CR1, USART_CR1_RE | USART_CR1_TE, TransferDirection); +} + +/** + * @brief Return enabled/disabled states of Transmitter and Receiver + * @rmtoll CR1 RE LL_LPUART_GetTransferDirection\n + * CR1 TE LL_LPUART_GetTransferDirection + * @param LPUARTx LPUART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPUART_DIRECTION_NONE + * @arg @ref LL_LPUART_DIRECTION_RX + * @arg @ref LL_LPUART_DIRECTION_TX + * @arg @ref LL_LPUART_DIRECTION_TX_RX + */ +__STATIC_INLINE uint32_t LL_LPUART_GetTransferDirection(const USART_TypeDef *LPUARTx) +{ + return (uint32_t)(READ_BIT(LPUARTx->CR1, USART_CR1_RE | USART_CR1_TE)); +} + +/** + * @brief Configure Parity (enabled/disabled and parity mode if enabled) + * @note This function selects if hardware parity control (generation and detection) is enabled or disabled. + * When the parity control is enabled (Odd or Even), computed parity bit is inserted at the MSB position + * (depending on data width) and parity is checked on the received data. + * @rmtoll CR1 PS LL_LPUART_SetParity\n + * CR1 PCE LL_LPUART_SetParity + * @param LPUARTx LPUART Instance + * @param Parity This parameter can be one of the following values: + * @arg @ref LL_LPUART_PARITY_NONE + * @arg @ref LL_LPUART_PARITY_EVEN + * @arg @ref LL_LPUART_PARITY_ODD + * @retval None + */ +__STATIC_INLINE void LL_LPUART_SetParity(USART_TypeDef *LPUARTx, uint32_t Parity) +{ + MODIFY_REG(LPUARTx->CR1, USART_CR1_PS | USART_CR1_PCE, Parity); +} + +/** + * @brief Return Parity configuration (enabled/disabled and parity mode if enabled) + * @rmtoll CR1 PS LL_LPUART_GetParity\n + * CR1 PCE LL_LPUART_GetParity + * @param LPUARTx LPUART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPUART_PARITY_NONE + * @arg @ref LL_LPUART_PARITY_EVEN + * @arg @ref LL_LPUART_PARITY_ODD + */ +__STATIC_INLINE uint32_t LL_LPUART_GetParity(const USART_TypeDef *LPUARTx) +{ + return (uint32_t)(READ_BIT(LPUARTx->CR1, USART_CR1_PS | USART_CR1_PCE)); +} + +/** + * @brief Set Receiver Wake Up method from Mute mode. + * @rmtoll CR1 WAKE LL_LPUART_SetWakeUpMethod + * @param LPUARTx LPUART Instance + * @param Method This parameter can be one of the following values: + * @arg @ref LL_LPUART_WAKEUP_IDLELINE + * @arg @ref LL_LPUART_WAKEUP_ADDRESSMARK + * @retval None + */ +__STATIC_INLINE void LL_LPUART_SetWakeUpMethod(USART_TypeDef *LPUARTx, uint32_t Method) +{ + MODIFY_REG(LPUARTx->CR1, USART_CR1_WAKE, Method); +} + +/** + * @brief Return Receiver Wake Up method from Mute mode + * @rmtoll CR1 WAKE LL_LPUART_GetWakeUpMethod + * @param LPUARTx LPUART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPUART_WAKEUP_IDLELINE + * @arg @ref LL_LPUART_WAKEUP_ADDRESSMARK + */ +__STATIC_INLINE uint32_t LL_LPUART_GetWakeUpMethod(const USART_TypeDef *LPUARTx) +{ + return (uint32_t)(READ_BIT(LPUARTx->CR1, USART_CR1_WAKE)); +} + +/** + * @brief Set Word length (nb of data bits, excluding start and stop bits) + * @rmtoll CR1 M LL_LPUART_SetDataWidth + * @param LPUARTx LPUART Instance + * @param DataWidth This parameter can be one of the following values: + * @arg @ref LL_LPUART_DATAWIDTH_7B + * @arg @ref LL_LPUART_DATAWIDTH_8B + * @arg @ref LL_LPUART_DATAWIDTH_9B + * @retval None + */ +__STATIC_INLINE void LL_LPUART_SetDataWidth(USART_TypeDef *LPUARTx, uint32_t DataWidth) +{ + MODIFY_REG(LPUARTx->CR1, USART_CR1_M, DataWidth); +} + +/** + * @brief Return Word length (i.e. nb of data bits, excluding start and stop bits) + * @rmtoll CR1 M LL_LPUART_GetDataWidth + * @param LPUARTx LPUART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPUART_DATAWIDTH_7B + * @arg @ref LL_LPUART_DATAWIDTH_8B + * @arg @ref LL_LPUART_DATAWIDTH_9B + */ +__STATIC_INLINE uint32_t LL_LPUART_GetDataWidth(const USART_TypeDef *LPUARTx) +{ + return (uint32_t)(READ_BIT(LPUARTx->CR1, USART_CR1_M)); +} + +/** + * @brief Allow switch between Mute Mode and Active mode + * @rmtoll CR1 MME LL_LPUART_EnableMuteMode + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_EnableMuteMode(USART_TypeDef *LPUARTx) +{ + ATOMIC_SET_BIT(LPUARTx->CR1, USART_CR1_MME); +} + +/** + * @brief Prevent Mute Mode use. Set Receiver in active mode permanently. + * @rmtoll CR1 MME LL_LPUART_DisableMuteMode + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_DisableMuteMode(USART_TypeDef *LPUARTx) +{ + ATOMIC_CLEAR_BIT(LPUARTx->CR1, USART_CR1_MME); +} + +/** + * @brief Indicate if switch between Mute Mode and Active mode is allowed + * @rmtoll CR1 MME LL_LPUART_IsEnabledMuteMode + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsEnabledMuteMode(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->CR1, USART_CR1_MME) == (USART_CR1_MME)) ? 1UL : 0UL); +} + +/** + * @brief Configure Clock source prescaler for baudrate generator and oversampling + * @rmtoll PRESC PRESCALER LL_LPUART_SetPrescaler + * @param LPUARTx LPUART Instance + * @param PrescalerValue This parameter can be one of the following values: + * @arg @ref LL_LPUART_PRESCALER_DIV1 + * @arg @ref LL_LPUART_PRESCALER_DIV2 + * @arg @ref LL_LPUART_PRESCALER_DIV4 + * @arg @ref LL_LPUART_PRESCALER_DIV6 + * @arg @ref LL_LPUART_PRESCALER_DIV8 + * @arg @ref LL_LPUART_PRESCALER_DIV10 + * @arg @ref LL_LPUART_PRESCALER_DIV12 + * @arg @ref LL_LPUART_PRESCALER_DIV16 + * @arg @ref LL_LPUART_PRESCALER_DIV32 + * @arg @ref LL_LPUART_PRESCALER_DIV64 + * @arg @ref LL_LPUART_PRESCALER_DIV128 + * @arg @ref LL_LPUART_PRESCALER_DIV256 + * @retval None + */ +__STATIC_INLINE void LL_LPUART_SetPrescaler(USART_TypeDef *LPUARTx, uint32_t PrescalerValue) +{ + MODIFY_REG(LPUARTx->PRESC, USART_PRESC_PRESCALER, (uint16_t)PrescalerValue); +} + +/** + * @brief Retrieve the Clock source prescaler for baudrate generator and oversampling + * @rmtoll PRESC PRESCALER LL_LPUART_GetPrescaler + * @param LPUARTx LPUART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPUART_PRESCALER_DIV1 + * @arg @ref LL_LPUART_PRESCALER_DIV2 + * @arg @ref LL_LPUART_PRESCALER_DIV4 + * @arg @ref LL_LPUART_PRESCALER_DIV6 + * @arg @ref LL_LPUART_PRESCALER_DIV8 + * @arg @ref LL_LPUART_PRESCALER_DIV10 + * @arg @ref LL_LPUART_PRESCALER_DIV12 + * @arg @ref LL_LPUART_PRESCALER_DIV16 + * @arg @ref LL_LPUART_PRESCALER_DIV32 + * @arg @ref LL_LPUART_PRESCALER_DIV64 + * @arg @ref LL_LPUART_PRESCALER_DIV128 + * @arg @ref LL_LPUART_PRESCALER_DIV256 + */ +__STATIC_INLINE uint32_t LL_LPUART_GetPrescaler(const USART_TypeDef *LPUARTx) +{ + return (uint32_t)(READ_BIT(LPUARTx->PRESC, USART_PRESC_PRESCALER)); +} + +/** + * @brief Set the length of the stop bits + * @rmtoll CR2 STOP LL_LPUART_SetStopBitsLength + * @param LPUARTx LPUART Instance + * @param StopBits This parameter can be one of the following values: + * @arg @ref LL_LPUART_STOPBITS_1 + * @arg @ref LL_LPUART_STOPBITS_2 + * @retval None + */ +__STATIC_INLINE void LL_LPUART_SetStopBitsLength(USART_TypeDef *LPUARTx, uint32_t StopBits) +{ + MODIFY_REG(LPUARTx->CR2, USART_CR2_STOP, StopBits); +} + +/** + * @brief Retrieve the length of the stop bits + * @rmtoll CR2 STOP LL_LPUART_GetStopBitsLength + * @param LPUARTx LPUART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPUART_STOPBITS_1 + * @arg @ref LL_LPUART_STOPBITS_2 + */ +__STATIC_INLINE uint32_t LL_LPUART_GetStopBitsLength(const USART_TypeDef *LPUARTx) +{ + return (uint32_t)(READ_BIT(LPUARTx->CR2, USART_CR2_STOP)); +} + +/** + * @brief Configure Character frame format (Datawidth, Parity control, Stop Bits) + * @note Call of this function is equivalent to following function call sequence : + * - Data Width configuration using @ref LL_LPUART_SetDataWidth() function + * - Parity Control and mode configuration using @ref LL_LPUART_SetParity() function + * - Stop bits configuration using @ref LL_LPUART_SetStopBitsLength() function + * @rmtoll CR1 PS LL_LPUART_ConfigCharacter\n + * CR1 PCE LL_LPUART_ConfigCharacter\n + * CR1 M LL_LPUART_ConfigCharacter\n + * CR2 STOP LL_LPUART_ConfigCharacter + * @param LPUARTx LPUART Instance + * @param DataWidth This parameter can be one of the following values: + * @arg @ref LL_LPUART_DATAWIDTH_7B + * @arg @ref LL_LPUART_DATAWIDTH_8B + * @arg @ref LL_LPUART_DATAWIDTH_9B + * @param Parity This parameter can be one of the following values: + * @arg @ref LL_LPUART_PARITY_NONE + * @arg @ref LL_LPUART_PARITY_EVEN + * @arg @ref LL_LPUART_PARITY_ODD + * @param StopBits This parameter can be one of the following values: + * @arg @ref LL_LPUART_STOPBITS_1 + * @arg @ref LL_LPUART_STOPBITS_2 + * @retval None + */ +__STATIC_INLINE void LL_LPUART_ConfigCharacter(USART_TypeDef *LPUARTx, uint32_t DataWidth, uint32_t Parity, + uint32_t StopBits) +{ + MODIFY_REG(LPUARTx->CR1, USART_CR1_PS | USART_CR1_PCE | USART_CR1_M, Parity | DataWidth); + MODIFY_REG(LPUARTx->CR2, USART_CR2_STOP, StopBits); +} + +/** + * @brief Configure TX/RX pins swapping setting. + * @rmtoll CR2 SWAP LL_LPUART_SetTXRXSwap + * @param LPUARTx LPUART Instance + * @param SwapConfig This parameter can be one of the following values: + * @arg @ref LL_LPUART_TXRX_STANDARD + * @arg @ref LL_LPUART_TXRX_SWAPPED + * @retval None + */ +__STATIC_INLINE void LL_LPUART_SetTXRXSwap(USART_TypeDef *LPUARTx, uint32_t SwapConfig) +{ + MODIFY_REG(LPUARTx->CR2, USART_CR2_SWAP, SwapConfig); +} + +/** + * @brief Retrieve TX/RX pins swapping configuration. + * @rmtoll CR2 SWAP LL_LPUART_GetTXRXSwap + * @param LPUARTx LPUART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPUART_TXRX_STANDARD + * @arg @ref LL_LPUART_TXRX_SWAPPED + */ +__STATIC_INLINE uint32_t LL_LPUART_GetTXRXSwap(const USART_TypeDef *LPUARTx) +{ + return (uint32_t)(READ_BIT(LPUARTx->CR2, USART_CR2_SWAP)); +} + +/** + * @brief Configure RX pin active level logic + * @rmtoll CR2 RXINV LL_LPUART_SetRXPinLevel + * @param LPUARTx LPUART Instance + * @param PinInvMethod This parameter can be one of the following values: + * @arg @ref LL_LPUART_RXPIN_LEVEL_STANDARD + * @arg @ref LL_LPUART_RXPIN_LEVEL_INVERTED + * @retval None + */ +__STATIC_INLINE void LL_LPUART_SetRXPinLevel(USART_TypeDef *LPUARTx, uint32_t PinInvMethod) +{ + MODIFY_REG(LPUARTx->CR2, USART_CR2_RXINV, PinInvMethod); +} + +/** + * @brief Retrieve RX pin active level logic configuration + * @rmtoll CR2 RXINV LL_LPUART_GetRXPinLevel + * @param LPUARTx LPUART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPUART_RXPIN_LEVEL_STANDARD + * @arg @ref LL_LPUART_RXPIN_LEVEL_INVERTED + */ +__STATIC_INLINE uint32_t LL_LPUART_GetRXPinLevel(const USART_TypeDef *LPUARTx) +{ + return (uint32_t)(READ_BIT(LPUARTx->CR2, USART_CR2_RXINV)); +} + +/** + * @brief Configure TX pin active level logic + * @rmtoll CR2 TXINV LL_LPUART_SetTXPinLevel + * @param LPUARTx LPUART Instance + * @param PinInvMethod This parameter can be one of the following values: + * @arg @ref LL_LPUART_TXPIN_LEVEL_STANDARD + * @arg @ref LL_LPUART_TXPIN_LEVEL_INVERTED + * @retval None + */ +__STATIC_INLINE void LL_LPUART_SetTXPinLevel(USART_TypeDef *LPUARTx, uint32_t PinInvMethod) +{ + MODIFY_REG(LPUARTx->CR2, USART_CR2_TXINV, PinInvMethod); +} + +/** + * @brief Retrieve TX pin active level logic configuration + * @rmtoll CR2 TXINV LL_LPUART_GetTXPinLevel + * @param LPUARTx LPUART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPUART_TXPIN_LEVEL_STANDARD + * @arg @ref LL_LPUART_TXPIN_LEVEL_INVERTED + */ +__STATIC_INLINE uint32_t LL_LPUART_GetTXPinLevel(const USART_TypeDef *LPUARTx) +{ + return (uint32_t)(READ_BIT(LPUARTx->CR2, USART_CR2_TXINV)); +} + +/** + * @brief Configure Binary data logic. + * + * @note Allow to define how Logical data from the data register are send/received : + * either in positive/direct logic (1=H, 0=L) or in negative/inverse logic (1=L, 0=H) + * @rmtoll CR2 DATAINV LL_LPUART_SetBinaryDataLogic + * @param LPUARTx LPUART Instance + * @param DataLogic This parameter can be one of the following values: + * @arg @ref LL_LPUART_BINARY_LOGIC_POSITIVE + * @arg @ref LL_LPUART_BINARY_LOGIC_NEGATIVE + * @retval None + */ +__STATIC_INLINE void LL_LPUART_SetBinaryDataLogic(USART_TypeDef *LPUARTx, uint32_t DataLogic) +{ + MODIFY_REG(LPUARTx->CR2, USART_CR2_DATAINV, DataLogic); +} + +/** + * @brief Retrieve Binary data configuration + * @rmtoll CR2 DATAINV LL_LPUART_GetBinaryDataLogic + * @param LPUARTx LPUART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPUART_BINARY_LOGIC_POSITIVE + * @arg @ref LL_LPUART_BINARY_LOGIC_NEGATIVE + */ +__STATIC_INLINE uint32_t LL_LPUART_GetBinaryDataLogic(const USART_TypeDef *LPUARTx) +{ + return (uint32_t)(READ_BIT(LPUARTx->CR2, USART_CR2_DATAINV)); +} + +/** + * @brief Configure transfer bit order (either Less or Most Significant Bit First) + * @note MSB First means data is transmitted/received with the MSB first, following the start bit. + * LSB First means data is transmitted/received with data bit 0 first, following the start bit. + * @rmtoll CR2 MSBFIRST LL_LPUART_SetTransferBitOrder + * @param LPUARTx LPUART Instance + * @param BitOrder This parameter can be one of the following values: + * @arg @ref LL_LPUART_BITORDER_LSBFIRST + * @arg @ref LL_LPUART_BITORDER_MSBFIRST + * @retval None + */ +__STATIC_INLINE void LL_LPUART_SetTransferBitOrder(USART_TypeDef *LPUARTx, uint32_t BitOrder) +{ + MODIFY_REG(LPUARTx->CR2, USART_CR2_MSBFIRST, BitOrder); +} + +/** + * @brief Return transfer bit order (either Less or Most Significant Bit First) + * @note MSB First means data is transmitted/received with the MSB first, following the start bit. + * LSB First means data is transmitted/received with data bit 0 first, following the start bit. + * @rmtoll CR2 MSBFIRST LL_LPUART_GetTransferBitOrder + * @param LPUARTx LPUART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPUART_BITORDER_LSBFIRST + * @arg @ref LL_LPUART_BITORDER_MSBFIRST + */ +__STATIC_INLINE uint32_t LL_LPUART_GetTransferBitOrder(const USART_TypeDef *LPUARTx) +{ + return (uint32_t)(READ_BIT(LPUARTx->CR2, USART_CR2_MSBFIRST)); +} + +/** + * @brief Set Address of the LPUART node. + * @note This is used in multiprocessor communication during Mute mode or Stop mode, + * for wake up with address mark detection. + * @note 4bits address node is used when 4-bit Address Detection is selected in ADDM7. + * (b7-b4 should be set to 0) + * 8bits address node is used when 7-bit Address Detection is selected in ADDM7. + * (This is used in multiprocessor communication during Mute mode or Stop mode, + * for wake up with 7-bit address mark detection. + * The MSB of the character sent by the transmitter should be equal to 1. + * It may also be used for character detection during normal reception, + * Mute mode inactive (for example, end of block detection in ModBus protocol). + * In this case, the whole received character (8-bit) is compared to the ADD[7:0] + * value and CMF flag is set on match) + * @rmtoll CR2 ADD LL_LPUART_ConfigNodeAddress\n + * CR2 ADDM7 LL_LPUART_ConfigNodeAddress + * @param LPUARTx LPUART Instance + * @param AddressLen This parameter can be one of the following values: + * @arg @ref LL_LPUART_ADDRESS_DETECT_4B + * @arg @ref LL_LPUART_ADDRESS_DETECT_7B + * @param NodeAddress 4 or 7 bit Address of the LPUART node. + * @retval None + */ +__STATIC_INLINE void LL_LPUART_ConfigNodeAddress(USART_TypeDef *LPUARTx, uint32_t AddressLen, uint32_t NodeAddress) +{ + MODIFY_REG(LPUARTx->CR2, USART_CR2_ADD | USART_CR2_ADDM7, + (uint32_t)(AddressLen | (NodeAddress << USART_CR2_ADD_Pos))); +} + +/** + * @brief Return 8 bit Address of the LPUART node as set in ADD field of CR2. + * @note If 4-bit Address Detection is selected in ADDM7, + * only 4bits (b3-b0) of returned value are relevant (b31-b4 are not relevant) + * If 7-bit Address Detection is selected in ADDM7, + * only 8bits (b7-b0) of returned value are relevant (b31-b8 are not relevant) + * @rmtoll CR2 ADD LL_LPUART_GetNodeAddress + * @param LPUARTx LPUART Instance + * @retval Address of the LPUART node (Value between Min_Data=0 and Max_Data=255) + */ +__STATIC_INLINE uint32_t LL_LPUART_GetNodeAddress(const USART_TypeDef *LPUARTx) +{ + return (uint32_t)(READ_BIT(LPUARTx->CR2, USART_CR2_ADD) >> USART_CR2_ADD_Pos); +} + +/** + * @brief Return Length of Node Address used in Address Detection mode (7-bit or 4-bit) + * @rmtoll CR2 ADDM7 LL_LPUART_GetNodeAddressLen + * @param LPUARTx LPUART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPUART_ADDRESS_DETECT_4B + * @arg @ref LL_LPUART_ADDRESS_DETECT_7B + */ +__STATIC_INLINE uint32_t LL_LPUART_GetNodeAddressLen(const USART_TypeDef *LPUARTx) +{ + return (uint32_t)(READ_BIT(LPUARTx->CR2, USART_CR2_ADDM7)); +} + +/** + * @brief Enable RTS HW Flow Control + * @rmtoll CR3 RTSE LL_LPUART_EnableRTSHWFlowCtrl + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_EnableRTSHWFlowCtrl(USART_TypeDef *LPUARTx) +{ + SET_BIT(LPUARTx->CR3, USART_CR3_RTSE); +} + +/** + * @brief Disable RTS HW Flow Control + * @rmtoll CR3 RTSE LL_LPUART_DisableRTSHWFlowCtrl + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_DisableRTSHWFlowCtrl(USART_TypeDef *LPUARTx) +{ + CLEAR_BIT(LPUARTx->CR3, USART_CR3_RTSE); +} + +/** + * @brief Enable CTS HW Flow Control + * @rmtoll CR3 CTSE LL_LPUART_EnableCTSHWFlowCtrl + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_EnableCTSHWFlowCtrl(USART_TypeDef *LPUARTx) +{ + SET_BIT(LPUARTx->CR3, USART_CR3_CTSE); +} + +/** + * @brief Disable CTS HW Flow Control + * @rmtoll CR3 CTSE LL_LPUART_DisableCTSHWFlowCtrl + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_DisableCTSHWFlowCtrl(USART_TypeDef *LPUARTx) +{ + CLEAR_BIT(LPUARTx->CR3, USART_CR3_CTSE); +} + +/** + * @brief Configure HW Flow Control mode (both CTS and RTS) + * @rmtoll CR3 RTSE LL_LPUART_SetHWFlowCtrl\n + * CR3 CTSE LL_LPUART_SetHWFlowCtrl + * @param LPUARTx LPUART Instance + * @param HardwareFlowControl This parameter can be one of the following values: + * @arg @ref LL_LPUART_HWCONTROL_NONE + * @arg @ref LL_LPUART_HWCONTROL_RTS + * @arg @ref LL_LPUART_HWCONTROL_CTS + * @arg @ref LL_LPUART_HWCONTROL_RTS_CTS + * @retval None + */ +__STATIC_INLINE void LL_LPUART_SetHWFlowCtrl(USART_TypeDef *LPUARTx, uint32_t HardwareFlowControl) +{ + MODIFY_REG(LPUARTx->CR3, USART_CR3_RTSE | USART_CR3_CTSE, HardwareFlowControl); +} + +/** + * @brief Return HW Flow Control configuration (both CTS and RTS) + * @rmtoll CR3 RTSE LL_LPUART_GetHWFlowCtrl\n + * CR3 CTSE LL_LPUART_GetHWFlowCtrl + * @param LPUARTx LPUART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPUART_HWCONTROL_NONE + * @arg @ref LL_LPUART_HWCONTROL_RTS + * @arg @ref LL_LPUART_HWCONTROL_CTS + * @arg @ref LL_LPUART_HWCONTROL_RTS_CTS + */ +__STATIC_INLINE uint32_t LL_LPUART_GetHWFlowCtrl(const USART_TypeDef *LPUARTx) +{ + return (uint32_t)(READ_BIT(LPUARTx->CR3, USART_CR3_RTSE | USART_CR3_CTSE)); +} + +/** + * @brief Enable Overrun detection + * @rmtoll CR3 OVRDIS LL_LPUART_EnableOverrunDetect + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_EnableOverrunDetect(USART_TypeDef *LPUARTx) +{ + CLEAR_BIT(LPUARTx->CR3, USART_CR3_OVRDIS); +} + +/** + * @brief Disable Overrun detection + * @rmtoll CR3 OVRDIS LL_LPUART_DisableOverrunDetect + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_DisableOverrunDetect(USART_TypeDef *LPUARTx) +{ + SET_BIT(LPUARTx->CR3, USART_CR3_OVRDIS); +} + +/** + * @brief Indicate if Overrun detection is enabled + * @rmtoll CR3 OVRDIS LL_LPUART_IsEnabledOverrunDetect + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsEnabledOverrunDetect(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->CR3, USART_CR3_OVRDIS) != USART_CR3_OVRDIS) ? 1UL : 0UL); +} + +/** + * @brief Select event type for Wake UP Interrupt Flag (WUS[1:0] bits) + * @rmtoll CR3 WUS LL_LPUART_SetWKUPType + * @param LPUARTx LPUART Instance + * @param Type This parameter can be one of the following values: + * @arg @ref LL_LPUART_WAKEUP_ON_ADDRESS + * @arg @ref LL_LPUART_WAKEUP_ON_STARTBIT + * @arg @ref LL_LPUART_WAKEUP_ON_RXNE + * @retval None + */ +__STATIC_INLINE void LL_LPUART_SetWKUPType(USART_TypeDef *LPUARTx, uint32_t Type) +{ + MODIFY_REG(LPUARTx->CR3, USART_CR3_WUS, Type); +} + +/** + * @brief Return event type for Wake UP Interrupt Flag (WUS[1:0] bits) + * @rmtoll CR3 WUS LL_LPUART_GetWKUPType + * @param LPUARTx LPUART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPUART_WAKEUP_ON_ADDRESS + * @arg @ref LL_LPUART_WAKEUP_ON_STARTBIT + * @arg @ref LL_LPUART_WAKEUP_ON_RXNE + */ +__STATIC_INLINE uint32_t LL_LPUART_GetWKUPType(const USART_TypeDef *LPUARTx) +{ + return (uint32_t)(READ_BIT(LPUARTx->CR3, USART_CR3_WUS)); +} + +/** + * @brief Configure LPUART BRR register for achieving expected Baud Rate value. + * + * @note Compute and set LPUARTDIV value in BRR Register (full BRR content) + * according to used Peripheral Clock and expected Baud Rate values + * @note Peripheral clock and Baud Rate values provided as function parameters should be valid + * (Baud rate value != 0). + * @note Provided that LPUARTx_BRR must be > = 0x300 and LPUART_BRR is 20-bit, + * a care should be taken when generating high baud rates using high PeriphClk + * values. PeriphClk must be in the range [3 x BaudRate, 4096 x BaudRate]. + * @rmtoll BRR BRR LL_LPUART_SetBaudRate + * @param LPUARTx LPUART Instance + * @param PeriphClk Peripheral Clock + * @param PrescalerValue This parameter can be one of the following values: + * @arg @ref LL_LPUART_PRESCALER_DIV1 + * @arg @ref LL_LPUART_PRESCALER_DIV2 + * @arg @ref LL_LPUART_PRESCALER_DIV4 + * @arg @ref LL_LPUART_PRESCALER_DIV6 + * @arg @ref LL_LPUART_PRESCALER_DIV8 + * @arg @ref LL_LPUART_PRESCALER_DIV10 + * @arg @ref LL_LPUART_PRESCALER_DIV12 + * @arg @ref LL_LPUART_PRESCALER_DIV16 + * @arg @ref LL_LPUART_PRESCALER_DIV32 + * @arg @ref LL_LPUART_PRESCALER_DIV64 + * @arg @ref LL_LPUART_PRESCALER_DIV128 + * @arg @ref LL_LPUART_PRESCALER_DIV256 + * @param BaudRate Baud Rate + * @retval None + */ +__STATIC_INLINE void LL_LPUART_SetBaudRate(USART_TypeDef *LPUARTx, uint32_t PeriphClk, uint32_t PrescalerValue, + uint32_t BaudRate) +{ + if (BaudRate != 0U) + { + LPUARTx->BRR = __LL_LPUART_DIV(PeriphClk, PrescalerValue, BaudRate); + } +} + +/** + * @brief Return current Baud Rate value, according to LPUARTDIV present in BRR register + * (full BRR content), and to used Peripheral Clock values + * @note In case of non-initialized or invalid value stored in BRR register, value 0 will be returned. + * @rmtoll BRR BRR LL_LPUART_GetBaudRate + * @param LPUARTx LPUART Instance + * @param PeriphClk Peripheral Clock + * @param PrescalerValue This parameter can be one of the following values: + * @arg @ref LL_LPUART_PRESCALER_DIV1 + * @arg @ref LL_LPUART_PRESCALER_DIV2 + * @arg @ref LL_LPUART_PRESCALER_DIV4 + * @arg @ref LL_LPUART_PRESCALER_DIV6 + * @arg @ref LL_LPUART_PRESCALER_DIV8 + * @arg @ref LL_LPUART_PRESCALER_DIV10 + * @arg @ref LL_LPUART_PRESCALER_DIV12 + * @arg @ref LL_LPUART_PRESCALER_DIV16 + * @arg @ref LL_LPUART_PRESCALER_DIV32 + * @arg @ref LL_LPUART_PRESCALER_DIV64 + * @arg @ref LL_LPUART_PRESCALER_DIV128 + * @arg @ref LL_LPUART_PRESCALER_DIV256 + * @retval Baud Rate + */ +__STATIC_INLINE uint32_t LL_LPUART_GetBaudRate(const USART_TypeDef *LPUARTx, uint32_t PeriphClk, + uint32_t PrescalerValue) +{ + uint32_t lpuartdiv; + uint32_t brrresult; + uint32_t periphclkpresc = (uint32_t)(PeriphClk / (LPUART_PRESCALER_TAB[(uint16_t)PrescalerValue])); + + lpuartdiv = LPUARTx->BRR & LPUART_BRR_MASK; + + if (lpuartdiv >= LPUART_BRR_MIN_VALUE) + { + brrresult = (uint32_t)(((uint64_t)(periphclkpresc) * LPUART_LPUARTDIV_FREQ_MUL) / lpuartdiv); + } + else + { + brrresult = 0x0UL; + } + + return (brrresult); +} + +/** + * @} + */ + +/** @defgroup LPUART_LL_EF_Configuration_HalfDuplex Configuration functions related to Half Duplex feature + * @{ + */ + +/** + * @brief Enable Single Wire Half-Duplex mode + * @rmtoll CR3 HDSEL LL_LPUART_EnableHalfDuplex + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_EnableHalfDuplex(USART_TypeDef *LPUARTx) +{ + SET_BIT(LPUARTx->CR3, USART_CR3_HDSEL); +} + +/** + * @brief Disable Single Wire Half-Duplex mode + * @rmtoll CR3 HDSEL LL_LPUART_DisableHalfDuplex + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_DisableHalfDuplex(USART_TypeDef *LPUARTx) +{ + CLEAR_BIT(LPUARTx->CR3, USART_CR3_HDSEL); +} + +/** + * @brief Indicate if Single Wire Half-Duplex mode is enabled + * @rmtoll CR3 HDSEL LL_LPUART_IsEnabledHalfDuplex + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsEnabledHalfDuplex(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->CR3, USART_CR3_HDSEL) == (USART_CR3_HDSEL)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup LPUART_LL_EF_Configuration_DE Configuration functions related to Driver Enable feature + * @{ + */ + +/** + * @brief Set DEDT (Driver Enable De-Assertion Time), Time value expressed on 5 bits ([4:0] bits). + * @rmtoll CR1 DEDT LL_LPUART_SetDEDeassertionTime + * @param LPUARTx LPUART Instance + * @param Time Value between Min_Data=0 and Max_Data=31 + * @retval None + */ +__STATIC_INLINE void LL_LPUART_SetDEDeassertionTime(USART_TypeDef *LPUARTx, uint32_t Time) +{ + MODIFY_REG(LPUARTx->CR1, USART_CR1_DEDT, Time << USART_CR1_DEDT_Pos); +} + +/** + * @brief Return DEDT (Driver Enable De-Assertion Time) + * @rmtoll CR1 DEDT LL_LPUART_GetDEDeassertionTime + * @param LPUARTx LPUART Instance + * @retval Time value expressed on 5 bits ([4:0] bits) : c + */ +__STATIC_INLINE uint32_t LL_LPUART_GetDEDeassertionTime(const USART_TypeDef *LPUARTx) +{ + return (uint32_t)(READ_BIT(LPUARTx->CR1, USART_CR1_DEDT) >> USART_CR1_DEDT_Pos); +} + +/** + * @brief Set DEAT (Driver Enable Assertion Time), Time value expressed on 5 bits ([4:0] bits). + * @rmtoll CR1 DEAT LL_LPUART_SetDEAssertionTime + * @param LPUARTx LPUART Instance + * @param Time Value between Min_Data=0 and Max_Data=31 + * @retval None + */ +__STATIC_INLINE void LL_LPUART_SetDEAssertionTime(USART_TypeDef *LPUARTx, uint32_t Time) +{ + MODIFY_REG(LPUARTx->CR1, USART_CR1_DEAT, Time << USART_CR1_DEAT_Pos); +} + +/** + * @brief Return DEAT (Driver Enable Assertion Time) + * @rmtoll CR1 DEAT LL_LPUART_GetDEAssertionTime + * @param LPUARTx LPUART Instance + * @retval Time value expressed on 5 bits ([4:0] bits) : Time Value between Min_Data=0 and Max_Data=31 + */ +__STATIC_INLINE uint32_t LL_LPUART_GetDEAssertionTime(const USART_TypeDef *LPUARTx) +{ + return (uint32_t)(READ_BIT(LPUARTx->CR1, USART_CR1_DEAT) >> USART_CR1_DEAT_Pos); +} + +/** + * @brief Enable Driver Enable (DE) Mode + * @rmtoll CR3 DEM LL_LPUART_EnableDEMode + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_EnableDEMode(USART_TypeDef *LPUARTx) +{ + SET_BIT(LPUARTx->CR3, USART_CR3_DEM); +} + +/** + * @brief Disable Driver Enable (DE) Mode + * @rmtoll CR3 DEM LL_LPUART_DisableDEMode + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_DisableDEMode(USART_TypeDef *LPUARTx) +{ + CLEAR_BIT(LPUARTx->CR3, USART_CR3_DEM); +} + +/** + * @brief Indicate if Driver Enable (DE) Mode is enabled + * @rmtoll CR3 DEM LL_LPUART_IsEnabledDEMode + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsEnabledDEMode(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->CR3, USART_CR3_DEM) == (USART_CR3_DEM)) ? 1UL : 0UL); +} + +/** + * @brief Select Driver Enable Polarity + * @rmtoll CR3 DEP LL_LPUART_SetDESignalPolarity + * @param LPUARTx LPUART Instance + * @param Polarity This parameter can be one of the following values: + * @arg @ref LL_LPUART_DE_POLARITY_HIGH + * @arg @ref LL_LPUART_DE_POLARITY_LOW + * @retval None + */ +__STATIC_INLINE void LL_LPUART_SetDESignalPolarity(USART_TypeDef *LPUARTx, uint32_t Polarity) +{ + MODIFY_REG(LPUARTx->CR3, USART_CR3_DEP, Polarity); +} + +/** + * @brief Return Driver Enable Polarity + * @rmtoll CR3 DEP LL_LPUART_GetDESignalPolarity + * @param LPUARTx LPUART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_LPUART_DE_POLARITY_HIGH + * @arg @ref LL_LPUART_DE_POLARITY_LOW + */ +__STATIC_INLINE uint32_t LL_LPUART_GetDESignalPolarity(const USART_TypeDef *LPUARTx) +{ + return (uint32_t)(READ_BIT(LPUARTx->CR3, USART_CR3_DEP)); +} + +/** + * @} + */ + +/** @defgroup LPUART_LL_EF_FLAG_Management FLAG_Management + * @{ + */ + +/** + * @brief Check if the LPUART Parity Error Flag is set or not + * @rmtoll ISR PE LL_LPUART_IsActiveFlag_PE + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_PE(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->ISR, USART_ISR_PE) == (USART_ISR_PE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the LPUART Framing Error Flag is set or not + * @rmtoll ISR FE LL_LPUART_IsActiveFlag_FE + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_FE(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->ISR, USART_ISR_FE) == (USART_ISR_FE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the LPUART Noise error detected Flag is set or not + * @rmtoll ISR NE LL_LPUART_IsActiveFlag_NE + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_NE(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->ISR, USART_ISR_NE) == (USART_ISR_NE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the LPUART OverRun Error Flag is set or not + * @rmtoll ISR ORE LL_LPUART_IsActiveFlag_ORE + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_ORE(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->ISR, USART_ISR_ORE) == (USART_ISR_ORE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the LPUART IDLE line detected Flag is set or not + * @rmtoll ISR IDLE LL_LPUART_IsActiveFlag_IDLE + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_IDLE(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->ISR, USART_ISR_IDLE) == (USART_ISR_IDLE)) ? 1UL : 0UL); +} + +#define LL_LPUART_IsActiveFlag_RXNE LL_LPUART_IsActiveFlag_RXNE_RXFNE /* Redefinition for legacy purpose */ + +/** + * @brief Check if the LPUART Read Data Register or LPUART RX FIFO Not Empty Flag is set or not + * @rmtoll ISR RXNE_RXFNE LL_LPUART_IsActiveFlag_RXNE_RXFNE + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_RXNE_RXFNE(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->ISR, USART_ISR_RXNE_RXFNE) == (USART_ISR_RXNE_RXFNE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the LPUART Transmission Complete Flag is set or not + * @rmtoll ISR TC LL_LPUART_IsActiveFlag_TC + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_TC(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->ISR, USART_ISR_TC) == (USART_ISR_TC)) ? 1UL : 0UL); +} + +#define LL_LPUART_IsActiveFlag_TXE LL_LPUART_IsActiveFlag_TXE_TXFNF /* Redefinition for legacy purpose */ + +/** + * @brief Check if the LPUART Transmit Data Register Empty or LPUART TX FIFO Not Full Flag is set or not + * @rmtoll ISR TXE_TXFNF LL_LPUART_IsActiveFlag_TXE_TXFNF + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_TXE_TXFNF(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->ISR, USART_ISR_TXE_TXFNF) == (USART_ISR_TXE_TXFNF)) ? 1UL : 0UL); +} + +/** + * @brief Check if the LPUART CTS interrupt Flag is set or not + * @rmtoll ISR CTSIF LL_LPUART_IsActiveFlag_nCTS + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_nCTS(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->ISR, USART_ISR_CTSIF) == (USART_ISR_CTSIF)) ? 1UL : 0UL); +} + +/** + * @brief Check if the LPUART CTS Flag is set or not + * @rmtoll ISR CTS LL_LPUART_IsActiveFlag_CTS + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_CTS(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->ISR, USART_ISR_CTS) == (USART_ISR_CTS)) ? 1UL : 0UL); +} + +/** + * @brief Check if the LPUART Busy Flag is set or not + * @rmtoll ISR BUSY LL_LPUART_IsActiveFlag_BUSY + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_BUSY(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->ISR, USART_ISR_BUSY) == (USART_ISR_BUSY)) ? 1UL : 0UL); +} + +/** + * @brief Check if the LPUART Character Match Flag is set or not + * @rmtoll ISR CMF LL_LPUART_IsActiveFlag_CM + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_CM(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->ISR, USART_ISR_CMF) == (USART_ISR_CMF)) ? 1UL : 0UL); +} + +/** + * @brief Check if the LPUART Send Break Flag is set or not + * @rmtoll ISR SBKF LL_LPUART_IsActiveFlag_SBK + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_SBK(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->ISR, USART_ISR_SBKF) == (USART_ISR_SBKF)) ? 1UL : 0UL); +} + +/** + * @brief Check if the LPUART Receive Wake Up from mute mode Flag is set or not + * @rmtoll ISR RWU LL_LPUART_IsActiveFlag_RWU + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_RWU(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->ISR, USART_ISR_RWU) == (USART_ISR_RWU)) ? 1UL : 0UL); +} + +/** + * @brief Check if the LPUART Wake Up from stop mode Flag is set or not + * @rmtoll ISR WUF LL_LPUART_IsActiveFlag_WKUP + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_WKUP(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->ISR, USART_ISR_WUF) == (USART_ISR_WUF)) ? 1UL : 0UL); +} + +/** + * @brief Check if the LPUART Transmit Enable Acknowledge Flag is set or not + * @rmtoll ISR TEACK LL_LPUART_IsActiveFlag_TEACK + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_TEACK(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->ISR, USART_ISR_TEACK) == (USART_ISR_TEACK)) ? 1UL : 0UL); +} + +/** + * @brief Check if the LPUART Receive Enable Acknowledge Flag is set or not + * @rmtoll ISR REACK LL_LPUART_IsActiveFlag_REACK + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_REACK(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->ISR, USART_ISR_REACK) == (USART_ISR_REACK)) ? 1UL : 0UL); +} + +/** + * @brief Check if the LPUART TX FIFO Empty Flag is set or not + * @rmtoll ISR TXFE LL_LPUART_IsActiveFlag_TXFE + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_TXFE(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->ISR, USART_ISR_TXFE) == (USART_ISR_TXFE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the LPUART RX FIFO Full Flag is set or not + * @rmtoll ISR RXFF LL_LPUART_IsActiveFlag_RXFF + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_RXFF(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->ISR, USART_ISR_RXFF) == (USART_ISR_RXFF)) ? 1UL : 0UL); +} + +/** + * @brief Check if the LPUART TX FIFO Threshold Flag is set or not + * @rmtoll ISR TXFT LL_LPUART_IsActiveFlag_TXFT + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_TXFT(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->ISR, USART_ISR_TXFT) == (USART_ISR_TXFT)) ? 1UL : 0UL); +} + +/** + * @brief Check if the LPUART RX FIFO Threshold Flag is set or not + * @rmtoll ISR RXFT LL_LPUART_IsActiveFlag_RXFT + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsActiveFlag_RXFT(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->ISR, USART_ISR_RXFT) == (USART_ISR_RXFT)) ? 1UL : 0UL); +} + +/** + * @brief Clear Parity Error Flag + * @rmtoll ICR PECF LL_LPUART_ClearFlag_PE + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_ClearFlag_PE(USART_TypeDef *LPUARTx) +{ + WRITE_REG(LPUARTx->ICR, USART_ICR_PECF); +} + +/** + * @brief Clear Framing Error Flag + * @rmtoll ICR FECF LL_LPUART_ClearFlag_FE + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_ClearFlag_FE(USART_TypeDef *LPUARTx) +{ + WRITE_REG(LPUARTx->ICR, USART_ICR_FECF); +} + +/** + * @brief Clear Noise detected Flag + * @rmtoll ICR NECF LL_LPUART_ClearFlag_NE + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_ClearFlag_NE(USART_TypeDef *LPUARTx) +{ + WRITE_REG(LPUARTx->ICR, USART_ICR_NECF); +} + +/** + * @brief Clear OverRun Error Flag + * @rmtoll ICR ORECF LL_LPUART_ClearFlag_ORE + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_ClearFlag_ORE(USART_TypeDef *LPUARTx) +{ + WRITE_REG(LPUARTx->ICR, USART_ICR_ORECF); +} + +/** + * @brief Clear IDLE line detected Flag + * @rmtoll ICR IDLECF LL_LPUART_ClearFlag_IDLE + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_ClearFlag_IDLE(USART_TypeDef *LPUARTx) +{ + WRITE_REG(LPUARTx->ICR, USART_ICR_IDLECF); +} + +/** + * @brief Clear Transmission Complete Flag + * @rmtoll ICR TCCF LL_LPUART_ClearFlag_TC + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_ClearFlag_TC(USART_TypeDef *LPUARTx) +{ + WRITE_REG(LPUARTx->ICR, USART_ICR_TCCF); +} + +/** + * @brief Clear CTS Interrupt Flag + * @rmtoll ICR CTSCF LL_LPUART_ClearFlag_nCTS + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_ClearFlag_nCTS(USART_TypeDef *LPUARTx) +{ + WRITE_REG(LPUARTx->ICR, USART_ICR_CTSCF); +} + +/** + * @brief Clear Character Match Flag + * @rmtoll ICR CMCF LL_LPUART_ClearFlag_CM + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_ClearFlag_CM(USART_TypeDef *LPUARTx) +{ + WRITE_REG(LPUARTx->ICR, USART_ICR_CMCF); +} + +/** + * @brief Clear Wake Up from stop mode Flag + * @rmtoll ICR WUCF LL_LPUART_ClearFlag_WKUP + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_ClearFlag_WKUP(USART_TypeDef *LPUARTx) +{ + WRITE_REG(LPUARTx->ICR, USART_ICR_WUCF); +} + +/** + * @} + */ + +/** @defgroup LPUART_LL_EF_IT_Management IT_Management + * @{ + */ + +/** + * @brief Enable IDLE Interrupt + * @rmtoll CR1 IDLEIE LL_LPUART_EnableIT_IDLE + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_EnableIT_IDLE(USART_TypeDef *LPUARTx) +{ + ATOMIC_SET_BIT(LPUARTx->CR1, USART_CR1_IDLEIE); +} + +#define LL_LPUART_EnableIT_RXNE LL_LPUART_EnableIT_RXNE_RXFNE /* Redefinition for legacy purpose */ + +/** + * @brief Enable RX Not Empty and RX FIFO Not Empty Interrupt + * @rmtoll CR1 RXNEIE_RXFNEIE LL_LPUART_EnableIT_RXNE_RXFNE + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_EnableIT_RXNE_RXFNE(USART_TypeDef *LPUARTx) +{ + ATOMIC_SET_BIT(LPUARTx->CR1, USART_CR1_RXNEIE_RXFNEIE); +} + +/** + * @brief Enable Transmission Complete Interrupt + * @rmtoll CR1 TCIE LL_LPUART_EnableIT_TC + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_EnableIT_TC(USART_TypeDef *LPUARTx) +{ + ATOMIC_SET_BIT(LPUARTx->CR1, USART_CR1_TCIE); +} + +#define LL_LPUART_EnableIT_TXE LL_LPUART_EnableIT_TXE_TXFNF /* Redefinition for legacy purpose */ + +/** + * @brief Enable TX Empty and TX FIFO Not Full Interrupt + * @rmtoll CR1 TXEIE_TXFNFIE LL_LPUART_EnableIT_TXE_TXFNF + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_EnableIT_TXE_TXFNF(USART_TypeDef *LPUARTx) +{ + ATOMIC_SET_BIT(LPUARTx->CR1, USART_CR1_TXEIE_TXFNFIE); +} + +/** + * @brief Enable Parity Error Interrupt + * @rmtoll CR1 PEIE LL_LPUART_EnableIT_PE + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_EnableIT_PE(USART_TypeDef *LPUARTx) +{ + ATOMIC_SET_BIT(LPUARTx->CR1, USART_CR1_PEIE); +} + +/** + * @brief Enable Character Match Interrupt + * @rmtoll CR1 CMIE LL_LPUART_EnableIT_CM + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_EnableIT_CM(USART_TypeDef *LPUARTx) +{ + ATOMIC_SET_BIT(LPUARTx->CR1, USART_CR1_CMIE); +} + +/** + * @brief Enable TX FIFO Empty Interrupt + * @rmtoll CR1 TXFEIE LL_LPUART_EnableIT_TXFE + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_EnableIT_TXFE(USART_TypeDef *LPUARTx) +{ + ATOMIC_SET_BIT(LPUARTx->CR1, USART_CR1_TXFEIE); +} + +/** + * @brief Enable RX FIFO Full Interrupt + * @rmtoll CR1 RXFFIE LL_LPUART_EnableIT_RXFF + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_EnableIT_RXFF(USART_TypeDef *LPUARTx) +{ + ATOMIC_SET_BIT(LPUARTx->CR1, USART_CR1_RXFFIE); +} + +/** + * @brief Enable Error Interrupt + * @note When set, Error Interrupt Enable Bit is enabling interrupt generation in case of a framing + * error, overrun error or noise flag (FE=1 or ORE=1 or NF=1 in the LPUARTx_ISR register). + * - 0: Interrupt is inhibited + * - 1: An interrupt is generated when FE=1 or ORE=1 or NF=1 in the LPUARTx_ISR register. + * @rmtoll CR3 EIE LL_LPUART_EnableIT_ERROR + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_EnableIT_ERROR(USART_TypeDef *LPUARTx) +{ + ATOMIC_SET_BIT(LPUARTx->CR3, USART_CR3_EIE); +} + +/** + * @brief Enable CTS Interrupt + * @rmtoll CR3 CTSIE LL_LPUART_EnableIT_CTS + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_EnableIT_CTS(USART_TypeDef *LPUARTx) +{ + ATOMIC_SET_BIT(LPUARTx->CR3, USART_CR3_CTSIE); +} + +/** + * @brief Enable Wake Up from Stop Mode Interrupt + * @rmtoll CR3 WUFIE LL_LPUART_EnableIT_WKUP + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_EnableIT_WKUP(USART_TypeDef *LPUARTx) +{ + ATOMIC_SET_BIT(LPUARTx->CR3, USART_CR3_WUFIE); +} + +/** + * @brief Enable TX FIFO Threshold Interrupt + * @rmtoll CR3 TXFTIE LL_LPUART_EnableIT_TXFT + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_EnableIT_TXFT(USART_TypeDef *LPUARTx) +{ + ATOMIC_SET_BIT(LPUARTx->CR3, USART_CR3_TXFTIE); +} + +/** + * @brief Enable RX FIFO Threshold Interrupt + * @rmtoll CR3 RXFTIE LL_LPUART_EnableIT_RXFT + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_EnableIT_RXFT(USART_TypeDef *LPUARTx) +{ + ATOMIC_SET_BIT(LPUARTx->CR3, USART_CR3_RXFTIE); +} + +/** + * @brief Disable IDLE Interrupt + * @rmtoll CR1 IDLEIE LL_LPUART_DisableIT_IDLE + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_DisableIT_IDLE(USART_TypeDef *LPUARTx) +{ + ATOMIC_CLEAR_BIT(LPUARTx->CR1, USART_CR1_IDLEIE); +} + +#define LL_LPUART_DisableIT_RXNE LL_LPUART_DisableIT_RXNE_RXFNE /* Redefinition for legacy purpose */ + +/** + * @brief Disable RX Not Empty and RX FIFO Not Empty Interrupt + * @rmtoll CR1 RXNEIE_RXFNEIE LL_LPUART_DisableIT_RXNE_RXFNE + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_DisableIT_RXNE_RXFNE(USART_TypeDef *LPUARTx) +{ + ATOMIC_CLEAR_BIT(LPUARTx->CR1, USART_CR1_RXNEIE_RXFNEIE); +} + +/** + * @brief Disable Transmission Complete Interrupt + * @rmtoll CR1 TCIE LL_LPUART_DisableIT_TC + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_DisableIT_TC(USART_TypeDef *LPUARTx) +{ + ATOMIC_CLEAR_BIT(LPUARTx->CR1, USART_CR1_TCIE); +} + +#define LL_LPUART_DisableIT_TXE LL_LPUART_DisableIT_TXE_TXFNF /* Redefinition for legacy purpose */ + +/** + * @brief Disable TX Empty and TX FIFO Not Full Interrupt + * @rmtoll CR1 TXEIE_TXFNFIE LL_LPUART_DisableIT_TXE_TXFNF + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_DisableIT_TXE_TXFNF(USART_TypeDef *LPUARTx) +{ + ATOMIC_CLEAR_BIT(LPUARTx->CR1, USART_CR1_TXEIE_TXFNFIE); +} + +/** + * @brief Disable Parity Error Interrupt + * @rmtoll CR1 PEIE LL_LPUART_DisableIT_PE + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_DisableIT_PE(USART_TypeDef *LPUARTx) +{ + ATOMIC_CLEAR_BIT(LPUARTx->CR1, USART_CR1_PEIE); +} + +/** + * @brief Disable Character Match Interrupt + * @rmtoll CR1 CMIE LL_LPUART_DisableIT_CM + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_DisableIT_CM(USART_TypeDef *LPUARTx) +{ + ATOMIC_CLEAR_BIT(LPUARTx->CR1, USART_CR1_CMIE); +} + +/** + * @brief Disable TX FIFO Empty Interrupt + * @rmtoll CR1 TXFEIE LL_LPUART_DisableIT_TXFE + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_DisableIT_TXFE(USART_TypeDef *LPUARTx) +{ + ATOMIC_CLEAR_BIT(LPUARTx->CR1, USART_CR1_TXFEIE); +} + +/** + * @brief Disable RX FIFO Full Interrupt + * @rmtoll CR1 RXFFIE LL_LPUART_DisableIT_RXFF + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_DisableIT_RXFF(USART_TypeDef *LPUARTx) +{ + ATOMIC_CLEAR_BIT(LPUARTx->CR1, USART_CR1_RXFFIE); +} + +/** + * @brief Disable Error Interrupt + * @note When set, Error Interrupt Enable Bit is enabling interrupt generation in case of a framing + * error, overrun error or noise flag (FE=1 or ORE=1 or NF=1 in the LPUARTx_ISR register). + * - 0: Interrupt is inhibited + * - 1: An interrupt is generated when FE=1 or ORE=1 or NF=1 in the LPUARTx_ISR register. + * @rmtoll CR3 EIE LL_LPUART_DisableIT_ERROR + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_DisableIT_ERROR(USART_TypeDef *LPUARTx) +{ + ATOMIC_CLEAR_BIT(LPUARTx->CR3, USART_CR3_EIE); +} + +/** + * @brief Disable CTS Interrupt + * @rmtoll CR3 CTSIE LL_LPUART_DisableIT_CTS + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_DisableIT_CTS(USART_TypeDef *LPUARTx) +{ + ATOMIC_CLEAR_BIT(LPUARTx->CR3, USART_CR3_CTSIE); +} + +/** + * @brief Disable Wake Up from Stop Mode Interrupt + * @rmtoll CR3 WUFIE LL_LPUART_DisableIT_WKUP + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_DisableIT_WKUP(USART_TypeDef *LPUARTx) +{ + ATOMIC_CLEAR_BIT(LPUARTx->CR3, USART_CR3_WUFIE); +} + +/** + * @brief Disable TX FIFO Threshold Interrupt + * @rmtoll CR3 TXFTIE LL_LPUART_DisableIT_TXFT + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_DisableIT_TXFT(USART_TypeDef *LPUARTx) +{ + ATOMIC_CLEAR_BIT(LPUARTx->CR3, USART_CR3_TXFTIE); +} + +/** + * @brief Disable RX FIFO Threshold Interrupt + * @rmtoll CR3 RXFTIE LL_LPUART_DisableIT_RXFT + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_DisableIT_RXFT(USART_TypeDef *LPUARTx) +{ + ATOMIC_CLEAR_BIT(LPUARTx->CR3, USART_CR3_RXFTIE); +} + +/** + * @brief Check if the LPUART IDLE Interrupt source is enabled or disabled. + * @rmtoll CR1 IDLEIE LL_LPUART_IsEnabledIT_IDLE + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsEnabledIT_IDLE(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->CR1, USART_CR1_IDLEIE) == (USART_CR1_IDLEIE)) ? 1UL : 0UL); +} + +#define LL_LPUART_IsEnabledIT_RXNE LL_LPUART_IsEnabledIT_RXNE_RXFNE /* Redefinition for legacy purpose */ + +/** + * @brief Check if the LPUART RX Not Empty and LPUART RX FIFO Not Empty Interrupt is enabled or disabled. + * @rmtoll CR1 RXNEIE_RXFNEIE LL_LPUART_IsEnabledIT_RXNE_RXFNE + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsEnabledIT_RXNE_RXFNE(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->CR1, USART_CR1_RXNEIE_RXFNEIE) == (USART_CR1_RXNEIE_RXFNEIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the LPUART Transmission Complete Interrupt is enabled or disabled. + * @rmtoll CR1 TCIE LL_LPUART_IsEnabledIT_TC + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsEnabledIT_TC(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->CR1, USART_CR1_TCIE) == (USART_CR1_TCIE)) ? 1UL : 0UL); +} + +#define LL_LPUART_IsEnabledIT_TXE LL_LPUART_IsEnabledIT_TXE_TXFNF /* Redefinition for legacy purpose */ + +/** + * @brief Check if the LPUART TX Empty and LPUART TX FIFO Not Full Interrupt is enabled or disabled + * @rmtoll CR1 TXEIE_TXFNFIE LL_LPUART_IsEnabledIT_TXE_TXFNF + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsEnabledIT_TXE_TXFNF(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->CR1, USART_CR1_TXEIE_TXFNFIE) == (USART_CR1_TXEIE_TXFNFIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the LPUART Parity Error Interrupt is enabled or disabled. + * @rmtoll CR1 PEIE LL_LPUART_IsEnabledIT_PE + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsEnabledIT_PE(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->CR1, USART_CR1_PEIE) == (USART_CR1_PEIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the LPUART Character Match Interrupt is enabled or disabled. + * @rmtoll CR1 CMIE LL_LPUART_IsEnabledIT_CM + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsEnabledIT_CM(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->CR1, USART_CR1_CMIE) == (USART_CR1_CMIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the LPUART TX FIFO Empty Interrupt is enabled or disabled + * @rmtoll CR1 TXFEIE LL_LPUART_IsEnabledIT_TXFE + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsEnabledIT_TXFE(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->CR1, USART_CR1_TXFEIE) == (USART_CR1_TXFEIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the LPUART RX FIFO Full Interrupt is enabled or disabled + * @rmtoll CR1 RXFFIE LL_LPUART_IsEnabledIT_RXFF + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsEnabledIT_RXFF(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->CR1, USART_CR1_RXFFIE) == (USART_CR1_RXFFIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the LPUART Error Interrupt is enabled or disabled. + * @rmtoll CR3 EIE LL_LPUART_IsEnabledIT_ERROR + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsEnabledIT_ERROR(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->CR3, USART_CR3_EIE) == (USART_CR3_EIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the LPUART CTS Interrupt is enabled or disabled. + * @rmtoll CR3 CTSIE LL_LPUART_IsEnabledIT_CTS + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsEnabledIT_CTS(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->CR3, USART_CR3_CTSIE) == (USART_CR3_CTSIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the LPUART Wake Up from Stop Mode Interrupt is enabled or disabled. + * @rmtoll CR3 WUFIE LL_LPUART_IsEnabledIT_WKUP + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsEnabledIT_WKUP(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->CR3, USART_CR3_WUFIE) == (USART_CR3_WUFIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if LPUART TX FIFO Threshold Interrupt is enabled or disabled + * @rmtoll CR3 TXFTIE LL_LPUART_IsEnabledIT_TXFT + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsEnabledIT_TXFT(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->CR3, USART_CR3_TXFTIE) == (USART_CR3_TXFTIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if LPUART RX FIFO Threshold Interrupt is enabled or disabled + * @rmtoll CR3 RXFTIE LL_LPUART_IsEnabledIT_RXFT + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsEnabledIT_RXFT(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->CR3, USART_CR3_RXFTIE) == (USART_CR3_RXFTIE)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup LPUART_LL_EF_DMA_Management DMA_Management + * @{ + */ + +/** + * @brief Enable DMA Mode for reception + * @rmtoll CR3 DMAR LL_LPUART_EnableDMAReq_RX + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_EnableDMAReq_RX(USART_TypeDef *LPUARTx) +{ + ATOMIC_SET_BIT(LPUARTx->CR3, USART_CR3_DMAR); +} + +/** + * @brief Disable DMA Mode for reception + * @rmtoll CR3 DMAR LL_LPUART_DisableDMAReq_RX + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_DisableDMAReq_RX(USART_TypeDef *LPUARTx) +{ + ATOMIC_CLEAR_BIT(LPUARTx->CR3, USART_CR3_DMAR); +} + +/** + * @brief Check if DMA Mode is enabled for reception + * @rmtoll CR3 DMAR LL_LPUART_IsEnabledDMAReq_RX + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsEnabledDMAReq_RX(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->CR3, USART_CR3_DMAR) == (USART_CR3_DMAR)) ? 1UL : 0UL); +} + +/** + * @brief Enable DMA Mode for transmission + * @rmtoll CR3 DMAT LL_LPUART_EnableDMAReq_TX + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_EnableDMAReq_TX(USART_TypeDef *LPUARTx) +{ + ATOMIC_SET_BIT(LPUARTx->CR3, USART_CR3_DMAT); +} + +/** + * @brief Disable DMA Mode for transmission + * @rmtoll CR3 DMAT LL_LPUART_DisableDMAReq_TX + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_DisableDMAReq_TX(USART_TypeDef *LPUARTx) +{ + ATOMIC_CLEAR_BIT(LPUARTx->CR3, USART_CR3_DMAT); +} + +/** + * @brief Check if DMA Mode is enabled for transmission + * @rmtoll CR3 DMAT LL_LPUART_IsEnabledDMAReq_TX + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsEnabledDMAReq_TX(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->CR3, USART_CR3_DMAT) == (USART_CR3_DMAT)) ? 1UL : 0UL); +} + +/** + * @brief Enable DMA Disabling on Reception Error + * @rmtoll CR3 DDRE LL_LPUART_EnableDMADeactOnRxErr + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_EnableDMADeactOnRxErr(USART_TypeDef *LPUARTx) +{ + SET_BIT(LPUARTx->CR3, USART_CR3_DDRE); +} + +/** + * @brief Disable DMA Disabling on Reception Error + * @rmtoll CR3 DDRE LL_LPUART_DisableDMADeactOnRxErr + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_DisableDMADeactOnRxErr(USART_TypeDef *LPUARTx) +{ + CLEAR_BIT(LPUARTx->CR3, USART_CR3_DDRE); +} + +/** + * @brief Indicate if DMA Disabling on Reception Error is disabled + * @rmtoll CR3 DDRE LL_LPUART_IsEnabledDMADeactOnRxErr + * @param LPUARTx LPUART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_LPUART_IsEnabledDMADeactOnRxErr(const USART_TypeDef *LPUARTx) +{ + return ((READ_BIT(LPUARTx->CR3, USART_CR3_DDRE) == (USART_CR3_DDRE)) ? 1UL : 0UL); +} + +/** + * @brief Get the LPUART data register address used for DMA transfer + * @rmtoll RDR RDR LL_LPUART_DMA_GetRegAddr\n + * @rmtoll TDR TDR LL_LPUART_DMA_GetRegAddr + * @param LPUARTx LPUART Instance + * @param Direction This parameter can be one of the following values: + * @arg @ref LL_LPUART_DMA_REG_DATA_TRANSMIT + * @arg @ref LL_LPUART_DMA_REG_DATA_RECEIVE + * @retval Address of data register + */ +__STATIC_INLINE uint32_t LL_LPUART_DMA_GetRegAddr(const USART_TypeDef *LPUARTx, uint32_t Direction) +{ + uint32_t data_reg_addr; + + if (Direction == LL_LPUART_DMA_REG_DATA_TRANSMIT) + { + /* return address of TDR register */ + data_reg_addr = (uint32_t) &(LPUARTx->TDR); + } + else + { + /* return address of RDR register */ + data_reg_addr = (uint32_t) &(LPUARTx->RDR); + } + + return data_reg_addr; +} + +/** + * @} + */ + +/** @defgroup LPUART_LL_EF_Data_Management Data_Management + * @{ + */ + +/** + * @brief Read Receiver Data register (Receive Data value, 8 bits) + * @rmtoll RDR RDR LL_LPUART_ReceiveData8 + * @param LPUARTx LPUART Instance + * @retval Time Value between Min_Data=0x00 and Max_Data=0xFF + */ +__STATIC_INLINE uint8_t LL_LPUART_ReceiveData8(const USART_TypeDef *LPUARTx) +{ + return (uint8_t)(READ_BIT(LPUARTx->RDR, USART_RDR_RDR) & 0xFFU); +} + +/** + * @brief Read Receiver Data register (Receive Data value, 9 bits) + * @rmtoll RDR RDR LL_LPUART_ReceiveData9 + * @param LPUARTx LPUART Instance + * @retval Time Value between Min_Data=0x00 and Max_Data=0x1FF + */ +__STATIC_INLINE uint16_t LL_LPUART_ReceiveData9(const USART_TypeDef *LPUARTx) +{ + return (uint16_t)(READ_BIT(LPUARTx->RDR, USART_RDR_RDR)); +} + +/** + * @brief Write in Transmitter Data Register (Transmit Data value, 8 bits) + * @rmtoll TDR TDR LL_LPUART_TransmitData8 + * @param LPUARTx LPUART Instance + * @param Value between Min_Data=0x00 and Max_Data=0xFF + * @retval None + */ +__STATIC_INLINE void LL_LPUART_TransmitData8(USART_TypeDef *LPUARTx, uint8_t Value) +{ + LPUARTx->TDR = Value; +} + +/** + * @brief Write in Transmitter Data Register (Transmit Data value, 9 bits) + * @rmtoll TDR TDR LL_LPUART_TransmitData9 + * @param LPUARTx LPUART Instance + * @param Value between Min_Data=0x00 and Max_Data=0x1FF + * @retval None + */ +__STATIC_INLINE void LL_LPUART_TransmitData9(USART_TypeDef *LPUARTx, uint16_t Value) +{ + LPUARTx->TDR = Value & 0x1FFUL; +} + +/** + * @} + */ + +/** @defgroup LPUART_LL_EF_Execution Execution + * @{ + */ + +/** + * @brief Request Break sending + * @rmtoll RQR SBKRQ LL_LPUART_RequestBreakSending + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_RequestBreakSending(USART_TypeDef *LPUARTx) +{ + SET_BIT(LPUARTx->RQR, (uint16_t)USART_RQR_SBKRQ); +} + +/** + * @brief Put LPUART in mute mode and set the RWU flag + * @rmtoll RQR MMRQ LL_LPUART_RequestEnterMuteMode + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_RequestEnterMuteMode(USART_TypeDef *LPUARTx) +{ + SET_BIT(LPUARTx->RQR, (uint16_t)USART_RQR_MMRQ); +} + +/** + * @brief Request a Receive Data and FIFO flush + * @note Allows to discard the received data without reading them, and avoid an overrun + * condition. + * @rmtoll RQR RXFRQ LL_LPUART_RequestRxDataFlush + * @param LPUARTx LPUART Instance + * @retval None + */ +__STATIC_INLINE void LL_LPUART_RequestRxDataFlush(USART_TypeDef *LPUARTx) +{ + SET_BIT(LPUARTx->RQR, (uint16_t)USART_RQR_RXFRQ); +} + +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup LPUART_LL_EF_Init Initialization and de-initialization functions + * @{ + */ +ErrorStatus LL_LPUART_DeInit(const USART_TypeDef *LPUARTx); +ErrorStatus LL_LPUART_Init(USART_TypeDef *LPUARTx, const LL_LPUART_InitTypeDef *LPUART_InitStruct); +void LL_LPUART_StructInit(LL_LPUART_InitTypeDef *LPUART_InitStruct); +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* LPUART1 */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_LL_LPUART_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_opamp.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_opamp.h new file mode 100644 index 0000000000..2212dc2741 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_opamp.h @@ -0,0 +1,845 @@ +/** + ********************************************************************************************************************** + * @file stm32h5xx_ll_opamp.h + * @author MCD Application Team + * @brief Header file of OPAMP LL module. + ********************************************************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ********************************************************************************************************************** + */ + +/* Define to prevent recursive inclusion -----------------------------------------------------------------------------*/ +#ifndef __STM32H5xx_LL_OPAMP_H +#define __STM32H5xx_LL_OPAMP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ----------------------------------------------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (OPAMP1) + +/** @defgroup OPAMP_LL OPAMP + * @{ + */ + +/* Private types -----------------------------------------------------------------------------------------------------*/ +/* Private variables -------------------------------------------------------------------------------------------------*/ + +/* Private constants -------------------------------------------------------------------------------------------------*/ +/** @defgroup OPAMP_LL_Private_Constants OPAMP Private Constants + * @{ + */ + +/* Internal mask for OPAMP power mode: */ +/* To select into literal LL_OPAMP_POWERMODE_x the relevant bits for: */ +/* - OPAMP power mode into control register */ +/* - OPAMP trimming register offset */ + +/* Internal register offset for OPAMP trimming configuration */ +#define OPAMP_POWERMODE_OTR_REGOFFSET 0x00000000U +#define OPAMP_POWERMODE_HSOTR_REGOFFSET 0x00000001U +#define OPAMP_POWERMODE_OTR_REGOFFSET_MASK (OPAMP_POWERMODE_OTR_REGOFFSET | OPAMP_POWERMODE_HSOTR_REGOFFSET) + +/* Mask for OPAMP power mode into control register */ +#define OPAMP_POWERMODE_CSR_BIT_MASK (OPAMP_CSR_OPAHSM) + +/* Internal mask for OPAMP trimming of transistors differential pair NMOS */ +/* or PMOS. */ +/* To select into literal LL_OPAMP_TRIMMING_x the relevant bits for: */ +/* - OPAMP trimming selection of transistors differential pair */ +/* - OPAMP trimming values of transistors differential pair */ +#define OPAMP_TRIMMING_SELECT_MASK 0x00030000U +#define OPAMP_TRIMMING_VALUE_MASK (OPAMP_OTR_TRIMOFFSETP | OPAMP_OTR_TRIMOFFSETN) + +/** + * @} + */ + + +/* Private macros ----------------------------------------------------------------------------------------------------*/ +/** @defgroup OPAMP_LL_Private_Macros OPAMP Private Macros + * @{ + */ + +/** + * @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_OFFSET__ Offset to be applied (unit: number of registers). + * @retval Register address + */ +#define __OPAMP_PTR_REG_OFFSET(__REG__, __REG_OFFSET__) \ + ((__IO uint32_t *)((uint32_t) ((uint32_t)(&(__REG__)) + ((__REG_OFFSET__) << 2U)))) + + + +/** + * @} + */ + + +/* Exported types ----------------------------------------------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup OPAMP_LL_ES_INIT OPAMP Exported Init structure + * @{ + */ + +/** + * @brief Structure definition of some features of OPAMP instance. + */ +typedef struct +{ + uint32_t PowerMode; /*!< Set OPAMP power mode. + This parameter can be a value of @ref OPAMP_LL_EC_POWER_MODE + This feature can be modified afterwards using unitary + function @ref LL_OPAMP_SetPowerMode(). */ + + uint32_t FunctionalMode; /*!< Set OPAMP functional mode by setting internal connections: + OPAMP operation in standalone, follower, ... + This parameter can be a value of @ref OPAMP_LL_EC_FUNCTIONAL_MODE + @note If OPAMP is configured in mode PGA, the gain can be configured + using function @ref LL_OPAMP_SetPGAGain(). + This feature can be modified afterwards using unitary + function @ref LL_OPAMP_SetFunctionalMode(). */ + + uint32_t InputNonInverting; /*!< Set OPAMP input non-inverting connection. + This parameter can be a value of @ref OPAMP_LL_EC_INPUT_NONINVERTING + This feature can be modified afterwards using unitar + function @ref LL_OPAMP_SetInputNonInverting(). */ + + uint32_t InputInverting; /*!< Set OPAMP inverting input connection. + This parameter can be a value of @ref OPAMP_LL_EC_INPUT_INVERTING + @note OPAMP inverting input is used with OPAMP in mode standalone or PGA with + external capacitors for filtering circuit. + Otherwise (OPAMP in mode follower), OPAMP inverting input is not used + (not connected to GPIO pin), this parameter is discarded. + This feature can be modified afterwards using unitary + function @ref LL_OPAMP_SetInputInverting(). */ + +} LL_OPAMP_InitTypeDef; + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/* Exported constants ------------------------------------------------------------------------------------------------*/ +/** @defgroup OPAMP_LL_Exported_Constants OPAMP Exported Constants + * @{ + */ + +/** @defgroup OPAMP_LL_EC_MODE OPAMP mode calibration or functional. + * @{ + */ +#define LL_OPAMP_MODE_FUNCTIONAL 0x00000000U /*!< OPAMP functional mode */ +#define LL_OPAMP_MODE_CALIBRATION (OPAMP_CSR_CALON) /*!< OPAMP calibration mode */ +/** + * @} + */ + +/** @defgroup OPAMP_LL_EC_FUNCTIONAL_MODE OPAMP functional mode + * @{ + */ +#define LL_OPAMP_MODE_STANDALONE 0x00000000U /*!< OPAMP functional mode, OPAMP operation + in standalone */ +#define LL_OPAMP_MODE_FOLLOWER (OPAMP_CSR_VMSEL_1 |\ + OPAMP_CSR_VMSEL_0) /*!< OPAMP functional mode, OPAMP operation in follower */ +#define LL_OPAMP_MODE_PGA (OPAMP_CSR_VMSEL_1) /*!< OPAMP functional mode, OPAMP operation in PGA */ +#define LL_OPAMP_MODE_PGA_IO0 (OPAMP_CSR_PGGAIN_2|\ + OPAMP_CSR_VMSEL_1) /*!< In PGA mode, the inverting input is connected + to VINM0 for filtering */ +#define LL_OPAMP_MODE_PGA_IO0_BIAS (OPAMP_CSR_PGGAIN_3|\ + OPAMP_CSR_VMSEL_1) /*!< In PGA mode, the inverting input is + connected to VINM0. + - Input signal on VINM0, bias on VINPx: negative gain + - Bias on VINM0, input signal on VINPx: + positive gain */ +#define LL_OPAMP_MODE_PGA_IO0_IO1_BIAS (OPAMP_CSR_PGGAIN_3|\ + OPAMP_CSR_PGGAIN_2|\ + OPAMP_CSR_VMSEL_1) /*!< In PGA mode, the inverting input is + connected to VINM0. + - Input signal on VINM0, bias on VINPx: negative gain + - Bias on VINM0, input signal on VINPx: positive gain + And VINM1 is connected too for filtering */ +/** + * @} + */ + +/** @defgroup OPAMP_LL_EC_MODE_PGA_GAIN OPAMP PGA gain (relevant when OPAMP is in functional mode PGA) + * @note Gain sign: + * - is positive if the @ref OPAMP_LL_EC_FUNCTIONAL_MODE configuration is + * @ref LL_OPAMP_MODE_PGA or LL_OPAMP_MODE_PGA_IO0 + * - may be positive or negative if the @ref OPAMP_LL_EC_FUNCTIONAL_MODE configuration is + * @ref LL_OPAMP_MODE_PGA_IO0_BIAS or LL_OPAMP_MODE_PGA_IO0_IO1_BIAS + * see @ref OPAMP_LL_EC_FUNCTIONAL_MODE for more details + * @{ + */ +#define LL_OPAMP_PGA_GAIN_2_OR_MINUS_1 0x00000000U /*!< OPAMP PGA gain 2 or -1 */ +#define LL_OPAMP_PGA_GAIN_4_OR_MINUS_3 (OPAMP_CSR_PGGAIN_0) /*!< OPAMP PGA gain 4 or -3 */ +#define LL_OPAMP_PGA_GAIN_8_OR_MINUS_7 (OPAMP_CSR_PGGAIN_1) /*!< OPAMP PGA gain 8 or -7 */ +#define LL_OPAMP_PGA_GAIN_16_OR_MINUS_15 (OPAMP_CSR_PGGAIN_1 | OPAMP_CSR_PGGAIN_0) /*!< OPAMP PGA gain 16 or -15 */ +/** + * @} + */ + +/** @defgroup OPAMP_LL_EC_INPUT_NONINVERTING OPAMP input non-inverting + * @{ + */ +#define LL_OPAMP_INPUT_NONINVERT_IO0 0x00000000U /*!< OPAMP non inverting input connected to I/O VINP0 + (PB0 for OPAMP1) + Note: On this STM32 series, all OPAMPx are not available on + all devices. Refer to device datasheet for more details */ +#define LL_OPAMP_INPUT_NONINVERT_IO1 OPAMP_CSR_VPSEL_1 /*!< OPAMP non inverting input connected to I/O VINP2 + (PA0 for OPAMP1) + Note: On this STM32 series, all OPAMPx are not available on + all devices. Refer to device datasheet for more details */ +#define LL_OPAMP_INPUT_NONINVERT_DAC OPAMP_CSR_VPSEL_0 /*!< OPAMP non inverting input connected internally to DAC channel + (DAC1_CH1 for OPAMP1) + Note: On this STM32 series, all OPAMPx are not available on + all devices. Refer to device datasheet for more details */ + +/** + * @} + */ + +/** @defgroup OPAMP_LL_EC_INPUT_INVERTING OPAMP input inverting + * @note OPAMP inverting input is used with OPAMP in mode standalone or PGA with negative gain or bias. + * Otherwise (OPAMP in mode follower), OPAMP inverting input is not used (not connected to GPIO pin). + * @{ + */ +#define LL_OPAMP_INPUT_INVERT_IO0 0x00000000U /*!< OPAMP inverting input connected to I/O VINM0 + (PC5 for OPAMP1) + Note: On this STM32 series, all OPAMPx are not + available on all devices. Refer to device datasheet + for more details */ +#define LL_OPAMP_INPUT_INVERT_IO1 OPAMP_CSR_VMSEL_0 /*!< OPAMP inverting input connected to I/0 VINM1 + (PB1 for OPAMP1) + Note: On this STM32 series, all OPAMPx are not + available on all devices. Refer to device datasheet + for more details */ +#define LL_OPAMP_INPUT_INVERT_CONNECT_NO OPAMP_CSR_VMSEL_1 /*!< OPAMP inverting input not externally connected + (intended for OPAMP in mode follower or PGA with + positive gain without bias). + Note: On this STM32 series, this literal include cases + of value 0x11 for mode follower and value 0x10 + for mode PGA. */ +/** + * @} + */ + + + +/** @defgroup OPAMP_LL_EC_POWER_MODE OPAMP PowerMode + * @{ + */ +#define LL_OPAMP_POWERMODE_NORMAL (OPAMP_POWERMODE_OTR_REGOFFSET) /*!< OPAMP output in + normal mode */ +#define LL_OPAMP_POWERMODE_HIGHSPEED (OPAMP_POWERMODE_HSOTR_REGOFFSET | OPAMP_CSR_OPAHSM) /*!< OPAMP output in + highspeed mode */ +/** + * @} + */ + +/** @defgroup OPAMP_LL_EC_TRIMMING_MODE OPAMP trimming mode + * @{ + */ +#define LL_OPAMP_TRIMMING_FACTORY 0x00000000U /*!< OPAMP trimming factors set to factory values */ +#define LL_OPAMP_TRIMMING_USER OPAMP_CSR_USERTRIM /*!< OPAMP trimming factors set to user values */ +/** + * @} + */ + +/** @defgroup OPAMP_LL_EC_TRIMMING_TRANSISTORS_DIFF_PAIR OPAMP trimming of transistors differential pair NMOS or PMOS + * @{ + */ +#define LL_OPAMP_TRIMMING_NMOS_VREF_90PC_VDDA (OPAMP_OTR_TRIMOFFSETN |\ + ((OPAMP_CSR_CALSEL_1 |\ + OPAMP_CSR_CALSEL_0) << 4)) /*!< OPAMP trimming of transistors + differential pair NMOS (internal + reference voltage set to 0.9*Vdda). + Default parameters to be used for + calibration using two trimming steps + (one with each transistors + differential pair NMOS and PMOS). */ +#define LL_OPAMP_TRIMMING_NMOS_VREF_50PC_VDDA (OPAMP_OTR_TRIMOFFSETN |\ + (OPAMP_CSR_CALSEL_1 << 4)) /*!< OPAMP trimming of transistors + differential pair NMOS (internal + reference voltage set to 0.5*Vdda). */ +#define LL_OPAMP_TRIMMING_PMOS_VREF_10PC_VDDA (OPAMP_OTR_TRIMOFFSETP |\ + (OPAMP_CSR_CALSEL_0 << 4)) /*!< OPAMP trimming of transistors + differential pair PMOS (internal + reference voltage set to 0.1*Vdda). + Default parameters to be used + for calibration using two trimming + steps (one with each transistors + differential pair NMOS and PMOS). */ +#define LL_OPAMP_TRIMMING_PMOS_VREF_3_3PC_VDDA (OPAMP_OTR_TRIMOFFSETP) /*!< OPAMP trimming of transistors + differential pair PMOS (internal + reference voltage set to 0.33*Vdda).*/ +#define LL_OPAMP_TRIMMING_NMOS (LL_OPAMP_TRIMMING_NMOS_VREF_90PC_VDDA) /*!< OPAMP trimming of transistors + differential pair NMOS (internal + reference voltage setto 0.9*Vdda). + Default parameters to be used + for calibration using two trimming + steps (one with each transistors + differential pair NMOS and PMOS). */ +#define LL_OPAMP_TRIMMING_PMOS (LL_OPAMP_TRIMMING_PMOS_VREF_10PC_VDDA) /*!< OPAMP trimming of transistors + differential pair PMOS (internal + reference voltage setto 0.1*Vdda). + Default parameters to be used for + calibration using two trimming + steps one with each transistors + differential pair NMOS and PMOS). */ +/** + * @} + */ + +/** @defgroup OPAMP_LL_EC_HW_DELAYS Definitions of OPAMP hardware constraints delays + * @note Only OPAMP Peripheral HW delays are defined in OPAMP LL driver driver, + * not timeout values. + * For details on delays values, refer to descriptions in source code + * above each literal definition. + * @{ + */ + +/* Delay for OPAMP startup time (transition from state disable to enable). */ +/* Note: OPAMP startup time depends on board application environment: */ +/* impedance connected to OPAMP output. */ +/* The delay below is specified under conditions: */ +/* - OPAMP in functional mode follower */ +/* - load impedance of 4kOhm (min), 50pF (max) */ +/* Literal set to maximum value (refer to device datasheet, */ +/* parameter "tWAKEUP"). */ +/* Unit: us */ +#define LL_OPAMP_DELAY_STARTUP_US (3U) /*!< Delay for OPAMP startup time */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ----------------------------------------------------------------------------------------------------*/ +/** @defgroup OPAMP_LL_Exported_Macros OPAMP Exported Macros + * @{ + */ +/** @defgroup OPAMP_LL_EM_WRITE_READ Common write and read registers macro + * @{ + */ +/** + * @brief Write a value in OPAMP LL_OPAMP_GetPowerModeregister + * @param __INSTANCE__ OPAMP Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_OPAMP_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG((__INSTANCE__)->__REG__, (__VALUE__)) + +/** + * @brief Read a value in OPAMP register + * @param __INSTANCE__ OPAMP Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_OPAMP_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions ------------------------------------------------------------------------------------------------*/ +/** @defgroup OPAMP_LL_Exported_Functions OPAMP Exported Functions + * @{ + */ + +/** @defgroup OPAMP_LL_EF_CONFIGURATION_OPAMP_INSTANCE Configuration of OPAMP hierarchical scope: OPAMP instance + * @{ + */ + +/** + * @brief Set OPAMP mode calibration or functional. + * @note OPAMP mode corresponds to functional or calibration mode: + * - functional mode: OPAMP operation in standalone, follower, ... + * Set functional mode using function + * @ref LL_OPAMP_SetFunctionalMode(). + * - calibration mode: offset calibration of the selected + * transistors differential pair NMOS or PMOS. + * @rmtoll CSR CALON LL_OPAMP_SetMode + * @param OPAMPx OPAMP instance + * @param Mode This parameter can be one of the following values: + * @arg @ref LL_OPAMP_MODE_FUNCTIONAL + * @arg @ref LL_OPAMP_MODE_CALIBRATION + * @retval None + */ +__STATIC_INLINE void LL_OPAMP_SetMode(OPAMP_TypeDef *OPAMPx, uint32_t Mode) +{ + MODIFY_REG(OPAMPx->CSR, OPAMP_CSR_CALON, Mode); +} + +/** + * @brief Get OPAMP mode calibration or functional. + * @note OPAMP mode corresponds to functional or calibration mode: + * - functional mode: OPAMP operation in standalone, follower, ... + * Set functional mode using function + * @ref LL_OPAMP_SetFunctionalMode(). + * - calibration mode: offset calibration of the selected + * transistors differential pair NMOS or PMOS. + * @rmtoll CSR CALON LL_OPAMP_GetMode + * @param OPAMPx OPAMP instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_OPAMP_MODE_FUNCTIONAL + * @arg @ref LL_OPAMP_MODE_CALIBRATION + */ +__STATIC_INLINE uint32_t LL_OPAMP_GetMode(const OPAMP_TypeDef *OPAMPx) +{ + return (uint32_t)(READ_BIT(OPAMPx->CSR, OPAMP_CSR_CALON)); +} + +/** + * @brief Set OPAMP functional mode by setting internal connections. + * OPAMP operation in standalone, follower, ... + * @note This function reset bit of calibration mode to ensure + * to be in functional mode, in order to have OPAMP parameters + * (inputs selection, ...) set with the corresponding OPAMP mode + * to be effective. + * @rmtoll CSR VMSEL LL_OPAMP_SetFunctionalMode + * @param OPAMPx OPAMP instance + * @param FunctionalMode This parameter can be one of the following values: + * @arg @ref LL_OPAMP_MODE_STANDALONE + * @arg @ref LL_OPAMP_MODE_FOLLOWER + * @arg @ref LL_OPAMP_MODE_PGA + * @arg @ref LL_OPAMP_MODE_PGA_IO0 + * @arg @ref LL_OPAMP_MODE_PGA_IO0_BIAS + * @arg @ref LL_OPAMP_MODE_PGA_IO0_IO1_BIAS + * @retval None + */ +__STATIC_INLINE void LL_OPAMP_SetFunctionalMode(OPAMP_TypeDef *OPAMPx, uint32_t FunctionalMode) +{ + /* Note: Bit OPAMP_CSR_CALON reset to ensure to be in functional mode */ + MODIFY_REG(OPAMPx->CSR, OPAMP_CSR_PGGAIN_3 | OPAMP_CSR_PGGAIN_2 | OPAMP_CSR_VMSEL | OPAMP_CSR_CALON, FunctionalMode); +} + +/** + * @brief Get OPAMP functional mode from setting of internal connections. + * OPAMP operation in standalone, follower, ... + * @rmtoll CSR VMSEL LL_OPAMP_GetFunctionalMode + * @param OPAMPx OPAMP instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_OPAMP_MODE_STANDALONE + * @arg @ref LL_OPAMP_MODE_FOLLOWER + * @arg @ref LL_OPAMP_MODE_PGA + * @arg @ref LL_OPAMP_MODE_PGA_IO0 + * @arg @ref LL_OPAMP_MODE_PGA_IO0_BIAS + * @arg @ref LL_OPAMP_MODE_PGA_IO0_IO1_BIAS + */ +__STATIC_INLINE uint32_t LL_OPAMP_GetFunctionalMode(const OPAMP_TypeDef *OPAMPx) +{ + return (uint32_t)(READ_BIT(OPAMPx->CSR, OPAMP_CSR_PGGAIN_3 | OPAMP_CSR_PGGAIN_2 | OPAMP_CSR_VMSEL)); +} + +/** + * @brief Set OPAMP PGA gain. + * @note Preliminarily, OPAMP must be set in mode PGA + * using function @ref LL_OPAMP_SetFunctionalMode(). + * @rmtoll CSR PGGAIN LL_OPAMP_SetPGAGain + * @param OPAMPx OPAMP instance + * @param PGAGain This parameter can be one of the following values: + * @arg @ref LL_OPAMP_PGA_GAIN_2_OR_MINUS_1 + * @arg @ref LL_OPAMP_PGA_GAIN_4_OR_MINUS_3 + * @arg @ref LL_OPAMP_PGA_GAIN_8_OR_MINUS_7 + * @arg @ref LL_OPAMP_PGA_GAIN_16_OR_MINUS_15 + * @retval None + */ +__STATIC_INLINE void LL_OPAMP_SetPGAGain(OPAMP_TypeDef *OPAMPx, uint32_t PGAGain) +{ + MODIFY_REG(OPAMPx->CSR, OPAMP_CSR_PGGAIN_1 | OPAMP_CSR_PGGAIN_0, PGAGain); +} + +/** + * @brief Get OPAMP PGA gain. + * @note Preliminarily, OPAMP must be set in mode PGA + * using function @ref LL_OPAMP_SetFunctionalMode(). + * @rmtoll CSR PGGAIN LL_OPAMP_GetPGAGain + * @param OPAMPx OPAMP instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_OPAMP_PGA_GAIN_2_OR_MINUS_1 + * @arg @ref LL_OPAMP_PGA_GAIN_4_OR_MINUS_3 + * @arg @ref LL_OPAMP_PGA_GAIN_8_OR_MINUS_7 + * @arg @ref LL_OPAMP_PGA_GAIN_16_OR_MINUS_15 + */ +__STATIC_INLINE uint32_t LL_OPAMP_GetPGAGain(const OPAMP_TypeDef *OPAMPx) +{ + return (uint32_t)(READ_BIT(OPAMPx->CSR, OPAMP_CSR_PGGAIN_1 | OPAMP_CSR_PGGAIN_0)); +} + +/** + * @brief Set OPAMP power mode normal or highspeed. + * @note OPAMP highspeed mode allows output stage to have a better slew rate. + * @rmtoll CSR OPAHSM LL_OPAMP_SetPowerMode + * @param OPAMPx OPAMP instance + * @param PowerMode This parameter can be one of the following values: + * @arg @ref LL_OPAMP_POWERMODE_NORMAL + * @arg @ref LL_OPAMP_POWERMODE_HIGHSPEED + * @retval None + */ +__STATIC_INLINE void LL_OPAMP_SetPowerMode(OPAMP_TypeDef *OPAMPx, uint32_t PowerMode) +{ + MODIFY_REG(OPAMPx->CSR, OPAMP_CSR_OPAHSM, (PowerMode & OPAMP_POWERMODE_CSR_BIT_MASK)); +} + +/** + * @brief Get OPAMP power mode normal or highspeed. + * @note OPAMP highspeed mode allows output stage to have a better slew rate. + * @rmtoll CSR OPAHSM LL_OPAMP_GetPowerMode + * @param OPAMPx OPAMP instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_OPAMP_POWERMODE_NORMAL + * @arg @ref LL_OPAMP_POWERMODE_HIGHSPEED + */ +__STATIC_INLINE uint32_t LL_OPAMP_GetPowerMode(const OPAMP_TypeDef *OPAMPx) +{ + uint32_t power_mode = (READ_BIT(OPAMPx->CSR, OPAMP_CSR_OPAHSM)); + + return (uint32_t)(power_mode | (power_mode >> (OPAMP_CSR_OPAHSM_Pos))); +} +/** + * @} + */ + +/** @defgroup OPAMP_LL_EF_CONFIGURATION_INPUTS Configuration of OPAMP inputs + * @{ + */ + +/** + * @brief Set OPAMP non-inverting input connection. + * @rmtoll CSR VPSEL LL_OPAMP_SetInputNonInverting + * @param OPAMPx OPAMP instance + * @param InputNonInverting This parameter can be one of the following values: + * @arg @ref LL_OPAMP_INPUT_NONINVERT_IO0 + * @arg @ref LL_OPAMP_INPUT_NONINVERT_IO1 + * @arg @ref LL_OPAMP_INPUT_NONINVERT_DAC + * @retval None + */ +__STATIC_INLINE void LL_OPAMP_SetInputNonInverting(OPAMP_TypeDef *OPAMPx, uint32_t InputNonInverting) +{ + MODIFY_REG(OPAMPx->CSR, OPAMP_CSR_VPSEL, InputNonInverting); +} + +/** + * @brief Get OPAMP non-inverting input connection. + * @rmtoll CSR VPSEL LL_OPAMP_GetInputNonInverting + * @param OPAMPx OPAMP instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_OPAMP_INPUT_NONINVERT_IO0 + * @arg @ref LL_OPAMP_INPUT_NONINVERT_IO1 + * @arg @ref LL_OPAMP_INPUT_NONINVERT_DAC + */ +__STATIC_INLINE uint32_t LL_OPAMP_GetInputNonInverting(const OPAMP_TypeDef *OPAMPx) +{ + return (uint32_t)(READ_BIT(OPAMPx->CSR, OPAMP_CSR_VPSEL)); +} + +/** + * @brief Set OPAMP inverting input connection. + * @note OPAMP inverting input is used with OPAMP in mode standalone + * or PGA with external capacitors for filtering circuit. + * Otherwise (OPAMP in mode follower), OPAMP inverting input + * is not used (not connected to GPIO pin). + * @rmtoll CSR VMSEL LL_OPAMP_SetInputInverting + * @param OPAMPx OPAMP instance + * @param InputInverting This parameter can be one of the following values: + * @arg @ref LL_OPAMP_INPUT_INVERT_IO0 + * @arg @ref LL_OPAMP_INPUT_INVERT_IO1 + * @arg @ref LL_OPAMP_INPUT_INVERT_CONNECT_NO + * @retval None + */ +__STATIC_INLINE void LL_OPAMP_SetInputInverting(OPAMP_TypeDef *OPAMPx, uint32_t InputInverting) +{ + /* Manage cases of OPAMP inverting input not connected (0x10 and 0x11) */ + /* to not modify OPAMP mode follower or PGA. */ + /* Bit OPAMP_CSR_VMSEL_1 is set by OPAMP mode (follower, PGA). */ + MODIFY_REG(OPAMPx->CSR, (~(InputInverting >> 1)) & OPAMP_CSR_VMSEL_0, InputInverting); +} + +/** + * @brief Get OPAMP inverting input connection. + * @rmtoll CSR VMSEL LL_OPAMP_GetInputInverting + * @param OPAMPx OPAMP instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_OPAMP_INPUT_INVERT_IO0 + * @arg @ref LL_OPAMP_INPUT_INVERT_IO1 + * @arg @ref LL_OPAMP_INPUT_INVERT_CONNECT_NO + */ +__STATIC_INLINE uint32_t LL_OPAMP_GetInputInverting(const OPAMP_TypeDef *OPAMPx) +{ + uint32_t input_inverting = READ_BIT(OPAMPx->CSR, OPAMP_CSR_VMSEL); + + /* Manage cases 0x10 and 0x11 to return the same value: OPAMP inverting */ + /* input not connected. */ + return (input_inverting & ~((input_inverting >> 1) & OPAMP_CSR_VMSEL_0)); +} + +/** + * @} + */ + +/** @defgroup OPAMP_LL_EF_OPAMP_TRIMMING Configuration and operation of OPAMP trimming + * @{ + */ + +/** + * @brief Set OPAMP trimming mode. + * @rmtoll CSR USERTRIM LL_OPAMP_SetTrimmingMode + * @param OPAMPx OPAMP instance + * @param TrimmingMode This parameter can be one of the following values: + * @arg @ref LL_OPAMP_TRIMMING_FACTORY + * @arg @ref LL_OPAMP_TRIMMING_USER + * @retval None + */ +__STATIC_INLINE void LL_OPAMP_SetTrimmingMode(OPAMP_TypeDef *OPAMPx, uint32_t TrimmingMode) +{ + MODIFY_REG(OPAMPx->CSR, OPAMP_CSR_USERTRIM, TrimmingMode); +} + +/** + * @brief Get OPAMP trimming mode. + * @rmtoll CSR USERTRIM LL_OPAMP_GetTrimmingMode + * @param OPAMPx OPAMP instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_OPAMP_TRIMMING_FACTORY + * @arg @ref LL_OPAMP_TRIMMING_USER + */ +__STATIC_INLINE uint32_t LL_OPAMP_GetTrimmingMode(const OPAMP_TypeDef *OPAMPx) +{ + return (uint32_t)(READ_BIT(OPAMPx->CSR, OPAMP_CSR_USERTRIM)); +} + +/** + * @brief Set OPAMP offset to calibrate the selected transistors + * differential pair NMOS or PMOS. + * @note Preliminarily, OPAMP must be set in mode calibration + * using function @ref LL_OPAMP_SetMode(). + * @rmtoll CSR CALSEL LL_OPAMP_SetCalibrationSelection + * @param OPAMPx OPAMP instance + * @param TransistorsDiffPair This parameter can be one of the following values: + * @arg @ref LL_OPAMP_TRIMMING_NMOS (1) + * @arg @ref LL_OPAMP_TRIMMING_PMOS (1) + * @arg @ref LL_OPAMP_TRIMMING_NMOS_VREF_50PC_VDDA + * @arg @ref LL_OPAMP_TRIMMING_PMOS_VREF_3_3PC_VDDA + * + * (1) Default parameters to be used for calibration + * using two trimming steps (one with each transistors differential + * pair NMOS and PMOS) + * @retval None + */ +__STATIC_INLINE void LL_OPAMP_SetCalibrationSelection(OPAMP_TypeDef *OPAMPx, uint32_t TransistorsDiffPair) +{ + /* Parameter used with mask "OPAMP_TRIMMING_SELECT_MASK" because */ + /* containing other bits reserved for other purpose. */ + MODIFY_REG(OPAMPx->CSR, OPAMP_CSR_CALSEL, ((TransistorsDiffPair & OPAMP_TRIMMING_SELECT_MASK) >> 4)); +} + +/** + * @brief Get OPAMP offset to calibrate the selected transistors + * differential pair NMOS or PMOS. + * @note Preliminarily, OPAMP must be set in mode calibration + * using function @ref LL_OPAMP_SetMode(). + * @rmtoll CSR CALSEL LL_OPAMP_GetCalibrationSelection + * @param OPAMPx OPAMP instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_OPAMP_TRIMMING_NMOS (1) + * @arg @ref LL_OPAMP_TRIMMING_PMOS (1) + * @arg @ref LL_OPAMP_TRIMMING_NMOS_VREF_50PC_VDDA + * @arg @ref LL_OPAMP_TRIMMING_PMOS_VREF_3_3PC_VDDA + * + * (1) Default parameters to be used for calibration + * using two trimming steps (one with each transistors differential + * pair NMOS and PMOS) + */ +__STATIC_INLINE uint32_t LL_OPAMP_GetCalibrationSelection(const OPAMP_TypeDef *OPAMPx) +{ + uint32_t CalibrationSelection = (uint32_t)(READ_BIT(OPAMPx->CSR, OPAMP_CSR_CALSEL)); + + return (uint32_t)((CalibrationSelection << 4) | + (((CalibrationSelection & OPAMP_CSR_CALSEL_1) == 0UL) ? OPAMP_OTR_TRIMOFFSETP : + OPAMP_OTR_TRIMOFFSETN)); +} + +/** + * @brief Get OPAMP calibration result of toggling output. + * @note This functions returns: + * 0 if OPAMP calibration output is reset + * 1 if OPAMP calibration output is set + * @rmtoll CSR OUTCAL LL_OPAMP_IsCalibrationOutputSet + * @param OPAMPx OPAMP instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_OPAMP_IsCalibrationOutputSet(const OPAMP_TypeDef *OPAMPx) +{ + return ((READ_BIT(OPAMPx->CSR, OPAMP_CSR_CALOUT) == OPAMP_CSR_CALOUT) ? 1UL : 0UL); +} + +/** + * @brief Set OPAMP trimming factor for the selected transistors + * differential pair NMOS or PMOS, corresponding to the selected + * power mode. + * @rmtoll OTR TRIMOFFSETN LL_OPAMP_SetTrimmingValue\n + * OTR TRIMOFFSETP LL_OPAMP_SetTrimmingValue\n + * HSOTR TRIMHSOFFSETN LL_OPAMP_SetTrimmingValue\n + * HSOTR TRIMHSOFFSETP LL_OPAMP_SetTrimmingValue + * @param OPAMPx OPAMP instance + * @param PowerMode This parameter can be one of the following values: + * @arg @ref LL_OPAMP_POWERMODE_NORMAL + * @arg @ref LL_OPAMP_POWERMODE_HIGHSPEED + * @param TransistorsDiffPair This parameter can be one of the following values: + * @arg @ref LL_OPAMP_TRIMMING_NMOS + * @arg @ref LL_OPAMP_TRIMMING_PMOS + * @param TrimmingValue 0x00...0x1F + * @retval None + */ +__STATIC_INLINE void LL_OPAMP_SetTrimmingValue(OPAMP_TypeDef *OPAMPx, uint32_t PowerMode, uint32_t TransistorsDiffPair, + uint32_t TrimmingValue) +{ + __IO uint32_t *preg = __OPAMP_PTR_REG_OFFSET(OPAMPx->OTR, (PowerMode & OPAMP_POWERMODE_OTR_REGOFFSET_MASK)); + + /* Set bits with position in register depending on parameter */ + /* "TransistorsDiffPair". */ + /* Parameter used with mask "OPAMP_TRIMMING_VALUE_MASK" because */ + /* containing other bits reserved for other purpose. */ + MODIFY_REG(*preg, + (TransistorsDiffPair & OPAMP_TRIMMING_VALUE_MASK) << 1U, + TrimmingValue << + ((TransistorsDiffPair == LL_OPAMP_TRIMMING_NMOS) ? OPAMP_OTR_TRIMOFFSETN_Pos : OPAMP_OTR_TRIMOFFSETP_Pos)); +} + +/** + * @brief Get OPAMP trimming factor for the selected transistors + * differential pair NMOS or PMOS, corresponding to the selected + * power mode. + * @rmtoll OTR TRIMOFFSETN LL_OPAMP_GetTrimmingValue\n + * OTR TRIMOFFSETP LL_OPAMP_GetTrimmingValue\n + * HSOTR TRIMHSOFFSETN LL_OPAMP_GetTrimmingValue\n + * HSOTR TRIMHSOFFSETP LL_OPAMP_GetTrimmingValue + * @param OPAMPx OPAMP instance + * @param PowerMode This parameter can be one of the following values: + * @arg @ref LL_OPAMP_POWERMODE_NORMAL + * @arg @ref LL_OPAMP_POWERMODE_HIGHSPEED + * @param TransistorsDiffPair This parameter can be one of the following values: + * @arg @ref LL_OPAMP_TRIMMING_NMOS + * @arg @ref LL_OPAMP_TRIMMING_PMOS + * @retval 0x0...0x1F + */ +__STATIC_INLINE uint32_t LL_OPAMP_GetTrimmingValue(const OPAMP_TypeDef *OPAMPx, uint32_t PowerMode, + uint32_t TransistorsDiffPair) +{ + const __IO uint32_t *preg = __OPAMP_PTR_REG_OFFSET(OPAMPx->OTR, (PowerMode & OPAMP_POWERMODE_OTR_REGOFFSET_MASK)); + + /* Retrieve bits with position in register depending on parameter */ + /* "TransistorsDiffPair". */ + /* Parameter used with mask "OPAMP_TRIMMING_VALUE_MASK" because */ + /* containing other bits reserved for other purpose. */ + return (uint32_t)(READ_BIT(*preg, (TransistorsDiffPair & OPAMP_TRIMMING_VALUE_MASK)) + >> ((TransistorsDiffPair == LL_OPAMP_TRIMMING_NMOS) ? + OPAMP_OTR_TRIMOFFSETN_Pos : OPAMP_OTR_TRIMOFFSETP_Pos)); +} + +/** + * @} + */ + +/** @defgroup OPAMP_LL_EF_OPERATION Operation on OPAMP instance + * @{ + */ +/** + * @brief Enable OPAMP instance. + * @note After enable from off state, OPAMP requires a delay + * to fulfill wake up time specification. + * Refer to device datasheet, parameter "tWAKEUP". + * @rmtoll CSR OPAMPXEN LL_OPAMP_Enable + * @param OPAMPx OPAMP instance + * @retval None + */ +__STATIC_INLINE void LL_OPAMP_Enable(OPAMP_TypeDef *OPAMPx) +{ + SET_BIT(OPAMPx->CSR, OPAMP_CSR_OPAMPxEN); +} + +/** + * @brief Disable OPAMP instance. + * @rmtoll CSR OPAMPXEN LL_OPAMP_Disable + * @param OPAMPx OPAMP instance + * @retval None + */ +__STATIC_INLINE void LL_OPAMP_Disable(OPAMP_TypeDef *OPAMPx) +{ + CLEAR_BIT(OPAMPx->CSR, OPAMP_CSR_OPAMPxEN); +} + +/** + * @brief Get OPAMP instance enable state + * (0: OPAMP is disabled, 1: OPAMP is enabled) + * @rmtoll CSR OPAMPXEN LL_OPAMP_IsEnabled + * @param OPAMPx OPAMP instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_OPAMP_IsEnabled(const OPAMP_TypeDef *OPAMPx) +{ + return ((READ_BIT(OPAMPx->CSR, OPAMP_CSR_OPAMPxEN) == (OPAMP_CSR_OPAMPxEN)) ? 1UL : 0UL); +} +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup OPAMP_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +ErrorStatus LL_OPAMP_DeInit(OPAMP_TypeDef *OPAMPx); +ErrorStatus LL_OPAMP_Init(OPAMP_TypeDef *OPAMPx, const LL_OPAMP_InitTypeDef *OPAMP_InitStruct); +void LL_OPAMP_StructInit(LL_OPAMP_InitTypeDef *OPAMP_InitStruct); + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* OPAMP1 */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32H5xx_LL_OPAMP_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_pka.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_pka.h new file mode 100644 index 0000000000..2dbd07ea2e --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_pka.h @@ -0,0 +1,601 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_pka.h + * @author MCD Application Team + * @brief Header file of PKA LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_LL_PKA_H +#define STM32H5xx_LL_PKA_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined(PKA) + +/** @defgroup PKA_LL PKA + * @{ + */ + +/* Private variables ---------------------------------------------------------*/ + +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup PKA_LL_ES_INIT PKA Exported Init structure + * @{ + */ + +/** + * @brief PKA Init structures definition + */ +typedef struct +{ + uint32_t Mode; /*!< Specifies the PKA operation mode. + This parameter can be a value of @ref PKA_LL_EC_MODE. + + This feature can be modified afterwards using unitary function @ref LL_PKA_SetMode(). */ +} LL_PKA_InitTypeDef; + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup PKA_LL_Exported_Constants PKA Exported Constants + * @{ + */ + +/** @defgroup PKA_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_PKA_ReadReg function + * @{ + */ +#define LL_PKA_SR_ADDRERRF PKA_SR_ADDRERRF +#define LL_PKA_SR_RAMERRF PKA_SR_RAMERRF +#define LL_PKA_SR_PROCENDF PKA_SR_PROCENDF +#define LL_PKA_SR_BUSY PKA_SR_BUSY +#define LL_PKA_SR_INITOK PKA_SR_INITOK +#define LL_PKA_SR_OPERRF PKA_SR_OPERRF +/** + * @} + */ + +/** @defgroup PKA_LL_EC_IT IT Defines + * @brief IT defines which can be used with LL_PKA_ReadReg and LL_PKA_WriteReg functions + * @{ + */ +#define LL_PKA_CR_ADDRERRIE PKA_CR_ADDRERRIE +#define LL_PKA_CR_RAMERRIE PKA_CR_RAMERRIE +#define LL_PKA_CR_PROCENDIE PKA_CR_PROCENDIE +#define LL_PKA_CLRFR_PROCENDFC PKA_CLRFR_PROCENDFC +#define LL_PKA_CLRFR_RAMERRFC PKA_CLRFR_RAMERRFC +#define LL_PKA_CLRFR_ADDRERRFC PKA_CLRFR_ADDRERRFC +#define LL_PKA_CR_OPERRIE PKA_CR_OPERRIE +#define LL_PKA_CLRFR_OPERRFC PKA_CLRFR_OPERRFC +/** + * @} + */ + +/** @defgroup PKA_LL_EC_MODE Operation Mode + * @brief List of operation mode. + * @{ + */ +#define LL_PKA_MODE_MODULAR_EXP ((uint32_t)0x00000000U) /*!< modular exponentiation */ +#define LL_PKA_MODE_MONTGOMERY_PARAM ((uint32_t)0x00000001U) /*!< Compute Montgomery parameter only */ +#define LL_PKA_MODE_MODULAR_EXP_FAST ((uint32_t)0x00000002U) /*!< modular exponentiation fast mode */ +#define LL_PKA_MODE_MODULAR_EXP_PROTECT ((uint32_t)0x00000003U) /*!< modular exponentiation protect mode */ +#define LL_PKA_MODE_ECC_MUL ((uint32_t)0x00000020U) /*!< compute ECC kP operation */ +#define LL_PKA_MODE_ECC_COMPLETE_ADD ((uint32_t)0x00000023U) /*!< ECC complete addition */ +#define LL_PKA_MODE_ECDSA_SIGNATURE ((uint32_t)0x00000024U) /*!< ECDSA signature */ +#define LL_PKA_MODE_ECDSA_VERIFICATION ((uint32_t)0x00000026U) /*!< ECDSA verification */ +#define LL_PKA_MODE_POINT_CHECK ((uint32_t)0x00000028U) /*!< Point check */ +#define LL_PKA_MODE_RSA_CRT_EXP ((uint32_t)0x00000007U) /*!< RSA CRT exponentiation */ +#define LL_PKA_MODE_MODULAR_INV ((uint32_t)0x00000008U) /*!< Modular inversion */ +#define LL_PKA_MODE_ARITHMETIC_ADD ((uint32_t)0x00000009U) /*!< Arithmetic addition */ +#define LL_PKA_MODE_ARITHMETIC_SUB ((uint32_t)0x0000000AU) /*!< Arithmetic subtraction */ +#define LL_PKA_MODE_ARITHMETIC_MUL ((uint32_t)0x0000000BU) /*!< Arithmetic multiplication */ +#define LL_PKA_MODE_COMPARISON ((uint32_t)0x0000000CU) /*!< Comparison */ +#define LL_PKA_MODE_MODULAR_REDUC ((uint32_t)0x0000000DU) /*!< Modular reduction */ +#define LL_PKA_MODE_MODULAR_ADD ((uint32_t)0x0000000EU) /*!< Modular addition */ +#define LL_PKA_MODE_MODULAR_SUB ((uint32_t)0x0000000FU) /*!< Modular subtraction */ +#define LL_PKA_MODE_MONTGOMERY_MUL ((uint32_t)0x00000010U) /*!< Montgomery multiplication */ +#define LL_PKA_MODE_DOUBLE_BASE_LADDER ((uint32_t)0x00000027U) /*!< Double base ladder */ +#define LL_PKA_MODE_ECC_PROJECTIVE_AFF ((uint32_t)0x0000002FU) /*!< ECC projective to affine */ + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup PKA_LL_Exported_Macros PKA Exported Macros + * @{ + */ + +/** @defgroup PKA_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in PKA register + * @param __INSTANCE__ PKA Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_PKA_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in PKA register + * @param __INSTANCE__ PKA Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_PKA_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup PKA_LL_Exported_Functions PKA Exported Functions + * @{ + */ + +/** @defgroup PKA_LL_EF_Configuration Configuration + * @{ + */ + +/** + * @brief Configure PKA peripheral. + * @brief Set PKA operating mode. + * @rmtoll CR MODE LL_PKA_Config + * @param PKAx PKA Instance. + * @param Mode This parameter can be one of the following values: + * @arg @ref LL_PKA_MODE_MONTGOMERY_PARAM + * @arg @ref LL_PKA_MODE_MODULAR_EXP + * @arg @ref LL_PKA_MODE_ECDSA_SIGNATURE + * @arg @ref LL_PKA_MODE_ECDSA_VERIFICATION + * @arg @ref LL_PKA_MODE_POINT_CHECK + * @arg @ref LL_PKA_MODE_RSA_CRT_EXP + * @arg @ref LL_PKA_MODE_MODULAR_INV + * @arg @ref LL_PKA_MODE_ARITHMETIC_ADD + * @arg @ref LL_PKA_MODE_ARITHMETIC_SUB + * @arg @ref LL_PKA_MODE_ARITHMETIC_MUL + * @arg @ref LL_PKA_MODE_COMPARISON + * @arg @ref LL_PKA_MODE_MODULAR_REDUC + * @arg @ref LL_PKA_MODE_MODULAR_ADD + * @arg @ref LL_PKA_MODE_MODULAR_SUB + * @arg @ref LL_PKA_MODE_MONTGOMERY_MUL + * @arg @ref LL_PKA_MODE_MODULAR_EXP_PROTECT + * @arg @ref LL_PKA_MODE_DOUBLE_BASE_LADDER + * @arg @ref LL_PKA_MODE_ECC_PROJECTIVE_AFF + * @arg @ref LL_PKA_MODE_ECC_COMPLETE_ADD + * @arg @ref LL_PKA_MODE_ECC_MUL + * @arg @ref LL_PKA_MODE_MODULAR_EXP_FAST + */ +__STATIC_INLINE void LL_PKA_Config(PKA_TypeDef *PKAx, uint32_t Mode) +{ + MODIFY_REG(PKAx->CR, (PKA_CR_MODE), (Mode << PKA_CR_MODE_Pos)); +} + +/** + * @brief Enable PKA peripheral. + * @rmtoll CR EN LL_PKA_Enable + * @param PKAx PKA Instance. + * @retval None + */ +__STATIC_INLINE void LL_PKA_Enable(PKA_TypeDef *PKAx) +{ + SET_BIT(PKAx->CR, PKA_CR_EN); +} + +/** + * @brief Disable PKA peripheral. + * @rmtoll CR EN LL_PKA_Disable + * @param PKAx PKA Instance. + * @retval None + */ +__STATIC_INLINE void LL_PKA_Disable(PKA_TypeDef *PKAx) +{ + CLEAR_BIT(PKAx->CR, PKA_CR_EN); +} + +/** + * @brief Check if the PKA peripheral is enabled or disabled. + * @rmtoll CR EN LL_PKA_IsEnabled + * @param PKAx PKA Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PKA_IsEnabled(const PKA_TypeDef *PKAx) +{ + return ((READ_BIT(PKAx->CR, PKA_CR_EN) == (PKA_CR_EN)) ? 1UL : 0UL); +} + +/** + * @brief Set PKA operating mode. + * @rmtoll CR MODE LL_PKA_SetMode + * @param PKAx PKA Instance. + * @param Mode This parameter can be one of the following values: + * @arg @ref LL_PKA_MODE_MONTGOMERY_PARAM + * @arg @ref LL_PKA_MODE_MODULAR_EXP + * @arg @ref LL_PKA_MODE_ECDSA_SIGNATURE + * @arg @ref LL_PKA_MODE_ECDSA_VERIFICATION + * @arg @ref LL_PKA_MODE_POINT_CHECK + * @arg @ref LL_PKA_MODE_RSA_CRT_EXP + * @arg @ref LL_PKA_MODE_MODULAR_INV + * @arg @ref LL_PKA_MODE_ARITHMETIC_ADD + * @arg @ref LL_PKA_MODE_ARITHMETIC_SUB + * @arg @ref LL_PKA_MODE_ARITHMETIC_MUL + * @arg @ref LL_PKA_MODE_COMPARISON + * @arg @ref LL_PKA_MODE_MODULAR_REDUC + * @arg @ref LL_PKA_MODE_MODULAR_ADD + * @arg @ref LL_PKA_MODE_MODULAR_SUB + * @arg @ref LL_PKA_MODE_MONTGOMERY_MUL + * @arg @ref LL_PKA_MODE_MODULAR_EXP_PROTECT + * @arg @ref LL_PKA_MODE_DOUBLE_BASE_LADDER + * @arg @ref LL_PKA_MODE_ECC_PROJECTIVE_AFF + * @arg @ref LL_PKA_MODE_ECC_COMPLETE_ADD + * @arg @ref LL_PKA_MODE_ECC_MUL + * @arg @ref LL_PKA_MODE_MODULAR_EXP_FAST + * @retval None + */ +__STATIC_INLINE void LL_PKA_SetMode(PKA_TypeDef *PKAx, uint32_t Mode) +{ + MODIFY_REG(PKAx->CR, PKA_CR_MODE, Mode << PKA_CR_MODE_Pos); +} + +/** + * @brief Get PKA operating mode. + * @rmtoll CR MODE LL_PKA_GetMode + * @param PKAx PKA Instance. + * @retval Returned value can be one of the following values: + * @arg @ref LL_PKA_MODE_MONTGOMERY_PARAM + * @arg @ref LL_PKA_MODE_MODULAR_EXP + * @arg @ref LL_PKA_MODE_ECDSA_SIGNATURE + * @arg @ref LL_PKA_MODE_ECDSA_VERIFICATION + * @arg @ref LL_PKA_MODE_POINT_CHECK + * @arg @ref LL_PKA_MODE_RSA_CRT_EXP + * @arg @ref LL_PKA_MODE_MODULAR_INV + * @arg @ref LL_PKA_MODE_ARITHMETIC_ADD + * @arg @ref LL_PKA_MODE_ARITHMETIC_SUB + * @arg @ref LL_PKA_MODE_ARITHMETIC_MUL + * @arg @ref LL_PKA_MODE_COMPARISON + * @arg @ref LL_PKA_MODE_MODULAR_REDUC + * @arg @ref LL_PKA_MODE_MODULAR_ADD + * @arg @ref LL_PKA_MODE_MODULAR_SUB + * @arg @ref LL_PKA_MODE_MONTGOMERY_MUL + * @arg @ref LL_PKA_MODE_MODULAR_EXP_PROTECT + * @arg @ref LL_PKA_MODE_DOUBLE_BASE_LADDER + * @arg @ref LL_PKA_MODE_ECC_PROJECTIVE_AFF + * @arg @ref LL_PKA_MODE_ECC_COMPLETE_ADD + * @arg @ref LL_PKA_MODE_ECC_MUL + * @arg @ref LL_PKA_MODE_MODULAR_EXP_FAST + */ +__STATIC_INLINE uint32_t LL_PKA_GetMode(const PKA_TypeDef *PKAx) +{ + return (uint32_t)(READ_BIT(PKAx->CR, PKA_CR_MODE) >> PKA_CR_MODE_Pos); +} + +/** + * @brief Start the operation selected using LL_PKA_SetMode. + * @rmtoll CR START LL_PKA_Start + * @param PKAx PKA Instance. + * @retval None + */ +__STATIC_INLINE void LL_PKA_Start(PKA_TypeDef *PKAx) +{ + SET_BIT(PKAx->CR, PKA_CR_START); +} + +/** + * @} + */ + +/** @defgroup PKA_LL_EF_IT_Management IT_Management + * @{ + */ + +/** + * @brief Enable address error interrupt. + * @rmtoll CR ADDRERRIE LL_PKA_EnableIT_ADDRERR + * @param PKAx PKA Instance. + * @retval None + */ +__STATIC_INLINE void LL_PKA_EnableIT_ADDRERR(PKA_TypeDef *PKAx) +{ + SET_BIT(PKAx->CR, PKA_CR_ADDRERRIE); +} + +/** + * @brief Enable RAM error interrupt. + * @rmtoll CR RAMERRIE LL_PKA_EnableIT_RAMERR + * @param PKAx PKA Instance. + * @retval None + */ +__STATIC_INLINE void LL_PKA_EnableIT_RAMERR(PKA_TypeDef *PKAx) +{ + SET_BIT(PKAx->CR, PKA_CR_RAMERRIE); +} + +/** + * @brief Enable OPERATION error interrupt. + * @rmtoll CR OPERRIE LL_PKA_EnableIT_OPERR + * @param PKAx PKA Instance. + * @retval None + */ +__STATIC_INLINE void LL_PKA_EnableIT_OPERR(PKA_TypeDef *PKAx) +{ + SET_BIT(PKAx->CR, PKA_CR_OPERRIE); +} + +/** + * @brief Enable end of operation interrupt. + * @rmtoll CR PROCENDIE LL_PKA_EnableIT_PROCEND + * @param PKAx PKA Instance. + * @retval None + */ +__STATIC_INLINE void LL_PKA_EnableIT_PROCEND(PKA_TypeDef *PKAx) +{ + SET_BIT(PKAx->CR, PKA_CR_PROCENDIE); +} + +/** + * @brief Disable address error interrupt. + * @rmtoll CR ADDRERRIE LL_PKA_DisableIT_ADDERR + * @param PKAx PKA Instance. + * @retval None + */ +__STATIC_INLINE void LL_PKA_DisableIT_ADDERR(PKA_TypeDef *PKAx) +{ + CLEAR_BIT(PKAx->CR, PKA_CR_ADDRERRIE); +} + +/** + * @brief Disable RAM error interrupt. + * @rmtoll CR RAMERRIE LL_PKA_DisableIT_RAMERR + * @param PKAx PKA Instance. + * @retval None + */ +__STATIC_INLINE void LL_PKA_DisableIT_RAMERR(PKA_TypeDef *PKAx) +{ + CLEAR_BIT(PKAx->CR, PKA_CR_RAMERRIE); +} + +/** + * @brief Disable End of operation interrupt. + * @rmtoll CR PROCENDIE LL_PKA_DisableIT_PROCEND + * @param PKAx PKA Instance. + * @retval None + */ +__STATIC_INLINE void LL_PKA_DisableIT_PROCEND(PKA_TypeDef *PKAx) +{ + CLEAR_BIT(PKAx->CR, PKA_CR_PROCENDIE); +} + +/** + * @brief Disable OPERATION error interrupt. + * @rmtoll CR OPERRIE LL_PKA_EnableIT_OPERR + * @param PKAx PKA Instance. + * @retval None + */ +__STATIC_INLINE void LL_PKA_DisableIT_OPERR(PKA_TypeDef *PKAx) +{ + CLEAR_BIT(PKAx->CR, PKA_CR_OPERRIE); +} + +/** + * @brief Check if address error interrupt is enabled. + * @rmtoll CR ADDRERRIE LL_PKA_IsEnabledIT_ADDRERR + * @param PKAx PKA Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PKA_IsEnabledIT_ADDRERR(const PKA_TypeDef *PKAx) +{ + return ((READ_BIT(PKAx->CR, PKA_CR_ADDRERRIE) == (PKA_CR_ADDRERRIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if RAM error interrupt is enabled. + * @rmtoll CR RAMERRIE LL_PKA_IsEnabledIT_RAMERR + * @param PKAx PKA Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PKA_IsEnabledIT_RAMERR(const PKA_TypeDef *PKAx) +{ + return ((READ_BIT(PKAx->CR, PKA_CR_RAMERRIE) == (PKA_CR_RAMERRIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if OPERATION error interrupt is enabled. + * @rmtoll CR OPERRIE LL_PKA_IsEnabledIT_OPERR + * @param PKAx PKA Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PKA_IsEnabledIT_OPERR(const PKA_TypeDef *PKAx) +{ + return ((READ_BIT(PKAx->CR, PKA_CR_OPERRIE) == (PKA_CR_OPERRIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if end of operation interrupt is enabled. + * @rmtoll CR PROCENDIE LL_PKA_IsEnabledIT_PROCEND + * @param PKAx PKA Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PKA_IsEnabledIT_PROCEND(const PKA_TypeDef *PKAx) +{ + return ((READ_BIT(PKAx->CR, PKA_CR_PROCENDIE) == (PKA_CR_PROCENDIE)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup PKA_LL_EF_FLAG_Management PKA flag management + * @{ + */ + +/** + * @brief Get PKA address error flag. + * @rmtoll SR ADDRERRF LL_PKA_IsActiveFlag_ADDRERR + * @param PKAx PKA Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PKA_IsActiveFlag_ADDRERR(const PKA_TypeDef *PKAx) +{ + return ((READ_BIT(PKAx->SR, PKA_SR_ADDRERRF) == (PKA_SR_ADDRERRF)) ? 1UL : 0UL); +} + +/** + * @brief Get PKA RAM error flag. + * @rmtoll SR RAMERRF LL_PKA_IsActiveFlag_RAMERR + * @param PKAx PKA Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PKA_IsActiveFlag_RAMERR(const PKA_TypeDef *PKAx) +{ + return ((READ_BIT(PKAx->SR, PKA_SR_RAMERRF) == (PKA_SR_RAMERRF)) ? 1UL : 0UL); +} + +/** + * @brief Get PKA OPERATION error flag. + * @rmtoll SR OPERRF LL_PKA_IsActiveFlag_OPERR + * @param PKAx PKA Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PKA_IsActiveFlag_OPERR(const PKA_TypeDef *PKAx) +{ + return ((READ_BIT(PKAx->SR, PKA_SR_OPERRF) == (PKA_SR_OPERRF)) ? 1UL : 0UL); +} + +/** + * @brief Get PKA end of operation flag. + * @rmtoll SR PROCENDF LL_PKA_IsActiveFlag_PROCEND + * @param PKAx PKA Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PKA_IsActiveFlag_PROCEND(const PKA_TypeDef *PKAx) +{ + return ((READ_BIT(PKAx->SR, PKA_SR_PROCENDF) == (PKA_SR_PROCENDF)) ? 1UL : 0UL); +} + +/** + * @brief Get PKA busy flag. + * @rmtoll SR BUSY LL_PKA_IsActiveFlag_BUSY + * @param PKAx PKA Instance. + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PKA_IsActiveFlag_BUSY(const PKA_TypeDef *PKAx) +{ + return ((READ_BIT(PKAx->SR, PKA_SR_BUSY) == (PKA_SR_BUSY)) ? 1UL : 0UL); +} + +/** + * @brief Clear PKA address error flag. + * @rmtoll CLRFR ADDRERRFC LL_PKA_ClearFlag_ADDERR + * @param PKAx PKA Instance. + * @retval None + */ +__STATIC_INLINE void LL_PKA_ClearFlag_ADDERR(PKA_TypeDef *PKAx) +{ + SET_BIT(PKAx->CLRFR, PKA_CLRFR_ADDRERRFC); +} + +/** + * @brief Clear PKA RAM error flag. + * @rmtoll CLRFR RAMERRFC LL_PKA_ClearFlag_RAMERR + * @param PKAx PKA Instance. + * @retval None + */ +__STATIC_INLINE void LL_PKA_ClearFlag_RAMERR(PKA_TypeDef *PKAx) +{ + SET_BIT(PKAx->CLRFR, PKA_CLRFR_RAMERRFC); +} + +/** + * @brief Clear PKA OPERATION error flag. + * @rmtoll CLRFR OPERRFC LL_PKA_ClearFlag_OPERR + * @param PKAx PKA Instance. + * @retval None + */ +__STATIC_INLINE void LL_PKA_ClearFlag_OPERR(PKA_TypeDef *PKAx) +{ + SET_BIT(PKAx->CLRFR, PKA_CLRFR_OPERRFC); +} + +/** + * @brief Clear PKA end of operation flag. + * @rmtoll CLRFR PROCENDFC LL_PKA_ClearFlag_PROCEND + * @param PKAx PKA Instance. + * @retval None + */ +__STATIC_INLINE void LL_PKA_ClearFlag_PROCEND(PKA_TypeDef *PKAx) +{ + SET_BIT(PKAx->CLRFR, PKA_CLRFR_PROCENDFC); +} + +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) + +/** @defgroup PKA_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +ErrorStatus LL_PKA_DeInit(const PKA_TypeDef *PKAx); +ErrorStatus LL_PKA_Init(PKA_TypeDef *PKAx, LL_PKA_InitTypeDef *PKA_InitStruct); +void LL_PKA_StructInit(LL_PKA_InitTypeDef *PKA_InitStruct); + +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined(PKA) */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_LL_PKA_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_pwr.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_pwr.h new file mode 100644 index 0000000000..72294ae911 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_pwr.h @@ -0,0 +1,2008 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_pwr.h + * @author MCD Application Team + * @brief Header file of PWR LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_LL_PWR_H +#define STM32H5xx_LL_PWR_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (PWR) + +/** @defgroup PWR_LL PWR + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup PWR_LL_Private_Constants PWR Private Constants + * @{ + */ + +/** @defgroup PWR_LL_WAKEUP_PIN_OFFSET Wake-Up Pins register offsets Defines + * @brief Flags defines which can be used with LL_PWR_WriteReg function + * @{ + */ +/* Wake-Up Pins PWR register offsets */ +#define LL_PWR_WAKEUP_PINS_PULL_SHIFT_OFFSET 2UL +#define LL_PWR_WAKEUP_PINS_MAX_SHIFT_MASK 0x7FU +/** + * @} + */ +/** + * @} + */ +/* Private macros ------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup PWR_LL_Exported_Constants PWR Exported Constants + * @{ + */ + +/** @defgroup PWR_LL_EC_CLEAR_FLAG Clear Flags Defines + * @brief Flags defines which can be used with LL_PWR_WriteReg function + * @{ + */ +#define LL_PWR_PMCR_CSSF PWR_PMCR_CSSF /*!< Clear STOP and STANDBY flags */ +#define LL_PWR_WUSCR_CWUF1 PWR_WUSCR_CWUF1 /*!< Clear Wakeup flag 1 */ +#define LL_PWR_WUSCR_CWUF2 PWR_WUSCR_CWUF2 /*!< Clear Wakeup flag 2 */ +#define LL_PWR_WUSCR_CWUF3 PWR_WUSCR_CWUF3 /*!< Clear Wakeup flag 3 */ +#define LL_PWR_WUSCR_CWUF4 PWR_WUSCR_CWUF4 /*!< Clear Wakeup flag 4 */ +#define LL_PWR_WUSCR_CWUF5 PWR_WUSCR_CWUF5 /*!< Clear Wakeup flag 5 */ +#define LL_PWR_WUSCR_CWUF6 PWR_WUSCR_CWUF6 /*!< Clear Wakeup flag 6 */ +#define LL_PWR_WUSCR_CWUF7 PWR_WUSCR_CWUF7 /*!< Clear Wakeup flag 7 */ +#define LL_PWR_WUSCR_CWUF8 PWR_WUSCR_CWUF8 /*!< Clear Wakeup flag 8 */ +#define LL_PWR_WUSCR_CWUF_ALL PWR_WUSCR_CWUF /*!< Clear all Wakeup flags */ +/** + * @} + */ + +/** @defgroup PWR_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_PWR_ReadReg function + * @{ + */ +#define LL_PWR_FLAG_VOSRDY PWR_VOSR_VOSRDY /*!< Voltage scaling ready flag */ +#define LL_PWR_FLAG_ACTVOSRDY PWR_VOSR_ACTOVSRDY /*!< Currently applied VOS ready flag */ +#define LL_PWR_FLAG_STOPF PWR_PMSR_STOPF /*!< STOP flag */ +#define LL_PWR_FLAG_SBF PWR_PMSR_SBF /*!< STANDBY flag */ +#define LL_PWR_FLAG_AVDO PWR_VMSR_AVDO /*!< Analog voltage detector output on VDDA flag */ +#define LL_PWR_FLAG_VDDIO2RDY PWR_VMSR_VDDIO2RDY /*!< VDDIO2 ready flag */ +#define LL_PWR_FLAG_PVDO PWR_VMSR_PVDO /*!< Programmable voltage detect output flag */ +#define LL_PWR_FLAG_USB33RDY PWR_VMSR_USB33RDY /*!< VDDUSB ready flag */ +#define LL_PWR_FLAG_TEMPH PWR_BDSR_TEMPH /*!< Temperature level flag (versus high threshold) */ +#define LL_PWR_FLAG_TEMPL PWR_BDSR_TEMPL /*!< Temperature level flag (versus low threshold) */ +#define LL_PWR_FLAG_VBATH PWR_BDSR_VBATH /*!< VBAT level flag (versus high threshold) */ +#define LL_PWR_FLAG_VBATL PWR_BDSR_VBATL /*!< VBAT level flag (versus low threshold) */ + + +#define LL_PWR_WAKEUP_FLAG1 PWR_WUSR_WUF1 /*!< Wakeup flag 1 */ +#define LL_PWR_WAKEUP_FLAG2 PWR_WUSR_WUF2 /*!< Wakeup flag 2 */ +#define LL_PWR_WAKEUP_FLAG3 PWR_WUSR_WUF3 /*!< Wakeup flag 3 */ +#define LL_PWR_WAKEUP_FLAG4 PWR_WUSR_WUF4 /*!< Wakeup flag 4 */ +#define LL_PWR_WAKEUP_FLAG5 PWR_WUSR_WUF5 /*!< Wakeup flag 5 */ +#define LL_PWR_WAKEUP_FLAG6 PWR_WUSR_WUF6 /*!< Wakeup flag 6 */ +#define LL_PWR_WAKEUP_FLAG7 PWR_WUSR_WUF7 /*!< Wakeup flag 7 */ +#define LL_PWR_WAKEUP_FLAG8 PWR_WUSR_WUF8 /*!< Wakeup flag 8 */ +/** + * @} + */ + +/** @defgroup PWR_LL_EC_LOW_POWER_MODE_SELCTION Low Power Mode Selection + * @{ + */ +#define LL_PWR_STOP_MODE (0U) /*!< STOP 0 mode */ +#define LL_PWR_STANDBY_MODE PWR_PMCR_LPMS /*!< STANDBY mode */ + + +/** + * @} + */ + +/** @defgroup PWR_LL_EC_VOLTAGE_SCALING_RANGE_SELECTION PWR Voltage scaling range selection + * @{ + */ +#define LL_PWR_REGU_VOLTAGE_SCALE0 PWR_VOSCR_VOS /*!< Voltage scaling range 0 */ +#define LL_PWR_REGU_VOLTAGE_SCALE1 PWR_VOSCR_VOS_1 /*!< Voltage scaling range 1 */ +#define LL_PWR_REGU_VOLTAGE_SCALE2 PWR_VOSCR_VOS_0 /*!< Voltage scaling range 2 */ +#define LL_PWR_REGU_VOLTAGE_SCALE3 0x00000000U /*!< Voltage scaling range 3 */ +/** + * @} + */ + +/** @defgroup PWR_LL_EC_STOP_MODE_REGU_VOLTAGE Stop mode Regulator Voltage Scaling + * @{ + */ +#define LL_PWR_REGU_VOLTAGE_SVOS_SCALE5 PWR_PMCR_SVOS_0 /*!< Select voltage scale 5 when system enters STOP mode */ +#define LL_PWR_REGU_VOLTAGE_SVOS_SCALE4 PWR_PMCR_SVOS_1 /*!< Select voltage scale 4 when system enters STOP mode */ +#define LL_PWR_REGU_VOLTAGE_SVOS_SCALE3 (PWR_PMCR_SVOS_0 | PWR_PMCR_SVOS_1) /*!< Select voltage scale 3 when system enters STOP mode */ +/** + * @} + */ + +/** @defgroup PWR_LL_EC_PVD_LEVEL_SELECTION PWR Power Voltage Detector Level Selection + * @{ + */ +#define LL_PWR_PVDLEVEL_0 0U /*!< Voltage threshold detected by PVD 1.95 V */ +#define LL_PWR_PVDLEVEL_1 PWR_VMCR_PLS_0 /*!< Voltage threshold detected by PVD 2.10 V */ +#define LL_PWR_PVDLEVEL_2 PWR_VMCR_PLS_1 /*!< Voltage threshold detected by PVD 2.25 V */ +#define LL_PWR_PVDLEVEL_3 (PWR_VMCR_PLS_0 | PWR_VMCR_PLS_1) /*!< Voltage threshold detected by PVD 2.40 V */ +#define LL_PWR_PVDLEVEL_4 PWR_VMCR_PLS_2 /*!< Voltage threshold detected by PVD 2.55 V */ +#define LL_PWR_PVDLEVEL_5 (PWR_VMCR_PLS_0 | PWR_VMCR_PLS_2) /*!< Voltage threshold detected by PVD 2.70 V */ +#define LL_PWR_PVDLEVEL_6 (PWR_VMCR_PLS_1 | PWR_VMCR_PLS_2) /*!< Voltage threshold detected by PVD 2.85 V */ +#define LL_PWR_PVDLEVEL_7 PWR_VMCR_PLS /*!< External input analog voltage on PVD_IN + pin, compared to internal VREFINT level */ +/** + * @} + */ + +/** @defgroup PWR_LL_EC_AVDLEVEL Power Analog Voltage Level Detector + * @{ + */ +#define LL_PWR_AVDLEVEL_0 0U /*!< Analog Voltage threshold detected by AVD 1.7 V */ +#define LL_PWR_AVDLEVEL_1 PWR_VMCR_ALS_0 /*!< Analog Voltage threshold detected by AVD 2.1 V */ +#define LL_PWR_AVDLEVEL_2 PWR_VMCR_ALS_1 /*!< Analog Voltage threshold detected by AVD 2.5 V */ +#define LL_PWR_AVDLEVEL_3 PWR_VMCR_ALS /*!< Analog Voltage threshold detected by AVD 2.8 V */ + +/** + * @} + */ + +/** @defgroup PWR_LL_EC_WAKEUP_PIN PWR Wake Up Pin + * @{ + */ +#define LL_PWR_WAKEUP_PIN1 PWR_WUCR_WUPEN1 /*!< Wakeup pin 1 enable */ +#define LL_PWR_WAKEUP_PIN2 PWR_WUCR_WUPEN2 /*!< Wakeup pin 2 enable */ +#define LL_PWR_WAKEUP_PIN3 PWR_WUCR_WUPEN3 /*!< Wakeup pin 3 enable */ +#define LL_PWR_WAKEUP_PIN4 PWR_WUCR_WUPEN4 /*!< Wakeup pin 4 enable */ +#define LL_PWR_WAKEUP_PIN5 PWR_WUCR_WUPEN5 /*!< Wakeup pin 5 enable */ +#define LL_PWR_WAKEUP_PIN6 PWR_WUCR_WUPEN6 /*!< Wakeup pin 6 enable */ +#define LL_PWR_WAKEUP_PIN7 PWR_WUCR_WUPEN7 /*!< Wakeup pin 7 enable */ +#define LL_PWR_WAKEUP_PIN8 PWR_WUCR_WUPEN8 /*!< Wakeup pin 8 enable */ +/** + * @} + */ + +/** @defgroup PWR_LL_EC_WAKEUP_PIN_PULL Wakeup Pins pull configuration + * @{ + */ +#define LL_PWR_WAKEUP_PIN_NOPULL 0x00000000UL /*!< Configure Wake-Up pin in no pull */ +#define LL_PWR_WAKEUP_PIN_PULLUP 0x00000001UL /*!< Configure Wake-Up pin in pull Up */ +#define LL_PWR_WAKEUP_PIN_PULLDOWN 0x00000002UL /*!< Configure Wake-Up pin in pull Down */ +/** + * @} + */ + +/** @defgroup PWR_LL_EC_SUPPLY_PWR Power supply source configuration + * @{ + */ +#define LL_PWR_EXTERNAL_SOURCE_SUPPLY PWR_SCCR_BYPASS /*!< The SMPS and the LDO are Bypassed. + The Core domains are supplied from an external source */ +/** + * @} + */ + +/** @defgroup PWR_LL_EC_CHARGING_RESISTOR_SELECTION PWR VBAT Charging Resistor Selection + * @{ + */ +#define LL_PWR_BATT_CHARG_RESISTOR_5K 0U /*!< Charge the battery through a 5 kO resistor */ +#define LL_PWR_BATT_CHARG_RESISTOR_1_5K PWR_BDCR_VBRS /*!< Charge the battery through a 1.5 kO resistor */ +/** + * @} + */ + +/** @defgroup PWR_LL_EC_ITEMS_SECURE_ATTRIBUTE PWR Items Secure Attribute + * @{ + */ +#define LL_PWR_WAKEUP_PIN1_NSEC 0U /* Wake up pin 1 nsecure mode */ +#define LL_PWR_WAKEUP_PIN1_SEC PWR_SECCFGR_WUP1SEC /* Wake up pin 1 secure mode */ +#define LL_PWR_WAKEUP_PIN2_NSEC 0U /* Wake up pin 2 nsecure mode */ +#define LL_PWR_WAKEUP_PIN2_SEC PWR_SECCFGR_WUP2SEC /* Wake up pin 2 secure mode */ +#define LL_PWR_WAKEUP_PIN3_NSEC 0U /* Wake up pin 3 nsecure mode */ +#define LL_PWR_WAKEUP_PIN3_SEC PWR_SECCFGR_WUP3SEC /* Wake up pin 3 secure mode */ +#define LL_PWR_WAKEUP_PIN4_NSEC 0U /* Wake up pin 4 nsecure mode */ +#define LL_PWR_WAKEUP_PIN4_SEC PWR_SECCFGR_WUP4SEC /* Wake up pin 4 secure mode */ +#define LL_PWR_WAKEUP_PIN5_NSEC 0U /* Wake up pin 5 nsecure mode */ +#define LL_PWR_WAKEUP_PIN5_SEC PWR_SECCFGR_WUP5SEC /* Wake up pin 5 secure mode */ +#define LL_PWR_WAKEUP_PIN6_NSEC 0U /* Wake up pin 6 nsecure mode */ +#define LL_PWR_WAKEUP_PIN6_SEC PWR_SECCFGR_WUP6SEC /* Wake up pin 6 secure mode */ +#define LL_PWR_WAKEUP_PIN7_NSEC 0U /* Wake up pin 7 nsecure mode */ +#define LL_PWR_WAKEUP_PIN7_SEC PWR_SECCFGR_WUP7SEC /* Wake up pin 7 secure mode */ +#define LL_PWR_WAKEUP_PIN8_NSEC 0U /* Wake up pin 8 nsecure mode */ +#define LL_PWR_WAKEUP_PIN8_SEC PWR_SECCFGR_WUP8SEC /* Wake up pin 8 secure mode */ + +#define LL_PWR_RET_NSEC 0U /* Retention nsecure mode */ +#define LL_PWR_RET_SEC PWR_SECCFGR_RETSEC /* Retention secure mode */ +#define LL_PWR_LPM_NSEC 0U /* Low-power modes nsecure mode */ +#define LL_PWR_LPM_SEC PWR_SECCFGR_LPMSEC /* Low-power modes secure mode */ +#define LL_PWR_VDM_NSEC 0U /* Voltage detection and monitoring nsecure mode */ +#define LL_PWR_VDM_SEC PWR_SECCFGR_SCMSEC /* Voltage detection and monitoring secure mode */ +#define LL_PWR_VB_NSEC 0U /* Backup domain nsecure mode */ +#define LL_PWR_VB_SEC PWR_SECCFGR_VBSEC /* Backup domain secure mode */ +#define LL_PWR_APC_NSEC 0U /* Pull-up/pull-down nsecure mode */ +#define LL_PWR_APC_SEC PWR_SECCFGR_VUSBSEC /* Pull-up/pull-down secure mode */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ + +/** @defgroup PWR_LL_Exported_Macros PWR Exported Macros + * @{ + */ + +/** @defgroup PWR_LL_EM_WRITE_READ Common Write and Read Registers Macros + * @{ + */ + +/** + * @brief Write a value in PWR register. + * @param __REG__ Register to be written. + * @param __VALUE__ Value to be written in the register. + * @retval None. + */ +#define LL_PWR_WriteReg(__REG__, __VALUE__) WRITE_REG(PWR->__REG__, (__VALUE__)) + +/** + * @brief Read a value in PWR register. + * @param __REG__ Register to be read. + * @retval Register value. + */ +#define LL_PWR_ReadReg(__REG__) READ_REG(PWR->__REG__) +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup PWR_LL_Exported_Functions PWR Exported Functions + * @{ + */ + +/** @defgroup PWR_LL_EF_CONFIGURATION PWR Configuration + * @{ + */ + +/** + * @brief Set system power mode. + * @rmtoll PMCR LPMS LL_PWR_SetPowerMode + * @param Mode : This parameter can be one of the following values: + * @arg @ref LL_PWR_STOP_MODE + * @arg @ref LL_PWR_STANDBY_MODE + * @retval None + */ +__STATIC_INLINE void LL_PWR_SetPowerMode(uint32_t Mode) +{ + MODIFY_REG(PWR->PMCR, PWR_PMCR_LPMS, Mode); +} + +/** + * @brief Get system power mode. + * @rmtoll PMCR LPMS LL_PWR_GetPowerMode + * @retval Returned value can be one of the following values: + * @arg @ref LL_PWR_STOP_MODE + * @arg @ref LL_PWR_STANDBY_MODE + */ +__STATIC_INLINE uint32_t LL_PWR_GetPowerMode(void) +{ + return (READ_BIT(PWR->PMCR, PWR_PMCR_LPMS)); +} + +/** + * @brief Set the internal Regulator output voltage in STOP mode + * @rmtoll PMCR SVOS LL_PWR_SetStopModeRegulVoltageScaling + * @param VoltageScaling This parameter can be one of the following values: + * @arg @ref LL_PWR_REGU_VOLTAGE_SVOS_SCALE3 + * @arg @ref LL_PWR_REGU_VOLTAGE_SVOS_SCALE4 + * @arg @ref LL_PWR_REGU_VOLTAGE_SVOS_SCALE5 + * @retval None + */ +__STATIC_INLINE void LL_PWR_SetStopModeRegulVoltageScaling(uint32_t VoltageScaling) +{ + MODIFY_REG(PWR->PMCR, PWR_PMCR_SVOS, VoltageScaling); +} + +/** + * @brief Get the internal Regulator output voltage in STOP mode + * @rmtoll PMCR SVOS LL_PWR_GetStopModeRegulVoltageScaling + * @retval Returned value can be one of the following values: + * @arg @ref LL_PWR_REGU_VOLTAGE_SVOS_SCALE3 + * @arg @ref LL_PWR_REGU_VOLTAGE_SVOS_SCALE4 + * @arg @ref LL_PWR_REGU_VOLTAGE_SVOS_SCALE5 + */ +__STATIC_INLINE uint32_t LL_PWR_GetStopModeRegulVoltageScaling(void) +{ + return (uint32_t)(READ_BIT(PWR->PMCR, PWR_PMCR_SVOS)); +} + +/** + * @brief Enable the Flash Power Down in Stop Mode + * @rmtoll PMCR FLPS LL_PWR_EnableFlashPowerDown + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableFlashPowerDown(void) +{ + SET_BIT(PWR->PMCR, PWR_PMCR_FLPS); +} + +/** + * @brief Disable the Flash Power Down in Stop Mode + * @rmtoll PMCR FLPS LL_PWR_DisableFlashPowerDown + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableFlashPowerDown(void) +{ + CLEAR_BIT(PWR->PMCR, PWR_PMCR_FLPS); +} + +/** + * @brief Check if the Flash Power Down in Stop Mode is enabled + * @rmtoll PMCR FLPS LL_PWR_IsEnabledFlashPowerDown + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledFlashPowerDown(void) +{ + return ((READ_BIT(PWR->PMCR, PWR_PMCR_FLPS) == (PWR_PMCR_FLPS)) ? 1UL : 0UL); +} + +/** + * @brief Enable the Analog Voltage Booster (VDDA) + * @rmtoll PMCR BOOSTE LL_PWR_EnableAnalogBooster + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableAnalogBooster(void) +{ + SET_BIT(PWR->PMCR, PWR_PMCR_BOOSTE); +} + +/** + * @brief Disable the Analog Voltage Booster (VDDA) + * @rmtoll PMCR BOOSTE LL_PWR_DisableAnalogBooster + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableAnalogBooster(void) +{ + CLEAR_BIT(PWR->PMCR, PWR_PMCR_BOOSTE); +} + +/** + * @brief Check if the Analog Voltage Booster (VDDA) is enabled + * @rmtoll PMCR BOOSTE LL_PWR_IsEnabledAnalogBooster + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledAnalogBooster(void) +{ + return ((READ_BIT(PWR->PMCR, PWR_PMCR_BOOSTE) == (PWR_PMCR_BOOSTE)) ? 1UL : 0UL); +} + +/** + * @brief Enable the Analog Voltage Ready to isolate the BOOST IP until VDDA will be ready + * @rmtoll PMCR AVD_READY LL_PWR_EnableAnalogVoltageReady + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableAnalogVoltageReady(void) +{ + SET_BIT(PWR->PMCR, PWR_PMCR_AVD_READY); +} + +/** + * @brief Disable the Analog Voltage Ready (VDDA) + * @rmtoll PMCR AVD_READY LL_PWR_DisableAnalogVoltageReady + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableAnalogVoltageReady(void) +{ + CLEAR_BIT(PWR->PMCR, PWR_PMCR_AVD_READY); +} + +/** + * @brief Check if the Analog Voltage Booster (VDDA) is enabled + * @rmtoll PMCR AVD_READY LL_PWR_IsEnabledAnalogVoltageReady + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledAnalogVoltageReady(void) +{ + return ((READ_BIT(PWR->PMCR, PWR_PMCR_AVD_READY) == (PWR_PMCR_AVD_READY)) ? 1UL : 0UL); +} + +/** + * @brief Enable the AHB RAM1 shut-off in Stop mode + * @rmtoll PMCR SRAM1SO LL_PWR_EnableAHBRAM1ShutOff + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableAHBRAM1ShutOff(void) +{ + SET_BIT(PWR->PMCR, PWR_PMCR_SRAM1SO); +} + +/** + * @brief Disable the AHB RAM1 shut-off in Stop mode + * @rmtoll PMCR SRAM1SO LL_PWR_DisableAHBRAM1ShutOff + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableAHBRAM1ShutOff(void) +{ + CLEAR_BIT(PWR->PMCR, PWR_PMCR_SRAM1SO); +} + +/** + * @brief Check if the AHB RAM1 shut-off in Stop mode is enabled + * @rmtoll CR1 SRAM1SO LL_PWR_IsEnabledAHBRAM1ShutOff + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledAHBRAM1ShutOff(void) +{ + return ((READ_BIT(PWR->PMCR, PWR_PMCR_SRAM1SO) == (PWR_PMCR_SRAM1SO)) ? 1UL : 0UL); +} +#if defined (PWR_PMCR_SRAM2_48SO) +/** + * @brief Enable the AHB RAM2 48K Bytes shut-off in Stop mode + * @rmtoll PMCR SRAM2_48SO LL_PWR_EnableAHBRAM2_48K_ShutOff + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableAHBRAM2_48K_ShutOff(void) +{ + SET_BIT(PWR->PMCR, PWR_PMCR_SRAM2_48SO); +} + +/** + * @brief Disable the AHB RAM2 48K Bytes shut-off in Stop mode + * @rmtoll PMCR SRAM2_48SO LL_PWR_DisableAHBRAM2_48K_ShutOff + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableAHBRAM2_48K_ShutOff(void) +{ + CLEAR_BIT(PWR->PMCR, PWR_PMCR_SRAM2_48SO); +} + +/** + * @brief Check if the AHB RAM2 shut-off in Stop mode is enabled + * @rmtoll PMCR SRAM2_48SO LL_PWR_IsEnabledAHBRAM2_48K_ShutOff + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledAHBRAM2_48K_ShutOff(void) +{ + return ((READ_BIT(PWR->PMCR, PWR_PMCR_SRAM2_48SO) == (PWR_PMCR_SRAM2_48SO)) ? 1UL : 0UL); +} +#endif /* PWR_PMCR_SRAM2_48SO */ + +#if defined (PWR_PMCR_SRAM2_16SO) +/** + * @brief Enable the AHB RAM2 16K Bytes shut-off in Stop mode + * @rmtoll PMCR SRAM2_16SO LL_PWR_EnableAHBRAM2_16K_ShutOff + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableAHBRAM2_16K_ShutOff(void) +{ + SET_BIT(PWR->PMCR, PWR_PMCR_SRAM2_16SO); +} + +/** + * @brief Disable the AHB RAM2 16K Bytes shut-off in Stop mode + * @rmtoll PMCR SRAM2_16SO LL_PWR_DisableAHBRAM2_16K_ShutOff + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableAHBRAM2_16K_ShutOff(void) +{ + CLEAR_BIT(PWR->PMCR, PWR_PMCR_SRAM2_16SO); +} + +/** + * @brief Check if the AHB RAM2 shut-off in Stop mode is enabled + * @rmtoll PMCR SRAM2_16SO LL_PWR_IsEnabledAHBRAM2_16K_ShutOff + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledAHBRAM2_16K_ShutOff(void) +{ + return ((READ_BIT(PWR->PMCR, PWR_PMCR_SRAM2_16SO) == (PWR_PMCR_SRAM2_16SO)) ? 1UL : 0UL); +} +#else +/** + * @brief Enable the AHB RAM2 shut-off in Stop mode + * @rmtoll PMCR SRAM2SO LL_PWR_EnableAHBRAM2ShutOff + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableAHBRAM2ShutOff(void) +{ + SET_BIT(PWR->PMCR, PWR_PMCR_SRAM2SO); +} + +/** + * @brief Disable the AHB RAM2 shut-off in Stop mode + * @rmtoll PMCR SRAM2SO LL_PWR_DisableAHBRAM2ShutOff + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableAHBRAM2ShutOff(void) +{ + CLEAR_BIT(PWR->PMCR, PWR_PMCR_SRAM2SO); +} + +/** + * @brief Check if the AHB RAM2 shut-off in Stop mode is enabled + * @rmtoll PMCR SRAM2SO LL_PWR_IsEnabledAHBRAM2ShutOff + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledAHBRAM2ShutOff(void) +{ + return ((READ_BIT(PWR->PMCR, PWR_PMCR_SRAM2SO) == (PWR_PMCR_SRAM2SO)) ? 1UL : 0UL); +} +#endif /* PWR_PMCR_SRAM2_16SO */ + +#if defined (PWR_PMCR_SRAM3SO) +/** + * @brief Enable the AHB RAM3 shut-off in Stop mode + * @rmtoll PMCR SRAM3SO LL_PWR_EnableAHBRAM3ShutOff + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableAHBRAM3ShutOff(void) +{ + SET_BIT(PWR->PMCR, PWR_PMCR_SRAM3SO); +} + +/** + * @brief Disable the AHB RAM3 shut-off in Stop mode + * @rmtoll PMCR SRAM3SO LL_PWR_DisableAHBRAM3ShutOff + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableAHBRAM3ShutOff(void) +{ + CLEAR_BIT(PWR->PMCR, PWR_PMCR_SRAM3SO); +} + +/** + * @brief Check if the AHB RAM3 shut-off in Stop mode is enabled + * @rmtoll PMCR SRAM3SO LL_PWR_IsEnabledAHBRAM3ShutOff + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledAHBRAM3ShutOff(void) +{ + return ((READ_BIT(PWR->PMCR, PWR_PMCR_SRAM3SO) == (PWR_PMCR_SRAM3SO)) ? 1UL : 0UL); +} +#endif /* PWR_PMCR_SRAM3SO */ + +#if defined (PWR_PMCR_ETHERNETSO) +/** + * @brief Enable the ETHERNET RAM shut-off in Stop mode + * @rmtoll PMCR ETHERNETSO LL_PWR_EnableETHERNETRAMShutOff + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableETHERNETRAMShutOff(void) +{ + SET_BIT(PWR->PMCR, PWR_PMCR_ETHERNETSO); +} + +/** + * @brief Disable the ETHERNET RAM shut-off in Stop mode + * @rmtoll PMCR ETHERNETSO LL_PWR_DisableETHERNETRAMShutOff + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableETHERNETRAMShutOff(void) +{ + CLEAR_BIT(PWR->PMCR, PWR_PMCR_ETHERNETSO); +} + +/** + * @brief Check if the ETHERNET RAM shut-off in Stop mode is enabled + * @rmtoll PMCR ETHERNETSO LL_PWR_IsEnabledETHERNETRAMShutOff + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledETHERNETRAMShutOff(void) +{ + return ((READ_BIT(PWR->PMCR, PWR_PMCR_ETHERNETSO) == (PWR_PMCR_ETHERNETSO)) ? 1UL : 0UL); +} +#endif /* PWR_PMCR_ETHERNETSO */ + +/** + * @brief Set the regulator supply output voltage. + * @rmtoll VOSCR VOS LL_PWR_SetRegulVoltageScaling + * @param VoltageScaling This parameter can be one of the following values: + * @arg @ref LL_PWR_REGU_VOLTAGE_SCALE0 + * @arg @ref LL_PWR_REGU_VOLTAGE_SCALE1 + * @arg @ref LL_PWR_REGU_VOLTAGE_SCALE2 + * @arg @ref LL_PWR_REGU_VOLTAGE_SCALE3 + * @retval None + */ +__STATIC_INLINE void LL_PWR_SetRegulVoltageScaling(uint32_t VoltageScaling) +{ + MODIFY_REG(PWR->VOSCR, PWR_VOSCR_VOS, VoltageScaling); +} + +/** + * @brief Get the regulator supply output voltage. + * @rmtoll VOSCR VOS LL_PWR_GetRegulVoltageScaling + * @retval Returned value can be one of the following values: + * @arg @ref LL_PWR_REGU_VOLTAGE_SCALE0 + * @arg @ref LL_PWR_REGU_VOLTAGE_SCALE1 + * @arg @ref LL_PWR_REGU_VOLTAGE_SCALE2 + * @arg @ref LL_PWR_REGU_VOLTAGE_SCALE3 + */ +__STATIC_INLINE uint32_t LL_PWR_GetRegulVoltageScaling(void) +{ + return (uint32_t)(READ_BIT(PWR->VOSCR, PWR_VOSCR_VOS)); +} + +/** + * @brief Get currently voltage scaling applied to VCORE. + * @rmtoll VOSSR ACTVOS[1:0] LL_PWR_GetCurrentVOS + * @retval Returned value can be one of the following values: + * @arg @ref LL_PWR_REGU_VOLTAGE_SCALE0 + * @arg @ref LL_PWR_REGU_VOLTAGE_SCALE1 + * @arg @ref LL_PWR_REGU_VOLTAGE_SCALE2 + * @arg @ref LL_PWR_REGU_VOLTAGE_SCALE3 + */ +__STATIC_INLINE uint32_t LL_PWR_GetCurrentVOS(void) +{ + return (READ_BIT(PWR->VOSSR, PWR_VOSSR_ACTVOS)); +} + +/** + * @brief Enable Backup Regulator + * @rmtoll BDCR BREN LL_PWR_EnableBkUpRegulator + * @note When set, the Backup Regulator (used to maintain backup SRAM content in Standby and + * VBAT modes) is enabled. If BRE is reset, the backup Regulator is switched off. The backup + * SRAM can still be used but its content will be lost in the Standby and VBAT modes. Once set, + * the application must wait that the Backup Regulator Ready flag (BRR) is set to indicate that + * the data written into the RAM will be maintained in the Standby and VBAT modes. + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableBkUpRegulator(void) +{ + SET_BIT(PWR->BDCR, PWR_BDCR_BREN); +} + +/** + * @brief Disable Backup Regulator + * @rmtoll BDCR BREN LL_PWR_DisableBkUpRegulator + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableBkUpRegulator(void) +{ + CLEAR_BIT(PWR->BDCR, PWR_BDCR_BREN); +} + +/** + * @brief Check if the backup Regulator is enabled + * @rmtoll BDCR BREN LL_PWR_IsEnabledBkUpRegulator + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledBkUpRegulator(void) +{ + return ((READ_BIT(PWR->BDCR, PWR_BDCR_BREN) == (PWR_BDCR_BREN)) ? 1UL : 0UL); +} + +/** + * @brief Enable VBAT and Temperature monitoring + * @rmtoll BDCR MONEN LL_PWR_EnableMonitoring + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableMonitoring(void) +{ + SET_BIT(PWR->BDCR, PWR_BDCR_MONEN); +} + +/** + * @brief Disable VBAT and Temperature monitoring + * @rmtoll BDCR MONEN LL_PWR_DisableMonitoring + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableMonitoring(void) +{ + CLEAR_BIT(PWR->BDCR, PWR_BDCR_MONEN); +} + +/** + * @brief Check if the VBAT and Temperature monitoring is enabled + * @rmtoll BDCR MONEN LL_PWR_IsEnabledMonitoring + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledMonitoring(void) +{ + return ((READ_BIT(PWR->BDCR, PWR_BDCR_MONEN) == (PWR_BDCR_MONEN)) ? 1UL : 0UL); +} + +/** + * @brief Enable battery charging + * @rmtoll BDCR VBE LL_PWR_EnableBatteryCharging + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableBatteryCharging(void) +{ + SET_BIT(PWR->BDCR, PWR_BDCR_VBE); +} + +/** + * @brief Disable battery charging + * @rmtoll BDCR VBE LL_PWR_DisableBatteryCharging + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableBatteryCharging(void) +{ + CLEAR_BIT(PWR->BDCR, PWR_BDCR_VBE); +} + +/** + * @brief Check if battery charging is enabled + * @rmtoll BDCR VBE LL_PWR_IsEnabledBatteryCharging + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledBatteryCharging(void) +{ + return ((READ_BIT(PWR->BDCR, PWR_BDCR_VBE) == (PWR_BDCR_VBE)) ? 1UL : 0UL); +} + +/** + * @brief Set the Battery charge resistor impedance + * @rmtoll BDCR VBRS LL_PWR_SetBattChargResistor + * @param Resistor This parameter can be one of the following values: + * @arg @ref LL_PWR_BATT_CHARG_RESISTOR_5K + * @arg @ref LL_PWR_BATT_CHARG_RESISTOR_1_5K + * @retval None + */ +__STATIC_INLINE void LL_PWR_SetBattChargResistor(uint32_t Resistor) +{ + MODIFY_REG(PWR->BDCR, PWR_BDCR_VBRS, Resistor); +} + +/** + * @brief Get the Battery charge resistor impedance + * @rmtoll BDCR VBRS LL_PWR_GetBattChargResistor + * @retval Returned value can be one of the following values: + * @arg @ref LL_PWR_BATT_CHARG_RESISTOR_5K + * @arg @ref LL_PWR_BATT_CHARG_RESISTOR_1_5K + */ +__STATIC_INLINE uint32_t LL_PWR_GetBattChargResistor(void) +{ + return (uint32_t)(READ_BIT(PWR->BDCR, PWR_BDCR_VBRS)); +} + +/** + * @brief Enable access to the backup domain + * @rmtoll DBPCR DBP LL_PWR_EnableBkUpAccess + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableBkUpAccess(void) +{ + SET_BIT(PWR->DBPCR, PWR_DBPCR_DBP); +} + +/** + * @brief Disable access to the backup domain + * @rmtoll DBPCR DBP LL_PWR_DisableBkUpAccess + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableBkUpAccess(void) +{ + CLEAR_BIT(PWR->DBPCR, PWR_DBPCR_DBP); +} + +/** + * @brief Check if the backup domain is enabled + * @rmtoll DBPCR DBP LL_PWR_IsEnabledBkUpAccess + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledBkUpAccess(void) +{ + return ((READ_BIT(PWR->DBPCR, PWR_DBPCR_DBP) == (PWR_DBPCR_DBP)) ? 1UL : 0UL); +} + +#if defined (PWR_UCPDR_UCPD_STBY) +/** + * @brief Enable the USB type-C and power delivery memorization in Standby + * mode. + * @note This function must be called just before entering Standby mode. + * @rmtoll UCPDR UCPD_STDBY LL_PWR_EnableUCPDStandbyMode + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableUCPDStandbyMode(void) +{ + SET_BIT(PWR->UCPDR, PWR_UCPDR_UCPD_STBY); +} + +/** + * @brief Disable the USB type-C and power delivery memorization in Standby + * mode. + * @note This function must be called after exiting Standby mode and before + * any UCPD configuration update. + * @rmtoll UCPDR UCPD_STDBY LL_PWR_DisableUCPDStandbyMode + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableUCPDStandbyMode(void) +{ + CLEAR_BIT(PWR->UCPDR, PWR_UCPDR_UCPD_STBY); +} + +/** + * @brief Check if the USB Type-C and Power Delivery Standby mode memorization + * is enabled. + * @rmtoll UCPDR UCPD_STDBY LL_PWR_IsEnabledUCPDStandbyMode + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledUCPDStandbyMode(void) +{ + return ((READ_BIT(PWR->UCPDR, PWR_UCPDR_UCPD_STBY) == (PWR_UCPDR_UCPD_STBY)) ? 1UL : 0UL); +} +#endif /* PWR_UCPDR_UCPD_STBY */ + +#if defined (PWR_UCPDR_UCPD_DBDIS) +/** + * @brief Enable the USB Type-C and power delivery dead battery pull-down behavior + * on UCPD CC1 and CC2 pins. + * @note After exiting reset, the USB Type-C dead battery behavior is enabled, + * which may have a pull-down effect on CC1 and CC2 pins. It is recommended + * to disable it in all cases, either to stop this pull-down or to hand over + * control to the UCPD (which should therefore be initialized before doing the disable). + * @rmtoll UCPDR UCPD_DBDIS LL_PWR_EnableUCPDDeadBattery + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableUCPDDeadBattery(void) +{ + CLEAR_BIT(PWR->UCPDR, PWR_UCPDR_UCPD_DBDIS); +} + +/** + * @brief Disable the USB Type-C and power delivery dead battery pull-down behavior + * on UCPD CC1 and CC2 pins. + * @note After exiting reset, the USB Type-C dead battery behavior is enabled, + * which may have a pull-down effect on CC1 and CC2 pins. It is recommended + * to disable it in all cases, either to stop this pull-down or to hand over + * control to the UCPD (which should therefore be initialized before doing the disable). + * @rmtoll UCPDR UCPD_DBDIS LL_PWR_DisableUCPDDeadBattery + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableUCPDDeadBattery(void) +{ + SET_BIT(PWR->UCPDR, PWR_UCPDR_UCPD_DBDIS); +} + +/** + * @brief Check the USB Type-C and power delivery dead battery pull-down behavior + * on UCPD CC1 and CC2 pins. + * @note After exiting reset, the USB Type-C dead battery behavior is enabled, + * which may have a pull-down effect on CC1 and CC2 pins. It is recommended + * to disable it in all cases, either to stop this pull-down or to hand over + * control to the UCPD (which should therefore be initialized before doing the disable). + * @rmtoll UCPDR UCPD_DBDIS LL_PWR_IsEnabledUCPDDeadBattery + * @retval State of feature (1 : enabled; 0 : disabled). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledUCPDDeadBattery(void) +{ + return ((READ_BIT(PWR->UCPDR, PWR_UCPDR_UCPD_DBDIS) == (PWR_UCPDR_UCPD_DBDIS)) ? 0UL : 1UL); +} +#endif /* PWR_UCPDR_UCPD_DBDIS */ + +/** + * @brief Configure the PWR supply + * @rmtoll SCCR BYPASS LL_PWR_ConfigSupply + * @param SupplySource This parameter can be one of the following values: + * @arg @ref LL_PWR_EXTERNAL_SOURCE_SUPPLY + * @retval None + */ +__STATIC_INLINE void LL_PWR_ConfigSupply(uint32_t SupplySource) +{ + /* Set the power supply configuration */ + MODIFY_REG(PWR->SCCR, (PWR_SCCR_BYPASS), SupplySource); +} + +/** + * @brief Get the PWR supply + * @rmtoll SCCR BYPASS LL_PWR_GetSupply + * @retval The supply configuration. + */ +__STATIC_INLINE uint32_t LL_PWR_GetSupply(void) +{ +#if defined (PWR_SCCR_SMPSEN) + /* Get the power supply configuration */ + return (uint32_t)(READ_BIT(PWR->SCCR, (PWR_SCCR_SMPSEN | PWR_SCCR_LDOEN | PWR_SCCR_BYPASS))); +#else + /* Get the power supply configuration */ + return (uint32_t)(READ_BIT(PWR->SCCR, (PWR_SCCR_LDOEN | PWR_SCCR_BYPASS))); +#endif /* PWR_SCCR_SMPSEN */ +} + +/** + * @brief Enable Power Voltage Detector + * @rmtoll VMCR PVDEN LL_PWR_EnablePVD + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnablePVD(void) +{ + SET_BIT(PWR->VMCR, PWR_VMCR_PVDEN); +} + +/** + * @brief Disable Power Voltage Detector + * @rmtoll VMCR PVDEN LL_PWR_DisablePVD + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisablePVD(void) +{ + CLEAR_BIT(PWR->VMCR, PWR_VMCR_PVDEN); +} + +/** + * @brief Check if Power Voltage Detector is enabled + * @rmtoll VMCR PVDEN LL_PWR_IsEnabledPVD + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledPVD(void) +{ + return ((READ_BIT(PWR->VMCR, PWR_VMCR_PVDEN) == (PWR_VMCR_PVDEN)) ? 1UL : 0UL); +} + +/** + * @brief Configure the voltage threshold detected by the Power Voltage Detector + * @rmtoll VMCR PLS LL_PWR_SetPVDLevel + * @param PVDLevel This parameter can be one of the following values: + * @arg @ref LL_PWR_PVDLEVEL_0 + * @arg @ref LL_PWR_PVDLEVEL_1 + * @arg @ref LL_PWR_PVDLEVEL_2 + * @arg @ref LL_PWR_PVDLEVEL_3 + * @arg @ref LL_PWR_PVDLEVEL_4 + * @arg @ref LL_PWR_PVDLEVEL_5 + * @arg @ref LL_PWR_PVDLEVEL_6 + * @arg @ref LL_PWR_PVDLEVEL_7 + * @retval None + */ +__STATIC_INLINE void LL_PWR_SetPVDLevel(uint32_t PVDLevel) +{ + MODIFY_REG(PWR->VMCR, PWR_VMCR_PLS, PVDLevel); +} + +/** + * @brief Get the voltage threshold detection + * @rmtoll VMCR PLS LL_PWR_GetPVDLevel + * @retval Returned value can be one of the following values: + * @arg @ref LL_PWR_PVDLEVEL_0 + * @arg @ref LL_PWR_PVDLEVEL_1 + * @arg @ref LL_PWR_PVDLEVEL_2 + * @arg @ref LL_PWR_PVDLEVEL_3 + * @arg @ref LL_PWR_PVDLEVEL_4 + * @arg @ref LL_PWR_PVDLEVEL_5 + * @arg @ref LL_PWR_PVDLEVEL_6 + * @arg @ref LL_PWR_PVDLEVEL_7 + */ +__STATIC_INLINE uint32_t LL_PWR_GetPVDLevel(void) +{ + return (uint32_t)(READ_BIT(PWR->VMCR, PWR_VMCR_PLS)); +} + + +/** + * @brief Enable Analog Power Voltage Detector + * @rmtoll VMCR AVDEN LL_PWR_EnableAVD + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableAVD(void) +{ + SET_BIT(PWR->VMCR, PWR_VMCR_AVDEN); +} + +/** + * @brief Disable Analog Power Voltage Detector + * @rmtoll VMCR AVDEN LL_PWR_DisableAVD + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableAVD(void) +{ + CLEAR_BIT(PWR->VMCR, PWR_VMCR_AVDEN); +} + +/** + * @brief Check if Analog Power Voltage Detector is enabled + * @rmtoll VMCR AVDEN LL_PWR_IsEnabledAVD + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledAVD(void) +{ + return ((READ_BIT(PWR->VMCR, PWR_VMCR_AVDEN) == (PWR_VMCR_AVDEN)) ? 1UL : 0UL); +} + +/** + * @brief Configure the voltage threshold to be detected by the Analog Power Voltage Detector + * @rmtoll VMCR ALS LL_PWR_SetAVDLevel + * @param AVDLevel This parameter can be one of the following values: + * @arg @ref LL_PWR_AVDLEVEL_0 + * @arg @ref LL_PWR_AVDLEVEL_1 + * @arg @ref LL_PWR_AVDLEVEL_2 + * @arg @ref LL_PWR_AVDLEVEL_3 + * @retval None + */ +__STATIC_INLINE void LL_PWR_SetAVDLevel(uint32_t AVDLevel) +{ + MODIFY_REG(PWR->VMCR, PWR_VMCR_ALS, AVDLevel); +} + +/** + * @brief Get the Analog Voltage threshold to be detected by the Analog Power Voltage Detector + * @rmtoll CR1 ALS LL_PWR_GetAVDLevel + * @retval Returned value can be one of the following values: + * @arg @ref LL_PWR_AVDLEVEL_0 + * @arg @ref LL_PWR_AVDLEVEL_1 + * @arg @ref LL_PWR_AVDLEVEL_2 + * @arg @ref LL_PWR_AVDLEVEL_3 + */ +__STATIC_INLINE uint32_t LL_PWR_GetAVDLevel(void) +{ + return (uint32_t)(READ_BIT(PWR->VMCR, PWR_VMCR_ALS)); +} + +#if defined (PWR_USBSCR_USB33DEN) +/** + * @brief Enable the USB voltage detector + * @rmtoll USBSCR USB33DEN LL_PWR_EnableUSBVoltageDetector + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableUSBVoltageDetector(void) +{ + SET_BIT(PWR->USBSCR, PWR_USBSCR_USB33DEN); +} + +/** + * @brief Disable the USB voltage detector + * @rmtoll USBSCR USB33DEN LL_PWR_DisableUSBVoltageDetector + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableUSBVoltageDetector(void) +{ + CLEAR_BIT(PWR->USBSCR, PWR_USBSCR_USB33DEN); +} + +/** + * @brief Check if the USB voltage detector is enabled + * @rmtoll USBSCR USB33DEN LL_PWR_IsEnabledUSBVoltageDetector + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledUSBVoltageDetector(void) +{ + return ((READ_BIT(PWR->USBSCR, PWR_USBSCR_USB33DEN) == (PWR_USBSCR_USB33DEN)) ? 1UL : 0UL); +} + +/** + * @brief Enable the independent USB supply. + * @rmtoll USBSCR USB33SV LL_PWR_EnableVDDUSB + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableVDDUSB(void) +{ + SET_BIT(PWR->USBSCR, PWR_USBSCR_USB33SV); +} + +/** + * @brief Disable the independent USB supply. + * @rmtoll USBSCR USB33SV LL_PWR_DisableVDDUSB + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableVDDUSB(void) +{ + CLEAR_BIT(PWR->USBSCR, PWR_USBSCR_USB33SV); +} + +/** + * @brief Check if the independent USB supply is enabled. + * @rmtoll USBSCR USB33SV LL_PWR_IsEnabledVDDUSB + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledVDDUSB(void) +{ + return ((READ_BIT(PWR->USBSCR, PWR_USBSCR_USB33SV) == (PWR_USBSCR_USB33SV)) ? 1UL : 0UL); +} +#endif /* PWR_USBSCR_USB33DEN */ + +/** + * @brief Enable the wake up pin_x. + * @rmtoll WUCR WUPENx LL_PWR_EnableWakeUpPin + * @param WakeUpPin This parameter can be a combination of the following values: + * @arg @ref LL_PWR_WAKEUP_PIN1 + * @arg @ref LL_PWR_WAKEUP_PIN2 + * @arg @ref LL_PWR_WAKEUP_PIN3 + * @arg @ref LL_PWR_WAKEUP_PIN4 + * @arg @ref LL_PWR_WAKEUP_PIN5 + * @arg @ref LL_PWR_WAKEUP_PIN6 + * @arg @ref LL_PWR_WAKEUP_PIN7 + * @arg @ref LL_PWR_WAKEUP_PIN8 + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableWakeUpPin(uint32_t WakeUpPin) +{ + SET_BIT(PWR->WUCR, WakeUpPin); +} + +/** + * @brief Disable the wake up pin_x. + * @rmtoll WUCR WUPENx LL_PWR_DisableWakeUpPin + * @param WakeUpPin This parameter can be a combination of the following values: + * @arg @ref LL_PWR_WAKEUP_PIN1 + * @arg @ref LL_PWR_WAKEUP_PIN2 + * @arg @ref LL_PWR_WAKEUP_PIN3 + * @arg @ref LL_PWR_WAKEUP_PIN4 + * @arg @ref LL_PWR_WAKEUP_PIN5 + * @arg @ref LL_PWR_WAKEUP_PIN6 + * @arg @ref LL_PWR_WAKEUP_PIN7 + * @arg @ref LL_PWR_WAKEUP_PIN8 + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableWakeUpPin(uint32_t WakeUpPin) +{ + CLEAR_BIT(PWR->WUCR, WakeUpPin); +} + +/** + * @brief Check if the wake up pin_x is enabled. + * @rmtoll WUCR WUPPx LL_PWR_IsEnabledWakeUpPin + * @param WakeUpPin This parameter can be one of the following values: + * @arg @ref LL_PWR_WAKEUP_PIN1 + * @arg @ref LL_PWR_WAKEUP_PIN2 + * @arg @ref LL_PWR_WAKEUP_PIN3 + * @arg @ref LL_PWR_WAKEUP_PIN4 + * @arg @ref LL_PWR_WAKEUP_PIN5 + * @arg @ref LL_PWR_WAKEUP_PIN6 + * @arg @ref LL_PWR_WAKEUP_PIN7 + * @arg @ref LL_PWR_WAKEUP_PIN8 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledWakeUpPin(uint32_t WakeUpPin) +{ + return ((READ_BIT(PWR->WUCR, WakeUpPin) == (WakeUpPin)) ? 1UL : 0UL); +} + +/** + * @brief Set the Wake-Up pin polarity low for the event detection + * @rmtoll WUCR WKUPP1 LL_PWR_SetWakeUpPinPolarityLow\n + * WUCR WKUPP2 LL_PWR_SetWakeUpPinPolarityLow\n + * WUCR WKUPP3 LL_PWR_SetWakeUpPinPolarityLow\n + * WUCR WKUPP4 LL_PWR_SetWakeUpPinPolarityLow\n + * WUCR WKUPP5 LL_PWR_SetWakeUpPinPolarityLow\n + * WUCR WKUPP6 LL_PWR_SetWakeUpPinPolarityLow\n + * WUCR WKUPP7 LL_PWR_SetWakeUpPinPolarityLow\n + * WUCR WKUPP8 LL_PWR_SetWakeUpPinPolarityLow + * @param WakeUpPin This parameter can be one of the following values: + * @arg @ref LL_PWR_WAKEUP_PIN1 + * @arg @ref LL_PWR_WAKEUP_PIN2 + * @arg @ref LL_PWR_WAKEUP_PIN3 + * @arg @ref LL_PWR_WAKEUP_PIN4 + * @arg @ref LL_PWR_WAKEUP_PIN5 + * @arg @ref LL_PWR_WAKEUP_PIN6 + * @arg @ref LL_PWR_WAKEUP_PIN7 + * @arg @ref LL_PWR_WAKEUP_PIN8 + * @retval None + */ +__STATIC_INLINE void LL_PWR_SetWakeUpPinPolarityLow(uint32_t WakeUpPin) +{ + SET_BIT(PWR->WUCR, (WakeUpPin << PWR_WUCR_WUPP1_Pos)); +} + +/** + * @brief Set the Wake-Up pin polarity high for the event detection + * @rmtoll WUCR WKUPP1 LL_PWR_SetWakeUpPinPolarityHigh\n + * WUCR WKUPP2 LL_PWR_SetWakeUpPinPolarityHigh\n + * WUCR WKUPP3 LL_PWR_SetWakeUpPinPolarityHigh\n + * WUCR WKUPP4 LL_PWR_SetWakeUpPinPolarityHigh\n + * WUCR WKUPP5 LL_PWR_SetWakeUpPinPolarityHigh\n + * WUCR WKUPP6 LL_PWR_SetWakeUpPinPolarityHigh\n + * WUCR WKUPP7 LL_PWR_SetWakeUpPinPolarityHigh\n + * WUCR WKUPP8 LL_PWR_SetWakeUpPinPolarityHigh + * @param WakeUpPin This parameter can be one of the following values: + * @arg @ref LL_PWR_WAKEUP_PIN1 + * @arg @ref LL_PWR_WAKEUP_PIN2 + * @arg @ref LL_PWR_WAKEUP_PIN3 + * @arg @ref LL_PWR_WAKEUP_PIN4 + * @arg @ref LL_PWR_WAKEUP_PIN5 + * @arg @ref LL_PWR_WAKEUP_PIN6 + * @arg @ref LL_PWR_WAKEUP_PIN7 + * @arg @ref LL_PWR_WAKEUP_PIN8 + * @retval None + */ +__STATIC_INLINE void LL_PWR_SetWakeUpPinPolarityHigh(uint32_t WakeUpPin) +{ + CLEAR_BIT(PWR->WUCR, (WakeUpPin << PWR_WUCR_WUPP1_Pos)); +} + +/** + * @brief Get the Wake-Up pin polarity for the event detection + * @rmtoll WUCR WUPP1 LL_PWR_SetWakeUpPinPolarityLow\n + * WUCR WUPP2 LL_PWR_SetWakeUpPinPolarityLow\n + * WUCR WUPP3 LL_PWR_SetWakeUpPinPolarityLow\n + * WUCR WUPP4 LL_PWR_SetWakeUpPinPolarityLow\n + * WUCR WUPP5 LL_PWR_SetWakeUpPinPolarityLow\n + * WUCR WUPP6 LL_PWR_SetWakeUpPinPolarityLow\n + * WUCR WUPP7 LL_PWR_SetWakeUpPinPolarityLow\n + * WUCR WUPP8 LL_PWR_SetWakeUpPinPolarityLow + * @param WakeUpPin This parameter can be one of the following values: + * @arg @ref LL_PWR_WAKEUP_PIN1 + * @arg @ref LL_PWR_WAKEUP_PIN2 + * @arg @ref LL_PWR_WAKEUP_PIN3 + * @arg @ref LL_PWR_WAKEUP_PIN4 + * @arg @ref LL_PWR_WAKEUP_PIN5 + * @arg @ref LL_PWR_WAKEUP_PIN6 + * @arg @ref LL_PWR_WAKEUP_PIN7 + * @arg @ref LL_PWR_WAKEUP_PIN8 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsWakeUpPinPolarityLow(uint32_t WakeUpPin) +{ + return ((READ_BIT(PWR->WUCR, (WakeUpPin << PWR_WUCR_WUPP1_Pos)) == (WakeUpPin << PWR_WUCR_WUPP1_Pos)) ? 1UL : 0UL); +} + +/** + * @brief Set the Wake-Up pin Pull None + * @rmtoll WUCR WUPPUPD1 LL_PWR_SetWakeUpPinPullNone\n + * WUCR WUPPUPD2 LL_PWR_SetWakeUpPinPullNone\n + * WUCR WUPPUPD3 LL_PWR_SetWakeUpPinPullNone\n + * WUCR WUPPUPD4 LL_PWR_SetWakeUpPinPullNone\n + * WUCR WUPPUPD5 LL_PWR_SetWakeUpPinPullNone\n + * WUCR WUPPUPD6 LL_PWR_SetWakeUpPinPullNone\n + * WUCR WUPPUPD7 LL_PWR_SetWakeUpPinPullNone\n + * WUCR WUPPUPD8 LL_PWR_SetWakeUpPinPullNone + * @param WakeUpPin This parameter can be one of the following values: + * @arg @ref LL_PWR_WAKEUP_PIN1 + * @arg @ref LL_PWR_WAKEUP_PIN2 + * @arg @ref LL_PWR_WAKEUP_PIN3 + * @arg @ref LL_PWR_WAKEUP_PIN4 + * @arg @ref LL_PWR_WAKEUP_PIN5 + * @arg @ref LL_PWR_WAKEUP_PIN6 + * @arg @ref LL_PWR_WAKEUP_PIN7 + * @arg @ref LL_PWR_WAKEUP_PIN8 + * + * @retval None + */ +__STATIC_INLINE void LL_PWR_SetWakeUpPinPullNone(uint32_t WakeUpPin) +{ + MODIFY_REG(PWR->WUCR, + (PWR_WUCR_WUPPUPD1 << ((LL_PWR_WAKEUP_PINS_PULL_SHIFT_OFFSET * (POSITION_VAL(WakeUpPin) & 0xFU)) & \ + LL_PWR_WAKEUP_PINS_MAX_SHIFT_MASK)), + (LL_PWR_WAKEUP_PIN_NOPULL << ((PWR_WUCR_WUPPUPD1_Pos + ((LL_PWR_WAKEUP_PINS_PULL_SHIFT_OFFSET * \ + POSITION_VAL(WakeUpPin)) & 0xFU)) & \ + LL_PWR_WAKEUP_PINS_MAX_SHIFT_MASK))); +} + +/** + * @brief Set the Wake-Up pin Pull Up + * @rmtoll WUCR WUPPUPD1 LL_PWR_SetWakeUpPinPullUp\n + * WUCR WUPPUPD2 LL_PWR_SetWakeUpPinPullUp\n + * WUCR WUPPUPD3 LL_PWR_SetWakeUpPinPullUp\n + * WUCR WUPPUPD4 LL_PWR_SetWakeUpPinPullUp\n + * WUCR WUPPUPD5 LL_PWR_SetWakeUpPinPullUp\n + * WUCR WUPPUPD6 LL_PWR_SetWakeUpPinPullUp\n + * WUCR WUPPUPD7 LL_PWR_SetWakeUpPinPullUp\n + * WUCR WUPPUPD8 LL_PWR_SetWakeUpPinPullUp + * @param WakeUpPin This parameter can be one of the following values: + * @arg @ref LL_PWR_WAKEUP_PIN1 + * @arg @ref LL_PWR_WAKEUP_PIN2 + * @arg @ref LL_PWR_WAKEUP_PIN3 + * @arg @ref LL_PWR_WAKEUP_PIN4 + * @arg @ref LL_PWR_WAKEUP_PIN5 + * @arg @ref LL_PWR_WAKEUP_PIN6 + * @arg @ref LL_PWR_WAKEUP_PIN7 + * @arg @ref LL_PWR_WAKEUP_PIN8 + * + * + * @retval None + */ +__STATIC_INLINE void LL_PWR_SetWakeUpPinPullUp(uint32_t WakeUpPin) +{ + MODIFY_REG(PWR->WUCR, + (PWR_WUCR_WUPPUPD1 << ((LL_PWR_WAKEUP_PINS_PULL_SHIFT_OFFSET * (POSITION_VAL(WakeUpPin) & 0xFU)) & \ + LL_PWR_WAKEUP_PINS_MAX_SHIFT_MASK)), + (LL_PWR_WAKEUP_PIN_PULLUP << ((PWR_WUCR_WUPPUPD1_Pos + ((LL_PWR_WAKEUP_PINS_PULL_SHIFT_OFFSET * \ + POSITION_VAL(WakeUpPin)) & 0xFU)) & \ + LL_PWR_WAKEUP_PINS_MAX_SHIFT_MASK))); +} + +/** + * @brief Set the Wake-Up pin Pull Down + * @rmtoll WUCR WUPPUPD1 LL_PWR_SetWakeUpPinPullDown\n + * WUCR WUPPUPD2 LL_PWR_SetWakeUpPinPullDown\n + * WUCR WUPPUPD3 LL_PWR_SetWakeUpPinPullDown\n + * WUCR WUPPUPD4 LL_PWR_SetWakeUpPinPullDown\n + * WUCR WUPPUPD5 LL_PWR_SetWakeUpPinPullDown\n + * WUCR WUPPUPD6 LL_PWR_SetWakeUpPinPullDown\n + * WUCR WUPPUPD7 LL_PWR_SetWakeUpPinPullDown\n + * WUCR WUPPUPD8 LL_PWR_SetWakeUpPinPullDown + * @param WakeUpPin This parameter can be one of the following values: + * @arg @ref LL_PWR_WAKEUP_PIN1 + * @arg @ref LL_PWR_WAKEUP_PIN2 + * @arg @ref LL_PWR_WAKEUP_PIN3 + * @arg @ref LL_PWR_WAKEUP_PIN4 + * @arg @ref LL_PWR_WAKEUP_PIN5 + * @arg @ref LL_PWR_WAKEUP_PIN6 + * @arg @ref LL_PWR_WAKEUP_PIN7 + * @arg @ref LL_PWR_WAKEUP_PIN8 + * + * @retval None + */ +__STATIC_INLINE void LL_PWR_SetWakeUpPinPullDown(uint32_t WakeUpPin) +{ + MODIFY_REG(PWR->WUCR, + (PWR_WUCR_WUPPUPD1 << ((LL_PWR_WAKEUP_PINS_PULL_SHIFT_OFFSET * (POSITION_VAL(WakeUpPin) & 0xFU)) & \ + LL_PWR_WAKEUP_PINS_MAX_SHIFT_MASK)), + (LL_PWR_WAKEUP_PIN_PULLDOWN << ((PWR_WUCR_WUPPUPD1_Pos + ((LL_PWR_WAKEUP_PINS_PULL_SHIFT_OFFSET * \ + POSITION_VAL(WakeUpPin)) & 0xFU)) & \ + LL_PWR_WAKEUP_PINS_MAX_SHIFT_MASK))); +} + +/** + * @brief Get the Wake-Up pin pull + * @rmtoll WUCR WUPPUPD1 LL_PWR_GetWakeUpPinPull\n + * WUCR WUPPUPD2 LL_PWR_GetWakeUpPinPull\n + * WUCR WUPPUPD3 LL_PWR_GetWakeUpPinPull\n + * WUCR WUPPUPD4 LL_PWR_GetWakeUpPinPull\n + * WUCR WUPPUPD5 LL_PWR_GetWakeUpPinPull\n + * WUCR WUPPUPD7 LL_PWR_GetWakeUpPinPull\n + * WUCR WUPPUPD7 LL_PWR_GetWakeUpPinPull\n + * WUCR WUPPUPD8 LL_PWR_GetWakeUpPinPull + * @param WakeUpPin This parameter can be one of the following values: + * @arg @ref LL_PWR_WAKEUP_PIN1 + * @arg @ref LL_PWR_WAKEUP_PIN2 + * @arg @ref LL_PWR_WAKEUP_PIN3 + * @arg @ref LL_PWR_WAKEUP_PIN4 + * @arg @ref LL_PWR_WAKEUP_PIN5 + * @arg @ref LL_PWR_WAKEUP_PIN6 + * @arg @ref LL_PWR_WAKEUP_PIN7 + * @arg @ref LL_PWR_WAKEUP_PIN8 + * + * @retval Returned value can be one of the following values: + * @arg @ref LL_PWR_WAKEUP_PIN_NOPULL + * @arg @ref LL_PWR_WAKEUP_PIN_PULLUP + * @arg @ref LL_PWR_WAKEUP_PIN_PULLDOWN + */ +__STATIC_INLINE uint32_t LL_PWR_GetWakeUpPinPull(uint32_t WakeUpPin) +{ + uint32_t regValue = READ_BIT(PWR->WUCR, (PWR_WUCR_WUPPUPD1 << ((LL_PWR_WAKEUP_PINS_PULL_SHIFT_OFFSET * \ + (POSITION_VAL(WakeUpPin) & 0xFU)) & \ + LL_PWR_WAKEUP_PINS_MAX_SHIFT_MASK))); + + return (uint32_t)(regValue >> ((PWR_WUCR_WUPPUPD1_Pos + ((LL_PWR_WAKEUP_PINS_PULL_SHIFT_OFFSET * \ + POSITION_VAL(WakeUpPin)) & 0xFU)) & \ + LL_PWR_WAKEUP_PINS_MAX_SHIFT_MASK)); +} + +/** + * @brief Enable IO Retention + * @rmtoll IORETR IORETEN LL_PWR_EnableIORetention + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableIORetention(void) +{ + SET_BIT(PWR->IORETR, PWR_IORETR_IORETEN); +} + +/** + * @brief Disable IO Retention + * @rmtoll IORETR IORETEN LL_PWR_DisableIORetention + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableIORetention(void) +{ + CLEAR_BIT(PWR->IORETR, PWR_IORETR_IORETEN); +} + +/** + * @brief Check if IO Retention is enabled + * @rmtoll IORETR IORETEN LL_PWR_IsEnabledIORetention + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledIORetention(void) +{ + return ((READ_BIT(PWR->IORETR, PWR_IORETR_IORETEN) == (PWR_IORETR_IORETEN)) ? 1UL : 0UL); +} + +/** + * @brief Enable JTAGIO Retention + * @rmtoll JTAGIORETR JTAGIORETEN LL_PWR_EnableJTAGIORetention + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableJTAGIORetention(void) +{ + SET_BIT(PWR->IORETR, PWR_IORETR_JTAGIORETEN); +} + +/** + * @brief Disable JTAGIO Retention + * @rmtoll JTAGIORETR JTAGIORETEN LL_PWR_DisableJTAGIORetention + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableJTAGIORetention(void) +{ + CLEAR_BIT(PWR->IORETR, PWR_IORETR_JTAGIORETEN); +} + +/** + * @brief Check if JTAGIO Retention is enabled + * @rmtoll IORETR JTAGIORETEN LL_PWR_IsEnabledJTAGIORetention + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledJTAGIORetention(void) +{ + return ((READ_BIT(PWR->IORETR, PWR_IORETR_JTAGIORETEN) == (PWR_IORETR_JTAGIORETEN)) ? 1UL : 0UL); +} +/** + * @} + */ + +/** @defgroup PWR_LL_EF_FLAG_MANAGEMENT PWR FLAG Management + * @{ + */ + +/** + * @brief Indicate whether the regulator voltage output is above voltage + * scaling range or not. + * @rmtoll VOSSR VOSRDY LL_PWR_IsActiveFlag_VOS + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_VOS(void) +{ + return ((READ_BIT(PWR->VOSSR, PWR_VOSSR_VOSRDY) == (PWR_VOSSR_VOSRDY)) ? 1UL : 0UL); +} + +/** + * @brief Indicate whether the system was in standby mode or not. + * @rmtoll PMSR SBF LL_PWR_IsActiveFlag_SB + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_SB(void) +{ + return ((READ_BIT(PWR->PMSR, PWR_PMSR_SBF) == (PWR_PMSR_SBF)) ? 1UL : 0UL); +} + +/** + * @brief Indicate whether the system was in stop mode or not. + * @rmtoll PMSR STOPF LL_PWR_IsActiveFlag_STOP + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_STOP(void) +{ + return ((READ_BIT(PWR->PMSR, PWR_PMSR_STOPF) == (PWR_PMSR_STOPF)) ? 1UL : 0UL); +} + +/** + * @brief Indicate whether the VDD voltage is below the threshold or not. + * @rmtoll VMSR PVDO LL_PWR_IsActiveFlag_PVDO + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_PVDO(void) +{ + return ((READ_BIT(PWR->VMSR, PWR_VMSR_PVDO) == (PWR_VMSR_PVDO)) ? 1UL : 0UL); +} + +/** + * @brief Indicate whether the VDD voltage is below the threshold or not. + * @rmtoll VMSR AVDO LL_PWR_IsActiveFlag_AVDO + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_AVDO(void) +{ + return ((READ_BIT(PWR->VMSR, PWR_VMSR_PVDO) == (PWR_VMSR_AVDO)) ? 1UL : 0UL); +} + +/** + * @brief Indicate whether the regulator voltage output is equal to current + * used voltage scaling range or not. + * @rmtoll VOSSR ACTVOSRDY LL_PWR_IsActiveFlag_ACTVOS + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_ACTVOS(void) +{ + return ((READ_BIT(PWR->VOSSR, PWR_VOSSR_ACTVOSRDY) == (PWR_VOSSR_ACTVOSRDY)) ? 1UL : 0UL); +} + +#if defined (PWR_VMSR_USB33RDY) +/** + * @brief Indicate whether the VDDUSB is below the threshold of monitor or not. + * @rmtoll VMSR USB33RDY LL_PWR_IsActiveFlag_VDDUSB + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_VDDUSB(void) +{ + return ((READ_BIT(PWR->VMSR, PWR_VMSR_USB33RDY) == (PWR_VMSR_USB33RDY)) ? 1UL : 0UL); +} +#endif /* PWR_VMSR_USB33RDY */ + +/** + * @brief Indicate whether VDDMMC voltage is below 1V2 + * @rmtoll VMSR VDDIO2RDY LL_PWR_IsActiveFlag_VDDIO2 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_VDDIO2(void) +{ + return ((READ_BIT(PWR->VMCR, PWR_VMSR_VDDIO2RDY) == (PWR_VMSR_VDDIO2RDY)) ? 1UL : 0UL); +} + +/** + * @brief Get Backup Regulator ready Flag + * @rmtoll BDSR BRRDY LL_PWR_IsActiveFlag_BRR + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_BRR(void) +{ + return ((READ_BIT(PWR->BDSR, PWR_BDSR_BRRDY) == (PWR_BDSR_BRRDY)) ? 1UL : 0UL); +} + +/** + * @brief Indicate whether the VBAT level is below high threshold or not. + * @rmtoll BDSR VBATL LL_PWR_IsActiveFlag_VBATL + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_VBATL(void) +{ + return ((READ_BIT(PWR->BDSR, PWR_BDSR_VBATL) == (PWR_BDSR_VBATL)) ? 1UL : 0UL); +} + +/** + * @brief Indicate whether the VBAT level is below high threshold or not. + * @rmtoll BDSR VBATH LL_PWR_IsActiveFlag_VBATH + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_VBATH(void) +{ + return ((READ_BIT(PWR->BDSR, PWR_BDSR_VBATH) == (PWR_BDSR_VBATH)) ? 1UL : 0UL); +} + +/** + * @brief Indicate whether the CPU temperature level is above low threshold or + * not. + * @rmtoll BDSR TEMPL LL_PWR_IsActiveFlag_TEMPL + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_TEMPL(void) +{ + return ((READ_BIT(PWR->BDSR, PWR_BDSR_TEMPL) == (PWR_BDSR_TEMPL)) ? 1UL : 0UL); +} + +/** + * @brief Indicate whether the CPU temperature level is below high threshold + * or not. + * @rmtoll BDSR TEMPH LL_PWR_IsActiveFlag_TEMPH + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_TEMPH(void) +{ + return ((READ_BIT(PWR->BDSR, PWR_BDSR_TEMPH) == (PWR_BDSR_TEMPH)) ? 1UL : 0UL); +} + +/** + * @brief Indicate whether a wakeup event is detected on wake up pin 1. + * @rmtoll WUSR WUF1 LL_PWR_IsActiveFlag_WU1 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_WU1(void) +{ + return ((READ_BIT(PWR->WUSR, PWR_WUSR_WUF1) == (PWR_WUSR_WUF1)) ? 1UL : 0UL); +} + +/** + * @brief Indicate whether a wakeup event is detected on wake up pin 2. + * @rmtoll WUSR WUF2 LL_PWR_IsActiveFlag_WU2 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_WU2(void) +{ + return ((READ_BIT(PWR->WUSR, PWR_WUSR_WUF2) == (PWR_WUSR_WUF2)) ? 1UL : 0UL); +} + +/** + * @brief Indicate whether a wakeup event is detected on wake up pin 3. + * @rmtoll WUSR WUF3 LL_PWR_IsActiveFlag_WU3 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_WU3(void) +{ + return ((READ_BIT(PWR->WUSR, PWR_WUSR_WUF3) == (PWR_WUSR_WUF3)) ? 1UL : 0UL); +} + +/** + * @brief Indicate whether a wakeup event is detected on wake up pin 4. + * @rmtoll WUSR WUF4 LL_PWR_IsActiveFlag_WU4 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_WU4(void) +{ + return ((READ_BIT(PWR->WUSR, PWR_WUSR_WUF4) == (PWR_WUSR_WUF4)) ? 1UL : 0UL); +} + +/** + * @brief Indicate whether a wakeup event is detected on wake up pin 5. + * @rmtoll WUSR WUF5 LL_PWR_IsActiveFlag_WU5 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_WU5(void) +{ + return ((READ_BIT(PWR->WUSR, PWR_WUSR_WUF5) == (PWR_WUSR_WUF5)) ? 1UL : 0UL); +} + +#if defined (PWR_WUSR_WUF6) +/** + * @brief Indicate whether a wakeup event is detected on wake up pin 6. + * @rmtoll WUSR WUF6 LL_PWR_IsActiveFlag_WU6 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_WU6(void) +{ + return ((READ_BIT(PWR->WUSR, PWR_WUSR_WUF6) == (PWR_WUSR_WUF6)) ? 1UL : 0UL); +} +#endif /* PWR_WUSR_WUF6 */ + +#if defined (PWR_WUSR_WUF7) +/** + * @brief Indicate whether a wakeup event is detected on wake up pin 7. + * @rmtoll WUSR WUF7 LL_PWR_IsActiveFlag_WU7 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_WU7(void) +{ + return ((READ_BIT(PWR->WUSR, PWR_WUSR_WUF7) == (PWR_WUSR_WUF7)) ? 1UL : 0UL); +} +#endif /* PWR_WUSR_WUF7 */ + +#if defined (PWR_WUSR_WUF8) +/** + * @brief Indicate whether a wakeup event is detected on wake up pin 8. + * @rmtoll WUSR WUF8 LL_PWR_IsActiveFlag_WU8 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_WU8(void) +{ + return ((READ_BIT(PWR->WUSR, PWR_WUSR_WUF8) == (PWR_WUSR_WUF8)) ? 1UL : 0UL); +} +#endif /* PWR_WUSR_WUF8 */ + +/** + * @brief Clear stop flag. + * @rmtoll PMCR CSSF LL_PWR_ClearFlag_STOP + * @retval None + */ +__STATIC_INLINE void LL_PWR_ClearFlag_STOP(void) +{ + WRITE_REG(PWR->PMCR, PWR_PMCR_CSSF); +} + +/** + * @brief Clear standby flag. + * @rmtoll PMCR CSSF LL_PWR_ClearFlag_SB + * @retval None + */ +__STATIC_INLINE void LL_PWR_ClearFlag_SB(void) +{ + WRITE_REG(PWR->PMCR, PWR_PMCR_CSSF); +} + +/** + * @brief Clear wake up flag 1. + * @rmtoll WUSCR CWUF1 LL_PWR_ClearFlag_WU1 + * @retval None + */ +__STATIC_INLINE void LL_PWR_ClearFlag_WU1(void) +{ + WRITE_REG(PWR->WUSCR, PWR_WUSCR_CWUF1); +} + +/** + * @brief Clear wake up flag 2. + * @rmtoll WUSCR CWUF2 LL_PWR_ClearFlag_WU2 + * @retval None + */ +__STATIC_INLINE void LL_PWR_ClearFlag_WU2(void) +{ + WRITE_REG(PWR->WUSCR, PWR_WUSCR_CWUF2); +} + +/** + * @brief Clear wake up flag 3. + * @rmtoll WUSCR CWUF3 LL_PWR_ClearFlag_WU3 + * @retval None + */ +__STATIC_INLINE void LL_PWR_ClearFlag_WU3(void) +{ + WRITE_REG(PWR->WUSCR, PWR_WUSCR_CWUF3); +} + +/** + * @brief Clear wake up flag 4. + * @rmtoll WUSCR CWUF4 LL_PWR_ClearFlag_WU4 + * @retval None + */ +__STATIC_INLINE void LL_PWR_ClearFlag_WU4(void) +{ + WRITE_REG(PWR->WUSCR, PWR_WUSCR_CWUF4); +} + +/** + * @brief Clear wake up flag 5. + * @rmtoll WUSCR CWUF5 LL_PWR_ClearFlag_WU5 + * @retval None + */ +__STATIC_INLINE void LL_PWR_ClearFlag_WU5(void) +{ + WRITE_REG(PWR->WUSCR, PWR_WUSCR_CWUF5); +} + +#if defined (PWR_WUSCR_CWUF6) +/** + * @brief Clear wake up flag 6. + * @rmtoll WUSCR CWUF6 LL_PWR_ClearFlag_WU6 + * @retval None + */ +__STATIC_INLINE void LL_PWR_ClearFlag_WU6(void) +{ + WRITE_REG(PWR->WUSCR, PWR_WUSCR_CWUF6); +} +#endif /* PWR_WUSCR_CWUF6 */ + +#if defined (PWR_WUSCR_CWUF7) +/** + * @brief Clear wake up flag 7. + * @rmtoll WUSCR CWUF7 LL_PWR_ClearFlag_WU7 + * @retval None + */ +__STATIC_INLINE void LL_PWR_ClearFlag_WU7(void) +{ + WRITE_REG(PWR->WUSCR, PWR_WUSCR_CWUF7); +} +#endif /* PWR_WUSCR_CWUF7 */ + +#if defined (PWR_WUSCR_CWUF8) +/** + * @brief Clear wake up flag 8. + * @rmtoll WUSCR CWUF8 LL_PWR_ClearFlag_WU8 + * @retval None + */ +__STATIC_INLINE void LL_PWR_ClearFlag_WU8(void) +{ + WRITE_REG(PWR->WUSCR, PWR_WUSCR_CWUF8); +} +#endif /* PWR_WUSCR_CWUF8 */ + +/** + * @brief Clear all wake up flags. + * @rmtoll WUSCR CWUF LL_PWR_ClearFlag_WU + * @retval None + */ +__STATIC_INLINE void LL_PWR_ClearFlag_WU(void) +{ + WRITE_REG(PWR->WUSCR, PWR_WUSCR_CWUF); +} +/** + * @} + */ + +/** @defgroup PWR_LL_EF_ATTRIBUTE_MANAGEMENT PWR Attribute Management + * @{ + */ + +#if defined(PWR_PRIVCFGR_NSPRIV) +/** + * @brief Enable privileged mode for nsecure items. + * @rmtoll PRIVCFGR NSPRIV LL_PWR_EnableNSecurePrivilege + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableNSecurePrivilege(void) +{ + SET_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_NSPRIV); +} + +/** + * @brief Disable privileged mode for nsecure items. + * @rmtoll PRIVCFGR NSPRIV LL_PWR_DisableNSecurePrivilege + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableNSecurePrivilege(void) +{ + CLEAR_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_NSPRIV); +} + +/** + * @brief Check if privileged mode for nsecure items is enabled. + * @rmtoll PRIVCFGR NSPRIV LL_PWR_IsEnabledNSecurePrivilege + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledNSecurePrivilege(void) +{ + return ((READ_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_NSPRIV) == PWR_PRIVCFGR_NSPRIV) ? 1UL : 0UL); +} +#else +/** + * @brief Enable privileged mode for nsecure items. + * @rmtoll PRIVCFGR NSPRIV LL_PWR_EnableNSecurePrivilege + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableNSecurePrivilege(void) +{ + SET_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_PRIV); +} + +/** + * @brief Disable privileged mode for nsecure items. + * @rmtoll PRIVCFGR NSPRIV LL_PWR_DisableNSecurePrivilege + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableNSecurePrivilege(void) +{ + CLEAR_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_PRIV); +} + +/** + * @brief Check if privileged mode for nsecure items is enabled. + * @rmtoll PRIVCFGR NSPRIV LL_PWR_IsEnabledNSecurePrivilege + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledNSecurePrivilege(void) +{ + return ((READ_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_PRIV) == PWR_PRIVCFGR_PRIV) ? 1UL : 0UL); +} +#endif /* RCC_PRIVCFGR_NSPRIV */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Enable privileged mode for secure items. + * @rmtoll PRIVCFGR SPRIV LL_PWR_EnableSecurePrivilege + * @retval None + */ +__STATIC_INLINE void LL_PWR_EnableSecurePrivilege(void) +{ + SET_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_SPRIV); +} + +/** + * @brief Disable privileged mode for secure items. + * @rmtoll PRIVCFGR SPRIV LL_PWR_DisableSecurePrivilege + * @retval None + */ +__STATIC_INLINE void LL_PWR_DisableSecurePrivilege(void) +{ + CLEAR_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_SPRIV); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#if defined (PWR_PRIVCFGR_SPRIV) +/** + * @brief Check if privileged mode for secure items is enabled. + * @rmtoll PRIVCFGR SPRIV LL_PWR_IsEnabledSecurePrivilege + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_PWR_IsEnabledSecurePrivilege(void) +{ + return ((READ_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_SPRIV) == PWR_PRIVCFGR_SPRIV) ? 1UL : 0UL); +} +#endif /* PWR_PRIVCFGR_SPRIV */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Configure secure attribute mode. + * @note This API can be executed only by CPU in secure mode. + * @rmtoll SECCFGR WUP1SEC LL_PWR_ConfigSecure\n + * SECCFGR WUP2SEC LL_PWR_ConfigSecure\n + * SECCFGR WUP3SEC LL_PWR_ConfigSecure\n + * SECCFGR WUP4SEC LL_PWR_ConfigSecure\n + * SECCFGR WUP5SEC LL_PWR_ConfigSecure\n + * SECCFGR WUP6SEC LL_PWR_ConfigSecure\n + * SECCFGR WUP7SEC LL_PWR_ConfigSecure\n + * SECCFGR WUP8SEC LL_PWR_ConfigSecure\n + * SECCFGR RETSEC LL_PWR_ConfigSecure\n + * SECCFGR LPMSEC LL_PWR_ConfigSecure\n + * SECCFGR VDMSEC LL_PWR_ConfigSecure\n + * SECCFGR VBSEC LL_PWR_ConfigSecure\n + * SECCFGR APCSEC LL_PWR_ConfigSecure + * @param SecureConfig This parameter can be the full combination + * of the following values: + * @arg @ref LL_PWR_WAKEUP_PIN1_NSEC or LL_PWR_WAKEUP_PIN1_SEC + * @arg @ref LL_PWR_WAKEUP_PIN2_NSEC or LL_PWR_WAKEUP_PIN2_SEC + * @arg @ref LL_PWR_WAKEUP_PIN3_NSEC or LL_PWR_WAKEUP_PIN3_SEC + * @arg @ref LL_PWR_WAKEUP_PIN4_NSEC or LL_PWR_WAKEUP_PIN4_SEC + * @arg @ref LL_PWR_WAKEUP_PIN5_NSEC or LL_PWR_WAKEUP_PIN5_SEC + * @arg @ref LL_PWR_WAKEUP_PIN6_NSEC or LL_PWR_WAKEUP_PIN6_SEC + * @arg @ref LL_PWR_WAKEUP_PIN7_NSEC or LL_PWR_WAKEUP_PIN7_SEC + * @arg @ref LL_PWR_WAKEUP_PIN8_NSEC or LL_PWR_WAKEUP_PIN8_SEC + * @arg @ref LL_PWR_RET_NSEC or LL_PWR_RET_SEC + * @arg @ref LL_PWR_LPM_NSEC or LL_PWR_LPM_SEC + * @arg @ref LL_PWR_VDM_NSEC or LL_PWR_VDM_SEC + * @arg @ref LL_PWR_VB_NSEC or LL_PWR_VB_SEC + * @arg @ref LL_PWR_APC_NSEC or LL_PWR_APC_SEC + * @retval None. + */ +__STATIC_INLINE void LL_PWR_ConfigSecure(uint32_t SecureConfig) +{ + WRITE_REG(PWR->SECCFGR, SecureConfig); +} + +/** + * @brief Get secure attribute configuration. + * @note This API can be executed only by CPU in secure mode. + * @rmtoll SECCFGR WUP1SEC LL_PWR_GetConfigSecure\n + * SECCFGR WUP2SEC LL_PWR_GetConfigSecure\n + * SECCFGR WUP3SEC LL_PWR_GetConfigSecure\n + * SECCFGR WUP4SEC LL_PWR_GetConfigSecure\n + * SECCFGR WUP5SEC LL_PWR_GetConfigSecure\n + * SECCFGR WUP6SEC LL_PWR_GetConfigSecure\n + * SECCFGR WUP7SEC LL_PWR_GetConfigSecure\n + * SECCFGR WUP8SEC LL_PWR_GetConfigSecure\n + * SECCFGR RETSEC LL_PWR_ConfigSecure\n + * SECCFGR LPMSEC LL_PWR_GetConfigSecure\n + * SECCFGR VDMSEC LL_PWR_GetConfigSecure\n + * SECCFGR VBSEC LL_PWR_GetConfigSecure\n + * SECCFGR APCSEC LL_PWR_GetConfigSecure + * @retval Returned value is the combination of the following values: + * @arg @ref LL_PWR_WAKEUP_PIN1_NSEC or LL_PWR_WAKEUP_PIN1_SEC + * @arg @ref LL_PWR_WAKEUP_PIN2_NSEC or LL_PWR_WAKEUP_PIN2_SEC + * @arg @ref LL_PWR_WAKEUP_PIN3_NSEC or LL_PWR_WAKEUP_PIN3_SEC + * @arg @ref LL_PWR_WAKEUP_PIN4_NSEC or LL_PWR_WAKEUP_PIN4_SEC + * @arg @ref LL_PWR_WAKEUP_PIN5_NSEC or LL_PWR_WAKEUP_PIN5_SEC + * @arg @ref LL_PWR_WAKEUP_PIN6_NSEC or LL_PWR_WAKEUP_PIN6_SEC + * @arg @ref LL_PWR_WAKEUP_PIN7_NSEC or LL_PWR_WAKEUP_PIN7_SEC + * @arg @ref LL_PWR_WAKEUP_PIN8_NSEC or LL_PWR_WAKEUP_PIN8_SEC + * @arg @ref LL_PWR_RET_NSEC or LL_PWR_RET_SEC + * @arg @ref LL_PWR_LPM_NSEC or LL_PWR_LPM_SEC + * @arg @ref LL_PWR_VDM_NSEC or LL_PWR_VDM_SEC + * @arg @ref LL_PWR_VB_NSEC or LL_PWR_VB_SEC + * @arg @ref LL_PWR_APC_NSEC or LL_PWR_APC_SEC + */ +__STATIC_INLINE uint32_t LL_PWR_GetConfigSecure(void) +{ + return (READ_REG(PWR->SECCFGR)); +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/** + * @} + */ + +#if defined (USE_FULL_LL_DRIVER) +/** @defgroup PWR_LL_EF_Init De-initialization function + * @{ + */ +ErrorStatus LL_PWR_DeInit(void); +/** + * @} + */ +#endif /* defined (USE_FULL_LL_DRIVER) */ + + +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined (PWR) */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* STM32H5xx_LL_PWR_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_rcc.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_rcc.h new file mode 100644 index 0000000000..41eddf3880 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_rcc.h @@ -0,0 +1,6072 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_rcc.h + * @author MCD Application Team + * @brief Header file of RCC LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32H5xx_LL_RCC_H +#define __STM32H5xx_LL_RCC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined(RCC) + +/** @defgroup RCC_LL RCC + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup RCC_LL_Private_Constants RCC Private Constants + * @{ + */ +/* Defines used for security configuration extension */ +#define RCC_SECURE_MASK 0x3BFFU +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +#if !defined(UNUSED) +#define UNUSED(x) ((void)(x)) +#endif /* !UNUSED */ + +/* 32 24 16 8 0 + -------------------------------------------------------- + | Mask | ClkSource | Bit | Register | + | | Config | Position | Offset | + --------------------------------------------------------*/ + +/* Clock source register offset */ +#define CCIPR1_OFFSET 0x00UL +#define CCIPR2_OFFSET 0x04UL +#define CCIPR3_OFFSET 0x08UL +#define CCIPR4_OFFSET 0x0CUL +#define CCIPR5_OFFSET 0x10UL + +#define LL_RCC_REG_SHIFT 0U +#define LL_RCC_POS_SHIFT 8U +#define LL_RCC_CONFIG_SHIFT 16U +#define LL_RCC_MASK_SHIFT 24U + +#define LL_CLKSOURCE_SHIFT(__CLKSOURCE__) (((__CLKSOURCE__) >> LL_RCC_POS_SHIFT ) & 0x1FUL) + +#define LL_CLKSOURCE_MASK(__CLKSOURCE__) ((((__CLKSOURCE__) >> LL_RCC_MASK_SHIFT ) &\ + 0xFFUL) << LL_CLKSOURCE_SHIFT(__CLKSOURCE__)) + +#define LL_CLKSOURCE_CONFIG(__CLKSOURCE__) ((((__CLKSOURCE__) >> LL_RCC_CONFIG_SHIFT) &\ + 0xFFUL) << LL_CLKSOURCE_SHIFT(__CLKSOURCE__)) + +#define LL_CLKSOURCE_REG(__CLKSOURCE__) (((__CLKSOURCE__) >> LL_RCC_REG_SHIFT ) & 0xFFUL) + +#define LL_CLKSOURCE(__REG__, __MSK__, __POS__, __CLK__) ((uint32_t)((((__MSK__) >> (__POS__)) << LL_RCC_MASK_SHIFT) | \ + (( __POS__ ) << LL_RCC_POS_SHIFT) | \ + (( __REG__ ) << LL_RCC_REG_SHIFT) | \ + (((__CLK__) >> (__POS__)) << LL_RCC_CONFIG_SHIFT))) + +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup RCC_LL_Exported_Types RCC Exported Types + * @{ + */ + +/** @defgroup LL_ES_CLOCK_FREQ Clocks Frequency Structure + * @{ + */ + +/** + * @brief RCC Clocks Frequency Structure + */ +typedef struct +{ + uint32_t SYSCLK_Frequency; /*!< SYSCLK clock frequency */ + uint32_t HCLK_Frequency; /*!< HCLK clock frequency */ + uint32_t PCLK1_Frequency; /*!< PCLK1 clock frequency */ + uint32_t PCLK2_Frequency; /*!< PCLK2 clock frequency */ + uint32_t PCLK3_Frequency; /*!< PCLK3 clock frequency */ +} LL_RCC_ClocksTypeDef; + +/** + * @brief PLL Clocks Frequency Structure + */ +typedef struct +{ + uint32_t PLL_P_Frequency; + uint32_t PLL_Q_Frequency; + uint32_t PLL_R_Frequency; +} LL_PLL_ClocksTypeDef; + +/** + * @} + */ + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup RCC_LL_Exported_Constants RCC Exported Constants + * @{ + */ + +/** @defgroup RCC_LL_EC_OSC_VALUES Oscillator Values adaptation + * @brief Defines used to adapt values of different oscillators + * @note These values could be modified in the user environment according to + * HW set-up. + * @{ + */ +#if !defined (HSE_VALUE) +#define HSE_VALUE 25000000U /*!< Value of the HSE oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSI_VALUE) +#define HSI_VALUE 64000000U /*!< Value of the HSI oscillator in Hz */ +#endif /* HSI_VALUE */ + +#if !defined (CSI_VALUE) +#define CSI_VALUE 4000000U /*!< Value of the CSI oscillator in Hz */ +#endif /* CSI_VALUE */ + +#if !defined (LSE_VALUE) +#define LSE_VALUE 32768U /*!< Value of the LSE oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSI_VALUE) +#define LSI_VALUE 32000U /*!< Value of the LSI oscillator in Hz */ +#endif /* LSI_VALUE */ + +#if !defined (HSI48_VALUE) +#define HSI48_VALUE 48000000U /*!< Value of the HSI48 oscillator in Hz */ +#endif /* HSI48_VALUE */ + +#if !defined (EXTERNAL_CLOCK_VALUE) +#define EXTERNAL_CLOCK_VALUE 12288000U /*!< Value of the External clock in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/** + * @} + */ + +/** @defgroup RCC_LL_EC_HSIDIV HSI oscillator divider + * @{ + */ +#define LL_RCC_HSI_DIV_1 0x00000000U /*!< HSI_DIV1 clock activation */ +#define LL_RCC_HSI_DIV_2 RCC_CR_HSIDIV_0 /*!< HSI_DIV2 clock activation */ +#define LL_RCC_HSI_DIV_4 RCC_CR_HSIDIV_1 /*!< HSI_DIV4 clock activation */ +#define LL_RCC_HSI_DIV_8 RCC_CR_HSIDIV /*!< HSI_DIV8 clock activation */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_LSEDRIVE LSE oscillator drive capability + * @{ + */ +#define LL_RCC_LSEDRIVE_LOW 0x00000000U /*!< Xtal mode lower driving capability */ +#define LL_RCC_LSEDRIVE_MEDIUMLOW RCC_BDCR_LSEDRV_0 /*!< Xtal mode medium low driving capability */ +#define LL_RCC_LSEDRIVE_MEDIUMHIGH RCC_BDCR_LSEDRV_1 /*!< Xtal mode medium high driving capability */ +#define LL_RCC_LSEDRIVE_HIGH RCC_BDCR_LSEDRV /*!< Xtal mode higher driving capability */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_SYS_CLKSOURCE_STATUS System clock switch status + * @{ + */ +#define LL_RCC_SYS_CLKSOURCE_HSI 0x00000000U /*!< HSI oscillator selection as system clock */ +#define LL_RCC_SYS_CLKSOURCE_CSI RCC_CFGR1_SW_0 /*!< CSI oscillator selection as system clock */ +#define LL_RCC_SYS_CLKSOURCE_HSE RCC_CFGR1_SW_1 /*!< HSE oscillator selection as system clock */ +#define LL_RCC_SYS_CLKSOURCE_PLL1 (RCC_CFGR1_SW_1 | RCC_CFGR1_SW_0) /*!< PLL1 selection as system clock */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_SYS_CLKSOURCE_STATUS System clock switch status + * @{ + */ +#define LL_RCC_SYS_CLKSOURCE_STATUS_HSI 0x00000000U /*!< HSI oscillator used as system clock */ +#define LL_RCC_SYS_CLKSOURCE_STATUS_CSI RCC_CFGR1_SWS_0 /*!< CSI oscillator used as system clock */ +#define LL_RCC_SYS_CLKSOURCE_STATUS_HSE RCC_CFGR1_SWS_1 /*!< HSE oscillator used as system clock */ +#define LL_RCC_SYS_CLKSOURCE_STATUS_PLL1 (RCC_CFGR1_SWS_1 | RCC_CFGR1_SWS_0) /*!< PLL1 used as system clock */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_HSEEXT EXTERNAL HSE clock Type + * @{ + */ +#define LL_RCC_HSE_ANALOG_TYPE 0U /*!< ANALOG clock used as HSE external clock source */ +#define LL_RCC_HSE_DIGITAL_TYPE RCC_CR_HSEEXT /*!< DIGITAL clock used as HSE external clock source */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_LSEEXT EXTERNAL LSE clock Type + * @{ + */ +#define LL_RCC_LSE_ANALOG_TYPE 0U /*!< ANALOG clock used as LSE external clock source */ +#define LL_RCC_LSE_DIGITAL_TYPE RCC_BDCR_LSEEXT /*!< DIGITAL clock used as LSE external clock source */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_LSCO_CLKSOURCE LSCO Selection + * @{ + */ +#define LL_RCC_LSCO_CLKSOURCE_LSI 0x00000000U /*!< LSI selection for low speed clock */ +#define LL_RCC_LSCO_CLKSOURCE_LSE RCC_BDCR_LSCOSEL /*!< LSE selection for low speed clock */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_SYSCLK_DIV AHB prescaler + * @{ + */ +#define LL_RCC_SYSCLK_DIV_1 0x00000000U /*!< SYSCLK not divided */ +#define LL_RCC_SYSCLK_DIV_2 RCC_CFGR2_HPRE_3 /*!< SYSCLK divided by 2 */ +#define LL_RCC_SYSCLK_DIV_4 (RCC_CFGR2_HPRE_0 | RCC_CFGR2_HPRE_3) /*!< SYSCLK divided by 4 */ +#define LL_RCC_SYSCLK_DIV_8 (RCC_CFGR2_HPRE_1 | RCC_CFGR2_HPRE_3) /*!< SYSCLK divided by 8 */ +#define LL_RCC_SYSCLK_DIV_16 (RCC_CFGR2_HPRE_0 | RCC_CFGR2_HPRE_1 | RCC_CFGR2_HPRE_3) /*!< SYSCLK divided by 16 */ +#define LL_RCC_SYSCLK_DIV_64 (RCC_CFGR2_HPRE_2 | RCC_CFGR2_HPRE_3) /*!< SYSCLK divided by 64 */ +#define LL_RCC_SYSCLK_DIV_128 (RCC_CFGR2_HPRE_0 | RCC_CFGR2_HPRE_2 | RCC_CFGR2_HPRE_3) /*!< SYSCLK divided by 128 */ +#define LL_RCC_SYSCLK_DIV_256 (RCC_CFGR2_HPRE_1 | RCC_CFGR2_HPRE_2 | RCC_CFGR2_HPRE_3) /*!< SYSCLK divided by 256 */ +#define LL_RCC_SYSCLK_DIV_512 (RCC_CFGR2_HPRE_0 | RCC_CFGR2_HPRE_1 | RCC_CFGR2_HPRE_2 | RCC_CFGR2_HPRE_3) /*!< SYSCLK divided by 512 */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_APB1_DIV APB low-speed prescaler (APB1) + * @{ + */ +#define LL_RCC_APB1_DIV_1 (0x00000000U) /*!< HCLK not divided */ +#define LL_RCC_APB1_DIV_2 RCC_CFGR2_PPRE1_2 /*!< HCLK divided by 2 */ +#define LL_RCC_APB1_DIV_4 (RCC_CFGR2_PPRE1_0 | RCC_CFGR2_PPRE1_2) /*!< HCLK divided by 4 */ +#define LL_RCC_APB1_DIV_8 (RCC_CFGR2_PPRE1_1 | RCC_CFGR2_PPRE1_2) /*!< HCLK divided by 8 */ +#define LL_RCC_APB1_DIV_16 (RCC_CFGR2_PPRE1_0 | RCC_CFGR2_PPRE1_1 | RCC_CFGR2_PPRE1_2) /*!< HCLK divided by 16 */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_APB2_DIV APB high-speed prescaler (APB2) + * @{ + */ +#define LL_RCC_APB2_DIV_1 0x00000000U /*!< HCLK not divided */ +#define LL_RCC_APB2_DIV_2 RCC_CFGR2_PPRE2_2 /*!< HCLK divided by 2 */ +#define LL_RCC_APB2_DIV_4 (RCC_CFGR2_PPRE2_2 | RCC_CFGR2_PPRE2_0) /*!< HCLK divided by 4 */ +#define LL_RCC_APB2_DIV_8 (RCC_CFGR2_PPRE2_2 | RCC_CFGR2_PPRE2_1) /*!< HCLK divided by 8 */ +#define LL_RCC_APB2_DIV_16 (RCC_CFGR2_PPRE2_2 | RCC_CFGR2_PPRE2_1 | RCC_CFGR2_PPRE2_0) /*!< HCLK divided by 16 */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_APB3_DIV APB high-speed prescaler (APB3) + * @{ + */ +#define LL_RCC_APB3_DIV_1 0x00000000U /*!< HCLK not divided */ +#define LL_RCC_APB3_DIV_2 RCC_CFGR2_PPRE3_2 /*!< HCLK divided by 2 */ +#define LL_RCC_APB3_DIV_4 (RCC_CFGR2_PPRE3_2 | RCC_CFGR2_PPRE3_0) /*!< HCLK divided by 4 */ +#define LL_RCC_APB3_DIV_8 (RCC_CFGR2_PPRE3_2 | RCC_CFGR2_PPRE3_1) /*!< HCLK divided by 8 */ +#define LL_RCC_APB3_DIV_16 (RCC_CFGR2_PPRE3_2 | RCC_CFGR2_PPRE3_1 | RCC_CFGR2_PPRE3_0) /*!< HCLK divided by 16 */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_AHB1_PERIPH AHB1 peripherals clock branch disable + * @{ + */ +#define LL_RCC_AHB1_PERIPH_DIS RCC_CFGR2_AHB1DIS /*!< Clock Branch disable for all AHB1 peripherals */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_AHB2_PERIPH AHB2 peripherals clock branch disable + * @{ + */ +#define LL_RCC_AHB2_PERIPH_DIS RCC_CFGR2_AHB2DIS /*!< Clock Branch disable for all AHB2 peripherals */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_AHB4_PERIPH AHB4 peripherals clock branch disable + * @{ + */ +#define LL_RCC_AHB4_PERIPH_DIS RCC_CFGR2_AHB4DIS /*!< Clock Branch disable for all AHB4 peripherals */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_APB1_PERIPH APB1 peripherals clock branch disable + * @{ + */ +#define LL_RCC_APB1_PERIPH_DIS RCC_CFGR2_APB1DIS /*!< Clock Branch disable for all APB1 peripherals */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_APB2_PERIPH APB2 peripherals clock branch disable + * @{ + */ +#define LL_RCC_APB2_PERIPH_DIS RCC_CFGR2_APB2DIS /*!< Clock Branch disable for all APB2 peripherals */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_APB3_PERIPH APB3 peripherals clock branch disable + * @{ + */ +#define LL_RCC_APB3_PERIPH_DIS RCC_CFGR2_APB3DIS /*!< Clock Branch disable for all APB3 peripherals */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_SYSTICK_CLKSOURCE SYSTICK clock source selection + * @{ + */ +#define LL_RCC_SYSTICK_CLKSOURCE_HCLKDIV8 0x00000000U /*!< HCLKDIV8 clock used as SYSTICK clock source */ +#define LL_RCC_SYSTICK_CLKSOURCE_LSI RCC_CCIPR4_SYSTICKSEL_0 /*!< LSI clock used as SYSTICK clock source */ +#define LL_RCC_SYSTICK_CLKSOURCE_LSE RCC_CCIPR4_SYSTICKSEL_1 /*!< LSE clock used as SYSTICK clock source */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_SYSWAKEUP_CLKSOURCE System wakeup from stop and CSS backup clock selection + * @{ + */ +#define LL_RCC_SYSWAKEUP_CLKSOURCE_HSI 0x00000000U /*!< HSI selection as system clock after wake-up from STOP */ +#define LL_RCC_SYSWAKEUP_CLKSOURCE_CSI RCC_CFGR1_STOPWUCK /*!< CSI selection as system clock after wake-up from STOP */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_KERWAKEUP_CLKSOURCE Kernel wakeup from stop clock source + * @{ + */ +#define LL_RCC_KERWAKEUP_CLKSOURCE_HSI 0x00000000U /*!< HSI selection as kernel clock after wake-up from STOP */ +#define LL_RCC_KERWAKEUP_CLKSOURCE_CSI RCC_CFGR1_STOPKERWUCK /*!< CSI selection as kernel clock after wake-up from STOP */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_RTC_HSE_DIV RTC HSE Prescaler + * @{ + */ +#define LL_RCC_RTC_HSE_NOCLOCK (0x00000000U) +#define LL_RCC_RTC_HSE_DIV_2 (0x00000200U) +#define LL_RCC_RTC_HSE_DIV_3 (0x00000300U) +#define LL_RCC_RTC_HSE_DIV_4 (0x00000400U) +#define LL_RCC_RTC_HSE_DIV_5 (0x00000500U) +#define LL_RCC_RTC_HSE_DIV_6 (0x00000600U) +#define LL_RCC_RTC_HSE_DIV_7 (0x00000700U) +#define LL_RCC_RTC_HSE_DIV_8 (0x00000800U) +#define LL_RCC_RTC_HSE_DIV_9 (0x00000900U) +#define LL_RCC_RTC_HSE_DIV_10 (0x00000A00U) +#define LL_RCC_RTC_HSE_DIV_11 (0x00000B00U) +#define LL_RCC_RTC_HSE_DIV_12 (0x00000C00U) +#define LL_RCC_RTC_HSE_DIV_13 (0x00000D00U) +#define LL_RCC_RTC_HSE_DIV_14 (0x00000E00U) +#define LL_RCC_RTC_HSE_DIV_15 (0x00000F00U) +#define LL_RCC_RTC_HSE_DIV_16 (0x00001000U) +#define LL_RCC_RTC_HSE_DIV_17 (0x00001100U) +#define LL_RCC_RTC_HSE_DIV_18 (0x00001200U) +#define LL_RCC_RTC_HSE_DIV_19 (0x00001300U) +#define LL_RCC_RTC_HSE_DIV_20 (0x00001400U) +#define LL_RCC_RTC_HSE_DIV_21 (0x00001500U) +#define LL_RCC_RTC_HSE_DIV_22 (0x00001600U) +#define LL_RCC_RTC_HSE_DIV_23 (0x00001700U) +#define LL_RCC_RTC_HSE_DIV_24 (0x00001800U) +#define LL_RCC_RTC_HSE_DIV_25 (0x00001900U) +#define LL_RCC_RTC_HSE_DIV_26 (0x00001A00U) +#define LL_RCC_RTC_HSE_DIV_27 (0x00001B00U) +#define LL_RCC_RTC_HSE_DIV_28 (0x00001C00U) +#define LL_RCC_RTC_HSE_DIV_29 (0x00001D00U) +#define LL_RCC_RTC_HSE_DIV_30 (0x00001E00U) +#define LL_RCC_RTC_HSE_DIV_31 (0x00001F00U) +#define LL_RCC_RTC_HSE_DIV_32 (0x00002000U) +#define LL_RCC_RTC_HSE_DIV_33 (0x00002100U) +#define LL_RCC_RTC_HSE_DIV_34 (0x00002200U) +#define LL_RCC_RTC_HSE_DIV_35 (0x00002300U) +#define LL_RCC_RTC_HSE_DIV_36 (0x00002400U) +#define LL_RCC_RTC_HSE_DIV_37 (0x00002500U) +#define LL_RCC_RTC_HSE_DIV_38 (0x00002600U) +#define LL_RCC_RTC_HSE_DIV_39 (0x00002700U) +#define LL_RCC_RTC_HSE_DIV_40 (0x00002800U) +#define LL_RCC_RTC_HSE_DIV_41 (0x00002900U) +#define LL_RCC_RTC_HSE_DIV_42 (0x00002A00U) +#define LL_RCC_RTC_HSE_DIV_43 (0x00002B00U) +#define LL_RCC_RTC_HSE_DIV_44 (0x00002C00U) +#define LL_RCC_RTC_HSE_DIV_45 (0x00002D00U) +#define LL_RCC_RTC_HSE_DIV_46 (0x00002E00U) +#define LL_RCC_RTC_HSE_DIV_47 (0x00002F00U) +#define LL_RCC_RTC_HSE_DIV_48 (0x00003000U) +#define LL_RCC_RTC_HSE_DIV_49 (0x00003100U) +#define LL_RCC_RTC_HSE_DIV_50 (0x00003200U) +#define LL_RCC_RTC_HSE_DIV_51 (0x00003300U) +#define LL_RCC_RTC_HSE_DIV_52 (0x00003400U) +#define LL_RCC_RTC_HSE_DIV_53 (0x00003500U) +#define LL_RCC_RTC_HSE_DIV_54 (0x00003600U) +#define LL_RCC_RTC_HSE_DIV_55 (0x00003700U) +#define LL_RCC_RTC_HSE_DIV_56 (0x00003800U) +#define LL_RCC_RTC_HSE_DIV_57 (0x00003900U) +#define LL_RCC_RTC_HSE_DIV_58 (0x00003A00U) +#define LL_RCC_RTC_HSE_DIV_59 (0x00003B00U) +#define LL_RCC_RTC_HSE_DIV_60 (0x00003C00U) +#define LL_RCC_RTC_HSE_DIV_61 (0x00003D00U) +#define LL_RCC_RTC_HSE_DIV_62 (0x00003E00U) +#define LL_RCC_RTC_HSE_DIV_63 (0x00003F00U) +/** + * @} + */ + +/** @defgroup RCC_LL_EC_TIM_CLKPRESCALER Timers clocks prescalers selection + * @{ + */ +#define LL_RCC_TIM_PRESCALER_TWICE (uint32_t)(0x00000000U) +#define LL_RCC_TIM_PRESCALER_FOUR_TIMES (uint32_t)(RCC_CFGR1_TIMPRE) +/** + * @} + */ + +/** @defgroup RCC_LL_EC_MCOxSOURCE MCO SOURCE selection + * @{ + */ +#define LL_RCC_MCO1SOURCE_HSI (uint32_t)((RCC_CFGR1_MCO1SEL>>16U) | 0x00000000U) +#define LL_RCC_MCO1SOURCE_LSE (uint32_t)((RCC_CFGR1_MCO1SEL>>16U) | RCC_CFGR1_MCO1SEL_0) +#define LL_RCC_MCO1SOURCE_HSE (uint32_t)((RCC_CFGR1_MCO1SEL>>16U) | RCC_CFGR1_MCO1SEL_1) +#define LL_RCC_MCO1SOURCE_PLL1Q (uint32_t)((RCC_CFGR1_MCO1SEL>>16U) |\ + RCC_CFGR1_MCO1SEL_1|RCC_CFGR1_MCO1SEL_0) +#define LL_RCC_MCO1SOURCE_HSI48 (uint32_t)((RCC_CFGR1_MCO1SEL>>16U) | RCC_CFGR1_MCO1SEL_2) +#define LL_RCC_MCO2SOURCE_SYSCLK (uint32_t)((RCC_CFGR1_MCO2SEL>>16U) | 0x00000000U) +#define LL_RCC_MCO2SOURCE_PLL2P (uint32_t)((RCC_CFGR1_MCO2SEL>>16U) | RCC_CFGR1_MCO2SEL_0) +#define LL_RCC_MCO2SOURCE_HSE (uint32_t)((RCC_CFGR1_MCO2SEL>>16U) | RCC_CFGR1_MCO2SEL_1) +#define LL_RCC_MCO2SOURCE_PLL1P (uint32_t)((RCC_CFGR1_MCO2SEL>>16U) |\ + RCC_CFGR1_MCO2SEL_1|RCC_CFGR1_MCO2SEL_0) +#define LL_RCC_MCO2SOURCE_CSI (uint32_t)((RCC_CFGR1_MCO2SEL>>16U) | RCC_CFGR1_MCO2SEL_2) +#define LL_RCC_MCO2SOURCE_LSI (uint32_t)((RCC_CFGR1_MCO2SEL>>16U) |\ + RCC_CFGR1_MCO2SEL_2|RCC_CFGR1_MCO2SEL_0) +/** + * @} + */ + +/** @defgroup RCC_LL_EC_MCOx_DIV MCO prescaler + * @{ + */ +#define LL_RCC_MCO1_DIV_1 (uint32_t)((RCC_CFGR1_MCO1PRE>>16U) | RCC_CFGR1_MCO1PRE_0) +#define LL_RCC_MCO1_DIV_2 (uint32_t)((RCC_CFGR1_MCO1PRE>>16U) | RCC_CFGR1_MCO1PRE_1) +#define LL_RCC_MCO1_DIV_3 (uint32_t)((RCC_CFGR1_MCO1PRE>>16U) |\ + RCC_CFGR1_MCO1PRE_0 | RCC_CFGR1_MCO1PRE_1) +#define LL_RCC_MCO1_DIV_4 (uint32_t)((RCC_CFGR1_MCO1PRE>>16U) | RCC_CFGR1_MCO1PRE_2) +#define LL_RCC_MCO1_DIV_5 (uint32_t)((RCC_CFGR1_MCO1PRE>>16U) |\ + RCC_CFGR1_MCO1PRE_0 | RCC_CFGR1_MCO1PRE_2) +#define LL_RCC_MCO1_DIV_6 (uint32_t)((RCC_CFGR1_MCO1PRE>>16U) |\ + RCC_CFGR1_MCO1PRE_1 | RCC_CFGR1_MCO1PRE_2) +#define LL_RCC_MCO1_DIV_7 (uint32_t)((RCC_CFGR1_MCO1PRE>>16U) |\ + RCC_CFGR1_MCO1PRE_0 | RCC_CFGR1_MCO1PRE_1 | RCC_CFGR1_MCO1PRE_2) +#define LL_RCC_MCO1_DIV_8 (uint32_t)((RCC_CFGR1_MCO1PRE>>16U) | RCC_CFGR1_MCO1PRE_3) +#define LL_RCC_MCO1_DIV_9 (uint32_t)((RCC_CFGR1_MCO1PRE>>16U) |\ + RCC_CFGR1_MCO1PRE_0 | RCC_CFGR1_MCO1PRE_3) +#define LL_RCC_MCO1_DIV_10 (uint32_t)((RCC_CFGR1_MCO1PRE>>16U) |\ + RCC_CFGR1_MCO1PRE_1 | RCC_CFGR1_MCO1PRE_3) +#define LL_RCC_MCO1_DIV_11 (uint32_t)((RCC_CFGR1_MCO1PRE>>16U) |\ + RCC_CFGR1_MCO1PRE_0 | RCC_CFGR1_MCO1PRE_1 | RCC_CFGR1_MCO1PRE_3) +#define LL_RCC_MCO1_DIV_12 (uint32_t)((RCC_CFGR1_MCO1PRE>>16U) |\ + RCC_CFGR1_MCO1PRE_2 | RCC_CFGR1_MCO1PRE_3) +#define LL_RCC_MCO1_DIV_13 (uint32_t)((RCC_CFGR1_MCO1PRE>>16U) |\ + RCC_CFGR1_MCO1PRE_0 | RCC_CFGR1_MCO1PRE_2 | RCC_CFGR1_MCO1PRE_3) +#define LL_RCC_MCO1_DIV_14 (uint32_t)((RCC_CFGR1_MCO1PRE>>16U) |\ + RCC_CFGR1_MCO1PRE_1 | RCC_CFGR1_MCO1PRE_2 | RCC_CFGR1_MCO1PRE_3) +#define LL_RCC_MCO1_DIV_15 (uint32_t)((RCC_CFGR1_MCO1PRE>>16U) | RCC_CFGR1_MCO1PRE) +#define LL_RCC_MCO2_DIV_1 (uint32_t)((RCC_CFGR1_MCO2PRE>>16U) | RCC_CFGR1_MCO2PRE_0) +#define LL_RCC_MCO2_DIV_2 (uint32_t)((RCC_CFGR1_MCO2PRE>>16U) | RCC_CFGR1_MCO2PRE_1) +#define LL_RCC_MCO2_DIV_3 (uint32_t)((RCC_CFGR1_MCO2PRE>>16U) |\ + RCC_CFGR1_MCO2PRE_0 | RCC_CFGR1_MCO2PRE_1) +#define LL_RCC_MCO2_DIV_4 (uint32_t)((RCC_CFGR1_MCO2PRE>>16U) | RCC_CFGR1_MCO2PRE_2) +#define LL_RCC_MCO2_DIV_5 (uint32_t)((RCC_CFGR1_MCO2PRE>>16U) |\ + RCC_CFGR1_MCO2PRE_0 | RCC_CFGR1_MCO2PRE_2) +#define LL_RCC_MCO2_DIV_6 (uint32_t)((RCC_CFGR1_MCO2PRE>>16U) |\ + RCC_CFGR1_MCO2PRE_1 | RCC_CFGR1_MCO2PRE_2) +#define LL_RCC_MCO2_DIV_7 (uint32_t)((RCC_CFGR1_MCO2PRE>>16U) |\ + RCC_CFGR1_MCO2PRE_0 | RCC_CFGR1_MCO2PRE_1 | RCC_CFGR1_MCO2PRE_2) +#define LL_RCC_MCO2_DIV_8 (uint32_t)((RCC_CFGR1_MCO2PRE>>16U) | RCC_CFGR1_MCO2PRE_3) +#define LL_RCC_MCO2_DIV_9 (uint32_t)((RCC_CFGR1_MCO2PRE>>16U) |\ + RCC_CFGR1_MCO2PRE_0 | RCC_CFGR1_MCO2PRE_3) +#define LL_RCC_MCO2_DIV_10 (uint32_t)((RCC_CFGR1_MCO2PRE>>16U) |\ + RCC_CFGR1_MCO2PRE_1 | RCC_CFGR1_MCO2PRE_3) +#define LL_RCC_MCO2_DIV_11 (uint32_t)((RCC_CFGR1_MCO2PRE>>16U) |\ + RCC_CFGR1_MCO2PRE_0 | RCC_CFGR1_MCO2PRE_1 | RCC_CFGR1_MCO2PRE_3) +#define LL_RCC_MCO2_DIV_12 (uint32_t)((RCC_CFGR1_MCO2PRE>>16U) |\ + RCC_CFGR1_MCO2PRE_2 | RCC_CFGR1_MCO2PRE_3) +#define LL_RCC_MCO2_DIV_13 (uint32_t)((RCC_CFGR1_MCO2PRE>>16U) |\ + RCC_CFGR1_MCO2PRE_0 | RCC_CFGR1_MCO2PRE_2 | RCC_CFGR1_MCO2PRE_3) +#define LL_RCC_MCO2_DIV_14 (uint32_t)((RCC_CFGR1_MCO2PRE>>16U) |\ + RCC_CFGR1_MCO2PRE_1 | RCC_CFGR1_MCO2PRE_2 | RCC_CFGR1_MCO2PRE_3) +#define LL_RCC_MCO2_DIV_15 (uint32_t)((RCC_CFGR1_MCO2PRE>>16U) | RCC_CFGR1_MCO2PRE) +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup RCC_LL_EC_PERIPH_FREQUENCY Peripheral clock frequency + * @{ + */ +#define LL_RCC_PERIPH_FREQUENCY_NO 0x00000000U /*!< No clock enabled for the peripheral */ +#define LL_RCC_PERIPH_FREQUENCY_NA 0xFFFFFFFFU /*!< Frequency cannot be provided as external clock */ +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** @defgroup RCC_LL_EC_RTC_CLKSOURCE RTC clock source selection + * @{ + */ +#define LL_RCC_RTC_CLKSOURCE_NONE 0x00000000U /*!< No clock used as RTC clock */ +#define LL_RCC_RTC_CLKSOURCE_LSE RCC_BDCR_RTCSEL_0 /*!< LSE oscillator clock used as RTC clock */ +#define LL_RCC_RTC_CLKSOURCE_LSI RCC_BDCR_RTCSEL_1 /*!< LSI oscillator clock used as RTC clock */ +#define LL_RCC_RTC_CLKSOURCE_HSE_DIV RCC_BDCR_RTCSEL /*!< HSE oscillator clock divided by RTCPRE used as RTC clock */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_USART_CLKSOURCE Peripheral USARTx clock source selection + * @{ + */ +#define LL_RCC_USART1_CLKSOURCE_PCLK2 LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART1SEL, RCC_CCIPR1_USART1SEL_Pos, 0x00000000U) /*!< PCLK2 clock used as USART1 clock source */ +#define LL_RCC_USART1_CLKSOURCE_PLL2Q LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART1SEL, RCC_CCIPR1_USART1SEL_Pos, RCC_CCIPR1_USART1SEL_0) /*!< PLL2 Q clock used as USART1 clock source */ +#if defined(RCC_CR_PLL3ON) +#define LL_RCC_USART1_CLKSOURCE_PLL3Q LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART1SEL, RCC_CCIPR1_USART1SEL_Pos, RCC_CCIPR1_USART1SEL_1) /*!< PLL3 Q clock used as USART1 clock source */ +#endif /* PLL3 */ +#define LL_RCC_USART1_CLKSOURCE_HSI LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART1SEL, RCC_CCIPR1_USART1SEL_Pos, RCC_CCIPR1_USART1SEL_1 | RCC_CCIPR1_USART1SEL_0) /*!< HSI clock used as USART1 clock source */ +#define LL_RCC_USART1_CLKSOURCE_CSI LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART1SEL, RCC_CCIPR1_USART1SEL_Pos, RCC_CCIPR1_USART1SEL_2) /*!< CSI clock used as USART1 clock source */ +#define LL_RCC_USART1_CLKSOURCE_LSE LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART1SEL, RCC_CCIPR1_USART1SEL_Pos, RCC_CCIPR1_USART1SEL_2 | RCC_CCIPR1_USART1SEL_0) /*!< LSE clock used as USART1 clock source */ + +#define LL_RCC_USART2_CLKSOURCE_PCLK1 LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART2SEL, RCC_CCIPR1_USART2SEL_Pos, 0x00000000U) /*!< PCLK1 clock used as USART2 clock source */ +#define LL_RCC_USART2_CLKSOURCE_PLL2Q LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART2SEL, RCC_CCIPR1_USART2SEL_Pos, RCC_CCIPR1_USART2SEL_0) /*!< PLL2 Q clock used as USART2 clock source */ +#if defined(RCC_CR_PLL3ON) +#define LL_RCC_USART2_CLKSOURCE_PLL3Q LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART2SEL, RCC_CCIPR1_USART2SEL_Pos, RCC_CCIPR1_USART2SEL_1) /*!< PLL3 Q clock used as USART2 clock source */ +#endif /* PLL3 */ +#define LL_RCC_USART2_CLKSOURCE_HSI LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART2SEL, RCC_CCIPR1_USART2SEL_Pos, RCC_CCIPR1_USART2SEL_1 | RCC_CCIPR1_USART2SEL_0) /*!< HSI clock used as USART2 clock source */ +#define LL_RCC_USART2_CLKSOURCE_CSI LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART2SEL, RCC_CCIPR1_USART2SEL_Pos, RCC_CCIPR1_USART2SEL_2) /*!< CSI clock used as USART2 clock source */ +#define LL_RCC_USART2_CLKSOURCE_LSE LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART2SEL, RCC_CCIPR1_USART2SEL_Pos, RCC_CCIPR1_USART2SEL_2 | RCC_CCIPR1_USART2SEL_0) /*!< LSE clock used as USART2 clock source */ + +#define LL_RCC_USART3_CLKSOURCE_PCLK1 LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART3SEL, RCC_CCIPR1_USART3SEL_Pos, 0x00000000U) /*!< PCLK1 clock used as USART3 clock source */ +#define LL_RCC_USART3_CLKSOURCE_PLL2Q LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART3SEL, RCC_CCIPR1_USART3SEL_Pos, RCC_CCIPR1_USART3SEL_0) /*!< PLL2 Q clock used as USART3 clock source */ +#if defined(RCC_CR_PLL3ON) +#define LL_RCC_USART3_CLKSOURCE_PLL3Q LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART3SEL, RCC_CCIPR1_USART3SEL_Pos, RCC_CCIPR1_USART3SEL_1) /*!< PLL3 Q clock used as USART3 clock source */ +#endif /* PLL3 */ +#define LL_RCC_USART3_CLKSOURCE_HSI LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART3SEL, RCC_CCIPR1_USART3SEL_Pos, RCC_CCIPR1_USART3SEL_1 | RCC_CCIPR1_USART3SEL_0) /*!< HSI clock used as USART3 clock source */ +#define LL_RCC_USART3_CLKSOURCE_CSI LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART3SEL, RCC_CCIPR1_USART3SEL_Pos, RCC_CCIPR1_USART3SEL_2) /*!< CSI clock used as USART3 clock source */ +#define LL_RCC_USART3_CLKSOURCE_LSE LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART3SEL, RCC_CCIPR1_USART3SEL_Pos, RCC_CCIPR1_USART3SEL_2 | RCC_CCIPR1_USART3SEL_0) /*!< LSE clock used as USART3 clock source */ + +#if defined(USART6) +#define LL_RCC_USART6_CLKSOURCE_PCLK1 LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART6SEL, RCC_CCIPR1_USART6SEL_Pos, 0x00000000U) /*!< PCLK1 clock used as USART6 clock source */ +#define LL_RCC_USART6_CLKSOURCE_PLL2Q LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART6SEL, RCC_CCIPR1_USART6SEL_Pos, RCC_CCIPR1_USART6SEL_0) /*!< PLL2 Q clock used as USART6 clock source */ +#define LL_RCC_USART6_CLKSOURCE_PLL3Q LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART6SEL, RCC_CCIPR1_USART6SEL_Pos, RCC_CCIPR1_USART6SEL_1) /*!< PLL3 Q clock used as USART6 clock source */ +#define LL_RCC_USART6_CLKSOURCE_HSI LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART6SEL, RCC_CCIPR1_USART6SEL_Pos, RCC_CCIPR1_USART6SEL_1 | RCC_CCIPR1_USART6SEL_0) /*!< HSI clock used as USART6 clock source */ +#define LL_RCC_USART6_CLKSOURCE_CSI LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART6SEL, RCC_CCIPR1_USART6SEL_Pos, RCC_CCIPR1_USART6SEL_2) /*!< CSI clock used as USART6 clock source */ +#define LL_RCC_USART6_CLKSOURCE_LSE LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART6SEL, RCC_CCIPR1_USART6SEL_Pos, RCC_CCIPR1_USART6SEL_2 | RCC_CCIPR1_USART6SEL_0) /*!< LSE clock used as USART6 clock source */ +#endif /* USART6 */ + +#if defined(USART10) +#define LL_RCC_USART10_CLKSOURCE_PCLK1 LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART10SEL, RCC_CCIPR1_USART10SEL_Pos, 0x00000000U) /*!< PCLK1 clock used as USART10 clock source */ +#define LL_RCC_USART10_CLKSOURCE_PLL2Q LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART10SEL, RCC_CCIPR1_USART10SEL_Pos, RCC_CCIPR1_USART10SEL_0) /*!< PLL2 Q clock used as USART10 clock source */ +#define LL_RCC_USART10_CLKSOURCE_PLL3Q LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART10SEL, RCC_CCIPR1_USART10SEL_Pos, RCC_CCIPR1_USART10SEL_1) /*!< PLL3 Q clock used as USART10 clock source */ +#define LL_RCC_USART10_CLKSOURCE_HSI LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART10SEL, RCC_CCIPR1_USART10SEL_Pos, RCC_CCIPR1_USART10SEL_1 | RCC_CCIPR1_USART10SEL_0) /*!< HSI clock used as USART10 clock source */ +#define LL_RCC_USART10_CLKSOURCE_CSI LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART10SEL, RCC_CCIPR1_USART10SEL_Pos, RCC_CCIPR1_USART10SEL_2) /*!< CSI clock used as USART10 clock source */ +#define LL_RCC_USART10_CLKSOURCE_LSE LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART10SEL, RCC_CCIPR1_USART10SEL_Pos, RCC_CCIPR1_USART10SEL_2 | RCC_CCIPR1_USART10SEL_0) /*!< LSE clock used as USART10 clock source */ +#endif /* USART10 */ + +#if defined(USART11) +#define LL_RCC_USART11_CLKSOURCE_PCLK1 LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_USART11SEL, RCC_CCIPR2_USART11SEL_Pos, 0x00000000U) /*!< PCLK1 clock used as USART11 clock source */ +#define LL_RCC_USART11_CLKSOURCE_PLL2Q LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_USART11SEL, RCC_CCIPR2_USART11SEL_Pos, RCC_CCIPR2_USART11SEL_0) /*!< PLL2 Q clock used as USART11 clock source */ +#define LL_RCC_USART11_CLKSOURCE_PLL3Q LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_USART11SEL, RCC_CCIPR2_USART11SEL_Pos, RCC_CCIPR2_USART11SEL_1) /*!< PLL3 Q clock used as USART11 clock source */ +#define LL_RCC_USART11_CLKSOURCE_HSI LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_USART11SEL, RCC_CCIPR2_USART11SEL_Pos, RCC_CCIPR2_USART11SEL_1 | RCC_CCIPR2_USART11SEL_0) /*!< HSI clock used as USART11 clock source */ +#define LL_RCC_USART11_CLKSOURCE_CSI LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_USART11SEL, RCC_CCIPR2_USART11SEL_Pos, RCC_CCIPR2_USART11SEL_2) /*!< CSI clock used as USART11 clock source */ +#define LL_RCC_USART11_CLKSOURCE_LSE LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_USART11SEL, RCC_CCIPR2_USART11SEL_Pos, RCC_CCIPR2_USART11SEL_2 | RCC_CCIPR2_USART11SEL_0) /*!< LSE clock used as USART11 clock source */ +#endif /* USART11 */ +/** + * @} + */ + +#if defined(UART4) +/** @defgroup RCC_LL_EC_UART_CLKSOURCE Peripheral UARTx clock source selection + * @{ + */ +#define LL_RCC_UART4_CLKSOURCE_PCLK1 LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART4SEL, RCC_CCIPR1_UART4SEL_Pos, 0x00000000U) /*!< PCLK1 clock used as UART4 clock source */ +#define LL_RCC_UART4_CLKSOURCE_PLL2Q LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART4SEL, RCC_CCIPR1_UART4SEL_Pos, RCC_CCIPR1_UART4SEL_0) /*!< PLL2 Q clock used as UART4 clock source */ +#define LL_RCC_UART4_CLKSOURCE_PLL3Q LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART4SEL, RCC_CCIPR1_UART4SEL_Pos, RCC_CCIPR1_UART4SEL_1) /*!< PLL3 Q clock used as UART4 clock source */ +#define LL_RCC_UART4_CLKSOURCE_HSI LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART4SEL, RCC_CCIPR1_UART4SEL_Pos, RCC_CCIPR1_UART4SEL_1 | RCC_CCIPR1_UART4SEL_0) /*!< HSI clock used as UART4 clock source */ +#define LL_RCC_UART4_CLKSOURCE_CSI LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART4SEL, RCC_CCIPR1_UART4SEL_Pos, RCC_CCIPR1_UART4SEL_2) /*!< CSI clock used as UART4 clock source */ +#define LL_RCC_UART4_CLKSOURCE_LSE LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART4SEL, RCC_CCIPR1_UART4SEL_Pos, RCC_CCIPR1_UART4SEL_2 | RCC_CCIPR1_UART4SEL_0) /*!< LSE clock used as UART4 clock source */ + +#define LL_RCC_UART5_CLKSOURCE_PCLK1 LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART5SEL, RCC_CCIPR1_UART5SEL_Pos, 0x00000000U) /*!< PCLK1 clock used as UART5 clock source */ +#define LL_RCC_UART5_CLKSOURCE_PLL2Q LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART5SEL, RCC_CCIPR1_UART5SEL_Pos, RCC_CCIPR1_UART5SEL_0) /*!< PLL2 Q clock used as UART5 clock source */ +#define LL_RCC_UART5_CLKSOURCE_PLL3Q LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART5SEL, RCC_CCIPR1_UART5SEL_Pos, RCC_CCIPR1_UART5SEL_1) /*!< PLL3 Q clock used as UART5 clock source */ +#define LL_RCC_UART5_CLKSOURCE_HSI LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART5SEL, RCC_CCIPR1_UART5SEL_Pos, RCC_CCIPR1_UART5SEL_1 | RCC_CCIPR1_UART5SEL_0) /*!< HSI clock used as UART5 clock source */ +#define LL_RCC_UART5_CLKSOURCE_CSI LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART5SEL, RCC_CCIPR1_UART5SEL_Pos, RCC_CCIPR1_UART5SEL_2) /*!< CSI clock used as UART5 clock source */ +#define LL_RCC_UART5_CLKSOURCE_LSE LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART5SEL, RCC_CCIPR1_UART5SEL_Pos, RCC_CCIPR1_UART5SEL_2 | RCC_CCIPR1_UART5SEL_0) /*!< LSE clock used as UART5 clock source */ + +#define LL_RCC_UART7_CLKSOURCE_PCLK1 LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART7SEL, RCC_CCIPR1_UART7SEL_Pos, 0x00000000U) /*!< PCLK1 clock used as UART7 clock source */ +#define LL_RCC_UART7_CLKSOURCE_PLL2Q LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART7SEL, RCC_CCIPR1_UART7SEL_Pos, RCC_CCIPR1_UART7SEL_0) /*!< PLL2 Q clock used as UART7 clock source */ +#define LL_RCC_UART7_CLKSOURCE_PLL3Q LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART7SEL, RCC_CCIPR1_UART7SEL_Pos, RCC_CCIPR1_UART7SEL_1) /*!< PLL3 Q clock used as UART7 clock source */ +#define LL_RCC_UART7_CLKSOURCE_HSI LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART7SEL, RCC_CCIPR1_UART7SEL_Pos, RCC_CCIPR1_UART7SEL_1 | RCC_CCIPR1_UART7SEL_0) /*!< HSI clock used as UART7 clock source */ +#define LL_RCC_UART7_CLKSOURCE_CSI LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART7SEL, RCC_CCIPR1_UART7SEL_Pos, RCC_CCIPR1_UART7SEL_2) /*!< CSI clock used as UART7 clock source */ +#define LL_RCC_UART7_CLKSOURCE_LSE LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART7SEL, RCC_CCIPR1_UART7SEL_Pos, RCC_CCIPR1_UART7SEL_2 | RCC_CCIPR1_UART7SEL_0) /*!< LSE clock used as UART7 clock source */ + +#define LL_RCC_UART8_CLKSOURCE_PCLK1 LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART8SEL, RCC_CCIPR1_UART8SEL_Pos, 0x00000000U) /*!< PCLK1 clock used as UART8 clock source */ +#define LL_RCC_UART8_CLKSOURCE_PLL2Q LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART8SEL, RCC_CCIPR1_UART8SEL_Pos, RCC_CCIPR1_UART8SEL_0) /*!< PLL2 Q clock used as UART8 clock source */ +#define LL_RCC_UART8_CLKSOURCE_PLL3Q LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART8SEL, RCC_CCIPR1_UART8SEL_Pos, RCC_CCIPR1_UART8SEL_1) /*!< PLL3 Q clock used as UART8 clock source */ +#define LL_RCC_UART8_CLKSOURCE_HSI LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART8SEL, RCC_CCIPR1_UART8SEL_Pos, RCC_CCIPR1_UART8SEL_1 | RCC_CCIPR1_UART8SEL_0) /*!< HSI clock used as UART8 clock source */ +#define LL_RCC_UART8_CLKSOURCE_CSI LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART8SEL, RCC_CCIPR1_UART8SEL_Pos, RCC_CCIPR1_UART8SEL_2) /*!< CSI clock used as UART8 clock source */ +#define LL_RCC_UART8_CLKSOURCE_LSE LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART8SEL, RCC_CCIPR1_UART8SEL_Pos, RCC_CCIPR1_UART8SEL_2 | RCC_CCIPR1_UART8SEL_0) /*!< LSE clock used as UART8 clock source */ + +#define LL_RCC_UART9_CLKSOURCE_PCLK1 LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART9SEL, RCC_CCIPR1_UART9SEL_Pos, 0x00000000U) /*!< PCLK1 clock used as UART9 clock source */ +#define LL_RCC_UART9_CLKSOURCE_PLL2Q LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART9SEL, RCC_CCIPR1_UART9SEL_Pos, RCC_CCIPR1_UART9SEL_0) /*!< PLL2 Q clock used as UART9 clock source */ +#define LL_RCC_UART9_CLKSOURCE_PLL3Q LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART9SEL, RCC_CCIPR1_UART9SEL_Pos, RCC_CCIPR1_UART9SEL_1) /*!< PLL3 Q clock used as UART9 clock source */ +#define LL_RCC_UART9_CLKSOURCE_HSI LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART9SEL, RCC_CCIPR1_UART9SEL_Pos, RCC_CCIPR1_UART9SEL_1 | RCC_CCIPR1_UART9SEL_0) /*!< HSI clock used as UART9 clock source */ +#define LL_RCC_UART9_CLKSOURCE_CSI LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART9SEL, RCC_CCIPR1_UART9SEL_Pos, RCC_CCIPR1_UART9SEL_2) /*!< CSI clock used as UART9 clock source */ +#define LL_RCC_UART9_CLKSOURCE_LSE LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART9SEL, RCC_CCIPR1_UART9SEL_Pos, RCC_CCIPR1_UART9SEL_2 | RCC_CCIPR1_UART9SEL_0) /*!< LSE clock used as UART9 clock source */ + +#define LL_RCC_UART12_CLKSOURCE_PCLK1 LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_UART12SEL, RCC_CCIPR2_UART12SEL_Pos, 0x00000000U) /*!< PCLK1 clock used as UART12 clock source */ +#define LL_RCC_UART12_CLKSOURCE_PLL2Q LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_UART12SEL, RCC_CCIPR2_UART12SEL_Pos, RCC_CCIPR2_UART12SEL_0) /*!< PLL2 Q clock used as UART12 clock source */ +#define LL_RCC_UART12_CLKSOURCE_PLL3Q LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_UART12SEL, RCC_CCIPR2_UART12SEL_Pos, RCC_CCIPR2_UART12SEL_1) /*!< PLL3 Q clock used as UART12 clock source */ +#define LL_RCC_UART12_CLKSOURCE_HSI LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_UART12SEL, RCC_CCIPR2_UART12SEL_Pos, RCC_CCIPR2_UART12SEL_1 | RCC_CCIPR2_UART12SEL_0) /*!< HSI clock used as UART12 clock source */ +#define LL_RCC_UART12_CLKSOURCE_CSI LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_UART12SEL, RCC_CCIPR2_UART12SEL_Pos, RCC_CCIPR2_UART12SEL_2) /*!< CSI clock used as UART12 clock source */ +#define LL_RCC_UART12_CLKSOURCE_LSE LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_UART12SEL, RCC_CCIPR2_UART12SEL_Pos, RCC_CCIPR2_UART12SEL_2 | RCC_CCIPR2_UART12SEL_0) /*!< LSE clock used as UART12 clock source */ +/** + * @} + */ +#endif /* UART4 */ + +/** @defgroup RCC_LL_EC_LPUART_CLKSOURCE Peripheral LPUARTx clock source selection + * @{ + */ +#define LL_RCC_LPUART1_CLKSOURCE_PCLK3 0x00000000U /*!< PCLK3 clock used as LPUART1 clock source */ +#define LL_RCC_LPUART1_CLKSOURCE_PLL2Q RCC_CCIPR3_LPUART1SEL_0 /*!< PLL2Q clock used as LPUART1 clock source */ +#if defined(RCC_CR_PLL3ON) +#define LL_RCC_LPUART1_CLKSOURCE_PLL3Q RCC_CCIPR3_LPUART1SEL_1 /*!< PLL3Q clock used as LPUART1 clock source */ +#endif /* PLL3 */ +#define LL_RCC_LPUART1_CLKSOURCE_HSI (RCC_CCIPR3_LPUART1SEL_0 | RCC_CCIPR3_LPUART1SEL_1) /*!< HSI clock used as LPUART1 clock source */ +#define LL_RCC_LPUART1_CLKSOURCE_CSI RCC_CCIPR3_LPUART1SEL_2 /*!< CSI clock used as LPUART1 clock source */ +#define LL_RCC_LPUART1_CLKSOURCE_LSE (RCC_CCIPR3_LPUART1SEL_0 | RCC_CCIPR3_LPUART1SEL_2) /*!< LSE clock used as LPUART1 clock source */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_I2C_CLKSOURCE Peripheral I2Cx clock source selection + * @{ + */ +#define LL_RCC_I2C1_CLKSOURCE_PCLK1 LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I2C1SEL, RCC_CCIPR4_I2C1SEL_Pos, 0x00000000U) /*!< PCLK1 clock used as I2C1 clock source */ +#if defined(RCC_CR_PLL3ON) +#define LL_RCC_I2C1_CLKSOURCE_PLL3R LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I2C1SEL, RCC_CCIPR4_I2C1SEL_Pos, RCC_CCIPR4_I2C1SEL_0) /*!< PLL3 R clock used as I2C1 clock source */ +#else +#define LL_RCC_I2C1_CLKSOURCE_PLL2R LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I2C1SEL, RCC_CCIPR4_I2C1SEL_Pos, RCC_CCIPR4_I2C1SEL_0) /*!< PLL2 R clock used as I2C1 clock source */ +#endif /* PLL3 */ +#define LL_RCC_I2C1_CLKSOURCE_HSI LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I2C1SEL, RCC_CCIPR4_I2C1SEL_Pos, RCC_CCIPR4_I2C1SEL_1) /*!< HSI clock used as I2C1 clock source */ +#define LL_RCC_I2C1_CLKSOURCE_CSI LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I2C1SEL, RCC_CCIPR4_I2C1SEL_Pos, RCC_CCIPR4_I2C1SEL) /*!< CSI clock used as I2C1 clock source */ + +#define LL_RCC_I2C2_CLKSOURCE_PCLK1 LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I2C2SEL, RCC_CCIPR4_I2C2SEL_Pos, 0x00000000U) /*!< PCLK1 clock used as I2C2 clock source */ +#if defined(RCC_CR_PLL3ON) +#define LL_RCC_I2C2_CLKSOURCE_PLL3R LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I2C2SEL, RCC_CCIPR4_I2C2SEL_Pos, RCC_CCIPR4_I2C2SEL_0) /*!< PLL3 R clock used as I2C2 clock source */ +#else +#define LL_RCC_I2C2_CLKSOURCE_PLL2R LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I2C2SEL, RCC_CCIPR4_I2C2SEL_Pos, RCC_CCIPR4_I2C2SEL_0) /*!< PLL2 R clock used as I2C2 clock source */ +#endif /* PLL3 */ +#define LL_RCC_I2C2_CLKSOURCE_HSI LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I2C2SEL, RCC_CCIPR4_I2C2SEL_Pos, RCC_CCIPR4_I2C2SEL_1) /*!< HSI clock used as I2C2 clock source */ +#define LL_RCC_I2C2_CLKSOURCE_CSI LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I2C2SEL, RCC_CCIPR4_I2C2SEL_Pos, RCC_CCIPR4_I2C2SEL) /*!< CSI clock used as I2C2 clock source */ + +#if defined(I2C3) +#define LL_RCC_I2C3_CLKSOURCE_PCLK3 LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I2C3SEL, RCC_CCIPR4_I2C3SEL_Pos, 0x00000000U) /*!< PCLK3 clock used as I2C3 clock source */ +#define LL_RCC_I2C3_CLKSOURCE_PLL3R LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I2C3SEL, RCC_CCIPR4_I2C3SEL_Pos, RCC_CCIPR4_I2C3SEL_0) /*!< PLL3 R clock used as I2C3 clock source */ +#define LL_RCC_I2C3_CLKSOURCE_HSI LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I2C3SEL, RCC_CCIPR4_I2C3SEL_Pos, RCC_CCIPR4_I2C3SEL_1) /*!< HSI clock used as I2C3 clock source */ +#define LL_RCC_I2C3_CLKSOURCE_CSI LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I2C3SEL, RCC_CCIPR4_I2C3SEL_Pos, RCC_CCIPR4_I2C3SEL) /*!< CSI clock used as I2C3 clock source */ +#endif /* I2C3 */ + +#if defined(I2C4) +#define LL_RCC_I2C4_CLKSOURCE_PCLK3 LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I2C4SEL, RCC_CCIPR4_I2C4SEL_Pos, 0x00000000U) /*!< PCLK3 clock used as I2C4 clock source */ +#define LL_RCC_I2C4_CLKSOURCE_PLL3R LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I2C4SEL, RCC_CCIPR4_I2C4SEL_Pos, RCC_CCIPR4_I2C4SEL_0) /*!< PLL3 R clock used as I2C4 clock source */ +#define LL_RCC_I2C4_CLKSOURCE_HSI LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I2C4SEL, RCC_CCIPR4_I2C4SEL_Pos, RCC_CCIPR4_I2C4SEL_1) /*!< HSI clock used as I2C4 clock source */ +#define LL_RCC_I2C4_CLKSOURCE_CSI LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I2C4SEL, RCC_CCIPR4_I2C4SEL_Pos, RCC_CCIPR4_I2C4SEL) /*!< CSI clock used as I2C4 clock source */ +#endif /* I2C4 */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_I3C_CLKSOURCE Peripheral I3Cx clock source selection + * @{ + */ +#define LL_RCC_I3C1_CLKSOURCE_PCLK1 LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I3C1SEL, RCC_CCIPR4_I3C1SEL_Pos, 0x00000000U) /*!< PCLK1 clock used as I3C1 clock source */ +#if defined(RCC_CR_PLL3ON) +#define LL_RCC_I3C1_CLKSOURCE_PLL3R LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I3C1SEL, RCC_CCIPR4_I3C1SEL_Pos, RCC_CCIPR4_I3C1SEL_0) /*!< PLL3 R clock used as I3C1 clock source */ +#else +#define LL_RCC_I3C1_CLKSOURCE_PLL2R LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I3C1SEL, RCC_CCIPR4_I3C1SEL_Pos, RCC_CCIPR4_I3C1SEL_0) /*!< PLL2 R clock used as I3C1 clock source */ +#endif /* PLL3 */ +#define LL_RCC_I3C1_CLKSOURCE_HSI LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I3C1SEL, RCC_CCIPR4_I3C1SEL_Pos, RCC_CCIPR4_I3C1SEL_1) /*!< HSI clock used as I3C1 clock source */ +#define LL_RCC_I3C1_CLKSOURCE_NONE LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I3C1SEL, RCC_CCIPR4_I3C1SEL_Pos, RCC_CCIPR4_I3C1SEL) /*!< NONE clock used as I3C1 clock source */ + +#if defined(I3C2) +#define LL_RCC_I3C2_CLKSOURCE_PCLK3 LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I3C2SEL, RCC_CCIPR4_I3C2SEL_Pos, 0x00000000U) /*!< PCLK3 clock used as I3C2 clock source */ +#define LL_RCC_I3C2_CLKSOURCE_PLL2R LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I3C2SEL, RCC_CCIPR4_I3C2SEL_Pos, RCC_CCIPR4_I3C2SEL_0) /*!< PLL2 R clock used as I3C2 clock source */ +#define LL_RCC_I3C2_CLKSOURCE_HSI LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I3C2SEL, RCC_CCIPR4_I3C2SEL_Pos, RCC_CCIPR4_I3C2SEL_1) /*!< HSI clock used as I3C2 clock source */ +#define LL_RCC_I3C2_CLKSOURCE_NONE LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I3C2SEL, RCC_CCIPR4_I3C2SEL_Pos, RCC_CCIPR4_I3C2SEL) /*!< NONE clock used as I3C2 clock source */ +#endif /* I3C2 */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_SPI_CLKSOURCE Peripheral SPIx clock source selection + * @{ + */ +#define LL_RCC_SPI1_CLKSOURCE_PLL1Q LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI1SEL, RCC_CCIPR3_SPI1SEL_Pos, 0x00000000U) /*!< PLL1 Q clock used as SPI1 clock source */ +#define LL_RCC_SPI1_CLKSOURCE_PLL2P LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI1SEL, RCC_CCIPR3_SPI1SEL_Pos, RCC_CCIPR3_SPI1SEL_0) /*!< PLL2 P clock used as SPI1 clock source */ +#if defined(RCC_CR_PLL3ON) +#define LL_RCC_SPI1_CLKSOURCE_PLL3P LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI1SEL, RCC_CCIPR3_SPI1SEL_Pos, RCC_CCIPR3_SPI1SEL_1) /*!< PLL3 P clock used as SPI1 clock source */ +#endif /* PLL3 */ +#define LL_RCC_SPI1_CLKSOURCE_PIN LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI1SEL, RCC_CCIPR3_SPI1SEL_Pos, RCC_CCIPR3_SPI1SEL_1 | RCC_CCIPR3_SPI1SEL_0) /*!< PIN clock used as SPI1 clock source */ +#define LL_RCC_SPI1_CLKSOURCE_CLKP LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI1SEL, RCC_CCIPR3_SPI1SEL_Pos, RCC_CCIPR3_SPI1SEL_2) /*!< CLKP clock used as SPI1 clock source */ + +#define LL_RCC_SPI2_CLKSOURCE_PLL1Q LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI2SEL, RCC_CCIPR3_SPI2SEL_Pos, 0x00000000U) /*!< PLL1 Q clock used as SPI2 clock source */ +#define LL_RCC_SPI2_CLKSOURCE_PLL2P LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI2SEL, RCC_CCIPR3_SPI2SEL_Pos, RCC_CCIPR3_SPI2SEL_0) /*!< PLL2 P clock used as SPI2 clock source */ +#if defined(RCC_CR_PLL3ON) +#define LL_RCC_SPI2_CLKSOURCE_PLL3P LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI2SEL, RCC_CCIPR3_SPI2SEL_Pos, RCC_CCIPR3_SPI2SEL_1) /*!< PLL3 P clock used as SPI2 clock source */ +#endif /* PLL3 */ +#define LL_RCC_SPI2_CLKSOURCE_PIN LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI2SEL, RCC_CCIPR3_SPI2SEL_Pos, RCC_CCIPR3_SPI2SEL_1 | RCC_CCIPR3_SPI2SEL_0) /*!< PIN clock used as SPI2 clock source */ +#define LL_RCC_SPI2_CLKSOURCE_CLKP LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI2SEL, RCC_CCIPR3_SPI2SEL_Pos, RCC_CCIPR3_SPI2SEL_2) /*!< CLKP clock used as SPI2 clock source */ + +#define LL_RCC_SPI3_CLKSOURCE_PLL1Q LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI3SEL, RCC_CCIPR3_SPI3SEL_Pos, 0x00000000U) /*!< PLL1 Q clock used as SPI3 clock source */ +#define LL_RCC_SPI3_CLKSOURCE_PLL2P LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI3SEL, RCC_CCIPR3_SPI3SEL_Pos, RCC_CCIPR3_SPI3SEL_0) /*!< PLL2 P clock used as SPI3 clock source */ +#if defined(RCC_CR_PLL3ON) +#define LL_RCC_SPI3_CLKSOURCE_PLL3P LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI3SEL, RCC_CCIPR3_SPI3SEL_Pos, RCC_CCIPR3_SPI3SEL_1) /*!< PLL3 P clock used as SPI3 clock source */ +#endif /* PLL3 */ +#define LL_RCC_SPI3_CLKSOURCE_PIN LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI3SEL, RCC_CCIPR3_SPI3SEL_Pos, RCC_CCIPR3_SPI3SEL_1 | RCC_CCIPR3_SPI3SEL_0) /*!< PIN clock used as SPI3 clock source */ +#define LL_RCC_SPI3_CLKSOURCE_CLKP LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI3SEL, RCC_CCIPR3_SPI3SEL_Pos, RCC_CCIPR3_SPI3SEL_2) /*!< CLKP clock used as SPI3 clock source */ + +#if defined(SPI4) +#define LL_RCC_SPI4_CLKSOURCE_PCLK2 LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI4SEL, RCC_CCIPR3_SPI4SEL_Pos, 0x00000000U) /*!< PCLK2 clock used as SPI4 clock source */ +#define LL_RCC_SPI4_CLKSOURCE_PLL2Q LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI4SEL, RCC_CCIPR3_SPI4SEL_Pos, RCC_CCIPR3_SPI4SEL_0) /*!< PLL2 Q clock used as SPI4 clock source */ +#define LL_RCC_SPI4_CLKSOURCE_PLL3Q LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI4SEL, RCC_CCIPR3_SPI4SEL_Pos, RCC_CCIPR3_SPI4SEL_1) /*!< PLL3 Q clock used as SPI4 clock source */ +#define LL_RCC_SPI4_CLKSOURCE_HSI LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI4SEL, RCC_CCIPR3_SPI4SEL_Pos, RCC_CCIPR3_SPI4SEL_1 | RCC_CCIPR3_SPI4SEL_0) /*!< HSI clock used as SPI4 clock source */ +#define LL_RCC_SPI4_CLKSOURCE_CSI LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI4SEL, RCC_CCIPR3_SPI4SEL_Pos, RCC_CCIPR3_SPI4SEL_2) /*!< CSI clock used as SPI4 clock source */ +#define LL_RCC_SPI4_CLKSOURCE_HSE LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI4SEL, RCC_CCIPR3_SPI4SEL_Pos, RCC_CCIPR3_SPI4SEL_2 | RCC_CCIPR3_SPI4SEL_0) /*!< HSE clock used as SPI4 clock source */ +#endif /* SPI4 */ + +#if defined(SPI5) +#define LL_RCC_SPI5_CLKSOURCE_PCLK3 LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI5SEL, RCC_CCIPR3_SPI5SEL_Pos, 0x00000000U) /*!< PCLK2 clock used as SPI5 clock source */ +#define LL_RCC_SPI5_CLKSOURCE_PLL2Q LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI5SEL, RCC_CCIPR3_SPI5SEL_Pos, RCC_CCIPR3_SPI5SEL_0) /*!< PLL2 Q clock used as SPI5 clock source */ +#define LL_RCC_SPI5_CLKSOURCE_PLL3Q LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI5SEL, RCC_CCIPR3_SPI5SEL_Pos, RCC_CCIPR3_SPI5SEL_1) /*!< PLL3 Q clock used as SPI5 clock source */ +#define LL_RCC_SPI5_CLKSOURCE_HSI LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI5SEL, RCC_CCIPR3_SPI5SEL_Pos, RCC_CCIPR3_SPI5SEL_1 | RCC_CCIPR3_SPI5SEL_0) /*!< HSI clock used as SPI5 clock source */ +#define LL_RCC_SPI5_CLKSOURCE_CSI LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI5SEL, RCC_CCIPR3_SPI5SEL_Pos, RCC_CCIPR3_SPI5SEL_2) /*!< CSI clock used as SPI5 clock source */ +#define LL_RCC_SPI5_CLKSOURCE_HSE LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI5SEL, RCC_CCIPR3_SPI5SEL_Pos, RCC_CCIPR3_SPI5SEL_2 | RCC_CCIPR3_SPI5SEL_0) /*!< HSE clock used as SPI5 clock source */ +#endif /* SPI5 */ + +#if defined(SPI6) +#define LL_RCC_SPI6_CLKSOURCE_PCLK2 LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI6SEL, RCC_CCIPR3_SPI6SEL_Pos, 0x00000000U) /*!< PCLK2 clock used as SPI6 clock source */ +#define LL_RCC_SPI6_CLKSOURCE_PLL2Q LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI6SEL, RCC_CCIPR3_SPI6SEL_Pos, RCC_CCIPR3_SPI6SEL_0) /*!< PLL2 Q clock used as SPI6 clock source */ +#define LL_RCC_SPI6_CLKSOURCE_PLL3Q LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI6SEL, RCC_CCIPR3_SPI6SEL_Pos, RCC_CCIPR3_SPI6SEL_1) /*!< PLL3 Q clock used as SPI6 clock source */ +#define LL_RCC_SPI6_CLKSOURCE_HSI LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI6SEL, RCC_CCIPR3_SPI6SEL_Pos, RCC_CCIPR3_SPI6SEL_1 | RCC_CCIPR3_SPI6SEL_0) /*!< HSI clock used as SPI6 clock source */ +#define LL_RCC_SPI6_CLKSOURCE_CSI LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI6SEL, RCC_CCIPR3_SPI6SEL_Pos, RCC_CCIPR3_SPI6SEL_2) /*!< CSI clock used as SPI6 clock source */ +#define LL_RCC_SPI6_CLKSOURCE_HSE LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI6SEL, RCC_CCIPR3_SPI6SEL_Pos, RCC_CCIPR3_SPI6SEL_2 | RCC_CCIPR3_SPI6SEL_0) /*!< HSE clock used as SPI6 clock source */ +#endif /* SPI6 */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_LPTIM_CLKSOURCE Peripheral LPTIMx clock source selection + * @{ + */ +#define LL_RCC_LPTIM1_CLKSOURCE_PCLK3 LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM1SEL, RCC_CCIPR2_LPTIM1SEL_Pos, 0x00000000U) /*!< PCLK3 clock used as LPTIM1 clock source */ +#define LL_RCC_LPTIM1_CLKSOURCE_PLL2P LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM1SEL, RCC_CCIPR2_LPTIM1SEL_Pos, RCC_CCIPR2_LPTIM1SEL_0) /*!< PLL2 P clock used as LPTIM1 clock source */ +#if defined(RCC_CR_PLL3ON) +#define LL_RCC_LPTIM1_CLKSOURCE_PLL3R LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM1SEL, RCC_CCIPR2_LPTIM1SEL_Pos, RCC_CCIPR2_LPTIM1SEL_1) /*!< PLL3 R clock used as LPTIM1 clock source */ +#endif /* PLL3 */ +#define LL_RCC_LPTIM1_CLKSOURCE_LSE LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM1SEL, RCC_CCIPR2_LPTIM1SEL_Pos, RCC_CCIPR2_LPTIM1SEL_0 | RCC_CCIPR2_LPTIM1SEL_1) /*!< LSE clock used as LPTIM1 clock source */ +#define LL_RCC_LPTIM1_CLKSOURCE_LSI LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM1SEL, RCC_CCIPR2_LPTIM1SEL_Pos, RCC_CCIPR2_LPTIM1SEL_2) /*!< LSI clock used as LPTIM1 clock source */ +#define LL_RCC_LPTIM1_CLKSOURCE_CLKP LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM1SEL, RCC_CCIPR2_LPTIM1SEL_Pos, RCC_CCIPR2_LPTIM1SEL_0 | RCC_CCIPR2_LPTIM1SEL_2) /*!< CLKP clock used as LPTIM1 clock source */ + +#define LL_RCC_LPTIM2_CLKSOURCE_PCLK1 LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM2SEL, RCC_CCIPR2_LPTIM2SEL_Pos, 0x00000000U) /*!< PCLK1 clock used as LPTIM2 clock source */ +#define LL_RCC_LPTIM2_CLKSOURCE_PLL2P LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM2SEL, RCC_CCIPR2_LPTIM2SEL_Pos, RCC_CCIPR2_LPTIM2SEL_0) /*!< PLL2 P clock used as LPTIM2 clock source */ +#if defined(RCC_CR_PLL3ON) +#define LL_RCC_LPTIM2_CLKSOURCE_PLL3R LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM2SEL, RCC_CCIPR2_LPTIM2SEL_Pos, RCC_CCIPR2_LPTIM2SEL_1) /*!< PLL3 R clock used as LPTIM2 clock source */ +#endif /* PLL3 */ +#define LL_RCC_LPTIM2_CLKSOURCE_LSE LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM2SEL, RCC_CCIPR2_LPTIM2SEL_Pos, RCC_CCIPR2_LPTIM2SEL_0 | RCC_CCIPR2_LPTIM2SEL_1) /*!< LSE clock used as LPTIM2 clock source */ +#define LL_RCC_LPTIM2_CLKSOURCE_LSI LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM2SEL, RCC_CCIPR2_LPTIM2SEL_Pos, RCC_CCIPR2_LPTIM2SEL_2) /*!< LSI clock used as LPTIM2 clock source */ +#define LL_RCC_LPTIM2_CLKSOURCE_CLKP LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM2SEL, RCC_CCIPR2_LPTIM2SEL_Pos, RCC_CCIPR2_LPTIM2SEL_0 | RCC_CCIPR2_LPTIM2SEL_2) /*!< CLKP clock used as LPTIM2 clock source */ + +#if defined(LPTIM3) +#define LL_RCC_LPTIM3_CLKSOURCE_PCLK3 LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM3SEL, RCC_CCIPR2_LPTIM3SEL_Pos, 0x00000000U) /*!< PCLK3 clock used as LPTIM3 clock source */ +#define LL_RCC_LPTIM3_CLKSOURCE_PLL2P LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM3SEL, RCC_CCIPR2_LPTIM3SEL_Pos, RCC_CCIPR2_LPTIM3SEL_0) /*!< PLL2 P clock used as LPTIM3 clock source */ +#define LL_RCC_LPTIM3_CLKSOURCE_PLL3R LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM3SEL, RCC_CCIPR2_LPTIM3SEL_Pos, RCC_CCIPR2_LPTIM3SEL_1) /*!< PLL3 R clock used as LPTIM3 clock source */ +#define LL_RCC_LPTIM3_CLKSOURCE_LSE LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM3SEL, RCC_CCIPR2_LPTIM3SEL_Pos, RCC_CCIPR2_LPTIM3SEL_0 | RCC_CCIPR2_LPTIM3SEL_1) /*!< LSE clock used as LPTIM3 clock source */ +#define LL_RCC_LPTIM3_CLKSOURCE_LSI LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM3SEL, RCC_CCIPR2_LPTIM3SEL_Pos, RCC_CCIPR2_LPTIM3SEL_2) /*!< LSI clock used as LPTIM3 clock source */ +#define LL_RCC_LPTIM3_CLKSOURCE_CLKP LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM3SEL, RCC_CCIPR2_LPTIM3SEL_Pos, RCC_CCIPR2_LPTIM3SEL_0 | RCC_CCIPR2_LPTIM3SEL_2) /*!< CLKP clock used as LPTIM3 clock source */ +#endif /* LPTIM3 */ + +#if defined(LPTIM4) +#define LL_RCC_LPTIM4_CLKSOURCE_PCLK3 LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM4SEL, RCC_CCIPR2_LPTIM4SEL_Pos, 0x00000000U) /*!< PCLK3 clock used as LPTIM4 clock source */ +#define LL_RCC_LPTIM4_CLKSOURCE_PLL2P LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM4SEL, RCC_CCIPR2_LPTIM4SEL_Pos, RCC_CCIPR2_LPTIM4SEL_0) /*!< PLL2 P clock used as LPTIM4 clock source */ +#define LL_RCC_LPTIM4_CLKSOURCE_PLL3R LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM4SEL, RCC_CCIPR2_LPTIM4SEL_Pos, RCC_CCIPR2_LPTIM4SEL_1) /*!< PLL3 R clock used as LPTIM4 clock source */ +#define LL_RCC_LPTIM4_CLKSOURCE_LSE LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM4SEL, RCC_CCIPR2_LPTIM4SEL_Pos, RCC_CCIPR2_LPTIM4SEL_0 | RCC_CCIPR2_LPTIM4SEL_1) /*!< LSE clock used as LPTIM4 clock source */ +#define LL_RCC_LPTIM4_CLKSOURCE_LSI LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM4SEL, RCC_CCIPR2_LPTIM4SEL_Pos, RCC_CCIPR2_LPTIM4SEL_2) /*!< LSI clock used as LPTIM4 clock source */ +#define LL_RCC_LPTIM4_CLKSOURCE_CLKP LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM4SEL, RCC_CCIPR2_LPTIM4SEL_Pos, RCC_CCIPR2_LPTIM4SEL_0 | RCC_CCIPR2_LPTIM4SEL_2) /*!< CLKP clock used as LPTIM4 clock source */ +#endif /* LPTIM4 */ + +#if defined(LPTIM5) +#define LL_RCC_LPTIM5_CLKSOURCE_PCLK3 LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM5SEL, RCC_CCIPR2_LPTIM5SEL_Pos, 0x00000000U) /*!< PCLK3 clock used as LPTIM5 clock source */ +#define LL_RCC_LPTIM5_CLKSOURCE_PLL2P LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM5SEL, RCC_CCIPR2_LPTIM5SEL_Pos, RCC_CCIPR2_LPTIM5SEL_0) /*!< PLL2 P clock used as LPTIM5 clock source */ +#define LL_RCC_LPTIM5_CLKSOURCE_PLL3R LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM5SEL, RCC_CCIPR2_LPTIM5SEL_Pos, RCC_CCIPR2_LPTIM5SEL_1) /*!< PLL3 R clock used as LPTIM5 clock source */ +#define LL_RCC_LPTIM5_CLKSOURCE_LSE LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM5SEL, RCC_CCIPR2_LPTIM5SEL_Pos, RCC_CCIPR2_LPTIM5SEL_0 | RCC_CCIPR2_LPTIM5SEL_1) /*!< LSE clock used as LPTIM5 clock source */ +#define LL_RCC_LPTIM5_CLKSOURCE_LSI LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM5SEL, RCC_CCIPR2_LPTIM5SEL_Pos, RCC_CCIPR2_LPTIM5SEL_2) /*!< LSI clock used as LPTIM5 clock source */ +#define LL_RCC_LPTIM5_CLKSOURCE_CLKP LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM5SEL, RCC_CCIPR2_LPTIM5SEL_Pos, RCC_CCIPR2_LPTIM5SEL_0 | RCC_CCIPR2_LPTIM5SEL_2) /*!< CLKP clock used as LPTIM5 clock source */ +#endif /* LPTIM5 */ + +#if defined(LPTIM6) +#define LL_RCC_LPTIM6_CLKSOURCE_PCLK3 LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM6SEL, RCC_CCIPR2_LPTIM6SEL_Pos, 0x00000000U) /*!< PCLK3 clock used as LPTIM6 clock source */ +#define LL_RCC_LPTIM6_CLKSOURCE_PLL2P LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM6SEL, RCC_CCIPR2_LPTIM6SEL_Pos, RCC_CCIPR2_LPTIM6SEL_0) /*!< PLL2 P clock used as LPTIM6 clock source */ +#define LL_RCC_LPTIM6_CLKSOURCE_PLL3R LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM6SEL, RCC_CCIPR2_LPTIM6SEL_Pos, RCC_CCIPR2_LPTIM6SEL_1) /*!< PLL3 R clock used as LPTIM6 clock source */ +#define LL_RCC_LPTIM6_CLKSOURCE_LSE LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM6SEL, RCC_CCIPR2_LPTIM6SEL_Pos, RCC_CCIPR2_LPTIM6SEL_0 | RCC_CCIPR2_LPTIM6SEL_1) /*!< LSE clock used as LPTIM6 clock source */ +#define LL_RCC_LPTIM6_CLKSOURCE_LSI LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM6SEL, RCC_CCIPR2_LPTIM6SEL_Pos, RCC_CCIPR2_LPTIM6SEL_2) /*!< LSI clock used as LPTIM6 clock source */ +#define LL_RCC_LPTIM6_CLKSOURCE_CLKP LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM6SEL, RCC_CCIPR2_LPTIM6SEL_Pos, RCC_CCIPR2_LPTIM6SEL_0 | RCC_CCIPR2_LPTIM6SEL_2) /*!< CLKP clock used as LPTIM6 clock source */ +#endif /* LPTIM6 */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_FDCAN_CLKSOURCE Peripheral FDCAN kernel clock source selection + * @{ + */ +#define LL_RCC_FDCAN_CLKSOURCE_HSE 0x00000000U /*!< HSE clock used as FDCAN kernel clock source */ +#define LL_RCC_FDCAN_CLKSOURCE_PLL1Q RCC_CCIPR5_FDCANSEL_0 /*!< PLL1 Q clock used as FDCAN kernel clock source */ +#define LL_RCC_FDCAN_CLKSOURCE_PLL2Q RCC_CCIPR5_FDCANSEL_1 /*!< PLL2 Q clock used as FDCAN kernel clock source */ +#define LL_RCC_FDCAN_CLKSOURCE_NONE RCC_CCIPR5_FDCANSEL /*!< NO clock used as FDCAN kernel clock source */ +/** + * @} + */ + +#if defined(SAI1) +/** @defgroup RCC_LL_EC_SAI_CLKSOURCE Peripheral SAIx clock source selection + * @{ + */ +#define LL_RCC_SAI1_CLKSOURCE_PLL1Q LL_CLKSOURCE(CCIPR5_OFFSET, RCC_CCIPR5_SAI1SEL, RCC_CCIPR5_SAI1SEL_Pos, 0x00000000U) /*!< PLL1 Q clock used as SAI1 clock source */ +#define LL_RCC_SAI1_CLKSOURCE_PLL2P LL_CLKSOURCE(CCIPR5_OFFSET, RCC_CCIPR5_SAI1SEL, RCC_CCIPR5_SAI1SEL_Pos, RCC_CCIPR5_SAI1SEL_0) /*!< PLL2 P clock used as SAI1 clock source */ +#define LL_RCC_SAI1_CLKSOURCE_PLL3P LL_CLKSOURCE(CCIPR5_OFFSET, RCC_CCIPR5_SAI1SEL, RCC_CCIPR5_SAI1SEL_Pos, RCC_CCIPR5_SAI1SEL_1) /*!< PLL3 P clock used as SAI1 clock source */ +#define LL_RCC_SAI1_CLKSOURCE_PIN LL_CLKSOURCE(CCIPR5_OFFSET, RCC_CCIPR5_SAI1SEL, RCC_CCIPR5_SAI1SEL_Pos, RCC_CCIPR5_SAI1SEL_1 | RCC_CCIPR5_SAI1SEL_0) /*!< External input clock used as SAI1 clock source */ +#define LL_RCC_SAI1_CLKSOURCE_CLKP LL_CLKSOURCE(CCIPR5_OFFSET, RCC_CCIPR5_SAI1SEL, RCC_CCIPR5_SAI1SEL_Pos, RCC_CCIPR5_SAI1SEL_2) /*!< CLKP clock used as SAI1 clock source */ + +#define LL_RCC_SAI2_CLKSOURCE_PLL1Q LL_CLKSOURCE(CCIPR5_OFFSET, RCC_CCIPR5_SAI2SEL, RCC_CCIPR5_SAI2SEL_Pos, 0x00000000U) /*!< PLL1 Q clock used as SAI2 clock source */ +#define LL_RCC_SAI2_CLKSOURCE_PLL2P LL_CLKSOURCE(CCIPR5_OFFSET, RCC_CCIPR5_SAI2SEL, RCC_CCIPR5_SAI2SEL_Pos, RCC_CCIPR5_SAI2SEL_0) /*!< PLL2 P clock used as SAI2 clock source */ +#define LL_RCC_SAI2_CLKSOURCE_PLL3P LL_CLKSOURCE(CCIPR5_OFFSET, RCC_CCIPR5_SAI2SEL, RCC_CCIPR5_SAI2SEL_Pos, RCC_CCIPR5_SAI2SEL_1) /*!< PLL3 P clock used as SAI2 clock source */ +#define LL_RCC_SAI2_CLKSOURCE_PIN LL_CLKSOURCE(CCIPR5_OFFSET, RCC_CCIPR5_SAI2SEL, RCC_CCIPR5_SAI2SEL_Pos, RCC_CCIPR5_SAI2SEL_1 | RCC_CCIPR5_SAI2SEL_0) /*!< External input clock used as SAI2 clock source */ +#define LL_RCC_SAI2_CLKSOURCE_CLKP LL_CLKSOURCE(CCIPR5_OFFSET, RCC_CCIPR5_SAI2SEL, RCC_CCIPR5_SAI2SEL_Pos, RCC_CCIPR5_SAI2SEL_2) /*!< CLKP clock used as SAI2 clock source */ +/** + * @} + */ +#endif /* SAI1 */ + +#if defined(SDMMC1) +/** @defgroup RCC_LL_EC_SDMMC_CLKSOURCE Peripheral SDMMCx kernel clock source selection + * @{ + */ +#define LL_RCC_SDMMC1_CLKSOURCE_PLL1Q LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_SDMMC1SEL, RCC_CCIPR4_SDMMC1SEL_Pos, 0x00000000U) /*!< PLL1 Q used as SDMMC1 clock source */ +#define LL_RCC_SDMMC1_CLKSOURCE_PLL2R LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_SDMMC1SEL, RCC_CCIPR4_SDMMC1SEL_Pos, RCC_CCIPR4_SDMMC1SEL) /*!< PLL2 R used as SDMMC1 clock source */ +#if defined(SDMMC2) +#define LL_RCC_SDMMC2_CLKSOURCE_PLL1Q LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_SDMMC2SEL, RCC_CCIPR4_SDMMC2SEL_Pos, 0x00000000U) /*!< PLL1 Q used as SDMMC2 clock source */ +#define LL_RCC_SDMMC2_CLKSOURCE_PLL2R LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_SDMMC2SEL, RCC_CCIPR4_SDMMC2SEL_Pos, RCC_CCIPR4_SDMMC2SEL) /*!< PLL2 R used as SDMMC2 clock source */ +#endif /*SDMMC2*/ +/** + * @} + */ +#endif /* SDMMC1 */ + +/** @defgroup RCC_LL_EC_RNG_CLKSOURCE Peripheral RNG clock source selection + * @{ + */ +#define LL_RCC_RNG_CLKSOURCE_HSI48 0x00000000U /*!< HSI48 clock used as RNG clock source */ +#define LL_RCC_RNG_CLKSOURCE_PLL1Q RCC_CCIPR5_RNGSEL_0 /*!< PLL1 Q clock used as RNG clock source */ +#define LL_RCC_RNG_CLKSOURCE_LSE RCC_CCIPR5_RNGSEL_1 /*!< LSE clock used as RNG clock source */ +#define LL_RCC_RNG_CLKSOURCE_LSI RCC_CCIPR5_RNGSEL /*!< LSI clock used as RNG clock source */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_USB_CLKSOURCE Peripheral USB clock source selection + * @{ + */ +#define LL_RCC_USB_CLKSOURCE_NONE 0x00000000U /*!< No clock used as USB clock source */ +#define LL_RCC_USB_CLKSOURCE_PLL1Q RCC_CCIPR4_USBSEL_0 /*!< PLL1 Q clock used as USB clock source */ +#if defined(RCC_CR_PLL3ON) +#define LL_RCC_USB_CLKSOURCE_PLL3Q RCC_CCIPR4_USBSEL_1 /*!< PLL3 Q clock used as USB clock source */ +#endif /* PLL3 */ +#define LL_RCC_USB_CLKSOURCE_HSI48 RCC_CCIPR4_USBSEL /*!< HSI48 clock used as USB clock source */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_ADCDAC_CLKSOURCE Peripheral ADCDAC clock source selection + * @{ + */ +#define LL_RCC_ADCDAC_CLKSOURCE_HCLK 0x00000000U /*!< AHB clock used as ADCDAC clock source */ +#define LL_RCC_ADCDAC_CLKSOURCE_SYSCLK RCC_CCIPR5_ADCDACSEL_0 /*!< SYSCLK clock used as ADCDAC clock source */ +#define LL_RCC_ADCDAC_CLKSOURCE_PLL2R RCC_CCIPR5_ADCDACSEL_1 /*!< PLL2 R clock used as ADCDAC clock source */ +#define LL_RCC_ADCDAC_CLKSOURCE_HSE (RCC_CCIPR5_ADCDACSEL_0 | RCC_CCIPR5_ADCDACSEL_1) /*!< HSE clock used as ADCDAC clock source */ +#define LL_RCC_ADCDAC_CLKSOURCE_HSI RCC_CCIPR5_ADCDACSEL_2 /*!< HSI clock used as ADCDAC clock source */ +#define LL_RCC_ADCDAC_CLKSOURCE_CSI (RCC_CCIPR5_ADCDACSEL_0 | RCC_CCIPR5_ADCDACSEL_2) /*!< CSI clock used as ADCDAC clock source */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_DAC_CLKSOURCE Peripheral DAC low-power clock source selection + * @{ + */ +#define LL_RCC_DAC_LP_CLKSOURCE_LSE 0x00000000U /*!< LSE clock used as DAC low-power clock */ +#define LL_RCC_DAC_LP_CLKSOURCE_LSI RCC_CCIPR5_DACSEL /*!< LSI clock used as DAC low-power clock */ +/** + * @} + */ + +#if defined(CEC) +/** @defgroup RCC_LL_EC_CEC_CLKSOURCE Peripheral CEC clock source selection + * @{ + */ +#define LL_RCC_CEC_CLKSOURCE_LSE 0x00000000U /*!< LSE clock used as CEC clock */ +#define LL_RCC_CEC_CLKSOURCE_LSI RCC_CCIPR5_CECSEL_0 /*!< LSI clock used as CEC clock */ +#define LL_RCC_CEC_CLKSOURCE_CSI_DIV122 RCC_CCIPR5_CECSEL_1 /*!< CSI clock divied by 122 used as CEC clock */ +#define LL_RCC_CEC_CLKSOURCE_NONE RCC_CCIPR5_CECSEL /*!< NO clock used as CEC clock source */ +/** + * @} + */ +#endif /* CEC */ + +#if defined(OCTOSPI1) +/** @defgroup RCC_LL_EC_OCTOSPI_CLKSOURCE Peripheral OCTOSPI kernel clock source selection + * @{ + */ +#define LL_RCC_OSPI_CLKSOURCE_HCLK 0x00000000U /*!< AHB clock used as OctoSPI kernel clock source */ +#define LL_RCC_OSPI_CLKSOURCE_PLL1Q RCC_CCIPR4_OCTOSPISEL_0 /*!< PLL1 Q clock used as OctoSPI kernel clock source */ +#define LL_RCC_OSPI_CLKSOURCE_PLL2R RCC_CCIPR4_OCTOSPISEL_1 /*!< PLL2 R clock used as OctoSPI kernel clock source */ +#define LL_RCC_OSPI_CLKSOURCE_CLKP RCC_CCIPR4_OCTOSPISEL /*!< CLKP clock used as OctoSPI clock source */ +/** + * @} + */ +#endif /* OCTOSPI1 */ + +/** @defgroup RCC_LL_EC_CLKP_CLKSOURCE Peripheral CLKP clock source selection + * @{ + */ +#define LL_RCC_CLKP_CLKSOURCE_HSI 0x00000000U /*!< HSI clock used as CLKP clock source */ +#define LL_RCC_CLKP_CLKSOURCE_CSI RCC_CCIPR5_CKERPSEL_0 /*!< CSI clock used as CLKP clock source */ +#define LL_RCC_CLKP_CLKSOURCE_HSE RCC_CCIPR5_CKERPSEL_1 /*!< HSE clock used as CLKP clock source */ +#define LL_RCC_CLKP_CLKSOURCE_NONE RCC_CCIPR5_CKERPSEL /*!< No clock selected as CLKP clock source */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_USART Peripheral USARTx get clock source + * @{ + */ +#define LL_RCC_USART1_CLKSOURCE LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART1SEL, RCC_CCIPR1_USART1SEL_Pos, 0x00000000U) /*!< USART1 Clock source selection */ +#define LL_RCC_USART2_CLKSOURCE LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART2SEL, RCC_CCIPR1_USART2SEL_Pos, 0x00000000U) /*!< USART2 Clock source selection */ +#define LL_RCC_USART3_CLKSOURCE LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART3SEL, RCC_CCIPR1_USART3SEL_Pos, 0x00000000U) /*!< USART3 Clock source selection */ +#if defined(USART6) +#define LL_RCC_USART6_CLKSOURCE LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART6SEL, RCC_CCIPR1_USART6SEL_Pos, 0x00000000U) /*!< USART6 Clock source selection */ +#endif /* USART6 */ +#if defined(USART10) +#define LL_RCC_USART10_CLKSOURCE LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_USART10SEL, RCC_CCIPR1_USART10SEL_Pos, 0x00000000U) /*!< USART10 Clock source selection */ +#endif /* USART10 */ +#if defined(USART11) +#define LL_RCC_USART11_CLKSOURCE LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_USART11SEL, RCC_CCIPR2_USART11SEL_Pos, 0x00000000U) /*!< USART11 Clock source selection */ +#endif /* USART11 */ +/** + * @} + */ + +#if defined(UART4) +/** @defgroup RCC_LL_EC_UART Peripheral UARTx get clock source + * @{ + */ +#define LL_RCC_UART4_CLKSOURCE LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART4SEL, RCC_CCIPR1_UART4SEL_Pos, 0x00000000U) /*!< UART4 Clock source selection */ +#define LL_RCC_UART5_CLKSOURCE LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART5SEL, RCC_CCIPR1_UART5SEL_Pos, 0x00000000U) /*!< UART5 Clock source selection */ +#define LL_RCC_UART7_CLKSOURCE LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART7SEL, RCC_CCIPR1_UART7SEL_Pos, 0x00000000U) /*!< UART7 Clock source selection */ +#define LL_RCC_UART8_CLKSOURCE LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART8SEL, RCC_CCIPR1_UART8SEL_Pos, 0x00000000U) /*!< UART8 Clock source selection */ +#define LL_RCC_UART9_CLKSOURCE LL_CLKSOURCE(CCIPR1_OFFSET, RCC_CCIPR1_UART9SEL, RCC_CCIPR1_UART9SEL_Pos, 0x00000000U) /*!< UART9 Clock source selection */ +#define LL_RCC_UART12_CLKSOURCE LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_UART12SEL, RCC_CCIPR2_UART12SEL_Pos, 0x00000000U) /*!< UART12 Clock source selection */ +/** + * @} + */ +#endif /*UART4*/ + +/** @defgroup RCC_LL_EC_SPI Peripheral SPIx get clock source + * @{ + */ +#define LL_RCC_SPI1_CLKSOURCE LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI1SEL, RCC_CCIPR3_SPI1SEL_Pos, 0x00000000U) /*!< SPI1 Clock source selection */ +#define LL_RCC_SPI2_CLKSOURCE LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI2SEL, RCC_CCIPR3_SPI2SEL_Pos, 0x00000000U) /*!< SPI2 Clock source selection */ +#define LL_RCC_SPI3_CLKSOURCE LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI3SEL, RCC_CCIPR3_SPI3SEL_Pos, 0x00000000U) /*!< SPI3 Clock source selection */ +#if defined(SPI4) +#define LL_RCC_SPI4_CLKSOURCE LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI4SEL, RCC_CCIPR3_SPI4SEL_Pos, 0x00000000U) /*!< SPI4 Clock source selection */ +#endif /* SPI4 */ +#if defined(SPI5) +#define LL_RCC_SPI5_CLKSOURCE LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI5SEL, RCC_CCIPR3_SPI5SEL_Pos, 0x00000000U) /*!< SPI5 Clock source selection */ +#endif /* SPI5 */ +#if defined(SPI6) +#define LL_RCC_SPI6_CLKSOURCE LL_CLKSOURCE(CCIPR3_OFFSET, RCC_CCIPR3_SPI6SEL, RCC_CCIPR3_SPI6SEL_Pos, 0x00000000U) /*!< SPI6 Clock source selection */ +#endif /* SPI6 */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_LPUART Peripheral LPUARTx get clock source + * @{ + */ +#define LL_RCC_LPUART1_CLKSOURCE RCC_CCIPR3_LPUART1SEL /*!< LPUART1 Clock source selection */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_I2C Peripheral I2Cx get clock source + * @{ + */ +#define LL_RCC_I2C1_CLKSOURCE LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I2C1SEL, RCC_CCIPR4_I2C1SEL_Pos, 0x00000000U) /*!< I2C1 Clock source selection */ +#define LL_RCC_I2C2_CLKSOURCE LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I2C2SEL, RCC_CCIPR4_I2C2SEL_Pos, 0x00000000U) /*!< I2C2 Clock source selection */ +#if defined(I2C3) +#define LL_RCC_I2C3_CLKSOURCE LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I2C3SEL, RCC_CCIPR4_I2C3SEL_Pos, 0x00000000U) /*!< I2C3 Clock source selection */ +#endif /* I2C3 */ +#if defined(I2C4) +#define LL_RCC_I2C4_CLKSOURCE LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I2C4SEL, RCC_CCIPR4_I2C4SEL_Pos, 0x00000000U) /*!< I2C4 Clock source selection */ +#endif /* I2C4 */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_I3C Peripheral I3Cx get clock source + * @{ + */ +#define LL_RCC_I3C1_CLKSOURCE LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I3C1SEL, RCC_CCIPR4_I3C1SEL_Pos, 0x00000000U) /*!< I3C1 Clock source selection */ +#if defined(I3C2) +#define LL_RCC_I3C2_CLKSOURCE LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_I3C2SEL, RCC_CCIPR4_I3C2SEL_Pos, 0x00000000U) /*!< I3C2 Clock source selection */ +#endif /* I3C2 */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_LPTIM Peripheral LPTIMx get clock source + * @{ + */ +#define LL_RCC_LPTIM1_CLKSOURCE LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM1SEL, RCC_CCIPR2_LPTIM1SEL_Pos, 0x00000000U) /*!< LPTIM1 Clock source selection */ +#define LL_RCC_LPTIM2_CLKSOURCE LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM2SEL, RCC_CCIPR2_LPTIM2SEL_Pos, 0x00000000U) /*!< LPTIM2 Clock source selection */ +#if defined(LPTIM3) +#define LL_RCC_LPTIM3_CLKSOURCE LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM3SEL, RCC_CCIPR2_LPTIM3SEL_Pos, 0x00000000U) /*!< LPTIM3 Clock source selection */ +#endif /* LPTIM3 */ +#if defined(LPTIM4) +#define LL_RCC_LPTIM4_CLKSOURCE LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM4SEL, RCC_CCIPR2_LPTIM4SEL_Pos, 0x00000000U) /*!< LPTIM4 Clock source selection */ +#endif /* LPTIM4 */ +#if defined(LPTIM5) +#define LL_RCC_LPTIM5_CLKSOURCE LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM5SEL, RCC_CCIPR2_LPTIM5SEL_Pos, 0x00000000U) /*!< LPTIM5 Clock source selection */ +#endif /* LPTIM5 */ +#if defined(LPTIM6) +#define LL_RCC_LPTIM6_CLKSOURCE LL_CLKSOURCE(CCIPR2_OFFSET, RCC_CCIPR2_LPTIM6SEL, RCC_CCIPR2_LPTIM6SEL_Pos, 0x00000000U) /*!< LPTIM6 Clock source selection */ +#endif /* LPTIM6 */ +/** + * @} + */ + +#if defined(SAI1) +/** @defgroup RCC_LL_EC_SAI Peripheral SAIx get clock source + * @{ + */ +#define LL_RCC_SAI1_CLKSOURCE LL_CLKSOURCE(CCIPR5_OFFSET, RCC_CCIPR5_SAI1SEL, RCC_CCIPR5_SAI1SEL_Pos, 0x00000000U) /*!< SAI1 Clock source selection */ +#define LL_RCC_SAI2_CLKSOURCE LL_CLKSOURCE(CCIPR5_OFFSET, RCC_CCIPR5_SAI2SEL, RCC_CCIPR5_SAI2SEL_Pos, 0x00000000U) /*!< SAI2 Clock source selection */ +/** + * @} + */ +#endif /* SAI1 */ + +#if defined(SDMMC1) +/** @defgroup RCC_LL_EC_SDMMC Peripheral SDMMC get clock source + * @{ + */ +#define LL_RCC_SDMMC1_CLKSOURCE LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_SDMMC1SEL, RCC_CCIPR4_SDMMC1SEL_Pos, 0x00000000U) /*!< SDMMC1 Kernel Clock source selection */ +#if defined(SDMMC2) +#define LL_RCC_SDMMC2_CLKSOURCE LL_CLKSOURCE(CCIPR4_OFFSET, RCC_CCIPR4_SDMMC2SEL, RCC_CCIPR4_SDMMC2SEL_Pos, 0x00000000U) /*!< SDMMC2 Kernel Clock source selection */ +#endif /*SDMMC2*/ +/** + * @} + */ +#endif /* SDMMC1 */ + +/** @defgroup RCC_LL_EC_RNG Peripheral RNG get clock source + * @{ + */ +#define LL_RCC_RNG_CLKSOURCE RCC_CCIPR5_RNGSEL /*!< RNG Clock source selection */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_USB Peripheral USB get clock source + * @{ + */ +#define LL_RCC_USB_CLKSOURCE RCC_CCIPR4_USBSEL /*!< USB Clock source selection */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_ADCDAC Peripheral ADCDAC get clock source + * @{ + */ +#define LL_RCC_ADCDAC_CLKSOURCE RCC_CCIPR5_ADCDACSEL /*!< ADCDACs Clock source selection */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_DAC Peripheral DAC get low-power clock source + * @{ + */ +#define LL_RCC_DAC_LP_CLKSOURCE RCC_CCIPR5_DACSEL /*!< DAC low-power Clock source selection */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_CEC Peripheral CEC get clock source + * @{ + */ +#define LL_RCC_CEC_CLKSOURCE RCC_CCIPR5_CECSEL +/** + * @} + */ + +/** @defgroup RCC_LL_EC_FDCAN Peripheral FDCAN get kernel clock source + * @{ + */ +#define LL_RCC_FDCAN_CLKSOURCE RCC_CCIPR5_FDCANSEL /*!< FDCAN kernel Clock source selection */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_OCTOSPI Peripheral OCTOSPI get clock source + * @{ + */ +#define LL_RCC_OCTOSPI_CLKSOURCE RCC_CCIPR4_OCTOSPISEL /*!< OctoSPI Clock source selection */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_CLKP Peripheral CLKP get clock source + * @{ + */ +#define LL_RCC_CLKP_CLKSOURCE RCC_CCIPR5_CKERPSEL /*!< CLKP Clock source selection */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_PLL1SOURCE PLL1 entry clock source + * @{ + */ +#define LL_RCC_PLL1SOURCE_NONE 0x00000000U /*!< No clock selected as main PLL1 entry clock source */ +#define LL_RCC_PLL1SOURCE_HSI RCC_PLL1CFGR_PLL1SRC_0 /*!< HSI clock selected as main PLL1 entry clock source */ +#define LL_RCC_PLL1SOURCE_CSI RCC_PLL1CFGR_PLL1SRC_1 /*!< CSI clock selected as main PLL1 entry clock source */ +#define LL_RCC_PLL1SOURCE_HSE (RCC_PLL1CFGR_PLL1SRC_0 | RCC_PLL1CFGR_PLL1SRC_1) /*!< HSE clock selected as main PLL1 entry clock source */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_PLLINPUTRANGE All PLLs input ranges + * @{ + */ +#define LL_RCC_PLLINPUTRANGE_1_2 0x00000000U /*!< VCO input range: 1 to 2 MHz */ +#define LL_RCC_PLLINPUTRANGE_2_4 0x00000001U /*!< VCO input range: 2 to 4 MHz */ +#define LL_RCC_PLLINPUTRANGE_4_8 0x00000002U /*!< VCO input range: 4 to 8 MHz */ +#define LL_RCC_PLLINPUTRANGE_8_16 0x00000003U /*!< VCO input range: 8 to 16 MHz */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_PLLOUTPUTRANGE All PLLs output ranges + * @{ + */ +#define LL_RCC_PLLVCORANGE_WIDE 0x00000000U /*!< VCO output range: 192 to 836 MHz */ +#define LL_RCC_PLLVCORANGE_MEDIUM 0x00000001U /*!< VCO output range: 150 to 420 MHz */ + +/** + * @} + */ + +/** @defgroup RCC_LL_EC_PLL2SOURCE PLL2 entry clock source + * @{ + */ +#define LL_RCC_PLL2SOURCE_NONE 0x00000000U /*!< No clock selected as main PLL2 entry clock source */ +#define LL_RCC_PLL2SOURCE_HSI RCC_PLL2CFGR_PLL2SRC_0 /*!< HSI clock selected as main PLL2 entry clock source */ +#define LL_RCC_PLL2SOURCE_CSI RCC_PLL2CFGR_PLL2SRC_1 /*!< CSI clock selected as main PLL2 entry clock source */ +#define LL_RCC_PLL2SOURCE_HSE (RCC_PLL2CFGR_PLL2SRC_0 | RCC_PLL2CFGR_PLL2SRC_1) /*!< HSE clock selected as main PLL2 entry clock source */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_PLL3SOURCE PLL3 entry clock source + * @{ + */ +#define LL_RCC_PLL3SOURCE_NONE 0x00000000U /*!< No clock selected as main PLL3 entry clock source */ +#define LL_RCC_PLL3SOURCE_HSI RCC_PLL3CFGR_PLL3SRC_0 /*!< HSI clock selected as main PLL3 entry clock source */ +#define LL_RCC_PLL3SOURCE_CSI RCC_PLL3CFGR_PLL3SRC_1 /*!< CSI clock selected as main PLL3 entry clock source */ +#define LL_RCC_PLL3SOURCE_HSE (RCC_PLL3CFGR_PLL3SRC_0 | RCC_PLL3CFGR_PLL3SRC_1) /*!< HSE clock selected as main PLL3 entry clock source */ +/** + * @} + */ + +#if defined(RCC_SECCFGR_HSISEC) +/** @defgroup RCC_LL_EC_SECURE_ATTRIBUTES Secure attributes + * @note Only available when system implements security (TZEN=1) + * @{ + */ +#define LL_RCC_ALL_SEC RCC_SECURE_MASK /*!< Security on all RCC resources */ +#define LL_RCC_ALL_NSEC 0U /*!< No security on RCC resources (default) */ + +#define LL_RCC_HSI_SEC RCC_SECCFGR_HSISEC /*!< HSI clock configuration secure-only access */ +#define LL_RCC_HSI_NSEC 0U /*!< HSI clock configuration secure/non-secure access */ +#define LL_RCC_HSE_SEC RCC_SECCFGR_HSESEC /*!< HSE clock configuration secure-only access */ +#define LL_RCC_HSE_NSEC 0U /*!< HSE clock configuration secure/non-secure access */ +#define LL_RCC_CSI_SEC RCC_SECCFGR_CSISEC /*!< CSI clock configuration secure-only access */ +#define LL_RCC_CSI_NSEC 0U /*!< CSI clock configuration secure/non-secure access */ +#define LL_RCC_LSI_SEC RCC_SECCFGR_LSISEC /*!< LSI clock configuration secure-only access */ +#define LL_RCC_LSI_NSEC 0U /*!< LSI clock configuration secure/non-secure access */ +#define LL_RCC_LSE_SEC RCC_SECCFGR_LSESEC /*!< LSE clock configuration secure-only access */ +#define LL_RCC_LSE_NSEC 0U /*!< LSE clock configuration secure/non-secure access */ +#define LL_RCC_SYSCLK_SEC RCC_SECCFGR_SYSCLKSEC /*!< SYSCLK clock; STOPWUCK and MCO output configuration secure-only access */ +#define LL_RCC_SYSCLK_NSEC 0U /*!< SYSCLK clock; STOPWUCK and MCO output configuration secure/non-secure access */ +#define LL_RCC_PRESCALERS_SEC RCC_SECCFGR_PRESCSEC /*!< AHBx/APBx prescaler configuration secure-only access */ +#define LL_RCC_PRESCALERS_NSEC 0U /*!< AHBx/APBx prescaler configuration secure/non-secure access */ +#define LL_RCC_PLL1_SEC RCC_SECCFGR_PLL1SEC /*!< main PLL clock configuration secure-only access */ +#define LL_RCC_PLL1_NSEC 0U /*!< main PLL clock configuration secure/non-secure access */ +#define LL_RCC_PLL2_SEC RCC_SECCFGR_PLL2SEC /*!< PLL2 clock configuration secure-only access */ +#define LL_RCC_PLL2_NSEC 0U /*!< PLL2 clock configuration secure/non-secure access */ +#define LL_RCC_PLL3_SEC RCC_SECCFGR_PLL3SEC /*!< PLL3 clock configuration secure-only access */ +#define LL_RCC_PLL3_NSEC 0U /*!< PLL3 clock configuration secure/non-secure access */ +#define LL_RCC_HSI48_SEC RCC_SECCFGR_HSI48SEC /*!< HSI48 clock configuration secure-only access */ +#define LL_RCC_HSI48_NSEC 0U /*!< HSI48 clock configuration secure/non-secure access */ +#define LL_RCC_RESET_FLAGS_SEC RCC_SECCFGR_RMVFSEC /*!< Remove reset flag secure-ony access */ +#define LL_RCC_RESET_FLAGS_NSEC 0U /*!< Remove reset flag secure/non-secure access */ +#define LL_RCC_CKPERSEL_SEC RCC_SECCFGR_CKPERSELSEC /*!< Periph clock configuration secure-ony access */ +#define LL_RCC_CKPERSEL_NSEC 0U /*!< Periph clock configuration secure/non-secure access */ +/** + * @} + */ +#endif /* RCC_SECCFGR_HSISEC */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup RCC_LL_Exported_Macros RCC Exported Macros + * @{ + */ + +/** @defgroup RCC_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in RCC register + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_RCC_WriteReg(__REG__, __VALUE__) WRITE_REG(RCC->__REG__, (__VALUE__)) + +/** + * @brief Read a value in RCC register + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_RCC_ReadReg(__REG__) READ_REG(RCC->__REG__) +/** + * @} + */ + +/** @defgroup RCC_LL_EM_CALC_FREQ Calculate frequencies + * @{ + */ + +/** + * @brief Helper macro to calculate the PLL1P clock frequency + * @note ex: @ref __LL_RCC_CALC_PLL1CLK_P_FREQ (HSE_VALUE,@ref LL_RCC_PLL1_GetM (), + * @ref LL_RCC_PLL1_GetN (), @ref LL_RCC_PLL1_GetP ()); + * @param __INPUTFREQ__ PLL1 Input frequency (based on HSI/HSE/CSI) + * @param __PLL1M__ parameter can be a value between 1 and 63 + * @param __PLL1N__ parameter can be a value between 4 and 512 + * @param __PLL1P__ parameter can be a value between 1 and 128 (odd values not allowed) + * @retval PLL1P clock frequency (in Hz) + */ + +#define __LL_RCC_CALC_PLL1CLK_P_FREQ(__INPUTFREQ__, __PLL1M__, __PLL1N__, __PLL1P__) \ + ((((__INPUTFREQ__) /(__PLL1M__)) * (__PLL1N__)) / (__PLL1P__)) + +/** + * @brief Helper macro to calculate the PLL1Q clock frequency + * @note ex: @ref __LL_RCC_CALC_PLL1CLK_Q_FREQ (HSE_VALUE,@ref LL_RCC_PLL1_GetM (), + * @ref LL_RCC_PLL1_GetN (), @ref LL_RCC_PLL1_GetQ ()); + * @param __INPUTFREQ__ PLL1 Input frequency (based on HSI/HSE/CSI) + * @param __PLL1M__ parameter can be a value between 1 and 63 + * @param __PLL1N__ parameter can be a value between 4 and 512 + * @param __PLL1Q__ parameter can be a value between 2 and 128 + * @retval PLL1Q clock frequency (in Hz) + */ +#define __LL_RCC_CALC_PLL1CLK_Q_FREQ(__INPUTFREQ__, __PLL1M__, __PLL1N__, __PLL1Q__) \ + ((((__INPUTFREQ__) /(__PLL1M__)) * (__PLL1N__)) / (__PLL1Q__)) + +/** + * @brief Helper macro to calculate the PLL1R clock frequency + * @note ex: @ref __LL_RCC_CALC_PLL1CLK_R_FREQ (HSE_VALUE,@ref LL_RCC_PLL1_GetM (), + * @ref LL_RCC_PLL1_GetN (), @ref LL_RCC_PLL1_GetN ()); + * @param __INPUTFREQ__ PLL1 Input frequency (based on HSI/HSE/CSI) + * @param __PLL1M__ parameter can be a value between 1 and 63 + * @param __PLL1N__ parameter can be a value between 4 and 512 + * @param __PLL1R__ parameter can be a value between 1 and 128 + * @retval PLL1R clock frequency (in Hz) + */ + +#define __LL_RCC_CALC_PLL1CLK_R_FREQ(__INPUTFREQ__, __PLL1M__, __PLL1N__, __PLL1R__) \ + ((((__INPUTFREQ__) /(__PLL1M__)) * (__PLL1N__)) / (__PLL1R__)) + +/** + * @brief Helper macro to calculate the PLL2P clock frequency + * @note ex: @ref __LL_RCC_CALC_PLL2CLK_P_FREQ (HSE_ALUE,@ref LL_RCC_PLL2_GetM (), + * @ref LL_RCC_PLL2_GetN (), @ref LL_RCC_PLL2_GetP ()); + * @param __INPUTFREQ__ PLL Input frequency (based on HSI/HSE/CSI) + * @param __PLL2M__ parameter can be a value between 1 and 63 + * @param __PLL2N__ parameter can be a value between 4 and 512 + * @param __PLL2P__ parameter can be a value between 2 and 128 + * @retval PLL2P clock frequency (in Hz) + */ +#define __LL_RCC_CALC_PLL2CLK_P_FREQ(__INPUTFREQ__, __PLL2M__, __PLL2N__, __PLL2P__) \ + ((((__INPUTFREQ__) /(__PLL2M__)) * (__PLL2N__)) / (__PLL2P__)) + +/** + * @brief Helper macro to calculate the PLL2Q clock frequency + * @note ex: @ref __LL_RCC_CALC_PLL2CLK_Q_FREQ (HSE_VALUE,@ref LL_RCC_PLL2_GetM (), + * @ref LL_RCC_PLL2_GetN (), @ref LL_RCC_PLL2_GetQ ()); + * @param __INPUTFREQ__ PLL Input frequency (based on HSI/HSE/CSI) + * @param __PLL2M__ parameter can be a value between 1 and 63 + * @param __PLL2N__ parameter can be a value between 4 and 512 + * @param __PLL2Q__ parameter can be a value between 1 and 128 + * @retval PLL2Q clock frequency (in Hz) + */ +#define __LL_RCC_CALC_PLL2CLK_Q_FREQ(__INPUTFREQ__, __PLL2M__, __PLL2N__, __PLL2Q__) \ + ((((__INPUTFREQ__) /(__PLL2M__)) * (__PLL2N__)) / (__PLL2Q__)) + +/** + * @brief Helper macro to calculate the PLL2R clock frequency + * @note ex: @ref __LL_RCC_CALC_PLL2CLK_R_FREQ (HSE_VALUE,@ref LL_RCC_PLL2_GetM (), + * @ref LL_RCC_PLL2_GetN (), @ref LL_RCC_PLL2_GetR ()); + * @param __INPUTFREQ__ PLL2 Input frequency (based on HSI/HSE/CSI) + * @param __PLL2M__ parameter can be a value between 1 and 63 + * @param __PLL2N__ parameter can be a value between 4 and 512 + * @param __PLL2R__ parameter can be a value between 1 and 128 + * @retval PLL2R clock frequency (in Hz) + */ +#define __LL_RCC_CALC_PLL2CLK_R_FREQ(__INPUTFREQ__, __PLL2M__, __PLL2N__, __PLL2R__) \ + ((((__INPUTFREQ__) /(__PLL2M__)) * (__PLL2N__)) / (__PLL2R__)) + +/** + * @brief Helper macro to calculate the PLL3P clock frequency + * @note ex: @ref __LL_RCC_CALC_PLL3CLK_P_FREQ (HSE_VALUE,@ref LL_RCC_PLL3_GetM (), + * @ref LL_RCC_PLL3_GetN (), @ref LL_RCC_PLL3_GetP ()); + * @param __INPUTFREQ__ PLL3 Input frequency (based on HSI/HSE/CSI) + * @param __PLL3M__ parameter can be a value between 1 and 63 + * @param __PLL3N__ parameter can be a value between 4 and 512 + * @param __PLL3P__ parameter can be a value between 2 and 128 + * @retval PLL3P clock frequency (in Hz) + */ +#define __LL_RCC_CALC_PLL3CLK_P_FREQ(__INPUTFREQ__, __PLL3M__, __PLL3N__, __PLL3P__) \ + ((((__INPUTFREQ__) /(__PLL3M__)) * (__PLL3N__)) / (__PLL3P__)) + +/** + * @brief Helper macro to calculate the PLL3 frequency + * @note ex: @ref __LL_RCC_CALC_PLL3CLK_Q_FREQ (HSE_VALUE,@ref LL_RCC_PLL3_GetM (), + * @ref LL_RCC_PLL3_GetN (), @ref LL_RCC_PLL3_GetQ ()); + * @param __INPUTFREQ__ PLL3 Input frequency (based on HSI/HSE/CSI) + * @param __PLL3M__ parameter can be a value between 1 and 63 + * @param __PLL3N__ parameter can be a value between 4 and 512 + * @param __PLL3Q__ parameter can be a value between 1 and 128 + * @retval PLL3Q clock frequency (in Hz) + */ +#define __LL_RCC_CALC_PLL3CLK_Q_FREQ(__INPUTFREQ__, __PLL3M__, __PLL3N__, __PLL3Q__) \ + ((((__INPUTFREQ__) /(__PLL3M__)) * (__PLL3N__)) / (__PLL3Q__)) + +/** + * @brief Helper macro to calculate the PLL3 frequency + * @note ex: @ref __LL_RCC_CALC_PLL3CLK_R_FREQ (HSE_VALUE,@ref LL_RCC_PLL3_GetM (), + * @ref LL_RCC_PLL3_GetN (), @ref LL_RCC_PLL3_GetR ()); + * @param __INPUTFREQ__ PLL3 Input frequency (based on HSI/HSE/CSI) + * @param __PLL3M__ parameter can be a value between 1 and 63 + * @param __PLL3N__ parameter can be a value between 4 and 512 + * @param __PLL3R__ parameter can be a value between 1 and 128 + * @retval PLL3R clock frequency (in Hz) + */ +#define __LL_RCC_CALC_PLL3CLK_R_FREQ(__INPUTFREQ__, __PLL3M__, __PLL3N__, __PLL3R__) \ + ((((__INPUTFREQ__) /(__PLL3M__)) * (__PLL3N__)) / (__PLL3R__)) + +/** + * @brief Helper macro to calculate the HCLK frequency + * @param __SYSCLKFREQ__ SYSCLK frequency (based on HSI/HSE/CSI/PLLCLK) + * @param __AHBPRESCALER__ This parameter can be one of the following values: + * @arg @ref LL_RCC_SYSCLK_DIV_1 + * @arg @ref LL_RCC_SYSCLK_DIV_2 + * @arg @ref LL_RCC_SYSCLK_DIV_4 + * @arg @ref LL_RCC_SYSCLK_DIV_8 + * @arg @ref LL_RCC_SYSCLK_DIV_16 + * @arg @ref LL_RCC_SYSCLK_DIV_64 + * @arg @ref LL_RCC_SYSCLK_DIV_128 + * @arg @ref LL_RCC_SYSCLK_DIV_256 + * @arg @ref LL_RCC_SYSCLK_DIV_512 + * @retval HCLK clock frequency (in Hz) + */ +#define __LL_RCC_CALC_HCLK_FREQ(__SYSCLKFREQ__, __AHBPRESCALER__) \ + ((__SYSCLKFREQ__) >> AHBPrescTable[((__AHBPRESCALER__) & RCC_CFGR2_HPRE) >> RCC_CFGR2_HPRE_Pos]) + +/** + * @brief Helper macro to calculate the PCLK1 frequency (APB1) + * @param __HCLKFREQ__ HCLK frequency + * @param __APB1PRESCALER__ This parameter can be one of the following values: + * @arg @ref LL_RCC_APB1_DIV_1 + * @arg @ref LL_RCC_APB1_DIV_2 + * @arg @ref LL_RCC_APB1_DIV_4 + * @arg @ref LL_RCC_APB1_DIV_8 + * @arg @ref LL_RCC_APB1_DIV_16 + * @retval PCLK1 clock frequency (in Hz) + */ +#define __LL_RCC_CALC_PCLK1_FREQ(__HCLKFREQ__, __APB1PRESCALER__) \ + ((__HCLKFREQ__) >> (APBPrescTable[((__APB1PRESCALER__) & RCC_CFGR2_PPRE1) >> RCC_CFGR2_PPRE1_Pos])) + +/** + * @brief Helper macro to calculate the PCLK2 frequency (APB2) + * @param __HCLKFREQ__ HCLK frequency + * @param __APB2PRESCALER__ This parameter can be one of the following values: + * @arg @ref LL_RCC_APB2_DIV_1 + * @arg @ref LL_RCC_APB2_DIV_2 + * @arg @ref LL_RCC_APB2_DIV_4 + * @arg @ref LL_RCC_APB2_DIV_8 + * @arg @ref LL_RCC_APB2_DIV_16 + * @retval PCLK2 clock frequency (in Hz) + */ +#define __LL_RCC_CALC_PCLK2_FREQ(__HCLKFREQ__, __APB2PRESCALER__) \ + ((__HCLKFREQ__) >> APBPrescTable[(__APB2PRESCALER__) >> RCC_CFGR2_PPRE2_Pos]) + + +/** + * @brief Helper macro to calculate the PCLK3 frequency (APB3) + * @param __HCLKFREQ__ HCLK frequency + * @param __APB3PRESCALER__ This parameter can be one of the following values: + * @arg @ref LL_RCC_APB3_DIV_1 + * @arg @ref LL_RCC_APB3_DIV_2 + * @arg @ref LL_RCC_APB3_DIV_4 + * @arg @ref LL_RCC_APB3_DIV_8 + * @arg @ref LL_RCC_APB3_DIV_16 + * @retval PCLK3 clock frequency (in Hz) + */ +#define __LL_RCC_CALC_PCLK3_FREQ(__HCLKFREQ__, __APB3PRESCALER__) \ + ((__HCLKFREQ__) >> APBPrescTable[(__APB3PRESCALER__) >> RCC_CFGR2_PPRE3_Pos]) + +/** + * @brief Helper macro to calculate the HSI frequency + * @param __HSIDIV__ This parameter can be one of the following values: + * @arg @ref LL_RCC_HSI_DIV_1 + * @arg @ref LL_RCC_HSI_DIV_2 + * @arg @ref LL_RCC_HSI_DIV_4 + * @arg @ref LL_RCC_HSI_DIV_8 + * @retval HSI clock frequency (in Hz) + */ +#define __LL_RCC_CALC_HSI_FREQ(__HSIDIV__) (HSI_VALUE >> ((__HSIDIV__)>> RCC_CR_HSIDIV_Pos)) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup RCC_LL_Exported_Functions RCC Exported Functions + * @{ + */ + +/** @defgroup RCC_LL_EF_HSE HSE + * @{ + */ + +/** + * @brief Enable the HSE Clock Security System. + * @rmtoll CR HSECSSON LL_RCC_HSE_EnableCSS + * @retval None + */ +__STATIC_INLINE void LL_RCC_HSE_EnableCSS(void) +{ + SET_BIT(RCC->CR, RCC_CR_HSECSSON); +} + +/** + * @brief Enable HSE external oscillator (HSE Bypass) + * @rmtoll CR HSEBYP LL_RCC_HSE_EnableBypass + * @retval None + */ +__STATIC_INLINE void LL_RCC_HSE_EnableBypass(void) +{ + SET_BIT(RCC->CR, RCC_CR_HSEBYP); +} + +/** + * @brief Disable HSE external oscillator (HSE Bypass) + * @rmtoll CR HSEBYP LL_RCC_HSE_DisableBypass + * @retval None + */ +__STATIC_INLINE void LL_RCC_HSE_DisableBypass(void) +{ + CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP); +} + +/** + * @brief Enable HSE crystal oscillator (HSE ON) + * @rmtoll CR HSEON LL_RCC_HSE_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_HSE_Enable(void) +{ + SET_BIT(RCC->CR, RCC_CR_HSEON); +} + +/** + * @brief Disable HSE crystal oscillator (HSE ON) + * @rmtoll CR HSEON LL_RCC_HSE_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_HSE_Disable(void) +{ + CLEAR_BIT(RCC->CR, RCC_CR_HSEON); +} + +/** + * @brief Check if HSE oscillator Ready + * @rmtoll CR HSERDY LL_RCC_HSE_IsReady + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_HSE_IsReady(void) +{ + return ((READ_BIT(RCC->CR, RCC_CR_HSERDY) == RCC_CR_HSERDY) ? 1UL : 0UL); +} + +/** + * @brief Set external HSE clock type in Bypass mode + * @note This bit can be written only if the HSE oscillator is disabled + * @rmtoll CR HSEEXT LL_RCC_HSE_SetExternalClockType + * @param HSEClockMode This parameter can be one of the following values: + * @arg @ref LL_RCC_HSE_ANALOG_TYPE + * @arg @ref LL_RCC_HSE_DIGITAL_TYPE + * @retval None + */ +__STATIC_INLINE void LL_RCC_HSE_SetExternalClockType(uint32_t HSEClockMode) +{ + MODIFY_REG(RCC->CR, RCC_CR_HSEEXT, HSEClockMode); +} + +/** + * @brief Get external HSE clock type in Bypass mode + * @rmtoll CR HSEEXT LL_RCC_HSE_GetExternalClockType + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_HSE_ANALOG_TYPE + * @arg @ref LL_RCC_HSE_DIGITAL_TYPE + */ +__STATIC_INLINE uint32_t LL_RCC_HSE_GetExternalClockType(void) +{ + return (uint32_t)(READ_BIT(RCC->CR, RCC_CR_HSEEXT)); +} + +/** + * @} + */ + +/** @defgroup RCC_LL_EF_HSI HSI + * @{ + */ + +/** + * @brief Enable HSI oscillator + * @rmtoll CR HSION LL_RCC_HSI_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_HSI_Enable(void) +{ + SET_BIT(RCC->CR, RCC_CR_HSION); +} + +/** + * @brief Disable HSI oscillator + * @rmtoll CR HSION LL_RCC_HSI_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_HSI_Disable(void) +{ + CLEAR_BIT(RCC->CR, RCC_CR_HSION); +} + +/** + * @brief Check if HSI clock is ready + * @rmtoll CR HSIRDY LL_RCC_HSI_IsReady + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_HSI_IsReady(void) +{ + return ((READ_BIT(RCC->CR, RCC_CR_HSIRDY) == RCC_CR_HSIRDY) ? 1UL : 0UL); +} + +/** + * @brief Enable HSI even in stop mode for some peripherals kernel + * @note HSI oscillator is forced ON even in Stop mode + * @rmtoll CR HSIKERON LL_RCC_HSI_EnableInStopMode + * @retval None + */ +__STATIC_INLINE void LL_RCC_HSI_EnableInStopMode(void) +{ + SET_BIT(RCC->CR, RCC_CR_HSIKERON); +} + +/** + * @brief Disable HSI in stop mode for some peripherals kernel + * @rmtoll CR HSIKERON LL_RCC_HSI_DisableInStopMode + * @retval None + */ +__STATIC_INLINE void LL_RCC_HSI_DisableInStopMode(void) +{ + CLEAR_BIT(RCC->CR, RCC_CR_HSIKERON); +} + +/** + * @brief Check if HSI is enabled in stop mode + * @rmtoll CR HSIKERON LL_RCC_HSI_IsEnabledInStopMode + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_HSI_IsEnabledInStopMode(void) +{ + return ((READ_BIT(RCC->CR, RCC_CR_HSIKERON) == RCC_CR_HSIKERON) ? 1UL : 0UL); +} + +/** + * @brief Check if HSI new divider applied and ready + * @rmtoll CR HSIDIVF LL_RCC_HSI_IsDividerReady + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_HSI_IsDividerReady(void) +{ + return ((READ_BIT(RCC->CR, RCC_CR_HSIDIVF) == (RCC_CR_HSIDIVF)) ? 1UL : 0UL); +} + +/** + * @brief Set HSI divider + * @rmtoll CR HSIDIV LL_RCC_HSI_SetDivider + * @param Divider This parameter can be one of the following values: + * @arg @ref LL_RCC_HSI_DIV_1 + * @arg @ref LL_RCC_HSI_DIV_2 + * @arg @ref LL_RCC_HSI_DIV_4 + * @arg @ref LL_RCC_HSI_DIV_8 + * @retval None. + */ +__STATIC_INLINE void LL_RCC_HSI_SetDivider(uint32_t Divider) +{ + MODIFY_REG(RCC->CR, RCC_CR_HSIDIV, Divider); +} + +/** + * @brief Get HSI divider + * @rmtoll CR HSIDIV LL_RCC_HSI_GetDivider + * @retval can be one of the following values: + * @arg @ref LL_RCC_HSI_DIV_1 + * @arg @ref LL_RCC_HSI_DIV_2 + * @arg @ref LL_RCC_HSI_DIV_4 + * @arg @ref LL_RCC_HSI_DIV_8 + */ +__STATIC_INLINE uint32_t LL_RCC_HSI_GetDivider(void) +{ + return (READ_BIT(RCC->CR, RCC_CR_HSIDIV)); +} + +/** + * @brief Get HSI Calibration value + * @note When HSITRIM is written, HSICAL is updated with the sum of + * HSITRIM and the factory trim value + * @rmtoll HSICFGR HSICAL LL_RCC_HSI_GetCalibration + * @retval A value between 0 and 4095 (0xFFF) + */ +__STATIC_INLINE uint32_t LL_RCC_HSI_GetCalibration(void) +{ + return (uint32_t)(READ_BIT(RCC->HSICFGR, RCC_HSICFGR_HSICAL) >> RCC_HSICFGR_HSICAL_Pos); +} + +/** + * @brief Set HSI Calibration trimming + * @note user-programmable trimming value that is added to the HSICAL + * @note Default value is 64, which, when added to the HSICAL value, + * should trim the HSI to 64 MHz +/- 1 % + * @rmtoll HSICFGR HSITRIM LL_RCC_HSI_SetCalibTrimming + * @param Value can be a value between Min_Data = 0 and Max_Data = 127 (0x7F) + * @retval None + */ +__STATIC_INLINE void LL_RCC_HSI_SetCalibTrimming(uint32_t Value) +{ + MODIFY_REG(RCC->HSICFGR, RCC_HSICFGR_HSITRIM, Value << RCC_HSICFGR_HSITRIM_Pos); +} + +/** + * @brief Get HSI Calibration trimming + * @rmtoll ICSC3R HSITRIM LL_RCC_HSI_GetCalibTrimming + * @retval A value between Min_Data = 0 and Max_Data = 127 (0x7F) + */ +__STATIC_INLINE uint32_t LL_RCC_HSI_GetCalibTrimming(void) +{ + return (uint32_t)(READ_BIT(RCC->HSICFGR, RCC_HSICFGR_HSITRIM) >> RCC_HSICFGR_HSITRIM_Pos); +} + +/** + * @} + */ + +/** @defgroup RCC_LL_EF_CSI CSI + * @{ + */ + +/** + * @brief Enable CSI oscillator + * @rmtoll CR CSION LL_RCC_CSI_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_CSI_Enable(void) +{ + SET_BIT(RCC->CR, RCC_CR_CSION); +} + +/** + * @brief Disable CSI oscillator + * @rmtoll CR CSION LL_RCC_CSI_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_CSI_Disable(void) +{ + CLEAR_BIT(RCC->CR, RCC_CR_CSION); +} + +/** + * @brief Check if CSI clock is ready + * @rmtoll CR CSIRDY LL_RCC_CSI_IsReady + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_CSI_IsReady(void) +{ + return ((READ_BIT(RCC->CR, RCC_CR_CSIRDY) == (RCC_CR_CSIRDY)) ? 1UL : 0UL); +} + +/** + * @brief Enable CSI oscillator in Stop mode for some peripherals kernel clock + * @rmtoll CR CSIKERON LL_RCC_CSI_EnableInStopMode + * @retval None + */ +__STATIC_INLINE void LL_RCC_CSI_EnableInStopMode(void) +{ + SET_BIT(RCC->CR, RCC_CR_CSIKERON); +} + +/** + * @brief Disable CSI oscillator in Stop mode for some peripherals kernel clock + * @rmtoll CR CSIKERON LL_RCC_CSI_DisableInStopMode + * @retval None + */ +__STATIC_INLINE void LL_RCC_CSI_DisableInStopMode(void) +{ + CLEAR_BIT(RCC->CR, RCC_CR_CSIKERON); +} + +/** + * @brief Check if CSI is enabled in stop mode + * @rmtoll CR CSIKERON LL_RCC_CSI_IsEnabledInStopMode + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_CSI_IsEnabledInStopMode(void) +{ + return ((READ_BIT(RCC->CR, RCC_CR_CSIKERON) == RCC_CR_CSIKERON) ? 1UL : 0UL); +} + +/** + * @brief Get CSI Calibration value + * @note When CSITRIM is written, CSICAL is updated with the sum of + * CSITRIM and the factory trim value + * @rmtoll CSICFGR CSICAL LL_RCC_CSI_GetCalibration + * @retval A value between 0 and 255 (0xFF) + */ +__STATIC_INLINE uint32_t LL_RCC_CSI_GetCalibration(void) +{ + return (uint32_t)(READ_BIT(RCC->CSICFGR, RCC_CSICFGR_CSICAL) >> RCC_CSICFGR_CSICAL_Pos); +} + +/** + * @brief Set CSI Calibration trimming + * @note user-programmable trimming value that is added to the CSICAL + * @note Default value is 16, which, when added to the CSICAL value, + * should trim the CSI to 4 MHz +/- 1 % + * @rmtoll CSICFGR CSITRIM LL_RCC_CSI_SetCalibTrimming + * @param Value can be a value between Min_Data = 0 and Max_Data = 63 (0x3F) + * @retval None + */ +__STATIC_INLINE void LL_RCC_CSI_SetCalibTrimming(uint32_t Value) +{ + MODIFY_REG(RCC->CSICFGR, RCC_CSICFGR_CSITRIM, Value << RCC_CSICFGR_CSITRIM_Pos); +} + +/** + * @brief Get CSI Calibration trimming + * @rmtoll CSICFGR CSITRIM LL_RCC_CSI_GetCalibTrimming + * @retval A value between 0 and 63 (0x3F) + */ +__STATIC_INLINE uint32_t LL_RCC_CSI_GetCalibTrimming(void) +{ + return (uint32_t)(READ_BIT(RCC->CSICFGR, RCC_CSICFGR_CSITRIM) >> RCC_CSICFGR_CSITRIM_Pos); +} + +/** + * @} + */ + +/** @defgroup RCC_LL_EF_HSI48 HSI48 + * @{ + */ + +/** + * @brief Enable HSI48 + * @rmtoll CR HSI48ON LL_RCC_HSI48_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_HSI48_Enable(void) +{ + SET_BIT(RCC->CR, RCC_CR_HSI48ON); +} + +/** + * @brief Disable HSI48 + * @rmtoll CR HSI48ON LL_RCC_HSI48_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_HSI48_Disable(void) +{ + CLEAR_BIT(RCC->CR, RCC_CR_HSI48ON); +} + +/** + * @brief Check if HSI48 oscillator Ready + * @rmtoll CR HSI48RDY LL_RCC_HSI48_IsReady + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_HSI48_IsReady(void) +{ + return ((READ_BIT(RCC->CR, RCC_CR_HSI48RDY) == RCC_CR_HSI48RDY) ? 1UL : 0UL); +} + +/** + * @brief Get HSI48 Calibration value + * @rmtoll CRRCR HSI48CAL LL_RCC_HSI48_GetCalibration + * @retval A value between 0 and 1023 (0x3FF) + */ +__STATIC_INLINE uint32_t LL_RCC_HSI48_GetCalibration(void) +{ + return (uint32_t)(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48CAL) >> RCC_CRRCR_HSI48CAL_Pos); +} + +/** + * @} + */ + +/** @defgroup RCC_LL_EF_LSE LSE + * @{ + */ + +/** + * @brief Enable Low Speed External (LSE) crystal. + * @rmtoll BDCR LSEON LL_RCC_LSE_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_LSE_Enable(void) +{ + SET_BIT(RCC->BDCR, RCC_BDCR_LSEON); +} + +/** + * @brief Disable Low Speed External (LSE) crystal. + * @rmtoll BDCR LSEON LL_RCC_LSE_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_LSE_Disable(void) +{ + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEON); +} + +/** + * @brief Check if LSE oscillator Ready + * @rmtoll BDCR LSERDY LL_RCC_LSE_IsReady + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_LSE_IsReady(void) +{ + return ((READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == RCC_BDCR_LSERDY) ? 1UL : 0UL); +} + +/** + * @brief Enable external clock source (LSE bypass). + * @rmtoll BDCR LSEBYP LL_RCC_LSE_EnableBypass + * @retval None + */ +__STATIC_INLINE void LL_RCC_LSE_EnableBypass(void) +{ + SET_BIT(RCC->BDCR, RCC_BDCR_LSEBYP); +} + +/** + * @brief Disable external clock source (LSE bypass). + * @rmtoll BDCR LSEBYP LL_RCC_LSE_DisableBypass + * @retval None + */ +__STATIC_INLINE void LL_RCC_LSE_DisableBypass(void) +{ + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEBYP); +} + +/** + * @brief Set external LSE clock type in Bypass mode + * @note This bit can be written only if the LSE oscillator is disabled + * @rmtoll BDCR LSEEXT LL_RCC_LSE_SetExternalClockType + * @param LSEClockMode This parameter can be one of the following values: + * @arg @ref LL_RCC_LSE_ANALOG_TYPE + * @arg @ref LL_RCC_LSE_DIGITAL_TYPE (*) + * @retval None + * + * (*) not to be used if RTC is active + */ +__STATIC_INLINE void LL_RCC_LSE_SetExternalClockType(uint32_t LSEClockMode) +{ + MODIFY_REG(RCC->BDCR, RCC_BDCR_LSEEXT, LSEClockMode); +} + +/** + * @brief Get external LSE clock type in Bypass mode + * @rmtoll BDCR LSEEXT LL_RCC_LSE_GetExternalClockType + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_LSE_ANALOG_TYPE + * @arg @ref LL_RCC_LSE_DIGITAL_TYPE + */ +__STATIC_INLINE uint32_t LL_RCC_LSE_GetExternalClockType(void) +{ + return (uint32_t)(READ_BIT(RCC->BDCR, RCC_BDCR_LSEEXT)); +} + +/** + * @brief Set LSE oscillator drive capability + * @note The oscillator is in Xtal mode when it is not in bypass mode. + * @rmtoll BDCR LSEDRV LL_RCC_LSE_SetDriveCapability + * @param LSEDrive This parameter can be one of the following values: + * @arg @ref LL_RCC_LSEDRIVE_LOW + * @arg @ref LL_RCC_LSEDRIVE_MEDIUMLOW + * @arg @ref LL_RCC_LSEDRIVE_MEDIUMHIGH + * @arg @ref LL_RCC_LSEDRIVE_HIGH + * @retval None + */ +__STATIC_INLINE void LL_RCC_LSE_SetDriveCapability(uint32_t LSEDrive) +{ + MODIFY_REG(RCC->BDCR, RCC_BDCR_LSEDRV, LSEDrive); +} + +/** + * @brief Get LSE oscillator drive capability + * @rmtoll BDCR LSEDRV LL_RCC_LSE_GetDriveCapability + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_LSEDRIVE_LOW + * @arg @ref LL_RCC_LSEDRIVE_MEDIUMLOW + * @arg @ref LL_RCC_LSEDRIVE_MEDIUMHIGH + * @arg @ref LL_RCC_LSEDRIVE_HIGH + */ +__STATIC_INLINE uint32_t LL_RCC_LSE_GetDriveCapability(void) +{ + return (uint32_t)(READ_BIT(RCC->BDCR, RCC_BDCR_LSEDRV)); +} + +/** + * @brief Enable Clock security system on LSE. + * @rmtoll BDCR LSECSSON LL_RCC_LSE_EnableCSS + * @retval None + */ +__STATIC_INLINE void LL_RCC_LSE_EnableCSS(void) +{ + SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON); +} + +/** + * @brief Disable Clock security system on LSE. + * @note Clock security system can be disabled only after a LSE + * failure detection. In that case it MUST be disabled by software. + * @rmtoll BDCR LSECSSON LL_RCC_LSE_DisableCSS + * @retval None + */ +__STATIC_INLINE void LL_RCC_LSE_DisableCSS(void) +{ + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSECSSON); +} + +/** + * @brief Check if CSS on LSE failure Detection + * @rmtoll BDCR LSECSSD LL_RCC_LSE_IsCSSDetected + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_LSE_IsCSSDetected(void) +{ + return ((READ_BIT(RCC->BDCR, RCC_BDCR_LSECSSD) == RCC_BDCR_LSECSSD) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup RCC_LL_EF_LSI LSI + * @{ + */ + +/** + * @brief Enable LSI Oscillator + * @rmtoll BDCR LSION LL_RCC_LSI_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_LSI_Enable(void) +{ + SET_BIT(RCC->BDCR, RCC_BDCR_LSION); +} + +/** + * @brief Disable LSI Oscillator + * @rmtoll BDCR LSION LL_RCC_LSI_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_LSI_Disable(void) +{ + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSION); +} + +/** + * @brief Check if LSI is Ready + * @rmtoll BDCR LSIRDY LL_RCC_LSI_IsReady + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_LSI_IsReady(void) +{ + return ((READ_BIT(RCC->BDCR, RCC_BDCR_LSIRDY) == RCC_BDCR_LSIRDY) ? 1UL : 0UL); +} + + +/** + * @} + */ + + +/** @defgroup RCC_LL_EF_LSCO LSCO + * @{ + */ + +/** + * @brief Enable Low Speed Microcontroller Clock Output + * @rmtoll BDCR LSCOEN LL_RCC_LSCO_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_LSCO_Enable(void) +{ + SET_BIT(RCC->BDCR, RCC_BDCR_LSCOEN); +} + +/** + * @brief Disable Low Speed Microcontroller Clock Output + * @rmtoll BDCR LSCOEN LL_RCC_LSCO_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_LSCO_Disable(void) +{ + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSCOEN); +} + +/** + * @brief Configure Low Speed Microcontroller Clock Output selection + * @rmtoll BDCR LSCOSEL LL_RCC_LSCO_SetSource + * @param Source This parameter can be one of the following values: + * @arg @ref LL_RCC_LSCO_CLKSOURCE_LSI + * @arg @ref LL_RCC_LSCO_CLKSOURCE_LSE + * @retval None + */ +__STATIC_INLINE void LL_RCC_LSCO_SetSource(uint32_t Source) +{ + MODIFY_REG(RCC->BDCR, RCC_BDCR_LSCOSEL, Source); +} + +/** + * @brief Get Low Speed Microcontroller Clock Output selection + * @rmtoll BDCR LSCOSEL LL_RCC_LSCO_GetSource + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_LSCO_CLKSOURCE_LSI + * @arg @ref LL_RCC_LSCO_CLKSOURCE_LSE + */ +__STATIC_INLINE uint32_t LL_RCC_LSCO_GetSource(void) +{ + return (uint32_t)(READ_BIT(RCC->BDCR, RCC_BDCR_LSCOSEL)); +} + +/** + * @} + */ + +/** @defgroup RCC_LL_EF_System System + * @{ + */ + +/** + * @brief Configure the system clock source + * @rmtoll CFGR1 SW LL_RCC_SetSysClkSource + * @param Source This parameter can be one of the following values: + * @arg @ref LL_RCC_SYS_CLKSOURCE_HSI + * @arg @ref LL_RCC_SYS_CLKSOURCE_CSI + * @arg @ref LL_RCC_SYS_CLKSOURCE_HSE + * @arg @ref LL_RCC_SYS_CLKSOURCE_PLL1 + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetSysClkSource(uint32_t Source) +{ + MODIFY_REG(RCC->CFGR1, RCC_CFGR1_SW, Source); +} + +/** + * @brief Get the system clock source + * @rmtoll CFGR1 SWS LL_RCC_GetSysClkSource + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_SYS_CLKSOURCE_STATUS_HSI + * @arg @ref LL_RCC_SYS_CLKSOURCE_STATUS_CSI + * @arg @ref LL_RCC_SYS_CLKSOURCE_STATUS_HSE + * @arg @ref LL_RCC_SYS_CLKSOURCE_STATUS_PLL1 + */ +__STATIC_INLINE uint32_t LL_RCC_GetSysClkSource(void) +{ + return (uint32_t)(READ_BIT(RCC->CFGR1, RCC_CFGR1_SWS)); +} + +/** + * @brief Set AHB prescaler + * @rmtoll CFGR2 HPRE LL_RCC_SetAHBPrescaler + * @param Prescaler This parameter can be one of the following values: + * @arg @ref LL_RCC_SYSCLK_DIV_1 + * @arg @ref LL_RCC_SYSCLK_DIV_2 + * @arg @ref LL_RCC_SYSCLK_DIV_4 + * @arg @ref LL_RCC_SYSCLK_DIV_8 + * @arg @ref LL_RCC_SYSCLK_DIV_16 + * @arg @ref LL_RCC_SYSCLK_DIV_64 + * @arg @ref LL_RCC_SYSCLK_DIV_128 + * @arg @ref LL_RCC_SYSCLK_DIV_256 + * @arg @ref LL_RCC_SYSCLK_DIV_512 + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetAHBPrescaler(uint32_t Prescaler) +{ + MODIFY_REG(RCC->CFGR2, RCC_CFGR2_HPRE, Prescaler); +} + +/** + * @brief Set Systick clock source + * @rmtoll CCIPR4 SYSTICKSEL LL_RCC_SetSystickClockSource + * @param SystickSource This parameter can be one of the following values: + * @arg @ref LL_RCC_SYSTICK_CLKSOURCE_LSI + * @arg @ref LL_RCC_SYSTICK_CLKSOURCE_LSE + * @arg @ref LL_RCC_SYSTICK_CLKSOURCE_HCLKDIV8 + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetSystickClockSource(uint32_t SystickSource) +{ + MODIFY_REG(RCC->CCIPR4, RCC_CCIPR4_SYSTICKSEL, SystickSource); +} + +/** + * @brief Set APB1 prescaler + * @rmtoll CFGR2 PPRE1 LL_RCC_SetAPB1Prescaler + * @param Prescaler This parameter can be one of the following values: + * @arg @ref LL_RCC_APB1_DIV_1 + * @arg @ref LL_RCC_APB1_DIV_2 + * @arg @ref LL_RCC_APB1_DIV_4 + * @arg @ref LL_RCC_APB1_DIV_8 + * @arg @ref LL_RCC_APB1_DIV_16 + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetAPB1Prescaler(uint32_t Prescaler) +{ + MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE1, Prescaler); +} + +/** + * @brief Set APB2 prescaler + * @rmtoll CFGR2 PPRE2 LL_RCC_SetAPB2Prescaler + * @param Prescaler This parameter can be one of the following values: + * @arg @ref LL_RCC_APB2_DIV_1 + * @arg @ref LL_RCC_APB2_DIV_2 + * @arg @ref LL_RCC_APB2_DIV_4 + * @arg @ref LL_RCC_APB2_DIV_8 + * @arg @ref LL_RCC_APB2_DIV_16 + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetAPB2Prescaler(uint32_t Prescaler) +{ + MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE2, Prescaler); +} + +/** + * @brief Set APB3 prescaler + * @rmtoll CFGR3 PPRE3 LL_RCC_SetAPB3Prescaler + * @param Prescaler This parameter can be one of the following values: + * @arg @ref LL_RCC_APB3_DIV_1 + * @arg @ref LL_RCC_APB3_DIV_2 + * @arg @ref LL_RCC_APB3_DIV_4 + * @arg @ref LL_RCC_APB3_DIV_8 + * @arg @ref LL_RCC_APB3_DIV_16 + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetAPB3Prescaler(uint32_t Prescaler) +{ + MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE3, Prescaler); +} + +/** + * @brief Get AHB prescaler + * @rmtoll CFGR2 HPRE LL_RCC_GetAHBPrescaler + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_SYSCLK_DIV_1 + * @arg @ref LL_RCC_SYSCLK_DIV_2 + * @arg @ref LL_RCC_SYSCLK_DIV_4 + * @arg @ref LL_RCC_SYSCLK_DIV_8 + * @arg @ref LL_RCC_SYSCLK_DIV_16 + * @arg @ref LL_RCC_SYSCLK_DIV_64 + * @arg @ref LL_RCC_SYSCLK_DIV_128 + * @arg @ref LL_RCC_SYSCLK_DIV_256 + * @arg @ref LL_RCC_SYSCLK_DIV_512 + */ +__STATIC_INLINE uint32_t LL_RCC_GetAHBPrescaler(void) +{ + return (uint32_t)(READ_BIT(RCC->CFGR2, RCC_CFGR2_HPRE)); +} + +/** + * @brief Get Sysctick clock source + * @rmtoll CCIPR4 SYSTICKSEL LL_RCC_SetSystickClockSource + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_SYSTICK_CLKSOURCE_LSI + * @arg @ref LL_RCC_SYSTICK_CLKSOURCE_LSE + * @arg @ref LL_RCC_SYSTICK_CLKSOURCE_HCLKDIV8 + */ +__STATIC_INLINE uint32_t LL_RCC_GetSystickClockSource(void) +{ + return (uint32_t)(READ_BIT(RCC->CCIPR4, RCC_CCIPR4_SYSTICKSEL)); +} + +/** + * @brief Get APB1 prescaler + * @rmtoll CFGR2 PPRE1 LL_RCC_GetAPB1Prescaler + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_APB1_DIV_1 + * @arg @ref LL_RCC_APB1_DIV_2 + * @arg @ref LL_RCC_APB1_DIV_4 + * @arg @ref LL_RCC_APB1_DIV_8 + * @arg @ref LL_RCC_APB1_DIV_16 + */ +__STATIC_INLINE uint32_t LL_RCC_GetAPB1Prescaler(void) +{ + return (uint32_t)(READ_BIT(RCC->CFGR2, RCC_CFGR2_PPRE1)); +} + +/** + * @brief Get APB2 prescaler + * @rmtoll CFGR2 PPRE2 LL_RCC_GetAPB2Prescaler + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_APB2_DIV_1 + * @arg @ref LL_RCC_APB2_DIV_2 + * @arg @ref LL_RCC_APB2_DIV_4 + * @arg @ref LL_RCC_APB2_DIV_8 + * @arg @ref LL_RCC_APB2_DIV_16 + */ +__STATIC_INLINE uint32_t LL_RCC_GetAPB2Prescaler(void) +{ + return (uint32_t)(READ_BIT(RCC->CFGR2, RCC_CFGR2_PPRE2)); +} + +/** + * @brief Get APB3 prescaler + * @rmtoll CFGR3 PPRE3 LL_RCC_GetAPB2Prescaler + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_APB3_DIV_1 + * @arg @ref LL_RCC_APB3_DIV_2 + * @arg @ref LL_RCC_APB3_DIV_4 + * @arg @ref LL_RCC_APB3_DIV_8 + * @arg @ref LL_RCC_APB3_DIV_16 + */ +__STATIC_INLINE uint32_t LL_RCC_GetAPB3Prescaler(void) +{ + return (uint32_t)(READ_BIT(RCC->CFGR2, RCC_CFGR2_PPRE3)); +} + +/** + * @brief Set System Clock After Wake-Up From Stop mode + * @rmtoll CFGR1 STOPWUCK LL_RCC_SetClkAfterWakeFromStop + * @param Clock This parameter can be one of the following values: + * @arg @ref LL_RCC_SYSWAKEUP_CLKSOURCE_HSI + * @arg @ref LL_RCC_SYSWAKEUP_CLKSOURCE_CSI + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetClkAfterWakeFromStop(uint32_t Clock) +{ + MODIFY_REG(RCC->CFGR1, RCC_CFGR1_STOPWUCK, Clock); +} + +/** + * @brief Get System Clock After Wake-Up From Stop mode + * @rmtoll CFGR1 STOPWUCK LL_RCC_GetClkAfterWakeFromStop + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_SYSWAKEUP_CLKSOURCE_HSI + * @arg @ref LL_RCC_SYSWAKEUP_CLKSOURCE_CSI + */ +__STATIC_INLINE uint32_t LL_RCC_GetClkAfterWakeFromStop(void) +{ + return (uint32_t)(READ_BIT(RCC->CFGR1, RCC_CFGR1_STOPWUCK)); +} +/** + * @} + */ + +/** @defgroup RCC_LL_EF_MCO MCO + * @{ + */ + +/** + * @brief Configure MCO1 (pin PA8) or MCO2 (pin PC9) + * @rmtoll CFGR1 MCO1 LL_RCC_ConfigMCO\n + * CFGR1 MCO1PRE LL_RCC_ConfigMCO\n + * CFGR1 MCO2 LL_RCC_ConfigMCO\n + * CFGR1 MCO2PRE LL_RCC_ConfigMCO + * @param MCOxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_MCO1SOURCE_HSI + * @arg @ref LL_RCC_MCO1SOURCE_LSE + * @arg @ref LL_RCC_MCO1SOURCE_HSE + * @arg @ref LL_RCC_MCO1SOURCE_PLL1Q + * @arg @ref LL_RCC_MCO1SOURCE_HSI48 + * @arg @ref LL_RCC_MCO2SOURCE_SYSCLK + * @arg @ref LL_RCC_MCO2SOURCE_PLL2P + * @arg @ref LL_RCC_MCO2SOURCE_HSE + * @arg @ref LL_RCC_MCO2SOURCE_PLL1P + * @arg @ref LL_RCC_MCO2SOURCE_CSI + * @arg @ref LL_RCC_MCO2SOURCE_LSI + * @param MCOxPrescaler This parameter can be one of the following values: + * @arg @ref LL_RCC_MCO1_DIV_1 + * @arg @ref LL_RCC_MCO1_DIV_2 + * @arg @ref LL_RCC_MCO1_DIV_3 + * @arg @ref LL_RCC_MCO1_DIV_4 + * @arg @ref LL_RCC_MCO1_DIV_5 + * @arg @ref LL_RCC_MCO1_DIV_6 + * @arg @ref LL_RCC_MCO1_DIV_7 + * @arg @ref LL_RCC_MCO1_DIV_8 + * @arg @ref LL_RCC_MCO1_DIV_9 + * @arg @ref LL_RCC_MCO1_DIV_10 + * @arg @ref LL_RCC_MCO1_DIV_11 + * @arg @ref LL_RCC_MCO1_DIV_12 + * @arg @ref LL_RCC_MCO1_DIV_13 + * @arg @ref LL_RCC_MCO1_DIV_14 + * @arg @ref LL_RCC_MCO1_DIV_15 + * @arg @ref LL_RCC_MCO2_DIV_1 + * @arg @ref LL_RCC_MCO2_DIV_2 + * @arg @ref LL_RCC_MCO2_DIV_3 + * @arg @ref LL_RCC_MCO2_DIV_4 + * @arg @ref LL_RCC_MCO2_DIV_5 + * @arg @ref LL_RCC_MCO2_DIV_6 + * @arg @ref LL_RCC_MCO2_DIV_7 + * @arg @ref LL_RCC_MCO2_DIV_8 + * @arg @ref LL_RCC_MCO2_DIV_9 + * @arg @ref LL_RCC_MCO2_DIV_10 + * @arg @ref LL_RCC_MCO2_DIV_11 + * @arg @ref LL_RCC_MCO2_DIV_12 + * @arg @ref LL_RCC_MCO2_DIV_13 + * @arg @ref LL_RCC_MCO2_DIV_14 + * @arg @ref LL_RCC_MCO2_DIV_15 + * @retval None + */ +__STATIC_INLINE void LL_RCC_ConfigMCO(uint32_t MCOxSource, uint32_t MCOxPrescaler) +{ + MODIFY_REG(RCC->CFGR1, (MCOxSource << 16U) | (MCOxPrescaler << 16U), \ + (MCOxSource & 0xFFFF0000U) | (MCOxPrescaler & 0xFFFF0000U)); +} + +/** + * @} + */ + + +/** @defgroup RCC_LL_EF_Peripheral_Clock_Source Peripheral Clock Source + * @{ + */ + +/** + * @brief Configure periph clock source + * @rmtoll CCIPR1 * LL_RCC_SetClockSource\n + * CCIPR2 * LL_RCC_SetClockSource\n + * CCIPR3 * LL_RCC_SetClockSource\n + * CCIPR4 * LL_RCC_SetClockSource\n + * CCIPR5 * LL_RCC_SetClockSource + * @param ClkSource This parameter can be one of the following values: + * @arg @ref LL_RCC_USART1_CLKSOURCE_PCLK2 + * @arg @ref LL_RCC_USART1_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_USART1_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_USART1_CLKSOURCE_HSI + * @arg @ref LL_RCC_USART1_CLKSOURCE_CSI + * @arg @ref LL_RCC_USART1_CLKSOURCE_LSE + * @arg @ref LL_RCC_USART2_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_USART2_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_USART2_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_USART2_CLKSOURCE_HSI + * @arg @ref LL_RCC_USART2_CLKSOURCE_CSI + * @arg @ref LL_RCC_USART2_CLKSOURCE_LSE + * @arg @ref LL_RCC_USART3_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_USART3_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_USART3_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_USART3_CLKSOURCE_HSI + * @arg @ref LL_RCC_USART3_CLKSOURCE_CSI + * @arg @ref LL_RCC_USART3_CLKSOURCE_LSE + * @arg @ref LL_RCC_USART6_CLKSOURCE_PCLK1 (*) + * @arg @ref LL_RCC_USART6_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_USART6_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_USART6_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_USART6_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_USART6_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_USART10_CLKSOURCE_PCLK1 (*) + * @arg @ref LL_RCC_USART10_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_USART10_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_USART10_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_USART10_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_USART10_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_USART11_CLKSOURCE_PCLK1 (*) + * @arg @ref LL_RCC_USART11_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_USART11_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_USART11_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_USART11_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_USART11_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_UART4_CLKSOURCE_PCLK1 (*) + * @arg @ref LL_RCC_UART4_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_UART4_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_UART4_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_UART4_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_UART4_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_UART5_CLKSOURCE_PCLK1 (*) + * @arg @ref LL_RCC_UART5_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_UART5_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_UART5_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_UART5_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_UART5_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_UART7_CLKSOURCE_PCLK1 (*) + * @arg @ref LL_RCC_UART7_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_UART7_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_UART7_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_UART7_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_UART7_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_UART8_CLKSOURCE_PCLK1 (*) + * @arg @ref LL_RCC_UART8_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_UART8_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_UART8_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_UART8_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_UART8_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_UART9_CLKSOURCE_PCLK1 (*) + * @arg @ref LL_RCC_UART9_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_UART9_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_UART9_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_UART9_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_UART9_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_UART12_CLKSOURCE_PCLK1 (*) + * @arg @ref LL_RCC_UART12_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_UART12_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_UART12_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_UART12_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_UART12_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_LPUART1_CLKSOURCE_PCLK3 + * @arg @ref LL_RCC_LPUART1_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_LPUART1_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_LPUART1_CLKSOURCE_HSI + * @arg @ref LL_RCC_LPUART1_CLKSOURCE_CSI + * @arg @ref LL_RCC_LPUART1_CLKSOURCE_LSE + * @arg @ref LL_RCC_I2C1_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_I2C1_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_I2C1_CLKSOURCE_PLL2R (*) + * @arg @ref LL_RCC_I2C1_CLKSOURCE_HSI + * @arg @ref LL_RCC_I2C1_CLKSOURCE_CSI + * @arg @ref LL_RCC_I2C2_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_I2C2_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_I2C2_CLKSOURCE_PLL2R (*) + * @arg @ref LL_RCC_I2C2_CLKSOURCE_HSI + * @arg @ref LL_RCC_I2C2_CLKSOURCE_CSI + * @arg @ref LL_RCC_I2C3_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_I2C3_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_I2C3_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_I2C3_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_I2C4_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_I2C4_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_I2C4_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_I2C4_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_I3C1_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_I3C1_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_I3C1_CLKSOURCE_PLL2R (*) + * @arg @ref LL_RCC_I3C1_CLKSOURCE_HSI + * @arg @ref LL_RCC_I3C1_CLKSOURCE_NONE + * @arg @ref LL_RCC_I3C2_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_I3C2_CLKSOURCE_PLL2R (*) + * @arg @ref LL_RCC_I3C2_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_I3C2_CLKSOURCE_NONE (*) + * @arg @ref LL_RCC_SPI1_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_SPI1_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_SPI1_CLKSOURCE_PLL3P + * @arg @ref LL_RCC_SPI1_CLKSOURCE_PIN + * @arg @ref LL_RCC_SPI1_CLKSOURCE_CLKP + * @arg @ref LL_RCC_SPI2_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_SPI2_CLKSOURCE_PLL2P (*) + * @arg @ref LL_RCC_SPI2_CLKSOURCE_PLL3P (*) + * @arg @ref LL_RCC_SPI2_CLKSOURCE_PIN + * @arg @ref LL_RCC_SPI2_CLKSOURCE_CLKP + * @arg @ref LL_RCC_SPI3_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_SPI3_CLKSOURCE_PLL2P (*) + * @arg @ref LL_RCC_SPI3_CLKSOURCE_PLL3P (*) + * @arg @ref LL_RCC_SPI3_CLKSOURCE_PIN + * @arg @ref LL_RCC_SPI3_CLKSOURCE_CLKP + * @arg @ref LL_RCC_SPI4_CLKSOURCE_PCLK2 (*) + * @arg @ref LL_RCC_SPI4_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_SPI4_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_SPI4_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_SPI4_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_SPI4_CLKSOURCE_HSE (*) + * @arg @ref LL_RCC_SPI5_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_SPI5_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_SPI5_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_SPI5_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_SPI5_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_SPI5_CLKSOURCE_HSE (*) + * @arg @ref LL_RCC_SPI6_CLKSOURCE_PCLK2 (*) + * @arg @ref LL_RCC_SPI6_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_SPI6_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_SPI6_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_SPI6_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_SPI6_CLKSOURCE_HSE (*) + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE_PCLK3 + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE_PLL3R + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE_LSE + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE_LSI + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE_CLKP + * @arg @ref LL_RCC_LPTIM2_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_LPTIM2_CLKSOURCE_PLL2P (*) + * @arg @ref LL_RCC_LPTIM2_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_LPTIM2_CLKSOURCE_LSE + * @arg @ref LL_RCC_LPTIM2_CLKSOURCE_LSI + * @arg @ref LL_RCC_LPTIM2_CLKSOURCE_CLKP + * @arg @ref LL_RCC_LPTIM3_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_LPTIM3_CLKSOURCE_PLL2P (*) + * @arg @ref LL_RCC_LPTIM3_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_LPTIM3_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_LPTIM3_CLKSOURCE_LSI (*) + * @arg @ref LL_RCC_LPTIM3_CLKSOURCE_CLKP (*) + * @arg @ref LL_RCC_LPTIM4_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_LPTIM4_CLKSOURCE_PLL2P (*) + * @arg @ref LL_RCC_LPTIM4_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_LPTIM4_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_LPTIM4_CLKSOURCE_LSI (*) + * @arg @ref LL_RCC_LPTIM4_CLKSOURCE_CLKP (*) + * @arg @ref LL_RCC_LPTIM5_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_LPTIM5_CLKSOURCE_PLL2P (*) + * @arg @ref LL_RCC_LPTIM5_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_LPTIM5_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_LPTIM5_CLKSOURCE_LSI (*) + * @arg @ref LL_RCC_LPTIM5_CLKSOURCE_CLKP (*) + * @arg @ref LL_RCC_LPTIM6_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_LPTIM6_CLKSOURCE_PLL2P (*) + * @arg @ref LL_RCC_LPTIM6_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_LPTIM6_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_LPTIM6_CLKSOURCE_LSI (*) + * @arg @ref LL_RCC_LPTIM6_CLKSOURCE_CLKP (*) + * @arg @ref LL_RCC_SAI1_CLKSOURCE_PLL1Q (*) + * @arg @ref LL_RCC_SAI1_CLKSOURCE_PLL2P (*) + * @arg @ref LL_RCC_SAI1_CLKSOURCE_PLL3P (*) + * @arg @ref LL_RCC_SAI1_CLKSOURCE_PIN (*) + * @arg @ref LL_RCC_SAI1_CLKSOURCE_CLKP (*) + * @arg @ref LL_RCC_SAI2_CLKSOURCE_PLL1Q (*) + * @arg @ref LL_RCC_SAI2_CLKSOURCE_PLL2P (*) + * @arg @ref LL_RCC_SAI2_CLKSOURCE_PLL3P (*) + * @arg @ref LL_RCC_SAI2_CLKSOURCE_PIN (*) + * @arg @ref LL_RCC_SAI2_CLKSOURCE_CLKP (*) + * @arg @ref LL_RCC_SDMMC1_CLKSOURCE_PLL1Q (*) + * @arg @ref LL_RCC_SDMMC1_CLKSOURCE_PLL2R (*) + * @arg @ref LL_RCC_SDMMC2_CLKSOURCE_PLL1Q (*) + * @arg @ref LL_RCC_SDMMC2_CLKSOURCE_PLL2R (*) + * + * (*) value not defined in all devices. + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetClockSource(uint32_t ClkSource) +{ + uint32_t *pReg = (uint32_t *)((uint32_t)&RCC->CCIPR1 + LL_CLKSOURCE_REG(ClkSource)); + MODIFY_REG(*pReg, LL_CLKSOURCE_MASK(ClkSource), LL_CLKSOURCE_CONFIG(ClkSource)); +} + + +/** + * @brief Configure USARTx kernel clock source + * @rmtoll CCIPR1 USART1SEL LL_RCC_SetUSARTClockSource\n + * CCIPR1 USART2SEL LL_RCC_SetUSARTClockSource\n + * CCIPR1 USART3SEL LL_RCC_SetUSARTClockSource\n + * CCIPR1 USART6SEL LL_RCC_SetUSARTClockSource\n + * CCIPR1 USART10SEL LL_RCC_SetUSARTClockSource\n + * CCIPR2 USART11SEL LL_RCC_SetUSARTClockSource + * @param USARTxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_USART1_CLKSOURCE_PCLK2 + * @arg @ref LL_RCC_USART1_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_USART1_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_USART1_CLKSOURCE_HSI + * @arg @ref LL_RCC_USART1_CLKSOURCE_CSI + * @arg @ref LL_RCC_USART1_CLKSOURCE_LSE + * @arg @ref LL_RCC_USART2_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_USART2_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_USART2_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_USART2_CLKSOURCE_HSI + * @arg @ref LL_RCC_USART2_CLKSOURCE_CSI + * @arg @ref LL_RCC_USART2_CLKSOURCE_LSE + * @arg @ref LL_RCC_USART3_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_USART3_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_USART3_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_USART3_CLKSOURCE_HSI + * @arg @ref LL_RCC_USART3_CLKSOURCE_CSI + * @arg @ref LL_RCC_USART3_CLKSOURCE_LSE + * @arg @ref LL_RCC_USART6_CLKSOURCE_PCLK1 (*) + * @arg @ref LL_RCC_USART6_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_USART6_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_USART6_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_USART6_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_USART6_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_USART10_CLKSOURCE_PCLK1 (*) + * @arg @ref LL_RCC_USART10_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_USART10_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_USART10_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_USART10_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_USART10_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_USART11_CLKSOURCE_PCLK1 (*) + * @arg @ref LL_RCC_USART11_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_USART11_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_USART11_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_USART11_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_USART11_CLKSOURCE_LSE (*) + * + * (*) : For stm32h56xxx and stm32h57xxx family lines only. + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetUSARTClockSource(uint32_t USARTxSource) +{ + LL_RCC_SetClockSource(USARTxSource); +} + +#if defined(UART4) +/** + * @brief Configure UARTx kernel clock source + * @rmtoll CCIPR1 UART4SEL LL_RCC_SetUARTClockSource\n + * CCIPR1 UART5SEL LL_RCC_SetUARTClockSource\n + * CCIPR1 UART7SEL LL_RCC_SetUARTClockSource\n + * CCIPR1 UART8SEL LL_RCC_SetUARTClockSource\n + * CCIPR1 UART9SEL LL_RCC_SetUARTClockSource\n + * CCIPR2 UART12SEL LL_RCC_SetUARTClockSource + * @param UARTxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_UART4_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_UART4_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_UART4_CLKSOURCE_PLL3Q + * @arg @ref LL_RCC_UART4_CLKSOURCE_HSI + * @arg @ref LL_RCC_UART4_CLKSOURCE_CSI + * @arg @ref LL_RCC_UART4_CLKSOURCE_LSE + * @arg @ref LL_RCC_UART5_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_UART5_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_UART5_CLKSOURCE_PLL3Q + * @arg @ref LL_RCC_UART5_CLKSOURCE_HSI + * @arg @ref LL_RCC_UART5_CLKSOURCE_CSI + * @arg @ref LL_RCC_UART5_CLKSOURCE_LSE + * @arg @ref LL_RCC_UART7_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_UART7_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_UART7_CLKSOURCE_PLL3Q + * @arg @ref LL_RCC_UART7_CLKSOURCE_HSI + * @arg @ref LL_RCC_UART7_CLKSOURCE_CSI + * @arg @ref LL_RCC_UART7_CLKSOURCE_LSE + * @arg @ref LL_RCC_UART8_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_UART8_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_UART8_CLKSOURCE_PLL3Q + * @arg @ref LL_RCC_UART8_CLKSOURCE_HSI + * @arg @ref LL_RCC_UART8_CLKSOURCE_CSI + * @arg @ref LL_RCC_UART8_CLKSOURCE_LSE + * @arg @ref LL_RCC_UART9_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_UART9_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_UART9_CLKSOURCE_PLL3Q + * @arg @ref LL_RCC_UART9_CLKSOURCE_HSI + * @arg @ref LL_RCC_UART9_CLKSOURCE_CSI + * @arg @ref LL_RCC_UART9_CLKSOURCE_LSE + * @arg @ref LL_RCC_UART12_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_UART12_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_UART12_CLKSOURCE_PLL3Q + * @arg @ref LL_RCC_UART12_CLKSOURCE_HSI + * @arg @ref LL_RCC_UART12_CLKSOURCE_CSI + * @arg @ref LL_RCC_UART12_CLKSOURCE_LSE + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetUARTClockSource(uint32_t UARTxSource) +{ + LL_RCC_SetClockSource(UARTxSource); +} +#endif /* UART4 */ + +/** + * @brief Configure LPUARTx kernel clock source + * @rmtoll CCIPR3 LPUART1SEL LL_RCC_SetLPUARTClockSource + * @param LPUARTxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_LPUART1_CLKSOURCE_PCLK3 + * @arg @ref LL_RCC_LPUART1_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_LPUART1_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_LPUART1_CLKSOURCE_HSI + * @arg @ref LL_RCC_LPUART1_CLKSOURCE_CSI + * @arg @ref LL_RCC_LPUART1_CLKSOURCE_LSE + * + * (*) : For stm32h56xxx and stm32h57xxx family lines only. + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetLPUARTClockSource(uint32_t LPUARTxSource) +{ + MODIFY_REG(RCC->CCIPR3, RCC_CCIPR3_LPUART1SEL, LPUARTxSource); +} + +/** + * @brief Configure I2Cx kernel clock source + * @rmtoll CCIPR4 I2C1SEL LL_RCC_SetI2CClockSource\n + * CCIPR4 I2C2SEL LL_RCC_SetI2CClockSource\n + * CCIPR4 I2C3SEL LL_RCC_SetI2CClockSource\n + * CCIPR4 I2C4SEL LL_RCC_SetI2CClockSource + * @param I2CxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_I2C1_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_I2C1_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_I2C1_CLKSOURCE_PLL2R (**) + * @arg @ref LL_RCC_I2C1_CLKSOURCE_HSI + * @arg @ref LL_RCC_I2C1_CLKSOURCE_CSI + * @arg @ref LL_RCC_I2C2_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_I2C2_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_I2C2_CLKSOURCE_PLL2R (**) + * @arg @ref LL_RCC_I2C2_CLKSOURCE_HSI + * @arg @ref LL_RCC_I2C2_CLKSOURCE_CSI + * @arg @ref LL_RCC_I2C3_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_I2C3_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_I2C3_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_I2C3_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_I2C4_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_I2C4_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_I2C4_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_I2C4_CLKSOURCE_CSI (*) + * + * (*) : For stm32h56xxx and stm32h57xxx family lines only. + * (**) : For stm32h503xx family line only. + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetI2CClockSource(uint32_t I2CxSource) +{ + LL_RCC_SetClockSource(I2CxSource); +} + +/** + * @brief Configure I3Cx kernel clock source + * @rmtoll CCIPR4 I3C1SEL LL_RCC_SetI3CClockSource\n + * CCIPR4 I3C2SEL LL_RCC_SetI3CClockSource + * @param I3CxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_I3C1_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_I3C1_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_I3C1_CLKSOURCE_PLL2R (**) + * @arg @ref LL_RCC_I3C1_CLKSOURCE_HSI + * @arg @ref LL_RCC_I3C1_CLKSOURCE_NONE + * @arg @ref LL_RCC_I3C2_CLKSOURCE_PCLK3 (**) + * @arg @ref LL_RCC_I3C2_CLKSOURCE_PLL2R (**) + * @arg @ref LL_RCC_I3C2_CLKSOURCE_HSI (**) + * @arg @ref LL_RCC_I3C2_CLKSOURCE_NONE (**) + * @retval None + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + * (**) : For stm32h503xx family line. + */ +__STATIC_INLINE void LL_RCC_SetI3CClockSource(uint32_t I3CxSource) +{ + LL_RCC_SetClockSource(I3CxSource); +} + +/** + * @brief Configure SPIx kernel clock source + * @rmtoll CCIPR3 SPI1SEL LL_RCC_SetSPIClockSource\n + * CCIPR3 SPI2SEL LL_RCC_SetSPIClockSource\n + * CCIPR3 SPI3SEL LL_RCC_SetSPIClockSource\n + * CCIPR3 SPI4SEL LL_RCC_SetSPIClockSource\n + * CCIPR3 SPI5SEL LL_RCC_SetSPIClockSource\n + * CCIPR3 SPI6SEL LL_RCC_SetSPIClockSource + * @param SPIxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_SPI1_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_SPI1_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_SPI1_CLKSOURCE_PLL3P (*) + * @arg @ref LL_RCC_SPI1_CLKSOURCE_PIN + * @arg @ref LL_RCC_SPI1_CLKSOURCE_CLKP + * @arg @ref LL_RCC_SPI2_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_SPI2_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_SPI2_CLKSOURCE_PLL3P (*) + * @arg @ref LL_RCC_SPI2_CLKSOURCE_PIN + * @arg @ref LL_RCC_SPI2_CLKSOURCE_CLKP + * @arg @ref LL_RCC_SPI3_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_SPI3_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_SPI3_CLKSOURCE_PLL3P (*) + * @arg @ref LL_RCC_SPI3_CLKSOURCE_PIN + * @arg @ref LL_RCC_SPI3_CLKSOURCE_CLKP + * @arg @ref LL_RCC_SPI4_CLKSOURCE_PCLK2 (*) + * @arg @ref LL_RCC_SPI4_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_SPI4_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_SPI4_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_SPI4_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_SPI4_CLKSOURCE_HSE (*) + * @arg @ref LL_RCC_SPI5_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_SPI5_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_SPI5_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_SPI5_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_SPI5_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_SPI5_CLKSOURCE_HSE (*) + * @arg @ref LL_RCC_SPI6_CLKSOURCE_PCLK2 (*) + * @arg @ref LL_RCC_SPI6_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_SPI6_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_SPI6_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_SPI6_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_SPI6_CLKSOURCE_HSE (*) + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetSPIClockSource(uint32_t SPIxSource) +{ + LL_RCC_SetClockSource(SPIxSource); +} + +/** + * @brief Configure LPTIMx kernel clock source + * @rmtoll CCIPR2 LPTIM1SEL LL_RCC_SetLPTIMClockSource\n + * CCIPR2 LPTIM2SEL LL_RCC_SetLPTIMClockSource\n + * CCIPR2 LPTIM3SEL LL_RCC_SetLPTIMClockSource\n + * CCIPR2 LPTIM4SEL LL_RCC_SetLPTIMClockSource\n + * CCIPR2 LPTIM5SEL LL_RCC_SetLPTIMClockSource\n + * CCIPR2 LPTIM6SEL LL_RCC_SetLPTIMClockSource + * @param LPTIMxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE_PCLK3 + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE_LSE + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE_LSI + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE_CLKP + * @arg @ref LL_RCC_LPTIM2_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_LPTIM2_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_LPTIM2_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_LPTIM2_CLKSOURCE_LSE + * @arg @ref LL_RCC_LPTIM2_CLKSOURCE_LSI + * @arg @ref LL_RCC_LPTIM2_CLKSOURCE_CLKP + * @arg @ref LL_RCC_LPTIM3_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_LPTIM3_CLKSOURCE_PLL2P (*) + * @arg @ref LL_RCC_LPTIM3_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_LPTIM3_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_LPTIM3_CLKSOURCE_LSI (*) + * @arg @ref LL_RCC_LPTIM3_CLKSOURCE_CLKP (*) + * @arg @ref LL_RCC_LPTIM4_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_LPTIM4_CLKSOURCE_PLL2P (*) + * @arg @ref LL_RCC_LPTIM4_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_LPTIM4_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_LPTIM4_CLKSOURCE_LSI (*) + * @arg @ref LL_RCC_LPTIM4_CLKSOURCE_CLKP (*) + * @arg @ref LL_RCC_LPTIM5_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_LPTIM5_CLKSOURCE_PLL2P (*) + * @arg @ref LL_RCC_LPTIM5_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_LPTIM5_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_LPTIM5_CLKSOURCE_LSI (*) + * @arg @ref LL_RCC_LPTIM5_CLKSOURCE_CLKP (*) + * @arg @ref LL_RCC_LPTIM6_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_LPTIM6_CLKSOURCE_PLL2P (*) + * @arg @ref LL_RCC_LPTIM6_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_LPTIM6_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_LPTIM6_CLKSOURCE_LSI (*) + * @arg @ref LL_RCC_LPTIM6_CLKSOURCE_CLKP (*) + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetLPTIMClockSource(uint32_t LPTIMxSource) +{ + LL_RCC_SetClockSource(LPTIMxSource); +} + +/** + * @brief Configure FDCAN kernel clock source + * @rmtoll CCIPR5 FDCANSEL LL_RCC_SetFDCANClockSource + * @param FDCANxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_FDCAN_CLKSOURCE_HSE + * @arg @ref LL_RCC_FDCAN_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_FDCAN_CLKSOURCE_PLL2Q + * @retval None + * + */ +__STATIC_INLINE void LL_RCC_SetFDCANClockSource(uint32_t FDCANxSource) +{ + MODIFY_REG(RCC->CCIPR5, RCC_CCIPR5_FDCANSEL, FDCANxSource); +} + +#if defined(SAI1) +/** + * @brief Configure SAIx kernel clock source + * @rmtoll CCIPR2 SAI1SEL LL_RCC_SetSAIClockSource\n + * CCIPR2 SAI2SEL LL_RCC_SetSAIClockSource + * @param SAIxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_SAI1_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_SAI1_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_SAI1_CLKSOURCE_PLL3P + * @arg @ref LL_RCC_SAI1_CLKSOURCE_PIN + * @arg @ref LL_RCC_SAI1_CLKSOURCE_CLKP + * @arg @ref LL_RCC_SAI2_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_SAI2_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_SAI2_CLKSOURCE_PLL3P + * @arg @ref LL_RCC_SAI2_CLKSOURCE_PIN + * @arg @ref LL_RCC_SAI2_CLKSOURCE_CLKP + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetSAIClockSource(uint32_t SAIxSource) +{ + LL_RCC_SetClockSource(SAIxSource); +} +#endif /* SAI1 */ + +#if defined(SDMMC1) +/** + * @brief Configure SDMMCx kernel clock source + * @rmtoll CCIPR4 SDMMC1SEL LL_RCC_SetSDMMCClockSource + * @rmtoll CCIPR4 SDMMC2SEL LL_RCC_SetSDMMCClockSource + * @param SDMMCxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_SDMMC1_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_SDMMC1_CLKSOURCE_PLL2R + * @arg @ref LL_RCC_SDMMC2_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_SDMMC2_CLKSOURCE_PLL2R + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetSDMMCClockSource(uint32_t SDMMCxSource) +{ + LL_RCC_SetClockSource(SDMMCxSource); +} +#endif /* SDMMC1 */ + +/** + * @brief Configure RNG kernel clock source + * @rmtoll CCIPR5 RNGSEL LL_RCC_SetRNGClockSource + * @param RNGxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_RNG_CLKSOURCE_HSI48 + * @arg @ref LL_RCC_RNG_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_RNG_CLKSOURCE_LSE + * @arg @ref LL_RCC_RNG_CLKSOURCE_LSI + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetRNGClockSource(uint32_t RNGxSource) +{ + MODIFY_REG(RCC->CCIPR5, RCC_CCIPR5_RNGSEL, RNGxSource); +} + +/** + * @brief Configure USB clock source + * @rmtoll CCIPR4 USBSEL LL_RCC_SetUSBClockSource + * @param USBxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_USB_CLKSOURCE_NONE + * @arg @ref LL_RCC_USB_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_USB_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_USB_CLKSOURCE_HSI48 + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetUSBClockSource(uint32_t USBxSource) +{ + MODIFY_REG(RCC->CCIPR4, RCC_CCIPR4_USBSEL, USBxSource); +} + +/** + * @brief Configure ADCx kernel clock source + * @rmtoll CCIPR5 ADCDACSEL LL_RCC_SetADCDACClockSource + * @param ADCDACxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_ADCDAC_CLKSOURCE_HCLK + * @arg @ref LL_RCC_ADCDAC_CLKSOURCE_SYSCLK + * @arg @ref LL_RCC_ADCDAC_CLKSOURCE_PLL2R + * @arg @ref LL_RCC_ADCDAC_CLKSOURCE_HSE + * @arg @ref LL_RCC_ADCDAC_CLKSOURCE_HSI + * @arg @ref LL_RCC_ADCDAC_CLKSOURCE_CSI + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetADCDACClockSource(uint32_t ADCDACxSource) +{ + MODIFY_REG(RCC->CCIPR5, RCC_CCIPR5_ADCDACSEL, ADCDACxSource); +} + +/** + * @brief Configure DAC low-power kernel clock source + * @rmtoll CCIPR5 DACSEL LL_RCC_SetDACLPClockSource + * @param DACLPxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_DAC_LP_CLKSOURCE_LSE + * @arg @ref LL_RCC_DAC_LP_CLKSOURCE_LSI + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetDACLPClockSource(uint32_t DACLPxSource) +{ + MODIFY_REG(RCC->CCIPR5, RCC_CCIPR5_DACSEL, DACLPxSource); +} + +#if defined(CEC) +/** + * @brief Configure CECx kernel clock source + * @rmtoll CCIPR5 CECSEL LL_RCC_SetCECClockSource + * @param CECxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_CEC_CLKSOURCE_LSE + * @arg @ref LL_RCC_CEC_CLKSOURCE_LSI + * @arg @ref LL_RCC_CEC_CLKSOURCE_CSI_DIV122 + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetCECClockSource(uint32_t CECxSource) +{ + MODIFY_REG(RCC->CCIPR5, RCC_CCIPR5_CECSEL, CECxSource); +} +#endif /* CEC */ + +#if defined(OCTOSPI1) +/** + * @brief Configure OCTOSPIx kernel clock source + * @rmtoll CCIPR4 OCTOSPISEL LL_RCC_SetOCTOSPIClockSource + * @param OCTOSPIxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_OSPI_CLKSOURCE_HCLK + * @arg @ref LL_RCC_OSPI_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_OSPI_CLKSOURCE_PLL2R + * @arg @ref LL_RCC_OSPI_CLKSOURCE_CLKP + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetOCTOSPIClockSource(uint32_t OCTOSPIxSource) +{ + MODIFY_REG(RCC->CCIPR4, RCC_CCIPR4_OCTOSPISEL, OCTOSPIxSource); +} +#endif /* OCTOSPI1 */ + +/** + * @brief Configure CLKP Kernel clock source + * @rmtoll CCIPR5 CKPERSEL LL_RCC_SetCLKPClockSource + * @param ClkSource This parameter can be one of the following values: + * @arg @ref LL_RCC_CLKP_CLKSOURCE_HSI + * @arg @ref LL_RCC_CLKP_CLKSOURCE_CSI + * @arg @ref LL_RCC_CLKP_CLKSOURCE_HSE + * @arg @ref LL_RCC_CLKP_CLKSOURCE_NONE + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetCLKPClockSource(uint32_t ClkSource) +{ + MODIFY_REG(RCC->CCIPR5, RCC_CCIPR5_CKERPSEL, ClkSource); +} + + +/** + * @brief Get periph clock source + * @rmtoll CCIPR1 * LL_RCC_GetClockSource\n + * CCIPR2 * LL_RCC_GetClockSource\n + * CCIPR3 * LL_RCC_GetClockSource\n + * CCIPR4 * LL_RCC_GetClockSource\n + * CCIPR5 * LL_RCC_GetClockSource + * @param Periph This parameter can be one of the following values: + * @arg @ref LL_RCC_USART1_CLKSOURCE + * @arg @ref LL_RCC_USART2_CLKSOURCE + * @arg @ref LL_RCC_USART3_CLKSOURCE + * @arg @ref LL_RCC_USART6_CLKSOURCE (*) + * @arg @ref LL_RCC_USART10_CLKSOURCE (*) + * @arg @ref LL_RCC_USART11_CLKSOURCE (*) + * @arg @ref LL_RCC_UART4_CLKSOURCE (*) + * @arg @ref LL_RCC_UART5_CLKSOURCE (*) + * @arg @ref LL_RCC_UART7_CLKSOURCE (*) + * @arg @ref LL_RCC_UART8_CLKSOURCE (*) + * @arg @ref LL_RCC_UART9_CLKSOURCE (*) + * @arg @ref LL_RCC_UART12_CLKSOURCE (*) + * @arg @ref LL_RCC_SPI1_CLKSOURCE + * @arg @ref LL_RCC_SPI2_CLKSOURCE + * @arg @ref LL_RCC_SPI3_CLKSOURCE + * @arg @ref LL_RCC_SPI4_CLKSOURCE (*) + * @arg @ref LL_RCC_SPI5_CLKSOURCE (*) + * @arg @ref LL_RCC_SPI6_CLKSOURCE (*) + * @arg @ref LL_RCC_I2C1_CLKSOURCE + * @arg @ref LL_RCC_I2C2_CLKSOURCE + * @arg @ref LL_RCC_I2C3_CLKSOURCE (*) + * @arg @ref LL_RCC_I2C4_CLKSOURCE (*) + * @arg @ref LL_RCC_I3C1_CLKSOURCE + * @arg @ref LL_RCC_I3C2_CLKSOURCE (*) + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE + * @arg @ref LL_RCC_LPTIM2_CLKSOURCE + * @arg @ref LL_RCC_LPTIM3_CLKSOURCE (*) + * @arg @ref LL_RCC_LPTIM4_CLKSOURCE (*) + * @arg @ref LL_RCC_LPTIM5_CLKSOURCE (*) + * @arg @ref LL_RCC_LPTIM6_CLKSOURCE (*) + * @arg @ref LL_RCC_SAI1_CLKSOURCE (*) + * @arg @ref LL_RCC_SAI2_CLKSOURCE (*) + * @arg @ref LL_RCC_SDMMC1_CLKSOURCE (*) + * @arg @ref LL_RCC_SDMMC2_CLKSOURCE (*) + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_USART1_CLKSOURCE_PCLK2 + * @arg @ref LL_RCC_USART1_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_USART1_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_USART1_CLKSOURCE_HSI + * @arg @ref LL_RCC_USART1_CLKSOURCE_CSI + * @arg @ref LL_RCC_USART1_CLKSOURCE_LSE + * @arg @ref LL_RCC_USART2_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_USART2_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_USART2_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_USART2_CLKSOURCE_HSI + * @arg @ref LL_RCC_USART2_CLKSOURCE_CSI + * @arg @ref LL_RCC_USART2_CLKSOURCE_LSE + * @arg @ref LL_RCC_USART3_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_USART3_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_USART3_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_USART3_CLKSOURCE_HSI + * @arg @ref LL_RCC_USART3_CLKSOURCE_CSI + * @arg @ref LL_RCC_USART3_CLKSOURCE_LSE + * @arg @ref LL_RCC_USART6_CLKSOURCE_PCLK1 (*) + * @arg @ref LL_RCC_USART6_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_USART6_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_USART6_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_USART6_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_USART6_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_USART10_CLKSOURCE_PCLK1 (*) + * @arg @ref LL_RCC_USART10_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_USART10_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_USART10_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_USART10_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_USART10_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_USART11_CLKSOURCE_PCLK1 (*) + * @arg @ref LL_RCC_USART11_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_USART11_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_USART11_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_USART11_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_USART11_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_UART4_CLKSOURCE_PCLK1 (*) + * @arg @ref LL_RCC_UART4_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_UART4_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_UART4_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_UART4_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_UART4_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_UART5_CLKSOURCE_PCLK1 (*) + * @arg @ref LL_RCC_UART5_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_UART5_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_UART5_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_UART5_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_UART5_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_UART7_CLKSOURCE_PCLK1 (*) + * @arg @ref LL_RCC_UART7_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_UART7_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_UART7_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_UART7_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_UART7_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_UART8_CLKSOURCE_PCLK1 (*) + * @arg @ref LL_RCC_UART8_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_UART8_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_UART8_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_UART8_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_UART8_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_UART9_CLKSOURCE_PCLK1 (*) + * @arg @ref LL_RCC_UART9_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_UART9_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_UART9_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_UART9_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_UART9_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_UART12_CLKSOURCE_PCLK1 (*) + * @arg @ref LL_RCC_UART12_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_UART12_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_UART12_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_UART12_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_UART12_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_LPUART1_CLKSOURCE_PCLK3 + * @arg @ref LL_RCC_LPUART1_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_LPUART1_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_LPUART1_CLKSOURCE_HSI + * @arg @ref LL_RCC_LPUART1_CLKSOURCE_CSI + * @arg @ref LL_RCC_LPUART1_CLKSOURCE_LSE + * @arg @ref LL_RCC_I2C1_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_I2C1_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_I2C1_CLKSOURCE_PLL2R (*) + * @arg @ref LL_RCC_I2C1_CLKSOURCE_HSI + * @arg @ref LL_RCC_I2C1_CLKSOURCE_CSI + * @arg @ref LL_RCC_I2C2_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_I2C2_CLKSOURCE_PLL3R + * @arg @ref LL_RCC_I2C2_CLKSOURCE_PLL2R + * @arg @ref LL_RCC_I2C2_CLKSOURCE_HSI + * @arg @ref LL_RCC_I2C2_CLKSOURCE_CSI + * @arg @ref LL_RCC_I2C3_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_I2C3_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_I2C3_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_I2C3_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_I2C4_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_I2C4_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_I2C4_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_I2C4_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_I3C1_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_I3C1_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_I3C1_CLKSOURCE_PLL2R (*) + * @arg @ref LL_RCC_I3C1_CLKSOURCE_HSI + * @arg @ref LL_RCC_I3C1_CLKSOURCE_NONE + * @arg @ref LL_RCC_I3C2_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_I3C2_CLKSOURCE_PLL2R (*) + * @arg @ref LL_RCC_I3C2_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_I3C2_CLKSOURCE_NONE (*) + * @arg @ref LL_RCC_SPI1_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_SPI1_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_SPI1_CLKSOURCE_PLL3P + * @arg @ref LL_RCC_SPI1_CLKSOURCE_PIN + * @arg @ref LL_RCC_SPI1_CLKSOURCE_CLKP + * @arg @ref LL_RCC_SPI2_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_SPI2_CLKSOURCE_PLL2P (*) + * @arg @ref LL_RCC_SPI2_CLKSOURCE_PLL3P (*) + * @arg @ref LL_RCC_SPI2_CLKSOURCE_PIN + * @arg @ref LL_RCC_SPI2_CLKSOURCE_CLKP + * @arg @ref LL_RCC_SPI3_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_SPI3_CLKSOURCE_PLL2P (*) + * @arg @ref LL_RCC_SPI3_CLKSOURCE_PLL3P (*) + * @arg @ref LL_RCC_SPI3_CLKSOURCE_PIN + * @arg @ref LL_RCC_SPI3_CLKSOURCE_CLKP + * @arg @ref LL_RCC_SPI4_CLKSOURCE_PCLK2 (*) + * @arg @ref LL_RCC_SPI4_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_SPI4_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_SPI4_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_SPI4_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_SPI4_CLKSOURCE_HSE (*) + * @arg @ref LL_RCC_SPI5_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_SPI5_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_SPI5_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_SPI5_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_SPI5_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_SPI5_CLKSOURCE_HSE (*) + * @arg @ref LL_RCC_SPI6_CLKSOURCE_PCLK2 (*) + * @arg @ref LL_RCC_SPI6_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_SPI6_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_SPI6_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_SPI6_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_SPI6_CLKSOURCE_HSE (*) + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE_PCLK3 + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE_PLL3R + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE_LSE + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE_LSI + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE_CLKP + * @arg @ref LL_RCC_LPTIM2_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_LPTIM2_CLKSOURCE_PLL2P (*) + * @arg @ref LL_RCC_LPTIM2_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_LPTIM2_CLKSOURCE_LSE + * @arg @ref LL_RCC_LPTIM2_CLKSOURCE_LSI + * @arg @ref LL_RCC_LPTIM2_CLKSOURCE_CLKP + * @arg @ref LL_RCC_LPTIM3_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_LPTIM3_CLKSOURCE_PLL2P (*) + * @arg @ref LL_RCC_LPTIM3_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_LPTIM3_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_LPTIM3_CLKSOURCE_LSI (*) + * @arg @ref LL_RCC_LPTIM3_CLKSOURCE_CLKP (*) + * @arg @ref LL_RCC_LPTIM4_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_LPTIM4_CLKSOURCE_PLL2P (*) + * @arg @ref LL_RCC_LPTIM4_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_LPTIM4_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_LPTIM4_CLKSOURCE_LSI (*) + * @arg @ref LL_RCC_LPTIM4_CLKSOURCE_CLKP (*) + * @arg @ref LL_RCC_LPTIM5_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_LPTIM5_CLKSOURCE_PLL2P (*) + * @arg @ref LL_RCC_LPTIM5_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_LPTIM5_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_LPTIM5_CLKSOURCE_LSI (*) + * @arg @ref LL_RCC_LPTIM5_CLKSOURCE_CLKP (*) + * @arg @ref LL_RCC_LPTIM6_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_LPTIM6_CLKSOURCE_PLL2P (*) + * @arg @ref LL_RCC_LPTIM6_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_LPTIM6_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_LPTIM6_CLKSOURCE_LSI (*) + * @arg @ref LL_RCC_LPTIM6_CLKSOURCE_CLKP (*) + * @arg @ref LL_RCC_SAI1_CLKSOURCE_PLL1Q (*) + * @arg @ref LL_RCC_SAI1_CLKSOURCE_PLL2P (*) + * @arg @ref LL_RCC_SAI1_CLKSOURCE_PLL3P (*) + * @arg @ref LL_RCC_SAI1_CLKSOURCE_PIN (*) + * @arg @ref LL_RCC_SAI1_CLKSOURCE_CLKP (*) + * @arg @ref LL_RCC_SAI2_CLKSOURCE_PLL1Q (*) + * @arg @ref LL_RCC_SAI2_CLKSOURCE_PLL2P (*) + * @arg @ref LL_RCC_SAI2_CLKSOURCE_PLL3P (*) + * @arg @ref LL_RCC_SAI2_CLKSOURCE_PIN (*) + * @arg @ref LL_RCC_SAI2_CLKSOURCE_CLKP (*) + * @arg @ref LL_RCC_SDMMC1_CLKSOURCE_PLL1Q (*) + * @arg @ref LL_RCC_SDMMC1_CLKSOURCE_PLL2R (*) + * @arg @ref LL_RCC_SDMMC2_CLKSOURCE_PLL1Q (*) + * @arg @ref LL_RCC_SDMMC2_CLKSOURCE_PLL2R (*) + * + * (*) value not defined in all devices. + * @retval None + */ +__STATIC_INLINE uint32_t LL_RCC_GetClockSource(uint32_t Periph) +{ + const uint32_t *pReg = (uint32_t *)((uint32_t)((uint32_t)(&RCC->CCIPR1) + LL_CLKSOURCE_REG(Periph))); + return (uint32_t)(Periph | (((READ_BIT(*pReg, LL_CLKSOURCE_MASK(Periph))) >> \ + LL_CLKSOURCE_SHIFT(Periph)) << LL_RCC_CONFIG_SHIFT)); +} + +/** + * @brief Get USARTx kernel clock source + * @rmtoll CCIPR1 USART1SEL LL_RCC_GetUSARTClockSource\n + * CCIPR1 USART2SEL LL_RCC_GetUSARTClockSource\n + * CCIPR1 USART3SEL LL_RCC_GetUSARTClockSource\n + * CCIPR1 USART6SEL LL_RCC_GetUSARTClockSource\n + * CCIPR1 USART10SEL LL_RCC_GetUSARTClockSource\n + * CCIPR2 USART11SEL LL_RCC_GetUSARTClockSource + * @param USARTx This parameter can be one of the following values: + * @arg @ref LL_RCC_USART1_CLKSOURCE + * @arg @ref LL_RCC_USART2_CLKSOURCE + * @arg @ref LL_RCC_USART3_CLKSOURCE + * @arg @ref LL_RCC_USART6_CLKSOURCE (*) + * @arg @ref LL_RCC_USART10_CLKSOURCE (*) + * @arg @ref LL_RCC_USART11_CLKSOURCE (*) + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_USART1_CLKSOURCE_PCLK2 + * @arg @ref LL_RCC_USART1_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_USART1_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_USART1_CLKSOURCE_HSI + * @arg @ref LL_RCC_USART1_CLKSOURCE_CSI + * @arg @ref LL_RCC_USART1_CLKSOURCE_LSE + * @arg @ref LL_RCC_USART2_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_USART2_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_USART2_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_USART2_CLKSOURCE_HSI + * @arg @ref LL_RCC_USART2_CLKSOURCE_CSI + * @arg @ref LL_RCC_USART2_CLKSOURCE_LSE + * @arg @ref LL_RCC_USART3_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_USART3_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_USART3_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_USART3_CLKSOURCE_HSI + * @arg @ref LL_RCC_USART3_CLKSOURCE_CSI + * @arg @ref LL_RCC_USART3_CLKSOURCE_LSE + * @arg @ref LL_RCC_USART6_CLKSOURCE_PCLK1 (*) + * @arg @ref LL_RCC_USART6_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_USART6_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_USART6_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_USART6_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_USART6_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_USART10_CLKSOURCE_PCLK1 (*) + * @arg @ref LL_RCC_USART10_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_USART10_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_USART10_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_USART10_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_USART10_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_USART11_CLKSOURCE_PCLK1 (*) + * @arg @ref LL_RCC_USART11_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_USART11_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_USART11_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_USART11_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_USART11_CLKSOURCE_LSE (*) + * + * (*) : For stm32h56xxx and stm32h57xxx family lines only. + */ +__STATIC_INLINE uint32_t LL_RCC_GetUSARTClockSource(uint32_t USARTx) +{ + return LL_RCC_GetClockSource(USARTx); +} + +#if defined(UART4) +/** + * @brief Get UARTx kernel clock source + * @rmtoll CCIPR1 UART4SEL LL_RCC_GetUARTClockSource\n + * CCIPR1 UART5SEL LL_RCC_GetUARTClockSource\n + * CCIPR1 UART7SEL LL_RCC_GetUARTClockSource\n + * CCIPR1 UART8SEL LL_RCC_GetUARTClockSource\n + * CCIPR1 UART9SEL LL_RCC_GetUARTClockSource\n + * CCIPR2 UART12SEL LL_RCC_GetUARTClockSource + * @param UARTx This parameter can be one of the following values: + * @arg @ref LL_RCC_UART4_CLKSOURCE + * @arg @ref LL_RCC_UART5_CLKSOURCE + * @arg @ref LL_RCC_UART7_CLKSOURCE + * @arg @ref LL_RCC_UART8_CLKSOURCE + * @arg @ref LL_RCC_UART9_CLKSOURCE + * @arg @ref LL_RCC_UART12_CLKSOURCE + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_UART4_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_UART4_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_UART4_CLKSOURCE_PLL3Q + * @arg @ref LL_RCC_UART4_CLKSOURCE_HSI + * @arg @ref LL_RCC_UART4_CLKSOURCE_CSI + * @arg @ref LL_RCC_UART4_CLKSOURCE_LSE + * @arg @ref LL_RCC_UART5_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_UART5_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_UART5_CLKSOURCE_PLL3Q + * @arg @ref LL_RCC_UART5_CLKSOURCE_HSI + * @arg @ref LL_RCC_UART5_CLKSOURCE_CSI + * @arg @ref LL_RCC_UART5_CLKSOURCE_LSE + * @arg @ref LL_RCC_UART7_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_UART7_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_UART7_CLKSOURCE_PLL3Q + * @arg @ref LL_RCC_UART7_CLKSOURCE_HSI + * @arg @ref LL_RCC_UART7_CLKSOURCE_CSI + * @arg @ref LL_RCC_UART7_CLKSOURCE_LSE + * @arg @ref LL_RCC_UART8_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_UART8_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_UART8_CLKSOURCE_PLL3Q + * @arg @ref LL_RCC_UART8_CLKSOURCE_HSI + * @arg @ref LL_RCC_UART8_CLKSOURCE_CSI + * @arg @ref LL_RCC_UART8_CLKSOURCE_LSE + * @arg @ref LL_RCC_UART9_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_UART9_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_UART9_CLKSOURCE_PLL3Q + * @arg @ref LL_RCC_UART9_CLKSOURCE_HSI + * @arg @ref LL_RCC_UART9_CLKSOURCE_CSI + * @arg @ref LL_RCC_UART9_CLKSOURCE_LSE + * @arg @ref LL_RCC_UART12_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_UART12_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_UART12_CLKSOURCE_PLL3Q + * @arg @ref LL_RCC_UART12_CLKSOURCE_HSI + * @arg @ref LL_RCC_UART12_CLKSOURCE_CSI + * @arg @ref LL_RCC_UART12_CLKSOURCE_LSE + */ +__STATIC_INLINE uint32_t LL_RCC_GetUARTClockSource(uint32_t UARTx) +{ + return LL_RCC_GetClockSource(UARTx); +} +#endif /* UART4 */ + +/** + * @brief Get LPUARTx kernel clock source + * @rmtoll CCIPR3 LPUART1SEL LL_RCC_GetLPUARTClockSource + * @param LPUARTx This parameter can be one of the following values: + * @arg @ref LL_RCC_LPUART1_CLKSOURCE + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_LPUART1_CLKSOURCE_PCLK3 + * @arg @ref LL_RCC_LPUART1_CLKSOURCE_PLL2Q + * @arg @ref LL_RCC_LPUART1_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_LPUART1_CLKSOURCE_HSI + * @arg @ref LL_RCC_LPUART1_CLKSOURCE_CSI + * @arg @ref LL_RCC_LPUART1_CLKSOURCE_LSE + * + * (*) : For stm32h56xxx and stm32h57xxx family lines only. + */ +__STATIC_INLINE uint32_t LL_RCC_GetLPUARTClockSource(uint32_t LPUARTx) +{ + return (uint32_t)(READ_BIT(RCC->CCIPR3, LPUARTx)); +} + +/** + * @brief Get I2Cx kernel clock source + * @rmtoll CCIPR4 I2C1SEL LL_RCC_GetI2CClockSource\n + * CCIPR4 I2C2SEL LL_RCC_GetI2CClockSource\n + * CCIPR4 I2C3SEL LL_RCC_GetI2CClockSource\n + * CCIPR4 I2C4SEL LL_RCC_GetI2CClockSource + * @param I2Cx This parameter can be one of the following values: + * @arg @ref LL_RCC_I2C1_CLKSOURCE + * @arg @ref LL_RCC_I2C2_CLKSOURCE + * @arg @ref LL_RCC_I2C3_CLKSOURCE (*) + * @arg @ref LL_RCC_I2C4_CLKSOURCE (*) + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_I2C1_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_I2C1_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_I2C1_CLKSOURCE_PLL2R (**) + * @arg @ref LL_RCC_I2C1_CLKSOURCE_HSI + * @arg @ref LL_RCC_I2C1_CLKSOURCE_CSI + * @arg @ref LL_RCC_I2C2_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_I2C2_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_I2C2_CLKSOURCE_PLL2R (**) + * @arg @ref LL_RCC_I2C2_CLKSOURCE_HSI + * @arg @ref LL_RCC_I2C2_CLKSOURCE_CSI + * @arg @ref LL_RCC_I2C3_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_I2C3_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_I2C3_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_I2C3_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_I2C4_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_I2C4_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_I2C4_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_I2C4_CLKSOURCE_CSI (*) + * + * (*) : For stm32h56xxx and stm32h57xxx family lines only. + * (**) : For stm32h503xx family line only. + */ +__STATIC_INLINE uint32_t LL_RCC_GetI2CClockSource(uint32_t I2Cx) +{ + return LL_RCC_GetClockSource(I2Cx); +} + +/** + * @brief Get I3Cx kernel clock source + * @rmtoll CCIPR4 I3C1SEL LL_RCC_GetI3CClockSource\n + * CCIPR4 I3C2SEL LL_RCC_GetI3CClockSource + * @param I3Cx This parameter can be one of the following values: + * @arg @ref LL_RCC_I3C1_CLKSOURCE + * @arg @ref LL_RCC_I3C2_CLKSOURCE (**) + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_I3C1_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_I3C1_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_I3C1_CLKSOURCE_PLL2R (**) + * @arg @ref LL_RCC_I3C1_CLKSOURCE_HSI + * @arg @ref LL_RCC_I3C1_CLKSOURCE_NONE + * @arg @ref LL_RCC_I3C2_CLKSOURCE_PCLK3 (**) + * @arg @ref LL_RCC_I3C2_CLKSOURCE_PLL2R (**) + * @arg @ref LL_RCC_I3C2_CLKSOURCE_HSI (**) + * @arg @ref LL_RCC_I3C2_CLKSOURCE_NONE (**) + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + * (**) : For stm32h503xx family line. + */ +__STATIC_INLINE uint32_t LL_RCC_GetI3CClockSource(uint32_t I3Cx) +{ + return LL_RCC_GetClockSource(I3Cx); +} + +/** + * @brief Get SPIx kernel clock source + * @rmtoll CCIPR3 SPI1SEL LL_RCC_GetSPIClockSource\n + * CCIPR3 SPI2SEL LL_RCC_GetSPIClockSource\n + * CCIPR3 SPI3SEL LL_RCC_GetSPIClockSource\n + * CCIPR3 SPI4SEL LL_RCC_GetSPIClockSource\n + * CCIPR3 SPI5SEL LL_RCC_GetSPIClockSource\n + * CCIPR3 SPI6SEL LL_RCC_GetSPIClockSource + * @param SPIx This parameter can be one of the following values: + * @arg @ref LL_RCC_SPI1_CLKSOURCE + * @arg @ref LL_RCC_SPI2_CLKSOURCE + * @arg @ref LL_RCC_SPI3_CLKSOURCE + * @arg @ref LL_RCC_SPI4_CLKSOURCE (*) + * @arg @ref LL_RCC_SPI5_CLKSOURCE (*) + * @arg @ref LL_RCC_SPI6_CLKSOURCE (*) + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_SPI1_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_SPI1_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_SPI1_CLKSOURCE_PLL3P (*) + * @arg @ref LL_RCC_SPI1_CLKSOURCE_PIN + * @arg @ref LL_RCC_SPI1_CLKSOURCE_CLKP + * @arg @ref LL_RCC_SPI2_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_SPI2_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_SPI2_CLKSOURCE_PLL3P (*) + * @arg @ref LL_RCC_SPI2_CLKSOURCE_PIN + * @arg @ref LL_RCC_SPI2_CLKSOURCE_CLKP + * @arg @ref LL_RCC_SPI3_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_SPI3_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_SPI3_CLKSOURCE_PLL3P (*) + * @arg @ref LL_RCC_SPI3_CLKSOURCE_PIN + * @arg @ref LL_RCC_SPI3_CLKSOURCE_CLKP + * @arg @ref LL_RCC_SPI4_CLKSOURCE_PCLK2 (*) + * @arg @ref LL_RCC_SPI4_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_SPI4_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_SPI4_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_SPI4_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_SPI4_CLKSOURCE_HSE (*) + * @arg @ref LL_RCC_SPI5_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_SPI5_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_SPI5_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_SPI5_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_SPI5_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_SPI5_CLKSOURCE_HSE (*) + * @arg @ref LL_RCC_SPI6_CLKSOURCE_PCLK2 (*) + * @arg @ref LL_RCC_SPI6_CLKSOURCE_PLL2Q (*) + * @arg @ref LL_RCC_SPI6_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_SPI6_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_SPI6_CLKSOURCE_CSI (*) + * @arg @ref LL_RCC_SPI6_CLKSOURCE_HSE (*) + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + */ +__STATIC_INLINE uint32_t LL_RCC_GetSPIClockSource(uint32_t SPIx) +{ + return LL_RCC_GetClockSource(SPIx); +} + +/** + * @brief Get LPTIMx kernel clock source + * @rmtoll CCIPR2 LPTIM1SEL LL_RCC_GetLPTIMClockSource\n + * CCIPR2 LPTIM2SEL LL_RCC_GetLPTIMClockSource\n + * CCIPR2 LPTIM3SEL LL_RCC_GetLPTIMClockSource\n + * CCIPR2 LPTIM4SEL LL_RCC_GetLPTIMClockSource\n + * CCIPR2 LPTIM5SEL LL_RCC_GetLPTIMClockSource\n + * CCIPR2 LPTIM6SEL LL_RCC_GetLPTIMClockSource + * @param LPTIMx This parameter can be one of the following values: + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE + * @arg @ref LL_RCC_LPTIM2_CLKSOURCE + * @arg @ref LL_RCC_LPTIM3_CLKSOURCE (*) + * @arg @ref LL_RCC_LPTIM4_CLKSOURCE (*) + * @arg @ref LL_RCC_LPTIM5_CLKSOURCE (*) + * @arg @ref LL_RCC_LPTIM6_CLKSOURCE (*) + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE_PCLK3 + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE_LSE + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE_LSI + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE_CLKP + * @arg @ref LL_RCC_LPTIM2_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_LPTIM2_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_LPTIM2_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_LPTIM2_CLKSOURCE_LSE + * @arg @ref LL_RCC_LPTIM2_CLKSOURCE_LSI + * @arg @ref LL_RCC_LPTIM2_CLKSOURCE_CLKP + * @arg @ref LL_RCC_LPTIM3_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_LPTIM3_CLKSOURCE_PLL2P (*) + * @arg @ref LL_RCC_LPTIM3_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_LPTIM3_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_LPTIM3_CLKSOURCE_LSI (*) + * @arg @ref LL_RCC_LPTIM3_CLKSOURCE_CLKP (*) + * @arg @ref LL_RCC_LPTIM4_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_LPTIM4_CLKSOURCE_PLL2P (*) + * @arg @ref LL_RCC_LPTIM4_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_LPTIM4_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_LPTIM4_CLKSOURCE_LSI (*) + * @arg @ref LL_RCC_LPTIM4_CLKSOURCE_CLKP (*) + * @arg @ref LL_RCC_LPTIM5_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_LPTIM5_CLKSOURCE_PLL2P (*) + * @arg @ref LL_RCC_LPTIM5_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_LPTIM5_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_LPTIM5_CLKSOURCE_LSI (*) + * @arg @ref LL_RCC_LPTIM5_CLKSOURCE_CLKP (*) + * @arg @ref LL_RCC_LPTIM6_CLKSOURCE_PCLK3 (*) + * @arg @ref LL_RCC_LPTIM6_CLKSOURCE_PLL2P (*) + * @arg @ref LL_RCC_LPTIM6_CLKSOURCE_PLL3R (*) + * @arg @ref LL_RCC_LPTIM6_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_LPTIM6_CLKSOURCE_LSI (*) + * @arg @ref LL_RCC_LPTIM6_CLKSOURCE_CLKP (*) + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + */ +__STATIC_INLINE uint32_t LL_RCC_GetLPTIMClockSource(uint32_t LPTIMx) +{ + return LL_RCC_GetClockSource(LPTIMx); +} + +/** + * @brief Enable TIM2,15 and LPTIM2 Input capture clock source + * @rmtoll CCIPR1 TIMICSEL LL_RCC_TIMIC_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_TIMIC_Enable(void) +{ + SET_BIT(RCC->CCIPR1, RCC_CCIPR1_TIMICSEL); +} + +/** + * @brief Disable TIM2,15 and LPTIM2 Input capture clock source + * @rmtoll CCIPR1 TIMICSEL LL_RCC_TIMIC_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_TIMIC_Disable(void) +{ + CLEAR_BIT(RCC->CCIPR1, RCC_CCIPR1_TIMICSEL); +} + +/** + * @brief Get FDCAN kernel clock source + * @rmtoll CCIPR5 FDCANSEL LL_RCC_GetFDCANClockSource + * @param FDCANx This parameter can be one of the following values: + * @arg @ref LL_RCC_FDCAN_CLKSOURCE + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_FDCAN_CLKSOURCE_HSE + * @arg @ref LL_RCC_FDCAN_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_FDCAN_CLKSOURCE_PLL2Q + */ +__STATIC_INLINE uint32_t LL_RCC_GetFDCANClockSource(uint32_t FDCANx) +{ + return (uint32_t)(READ_BIT(RCC->CCIPR5, FDCANx)); +} + +#if defined(SAI1) +/** + * @brief Get SAIx kernel clock source + * @rmtoll CCIPR2 SAI1SEL LL_RCC_GetSAIClockSource\n + * CCIPR2 SAI2SEL LL_RCC_GetSAIClockSource + * @param SAIx This parameter can be one of the following values: + * @arg @ref LL_RCC_SAI1_CLKSOURCE + * @arg @ref LL_RCC_SAI2_CLKSOURCE + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_SAI1_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_SAI1_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_SAI1_CLKSOURCE_PLL3P + * @arg @ref LL_RCC_SAI1_CLKSOURCE_PIN + * @arg @ref LL_RCC_SAI1_CLKSOURCE_CLKP + * @arg @ref LL_RCC_SAI2_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_SAI2_CLKSOURCE_PLL2P + * @arg @ref LL_RCC_SAI2_CLKSOURCE_PLL3P + * @arg @ref LL_RCC_SAI2_CLKSOURCE_PIN + * @arg @ref LL_RCC_SAI2_CLKSOURCE_CLKP + */ +__STATIC_INLINE uint32_t LL_RCC_GetSAIClockSource(uint32_t SAIx) +{ + return LL_RCC_GetClockSource(SAIx); +} +#endif /* SAI1 */ + +#if defined(SDMMC1) +/** + * @brief Get SDMMCx kernel clock source + * @rmtoll CCIPR4 SDMMC1SEL LL_RCC_GetSDMMCClockSource + * CCIPR4 SDMMC2SEL LL_RCC_GetSDMMCClockSource + * @param SDMMCx This parameter can be one of the following values: + * @arg @ref LL_RCC_SDMMC1_CLKSOURCE + * @arg @ref LL_RCC_SDMMC2_CLKSOURCE (*) + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_SDMMC1_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_SDMMC1_CLKSOURCE_PLL2R + * @arg @ref LL_RCC_SDMMC2_CLKSOURCE_PLL1Q (*) + * @arg @ref LL_RCC_SDMMC2_CLKSOURCE_PLL2R (*) + * + * (*) value not defined in all devices. + */ +__STATIC_INLINE uint32_t LL_RCC_GetSDMMCClockSource(uint32_t SDMMCx) +{ + return LL_RCC_GetClockSource(SDMMCx); +} +#endif /* SDMMC1 */ + +/** + * @brief Get RNGx kernel clock source + * @rmtoll CCIPR5 RNGSEL LL_RCC_GetRNGClockSource + * @param RNGx This parameter can be one of the following values: + * @arg @ref LL_RCC_RNG_CLKSOURCE + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_RNG_CLKSOURCE_HSI48 + * @arg @ref LL_RCC_RNG_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_RNG_CLKSOURCE_LSE + * @arg @ref LL_RCC_RNG_CLKSOURCE_LSI + */ +__STATIC_INLINE uint32_t LL_RCC_GetRNGClockSource(uint32_t RNGx) +{ + return (uint32_t)(READ_BIT(RCC->CCIPR5, RNGx)); +} + +/** + * @brief Get USB clock source + * @rmtoll CCIPR4 USBSEL LL_RCC_GetUSBClockSource + * @param USBx This parameter can be one of the following values: + * @arg @ref LL_RCC_USB_CLKSOURCE + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_USB_CLKSOURCE_NONE + * @arg @ref LL_RCC_USB_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_USB_CLKSOURCE_PLL3Q (*) + * @arg @ref LL_RCC_USB_CLKSOURCE_HSI48 + * + * (*) : For stm32h56xxx and stm32h57xxx family lines. + */ +__STATIC_INLINE uint32_t LL_RCC_GetUSBClockSource(uint32_t USBx) +{ + return (uint32_t)(READ_BIT(RCC->CCIPR4, USBx)); +} + +/** + * @brief Get ADCDACx kernel clock source + * @rmtoll CCIPR5 ADCDACSEL LL_RCC_GetADCDACClockSource + * @param ADCDACx This parameter can be one of the following values: + * @arg @ref LL_RCC_ADCDAC_CLKSOURCE + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_ADCDAC_CLKSOURCE_HCLK + * @arg @ref LL_RCC_ADCDAC_CLKSOURCE_SYSCLK + * @arg @ref LL_RCC_ADCDAC_CLKSOURCE_PLL2R + * @arg @ref LL_RCC_ADCDAC_CLKSOURCE_HSE + * @arg @ref LL_RCC_ADCDAC_CLKSOURCE_HSI + * @arg @ref LL_RCC_ADCDAC_CLKSOURCE_CSI + */ +__STATIC_INLINE uint32_t LL_RCC_GetADCDACClockSource(uint32_t ADCDACx) +{ + return (uint32_t)(READ_BIT(RCC->CCIPR5, ADCDACx)); +} + +/** + * @brief Get DAC low-power kernel Clock Source + * @rmtoll CCIPR5 DACSEL LL_RCC_GetDACLPClockSource + * @param DACLPx This parameter can be one of the following values: + * @arg @ref LL_RCC_DAC_LP_CLKSOURCE + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_DAC_LP_CLKSOURCE_LSE + * @arg @ref LL_RCC_DAC_LP_CLKSOURCE_LSI + */ +__STATIC_INLINE uint32_t LL_RCC_GetDACLPClockSource(uint32_t DACLPx) +{ + return (uint32_t)(READ_BIT(RCC->CCIPR5, DACLPx)); +} + +/** + * @brief Get CECx kernel clock source + * @rmtoll CCIPR5 CECSEL LL_RCC_GetCECClockSource + * @param CECx This parameter can be one of the following values: + * @arg @ref LL_RCC_CEC_CLKSOURCE + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_CEC_CLKSOURCE_LSE + * @arg @ref LL_RCC_CEC_CLKSOURCE_LSI + * @arg @ref LL_RCC_CEC_CLKSOURCE_CSI_DIV122 + */ +__STATIC_INLINE uint32_t LL_RCC_GetCECClockSource(uint32_t CECx) +{ + return (uint32_t)(READ_BIT(RCC->CCIPR5, CECx)); +} + +#if defined(OCTOSPI1) +/** + * @brief Get OCTOSPI kernel clock source + * @rmtoll CCIPR4 OCTOSPISEL LL_RCC_GetOCTOSPIClockSource + * @param OCTOSPIx This parameter can be one of the following values: + * @arg @ref LL_RCC_OCTOSPI_CLKSOURCE + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_OSPI_CLKSOURCE_HCLK + * @arg @ref LL_RCC_OSPI_CLKSOURCE_PLL1Q + * @arg @ref LL_RCC_OSPI_CLKSOURCE_PLL2R + * @arg @ref LL_RCC_OSPI_CLKSOURCE_CLKP + */ +__STATIC_INLINE uint32_t LL_RCC_GetOCTOSPIClockSource(uint32_t OCTOSPIx) +{ + return (uint32_t)(READ_BIT(RCC->CCIPR4, OCTOSPIx)); +} +#endif /* OCTOSPI1 */ + +/** + * @brief Get CLKP kernel clock source + * @rmtoll CCIPR5 CKPERSEL LL_RCC_GetCLKPClockSource + * @param CLKPx This parameter can be one of the following values: + * @arg @ref LL_RCC_CLKP_CLKSOURCE + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_CLKP_CLKSOURCE_HSI + * @arg @ref LL_RCC_CLKP_CLKSOURCE_CSI + * @arg @ref LL_RCC_CLKP_CLKSOURCE_HSE + * @arg @ref LL_RCC_CLKP_CLKSOURCE_NONE + */ +__STATIC_INLINE uint32_t LL_RCC_GetCLKPClockSource(uint32_t CLKPx) +{ + return (uint32_t)(READ_BIT(RCC->CCIPR5, CLKPx)); +} + +/** + * @brief Configure the Kernel wakeup clock source + * @rmtoll CFGR1 STOPKERWUCK LL_RCC_SetKerWakeUpClkSource + * @param Source This parameter can be one of the following values: + * @arg @ref LL_RCC_KERWAKEUP_CLKSOURCE_HSI + * @arg @ref LL_RCC_KERWAKEUP_CLKSOURCE_CSI + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetKerWakeUpClkSource(uint32_t Source) +{ + MODIFY_REG(RCC->CFGR1, RCC_CFGR1_STOPKERWUCK, Source); +} + +/** + * @brief Get the Kernel wakeup clock source + * @rmtoll CFGR1 STOPKERWUCK LL_RCC_GetKerWakeUpClkSource + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_KERWAKEUP_CLKSOURCE_HSI + * @arg @ref LL_RCC_KERWAKEUP_CLKSOURCE_CSI + */ +__STATIC_INLINE uint32_t LL_RCC_GetKerWakeUpClkSource(void) +{ + return (uint32_t)(READ_BIT(RCC->CFGR1, RCC_CFGR1_STOPKERWUCK)); +} + +/** + * @} + */ + +/** @defgroup RCC_LL_EF_RTC RTC + * @{ + */ + +/** + * @brief Set RTC Clock Source + * @note Once the RTC clock source has been selected, it cannot be changed anymore unless + * the Backup domain is reset, or unless a failure is detected on LSE (LSECSSD is + * set). The BDRST bit can be used to reset them. + * @rmtoll BDCR RTCSEL LL_RCC_SetRTCClockSource + * @param Source This parameter can be one of the following values: + * @arg @ref LL_RCC_RTC_CLKSOURCE_NONE + * @arg @ref LL_RCC_RTC_CLKSOURCE_LSE + * @arg @ref LL_RCC_RTC_CLKSOURCE_LSI + * @arg @ref LL_RCC_RTC_CLKSOURCE_HSE_DIV + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetRTCClockSource(uint32_t Source) +{ + MODIFY_REG(RCC->BDCR, RCC_BDCR_RTCSEL, Source); +} + +/** + * @brief Get RTC Clock Source + * @rmtoll BDCR RTCSEL LL_RCC_GetRTCClockSource + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_RTC_CLKSOURCE_NONE + * @arg @ref LL_RCC_RTC_CLKSOURCE_LSE + * @arg @ref LL_RCC_RTC_CLKSOURCE_LSI + * @arg @ref LL_RCC_RTC_CLKSOURCE_HSE_DIV + */ +__STATIC_INLINE uint32_t LL_RCC_GetRTCClockSource(void) +{ + return (uint32_t)(READ_BIT(RCC->BDCR, RCC_BDCR_RTCSEL)); +} + +/** + * @brief Enable RTC + * @rmtoll BDCR RTCEN LL_RCC_EnableRTC + * @retval None + */ +__STATIC_INLINE void LL_RCC_EnableRTC(void) +{ + SET_BIT(RCC->BDCR, RCC_BDCR_RTCEN); +} + +/** + * @brief Disable RTC + * @rmtoll BDCR RTCEN LL_RCC_DisableRTC + * @retval None + */ +__STATIC_INLINE void LL_RCC_DisableRTC(void) +{ + CLEAR_BIT(RCC->BDCR, RCC_BDCR_RTCEN); +} + +/** + * @brief Check if RTC has been enabled or not + * @rmtoll BDCR RTCEN LL_RCC_IsEnabledRTC + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsEnabledRTC(void) +{ + return ((READ_BIT(RCC->BDCR, RCC_BDCR_RTCEN) == RCC_BDCR_RTCEN) ? 1UL : 0UL); +} + +/** + * @brief Force the Backup domain reset + * @rmtoll BDCR BDRST LL_RCC_ForceBackupDomainReset + * @retval None + */ +__STATIC_INLINE void LL_RCC_ForceBackupDomainReset(void) +{ + SET_BIT(RCC->BDCR, RCC_BDCR_VSWRST); +} + +/** + * @brief Release the Backup domain reset + * @rmtoll BDCR BDRST LL_RCC_ReleaseBackupDomainReset + * @retval None + */ +__STATIC_INLINE void LL_RCC_ReleaseBackupDomainReset(void) +{ + CLEAR_BIT(RCC->BDCR, RCC_BDCR_VSWRST); +} + +/** + * @brief Set HSE Prescalers for RTC Clock + * @rmtoll CFGR1 RTCPRE LL_RCC_SetRTC_HSEPrescaler + * @param Prescaler This parameter can be one of the following values: + * @arg @ref LL_RCC_RTC_HSE_NOCLOCK + * @arg @ref LL_RCC_RTC_HSE_DIV_2 + * @arg @ref LL_RCC_RTC_HSE_DIV_3 + * @arg @ref LL_RCC_RTC_HSE_DIV_4 + * @arg @ref LL_RCC_RTC_HSE_DIV_5 + * @arg @ref LL_RCC_RTC_HSE_DIV_6 + * @arg @ref LL_RCC_RTC_HSE_DIV_7 + * @arg @ref LL_RCC_RTC_HSE_DIV_8 + * @arg @ref LL_RCC_RTC_HSE_DIV_9 + * @arg @ref LL_RCC_RTC_HSE_DIV_10 + * @arg @ref LL_RCC_RTC_HSE_DIV_11 + * @arg @ref LL_RCC_RTC_HSE_DIV_12 + * @arg @ref LL_RCC_RTC_HSE_DIV_13 + * @arg @ref LL_RCC_RTC_HSE_DIV_14 + * @arg @ref LL_RCC_RTC_HSE_DIV_15 + * @arg @ref LL_RCC_RTC_HSE_DIV_16 + * @arg @ref LL_RCC_RTC_HSE_DIV_17 + * @arg @ref LL_RCC_RTC_HSE_DIV_18 + * @arg @ref LL_RCC_RTC_HSE_DIV_19 + * @arg @ref LL_RCC_RTC_HSE_DIV_20 + * @arg @ref LL_RCC_RTC_HSE_DIV_21 + * @arg @ref LL_RCC_RTC_HSE_DIV_22 + * @arg @ref LL_RCC_RTC_HSE_DIV_23 + * @arg @ref LL_RCC_RTC_HSE_DIV_24 + * @arg @ref LL_RCC_RTC_HSE_DIV_25 + * @arg @ref LL_RCC_RTC_HSE_DIV_26 + * @arg @ref LL_RCC_RTC_HSE_DIV_27 + * @arg @ref LL_RCC_RTC_HSE_DIV_28 + * @arg @ref LL_RCC_RTC_HSE_DIV_29 + * @arg @ref LL_RCC_RTC_HSE_DIV_30 + * @arg @ref LL_RCC_RTC_HSE_DIV_31 + * @arg @ref LL_RCC_RTC_HSE_DIV_32 + * @arg @ref LL_RCC_RTC_HSE_DIV_33 + * @arg @ref LL_RCC_RTC_HSE_DIV_34 + * @arg @ref LL_RCC_RTC_HSE_DIV_35 + * @arg @ref LL_RCC_RTC_HSE_DIV_36 + * @arg @ref LL_RCC_RTC_HSE_DIV_37 + * @arg @ref LL_RCC_RTC_HSE_DIV_38 + * @arg @ref LL_RCC_RTC_HSE_DIV_39 + * @arg @ref LL_RCC_RTC_HSE_DIV_40 + * @arg @ref LL_RCC_RTC_HSE_DIV_41 + * @arg @ref LL_RCC_RTC_HSE_DIV_42 + * @arg @ref LL_RCC_RTC_HSE_DIV_43 + * @arg @ref LL_RCC_RTC_HSE_DIV_44 + * @arg @ref LL_RCC_RTC_HSE_DIV_45 + * @arg @ref LL_RCC_RTC_HSE_DIV_46 + * @arg @ref LL_RCC_RTC_HSE_DIV_47 + * @arg @ref LL_RCC_RTC_HSE_DIV_48 + * @arg @ref LL_RCC_RTC_HSE_DIV_49 + * @arg @ref LL_RCC_RTC_HSE_DIV_50 + * @arg @ref LL_RCC_RTC_HSE_DIV_51 + * @arg @ref LL_RCC_RTC_HSE_DIV_52 + * @arg @ref LL_RCC_RTC_HSE_DIV_53 + * @arg @ref LL_RCC_RTC_HSE_DIV_54 + * @arg @ref LL_RCC_RTC_HSE_DIV_55 + * @arg @ref LL_RCC_RTC_HSE_DIV_56 + * @arg @ref LL_RCC_RTC_HSE_DIV_57 + * @arg @ref LL_RCC_RTC_HSE_DIV_58 + * @arg @ref LL_RCC_RTC_HSE_DIV_59 + * @arg @ref LL_RCC_RTC_HSE_DIV_60 + * @arg @ref LL_RCC_RTC_HSE_DIV_61 + * @arg @ref LL_RCC_RTC_HSE_DIV_62 + * @arg @ref LL_RCC_RTC_HSE_DIV_63 + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetRTC_HSEPrescaler(uint32_t Prescaler) +{ + MODIFY_REG(RCC->CFGR1, RCC_CFGR1_RTCPRE, Prescaler); +} + +/** + * @brief Get HSE Prescalers for RTC Clock + * @rmtoll CFGR1 RTCPRE LL_RCC_GetRTC_HSEPrescaler + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_RTC_HSE_NOCLOCK + * @arg @ref LL_RCC_RTC_HSE_DIV_2 + * @arg @ref LL_RCC_RTC_HSE_DIV_3 + * @arg @ref LL_RCC_RTC_HSE_DIV_4 + * @arg @ref LL_RCC_RTC_HSE_DIV_5 + * @arg @ref LL_RCC_RTC_HSE_DIV_6 + * @arg @ref LL_RCC_RTC_HSE_DIV_7 + * @arg @ref LL_RCC_RTC_HSE_DIV_8 + * @arg @ref LL_RCC_RTC_HSE_DIV_9 + * @arg @ref LL_RCC_RTC_HSE_DIV_10 + * @arg @ref LL_RCC_RTC_HSE_DIV_11 + * @arg @ref LL_RCC_RTC_HSE_DIV_12 + * @arg @ref LL_RCC_RTC_HSE_DIV_13 + * @arg @ref LL_RCC_RTC_HSE_DIV_14 + * @arg @ref LL_RCC_RTC_HSE_DIV_15 + * @arg @ref LL_RCC_RTC_HSE_DIV_16 + * @arg @ref LL_RCC_RTC_HSE_DIV_17 + * @arg @ref LL_RCC_RTC_HSE_DIV_18 + * @arg @ref LL_RCC_RTC_HSE_DIV_19 + * @arg @ref LL_RCC_RTC_HSE_DIV_20 + * @arg @ref LL_RCC_RTC_HSE_DIV_21 + * @arg @ref LL_RCC_RTC_HSE_DIV_22 + * @arg @ref LL_RCC_RTC_HSE_DIV_23 + * @arg @ref LL_RCC_RTC_HSE_DIV_24 + * @arg @ref LL_RCC_RTC_HSE_DIV_25 + * @arg @ref LL_RCC_RTC_HSE_DIV_26 + * @arg @ref LL_RCC_RTC_HSE_DIV_27 + * @arg @ref LL_RCC_RTC_HSE_DIV_28 + * @arg @ref LL_RCC_RTC_HSE_DIV_29 + * @arg @ref LL_RCC_RTC_HSE_DIV_30 + * @arg @ref LL_RCC_RTC_HSE_DIV_31 + * @arg @ref LL_RCC_RTC_HSE_DIV_32 + * @arg @ref LL_RCC_RTC_HSE_DIV_33 + * @arg @ref LL_RCC_RTC_HSE_DIV_34 + * @arg @ref LL_RCC_RTC_HSE_DIV_35 + * @arg @ref LL_RCC_RTC_HSE_DIV_36 + * @arg @ref LL_RCC_RTC_HSE_DIV_37 + * @arg @ref LL_RCC_RTC_HSE_DIV_38 + * @arg @ref LL_RCC_RTC_HSE_DIV_39 + * @arg @ref LL_RCC_RTC_HSE_DIV_40 + * @arg @ref LL_RCC_RTC_HSE_DIV_41 + * @arg @ref LL_RCC_RTC_HSE_DIV_42 + * @arg @ref LL_RCC_RTC_HSE_DIV_43 + * @arg @ref LL_RCC_RTC_HSE_DIV_44 + * @arg @ref LL_RCC_RTC_HSE_DIV_45 + * @arg @ref LL_RCC_RTC_HSE_DIV_46 + * @arg @ref LL_RCC_RTC_HSE_DIV_47 + * @arg @ref LL_RCC_RTC_HSE_DIV_48 + * @arg @ref LL_RCC_RTC_HSE_DIV_49 + * @arg @ref LL_RCC_RTC_HSE_DIV_50 + * @arg @ref LL_RCC_RTC_HSE_DIV_51 + * @arg @ref LL_RCC_RTC_HSE_DIV_52 + * @arg @ref LL_RCC_RTC_HSE_DIV_53 + * @arg @ref LL_RCC_RTC_HSE_DIV_54 + * @arg @ref LL_RCC_RTC_HSE_DIV_55 + * @arg @ref LL_RCC_RTC_HSE_DIV_56 + * @arg @ref LL_RCC_RTC_HSE_DIV_57 + * @arg @ref LL_RCC_RTC_HSE_DIV_58 + * @arg @ref LL_RCC_RTC_HSE_DIV_59 + * @arg @ref LL_RCC_RTC_HSE_DIV_60 + * @arg @ref LL_RCC_RTC_HSE_DIV_61 + * @arg @ref LL_RCC_RTC_HSE_DIV_62 + * @arg @ref LL_RCC_RTC_HSE_DIV_63 + */ +__STATIC_INLINE uint32_t LL_RCC_GetRTC_HSEPrescaler(void) +{ + return (uint32_t)(READ_BIT(RCC->CFGR1, RCC_CFGR1_RTCPRE)); +} + + +/** + * @} + */ + +/** @defgroup RCC_LL_EF_TIM_CLOCK_PRESCALER TIM + * @{ + */ + +/** + * @brief Set Timers Clock Prescalers + * @rmtoll CFGR1 TIMPRE LL_RCC_SetTIMPrescaler + * @param Prescaler This parameter can be one of the following values: + * @arg @ref LL_RCC_TIM_PRESCALER_TWICE + * @arg @ref LL_RCC_TIM_PRESCALER_FOUR_TIMES + * @retval None + */ +__STATIC_INLINE void LL_RCC_SetTIMPrescaler(uint32_t Prescaler) +{ + MODIFY_REG(RCC->CFGR1, RCC_CFGR1_TIMPRE, Prescaler); +} + +/** + * @brief Get Timers Clock Prescalers + * @rmtoll CFGR1 TIMPRE LL_RCC_GetTIMPrescaler + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_TIM_PRESCALER_TWICE + * @arg @ref LL_RCC_TIM_PRESCALER_FOUR_TIMES + */ +__STATIC_INLINE uint32_t LL_RCC_GetTIMPrescaler(void) +{ + return (uint32_t)(READ_BIT(RCC->CFGR1, RCC_CFGR1_TIMPRE)); +} + +/** + * @} + */ + +/** @defgroup RCC_LL_EF_PLL1 PLL1 + * @{ + */ + +/** + * @brief Enable PLL1 + * @rmtoll CR PLL1ON LL_RCC_PLL1_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL1_Enable(void) +{ + SET_BIT(RCC->CR, RCC_CR_PLL1ON); +} + +/** + * @brief Disable PLL1 + * @note Cannot be disabled if the PLL1 clock is used as the system clock + * @rmtoll CR PLLON LL_RCC_PLL1_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL1_Disable(void) +{ + CLEAR_BIT(RCC->CR, RCC_CR_PLL1ON); +} + +/** + * @brief Check if PLL1 Ready + * @rmtoll CR PLL1RDY LL_RCC_PLL1_IsReady + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1_IsReady(void) +{ + return ((READ_BIT(RCC->CR, RCC_CR_PLL1RDY) == RCC_CR_PLL1RDY) ? 1UL : 0UL); +} + +/** + * @brief Enable PLL1 P output mapped to SYSCLK + * @note This API shall be called only when PLL1 is disabled. + * @rmtoll PLL1CFGR PLL1PEN LL_RCC_PLL1P_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL1P_Enable(void) +{ + SET_BIT(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1PEN); +} + +/** + * @brief Disable PLL1 P output mapped to SYSCLK + * @note Cannot be disabled if the PLL1 clock is used as the system + * clock + * @rmtoll PLL1CFGR PLL1PEN LL_RCC_PLL1P_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL1P_Disable(void) +{ + CLEAR_BIT(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1PEN); +} + +/** + * @brief Enable PLL1 Q output + * @note This API shall be called only when PLL1 is disabled. + * @rmtoll PLL1CFGR PLL1QEN LL_RCC_PLL1Q_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL1Q_Enable(void) +{ + SET_BIT(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1QEN); +} + +/** + * @brief Disable PLL1 Q output + * @note In order to save power, when the PLL1 Q output of the PLL1 is + * not used, PLL1Q should be 0 + * @rmtoll PLL1CFGR PLL1QEN LL_RCC_PLL1Q_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL1Q_Disable(void) +{ + CLEAR_BIT(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1QEN); +} + +/** + * @brief Enable PLL1 R output + * @note This API shall be called only when PLL1 is disabled. + * @rmtoll PLL1CFGR PLL1REN LL_RCC_PLL1R_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL1R_Enable(void) +{ + SET_BIT(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1REN); +} + +/** + * @brief Disable PLL1 R output + * @note In order to save power, when the PLL1 R output of the PLL1 is + * not used, PLL1R should be 0 + * @rmtoll PLL1CFGR PLL1REN LL_RCC_PLL1R_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL1R_Disable(void) +{ + CLEAR_BIT(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1REN); +} + +/** + * @brief Check if PLL1 P is enabled + * @rmtoll PLLCFGR DIVP1EN LL_RCC_PLL1P_IsEnabled + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1P_IsEnabled(void) +{ + return ((READ_BIT(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1PEN) == RCC_PLL1CFGR_PLL1PEN) ? 1UL : 0UL); +} + +/** + * @brief Check if PLL1 Q is enabled + * @rmtoll PLLCFGR DIVQ1EN LL_RCC_PLL1Q_IsEnabled + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1Q_IsEnabled(void) +{ + return ((READ_BIT(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1QEN) == RCC_PLL1CFGR_PLL1QEN) ? 1UL : 0UL); +} + +/** + * @brief Check if PLL1 R is enabled + * @rmtoll PLLCFGR DIVR1EN LL_RCC_PLL1R_IsEnabled + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1R_IsEnabled(void) +{ + return ((READ_BIT(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1REN) == RCC_PLL1CFGR_PLL1REN) ? 1UL : 0UL); +} + +/** + * @brief Configure PLL1 used for SYSCLK + * @note PLL1 Source, PLL1M, PLL1N and PLL1P can be written only when PLL1 is disabled. + * @rmtoll PLL1CFGR PLL1SRC LL_RCC_PLL1_ConfigDomain_SYS\n + * PLL1CFGR PLL1M LL_RCC_PLL1_ConfigDomain_SYS\n + * PLL1CFGR PLL1N LL_RCC_PLL1_ConfigDomain_SYS\n + * PLL1CFGR PLL1R LL_RCC_PLL1_ConfigDomain_SYS + * @param Source This parameter can be one of the following values: + * @arg @ref LL_RCC_PLL1SOURCE_NONE + * @arg @ref LL_RCC_PLL1SOURCE_HSI + * @arg @ref LL_RCC_PLL1SOURCE_CSI + * @arg @ref LL_RCC_PLL1SOURCE_HSE + * @param PLL1M parameter can be a value between 1 and 63 + * @param PLL1P parameter can be a value between 1 and 128 (odd values not allowed) + * @param PLL1N parameter can be a value between 4 and 512 + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL1_ConfigDomain_SYS(uint32_t Source, uint32_t PLL1M, uint32_t PLL1N, uint32_t PLL1P) +{ + MODIFY_REG(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1SRC | RCC_PLL1CFGR_PLL1M, Source | (PLL1M << RCC_PLL1CFGR_PLL1M_Pos)); + MODIFY_REG(RCC->PLL1DIVR, RCC_PLL1DIVR_PLL1N | RCC_PLL1DIVR_PLL1P, \ + ((PLL1N - 1UL) << RCC_PLL1DIVR_PLL1N_Pos) | ((PLL1P - 1UL) << RCC_PLL1DIVR_PLL1P_Pos)); +} + +/** + * @brief Configure PLL clock source + * @rmtoll PLL1CFGR PLL1SRC LL_RCC_PLL1_SetSource + * @param PLL1Source This parameter can be one of the following values: + * @arg @ref LL_RCC_PLL1SOURCE_NONE + * @arg @ref LL_RCC_PLL1SOURCE_HSI + * @arg @ref LL_RCC_PLL1SOURCE_CSI + * @arg @ref LL_RCC_PLL1SOURCE_HSE + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL1_SetSource(uint32_t PLL1Source) +{ + MODIFY_REG(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1SRC, PLL1Source); +} + +/** + * @brief Get the oscillator used as PLL1 clock source. + * @rmtoll PLL1CFGR PLL1SRC LL_RCC_PLL1_GetSource + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_PLL1SOURCE_NONE + * @arg @ref LL_RCC_PLL1SOURCE_CSI + * @arg @ref LL_RCC_PLL1SOURCE_HSI + * @arg @ref LL_RCC_PLL1SOURCE_HSE + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1_GetSource(void) +{ + return (uint32_t)(READ_BIT(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1SRC)); +} + +/** + * @brief Set Main PLL1 multiplication factor for VCO + * @rmtoll PLL1CFGR PLL1N LL_RCC_PLL1_SetN + * @param PLL1N parameter can be a value between 4 and 512 + */ +__STATIC_INLINE void LL_RCC_PLL1_SetN(uint32_t PLL1N) +{ + MODIFY_REG(RCC->PLL1DIVR, RCC_PLL1DIVR_PLL1N, (PLL1N - 1UL) << RCC_PLL1DIVR_PLL1N_Pos); +} + +/** + * @brief Get Main PLL1 multiplication factor for VCO + * @rmtoll PLL1CFGR PLL1N LL_RCC_PLL1_GetN + * @retval Between 4 and 512 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1_GetN(void) +{ + return (uint32_t)((READ_BIT(RCC->PLL1DIVR, RCC_PLL1DIVR_PLL1N) >> RCC_PLL1DIVR_PLL1N_Pos) + 1UL); +} + +/** + * @brief Set Main PLL1 division factor for PLL1P + * @note Used for System clock + * @rmtoll PLL1CFGR PLL1P LL_RCC_PLL1_SetP + * @param PLL1P parameter can be a value between 2 and 128 (odd value not allowed) + */ +__STATIC_INLINE void LL_RCC_PLL1_SetP(uint32_t PLL1P) +{ + MODIFY_REG(RCC->PLL1DIVR, RCC_PLL1DIVR_PLL1P, (PLL1P - 1UL) << RCC_PLL1DIVR_PLL1P_Pos); +} + +/** + * @brief Get PLL1 division factor for PLL1P + * @note Used for System clock + * @rmtoll PLL1CFGR PLL1P LL_RCC_PLL1_GetP + * @retval Between 2 and 128 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1_GetP(void) +{ + return (uint32_t)((READ_BIT(RCC->PLL1DIVR, RCC_PLL1DIVR_PLL1P) >> RCC_PLL1DIVR_PLL1P_Pos) + 1UL); +} + + +/** + * @brief Set PLL1 division factor for PLL1Q + * @note Used for peripherals clocks + * @rmtoll PLLCFGR PLL1Q LL_RCC_PLL1_SetQ + * @param PLL1Q parameter can be a value between 1 and 128 + */ +__STATIC_INLINE void LL_RCC_PLL1_SetQ(uint32_t PLL1Q) +{ + MODIFY_REG(RCC->PLL1DIVR, RCC_PLL1DIVR_PLL1Q, (PLL1Q - 1UL) << RCC_PLL1DIVR_PLL1Q_Pos); +} + +/** + * @brief Get PLL1 division factor for PLL1Q + * @note Used for peripherals clocks + * @rmtoll PLL1CFGR PLL1Q LL_RCC_PLL1_GetQ + * @retval Between 1 and 128 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1_GetQ(void) +{ + return (uint32_t)((READ_BIT(RCC->PLL1DIVR, RCC_PLL1DIVR_PLL1Q) >> RCC_PLL1DIVR_PLL1Q_Pos) + 1UL); +} + +/** + * @brief Set PLL1 division factor for PLL1R + * @note Used for trace + * @rmtoll PLL1DIVR PLL1R LL_RCC_PLL1_SetR + * @param PLL1R parameter can be a value between 1 and 128 + */ +__STATIC_INLINE void LL_RCC_PLL1_SetR(uint32_t PLL1R) +{ + MODIFY_REG(RCC->PLL1DIVR, RCC_PLL1DIVR_PLL1R, (PLL1R - 1UL) << RCC_PLL1DIVR_PLL1R_Pos); +} + +/** + * @brief Get Main PLL1 division factor for PLL1R + * @note Used for trace + * @rmtoll PLL1DIVR PLL1R LL_RCC_PLL1_GetR + * @retval Between 1 and 128 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1_GetR(void) +{ + return (uint32_t)((READ_BIT(RCC->PLL1DIVR, RCC_PLL1DIVR_PLL1R) >> RCC_PLL1DIVR_PLL1R_Pos) + 1UL); +} + +/** + * @brief Set Division factor for the main PLL and other PLL + * @rmtoll PLL1CFGR PLL1M LL_RCC_PLL1_SetM + * @param PLL1M parameter can be a value between 1 and 63 + */ +__STATIC_INLINE void LL_RCC_PLL1_SetM(uint32_t PLL1M) +{ + MODIFY_REG(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1M, PLL1M << RCC_PLL1CFGR_PLL1M_Pos); +} + +/** + * @brief Get Division factor for the main PLL and other PLL + * @rmtoll PLL1CFGR PLL1M LL_RCC_PLL1_GetM + * @retval Between 0 and 63 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1_GetM(void) +{ + return (uint32_t)(READ_BIT(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1M) >> RCC_PLL1CFGR_PLL1M_Pos); +} + +/** + * @brief Enable PLL1 FRACN + * @rmtoll PLL1CFGR PLL1FRACEN LL_RCC_PLL1FRACN_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL1FRACN_Enable(void) +{ + SET_BIT(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1FRACEN); +} + +/** + * @brief Check if PLL1 FRACN is enabled + * @rmtoll PLL1CFGR PLL1FRACEN LL_RCC_PLL1FRACN_IsEnabled + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1FRACN_IsEnabled(void) +{ + return ((READ_BIT(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1FRACEN) == RCC_PLL1CFGR_PLL1FRACEN) ? 1UL : 0UL); +} + +/** + * @brief Disable PLL1 FRACN + * @rmtoll PLL1CFGR PLL1FRACEN LL_RCC_PLL1FRACN_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL1FRACN_Disable(void) +{ + CLEAR_BIT(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1FRACEN); +} + +/** + * @brief Set PLL1 FRACN Coefficient + * @rmtoll PLL1FRACR PLL1FRACN LL_RCC_PLL1_SetFRACN + * @param FRACN parameter can be a value between 0 and 8191 (0x1FFF) + */ +__STATIC_INLINE void LL_RCC_PLL1_SetFRACN(uint32_t FRACN) +{ + MODIFY_REG(RCC->PLL1FRACR, RCC_PLL1FRACR_PLL1FRACN, FRACN << RCC_PLL1FRACR_PLL1FRACN_Pos); +} + +/** + * @brief Get PLL1 FRACN Coefficient + * @rmtoll PLL1FRACR PLL1FRACN LL_RCC_PLL1_GetFRACN + * @retval A value between 0 and 8191 (0x1FFF) + */ +__STATIC_INLINE uint32_t LL_RCC_PLL1_GetFRACN(void) +{ + return (uint32_t)(READ_BIT(RCC->PLL1FRACR, RCC_PLL1FRACR_PLL1FRACN) >> RCC_PLL1FRACR_PLL1FRACN_Pos); +} + +/** + * @brief Set PLL1 VCO Input Range + * @note This API shall be called only when PLL1 is disabled. + * @rmtoll PLL1CFGR PLL1RGE LL_RCC_PLL1_SetVCOInputRange + * @param InputRange This parameter can be one of the following values: + * @arg @ref LL_RCC_PLLINPUTRANGE_1_2 + * @arg @ref LL_RCC_PLLINPUTRANGE_2_4 + * @arg @ref LL_RCC_PLLINPUTRANGE_4_8 + * @arg @ref LL_RCC_PLLINPUTRANGE_8_16 + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL1_SetVCOInputRange(uint32_t InputRange) +{ + MODIFY_REG(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1RGE, InputRange << RCC_PLL1CFGR_PLL1RGE_Pos); +} + +/** + * @brief Set PLL1 VCO OutputRange + * @note This API shall be called only when PLL1 is disabled. + * @rmtoll PLLCFGR PLL1VCOSEL LL_RCC_PLL1_SetVCOOutputRange + * @param VCORange This parameter can be one of the following values: + * @arg @ref LL_RCC_PLLVCORANGE_WIDE + * @arg @ref LL_RCC_PLLVCORANGE_MEDIUM + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL1_SetVCOOutputRange(uint32_t VCORange) +{ + MODIFY_REG(RCC->PLL1CFGR, RCC_PLL1CFGR_PLL1VCOSEL, VCORange << RCC_PLL1CFGR_PLL1VCOSEL_Pos); +} + +/** + * @} + */ + +/** @defgroup RCC_LL_EF_PLL2 PLL2 + * @{ + */ + +/** + * @brief Enable PLL2 + * @rmtoll CR PLL2ON LL_RCC_PLL2_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL2_Enable(void) +{ + SET_BIT(RCC->CR, RCC_CR_PLL2ON); +} + +/** + * @brief Disable PLL2 + * @rmtoll CR PLL2ON LL_RCC_PLL2_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL2_Disable(void) +{ + CLEAR_BIT(RCC->CR, RCC_CR_PLL2ON); +} + +/** + * @brief Check if PLL2 Ready + * @rmtoll CR PLL2RDY LL_RCC_PLL2_IsReady + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2_IsReady(void) +{ + return ((READ_BIT(RCC->CR, RCC_CR_PLL2RDY) == RCC_CR_PLL2RDY) ? 1UL : 0UL); +} + +/** + * @brief Configure PLL2 clock source + * @rmtoll PLL2CFGR PLL2SRC LL_RCC_PLL2_SetSource + * @param PLL2Source This parameter can be one of the following values: + * @arg @ref LL_RCC_PLL2SOURCE_NONE + * @arg @ref LL_RCC_PLL2SOURCE_CSI + * @arg @ref LL_RCC_PLL2SOURCE_HSI + * @arg @ref LL_RCC_PLL2SOURCE_HSE + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL2_SetSource(uint32_t PLL2Source) +{ + MODIFY_REG(RCC->PLL2CFGR, RCC_PLL2CFGR_PLL2SRC, PLL2Source); +} + +/** + * @brief Get the oscillator used as PLL2 clock source. + * @rmtoll PLL2CFGR PLL2SRC LL_RCC_PLL2_GetSource + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_PLL2SOURCE_NONE + * @arg @ref LL_RCC_PLL2SOURCE_CSI + * @arg @ref LL_RCC_PLL2SOURCE_HSI + * @arg @ref LL_RCC_PLL2SOURCE_HSE + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2_GetSource(void) +{ + return (uint32_t)(READ_BIT(RCC->PLL2CFGR, RCC_PLL2CFGR_PLL2SRC)); +} + +/** + * @brief Set PLL2 Division factor M + * @note This API shall be called only when PLL2 is disabled. + * @rmtoll PLL2CFGR PLL2M LL_RCC_PLL2_SetM + * @param PLL2M parameter can be a value between 1 and 63 + */ +__STATIC_INLINE void LL_RCC_PLL2_SetM(uint32_t PLL2M) +{ + MODIFY_REG(RCC->PLL2CFGR, RCC_PLL2CFGR_PLL2M, PLL2M << RCC_PLL2CFGR_PLL2M_Pos); +} + +/** + * @brief Get PLL2 division factor M + * @rmtoll PLL2CFGR PLL2M LL_RCC_PLL2_GetM + * @retval Between 1 and 63 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2_GetM(void) +{ + return (uint32_t)(READ_BIT(RCC->PLL2CFGR, RCC_PLL2CFGR_PLL2M) >> RCC_PLL2CFGR_PLL2M_Pos); +} + +/** + * @brief Set PLL2 multiplication factor N + * @rmtoll PLL2CFGR PLL2N LL_RCC_PLL2_SetN + * @param PLL2N parameter can be a value between 4 and 512 + */ +__STATIC_INLINE void LL_RCC_PLL2_SetN(uint32_t PLL2N) +{ + MODIFY_REG(RCC->PLL2DIVR, RCC_PLL2DIVR_PLL2N, (PLL2N - 1UL) << RCC_PLL2DIVR_PLL2N_Pos); +} + +/** + * @brief Get PLL2 multiplication factor N + * @rmtoll PLL2CFGR PLL2N LL_RCC_PLL2_GetN + * @retval Between 4 and 512 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2_GetN(void) +{ + return (uint32_t)((READ_BIT(RCC->PLL2DIVR, RCC_PLL2DIVR_PLL2N) >> RCC_PLL2DIVR_PLL2N_Pos) + 1UL); +} + +/** + * @brief Set PLL2 division factor P + * @note Used for peripherals clocks + * @rmtoll PLL2CFGR PLL2P LL_RCC_PLL2_SetP + * @param PLL2P parameter can be a value between 1 and 128 + */ +__STATIC_INLINE void LL_RCC_PLL2_SetP(uint32_t PLL2P) +{ + MODIFY_REG(RCC->PLL2DIVR, RCC_PLL2DIVR_PLL2P, (PLL2P - 1UL) << RCC_PLL2DIVR_PLL2P_Pos); +} + +/** + * @brief Get PLL2 division factor P + * @note Used for peripherals clocks + * @rmtoll PLL2CFGR PLL2P LL_RCC_PLL2_GetP + * @retval Between 1 and 128 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2_GetP(void) +{ + return (uint32_t)((READ_BIT(RCC->PLL2DIVR, RCC_PLL2DIVR_PLL2P) >> RCC_PLL2DIVR_PLL2P_Pos) + 1UL); +} + + +/** + * @brief Set PLL2 division factor Q + * @note Used for peripherals clocks + * @rmtoll PLLCFGR PLL2Q LL_RCC_PLL2_SetQ + * @param PLL2Q parameter can be a value between 1 and 128 + */ +__STATIC_INLINE void LL_RCC_PLL2_SetQ(uint32_t PLL2Q) +{ + MODIFY_REG(RCC->PLL2DIVR, RCC_PLL2DIVR_PLL2Q, (PLL2Q - 1UL) << RCC_PLL2DIVR_PLL2Q_Pos); +} + +/** + * @brief Get PLL2 division factor Q + * @note Used for peripherals clocks + * @rmtoll PLL2CFGR PLL2Q LL_RCC_PLL2_GetQ + * @retval Between 1 and 128 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2_GetQ(void) +{ + return (uint32_t)((READ_BIT(RCC->PLL2DIVR, RCC_PLL2DIVR_PLL2Q) >> RCC_PLL2DIVR_PLL2Q_Pos) + 1UL); +} + +/** + * @brief Set PLL2 division factor R + * @note Used for PLL2CLK selected for peripherals clocks + * @rmtoll PLL2CFGR PLL2Q LL_RCC_PLL2_SetR + * @param PLL2R parameter can be a value between 1 and 128 + */ +__STATIC_INLINE void LL_RCC_PLL2_SetR(uint32_t PLL2R) +{ + MODIFY_REG(RCC->PLL2DIVR, RCC_PLL2DIVR_PLL2R, (PLL2R - 1UL) << RCC_PLL2DIVR_PLL2R_Pos); +} + +/** + * @brief Get PLL2 division factor R + * @note Used for PLL2CLK (system clock) + * @rmtoll PLL2DIVR PLL2R LL_RCC_PLL2_GetR + * @retval Between 1 and 128 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2_GetR(void) +{ + return (uint32_t)((READ_BIT(RCC->PLL2DIVR, RCC_PLL2DIVR_PLL2R) >> RCC_PLL2DIVR_PLL2R_Pos) + 1UL); +} + +/** + * @brief Enable PLL2 P output + * @rmtoll PLL2CFGR PLL2PEN LL_RCC_PLL2P_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL2P_Enable(void) +{ + SET_BIT(RCC->PLL2CFGR, RCC_PLL2CFGR_PLL2PEN); +} + +/** + * @brief Disable PLL2 P output + * @note In order to save power, when PLL2P output is + * not used, it should be disabled (at any time) + * @rmtoll PLL2CFGR PLL2PEN LL_RCC_PLL2P_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL2P_Disable(void) +{ + CLEAR_BIT(RCC->PLL2CFGR, RCC_PLL2CFGR_PLL2PEN); +} + +/** + * @brief Enable PLL2 Q output + * @rmtoll PLL2CFGR PLL2QEN LL_RCC_PLL2Q_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL2Q_Enable(void) +{ + SET_BIT(RCC->PLL2CFGR, RCC_PLL2CFGR_PLL2QEN); +} + +/** + * @brief Disable PLL2 Q output + * @note In order to save power, when PLL2Q output is + * not used, it should be disabled (at any time) + * @rmtoll PLL2CFGR PLL2QEN LL_RCC_PLL2_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL2Q_Disable(void) +{ + CLEAR_BIT(RCC->PLL2CFGR, RCC_PLL2CFGR_PLL2QEN); +} + +/** + * @brief Enable PLL2 R output + * @rmtoll PLL2CFGR PLL2REN LL_RCC_PLL2R_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL2R_Enable(void) +{ + SET_BIT(RCC->PLL2CFGR, RCC_PLL2CFGR_PLL2REN); +} + +/** + * @brief Disable PLL2 R output + * @note In order to save power, when PLL2R output is + * not used, it should be disabled (at any time) + * @rmtoll PLL2CFGR PLL2REN LL_RCC_PLL2R_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL2R_Disable(void) +{ + CLEAR_BIT(RCC->PLL2CFGR, RCC_PLL2CFGR_PLL2REN); +} + +/** + * @brief Check if PLL2 P is enabled + * @rmtoll PLL2CFGR PLL2PEN LL_RCC_PLL2P_IsEnabled + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2P_IsEnabled(void) +{ + return ((READ_BIT(RCC->PLL2CFGR, RCC_PLL2CFGR_PLL2PEN) == RCC_PLL2CFGR_PLL2PEN) ? 1UL : 0UL); +} + +/** + * @brief Check if PLL2 Q is enabled + * @rmtoll PLL2CFGR PLL2QEN LL_RCC_PLL2Q_IsEnabled + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2Q_IsEnabled(void) +{ + return ((READ_BIT(RCC->PLL2CFGR, RCC_PLL2CFGR_PLL2QEN) == RCC_PLL2CFGR_PLL2QEN) ? 1UL : 0UL); +} + +/** + * @brief Check if PLL2 R is enabled + * @rmtoll PLL2CFGR PLL2REN LL_RCC_PLL2R_IsEnabled + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2R_IsEnabled(void) +{ + return ((READ_BIT(RCC->PLL2CFGR, RCC_PLL2CFGR_PLL2REN) == RCC_PLL2CFGR_PLL2REN) ? 1UL : 0UL); +} + +/** + * @brief Enable PLL2 FRACN + * @rmtoll PLL2CFGR PLL2FRACEN LL_RCC_PLL2FRACN_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL2FRACN_Enable(void) +{ + SET_BIT(RCC->PLL2CFGR, RCC_PLL2CFGR_PLL2FRACEN); +} + +/** + * @brief Check if PLL2 FRACN is enabled + * @rmtoll PLL2CFGR PLL2FRACEN LL_RCC_PLL2FRACN_IsEnabled + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2FRACN_IsEnabled(void) +{ + return ((READ_BIT(RCC->PLL2CFGR, RCC_PLL2CFGR_PLL2FRACEN) == RCC_PLL2CFGR_PLL2FRACEN) ? 1UL : 0UL); +} + +/** + * @brief Disable PLL2 FRACN + * @rmtoll PLL2CFGR PLL2FRACEN LL_RCC_PLL2FRACN_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL2FRACN_Disable(void) +{ + CLEAR_BIT(RCC->PLL2CFGR, RCC_PLL2CFGR_PLL2FRACEN); +} + +/** + * @brief Set PLL2 FRACN Coefficient + * @rmtoll PLL2FRACR PLL2FRACN LL_RCC_PLL2_SetFRACN + * @param FRACN parameter can be a value between 0 and 8191 (0x1FFF) + */ +__STATIC_INLINE void LL_RCC_PLL2_SetFRACN(uint32_t FRACN) +{ + MODIFY_REG(RCC->PLL2FRACR, RCC_PLL2FRACR_PLL2FRACN, FRACN << RCC_PLL2FRACR_PLL2FRACN_Pos); +} + +/** + * @brief Get PLL2 FRACN Coefficient + * @rmtoll PLL2FRACR PLL2FRACN LL_RCC_PLL2_GetFRACN + * @retval A value between 0 and 8191 (0x1FFF) + */ +__STATIC_INLINE uint32_t LL_RCC_PLL2_GetFRACN(void) +{ + return (uint32_t)(READ_BIT(RCC->PLL2FRACR, RCC_PLL2FRACR_PLL2FRACN) >> RCC_PLL2FRACR_PLL2FRACN_Pos); +} + +/** + * @brief Set PLL2 VCO Input Range + * @note This API shall be called only when PLL2 is disabled. + * @rmtoll PLL2CFGR PLL2RGE LL_RCC_PLL2_SetVCOInputRange + * @param InputRange This parameter can be one of the following values: + * @arg @ref LL_RCC_PLLINPUTRANGE_1_2 + * @arg @ref LL_RCC_PLLINPUTRANGE_2_4 + * @arg @ref LL_RCC_PLLINPUTRANGE_4_8 + * @arg @ref LL_RCC_PLLINPUTRANGE_8_16 + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL2_SetVCOInputRange(uint32_t InputRange) +{ + MODIFY_REG(RCC->PLL2CFGR, RCC_PLL2CFGR_PLL2RGE, InputRange << RCC_PLL2CFGR_PLL2RGE_Pos); +} + +/** + * @brief Set PLL2 VCO OutputRange + * @note This API shall be called only when PLL2 is disabled. + * @rmtoll PLL2CFGR PLL2VCOSEL LL_RCC_PLL2_SetVCOOutputRange + * @param VCORange This parameter can be one of the following values: + * @arg @ref LL_RCC_PLLVCORANGE_WIDE + * @arg @ref LL_RCC_PLLVCORANGE_MEDIUM + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL2_SetVCOOutputRange(uint32_t VCORange) +{ + MODIFY_REG(RCC->PLL2CFGR, RCC_PLL2CFGR_PLL2VCOSEL, VCORange << RCC_PLL2CFGR_PLL2VCOSEL_Pos); +} + +/** + * @} + */ + +#if defined(RCC_CR_PLL3ON) +/** @defgroup RCC_LL_EF_PLL3 PLL3 + * @{ + */ + +/** + * @brief Enable PLL3 + * @rmtoll CR PLL3ON LL_RCC_PLL3_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL3_Enable(void) +{ + SET_BIT(RCC->CR, RCC_CR_PLL3ON); +} + +/** + * @brief Disable PLL3 + * @rmtoll CR PLL3ON LL_RCC_PLL3_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL3_Disable(void) +{ + CLEAR_BIT(RCC->CR, RCC_CR_PLL3ON); +} + +/** + * @brief Check if PLL3 is Ready + * @rmtoll CR PLL3RDY LL_RCC_PLL3_IsReady + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL3_IsReady(void) +{ + return ((READ_BIT(RCC->CR, RCC_CR_PLL3RDY) == RCC_CR_PLL3RDY) ? 1UL : 0UL); +} + + +/** + * @brief Configure PLL3 clock source + * @rmtoll PLL3CFGR PLL3SRC LL_RCC_PLL3_SetSource + * @param PLLSource This parameter can be one of the following values: + * @arg @ref LL_RCC_PLL3SOURCE_NONE + * @arg @ref LL_RCC_PLL3SOURCE_CSI + * @arg @ref LL_RCC_PLL3SOURCE_HSI + * @arg @ref LL_RCC_PLL3SOURCE_HSE + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL3_SetSource(uint32_t PLLSource) +{ + MODIFY_REG(RCC->PLL3CFGR, RCC_PLL3CFGR_PLL3SRC, PLLSource); +} + +/** + * @brief Get the oscillator used as PLL3 clock source. + * @rmtoll PLL3CFGR PLL3SRC LL_RCC_PLL3_GetSource + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_PLL3SOURCE_NONE + * @arg @ref LL_RCC_PLL3SOURCE_CSI + * @arg @ref LL_RCC_PLL3SOURCE_HSI + * @arg @ref LL_RCC_PLL3SOURCE_HSE + */ +__STATIC_INLINE uint32_t LL_RCC_PLL3_GetSource(void) +{ + return (uint32_t)(READ_BIT(RCC->PLL3CFGR, RCC_PLL3CFGR_PLL3SRC)); +} + +/** + * @brief Set PLL3 multiplication factor N + * @rmtoll PLL3CFGR PLL3N LL_RCC_PLL3_SetN + * @param PLL3N parameter can be a value between 4 and 512 + */ +__STATIC_INLINE void LL_RCC_PLL3_SetN(uint32_t PLL3N) +{ + MODIFY_REG(RCC->PLL3DIVR, RCC_PLL3DIVR_PLL3N, (PLL3N - 1UL) << RCC_PLL3DIVR_PLL3N_Pos); +} + +/** + * @brief Get PLL3 multiplication factor N + * @rmtoll PLL3CFGR PLL3N LL_RCC_PLL3_GetN + * @retval Between 4 and 512 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL3_GetN(void) +{ + return (uint32_t)((READ_BIT(RCC->PLL3DIVR, RCC_PLL3DIVR_PLL3N) >> RCC_PLL3DIVR_PLL3N_Pos) + 1UL); +} + +/** + * @brief Set PLL3 division factor P + * @note Used for peripherals clocks + * @rmtoll PLL3CFGR PLL3P LL_RCC_PLL3_SetP + * @param PLL3P parameter can be a value between 1 and 128 + */ +__STATIC_INLINE void LL_RCC_PLL3_SetP(uint32_t PLL3P) +{ + MODIFY_REG(RCC->PLL3DIVR, RCC_PLL3DIVR_PLL3P, (PLL3P - 1UL) << RCC_PLL3DIVR_PLL3P_Pos); +} + +/** + * @brief Get PLL3 division factor P + * @note Used for peripherals clocks + * @rmtoll PLL3CFGR PLL3P LL_RCC_PLL3_GetP + * @retval Between 1 and 128 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL3_GetP(void) +{ + return (uint32_t)((READ_BIT(RCC->PLL3DIVR, RCC_PLL3DIVR_PLL3P) >> RCC_PLL3DIVR_PLL3P_Pos) + 1UL); +} + +/** + * @brief Set PLL3 division factor Q + * @note Used for peripherals clocks + * @rmtoll PLLCFGR PLL3Q LL_RCC_PLL3_SetQ + * @param PLL3Q parameter can be a value between 1 and 128 + */ +__STATIC_INLINE void LL_RCC_PLL3_SetQ(uint32_t PLL3Q) +{ + MODIFY_REG(RCC->PLL3DIVR, RCC_PLL3DIVR_PLL3Q, (PLL3Q - 1UL) << RCC_PLL3DIVR_PLL3Q_Pos); +} + +/** + * @brief Get PLL3 division factor Q + * @note Used for peripherals clocks + * @rmtoll PLL3CFGR PLL3Q LL_RCC_PLL3_GetQ + * @retval Between 1 and 128 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL3_GetQ(void) +{ + return (uint32_t)((READ_BIT(RCC->PLL3DIVR, RCC_PLL3DIVR_PLL3Q) >> RCC_PLL3DIVR_PLL3Q_Pos) + 1UL); +} + +/** + * @brief Set PLL3 division factor R + * @note Used for peripherals clocks + * @rmtoll PLL3CFGR PLL3Q LL_RCC_PLL3_SetR + * @param PLL3R parameter can be a value between 1 and 128 + */ +__STATIC_INLINE void LL_RCC_PLL3_SetR(uint32_t PLL3R) +{ + MODIFY_REG(RCC->PLL3DIVR, RCC_PLL3DIVR_PLL3R, (PLL3R - 1UL) << RCC_PLL3DIVR_PLL3R_Pos); +} + +/** + * @brief Get PLL3 division factor R + * @note Used for PLL3CLK (system clock) + * @rmtoll PLL3DIVR PLL3R LL_RCC_PLL3_GetR + * @retval Between 1 and 128 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL3_GetR(void) +{ + return (uint32_t)((READ_BIT(RCC->PLL3DIVR, RCC_PLL3DIVR_PLL3R) >> RCC_PLL3DIVR_PLL3R_Pos) + 1UL); +} + +/** + * @brief Set PLL3 Division factor M + * @rmtoll PLL3CFGR PLL3M LL_RCC_PLL3_SetM + * @param PLL3M parameter can be a value between 1 and 63 + */ +__STATIC_INLINE void LL_RCC_PLL3_SetM(uint32_t PLL3M) +{ + MODIFY_REG(RCC->PLL3CFGR, RCC_PLL3CFGR_PLL3M, PLL3M << RCC_PLL3CFGR_PLL3M_Pos); +} + +/** + * @brief Get PLL3 Division factor M + * @rmtoll PLL3CFGR PLL3M LL_RCC_PLL3_GetM + * @retval Between 1 and 63 + */ +__STATIC_INLINE uint32_t LL_RCC_PLL3_GetM(void) +{ + return (uint32_t)(READ_BIT(RCC->PLL3CFGR, RCC_PLL3CFGR_PLL3M) >> RCC_PLL3CFGR_PLL3M_Pos); +} + +/** + * @brief Enable PLL3 P output + * @rmtoll PLL3CFGR PLL3PEN LL_RCC_PLL3P_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL3P_Enable(void) +{ + SET_BIT(RCC->PLL3CFGR, RCC_PLL3CFGR_PLL3PEN); +} + +/** + * @brief Disable PLL3 P output + * @note In order to save power, when PLL3P output is + * not used, it should be disabled (at any time) + * @rmtoll PLL3CFGR PLL3PEN LL_RCC_PLL3P_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL3P_Disable(void) +{ + CLEAR_BIT(RCC->PLL3CFGR, RCC_PLL3CFGR_PLL3PEN); +} + +/** + * @brief Enable PLL3 Q output + * @rmtoll PLL3CFGR PLL3QEN LL_RCC_PLL3Q_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL3Q_Enable(void) +{ + SET_BIT(RCC->PLL3CFGR, RCC_PLL3CFGR_PLL3QEN); +} + +/** + * @brief Disable PLL3 Q output + * @note In order to save power, when PLL3Q output is + * not used, it should be disabled (at any time) + * @rmtoll PLL3CFGR PLL3QEN LL_RCC_PLL3Q_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL3Q_Disable(void) +{ + CLEAR_BIT(RCC->PLL3CFGR, RCC_PLL3CFGR_PLL3QEN); +} + +/** + * @brief Enable PLL3 R output + * @rmtoll PLL3CFGR PLL3REN LL_RCC_PLL3R_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL3R_Enable(void) +{ + SET_BIT(RCC->PLL3CFGR, RCC_PLL3CFGR_PLL3REN); +} + +/** + * @brief Disable PLL3 R output + * @note In order to save power, when PLL3R output is + * not used, it should be disabled (at any time) + * @rmtoll PLL3CFGR PLL3REN LL_RCC_PLL3R_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL3R_Disable(void) +{ + CLEAR_BIT(RCC->PLL3CFGR, RCC_PLL3CFGR_PLL3REN); +} + +/** + * @brief Check if PLL3 P is enabled + * @rmtoll PLL3CFGR PLL3PEN LL_RCC_PLL3P_IsEnabled + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL3P_IsEnabled(void) +{ + return ((READ_BIT(RCC->PLL3CFGR, RCC_PLL3CFGR_PLL3PEN) == RCC_PLL3CFGR_PLL3PEN) ? 1UL : 0UL); +} + +/** + * @brief Check if PLL3 Q is enabled + * @rmtoll PLL3CFGR PLL3QEN LL_RCC_PLL3Q_IsEnabled + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL3Q_IsEnabled(void) +{ + return ((READ_BIT(RCC->PLL3CFGR, RCC_PLL3CFGR_PLL3QEN) == RCC_PLL3CFGR_PLL3QEN) ? 1UL : 0UL); +} + +/** + * @brief Check if PLL3 R is enabled + * @rmtoll PLL3CFGR PLL3REN LL_RCC_PLL3R_IsEnabled + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL3R_IsEnabled(void) +{ + return ((READ_BIT(RCC->PLL3CFGR, RCC_PLL3CFGR_PLL3REN) == RCC_PLL3CFGR_PLL3REN) ? 1UL : 0UL); +} + +/** + * @brief Enable PLL3 FRACN + * @rmtoll PLL3CFGR PLL3FRACEN LL_RCC_PLL3FRACN_Enable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL3FRACN_Enable(void) +{ + SET_BIT(RCC->PLL3CFGR, RCC_PLL3CFGR_PLL3FRACEN); +} + +/** + * @brief Check if PLL3 FRACN is enabled + * @rmtoll PLL3CFGR PLL3FRACEN LL_RCC_PLL3FRACN_IsEnabled + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_PLL3FRACN_IsEnabled(void) +{ + return ((READ_BIT(RCC->PLL3CFGR, RCC_PLL3CFGR_PLL3FRACEN) == RCC_PLL3CFGR_PLL3FRACEN) ? 1UL : 0UL); +} + +/** + * @brief Disable PLL3 FRACN + * @rmtoll PLL3CFGR PLL3FRACEN LL_RCC_PLL3FRACN_Disable + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL3FRACN_Disable(void) +{ + CLEAR_BIT(RCC->PLL3CFGR, RCC_PLL3CFGR_PLL3FRACEN); +} + +/** + * @brief Set PLL3 FRACN Coefficient + * @rmtoll PLL3FRACR PLL3FRACN LL_RCC_PLL3_SetFRACN + * @param FRACN parameter can be a value between 0 and 8191 (0x1FFF) + */ +__STATIC_INLINE void LL_RCC_PLL3_SetFRACN(uint32_t FRACN) +{ + MODIFY_REG(RCC->PLL3FRACR, RCC_PLL3FRACR_PLL3FRACN, FRACN << RCC_PLL3FRACR_PLL3FRACN_Pos); +} + +/** + * @brief Get PLL3 FRACN Coefficient + * @rmtoll PLL3FRACR PLL3FRACN LL_RCC_PLL3_GetFRACN + * @retval A value between 0 and 8191 (0x1FFF) + */ +__STATIC_INLINE uint32_t LL_RCC_PLL3_GetFRACN(void) +{ + return (uint32_t)(READ_BIT(RCC->PLL3FRACR, RCC_PLL3FRACR_PLL3FRACN) >> RCC_PLL3FRACR_PLL3FRACN_Pos); +} + +/** + * @brief Set PLL3 VCO Input Range + * @note This API shall be called only when PLL3 is disabled. + * @rmtoll PLL3CFGR PLL3RGE LL_RCC_PLL3_SetVCOInputRange + * @param InputRange This parameter can be one of the following values: + * @arg @ref LL_RCC_PLLINPUTRANGE_1_2 + * @arg @ref LL_RCC_PLLINPUTRANGE_2_4 + * @arg @ref LL_RCC_PLLINPUTRANGE_4_8 + * @arg @ref LL_RCC_PLLINPUTRANGE_8_16 + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL3_SetVCOInputRange(uint32_t InputRange) +{ + MODIFY_REG(RCC->PLL3CFGR, RCC_PLL3CFGR_PLL3RGE, InputRange << RCC_PLL3CFGR_PLL3RGE_Pos); +} + +/** + * @brief Set PLL3 VCO OutputRange + * @note This API shall be called only when PLL3 is disabled. + * @rmtoll PLL3CFGR PLL3VCOSEL LL_RCC_PLL3_SetVCOOutputRange + * @param VCORange This parameter can be one of the following values: + * @arg @ref LL_RCC_PLLVCORANGE_WIDE + * @arg @ref LL_RCC_PLLVCORANGE_MEDIUM + * @retval None + */ +__STATIC_INLINE void LL_RCC_PLL3_SetVCOOutputRange(uint32_t VCORange) +{ + MODIFY_REG(RCC->PLL3CFGR, RCC_PLL3CFGR_PLL3VCOSEL, VCORange << RCC_PLL3CFGR_PLL3VCOSEL_Pos); +} + +/** + * @} + */ +#endif /* PLL3 */ + +/** @defgroup RCC_LL_EF_PRIV Privileged mode + * @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Enable Secure Privileged mode + * @rmtoll PRIVCFGR SPRIV LL_RCC_EnableSecPrivilegedMode + * @retval None + */ +__STATIC_INLINE void LL_RCC_EnableSecPrivilegedMode(void) +{ + SET_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_SPRIV); +} + +/** + * @brief Disable Secure Privileged mode + * @rmtoll PRIVCFGR SPRIV LL_RCC_DisableSecPrivilegedMode + * @retval None + */ +__STATIC_INLINE void LL_RCC_DisableSecPrivilegedMode(void) +{ + CLEAR_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_SPRIV); +} + +#endif /* __ARM_FEATURE_CMSE && (__ARM_FEATURE_CMSE == 3U) */ + +#if defined(RCC_PRIVCFGR_NSPRIV) +/** + * @brief Enable Non Secure Privileged mode + * @rmtoll PRIVCFGR NSPRIV LL_RCC_EnableNSecPrivilegedMode + * @retval None + */ +__STATIC_INLINE void LL_RCC_EnableNSecPrivilegedMode(void) +{ + SET_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_NSPRIV); +} + +/** + * @brief Disable Non Secure Privileged mode + * @rmtoll PRIVCFGR NSPRIV LL_RCC_DisableNSecPrivilegedMode + * @retval None + */ +__STATIC_INLINE void LL_RCC_DisableNSecPrivilegedMode(void) +{ + CLEAR_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_NSPRIV); +} + +/** + * @brief Check if Secure Privileged mode has been enabled or not + * @rmtoll PRIVCFGR SPRIV LL_RCC_IsEnabledSecPrivilegedMode + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsEnabledSecPrivilegedMode(void) +{ + return ((READ_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_SPRIV) == RCC_PRIVCFGR_SPRIV) ? 1UL : 0UL); +} + +/** + * @brief Check if Non Secure Privileged mode has been enabled or not + * @rmtoll PRIVCFGR NSPRIV LL_RCC_IsEnabledNSecPrivilegedMode + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsEnabledNSecPrivilegedMode(void) +{ + return ((READ_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_NSPRIV) == RCC_PRIVCFGR_NSPRIV) ? 1UL : 0UL); +} + +#else +/** + * @brief Enable Privileged mode + * @rmtoll PRIVCFGR PRIV LL_RCC_EnablePrivilegedMode + * @retval None + */ +__STATIC_INLINE void LL_RCC_EnablePrivilegedMode(void) +{ + SET_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_PRIV); +} + +/** + * @brief Disable Privileged mode + * @rmtoll PRIVCFGR PRIV LL_RCC_DisablePrivilegedMode + * @retval None + */ +__STATIC_INLINE void LL_RCC_DisablePrivilegedMode(void) +{ + CLEAR_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_PRIV); +} + +/** + * @brief Check if Privileged mode has been enabled or not + * @rmtoll PRIVCFGR PRIV LL_RCC_IsEnabledPrivilegedMode + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsEnabledPrivilegedMode(void) +{ + return ((READ_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_PRIV) == RCC_PRIVCFGR_PRIV) ? 1UL : 0UL); +} + +#endif /* RCC_PRIVCFGR_NSPRIV */ + +/** + * @} + */ + +/** @defgroup RCC_LL_EF_FLAG_Management FLAG Management + * @{ + */ + +/** + * @brief Clear LSI ready interrupt flag + * @rmtoll CICR LSIRDYC LL_RCC_ClearFlag_LSIRDY + * @retval None + */ +__STATIC_INLINE void LL_RCC_ClearFlag_LSIRDY(void) +{ + SET_BIT(RCC->CICR, RCC_CICR_LSIRDYC); +} + +/** + * @brief Clear LSE ready interrupt flag + * @rmtoll CICR LSERDYC LL_RCC_ClearFlag_LSERDY + * @retval None + */ +__STATIC_INLINE void LL_RCC_ClearFlag_LSERDY(void) +{ + SET_BIT(RCC->CICR, RCC_CICR_LSERDYC); +} + +/** + * @brief Clear CSI ready interrupt flag + * @rmtoll CICR CSIRDYC LL_RCC_ClearFlag_CSIRDY + * @retval None + */ +__STATIC_INLINE void LL_RCC_ClearFlag_CSIRDY(void) +{ + SET_BIT(RCC->CICR, RCC_CICR_CSIRDYC); +} + +/** + * @brief Clear HSI ready interrupt flag + * @rmtoll CICR HSIRDYC LL_RCC_ClearFlag_HSIRDY + * @retval None + */ +__STATIC_INLINE void LL_RCC_ClearFlag_HSIRDY(void) +{ + SET_BIT(RCC->CICR, RCC_CICR_HSIRDYC); +} + +/** + * @brief Clear HSE ready interrupt flag + * @rmtoll CICR HSERDYC LL_RCC_ClearFlag_HSERDY + * @retval None + */ +__STATIC_INLINE void LL_RCC_ClearFlag_HSERDY(void) +{ + SET_BIT(RCC->CICR, RCC_CICR_HSERDYC); +} + + +/** + * @brief Clear HSI48 ready interrupt flag + * @rmtoll CICR HSI48RDYC LL_RCC_ClearFlag_HSI48RDY + * @retval None + */ +__STATIC_INLINE void LL_RCC_ClearFlag_HSI48RDY(void) +{ + SET_BIT(RCC->CICR, RCC_CICR_HSI48RDYC); +} + +/** + * @brief Clear PLL1 ready interrupt flag + * @rmtoll CICR PLL1RDYC LL_RCC_ClearFlag_PLL1RDY + * @retval None + */ +__STATIC_INLINE void LL_RCC_ClearFlag_PLL1RDY(void) +{ + SET_BIT(RCC->CICR, RCC_CICR_PLL1RDYC); +} + +/** + * @brief Clear PLL2 ready interrupt flag + * @rmtoll CICR PLL2RDYC LL_RCC_ClearFlag_PLL2RDY + * @retval None + */ +__STATIC_INLINE void LL_RCC_ClearFlag_PLL2RDY(void) +{ + SET_BIT(RCC->CICR, RCC_CICR_PLL2RDYC); +} + +#if defined(RCC_CR_PLL3ON) +/** + * @brief Clear PLL3 ready interrupt flag + * @rmtoll CICR PLL3RDYC LL_RCC_ClearFlag_PLL3RDY + * @retval None + */ +__STATIC_INLINE void LL_RCC_ClearFlag_PLL3RDY(void) +{ + SET_BIT(RCC->CICR, RCC_CICR_PLL3RDYC); +} +#endif /* PLL3 */ + +/** + * @brief Clear Clock security system interrupt flag + * @rmtoll CICR HSECSSC LL_RCC_ClearFlag_HSECSS + * @retval None + */ +__STATIC_INLINE void LL_RCC_ClearFlag_HSECSS(void) +{ + SET_BIT(RCC->CICR, RCC_CICR_HSECSSC); +} + +/** + * @brief Check if LSI ready interrupt occurred or not + * @rmtoll CIFR LSIRDYF LL_RCC_IsActiveFlag_LSIRDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_LSIRDY(void) +{ + return ((READ_BIT(RCC->CIFR, RCC_CIFR_LSIRDYF) == RCC_CIFR_LSIRDYF) ? 1UL : 0UL); +} + +/** + * @brief Check if LSE ready interrupt occurred or not + * @rmtoll CIFR LSERDYF LL_RCC_IsActiveFlag_LSERDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_LSERDY(void) +{ + return ((READ_BIT(RCC->CIFR, RCC_CIFR_LSERDYF) == RCC_CIFR_LSERDYF) ? 1UL : 0UL); +} + +/** + * @brief Check if CSI ready interrupt occurred or not + * @rmtoll CIFR CSIRDYF LL_RCC_IsActiveFlag_CSIRDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_CSIRDY(void) +{ + return ((READ_BIT(RCC->CIFR, RCC_CIFR_CSIRDYF) == RCC_CIFR_CSIRDYF) ? 1UL : 0UL); +} + +/** + * @brief Check if HSI ready interrupt occurred or not + * @rmtoll CIFR HSIRDYF LL_RCC_IsActiveFlag_HSIRDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_HSIRDY(void) +{ + return ((READ_BIT(RCC->CIFR, RCC_CIFR_HSIRDYF) == RCC_CIFR_HSIRDYF) ? 1UL : 0UL); +} + +/** + * @brief Check if HSE ready interrupt occurred or not + * @rmtoll CIFR HSERDYF LL_RCC_IsActiveFlag_HSERDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_HSERDY(void) +{ + return ((READ_BIT(RCC->CIFR, RCC_CIFR_HSERDYF) == RCC_CIFR_HSERDYF) ? 1UL : 0UL); +} + +/** + * @brief Check if HSI48 ready interrupt occurred or not + * @rmtoll CIFR HSI48RDYF LL_RCC_IsActiveFlag_HSI48RDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_HSI48RDY(void) +{ + return ((READ_BIT(RCC->CIFR, RCC_CIFR_HSI48RDYF) == RCC_CIFR_HSI48RDYF) ? 1UL : 0UL); +} +/** + * @brief Check if PLL1 ready interrupt occurred or not + * @rmtoll CIFR PLL1RDYF LL_RCC_IsActiveFlag_PLL1RDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_PLL1RDY(void) +{ + return ((READ_BIT(RCC->CIFR, RCC_CIFR_PLL1RDYF) == RCC_CIFR_PLL1RDYF) ? 1UL : 0UL); +} + +/** + * @brief Check if PLL2 ready interrupt occurred or not + * @rmtoll CIFR PLL2RDYF LL_RCC_IsActiveFlag_PLL2RDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_PLL2RDY(void) +{ + return ((READ_BIT(RCC->CIFR, RCC_CIFR_PLL2RDYF) == RCC_CIFR_PLL2RDYF) ? 1UL : 0UL); +} + +#if defined(RCC_CR_PLL3ON) +/** + * @brief Check if PLL3 ready interrupt occurred or not + * @rmtoll CIFR PLL3RDYF LL_RCC_IsActiveFlag_PLL3RDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_PLL3RDY(void) +{ + return ((READ_BIT(RCC->CIFR, RCC_CIFR_PLL3RDYF) == RCC_CIFR_PLL3RDYF) ? 1UL : 0UL); +} +#endif /* PLL3 */ + +/** + * @brief Check if Clock security system interrupt occurred or not + * @rmtoll CIFR HSECSSF LL_RCC_IsActiveFlag_HSECSS + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_HSECSS(void) +{ + return ((READ_BIT(RCC->CIFR, RCC_CIFR_HSECSSF) == RCC_CIFR_HSECSSF) ? 1UL : 0UL); +} + +/** + * @brief Check if RCC flag Independent Watchdog reset is set or not. + * @rmtoll RSR IWDGRSTF LL_RCC_IsActiveFlag_IWDGRST + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_IWDGRST(void) +{ + return ((READ_BIT(RCC->RSR, RCC_RSR_IWDGRSTF) == RCC_RSR_IWDGRSTF) ? 1UL : 0UL); +} + +/** + * @brief Check if RCC flag Low Power reset is set or not. + * @rmtoll RSR LPWRRSTF LL_RCC_IsActiveFlag_LPWRRST + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_LPWRRST(void) +{ + return ((READ_BIT(RCC->RSR, RCC_RSR_LPWRRSTF) == RCC_RSR_LPWRRSTF) ? 1UL : 0UL); +} + +/** + * @brief Check if RCC flag Pin reset is set or not. + * @rmtoll RSR PINRSTF LL_RCC_IsActiveFlag_PINRST + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_PINRST(void) +{ + return ((READ_BIT(RCC->RSR, RCC_RSR_PINRSTF) == RCC_RSR_PINRSTF) ? 1UL : 0UL); +} + +/** + * @brief Check if RCC flag Software reset is set or not. + * @rmtoll RSR SFTRSTF LL_RCC_IsActiveFlag_SFTRST + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_SFTRST(void) +{ + return ((READ_BIT(RCC->RSR, RCC_RSR_SFTRSTF) == RCC_RSR_SFTRSTF) ? 1UL : 0UL); +} + +/** + * @brief Check if RCC flag Window Watchdog reset is set or not. + * @rmtoll RSR WWDGRSTF LL_RCC_IsActiveFlag_WWDGRST + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_WWDGRST(void) +{ + return ((READ_BIT(RCC->RSR, RCC_RSR_WWDGRSTF) == RCC_RSR_WWDGRSTF) ? 1UL : 0UL); +} + +/** + * @brief Check if RCC flag BOR reset is set or not. + * @rmtoll RSR BORRSTF LL_RCC_IsActiveFlag_BORRST + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_BORRST(void) +{ + return ((READ_BIT(RCC->RSR, RCC_RSR_BORRSTF) == RCC_RSR_BORRSTF) ? 1UL : 0UL); +} + +/** + * @brief Set RMVF bit to clear the reset flags. + * @rmtoll RSR RMVF LL_RCC_ClearResetFlags + * @retval None + */ +__STATIC_INLINE void LL_RCC_ClearResetFlags(void) +{ + SET_BIT(RCC->RSR, RCC_RSR_RMVF); +} + +/** + * @} + */ + +/** @defgroup RCC_LL_EF_IT_Management IT Management + * @{ + */ + +/** + * @brief Enable LSI ready interrupt + * @rmtoll CIER LSIRDYIE LL_RCC_EnableIT_LSIRDY + * @retval None + */ +__STATIC_INLINE void LL_RCC_EnableIT_LSIRDY(void) +{ + SET_BIT(RCC->CIER, RCC_CIER_LSIRDYIE); +} + +/** + * @brief Enable LSE ready interrupt + * @rmtoll CIER LSERDYIE LL_RCC_EnableIT_LSERDY + * @retval None + */ +__STATIC_INLINE void LL_RCC_EnableIT_LSERDY(void) +{ + SET_BIT(RCC->CIER, RCC_CIER_LSERDYIE); +} + +/** + * @brief Enable CSI ready interrupt + * @rmtoll CIER CSIRDYIE LL_RCC_EnableIT_CSIRDY + * @retval None + */ +__STATIC_INLINE void LL_RCC_EnableIT_CSIRDY(void) +{ + SET_BIT(RCC->CIER, RCC_CIER_CSIRDYIE); +} + +/** + * @brief Enable HSI ready interrupt + * @rmtoll CIER HSIRDYIE LL_RCC_EnableIT_HSIRDY + * @retval None + */ +__STATIC_INLINE void LL_RCC_EnableIT_HSIRDY(void) +{ + SET_BIT(RCC->CIER, RCC_CIER_HSIRDYIE); +} + +/** + * @brief Enable HSE ready interrupt + * @rmtoll CIER HSERDYIE LL_RCC_EnableIT_HSERDY + * @retval None + */ +__STATIC_INLINE void LL_RCC_EnableIT_HSERDY(void) +{ + SET_BIT(RCC->CIER, RCC_CIER_HSERDYIE); +} + +/** + * @brief Enable HSI48 ready interrupt + * @rmtoll CIER HSI48RDYIE LL_RCC_EnableIT_HSI48RDY + * @retval None + */ +__STATIC_INLINE void LL_RCC_EnableIT_HSI48RDY(void) +{ + SET_BIT(RCC->CIER, RCC_CIER_HSI48RDYIE); +} + +/** + * @brief Enable PLL1 ready interrupt + * @rmtoll CIER PLL1RDYIE LL_RCC_EnableIT_PLL1RDY + * @retval None + */ +__STATIC_INLINE void LL_RCC_EnableIT_PLL1RDY(void) +{ + SET_BIT(RCC->CIER, RCC_CIER_PLL1RDYIE); +} + +/** + * @brief Enable PLL2 ready interrupt + * @rmtoll CIER PLL2RDYIE LL_RCC_EnableIT_PLL2RDY + * @retval None + */ +__STATIC_INLINE void LL_RCC_EnableIT_PLL2RDY(void) +{ + SET_BIT(RCC->CIER, RCC_CIER_PLL2RDYIE); +} + +#if defined(RCC_CR_PLL3ON) +/** + * @brief Enable PLL3 ready interrupt + * @rmtoll CIER PLL3RDYIE LL_RCC_EnableIT_PLL3RDY + * @retval None + */ +__STATIC_INLINE void LL_RCC_EnableIT_PLL3RDY(void) +{ + SET_BIT(RCC->CIER, RCC_CIER_PLL3RDYIE); +} +#endif /* PLL3 */ + +/** + * @brief Disable LSI ready interrupt + * @rmtoll CIER LSIRDYIE LL_RCC_DisableIT_LSIRDY + * @retval None + */ +__STATIC_INLINE void LL_RCC_DisableIT_LSIRDY(void) +{ + CLEAR_BIT(RCC->CIER, RCC_CIER_LSIRDYIE); +} + +/** + * @brief Disable LSE ready interrupt + * @rmtoll CIER LSERDYIE LL_RCC_DisableIT_LSERDY + * @retval None + */ +__STATIC_INLINE void LL_RCC_DisableIT_LSERDY(void) +{ + CLEAR_BIT(RCC->CIER, RCC_CIER_LSERDYIE); +} + +/** + * @brief Disable CSI ready interrupt + * @rmtoll CIER CSIRDYIE LL_RCC_DisableIT_CSIRDY + * @retval None + */ +__STATIC_INLINE void LL_RCC_DisableIT_CSIRDY(void) +{ + CLEAR_BIT(RCC->CIER, RCC_CIER_CSIRDYIE); +} + +/** + * @brief Disable HSI ready interrupt + * @rmtoll CIER HSIRDYIE LL_RCC_DisableIT_HSIRDY + * @retval None + */ +__STATIC_INLINE void LL_RCC_DisableIT_HSIRDY(void) +{ + CLEAR_BIT(RCC->CIER, RCC_CIER_HSIRDYIE); +} + +/** + * @brief Disable HSE ready interrupt + * @rmtoll CIER HSERDYIE LL_RCC_DisableIT_HSERDY + * @retval None + */ +__STATIC_INLINE void LL_RCC_DisableIT_HSERDY(void) +{ + CLEAR_BIT(RCC->CIER, RCC_CIER_HSERDYIE); +} + +/** + * @brief Disable HSI48 ready interrupt + * @rmtoll CIER HSI48RDYIE LL_RCC_DisableIT_HSI48RDY + * @retval None + */ +__STATIC_INLINE void LL_RCC_DisableIT_HSI48RDY(void) +{ + CLEAR_BIT(RCC->CIER, RCC_CIER_HSI48RDYIE); +} + +/** + * @brief Disable PLL1 ready interrupt + * @rmtoll CIER PLL1RDYIE LL_RCC_DisableIT_PLL1RDY + * @retval None + */ +__STATIC_INLINE void LL_RCC_DisableIT_PLL1RDY(void) +{ + CLEAR_BIT(RCC->CIER, RCC_CIER_PLL1RDYIE); +} + +/** + * @brief Disable PLL2 ready interrupt + * @rmtoll CIER PLL2RDYIE LL_RCC_DisableIT_PLL2RDY + * @retval None + */ +__STATIC_INLINE void LL_RCC_DisableIT_PLL2RDY(void) +{ + CLEAR_BIT(RCC->CIER, RCC_CIER_PLL2RDYIE); +} + +#if defined(RCC_CR_PLL3ON) +/** + * @brief Disable PLL3 ready interrupt + * @rmtoll CIER PLL3RDYIE LL_RCC_DisableIT_PLL3RDY + * @retval None + */ +__STATIC_INLINE void LL_RCC_DisableIT_PLL3RDY(void) +{ + CLEAR_BIT(RCC->CIER, RCC_CIER_PLL3RDYIE); +} +#endif /* PLL3 */ + +/** + * @brief Checks if LSI ready interrupt source is enabled or disabled. + * @rmtoll CIER LSIRDYIE LL_RCC_IsEnabledIT_LSIRDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsEnabledIT_LSIRDY(void) +{ + return ((READ_BIT(RCC->CIER, RCC_CIER_LSIRDYIE) == RCC_CIER_LSIRDYIE) ? 1UL : 0UL); +} + +/** + * @brief Checks if LSE ready interrupt source is enabled or disabled. + * @rmtoll CIER LSERDYIE LL_RCC_IsEnabledIT_LSERDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsEnabledIT_LSERDY(void) +{ + return ((READ_BIT(RCC->CIER, RCC_CIER_LSERDYIE) == RCC_CIER_LSERDYIE) ? 1UL : 0UL); +} + +/** + * @brief Checks if CSI ready interrupt source is enabled or disabled. + * @rmtoll CIER CSIRDYIE LL_RCC_IsEnabledIT_CSIRDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsEnabledIT_CSIRDY(void) +{ + return ((READ_BIT(RCC->CIER, RCC_CIER_CSIRDYIE) == RCC_CIER_CSIRDYIE) ? 1UL : 0UL); +} + +/** + * @brief Checks if HSI ready interrupt source is enabled or disabled. + * @rmtoll CIER HSIRDYIE LL_RCC_IsEnabledIT_HSIRDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsEnabledIT_HSIRDY(void) +{ + return ((READ_BIT(RCC->CIER, RCC_CIER_HSIRDYIE) == RCC_CIER_HSIRDYIE) ? 1UL : 0UL); +} + +/** + * @brief Checks if HSE ready interrupt source is enabled or disabled. + * @rmtoll CIER HSERDYIE LL_RCC_IsEnabledIT_HSERDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsEnabledIT_HSERDY(void) +{ + return ((READ_BIT(RCC->CIER, RCC_CIER_HSERDYIE) == RCC_CIER_HSERDYIE) ? 1UL : 0UL); +} + +/** + * @brief Checks if HSI48 ready interrupt source is enabled or disabled. + * @rmtoll CIER HSI48RDYIE LL_RCC_IsEnabledIT_HSI48RDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsEnabledIT_HSI48RDY(void) +{ + return ((READ_BIT(RCC->CIER, RCC_CIER_HSI48RDYIE) == RCC_CIER_HSI48RDYIE) ? 1UL : 0UL); +} +/** + * @brief Checks if PLL1 ready interrupt source is enabled or disabled. + * @rmtoll CIER PLL1RDYIE LL_RCC_IsEnabledIT_PLL1RDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsEnabledIT_PLL1RDY(void) +{ + return ((READ_BIT(RCC->CIER, RCC_CIER_PLL1RDYIE) == RCC_CIER_PLL1RDYIE) ? 1UL : 0UL); +} + +/** + * @brief Checks if PLL2 ready interrupt source is enabled or disabled. + * @rmtoll CIER PLL2RDYIE LL_RCC_IsEnabledIT_PLL2RDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsEnabledIT_PLL2RDY(void) +{ + return ((READ_BIT(RCC->CIER, RCC_CIER_PLL2RDYIE) == RCC_CIER_PLL2RDYIE) ? 1UL : 0UL); +} + +#if defined(RCC_CR_PLL3ON) +/** + * @brief Checks if PLL3 ready interrupt source is enabled or disabled. + * @rmtoll CIER PLL3RDYIE LL_RCC_IsEnabledIT_PLL3RDY + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RCC_IsEnabledIT_PLL3RDY(void) +{ + return ((READ_BIT(RCC->CIER, RCC_CIER_PLL3RDYIE) == RCC_CIER_PLL3RDYIE) ? 1UL : 0UL); +} +#endif /* PLL3 */ + +/** + * @} + */ + +/** @defgroup RCC_LL_EF_Security_Services Security Services + * @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Configure RCC resources security + * @note Only available from secure state when system implements security (TZEN=1) + * @rmtoll SECCFGR HSISEC LL_RCC_ConfigSecure\n + * SECCFGR HSESEC LL_RCC_ConfigSecure\n + * SECCFGR CSISEC LL_RCC_ConfigSecure\n + * SECCFGR LSISEC LL_RCC_ConfigSecure\n + * SECCFGR LSESEC LL_RCC_ConfigSecure\n + * SECCFGR SYSCLKSEC LL_RCC_ConfigSecure\n + * SECCFGR PRESCSEC LL_RCC_ConfigSecure\n + * SECCFGR PLL1SEC LL_RCC_ConfigSecure\n + * SECCFGR PLL2SEC LL_RCC_ConfigSecure\n + * SECCFGR PLL3SEC LL_RCC_ConfigSecure\n + * SECCFGR HSI48SEC LL_RCC_ConfigSecure\n + * SECCFGR RMVFSEC LL_RCC_ConfigSecure\n + * SECCFGR CKPERSELSEC LL_RCC_ConfigSecure + * @param Configuration This parameter shall be the full combination of the following values: + * @arg @ref LL_RCC_ALL_SEC or LL_RCC_ALL_NSEC + * @arg @ref LL_RCC_HSI_SEC or LL_RCC_HSI_NSEC + * @arg @ref LL_RCC_HSE_SEC or LL_RCC_HSE_NSEC + * @arg @ref LL_RCC_CSI_SEC or LL_RCC_CSI_NSEC + * @arg @ref LL_RCC_LSE_SEC or LL_RCC_LSE_NSEC + * @arg @ref LL_RCC_LSI_SEC or LL_RCC_LSI_NSEC + * @arg @ref LL_RCC_SYSCLK_SEC or LL_RCC_SYSCLK_NSEC + * @arg @ref LL_RCC_PRESCALERS_SEC or LL_RCC_PRESCALERS_NSEC + * @arg @ref LL_RCC_PLL1_SEC or LL_RCC_PLL1_NSEC + * @arg @ref LL_RCC_PLL2_SEC or LL_RCC_PLL2_NSEC + * @arg @ref LL_RCC_PLL3_SEC or LL_RCC_PLL3_NSEC + * @arg @ref LL_RCC_HSI48_SEC or LL_RCC_HSI48_NSEC + * @arg @ref LL_RCC_RESET_FLAGS_SEC or LL_RCC_RESET_FLAGS_NSEC + * @arg @ref LL_RCC_CKPERSEL_SEC or LL_RCC_CKPERSEL_NSEC + * @retval None + */ +__STATIC_INLINE void LL_RCC_ConfigSecure(uint32_t Configuration) +{ + WRITE_REG(RCC->SECCFGR, Configuration); +} +#endif /* __ARM_FEATURE_CMSE && (__ARM_FEATURE_CMSE == 3U) */ + +#if defined(RCC_SECCFGR_HSISEC) +/** + * @brief Get RCC resources security status + * @note Only available from secure state when system implements security (TZEN=1) + * @rmtoll SECCFGR HSISEC LL_RCC_GetConfigSecure\n + * SECCFGR HSESEC LL_RCC_GetConfigSecure\n + * SECCFGR CSISEC LL_RCC_GetConfigSecure\n + * SECCFGR LSISEC LL_RCC_GetConfigSecure\n + * SECCFGR LSESEC LL_RCC_GetConfigSecure\n + * SECCFGR SYSCLKSEC LL_RCC_GetConfigSecure\n + * SECCFGR PRESCSEC LL_RCC_GetConfigSecure\n + * SECCFGR PLL1SEC LL_RCC_GetConfigSecure\n + * SECCFGR PLL2SEC LL_RCC_GetConfigSecure\n + * SECCFGR PLL3SEC LL_RCC_GetConfigSecure\n + * SECCFGR HSI48SEC LL_RCC_GetConfigSecure\n + * SECCFGR RMVFSEC LL_RCC_GetConfigSecure\n + * SECCFGR CKPERSELSEC LL_RCC_GetConfigSecure + * @retval Returned value is the combination of the following values: + * @arg @ref LL_RCC_ALL_SEC or LL_RCC_ALL_NSEC + * @arg @ref LL_RCC_HSI_SEC or LL_RCC_HSI_NSEC + * @arg @ref LL_RCC_HSE_SEC or LL_RCC_HSE_NSEC + * @arg @ref LL_RCC_CSI_SEC or LL_RCC_CSI_NSEC + * @arg @ref LL_RCC_LSE_SEC or LL_RCC_LSE_NSEC + * @arg @ref LL_RCC_LSI_SEC or LL_RCC_LSI_NSEC + * @arg @ref LL_RCC_SYSCLK_SEC or LL_RCC_SYSCLK_NSEC + * @arg @ref LL_RCC_PRESCALERS_SEC or LL_RCC_PRESCALERS_NSEC + * @arg @ref LL_RCC_PLL1_SEC or LL_RCC_PLL1_NSEC + * @arg @ref LL_RCC_PLL2_SEC or LL_RCC_PLL2_NSEC + * @arg @ref LL_RCC_PLL3_SEC or LL_RCC_PLL3_NSEC + * @arg @ref LL_RCC_HSI48_SEC or LL_RCC_HSI48_NSEC + * @arg @ref LL_RCC_RESET_FLAGS_SEC or LL_RCC_RESET_FLAGS_NSEC + * @arg @ref LL_RCC_CKPERSEL_SEC or LL_RCC_CKPERSEL_NSEC + * @retval None + */ +__STATIC_INLINE uint32_t LL_RCC_GetConfigSecure(void) +{ + return (uint32_t)(READ_BIT(RCC->SECCFGR, RCC_SECURE_MASK)); +} +#endif /* RCC_SECCFGR_HSISEC */ + +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup RCC_LL_EF_Init De-initialization function + * @{ + */ +ErrorStatus LL_RCC_DeInit(void); +/** + * @} + */ + +/** @defgroup RCC_LL_EF_Get_Freq Get system and peripherals clocks frequency functions + * @{ + */ + +uint32_t LL_RCC_CalcPLLClockFreq(uint32_t PLLInputFreq, uint32_t M, uint32_t N, uint32_t FRACN, uint32_t PQR); + +void LL_RCC_GetPLL1ClockFreq(LL_PLL_ClocksTypeDef *pPLL_Clocks); +void LL_RCC_GetPLL2ClockFreq(LL_PLL_ClocksTypeDef *pPLL_Clocks); +#if defined(RCC_CR_PLL3ON) +void LL_RCC_GetPLL3ClockFreq(LL_PLL_ClocksTypeDef *pPLL_Clocks); +#endif /* PLL3 */ +void LL_RCC_GetSystemClocksFreq(LL_RCC_ClocksTypeDef *pRCC_Clocks); +uint32_t LL_RCC_GetUSARTClockFreq(uint32_t USARTxSource); +#if defined(UART4) +uint32_t LL_RCC_GetUARTClockFreq(uint32_t UARTxSource); +#endif /* UART4 */ +uint32_t LL_RCC_GetI2CClockFreq(uint32_t I2CxSource); +uint32_t LL_RCC_GetI3CClockFreq(uint32_t I3CxSource); +uint32_t LL_RCC_GetLPUARTClockFreq(uint32_t LPUARTxSource); +uint32_t LL_RCC_GetLPTIMClockFreq(uint32_t LPTIMxSource); +uint32_t LL_RCC_GetFDCANClockFreq(uint32_t FDCANxSource); +#if defined (SAI1) +uint32_t LL_RCC_GetSAIClockFreq(uint32_t SAIxSource); +#endif /* SAI1 */ +#if defined(SDMMC1) +uint32_t LL_RCC_GetSDMMCClockFreq(uint32_t SDMMCxSource); +#endif /* SDMMC1 */ +uint32_t LL_RCC_GetRNGClockFreq(uint32_t RNGxSource); +uint32_t LL_RCC_GetUSBClockFreq(uint32_t USBxSource); +uint32_t LL_RCC_GetADCDACClockFreq(uint32_t ADCDACxSource); +uint32_t LL_RCC_GetDACLPClockFreq(uint32_t DACLPxSource); +#if defined(OCTOSPI1) +uint32_t LL_RCC_GetOCTOSPIClockFreq(uint32_t OCTOSPIxSource); +#endif /* OCTOSPI1 */ +uint32_t LL_RCC_GetSPIClockFreq(uint32_t SPIxSource); +#if defined(CEC) +uint32_t LL_RCC_GetCECClockFreq(uint32_t CECxSource); +#endif /* CEC */ +uint32_t LL_RCC_GetCLKPClockFreq(uint32_t CLKPxSource); +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined(RCC) */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32H5xx_LL_RCC_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_rng.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_rng.h new file mode 100644 index 0000000000..a476175bae --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_rng.h @@ -0,0 +1,724 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_rng.h + * @author MCD Application Team + * @brief Header file of RNG LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_LL_RNG_H +#define STM32H5xx_LL_RNG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (RNG) + +/** @defgroup RNG_LL RNG + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ + +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup RNG_LL_ES_Init_Struct RNG Exported Init structures + * @{ + */ + + +/** + * @brief LL RNG Init Structure Definition + */ +typedef struct +{ + uint32_t ClockErrorDetection; /*!< Clock error detection. + This parameter can be one value of @ref RNG_LL_CED. + This parameter can be modified using unitary + functions @ref LL_RNG_EnableClkErrorDetect(). */ +} LL_RNG_InitTypeDef; + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup RNG_LL_Exported_Constants RNG Exported Constants + * @{ + */ + +/** @defgroup RNG_LL_CED Clock Error Detection + * @{ + */ +#define LL_RNG_CED_ENABLE 0x00000000U /*!< Clock error detection enabled */ +#define LL_RNG_CED_DISABLE RNG_CR_CED /*!< Clock error detection disabled */ +/** + * @} + */ +/** @defgroup RNG_LL_ARDIS Auto reset disable + * @{ + */ +#define LL_RNG_ARDIS_ENABLE 0x00000000U /*!< ARDIS enabled automatic reset to clear SECS bit*/ +#define LL_RNG_ARDIS_DISABLE RNG_CR_ARDIS /*!< ARDIS disabled no automatic reset to clear SECS bit*/ +/** + * @} + */ + +/** @defgroup RNG_LL_Clock_Divider_Factor Value used to configure an internal + * programmable divider acting on the incoming RNG clock + * @{ + */ +#define LL_RNG_CLKDIV_BY_1 (0x00000000UL) /*!< No clock division */ +#define LL_RNG_CLKDIV_BY_2 (RNG_CR_CLKDIV_0) /*!< 2 RNG clock cycles per internal RNG clock */ +#define LL_RNG_CLKDIV_BY_4 (RNG_CR_CLKDIV_1) /*!< 4 RNG clock cycles per internal RNG clock */ +#define LL_RNG_CLKDIV_BY_8 (RNG_CR_CLKDIV_1 | RNG_CR_CLKDIV_0) /*!< 8 RNG clock cycles per internal RNG clock */ +#define LL_RNG_CLKDIV_BY_16 (RNG_CR_CLKDIV_2) /*!< 16 RNG clock cycles per internal RNG clock */ +#define LL_RNG_CLKDIV_BY_32 (RNG_CR_CLKDIV_2 | RNG_CR_CLKDIV_0) /*!< 32 RNG clock cycles per internal RNG clock */ +#define LL_RNG_CLKDIV_BY_64 (RNG_CR_CLKDIV_2 | RNG_CR_CLKDIV_1) /*!< 64 RNG clock cycles per internal RNG clock */ +#define LL_RNG_CLKDIV_BY_128 (RNG_CR_CLKDIV_2 | RNG_CR_CLKDIV_1 | RNG_CR_CLKDIV_0) /*!< 128 RNG clock cycles per internal RNG clock */ +#define LL_RNG_CLKDIV_BY_256 (RNG_CR_CLKDIV_3) /*!< 256 RNG clock cycles per internal RNG clock */ +#define LL_RNG_CLKDIV_BY_512 (RNG_CR_CLKDIV_3 | RNG_CR_CLKDIV_0) /*!< 512 RNG clock cycles per internal RNG clock */ +#define LL_RNG_CLKDIV_BY_1024 (RNG_CR_CLKDIV_3 | RNG_CR_CLKDIV_1) /*!< 1024 RNG clock cycles per internal RNG clock */ +#define LL_RNG_CLKDIV_BY_2048 (RNG_CR_CLKDIV_3 | RNG_CR_CLKDIV_1 | RNG_CR_CLKDIV_0) /*!< 2048 RNG clock cycles per internal RNG clock */ +#define LL_RNG_CLKDIV_BY_4096 (RNG_CR_CLKDIV_3 | RNG_CR_CLKDIV_2) /*!< 4096 RNG clock cycles per internal RNG clock */ +#define LL_RNG_CLKDIV_BY_8192 (RNG_CR_CLKDIV_3 | RNG_CR_CLKDIV_2 | RNG_CR_CLKDIV_0) /*!< 8192 RNG clock cycles per internal RNG clock */ +#define LL_RNG_CLKDIV_BY_16384 (RNG_CR_CLKDIV_3 | RNG_CR_CLKDIV_2 | RNG_CR_CLKDIV_1) /*!< 16384 RNG clock cycles per internal RNG clock */ +#define LL_RNG_CLKDIV_BY_32768 (RNG_CR_CLKDIV_3 | RNG_CR_CLKDIV_2 | RNG_CR_CLKDIV_1 | RNG_CR_CLKDIV_0) /*!< 32768 RNG clock cycles per internal RNG clock */ +/** + * @} + */ + +/** @defgroup RNG_LL_NIST_Compliance NIST Compliance configuration + * @{ + */ +#define LL_RNG_NIST_COMPLIANT (0x00000000UL) /*!< Default NIST compliant configuration*/ +#define LL_RNG_CUSTOM_NIST (RNG_CR_NISTC) /*!< Custom NIST configuration */ + +/** + * @} + */ + +/** @defgroup RNG_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_RNG_ReadReg function + * @{ + */ +#define LL_RNG_SR_DRDY RNG_SR_DRDY /*!< Register contains valid random data */ +#define LL_RNG_SR_CECS RNG_SR_CECS /*!< Clock error current status */ +#define LL_RNG_SR_SECS RNG_SR_SECS /*!< Seed error current status */ +#define LL_RNG_SR_CEIS RNG_SR_CEIS /*!< Clock error interrupt status */ +#define LL_RNG_SR_SEIS RNG_SR_SEIS /*!< Seed error interrupt status */ +/** + * @} + */ + +/** @defgroup RNG_LL_EC_IT IT Defines + * @brief IT defines which can be used with LL_RNG_ReadReg and LL_RNG_WriteReg macros + * @{ + */ +#define LL_RNG_CR_IE RNG_CR_IE /*!< RNG Interrupt enable */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup RNG_LL_Exported_Macros RNG Exported Macros + * @{ + */ + +/** @defgroup RNG_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in RNG register + * @param __INSTANCE__ RNG Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_RNG_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in RNG register + * @param __INSTANCE__ RNG Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_RNG_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) +/** + * @} + */ + +/** + * @} + */ + + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup RNG_LL_Exported_Functions RNG Exported Functions + * @{ + */ +/** @defgroup RNG_LL_EF_Configuration RNG Configuration functions + * @{ + */ + +/** + * @brief Enable Random Number Generation + * @rmtoll CR RNGEN LL_RNG_Enable + * @param RNGx RNG Instance + * @retval None + */ +__STATIC_INLINE void LL_RNG_Enable(RNG_TypeDef *RNGx) +{ + SET_BIT(RNGx->CR, RNG_CR_RNGEN); +} + +/** + * @brief Disable Random Number Generation + * @rmtoll CR RNGEN LL_RNG_Disable + * @param RNGx RNG Instance + * @retval None + */ +__STATIC_INLINE void LL_RNG_Disable(RNG_TypeDef *RNGx) +{ + CLEAR_BIT(RNGx->CR, RNG_CR_RNGEN); +} + +/** + * @brief Check if Random Number Generator is enabled + * @rmtoll CR RNGEN LL_RNG_IsEnabled + * @param RNGx RNG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RNG_IsEnabled(const RNG_TypeDef *RNGx) +{ + return ((READ_BIT(RNGx->CR, RNG_CR_RNGEN) == (RNG_CR_RNGEN)) ? 1UL : 0UL); +} + +/** + * @brief Enable Clock Error Detection + * @rmtoll CR CED LL_RNG_EnableClkErrorDetect + * @param RNGx RNG Instance + * @retval None + */ +__STATIC_INLINE void LL_RNG_EnableClkErrorDetect(RNG_TypeDef *RNGx) +{ + CLEAR_BIT(RNGx->CR, RNG_CR_CED); +} + +/** + * @brief Disable RNG Clock Error Detection + * @rmtoll CR CED LL_RNG_DisableClkErrorDetect + * @param RNGx RNG Instance + * @retval None + */ +__STATIC_INLINE void LL_RNG_DisableClkErrorDetect(RNG_TypeDef *RNGx) +{ + SET_BIT(RNGx->CR, RNG_CR_CED); +} + +/** + * @brief Check if RNG Clock Error Detection is enabled + * @rmtoll CR CED LL_RNG_IsEnabledClkErrorDetect + * @param RNGx RNG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RNG_IsEnabledClkErrorDetect(const RNG_TypeDef *RNGx) +{ + return ((READ_BIT(RNGx->CR, RNG_CR_CED) != (RNG_CR_CED)) ? 1UL : 0UL); +} + +/** + * @brief Set RNG Conditioning Soft Reset bit + * @rmtoll CR CONDRST LL_RNG_EnableCondReset + * @param RNGx RNG Instance + * @retval None + */ +__STATIC_INLINE void LL_RNG_EnableCondReset(RNG_TypeDef *RNGx) +{ + SET_BIT(RNGx->CR, RNG_CR_CONDRST); +} + +/** + * @brief Reset RNG Conditioning Soft Reset bit + * @rmtoll CR CONDRST LL_RNG_DisableCondReset + * @param RNGx RNG Instance + * @retval None + */ +__STATIC_INLINE void LL_RNG_DisableCondReset(RNG_TypeDef *RNGx) +{ + CLEAR_BIT(RNGx->CR, RNG_CR_CONDRST); +} + +/** + * @brief Check if RNG Conditioning Soft Reset bit is set + * @rmtoll CR CONDRST LL_RNG_IsEnabledCondReset + * @param RNGx RNG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RNG_IsEnabledCondReset(const RNG_TypeDef *RNGx) +{ + return ((READ_BIT(RNGx->CR, RNG_CR_CONDRST) == (RNG_CR_CONDRST)) ? 1UL : 0UL); +} + +/** + * @brief Enable RNG Config Lock + * @rmtoll CR CONFIGLOCK LL_RNG_ConfigLock + * @param RNGx RNG Instance + * @retval None + */ +__STATIC_INLINE void LL_RNG_ConfigLock(RNG_TypeDef *RNGx) +{ + SET_BIT(RNGx->CR, RNG_CR_CONFIGLOCK); +} + +/** + * @brief Check if RNG Config Lock is enabled + * @rmtoll CR CONFIGLOCK LL_RNG_IsConfigLocked + * @param RNGx RNG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RNG_IsConfigLocked(const RNG_TypeDef *RNGx) +{ + return ((READ_BIT(RNGx->CR, RNG_CR_CONFIGLOCK) == (RNG_CR_CONFIGLOCK)) ? 1UL : 0UL); +} + +/** + * @brief Enable NIST Compliance + * @rmtoll CR NISTC LL_RNG_EnableNistCompliance + * @param RNGx RNG Instance + * @retval None + */ +__STATIC_INLINE void LL_RNG_EnableNistCompliance(RNG_TypeDef *RNGx) +{ + MODIFY_REG(RNGx->CR, RNG_CR_NISTC | RNG_CR_CONDRST, LL_RNG_NIST_COMPLIANT | RNG_CR_CONDRST); + CLEAR_BIT(RNGx->CR, RNG_CR_CONDRST); +} + +/** + * @brief Disable NIST Compliance + * @rmtoll CR NISTC LL_RNG_DisableNistCompliance + * @param RNGx RNG Instance + * @retval None + */ +__STATIC_INLINE void LL_RNG_DisableNistCompliance(RNG_TypeDef *RNGx) +{ + MODIFY_REG(RNGx->CR, RNG_CR_NISTC | RNG_CR_CONDRST, LL_RNG_CUSTOM_NIST | RNG_CR_CONDRST); + CLEAR_BIT(RNGx->CR, RNG_CR_CONDRST);; +} + +/** + * @brief Check if NIST Compliance is enabled + * @rmtoll CR NISTC LL_RNG_IsEnabledNistCompliance + * @param RNGx RNG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RNG_IsEnabledNistCompliance(const RNG_TypeDef *RNGx) +{ + return ((READ_BIT(RNGx->CR, RNG_CR_NISTC) != (RNG_CR_NISTC)) ? 1UL : 0UL); +} + +/** + * @brief Set RNG Config1 Configuration field value + * @rmtoll CR RNG_CONFIG1 LL_RNG_SetConfig1 + * @param RNGx RNG Instance + * @param Config1 Value between 0 and 0x3F + * @retval None + */ +__STATIC_INLINE void LL_RNG_SetConfig1(RNG_TypeDef *RNGx, uint32_t Config1) +{ + MODIFY_REG(RNGx->CR, RNG_CR_RNG_CONFIG1 | RNG_CR_CONDRST, (Config1 << RNG_CR_RNG_CONFIG1_Pos) | RNG_CR_CONDRST); + CLEAR_BIT(RNGx->CR, RNG_CR_CONDRST); +} + +/** + * @brief Get RNG Config1 Configuration field value + * @rmtoll CR RNG_CONFIG1 LL_RNG_GetConfig1 + * @param RNGx RNG Instance + * @retval Returned Value expressed on 6 bits : Value between 0 and 0x3F + */ +__STATIC_INLINE uint32_t LL_RNG_GetConfig1(const RNG_TypeDef *RNGx) +{ + return (uint32_t)(READ_BIT(RNGx->CR, RNG_CR_RNG_CONFIG1) >> RNG_CR_RNG_CONFIG1_Pos); +} + +/** + * @brief Set RNG Config2 Configuration field value + * @rmtoll CR RNG_CONFIG2 LL_RNG_SetConfig2 + * @param RNGx RNG Instance + * @param Config2 Value between 0 and 0x7 + * @retval None + */ +__STATIC_INLINE void LL_RNG_SetConfig2(RNG_TypeDef *RNGx, uint32_t Config2) +{ + MODIFY_REG(RNGx->CR, RNG_CR_RNG_CONFIG2 | RNG_CR_CONDRST, (Config2 << RNG_CR_RNG_CONFIG2_Pos) | RNG_CR_CONDRST); + CLEAR_BIT(RNGx->CR, RNG_CR_CONDRST); +} + +/** + * @brief Get RNG Config2 Configuration field value + * @rmtoll CR RNG_CONFIG2 LL_RNG_GetConfig2 + * @param RNGx RNG Instance + * @retval Returned Value expressed on 3 bits : Value between 0 and 0x7 + */ +__STATIC_INLINE uint32_t LL_RNG_GetConfig2(const RNG_TypeDef *RNGx) +{ + return (uint32_t)(READ_BIT(RNGx->CR, RNG_CR_RNG_CONFIG2) >> RNG_CR_RNG_CONFIG2_Pos); +} + +/** + * @brief Set RNG Config3 Configuration field value + * @rmtoll CR RNG_CONFIG3 LL_RNG_SetConfig3 + * @param RNGx RNG Instance + * @param Config3 Value between 0 and 0xF + * @retval None + */ +__STATIC_INLINE void LL_RNG_SetConfig3(RNG_TypeDef *RNGx, uint32_t Config3) +{ + MODIFY_REG(RNGx->CR, RNG_CR_RNG_CONFIG3 | RNG_CR_CONDRST, (Config3 << RNG_CR_RNG_CONFIG3_Pos) | RNG_CR_CONDRST); + CLEAR_BIT(RNGx->CR, RNG_CR_CONDRST); +} + +/** + * @brief Get RNG Config3 Configuration field value + * @rmtoll CR RNG_CONFIG3 LL_RNG_GetConfig3 + * @param RNGx RNG Instance + * @retval Returned Value expressed on 4 bits : Value between 0 and 0xF + */ +__STATIC_INLINE uint32_t LL_RNG_GetConfig3(const RNG_TypeDef *RNGx) +{ + return (uint32_t)(READ_BIT(RNGx->CR, RNG_CR_RNG_CONFIG3) >> RNG_CR_RNG_CONFIG3_Pos); +} + +/** + * @brief Set RNG Clock divider factor + * @rmtoll CR CLKDIV LL_RNG_SetClockDivider + * @param RNGx RNG Instance + * @param Divider can be one of the following values: + * @arg @ref LL_RNG_CLKDIV_BY_1 + * @arg @ref LL_RNG_CLKDIV_BY_2 + * @arg @ref LL_RNG_CLKDIV_BY_4 + * @arg @ref LL_RNG_CLKDIV_BY_8 + * @arg @ref LL_RNG_CLKDIV_BY_16 + * @arg @ref LL_RNG_CLKDIV_BY_32 + * @arg @ref LL_RNG_CLKDIV_BY_64 + * @arg @ref LL_RNG_CLKDIV_BY_128 + * @arg @ref LL_RNG_CLKDIV_BY_256 + * @arg @ref LL_RNG_CLKDIV_BY_512 + * @arg @ref LL_RNG_CLKDIV_BY_1024 + * @arg @ref LL_RNG_CLKDIV_BY_2048 + * @arg @ref LL_RNG_CLKDIV_BY_4096 + * @arg @ref LL_RNG_CLKDIV_BY_8192 + * @arg @ref LL_RNG_CLKDIV_BY_16384 + * @arg @ref LL_RNG_CLKDIV_BY_32768 + * @retval None + */ +__STATIC_INLINE void LL_RNG_SetClockDivider(RNG_TypeDef *RNGx, uint32_t Divider) +{ + MODIFY_REG(RNGx->CR, RNG_CR_CLKDIV | RNG_CR_CONDRST, (Divider << RNG_CR_CLKDIV_Pos) | RNG_CR_CONDRST); + CLEAR_BIT(RNGx->CR, RNG_CR_CONDRST); +} + +/** + * @brief Get RNG Clock divider factor + * @rmtoll CR CLKDIV LL_RNG_GetClockDivider + * @param RNGx RNG Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_RNG_CLKDIV_BY_1 + * @arg @ref LL_RNG_CLKDIV_BY_2 + * @arg @ref LL_RNG_CLKDIV_BY_4 + * @arg @ref LL_RNG_CLKDIV_BY_8 + * @arg @ref LL_RNG_CLKDIV_BY_16 + * @arg @ref LL_RNG_CLKDIV_BY_32 + * @arg @ref LL_RNG_CLKDIV_BY_64 + * @arg @ref LL_RNG_CLKDIV_BY_128 + * @arg @ref LL_RNG_CLKDIV_BY_256 + * @arg @ref LL_RNG_CLKDIV_BY_512 + * @arg @ref LL_RNG_CLKDIV_BY_1024 + * @arg @ref LL_RNG_CLKDIV_BY_2048 + * @arg @ref LL_RNG_CLKDIV_BY_4096 + * @arg @ref LL_RNG_CLKDIV_BY_8192 + * @arg @ref LL_RNG_CLKDIV_BY_16384 + * @arg @ref LL_RNG_CLKDIV_BY_32768 + */ +__STATIC_INLINE uint32_t LL_RNG_GetClockDivider(const RNG_TypeDef *RNGx) +{ + return (uint32_t)READ_BIT(RNGx->CR, RNG_CR_CLKDIV); +} +/** + * @} + */ + +/** @defgroup RNG_LL_EF_FLAG_Management FLAG Management + * @{ + */ + +/** + * @brief Indicate if the RNG Data ready Flag is set or not + * @rmtoll SR DRDY LL_RNG_IsActiveFlag_DRDY + * @param RNGx RNG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RNG_IsActiveFlag_DRDY(const RNG_TypeDef *RNGx) +{ + return ((READ_BIT(RNGx->SR, RNG_SR_DRDY) == (RNG_SR_DRDY)) ? 1UL : 0UL); +} + +/** + * @brief Indicate if the Clock Error Current Status Flag is set or not + * @rmtoll SR CECS LL_RNG_IsActiveFlag_CECS + * @param RNGx RNG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RNG_IsActiveFlag_CECS(const RNG_TypeDef *RNGx) +{ + return ((READ_BIT(RNGx->SR, RNG_SR_CECS) == (RNG_SR_CECS)) ? 1UL : 0UL); +} + +/** + * @brief Indicate if the Seed Error Current Status Flag is set or not + * @rmtoll SR SECS LL_RNG_IsActiveFlag_SECS + * @param RNGx RNG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RNG_IsActiveFlag_SECS(const RNG_TypeDef *RNGx) +{ + return ((READ_BIT(RNGx->SR, RNG_SR_SECS) == (RNG_SR_SECS)) ? 1UL : 0UL); +} + +/** + * @brief Indicate if the Clock Error Interrupt Status Flag is set or not + * @rmtoll SR CEIS LL_RNG_IsActiveFlag_CEIS + * @param RNGx RNG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RNG_IsActiveFlag_CEIS(const RNG_TypeDef *RNGx) +{ + return ((READ_BIT(RNGx->SR, RNG_SR_CEIS) == (RNG_SR_CEIS)) ? 1UL : 0UL); +} + +/** + * @brief Indicate if the Seed Error Interrupt Status Flag is set or not + * @rmtoll SR SEIS LL_RNG_IsActiveFlag_SEIS + * @param RNGx RNG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RNG_IsActiveFlag_SEIS(const RNG_TypeDef *RNGx) +{ + return ((READ_BIT(RNGx->SR, RNG_SR_SEIS) == (RNG_SR_SEIS)) ? 1UL : 0UL); +} + +/** + * @brief Clear Clock Error interrupt Status (CEIS) Flag + * @rmtoll SR CEIS LL_RNG_ClearFlag_CEIS + * @param RNGx RNG Instance + * @retval None + */ +__STATIC_INLINE void LL_RNG_ClearFlag_CEIS(RNG_TypeDef *RNGx) +{ + WRITE_REG(RNGx->SR, ~RNG_SR_CEIS); +} + +/** + * @brief Clear Seed Error interrupt Status (SEIS) Flag + * @rmtoll SR SEIS LL_RNG_ClearFlag_SEIS + * @param RNGx RNG Instance + * @retval None + */ +__STATIC_INLINE void LL_RNG_ClearFlag_SEIS(RNG_TypeDef *RNGx) +{ + WRITE_REG(RNGx->SR, ~RNG_SR_SEIS); +} + +/** + * @} + */ + +/** @defgroup RNG_LL_EF_IT_Management IT Management + * @{ + */ + +/** + * @brief Enable Random Number Generator Interrupt + * (applies for either Seed error, Clock Error or Data ready interrupts) + * @rmtoll CR IE LL_RNG_EnableIT + * @param RNGx RNG Instance + * @retval None + */ +__STATIC_INLINE void LL_RNG_EnableIT(RNG_TypeDef *RNGx) +{ + SET_BIT(RNGx->CR, RNG_CR_IE); +} + +/** + * @brief Disable Random Number Generator Interrupt + * (applies for either Seed error, Clock Error or Data ready interrupts) + * @rmtoll CR IE LL_RNG_DisableIT + * @param RNGx RNG Instance + * @retval None + */ +__STATIC_INLINE void LL_RNG_DisableIT(RNG_TypeDef *RNGx) +{ + CLEAR_BIT(RNGx->CR, RNG_CR_IE); +} + +/** + * @brief Check if Random Number Generator Interrupt is enabled + * (applies for either Seed error, Clock Error or Data ready interrupts) + * @rmtoll CR IE LL_RNG_IsEnabledIT + * @param RNGx RNG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RNG_IsEnabledIT(const RNG_TypeDef *RNGx) +{ + return ((READ_BIT(RNGx->CR, RNG_CR_IE) == (RNG_CR_IE)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup RNG_LL_EF_Data_Management Data Management + * @{ + */ + +/** + * @brief Return32-bit Random Number value + * @rmtoll DR RNDATA LL_RNG_ReadRandData32 + * @param RNGx RNG Instance + * @retval Generated 32-bit random value + */ +__STATIC_INLINE uint32_t LL_RNG_ReadRandData32(const RNG_TypeDef *RNGx) +{ + return (uint32_t)(READ_REG(RNGx->DR)); +} + +/** + * @} + */ + +/** + * @brief Enable Auto reset + * @rmtoll CR ARDIS LL_RNG_EnableArdis + * @param RNGx RNG Instance + * @retval None + */ +__STATIC_INLINE void LL_RNG_EnableArdis(RNG_TypeDef *RNGx) +{ + MODIFY_REG(RNGx->CR, RNG_CR_ARDIS | RNG_CR_CONDRST, LL_RNG_ARDIS_ENABLE | RNG_CR_CONDRST); + CLEAR_BIT(RNGx->CR, RNG_CR_CONDRST); +} + +/** + * @brief Disable Auto reset + * @rmtoll CR ARDIS LL_RNG_DisableArdis + * @param RNGx RNG Instance + * @retval None + */ +__STATIC_INLINE void LL_RNG_DisableArdis(RNG_TypeDef *RNGx) +{ + MODIFY_REG(RNGx->CR, RNG_CR_ARDIS | RNG_CR_CONDRST, LL_RNG_ARDIS_DISABLE | RNG_CR_CONDRST); + CLEAR_BIT(RNGx->CR, RNG_CR_CONDRST); +} + +/** + * @brief Check if RNG Auto reset is enabled + * @rmtoll CR ARDIS LL_RNG_IsEnabledArdis + * @param RNGx RNG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RNG_IsEnabledArdis(const RNG_TypeDef *RNGx) +{ + return ((READ_BIT(RNGx->CR, RNG_CR_ARDIS) != (RNG_CR_ARDIS)) ? 1UL : 0UL); +} + +/** @defgroup RNG_LL_EF_Health_Test_Control Health Test Control + * @{ + */ + +/** + * @brief Set RNG Health Test Control + * @rmtoll HTCR HTCFG LL_RNG_SetHealthConfig + * @param RNGx RNG Instance + * @param HTCFG can be values of 32 bits + * @retval None + */ +__STATIC_INLINE void LL_RNG_SetHealthConfig(RNG_TypeDef *RNGx, uint32_t HTCFG) +{ + WRITE_REG(RNGx->HTCR, HTCFG); +} + +/** + * @brief Get RNG Health Test Control + * @rmtoll HTCR HTCFG LL_RNG_GetHealthConfig + * @param RNGx RNG Instance + * @retval Return 32-bit RNG Health Test configuration + */ +__STATIC_INLINE uint32_t LL_RNG_GetHealthConfig(const RNG_TypeDef *RNGx) +{ + return (uint32_t)READ_REG(RNGx->HTCR); +} + +/** + * @} + */ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup RNG_LL_EF_Init Initialization and de-initialization functions + * @{ + */ +ErrorStatus LL_RNG_Init(RNG_TypeDef *RNGx, LL_RNG_InitTypeDef *RNG_InitStruct); +void LL_RNG_StructInit(LL_RNG_InitTypeDef *RNG_InitStruct); +ErrorStatus LL_RNG_DeInit(const RNG_TypeDef *RNGx); + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* RNG */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32H5xx_LL_RNG_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_rtc.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_rtc.h new file mode 100644 index 0000000000..8cdacb980b --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_rtc.h @@ -0,0 +1,6462 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_rtc.h + * @author MCD Application Team + * @brief Header file of RTC LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_LL_RTC_H +#define STM32H5xx_LL_RTC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined(RTC) + +/** @defgroup RTC_LL RTC + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup RTC_LL_Private_Constants RTC Private Constants + * @{ + */ +/* Masks Definition */ +#define RTC_LL_INIT_MASK 0xFFFFFFFFU +#define RTC_LL_RSF_MASK 0xFFFFFF5FU + +/* Write protection defines */ +#define RTC_WRITE_PROTECTION_DISABLE (uint8_t)0xFF +#define RTC_WRITE_PROTECTION_ENABLE_1 (uint8_t)0xCA +#define RTC_WRITE_PROTECTION_ENABLE_2 (uint8_t)0x53 + +/* Defines used to combine date & time */ +#define RTC_OFFSET_WEEKDAY 24U +#define RTC_OFFSET_DAY 16U +#define RTC_OFFSET_MONTH 8U +#define RTC_OFFSET_HOUR 16U +#define RTC_OFFSET_MINUTE 8U + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup RTC_LL_Private_Macros RTC Private Macros + * @{ + */ +/** + * @} + */ +#endif /*USE_FULL_LL_DRIVER*/ + +#if !defined (UNUSED) +#define UNUSED(x) ((void)(x)) +#endif /* !defined (UNUSED) */ + +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup RTC_LL_ES_INIT RTC Exported Init structure + * @{ + */ + +/** + * @brief RTC Init structures definition + */ +typedef struct +{ + uint32_t HourFormat; /*!< Specifies the RTC Hours Format. + This parameter can be a value of @ref RTC_LL_EC_HOURFORMAT + + This feature can be modified afterwards using unitary function + @ref LL_RTC_SetHourFormat(). */ + + uint32_t AsynchPrescaler; /*!< Specifies the RTC Asynchronous Predivider value. + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0x7F + + This feature can be modified afterwards using unitary function + @ref LL_RTC_SetAsynchPrescaler(). */ + + uint32_t SynchPrescaler; /*!< Specifies the RTC Synchronous Predivider value. + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0x7FFF + + This feature can be modified afterwards using unitary function + @ref LL_RTC_SetSynchPrescaler(). */ +} LL_RTC_InitTypeDef; + +/** + * @brief RTC Time structure definition + */ +typedef struct +{ + uint32_t TimeFormat; /*!< Specifies the RTC AM/PM Time. + This parameter can be a value of @ref RTC_LL_EC_TIME_FORMAT + + This feature can be modified afterwards using unitary function + @ref LL_RTC_TIME_SetFormat(). */ + + uint8_t Hours; /*!< Specifies the RTC Time Hours. + This parameter must be a number between Min_Data = 0 and Max_Data = 12 + if the @ref LL_RTC_TIME_FORMAT_PM is selected. + + This parameter must be a number between Min_Data = 0 and Max_Data = 23 + if the @ref LL_RTC_TIME_FORMAT_AM_OR_24 is selected. + + This feature can be modified afterwards using unitary function + @ref LL_RTC_TIME_SetHour(). */ + + uint8_t Minutes; /*!< Specifies the RTC Time Minutes. + This parameter must be a number between Min_Data = 0 and Max_Data = 59 + + This feature can be modified afterwards using unitary function + @ref LL_RTC_TIME_SetMinute(). */ + + uint8_t Seconds; /*!< Specifies the RTC Time Seconds. + This parameter must be a number between Min_Data = 0 and Max_Data = 59 + + This feature can be modified afterwards using unitary function + @ref LL_RTC_TIME_SetSecond(). */ +} LL_RTC_TimeTypeDef; + +/** + * @brief RTC Date structure definition + */ +typedef struct +{ + uint8_t WeekDay; /*!< Specifies the RTC Date WeekDay. + This parameter can be a value of @ref RTC_LL_EC_WEEKDAY + + This feature can be modified afterwards using unitary function + @ref LL_RTC_DATE_SetWeekDay(). */ + + uint8_t Month; /*!< Specifies the RTC Date Month. + This parameter can be a value of @ref RTC_LL_EC_MONTH + + This feature can be modified afterwards using unitary function + @ref LL_RTC_DATE_SetMonth(). */ + + uint8_t Day; /*!< Specifies the RTC Date Day. + This parameter must be a number between Min_Data = 1 and Max_Data = 31 + + This feature can be modified afterwards using unitary function + @ref LL_RTC_DATE_SetDay(). */ + + uint8_t Year; /*!< Specifies the RTC Date Year. + This parameter must be a number between Min_Data = 0 and Max_Data = 99 + + This feature can be modified afterwards using unitary function + @ref LL_RTC_DATE_SetYear(). */ +} LL_RTC_DateTypeDef; + +/** + * @brief RTC Alarm structure definition + */ +typedef struct +{ + LL_RTC_TimeTypeDef AlarmTime; /*!< Specifies the RTC Alarm Time members. */ + + uint32_t AlarmMask; /*!< Specifies the RTC Alarm Masks. + This parameter can be a value of @ref RTC_LL_EC_ALMA_MASK for ALARM A or + @ref RTC_LL_EC_ALMB_MASK for ALARM B. + + This feature can be modified afterwards using unitary function + @ref LL_RTC_ALMA_SetMask() for ALARM A or @ref LL_RTC_ALMB_SetMask() for ALARM B. + */ + + uint32_t AlarmDateWeekDaySel; /*!< Specifies the RTC Alarm is on day or WeekDay. + This parameter can be a value of @ref RTC_LL_EC_ALMA_WEEKDAY_SELECTION + for ALARM A or @ref RTC_LL_EC_ALMB_WEEKDAY_SELECTION for ALARM B. + + This feature can be modified afterwards using unitary function + @ref LL_RTC_ALMA_EnableWeekday() or @ref LL_RTC_ALMA_DisableWeekday() for ALARM A + or @ref LL_RTC_ALMB_EnableWeekday() or @ref LL_RTC_ALMB_DisableWeekday() + for ALARM B. + */ + + uint8_t AlarmDateWeekDay; /*!< Specifies the RTC Alarm Day/WeekDay. + If AlarmDateWeekDaySel set to day, this parameter must be a number + between Min_Data = 1 and Max_Data = 31. + + This feature can be modified afterwards using unitary function + @ref LL_RTC_ALMA_SetDay() for ALARM A or @ref LL_RTC_ALMB_SetDay() for ALARM B. + + If AlarmDateWeekDaySel set to Weekday, this parameter can be a value of + @ref RTC_LL_EC_WEEKDAY. + + This feature can be modified afterwards using unitary function + @ref LL_RTC_ALMA_SetWeekDay() for ALARM A or + @ref LL_RTC_ALMB_SetWeekDay() for ALARM B. + */ +} LL_RTC_AlarmTypeDef; + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup RTC_LL_Exported_Constants RTC Exported Constants + * @{ + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup RTC_LL_EC_FORMAT FORMAT + * @{ + */ +#define LL_RTC_FORMAT_BIN 0U /*!< Binary data format */ +#define LL_RTC_FORMAT_BCD 1U /*!< BCD data format */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_ALMA_WEEKDAY_SELECTION RTC Alarm A Date WeekDay + * @{ + */ +#define LL_RTC_ALMA_DATEWEEKDAYSEL_DATE 0U /*!< Alarm A Date is selected */ +#define LL_RTC_ALMA_DATEWEEKDAYSEL_WEEKDAY RTC_ALRMAR_WDSEL /*!< Alarm A WeekDay is selected */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_ALMB_WEEKDAY_SELECTION RTC Alarm B Date WeekDay + * @{ + */ +#define LL_RTC_ALMB_DATEWEEKDAYSEL_DATE 0U /*!< Alarm B Date is selected */ +#define LL_RTC_ALMB_DATEWEEKDAYSEL_WEEKDAY RTC_ALRMBR_WDSEL /*!< Alarm B WeekDay is selected */ +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ + +/** @defgroup RTC_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_RTC_ReadReg function + * @{ + */ +#define LL_RTC_SCR_SSRUF RTC_SCR_CSSRUF +#define LL_RTC_SCR_ITSF RTC_SCR_CITSF +#define LL_RTC_SCR_TSOVF RTC_SCR_CTSOVF +#define LL_RTC_SCR_TSF RTC_SCR_CTSF +#define LL_RTC_SCR_WUTF RTC_SCR_CWUTF +#define LL_RTC_SCR_ALRBF RTC_SCR_CALRBF +#define LL_RTC_SCR_ALRAF RTC_SCR_CALRAF + +#define LL_RTC_ICSR_RECALPF RTC_ICSR_RECALPF +#define LL_RTC_ICSR_BCDU_2 RTC_ICSR_BCDU_2 +#define LL_RTC_ICSR_BCDU_1 RTC_ICSR_BCDU_1 +#define LL_RTC_ICSR_BCDU_0 RTC_ICSR_BCDU_0 +#define LL_RTC_ICSR_BIN_1 RTC_ICSR_BIN_1 +#define LL_RTC_ICSR_BIN_0 RTC_ICSR_BIN_0 +#define LL_RTC_ICSR_INITF RTC_ICSR_INITF +#define LL_RTC_ICSR_RSF RTC_ICSR_RSF +#define LL_RTC_ICSR_INITS RTC_ICSR_INITS +#define LL_RTC_ICSR_SHPF RTC_ICSR_SHPF +#define LL_RTC_ICSR_WUTWF RTC_ICSR_WUTWF +/** + * @} + */ + +/** @defgroup RTC_LL_EC_IT IT Defines + * @brief IT defines which can be used with LL_RTC_ReadReg and LL_RTC_WriteReg functions + * @{ + */ +#define LL_RTC_CR_TSIE RTC_CR_TSIE +#define LL_RTC_CR_WUTIE RTC_CR_WUTIE +#define LL_RTC_CR_ALRBIE RTC_CR_ALRBIE +#define LL_RTC_CR_ALRAIE RTC_CR_ALRAIE +/** + * @} + */ + +/** @defgroup RTC_LL_EC_WEEKDAY WEEK DAY + * @{ + */ +#define LL_RTC_WEEKDAY_MONDAY (uint8_t)0x01 /*!< Monday */ +#define LL_RTC_WEEKDAY_TUESDAY (uint8_t)0x02 /*!< Tuesday */ +#define LL_RTC_WEEKDAY_WEDNESDAY (uint8_t)0x03 /*!< Wednesday */ +#define LL_RTC_WEEKDAY_THURSDAY (uint8_t)0x04 /*!< Thrusday */ +#define LL_RTC_WEEKDAY_FRIDAY (uint8_t)0x05 /*!< Friday */ +#define LL_RTC_WEEKDAY_SATURDAY (uint8_t)0x06 /*!< Saturday */ +#define LL_RTC_WEEKDAY_SUNDAY (uint8_t)0x07 /*!< Sunday */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_MONTH MONTH + * @{ + */ +#define LL_RTC_MONTH_JANUARY (uint8_t)0x01 /*!< January */ +#define LL_RTC_MONTH_FEBRUARY (uint8_t)0x02 /*!< February */ +#define LL_RTC_MONTH_MARCH (uint8_t)0x03 /*!< March */ +#define LL_RTC_MONTH_APRIL (uint8_t)0x04 /*!< April */ +#define LL_RTC_MONTH_MAY (uint8_t)0x05 /*!< May */ +#define LL_RTC_MONTH_JUNE (uint8_t)0x06 /*!< June */ +#define LL_RTC_MONTH_JULY (uint8_t)0x07 /*!< July */ +#define LL_RTC_MONTH_AUGUST (uint8_t)0x08 /*!< August */ +#define LL_RTC_MONTH_SEPTEMBER (uint8_t)0x09 /*!< September */ +#define LL_RTC_MONTH_OCTOBER (uint8_t)0x10 /*!< October */ +#define LL_RTC_MONTH_NOVEMBER (uint8_t)0x11 /*!< November */ +#define LL_RTC_MONTH_DECEMBER (uint8_t)0x12 /*!< December */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_HOURFORMAT HOUR FORMAT + * @{ + */ +#define LL_RTC_HOURFORMAT_24HOUR 0U /*!< 24 hour/day format */ +#define LL_RTC_HOURFORMAT_AMPM RTC_CR_FMT /*!< AM/PM hour format */ +/** + * @} + */ + +#if defined(RTC_CR_OSEL) +/** @defgroup RTC_LL_EC_ALARMOUT ALARM OUTPUT + * @{ + */ +#define LL_RTC_ALARMOUT_DISABLE 0U /*!< Output disabled */ +#define LL_RTC_ALARMOUT_ALMA RTC_CR_OSEL_0 /*!< Alarm A output enabled */ +#define LL_RTC_ALARMOUT_ALMB RTC_CR_OSEL_1 /*!< Alarm B output enabled */ +#define LL_RTC_ALARMOUT_WAKEUP RTC_CR_OSEL /*!< Wakeup output enabled */ +/** + * @} + */ +#endif /* RTC_CR_OSEL */ + +/** @defgroup RTC_LL_EC_ALARM_OUTPUTTYPE ALARM OUTPUT TYPE + * @{ + */ +#define LL_RTC_ALARM_OUTPUTTYPE_PUSHPULL 0U /*!< RTC_ALARM is push-pull output */ +#define LL_RTC_ALARM_OUTPUTTYPE_OPENDRAIN RTC_CR_TAMPALRM_TYPE /*!< RTC_ALARM is open-drain output */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_OUTPUTPOLARITY_PIN OUTPUT POLARITY PIN + * @{ + */ +#define LL_RTC_OUTPUTPOLARITY_PIN_HIGH 0U /*!< Pin is high when ALRAF/ALRBF/WUTF is asserted (depending on OSEL) */ +#define LL_RTC_OUTPUTPOLARITY_PIN_LOW RTC_CR_POL /*!< Pin is low when ALRAF/ALRBF/WUTF is asserted (depending on OSEL) */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_TIME_FORMAT TIME FORMAT + * @{ + */ +#define LL_RTC_TIME_FORMAT_AM_OR_24 0U /*!< AM or 24-hour format */ +#define LL_RTC_TIME_FORMAT_PM RTC_TR_PM /*!< PM */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_SHIFT_SECOND SHIFT SECOND + * @{ + */ +#define LL_RTC_SHIFT_SECOND_DELAY 0U /*!< Delay (seconds) = SUBFS / (PREDIV_S + 1) */ +#define LL_RTC_SHIFT_SECOND_ADVANCE RTC_SHIFTR_ADD1S /*!< Advance (seconds) = (1 - (SUBFS / (PREDIV_S + 1))) */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_ALMA_MASK ALARMA MASK + * @{ + */ +#define LL_RTC_ALMA_MASK_NONE 0U /*!< No masks applied on Alarm A */ +#define LL_RTC_ALMA_MASK_DATEWEEKDAY RTC_ALRMAR_MSK4 /*!< Date/day do not care in Alarm A comparison */ +#define LL_RTC_ALMA_MASK_HOURS RTC_ALRMAR_MSK3 /*!< Hours do not care in Alarm A comparison */ +#define LL_RTC_ALMA_MASK_MINUTES RTC_ALRMAR_MSK2 /*!< Minutes do not care in Alarm A comparison */ +#define LL_RTC_ALMA_MASK_SECONDS RTC_ALRMAR_MSK1 /*!< Seconds do not care in Alarm A comparison */ +#define LL_RTC_ALMA_MASK_ALL (RTC_ALRMAR_MSK4 | RTC_ALRMAR_MSK3 | RTC_ALRMAR_MSK2 | RTC_ALRMAR_MSK1) /*!< Masks all */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_ALMA_TIME_FORMAT ALARMA TIME FORMAT + * @{ + */ +#define LL_RTC_ALMA_TIME_FORMAT_AM 0U /*!< AM or 24-hour format */ +#define LL_RTC_ALMA_TIME_FORMAT_PM RTC_ALRMAR_PM /*!< PM */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_ALMA_SUBSECONDBIN_AUTOCLR RTC Alarm Sub Seconds with binary mode auto clear Definitions + * @{ + */ +#define LL_RTC_ALMA_SUBSECONDBIN_AUTOCLR_NO 0UL +/*!< The synchronous binary counter (SS[31:0] in RTC_SSR) is free-running. */ + +#define LL_RTC_ALMA_SUBSECONDBIN_AUTOCLR_YES RTC_ALRMASSR_SSCLR +/*!< The synchronous binary counter (SS[31:0] in RTC_SSR) is running from 0xFFFF FFFF to RTC_ALRMABINR -> SS[31:0] + value and is automatically reloaded with 0xFFFF FFFF when reaching RTC_ALRMABINR -> SS[31:0]. */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_ALMB_MASK ALARMB MASK + * @{ + */ +#define LL_RTC_ALMB_MASK_NONE 0U /*!< No masks applied on Alarm B */ +#define LL_RTC_ALMB_MASK_DATEWEEKDAY RTC_ALRMBR_MSK4 /*!< Date/day do not care in Alarm B comparison */ +#define LL_RTC_ALMB_MASK_HOURS RTC_ALRMBR_MSK3 /*!< Hours do not care in Alarm B comparison */ +#define LL_RTC_ALMB_MASK_MINUTES RTC_ALRMBR_MSK2 /*!< Minutes do not care in Alarm B comparison */ +#define LL_RTC_ALMB_MASK_SECONDS RTC_ALRMBR_MSK1 /*!< Seconds do not care in Alarm B comparison */ +#define LL_RTC_ALMB_MASK_ALL (RTC_ALRMBR_MSK4 | RTC_ALRMBR_MSK3 | RTC_ALRMBR_MSK2 | RTC_ALRMBR_MSK1) /*!< Masks all */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_ALMB_TIME_FORMAT ALARMB TIME FORMAT + * @{ + */ +#define LL_RTC_ALMB_TIME_FORMAT_AM 0U /*!< AM or 24-hour format */ +#define LL_RTC_ALMB_TIME_FORMAT_PM RTC_ALRMBR_PM /*!< PM */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_ALMB_SUBSECONDBIN_AUTOCLR Alarm Sub Seconds with binary mode auto clear Definitions + * @{ + */ +#define LL_RTC_ALMB_SUBSECONDBIN_AUTOCLR_NO 0UL +/*!< The synchronous binary counter (SS[31:0] in RTC_SSR) is free-running. */ + +#define LL_RTC_ALMB_SUBSECONDBIN_AUTOCLR_YES RTC_ALRMBSSR_SSCLR +/*!< The synchronous binary counter (SS[31:0] in RTC_SSR) is running from 0xFFFF FFFF to RTC_ALRMBBINR -> SS[31:0] + value and is automatically reloaded with 0xFFFF FFFF when reaching RTC_ALRMBBINR -> SS[31:0]. */ +/** + * @} + */ + +#if defined(RTC_CR_TSEDGE) +/** @defgroup RTC_LL_EC_TIMESTAMP_EDGE TIMESTAMP EDGE + * @{ + */ +#define LL_RTC_TIMESTAMP_EDGE_RISING 0U /*!< RTC_TS input rising edge generates a time-stamp event */ +#define LL_RTC_TIMESTAMP_EDGE_FALLING RTC_CR_TSEDGE /*!< RTC_TS input falling edge generates a time-stamp even */ +/** + * @} + */ +#endif /* RTC_CR_TSEDGE */ + +/** @defgroup RTC_LL_EC_TS_TIME_FORMAT TIMESTAMP TIME FORMAT + * @{ + */ +#define LL_RTC_TS_TIME_FORMAT_AM 0U /*!< AM or 24-hour format */ +#define LL_RTC_TS_TIME_FORMAT_PM RTC_TSTR_PM /*!< PM */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_TAMPER TAMPER + * @{ + */ +#define LL_RTC_TAMPER_1 TAMP_CR1_TAMP1E /*!< Tamper 1 input detection */ +#define LL_RTC_TAMPER_2 TAMP_CR1_TAMP2E /*!< Tamper 2 input detection */ +#if (RTC_TAMP_NB == 3U) +#define LL_RTC_TAMPER_3 TAMP_CR1_TAMP3E /*!< Tamper 3 input detection */ +#elif (RTC_TAMP_NB == 8U) +#define LL_RTC_TAMPER_3 TAMP_CR1_TAMP3E /*!< Tamper 3 input detection */ +#define LL_RTC_TAMPER_4 TAMP_CR1_TAMP4E /*!< Tamper 4 input detection */ +#define LL_RTC_TAMPER_5 TAMP_CR1_TAMP5E /*!< Tamper 5 input detection */ +#define LL_RTC_TAMPER_6 TAMP_CR1_TAMP6E /*!< Tamper 6 input detection */ +#define LL_RTC_TAMPER_7 TAMP_CR1_TAMP7E /*!< Tamper 7 input detection */ +#define LL_RTC_TAMPER_8 TAMP_CR1_TAMP8E /*!< Tamper 8 input detection */ +#endif /* RTC_TAMP_NB */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_TAMPER_MASK TAMPER MASK + * @{ + */ +#define LL_RTC_TAMPER_MASK_TAMPER1 TAMP_CR2_TAMP1MSK /*!< Tamper 1 event generates a trigger event. TAMP1F is masked and internally cleared by hardware. The backup registers are not erased */ +#define LL_RTC_TAMPER_MASK_TAMPER2 TAMP_CR2_TAMP2MSK /*!< Tamper 2 event generates a trigger event. TAMP2F is masked and internally cleared by hardware. The backup registers are not erased */ +#if (RTC_TAMP_NB > 2U) +#define LL_RTC_TAMPER_MASK_TAMPER3 TAMP_CR2_TAMP3MSK /*!< Tamper 3 event generates a trigger event. TAMP3F is masked and internally cleared by hardware. The backup registers are not erased */ +#endif /* (RTC_TAMP_NB > 2U) */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_TAMPER_NOERASE TAMPER NO ERASE + * @{ + */ +#define LL_RTC_TAMPER_NOERASE_TAMPER1 TAMP_CR2_TAMP1NOERASE /*!< Tamper 1 event does not erase the backup registers */ +#define LL_RTC_TAMPER_NOERASE_TAMPER2 TAMP_CR2_TAMP2NOERASE /*!< Tamper 2 event does not erase the backup registers */ +#if (RTC_TAMP_NB == 3U) +#define LL_RTC_TAMPER_NOERASE_TAMPER3 TAMP_CR2_TAMP3NOERASE /*!< Tamper 3 event does not erase the backup registers */ +#elif (RTC_TAMP_NB == 8U) +#define LL_RTC_TAMPER_NOERASE_TAMPER3 TAMP_CR2_TAMP3NOERASE /*!< Tamper 3 event does not erase the backup registers */ +#define LL_RTC_TAMPER_NOERASE_TAMPER4 TAMP_CR2_TAMP4NOERASE /*!< Tamper 4 event does not erase the backup registers */ +#define LL_RTC_TAMPER_NOERASE_TAMPER5 TAMP_CR2_TAMP5NOERASE /*!< Tamper 5 event does not erase the backup registers */ +#define LL_RTC_TAMPER_NOERASE_TAMPER6 TAMP_CR2_TAMP6NOERASE /*!< Tamper 6 event does not erase the backup registers */ +#define LL_RTC_TAMPER_NOERASE_TAMPER7 TAMP_CR2_TAMP7NOERASE /*!< Tamper 7 event does not erase the backup registers */ +#define LL_RTC_TAMPER_NOERASE_TAMPER8 TAMP_CR2_TAMP8NOERASE /*!< Tamper 8 event does not erase the backup registers */ +#endif /* RTC_TAMP_NB */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_TAMPER_DURATION TAMPER DURATION + * @{ + */ +#define LL_RTC_TAMPER_DURATION_1RTCCLK 0U /*!< Tamper pins are pre-charged before sampling during 1 RTCCLK cycle */ +#define LL_RTC_TAMPER_DURATION_2RTCCLK TAMP_FLTCR_TAMPPRCH_0 /*!< Tamper pins are pre-charged before sampling during 2 RTCCLK cycles */ +#define LL_RTC_TAMPER_DURATION_4RTCCLK TAMP_FLTCR_TAMPPRCH_1 /*!< Tamper pins are pre-charged before sampling during 4 RTCCLK cycles */ +#define LL_RTC_TAMPER_DURATION_8RTCCLK TAMP_FLTCR_TAMPPRCH /*!< Tamper pins are pre-charged before sampling during 8 RTCCLK cycles */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_TAMPER_FILTER TAMPER FILTER + * @{ + */ +#define LL_RTC_TAMPER_FILTER_DISABLE 0U /*!< Tamper filter is disabled */ +#define LL_RTC_TAMPER_FILTER_2SAMPLE TAMP_FLTCR_TAMPFLT_0 /*!< Tamper is activated after 2 consecutive samples at the active level */ +#define LL_RTC_TAMPER_FILTER_4SAMPLE TAMP_FLTCR_TAMPFLT_1 /*!< Tamper is activated after 4 consecutive samples at the active level */ +#define LL_RTC_TAMPER_FILTER_8SAMPLE TAMP_FLTCR_TAMPFLT /*!< Tamper is activated after 8 consecutive samples at the active level */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_TAMPER_SAMPLFREQDIV TAMPER SAMPLING FREQUENCY DIVIDER + * @{ + */ +#define LL_RTC_TAMPER_SAMPLFREQDIV_32768 0U /*!< Each of the tamper inputs are sampled with a frequency = RTCCLK / 32768 */ +#define LL_RTC_TAMPER_SAMPLFREQDIV_16384 TAMP_FLTCR_TAMPFREQ_0 /*!< Each of the tamper inputs are sampled with a frequency = RTCCLK / 16384 */ +#define LL_RTC_TAMPER_SAMPLFREQDIV_8192 TAMP_FLTCR_TAMPFREQ_1 /*!< Each of the tamper inputs are sampled with a frequency = RTCCLK / 8192 */ +#define LL_RTC_TAMPER_SAMPLFREQDIV_4096 (TAMP_FLTCR_TAMPFREQ_1 | TAMP_FLTCR_TAMPFREQ_0) /*!< Each of the tamper inputs are sampled with a frequency = RTCCLK / 4096 */ +#define LL_RTC_TAMPER_SAMPLFREQDIV_2048 TAMP_FLTCR_TAMPFREQ_2 /*!< Each of the tamper inputs are sampled with a frequency = RTCCLK / 2048 */ +#define LL_RTC_TAMPER_SAMPLFREQDIV_1024 (TAMP_FLTCR_TAMPFREQ_2 | TAMP_FLTCR_TAMPFREQ_0) /*!< Each of the tamper inputs are sampled with a frequency = RTCCLK / 1024 */ +#define LL_RTC_TAMPER_SAMPLFREQDIV_512 (TAMP_FLTCR_TAMPFREQ_2 | TAMP_FLTCR_TAMPFREQ_1) /*!< Each of the tamper inputs are sampled with a frequency = RTCCLK / 512 */ +#define LL_RTC_TAMPER_SAMPLFREQDIV_256 TAMP_FLTCR_TAMPFREQ /*!< Each of the tamper inputs are sampled with a frequency = RTCCLK / 256 */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_TAMPER_ACTIVELEVEL TAMPER ACTIVE LEVEL + * @{ + */ +#define LL_RTC_TAMPER_ACTIVELEVEL_TAMP1 TAMP_CR2_TAMP1TRG /*!< Tamper 1 input falling edge (if TAMPFLT = 00) or staying high (if TAMPFLT != 00) triggers a tamper detection event */ +#define LL_RTC_TAMPER_ACTIVELEVEL_TAMP2 TAMP_CR2_TAMP2TRG /*!< Tamper 2 input falling edge (if TAMPFLT = 00) or staying high (if TAMPFLT != 00) triggers a tamper detection event */ +#if (RTC_TAMP_NB == 3U) +#define LL_RTC_TAMPER_ACTIVELEVEL_TAMP3 TAMP_CR2_TAMP3TRG /*!< Tamper 3 input falling edge (if TAMPFLT = 00) or staying high (if TAMPFLT != 00) triggers a tamper detection event */ +#elif (RTC_TAMP_NB == 8U) +#define LL_RTC_TAMPER_ACTIVELEVEL_TAMP3 TAMP_CR2_TAMP3TRG /*!< Tamper 3 input falling edge (if TAMPFLT = 00) or staying high (if TAMPFLT != 00) triggers a tamper detection event */ +#define LL_RTC_TAMPER_ACTIVELEVEL_TAMP4 TAMP_CR2_TAMP4TRG /*!< Tamper 4 input falling edge (if TAMPFLT = 00) or staying high (if TAMPFLT != 00) triggers a tamper detection event */ +#define LL_RTC_TAMPER_ACTIVELEVEL_TAMP5 TAMP_CR2_TAMP5TRG /*!< Tamper 5 input falling edge (if TAMPFLT = 00) or staying high (if TAMPFLT != 00) triggers a tamper detection event */ +#define LL_RTC_TAMPER_ACTIVELEVEL_TAMP6 TAMP_CR2_TAMP6TRG /*!< Tamper 6 input falling edge (if TAMPFLT = 00) or staying high (if TAMPFLT != 00) triggers a tamper detection event */ +#define LL_RTC_TAMPER_ACTIVELEVEL_TAMP7 TAMP_CR2_TAMP7TRG /*!< Tamper 7 input falling edge (if TAMPFLT = 00) or staying high (if TAMPFLT != 00) triggers a tamper detection event */ +#define LL_RTC_TAMPER_ACTIVELEVEL_TAMP8 TAMP_CR2_TAMP8TRG /*!< Tamper 8 input falling edge (if TAMPFLT = 00) or staying high (if TAMPFLT != 00) triggers a tamper detection event */ +#endif /* RTC_TAMP_NB */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_INTERNAL INTERNAL TAMPER + * @{ + */ +#define LL_RTC_TAMPER_ITAMP1 TAMP_CR1_ITAMP1E /*!< Internal tamper 1: RTC supply voltage monitoring */ +#define LL_RTC_TAMPER_ITAMP2 TAMP_CR1_ITAMP2E /*!< Internal tamper 2: Temperature monitoring */ +#define LL_RTC_TAMPER_ITAMP3 TAMP_CR1_ITAMP3E /*!< Internal tamper 3: LSE monitoring */ +#define LL_RTC_TAMPER_ITAMP4 TAMP_CR1_ITAMP4E /*!< Internal tamper 4: HSE monitoring */ +#define LL_RTC_TAMPER_ITAMP5 TAMP_CR1_ITAMP5E /*!< Internal tamper 5: RTC calendar overflow */ +#define LL_RTC_TAMPER_ITAMP6 TAMP_CR1_ITAMP6E /*!< Internal tamper 6: JTAG/SWD access when RDP > 0 */ +#define LL_RTC_TAMPER_ITAMP7 TAMP_CR1_ITAMP7E /*!< Internal tamper 7: Voltage monitoring (VCORE, VREF+), through ADC analog watchdog */ +#define LL_RTC_TAMPER_ITAMP8 TAMP_CR1_ITAMP8E /*!< Internal tamper 8: Monotonic counter overflow */ +#define LL_RTC_TAMPER_ITAMP9 TAMP_CR1_ITAMP9E /*!< Internal tamper 9: Cryptographic IPs fault */ +#define LL_RTC_TAMPER_ITAMP11 TAMP_CR1_ITAMP11E /*!< Internal tamper 11: IWDG reset when tamper flag is set */ +#define LL_RTC_TAMPER_ITAMP12 TAMP_CR1_ITAMP12E /*!< Internal tamper 12: Voltage monitoring (VCORE, VREF+), through ADC analog watchdog */ +#define LL_RTC_TAMPER_ITAMP13 TAMP_CR1_ITAMP13E /*!< Internal tamper 13: Voltage monitoring (VCORE, VREF+), through ADC analog watchdog */ +#define LL_RTC_TAMPER_ITAMP15 TAMP_CR1_ITAMP15E /*!< Internal tamper 15: System fault detection */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_ITAMPER_NOERASE INTERNAL TAMPER NO ERASE + * @{ + */ +#define LL_RTC_TAMPER_NOERASE_ITAMPER1 TAMP_CR3_ITAMP1NOER /*!< Internal tamper 1 event does not erase the backup registers */ +#define LL_RTC_TAMPER_NOERASE_ITAMPER2 TAMP_CR3_ITAMP2NOER /*!< Internal tamper 2 event does not erase the backup registers */ +#define LL_RTC_TAMPER_NOERASE_ITAMPER3 TAMP_CR3_ITAMP3NOER /*!< Internal tamper 3 event does not erase the backup registers */ +#define LL_RTC_TAMPER_NOERASE_ITAMPER4 TAMP_CR3_ITAMP4NOER /*!< Internal tamper 4 event does not erase the backup registers */ +#define LL_RTC_TAMPER_NOERASE_ITAMPER5 TAMP_CR3_ITAMP5NOER /*!< Internal tamper 5 event does not erase the backup registers */ +#define LL_RTC_TAMPER_NOERASE_ITAMPER6 TAMP_CR3_ITAMP6NOER /*!< Internal tamper 6 event does not erase the backup registers */ +#define LL_RTC_TAMPER_NOERASE_ITAMPER7 TAMP_CR3_ITAMP7NOER /*!< Internal tamper 7 event does not erase the backup registers */ +#define LL_RTC_TAMPER_NOERASE_ITAMPER8 TAMP_CR3_ITAMP8NOER /*!< Internal tamper 8 event does not erase the backup registers */ +#define LL_RTC_TAMPER_NOERASE_ITAMPER9 TAMP_CR3_ITAMP9NOER /*!< Internal tamper 9 event does not erase the backup registers */ +#define LL_RTC_TAMPER_NOERASE_ITAMPER11 TAMP_CR3_ITAMP11NOER /*!< Internal tamper 10 event does not erase the backup registers */ +#define LL_RTC_TAMPER_NOERASE_ITAMPER12 TAMP_CR3_ITAMP12NOER /*!< Internal tamper 11 event does not erase the backup registers */ +#define LL_RTC_TAMPER_NOERASE_ITAMPER13 TAMP_CR3_ITAMP13NOER /*!< Internal tamper 12 event does not erase the backup registers */ +#define LL_RTC_TAMPER_NOERASE_ITAMPER15 TAMP_CR3_ITAMP15NOER /*!< Internal tamper 13 event does not erase the backup registers */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_ACTIVE_MODE ACTIVE TAMPER MODE + * @{ + */ +#define LL_RTC_TAMPER_ATAMP_TAMP1AM TAMP_ATCR1_TAMP1AM /*!< Tamper 1 is active */ +#define LL_RTC_TAMPER_ATAMP_TAMP2AM TAMP_ATCR1_TAMP2AM /*!< Tamper 2 is active */ +#if (RTC_TAMP_NB == 3U) +#define LL_RTC_TAMPER_ATAMP_TAMP3AM TAMP_ATCR1_TAMP3AM /*!< Tamper 3 is active */ +#elif (RTC_TAMP_NB == 8U) +#define LL_RTC_TAMPER_ATAMP_TAMP3AM TAMP_ATCR1_TAMP3AM /*!< Tamper 3 is active */ +#define LL_RTC_TAMPER_ATAMP_TAMP4AM TAMP_ATCR1_TAMP4AM /*!< Tamper 4 is active */ +#define LL_RTC_TAMPER_ATAMP_TAMP5AM TAMP_ATCR1_TAMP5AM /*!< Tamper 5 is active */ +#define LL_RTC_TAMPER_ATAMP_TAMP6AM TAMP_ATCR1_TAMP6AM /*!< Tamper 6 is active */ +#define LL_RTC_TAMPER_ATAMP_TAMP7AM TAMP_ATCR1_TAMP7AM /*!< Tamper 7 is active */ +#define LL_RTC_TAMPER_ATAMP_TAMP8AM TAMP_ATCR1_TAMP8AM /*!< Tamper 8 is active */ +#endif /* RTC_TAMP_NB */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_ACTIVE_ASYNC_PRESCALER ACTIVE TAMPER ASYNCHRONOUS PRESCALER CLOCK + * @{ + */ +#define LL_RTC_TAMPER_ATAMP_ASYNCPRES_RTCCLK 0U /*!< RTCCLK */ +#define LL_RTC_TAMPER_ATAMP_ASYNCPRES_RTCCLK_2 TAMP_ATCR1_ATCKSEL_0 /*!< RTCCLK/2 */ +#define LL_RTC_TAMPER_ATAMP_ASYNCPRES_RTCCLK_4 TAMP_ATCR1_ATCKSEL_1 /*!< RTCCLK/4 */ +#define LL_RTC_TAMPER_ATAMP_ASYNCPRES_RTCCLK_8 (TAMP_ATCR1_ATCKSEL_1 | TAMP_ATCR1_ATCKSEL_0) /*!< RTCCLK/8 */ +#define LL_RTC_TAMPER_ATAMP_ASYNCPRES_RTCCLK_16 TAMP_ATCR1_ATCKSEL_2 /*!< RTCCLK/16 */ +#define LL_RTC_TAMPER_ATAMP_ASYNCPRES_RTCCLK_32 (TAMP_ATCR1_ATCKSEL_2 | TAMP_ATCR1_ATCKSEL_0) /*!< RTCCLK/32 */ +#define LL_RTC_TAMPER_ATAMP_ASYNCPRES_RTCCLK_64 (TAMP_ATCR1_ATCKSEL_2 | TAMP_ATCR1_ATCKSEL_1) /*!< RTCCLK/64 */ +#define LL_RTC_TAMPER_ATAMP_ASYNCPRES_RTCCLK_128 (TAMP_ATCR1_ATCKSEL_2 | TAMP_ATCR1_ATCKSEL_1 | TAMP_ATCR1_ATCKSEL_0) /*!< RTCCLK/128 */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_ACTIVE_OUTPUT_SELECTION ACTIVE TAMPER OUTPUT SELECTION + * @{ + */ +#define LL_RTC_TAMPER_ATAMP1IN_ATAMP1OUT (0U << TAMP_ATCR2_ATOSEL1_Pos) +#define LL_RTC_TAMPER_ATAMP1IN_ATAMP2OUT (1U << TAMP_ATCR2_ATOSEL1_Pos) +#if (RTC_TAMP_NB == 3U) +#define LL_RTC_TAMPER_ATAMP1IN_ATAMP3OUT (2U << TAMP_ATCR2_ATOSEL1_Pos) +#elif (RTC_TAMP_NB == 8U) +#define LL_RTC_TAMPER_ATAMP1IN_ATAMP3OUT (2U << TAMP_ATCR2_ATOSEL1_Pos) +#define LL_RTC_TAMPER_ATAMP1IN_ATAMP4OUT (3U << TAMP_ATCR2_ATOSEL1_Pos) +#define LL_RTC_TAMPER_ATAMP1IN_ATAMP5OUT (4U << TAMP_ATCR2_ATOSEL1_Pos) +#define LL_RTC_TAMPER_ATAMP1IN_ATAMP6OUT (5U << TAMP_ATCR2_ATOSEL1_Pos) +#define LL_RTC_TAMPER_ATAMP1IN_ATAMP7OUT (6U << TAMP_ATCR2_ATOSEL1_Pos) +#define LL_RTC_TAMPER_ATAMP1IN_ATAMP8OUT (7U << TAMP_ATCR2_ATOSEL1_Pos) +#endif /* RTC_TAMP_NB */ + +#define LL_RTC_TAMPER_ATAMP2IN_ATAMP1OUT (0U << TAMP_ATCR2_ATOSEL2_Pos) +#define LL_RTC_TAMPER_ATAMP2IN_ATAMP2OUT (1U << TAMP_ATCR2_ATOSEL2_Pos) +#if (RTC_TAMP_NB == 3U) +#define LL_RTC_TAMPER_ATAMP2IN_ATAMP3OUT (2U << TAMP_ATCR2_ATOSEL2_Pos) +#elif (RTC_TAMP_NB == 8U) +#define LL_RTC_TAMPER_ATAMP2IN_ATAMP3OUT (2U << TAMP_ATCR2_ATOSEL2_Pos) +#define LL_RTC_TAMPER_ATAMP2IN_ATAMP4OUT (3U << TAMP_ATCR2_ATOSEL2_Pos) +#define LL_RTC_TAMPER_ATAMP2IN_ATAMP5OUT (4U << TAMP_ATCR2_ATOSEL2_Pos) +#define LL_RTC_TAMPER_ATAMP2IN_ATAMP6OUT (5U << TAMP_ATCR2_ATOSEL2_Pos) +#define LL_RTC_TAMPER_ATAMP2IN_ATAMP7OUT (6U << TAMP_ATCR2_ATOSEL2_Pos) +#define LL_RTC_TAMPER_ATAMP2IN_ATAMP8OUT (7U << TAMP_ATCR2_ATOSEL2_Pos) +#endif /* RTC_TAMP_NB */ + +#if (RTC_TAMP_NB == 3U) +#define LL_RTC_TAMPER_ATAMP3IN_ATAMP1OUT (0U << TAMP_ATCR2_ATOSEL3_Pos) +#define LL_RTC_TAMPER_ATAMP3IN_ATAMP2OUT (1U << TAMP_ATCR2_ATOSEL3_Pos) +#define LL_RTC_TAMPER_ATAMP3IN_ATAMP3OUT (2U << TAMP_ATCR2_ATOSEL3_Pos) +#elif (RTC_TAMP_NB == 8U) +#define LL_RTC_TAMPER_ATAMP3IN_ATAMP1OUT (0U << TAMP_ATCR2_ATOSEL3_Pos) +#define LL_RTC_TAMPER_ATAMP3IN_ATAMP2OUT (1U << TAMP_ATCR2_ATOSEL3_Pos) +#define LL_RTC_TAMPER_ATAMP3IN_ATAMP3OUT (2U << TAMP_ATCR2_ATOSEL3_Pos) +#define LL_RTC_TAMPER_ATAMP3IN_ATAMP4OUT (3U << TAMP_ATCR2_ATOSEL3_Pos) +#define LL_RTC_TAMPER_ATAMP3IN_ATAMP5OUT (4U << TAMP_ATCR2_ATOSEL3_Pos) +#define LL_RTC_TAMPER_ATAMP3IN_ATAMP6OUT (5U << TAMP_ATCR2_ATOSEL3_Pos) +#define LL_RTC_TAMPER_ATAMP3IN_ATAMP7OUT (6U << TAMP_ATCR2_ATOSEL3_Pos) +#define LL_RTC_TAMPER_ATAMP3IN_ATAMP8OUT (7U << TAMP_ATCR2_ATOSEL3_Pos) +#endif /* RTC_TAMP_NB */ + +#if (RTC_TAMP_NB == 8U) +#define LL_RTC_TAMPER_ATAMP4IN_ATAMP1OUT (0U << TAMP_ATCR2_ATOSEL4_Pos) +#define LL_RTC_TAMPER_ATAMP4IN_ATAMP2OUT (1U << TAMP_ATCR2_ATOSEL4_Pos) +#define LL_RTC_TAMPER_ATAMP4IN_ATAMP3OUT (2U << TAMP_ATCR2_ATOSEL4_Pos) +#define LL_RTC_TAMPER_ATAMP4IN_ATAMP4OUT (3U << TAMP_ATCR2_ATOSEL4_Pos) +#define LL_RTC_TAMPER_ATAMP4IN_ATAMP5OUT (4U << TAMP_ATCR2_ATOSEL4_Pos) +#define LL_RTC_TAMPER_ATAMP4IN_ATAMP6OUT (5U << TAMP_ATCR2_ATOSEL4_Pos) +#define LL_RTC_TAMPER_ATAMP4IN_ATAMP7OUT (6U << TAMP_ATCR2_ATOSEL4_Pos) +#define LL_RTC_TAMPER_ATAMP4IN_ATAMP8OUT (7U << TAMP_ATCR2_ATOSEL4_Pos) + +#define LL_RTC_TAMPER_ATAMP5IN_ATAMP1OUT (0U << TAMP_ATCR2_ATOSEL5_Pos) +#define LL_RTC_TAMPER_ATAMP5IN_ATAMP2OUT (1U << TAMP_ATCR2_ATOSEL5_Pos) +#define LL_RTC_TAMPER_ATAMP5IN_ATAMP3OUT (2U << TAMP_ATCR2_ATOSEL5_Pos) +#define LL_RTC_TAMPER_ATAMP5IN_ATAMP4OUT (3U << TAMP_ATCR2_ATOSEL5_Pos) +#define LL_RTC_TAMPER_ATAMP5IN_ATAMP5OUT (4U << TAMP_ATCR2_ATOSEL5_Pos) +#define LL_RTC_TAMPER_ATAMP5IN_ATAMP6OUT (5U << TAMP_ATCR2_ATOSEL5_Pos) +#define LL_RTC_TAMPER_ATAMP5IN_ATAMP7OUT (6U << TAMP_ATCR2_ATOSEL5_Pos) +#define LL_RTC_TAMPER_ATAMP5IN_ATAMP8OUT (7U << TAMP_ATCR2_ATOSEL5_Pos) + +#define LL_RTC_TAMPER_ATAMP6IN_ATAMP1OUT (0U << TAMP_ATCR2_ATOSEL6_Pos) +#define LL_RTC_TAMPER_ATAMP6IN_ATAMP2OUT (1U << TAMP_ATCR2_ATOSEL6_Pos) +#define LL_RTC_TAMPER_ATAMP6IN_ATAMP3OUT (2U << TAMP_ATCR2_ATOSEL6_Pos) +#define LL_RTC_TAMPER_ATAMP6IN_ATAMP4OUT (3U << TAMP_ATCR2_ATOSEL6_Pos) +#define LL_RTC_TAMPER_ATAMP6IN_ATAMP5OUT (4U << TAMP_ATCR2_ATOSEL6_Pos) +#define LL_RTC_TAMPER_ATAMP6IN_ATAMP6OUT (5U << TAMP_ATCR2_ATOSEL6_Pos) +#define LL_RTC_TAMPER_ATAMP6IN_ATAMP7OUT (6U << TAMP_ATCR2_ATOSEL6_Pos) +#define LL_RTC_TAMPER_ATAMP6IN_ATAMP8OUT (7U << TAMP_ATCR2_ATOSEL6_Pos) + +#define LL_RTC_TAMPER_ATAMP7IN_ATAMP1OUT (0U << TAMP_ATCR2_ATOSEL7_Pos) +#define LL_RTC_TAMPER_ATAMP7IN_ATAMP2OUT (1U << TAMP_ATCR2_ATOSEL7_Pos) +#define LL_RTC_TAMPER_ATAMP7IN_ATAMP3OUT (2U << TAMP_ATCR2_ATOSEL7_Pos) +#define LL_RTC_TAMPER_ATAMP7IN_ATAMP4OUT (3U << TAMP_ATCR2_ATOSEL7_Pos) +#define LL_RTC_TAMPER_ATAMP7IN_ATAMP5OUT (4U << TAMP_ATCR2_ATOSEL7_Pos) +#define LL_RTC_TAMPER_ATAMP7IN_ATAMP6OUT (5U << TAMP_ATCR2_ATOSEL7_Pos) +#define LL_RTC_TAMPER_ATAMP7IN_ATAMP7OUT (6U << TAMP_ATCR2_ATOSEL7_Pos) +#define LL_RTC_TAMPER_ATAMP7IN_ATAMP8OUT (7U << TAMP_ATCR2_ATOSEL7_Pos) + +#define LL_RTC_TAMPER_ATAMP8IN_ATAMP1OUT (0U << TAMP_ATCR2_ATOSEL8_Pos) +#define LL_RTC_TAMPER_ATAMP8IN_ATAMP2OUT (1U << TAMP_ATCR2_ATOSEL8_Pos) +#define LL_RTC_TAMPER_ATAMP8IN_ATAMP3OUT (2U << TAMP_ATCR2_ATOSEL8_Pos) +#define LL_RTC_TAMPER_ATAMP8IN_ATAMP4OUT (3U << TAMP_ATCR2_ATOSEL8_Pos) +#define LL_RTC_TAMPER_ATAMP8IN_ATAMP5OUT (4U << TAMP_ATCR2_ATOSEL8_Pos) +#define LL_RTC_TAMPER_ATAMP8IN_ATAMP6OUT (5U << TAMP_ATCR2_ATOSEL8_Pos) +#define LL_RTC_TAMPER_ATAMP8IN_ATAMP7OUT (6U << TAMP_ATCR2_ATOSEL8_Pos) +#define LL_RTC_TAMPER_ATAMP8IN_ATAMP8OUT (7U << TAMP_ATCR2_ATOSEL8_Pos) +#endif /* RTC_TAMP_NB */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_BKP BACKUP + * @{ + */ +#define LL_RTC_BKP_NUMBER RTC_BACKUP_NB +#define LL_RTC_BKP_DR0 0U +#define LL_RTC_BKP_DR1 1U +#define LL_RTC_BKP_DR2 2U +#define LL_RTC_BKP_DR3 3U +#define LL_RTC_BKP_DR4 4U +#define LL_RTC_BKP_DR5 5U +#define LL_RTC_BKP_DR6 6U +#define LL_RTC_BKP_DR7 7U +#define LL_RTC_BKP_DR8 8U +#define LL_RTC_BKP_DR9 9U +#define LL_RTC_BKP_DR10 10U +#define LL_RTC_BKP_DR11 11U +#define LL_RTC_BKP_DR12 12U +#define LL_RTC_BKP_DR13 13U +#define LL_RTC_BKP_DR14 14U +#define LL_RTC_BKP_DR15 15U +#define LL_RTC_BKP_DR16 16U +#define LL_RTC_BKP_DR17 17U +#define LL_RTC_BKP_DR18 18U +#define LL_RTC_BKP_DR19 19U +#define LL_RTC_BKP_DR20 20U +#define LL_RTC_BKP_DR21 21U +#define LL_RTC_BKP_DR22 22U +#define LL_RTC_BKP_DR23 23U +#define LL_RTC_BKP_DR24 24U +#define LL_RTC_BKP_DR25 25U +#define LL_RTC_BKP_DR26 26U +#define LL_RTC_BKP_DR27 27U +#define LL_RTC_BKP_DR28 28U +#define LL_RTC_BKP_DR29 29U +#define LL_RTC_BKP_DR30 30U +#define LL_RTC_BKP_DR31 31U +/** + * @} + */ + +/** @defgroup RTC_LL_EC_WAKEUPCLOCK_DIV WAKEUP CLOCK DIV + * @{ + */ +#define LL_RTC_WAKEUPCLOCK_DIV_16 0U /*!< RTC/16 clock is selected */ +#define LL_RTC_WAKEUPCLOCK_DIV_8 RTC_CR_WUCKSEL_0 /*!< RTC/8 clock is selected */ +#define LL_RTC_WAKEUPCLOCK_DIV_4 RTC_CR_WUCKSEL_1 /*!< RTC/4 clock is selected */ +#define LL_RTC_WAKEUPCLOCK_DIV_2 (RTC_CR_WUCKSEL_1 | RTC_CR_WUCKSEL_0) /*!< RTC/2 clock is selected */ +#define LL_RTC_WAKEUPCLOCK_CKSPRE RTC_CR_WUCKSEL_2 /*!< ck_spre (usually 1 Hz) clock is selected */ +#define LL_RTC_WAKEUPCLOCK_CKSPRE_WUT (RTC_CR_WUCKSEL_2 | RTC_CR_WUCKSEL_1) /*!< ck_spre (usually 1 Hz) clock is selected and 2exp16 is added to the WUT counter value */ +/** + * @} + */ + +#if defined(RTC_CR_COE) +/** @defgroup RTC_LL_EC_CALIB_OUTPUT Calibration output + * @{ + */ +#define LL_RTC_CALIB_OUTPUT_NONE 0U /*!< Calibration output disabled */ +#define LL_RTC_CALIB_OUTPUT_1HZ (RTC_CR_COE | RTC_CR_COSEL) /*!< Calibration output is 1 Hz */ +#define LL_RTC_CALIB_OUTPUT_512HZ RTC_CR_COE /*!< Calibration output is 512 Hz */ +/** + * @} + */ +#endif /* RTC_CR_COE */ + +/** @defgroup RTC_LL_EC_CALIB_INSERTPULSE Calibration pulse insertion + * @{ + */ +#define LL_RTC_CALIB_INSERTPULSE_NONE 0U /*!< No RTCCLK pulses are added */ +#define LL_RTC_CALIB_INSERTPULSE_SET RTC_CALR_CALP /*!< One RTCCLK pulse is effectively inserted every 2exp11 pulses (frequency increased by 488.5 ppm) */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_CALIB_PERIOD Calibration period + * @{ + */ +#define LL_RTC_CALIB_PERIOD_32SEC 0U /*!< Use a 32-second calibration cycle period */ +#define LL_RTC_CALIB_PERIOD_16SEC RTC_CALR_CALW16 /*!< Use a 16-second calibration cycle period */ +#define LL_RTC_CALIB_PERIOD_8SEC RTC_CALR_CALW8 /*!< Use a 8-second calibration cycle period */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_CALIB_LOWPOWER Calibration low power + * @{ + */ +#define LL_RTC_CALIB_LOWPOWER_NONE 0U /*!< High conso mode */ +#define LL_RTC_CALIB_LOWPOWER_SET RTC_CALR_LPCAL /*!< Low power mode */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_BINARY_MODE Binary mode (Sub Second Register) + * @{ + */ +#define LL_RTC_BINARY_NONE 0U /*!< Free running BCD calendar mode (Binary mode disabled) */ +#define LL_RTC_BINARY_ONLY RTC_ICSR_BIN_0 /*!< Free running Binary mode (BCD mode disabled) */ +#define LL_RTC_BINARY_MIX RTC_ICSR_BIN_1 /*!< Free running BCD calendar and Binary mode enable */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_BINARY_MIX_BCDU Calendar second incrementation in Binary mix mode + * @{ + */ +#define LL_RTC_BINARY_MIX_BCDU_0 0U /*!< 1s calendar increment is generated each time SS[7:0] = 0 */ +#define LL_RTC_BINARY_MIX_BCDU_1 (0x1UL << RTC_ICSR_BCDU_Pos) /*!< 1s calendar increment is generated each time SS[8:0] = 0 */ +#define LL_RTC_BINARY_MIX_BCDU_2 (0x2UL << RTC_ICSR_BCDU_Pos) /*!< 1s calendar increment is generated each time SS[9:0] = 0 */ +#define LL_RTC_BINARY_MIX_BCDU_3 (0x3UL << RTC_ICSR_BCDU_Pos) /*!< 1s calendar increment is generated each time SS[10:0] = 0 */ +#define LL_RTC_BINARY_MIX_BCDU_4 (0x4UL << RTC_ICSR_BCDU_Pos) /*!< 1s calendar increment is generated each time SS[11:0] = 0 */ +#define LL_RTC_BINARY_MIX_BCDU_5 (0x5UL << RTC_ICSR_BCDU_Pos) /*!< 1s calendar increment is generated each time SS[12:0] = 0 */ +#define LL_RTC_BINARY_MIX_BCDU_6 (0x6UL << RTC_ICSR_BCDU_Pos) /*!< 1s calendar increment is generated each time SS[13:0] = 0 */ +#define LL_RTC_BINARY_MIX_BCDU_7 (0x7UL << RTC_ICSR_BCDU_Pos) /*!< 1s calendar increment is generated each time SS[14:0] = 0 */ +/** + * @} + */ + +#if defined(RTC_SECCFGR_SEC) +/** @defgroup RTC_LL_EC_SECURE_RTC_FULL Secure full rtc + * @{ + */ +#define LL_RTC_SECURE_FULL_YES RTC_SECCFGR_SEC /*!< RTC full secure */ +#define LL_RTC_SECURE_FULL_NO 0U /*!< RTC is not full secure, features can be secure. See RTC_LL_EC_SECURE_RTC_FEATURE */ +/** + * @} + */ +#endif /* RTC_SECCFGR_SEC */ + +/** @defgroup RTC_LL_EC_SECURE_RTC_FEATURE Secure features rtc in case of LL_RTC_SECURE_FULL_NO. + * @{ + */ +#define LL_RTC_SECURE_FEATURE_INIT RTC_SECCFGR_INITSEC /*!< Initialization feature is secure */ +#define LL_RTC_SECURE_FEATURE_CAL RTC_SECCFGR_CALSEC /*!< Calibration feature is secure */ +#define LL_RTC_SECURE_FEATURE_TS RTC_SECCFGR_TSSEC /*!< Time stamp feature is secure */ +#define LL_RTC_SECURE_FEATURE_WUT RTC_SECCFGR_WUTSEC /*!< Wake up timer feature is secure */ +#define LL_RTC_SECURE_FEATURE_ALRA RTC_SECCFGR_ALRASEC /*!< Alarm A feature is secure */ +#define LL_RTC_SECURE_FEATURE_ALRB RTC_SECCFGR_ALRBSEC /*!< Alarm B feature is secure */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_SECURE_TAMP Secure tamp + * @{ + */ +#define LL_TAMP_SECURE_FULL_YES TAMP_SECCFGR_TAMPSEC /*!< TAMP full secure */ +#define LL_TAMP_SECURE_FULL_NO 0U /*!< TAMP is not secure */ +/** + * @} + */ + +#if defined(RTC_PRIVCFGR_PRIV) +/** @defgroup RTC_LL_EC_PRIVILEGE_RTC_FULL Privilege full rtc + * @{ + */ +#define LL_RTC_PRIVILEGE_FULL_YES RTC_PRIVCFGR_PRIV /*!< RTC full privilege */ +#define LL_RTC_PRIVILEGE_FULL_NO 0U /*!< RTC is not full privilege, features can be unprivilege. See RTC_LL_EC_PRIVILEGE_RTC_FEATURE */ +/** + * @} + */ +#endif /* RTC_PRIVCFGR_PRIV */ + +/** @defgroup RTC_LL_EC_PRIVILEGE_RTC_FEATURE Privilege rtc features in case of LL_RTC_PRIVILEGE_FULL_NO. + * @{ + */ +#define LL_RTC_PRIVILEGE_FEATURE_INIT RTC_PRIVCFGR_INITPRIV /*!< Initialization feature is privilege */ +#define LL_RTC_PRIVILEGE_FEATURE_CAL RTC_PRIVCFGR_CALPRIV /*!< Calibration feature is privilege */ +#define LL_RTC_PRIVILEGE_FEATURE_TS RTC_PRIVCFGR_TSPRIV /*!< Time stamp feature is privilege */ +#define LL_RTC_PRIVILEGE_FEATURE_WUT RTC_PRIVCFGR_WUTPRIV /*!< Wake up timer feature is privilege */ +#define LL_RTC_PRIVILEGE_FEATURE_ALRA RTC_PRIVCFGR_ALRAPRIV /*!< Alarm A feature is privilege */ +#define LL_RTC_PRIVILEGE_FEATURE_ALRB RTC_PRIVCFGR_ALRBPRIV /*!< Alarm B feature is privilege */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_PRIVILEGE_TAMP_FULL Privilege full tamp + * @{ + */ +#define LL_TAMP_PRIVILEGE_FULL_YES TAMP_PRIVCFGR_TAMPPRIV /*!< TAMP full privilege */ +#define LL_TAMP_PRIVILEGE_FULL_NO 0U /*!< TAMP is not privilege */ +/** + * @} + */ + +/** @defgroup RTC_LL_EC_PRIVILEGE_BACKUP_REG_ZONE Privilege Backup register privilege zone + * @{ + */ +#define LL_RTC_PRIVILEGE_BKUP_ZONE_NONE 0U +#define LL_RTC_PRIVILEGE_BKUP_ZONE_1 TAMP_PRIVCFGR_BKPRWPRIV +#define LL_RTC_PRIVILEGE_BKUP_ZONE_2 TAMP_PRIVCFGR_BKPWPRIV +#define LL_RTC_PRIVILEGE_BKUP_ZONE_ALL (LL_RTC_PRIVILEGE_BKUP_ZONE_1 | LL_RTC_PRIVILEGE_BKUP_ZONE_2) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup RTC_LL_Exported_Macros RTC Exported Macros + * @{ + */ + +/** @defgroup RTC_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in RTC register + * @param __INSTANCE__ RTC Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_RTC_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in RTC register + * @param __INSTANCE__ RTC Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_RTC_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) +/** + * @} + */ + +/** @defgroup RTC_LL_EM_Convert Convert helper Macros + * @{ + */ + +/** + * @brief Helper macro to convert a value from 2 digit decimal format to BCD format + * @param __VALUE__ Byte to be converted + * @retval Converted byte + */ +#define __LL_RTC_CONVERT_BIN2BCD(__VALUE__) ((uint8_t)((((__VALUE__) / 10U) << 4U) | ((__VALUE__) % 10U))) + +/** + * @brief Helper macro to convert a value from BCD format to 2 digit decimal format + * @param __VALUE__ BCD value to be converted + * @retval Converted byte + */ +#define __LL_RTC_CONVERT_BCD2BIN(__VALUE__) \ + ((uint8_t)((((uint8_t)((__VALUE__) & (uint8_t)0xF0U) >> (uint8_t)0x4U) * 10U) + ((__VALUE__) & (uint8_t)0x0FU))) + +/** + * @} + */ + +/** @defgroup RTC_LL_EM_Date Date helper Macros + * @{ + */ + +/** + * @brief Helper macro to retrieve weekday. + * @param __RTC_DATE__ Date returned by @ref LL_RTC_DATE_Get function. + * @retval Returned value can be one of the following values: + * @arg @ref LL_RTC_WEEKDAY_MONDAY + * @arg @ref LL_RTC_WEEKDAY_TUESDAY + * @arg @ref LL_RTC_WEEKDAY_WEDNESDAY + * @arg @ref LL_RTC_WEEKDAY_THURSDAY + * @arg @ref LL_RTC_WEEKDAY_FRIDAY + * @arg @ref LL_RTC_WEEKDAY_SATURDAY + * @arg @ref LL_RTC_WEEKDAY_SUNDAY + */ +#define __LL_RTC_GET_WEEKDAY(__RTC_DATE__) (((__RTC_DATE__) >> RTC_OFFSET_WEEKDAY) & 0x000000FFU) + +/** + * @brief Helper macro to retrieve Year in BCD format + * @param __RTC_DATE__ Value returned by @ref LL_RTC_DATE_Get + * @retval Year in BCD format (0x00 . . . 0x99) + */ +#define __LL_RTC_GET_YEAR(__RTC_DATE__) ((__RTC_DATE__) & 0x000000FFU) + +/** + * @brief Helper macro to retrieve Month in BCD format + * @param __RTC_DATE__ Value returned by @ref LL_RTC_DATE_Get + * @retval Returned value can be one of the following values: + * @arg @ref LL_RTC_MONTH_JANUARY + * @arg @ref LL_RTC_MONTH_FEBRUARY + * @arg @ref LL_RTC_MONTH_MARCH + * @arg @ref LL_RTC_MONTH_APRIL + * @arg @ref LL_RTC_MONTH_MAY + * @arg @ref LL_RTC_MONTH_JUNE + * @arg @ref LL_RTC_MONTH_JULY + * @arg @ref LL_RTC_MONTH_AUGUST + * @arg @ref LL_RTC_MONTH_SEPTEMBER + * @arg @ref LL_RTC_MONTH_OCTOBER + * @arg @ref LL_RTC_MONTH_NOVEMBER + * @arg @ref LL_RTC_MONTH_DECEMBER + */ +#define __LL_RTC_GET_MONTH(__RTC_DATE__) (((__RTC_DATE__) >>RTC_OFFSET_MONTH) & 0x000000FFU) + +/** + * @brief Helper macro to retrieve Day in BCD format + * @param __RTC_DATE__ Value returned by @ref LL_RTC_DATE_Get + * @retval Day in BCD format (0x01 . . . 0x31) + */ +#define __LL_RTC_GET_DAY(__RTC_DATE__) (((__RTC_DATE__) >>RTC_OFFSET_DAY) & 0x000000FFU) + +/** + * @} + */ + +/** @defgroup RTC_LL_EM_Time Time helper Macros + * @{ + */ + +/** + * @brief Helper macro to retrieve hour in BCD format + * @param __RTC_TIME__ RTC time returned by @ref LL_RTC_TIME_Get function + * @retval Hours in BCD format (0x01. . .0x12 or between Min_Data=0x00 and Max_Data=0x23) + */ +#define __LL_RTC_GET_HOUR(__RTC_TIME__) (((__RTC_TIME__) >> RTC_OFFSET_HOUR) & 0x000000FFU) + +/** + * @brief Helper macro to retrieve minute in BCD format + * @param __RTC_TIME__ RTC time returned by @ref LL_RTC_TIME_Get function + * @retval Minutes in BCD format (0x00. . .0x59) + */ +#define __LL_RTC_GET_MINUTE(__RTC_TIME__) (((__RTC_TIME__) >> RTC_OFFSET_MINUTE) & 0x000000FFU) + +/** + * @brief Helper macro to retrieve second in BCD format + * @param __RTC_TIME__ RTC time returned by @ref LL_RTC_TIME_Get function + * @retval Seconds in format (0x00. . .0x59) + */ +#define __LL_RTC_GET_SECOND(__RTC_TIME__) ((__RTC_TIME__) & 0x000000FFU) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup RTC_LL_Exported_Functions RTC Exported Functions + * @{ + */ + +/** @defgroup RTC_LL_EF_Configuration Configuration + * @{ + */ + +/** + * @brief Set Hours format (24 hour/day or AM/PM hour format) + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @note It can be written in initialization mode only (@ref LL_RTC_EnableInitMode function) + * @rmtoll RTC_CR FMT LL_RTC_SetHourFormat + * @param RTCx RTC Instance + * @param HourFormat This parameter can be one of the following values: + * @arg @ref LL_RTC_HOURFORMAT_24HOUR + * @arg @ref LL_RTC_HOURFORMAT_AMPM + * @retval None + */ +__STATIC_INLINE void LL_RTC_SetHourFormat(RTC_TypeDef *RTCx, uint32_t HourFormat) +{ + MODIFY_REG(RTCx->CR, RTC_CR_FMT, HourFormat); +} + +/** + * @brief Get Hours format (24 hour/day or AM/PM hour format) + * @rmtoll RTC_CR FMT LL_RTC_GetHourFormat + * @param RTCx RTC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_RTC_HOURFORMAT_24HOUR + * @arg @ref LL_RTC_HOURFORMAT_AMPM + */ +__STATIC_INLINE uint32_t LL_RTC_GetHourFormat(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->CR, RTC_CR_FMT)); +} + +#if defined(RTC_CR_OSEL) +/** + * @brief Select the flag to be routed to RTC_ALARM output + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR OSEL LL_RTC_SetAlarmOutEvent + * @param RTCx RTC Instance + * @param AlarmOutput This parameter can be one of the following values: + * @arg @ref LL_RTC_ALARMOUT_DISABLE + * @arg @ref LL_RTC_ALARMOUT_ALMA + * @arg @ref LL_RTC_ALARMOUT_ALMB + * @arg @ref LL_RTC_ALARMOUT_WAKEUP + * @retval None + */ +__STATIC_INLINE void LL_RTC_SetAlarmOutEvent(RTC_TypeDef *RTCx, uint32_t AlarmOutput) +{ + MODIFY_REG(RTCx->CR, RTC_CR_OSEL, AlarmOutput); +} + +/** + * @brief Get the flag to be routed to RTC_ALARM output + * @rmtoll RTC_CR OSEL LL_RTC_GetAlarmOutEvent + * @param RTCx RTC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_RTC_ALARMOUT_DISABLE + * @arg @ref LL_RTC_ALARMOUT_ALMA + * @arg @ref LL_RTC_ALARMOUT_ALMB + * @arg @ref LL_RTC_ALARMOUT_WAKEUP + */ +__STATIC_INLINE uint32_t LL_RTC_GetAlarmOutEvent(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->CR, RTC_CR_OSEL)); +} +#endif /* RTC_CR_OSEL */ + + +#ifdef RTC_CR_TAMPALRM_TYPE +/** + * @brief Set RTC_ALARM output type (ALARM in push-pull or open-drain output) + * @rmtoll RTC_CR TAMPALRM_TYPE LL_RTC_SetAlarmOutputType + * @param RTCx RTC Instance + * @param Output This parameter can be one of the following values: + * @arg @ref LL_RTC_ALARM_OUTPUTTYPE_OPENDRAIN + * @arg @ref LL_RTC_ALARM_OUTPUTTYPE_PUSHPULL + * @retval None + */ +__STATIC_INLINE void LL_RTC_SetAlarmOutputType(RTC_TypeDef *RTCx, uint32_t Output) +{ + MODIFY_REG(RTCx->CR, RTC_CR_TAMPALRM_TYPE, Output); +} + +/** + * @brief Get RTC_ALARM output type (ALARM in push-pull or open-drain output) + * @rmtoll RTC_CR TAMPALRM_TYPE LL_RTC_GetAlarmOutputType + * @param RTCx RTC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_RTC_ALARM_OUTPUTTYPE_OPENDRAIN + * @arg @ref LL_RTC_ALARM_OUTPUTTYPE_PUSHPULL + */ +__STATIC_INLINE uint32_t LL_RTC_GetAlarmOutputType(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->CR, RTC_CR_TAMPALRM_TYPE)); +} +#endif /* RTC_CR_TAMPALRM_TYPE */ + +/** + * @brief Enable initialization mode + * @note Initialization mode is used to program time and date register (RTC_TR and RTC_DR) + * and prescaler register (RTC_PRER). + * Counters are stopped and start counting from the new value when INIT is reset. + * @rmtoll RTC_ICSR INIT LL_RTC_EnableInitMode + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableInitMode(RTC_TypeDef *RTCx) +{ + /* Set the Initialization mode */ + SET_BIT(RTCx->ICSR, RTC_ICSR_INIT); +} + +/** + * @brief Disable initialization mode (Free running mode) + * @rmtoll RTC_ICSR INIT LL_RTC_DisableInitMode + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableInitMode(RTC_TypeDef *RTCx) +{ + /* Exit Initialization mode */ + CLEAR_BIT(RTCx->ICSR, RTC_ICSR_INIT); + +} + +/** + * @brief Set Binary mode (Sub Second Register) + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @note It can be written in initialization mode only (@ref LL_RTC_EnableInitMode function). + * @rmtoll RTC_ICSR BIN LL_RTC_SetBinaryMode + * @param RTCx RTC Instance + * @param BinaryMode can be one of the following values: + * @arg @ref LL_RTC_BINARY_NONE + * @arg @ref LL_RTC_BINARY_ONLY + * @arg @ref LL_RTC_BINARY_MIX + * @retval None + */ +__STATIC_INLINE void LL_RTC_SetBinaryMode(RTC_TypeDef *RTCx, uint32_t BinaryMode) +{ + MODIFY_REG(RTCx->ICSR, RTC_ICSR_BIN, BinaryMode); +} + +/** + * @brief Get Binary mode (Sub Second Register) + * @rmtoll RTC_ICSR BIN LL_RTC_GetBinaryMode + * @param RTCx RTC Instance + * @retval This parameter can be one of the following values: + * @arg @ref LL_RTC_BINARY_NONE + * @arg @ref LL_RTC_BINARY_ONLY + * @arg @ref LL_RTC_BINARY_MIX + * @retval None + */ +__STATIC_INLINE uint32_t LL_RTC_GetBinaryMode(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->ICSR, RTC_ICSR_BIN)); +} + +/** + * @brief Set Binary Mix mode BCDU + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @note It can be written in initialization mode only (@ref LL_RTC_EnableInitMode function). + * @rmtoll RTC_ICSR BCDU LL_RTC_SetBinMixBCDU + * @param RTCx RTC Instance + * @param BinMixBcdU can be one of the following values: + * @arg @ref LL_RTC_BINARY_MIX_BCDU_0 + * @arg @ref LL_RTC_BINARY_MIX_BCDU_1 + * @arg @ref LL_RTC_BINARY_MIX_BCDU_2 + * @arg @ref LL_RTC_BINARY_MIX_BCDU_3 + * @arg @ref LL_RTC_BINARY_MIX_BCDU_4 + * @arg @ref LL_RTC_BINARY_MIX_BCDU_5 + * @arg @ref LL_RTC_BINARY_MIX_BCDU_6 + * @arg @ref LL_RTC_BINARY_MIX_BCDU_7 + * @retval None + */ +__STATIC_INLINE void LL_RTC_SetBinMixBCDU(RTC_TypeDef *RTCx, uint32_t BinMixBcdU) +{ + MODIFY_REG(RTCx->ICSR, RTC_ICSR_BCDU, BinMixBcdU); +} + +/** + * @brief Get Binary Mix mode BCDU + * @rmtoll RTC_ICSR BCDU LL_RTC_GetBinMixBCDU + * @param RTCx RTC Instance + * @retval This parameter can be one of the following values: + * @arg @ref LL_RTC_BINARY_MIX_BCDU_0 + * @arg @ref LL_RTC_BINARY_MIX_BCDU_1 + * @arg @ref LL_RTC_BINARY_MIX_BCDU_2 + * @arg @ref LL_RTC_BINARY_MIX_BCDU_3 + * @arg @ref LL_RTC_BINARY_MIX_BCDU_4 + * @arg @ref LL_RTC_BINARY_MIX_BCDU_5 + * @arg @ref LL_RTC_BINARY_MIX_BCDU_6 + * @arg @ref LL_RTC_BINARY_MIX_BCDU_7 + * @retval None + */ +__STATIC_INLINE uint32_t LL_RTC_GetBinMixBCDU(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->ICSR, RTC_ICSR_BCDU)); +} + + +#ifdef RTC_CR_POL +/** + * @brief Set Output polarity (pin is low when ALRAF/ALRBF/WUTF is asserted) + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR POL LL_RTC_SetOutputPolarity + * @param RTCx RTC Instance + * @param Polarity This parameter can be one of the following values: + * @arg @ref LL_RTC_OUTPUTPOLARITY_PIN_HIGH + * @arg @ref LL_RTC_OUTPUTPOLARITY_PIN_LOW + * @retval None + */ +__STATIC_INLINE void LL_RTC_SetOutputPolarity(RTC_TypeDef *RTCx, uint32_t Polarity) +{ + MODIFY_REG(RTCx->CR, RTC_CR_POL, Polarity); +} + +/** + * @brief Get Output polarity + * @rmtoll RTC_CR POL LL_RTC_GetOutputPolarity + * @param RTCx RTC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_RTC_OUTPUTPOLARITY_PIN_HIGH + * @arg @ref LL_RTC_OUTPUTPOLARITY_PIN_LOW + */ +__STATIC_INLINE uint32_t LL_RTC_GetOutputPolarity(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->CR, RTC_CR_POL)); +} +#endif /* RTC_CR_POL */ + +/** + * @brief Enable Bypass the shadow registers + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR BYPSHAD LL_RTC_EnableShadowRegBypass + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableShadowRegBypass(RTC_TypeDef *RTCx) +{ + SET_BIT(RTCx->CR, RTC_CR_BYPSHAD); +} + +/** + * @brief Disable Bypass the shadow registers + * @rmtoll RTC_CR BYPSHAD LL_RTC_DisableShadowRegBypass + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableShadowRegBypass(RTC_TypeDef *RTCx) +{ + CLEAR_BIT(RTCx->CR, RTC_CR_BYPSHAD); +} + +/** + * @brief Check if Shadow registers bypass is enabled or not. + * @rmtoll RTC_CR BYPSHAD LL_RTC_IsShadowRegBypassEnabled + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsShadowRegBypassEnabled(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->CR, RTC_CR_BYPSHAD) == (RTC_CR_BYPSHAD)) ? 1U : 0U); +} + +#if defined(RTC_CR_REFCKON) +/** + * @brief Enable RTC_REFIN reference clock detection (50 or 60 Hz) + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @note It can be written in initialization mode only (@ref LL_RTC_EnableInitMode function) + * @rmtoll RTC_CR REFCKON LL_RTC_EnableRefClock + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableRefClock(RTC_TypeDef *RTCx) +{ + SET_BIT(RTCx->CR, RTC_CR_REFCKON); +} + +/** + * @brief Disable RTC_REFIN reference clock detection (50 or 60 Hz) + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @note It can be written in initialization mode only (@ref LL_RTC_EnableInitMode function) + * @rmtoll RTC_CR REFCKON LL_RTC_DisableRefClock + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableRefClock(RTC_TypeDef *RTCx) +{ + CLEAR_BIT(RTCx->CR, RTC_CR_REFCKON); +} +#endif /* RTC_CR_REFCKON */ + +/** + * @brief Set Asynchronous prescaler factor + * @rmtoll RTC_PRER PREDIV_A LL_RTC_SetAsynchPrescaler + * @param RTCx RTC Instance + * @param AsynchPrescaler Value between Min_Data = 0 and Max_Data = 0x7F + * @retval None + */ +__STATIC_INLINE void LL_RTC_SetAsynchPrescaler(RTC_TypeDef *RTCx, uint32_t AsynchPrescaler) +{ + MODIFY_REG(RTCx->PRER, RTC_PRER_PREDIV_A, AsynchPrescaler << RTC_PRER_PREDIV_A_Pos); +} + +/** + * @brief Set Synchronous prescaler factor + * @rmtoll RTC_PRER PREDIV_S LL_RTC_SetSynchPrescaler + * @param RTCx RTC Instance + * @param SynchPrescaler Value between Min_Data = 0 and Max_Data = 0x7FFF + * @retval None + */ +__STATIC_INLINE void LL_RTC_SetSynchPrescaler(RTC_TypeDef *RTCx, uint32_t SynchPrescaler) +{ + MODIFY_REG(RTCx->PRER, RTC_PRER_PREDIV_S, SynchPrescaler); +} + +/** + * @brief Get Asynchronous prescaler factor + * @rmtoll RTC_PRER PREDIV_A LL_RTC_GetAsynchPrescaler + * @param RTCx RTC Instance + * @retval Value between Min_Data = 0 and Max_Data = 0x7F + */ +__STATIC_INLINE uint32_t LL_RTC_GetAsynchPrescaler(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->PRER, RTC_PRER_PREDIV_A) >> RTC_PRER_PREDIV_A_Pos); +} + +/** + * @brief Get Synchronous prescaler factor + * @rmtoll RTC_PRER PREDIV_S LL_RTC_GetSynchPrescaler + * @param RTCx RTC Instance + * @retval Value between Min_Data = 0 and Max_Data = 0x7FFF + */ +__STATIC_INLINE uint32_t LL_RTC_GetSynchPrescaler(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->PRER, RTC_PRER_PREDIV_S)); +} + +/** + * @brief Enable the write protection for RTC registers. + * @rmtoll RTC_WPR KEY LL_RTC_EnableWriteProtection + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableWriteProtection(RTC_TypeDef *RTCx) +{ + WRITE_REG(RTCx->WPR, RTC_WRITE_PROTECTION_DISABLE); +} + +/** + * @brief Disable the write protection for RTC registers. + * @rmtoll RTC_WPR KEY LL_RTC_DisableWriteProtection + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableWriteProtection(RTC_TypeDef *RTCx) +{ + WRITE_REG(RTCx->WPR, RTC_WRITE_PROTECTION_ENABLE_1); + WRITE_REG(RTCx->WPR, RTC_WRITE_PROTECTION_ENABLE_2); +} + +#ifdef RTC_CR_TAMPOE +/** + * @brief Enable tamper output. + * @note When the tamper output is enabled, all external and internal tamper flags + * are ORed and routed to the TAMPALRM output. + * @rmtoll RTC_CR TAMPOE LL_RTC_EnableTamperOutput + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableTamperOutput(RTC_TypeDef *RTCx) +{ + SET_BIT(RTCx->CR, RTC_CR_TAMPOE); +} + +/** + * @brief Disable tamper output. + * @rmtoll RTC_CR TAMPOE LL_RTC_DisableTamperOutput + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableTamperOutput(RTC_TypeDef *RTCx) +{ + CLEAR_BIT(RTCx->CR, RTC_CR_TAMPOE); +} + +/** + * @brief Check if tamper output is enabled or not. + * @rmtoll RTC_CR TAMPOE LL_RTC_IsTamperOutputEnabled + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsTamperOutputEnabled(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->CR, RTC_CR_TAMPOE) == (RTC_CR_TAMPOE)) ? 1U : 0U); +} + +/** + * @brief Enable internal pull-up in output mode. + * @rmtoll RTC_CR TAMPALRM_PU LL_RTC_EnableAlarmPullUp + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableAlarmPullUp(RTC_TypeDef *RTCx) +{ + SET_BIT(RTCx->CR, RTC_CR_TAMPALRM_PU); +} +#endif /* RTC_CR_TAMPOE */ + +#ifdef RTC_CR_TAMPALRM_PU +/** + * @brief Disable internal pull-up in output mode. + * @rmtoll RTC_CR TAMPALRM_PU LL_RTC_EnableAlarmPullUp + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableAlarmPullUp(RTC_TypeDef *RTCx) +{ + CLEAR_BIT(RTCx->CR, RTC_CR_TAMPALRM_PU); +} + +/** + * @brief Check if internal pull-up in output mode is enabled or not. + * @rmtoll RTC_CR TAMPALRM_PU LL_RTC_IsAlarmPullUpEnabled + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsAlarmPullUpEnabled(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->CR, RTC_CR_TAMPALRM_PU) == (RTC_CR_TAMPALRM_PU)) ? 1U : 0U); +} +#endif /* RTC_CR_TAMPALRM_PU */ + + +#if defined(RTC_CR_OUT2EN) +/** + * @brief Enable RTC_OUT2 output + * @note RTC_OUT2 mapping depends on both OSEL (@ref LL_RTC_SetAlarmOutEvent) + * and COE (@ref LL_RTC_CAL_SetOutputFreq) settings. + * @note RTC_OUT2 is not available ins VBAT mode. + * @rmtoll RTC_CR OUT2EN LL_RTC_EnableOutput2 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableOutput2(RTC_TypeDef *RTCx) +{ + SET_BIT(RTCx->CR, RTC_CR_OUT2EN); +} + +/** + * @brief Disable RTC_OUT2 output + * @rmtoll RTC_CR OUT2EN LL_RTC_DisableOutput2 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableOutput2(RTC_TypeDef *RTCx) +{ + CLEAR_BIT(RTCx->CR, RTC_CR_OUT2EN); +} + +/** + * @brief Check if RTC_OUT2 output is enabled or not. + * @rmtoll RTC_CR OUT2EN LL_RTC_IsOutput2Enabled + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsOutput2Enabled(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->CR, RTC_CR_OUT2EN) == (RTC_CR_OUT2EN)) ? 1U : 0U); +} +#endif /* RTC_CR_OUT2EN */ + +/** + * @} + */ + +/** @defgroup RTC_LL_EF_Time Time + * @{ + */ + +/** + * @brief Set time format (AM/24-hour or PM notation) + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @note It can be written in initialization mode only (@ref LL_RTC_EnableInitMode function) + * @rmtoll RTC_TR PM LL_RTC_TIME_SetFormat + * @param RTCx RTC Instance + * @param TimeFormat This parameter can be one of the following values: + * @arg @ref LL_RTC_TIME_FORMAT_AM_OR_24 + * @arg @ref LL_RTC_TIME_FORMAT_PM + * @retval None + */ +__STATIC_INLINE void LL_RTC_TIME_SetFormat(RTC_TypeDef *RTCx, uint32_t TimeFormat) +{ + MODIFY_REG(RTCx->TR, RTC_TR_PM, TimeFormat); +} + +/** + * @brief Get time format (AM or PM notation) + * @note if shadow mode is disabled (BYPSHAD=0), need to check if RSF flag is set + * before reading this bit + * @note Read either RTC_SSR or RTC_TR locks the values in the higher-order calendar + * shadow registers until RTC_DR is read (LL_RTC_ReadReg(RTC, DR)). + * @rmtoll RTC_TR PM LL_RTC_TIME_GetFormat + * @param RTCx RTC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_RTC_TIME_FORMAT_AM_OR_24 + * @arg @ref LL_RTC_TIME_FORMAT_PM + */ +__STATIC_INLINE uint32_t LL_RTC_TIME_GetFormat(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->TR, RTC_TR_PM)); +} + +/** + * @brief Set Hours in BCD format + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @note It can be written in initialization mode only (@ref LL_RTC_EnableInitMode function) + * @note helper macro __LL_RTC_CONVERT_BIN2BCD is available to convert hour from binary to BCD format + * @rmtoll RTC_TR HT LL_RTC_TIME_SetHour\n + * RTC_TR HU LL_RTC_TIME_SetHour + * @param RTCx RTC Instance + * @param Hours Value between Min_Data=0x01 and Max_Data=0x12 or between Min_Data=0x00 and Max_Data=0x23 + * @retval None + */ +__STATIC_INLINE void LL_RTC_TIME_SetHour(RTC_TypeDef *RTCx, uint32_t Hours) +{ + MODIFY_REG(RTCx->TR, (RTC_TR_HT | RTC_TR_HU), + (((Hours & 0xF0U) << (RTC_TR_HT_Pos - 4U)) | ((Hours & 0x0FU) << RTC_TR_HU_Pos))); +} + +/** + * @brief Get Hours in BCD format + * @note if shadow mode is disabled (BYPSHAD=0), need to check if RSF flag is set + * before reading this bit + * @note Read either RTC_SSR or RTC_TR locks the values in the higher-order calendar + * shadow registers until RTC_DR is read (LL_RTC_ReadReg(RTC, DR)). + * @note helper macro __LL_RTC_CONVERT_BCD2BIN is available to convert hour from BCD to + * Binary format + * @rmtoll RTC_TR HT LL_RTC_TIME_GetHour\n + * RTC_TR HU LL_RTC_TIME_GetHour + * @param RTCx RTC Instance + * @retval Value between Min_Data=0x01 and Max_Data=0x12 or between Min_Data=0x00 and Max_Data=0x23 + */ +__STATIC_INLINE uint32_t LL_RTC_TIME_GetHour(const RTC_TypeDef *RTCx) +{ + return (uint32_t)((READ_BIT(RTCx->TR, (RTC_TR_HT | RTC_TR_HU))) >> RTC_TR_HU_Pos); +} + +/** + * @brief Set Minutes in BCD format + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @note It can be written in initialization mode only (@ref LL_RTC_EnableInitMode function) + * @note helper macro __LL_RTC_CONVERT_BIN2BCD is available to convert Minutes from binary to BCD format + * @rmtoll RTC_TR MNT LL_RTC_TIME_SetMinute\n + * RTC_TR MNU LL_RTC_TIME_SetMinute + * @param RTCx RTC Instance + * @param Minutes Value between Min_Data=0x00 and Max_Data=0x59 + * @retval None + */ +__STATIC_INLINE void LL_RTC_TIME_SetMinute(RTC_TypeDef *RTCx, uint32_t Minutes) +{ + MODIFY_REG(RTCx->TR, (RTC_TR_MNT | RTC_TR_MNU), + (((Minutes & 0xF0U) << (RTC_TR_MNT_Pos - 4U)) | ((Minutes & 0x0FU) << RTC_TR_MNU_Pos))); +} + +/** + * @brief Get Minutes in BCD format + * @note if shadow mode is disabled (BYPSHAD=0), need to check if RSF flag is set + * before reading this bit + * @note Read either RTC_SSR or RTC_TR locks the values in the higher-order calendar + * shadow registers until RTC_DR is read (LL_RTC_ReadReg(RTC, DR)). + * @note helper macro __LL_RTC_CONVERT_BCD2BIN is available to convert minute from BCD + * to Binary format + * @rmtoll RTC_TR MNT LL_RTC_TIME_GetMinute\n + * RTC_TR MNU LL_RTC_TIME_GetMinute + * @param RTCx RTC Instance + * @retval Value between Min_Data=0x00 and Max_Data=0x59 + */ +__STATIC_INLINE uint32_t LL_RTC_TIME_GetMinute(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->TR, (RTC_TR_MNT | RTC_TR_MNU)) >> RTC_TR_MNU_Pos); +} + +/** + * @brief Set Seconds in BCD format + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @note It can be written in initialization mode only (@ref LL_RTC_EnableInitMode function) + * @note helper macro __LL_RTC_CONVERT_BIN2BCD is available to convert Seconds from binary to BCD format + * @rmtoll RTC_TR ST LL_RTC_TIME_SetSecond\n + * RTC_TR SU LL_RTC_TIME_SetSecond + * @param RTCx RTC Instance + * @param Seconds Value between Min_Data=0x00 and Max_Data=0x59 + * @retval None + */ +__STATIC_INLINE void LL_RTC_TIME_SetSecond(RTC_TypeDef *RTCx, uint32_t Seconds) +{ + MODIFY_REG(RTCx->TR, (RTC_TR_ST | RTC_TR_SU), + (((Seconds & 0xF0U) << (RTC_TR_ST_Pos - 4U)) | ((Seconds & 0x0FU) << RTC_TR_SU_Pos))); +} + +/** + * @brief Get Seconds in BCD format + * @note if shadow mode is disabled (BYPSHAD=0), need to check if RSF flag is set + * before reading this bit + * @note Read either RTC_SSR or RTC_TR locks the values in the higher-order calendar + * shadow registers until RTC_DR is read (LL_RTC_ReadReg(RTC, DR)). + * @note helper macro __LL_RTC_CONVERT_BCD2BIN is available to convert Seconds from BCD + * to Binary format + * @rmtoll RTC_TR ST LL_RTC_TIME_GetSecond\n + * RTC_TR SU LL_RTC_TIME_GetSecond + * @param RTCx RTC Instance + * @retval Value between Min_Data=0x00 and Max_Data=0x59 + */ +__STATIC_INLINE uint32_t LL_RTC_TIME_GetSecond(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->TR, (RTC_TR_ST | RTC_TR_SU)) >> RTC_TR_SU_Pos); +} + +/** + * @brief Set time (hour, minute and second) in BCD format + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @note It can be written in initialization mode only (@ref LL_RTC_EnableInitMode function) + * @note TimeFormat and Hours should follow the same format + * @rmtoll RTC_TR PM LL_RTC_TIME_Config\n + * RTC_TR HT LL_RTC_TIME_Config\n + * RTC_TR HU LL_RTC_TIME_Config\n + * RTC_TR MNT LL_RTC_TIME_Config\n + * RTC_TR MNU LL_RTC_TIME_Config\n + * RTC_TR ST LL_RTC_TIME_Config\n + * RTC_TR SU LL_RTC_TIME_Config + * @param RTCx RTC Instance + * @param Format12_24 This parameter can be one of the following values: + * @arg @ref LL_RTC_TIME_FORMAT_AM_OR_24 + * @arg @ref LL_RTC_TIME_FORMAT_PM + * @param Hours Value between Min_Data=0x01 and Max_Data=0x12 or between Min_Data=0x00 and Max_Data=0x23 + * @param Minutes Value between Min_Data=0x00 and Max_Data=0x59 + * @param Seconds Value between Min_Data=0x00 and Max_Data=0x59 + * @retval None + */ +__STATIC_INLINE void LL_RTC_TIME_Config(RTC_TypeDef *RTCx, + uint32_t Format12_24, + uint32_t Hours, + uint32_t Minutes, + uint32_t Seconds) +{ + uint32_t temp; + + temp = Format12_24 | \ + (((Hours & 0xF0U) << (RTC_TR_HT_Pos - 4U)) | ((Hours & 0x0FU) << RTC_TR_HU_Pos)) | \ + (((Minutes & 0xF0U) << (RTC_TR_MNT_Pos - 4U)) | ((Minutes & 0x0FU) << RTC_TR_MNU_Pos)) | \ + (((Seconds & 0xF0U) << (RTC_TR_ST_Pos - 4U)) | ((Seconds & 0x0FU) << RTC_TR_SU_Pos)); + MODIFY_REG(RTCx->TR, (RTC_TR_PM | RTC_TR_HT | RTC_TR_HU | RTC_TR_MNT | RTC_TR_MNU | RTC_TR_ST | RTC_TR_SU), temp); +} + +/** + * @brief Get time (hour, minute and second) in BCD format + * @note if shadow mode is disabled (BYPSHAD=0), need to check if RSF flag is set + * before reading this bit + * @note Read either RTC_SSR or RTC_TR locks the values in the higher-order calendar + * shadow registers until RTC_DR is read (LL_RTC_ReadReg(RTC, DR)). + * @note helper macros __LL_RTC_GET_HOUR, __LL_RTC_GET_MINUTE and __LL_RTC_GET_SECOND + * are available to get independently each parameter. + * @rmtoll RTC_TR HT LL_RTC_TIME_Get\n + * RTC_TR HU LL_RTC_TIME_Get\n + * RTC_TR MNT LL_RTC_TIME_Get\n + * RTC_TR MNU LL_RTC_TIME_Get\n + * RTC_TR ST LL_RTC_TIME_Get\n + * RTC_TR SU LL_RTC_TIME_Get + * @param RTCx RTC Instance + * @retval Combination of hours, minutes and seconds (Format: 0x00HHMMSS). + */ +__STATIC_INLINE uint32_t LL_RTC_TIME_Get(const RTC_TypeDef *RTCx) +{ + uint32_t temp; + + temp = READ_BIT(RTCx->TR, (RTC_TR_HT | RTC_TR_HU | RTC_TR_MNT | RTC_TR_MNU | RTC_TR_ST | RTC_TR_SU)); + return (uint32_t)((((((temp & RTC_TR_HT) >> RTC_TR_HT_Pos) << 4U) | \ + ((temp & RTC_TR_HU) >> RTC_TR_HU_Pos)) << RTC_OFFSET_HOUR) | \ + (((((temp & RTC_TR_MNT) >> RTC_TR_MNT_Pos) << 4U) | \ + ((temp & RTC_TR_MNU) >> RTC_TR_MNU_Pos)) << RTC_OFFSET_MINUTE) | \ + ((((temp & RTC_TR_ST) >> RTC_TR_ST_Pos) << 4U) | ((temp & RTC_TR_SU) >> RTC_TR_SU_Pos))); +} + +/** + * @brief Memorize whether the daylight saving time change has been performed + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR BKP LL_RTC_TIME_EnableDayLightStore + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_TIME_EnableDayLightStore(RTC_TypeDef *RTCx) +{ + SET_BIT(RTCx->CR, RTC_CR_BKP); +} + +/** + * @brief Disable memorization whether the daylight saving time change has been performed. + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR BKP LL_RTC_TIME_DisableDayLightStore + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_TIME_DisableDayLightStore(RTC_TypeDef *RTCx) +{ + CLEAR_BIT(RTCx->CR, RTC_CR_BKP); +} + +/** + * @brief Check if RTC Day Light Saving stored operation has been enabled or not + * @rmtoll RTC_CR BKP LL_RTC_TIME_IsDayLightStoreEnabled + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_TIME_IsDayLightStoreEnabled(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->CR, RTC_CR_BKP) == (RTC_CR_BKP)) ? 1U : 0U); +} + +/** + * @brief Subtract 1 hour (winter time change) + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR SUB1H LL_RTC_TIME_DecHour + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_TIME_DecHour(RTC_TypeDef *RTCx) +{ + SET_BIT(RTCx->CR, RTC_CR_SUB1H); +} + +/** + * @brief Add 1 hour (summer time change) + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR ADD1H LL_RTC_TIME_IncHour + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_TIME_IncHour(RTC_TypeDef *RTCx) +{ + SET_BIT(RTCx->CR, RTC_CR_ADD1H); +} + +/** + * @brief Get Sub second value in the synchronous prescaler counter. + * @note You can use both SubSeconds value and SecondFraction (PREDIV_S through + * LL_RTC_GetSynchPrescaler function) terms returned to convert Calendar + * SubSeconds value in second fraction ratio with time unit following + * generic formula: + * ==> Seconds fraction ratio * time_unit= [(SecondFraction-SubSeconds)/(SecondFraction+1)] * time_unit + * This conversion can be performed only if no shift operation is pending + * (ie. SHFP=0) when PREDIV_S >= SS. + * @rmtoll RTC_SSR SS LL_RTC_TIME_GetSubSecond + * @param RTCx RTC Instance + * @retval If binary mode is none, Value between Min_Data=0x0 and Max_Data=0x7FFF + * else Value between Min_Data=0x0 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_RTC_TIME_GetSubSecond(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->SSR, RTC_SSR_SS)); +} + +/** + * @brief Synchronize to a remote clock with a high degree of precision. + * @note This operation effectively subtracts from (delays) or advance the clock of a fraction of a second. + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @note When REFCKON is set, firmware must not write to Shift control register. + * @rmtoll RTC_SHIFTR ADD1S LL_RTC_TIME_Synchronize\n + * RTC_SHIFTR SUBFS LL_RTC_TIME_Synchronize + * @param RTCx RTC Instance + * @param ShiftSecond This parameter can be one of the following values: + * @arg @ref LL_RTC_SHIFT_SECOND_DELAY + * @arg @ref LL_RTC_SHIFT_SECOND_ADVANCE + * @param Fraction Number of Seconds Fractions (any value from 0 to 0x7FFF) + * @retval None + */ +__STATIC_INLINE void LL_RTC_TIME_Synchronize(RTC_TypeDef *RTCx, uint32_t ShiftSecond, uint32_t Fraction) +{ + WRITE_REG(RTCx->SHIFTR, ShiftSecond | Fraction); +} + +/** + * @} + */ + +/** @defgroup RTC_LL_EF_Date Date + * @{ + */ + +/** + * @brief Set Year in BCD format + * @note helper macro __LL_RTC_CONVERT_BIN2BCD is available to convert Year from binary to BCD format + * @rmtoll RTC_DR YT LL_RTC_DATE_SetYear\n + * RTC_DR YU LL_RTC_DATE_SetYear + * @param RTCx RTC Instance + * @param Year Value between Min_Data=0x00 and Max_Data=0x99 + * @retval None + */ +__STATIC_INLINE void LL_RTC_DATE_SetYear(RTC_TypeDef *RTCx, uint32_t Year) +{ + MODIFY_REG(RTCx->DR, (RTC_DR_YT | RTC_DR_YU), + (((Year & 0xF0U) << (RTC_DR_YT_Pos - 4U)) | ((Year & 0x0FU) << RTC_DR_YU_Pos))); +} + +/** + * @brief Get Year in BCD format + * @note if shadow mode is disabled (BYPSHAD=0), need to check if RSF flag is set + * before reading this bit + * @note helper macro __LL_RTC_CONVERT_BCD2BIN is available to convert Year from BCD to Binary format + * @rmtoll RTC_DR YT LL_RTC_DATE_GetYear\n + * RTC_DR YU LL_RTC_DATE_GetYear + * @param RTCx RTC Instance + * @retval Value between Min_Data=0x00 and Max_Data=0x99 + */ +__STATIC_INLINE uint32_t LL_RTC_DATE_GetYear(const RTC_TypeDef *RTCx) +{ + return (uint32_t)((READ_BIT(RTCx->DR, (RTC_DR_YT | RTC_DR_YU))) >> RTC_DR_YU_Pos); +} + +/** + * @brief Set Week day + * @rmtoll RTC_DR WDU LL_RTC_DATE_SetWeekDay + * @param RTCx RTC Instance + * @param WeekDay This parameter can be one of the following values: + * @arg @ref LL_RTC_WEEKDAY_MONDAY + * @arg @ref LL_RTC_WEEKDAY_TUESDAY + * @arg @ref LL_RTC_WEEKDAY_WEDNESDAY + * @arg @ref LL_RTC_WEEKDAY_THURSDAY + * @arg @ref LL_RTC_WEEKDAY_FRIDAY + * @arg @ref LL_RTC_WEEKDAY_SATURDAY + * @arg @ref LL_RTC_WEEKDAY_SUNDAY + * @retval None + */ +__STATIC_INLINE void LL_RTC_DATE_SetWeekDay(RTC_TypeDef *RTCx, uint32_t WeekDay) +{ + MODIFY_REG(RTCx->DR, RTC_DR_WDU, WeekDay << RTC_DR_WDU_Pos); +} + +/** + * @brief Get Week day + * @note if shadow mode is disabled (BYPSHAD=0), need to check if RSF flag is set + * before reading this bit + * @rmtoll RTC_DR WDU LL_RTC_DATE_GetWeekDay + * @param RTCx RTC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_RTC_WEEKDAY_MONDAY + * @arg @ref LL_RTC_WEEKDAY_TUESDAY + * @arg @ref LL_RTC_WEEKDAY_WEDNESDAY + * @arg @ref LL_RTC_WEEKDAY_THURSDAY + * @arg @ref LL_RTC_WEEKDAY_FRIDAY + * @arg @ref LL_RTC_WEEKDAY_SATURDAY + * @arg @ref LL_RTC_WEEKDAY_SUNDAY + */ +__STATIC_INLINE uint32_t LL_RTC_DATE_GetWeekDay(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->DR, RTC_DR_WDU) >> RTC_DR_WDU_Pos); +} + +/** + * @brief Set Month in BCD format + * @note helper macro __LL_RTC_CONVERT_BIN2BCD is available to convert Month from binary to BCD format + * @rmtoll RTC_DR MT LL_RTC_DATE_SetMonth\n + * RTC_DR MU LL_RTC_DATE_SetMonth + * @param RTCx RTC Instance + * @param Month This parameter can be one of the following values: + * @arg @ref LL_RTC_MONTH_JANUARY + * @arg @ref LL_RTC_MONTH_FEBRUARY + * @arg @ref LL_RTC_MONTH_MARCH + * @arg @ref LL_RTC_MONTH_APRIL + * @arg @ref LL_RTC_MONTH_MAY + * @arg @ref LL_RTC_MONTH_JUNE + * @arg @ref LL_RTC_MONTH_JULY + * @arg @ref LL_RTC_MONTH_AUGUST + * @arg @ref LL_RTC_MONTH_SEPTEMBER + * @arg @ref LL_RTC_MONTH_OCTOBER + * @arg @ref LL_RTC_MONTH_NOVEMBER + * @arg @ref LL_RTC_MONTH_DECEMBER + * @retval None + */ +__STATIC_INLINE void LL_RTC_DATE_SetMonth(RTC_TypeDef *RTCx, uint32_t Month) +{ + MODIFY_REG(RTCx->DR, (RTC_DR_MT | RTC_DR_MU), + (((Month & 0xF0U) << (RTC_DR_MT_Pos - 4U)) | ((Month & 0x0FU) << RTC_DR_MU_Pos))); +} + +/** + * @brief Get Month in BCD format + * @note if shadow mode is disabled (BYPSHAD=0), need to check if RSF flag is set + * before reading this bit + * @note helper macro __LL_RTC_CONVERT_BCD2BIN is available to convert Month from BCD to Binary format + * @rmtoll RTC_DR MT LL_RTC_DATE_GetMonth\n + * RTC_DR MU LL_RTC_DATE_GetMonth + * @param RTCx RTC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_RTC_MONTH_JANUARY + * @arg @ref LL_RTC_MONTH_FEBRUARY + * @arg @ref LL_RTC_MONTH_MARCH + * @arg @ref LL_RTC_MONTH_APRIL + * @arg @ref LL_RTC_MONTH_MAY + * @arg @ref LL_RTC_MONTH_JUNE + * @arg @ref LL_RTC_MONTH_JULY + * @arg @ref LL_RTC_MONTH_AUGUST + * @arg @ref LL_RTC_MONTH_SEPTEMBER + * @arg @ref LL_RTC_MONTH_OCTOBER + * @arg @ref LL_RTC_MONTH_NOVEMBER + * @arg @ref LL_RTC_MONTH_DECEMBER + */ +__STATIC_INLINE uint32_t LL_RTC_DATE_GetMonth(const RTC_TypeDef *RTCx) +{ + return (uint32_t)((READ_BIT(RTCx->DR, (RTC_DR_MT | RTC_DR_MU))) >> RTC_DR_MU_Pos); +} + +/** + * @brief Set Day in BCD format + * @note helper macro __LL_RTC_CONVERT_BIN2BCD is available to convert Day from binary to BCD format + * @rmtoll RTC_DR DT LL_RTC_DATE_SetDay\n + * RTC_DR DU LL_RTC_DATE_SetDay + * @param RTCx RTC Instance + * @param Day Value between Min_Data=0x01 and Max_Data=0x31 + * @retval None + */ +__STATIC_INLINE void LL_RTC_DATE_SetDay(RTC_TypeDef *RTCx, uint32_t Day) +{ + MODIFY_REG(RTCx->DR, (RTC_DR_DT | RTC_DR_DU), + (((Day & 0xF0U) << (RTC_DR_DT_Pos - 4U)) | ((Day & 0x0FU) << RTC_DR_DU_Pos))); +} + +/** + * @brief Get Day in BCD format + * @note if shadow mode is disabled (BYPSHAD=0), need to check if RSF flag is set + * before reading this bit + * @note helper macro __LL_RTC_CONVERT_BCD2BIN is available to convert Day from BCD to Binary format + * @rmtoll RTC_DR DT LL_RTC_DATE_GetDay\n + * RTC_DR DU LL_RTC_DATE_GetDay + * @param RTCx RTC Instance + * @retval Value between Min_Data=0x01 and Max_Data=0x31 + */ +__STATIC_INLINE uint32_t LL_RTC_DATE_GetDay(const RTC_TypeDef *RTCx) +{ + return (uint32_t)((READ_BIT(RTCx->DR, (RTC_DR_DT | RTC_DR_DU))) >> RTC_DR_DU_Pos); +} + +/** + * @brief Set date (WeekDay, Day, Month and Year) in BCD format + * @rmtoll RTC_DR WDU LL_RTC_DATE_Config\n + * RTC_DR MT LL_RTC_DATE_Config\n + * RTC_DR MU LL_RTC_DATE_Config\n + * RTC_DR DT LL_RTC_DATE_Config\n + * RTC_DR DU LL_RTC_DATE_Config\n + * RTC_DR YT LL_RTC_DATE_Config\n + * RTC_DR YU LL_RTC_DATE_Config + * @param RTCx RTC Instance + * @param WeekDay This parameter can be one of the following values: + * @arg @ref LL_RTC_WEEKDAY_MONDAY + * @arg @ref LL_RTC_WEEKDAY_TUESDAY + * @arg @ref LL_RTC_WEEKDAY_WEDNESDAY + * @arg @ref LL_RTC_WEEKDAY_THURSDAY + * @arg @ref LL_RTC_WEEKDAY_FRIDAY + * @arg @ref LL_RTC_WEEKDAY_SATURDAY + * @arg @ref LL_RTC_WEEKDAY_SUNDAY + * @param Day Value between Min_Data=0x01 and Max_Data=0x31 + * @param Month This parameter can be one of the following values: + * @arg @ref LL_RTC_MONTH_JANUARY + * @arg @ref LL_RTC_MONTH_FEBRUARY + * @arg @ref LL_RTC_MONTH_MARCH + * @arg @ref LL_RTC_MONTH_APRIL + * @arg @ref LL_RTC_MONTH_MAY + * @arg @ref LL_RTC_MONTH_JUNE + * @arg @ref LL_RTC_MONTH_JULY + * @arg @ref LL_RTC_MONTH_AUGUST + * @arg @ref LL_RTC_MONTH_SEPTEMBER + * @arg @ref LL_RTC_MONTH_OCTOBER + * @arg @ref LL_RTC_MONTH_NOVEMBER + * @arg @ref LL_RTC_MONTH_DECEMBER + * @param Year Value between Min_Data=0x00 and Max_Data=0x99 + * @retval None + */ +__STATIC_INLINE void LL_RTC_DATE_Config(RTC_TypeDef *RTCx, + uint32_t WeekDay, + uint32_t Day, + uint32_t Month, + uint32_t Year) +{ + uint32_t temp; + + temp = (WeekDay << RTC_DR_WDU_Pos) | \ + (((Year & 0xF0U) << (RTC_DR_YT_Pos - 4U)) | ((Year & 0x0FU) << RTC_DR_YU_Pos)) | \ + (((Month & 0xF0U) << (RTC_DR_MT_Pos - 4U)) | ((Month & 0x0FU) << RTC_DR_MU_Pos)) | \ + (((Day & 0xF0U) << (RTC_DR_DT_Pos - 4U)) | ((Day & 0x0FU) << RTC_DR_DU_Pos)); + + MODIFY_REG(RTCx->DR, (RTC_DR_WDU | RTC_DR_MT | RTC_DR_MU | RTC_DR_DT | RTC_DR_DU | RTC_DR_YT | RTC_DR_YU), temp); +} + +/** + * @brief Get date (WeekDay, Day, Month and Year) in BCD format + * @note if shadow mode is disabled (BYPSHAD=0), need to check if RSF flag is set + * before reading this bit + * @note helper macros __LL_RTC_GET_WEEKDAY, __LL_RTC_GET_YEAR, __LL_RTC_GET_MONTH, + * and __LL_RTC_GET_DAY are available to get independently each parameter. + * @rmtoll RTC_DR WDU LL_RTC_DATE_Get\n + * RTC_DR MT LL_RTC_DATE_Get\n + * RTC_DR MU LL_RTC_DATE_Get\n + * RTC_DR DT LL_RTC_DATE_Get\n + * RTC_DR DU LL_RTC_DATE_Get\n + * RTC_DR YT LL_RTC_DATE_Get\n + * RTC_DR YU LL_RTC_DATE_Get + * @param RTCx RTC Instance + * @retval Combination of WeekDay, Day, Month and Year (Format: 0xWWDDMMYY). + */ +__STATIC_INLINE uint32_t LL_RTC_DATE_Get(const RTC_TypeDef *RTCx) +{ + uint32_t temp; + + temp = READ_BIT(RTCx->DR, (RTC_DR_WDU | RTC_DR_MT | RTC_DR_MU | RTC_DR_DT | RTC_DR_DU | RTC_DR_YT | RTC_DR_YU)); + return (uint32_t)((((temp & RTC_DR_WDU) >> RTC_DR_WDU_Pos) << RTC_OFFSET_WEEKDAY) | \ + (((((temp & RTC_DR_DT) >> RTC_DR_DT_Pos) << 4U) | \ + ((temp & RTC_DR_DU) >> RTC_DR_DU_Pos)) << RTC_OFFSET_DAY) | \ + (((((temp & RTC_DR_MT) >> RTC_DR_MT_Pos) << 4U) | \ + ((temp & RTC_DR_MU) >> RTC_DR_MU_Pos)) << RTC_OFFSET_MONTH) | \ + ((((temp & RTC_DR_YT) >> RTC_DR_YT_Pos) << 4U) | ((temp & RTC_DR_YU) >> RTC_DR_YU_Pos))); +} + +/** + * @} + */ + +/** @defgroup RTC_LL_EF_ALARMA ALARMA + * @{ + */ + +/** + * @brief Enable Alarm A + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR ALRAE LL_RTC_ALMA_Enable + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMA_Enable(RTC_TypeDef *RTCx) +{ + SET_BIT(RTCx->CR, RTC_CR_ALRAE); +} + +/** + * @brief Disable Alarm A + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR ALRAE LL_RTC_ALMA_Disable + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMA_Disable(RTC_TypeDef *RTCx) +{ + CLEAR_BIT(RTCx->CR, RTC_CR_ALRAE); +} + +/** + * @brief Specify the Alarm A masks. + * @rmtoll RTC_ALRMAR MSK4 LL_RTC_ALMA_SetMask\n + * RTC_ALRMAR MSK3 LL_RTC_ALMA_SetMask\n + * RTC_ALRMAR MSK2 LL_RTC_ALMA_SetMask\n + * RTC_ALRMAR MSK1 LL_RTC_ALMA_SetMask + * @param RTCx RTC Instance + * @param Mask This parameter can be a combination of the following values: + * @arg @ref LL_RTC_ALMA_MASK_NONE + * @arg @ref LL_RTC_ALMA_MASK_DATEWEEKDAY + * @arg @ref LL_RTC_ALMA_MASK_HOURS + * @arg @ref LL_RTC_ALMA_MASK_MINUTES + * @arg @ref LL_RTC_ALMA_MASK_SECONDS + * @arg @ref LL_RTC_ALMA_MASK_ALL + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMA_SetMask(RTC_TypeDef *RTCx, uint32_t Mask) +{ + MODIFY_REG(RTCx->ALRMAR, RTC_ALRMAR_MSK4 | RTC_ALRMAR_MSK3 | RTC_ALRMAR_MSK2 | RTC_ALRMAR_MSK1, Mask); +} + +/** + * @brief Get the Alarm A masks. + * @rmtoll RTC_ALRMAR MSK4 LL_RTC_ALMA_GetMask\n + * RTC_ALRMAR MSK3 LL_RTC_ALMA_GetMask\n + * RTC_ALRMAR MSK2 LL_RTC_ALMA_GetMask\n + * RTC_ALRMAR MSK1 LL_RTC_ALMA_GetMask + * @param RTCx RTC Instance + * @retval Returned value can be can be a combination of the following values: + * @arg @ref LL_RTC_ALMA_MASK_NONE + * @arg @ref LL_RTC_ALMA_MASK_DATEWEEKDAY + * @arg @ref LL_RTC_ALMA_MASK_HOURS + * @arg @ref LL_RTC_ALMA_MASK_MINUTES + * @arg @ref LL_RTC_ALMA_MASK_SECONDS + * @arg @ref LL_RTC_ALMA_MASK_ALL + */ +__STATIC_INLINE uint32_t LL_RTC_ALMA_GetMask(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->ALRMAR, RTC_ALRMAR_MSK4 | RTC_ALRMAR_MSK3 | RTC_ALRMAR_MSK2 | RTC_ALRMAR_MSK1)); +} + +/** + * @brief Enable AlarmA Week day selection (DU[3:0] represents the week day. DT[1:0] is do not care) + * @rmtoll RTC_ALRMAR WDSEL LL_RTC_ALMA_EnableWeekday + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMA_EnableWeekday(RTC_TypeDef *RTCx) +{ + SET_BIT(RTCx->ALRMAR, RTC_ALRMAR_WDSEL); +} + +/** + * @brief Disable AlarmA Week day selection (DU[3:0] represents the date ) + * @rmtoll RTC_ALRMAR WDSEL LL_RTC_ALMA_DisableWeekday + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMA_DisableWeekday(RTC_TypeDef *RTCx) +{ + CLEAR_BIT(RTCx->ALRMAR, RTC_ALRMAR_WDSEL); +} + +/** + * @brief Set ALARM A Day in BCD format + * @note helper macro __LL_RTC_CONVERT_BIN2BCD is available to convert Day from binary to BCD format + * @rmtoll RTC_ALRMAR DT LL_RTC_ALMA_SetDay\n + * RTC_ALRMAR DU LL_RTC_ALMA_SetDay + * @param RTCx RTC Instance + * @param Day Value between Min_Data=0x01 and Max_Data=0x31 + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMA_SetDay(RTC_TypeDef *RTCx, uint32_t Day) +{ + MODIFY_REG(RTCx->ALRMAR, (RTC_ALRMAR_DT | RTC_ALRMAR_DU), + (((Day & 0xF0U) << (RTC_ALRMAR_DT_Pos - 4U)) | ((Day & 0x0FU) << RTC_ALRMAR_DU_Pos))); +} + +/** + * @brief Get ALARM A Day in BCD format + * @note helper macro __LL_RTC_CONVERT_BCD2BIN is available to convert Day from BCD to Binary format + * @rmtoll RTC_ALRMAR DT LL_RTC_ALMA_GetDay\n + * RTC_ALRMAR DU LL_RTC_ALMA_GetDay + * @param RTCx RTC Instance + * @retval Value between Min_Data=0x01 and Max_Data=0x31 + */ +__STATIC_INLINE uint32_t LL_RTC_ALMA_GetDay(const RTC_TypeDef *RTCx) +{ + return (uint32_t)((READ_BIT(RTCx->ALRMAR, (RTC_ALRMAR_DT | RTC_ALRMAR_DU))) >> RTC_ALRMAR_DU_Pos); +} + +/** + * @brief Set ALARM A Weekday + * @rmtoll RTC_ALRMAR DU LL_RTC_ALMA_SetWeekDay + * @param RTCx RTC Instance + * @param WeekDay This parameter can be one of the following values: + * @arg @ref LL_RTC_WEEKDAY_MONDAY + * @arg @ref LL_RTC_WEEKDAY_TUESDAY + * @arg @ref LL_RTC_WEEKDAY_WEDNESDAY + * @arg @ref LL_RTC_WEEKDAY_THURSDAY + * @arg @ref LL_RTC_WEEKDAY_FRIDAY + * @arg @ref LL_RTC_WEEKDAY_SATURDAY + * @arg @ref LL_RTC_WEEKDAY_SUNDAY + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMA_SetWeekDay(RTC_TypeDef *RTCx, uint32_t WeekDay) +{ + MODIFY_REG(RTCx->ALRMAR, RTC_ALRMAR_DU, WeekDay << RTC_ALRMAR_DU_Pos); +} + +/** + * @brief Get ALARM A Weekday + * @rmtoll RTC_ALRMAR DU LL_RTC_ALMA_GetWeekDay + * @param RTCx RTC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_RTC_WEEKDAY_MONDAY + * @arg @ref LL_RTC_WEEKDAY_TUESDAY + * @arg @ref LL_RTC_WEEKDAY_WEDNESDAY + * @arg @ref LL_RTC_WEEKDAY_THURSDAY + * @arg @ref LL_RTC_WEEKDAY_FRIDAY + * @arg @ref LL_RTC_WEEKDAY_SATURDAY + * @arg @ref LL_RTC_WEEKDAY_SUNDAY + */ +__STATIC_INLINE uint32_t LL_RTC_ALMA_GetWeekDay(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->ALRMAR, RTC_ALRMAR_DU) >> RTC_ALRMAR_DU_Pos); +} + +/** + * @brief Set Alarm A time format (AM/24-hour or PM notation) + * @rmtoll RTC_ALRMAR PM LL_RTC_ALMA_SetTimeFormat + * @param RTCx RTC Instance + * @param TimeFormat This parameter can be one of the following values: + * @arg @ref LL_RTC_ALMA_TIME_FORMAT_AM + * @arg @ref LL_RTC_ALMA_TIME_FORMAT_PM + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMA_SetTimeFormat(RTC_TypeDef *RTCx, uint32_t TimeFormat) +{ + MODIFY_REG(RTCx->ALRMAR, RTC_ALRMAR_PM, TimeFormat); +} + +/** + * @brief Get Alarm A time format (AM or PM notation) + * @rmtoll RTC_ALRMAR PM LL_RTC_ALMA_GetTimeFormat + * @param RTCx RTC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_RTC_ALMA_TIME_FORMAT_AM + * @arg @ref LL_RTC_ALMA_TIME_FORMAT_PM + */ +__STATIC_INLINE uint32_t LL_RTC_ALMA_GetTimeFormat(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->ALRMAR, RTC_ALRMAR_PM)); +} + +/** + * @brief Set ALARM A Hours in BCD format + * @note helper macro __LL_RTC_CONVERT_BIN2BCD is available to convert Hours from binary to BCD format + * @rmtoll RTC_ALRMAR HT LL_RTC_ALMA_SetHour\n + * RTC_ALRMAR HU LL_RTC_ALMA_SetHour + * @param RTCx RTC Instance + * @param Hours Value between Min_Data=0x01 and Max_Data=0x12 or between Min_Data=0x00 and Max_Data=0x23 + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMA_SetHour(RTC_TypeDef *RTCx, uint32_t Hours) +{ + MODIFY_REG(RTCx->ALRMAR, (RTC_ALRMAR_HT | RTC_ALRMAR_HU), + (((Hours & 0xF0U) << (RTC_ALRMAR_HT_Pos - 4U)) | ((Hours & 0x0FU) << RTC_ALRMAR_HU_Pos))); +} + +/** + * @brief Get ALARM A Hours in BCD format + * @note helper macro __LL_RTC_CONVERT_BCD2BIN is available to convert Hours from BCD to Binary format + * @rmtoll RTC_ALRMAR HT LL_RTC_ALMA_GetHour\n + * RTC_ALRMAR HU LL_RTC_ALMA_GetHour + * @param RTCx RTC Instance + * @retval Value between Min_Data=0x01 and Max_Data=0x12 or between Min_Data=0x00 and Max_Data=0x23 + */ +__STATIC_INLINE uint32_t LL_RTC_ALMA_GetHour(const RTC_TypeDef *RTCx) +{ + return (uint32_t)((READ_BIT(RTCx->ALRMAR, (RTC_ALRMAR_HT | RTC_ALRMAR_HU))) >> RTC_ALRMAR_HU_Pos); +} + +/** + * @brief Set ALARM A Minutes in BCD format + * @note helper macro __LL_RTC_CONVERT_BIN2BCD is available to convert Minutes from binary to BCD format + * @rmtoll RTC_ALRMAR MNT LL_RTC_ALMA_SetMinute\n + * RTC_ALRMAR MNU LL_RTC_ALMA_SetMinute + * @param RTCx RTC Instance + * @param Minutes Value between Min_Data=0x00 and Max_Data=0x59 + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMA_SetMinute(RTC_TypeDef *RTCx, uint32_t Minutes) +{ + MODIFY_REG(RTCx->ALRMAR, (RTC_ALRMAR_MNT | RTC_ALRMAR_MNU), + (((Minutes & 0xF0U) << (RTC_ALRMAR_MNT_Pos - 4U)) | ((Minutes & 0x0FU) << RTC_ALRMAR_MNU_Pos))); +} + +/** + * @brief Get ALARM A Minutes in BCD format + * @note helper macro __LL_RTC_CONVERT_BCD2BIN is available to convert Minutes from BCD to Binary format + * @rmtoll RTC_ALRMAR MNT LL_RTC_ALMA_GetMinute\n + * RTC_ALRMAR MNU LL_RTC_ALMA_GetMinute + * @param RTCx RTC Instance + * @retval Value between Min_Data=0x00 and Max_Data=0x59 + */ +__STATIC_INLINE uint32_t LL_RTC_ALMA_GetMinute(const RTC_TypeDef *RTCx) +{ + return (uint32_t)((READ_BIT(RTCx->ALRMAR, (RTC_ALRMAR_MNT | RTC_ALRMAR_MNU))) >> RTC_ALRMAR_MNU_Pos); +} + +/** + * @brief Set ALARM A Seconds in BCD format + * @note helper macro __LL_RTC_CONVERT_BIN2BCD is available to convert Seconds from binary to BCD format + * @rmtoll RTC_ALRMAR ST LL_RTC_ALMA_SetSecond\n + * RTC_ALRMAR SU LL_RTC_ALMA_SetSecond + * @param RTCx RTC Instance + * @param Seconds Value between Min_Data=0x00 and Max_Data=0x59 + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMA_SetSecond(RTC_TypeDef *RTCx, uint32_t Seconds) +{ + MODIFY_REG(RTCx->ALRMAR, (RTC_ALRMAR_ST | RTC_ALRMAR_SU), + (((Seconds & 0xF0U) << (RTC_ALRMAR_ST_Pos - 4U)) | ((Seconds & 0x0FU) << RTC_ALRMAR_SU_Pos))); +} + +/** + * @brief Get ALARM A Seconds in BCD format + * @note helper macro __LL_RTC_CONVERT_BCD2BIN is available to convert Seconds from BCD to Binary format + * @rmtoll RTC_ALRMAR ST LL_RTC_ALMA_GetSecond\n + * RTC_ALRMAR SU LL_RTC_ALMA_GetSecond + * @param RTCx RTC Instance + * @retval Value between Min_Data=0x00 and Max_Data=0x59 + */ +__STATIC_INLINE uint32_t LL_RTC_ALMA_GetSecond(const RTC_TypeDef *RTCx) +{ + return (uint32_t)((READ_BIT(RTCx->ALRMAR, (RTC_ALRMAR_ST | RTC_ALRMAR_SU))) >> RTC_ALRMAR_SU_Pos); +} + +/** + * @brief Set Alarm A Time (hour, minute and second) in BCD format + * @rmtoll RTC_ALRMAR PM LL_RTC_ALMA_ConfigTime\n + * RTC_ALRMAR HT LL_RTC_ALMA_ConfigTime\n + * RTC_ALRMAR HU LL_RTC_ALMA_ConfigTime\n + * RTC_ALRMAR MNT LL_RTC_ALMA_ConfigTime\n + * RTC_ALRMAR MNU LL_RTC_ALMA_ConfigTime\n + * RTC_ALRMAR ST LL_RTC_ALMA_ConfigTime\n + * RTC_ALRMAR SU LL_RTC_ALMA_ConfigTime + * @param RTCx RTC Instance + * @param Format12_24 This parameter can be one of the following values: + * @arg @ref LL_RTC_ALMA_TIME_FORMAT_AM + * @arg @ref LL_RTC_ALMA_TIME_FORMAT_PM + * @param Hours Value between Min_Data=0x01 and Max_Data=0x12 or between Min_Data=0x00 and Max_Data=0x23 + * @param Minutes Value between Min_Data=0x00 and Max_Data=0x59 + * @param Seconds Value between Min_Data=0x00 and Max_Data=0x59 + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMA_ConfigTime(RTC_TypeDef *RTCx, + uint32_t Format12_24, + uint32_t Hours, + uint32_t Minutes, + uint32_t Seconds) +{ + uint32_t temp; + + temp = Format12_24 | (((Hours & 0xF0U) << (RTC_ALRMAR_HT_Pos - 4U)) | ((Hours & 0x0FU) << RTC_ALRMAR_HU_Pos)) | \ + (((Minutes & 0xF0U) << (RTC_ALRMAR_MNT_Pos - 4U)) | ((Minutes & 0x0FU) << RTC_ALRMAR_MNU_Pos)) | \ + (((Seconds & 0xF0U) << (RTC_ALRMAR_ST_Pos - 4U)) | ((Seconds & 0x0FU) << RTC_ALRMAR_SU_Pos)); + + MODIFY_REG(RTCx->ALRMAR, RTC_ALRMAR_PM | RTC_ALRMAR_HT | RTC_ALRMAR_HU | RTC_ALRMAR_MNT | RTC_ALRMAR_MNU | \ + RTC_ALRMAR_ST | RTC_ALRMAR_SU, temp); +} + +/** + * @brief Get Alarm B Time (hour, minute and second) in BCD format + * @note helper macros __LL_RTC_GET_HOUR, __LL_RTC_GET_MINUTE and __LL_RTC_GET_SECOND + * are available to get independently each parameter. + * @rmtoll RTC_ALRMAR HT LL_RTC_ALMA_GetTime\n + * RTC_ALRMAR HU LL_RTC_ALMA_GetTime\n + * RTC_ALRMAR MNT LL_RTC_ALMA_GetTime\n + * RTC_ALRMAR MNU LL_RTC_ALMA_GetTime\n + * RTC_ALRMAR ST LL_RTC_ALMA_GetTime\n + * RTC_ALRMAR SU LL_RTC_ALMA_GetTime + * @param RTCx RTC Instance + * @retval Combination of hours, minutes and seconds. + */ +__STATIC_INLINE uint32_t LL_RTC_ALMA_GetTime(const RTC_TypeDef *RTCx) +{ + return (uint32_t)((LL_RTC_ALMA_GetHour(RTCx) << RTC_OFFSET_HOUR) | + (LL_RTC_ALMA_GetMinute(RTCx) << RTC_OFFSET_MINUTE) | LL_RTC_ALMA_GetSecond(RTCx)); +} + +/** + * @brief Set Alarm A Mask the most-significant bits starting at this bit + * @note This register can be written only when ALRAE is reset in RTC_CR register, + * or in initialization mode. + * @rmtoll RTC_ALRMASSR MASKSS LL_RTC_ALMA_SetSubSecondMask + * @param RTCx RTC Instance + * @param Mask If binary mode is none, Value between Min_Data=0x0 and Max_Data=0xF + * else Value between Min_Data=0x0 and Max_Data=0x3F + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMA_SetSubSecondMask(RTC_TypeDef *RTCx, uint32_t Mask) +{ + MODIFY_REG(RTCx->ALRMASSR, RTC_ALRMASSR_MASKSS, Mask << RTC_ALRMASSR_MASKSS_Pos); +} + +/** + * @brief Get Alarm A Mask the most-significant bits starting at this bit + * @rmtoll RTC_ALRMASSR MASKSS LL_RTC_ALMA_GetSubSecondMask + * @param RTCx RTC Instance + * @retval If binary mode is none, Value between Min_Data=0x0 and Max_Data=0xF + * else Value between Min_Data=0x0 and Max_Data=0x3F + */ +__STATIC_INLINE uint32_t LL_RTC_ALMA_GetSubSecondMask(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->ALRMASSR, RTC_ALRMASSR_MASKSS) >> RTC_ALRMASSR_MASKSS_Pos); +} + +/** + * @brief Set Alarm A Binary mode auto clear + * @note This register can be written only when ALRAE is reset in RTC_CR register, + * or in initialization mode. + * @rmtoll RTC_ALRABINR SSCLR LL_RTC_ALMA_SetBinAutoClr + * @param RTCx RTC Instance + * @param BinaryAutoClr This parameter can be one of the following values: + * @arg @ref LL_RTC_ALMA_SUBSECONDBIN_AUTOCLR_NO + * @arg @ref LL_RTC_ALMA_SUBSECONDBIN_AUTOCLR_YES + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMA_SetBinAutoClr(RTC_TypeDef *RTCx, uint32_t BinaryAutoClr) +{ + MODIFY_REG(RTCx->ALRMASSR, RTC_ALRMASSR_SSCLR, BinaryAutoClr); +} + +/** + * @brief Get Alarm A Binary mode auto clear + * @rmtoll RTC_ALRABINR SSCLR LL_RTC_ALMA_GetBinAutoClr + * @param RTCx RTC Instance + * @retval It can be one of the following values: + * @arg @ref LL_RTC_ALMA_SUBSECONDBIN_AUTOCLR_NO + * @arg @ref LL_RTC_ALMA_SUBSECONDBIN_AUTOCLR_YES + */ +__STATIC_INLINE uint32_t LL_RTC_ALMA_GetBinAutoClr(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->ALRMASSR, RTC_ALRMASSR_SSCLR)); +} + +/** + * @brief Set Alarm A Sub seconds value + * @rmtoll RCT_ALRMASSR SS LL_RTC_ALMA_SetSubSecond + * @param RTCx RTC Instance + * @param Subsecond If binary mode is none, Value between Min_Data=0x0 and Max_Data=0x7FFF + * else Value between Min_Data=0x0 and Max_Data=0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMA_SetSubSecond(RTC_TypeDef *RTCx, uint32_t Subsecond) +{ + MODIFY_REG(RTCx->ALRMASSR, RTC_ALRMASSR_SS, Subsecond); +} + +/** + * @brief Get Alarm A Sub seconds value + * @rmtoll RCT_ALRMASSR SS LL_RTC_ALMA_GetSubSecond + * @param RTCx RTC Instance + * @retval If binary mode is none, Value between Min_Data=0x0 and Max_Data=0x7FFF + * else Value between Min_Data=0x0 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_RTC_ALMA_GetSubSecond(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->ALRMASSR, RTC_ALRMASSR_SS)); +} + +/** + * @} + */ + +/** @defgroup RTC_LL_EF_ALARMB ALARMB + * @{ + */ + +/** + * @brief Enable Alarm B + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR ALRBE LL_RTC_ALMB_Enable + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMB_Enable(RTC_TypeDef *RTCx) +{ + SET_BIT(RTCx->CR, RTC_CR_ALRBE); +} + +/** + * @brief Disable Alarm B + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR ALRBE LL_RTC_ALMB_Disable + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMB_Disable(RTC_TypeDef *RTCx) +{ + CLEAR_BIT(RTCx->CR, RTC_CR_ALRBE); +} + +/** + * @brief Specify the Alarm B masks. + * @rmtoll RTC_ALRMBR MSK4 LL_RTC_ALMB_SetMask\n + * RTC_ALRMBR MSK3 LL_RTC_ALMB_SetMask\n + * RTC_ALRMBR MSK2 LL_RTC_ALMB_SetMask\n + * RTC_ALRMBR MSK1 LL_RTC_ALMB_SetMask + * @param RTCx RTC Instance + * @param Mask This parameter can be a combination of the following values: + * @arg @ref LL_RTC_ALMB_MASK_NONE + * @arg @ref LL_RTC_ALMB_MASK_DATEWEEKDAY + * @arg @ref LL_RTC_ALMB_MASK_HOURS + * @arg @ref LL_RTC_ALMB_MASK_MINUTES + * @arg @ref LL_RTC_ALMB_MASK_SECONDS + * @arg @ref LL_RTC_ALMB_MASK_ALL + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMB_SetMask(RTC_TypeDef *RTCx, uint32_t Mask) +{ + MODIFY_REG(RTCx->ALRMBR, RTC_ALRMBR_MSK4 | RTC_ALRMBR_MSK3 | RTC_ALRMBR_MSK2 | RTC_ALRMBR_MSK1, Mask); +} + +/** + * @brief Get the Alarm B masks. + * @rmtoll RTC_ALRMBR MSK4 LL_RTC_ALMB_GetMask\n + * RTC_ALRMBR MSK3 LL_RTC_ALMB_GetMask\n + * RTC_ALRMBR MSK2 LL_RTC_ALMB_GetMask\n + * RTC_ALRMBR MSK1 LL_RTC_ALMB_GetMask + * @param RTCx RTC Instance + * @retval Returned value can be can be a combination of the following values: + * @arg @ref LL_RTC_ALMB_MASK_NONE + * @arg @ref LL_RTC_ALMB_MASK_DATEWEEKDAY + * @arg @ref LL_RTC_ALMB_MASK_HOURS + * @arg @ref LL_RTC_ALMB_MASK_MINUTES + * @arg @ref LL_RTC_ALMB_MASK_SECONDS + * @arg @ref LL_RTC_ALMB_MASK_ALL + */ +__STATIC_INLINE uint32_t LL_RTC_ALMB_GetMask(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->ALRMBR, RTC_ALRMBR_MSK4 | RTC_ALRMBR_MSK3 | RTC_ALRMBR_MSK2 | RTC_ALRMBR_MSK1)); +} + +/** + * @brief Enable AlarmB Week day selection (DU[3:0] represents the week day. DT[1:0] is do not care) + * @rmtoll RTC_ALRMBR WDSEL LL_RTC_ALMB_EnableWeekday + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMB_EnableWeekday(RTC_TypeDef *RTCx) +{ + SET_BIT(RTCx->ALRMBR, RTC_ALRMBR_WDSEL); +} + +/** + * @brief Disable AlarmB Week day selection (DU[3:0] represents the date ) + * @rmtoll RTC_ALRMBR WDSEL LL_RTC_ALMB_DisableWeekday + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMB_DisableWeekday(RTC_TypeDef *RTCx) +{ + CLEAR_BIT(RTCx->ALRMBR, RTC_ALRMBR_WDSEL); +} + +/** + * @brief Set ALARM B Day in BCD format + * @note helper macro __LL_RTC_CONVERT_BIN2BCD is available to convert Day from binary to BCD format + * @rmtoll RTC_ALRMBR DT LL_RTC_ALMB_SetDay\n + * RTC_ALRMBR DU LL_RTC_ALMB_SetDay + * @param RTCx RTC Instance + * @param Day Value between Min_Data=0x01 and Max_Data=0x31 + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMB_SetDay(RTC_TypeDef *RTCx, uint32_t Day) +{ + MODIFY_REG(RTCx->ALRMBR, (RTC_ALRMBR_DT | RTC_ALRMBR_DU), + (((Day & 0xF0U) << (RTC_ALRMBR_DT_Pos - 4U)) | ((Day & 0x0FU) << RTC_ALRMBR_DU_Pos))); +} + +/** + * @brief Get ALARM B Day in BCD format + * @note helper macro __LL_RTC_CONVERT_BCD2BIN is available to convert Day from BCD to Binary format + * @rmtoll RTC_ALRMBR DT LL_RTC_ALMB_GetDay\n + * RTC_ALRMBR DU LL_RTC_ALMB_GetDay + * @param RTCx RTC Instance + * @retval Value between Min_Data=0x01 and Max_Data=0x31 + */ +__STATIC_INLINE uint32_t LL_RTC_ALMB_GetDay(const RTC_TypeDef *RTCx) +{ + return (uint32_t)((READ_BIT(RTCx->ALRMBR, (RTC_ALRMBR_DT | RTC_ALRMBR_DU))) >> RTC_ALRMBR_DU_Pos); +} + +/** + * @brief Set ALARM B Weekday + * @rmtoll RTC_ALRMBR DU LL_RTC_ALMB_SetWeekDay + * @param RTCx RTC Instance + * @param WeekDay This parameter can be one of the following values: + * @arg @ref LL_RTC_WEEKDAY_MONDAY + * @arg @ref LL_RTC_WEEKDAY_TUESDAY + * @arg @ref LL_RTC_WEEKDAY_WEDNESDAY + * @arg @ref LL_RTC_WEEKDAY_THURSDAY + * @arg @ref LL_RTC_WEEKDAY_FRIDAY + * @arg @ref LL_RTC_WEEKDAY_SATURDAY + * @arg @ref LL_RTC_WEEKDAY_SUNDAY + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMB_SetWeekDay(RTC_TypeDef *RTCx, uint32_t WeekDay) +{ + MODIFY_REG(RTCx->ALRMBR, RTC_ALRMBR_DU, WeekDay << RTC_ALRMBR_DU_Pos); +} + +/** + * @brief Get ALARM B Weekday + * @rmtoll RTC_ALRMBR DU LL_RTC_ALMB_GetWeekDay + * @param RTCx RTC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_RTC_WEEKDAY_MONDAY + * @arg @ref LL_RTC_WEEKDAY_TUESDAY + * @arg @ref LL_RTC_WEEKDAY_WEDNESDAY + * @arg @ref LL_RTC_WEEKDAY_THURSDAY + * @arg @ref LL_RTC_WEEKDAY_FRIDAY + * @arg @ref LL_RTC_WEEKDAY_SATURDAY + * @arg @ref LL_RTC_WEEKDAY_SUNDAY + */ +__STATIC_INLINE uint32_t LL_RTC_ALMB_GetWeekDay(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->ALRMBR, RTC_ALRMBR_DU) >> RTC_ALRMBR_DU_Pos); +} + +/** + * @brief Set ALARM B time format (AM/24-hour or PM notation) + * @rmtoll RTC_ALRMBR PM LL_RTC_ALMB_SetTimeFormat + * @param RTCx RTC Instance + * @param TimeFormat This parameter can be one of the following values: + * @arg @ref LL_RTC_ALMB_TIME_FORMAT_AM + * @arg @ref LL_RTC_ALMB_TIME_FORMAT_PM + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMB_SetTimeFormat(RTC_TypeDef *RTCx, uint32_t TimeFormat) +{ + MODIFY_REG(RTCx->ALRMBR, RTC_ALRMBR_PM, TimeFormat); +} + +/** + * @brief Get ALARM B time format (AM or PM notation) + * @rmtoll RTC_ALRMBR PM LL_RTC_ALMB_GetTimeFormat + * @param RTCx RTC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_RTC_ALMB_TIME_FORMAT_AM + * @arg @ref LL_RTC_ALMB_TIME_FORMAT_PM + */ +__STATIC_INLINE uint32_t LL_RTC_ALMB_GetTimeFormat(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->ALRMBR, RTC_ALRMBR_PM)); +} + +/** + * @brief Set ALARM B Hours in BCD format + * @note helper macro __LL_RTC_CONVERT_BIN2BCD is available to convert Hours from binary to BCD format + * @rmtoll RTC_ALRMBR HT LL_RTC_ALMB_SetHour\n + * RTC_ALRMBR HU LL_RTC_ALMB_SetHour + * @param RTCx RTC Instance + * @param Hours Value between Min_Data=0x01 and Max_Data=0x12 or between Min_Data=0x00 and Max_Data=0x23 + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMB_SetHour(RTC_TypeDef *RTCx, uint32_t Hours) +{ + MODIFY_REG(RTCx->ALRMBR, (RTC_ALRMBR_HT | RTC_ALRMBR_HU), + (((Hours & 0xF0U) << (RTC_ALRMBR_HT_Pos - 4U)) | ((Hours & 0x0FU) << RTC_ALRMBR_HU_Pos))); +} + +/** + * @brief Get ALARM B Hours in BCD format + * @note helper macro __LL_RTC_CONVERT_BCD2BIN is available to convert Hours from BCD to Binary format + * @rmtoll RTC_ALRMBR HT LL_RTC_ALMB_GetHour\n + * RTC_ALRMBR HU LL_RTC_ALMB_GetHour + * @param RTCx RTC Instance + * @retval Value between Min_Data=0x01 and Max_Data=0x12 or between Min_Data=0x00 and Max_Data=0x23 + */ +__STATIC_INLINE uint32_t LL_RTC_ALMB_GetHour(const RTC_TypeDef *RTCx) +{ + return (uint32_t)((READ_BIT(RTCx->ALRMBR, (RTC_ALRMBR_HT | RTC_ALRMBR_HU))) >> RTC_ALRMBR_HU_Pos); +} + +/** + * @brief Set ALARM B Minutes in BCD format + * @note helper macro __LL_RTC_CONVERT_BIN2BCD is available to convert Minutes from binary to BCD format + * @rmtoll RTC_ALRMBR MNT LL_RTC_ALMB_SetMinute\n + * RTC_ALRMBR MNU LL_RTC_ALMB_SetMinute + * @param RTCx RTC Instance + * @param Minutes between Min_Data=0x00 and Max_Data=0x59 + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMB_SetMinute(RTC_TypeDef *RTCx, uint32_t Minutes) +{ + MODIFY_REG(RTCx->ALRMBR, (RTC_ALRMBR_MNT | RTC_ALRMBR_MNU), + (((Minutes & 0xF0U) << (RTC_ALRMBR_MNT_Pos - 4U)) | ((Minutes & 0x0FU) << RTC_ALRMBR_MNU_Pos))); +} + +/** + * @brief Get ALARM B Minutes in BCD format + * @note helper macro __LL_RTC_CONVERT_BCD2BIN is available to convert Minutes from BCD to Binary format + * @rmtoll RTC_ALRMBR MNT LL_RTC_ALMB_GetMinute\n + * RTC_ALRMBR MNU LL_RTC_ALMB_GetMinute + * @param RTCx RTC Instance + * @retval Value between Min_Data=0x00 and Max_Data=0x59 + */ +__STATIC_INLINE uint32_t LL_RTC_ALMB_GetMinute(const RTC_TypeDef *RTCx) +{ + return (uint32_t)((READ_BIT(RTCx->ALRMBR, (RTC_ALRMBR_MNT | RTC_ALRMBR_MNU))) >> RTC_ALRMBR_MNU_Pos); +} + +/** + * @brief Set ALARM B Seconds in BCD format + * @note helper macro __LL_RTC_CONVERT_BIN2BCD is available to convert Seconds from binary to BCD format + * @rmtoll RTC_ALRMBR ST LL_RTC_ALMB_SetSecond\n + * RTC_ALRMBR SU LL_RTC_ALMB_SetSecond + * @param RTCx RTC Instance + * @param Seconds Value between Min_Data=0x00 and Max_Data=0x59 + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMB_SetSecond(RTC_TypeDef *RTCx, uint32_t Seconds) +{ + MODIFY_REG(RTCx->ALRMBR, (RTC_ALRMBR_ST | RTC_ALRMBR_SU), + (((Seconds & 0xF0U) << (RTC_ALRMBR_ST_Pos - 4U)) | ((Seconds & 0x0FU) << RTC_ALRMBR_SU_Pos))); +} + +/** + * @brief Get ALARM B Seconds in BCD format + * @note helper macro __LL_RTC_CONVERT_BCD2BIN is available to convert Seconds from BCD to Binary format + * @rmtoll RTC_ALRMBR ST LL_RTC_ALMB_GetSecond\n + * RTC_ALRMBR SU LL_RTC_ALMB_GetSecond + * @param RTCx RTC Instance + * @retval Value between Min_Data=0x00 and Max_Data=0x59 + */ +__STATIC_INLINE uint32_t LL_RTC_ALMB_GetSecond(const RTC_TypeDef *RTCx) +{ + return (uint32_t)((READ_BIT(RTCx->ALRMBR, (RTC_ALRMBR_ST | RTC_ALRMBR_SU))) >> RTC_ALRMBR_SU_Pos); +} + +/** + * @brief Set Alarm B Time (hour, minute and second) in BCD format + * @rmtoll RTC_ALRMBR PM LL_RTC_ALMB_ConfigTime\n + * RTC_ALRMBR HT LL_RTC_ALMB_ConfigTime\n + * RTC_ALRMBR HU LL_RTC_ALMB_ConfigTime\n + * RTC_ALRMBR MNT LL_RTC_ALMB_ConfigTime\n + * RTC_ALRMBR MNU LL_RTC_ALMB_ConfigTime\n + * RTC_ALRMBR ST LL_RTC_ALMB_ConfigTime\n + * RTC_ALRMBR SU LL_RTC_ALMB_ConfigTime + * @param RTCx RTC Instance + * @param Format12_24 This parameter can be one of the following values: + * @arg @ref LL_RTC_ALMB_TIME_FORMAT_AM + * @arg @ref LL_RTC_ALMB_TIME_FORMAT_PM + * @param Hours Value between Min_Data=0x01 and Max_Data=0x12 or between Min_Data=0x00 and Max_Data=0x23 + * @param Minutes Value between Min_Data=0x00 and Max_Data=0x59 + * @param Seconds Value between Min_Data=0x00 and Max_Data=0x59 + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMB_ConfigTime(RTC_TypeDef *RTCx, + uint32_t Format12_24, + uint32_t Hours, + uint32_t Minutes, + uint32_t Seconds) +{ + uint32_t temp; + + temp = Format12_24 | (((Hours & 0xF0U) << (RTC_ALRMBR_HT_Pos - 4U)) | ((Hours & 0x0FU) << RTC_ALRMBR_HU_Pos)) | \ + (((Minutes & 0xF0U) << (RTC_ALRMBR_MNT_Pos - 4U)) | ((Minutes & 0x0FU) << RTC_ALRMBR_MNU_Pos)) | \ + (((Seconds & 0xF0U) << (RTC_ALRMBR_ST_Pos - 4U)) | ((Seconds & 0x0FU) << RTC_ALRMBR_SU_Pos)); + + MODIFY_REG(RTCx->ALRMBR, RTC_ALRMBR_PM | RTC_ALRMBR_HT | RTC_ALRMBR_HU | RTC_ALRMBR_MNT | RTC_ALRMBR_MNU | \ + RTC_ALRMBR_ST | RTC_ALRMBR_SU, temp); +} + +/** + * @brief Get Alarm B Time (hour, minute and second) in BCD format + * @note helper macros __LL_RTC_GET_HOUR, __LL_RTC_GET_MINUTE and __LL_RTC_GET_SECOND + * are available to get independently each parameter. + * @rmtoll RTC_ALRMBR HT LL_RTC_ALMB_GetTime\n + * RTC_ALRMBR HU LL_RTC_ALMB_GetTime\n + * RTC_ALRMBR MNT LL_RTC_ALMB_GetTime\n + * RTC_ALRMBR MNU LL_RTC_ALMB_GetTime\n + * RTC_ALRMBR ST LL_RTC_ALMB_GetTime\n + * RTC_ALRMBR SU LL_RTC_ALMB_GetTime + * @param RTCx RTC Instance + * @retval Combination of hours, minutes and seconds. + */ +__STATIC_INLINE uint32_t LL_RTC_ALMB_GetTime(const RTC_TypeDef *RTCx) +{ + return (uint32_t)((LL_RTC_ALMB_GetHour(RTCx) << RTC_OFFSET_HOUR) | \ + (LL_RTC_ALMB_GetMinute(RTCx) << RTC_OFFSET_MINUTE) | LL_RTC_ALMB_GetSecond(RTCx)); +} + +/** + * @brief Set Alarm B Mask the most-significant bits starting at this bit + * @note This register can be written only when ALRBE is reset in RTC_CR register, + * or in initialization mode. + * @rmtoll RTC_ALRMBSSR MASKSS LL_RTC_ALMB_SetSubSecondMask + * @param RTCx RTC Instance + * @param Mask If binary mode is none, Value between Min_Data=0x0 and Max_Data=0xF + * else Value between Min_Data=0x0 and Max_Data=0x3F + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMB_SetSubSecondMask(RTC_TypeDef *RTCx, uint32_t Mask) +{ + MODIFY_REG(RTCx->ALRMBSSR, RTC_ALRMBSSR_MASKSS, Mask << RTC_ALRMBSSR_MASKSS_Pos); +} + +/** + * @brief Get Alarm B Mask the most-significant bits starting at this bit + * @rmtoll RTC_ALRMBSSR MASKSS LL_RTC_ALMB_GetSubSecondMask + * @param RTCx RTC Instance + * @retval If binary mode is none, Value between Min_Data=0x0 and Max_Data=0xF + * else Value between Min_Data=0x0 and Max_Data=0x3F + */ +__STATIC_INLINE uint32_t LL_RTC_ALMB_GetSubSecondMask(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->ALRMBSSR, RTC_ALRMBSSR_MASKSS) >> RTC_ALRMBSSR_MASKSS_Pos); +} + +/** + * @brief Set Alarm B Binary mode auto clear + * @note This register can be written only when ALRBE is reset in RTC_CR register, + * or in initialization mode. + * @rmtoll RTC_ALRBBINR SSCLR LL_RTC_ALMB_SetBinAutoClr + * @param RTCx RTC Instance + * @param BinaryAutoClr This parameter can be one of the following values: + * @arg @ref LL_RTC_ALMB_SUBSECONDBIN_AUTOCLR_NO + * @arg @ref LL_RTC_ALMB_SUBSECONDBIN_AUTOCLR_YES + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMB_SetBinAutoClr(RTC_TypeDef *RTCx, uint32_t BinaryAutoClr) +{ + MODIFY_REG(RTCx->ALRMBSSR, RTC_ALRMBSSR_SSCLR, BinaryAutoClr); +} + +/** + * @brief Get Alarm B Binary mode auto clear + * @rmtoll RTC_ALRBBINR SSCLR LL_RTC_ALMB_GetBinAutoClr + * @param RTCx RTC Instance + * @retval It can be one of the following values: + * @arg @ref LL_RTC_ALMB_SUBSECONDBIN_AUTOCLR_NO + * @arg @ref LL_RTC_ALMB_SUBSECONDBIN_AUTOCLR_YES + */ +__STATIC_INLINE uint32_t LL_RTC_ALMB_GetBinAutoClr(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->ALRMBSSR, RTC_ALRMBSSR_SSCLR)); +} + +/** + * @brief Set Alarm B Sub seconds value + * @rmtoll RTC_ALRMBSSR SS LL_RTC_ALMB_SetSubSecond + * @param RTCx RTC Instance + * @param Subsecond If binary mode is none, Value between Min_Data=0x0 and Max_Data=0x7FFF + * else Value between Min_Data=0x0 and Max_Data=0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void LL_RTC_ALMB_SetSubSecond(RTC_TypeDef *RTCx, uint32_t Subsecond) +{ + MODIFY_REG(RTCx->ALRMBSSR, RTC_ALRMBSSR_SS, Subsecond); +} + +/** + * @brief Get Alarm B Sub seconds value + * @rmtoll RTC_ALRMBSSR SS LL_RTC_ALMB_GetSubSecond + * @param RTCx RTC Instance + * @retval If binary mode is none, Value between Min_Data=0x0 and Max_Data=0x7FFF + * else Value between Min_Data=0x0 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_RTC_ALMB_GetSubSecond(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->ALRMBSSR, RTC_ALRMBSSR_SS)); +} + +/** + * @} + */ + +/** @defgroup RTC_LL_EF_Timestamp Timestamp + * @{ + */ + +/** + * @brief Enable internal event timestamp + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR ITSE LL_RTC_TS_EnableInternalEvent + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_TS_EnableInternalEvent(RTC_TypeDef *RTCx) +{ + SET_BIT(RTCx->CR, RTC_CR_ITSE); +} + +/** + * @brief Disable internal event timestamp + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR ITSE LL_RTC_TS_DisableInternalEvent + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_TS_DisableInternalEvent(RTC_TypeDef *RTCx) +{ + CLEAR_BIT(RTCx->CR, RTC_CR_ITSE); +} + +#ifdef RTC_CR_TSE +/** + * @brief Enable Timestamp + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR TSE LL_RTC_TS_Enable + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_TS_Enable(RTC_TypeDef *RTCx) +{ + SET_BIT(RTCx->CR, RTC_CR_TSE); +} + +/** + * @brief Disable Timestamp + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR TSE LL_RTC_TS_Disable + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_TS_Disable(RTC_TypeDef *RTCx) +{ + CLEAR_BIT(RTCx->CR, RTC_CR_TSE); +} +#endif /* RTC_CR_TSE */ + +#if defined(RTC_CR_TSEDGE) +/** + * @brief Set Time-stamp event active edge + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @note TSE must be reset when TSEDGE is changed to avoid unwanted TSF setting + * @rmtoll RTC_CR TSEDGE LL_RTC_TS_SetActiveEdge + * @param RTCx RTC Instance + * @param Edge This parameter can be one of the following values: + * @arg @ref LL_RTC_TIMESTAMP_EDGE_RISING + * @arg @ref LL_RTC_TIMESTAMP_EDGE_FALLING + * @retval None + */ +__STATIC_INLINE void LL_RTC_TS_SetActiveEdge(RTC_TypeDef *RTCx, uint32_t Edge) +{ + MODIFY_REG(RTCx->CR, RTC_CR_TSEDGE, Edge); +} + +/** + * @brief Get Time-stamp event active edge + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR TSEDGE LL_RTC_TS_GetActiveEdge + * @param RTCx RTC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_RTC_TIMESTAMP_EDGE_RISING + * @arg @ref LL_RTC_TIMESTAMP_EDGE_FALLING + */ +__STATIC_INLINE uint32_t LL_RTC_TS_GetActiveEdge(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->CR, RTC_CR_TSEDGE)); +} +#endif /* RTC_CR_TSEDGE */ + +/** + * @brief Get Timestamp AM/PM notation (AM or 24-hour format) + * @rmtoll RTC_TSTR PM LL_RTC_TS_GetTimeFormat + * @param RTCx RTC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_RTC_TS_TIME_FORMAT_AM + * @arg @ref LL_RTC_TS_TIME_FORMAT_PM + */ +__STATIC_INLINE uint32_t LL_RTC_TS_GetTimeFormat(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->TSTR, RTC_TSTR_PM)); +} + +/** + * @brief Get Timestamp Hours in BCD format + * @note helper macro __LL_RTC_CONVERT_BCD2BIN is available to convert Hours from BCD to Binary format + * @rmtoll RTC_TSTR HT LL_RTC_TS_GetHour\n + * RTC_TSTR HU LL_RTC_TS_GetHour + * @param RTCx RTC Instance + * @retval Value between Min_Data=0x01 and Max_Data=0x12 or between Min_Data=0x00 and Max_Data=0x23 + */ +__STATIC_INLINE uint32_t LL_RTC_TS_GetHour(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->TSTR, RTC_TSTR_HT | RTC_TSTR_HU) >> RTC_TSTR_HU_Pos); +} + +/** + * @brief Get Timestamp Minutes in BCD format + * @note helper macro __LL_RTC_CONVERT_BCD2BIN is available to convert Minutes from BCD to Binary format + * @rmtoll RTC_TSTR MNT LL_RTC_TS_GetMinute\n + * RTC_TSTR MNU LL_RTC_TS_GetMinute + * @param RTCx RTC Instance + * @retval Value between Min_Data=0x00 and Max_Data=0x59 + */ +__STATIC_INLINE uint32_t LL_RTC_TS_GetMinute(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->TSTR, RTC_TSTR_MNT | RTC_TSTR_MNU) >> RTC_TSTR_MNU_Pos); +} + +/** + * @brief Get Timestamp Seconds in BCD format + * @note helper macro __LL_RTC_CONVERT_BCD2BIN is available to convert Seconds from BCD to Binary format + * @rmtoll RTC_TSTR ST LL_RTC_TS_GetSecond\n + * RTC_TSTR SU LL_RTC_TS_GetSecond + * @param RTCx RTC Instance + * @retval Value between Min_Data=0x00 and Max_Data=0x59 + */ +__STATIC_INLINE uint32_t LL_RTC_TS_GetSecond(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->TSTR, RTC_TSTR_ST | RTC_TSTR_SU)); +} + +/** + * @brief Get Timestamp time (hour, minute and second) in BCD format + * @note helper macros __LL_RTC_GET_HOUR, __LL_RTC_GET_MINUTE and __LL_RTC_GET_SECOND + * are available to get independently each parameter. + * @rmtoll RTC_TSTR HT LL_RTC_TS_GetTime\n + * RTC_TSTR HU LL_RTC_TS_GetTime\n + * RTC_TSTR MNT LL_RTC_TS_GetTime\n + * RTC_TSTR MNU LL_RTC_TS_GetTime\n + * RTC_TSTR ST LL_RTC_TS_GetTime\n + * RTC_TSTR SU LL_RTC_TS_GetTime + * @param RTCx RTC Instance + * @retval Combination of hours, minutes and seconds. + */ +__STATIC_INLINE uint32_t LL_RTC_TS_GetTime(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->TSTR, + RTC_TSTR_HT | RTC_TSTR_HU | RTC_TSTR_MNT | RTC_TSTR_MNU | RTC_TSTR_ST | RTC_TSTR_SU)); +} + +/** + * @brief Get Timestamp Week day + * @rmtoll RTC_TSDR WDU LL_RTC_TS_GetWeekDay + * @param RTCx RTC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_RTC_WEEKDAY_MONDAY + * @arg @ref LL_RTC_WEEKDAY_TUESDAY + * @arg @ref LL_RTC_WEEKDAY_WEDNESDAY + * @arg @ref LL_RTC_WEEKDAY_THURSDAY + * @arg @ref LL_RTC_WEEKDAY_FRIDAY + * @arg @ref LL_RTC_WEEKDAY_SATURDAY + * @arg @ref LL_RTC_WEEKDAY_SUNDAY + */ +__STATIC_INLINE uint32_t LL_RTC_TS_GetWeekDay(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->TSDR, RTC_TSDR_WDU) >> RTC_TSDR_WDU_Pos); +} + +/** + * @brief Get Timestamp Month in BCD format + * @note helper macro __LL_RTC_CONVERT_BCD2BIN is available to convert Month from BCD to Binary format + * @rmtoll RTC_TSDR MT LL_RTC_TS_GetMonth\n + * RTC_TSDR MU LL_RTC_TS_GetMonth + * @param RTCx RTC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_RTC_MONTH_JANUARY + * @arg @ref LL_RTC_MONTH_FEBRUARY + * @arg @ref LL_RTC_MONTH_MARCH + * @arg @ref LL_RTC_MONTH_APRIL + * @arg @ref LL_RTC_MONTH_MAY + * @arg @ref LL_RTC_MONTH_JUNE + * @arg @ref LL_RTC_MONTH_JULY + * @arg @ref LL_RTC_MONTH_AUGUST + * @arg @ref LL_RTC_MONTH_SEPTEMBER + * @arg @ref LL_RTC_MONTH_OCTOBER + * @arg @ref LL_RTC_MONTH_NOVEMBER + * @arg @ref LL_RTC_MONTH_DECEMBER + */ +__STATIC_INLINE uint32_t LL_RTC_TS_GetMonth(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->TSDR, RTC_TSDR_MT | RTC_TSDR_MU) >> RTC_TSDR_MU_Pos); +} + +/** + * @brief Get Timestamp Day in BCD format + * @note helper macro __LL_RTC_CONVERT_BCD2BIN is available to convert Day from BCD to Binary format + * @rmtoll RTC_TSDR DT LL_RTC_TS_GetDay\n + * RTC_TSDR DU LL_RTC_TS_GetDay + * @param RTCx RTC Instance + * @retval Value between Min_Data=0x01 and Max_Data=0x31 + */ +__STATIC_INLINE uint32_t LL_RTC_TS_GetDay(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->TSDR, RTC_TSDR_DT | RTC_TSDR_DU)); +} + +/** + * @brief Get Timestamp date (WeekDay, Day and Month) in BCD format + * @note helper macros __LL_RTC_GET_WEEKDAY, __LL_RTC_GET_MONTH, + * and __LL_RTC_GET_DAY are available to get independently each parameter. + * @rmtoll RTC_TSDR WDU LL_RTC_TS_GetDate\n + * RTC_TSDR MT LL_RTC_TS_GetDate\n + * RTC_TSDR MU LL_RTC_TS_GetDate\n + * RTC_TSDR DT LL_RTC_TS_GetDate\n + * RTC_TSDR DU LL_RTC_TS_GetDate + * @param RTCx RTC Instance + * @retval Combination of Weekday, Day and Month + */ +__STATIC_INLINE uint32_t LL_RTC_TS_GetDate(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->TSDR, RTC_TSDR_WDU | RTC_TSDR_MT | RTC_TSDR_MU | RTC_TSDR_DT | RTC_TSDR_DU)); +} + +/** + * @brief Get time-stamp sub second value + * @rmtoll RTC_TSDR SS LL_RTC_TS_GetSubSecond + * @param RTCx RTC Instance + * @retval If binary mode is none, Value between Min_Data=0x0 and Max_Data=0x7FFF + * else Value between Min_Data=0x0 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_RTC_TS_GetSubSecond(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->TSSSR, RTC_TSSSR_SS)); +} + +/** + * @brief Activate timestamp on tamper detection event + * @rmtoll RTC_CR TAMPTS LL_RTC_TS_EnableOnTamper + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_TS_EnableOnTamper(RTC_TypeDef *RTCx) +{ + SET_BIT(RTCx->CR, RTC_CR_TAMPTS); +} + +/** + * @brief Disable timestamp on tamper detection event + * @rmtoll RTC_CR TAMPTS LL_RTC_TS_DisableOnTamper + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_TS_DisableOnTamper(RTC_TypeDef *RTCx) +{ + CLEAR_BIT(RTCx->CR, RTC_CR_TAMPTS); +} + + +/** + * @} + */ + +/** @defgroup RTC_LL_EF_Tamper Tamper + * @{ + */ + +/** + * @brief Enable TAMPx input detection + * @rmtoll TAMP_CR1 TAMP1E LL_RTC_TAMPER_Enable\n + * TAMP_CR1 TAMP2E... LL_RTC_TAMPER_Enable\n + * @param RTCx RTC Instance + * @param Tamper This parameter can be a combination of the following values: + * @arg @ref RTC_LL_EC_TAMPER + * + * @retval None + */ +__STATIC_INLINE void LL_RTC_TAMPER_Enable(const RTC_TypeDef *RTCx, uint32_t Tamper) +{ + UNUSED(RTCx); + SET_BIT(TAMP->CR1, Tamper); +} + +/** + * @brief Clear TAMPx input detection + * @rmtoll TAMP_CR1 TAMP1E LL_RTC_TAMPER_Disable\n + * TAMP_CR1 TAMP2E... LL_RTC_TAMPER_Disable + * @param RTCx RTC Instance + * @param Tamper This parameter can be a combination of the following values: + * @arg @ref RTC_LL_EC_TAMPER + * + * @retval None + */ +__STATIC_INLINE void LL_RTC_TAMPER_Disable(const RTC_TypeDef *RTCx, uint32_t Tamper) +{ + UNUSED(RTCx); + CLEAR_BIT(TAMP->CR1, Tamper); +} + +/** + * @brief Enable Tamper mask flag + * @note Associated Tamper IT must not enabled when tamper mask is set. + * @rmtoll TAMP_CR2 TAMP1MF LL_RTC_TAMPER_EnableMask\n + * TAMP_CR2 TAMP2MF... LL_RTC_TAMPER_EnableMask + * @param RTCx RTC Instance + * @param Mask This parameter can be a combination of the following values: + * @arg @ref RTC_LL_EC_TAMPER_MASK + * + * @retval None + */ +__STATIC_INLINE void LL_RTC_TAMPER_EnableMask(const RTC_TypeDef *RTCx, uint32_t Mask) +{ + UNUSED(RTCx); + SET_BIT(TAMP->CR2, Mask); +} + +/** + * @brief Disable Tamper mask flag + * @rmtoll TAMP_CR2 TAMP1MF LL_RTC_TAMPER_DisableMask\n + * TAMP_CR2 TAMP2MF... LL_RTC_TAMPER_DisableMask + * @param RTCx RTC Instance + * @param Mask This parameter can be a combination of the following values: + * @arg @ref RTC_LL_EC_TAMPER_MASK + * + * @retval None + */ +__STATIC_INLINE void LL_RTC_TAMPER_DisableMask(const RTC_TypeDef *RTCx, uint32_t Mask) +{ + UNUSED(RTCx); + CLEAR_BIT(TAMP->CR2, Mask); +} + +/** + * @brief Enable backup register erase after Tamper event detection + * @rmtoll TAMP_CR2 TAMP1NOERASE LL_RTC_TAMPER_EnableEraseBKP\n + * TAMP_CR2 TAMP2NOERASE... LL_RTC_TAMPER_EnableEraseBKP + * @param RTCx RTC Instance + * @param Tamper This parameter can be a combination of the following values: + * @arg @ref RTC_LL_EC_TAMPER_NOERASE + * + * @retval None + */ +__STATIC_INLINE void LL_RTC_TAMPER_EnableEraseBKP(const RTC_TypeDef *RTCx, uint32_t Tamper) +{ + UNUSED(RTCx); + CLEAR_BIT(TAMP->CR2, Tamper); +} + +/** + * @brief Disable backup register erase after Tamper event detection + * @rmtoll TAMP_CR2 TAMP1NOERASE LL_RTC_TAMPER_DisableEraseBKP\n + * TAMP_CR2 TAMP2NOERASE... LL_RTC_TAMPER_DisableEraseBKP + * @param RTCx RTC Instance + * @param Tamper This parameter can be a combination of the following values: + * @arg @ref RTC_LL_EC_TAMPER_NOERASE + * + * @retval None + */ +__STATIC_INLINE void LL_RTC_TAMPER_DisableEraseBKP(const RTC_TypeDef *RTCx, uint32_t Tamper) +{ + UNUSED(RTCx); + SET_BIT(TAMP->CR2, Tamper); +} + +/** + * @brief Disable RTC_TAMPx pull-up disable (Disable precharge of RTC_TAMPx pins) + * @rmtoll TAMP_FLTCR TAMPPUDIS LL_RTC_TAMPER_DisablePullUp + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_TAMPER_DisablePullUp(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + SET_BIT(TAMP->FLTCR, TAMP_FLTCR_TAMPPUDIS); +} + +/** + * @brief Enable RTC_TAMPx pull-up disable ( Precharge RTC_TAMPx pins before sampling) + * @rmtoll TAMP_FLTCR TAMPPUDIS LL_RTC_TAMPER_EnablePullUp + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_TAMPER_EnablePullUp(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + CLEAR_BIT(TAMP->FLTCR, TAMP_FLTCR_TAMPPUDIS); +} + +/** + * @brief Set RTC_TAMPx precharge duration + * @rmtoll TAMP_FLTCR TAMPPRCH LL_RTC_TAMPER_SetPrecharge + * @param RTCx RTC Instance + * @param Duration This parameter can be one of the following values: + * @arg @ref LL_RTC_TAMPER_DURATION_1RTCCLK + * @arg @ref LL_RTC_TAMPER_DURATION_2RTCCLK + * @arg @ref LL_RTC_TAMPER_DURATION_4RTCCLK + * @arg @ref LL_RTC_TAMPER_DURATION_8RTCCLK + * @retval None + */ +__STATIC_INLINE void LL_RTC_TAMPER_SetPrecharge(const RTC_TypeDef *RTCx, uint32_t Duration) +{ + UNUSED(RTCx); + MODIFY_REG(TAMP->FLTCR, TAMP_FLTCR_TAMPPRCH, Duration); +} + +/** + * @brief Get RTC_TAMPx precharge duration + * @rmtoll TAMP_FLTCR TAMPPRCH LL_RTC_TAMPER_GetPrecharge + * @param RTCx RTC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_RTC_TAMPER_DURATION_1RTCCLK + * @arg @ref LL_RTC_TAMPER_DURATION_2RTCCLK + * @arg @ref LL_RTC_TAMPER_DURATION_4RTCCLK + * @arg @ref LL_RTC_TAMPER_DURATION_8RTCCLK + */ +__STATIC_INLINE uint32_t LL_RTC_TAMPER_GetPrecharge(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return (uint32_t)(READ_BIT(TAMP->FLTCR, TAMP_FLTCR_TAMPPRCH)); +} + +/** + * @brief Set RTC_TAMPx filter count + * @rmtoll TAMP_FLTCR TAMPFLT LL_RTC_TAMPER_SetFilterCount + * @param RTCx RTC Instance + * @param FilterCount This parameter can be one of the following values: + * @arg @ref LL_RTC_TAMPER_FILTER_DISABLE + * @arg @ref LL_RTC_TAMPER_FILTER_2SAMPLE + * @arg @ref LL_RTC_TAMPER_FILTER_4SAMPLE + * @arg @ref LL_RTC_TAMPER_FILTER_8SAMPLE + * @retval None + */ +__STATIC_INLINE void LL_RTC_TAMPER_SetFilterCount(const RTC_TypeDef *RTCx, uint32_t FilterCount) +{ + UNUSED(RTCx); + MODIFY_REG(TAMP->FLTCR, TAMP_FLTCR_TAMPFLT, FilterCount); +} + +/** + * @brief Get RTC_TAMPx filter count + * @rmtoll TAMP_FLTCR TAMPFLT LL_RTC_TAMPER_GetFilterCount + * @param RTCx RTC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_RTC_TAMPER_FILTER_DISABLE + * @arg @ref LL_RTC_TAMPER_FILTER_2SAMPLE + * @arg @ref LL_RTC_TAMPER_FILTER_4SAMPLE + * @arg @ref LL_RTC_TAMPER_FILTER_8SAMPLE + */ +__STATIC_INLINE uint32_t LL_RTC_TAMPER_GetFilterCount(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return (uint32_t)(READ_BIT(TAMP->FLTCR, TAMP_FLTCR_TAMPFLT)); +} + +/** + * @brief Set Tamper sampling frequency + * @rmtoll TAMP_FLTCR TAMPFREQ LL_RTC_TAMPER_SetSamplingFreq + * @param RTCx RTC Instance + * @param SamplingFreq This parameter can be one of the following values: + * @arg @ref LL_RTC_TAMPER_SAMPLFREQDIV_32768 + * @arg @ref LL_RTC_TAMPER_SAMPLFREQDIV_16384 + * @arg @ref LL_RTC_TAMPER_SAMPLFREQDIV_8192 + * @arg @ref LL_RTC_TAMPER_SAMPLFREQDIV_4096 + * @arg @ref LL_RTC_TAMPER_SAMPLFREQDIV_2048 + * @arg @ref LL_RTC_TAMPER_SAMPLFREQDIV_1024 + * @arg @ref LL_RTC_TAMPER_SAMPLFREQDIV_512 + * @arg @ref LL_RTC_TAMPER_SAMPLFREQDIV_256 + * @retval None + */ +__STATIC_INLINE void LL_RTC_TAMPER_SetSamplingFreq(const RTC_TypeDef *RTCx, uint32_t SamplingFreq) +{ + UNUSED(RTCx); + MODIFY_REG(TAMP->FLTCR, TAMP_FLTCR_TAMPFREQ, SamplingFreq); +} + +/** + * @brief Get Tamper sampling frequency + * @rmtoll TAMP_FLTCR TAMPFREQ LL_RTC_TAMPER_GetSamplingFreq + * @param RTCx RTC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_RTC_TAMPER_SAMPLFREQDIV_32768 + * @arg @ref LL_RTC_TAMPER_SAMPLFREQDIV_16384 + * @arg @ref LL_RTC_TAMPER_SAMPLFREQDIV_8192 + * @arg @ref LL_RTC_TAMPER_SAMPLFREQDIV_4096 + * @arg @ref LL_RTC_TAMPER_SAMPLFREQDIV_2048 + * @arg @ref LL_RTC_TAMPER_SAMPLFREQDIV_1024 + * @arg @ref LL_RTC_TAMPER_SAMPLFREQDIV_512 + * @arg @ref LL_RTC_TAMPER_SAMPLFREQDIV_256 + */ +__STATIC_INLINE uint32_t LL_RTC_TAMPER_GetSamplingFreq(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return (uint32_t)(READ_BIT(TAMP->FLTCR, TAMP_FLTCR_TAMPFREQ)); +} + +/** + * @brief Enable Active level for Tamper input + * @rmtoll TAMP_CR2 TAMP1TRG LL_RTC_TAMPER_EnableActiveLevel\n + * TAMP_CR2 TAMP2TRG LL_RTC_TAMPER_EnableActiveLevel\n + * TAMP_CR2 TAMPxTRG LL_RTC_TAMPER_EnableActiveLevel\n + * @param RTCx RTC Instance + * @param Tamper This parameter can be a combination of the following values: + * @arg @ref RTC_LL_EC_TAMPER_ACTIVELEVEL + * + * @retval None + */ +__STATIC_INLINE void LL_RTC_TAMPER_EnableActiveLevel(const RTC_TypeDef *RTCx, uint32_t Tamper) +{ + UNUSED(RTCx); + SET_BIT(TAMP->CR2, Tamper); +} + +/** + * @brief Disable Active level for Tamper input + * @rmtoll TAMP_CR2 TAMP1TRG LL_RTC_TAMPER_DisableActiveLevel\n + * TAMP_CR2 TAMP2TRG LL_RTC_TAMPER_DisableActiveLevel\n + * TAMP_CR2 TAMPxTRG LL_RTC_TAMPER_DisableActiveLevel\n + * @param RTCx RTC Instance + * @param Tamper This parameter can be a combination of the following values: + * @arg @ref RTC_LL_EC_TAMPER_ACTIVELEVEL + * + * @retval None + */ +__STATIC_INLINE void LL_RTC_TAMPER_DisableActiveLevel(const RTC_TypeDef *RTCx, uint32_t Tamper) +{ + UNUSED(RTCx); + CLEAR_BIT(TAMP->CR2, Tamper); +} + +/** + * @} + */ + +/** @defgroup RTC_LL_EF_Internal_Tamper Internal Tamper + * @{ + */ + +/** + * @brief Enable internal tamper detection. + * @rmtoll TAMP_CR1 ITAMP1E LL_RTC_TAMPER_ITAMP_Enable\n + * TAMP_CR1 ITAMP2E LL_RTC_TAMPER_ITAMP_Enable\n + * TAMP_CR1 ITAMPxE.. LL_RTC_TAMPER_ITAMP_Enable\n + * @param RTCx RTC Instance + * @param InternalTamper This parameter can be a combination of the following values: + * @arg @ref RTC_LL_EC_INTERNAL + * + * @retval None + */ +__STATIC_INLINE void LL_RTC_TAMPER_ITAMP_Enable(const RTC_TypeDef *RTCx, uint32_t InternalTamper) +{ + UNUSED(RTCx); + SET_BIT(TAMP->CR1, InternalTamper); +} + +/** + * @brief Disable internal tamper detection. + * @rmtoll TAMP_CR1 ITAMP1E LL_RTC_TAMPER_ITAMP_Disable\n + * TAMP_CR1 ITAMP2E LL_RTC_TAMPER_ITAMP_Disable\n + * TAMP_CR1 ITAMPxE LL_RTC_TAMPER_ITAMP_Disable\n + * @param RTCx RTC Instance + * @param InternalTamper This parameter can be a combination of the following values: + * @arg @ref RTC_LL_EC_INTERNAL + * + * @retval None + */ +__STATIC_INLINE void LL_RTC_TAMPER_ITAMP_Disable(const RTC_TypeDef *RTCx, uint32_t InternalTamper) +{ + UNUSED(RTCx); + CLEAR_BIT(TAMP->CR1, InternalTamper); +} + +/** + * @brief Enable backup register erase after internal tamper event detection + * @rmtoll TAMP_CR3 ITAMP1NOER LL_RTC_TAMPER_ITAMP_EnableEraseBKP + * TAMP_CR3 ITAMP2NOER... LL_RTC_TAMPER_ITAMP_EnableEraseBKP + * @param RTCx RTC Instance + * @param InternalTamper This parameter can be a combination of the following values: + * @arg @ref RTC_LL_EC_ITAMPER_NOERASE + * + * @retval None + */ +__STATIC_INLINE void LL_RTC_TAMPER_ITAMP_EnableEraseBKP(const RTC_TypeDef *RTCx, uint32_t InternalTamper) +{ + UNUSED(RTCx); + CLEAR_BIT(TAMP->CR3, InternalTamper); +} + +/** + * @brief Disable backup register erase after internal tamper event detection + * @rmtoll TAMP_CR3 ITAMP1NOER LL_RTC_TAMPER_ITAMP_DisableEraseBKP + * TAMP_CR3 ITAMP2NOER... LL_RTC_TAMPER_ITAMP_DisableEraseBKP + * @param RTCx RTC Instance + * @param InternalTamper This parameter can be a combination of the following values: + * @arg @ref RTC_LL_EC_ITAMPER_NOERASE + * + * @retval None + */ +__STATIC_INLINE void LL_RTC_TAMPER_ITAMP_DisableEraseBKP(const RTC_TypeDef *RTCx, uint32_t InternalTamper) +{ + UNUSED(RTCx); + SET_BIT(TAMP->CR3, InternalTamper); +} + +/** + * @} + */ + +/** @defgroup RTC_LL_EF_Active_Tamper Active Tamper + * @{ + */ +/** + * @brief Enable tamper active mode. + * @rmtoll TAMP_ATCR1 TAMP1AM LL_RTC_TAMPER_ATAMP_EnableActiveMode\n + * @rmtoll TAMP_ATCR1 TAMP2AM LL_RTC_TAMPER_ATAMP_EnableActiveMode\n + * @rmtoll TAMP_ATCR1 TAMPxAM LL_RTC_TAMPER_ATAMP_EnableActiveMode\n + * @param Tamper to configure as active. This parameter can be a combination of the following values: + * @arg @ref RTC_LL_EC_ACTIVE_MODE + * + * @retval None + */ +__STATIC_INLINE void LL_RTC_TAMPER_ATAMP_EnableActiveMode(uint32_t Tamper) +{ + SET_BIT(TAMP->ATCR1, Tamper); +} + +/** + * @brief Disable tamper active mode. + * @rmtoll TAMP_ATCR1 TAMP1AM LL_RTC_TAMPER_ATAMP_DisableActiveMode\n + * @rmtoll TAMP_ATCR1 TAMP2AM LL_RTC_TAMPER_ATAMP_DisableActiveMode\n + * @rmtoll TAMP_ATCR1 TAMPxAM LL_RTC_TAMPER_ATAMP_DisableActiveMode\n + * @param Tamper to configure as active. This parameter can be a combination of the following values: + * @arg @ref RTC_LL_EC_ACTIVE_MODE + * + * @retval None + */ +__STATIC_INLINE void LL_RTC_TAMPER_ATAMP_DisableActiveMode(uint32_t Tamper) +{ + CLEAR_BIT(TAMP->ATCR1, Tamper); +} + +/** + * @brief Enable active tamper filter. + * @rmtoll TAMP_ATCR1 FLTEN LL_RTC_TAMPER_ATAMP_EnableFilter\n + * @retval None + */ +__STATIC_INLINE void LL_RTC_TAMPER_ATAMP_EnableFilter(void) +{ + SET_BIT(TAMP->ATCR1, TAMP_ATCR1_FLTEN); +} + +/** + * @brief Disable active tamper filter. + * @rmtoll TAMP_ATCR1 FLTEN LL_RTC_TAMPER_ATAMP_DisableFilter\n + * @retval None + */ +__STATIC_INLINE void LL_RTC_TAMPER_ATAMP_DisableFilter(void) +{ + CLEAR_BIT(TAMP->ATCR1, TAMP_ATCR1_FLTEN); +} + +/** + * @brief Set Active tamper output change period. + * @rmtoll TAMP_ATCR1 ATPER LL_RTC_TAMPER_ATAMP_SetOutputChangePeriod\n + * @param ActiveOutputChangePeriod This parameter can be a value from 0 to 7 + * @retval None + */ +__STATIC_INLINE void LL_RTC_TAMPER_ATAMP_SetOutputChangePeriod(uint32_t ActiveOutputChangePeriod) +{ + MODIFY_REG(TAMP->ATCR1, TAMP_ATCR1_ATPER, (ActiveOutputChangePeriod << TAMP_ATCR1_ATPER_Pos)); +} + +/** + * @brief Get Active tamper output change period. + * @rmtoll TAMP_ATCR1 ATPER LL_RTC_TAMPER_ATAMP_GetOutputChangePeriod\n + * @retval Output change period. This parameter can be a value from 0 to 7. + */ +__STATIC_INLINE uint32_t LL_RTC_TAMPER_ATAMP_GetOutputChangePeriod(void) +{ + return (READ_BIT(TAMP->ATCR1, TAMP_ATCR1_ATPER) >> TAMP_ATCR1_ATPER_Pos); +} + +/** + * @brief Set Active tamper asynchronous prescaler clock selection. + * @rmtoll TAMP_ATCR1 ATCKSEL LL_RTC_TAMPER_ATAMP_SetAsyncPrescaler\n + * @param ActiveAsynvPrescaler Specifies the Active Tamper asynchronous Prescaler clock. + This parameter can be a value of the following values: + * @arg @ref RTC_LL_EC_ACTIVE_ASYNC_PRESCALER + * @retval None + */ +__STATIC_INLINE void LL_RTC_TAMPER_ATAMP_SetAsyncPrescaler(uint32_t ActiveAsynvPrescaler) +{ + MODIFY_REG(TAMP->ATCR1, TAMP_ATCR1_ATCKSEL, ActiveAsynvPrescaler); +} + +/** + * @brief Get Active tamper asynchronous prescaler clock selection. + * @rmtoll TAMP_ATCR1 ATCKSEL LL_RTC_TAMPER_ATAMP_GetAsyncPrescaler\n + * @retval One of @arg @ref RTC_LL_EC_ACTIVE_ASYNC_PRESCALER + */ +__STATIC_INLINE uint32_t LL_RTC_TAMPER_ATAMP_GetAsyncPrescaler(void) +{ + return (READ_BIT(TAMP->ATCR1, TAMP_ATCR1_ATCKSEL)); +} + +/** + * @brief Enable active tamper output sharing. + * @rmtoll TAMP_ATCR1 ATOSHARE LL_RTC_TAMPER_ATAMP_EnableOutputSharing\n + * @retval None + */ +__STATIC_INLINE void LL_RTC_TAMPER_ATAMP_EnableOutputSharing(void) +{ + SET_BIT(TAMP->ATCR1, TAMP_ATCR1_ATOSHARE); +} + +/** + * @brief Disable active tamper output sharing. + * @rmtoll TAMP_ATCR1 ATOSHARE LL_RTC_TAMPER_ATAMP_DisableOutputSharing\n + * @retval None + */ +__STATIC_INLINE void LL_RTC_TAMPER_ATAMP_DisableOutputSharing(void) +{ + CLEAR_BIT(TAMP->ATCR1, TAMP_ATCR1_ATOSHARE); +} + +/** + * @brief Set Active tamper shared output selection. + * @rmtoll TAMP_ATCR2 ATOSELx LL_RTC_TAMPER_ATAMP_SetSharedOuputSelection\n + * @param OutputSelection Specifies all the output selection of the Active Tamper. + This parameter is a combinasation of the following values: + * One of @arg @ref RTC_LL_EC_ACTIVE_OUTPUT_SELECTION + * @retval None + */ +__STATIC_INLINE void LL_RTC_TAMPER_ATAMP_SetSharedOuputSelection(uint32_t OutputSelection) +{ +#if (RTC_TAMP_NB == 2U) + MODIFY_REG(TAMP->ATCR2, (TAMP_ATCR2_ATOSEL1 | TAMP_ATCR2_ATOSEL2), OutputSelection); +#elif (RTC_TAMP_NB == 3U) + MODIFY_REG(TAMP->ATCR2, (TAMP_ATCR2_ATOSEL1 | TAMP_ATCR2_ATOSEL2 | TAMP_ATCR2_ATOSEL3), OutputSelection); +#elif (RTC_TAMP_NB == 8U) + MODIFY_REG(TAMP->ATCR2, (TAMP_ATCR2_ATOSEL1 | TAMP_ATCR2_ATOSEL2 | TAMP_ATCR2_ATOSEL3 | TAMP_ATCR2_ATOSEL4 | \ + TAMP_ATCR2_ATOSEL5 | TAMP_ATCR2_ATOSEL6 | TAMP_ATCR2_ATOSEL7 | TAMP_ATCR2_ATOSEL8), \ + OutputSelection); +#endif /* RTC_TAMP_NB */ + +} + +/** + * @brief Get Active tamper shared output selection. + * @rmtoll TAMP_ATCR2 ATOSELx LL_RTC_TAMPER_ATAMP_GetSharedOuputSelection\n + * @retval A combination of @arg @ref RTC_LL_EC_ACTIVE_OUTPUT_SELECTION + */ +__STATIC_INLINE uint32_t LL_RTC_TAMPER_ATAMP_GetSharedOuputSelection(void) +{ +#if (RTC_TAMP_NB == 2U) + return (READ_BIT(TAMP->ATCR2, (TAMP_ATCR2_ATOSEL1 | TAMP_ATCR2_ATOSEL2))); +#elif (RTC_TAMP_NB == 3U) + return (READ_BIT(TAMP->ATCR2, (TAMP_ATCR2_ATOSEL1 | TAMP_ATCR2_ATOSEL2 | TAMP_ATCR2_ATOSEL3))); +#elif (RTC_TAMP_NB == 8U) + return (READ_BIT(TAMP->ATCR2, (TAMP_ATCR2_ATOSEL1 | TAMP_ATCR2_ATOSEL2 | TAMP_ATCR2_ATOSEL3 | TAMP_ATCR2_ATOSEL4 | \ + TAMP_ATCR2_ATOSEL5 | TAMP_ATCR2_ATOSEL6 | TAMP_ATCR2_ATOSEL7 | TAMP_ATCR2_ATOSEL8))); +#endif /* RTC_TAMP_NB */ +} + +/** + * @brief Write active tamper seed. + * @rmtoll TAMP_ATSEEDR SEED LL_RTC_TAMPER_ATAMP_WriteSeed\n + * @param Seed + * @retval None + */ +__STATIC_INLINE void LL_RTC_TAMPER_ATAMP_WriteSeed(uint32_t Seed) +{ + WRITE_REG(TAMP->ATSEEDR, Seed); +} + +/** + * @brief Get active tamper initialization status flag. + * @rmtoll TAMP_ATOR INITS LL_RTC_IsActiveFlag_ATAMP_INITS + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ATAMP_INITS(void) +{ + return ((READ_BIT(TAMP->ATOR, TAMP_ATOR_INITS) == (TAMP_ATOR_INITS)) ? 1U : 0U); +} + +/** + * @brief Get active tamper seed running status flag. + * @rmtoll TAMP_ATOR SEEDF LL_RTC_IsActiveFlag_ATAMP_SEEDF + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ATAMP_SEEDF(void) +{ + return ((READ_BIT(TAMP->ATOR, TAMP_ATOR_SEEDF) == (TAMP_ATOR_SEEDF)) ? 1U : 0U); +} + +/** + * @} + */ + +/** @defgroup RTC_LL_EF_Wakeup Wakeup + * @{ + */ + +/** + * @brief Enable Wakeup timer + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR WUTE LL_RTC_WAKEUP_Enable + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_WAKEUP_Enable(RTC_TypeDef *RTCx) +{ + SET_BIT(RTCx->CR, RTC_CR_WUTE); +} + +/** + * @brief Disable Wakeup timer + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR WUTE LL_RTC_WAKEUP_Disable + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_WAKEUP_Disable(RTC_TypeDef *RTCx) +{ + CLEAR_BIT(RTCx->CR, RTC_CR_WUTE); +} + +/** + * @brief Check if Wakeup timer is enabled or not + * @rmtoll RTC_CR WUTE LL_RTC_WAKEUP_IsEnabled + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_WAKEUP_IsEnabled(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->CR, RTC_CR_WUTE) == (RTC_CR_WUTE)) ? 1U : 0U); +} + +/** + * @brief Select Wakeup clock + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @note Bit can be written only when RTC_CR WUTE bit = 0 and RTC_ICSR WUTWF bit = 1 + * @rmtoll RTC_CR WUCKSEL LL_RTC_WAKEUP_SetClock + * @param RTCx RTC Instance + * @param WakeupClock This parameter can be one of the following values: + * @arg @ref LL_RTC_WAKEUPCLOCK_DIV_16 + * @arg @ref LL_RTC_WAKEUPCLOCK_DIV_8 + * @arg @ref LL_RTC_WAKEUPCLOCK_DIV_4 + * @arg @ref LL_RTC_WAKEUPCLOCK_DIV_2 + * @arg @ref LL_RTC_WAKEUPCLOCK_CKSPRE + * @arg @ref LL_RTC_WAKEUPCLOCK_CKSPRE_WUT + * @retval None + */ +__STATIC_INLINE void LL_RTC_WAKEUP_SetClock(RTC_TypeDef *RTCx, uint32_t WakeupClock) +{ + MODIFY_REG(RTCx->CR, RTC_CR_WUCKSEL, WakeupClock); +} + +/** + * @brief Get Wakeup clock + * @rmtoll RTC_CR WUCKSEL LL_RTC_WAKEUP_GetClock + * @param RTCx RTC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_RTC_WAKEUPCLOCK_DIV_16 + * @arg @ref LL_RTC_WAKEUPCLOCK_DIV_8 + * @arg @ref LL_RTC_WAKEUPCLOCK_DIV_4 + * @arg @ref LL_RTC_WAKEUPCLOCK_DIV_2 + * @arg @ref LL_RTC_WAKEUPCLOCK_CKSPRE + * @arg @ref LL_RTC_WAKEUPCLOCK_CKSPRE_WUT + */ +__STATIC_INLINE uint32_t LL_RTC_WAKEUP_GetClock(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->CR, RTC_CR_WUCKSEL)); +} + +/** + * @brief Set Wakeup auto-reload value + * @note Bit can be written only when WUTWF is set to 1 in RTC_ICSR + * @rmtoll RTC_WUTR WUT LL_RTC_WAKEUP_SetAutoReload + * @param RTCx RTC Instance + * @param Value Value between Min_Data=0x00 and Max_Data=0xFFFF + * @retval None + */ +__STATIC_INLINE void LL_RTC_WAKEUP_SetAutoReload(RTC_TypeDef *RTCx, uint32_t Value) +{ + MODIFY_REG(RTCx->WUTR, RTC_WUTR_WUT, Value); +} + +/** + * @brief Get Wakeup auto-reload value + * @rmtoll RTC_WUTR WUT LL_RTC_WAKEUP_GetAutoReload + * @param RTCx RTC Instance + * @retval Value between Min_Data=0x00 and Max_Data=0xFFFF + */ +__STATIC_INLINE uint32_t LL_RTC_WAKEUP_GetAutoReload(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->WUTR, RTC_WUTR_WUT)); +} + +/** + * @} + */ + +/** @defgroup RTC_LL_EF_Backup_Registers Backup_Registers + * @{ + */ + +/** + * @brief Writes a data in a specified Backup data register. + * @rmtoll TAMP_BKPxR BKP LL_RTC_BKP_SetRegister + * @param RTCx RTC Instance + * @param BackupRegister This parameter can be one of the following values: + * @arg @ref LL_RTC_BKP_DR0 + * @arg @ref LL_RTC_BKP_DR1 + * @arg @ref LL_RTC_BKP_DR2 + * @arg @ref LL_RTC_BKP_DR3 + * @arg @ref LL_RTC_BKP_DR4 + * @arg LL_RTC_BKP_DRx ... + * @param Data Value between Min_Data=0x00 and Max_Data=0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void LL_RTC_BKP_SetRegister(const RTC_TypeDef *RTCx, uint32_t BackupRegister, uint32_t Data) +{ + __IO uint32_t tmp; + + UNUSED(RTCx); + + tmp = (uint32_t)(&(TAMP->BKP0R)); + tmp += (BackupRegister * 4U); + + /* Write the specified register */ + *(__IO uint32_t *)tmp = (uint32_t)Data; +} + +/** + * @brief Reads data from the specified RTC Backup data Register. + * @rmtoll TAMP_BKPxR BKP LL_RTC_BKP_GetRegister + * @param RTCx RTC Instance + * @param BackupRegister This parameter can be one of the following values: + * @arg @ref LL_RTC_BKP_DR0 + * @arg @ref LL_RTC_BKP_DR1 + * @arg @ref LL_RTC_BKP_DR2 + * @arg @ref LL_RTC_BKP_DR3 + * @arg @ref LL_RTC_BKP_DR4 + * @arg LL_RTC_BKP_DRx ... + * @retval Value between Min_Data=0x00 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_RTC_BKP_GetRegister(const RTC_TypeDef *RTCx, uint32_t BackupRegister) +{ + uint32_t tmp; + + UNUSED(RTCx); + + tmp = (uint32_t)(&(TAMP->BKP0R)); + tmp += (BackupRegister * 4U); + + /* Read the specified register */ + return (*(__IO uint32_t *)tmp); +} + +/** + * @} + */ + +/** @defgroup RTC_LL_EF_Calibration Calibration + * @{ + */ + +#if defined(RTC_CR_COE) +/** + * @brief Set Calibration output frequency (1 Hz or 512 Hz) + * @note Bits are write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR COE LL_RTC_CAL_SetOutputFreq\n + * RTC_CR COSEL LL_RTC_CAL_SetOutputFreq + * @param RTCx RTC Instance + * @param Frequency This parameter can be one of the following values: + * @arg @ref LL_RTC_CALIB_OUTPUT_NONE + * @arg @ref LL_RTC_CALIB_OUTPUT_1HZ + * @arg @ref LL_RTC_CALIB_OUTPUT_512HZ + * @retval None + */ +__STATIC_INLINE void LL_RTC_CAL_SetOutputFreq(RTC_TypeDef *RTCx, uint32_t Frequency) +{ + MODIFY_REG(RTCx->CR, RTC_CR_COE | RTC_CR_COSEL, Frequency); +} + +/** + * @brief Get Calibration output frequency (1 Hz or 512 Hz) + * @rmtoll RTC_CR COE LL_RTC_CAL_GetOutputFreq\n + * RTC_CR COSEL LL_RTC_CAL_GetOutputFreq + * @param RTCx RTC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_RTC_CALIB_OUTPUT_NONE + * @arg @ref LL_RTC_CALIB_OUTPUT_1HZ + * @arg @ref LL_RTC_CALIB_OUTPUT_512HZ + */ +__STATIC_INLINE uint32_t LL_RTC_CAL_GetOutputFreq(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->CR, RTC_CR_COE | RTC_CR_COSEL)); +} +#endif /* RTC_CR_COE */ + +/** + * @brief Insert or not One RTCCLK pulse every 2exp11 pulses (frequency increased by 488.5 ppm) + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @note Bit can be written only when RECALPF is set to 0 in RTC_ICSR + * @rmtoll RTC_CALR CALP LL_RTC_CAL_SetPulse + * @param RTCx RTC Instance + * @param Pulse This parameter can be one of the following values: + * @arg @ref LL_RTC_CALIB_INSERTPULSE_NONE + * @arg @ref LL_RTC_CALIB_INSERTPULSE_SET + * @retval None + */ +__STATIC_INLINE void LL_RTC_CAL_SetPulse(RTC_TypeDef *RTCx, uint32_t Pulse) +{ + MODIFY_REG(RTCx->CALR, RTC_CALR_CALP, Pulse); +} + +/** + * @brief Check if one RTCCLK has been inserted or not every 2exp11 pulses (frequency increased by 488.5 ppm) + * @rmtoll RTC_CALR CALP LL_RTC_CAL_IsPulseInserted + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_CAL_IsPulseInserted(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->CALR, RTC_CALR_CALP) == (RTC_CALR_CALP)) ? 1U : 0U); +} + +/** + * @brief Set the calibration cycle period + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @note Bit can be written only when RECALPF is set to 0 in RTC_ICSR + * @rmtoll RTC_CALR CALW8 LL_RTC_CAL_SetPeriod\n + * RTC_CALR CALW16 LL_RTC_CAL_SetPeriod + * @param RTCx RTC Instance + * @param Period This parameter can be one of the following values: + * @arg @ref LL_RTC_CALIB_PERIOD_32SEC + * @arg @ref LL_RTC_CALIB_PERIOD_16SEC + * @arg @ref LL_RTC_CALIB_PERIOD_8SEC + * @retval None + */ +__STATIC_INLINE void LL_RTC_CAL_SetPeriod(RTC_TypeDef *RTCx, uint32_t Period) +{ + MODIFY_REG(RTCx->CALR, RTC_CALR_CALW8 | RTC_CALR_CALW16, Period); +} + +/** + * @brief Get the calibration cycle period + * @rmtoll RTC_CALR CALW8 LL_RTC_CAL_GetPeriod\n + * RTC_CALR CALW16 LL_RTC_CAL_GetPeriod + * @param RTCx RTC Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_RTC_CALIB_PERIOD_32SEC + * @arg @ref LL_RTC_CALIB_PERIOD_16SEC + * @arg @ref LL_RTC_CALIB_PERIOD_8SEC + */ +__STATIC_INLINE uint32_t LL_RTC_CAL_GetPeriod(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->CALR, RTC_CALR_CALW8 | RTC_CALR_CALW16)); +} + +/** + * @brief Set Calibration minus + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @note Bit can be written only when RECALPF is set to 0 in RTC_ICSR + * @rmtoll RTC_CALR CALM LL_RTC_CAL_SetMinus + * @param RTCx RTC Instance + * @param CalibMinus Value between Min_Data=0x00 and Max_Data=0x1FF + * @retval None + */ +__STATIC_INLINE void LL_RTC_CAL_SetMinus(RTC_TypeDef *RTCx, uint32_t CalibMinus) +{ + MODIFY_REG(RTCx->CALR, RTC_CALR_CALM, CalibMinus); +} + +/** + * @brief Get Calibration minus + * @rmtoll RTC_CALR CALM LL_RTC_CAL_GetMinus + * @param RTCx RTC Instance + * @retval Value between Min_Data=0x00 and Max_Data= 0x1FF + */ +__STATIC_INLINE uint32_t LL_RTC_CAL_GetMinus(const RTC_TypeDef *RTCx) +{ + return (uint32_t)(READ_BIT(RTCx->CALR, RTC_CALR_CALM)); +} + +/** + * @brief Enable Calibration Low Power + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @note Bit can be written only when RECALPF is set to 0 + * @rmtoll RTC_CALR LPCAL LL_RTC_CAL_LowPower_Enable + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_CAL_LowPower_Enable(RTC_TypeDef *RTCx) +{ + SET_BIT(RTCx->CALR, RTC_CALR_LPCAL); +} + +/** + * @brief Disable Calibration Low Power + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @note Bit can be written only when RECALPF is set to 0 + * @rmtoll RTC_CALR LPCAL LL_RTC_CAL_LowPower_Disable + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_CAL_LowPower_Disable(RTC_TypeDef *RTCx) +{ + CLEAR_BIT(RTCx->CALR, RTC_CALR_LPCAL); +} + +/** + * @brief Check if Calibration Low Power is enabled or not + * @rmtoll RTC_CALR LPCAL LL_RTC_CAL_LowPower_IsEnabled + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_CAL_LowPower_IsEnabled(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->CALR, RTC_CALR_LPCAL) == (RTC_CALR_LPCAL)) ? 1U : 0U); +} + +/** + * @} + */ + +/** @defgroup RTC_LL_EF_FLAG_Management FLAG_Management + * @{ + */ + +/** + * @brief Get Internal Time-stamp flag + * @rmtoll RTC_SR ITSF LL_RTC_IsActiveFlag_ITS + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ITS(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->SR, RTC_SR_ITSF) == (RTC_SR_ITSF)) ? 1U : 0U); +} + +/** + * @brief Get Recalibration pending Flag + * @rmtoll RTC_ICSR RECALPF LL_RTC_IsActiveFlag_RECALP + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_RECALP(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->ICSR, RTC_ICSR_RECALPF) == (RTC_ICSR_RECALPF)) ? 1U : 0U); +} + +/** + * @brief Get Time-stamp overflow flag + * @rmtoll RTC_SR TSOVF LL_RTC_IsActiveFlag_TSOV + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_TSOV(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->SR, RTC_SR_TSOVF) == (RTC_SR_TSOVF)) ? 1U : 0U); +} + +/** + * @brief Get Time-stamp flag + * @rmtoll RTC_SR TSF LL_RTC_IsActiveFlag_TS + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_TS(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->SR, RTC_SR_TSF) == (RTC_SR_TSF)) ? 1U : 0U); +} + +/** + * @brief Get Wakeup timer flag + * @rmtoll RTC_SR WUTF LL_RTC_IsActiveFlag_WUT + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_WUT(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->SR, RTC_SR_WUTF) == (RTC_SR_WUTF)) ? 1U : 0U); +} + +/** + * @brief Get Alarm B flag + * @rmtoll RTC_SR ALRBF LL_RTC_IsActiveFlag_ALRB + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ALRB(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->SR, RTC_SR_ALRBF) == (RTC_SR_ALRBF)) ? 1U : 0U); +} + +/** + * @brief Get Alarm A flag + * @rmtoll RTC_SR ALRAF LL_RTC_IsActiveFlag_ALRA + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ALRA(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->SR, RTC_SR_ALRAF) == (RTC_SR_ALRAF)) ? 1U : 0U); +} + +/** + * @brief Get SSR Underflow flag + * @rmtoll RTC_SR SSRUF LL_RTC_IsActiveFlag_SSRU + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_SSRU(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->SR, RTC_SR_SSRUF) == (RTC_SR_SSRUF)) ? 1U : 0U); +} + +/** + * @brief Clear Internal Time-stamp flag + * @rmtoll RTC_SCR CITSF LL_RTC_ClearFlag_ITS + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_ITS(RTC_TypeDef *RTCx) +{ + WRITE_REG(RTCx->SCR, RTC_SCR_CITSF); +} + +/** + * @brief Clear Time-stamp overflow flag + * @rmtoll RTC_SCR CTSOVF LL_RTC_ClearFlag_TSOV + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_TSOV(RTC_TypeDef *RTCx) +{ + WRITE_REG(RTCx->SCR, RTC_SCR_CTSOVF); +} + +/** + * @brief Clear Time-stamp flag + * @rmtoll RTC_SCR CTSF LL_RTC_ClearFlag_TS + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_TS(RTC_TypeDef *RTCx) +{ + WRITE_REG(RTCx->SCR, RTC_SCR_CTSF); +} + +/** + * @brief Clear Wakeup timer flag + * @rmtoll RTC_SCR CWUTF LL_RTC_ClearFlag_WUT + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_WUT(RTC_TypeDef *RTCx) +{ + WRITE_REG(RTCx->SCR, RTC_SCR_CWUTF); +} + +/** + * @brief Clear Alarm B flag + * @rmtoll RTC_SCR CALRBF LL_RTC_ClearFlag_ALRB + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_ALRB(RTC_TypeDef *RTCx) +{ + WRITE_REG(RTCx->SCR, RTC_SCR_CALRBF); +} + +/** + * @brief Clear Alarm A flag + * @rmtoll RTC_SCR CALRAF LL_RTC_ClearFlag_ALRA + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_ALRA(RTC_TypeDef *RTCx) +{ + WRITE_REG(RTCx->SCR, RTC_SCR_CALRAF); +} + +/** + * @brief Clear SSR Underflow flag + * @rmtoll RTC_SCR CSSRUF LL_RTC_ClearFlag_SSRU + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_SSRU(RTC_TypeDef *RTCx) +{ + WRITE_REG(RTCx->SCR, RTC_SCR_CSSRUF); +} + +/** + * @brief Get Initialization flag + * @rmtoll RTC_ICSR INITF LL_RTC_IsActiveFlag_INIT + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_INIT(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->ICSR, RTC_ICSR_INITF) == (RTC_ICSR_INITF)) ? 1U : 0U); +} + +/** + * @brief Get Registers synchronization flag + * @rmtoll RTC_ICSR RSF LL_RTC_IsActiveFlag_RS + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_RS(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->ICSR, RTC_ICSR_RSF) == (RTC_ICSR_RSF)) ? 1U : 0U); +} + +/** + * @brief Clear Registers synchronization flag + * @rmtoll RTC_ICSR RSF LL_RTC_ClearFlag_RS + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_RS(RTC_TypeDef *RTCx) +{ + WRITE_REG(RTCx->ICSR, (~((RTC_ICSR_RSF | RTC_ICSR_INIT) & 0x000000FFU) | (RTCx->ICSR & RTC_ICSR_INIT))); +} + +/** + * @brief Get Initialization status flag + * @rmtoll RTC_ICSR INITS LL_RTC_IsActiveFlag_INITS + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_INITS(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->ICSR, RTC_ICSR_INITS) == (RTC_ICSR_INITS)) ? 1U : 0U); +} + +/** + * @brief Get Shift operation pending flag + * @rmtoll RTC_ICSR SHPF LL_RTC_IsActiveFlag_SHP + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_SHP(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->ICSR, RTC_ICSR_SHPF) == (RTC_ICSR_SHPF)) ? 1U : 0U); +} + +/** + * @brief Get Wakeup timer write flag + * @rmtoll RTC_ICSR WUTWF LL_RTC_IsActiveFlag_WUTW + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_WUTW(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->ICSR, RTC_ICSR_WUTWF) == (RTC_ICSR_WUTWF)) ? 1U : 0U); +} + +/** + * @brief Get Alarm A masked flag. + * @rmtoll RTC_MISR ALRAMF LL_RTC_IsActiveFlag_ALRAM + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ALRAM(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->MISR, RTC_MISR_ALRAMF) == (RTC_MISR_ALRAMF)) ? 1U : 0U); +} + +/** + * @brief Get SSR Underflow masked flag. + * @rmtoll RTC_MISR SSRUMF LL_RTC_IsActiveFlag_SSRUM + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_SSRUM(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->MISR, RTC_MISR_SSRUMF) == (RTC_MISR_SSRUMF)) ? 1U : 0U); +} + +/** + * @brief Get Alarm B masked flag. + * @rmtoll RTC_MISR ALRBMF LL_RTC_IsActiveFlag_ALRBM + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ALRBM(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->MISR, RTC_MISR_ALRBMF) == (RTC_MISR_ALRBMF)) ? 1U : 0U); +} + +/** + * @brief Get Wakeup timer masked flag. + * @rmtoll RTC_MISR WUTMF LL_RTC_IsActiveFlag_WUTM + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_WUTM(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->MISR, RTC_MISR_WUTMF) == (RTC_MISR_WUTMF)) ? 1U : 0U); +} + +/** + * @brief Get Time-stamp masked flag. + * @rmtoll RTC_MISR TSMF LL_RTC_IsActiveFlag_TSM + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_TSM(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->MISR, RTC_MISR_TSMF) == (RTC_MISR_TSMF)) ? 1U : 0U); +} + +/** + * @brief Get Time-stamp overflow masked flag. + * @rmtoll RTC_MISR TSOVMF LL_RTC_IsActiveFlag_TSOVM + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_TSOVM(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->MISR, RTC_MISR_TSOVMF) == (RTC_MISR_TSOVMF)) ? 1U : 0U); +} + +/** + * @brief Get Internal Time-stamp masked flag. + * @rmtoll RTC_MISR ITSMF LL_RTC_IsActiveFlag_ITSM + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ITSM(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->MISR, RTC_MISR_ITSMF) == (RTC_MISR_ITSMF)) ? 1U : 0U); +} + +/** + * @brief Get tamper 1 detection flag. + * @rmtoll TAMP_SR TAMP1F LL_RTC_IsActiveFlag_TAMP1 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_TAMP1(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->SR, TAMP_SR_TAMP1F) == (TAMP_SR_TAMP1F)) ? 1U : 0U); +} + +/** + * @brief Get tamper 2 detection flag. + * @rmtoll TAMP_SR TAMP2F LL_RTC_IsActiveFlag_TAMP2 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_TAMP2(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->SR, TAMP_SR_TAMP2F) == (TAMP_SR_TAMP2F)) ? 1U : 0U); +} + +#if (RTC_TAMP_NB > 2U) +/** + * @brief Get tamper 3 detection flag. + * @rmtoll TAMP_SR TAMP3F LL_RTC_IsActiveFlag_TAMP3 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_TAMP3(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->SR, TAMP_SR_TAMP3F) == (TAMP_SR_TAMP3F)) ? 1U : 0U); +} + +/** + * @brief Get tamper 4 detection flag. + * @rmtoll TAMP_SR TAMP4F LL_RTC_IsActiveFlag_TAMP4 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_TAMP4(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->SR, TAMP_SR_TAMP4F) == (TAMP_SR_TAMP4F)) ? 1U : 0U); +} + +/** + * @brief Get tamper 5 detection flag. + * @rmtoll TAMP_SR TAMP5F LL_RTC_IsActiveFlag_TAMP5 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_TAMP5(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->SR, TAMP_SR_TAMP5F) == (TAMP_SR_TAMP5F)) ? 1U : 0U); +} + +/** + * @brief Get tamper 6 detection flag. + * @rmtoll TAMP_SR TAMP6F LL_RTC_IsActiveFlag_TAMP6 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_TAMP6(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->SR, TAMP_SR_TAMP6F) == (TAMP_SR_TAMP6F)) ? 1U : 0U); +} +#endif /* (RTC_TAMP_NB > 2U) */ + +#if (RTC_TAMP_NB > 6U) +/** + * @brief Get tamper 7 detection flag. + * @rmtoll TAMP_SR TAMP7F LL_RTC_IsActiveFlag_TAMP7 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_TAMP7(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->SR, TAMP_SR_TAMP7F) == (TAMP_SR_TAMP7F)) ? 1U : 0U); +} + +/** + * @brief Get tamper 8 detection flag. + * @rmtoll TAMP_SR TAMP8F LL_RTC_IsActiveFlag_TAMP8 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_TAMP8(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->SR, TAMP_SR_TAMP8F) == (TAMP_SR_TAMP8F)) ? 1U : 0U); +} +#endif /* (RTC_TAMP_NB > 6U) */ + +/** + * @brief Get internal tamper 1 detection flag. + * @rmtoll TAMP_SR ITAMP1F LL_RTC_IsActiveFlag_ITAMP1 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ITAMP1(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->SR, TAMP_SR_ITAMP1F) == (TAMP_SR_ITAMP1F)) ? 1U : 0U); +} + +/** + * @brief Get internal tamper 2 detection flag. + * @rmtoll TAMP_SR ITAMP2F LL_RTC_IsActiveFlag_ITAMP2 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ITAMP2(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->SR, TAMP_SR_ITAMP2F) == (TAMP_SR_ITAMP2F)) ? 1U : 0U); +} + +/** + * @brief Get internal tamper 3 detection flag. + * @rmtoll TAMP_SR ITAMP3F LL_RTC_IsActiveFlag_ITAMP3 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ITAMP3(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->SR, TAMP_SR_ITAMP3F) == (TAMP_SR_ITAMP3F)) ? 1U : 0U); +} + +/** + * @brief Get internal tamper 4 detection flag. + * @rmtoll TAMP_SR ITAMP4F LL_RTC_IsActiveFlag_ITAMP4 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ITAMP4(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->SR, TAMP_SR_ITAMP4F) == (TAMP_SR_ITAMP4F)) ? 1U : 0U); +} + +/** + * @brief Get internal tamper 5 detection flag. + * @rmtoll TAMP_SR ITAMP5F LL_RTC_IsActiveFlag_ITAMP5 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ITAMP5(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->SR, TAMP_SR_ITAMP5F) == (TAMP_SR_ITAMP5F)) ? 1U : 0U); +} + +/** + * @brief Get internal tamper 6 detection flag. + * @rmtoll TAMP_SR ITAMP6F LL_RTC_IsActiveFlag_ITAMP6 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ITAMP6(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->SR, TAMP_SR_ITAMP6F) == (TAMP_SR_ITAMP6F)) ? 1U : 0U); +} + +/** + * @brief Get internal tamper 7 detection flag. + * @rmtoll TAMP_SR ITAMP7F LL_RTC_IsActiveFlag_ITAMP7 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ITAMP7(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->SR, TAMP_SR_ITAMP7F) == (TAMP_SR_ITAMP7F)) ? 1U : 0U); +} + +/** + * @brief Get internal tamper 8 detection flag. + * @rmtoll TAMP_SR ITAMP8F LL_RTC_IsActiveFlag_ITAMP8 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ITAMP8(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->SR, TAMP_SR_ITAMP8F) == (TAMP_SR_ITAMP8F)) ? 1U : 0U); +} + +/** + * @brief Get internal tamper 9 detection flag. + * @rmtoll TAMP_SR ITAMP9F LL_RTC_IsActiveFlag_ITAMP9 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ITAMP9(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->SR, TAMP_SR_ITAMP9F) == (TAMP_SR_ITAMP9F)) ? 1U : 0U); +} + +/** + * @brief Get internal tamper 11 detection flag. + * @rmtoll TAMP_SR ITAMP11F LL_RTC_IsActiveFlag_ITAMP11 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ITAMP11(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->SR, TAMP_SR_ITAMP11F) == (TAMP_SR_ITAMP11F)) ? 1U : 0U); +} + +/** + * @brief Get internal tamper 12 detection flag. + * @rmtoll TAMP_SR ITAMP12F LL_RTC_IsActiveFlag_ITAMP12 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ITAMP12(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->SR, TAMP_SR_ITAMP12F) == (TAMP_SR_ITAMP12F)) ? 1U : 0U); +} + +/** + * @brief Get internal tamper 13 detection flag. + * @rmtoll TAMP_SR ITAMP13F LL_RTC_IsActiveFlag_ITAMP13 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ITAMP13(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->SR, TAMP_SR_ITAMP13F) == (TAMP_SR_ITAMP13F)) ? 1U : 0U); +} + +/** + * @brief Get internal tamper 15 detection flag. + * @rmtoll TAMP_SR ITAMP15F LL_RTC_IsActiveFlag_ITAMP15 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ITAMP15(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->SR, TAMP_SR_ITAMP15F) == (TAMP_SR_ITAMP15F)) ? 1U : 0U); +} + +/** + * @brief Get tamper 1 interrupt masked flag. + * @rmtoll TAMP_MISR TAMP1MF LL_RTC_IsActiveFlag_TAMP1M + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_TAMP1M(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->MISR, TAMP_MISR_TAMP1MF) == (TAMP_MISR_TAMP1MF)) ? 1U : 0U); +} + +/** + * @brief Get tamper 2 interrupt masked flag. + * @rmtoll TAMP_MISR TAMP2MF LL_RTC_IsActiveFlag_TAMP2M + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_TAMP2M(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->MISR, TAMP_MISR_TAMP2MF) == (TAMP_MISR_TAMP2MF)) ? 1U : 0U); +} + +#if (RTC_TAMP_NB > 2U) +/** + * @brief Get tamper 3 interrupt masked flag. + * @rmtoll TAMP_MISR TAMP3MF LL_RTC_IsActiveFlag_TAMP3M + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_TAMP3M(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->MISR, TAMP_MISR_TAMP3MF) == (TAMP_MISR_TAMP3MF)) ? 1U : 0U); +} + +/** + * @brief Get tamper 4 interrupt masked flag. + * @rmtoll TAMP_MISR TAMP4MF LL_RTC_IsActiveFlag_TAMP4M + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_TAMP4M(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->MISR, TAMP_MISR_TAMP4MF) == (TAMP_MISR_TAMP4MF)) ? 1U : 0U); +} + +/** + * @brief Get tamper 5 interrupt masked flag. + * @rmtoll TAMP_MISR TAMP5MF LL_RTC_IsActiveFlag_TAMP5M + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_TAMP5M(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->MISR, TAMP_MISR_TAMP5MF) == (TAMP_MISR_TAMP5MF)) ? 1U : 0U); +} + +/** + * @brief Get tamper 6 interrupt masked flag. + * @rmtoll TAMP_MISR TAMP6MF LL_RTC_IsActiveFlag_TAMP6M + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_TAMP6M(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->MISR, TAMP_MISR_TAMP6MF) == (TAMP_MISR_TAMP6MF)) ? 1U : 0U); +} +#endif /* (RTC_TAMP_NB > 2U) */ + +#if (RTC_TAMP_NB > 6U) +/** + * @brief Get tamper 7 interrupt masked flag. + * @rmtoll TAMP_MISR TAMP7MF LL_RTC_IsActiveFlag_TAMP7M + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_TAMP7M(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->MISR, TAMP_MISR_TAMP7MF) == (TAMP_MISR_TAMP7MF)) ? 1U : 0U); +} + +/** + * @brief Get tamper 8 interrupt masked flag. + * @rmtoll TAMP_MISR TAMP8MF LL_RTC_IsActiveFlag_TAMP8M + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_TAMP8M(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->MISR, TAMP_MISR_TAMP8MF) == (TAMP_MISR_TAMP8MF)) ? 1U : 0U); +} +#endif /* (RTC_TAMP_NB > 6U) */ + +/** + * @brief Get internal tamper 1 interrupt masked flag. + * @rmtoll TAMP_MISR ITAMP1MF LL_RTC_IsActiveFlag_ITAMP1M + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ITAMP1M(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->MISR, TAMP_MISR_ITAMP1MF) == (TAMP_MISR_ITAMP1MF)) ? 1U : 0U); +} + +/** + * @brief Get internal tamper 2 interrupt masked flag. + * @rmtoll TAMP_MISR ITAMP2MF LL_RTC_IsActiveFlag_ITAMP2M + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ITAMP2M(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->MISR, TAMP_MISR_ITAMP2MF) == (TAMP_MISR_ITAMP2MF)) ? 1U : 0U); +} + +/** + * @brief Get internal tamper 3 interrupt masked flag. + * @rmtoll TAMP_MISR ITAMP3MF LL_RTC_IsActiveFlag_ITAMP3M + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ITAMP3M(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->MISR, TAMP_MISR_ITAMP3MF) == (TAMP_MISR_ITAMP3MF)) ? 1U : 0U); +} + +/** + * @brief Get internal tamper 4 interrupt masked flag. + * @rmtoll TAMP_MISR ITAMP4MF LL_RTC_IsActiveFlag_ITAMP4M + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ITAMP4M(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->MISR, TAMP_MISR_ITAMP4MF) == (TAMP_MISR_ITAMP4MF)) ? 1U : 0U); +} + +/** + * @brief Get internal tamper 5 interrupt masked flag. + * @rmtoll TAMP_MISR ITAMP5MF LL_RTC_IsActiveFlag_ITAMP5M + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ITAMP5M(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->MISR, TAMP_MISR_ITAMP5MF) == (TAMP_MISR_ITAMP5MF)) ? 1U : 0U); +} + +/** + * @brief Get internal tamper 6 interrupt masked flag. + * @rmtoll TAMP_MISR ITAMP6MF LL_RTC_IsActiveFlag_ITAMP6M + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ITAMP6M(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->MISR, TAMP_MISR_ITAMP6MF) == (TAMP_MISR_ITAMP6MF)) ? 1U : 0U); +} + +/** + * @brief Get internal tamper 7 interrupt masked flag. + * @rmtoll TAMP_MISR ITAMP7MF LL_RTC_IsActiveFlag_ITAMP7M + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ITAMP7M(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->MISR, TAMP_MISR_ITAMP7MF) == (TAMP_MISR_ITAMP7MF)) ? 1U : 0U); +} + +/** + * @brief Get internal tamper 8 interrupt masked flag. + * @rmtoll TAMP_MISR ITAMP8MF LL_RTC_IsActiveFlag_ITAMP8M + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ITAMP8M(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->MISR, TAMP_MISR_ITAMP8MF) == (TAMP_MISR_ITAMP8MF)) ? 1U : 0U); +} + +/** + * @brief Get internal tamper 9 interrupt masked flag. + * @rmtoll TAMP_MISR ITAMP9MF LL_RTC_IsActiveFlag_ITAMP9M + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ITAMP9M(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->MISR, TAMP_MISR_ITAMP9MF) == (TAMP_MISR_ITAMP9MF)) ? 1U : 0U); +} + +/** + * @brief Get internal tamper 11 interrupt masked flag. + * @rmtoll TAMP_MISR ITAMP11MF LL_RTC_IsActiveFlag_ITAMP11M + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ITAMP11M(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->MISR, TAMP_MISR_ITAMP11MF) == (TAMP_MISR_ITAMP11MF)) ? 1U : 0U); +} + +/** + * @brief Get internal tamper 12 interrupt masked flag. + * @rmtoll TAMP_MISR ITAMP12MF LL_RTC_IsActiveFlag_ITAMP12M + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ITAMP12M(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->MISR, TAMP_MISR_ITAMP12MF) == (TAMP_MISR_ITAMP12MF)) ? 1U : 0U); +} + +/** + * @brief Get internal tamper 13 interrupt masked flag. + * @rmtoll TAMP_MISR ITAMP13MF LL_RTC_IsActiveFlag_ITAMP13M + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ITAMP13M(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->MISR, TAMP_MISR_ITAMP13MF) == (TAMP_MISR_ITAMP13MF)) ? 1U : 0U); +} + +/** + * @brief Get internal tamper 15 interrupt masked flag. + * @rmtoll TAMP_MISR ITAMP15MF LL_RTC_IsActiveFlag_ITAMP15M + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsActiveFlag_ITAMP15M(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->MISR, TAMP_MISR_ITAMP15MF) == (TAMP_MISR_ITAMP15MF)) ? 1U : 0U); +} + +/** + * @brief Clear tamper 1 detection flag. + * @rmtoll TAMP_SCR CTAMP1F LL_RTC_ClearFlag_TAMP1 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_TAMP1(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + WRITE_REG(TAMP->SCR, TAMP_SCR_CTAMP1F); +} + +/** + * @brief Clear tamper 2 detection flag. + * @rmtoll TAMP_SCR CTAMP2F LL_RTC_ClearFlag_TAMP2 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_TAMP2(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + WRITE_REG(TAMP->SCR, TAMP_SCR_CTAMP2F); +} + +#if (RTC_TAMP_NB > 2U) +/** + * @brief Clear tamper 3 detection flag. + * @rmtoll TAMP_SCR CTAMP3F LL_RTC_ClearFlag_TAMP3 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_TAMP3(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + WRITE_REG(TAMP->SCR, TAMP_SCR_CTAMP3F); +} + +/** + * @brief Clear tamper 4 detection flag. + * @rmtoll TAMP_SCR CTAMP4F LL_RTC_ClearFlag_TAMP4 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_TAMP4(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + WRITE_REG(TAMP->SCR, TAMP_SCR_CTAMP4F); +} + +/** + * @brief Clear tamper 5 detection flag. + * @rmtoll TAMP_SCR CTAMP5F LL_RTC_ClearFlag_TAMP5 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_TAMP5(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + WRITE_REG(TAMP->SCR, TAMP_SCR_CTAMP5F); +} + +/** + * @brief Clear tamper 6 detection flag. + * @rmtoll TAMP_SCR CTAMP6F LL_RTC_ClearFlag_TAMP6 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_TAMP6(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + WRITE_REG(TAMP->SCR, TAMP_SCR_CTAMP6F); +} +#endif /* (RTC_TAMP_NB > 2U) */ + +#if (RTC_TAMP_NB > 6U) +/** + * @brief Clear tamper 7 detection flag. + * @rmtoll TAMP_SCR CTAMP7F LL_RTC_ClearFlag_TAMP7 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_TAMP7(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + WRITE_REG(TAMP->SCR, TAMP_SCR_CTAMP7F); +} + +/** + * @brief Clear tamper 8 detection flag. + * @rmtoll TAMP_SCR CTAMP8F LL_RTC_ClearFlag_TAMP8 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_TAMP8(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + WRITE_REG(TAMP->SCR, TAMP_SCR_CTAMP8F); +} +#endif /* (RTC_TAMP_NB > 6U) */ + +/** + * @brief Clear internal tamper 1 detection flag. + * @rmtoll TAMP_SCR CITAMP1F LL_RTC_ClearFlag_ITAMP1 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_ITAMP1(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + WRITE_REG(TAMP->SCR, TAMP_SCR_CITAMP1F); +} + +/** + * @brief Clear internal tamper 2 detection flag. + * @rmtoll TAMP_SCR CITAMP2F LL_RTC_ClearFlag_ITAMP2 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_ITAMP2(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + WRITE_REG(TAMP->SCR, TAMP_SCR_CITAMP2F); +} + +/** + * @brief Clear internal tamper 3 detection flag. + * @rmtoll TAMP_SCR CITAMP3F LL_RTC_ClearFlag_ITAMP3 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_ITAMP3(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + WRITE_REG(TAMP->SCR, TAMP_SCR_CITAMP3F); +} + +/** + * @brief Clear internal tamper 4 detection flag. + * @rmtoll TAMP_SCR CITAMP4F LL_RTC_ClearFlag_ITAMP4 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_ITAMP4(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + WRITE_REG(TAMP->SCR, TAMP_SCR_CITAMP4F); +} + +/** + * @brief Clear internal tamper 5 detection flag. + * @rmtoll TAMP_SCR CITAMP5F LL_RTC_ClearFlag_ITAMP5 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_ITAMP5(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + WRITE_REG(TAMP->SCR, TAMP_SCR_CITAMP5F); +} + +/** + * @brief Clear internal tamper 6 detection flag. + * @rmtoll TAMP_SCR CITAMP6F LL_RTC_ClearFlag_ITAMP6 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_ITAMP6(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + WRITE_REG(TAMP->SCR, TAMP_SCR_CITAMP6F); +} + +/** + * @brief Clear internal tamper 7 detection flag. + * @rmtoll TAMP_SCR CITAMP7F LL_RTC_ClearFlag_ITAMP7 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_ITAMP7(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + WRITE_REG(TAMP->SCR, TAMP_SCR_CITAMP7F); +} + +/** + * @brief Clear internal tamper 8 detection flag. + * @rmtoll TAMP_SCR CITAMP8F LL_RTC_ClearFlag_ITAMP8 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_ITAMP8(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + WRITE_REG(TAMP->SCR, TAMP_SCR_CITAMP8F); +} + +/** + * @brief Clear internal tamper 9 detection flag. + * @rmtoll TAMP_SCR CITAMP9F LL_RTC_ClearFlag_ITAMP9 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_ITAMP9(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + WRITE_REG(TAMP->SCR, TAMP_SCR_CITAMP9F); +} + +/** + * @brief Clear internal tamper 11 detection flag. + * @rmtoll TAMP_SCR CITAMP11F LL_RTC_ClearFlag_ITAMP11 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_ITAMP11(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + WRITE_REG(TAMP->SCR, TAMP_SCR_CITAMP11F); +} + +/** + * @brief Clear internal tamper 12 detection flag. + * @rmtoll TAMP_SCR CITAMP12F LL_RTC_ClearFlag_ITAMP12 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_ITAMP12(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + WRITE_REG(TAMP->SCR, TAMP_SCR_CITAMP12F); +} + +/** + * @brief Clear internal tamper 13 detection flag. + * @rmtoll TAMP_SCR CITAMP13F LL_RTC_ClearFlag_ITAMP13 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_ITAMP13(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + WRITE_REG(TAMP->SCR, TAMP_SCR_CITAMP13F); +} + +/** + * @brief Clear internal tamper 15 detection flag. + * @rmtoll TAMP_SCR CITAMP15F LL_RTC_ClearFlag_ITAMP15 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_ClearFlag_ITAMP15(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + WRITE_REG(TAMP->SCR, TAMP_SCR_CITAMP15F); +} + +/** + * @} + */ + +#if defined(RTC_SECCFGR_SEC) +/** @defgroup RTC_LL_EF_SECURITY SECURITY_Management + * @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Set RTC secure level. + * @note secure features are relevant if LL_RTC_SECURE_FULL_NO. + * @rmtoll RTC_SECCFGR SEC LL_RTC_SetRtcSecure + * @rmtoll RTC_SECCFGR INITSEC LL_RTC_SetRtcSecure + * @rmtoll RTC_SECCFGR CALSEC LL_RTC_SetRtcSecure + * @rmtoll RTC_SECCFGR TSSEC LL_RTC_SetRtcSecure + * @rmtoll RTC_SECCFGR WUTSEC LL_RTC_SetRtcSecure + * @rmtoll RTC_SECCFGR ALRASEC LL_RTC_SetRtcSecure + * @rmtoll RTC_SECCFGR ALRBSEC LL_RTC_SetRtcSecure + * @param RTCx RTC Instance + * @param rtcSecure This parameter can be a combination of the following values: + * @arg @ref LL_RTC_SECURE_FULL_YES + * @arg @ref LL_RTC_SECURE_FULL_NO + * @arg @ref LL_RTC_SECURE_FEATURE_INIT + * @arg @ref LL_RTC_SECURE_FEATURE_CAL + * @arg @ref LL_RTC_SECURE_FEATURE_TS + * @arg @ref LL_RTC_SECURE_FEATURE_WUT + * @arg @ref LL_RTC_SECURE_FEATURE_ALRA + * @arg @ref LL_RTC_SECURE_FEATURE_ALRB + + * @retval None + */ +__STATIC_INLINE void LL_RTC_SetRtcSecure(RTC_TypeDef *RTCx, uint32_t rtcSecure) +{ + MODIFY_REG(RTCx->SECCFGR, RTC_SECCFGR_SEC | RTC_SECCFGR_INITSEC | RTC_SECCFGR_CALSEC | RTC_SECCFGR_TSSEC | \ + RTC_SECCFGR_WUTSEC | RTC_SECCFGR_ALRASEC | RTC_SECCFGR_ALRBSEC, rtcSecure); +} +#endif /* #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/** + * @brief Get RTC secure level. + * @note Secure features is relevant if LL_RTC_SECURE_FULL_NO. + * @rmtoll RTC_SECCFGR SEC LL_RTC_SetRtcSecure + * @rmtoll RTC_SECCFGR INISEC LL_RTC_SetRtcSecure + * @rmtoll RTC_SECCFGR CALSEC LL_RTC_SetRtcSecure + * @rmtoll RTC_SECCFGR TSSEC LL_RTC_SetRtcSecure + * @rmtoll RTC_SECCFGR WUTSEC LL_RTC_SetRtcSecure + * @rmtoll RTC_SECCFGR ALRASEC LL_RTC_SetRtcSecure + * @rmtoll RTC_SECCFGR ALRBSEC LL_RTC_SetRtcSecure + * @param RTCx RTC Instance + * @retval Combination of the following values: + * @arg @ref LL_RTC_SECURE_FULL_YES + * @arg @ref LL_RTC_SECURE_FULL_NO + * @arg @ref LL_RTC_SECURE_FEATURE_INIT + * @arg @ref LL_RTC_SECURE_FEATURE_CAL + * @arg @ref LL_RTC_SECURE_FEATURE_TS + * @arg @ref LL_RTC_SECURE_FEATURE_WUT + * @arg @ref LL_RTC_SECURE_FEATURE_ALRA + * @arg @ref LL_RTC_SECURE_FEATURE_ALRB + */ +__STATIC_INLINE uint32_t LL_RTC_GetRtcSecure(const RTC_TypeDef *RTCx) +{ + return READ_BIT(RTCx->SECCFGR, RTC_SECCFGR_SEC | RTC_SECCFGR_INITSEC | RTC_SECCFGR_CALSEC | RTC_SECCFGR_TSSEC | \ + RTC_SECCFGR_WUTSEC | RTC_SECCFGR_ALRASEC | RTC_SECCFGR_ALRBSEC); +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Set TAMPER secure level. + * @rmtoll TAMP_SECCFGR TAMPSEC LL_RTC_SetTampSecure + * @param RTCx RTC Instance + * @param tampSecure This parameter can be one of the following values: + * @arg @ref LL_TAMP_SECURE_FULL_YES + * @arg @ref LL_TAMP_SECURE_FULL_NO + * @retval None + */ +__STATIC_INLINE void LL_RTC_SetTampSecure(const RTC_TypeDef *RTCx, uint32_t tampSecure) +{ + UNUSED(RTCx); + MODIFY_REG(TAMP->SECCFGR, TAMP_SECCFGR_TAMPSEC, tampSecure); +} +#endif /* #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/** + * @brief Get TAMPER secure level. + * @rmtoll TAMP_SECCFGR TAMPSEC LL_RTC_GetTampSecure + * @param RTCx RTC Instance + * @retval This parameter can be one of the following values: + * @arg @ref LL_TAMP_SECURE_FULL_YES + * @arg @ref LL_TAMP_SECURE_FULL_NO + */ +__STATIC_INLINE uint32_t LL_RTC_GetTampSecure(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return READ_BIT(TAMP->SECCFGR, TAMP_SECCFGR_TAMPSEC); +} + +/** + * @} + */ +#endif /* RTC_SECCFGR_SEC */ + +#if defined(RTC_PRIVCFGR_PRIV) +/** @defgroup RTC_LL_EF_PRIVILEGE PRIVILEGE_Management + * @{ + */ + +/** + * @brief Set RTC privilege level. + * @note Privilege features are relevant if LL_RTC_PRIVILEGE_FULL_NO. + * @rmtoll RTC_PRIVCFGR PRIV LL_RTC_SetRtcPrivilege + * @rmtoll RTC_PRIVCFGR INITPRIV LL_RTC_SetRtcPrivilege + * @rmtoll RTC_PRIVCFGR CALPRIV LL_RTC_SetRtcPrivilege + * @rmtoll RTC_PRIVCFGR TSPRIV LL_RTC_SetRtcPrivilege + * @rmtoll RTC_PRIVCFGR WUTPRIV LL_RTC_SetRtcPrivilege + * @rmtoll RTC_PRIVCFGR ALRAPRIV LL_RTC_SetRtcPrivilege + * @rmtoll RTC_PRIVCFGR ALRBPRIV LL_RTC_SetRtcPrivilege + * @param RTCx RTC Instance + * @param rtcPrivilege This parameter can be a combination of the following values: + * @arg @ref LL_RTC_PRIVILEGE_FULL_YES + * @arg @ref LL_RTC_PRIVILEGE_FULL_NO + * @arg @ref LL_RTC_PRIVILEGE_FEATURE_INIT + * @arg @ref LL_RTC_PRIVILEGE_FEATURE_CAL + * @arg @ref LL_RTC_PRIVILEGE_FEATURE_TS + * @arg @ref LL_RTC_PRIVILEGE_FEATURE_WUT + * @arg @ref LL_RTC_PRIVILEGE_FEATURE_ALRA + * @arg @ref LL_RTC_PRIVILEGE_FEATURE_ALRB + * @retval None + */ +__STATIC_INLINE void LL_RTC_SetRtcPrivilege(RTC_TypeDef *RTCx, uint32_t rtcPrivilege) +{ + MODIFY_REG(RTCx->PRIVCFGR, RTC_PRIVCFGR_PRIV | RTC_PRIVCFGR_INITPRIV | RTC_PRIVCFGR_CALPRIV | RTC_PRIVCFGR_TSPRIV | \ + RTC_PRIVCFGR_WUTPRIV | RTC_PRIVCFGR_ALRAPRIV | RTC_PRIVCFGR_ALRBPRIV, rtcPrivilege); +} + +/** + * @brief Get RTC privilege level. + * @note Privilege features are relevant if LL_RTC_PRIVILEGE_FULL_NO. + * @rmtoll RTC_PRIVCFGR PRIV LL_RTC_SetRtcPrivilege + * @rmtoll RTC_PRIVCFGR INITPRIV LL_RTC_SetRtcPrivilege + * @rmtoll RTC_PRIVCFGR CALPRIV LL_RTC_SetRtcPrivilege + * @rmtoll RTC_PRIVCFGR TSPRIV LL_RTC_SetRtcPrivilege + * @rmtoll RTC_PRIVCFGR WUTPRIV LL_RTC_SetRtcPrivilege + * @rmtoll RTC_PRIVCFGR ALRAPRIV LL_RTC_SetRtcPrivilege + * @rmtoll RTC_PRIVCFGR ALRBPRIV LL_RTC_SetRtcPrivilege + * @param RTCx RTC Instance + * @retval Combination of the following values: + * @arg @ref LL_RTC_PRIVILEGE_FULL_YES + * @arg @ref LL_RTC_PRIVILEGE_FULL_NO + * @arg @ref LL_RTC_PRIVILEGE_FEATURE_INIT + * @arg @ref LL_RTC_PRIVILEGE_FEATURE_CAL + * @arg @ref LL_RTC_PRIVILEGE_FEATURE_TS + * @arg @ref LL_RTC_PRIVILEGE_FEATURE_WUT + * @arg @ref LL_RTC_PRIVILEGE_FEATURE_ALRA + * @arg @ref LL_RTC_PRIVILEGE_FEATURE_ALRB + */ +__STATIC_INLINE uint32_t LL_RTC_GetRtcPrivilege(const RTC_TypeDef *RTCx) +{ + return READ_BIT(RTCx->PRIVCFGR, RTC_PRIVCFGR_PRIV | RTC_PRIVCFGR_INITPRIV | RTC_PRIVCFGR_CALPRIV | \ + RTC_PRIVCFGR_TSPRIV | RTC_PRIVCFGR_WUTPRIV | RTC_PRIVCFGR_ALRAPRIV | \ + RTC_PRIVCFGR_ALRBPRIV); +} + +/** + * @brief Set TAMPER privilege level. + * @rmtoll TAMP_PRIVCFGR TAMPPRIV LL_RTC_SetTampPrivilege + * @param RTCx RTC Instance + * @param tampPrivilege This parameter can be one of the following values: + * @arg @ref LL_TAMP_PRIVILEGE_FULL_YES + * @arg @ref LL_TAMP_PRIVILEGE_FULL_NO + * @retval None + */ +__STATIC_INLINE void LL_RTC_SetTampPrivilege(const RTC_TypeDef *RTCx, uint32_t tampPrivilege) +{ + UNUSED(RTCx); + MODIFY_REG(TAMP->PRIVCFGR, TAMP_PRIVCFGR_TAMPPRIV, tampPrivilege); +} + +/** + * @brief Get TAMPER privilege level. + * @rmtoll TAMP_PRIVCFGR TAMPPRIV LL_RTC_GetTampPrivilege + * @param RTCx RTC Instance + * @retval This parameter can be one of the following values: + * @arg @ref LL_TAMP_PRIVILEGE_FULL_YES + * @arg @ref LL_TAMP_PRIVILEGE_FULL_NO + */ +__STATIC_INLINE uint32_t LL_RTC_GetTampPrivilege(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return READ_BIT(TAMP->PRIVCFGR, TAMP_PRIVCFGR_TAMPPRIV); +} + +/** + * @brief Set Backup Registers privilege level. + * @note bckupRegisterPrivilege is only writable in secure mode or if trustzone is disabled + * @rmtoll TAMP_PRIVCFGR BKPWPRIV LL_RTC_SetBackupRegisterPrivilege + * @rmtoll TAMP_PRIVCFGR BKPRWPRIV LL_RTC_SetBackupRegisterPrivilege + * @param RTCx RTC Instance + * @param bckupRegisterPrivilege This parameter can be one of the following values: + * @arg @ref LL_RTC_PRIVILEGE_BKUP_ZONE_NONE + * @arg @ref LL_RTC_PRIVILEGE_BKUP_ZONE_1 + * @arg @ref LL_RTC_PRIVILEGE_BKUP_ZONE_2 + * @arg @ref LL_RTC_PRIVILEGE_BKUP_ZONE_ALL + * @retval None + */ +__STATIC_INLINE void LL_RTC_SetBackupRegisterPrivilege(const RTC_TypeDef *RTCx, uint32_t bckupRegisterPrivilege) +{ + UNUSED(RTCx); + MODIFY_REG(TAMP->PRIVCFGR, (TAMP_PRIVCFGR_BKPWPRIV | TAMP_PRIVCFGR_BKPRWPRIV), bckupRegisterPrivilege); +} + +/** + * @brief Get Backup Registers privilege level. + * @rmtoll TAMP_PRIVCFGR BKPWPRIV LL_RTC_GetBackupRegisterPrivilege + * @rmtoll TAMP_PRIVCFGR BKPRWPRIV LL_RTC_GetBackupRegisterPrivilege + * @param RTCx RTC Instance + * @retval This parameter can be one of the following values: + * @arg @ref LL_RTC_PRIVILEGE_BKUP_ZONE_NONE + * @arg @ref LL_RTC_PRIVILEGE_BKUP_ZONE_1 + * @arg @ref LL_RTC_PRIVILEGE_BKUP_ZONE_2 + * @arg @ref LL_RTC_PRIVILEGE_BKUP_ZONE_ALL + */ +__STATIC_INLINE uint32_t LL_RTC_GetBackupRegisterPrivilege(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return READ_BIT(TAMP->PRIVCFGR, (TAMP_PRIVCFGR_BKPWPRIV | TAMP_PRIVCFGR_BKPRWPRIV)); +} +/** + * @} + */ +#endif /* RTC_PRIVCFGR_PRIV */ + +/** @defgroup RTC_LL_EF_BACKUP_REG_PROTECTION PROTECTION_BACKUP_REG_Management + * @brief Backup register protection is common to security and privilege. + * @{ + */ + +/** + * @brief Set Backup registers protection level. + * @note Zone 1 : read protection write protection + * @note Zone 2 : read non-protection write protection + * @note Zone 3 : read non-protection write non-protection + * @note zone 1 : start from 0 to startZone2 start value + * @note zone 2 : start from startZone2 start value to startZone3 start value + * @note zone 3 : start from to startZone3 to the end of BACKUPREG + * @note Warning : this parameter is only writable in secure mode or if trustzone is disabled + * @rmtoll TAMP_SECCFGR BKPWSEC LL_RTC_SetBackupRegProtection + * @rmtoll TAMP_SECCFGR BKPRWSEC LL_RTC_SetBackupRegProtection + * @param RTCx RTC Instance + * @param startZone2 This parameter can be one of the following values: + * @arg @ref LL_RTC_BKP_DR0 + * @arg @ref LL_RTC_BKP_DR1 + * @arg @ref LL_RTC_BKP_DR2 + * @arg @ref LL_RTC_BKP_DR3 + * @arg @ref LL_RTC_BKP_DR4 + * @arg LL_RTC_BKP_DRx ... + * @param startZone3 This parameter can be one of the following values: + * @arg @ref LL_RTC_BKP_DR0 + * @arg @ref LL_RTC_BKP_DR1 + * @arg @ref LL_RTC_BKP_DR2 + * @arg @ref LL_RTC_BKP_DR3 + * @arg @ref LL_RTC_BKP_DR4 + * @arg LL_RTC_BKP_DRx ... + * @retval None + */ +__STATIC_INLINE void LL_RTC_SetBackupRegProtection(const RTC_TypeDef *RTCx, uint32_t startZone2, uint32_t startZone3) +{ + UNUSED(RTCx); + MODIFY_REG(TAMP->SECCFGR, (TAMP_SECCFGR_BKPRWSEC_Msk | TAMP_SECCFGR_BKPWSEC_Msk), + (startZone2 << TAMP_SECCFGR_BKPRWSEC_Pos) | (startZone3 << TAMP_SECCFGR_BKPWSEC_Pos)); +} + +/** + * @brief Get Backup registers protection level start zone 2. + * @note Zone 1 : read protection write protection + * @note Zone 2 : read non-protection/non-privile write protection + * @note Zone 3 : read non-protection write non-protection + * @rmtoll TAMP_SECCFGR BKPRWSEC LL_RTC_GetBackupRegProtectionStartZone2 + * @param RTCx RTC Instance + * @retval Start zone 2 + */ +__STATIC_INLINE uint32_t LL_RTC_GetBackupRegProtectionStartZone2(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return READ_BIT(TAMP->SECCFGR, TAMP_SECCFGR_BKPRWSEC_Msk) >> TAMP_SECCFGR_BKPRWSEC_Pos; +} + +/** + * @brief Get Backup registers protection level start zone 3. + * @note Zone 1 : read protection write protection + * @note Zone 2 : read non-protection write protection + * @note Zone 3 : read non-protection write non-protection + * @rmtoll TAMP_SECCFGR BKPWSEC LL_RTC_GetBackupRegProtectionStartZone3 + * @param RTCx RTC Instance + * @retval Start zone 2 + */ +__STATIC_INLINE uint32_t LL_RTC_GetBackupRegProtectionStartZone3(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return READ_BIT(TAMP->SECCFGR, TAMP_SECCFGR_BKPWSEC_Msk) >> TAMP_SECCFGR_BKPWSEC_Pos; +} +/** + * @} + */ + +/** @defgroup RTC_LL_EF_IT_Management IT_Management + * @{ + */ + +/** + * @brief Enable Time-stamp interrupt + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR TSIE LL_RTC_EnableIT_TS + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableIT_TS(RTC_TypeDef *RTCx) +{ + SET_BIT(RTCx->CR, RTC_CR_TSIE); +} + +/** + * @brief Disable Time-stamp interrupt + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR TSIE LL_RTC_DisableIT_TS + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableIT_TS(RTC_TypeDef *RTCx) +{ + CLEAR_BIT(RTCx->CR, RTC_CR_TSIE); +} + +/** + * @brief Enable Wakeup timer interrupt + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR WUTIE LL_RTC_EnableIT_WUT + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableIT_WUT(RTC_TypeDef *RTCx) +{ + SET_BIT(RTCx->CR, RTC_CR_WUTIE); +} + +/** + * @brief Disable Wakeup timer interrupt + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR WUTIE LL_RTC_DisableIT_WUT + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableIT_WUT(RTC_TypeDef *RTCx) +{ + CLEAR_BIT(RTCx->CR, RTC_CR_WUTIE); +} + +/** + * @brief Enable Alarm B interrupt + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR ALRBIE LL_RTC_EnableIT_ALRB + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableIT_ALRB(RTC_TypeDef *RTCx) +{ + SET_BIT(RTCx->CR, RTC_CR_ALRBIE); +} + +/** + * @brief Disable Alarm B interrupt + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR ALRBIE LL_RTC_DisableIT_ALRB + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableIT_ALRB(RTC_TypeDef *RTCx) +{ + CLEAR_BIT(RTCx->CR, RTC_CR_ALRBIE); +} + +/** + * @brief Enable Alarm A interrupt + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR ALRAIE LL_RTC_EnableIT_ALRA + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableIT_ALRA(RTC_TypeDef *RTCx) +{ + SET_BIT(RTCx->CR, RTC_CR_ALRAIE); +} + +/** + * @brief Disable Alarm A interrupt + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR ALRAIE LL_RTC_DisableIT_ALRA + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableIT_ALRA(RTC_TypeDef *RTCx) +{ + CLEAR_BIT(RTCx->CR, RTC_CR_ALRAIE); +} + +/** + * @brief Enable SSR Underflow interrupt + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR SSRUIE LL_RTC_EnableIT_SSRU + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableIT_SSRU(RTC_TypeDef *RTCx) +{ + SET_BIT(RTCx->CR, RTC_CR_SSRUIE); +} + +/** + * @brief Disable SSR Underflow interrupt + * @note Bit is write-protected. @ref LL_RTC_DisableWriteProtection function should be called before. + * @rmtoll RTC_CR SSRUIE LL_RTC_DisableIT_SSRU + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableIT_SSRU(RTC_TypeDef *RTCx) +{ + CLEAR_BIT(RTCx->CR, RTC_CR_SSRUIE); +} + +/** + * @brief Check if Time-stamp interrupt is enabled or not + * @rmtoll RTC_CR TSIE LL_RTC_IsEnabledIT_TS + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_TS(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->CR, RTC_CR_TSIE) == (RTC_CR_TSIE)) ? 1U : 0U); +} + +/** + * @brief Check if Wakeup timer interrupt is enabled or not + * @rmtoll RTC_CR WUTIE LL_RTC_IsEnabledIT_WUT + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_WUT(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->CR, RTC_CR_WUTIE) == (RTC_CR_WUTIE)) ? 1U : 0U); +} + +/** + * @brief Check if Alarm B interrupt is enabled or not + * @rmtoll RTC_CR ALRBIE LL_RTC_IsEnabledIT_ALRB + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_ALRB(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->CR, RTC_CR_ALRBIE) == (RTC_CR_ALRBIE)) ? 1U : 0U); +} + +/** + * @brief Check if Alarm A interrupt is enabled or not + * @rmtoll RTC_CR ALRAIE LL_RTC_IsEnabledIT_ALRA + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_ALRA(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->CR, RTC_CR_ALRAIE) == (RTC_CR_ALRAIE)) ? 1U : 0U); +} + +/** + * @brief Check if SSR Underflow interrupt is enabled or not + * @rmtoll RTC_CR SSRUIE LL_RTC_IsEnabledIT_SSRU + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_SSRU(const RTC_TypeDef *RTCx) +{ + return ((READ_BIT(RTCx->CR, RTC_CR_SSRUIE) == (RTC_CR_SSRUIE)) ? 1U : 0U); +} + +/** + * @brief Enable tamper 1 interrupt. + * @rmtoll TAMP_IER TAMP1IE LL_RTC_EnableIT_TAMP1 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableIT_TAMP1(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + SET_BIT(TAMP->IER, TAMP_IER_TAMP1IE); +} + +/** + * @brief Disable tamper 1 interrupt. + * @rmtoll TAMP_IER TAMP1IE LL_RTC_DisableIT_TAMP1 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableIT_TAMP1(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + CLEAR_BIT(TAMP->IER, TAMP_IER_TAMP1IE); +} + +/** + * @brief Enable tamper 2 interrupt. + * @rmtoll TAMP_IER TAMP2IE LL_RTC_EnableIT_TAMP2 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableIT_TAMP2(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + SET_BIT(TAMP->IER, TAMP_IER_TAMP2IE); +} + +/** + * @brief Disable tamper 2 interrupt. + * @rmtoll TAMP_IER TAMP2IE LL_RTC_DisableIT_TAMP2 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableIT_TAMP2(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + CLEAR_BIT(TAMP->IER, TAMP_IER_TAMP2IE); +} + +#if (RTC_TAMP_NB > 2U) +/** + * @brief Enable tamper 3 interrupt. + * @rmtoll TAMP_IER TAMP3IE LL_RTC_EnableIT_TAMP3 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableIT_TAMP3(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + SET_BIT(TAMP->IER, TAMP_IER_TAMP3IE); +} + +/** + * @brief Disable tamper 3 interrupt. + * @rmtoll TAMP_IER TAMP3IE LL_RTC_DisableIT_TAMP3 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableIT_TAMP3(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + CLEAR_BIT(TAMP->IER, TAMP_IER_TAMP3IE); +} + +/** + * @brief Enable tamper 4 interrupt. + * @rmtoll TAMP_IER TAMP4IE LL_RTC_EnableIT_TAMP4 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableIT_TAMP4(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + SET_BIT(TAMP->IER, TAMP_IER_TAMP4IE); +} + +/** + * @brief Disable tamper 4 interrupt. + * @rmtoll TAMP_IER TAMP4IE LL_RTC_DisableIT_TAMP4 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableIT_TAMP4(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + CLEAR_BIT(TAMP->IER, TAMP_IER_TAMP4IE); +} + +/** + * @brief Enable tamper 5 interrupt. + * @rmtoll TAMP_IER TAMP5IE LL_RTC_EnableIT_TAMP5 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableIT_TAMP5(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + SET_BIT(TAMP->IER, TAMP_IER_TAMP5IE); +} + +/** + * @brief Disable tamper 5 interrupt. + * @rmtoll TAMP_IER TAMP5IE LL_RTC_DisableIT_TAMP5 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableIT_TAMP5(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + CLEAR_BIT(TAMP->IER, TAMP_IER_TAMP5IE); +} + +/** + * @brief Enable tamper 6 interrupt. + * @rmtoll TAMP_IER TAMP6IE LL_RTC_EnableIT_TAMP6 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableIT_TAMP6(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + SET_BIT(TAMP->IER, TAMP_IER_TAMP6IE); +} + +/** + * @brief Disable tamper 6 interrupt. + * @rmtoll TAMP_IER TAMP6IE LL_RTC_DisableIT_TAMP6 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableIT_TAMP6(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + CLEAR_BIT(TAMP->IER, TAMP_IER_TAMP6IE); +} +#endif /* (RTC_TAMP_NB > 2U) */ + +#if (RTC_TAMP_NB > 6U) +/** + * @brief Enable tamper 7 interrupt. + * @rmtoll TAMP_IER TAMP7IE LL_RTC_EnableIT_TAMP7 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableIT_TAMP7(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + SET_BIT(TAMP->IER, TAMP_IER_TAMP7IE); +} + +/** + * @brief Disable tamper 7 interrupt. + * @rmtoll TAMP_IER TAMP7IE LL_RTC_DisableIT_TAMP7 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableIT_TAMP7(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + CLEAR_BIT(TAMP->IER, TAMP_IER_TAMP7IE); +} + +/** + * @brief Enable tamper 8 interrupt. + * @rmtoll TAMP_IER TAMP8IE LL_RTC_EnableIT_TAMP8 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableIT_TAMP8(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + SET_BIT(TAMP->IER, TAMP_IER_TAMP8IE); +} + +/** + * @brief Disable tamper 8 interrupt. + * @rmtoll TAMP_IER TAMP8IE LL_RTC_DisableIT_TAMP8 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableIT_TAMP8(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + CLEAR_BIT(TAMP->IER, TAMP_IER_TAMP8IE); +} +#endif /* (RTC_TAMP_NB > 6U) */ + +/** + * @brief Enable internal tamper 1 interrupt. + * @rmtoll TAMP_IER ITAMP1IE LL_RTC_EnableIT_ITAMP1 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableIT_ITAMP1(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + SET_BIT(TAMP->IER, TAMP_IER_ITAMP1IE); +} + +/** + * @brief Disable internal tamper 1 interrupt. + * @rmtoll TAMP_IER ITAMP1IE LL_RTC_DisableIT_ITAMP1 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableIT_ITAMP1(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + CLEAR_BIT(TAMP->IER, TAMP_IER_ITAMP1IE); +} + +/** + * @brief Enable internal tamper 2 interrupt. + * @rmtoll TAMP_IER ITAMP2IE LL_RTC_EnableIT_ITAMP2 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableIT_ITAMP2(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + SET_BIT(TAMP->IER, TAMP_IER_ITAMP2IE); +} + +/** + * @brief Disable internal tamper 2 interrupt. + * @rmtoll TAMP_IER ITAMP2IE LL_RTC_DisableIT_ITAMP2 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableIT_ITAMP2(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + CLEAR_BIT(TAMP->IER, TAMP_IER_ITAMP2IE); +} + +/** + * @brief Enable internal tamper 3 interrupt. + * @rmtoll TAMP_IER ITAMP3IE LL_RTC_EnableIT_ITAMP3 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableIT_ITAMP3(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + SET_BIT(TAMP->IER, TAMP_IER_ITAMP3IE); +} + +/** + * @brief Disable internal tamper 3 interrupt. + * @rmtoll TAMP_IER ITAMP3IE LL_RTC_DisableIT_ITAMP3 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableIT_ITAMP3(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + CLEAR_BIT(TAMP->IER, TAMP_IER_ITAMP3IE); +} + +/** + * @brief Enable internal tamper 4 interrupt. + * @rmtoll TAMP_IER ITAMP4IE LL_RTC_EnableIT_ITAMP4 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableIT_ITAMP4(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + SET_BIT(TAMP->IER, TAMP_IER_ITAMP4IE); +} + +/** + * @brief Disable internal tamper 4 interrupt. + * @rmtoll TAMP_IER ITAMP4IE LL_RTC_DisableIT_ITAMP4 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableIT_ITAMP4(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + CLEAR_BIT(TAMP->IER, TAMP_IER_ITAMP4IE); +} + +/** + * @brief Enable internal tamper 5 interrupt. + * @rmtoll TAMP_IER ITAMP5IE LL_RTC_EnableIT_ITAMP5 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableIT_ITAMP5(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + SET_BIT(TAMP->IER, TAMP_IER_ITAMP5IE); +} + +/** + * @brief Disable internal tamper 5 interrupt. + * @rmtoll TAMP_IER ITAMP5IE LL_RTC_DisableIT_ITAMP5 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableIT_ITAMP5(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + CLEAR_BIT(TAMP->IER, TAMP_IER_ITAMP5IE); +} + +/** + * @brief Enable internal tamper 6 interrupt. + * @rmtoll TAMP_IER ITAMP6IE LL_RTC_EnableIT_ITAMP6 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableIT_ITAMP6(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + SET_BIT(TAMP->IER, TAMP_IER_ITAMP6IE); +} + +/** + * @brief Disable internal tamper 6 interrupt. + * @rmtoll TAMP_IER ITAMP6IE LL_RTC_DisableIT_ITAMP6 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableIT_ITAMP6(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + CLEAR_BIT(TAMP->IER, TAMP_IER_ITAMP6IE); +} + +/** + * @brief Enable internal tamper 7 interrupt. + * @rmtoll TAMP_IER ITAMP7IE LL_RTC_EnableIT_ITAMP7 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableIT_ITAMP7(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + SET_BIT(TAMP->IER, TAMP_IER_ITAMP7IE); +} + +/** + * @brief Disable internal tamper 7 interrupt. + * @rmtoll TAMP_IER ITAMP7IE LL_RTC_DisableIT_ITAMP7 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableIT_ITAMP7(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + CLEAR_BIT(TAMP->IER, TAMP_IER_ITAMP7IE); +} + +/** + * @brief Enable internal tamper 8 interrupt. + * @rmtoll TAMP_IER ITAMP8IE LL_RTC_EnableIT_ITAMP8 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableIT_ITAMP8(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + SET_BIT(TAMP->IER, TAMP_IER_ITAMP8IE); +} + +/** + * @brief Disable internal tamper 8 interrupt. + * @rmtoll TAMP_IER ITAMP8IE LL_RTC_DisableIT_ITAMP8 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableIT_ITAMP8(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + CLEAR_BIT(TAMP->IER, TAMP_IER_ITAMP8IE); +} + +/** + * @brief Enable internal tamper 9 interrupt. + * @rmtoll TAMP_IER ITAMP9IE LL_RTC_EnableIT_ITAMP9 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableIT_ITAMP9(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + SET_BIT(TAMP->IER, TAMP_IER_ITAMP9IE); +} + +/** + * @brief Disable internal tamper 9 interrupt. + * @rmtoll TAMP_IER ITAMP9IE LL_RTC_DisableIT_ITAMP9 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableIT_ITAMP9(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + CLEAR_BIT(TAMP->IER, TAMP_IER_ITAMP9IE); +} + +/** + * @brief Enable internal tamper 11 interrupt. + * @rmtoll TAMP_IER ITAMP11IE LL_RTC_EnableIT_ITAMP11 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableIT_ITAMP11(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + SET_BIT(TAMP->IER, TAMP_IER_ITAMP11IE); +} + +/** + * @brief Disable internal tamper 11 interrupt. + * @rmtoll TAMP_IER ITAMP11IE LL_RTC_DisableIT_ITAMP11 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableIT_ITAMP11(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + CLEAR_BIT(TAMP->IER, TAMP_IER_ITAMP11IE); +} + +/** + * @brief Enable internal tamper 12 interrupt. + * @rmtoll TAMP_IER ITAMP12IE LL_RTC_EnableIT_ITAMP12 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableIT_ITAMP12(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + SET_BIT(TAMP->IER, TAMP_IER_ITAMP12IE); +} + +/** + * @brief Disable internal tamper 12 interrupt. + * @rmtoll TAMP_IER ITAMP12IE LL_RTC_DisableIT_ITAMP12 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableIT_ITAMP12(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + CLEAR_BIT(TAMP->IER, TAMP_IER_ITAMP12IE); +} + +/** + * @brief Enable internal tamper 13 interrupt. + * @rmtoll TAMP_IER ITAMP13IE LL_RTC_EnableIT_ITAMP13 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableIT_ITAMP13(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + SET_BIT(TAMP->IER, TAMP_IER_ITAMP13IE); +} + +/** + * @brief Disable internal tamper 13 interrupt. + * @rmtoll TAMP_IER ITAMP13IE LL_RTC_DisableIT_ITAMP13 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableIT_ITAMP13(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + CLEAR_BIT(TAMP->IER, TAMP_IER_ITAMP13IE); +} + +/** + * @brief Enable internal tamper 15 interrupt. + * @rmtoll TAMP_IER ITAMP15IE LL_RTC_EnableIT_ITAMP15 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_EnableIT_ITAMP15(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + SET_BIT(TAMP->IER, TAMP_IER_ITAMP15IE); +} + +/** + * @brief Disable internal tamper 15 interrupt. + * @rmtoll TAMP_IER ITAMP15IE LL_RTC_DisableIT_ITAMP15 + * @param RTCx RTC Instance + * @retval None + */ +__STATIC_INLINE void LL_RTC_DisableIT_ITAMP15(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + CLEAR_BIT(TAMP->IER, TAMP_IER_ITAMP15IE); +} + +/** + * @brief Check if tamper 1 interrupt is enabled or not. + * @rmtoll TAMP_IER TAMP1IE LL_RTC_IsEnabledIT_TAMP1 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_TAMP1(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->IER, TAMP_IER_TAMP1IE) == (TAMP_IER_TAMP1IE)) ? 1U : 0U); +} + +/** + * @brief Check if tamper 2 interrupt is enabled or not. + * @rmtoll TAMP_IER TAMP2IE LL_RTC_IsEnabledIT_TAMP2 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_TAMP2(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->IER, TAMP_IER_TAMP2IE) == (TAMP_IER_TAMP2IE)) ? 1U : 0U); +} + +#if (RTC_TAMP_NB > 2U) +/** + * @brief Check if tamper 3 interrupt is enabled or not. + * @rmtoll TAMP_IER TAMP3IE LL_RTC_IsEnabledIT_TAMP3 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_TAMP3(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->IER, TAMP_IER_TAMP3IE) == (TAMP_IER_TAMP3IE)) ? 1U : 0U); +} + +/** + * @brief Check if tamper 4 interrupt is enabled or not. + * @rmtoll TAMP_IER TAMP4IE LL_RTC_IsEnabledIT_TAMP4 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_TAMP4(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->IER, TAMP_IER_TAMP4IE) == (TAMP_IER_TAMP4IE)) ? 1U : 0U); +} + +/** + * @brief Check if tamper 5 interrupt is enabled or not. + * @rmtoll TAMP_IER TAMP5IE LL_RTC_IsEnabledIT_TAMP5 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_TAMP5(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->IER, TAMP_IER_TAMP5IE) == (TAMP_IER_TAMP5IE)) ? 1U : 0U); +} + +/** + * @brief Check if tamper 6 interrupt is enabled or not. + * @rmtoll TAMP_IER TAMP6IE LL_RTC_IsEnabledIT_TAMP6 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_TAMP6(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->IER, TAMP_IER_TAMP6IE) == (TAMP_IER_TAMP6IE)) ? 1U : 0U); +} +#endif /* (RTC_TAMP_NB > 2U) */ + +#if (RTC_TAMP_NB > 6U) +/** + * @brief Check if tamper 7 interrupt is enabled or not. + * @rmtoll TAMP_IER TAMP7IE LL_RTC_IsEnabledIT_TAMP7 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_TAMP7(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->IER, TAMP_IER_TAMP7IE) == (TAMP_IER_TAMP7IE)) ? 1U : 0U); +} + +/** + * @brief Check if tamper 8 interrupt is enabled or not. + * @rmtoll TAMP_IER TAMP8IE LL_RTC_IsEnabledIT_TAMP8 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_TAMP8(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->IER, TAMP_IER_TAMP8IE) == (TAMP_IER_TAMP8IE)) ? 1U : 0U); +} +#endif /* (RTC_TAMP_NB > 6U) */ + +/** + * @brief Check if internal tamper 1 interrupt is enabled or not. + * @rmtoll TAMP_IER ITAMP1IE LL_RTC_IsEnabledIT_ITAMP1 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_ITAMP1(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->IER, TAMP_IER_ITAMP1IE) == (TAMP_IER_ITAMP1IE)) ? 1U : 0U); +} + +/** + * @brief Check if internal tamper 2 interrupt is enabled or not. + * @rmtoll TAMP_IER ITAMP2IE LL_RTC_IsEnabledIT_ITAMP2 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_ITAMP2(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->IER, TAMP_IER_ITAMP2IE) == (TAMP_IER_ITAMP2IE)) ? 1U : 0U); +} + +/** + * @brief Check if internal tamper 3 interrupt is enabled or not. + * @rmtoll TAMP_IER ITAMP3IE LL_RTC_IsEnabledIT_ITAMP3 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_ITAMP3(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->IER, TAMP_IER_ITAMP3IE) == (TAMP_IER_ITAMP3IE)) ? 1U : 0U); +} + +/** + * @brief Check if internal tamper 4 interrupt is enabled or not. + * @rmtoll TAMP_IER ITAMP4IE LL_RTC_IsEnabledIT_ITAMP4 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_ITAMP4(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->IER, TAMP_IER_ITAMP4IE) == (TAMP_IER_ITAMP4IE)) ? 1U : 0U); +} + +/** + * @brief Check if internal tamper 5 interrupt is enabled or not. + * @rmtoll TAMP_IER ITAMP5IE LL_RTC_IsEnabledIT_ITAMP5 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_ITAMP5(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->IER, TAMP_IER_ITAMP5IE) == (TAMP_IER_ITAMP5IE)) ? 1U : 0U); +} + +/** + * @brief Check if internal tamper 6 interrupt is enabled or not. + * @rmtoll TAMP_IER ITAMP6IE LL_RTC_IsEnabledIT_ITAMP6 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_ITAMP6(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->IER, TAMP_IER_ITAMP6IE) == (TAMP_IER_ITAMP6IE)) ? 1U : 0U); +} + +/** + * @brief Check if internal tamper 7 interrupt is enabled or not. + * @rmtoll TAMP_IER ITAMP7IE LL_RTC_IsEnabledIT_ITAMP7 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_ITAMP7(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->IER, TAMP_IER_ITAMP7IE) == (TAMP_IER_ITAMP7IE)) ? 1U : 0U); +} + +/** + * @brief Check if internal tamper 8 interrupt is enabled or not. + * @rmtoll TAMP_IER ITAMP8IE LL_RTC_IsEnabledIT_ITAMP8 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_ITAMP8(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->IER, TAMP_IER_ITAMP8IE) == (TAMP_IER_ITAMP8IE)) ? 1U : 0U); +} + +/** + * @brief Check if internal tamper 9 interrupt is enabled or not. + * @rmtoll TAMP_IER ITAMP9IE LL_RTC_IsEnabledIT_ITAMP9 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_ITAMP9(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->IER, TAMP_IER_ITAMP9IE) == (TAMP_IER_ITAMP9IE)) ? 1U : 0U); +} + +/** + * @brief Check if internal tamper 11 interrupt is enabled or not. + * @rmtoll TAMP_IER ITAMP11IE LL_RTC_IsEnabledIT_ITAMP11 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_ITAMP11(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->IER, TAMP_IER_ITAMP11IE) == (TAMP_IER_ITAMP11IE)) ? 1U : 0U); +} + +/** + * @brief Check if internal tamper 12 interrupt is enabled or not. + * @rmtoll TAMP_IER ITAMP12IE LL_RTC_IsEnabledIT_ITAMP12 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_ITAMP12(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->IER, TAMP_IER_ITAMP12IE) == (TAMP_IER_ITAMP12IE)) ? 1U : 0U); +} + +/** + * @brief Check if internal tamper 13 interrupt is enabled or not. + * @rmtoll TAMP_IER ITAMP13IE LL_RTC_IsEnabledIT_ITAMP13 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_ITAMP13(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->IER, TAMP_IER_ITAMP13IE) == (TAMP_IER_ITAMP13IE)) ? 1U : 0U); +} + +/** + * @brief Check if internal tamper 15 interrupt is enabled or not. + * @rmtoll TAMP_IER ITAMP15IE LL_RTC_IsEnabledIT_ITAMP15 + * @param RTCx RTC Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_RTC_IsEnabledIT_ITAMP15(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return ((READ_BIT(TAMP->IER, TAMP_IER_ITAMP15IE) == (TAMP_IER_ITAMP15IE)) ? 1U : 0U); +} + +/** + * @brief Increment Monotonic counter. + * @rmtoll TAMP_COUNT1R COUNT LL_RTC_IncrementMonotonicCounter + * @param RTCx RTC Instance + * @retval None. + */ +__STATIC_INLINE void LL_RTC_IncrementMonotonicCounter(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + WRITE_REG(TAMP->COUNT1R, 0U); +} + +/** + * @brief Increment Monotonic counter. + * @rmtoll TAMP_COUNT1R COUNT LL_RTC_GetMonotonicCounter + * @param RTCx RTC Instance + * @retval Monotonic counter value. + */ +__STATIC_INLINE uint32_t LL_RTC_GetMonotonicCounter(const RTC_TypeDef *RTCx) +{ + UNUSED(RTCx); + return READ_REG(TAMP->COUNT1R); +} + +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup RTC_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +ErrorStatus LL_RTC_DeInit(RTC_TypeDef *RTCx); +ErrorStatus LL_RTC_Init(RTC_TypeDef *RTCx, LL_RTC_InitTypeDef *RTC_InitStruct); +void LL_RTC_StructInit(LL_RTC_InitTypeDef *RTC_InitStruct); +ErrorStatus LL_RTC_TIME_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_TimeTypeDef *RTC_TimeStruct); +void LL_RTC_TIME_StructInit(LL_RTC_TimeTypeDef *RTC_TimeStruct); +ErrorStatus LL_RTC_DATE_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_DateTypeDef *RTC_DateStruct); +void LL_RTC_DATE_StructInit(LL_RTC_DateTypeDef *RTC_DateStruct); +ErrorStatus LL_RTC_ALMA_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_AlarmTypeDef *RTC_AlarmStruct); +ErrorStatus LL_RTC_ALMB_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_AlarmTypeDef *RTC_AlarmStruct); +void LL_RTC_ALMA_StructInit(LL_RTC_AlarmTypeDef *RTC_AlarmStruct); +void LL_RTC_ALMB_StructInit(LL_RTC_AlarmTypeDef *RTC_AlarmStruct); +ErrorStatus LL_RTC_EnterInitMode(RTC_TypeDef *RTCx); +ErrorStatus LL_RTC_ExitInitMode(RTC_TypeDef *RTCx); +ErrorStatus LL_RTC_WaitForSynchro(RTC_TypeDef *RTCx); + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined(RTC) */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_LL_RTC_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_sdmmc.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_sdmmc.h new file mode 100644 index 0000000000..190f1acaf1 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_sdmmc.h @@ -0,0 +1,1161 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_sdmmc.h + * @author MCD Application Team + * @brief Header file of SDMMC HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_LL_SDMMC_H +#define STM32H5xx_LL_SDMMC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +/** @addtogroup STM32H5xx_Driver + * @{ + */ +#if defined (SDMMC1) || defined (SDMMC2) +/** @addtogroup SDMMC_LL + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup SDMMC_LL_Exported_Types SDMMC_LL Exported Types + * @{ + */ + +/** + * @brief SDMMC Configuration Structure definition + */ +typedef struct +{ + uint32_t ClockEdge; /*!< Specifies the SDMMC_CCK clock transition on which Data and Command change. + This parameter can be a value of @ref SDMMC_LL_Clock_Edge */ + + uint32_t ClockPowerSave; /*!< Specifies whether SDMMC Clock output is enabled or + disabled when the bus is idle. + This parameter can be a value of @ref SDMMC_LL_Clock_Power_Save */ + + uint32_t BusWide; /*!< Specifies the SDMMC bus width. + This parameter can be a value of @ref SDMMC_LL_Bus_Wide */ + + uint32_t HardwareFlowControl; /*!< Specifies whether the SDMMC hardware flow control is enabled or disabled. + This parameter can be a value of @ref SDMMC_LL_Hardware_Flow_Control */ + + uint32_t ClockDiv; /*!< Specifies the clock frequency of the SDMMC controller. + This parameter can be a value between Min_Data = 0 and Max_Data = 1023 */ + +#if (USE_SD_TRANSCEIVER != 0U) + uint32_t TranceiverPresent; /*!< Specifies if there is a 1V8 Transceiver/Switcher. + This parameter can be a value of @ref SDMMC_LL_TRANSCEIVER_PRESENT */ +#endif /* USE_SD_TRANSCEIVER */ +} SDMMC_InitTypeDef; + + +/** + * @brief SDMMC Command Control structure + */ +typedef struct +{ + uint32_t Argument; /*!< Specifies the SDMMC command argument which is sent + to a card as part of a command message. If a command + contains an argument, it must be loaded into this register + before writing the command to the command register. */ + + uint32_t CmdIndex; /*!< Specifies the SDMMC command index. It must be Min_Data = 0 and + Max_Data = 64 */ + + uint32_t Response; /*!< Specifies the SDMMC response type. + This parameter can be a value of @ref SDMMC_LL_Response_Type */ + + uint32_t WaitForInterrupt; /*!< Specifies whether SDMMC wait for interrupt request is + enabled or disabled. + This parameter can be a value of @ref SDMMC_LL_Wait_Interrupt_State */ + + uint32_t CPSM; /*!< Specifies whether SDMMC Command path state machine (CPSM) + is enabled or disabled. + This parameter can be a value of @ref SDMMC_LL_CPSM_State */ +} SDMMC_CmdInitTypeDef; + + +/** + * @brief SDMMC Data Control structure + */ +typedef struct +{ + uint32_t DataTimeOut; /*!< Specifies the data timeout period in card bus clock periods. */ + + uint32_t DataLength; /*!< Specifies the number of data bytes to be transferred. */ + + uint32_t DataBlockSize; /*!< Specifies the data block size for block transfer. + This parameter can be a value of @ref SDMMC_LL_Data_Block_Size */ + + uint32_t TransferDir; /*!< Specifies the data transfer direction, whether the transfer + is a read or write. + This parameter can be a value of @ref SDMMC_LL_Transfer_Direction */ + + uint32_t TransferMode; /*!< Specifies whether data transfer is in stream or block mode. + This parameter can be a value of @ref SDMMC_LL_Transfer_Type */ + + uint32_t DPSM; /*!< Specifies whether SDMMC Data path state machine (DPSM) + is enabled or disabled. + This parameter can be a value of @ref SDMMC_LL_DPSM_State */ +} SDMMC_DataInitTypeDef; + +/** @defgroup SDEx_Exported_Types_Group1 SD Card Internal DMA Buffer structure + * @{ + */ +typedef struct +{ + __IO uint32_t IDMALAR; /*!< SDMMC DMA linked list configuration register */ + __IO uint32_t IDMABASER; /*!< SDMMC DMA buffer base address register */ + __IO uint32_t IDMABSIZE; /*!< SDMMC DMA buffer size register */ +} SDMMC_DMALinkNodeTypeDef; + +typedef struct +{ + uint32_t BufferAddress; /*!< Node Buffer address */ + uint32_t BufferSize ; /*!< Node Buffer size */ +} SDMMC_DMALinkNodeConfTypeDef; + +typedef struct +{ + SDMMC_DMALinkNodeTypeDef *pHeadNode; /*!< Linked List Node Head */ + SDMMC_DMALinkNodeTypeDef *pTailNode; /*!< Linked List Node Head */ + uint32_t NodesCounter ; /*!< Node is ready for execution */ +} SDMMC_DMALinkedListTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup SDMMC_LL_Exported_Constants SDMMC_LL Exported Constants + * @{ + */ +#define SDMMC_ERROR_NONE ((uint32_t)0x00000000U) /*!< No error */ +#define SDMMC_ERROR_CMD_CRC_FAIL ((uint32_t)0x00000001U) /*!< Command response received (but CRC check failed) */ +#define SDMMC_ERROR_DATA_CRC_FAIL ((uint32_t)0x00000002U) /*!< Data block sent/received (CRC check failed) */ +#define SDMMC_ERROR_CMD_RSP_TIMEOUT ((uint32_t)0x00000004U) /*!< Command response timeout */ +#define SDMMC_ERROR_DATA_TIMEOUT ((uint32_t)0x00000008U) /*!< Data timeout */ +#define SDMMC_ERROR_TX_UNDERRUN ((uint32_t)0x00000010U) /*!< Transmit FIFO underrun */ +#define SDMMC_ERROR_RX_OVERRUN ((uint32_t)0x00000020U) /*!< Receive FIFO overrun */ +#define SDMMC_ERROR_ADDR_MISALIGNED ((uint32_t)0x00000040U) /*!< Misaligned address */ +#define SDMMC_ERROR_BLOCK_LEN_ERR ((uint32_t)0x00000080U) /*!< Transferred block length is not allowed for the card or the number of transferred bytes does not match the block length */ +#define SDMMC_ERROR_ERASE_SEQ_ERR ((uint32_t)0x00000100U) /*!< An error in the sequence of erase command occurs */ +#define SDMMC_ERROR_BAD_ERASE_PARAM ((uint32_t)0x00000200U) /*!< An invalid selection for erase groups */ +#define SDMMC_ERROR_WRITE_PROT_VIOLATION ((uint32_t)0x00000400U) /*!< Attempt to program a write protect block */ +#define SDMMC_ERROR_LOCK_UNLOCK_FAILED ((uint32_t)0x00000800U) /*!< Sequence or password error has been detected in unlock command or if there was an attempt to access a locked card */ +#define SDMMC_ERROR_COM_CRC_FAILED ((uint32_t)0x00001000U) /*!< CRC check of the previous command failed */ +#define SDMMC_ERROR_ILLEGAL_CMD ((uint32_t)0x00002000U) /*!< Command is not legal for the card state */ +#define SDMMC_ERROR_CARD_ECC_FAILED ((uint32_t)0x00004000U) /*!< Card internal ECC was applied but failed to correct the data */ +#define SDMMC_ERROR_CC_ERR ((uint32_t)0x00008000U) /*!< Internal card controller error */ +#define SDMMC_ERROR_GENERAL_UNKNOWN_ERR ((uint32_t)0x00010000U) /*!< General or unknown error */ +#define SDMMC_ERROR_STREAM_READ_UNDERRUN ((uint32_t)0x00020000U) /*!< The card could not sustain data reading in stream rmode */ +#define SDMMC_ERROR_STREAM_WRITE_OVERRUN ((uint32_t)0x00040000U) /*!< The card could not sustain data programming in stream mode */ +#define SDMMC_ERROR_CID_CSD_OVERWRITE ((uint32_t)0x00080000U) /*!< CID/CSD overwrite error */ +#define SDMMC_ERROR_WP_ERASE_SKIP ((uint32_t)0x00100000U) /*!< Only partial address space was erased */ +#define SDMMC_ERROR_CARD_ECC_DISABLED ((uint32_t)0x00200000U) /*!< Command has been executed without using internal ECC */ +#define SDMMC_ERROR_ERASE_RESET ((uint32_t)0x00400000U) /*!< Erase sequence was cleared before executing because an out of erase sequence command was received */ +#define SDMMC_ERROR_AKE_SEQ_ERR ((uint32_t)0x00800000U) /*!< Error in sequence of authentication */ +#define SDMMC_ERROR_INVALID_VOLTRANGE ((uint32_t)0x01000000U) /*!< Error in case of invalid voltage range */ +#define SDMMC_ERROR_ADDR_OUT_OF_RANGE ((uint32_t)0x02000000U) /*!< Error when addressed block is out of range */ +#define SDMMC_ERROR_REQUEST_NOT_APPLICABLE ((uint32_t)0x04000000U) /*!< Error when command request is not applicable */ +#define SDMMC_ERROR_INVALID_PARAMETER ((uint32_t)0x08000000U) /*!< the used parameter is not valid */ +#define SDMMC_ERROR_UNSUPPORTED_FEATURE ((uint32_t)0x10000000U) /*!< Error when feature is not insupported */ +#define SDMMC_ERROR_BUSY ((uint32_t)0x20000000U) /*!< Error when transfer process is busy */ +#define SDMMC_ERROR_DMA ((uint32_t)0x40000000U) /*!< Error while DMA transfer */ +#define SDMMC_ERROR_TIMEOUT ((uint32_t)0x80000000U) /*!< Timeout error */ + +/** + * @brief SDMMC Commands Index + */ +#define SDMMC_CMD_GO_IDLE_STATE ((uint8_t)0U) /*!< Resets the SD memory card. */ +#define SDMMC_CMD_SEND_OP_COND ((uint8_t)1U) /*!< Sends host capacity support information and activates the card's initialization process. */ +#define SDMMC_CMD_ALL_SEND_CID ((uint8_t)2U) /*!< Asks any card connected to the host to send the CID numbers on the CMD line. */ +#define SDMMC_CMD_SET_REL_ADDR ((uint8_t)3U) /*!< Asks the card to publish a new relative address (RCA). */ +#define SDMMC_CMD_SET_DSR ((uint8_t)4U) /*!< Programs the DSR of all cards. */ +#define SDMMC_CMD_SDMMC_SEN_OP_COND ((uint8_t)5U) /*!< Sends host capacity support information (HCS) and asks the accessed card to send its operating condition register (OCR) content in the response on the CMD line.*/ +#define SDMMC_CMD_HS_SWITCH ((uint8_t)6U) /*!< Checks switchable function (mode 0) and switch card function (mode 1). */ +#define SDMMC_CMD_SEL_DESEL_CARD ((uint8_t)7U) /*!< Selects the card by its own relative address and gets deselected by any other address */ +#define SDMMC_CMD_HS_SEND_EXT_CSD ((uint8_t)8U) /*!< Sends SD Memory Card interface condition, which includes host supply voltage information and asks the card whether card supports voltage. */ +#define SDMMC_CMD_SEND_CSD ((uint8_t)9U) /*!< Addressed card sends its card specific data (CSD) on the CMD line. */ +#define SDMMC_CMD_SEND_CID ((uint8_t)10U) /*!< Addressed card sends its card identification (CID) on the CMD line. */ +#define SDMMC_CMD_VOLTAGE_SWITCH ((uint8_t)11U) /*!< SD card Voltage switch to 1.8V mode. */ +#define SDMMC_CMD_STOP_TRANSMISSION ((uint8_t)12U) /*!< Forces the card to stop transmission. */ +#define SDMMC_CMD_SEND_STATUS ((uint8_t)13U) /*!< Addressed card sends its status register. */ +#define SDMMC_CMD_HS_BUSTEST_READ ((uint8_t)14U) /*!< Reserved */ +#define SDMMC_CMD_GO_INACTIVE_STATE ((uint8_t)15U) /*!< Sends an addressed card into the inactive state. */ +#define SDMMC_CMD_SET_BLOCKLEN ((uint8_t)16U) /*!< Sets the block length (in bytes for SDSC) for all following block commands (read, write, lock). Default block length is fixed to 512 Bytes. Not effective */ +/*!< for SDHS and SDXC. */ +#define SDMMC_CMD_READ_SINGLE_BLOCK ((uint8_t)17U) /*!< Reads single block of size selected by SET_BLOCKLEN in case of SDSC, and a block of fixed 512 bytes in case of SDHC and SDXC. */ +#define SDMMC_CMD_READ_MULT_BLOCK ((uint8_t)18U) /*!< Continuously transfers data blocks from card to host until interrupted by STOP_TRANSMISSION command. */ +#define SDMMC_CMD_HS_BUSTEST_WRITE ((uint8_t)19U) /*!< 64 bytes tuning pattern is sent for SDR50 and SDR104. */ +#define SDMMC_CMD_WRITE_DAT_UNTIL_STOP ((uint8_t)20U) /*!< Speed class control command. */ +#define SDMMC_CMD_SET_BLOCK_COUNT ((uint8_t)23U) /*!< Specify block count for CMD18 and CMD25. */ +#define SDMMC_CMD_WRITE_SINGLE_BLOCK ((uint8_t)24U) /*!< Writes single block of size selected by SET_BLOCKLEN in case of SDSC, and a block of fixed 512 bytes in case of SDHC and SDXC. */ +#define SDMMC_CMD_WRITE_MULT_BLOCK ((uint8_t)25U) /*!< Continuously writes blocks of data until a STOP_TRANSMISSION follows. */ +#define SDMMC_CMD_PROG_CID ((uint8_t)26U) /*!< Reserved for manufacturers. */ +#define SDMMC_CMD_PROG_CSD ((uint8_t)27U) /*!< Programming of the programmable bits of the CSD. */ +#define SDMMC_CMD_SET_WRITE_PROT ((uint8_t)28U) /*!< Sets the write protection bit of the addressed group. */ +#define SDMMC_CMD_CLR_WRITE_PROT ((uint8_t)29U) /*!< Clears the write protection bit of the addressed group. */ +#define SDMMC_CMD_SEND_WRITE_PROT ((uint8_t)30U) /*!< Asks the card to send the status of the write protection bits. */ +#define SDMMC_CMD_SD_ERASE_GRP_START ((uint8_t)32U) /*!< Sets the address of the first write block to be erased. (For SD card only). */ +#define SDMMC_CMD_SD_ERASE_GRP_END ((uint8_t)33U) /*!< Sets the address of the last write block of the continuous range to be erased. */ +#define SDMMC_CMD_ERASE_GRP_START ((uint8_t)35U) /*!< Sets the address of the first write block to be erased. Reserved for each command system set by switch function command (CMD6). */ +#define SDMMC_CMD_ERASE_GRP_END ((uint8_t)36U) /*!< Sets the address of the last write block of the continuous range to be erased. Reserved for each command system set by switch function command (CMD6). */ +#define SDMMC_CMD_ERASE ((uint8_t)38U) /*!< Reserved for SD security applications. */ +#define SDMMC_CMD_FAST_IO ((uint8_t)39U) /*!< SD card doesn't support it (Reserved). */ +#define SDMMC_CMD_GO_IRQ_STATE ((uint8_t)40U) /*!< SD card doesn't support it (Reserved). */ +#define SDMMC_CMD_LOCK_UNLOCK ((uint8_t)42U) /*!< Sets/resets the password or lock/unlock the card. The size of the data block is set by the SET_BLOCK_LEN command. */ +#define SDMMC_CMD_APP_CMD ((uint8_t)55U) /*!< Indicates to the card that the next command is an application specific command rather than a standard command. */ +#define SDMMC_CMD_GEN_CMD ((uint8_t)56U) /*!< Used either to transfer a data block to the card or to get a data block from the card for general purpose/application specific commands. */ +#define SDMMC_CMD_NO_CMD ((uint8_t)64U) /*!< No command */ + +/** + * @brief Following commands are SD Card Specific commands. + * SDMMC_APP_CMD should be sent before sending these commands. + */ +#define SDMMC_CMD_APP_SD_SET_BUSWIDTH ((uint8_t)6U) /*!< (ACMD6) Defines the data bus width to be used for data transfer. The allowed data bus widths are given in SCR register. */ +#define SDMMC_CMD_SD_APP_STATUS ((uint8_t)13U) /*!< (ACMD13) Sends the SD status. */ +#define SDMMC_CMD_SD_APP_SEND_NUM_WRITE_BLOCKS ((uint8_t)22U) /*!< (ACMD22) Sends the number of the written (without errors) write blocks. Responds with 32bit+CRC data block. */ +#define SDMMC_CMD_SD_APP_OP_COND ((uint8_t)41U) /*!< (ACMD41) Sends host capacity support information (HCS) and asks the accessed card to send its operating condition register (OCR) content in the response on the CMD line. */ +#define SDMMC_CMD_SD_APP_SET_CLR_CARD_DETECT ((uint8_t)42U) /*!< (ACMD42) Connect/Disconnect the 50 KOhm pull-up resistor on CD/DAT3 (pin 1) of the card */ +#define SDMMC_CMD_SD_APP_SEND_SCR ((uint8_t)51U) /*!< Reads the SD Configuration Register (SCR). */ +#define SDMMC_CMD_SDMMC_RW_DIRECT ((uint8_t)52U) /*!< For SD I/O card only, reserved for security specification. */ +#define SDMMC_CMD_SDMMC_RW_EXTENDED ((uint8_t)53U) /*!< For SD I/O card only, reserved for security specification. */ + +/** + * @brief Following commands are MMC Specific commands. + */ +#define SDMMC_CMD_MMC_SLEEP_AWAKE ((uint8_t)5U) /*!< Toggle the device between Sleep state and Standby state. */ + +/** + * @brief Following commands are SD Card Specific security commands. + * SDMMC_CMD_APP_CMD should be sent before sending these commands. + */ +#define SDMMC_CMD_SD_APP_GET_MKB ((uint8_t)43U) +#define SDMMC_CMD_SD_APP_GET_MID ((uint8_t)44U) +#define SDMMC_CMD_SD_APP_SET_CER_RN1 ((uint8_t)45U) +#define SDMMC_CMD_SD_APP_GET_CER_RN2 ((uint8_t)46U) +#define SDMMC_CMD_SD_APP_SET_CER_RES2 ((uint8_t)47U) +#define SDMMC_CMD_SD_APP_GET_CER_RES1 ((uint8_t)48U) +#define SDMMC_CMD_SD_APP_SECURE_READ_MULTIPLE_BLOCK ((uint8_t)18U) +#define SDMMC_CMD_SD_APP_SECURE_WRITE_MULTIPLE_BLOCK ((uint8_t)25U) +#define SDMMC_CMD_SD_APP_SECURE_ERASE ((uint8_t)38U) +#define SDMMC_CMD_SD_APP_CHANGE_SECURE_AREA ((uint8_t)49U) +#define SDMMC_CMD_SD_APP_SECURE_WRITE_MKB ((uint8_t)48U) + +/** + * @brief Masks for errors Card Status R1 (OCR Register) + */ +#define SDMMC_OCR_ADDR_OUT_OF_RANGE ((uint32_t)0x80000000U) +#define SDMMC_OCR_ADDR_MISALIGNED ((uint32_t)0x40000000U) +#define SDMMC_OCR_BLOCK_LEN_ERR ((uint32_t)0x20000000U) +#define SDMMC_OCR_ERASE_SEQ_ERR ((uint32_t)0x10000000U) +#define SDMMC_OCR_BAD_ERASE_PARAM ((uint32_t)0x08000000U) +#define SDMMC_OCR_WRITE_PROT_VIOLATION ((uint32_t)0x04000000U) +#define SDMMC_OCR_LOCK_UNLOCK_FAILED ((uint32_t)0x01000000U) +#define SDMMC_OCR_COM_CRC_FAILED ((uint32_t)0x00800000U) +#define SDMMC_OCR_ILLEGAL_CMD ((uint32_t)0x00400000U) +#define SDMMC_OCR_CARD_ECC_FAILED ((uint32_t)0x00200000U) +#define SDMMC_OCR_CC_ERROR ((uint32_t)0x00100000U) +#define SDMMC_OCR_GENERAL_UNKNOWN_ERROR ((uint32_t)0x00080000U) +#define SDMMC_OCR_STREAM_READ_UNDERRUN ((uint32_t)0x00040000U) +#define SDMMC_OCR_STREAM_WRITE_OVERRUN ((uint32_t)0x00020000U) +#define SDMMC_OCR_CID_CSD_OVERWRITE ((uint32_t)0x00010000U) +#define SDMMC_OCR_WP_ERASE_SKIP ((uint32_t)0x00008000U) +#define SDMMC_OCR_CARD_ECC_DISABLED ((uint32_t)0x00004000U) +#define SDMMC_OCR_ERASE_RESET ((uint32_t)0x00002000U) +#define SDMMC_OCR_AKE_SEQ_ERROR ((uint32_t)0x00000008U) +#define SDMMC_OCR_ERRORBITS ((uint32_t)0xFDFFE008U) + +/** + * @brief Masks for R6 Response + */ +#define SDMMC_R6_GENERAL_UNKNOWN_ERROR ((uint32_t)0x00002000U) +#define SDMMC_R6_ILLEGAL_CMD ((uint32_t)0x00004000U) +#define SDMMC_R6_COM_CRC_FAILED ((uint32_t)0x00008000U) + +#define SDMMC_VOLTAGE_WINDOW_SD ((uint32_t)0x80100000U) +#define SDMMC_HIGH_CAPACITY ((uint32_t)0x40000000U) +#define SDMMC_STD_CAPACITY ((uint32_t)0x00000000U) +#define SDMMC_CHECK_PATTERN ((uint32_t)0x000001AAU) +#define SD_SWITCH_1_8V_CAPACITY ((uint32_t)0x01000000U) +#define SDMMC_DDR50_SWITCH_PATTERN ((uint32_t)0x80FFFF04U) +#define SDMMC_SDR104_SWITCH_PATTERN ((uint32_t)0x80FF1F03U) +#define SDMMC_SDR50_SWITCH_PATTERN ((uint32_t)0x80FF1F02U) +#define SDMMC_SDR25_SWITCH_PATTERN ((uint32_t)0x80FFFF01U) +#define SDMMC_SDR12_SWITCH_PATTERN ((uint32_t)0x80FFFF00U) + +#define SDMMC_MAX_VOLT_TRIAL ((uint32_t)0x0000FFFFU) + +#define SDMMC_MAX_TRIAL ((uint32_t)0x0000FFFFU) + +#define SDMMC_ALLZERO ((uint32_t)0x00000000U) + +#define SDMMC_WIDE_BUS_SUPPORT ((uint32_t)0x00040000U) +#define SDMMC_SINGLE_BUS_SUPPORT ((uint32_t)0x00010000U) +#define SDMMC_CARD_LOCKED ((uint32_t)0x02000000U) + +#ifndef SDMMC_DATATIMEOUT /*Hardware Data Timeout (ms) */ +#define SDMMC_DATATIMEOUT ((uint32_t)0xFFFFFFFFU) +#endif /* SDMMC_DATATIMEOUT */ + +#ifndef SDMMC_SWDATATIMEOUT /*Software Data Timeout (ms) */ +#define SDMMC_SWDATATIMEOUT SDMMC_DATATIMEOUT +#endif /* SDMMC_SWDATATIMEOUT */ + +#define SDMMC_0TO7BITS ((uint32_t)0x000000FFU) +#define SDMMC_8TO15BITS ((uint32_t)0x0000FF00U) +#define SDMMC_16TO23BITS ((uint32_t)0x00FF0000U) +#define SDMMC_24TO31BITS ((uint32_t)0xFF000000U) +#define SDMMC_MAX_DATA_LENGTH ((uint32_t)0x01FFFFFFU) + +#define SDMMC_HALFFIFO ((uint32_t)0x00000008U) +#define SDMMC_HALFFIFOBYTES ((uint32_t)0x00000020U) + +/* SDMMC FIFO Size */ +#define SDMMC_FIFO_SIZE 32U +/** + * @brief Command Class supported + */ +#define SDMMC_CCCC_ERASE ((uint32_t)0x00000020U) + +#define SDMMC_CMDTIMEOUT ((uint32_t)5000U) /* Command send and response timeout */ +#define SDMMC_MAXERASETIMEOUT ((uint32_t)63000U) /* Max erase Timeout 63 s */ +#define SDMMC_STOPTRANSFERTIMEOUT ((uint32_t)100000000U) /* Timeout for STOP TRANSMISSION command */ + +/** @defgroup SDMMC_LL_Clock_Edge Clock Edge + * @{ + */ +#define SDMMC_CLOCK_EDGE_RISING ((uint32_t)0x00000000U) +#define SDMMC_CLOCK_EDGE_FALLING SDMMC_CLKCR_NEGEDGE + +#define IS_SDMMC_CLOCK_EDGE(EDGE) (((EDGE) == SDMMC_CLOCK_EDGE_RISING) || \ + ((EDGE) == SDMMC_CLOCK_EDGE_FALLING)) +/** + * @} + */ + +/** @defgroup SDMMC_LL_Clock_Power_Save Clock Power Saving + * @{ + */ +#define SDMMC_CLOCK_POWER_SAVE_DISABLE ((uint32_t)0x00000000U) +#define SDMMC_CLOCK_POWER_SAVE_ENABLE SDMMC_CLKCR_PWRSAV + +#define IS_SDMMC_CLOCK_POWER_SAVE(SAVE) (((SAVE) == SDMMC_CLOCK_POWER_SAVE_DISABLE) || \ + ((SAVE) == SDMMC_CLOCK_POWER_SAVE_ENABLE)) +/** + * @} + */ + +/** @defgroup SDMMC_LL_Bus_Wide Bus Width + * @{ + */ +#define SDMMC_BUS_WIDE_1B ((uint32_t)0x00000000U) +#define SDMMC_BUS_WIDE_4B SDMMC_CLKCR_WIDBUS_0 +#define SDMMC_BUS_WIDE_8B SDMMC_CLKCR_WIDBUS_1 + +#define IS_SDMMC_BUS_WIDE(WIDE) (((WIDE) == SDMMC_BUS_WIDE_1B) || \ + ((WIDE) == SDMMC_BUS_WIDE_4B) || \ + ((WIDE) == SDMMC_BUS_WIDE_8B)) +/** + * @} + */ + +/** @defgroup SDMMC_LL_Speed_Mode + * @{ + */ +#define SDMMC_SPEED_MODE_AUTO ((uint32_t)0x00000000U) +#define SDMMC_SPEED_MODE_DEFAULT ((uint32_t)0x00000001U) +#define SDMMC_SPEED_MODE_HIGH ((uint32_t)0x00000002U) +#define SDMMC_SPEED_MODE_ULTRA ((uint32_t)0x00000003U) +#define SDMMC_SPEED_MODE_ULTRA_SDR104 SDMMC_SPEED_MODE_ULTRA +#define SDMMC_SPEED_MODE_DDR ((uint32_t)0x00000004U) +#define SDMMC_SPEED_MODE_ULTRA_SDR50 ((uint32_t)0x00000005U) + +#define IS_SDMMC_SPEED_MODE(MODE) (((MODE) == SDMMC_SPEED_MODE_AUTO) || \ + ((MODE) == SDMMC_SPEED_MODE_DEFAULT) || \ + ((MODE) == SDMMC_SPEED_MODE_HIGH) || \ + ((MODE) == SDMMC_SPEED_MODE_ULTRA) || \ + ((MODE) == SDMMC_SPEED_MODE_ULTRA_SDR50) || \ + ((MODE) == SDMMC_SPEED_MODE_DDR)) + +/** + * @} + */ + +/** @defgroup SDMMC_LL_Hardware_Flow_Control Hardware Flow Control + * @{ + */ +#define SDMMC_HARDWARE_FLOW_CONTROL_DISABLE ((uint32_t)0x00000000U) +#define SDMMC_HARDWARE_FLOW_CONTROL_ENABLE SDMMC_CLKCR_HWFC_EN + +#define IS_SDMMC_HARDWARE_FLOW_CONTROL(CONTROL) (((CONTROL) == SDMMC_HARDWARE_FLOW_CONTROL_DISABLE) || \ + ((CONTROL) == SDMMC_HARDWARE_FLOW_CONTROL_ENABLE)) +/** + * @} + */ + +/** @defgroup SDMMC_LL_Clock_Division Clock Division + * @{ + */ +/* SDMMC_CK frequency = SDMMCCLK / [2 * CLKDIV] */ +#define IS_SDMMC_CLKDIV(DIV) ((DIV) < 0x400U) +/** + * @} + */ + +/** @defgroup SDMMC_LL_TRANSCEIVER_PRESENT Transceiver Present + * @{ + */ +#define SDMMC_TRANSCEIVER_UNKNOWN ((uint32_t)0x00000000U) +#define SDMMC_TRANSCEIVER_NOT_PRESENT ((uint32_t)0x00000001U) +#define SDMMC_TRANSCEIVER_PRESENT ((uint32_t)0x00000002U) + +/** + * @} + */ + +/** @defgroup SDMMC_LL_Command_Index Command Index + * @{ + */ +#define IS_SDMMC_CMD_INDEX(INDEX) ((INDEX) < 0x40U) +/** + * @} + */ + +/** @defgroup SDMMC_LL_Response_Type Response Type + * @{ + */ +#define SDMMC_RESPONSE_NO ((uint32_t)0x00000000U) +#define SDMMC_RESPONSE_SHORT SDMMC_CMD_WAITRESP_0 +#define SDMMC_RESPONSE_LONG SDMMC_CMD_WAITRESP + +#define IS_SDMMC_RESPONSE(RESPONSE) (((RESPONSE) == SDMMC_RESPONSE_NO) || \ + ((RESPONSE) == SDMMC_RESPONSE_SHORT) || \ + ((RESPONSE) == SDMMC_RESPONSE_LONG)) +/** + * @} + */ + +/** @defgroup SDMMC_LL_Wait_Interrupt_State Wait Interrupt + * @{ + */ +#define SDMMC_WAIT_NO ((uint32_t)0x00000000U) +#define SDMMC_WAIT_IT SDMMC_CMD_WAITINT +#define SDMMC_WAIT_PEND SDMMC_CMD_WAITPEND + +#define IS_SDMMC_WAIT(WAIT) (((WAIT) == SDMMC_WAIT_NO) || \ + ((WAIT) == SDMMC_WAIT_IT) || \ + ((WAIT) == SDMMC_WAIT_PEND)) +/** + * @} + */ + +/** @defgroup SDMMC_LL_CPSM_State CPSM State + * @{ + */ +#define SDMMC_CPSM_DISABLE ((uint32_t)0x00000000U) +#define SDMMC_CPSM_ENABLE SDMMC_CMD_CPSMEN + +#define IS_SDMMC_CPSM(CPSM) (((CPSM) == SDMMC_CPSM_DISABLE) || \ + ((CPSM) == SDMMC_CPSM_ENABLE)) +/** + * @} + */ + +/** @defgroup SDMMC_LL_Response_Registers Response Register + * @{ + */ +#define SDMMC_RESP1 ((uint32_t)0x00000000U) +#define SDMMC_RESP2 ((uint32_t)0x00000004U) +#define SDMMC_RESP3 ((uint32_t)0x00000008U) +#define SDMMC_RESP4 ((uint32_t)0x0000000CU) + +#define IS_SDMMC_RESP(RESP) (((RESP) == SDMMC_RESP1) || \ + ((RESP) == SDMMC_RESP2) || \ + ((RESP) == SDMMC_RESP3) || \ + ((RESP) == SDMMC_RESP4)) + +/** @defgroup SDMMC_Internal_DMA_Mode SDMMC Internal DMA Mode + * @{ + */ +#define SDMMC_DISABLE_IDMA ((uint32_t)0x00000000) +#define SDMMC_ENABLE_IDMA_SINGLE_BUFF (SDMMC_IDMA_IDMAEN) +#define SDMMC_ENABLE_IDMA_DOUBLE_BUFF0 (SDMMC_IDMA_IDMAEN | SDMMC_IDMA_IDMABMODE) +#define SDMMC_ENABLE_IDMA_DOUBLE_BUFF1 (SDMMC_IDMA_IDMAEN | SDMMC_IDMA_IDMABMODE | SDMMC_IDMA_IDMABACT) + +/** + * @} + */ + +/** @defgroup SDMMC_LL_Data_Length Data Length + * @{ + */ +#define IS_SDMMC_DATA_LENGTH(LENGTH) ((LENGTH) <= 0x01FFFFFFU) +/** + * @} + */ + +/** @defgroup SDMMC_LL_Data_Block_Size Data Block Size + * @{ + */ +#define SDMMC_DATABLOCK_SIZE_1B ((uint32_t)0x00000000U) +#define SDMMC_DATABLOCK_SIZE_2B SDMMC_DCTRL_DBLOCKSIZE_0 +#define SDMMC_DATABLOCK_SIZE_4B SDMMC_DCTRL_DBLOCKSIZE_1 +#define SDMMC_DATABLOCK_SIZE_8B (SDMMC_DCTRL_DBLOCKSIZE_0|SDMMC_DCTRL_DBLOCKSIZE_1) +#define SDMMC_DATABLOCK_SIZE_16B SDMMC_DCTRL_DBLOCKSIZE_2 +#define SDMMC_DATABLOCK_SIZE_32B (SDMMC_DCTRL_DBLOCKSIZE_0|SDMMC_DCTRL_DBLOCKSIZE_2) +#define SDMMC_DATABLOCK_SIZE_64B (SDMMC_DCTRL_DBLOCKSIZE_1|SDMMC_DCTRL_DBLOCKSIZE_2) +#define SDMMC_DATABLOCK_SIZE_128B (SDMMC_DCTRL_DBLOCKSIZE_0| \ + SDMMC_DCTRL_DBLOCKSIZE_1|SDMMC_DCTRL_DBLOCKSIZE_2) +#define SDMMC_DATABLOCK_SIZE_256B SDMMC_DCTRL_DBLOCKSIZE_3 +#define SDMMC_DATABLOCK_SIZE_512B (SDMMC_DCTRL_DBLOCKSIZE_0|SDMMC_DCTRL_DBLOCKSIZE_3) +#define SDMMC_DATABLOCK_SIZE_1024B (SDMMC_DCTRL_DBLOCKSIZE_1|SDMMC_DCTRL_DBLOCKSIZE_3) +#define SDMMC_DATABLOCK_SIZE_2048B (SDMMC_DCTRL_DBLOCKSIZE_0| \ + SDMMC_DCTRL_DBLOCKSIZE_1|SDMMC_DCTRL_DBLOCKSIZE_3) +#define SDMMC_DATABLOCK_SIZE_4096B (SDMMC_DCTRL_DBLOCKSIZE_2|SDMMC_DCTRL_DBLOCKSIZE_3) +#define SDMMC_DATABLOCK_SIZE_8192B (SDMMC_DCTRL_DBLOCKSIZE_0| \ + SDMMC_DCTRL_DBLOCKSIZE_2|SDMMC_DCTRL_DBLOCKSIZE_3) +#define SDMMC_DATABLOCK_SIZE_16384B (SDMMC_DCTRL_DBLOCKSIZE_1| \ + SDMMC_DCTRL_DBLOCKSIZE_2|SDMMC_DCTRL_DBLOCKSIZE_3) + +#define IS_SDMMC_BLOCK_SIZE(SIZE) (((SIZE) == SDMMC_DATABLOCK_SIZE_1B) || \ + ((SIZE) == SDMMC_DATABLOCK_SIZE_2B) || \ + ((SIZE) == SDMMC_DATABLOCK_SIZE_4B) || \ + ((SIZE) == SDMMC_DATABLOCK_SIZE_8B) || \ + ((SIZE) == SDMMC_DATABLOCK_SIZE_16B) || \ + ((SIZE) == SDMMC_DATABLOCK_SIZE_32B) || \ + ((SIZE) == SDMMC_DATABLOCK_SIZE_64B) || \ + ((SIZE) == SDMMC_DATABLOCK_SIZE_128B) || \ + ((SIZE) == SDMMC_DATABLOCK_SIZE_256B) || \ + ((SIZE) == SDMMC_DATABLOCK_SIZE_512B) || \ + ((SIZE) == SDMMC_DATABLOCK_SIZE_1024B) || \ + ((SIZE) == SDMMC_DATABLOCK_SIZE_2048B) || \ + ((SIZE) == SDMMC_DATABLOCK_SIZE_4096B) || \ + ((SIZE) == SDMMC_DATABLOCK_SIZE_8192B) || \ + ((SIZE) == SDMMC_DATABLOCK_SIZE_16384B)) +/** + * @} + */ + +/** @defgroup SDMMC_LL_Transfer_Direction Transfer Direction + * @{ + */ +#define SDMMC_TRANSFER_DIR_TO_CARD ((uint32_t)0x00000000U) +#define SDMMC_TRANSFER_DIR_TO_SDMMC SDMMC_DCTRL_DTDIR + +#define IS_SDMMC_TRANSFER_DIR(DIR) (((DIR) == SDMMC_TRANSFER_DIR_TO_CARD) || \ + ((DIR) == SDMMC_TRANSFER_DIR_TO_SDMMC)) +/** + * @} + */ + +/** @defgroup SDMMC_LL_Transfer_Type Transfer Type + * @{ + */ +#define SDMMC_TRANSFER_MODE_BLOCK ((uint32_t)0x00000000U) +#define SDMMC_TRANSFER_MODE_STREAM SDMMC_DCTRL_DTMODE_1 + +#define IS_SDMMC_TRANSFER_MODE(MODE) (((MODE) == SDMMC_TRANSFER_MODE_BLOCK) || \ + ((MODE) == SDMMC_TRANSFER_MODE_STREAM)) +/** + * @} + */ + +/** @defgroup SDMMC_LL_DPSM_State DPSM State + * @{ + */ +#define SDMMC_DPSM_DISABLE ((uint32_t)0x00000000U) +#define SDMMC_DPSM_ENABLE SDMMC_DCTRL_DTEN + +#define IS_SDMMC_DPSM(DPSM) (((DPSM) == SDMMC_DPSM_DISABLE) ||\ + ((DPSM) == SDMMC_DPSM_ENABLE)) +/** + * @} + */ + +/** @defgroup SDMMC_LL_Read_Wait_Mode Read Wait Mode + * @{ + */ +#define SDMMC_READ_WAIT_MODE_DATA2 ((uint32_t)0x00000000U) +#define SDMMC_READ_WAIT_MODE_CLK (SDMMC_DCTRL_RWMOD) + +#define IS_SDMMC_READWAIT_MODE(MODE) (((MODE) == SDMMC_READ_WAIT_MODE_CLK) || \ + ((MODE) == SDMMC_READ_WAIT_MODE_DATA2)) +/** + * @} + */ + +/** @defgroup SDMMC_LL_Interrupt_sources Interrupt Sources + * @{ + */ +#define SDMMC_IT_CCRCFAIL SDMMC_MASK_CCRCFAILIE +#define SDMMC_IT_DCRCFAIL SDMMC_MASK_DCRCFAILIE +#define SDMMC_IT_CTIMEOUT SDMMC_MASK_CTIMEOUTIE +#define SDMMC_IT_DTIMEOUT SDMMC_MASK_DTIMEOUTIE +#define SDMMC_IT_TXUNDERR SDMMC_MASK_TXUNDERRIE +#define SDMMC_IT_RXOVERR SDMMC_MASK_RXOVERRIE +#define SDMMC_IT_CMDREND SDMMC_MASK_CMDRENDIE +#define SDMMC_IT_CMDSENT SDMMC_MASK_CMDSENTIE +#define SDMMC_IT_DATAEND SDMMC_MASK_DATAENDIE +#define SDMMC_IT_DHOLD SDMMC_MASK_DHOLDIE +#define SDMMC_IT_DBCKEND SDMMC_MASK_DBCKENDIE +#define SDMMC_IT_DABORT SDMMC_MASK_DABORTIE +#define SDMMC_IT_TXFIFOHE SDMMC_MASK_TXFIFOHEIE +#define SDMMC_IT_RXFIFOHF SDMMC_MASK_RXFIFOHFIE +#define SDMMC_IT_RXFIFOF SDMMC_MASK_RXFIFOFIE +#define SDMMC_IT_TXFIFOE SDMMC_MASK_TXFIFOEIE +#define SDMMC_IT_BUSYD0END SDMMC_MASK_BUSYD0ENDIE +#define SDMMC_IT_SDIOIT SDMMC_MASK_SDIOITIE +#define SDMMC_IT_ACKFAIL SDMMC_MASK_ACKFAILIE +#define SDMMC_IT_ACKTIMEOUT SDMMC_MASK_ACKTIMEOUTIE +#define SDMMC_IT_VSWEND SDMMC_MASK_VSWENDIE +#define SDMMC_IT_CKSTOP SDMMC_MASK_CKSTOPIE +#define SDMMC_IT_IDMABTC SDMMC_MASK_IDMABTCIE +/** + * @} + */ + +/** @defgroup SDMMC_LL_Flags Flags + * @{ + */ +#define SDMMC_FLAG_CCRCFAIL SDMMC_STA_CCRCFAIL +#define SDMMC_FLAG_DCRCFAIL SDMMC_STA_DCRCFAIL +#define SDMMC_FLAG_CTIMEOUT SDMMC_STA_CTIMEOUT +#define SDMMC_FLAG_DTIMEOUT SDMMC_STA_DTIMEOUT +#define SDMMC_FLAG_TXUNDERR SDMMC_STA_TXUNDERR +#define SDMMC_FLAG_RXOVERR SDMMC_STA_RXOVERR +#define SDMMC_FLAG_CMDREND SDMMC_STA_CMDREND +#define SDMMC_FLAG_CMDSENT SDMMC_STA_CMDSENT +#define SDMMC_FLAG_DATAEND SDMMC_STA_DATAEND +#define SDMMC_FLAG_DHOLD SDMMC_STA_DHOLD +#define SDMMC_FLAG_DBCKEND SDMMC_STA_DBCKEND +#define SDMMC_FLAG_DABORT SDMMC_STA_DABORT +#define SDMMC_FLAG_DPSMACT SDMMC_STA_DPSMACT +#define SDMMC_FLAG_CMDACT SDMMC_STA_CPSMACT +#define SDMMC_FLAG_TXFIFOHE SDMMC_STA_TXFIFOHE +#define SDMMC_FLAG_RXFIFOHF SDMMC_STA_RXFIFOHF +#define SDMMC_FLAG_TXFIFOF SDMMC_STA_TXFIFOF +#define SDMMC_FLAG_RXFIFOF SDMMC_STA_RXFIFOF +#define SDMMC_FLAG_TXFIFOE SDMMC_STA_TXFIFOE +#define SDMMC_FLAG_RXFIFOE SDMMC_STA_RXFIFOE +#define SDMMC_FLAG_BUSYD0 SDMMC_STA_BUSYD0 +#define SDMMC_FLAG_BUSYD0END SDMMC_STA_BUSYD0END +#define SDMMC_FLAG_SDIOIT SDMMC_STA_SDIOIT +#define SDMMC_FLAG_ACKFAIL SDMMC_STA_ACKFAIL +#define SDMMC_FLAG_ACKTIMEOUT SDMMC_STA_ACKTIMEOUT +#define SDMMC_FLAG_VSWEND SDMMC_STA_VSWEND +#define SDMMC_FLAG_CKSTOP SDMMC_STA_CKSTOP +#define SDMMC_FLAG_IDMATE SDMMC_STA_IDMATE +#define SDMMC_FLAG_IDMABTC SDMMC_STA_IDMABTC + +#define SDMMC_STATIC_FLAGS ((uint32_t)(SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_CTIMEOUT |\ + SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_RXOVERR |\ + SDMMC_FLAG_CMDREND | SDMMC_FLAG_CMDSENT | SDMMC_FLAG_DATAEND |\ + SDMMC_FLAG_DHOLD | SDMMC_FLAG_DBCKEND | SDMMC_FLAG_DABORT |\ + SDMMC_FLAG_BUSYD0END | SDMMC_FLAG_SDIOIT | SDMMC_FLAG_ACKFAIL |\ + SDMMC_FLAG_ACKTIMEOUT | SDMMC_FLAG_VSWEND | SDMMC_FLAG_CKSTOP |\ + SDMMC_FLAG_IDMATE | SDMMC_FLAG_IDMABTC)) + +#define SDMMC_STATIC_CMD_FLAGS ((uint32_t)(SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CTIMEOUT | SDMMC_FLAG_CMDREND |\ + SDMMC_FLAG_CMDSENT | SDMMC_FLAG_BUSYD0END)) + +#define SDMMC_STATIC_DATA_FLAGS ((uint32_t)(SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_TXUNDERR |\ + SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DATAEND | SDMMC_FLAG_DHOLD |\ + SDMMC_FLAG_DBCKEND | SDMMC_FLAG_DABORT | SDMMC_FLAG_IDMATE |\ + SDMMC_FLAG_IDMABTC)) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup SDMMC_LL_Exported_macros SDMMC_LL Exported Macros + * @{ + */ + +/** @defgroup SDMMC_LL_Register Bits And Addresses Definitions + * @brief SDMMC_LL registers bit address in the alias region + * @{ + */ +/* ---------------------- SDMMC registers bit mask --------------------------- */ +/* --- CLKCR Register ---*/ +/* CLKCR register clear mask */ +#define CLKCR_CLEAR_MASK ((uint32_t)(SDMMC_CLKCR_CLKDIV | SDMMC_CLKCR_PWRSAV |\ + SDMMC_CLKCR_WIDBUS |\ + SDMMC_CLKCR_NEGEDGE | SDMMC_CLKCR_HWFC_EN |\ + SDMMC_CLKCR_DDR | SDMMC_CLKCR_BUSSPEED |\ + SDMMC_CLKCR_SELCLKRX)) + +/* --- DCTRL Register ---*/ +/* SDMMC DCTRL Clear Mask */ +#define DCTRL_CLEAR_MASK ((uint32_t)(SDMMC_DCTRL_DTEN | SDMMC_DCTRL_DTDIR |\ + SDMMC_DCTRL_DTMODE | SDMMC_DCTRL_DBLOCKSIZE)) + +/* --- CMD Register ---*/ +/* CMD Register clear mask */ +#define CMD_CLEAR_MASK ((uint32_t)(SDMMC_CMD_CMDINDEX | SDMMC_CMD_WAITRESP |\ + SDMMC_CMD_WAITINT | SDMMC_CMD_WAITPEND |\ + SDMMC_CMD_CPSMEN | SDMMC_CMD_CMDSUSPEND)) + +/* SDMMC Initialization Frequency (400KHz max) for Peripheral CLK 200MHz*/ +#define SDMMC_INIT_CLK_DIV ((uint8_t)0xFA) + +/* SDMMC Default Speed Frequency (25Mhz max) for Peripheral CLK 200MHz*/ +#define SDMMC_NSPEED_CLK_DIV ((uint8_t)0x4) + +/* SDMMC High Speed Frequency (50Mhz max) for Peripheral CLK 200MHz*/ +#define SDMMC_HSPEED_CLK_DIV ((uint8_t)0x2) +/** + * @} + */ + +/** @defgroup SDMMC_LL_Interrupt_Clock Interrupt And Clock Configuration + * @brief macros to handle interrupts and specific clock configurations + * @{ + */ + +/** + * @brief Enable the SDMMC device interrupt. + * @param __INSTANCE__ Pointer to SDMMC register base + * @param __INTERRUPT__ specifies the SDMMC interrupt sources to be enabled. + * This parameter can be one or a combination of the following values: + * @arg SDMMC_IT_CCRCFAIL: Command response received (CRC check failed) interrupt + * @arg SDMMC_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt + * @arg SDMMC_IT_CTIMEOUT: Command response timeout interrupt + * @arg SDMMC_IT_DTIMEOUT: Data timeout interrupt + * @arg SDMMC_IT_TXUNDERR: Transmit FIFO underrun error interrupt + * @arg SDMMC_IT_RXOVERR: Received FIFO overrun error interrupt + * @arg SDMMC_IT_CMDREND: Command response received (CRC check passed) interrupt + * @arg SDMMC_IT_CMDSENT: Command sent (no response required) interrupt + * @arg SDMMC_IT_DATAEND: Data end (data counter, DATACOUNT, is zero) interrupt + * @arg SDMMC_IT_DHOLD: Data transfer Hold interrupt + * @arg SDMMC_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt + * @arg SDMMC_IT_DABORT: Data transfer aborted by CMD12 interrupt + * @arg SDMMC_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt + * @arg SDMMC_IT_RXFIFOHF: Receive FIFO Half Full interrupt + * @arg SDMMC_IT_RXFIFOF: Receive FIFO full interrupt + * @arg SDMMC_IT_TXFIFOE: Transmit FIFO empty interrupt + * @arg SDMMC_IT_BUSYD0END: End of SDMMC_D0 Busy following a CMD response detected interrupt + * @arg SDMMC_IT_SDIOIT: SDIO interrupt received interrupt + * @arg SDMMC_IT_ACKFAIL: Boot Acknowledgment received interrupt + * @arg SDMMC_IT_ACKTIMEOUT: Boot Acknowledgment timeout interrupt + * @arg SDMMC_IT_VSWEND: Voltage switch critical timing section completion interrupt + * @arg SDMMC_IT_CKSTOP: SDMMC_CK stopped in Voltage switch procedure interrupt + * @arg SDMMC_IT_IDMABTC: IDMA buffer transfer complete interrupt + * @retval None + */ +#define __SDMMC_ENABLE_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->MASK |= (__INTERRUPT__)) + +/** + * @brief Disable the SDMMC device interrupt. + * @param __INSTANCE__ Pointer to SDMMC register base + * @param __INTERRUPT__ specifies the SDMMC interrupt sources to be disabled. + * This parameter can be one or a combination of the following values: + * @arg SDMMC_IT_CCRCFAIL: Command response received (CRC check failed) interrupt + * @arg SDMMC_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt + * @arg SDMMC_IT_CTIMEOUT: Command response timeout interrupt + * @arg SDMMC_IT_DTIMEOUT: Data timeout interrupt + * @arg SDMMC_IT_TXUNDERR: Transmit FIFO underrun error interrupt + * @arg SDMMC_IT_RXOVERR: Received FIFO overrun error interrupt + * @arg SDMMC_IT_CMDREND: Command response received (CRC check passed) interrupt + * @arg SDMMC_IT_CMDSENT: Command sent (no response required) interrupt + * @arg SDMMC_IT_DATAEND: Data end (data counter, DATACOUNT, is zero) interrupt + * @arg SDMMC_IT_DHOLD: Data transfer Hold interrupt + * @arg SDMMC_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt + * @arg SDMMC_IT_DABORT: Data transfer aborted by CMD12 interrupt + * @arg SDMMC_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt + * @arg SDMMC_IT_RXFIFOHF: Receive FIFO Half Full interrupt + * @arg SDMMC_IT_RXFIFOF: Receive FIFO full interrupt + * @arg SDMMC_IT_TXFIFOE: Transmit FIFO empty interrupt + * @arg SDMMC_IT_BUSYD0END: End of SDMMC_D0 Busy following a CMD response detected interrupt + * @arg SDMMC_IT_SDIOIT: SDIO interrupt received interrupt + * @arg SDMMC_IT_ACKFAIL: Boot Acknowledgment received interrupt + * @arg SDMMC_IT_ACKTIMEOUT: Boot Acknowledgment timeout interrupt + * @arg SDMMC_IT_VSWEND: Voltage switch critical timing section completion interrupt + * @arg SDMMC_IT_CKSTOP: SDMMC_CK stopped in Voltage switch procedure interrupt + * @arg SDMMC_IT_IDMABTC: IDMA buffer transfer complete interrupt + * @retval None + */ +#define __SDMMC_DISABLE_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->MASK &= ~(__INTERRUPT__)) + +/** + * @brief Checks whether the specified SDMMC flag is set or not. + * @param __INSTANCE__ Pointer to SDMMC register base + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg SDMMC_FLAG_CCRCFAIL: Command response received (CRC check failed) + * @arg SDMMC_FLAG_DCRCFAIL: Data block sent/received (CRC check failed) + * @arg SDMMC_FLAG_CTIMEOUT: Command response timeout + * @arg SDMMC_FLAG_DTIMEOUT: Data timeout + * @arg SDMMC_FLAG_TXUNDERR: Transmit FIFO underrun error + * @arg SDMMC_FLAG_RXOVERR: Received FIFO overrun error + * @arg SDMMC_FLAG_CMDREND: Command response received (CRC check passed) + * @arg SDMMC_FLAG_CMDSENT: Command sent (no response required) + * @arg SDMMC_FLAG_DATAEND: Data end (data counter, DATACOUNT, is zero) + * @arg SDMMC_FLAG_DHOLD: Data transfer Hold + * @arg SDMMC_FLAG_DBCKEND: Data block sent/received (CRC check passed) + * @arg SDMMC_FLAG_DABORT: Data transfer aborted by CMD12 + * @arg SDMMC_FLAG_DPSMACT: Data path state machine active + * @arg SDMMC_FLAG_CPSMACT: Command path state machine active + * @arg SDMMC_FLAG_TXFIFOHE: Transmit FIFO Half Empty + * @arg SDMMC_FLAG_RXFIFOHF: Receive FIFO Half Full + * @arg SDMMC_FLAG_TXFIFOF: Transmit FIFO full + * @arg SDMMC_FLAG_RXFIFOF: Receive FIFO full + * @arg SDMMC_FLAG_TXFIFOE: Transmit FIFO empty + * @arg SDMMC_FLAG_RXFIFOE: Receive FIFO empty + * @arg SDMMC_FLAG_BUSYD0: Inverted value of SDMMC_D0 line (Busy) + * @arg SDMMC_FLAG_BUSYD0END: End of SDMMC_D0 Busy following a CMD response detected + * @arg SDMMC_FLAG_SDIOIT: SDIO interrupt received + * @arg SDMMC_FLAG_ACKFAIL: Boot Acknowledgment received + * @arg SDMMC_FLAG_ACKTIMEOUT: Boot Acknowledgment timeout + * @arg SDMMC_FLAG_VSWEND: Voltage switch critical timing section completion + * @arg SDMMC_FLAG_CKSTOP: SDMMC_CK stopped in Voltage switch procedure + * @arg SDMMC_FLAG_IDMATE: IDMA transfer error + * @arg SDMMC_FLAG_IDMABTC: IDMA buffer transfer complete + * @retval The new state of SDMMC_FLAG (SET or RESET). + */ +#define __SDMMC_GET_FLAG(__INSTANCE__, __FLAG__) (((__INSTANCE__)->STA &(__FLAG__)) != 0U) + + +/** + * @brief Clears the SDMMC pending flags. + * @param __INSTANCE__ Pointer to SDMMC register base + * @param __FLAG__ specifies the flag to clear. + * This parameter can be one or a combination of the following values: + * @arg SDMMC_FLAG_CCRCFAIL: Command response received (CRC check failed) + * @arg SDMMC_FLAG_DCRCFAIL: Data block sent/received (CRC check failed) + * @arg SDMMC_FLAG_CTIMEOUT: Command response timeout + * @arg SDMMC_FLAG_DTIMEOUT: Data timeout + * @arg SDMMC_FLAG_TXUNDERR: Transmit FIFO underrun error + * @arg SDMMC_FLAG_RXOVERR: Received FIFO overrun error + * @arg SDMMC_FLAG_CMDREND: Command response received (CRC check passed) + * @arg SDMMC_FLAG_CMDSENT: Command sent (no response required) + * @arg SDMMC_FLAG_DATAEND: Data end (data counter, DATACOUNT, is zero) + * @arg SDMMC_FLAG_DHOLD: Data transfer Hold + * @arg SDMMC_FLAG_DBCKEND: Data block sent/received (CRC check passed) + * @arg SDMMC_FLAG_DABORT: Data transfer aborted by CMD12 + * @arg SDMMC_FLAG_BUSYD0END: End of SDMMC_D0 Busy following a CMD response detected + * @arg SDMMC_FLAG_SDIOIT: SDIO interrupt received + * @arg SDMMC_FLAG_ACKFAIL: Boot Acknowledgment received + * @arg SDMMC_FLAG_ACKTIMEOUT: Boot Acknowledgment timeout + * @arg SDMMC_FLAG_VSWEND: Voltage switch critical timing section completion + * @arg SDMMC_FLAG_CKSTOP: SDMMC_CK stopped in Voltage switch procedure + * @arg SDMMC_FLAG_IDMATE: IDMA transfer error + * @arg SDMMC_FLAG_IDMABTC: IDMA buffer transfer complete + * @retval None + */ +#define __SDMMC_CLEAR_FLAG(__INSTANCE__, __FLAG__) ((__INSTANCE__)->ICR = (__FLAG__)) + +/** + * @brief Checks whether the specified SDMMC interrupt has occurred or not. + * @param __INSTANCE__ Pointer to SDMMC register base + * @param __INTERRUPT__ specifies the SDMMC interrupt source to check. + * This parameter can be one of the following values: + * @arg SDMMC_IT_CCRCFAIL: Command response received (CRC check failed) interrupt + * @arg SDMMC_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt + * @arg SDMMC_IT_CTIMEOUT: Command response timeout interrupt + * @arg SDMMC_IT_DTIMEOUT: Data timeout interrupt + * @arg SDMMC_IT_TXUNDERR: Transmit FIFO underrun error interrupt + * @arg SDMMC_IT_RXOVERR: Received FIFO overrun error interrupt + * @arg SDMMC_IT_CMDREND: Command response received (CRC check passed) interrupt + * @arg SDMMC_IT_CMDSENT: Command sent (no response required) interrupt + * @arg SDMMC_IT_DATAEND: Data end (data counter, DATACOUNT, is zero) interrupt + * @arg SDMMC_IT_DHOLD: Data transfer Hold interrupt + * @arg SDMMC_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt + * @arg SDMMC_IT_DABORT: Data transfer aborted by CMD12 interrupt + * @arg SDMMC_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt + * @arg SDMMC_IT_RXFIFOHF: Receive FIFO Half Full interrupt + * @arg SDMMC_IT_RXFIFOF: Receive FIFO full interrupt + * @arg SDMMC_IT_TXFIFOE: Transmit FIFO empty interrupt + * @arg SDMMC_IT_BUSYD0END: End of SDMMC_D0 Busy following a CMD response detected interrupt + * @arg SDMMC_IT_SDIOIT: SDIO interrupt received interrupt + * @arg SDMMC_IT_ACKFAIL: Boot Acknowledgment received interrupt + * @arg SDMMC_IT_ACKTIMEOUT: Boot Acknowledgment timeout interrupt + * @arg SDMMC_IT_VSWEND: Voltage switch critical timing section completion interrupt + * @arg SDMMC_IT_CKSTOP: SDMMC_CK stopped in Voltage switch procedure interrupt + * @arg SDMMC_IT_IDMABTC: IDMA buffer transfer complete interrupt + * @retval The new state of SDMMC_IT (SET or RESET). + */ +#define __SDMMC_GET_IT(__INSTANCE__, __INTERRUPT__) (((__INSTANCE__)->STA &(__INTERRUPT__)) == (__INTERRUPT__)) + +/** + * @brief Clears the SDMMC's interrupt pending bits. + * @param __INSTANCE__ Pointer to SDMMC register base + * @param __INTERRUPT__ specifies the interrupt pending bit to clear. + * This parameter can be one or a combination of the following values: + * @arg SDMMC_IT_CCRCFAIL: Command response received (CRC check failed) interrupt + * @arg SDMMC_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt + * @arg SDMMC_IT_CTIMEOUT: Command response timeout interrupt + * @arg SDMMC_IT_DTIMEOUT: Data timeout interrupt + * @arg SDMMC_IT_TXUNDERR: Transmit FIFO underrun error interrupt + * @arg SDMMC_IT_RXOVERR: Received FIFO overrun error interrupt + * @arg SDMMC_IT_CMDREND: Command response received (CRC check passed) interrupt + * @arg SDMMC_IT_CMDSENT: Command sent (no response required) interrupt + * @arg SDMMC_IT_DATAEND: Data end (data counter, DATACOUNT, is zero) interrupt + * @arg SDMMC_IT_DHOLD: Data transfer Hold interrupt + * @arg SDMMC_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt + * @arg SDMMC_IT_DABORT: Data transfer aborted by CMD12 interrupt + * @arg SDMMC_IT_BUSYD0END: End of SDMMC_D0 Busy following a CMD response detected interrupt + * @arg SDMMC_IT_SDIOIT: SDIO interrupt received interrupt + * @arg SDMMC_IT_ACKFAIL: Boot Acknowledgment received interrupt + * @arg SDMMC_IT_ACKTIMEOUT: Boot Acknowledgment timeout interrupt + * @arg SDMMC_IT_VSWEND: Voltage switch critical timing section completion interrupt + * @arg SDMMC_IT_CKSTOP: SDMMC_CK stopped in Voltage switch procedure interrupt + * @arg SDMMC_IT_IDMABTC: IDMA buffer transfer complete interrupt + * @retval None + */ +#define __SDMMC_CLEAR_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->ICR = (__INTERRUPT__)) + +/** + * @brief Enable Start the SD I/O Read Wait operation. + * @param __INSTANCE__ Pointer to SDMMC register base + * @retval None + */ +#define __SDMMC_START_READWAIT_ENABLE(__INSTANCE__) ((__INSTANCE__)->DCTRL |= SDMMC_DCTRL_RWSTART) + +/** + * @brief Disable Start the SD I/O Read Wait operations. + * @param __INSTANCE__ Pointer to SDMMC register base + * @retval None + */ +#define __SDMMC_START_READWAIT_DISABLE(__INSTANCE__) ((__INSTANCE__)->DCTRL &= ~SDMMC_DCTRL_RWSTART) + +/** + * @brief Enable Start the SD I/O Read Wait operation. + * @param __INSTANCE__ Pointer to SDMMC register base + * @retval None + */ +#define __SDMMC_STOP_READWAIT_ENABLE(__INSTANCE__) ((__INSTANCE__)->DCTRL |= SDMMC_DCTRL_RWSTOP) + +/** + * @brief Disable Stop the SD I/O Read Wait operations. + * @param __INSTANCE__ Pointer to SDMMC register base + * @retval None + */ +#define __SDMMC_STOP_READWAIT_DISABLE(__INSTANCE__) ((__INSTANCE__)->DCTRL &= ~SDMMC_DCTRL_RWSTOP) + +/** + * @brief Enable the SD I/O Mode Operation. + * @param __INSTANCE__ Pointer to SDMMC register base + * @retval None + */ +#define __SDMMC_OPERATION_ENABLE(__INSTANCE__) ((__INSTANCE__)->DCTRL |= SDMMC_DCTRL_SDIOEN) + +/** + * @brief Disable the SD I/O Mode Operation. + * @param __INSTANCE__ Pointer to SDMMC register base + * @retval None + */ +#define __SDMMC_OPERATION_DISABLE(__INSTANCE__) ((__INSTANCE__)->DCTRL &= ~SDMMC_DCTRL_SDIOEN) + +/** + * @brief Enable the SD I/O Suspend command sending. + * @param __INSTANCE__ Pointer to SDMMC register base + * @retval None + */ +#define __SDMMC_SUSPEND_CMD_ENABLE(__INSTANCE__) ((__INSTANCE__)->CMD |= SDMMC_CMD_CMDSUSPEND) + +/** + * @brief Disable the SD I/O Suspend command sending. + * @param __INSTANCE__ Pointer to SDMMC register base + * @retval None + */ +#define __SDMMC_SUSPEND_CMD_DISABLE(__INSTANCE__) ((__INSTANCE__)->CMD &= ~SDMMC_CMD_CMDSUSPEND) + +/** + * @brief Enable the CMDTRANS mode. + * @param __INSTANCE__ Pointer to SDMMC register base + * @retval None + */ +#define __SDMMC_CMDTRANS_ENABLE(__INSTANCE__) ((__INSTANCE__)->CMD |= SDMMC_CMD_CMDTRANS) + +/** + * @brief Disable the CMDTRANS mode. + * @param __INSTANCE__ Pointer to SDMMC register base + * @retval None + */ +#define __SDMMC_CMDTRANS_DISABLE(__INSTANCE__) ((__INSTANCE__)->CMD &= ~SDMMC_CMD_CMDTRANS) + +/** + * @brief Enable the CMDSTOP mode. + * @param __INSTANCE__ Pointer to SDMMC register base + * @retval None + */ +#define __SDMMC_CMDSTOP_ENABLE(__INSTANCE__) ((__INSTANCE__)->CMD |= SDMMC_CMD_CMDSTOP) + +/** + * @brief Disable the CMDSTOP mode. + * @param __INSTANCE__ Pointer to SDMMC register base + * @retval None + */ +#define __SDMMC_CMDSTOP_DISABLE(__INSTANCE__) ((__INSTANCE__)->CMD &= ~SDMMC_CMD_CMDSTOP) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup SDMMC_LL_Exported_Functions + * @{ + */ + +/* Initialization/de-initialization functions **********************************/ +/** @addtogroup HAL_SDMMC_LL_Group1 + * @{ + */ +HAL_StatusTypeDef SDMMC_Init(SDMMC_TypeDef *SDMMCx, SDMMC_InitTypeDef Init); +/** + * @} + */ + +/* I/O operation functions *****************************************************/ +/** @addtogroup HAL_SDMMC_LL_Group2 + * @{ + */ +uint32_t SDMMC_ReadFIFO(const SDMMC_TypeDef *SDMMCx); +HAL_StatusTypeDef SDMMC_WriteFIFO(SDMMC_TypeDef *SDMMCx, uint32_t *pWriteData); +/** + * @} + */ + +/* Peripheral Control functions ************************************************/ +/** @addtogroup HAL_SDMMC_LL_Group3 + * @{ + */ +HAL_StatusTypeDef SDMMC_PowerState_ON(SDMMC_TypeDef *SDMMCx); +HAL_StatusTypeDef SDMMC_PowerState_Cycle(SDMMC_TypeDef *SDMMCx); +HAL_StatusTypeDef SDMMC_PowerState_OFF(SDMMC_TypeDef *SDMMCx); +uint32_t SDMMC_GetPowerState(const SDMMC_TypeDef *SDMMCx); + +/* Command path state machine (CPSM) management functions */ +HAL_StatusTypeDef SDMMC_SendCommand(SDMMC_TypeDef *SDMMCx, SDMMC_CmdInitTypeDef *Command); +uint8_t SDMMC_GetCommandResponse(const SDMMC_TypeDef *SDMMCx); +uint32_t SDMMC_GetResponse(const SDMMC_TypeDef *SDMMCx, uint32_t Response); + +/* Data path state machine (DPSM) management functions */ +HAL_StatusTypeDef SDMMC_ConfigData(SDMMC_TypeDef *SDMMCx, SDMMC_DataInitTypeDef *Data); +uint32_t SDMMC_GetDataCounter(const SDMMC_TypeDef *SDMMCx); +uint32_t SDMMC_GetFIFOCount(const SDMMC_TypeDef *SDMMCx); + +/* SDMMC Cards mode management functions */ +HAL_StatusTypeDef SDMMC_SetSDMMCReadWaitMode(SDMMC_TypeDef *SDMMCx, uint32_t SDMMC_ReadWaitMode); +/** + * @} + */ + +/* SDMMC Commands management functions ******************************************/ +/** @addtogroup HAL_SDMMC_LL_Group4 + * @{ + */ +uint32_t SDMMC_CmdBlockLength(SDMMC_TypeDef *SDMMCx, uint32_t BlockSize); +uint32_t SDMMC_CmdReadSingleBlock(SDMMC_TypeDef *SDMMCx, uint32_t ReadAdd); +uint32_t SDMMC_CmdReadMultiBlock(SDMMC_TypeDef *SDMMCx, uint32_t ReadAdd); +uint32_t SDMMC_CmdWriteSingleBlock(SDMMC_TypeDef *SDMMCx, uint32_t WriteAdd); +uint32_t SDMMC_CmdWriteMultiBlock(SDMMC_TypeDef *SDMMCx, uint32_t WriteAdd); +uint32_t SDMMC_CmdEraseStartAdd(SDMMC_TypeDef *SDMMCx, uint32_t StartAdd); +uint32_t SDMMC_CmdSDEraseStartAdd(SDMMC_TypeDef *SDMMCx, uint32_t StartAdd); +uint32_t SDMMC_CmdEraseEndAdd(SDMMC_TypeDef *SDMMCx, uint32_t EndAdd); +uint32_t SDMMC_CmdSDEraseEndAdd(SDMMC_TypeDef *SDMMCx, uint32_t EndAdd); +uint32_t SDMMC_CmdErase(SDMMC_TypeDef *SDMMCx, uint32_t EraseType); +uint32_t SDMMC_CmdStopTransfer(SDMMC_TypeDef *SDMMCx); +uint32_t SDMMC_CmdSelDesel(SDMMC_TypeDef *SDMMCx, uint32_t Addr); +uint32_t SDMMC_CmdGoIdleState(SDMMC_TypeDef *SDMMCx); +uint32_t SDMMC_CmdOperCond(SDMMC_TypeDef *SDMMCx); +uint32_t SDMMC_CmdAppCommand(SDMMC_TypeDef *SDMMCx, uint32_t Argument); +uint32_t SDMMC_CmdAppOperCommand(SDMMC_TypeDef *SDMMCx, uint32_t Argument); +uint32_t SDMMC_CmdBusWidth(SDMMC_TypeDef *SDMMCx, uint32_t BusWidth); +uint32_t SDMMC_CmdSendSCR(SDMMC_TypeDef *SDMMCx); +uint32_t SDMMC_CmdSendCID(SDMMC_TypeDef *SDMMCx); +uint32_t SDMMC_CmdSendCSD(SDMMC_TypeDef *SDMMCx, uint32_t Argument); +uint32_t SDMMC_CmdSetRelAdd(SDMMC_TypeDef *SDMMCx, uint16_t *pRCA); +uint32_t SDMMC_CmdSetRelAddMmc(SDMMC_TypeDef *SDMMCx, uint16_t RCA); +uint32_t SDMMC_CmdSleepMmc(SDMMC_TypeDef *SDMMCx, uint32_t Argument); +uint32_t SDMMC_CmdSendStatus(SDMMC_TypeDef *SDMMCx, uint32_t Argument); +uint32_t SDMMC_CmdStatusRegister(SDMMC_TypeDef *SDMMCx); +uint32_t SDMMC_CmdVoltageSwitch(SDMMC_TypeDef *SDMMCx); +uint32_t SDMMC_CmdOpCondition(SDMMC_TypeDef *SDMMCx, uint32_t Argument); +uint32_t SDMMC_CmdSwitch(SDMMC_TypeDef *SDMMCx, uint32_t Argument); +uint32_t SDMMC_CmdSendEXTCSD(SDMMC_TypeDef *SDMMCx, uint32_t Argument); +/** + * @} + */ + +/* SDMMC Responses management functions *****************************************/ +/** @addtogroup HAL_SDMMC_LL_Group5 + * @{ + */ +uint32_t SDMMC_GetCmdResp1(SDMMC_TypeDef *SDMMCx, uint8_t SD_CMD, uint32_t Timeout); +uint32_t SDMMC_GetCmdResp2(SDMMC_TypeDef *SDMMCx); +uint32_t SDMMC_GetCmdResp3(SDMMC_TypeDef *SDMMCx); +uint32_t SDMMC_GetCmdResp6(SDMMC_TypeDef *SDMMCx, uint8_t SD_CMD, uint16_t *pRCA); +uint32_t SDMMC_GetCmdResp7(SDMMC_TypeDef *SDMMCx); +/** + * @} + */ + +/* Linked List functions *******************************************************/ +/** @addtogroup HAL_SDMMC_LL_Group6 + * @{ + */ +uint32_t SDMMC_DMALinkedList_BuildNode(SDMMC_DMALinkNodeTypeDef *pNode, SDMMC_DMALinkNodeConfTypeDef *pNodeConf); +uint32_t SDMMC_DMALinkedList_InsertNode(SDMMC_DMALinkedListTypeDef *pLinkedList, SDMMC_DMALinkNodeTypeDef *pPrevNode, + SDMMC_DMALinkNodeTypeDef *pNode); +uint32_t SDMMC_DMALinkedList_RemoveNode(SDMMC_DMALinkedListTypeDef *pLinkedList, SDMMC_DMALinkNodeTypeDef *pNode); +uint32_t SDMMC_DMALinkedList_LockNode(SDMMC_DMALinkNodeTypeDef *pNode); +uint32_t SDMMC_DMALinkedList_UnlockNode(SDMMC_DMALinkNodeTypeDef *pNode); +uint32_t SDMMC_DMALinkedList_EnableCircularMode(SDMMC_DMALinkedListTypeDef *pLinkedList); +uint32_t SDMMC_DMALinkedList_DisableCircularMode(SDMMC_DMALinkedListTypeDef *pLinkedList); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* SDMMC1 || SDMMC2 */ +/** + * @} + */ +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_LL_SDMMC_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_spi.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_spi.h new file mode 100644 index 0000000000..9418b3ebef --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_spi.h @@ -0,0 +1,3662 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_spi.h + * @author MCD Application Team + * @brief Header file of SPI LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_LL_SPI_H +#define STM32H5xx_LL_SPI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined(SPI1) || defined(SPI2) || defined(SPI3) || defined(SPI4) || defined(SPI5) || defined(SPI6) + +/** @defgroup SPI_LL SPI + * @{ + */ + +/* Private variables ---------------------------------------------------------*/ + +/* Private constants ---------------------------------------------------------*/ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup SPI_LL_Private_Macros SPI Private Macros + * @{ + */ +/** + * @} + */ + +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup SPI_LL_Exported_Types SPI Exported Types + * @{ + */ + +/** + * @brief SPI Init structures definition + */ +typedef struct +{ + uint32_t TransferDirection; /*!< Specifies the SPI unidirectional or bidirectional data mode. + This parameter can be a value of @ref SPI_LL_EC_TRANSFER_MODE. + + This feature can be modified afterwards using unitary function + @ref LL_SPI_SetTransferDirection().*/ + + uint32_t Mode; /*!< Specifies the SPI mode (Master/Slave). + This parameter can be a value of @ref SPI_LL_EC_MODE. + + This feature can be modified afterwards using unitary function + @ref LL_SPI_SetMode().*/ + + uint32_t DataWidth; /*!< Specifies the SPI data width. + This parameter can be a value of @ref SPI_LL_EC_DATAWIDTH. + + This feature can be modified afterwards using unitary function + @ref LL_SPI_SetDataWidth().*/ + + uint32_t ClockPolarity; /*!< Specifies the serial clock steady state. + This parameter can be a value of @ref SPI_LL_EC_POLARITY. + + This feature can be modified afterwards using unitary function + @ref LL_SPI_SetClockPolarity().*/ + + uint32_t ClockPhase; /*!< Specifies the clock active edge for the bit capture. + This parameter can be a value of @ref SPI_LL_EC_PHASE. + + This feature can be modified afterwards using unitary function + @ref LL_SPI_SetClockPhase().*/ + + uint32_t NSS; /*!< Specifies whether the NSS signal is managed by hardware (NSS pin) + or by software using the SSI bit. + + This parameter can be a value of @ref SPI_LL_EC_NSS_MODE. + + This feature can be modified afterwards using unitary function + @ref LL_SPI_SetNSSMode().*/ + + uint32_t BaudRate; /*!< Specifies the BaudRate prescaler value which will be used to configure + the transmit and receive SCK clock. + This parameter can be a value of @ref SPI_LL_EC_BAUDRATEPRESCALER. + @note The communication clock is derived from the master clock. + The slave clock does not need to be set. + + This feature can be modified afterwards using unitary function + @ref LL_SPI_SetBaudRatePrescaler().*/ + + uint32_t BitOrder; /*!< Specifies whether data transfers start from MSB or LSB bit. + This parameter can be a value of @ref SPI_LL_EC_BIT_ORDER. + + This feature can be modified afterwards using unitary function + @ref LL_SPI_SetTransferBitOrder().*/ + + uint32_t CRCCalculation; /*!< Specifies if the CRC calculation is enabled or not. + This parameter can be a value of @ref SPI_LL_EC_CRC_CALCULATION. + + This feature can be modified afterwards using unitary functions + @ref LL_SPI_EnableCRC() and @ref LL_SPI_DisableCRC().*/ + + uint32_t CRCPoly; /*!< Specifies the polynomial used for the CRC calculation. + This parameter must be a number between Min_Data = 0x00 + and Max_Data = 0xFFFFFFFF. + + This feature can be modified afterwards using unitary function + @ref LL_SPI_SetCRCPolynomial().*/ + +} LL_SPI_InitTypeDef; + +/** + * @} + */ +#endif /*USE_FULL_LL_DRIVER*/ + +/* Exported types ------------------------------------------------------------*/ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup SPI_LL_Exported_Constants SPI Exported Constants + * @{ + */ + +/** @defgroup SPI_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_SPI_ReadReg function + * @{ + */ +#define LL_SPI_SR_RXP (SPI_SR_RXP) +#define LL_SPI_SR_TXP (SPI_SR_TXP) +#define LL_SPI_SR_DXP (SPI_SR_DXP) +#define LL_SPI_SR_EOT (SPI_SR_EOT) +#define LL_SPI_SR_TXTF (SPI_SR_TXTF) +#define LL_SPI_SR_UDR (SPI_SR_UDR) +#define LL_SPI_SR_CRCE (SPI_SR_CRCE) +#define LL_SPI_SR_MODF (SPI_SR_MODF) +#define LL_SPI_SR_OVR (SPI_SR_OVR) +#define LL_SPI_SR_TIFRE (SPI_SR_TIFRE) +#define LL_SPI_SR_SUSP (SPI_SR_SUSP) +#define LL_SPI_SR_TXC (SPI_SR_TXC) +#define LL_SPI_SR_RXWNE (SPI_SR_RXWNE) +/** + * @} + */ + +/** @defgroup SPI_LL_EC_IT IT Defines + * @brief IT defines which can be used with LL_SPI_ReadReg and LL_SPI_WriteReg functions + * @{ + */ +#define LL_SPI_IER_RXPIE (SPI_IER_RXPIE) +#define LL_SPI_IER_TXPIE (SPI_IER_TXPIE) +#define LL_SPI_IER_DXPIE (SPI_IER_DXPIE) +#define LL_SPI_IER_EOTIE (SPI_IER_EOTIE) +#define LL_SPI_IER_TXTFIE (SPI_IER_TXTFIE) +#define LL_SPI_IER_UDRIE (SPI_IER_UDRIE) +#define LL_SPI_IER_OVRIE (SPI_IER_OVRIE) +#define LL_SPI_IER_CRCEIE (SPI_IER_CRCEIE) +#define LL_SPI_IER_TIFREIE (SPI_IER_TIFREIE) +#define LL_SPI_IER_MODFIE (SPI_IER_MODFIE) +/** + * @} + */ + +/** @defgroup SPI_LL_EC_MODE Mode + * @{ + */ +#define LL_SPI_MODE_MASTER (SPI_CFG2_MASTER) +#define LL_SPI_MODE_SLAVE (0x00000000UL) +/** + * @} + */ + +/** @defgroup SPI_LL_EC_SS_LEVEL SS Level + * @{ + */ +#define LL_SPI_SS_LEVEL_HIGH (SPI_CR1_SSI) +#define LL_SPI_SS_LEVEL_LOW (0x00000000UL) +/** + * @} + */ + +/** @defgroup SPI_LL_EC_SS_IDLENESS SS Idleness + * @{ + */ +#define LL_SPI_SS_IDLENESS_00CYCLE (0x00000000UL) +#define LL_SPI_SS_IDLENESS_01CYCLE (SPI_CFG2_MSSI_0) +#define LL_SPI_SS_IDLENESS_02CYCLE (SPI_CFG2_MSSI_1) +#define LL_SPI_SS_IDLENESS_03CYCLE (SPI_CFG2_MSSI_0 | SPI_CFG2_MSSI_1) +#define LL_SPI_SS_IDLENESS_04CYCLE (SPI_CFG2_MSSI_2) +#define LL_SPI_SS_IDLENESS_05CYCLE (SPI_CFG2_MSSI_2 | SPI_CFG2_MSSI_0) +#define LL_SPI_SS_IDLENESS_06CYCLE (SPI_CFG2_MSSI_2 | SPI_CFG2_MSSI_1) +#define LL_SPI_SS_IDLENESS_07CYCLE (SPI_CFG2_MSSI_2 | SPI_CFG2_MSSI_1 | SPI_CFG2_MSSI_0) +#define LL_SPI_SS_IDLENESS_08CYCLE (SPI_CFG2_MSSI_3) +#define LL_SPI_SS_IDLENESS_09CYCLE (SPI_CFG2_MSSI_3 | SPI_CFG2_MSSI_0) +#define LL_SPI_SS_IDLENESS_10CYCLE (SPI_CFG2_MSSI_3 | SPI_CFG2_MSSI_1) +#define LL_SPI_SS_IDLENESS_11CYCLE (SPI_CFG2_MSSI_3 | SPI_CFG2_MSSI_1 | SPI_CFG2_MSSI_0) +#define LL_SPI_SS_IDLENESS_12CYCLE (SPI_CFG2_MSSI_3 | SPI_CFG2_MSSI_2) +#define LL_SPI_SS_IDLENESS_13CYCLE (SPI_CFG2_MSSI_3 | SPI_CFG2_MSSI_2 | SPI_CFG2_MSSI_0) +#define LL_SPI_SS_IDLENESS_14CYCLE (SPI_CFG2_MSSI_3 | SPI_CFG2_MSSI_2 | SPI_CFG2_MSSI_1) +#define LL_SPI_SS_IDLENESS_15CYCLE (SPI_CFG2_MSSI_3\ + | SPI_CFG2_MSSI_2 | SPI_CFG2_MSSI_1 | SPI_CFG2_MSSI_0) +/** + * @} + */ + +/** @defgroup SPI_LL_EC_ID_IDLENESS Master Inter-Data Idleness + * @{ + */ +#define LL_SPI_ID_IDLENESS_00CYCLE (0x00000000UL) +#define LL_SPI_ID_IDLENESS_01CYCLE (SPI_CFG2_MIDI_0) +#define LL_SPI_ID_IDLENESS_02CYCLE (SPI_CFG2_MIDI_1) +#define LL_SPI_ID_IDLENESS_03CYCLE (SPI_CFG2_MIDI_0 | SPI_CFG2_MIDI_1) +#define LL_SPI_ID_IDLENESS_04CYCLE (SPI_CFG2_MIDI_2) +#define LL_SPI_ID_IDLENESS_05CYCLE (SPI_CFG2_MIDI_2 | SPI_CFG2_MIDI_0) +#define LL_SPI_ID_IDLENESS_06CYCLE (SPI_CFG2_MIDI_2 | SPI_CFG2_MIDI_1) +#define LL_SPI_ID_IDLENESS_07CYCLE (SPI_CFG2_MIDI_2 | SPI_CFG2_MIDI_1 | SPI_CFG2_MIDI_0) +#define LL_SPI_ID_IDLENESS_08CYCLE (SPI_CFG2_MIDI_3) +#define LL_SPI_ID_IDLENESS_09CYCLE (SPI_CFG2_MIDI_3 | SPI_CFG2_MIDI_0) +#define LL_SPI_ID_IDLENESS_10CYCLE (SPI_CFG2_MIDI_3 | SPI_CFG2_MIDI_1) +#define LL_SPI_ID_IDLENESS_11CYCLE (SPI_CFG2_MIDI_3 | SPI_CFG2_MIDI_1 | SPI_CFG2_MIDI_0) +#define LL_SPI_ID_IDLENESS_12CYCLE (SPI_CFG2_MIDI_3 | SPI_CFG2_MIDI_2) +#define LL_SPI_ID_IDLENESS_13CYCLE (SPI_CFG2_MIDI_3 | SPI_CFG2_MIDI_2 | SPI_CFG2_MIDI_0) +#define LL_SPI_ID_IDLENESS_14CYCLE (SPI_CFG2_MIDI_3 | SPI_CFG2_MIDI_2 | SPI_CFG2_MIDI_1) +#define LL_SPI_ID_IDLENESS_15CYCLE (SPI_CFG2_MIDI_3\ + | SPI_CFG2_MIDI_2 | SPI_CFG2_MIDI_1 | SPI_CFG2_MIDI_0) +/** + * @} + */ + +/** @defgroup SPI_LL_EC_TXCRCINIT_ALL TXCRC Init All + * @{ + */ +#define LL_SPI_TXCRCINIT_ALL_ZERO_PATTERN (0x00000000UL) +#define LL_SPI_TXCRCINIT_ALL_ONES_PATTERN (SPI_CR1_TCRCINI) +/** + * @} + */ + +/** @defgroup SPI_LL_EC_RXCRCINIT_ALL RXCRC Init All + * @{ + */ +#define LL_SPI_RXCRCINIT_ALL_ZERO_PATTERN (0x00000000UL) +#define LL_SPI_RXCRCINIT_ALL_ONES_PATTERN (SPI_CR1_RCRCINI) +/** + * @} + */ + +/** @defgroup SPI_LL_EC_UDR_CONFIG_REGISTER UDR Config Register + * @{ + */ +#define LL_SPI_UDR_CONFIG_REGISTER_PATTERN (0x00000000UL) +#define LL_SPI_UDR_CONFIG_LAST_RECEIVED (SPI_CFG1_UDRCFG) +/** + * @} + */ + +/** @defgroup SPI_LL_EC_PROTOCOL Protocol + * @{ + */ +#define LL_SPI_PROTOCOL_MOTOROLA (0x00000000UL) +#define LL_SPI_PROTOCOL_TI (SPI_CFG2_SP_0) +/** + * @} + */ + +/** @defgroup SPI_LL_EC_PHASE Phase + * @{ + */ +#define LL_SPI_PHASE_1EDGE (0x00000000UL) +#define LL_SPI_PHASE_2EDGE (SPI_CFG2_CPHA) +/** + * @} + */ + +/** @defgroup SPI_LL_EC_POLARITY Polarity + * @{ + */ +#define LL_SPI_POLARITY_LOW (0x00000000UL) +#define LL_SPI_POLARITY_HIGH (SPI_CFG2_CPOL) +/** + * @} + */ + +/** @defgroup SPI_LL_EC_NSS_POLARITY NSS Polarity + * @{ + */ +#define LL_SPI_NSS_POLARITY_LOW (0x00000000UL) +#define LL_SPI_NSS_POLARITY_HIGH (SPI_CFG2_SSIOP) +/** + * @} + */ + +/** @defgroup SPI_LL_EC_BAUDRATEPRESCALER Baud Rate Prescaler + * @{ + */ +#define LL_SPI_BAUDRATEPRESCALER_BYPASS (SPI_CFG1_BPASS) +#define LL_SPI_BAUDRATEPRESCALER_DIV2 (0x00000000UL) +#define LL_SPI_BAUDRATEPRESCALER_DIV4 (SPI_CFG1_MBR_0) +#define LL_SPI_BAUDRATEPRESCALER_DIV8 (SPI_CFG1_MBR_1) +#define LL_SPI_BAUDRATEPRESCALER_DIV16 (SPI_CFG1_MBR_1 | SPI_CFG1_MBR_0) +#define LL_SPI_BAUDRATEPRESCALER_DIV32 (SPI_CFG1_MBR_2) +#define LL_SPI_BAUDRATEPRESCALER_DIV64 (SPI_CFG1_MBR_2 | SPI_CFG1_MBR_0) +#define LL_SPI_BAUDRATEPRESCALER_DIV128 (SPI_CFG1_MBR_2 | SPI_CFG1_MBR_1) +#define LL_SPI_BAUDRATEPRESCALER_DIV256 (SPI_CFG1_MBR_2 | SPI_CFG1_MBR_1 | SPI_CFG1_MBR_0) +/** + * @} + */ + +/** @defgroup SPI_LL_EC_BIT_ORDER Bit Order + * @{ + */ +#define LL_SPI_LSB_FIRST (SPI_CFG2_LSBFRST) +#define LL_SPI_MSB_FIRST (0x00000000UL) +/** + * @} + */ + +/** @defgroup SPI_LL_EC_TRANSFER_MODE Transfer Mode + * @{ + */ +#define LL_SPI_FULL_DUPLEX (0x00000000UL) +#define LL_SPI_SIMPLEX_TX (SPI_CFG2_COMM_0) +#define LL_SPI_SIMPLEX_RX (SPI_CFG2_COMM_1) +#define LL_SPI_HALF_DUPLEX_RX (SPI_CFG2_COMM_0|SPI_CFG2_COMM_1) +#define LL_SPI_HALF_DUPLEX_TX (SPI_CFG2_COMM_0|SPI_CFG2_COMM_1|SPI_CR1_HDDIR) +/** + * @} + */ + +/** @defgroup SPI_LL_EC_DATAWIDTH Data Width + * @{ + */ +#define LL_SPI_DATAWIDTH_4BIT (SPI_CFG1_DSIZE_0 | SPI_CFG1_DSIZE_1) +#define LL_SPI_DATAWIDTH_5BIT (SPI_CFG1_DSIZE_2) +#define LL_SPI_DATAWIDTH_6BIT (SPI_CFG1_DSIZE_2 | SPI_CFG1_DSIZE_0) +#define LL_SPI_DATAWIDTH_7BIT (SPI_CFG1_DSIZE_2 | SPI_CFG1_DSIZE_1) +#define LL_SPI_DATAWIDTH_8BIT (SPI_CFG1_DSIZE_2 | SPI_CFG1_DSIZE_1 | SPI_CFG1_DSIZE_0) +#define LL_SPI_DATAWIDTH_9BIT (SPI_CFG1_DSIZE_3) +#define LL_SPI_DATAWIDTH_10BIT (SPI_CFG1_DSIZE_3 | SPI_CFG1_DSIZE_0) +#define LL_SPI_DATAWIDTH_11BIT (SPI_CFG1_DSIZE_3 | SPI_CFG1_DSIZE_1) +#define LL_SPI_DATAWIDTH_12BIT (SPI_CFG1_DSIZE_3 | SPI_CFG1_DSIZE_1 | SPI_CFG1_DSIZE_0) +#define LL_SPI_DATAWIDTH_13BIT (SPI_CFG1_DSIZE_3 | SPI_CFG1_DSIZE_2) +#define LL_SPI_DATAWIDTH_14BIT (SPI_CFG1_DSIZE_3 | SPI_CFG1_DSIZE_2 | SPI_CFG1_DSIZE_0) +#define LL_SPI_DATAWIDTH_15BIT (SPI_CFG1_DSIZE_3 | SPI_CFG1_DSIZE_2 | SPI_CFG1_DSIZE_1) +#define LL_SPI_DATAWIDTH_16BIT (SPI_CFG1_DSIZE_3\ + | SPI_CFG1_DSIZE_2 | SPI_CFG1_DSIZE_1 | SPI_CFG1_DSIZE_0) +#define LL_SPI_DATAWIDTH_17BIT (SPI_CFG1_DSIZE_4) +#define LL_SPI_DATAWIDTH_18BIT (SPI_CFG1_DSIZE_4 | SPI_CFG1_DSIZE_0) +#define LL_SPI_DATAWIDTH_19BIT (SPI_CFG1_DSIZE_4 | SPI_CFG1_DSIZE_1) +#define LL_SPI_DATAWIDTH_20BIT (SPI_CFG1_DSIZE_4 | SPI_CFG1_DSIZE_0 | SPI_CFG1_DSIZE_1) +#define LL_SPI_DATAWIDTH_21BIT (SPI_CFG1_DSIZE_4 | SPI_CFG1_DSIZE_2) +#define LL_SPI_DATAWIDTH_22BIT (SPI_CFG1_DSIZE_4 | SPI_CFG1_DSIZE_2 | SPI_CFG1_DSIZE_0) +#define LL_SPI_DATAWIDTH_23BIT (SPI_CFG1_DSIZE_4 | SPI_CFG1_DSIZE_2 | SPI_CFG1_DSIZE_1) +#define LL_SPI_DATAWIDTH_24BIT (SPI_CFG1_DSIZE_4\ + | SPI_CFG1_DSIZE_2 | SPI_CFG1_DSIZE_1 | SPI_CFG1_DSIZE_0) +#define LL_SPI_DATAWIDTH_25BIT (SPI_CFG1_DSIZE_4 | SPI_CFG1_DSIZE_3) +#define LL_SPI_DATAWIDTH_26BIT (SPI_CFG1_DSIZE_4 | SPI_CFG1_DSIZE_3 | SPI_CFG1_DSIZE_0) +#define LL_SPI_DATAWIDTH_27BIT (SPI_CFG1_DSIZE_4 | SPI_CFG1_DSIZE_3 | SPI_CFG1_DSIZE_1) +#define LL_SPI_DATAWIDTH_28BIT (SPI_CFG1_DSIZE_4\ + | SPI_CFG1_DSIZE_3 | SPI_CFG1_DSIZE_1 | SPI_CFG1_DSIZE_0) +#define LL_SPI_DATAWIDTH_29BIT (SPI_CFG1_DSIZE_4 | SPI_CFG1_DSIZE_3 | SPI_CFG1_DSIZE_2) +#define LL_SPI_DATAWIDTH_30BIT (SPI_CFG1_DSIZE_4\ + | SPI_CFG1_DSIZE_3 | SPI_CFG1_DSIZE_2 | SPI_CFG1_DSIZE_0) +#define LL_SPI_DATAWIDTH_31BIT (SPI_CFG1_DSIZE_4\ + | SPI_CFG1_DSIZE_3 | SPI_CFG1_DSIZE_2 | SPI_CFG1_DSIZE_1) +#define LL_SPI_DATAWIDTH_32BIT (SPI_CFG1_DSIZE_4 | SPI_CFG1_DSIZE_3\ + | SPI_CFG1_DSIZE_2 | SPI_CFG1_DSIZE_1 | SPI_CFG1_DSIZE_0) +/** + * @} + */ + +/** @defgroup SPI_LL_EC_FIFO_TH FIFO Threshold + * @{ + */ +#define LL_SPI_FIFO_TH_01DATA (0x00000000UL) +#define LL_SPI_FIFO_TH_02DATA (SPI_CFG1_FTHLV_0) +#define LL_SPI_FIFO_TH_03DATA (SPI_CFG1_FTHLV_1) +#define LL_SPI_FIFO_TH_04DATA (SPI_CFG1_FTHLV_0 | SPI_CFG1_FTHLV_1) +#define LL_SPI_FIFO_TH_05DATA (SPI_CFG1_FTHLV_2) +#define LL_SPI_FIFO_TH_06DATA (SPI_CFG1_FTHLV_2 | SPI_CFG1_FTHLV_0) +#define LL_SPI_FIFO_TH_07DATA (SPI_CFG1_FTHLV_2 | SPI_CFG1_FTHLV_1) +#define LL_SPI_FIFO_TH_08DATA (SPI_CFG1_FTHLV_2 | SPI_CFG1_FTHLV_1 | SPI_CFG1_FTHLV_0) +#define LL_SPI_FIFO_TH_09DATA (SPI_CFG1_FTHLV_3) +#define LL_SPI_FIFO_TH_10DATA (SPI_CFG1_FTHLV_3 | SPI_CFG1_FTHLV_0) +#define LL_SPI_FIFO_TH_11DATA (SPI_CFG1_FTHLV_3 | SPI_CFG1_FTHLV_1) +#define LL_SPI_FIFO_TH_12DATA (SPI_CFG1_FTHLV_3 | SPI_CFG1_FTHLV_1 | SPI_CFG1_FTHLV_0) +#define LL_SPI_FIFO_TH_13DATA (SPI_CFG1_FTHLV_3 | SPI_CFG1_FTHLV_2) +#define LL_SPI_FIFO_TH_14DATA (SPI_CFG1_FTHLV_3 | SPI_CFG1_FTHLV_2 | SPI_CFG1_FTHLV_0) +#define LL_SPI_FIFO_TH_15DATA (SPI_CFG1_FTHLV_3 | SPI_CFG1_FTHLV_2 | SPI_CFG1_FTHLV_1) +#define LL_SPI_FIFO_TH_16DATA (SPI_CFG1_FTHLV_3\ + | SPI_CFG1_FTHLV_2 | SPI_CFG1_FTHLV_1 | SPI_CFG1_FTHLV_0) +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) + +/** @defgroup SPI_LL_EC_CRC_CALCULATION CRC Calculation + * @{ + */ +#define LL_SPI_CRCCALCULATION_DISABLE (0x00000000UL) /*!< CRC calculation disabled */ +#define LL_SPI_CRCCALCULATION_ENABLE (SPI_CFG1_CRCEN) /*!< CRC calculation enabled */ +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** @defgroup SPI_LL_EC_CRC CRC + * @{ + */ +#define LL_SPI_CRC_4BIT (SPI_CFG1_CRCSIZE_0 | SPI_CFG1_CRCSIZE_1) +#define LL_SPI_CRC_5BIT (SPI_CFG1_CRCSIZE_2) +#define LL_SPI_CRC_6BIT (SPI_CFG1_CRCSIZE_2 | SPI_CFG1_CRCSIZE_0) +#define LL_SPI_CRC_7BIT (SPI_CFG1_CRCSIZE_2 | SPI_CFG1_CRCSIZE_1) +#define LL_SPI_CRC_8BIT (SPI_CFG1_CRCSIZE_2 | SPI_CFG1_CRCSIZE_1 | SPI_CFG1_CRCSIZE_0) +#define LL_SPI_CRC_9BIT (SPI_CFG1_CRCSIZE_3) +#define LL_SPI_CRC_10BIT (SPI_CFG1_CRCSIZE_3 | SPI_CFG1_CRCSIZE_0) +#define LL_SPI_CRC_11BIT (SPI_CFG1_CRCSIZE_3 | SPI_CFG1_CRCSIZE_1) +#define LL_SPI_CRC_12BIT (SPI_CFG1_CRCSIZE_3 | SPI_CFG1_CRCSIZE_1 | SPI_CFG1_CRCSIZE_0) +#define LL_SPI_CRC_13BIT (SPI_CFG1_CRCSIZE_3 | SPI_CFG1_CRCSIZE_2) +#define LL_SPI_CRC_14BIT (SPI_CFG1_CRCSIZE_3 | SPI_CFG1_CRCSIZE_2 | SPI_CFG1_CRCSIZE_0) +#define LL_SPI_CRC_15BIT (SPI_CFG1_CRCSIZE_3 | SPI_CFG1_CRCSIZE_2 | SPI_CFG1_CRCSIZE_1) +#define LL_SPI_CRC_16BIT (SPI_CFG1_CRCSIZE_3\ + | SPI_CFG1_CRCSIZE_2 | SPI_CFG1_CRCSIZE_1 | SPI_CFG1_CRCSIZE_0) +#define LL_SPI_CRC_17BIT (SPI_CFG1_CRCSIZE_4) +#define LL_SPI_CRC_18BIT (SPI_CFG1_CRCSIZE_4 | SPI_CFG1_CRCSIZE_0) +#define LL_SPI_CRC_19BIT (SPI_CFG1_CRCSIZE_4 | SPI_CFG1_CRCSIZE_1) +#define LL_SPI_CRC_20BIT (SPI_CFG1_CRCSIZE_4 | SPI_CFG1_CRCSIZE_0 | SPI_CFG1_CRCSIZE_1) +#define LL_SPI_CRC_21BIT (SPI_CFG1_CRCSIZE_4 | SPI_CFG1_CRCSIZE_2) +#define LL_SPI_CRC_22BIT (SPI_CFG1_CRCSIZE_4 | SPI_CFG1_CRCSIZE_2 | SPI_CFG1_CRCSIZE_0) +#define LL_SPI_CRC_23BIT (SPI_CFG1_CRCSIZE_4 | SPI_CFG1_CRCSIZE_2 | SPI_CFG1_CRCSIZE_1) +#define LL_SPI_CRC_24BIT (SPI_CFG1_CRCSIZE_4\ + | SPI_CFG1_CRCSIZE_2 | SPI_CFG1_CRCSIZE_1 | SPI_CFG1_CRCSIZE_0) +#define LL_SPI_CRC_25BIT (SPI_CFG1_CRCSIZE_4 | SPI_CFG1_CRCSIZE_3) +#define LL_SPI_CRC_26BIT (SPI_CFG1_CRCSIZE_4 | SPI_CFG1_CRCSIZE_3 | SPI_CFG1_CRCSIZE_0) +#define LL_SPI_CRC_27BIT (SPI_CFG1_CRCSIZE_4 | SPI_CFG1_CRCSIZE_3 | SPI_CFG1_CRCSIZE_1) +#define LL_SPI_CRC_28BIT (SPI_CFG1_CRCSIZE_4\ + | SPI_CFG1_CRCSIZE_3 | SPI_CFG1_CRCSIZE_1 | SPI_CFG1_CRCSIZE_0) +#define LL_SPI_CRC_29BIT (SPI_CFG1_CRCSIZE_4 | SPI_CFG1_CRCSIZE_3 | SPI_CFG1_CRCSIZE_2) +#define LL_SPI_CRC_30BIT (SPI_CFG1_CRCSIZE_4\ + | SPI_CFG1_CRCSIZE_3 | SPI_CFG1_CRCSIZE_2 | SPI_CFG1_CRCSIZE_0) +#define LL_SPI_CRC_31BIT (SPI_CFG1_CRCSIZE_4\ + | SPI_CFG1_CRCSIZE_3 | SPI_CFG1_CRCSIZE_2 | SPI_CFG1_CRCSIZE_1) +#define LL_SPI_CRC_32BIT (SPI_CFG1_CRCSIZE_4 | SPI_CFG1_CRCSIZE_3\ + | SPI_CFG1_CRCSIZE_2 | SPI_CFG1_CRCSIZE_1 | SPI_CFG1_CRCSIZE_0) +/** + * @} + */ + +/** @defgroup SPI_LL_EC_NSS_MODE NSS Mode + * @{ + */ +#define LL_SPI_NSS_SOFT (SPI_CFG2_SSM) +#define LL_SPI_NSS_HARD_INPUT (0x00000000UL) +#define LL_SPI_NSS_HARD_OUTPUT (SPI_CFG2_SSOE) +/** + * @} + */ + +/** @defgroup SPI_LL_EC_RX_FIFO RxFIFO Packing LeVel + * @{ + */ +#define LL_SPI_RX_FIFO_0PACKET (0x00000000UL) /* 0 or multiple of 4 packet available is the RxFIFO */ +#define LL_SPI_RX_FIFO_1PACKET (SPI_SR_RXPLVL_0) +#define LL_SPI_RX_FIFO_2PACKET (SPI_SR_RXPLVL_1) +#define LL_SPI_RX_FIFO_3PACKET (SPI_SR_RXPLVL_1 | SPI_SR_RXPLVL_0) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup SPI_LL_Exported_Macros SPI Exported Macros + * @{ + */ + +/** @defgroup SPI_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in SPI register + * @param __INSTANCE__ SPI Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_SPI_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in SPI register + * @param __INSTANCE__ SPI Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_SPI_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) +/** + * @} + */ + +/** + * @} + */ + + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup SPI_LL_Exported_Functions SPI Exported Functions + * @{ + */ + +/** @defgroup SPI_LL_EF_Configuration Configuration + * @{ + */ + +/** + * @brief Enable SPI peripheral + * @rmtoll CR1 SPE LL_SPI_Enable + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_Enable(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->CR1, SPI_CR1_SPE); +} + +/** + * @brief Disable SPI peripheral + * @note When disabling the SPI, follow the procedure described in the Reference Manual. + * @rmtoll CR1 SPE LL_SPI_Disable + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_Disable(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->CR1, SPI_CR1_SPE); +} + +/** + * @brief Check if SPI peripheral is enabled + * @rmtoll CR1 SPE LL_SPI_IsEnabled + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_SPI_IsEnabled(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->CR1, SPI_CR1_SPE) == (SPI_CR1_SPE)) ? 1UL : 0UL); +} + +/** + * @brief Swap the MOSI and MISO pin + * @note This configuration can not be changed when SPI is enabled. + * @rmtoll CFG2 IOSWP LL_SPI_EnableIOSwap + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_EnableIOSwap(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->CFG2, SPI_CFG2_IOSWP); +} + +/** + * @brief Restore default function for MOSI and MISO pin + * @note This configuration can not be changed when SPI is enabled. + * @rmtoll CFG2 IOSWP LL_SPI_DisableIOSwap + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_DisableIOSwap(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->CFG2, SPI_CFG2_IOSWP); +} + +/** + * @brief Check if MOSI and MISO pin are swapped + * @rmtoll CFG2 IOSWP LL_SPI_IsEnabledIOSwap + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_SPI_IsEnabledIOSwap(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->CFG2, SPI_CFG2_IOSWP) == (SPI_CFG2_IOSWP)) ? 1UL : 0UL); +} + +/** + * @brief Enable GPIO control + * @note This configuration can not be changed when SPI is enabled. + * @rmtoll CFG2 AFCNTR LL_SPI_EnableGPIOControl + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_EnableGPIOControl(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->CFG2, SPI_CFG2_AFCNTR); +} + +/** + * @brief Disable GPIO control + * @note This configuration can not be changed when SPI is enabled. + * @rmtoll CFG2 AFCNTR LL_SPI_DisableGPIOControl + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_DisableGPIOControl(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->CFG2, SPI_CFG2_AFCNTR); +} + +/** + * @brief Check if GPIO control is active + * @rmtoll CFG2 AFCNTR LL_SPI_IsEnabledGPIOControl + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_SPI_IsEnabledGPIOControl(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->CFG2, SPI_CFG2_AFCNTR) == (SPI_CFG2_AFCNTR)) ? 1UL : 0UL); +} + +/** + * @brief Set SPI Mode to Master or Slave + * @note This configuration can not be changed when SPI is enabled. + * @rmtoll CFG2 MASTER LL_SPI_SetMode + * @param SPIx SPI Instance + * @param Mode This parameter can be one of the following values: + * @arg @ref LL_SPI_MODE_MASTER + * @arg @ref LL_SPI_MODE_SLAVE + * @retval None + */ +__STATIC_INLINE void LL_SPI_SetMode(SPI_TypeDef *SPIx, uint32_t Mode) +{ + MODIFY_REG(SPIx->CFG2, SPI_CFG2_MASTER, Mode); +} + +/** + * @brief Get SPI Mode (Master or Slave) + * @rmtoll CFG2 MASTER LL_SPI_GetMode + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_MODE_MASTER + * @arg @ref LL_SPI_MODE_SLAVE + */ +__STATIC_INLINE uint32_t LL_SPI_GetMode(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CFG2, SPI_CFG2_MASTER)); +} + +/** + * @brief Configure the Idleness applied by master between active edge of SS and first send data + * @rmtoll CFG2 MSSI LL_SPI_SetMasterSSIdleness + * @param SPIx SPI Instance + * @param MasterSSIdleness This parameter can be one of the following values: + * @arg @ref LL_SPI_SS_IDLENESS_00CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_01CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_02CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_03CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_04CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_05CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_06CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_07CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_08CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_09CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_10CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_11CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_12CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_13CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_14CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_15CYCLE + * @retval None + */ +__STATIC_INLINE void LL_SPI_SetMasterSSIdleness(SPI_TypeDef *SPIx, uint32_t MasterSSIdleness) +{ + MODIFY_REG(SPIx->CFG2, SPI_CFG2_MSSI, MasterSSIdleness); +} + +/** + * @brief Get the configured Idleness applied by master + * @rmtoll CFG2 MSSI LL_SPI_GetMasterSSIdleness + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_SS_IDLENESS_00CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_01CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_02CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_03CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_04CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_05CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_06CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_07CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_08CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_09CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_10CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_11CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_12CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_13CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_14CYCLE + * @arg @ref LL_SPI_SS_IDLENESS_15CYCLE + */ +__STATIC_INLINE uint32_t LL_SPI_GetMasterSSIdleness(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CFG2, SPI_CFG2_MSSI)); +} + +/** + * @brief Configure the idleness applied by master between data frame + * @rmtoll CFG2 MIDI LL_SPI_SetInterDataIdleness + * @param SPIx SPI Instance + * @param MasterInterDataIdleness This parameter can be one of the following values: + * @arg @ref LL_SPI_ID_IDLENESS_00CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_01CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_02CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_03CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_04CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_05CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_06CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_07CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_08CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_09CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_10CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_11CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_12CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_13CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_14CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_15CYCLE + * @retval None + */ +__STATIC_INLINE void LL_SPI_SetInterDataIdleness(SPI_TypeDef *SPIx, uint32_t MasterInterDataIdleness) +{ + MODIFY_REG(SPIx->CFG2, SPI_CFG2_MIDI, MasterInterDataIdleness); +} + +/** + * @brief Get the configured inter data idleness + * @rmtoll CFG2 MIDI LL_SPI_SetInterDataIdleness + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_ID_IDLENESS_00CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_01CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_02CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_03CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_04CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_05CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_06CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_07CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_08CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_09CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_10CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_11CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_12CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_13CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_14CYCLE + * @arg @ref LL_SPI_ID_IDLENESS_15CYCLE + */ +__STATIC_INLINE uint32_t LL_SPI_GetInterDataIdleness(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CFG2, SPI_CFG2_MIDI)); +} + +/** + * @brief Set transfer size + * @note Count is the number of frame to be transferred + * @rmtoll CR2 TSIZE LL_SPI_SetTransferSize + * @param SPIx SPI Instance + * @param Count 0..0xFFFF + * @retval None + */ +__STATIC_INLINE void LL_SPI_SetTransferSize(SPI_TypeDef *SPIx, uint32_t Count) +{ + MODIFY_REG(SPIx->CR2, SPI_CR2_TSIZE, Count); +} + +/** + * @brief Get transfer size + * @note Count is the number of frame to be transferred + * @rmtoll CR2 TSIZE LL_SPI_GetTransferSize + * @param SPIx SPI Instance + * @retval 0..0xFFFF + */ +__STATIC_INLINE uint32_t LL_SPI_GetTransferSize(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CR2, SPI_CR2_TSIZE)); +} + +/** + * @brief Lock the AF configuration of associated IOs + * @note Once this bit is set, the AF configuration remains locked until a hardware reset occurs. + * the reset of the IOLock bit is done by hardware. for that, LL_SPI_DisableIOLock can not exist. + * @rmtoll CR1 IOLOCK LL_SPI_EnableIOLock + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_EnableIOLock(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->CR1, SPI_CR1_IOLOCK); +} + +/** + * @brief Check if the AF configuration is locked. + * @rmtoll CR1 IOLOCK LL_SPI_IsEnabledIOLock + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_SPI_IsEnabledIOLock(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->CR1, SPI_CR1_IOLOCK) == (SPI_CR1_IOLOCK)) ? 1UL : 0UL); +} + +/** + * @brief Set Tx CRC Initialization Pattern + * @rmtoll CR1 TCRCINI LL_SPI_SetTxCRCInitPattern + * @param SPIx SPI Instance + * @param TXCRCInitAll This parameter can be one of the following values: + * @arg @ref LL_SPI_TXCRCINIT_ALL_ZERO_PATTERN + * @arg @ref LL_SPI_TXCRCINIT_ALL_ONES_PATTERN + * @retval None + */ +__STATIC_INLINE void LL_SPI_SetTxCRCInitPattern(SPI_TypeDef *SPIx, uint32_t TXCRCInitAll) +{ + MODIFY_REG(SPIx->CR1, SPI_CR1_RCRCINI, TXCRCInitAll); +} + +/** + * @brief Get Tx CRC Initialization Pattern + * @rmtoll CR1 TCRCINI LL_SPI_GetTxCRCInitPattern + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_TXCRCINIT_ALL_ZERO_PATTERN + * @arg @ref LL_SPI_TXCRCINIT_ALL_ONES_PATTERN + */ +__STATIC_INLINE uint32_t LL_SPI_GetTxCRCInitPattern(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CR1, SPI_CR1_TCRCINI)); +} + +/** + * @brief Set Rx CRC Initialization Pattern + * @rmtoll CR1 RCRCINI LL_SPI_SetRxCRCInitPattern + * @param SPIx SPI Instance + * @param RXCRCInitAll This parameter can be one of the following values: + * @arg @ref LL_SPI_RXCRCINIT_ALL_ZERO_PATTERN + * @arg @ref LL_SPI_RXCRCINIT_ALL_ONES_PATTERN + * @retval None + */ +__STATIC_INLINE void LL_SPI_SetRxCRCInitPattern(SPI_TypeDef *SPIx, uint32_t RXCRCInitAll) +{ + MODIFY_REG(SPIx->CR1, SPI_CR1_RCRCINI, RXCRCInitAll); +} + +/** + * @brief Get Rx CRC Initialization Pattern + * @rmtoll CR1 RCRCINI LL_SPI_GetRxCRCInitPattern + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_RXCRCINIT_ALL_ZERO_PATTERN + * @arg @ref LL_SPI_RXCRCINIT_ALL_ONES_PATTERN + */ +__STATIC_INLINE uint32_t LL_SPI_GetRxCRCInitPattern(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CR1, SPI_CR1_RCRCINI)); +} + +/** + * @brief Set internal SS input level ignoring what comes from PIN. + * @note This configuration has effect only with config LL_SPI_NSS_SOFT + * @rmtoll CR1 SSI LL_SPI_SetInternalSSLevel + * @param SPIx SPI Instance + * @param SSLevel This parameter can be one of the following values: + * @arg @ref LL_SPI_SS_LEVEL_HIGH + * @arg @ref LL_SPI_SS_LEVEL_LOW + * @retval None + */ +__STATIC_INLINE void LL_SPI_SetInternalSSLevel(SPI_TypeDef *SPIx, uint32_t SSLevel) +{ + MODIFY_REG(SPIx->CR1, SPI_CR1_SSI, SSLevel); +} + +/** + * @brief Get internal SS input level + * @rmtoll CR1 SSI LL_SPI_GetInternalSSLevel + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_SS_LEVEL_HIGH + * @arg @ref LL_SPI_SS_LEVEL_LOW + */ +__STATIC_INLINE uint32_t LL_SPI_GetInternalSSLevel(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CR1, SPI_CR1_SSI)); +} + +/** + * @brief Enable CRC computation on 33/17 bits + * @rmtoll CR1 CRC33_17 LL_SPI_EnableFullSizeCRC + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_EnableFullSizeCRC(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->CR1, SPI_CR1_CRC33_17); +} + +/** + * @brief Disable CRC computation on 33/17 bits + * @rmtoll CR1 CRC33_17 LL_SPI_DisableFullSizeCRC + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_DisableFullSizeCRC(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->CR1, SPI_CR1_CRC33_17); +} + +/** + * @brief Check if Enable CRC computation on 33/17 bits is enabled + * @rmtoll CR1 CRC33_17 LL_SPI_IsEnabledFullSizeCRC + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_SPI_IsEnabledFullSizeCRC(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->CR1, SPI_CR1_CRC33_17) == (SPI_CR1_CRC33_17)) ? 1UL : 0UL); +} + +/** + * @brief Suspend an ongoing transfer for Master configuration + * @rmtoll CR1 CSUSP LL_SPI_SuspendMasterTransfer + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_SuspendMasterTransfer(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->CR1, SPI_CR1_CSUSP); +} + +/** + * @brief Start effective transfer on wire for Master configuration + * @rmtoll CR1 CSTART LL_SPI_StartMasterTransfer + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_StartMasterTransfer(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->CR1, SPI_CR1_CSTART); +} + +/** + * @brief Check if there is an unfinished master transfer + * @rmtoll CR1 CSTART LL_SPI_IsActiveMasterTransfer + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_SPI_IsActiveMasterTransfer(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->CR1, SPI_CR1_CSTART) == (SPI_CR1_CSTART)) ? 1UL : 0UL); +} + +/** + * @brief Enable Master Rx auto suspend in case of overrun + * @rmtoll CR1 MASRX LL_SPI_EnableMasterRxAutoSuspend + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_EnableMasterRxAutoSuspend(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->CR1, SPI_CR1_MASRX); +} + +/** + * @brief Disable Master Rx auto suspend in case of overrun + * @rmtoll CR1 MASRX LL_SPI_DisableMasterRxAutoSuspend + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_DisableMasterRxAutoSuspend(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->CR1, SPI_CR1_MASRX); +} + +/** + * @brief Check if Master Rx auto suspend is activated + * @rmtoll CR1 MASRX LL_SPI_IsEnabledMasterRxAutoSuspend + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_SPI_IsEnabledMasterRxAutoSuspend(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->CR1, SPI_CR1_MASRX) == (SPI_CR1_MASRX)) ? 1UL : 0UL); +} + +/** + * @brief Set Underrun behavior + * @note This configuration can not be changed when SPI is enabled. + * @rmtoll CFG1 UDRCFG LL_SPI_SetUDRConfiguration + * @param SPIx SPI Instance + * @param UDRConfig This parameter can be one of the following values: + * @arg @ref LL_SPI_UDR_CONFIG_REGISTER_PATTERN + * @arg @ref LL_SPI_UDR_CONFIG_LAST_RECEIVED + * @retval None + */ +__STATIC_INLINE void LL_SPI_SetUDRConfiguration(SPI_TypeDef *SPIx, uint32_t UDRConfig) +{ + MODIFY_REG(SPIx->CFG1, SPI_CFG1_UDRCFG, UDRConfig); +} + +/** + * @brief Get Underrun behavior + * @rmtoll CFG1 UDRCFG LL_SPI_GetUDRConfiguration + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_UDR_CONFIG_REGISTER_PATTERN + * @arg @ref LL_SPI_UDR_CONFIG_LAST_RECEIVED + */ +__STATIC_INLINE uint32_t LL_SPI_GetUDRConfiguration(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CFG1, SPI_CFG1_UDRCFG)); +} + + +/** + * @brief Set Serial protocol used + * @note This configuration can not be changed when SPI is enabled. + * @rmtoll CFG2 SP LL_SPI_SetStandard + * @param SPIx SPI Instance + * @param Standard This parameter can be one of the following values: + * @arg @ref LL_SPI_PROTOCOL_MOTOROLA + * @arg @ref LL_SPI_PROTOCOL_TI + * @retval None + */ +__STATIC_INLINE void LL_SPI_SetStandard(SPI_TypeDef *SPIx, uint32_t Standard) +{ + MODIFY_REG(SPIx->CFG2, SPI_CFG2_SP, Standard); +} + +/** + * @brief Get Serial protocol used + * @rmtoll CFG2 SP LL_SPI_GetStandard + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_PROTOCOL_MOTOROLA + * @arg @ref LL_SPI_PROTOCOL_TI + */ +__STATIC_INLINE uint32_t LL_SPI_GetStandard(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CFG2, SPI_CFG2_SP)); +} + +/** + * @brief Set Clock phase + * @note This configuration can not be changed when SPI is enabled. + * This bit is not used in SPI TI mode. + * @rmtoll CFG2 CPHA LL_SPI_SetClockPhase + * @param SPIx SPI Instance + * @param ClockPhase This parameter can be one of the following values: + * @arg @ref LL_SPI_PHASE_1EDGE + * @arg @ref LL_SPI_PHASE_2EDGE + * @retval None + */ +__STATIC_INLINE void LL_SPI_SetClockPhase(SPI_TypeDef *SPIx, uint32_t ClockPhase) +{ + MODIFY_REG(SPIx->CFG2, SPI_CFG2_CPHA, ClockPhase); +} + +/** + * @brief Get Clock phase + * @rmtoll CFG2 CPHA LL_SPI_GetClockPhase + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_PHASE_1EDGE + * @arg @ref LL_SPI_PHASE_2EDGE + */ +__STATIC_INLINE uint32_t LL_SPI_GetClockPhase(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CFG2, SPI_CFG2_CPHA)); +} + +/** + * @brief Set Clock polarity + * @note This configuration can not be changed when SPI is enabled. + * This bit is not used in SPI TI mode. + * @rmtoll CFG2 CPOL LL_SPI_SetClockPolarity + * @param SPIx SPI Instance + * @param ClockPolarity This parameter can be one of the following values: + * @arg @ref LL_SPI_POLARITY_LOW + * @arg @ref LL_SPI_POLARITY_HIGH + * @retval None + */ +__STATIC_INLINE void LL_SPI_SetClockPolarity(SPI_TypeDef *SPIx, uint32_t ClockPolarity) +{ + MODIFY_REG(SPIx->CFG2, SPI_CFG2_CPOL, ClockPolarity); +} + +/** + * @brief Get Clock polarity + * @rmtoll CFG2 CPOL LL_SPI_GetClockPolarity + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_POLARITY_LOW + * @arg @ref LL_SPI_POLARITY_HIGH + */ +__STATIC_INLINE uint32_t LL_SPI_GetClockPolarity(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CFG2, SPI_CFG2_CPOL)); +} + +/** + * @brief Set NSS polarity + * @note This configuration can not be changed when SPI is enabled. + * This bit is not used in SPI TI mode. + * @rmtoll CFG2 SSIOP LL_SPI_SetNSSPolarity + * @param SPIx SPI Instance + * @param NSSPolarity This parameter can be one of the following values: + * @arg @ref LL_SPI_NSS_POLARITY_LOW + * @arg @ref LL_SPI_NSS_POLARITY_HIGH + * @retval None + */ +__STATIC_INLINE void LL_SPI_SetNSSPolarity(SPI_TypeDef *SPIx, uint32_t NSSPolarity) +{ + MODIFY_REG(SPIx->CFG2, SPI_CFG2_SSIOP, NSSPolarity); +} + +/** + * @brief Get NSS polarity + * @rmtoll CFG2 SSIOP LL_SPI_GetNSSPolarity + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_NSS_POLARITY_LOW + * @arg @ref LL_SPI_NSS_POLARITY_HIGH + */ +__STATIC_INLINE uint32_t LL_SPI_GetNSSPolarity(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CFG2, SPI_CFG2_SSIOP)); +} + +/** + * @brief Set Baudrate Prescaler + * @note This configuration can not be changed when SPI is enabled. + * SPI BaudRate = fPCLK/Pescaler. + * @rmtoll CFG1 MBR LL_SPI_SetBaudRatePrescaler\n + * CFG1 BPASS LL_SPI_SetBaudRatePrescaler + * @param SPIx SPI Instance + * @param Baudrate This parameter can be one of the following values: + * @arg @ref LL_SPI_BAUDRATEPRESCALER_BYPASS + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV2 + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV4 + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV8 + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV16 + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV32 + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV64 + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV128 + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV256 + * @retval None + */ +__STATIC_INLINE void LL_SPI_SetBaudRatePrescaler(SPI_TypeDef *SPIx, uint32_t Baudrate) +{ + MODIFY_REG(SPIx->CFG1, (SPI_CFG1_MBR | SPI_CFG1_BPASS), Baudrate); +} + +/** + * @brief Get Baudrate Prescaler + * @rmtoll CFG1 MBR LL_SPI_GetBaudRatePrescaler\n + * CFG1 BPASS LL_SPI_GetBaudRatePrescaler + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_BAUDRATEPRESCALER_BYPASS + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV2 + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV4 + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV8 + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV16 + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV32 + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV64 + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV128 + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV256 + */ +__STATIC_INLINE uint32_t LL_SPI_GetBaudRatePrescaler(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CFG1, (SPI_CFG1_MBR | SPI_CFG1_BPASS))); +} + +/** + * @brief Set Transfer Bit Order + * @note This configuration can not be changed when SPI is enabled. + * This bit is not used in SPI TI mode. + * @rmtoll CFG2 LSBFRST LL_SPI_SetTransferBitOrder + * @param SPIx SPI Instance + * @param BitOrder This parameter can be one of the following values: + * @arg @ref LL_SPI_LSB_FIRST + * @arg @ref LL_SPI_MSB_FIRST + * @retval None + */ +__STATIC_INLINE void LL_SPI_SetTransferBitOrder(SPI_TypeDef *SPIx, uint32_t BitOrder) +{ + MODIFY_REG(SPIx->CFG2, SPI_CFG2_LSBFRST, BitOrder); +} + +/** + * @brief Get Transfer Bit Order + * @rmtoll CFG2 LSBFRST LL_SPI_GetTransferBitOrder + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_LSB_FIRST + * @arg @ref LL_SPI_MSB_FIRST + */ +__STATIC_INLINE uint32_t LL_SPI_GetTransferBitOrder(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CFG2, SPI_CFG2_LSBFRST)); +} + +/** + * @brief Set Transfer Mode + * @note This configuration can not be changed when SPI is enabled except for half duplex direction + * using LL_SPI_SetHalfDuplexDirection. + * @rmtoll CR1 HDDIR LL_SPI_SetTransferDirection\n + * CFG2 COMM LL_SPI_SetTransferDirection + * @param SPIx SPI Instance + * @param TransferDirection This parameter can be one of the following values: + * @arg @ref LL_SPI_FULL_DUPLEX + * @arg @ref LL_SPI_SIMPLEX_TX + * @arg @ref LL_SPI_SIMPLEX_RX + * @arg @ref LL_SPI_HALF_DUPLEX_RX + * @arg @ref LL_SPI_HALF_DUPLEX_TX + * @retval None + */ +__STATIC_INLINE void LL_SPI_SetTransferDirection(SPI_TypeDef *SPIx, uint32_t TransferDirection) +{ + MODIFY_REG(SPIx->CR1, SPI_CR1_HDDIR, TransferDirection & SPI_CR1_HDDIR); + MODIFY_REG(SPIx->CFG2, SPI_CFG2_COMM, TransferDirection & SPI_CFG2_COMM); +} + +/** + * @brief Get Transfer Mode + * @rmtoll CR1 HDDIR LL_SPI_GetTransferDirection\n + * CFG2 COMM LL_SPI_GetTransferDirection + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_FULL_DUPLEX + * @arg @ref LL_SPI_SIMPLEX_TX + * @arg @ref LL_SPI_SIMPLEX_RX + * @arg @ref LL_SPI_HALF_DUPLEX_RX + * @arg @ref LL_SPI_HALF_DUPLEX_TX + */ +__STATIC_INLINE uint32_t LL_SPI_GetTransferDirection(const SPI_TypeDef *SPIx) +{ + uint32_t Hddir = READ_BIT(SPIx->CR1, SPI_CR1_HDDIR); + uint32_t Comm = READ_BIT(SPIx->CFG2, SPI_CFG2_COMM); + return (Hddir | Comm); +} + +/** + * @brief Set direction for Half-Duplex Mode + * @note In master mode the MOSI pin is used and in slave mode the MISO pin is used for Half-Duplex. + * @rmtoll CR1 HDDIR LL_SPI_SetHalfDuplexDirection + * @param SPIx SPI Instance + * @param HalfDuplexDirection This parameter can be one of the following values: + * @arg @ref LL_SPI_HALF_DUPLEX_RX + * @arg @ref LL_SPI_HALF_DUPLEX_TX + * @retval None + */ +__STATIC_INLINE void LL_SPI_SetHalfDuplexDirection(SPI_TypeDef *SPIx, uint32_t HalfDuplexDirection) +{ + MODIFY_REG(SPIx->CR1, SPI_CR1_HDDIR, HalfDuplexDirection & SPI_CR1_HDDIR); +} + +/** + * @brief Get direction for Half-Duplex Mode + * @note In master mode the MOSI pin is used and in slave mode the MISO pin is used for Half-Duplex. + * @rmtoll CR1 HDDIR LL_SPI_GetHalfDuplexDirection + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_HALF_DUPLEX_RX + * @arg @ref LL_SPI_HALF_DUPLEX_TX + */ +__STATIC_INLINE uint32_t LL_SPI_GetHalfDuplexDirection(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CR1, SPI_CR1_HDDIR) | SPI_CFG2_COMM); +} + +/** + * @brief Set Frame Data Size + * @note This configuration can not be changed when SPI is enabled. + * @rmtoll CFG1 DSIZE LL_SPI_SetDataWidth + * @param SPIx SPI Instance + * @param DataWidth This parameter can be one of the following values: + * @arg @ref LL_SPI_DATAWIDTH_4BIT + * @arg @ref LL_SPI_DATAWIDTH_5BIT + * @arg @ref LL_SPI_DATAWIDTH_6BIT + * @arg @ref LL_SPI_DATAWIDTH_7BIT + * @arg @ref LL_SPI_DATAWIDTH_8BIT + * @arg @ref LL_SPI_DATAWIDTH_9BIT + * @arg @ref LL_SPI_DATAWIDTH_10BIT + * @arg @ref LL_SPI_DATAWIDTH_11BIT + * @arg @ref LL_SPI_DATAWIDTH_12BIT + * @arg @ref LL_SPI_DATAWIDTH_13BIT + * @arg @ref LL_SPI_DATAWIDTH_14BIT + * @arg @ref LL_SPI_DATAWIDTH_15BIT + * @arg @ref LL_SPI_DATAWIDTH_16BIT + * @arg @ref LL_SPI_DATAWIDTH_17BIT + * @arg @ref LL_SPI_DATAWIDTH_18BIT + * @arg @ref LL_SPI_DATAWIDTH_19BIT + * @arg @ref LL_SPI_DATAWIDTH_20BIT + * @arg @ref LL_SPI_DATAWIDTH_21BIT + * @arg @ref LL_SPI_DATAWIDTH_22BIT + * @arg @ref LL_SPI_DATAWIDTH_23BIT + * @arg @ref LL_SPI_DATAWIDTH_24BIT + * @arg @ref LL_SPI_DATAWIDTH_25BIT + * @arg @ref LL_SPI_DATAWIDTH_26BIT + * @arg @ref LL_SPI_DATAWIDTH_27BIT + * @arg @ref LL_SPI_DATAWIDTH_28BIT + * @arg @ref LL_SPI_DATAWIDTH_29BIT + * @arg @ref LL_SPI_DATAWIDTH_30BIT + * @arg @ref LL_SPI_DATAWIDTH_31BIT + * @arg @ref LL_SPI_DATAWIDTH_32BIT + * @retval None + */ +__STATIC_INLINE void LL_SPI_SetDataWidth(SPI_TypeDef *SPIx, uint32_t DataWidth) +{ + MODIFY_REG(SPIx->CFG1, SPI_CFG1_DSIZE, DataWidth); +} + +/** + * @brief Get Frame Data Size + * @rmtoll CFG1 DSIZE LL_SPI_GetDataWidth + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_DATAWIDTH_4BIT + * @arg @ref LL_SPI_DATAWIDTH_5BIT + * @arg @ref LL_SPI_DATAWIDTH_6BIT + * @arg @ref LL_SPI_DATAWIDTH_7BIT + * @arg @ref LL_SPI_DATAWIDTH_8BIT + * @arg @ref LL_SPI_DATAWIDTH_9BIT + * @arg @ref LL_SPI_DATAWIDTH_10BIT + * @arg @ref LL_SPI_DATAWIDTH_11BIT + * @arg @ref LL_SPI_DATAWIDTH_12BIT + * @arg @ref LL_SPI_DATAWIDTH_13BIT + * @arg @ref LL_SPI_DATAWIDTH_14BIT + * @arg @ref LL_SPI_DATAWIDTH_15BIT + * @arg @ref LL_SPI_DATAWIDTH_16BIT + * @arg @ref LL_SPI_DATAWIDTH_17BIT + * @arg @ref LL_SPI_DATAWIDTH_18BIT + * @arg @ref LL_SPI_DATAWIDTH_19BIT + * @arg @ref LL_SPI_DATAWIDTH_20BIT + * @arg @ref LL_SPI_DATAWIDTH_21BIT + * @arg @ref LL_SPI_DATAWIDTH_22BIT + * @arg @ref LL_SPI_DATAWIDTH_23BIT + * @arg @ref LL_SPI_DATAWIDTH_24BIT + * @arg @ref LL_SPI_DATAWIDTH_25BIT + * @arg @ref LL_SPI_DATAWIDTH_26BIT + * @arg @ref LL_SPI_DATAWIDTH_27BIT + * @arg @ref LL_SPI_DATAWIDTH_28BIT + * @arg @ref LL_SPI_DATAWIDTH_29BIT + * @arg @ref LL_SPI_DATAWIDTH_30BIT + * @arg @ref LL_SPI_DATAWIDTH_31BIT + * @arg @ref LL_SPI_DATAWIDTH_32BIT + */ +__STATIC_INLINE uint32_t LL_SPI_GetDataWidth(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CFG1, SPI_CFG1_DSIZE)); +} + +/** + * @brief Set threshold of FIFO that triggers a transfer event + * @note This configuration can not be changed when SPI is enabled. + * @rmtoll CFG1 FTHLV LL_SPI_SetFIFOThreshold + * @param SPIx SPI Instance + * @param Threshold This parameter can be one of the following values: + * @arg @ref LL_SPI_FIFO_TH_01DATA + * @arg @ref LL_SPI_FIFO_TH_02DATA + * @arg @ref LL_SPI_FIFO_TH_03DATA + * @arg @ref LL_SPI_FIFO_TH_04DATA + * @arg @ref LL_SPI_FIFO_TH_05DATA + * @arg @ref LL_SPI_FIFO_TH_06DATA + * @arg @ref LL_SPI_FIFO_TH_07DATA + * @arg @ref LL_SPI_FIFO_TH_08DATA + * @arg @ref LL_SPI_FIFO_TH_09DATA + * @arg @ref LL_SPI_FIFO_TH_10DATA + * @arg @ref LL_SPI_FIFO_TH_11DATA + * @arg @ref LL_SPI_FIFO_TH_12DATA + * @arg @ref LL_SPI_FIFO_TH_13DATA + * @arg @ref LL_SPI_FIFO_TH_14DATA + * @arg @ref LL_SPI_FIFO_TH_15DATA + * @arg @ref LL_SPI_FIFO_TH_16DATA + * @retval None + */ +__STATIC_INLINE void LL_SPI_SetFIFOThreshold(SPI_TypeDef *SPIx, uint32_t Threshold) +{ + MODIFY_REG(SPIx->CFG1, SPI_CFG1_FTHLV, Threshold); +} + +/** + * @brief Get threshold of FIFO that triggers a transfer event + * @rmtoll CFG1 FTHLV LL_SPI_GetFIFOThreshold + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_FIFO_TH_01DATA + * @arg @ref LL_SPI_FIFO_TH_02DATA + * @arg @ref LL_SPI_FIFO_TH_03DATA + * @arg @ref LL_SPI_FIFO_TH_04DATA + * @arg @ref LL_SPI_FIFO_TH_05DATA + * @arg @ref LL_SPI_FIFO_TH_06DATA + * @arg @ref LL_SPI_FIFO_TH_07DATA + * @arg @ref LL_SPI_FIFO_TH_08DATA + * @arg @ref LL_SPI_FIFO_TH_09DATA + * @arg @ref LL_SPI_FIFO_TH_10DATA + * @arg @ref LL_SPI_FIFO_TH_11DATA + * @arg @ref LL_SPI_FIFO_TH_12DATA + * @arg @ref LL_SPI_FIFO_TH_13DATA + * @arg @ref LL_SPI_FIFO_TH_14DATA + * @arg @ref LL_SPI_FIFO_TH_15DATA + * @arg @ref LL_SPI_FIFO_TH_16DATA + */ +__STATIC_INLINE uint32_t LL_SPI_GetFIFOThreshold(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CFG1, SPI_CFG1_FTHLV)); +} + +/** + * @brief Enable CRC + * @note This configuration can not be changed when SPI is enabled. + * @rmtoll CFG1 CRCEN LL_SPI_EnableCRC + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_EnableCRC(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->CFG1, SPI_CFG1_CRCEN); +} + +/** + * @brief Disable CRC + * @rmtoll CFG1 CRCEN LL_SPI_DisableCRC + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_DisableCRC(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->CFG1, SPI_CFG1_CRCEN); +} + +/** + * @brief Check if CRC is enabled + * @rmtoll CFG1 CRCEN LL_SPI_IsEnabledCRC + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SPI_IsEnabledCRC(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->CFG1, SPI_CFG1_CRCEN) == SPI_CFG1_CRCEN) ? 1UL : 0UL); +} + +/** + * @brief Set CRC Length + * @note This configuration can not be changed when SPI is enabled. + * @rmtoll CFG1 CRCSIZE LL_SPI_SetCRCWidth + * @param SPIx SPI Instance + * @param CRCLength This parameter can be one of the following values: + * @arg @ref LL_SPI_CRC_4BIT + * @arg @ref LL_SPI_CRC_5BIT + * @arg @ref LL_SPI_CRC_6BIT + * @arg @ref LL_SPI_CRC_7BIT + * @arg @ref LL_SPI_CRC_8BIT + * @arg @ref LL_SPI_CRC_9BIT + * @arg @ref LL_SPI_CRC_10BIT + * @arg @ref LL_SPI_CRC_11BIT + * @arg @ref LL_SPI_CRC_12BIT + * @arg @ref LL_SPI_CRC_13BIT + * @arg @ref LL_SPI_CRC_14BIT + * @arg @ref LL_SPI_CRC_15BIT + * @arg @ref LL_SPI_CRC_16BIT + * @arg @ref LL_SPI_CRC_17BIT + * @arg @ref LL_SPI_CRC_18BIT + * @arg @ref LL_SPI_CRC_19BIT + * @arg @ref LL_SPI_CRC_20BIT + * @arg @ref LL_SPI_CRC_21BIT + * @arg @ref LL_SPI_CRC_22BIT + * @arg @ref LL_SPI_CRC_23BIT + * @arg @ref LL_SPI_CRC_24BIT + * @arg @ref LL_SPI_CRC_25BIT + * @arg @ref LL_SPI_CRC_26BIT + * @arg @ref LL_SPI_CRC_27BIT + * @arg @ref LL_SPI_CRC_28BIT + * @arg @ref LL_SPI_CRC_29BIT + * @arg @ref LL_SPI_CRC_30BIT + * @arg @ref LL_SPI_CRC_31BIT + * @arg @ref LL_SPI_CRC_32BIT + * @retval None + */ +__STATIC_INLINE void LL_SPI_SetCRCWidth(SPI_TypeDef *SPIx, uint32_t CRCLength) +{ + MODIFY_REG(SPIx->CFG1, SPI_CFG1_CRCSIZE, CRCLength); +} + +/** + * @brief Get CRC Length + * @rmtoll CFG1 CRCSIZE LL_SPI_GetCRCWidth + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_CRC_4BIT + * @arg @ref LL_SPI_CRC_5BIT + * @arg @ref LL_SPI_CRC_6BIT + * @arg @ref LL_SPI_CRC_7BIT + * @arg @ref LL_SPI_CRC_8BIT + * @arg @ref LL_SPI_CRC_9BIT + * @arg @ref LL_SPI_CRC_10BIT + * @arg @ref LL_SPI_CRC_11BIT + * @arg @ref LL_SPI_CRC_12BIT + * @arg @ref LL_SPI_CRC_13BIT + * @arg @ref LL_SPI_CRC_14BIT + * @arg @ref LL_SPI_CRC_15BIT + * @arg @ref LL_SPI_CRC_16BIT + * @arg @ref LL_SPI_CRC_17BIT + * @arg @ref LL_SPI_CRC_18BIT + * @arg @ref LL_SPI_CRC_19BIT + * @arg @ref LL_SPI_CRC_20BIT + * @arg @ref LL_SPI_CRC_21BIT + * @arg @ref LL_SPI_CRC_22BIT + * @arg @ref LL_SPI_CRC_23BIT + * @arg @ref LL_SPI_CRC_24BIT + * @arg @ref LL_SPI_CRC_25BIT + * @arg @ref LL_SPI_CRC_26BIT + * @arg @ref LL_SPI_CRC_27BIT + * @arg @ref LL_SPI_CRC_28BIT + * @arg @ref LL_SPI_CRC_29BIT + * @arg @ref LL_SPI_CRC_30BIT + * @arg @ref LL_SPI_CRC_31BIT + * @arg @ref LL_SPI_CRC_32BIT + */ +__STATIC_INLINE uint32_t LL_SPI_GetCRCWidth(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CFG1, SPI_CFG1_CRCSIZE)); +} + +/** + * @brief Set NSS Mode + * @note This configuration can not be changed when SPI is enabled. + * This bit is not used in SPI TI mode. + * @rmtoll CFG2 SSM LL_SPI_SetNSSMode\n + * CFG2 SSOE LL_SPI_SetNSSMode + * @param SPIx SPI Instance + * @param NSS This parameter can be one of the following values: + * @arg @ref LL_SPI_NSS_SOFT + * @arg @ref LL_SPI_NSS_HARD_INPUT + * @arg @ref LL_SPI_NSS_HARD_OUTPUT + * @retval None + */ +__STATIC_INLINE void LL_SPI_SetNSSMode(SPI_TypeDef *SPIx, uint32_t NSS) +{ + MODIFY_REG(SPIx->CFG2, SPI_CFG2_SSM | SPI_CFG2_SSOE, NSS); +} + +/** + * @brief Set NSS Mode + * @rmtoll CFG2 SSM LL_SPI_GetNSSMode\n + * CFG2 SSOE LL_SPI_GetNSSMode + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_NSS_SOFT + * @arg @ref LL_SPI_NSS_HARD_INPUT + * @arg @ref LL_SPI_NSS_HARD_OUTPUT + */ +__STATIC_INLINE uint32_t LL_SPI_GetNSSMode(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->CFG2, SPI_CFG2_SSM | SPI_CFG2_SSOE)); +} + +/** + * @brief Enable NSS pulse mgt + * @note This configuration can not be changed when SPI is enabled. + * This bit is not used in SPI TI mode. + * @rmtoll CFG2 SSOM LL_SPI_EnableNSSPulseMgt + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_EnableNSSPulseMgt(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->CFG2, SPI_CFG2_SSOM); +} + +/** + * @brief Disable NSS pulse mgt + * @note This configuration can not be changed when SPI is enabled. + * This bit is not used in SPI TI mode. + * @rmtoll CFG2 SSOM LL_SPI_DisableNSSPulseMgt + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_DisableNSSPulseMgt(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->CFG2, SPI_CFG2_SSOM); +} + +/** + * @brief Check if NSS pulse is enabled + * @rmtoll CFG2 SSOM LL_SPI_IsEnabledNSSPulse + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_SPI_IsEnabledNSSPulse(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->CFG2, SPI_CFG2_SSOM) == SPI_CFG2_SSOM) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup SPI_LL_EF_FLAG_Management FLAG_Management + * @{ + */ + +/** + * @brief Check if there is enough data in FIFO to read a full packet + * @rmtoll SR RXP LL_SPI_IsActiveFlag_RXP + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_RXP(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->SR, SPI_SR_RXP) == (SPI_SR_RXP)) ? 1UL : 0UL); +} + +/** + * @brief Check if there is enough space in FIFO to hold a full packet + * @rmtoll SR TXP LL_SPI_IsActiveFlag_TXP + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_TXP(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->SR, SPI_SR_TXP) == (SPI_SR_TXP)) ? 1UL : 0UL); +} + +/** + * @brief Check if there enough space in FIFO to hold a full packet, AND enough data to read a full packet + * @rmtoll SR DXP LL_SPI_IsActiveFlag_DXP + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_DXP(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->SR, SPI_SR_DXP) == (SPI_SR_DXP)) ? 1UL : 0UL); +} + +/** + * @brief Check that end of transfer event occurred + * @rmtoll SR EOT LL_SPI_IsActiveFlag_EOT + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_EOT(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->SR, SPI_SR_EOT) == (SPI_SR_EOT)) ? 1UL : 0UL); +} + +/** + * @brief Check that all required data has been filled in the fifo according to transfer size + * @rmtoll SR TXTF LL_SPI_IsActiveFlag_TXTF + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_TXTF(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->SR, SPI_SR_TXTF) == (SPI_SR_TXTF)) ? 1UL : 0UL); +} + +/** + * @brief Get Underrun error flag + * @rmtoll SR UDR LL_SPI_IsActiveFlag_UDR + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_UDR(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->SR, SPI_SR_UDR) == (SPI_SR_UDR)) ? 1UL : 0UL); +} + +/** + * @brief Get CRC error flag + * @rmtoll SR CRCE LL_SPI_IsActiveFlag_CRCERR + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_CRCERR(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->SR, SPI_SR_CRCE) == (SPI_SR_CRCE)) ? 1UL : 0UL); +} + +/** + * @brief Get Mode fault error flag + * @rmtoll SR MODF LL_SPI_IsActiveFlag_MODF + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_MODF(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->SR, SPI_SR_MODF) == (SPI_SR_MODF)) ? 1UL : 0UL); +} + +/** + * @brief Get Overrun error flag + * @rmtoll SR OVR LL_SPI_IsActiveFlag_OVR + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_OVR(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->SR, SPI_SR_OVR) == (SPI_SR_OVR)) ? 1UL : 0UL); +} + +/** + * @brief Get TI Frame format error flag + * @rmtoll SR TIFRE LL_SPI_IsActiveFlag_FRE + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_FRE(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->SR, SPI_SR_TIFRE) == (SPI_SR_TIFRE)) ? 1UL : 0UL); +} + +/** + * @brief Check if a suspend operation is done + * @rmtoll SR SUSP LL_SPI_IsActiveFlag_SUSP + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_SUSP(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->SR, SPI_SR_SUSP) == (SPI_SR_SUSP)) ? 1UL : 0UL); +} + +/** + * @brief Check if last TxFIFO or CRC frame transmission is completed + * @rmtoll SR TXC LL_SPI_IsActiveFlag_TXC + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_TXC(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->SR, SPI_SR_TXC) == (SPI_SR_TXC)) ? 1UL : 0UL); +} + +/** + * @brief Check if at least one 32-bit data is available in RxFIFO + * @rmtoll SR RXWNE LL_SPI_IsActiveFlag_RXWNE + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_RXWNE(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->SR, SPI_SR_RXWNE) == (SPI_SR_RXWNE)) ? 1UL : 0UL); +} + +/** + * @brief Get number of data framed remaining in current TSIZE + * @rmtoll SR CTSIZE LL_SPI_GetRemainingDataFrames + * @param SPIx SPI Instance + * @retval 0..0xFFFF + */ +__STATIC_INLINE uint32_t LL_SPI_GetRemainingDataFrames(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->SR, SPI_SR_CTSIZE) >> SPI_SR_CTSIZE_Pos); +} + +/** + * @brief Get RxFIFO packing Level + * @rmtoll SR RXPLVL LL_SPI_GetRxFIFOPackingLevel + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_RX_FIFO_0PACKET + * @arg @ref LL_SPI_RX_FIFO_1PACKET + * @arg @ref LL_SPI_RX_FIFO_2PACKET + * @arg @ref LL_SPI_RX_FIFO_3PACKET + */ +__STATIC_INLINE uint32_t LL_SPI_GetRxFIFOPackingLevel(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->SR, SPI_SR_RXPLVL)); +} + +/** + * @brief Clear End Of Transfer flag + * @rmtoll IFCR EOTC LL_SPI_ClearFlag_EOT + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_ClearFlag_EOT(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IFCR, SPI_IFCR_EOTC); +} + +/** + * @brief Clear TXTF flag + * @rmtoll IFCR TXTFC LL_SPI_ClearFlag_TXTF + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_ClearFlag_TXTF(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IFCR, SPI_IFCR_TXTFC); +} + +/** + * @brief Clear Underrun error flag + * @rmtoll IFCR UDRC LL_SPI_ClearFlag_UDR + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_ClearFlag_UDR(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IFCR, SPI_IFCR_UDRC); +} + +/** + * @brief Clear Overrun error flag + * @rmtoll IFCR OVRC LL_SPI_ClearFlag_OVR + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_ClearFlag_OVR(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IFCR, SPI_IFCR_OVRC); +} + +/** + * @brief Clear CRC error flag + * @rmtoll IFCR CRCEC LL_SPI_ClearFlag_CRCERR + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_ClearFlag_CRCERR(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IFCR, SPI_IFCR_CRCEC); +} + +/** + * @brief Clear Mode fault error flag + * @rmtoll IFCR MODFC LL_SPI_ClearFlag_MODF + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_ClearFlag_MODF(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IFCR, SPI_IFCR_MODFC); +} + +/** + * @brief Clear Frame format error flag + * @rmtoll IFCR TIFREC LL_SPI_ClearFlag_FRE + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_ClearFlag_FRE(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IFCR, SPI_IFCR_TIFREC); +} + +/** + * @brief Clear SUSP flag + * @rmtoll IFCR SUSPC LL_SPI_ClearFlag_SUSP + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_ClearFlag_SUSP(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IFCR, SPI_IFCR_SUSPC); +} + +/** + * @} + */ + +/** @defgroup SPI_LL_EF_IT_Management IT_Management + * @{ + */ + +/** + * @brief Enable Rx Packet available IT + * @rmtoll IER RXPIE LL_SPI_EnableIT_RXP + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_EnableIT_RXP(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IER, SPI_IER_RXPIE); +} + +/** + * @brief Enable Tx Packet space available IT + * @rmtoll IER TXPIE LL_SPI_EnableIT_TXP + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_EnableIT_TXP(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IER, SPI_IER_TXPIE); +} + +/** + * @brief Enable Duplex Packet available IT + * @rmtoll IER DXPIE LL_SPI_EnableIT_DXP + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_EnableIT_DXP(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IER, SPI_IER_DXPIE); +} + +/** + * @brief Enable End Of Transfer IT + * @rmtoll IER EOTIE LL_SPI_EnableIT_EOT + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_EnableIT_EOT(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IER, SPI_IER_EOTIE); +} + +/** + * @brief Enable TXTF IT + * @rmtoll IER TXTFIE LL_SPI_EnableIT_TXTF + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_EnableIT_TXTF(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IER, SPI_IER_TXTFIE); +} + +/** + * @brief Enable Underrun IT + * @rmtoll IER UDRIE LL_SPI_EnableIT_UDR + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_EnableIT_UDR(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IER, SPI_IER_UDRIE); +} + +/** + * @brief Enable Overrun IT + * @rmtoll IER OVRIE LL_SPI_EnableIT_OVR + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_EnableIT_OVR(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IER, SPI_IER_OVRIE); +} + +/** + * @brief Enable CRC Error IT + * @rmtoll IER CRCEIE LL_SPI_EnableIT_CRCERR + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_EnableIT_CRCERR(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IER, SPI_IER_CRCEIE); +} + +/** + * @brief Enable TI Frame Format Error IT + * @rmtoll IER TIFREIE LL_SPI_EnableIT_FRE + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_EnableIT_FRE(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IER, SPI_IER_TIFREIE); +} + +/** + * @brief Enable MODF IT + * @rmtoll IER MODFIE LL_SPI_EnableIT_MODF + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_EnableIT_MODF(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->IER, SPI_IER_MODFIE); +} + +/** + * @brief Disable Rx Packet available IT + * @rmtoll IER RXPIE LL_SPI_DisableIT_RXP + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_DisableIT_RXP(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->IER, SPI_IER_RXPIE); +} + +/** + * @brief Disable Tx Packet space available IT + * @rmtoll IER TXPIE LL_SPI_DisableIT_TXP + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_DisableIT_TXP(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->IER, SPI_IER_TXPIE); +} + +/** + * @brief Disable Duplex Packet available IT + * @rmtoll IER DXPIE LL_SPI_DisableIT_DXP + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_DisableIT_DXP(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->IER, SPI_IER_DXPIE); +} + +/** + * @brief Disable End Of Transfer IT + * @rmtoll IER EOTIE LL_SPI_DisableIT_EOT + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_DisableIT_EOT(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->IER, SPI_IER_EOTIE); +} + +/** + * @brief Disable TXTF IT + * @rmtoll IER TXTFIE LL_SPI_DisableIT_TXTF + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_DisableIT_TXTF(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->IER, SPI_IER_TXTFIE); +} + +/** + * @brief Disable Underrun IT + * @rmtoll IER UDRIE LL_SPI_DisableIT_UDR + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_DisableIT_UDR(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->IER, SPI_IER_UDRIE); +} + +/** + * @brief Disable Overrun IT + * @rmtoll IER OVRIE LL_SPI_DisableIT_OVR + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_DisableIT_OVR(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->IER, SPI_IER_OVRIE); +} + +/** + * @brief Disable CRC Error IT + * @rmtoll IER CRCEIE LL_SPI_DisableIT_CRCERR + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_DisableIT_CRCERR(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->IER, SPI_IER_CRCEIE); +} + +/** + * @brief Disable TI Frame Format Error IT + * @rmtoll IER TIFREIE LL_SPI_DisableIT_FRE + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_DisableIT_FRE(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->IER, SPI_IER_TIFREIE); +} + +/** + * @brief Disable MODF IT + * @rmtoll IER MODFIE LL_SPI_DisableIT_MODF + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_DisableIT_MODF(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->IER, SPI_IER_MODFIE); +} + +/** + * @brief Check if Rx Packet available IT is enabled + * @rmtoll IER RXPIE LL_SPI_IsEnabledIT_RXP + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_RXP(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->IER, SPI_IER_RXPIE) == (SPI_IER_RXPIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if Tx Packet space available IT is enabled + * @rmtoll IER TXPIE LL_SPI_IsEnabledIT_TXP + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_TXP(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->IER, SPI_IER_TXPIE) == (SPI_IER_TXPIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if Duplex Packet available IT is enabled + * @rmtoll IER DXPIE LL_SPI_IsEnabledIT_DXP + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_DXP(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->IER, SPI_IER_DXPIE) == (SPI_IER_DXPIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if End Of Transfer IT is enabled + * @rmtoll IER EOTIE LL_SPI_IsEnabledIT_EOT + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_EOT(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->IER, SPI_IER_EOTIE) == (SPI_IER_EOTIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if TXTF IT is enabled + * @rmtoll IER TXTFIE LL_SPI_IsEnabledIT_TXTF + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_TXTF(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->IER, SPI_IER_TXTFIE) == (SPI_IER_TXTFIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if Underrun IT is enabled + * @rmtoll IER UDRIE LL_SPI_IsEnabledIT_UDR + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_UDR(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->IER, SPI_IER_UDRIE) == (SPI_IER_UDRIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if Overrun IT is enabled + * @rmtoll IER OVRIE LL_SPI_IsEnabledIT_OVR + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_OVR(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->IER, SPI_IER_OVRIE) == (SPI_IER_OVRIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if CRC Error IT is enabled + * @rmtoll IER CRCEIE LL_SPI_IsEnabledIT_CRCERR + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_CRCERR(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->IER, SPI_IER_CRCEIE) == (SPI_IER_CRCEIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if TI Frame Format Error IT is enabled + * @rmtoll IER TIFREIE LL_SPI_IsEnabledIT_FRE + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_FRE(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->IER, SPI_IER_TIFREIE) == (SPI_IER_TIFREIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if MODF IT is enabled + * @rmtoll IER MODFIE LL_SPI_IsEnabledIT_MODF + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_MODF(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->IER, SPI_IER_MODFIE) == (SPI_IER_MODFIE)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup SPI_LL_EF_DMA_Management DMA Management + * @{ + */ + +/** + * @brief Enable DMA Rx + * @rmtoll CFG1 RXDMAEN LL_SPI_EnableDMAReq_RX + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_EnableDMAReq_RX(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->CFG1, SPI_CFG1_RXDMAEN); +} + +/** + * @brief Disable DMA Rx + * @rmtoll CFG1 RXDMAEN LL_SPI_DisableDMAReq_RX + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_DisableDMAReq_RX(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->CFG1, SPI_CFG1_RXDMAEN); +} + +/** + * @brief Check if DMA Rx is enabled + * @rmtoll CFG1 RXDMAEN LL_SPI_IsEnabledDMAReq_RX + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_SPI_IsEnabledDMAReq_RX(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->CFG1, SPI_CFG1_RXDMAEN) == (SPI_CFG1_RXDMAEN)) ? 1UL : 0UL); +} + +/** + * @brief Enable DMA Tx + * @rmtoll CFG1 TXDMAEN LL_SPI_EnableDMAReq_TX + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_EnableDMAReq_TX(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->CFG1, SPI_CFG1_TXDMAEN); +} + +/** + * @brief Disable DMA Tx + * @rmtoll CFG1 TXDMAEN LL_SPI_DisableDMAReq_TX + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_SPI_DisableDMAReq_TX(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->CFG1, SPI_CFG1_TXDMAEN); +} + +/** + * @brief Check if DMA Tx is enabled + * @rmtoll CFG1 TXDMAEN LL_SPI_IsEnabledDMAReq_TX + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_SPI_IsEnabledDMAReq_TX(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->CFG1, SPI_CFG1_TXDMAEN) == (SPI_CFG1_TXDMAEN)) ? 1UL : 0UL); +} +/** + * @brief Get the data register address used for DMA transfer + * @rmtoll TXDR TXDR LL_SPI_DMA_GetTxRegAddr + * @param SPIx SPI Instance + * @retval Address of data register + */ +__STATIC_INLINE uint32_t LL_SPI_DMA_GetTxRegAddr(const SPI_TypeDef *SPIx) +{ + return (uint32_t) &(SPIx->TXDR); +} + +/** + * @brief Get the data register address used for DMA transfer + * @rmtoll RXDR RXDR LL_SPI_DMA_GetRxRegAddr + * @param SPIx SPI Instance + * @retval Address of data register + */ +__STATIC_INLINE uint32_t LL_SPI_DMA_GetRxRegAddr(const SPI_TypeDef *SPIx) +{ + return (uint32_t) &(SPIx->RXDR); +} +/** + * @} + */ + +/** @defgroup SPI_LL_EF_DATA_Management DATA_Management + * @{ + */ + +/** + * @brief Read Data Register + * @rmtoll RXDR . LL_SPI_ReceiveData8 + * @param SPIx SPI Instance + * @retval 0..0xFF + */ +__STATIC_INLINE uint8_t LL_SPI_ReceiveData8(SPI_TypeDef *SPIx) /* Derogation MISRAC2012-Rule-8.13 */ +{ + return (*((__IO uint8_t *)&SPIx->RXDR)); +} + +/** + * @brief Read Data Register + * @rmtoll RXDR . LL_SPI_ReceiveData16 + * @param SPIx SPI Instance + * @retval 0..0xFFFF + */ +__STATIC_INLINE uint16_t LL_SPI_ReceiveData16(SPI_TypeDef *SPIx) /* Derogation MISRAC2012-Rule-8.13 */ +{ +#if defined (__GNUC__) + __IO uint16_t *spirxdr = (__IO uint16_t *)(&(SPIx->RXDR)); + return (*spirxdr); +#else + return (*((__IO uint16_t *)&SPIx->RXDR)); +#endif /* __GNUC__ */ +} + +/** + * @brief Read Data Register + * @rmtoll RXDR . LL_SPI_ReceiveData32 + * @param SPIx SPI Instance + * @retval 0..0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_SPI_ReceiveData32(SPI_TypeDef *SPIx) /* Derogation MISRAC2012-Rule-8.13 */ +{ + return (*((__IO uint32_t *)&SPIx->RXDR)); +} + +/** + * @brief Write Data Register + * @rmtoll TXDR . LL_SPI_TransmitData8 + * @param SPIx SPI Instance + * @param TxData 0..0xFF + * @retval None + */ +__STATIC_INLINE void LL_SPI_TransmitData8(SPI_TypeDef *SPIx, uint8_t TxData) +{ + *((__IO uint8_t *)&SPIx->TXDR) = TxData; +} + +/** + * @brief Write Data Register + * @rmtoll TXDR . LL_SPI_TransmitData16 + * @param SPIx SPI Instance + * @param TxData 0..0xFFFF + * @retval None + */ +__STATIC_INLINE void LL_SPI_TransmitData16(SPI_TypeDef *SPIx, uint16_t TxData) +{ +#if defined (__GNUC__) + __IO uint16_t *spitxdr = ((__IO uint16_t *)&SPIx->TXDR); + *spitxdr = TxData; +#else + *((__IO uint16_t *)&SPIx->TXDR) = TxData; +#endif /* __GNUC__ */ +} + +/** + * @brief Write Data Register + * @rmtoll TXDR . LL_SPI_TransmitData32 + * @param SPIx SPI Instance + * @param TxData 0..0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void LL_SPI_TransmitData32(SPI_TypeDef *SPIx, uint32_t TxData) +{ + *((__IO uint32_t *)&SPIx->TXDR) = TxData; +} + +/** + * @brief Set polynomial for CRC calcul + * @rmtoll CRCPOLY CRCPOLY LL_SPI_SetCRCPolynomial + * @param SPIx SPI Instance + * @param CRCPoly 0..0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void LL_SPI_SetCRCPolynomial(SPI_TypeDef *SPIx, uint32_t CRCPoly) +{ + WRITE_REG(SPIx->CRCPOLY, CRCPoly); +} + +/** + * @brief Get polynomial for CRC calcul + * @rmtoll CRCPOLY CRCPOLY LL_SPI_GetCRCPolynomial + * @param SPIx SPI Instance + * @retval 0..0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_SPI_GetCRCPolynomial(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_REG(SPIx->CRCPOLY)); +} + +/** + * @brief Set the underrun pattern + * @rmtoll UDRDR UDRDR LL_SPI_SetUDRPattern + * @param SPIx SPI Instance + * @param Pattern 0..0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void LL_SPI_SetUDRPattern(SPI_TypeDef *SPIx, uint32_t Pattern) +{ + WRITE_REG(SPIx->UDRDR, Pattern); +} + +/** + * @brief Get the underrun pattern + * @rmtoll UDRDR UDRDR LL_SPI_GetUDRPattern + * @param SPIx SPI Instance + * @retval 0..0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_SPI_GetUDRPattern(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_REG(SPIx->UDRDR)); +} + +/** + * @brief Get Rx CRC + * @rmtoll RXCRCR RXCRC LL_SPI_GetRxCRC + * @param SPIx SPI Instance + * @retval 0..0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_SPI_GetRxCRC(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_REG(SPIx->RXCRC)); +} + +/** + * @brief Get Tx CRC + * @rmtoll TXCRCR TXCRC LL_SPI_GetTxCRC + * @param SPIx SPI Instance + * @retval 0..0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_SPI_GetTxCRC(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_REG(SPIx->TXCRC)); +} + +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup SPI_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +ErrorStatus LL_SPI_DeInit(const SPI_TypeDef *SPIx); +ErrorStatus LL_SPI_Init(SPI_TypeDef *SPIx, LL_SPI_InitTypeDef *SPI_InitStruct); +void LL_SPI_StructInit(LL_SPI_InitTypeDef *SPI_InitStruct); + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ +/** + * @} + */ +/** + * @} + */ + +/** @defgroup I2S_LL I2S + * @{ + */ + +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ + +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup I2S_LL_ES_INIT I2S Exported Init structure + * @{ + */ + +/** + * @brief I2S Init structure definition + */ + +typedef struct +{ + uint32_t Mode; /*!< Specifies the I2S operating mode. + This parameter can be a value of @ref I2S_LL_EC_MODE + + This feature can be modified afterwards using unitary function + @ref LL_I2S_SetTransferMode().*/ + + uint32_t Standard; /*!< Specifies the standard used for the I2S communication. + This parameter can be a value of @ref I2S_LL_EC_STANDARD + + This feature can be modified afterwards using unitary function + @ref LL_I2S_SetStandard().*/ + + + uint32_t DataFormat; /*!< Specifies the data format for the I2S communication. + This parameter can be a value of @ref I2S_LL_EC_DATA_FORMAT + + This feature can be modified afterwards using unitary function + @ref LL_I2S_SetDataFormat().*/ + + + uint32_t MCLKOutput; /*!< Specifies whether the I2S MCLK output is enabled or not. + This parameter can be a value of @ref I2S_LL_EC_MCLK_OUTPUT + + This feature can be modified afterwards using unitary functions + @ref LL_I2S_EnableMasterClock() or @ref LL_I2S_DisableMasterClock.*/ + + + uint32_t AudioFreq; /*!< Specifies the frequency selected for the I2S communication. + This parameter can be a value of @ref I2S_LL_EC_AUDIO_FREQ + + Audio Frequency can be modified afterwards using Reference manual formulas + to calculate Prescaler Linear, Parity and unitary functions + @ref LL_I2S_SetPrescalerLinear() and @ref LL_I2S_SetPrescalerParity() + to set it.*/ + + + uint32_t ClockPolarity; /*!< Specifies the idle state of the I2S clock. + This parameter can be a value of @ref I2S_LL_EC_POLARITY + + This feature can be modified afterwards using unitary function + @ref LL_I2S_SetClockPolarity().*/ + +} LL_I2S_InitTypeDef; + +/** + * @} + */ +#endif /*USE_FULL_LL_DRIVER*/ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup I2S_LL_Exported_Constants I2S Exported Constants + * @{ + */ + +/** @defgroup I2S_LL_EC_DATA_FORMAT Data Format + * @{ + */ +#define LL_I2S_DATAFORMAT_16B (0x00000000UL) +#define LL_I2S_DATAFORMAT_16B_EXTENDED (SPI_I2SCFGR_CHLEN) +#define LL_I2S_DATAFORMAT_24B (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN_0) +#define LL_I2S_DATAFORMAT_24B_LEFT_ALIGNED (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN_0 | SPI_I2SCFGR_DATFMT) +#define LL_I2S_DATAFORMAT_32B (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN_1) +/** + * @} + */ + +/** @defgroup I2S_LL_EC_CHANNEL_LENGTH_TYPE Type of Channel Length + * @{ + */ +#define LL_I2S_SLAVE_VARIABLE_CH_LENGTH (0x00000000UL) +#define LL_I2S_SLAVE_FIXED_CH_LENGTH (SPI_I2SCFGR_FIXCH) +/** + * @} + */ + +/** @defgroup I2S_LL_EC_POLARITY Clock Polarity + * @{ + */ +#define LL_I2S_POLARITY_LOW (0x00000000UL) +#define LL_I2S_POLARITY_HIGH (SPI_I2SCFGR_CKPOL) +/** + * @} + */ + +/** @defgroup I2S_LL_EC_STANDARD I2S Standard + * @{ + */ +#define LL_I2S_STANDARD_PHILIPS (0x00000000UL) +#define LL_I2S_STANDARD_MSB (SPI_I2SCFGR_I2SSTD_0) +#define LL_I2S_STANDARD_LSB (SPI_I2SCFGR_I2SSTD_1) +#define LL_I2S_STANDARD_PCM_SHORT (SPI_I2SCFGR_I2SSTD_0 | SPI_I2SCFGR_I2SSTD_1) +#define LL_I2S_STANDARD_PCM_LONG (SPI_I2SCFGR_I2SSTD_0 | SPI_I2SCFGR_I2SSTD_1 | SPI_I2SCFGR_PCMSYNC) +/** + * @} + */ + +/** @defgroup I2S_LL_EC_MODE Operation Mode + * @{ + */ +#define LL_I2S_MODE_SLAVE_TX (0x00000000UL) +#define LL_I2S_MODE_SLAVE_RX (SPI_I2SCFGR_I2SCFG_0) +#define LL_I2S_MODE_SLAVE_FULL_DUPLEX (SPI_I2SCFGR_I2SCFG_2) +#define LL_I2S_MODE_MASTER_TX (SPI_I2SCFGR_I2SCFG_1) +#define LL_I2S_MODE_MASTER_RX (SPI_I2SCFGR_I2SCFG_1 | SPI_I2SCFGR_I2SCFG_0) +#define LL_I2S_MODE_MASTER_FULL_DUPLEX (SPI_I2SCFGR_I2SCFG_2 | SPI_I2SCFGR_I2SCFG_0) +/** + * @} + */ + +/** @defgroup I2S_LL_EC_PRESCALER_PARITY Prescaler Factor + * @{ + */ +#define LL_I2S_PRESCALER_PARITY_EVEN (0x00000000UL) /*!< Odd factor: Real divider value is = I2SDIV * 2 */ +#define LL_I2S_PRESCALER_PARITY_ODD (0x00000001UL) /*!< Odd factor: Real divider value is = (I2SDIV * 2)+1 */ +/** + * @} + */ + +/** @defgroup I2S_LL_EC_FIFO_TH FIFO Threshold Level + * @{ + */ +#define LL_I2S_FIFO_TH_01DATA (LL_SPI_FIFO_TH_01DATA) +#define LL_I2S_FIFO_TH_02DATA (LL_SPI_FIFO_TH_02DATA) +#define LL_I2S_FIFO_TH_03DATA (LL_SPI_FIFO_TH_03DATA) +#define LL_I2S_FIFO_TH_04DATA (LL_SPI_FIFO_TH_04DATA) +#define LL_I2S_FIFO_TH_05DATA (LL_SPI_FIFO_TH_05DATA) +#define LL_I2S_FIFO_TH_06DATA (LL_SPI_FIFO_TH_06DATA) +#define LL_I2S_FIFO_TH_07DATA (LL_SPI_FIFO_TH_07DATA) +#define LL_I2S_FIFO_TH_08DATA (LL_SPI_FIFO_TH_08DATA) +/** + * @} + */ + +/** @defgroup I2S_LL_EC_BIT_ORDER Transmission Bit Order + * @{ + */ +#define LL_I2S_LSB_FIRST (LL_SPI_LSB_FIRST) +#define LL_I2S_MSB_FIRST (LL_SPI_MSB_FIRST) +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) + +/** @defgroup I2S_LL_EC_MCLK_OUTPUT MCLK Output + * @{ + */ +#define LL_I2S_MCLK_OUTPUT_DISABLE (0x00000000UL) +#define LL_I2S_MCLK_OUTPUT_ENABLE (SPI_I2SCFGR_MCKOE) +/** + * @} + */ + +/** @defgroup I2S_LL_EC_AUDIO_FREQ Audio Frequency + * @{ + */ + +#define LL_I2S_AUDIOFREQ_192K 192000UL /*!< Audio Frequency configuration 192000 Hz */ +#define LL_I2S_AUDIOFREQ_96K 96000UL /*!< Audio Frequency configuration 96000 Hz */ +#define LL_I2S_AUDIOFREQ_48K 48000UL /*!< Audio Frequency configuration 48000 Hz */ +#define LL_I2S_AUDIOFREQ_44K 44100UL /*!< Audio Frequency configuration 44100 Hz */ +#define LL_I2S_AUDIOFREQ_32K 32000UL /*!< Audio Frequency configuration 32000 Hz */ +#define LL_I2S_AUDIOFREQ_22K 22050UL /*!< Audio Frequency configuration 22050 Hz */ +#define LL_I2S_AUDIOFREQ_16K 16000UL /*!< Audio Frequency configuration 16000 Hz */ +#define LL_I2S_AUDIOFREQ_11K 11025UL /*!< Audio Frequency configuration 11025 Hz */ +#define LL_I2S_AUDIOFREQ_8K 8000UL /*!< Audio Frequency configuration 8000 Hz */ +#define LL_I2S_AUDIOFREQ_DEFAULT 0UL /*!< Audio Freq not specified. Register I2SDIV = 0 */ +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup I2S_LL_Exported_Macros I2S Exported Macros + * @{ + */ + +/** @defgroup I2S_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in I2S register + * @param __INSTANCE__ I2S Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_I2S_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in I2S register + * @param __INSTANCE__ I2S Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_I2S_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) +/** + * @} + */ + +/** + * @} + */ + + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup I2S_LL_Exported_Functions I2S Exported Functions + * @{ + */ + +/** @defgroup I2S_LL_EF_Configuration Configuration + * @{ + */ + +/** + * @brief Set I2S Data frame format + * @rmtoll I2SCFGR DATLEN LL_I2S_SetDataFormat\n + * I2SCFGR CHLEN LL_I2S_SetDataFormat\n + * I2SCFGR DATFMT LL_I2S_SetDataFormat + * @param SPIx SPI Handle + * @param DataLength This parameter can be one of the following values: + * @arg @ref LL_I2S_DATAFORMAT_16B + * @arg @ref LL_I2S_DATAFORMAT_16B_EXTENDED + * @arg @ref LL_I2S_DATAFORMAT_24B + * @arg @ref LL_I2S_DATAFORMAT_24B_LEFT_ALIGNED + * @arg @ref LL_I2S_DATAFORMAT_32B + * @retval None + */ +__STATIC_INLINE void LL_I2S_SetDataFormat(SPI_TypeDef *SPIx, uint32_t DataLength) +{ + MODIFY_REG(SPIx->I2SCFGR, SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATFMT, DataLength); +} + +/** + * @brief Get I2S Data frame format + * @rmtoll I2SCFGR DATLEN LL_I2S_GetDataFormat\n + * I2SCFGR CHLEN LL_I2S_GetDataFormat\n + * I2SCFGR DATFMT LL_I2S_GetDataFormat + * @param SPIx SPI Handle + * @retval Return value can be one of the following values: + * @arg @ref LL_I2S_DATAFORMAT_16B + * @arg @ref LL_I2S_DATAFORMAT_16B_EXTENDED + * @arg @ref LL_I2S_DATAFORMAT_24B + * @arg @ref LL_I2S_DATAFORMAT_24B_LEFT_ALIGNED + * @arg @ref LL_I2S_DATAFORMAT_32B + */ +__STATIC_INLINE uint32_t LL_I2S_GetDataFormat(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATFMT)); +} + +/** + * @brief Set I2S Channel Length Type + * @note This feature is useful with SLAVE only + * @rmtoll I2SCFGR FIXCH LL_I2S_SetChannelLengthType + * @param SPIx SPI Handle + * @param ChannelLengthType This parameter can be one of the following values: + * @arg @ref LL_I2S_SLAVE_VARIABLE_CH_LENGTH + * @arg @ref LL_I2S_SLAVE_FIXED_CH_LENGTH + * @retval None + */ +__STATIC_INLINE void LL_I2S_SetChannelLengthType(SPI_TypeDef *SPIx, uint32_t ChannelLengthType) +{ + MODIFY_REG(SPIx->I2SCFGR, SPI_I2SCFGR_FIXCH, ChannelLengthType); +} + +/** + * @brief Get I2S Channel Length Type + * @note This feature is useful with SLAVE only + * @rmtoll I2SCFGR FIXCH LL_I2S_GetChannelLengthType + * @param SPIx SPI Handle + * @retval Return value can be one of the following values: + * @arg @ref LL_I2S_SLAVE_VARIABLE_CH_LENGTH + * @arg @ref LL_I2S_SLAVE_FIXED_CH_LENGTH + */ +__STATIC_INLINE uint32_t LL_I2S_GetChannelLengthType(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_FIXCH)); +} + +/** + * @brief Invert the default polarity of WS signal + * @rmtoll I2SCFGR WSINV LL_I2S_EnableWordSelectInversion + * @param SPIx SPI Handle + * @retval None + */ +__STATIC_INLINE void LL_I2S_EnableWordSelectInversion(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_WSINV); +} + +/** + * @brief Use the default polarity of WS signal + * @rmtoll I2SCFGR WSINV LL_I2S_DisableWordSelectInversion + * @param SPIx SPI Handle + * @retval None + */ +__STATIC_INLINE void LL_I2S_DisableWordSelectInversion(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_WSINV); +} + +/** + * @brief Check if polarity of WS signal is inverted + * @rmtoll I2SCFGR WSINV LL_I2S_IsEnabledWordSelectInversion + * @param SPIx SPI Handle + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_I2S_IsEnabledWordSelectInversion(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_WSINV) == (SPI_I2SCFGR_WSINV)) ? 1UL : 0UL); +} + +/** + * @brief Set 2S Clock Polarity + * @rmtoll I2SCFGR CKPOL LL_I2S_SetClockPolarity + * @param SPIx SPI Handle + * @param ClockPolarity This parameter can be one of the following values: + * @arg @ref LL_I2S_POLARITY_LOW + * @arg @ref LL_I2S_POLARITY_HIGH + * @retval None + */ +__STATIC_INLINE void LL_I2S_SetClockPolarity(SPI_TypeDef *SPIx, uint32_t ClockPolarity) +{ + MODIFY_REG(SPIx->I2SCFGR, SPI_I2SCFGR_CKPOL, ClockPolarity); +} + +/** + * @brief Get 2S Clock Polarity + * @rmtoll I2SCFGR CKPOL LL_I2S_GetClockPolarity + * @param SPIx SPI Handle + * @retval Return value can be one of the following values: + * @arg @ref LL_I2S_POLARITY_LOW + * @arg @ref LL_I2S_POLARITY_HIGH + */ +__STATIC_INLINE uint32_t LL_I2S_GetClockPolarity(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_CKPOL)); +} + +/** + * @brief Set I2S standard + * @rmtoll I2SCFGR I2SSTD LL_I2S_SetStandard\n + * I2SCFGR PCMSYNC LL_I2S_SetStandard + * @param SPIx SPI Handle + * @param Standard This parameter can be one of the following values: + * @arg @ref LL_I2S_STANDARD_PHILIPS + * @arg @ref LL_I2S_STANDARD_MSB + * @arg @ref LL_I2S_STANDARD_LSB + * @arg @ref LL_I2S_STANDARD_PCM_SHORT + * @arg @ref LL_I2S_STANDARD_PCM_LONG + * @retval None + */ +__STATIC_INLINE void LL_I2S_SetStandard(SPI_TypeDef *SPIx, uint32_t Standard) +{ + MODIFY_REG(SPIx->I2SCFGR, SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC, Standard); +} + +/** + * @brief Get I2S standard + * @rmtoll I2SCFGR I2SSTD LL_I2S_GetStandard\n + * I2SCFGR PCMSYNC LL_I2S_GetStandard + * @param SPIx SPI Handle + * @retval Return value can be one of the following values: + * @arg @ref LL_I2S_STANDARD_PHILIPS + * @arg @ref LL_I2S_STANDARD_MSB + * @arg @ref LL_I2S_STANDARD_LSB + * @arg @ref LL_I2S_STANDARD_PCM_SHORT + * @arg @ref LL_I2S_STANDARD_PCM_LONG + */ +__STATIC_INLINE uint32_t LL_I2S_GetStandard(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC)); +} + +/** + * @brief Set I2S config + * @rmtoll I2SCFGR I2SCFG LL_I2S_SetTransferMode + * @param SPIx SPI Handle + * @param Standard This parameter can be one of the following values: + * @arg @ref LL_I2S_MODE_SLAVE_TX + * @arg @ref LL_I2S_MODE_SLAVE_RX + * @arg @ref LL_I2S_MODE_SLAVE_FULL_DUPLEX + * @arg @ref LL_I2S_MODE_MASTER_TX + * @arg @ref LL_I2S_MODE_MASTER_RX + * @arg @ref LL_I2S_MODE_MASTER_FULL_DUPLEX + * @retval None + */ +__STATIC_INLINE void LL_I2S_SetTransferMode(SPI_TypeDef *SPIx, uint32_t Standard) +{ + MODIFY_REG(SPIx->I2SCFGR, SPI_I2SCFGR_I2SCFG, Standard); +} + +/** + * @brief Get I2S config + * @rmtoll I2SCFGR I2SCFG LL_I2S_GetTransferMode + * @param SPIx SPI Handle + * @retval Return value can be one of the following values: + * @arg @ref LL_I2S_MODE_SLAVE_TX + * @arg @ref LL_I2S_MODE_SLAVE_RX + * @arg @ref LL_I2S_MODE_SLAVE_FULL_DUPLEX + * @arg @ref LL_I2S_MODE_MASTER_TX + * @arg @ref LL_I2S_MODE_MASTER_RX + * @arg @ref LL_I2S_MODE_MASTER_FULL_DUPLEX + */ +__STATIC_INLINE uint32_t LL_I2S_GetTransferMode(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SCFG)); +} + +/** + * @brief Select I2S mode and Enable I2S peripheral + * @rmtoll I2SCFGR I2SMOD LL_I2S_Enable\n + * CR1 SPE LL_I2S_Enable + * @param SPIx SPI Handle + * @retval None + */ +__STATIC_INLINE void LL_I2S_Enable(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SMOD); + SET_BIT(SPIx->CR1, SPI_CR1_SPE); +} + +/** + * @brief Disable I2S peripheral and disable I2S mode + * @rmtoll CR1 SPE LL_I2S_Disable\n + * I2SCFGR I2SMOD LL_I2S_Disable + * @param SPIx SPI Handle + * @retval None + */ +__STATIC_INLINE void LL_I2S_Disable(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->CR1, SPI_CR1_SPE); + CLEAR_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SMOD); +} + +/** + * @brief Swap the SDO and SDI pin + * @note This configuration can not be changed when I2S is enabled. + * @rmtoll CFG2 IOSWP LL_I2S_EnableIOSwap + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_I2S_EnableIOSwap(SPI_TypeDef *SPIx) +{ + LL_SPI_EnableIOSwap(SPIx); +} + +/** + * @brief Restore default function for SDO and SDI pin + * @note This configuration can not be changed when I2S is enabled. + * @rmtoll CFG2 IOSWP LL_I2S_DisableIOSwap + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_I2S_DisableIOSwap(SPI_TypeDef *SPIx) +{ + LL_SPI_DisableIOSwap(SPIx); +} + +/** + * @brief Check if SDO and SDI pin are swapped + * @rmtoll CFG2 IOSWP LL_I2S_IsEnabledIOSwap + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_I2S_IsEnabledIOSwap(const SPI_TypeDef *SPIx) +{ + return LL_SPI_IsEnabledIOSwap(SPIx); +} + +/** + * @brief Enable GPIO control + * @note This configuration can not be changed when I2S is enabled. + * @rmtoll CFG2 AFCNTR LL_I2S_EnableGPIOControl + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_I2S_EnableGPIOControl(SPI_TypeDef *SPIx) +{ + LL_SPI_EnableGPIOControl(SPIx); +} + +/** + * @brief Disable GPIO control + * @note This configuration can not be changed when I2S is enabled. + * @rmtoll CFG2 AFCNTR LL_I2S_DisableGPIOControl + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_I2S_DisableGPIOControl(SPI_TypeDef *SPIx) +{ + LL_SPI_DisableGPIOControl(SPIx); +} + +/** + * @brief Check if GPIO control is active + * @rmtoll CFG2 AFCNTR LL_I2S_IsEnabledGPIOControl + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_I2S_IsEnabledGPIOControl(const SPI_TypeDef *SPIx) +{ + return LL_SPI_IsEnabledGPIOControl(SPIx); +} + +/** + * @brief Lock the AF configuration of associated IOs + * @note Once this bit is set, the SPI_CFG2 register content can not be modified until a hardware reset occurs. + * The reset of the IOLock bit is done by hardware. for that, LL_SPI_DisableIOLock can not exist. + * @rmtoll CR1 IOLOCK LL_SPI_EnableIOLock + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_I2S_EnableIOLock(SPI_TypeDef *SPIx) +{ + LL_SPI_EnableIOLock(SPIx); +} + +/** + * @brief Check if the the SPI_CFG2 register is locked + * @rmtoll CR1 IOLOCK LL_I2S_IsEnabledIOLock + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_I2S_IsEnabledIOLock(const SPI_TypeDef *SPIx) +{ + return LL_SPI_IsEnabledIOLock(SPIx); +} + +/** + * @brief Set Transfer Bit Order + * @note This configuration can not be changed when I2S is enabled. + * @rmtoll CFG2 LSBFRST LL_I2S_SetTransferBitOrder + * @param SPIx SPI Instance + * @param BitOrder This parameter can be one of the following values: + * @arg @ref LL_I2S_LSB_FIRST + * @arg @ref LL_I2S_MSB_FIRST + * @retval None + */ +__STATIC_INLINE void LL_I2S_SetTransferBitOrder(SPI_TypeDef *SPIx, uint32_t BitOrder) +{ + LL_SPI_SetTransferBitOrder(SPIx, BitOrder); +} +/** + * @brief Get Transfer Bit Order + * @rmtoll CFG2 LSBFRST LL_I2S_GetTransferBitOrder + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_I2S_LSB_FIRST + * @arg @ref LL_I2S_MSB_FIRST + */ +__STATIC_INLINE uint32_t LL_I2S_GetTransferBitOrder(const SPI_TypeDef *SPIx) +{ + return LL_SPI_GetTransferBitOrder(SPIx); +} + +/** + * @brief Start effective transfer on wire + * @rmtoll CR1 CSTART LL_I2S_StartTransfer + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_I2S_StartTransfer(SPI_TypeDef *SPIx) +{ + LL_SPI_StartMasterTransfer(SPIx); +} + +/** + * @brief Check if there is an unfinished transfer + * @rmtoll CR1 CSTART LL_I2S_IsActiveTransfer + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_I2S_IsActiveTransfer(const SPI_TypeDef *SPIx) +{ + return LL_SPI_IsActiveMasterTransfer(SPIx); +} + +/** + * @brief Set threshold of FIFO that triggers a transfer event + * @note This configuration can not be changed when I2S is enabled. + * @rmtoll CFG1 FTHLV LL_I2S_SetFIFOThreshold + * @param SPIx SPI Instance + * @param Threshold This parameter can be one of the following values: + * @arg @ref LL_I2S_FIFO_TH_01DATA + * @arg @ref LL_I2S_FIFO_TH_02DATA + * @arg @ref LL_I2S_FIFO_TH_03DATA + * @arg @ref LL_I2S_FIFO_TH_04DATA + * @arg @ref LL_I2S_FIFO_TH_05DATA + * @arg @ref LL_I2S_FIFO_TH_06DATA + * @arg @ref LL_I2S_FIFO_TH_07DATA + * @arg @ref LL_I2S_FIFO_TH_08DATA + * @retval None + */ +__STATIC_INLINE void LL_I2S_SetFIFOThreshold(SPI_TypeDef *SPIx, uint32_t Threshold) +{ + LL_SPI_SetFIFOThreshold(SPIx, Threshold); +} + +/** + * @brief Get threshold of FIFO that triggers a transfer event + * @rmtoll CFG1 FTHLV LL_I2S_GetFIFOThreshold + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_I2S_FIFO_TH_01DATA + * @arg @ref LL_I2S_FIFO_TH_02DATA + * @arg @ref LL_I2S_FIFO_TH_03DATA + * @arg @ref LL_I2S_FIFO_TH_04DATA + * @arg @ref LL_I2S_FIFO_TH_05DATA + * @arg @ref LL_I2S_FIFO_TH_06DATA + * @arg @ref LL_I2S_FIFO_TH_07DATA + * @arg @ref LL_I2S_FIFO_TH_08DATA + */ +__STATIC_INLINE uint32_t LL_I2S_GetFIFOThreshold(const SPI_TypeDef *SPIx) +{ + return LL_SPI_GetFIFOThreshold(SPIx); +} + +/** + * @brief Set I2S linear prescaler + * @rmtoll I2SCFGR I2SDIV LL_I2S_SetPrescalerLinear + * @param SPIx SPI Instance + * @param PrescalerLinear Value between Min_Data=0x00 and Max_Data=0xFF + * @note PrescalerLinear '1' is not authorized with parity LL_I2S_PRESCALER_PARITY_ODD + * @retval None + */ +__STATIC_INLINE void LL_I2S_SetPrescalerLinear(SPI_TypeDef *SPIx, uint32_t PrescalerLinear) +{ + MODIFY_REG(SPIx->I2SCFGR, SPI_I2SCFGR_I2SDIV, (PrescalerLinear << SPI_I2SCFGR_I2SDIV_Pos)); +} + +/** + * @brief Get I2S linear prescaler + * @rmtoll I2SCFGR I2SDIV LL_I2S_GetPrescalerLinear + * @param SPIx SPI Instance + * @retval PrescalerLinear Value between Min_Data=0x00 and Max_Data=0xFF + */ +__STATIC_INLINE uint32_t LL_I2S_GetPrescalerLinear(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SDIV) >> SPI_I2SCFGR_I2SDIV_Pos); +} + +/** + * @brief Set I2S parity prescaler + * @rmtoll I2SCFGR ODD LL_I2S_SetPrescalerParity + * @param SPIx SPI Instance + * @param PrescalerParity This parameter can be one of the following values: + * @arg @ref LL_I2S_PRESCALER_PARITY_EVEN + * @arg @ref LL_I2S_PRESCALER_PARITY_ODD + * @retval None + */ +__STATIC_INLINE void LL_I2S_SetPrescalerParity(SPI_TypeDef *SPIx, uint32_t PrescalerParity) +{ + MODIFY_REG(SPIx->I2SCFGR, SPI_I2SCFGR_ODD, PrescalerParity << SPI_I2SCFGR_ODD_Pos); +} + +/** + * @brief Get I2S parity prescaler + * @rmtoll I2SCFGR ODD LL_I2S_GetPrescalerParity + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_I2S_PRESCALER_PARITY_EVEN + * @arg @ref LL_I2S_PRESCALER_PARITY_ODD + */ +__STATIC_INLINE uint32_t LL_I2S_GetPrescalerParity(const SPI_TypeDef *SPIx) +{ + return (uint32_t)(READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_ODD) >> SPI_I2SCFGR_ODD_Pos); +} + +/** + * @brief Enable the Master Clock Output (Pin MCK) + * @rmtoll I2SCFGR MCKOE LL_I2S_EnableMasterClock + * @param SPIx SPI Handle + * @retval None + */ +__STATIC_INLINE void LL_I2S_EnableMasterClock(SPI_TypeDef *SPIx) +{ + SET_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_MCKOE); +} + +/** + * @brief Disable the Master Clock Output (Pin MCK) + * @rmtoll I2SCFGR MCKOE LL_I2S_DisableMasterClock + * @param SPIx SPI Handle + * @retval None + */ +__STATIC_INLINE void LL_I2S_DisableMasterClock(SPI_TypeDef *SPIx) +{ + CLEAR_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_MCKOE); +} + +/** + * @brief Check if the master clock output (Pin MCK) is enabled + * @rmtoll I2SCFGR MCKOE LL_I2S_IsEnabledMasterClock + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_I2S_IsEnabledMasterClock(const SPI_TypeDef *SPIx) +{ + return ((READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_MCKOE) == (SPI_I2SCFGR_MCKOE)) ? 1UL : 0UL); +} + +/** + * @} + */ + + +/** @defgroup I2S_LL_EF_FLAG_Management FLAG_Management + * @{ + */ + +/** + * @brief Check if there enough data in FIFO to read a full packet + * @rmtoll SR RXP LL_I2S_IsActiveFlag_RXP + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_RXP(const SPI_TypeDef *SPIx) +{ + return LL_SPI_IsActiveFlag_RXP(SPIx); +} + +/** + * @brief Check if there enough space in FIFO to hold a full packet + * @rmtoll SR TXP LL_I2S_IsActiveFlag_TXP + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_TXP(const SPI_TypeDef *SPIx) +{ + return LL_SPI_IsActiveFlag_TXP(SPIx); +} + +/** + * @brief Get Underrun error flag + * @rmtoll SR UDR LL_I2S_IsActiveFlag_UDR + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_UDR(const SPI_TypeDef *SPIx) +{ + return LL_SPI_IsActiveFlag_UDR(SPIx); +} + +/** + * @brief Get Overrun error flag + * @rmtoll SR OVR LL_I2S_IsActiveFlag_OVR + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_OVR(const SPI_TypeDef *SPIx) +{ + return LL_SPI_IsActiveFlag_OVR(SPIx); +} + +/** + * @brief Get TI Frame format error flag + * @rmtoll SR TIFRE LL_I2S_IsActiveFlag_FRE + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_FRE(const SPI_TypeDef *SPIx) +{ + return LL_SPI_IsActiveFlag_FRE(SPIx); +} + +/** + * @brief Clear Underrun error flag + * @rmtoll IFCR UDRC LL_I2S_ClearFlag_UDR + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_I2S_ClearFlag_UDR(SPI_TypeDef *SPIx) +{ + LL_SPI_ClearFlag_UDR(SPIx); +} + +/** + * @brief Clear Overrun error flag + * @rmtoll IFCR OVRC LL_I2S_ClearFlag_OVR + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_I2S_ClearFlag_OVR(SPI_TypeDef *SPIx) +{ + LL_SPI_ClearFlag_OVR(SPIx); +} + +/** + * @brief Clear Frame format error flag + * @rmtoll IFCR TIFREC LL_I2S_ClearFlag_FRE + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_I2S_ClearFlag_FRE(SPI_TypeDef *SPIx) +{ + LL_SPI_ClearFlag_FRE(SPIx); +} + +/** + * @} + */ + +/** @defgroup I2S_LL_EF_IT_Management IT_Management + * @{ + */ + +/** + * @brief Enable Rx Packet available IT + * @rmtoll IER RXPIE LL_I2S_EnableIT_RXP + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_I2S_EnableIT_RXP(SPI_TypeDef *SPIx) +{ + LL_SPI_EnableIT_RXP(SPIx); +} + +/** + * @brief Enable Tx Packet space available IT + * @rmtoll IER TXPIE LL_I2S_EnableIT_TXP + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_I2S_EnableIT_TXP(SPI_TypeDef *SPIx) +{ + LL_SPI_EnableIT_TXP(SPIx); +} + +/** + * @brief Enable Underrun IT + * @rmtoll IER UDRIE LL_I2S_EnableIT_UDR + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_I2S_EnableIT_UDR(SPI_TypeDef *SPIx) +{ + LL_SPI_EnableIT_UDR(SPIx); +} + +/** + * @brief Enable Overrun IT + * @rmtoll IER OVRIE LL_I2S_EnableIT_OVR + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_I2S_EnableIT_OVR(SPI_TypeDef *SPIx) +{ + LL_SPI_EnableIT_OVR(SPIx); +} + +/** + * @brief Enable TI Frame Format Error IT + * @rmtoll IER TIFREIE LL_I2S_EnableIT_FRE + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_I2S_EnableIT_FRE(SPI_TypeDef *SPIx) +{ + LL_SPI_EnableIT_FRE(SPIx); +} + +/** + * @brief Disable Rx Packet available IT + * @rmtoll IER RXPIE LL_I2S_DisableIT_RXP + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_I2S_DisableIT_RXP(SPI_TypeDef *SPIx) +{ + LL_SPI_DisableIT_RXP(SPIx); +} + +/** + * @brief Disable Tx Packet space available IT + * @rmtoll IER TXPIE LL_I2S_DisableIT_TXP + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_I2S_DisableIT_TXP(SPI_TypeDef *SPIx) +{ + LL_SPI_DisableIT_TXP(SPIx); +} + +/** + * @brief Disable Underrun IT + * @rmtoll IER UDRIE LL_I2S_DisableIT_UDR + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_I2S_DisableIT_UDR(SPI_TypeDef *SPIx) +{ + LL_SPI_DisableIT_UDR(SPIx); +} + +/** + * @brief Disable Overrun IT + * @rmtoll IER OVRIE LL_I2S_DisableIT_OVR + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_I2S_DisableIT_OVR(SPI_TypeDef *SPIx) +{ + LL_SPI_DisableIT_OVR(SPIx); +} + +/** + * @brief Disable TI Frame Format Error IT + * @rmtoll IER TIFREIE LL_I2S_DisableIT_FRE + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_I2S_DisableIT_FRE(SPI_TypeDef *SPIx) +{ + LL_SPI_DisableIT_FRE(SPIx); +} + +/** + * @brief Check if Rx Packet available IT is enabled + * @rmtoll IER RXPIE LL_I2S_IsEnabledIT_RXP + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_I2S_IsEnabledIT_RXP(const SPI_TypeDef *SPIx) +{ + return LL_SPI_IsEnabledIT_RXP(SPIx); +} + +/** + * @brief Check if Tx Packet space available IT is enabled + * @rmtoll IER TXPIE LL_I2S_IsEnabledIT_TXP + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_I2S_IsEnabledIT_TXP(const SPI_TypeDef *SPIx) +{ + return LL_SPI_IsEnabledIT_TXP(SPIx); +} + +/** + * @brief Check if Underrun IT is enabled + * @rmtoll IER UDRIE LL_I2S_IsEnabledIT_UDR + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_I2S_IsEnabledIT_UDR(const SPI_TypeDef *SPIx) +{ + return LL_SPI_IsEnabledIT_UDR(SPIx); +} + +/** + * @brief Check if Overrun IT is enabled + * @rmtoll IER OVRIE LL_I2S_IsEnabledIT_OVR + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_I2S_IsEnabledIT_OVR(const SPI_TypeDef *SPIx) +{ + return LL_SPI_IsEnabledIT_OVR(SPIx); +} + +/** + * @brief Check if TI Frame Format Error IT is enabled + * @rmtoll IER TIFREIE LL_I2S_IsEnabledIT_FRE + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_I2S_IsEnabledIT_FRE(const SPI_TypeDef *SPIx) +{ + return LL_SPI_IsEnabledIT_FRE(SPIx); +} + +/** + * @} + */ + +/** @defgroup I2S_LL_EF_DMA_Management DMA_Management + * @{ + */ + +/** + * @brief Enable DMA Rx + * @rmtoll CFG1 RXDMAEN LL_I2S_EnableDMAReq_RX + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_I2S_EnableDMAReq_RX(SPI_TypeDef *SPIx) +{ + LL_SPI_EnableDMAReq_RX(SPIx); +} + +/** + * @brief Disable DMA Rx + * @rmtoll CFG1 RXDMAEN LL_I2S_DisableDMAReq_RX + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_I2S_DisableDMAReq_RX(SPI_TypeDef *SPIx) +{ + LL_SPI_DisableDMAReq_RX(SPIx); +} + +/** + * @brief Check if DMA Rx is enabled + * @rmtoll CFG1 RXDMAEN LL_I2S_IsEnabledDMAReq_RX + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_I2S_IsEnabledDMAReq_RX(const SPI_TypeDef *SPIx) +{ + return LL_SPI_IsEnabledDMAReq_RX(SPIx); +} + +/** + * @brief Enable DMA Tx + * @rmtoll CFG1 TXDMAEN LL_I2S_EnableDMAReq_TX + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_I2S_EnableDMAReq_TX(SPI_TypeDef *SPIx) +{ + LL_SPI_EnableDMAReq_TX(SPIx); +} + +/** + * @brief Disable DMA Tx + * @rmtoll CFG1 TXDMAEN LL_I2S_DisableDMAReq_TX + * @param SPIx SPI Instance + * @retval None + */ +__STATIC_INLINE void LL_I2S_DisableDMAReq_TX(SPI_TypeDef *SPIx) +{ + LL_SPI_DisableDMAReq_TX(SPIx); +} + +/** + * @brief Check if DMA Tx is enabled + * @rmtoll CFG1 TXDMAEN LL_I2S_IsEnabledDMAReq_TX + * @param SPIx SPI Instance + * @retval State of bit (1 or 0) + */ +__STATIC_INLINE uint32_t LL_I2S_IsEnabledDMAReq_TX(const SPI_TypeDef *SPIx) +{ + return LL_SPI_IsEnabledDMAReq_TX(SPIx); +} + +/** + * @} + */ + +/** @defgroup I2S_LL_EF_DATA_Management DATA_Management + * @{ + */ + +/** + * @brief Read Data Register + * @rmtoll RXDR . LL_I2S_ReceiveData16 + * @param SPIx SPI Instance + * @retval 0..0xFFFF + */ +__STATIC_INLINE uint16_t LL_I2S_ReceiveData16(SPI_TypeDef *SPIx) /* Derogation MISRAC2012-Rule-8.13 */ +{ + return LL_SPI_ReceiveData16(SPIx); +} + +/** + * @brief Read Data Register + * @rmtoll RXDR . LL_I2S_ReceiveData32 + * @param SPIx SPI Instance + * @retval 0..0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_I2S_ReceiveData32(SPI_TypeDef *SPIx) /* Derogation MISRAC2012-Rule-8.13 */ +{ + return LL_SPI_ReceiveData32(SPIx); +} + +/** + * @brief Write Data Register + * @rmtoll TXDR . LL_I2S_TransmitData16 + * @param SPIx SPI Instance + * @param TxData 0..0xFFFF + * @retval None + */ +__STATIC_INLINE void LL_I2S_TransmitData16(SPI_TypeDef *SPIx, uint16_t TxData) +{ + LL_SPI_TransmitData16(SPIx, TxData); +} + +/** + * @brief Write Data Register + * @rmtoll TXDR . LL_I2S_TransmitData32 + * @param SPIx SPI Instance + * @param TxData 0..0xFFFFFFFF + * @retval None + */ +__STATIC_INLINE void LL_I2S_TransmitData32(SPI_TypeDef *SPIx, uint32_t TxData) +{ + LL_SPI_TransmitData32(SPIx, TxData); +} + + +/** + * @} + */ + + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup I2S_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +ErrorStatus LL_I2S_DeInit(const SPI_TypeDef *SPIx); +ErrorStatus LL_I2S_Init(SPI_TypeDef *SPIx, LL_I2S_InitTypeDef *I2S_InitStruct); +void LL_I2S_StructInit(LL_I2S_InitTypeDef *I2S_InitStruct); +void LL_I2S_ConfigPrescaler(SPI_TypeDef *SPIx, uint32_t PrescalerLinear, uint32_t PrescalerParity); + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined(SPI1) || defined(SPI2) || defined(SPI3) || defined(SPI4) || defined(SPI5) || defined(SPI6) */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_LL_SPI_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_system.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_system.h new file mode 100644 index 0000000000..23496ef9e5 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_system.h @@ -0,0 +1,1824 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_system.h + * @author MCD Application Team + * @brief Header file of SYSTEM LL module. + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The LL SYSTEM driver contains a set of generic APIs that can be + used by user: + (+) Some of the FLASH features need to be handled in the SYSTEM file. + (+) Access to DBGCMU registers + (+) Access to SBS registers + (+) Access to VREFBUF registers + @endverbatim + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_LL_SYSTEM_H +#define STM32H5xx_LL_SYSTEM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (FLASH) || defined (SBS) || defined (DBGMCU) || defined (VREFBUF) + +/** @defgroup SYSTEM_LL SYSTEM + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup SYSTEM_LL_Private_Constants SYSTEM Private Constants + * @{ + */ +#define LL_SBS_HDPL_INCREMENT_VALUE 0x6AU /*!< Define used for the HDPL increment */ +#define LL_SBS_DBG_UNLOCK (0xB4U << SBS_DBGCR_DBG_UNLOCK_Pos) /*!< Define used to unlock debug */ +#define LL_SBS_ACCESS_PORT_UNLOCK 0xB4U /*!< Define used to unlock access port */ +#define LL_SBS_DBG_CONFIG_LOCK 0xC3U /*!< Define used to lock debug configuration */ +#define LL_SBS_DBG_CONFIG_UNLOCK 0xB4U /*!< Define used to unlock debug configuration */ +#define LL_SBS_DEBUG_SEC_NSEC 0xB4U /*!< Define used to open debug for secure and non-secure */ +#define LL_SBS_DEBUG_NSEC 0x3CU /*!< Define used to open debug for non-secure only */ +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup SYSTEM_LL_Exported_Constants SYSTEM Exported Constants + * @{ + */ + +/** @defgroup SYSTEM_LL_SBS_EC_FASTMODEPLUS SBS FASTMODEPLUS + * @{ + */ +#define LL_SBS_FASTMODEPLUS_PB6 SBS_PMCR_PB6_FMP /*!< Enable Fast Mode Plus on PB6 */ +#define LL_SBS_FASTMODEPLUS_PB7 SBS_PMCR_PB7_FMP /*!< Enable Fast Mode Plus on PB7 */ +#define LL_SBS_FASTMODEPLUS_PB8 SBS_PMCR_PB8_FMP /*!< Enable Fast Mode Plus on PB8 */ +#if defined(SBS_PMCR_PB9_FMP) +#define LL_SBS_FASTMODEPLUS_PB9 SBS_PMCR_PB9_FMP /*!< Enable Fast Mode Plus on PB9 */ +#endif /* SBS_PMCR_PB9_FMP */ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_SBS_EC_CS1 SBS Vdd compensation cell Code selection + * @{ + */ +#define LL_SBS_VDD_CELL_CODE 0x0UL /*!< VDD I/Os code from the cell (available in the SBS_CCVALR) */ +#define LL_SBS_VDD_REGISTER_CODE SBS_CCCSR_CS1 /*!< VDD I/Os code from the SBS compensation cell code register (SBS_CCSWCR) */ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_SBS_EC_CS2 SBS VddIO compensation cell Code selection + * @{ + */ +#define LL_SBS_VDDIO_CELL_CODE 0x0UL /*!< VDDIO I/Os code from the cell (available in the SBS_CCVALR)*/ +#define LL_SBS_VDDIO_REGISTER_CODE SBS_CCCSR_CS2 /*!< VDDIO I/Os code from the SBS compensation cell code register (SBS_CCSWCR)*/ +/** + * @} + */ + +#if defined(SBS_PMCR_ETH_SEL_PHY) +/** @defgroup SYSTEM_LL_SBS_ETHERNET_CONFIG ETHENET CONFIG + * @{ + */ +#define LL_SBS_ETH_MII 0x0UL /*!< Select the Media Independent Interface (MII) or GMII */ +#define LL_SBS_ETH_RMII SBS_PMCR_ETH_SEL_PHY_2 /*!< Select the Reduced Media Independent Interface (RMII) */ + +/** + * @} + */ +#endif /* SBS_PMCR_ETH_SEL_PHY */ + +/** @defgroup SYSTEM_Memories_Erase_Flag_Status Memories Erase Flags Status + * @{ + */ +#define LL_SBS_MEMORIES_ERASE_MCLR_ON_GOING 0x0UL /*!< Erase after Power-on Reset of SRAM2, BKPRAM, ICACHE, DCACHE and PKA RAMs on going or cleared by SW */ +#define LL_SBS_MEMORIES_ERASE_MCLR_ENDED SBS_MESR_MCLR /*!< Erase after Power-on Reset of SRAM2, BKPRAM, ICACHE, DCACHE and PKA RAMs done */ +#define LL_SBS_MEMORIES_ERASE_IPMEE_ON_GOING 0x0UL /*!< Erase after Power-on Reset or Tamper detection for ICACHE and PKA RAMs on going or cleared by SW */ +#define LL_SBS_MEMORIES_ERASE_IPMEE_ENDED SBS_MESR_IPMEE /*!< Erase after Power-on Reset or Tamper detection for ICACHE and PKA RAMs done */ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_SBS_EC_TIMBREAK SBS TIMER BREAK + * @{ + */ +#define LL_SBS_TIMBREAK_ECC SBS_CFGR2_ECCL /*!< Enables and locks the Flash ECC double error signal + with Break Input of TIM1/8/15/16/17 */ +#define LL_SBS_TIMBREAK_PVD SBS_CFGR2_PVDL /*!< Enables and locks the PVD connection + with TIM1/8/15/16/17 Break Input and also the PVDE + and PLS bits of the Power Control Interface */ +#define LL_SBS_TIMBREAK_SRAM_ECC SBS_CFGR2_SEL /*!< Enables and locks the SRAM ECC double error signal + with Break Input of TIM1/8/15/16/17 */ +#define LL_SBS_TIMBREAK_LOCKUP SBS_CFGR2_CLL /*!< Enables and locks the LOCKUP (Hardfault) output of + Cortex-M33 with Break Input of TIM1/15/16/17 */ +/** + * @} + */ + + +/** @defgroup SYSTEM_LL_SBS_EPOCH_Selection EPOCH Selection + * @{ + */ +#define LL_SBS_EPOCH_SEL_SECURE 0x0UL /*!< EPOCH secure selected */ +#define LL_SBS_EPOCH_SEL_NONSECURE SBS_EPOCHSELCR_EPOCH_SEL_0 /*!< EPOCH non secure selected */ +#define LL_SBS_EPOCH_SEL_PUFCHECK SBS_EPOCHSELCR_EPOCH_SEL_1 /*!< EPOCH all zeros for PUF integrity check */ + +/** + * @} + */ + +/** @defgroup SYSTEM_LL_SBS_NextHDPL_Selection Next HDPL Selection + * @{ + */ +#define LL_SBS_OBKHDPL_INCR_0 0x00000000U /*!< Index to add to the current HDPL to point (through OBK-HDPL) to the next secure storage areas */ +#define LL_SBS_OBKHDPL_INCR_1 SBS_NEXTHDPLCR_NEXTHDPL_0 /*!< Index to add to the current HDPL to point (through OBK-HDPL) to the next secure storage areas */ +#define LL_SBS_OBKHDPL_INCR_2 SBS_NEXTHDPLCR_NEXTHDPL_1 /*!< Index to add to the current HDPL to point (through OBK-HDPL) to the next secure storage areas */ +#define LL_SBS_OBKHDPL_INCR_3 SBS_NEXTHDPLCR_NEXTHDPL /*!< Index to add to the current HDPL to point (through OBK-HDPL) to the next secure storage areas */ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_SBS_HDPL_Value HDPL Value + * @{ + */ +#define LL_SBS_HDPL_VALUE_0 0x000000B4U /*!< Hide protection level 0 */ +#define LL_SBS_HDPL_VALUE_1 0x00000051U /*!< Hide protection level 1 */ +#define LL_SBS_HDPL_VALUE_2 0x0000008AU /*!< Hide protection level 2 */ +#define LL_SBS_HDPL_VALUE_3 0x0000006FU /*!< Hide protection level 3 */ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_SBS_NS_Lock_items Lock items + * @brief SBS non secure items to set lock on + * @{ + */ +#define LL_SBS_MPU_NSEC SBS_CNSLCKR_LOCKNSMPU /*!< Non-secure MPU lock (privileged secure or non-secure only) */ +#define LL_SBS_VTOR_NSEC SBS_CNSLCKR_LOCKNSVTOR /*!< Non-secure VTOR lock (privileged secure or non-secure only) */ +#define LL_SBS_LOCK_ALL_NSEC (LL_SBS_MPU_NSEC | LL_SBS_VTOR_NSEC) /*!< lock all Non-secure (privileged secure or non-secure only) */ +/** + * @} + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** @defgroup SYSTEM_LL_SBS_S_Lock_items SBS Lock items + * @brief SBS secure items to set lock on + * @{ + */ +#define LL_SBS_SAU SBS_CSLCKR_LOCKSAU /*!< SAU lock (privileged secure code only) */ +#define LL_SBS_MPU_SEC SBS_CSLCKR_LOCKSMPU /*!< Secure MPU lock (privileged secure code only) */ +#define LL_SBS_VTOR_AIRCR_SEC SBS_CSLCKR_LOCKSVTAIRCR /*!< VTOR_S and AIRCR lock (privileged secure code only) */ +#define LL_SBS_LOCK_ALL_SEC (LL_SBS_SAU | LL_SBS_MPU_SEC | LL_SBS_VTOR_AIRCR_SEC) /*!< lock all secure (privileged secure only) */ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_SBS_EC_SECURE_ATTRIBUTES Secure attributes + * @note Only available when system implements security (TZEN=1) + * @{ + */ +#define LL_SBS_CLOCK_SEC SBS_SECCFGR_SBSSEC /*!< SBS clock configuration secure-only access */ +#define LL_SBS_CLOCK_NSEC 0U /*!< SBS clock configuration secure/non-secure access */ +#define LL_SBS_CLASSB_SEC SBS_SECCFGR_CLASSBSEC /*!< Class B configuration secure-only access */ +#define LL_SBS_CLASSB_NSEC 0U /*!< Class B configuration secure/non-secure access */ +#define LL_SBS_FPU_SEC SBS_SECCFGR_FPUSEC /*!< FPU configuration secure-only access */ +#define LL_SBS_FPU_NSEC 0U /*!< FPU configuration secure/non-secure access */ +#define LL_SBS_SMPS_SEC SBS_SECCFGR_SDCE_SEC_EN /*!< SMPS configuration secure-only access */ +#define LL_SBS_SMPS_NSEC 0U /*!< SMPS configuration secure/non-secure access */ +/** + * @} + */ +#endif /* __ARM_FEATURE_CMSE */ + +/** @defgroup SYSTEM_LL_DBGMCU_EC_TRACE DBGMCU TRACE Pin Assignment + * @{ + */ +#define LL_DBGMCU_TRACE_NONE 0x00000000U /*!< TRACE pins not assigned (default state) */ +#define LL_DBGMCU_TRACE_ASYNCH DBGMCU_CR_TRACE_IOEN /*!< TRACE pin assignment for Asynchronous Mode */ +#define LL_DBGMCU_TRACE_SYNCH_SIZE1 (DBGMCU_CR_TRACE_IOEN | DBGMCU_CR_TRACE_MODE_0) /*!< TRACE pin assignment for Synchronous Mode with a TRACEDATA size of 1 */ +#define LL_DBGMCU_TRACE_SYNCH_SIZE2 (DBGMCU_CR_TRACE_IOEN | DBGMCU_CR_TRACE_MODE_1) /*!< TRACE pin assignment for Synchronous Mode with a TRACEDATA size of 2 */ +#define LL_DBGMCU_TRACE_SYNCH_SIZE4 (DBGMCU_CR_TRACE_IOEN | DBGMCU_CR_TRACE_MODE) /*!< TRACE pin assignment for Synchronous Mode with a TRACEDATA size of 4 */ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_DBGMCU_EC_APB1_GRP1_STOP_IP DBGMCU APB1 GRP1 STOP IP + * @{ + */ +#define LL_DBGMCU_APB1_GRP1_TIM2_STOP DBGMCU_APB1FZR1_DBG_TIM2_STOP /*!< The counter clock of TIM2 is stopped when the core is halted*/ +#define LL_DBGMCU_APB1_GRP1_TIM3_STOP DBGMCU_APB1FZR1_DBG_TIM3_STOP /*!< The counter clock of TIM3 is stopped when the core is halted*/ +#if defined(TIM4) +#define LL_DBGMCU_APB1_GRP1_TIM4_STOP DBGMCU_APB1FZR1_DBG_TIM4_STOP /*!< The counter clock of TIM4 is stopped when the core is halted*/ +#endif /* TIM4 */ +#if defined(TIM5) +#define LL_DBGMCU_APB1_GRP1_TIM5_STOP DBGMCU_APB1FZR1_DBG_TIM5_STOP /*!< The counter clock of TIM5 is stopped when the core is halted*/ +#endif /* TIM5 */ +#define LL_DBGMCU_APB1_GRP1_TIM6_STOP DBGMCU_APB1FZR1_DBG_TIM6_STOP /*!< The counter clock of TIM6 is stopped when the core is halted*/ +#define LL_DBGMCU_APB1_GRP1_TIM7_STOP DBGMCU_APB1FZR1_DBG_TIM7_STOP /*!< The counter clock of TIM7 is stopped when the core is halted*/ +#if defined(TIM12) +#define LL_DBGMCU_APB1_GRP1_TIM12_STOP DBGMCU_APB1FZR1_DBG_TIM12_STOP /*!< The counter clock of TIM12 is stopped when the core is halted*/ +#endif /* TIM12 */ +#if defined(TIM13) +#define LL_DBGMCU_APB1_GRP1_TIM13_STOP DBGMCU_APB1FZR1_DBG_TIM13_STOP /*!< The counter clock of TIM13 is stopped when the core is halted*/ +#endif /* TIM13 */ +#if defined(TIM14) +#define LL_DBGMCU_APB1_GRP1_TIM14_STOP DBGMCU_APB1FZR1_DBG_TIM14_STOP /*!< The counter clock of TIM14 is stopped when the core is halted*/ +#endif /* TIM14 */ +#define LL_DBGMCU_APB1_GRP1_WWDG_STOP DBGMCU_APB1FZR1_DBG_WWDG_STOP /*!< The window watchdog counter clock is stopped when the core is halted*/ +#define LL_DBGMCU_APB1_GRP1_IWDG_STOP DBGMCU_APB1FZR1_DBG_IWDG_STOP /*!< The independent watchdog counter clock is stopped when the core is halted*/ +#define LL_DBGMCU_APB1_GRP1_I2C1_STOP DBGMCU_APB1FZR1_DBG_I2C1_STOP /*!< The I2C1 SMBus timeout is frozen*/ +#define LL_DBGMCU_APB1_GRP1_I2C2_STOP DBGMCU_APB1FZR1_DBG_I2C2_STOP /*!< The I2C2 SMBus timeout is frozen*/ +#define LL_DBGMCU_APB1_GRP1_I3C1_STOP DBGMCU_APB1FZR1_DBG_I3C1_STOP /*!< The I3C1 SMBus timeout is frozen*/ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_DBGMCU_EC_APB1_GRP2_STOP_IP DBGMCU APB1 GRP2 STOP IP + * @{ + */ +#define LL_DBGMCU_APB1_GRP2_LPTIM2_STOP DBGMCU_APB1FZR2_DBG_LPTIM2_STOP /*!< The counter clock of LPTIM2 is stopped when the core is halted*/ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_DBGMCU_EC_APB2_GRP1_STOP_IP DBGMCU APB2 GRP1 STOP IP + * @{ + */ +#define LL_DBGMCU_APB2_GRP1_TIM1_STOP DBGMCU_APB2FZR_DBG_TIM1_STOP /*!< The counter clock of TIM1 is stopped when the core is halted*/ +#if defined(TIM8) +#define LL_DBGMCU_APB2_GRP1_TIM8_STOP DBGMCU_APB2FZR_DBG_TIM8_STOP /*!< The counter clock of TIM8 is stopped when the core is halted*/ +#endif /* TIM8 */ +#if defined(TIM15) +#define LL_DBGMCU_APB2_GRP1_TIM15_STOP DBGMCU_APB2FZR_DBG_TIM15_STOP /*!< The counter clock of TIM15 is stopped when the core is halted*/ +#endif /* TIM15 */ +#if defined(TIM16) +#define LL_DBGMCU_APB2_GRP1_TIM16_STOP DBGMCU_APB2FZR_DBG_TIM16_STOP /*!< The counter clock of TIM16 is stopped when the core is halted*/ +#endif /* TIM16 */ +#if defined(TIM17) +#define LL_DBGMCU_APB2_GRP1_TIM17_STOP DBGMCU_APB2FZR_DBG_TIM17_STOP /*!< The counter clock of TIM17 is stopped when the core is halted*/ +#endif /* TIM17 */ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_DBGMCU_EC_APB3_GRP1_STOP_IP DBGMCU APB3 GRP1 STOP IP + * @{ + */ +#if defined(I2C3) +#define LL_DBGMCU_APB3_GRP1_I2C3_STOP DBGMCU_APB3FZR_DBG_I2C3_STOP /*!< The counter clock of I2C3 is stopped when the core is halted*/ +#endif /* I2C3 */ +#if defined(I2C4) +#define LL_DBGMCU_APB3_GRP1_I2C4_STOP DBGMCU_APB3FZR_DBG_I2C4_STOP /*!< The counter clock of I2C4 is stopped when the core is halted*/ +#endif /* I2C4 */ +#if defined(I3C2) +#define LL_DBGMCU_APB3_GRP1_I3C2_STOP DBGMCU_APB3FZR_DBG_I3C2_STOP /*!< The counter clock of I3C2 is stopped when the core is halted*/ +#endif /* I3C2 */ +#define LL_DBGMCU_APB3_GRP1_LPTIM1_STOP DBGMCU_APB3FZR_DBG_LPTIM1_STOP /*!< The counter clock of LPTIM1 is stopped when the core is halted*/ +#if defined(LPTIM3) +#define LL_DBGMCU_APB3_GRP1_LPTIM3_STOP DBGMCU_APB3FZR_DBG_LPTIM3_STOP /*!< The counter clock of LPTIM3 is stopped when the core is halted*/ +#endif /* LPTIM3 */ +#if defined(LPTIM4) +#define LL_DBGMCU_APB3_GRP1_LPTIM4_STOP DBGMCU_APB3FZR_DBG_LPTIM4_STOP /*!< The counter clock of LPTIM4 is stopped when the core is halted*/ +#endif /* LPTIM4 */ +#if defined(LPTIM5) +#define LL_DBGMCU_APB3_GRP1_LPTIM5_STOP DBGMCU_APB3FZR_DBG_LPTIM5_STOP /*!< The counter clock of LPTIM5 is stopped when the core is halted*/ +#endif /* LPTIM5 */ +#if defined(LPTIM6) +#define LL_DBGMCU_APB3_GRP1_LPTIM6_STOP DBGMCU_APB3FZR_DBG_LPTIM6_STOP /*!< The counter clock of LPTIM6 is stopped when the core is halted*/ +#endif /* LPTIM6 */ +#define LL_DBGMCU_APB3_GRP1_RTC_STOP DBGMCU_APB3FZR_DBG_RTC_STOP /*!< The counter clock of RTC is stopped when the core is halted*/ +/** + * @} + */ + + +#if defined(VREFBUF) +/** @defgroup SYSTEM_LL_VREFBUF_EC_VOLTAGE VREFBUF VOLTAGE + * @{ + */ +#define LL_VREFBUF_VOLTAGE_SCALE0 ((uint32_t)0x00000000) /*!< Voltage reference scale 0 (VREF_OUT1) */ +#define LL_VREFBUF_VOLTAGE_SCALE1 VREFBUF_CSR_VRS_0 /*!< Voltage reference scale 1 (VREF_OUT2) */ +#define LL_VREFBUF_VOLTAGE_SCALE2 VREFBUF_CSR_VRS_1 /*!< Voltage reference scale 2 (VREF_OUT3) */ +#define LL_VREFBUF_VOLTAGE_SCALE3 (VREFBUF_CSR_VRS_0 | VREFBUF_CSR_VRS_1) /*!< Voltage reference scale 3 (VREF_OUT4) */ +/** + * @} + */ +#endif /* VREFBUF */ + +/** @defgroup SYSTEM_LL_FLASH_EC_LATENCY FLASH LATENCY + * @{ + */ +#define LL_FLASH_LATENCY_0 FLASH_ACR_LATENCY_0WS /*!< FLASH zero wait state */ +#define LL_FLASH_LATENCY_1 FLASH_ACR_LATENCY_1WS /*!< FLASH one wait state */ +#define LL_FLASH_LATENCY_2 FLASH_ACR_LATENCY_2WS /*!< FLASH two wait states */ +#define LL_FLASH_LATENCY_3 FLASH_ACR_LATENCY_3WS /*!< FLASH three wait states */ +#define LL_FLASH_LATENCY_4 FLASH_ACR_LATENCY_4WS /*!< FLASH four wait states */ +#define LL_FLASH_LATENCY_5 FLASH_ACR_LATENCY_5WS /*!< FLASH five wait states */ +#define LL_FLASH_LATENCY_6 FLASH_ACR_LATENCY_6WS /*!< FLASH six wait state */ +#define LL_FLASH_LATENCY_7 FLASH_ACR_LATENCY_7WS /*!< FLASH Seven wait states */ +#define LL_FLASH_LATENCY_8 FLASH_ACR_LATENCY_8WS /*!< FLASH Eight wait states */ +#define LL_FLASH_LATENCY_9 FLASH_ACR_LATENCY_9WS /*!< FLASH nine wait states */ +#define LL_FLASH_LATENCY_10 FLASH_ACR_LATENCY_10WS /*!< FLASH ten wait states */ +#define LL_FLASH_LATENCY_11 FLASH_ACR_LATENCY_11WS /*!< FLASH eleven wait states */ +#define LL_FLASH_LATENCY_12 FLASH_ACR_LATENCY_12WS /*!< FLASH twelve wait states */ +#define LL_FLASH_LATENCY_13 FLASH_ACR_LATENCY_13WS /*!< FLASH thirteen wait states */ +#define LL_FLASH_LATENCY_14 FLASH_ACR_LATENCY_14WS /*!< FLASH fourteen wait states */ +#define LL_FLASH_LATENCY_15 FLASH_ACR_LATENCY_15WS /*!< FLASH fifteen wait states */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup SYSTEM_LL_Exported_Functions SYSTEM Exported Functions + * @{ + */ + +/** @defgroup SYSTEM_LL_EF_SBS SBS + * @{ + */ + +#if defined(SBS_PMCR_ETH_SEL_PHY) +/** + * @brief Select Ethernet PHY interface + * @rmtoll PMCR EPIS_SEL LL_SBS_SetPHYInterface + * @param Interface This parameter can be one of the following values: + * @arg @ref LL_SBS_ETH_MII + * @arg @ref LL_SBS_ETH_RMII + * @retval None + */ +__STATIC_INLINE void LL_SBS_SetPHYInterface(uint32_t Interface) +{ + MODIFY_REG(SBS->PMCR, SBS_PMCR_ETH_SEL_PHY, Interface); +} + +/** + * @brief Get Ethernet PHY interface + * @rmtoll PMCR EPIS_SEL LL_SBS_GetPHYInterface + * @retval Returned value can be one of the following values: + * @arg @ref LL_SBS_ETH_MII + * @arg @ref LL_SBS_ETH_RMII + */ +__STATIC_INLINE uint32_t LL_SBS_GetPHYInterface(void) +{ + return (uint32_t)(READ_BIT(SBS->PMCR, SBS_PMCR_ETH_SEL_PHY)); +} +#endif /* SBS_PMCR_ETH_SEL_PHY */ + +/** + * @brief Enable the fast mode plus driving capability. + * @rmtoll PMCR PBx_FMP LL_SBS_EnableFastModePlus\n + * PMCR PBx_FMP LL_SBS_EnableFastModePlus + * @param ConfigFastModePlus This parameter can be a combination of the following values: + * @arg @ref LL_SBS_FASTMODEPLUS_PB6 + * @arg @ref LL_SBS_FASTMODEPLUS_PB7 + * @arg @ref LL_SBS_FASTMODEPLUS_PB8 + * @arg @ref LL_SBS_FASTMODEPLUS_PB9 + * @retval None + */ +__STATIC_INLINE void LL_SBS_EnableFastModePlus(uint32_t ConfigFastModePlus) +{ + SET_BIT(SBS->PMCR, ConfigFastModePlus); +} + +/** + * @brief Disable the fast mode plus driving capability. + * @rmtoll PMCR PBx_FMP LL_SBS_DisableFastModePlus\n + * PMCR PBx_FMP LL_SBS_DisableFastModePlus + * @param ConfigFastModePlus This parameter can be a combination of the following values: + * @arg @ref LL_SBS_FASTMODEPLUS_PB6 + * @arg @ref LL_SBS_FASTMODEPLUS_PB7 + * @arg @ref LL_SBS_FASTMODEPLUS_PB8 + * @arg @ref LL_SBS_FASTMODEPLUS_PB9 + * @retval None + */ +__STATIC_INLINE void LL_SBS_DisableFastModePlus(uint32_t ConfigFastModePlus) +{ + CLEAR_BIT(SBS->PMCR, ConfigFastModePlus); +} + +/** + * @brief Enable Floating Point Unit Invalid operation Interrupt + * @rmtoll FPUIMR FPU_IE_0 LL_SBS_EnableIT_FPU_IOC + * @retval None + */ +__STATIC_INLINE void LL_SBS_EnableIT_FPU_IOC(void) +{ + SET_BIT(SBS->FPUIMR, SBS_FPUIMR_FPU_IE_0); +} + +/** + * @brief Enable Floating Point Unit Divide-by-zero Interrupt + * @rmtoll FPUIMR FPU_IE_1 LL_SBS_EnableIT_FPU_DZC + * @retval None + */ +__STATIC_INLINE void LL_SBS_EnableIT_FPU_DZC(void) +{ + SET_BIT(SBS->FPUIMR, SBS_FPUIMR_FPU_IE_1); +} + +/** + * @brief Enable Floating Point Unit Underflow Interrupt + * @rmtoll FPUIMR FPU_IE_2 LL_SBS_EnableIT_FPU_UFC + * @retval None + */ +__STATIC_INLINE void LL_SBS_EnableIT_FPU_UFC(void) +{ + SET_BIT(SBS->FPUIMR, SBS_FPUIMR_FPU_IE_2); +} + +/** + * @brief Enable Floating Point Unit Overflow Interrupt + * @rmtoll FPUIMR FPU_IE_3 LL_SBS_EnableIT_FPU_OFC + * @retval None + */ +__STATIC_INLINE void LL_SBS_EnableIT_FPU_OFC(void) +{ + SET_BIT(SBS->FPUIMR, SBS_FPUIMR_FPU_IE_3); +} + +/** + * @brief Enable Floating Point Unit Input denormal Interrupt + * @rmtoll FPUIMR FPU_IE_4 LL_SBS_EnableIT_FPU_IDC + * @retval None + */ +__STATIC_INLINE void LL_SBS_EnableIT_FPU_IDC(void) +{ + SET_BIT(SBS->FPUIMR, SBS_FPUIMR_FPU_IE_4); +} + +/** + * @brief Enable Floating Point Unit Inexact Interrupt + * @rmtoll FPUIMR FPU_IE_5 LL_SBS_EnableIT_FPU_IXC + * @retval None + */ +__STATIC_INLINE void LL_SBS_EnableIT_FPU_IXC(void) +{ + SET_BIT(SBS->FPUIMR, SBS_FPUIMR_FPU_IE_5); +} + +/** + * @brief Disable Floating Point Unit Invalid operation Interrupt + * @rmtoll FPUIMR FPU_IE_0 LL_SBS_DisableIT_FPU_IOC + * @retval None + */ +__STATIC_INLINE void LL_SBS_DisableIT_FPU_IOC(void) +{ + CLEAR_BIT(SBS->FPUIMR, SBS_FPUIMR_FPU_IE_0); +} + +/** + * @brief Disable Floating Point Unit Divide-by-zero Interrupt + * @rmtoll FPUIMR FPU_IE_1 LL_SBS_DisableIT_FPU_DZC + * @retval None + */ +__STATIC_INLINE void LL_SBS_DisableIT_FPU_DZC(void) +{ + CLEAR_BIT(SBS->FPUIMR, SBS_FPUIMR_FPU_IE_1); +} + +/** + * @brief Disable Floating Point Unit Underflow Interrupt + * @rmtoll FPUIMR FPU_IE_2 LL_SBS_DisableIT_FPU_UFC + * @retval None + */ +__STATIC_INLINE void LL_SBS_DisableIT_FPU_UFC(void) +{ + CLEAR_BIT(SBS->FPUIMR, SBS_FPUIMR_FPU_IE_2); +} + +/** + * @brief Disable Floating Point Unit Overflow Interrupt + * @rmtoll FPUIMR FPU_IE_3 LL_SBS_DisableIT_FPU_OFC + * @retval None + */ +__STATIC_INLINE void LL_SBS_DisableIT_FPU_OFC(void) +{ + CLEAR_BIT(SBS->FPUIMR, SBS_FPUIMR_FPU_IE_3); +} + +/** + * @brief Disable Floating Point Unit Input denormal Interrupt + * @rmtoll FPUIMR FPU_IE_4 LL_SBS_DisableIT_FPU_IDC + * @retval None + */ +__STATIC_INLINE void LL_SBS_DisableIT_FPU_IDC(void) +{ + CLEAR_BIT(SBS->FPUIMR, SBS_FPUIMR_FPU_IE_4); +} + +/** + * @brief Disable Floating Point Unit Inexact Interrupt + * @rmtoll FPUIMR FPU_IE_5 LL_SBS_DisableIT_FPU_IXC + * @retval None + */ +__STATIC_INLINE void LL_SBS_DisableIT_FPU_IXC(void) +{ + CLEAR_BIT(SBS->FPUIMR, SBS_FPUIMR_FPU_IE_5); +} + +/** + * @brief Check if Floating Point Unit Invalid operation Interrupt source is enabled or disabled. + * @rmtoll FPUIMR FPU_IE_0 LL_SBS_IsEnabledIT_FPU_IOC + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SBS_IsEnabledIT_FPU_IOC(void) +{ + return ((READ_BIT(SBS->FPUIMR, SBS_FPUIMR_FPU_IE_0) == SBS_FPUIMR_FPU_IE_0) ? 1UL : 0UL); +} + +/** + * @brief Check if Floating Point Unit Divide-by-zero Interrupt source is enabled or disabled. + * @rmtoll FPUIMR FPU_IE_1 LL_SBS_IsEnabledIT_FPU_DZC + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SBS_IsEnabledIT_FPU_DZC(void) +{ + return ((READ_BIT(SBS->FPUIMR, SBS_FPUIMR_FPU_IE_1) == SBS_FPUIMR_FPU_IE_1) ? 1UL : 0UL); +} + +/** + * @brief Check if Floating Point Unit Underflow Interrupt source is enabled or disabled. + * @rmtoll FPUIMR FPU_IE_2 LL_SBS_IsEnabledIT_FPU_UFC + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SBS_IsEnabledIT_FPU_UFC(void) +{ + return ((READ_BIT(SBS->FPUIMR, SBS_FPUIMR_FPU_IE_2) == SBS_FPUIMR_FPU_IE_2) ? 1UL : 0UL); +} + +/** + * @brief Check if Floating Point Unit Overflow Interrupt source is enabled or disabled. + * @rmtoll FPUIMR FPU_IE_3 LL_SBS_IsEnabledIT_FPU_OFC + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SBS_IsEnabledIT_FPU_OFC(void) +{ + return ((READ_BIT(SBS->FPUIMR, SBS_FPUIMR_FPU_IE_3) == SBS_FPUIMR_FPU_IE_3) ? 1UL : 0UL); +} + +/** + * @brief Check if Floating Point Unit Input denormal Interrupt source is enabled or disabled. + * @rmtoll FPUIMR FPU_IE_4 LL_SBS_IsEnabledIT_FPU_IDC + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SBS_IsEnabledIT_FPU_IDC(void) +{ + return ((READ_BIT(SBS->FPUIMR, SBS_FPUIMR_FPU_IE_4) == SBS_FPUIMR_FPU_IE_4) ? 1UL : 0UL); +} + +/** + * @brief Check if Floating Point Unit Inexact Interrupt source is enabled or disabled. + * @rmtoll FPUIMR FPU_IE_5 LL_SBS_IsEnabledIT_FPU_IXC + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SBS_IsEnabledIT_FPU_IXC(void) +{ + return ((READ_BIT(SBS->FPUIMR, SBS_FPUIMR_FPU_IE_5) == SBS_FPUIMR_FPU_IE_5) ? 1UL : 0UL); +} + +/** + * @brief Set connections to TIM1/8/15/16/17 Break inputs + * @rmtoll CFGR2 CLL LL_SBS_SetTIMBreakInputs\n + * CFGR2 SEL LL_SBS_SetTIMBreakInputs\n + * CFGR2 PVDL LL_SBS_SetTIMBreakInputs\n + * CFGR2 ECCL LL_SBS_SetTIMBreakInputs + * @param Break This parameter can be a combination of the following values: + * where non selected TIMBREAK input is disconnected. + * @arg @ref LL_SBS_TIMBREAK_ECC + * @arg @ref LL_SBS_TIMBREAK_PVD + * @arg @ref LL_SBS_TIMBREAK_SRAM_ECC + * @arg @ref LL_SBS_TIMBREAK_LOCKUP + * @retval None + */ +__STATIC_INLINE void LL_SBS_SetTIMBreakInputs(uint32_t Break) +{ + MODIFY_REG(SBS->CFGR2, SBS_CFGR2_CLL | SBS_CFGR2_SEL | SBS_CFGR2_PVDL | SBS_CFGR2_ECCL, Break); +} + +/** + * @brief Get connections to TIM1/8/15/16/17 Break inputs + * @rmtoll CFGR2 CLL LL_SBS_GetTIMBreakInputs\n + * CFGR2 SEL LL_SBS_GetTIMBreakInputs\n + * CFGR2 PVDL LL_SBS_GetTIMBreakInputs\n + * CFGR2 ECCL LL_SBS_GetTIMBreakInputs + * @retval Returned value can be a combination of the following values: + * @arg @ref LL_SBS_TIMBREAK_ECC + * @arg @ref LL_SBS_TIMBREAK_PVD + * @arg @ref LL_SBS_TIMBREAK_SRAM_ECC + * @arg @ref LL_SBS_TIMBREAK_LOCKUP + */ +__STATIC_INLINE uint32_t LL_SBS_GetTIMBreakInputs(void) +{ + return (uint32_t)(READ_BIT(SBS->CFGR2, SBS_CFGR2_CLL | SBS_CFGR2_SEL | SBS_CFGR2_PVDL | SBS_CFGR2_ECCL)); +} + +#if defined(SBS_EPOCHSELCR_EPOCH_SEL) +/** + * @brief Select EPOCH security sent to SAES IP to encrypt/decrypt keys + * @rmtoll EPOCHSELCR EPOCH_SEL LL_SBS_EPOCHSelection + * @param Epoch_Selection: Select EPOCH security + * This parameter can be one of the following values: + * @arg LL_SBS_EPOCH_SEL_SECURE : EPOCH secure selected. + * @arg LL_SBS_EPOCH_SEL_NONSECURE : EPOCH non secure selected. + * @arg LL_SBS_EPOCH_SEL_PUFCHECK : EPOCH all zeros for PUF integrity check. + * @retval None + */ +__STATIC_INLINE void LL_SBS_EPOCHSelection(uint32_t Epoch_Selection) +{ + MODIFY_REG(SBS->EPOCHSELCR, SBS_EPOCHSELCR_EPOCH_SEL, (uint32_t)(Epoch_Selection)); +} + +/** + * @brief Get EPOCH security selection + * @rmtoll EPOCHSELCR EPOCH_SEL LL_SBS_GetEPOCHSelection + * @retval Returned value can be one of the following values: + * @arg LL_SBS_EPOCH_SEL_SECURE : EPOCH secure selected. + * @arg LL_SBS_EPOCH_SEL_NONSECURE : EPOCH non secure selected. + * @arg LL_SBS_EPOCH_SEL_PUFCHECK : EPOCH all zeros for PUF integrity check. + */ +__STATIC_INLINE uint32_t LL_SBS_GetEPOCHSelection(void) +{ + return (uint32_t)(READ_BIT(SBS->EPOCHSELCR, SBS_EPOCHSELCR_EPOCH_SEL)); +} +#endif /* SBS_EPOCHSELCR_EPOCH_SEL */ + +/** + * @brief Disable the NMI in case of double ECC error in FLASH Interface. + * @rmtoll ECCNMIR SBS_ECCNMIR_ECCNMI_MASK_EN LL_SBS_FLASH_DisableECCNMI + * @retval None + */ +__STATIC_INLINE void LL_SBS_FLASH_DisableECCNMI(void) +{ + SET_BIT(SBS->ECCNMIR, SBS_ECCNMIR_ECCNMI_MASK_EN); +} + +/** + * @brief Enable the NMI in case of double ECC error in FLASH Interface. + * @rmtoll ECCNMIR SBS_ECCNMIR_ECCNMI_MASK_EN LL_SBS_FLASH_EnableECCNMI + * @retval None + */ +__STATIC_INLINE void LL_SBS_FLASH_EnableECCNMI(void) +{ + CLEAR_BIT(SBS->ECCNMIR, SBS_ECCNMIR_ECCNMI_MASK_EN); +} + +/** @defgroup SYSTEM_LL_SBS_EF_HDPL_Management HDPL Management + * @{ + */ + +/** + * @brief Increment by 1 the HDPL value + * @rmtoll HDPLCR HDPL_INCR LL_SBS_IncrementHDPLValue + * @retval None + */ +__STATIC_INLINE void LL_SBS_IncrementHDPLValue(void) +{ + MODIFY_REG(SBS->HDPLCR, SBS_HDPLCR_INCR_HDPL, LL_SBS_HDPL_INCREMENT_VALUE); +} + +/** + * @brief Get the HDPL Value. + * @rmtoll HDPLSR HDPL LL_SBS_GetHDPLValue + * @retval Returns the HDPL value + * This return value can be one of the following values: + * @arg LL_SBS_HDPL_VALUE_0: HDPL0 + * @arg LL_SBS_HDPL_VALUE_1: HDPL1 + * @arg LL_SBS_HDPL_VALUE_2: HDPL2 + * @arg LL_SBS_HDPL_VALUE_3: HDPL3 + */ +__STATIC_INLINE uint32_t LL_SBS_GetHDPLValue(void) +{ + return (uint32_t)(READ_BIT(SBS->HDPLSR, SBS_HDPLSR_HDPL)); +} + +#if defined(SBS_NEXTHDPLCR_NEXTHDPL) +/** + * @brief Set the OBK-HDPL Value. + * @rmtoll NEXTHDPLCR NEXTHDPL LL_SBS_SetOBKHDPL + * @param OBKHDPL_Value Value of increment to add to HDPL value to generate the OBK-HDPL. + * This parameter can be one of the following values: + * @arg LL_SBS_OBKHDPL_INCR_0 : HDPL + * @arg LL_SBS_OBKHDPL_INCR_1 : HDPL + 1 + * @arg LL_SBS_OBKHDPL_INCR_2 : HDPL + 2 + * @arg LL_SBS_OBKHDPL_INCR_3 : HDPL + 3 + * @retval None + */ +__STATIC_INLINE void LL_SBS_SetOBKHDPL(uint32_t OBKHDPL_Value) +{ + MODIFY_REG(SBS->NEXTHDPLCR, SBS_NEXTHDPLCR_NEXTHDPL, (uint32_t)(OBKHDPL_Value)); +} + +/** + * @brief Get the OBK-HDPL Value. + * @rmtoll NEXTHDPLCR NEXTHDPL LL_SBS_GetOBKHDPL + * @retval Returns the incremement to add to HDPL value to generate OBK-HDPL + * This return value can be one of the following values: + * @arg LL_SBS_OBKHDPL_INCR_0: HDPL + * @arg LL_SBS_OBKHDPL_INCR_1: HDPL + 1 + * @arg LL_SBS_OBKHDPL_INCR_2: HDPL + 2 + * @arg LL_SBS_OBKHDPL_INCR_3: HDPL + 3 + */ +__STATIC_INLINE uint32_t LL_SBS_GetOBKHDPL(void) +{ + return (uint32_t)(READ_BIT(SBS->NEXTHDPLCR, SBS_NEXTHDPLCR_NEXTHDPL)); +} +#endif /* SBS_NEXTHDPLCR_NEXTHDPL */ + +/** + * @} + */ + +/** @defgroup SYSTEM_LL_SBS_EF_Debug_Control Debug Control + * @{ + */ + +/** + * @brief Set the authenticated debug hide protection level + * @rmtoll SBS_DBGCR DBG_AUTH_HDPL LL_SBS_SetAuthDbgHDPL + * @param Level This parameter can be one of the following values: + * @arg @ref LL_SBS_HDPL_VALUE_1 + * @arg @ref LL_SBS_HDPL_VALUE_2 + * @arg @ref LL_SBS_HDPL_VALUE_3 + * @retval None + */ +__STATIC_INLINE void LL_SBS_SetAuthDbgHDPL(uint32_t Level) +{ + MODIFY_REG(SBS->DBGCR, SBS_DBGCR_DBG_AUTH_HDPL, (Level << SBS_DBGCR_DBG_AUTH_HDPL_Pos)); +} + +/** + * @brief Get current hide protection level + * @rmtoll SBS_DBGCR DBG_AUTH_HDPL LL_SBS_GetAuthDbgHDPL + * @retval Returned value is the hide protection level where the authenticated debug is opened: + * @arg @ref LL_SBS_HDPL_VALUE_1 + * @arg @ref LL_SBS_HDPL_VALUE_2 + * @arg @ref LL_SBS_HDPL_VALUE_3 + */ +__STATIC_INLINE uint32_t LL_SBS_GetAuthDbgHDPL(void) +{ + return (uint32_t)(READ_BIT(SBS->DBGCR, SBS_DBGCR_DBG_AUTH_HDPL) >> SBS_DBGCR_DBG_AUTH_HDPL_Pos); +} + +#if defined(SBS_DBGCR_DBG_AUTH_SEC) +/** + * @brief Configure the authenticated debug security access. + * @rmtoll SBS_DBGCR DBG_AUTH_SEC LL_SBS_SetAuthDbgSec + * @param Control debug opening secure/non-secure or non-secure only + * This parameter can be one of the following values: + * @arg LL_SBS_DEBUG_SEC_NSEC: debug opening for secure and non-secure. + * @arg LL_SBS_DEBUG_NSEC: debug opening for non-secure only. + * @retval None + */ +__STATIC_INLINE void LL_SBS_SetAuthDbgSec(uint32_t Security) +{ + MODIFY_REG(SBS->DBGCR, SBS_DBGCR_DBG_AUTH_SEC, (Security << SBS_DBGCR_DBG_AUTH_SEC_Pos)); +} + +/** + * @brief Get the current value of the hide protection level. + * @rmtoll SBS_DBGCR DBG_AUTH_SEC LL_SBS_GetAuthDbgSec + * @note This function can be only used when device state is Closed. + * @retval Returned value can be one of the following values: + * @arg SBS_DEBUG_SEC_NSEC: debug opening for secure and non-secure. + * @arg any other value: debug opening for non-secure only. + */ +__STATIC_INLINE uint32_t LL_SBS_GetAuthDbgSec(void) +{ + return ((SBS->DBGCR & SBS_DBGCR_DBG_AUTH_SEC) >> SBS_DBGCR_DBG_AUTH_SEC_Pos); +} + +#endif /* SBS_DBGCR_DBG_AUTH_SEC */ + +/** + * @brief Unlock the debug + * @rmtoll SBS_DBGCR DBG_UNLOCK LL_SBS_UnlockDebug + * @retval None + */ +__STATIC_INLINE void LL_SBS_UnlockDebug(void) +{ + MODIFY_REG(SBS->DBGCR, SBS_DBGCR_DBG_UNLOCK, LL_SBS_DBG_UNLOCK); +} + +/** + * @brief Check if the debug is unlocked + * @rmtoll SBS_DBGCR DBG_UNLOCK LL_SBS_IsUnlockedDebug + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SBS_IsUnlockedDebug(void) +{ + return ((READ_BIT(SBS->DBGCR, SBS_DBGCR_DBG_UNLOCK) == LL_SBS_DBG_UNLOCK) ? 1UL : 0UL); +} + +/** + * @brief Unlock the access port + * @rmtoll SBS_DBGCR AP_UNLOCK LL_SBS_UnlockAccessPort + * @retval None + */ +__STATIC_INLINE void LL_SBS_UnlockAccessPort(void) +{ + MODIFY_REG(SBS->DBGCR, SBS_DBGCR_AP_UNLOCK, LL_SBS_ACCESS_PORT_UNLOCK); +} + +/** + * @brief Check if the access port is unlocked + * @rmtoll SBS_DBGCR AP_UNLOCK LL_SBS_IsUnlockedAccessPort + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SBS_IsUnlockedAccessPort(void) +{ + return ((READ_BIT(SBS->DBGCR, SBS_DBGCR_AP_UNLOCK) == LL_SBS_ACCESS_PORT_UNLOCK) ? 1UL : 0UL); +} + +/** + * @brief Lock the debug configuration + * @rmtoll SBS_DBGLOCKR DBGCFG_LOCK LL_SBS_LockDebugConfig + * @retval None + */ +__STATIC_INLINE void LL_SBS_LockDebugConfig(void) +{ + MODIFY_REG(SBS->DBGLOCKR, SBS_DBGLOCKR_DBGCFG_LOCK, LL_SBS_DBG_CONFIG_LOCK); +} + +/** + * @brief Check if the debug configuration is locked + * @rmtoll SBS_DBGLOCKR DBGCFG_LOCK LL_SBS_IsLockedDebugConfig + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SBS_IsLockedDebugConfig(void) +{ + return ((READ_BIT(SBS->DBGLOCKR, SBS_DBGLOCKR_DBGCFG_LOCK) != LL_SBS_DBG_CONFIG_UNLOCK) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup SYSTEM_LL_SBS_EF_lock_Management lock Management + * @{ + */ + +/** + * @brief Non-secure Lock of SBS item(s). + * @note Setting lock(s) depends on privilege mode in secure/non-secure code + * Lock(s) cleared only at system reset + * @rmtoll CNSLCKR LOCKNSVTOR LL_SBS_NonSecureLock\n + * CNSLCKR LOCKNSMPU LL_SBS_NonSecureLock + * @param Item Item(s) to set lock on. + * This parameter can be one of the following values : + * @arg LL_SBS_VTOR_NSEC : VTOR_NS register lock + * @arg LL_SBS_MPU_NSEC : Non-secure MPU registers lock + * @arg LL_SBS_LOCK_ALL_NSEC : Non-secure MPU and VTOR_NS lock + * @retval None + */ +__STATIC_INLINE void LL_SBS_NonSecureLock(uint32_t Item) +{ + /* Privilege secure/non-secure locks */ + SBS->CNSLCKR = Item; +} + +/** + * @brief Get the non secure lock state of SBS items. + * @note Getting lock(s) depends on privilege mode in secure/non-secure code + * @rmtoll CNSLCKR LOCKNSVTOR LL_SBS_NonSecureLock\n + * CNSLCKR LOCKNSMPU LL_SBS_NonSecureLock + * @retval the return value can be one of the following values : + * @arg LL_SBS_VTOR_NSEC : VTOR_NS register lock + * @arg LL_SBS_MPU_NSEC : Non-secure MPU registers lock + * @arg LL_SBS_LOCK_ALL_NSEC : VTOR_NS and Non-secure MPU registers lock + */ +__STATIC_INLINE uint32_t LL_SBS_GetNonSecureLock(void) +{ + return (uint32_t)(READ_BIT(SBS->CNSLCKR, LL_SBS_LOCK_ALL_NSEC)); +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Secure Lock of System item(s). + * @note Setting lock(s) depends on privilege mode in secure code + * Lock(s) cleared only at system reset + * @rmtoll CSLCKR LOCKSVTAIRCR LL_SBS_SecureLock\n + * CSLCKR LOCKSMPU LL_SBS_SecureLock\n + * CSLCKR LOCKSAU LL_SBS_SecureLock + * @param Item Item(s) to set lock on. + * This parameter can be a combination of the following values : + * @arg LL_SBS_VTOR_AIRCR_SEC : VTOR_S and AIRCR registers lock + * @arg LL_SBS_MPU_SEC : Secure MPU registers lock + * @arg LL_SBS_SAU : SAU registers lock + * @arg LL_SBS_LOCK_ALL_SEC : VTOR_S, AIRCR, Secure MPU and SAU registers lock + * @retval None + */ +__STATIC_INLINE void LL_SBS_SecureLock(uint32_t Item) +{ + /* Privilege secure only locks */ + SBS->CSLCKR = Item; +} + +/** + * @brief Get the secure lock state of System items. + * @note Getting lock(s) depends on privilege mode in secure code + * @rmtoll CSLCKR LOCKSVTAIRCR LL_SBS_GetSecureLock\n + * CSLCKR LOCKSMPU LL_SBS_GetSecureLock\n + * CSLCKR LOCKSAU LL_SBS_GetSecureLock + * @retval the return value is a combination of the following values : + * @arg LL_SBS_VTOR_AIRCR_SEC : VTOR_S and AIRCR registers lock + * @arg LL_SBS_MPU_SEC : Secure MPU registers lock + * @arg LL_SBS_SAU : SAU registers lock + * @arg LL_SBS_LOCK_ALL_SEC : VTOR_S, AIRCR, Secure MPU and SAU registers lock + */ +__STATIC_INLINE uint32_t LL_SBS_GetSecureLock(void) +{ + return (uint32_t)(READ_BIT(SBS->CSLCKR, LL_SBS_LOCK_ALL_SEC)); +} +#endif /* __ARM_FEATURE_CMSE && __ARM_FEATURE_CMSE == 3U */ + +/** + * @} + */ + +/** @defgroup SYSTEM_LL_SBS_EF_Secure_Management Secure Management + * @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + * @brief Configure Secure mode + * @note Only available from secure state when system implements security (TZEN=1) + * @rmtoll SECCFGR SBSSEC LL_SBS_ConfigSecure\n + * SECCFGR CLASSBSEC LL_SBS_ConfigSecure\n + * SECCFGR FPUSEC LL_SBS_ConfigSecure\n + * SECCFGR SDCE_SEC_EN LL_SBS_ConfigSecure + * @param Configuration This parameter shall be the full combination + * of the following values: + * @arg @ref LL_SBS_CLOCK_SEC or LL_SBS_CLOCK_NSEC + * @arg @ref LL_SBS_CLASSB_SEC or LL_SBS_CLASSB_NSEC + * @arg @ref LL_SBS_FPU_SEC or LL_SBS_FPU_NSEC + * @arg @ref LL_SBS_SMPS_SEC or LL_SBS_SMPS_NSEC + * @retval None + */ +__STATIC_INLINE void LL_SBS_ConfigSecure(uint32_t Configuration) +{ + WRITE_REG(SBS->SECCFGR, Configuration); +} + +/** + * @brief Get Secure mode configuration + * @note Only available when system implements security (TZEN=1) + * @rmtoll SECCFGR SBSSEC LL_SBS_ConfigSecure\n + * SECCFGR CLASSBSEC LL_SBS_ConfigSecure\n + * SECCFGR FPUSEC LL_SBS_ConfigSecure\n + * SECCFGR SDCE_SEC_EN LL_SBS_ConfigSecure + * @retval Returned value is the combination of the following values: + * @arg @ref LL_SBS_CLOCK_SEC or LL_SBS_CLOCK_NSEC + * @arg @ref LL_SBS_CLASSB_SEC or LL_SBS_CLASSB_NSEC + * @arg @ref LL_SBS_FPU_SEC or LL_SBS_FPU_NSEC + * @arg @ref LL_SBS_SMPS_SEC or LL_SBS_SMPS_NSEC + */ +__STATIC_INLINE uint32_t LL_SBS_GetConfigSecure(void) +{ + return (uint32_t)(READ_BIT(SBS->SECCFGR, LL_SBS_CLOCK_SEC | LL_SBS_CLASSB_SEC | LL_SBS_FPU_SEC | LL_SBS_SMPS_SEC)); +} + +#endif /* __ARM_FEATURE_CMSE && __ARM_FEATURE_CMSE == 3U */ + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup SYSTEM_LL_SBS_EF_COMPENSATION Compensation Cell Control + * @{ + */ + +/** + * @brief Get the compensation cell value of the GPIO PMOS transistor supplied by VDD + * @rmtoll CCVALR PCV1 LL_SBS_GetPMOSVddCompensationValue + * @retval Returned value is the PMOS compensation cell + */ +__STATIC_INLINE uint32_t LL_SBS_GetPMOSVddCompensationValue(void) +{ + return (uint32_t)(READ_BIT(SBS->CCVALR, SBS_CCVALR_APSRC1)); +} + +/** + * @brief Get the compensation cell value of the GPIO NMOS transistor supplied by VDD + * @rmtoll CCVALR NCV1 LL_SBS_GetNMOSVddCompensationValue + * @retval Returned value is the NMOS compensation cell + */ +__STATIC_INLINE uint32_t LL_SBS_GetNMOSVddCompensationValue(void) +{ + return (uint32_t)(READ_BIT(SBS->CCVALR, SBS_CCVALR_ANSRC1)); +} + +/** + * @brief Get the compensation cell value of the GPIO PMOS transistor supplied by VDDIO2 + * @rmtoll CCVALR PCV2 LL_SBS_GetPMOSVddIO2CompensationValue + * @retval Returned value is the PMOS compensation cell + */ +__STATIC_INLINE uint32_t LL_SBS_GetPMOSVddIO2CompensationValue(void) +{ + return (uint32_t)(READ_BIT(SBS->CCVALR, SBS_CCVALR_APSRC2)); +} + +/** + * @brief Get the compensation cell value of the GPIO NMOS transistor supplied by VDDIO2 + * @rmtoll CCVALR NCV2 LL_SBS_GetNMOSVddIO2CompensationValue + * @retval Returned value is the NMOS compensation cell + */ +__STATIC_INLINE uint32_t LL_SBS_GetNMOSVddIO2CompensationValue(void) +{ + return (uint32_t)(READ_BIT(SBS->CCVALR, SBS_CCVALR_ANSRC2)); +} + +/** + * @brief Set the compensation cell code of the GPIO PMOS transistor supplied by VDD + * @rmtoll CCSWCR PCC1 LL_SBS_SetPMOSVddCompensationCode + * @param PMOSCode PMOS compensation code + * This code is applied to the PMOS compensation cell when the CS1 bit of the + * SBS_CCCSR is set + * @retval None + */ +__STATIC_INLINE void LL_SBS_SetPMOSVddCompensationCode(uint32_t PMOSCode) +{ + MODIFY_REG(SBS->CCSWCR, SBS_CCSWCR_SW_APSRC1, PMOSCode << SBS_CCSWCR_SW_APSRC1_Pos); +} + +/** + * @brief Get the compensation cell code of the GPIO PMOS transistor supplied by VDD + * @rmtoll CCSWCR PCC1 LL_SBS_GetPMOSVddCompensationCode + * @retval Returned value is the PMOS compensation cell + */ +__STATIC_INLINE uint32_t LL_SBS_GetPMOSVddCompensationCode(void) +{ + return (uint32_t)(READ_BIT(SBS->CCSWCR, SBS_CCSWCR_SW_APSRC1)); +} + +/** + * @brief Set the compensation cell code of the GPIO PMOS transistor supplied by VDDIO + * @rmtoll CCSWCR PCC2 LL_SBS_SetPMOSVddIOCompensationCode + * @param PMOSCode PMOS compensation code + * This code is applied to the PMOS compensation cell when the CS2 bit of the + * SBS_CCCSR is set + * @retval None + */ +__STATIC_INLINE void LL_SBS_SetPMOSVddIOCompensationCode(uint32_t PMOSCode) +{ + MODIFY_REG(SBS->CCSWCR, SBS_CCSWCR_SW_APSRC2, PMOSCode << SBS_CCSWCR_SW_APSRC2_Pos); +} + + +/** + * @brief Get the compensation cell code of the GPIO PMOS transistor supplied by VDDIO + * @rmtoll CCSWCR PCC2 LL_SBS_GetPMOSVddIOCompensationCode + * @retval Returned value is the PMOS compensation + */ +__STATIC_INLINE uint32_t LL_SBS_GetPMOSVddIOCompensationCode(void) +{ + return (uint32_t)(READ_BIT(SBS->CCSWCR, SBS_CCSWCR_SW_APSRC2)); +} + +/** + * @brief Set the compensation cell code of the GPIO NMOS transistor supplied by VDD + * @rmtoll CCSWCR PCC2 LL_SBS_SetNMOSVddCompensationCode + * @param NMOSCode NMOS compensation code + * This code is applied to the NMOS compensation cell when the CS2 bit of the + * SBS_CCCSR is set + * @retval None + */ +__STATIC_INLINE void LL_SBS_SetNMOSVddCompensationCode(uint32_t NMOSCode) +{ + MODIFY_REG(SBS->CCSWCR, SBS_CCSWCR_SW_ANSRC1, NMOSCode << SBS_CCSWCR_SW_ANSRC1_Pos); +} + +/** + * @brief Get the compensation cell code of the GPIO NMOS transistor supplied by VDD + * @rmtoll CCSWCR NCC1 LL_SBS_GetNMOSVddCompensationCode + * @retval Returned value is the Vdd compensation cell code for NMOS transistors + */ +__STATIC_INLINE uint32_t LL_SBS_GetNMOSVddCompensationCode(void) +{ + return (uint32_t)(READ_BIT(SBS->CCSWCR, SBS_CCSWCR_SW_ANSRC1)); +} + +/** + * @brief Set the compensation cell code of the GPIO NMOS transistor supplied by VDDIO + * @rmtoll CCSWCR NCC2 LL_SBS_SetNMOSVddIOCompensationCode + * @param NMOSCode NMOS compensation cell code + * This code is applied to the NMOS compensation cell when the CS2 bit of the + * SBS_CCCSR is set + * @retval None + */ +__STATIC_INLINE void LL_SBS_SetNMOSVddIOCompensationCode(uint32_t NMOSCode) +{ + MODIFY_REG(SBS->CCSWCR, SBS_CCSWCR_SW_ANSRC2, NMOSCode << SBS_CCSWCR_SW_ANSRC2_Pos); +} + + +/** + * @brief Get the compensation cell code of the GPIO NMOS transistor supplied by VDDIO + * @rmtoll CCSWCR NCC2 LL_SBS_GetNMOSVddIOCompensationCode + * @retval Returned value is the NMOS compensation cell code + */ +__STATIC_INLINE uint32_t LL_SBS_GetNMOSVddIOCompensationCode(void) +{ + return (uint32_t)(READ_BIT(SBS->CCSWCR, SBS_CCSWCR_SW_ANSRC2)); +} + +/** + * @brief Enable the Compensation Cell of GPIO supplied by VDD + * @rmtoll CCCSR EN1 LL_SBS_EnableVddCompensationCell + * @note The vdd compensation cell can be used only when the device supply + * voltage ranges from 1.71 to 3.6 V + * @retval None + */ +__STATIC_INLINE void LL_SBS_EnableVddCompensationCell(void) +{ + SET_BIT(SBS->CCCSR, SBS_CCCSR_EN1); +} + +/** + * @brief Enable the Compensation Cell of GPIO supplied by VDDIO + * @rmtoll CCCSR EN2 LL_SBS_EnableVddIOCompensationCell + * @note The Vdd I/O compensation cell can be used only when the device supply + * voltage ranges from 1.08 to 3.6 V + * @retval None + */ +__STATIC_INLINE void LL_SBS_EnableVddIOCompensationCell(void) +{ + SET_BIT(SBS->CCCSR, SBS_CCCSR_EN2); +} + +/** + * @brief Disable the Compensation Cell of GPIO supplied by VDD + * @rmtoll CCCSR EN1 LL_SBS_DisableVddCompensationCell + * @note The Vdd compensation cell can be used only when the device supply + * voltage ranges from 1.71 to 3.6 V + * @retval None + */ +__STATIC_INLINE void LL_SBS_DisableVddCompensationCell(void) +{ + CLEAR_BIT(SBS->CCCSR, SBS_CCCSR_EN1); +} + +/** + * @brief Disable the Compensation Cell of GPIO supplied by VDDIO + * @rmtoll CCCSR EN2 LL_SBS_DisableVddIOCompensationCell + * @note The Vdd I/O compensation cell can be used only when the device supply + * voltage ranges from 1.08 to 3.6 V + * @retval None + */ +__STATIC_INLINE void LL_SBS_DisableVddIOCompensationCell(void) +{ + CLEAR_BIT(SBS->CCCSR, SBS_CCCSR_EN2); +} + +/** + * @brief Check if the Compensation Cell of GPIO supplied by VDD is enable + * @rmtoll CCCSR EN1 LL_SBS_IsEnabled_VddCompensationCell + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SBS_IsEnabled_VddCompensationCell(void) +{ + return ((READ_BIT(SBS->CCCSR, SBS_CCCSR_EN1) == SBS_CCCSR_EN1) ? 1UL : 0UL); +} + +/** + * @brief Check if the Compensation Cell of GPIO supplied by VDDIO is enable + * @rmtoll CCCSR EN2 LL_SBS_IsEnabled_VddIOCompensationCell + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SBS_IsEnabled_VddIOCompensationCell(void) +{ + return ((READ_BIT(SBS->CCCSR, SBS_CCCSR_EN2) == SBS_CCCSR_EN2) ? 1UL : 0UL); +} + +/** + * @brief Get Compensation Cell ready Flag of GPIO supplied by VDD + * @rmtoll CCCSR RDY1 LL_SBS_IsActiveFlag_VddCMPCR + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SBS_IsActiveFlag_VddCMPCR(void) +{ + return ((READ_BIT(SBS->CCCSR, SBS_CCCSR_RDY1) == (SBS_CCCSR_RDY1)) ? 1UL : 0UL); +} + +/** + * @brief Get Compensation Cell ready Flag of GPIO supplied by VDDIO + * @rmtoll CCCSR RDY1 LL_SBS_IsActiveFlag_VddIOCMPCR + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_SBS_IsActiveFlag_VddIOCMPCR(void) +{ + return ((READ_BIT(SBS->CCCSR, SBS_CCCSR_RDY2) == (SBS_CCCSR_RDY2)) ? 1UL : 0UL); +} + + +/** + * @brief Set the compensation cell code selection of GPIO supplied by VDD + * @rmtoll CCCSR CS1 LL_SBS_SetVddCellCompensationCode + * @param CompCode: Selects the code to be applied for the Vdd compensation cell + * This parameter can be one of the following values: + * @arg LL_SBS_VDD_CELL_CODE : Select Code from the cell (available in the SBS_CCVALR) + * @arg LL_SBS_VDD_REGISTER_CODE: Select Code from the SBS compensation cell code register (SBS_CCSWCR) + * @retval None + */ +__STATIC_INLINE void LL_SBS_SetVddCellCompensationCode(uint32_t CompCode) +{ + SET_BIT(SBS->CCCSR, CompCode); +} + +/** + * @brief Set the compensation cell code selection of GPIO supplied by VDDIO + * @rmtoll CCCSR CS2 LL_SBS_SetVddIOCellCompensationCode + * @param CompCode: Selects the code to be applied for the VddIO compensation cell + * This parameter can be one of the following values: + * @arg LL_SBS_VDDIO_CELL_CODE : Select Code from the cell (available in the SBS_CCVALR) + * @arg LL_SBS_VDDIO_REGISTER_CODE: Select Code from the SBS compensation cell code register (SBS_CCSWCR) + * @retval None + */ +__STATIC_INLINE void LL_SBS_SetVddIOCellCompensationCode(uint32_t CompCode) +{ + SET_BIT(SBS->CCCSR, CompCode); +} + +/** + * @brief Get the compensation cell code selection of GPIO supplied by VDD + * @rmtoll CCCSR CS1 LL_SBS_GetVddCellCompensationCode + * @retval Returned value can be one of the following values: + * @arg LL_SBS_VDD_CELL_CODE : Selected Code is from the cell (available in the SBS_CCVALR) + * @arg LL_SBS_VDD_REGISTER_CODE: Selected Code is from the SBS compensation cell code register (SBS_CCSWCR) + */ +__STATIC_INLINE uint32_t LL_SBS_GetVddCellCompensationCode(void) +{ + return (uint32_t)(READ_BIT(SBS->CCCSR, SBS_CCCSR_CS1)); +} + +/** + * @brief Get the compensation cell code selection of GPIO supplied by VDDIO + * @rmtoll CCCSR CS2 LL_SBS_GetVddIOCellCompensationCode + * @retval Returned value can be one of the following values: + * @arg LL_SBS_VDDIO_CELL_CODE : Selected Code is from the cell (available in the SBS_CCVALR) + * @arg LL_SBS_VDDIO_REGISTER_CODE: Selected Code is from the SBS compensation cell code register (SBS_CCSWCR) + */ +__STATIC_INLINE uint32_t LL_SBS_GetVddIOCellCompensationCode(void) +{ + return (uint32_t)(READ_BIT(SBS->CCCSR, SBS_CCCSR_CS2)); +} + +/** + * @} + */ + +/** @defgroup SYSTEM_LL_DBGMCU_EF DBGMCU + * @{ + */ + +/** + * @brief Return the device identifier + * @rmtoll DBGMCU_IDCODE DEV_ID LL_DBGMCU_GetDeviceID + * @retval Values between Min_Data=0x00 and Max_Data=0xFFFF (ex: device ID is 0x6415) + */ +__STATIC_INLINE uint32_t LL_DBGMCU_GetDeviceID(void) +{ + return (uint32_t)(READ_BIT(DBGMCU->IDCODE, DBGMCU_IDCODE_DEV_ID)); +} + +/** + * @brief Return the device revision identifier + * @note This field indicates the revision of the device. + * @rmtoll DBGMCU_IDCODE REV_ID LL_DBGMCU_GetRevisionID + * @retval Values between Min_Data=0x00 and Max_Data=0xFFFF + */ +__STATIC_INLINE uint32_t LL_DBGMCU_GetRevisionID(void) +{ + return (uint32_t)(READ_BIT(DBGMCU->IDCODE, DBGMCU_IDCODE_REV_ID) >> DBGMCU_IDCODE_REV_ID_Pos); +} + +/** + * @brief Enable the Debug Module during STOP mode + * @rmtoll DBGMCU_CR DBG_STOP LL_DBGMCU_EnableDBGStopMode + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_EnableDBGStopMode(void) +{ + SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP); +} + +/** + * @brief Disable the Debug Module during STOP mode + * @rmtoll DBGMCU_CR DBG_STOP LL_DBGMCU_DisableDBGStopMode + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_DisableDBGStopMode(void) +{ + CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP); +} + +/** + * @brief Enable the Debug Module during STANDBY mode + * @rmtoll DBGMCU_CR DBG_STANDBY LL_DBGMCU_EnableDBGStandbyMode + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_EnableDBGStandbyMode(void) +{ + SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY); +} + +/** + * @brief Disable the Debug Module during STANDBY mode + * @rmtoll DBGMCU_CR DBG_STANDBY LL_DBGMCU_DisableDBGStandbyMode + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_DisableDBGStandbyMode(void) +{ + CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY); +} + + +/** + * @brief Enable the Debug Clock Trace + * @rmtoll DBGMCU_CR TRACE_CLKEN LL_DBGMCU_EnableTraceClock + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_EnableTraceClock(void) +{ + SET_BIT(DBGMCU->CR, DBGMCU_CR_TRACE_CLKEN); +} + +/** + * @brief Disable the Debug Clock Trace + * @rmtoll DBGMCU_CR TRACE_CLKEN LL_DBGMCU_DisableTraceClock + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_DisableTraceClock(void) +{ + CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_TRACE_CLKEN); +} + + +/** + * @brief Check if clock trace is enabled or disabled. + * @rmtoll DBGMCU_CR_TRACE_CLKEN LL_DBGMCU_IsEnabledTraceClock + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_DBGMCU_IsEnabledTraceClock(void) +{ + return ((READ_BIT(DBGMCU->CR, DBGMCU_CR_TRACE_CLKEN) == DBGMCU_CR_TRACE_CLKEN) ? 1UL : 0UL); +} + +/** + * @brief Set Trace pin assignment control + * @rmtoll DBGMCU_CR TRACE_IOEN LL_DBGMCU_SetTracePinAssignment\n + * DBGMCU_CR TRACE_MODE LL_DBGMCU_SetTracePinAssignment + * @param PinAssignment This parameter can be one of the following values: + * @arg @ref LL_DBGMCU_TRACE_NONE + * @arg @ref LL_DBGMCU_TRACE_ASYNCH + * @arg @ref LL_DBGMCU_TRACE_SYNCH_SIZE1 + * @arg @ref LL_DBGMCU_TRACE_SYNCH_SIZE2 + * @arg @ref LL_DBGMCU_TRACE_SYNCH_SIZE4 + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_SetTracePinAssignment(uint32_t PinAssignment) +{ + MODIFY_REG(DBGMCU->CR, DBGMCU_CR_TRACE_IOEN | DBGMCU_CR_TRACE_MODE, PinAssignment); +} + +/** + * @brief Get Trace pin assignment control + * @rmtoll DBGMCU_CR TRACE_IOEN LL_DBGMCU_GetTracePinAssignment\n + * DBGMCU_CR TRACE_MODE LL_DBGMCU_GetTracePinAssignment + * @retval Returned value can be one of the following values: + * @arg @ref LL_DBGMCU_TRACE_NONE + * @arg @ref LL_DBGMCU_TRACE_ASYNCH + * @arg @ref LL_DBGMCU_TRACE_SYNCH_SIZE1 + * @arg @ref LL_DBGMCU_TRACE_SYNCH_SIZE2 + * @arg @ref LL_DBGMCU_TRACE_SYNCH_SIZE4 + */ +__STATIC_INLINE uint32_t LL_DBGMCU_GetTracePinAssignment(void) +{ + return (uint32_t)(READ_BIT(DBGMCU->CR, DBGMCU_CR_TRACE_IOEN | DBGMCU_CR_TRACE_MODE)); +} + +/** + * @brief Freeze APB1 peripherals (group1 peripherals) + * @rmtoll DBGMCU_APB1FZR1 DBG_xxxx_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM2_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM3_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM4_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM5_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM6_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM7_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM12_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM13_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM14_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_WWDG_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_IWDG_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_I2C1_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_I2C2_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_I3C1_STOP + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_APB1_GRP1_FreezePeriph(uint32_t Periphs) +{ + SET_BIT(DBGMCU->APB1FZR1, Periphs); +} + +/** + * @brief Freeze APB1 peripherals (group2 peripherals) + * @rmtoll DBGMCU_APB1FZR2 DBG_xxxx_STOP LL_DBGMCU_APB1_GRP2_FreezePeriph + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_DBGMCU_APB1_GRP2_LPTIM2_STOP + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_APB1_GRP2_FreezePeriph(uint32_t Periphs) +{ + SET_BIT(DBGMCU->APB1FZR2, Periphs); +} + +/** + * @brief Unfreeze APB1 peripherals (group1 peripherals) + * @rmtoll DBGMCU_APB1FZR1 DBG_xxxx_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM2_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM3_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM4_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM5_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM6_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM7_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM12_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM13_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM14_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_WWDG_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_IWDG_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_I2C1_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_I2C2_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_I3C1_STOP + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_APB1_GRP1_UnFreezePeriph(uint32_t Periphs) +{ + CLEAR_BIT(DBGMCU->APB1FZR1, Periphs); +} + +/** + * @brief Unfreeze APB1 peripherals (group2 peripherals) + * @rmtoll DBGMCU_APB1FZR2 DBG_xxxx_STOP LL_DBGMCU_APB1_GRP2_UnFreezePeriph + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_DBGMCU_APB1_GRP2_LPTIM2_STOP + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_APB1_GRP2_UnFreezePeriph(uint32_t Periphs) +{ + CLEAR_BIT(DBGMCU->APB1FZR2, Periphs); +} + +/** + * @brief Freeze APB2 peripherals + * @rmtoll DBGMCU_APB2FZ DBG_TIMx_STOP LL_DBGMCU_APB2_GRP1_FreezePeriph + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_DBGMCU_APB2_GRP1_TIM1_STOP + * @arg @ref LL_DBGMCU_APB2_GRP1_TIM8_STOP + * @arg @ref LL_DBGMCU_APB2_GRP1_TIM15_STOP + * @arg @ref LL_DBGMCU_APB2_GRP1_TIM16_STOP + * @arg @ref LL_DBGMCU_APB2_GRP1_TIM17_STOP + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_APB2_GRP1_FreezePeriph(uint32_t Periphs) +{ + SET_BIT(DBGMCU->APB2FZR, Periphs); +} + +/** + * @brief Unfreeze APB2 peripherals + * @rmtoll DBGMCU_APB2FZR DBG_TIMx_STOP LL_DBGMCU_APB2_GRP1_UnFreezePeriph + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_DBGMCU_APB2_GRP1_TIM1_STOP + * @arg @ref LL_DBGMCU_APB2_GRP1_TIM8_STOP + * @arg @ref LL_DBGMCU_APB2_GRP1_TIM15_STOP + * @arg @ref LL_DBGMCU_APB2_GRP1_TIM16_STOP + * @arg @ref LL_DBGMCU_APB2_GRP1_TIM17_STOP + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_APB2_GRP1_UnFreezePeriph(uint32_t Periphs) +{ + CLEAR_BIT(DBGMCU->APB2FZR, Periphs); +} + +/** + * @brief Freeze APB3 peripherals + * @rmtoll DBGMCU_APB3FZ DBG_TIMx_STOP LL_DBGMCU_APB3_GRP1_FreezePeriph + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_DBGMCU_APB3_GRP1_I2C3_STOP + * @arg @ref LL_DBGMCU_APB3_GRP1_I2C4_STOP + * @arg @ref LL_DBGMCU_APB3_GRP1_LPTIM1_STOP + * @arg @ref LL_DBGMCU_APB3_GRP1_RTC_STOP + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_APB3_GRP1_FreezePeriph(uint32_t Periphs) +{ + SET_BIT(DBGMCU->APB3FZR, Periphs); +} + +/** + * @brief Unfreeze APB3 peripherals + * @rmtoll DBGMCU_APB3FZR DBG_TIMx_STOP LL_DBGMCU_APB3_GRP1_UnFreezePeriph + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_DBGMCU_APB3_GRP1_I2C3_STOP + * @arg @ref LL_DBGMCU_APB3_GRP1_I2C4_STOP + * @arg @ref LL_DBGMCU_APB3_GRP1_LPTIM1_STOP + * @arg @ref LL_DBGMCU_APB3_GRP1_RTC_STOP + * @retval None + */ +__STATIC_INLINE void LL_DBGMCU_APB3_GRP1_UnFreezePeriph(uint32_t Periphs) +{ + CLEAR_BIT(DBGMCU->APB3FZR, Periphs); +} + +/** + * @} + */ + +#if defined(VREFBUF) +/** @defgroup SYSTEM_LL_VREFBUF_EF VREFBUF + * @{ + */ + +/** + * @brief Enable Internal voltage reference + * @rmtoll VREFBUF_CSR ENVR LL_VREFBUF_Enable + * @retval None + */ +__STATIC_INLINE void LL_VREFBUF_Enable(void) +{ + SET_BIT(VREFBUF->CSR, VREFBUF_CSR_ENVR); +} + +/** + * @brief Disable Internal voltage reference + * @rmtoll VREFBUF_CSR ENVR LL_VREFBUF_Disable + * @retval None + */ +__STATIC_INLINE void LL_VREFBUF_Disable(void) +{ + CLEAR_BIT(VREFBUF->CSR, VREFBUF_CSR_ENVR); +} + +/** + * @brief Enable high impedance (VREF+pin is high impedance) + * @rmtoll VREFBUF_CSR HIZ LL_VREFBUF_EnableHIZ + * @retval None + */ +__STATIC_INLINE void LL_VREFBUF_EnableHIZ(void) +{ + SET_BIT(VREFBUF->CSR, VREFBUF_CSR_HIZ); +} + +/** + * @brief Disable high impedance (VREF+pin is internally connected to the voltage reference buffer output) + * @rmtoll VREFBUF_CSR HIZ LL_VREFBUF_DisableHIZ + * @retval None + */ +__STATIC_INLINE void LL_VREFBUF_DisableHIZ(void) +{ + CLEAR_BIT(VREFBUF->CSR, VREFBUF_CSR_HIZ); +} + +/** + * @brief Set the Voltage reference scale + * @rmtoll VREFBUF_CSR VRS LL_VREFBUF_SetVoltageScaling + * @param Scale This parameter can be one of the following values: + * @arg @ref LL_VREFBUF_VOLTAGE_SCALE0 + * @arg @ref LL_VREFBUF_VOLTAGE_SCALE1 + * @arg @ref LL_VREFBUF_VOLTAGE_SCALE2 + * @arg @ref LL_VREFBUF_VOLTAGE_SCALE3 + * @retval None + */ +__STATIC_INLINE void LL_VREFBUF_SetVoltageScaling(uint32_t Scale) +{ + MODIFY_REG(VREFBUF->CSR, VREFBUF_CSR_VRS, Scale); +} + +/** + * @brief Get the Voltage reference scale + * @rmtoll VREFBUF_CSR VRS LL_VREFBUF_GetVoltageScaling + * @retval Returned value can be one of the following values: + * @arg @ref LL_VREFBUF_VOLTAGE_SCALE0 + * @arg @ref LL_VREFBUF_VOLTAGE_SCALE1 + * @arg @ref LL_VREFBUF_VOLTAGE_SCALE2 + * @arg @ref LL_VREFBUF_VOLTAGE_SCALE3 + */ +__STATIC_INLINE uint32_t LL_VREFBUF_GetVoltageScaling(void) +{ + return (uint32_t)(READ_BIT(VREFBUF->CSR, VREFBUF_CSR_VRS)); +} + +/** + * @brief Check if Voltage reference buffer is ready + * @rmtoll VREFBUF_CSR VRR LL_VREFBUF_IsVREFReady + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_VREFBUF_IsVREFReady(void) +{ + return ((READ_BIT(VREFBUF->CSR, VREFBUF_CSR_VRR) == VREFBUF_CSR_VRR) ? 1UL : 0UL); +} + +/** + * @brief Get the trimming code for VREFBUF calibration + * @rmtoll VREFBUF_CCR TRIM LL_VREFBUF_GetTrimming + * @retval Between 0 and 0x3F + */ +__STATIC_INLINE uint32_t LL_VREFBUF_GetTrimming(void) +{ + return (uint32_t)(READ_BIT(VREFBUF->CCR, VREFBUF_CCR_TRIM)); +} + +/** + * @brief Set the trimming code for VREFBUF calibration (Tune the internal reference buffer voltage) + * @rmtoll VREFBUF_CCR TRIM LL_VREFBUF_SetTrimming + * @param Value Between 0 and 0x3F + * @retval None + */ +__STATIC_INLINE void LL_VREFBUF_SetTrimming(uint32_t Value) +{ + WRITE_REG(VREFBUF->CCR, Value); +} + +/** + * @} + */ +#endif /* VREFBUF */ + +/** @defgroup SYSTEM_LL_FLASH_EF FLASH + * @{ + */ +/** + * @brief Set FLASH Latency + * @rmtoll FLASH_ACR LATENCY LL_FLASH_SetLatency + * @param Latency This parameter can be one of the following values: + * @arg @ref LL_FLASH_LATENCY_0 + * @arg @ref LL_FLASH_LATENCY_1 + * @arg @ref LL_FLASH_LATENCY_2 + * @arg @ref LL_FLASH_LATENCY_3 + * @arg @ref LL_FLASH_LATENCY_4 + * @arg @ref LL_FLASH_LATENCY_5 + * @arg @ref LL_FLASH_LATENCY_6 + * @arg @ref LL_FLASH_LATENCY_7 + * @arg @ref LL_FLASH_LATENCY_8 + * @arg @ref LL_FLASH_LATENCY_9 + * @arg @ref LL_FLASH_LATENCY_10 + * @arg @ref LL_FLASH_LATENCY_11 + * @arg @ref LL_FLASH_LATENCY_12 + * @arg @ref LL_FLASH_LATENCY_13 + * @arg @ref LL_FLASH_LATENCY_14 + * @arg @ref LL_FLASH_LATENCY_15 + * @retval None + */ +__STATIC_INLINE void LL_FLASH_SetLatency(uint32_t Latency) +{ + MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, Latency); +} + +/** + * @brief Get FLASH Latency + * @rmtoll FLASH_ACR LATENCY LL_FLASH_GetLatency + * @retval Returned value can be one of the following values: + * @arg @ref LL_FLASH_LATENCY_0 + * @arg @ref LL_FLASH_LATENCY_1 + * @arg @ref LL_FLASH_LATENCY_2 + * @arg @ref LL_FLASH_LATENCY_3 + * @arg @ref LL_FLASH_LATENCY_4 + * @arg @ref LL_FLASH_LATENCY_5 + * @arg @ref LL_FLASH_LATENCY_6 + * @arg @ref LL_FLASH_LATENCY_7 + * @arg @ref LL_FLASH_LATENCY_8 + * @arg @ref LL_FLASH_LATENCY_9 + * @arg @ref LL_FLASH_LATENCY_10 + * @arg @ref LL_FLASH_LATENCY_11 + * @arg @ref LL_FLASH_LATENCY_12 + * @arg @ref LL_FLASH_LATENCY_13 + * @arg @ref LL_FLASH_LATENCY_14 + * @arg @ref LL_FLASH_LATENCY_15 + */ +__STATIC_INLINE uint32_t LL_FLASH_GetLatency(void) +{ + return (uint32_t)(READ_BIT(FLASH->ACR, FLASH_ACR_LATENCY)); +} + +/** + * @} + */ + + +/** @defgroup SYSTEM_LL_SBS_EF_ERASE_MEMORY_STATUS_CLEAR Erase Memory Status + * @{ + */ + +/** + * @brief Clear Status of End of Erase for ICACHE and PKA RAMs + * @rmtoll MESR IPMEE LL_SBS_ClearEraseEndStatus + * @retval None + */ +__STATIC_INLINE void LL_SBS_ClearEraseEndStatus(void) +{ + WRITE_REG(SBS->MESR, SBS_MESR_IPMEE); +} + +/** + * @brief Get Status of End of Erase for ICACHE and PKA RAMs + * @rmtoll MESR IPMEE LL_SBS_GetEraseEndStatus + * @retval Returned value can be one of the following values: + * @arg LL_SBS_MEMORIES_ERASE_IPMEE_ON_GOING : Erase of ICACHE and PKA RAMs on going or flag cleared by SW + * @arg LL_SBS_MEMORIES_ERASE_IPMEE_ENDED: Erase of ICACHE and PKA RAMs ended + */ +__STATIC_INLINE uint32_t LL_SBS_GetEraseEndStatus(void) +{ + return (uint32_t)(READ_BIT(SBS->MESR, SBS_MESR_IPMEE)); +} + +/** + * @brief Clear Status of End of Erase after Power-on Reset for SRAM2, BKPRAM, ICACHE, DCACHE and PKA RAMs + * @rmtoll MESR MCLR LL_SBS_ClearEraseAfterResetStatus + * @retval None + */ +__STATIC_INLINE void LL_SBS_ClearEraseAfterResetStatus(void) +{ + WRITE_REG(SBS->MESR, SBS_MESR_MCLR); +} + +/** + * @brief Get Status of End of Erase after Power-on Reset for SRAM2, BKPRAM, ICACHE, DCACHE and PKA RAMs + * @rmtoll MESR MCLR LL_SBS_GetEraseAfterResetStatus + * @retval Returned value can be one of the following values: + * @arg LL_SBS_MEMORIES_ERASE_MCLR_ON_GOING : Erase of memories on going or flag cleared by SW + * @arg LL_SBS_MEMORIES_ERASE_MCLR_ENDED: Erase of memories ended + */ +__STATIC_INLINE uint32_t LL_SBS_GetEraseAfterResetStatus(void) +{ + return (uint32_t)(READ_BIT(SBS->MESR, SBS_MESR_MCLR)); +} +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +#endif /* defined (FLASH) || defined (SBS) || defined (DBGMCU) || defined (VREFBUF) */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32h5xx_LL_SYSTEM_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_tim.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_tim.h new file mode 100644 index 0000000000..bae316791b --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_tim.h @@ -0,0 +1,6269 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_tim.h + * @author MCD Application Team + * @brief Header file of TIM LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32H5xx_LL_TIM_H +#define __STM32H5xx_LL_TIM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (TIM1) \ + || defined (TIM2) \ + || defined (TIM3) \ + || defined (TIM4) \ + || defined (TIM5) \ + || defined (TIM6) \ + || defined (TIM7) \ + || defined (TIM8) \ + || defined (TIM12) \ + || defined (TIM13) \ + || defined (TIM14) \ + || defined (TIM15) \ + || defined (TIM16) \ + || defined (TIM17) + +/** @defgroup TIM_LL TIM + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/** @defgroup TIM_LL_Private_Variables TIM Private Variables + * @{ + */ +static const uint8_t OFFSET_TAB_CCMRx[] = +{ + 0x00U, /* 0: TIMx_CH1 */ + 0x00U, /* 1: TIMx_CH1N */ + 0x00U, /* 2: TIMx_CH2 */ + 0x00U, /* 3: TIMx_CH2N */ + 0x04U, /* 4: TIMx_CH3 */ + 0x04U, /* 5: TIMx_CH3N */ + 0x04U, /* 6: TIMx_CH4 */ + 0x04U, /* 7: TIMx_CH4N */ + 0x38U, /* 8: TIMx_CH5 */ + 0x38U /* 9: TIMx_CH6 */ + +}; + +static const uint8_t SHIFT_TAB_OCxx[] = +{ + 0U, /* 0: OC1M, OC1FE, OC1PE */ + 0U, /* 1: - NA */ + 8U, /* 2: OC2M, OC2FE, OC2PE */ + 0U, /* 3: - NA */ + 0U, /* 4: OC3M, OC3FE, OC3PE */ + 0U, /* 5: - NA */ + 8U, /* 6: OC4M, OC4FE, OC4PE */ + 0U, /* 7: - NA */ + 0U, /* 8: OC5M, OC5FE, OC5PE */ + 8U /* 9: OC6M, OC6FE, OC6PE */ +}; + +static const uint8_t SHIFT_TAB_ICxx[] = +{ + 0U, /* 0: CC1S, IC1PSC, IC1F */ + 0U, /* 1: - NA */ + 8U, /* 2: CC2S, IC2PSC, IC2F */ + 0U, /* 3: - NA */ + 0U, /* 4: CC3S, IC3PSC, IC3F */ + 0U, /* 5: - NA */ + 8U, /* 6: CC4S, IC4PSC, IC4F */ + 0U, /* 7: - NA */ + 0U, /* 8: - NA */ + 0U /* 9: - NA */ +}; + +static const uint8_t SHIFT_TAB_CCxP[] = +{ + 0U, /* 0: CC1P */ + 2U, /* 1: CC1NP */ + 4U, /* 2: CC2P */ + 6U, /* 3: CC2NP */ + 8U, /* 4: CC3P */ + 10U, /* 5: CC3NP */ + 12U, /* 6: CC4P */ + 14U, /* 7: CC4NP */ + 16U, /* 8: CC5P */ + 20U /* 9: CC6P */ +}; + +static const uint8_t SHIFT_TAB_OISx[] = +{ + 0U, /* 0: OIS1 */ + 1U, /* 1: OIS1N */ + 2U, /* 2: OIS2 */ + 3U, /* 3: OIS2N */ + 4U, /* 4: OIS3 */ + 5U, /* 5: OIS3N */ + 6U, /* 6: OIS4 */ + 7U, /* 7: OIS4N */ + 8U, /* 8: OIS5 */ + 10U /* 9: OIS6 */ +}; +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup TIM_LL_Private_Constants TIM Private Constants + * @{ + */ + +/* Defines used for the bit position in the register and perform offsets */ +#define TIM_POSITION_BRK_SOURCE (POSITION_VAL(Source) & 0x1FUL) + +/* Generic bit definitions for TIMx_AF1 register */ +#define TIMx_AF1_BKINP TIM1_AF1_BKINP /*!< BRK BKIN input polarity */ +#define TIMx_AF1_ETRSEL TIM1_AF1_ETRSEL /*!< TIMx ETR source selection */ + + +/* Mask used to set the TDG[x:0] of the DTG bits of the TIMx_BDTR register */ +#define DT_DELAY_1 ((uint8_t)0x7F) +#define DT_DELAY_2 ((uint8_t)0x3F) +#define DT_DELAY_3 ((uint8_t)0x1F) +#define DT_DELAY_4 ((uint8_t)0x1F) + +/* Mask used to set the DTG[7:5] bits of the DTG bits of the TIMx_BDTR register */ +#define DT_RANGE_1 ((uint8_t)0x00) +#define DT_RANGE_2 ((uint8_t)0x80) +#define DT_RANGE_3 ((uint8_t)0xC0) +#define DT_RANGE_4 ((uint8_t)0xE0) + +/** Legacy definitions for compatibility purpose +@cond 0 + */ +/** +@endcond + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup TIM_LL_Private_Macros TIM Private Macros + * @{ + */ +/** @brief Convert channel id into channel index. + * @param __CHANNEL__ This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH4N + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @retval none + */ +#define TIM_GET_CHANNEL_INDEX( __CHANNEL__) \ + (((__CHANNEL__) == LL_TIM_CHANNEL_CH1) ? 0U :\ + ((__CHANNEL__) == LL_TIM_CHANNEL_CH1N) ? 1U :\ + ((__CHANNEL__) == LL_TIM_CHANNEL_CH2) ? 2U :\ + ((__CHANNEL__) == LL_TIM_CHANNEL_CH2N) ? 3U :\ + ((__CHANNEL__) == LL_TIM_CHANNEL_CH3) ? 4U :\ + ((__CHANNEL__) == LL_TIM_CHANNEL_CH3N) ? 5U :\ + ((__CHANNEL__) == LL_TIM_CHANNEL_CH4) ? 6U :\ + ((__CHANNEL__) == LL_TIM_CHANNEL_CH4N) ? 7U :\ + ((__CHANNEL__) == LL_TIM_CHANNEL_CH5) ? 8U : 9U) + +/** @brief Calculate the deadtime sampling period(in ps). + * @param __TIMCLK__ timer input clock frequency (in Hz). + * @param __CKD__ This parameter can be one of the following values: + * @arg @ref LL_TIM_CLOCKDIVISION_DIV1 + * @arg @ref LL_TIM_CLOCKDIVISION_DIV2 + * @arg @ref LL_TIM_CLOCKDIVISION_DIV4 + * @retval none + */ +#define TIM_CALC_DTS(__TIMCLK__, __CKD__) \ + (((__CKD__) == LL_TIM_CLOCKDIVISION_DIV1) ? ((uint64_t)1000000000000U/(__TIMCLK__)) : \ + ((__CKD__) == LL_TIM_CLOCKDIVISION_DIV2) ? ((uint64_t)1000000000000U/((__TIMCLK__) >> 1U)) : \ + ((uint64_t)1000000000000U/((__TIMCLK__) >> 2U))) +/** + * @} + */ + + +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup TIM_LL_ES_INIT TIM Exported Init structure + * @{ + */ + +/** + * @brief TIM Time Base configuration structure definition. + */ +typedef struct +{ + uint16_t Prescaler; /*!< Specifies the prescaler value used to divide the TIM clock. + This parameter can be a number between Min_Data=0x0000 and Max_Data=0xFFFF. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_SetPrescaler().*/ + + uint32_t CounterMode; /*!< Specifies the counter mode. + This parameter can be a value of @ref TIM_LL_EC_COUNTERMODE. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_SetCounterMode().*/ + + uint32_t Autoreload; /*!< Specifies the auto reload value to be loaded into the active + Auto-Reload Register at the next update event. + This parameter must be a number between Min_Data=0x0000 and Max_Data=0xFFFF. + Some timer instances may support 32 bits counters. In that case this parameter must + be a number between 0x0000 and 0xFFFFFFFF. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_SetAutoReload().*/ + + uint32_t ClockDivision; /*!< Specifies the clock division. + This parameter can be a value of @ref TIM_LL_EC_CLOCKDIVISION. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_SetClockDivision().*/ + + uint32_t RepetitionCounter; /*!< Specifies the repetition counter value. Each time the RCR downcounter + reaches zero, an update event is generated and counting restarts + from the RCR value (N). + This means in PWM mode that (N+1) corresponds to: + - the number of PWM periods in edge-aligned mode + - the number of half PWM period in center-aligned mode + GP timers: this parameter must be a number between Min_Data = 0x00 and + Max_Data = 0xFF. + Advanced timers: this parameter must be a number between Min_Data = 0x0000 and + Max_Data = 0xFFFF. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_SetRepetitionCounter().*/ +} LL_TIM_InitTypeDef; + +/** + * @brief TIM Output Compare configuration structure definition. + */ +typedef struct +{ + uint32_t OCMode; /*!< Specifies the output mode. + This parameter can be a value of @ref TIM_LL_EC_OCMODE. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_OC_SetMode().*/ + + uint32_t OCState; /*!< Specifies the TIM Output Compare state. + This parameter can be a value of @ref TIM_LL_EC_OCSTATE. + + This feature can be modified afterwards using unitary functions + @ref LL_TIM_CC_EnableChannel() or @ref LL_TIM_CC_DisableChannel().*/ + + uint32_t OCNState; /*!< Specifies the TIM complementary Output Compare state. + This parameter can be a value of @ref TIM_LL_EC_OCSTATE. + + This feature can be modified afterwards using unitary functions + @ref LL_TIM_CC_EnableChannel() or @ref LL_TIM_CC_DisableChannel().*/ + + uint32_t CompareValue; /*!< Specifies the Compare value to be loaded into the Capture Compare Register. + This parameter can be a number between Min_Data=0x0000 and Max_Data=0xFFFF. + + This feature can be modified afterwards using unitary function + LL_TIM_OC_SetCompareCHx (x=1..6).*/ + + uint32_t OCPolarity; /*!< Specifies the output polarity. + This parameter can be a value of @ref TIM_LL_EC_OCPOLARITY. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_OC_SetPolarity().*/ + + uint32_t OCNPolarity; /*!< Specifies the complementary output polarity. + This parameter can be a value of @ref TIM_LL_EC_OCPOLARITY. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_OC_SetPolarity().*/ + + + uint32_t OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. + This parameter can be a value of @ref TIM_LL_EC_OCIDLESTATE. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_OC_SetIdleState().*/ + + uint32_t OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. + This parameter can be a value of @ref TIM_LL_EC_OCIDLESTATE. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_OC_SetIdleState().*/ +} LL_TIM_OC_InitTypeDef; + +/** + * @brief TIM Input Capture configuration structure definition. + */ + +typedef struct +{ + + uint32_t ICPolarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_LL_EC_IC_POLARITY. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetPolarity().*/ + + uint32_t ICActiveInput; /*!< Specifies the input. + This parameter can be a value of @ref TIM_LL_EC_ACTIVEINPUT. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetActiveInput().*/ + + uint32_t ICPrescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref TIM_LL_EC_ICPSC. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetPrescaler().*/ + + uint32_t ICFilter; /*!< Specifies the input capture filter. + This parameter can be a value of @ref TIM_LL_EC_IC_FILTER. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetFilter().*/ +} LL_TIM_IC_InitTypeDef; + + +/** + * @brief TIM Encoder interface configuration structure definition. + */ +typedef struct +{ + uint32_t EncoderMode; /*!< Specifies the encoder resolution (x2 or x4). + This parameter can be a value of @ref TIM_LL_EC_ENCODERMODE. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_SetEncoderMode().*/ + + uint32_t IC1Polarity; /*!< Specifies the active edge of TI1 input. + This parameter can be a value of @ref TIM_LL_EC_IC_POLARITY. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetPolarity().*/ + + uint32_t IC1ActiveInput; /*!< Specifies the TI1 input source + This parameter can be a value of @ref TIM_LL_EC_ACTIVEINPUT. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetActiveInput().*/ + + uint32_t IC1Prescaler; /*!< Specifies the TI1 input prescaler value. + This parameter can be a value of @ref TIM_LL_EC_ICPSC. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetPrescaler().*/ + + uint32_t IC1Filter; /*!< Specifies the TI1 input filter. + This parameter can be a value of @ref TIM_LL_EC_IC_FILTER. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetFilter().*/ + + uint32_t IC2Polarity; /*!< Specifies the active edge of TI2 input. + This parameter can be a value of @ref TIM_LL_EC_IC_POLARITY. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetPolarity().*/ + + uint32_t IC2ActiveInput; /*!< Specifies the TI2 input source + This parameter can be a value of @ref TIM_LL_EC_ACTIVEINPUT. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetActiveInput().*/ + + uint32_t IC2Prescaler; /*!< Specifies the TI2 input prescaler value. + This parameter can be a value of @ref TIM_LL_EC_ICPSC. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetPrescaler().*/ + + uint32_t IC2Filter; /*!< Specifies the TI2 input filter. + This parameter can be a value of @ref TIM_LL_EC_IC_FILTER. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetFilter().*/ + +} LL_TIM_ENCODER_InitTypeDef; + +/** + * @brief TIM Hall sensor interface configuration structure definition. + */ +typedef struct +{ + + uint32_t IC1Polarity; /*!< Specifies the active edge of TI1 input. + This parameter can be a value of @ref TIM_LL_EC_IC_POLARITY. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetPolarity().*/ + + uint32_t IC1Prescaler; /*!< Specifies the TI1 input prescaler value. + Prescaler must be set to get a maximum counter period longer than the + time interval between 2 consecutive changes on the Hall inputs. + This parameter can be a value of @ref TIM_LL_EC_ICPSC. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetPrescaler().*/ + + uint32_t IC1Filter; /*!< Specifies the TI1 input filter. + This parameter can be a value of + @ref TIM_LL_EC_IC_FILTER. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetFilter().*/ + + uint32_t CommutationDelay; /*!< Specifies the compare value to be loaded into the Capture Compare Register. + A positive pulse (TRGO event) is generated with a programmable delay every time + a change occurs on the Hall inputs. + This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_OC_SetCompareCH2().*/ +} LL_TIM_HALLSENSOR_InitTypeDef; + +/** + * @brief BDTR (Break and Dead Time) structure definition + */ +typedef struct +{ + uint32_t OSSRState; /*!< Specifies the Off-State selection used in Run mode. + This parameter can be a value of @ref TIM_LL_EC_OSSR + + This feature can be modified afterwards using unitary function + @ref LL_TIM_SetOffStates() + + @note This bit-field cannot be modified as long as LOCK level 2 has been + programmed. */ + + uint32_t OSSIState; /*!< Specifies the Off-State used in Idle state. + This parameter can be a value of @ref TIM_LL_EC_OSSI + + This feature can be modified afterwards using unitary function + @ref LL_TIM_SetOffStates() + + @note This bit-field cannot be modified as long as LOCK level 2 has been + programmed. */ + + uint32_t LockLevel; /*!< Specifies the LOCK level parameters. + This parameter can be a value of @ref TIM_LL_EC_LOCKLEVEL + + @note The LOCK bits can be written only once after the reset. Once the TIMx_BDTR + register has been written, their content is frozen until the next reset.*/ + + uint8_t DeadTime; /*!< Specifies the delay time between the switching-off and the + switching-on of the outputs. + This parameter can be a number between Min_Data = 0x00 and Max_Data = 0xFF. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_OC_SetDeadTime() + + @note This bit-field can not be modified as long as LOCK level 1, 2 or 3 has been + programmed. */ + + uint16_t BreakState; /*!< Specifies whether the TIM Break input is enabled or not. + This parameter can be a value of @ref TIM_LL_EC_BREAK_ENABLE + + This feature can be modified afterwards using unitary functions + @ref LL_TIM_EnableBRK() or @ref LL_TIM_DisableBRK() + + @note This bit-field can not be modified as long as LOCK level 1 has been + programmed. */ + + uint32_t BreakPolarity; /*!< Specifies the TIM Break Input pin polarity. + This parameter can be a value of @ref TIM_LL_EC_BREAK_POLARITY + + This feature can be modified afterwards using unitary function + @ref LL_TIM_ConfigBRK() + + @note This bit-field can not be modified as long as LOCK level 1 has been + programmed. */ + + uint32_t BreakFilter; /*!< Specifies the TIM Break Filter. + This parameter can be a value of @ref TIM_LL_EC_BREAK_FILTER + + This feature can be modified afterwards using unitary function + @ref LL_TIM_ConfigBRK() + + @note This bit-field can not be modified as long as LOCK level 1 has been + programmed. */ + + uint32_t BreakAFMode; /*!< Specifies the alternate function mode of the break input. + This parameter can be a value of @ref TIM_LL_EC_BREAK_AFMODE + + This feature can be modified afterwards using unitary functions + @ref LL_TIM_ConfigBRK() + + @note Bidirectional break input is only supported by advanced timers instances. + + @note This bit-field can not be modified as long as LOCK level 1 has been + programmed. */ + + uint32_t Break2State; /*!< Specifies whether the TIM Break2 input is enabled or not. + This parameter can be a value of @ref TIM_LL_EC_BREAK2_ENABLE + + This feature can be modified afterwards using unitary functions + @ref LL_TIM_EnableBRK2() or @ref LL_TIM_DisableBRK2() + + @note This bit-field can not be modified as long as LOCK level 1 has been + programmed. */ + + uint32_t Break2Polarity; /*!< Specifies the TIM Break2 Input pin polarity. + This parameter can be a value of @ref TIM_LL_EC_BREAK2_POLARITY + + This feature can be modified afterwards using unitary function + @ref LL_TIM_ConfigBRK2() + + @note This bit-field can not be modified as long as LOCK level 1 has been + programmed. */ + + uint32_t Break2Filter; /*!< Specifies the TIM Break2 Filter. + This parameter can be a value of @ref TIM_LL_EC_BREAK2_FILTER + + This feature can be modified afterwards using unitary function + @ref LL_TIM_ConfigBRK2() + + @note This bit-field can not be modified as long as LOCK level 1 has been + programmed. */ + + uint32_t Break2AFMode; /*!< Specifies the alternate function mode of the break2 input. + This parameter can be a value of @ref TIM_LL_EC_BREAK2_AFMODE + + This feature can be modified afterwards using unitary functions + @ref LL_TIM_ConfigBRK2() + + @note Bidirectional break input is only supported by advanced timers instances. + + @note This bit-field can not be modified as long as LOCK level 1 has been + programmed. */ + + uint32_t AutomaticOutput; /*!< Specifies whether the TIM Automatic Output feature is enabled or not. + This parameter can be a value of @ref TIM_LL_EC_AUTOMATICOUTPUT_ENABLE + + This feature can be modified afterwards using unitary functions + @ref LL_TIM_EnableAutomaticOutput() or @ref LL_TIM_DisableAutomaticOutput() + + @note This bit-field can not be modified as long as LOCK level 1 has been + programmed. */ +} LL_TIM_BDTR_InitTypeDef; + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup TIM_LL_Exported_Constants TIM Exported Constants + * @{ + */ + +/** @defgroup TIM_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_TIM_ReadReg function. + * @{ + */ +#define LL_TIM_SR_UIF TIM_SR_UIF /*!< Update interrupt flag */ +#define LL_TIM_SR_CC1IF TIM_SR_CC1IF /*!< Capture/compare 1 interrupt flag */ +#define LL_TIM_SR_CC2IF TIM_SR_CC2IF /*!< Capture/compare 2 interrupt flag */ +#define LL_TIM_SR_CC3IF TIM_SR_CC3IF /*!< Capture/compare 3 interrupt flag */ +#define LL_TIM_SR_CC4IF TIM_SR_CC4IF /*!< Capture/compare 4 interrupt flag */ +#define LL_TIM_SR_CC5IF TIM_SR_CC5IF /*!< Capture/compare 5 interrupt flag */ +#define LL_TIM_SR_CC6IF TIM_SR_CC6IF /*!< Capture/compare 6 interrupt flag */ +#define LL_TIM_SR_COMIF TIM_SR_COMIF /*!< COM interrupt flag */ +#define LL_TIM_SR_TIF TIM_SR_TIF /*!< Trigger interrupt flag */ +#define LL_TIM_SR_BIF TIM_SR_BIF /*!< Break interrupt flag */ +#define LL_TIM_SR_B2IF TIM_SR_B2IF /*!< Second break interrupt flag */ +#define LL_TIM_SR_CC1OF TIM_SR_CC1OF /*!< Capture/Compare 1 overcapture flag */ +#define LL_TIM_SR_CC2OF TIM_SR_CC2OF /*!< Capture/Compare 2 overcapture flag */ +#define LL_TIM_SR_CC3OF TIM_SR_CC3OF /*!< Capture/Compare 3 overcapture flag */ +#define LL_TIM_SR_CC4OF TIM_SR_CC4OF /*!< Capture/Compare 4 overcapture flag */ +#define LL_TIM_SR_SBIF TIM_SR_SBIF /*!< System Break interrupt flag */ +#define LL_TIM_SR_IDXF TIM_SR_IDXF /*!< Index interrupt flag */ +#define LL_TIM_SR_DIRF TIM_SR_DIRF /*!< Direction Change interrupt flag */ +#define LL_TIM_SR_IERRF TIM_SR_IERRF /*!< Index Error flag */ +#define LL_TIM_SR_TERRF TIM_SR_TERRF /*!< Transition Error flag */ +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup TIM_LL_EC_BREAK_ENABLE Break Enable + * @{ + */ +#define LL_TIM_BREAK_DISABLE 0x00000000U /*!< Break function disabled */ +#define LL_TIM_BREAK_ENABLE TIM_BDTR_BKE /*!< Break function enabled */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_BREAK2_ENABLE Break2 Enable + * @{ + */ +#define LL_TIM_BREAK2_DISABLE 0x00000000U /*!< Break2 function disabled */ +#define LL_TIM_BREAK2_ENABLE TIM_BDTR_BK2E /*!< Break2 function enabled */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_AUTOMATICOUTPUT_ENABLE Automatic output enable + * @{ + */ +#define LL_TIM_AUTOMATICOUTPUT_DISABLE 0x00000000U /*!< MOE can be set only by software */ +#define LL_TIM_AUTOMATICOUTPUT_ENABLE TIM_BDTR_AOE /*!< MOE can be set by software or automatically at the next update event */ +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** @defgroup TIM_LL_EC_IT IT Defines + * @brief IT defines which can be used with LL_TIM_ReadReg and LL_TIM_WriteReg functions. + * @{ + */ +#define LL_TIM_DIER_UIE TIM_DIER_UIE /*!< Update interrupt enable */ +#define LL_TIM_DIER_CC1IE TIM_DIER_CC1IE /*!< Capture/compare 1 interrupt enable */ +#define LL_TIM_DIER_CC2IE TIM_DIER_CC2IE /*!< Capture/compare 2 interrupt enable */ +#define LL_TIM_DIER_CC3IE TIM_DIER_CC3IE /*!< Capture/compare 3 interrupt enable */ +#define LL_TIM_DIER_CC4IE TIM_DIER_CC4IE /*!< Capture/compare 4 interrupt enable */ +#define LL_TIM_DIER_COMIE TIM_DIER_COMIE /*!< COM interrupt enable */ +#define LL_TIM_DIER_TIE TIM_DIER_TIE /*!< Trigger interrupt enable */ +#define LL_TIM_DIER_BIE TIM_DIER_BIE /*!< Break interrupt enable */ +#define LL_TIM_DIER_IDXIE TIM_DIER_IDXIE /*!< Index interrupt enable */ +#define LL_TIM_DIER_DIRIE TIM_DIER_DIRIE /*!< Direction Change interrupt enable */ +#define LL_TIM_DIER_IERRIE TIM_DIER_IERRIE /*!< Index Error interrupt enable */ +#define LL_TIM_DIER_TERRIE TIM_DIER_TERRIE /*!< Transition Error interrupt enable */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_UPDATESOURCE Update Source + * @{ + */ +#define LL_TIM_UPDATESOURCE_REGULAR 0x00000000U /*!< Counter overflow/underflow, Setting the UG bit or Update generation through the slave mode controller generates an update request */ +#define LL_TIM_UPDATESOURCE_COUNTER TIM_CR1_URS /*!< Only counter overflow/underflow generates an update request */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_ONEPULSEMODE One Pulse Mode + * @{ + */ +#define LL_TIM_ONEPULSEMODE_SINGLE TIM_CR1_OPM /*!< Counter stops counting at the next update event */ +#define LL_TIM_ONEPULSEMODE_REPETITIVE 0x00000000U /*!< Counter is not stopped at update event */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_COUNTERMODE Counter Mode + * @{ + */ +#define LL_TIM_COUNTERMODE_UP 0x00000000U /*!TIMx_CCRy else active.*/ +#define LL_TIM_OCMODE_PWM2 (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0) /*!TIMx_CCRy else inactive*/ +#define LL_TIM_OCMODE_RETRIG_OPM1 TIM_CCMR1_OC1M_3 /*!__REG__, (__VALUE__)) + +/** + * @brief Read a value in TIM register. + * @param __INSTANCE__ TIM Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_TIM_ReadReg(__INSTANCE__, __REG__) READ_REG((__INSTANCE__)->__REG__) +/** + * @} + */ + +/** + * @brief HELPER macro retrieving the UIFCPY flag from the counter value. + * @note ex: @ref __LL_TIM_GETFLAG_UIFCPY (@ref LL_TIM_GetCounter ()); + * @note Relevant only if UIF flag remapping has been enabled (UIF status bit is copied + * to TIMx_CNT register bit 31) + * @param __CNT__ Counter value + * @retval UIF status bit + */ +#define __LL_TIM_GETFLAG_UIFCPY(__CNT__) \ + (READ_BIT((__CNT__), TIM_CNT_UIFCPY) >> TIM_CNT_UIFCPY_Pos) + +/** + * @brief HELPER macro calculating DTG[0:7] in the TIMx_BDTR register to achieve the requested dead time duration. + * @note ex: @ref __LL_TIM_CALC_DEADTIME (80000000, @ref LL_TIM_GetClockDivision (), 120); + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __CKD__ This parameter can be one of the following values: + * @arg @ref LL_TIM_CLOCKDIVISION_DIV1 + * @arg @ref LL_TIM_CLOCKDIVISION_DIV2 + * @arg @ref LL_TIM_CLOCKDIVISION_DIV4 + * @param __DT__ deadtime duration (in ns) + * @retval DTG[0:7] + */ +#define __LL_TIM_CALC_DEADTIME(__TIMCLK__, __CKD__, __DT__) \ + ( (((uint64_t)((__DT__)*1000U)) < ((DT_DELAY_1+1U) * TIM_CALC_DTS((__TIMCLK__), (__CKD__)))) ? \ + (uint8_t)(((uint64_t)((__DT__)*1000U) / TIM_CALC_DTS((__TIMCLK__), (__CKD__))) & DT_DELAY_1) : \ + (((uint64_t)((__DT__)*1000U)) < ((64U + (DT_DELAY_2+1U)) * 2U * TIM_CALC_DTS((__TIMCLK__), (__CKD__)))) ? \ + (uint8_t)(DT_RANGE_2 | ((uint8_t)((uint8_t)((((uint64_t)((__DT__)*1000U))/ TIM_CALC_DTS((__TIMCLK__), \ + (__CKD__))) >> 1U) - (uint8_t) 64) & DT_DELAY_2)) :\ + (((uint64_t)((__DT__)*1000U)) < ((32U + (DT_DELAY_3+1U)) * 8U * TIM_CALC_DTS((__TIMCLK__), (__CKD__)))) ? \ + (uint8_t)(DT_RANGE_3 | ((uint8_t)((uint8_t)(((((uint64_t)(__DT__)*1000U))/ TIM_CALC_DTS((__TIMCLK__), \ + (__CKD__))) >> 3U) - (uint8_t) 32) & DT_DELAY_3)) :\ + (((uint64_t)((__DT__)*1000U)) < ((32U + (DT_DELAY_4+1U)) * 16U * TIM_CALC_DTS((__TIMCLK__), (__CKD__)))) ? \ + (uint8_t)(DT_RANGE_4 | ((uint8_t)((uint8_t)(((((uint64_t)(__DT__)*1000U))/ TIM_CALC_DTS((__TIMCLK__), \ + (__CKD__))) >> 4U) - (uint8_t) 32) & DT_DELAY_4)) :\ + 0U) + +/** + * @brief HELPER macro calculating the prescaler value to achieve the required counter clock frequency. + * @note ex: @ref __LL_TIM_CALC_PSC (80000000, 1000000); + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __CNTCLK__ counter clock frequency (in Hz) + * @retval Prescaler value (between Min_Data=0 and Max_Data=65535) + */ +#define __LL_TIM_CALC_PSC(__TIMCLK__, __CNTCLK__) \ + (((__TIMCLK__) >= (__CNTCLK__)) ? (uint32_t)((((__TIMCLK__) + (__CNTCLK__)/2U)/(__CNTCLK__)) - 1U) : 0U) + +/** + * @brief HELPER macro calculating the auto-reload value to achieve the required output signal frequency. + * @note ex: @ref __LL_TIM_CALC_ARR (1000000, @ref LL_TIM_GetPrescaler (), 10000); + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __PSC__ prescaler + * @param __FREQ__ output signal frequency (in Hz) + * @retval Auto-reload value (between Min_Data=0 and Max_Data=65535) + */ +#define __LL_TIM_CALC_ARR(__TIMCLK__, __PSC__, __FREQ__) \ + ((((__TIMCLK__)/((__PSC__) + 1U)) >= (__FREQ__)) ? (((__TIMCLK__)/((__FREQ__) * ((__PSC__) + 1U))) - 1U) : 0U) + +/** + * @brief HELPER macro calculating the auto-reload value, with dithering feature enabled, to achieve the required + * output signal frequency. + * @note ex: @ref __LL_TIM_CALC_ARR_DITHER (1000000, @ref LL_TIM_GetPrescaler (), 10000); + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __PSC__ prescaler + * @param __FREQ__ output signal frequency (in Hz) + * @retval Auto-reload value (between Min_Data=0 and Max_Data=65535) + */ +#define __LL_TIM_CALC_ARR_DITHER(__TIMCLK__, __PSC__, __FREQ__) \ + ((((__TIMCLK__)/((__PSC__) + 1U)) >= (__FREQ__)) ? \ + (uint32_t)((((uint64_t)(__TIMCLK__) * 16U/((__FREQ__) * ((__PSC__) + 1U))) - 16U)) : 0U) + +/** + * @brief HELPER macro calculating the compare value required to achieve the required timer output compare + * active/inactive delay. + * @note ex: @ref __LL_TIM_CALC_DELAY (1000000, @ref LL_TIM_GetPrescaler (), 10); + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __PSC__ prescaler + * @param __DELAY__ timer output compare active/inactive delay (in us) + * @retval Compare value (between Min_Data=0 and Max_Data=65535) + */ +#define __LL_TIM_CALC_DELAY(__TIMCLK__, __PSC__, __DELAY__) \ + ((uint32_t)(((uint64_t)(__TIMCLK__) * (uint64_t)(__DELAY__)) \ + / ((uint64_t)1000000U * (uint64_t)((__PSC__) + 1U)))) + +/** + * @brief HELPER macro calculating the compare value, with dithering feature enabled, to achieve the required timer + * output compare active/inactive delay. + * @note ex: @ref __LL_TIM_CALC_DELAY_DITHER (1000000, @ref LL_TIM_GetPrescaler (), 10); + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __PSC__ prescaler + * @param __DELAY__ timer output compare active/inactive delay (in us) + * @retval Compare value (between Min_Data=0 and Max_Data=65535) + */ +#define __LL_TIM_CALC_DELAY_DITHER(__TIMCLK__, __PSC__, __DELAY__) \ + ((uint32_t)(((uint64_t)(__TIMCLK__) * (uint64_t)(__DELAY__) * 16U) \ + / ((uint64_t)1000000U * (uint64_t)((__PSC__) + 1U)))) + +/** + * @brief HELPER macro calculating the auto-reload value to achieve the required pulse duration + * (when the timer operates in one pulse mode). + * @note ex: @ref __LL_TIM_CALC_PULSE (1000000, @ref LL_TIM_GetPrescaler (), 10, 20); + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __PSC__ prescaler + * @param __DELAY__ timer output compare active/inactive delay (in us) + * @param __PULSE__ pulse duration (in us) + * @retval Auto-reload value (between Min_Data=0 and Max_Data=65535) + */ +#define __LL_TIM_CALC_PULSE(__TIMCLK__, __PSC__, __DELAY__, __PULSE__) \ + ((uint32_t)(__LL_TIM_CALC_DELAY((__TIMCLK__), (__PSC__), (__PULSE__)) \ + + __LL_TIM_CALC_DELAY((__TIMCLK__), (__PSC__), (__DELAY__)))) + +/** + * @brief HELPER macro calculating the auto-reload value, with dithering feature enabled, to achieve the required + * pulse duration (when the timer operates in one pulse mode). + * @note ex: @ref __LL_TIM_CALC_PULSE_DITHER (1000000, @ref LL_TIM_GetPrescaler (), 10, 20); + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __PSC__ prescaler + * @param __DELAY__ timer output compare active/inactive delay (in us) + * @param __PULSE__ pulse duration (in us) + * @retval Auto-reload value (between Min_Data=0 and Max_Data=65535) + */ +#define __LL_TIM_CALC_PULSE_DITHER(__TIMCLK__, __PSC__, __DELAY__, __PULSE__) \ + ((uint32_t)(__LL_TIM_CALC_DELAY_DITHER((__TIMCLK__), (__PSC__), (__PULSE__)) \ + + __LL_TIM_CALC_DELAY_DITHER((__TIMCLK__), (__PSC__), (__DELAY__)))) + +/** + * @brief HELPER macro retrieving the ratio of the input capture prescaler + * @note ex: @ref __LL_TIM_GET_ICPSC_RATIO (@ref LL_TIM_IC_GetPrescaler ()); + * @param __ICPSC__ This parameter can be one of the following values: + * @arg @ref LL_TIM_ICPSC_DIV1 + * @arg @ref LL_TIM_ICPSC_DIV2 + * @arg @ref LL_TIM_ICPSC_DIV4 + * @arg @ref LL_TIM_ICPSC_DIV8 + * @retval Input capture prescaler ratio (1, 2, 4 or 8) + */ +#define __LL_TIM_GET_ICPSC_RATIO(__ICPSC__) \ + ((uint32_t)(0x01U << (((__ICPSC__) >> 16U) >> TIM_CCMR1_IC1PSC_Pos))) + + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup TIM_LL_Exported_Functions TIM Exported Functions + * @{ + */ + +/** @defgroup TIM_LL_EF_Time_Base Time Base configuration + * @{ + */ +/** + * @brief Enable timer counter. + * @rmtoll CR1 CEN LL_TIM_EnableCounter + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableCounter(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->CR1, TIM_CR1_CEN); +} + +/** + * @brief Disable timer counter. + * @rmtoll CR1 CEN LL_TIM_DisableCounter + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableCounter(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->CR1, TIM_CR1_CEN); +} + +/** + * @brief Indicates whether the timer counter is enabled. + * @rmtoll CR1 CEN LL_TIM_IsEnabledCounter + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledCounter(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->CR1, TIM_CR1_CEN) == (TIM_CR1_CEN)) ? 1UL : 0UL); +} + +/** + * @brief Enable update event generation. + * @rmtoll CR1 UDIS LL_TIM_EnableUpdateEvent + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableUpdateEvent(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->CR1, TIM_CR1_UDIS); +} + +/** + * @brief Disable update event generation. + * @rmtoll CR1 UDIS LL_TIM_DisableUpdateEvent + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableUpdateEvent(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->CR1, TIM_CR1_UDIS); +} + +/** + * @brief Indicates whether update event generation is enabled. + * @rmtoll CR1 UDIS LL_TIM_IsEnabledUpdateEvent + * @param TIMx Timer instance + * @retval Inverted state of bit (0 or 1). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledUpdateEvent(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->CR1, TIM_CR1_UDIS) == (uint32_t)RESET) ? 1UL : 0UL); +} + +/** + * @brief Set update event source + * @note Update event source set to LL_TIM_UPDATESOURCE_REGULAR: any of the following events + * generate an update interrupt or DMA request if enabled: + * - Counter overflow/underflow + * - Setting the UG bit + * - Update generation through the slave mode controller + * @note Update event source set to LL_TIM_UPDATESOURCE_COUNTER: only counter + * overflow/underflow generates an update interrupt or DMA request if enabled. + * @rmtoll CR1 URS LL_TIM_SetUpdateSource + * @param TIMx Timer instance + * @param UpdateSource This parameter can be one of the following values: + * @arg @ref LL_TIM_UPDATESOURCE_REGULAR + * @arg @ref LL_TIM_UPDATESOURCE_COUNTER + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetUpdateSource(TIM_TypeDef *TIMx, uint32_t UpdateSource) +{ + MODIFY_REG(TIMx->CR1, TIM_CR1_URS, UpdateSource); +} + +/** + * @brief Get actual event update source + * @rmtoll CR1 URS LL_TIM_GetUpdateSource + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_UPDATESOURCE_REGULAR + * @arg @ref LL_TIM_UPDATESOURCE_COUNTER + */ +__STATIC_INLINE uint32_t LL_TIM_GetUpdateSource(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_URS)); +} + +/** + * @brief Set one pulse mode (one shot v.s. repetitive). + * @rmtoll CR1 OPM LL_TIM_SetOnePulseMode + * @param TIMx Timer instance + * @param OnePulseMode This parameter can be one of the following values: + * @arg @ref LL_TIM_ONEPULSEMODE_SINGLE + * @arg @ref LL_TIM_ONEPULSEMODE_REPETITIVE + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetOnePulseMode(TIM_TypeDef *TIMx, uint32_t OnePulseMode) +{ + MODIFY_REG(TIMx->CR1, TIM_CR1_OPM, OnePulseMode); +} + +/** + * @brief Get actual one pulse mode. + * @rmtoll CR1 OPM LL_TIM_GetOnePulseMode + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_ONEPULSEMODE_SINGLE + * @arg @ref LL_TIM_ONEPULSEMODE_REPETITIVE + */ +__STATIC_INLINE uint32_t LL_TIM_GetOnePulseMode(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_OPM)); +} + +/** + * @brief Set the timer counter counting mode. + * @note Macro IS_TIM_COUNTER_MODE_SELECT_INSTANCE(TIMx) can be used to + * check whether or not the counter mode selection feature is supported + * by a timer instance. + * @note Switching from Center Aligned counter mode to Edge counter mode (or reverse) + * requires a timer reset to avoid unexpected direction + * due to DIR bit readonly in center aligned mode. + * @rmtoll CR1 DIR LL_TIM_SetCounterMode\n + * CR1 CMS LL_TIM_SetCounterMode + * @param TIMx Timer instance + * @param CounterMode This parameter can be one of the following values: + * @arg @ref LL_TIM_COUNTERMODE_UP + * @arg @ref LL_TIM_COUNTERMODE_DOWN + * @arg @ref LL_TIM_COUNTERMODE_CENTER_UP + * @arg @ref LL_TIM_COUNTERMODE_CENTER_DOWN + * @arg @ref LL_TIM_COUNTERMODE_CENTER_UP_DOWN + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetCounterMode(TIM_TypeDef *TIMx, uint32_t CounterMode) +{ + MODIFY_REG(TIMx->CR1, (TIM_CR1_DIR | TIM_CR1_CMS), CounterMode); +} + +/** + * @brief Get actual counter mode. + * @note Macro IS_TIM_COUNTER_MODE_SELECT_INSTANCE(TIMx) can be used to + * check whether or not the counter mode selection feature is supported + * by a timer instance. + * @rmtoll CR1 DIR LL_TIM_GetCounterMode\n + * CR1 CMS LL_TIM_GetCounterMode + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_COUNTERMODE_UP + * @arg @ref LL_TIM_COUNTERMODE_DOWN + * @arg @ref LL_TIM_COUNTERMODE_CENTER_UP + * @arg @ref LL_TIM_COUNTERMODE_CENTER_DOWN + * @arg @ref LL_TIM_COUNTERMODE_CENTER_UP_DOWN + */ +__STATIC_INLINE uint32_t LL_TIM_GetCounterMode(const TIM_TypeDef *TIMx) +{ + uint32_t counter_mode; + + counter_mode = (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_CMS)); + + if (counter_mode == 0U) + { + counter_mode = (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_DIR)); + } + + return counter_mode; +} + +/** + * @brief Enable auto-reload (ARR) preload. + * @rmtoll CR1 ARPE LL_TIM_EnableARRPreload + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableARRPreload(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->CR1, TIM_CR1_ARPE); +} + +/** + * @brief Disable auto-reload (ARR) preload. + * @rmtoll CR1 ARPE LL_TIM_DisableARRPreload + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableARRPreload(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->CR1, TIM_CR1_ARPE); +} + +/** + * @brief Indicates whether auto-reload (ARR) preload is enabled. + * @rmtoll CR1 ARPE LL_TIM_IsEnabledARRPreload + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledARRPreload(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->CR1, TIM_CR1_ARPE) == (TIM_CR1_ARPE)) ? 1UL : 0UL); +} + +/** + * @brief Set the division ratio between the timer clock and the sampling clock used by the dead-time generators + * (when supported) and the digital filters. + * @note Macro IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx) can be used to check + * whether or not the clock division feature is supported by the timer + * instance. + * @rmtoll CR1 CKD LL_TIM_SetClockDivision + * @param TIMx Timer instance + * @param ClockDivision This parameter can be one of the following values: + * @arg @ref LL_TIM_CLOCKDIVISION_DIV1 + * @arg @ref LL_TIM_CLOCKDIVISION_DIV2 + * @arg @ref LL_TIM_CLOCKDIVISION_DIV4 + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetClockDivision(TIM_TypeDef *TIMx, uint32_t ClockDivision) +{ + MODIFY_REG(TIMx->CR1, TIM_CR1_CKD, ClockDivision); +} + +/** + * @brief Get the actual division ratio between the timer clock and the sampling clock used by the dead-time + * generators (when supported) and the digital filters. + * @note Macro IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx) can be used to check + * whether or not the clock division feature is supported by the timer + * instance. + * @rmtoll CR1 CKD LL_TIM_GetClockDivision + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_CLOCKDIVISION_DIV1 + * @arg @ref LL_TIM_CLOCKDIVISION_DIV2 + * @arg @ref LL_TIM_CLOCKDIVISION_DIV4 + */ +__STATIC_INLINE uint32_t LL_TIM_GetClockDivision(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_CKD)); +} + +/** + * @brief Set the counter value. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note If dithering is activated, pay attention to the Counter value interpretation + * @rmtoll CNT CNT LL_TIM_SetCounter + * @param TIMx Timer instance + * @param Counter Counter value (between Min_Data=0 and Max_Data=0xFFFF or 0xFFFFFFFF) + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetCounter(TIM_TypeDef *TIMx, uint32_t Counter) +{ + WRITE_REG(TIMx->CNT, Counter); +} + +/** + * @brief Get the counter value. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note If dithering is activated, pay attention to the Counter value interpretation + * @rmtoll CNT CNT LL_TIM_GetCounter + * @param TIMx Timer instance + * @retval Counter value (between Min_Data=0 and Max_Data=0xFFFF or 0xFFFFFFFF) + */ +__STATIC_INLINE uint32_t LL_TIM_GetCounter(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CNT)); +} + +/** + * @brief Get the current direction of the counter + * @rmtoll CR1 DIR LL_TIM_GetDirection + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_COUNTERDIRECTION_UP + * @arg @ref LL_TIM_COUNTERDIRECTION_DOWN + */ +__STATIC_INLINE uint32_t LL_TIM_GetDirection(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_DIR)); +} + +/** + * @brief Set the prescaler value. + * @note The counter clock frequency CK_CNT is equal to fCK_PSC / (PSC[15:0] + 1). + * @note The prescaler can be changed on the fly as this control register is buffered. The new + * prescaler ratio is taken into account at the next update event. + * @note Helper macro @ref __LL_TIM_CALC_PSC can be used to calculate the Prescaler parameter + * @rmtoll PSC PSC LL_TIM_SetPrescaler + * @param TIMx Timer instance + * @param Prescaler between Min_Data=0 and Max_Data=65535 + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetPrescaler(TIM_TypeDef *TIMx, uint32_t Prescaler) +{ + WRITE_REG(TIMx->PSC, Prescaler); +} + +/** + * @brief Get the prescaler value. + * @rmtoll PSC PSC LL_TIM_GetPrescaler + * @param TIMx Timer instance + * @retval Prescaler value between Min_Data=0 and Max_Data=65535 + */ +__STATIC_INLINE uint32_t LL_TIM_GetPrescaler(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->PSC)); +} + +/** + * @brief Set the auto-reload value. + * @note The counter is blocked while the auto-reload value is null. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note Helper macro @ref __LL_TIM_CALC_ARR can be used to calculate the AutoReload parameter + * In case dithering is activated,macro __LL_TIM_CALC_ARR_DITHER can be used instead, to calculate the AutoReload + * parameter. + * @rmtoll ARR ARR LL_TIM_SetAutoReload + * @param TIMx Timer instance + * @param AutoReload between Min_Data=0 and Max_Data=65535 + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetAutoReload(TIM_TypeDef *TIMx, uint32_t AutoReload) +{ + WRITE_REG(TIMx->ARR, AutoReload); +} + +/** + * @brief Get the auto-reload value. + * @rmtoll ARR ARR LL_TIM_GetAutoReload + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note If dithering is activated, pay attention to the returned value interpretation + * @param TIMx Timer instance + * @retval Auto-reload value + */ +__STATIC_INLINE uint32_t LL_TIM_GetAutoReload(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->ARR)); +} + +/** + * @brief Set the repetition counter value. + * @note For advanced timer instances RepetitionCounter can be up to 65535. + * @note Macro IS_TIM_REPETITION_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a repetition counter. + * @rmtoll RCR REP LL_TIM_SetRepetitionCounter + * @param TIMx Timer instance + * @param RepetitionCounter between Min_Data=0 and Max_Data=255 or 65535 for advanced timer. + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetRepetitionCounter(TIM_TypeDef *TIMx, uint32_t RepetitionCounter) +{ + WRITE_REG(TIMx->RCR, RepetitionCounter); +} + +/** + * @brief Get the repetition counter value. + * @note Macro IS_TIM_REPETITION_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a repetition counter. + * @rmtoll RCR REP LL_TIM_GetRepetitionCounter + * @param TIMx Timer instance + * @retval Repetition counter value + */ +__STATIC_INLINE uint32_t LL_TIM_GetRepetitionCounter(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->RCR)); +} + +/** + * @brief Force a continuous copy of the update interrupt flag (UIF) into the timer counter register (bit 31). + * @note This allows both the counter value and a potential roll-over condition signalled by the UIFCPY flag to be read + * in an atomic way. + * @rmtoll CR1 UIFREMAP LL_TIM_EnableUIFRemap + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableUIFRemap(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->CR1, TIM_CR1_UIFREMAP); +} + +/** + * @brief Disable update interrupt flag (UIF) remapping. + * @rmtoll CR1 UIFREMAP LL_TIM_DisableUIFRemap + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableUIFRemap(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->CR1, TIM_CR1_UIFREMAP); +} + +/** + * @brief Indicate whether update interrupt flag (UIF) copy is set. + * @param Counter Counter value + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveUIFCPY(const uint32_t Counter) +{ + return (((Counter & TIM_CNT_UIFCPY) == (TIM_CNT_UIFCPY)) ? 1UL : 0UL); +} + +/** + * @brief Enable dithering. + * @note Macro IS_TIM_DITHERING_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides dithering. + * @rmtoll CR1 DITHEN LL_TIM_EnableDithering + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableDithering(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->CR1, TIM_CR1_DITHEN); +} + +/** + * @brief Disable dithering. + * @note Macro IS_TIM_DITHERING_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides dithering. + * @rmtoll CR1 DITHEN LL_TIM_DisableDithering + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableDithering(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->CR1, TIM_CR1_DITHEN); +} + +/** + * @brief Indicates whether dithering is activated. + * @note Macro IS_TIM_DITHERING_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides dithering. + * @rmtoll CR1 DITHEN LL_TIM_IsEnabledDithering + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDithering(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->CR1, TIM_CR1_DITHEN) == (TIM_CR1_DITHEN)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_Capture_Compare Capture Compare configuration + * @{ + */ +/** + * @brief Enable the capture/compare control bits (CCxE, CCxNE and OCxM) preload. + * @note CCxE, CCxNE and OCxM bits are preloaded, after having been written, + * they are updated only when a commutation event (COM) occurs. + * @note Only on channels that have a complementary output. + * @note Macro IS_TIM_COMMUTATION_EVENT_INSTANCE(TIMx) can be used to check + * whether or not a timer instance is able to generate a commutation event. + * @rmtoll CR2 CCPC LL_TIM_CC_EnablePreload + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_CC_EnablePreload(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->CR2, TIM_CR2_CCPC); +} + +/** + * @brief Disable the capture/compare control bits (CCxE, CCxNE and OCxM) preload. + * @note Macro IS_TIM_COMMUTATION_EVENT_INSTANCE(TIMx) can be used to check + * whether or not a timer instance is able to generate a commutation event. + * @rmtoll CR2 CCPC LL_TIM_CC_DisablePreload + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_CC_DisablePreload(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->CR2, TIM_CR2_CCPC); +} + +/** + * @brief Set the updated source of the capture/compare control bits (CCxE, CCxNE and OCxM). + * @note Macro IS_TIM_COMMUTATION_EVENT_INSTANCE(TIMx) can be used to check + * whether or not a timer instance is able to generate a commutation event. + * @rmtoll CR2 CCUS LL_TIM_CC_SetUpdate + * @param TIMx Timer instance + * @param CCUpdateSource This parameter can be one of the following values: + * @arg @ref LL_TIM_CCUPDATESOURCE_COMG_ONLY + * @arg @ref LL_TIM_CCUPDATESOURCE_COMG_AND_TRGI + * @retval None + */ +__STATIC_INLINE void LL_TIM_CC_SetUpdate(TIM_TypeDef *TIMx, uint32_t CCUpdateSource) +{ + MODIFY_REG(TIMx->CR2, TIM_CR2_CCUS, CCUpdateSource); +} + +/** + * @brief Set the trigger of the capture/compare DMA request. + * @rmtoll CR2 CCDS LL_TIM_CC_SetDMAReqTrigger + * @param TIMx Timer instance + * @param DMAReqTrigger This parameter can be one of the following values: + * @arg @ref LL_TIM_CCDMAREQUEST_CC + * @arg @ref LL_TIM_CCDMAREQUEST_UPDATE + * @retval None + */ +__STATIC_INLINE void LL_TIM_CC_SetDMAReqTrigger(TIM_TypeDef *TIMx, uint32_t DMAReqTrigger) +{ + MODIFY_REG(TIMx->CR2, TIM_CR2_CCDS, DMAReqTrigger); +} + +/** + * @brief Get actual trigger of the capture/compare DMA request. + * @rmtoll CR2 CCDS LL_TIM_CC_GetDMAReqTrigger + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_CCDMAREQUEST_CC + * @arg @ref LL_TIM_CCDMAREQUEST_UPDATE + */ +__STATIC_INLINE uint32_t LL_TIM_CC_GetDMAReqTrigger(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_BIT(TIMx->CR2, TIM_CR2_CCDS)); +} + +/** + * @brief Set the lock level to freeze the + * configuration of several capture/compare parameters. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * the lock mechanism is supported by a timer instance. + * @rmtoll BDTR LOCK LL_TIM_CC_SetLockLevel + * @param TIMx Timer instance + * @param LockLevel This parameter can be one of the following values: + * @arg @ref LL_TIM_LOCKLEVEL_OFF + * @arg @ref LL_TIM_LOCKLEVEL_1 + * @arg @ref LL_TIM_LOCKLEVEL_2 + * @arg @ref LL_TIM_LOCKLEVEL_3 + * @retval None + */ +__STATIC_INLINE void LL_TIM_CC_SetLockLevel(TIM_TypeDef *TIMx, uint32_t LockLevel) +{ + MODIFY_REG(TIMx->BDTR, TIM_BDTR_LOCK, LockLevel); +} + +/** + * @brief Enable capture/compare channels. + * @rmtoll CCER CC1E LL_TIM_CC_EnableChannel\n + * CCER CC1NE LL_TIM_CC_EnableChannel\n + * CCER CC2E LL_TIM_CC_EnableChannel\n + * CCER CC2NE LL_TIM_CC_EnableChannel\n + * CCER CC3E LL_TIM_CC_EnableChannel\n + * CCER CC3NE LL_TIM_CC_EnableChannel\n + * CCER CC4E LL_TIM_CC_EnableChannel\n + * CCER CC4NE LL_TIM_CC_EnableChannel\n + * CCER CC5E LL_TIM_CC_EnableChannel\n + * CCER CC6E LL_TIM_CC_EnableChannel + * @param TIMx Timer instance + * @param Channels This parameter can be a combination of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH4N + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @retval None + */ +__STATIC_INLINE void LL_TIM_CC_EnableChannel(TIM_TypeDef *TIMx, uint32_t Channels) +{ + SET_BIT(TIMx->CCER, Channels); +} + +/** + * @brief Disable capture/compare channels. + * @rmtoll CCER CC1E LL_TIM_CC_DisableChannel\n + * CCER CC1NE LL_TIM_CC_DisableChannel\n + * CCER CC2E LL_TIM_CC_DisableChannel\n + * CCER CC2NE LL_TIM_CC_DisableChannel\n + * CCER CC3E LL_TIM_CC_DisableChannel\n + * CCER CC3NE LL_TIM_CC_DisableChannel\n + * CCER CC4E LL_TIM_CC_DisableChannel\n + * CCER CC4NE LL_TIM_CC_DisableChannel\n + * CCER CC5E LL_TIM_CC_DisableChannel\n + * CCER CC6E LL_TIM_CC_DisableChannel + * @param TIMx Timer instance + * @param Channels This parameter can be a combination of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH4N + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @retval None + */ +__STATIC_INLINE void LL_TIM_CC_DisableChannel(TIM_TypeDef *TIMx, uint32_t Channels) +{ + CLEAR_BIT(TIMx->CCER, Channels); +} + +/** + * @brief Indicate whether channel(s) is(are) enabled. + * @rmtoll CCER CC1E LL_TIM_CC_IsEnabledChannel\n + * CCER CC1NE LL_TIM_CC_IsEnabledChannel\n + * CCER CC2E LL_TIM_CC_IsEnabledChannel\n + * CCER CC2NE LL_TIM_CC_IsEnabledChannel\n + * CCER CC3E LL_TIM_CC_IsEnabledChannel\n + * CCER CC3NE LL_TIM_CC_IsEnabledChannel\n + * CCER CC4E LL_TIM_CC_IsEnabledChannel\n + * CCER CC4NE LL_TIM_CC_IsEnabledChannel\n + * CCER CC5E LL_TIM_CC_IsEnabledChannel\n + * CCER CC6E LL_TIM_CC_IsEnabledChannel + * @param TIMx Timer instance + * @param Channels This parameter can be a combination of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH4N + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_CC_IsEnabledChannel(const TIM_TypeDef *TIMx, uint32_t Channels) +{ + return ((READ_BIT(TIMx->CCER, Channels) == (Channels)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_Output_Channel Output channel configuration + * @{ + */ +/** + * @brief Configure an output channel. + * @rmtoll CCMR1 CC1S LL_TIM_OC_ConfigOutput\n + * CCMR1 CC2S LL_TIM_OC_ConfigOutput\n + * CCMR2 CC3S LL_TIM_OC_ConfigOutput\n + * CCMR2 CC4S LL_TIM_OC_ConfigOutput\n + * CCMR3 CC5S LL_TIM_OC_ConfigOutput\n + * CCMR3 CC6S LL_TIM_OC_ConfigOutput\n + * CCER CC1P LL_TIM_OC_ConfigOutput\n + * CCER CC2P LL_TIM_OC_ConfigOutput\n + * CCER CC3P LL_TIM_OC_ConfigOutput\n + * CCER CC4P LL_TIM_OC_ConfigOutput\n + * CCER CC5P LL_TIM_OC_ConfigOutput\n + * CCER CC6P LL_TIM_OC_ConfigOutput\n + * CR2 OIS1 LL_TIM_OC_ConfigOutput\n + * CR2 OIS2 LL_TIM_OC_ConfigOutput\n + * CR2 OIS3 LL_TIM_OC_ConfigOutput\n + * CR2 OIS4 LL_TIM_OC_ConfigOutput\n + * CR2 OIS5 LL_TIM_OC_ConfigOutput\n + * CR2 OIS6 LL_TIM_OC_ConfigOutput + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @param Configuration This parameter must be a combination of all the following values: + * @arg @ref LL_TIM_OCPOLARITY_HIGH or @ref LL_TIM_OCPOLARITY_LOW + * @arg @ref LL_TIM_OCIDLESTATE_LOW or @ref LL_TIM_OCIDLESTATE_HIGH + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_ConfigOutput(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t Configuration) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + CLEAR_BIT(*pReg, (TIM_CCMR1_CC1S << SHIFT_TAB_OCxx[iChannel])); + MODIFY_REG(TIMx->CCER, (TIM_CCER_CC1P << SHIFT_TAB_CCxP[iChannel]), + (Configuration & TIM_CCER_CC1P) << SHIFT_TAB_CCxP[iChannel]); + MODIFY_REG(TIMx->CR2, (TIM_CR2_OIS1 << SHIFT_TAB_OISx[iChannel]), + (Configuration & TIM_CR2_OIS1) << SHIFT_TAB_OISx[iChannel]); +} + +/** + * @brief Define the behavior of the output reference signal OCxREF from which + * OCx and OCxN (when relevant) are derived. + * @rmtoll CCMR1 OC1M LL_TIM_OC_SetMode\n + * CCMR1 OC2M LL_TIM_OC_SetMode\n + * CCMR2 OC3M LL_TIM_OC_SetMode\n + * CCMR2 OC4M LL_TIM_OC_SetMode\n + * CCMR3 OC5M LL_TIM_OC_SetMode\n + * CCMR3 OC6M LL_TIM_OC_SetMode + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @param Mode This parameter can be one of the following values: + * @arg @ref LL_TIM_OCMODE_FROZEN + * @arg @ref LL_TIM_OCMODE_ACTIVE + * @arg @ref LL_TIM_OCMODE_INACTIVE + * @arg @ref LL_TIM_OCMODE_TOGGLE + * @arg @ref LL_TIM_OCMODE_FORCED_INACTIVE + * @arg @ref LL_TIM_OCMODE_FORCED_ACTIVE + * @arg @ref LL_TIM_OCMODE_PWM1 + * @arg @ref LL_TIM_OCMODE_PWM2 + * @arg @ref LL_TIM_OCMODE_RETRIG_OPM1 + * @arg @ref LL_TIM_OCMODE_RETRIG_OPM2 + * @arg @ref LL_TIM_OCMODE_COMBINED_PWM1 + * @arg @ref LL_TIM_OCMODE_COMBINED_PWM2 + * @arg @ref LL_TIM_OCMODE_ASSYMETRIC_PWM1 + * @arg @ref LL_TIM_OCMODE_ASSYMETRIC_PWM2 + * @arg @ref LL_TIM_OCMODE_PULSE_ON_COMPARE (for channel 3 or channel 4 only) + * @arg @ref LL_TIM_OCMODE_DIRECTION_OUTPUT (for channel 3 or channel 4 only) + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetMode(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t Mode) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + MODIFY_REG(*pReg, ((TIM_CCMR1_OC1M | TIM_CCMR1_CC1S) << SHIFT_TAB_OCxx[iChannel]), Mode << SHIFT_TAB_OCxx[iChannel]); +} + +/** + * @brief Get the output compare mode of an output channel. + * @rmtoll CCMR1 OC1M LL_TIM_OC_GetMode\n + * CCMR1 OC2M LL_TIM_OC_GetMode\n + * CCMR2 OC3M LL_TIM_OC_GetMode\n + * CCMR2 OC4M LL_TIM_OC_GetMode\n + * CCMR3 OC5M LL_TIM_OC_GetMode\n + * CCMR3 OC6M LL_TIM_OC_GetMode + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_OCMODE_FROZEN + * @arg @ref LL_TIM_OCMODE_ACTIVE + * @arg @ref LL_TIM_OCMODE_INACTIVE + * @arg @ref LL_TIM_OCMODE_TOGGLE + * @arg @ref LL_TIM_OCMODE_FORCED_INACTIVE + * @arg @ref LL_TIM_OCMODE_FORCED_ACTIVE + * @arg @ref LL_TIM_OCMODE_PWM1 + * @arg @ref LL_TIM_OCMODE_PWM2 + * @arg @ref LL_TIM_OCMODE_RETRIG_OPM1 + * @arg @ref LL_TIM_OCMODE_RETRIG_OPM2 + * @arg @ref LL_TIM_OCMODE_COMBINED_PWM1 + * @arg @ref LL_TIM_OCMODE_COMBINED_PWM2 + * @arg @ref LL_TIM_OCMODE_ASSYMETRIC_PWM1 + * @arg @ref LL_TIM_OCMODE_ASSYMETRIC_PWM2 + * @arg @ref LL_TIM_OCMODE_PULSE_ON_COMPARE (for channel 3 or channel 4 only) + * @arg @ref LL_TIM_OCMODE_DIRECTION_OUTPUT (for channel 3 or channel 4 only) + */ +__STATIC_INLINE uint32_t LL_TIM_OC_GetMode(const TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + const __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + return (READ_BIT(*pReg, ((TIM_CCMR1_OC1M | TIM_CCMR1_CC1S) << SHIFT_TAB_OCxx[iChannel])) >> SHIFT_TAB_OCxx[iChannel]); +} + +/** + * @brief Set the polarity of an output channel. + * @rmtoll CCER CC1P LL_TIM_OC_SetPolarity\n + * CCER CC1NP LL_TIM_OC_SetPolarity\n + * CCER CC2P LL_TIM_OC_SetPolarity\n + * CCER CC2NP LL_TIM_OC_SetPolarity\n + * CCER CC3P LL_TIM_OC_SetPolarity\n + * CCER CC3NP LL_TIM_OC_SetPolarity\n + * CCER CC4P LL_TIM_OC_SetPolarity\n + * CCER CC4NP LL_TIM_OC_SetPolarity\n + * CCER CC5P LL_TIM_OC_SetPolarity\n + * CCER CC6P LL_TIM_OC_SetPolarity + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH4N + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @param Polarity This parameter can be one of the following values: + * @arg @ref LL_TIM_OCPOLARITY_HIGH + * @arg @ref LL_TIM_OCPOLARITY_LOW + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetPolarity(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t Polarity) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + MODIFY_REG(TIMx->CCER, (TIM_CCER_CC1P << SHIFT_TAB_CCxP[iChannel]), Polarity << SHIFT_TAB_CCxP[iChannel]); +} + +/** + * @brief Get the polarity of an output channel. + * @rmtoll CCER CC1P LL_TIM_OC_GetPolarity\n + * CCER CC1NP LL_TIM_OC_GetPolarity\n + * CCER CC2P LL_TIM_OC_GetPolarity\n + * CCER CC2NP LL_TIM_OC_GetPolarity\n + * CCER CC3P LL_TIM_OC_GetPolarity\n + * CCER CC3NP LL_TIM_OC_GetPolarity\n + * CCER CC4P LL_TIM_OC_GetPolarity\n + * CCER CC4NP LL_TIM_OC_GetPolarity\n + * CCER CC5P LL_TIM_OC_GetPolarity\n + * CCER CC6P LL_TIM_OC_GetPolarity + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH4N + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_OCPOLARITY_HIGH + * @arg @ref LL_TIM_OCPOLARITY_LOW + */ +__STATIC_INLINE uint32_t LL_TIM_OC_GetPolarity(const TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + return (READ_BIT(TIMx->CCER, (TIM_CCER_CC1P << SHIFT_TAB_CCxP[iChannel])) >> SHIFT_TAB_CCxP[iChannel]); +} + +/** + * @brief Set the IDLE state of an output channel + * @note This function is significant only for the timer instances + * supporting the break feature. Macro IS_TIM_BREAK_INSTANCE(TIMx) + * can be used to check whether or not a timer instance provides + * a break input. + * @rmtoll CR2 OIS1 LL_TIM_OC_SetIdleState\n + * CR2 OIS2N LL_TIM_OC_SetIdleState\n + * CR2 OIS2 LL_TIM_OC_SetIdleState\n + * CR2 OIS2N LL_TIM_OC_SetIdleState\n + * CR2 OIS3 LL_TIM_OC_SetIdleState\n + * CR2 OIS3N LL_TIM_OC_SetIdleState\n + * CR2 OIS4 LL_TIM_OC_SetIdleState\n + * CR2 OIS4N LL_TIM_OC_SetIdleState\n + * CR2 OIS5 LL_TIM_OC_SetIdleState\n + * CR2 OIS6 LL_TIM_OC_SetIdleState + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH4N + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @param IdleState This parameter can be one of the following values: + * @arg @ref LL_TIM_OCIDLESTATE_LOW + * @arg @ref LL_TIM_OCIDLESTATE_HIGH + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetIdleState(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t IdleState) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + MODIFY_REG(TIMx->CR2, (TIM_CR2_OIS1 << SHIFT_TAB_OISx[iChannel]), IdleState << SHIFT_TAB_OISx[iChannel]); +} + +/** + * @brief Get the IDLE state of an output channel + * @rmtoll CR2 OIS1 LL_TIM_OC_GetIdleState\n + * CR2 OIS2N LL_TIM_OC_GetIdleState\n + * CR2 OIS2 LL_TIM_OC_GetIdleState\n + * CR2 OIS2N LL_TIM_OC_GetIdleState\n + * CR2 OIS3 LL_TIM_OC_GetIdleState\n + * CR2 OIS3N LL_TIM_OC_GetIdleState\n + * CR2 OIS4 LL_TIM_OC_GetIdleState\n + * CR2 OIS4N LL_TIM_OC_GetIdleState\n + * CR2 OIS5 LL_TIM_OC_GetIdleState\n + * CR2 OIS6 LL_TIM_OC_GetIdleState + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH4N + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_OCIDLESTATE_LOW + * @arg @ref LL_TIM_OCIDLESTATE_HIGH + */ +__STATIC_INLINE uint32_t LL_TIM_OC_GetIdleState(const TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + return (READ_BIT(TIMx->CR2, (TIM_CR2_OIS1 << SHIFT_TAB_OISx[iChannel])) >> SHIFT_TAB_OISx[iChannel]); +} + +/** + * @brief Enable fast mode for the output channel. + * @note Acts only if the channel is configured in PWM1 or PWM2 mode. + * @rmtoll CCMR1 OC1FE LL_TIM_OC_EnableFast\n + * CCMR1 OC2FE LL_TIM_OC_EnableFast\n + * CCMR2 OC3FE LL_TIM_OC_EnableFast\n + * CCMR2 OC4FE LL_TIM_OC_EnableFast\n + * CCMR3 OC5FE LL_TIM_OC_EnableFast\n + * CCMR3 OC6FE LL_TIM_OC_EnableFast + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_EnableFast(TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + SET_BIT(*pReg, (TIM_CCMR1_OC1FE << SHIFT_TAB_OCxx[iChannel])); + +} + +/** + * @brief Disable fast mode for the output channel. + * @rmtoll CCMR1 OC1FE LL_TIM_OC_DisableFast\n + * CCMR1 OC2FE LL_TIM_OC_DisableFast\n + * CCMR2 OC3FE LL_TIM_OC_DisableFast\n + * CCMR2 OC4FE LL_TIM_OC_DisableFast\n + * CCMR3 OC5FE LL_TIM_OC_DisableFast\n + * CCMR3 OC6FE LL_TIM_OC_DisableFast + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_DisableFast(TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + CLEAR_BIT(*pReg, (TIM_CCMR1_OC1FE << SHIFT_TAB_OCxx[iChannel])); + +} + +/** + * @brief Indicates whether fast mode is enabled for the output channel. + * @rmtoll CCMR1 OC1FE LL_TIM_OC_IsEnabledFast\n + * CCMR1 OC2FE LL_TIM_OC_IsEnabledFast\n + * CCMR2 OC3FE LL_TIM_OC_IsEnabledFast\n + * CCMR2 OC4FE LL_TIM_OC_IsEnabledFast\n + * CCMR3 OC5FE LL_TIM_OC_IsEnabledFast\n + * CCMR3 OC6FE LL_TIM_OC_IsEnabledFast + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_OC_IsEnabledFast(const TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + const __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + uint32_t bitfield = TIM_CCMR1_OC1FE << SHIFT_TAB_OCxx[iChannel]; + return ((READ_BIT(*pReg, bitfield) == bitfield) ? 1UL : 0UL); +} + +/** + * @brief Enable compare register (TIMx_CCRx) preload for the output channel. + * @rmtoll CCMR1 OC1PE LL_TIM_OC_EnablePreload\n + * CCMR1 OC2PE LL_TIM_OC_EnablePreload\n + * CCMR2 OC3PE LL_TIM_OC_EnablePreload\n + * CCMR2 OC4PE LL_TIM_OC_EnablePreload\n + * CCMR3 OC5PE LL_TIM_OC_EnablePreload\n + * CCMR3 OC6PE LL_TIM_OC_EnablePreload + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_EnablePreload(TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + SET_BIT(*pReg, (TIM_CCMR1_OC1PE << SHIFT_TAB_OCxx[iChannel])); +} + +/** + * @brief Disable compare register (TIMx_CCRx) preload for the output channel. + * @rmtoll CCMR1 OC1PE LL_TIM_OC_DisablePreload\n + * CCMR1 OC2PE LL_TIM_OC_DisablePreload\n + * CCMR2 OC3PE LL_TIM_OC_DisablePreload\n + * CCMR2 OC4PE LL_TIM_OC_DisablePreload\n + * CCMR3 OC5PE LL_TIM_OC_DisablePreload\n + * CCMR3 OC6PE LL_TIM_OC_DisablePreload + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_DisablePreload(TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + CLEAR_BIT(*pReg, (TIM_CCMR1_OC1PE << SHIFT_TAB_OCxx[iChannel])); +} + +/** + * @brief Indicates whether compare register (TIMx_CCRx) preload is enabled for the output channel. + * @rmtoll CCMR1 OC1PE LL_TIM_OC_IsEnabledPreload\n + * CCMR1 OC2PE LL_TIM_OC_IsEnabledPreload\n + * CCMR2 OC3PE LL_TIM_OC_IsEnabledPreload\n + * CCMR2 OC4PE LL_TIM_OC_IsEnabledPreload\n + * CCMR3 OC5PE LL_TIM_OC_IsEnabledPreload\n + * CCMR3 OC6PE LL_TIM_OC_IsEnabledPreload + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_OC_IsEnabledPreload(const TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + const __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + uint32_t bitfield = TIM_CCMR1_OC1PE << SHIFT_TAB_OCxx[iChannel]; + return ((READ_BIT(*pReg, bitfield) == bitfield) ? 1UL : 0UL); +} + +/** + * @brief Enable clearing the output channel on an external event. + * @note This function can only be used in Output compare and PWM modes. It does not work in Forced mode. + * @note Macro IS_TIM_OCXREF_CLEAR_INSTANCE(TIMx) can be used to check whether + * or not a timer instance can clear the OCxREF signal on an external event. + * @rmtoll CCMR1 OC1CE LL_TIM_OC_EnableClear\n + * CCMR1 OC2CE LL_TIM_OC_EnableClear\n + * CCMR2 OC3CE LL_TIM_OC_EnableClear\n + * CCMR2 OC4CE LL_TIM_OC_EnableClear\n + * CCMR3 OC5CE LL_TIM_OC_EnableClear\n + * CCMR3 OC6CE LL_TIM_OC_EnableClear + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_EnableClear(TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + SET_BIT(*pReg, (TIM_CCMR1_OC1CE << SHIFT_TAB_OCxx[iChannel])); +} + +/** + * @brief Disable clearing the output channel on an external event. + * @note Macro IS_TIM_OCXREF_CLEAR_INSTANCE(TIMx) can be used to check whether + * or not a timer instance can clear the OCxREF signal on an external event. + * @rmtoll CCMR1 OC1CE LL_TIM_OC_DisableClear\n + * CCMR1 OC2CE LL_TIM_OC_DisableClear\n + * CCMR2 OC3CE LL_TIM_OC_DisableClear\n + * CCMR2 OC4CE LL_TIM_OC_DisableClear\n + * CCMR3 OC5CE LL_TIM_OC_DisableClear\n + * CCMR3 OC6CE LL_TIM_OC_DisableClear + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_DisableClear(TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + CLEAR_BIT(*pReg, (TIM_CCMR1_OC1CE << SHIFT_TAB_OCxx[iChannel])); +} + +/** + * @brief Indicates clearing the output channel on an external event is enabled for the output channel. + * @note This function enables clearing the output channel on an external event. + * @note This function can only be used in Output compare and PWM modes. It does not work in Forced mode. + * @note Macro IS_TIM_OCXREF_CLEAR_INSTANCE(TIMx) can be used to check whether + * or not a timer instance can clear the OCxREF signal on an external event. + * @rmtoll CCMR1 OC1CE LL_TIM_OC_IsEnabledClear\n + * CCMR1 OC2CE LL_TIM_OC_IsEnabledClear\n + * CCMR2 OC3CE LL_TIM_OC_IsEnabledClear\n + * CCMR2 OC4CE LL_TIM_OC_IsEnabledClear\n + * CCMR3 OC5CE LL_TIM_OC_IsEnabledClear\n + * CCMR3 OC6CE LL_TIM_OC_IsEnabledClear + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_OC_IsEnabledClear(const TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + const __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + uint32_t bitfield = TIM_CCMR1_OC1CE << SHIFT_TAB_OCxx[iChannel]; + return ((READ_BIT(*pReg, bitfield) == bitfield) ? 1UL : 0UL); +} + +/** + * @brief Set the dead-time delay (delay inserted between the rising edge of the OCxREF signal and the rising edge of + * the Ocx and OCxN signals). + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * dead-time insertion feature is supported by a timer instance. + * @note Helper macro @ref __LL_TIM_CALC_DEADTIME can be used to calculate the DeadTime parameter + * @rmtoll BDTR DTG LL_TIM_OC_SetDeadTime + * @param TIMx Timer instance + * @param DeadTime between Min_Data=0 and Max_Data=255 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetDeadTime(TIM_TypeDef *TIMx, uint32_t DeadTime) +{ + MODIFY_REG(TIMx->BDTR, TIM_BDTR_DTG, DeadTime); +} + +/** + * @brief Set compare value for output channel 1 (TIMx_CCR1). + * @note In 32-bit timer implementations compare value can be between 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note Macro IS_TIM_CC1_INSTANCE(TIMx) can be used to check whether or not + * output channel 1 is supported by a timer instance. + * @note If dithering is activated, CompareValue can be calculated with macro @ref __LL_TIM_CALC_DELAY_DITHER . + * @rmtoll CCR1 CCR1 LL_TIM_OC_SetCompareCH1 + * @param TIMx Timer instance + * @param CompareValue between Min_Data=0 and Max_Data=65535 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetCompareCH1(TIM_TypeDef *TIMx, uint32_t CompareValue) +{ + WRITE_REG(TIMx->CCR1, CompareValue); +} + +/** + * @brief Set compare value for output channel 2 (TIMx_CCR2). + * @note In 32-bit timer implementations compare value can be between 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note Macro IS_TIM_CC2_INSTANCE(TIMx) can be used to check whether or not + * output channel 2 is supported by a timer instance. + * @note If dithering is activated, CompareValue can be calculated with macro @ref __LL_TIM_CALC_DELAY_DITHER . + * @rmtoll CCR2 CCR2 LL_TIM_OC_SetCompareCH2 + * @param TIMx Timer instance + * @param CompareValue between Min_Data=0 and Max_Data=65535 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetCompareCH2(TIM_TypeDef *TIMx, uint32_t CompareValue) +{ + WRITE_REG(TIMx->CCR2, CompareValue); +} + +/** + * @brief Set compare value for output channel 3 (TIMx_CCR3). + * @note In 32-bit timer implementations compare value can be between 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note Macro IS_TIM_CC3_INSTANCE(TIMx) can be used to check whether or not + * output channel is supported by a timer instance. + * @note If dithering is activated, CompareValue can be calculated with macro @ref __LL_TIM_CALC_DELAY_DITHER . + * @rmtoll CCR3 CCR3 LL_TIM_OC_SetCompareCH3 + * @param TIMx Timer instance + * @param CompareValue between Min_Data=0 and Max_Data=65535 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetCompareCH3(TIM_TypeDef *TIMx, uint32_t CompareValue) +{ + WRITE_REG(TIMx->CCR3, CompareValue); +} + +/** + * @brief Set compare value for output channel 4 (TIMx_CCR4). + * @note In 32-bit timer implementations compare value can be between 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note Macro IS_TIM_CC4_INSTANCE(TIMx) can be used to check whether or not + * output channel 4 is supported by a timer instance. + * @note If dithering is activated, CompareValue can be calculated with macro @ref __LL_TIM_CALC_DELAY_DITHER . + * @rmtoll CCR4 CCR4 LL_TIM_OC_SetCompareCH4 + * @param TIMx Timer instance + * @param CompareValue between Min_Data=0 and Max_Data=65535 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetCompareCH4(TIM_TypeDef *TIMx, uint32_t CompareValue) +{ + WRITE_REG(TIMx->CCR4, CompareValue); +} + +/** + * @brief Set compare value for output channel 5 (TIMx_CCR5). + * @note Macro IS_TIM_CC5_INSTANCE(TIMx) can be used to check whether or not + * output channel 5 is supported by a timer instance. + * @note If dithering is activated, CompareValue can be calculated with macro @ref __LL_TIM_CALC_DELAY_DITHER . + * @rmtoll CCR5 CCR5 LL_TIM_OC_SetCompareCH5 + * @param TIMx Timer instance + * @param CompareValue between Min_Data=0 and Max_Data=65535 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetCompareCH5(TIM_TypeDef *TIMx, uint32_t CompareValue) +{ + MODIFY_REG(TIMx->CCR5, TIM_CCR5_CCR5, CompareValue); +} + +/** + * @brief Set compare value for output channel 6 (TIMx_CCR6). + * @note Macro IS_TIM_CC6_INSTANCE(TIMx) can be used to check whether or not + * output channel 6 is supported by a timer instance. + * @note If dithering is activated, CompareValue can be calculated with macro @ref __LL_TIM_CALC_DELAY_DITHER . + * @rmtoll CCR6 CCR6 LL_TIM_OC_SetCompareCH6 + * @param TIMx Timer instance + * @param CompareValue between Min_Data=0 and Max_Data=65535 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetCompareCH6(TIM_TypeDef *TIMx, uint32_t CompareValue) +{ + WRITE_REG(TIMx->CCR6, CompareValue); +} + +/** + * @brief Get compare value (TIMx_CCR1) set for output channel 1. + * @note In 32-bit timer implementations returned compare value can be between 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note Macro IS_TIM_CC1_INSTANCE(TIMx) can be used to check whether or not + * output channel 1 is supported by a timer instance. + * @note If dithering is activated, pay attention to the returned value interpretation. + * @rmtoll CCR1 CCR1 LL_TIM_OC_GetCompareCH1 + * @param TIMx Timer instance + * @retval CompareValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH1(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR1)); +} + +/** + * @brief Get compare value (TIMx_CCR2) set for output channel 2. + * @note In 32-bit timer implementations returned compare value can be between 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note Macro IS_TIM_CC2_INSTANCE(TIMx) can be used to check whether or not + * output channel 2 is supported by a timer instance. + * @note If dithering is activated, pay attention to the returned value interpretation. + * @rmtoll CCR2 CCR2 LL_TIM_OC_GetCompareCH2 + * @param TIMx Timer instance + * @retval CompareValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH2(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR2)); +} + +/** + * @brief Get compare value (TIMx_CCR3) set for output channel 3. + * @note In 32-bit timer implementations returned compare value can be between 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note Macro IS_TIM_CC3_INSTANCE(TIMx) can be used to check whether or not + * output channel 3 is supported by a timer instance. + * @note If dithering is activated, pay attention to the returned value interpretation. + * @rmtoll CCR3 CCR3 LL_TIM_OC_GetCompareCH3 + * @param TIMx Timer instance + * @retval CompareValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH3(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR3)); +} + +/** + * @brief Get compare value (TIMx_CCR4) set for output channel 4. + * @note In 32-bit timer implementations returned compare value can be between 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note Macro IS_TIM_CC4_INSTANCE(TIMx) can be used to check whether or not + * output channel 4 is supported by a timer instance. + * @note If dithering is activated, pay attention to the returned value interpretation. + * @rmtoll CCR4 CCR4 LL_TIM_OC_GetCompareCH4 + * @param TIMx Timer instance + * @retval CompareValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH4(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR4)); +} + +/** + * @brief Get compare value (TIMx_CCR5) set for output channel 5. + * @note Macro IS_TIM_CC5_INSTANCE(TIMx) can be used to check whether or not + * output channel 5 is supported by a timer instance. + * @note If dithering is activated, pay attention to the returned value interpretation. + * @rmtoll CCR5 CCR5 LL_TIM_OC_GetCompareCH5 + * @param TIMx Timer instance + * @retval CompareValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH5(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_BIT(TIMx->CCR5, TIM_CCR5_CCR5)); +} + +/** + * @brief Get compare value (TIMx_CCR6) set for output channel 6. + * @note Macro IS_TIM_CC6_INSTANCE(TIMx) can be used to check whether or not + * output channel 6 is supported by a timer instance. + * @note If dithering is activated, pay attention to the returned value interpretation. + * @rmtoll CCR6 CCR6 LL_TIM_OC_GetCompareCH6 + * @param TIMx Timer instance + * @retval CompareValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH6(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR6)); +} + +/** + * @brief Select on which reference signal the OC5REF is combined to. + * @note Macro IS_TIM_COMBINED3PHASEPWM_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports the combined 3-phase PWM mode. + * @rmtoll CCR5 GC5C3 LL_TIM_SetCH5CombinedChannels\n + * CCR5 GC5C2 LL_TIM_SetCH5CombinedChannels\n + * CCR5 GC5C1 LL_TIM_SetCH5CombinedChannels + * @param TIMx Timer instance + * @param GroupCH5 This parameter can be a combination of the following values: + * @arg @ref LL_TIM_GROUPCH5_NONE + * @arg @ref LL_TIM_GROUPCH5_OC1REFC + * @arg @ref LL_TIM_GROUPCH5_OC2REFC + * @arg @ref LL_TIM_GROUPCH5_OC3REFC + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetCH5CombinedChannels(TIM_TypeDef *TIMx, uint32_t GroupCH5) +{ + MODIFY_REG(TIMx->CCR5, (TIM_CCR5_GC5C3 | TIM_CCR5_GC5C2 | TIM_CCR5_GC5C1), GroupCH5); +} + +/** + * @brief Set the pulse on compare pulse width prescaler. + * @note Macro IS_TIM_PULSEONCOMPARE_INSTANCE(TIMx) can be used to check + * whether or not the pulse on compare feature is supported by the timer + * instance. + * @rmtoll ECR PWPRSC LL_TIM_OC_SetPulseWidthPrescaler + * @param TIMx Timer instance + * @param PulseWidthPrescaler This parameter can be one of the following values: + * @arg @ref LL_TIM_PWPRSC_X1 + * @arg @ref LL_TIM_PWPRSC_X2 + * @arg @ref LL_TIM_PWPRSC_X4 + * @arg @ref LL_TIM_PWPRSC_X8 + * @arg @ref LL_TIM_PWPRSC_X16 + * @arg @ref LL_TIM_PWPRSC_X32 + * @arg @ref LL_TIM_PWPRSC_X64 + * @arg @ref LL_TIM_PWPRSC_X128 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetPulseWidthPrescaler(TIM_TypeDef *TIMx, uint32_t PulseWidthPrescaler) +{ + MODIFY_REG(TIMx->ECR, TIM_ECR_PWPRSC, PulseWidthPrescaler); +} + +/** + * @brief Get the pulse on compare pulse width prescaler. + * @note Macro IS_TIM_PULSEONCOMPARE_INSTANCE(TIMx) can be used to check + * whether or not the pulse on compare feature is supported by the timer + * instance. + * @rmtoll ECR PWPRSC LL_TIM_OC_GetPulseWidthPrescaler + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_PWPRSC_X1 + * @arg @ref LL_TIM_PWPRSC_X2 + * @arg @ref LL_TIM_PWPRSC_X4 + * @arg @ref LL_TIM_PWPRSC_X8 + * @arg @ref LL_TIM_PWPRSC_X16 + * @arg @ref LL_TIM_PWPRSC_X32 + * @arg @ref LL_TIM_PWPRSC_X64 + * @arg @ref LL_TIM_PWPRSC_X128 + */ +__STATIC_INLINE uint32_t LL_TIM_OC_GetPulseWidthPrescaler(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_BIT(TIMx->ECR, TIM_ECR_PWPRSC)); +} + +/** + * @brief Set the pulse on compare pulse width duration. + * @note Macro IS_TIM_PULSEONCOMPARE_INSTANCE(TIMx) can be used to check + * whether or not the pulse on compare feature is supported by the timer + * instance. + * @rmtoll ECR PW LL_TIM_OC_SetPulseWidth + * @param TIMx Timer instance + * @param PulseWidth This parameter can be between Min_Data=0 and Max_Data=255 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetPulseWidth(TIM_TypeDef *TIMx, uint32_t PulseWidth) +{ + MODIFY_REG(TIMx->ECR, TIM_ECR_PW, PulseWidth << TIM_ECR_PW_Pos); +} + +/** + * @brief Get the pulse on compare pulse width duration. + * @note Macro IS_TIM_PULSEONCOMPARE_INSTANCE(TIMx) can be used to check + * whether or not the pulse on compare feature is supported by the timer + * instance. + * @rmtoll ECR PW LL_TIM_OC_GetPulseWidth + * @param TIMx Timer instance + * @retval Returned value can be between Min_Data=0 and Max_Data=255: + */ +__STATIC_INLINE uint32_t LL_TIM_OC_GetPulseWidth(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_BIT(TIMx->ECR, TIM_ECR_PW)); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_Input_Channel Input channel configuration + * @{ + */ +/** + * @brief Configure input channel. + * @rmtoll CCMR1 CC1S LL_TIM_IC_Config\n + * CCMR1 IC1PSC LL_TIM_IC_Config\n + * CCMR1 IC1F LL_TIM_IC_Config\n + * CCMR1 CC2S LL_TIM_IC_Config\n + * CCMR1 IC2PSC LL_TIM_IC_Config\n + * CCMR1 IC2F LL_TIM_IC_Config\n + * CCMR2 CC3S LL_TIM_IC_Config\n + * CCMR2 IC3PSC LL_TIM_IC_Config\n + * CCMR2 IC3F LL_TIM_IC_Config\n + * CCMR2 CC4S LL_TIM_IC_Config\n + * CCMR2 IC4PSC LL_TIM_IC_Config\n + * CCMR2 IC4F LL_TIM_IC_Config\n + * CCER CC1P LL_TIM_IC_Config\n + * CCER CC1NP LL_TIM_IC_Config\n + * CCER CC2P LL_TIM_IC_Config\n + * CCER CC2NP LL_TIM_IC_Config\n + * CCER CC3P LL_TIM_IC_Config\n + * CCER CC3NP LL_TIM_IC_Config\n + * CCER CC4P LL_TIM_IC_Config\n + * CCER CC4NP LL_TIM_IC_Config + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param Configuration This parameter must be a combination of all the following values: + * @arg @ref LL_TIM_ACTIVEINPUT_DIRECTTI or @ref LL_TIM_ACTIVEINPUT_INDIRECTTI or @ref LL_TIM_ACTIVEINPUT_TRC + * @arg @ref LL_TIM_ICPSC_DIV1 or ... or @ref LL_TIM_ICPSC_DIV8 + * @arg @ref LL_TIM_IC_FILTER_FDIV1 or ... or @ref LL_TIM_IC_FILTER_FDIV32_N8 + * @arg @ref LL_TIM_IC_POLARITY_RISING or @ref LL_TIM_IC_POLARITY_FALLING or @ref LL_TIM_IC_POLARITY_BOTHEDGE + * @retval None + */ +__STATIC_INLINE void LL_TIM_IC_Config(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t Configuration) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + MODIFY_REG(*pReg, ((TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC | TIM_CCMR1_CC1S) << SHIFT_TAB_ICxx[iChannel]), + ((Configuration >> 16U) & (TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC | TIM_CCMR1_CC1S)) \ + << SHIFT_TAB_ICxx[iChannel]); + MODIFY_REG(TIMx->CCER, ((TIM_CCER_CC1NP | TIM_CCER_CC1P) << SHIFT_TAB_CCxP[iChannel]), + (Configuration & (TIM_CCER_CC1NP | TIM_CCER_CC1P)) << SHIFT_TAB_CCxP[iChannel]); +} + +/** + * @brief Set the active input. + * @rmtoll CCMR1 CC1S LL_TIM_IC_SetActiveInput\n + * CCMR1 CC2S LL_TIM_IC_SetActiveInput\n + * CCMR2 CC3S LL_TIM_IC_SetActiveInput\n + * CCMR2 CC4S LL_TIM_IC_SetActiveInput + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param ICActiveInput This parameter can be one of the following values: + * @arg @ref LL_TIM_ACTIVEINPUT_DIRECTTI + * @arg @ref LL_TIM_ACTIVEINPUT_INDIRECTTI + * @arg @ref LL_TIM_ACTIVEINPUT_TRC + * @retval None + */ +__STATIC_INLINE void LL_TIM_IC_SetActiveInput(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ICActiveInput) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + MODIFY_REG(*pReg, ((TIM_CCMR1_CC1S) << SHIFT_TAB_ICxx[iChannel]), (ICActiveInput >> 16U) << SHIFT_TAB_ICxx[iChannel]); +} + +/** + * @brief Get the current active input. + * @rmtoll CCMR1 CC1S LL_TIM_IC_GetActiveInput\n + * CCMR1 CC2S LL_TIM_IC_GetActiveInput\n + * CCMR2 CC3S LL_TIM_IC_GetActiveInput\n + * CCMR2 CC4S LL_TIM_IC_GetActiveInput + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_ACTIVEINPUT_DIRECTTI + * @arg @ref LL_TIM_ACTIVEINPUT_INDIRECTTI + * @arg @ref LL_TIM_ACTIVEINPUT_TRC + */ +__STATIC_INLINE uint32_t LL_TIM_IC_GetActiveInput(const TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + const __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + return ((READ_BIT(*pReg, ((TIM_CCMR1_CC1S) << SHIFT_TAB_ICxx[iChannel])) >> SHIFT_TAB_ICxx[iChannel]) << 16U); +} + +/** + * @brief Set the prescaler of input channel. + * @rmtoll CCMR1 IC1PSC LL_TIM_IC_SetPrescaler\n + * CCMR1 IC2PSC LL_TIM_IC_SetPrescaler\n + * CCMR2 IC3PSC LL_TIM_IC_SetPrescaler\n + * CCMR2 IC4PSC LL_TIM_IC_SetPrescaler + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param ICPrescaler This parameter can be one of the following values: + * @arg @ref LL_TIM_ICPSC_DIV1 + * @arg @ref LL_TIM_ICPSC_DIV2 + * @arg @ref LL_TIM_ICPSC_DIV4 + * @arg @ref LL_TIM_ICPSC_DIV8 + * @retval None + */ +__STATIC_INLINE void LL_TIM_IC_SetPrescaler(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ICPrescaler) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + MODIFY_REG(*pReg, ((TIM_CCMR1_IC1PSC) << SHIFT_TAB_ICxx[iChannel]), (ICPrescaler >> 16U) << SHIFT_TAB_ICxx[iChannel]); +} + +/** + * @brief Get the current prescaler value acting on an input channel. + * @rmtoll CCMR1 IC1PSC LL_TIM_IC_GetPrescaler\n + * CCMR1 IC2PSC LL_TIM_IC_GetPrescaler\n + * CCMR2 IC3PSC LL_TIM_IC_GetPrescaler\n + * CCMR2 IC4PSC LL_TIM_IC_GetPrescaler + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_ICPSC_DIV1 + * @arg @ref LL_TIM_ICPSC_DIV2 + * @arg @ref LL_TIM_ICPSC_DIV4 + * @arg @ref LL_TIM_ICPSC_DIV8 + */ +__STATIC_INLINE uint32_t LL_TIM_IC_GetPrescaler(const TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + const __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + return ((READ_BIT(*pReg, ((TIM_CCMR1_IC1PSC) << SHIFT_TAB_ICxx[iChannel])) >> SHIFT_TAB_ICxx[iChannel]) << 16U); +} + +/** + * @brief Set the input filter duration. + * @rmtoll CCMR1 IC1F LL_TIM_IC_SetFilter\n + * CCMR1 IC2F LL_TIM_IC_SetFilter\n + * CCMR2 IC3F LL_TIM_IC_SetFilter\n + * CCMR2 IC4F LL_TIM_IC_SetFilter + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param ICFilter This parameter can be one of the following values: + * @arg @ref LL_TIM_IC_FILTER_FDIV1 + * @arg @ref LL_TIM_IC_FILTER_FDIV1_N2 + * @arg @ref LL_TIM_IC_FILTER_FDIV1_N4 + * @arg @ref LL_TIM_IC_FILTER_FDIV1_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV2_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV2_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV4_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV4_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV8_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV8_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV16_N5 + * @arg @ref LL_TIM_IC_FILTER_FDIV16_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV16_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV32_N5 + * @arg @ref LL_TIM_IC_FILTER_FDIV32_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV32_N8 + * @retval None + */ +__STATIC_INLINE void LL_TIM_IC_SetFilter(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ICFilter) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + MODIFY_REG(*pReg, ((TIM_CCMR1_IC1F) << SHIFT_TAB_ICxx[iChannel]), (ICFilter >> 16U) << SHIFT_TAB_ICxx[iChannel]); +} + +/** + * @brief Get the input filter duration. + * @rmtoll CCMR1 IC1F LL_TIM_IC_GetFilter\n + * CCMR1 IC2F LL_TIM_IC_GetFilter\n + * CCMR2 IC3F LL_TIM_IC_GetFilter\n + * CCMR2 IC4F LL_TIM_IC_GetFilter + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_IC_FILTER_FDIV1 + * @arg @ref LL_TIM_IC_FILTER_FDIV1_N2 + * @arg @ref LL_TIM_IC_FILTER_FDIV1_N4 + * @arg @ref LL_TIM_IC_FILTER_FDIV1_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV2_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV2_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV4_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV4_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV8_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV8_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV16_N5 + * @arg @ref LL_TIM_IC_FILTER_FDIV16_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV16_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV32_N5 + * @arg @ref LL_TIM_IC_FILTER_FDIV32_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV32_N8 + */ +__STATIC_INLINE uint32_t LL_TIM_IC_GetFilter(const TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + const __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + return ((READ_BIT(*pReg, ((TIM_CCMR1_IC1F) << SHIFT_TAB_ICxx[iChannel])) >> SHIFT_TAB_ICxx[iChannel]) << 16U); +} + +/** + * @brief Set the input channel polarity. + * @rmtoll CCER CC1P LL_TIM_IC_SetPolarity\n + * CCER CC1NP LL_TIM_IC_SetPolarity\n + * CCER CC2P LL_TIM_IC_SetPolarity\n + * CCER CC2NP LL_TIM_IC_SetPolarity\n + * CCER CC3P LL_TIM_IC_SetPolarity\n + * CCER CC3NP LL_TIM_IC_SetPolarity\n + * CCER CC4P LL_TIM_IC_SetPolarity\n + * CCER CC4NP LL_TIM_IC_SetPolarity + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param ICPolarity This parameter can be one of the following values: + * @arg @ref LL_TIM_IC_POLARITY_RISING + * @arg @ref LL_TIM_IC_POLARITY_FALLING + * @arg @ref LL_TIM_IC_POLARITY_BOTHEDGE + * @retval None + */ +__STATIC_INLINE void LL_TIM_IC_SetPolarity(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ICPolarity) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + MODIFY_REG(TIMx->CCER, ((TIM_CCER_CC1NP | TIM_CCER_CC1P) << SHIFT_TAB_CCxP[iChannel]), + ICPolarity << SHIFT_TAB_CCxP[iChannel]); +} + +/** + * @brief Get the current input channel polarity. + * @rmtoll CCER CC1P LL_TIM_IC_GetPolarity\n + * CCER CC1NP LL_TIM_IC_GetPolarity\n + * CCER CC2P LL_TIM_IC_GetPolarity\n + * CCER CC2NP LL_TIM_IC_GetPolarity\n + * CCER CC3P LL_TIM_IC_GetPolarity\n + * CCER CC3NP LL_TIM_IC_GetPolarity\n + * CCER CC4P LL_TIM_IC_GetPolarity\n + * CCER CC4NP LL_TIM_IC_GetPolarity + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_IC_POLARITY_RISING + * @arg @ref LL_TIM_IC_POLARITY_FALLING + * @arg @ref LL_TIM_IC_POLARITY_BOTHEDGE + */ +__STATIC_INLINE uint32_t LL_TIM_IC_GetPolarity(const TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + return (READ_BIT(TIMx->CCER, ((TIM_CCER_CC1NP | TIM_CCER_CC1P) << SHIFT_TAB_CCxP[iChannel])) >> + SHIFT_TAB_CCxP[iChannel]); +} + +/** + * @brief Connect the TIMx_CH1, CH2 and CH3 pins to the TI1 input (XOR combination). + * @note Macro IS_TIM_XOR_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an XOR input. + * @rmtoll CR2 TI1S LL_TIM_IC_EnableXORCombination + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_IC_EnableXORCombination(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->CR2, TIM_CR2_TI1S); +} + +/** + * @brief Disconnect the TIMx_CH1, CH2 and CH3 pins from the TI1 input. + * @note Macro IS_TIM_XOR_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an XOR input. + * @rmtoll CR2 TI1S LL_TIM_IC_DisableXORCombination + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_IC_DisableXORCombination(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->CR2, TIM_CR2_TI1S); +} + +/** + * @brief Indicates whether the TIMx_CH1, CH2 and CH3 pins are connectected to the TI1 input. + * @note Macro IS_TIM_XOR_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an XOR input. + * @rmtoll CR2 TI1S LL_TIM_IC_IsEnabledXORCombination + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IC_IsEnabledXORCombination(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->CR2, TIM_CR2_TI1S) == (TIM_CR2_TI1S)) ? 1UL : 0UL); +} + +/** + * @brief Get captured value for input channel 1. + * @note In 32-bit timer implementations returned captured value can be between 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note Macro IS_TIM_CC1_INSTANCE(TIMx) can be used to check whether or not + * input channel 1 is supported by a timer instance. + * @note If dithering is activated, pay attention to the returned value interpretation. + * @rmtoll CCR1 CCR1 LL_TIM_IC_GetCaptureCH1 + * @param TIMx Timer instance + * @retval CapturedValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_TIM_IC_GetCaptureCH1(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR1)); +} + +/** + * @brief Get captured value for input channel 2. + * @note In 32-bit timer implementations returned captured value can be between 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note Macro IS_TIM_CC2_INSTANCE(TIMx) can be used to check whether or not + * input channel 2 is supported by a timer instance. + * @note If dithering is activated, pay attention to the returned value interpretation. + * @rmtoll CCR2 CCR2 LL_TIM_IC_GetCaptureCH2 + * @param TIMx Timer instance + * @retval CapturedValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_TIM_IC_GetCaptureCH2(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR2)); +} + +/** + * @brief Get captured value for input channel 3. + * @note In 32-bit timer implementations returned captured value can be between 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note Macro IS_TIM_CC3_INSTANCE(TIMx) can be used to check whether or not + * input channel 3 is supported by a timer instance. + * @note If dithering is activated, pay attention to the returned value interpretation. + * @rmtoll CCR3 CCR3 LL_TIM_IC_GetCaptureCH3 + * @param TIMx Timer instance + * @retval CapturedValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_TIM_IC_GetCaptureCH3(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR3)); +} + +/** + * @brief Get captured value for input channel 4. + * @note In 32-bit timer implementations returned captured value can be between 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note Macro IS_TIM_CC4_INSTANCE(TIMx) can be used to check whether or not + * input channel 4 is supported by a timer instance. + * @note If dithering is activated, pay attention to the returned value interpretation. + * @rmtoll CCR4 CCR4 LL_TIM_IC_GetCaptureCH4 + * @param TIMx Timer instance + * @retval CapturedValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_TIM_IC_GetCaptureCH4(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR4)); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_Clock_Selection Counter clock selection + * @{ + */ +/** + * @brief Enable external clock mode 2. + * @note When external clock mode 2 is enabled the counter is clocked by any active edge on the ETRF signal. + * @note Macro IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports external clock mode2. + * @rmtoll SMCR ECE LL_TIM_EnableExternalClock + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableExternalClock(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->SMCR, TIM_SMCR_ECE); +} + +/** + * @brief Disable external clock mode 2. + * @note Macro IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports external clock mode2. + * @rmtoll SMCR ECE LL_TIM_DisableExternalClock + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableExternalClock(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->SMCR, TIM_SMCR_ECE); +} + +/** + * @brief Indicate whether external clock mode 2 is enabled. + * @note Macro IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports external clock mode2. + * @rmtoll SMCR ECE LL_TIM_IsEnabledExternalClock + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledExternalClock(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SMCR, TIM_SMCR_ECE) == (TIM_SMCR_ECE)) ? 1UL : 0UL); +} + +/** + * @brief Set the clock source of the counter clock. + * @note when selected clock source is external clock mode 1, the timer input + * the external clock is applied is selected by calling the @ref LL_TIM_SetTriggerInput() + * function. This timer input must be configured by calling + * the @ref LL_TIM_IC_Config() function. + * @note Macro IS_TIM_CLOCKSOURCE_ETRMODE1_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports external clock mode1. + * @note Macro IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports external clock mode2. + * @rmtoll SMCR SMS LL_TIM_SetClockSource\n + * SMCR ECE LL_TIM_SetClockSource + * @param TIMx Timer instance + * @param ClockSource This parameter can be one of the following values: + * @arg @ref LL_TIM_CLOCKSOURCE_INTERNAL + * @arg @ref LL_TIM_CLOCKSOURCE_EXT_MODE1 + * @arg @ref LL_TIM_CLOCKSOURCE_EXT_MODE2 + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetClockSource(TIM_TypeDef *TIMx, uint32_t ClockSource) +{ + MODIFY_REG(TIMx->SMCR, TIM_SMCR_SMS | TIM_SMCR_ECE, ClockSource); +} + +/** + * @brief Set the encoder interface mode. + * @note Macro IS_TIM_ENCODER_INTERFACE_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports the encoder mode. + * @rmtoll SMCR SMS LL_TIM_SetEncoderMode + * @param TIMx Timer instance + * @param EncoderMode This parameter can be one of the following values: + * @arg @ref LL_TIM_ENCODERMODE_X2_TI1 + * @arg @ref LL_TIM_ENCODERMODE_X2_TI2 + * @arg @ref LL_TIM_ENCODERMODE_X4_TI12 + * @arg @ref LL_TIM_ENCODERMODE_CLOCKPLUSDIRECTION_X2 + * @arg @ref LL_TIM_ENCODERMODE_CLOCKPLUSDIRECTION_X1 + * @arg @ref LL_TIM_ENCODERMODE_DIRECTIONALCLOCK_X2 + * @arg @ref LL_TIM_ENCODERMODE_DIRECTIONALCLOCK_X1_TI12 + * @arg @ref LL_TIM_ENCODERMODE_X1_TI1 + * @arg @ref LL_TIM_ENCODERMODE_X1_TI2 + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetEncoderMode(TIM_TypeDef *TIMx, uint32_t EncoderMode) +{ + MODIFY_REG(TIMx->SMCR, TIM_SMCR_SMS, EncoderMode); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_Timer_Synchronization Timer synchronisation configuration + * @{ + */ +/** + * @brief Set the trigger output (TRGO) used for timer synchronization . + * @note Macro IS_TIM_MASTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance can operate as a master timer. + * @rmtoll CR2 MMS LL_TIM_SetTriggerOutput + * @param TIMx Timer instance + * @param TimerSynchronization This parameter can be one of the following values: + * @arg @ref LL_TIM_TRGO_RESET + * @arg @ref LL_TIM_TRGO_ENABLE + * @arg @ref LL_TIM_TRGO_UPDATE + * @arg @ref LL_TIM_TRGO_CC1IF + * @arg @ref LL_TIM_TRGO_OC1REF + * @arg @ref LL_TIM_TRGO_OC2REF + * @arg @ref LL_TIM_TRGO_OC3REF + * @arg @ref LL_TIM_TRGO_OC4REF + * @arg @ref LL_TIM_TRGO_ENCODERCLK + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetTriggerOutput(TIM_TypeDef *TIMx, uint32_t TimerSynchronization) +{ + MODIFY_REG(TIMx->CR2, TIM_CR2_MMS, TimerSynchronization); +} + +/** + * @brief Set the trigger output 2 (TRGO2) used for ADC synchronization . + * @note Macro IS_TIM_TRGO2_INSTANCE(TIMx) can be used to check + * whether or not a timer instance can be used for ADC synchronization. + * @rmtoll CR2 MMS2 LL_TIM_SetTriggerOutput2 + * @param TIMx Timer Instance + * @param ADCSynchronization This parameter can be one of the following values: + * @arg @ref LL_TIM_TRGO2_RESET + * @arg @ref LL_TIM_TRGO2_ENABLE + * @arg @ref LL_TIM_TRGO2_UPDATE + * @arg @ref LL_TIM_TRGO2_CC1F + * @arg @ref LL_TIM_TRGO2_OC1 + * @arg @ref LL_TIM_TRGO2_OC2 + * @arg @ref LL_TIM_TRGO2_OC3 + * @arg @ref LL_TIM_TRGO2_OC4 + * @arg @ref LL_TIM_TRGO2_OC5 + * @arg @ref LL_TIM_TRGO2_OC6 + * @arg @ref LL_TIM_TRGO2_OC4_RISINGFALLING + * @arg @ref LL_TIM_TRGO2_OC6_RISINGFALLING + * @arg @ref LL_TIM_TRGO2_OC4_RISING_OC6_RISING + * @arg @ref LL_TIM_TRGO2_OC4_RISING_OC6_FALLING + * @arg @ref LL_TIM_TRGO2_OC5_RISING_OC6_RISING + * @arg @ref LL_TIM_TRGO2_OC5_RISING_OC6_FALLING + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetTriggerOutput2(TIM_TypeDef *TIMx, uint32_t ADCSynchronization) +{ + MODIFY_REG(TIMx->CR2, TIM_CR2_MMS2, ADCSynchronization); +} + +/** + * @brief Set the synchronization mode of a slave timer. + * @note Macro IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not + * a timer instance can operate as a slave timer. + * @rmtoll SMCR SMS LL_TIM_SetSlaveMode + * @param TIMx Timer instance + * @param SlaveMode This parameter can be one of the following values: + * @arg @ref LL_TIM_SLAVEMODE_DISABLED + * @arg @ref LL_TIM_SLAVEMODE_RESET + * @arg @ref LL_TIM_SLAVEMODE_GATED + * @arg @ref LL_TIM_SLAVEMODE_TRIGGER + * @arg @ref LL_TIM_SLAVEMODE_COMBINED_RESETTRIGGER + * @arg @ref LL_TIM_SLAVEMODE_COMBINED_GATEDRESET + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetSlaveMode(TIM_TypeDef *TIMx, uint32_t SlaveMode) +{ + MODIFY_REG(TIMx->SMCR, TIM_SMCR_SMS, SlaveMode); +} + +/** + * @brief Set the selects the trigger input to be used to synchronize the counter. + * @note Macro IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not + * a timer instance can operate as a slave timer. + * @rmtoll SMCR TS LL_TIM_SetTriggerInput + * @param TIMx Timer instance + * @param TriggerInput This parameter can be one of the following values: + * @arg @ref LL_TIM_TS_ITR0 + * @arg @ref LL_TIM_TS_ITR1 + * @arg @ref LL_TIM_TS_ITR2 + * @arg @ref LL_TIM_TS_ITR3 + * @arg @ref LL_TIM_TS_ITR4 + * @arg @ref LL_TIM_TS_ITR5 + * @arg @ref LL_TIM_TS_ITR6 + * @arg @ref LL_TIM_TS_ITR7 + * @arg @ref LL_TIM_TS_ITR8 + * @arg @ref LL_TIM_TS_ITR9 + * @arg @ref LL_TIM_TS_ITR10 + * @arg @ref LL_TIM_TS_ITR11 + * @arg @ref LL_TIM_TS_ITR12 + * @arg @ref LL_TIM_TS_TI1F_ED + * @arg @ref LL_TIM_TS_TI1FP1 + * @arg @ref LL_TIM_TS_TI2FP2 + * @arg @ref LL_TIM_TS_ETRF + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetTriggerInput(TIM_TypeDef *TIMx, uint32_t TriggerInput) +{ + MODIFY_REG(TIMx->SMCR, TIM_SMCR_TS, TriggerInput); +} + +/** + * @brief Enable the Master/Slave mode. + * @note Macro IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not + * a timer instance can operate as a slave timer. + * @rmtoll SMCR MSM LL_TIM_EnableMasterSlaveMode + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableMasterSlaveMode(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->SMCR, TIM_SMCR_MSM); +} + +/** + * @brief Disable the Master/Slave mode. + * @note Macro IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not + * a timer instance can operate as a slave timer. + * @rmtoll SMCR MSM LL_TIM_DisableMasterSlaveMode + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableMasterSlaveMode(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->SMCR, TIM_SMCR_MSM); +} + +/** + * @brief Indicates whether the Master/Slave mode is enabled. + * @note Macro IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not + * a timer instance can operate as a slave timer. + * @rmtoll SMCR MSM LL_TIM_IsEnabledMasterSlaveMode + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledMasterSlaveMode(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SMCR, TIM_SMCR_MSM) == (TIM_SMCR_MSM)) ? 1UL : 0UL); +} + +/** + * @brief Configure the external trigger (ETR) input. + * @note Macro IS_TIM_ETR_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an external trigger input. + * @rmtoll SMCR ETP LL_TIM_ConfigETR\n + * SMCR ETPS LL_TIM_ConfigETR\n + * SMCR ETF LL_TIM_ConfigETR + * @param TIMx Timer instance + * @param ETRPolarity This parameter can be one of the following values: + * @arg @ref LL_TIM_ETR_POLARITY_NONINVERTED + * @arg @ref LL_TIM_ETR_POLARITY_INVERTED + * @param ETRPrescaler This parameter can be one of the following values: + * @arg @ref LL_TIM_ETR_PRESCALER_DIV1 + * @arg @ref LL_TIM_ETR_PRESCALER_DIV2 + * @arg @ref LL_TIM_ETR_PRESCALER_DIV4 + * @arg @ref LL_TIM_ETR_PRESCALER_DIV8 + * @param ETRFilter This parameter can be one of the following values: + * @arg @ref LL_TIM_ETR_FILTER_FDIV1 + * @arg @ref LL_TIM_ETR_FILTER_FDIV1_N2 + * @arg @ref LL_TIM_ETR_FILTER_FDIV1_N4 + * @arg @ref LL_TIM_ETR_FILTER_FDIV1_N8 + * @arg @ref LL_TIM_ETR_FILTER_FDIV2_N6 + * @arg @ref LL_TIM_ETR_FILTER_FDIV2_N8 + * @arg @ref LL_TIM_ETR_FILTER_FDIV4_N6 + * @arg @ref LL_TIM_ETR_FILTER_FDIV4_N8 + * @arg @ref LL_TIM_ETR_FILTER_FDIV8_N6 + * @arg @ref LL_TIM_ETR_FILTER_FDIV8_N8 + * @arg @ref LL_TIM_ETR_FILTER_FDIV16_N5 + * @arg @ref LL_TIM_ETR_FILTER_FDIV16_N6 + * @arg @ref LL_TIM_ETR_FILTER_FDIV16_N8 + * @arg @ref LL_TIM_ETR_FILTER_FDIV32_N5 + * @arg @ref LL_TIM_ETR_FILTER_FDIV32_N6 + * @arg @ref LL_TIM_ETR_FILTER_FDIV32_N8 + * @retval None + */ +__STATIC_INLINE void LL_TIM_ConfigETR(TIM_TypeDef *TIMx, uint32_t ETRPolarity, uint32_t ETRPrescaler, + uint32_t ETRFilter) +{ + MODIFY_REG(TIMx->SMCR, TIM_SMCR_ETP | TIM_SMCR_ETPS | TIM_SMCR_ETF, ETRPolarity | ETRPrescaler | ETRFilter); +} + +/** + * @brief Select the external trigger (ETR) input source. + * @note Macro IS_TIM_ETRSEL_INSTANCE(TIMx) can be used to check whether or + * not a timer instance supports ETR source selection. + * @rmtoll AF1 ETRSEL LL_TIM_SetETRSource + * @param TIMx Timer instance + * @param ETRSource This parameter can be one of the following values: + * + * TIM1: any combination of ETR_RMP where + * + * @arg @ref LL_TIM_TIM1_ETRSOURCE_GPIO + * @arg @ref LL_TIM_TIM1_ETRSOURCE_COMP1 (*) + * @arg @ref LL_TIM_TIM1_ETRSOURCE_ADC1_AWD1 + * @arg @ref LL_TIM_TIM1_ETRSOURCE_ADC1_AWD2 + * @arg @ref LL_TIM_TIM1_ETRSOURCE_ADC1_AWD3 + * + * TIM2: any combination of ETR_RMP where + * + * @arg @ref LL_TIM_TIM2_ETRSOURCE_GPIO + * @arg @ref LL_TIM_TIM2_ETRSOURCE_COMP1 (*) + * @arg @ref LL_TIM_TIM2_ETRSOURCE_LSE + * @arg @ref LL_TIM_TIM2_ETRSOURCE_SAI1_FSA (*) + * @arg @ref LL_TIM_TIM2_ETRSOURCE_SAI1_FSB (*) + * @arg @ref LL_TIM_TIM2_ETRSOURCE_TIM3_ETR + * @arg @ref LL_TIM_TIM2_ETRSOURCE_TIM4_ETR (*) + * @arg @ref LL_TIM_TIM2_ETRSOURCE_TIM5_ETR (*) + * @arg @ref LL_TIM_TIM2_ETRSOURCE_ETH_PPS (*) + + * + * TIM3: any combination of ETR_RMP where + * + * @arg @ref LL_TIM_TIM3_ETRSOURCE_GPIO + * @arg @ref LL_TIM_TIM3_ETRSOURCE_COMP1 (*) + * @arg @ref LL_TIM_TIM3_ETRSOURCE_TIM2_ETR + * @arg @ref LL_TIM_TIM3_ETRSOURCE_TIM4_ETR (*) + * @arg @ref LL_TIM_TIM3_ETRSOURCE_TIM5_ETR (*) + * @arg @ref LL_TIM_TIM3_ETRSOURCE_ETH_PPS (*) + * + * TIM4: any combination of ETR_RMP where (**) + * + * @arg @ref LL_TIM_TIM4_ETRSOURCE_GPIO + * @arg @ref LL_TIM_TIM4_ETRSOURCE_TIM2_ETR + * @arg @ref LL_TIM_TIM4_ETRSOURCE_TIM3_ETR + * @arg @ref LL_TIM_TIM4_ETRSOURCE_TIM5_ETR + * + * TIM5: any combination of ETR_RMP where (**) + * + * @arg @ref LL_TIM_TIM5_ETRSOURCE_GPIO + * @arg @ref LL_TIM_TIM5_ETRSOURCE_SAI2_FSA + * @arg @ref LL_TIM_TIM5_ETRSOURCE_SAI2_FSB + * @arg @ref LL_TIM_TIM5_ETRSOURCE_TIM2_ETR + * @arg @ref LL_TIM_TIM5_ETRSOURCE_TIM3_ETR + * @arg @ref LL_TIM_TIM5_ETRSOURCE_TIM4_ETR + * + * TIM8: any combination of ETR_RMP where (**) + * + * . . ETR_RMP can be one of the following values + * @arg @ref LL_TIM_TIM8_ETRSOURCE_GPIO + * @arg @ref LL_TIM_TIM8_ETRSOURCE_ADC2_AWD1 + * @arg @ref LL_TIM_TIM8_ETRSOURCE_ADC2_AWD2 + * @arg @ref LL_TIM_TIM8_ETRSOURCE_ADC2_AWD3 + * + * (*) Value not defined in all devices. \n + * (**) Timer instance not available on all devices. \n + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetETRSource(TIM_TypeDef *TIMx, uint32_t ETRSource) +{ + MODIFY_REG(TIMx->AF1, TIMx_AF1_ETRSEL, ETRSource); +} + +/** + * @brief Enable SMS preload. + * @note Macro IS_TIM_SMS_PRELOAD_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports the preload of SMS field in SMCR register. + * @rmtoll SMCR SMSPE LL_TIM_EnableSMSPreload + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableSMSPreload(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->SMCR, TIM_SMCR_SMSPE); +} + +/** + * @brief Disable SMS preload. + * @note Macro IS_TIM_SMS_PRELOAD_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports the preload of SMS field in SMCR register. + * @rmtoll SMCR SMSPE LL_TIM_DisableSMSPreload + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableSMSPreload(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->SMCR, TIM_SMCR_SMSPE); +} + +/** + * @brief Indicate whether SMS preload is enabled. + * @note Macro IS_TIM_SMS_PRELOAD_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports the preload of SMS field in SMCR register. + * @rmtoll SMCR SMSPE LL_TIM_IsEnabledSMSPreload + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledSMSPreload(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SMCR, TIM_SMCR_SMSPE) == (TIM_SMCR_SMSPE)) ? 1UL : 0UL); +} + +/** + * @brief Set the preload source of SMS. + * @note Macro IS_TIM_SMS_PRELOAD_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports the preload of SMS field in SMCR register. + * @rmtoll SMCR SMSPS LL_TIM_SetSMSPreloadSource\n + * @param TIMx Timer instance + * @param PreloadSource This parameter can be one of the following values: + * @arg @ref LL_TIM_SMSPS_TIMUPDATE + * @arg @ref LL_TIM_SMSPS_INDEX + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetSMSPreloadSource(TIM_TypeDef *TIMx, uint32_t PreloadSource) +{ + MODIFY_REG(TIMx->SMCR, TIM_SMCR_SMSPS, PreloadSource); +} + +/** + * @brief Get the preload source of SMS. + * @note Macro IS_TIM_SMS_PRELOAD_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports the preload of SMS field in SMCR register. + * @rmtoll SMCR SMSPS LL_TIM_GetSMSPreloadSource\n + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_SMSPS_TIMUPDATE + * @arg @ref LL_TIM_SMSPS_INDEX + */ +__STATIC_INLINE uint32_t LL_TIM_GetSMSPreloadSource(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_BIT(TIMx->SMCR, TIM_SMCR_SMSPS)); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_Break_Function Break function configuration + * @{ + */ +/** + * @brief Enable the break function. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR BKE LL_TIM_EnableBRK + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableBRK(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->BDTR, TIM_BDTR_BKE); +} + +/** + * @brief Disable the break function. + * @rmtoll BDTR BKE LL_TIM_DisableBRK + * @param TIMx Timer instance + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableBRK(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->BDTR, TIM_BDTR_BKE); +} + +/** + * @brief Configure the break input. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @note Bidirectional mode is only supported by advanced timer instances. + * Macro IS_TIM_ADVANCED_INSTANCE(TIMx) can be used to check whether or not + * a timer instance is an advanced-control timer. + * @note In bidirectional mode (BKBID bit set), the Break input is configured both + * in input mode and in open drain output mode. Any active Break event will + * assert a low logic level on the Break input to indicate an internal break + * event to external devices. + * @note When bidirectional mode isn't supported, BreakAFMode must be set to + * LL_TIM_BREAK_AFMODE_INPUT. + * @rmtoll BDTR BKP LL_TIM_ConfigBRK\n + * BDTR BKF LL_TIM_ConfigBRK\n + * BDTR BKBID LL_TIM_ConfigBRK + * @param TIMx Timer instance + * @param BreakPolarity This parameter can be one of the following values: + * @arg @ref LL_TIM_BREAK_POLARITY_LOW + * @arg @ref LL_TIM_BREAK_POLARITY_HIGH + * @param BreakFilter This parameter can be one of the following values: + * @arg @ref LL_TIM_BREAK_FILTER_FDIV1 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV1_N2 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV1_N4 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV1_N8 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV2_N6 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV2_N8 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV4_N6 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV4_N8 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV8_N6 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV8_N8 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV16_N5 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV16_N6 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV16_N8 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV32_N5 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV32_N6 + * @arg @ref LL_TIM_BREAK_FILTER_FDIV32_N8 + * @param BreakAFMode This parameter can be one of the following values: + * @arg @ref LL_TIM_BREAK_AFMODE_INPUT + * @arg @ref LL_TIM_BREAK_AFMODE_BIDIRECTIONAL + * @retval None + */ +__STATIC_INLINE void LL_TIM_ConfigBRK(TIM_TypeDef *TIMx, uint32_t BreakPolarity, uint32_t BreakFilter, + uint32_t BreakAFMode) +{ + MODIFY_REG(TIMx->BDTR, TIM_BDTR_BKP | TIM_BDTR_BKF | TIM_BDTR_BKBID, BreakPolarity | BreakFilter | BreakAFMode); +} + +/** + * @brief Disarm the break input (when it operates in bidirectional mode). + * @note The break input can be disarmed only when it is configured in + * bidirectional mode and when when MOE is reset. + * @note Purpose is to be able to have the input voltage back to high-state, + * whatever the time constant on the output . + * @rmtoll BDTR BKDSRM LL_TIM_DisarmBRK + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisarmBRK(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->BDTR, TIM_BDTR_BKDSRM); +} + +/** + * @brief Re-arm the break input (when it operates in bidirectional mode). + * @note The Break input is automatically armed as soon as MOE bit is set. + * @rmtoll BDTR BKDSRM LL_TIM_ReArmBRK + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ReArmBRK(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->BDTR, TIM_BDTR_BKDSRM); +} + +/** + * @brief Enable the break 2 function. + * @note Macro IS_TIM_BKIN2_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a second break input. + * @rmtoll BDTR BK2E LL_TIM_EnableBRK2 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableBRK2(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->BDTR, TIM_BDTR_BK2E); +} + +/** + * @brief Disable the break 2 function. + * @note Macro IS_TIM_BKIN2_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a second break input. + * @rmtoll BDTR BK2E LL_TIM_DisableBRK2 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableBRK2(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->BDTR, TIM_BDTR_BK2E); +} + +/** + * @brief Configure the break 2 input. + * @note Macro IS_TIM_BKIN2_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a second break input. + * @note Bidirectional mode is only supported by advanced timer instances. + * Macro IS_TIM_ADVANCED_INSTANCE(TIMx) can be used to check whether or not + * a timer instance is an advanced-control timer. + * @note In bidirectional mode (BK2BID bit set), the Break 2 input is configured both + * in input mode and in open drain output mode. Any active Break event will + * assert a low logic level on the Break 2 input to indicate an internal break + * event to external devices. + * @note When bidirectional mode isn't supported, Break2AFMode must be set to + * LL_TIM_BREAK2_AFMODE_INPUT. + * @rmtoll BDTR BK2P LL_TIM_ConfigBRK2\n + * BDTR BK2F LL_TIM_ConfigBRK2\n + * BDTR BK2BID LL_TIM_ConfigBRK2 + * @param TIMx Timer instance + * @param Break2Polarity This parameter can be one of the following values: + * @arg @ref LL_TIM_BREAK2_POLARITY_LOW + * @arg @ref LL_TIM_BREAK2_POLARITY_HIGH + * @param Break2Filter This parameter can be one of the following values: + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV1 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV1_N2 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV1_N4 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV1_N8 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV2_N6 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV2_N8 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV4_N6 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV4_N8 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV8_N6 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV8_N8 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV16_N5 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV16_N6 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV16_N8 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV32_N5 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV32_N6 + * @arg @ref LL_TIM_BREAK2_FILTER_FDIV32_N8 + * @param Break2AFMode This parameter can be one of the following values: + * @arg @ref LL_TIM_BREAK2_AFMODE_INPUT + * @arg @ref LL_TIM_BREAK2_AFMODE_BIDIRECTIONAL + * @retval None + */ +__STATIC_INLINE void LL_TIM_ConfigBRK2(TIM_TypeDef *TIMx, uint32_t Break2Polarity, uint32_t Break2Filter, + uint32_t Break2AFMode) +{ + MODIFY_REG(TIMx->BDTR, TIM_BDTR_BK2P | TIM_BDTR_BK2F | TIM_BDTR_BK2BID, Break2Polarity | Break2Filter | Break2AFMode); +} + +/** + * @brief Disarm the break 2 input (when it operates in bidirectional mode). + * @note The break 2 input can be disarmed only when it is configured in + * bidirectional mode and when when MOE is reset. + * @note Purpose is to be able to have the input voltage back to high-state, + * whatever the time constant on the output. + * @rmtoll BDTR BK2DSRM LL_TIM_DisarmBRK2 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisarmBRK2(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->BDTR, TIM_BDTR_BK2DSRM); +} + +/** + * @brief Re-arm the break 2 input (when it operates in bidirectional mode). + * @note The Break 2 input is automatically armed as soon as MOE bit is set. + * @rmtoll BDTR BK2DSRM LL_TIM_ReArmBRK2 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ReArmBRK2(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->BDTR, TIM_BDTR_BK2DSRM); +} + +/** + * @brief Select the outputs off state (enabled v.s. disabled) in Idle and Run modes. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR OSSI LL_TIM_SetOffStates\n + * BDTR OSSR LL_TIM_SetOffStates + * @param TIMx Timer instance + * @param OffStateIdle This parameter can be one of the following values: + * @arg @ref LL_TIM_OSSI_DISABLE + * @arg @ref LL_TIM_OSSI_ENABLE + * @param OffStateRun This parameter can be one of the following values: + * @arg @ref LL_TIM_OSSR_DISABLE + * @arg @ref LL_TIM_OSSR_ENABLE + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetOffStates(TIM_TypeDef *TIMx, uint32_t OffStateIdle, uint32_t OffStateRun) +{ + MODIFY_REG(TIMx->BDTR, TIM_BDTR_OSSI | TIM_BDTR_OSSR, OffStateIdle | OffStateRun); +} + +/** + * @brief Enable automatic output (MOE can be set by software or automatically when a break input is active). + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR AOE LL_TIM_EnableAutomaticOutput + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableAutomaticOutput(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->BDTR, TIM_BDTR_AOE); +} + +/** + * @brief Disable automatic output (MOE can be set only by software). + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR AOE LL_TIM_DisableAutomaticOutput + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableAutomaticOutput(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->BDTR, TIM_BDTR_AOE); +} + +/** + * @brief Indicate whether automatic output is enabled. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR AOE LL_TIM_IsEnabledAutomaticOutput + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledAutomaticOutput(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->BDTR, TIM_BDTR_AOE) == (TIM_BDTR_AOE)) ? 1UL : 0UL); +} + +/** + * @brief Enable the outputs (set the MOE bit in TIMx_BDTR register). + * @note The MOE bit in TIMx_BDTR register allows to enable /disable the outputs by + * software and is reset in case of break or break2 event + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR MOE LL_TIM_EnableAllOutputs + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableAllOutputs(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->BDTR, TIM_BDTR_MOE); +} + +/** + * @brief Disable the outputs (reset the MOE bit in TIMx_BDTR register). + * @note The MOE bit in TIMx_BDTR register allows to enable /disable the outputs by + * software and is reset in case of break or break2 event. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR MOE LL_TIM_DisableAllOutputs + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableAllOutputs(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->BDTR, TIM_BDTR_MOE); +} + +/** + * @brief Indicates whether outputs are enabled. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR MOE LL_TIM_IsEnabledAllOutputs + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledAllOutputs(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->BDTR, TIM_BDTR_MOE) == (TIM_BDTR_MOE)) ? 1UL : 0UL); +} + +/** + * @brief Enable the signals connected to the designated timer break input. + * @note Macro IS_TIM_BREAKSOURCE_INSTANCE(TIMx) can be used to check whether + * or not a timer instance allows for break input selection. + * @rmtoll AF1 BKINE LL_TIM_EnableBreakInputSource\n + * AF1 BKCMP1E LL_TIM_EnableBreakInputSource\n + * AF2 BK2INE LL_TIM_EnableBreakInputSource\n + * AF2 BK2CMP1E LL_TIM_EnableBreakInputSource\n + * @param TIMx Timer instance + * @param BreakInput This parameter can be one of the following values: + * @arg @ref LL_TIM_BREAK_INPUT_BKIN + * @arg @ref LL_TIM_BREAK_INPUT_BKIN2 + * @param Source This parameter can be one of the following values: + * @arg @ref LL_TIM_BKIN_SOURCE_BKIN + * @arg @ref LL_TIM_BKIN_SOURCE_BKCOMP1 (*) + * + * (*) Value not defined in all devices. + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableBreakInputSource(TIM_TypeDef *TIMx, uint32_t BreakInput, uint32_t Source) +{ + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->AF1) + BreakInput)); + SET_BIT(*pReg, Source); +} + +/** + * @brief Disable the signals connected to the designated timer break input. + * @note Macro IS_TIM_BREAKSOURCE_INSTANCE(TIMx) can be used to check whether + * or not a timer instance allows for break input selection. + * @rmtoll AF1 BKINE LL_TIM_DisableBreakInputSource\n + * AF1 BKCMP1E LL_TIM_DisableBreakInputSource\n + * AF2 BK2INE LL_TIM_DisableBreakInputSource\n + * AF2 BK2CMP1E LL_TIM_DisableBreakInputSource\n + * @param TIMx Timer instance + * @param BreakInput This parameter can be one of the following values: + * @arg @ref LL_TIM_BREAK_INPUT_BKIN + * @arg @ref LL_TIM_BREAK_INPUT_BKIN2 + * @param Source This parameter can be one of the following values: + * @arg @ref LL_TIM_BKIN_SOURCE_BKIN + * @arg @ref LL_TIM_BKIN_SOURCE_BKCOMP1 (*) + * + * (*) Value not defined in all devices. + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableBreakInputSource(TIM_TypeDef *TIMx, uint32_t BreakInput, uint32_t Source) +{ + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->AF1) + BreakInput)); + CLEAR_BIT(*pReg, Source); +} + +/** + * @brief Set the polarity of the break signal for the timer break input. + * @note Macro IS_TIM_BREAKSOURCE_INSTANCE(TIMx) can be used to check whether + * or not a timer instance allows for break input selection. + * @rmtoll AF1 BKINP LL_TIM_SetBreakInputSourcePolarity\n + * AF1 BKCMP1P LL_TIM_SetBreakInputSourcePolarity\n + * AF2 BK2INP LL_TIM_SetBreakInputSourcePolarity\n + * AF2 BK2CMP1P LL_TIM_SetBreakInputSourcePolarity\n + * @param TIMx Timer instance + * @param BreakInput This parameter can be one of the following values: + * @arg @ref LL_TIM_BREAK_INPUT_BKIN + * @arg @ref LL_TIM_BREAK_INPUT_BKIN2 + * @param Source This parameter can be one of the following values: + * @arg @ref LL_TIM_BKIN_SOURCE_BKIN + * @arg @ref LL_TIM_BKIN_SOURCE_BKCOMP1 (*) + * @param Polarity This parameter can be one of the following values: + * @arg @ref LL_TIM_BKIN_POLARITY_LOW + * @arg @ref LL_TIM_BKIN_POLARITY_HIGH + * + * (*) Value not defined in all devices. + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetBreakInputSourcePolarity(TIM_TypeDef *TIMx, uint32_t BreakInput, uint32_t Source, + uint32_t Polarity) +{ + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->AF1) + BreakInput)); + MODIFY_REG(*pReg, (TIMx_AF1_BKINP << TIM_POSITION_BRK_SOURCE), (Polarity << TIM_POSITION_BRK_SOURCE)); +} +/** + * @brief Enable asymmetrical deadtime. + * @note Macro IS_TIM_DEADTIME_ASYMMETRICAL_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides asymmetrical deadtime. + * @rmtoll DTR2 DTAE LL_TIM_EnableAsymmetricalDeadTime + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableAsymmetricalDeadTime(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DTR2, TIM_DTR2_DTAE); +} + +/** + * @brief Disable asymmetrical dead-time. + * @note Macro IS_TIM_DEADTIME_ASYMMETRICAL_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides asymmetrical deadtime. + * @rmtoll DTR2 DTAE LL_TIM_DisableAsymmetricalDeadTime + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableAsymmetricalDeadTime(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DTR2, TIM_DTR2_DTAE); +} + +/** + * @brief Indicates whether asymmetrical deadtime is activated. + * @note Macro IS_TIM_DEADTIME_ASYMMETRICAL_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides asymmetrical deadtime. + * @rmtoll DTR2 DTAE LL_TIM_IsEnabledAsymmetricalDeadTime + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledAsymmetricalDeadTime(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DTR2, TIM_DTR2_DTAE) == (TIM_DTR2_DTAE)) ? 1UL : 0UL); +} + +/** + * @brief Set the falling edge dead-time delay (delay inserted between the falling edge of the OCxREF signal and the + * rising edge of OCxN signals). + * @note Macro IS_TIM_DEADTIME_ASYMMETRICAL_INSTANCE(TIMx) can be used to check whether or not + * asymmetrical dead-time insertion feature is supported by a timer instance. + * @note Helper macro @ref __LL_TIM_CALC_DEADTIME can be used to calculate the DeadTime parameter + * @note This bit-field can not be modified as long as LOCK level 1, 2 or 3 has been programmed + * (LOCK bits in TIMx_BDTR register). + * @rmtoll DTR2 DTGF LL_TIM_SetFallingDeadTime + * @param TIMx Timer instance + * @param DeadTime between Min_Data=0 and Max_Data=255 + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetFallingDeadTime(TIM_TypeDef *TIMx, uint32_t DeadTime) +{ + MODIFY_REG(TIMx->DTR2, TIM_DTR2_DTGF, DeadTime); +} + +/** + * @brief Get the falling edge dead-time delay (delay inserted between the falling edge of the OCxREF signal and + * the rising edge of OCxN signals). + * @note Macro IS_TIM_DEADTIME_ASYMMETRICAL_INSTANCE(TIMx) can be used to check whether or not + * asymmetrical dead-time insertion feature is supported by a timer instance. + * @note This bit-field can not be modified as long as LOCK level 1, 2 or 3 has been programmed + * (LOCK bits in TIMx_BDTR register). + * @rmtoll DTR2 DTGF LL_TIM_GetFallingDeadTime + * @param TIMx Timer instance + * @retval Returned value can be between Min_Data=0 and Max_Data=255: + */ +__STATIC_INLINE uint32_t LL_TIM_GetFallingDeadTime(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_BIT(TIMx->DTR2, TIM_DTR2_DTGF)); +} + +/** + * @brief Enable deadtime preload. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides deadtime preload. + * @rmtoll DTR2 DTPE LL_TIM_EnableDeadTimePreload + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableDeadTimePreload(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DTR2, TIM_DTR2_DTPE); +} + +/** + * @brief Disable dead-time preload. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides deadtime preload. + * @rmtoll DTR2 DTPE LL_TIM_DisableDeadTimePreload + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableDeadTimePreload(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DTR2, TIM_DTR2_DTPE); +} + +/** + * @brief Indicates whether deadtime preload is activated. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides deadtime preload. + * @rmtoll DTR2 DTPE LL_TIM_IsEnabledDeadTimePreload + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDeadTimePreload(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DTR2, TIM_DTR2_DTPE) == (TIM_DTR2_DTPE)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_DMA_Burst_Mode DMA burst mode configuration + * @{ + */ +/** + * @brief Configures the timer DMA burst feature. + * @note Macro IS_TIM_DMABURST_INSTANCE(TIMx) can be used to check whether or + * not a timer instance supports the DMA burst mode. + * @rmtoll DCR DBL LL_TIM_ConfigDMABurst\n + * DCR DBA LL_TIM_ConfigDMABurst + * @param TIMx Timer instance + * @param DMABurstBaseAddress This parameter can be one of the following values: + * @arg @ref LL_TIM_DMABURST_BASEADDR_CR1 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CR2 + * @arg @ref LL_TIM_DMABURST_BASEADDR_SMCR + * @arg @ref LL_TIM_DMABURST_BASEADDR_DIER + * @arg @ref LL_TIM_DMABURST_BASEADDR_SR + * @arg @ref LL_TIM_DMABURST_BASEADDR_EGR + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCMR1 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCMR2 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCER + * @arg @ref LL_TIM_DMABURST_BASEADDR_CNT + * @arg @ref LL_TIM_DMABURST_BASEADDR_PSC + * @arg @ref LL_TIM_DMABURST_BASEADDR_ARR + * @arg @ref LL_TIM_DMABURST_BASEADDR_RCR + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCR1 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCR2 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCR3 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCR4 + * @arg @ref LL_TIM_DMABURST_BASEADDR_BDTR + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCR5 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCR6 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCMR3 + * @arg @ref LL_TIM_DMABURST_BASEADDR_DTR2 + * @arg @ref LL_TIM_DMABURST_BASEADDR_ECR + * @arg @ref LL_TIM_DMABURST_BASEADDR_TISEL + * @arg @ref LL_TIM_DMABURST_BASEADDR_AF1 + * @arg @ref LL_TIM_DMABURST_BASEADDR_AF2 + * @param DMABurstLength This parameter can be one of the following values: + * @arg @ref LL_TIM_DMABURST_LENGTH_1TRANSFER + * @arg @ref LL_TIM_DMABURST_LENGTH_2TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_3TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_4TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_5TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_6TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_7TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_8TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_9TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_10TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_11TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_12TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_13TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_14TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_15TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_16TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_17TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_18TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_19TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_20TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_21TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_22TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_23TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_24TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_25TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_26TRANSFERS + * @param DMABurstSource This parameter can be one of the following values: + * @arg @ref LL_TIM_DMA_UPDATE + * @arg @ref LL_TIM_DMA_CC1 + * @arg @ref LL_TIM_DMA_CC2 + * @arg @ref LL_TIM_DMA_CC3 + * @arg @ref LL_TIM_DMA_CC4 + * @arg @ref LL_TIM_DMA_COM + * @arg @ref LL_TIM_DMA_TRIGGER + * @retval None + */ +__STATIC_INLINE void LL_TIM_ConfigDMABurst(TIM_TypeDef *TIMx, uint32_t DMABurstBaseAddress, uint32_t DMABurstLength, + uint32_t DMABurstSource) +{ + MODIFY_REG(TIMx->DCR, (TIM_DCR_DBL | TIM_DCR_DBA | TIM_DCR_DBSS), + (DMABurstBaseAddress | DMABurstLength | DMABurstSource)); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_Encoder Encoder configuration + * @{ + */ + +/** + * @brief Enable encoder index. + * @note Macro IS_TIM_INDEX_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an index input. + * @rmtoll ECR IE LL_TIM_EnableEncoderIndex + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableEncoderIndex(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->ECR, TIM_ECR_IE); +} + +/** + * @brief Disable encoder index. + * @note Macro IS_TIM_INDEX_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an index input. + * @rmtoll ECR IE LL_TIM_DisableEncoderIndex + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableEncoderIndex(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->ECR, TIM_ECR_IE); +} + +/** + * @brief Indicate whether encoder index is enabled. + * @note Macro IS_TIM_INDEX_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an index input. + * @rmtoll ECR IE LL_TIM_IsEnabledEncoderIndex + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledEncoderIndex(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->ECR, TIM_ECR_IE) == (TIM_ECR_IE)) ? 1U : 0U); +} + +/** + * @brief Set index direction + * @note Macro IS_TIM_INDEX_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an index input. + * @rmtoll ECR IDIR LL_TIM_SetIndexDirection + * @param TIMx Timer instance + * @param IndexDirection This parameter can be one of the following values: + * @arg @ref LL_TIM_INDEX_UP_DOWN + * @arg @ref LL_TIM_INDEX_UP + * @arg @ref LL_TIM_INDEX_DOWN + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetIndexDirection(TIM_TypeDef *TIMx, uint32_t IndexDirection) +{ + MODIFY_REG(TIMx->ECR, TIM_ECR_IDIR, IndexDirection); +} + +/** + * @brief Get actual index direction + * @note Macro IS_TIM_INDEX_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an index input. + * @rmtoll ECR IDIR LL_TIM_GetIndexDirection + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_INDEX_UP_DOWN + * @arg @ref LL_TIM_INDEX_UP + * @arg @ref LL_TIM_INDEX_DOWN + */ +__STATIC_INLINE uint32_t LL_TIM_GetIndexDirection(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_BIT(TIMx->ECR, TIM_ECR_IDIR)); +} + +/** + * @brief Set index blanking + * @note Macro IS_TIM_INDEX_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an index input. + * @rmtoll ECR IBLK LL_TIM_SetIndexblanking + * @param TIMx Timer instance + * @param Indexblanking This parameter can be one of the following values: + * @arg @ref LL_TIM_INDEX_BLANK_ALWAYS + * @arg @ref LL_TIM_INDEX_BLANK_TI3 + * @arg @ref LL_TIM_INDEX_BLANK_TI4 + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetIndexblanking(TIM_TypeDef *TIMx, uint32_t Indexblanking) +{ + MODIFY_REG(TIMx->ECR, TIM_ECR_IBLK, Indexblanking); +} + +/** + * @brief Get actual index blanking + * @note Macro IS_TIM_INDEX_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an index input. + * @rmtoll ECR IBLK LL_TIM_GetIndexblanking + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_INDEX_BLANK_ALWAYS + * @arg @ref LL_TIM_INDEX_BLANK_TI3 + * @arg @ref LL_TIM_INDEX_BLANK_TI4 + */ +__STATIC_INLINE uint32_t LL_TIM_GetIndexblanking(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_BIT(TIMx->ECR, TIM_ECR_IBLK)); +} + + +/** + * @brief Enable first index. + * @note Macro IS_TIM_INDEX_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an index input. + * @rmtoll ECR FIDX LL_TIM_EnableFirstIndex + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableFirstIndex(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->ECR, TIM_ECR_FIDX); +} + +/** + * @brief Disable first index. + * @note Macro IS_TIM_INDEX_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an index input. + * @rmtoll ECR FIDX LL_TIM_DisableFirstIndex + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableFirstIndex(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->ECR, TIM_ECR_FIDX); +} + +/** + * @brief Indicates whether first index is enabled. + * @note Macro IS_TIM_INDEX_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an index input. + * @rmtoll ECR FIDX LL_TIM_IsEnabledFirstIndex + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledFirstIndex(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->ECR, TIM_ECR_FIDX) == (TIM_ECR_FIDX)) ? 1UL : 0UL); +} + +/** + * @brief Set index positioning + * @note Macro IS_TIM_INDEX_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an index input. + * @rmtoll ECR IPOS LL_TIM_SetIndexPositionning + * @param TIMx Timer instance + * @param IndexPositionning This parameter can be one of the following values: + * @arg @ref LL_TIM_INDEX_POSITION_DOWN_DOWN + * @arg @ref LL_TIM_INDEX_POSITION_DOWN_UP + * @arg @ref LL_TIM_INDEX_POSITION_UP_DOWN + * @arg @ref LL_TIM_INDEX_POSITION_UP_UP + * @arg @ref LL_TIM_INDEX_POSITION_DOWN + * @arg @ref LL_TIM_INDEX_POSITION_UP + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetIndexPositionning(TIM_TypeDef *TIMx, uint32_t IndexPositionning) +{ + MODIFY_REG(TIMx->ECR, TIM_ECR_IPOS, IndexPositionning); +} + +/** + * @brief Get actual index positioning + * @note Macro IS_TIM_INDEX_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an index input. + * @rmtoll ECR IPOS LL_TIM_GetIndexPositionning + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_INDEX_POSITION_DOWN_DOWN + * @arg @ref LL_TIM_INDEX_POSITION_DOWN_UP + * @arg @ref LL_TIM_INDEX_POSITION_UP_DOWN + * @arg @ref LL_TIM_INDEX_POSITION_UP_UP + * @arg @ref LL_TIM_INDEX_POSITION_DOWN + * @arg @ref LL_TIM_INDEX_POSITION_UP + */ +__STATIC_INLINE uint32_t LL_TIM_GetIndexPositionning(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_BIT(TIMx->ECR, TIM_ECR_IPOS)); +} + +/** + * @brief Configure encoder index. + * @note Macro IS_TIM_INDEX_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an index input. + * @rmtoll ECR IDIR LL_TIM_ConfigIDX\n + * ECR IBLK LL_TIM_ConfigIDX\n + * ECR FIDX LL_TIM_ConfigIDX\n + * ECR IPOS LL_TIM_ConfigIDX + * @param TIMx Timer instance + * @param Configuration This parameter must be a combination of all the following values: + * @arg @ref LL_TIM_INDEX_UP or @ref LL_TIM_INDEX_DOWN or @ref LL_TIM_INDEX_UP_DOWN + * @arg @ref LL_TIM_INDEX_BLANK_ALWAYS or @ref LL_TIM_INDEX_BLANK_TI3 or @ref LL_TIM_INDEX_BLANK_TI4 + * @arg @ref LL_TIM_INDEX_ALL or @ref LL_TIM_INDEX_FIRST_ONLY + * @arg @ref LL_TIM_INDEX_POSITION_DOWN_DOWN or ... or @ref LL_TIM_INDEX_POSITION_UP + * @retval None + */ +__STATIC_INLINE void LL_TIM_ConfigIDX(TIM_TypeDef *TIMx, uint32_t Configuration) +{ + MODIFY_REG(TIMx->ECR, TIM_ECR_IDIR | TIM_ECR_IBLK | TIM_ECR_FIDX | TIM_ECR_IPOS, Configuration); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_Timer_Inputs_Remapping Timer input remapping + * @{ + */ +/** + * @brief Remap TIM inputs (input channel, internal/external triggers). + * @note Macro IS_TIM_REMAP_INSTANCE(TIMx) can be used to check whether or not + * a some timer inputs can be remapped. + * @rmtoll TIM1_TISEL TI1SEL LL_TIM_SetRemap\n + * TIM2_TISEL TI1SEL LL_TIM_SetRemap\n + * TIM2_TISEL TI2SEL LL_TIM_SetRemap\n + * TIM2_TISEL TI4SEL LL_TIM_SetRemap\n + * TIM3_TISEL TI1SEL LL_TIM_SetRemap\n + * TIM3_TISEL TI2SEL LL_TIM_SetRemap\n + * TIM4_TISEL TI1SEL LL_TIM_SetRemap\n + * TIM4_TISEL TI2SEL LL_TIM_SetRemap\n + * TIM5_TISEL TI1SEL LL_TIM_SetRemap\n + * TIM5_TISEL TI2SEL LL_TIM_SetRemap\n + * TIM8_TISEL TI1SEL LL_TIM_SetRemap\n + * TIM12_TISEL TI1SEL LL_TIM_SetRemap\n + * TIM13_TISEL TI1SEL LL_TIM_SetRemap\n + * TIM14_TISEL TI1SEL LL_TIM_SetRemap\n + * TIM15_TISEL TI1SEL LL_TIM_SetRemap\n + * TIM15_TISEL TI2SEL LL_TIM_SetRemap\n + * TIM16_TISEL TI1SEL LL_TIM_SetRemap\n + * TIM17_TISEL TI1SEL LL_TIM_SetRemap\n + * + * @param TIMx Timer instance + * @param Remap Remap param depends on the TIMx. Description available only + * in CHM version of the User Manual (not in .pdf). + * Otherwise see Reference Manual description of TISEL registers. + * + * Below description summarizes "Timer Instance" and "Remap" param combinations: + * + * TIM1: one of the following values: + * @arg LL_TIM_TIM1_TI1_RMP_GPIO: TIM1 TI1 is connected to GPIO + * @arg LL_TIM_TIM1_TI1_RMP_COMP1: TIM1 TI1 is connected to COMP1 output (*) + * @arg LL_TIM_TIM1_TI2_RMP_GPIO: TIM1 TI2 is connected to GPIO + * @arg LL_TIM_TIM1_TI3_RMP_GPIO: TIM1 TI3 is connected to GPIO + * @arg LL_TIM_TIM1_TI4_RMP_GPIO: TIM1 TI4 is connected to GPIO + * + * TIM2: one of the following values: + * @arg LL_TIM_TIM2_TI1_RMP_GPIO: TIM2 TI1 is connected to GPIO + * @arg LL_TIM_TIM2_TI1_RMP_LSI: TIM2 TI1 is connected to LSI (*) + * @arg LL_TIM_TIM2_TI1_RMP_LSE: TIM2 TI1 is connected to LSE (*) + * @arg LL_TIM_TIM2_TI1_RMP_RTC: TIM2 TI1 is connected to RTC (*) + * @arg LL_TIM_TIM2_TI1_RMP_TIM3_TI1: TIM2 TI1 is connected to TIM3 TI1 (*) + * @arg LL_TIM_TIM2_TI1_RMP_ETH_PPS: TIM2 TI1 is connected to ETH PPS (*) + * @arg LL_TIM_TIM2_TI2_RMP_GPIO: TIM2 TI2 is connected to GPIO + * @arg LL_TIM_TIM2_TI2_RMP_HSI_1024: TIM2 TI2 is connected to HSI 1024 (*) + * @arg LL_TIM_TIM2_TI2_RMP_CSI_128: TIM2 TI2 is connected to CSI 128 (*) + * @arg LL_TIM_TIM2_TI2_RMP_MCO2: TIM2 TI2 is connected to MCO2 (*) + * @arg LL_TIM_TIM2_TI2_RMP_MCO1: TIM2 TI2 is connected to MCO1 (*) + * @arg LL_TIM_TIM2_TI3_RMP_GPIO: TIM2 TI3 is connected to GPIO + * @arg LL_TIM_TIM2_TI4_RMP_GPIO: TIM2 TI4 is connected to GPIO + * @arg LL_TIM_TIM2_TI4_RMP_COMP1: TIM2 TI4 is connected to COMP1 (*) + * + * TIM3: one of the following values: + * @arg LL_TIM_TIM3_TI1_RMP_GPIO: TIM3 TI1 is connected to GPIO + * @arg LL_TIM_TIM3_TI1_RMP_COMP1: TIM3 TI1 is connected to COMP1 output (*) + * @arg LL_TIM_TIM3_TI1_RMP_MCO1: TIM3 TI1 is connected to MCO1 (*) + * @arg LL_TIM_TIM3_TI1_RMP_TIM2_TI1: TIM3 TI1 is connected to TIM2 TI1 (*) + * @arg LL_TIM_TIM3_TI1_RMP_HSE_1MHZ: TIM3 TI1 is connected to HSE_1MHZ (*) + * @arg LL_TIM_TIM3_TI1_RMP_ETH_PPS: TIM3 TI1 is connected to ETH PPS (*) + * @arg LL_TIM_TIM3_TI2_RMP_GPIO: TIM3 TI2 is connected to GPIO + * @arg LL_TIM_TIM3_TI2_RMP_CSI_128: TIM3 TI2 is connected to CSI_128 (*) + * @arg LL_TIM_TIM3_TI2_RMP_MCO2: TIM3 TI2 is connected to MCO2 (*) + * @arg LL_TIM_TIM3_TI2_RMP_HSI_1024: TIM3 TI2 is connected to HSI_1024 (*) + * @arg LL_TIM_TIM3_TI3_RMP_GPIO: TIM3 TI3 is connected to GPIO + * @arg LL_TIM_TIM3_TI4_RMP_GPIO: TIM3 TI4 is connected to GPIO + * + * TIM4: one of the following values: (**) + * @arg LL_TIM_TIM4_TI1_RMP_GPIO: TIM4 TI1 is connected to GPIO + * @arg LL_TIM_TIM4_TI2_RMP_GPIO: TIM4 TI2 is connected to GPIO + * @arg LL_TIM_TIM4_TI3_RMP_GPIO: TIM4 TI3 is connected to GPIO + * @arg LL_TIM_TIM4_TI4_RMP_GPIO: TIM4 TI4 is connected to GPIO + * + * TIM5: one of the following values: (**) + * @arg LL_TIM_TIM5_TI1_RMP_GPIO: TIM5 TI1 is connected to GPIO + * @arg LL_TIM_TIM5_TI2_RMP_GPIO: TIM5 TI2 is connected to GPIO + * @arg LL_TIM_TIM5_TI3_RMP_GPIO: TIM5 TI3 is connected to GPIO + * @arg LL_TIM_TIM5_TI4_RMP_GPIO: TIM5 TI4 is connected to GPIO + * + * TIM8: one of the following values: (**) + * @arg LL_TIM_TIM8_TI1_RMP_GPIO: TIM8 TI1 is connected to GPIO + * @arg LL_TIM_TIM8_TI2_RMP_GPIO: TIM8 TI2 is connected to GPIO + * @arg LL_TIM_TIM8_TI3_RMP_GPIO: TIM8 TI3 is connected to GPIO + * @arg LL_TIM_TIM8_TI4_RMP_GPIO: TIM8 TI4 is connected to GPIO + * + * TIM12: one of the following values: (**) + * @arg LL_TIM_TIM12_TI1_RMP_GPIO: TIM12 TI1 is connected to GPIO + * @arg LL_TIM_TIM12_TI1_RMP_HSI_1024: TIM12 TI1 is connected to GPIO + * @arg LL_TIM_TIM12_TI1_RMP_CSI_128: TIM12 TI1 is connected to GPIO + * + * TIM13: one of the following values: (**) + * @arg LL_TIM_TIM13_TI1_RMP_GPIO: TIM13 TI1 is connected to GPIO + * + * TIM14: one of the following values: (**) + * @arg LL_TIM_TIM14_TI1_RMP_GPIO: TIM14 TI1 is connected to GPIO + * + * TIM15: one of the following values: (**) + * @arg LL_TIM_TIM15_TI1_RMP_GPIO: TIM15 TI1 is connected to GPIO + * @arg LL_TIM_TIM15_TI1_RMP_TIM2: TIM15 TI1 is connected to TIM2 + * @arg LL_TIM_TIM15_TI1_RMP_TIM3: TIM15 TI1 is connected to TIM3 + * @arg LL_TIM_TIM15_TI1_RMP_TIM4: TIM15 TI1 is connected to TIM4 + * @arg LL_TIM_TIM15_TI1_RMP_LSE: TIM15 TI1 is connected to LSE + * @arg LL_TIM_TIM15_TI1_RMP_CSI_128: TIM15 TI1 is connected to CSI/128 + * @arg LL_TIM_TIM15_TI1_RMP_MCO2: TIM15 TI1 is connected to MCO2 + * @arg LL_TIM_TIM15_TI2_RMP_GPIO: TIM15 TI1 is connected to GPIO + * @arg LL_TIM_TIM15_TI2_RMP_TIM2: TIM15 TI1 is connected to TIM2 + * @arg LL_TIM_TIM15_TI2_RMP_TIM3: TIM15 TI1 is connected to TIM3 + * @arg LL_TIM_TIM15_TI2_RMP_TIM4: TIM15 TI1 is connected to TIM4 + * + * TIM16: one of the following values: (**) + * @arg LL_TIM_TIM16_TI1_RMP_GPIO: TIM16 TI1 is connected to GPIO + * @arg LL_TIM_TIM16_TI1_RMP_LSI: TIM16 TI1 is connected to LSI + * @arg LL_TIM_TIM16_TI1_RMP_LSE: TIM16 TI1 is connected to LSE + * @arg LL_TIM_TIM16_TI1_RMP_RTC_WKUP: TIM16 TI1 is connected to RTC_WKUP + * + * TIM17: one of the following values: (**) + * @arg LL_TIM_TIM17_TI1_RMP_GPIO: TIM17 TI1 is connected to GPIO + * @arg LL_TIM_TIM17_TI1_RMP_HSE_1MHZ: TIM17 TI1 is connected to HSE_1MHZ + * @arg LL_TIM_TIM17_TI1_RMP_MCO1: TIM17 TI1 is connected to MCO1 + * + * (*) Value not defined in all devices. \n + * (**) Timer instance not available on all devices. \n + * + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetRemap(TIM_TypeDef *TIMx, uint32_t Remap) +{ + MODIFY_REG(TIMx->TISEL, (TIM_TISEL_TI1SEL | TIM_TISEL_TI2SEL | TIM_TISEL_TI3SEL | TIM_TISEL_TI4SEL), Remap); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_OCREF_Clear OCREF_Clear_Management + * @{ + */ +/** + * @brief Set the OCREF clear input source + * @note The OCxREF signal of a given channel can be cleared when a high level is applied on the OCREF_CLR_INPUT + * @note This function can only be used in Output compare and PWM modes. + * @rmtoll SMCR OCCS LL_TIM_SetOCRefClearInputSource + * @param TIMx Timer instance + * @param OCRefClearInputSource This parameter can be one of the following values: + * @arg @ref LL_TIM_OCREF_CLR_INT_OCREF_CLR + * @arg @ref LL_TIM_OCREF_CLR_INT_ETR + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetOCRefClearInputSource(TIM_TypeDef *TIMx, uint32_t OCRefClearInputSource) +{ + MODIFY_REG(TIMx->SMCR, TIM_SMCR_OCCS, OCRefClearInputSource); +} +/** + * @} + */ + +/** @defgroup TIM_LL_EF_FLAG_Management FLAG-Management + * @{ + */ +/** + * @brief Clear the update interrupt flag (UIF). + * @rmtoll SR UIF LL_TIM_ClearFlag_UPDATE + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_UPDATE(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_UIF)); +} + +/** + * @brief Indicate whether update interrupt flag (UIF) is set (update interrupt is pending). + * @rmtoll SR UIF LL_TIM_IsActiveFlag_UPDATE + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_UPDATE(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_UIF) == (TIM_SR_UIF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Capture/Compare 1 interrupt flag (CC1F). + * @rmtoll SR CC1IF LL_TIM_ClearFlag_CC1 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_CC1(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_CC1IF)); +} + +/** + * @brief Indicate whether Capture/Compare 1 interrupt flag (CC1F) is set (Capture/Compare 1 interrupt is pending). + * @rmtoll SR CC1IF LL_TIM_IsActiveFlag_CC1 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC1(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC1IF) == (TIM_SR_CC1IF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Capture/Compare 2 interrupt flag (CC2F). + * @rmtoll SR CC2IF LL_TIM_ClearFlag_CC2 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_CC2(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_CC2IF)); +} + +/** + * @brief Indicate whether Capture/Compare 2 interrupt flag (CC2F) is set (Capture/Compare 2 interrupt is pending). + * @rmtoll SR CC2IF LL_TIM_IsActiveFlag_CC2 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC2(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC2IF) == (TIM_SR_CC2IF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Capture/Compare 3 interrupt flag (CC3F). + * @rmtoll SR CC3IF LL_TIM_ClearFlag_CC3 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_CC3(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_CC3IF)); +} + +/** + * @brief Indicate whether Capture/Compare 3 interrupt flag (CC3F) is set (Capture/Compare 3 interrupt is pending). + * @rmtoll SR CC3IF LL_TIM_IsActiveFlag_CC3 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC3(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC3IF) == (TIM_SR_CC3IF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Capture/Compare 4 interrupt flag (CC4F). + * @rmtoll SR CC4IF LL_TIM_ClearFlag_CC4 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_CC4(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_CC4IF)); +} + +/** + * @brief Indicate whether Capture/Compare 4 interrupt flag (CC4F) is set (Capture/Compare 4 interrupt is pending). + * @rmtoll SR CC4IF LL_TIM_IsActiveFlag_CC4 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC4(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC4IF) == (TIM_SR_CC4IF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Capture/Compare 5 interrupt flag (CC5F). + * @rmtoll SR CC5IF LL_TIM_ClearFlag_CC5 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_CC5(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_CC5IF)); +} + +/** + * @brief Indicate whether Capture/Compare 5 interrupt flag (CC5F) is set (Capture/Compare 5 interrupt is pending). + * @rmtoll SR CC5IF LL_TIM_IsActiveFlag_CC5 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC5(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC5IF) == (TIM_SR_CC5IF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Capture/Compare 6 interrupt flag (CC6F). + * @rmtoll SR CC6IF LL_TIM_ClearFlag_CC6 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_CC6(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_CC6IF)); +} + +/** + * @brief Indicate whether Capture/Compare 6 interrupt flag (CC6F) is set (Capture/Compare 6 interrupt is pending). + * @rmtoll SR CC6IF LL_TIM_IsActiveFlag_CC6 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC6(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC6IF) == (TIM_SR_CC6IF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the commutation interrupt flag (COMIF). + * @rmtoll SR COMIF LL_TIM_ClearFlag_COM + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_COM(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_COMIF)); +} + +/** + * @brief Indicate whether commutation interrupt flag (COMIF) is set (commutation interrupt is pending). + * @rmtoll SR COMIF LL_TIM_IsActiveFlag_COM + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_COM(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_COMIF) == (TIM_SR_COMIF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the trigger interrupt flag (TIF). + * @rmtoll SR TIF LL_TIM_ClearFlag_TRIG + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_TRIG(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_TIF)); +} + +/** + * @brief Indicate whether trigger interrupt flag (TIF) is set (trigger interrupt is pending). + * @rmtoll SR TIF LL_TIM_IsActiveFlag_TRIG + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_TRIG(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_TIF) == (TIM_SR_TIF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the break interrupt flag (BIF). + * @rmtoll SR BIF LL_TIM_ClearFlag_BRK + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_BRK(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_BIF)); +} + +/** + * @brief Indicate whether break interrupt flag (BIF) is set (break interrupt is pending). + * @rmtoll SR BIF LL_TIM_IsActiveFlag_BRK + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_BRK(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_BIF) == (TIM_SR_BIF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the break 2 interrupt flag (B2IF). + * @rmtoll SR B2IF LL_TIM_ClearFlag_BRK2 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_BRK2(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_B2IF)); +} + +/** + * @brief Indicate whether break 2 interrupt flag (B2IF) is set (break 2 interrupt is pending). + * @rmtoll SR B2IF LL_TIM_IsActiveFlag_BRK2 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_BRK2(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_B2IF) == (TIM_SR_B2IF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Capture/Compare 1 over-capture interrupt flag (CC1OF). + * @rmtoll SR CC1OF LL_TIM_ClearFlag_CC1OVR + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_CC1OVR(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_CC1OF)); +} + +/** + * @brief Indicate whether Capture/Compare 1 over-capture interrupt flag (CC1OF) is set + * (Capture/Compare 1 interrupt is pending). + * @rmtoll SR CC1OF LL_TIM_IsActiveFlag_CC1OVR + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC1OVR(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC1OF) == (TIM_SR_CC1OF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Capture/Compare 2 over-capture interrupt flag (CC2OF). + * @rmtoll SR CC2OF LL_TIM_ClearFlag_CC2OVR + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_CC2OVR(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_CC2OF)); +} + +/** + * @brief Indicate whether Capture/Compare 2 over-capture interrupt flag (CC2OF) is set + * (Capture/Compare 2 over-capture interrupt is pending). + * @rmtoll SR CC2OF LL_TIM_IsActiveFlag_CC2OVR + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC2OVR(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC2OF) == (TIM_SR_CC2OF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Capture/Compare 3 over-capture interrupt flag (CC3OF). + * @rmtoll SR CC3OF LL_TIM_ClearFlag_CC3OVR + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_CC3OVR(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_CC3OF)); +} + +/** + * @brief Indicate whether Capture/Compare 3 over-capture interrupt flag (CC3OF) is set + * (Capture/Compare 3 over-capture interrupt is pending). + * @rmtoll SR CC3OF LL_TIM_IsActiveFlag_CC3OVR + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC3OVR(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC3OF) == (TIM_SR_CC3OF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Capture/Compare 4 over-capture interrupt flag (CC4OF). + * @rmtoll SR CC4OF LL_TIM_ClearFlag_CC4OVR + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_CC4OVR(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_CC4OF)); +} + +/** + * @brief Indicate whether Capture/Compare 4 over-capture interrupt flag (CC4OF) is set + * (Capture/Compare 4 over-capture interrupt is pending). + * @rmtoll SR CC4OF LL_TIM_IsActiveFlag_CC4OVR + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC4OVR(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC4OF) == (TIM_SR_CC4OF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the system break interrupt flag (SBIF). + * @rmtoll SR SBIF LL_TIM_ClearFlag_SYSBRK + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_SYSBRK(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_SBIF)); +} + +/** + * @brief Indicate whether system break interrupt flag (SBIF) is set (system break interrupt is pending). + * @rmtoll SR SBIF LL_TIM_IsActiveFlag_SYSBRK + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_SYSBRK(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_SBIF) == (TIM_SR_SBIF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the transition error interrupt flag (TERRF). + * @note Macro IS_TIM_ENCODER_ERROR_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides encoder error management. + * @rmtoll SR TERRF LL_TIM_ClearFlag_TERR + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_TERR(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_TERRF)); +} + +/** + * @brief Indicate whether transition error interrupt flag (TERRF) is set (transition error interrupt is pending). + * @note Macro IS_TIM_ENCODER_ERROR_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides encoder error management. + * @rmtoll SR TERRF LL_TIM_IsActiveFlag_TERR + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_TERR(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_TERRF) == (TIM_SR_TERRF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the index error interrupt flag (IERRF). + * @note Macro IS_TIM_ENCODER_ERROR_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides encoder error management. + * @rmtoll SR IERRF LL_TIM_ClearFlag_IERR + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_IERR(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_IERRF)); +} + +/** + * @brief Indicate whether index error interrupt flag (IERRF) is set (index error interrupt is pending). + * @note Macro IS_TIM_ENCODER_ERROR_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides encoder error management. + * @rmtoll SR IERRF LL_TIM_IsActiveFlag_IERR + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_IERR(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_IERRF) == (TIM_SR_IERRF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the direction change interrupt flag (DIRF). + * @note Macro IS_TIM_FUNCTINONAL_ENCODER_INTERRUPT_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides encoder interrupt management. + * @rmtoll SR DIRF LL_TIM_ClearFlag_DIR + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_DIR(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_DIRF)); +} + +/** + * @brief Indicate whether direction change interrupt flag (DIRF) is set (direction change interrupt is pending). + * @note Macro IS_TIM_FUNCTINONAL_ENCODER_INTERRUPT_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides encoder interrupt management. + * @rmtoll SR DIRF LL_TIM_IsActiveFlag_DIR + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_DIR(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_DIRF) == (TIM_SR_DIRF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the index interrupt flag (IDXF). + * @note Macro IS_TIM_FUNCTINONAL_ENCODER_INTERRUPT_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides encoder interrupt management. + * @rmtoll SR IDXF LL_TIM_ClearFlag_IDX + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_IDX(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_IDXF)); +} + +/** + * @brief Indicate whether index interrupt flag (IDXF) is set (index interrupt is pending). + * @note Macro IS_TIM_FUNCTINONAL_ENCODER_INTERRUPT_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides encoder interrupt management. + * @rmtoll SR IDXF LL_TIM_IsActiveFlag_IDX + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_IDX(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_IDXF) == (TIM_SR_IDXF)) ? 1UL : 0UL); +} +/** + * @} + */ + +/** @defgroup TIM_LL_EF_IT_Management IT-Management + * @{ + */ +/** + * @brief Enable update interrupt (UIE). + * @rmtoll DIER UIE LL_TIM_EnableIT_UPDATE + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableIT_UPDATE(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_UIE); +} + +/** + * @brief Disable update interrupt (UIE). + * @rmtoll DIER UIE LL_TIM_DisableIT_UPDATE + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableIT_UPDATE(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_UIE); +} + +/** + * @brief Indicates whether the update interrupt (UIE) is enabled. + * @rmtoll DIER UIE LL_TIM_IsEnabledIT_UPDATE + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_UPDATE(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_UIE) == (TIM_DIER_UIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable capture/compare 1 interrupt (CC1IE). + * @rmtoll DIER CC1IE LL_TIM_EnableIT_CC1 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableIT_CC1(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_CC1IE); +} + +/** + * @brief Disable capture/compare 1 interrupt (CC1IE). + * @rmtoll DIER CC1IE LL_TIM_DisableIT_CC1 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableIT_CC1(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC1IE); +} + +/** + * @brief Indicates whether the capture/compare 1 interrupt (CC1IE) is enabled. + * @rmtoll DIER CC1IE LL_TIM_IsEnabledIT_CC1 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_CC1(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC1IE) == (TIM_DIER_CC1IE)) ? 1UL : 0UL); +} + +/** + * @brief Enable capture/compare 2 interrupt (CC2IE). + * @rmtoll DIER CC2IE LL_TIM_EnableIT_CC2 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableIT_CC2(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_CC2IE); +} + +/** + * @brief Disable capture/compare 2 interrupt (CC2IE). + * @rmtoll DIER CC2IE LL_TIM_DisableIT_CC2 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableIT_CC2(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC2IE); +} + +/** + * @brief Indicates whether the capture/compare 2 interrupt (CC2IE) is enabled. + * @rmtoll DIER CC2IE LL_TIM_IsEnabledIT_CC2 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_CC2(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC2IE) == (TIM_DIER_CC2IE)) ? 1UL : 0UL); +} + +/** + * @brief Enable capture/compare 3 interrupt (CC3IE). + * @rmtoll DIER CC3IE LL_TIM_EnableIT_CC3 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableIT_CC3(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_CC3IE); +} + +/** + * @brief Disable capture/compare 3 interrupt (CC3IE). + * @rmtoll DIER CC3IE LL_TIM_DisableIT_CC3 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableIT_CC3(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC3IE); +} + +/** + * @brief Indicates whether the capture/compare 3 interrupt (CC3IE) is enabled. + * @rmtoll DIER CC3IE LL_TIM_IsEnabledIT_CC3 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_CC3(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC3IE) == (TIM_DIER_CC3IE)) ? 1UL : 0UL); +} + +/** + * @brief Enable capture/compare 4 interrupt (CC4IE). + * @rmtoll DIER CC4IE LL_TIM_EnableIT_CC4 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableIT_CC4(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_CC4IE); +} + +/** + * @brief Disable capture/compare 4 interrupt (CC4IE). + * @rmtoll DIER CC4IE LL_TIM_DisableIT_CC4 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableIT_CC4(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC4IE); +} + +/** + * @brief Indicates whether the capture/compare 4 interrupt (CC4IE) is enabled. + * @rmtoll DIER CC4IE LL_TIM_IsEnabledIT_CC4 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_CC4(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC4IE) == (TIM_DIER_CC4IE)) ? 1UL : 0UL); +} + +/** + * @brief Enable commutation interrupt (COMIE). + * @rmtoll DIER COMIE LL_TIM_EnableIT_COM + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableIT_COM(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_COMIE); +} + +/** + * @brief Disable commutation interrupt (COMIE). + * @rmtoll DIER COMIE LL_TIM_DisableIT_COM + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableIT_COM(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_COMIE); +} + +/** + * @brief Indicates whether the commutation interrupt (COMIE) is enabled. + * @rmtoll DIER COMIE LL_TIM_IsEnabledIT_COM + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_COM(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_COMIE) == (TIM_DIER_COMIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable trigger interrupt (TIE). + * @rmtoll DIER TIE LL_TIM_EnableIT_TRIG + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableIT_TRIG(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_TIE); +} + +/** + * @brief Disable trigger interrupt (TIE). + * @rmtoll DIER TIE LL_TIM_DisableIT_TRIG + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableIT_TRIG(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_TIE); +} + +/** + * @brief Indicates whether the trigger interrupt (TIE) is enabled. + * @rmtoll DIER TIE LL_TIM_IsEnabledIT_TRIG + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_TRIG(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_TIE) == (TIM_DIER_TIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable break interrupt (BIE). + * @rmtoll DIER BIE LL_TIM_EnableIT_BRK + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableIT_BRK(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_BIE); +} + +/** + * @brief Disable break interrupt (BIE). + * @rmtoll DIER BIE LL_TIM_DisableIT_BRK + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableIT_BRK(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_BIE); +} + +/** + * @brief Indicates whether the break interrupt (BIE) is enabled. + * @rmtoll DIER BIE LL_TIM_IsEnabledIT_BRK + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_BRK(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_BIE) == (TIM_DIER_BIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable transition error interrupt (TERRIE). + * @note Macro IS_TIM_ENCODER_ERROR_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides encoder error management. + * @rmtoll DIER TERRIE LL_TIM_EnableIT_TERR + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableIT_TERR(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_TERRIE); +} + +/** + * @brief Disable transition error interrupt (TERRIE). + * @note Macro IS_TIM_ENCODER_ERROR_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides encoder error management. + * @rmtoll DIER TERRIE LL_TIM_DisableIT_TERR + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableIT_TERR(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_TERRIE); +} + +/** + * @brief Indicates whether the transition error interrupt (TERRIE) is enabled. + * @note Macro IS_TIM_ENCODER_ERROR_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides encoder error management. + * @rmtoll DIER TERRIE LL_TIM_IsEnabledIT_TERR + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_TERR(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_TERRIE) == (TIM_DIER_TERRIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable index error interrupt (IERRIE). + * @note Macro IS_TIM_ENCODER_ERROR_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides encoder error management. + * @rmtoll DIER IERRIE LL_TIM_EnableIT_IERR + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableIT_IERR(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_IERRIE); +} + +/** + * @brief Disable index error interrupt (IERRIE). + * @note Macro IS_TIM_ENCODER_ERROR_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides encoder error management. + * @rmtoll DIER IERRIE LL_TIM_DisableIT_IERR + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableIT_IERR(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_IERRIE); +} + +/** + * @brief Indicates whether the index error interrupt (IERRIE) is enabled. + * @note Macro IS_TIM_ENCODER_ERROR_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides encoder error management. + * @rmtoll DIER IERRIE LL_TIM_IsEnabledIT_IERR + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_IERR(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_IERRIE) == (TIM_DIER_IERRIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable direction change interrupt (DIRIE). + * @note Macro IS_TIM_FUNCTINONAL_ENCODER_INTERRUPT_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides encoder interrupt management. + * @rmtoll DIER DIRIE LL_TIM_EnableIT_DIR + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableIT_DIR(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_DIRIE); +} + +/** + * @brief Disable direction change interrupt (DIRIE). + * @note Macro IS_TIM_FUNCTINONAL_ENCODER_INTERRUPT_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides encoder interrupt management. + * @rmtoll DIER DIRIE LL_TIM_DisableIT_DIR + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableIT_DIR(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_DIRIE); +} + +/** + * @brief Indicates whether the direction change interrupt (DIRIE) is enabled. + * @note Macro IS_TIM_FUNCTINONAL_ENCODER_INTERRUPT_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides encoder interrupt management. + * @rmtoll DIER DIRIE LL_TIM_IsEnabledIT_DIR + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_DIR(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_DIRIE) == (TIM_DIER_DIRIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable index interrupt (IDXIE). + * @note Macro IS_TIM_FUNCTINONAL_ENCODER_INTERRUPT_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides encoder interrupt management. + * @rmtoll DIER IDXIE LL_TIM_EnableIT_IDX + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableIT_IDX(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_IDXIE); +} + +/** + * @brief Disable index interrupt (IDXIE). + * @note Macro IS_TIM_FUNCTINONAL_ENCODER_INTERRUPT_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides encoder interrupt management. + * @rmtoll DIER IDXIE LL_TIM_DisableIT_IDX + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableIT_IDX(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_IDXIE); +} + +/** + * @brief Indicates whether the index interrupt (IDXIE) is enabled. + * @note Macro IS_TIM_FUNCTINONAL_ENCODER_INTERRUPT_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides encoder interrupt management. + * @rmtoll DIER IDXIE LL_TIM_IsEnabledIT_IDX + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_IDX(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_IDXIE) == (TIM_DIER_IDXIE)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_DMA_Management DMA Management + * @{ + */ +/** + * @brief Enable update DMA request (UDE). + * @rmtoll DIER UDE LL_TIM_EnableDMAReq_UPDATE + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableDMAReq_UPDATE(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_UDE); +} + +/** + * @brief Disable update DMA request (UDE). + * @rmtoll DIER UDE LL_TIM_DisableDMAReq_UPDATE + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableDMAReq_UPDATE(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_UDE); +} + +/** + * @brief Indicates whether the update DMA request (UDE) is enabled. + * @rmtoll DIER UDE LL_TIM_IsEnabledDMAReq_UPDATE + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_UPDATE(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_UDE) == (TIM_DIER_UDE)) ? 1UL : 0UL); +} + +/** + * @brief Enable capture/compare 1 DMA request (CC1DE). + * @rmtoll DIER CC1DE LL_TIM_EnableDMAReq_CC1 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableDMAReq_CC1(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_CC1DE); +} + +/** + * @brief Disable capture/compare 1 DMA request (CC1DE). + * @rmtoll DIER CC1DE LL_TIM_DisableDMAReq_CC1 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableDMAReq_CC1(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC1DE); +} + +/** + * @brief Indicates whether the capture/compare 1 DMA request (CC1DE) is enabled. + * @rmtoll DIER CC1DE LL_TIM_IsEnabledDMAReq_CC1 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_CC1(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC1DE) == (TIM_DIER_CC1DE)) ? 1UL : 0UL); +} + +/** + * @brief Enable capture/compare 2 DMA request (CC2DE). + * @rmtoll DIER CC2DE LL_TIM_EnableDMAReq_CC2 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableDMAReq_CC2(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_CC2DE); +} + +/** + * @brief Disable capture/compare 2 DMA request (CC2DE). + * @rmtoll DIER CC2DE LL_TIM_DisableDMAReq_CC2 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableDMAReq_CC2(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC2DE); +} + +/** + * @brief Indicates whether the capture/compare 2 DMA request (CC2DE) is enabled. + * @rmtoll DIER CC2DE LL_TIM_IsEnabledDMAReq_CC2 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_CC2(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC2DE) == (TIM_DIER_CC2DE)) ? 1UL : 0UL); +} + +/** + * @brief Enable capture/compare 3 DMA request (CC3DE). + * @rmtoll DIER CC3DE LL_TIM_EnableDMAReq_CC3 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableDMAReq_CC3(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_CC3DE); +} + +/** + * @brief Disable capture/compare 3 DMA request (CC3DE). + * @rmtoll DIER CC3DE LL_TIM_DisableDMAReq_CC3 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableDMAReq_CC3(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC3DE); +} + +/** + * @brief Indicates whether the capture/compare 3 DMA request (CC3DE) is enabled. + * @rmtoll DIER CC3DE LL_TIM_IsEnabledDMAReq_CC3 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_CC3(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC3DE) == (TIM_DIER_CC3DE)) ? 1UL : 0UL); +} + +/** + * @brief Enable capture/compare 4 DMA request (CC4DE). + * @rmtoll DIER CC4DE LL_TIM_EnableDMAReq_CC4 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableDMAReq_CC4(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_CC4DE); +} + +/** + * @brief Disable capture/compare 4 DMA request (CC4DE). + * @rmtoll DIER CC4DE LL_TIM_DisableDMAReq_CC4 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableDMAReq_CC4(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC4DE); +} + +/** + * @brief Indicates whether the capture/compare 4 DMA request (CC4DE) is enabled. + * @rmtoll DIER CC4DE LL_TIM_IsEnabledDMAReq_CC4 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_CC4(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC4DE) == (TIM_DIER_CC4DE)) ? 1UL : 0UL); +} + +/** + * @brief Enable commutation DMA request (COMDE). + * @rmtoll DIER COMDE LL_TIM_EnableDMAReq_COM + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableDMAReq_COM(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_COMDE); +} + +/** + * @brief Disable commutation DMA request (COMDE). + * @rmtoll DIER COMDE LL_TIM_DisableDMAReq_COM + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableDMAReq_COM(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_COMDE); +} + +/** + * @brief Indicates whether the commutation DMA request (COMDE) is enabled. + * @rmtoll DIER COMDE LL_TIM_IsEnabledDMAReq_COM + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_COM(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_COMDE) == (TIM_DIER_COMDE)) ? 1UL : 0UL); +} + +/** + * @brief Enable trigger interrupt (TDE). + * @rmtoll DIER TDE LL_TIM_EnableDMAReq_TRIG + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableDMAReq_TRIG(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_TDE); +} + +/** + * @brief Disable trigger interrupt (TDE). + * @rmtoll DIER TDE LL_TIM_DisableDMAReq_TRIG + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableDMAReq_TRIG(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_TDE); +} + +/** + * @brief Indicates whether the trigger interrupt (TDE) is enabled. + * @rmtoll DIER TDE LL_TIM_IsEnabledDMAReq_TRIG + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_TRIG(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_TDE) == (TIM_DIER_TDE)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_EVENT_Management EVENT-Management + * @{ + */ +/** + * @brief Generate an update event. + * @rmtoll EGR UG LL_TIM_GenerateEvent_UPDATE + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_GenerateEvent_UPDATE(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->EGR, TIM_EGR_UG); +} + +/** + * @brief Generate Capture/Compare 1 event. + * @rmtoll EGR CC1G LL_TIM_GenerateEvent_CC1 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_GenerateEvent_CC1(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->EGR, TIM_EGR_CC1G); +} + +/** + * @brief Generate Capture/Compare 2 event. + * @rmtoll EGR CC2G LL_TIM_GenerateEvent_CC2 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_GenerateEvent_CC2(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->EGR, TIM_EGR_CC2G); +} + +/** + * @brief Generate Capture/Compare 3 event. + * @rmtoll EGR CC3G LL_TIM_GenerateEvent_CC3 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_GenerateEvent_CC3(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->EGR, TIM_EGR_CC3G); +} + +/** + * @brief Generate Capture/Compare 4 event. + * @rmtoll EGR CC4G LL_TIM_GenerateEvent_CC4 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_GenerateEvent_CC4(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->EGR, TIM_EGR_CC4G); +} + +/** + * @brief Generate commutation event. + * @rmtoll EGR COMG LL_TIM_GenerateEvent_COM + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_GenerateEvent_COM(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->EGR, TIM_EGR_COMG); +} + +/** + * @brief Generate trigger event. + * @rmtoll EGR TG LL_TIM_GenerateEvent_TRIG + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_GenerateEvent_TRIG(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->EGR, TIM_EGR_TG); +} + +/** + * @brief Generate break event. + * @rmtoll EGR BG LL_TIM_GenerateEvent_BRK + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_GenerateEvent_BRK(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->EGR, TIM_EGR_BG); +} + +/** + * @brief Generate break 2 event. + * @rmtoll EGR B2G LL_TIM_GenerateEvent_BRK2 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_GenerateEvent_BRK2(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->EGR, TIM_EGR_B2G); +} + +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup TIM_LL_EF_Init Initialisation and deinitialisation functions + * @{ + */ + +ErrorStatus LL_TIM_DeInit(const TIM_TypeDef *TIMx); +void LL_TIM_StructInit(LL_TIM_InitTypeDef *TIM_InitStruct); +ErrorStatus LL_TIM_Init(TIM_TypeDef *TIMx, const LL_TIM_InitTypeDef *TIM_InitStruct); +void LL_TIM_OC_StructInit(LL_TIM_OC_InitTypeDef *TIM_OC_InitStruct); +ErrorStatus LL_TIM_OC_Init(TIM_TypeDef *TIMx, uint32_t Channel, const LL_TIM_OC_InitTypeDef *TIM_OC_InitStruct); +void LL_TIM_IC_StructInit(LL_TIM_IC_InitTypeDef *TIM_ICInitStruct); +ErrorStatus LL_TIM_IC_Init(TIM_TypeDef *TIMx, uint32_t Channel, const LL_TIM_IC_InitTypeDef *TIM_IC_InitStruct); +void LL_TIM_ENCODER_StructInit(LL_TIM_ENCODER_InitTypeDef *TIM_EncoderInitStruct); +ErrorStatus LL_TIM_ENCODER_Init(TIM_TypeDef *TIMx, const LL_TIM_ENCODER_InitTypeDef *TIM_EncoderInitStruct); +void LL_TIM_HALLSENSOR_StructInit(LL_TIM_HALLSENSOR_InitTypeDef *TIM_HallSensorInitStruct); +ErrorStatus LL_TIM_HALLSENSOR_Init(TIM_TypeDef *TIMx, const LL_TIM_HALLSENSOR_InitTypeDef *TIM_HallSensorInitStruct); +void LL_TIM_BDTR_StructInit(LL_TIM_BDTR_InitTypeDef *TIM_BDTRInitStruct); +ErrorStatus LL_TIM_BDTR_Init(TIM_TypeDef *TIMx, const LL_TIM_BDTR_InitTypeDef *TIM_BDTRInitStruct); +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* TIM1 || TIM2 || TIM3 || TIM4 || TIM5 || TIM6 || TIM7 || TIM8 || TIM12 || TIM13 || TIM14 || TIM15 || TIM16 || TIM17 */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32H5xx_LL_TIM_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_ucpd.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_ucpd.h new file mode 100644 index 0000000000..dd55bdffc8 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_ucpd.h @@ -0,0 +1,1885 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_ucpd.h + * @author MCD Application Team + * @brief Header file of UCPD LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_LL_UCPD_H +#define STM32H5xx_LL_UCPD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (UCPD1) + +/** @defgroup UCPD_LL UCPD + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ + +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup UCPD_LL_ES_INIT UCPD Exported Init structure + * @{ + */ + +/** + * @brief UCPD Init structures definition + */ +typedef struct +{ + uint32_t psc_ucpdclk; /*!< Specify the prescaler for the UCPD clock. + This parameter can be a value of @ref UCPD_LL_EC_PSC. + This feature can be modified afterwards using function @ref LL_UCPD_SetPSCClk(). + */ + + uint32_t transwin; /*!< Specify the number of cycles (minus 1) of the half bit clock (see HBITCLKDIV) + to achieve a legal tTransitionWindow (set according to peripheral clock to define + an interval of between 12 and 20 us). + This parameter can be a value between Min_Data=0x1 and Max_Data=0x1F + This value can be modified afterwards using function @ref LL_UCPD_SetTransWin(). + */ + + uint32_t IfrGap; /*!< Specify the definition of the clock divider (minus 1) in order to generate + tInterframeGap from the peripheral clock. + This parameter can be a value between Min_Data=0x1 and Max_Data=0x1F + This feature can be modified afterwards using function @ref LL_UCPD_SetIfrGap(). + */ + + uint32_t HbitClockDiv; /*!< Specify the number of cycles (minus one) at UCPD peripheral for a half bit clock + e.g. program 3 for a bit clock that takes 8 cycles of the peripheral clock : + "UCPD1_CLK". + This parameter can be a value between Min_Data=0x0 and Max_Data=0x3F. + This feature can be modified using function @ref LL_UCPD_SetHbitClockDiv(). + */ + +} LL_UCPD_InitTypeDef; + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup UCPD_LL_Exported_Constants UCPD Exported Constants + * @{ + */ + +/** @defgroup UCPD_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_ucpd_ReadReg function + * @{ + */ +#define LL_UCPD_SR_TXIS UCPD_SR_TXIS /*!< Transmit interrupt status */ +#define LL_UCPD_SR_TXMSGDISC UCPD_SR_TXMSGDISC /*!< Transmit message discarded interrupt */ +#define LL_UCPD_SR_TXMSGSENT UCPD_SR_TXMSGSENT /*!< Transmit message sent interrupt */ +#define LL_UCPD_SR_TXMSGABT UCPD_SR_TXMSGABT /*!< Transmit message abort interrupt */ +#define LL_UCPD_SR_HRSTDISC UCPD_SR_HRSTDISC /*!< HRST discarded interrupt */ +#define LL_UCPD_SR_HRSTSENT UCPD_SR_HRSTSENT /*!< HRST sent interrupt */ +#define LL_UCPD_SR_TXUND UCPD_SR_TXUND /*!< Tx data underrun condition interrupt */ +#define LL_UCPD_SR_RXNE UCPD_SR_RXNE /*!< Receive data register not empty interrupt */ +#define LL_UCPD_SR_RXORDDET UCPD_SR_RXORDDET /*!< Rx ordered set (4 K-codes) detected interrupt */ +#define LL_UCPD_SR_RXHRSTDET UCPD_SR_RXHRSTDET /*!< Rx Hard Reset detect interrupt */ +#define LL_UCPD_SR_RXOVR UCPD_SR_RXOVR /*!< Rx data overflow interrupt */ +#define LL_UCPD_SR_RXMSGEND UCPD_SR_RXMSGEND /*!< Rx message received */ +#define LL_UCPD_SR_RXERR UCPD_SR_RXERR /*!< Rx error */ +#define LL_UCPD_SR_TYPECEVT1 UCPD_SR_TYPECEVT1 /*!< Type C voltage level event on CC1 */ +#define LL_UCPD_SR_TYPECEVT2 UCPD_SR_TYPECEVT2 /*!< Type C voltage level event on CC2 */ +#define LL_UCPD_SR_TYPEC_VSTATE_CC1 UCPD_SR_TYPEC_VSTATE_CC1 /*!__REG__, (__VALUE__)) + +/** + * @brief Read a value in UCPD register + * @param __INSTANCE__ UCPD Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_UCPD_ReadReg(__INSTANCE__, __REG__) READ_REG((__INSTANCE__)->__REG__) +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup UCPD_LL_Exported_Functions UCPD Exported Functions + * @{ + */ + +/** @defgroup UCPD_LL_EF_Configuration Configuration + * @{ + */ + +/** @defgroup UCPD_LL_EF_CFG1 CFG1 register + * @{ + */ +/** + * @brief Enable UCPD peripheral + * @rmtoll CFG1 UCPDEN LL_UCPD_Enable + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_Enable(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->CFG1, UCPD_CFG1_UCPDEN); +} + +/** + * @brief Disable UCPD peripheral + * @note When disabling the UCPD, follow the procedure described in the Reference Manual. + * @rmtoll CFG1 UCPDEN LL_UCPD_Disable + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_Disable(UCPD_TypeDef *UCPDx) +{ + CLEAR_BIT(UCPDx->CFG1, UCPD_CFG1_UCPDEN); +} + +/** + * @brief Check if UCPD peripheral is enabled + * @rmtoll CFG1 UCPDEN LL_UCPD_IsEnabled + * @param UCPDx UCPD Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_UCPD_IsEnabled(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->CFG1, UCPD_CFG1_UCPDEN) == (UCPD_CFG1_UCPDEN)) ? 1UL : 0UL); +} + +/** + * @brief Set the receiver ordered set detection enable + * @rmtoll CFG1 RXORDSETEN LL_UCPD_SetRxOrderSet + * @param UCPDx UCPD Instance + * @param OrderSet This parameter can be combination of the following values: + * @arg @ref LL_UCPD_ORDERSET_SOP + * @arg @ref LL_UCPD_ORDERSET_SOP1 + * @arg @ref LL_UCPD_ORDERSET_SOP2 + * @arg @ref LL_UCPD_ORDERSET_HARDRST + * @arg @ref LL_UCPD_ORDERSET_CABLERST + * @arg @ref LL_UCPD_ORDERSET_SOP1_DEBUG + * @arg @ref LL_UCPD_ORDERSET_SOP2_DEBUG + * @arg @ref LL_UCPD_ORDERSET_SOP_EXT1 + * @arg @ref LL_UCPD_ORDERSET_SOP_EXT2 + * @retval None + */ +__STATIC_INLINE void LL_UCPD_SetRxOrderSet(UCPD_TypeDef *UCPDx, uint32_t OrderSet) +{ + MODIFY_REG(UCPDx->CFG1, UCPD_CFG1_RXORDSETEN, OrderSet); +} + +/** + * @brief Set the prescaler for ucpd clock + * @rmtoll CFG1 UCPDCLK LL_UCPD_SetPSCClk + * @param UCPDx UCPD Instance + * @param Psc This parameter can be one of the following values: + * @arg @ref LL_UCPD_PSC_DIV1 + * @arg @ref LL_UCPD_PSC_DIV2 + * @arg @ref LL_UCPD_PSC_DIV4 + * @arg @ref LL_UCPD_PSC_DIV8 + * @arg @ref LL_UCPD_PSC_DIV16 + * @retval None + */ +__STATIC_INLINE void LL_UCPD_SetPSCClk(UCPD_TypeDef *UCPDx, uint32_t Psc) +{ + MODIFY_REG(UCPDx->CFG1, UCPD_CFG1_PSC_UCPDCLK, Psc); +} + +/** + * @brief Set the number of cycles (minus 1) of the half bit clock + * @rmtoll CFG1 TRANSWIN LL_UCPD_SetTransWin + * @param UCPDx UCPD Instance + * @param TransWin a value between Min_Data=0x1 and Max_Data=0x1F + * @retval None + */ +__STATIC_INLINE void LL_UCPD_SetTransWin(UCPD_TypeDef *UCPDx, uint32_t TransWin) +{ + MODIFY_REG(UCPDx->CFG1, UCPD_CFG1_TRANSWIN, TransWin << UCPD_CFG1_TRANSWIN_Pos); +} + +/** + * @brief Set the clock divider value to generate an interframe gap + * @rmtoll CFG1 IFRGAP LL_UCPD_SetIfrGap + * @param UCPDx UCPD Instance + * @param IfrGap a value between Min_Data=0x1 and Max_Data=0x1F + * @retval None + */ +__STATIC_INLINE void LL_UCPD_SetIfrGap(UCPD_TypeDef *UCPDx, uint32_t IfrGap) +{ + MODIFY_REG(UCPDx->CFG1, UCPD_CFG1_IFRGAP, IfrGap << UCPD_CFG1_IFRGAP_Pos); +} + +/** + * @brief Set the clock divider value to generate an interframe gap + * @rmtoll CFG1 HBITCLKDIV LL_UCPD_SetHbitClockDiv + * @param UCPDx UCPD Instance + * @param HbitClock a value between Min_Data=0x0 and Max_Data=0x3F + * @retval None + */ +__STATIC_INLINE void LL_UCPD_SetHbitClockDiv(UCPD_TypeDef *UCPDx, uint32_t HbitClock) +{ + MODIFY_REG(UCPDx->CFG1, UCPD_CFG1_HBITCLKDIV, HbitClock << UCPD_CFG1_HBITCLKDIV_Pos); +} + +/** + * @} + */ + +/** @defgroup UCPD_LL_EF_CFG2 CFG2 register + * @{ + */ + +/** + * @brief Enable Rx Analog Filter + * @rmtoll CFG2 RXAFILTEN LL_UCPD_RxAnalogFilterEnable + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_RxAnalogFilterEnable(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->CFG2, UCPD_CFG2_RXAFILTEN); +} + +/** + * @brief Disable Rx Analog Filter + * @rmtoll CFG2 RXAFILTEN LL_UCPD_RxAnalogFilterDisable + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_RxAnalogFilterDisable(UCPD_TypeDef *UCPDx) +{ + CLEAR_BIT(UCPDx->CFG2, UCPD_CFG2_RXAFILTEN); +} + +/** + * @brief Enable the wakeup mode + * @rmtoll CFG2 WUPEN LL_UCPD_WakeUpEnable + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_WakeUpEnable(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->CFG2, UCPD_CFG2_WUPEN); +} + +/** + * @brief Disable the wakeup mode + * @rmtoll CFG2 WUPEN LL_UCPD_WakeUpDisable + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_WakeUpDisable(UCPD_TypeDef *UCPDx) +{ + CLEAR_BIT(UCPDx->CFG2, UCPD_CFG2_WUPEN); +} + +/** + * @brief Force clock enable + * @rmtoll CFG2 FORCECLK LL_UCPD_ForceClockEnable + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_ForceClockEnable(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->CFG2, UCPD_CFG2_FORCECLK); +} + +/** + * @brief Force clock disable + * @rmtoll CFG2 FORCECLK LL_UCPD_ForceClockDisable + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_ForceClockDisable(UCPD_TypeDef *UCPDx) +{ + CLEAR_BIT(UCPDx->CFG2, UCPD_CFG2_FORCECLK); +} + +/** + * @brief RxFilter enable + * @rmtoll CFG2 RXFILTDIS LL_UCPD_RxFilterEnable + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_RxFilterEnable(UCPD_TypeDef *UCPDx) +{ + CLEAR_BIT(UCPDx->CFG2, UCPD_CFG2_RXFILTDIS); +} + +/** + * @brief RxFilter disable + * @rmtoll CFG2 RXFILTDIS LL_UCPD_RxFilterDisable + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_RxFilterDisable(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->CFG2, UCPD_CFG2_RXFILTDIS); +} + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup UCPD_LL_EF_CR CR register + * @{ + */ +/** + * @brief Type C detector for CC2 enable + * @rmtoll CR CC2TCDIS LL_UCPD_TypeCDetectionCC2Enable + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_TypeCDetectionCC2Enable(UCPD_TypeDef *UCPDx) +{ + CLEAR_BIT(UCPDx->CR, UCPD_CR_CC2TCDIS); +} + +/** + * @brief Type C detector for CC2 disable + * @rmtoll CR CC2TCDIS LL_UCPD_TypeCDetectionCC2Disable + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_TypeCDetectionCC2Disable(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->CR, UCPD_CR_CC2TCDIS); +} + +/** + * @brief Type C detector for CC1 enable + * @rmtoll CR CC1TCDIS LL_UCPD_TypeCDetectionCC1Enable + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_TypeCDetectionCC1Enable(UCPD_TypeDef *UCPDx) +{ + CLEAR_BIT(UCPDx->CR, UCPD_CR_CC1TCDIS); +} + +/** + * @brief Type C detector for CC1 disable + * @rmtoll CR CC1TCDIS LL_UCPD_TypeCDetectionCC1Disable + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_TypeCDetectionCC1Disable(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->CR, UCPD_CR_CC1TCDIS); +} + +/** + * @brief Source Vconn discharge enable + * @rmtoll CR RDCH LL_UCPD_VconnDischargeEnable + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_VconnDischargeEnable(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->CR, UCPD_CR_RDCH); +} + +/** + * @brief Source Vconn discharge disable + * @rmtoll CR RDCH LL_UCPD_VconnDischargeDisable + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_VconnDischargeDisable(UCPD_TypeDef *UCPDx) +{ + CLEAR_BIT(UCPDx->CR, UCPD_CR_RDCH); +} + +/** + * @brief Signal Fast Role Swap request + * @rmtoll CR FRSTX LL_UCPD_VconnDischargeDisable + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_SignalFRSTX(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->CR, UCPD_CR_FRSTX); +} + +/** + * @brief Fast Role swap RX detection enable + * @rmtoll CR FRSRXEN LL_UCPD_FRSDetectionEnable + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_FRSDetectionEnable(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->CR, UCPD_CR_FRSRXEN); +} + +/** + * @brief Fast Role swap RX detection disable + * @rmtoll CR FRSRXEN LL_UCPD_FRSDetectionDisable + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_FRSDetectionDisable(UCPD_TypeDef *UCPDx) +{ + CLEAR_BIT(UCPDx->CR, UCPD_CR_FRSRXEN); +} + +/** + * @brief Set cc enable + * @rmtoll CR CC1VCONNEN LL_UCPD_SetccEnable + * @param UCPDx UCPD Instance + * @param CCEnable This parameter can be one of the following values: + * @arg @ref LL_UCPD_CCENABLE_NONE + * @arg @ref LL_UCPD_CCENABLE_CC1 + * @arg @ref LL_UCPD_CCENABLE_CC2 + * @arg @ref LL_UCPD_CCENABLE_CC1CC2 + * @retval None + */ +__STATIC_INLINE void LL_UCPD_SetccEnable(UCPD_TypeDef *UCPDx, uint32_t CCEnable) +{ + MODIFY_REG(UCPDx->CR, UCPD_CR_CCENABLE, CCEnable); +} + +/** + * @brief Set UCPD SNK role + * @rmtoll CR ANAMODE LL_UCPD_SetSNKRole + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_SetSNKRole(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->CR, UCPD_CR_ANAMODE); +} + +/** + * @brief Set UCPD SRC role + * @rmtoll CR ANAMODE LL_UCPD_SetSRCRole + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_SetSRCRole(UCPD_TypeDef *UCPDx) +{ + CLEAR_BIT(UCPDx->CR, UCPD_CR_ANAMODE); +} + +/** + * @brief Get UCPD Role + * @rmtoll CR ANAMODE LL_UCPD_GetRole + * @param UCPDx UCPD Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_UCPD_ROLE_SNK + * @arg @ref LL_UCPD_ROLE_SRC + */ +__STATIC_INLINE uint32_t LL_UCPD_GetRole(UCPD_TypeDef const *const UCPDx) +{ + return (uint32_t)(READ_BIT(UCPDx->CR, UCPD_CR_ANAMODE)); +} + +/** + * @brief Set Rp resistor + * @rmtoll CR ANASUBMODE LL_UCPD_SetRpResistor + * @param UCPDx UCPD Instance + * @param Resistor This parameter can be one of the following values: + * @arg @ref LL_UCPD_RESISTOR_DEFAULT + * @arg @ref LL_UCPD_RESISTOR_1_5A + * @arg @ref LL_UCPD_RESISTOR_3_0A + * @arg @ref LL_UCPD_RESISTOR_NONE + * @retval None + */ +__STATIC_INLINE void LL_UCPD_SetRpResistor(UCPD_TypeDef *UCPDx, uint32_t Resistor) +{ + MODIFY_REG(UCPDx->CR, UCPD_CR_ANASUBMODE, Resistor); +} + +/** + * @brief Set CC pin + * @rmtoll CR PHYCCSEL LL_UCPD_SetCCPin + * @param UCPDx UCPD Instance + * @param CCPin This parameter can be one of the following values: + * @arg @ref LL_UCPD_CCPIN_CC1 + * @arg @ref LL_UCPD_CCPIN_CC2 + * @retval None + */ +__STATIC_INLINE void LL_UCPD_SetCCPin(UCPD_TypeDef *UCPDx, uint32_t CCPin) +{ + MODIFY_REG(UCPDx->CR, UCPD_CR_PHYCCSEL, CCPin); +} + +/** + * @brief Rx enable + * @rmtoll CR PHYRXEN LL_UCPD_RxEnable + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_RxEnable(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->CR, UCPD_CR_PHYRXEN); +} + +/** + * @brief Rx disable + * @rmtoll CR PHYRXEN LL_UCPD_RxDisable + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_RxDisable(UCPD_TypeDef *UCPDx) +{ + CLEAR_BIT(UCPDx->CR, UCPD_CR_PHYRXEN); +} + +/** + * @brief Set Rx mode + * @rmtoll CR RXMODE LL_UCPD_SetRxMode + * @param UCPDx UCPD Instance + * @param RxMode This parameter can be one of the following values: + * @arg @ref LL_UCPD_RXMODE_NORMAL + * @arg @ref LL_UCPD_RXMODE_BIST_TEST_DATA + * @retval None + */ +__STATIC_INLINE void LL_UCPD_SetRxMode(UCPD_TypeDef *UCPDx, uint32_t RxMode) +{ + MODIFY_REG(UCPDx->CR, UCPD_CR_RXMODE, RxMode); +} + +/** + * @brief Send Hard Reset + * @rmtoll CR TXHRST LL_UCPD_SendHardReset + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_SendHardReset(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->CR, UCPD_CR_TXHRST); +} + +/** + * @brief Send message + * @rmtoll CR TXSEND LL_UCPD_SendMessage + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_SendMessage(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->CR, UCPD_CR_TXSEND); +} + +/** + * @brief Set Tx mode + * @rmtoll CR TXMODE LL_UCPD_SetTxMode + * @param UCPDx UCPD Instance + * @param TxMode This parameter can be one of the following values: + * @arg @ref LL_UCPD_TXMODE_NORMAL + * @arg @ref LL_UCPD_TXMODE_CABLE_RESET + * @arg @ref LL_UCPD_TXMODE_BIST_CARRIER2 + * @retval None + */ +__STATIC_INLINE void LL_UCPD_SetTxMode(UCPD_TypeDef *UCPDx, uint32_t TxMode) +{ + MODIFY_REG(UCPDx->CR, UCPD_CR_TXMODE, TxMode); +} + +/** + * @} + */ + +/** @defgroup UCPD_LL_EF_IT_Management Interrupt Management + * @{ + */ + +/** + * @brief Enable FRS interrupt + * @rmtoll IMR FRSEVTIE LL_UCPD_EnableIT_FRS + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_EnableIT_FRS(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->IMR, UCPD_IMR_FRSEVTIE); +} + +/** + * @brief Enable type c event on CC2 + * @rmtoll IMR TYPECEVT2IE LL_UCPD_EnableIT_TypeCEventCC2 + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_EnableIT_TypeCEventCC2(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->IMR, UCPD_IMR_TYPECEVT2IE); +} + +/** + * @brief Enable type c event on CC1 + * @rmtoll IMR TYPECEVT1IE LL_UCPD_EnableIT_TypeCEventCC1 + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_EnableIT_TypeCEventCC1(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->IMR, UCPD_IMR_TYPECEVT1IE); +} + +/** + * @brief Enable Rx message end interrupt + * @rmtoll IMR RXMSGENDIE LL_UCPD_EnableIT_RxMsgEnd + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_EnableIT_RxMsgEnd(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->IMR, UCPD_IMR_RXMSGENDIE); +} + +/** + * @brief Enable Rx overrun interrupt + * @rmtoll IMR RXOVRIE LL_UCPD_EnableIT_RxOvr + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_EnableIT_RxOvr(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->IMR, UCPD_IMR_RXOVRIE); +} + +/** + * @brief Enable Rx hard resrt interrupt + * @rmtoll IMR RXHRSTDETIE LL_UCPD_EnableIT_RxHRST + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_EnableIT_RxHRST(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->IMR, UCPD_IMR_RXHRSTDETIE); +} + +/** + * @brief Enable Rx orderset interrupt + * @rmtoll IMR RXORDDETIE LL_UCPD_EnableIT_RxOrderSet + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_EnableIT_RxOrderSet(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->IMR, UCPD_IMR_RXORDDETIE); +} + +/** + * @brief Enable Rx non empty interrupt + * @rmtoll IMR RXNEIE LL_UCPD_EnableIT_RxNE + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_EnableIT_RxNE(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->IMR, UCPD_IMR_RXNEIE); +} + +/** + * @brief Enable TX underrun interrupt + * @rmtoll IMR TXUNDIE LL_UCPD_EnableIT_TxUND + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_EnableIT_TxUND(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->IMR, UCPD_IMR_TXUNDIE); +} + +/** + * @brief Enable hard reset sent interrupt + * @rmtoll IMR HRSTSENTIE LL_UCPD_EnableIT_TxHRSTSENT + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_EnableIT_TxHRSTSENT(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->IMR, UCPD_IMR_HRSTSENTIE); +} + +/** + * @brief Enable hard reset discard interrupt + * @rmtoll IMR HRSTDISCIE LL_UCPD_EnableIT_TxHRSTDISC + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_EnableIT_TxHRSTDISC(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->IMR, UCPD_IMR_HRSTDISCIE); +} + +/** + * @brief Enable Tx message abort interrupt + * @rmtoll IMR TXMSGABTIE LL_UCPD_EnableIT_TxMSGABT + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_EnableIT_TxMSGABT(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->IMR, UCPD_IMR_TXMSGABTIE); +} + +/** + * @brief Enable Tx message sent interrupt + * @rmtoll IMR TXMSGSENTIE LL_UCPD_EnableIT_TxMSGSENT + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_EnableIT_TxMSGSENT(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->IMR, UCPD_IMR_TXMSGSENTIE); +} + +/** + * @brief Enable Tx message discarded interrupt + * @rmtoll IMR TXMSGDISCIE LL_UCPD_EnableIT_TxMSGDISC + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_EnableIT_TxMSGDISC(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->IMR, UCPD_IMR_TXMSGDISCIE); +} + +/** + * @brief Enable Tx data receive interrupt + * @rmtoll IMR TXISIE LL_UCPD_EnableIT_TxIS + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_EnableIT_TxIS(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->IMR, UCPD_IMR_TXISIE); +} + +/** + * @brief Disable FRS interrupt + * @rmtoll IMR FRSEVTIE LL_UCPD_DisableIT_FRS + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_DisableIT_FRS(UCPD_TypeDef *UCPDx) +{ + CLEAR_BIT(UCPDx->IMR, UCPD_IMR_FRSEVTIE); +} + +/** + * @brief Disable type c event on CC2 + * @rmtoll IMR TYPECEVT2IE LL_UCPD_DisableIT_TypeCEventCC2 + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_DisableIT_TypeCEventCC2(UCPD_TypeDef *UCPDx) +{ + CLEAR_BIT(UCPDx->IMR, UCPD_IMR_TYPECEVT2IE); +} + +/** + * @brief Disable type c event on CC1 + * @rmtoll IMR TYPECEVT1IE LL_UCPD_DisableIT_TypeCEventCC1 + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_DisableIT_TypeCEventCC1(UCPD_TypeDef *UCPDx) +{ + CLEAR_BIT(UCPDx->IMR, UCPD_IMR_TYPECEVT1IE); +} + +/** + * @brief Disable Rx message end interrupt + * @rmtoll IMR RXMSGENDIE LL_UCPD_DisableIT_RxMsgEnd + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_DisableIT_RxMsgEnd(UCPD_TypeDef *UCPDx) +{ + CLEAR_BIT(UCPDx->IMR, UCPD_IMR_RXMSGENDIE); +} + +/** + * @brief Disable Rx overrun interrupt + * @rmtoll IMR RXOVRIE LL_UCPD_DisableIT_RxOvr + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_DisableIT_RxOvr(UCPD_TypeDef *UCPDx) +{ + CLEAR_BIT(UCPDx->IMR, UCPD_IMR_RXOVRIE); +} + +/** + * @brief Disable Rx hard resrt interrupt + * @rmtoll IMR RXHRSTDETIE LL_UCPD_DisableIT_RxHRST + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_DisableIT_RxHRST(UCPD_TypeDef *UCPDx) +{ + CLEAR_BIT(UCPDx->IMR, UCPD_IMR_RXHRSTDETIE); +} + +/** + * @brief Disable Rx orderset interrupt + * @rmtoll IMR RXORDDETIE LL_UCPD_DisableIT_RxOrderSet + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_DisableIT_RxOrderSet(UCPD_TypeDef *UCPDx) +{ + CLEAR_BIT(UCPDx->IMR, UCPD_IMR_RXORDDETIE); +} + +/** + * @brief Disable Rx non empty interrupt + * @rmtoll IMR RXNEIE LL_UCPD_DisableIT_RxNE + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_DisableIT_RxNE(UCPD_TypeDef *UCPDx) +{ + CLEAR_BIT(UCPDx->IMR, UCPD_IMR_RXNEIE); +} + +/** + * @brief Disable TX underrun interrupt + * @rmtoll IMR TXUNDIE LL_UCPD_DisableIT_TxUND + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_DisableIT_TxUND(UCPD_TypeDef *UCPDx) +{ + CLEAR_BIT(UCPDx->IMR, UCPD_IMR_TXUNDIE); +} + +/** + * @brief Disable hard reset sent interrupt + * @rmtoll IMR HRSTSENTIE LL_UCPD_DisableIT_TxHRSTSENT + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_DisableIT_TxHRSTSENT(UCPD_TypeDef *UCPDx) +{ + CLEAR_BIT(UCPDx->IMR, UCPD_IMR_HRSTSENTIE); +} + +/** + * @brief Disable hard reset discard interrupt + * @rmtoll IMR HRSTDISCIE LL_UCPD_DisableIT_TxHRSTDISC + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_DisableIT_TxHRSTDISC(UCPD_TypeDef *UCPDx) +{ + CLEAR_BIT(UCPDx->IMR, UCPD_IMR_HRSTDISCIE); +} + +/** + * @brief Disable Tx message abort interrupt + * @rmtoll IMR TXMSGABTIE LL_UCPD_DisableIT_TxMSGABT + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_DisableIT_TxMSGABT(UCPD_TypeDef *UCPDx) +{ + CLEAR_BIT(UCPDx->IMR, UCPD_IMR_TXMSGABTIE); +} + +/** + * @brief Disable Tx message sent interrupt + * @rmtoll IMR TXMSGSENTIE LL_UCPD_DisableIT_TxMSGSENT + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_DisableIT_TxMSGSENT(UCPD_TypeDef *UCPDx) +{ + CLEAR_BIT(UCPDx->IMR, UCPD_IMR_TXMSGSENTIE); +} + +/** + * @brief Disable Tx message discarded interrupt + * @rmtoll IMR TXMSGDISCIE LL_UCPD_DisableIT_TxMSGDISC + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_DisableIT_TxMSGDISC(UCPD_TypeDef *UCPDx) +{ + CLEAR_BIT(UCPDx->IMR, UCPD_IMR_TXMSGDISCIE); +} + +/** + * @brief Disable Tx data receive interrupt + * @rmtoll IMR TXISIE LL_UCPD_DisableIT_TxIS + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_DisableIT_TxIS(UCPD_TypeDef *UCPDx) +{ + CLEAR_BIT(UCPDx->IMR, UCPD_IMR_TXISIE); +} + +/** + * @brief Check if FRS interrupt enabled + * @rmtoll IMR FRSEVTIE LL_UCPD_DisableIT_FRS + * @param UCPDx UCPD Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_UCPD_IsEnableIT_FRS(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->IMR, UCPD_IMR_FRSEVTIE) == UCPD_IMR_FRSEVTIE) ? 1UL : 0UL); +} + +/** + * @brief Check if type c event on CC2 enabled + * @rmtoll IMR TYPECEVT2IE LL_UCPD_DisableIT_TypeCEventCC2 + * @param UCPDx UCPD Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_UCPD_IsEnableIT_TypeCEventCC2(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->IMR, UCPD_IMR_TYPECEVT2IE) == UCPD_IMR_TYPECEVT2IE) ? 1UL : 0UL); +} + +/** + * @brief Check if type c event on CC1 enabled + * @rmtoll IMR2 TYPECEVT1IE LL_UCPD_IsEnableIT_TypeCEventCC1 + * @param UCPDx UCPD Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_UCPD_IsEnableIT_TypeCEventCC1(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->IMR, UCPD_IMR_TYPECEVT1IE) == UCPD_IMR_TYPECEVT1IE) ? 1UL : 0UL); +} + +/** + * @brief Check if Rx message end interrupt enabled + * @rmtoll IMR RXMSGENDIE LL_UCPD_IsEnableIT_RxMsgEnd + * @param UCPDx UCPD Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_UCPD_IsEnableIT_RxMsgEnd(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->IMR, UCPD_IMR_RXMSGENDIE) == UCPD_IMR_RXMSGENDIE) ? 1UL : 0UL); +} + +/** + * @brief Check if Rx overrun interrupt enabled + * @rmtoll IMR RXOVRIE LL_UCPD_IsEnableIT_RxOvr + * @param UCPDx UCPD Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_UCPD_IsEnableIT_RxOvr(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->IMR, UCPD_IMR_RXOVRIE) == UCPD_IMR_RXOVRIE) ? 1UL : 0UL); +} + +/** + * @brief Check if Rx hard resrt interrupt enabled + * @rmtoll IMR RXHRSTDETIE LL_UCPD_IsEnableIT_RxHRST + * @param UCPDx UCPD Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_UCPD_IsEnableIT_RxHRST(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->IMR, UCPD_IMR_RXHRSTDETIE) == UCPD_IMR_RXHRSTDETIE) ? 1UL : 0UL); +} + +/** + * @brief Check if Rx orderset interrupt enabled + * @rmtoll IMR RXORDDETIE LL_UCPD_IsEnableIT_RxOrderSet + * @param UCPDx UCPD Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_UCPD_IsEnableIT_RxOrderSet(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->IMR, UCPD_IMR_RXORDDETIE) == UCPD_IMR_RXORDDETIE) ? 1UL : 0UL); +} + +/** + * @brief Check if Rx non empty interrupt enabled + * @rmtoll IMR RXNEIE LL_UCPD_IsEnableIT_RxNE + * @param UCPDx UCPD Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_UCPD_IsEnableIT_RxNE(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->IMR, UCPD_IMR_RXNEIE) == UCPD_IMR_RXNEIE) ? 1UL : 0UL); +} + +/** + * @brief Check if TX underrun interrupt enabled + * @rmtoll IMR TXUNDIE LL_UCPD_IsEnableIT_TxUND + * @param UCPDx UCPD Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_UCPD_IsEnableIT_TxUND(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->IMR, UCPD_IMR_TXUNDIE) == UCPD_IMR_TXUNDIE) ? 1UL : 0UL); +} + +/** + * @brief Check if hard reset sent interrupt enabled + * @rmtoll IMR HRSTSENTIE LL_UCPD_IsEnableIT_TxHRSTSENT + * @param UCPDx UCPD Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_UCPD_IsEnableIT_TxHRSTSENT(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->IMR, UCPD_IMR_HRSTSENTIE) == UCPD_IMR_HRSTSENTIE) ? 1UL : 0UL); +} + +/** + * @brief Check if hard reset discard interrupt enabled + * @rmtoll IMR HRSTDISCIE LL_UCPD_IsEnableIT_TxHRSTDISC + * @param UCPDx UCPD Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_UCPD_IsEnableIT_TxHRSTDISC(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->IMR, UCPD_IMR_HRSTDISCIE) == UCPD_IMR_HRSTDISCIE) ? 1UL : 0UL); +} + +/** + * @brief Check if Tx message abort interrupt enabled + * @rmtoll IMR TXMSGABTIE LL_UCPD_IsEnableIT_TxMSGABT + * @param UCPDx UCPD Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_UCPD_IsEnableIT_TxMSGABT(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->IMR, UCPD_IMR_TXMSGABTIE) == UCPD_IMR_TXMSGABTIE) ? 1UL : 0UL); +} + +/** + * @brief Check if Tx message sent interrupt enabled + * @rmtoll IMR TXMSGSENTIE LL_UCPD_IsEnableIT_TxMSGSENT + * @param UCPDx UCPD Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_UCPD_IsEnableIT_TxMSGSENT(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->IMR, UCPD_IMR_TXMSGSENTIE) == UCPD_IMR_TXMSGSENTIE) ? 1UL : 0UL); +} + +/** + * @brief Check if Tx message discarded interrupt enabled + * @rmtoll IMR TXMSGDISCIE LL_UCPD_IsEnableIT_TxMSGDISC + * @param UCPDx UCPD Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_UCPD_IsEnableIT_TxMSGDISC(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->IMR, UCPD_IMR_TXMSGDISCIE) == UCPD_IMR_TXMSGDISCIE) ? 1UL : 0UL); +} + +/** + * @brief Check if Tx data receive interrupt enabled + * @rmtoll IMR TXISIE LL_UCPD_IsEnableIT_TxIS + * @param UCPDx UCPD Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_UCPD_IsEnableIT_TxIS(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->IMR, UCPD_IMR_TXISIE) == UCPD_IMR_TXISIE) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup UCPD_LL_EF_IT_Clear Interrupt Clear + * @{ + */ + +/** + * @brief Clear FRS interrupt + * @rmtoll ICR FRSEVTIE LL_UCPD_ClearFlag_FRS + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_ClearFlag_FRS(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->ICR, UCPD_ICR_FRSEVTCF); +} + +/** + * @brief Clear type c event on CC2 + * @rmtoll IIMR TYPECEVT2IE LL_UCPD_ClearFlag_TypeCEventCC2 + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_ClearFlag_TypeCEventCC2(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->ICR, UCPD_ICR_TYPECEVT2CF); +} + +/** + * @brief Clear type c event on CC1 + * @rmtoll IIMR TYPECEVT1IE LL_UCPD_ClearFlag_TypeCEventCC1 + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_ClearFlag_TypeCEventCC1(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->ICR, UCPD_ICR_TYPECEVT1CF); +} + +/** + * @brief Clear Rx message end interrupt + * @rmtoll ICR RXMSGENDIE LL_UCPD_ClearFlag_RxMsgEnd + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_ClearFlag_RxMsgEnd(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->ICR, UCPD_ICR_RXMSGENDCF); +} + +/** + * @brief Clear Rx overrun interrupt + * @rmtoll ICR RXOVRIE LL_UCPD_ClearFlag_RxOvr + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_ClearFlag_RxOvr(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->ICR, UCPD_ICR_RXOVRCF); +} + +/** + * @brief Clear Rx hard resrt interrupt + * @rmtoll ICR RXHRSTDETIE LL_UCPD_ClearFlag_RxHRST + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_ClearFlag_RxHRST(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->ICR, UCPD_ICR_RXHRSTDETCF); +} + +/** + * @brief Clear Rx orderset interrupt + * @rmtoll ICR RXORDDETIE LL_UCPD_ClearFlag_RxOrderSet + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_ClearFlag_RxOrderSet(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->ICR, UCPD_ICR_RXORDDETCF); +} + +/** + * @brief Clear TX underrun interrupt + * @rmtoll ICR TXUNDIE LL_UCPD_ClearFlag_TxUND + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_ClearFlag_TxUND(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->ICR, UCPD_ICR_TXUNDCF); +} + +/** + * @brief Clear hard reset sent interrupt + * @rmtoll ICR HRSTSENTIE LL_UCPD_ClearFlag_TxHRSTSENT + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_ClearFlag_TxHRSTSENT(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->ICR, UCPD_ICR_HRSTSENTCF); +} + +/** + * @brief Clear hard reset discard interrupt + * @rmtoll ICR HRSTDISCIE LL_UCPD_ClearFlag_TxHRSTDISC + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_ClearFlag_TxHRSTDISC(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->ICR, UCPD_ICR_HRSTDISCCF); +} + +/** + * @brief Clear Tx message abort interrupt + * @rmtoll ICR TXMSGABTIE LL_UCPD_ClearFlag_TxMSGABT + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_ClearFlag_TxMSGABT(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->ICR, UCPD_ICR_TXMSGABTCF); +} + +/** + * @brief Clear Tx message sent interrupt + * @rmtoll ICR TXMSGSENTIE LL_UCPD_ClearFlag_TxMSGSENT + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_ClearFlag_TxMSGSENT(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->ICR, UCPD_ICR_TXMSGSENTCF); +} + +/** + * @brief Clear Tx message discarded interrupt + * @rmtoll ICR TXMSGDISCIE LL_UCPD_ClearFlag_TxMSGDISC + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_ClearFlag_TxMSGDISC(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->ICR, UCPD_ICR_TXMSGDISCCF); +} + +/** + * @} + */ + +/** @defgroup UCPD_LL_EF_FLAG_Management FLAG Management + * @{ + */ + +/** + * @brief Check if FRS interrupt + * @rmtoll SR FRSEVT LL_UCPD_IsActiveFlag_FRS + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE uint32_t LL_UCPD_IsActiveFlag_FRS(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->SR, UCPD_SR_FRSEVT) == UCPD_SR_FRSEVT) ? 1UL : 0UL); +} + +/** + * @brief Check if type c event on CC2 + * @rmtoll SR TYPECEVT2 LL_UCPD_IsActiveFlag_TypeCEventCC2 + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE uint32_t LL_UCPD_IsActiveFlag_TypeCEventCC2(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->SR, UCPD_SR_TYPECEVT2) == UCPD_SR_TYPECEVT2) ? 1UL : 0UL); +} + +/** + * @brief Check if type c event on CC1 + * @rmtoll SR TYPECEVT1 LL_UCPD_IsActiveFlag_TypeCEventCC1 + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE uint32_t LL_UCPD_IsActiveFlag_TypeCEventCC1(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->SR, UCPD_SR_TYPECEVT1) == UCPD_SR_TYPECEVT1) ? 1UL : 0UL); +} + +/** + * @brief Check if Rx message end interrupt + * @rmtoll SR RXMSGEND LL_UCPD_IsActiveFlag_RxMsgEnd + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE uint32_t LL_UCPD_IsActiveFlag_RxMsgEnd(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->SR, UCPD_SR_RXMSGEND) == UCPD_SR_RXMSGEND) ? 1UL : 0UL); +} + +/** + * @brief Check if Rx overrun interrupt + * @rmtoll SR RXOVR LL_UCPD_IsActiveFlag_RxOvr + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE uint32_t LL_UCPD_IsActiveFlag_RxOvr(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->SR, UCPD_SR_RXOVR) == UCPD_SR_RXOVR) ? 1UL : 0UL); +} + +/** + * @brief Check if Rx hard resrt interrupt + * @rmtoll SR RXHRSTDET LL_UCPD_IsActiveFlag_RxHRST + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE uint32_t LL_UCPD_IsActiveFlag_RxHRST(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->SR, UCPD_SR_RXHRSTDET) == UCPD_SR_RXHRSTDET) ? 1UL : 0UL); +} + +/** + * @brief Check if Rx orderset interrupt + * @rmtoll SR RXORDDET LL_UCPD_IsActiveFlag_RxOrderSet + * @param UCPDx UCPD Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_UCPD_IsActiveFlag_RxOrderSet(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->SR, UCPD_SR_RXORDDET) == UCPD_SR_RXORDDET) ? 1UL : 0UL); +} + +/** + * @brief Check if Rx non empty interrupt + * @rmtoll SR RXNE LL_UCPD_IsActiveFlag_RxNE + * @param UCPDx UCPD Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_UCPD_IsActiveFlag_RxNE(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->SR, UCPD_SR_RXNE) == UCPD_SR_RXNE) ? 1UL : 0UL); +} + +/** + * @brief Check if TX underrun interrupt + * @rmtoll SR TXUND LL_UCPD_IsActiveFlag_TxUND + * @param UCPDx UCPD Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_UCPD_IsActiveFlag_TxUND(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->SR, UCPD_SR_TXUND) == UCPD_SR_TXUND) ? 1UL : 0UL); +} + +/** + * @brief Check if hard reset sent interrupt + * @rmtoll SR HRSTSENT LL_UCPD_IsActiveFlag_TxHRSTSENT + * @param UCPDx UCPD Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_UCPD_IsActiveFlag_TxHRSTSENT(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->SR, UCPD_SR_HRSTSENT) == UCPD_SR_HRSTSENT) ? 1UL : 0UL); +} + +/** + * @brief Check if hard reset discard interrupt + * @rmtoll SR HRSTDISC LL_UCPD_IsActiveFlag_TxHRSTDISC + * @param UCPDx UCPD Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_UCPD_IsActiveFlag_TxHRSTDISC(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->SR, UCPD_SR_HRSTDISC) == UCPD_SR_HRSTDISC) ? 1UL : 0UL); +} + +/** + * @brief Check if Tx message abort interrupt + * @rmtoll SR TXMSGABT LL_UCPD_IsActiveFlag_TxMSGABT + * @param UCPDx UCPD Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_UCPD_IsActiveFlag_TxMSGABT(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->SR, UCPD_SR_TXMSGABT) == UCPD_SR_TXMSGABT) ? 1UL : 0UL); +} + +/** + * @brief Check if Tx message sent interrupt + * @rmtoll SR TXMSGSENT LL_UCPD_IsActiveFlag_TxMSGSENT + * @param UCPDx UCPD Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_UCPD_IsActiveFlag_TxMSGSENT(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->SR, UCPD_SR_TXMSGSENT) == UCPD_SR_TXMSGSENT) ? 1UL : 0UL); +} + +/** + * @brief Check if Tx message discarded interrupt + * @rmtoll SR TXMSGDISC LL_UCPD_IsActiveFlag_TxMSGDISC + * @param UCPDx UCPD Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_UCPD_IsActiveFlag_TxMSGDISC(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->SR, UCPD_SR_TXMSGDISC) == UCPD_SR_TXMSGDISC) ? 1UL : 0UL); +} + +/** + * @brief Check if Tx data receive interrupt + * @rmtoll SR TXIS LL_UCPD_IsActiveFlag_TxIS + * @param UCPDx UCPD Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_UCPD_IsActiveFlag_TxIS(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->SR, UCPD_SR_TXIS) == UCPD_SR_TXIS) ? 1UL : 0UL); +} + +/** + * @brief return the vstate value for CC2 + * @rmtoll SR TXIS LL_UCPD_GetTypeCVstateCC2 + * @param UCPDx UCPD Instance + * @retval val + */ +__STATIC_INLINE uint32_t LL_UCPD_GetTypeCVstateCC2(UCPD_TypeDef const *const UCPDx) +{ + return UCPDx->SR & UCPD_SR_TYPEC_VSTATE_CC2; +} + +/** + * @brief return the vstate value for CC1 + * @rmtoll SR TXIS LL_UCPD_GetTypeCVstateCC1 + * @param UCPDx UCPD Instance + * @retval val + */ +__STATIC_INLINE uint32_t LL_UCPD_GetTypeCVstateCC1(UCPD_TypeDef const *const UCPDx) +{ + return UCPDx->SR & UCPD_SR_TYPEC_VSTATE_CC1; +} + +/** + * @} + */ + + +/** @defgroup UCPD_LL_EF_DMA_Management DMA Management + * @{ + */ + +/** + * @brief Rx DMA Enable + * @rmtoll CFG1 RXDMAEN LL_UCPD_RxDMAEnable + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_RxDMAEnable(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->CFG1, UCPD_CFG1_RXDMAEN); +} + +/** + * @brief Rx DMA Disable + * @rmtoll CFG1 RXDMAEN LL_UCPD_RxDMADisable + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_RxDMADisable(UCPD_TypeDef *UCPDx) +{ + CLEAR_BIT(UCPDx->CFG1, UCPD_CFG1_RXDMAEN); +} + +/** + * @brief Tx DMA Enable + * @rmtoll CFG1 TXDMAEN LL_UCPD_TxDMAEnable + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_TxDMAEnable(UCPD_TypeDef *UCPDx) +{ + SET_BIT(UCPDx->CFG1, UCPD_CFG1_TXDMAEN); +} + +/** + * @brief Tx DMA Disable + * @rmtoll CFG1 TXDMAEN LL_UCPD_TxDMADisable + * @param UCPDx UCPD Instance + * @retval None + */ +__STATIC_INLINE void LL_UCPD_TxDMADisable(UCPD_TypeDef *UCPDx) +{ + CLEAR_BIT(UCPDx->CFG1, UCPD_CFG1_TXDMAEN); +} + +/** + * @brief Check if DMA Tx is enabled + * @rmtoll CR2 TXDMAEN LL_UCPD_IsEnabledTxDMA + * @param UCPDx UCPD Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_UCPD_IsEnabledTxDMA(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->CFG1, UCPD_CFG1_TXDMAEN) == (UCPD_CFG1_TXDMAEN)) ? 1UL : 0UL); +} + +/** + * @brief Check if DMA Rx is enabled + * @rmtoll CR2 RXDMAEN LL_UCPD_IsEnabledRxDMA + * @param UCPDx UCPD Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_UCPD_IsEnabledRxDMA(UCPD_TypeDef const *const UCPDx) +{ + return ((READ_BIT(UCPDx->CFG1, UCPD_CFG1_RXDMAEN) == (UCPD_CFG1_RXDMAEN)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup UCPD_LL_EF_DATA_Management DATA Management + * @{ + */ + +/** + * @brief write the orderset for Tx message + * @rmtoll TX_ORDSET TXORDSET LL_UCPD_WriteTxOrderSet + * @param UCPDx UCPD Instance + * @param TxOrderSet one of the following value + * @arg @ref LL_UCPD_ORDERED_SET_SOP + * @arg @ref LL_UCPD_ORDERED_SET_SOP1 + * @arg @ref LL_UCPD_ORDERED_SET_SOP2 + * @arg @ref LL_UCPD_ORDERED_SET_HARD_RESET + * @arg @ref LL_UCPD_ORDERED_SET_CABLE_RESET + * @arg @ref LL_UCPD_ORDERED_SET_SOP1_DEBUG + * @arg @ref LL_UCPD_ORDERED_SET_SOP2_DEBUG + * @retval None + */ +__STATIC_INLINE void LL_UCPD_WriteTxOrderSet(UCPD_TypeDef *UCPDx, uint32_t TxOrderSet) +{ + WRITE_REG(UCPDx->TX_ORDSET, TxOrderSet); +} + +/** + * @brief write the Tx paysize + * @rmtoll TX_PAYSZ TXPAYSZ LL_UCPD_WriteTxPaySize + * @param UCPDx UCPD Instance + * @param TxPaySize + * @retval None. + */ +__STATIC_INLINE void LL_UCPD_WriteTxPaySize(UCPD_TypeDef *UCPDx, uint32_t TxPaySize) +{ + WRITE_REG(UCPDx->TX_PAYSZ, TxPaySize); +} + +/** + * @brief Write data + * @rmtoll TXDR DR LL_UCPD_WriteData + * @param UCPDx UCPD Instance + * @param Data Value between Min_Data=0x00 and Max_Data=0xFF + * @retval None. + */ +__STATIC_INLINE void LL_UCPD_WriteData(UCPD_TypeDef *UCPDx, uint8_t Data) +{ + WRITE_REG(UCPDx->TXDR, Data); +} + +/** + * @brief read RX the orderset + * @rmtoll RX_ORDSET RXORDSET LL_UCPD_ReadRxOrderSet + * @param UCPDx UCPD Instance + * @retval RxOrderSet one of the following value + * @arg @ref LL_UCPD_RXORDSET_SOP + * @arg @ref LL_UCPD_RXORDSET_SOP1 + * @arg @ref LL_UCPD_RXORDSET_SOP2 + * @arg @ref LL_UCPD_RXORDSET_SOP1_DEBUG + * @arg @ref LL_UCPD_RXORDSET_SOP2_DEBUG + * @arg @ref LL_UCPD_RXORDSET_CABLE_RESET + * @arg @ref LL_UCPD_RXORDSET_SOPEXT1 + * @arg @ref LL_UCPD_RXORDSET_SOPEXT2 + */ +__STATIC_INLINE uint32_t LL_UCPD_ReadRxOrderSet(UCPD_TypeDef const *const UCPDx) +{ + return READ_BIT(UCPDx->RX_ORDSET, UCPD_RX_ORDSET_RXORDSET); +} + +/** + * @brief Read the Rx paysize + * @rmtoll RX_PAYSZ RXPAYSZ LL_UCPD_ReadRxPaySize + * @param UCPDx UCPD Instance + * @retval RXPaysize. + */ +__STATIC_INLINE uint32_t LL_UCPD_ReadRxPaySize(UCPD_TypeDef const *const UCPDx) +{ + return READ_BIT(UCPDx->RX_PAYSZ, UCPD_RX_PAYSZ_RXPAYSZ); +} + +/** + * @brief Read data + * @rmtoll RXDR RXDATA LL_UCPD_ReadData + * @param UCPDx UCPD Instance + * @retval RxData Value between Min_Data=0x00 and Max_Data=0xFF + */ +__STATIC_INLINE uint32_t LL_UCPD_ReadData(UCPD_TypeDef const *const UCPDx) +{ + return READ_REG(UCPDx->RXDR); +} + +/** + * @brief Set Rx OrderSet Ext1 + * @rmtoll RX_ORDEXT1 RXSOPX1 LL_UCPD_SetRxOrdExt1 + * @param UCPDx UCPD Instance + * @param SOPExt Value between Min_Data=0x00000 and Max_Data=0xFFFFF + * @retval None + */ +__STATIC_INLINE void LL_UCPD_SetRxOrdExt1(UCPD_TypeDef *UCPDx, uint32_t SOPExt) +{ + WRITE_REG(UCPDx->RX_ORDEXT1, SOPExt); +} + +/** + * @brief Set Rx OrderSet Ext2 + * @rmtoll RX_ORDEXT2 RXSOPX2 LL_UCPD_SetRxOrdExt2 + * @param UCPDx UCPD Instance + * @param SOPExt Value between Min_Data=0x00000 and Max_Data=0xFFFFF + * @retval None + */ +__STATIC_INLINE void LL_UCPD_SetRxOrdExt2(UCPD_TypeDef *UCPDx, uint32_t SOPExt) +{ + WRITE_REG(UCPDx->RX_ORDEXT2, SOPExt); +} + +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup UCPD_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +ErrorStatus LL_UCPD_DeInit(UCPD_TypeDef *UCPDx); +ErrorStatus LL_UCPD_Init(UCPD_TypeDef *UCPDx, LL_UCPD_InitTypeDef *UCPD_InitStruct); +void LL_UCPD_StructInit(LL_UCPD_InitTypeDef *UCPD_InitStruct); + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +#endif /* defined (UCPD1) */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_LL_UCPD_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_usart.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_usart.h new file mode 100644 index 0000000000..11d0662b35 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_usart.h @@ -0,0 +1,4401 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_usart.h + * @author MCD Application Team + * @brief Header file of USART LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_LL_USART_H +#define STM32H5xx_LL_USART_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined(USART1) || defined(USART2) || defined(USART3) || defined(UART4) || defined(UART5) || defined(USART6) \ + || defined(UART7) || defined(UART8) || defined(UART9) || defined(USART10) || defined(USART11) || defined(UART12) + +/** @defgroup USART_LL USART + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/** @defgroup USART_LL_Private_Variables USART Private Variables + * @{ + */ +/* Array used to get the USART prescaler division decimal values versus @ref USART_LL_EC_PRESCALER values */ +static const uint32_t USART_PRESCALER_TAB[] = +{ + 1UL, + 2UL, + 4UL, + 6UL, + 8UL, + 10UL, + 12UL, + 16UL, + 32UL, + 64UL, + 128UL, + 256UL +}; +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup USART_LL_Private_Constants USART Private Constants + * @{ + */ +/** + * @} + */ +/* Private macros ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup USART_LL_Private_Macros USART Private Macros + * @{ + */ +/** + * @} + */ +#endif /*USE_FULL_LL_DRIVER*/ + +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup USART_LL_ES_INIT USART Exported Init structures + * @{ + */ + +/** + * @brief LL USART Init Structure definition + */ +typedef struct +{ + uint32_t PrescalerValue; /*!< Specifies the Prescaler to compute the communication baud rate. + This parameter can be a value of @ref USART_LL_EC_PRESCALER. + + This feature can be modified afterwards using unitary + function @ref LL_USART_SetPrescaler().*/ + + uint32_t BaudRate; /*!< This field defines expected Usart communication baud rate. + + This feature can be modified afterwards using unitary + function @ref LL_USART_SetBaudRate().*/ + + uint32_t DataWidth; /*!< Specifies the number of data bits transmitted or received in a frame. + This parameter can be a value of @ref USART_LL_EC_DATAWIDTH. + + This feature can be modified afterwards using unitary + function @ref LL_USART_SetDataWidth().*/ + + uint32_t StopBits; /*!< Specifies the number of stop bits transmitted. + This parameter can be a value of @ref USART_LL_EC_STOPBITS. + + This feature can be modified afterwards using unitary + function @ref LL_USART_SetStopBitsLength().*/ + + uint32_t Parity; /*!< Specifies the parity mode. + This parameter can be a value of @ref USART_LL_EC_PARITY. + + This feature can be modified afterwards using unitary + function @ref LL_USART_SetParity().*/ + + uint32_t TransferDirection; /*!< Specifies whether the Receive and/or Transmit mode is enabled or disabled. + This parameter can be a value of @ref USART_LL_EC_DIRECTION. + + This feature can be modified afterwards using unitary + function @ref LL_USART_SetTransferDirection().*/ + + uint32_t HardwareFlowControl; /*!< Specifies whether the hardware flow control mode is enabled or disabled. + This parameter can be a value of @ref USART_LL_EC_HWCONTROL. + + This feature can be modified afterwards using unitary + function @ref LL_USART_SetHWFlowCtrl().*/ + + uint32_t OverSampling; /*!< Specifies whether USART oversampling mode is 16 or 8. + This parameter can be a value of @ref USART_LL_EC_OVERSAMPLING. + + This feature can be modified afterwards using unitary + function @ref LL_USART_SetOverSampling().*/ + +} LL_USART_InitTypeDef; + +/** + * @brief LL USART Clock Init Structure definition + */ +typedef struct +{ + uint32_t ClockOutput; /*!< Specifies whether the USART clock is enabled or disabled. + This parameter can be a value of @ref USART_LL_EC_CLOCK. + + USART HW configuration can be modified afterwards using unitary functions + @ref LL_USART_EnableSCLKOutput() or @ref LL_USART_DisableSCLKOutput(). + For more details, refer to description of this function. */ + + uint32_t ClockPolarity; /*!< Specifies the steady state of the serial clock. + This parameter can be a value of @ref USART_LL_EC_POLARITY. + + USART HW configuration can be modified afterwards using unitary + functions @ref LL_USART_SetClockPolarity(). + For more details, refer to description of this function. */ + + uint32_t ClockPhase; /*!< Specifies the clock transition on which the bit capture is made. + This parameter can be a value of @ref USART_LL_EC_PHASE. + + USART HW configuration can be modified afterwards using unitary + functions @ref LL_USART_SetClockPhase(). + For more details, refer to description of this function. */ + + uint32_t LastBitClockPulse; /*!< Specifies whether the clock pulse corresponding to the last transmitted + data bit (MSB) has to be output on the SCLK pin in synchronous mode. + This parameter can be a value of @ref USART_LL_EC_LASTCLKPULSE. + + USART HW configuration can be modified afterwards using unitary + functions @ref LL_USART_SetLastClkPulseOutput(). + For more details, refer to description of this function. */ + +} LL_USART_ClockInitTypeDef; + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup USART_LL_Exported_Constants USART Exported Constants + * @{ + */ + +/** @defgroup USART_LL_EC_CLEAR_FLAG Clear Flags Defines + * @brief Flags defines which can be used with LL_USART_WriteReg function + * @{ + */ +#define LL_USART_ICR_PECF USART_ICR_PECF /*!< Parity error clear flag */ +#define LL_USART_ICR_FECF USART_ICR_FECF /*!< Framing error clear flag */ +#define LL_USART_ICR_NECF USART_ICR_NECF /*!< Noise error detected clear flag */ +#define LL_USART_ICR_ORECF USART_ICR_ORECF /*!< Overrun error clear flag */ +#define LL_USART_ICR_IDLECF USART_ICR_IDLECF /*!< Idle line detected clear flag */ +#define LL_USART_ICR_TXFECF USART_ICR_TXFECF /*!< TX FIFO Empty clear flag */ +#define LL_USART_ICR_TCCF USART_ICR_TCCF /*!< Transmission complete clear flag */ +#define LL_USART_ICR_TCBGTCF USART_ICR_TCBGTCF /*!< Transmission completed before guard time clear flag */ +#define LL_USART_ICR_LBDCF USART_ICR_LBDCF /*!< LIN break detection clear flag */ +#define LL_USART_ICR_CTSCF USART_ICR_CTSCF /*!< CTS clear flag */ +#define LL_USART_ICR_RTOCF USART_ICR_RTOCF /*!< Receiver timeout clear flag */ +#define LL_USART_ICR_EOBCF USART_ICR_EOBCF /*!< End of block clear flag */ +#define LL_USART_ICR_UDRCF USART_ICR_UDRCF /*!< SPI Slave Underrun clear flag */ +#define LL_USART_ICR_CMCF USART_ICR_CMCF /*!< Character match clear flag */ +#define LL_USART_ICR_WUCF USART_ICR_WUCF /*!< Wakeup from Stop mode clear flag */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_USART_ReadReg function + * @{ + */ +#define LL_USART_ISR_PE USART_ISR_PE /*!< Parity error flag */ +#define LL_USART_ISR_FE USART_ISR_FE /*!< Framing error flag */ +#define LL_USART_ISR_NE USART_ISR_NE /*!< Noise detected flag */ +#define LL_USART_ISR_ORE USART_ISR_ORE /*!< Overrun error flag */ +#define LL_USART_ISR_IDLE USART_ISR_IDLE /*!< Idle line detected flag */ +#define LL_USART_ISR_RXNE_RXFNE USART_ISR_RXNE_RXFNE /*!< Read data register or RX FIFO not empty flag */ +#define LL_USART_ISR_TC USART_ISR_TC /*!< Transmission complete flag */ +#define LL_USART_ISR_TXE_TXFNF USART_ISR_TXE_TXFNF /*!< Transmit data register empty or TX FIFO Not Full flag*/ +#define LL_USART_ISR_LBDF USART_ISR_LBDF /*!< LIN break detection flag */ +#define LL_USART_ISR_CTSIF USART_ISR_CTSIF /*!< CTS interrupt flag */ +#define LL_USART_ISR_CTS USART_ISR_CTS /*!< CTS flag */ +#define LL_USART_ISR_RTOF USART_ISR_RTOF /*!< Receiver timeout flag */ +#define LL_USART_ISR_EOBF USART_ISR_EOBF /*!< End of block flag */ +#define LL_USART_ISR_UDR USART_ISR_UDR /*!< SPI Slave underrun error flag */ +#define LL_USART_ISR_ABRE USART_ISR_ABRE /*!< Auto baud rate error flag */ +#define LL_USART_ISR_ABRF USART_ISR_ABRF /*!< Auto baud rate flag */ +#define LL_USART_ISR_BUSY USART_ISR_BUSY /*!< Busy flag */ +#define LL_USART_ISR_CMF USART_ISR_CMF /*!< Character match flag */ +#define LL_USART_ISR_SBKF USART_ISR_SBKF /*!< Send break flag */ +#define LL_USART_ISR_RWU USART_ISR_RWU /*!< Receiver wakeup from Mute mode flag */ +#define LL_USART_ISR_WUF USART_ISR_WUF /*!< Wakeup from Stop mode flag */ +#define LL_USART_ISR_TEACK USART_ISR_TEACK /*!< Transmit enable acknowledge flag */ +#define LL_USART_ISR_REACK USART_ISR_REACK /*!< Receive enable acknowledge flag */ +#define LL_USART_ISR_TXFE USART_ISR_TXFE /*!< TX FIFO empty flag */ +#define LL_USART_ISR_RXFF USART_ISR_RXFF /*!< RX FIFO full flag */ +#define LL_USART_ISR_TCBGT USART_ISR_TCBGT /*!< Transmission complete before guard time completion flag */ +#define LL_USART_ISR_RXFT USART_ISR_RXFT /*!< RX FIFO threshold flag */ +#define LL_USART_ISR_TXFT USART_ISR_TXFT /*!< TX FIFO threshold flag */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_IT IT Defines + * @brief IT defines which can be used with LL_USART_ReadReg and LL_USART_WriteReg functions + * @{ + */ +#define LL_USART_CR1_IDLEIE USART_CR1_IDLEIE /*!< IDLE interrupt enable */ +#define LL_USART_CR1_RXNEIE_RXFNEIE USART_CR1_RXNEIE_RXFNEIE /*!< Read data register and RXFIFO not empty interrupt enable */ +#define LL_USART_CR1_TCIE USART_CR1_TCIE /*!< Transmission complete interrupt enable */ +#define LL_USART_CR1_TXEIE_TXFNFIE USART_CR1_TXEIE_TXFNFIE /*!< Transmit data register empty and TX FIFO not full interrupt enable */ +#define LL_USART_CR1_PEIE USART_CR1_PEIE /*!< Parity error */ +#define LL_USART_CR1_CMIE USART_CR1_CMIE /*!< Character match interrupt enable */ +#define LL_USART_CR1_RTOIE USART_CR1_RTOIE /*!< Receiver timeout interrupt enable */ +#define LL_USART_CR1_EOBIE USART_CR1_EOBIE /*!< End of Block interrupt enable */ +#define LL_USART_CR1_TXFEIE USART_CR1_TXFEIE /*!< TX FIFO empty interrupt enable */ +#define LL_USART_CR1_RXFFIE USART_CR1_RXFFIE /*!< RX FIFO full interrupt enable */ +#define LL_USART_CR2_LBDIE USART_CR2_LBDIE /*!< LIN break detection interrupt enable */ +#define LL_USART_CR3_EIE USART_CR3_EIE /*!< Error interrupt enable */ +#define LL_USART_CR3_CTSIE USART_CR3_CTSIE /*!< CTS interrupt enable */ +#define LL_USART_CR3_WUFIE USART_CR3_WUFIE /*!< Wakeup from Stop mode interrupt enable */ +#define LL_USART_CR3_TXFTIE USART_CR3_TXFTIE /*!< TX FIFO threshold interrupt enable */ +#define LL_USART_CR3_TCBGTIE USART_CR3_TCBGTIE /*!< Transmission complete before guard time interrupt enable */ +#define LL_USART_CR3_RXFTIE USART_CR3_RXFTIE /*!< RX FIFO threshold interrupt enable */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_FIFOTHRESHOLD FIFO Threshold + * @{ + */ +#define LL_USART_FIFOTHRESHOLD_1_8 0x00000000U /*!< FIFO reaches 1/8 of its depth */ +#define LL_USART_FIFOTHRESHOLD_1_4 0x00000001U /*!< FIFO reaches 1/4 of its depth */ +#define LL_USART_FIFOTHRESHOLD_1_2 0x00000002U /*!< FIFO reaches 1/2 of its depth */ +#define LL_USART_FIFOTHRESHOLD_3_4 0x00000003U /*!< FIFO reaches 3/4 of its depth */ +#define LL_USART_FIFOTHRESHOLD_7_8 0x00000004U /*!< FIFO reaches 7/8 of its depth */ +#define LL_USART_FIFOTHRESHOLD_8_8 0x00000005U /*!< FIFO becomes empty for TX and full for RX */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_DIRECTION Communication Direction + * @{ + */ +#define LL_USART_DIRECTION_NONE 0x00000000U /*!< Transmitter and Receiver are disabled */ +#define LL_USART_DIRECTION_RX USART_CR1_RE /*!< Transmitter is disabled and Receiver is enabled */ +#define LL_USART_DIRECTION_TX USART_CR1_TE /*!< Transmitter is enabled and Receiver is disabled */ +#define LL_USART_DIRECTION_TX_RX (USART_CR1_TE |USART_CR1_RE) /*!< Transmitter and Receiver are enabled */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_PARITY Parity Control + * @{ + */ +#define LL_USART_PARITY_NONE 0x00000000U /*!< Parity control disabled */ +#define LL_USART_PARITY_EVEN USART_CR1_PCE /*!< Parity control enabled and Even Parity is selected */ +#define LL_USART_PARITY_ODD (USART_CR1_PCE | USART_CR1_PS) /*!< Parity control enabled and Odd Parity is selected */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_WAKEUP Wakeup + * @{ + */ +#define LL_USART_WAKEUP_IDLELINE 0x00000000U /*!< USART wake up from Mute mode on Idle Line */ +#define LL_USART_WAKEUP_ADDRESSMARK USART_CR1_WAKE /*!< USART wake up from Mute mode on Address Mark */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_DATAWIDTH Datawidth + * @{ + */ +#define LL_USART_DATAWIDTH_7B USART_CR1_M1 /*!< 7 bits word length : Start bit, 7 data bits, n stop bits */ +#define LL_USART_DATAWIDTH_8B 0x00000000U /*!< 8 bits word length : Start bit, 8 data bits, n stop bits */ +#define LL_USART_DATAWIDTH_9B USART_CR1_M0 /*!< 9 bits word length : Start bit, 9 data bits, n stop bits */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_OVERSAMPLING Oversampling + * @{ + */ +#define LL_USART_OVERSAMPLING_16 0x00000000U /*!< Oversampling by 16 */ +#define LL_USART_OVERSAMPLING_8 USART_CR1_OVER8 /*!< Oversampling by 8 */ +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup USART_LL_EC_CLOCK Clock Signal + * @{ + */ + +#define LL_USART_CLOCK_DISABLE 0x00000000U /*!< Clock signal not provided */ +#define LL_USART_CLOCK_ENABLE USART_CR2_CLKEN /*!< Clock signal provided */ +/** + * @} + */ +#endif /*USE_FULL_LL_DRIVER*/ + +/** @defgroup USART_LL_EC_LASTCLKPULSE Last Clock Pulse + * @{ + */ +#define LL_USART_LASTCLKPULSE_NO_OUTPUT 0x00000000U /*!< The clock pulse of the last data bit is not output to the SCLK pin */ +#define LL_USART_LASTCLKPULSE_OUTPUT USART_CR2_LBCL /*!< The clock pulse of the last data bit is output to the SCLK pin */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_PHASE Clock Phase + * @{ + */ +#define LL_USART_PHASE_1EDGE 0x00000000U /*!< The first clock transition is the first data capture edge */ +#define LL_USART_PHASE_2EDGE USART_CR2_CPHA /*!< The second clock transition is the first data capture edge */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_POLARITY Clock Polarity + * @{ + */ +#define LL_USART_POLARITY_LOW 0x00000000U /*!< Steady low value on SCLK pin outside transmission window*/ +#define LL_USART_POLARITY_HIGH USART_CR2_CPOL /*!< Steady high value on SCLK pin outside transmission window */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_PRESCALER Clock Source Prescaler + * @{ + */ +#define LL_USART_PRESCALER_DIV1 0x00000000U /*!< Input clock not divided */ +#define LL_USART_PRESCALER_DIV2 (USART_PRESC_PRESCALER_0) /*!< Input clock divided by 2 */ +#define LL_USART_PRESCALER_DIV4 (USART_PRESC_PRESCALER_1) /*!< Input clock divided by 4 */ +#define LL_USART_PRESCALER_DIV6 (USART_PRESC_PRESCALER_1 | USART_PRESC_PRESCALER_0) /*!< Input clock divided by 6 */ +#define LL_USART_PRESCALER_DIV8 (USART_PRESC_PRESCALER_2) /*!< Input clock divided by 8 */ +#define LL_USART_PRESCALER_DIV10 (USART_PRESC_PRESCALER_2 | USART_PRESC_PRESCALER_0) /*!< Input clock divided by 10 */ +#define LL_USART_PRESCALER_DIV12 (USART_PRESC_PRESCALER_2 | USART_PRESC_PRESCALER_1) /*!< Input clock divided by 12 */ +#define LL_USART_PRESCALER_DIV16 (USART_PRESC_PRESCALER_2 | USART_PRESC_PRESCALER_1 | USART_PRESC_PRESCALER_0) /*!< Input clock divided by 16 */ +#define LL_USART_PRESCALER_DIV32 (USART_PRESC_PRESCALER_3) /*!< Input clock divided by 32 */ +#define LL_USART_PRESCALER_DIV64 (USART_PRESC_PRESCALER_3 | USART_PRESC_PRESCALER_0) /*!< Input clock divided by 64 */ +#define LL_USART_PRESCALER_DIV128 (USART_PRESC_PRESCALER_3 | USART_PRESC_PRESCALER_1) /*!< Input clock divided by 128 */ +#define LL_USART_PRESCALER_DIV256 (USART_PRESC_PRESCALER_3 | USART_PRESC_PRESCALER_1 | USART_PRESC_PRESCALER_0) /*!< Input clock divided by 256 */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_STOPBITS Stop Bits + * @{ + */ +#define LL_USART_STOPBITS_0_5 USART_CR2_STOP_0 /*!< 0.5 stop bit */ +#define LL_USART_STOPBITS_1 0x00000000U /*!< 1 stop bit */ +#define LL_USART_STOPBITS_1_5 (USART_CR2_STOP_0 | USART_CR2_STOP_1) /*!< 1.5 stop bits */ +#define LL_USART_STOPBITS_2 USART_CR2_STOP_1 /*!< 2 stop bits */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_TXRX TX RX Pins Swap + * @{ + */ +#define LL_USART_TXRX_STANDARD 0x00000000U /*!< TX/RX pins are used as defined in standard pinout */ +#define LL_USART_TXRX_SWAPPED (USART_CR2_SWAP) /*!< TX and RX pins functions are swapped. */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_RXPIN_LEVEL RX Pin Active Level Inversion + * @{ + */ +#define LL_USART_RXPIN_LEVEL_STANDARD 0x00000000U /*!< RX pin signal works using the standard logic levels */ +#define LL_USART_RXPIN_LEVEL_INVERTED (USART_CR2_RXINV) /*!< RX pin signal values are inverted. */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_TXPIN_LEVEL TX Pin Active Level Inversion + * @{ + */ +#define LL_USART_TXPIN_LEVEL_STANDARD 0x00000000U /*!< TX pin signal works using the standard logic levels */ +#define LL_USART_TXPIN_LEVEL_INVERTED (USART_CR2_TXINV) /*!< TX pin signal values are inverted. */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_BINARY_LOGIC Binary Data Inversion + * @{ + */ +#define LL_USART_BINARY_LOGIC_POSITIVE 0x00000000U /*!< Logical data from the data register are send/received in positive/direct logic. (1=H, 0=L) */ +#define LL_USART_BINARY_LOGIC_NEGATIVE USART_CR2_DATAINV /*!< Logical data from the data register are send/received in negative/inverse logic. (1=L, 0=H). The parity bit is also inverted. */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_BITORDER Bit Order + * @{ + */ +#define LL_USART_BITORDER_LSBFIRST 0x00000000U /*!< data is transmitted/received with data bit 0 first, following the start bit */ +#define LL_USART_BITORDER_MSBFIRST USART_CR2_MSBFIRST /*!< data is transmitted/received with the MSB first, following the start bit */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_AUTOBAUD_DETECT_ON Autobaud Detection + * @{ + */ +#define LL_USART_AUTOBAUD_DETECT_ON_STARTBIT 0x00000000U /*!< Measurement of the start bit is used to detect the baud rate */ +#define LL_USART_AUTOBAUD_DETECT_ON_FALLINGEDGE USART_CR2_ABRMODE_0 /*!< Falling edge to falling edge measurement. Received frame must start with a single bit = 1 -> Frame = Start10xxxxxx */ +#define LL_USART_AUTOBAUD_DETECT_ON_7F_FRAME USART_CR2_ABRMODE_1 /*!< 0x7F frame detection */ +#define LL_USART_AUTOBAUD_DETECT_ON_55_FRAME (USART_CR2_ABRMODE_1 | USART_CR2_ABRMODE_0) /*!< 0x55 frame detection */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_ADDRESS_DETECT Address Length Detection + * @{ + */ +#define LL_USART_ADDRESS_DETECT_4B 0x00000000U /*!< 4-bit address detection method selected */ +#define LL_USART_ADDRESS_DETECT_7B USART_CR2_ADDM7 /*!< 7-bit address detection (in 8-bit data mode) method selected */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_HWCONTROL Hardware Control + * @{ + */ +#define LL_USART_HWCONTROL_NONE 0x00000000U /*!< CTS and RTS hardware flow control disabled */ +#define LL_USART_HWCONTROL_RTS USART_CR3_RTSE /*!< RTS output enabled, data is only requested when there is space in the receive buffer */ +#define LL_USART_HWCONTROL_CTS USART_CR3_CTSE /*!< CTS mode enabled, data is only transmitted when the nCTS input is asserted (tied to 0) */ +#define LL_USART_HWCONTROL_RTS_CTS (USART_CR3_RTSE | USART_CR3_CTSE) /*!< CTS and RTS hardware flow control enabled */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_WAKEUP_ON Wakeup Activation + * @{ + */ +#define LL_USART_WAKEUP_ON_ADDRESS 0x00000000U /*!< Wake up active on address match */ +#define LL_USART_WAKEUP_ON_STARTBIT USART_CR3_WUS_1 /*!< Wake up active on Start bit detection */ +#define LL_USART_WAKEUP_ON_RXNE (USART_CR3_WUS_0 | USART_CR3_WUS_1) /*!< Wake up active on RXNE */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_IRDA_POWER IrDA Power + * @{ + */ +#define LL_USART_IRDA_POWER_NORMAL 0x00000000U /*!< IrDA normal power mode */ +#define LL_USART_IRDA_POWER_LOW USART_CR3_IRLP /*!< IrDA low power mode */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_LINBREAK_DETECT LIN Break Detection Length + * @{ + */ +#define LL_USART_LINBREAK_DETECT_10B 0x00000000U /*!< 10-bit break detection method selected */ +#define LL_USART_LINBREAK_DETECT_11B USART_CR2_LBDL /*!< 11-bit break detection method selected */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_DE_POLARITY Driver Enable Polarity + * @{ + */ +#define LL_USART_DE_POLARITY_HIGH 0x00000000U /*!< DE signal is active high */ +#define LL_USART_DE_POLARITY_LOW USART_CR3_DEP /*!< DE signal is active low */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_DMA_REG_DATA DMA Register Data + * @{ + */ +#define LL_USART_DMA_REG_DATA_TRANSMIT 0x00000000U /*!< Get address of data register used for transmission */ +#define LL_USART_DMA_REG_DATA_RECEIVE 0x00000001U /*!< Get address of data register used for reception */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup USART_LL_Exported_Macros USART Exported Macros + * @{ + */ + +/** @defgroup USART_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in USART register + * @param __INSTANCE__ USART Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_USART_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in USART register + * @param __INSTANCE__ USART Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_USART_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) +/** + * @} + */ + +/** @defgroup USART_LL_EM_Exported_Macros_Helper Exported_Macros_Helper + * @{ + */ + +/** + * @brief Compute USARTDIV value according to Peripheral Clock and + * expected Baud Rate in 8 bits sampling mode (32 bits value of USARTDIV is returned) + * @param __PERIPHCLK__ Peripheral Clock frequency used for USART instance + * @param __PRESCALER__ This parameter can be one of the following values: + * @arg @ref LL_USART_PRESCALER_DIV1 + * @arg @ref LL_USART_PRESCALER_DIV2 + * @arg @ref LL_USART_PRESCALER_DIV4 + * @arg @ref LL_USART_PRESCALER_DIV6 + * @arg @ref LL_USART_PRESCALER_DIV8 + * @arg @ref LL_USART_PRESCALER_DIV10 + * @arg @ref LL_USART_PRESCALER_DIV12 + * @arg @ref LL_USART_PRESCALER_DIV16 + * @arg @ref LL_USART_PRESCALER_DIV32 + * @arg @ref LL_USART_PRESCALER_DIV64 + * @arg @ref LL_USART_PRESCALER_DIV128 + * @arg @ref LL_USART_PRESCALER_DIV256 + * @param __BAUDRATE__ Baud rate value to achieve + * @retval USARTDIV value to be used for BRR register filling in OverSampling_8 case + */ +#define __LL_USART_DIV_SAMPLING8(__PERIPHCLK__, __PRESCALER__, __BAUDRATE__) \ + (((((__PERIPHCLK__)/(USART_PRESCALER_TAB[(__PRESCALER__)]))*2U)\ + + ((__BAUDRATE__)/2U))/(__BAUDRATE__)) + +/** + * @brief Compute USARTDIV value according to Peripheral Clock and + * expected Baud Rate in 16 bits sampling mode (32 bits value of USARTDIV is returned) + * @param __PERIPHCLK__ Peripheral Clock frequency used for USART instance + * @param __PRESCALER__ This parameter can be one of the following values: + * @arg @ref LL_USART_PRESCALER_DIV1 + * @arg @ref LL_USART_PRESCALER_DIV2 + * @arg @ref LL_USART_PRESCALER_DIV4 + * @arg @ref LL_USART_PRESCALER_DIV6 + * @arg @ref LL_USART_PRESCALER_DIV8 + * @arg @ref LL_USART_PRESCALER_DIV10 + * @arg @ref LL_USART_PRESCALER_DIV12 + * @arg @ref LL_USART_PRESCALER_DIV16 + * @arg @ref LL_USART_PRESCALER_DIV32 + * @arg @ref LL_USART_PRESCALER_DIV64 + * @arg @ref LL_USART_PRESCALER_DIV128 + * @arg @ref LL_USART_PRESCALER_DIV256 + * @param __BAUDRATE__ Baud rate value to achieve + * @retval USARTDIV value to be used for BRR register filling in OverSampling_16 case + */ +#define __LL_USART_DIV_SAMPLING16(__PERIPHCLK__, __PRESCALER__, __BAUDRATE__) \ + ((((__PERIPHCLK__)/(USART_PRESCALER_TAB[(__PRESCALER__)]))\ + + ((__BAUDRATE__)/2U))/(__BAUDRATE__)) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup USART_LL_Exported_Functions USART Exported Functions + * @{ + */ + +/** @defgroup USART_LL_EF_Configuration Configuration functions + * @{ + */ + +/** + * @brief USART Enable + * @rmtoll CR1 UE LL_USART_Enable + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_Enable(USART_TypeDef *USARTx) +{ + SET_BIT(USARTx->CR1, USART_CR1_UE); +} + +/** + * @brief USART Disable (all USART prescalers and outputs are disabled) + * @note When USART is disabled, USART prescalers and outputs are stopped immediately, + * and current operations are discarded. The configuration of the USART is kept, but all the status + * flags, in the USARTx_ISR are set to their default values. + * @rmtoll CR1 UE LL_USART_Disable + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_Disable(USART_TypeDef *USARTx) +{ + CLEAR_BIT(USARTx->CR1, USART_CR1_UE); +} + +/** + * @brief Indicate if USART is enabled + * @rmtoll CR1 UE LL_USART_IsEnabled + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabled(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR1, USART_CR1_UE) == (USART_CR1_UE)) ? 1UL : 0UL); +} + +/** + * @brief FIFO Mode Enable + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll CR1 FIFOEN LL_USART_EnableFIFO + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableFIFO(USART_TypeDef *USARTx) +{ + SET_BIT(USARTx->CR1, USART_CR1_FIFOEN); +} + +/** + * @brief FIFO Mode Disable + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll CR1 FIFOEN LL_USART_DisableFIFO + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableFIFO(USART_TypeDef *USARTx) +{ + CLEAR_BIT(USARTx->CR1, USART_CR1_FIFOEN); +} + +/** + * @brief Indicate if FIFO Mode is enabled + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll CR1 FIFOEN LL_USART_IsEnabledFIFO + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledFIFO(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR1, USART_CR1_FIFOEN) == (USART_CR1_FIFOEN)) ? 1UL : 0UL); +} + +/** + * @brief Configure TX FIFO Threshold + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll CR3 TXFTCFG LL_USART_SetTXFIFOThreshold + * @param USARTx USART Instance + * @param Threshold This parameter can be one of the following values: + * @arg @ref LL_USART_FIFOTHRESHOLD_1_8 + * @arg @ref LL_USART_FIFOTHRESHOLD_1_4 + * @arg @ref LL_USART_FIFOTHRESHOLD_1_2 + * @arg @ref LL_USART_FIFOTHRESHOLD_3_4 + * @arg @ref LL_USART_FIFOTHRESHOLD_7_8 + * @arg @ref LL_USART_FIFOTHRESHOLD_8_8 + * @retval None + */ +__STATIC_INLINE void LL_USART_SetTXFIFOThreshold(USART_TypeDef *USARTx, uint32_t Threshold) +{ + ATOMIC_MODIFY_REG(USARTx->CR3, USART_CR3_TXFTCFG, Threshold << USART_CR3_TXFTCFG_Pos); +} + +/** + * @brief Return TX FIFO Threshold Configuration + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll CR3 TXFTCFG LL_USART_GetTXFIFOThreshold + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_FIFOTHRESHOLD_1_8 + * @arg @ref LL_USART_FIFOTHRESHOLD_1_4 + * @arg @ref LL_USART_FIFOTHRESHOLD_1_2 + * @arg @ref LL_USART_FIFOTHRESHOLD_3_4 + * @arg @ref LL_USART_FIFOTHRESHOLD_7_8 + * @arg @ref LL_USART_FIFOTHRESHOLD_8_8 + */ +__STATIC_INLINE uint32_t LL_USART_GetTXFIFOThreshold(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->CR3, USART_CR3_TXFTCFG) >> USART_CR3_TXFTCFG_Pos); +} + +/** + * @brief Configure RX FIFO Threshold + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll CR3 RXFTCFG LL_USART_SetRXFIFOThreshold + * @param USARTx USART Instance + * @param Threshold This parameter can be one of the following values: + * @arg @ref LL_USART_FIFOTHRESHOLD_1_8 + * @arg @ref LL_USART_FIFOTHRESHOLD_1_4 + * @arg @ref LL_USART_FIFOTHRESHOLD_1_2 + * @arg @ref LL_USART_FIFOTHRESHOLD_3_4 + * @arg @ref LL_USART_FIFOTHRESHOLD_7_8 + * @arg @ref LL_USART_FIFOTHRESHOLD_8_8 + * @retval None + */ +__STATIC_INLINE void LL_USART_SetRXFIFOThreshold(USART_TypeDef *USARTx, uint32_t Threshold) +{ + ATOMIC_MODIFY_REG(USARTx->CR3, USART_CR3_RXFTCFG, Threshold << USART_CR3_RXFTCFG_Pos); +} + +/** + * @brief Return RX FIFO Threshold Configuration + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll CR3 RXFTCFG LL_USART_GetRXFIFOThreshold + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_FIFOTHRESHOLD_1_8 + * @arg @ref LL_USART_FIFOTHRESHOLD_1_4 + * @arg @ref LL_USART_FIFOTHRESHOLD_1_2 + * @arg @ref LL_USART_FIFOTHRESHOLD_3_4 + * @arg @ref LL_USART_FIFOTHRESHOLD_7_8 + * @arg @ref LL_USART_FIFOTHRESHOLD_8_8 + */ +__STATIC_INLINE uint32_t LL_USART_GetRXFIFOThreshold(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->CR3, USART_CR3_RXFTCFG) >> USART_CR3_RXFTCFG_Pos); +} + +/** + * @brief Configure TX and RX FIFOs Threshold + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll CR3 TXFTCFG LL_USART_ConfigFIFOsThreshold\n + * CR3 RXFTCFG LL_USART_ConfigFIFOsThreshold + * @param USARTx USART Instance + * @param TXThreshold This parameter can be one of the following values: + * @arg @ref LL_USART_FIFOTHRESHOLD_1_8 + * @arg @ref LL_USART_FIFOTHRESHOLD_1_4 + * @arg @ref LL_USART_FIFOTHRESHOLD_1_2 + * @arg @ref LL_USART_FIFOTHRESHOLD_3_4 + * @arg @ref LL_USART_FIFOTHRESHOLD_7_8 + * @arg @ref LL_USART_FIFOTHRESHOLD_8_8 + * @param RXThreshold This parameter can be one of the following values: + * @arg @ref LL_USART_FIFOTHRESHOLD_1_8 + * @arg @ref LL_USART_FIFOTHRESHOLD_1_4 + * @arg @ref LL_USART_FIFOTHRESHOLD_1_2 + * @arg @ref LL_USART_FIFOTHRESHOLD_3_4 + * @arg @ref LL_USART_FIFOTHRESHOLD_7_8 + * @arg @ref LL_USART_FIFOTHRESHOLD_8_8 + * @retval None + */ +__STATIC_INLINE void LL_USART_ConfigFIFOsThreshold(USART_TypeDef *USARTx, uint32_t TXThreshold, uint32_t RXThreshold) +{ + ATOMIC_MODIFY_REG(USARTx->CR3, USART_CR3_TXFTCFG | USART_CR3_RXFTCFG, (TXThreshold << USART_CR3_TXFTCFG_Pos) | + (RXThreshold << USART_CR3_RXFTCFG_Pos)); +} + +/** + * @brief USART enabled in STOP Mode. + * @note When this function is enabled, USART is able to wake up the MCU from Stop mode, provided that + * USART clock selection is HSI or LSE in RCC. + * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether or not + * Wake-up from Stop mode feature is supported by the USARTx instance. + * @rmtoll CR1 UESM LL_USART_EnableInStopMode + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableInStopMode(USART_TypeDef *USARTx) +{ + ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_UESM); +} + +/** + * @brief USART disabled in STOP Mode. + * @note When this function is disabled, USART is not able to wake up the MCU from Stop mode + * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether or not + * Wake-up from Stop mode feature is supported by the USARTx instance. + * @rmtoll CR1 UESM LL_USART_DisableInStopMode + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableInStopMode(USART_TypeDef *USARTx) +{ + ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_UESM); +} + +/** + * @brief Indicate if USART is enabled in STOP Mode (able to wake up MCU from Stop mode or not) + * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether or not + * Wake-up from Stop mode feature is supported by the USARTx instance. + * @rmtoll CR1 UESM LL_USART_IsEnabledInStopMode + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledInStopMode(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR1, USART_CR1_UESM) == (USART_CR1_UESM)) ? 1UL : 0UL); +} + +/** + * @brief Receiver Enable (Receiver is enabled and begins searching for a start bit) + * @rmtoll CR1 RE LL_USART_EnableDirectionRx + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableDirectionRx(USART_TypeDef *USARTx) +{ + ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_RE); +} + +/** + * @brief Receiver Disable + * @rmtoll CR1 RE LL_USART_DisableDirectionRx + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableDirectionRx(USART_TypeDef *USARTx) +{ + ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_RE); +} + +/** + * @brief Transmitter Enable + * @rmtoll CR1 TE LL_USART_EnableDirectionTx + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableDirectionTx(USART_TypeDef *USARTx) +{ + ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_TE); +} + +/** + * @brief Transmitter Disable + * @rmtoll CR1 TE LL_USART_DisableDirectionTx + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableDirectionTx(USART_TypeDef *USARTx) +{ + ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_TE); +} + +/** + * @brief Configure simultaneously enabled/disabled states + * of Transmitter and Receiver + * @rmtoll CR1 RE LL_USART_SetTransferDirection\n + * CR1 TE LL_USART_SetTransferDirection + * @param USARTx USART Instance + * @param TransferDirection This parameter can be one of the following values: + * @arg @ref LL_USART_DIRECTION_NONE + * @arg @ref LL_USART_DIRECTION_RX + * @arg @ref LL_USART_DIRECTION_TX + * @arg @ref LL_USART_DIRECTION_TX_RX + * @retval None + */ +__STATIC_INLINE void LL_USART_SetTransferDirection(USART_TypeDef *USARTx, uint32_t TransferDirection) +{ + ATOMIC_MODIFY_REG(USARTx->CR1, USART_CR1_RE | USART_CR1_TE, TransferDirection); +} + +/** + * @brief Return enabled/disabled states of Transmitter and Receiver + * @rmtoll CR1 RE LL_USART_GetTransferDirection\n + * CR1 TE LL_USART_GetTransferDirection + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_DIRECTION_NONE + * @arg @ref LL_USART_DIRECTION_RX + * @arg @ref LL_USART_DIRECTION_TX + * @arg @ref LL_USART_DIRECTION_TX_RX + */ +__STATIC_INLINE uint32_t LL_USART_GetTransferDirection(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_RE | USART_CR1_TE)); +} + +/** + * @brief Configure Parity (enabled/disabled and parity mode if enabled). + * @note This function selects if hardware parity control (generation and detection) is enabled or disabled. + * When the parity control is enabled (Odd or Even), computed parity bit is inserted at the MSB position + * (9th or 8th bit depending on data width) and parity is checked on the received data. + * @rmtoll CR1 PS LL_USART_SetParity\n + * CR1 PCE LL_USART_SetParity + * @param USARTx USART Instance + * @param Parity This parameter can be one of the following values: + * @arg @ref LL_USART_PARITY_NONE + * @arg @ref LL_USART_PARITY_EVEN + * @arg @ref LL_USART_PARITY_ODD + * @retval None + */ +__STATIC_INLINE void LL_USART_SetParity(USART_TypeDef *USARTx, uint32_t Parity) +{ + MODIFY_REG(USARTx->CR1, USART_CR1_PS | USART_CR1_PCE, Parity); +} + +/** + * @brief Return Parity configuration (enabled/disabled and parity mode if enabled) + * @rmtoll CR1 PS LL_USART_GetParity\n + * CR1 PCE LL_USART_GetParity + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_PARITY_NONE + * @arg @ref LL_USART_PARITY_EVEN + * @arg @ref LL_USART_PARITY_ODD + */ +__STATIC_INLINE uint32_t LL_USART_GetParity(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_PS | USART_CR1_PCE)); +} + +/** + * @brief Set Receiver Wake Up method from Mute mode. + * @rmtoll CR1 WAKE LL_USART_SetWakeUpMethod + * @param USARTx USART Instance + * @param Method This parameter can be one of the following values: + * @arg @ref LL_USART_WAKEUP_IDLELINE + * @arg @ref LL_USART_WAKEUP_ADDRESSMARK + * @retval None + */ +__STATIC_INLINE void LL_USART_SetWakeUpMethod(USART_TypeDef *USARTx, uint32_t Method) +{ + MODIFY_REG(USARTx->CR1, USART_CR1_WAKE, Method); +} + +/** + * @brief Return Receiver Wake Up method from Mute mode + * @rmtoll CR1 WAKE LL_USART_GetWakeUpMethod + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_WAKEUP_IDLELINE + * @arg @ref LL_USART_WAKEUP_ADDRESSMARK + */ +__STATIC_INLINE uint32_t LL_USART_GetWakeUpMethod(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_WAKE)); +} + +/** + * @brief Set Word length (i.e. nb of data bits, excluding start and stop bits) + * @rmtoll CR1 M0 LL_USART_SetDataWidth\n + * CR1 M1 LL_USART_SetDataWidth + * @param USARTx USART Instance + * @param DataWidth This parameter can be one of the following values: + * @arg @ref LL_USART_DATAWIDTH_7B + * @arg @ref LL_USART_DATAWIDTH_8B + * @arg @ref LL_USART_DATAWIDTH_9B + * @retval None + */ +__STATIC_INLINE void LL_USART_SetDataWidth(USART_TypeDef *USARTx, uint32_t DataWidth) +{ + MODIFY_REG(USARTx->CR1, USART_CR1_M, DataWidth); +} + +/** + * @brief Return Word length (i.e. nb of data bits, excluding start and stop bits) + * @rmtoll CR1 M0 LL_USART_GetDataWidth\n + * CR1 M1 LL_USART_GetDataWidth + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_DATAWIDTH_7B + * @arg @ref LL_USART_DATAWIDTH_8B + * @arg @ref LL_USART_DATAWIDTH_9B + */ +__STATIC_INLINE uint32_t LL_USART_GetDataWidth(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_M)); +} + +/** + * @brief Allow switch between Mute Mode and Active mode + * @rmtoll CR1 MME LL_USART_EnableMuteMode + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableMuteMode(USART_TypeDef *USARTx) +{ + ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_MME); +} + +/** + * @brief Prevent Mute Mode use. Set Receiver in active mode permanently. + * @rmtoll CR1 MME LL_USART_DisableMuteMode + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableMuteMode(USART_TypeDef *USARTx) +{ + ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_MME); +} + +/** + * @brief Indicate if switch between Mute Mode and Active mode is allowed + * @rmtoll CR1 MME LL_USART_IsEnabledMuteMode + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledMuteMode(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR1, USART_CR1_MME) == (USART_CR1_MME)) ? 1UL : 0UL); +} + +/** + * @brief Set Oversampling to 8-bit or 16-bit mode + * @rmtoll CR1 OVER8 LL_USART_SetOverSampling + * @param USARTx USART Instance + * @param OverSampling This parameter can be one of the following values: + * @arg @ref LL_USART_OVERSAMPLING_16 + * @arg @ref LL_USART_OVERSAMPLING_8 + * @retval None + */ +__STATIC_INLINE void LL_USART_SetOverSampling(USART_TypeDef *USARTx, uint32_t OverSampling) +{ + MODIFY_REG(USARTx->CR1, USART_CR1_OVER8, OverSampling); +} + +/** + * @brief Return Oversampling mode + * @rmtoll CR1 OVER8 LL_USART_GetOverSampling + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_OVERSAMPLING_16 + * @arg @ref LL_USART_OVERSAMPLING_8 + */ +__STATIC_INLINE uint32_t LL_USART_GetOverSampling(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_OVER8)); +} + +/** + * @brief Configure if Clock pulse of the last data bit is output to the SCLK pin or not + * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not + * Synchronous mode is supported by the USARTx instance. + * @rmtoll CR2 LBCL LL_USART_SetLastClkPulseOutput + * @param USARTx USART Instance + * @param LastBitClockPulse This parameter can be one of the following values: + * @arg @ref LL_USART_LASTCLKPULSE_NO_OUTPUT + * @arg @ref LL_USART_LASTCLKPULSE_OUTPUT + * @retval None + */ +__STATIC_INLINE void LL_USART_SetLastClkPulseOutput(USART_TypeDef *USARTx, uint32_t LastBitClockPulse) +{ + MODIFY_REG(USARTx->CR2, USART_CR2_LBCL, LastBitClockPulse); +} + +/** + * @brief Retrieve Clock pulse of the last data bit output configuration + * (Last bit Clock pulse output to the SCLK pin or not) + * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not + * Synchronous mode is supported by the USARTx instance. + * @rmtoll CR2 LBCL LL_USART_GetLastClkPulseOutput + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_LASTCLKPULSE_NO_OUTPUT + * @arg @ref LL_USART_LASTCLKPULSE_OUTPUT + */ +__STATIC_INLINE uint32_t LL_USART_GetLastClkPulseOutput(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_LBCL)); +} + +/** + * @brief Select the phase of the clock output on the SCLK pin in synchronous mode + * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not + * Synchronous mode is supported by the USARTx instance. + * @rmtoll CR2 CPHA LL_USART_SetClockPhase + * @param USARTx USART Instance + * @param ClockPhase This parameter can be one of the following values: + * @arg @ref LL_USART_PHASE_1EDGE + * @arg @ref LL_USART_PHASE_2EDGE + * @retval None + */ +__STATIC_INLINE void LL_USART_SetClockPhase(USART_TypeDef *USARTx, uint32_t ClockPhase) +{ + MODIFY_REG(USARTx->CR2, USART_CR2_CPHA, ClockPhase); +} + +/** + * @brief Return phase of the clock output on the SCLK pin in synchronous mode + * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not + * Synchronous mode is supported by the USARTx instance. + * @rmtoll CR2 CPHA LL_USART_GetClockPhase + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_PHASE_1EDGE + * @arg @ref LL_USART_PHASE_2EDGE + */ +__STATIC_INLINE uint32_t LL_USART_GetClockPhase(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_CPHA)); +} + +/** + * @brief Select the polarity of the clock output on the SCLK pin in synchronous mode + * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not + * Synchronous mode is supported by the USARTx instance. + * @rmtoll CR2 CPOL LL_USART_SetClockPolarity + * @param USARTx USART Instance + * @param ClockPolarity This parameter can be one of the following values: + * @arg @ref LL_USART_POLARITY_LOW + * @arg @ref LL_USART_POLARITY_HIGH + * @retval None + */ +__STATIC_INLINE void LL_USART_SetClockPolarity(USART_TypeDef *USARTx, uint32_t ClockPolarity) +{ + MODIFY_REG(USARTx->CR2, USART_CR2_CPOL, ClockPolarity); +} + +/** + * @brief Return polarity of the clock output on the SCLK pin in synchronous mode + * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not + * Synchronous mode is supported by the USARTx instance. + * @rmtoll CR2 CPOL LL_USART_GetClockPolarity + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_POLARITY_LOW + * @arg @ref LL_USART_POLARITY_HIGH + */ +__STATIC_INLINE uint32_t LL_USART_GetClockPolarity(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_CPOL)); +} + +/** + * @brief Configure Clock signal format (Phase Polarity and choice about output of last bit clock pulse) + * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not + * Synchronous mode is supported by the USARTx instance. + * @note Call of this function is equivalent to following function call sequence : + * - Clock Phase configuration using @ref LL_USART_SetClockPhase() function + * - Clock Polarity configuration using @ref LL_USART_SetClockPolarity() function + * - Output of Last bit Clock pulse configuration using @ref LL_USART_SetLastClkPulseOutput() function + * @rmtoll CR2 CPHA LL_USART_ConfigClock\n + * CR2 CPOL LL_USART_ConfigClock\n + * CR2 LBCL LL_USART_ConfigClock + * @param USARTx USART Instance + * @param Phase This parameter can be one of the following values: + * @arg @ref LL_USART_PHASE_1EDGE + * @arg @ref LL_USART_PHASE_2EDGE + * @param Polarity This parameter can be one of the following values: + * @arg @ref LL_USART_POLARITY_LOW + * @arg @ref LL_USART_POLARITY_HIGH + * @param LBCPOutput This parameter can be one of the following values: + * @arg @ref LL_USART_LASTCLKPULSE_NO_OUTPUT + * @arg @ref LL_USART_LASTCLKPULSE_OUTPUT + * @retval None + */ +__STATIC_INLINE void LL_USART_ConfigClock(USART_TypeDef *USARTx, uint32_t Phase, uint32_t Polarity, uint32_t LBCPOutput) +{ + MODIFY_REG(USARTx->CR2, USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_LBCL, Phase | Polarity | LBCPOutput); +} + +/** + * @brief Configure Clock source prescaler for baudrate generator and oversampling + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll PRESC PRESCALER LL_USART_SetPrescaler + * @param USARTx USART Instance + * @param PrescalerValue This parameter can be one of the following values: + * @arg @ref LL_USART_PRESCALER_DIV1 + * @arg @ref LL_USART_PRESCALER_DIV2 + * @arg @ref LL_USART_PRESCALER_DIV4 + * @arg @ref LL_USART_PRESCALER_DIV6 + * @arg @ref LL_USART_PRESCALER_DIV8 + * @arg @ref LL_USART_PRESCALER_DIV10 + * @arg @ref LL_USART_PRESCALER_DIV12 + * @arg @ref LL_USART_PRESCALER_DIV16 + * @arg @ref LL_USART_PRESCALER_DIV32 + * @arg @ref LL_USART_PRESCALER_DIV64 + * @arg @ref LL_USART_PRESCALER_DIV128 + * @arg @ref LL_USART_PRESCALER_DIV256 + * @retval None + */ +__STATIC_INLINE void LL_USART_SetPrescaler(USART_TypeDef *USARTx, uint32_t PrescalerValue) +{ + MODIFY_REG(USARTx->PRESC, USART_PRESC_PRESCALER, (uint16_t)PrescalerValue); +} + +/** + * @brief Retrieve the Clock source prescaler for baudrate generator and oversampling + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll PRESC PRESCALER LL_USART_GetPrescaler + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_PRESCALER_DIV1 + * @arg @ref LL_USART_PRESCALER_DIV2 + * @arg @ref LL_USART_PRESCALER_DIV4 + * @arg @ref LL_USART_PRESCALER_DIV6 + * @arg @ref LL_USART_PRESCALER_DIV8 + * @arg @ref LL_USART_PRESCALER_DIV10 + * @arg @ref LL_USART_PRESCALER_DIV12 + * @arg @ref LL_USART_PRESCALER_DIV16 + * @arg @ref LL_USART_PRESCALER_DIV32 + * @arg @ref LL_USART_PRESCALER_DIV64 + * @arg @ref LL_USART_PRESCALER_DIV128 + * @arg @ref LL_USART_PRESCALER_DIV256 + */ +__STATIC_INLINE uint32_t LL_USART_GetPrescaler(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->PRESC, USART_PRESC_PRESCALER)); +} + +/** + * @brief Enable Clock output on SCLK pin + * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not + * Synchronous mode is supported by the USARTx instance. + * @rmtoll CR2 CLKEN LL_USART_EnableSCLKOutput + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableSCLKOutput(USART_TypeDef *USARTx) +{ + SET_BIT(USARTx->CR2, USART_CR2_CLKEN); +} + +/** + * @brief Disable Clock output on SCLK pin + * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not + * Synchronous mode is supported by the USARTx instance. + * @rmtoll CR2 CLKEN LL_USART_DisableSCLKOutput + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableSCLKOutput(USART_TypeDef *USARTx) +{ + CLEAR_BIT(USARTx->CR2, USART_CR2_CLKEN); +} + +/** + * @brief Indicate if Clock output on SCLK pin is enabled + * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not + * Synchronous mode is supported by the USARTx instance. + * @rmtoll CR2 CLKEN LL_USART_IsEnabledSCLKOutput + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledSCLKOutput(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR2, USART_CR2_CLKEN) == (USART_CR2_CLKEN)) ? 1UL : 0UL); +} + +/** + * @brief Set the length of the stop bits + * @rmtoll CR2 STOP LL_USART_SetStopBitsLength + * @param USARTx USART Instance + * @param StopBits This parameter can be one of the following values: + * @arg @ref LL_USART_STOPBITS_0_5 + * @arg @ref LL_USART_STOPBITS_1 + * @arg @ref LL_USART_STOPBITS_1_5 + * @arg @ref LL_USART_STOPBITS_2 + * @retval None + */ +__STATIC_INLINE void LL_USART_SetStopBitsLength(USART_TypeDef *USARTx, uint32_t StopBits) +{ + MODIFY_REG(USARTx->CR2, USART_CR2_STOP, StopBits); +} + +/** + * @brief Retrieve the length of the stop bits + * @rmtoll CR2 STOP LL_USART_GetStopBitsLength + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_STOPBITS_0_5 + * @arg @ref LL_USART_STOPBITS_1 + * @arg @ref LL_USART_STOPBITS_1_5 + * @arg @ref LL_USART_STOPBITS_2 + */ +__STATIC_INLINE uint32_t LL_USART_GetStopBitsLength(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_STOP)); +} + +/** + * @brief Configure Character frame format (Datawidth, Parity control, Stop Bits) + * @note Call of this function is equivalent to following function call sequence : + * - Data Width configuration using @ref LL_USART_SetDataWidth() function + * - Parity Control and mode configuration using @ref LL_USART_SetParity() function + * - Stop bits configuration using @ref LL_USART_SetStopBitsLength() function + * @rmtoll CR1 PS LL_USART_ConfigCharacter\n + * CR1 PCE LL_USART_ConfigCharacter\n + * CR1 M0 LL_USART_ConfigCharacter\n + * CR1 M1 LL_USART_ConfigCharacter\n + * CR2 STOP LL_USART_ConfigCharacter + * @param USARTx USART Instance + * @param DataWidth This parameter can be one of the following values: + * @arg @ref LL_USART_DATAWIDTH_7B + * @arg @ref LL_USART_DATAWIDTH_8B + * @arg @ref LL_USART_DATAWIDTH_9B + * @param Parity This parameter can be one of the following values: + * @arg @ref LL_USART_PARITY_NONE + * @arg @ref LL_USART_PARITY_EVEN + * @arg @ref LL_USART_PARITY_ODD + * @param StopBits This parameter can be one of the following values: + * @arg @ref LL_USART_STOPBITS_0_5 + * @arg @ref LL_USART_STOPBITS_1 + * @arg @ref LL_USART_STOPBITS_1_5 + * @arg @ref LL_USART_STOPBITS_2 + * @retval None + */ +__STATIC_INLINE void LL_USART_ConfigCharacter(USART_TypeDef *USARTx, uint32_t DataWidth, uint32_t Parity, + uint32_t StopBits) +{ + MODIFY_REG(USARTx->CR1, USART_CR1_PS | USART_CR1_PCE | USART_CR1_M, Parity | DataWidth); + MODIFY_REG(USARTx->CR2, USART_CR2_STOP, StopBits); +} + +/** + * @brief Configure TX/RX pins swapping setting. + * @rmtoll CR2 SWAP LL_USART_SetTXRXSwap + * @param USARTx USART Instance + * @param SwapConfig This parameter can be one of the following values: + * @arg @ref LL_USART_TXRX_STANDARD + * @arg @ref LL_USART_TXRX_SWAPPED + * @retval None + */ +__STATIC_INLINE void LL_USART_SetTXRXSwap(USART_TypeDef *USARTx, uint32_t SwapConfig) +{ + MODIFY_REG(USARTx->CR2, USART_CR2_SWAP, SwapConfig); +} + +/** + * @brief Retrieve TX/RX pins swapping configuration. + * @rmtoll CR2 SWAP LL_USART_GetTXRXSwap + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_TXRX_STANDARD + * @arg @ref LL_USART_TXRX_SWAPPED + */ +__STATIC_INLINE uint32_t LL_USART_GetTXRXSwap(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_SWAP)); +} + +/** + * @brief Configure RX pin active level logic + * @rmtoll CR2 RXINV LL_USART_SetRXPinLevel + * @param USARTx USART Instance + * @param PinInvMethod This parameter can be one of the following values: + * @arg @ref LL_USART_RXPIN_LEVEL_STANDARD + * @arg @ref LL_USART_RXPIN_LEVEL_INVERTED + * @retval None + */ +__STATIC_INLINE void LL_USART_SetRXPinLevel(USART_TypeDef *USARTx, uint32_t PinInvMethod) +{ + MODIFY_REG(USARTx->CR2, USART_CR2_RXINV, PinInvMethod); +} + +/** + * @brief Retrieve RX pin active level logic configuration + * @rmtoll CR2 RXINV LL_USART_GetRXPinLevel + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_RXPIN_LEVEL_STANDARD + * @arg @ref LL_USART_RXPIN_LEVEL_INVERTED + */ +__STATIC_INLINE uint32_t LL_USART_GetRXPinLevel(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_RXINV)); +} + +/** + * @brief Configure TX pin active level logic + * @rmtoll CR2 TXINV LL_USART_SetTXPinLevel + * @param USARTx USART Instance + * @param PinInvMethod This parameter can be one of the following values: + * @arg @ref LL_USART_TXPIN_LEVEL_STANDARD + * @arg @ref LL_USART_TXPIN_LEVEL_INVERTED + * @retval None + */ +__STATIC_INLINE void LL_USART_SetTXPinLevel(USART_TypeDef *USARTx, uint32_t PinInvMethod) +{ + MODIFY_REG(USARTx->CR2, USART_CR2_TXINV, PinInvMethod); +} + +/** + * @brief Retrieve TX pin active level logic configuration + * @rmtoll CR2 TXINV LL_USART_GetTXPinLevel + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_TXPIN_LEVEL_STANDARD + * @arg @ref LL_USART_TXPIN_LEVEL_INVERTED + */ +__STATIC_INLINE uint32_t LL_USART_GetTXPinLevel(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_TXINV)); +} + +/** + * @brief Configure Binary data logic. + * @note Allow to define how Logical data from the data register are send/received : + * either in positive/direct logic (1=H, 0=L) or in negative/inverse logic (1=L, 0=H) + * @rmtoll CR2 DATAINV LL_USART_SetBinaryDataLogic + * @param USARTx USART Instance + * @param DataLogic This parameter can be one of the following values: + * @arg @ref LL_USART_BINARY_LOGIC_POSITIVE + * @arg @ref LL_USART_BINARY_LOGIC_NEGATIVE + * @retval None + */ +__STATIC_INLINE void LL_USART_SetBinaryDataLogic(USART_TypeDef *USARTx, uint32_t DataLogic) +{ + MODIFY_REG(USARTx->CR2, USART_CR2_DATAINV, DataLogic); +} + +/** + * @brief Retrieve Binary data configuration + * @rmtoll CR2 DATAINV LL_USART_GetBinaryDataLogic + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_BINARY_LOGIC_POSITIVE + * @arg @ref LL_USART_BINARY_LOGIC_NEGATIVE + */ +__STATIC_INLINE uint32_t LL_USART_GetBinaryDataLogic(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_DATAINV)); +} + +/** + * @brief Configure transfer bit order (either Less or Most Significant Bit First) + * @note MSB First means data is transmitted/received with the MSB first, following the start bit. + * LSB First means data is transmitted/received with data bit 0 first, following the start bit. + * @rmtoll CR2 MSBFIRST LL_USART_SetTransferBitOrder + * @param USARTx USART Instance + * @param BitOrder This parameter can be one of the following values: + * @arg @ref LL_USART_BITORDER_LSBFIRST + * @arg @ref LL_USART_BITORDER_MSBFIRST + * @retval None + */ +__STATIC_INLINE void LL_USART_SetTransferBitOrder(USART_TypeDef *USARTx, uint32_t BitOrder) +{ + MODIFY_REG(USARTx->CR2, USART_CR2_MSBFIRST, BitOrder); +} + +/** + * @brief Return transfer bit order (either Less or Most Significant Bit First) + * @note MSB First means data is transmitted/received with the MSB first, following the start bit. + * LSB First means data is transmitted/received with data bit 0 first, following the start bit. + * @rmtoll CR2 MSBFIRST LL_USART_GetTransferBitOrder + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_BITORDER_LSBFIRST + * @arg @ref LL_USART_BITORDER_MSBFIRST + */ +__STATIC_INLINE uint32_t LL_USART_GetTransferBitOrder(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_MSBFIRST)); +} + +/** + * @brief Enable Auto Baud-Rate Detection + * @note Macro IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(USARTx) can be used to check whether or not + * Auto Baud Rate detection feature is supported by the USARTx instance. + * @rmtoll CR2 ABREN LL_USART_EnableAutoBaudRate + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableAutoBaudRate(USART_TypeDef *USARTx) +{ + SET_BIT(USARTx->CR2, USART_CR2_ABREN); +} + +/** + * @brief Disable Auto Baud-Rate Detection + * @note Macro IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(USARTx) can be used to check whether or not + * Auto Baud Rate detection feature is supported by the USARTx instance. + * @rmtoll CR2 ABREN LL_USART_DisableAutoBaudRate + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableAutoBaudRate(USART_TypeDef *USARTx) +{ + CLEAR_BIT(USARTx->CR2, USART_CR2_ABREN); +} + +/** + * @brief Indicate if Auto Baud-Rate Detection mechanism is enabled + * @note Macro IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(USARTx) can be used to check whether or not + * Auto Baud Rate detection feature is supported by the USARTx instance. + * @rmtoll CR2 ABREN LL_USART_IsEnabledAutoBaud + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledAutoBaud(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR2, USART_CR2_ABREN) == (USART_CR2_ABREN)) ? 1UL : 0UL); +} + +/** + * @brief Set Auto Baud-Rate mode bits + * @note Macro IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(USARTx) can be used to check whether or not + * Auto Baud Rate detection feature is supported by the USARTx instance. + * @rmtoll CR2 ABRMODE LL_USART_SetAutoBaudRateMode + * @param USARTx USART Instance + * @param AutoBaudRateMode This parameter can be one of the following values: + * @arg @ref LL_USART_AUTOBAUD_DETECT_ON_STARTBIT + * @arg @ref LL_USART_AUTOBAUD_DETECT_ON_FALLINGEDGE + * @arg @ref LL_USART_AUTOBAUD_DETECT_ON_7F_FRAME + * @arg @ref LL_USART_AUTOBAUD_DETECT_ON_55_FRAME + * @retval None + */ +__STATIC_INLINE void LL_USART_SetAutoBaudRateMode(USART_TypeDef *USARTx, uint32_t AutoBaudRateMode) +{ + MODIFY_REG(USARTx->CR2, USART_CR2_ABRMODE, AutoBaudRateMode); +} + +/** + * @brief Return Auto Baud-Rate mode + * @note Macro IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(USARTx) can be used to check whether or not + * Auto Baud Rate detection feature is supported by the USARTx instance. + * @rmtoll CR2 ABRMODE LL_USART_GetAutoBaudRateMode + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_AUTOBAUD_DETECT_ON_STARTBIT + * @arg @ref LL_USART_AUTOBAUD_DETECT_ON_FALLINGEDGE + * @arg @ref LL_USART_AUTOBAUD_DETECT_ON_7F_FRAME + * @arg @ref LL_USART_AUTOBAUD_DETECT_ON_55_FRAME + */ +__STATIC_INLINE uint32_t LL_USART_GetAutoBaudRateMode(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_ABRMODE)); +} + +/** + * @brief Enable Receiver Timeout + * @rmtoll CR2 RTOEN LL_USART_EnableRxTimeout + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableRxTimeout(USART_TypeDef *USARTx) +{ + SET_BIT(USARTx->CR2, USART_CR2_RTOEN); +} + +/** + * @brief Disable Receiver Timeout + * @rmtoll CR2 RTOEN LL_USART_DisableRxTimeout + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableRxTimeout(USART_TypeDef *USARTx) +{ + CLEAR_BIT(USARTx->CR2, USART_CR2_RTOEN); +} + +/** + * @brief Indicate if Receiver Timeout feature is enabled + * @rmtoll CR2 RTOEN LL_USART_IsEnabledRxTimeout + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledRxTimeout(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR2, USART_CR2_RTOEN) == (USART_CR2_RTOEN)) ? 1UL : 0UL); +} + +/** + * @brief Set Address of the USART node. + * @note This is used in multiprocessor communication during Mute mode or Stop mode, + * for wake up with address mark detection. + * @note 4bits address node is used when 4-bit Address Detection is selected in ADDM7. + * (b7-b4 should be set to 0) + * 8bits address node is used when 7-bit Address Detection is selected in ADDM7. + * (This is used in multiprocessor communication during Mute mode or Stop mode, + * for wake up with 7-bit address mark detection. + * The MSB of the character sent by the transmitter should be equal to 1. + * It may also be used for character detection during normal reception, + * Mute mode inactive (for example, end of block detection in ModBus protocol). + * In this case, the whole received character (8-bit) is compared to the ADD[7:0] + * value and CMF flag is set on match) + * @rmtoll CR2 ADD LL_USART_ConfigNodeAddress\n + * CR2 ADDM7 LL_USART_ConfigNodeAddress + * @param USARTx USART Instance + * @param AddressLen This parameter can be one of the following values: + * @arg @ref LL_USART_ADDRESS_DETECT_4B + * @arg @ref LL_USART_ADDRESS_DETECT_7B + * @param NodeAddress 4 or 7 bit Address of the USART node. + * @retval None + */ +__STATIC_INLINE void LL_USART_ConfigNodeAddress(USART_TypeDef *USARTx, uint32_t AddressLen, uint32_t NodeAddress) +{ + MODIFY_REG(USARTx->CR2, USART_CR2_ADD | USART_CR2_ADDM7, + (uint32_t)(AddressLen | (NodeAddress << USART_CR2_ADD_Pos))); +} + +/** + * @brief Return 8 bit Address of the USART node as set in ADD field of CR2. + * @note If 4-bit Address Detection is selected in ADDM7, + * only 4bits (b3-b0) of returned value are relevant (b31-b4 are not relevant) + * If 7-bit Address Detection is selected in ADDM7, + * only 8bits (b7-b0) of returned value are relevant (b31-b8 are not relevant) + * @rmtoll CR2 ADD LL_USART_GetNodeAddress + * @param USARTx USART Instance + * @retval Address of the USART node (Value between Min_Data=0 and Max_Data=255) + */ +__STATIC_INLINE uint32_t LL_USART_GetNodeAddress(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_ADD) >> USART_CR2_ADD_Pos); +} + +/** + * @brief Return Length of Node Address used in Address Detection mode (7-bit or 4-bit) + * @rmtoll CR2 ADDM7 LL_USART_GetNodeAddressLen + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_ADDRESS_DETECT_4B + * @arg @ref LL_USART_ADDRESS_DETECT_7B + */ +__STATIC_INLINE uint32_t LL_USART_GetNodeAddressLen(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_ADDM7)); +} + +/** + * @brief Enable RTS HW Flow Control + * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not + * Hardware Flow control feature is supported by the USARTx instance. + * @rmtoll CR3 RTSE LL_USART_EnableRTSHWFlowCtrl + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableRTSHWFlowCtrl(USART_TypeDef *USARTx) +{ + SET_BIT(USARTx->CR3, USART_CR3_RTSE); +} + +/** + * @brief Disable RTS HW Flow Control + * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not + * Hardware Flow control feature is supported by the USARTx instance. + * @rmtoll CR3 RTSE LL_USART_DisableRTSHWFlowCtrl + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableRTSHWFlowCtrl(USART_TypeDef *USARTx) +{ + CLEAR_BIT(USARTx->CR3, USART_CR3_RTSE); +} + +/** + * @brief Enable CTS HW Flow Control + * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not + * Hardware Flow control feature is supported by the USARTx instance. + * @rmtoll CR3 CTSE LL_USART_EnableCTSHWFlowCtrl + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableCTSHWFlowCtrl(USART_TypeDef *USARTx) +{ + SET_BIT(USARTx->CR3, USART_CR3_CTSE); +} + +/** + * @brief Disable CTS HW Flow Control + * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not + * Hardware Flow control feature is supported by the USARTx instance. + * @rmtoll CR3 CTSE LL_USART_DisableCTSHWFlowCtrl + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableCTSHWFlowCtrl(USART_TypeDef *USARTx) +{ + CLEAR_BIT(USARTx->CR3, USART_CR3_CTSE); +} + +/** + * @brief Configure HW Flow Control mode (both CTS and RTS) + * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not + * Hardware Flow control feature is supported by the USARTx instance. + * @rmtoll CR3 RTSE LL_USART_SetHWFlowCtrl\n + * CR3 CTSE LL_USART_SetHWFlowCtrl + * @param USARTx USART Instance + * @param HardwareFlowControl This parameter can be one of the following values: + * @arg @ref LL_USART_HWCONTROL_NONE + * @arg @ref LL_USART_HWCONTROL_RTS + * @arg @ref LL_USART_HWCONTROL_CTS + * @arg @ref LL_USART_HWCONTROL_RTS_CTS + * @retval None + */ +__STATIC_INLINE void LL_USART_SetHWFlowCtrl(USART_TypeDef *USARTx, uint32_t HardwareFlowControl) +{ + MODIFY_REG(USARTx->CR3, USART_CR3_RTSE | USART_CR3_CTSE, HardwareFlowControl); +} + +/** + * @brief Return HW Flow Control configuration (both CTS and RTS) + * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not + * Hardware Flow control feature is supported by the USARTx instance. + * @rmtoll CR3 RTSE LL_USART_GetHWFlowCtrl\n + * CR3 CTSE LL_USART_GetHWFlowCtrl + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_HWCONTROL_NONE + * @arg @ref LL_USART_HWCONTROL_RTS + * @arg @ref LL_USART_HWCONTROL_CTS + * @arg @ref LL_USART_HWCONTROL_RTS_CTS + */ +__STATIC_INLINE uint32_t LL_USART_GetHWFlowCtrl(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->CR3, USART_CR3_RTSE | USART_CR3_CTSE)); +} + +/** + * @brief Enable One bit sampling method + * @rmtoll CR3 ONEBIT LL_USART_EnableOneBitSamp + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableOneBitSamp(USART_TypeDef *USARTx) +{ + SET_BIT(USARTx->CR3, USART_CR3_ONEBIT); +} + +/** + * @brief Disable One bit sampling method + * @rmtoll CR3 ONEBIT LL_USART_DisableOneBitSamp + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableOneBitSamp(USART_TypeDef *USARTx) +{ + CLEAR_BIT(USARTx->CR3, USART_CR3_ONEBIT); +} + +/** + * @brief Indicate if One bit sampling method is enabled + * @rmtoll CR3 ONEBIT LL_USART_IsEnabledOneBitSamp + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledOneBitSamp(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR3, USART_CR3_ONEBIT) == (USART_CR3_ONEBIT)) ? 1UL : 0UL); +} + +/** + * @brief Enable Overrun detection + * @rmtoll CR3 OVRDIS LL_USART_EnableOverrunDetect + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableOverrunDetect(USART_TypeDef *USARTx) +{ + CLEAR_BIT(USARTx->CR3, USART_CR3_OVRDIS); +} + +/** + * @brief Disable Overrun detection + * @rmtoll CR3 OVRDIS LL_USART_DisableOverrunDetect + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableOverrunDetect(USART_TypeDef *USARTx) +{ + SET_BIT(USARTx->CR3, USART_CR3_OVRDIS); +} + +/** + * @brief Indicate if Overrun detection is enabled + * @rmtoll CR3 OVRDIS LL_USART_IsEnabledOverrunDetect + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledOverrunDetect(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR3, USART_CR3_OVRDIS) != USART_CR3_OVRDIS) ? 1UL : 0UL); +} + +/** + * @brief Select event type for Wake UP Interrupt Flag (WUS[1:0] bits) + * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether or not + * Wake-up from Stop mode feature is supported by the USARTx instance. + * @rmtoll CR3 WUS LL_USART_SetWKUPType + * @param USARTx USART Instance + * @param Type This parameter can be one of the following values: + * @arg @ref LL_USART_WAKEUP_ON_ADDRESS + * @arg @ref LL_USART_WAKEUP_ON_STARTBIT + * @arg @ref LL_USART_WAKEUP_ON_RXNE + * @retval None + */ +__STATIC_INLINE void LL_USART_SetWKUPType(USART_TypeDef *USARTx, uint32_t Type) +{ + MODIFY_REG(USARTx->CR3, USART_CR3_WUS, Type); +} + +/** + * @brief Return event type for Wake UP Interrupt Flag (WUS[1:0] bits) + * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether or not + * Wake-up from Stop mode feature is supported by the USARTx instance. + * @rmtoll CR3 WUS LL_USART_GetWKUPType + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_WAKEUP_ON_ADDRESS + * @arg @ref LL_USART_WAKEUP_ON_STARTBIT + * @arg @ref LL_USART_WAKEUP_ON_RXNE + */ +__STATIC_INLINE uint32_t LL_USART_GetWKUPType(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->CR3, USART_CR3_WUS)); +} + +/** + * @brief Configure USART BRR register for achieving expected Baud Rate value. + * @note Compute and set USARTDIV value in BRR Register (full BRR content) + * according to used Peripheral Clock, Oversampling mode, and expected Baud Rate values + * @note Peripheral clock and Baud rate values provided as function parameters should be valid + * (Baud rate value != 0) + * @note In case of oversampling by 16 and 8, BRR content must be greater than or equal to 16d. + * @rmtoll BRR BRR LL_USART_SetBaudRate + * @param USARTx USART Instance + * @param PeriphClk Peripheral Clock + * @param PrescalerValue This parameter can be one of the following values: + * @arg @ref LL_USART_PRESCALER_DIV1 + * @arg @ref LL_USART_PRESCALER_DIV2 + * @arg @ref LL_USART_PRESCALER_DIV4 + * @arg @ref LL_USART_PRESCALER_DIV6 + * @arg @ref LL_USART_PRESCALER_DIV8 + * @arg @ref LL_USART_PRESCALER_DIV10 + * @arg @ref LL_USART_PRESCALER_DIV12 + * @arg @ref LL_USART_PRESCALER_DIV16 + * @arg @ref LL_USART_PRESCALER_DIV32 + * @arg @ref LL_USART_PRESCALER_DIV64 + * @arg @ref LL_USART_PRESCALER_DIV128 + * @arg @ref LL_USART_PRESCALER_DIV256 + * @param OverSampling This parameter can be one of the following values: + * @arg @ref LL_USART_OVERSAMPLING_16 + * @arg @ref LL_USART_OVERSAMPLING_8 + * @param BaudRate Baud Rate + * @retval None + */ +__STATIC_INLINE void LL_USART_SetBaudRate(USART_TypeDef *USARTx, uint32_t PeriphClk, uint32_t PrescalerValue, + uint32_t OverSampling, + uint32_t BaudRate) +{ + uint32_t usartdiv; + uint32_t brrtemp; + + if (PrescalerValue > LL_USART_PRESCALER_DIV256) + { + /* Do not overstep the size of USART_PRESCALER_TAB */ + } + else if (BaudRate == 0U) + { + /* Can Not divide per 0 */ + } + else if (OverSampling == LL_USART_OVERSAMPLING_8) + { + usartdiv = (uint16_t)(__LL_USART_DIV_SAMPLING8(PeriphClk, (uint8_t)PrescalerValue, BaudRate)); + brrtemp = usartdiv & 0xFFF0U; + brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U); + USARTx->BRR = brrtemp; + } + else + { + USARTx->BRR = (uint16_t)(__LL_USART_DIV_SAMPLING16(PeriphClk, (uint8_t)PrescalerValue, BaudRate)); + } +} + +/** + * @brief Return current Baud Rate value, according to USARTDIV present in BRR register + * (full BRR content), and to used Peripheral Clock and Oversampling mode values + * @note In case of non-initialized or invalid value stored in BRR register, value 0 will be returned. + * @note In case of oversampling by 16 and 8, BRR content must be greater than or equal to 16d. + * @rmtoll BRR BRR LL_USART_GetBaudRate + * @param USARTx USART Instance + * @param PeriphClk Peripheral Clock + * @param PrescalerValue This parameter can be one of the following values: + * @arg @ref LL_USART_PRESCALER_DIV1 + * @arg @ref LL_USART_PRESCALER_DIV2 + * @arg @ref LL_USART_PRESCALER_DIV4 + * @arg @ref LL_USART_PRESCALER_DIV6 + * @arg @ref LL_USART_PRESCALER_DIV8 + * @arg @ref LL_USART_PRESCALER_DIV10 + * @arg @ref LL_USART_PRESCALER_DIV12 + * @arg @ref LL_USART_PRESCALER_DIV16 + * @arg @ref LL_USART_PRESCALER_DIV32 + * @arg @ref LL_USART_PRESCALER_DIV64 + * @arg @ref LL_USART_PRESCALER_DIV128 + * @arg @ref LL_USART_PRESCALER_DIV256 + * @param OverSampling This parameter can be one of the following values: + * @arg @ref LL_USART_OVERSAMPLING_16 + * @arg @ref LL_USART_OVERSAMPLING_8 + * @retval Baud Rate + */ +__STATIC_INLINE uint32_t LL_USART_GetBaudRate(const USART_TypeDef *USARTx, uint32_t PeriphClk, uint32_t PrescalerValue, + uint32_t OverSampling) +{ + uint32_t usartdiv; + uint32_t brrresult = 0x0U; + uint32_t periphclkpresc = (uint32_t)(PeriphClk / (USART_PRESCALER_TAB[(uint8_t)PrescalerValue])); + + usartdiv = USARTx->BRR; + + if (usartdiv == 0U) + { + /* Do not perform a division by 0 */ + } + else if (OverSampling == LL_USART_OVERSAMPLING_8) + { + usartdiv = (uint16_t)((usartdiv & 0xFFF0U) | ((usartdiv & 0x0007U) << 1U)) ; + if (usartdiv != 0U) + { + brrresult = (periphclkpresc * 2U) / usartdiv; + } + } + else + { + if ((usartdiv & 0xFFFFU) != 0U) + { + brrresult = periphclkpresc / usartdiv; + } + } + return (brrresult); +} + +/** + * @brief Set Receiver Time Out Value (expressed in nb of bits duration) + * @rmtoll RTOR RTO LL_USART_SetRxTimeout + * @param USARTx USART Instance + * @param Timeout Value between Min_Data=0x00 and Max_Data=0x00FFFFFF + * @retval None + */ +__STATIC_INLINE void LL_USART_SetRxTimeout(USART_TypeDef *USARTx, uint32_t Timeout) +{ + MODIFY_REG(USARTx->RTOR, USART_RTOR_RTO, Timeout); +} + +/** + * @brief Get Receiver Time Out Value (expressed in nb of bits duration) + * @rmtoll RTOR RTO LL_USART_GetRxTimeout + * @param USARTx USART Instance + * @retval Value between Min_Data=0x00 and Max_Data=0x00FFFFFF + */ +__STATIC_INLINE uint32_t LL_USART_GetRxTimeout(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->RTOR, USART_RTOR_RTO)); +} + +/** + * @brief Set Block Length value in reception + * @rmtoll RTOR BLEN LL_USART_SetBlockLength + * @param USARTx USART Instance + * @param BlockLength Value between Min_Data=0x00 and Max_Data=0xFF + * @retval None + */ +__STATIC_INLINE void LL_USART_SetBlockLength(USART_TypeDef *USARTx, uint32_t BlockLength) +{ + MODIFY_REG(USARTx->RTOR, USART_RTOR_BLEN, BlockLength << USART_RTOR_BLEN_Pos); +} + +/** + * @brief Get Block Length value in reception + * @rmtoll RTOR BLEN LL_USART_GetBlockLength + * @param USARTx USART Instance + * @retval Value between Min_Data=0x00 and Max_Data=0xFF + */ +__STATIC_INLINE uint32_t LL_USART_GetBlockLength(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->RTOR, USART_RTOR_BLEN) >> USART_RTOR_BLEN_Pos); +} + +/** + * @} + */ + +/** @defgroup USART_LL_EF_Configuration_IRDA Configuration functions related to Irda feature + * @{ + */ + +/** + * @brief Enable IrDA mode + * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not + * IrDA feature is supported by the USARTx instance. + * @rmtoll CR3 IREN LL_USART_EnableIrda + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableIrda(USART_TypeDef *USARTx) +{ + SET_BIT(USARTx->CR3, USART_CR3_IREN); +} + +/** + * @brief Disable IrDA mode + * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not + * IrDA feature is supported by the USARTx instance. + * @rmtoll CR3 IREN LL_USART_DisableIrda + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableIrda(USART_TypeDef *USARTx) +{ + CLEAR_BIT(USARTx->CR3, USART_CR3_IREN); +} + +/** + * @brief Indicate if IrDA mode is enabled + * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not + * IrDA feature is supported by the USARTx instance. + * @rmtoll CR3 IREN LL_USART_IsEnabledIrda + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledIrda(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR3, USART_CR3_IREN) == (USART_CR3_IREN)) ? 1UL : 0UL); +} + +/** + * @brief Configure IrDA Power Mode (Normal or Low Power) + * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not + * IrDA feature is supported by the USARTx instance. + * @rmtoll CR3 IRLP LL_USART_SetIrdaPowerMode + * @param USARTx USART Instance + * @param PowerMode This parameter can be one of the following values: + * @arg @ref LL_USART_IRDA_POWER_NORMAL + * @arg @ref LL_USART_IRDA_POWER_LOW + * @retval None + */ +__STATIC_INLINE void LL_USART_SetIrdaPowerMode(USART_TypeDef *USARTx, uint32_t PowerMode) +{ + MODIFY_REG(USARTx->CR3, USART_CR3_IRLP, PowerMode); +} + +/** + * @brief Retrieve IrDA Power Mode configuration (Normal or Low Power) + * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not + * IrDA feature is supported by the USARTx instance. + * @rmtoll CR3 IRLP LL_USART_GetIrdaPowerMode + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_IRDA_POWER_NORMAL + * @arg @ref LL_USART_PHASE_2EDGE + */ +__STATIC_INLINE uint32_t LL_USART_GetIrdaPowerMode(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->CR3, USART_CR3_IRLP)); +} + +/** + * @brief Set Irda prescaler value, used for dividing the USART clock source + * to achieve the Irda Low Power frequency (8 bits value) + * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not + * IrDA feature is supported by the USARTx instance. + * @rmtoll GTPR PSC LL_USART_SetIrdaPrescaler + * @param USARTx USART Instance + * @param PrescalerValue Value between Min_Data=0x00 and Max_Data=0xFF + * @retval None + */ +__STATIC_INLINE void LL_USART_SetIrdaPrescaler(USART_TypeDef *USARTx, uint32_t PrescalerValue) +{ + MODIFY_REG(USARTx->GTPR, USART_GTPR_PSC, (uint16_t)PrescalerValue); +} + +/** + * @brief Return Irda prescaler value, used for dividing the USART clock source + * to achieve the Irda Low Power frequency (8 bits value) + * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not + * IrDA feature is supported by the USARTx instance. + * @rmtoll GTPR PSC LL_USART_GetIrdaPrescaler + * @param USARTx USART Instance + * @retval Irda prescaler value (Value between Min_Data=0x00 and Max_Data=0xFF) + */ +__STATIC_INLINE uint32_t LL_USART_GetIrdaPrescaler(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->GTPR, USART_GTPR_PSC)); +} + +/** + * @} + */ + +/** @defgroup USART_LL_EF_Configuration_Smartcard Configuration functions related to Smartcard feature + * @{ + */ + +/** + * @brief Enable Smartcard NACK transmission + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll CR3 NACK LL_USART_EnableSmartcardNACK + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableSmartcardNACK(USART_TypeDef *USARTx) +{ + SET_BIT(USARTx->CR3, USART_CR3_NACK); +} + +/** + * @brief Disable Smartcard NACK transmission + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll CR3 NACK LL_USART_DisableSmartcardNACK + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableSmartcardNACK(USART_TypeDef *USARTx) +{ + CLEAR_BIT(USARTx->CR3, USART_CR3_NACK); +} + +/** + * @brief Indicate if Smartcard NACK transmission is enabled + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll CR3 NACK LL_USART_IsEnabledSmartcardNACK + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledSmartcardNACK(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR3, USART_CR3_NACK) == (USART_CR3_NACK)) ? 1UL : 0UL); +} + +/** + * @brief Enable Smartcard mode + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll CR3 SCEN LL_USART_EnableSmartcard + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableSmartcard(USART_TypeDef *USARTx) +{ + SET_BIT(USARTx->CR3, USART_CR3_SCEN); +} + +/** + * @brief Disable Smartcard mode + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll CR3 SCEN LL_USART_DisableSmartcard + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableSmartcard(USART_TypeDef *USARTx) +{ + CLEAR_BIT(USARTx->CR3, USART_CR3_SCEN); +} + +/** + * @brief Indicate if Smartcard mode is enabled + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll CR3 SCEN LL_USART_IsEnabledSmartcard + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledSmartcard(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR3, USART_CR3_SCEN) == (USART_CR3_SCEN)) ? 1UL : 0UL); +} + +/** + * @brief Set Smartcard Auto-Retry Count value (SCARCNT[2:0] bits) + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @note This bit-field specifies the number of retries in transmit and receive, in Smartcard mode. + * In transmission mode, it specifies the number of automatic retransmission retries, before + * generating a transmission error (FE bit set). + * In reception mode, it specifies the number or erroneous reception trials, before generating a + * reception error (RXNE and PE bits set) + * @rmtoll CR3 SCARCNT LL_USART_SetSmartcardAutoRetryCount + * @param USARTx USART Instance + * @param AutoRetryCount Value between Min_Data=0 and Max_Data=7 + * @retval None + */ +__STATIC_INLINE void LL_USART_SetSmartcardAutoRetryCount(USART_TypeDef *USARTx, uint32_t AutoRetryCount) +{ + MODIFY_REG(USARTx->CR3, USART_CR3_SCARCNT, AutoRetryCount << USART_CR3_SCARCNT_Pos); +} + +/** + * @brief Return Smartcard Auto-Retry Count value (SCARCNT[2:0] bits) + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll CR3 SCARCNT LL_USART_GetSmartcardAutoRetryCount + * @param USARTx USART Instance + * @retval Smartcard Auto-Retry Count value (Value between Min_Data=0 and Max_Data=7) + */ +__STATIC_INLINE uint32_t LL_USART_GetSmartcardAutoRetryCount(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->CR3, USART_CR3_SCARCNT) >> USART_CR3_SCARCNT_Pos); +} + +/** + * @brief Set Smartcard prescaler value, used for dividing the USART clock + * source to provide the SMARTCARD Clock (5 bits value) + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll GTPR PSC LL_USART_SetSmartcardPrescaler + * @param USARTx USART Instance + * @param PrescalerValue Value between Min_Data=0 and Max_Data=31 + * @retval None + */ +__STATIC_INLINE void LL_USART_SetSmartcardPrescaler(USART_TypeDef *USARTx, uint32_t PrescalerValue) +{ + MODIFY_REG(USARTx->GTPR, USART_GTPR_PSC, (uint16_t)PrescalerValue); +} + +/** + * @brief Return Smartcard prescaler value, used for dividing the USART clock + * source to provide the SMARTCARD Clock (5 bits value) + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll GTPR PSC LL_USART_GetSmartcardPrescaler + * @param USARTx USART Instance + * @retval Smartcard prescaler value (Value between Min_Data=0 and Max_Data=31) + */ +__STATIC_INLINE uint32_t LL_USART_GetSmartcardPrescaler(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->GTPR, USART_GTPR_PSC)); +} + +/** + * @brief Set Smartcard Guard time value, expressed in nb of baud clocks periods + * (GT[7:0] bits : Guard time value) + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll GTPR GT LL_USART_SetSmartcardGuardTime + * @param USARTx USART Instance + * @param GuardTime Value between Min_Data=0x00 and Max_Data=0xFF + * @retval None + */ +__STATIC_INLINE void LL_USART_SetSmartcardGuardTime(USART_TypeDef *USARTx, uint32_t GuardTime) +{ + MODIFY_REG(USARTx->GTPR, USART_GTPR_GT, (uint16_t)(GuardTime << USART_GTPR_GT_Pos)); +} + +/** + * @brief Return Smartcard Guard time value, expressed in nb of baud clocks periods + * (GT[7:0] bits : Guard time value) + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll GTPR GT LL_USART_GetSmartcardGuardTime + * @param USARTx USART Instance + * @retval Smartcard Guard time value (Value between Min_Data=0x00 and Max_Data=0xFF) + */ +__STATIC_INLINE uint32_t LL_USART_GetSmartcardGuardTime(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->GTPR, USART_GTPR_GT) >> USART_GTPR_GT_Pos); +} + +/** + * @} + */ + +/** @defgroup USART_LL_EF_Configuration_HalfDuplex Configuration functions related to Half Duplex feature + * @{ + */ + +/** + * @brief Enable Single Wire Half-Duplex mode + * @note Macro IS_UART_HALFDUPLEX_INSTANCE(USARTx) can be used to check whether or not + * Half-Duplex mode is supported by the USARTx instance. + * @rmtoll CR3 HDSEL LL_USART_EnableHalfDuplex + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableHalfDuplex(USART_TypeDef *USARTx) +{ + SET_BIT(USARTx->CR3, USART_CR3_HDSEL); +} + +/** + * @brief Disable Single Wire Half-Duplex mode + * @note Macro IS_UART_HALFDUPLEX_INSTANCE(USARTx) can be used to check whether or not + * Half-Duplex mode is supported by the USARTx instance. + * @rmtoll CR3 HDSEL LL_USART_DisableHalfDuplex + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableHalfDuplex(USART_TypeDef *USARTx) +{ + CLEAR_BIT(USARTx->CR3, USART_CR3_HDSEL); +} + +/** + * @brief Indicate if Single Wire Half-Duplex mode is enabled + * @note Macro IS_UART_HALFDUPLEX_INSTANCE(USARTx) can be used to check whether or not + * Half-Duplex mode is supported by the USARTx instance. + * @rmtoll CR3 HDSEL LL_USART_IsEnabledHalfDuplex + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledHalfDuplex(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR3, USART_CR3_HDSEL) == (USART_CR3_HDSEL)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup USART_LL_EF_Configuration_SPI_SLAVE Configuration functions related to SPI Slave feature + * @{ + */ +/** + * @brief Enable SPI Synchronous Slave mode + * @note Macro IS_UART_SPI_SLAVE_INSTANCE(USARTx) can be used to check whether or not + * SPI Slave mode feature is supported by the USARTx instance. + * @rmtoll CR2 SLVEN LL_USART_EnableSPISlave + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableSPISlave(USART_TypeDef *USARTx) +{ + SET_BIT(USARTx->CR2, USART_CR2_SLVEN); +} + +/** + * @brief Disable SPI Synchronous Slave mode + * @note Macro IS_UART_SPI_SLAVE_INSTANCE(USARTx) can be used to check whether or not + * SPI Slave mode feature is supported by the USARTx instance. + * @rmtoll CR2 SLVEN LL_USART_DisableSPISlave + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableSPISlave(USART_TypeDef *USARTx) +{ + CLEAR_BIT(USARTx->CR2, USART_CR2_SLVEN); +} + +/** + * @brief Indicate if SPI Synchronous Slave mode is enabled + * @note Macro IS_UART_SPI_SLAVE_INSTANCE(USARTx) can be used to check whether or not + * SPI Slave mode feature is supported by the USARTx instance. + * @rmtoll CR2 SLVEN LL_USART_IsEnabledSPISlave + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledSPISlave(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR2, USART_CR2_SLVEN) == (USART_CR2_SLVEN)) ? 1UL : 0UL); +} + +/** + * @brief Enable SPI Slave Selection using NSS input pin + * @note Macro IS_UART_SPI_SLAVE_INSTANCE(USARTx) can be used to check whether or not + * SPI Slave mode feature is supported by the USARTx instance. + * @note SPI Slave Selection depends on NSS input pin + * (The slave is selected when NSS is low and deselected when NSS is high). + * @rmtoll CR2 DIS_NSS LL_USART_EnableSPISlaveSelect + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableSPISlaveSelect(USART_TypeDef *USARTx) +{ + CLEAR_BIT(USARTx->CR2, USART_CR2_DIS_NSS); +} + +/** + * @brief Disable SPI Slave Selection using NSS input pin + * @note Macro IS_UART_SPI_SLAVE_INSTANCE(USARTx) can be used to check whether or not + * SPI Slave mode feature is supported by the USARTx instance. + * @note SPI Slave will be always selected and NSS input pin will be ignored. + * @rmtoll CR2 DIS_NSS LL_USART_DisableSPISlaveSelect + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableSPISlaveSelect(USART_TypeDef *USARTx) +{ + SET_BIT(USARTx->CR2, USART_CR2_DIS_NSS); +} + +/** + * @brief Indicate if SPI Slave Selection depends on NSS input pin + * @note Macro IS_UART_SPI_SLAVE_INSTANCE(USARTx) can be used to check whether or not + * SPI Slave mode feature is supported by the USARTx instance. + * @rmtoll CR2 DIS_NSS LL_USART_IsEnabledSPISlaveSelect + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledSPISlaveSelect(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR2, USART_CR2_DIS_NSS) != (USART_CR2_DIS_NSS)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup USART_LL_EF_Configuration_LIN Configuration functions related to LIN feature + * @{ + */ + +/** + * @brief Set LIN Break Detection Length + * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not + * LIN feature is supported by the USARTx instance. + * @rmtoll CR2 LBDL LL_USART_SetLINBrkDetectionLen + * @param USARTx USART Instance + * @param LINBDLength This parameter can be one of the following values: + * @arg @ref LL_USART_LINBREAK_DETECT_10B + * @arg @ref LL_USART_LINBREAK_DETECT_11B + * @retval None + */ +__STATIC_INLINE void LL_USART_SetLINBrkDetectionLen(USART_TypeDef *USARTx, uint32_t LINBDLength) +{ + MODIFY_REG(USARTx->CR2, USART_CR2_LBDL, LINBDLength); +} + +/** + * @brief Return LIN Break Detection Length + * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not + * LIN feature is supported by the USARTx instance. + * @rmtoll CR2 LBDL LL_USART_GetLINBrkDetectionLen + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_LINBREAK_DETECT_10B + * @arg @ref LL_USART_LINBREAK_DETECT_11B + */ +__STATIC_INLINE uint32_t LL_USART_GetLINBrkDetectionLen(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_LBDL)); +} + +/** + * @brief Enable LIN mode + * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not + * LIN feature is supported by the USARTx instance. + * @rmtoll CR2 LINEN LL_USART_EnableLIN + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableLIN(USART_TypeDef *USARTx) +{ + SET_BIT(USARTx->CR2, USART_CR2_LINEN); +} + +/** + * @brief Disable LIN mode + * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not + * LIN feature is supported by the USARTx instance. + * @rmtoll CR2 LINEN LL_USART_DisableLIN + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableLIN(USART_TypeDef *USARTx) +{ + CLEAR_BIT(USARTx->CR2, USART_CR2_LINEN); +} + +/** + * @brief Indicate if LIN mode is enabled + * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not + * LIN feature is supported by the USARTx instance. + * @rmtoll CR2 LINEN LL_USART_IsEnabledLIN + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledLIN(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR2, USART_CR2_LINEN) == (USART_CR2_LINEN)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup USART_LL_EF_Configuration_DE Configuration functions related to Driver Enable feature + * @{ + */ + +/** + * @brief Set DEDT (Driver Enable De-Assertion Time), Time value expressed on 5 bits ([4:0] bits). + * @note Macro IS_UART_DRIVER_ENABLE_INSTANCE(USARTx) can be used to check whether or not + * Driver Enable feature is supported by the USARTx instance. + * @rmtoll CR1 DEDT LL_USART_SetDEDeassertionTime + * @param USARTx USART Instance + * @param Time Value between Min_Data=0 and Max_Data=31 + * @retval None + */ +__STATIC_INLINE void LL_USART_SetDEDeassertionTime(USART_TypeDef *USARTx, uint32_t Time) +{ + MODIFY_REG(USARTx->CR1, USART_CR1_DEDT, Time << USART_CR1_DEDT_Pos); +} + +/** + * @brief Return DEDT (Driver Enable De-Assertion Time) + * @note Macro IS_UART_DRIVER_ENABLE_INSTANCE(USARTx) can be used to check whether or not + * Driver Enable feature is supported by the USARTx instance. + * @rmtoll CR1 DEDT LL_USART_GetDEDeassertionTime + * @param USARTx USART Instance + * @retval Time value expressed on 5 bits ([4:0] bits) : Value between Min_Data=0 and Max_Data=31 + */ +__STATIC_INLINE uint32_t LL_USART_GetDEDeassertionTime(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_DEDT) >> USART_CR1_DEDT_Pos); +} + +/** + * @brief Set DEAT (Driver Enable Assertion Time), Time value expressed on 5 bits ([4:0] bits). + * @note Macro IS_UART_DRIVER_ENABLE_INSTANCE(USARTx) can be used to check whether or not + * Driver Enable feature is supported by the USARTx instance. + * @rmtoll CR1 DEAT LL_USART_SetDEAssertionTime + * @param USARTx USART Instance + * @param Time Value between Min_Data=0 and Max_Data=31 + * @retval None + */ +__STATIC_INLINE void LL_USART_SetDEAssertionTime(USART_TypeDef *USARTx, uint32_t Time) +{ + MODIFY_REG(USARTx->CR1, USART_CR1_DEAT, Time << USART_CR1_DEAT_Pos); +} + +/** + * @brief Return DEAT (Driver Enable Assertion Time) + * @note Macro IS_UART_DRIVER_ENABLE_INSTANCE(USARTx) can be used to check whether or not + * Driver Enable feature is supported by the USARTx instance. + * @rmtoll CR1 DEAT LL_USART_GetDEAssertionTime + * @param USARTx USART Instance + * @retval Time value expressed on 5 bits ([4:0] bits) : Value between Min_Data=0 and Max_Data=31 + */ +__STATIC_INLINE uint32_t LL_USART_GetDEAssertionTime(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_DEAT) >> USART_CR1_DEAT_Pos); +} + +/** + * @brief Enable Driver Enable (DE) Mode + * @note Macro IS_UART_DRIVER_ENABLE_INSTANCE(USARTx) can be used to check whether or not + * Driver Enable feature is supported by the USARTx instance. + * @rmtoll CR3 DEM LL_USART_EnableDEMode + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableDEMode(USART_TypeDef *USARTx) +{ + SET_BIT(USARTx->CR3, USART_CR3_DEM); +} + +/** + * @brief Disable Driver Enable (DE) Mode + * @note Macro IS_UART_DRIVER_ENABLE_INSTANCE(USARTx) can be used to check whether or not + * Driver Enable feature is supported by the USARTx instance. + * @rmtoll CR3 DEM LL_USART_DisableDEMode + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableDEMode(USART_TypeDef *USARTx) +{ + CLEAR_BIT(USARTx->CR3, USART_CR3_DEM); +} + +/** + * @brief Indicate if Driver Enable (DE) Mode is enabled + * @note Macro IS_UART_DRIVER_ENABLE_INSTANCE(USARTx) can be used to check whether or not + * Driver Enable feature is supported by the USARTx instance. + * @rmtoll CR3 DEM LL_USART_IsEnabledDEMode + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledDEMode(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR3, USART_CR3_DEM) == (USART_CR3_DEM)) ? 1UL : 0UL); +} + +/** + * @brief Select Driver Enable Polarity + * @note Macro IS_UART_DRIVER_ENABLE_INSTANCE(USARTx) can be used to check whether or not + * Driver Enable feature is supported by the USARTx instance. + * @rmtoll CR3 DEP LL_USART_SetDESignalPolarity + * @param USARTx USART Instance + * @param Polarity This parameter can be one of the following values: + * @arg @ref LL_USART_DE_POLARITY_HIGH + * @arg @ref LL_USART_DE_POLARITY_LOW + * @retval None + */ +__STATIC_INLINE void LL_USART_SetDESignalPolarity(USART_TypeDef *USARTx, uint32_t Polarity) +{ + MODIFY_REG(USARTx->CR3, USART_CR3_DEP, Polarity); +} + +/** + * @brief Return Driver Enable Polarity + * @note Macro IS_UART_DRIVER_ENABLE_INSTANCE(USARTx) can be used to check whether or not + * Driver Enable feature is supported by the USARTx instance. + * @rmtoll CR3 DEP LL_USART_GetDESignalPolarity + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_DE_POLARITY_HIGH + * @arg @ref LL_USART_DE_POLARITY_LOW + */ +__STATIC_INLINE uint32_t LL_USART_GetDESignalPolarity(const USART_TypeDef *USARTx) +{ + return (uint32_t)(READ_BIT(USARTx->CR3, USART_CR3_DEP)); +} + +/** + * @} + */ + +/** @defgroup USART_LL_EF_AdvancedConfiguration Advanced Configurations services + * @{ + */ + +/** + * @brief Perform basic configuration of USART for enabling use in Asynchronous Mode (UART) + * @note In UART mode, the following bits must be kept cleared: + * - LINEN bit in the USART_CR2 register, + * - CLKEN bit in the USART_CR2 register, + * - SCEN bit in the USART_CR3 register, + * - IREN bit in the USART_CR3 register, + * - HDSEL bit in the USART_CR3 register. + * @note Call of this function is equivalent to following function call sequence : + * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function + * - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function + * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function + * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function + * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function + * @note Other remaining configurations items related to Asynchronous Mode + * (as Baud Rate, Word length, Parity, ...) should be set using + * dedicated functions + * @rmtoll CR2 LINEN LL_USART_ConfigAsyncMode\n + * CR2 CLKEN LL_USART_ConfigAsyncMode\n + * CR3 SCEN LL_USART_ConfigAsyncMode\n + * CR3 IREN LL_USART_ConfigAsyncMode\n + * CR3 HDSEL LL_USART_ConfigAsyncMode + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_ConfigAsyncMode(USART_TypeDef *USARTx) +{ + /* In Asynchronous mode, the following bits must be kept cleared: + - LINEN, CLKEN bits in the USART_CR2 register, + - SCEN, IREN and HDSEL bits in the USART_CR3 register. + */ + CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); + CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_IREN | USART_CR3_HDSEL)); +} + +/** + * @brief Perform basic configuration of USART for enabling use in Synchronous Mode + * @note In Synchronous mode, the following bits must be kept cleared: + * - LINEN bit in the USART_CR2 register, + * - SCEN bit in the USART_CR3 register, + * - IREN bit in the USART_CR3 register, + * - HDSEL bit in the USART_CR3 register. + * This function also sets the USART in Synchronous mode. + * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not + * Synchronous mode is supported by the USARTx instance. + * @note Call of this function is equivalent to following function call sequence : + * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function + * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function + * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function + * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function + * - Set CLKEN in CR2 using @ref LL_USART_EnableSCLKOutput() function + * @note Other remaining configurations items related to Synchronous Mode + * (as Baud Rate, Word length, Parity, Clock Polarity, ...) should be set using + * dedicated functions + * @rmtoll CR2 LINEN LL_USART_ConfigSyncMode\n + * CR2 CLKEN LL_USART_ConfigSyncMode\n + * CR3 SCEN LL_USART_ConfigSyncMode\n + * CR3 IREN LL_USART_ConfigSyncMode\n + * CR3 HDSEL LL_USART_ConfigSyncMode + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_ConfigSyncMode(USART_TypeDef *USARTx) +{ + /* In Synchronous mode, the following bits must be kept cleared: + - LINEN bit in the USART_CR2 register, + - SCEN, IREN and HDSEL bits in the USART_CR3 register. + */ + CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN)); + CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_IREN | USART_CR3_HDSEL)); + /* set the UART/USART in Synchronous mode */ + SET_BIT(USARTx->CR2, USART_CR2_CLKEN); +} + +/** + * @brief Perform basic configuration of USART for enabling use in LIN Mode + * @note In LIN mode, the following bits must be kept cleared: + * - STOP and CLKEN bits in the USART_CR2 register, + * - SCEN bit in the USART_CR3 register, + * - IREN bit in the USART_CR3 register, + * - HDSEL bit in the USART_CR3 register. + * This function also set the UART/USART in LIN mode. + * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not + * LIN feature is supported by the USARTx instance. + * @note Call of this function is equivalent to following function call sequence : + * - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function + * - Clear STOP in CR2 using @ref LL_USART_SetStopBitsLength() function + * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function + * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function + * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function + * - Set LINEN in CR2 using @ref LL_USART_EnableLIN() function + * @note Other remaining configurations items related to LIN Mode + * (as Baud Rate, Word length, LIN Break Detection Length, ...) should be set using + * dedicated functions + * @rmtoll CR2 CLKEN LL_USART_ConfigLINMode\n + * CR2 STOP LL_USART_ConfigLINMode\n + * CR2 LINEN LL_USART_ConfigLINMode\n + * CR3 IREN LL_USART_ConfigLINMode\n + * CR3 SCEN LL_USART_ConfigLINMode\n + * CR3 HDSEL LL_USART_ConfigLINMode + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_ConfigLINMode(USART_TypeDef *USARTx) +{ + /* In LIN mode, the following bits must be kept cleared: + - STOP and CLKEN bits in the USART_CR2 register, + - IREN, SCEN and HDSEL bits in the USART_CR3 register. + */ + CLEAR_BIT(USARTx->CR2, (USART_CR2_CLKEN | USART_CR2_STOP)); + CLEAR_BIT(USARTx->CR3, (USART_CR3_IREN | USART_CR3_SCEN | USART_CR3_HDSEL)); + /* Set the UART/USART in LIN mode */ + SET_BIT(USARTx->CR2, USART_CR2_LINEN); +} + +/** + * @brief Perform basic configuration of USART for enabling use in Half Duplex Mode + * @note In Half Duplex mode, the following bits must be kept cleared: + * - LINEN bit in the USART_CR2 register, + * - CLKEN bit in the USART_CR2 register, + * - SCEN bit in the USART_CR3 register, + * - IREN bit in the USART_CR3 register, + * This function also sets the UART/USART in Half Duplex mode. + * @note Macro IS_UART_HALFDUPLEX_INSTANCE(USARTx) can be used to check whether or not + * Half-Duplex mode is supported by the USARTx instance. + * @note Call of this function is equivalent to following function call sequence : + * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function + * - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function + * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function + * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function + * - Set HDSEL in CR3 using @ref LL_USART_EnableHalfDuplex() function + * @note Other remaining configurations items related to Half Duplex Mode + * (as Baud Rate, Word length, Parity, ...) should be set using + * dedicated functions + * @rmtoll CR2 LINEN LL_USART_ConfigHalfDuplexMode\n + * CR2 CLKEN LL_USART_ConfigHalfDuplexMode\n + * CR3 HDSEL LL_USART_ConfigHalfDuplexMode\n + * CR3 SCEN LL_USART_ConfigHalfDuplexMode\n + * CR3 IREN LL_USART_ConfigHalfDuplexMode + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_ConfigHalfDuplexMode(USART_TypeDef *USARTx) +{ + /* In Half Duplex mode, the following bits must be kept cleared: + - LINEN and CLKEN bits in the USART_CR2 register, + - SCEN and IREN bits in the USART_CR3 register. + */ + CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); + CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_IREN)); + /* set the UART/USART in Half Duplex mode */ + SET_BIT(USARTx->CR3, USART_CR3_HDSEL); +} + +/** + * @brief Perform basic configuration of USART for enabling use in Smartcard Mode + * @note In Smartcard mode, the following bits must be kept cleared: + * - LINEN bit in the USART_CR2 register, + * - IREN bit in the USART_CR3 register, + * - HDSEL bit in the USART_CR3 register. + * This function also configures Stop bits to 1.5 bits and + * sets the USART in Smartcard mode (SCEN bit). + * Clock Output is also enabled (CLKEN). + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @note Call of this function is equivalent to following function call sequence : + * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function + * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function + * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function + * - Configure STOP in CR2 using @ref LL_USART_SetStopBitsLength() function + * - Set CLKEN in CR2 using @ref LL_USART_EnableSCLKOutput() function + * - Set SCEN in CR3 using @ref LL_USART_EnableSmartcard() function + * @note Other remaining configurations items related to Smartcard Mode + * (as Baud Rate, Word length, Parity, ...) should be set using + * dedicated functions + * @rmtoll CR2 LINEN LL_USART_ConfigSmartcardMode\n + * CR2 STOP LL_USART_ConfigSmartcardMode\n + * CR2 CLKEN LL_USART_ConfigSmartcardMode\n + * CR3 HDSEL LL_USART_ConfigSmartcardMode\n + * CR3 SCEN LL_USART_ConfigSmartcardMode + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_ConfigSmartcardMode(USART_TypeDef *USARTx) +{ + /* In Smartcard mode, the following bits must be kept cleared: + - LINEN bit in the USART_CR2 register, + - IREN and HDSEL bits in the USART_CR3 register. + */ + CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN)); + CLEAR_BIT(USARTx->CR3, (USART_CR3_IREN | USART_CR3_HDSEL)); + /* Configure Stop bits to 1.5 bits */ + /* Synchronous mode is activated by default */ + SET_BIT(USARTx->CR2, (USART_CR2_STOP_0 | USART_CR2_STOP_1 | USART_CR2_CLKEN)); + /* set the UART/USART in Smartcard mode */ + SET_BIT(USARTx->CR3, USART_CR3_SCEN); +} + +/** + * @brief Perform basic configuration of USART for enabling use in Irda Mode + * @note In IRDA mode, the following bits must be kept cleared: + * - LINEN bit in the USART_CR2 register, + * - STOP and CLKEN bits in the USART_CR2 register, + * - SCEN bit in the USART_CR3 register, + * - HDSEL bit in the USART_CR3 register. + * This function also sets the UART/USART in IRDA mode (IREN bit). + * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not + * IrDA feature is supported by the USARTx instance. + * @note Call of this function is equivalent to following function call sequence : + * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function + * - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function + * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function + * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function + * - Configure STOP in CR2 using @ref LL_USART_SetStopBitsLength() function + * - Set IREN in CR3 using @ref LL_USART_EnableIrda() function + * @note Other remaining configurations items related to Irda Mode + * (as Baud Rate, Word length, Power mode, ...) should be set using + * dedicated functions + * @rmtoll CR2 LINEN LL_USART_ConfigIrdaMode\n + * CR2 CLKEN LL_USART_ConfigIrdaMode\n + * CR2 STOP LL_USART_ConfigIrdaMode\n + * CR3 SCEN LL_USART_ConfigIrdaMode\n + * CR3 HDSEL LL_USART_ConfigIrdaMode\n + * CR3 IREN LL_USART_ConfigIrdaMode + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_ConfigIrdaMode(USART_TypeDef *USARTx) +{ + /* In IRDA mode, the following bits must be kept cleared: + - LINEN, STOP and CLKEN bits in the USART_CR2 register, + - SCEN and HDSEL bits in the USART_CR3 register. + */ + CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN | USART_CR2_STOP)); + CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL)); + /* set the UART/USART in IRDA mode */ + SET_BIT(USARTx->CR3, USART_CR3_IREN); +} + +/** + * @brief Perform basic configuration of USART for enabling use in Multi processor Mode + * (several USARTs connected in a network, one of the USARTs can be the master, + * its TX output connected to the RX inputs of the other slaves USARTs). + * @note In MultiProcessor mode, the following bits must be kept cleared: + * - LINEN bit in the USART_CR2 register, + * - CLKEN bit in the USART_CR2 register, + * - SCEN bit in the USART_CR3 register, + * - IREN bit in the USART_CR3 register, + * - HDSEL bit in the USART_CR3 register. + * @note Call of this function is equivalent to following function call sequence : + * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function + * - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function + * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function + * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function + * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function + * @note Other remaining configurations items related to Multi processor Mode + * (as Baud Rate, Wake Up Method, Node address, ...) should be set using + * dedicated functions + * @rmtoll CR2 LINEN LL_USART_ConfigMultiProcessMode\n + * CR2 CLKEN LL_USART_ConfigMultiProcessMode\n + * CR3 SCEN LL_USART_ConfigMultiProcessMode\n + * CR3 HDSEL LL_USART_ConfigMultiProcessMode\n + * CR3 IREN LL_USART_ConfigMultiProcessMode + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_ConfigMultiProcessMode(USART_TypeDef *USARTx) +{ + /* In Multi Processor mode, the following bits must be kept cleared: + - LINEN and CLKEN bits in the USART_CR2 register, + - IREN, SCEN and HDSEL bits in the USART_CR3 register. + */ + CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); + CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN)); +} + +/** + * @} + */ + +/** @defgroup USART_LL_EF_FLAG_Management FLAG_Management + * @{ + */ + +/** + * @brief Check if the USART Parity Error Flag is set or not + * @rmtoll ISR PE LL_USART_IsActiveFlag_PE + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_PE(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->ISR, USART_ISR_PE) == (USART_ISR_PE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART Framing Error Flag is set or not + * @rmtoll ISR FE LL_USART_IsActiveFlag_FE + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_FE(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->ISR, USART_ISR_FE) == (USART_ISR_FE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART Noise error detected Flag is set or not + * @rmtoll ISR NE LL_USART_IsActiveFlag_NE + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_NE(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->ISR, USART_ISR_NE) == (USART_ISR_NE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART OverRun Error Flag is set or not + * @rmtoll ISR ORE LL_USART_IsActiveFlag_ORE + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_ORE(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->ISR, USART_ISR_ORE) == (USART_ISR_ORE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART IDLE line detected Flag is set or not + * @rmtoll ISR IDLE LL_USART_IsActiveFlag_IDLE + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_IDLE(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->ISR, USART_ISR_IDLE) == (USART_ISR_IDLE)) ? 1UL : 0UL); +} + +#define LL_USART_IsActiveFlag_RXNE LL_USART_IsActiveFlag_RXNE_RXFNE /* Redefinition for legacy purpose */ + +/** + * @brief Check if the USART Read Data Register or USART RX FIFO Not Empty Flag is set or not + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll ISR RXNE_RXFNE LL_USART_IsActiveFlag_RXNE_RXFNE + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_RXNE_RXFNE(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->ISR, USART_ISR_RXNE_RXFNE) == (USART_ISR_RXNE_RXFNE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART Transmission Complete Flag is set or not + * @rmtoll ISR TC LL_USART_IsActiveFlag_TC + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_TC(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->ISR, USART_ISR_TC) == (USART_ISR_TC)) ? 1UL : 0UL); +} + +#define LL_USART_IsActiveFlag_TXE LL_USART_IsActiveFlag_TXE_TXFNF /* Redefinition for legacy purpose */ + +/** + * @brief Check if the USART Transmit Data Register Empty or USART TX FIFO Not Full Flag is set or not + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll ISR TXE_TXFNF LL_USART_IsActiveFlag_TXE_TXFNF + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_TXE_TXFNF(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->ISR, USART_ISR_TXE_TXFNF) == (USART_ISR_TXE_TXFNF)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART LIN Break Detection Flag is set or not + * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not + * LIN feature is supported by the USARTx instance. + * @rmtoll ISR LBDF LL_USART_IsActiveFlag_LBD + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_LBD(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->ISR, USART_ISR_LBDF) == (USART_ISR_LBDF)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART CTS interrupt Flag is set or not + * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not + * Hardware Flow control feature is supported by the USARTx instance. + * @rmtoll ISR CTSIF LL_USART_IsActiveFlag_nCTS + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_nCTS(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->ISR, USART_ISR_CTSIF) == (USART_ISR_CTSIF)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART CTS Flag is set or not + * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not + * Hardware Flow control feature is supported by the USARTx instance. + * @rmtoll ISR CTS LL_USART_IsActiveFlag_CTS + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_CTS(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->ISR, USART_ISR_CTS) == (USART_ISR_CTS)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART Receiver Time Out Flag is set or not + * @rmtoll ISR RTOF LL_USART_IsActiveFlag_RTO + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_RTO(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->ISR, USART_ISR_RTOF) == (USART_ISR_RTOF)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART End Of Block Flag is set or not + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll ISR EOBF LL_USART_IsActiveFlag_EOB + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_EOB(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->ISR, USART_ISR_EOBF) == (USART_ISR_EOBF)) ? 1UL : 0UL); +} + +/** + * @brief Check if the SPI Slave Underrun error flag is set or not + * @note Macro IS_UART_SPI_SLAVE_INSTANCE(USARTx) can be used to check whether or not + * SPI Slave mode feature is supported by the USARTx instance. + * @rmtoll ISR UDR LL_USART_IsActiveFlag_UDR + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_UDR(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->ISR, USART_ISR_UDR) == (USART_ISR_UDR)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART Auto-Baud Rate Error Flag is set or not + * @note Macro IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(USARTx) can be used to check whether or not + * Auto Baud Rate detection feature is supported by the USARTx instance. + * @rmtoll ISR ABRE LL_USART_IsActiveFlag_ABRE + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_ABRE(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->ISR, USART_ISR_ABRE) == (USART_ISR_ABRE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART Auto-Baud Rate Flag is set or not + * @note Macro IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(USARTx) can be used to check whether or not + * Auto Baud Rate detection feature is supported by the USARTx instance. + * @rmtoll ISR ABRF LL_USART_IsActiveFlag_ABR + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_ABR(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->ISR, USART_ISR_ABRF) == (USART_ISR_ABRF)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART Busy Flag is set or not + * @rmtoll ISR BUSY LL_USART_IsActiveFlag_BUSY + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_BUSY(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->ISR, USART_ISR_BUSY) == (USART_ISR_BUSY)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART Character Match Flag is set or not + * @rmtoll ISR CMF LL_USART_IsActiveFlag_CM + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_CM(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->ISR, USART_ISR_CMF) == (USART_ISR_CMF)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART Send Break Flag is set or not + * @rmtoll ISR SBKF LL_USART_IsActiveFlag_SBK + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_SBK(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->ISR, USART_ISR_SBKF) == (USART_ISR_SBKF)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART Receive Wake Up from mute mode Flag is set or not + * @rmtoll ISR RWU LL_USART_IsActiveFlag_RWU + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_RWU(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->ISR, USART_ISR_RWU) == (USART_ISR_RWU)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART Wake Up from stop mode Flag is set or not + * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether or not + * Wake-up from Stop mode feature is supported by the USARTx instance. + * @rmtoll ISR WUF LL_USART_IsActiveFlag_WKUP + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_WKUP(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->ISR, USART_ISR_WUF) == (USART_ISR_WUF)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART Transmit Enable Acknowledge Flag is set or not + * @rmtoll ISR TEACK LL_USART_IsActiveFlag_TEACK + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_TEACK(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->ISR, USART_ISR_TEACK) == (USART_ISR_TEACK)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART Receive Enable Acknowledge Flag is set or not + * @rmtoll ISR REACK LL_USART_IsActiveFlag_REACK + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_REACK(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->ISR, USART_ISR_REACK) == (USART_ISR_REACK)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART TX FIFO Empty Flag is set or not + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll ISR TXFE LL_USART_IsActiveFlag_TXFE + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_TXFE(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->ISR, USART_ISR_TXFE) == (USART_ISR_TXFE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART RX FIFO Full Flag is set or not + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll ISR RXFF LL_USART_IsActiveFlag_RXFF + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_RXFF(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->ISR, USART_ISR_RXFF) == (USART_ISR_RXFF)) ? 1UL : 0UL); +} + +/** + * @brief Check if the Smartcard Transmission Complete Before Guard Time Flag is set or not + * @rmtoll ISR TCBGT LL_USART_IsActiveFlag_TCBGT + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_TCBGT(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->ISR, USART_ISR_TCBGT) == (USART_ISR_TCBGT)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART TX FIFO Threshold Flag is set or not + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll ISR TXFT LL_USART_IsActiveFlag_TXFT + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_TXFT(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->ISR, USART_ISR_TXFT) == (USART_ISR_TXFT)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART RX FIFO Threshold Flag is set or not + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll ISR RXFT LL_USART_IsActiveFlag_RXFT + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_RXFT(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->ISR, USART_ISR_RXFT) == (USART_ISR_RXFT)) ? 1UL : 0UL); +} + +/** + * @brief Clear Parity Error Flag + * @rmtoll ICR PECF LL_USART_ClearFlag_PE + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_ClearFlag_PE(USART_TypeDef *USARTx) +{ + WRITE_REG(USARTx->ICR, USART_ICR_PECF); +} + +/** + * @brief Clear Framing Error Flag + * @rmtoll ICR FECF LL_USART_ClearFlag_FE + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_ClearFlag_FE(USART_TypeDef *USARTx) +{ + WRITE_REG(USARTx->ICR, USART_ICR_FECF); +} + +/** + * @brief Clear Noise Error detected Flag + * @rmtoll ICR NECF LL_USART_ClearFlag_NE + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_ClearFlag_NE(USART_TypeDef *USARTx) +{ + WRITE_REG(USARTx->ICR, USART_ICR_NECF); +} + +/** + * @brief Clear OverRun Error Flag + * @rmtoll ICR ORECF LL_USART_ClearFlag_ORE + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_ClearFlag_ORE(USART_TypeDef *USARTx) +{ + WRITE_REG(USARTx->ICR, USART_ICR_ORECF); +} + +/** + * @brief Clear IDLE line detected Flag + * @rmtoll ICR IDLECF LL_USART_ClearFlag_IDLE + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_ClearFlag_IDLE(USART_TypeDef *USARTx) +{ + WRITE_REG(USARTx->ICR, USART_ICR_IDLECF); +} + +/** + * @brief Clear TX FIFO Empty Flag + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll ICR TXFECF LL_USART_ClearFlag_TXFE + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_ClearFlag_TXFE(USART_TypeDef *USARTx) +{ + WRITE_REG(USARTx->ICR, USART_ICR_TXFECF); +} + +/** + * @brief Clear Transmission Complete Flag + * @rmtoll ICR TCCF LL_USART_ClearFlag_TC + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_ClearFlag_TC(USART_TypeDef *USARTx) +{ + WRITE_REG(USARTx->ICR, USART_ICR_TCCF); +} + +/** + * @brief Clear Smartcard Transmission Complete Before Guard Time Flag + * @rmtoll ICR TCBGTCF LL_USART_ClearFlag_TCBGT + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_ClearFlag_TCBGT(USART_TypeDef *USARTx) +{ + WRITE_REG(USARTx->ICR, USART_ICR_TCBGTCF); +} + +/** + * @brief Clear LIN Break Detection Flag + * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not + * LIN feature is supported by the USARTx instance. + * @rmtoll ICR LBDCF LL_USART_ClearFlag_LBD + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_ClearFlag_LBD(USART_TypeDef *USARTx) +{ + WRITE_REG(USARTx->ICR, USART_ICR_LBDCF); +} + +/** + * @brief Clear CTS Interrupt Flag + * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not + * Hardware Flow control feature is supported by the USARTx instance. + * @rmtoll ICR CTSCF LL_USART_ClearFlag_nCTS + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_ClearFlag_nCTS(USART_TypeDef *USARTx) +{ + WRITE_REG(USARTx->ICR, USART_ICR_CTSCF); +} + +/** + * @brief Clear Receiver Time Out Flag + * @rmtoll ICR RTOCF LL_USART_ClearFlag_RTO + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_ClearFlag_RTO(USART_TypeDef *USARTx) +{ + WRITE_REG(USARTx->ICR, USART_ICR_RTOCF); +} + +/** + * @brief Clear End Of Block Flag + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll ICR EOBCF LL_USART_ClearFlag_EOB + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_ClearFlag_EOB(USART_TypeDef *USARTx) +{ + WRITE_REG(USARTx->ICR, USART_ICR_EOBCF); +} + +/** + * @brief Clear SPI Slave Underrun Flag + * @note Macro IS_UART_SPI_SLAVE_INSTANCE(USARTx) can be used to check whether or not + * SPI Slave mode feature is supported by the USARTx instance. + * @rmtoll ICR UDRCF LL_USART_ClearFlag_UDR + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_ClearFlag_UDR(USART_TypeDef *USARTx) +{ + WRITE_REG(USARTx->ICR, USART_ICR_UDRCF); +} + +/** + * @brief Clear Character Match Flag + * @rmtoll ICR CMCF LL_USART_ClearFlag_CM + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_ClearFlag_CM(USART_TypeDef *USARTx) +{ + WRITE_REG(USARTx->ICR, USART_ICR_CMCF); +} + +/** + * @brief Clear Wake Up from stop mode Flag + * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether or not + * Wake-up from Stop mode feature is supported by the USARTx instance. + * @rmtoll ICR WUCF LL_USART_ClearFlag_WKUP + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_ClearFlag_WKUP(USART_TypeDef *USARTx) +{ + WRITE_REG(USARTx->ICR, USART_ICR_WUCF); +} + +/** + * @} + */ + +/** @defgroup USART_LL_EF_IT_Management IT_Management + * @{ + */ + +/** + * @brief Enable IDLE Interrupt + * @rmtoll CR1 IDLEIE LL_USART_EnableIT_IDLE + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableIT_IDLE(USART_TypeDef *USARTx) +{ + ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_IDLEIE); +} + +#define LL_USART_EnableIT_RXNE LL_USART_EnableIT_RXNE_RXFNE /* Redefinition for legacy purpose */ + +/** + * @brief Enable RX Not Empty and RX FIFO Not Empty Interrupt + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll CR1 RXNEIE_RXFNEIE LL_USART_EnableIT_RXNE_RXFNE + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableIT_RXNE_RXFNE(USART_TypeDef *USARTx) +{ + ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_RXNEIE_RXFNEIE); +} + +/** + * @brief Enable Transmission Complete Interrupt + * @rmtoll CR1 TCIE LL_USART_EnableIT_TC + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableIT_TC(USART_TypeDef *USARTx) +{ + ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_TCIE); +} + +#define LL_USART_EnableIT_TXE LL_USART_EnableIT_TXE_TXFNF /* Redefinition for legacy purpose */ + +/** + * @brief Enable TX Empty and TX FIFO Not Full Interrupt + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll CR1 TXEIE_TXFNFIE LL_USART_EnableIT_TXE_TXFNF + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableIT_TXE_TXFNF(USART_TypeDef *USARTx) +{ + ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_TXEIE_TXFNFIE); +} + +/** + * @brief Enable Parity Error Interrupt + * @rmtoll CR1 PEIE LL_USART_EnableIT_PE + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableIT_PE(USART_TypeDef *USARTx) +{ + ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_PEIE); +} + +/** + * @brief Enable Character Match Interrupt + * @rmtoll CR1 CMIE LL_USART_EnableIT_CM + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableIT_CM(USART_TypeDef *USARTx) +{ + ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_CMIE); +} + +/** + * @brief Enable Receiver Timeout Interrupt + * @rmtoll CR1 RTOIE LL_USART_EnableIT_RTO + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableIT_RTO(USART_TypeDef *USARTx) +{ + ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_RTOIE); +} + +/** + * @brief Enable End Of Block Interrupt + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll CR1 EOBIE LL_USART_EnableIT_EOB + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableIT_EOB(USART_TypeDef *USARTx) +{ + ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_EOBIE); +} + +/** + * @brief Enable TX FIFO Empty Interrupt + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll CR1 TXFEIE LL_USART_EnableIT_TXFE + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableIT_TXFE(USART_TypeDef *USARTx) +{ + ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_TXFEIE); +} + +/** + * @brief Enable RX FIFO Full Interrupt + * @rmtoll CR1 RXFFIE LL_USART_EnableIT_RXFF + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableIT_RXFF(USART_TypeDef *USARTx) +{ + ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_RXFFIE); +} + +/** + * @brief Enable LIN Break Detection Interrupt + * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not + * LIN feature is supported by the USARTx instance. + * @rmtoll CR2 LBDIE LL_USART_EnableIT_LBD + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableIT_LBD(USART_TypeDef *USARTx) +{ + SET_BIT(USARTx->CR2, USART_CR2_LBDIE); +} + +/** + * @brief Enable Error Interrupt + * @note When set, Error Interrupt Enable Bit is enabling interrupt generation in case of a framing + * error, overrun error or noise flag (FE=1 or ORE=1 or NF=1 in the USARTx_ISR register). + * 0: Interrupt is inhibited + * 1: An interrupt is generated when FE=1 or ORE=1 or NF=1 in the USARTx_ISR register. + * @rmtoll CR3 EIE LL_USART_EnableIT_ERROR + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableIT_ERROR(USART_TypeDef *USARTx) +{ + ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_EIE); +} + +/** + * @brief Enable CTS Interrupt + * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not + * Hardware Flow control feature is supported by the USARTx instance. + * @rmtoll CR3 CTSIE LL_USART_EnableIT_CTS + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableIT_CTS(USART_TypeDef *USARTx) +{ + ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_CTSIE); +} + +/** + * @brief Enable Wake Up from Stop Mode Interrupt + * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether or not + * Wake-up from Stop mode feature is supported by the USARTx instance. + * @rmtoll CR3 WUFIE LL_USART_EnableIT_WKUP + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableIT_WKUP(USART_TypeDef *USARTx) +{ + ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_WUFIE); +} + +/** + * @brief Enable TX FIFO Threshold Interrupt + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll CR3 TXFTIE LL_USART_EnableIT_TXFT + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableIT_TXFT(USART_TypeDef *USARTx) +{ + ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_TXFTIE); +} + +/** + * @brief Enable Smartcard Transmission Complete Before Guard Time Interrupt + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll CR3 TCBGTIE LL_USART_EnableIT_TCBGT + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableIT_TCBGT(USART_TypeDef *USARTx) +{ + ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_TCBGTIE); +} + +/** + * @brief Enable RX FIFO Threshold Interrupt + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll CR3 RXFTIE LL_USART_EnableIT_RXFT + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableIT_RXFT(USART_TypeDef *USARTx) +{ + ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_RXFTIE); +} + +/** + * @brief Disable IDLE Interrupt + * @rmtoll CR1 IDLEIE LL_USART_DisableIT_IDLE + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableIT_IDLE(USART_TypeDef *USARTx) +{ + ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_IDLEIE); +} + +#define LL_USART_DisableIT_RXNE LL_USART_DisableIT_RXNE_RXFNE /* Redefinition for legacy purpose */ + +/** + * @brief Disable RX Not Empty and RX FIFO Not Empty Interrupt + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll CR1 RXNEIE_RXFNEIE LL_USART_DisableIT_RXNE_RXFNE + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableIT_RXNE_RXFNE(USART_TypeDef *USARTx) +{ + ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_RXNEIE_RXFNEIE); +} + +/** + * @brief Disable Transmission Complete Interrupt + * @rmtoll CR1 TCIE LL_USART_DisableIT_TC + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableIT_TC(USART_TypeDef *USARTx) +{ + ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_TCIE); +} + +#define LL_USART_DisableIT_TXE LL_USART_DisableIT_TXE_TXFNF /* Redefinition for legacy purpose */ + +/** + * @brief Disable TX Empty and TX FIFO Not Full Interrupt + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll CR1 TXEIE_TXFNFIE LL_USART_DisableIT_TXE_TXFNF + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableIT_TXE_TXFNF(USART_TypeDef *USARTx) +{ + ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_TXEIE_TXFNFIE); +} + +/** + * @brief Disable Parity Error Interrupt + * @rmtoll CR1 PEIE LL_USART_DisableIT_PE + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableIT_PE(USART_TypeDef *USARTx) +{ + ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_PEIE); +} + +/** + * @brief Disable Character Match Interrupt + * @rmtoll CR1 CMIE LL_USART_DisableIT_CM + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableIT_CM(USART_TypeDef *USARTx) +{ + ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_CMIE); +} + +/** + * @brief Disable Receiver Timeout Interrupt + * @rmtoll CR1 RTOIE LL_USART_DisableIT_RTO + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableIT_RTO(USART_TypeDef *USARTx) +{ + ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_RTOIE); +} + +/** + * @brief Disable End Of Block Interrupt + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll CR1 EOBIE LL_USART_DisableIT_EOB + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableIT_EOB(USART_TypeDef *USARTx) +{ + ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_EOBIE); +} + +/** + * @brief Disable TX FIFO Empty Interrupt + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll CR1 TXFEIE LL_USART_DisableIT_TXFE + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableIT_TXFE(USART_TypeDef *USARTx) +{ + ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_TXFEIE); +} + +/** + * @brief Disable RX FIFO Full Interrupt + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll CR1 RXFFIE LL_USART_DisableIT_RXFF + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableIT_RXFF(USART_TypeDef *USARTx) +{ + ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_RXFFIE); +} + +/** + * @brief Disable LIN Break Detection Interrupt + * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not + * LIN feature is supported by the USARTx instance. + * @rmtoll CR2 LBDIE LL_USART_DisableIT_LBD + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableIT_LBD(USART_TypeDef *USARTx) +{ + CLEAR_BIT(USARTx->CR2, USART_CR2_LBDIE); +} + +/** + * @brief Disable Error Interrupt + * @note When set, Error Interrupt Enable Bit is enabling interrupt generation in case of a framing + * error, overrun error or noise flag (FE=1 or ORE=1 or NF=1 in the USARTx_ISR register). + * 0: Interrupt is inhibited + * 1: An interrupt is generated when FE=1 or ORE=1 or NF=1 in the USARTx_ISR register. + * @rmtoll CR3 EIE LL_USART_DisableIT_ERROR + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableIT_ERROR(USART_TypeDef *USARTx) +{ + ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_EIE); +} + +/** + * @brief Disable CTS Interrupt + * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not + * Hardware Flow control feature is supported by the USARTx instance. + * @rmtoll CR3 CTSIE LL_USART_DisableIT_CTS + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableIT_CTS(USART_TypeDef *USARTx) +{ + ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_CTSIE); +} + +/** + * @brief Disable Wake Up from Stop Mode Interrupt + * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether or not + * Wake-up from Stop mode feature is supported by the USARTx instance. + * @rmtoll CR3 WUFIE LL_USART_DisableIT_WKUP + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableIT_WKUP(USART_TypeDef *USARTx) +{ + ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_WUFIE); +} + +/** + * @brief Disable TX FIFO Threshold Interrupt + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll CR3 TXFTIE LL_USART_DisableIT_TXFT + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableIT_TXFT(USART_TypeDef *USARTx) +{ + ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_TXFTIE); +} + +/** + * @brief Disable Smartcard Transmission Complete Before Guard Time Interrupt + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll CR3 TCBGTIE LL_USART_DisableIT_TCBGT + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableIT_TCBGT(USART_TypeDef *USARTx) +{ + ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_TCBGTIE); +} + +/** + * @brief Disable RX FIFO Threshold Interrupt + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll CR3 RXFTIE LL_USART_DisableIT_RXFT + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableIT_RXFT(USART_TypeDef *USARTx) +{ + ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_RXFTIE); +} + +/** + * @brief Check if the USART IDLE Interrupt source is enabled or disabled. + * @rmtoll CR1 IDLEIE LL_USART_IsEnabledIT_IDLE + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_IDLE(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR1, USART_CR1_IDLEIE) == (USART_CR1_IDLEIE)) ? 1UL : 0UL); +} + +#define LL_USART_IsEnabledIT_RXNE LL_USART_IsEnabledIT_RXNE_RXFNE /* Redefinition for legacy purpose */ + +/** + * @brief Check if the USART RX Not Empty and USART RX FIFO Not Empty Interrupt is enabled or disabled. + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll CR1 RXNEIE_RXFNEIE LL_USART_IsEnabledIT_RXNE_RXFNE + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_RXNE_RXFNE(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR1, USART_CR1_RXNEIE_RXFNEIE) == (USART_CR1_RXNEIE_RXFNEIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART Transmission Complete Interrupt is enabled or disabled. + * @rmtoll CR1 TCIE LL_USART_IsEnabledIT_TC + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_TC(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR1, USART_CR1_TCIE) == (USART_CR1_TCIE)) ? 1UL : 0UL); +} + +#define LL_USART_IsEnabledIT_TXE LL_USART_IsEnabledIT_TXE_TXFNF /* Redefinition for legacy purpose */ + +/** + * @brief Check if the USART TX Empty and USART TX FIFO Not Full Interrupt is enabled or disabled + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll CR1 TXEIE_TXFNFIE LL_USART_IsEnabledIT_TXE_TXFNF + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_TXE_TXFNF(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR1, USART_CR1_TXEIE_TXFNFIE) == (USART_CR1_TXEIE_TXFNFIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART Parity Error Interrupt is enabled or disabled. + * @rmtoll CR1 PEIE LL_USART_IsEnabledIT_PE + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_PE(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR1, USART_CR1_PEIE) == (USART_CR1_PEIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART Character Match Interrupt is enabled or disabled. + * @rmtoll CR1 CMIE LL_USART_IsEnabledIT_CM + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_CM(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR1, USART_CR1_CMIE) == (USART_CR1_CMIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART Receiver Timeout Interrupt is enabled or disabled. + * @rmtoll CR1 RTOIE LL_USART_IsEnabledIT_RTO + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_RTO(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR1, USART_CR1_RTOIE) == (USART_CR1_RTOIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART End Of Block Interrupt is enabled or disabled. + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll CR1 EOBIE LL_USART_IsEnabledIT_EOB + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_EOB(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR1, USART_CR1_EOBIE) == (USART_CR1_EOBIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART TX FIFO Empty Interrupt is enabled or disabled + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll CR1 TXFEIE LL_USART_IsEnabledIT_TXFE + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_TXFE(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR1, USART_CR1_TXFEIE) == (USART_CR1_TXFEIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART RX FIFO Full Interrupt is enabled or disabled + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll CR1 RXFFIE LL_USART_IsEnabledIT_RXFF + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_RXFF(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR1, USART_CR1_RXFFIE) == (USART_CR1_RXFFIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART LIN Break Detection Interrupt is enabled or disabled. + * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not + * LIN feature is supported by the USARTx instance. + * @rmtoll CR2 LBDIE LL_USART_IsEnabledIT_LBD + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_LBD(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR2, USART_CR2_LBDIE) == (USART_CR2_LBDIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART Error Interrupt is enabled or disabled. + * @rmtoll CR3 EIE LL_USART_IsEnabledIT_ERROR + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_ERROR(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR3, USART_CR3_EIE) == (USART_CR3_EIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART CTS Interrupt is enabled or disabled. + * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not + * Hardware Flow control feature is supported by the USARTx instance. + * @rmtoll CR3 CTSIE LL_USART_IsEnabledIT_CTS + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_CTS(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR3, USART_CR3_CTSIE) == (USART_CR3_CTSIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the USART Wake Up from Stop Mode Interrupt is enabled or disabled. + * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether or not + * Wake-up from Stop mode feature is supported by the USARTx instance. + * @rmtoll CR3 WUFIE LL_USART_IsEnabledIT_WKUP + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_WKUP(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR3, USART_CR3_WUFIE) == (USART_CR3_WUFIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if USART TX FIFO Threshold Interrupt is enabled or disabled + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll CR3 TXFTIE LL_USART_IsEnabledIT_TXFT + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_TXFT(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR3, USART_CR3_TXFTIE) == (USART_CR3_TXFTIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if the Smartcard Transmission Complete Before Guard Time Interrupt is enabled or disabled. + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll CR3 TCBGTIE LL_USART_IsEnabledIT_TCBGT + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_TCBGT(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR3, USART_CR3_TCBGTIE) == (USART_CR3_TCBGTIE)) ? 1UL : 0UL); +} + +/** + * @brief Check if USART RX FIFO Threshold Interrupt is enabled or disabled + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll CR3 RXFTIE LL_USART_IsEnabledIT_RXFT + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledIT_RXFT(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR3, USART_CR3_RXFTIE) == (USART_CR3_RXFTIE)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup USART_LL_EF_DMA_Management DMA_Management + * @{ + */ + +/** + * @brief Enable DMA Mode for reception + * @rmtoll CR3 DMAR LL_USART_EnableDMAReq_RX + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableDMAReq_RX(USART_TypeDef *USARTx) +{ + ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_DMAR); +} + +/** + * @brief Disable DMA Mode for reception + * @rmtoll CR3 DMAR LL_USART_DisableDMAReq_RX + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableDMAReq_RX(USART_TypeDef *USARTx) +{ + ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_DMAR); +} + +/** + * @brief Check if DMA Mode is enabled for reception + * @rmtoll CR3 DMAR LL_USART_IsEnabledDMAReq_RX + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledDMAReq_RX(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR3, USART_CR3_DMAR) == (USART_CR3_DMAR)) ? 1UL : 0UL); +} + +/** + * @brief Enable DMA Mode for transmission + * @rmtoll CR3 DMAT LL_USART_EnableDMAReq_TX + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableDMAReq_TX(USART_TypeDef *USARTx) +{ + ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_DMAT); +} + +/** + * @brief Disable DMA Mode for transmission + * @rmtoll CR3 DMAT LL_USART_DisableDMAReq_TX + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableDMAReq_TX(USART_TypeDef *USARTx) +{ + ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_DMAT); +} + +/** + * @brief Check if DMA Mode is enabled for transmission + * @rmtoll CR3 DMAT LL_USART_IsEnabledDMAReq_TX + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledDMAReq_TX(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR3, USART_CR3_DMAT) == (USART_CR3_DMAT)) ? 1UL : 0UL); +} + +/** + * @brief Enable DMA Disabling on Reception Error + * @rmtoll CR3 DDRE LL_USART_EnableDMADeactOnRxErr + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_EnableDMADeactOnRxErr(USART_TypeDef *USARTx) +{ + SET_BIT(USARTx->CR3, USART_CR3_DDRE); +} + +/** + * @brief Disable DMA Disabling on Reception Error + * @rmtoll CR3 DDRE LL_USART_DisableDMADeactOnRxErr + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_DisableDMADeactOnRxErr(USART_TypeDef *USARTx) +{ + CLEAR_BIT(USARTx->CR3, USART_CR3_DDRE); +} + +/** + * @brief Indicate if DMA Disabling on Reception Error is disabled + * @rmtoll CR3 DDRE LL_USART_IsEnabledDMADeactOnRxErr + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_USART_IsEnabledDMADeactOnRxErr(const USART_TypeDef *USARTx) +{ + return ((READ_BIT(USARTx->CR3, USART_CR3_DDRE) == (USART_CR3_DDRE)) ? 1UL : 0UL); +} + +/** + * @brief Get the data register address used for DMA transfer + * @rmtoll RDR RDR LL_USART_DMA_GetRegAddr\n + * @rmtoll TDR TDR LL_USART_DMA_GetRegAddr + * @param USARTx USART Instance + * @param Direction This parameter can be one of the following values: + * @arg @ref LL_USART_DMA_REG_DATA_TRANSMIT + * @arg @ref LL_USART_DMA_REG_DATA_RECEIVE + * @retval Address of data register + */ +__STATIC_INLINE uint32_t LL_USART_DMA_GetRegAddr(const USART_TypeDef *USARTx, uint32_t Direction) +{ + uint32_t data_reg_addr; + + if (Direction == LL_USART_DMA_REG_DATA_TRANSMIT) + { + /* return address of TDR register */ + data_reg_addr = (uint32_t) &(USARTx->TDR); + } + else + { + /* return address of RDR register */ + data_reg_addr = (uint32_t) &(USARTx->RDR); + } + + return data_reg_addr; +} + +/** + * @} + */ + +/** @defgroup USART_LL_EF_Data_Management Data_Management + * @{ + */ + +/** + * @brief Read Receiver Data register (Receive Data value, 8 bits) + * @rmtoll RDR RDR LL_USART_ReceiveData8 + * @param USARTx USART Instance + * @retval Value between Min_Data=0x00 and Max_Data=0xFF + */ +__STATIC_INLINE uint8_t LL_USART_ReceiveData8(const USART_TypeDef *USARTx) +{ + return (uint8_t)(READ_BIT(USARTx->RDR, USART_RDR_RDR) & 0xFFU); +} + +/** + * @brief Read Receiver Data register (Receive Data value, 9 bits) + * @rmtoll RDR RDR LL_USART_ReceiveData9 + * @param USARTx USART Instance + * @retval Value between Min_Data=0x00 and Max_Data=0x1FF + */ +__STATIC_INLINE uint16_t LL_USART_ReceiveData9(const USART_TypeDef *USARTx) +{ + return (uint16_t)(READ_BIT(USARTx->RDR, USART_RDR_RDR)); +} + +/** + * @brief Write in Transmitter Data Register (Transmit Data value, 8 bits) + * @rmtoll TDR TDR LL_USART_TransmitData8 + * @param USARTx USART Instance + * @param Value between Min_Data=0x00 and Max_Data=0xFF + * @retval None + */ +__STATIC_INLINE void LL_USART_TransmitData8(USART_TypeDef *USARTx, uint8_t Value) +{ + USARTx->TDR = Value; +} + +/** + * @brief Write in Transmitter Data Register (Transmit Data value, 9 bits) + * @rmtoll TDR TDR LL_USART_TransmitData9 + * @param USARTx USART Instance + * @param Value between Min_Data=0x00 and Max_Data=0x1FF + * @retval None + */ +__STATIC_INLINE void LL_USART_TransmitData9(USART_TypeDef *USARTx, uint16_t Value) +{ + USARTx->TDR = (uint16_t)(Value & 0x1FFUL); +} + +/** + * @} + */ + +/** @defgroup USART_LL_EF_Execution Execution + * @{ + */ + +/** + * @brief Request an Automatic Baud Rate measurement on next received data frame + * @note Macro IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(USARTx) can be used to check whether or not + * Auto Baud Rate detection feature is supported by the USARTx instance. + * @rmtoll RQR ABRRQ LL_USART_RequestAutoBaudRate + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_RequestAutoBaudRate(USART_TypeDef *USARTx) +{ + SET_BIT(USARTx->RQR, (uint16_t)USART_RQR_ABRRQ); +} + +/** + * @brief Request Break sending + * @rmtoll RQR SBKRQ LL_USART_RequestBreakSending + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_RequestBreakSending(USART_TypeDef *USARTx) +{ + SET_BIT(USARTx->RQR, (uint16_t)USART_RQR_SBKRQ); +} + +/** + * @brief Put USART in mute mode and set the RWU flag + * @rmtoll RQR MMRQ LL_USART_RequestEnterMuteMode + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_RequestEnterMuteMode(USART_TypeDef *USARTx) +{ + SET_BIT(USARTx->RQR, (uint16_t)USART_RQR_MMRQ); +} + +/** + * @brief Request a Receive Data and FIFO flush + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @note Allows to discard the received data without reading them, and avoid an overrun + * condition. + * @rmtoll RQR RXFRQ LL_USART_RequestRxDataFlush + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_RequestRxDataFlush(USART_TypeDef *USARTx) +{ + SET_BIT(USARTx->RQR, (uint16_t)USART_RQR_RXFRQ); +} + +/** + * @brief Request a Transmit data and FIFO flush + * @note Macro IS_UART_FIFO_INSTANCE(USARTx) can be used to check whether or not + * FIFO mode feature is supported by the USARTx instance. + * @rmtoll RQR TXFRQ LL_USART_RequestTxDataFlush + * @param USARTx USART Instance + * @retval None + */ +__STATIC_INLINE void LL_USART_RequestTxDataFlush(USART_TypeDef *USARTx) +{ + SET_BIT(USARTx->RQR, (uint16_t)USART_RQR_TXFRQ); +} + +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup USART_LL_EF_Init Initialization and de-initialization functions + * @{ + */ +ErrorStatus LL_USART_DeInit(const USART_TypeDef *USARTx); +ErrorStatus LL_USART_Init(USART_TypeDef *USARTx, const LL_USART_InitTypeDef *USART_InitStruct); +void LL_USART_StructInit(LL_USART_InitTypeDef *USART_InitStruct); +ErrorStatus LL_USART_ClockInit(USART_TypeDef *USARTx, const LL_USART_ClockInitTypeDef *USART_ClockInitStruct); +void LL_USART_ClockStructInit(LL_USART_ClockInitTypeDef *USART_ClockInitStruct); +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* USART1 || USART2 || USART3 || UART4 || UART5 || USART6 + || UART7 || UART8 || UART9 || USART10 || USART11 || UART12 */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_LL_USART_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_usb.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_usb.h new file mode 100644 index 0000000000..8835a2126d --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_usb.h @@ -0,0 +1,908 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_usb.h + * @author MCD Application Team + * @brief Header file of USB Low Layer HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_LL_USB_H +#define STM32H5xx_LL_USB_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal_def.h" + +#if defined (USB_DRD_FS) +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup USB_LL + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief USB Mode definition + */ + +typedef enum +{ + USB_DEVICE_MODE = 0, + USB_HOST_MODE = 1 +} USB_ModeTypeDef; + +/** + * @brief URB States definition + */ +typedef enum +{ + URB_IDLE = 0, + URB_DONE, + URB_NOTREADY, + URB_NYET, + URB_ERROR, + URB_STALL +} USB_URBStateTypeDef; + +/** + * @brief Host channel States definition + */ +typedef enum +{ + HC_IDLE = 0, + HC_XFRC, + HC_HALTED, + HC_ACK, + HC_NAK, + HC_NYET, + HC_STALL, + HC_XACTERR, + HC_BBLERR, + HC_DATATGLERR +} USB_HCStateTypeDef; + + +/** + * @brief USB Instance Initialization Structure definition + */ +typedef struct +{ + uint32_t dev_endpoints; /*!< Device Endpoints number. + This parameter depends on the used USB core. + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint32_t Host_channels; /*!< Host Channels number. + This parameter Depends on the used USB core. + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint32_t dma_enable; /*!< USB DMA state. + If DMA is not supported this parameter shall be set by default to zero */ + + uint32_t speed; /*!< USB Core speed. + This parameter can be any value of @ref PCD_Speed/HCD_Speed + (HCD_SPEED_xxx, HCD_SPEED_xxx) */ + + uint32_t ep0_mps; /*!< Set the Endpoint 0 Max Packet size. */ + + uint32_t phy_itface; /*!< Select the used PHY interface. + This parameter can be any value of @ref PCD_PHY_Module/HCD_PHY_Module */ + + uint32_t Sof_enable; /*!< Enable or disable the output of the SOF signal. */ + + uint32_t low_power_enable; /*!< Enable or disable the low Power Mode. */ + + uint32_t lpm_enable; /*!< Enable or disable Link Power Management. */ + + uint32_t battery_charging_enable; /*!< Enable or disable Battery charging. */ + + uint32_t vbus_sensing_enable; /*!< Enable or disable the VBUS Sensing feature. */ + + uint32_t bulk_doublebuffer_enable; /*!< Enable or disable the double buffer mode on bulk EP */ + + uint32_t iso_singlebuffer_enable; /*!< Enable or disable the Single buffer mode on Isochronous EP */ +} USB_CfgTypeDef; + +typedef struct +{ + uint8_t num; /*!< Endpoint number + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint8_t is_in; /*!< Endpoint direction + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t is_stall; /*!< Endpoint stall condition + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t type; /*!< Endpoint type + This parameter can be any value of @ref USB_LL_EP_Type */ + + uint8_t data_pid_start; /*!< Initial data PID + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + + uint16_t pmaadress; /*!< PMA Address + This parameter can be any value between Min_addr = 0 and Max_addr = 1K */ + + uint16_t pmaaddr0; /*!< PMA Address0 + This parameter can be any value between Min_addr = 0 and Max_addr = 1K */ + + uint16_t pmaaddr1; /*!< PMA Address1 + This parameter can be any value between Min_addr = 0 and Max_addr = 1K */ + + uint8_t doublebuffer; /*!< Double buffer enable + This parameter can be 0 or 1 */ + + + uint32_t maxpacket; /*!< Endpoint Max packet size + This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */ + + uint8_t *xfer_buff; /*!< Pointer to transfer buffer */ + + uint32_t xfer_len; /*!< Current transfer length */ + + uint32_t xfer_count; /*!< Partial transfer length in case of multi packet transfer */ + + uint32_t xfer_len_db; /*!< double buffer transfer length used with bulk double buffer in */ + + uint8_t xfer_fill_db; /*!< double buffer Need to Fill new buffer used with bulk_in */ +} USB_EPTypeDef; + +typedef struct +{ + uint8_t dev_addr; /*!< USB device address. + This parameter must be a number between Min_Data = 1 and Max_Data = 255 */ + + uint8_t phy_ch_num; /*!< Host channel number. + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint8_t ep_num; /*!< Endpoint number. + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint8_t ch_dir; /*!< channel direction + This parameter store the physical channel direction IN/OUT/BIDIR */ + + uint8_t speed; /*!< USB Host Channel speed. + This parameter can be any value of @ref HCD_Device_Speed: + (HCD_DEVICE_SPEED_xxx) */ + + uint8_t hub_port_nbr; /*!< USB HUB port number */ + uint8_t hub_addr; /*!< USB HUB address */ + + uint8_t ep_type; /*!< Endpoint Type. + This parameter can be any value of @ref USB_LL_EP_Type */ + + uint16_t max_packet; /*!< Endpoint Max packet size. + This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */ + + uint8_t data_pid; /*!< Initial data PID. + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t *xfer_buff; /*!< Pointer to transfer buffer. */ + + uint32_t xfer_len; /*!< Current transfer length. */ + + uint32_t xfer_len_db; /*!< Current transfer length used in double buffer mode. */ + + + uint32_t xfer_count; /*!< Partial transfer length in case of multi packet transfer. */ + + uint8_t toggle_in; /*!< IN transfer current toggle flag. + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t toggle_out; /*!< OUT transfer current toggle flag + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint32_t ErrCnt; /*!< Host channel error count. */ + + uint16_t pmaadress; /*!< PMA Address + This parameter can be any value between Min_addr = 0 and Max_addr = 1K */ + + uint16_t pmaaddr0; /*!< PMA Address0 + This parameter can be any value between Min_addr = 0 and Max_addr = 1K */ + + uint16_t pmaaddr1; /*!< PMA Address1 + This parameter can be any value between Min_addr = 0 and Max_addr = 1K */ + + uint8_t doublebuffer; /*!< Double buffer enable + This parameter can be 0 or 1 */ + + USB_URBStateTypeDef urb_state; /*!< URB state. + This parameter can be any value of @ref USB_URBStateTypeDef */ + + USB_HCStateTypeDef state; /*!< Host Channel state. + This parameter can be any value of @ref USB_HCStateTypeDef */ +} USB_HCTypeDef; + +typedef USB_ModeTypeDef USB_DRD_ModeTypeDef; +typedef USB_CfgTypeDef USB_DRD_CfgTypeDef; +typedef USB_EPTypeDef USB_DRD_EPTypeDef; +typedef USB_URBStateTypeDef USB_DRD_URBStateTypeDef; +typedef USB_HCStateTypeDef USB_DRD_HCStateTypeDef; +typedef USB_HCTypeDef USB_DRD_HCTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup PCD_Exported_Constants PCD Exported Constants + * @{ + */ +/** @defgroup USB_LL_EP0_MPS USB Low Layer EP0 MPS + * @{ + */ +#define EP_MPS_64 0U +#define EP_MPS_32 1U +#define EP_MPS_16 2U +#define EP_MPS_8 3U +/** + * @} + */ + +/** @defgroup USB_LL_EP_Type USB Low Layer EP Type + * @{ + */ +#define EP_TYPE_CTRL 0U +#define EP_TYPE_ISOC 1U +#define EP_TYPE_BULK 2U +#define EP_TYPE_INTR 3U +#define EP_TYPE_MSK 3U +/** + * @} + */ + +/** @defgroup USB_LL_EP_Speed USB Low Layer EP Speed + * @{ + */ +#define EP_SPEED_LOW 0U +#define EP_SPEED_FULL 1U +#define EP_SPEED_HIGH 2U +/** + * @} + */ + +/** @defgroup USB_LL_CH_PID_Type USB Low Layer Channel PID Type + * @{ + */ +#define HC_PID_DATA0 0U +#define HC_PID_DATA2 1U +#define HC_PID_DATA1 2U +#define HC_PID_SETUP 3U +/** + * @} + */ + +/** @defgroup USB_LL Device Speed + * @{ + */ +#define USBD_FS_SPEED 2U +#define USBH_FSLS_SPEED 1U +/** + * @} + */ + +#define EP_ADDR_MSK 0x7U + +#ifndef USE_USB_DOUBLE_BUFFER +#define USE_USB_DOUBLE_BUFFER 1U +#endif /* USE_USB_DOUBLE_BUFFER */ + +#define USB_EMBEDDED_PHY 2U + +/*!< USB Speed */ +#define USB_DRD_SPEED_FS 1U +#define USB_DRD_SPEED_LS 2U +#define USB_DRD_SPEED_LSFS 3U + +/*!< Channel Direction */ +#define CH_IN_DIR 1U +#define CH_OUT_DIR 0U + +/*!< Number of used channels in the Application */ +#ifndef USB_DRD_USED_CHANNELS +#define USB_DRD_USED_CHANNELS 8U +#endif /* USB_DRD_USED_CHANNELS */ + +/** + * used for USB_HC_DoubleBuffer API + */ +#define USB_DRD_BULK_DBUFF_ENBALE 1U +#define USB_DRD_BULK_DBUFF_DISABLE 2U +#define USB_DRD_ISOC_DBUFF_ENBALE 3U +#define USB_DRD_ISOC_DBUFF_DISABLE 4U + +/* First available address in PMA */ +#define PMA_START_ADDR (0x10U + (8U *(USB_DRD_USED_CHANNELS - 2U))) +#define PMA_END_ADDR USB_DRD_PMA_SIZE + +/* Exported macro ------------------------------------------------------------*/ +/** + * @} + */ +/******************** Bit definition for USB_COUNTn_RX register *************/ +#define USB_CNTRX_NBLK_MSK (0x1FU << 26) +#define USB_CNTRX_BLSIZE (0x1U << 31) + + +/*Set Channel/Endpoint to the USB Register */ +#define USB_DRD_SET_CHEP(USBx, bEpChNum, wRegValue) (*(__IO uint32_t *)\ + (&(USBx)->CHEP0R + (bEpChNum)) = (uint32_t)(wRegValue)) + +/*Get Channel/Endpoint from the USB Register */ +#define USB_DRD_GET_CHEP(USBx, bEpChNum) (*(__IO uint32_t *)(&(USBx)->CHEP0R + (bEpChNum))) + + +/** + * @brief free buffer used from the application realizing it to the line + * toggles bit SW_BUF in the double buffered endpoint register + * @param USBx USB device. + * @param bEpChNum, bDir + * @retval None + */ +#define USB_DRD_FREE_USER_BUFFER(USBx, bEpChNum, bDir) \ + do { \ + if ((bDir) == 0U) \ + { \ + /* OUT double buffered endpoint */ \ + USB_DRD_TX_DTOG((USBx), (bEpChNum)); \ + } \ + else if ((bDir) == 1U) \ + { \ + /* IN double buffered endpoint */ \ + USB_DRD_RX_DTOG((USBx), (bEpChNum)); \ + } \ + } while(0) + + +/** + * @brief Set the Setup bit in the corresponding channel, when a Setup + transaction is needed. + * @param USBx USB device. + * @param bEpChNum + * @retval None + */ +#define USB_DRD_CHEP_TX_SETUP(USBx, bEpChNum) \ + do { \ + uint32_t _wRegVal; \ + \ + _wRegVal = USB_DRD_GET_CHEP((USBx), (bEpChNum)) ; \ + \ + /* Set Setup bit */ \ + USB_DRD_SET_CHEP((USBx), (bEpChNum), (_wRegVal | USB_CHEP_SETUP)); \ + } while(0) + + +/** + * @brief Clears bit ERR_RX in the Channel register + * @param USBx USB peripheral instance register address. + * @param bChNum Endpoint Number. + * @retval None + */ +#define USB_DRD_CLEAR_CHEP_RX_ERR(USBx, bChNum) \ + do { \ + uint32_t _wRegVal; \ + \ + _wRegVal = USB_DRD_GET_CHEP((USBx), (bChNum)); \ + _wRegVal = (_wRegVal & USB_CHEP_REG_MASK & (~USB_CHEP_ERRRX) & (~USB_CHEP_VTRX)) | \ + (USB_CHEP_VTTX | USB_CHEP_ERRTX); \ + \ + USB_DRD_SET_CHEP((USBx), (bChNum), _wRegVal); \ + } while(0) /* USB_DRD_CLEAR_CHEP_RX_ERR */ + + +/** + * @brief Clears bit ERR_TX in the Channel register + * @param USBx USB peripheral instance register address. + * @param bChNum Endpoint Number. + * @retval None + */ +#define USB_DRD_CLEAR_CHEP_TX_ERR(USBx, bChNum) \ + do { \ + uint32_t _wRegVal; \ + \ + _wRegVal = USB_DRD_GET_CHEP((USBx), (bChNum)); \ + _wRegVal = (_wRegVal & USB_CHEP_REG_MASK & (~USB_CHEP_ERRTX) & (~USB_CHEP_VTTX)) | \ + (USB_CHEP_VTRX|USB_CHEP_ERRRX); \ + \ + USB_DRD_SET_CHEP((USBx), (bChNum), _wRegVal); \ + } while(0) /* USB_DRD_CLEAR_CHEP_TX_ERR */ + + +/** + * @brief sets the status for tx transfer (bits STAT_TX[1:0]). + * @param USBx USB peripheral instance register address. + * @param bEpChNum Endpoint Number. + * @param wState new state + * @retval None + */ +#define USB_DRD_SET_CHEP_TX_STATUS(USBx, bEpChNum, wState) \ + do { \ + uint32_t _wRegVal; \ + \ + _wRegVal = USB_DRD_GET_CHEP((USBx), (bEpChNum)) & USB_CHEP_TX_DTOGMASK; \ + /* toggle first bit ? */ \ + if ((USB_CHEP_TX_DTOG1 & (wState)) != 0U) \ + { \ + _wRegVal ^= USB_CHEP_TX_DTOG1; \ + } \ + /* toggle second bit ? */ \ + if ((USB_CHEP_TX_DTOG2 & (wState)) != 0U) \ + { \ + _wRegVal ^= USB_CHEP_TX_DTOG2; \ + } \ + USB_DRD_SET_CHEP((USBx), (bEpChNum), (_wRegVal | USB_CHEP_VTRX| USB_CHEP_VTTX)); \ + } while(0) /* USB_DRD_SET_CHEP_TX_STATUS */ + + +/** + * @brief sets the status for rx transfer (bits STAT_TX[1:0]) + * @param USBx USB peripheral instance register address. + * @param bEpChNum Endpoint Number. + * @param wState new state + * @retval None + */ +#define USB_DRD_SET_CHEP_RX_STATUS(USBx, bEpChNum, wState) \ + do { \ + uint32_t _wRegVal; \ + \ + _wRegVal = USB_DRD_GET_CHEP((USBx), (bEpChNum)) & USB_CHEP_RX_DTOGMASK; \ + /* toggle first bit ? */ \ + if ((USB_CHEP_RX_DTOG1 & (wState)) != 0U) \ + { \ + _wRegVal ^= USB_CHEP_RX_DTOG1; \ + } \ + /* toggle second bit ? */ \ + if ((USB_CHEP_RX_DTOG2 & (wState)) != 0U) \ + { \ + _wRegVal ^= USB_CHEP_RX_DTOG2; \ + } \ + USB_DRD_SET_CHEP((USBx), (bEpChNum), (_wRegVal | USB_CHEP_VTRX | USB_CHEP_VTTX)); \ + } while(0) /* USB_DRD_SET_CHEP_RX_STATUS */ + + +/** + * @brief gets the status for tx/rx transfer (bits STAT_TX[1:0] + * /STAT_RX[1:0]) + * @param USBx USB peripheral instance register address. + * @param bEpChNum Endpoint Number. + * @retval status + */ +#define USB_DRD_GET_CHEP_TX_STATUS(USBx, bEpChNum) \ + ((uint16_t)USB_DRD_GET_CHEP((USBx), (bEpChNum)) & USB_DRD_CHEP_TX_STTX) + +#define USB_DRD_GET_CHEP_RX_STATUS(USBx, bEpChNum) \ + ((uint16_t)USB_DRD_GET_CHEP((USBx), (bEpChNum)) & USB_DRD_CHEP_RX_STRX) + + +/** + * @brief set EP_KIND bit. + * @param USBx USB peripheral instance register address. + * @param bEpChNum Endpoint Number. + * @retval None + */ +#define USB_DRD_SET_CHEP_KIND(USBx, bEpChNum) \ + do { \ + uint32_t _wRegVal; \ + \ + _wRegVal = USB_DRD_GET_CHEP((USBx), (bEpChNum)) & USB_CHEP_REG_MASK; \ + \ + USB_DRD_SET_CHEP((USBx), (bEpChNum), (_wRegVal | USB_CHEP_VTRX | USB_CHEP_VTTX | USB_CHEP_KIND)); \ + } while(0) /* USB_DRD_SET_CHEP_KIND */ + + +/** + * @brief clear EP_KIND bit. + * @param USBx USB peripheral instance register address. + * @param bEpChNum Endpoint Number. + * @retval None + */ +#define USB_DRD_CLEAR_CHEP_KIND(USBx, bEpChNum) \ + do { \ + uint32_t _wRegVal; \ + \ + _wRegVal = USB_DRD_GET_CHEP((USBx), (bEpChNum)) & USB_EP_KIND_MASK; \ + \ + USB_DRD_SET_CHEP((USBx), (bEpChNum), (_wRegVal | USB_CHEP_VTRX | USB_CHEP_VTTX)); \ + } while(0) /* USB_DRD_CLEAR_CHEP_KIND */ + + +/** + * @brief Clears bit CTR_RX / CTR_TX in the endpoint register. + * @param USBx USB peripheral instance register address. + * @param bEpChNum Endpoint Number. + * @retval None + */ +#define USB_DRD_CLEAR_RX_CHEP_CTR(USBx, bEpChNum) \ + do { \ + uint32_t _wRegVal; \ + \ + _wRegVal = USB_DRD_GET_CHEP((USBx), (bEpChNum)) & (0xFFFF7FFFU & USB_CHEP_REG_MASK); \ + \ + USB_DRD_SET_CHEP((USBx), (bEpChNum), (_wRegVal | USB_CHEP_VTTX)); \ + } while(0) /* USB_CLEAR_RX_CHEP_CTR */ + +#define USB_DRD_CLEAR_TX_CHEP_CTR(USBx, bEpChNum) \ + do { \ + uint32_t _wRegVal; \ + \ + _wRegVal = USB_DRD_GET_CHEP((USBx), (bEpChNum)) & (0xFFFFFF7FU & USB_CHEP_REG_MASK); \ + \ + USB_DRD_SET_CHEP((USBx), (bEpChNum), (_wRegVal | USB_CHEP_VTRX)); \ + } while(0) /* USB_CLEAR_TX_CHEP_CTR */ + + +/** + * @brief Toggles DTOG_RX / DTOG_TX bit in the endpoint register. + * @param USBx USB peripheral instance register address. + * @param bEpChNum Endpoint Number. + * @retval None + */ +#define USB_DRD_RX_DTOG(USBx, bEpChNum) \ + do { \ + uint32_t _wEPVal; \ + \ + _wEPVal = USB_DRD_GET_CHEP((USBx), (bEpChNum)) & USB_CHEP_REG_MASK; \ + \ + USB_DRD_SET_CHEP((USBx), (bEpChNum), (_wEPVal | USB_CHEP_VTRX | USB_CHEP_VTTX | USB_CHEP_DTOG_RX)); \ + } while(0) /* USB_DRD_RX_DTOG */ + +#define USB_DRD_TX_DTOG(USBx, bEpChNum) \ + do { \ + uint32_t _wEPVal; \ + \ + _wEPVal = USB_DRD_GET_CHEP((USBx), (bEpChNum)) & USB_CHEP_REG_MASK; \ + \ + USB_DRD_SET_CHEP((USBx), (bEpChNum), (_wEPVal | USB_CHEP_VTRX | USB_CHEP_VTTX | USB_CHEP_DTOG_TX)); \ + } while(0) /* USB_TX_DTOG */ + + +/** + * @brief Clears DTOG_RX / DTOG_TX bit in the endpoint register. + * @param USBx USB peripheral instance register address. + * @param bEpChNum Endpoint Number. + * @retval None + */ +#define USB_DRD_CLEAR_RX_DTOG(USBx, bEpChNum) \ + do { \ + uint32_t _wRegVal; \ + \ + _wRegVal = USB_DRD_GET_CHEP((USBx), (bEpChNum)); \ + \ + if ((_wRegVal & USB_CHEP_DTOG_RX) != 0U) \ + { \ + USB_DRD_RX_DTOG((USBx), (bEpChNum)); \ + } \ + } while(0) /* USB_DRD_CLEAR_RX_DTOG */ + +#define USB_DRD_CLEAR_TX_DTOG(USBx, bEpChNum) \ + do { \ + uint32_t _wRegVal; \ + \ + _wRegVal = USB_DRD_GET_CHEP((USBx), (bEpChNum)); \ + \ + if ((_wRegVal & USB_CHEP_DTOG_TX) != 0U) \ + { \ + USB_DRD_TX_DTOG((USBx), (bEpChNum)); \ + } \ + } while(0) /* USB_DRD_CLEAR_TX_DTOG */ + + +/** + * @brief Sets address in an endpoint register. + * @param USBx USB peripheral instance register address. + * @param bEpChNum Endpoint Number. + * @param bAddr Address. + * @retval None + */ +#define USB_DRD_SET_CHEP_ADDRESS(USBx, bEpChNum, bAddr) \ + do { \ + uint32_t _wRegVal; \ + \ + /*Read the USB->CHEPx into _wRegVal, Reset(DTOGRX/STRX/DTOGTX/STTX) and set the EpAddress*/ \ + _wRegVal = (USB_DRD_GET_CHEP((USBx), (bEpChNum)) & USB_CHEP_REG_MASK) | (bAddr); \ + \ + /*Set _wRegVal in USB->CHEPx and set Transmit/Receive Valid Transfer (x=bEpChNum)*/ \ + USB_DRD_SET_CHEP((USBx), (bEpChNum), (_wRegVal | USB_CHEP_VTRX | USB_CHEP_VTTX)); \ + } while(0) /* USB_DRD_SET_CHEP_ADDRESS */ + + +/* PMA API Buffer Descriptor Management ------------------------------------------------------------*/ +/* Buffer Descriptor Table TXBD0/RXBD0 --- > TXBD7/RXBD7 8 possible descriptor +* The buffer descriptor is located inside the packet buffer memory (USB_PMA_BUFF) +* TXBD [Reserve |Countx| Address_Tx] +* RXBD [BLSIEZ|NUM_Block |CounRx| Address_Rx] */ + +/* Set TX Buffer Descriptor Address Field */ +#define USB_DRD_SET_CHEP_TX_ADDRESS(USBx, bEpChNum, wAddr) \ + do { \ + /* Reset old Address */ \ + (USB_DRD_PMA_BUFF + (bEpChNum))->TXBD &= USB_PMA_TXBD_ADDMSK; \ + \ + /* Bit0 & Bit1 should be =0 PMA must be Word aligned */ \ + (USB_DRD_PMA_BUFF + (bEpChNum))->TXBD |= (uint32_t)(((uint32_t)(wAddr) >> 2U) << 2U); \ + } while(0) /* USB_DRD_SET_CHEP_TX_ADDRESS */ + +/* Set RX Buffer Descriptor Address Field */ +#define USB_DRD_SET_CHEP_RX_ADDRESS(USBx, bEpChNum, wAddr) \ + do { \ + /* Reset old Address */ \ + (USB_DRD_PMA_BUFF + (bEpChNum))->RXBD &= USB_PMA_RXBD_ADDMSK; \ + \ + /* Bit0 & Bit1 should be =0 PMA must be Word aligned */ \ + (USB_DRD_PMA_BUFF + (bEpChNum))->RXBD |= (uint32_t)(((uint32_t)(wAddr) >> 2U) << 2U); \ + } while(0) /* USB_SET_CHEP_RX_ADDRESS */ + + +/** + * @brief Sets counter of rx buffer with no. of blocks. + * @param pdwReg Register pointer + * @param wCount Counter. + * @param wNBlocks no. of Blocks. + * @retval None + */ +#define USB_DRD_CALC_BLK32(pdwReg, wCount, wNBlocks) \ + do { \ + /* Divide PacketSize by 32 to calculate the Nb of Block32 */ \ + (wNBlocks) =((uint32_t)(wCount) >> 5U); \ + if (((uint32_t)(wCount) % 32U) == 0U) \ + { \ + (wNBlocks)--; \ + } \ + \ + (pdwReg)|= (uint32_t)((((wNBlocks) << 26U)) | USB_CNTRX_BLSIZE); \ + } while(0) /* USB_DRD_CALC_BLK32 */ + +#define USB_DRD_CALC_BLK2(pdwReg, wCount, wNBlocks) \ + do { \ + /* Divide PacketSize by 32 to calculate the Nb of Block32 */ \ + (wNBlocks) = (uint32_t)((uint32_t)(wCount) >> 1U); \ + if (((wCount) & 0x1U) != 0U) \ + { \ + (wNBlocks)++; \ + } \ + (pdwReg) |= (uint32_t)((wNBlocks) << 26U); \ + } while(0) /* USB_DRD_CALC_BLK2 */ + +#define USB_DRD_SET_CHEP_CNT_RX_REG(pdwReg, wCount) \ + do { \ + uint32_t wNBlocks; \ + \ + (pdwReg) &= ~(USB_CNTRX_BLSIZE | USB_CNTRX_NBLK_MSK); \ + \ + if ((wCount) > 62U) \ + { \ + USB_DRD_CALC_BLK32((pdwReg), (wCount), wNBlocks); \ + } \ + else \ + { \ + if ((wCount) == 0U) \ + { \ + (pdwReg) |= USB_CNTRX_BLSIZE; \ + } \ + else \ + { \ + USB_DRD_CALC_BLK2((pdwReg), (wCount), wNBlocks); \ + } \ + } \ + } while(0) /* USB_DRD_SET_CHEP_CNT_RX_REG */ + + +/** + * @brief sets counter for the tx/rx buffer. + * @param USBx USB peripheral instance register address. + * @param bEpChNum Endpoint Number. + * @param wCount Counter value. + * @retval None + */ +#define USB_DRD_SET_CHEP_TX_CNT(USBx,bEpChNum, wCount) \ + do { \ + /* Reset old TX_Count value */ \ + (USB_DRD_PMA_BUFF + (bEpChNum))->TXBD &= USB_PMA_TXBD_COUNTMSK; \ + \ + /* Set the wCount in the dedicated EP_TXBuffer */ \ + (USB_DRD_PMA_BUFF + (bEpChNum))->TXBD |= (uint32_t)((uint32_t)(wCount) << 16U); \ + } while(0) + +#define USB_DRD_SET_CHEP_RX_DBUF0_CNT(USBx, bEpChNum, wCount) \ + USB_DRD_SET_CHEP_CNT_RX_REG(((USB_DRD_PMA_BUFF + (bEpChNum))->TXBD), (wCount)) + +#define USB_DRD_SET_CHEP_RX_CNT(USBx, bEpChNum, wCount) \ + USB_DRD_SET_CHEP_CNT_RX_REG(((USB_DRD_PMA_BUFF + (bEpChNum))->RXBD), (wCount)) + +/** + * @brief gets counter of the tx buffer. + * @param USBx USB peripheral instance register address. + * @param bEpChNum Endpoint Number. + * @retval Counter value + */ +#define USB_DRD_GET_CHEP_TX_CNT(USBx, bEpChNum) (((USB_DRD_PMA_BUFF + (bEpChNum))->TXBD & 0x03FF0000U) >> 16U) +#define USB_DRD_GET_CHEP_RX_CNT(USBx, bEpChNum) (((USB_DRD_PMA_BUFF + (bEpChNum))->RXBD & 0x03FF0000U) >> 16U) + +#define USB_DRD_GET_EP_TX_CNT USB_GET_CHEP_TX_CNT +#define USB_DRD_GET_CH_TX_CNT USB_GET_CHEP_TX_CNT + +#define USB_DRD_GET_EP_RX_CNT USB_DRD_GET_CHEP_RX_CNT +#define USB_DRD_GET_CH_RX_CNT USB_DRD_GET_CHEP_RX_CNT +/** + * @brief Sets buffer 0/1 address in a double buffer endpoint. + * @param USBx USB peripheral instance register address. + * @param bEpChNum Endpoint Number. + * @param wBuf0Addr buffer 0 address. + * @retval Counter value + */ +#define USB_DRD_SET_CHEP_DBUF0_ADDR(USBx, bEpChNum, wBuf0Addr) \ + USB_DRD_SET_CHEP_TX_ADDRESS((USBx), (bEpChNum), (wBuf0Addr)) + +#define USB_DRD_SET_CHEP_DBUF1_ADDR(USBx, bEpChNum, wBuf1Addr) \ + USB_DRD_SET_CHEP_RX_ADDRESS((USBx), (bEpChNum), (wBuf1Addr)) + + +/** + * @brief Sets addresses in a double buffer endpoint. + * @param USBx USB peripheral instance register address. + * @param bEpChNum Endpoint Number. + * @param wBuf0Addr: buffer 0 address. + * @param wBuf1Addr = buffer 1 address. + * @retval None + */ +#define USB_DRD_SET_CHEP_DBUF_ADDR(USBx, bEpChNum, wBuf0Addr, wBuf1Addr) \ + do { \ + USB_DRD_SET_CHEP_DBUF0_ADDR((USBx), (bEpChNum), (wBuf0Addr)); \ + USB_DRD_SET_CHEP_DBUF1_ADDR((USBx), (bEpChNum), (wBuf1Addr)); \ + } while(0) /* USB_DRD_SET_CHEP_DBUF_ADDR */ + + +/** + * @brief Gets buffer 0/1 address of a double buffer endpoint. + * @param USBx USB peripheral instance register address. + * @param bEpChNum Endpoint Number. + * @param bDir endpoint dir EP_DBUF_OUT = OUT + * EP_DBUF_IN = IN + * @param wCount: Counter value + * @retval None + */ +#define USB_DRD_SET_CHEP_DBUF0_CNT(USBx, bEpChNum, bDir, wCount) \ + do { \ + if ((bDir) == 0U) \ + { \ + /* OUT endpoint */ \ + USB_DRD_SET_CHEP_RX_DBUF0_CNT((USBx), (bEpChNum), (wCount)); \ + } \ + else \ + { \ + if ((bDir) == 1U) \ + { \ + /* IN endpoint */ \ + USB_DRD_SET_CHEP_TX_CNT((USBx), (bEpChNum), (wCount)); \ + } \ + } \ + } while(0) /* USB_DRD_SET_CHEP_DBUF0_CNT */ + +#define USB_DRD_SET_CHEP_DBUF1_CNT(USBx, bEpChNum, bDir, wCount) \ + do { \ + if ((bDir) == 0U) \ + { \ + /* OUT endpoint */ \ + USB_DRD_SET_CHEP_RX_CNT((USBx), (bEpChNum), (wCount)); \ + } \ + else \ + { \ + if ((bDir) == 1U) \ + { \ + /* IN endpoint */ \ + (USB_DRD_PMA_BUFF + (bEpChNum))->RXBD &= USB_PMA_TXBD_COUNTMSK; \ + (USB_DRD_PMA_BUFF + (bEpChNum))->RXBD |= (uint32_t)((uint32_t)(wCount) << 16U); \ + } \ + } \ + } while(0) /* USB_DRD_SET_CHEP_DBUF1_CNT */ + +#define USB_DRD_SET_CHEP_DBUF_CNT(USBx, bEpChNum, bDir, wCount) \ + do { \ + USB_DRD_SET_CHEP_DBUF0_CNT((USBx), (bEpChNum), (bDir), (wCount)); \ + USB_DRD_SET_CHEP_DBUF1_CNT((USBx), (bEpChNum), (bDir), (wCount)); \ + } while(0) /* USB_DRD_SET_EPCH_DBUF_CNT */ + +/** + * @brief Gets buffer 0/1 rx/tx counter for double buffering. + * @param USBx USB peripheral instance register address. + * @param bEpChNum Endpoint Number. + * @retval None + */ +#define USB_DRD_GET_CHEP_DBUF0_CNT(USBx, bEpChNum) (USB_DRD_GET_CHEP_TX_CNT((USBx), (bEpChNum))) +#define USB_DRD_GET_CHEP_DBUF1_CNT(USBx, bEpChNum) (USB_DRD_GET_CHEP_RX_CNT((USBx), (bEpChNum))) + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup USB_LL_Exported_Functions USB Low Layer Exported Functions + * @{ + */ + + +HAL_StatusTypeDef USB_CoreInit(USB_DRD_TypeDef *USBx, USB_DRD_CfgTypeDef cfg); +HAL_StatusTypeDef USB_DevInit(USB_DRD_TypeDef *USBx, USB_DRD_CfgTypeDef cfg); +HAL_StatusTypeDef USB_EnableGlobalInt(USB_DRD_TypeDef *USBx); +HAL_StatusTypeDef USB_DisableGlobalInt(USB_DRD_TypeDef *USBx); +HAL_StatusTypeDef USB_SetCurrentMode(USB_DRD_TypeDef *USBx, USB_DRD_ModeTypeDef mode); + +#if defined (HAL_PCD_MODULE_ENABLED) +HAL_StatusTypeDef USB_ActivateEndpoint(USB_DRD_TypeDef *USBx, USB_DRD_EPTypeDef *ep); +HAL_StatusTypeDef USB_DeactivateEndpoint(USB_DRD_TypeDef *USBx, USB_DRD_EPTypeDef *ep); +HAL_StatusTypeDef USB_EPStartXfer(USB_DRD_TypeDef *USBx, USB_DRD_EPTypeDef *ep); +HAL_StatusTypeDef USB_EPSetStall(USB_DRD_TypeDef *USBx, USB_DRD_EPTypeDef *ep); +HAL_StatusTypeDef USB_EPClearStall(USB_DRD_TypeDef *USBx, USB_DRD_EPTypeDef *ep); +HAL_StatusTypeDef USB_EPStopXfer(USB_DRD_TypeDef *USBx, USB_DRD_EPTypeDef *ep); +#endif /* defined (HAL_PCD_MODULE_ENABLED) */ + +HAL_StatusTypeDef USB_SetDevAddress(USB_DRD_TypeDef *USBx, uint8_t address); +HAL_StatusTypeDef USB_DevConnect(USB_DRD_TypeDef *USBx); +HAL_StatusTypeDef USB_DevDisconnect(USB_DRD_TypeDef *USBx); +HAL_StatusTypeDef USB_StopDevice(USB_DRD_TypeDef *USBx); +uint32_t USB_ReadInterrupts(USB_DRD_TypeDef const *USBx); + +HAL_StatusTypeDef USB_ResetPort(USB_DRD_TypeDef *USBx); +HAL_StatusTypeDef USB_HostInit(USB_DRD_TypeDef *USBx, USB_DRD_CfgTypeDef cfg); +HAL_StatusTypeDef USB_HC_IN_Halt(USB_DRD_TypeDef *USBx, uint8_t phy_ch); +HAL_StatusTypeDef USB_HC_OUT_Halt(USB_DRD_TypeDef *USBx, uint8_t phy_ch); +HAL_StatusTypeDef USB_HC_StartXfer(USB_DRD_TypeDef *USBx, USB_DRD_HCTypeDef *hc); + +uint32_t USB_GetHostSpeed(USB_DRD_TypeDef const *USBx); +uint32_t USB_GetCurrentFrame(USB_DRD_TypeDef const *USBx); +HAL_StatusTypeDef USB_StopHost(USB_DRD_TypeDef *USBx); +HAL_StatusTypeDef USB_HC_DoubleBuffer(USB_DRD_TypeDef *USBx, uint8_t phy_ch_num, uint8_t db_state); +HAL_StatusTypeDef USB_HC_Init(USB_DRD_TypeDef *USBx, uint8_t phy_ch_num, uint8_t epnum, + uint8_t dev_address, uint8_t speed, uint8_t ep_type, uint16_t mps); + +HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_DRD_TypeDef *USBx); +HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_DRD_TypeDef *USBx); + +void USB_WritePMA(USB_DRD_TypeDef const *USBx, uint8_t *pbUsrBuf, + uint16_t wPMABufAddr, uint16_t wNBytes); + +void USB_ReadPMA(USB_DRD_TypeDef const *USBx, uint8_t *pbUsrBuf, + uint16_t wPMABufAddr, uint16_t wNBytes); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* defined (USB_DRD_FS) */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* STM32H5xx_LL_USB_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_utils.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_utils.h new file mode 100644 index 0000000000..c7cdf376b1 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_utils.h @@ -0,0 +1,354 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_utils.h + * @author MCD Application Team + * @brief Header file of UTILS LL module. + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The LL UTILS driver contains a set of generic APIs that can be + used by user: + (+) Device electronic signature + (+) Timing functions + (+) PLL configuration functions + + @endverbatim + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32H5xx_LL_UTILS_H +#define __STM32H5xx_LL_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +/** @defgroup UTILS_LL UTILS + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup UTILS_LL_Private_Constants UTILS Private Constants + * @{ + */ + +/* Max delay can be used in LL_mDelay */ +#define LL_MAX_DELAY 0xFFFFFFFFU + +/** + * @brief Unique device ID register base address + */ +#define UID_BASE_ADDRESS UID_BASE + +/** + * @brief Flash size data register base address + */ +#define FLASHSIZE_BASE_ADDRESS FLASHSIZE_BASE + +/** + * @brief Package data register base address + */ +#define PACKAGE_BASE_ADDRESS PACKAGE_BASE + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup UTILS_LL_Private_Macros UTILS Private Macros + * @{ + */ +/** + * @} + */ +/* Exported types ------------------------------------------------------------*/ +/** @defgroup UTILS_LL_ES_INIT UTILS Exported structures + * @{ + */ + +/** + * @brief UTILS PLL structure definition + */ +typedef struct +{ + uint32_t PLLM; /*!< Division factor for PLL VCO input clock. + This parameter must be a number between Min_Data = 1 and Max_Data = 63 + + This feature can be modified afterwards using unitary function + @ref LL_RCC_PLL1_SetM(). */ + + uint32_t PLLN; /*!< Multiplication factor for PLL VCO output clock. + This parameter must be a number between Min_Data = 4 and Max_Data = 512 + + This feature can be modified afterwards using unitary function + @ref LL_RCC_PLL1_SetN(). */ + + uint32_t PLLP; /*!< Division for the main system clock. + This parameter must be a number between Min_Data = 2 and Max_Data = 128 + odd division factors are not allowed + + This feature can be modified afterwards using unitary function + @ref LL_RCC_PLL1_SetP(). */ + + uint32_t FRACN; /*!< Fractional part of the multiplication factor for PLL VCO. + This parameter can be a value between 0 and 8191 + + This feature can be modified afterwards using unitary function + @ref LL_RCC_PLL1_SetFRACN(). */ + + uint32_t VCO_Input; /*!< PLL clock Input range. + This parameter can be a value of @ref RCC_LL_EC_PLLINPUTRANGE + + This feature can be modified afterwards using unitary function + @ref LL_RCC_PLL1_SetVCOInputRange(). */ + + uint32_t VCO_Output; /*!< PLL clock Output range. + This parameter can be a value of @ref RCC_LL_EC_PLLOUTPUTRANGE + + This feature can be modified afterwards using unitary function + @ref LL_RCC_PLL1_SetVCOOutputRange(). */ + +} LL_UTILS_PLLInitTypeDef; + +/** + * @brief UTILS System, AHB and APB buses clock configuration structure definition + */ +typedef struct +{ + uint32_t SYSCLKDivider; /*!< The System clock (SYSCLK) divider. This clock is derived from the System clock. + This parameter can be a value of @ref RCC_LL_EC_SYSCLK_DIV + + This feature can be modified afterwards using unitary function + @ref LL_RCC_SetAHBPrescaler(). */ + + uint32_t APB1CLKDivider; /*!< The APB1 clock (PCLK1) divider. This clock is derived from the AHB clock (HCLK). + This parameter can be a value of @ref RCC_LL_EC_APB1_DIV + + This feature can be modified afterwards using unitary function + @ref LL_RCC_SetAPB1Prescaler(). */ + + uint32_t APB2CLKDivider; /*!< The APB2 clock (PCLK2) divider. This clock is derived from the AHB clock (HCLK). + This parameter can be a value of @ref RCC_LL_EC_APB2_DIV + + This feature can be modified afterwards using unitary function + @ref LL_RCC_SetAPB2Prescaler(). */ + + uint32_t APB3CLKDivider; /*!< The APB3 clock (PCLK3) divider. This clock is derived from the AHB clock (HCLK). + This parameter can be a value of @ref RCC_LL_EC_APB3_DIV + + This feature can be modified afterwards using unitary function + @ref LL_RCC_SetAPB3Prescaler(). */ + +} LL_UTILS_ClkInitTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup UTILS_LL_Exported_Constants UTILS Exported Constants + * @{ + */ + +/** @defgroup UTILS_EC_HSE_BYPASS HSE Bypass activation + * @{ + */ +#define LL_UTILS_HSEBYPASS_OFF 0x00000000U /*!< HSE Bypass is not enabled */ +#define LL_UTILS_HSEBYPASS_ON 0x00000001U /*!< HSE Bypass Analog is enabled */ +#define LL_UTILS_HSEBYPASS_DIGITAL_ON 0x00000002U /*!< HSE Bypass Digital is enabled */ +/** + * @} + */ + +/** @defgroup UTILS_EC_PACKAGETYPE PACKAGE TYPE + * @{ + */ +#define LL_UTILS_PACKAGETYPE_LQFP64 0x00000000U /*!< LQFP64 package type */ +#define LL_UTILS_PACKAGETYPE_VFQFPN68 0x00000001U /*!< VFQFPN68 package type */ +#define LL_UTILS_PACKAGETYPE_LQFP100 0x00000002U /*!< LQFP100 package type */ +#define LL_UTILS_PACKAGETYPE_UFBGA176 0x00000003U /*!< UFBGA176+25 package type */ +#define LL_UTILS_PACKAGETYPE_LQFP144 0x00000004U /*!< LQFP144 package type */ +#define LL_UTILS_PACKAGETYPE_LQFP48 0x00000005U /*!< LQFP48 package type */ +#define LL_UTILS_PACKAGETYPE_UFBGA169 0x00000006U /*!< UFBGA169 package type */ +#define LL_UTILS_PACKAGETYPE_LQFP176 0x00000007U /*!< LQFP176 package type */ +#define LL_UTILS_PACKAGETYPE_UFQFPN32 0x00000009U /*!< UFQFPN32 package type */ +#define LL_UTILS_PACKAGETYPE_LQFP100_SMPS 0x0000000AU /*!< LQFP100 with internal SMPS package type */ +#define LL_UTILS_PACKAGETYPE_UFBGA176_SMPS 0x0000000BU /*!< UFBGA176+25 with internal SMPS package type */ +#define LL_UTILS_PACKAGETYPE_LQFP144_SMPS 0x0000000CU /*!< LQFP144 with internal SMPS package type */ +#define LL_UTILS_PACKAGETYPE_LQFP176_SMPS 0x0000000DU /*!< LQFP176 with internal SMPS package type */ +#define LL_UTILS_PACKAGETYPE_UFBGA169_SMPS 0x0000000EU /*!< UFBGA169 with internal SMPS package type */ +#define LL_UTILS_PACKAGETYPE_WLCSP25 0x0000000FU /*!< WLCSP25 package type */ +#define LL_UTILS_PACKAGETYPE_UFQFPN48 0x00000010U /*!< UFQFPN48 package type */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup UTILS_LL_Exported_Functions UTILS Exported Functions + * @{ + */ + +/** @defgroup UTILS_EF_DEVICE_ELECTRONIC_SIGNATURE DEVICE ELECTRONIC SIGNATURE + * @{ + */ + +/** + * @brief Get Word0 of the unique device identifier (UID based on 96 bits) + * @retval UID[31:0]: X and Y coordinates on the wafer expressed in BCD format + */ +__STATIC_INLINE uint32_t LL_GetUID_Word0(void) +{ + return (uint32_t)(READ_REG(*((uint32_t *)UID_BASE_ADDRESS))); +} + +/** + * @brief Get Word1 of the unique device identifier (UID based on 96 bits) + * @retval UID[63:32]: Wafer number (UID[39:32]) & LOT_NUM[23:0] (UID[63:40]) + */ +__STATIC_INLINE uint32_t LL_GetUID_Word1(void) +{ + return (uint32_t)(READ_REG(*((uint32_t *)(UID_BASE_ADDRESS + 4U)))); +} + +/** + * @brief Get Word2 of the unique device identifier (UID based on 96 bits) + * @retval UID[95:64]: Lot number (ASCII encoded) - LOT_NUM[55:24] + */ +__STATIC_INLINE uint32_t LL_GetUID_Word2(void) +{ + return (uint32_t)(READ_REG(*((uint32_t *)(UID_BASE_ADDRESS + 8U)))); +} + +/** + * @brief Get Flash memory size + * @note This bitfield indicates the size of the device Flash memory expressed in + * Kbytes. As an example, 0x040 corresponds to 64 Kbytes. + * @retval FLASH_SIZE[15:0]: Flash memory size + */ +__STATIC_INLINE uint32_t LL_GetFlashSize(void) +{ + return (uint32_t)(READ_REG(*((uint32_t *)FLASHSIZE_BASE_ADDRESS)) & 0xFFFFU); +} + +/** + * @brief Get Package type + * @retval Returned value can be one of the following values: + * @arg @ref LL_UTILS_PACKAGETYPE_LQFP64 + * @arg @ref LL_UTILS_PACKAGETYPE_VFQFPN68 + * @arg @ref LL_UTILS_PACKAGETYPE_LQFP100 + * @arg @ref LL_UTILS_PACKAGETYPE_UFBGA176 + * @arg @ref LL_UTILS_PACKAGETYPE_LQFP144 + * @arg @ref LL_UTILS_PACKAGETYPE_LQFP48 + * @arg @ref LL_UTILS_PACKAGETYPE_UFBGA169 + * @arg @ref LL_UTILS_PACKAGETYPE_LQFP176 + * @arg @ref LL_UTILS_PACKAGETYPE_UFQFPN32 + * @arg @ref LL_UTILS_PACKAGETYPE_LQFP100_SMPS + * @arg @ref LL_UTILS_PACKAGETYPE_UFBGA176_SMPS + * @arg @ref LL_UTILS_PACKAGETYPE_LQFP144_SMPS + * @arg @ref LL_UTILS_PACKAGETYPE_LQFP176_SMPS + * @arg @ref LL_UTILS_PACKAGETYPE_UFBGA169_SMPS + * @arg @ref LL_UTILS_PACKAGETYPE_WLCSP25 + * @arg @ref LL_UTILS_PACKAGETYPE_UFQFPN48 + */ +__STATIC_INLINE uint32_t LL_GetPackageType(void) +{ + return (uint32_t)(READ_REG(*((uint16_t *)PACKAGE_BASE_ADDRESS))); +} + +/** + * @} + */ + +/** @defgroup UTILS_LL_EF_DELAY DELAY + * @{ + */ + +/** + * @brief This function configures the Cortex-M SysTick source of the time base. + * @param HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro) + * @note When a RTOS is used, it is recommended to avoid changing the SysTick + * configuration by calling this function, for a delay use rather osDelay RTOS service. + * @param Ticks Number of ticks + * @retval None + */ +__STATIC_INLINE void LL_InitTick(uint32_t HCLKFrequency, uint32_t Ticks) +{ + /* Configure the SysTick to have interrupt in 1ms time base */ + SysTick->LOAD = (uint32_t)((HCLKFrequency / Ticks) - 1UL); /* set reload register */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable the Systick Timer */ +} + +void LL_Init1msTick(uint32_t HCLKFrequency); +void LL_mDelay(uint32_t Delay); + +/** + * @} + */ + +/** @defgroup UTILS_EF_SYSTEM SYSTEM + * @{ + */ + +void LL_SetSystemCoreClock(uint32_t HCLKFrequency); +ErrorStatus LL_PLL_ConfigSystemClock_CSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, + LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct); +ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, + LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct); +ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, + uint32_t HSEBypass, + LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, + LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct); +ErrorStatus LL_SetFlashLatency(uint32_t HCLK_Frequency); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32H5xx_LL_UTILS_H */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_wwdg.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_wwdg.h new file mode 100644 index 0000000000..68acae2fef --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_ll_wwdg.h @@ -0,0 +1,328 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_wwdg.h + * @author MCD Application Team + * @brief Header file of WWDG LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_LL_WWDG_H +#define STM32H5xx_LL_WWDG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (WWDG) + +/** @defgroup WWDG_LL WWDG + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup WWDG_LL_Exported_Constants WWDG Exported Constants + * @{ + */ + +/** @defgroup WWDG_LL_EC_IT IT Defines + * @brief IT defines which can be used with LL_WWDG_ReadReg and LL_WWDG_WriteReg functions + * @{ + */ +#define LL_WWDG_CFR_EWI WWDG_CFR_EWI +/** + * @} + */ + +/** @defgroup WWDG_LL_EC_PRESCALER PRESCALER + * @{ + */ +#define LL_WWDG_PRESCALER_1 0x00000000u /*!< WWDG counter clock = (PCLK1/4096)/1 */ +#define LL_WWDG_PRESCALER_2 WWDG_CFR_WDGTB_0 /*!< WWDG counter clock = (PCLK1/4096)/2 */ +#define LL_WWDG_PRESCALER_4 WWDG_CFR_WDGTB_1 /*!< WWDG counter clock = (PCLK1/4096)/4 */ +#define LL_WWDG_PRESCALER_8 (WWDG_CFR_WDGTB_0 | WWDG_CFR_WDGTB_1) /*!< WWDG counter clock = (PCLK1/4096)/8 */ +#define LL_WWDG_PRESCALER_16 WWDG_CFR_WDGTB_2 /*!< WWDG counter clock = (PCLK1/4096)/16 */ +#define LL_WWDG_PRESCALER_32 (WWDG_CFR_WDGTB_2 | WWDG_CFR_WDGTB_0) /*!< WWDG counter clock = (PCLK1/4096)/32 */ +#define LL_WWDG_PRESCALER_64 (WWDG_CFR_WDGTB_2 | WWDG_CFR_WDGTB_1) /*!< WWDG counter clock = (PCLK1/4096)/64 */ +#define LL_WWDG_PRESCALER_128 (WWDG_CFR_WDGTB_2 | WWDG_CFR_WDGTB_1 | WWDG_CFR_WDGTB_0) /*!< WWDG counter clock = (PCLK1/4096)/128 */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup WWDG_LL_Exported_Macros WWDG Exported Macros + * @{ + */ +/** @defgroup WWDG_LL_EM_WRITE_READ Common Write and read registers macros + * @{ + */ +/** + * @brief Write a value in WWDG register + * @param __INSTANCE__ WWDG Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_WWDG_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in WWDG register + * @param __INSTANCE__ WWDG Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_WWDG_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup WWDG_LL_Exported_Functions WWDG Exported Functions + * @{ + */ + +/** @defgroup WWDG_LL_EF_Configuration Configuration + * @{ + */ +/** + * @brief Enable Window Watchdog. The watchdog is always disabled after a reset. + * @note It is enabled by setting the WDGA bit in the WWDG_CR register, + * then it cannot be disabled again except by a reset. + * This bit is set by software and only cleared by hardware after a reset. + * When WDGA = 1, the watchdog can generate a reset. + * @rmtoll CR WDGA LL_WWDG_Enable + * @param WWDGx WWDG Instance + * @retval None + */ +__STATIC_INLINE void LL_WWDG_Enable(WWDG_TypeDef *WWDGx) +{ + SET_BIT(WWDGx->CR, WWDG_CR_WDGA); +} + +/** + * @brief Checks if Window Watchdog is enabled + * @rmtoll CR WDGA LL_WWDG_IsEnabled + * @param WWDGx WWDG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_WWDG_IsEnabled(const WWDG_TypeDef *WWDGx) +{ + return ((READ_BIT(WWDGx->CR, WWDG_CR_WDGA) == (WWDG_CR_WDGA)) ? 1UL : 0UL); +} + +/** + * @brief Set the Watchdog counter value to provided value (7-bits T[6:0]) + * @note When writing to the WWDG_CR register, always write 1 in the MSB b6 to avoid generating an immediate reset + * This counter is decremented every (4096 x 2expWDGTB) PCLK cycles + * A reset is produced when it rolls over from 0x40 to 0x3F (bit T6 becomes cleared) + * Setting the counter lower then 0x40 causes an immediate reset (if WWDG enabled) + * @rmtoll CR T LL_WWDG_SetCounter + * @param WWDGx WWDG Instance + * @param Counter 0..0x7F (7 bit counter value) + * @retval None + */ +__STATIC_INLINE void LL_WWDG_SetCounter(WWDG_TypeDef *WWDGx, uint32_t Counter) +{ + MODIFY_REG(WWDGx->CR, WWDG_CR_T, Counter); +} + +/** + * @brief Return current Watchdog Counter Value (7 bits counter value) + * @rmtoll CR T LL_WWDG_GetCounter + * @param WWDGx WWDG Instance + * @retval 7 bit Watchdog Counter value + */ +__STATIC_INLINE uint32_t LL_WWDG_GetCounter(const WWDG_TypeDef *WWDGx) +{ + return (READ_BIT(WWDGx->CR, WWDG_CR_T)); +} + +/** + * @brief Set the time base of the prescaler (WDGTB). + * @note Prescaler is used to apply ratio on PCLK clock, so that Watchdog counter + * is decremented every (4096 x 2expWDGTB) PCLK cycles + * @rmtoll CFR WDGTB LL_WWDG_SetPrescaler + * @param WWDGx WWDG Instance + * @param Prescaler This parameter can be one of the following values: + * @arg @ref LL_WWDG_PRESCALER_1 + * @arg @ref LL_WWDG_PRESCALER_2 + * @arg @ref LL_WWDG_PRESCALER_4 + * @arg @ref LL_WWDG_PRESCALER_8 + * @arg @ref LL_WWDG_PRESCALER_16 + * @arg @ref LL_WWDG_PRESCALER_32 + * @arg @ref LL_WWDG_PRESCALER_64 + * @arg @ref LL_WWDG_PRESCALER_128 + * @retval None + */ +__STATIC_INLINE void LL_WWDG_SetPrescaler(WWDG_TypeDef *WWDGx, uint32_t Prescaler) +{ + MODIFY_REG(WWDGx->CFR, WWDG_CFR_WDGTB, Prescaler); +} + +/** + * @brief Return current Watchdog Prescaler Value + * @rmtoll CFR WDGTB LL_WWDG_GetPrescaler + * @param WWDGx WWDG Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_WWDG_PRESCALER_1 + * @arg @ref LL_WWDG_PRESCALER_2 + * @arg @ref LL_WWDG_PRESCALER_4 + * @arg @ref LL_WWDG_PRESCALER_8 + * @arg @ref LL_WWDG_PRESCALER_16 + * @arg @ref LL_WWDG_PRESCALER_32 + * @arg @ref LL_WWDG_PRESCALER_64 + * @arg @ref LL_WWDG_PRESCALER_128 + */ +__STATIC_INLINE uint32_t LL_WWDG_GetPrescaler(const WWDG_TypeDef *WWDGx) +{ + return (READ_BIT(WWDGx->CFR, WWDG_CFR_WDGTB)); +} + +/** + * @brief Set the Watchdog Window value to be compared to the downcounter (7-bits W[6:0]). + * @note This window value defines when write in the WWDG_CR register + * to program Watchdog counter is allowed. + * Watchdog counter value update must occur only when the counter value + * is lower than the Watchdog window register value. + * Otherwise, a MCU reset is generated if the 7-bit Watchdog counter value + * (in the control register) is refreshed before the downcounter has reached + * the watchdog window register value. + * Physically is possible to set the Window lower then 0x40 but it is not recommended. + * To generate an immediate reset, it is possible to set the Counter lower than 0x40. + * @rmtoll CFR W LL_WWDG_SetWindow + * @param WWDGx WWDG Instance + * @param Window 0x00..0x7F (7 bit Window value) + * @retval None + */ +__STATIC_INLINE void LL_WWDG_SetWindow(WWDG_TypeDef *WWDGx, uint32_t Window) +{ + MODIFY_REG(WWDGx->CFR, WWDG_CFR_W, Window); +} + +/** + * @brief Return current Watchdog Window Value (7 bits value) + * @rmtoll CFR W LL_WWDG_GetWindow + * @param WWDGx WWDG Instance + * @retval 7 bit Watchdog Window value + */ +__STATIC_INLINE uint32_t LL_WWDG_GetWindow(const WWDG_TypeDef *WWDGx) +{ + return (READ_BIT(WWDGx->CFR, WWDG_CFR_W)); +} + +/** + * @} + */ + +/** @defgroup WWDG_LL_EF_FLAG_Management FLAG_Management + * @{ + */ +/** + * @brief Indicates if the WWDG Early Wakeup Interrupt Flag is set or not. + * @note This bit is set by hardware when the counter has reached the value 0x40. + * It must be cleared by software by writing 0. + * A write of 1 has no effect. This bit is also set if the interrupt is not enabled. + * @rmtoll SR EWIF LL_WWDG_IsActiveFlag_EWKUP + * @param WWDGx WWDG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_WWDG_IsActiveFlag_EWKUP(const WWDG_TypeDef *WWDGx) +{ + return ((READ_BIT(WWDGx->SR, WWDG_SR_EWIF) == (WWDG_SR_EWIF)) ? 1UL : 0UL); +} + +/** + * @brief Clear WWDG Early Wakeup Interrupt Flag (EWIF) + * @rmtoll SR EWIF LL_WWDG_ClearFlag_EWKUP + * @param WWDGx WWDG Instance + * @retval None + */ +__STATIC_INLINE void LL_WWDG_ClearFlag_EWKUP(WWDG_TypeDef *WWDGx) +{ + WRITE_REG(WWDGx->SR, ~WWDG_SR_EWIF); +} + +/** + * @} + */ + +/** @defgroup WWDG_LL_EF_IT_Management IT_Management + * @{ + */ +/** + * @brief Enable the Early Wakeup Interrupt. + * @note When set, an interrupt occurs whenever the counter reaches value 0x40. + * This interrupt is only cleared by hardware after a reset + * @rmtoll CFR EWI LL_WWDG_EnableIT_EWKUP + * @param WWDGx WWDG Instance + * @retval None + */ +__STATIC_INLINE void LL_WWDG_EnableIT_EWKUP(WWDG_TypeDef *WWDGx) +{ + SET_BIT(WWDGx->CFR, WWDG_CFR_EWI); +} + +/** + * @brief Check if Early Wakeup Interrupt is enabled + * @rmtoll CFR EWI LL_WWDG_IsEnabledIT_EWKUP + * @param WWDGx WWDG Instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_WWDG_IsEnabledIT_EWKUP(const WWDG_TypeDef *WWDGx) +{ + return ((READ_BIT(WWDGx->CFR, WWDG_CFR_EWI) == (WWDG_CFR_EWI)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* WWDG */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_LL_WWDG_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_util_i3c.h b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_util_i3c.h new file mode 100644 index 0000000000..23fd087b0d --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Inc/stm32h5xx_util_i3c.h @@ -0,0 +1,133 @@ +/** + ********************************************************************************************************************** + * @file stm32h5xx_util_i3c.h + * @author MCD Application Team + * @brief Header of stm32h5xx_util_i3c.c + ********************************************************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ********************************************************************************************************************** + */ + +/* Define to prevent recursive inclusion -----------------------------------------------------------------------------*/ +#ifndef STM32H5xx_UTIL_I3C_H +#define STM32H5xx_UTIL_I3C_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ----------------------------------------------------------------------------------------------------------*/ +#if defined (USE_HAL_DRIVER) +#include "stm32h5xx_hal.h" +#else +#include "stm32h5xx_ll_i3c.h" +#endif /* USE_HAL_DRIVER */ + +/** @addtogroup STM32H5xx_UTIL_Driver + * @{ + */ + +/** @addtogroup I3C + * @{ + */ +/* Exported types ----------------------------------------------------------------------------------------------------*/ +/** @defgroup I3C_Exported_Types I3C Exported Types + * @{ + */ + +/** @defgroup I3C_Controller_Timing_Structure_definition I3C Controller Timing Structure definition + * @brief I3C Controller Timing Structure definition + * @{ + */ +typedef struct +{ + uint32_t clockSrcFreq; /*!< Specifies the I3C clock source (in Hz). */ + + uint32_t i3cPPFreq; /*!< Specifies the I3C required bus clock for Push-Pull phase (in Hz). */ + + uint32_t i2cODFreq; /*!< Specifies I2C required bus clock for Open-Drain phase (in Hz). */ + + uint32_t dutyCycle; /*!< Specifies the I3C duty cycle for Pure I3C bus or I2C duty cycle for Mixed bus in percent + This parameter must be a value less than or equal to 50 percent. */ + + uint32_t busType; /*!< Specifies the Bus configuration type. + This parameter must be a value of @ref I3C_UTIL_EC_BUS_TYPE */ +} I3C_CtrlTimingTypeDef; +/** + * @} + */ + +/** @defgroup I3C_Target_Timing_Structure_definition I3C Target Timing Structure definition + * @brief I3C Target Timing Structure definition + * @{ + */ +typedef struct +{ + uint32_t clockSrcFreq; /*!< Specifies the I3C clock source (in Hz). */ +} I3C_TgtTimingTypeDef; +/** + * @} + */ + +/** + * @} + */ + +/* Exported define ---------------------------------------------------------------------------------------------------*/ +/** @defgroup I3C_UTIL_Exported_Define I3C Utility Exported Define + * @{ + */ + +/** @defgroup I3C_UTIL_EC_BUS_TYPE I3C Utility Bus Type + * @brief Bus type defines which can be used with I3C_CtrlTimingComputation function + * @{ + */ +#define I3C_PURE_I3C_BUS 0U /*!< Pure I3C bus, no I2C */ +#define I3C_MIXED_BUS 1U /*!< Mixed bus I3C and I2C */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions ------------------------------------------------------------------------------------------------*/ +/** @addtogroup I3C_UTIL_Exported_Functions + * @{ + */ +/** @addtogroup I3C_UTIL_EF_Computation + * @{ + */ +ErrorStatus I3C_CtrlTimingComputation(const I3C_CtrlTimingTypeDef *pInputTiming, + LL_I3C_CtrlBusConfTypeDef *pOutputConfig); +ErrorStatus I3C_TgtTimingComputation(const I3C_TgtTimingTypeDef *pInputTiming, + LL_I3C_TgtBusConfTypeDef *pOutputConfig); +/** + * @} + */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32H5xx_UTIL_I3C_H */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/LICENSE.txt b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/LICENSE.txt new file mode 100644 index 0000000000..3edc4d1464 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/LICENSE.txt @@ -0,0 +1,6 @@ +This software component is provided to you as part of a software package and +applicable license terms are in the Package_license file. If you received this +software component outside of a package or without applicable license terms, +the terms of the BSD-3-Clause license shall apply. +You may obtain a copy of the BSD-3-Clause at: +https://opensource.org/licenses/BSD-3-Clause diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal.c new file mode 100644 index 0000000000..db2ca5bdb9 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal.c @@ -0,0 +1,1298 @@ +/** + ********************************************************************************************************************** + * @file stm32h5xx_hal.c + * @author MCD Application Team + * @brief HAL module driver. + * This is the common part of the HAL initialization + * + @verbatim + ====================================================================================================================== + ##### How to use this driver ##### + ====================================================================================================================== + [..] + The common HAL driver contains a set of generic and common APIs that can be + used by the PPP peripheral drivers and the user to start using the HAL. + [..] + The HAL contains two APIs' categories: + (+) Common HAL APIs + (+) Services HAL APIs + + @endverbatim + ********************************************************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ********************************************************************************************************************** + */ + +/* Includes ----------------------------------------------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup HAL HAL + * @brief HAL module driver + * @{ + */ + +#ifdef HAL_MODULE_ENABLED + +/* Private typedef ---------------------------------------------------------------------------------------------------*/ +/* Private define ----------------------------------------------------------------------------------------------------*/ +/** + * @brief STM32H5xx HAL Driver version number 1.1.0 + */ +#define __STM32H5XX_HAL_VERSION_MAIN (0x01U) /*!< [31:24] main version */ +#define __STM32H5XX_HAL_VERSION_SUB1 (0x01U) /*!< [23:16] sub1 version */ +#define __STM32H5XX_HAL_VERSION_SUB2 (0x00U) /*!< [15:8] sub2 version */ +#define __STM32H5XX_HAL_VERSION_RC (0x00U) /*!< [7:0] release candidate */ +#define __STM32H5XX_HAL_VERSION ((__STM32H5XX_HAL_VERSION_MAIN << 24U)\ + |(__STM32H5XX_HAL_VERSION_SUB1 << 16U)\ + |(__STM32H5XX_HAL_VERSION_SUB2 << 8U )\ + |(__STM32H5XX_HAL_VERSION_RC)) + +#if defined(VREFBUF) +#define VREFBUF_TIMEOUT_VALUE 10U /* 10 ms */ +#endif /* VREFBUF */ + +/* Value used to increment hide protection level */ +#define SBS_HDPL_INCREMENT_VALUE (uint8_t)0x6A + +/* Value used to lock/unlock debug functionalities */ +#define SBS_DEBUG_LOCK_VALUE (uint8_t)0xC3 +#define SBS_DEBUG_UNLOCK_VALUE (uint8_t)0xB4 + +/* Private macro -----------------------------------------------------------------------------------------------------*/ +/* Private variables -------------------------------------------------------------------------------------------------*/ +/* Exported variables ------------------------------------------------------------------------------------------------*/ + +/** @defgroup HAL_Exported_Variables HAL Exported Variables + * @{ + */ +__IO uint32_t uwTick; +uint32_t uwTickPrio = (1UL << __NVIC_PRIO_BITS); /* Invalid PRIO */ +HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT; /* 1KHz */ +/** + * @} + */ + +/* Private function prototypes ---------------------------------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------------------------------------------------*/ + +/** @defgroup HAL_Exported_Functions HAL Exported Functions + * @{ + */ + +/** @defgroup HAL_Exported_Functions_Group1 Initialization and de-initialization Functions + * @brief Initialization and de-initialization functions + * +@verbatim + ======================================================================================================================= + ##### Initialization and de-initialization functions ##### + ======================================================================================================================= + [..] This section provides functions allowing to: + (+) Initializes the Flash interface the NVIC allocation and initial clock + configuration. It initializes the systick also when timeout is needed + and the backup domain when enabled. + (+) De-Initializes common part of the HAL. + (+) Configure The time base source to have 1ms time base with a dedicated + Tick interrupt priority. + (++) SysTick timer is used by default as source of time base, but user + can eventually implement his proper time base source (a general purpose + timer for example or other time source), keeping in mind that Time base + duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and + handled in milliseconds basis. + (++) Time base configuration function (HAL_InitTick ()) is called automatically + at the beginning of the program after reset by HAL_Init() or at any time + when clock is configured, by HAL_RCC_ClockConfig(). + (++) Source of time base is configured to generate interrupts at regular + time intervals. Care must be taken if HAL_Delay() is called from a + peripheral ISR process, the Tick interrupt line must have higher priority + (numerically lower) than the peripheral interrupt. Otherwise the caller + ISR process will be blocked. + (++) functions affecting time base configurations are declared as __weak + to make override possible in case of other implementations in user file. +@endverbatim + * @{ + */ + +/** + * @brief Configure the Flash prefetch, the time base source, NVIC and any required global low + * level hardware by calling the HAL_MspInit() callback function to be optionally defined + * in user file stm32h5xx_hal_msp.c. + * + * @note HAL_Init() function is called at the beginning of program after reset and before + * the clock configuration. + * + * @note In the default implementation the System Timer (Systick) is used as source of time base. + * The Systick configuration is based on HSI clock, as HSI is the clock + * used after a system Reset and the NVIC configuration is set to Priority group 4. + * Once done, time base tick starts incrementing: the tick variable counter is incremented + * each 1ms in the SysTick_Handler() interrupt handler. + * + * @retval HAL status + */ +HAL_StatusTypeDef HAL_Init(void) +{ + /* Configure Flash prefetch */ +#if (PREFETCH_ENABLE != 0U) + __HAL_FLASH_PREFETCH_BUFFER_ENABLE(); +#endif /* PREFETCH_ENABLE */ + + /* Set Interrupt Group Priority */ + HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); + + /* Update the SystemCoreClock global variable */ + SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR2 & RCC_CFGR2_HPRE) >> RCC_CFGR2_HPRE_Pos]; + + /* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */ + if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK) + { + return HAL_ERROR; + } + + /* Init the low level hardware */ + HAL_MspInit(); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief This function de-Initializes common part of the HAL and stops the systick. + * This function is optional. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DeInit(void) +{ + /* Reset of all peripherals */ + __HAL_RCC_APB1_FORCE_RESET(); + __HAL_RCC_APB1_RELEASE_RESET(); + + __HAL_RCC_APB2_FORCE_RESET(); + __HAL_RCC_APB2_RELEASE_RESET(); + + __HAL_RCC_APB3_FORCE_RESET(); + __HAL_RCC_APB3_RELEASE_RESET(); + + __HAL_RCC_AHB1_FORCE_RESET(); + __HAL_RCC_AHB1_RELEASE_RESET(); + + __HAL_RCC_AHB2_FORCE_RESET(); + __HAL_RCC_AHB2_RELEASE_RESET(); + +#if defined(AHB4PERIPH_BASE) + __HAL_RCC_AHB4_FORCE_RESET(); + __HAL_RCC_AHB4_RELEASE_RESET(); +#endif /* AHB4PERIPH_BASE */ + + /* De-Init the low level hardware */ + HAL_MspDeInit(); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the MSP. + * @retval None + */ +__weak void HAL_MspInit(void) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes the MSP. + * @retval None + */ +__weak void HAL_MspDeInit(void) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief This function configures the source of the time base. + * The time source is configured to have 1ms time base with a dedicated + * Tick interrupt priority. + * @note This function is called automatically at the beginning of program after + * reset by HAL_Init() or at any time when clock is reconfigured by HAL_RCC_ClockConfig(). + * @note In the default implementation, SysTick timer is the source of time base. + * It is used to generate interrupts at regular time intervals. + * Care must be taken if HAL_Delay() is called from a peripheral ISR process, + * The SysTick interrupt must have higher priority (numerically lower) + * than the peripheral interrupt. Otherwise the caller ISR process will be blocked. + * The function is declared as __weak to be overwritten in case of other + * implementation in user file. + * @param TickPriority: Tick interrupt priority. + * @retval HAL status + */ +__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) +{ + /* Check uwTickFreq for MisraC 2012 (even if uwTickFreq is a enum type that don't take the value zero)*/ + if ((uint32_t)uwTickFreq == 0UL) + { + return HAL_ERROR; + } + + /* Configure the SysTick to have interrupt in 1ms time basis*/ + if (HAL_SYSTICK_Config(SystemCoreClock / (1000UL / (uint32_t)uwTickFreq)) > 0U) + { + return HAL_ERROR; + } + + /* Configure the SysTick IRQ priority */ + if (TickPriority < (1UL << __NVIC_PRIO_BITS)) + { + HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U); + uwTickPrio = TickPriority; + } + else + { + return HAL_ERROR; + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup HAL_Group2 HAL Control functions + * @brief HAL Control functions + * +@verbatim + ======================================================================================================================= + ##### HAL Control functions ##### + ======================================================================================================================= + [..] This section provides functions allowing to: + (+) Provide a tick value in millisecond + (+) Provide a blocking delay in millisecond + (+) Suspend the time base source interrupt + (+) Resume the time base source interrupt + (+) Get the HAL API driver version + (+) Get the device identifier + (+) Get the device revision identifier + +@endverbatim + * @{ + */ + +/** + * @brief This function is called to increment a global variable "uwTick" + * used as application time base. + * @note In the default implementation, this variable is incremented each 1ms + * in Systick ISR. + * @note This function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @retval None + */ +__weak void HAL_IncTick(void) +{ + uwTick += (uint32_t)uwTickFreq; +} + +/** + * @brief Provides a tick value in millisecond. + * @note This function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @retval tick value + */ +__weak uint32_t HAL_GetTick(void) +{ + return uwTick; +} + +/** + * @brief This function returns a tick priority. + * @retval tick priority + */ +uint32_t HAL_GetTickPrio(void) +{ + return uwTickPrio; +} + +/** + * @brief Set new tick Freq. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq) +{ + HAL_StatusTypeDef status = HAL_OK; + HAL_TickFreqTypeDef prevTickFreq; + + assert_param(IS_TICKFREQ(Freq)); + + if (uwTickFreq != Freq) + { + + /* Back up uwTickFreq frequency */ + prevTickFreq = uwTickFreq; + + /* Update uwTickFreq global variable used by HAL_InitTick() */ + uwTickFreq = Freq; + + /* Apply the new tick Freq */ + status = HAL_InitTick(uwTickPrio); + if (status != HAL_OK) + { + /* Restore previous tick frequency */ + uwTickFreq = prevTickFreq; + } + } + + return status; +} + +/** + * @brief Return tick frequency. + * @retval Tick frequency. + * Value of @ref HAL_TickFreqTypeDef. + */ +HAL_TickFreqTypeDef HAL_GetTickFreq(void) +{ + return uwTickFreq; +} + +/** + * @brief This function provides minimum delay (in milliseconds) based + * on variable incremented. + * @note In the default implementation , SysTick timer is the source of time base. + * It is used to generate interrupts at regular time intervals where uwTick + * is incremented. + * @note This function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @param Delay specifies the delay time length, in milliseconds. + * @retval None + */ +__weak void HAL_Delay(uint32_t Delay) +{ + uint32_t tickstart = HAL_GetTick(); + uint32_t wait = Delay; + + /* Add a freq to guarantee minimum wait */ + if (wait < HAL_MAX_DELAY) + { + wait += (uint32_t)(uwTickFreq); + } + + while ((HAL_GetTick() - tickstart) < wait) + { + } +} + +/** + * @brief Suspend Tick increment. + * @note In the default implementation , SysTick timer is the source of time base. It is + * used to generate interrupts at regular time intervals. Once HAL_SuspendTick() + * is called, the SysTick interrupt will be disabled and so Tick increment + * is suspended. + * @note This function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @retval None + */ +__weak void HAL_SuspendTick(void) +{ + /* Disable SysTick Interrupt */ + SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk; +} + +/** + * @brief Resume Tick increment. + * @note In the default implementation , SysTick timer is the source of time base. It is + * used to generate interrupts at regular time intervals. Once HAL_ResumeTick() + * is called, the SysTick interrupt will be enabled and so Tick increment + * is resumed. + * @note This function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @retval None + */ +__weak void HAL_ResumeTick(void) +{ + /* Enable SysTick Interrupt */ + SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; +} + +/** + * @brief Returns the HAL revision + * @retval version : 0xXYZR (8bits for each decimal, R for RC) + */ +uint32_t HAL_GetHalVersion(void) +{ + return __STM32H5XX_HAL_VERSION; +} + +/** + * @brief Returns the device revision identifier. + * @retval Device revision identifier + */ +uint32_t HAL_GetREVID(void) +{ + return ((DBGMCU->IDCODE & DBGMCU_IDCODE_REV_ID) >> 16); +} + +/** + * @brief Returns the device identifier. + * @retval Device identifier + */ +uint32_t HAL_GetDEVID(void) +{ + return (DBGMCU->IDCODE & DBGMCU_IDCODE_DEV_ID); +} + +/** + * @brief Return the first word of the unique device identifier (UID based on 96 bits) + * @retval Device identifier + */ +uint32_t HAL_GetUIDw0(void) +{ + return (READ_REG(*((uint32_t *)UID_BASE))); +} + +/** + * @brief Return the second word of the unique device identifier (UID based on 96 bits) + * @retval Device identifier + */ +uint32_t HAL_GetUIDw1(void) +{ + return (READ_REG(*((uint32_t *)(UID_BASE + 4U)))); +} + +/** + * @brief Return the third word of the unique device identifier (UID based on 96 bits) + * @retval Device identifier + */ +uint32_t HAL_GetUIDw2(void) +{ + return (READ_REG(*((uint32_t *)(UID_BASE + 8U)))); +} + +/** + * @} + */ + + +/** @defgroup HAL_Exported_Functions_Group3 HAL Debug functions + * @brief HAL Debug functions + * +@verbatim + ======================================================================================================================= + ##### HAL Debug functions ##### + ======================================================================================================================= + [..] This section provides functions allowing to: + (+) Enable/Disable Debug module during STOP mode + (+) Enable/Disable Debug module during STANDBY mode + +@endverbatim + * @{ + */ + +/** + * @brief Enable the Debug Module during STOP mode. + * @retval None + */ +void HAL_DBGMCU_EnableDBGStopMode(void) +{ + SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP); +} + +/** + * @brief Disable the Debug Module during STOP mode. + * @retval None + */ +void HAL_DBGMCU_DisableDBGStopMode(void) +{ + CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP); +} + +/** + * @brief Enable the Debug Module during STANDBY mode. + * @retval None + */ +void HAL_DBGMCU_EnableDBGStandbyMode(void) +{ + SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY); +} + +/** + * @brief Disable the Debug Module during STANDBY mode. + * @retval None + */ +void HAL_DBGMCU_DisableDBGStandbyMode(void) +{ + CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY); +} + +/** + * @} + */ + +/** @defgroup HAL_Exported_Functions_Group4 HAL VREFBUF Control functions + * @brief HAL VREFBUF Control functions + * +@verbatim + ======================================================================================================================= + ##### HAL VREFBUF Control functions ##### + ======================================================================================================================= + [..] This section provides functions allowing to: + (+) Configure the Voltage reference buffer + (+) Enable/Disable the Voltage reference buffer + +@endverbatim + * @{ + */ + +#if defined(VREFBUF) +/** + * @brief Configure the internal voltage reference buffer voltage scale. + * @param VoltageScaling: specifies the output voltage to achieve + * This parameter can be one of the following values: + * @arg VREFBUF_VOLTAGE_SCALE0: VREF_OUT1 around 2.5 V. + * This requires VDDA equal to or higher than 2.8 V. + * @arg VREFBUF_VOLTAGE_SCALE1: VREF_OUT2 around 2.048 V. + * This requires VDDA equal to or higher than 2.4 V. + * @arg VREFBUF_VOLTAGE_SCALE2: VREF_OUT3 around 1.8 V. + * This requires VDDA equal to or higher than 2.1 V. + * @arg VREFBUF_VOLTAGE_SCALE3: VREF_OUT4 around 1.5 V. + * This requires VDDA equal to or higher than 1.8 V. + * @retval None + */ +void HAL_VREFBUF_VoltageScalingConfig(uint32_t VoltageScaling) +{ + /* Check the parameters */ + assert_param(IS_VREFBUF_VOLTAGE_SCALE(VoltageScaling)); + + MODIFY_REG(VREFBUF->CSR, VREFBUF_CSR_VRS, VoltageScaling); +} + +/** + * @brief Configure the internal voltage reference buffer high impedance mode. + * @param Mode: specifies the high impedance mode + * This parameter can be one of the following values: + * @arg VREFBUF_HIGH_IMPEDANCE_DISABLE: VREF+ pin is internally connect to VREFINT output. + * @arg VREFBUF_HIGH_IMPEDANCE_ENABLE: VREF+ pin is high impedance. + * @retval None + */ +void HAL_VREFBUF_HighImpedanceConfig(uint32_t Mode) +{ + /* Check the parameters */ + assert_param(IS_VREFBUF_HIGH_IMPEDANCE(Mode)); + + MODIFY_REG(VREFBUF->CSR, VREFBUF_CSR_HIZ, Mode); +} + +/** + * @brief Tune the Internal Voltage Reference buffer (VREFBUF). + * @retval None + */ +void HAL_VREFBUF_TrimmingConfig(uint32_t TrimmingValue) +{ + /* Check the parameters */ + assert_param(IS_VREFBUF_TRIMMING(TrimmingValue)); + + MODIFY_REG(VREFBUF->CCR, VREFBUF_CCR_TRIM, TrimmingValue); +} + +/** + * @brief Enable the Internal Voltage Reference buffer (VREFBUF). + * @retval HAL_OK/HAL_TIMEOUT + */ +HAL_StatusTypeDef HAL_EnableVREFBUF(void) +{ + uint32_t tickstart; + + SET_BIT(VREFBUF->CSR, VREFBUF_CSR_ENVR); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait for VRR bit */ + while (READ_BIT(VREFBUF->CSR, VREFBUF_CSR_VRR) == 0UL) + { + if ((HAL_GetTick() - tickstart) > VREFBUF_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + return HAL_OK; +} + +/** + * @brief Disable the Internal Voltage Reference buffer (VREFBUF). + * + * @retval None + */ +void HAL_DisableVREFBUF(void) +{ + CLEAR_BIT(VREFBUF->CSR, VREFBUF_CSR_ENVR); +} +#endif /* VREFBUF */ + +/** + * @} + */ + +/** @defgroup HAL_Exported_Functions_Group5 HAL SBS configuration functions + * @brief HAL SBS configuration functions + * +@verbatim + ======================================================================================================================= + ##### HAL SBS configuration functions ##### + ======================================================================================================================= + [..] This section provides functions allowing to: + (+) Select the Ethernet PHY Interface + (+) Enable/Disable the VDD I/Os Compensation Cell + (+) Code selection/configuration for the VDD I/O Compensation cell + (+) Get ready flag status of VDD I/Os Compensation cell + (+) Get PMOS/NMOS compensation value of the I/Os supplied by VDD + (+) Enable/Disable the NMI in case of double ECC error in FLASH Interface + +@endverbatim + * @{ + */ + +#if defined(SBS_PMCR_ETH_SEL_PHY) +/** + * @brief Ethernet PHY Interface Selection either MII or RMII + * @param SBS_ETHInterface: Selects the Ethernet PHY interface + * This parameter can be one of the following values: + * @arg SBS_ETH_MII : Select the Media Independent Interface + * @arg SBS_ETH_RMII: Select the Reduced Media Independent Interface + * @retval None + */ +void HAL_SBS_ETHInterfaceSelect(uint32_t SBS_ETHInterface) +{ + /* Check the parameter */ + assert_param(IS_SBS_ETHERNET_CONFIG(SBS_ETHInterface)); + + MODIFY_REG(SBS->PMCR, SBS_PMCR_ETH_SEL_PHY, (uint32_t)(SBS_ETHInterface)); +} +#endif /* SBS_PMCR_ETH_SEL_PHY */ + +/** + * @brief Enables the VDD I/Os Compensation Cell. + * @note The I/O compensation cell can be used only when the device supply + * voltage ranges from 2.4 to 3.6 V. + * @retval None + */ +void HAL_SBS_EnableVddIO1CompensationCell(void) +{ + SET_BIT(SBS->CCCSR, SBS_CCCSR_EN1) ; +} + +/** + * @brief Power-down the VDD I/Os Compensation Cell. + * @note The I/O compensation cell can be used only when the device supply + * voltage ranges from 2.4 to 3.6 V. + * @retval None + */ +void HAL_SBS_DisableVddIO1CompensationCell(void) +{ + CLEAR_BIT(SBS->CCCSR, SBS_CCCSR_EN1); +} + +/** + * @brief Enables the VDDIO2 I/Os Compensation Cell. + * @note The I/O compensation cell can be used only when the device supply + * voltage ranges from 2.4 to 3.6 V. + * @retval None + */ +void HAL_SBS_EnableVddIO2CompensationCell(void) +{ + SET_BIT(SBS->CCCSR, SBS_CCCSR_EN2) ; +} + +/** + * @brief Power-down the VDDIO2 I/Os Compensation Cell. + * @note The I/O compensation cell can be used only when the device supply + * voltage ranges from 2.4 to 3.6 V. + * @retval None + */ +void HAL_SBS_DisableVddIO2CompensationCell(void) +{ + CLEAR_BIT(SBS->CCCSR, SBS_CCCSR_EN2); +} + +/** + * @brief Code selection for the VDD I/O Compensation cell + * @param SBS_CompCode: Selects the code to be applied for the I/O compensation cell + * This parameter can be one of the following values: + * @arg SBS_VDD_CELL_CODE : Select Code from the cell (available in the SBS_CCVALR) + * @arg SBS_VDD_REGISTER_CODE: Select Code from the SBS compensation cell code register (SBS_CCSWCR) + * @retval None + */ +void HAL_SBS_VDDCompensationCodeSelect(uint32_t SBS_CompCode) +{ + /* Check the parameter */ + assert_param(IS_SBS_VDD_CODE_SELECT(SBS_CompCode)); + MODIFY_REG(SBS->CCCSR, SBS_CCCSR_CS1, (uint32_t)(SBS_CompCode)); +} + +/** + * @brief Code selection for the VDDIO I/O Compensation cell + * @param SBS_CompCode: Selects the code to be applied for the I/O compensation cell + * This parameter can be one of the following values: + * @arg SBS_VDDIO_CELL_CODE : Select Code from the cell (available in the SBS_CCVALR) + * @arg SBS_VDDIO_REGISTER_CODE: Select Code from the SBS compensation cell code register (SBS_CCSWCR) + * @retval None + */ +void HAL_SBS_VDDIOCompensationCodeSelect(uint32_t SBS_CompCode) +{ + /* Check the parameter */ + assert_param(IS_SBS_VDDIO_CODE_SELECT(SBS_CompCode)); + MODIFY_REG(SBS->CCCSR, SBS_CCCSR_CS2, (uint32_t)(SBS_CompCode)); +} + +/** + * @brief VDDIO1 I/O Compensation cell get ready flag status + * @retval State of bit (1 or 0). + */ +uint32_t HAL_SBS_GetVddIO1CompensationCellReadyFlag(void) +{ + return ((READ_BIT(SBS->CCCSR, SBS_CCCSR_RDY1) == SBS_CCCSR_RDY1) ? 1UL : 0UL); +} + +/** + * @brief VDDIO2 I/O Compensation cell get ready flag status + * @retval State of bit (1 or 0). + */ +uint32_t HAL_SBS_GetVddIO2CompensationCellReadyFlag(void) +{ + return ((READ_BIT(SBS->CCCSR, SBS_CCCSR_RDY2) == SBS_CCCSR_RDY2) ? 1UL : 0UL); +} + +/** + * @brief Code configuration for the VDD I/O Compensation cell + * @param SBS_PMOSCode: PMOS compensation code + * This code is applied to the VDD I/O compensation cell when the CS1 bit of the + * SBS_CCSR is set + * @param SBS_NMOSCode: NMOS compensation code + * This code is applied to the VDD I/O compensation cell when the CS1 bit of the + * SBS_CCSR is set + * @retval None + */ +void HAL_SBS_VDDCompensationCodeConfig(uint32_t SBS_PMOSCode, uint32_t SBS_NMOSCode) +{ + /* Check the parameter */ + assert_param(IS_SBS_CODE_CONFIG(SBS_PMOSCode)); + assert_param(IS_SBS_CODE_CONFIG(SBS_NMOSCode)); + MODIFY_REG(SBS->CCSWCR, SBS_CCSWCR_SW_ANSRC1 | SBS_CCSWCR_SW_APSRC1, (((uint32_t)(SBS_PMOSCode) << 4) | \ + (uint32_t)(SBS_NMOSCode))); +} + +/** + * @brief Code configuration for the VDDIO I/O Compensation cell + * @param SBS_PMOSCode: PMOS compensation code + * This code is applied to the VDDIO I/O compensation cell when the CS2 bit of the + * SBS_CCSR is set + * @param SBS_NMOSCode: NMOS compensation code + * This code is applied to the VDDIO I/O compensation cell when the CS2 bit of the + * SBS_CCSR is set + * @retval None + */ +void HAL_SBS_VDDIOCompensationCodeConfig(uint32_t SBS_PMOSCode, uint32_t SBS_NMOSCode) +{ + /* Check the parameter */ + assert_param(IS_SBS_CODE_CONFIG(SBS_PMOSCode)); + assert_param(IS_SBS_CODE_CONFIG(SBS_NMOSCode)); + MODIFY_REG(SBS->CCSWCR, SBS_CCSWCR_SW_ANSRC2 | SBS_CCSWCR_SW_APSRC2, (((uint32_t)(SBS_PMOSCode) << 12) | \ + ((uint32_t)(SBS_NMOSCode) << 8))); +} + +/** + * @brief Get NMOS compensation value of the I/Os supplied by VDD + * @retval None + */ +uint32_t HAL_SBS_GetNMOSVddCompensationValue(void) +{ + return (uint32_t)(READ_BIT(SBS->CCVALR, SBS_CCVALR_ANSRC1)); +} + +/** + * @brief Get PMOS compensation value of the I/Os supplied by VDD + * @retval None + */ +uint32_t HAL_SBS_GetPMOSVddCompensationValue(void) +{ + return (uint32_t)(READ_BIT(SBS->CCVALR, SBS_CCVALR_APSRC1) >> SBS_CCVALR_APSRC1_Pos); +} + +/** + * @brief Get NMOS compensation value of the I/Os supplied by VDDIO2 + * @retval None + */ +uint32_t HAL_SBS_GetNMOSVddIO2CompensationValue(void) +{ + return (uint32_t)(READ_BIT(SBS->CCVALR, SBS_CCVALR_ANSRC2) >> SBS_CCVALR_ANSRC2_Pos); +} + + +/** + * @brief Get PMOS compensation value of the I/Os supplied by VDDIO2 + * @retval None + */ +uint32_t HAL_SBS_GetPMOSVddIO2CompensationValue(void) +{ + return (uint32_t)(READ_BIT(SBS->CCVALR, SBS_CCVALR_APSRC2) >> SBS_CCVALR_APSRC2_Pos); +} + +/** + * @brief Disable the NMI in case of double ECC error in FLASH Interface. + * + * @retval None + */ +void HAL_SBS_FLASH_DisableECCNMI(void) +{ + SET_BIT(SBS->ECCNMIR, SBS_ECCNMIR_ECCNMI_MASK_EN); +} + +/** + * @brief Enable the NMI in case of double ECC error in FLASH Interface. + * + * @retval None + */ +void HAL_SBS_FLASH_EnableECCNMI(void) +{ + CLEAR_BIT(SBS->ECCNMIR, SBS_ECCNMIR_ECCNMI_MASK_EN); +} + +/** + * @brief Check if the NMI is Enabled in case of double ECC error in FLASH Interface. + * + * @retval State of bit (1 or 0). + */ +uint32_t HAL_SBS_FLASH_ECCNMI_IsDisabled(void) +{ + return ((READ_BIT(SBS->ECCNMIR, SBS_ECCNMIR_ECCNMI_MASK_EN) == SBS_ECCNMIR_ECCNMI_MASK_EN) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup HAL_Exported_Functions_Group6 HAL SBS Boot control functions + * @brief HAL SBS Boot functions + * +@verbatim + ======================================================================================================================= + ##### HAL SBS Boot control functions ##### + ======================================================================================================================= + [..] This section provides functions allowing to: + (+) Increment the HDPL value + (+) Get the HDPL value + +@endverbatim + * @{ + */ + +/** + * @brief Increment by 1 the HDPL value + * @retval None + */ +void HAL_SBS_IncrementHDPLValue(void) +{ + MODIFY_REG(SBS->HDPLCR, SBS_HDPLCR_INCR_HDPL, SBS_HDPL_INCREMENT_VALUE); +} + +/** + * @brief Get the HDPL Value. + * + * @retval Returns the HDPL value + * This return value can be one of the following values: + * @arg SBS_HDPL_VALUE_0: HDPL0 + * @arg SBS_HDPL_VALUE_1: HDPL1 + * @arg SBS_HDPL_VALUE_2: HDPL2 + * @arg SBS_HDPL_VALUE_3: HDPL3 + */ +uint32_t HAL_SBS_GetHDPLValue(void) +{ + return (uint32_t)(READ_BIT(SBS->HDPLSR, SBS_HDPLSR_HDPL)); +} + +/** + * @} + */ + +/** @defgroup HAL_Exported_Functions_Group7 HAL SBS Hardware secure storage control functions + * @brief HAL SBS Hardware secure storage functions + * +@verbatim + ======================================================================================================================= + ##### HAL SBS Hardware secure storage control functions ##### + ======================================================================================================================= + [..] This section provides functions allowing to: + (+) Select EPOCH security sent to SAES IP + (+) Set/Get EPOCH security selection + (+) Set/Get the OBK-HDPL Value + +@endverbatim + * @{ + */ + +#if defined(SBS_EPOCHSELCR_EPOCH_SEL) +/** + * @brief Select EPOCH security sent to SAES IP to encrypt/decrypt keys + * @param Epoch_Selection: Select EPOCH security + * This parameter can be one of the following values: + * @arg SBS_EPOCH_SEL_SECURE : EPOCH secure selected. + * @arg SBS_EPOCH_SEL_NONSECURE : EPOCH non secure selected. + * @arg SBS_EPOCH_SEL_PUFCHECK : EPOCH all zeros for PUF integrity check. + * @retval None + */ +void HAL_SBS_EPOCHSelection(uint32_t Epoch_Selection) +{ + /* Check the parameter */ + assert_param(IS_SBS_EPOCH_SELECTION(Epoch_Selection)); + + MODIFY_REG(SBS->EPOCHSELCR, SBS_EPOCHSELCR_EPOCH_SEL, (uint32_t)(Epoch_Selection)); +} + +/** + * @brief Get EPOCH security selection + * @retval Returned value can be one of the following values: + * @arg SBS_EPOCH_SEL_SECURE : EPOCH secure selected. + * @arg SBS_EPOCH_SEL_NONSECURE : EPOCH non secure selected. + * @arg SBS_EPOCH_SEL_PUFCHECK : EPOCH all zeros for PUF integrity check. + */ +uint32_t HAL_SBS_GetEPOCHSelection(void) +{ + return (uint32_t)(READ_BIT(SBS->EPOCHSELCR, SBS_EPOCHSELCR_EPOCH_SEL)); +} +#endif /* SBS_EPOCHSELCR_EPOCH_SEL */ + +#if defined(SBS_NEXTHDPLCR_NEXTHDPL) +/** + * @brief Set the OBK-HDPL Value. + * @param OBKHDPL_Value Value of the increment to add to HDPL value to generate the OBK-HDPL. + * This parameter can be one of the following values: + * @arg SBS_OBKHDPL_INCR_0 : HDPL + * @arg SBS_OBKHDPL_INCR_1 : HDPL + 1 + * @arg SBS_OBKHDPL_INCR_2 : HDPL + 2 + * @arg SBS_OBKHDPL_INCR_3 : HDPL + 3 + * @retval None + */ +void HAL_SBS_SetOBKHDPL(uint32_t OBKHDPL_Value) +{ + /* Check the parameter */ + assert_param(IS_SBS_OBKHDPL_SELECTION(OBKHDPL_Value)); + + MODIFY_REG(SBS->NEXTHDPLCR, SBS_NEXTHDPLCR_NEXTHDPL, (uint32_t)(OBKHDPL_Value)); +} + +/** + * @brief Get the OBK-HDPL Value. + * @retval Returns the incremement to add to HDPL value to generate OBK-HDPL + * This return value can be one of the following values: + * @arg SBS_OBKHDPL_INCR_0: HDPL + * @arg SBS_OBKHDPL_INCR_1: HDPL + 1 + * @arg SBS_OBKHDPL_INCR_2: HDPL + 2 + * @arg SBS_OBKHDPL_INCR_3: HDPL + 3 + */ +uint32_t HAL_SBS_GetOBKHDPL(void) +{ + return (uint32_t)(READ_BIT(SBS->NEXTHDPLCR, SBS_NEXTHDPLCR_NEXTHDPL)); +} +#endif /* SBS_NEXTHDPLCR_NEXTHDPL */ + +/** + * @} + */ + +/** @defgroup HAL_Exported_Functions_Group8 HAL SBS Debug control functions + * @brief HAL SBS Debug functions + * +@verbatim + ======================================================================================================================= + ##### SBS Debug control functions ##### + ======================================================================================================================= + [..] This section provides functions allowing to: + (+) Open the device access port + (+) Open the debug + (+) Configure the authenticated debug HDPL + (+) Get the current value of the hide protection level + (+) Lock the access to the debug control register + (+) Configure/Get the authenticated debug security access + +@endverbatim + * @{ + */ + +/** + * @brief Open the device access port. + * @note This function can be only used when device state is Closed. + * @retval None + */ +void HAL_SBS_OpenAccessPort(void) +{ + MODIFY_REG(SBS->DBGCR, SBS_DBGCR_AP_UNLOCK, SBS_DEBUG_UNLOCK_VALUE); +} + +/** + * @brief Open the debug when the hide protection level is authorized. + * @note This function can be only used when device state is Closed. + * @retval None + */ +void HAL_SBS_OpenDebug(void) +{ + MODIFY_REG(SBS->DBGCR, SBS_DBGCR_DBG_UNLOCK, (SBS_DEBUG_UNLOCK_VALUE << SBS_DBGCR_DBG_UNLOCK_Pos)); +} + +/** + * @brief Configure the authenticated debug hide protection level. + * @note This function can be only used when device state is Closed. + * @param Level Hide protection level where the authenticated debug opens + * This value is one of @ref SBS_HDPL_Value (except SBS_HDPL_VALUE_0) + * @retval HAL_OK if parameter is correct + * HAL_ERROR otherwise + */ +HAL_StatusTypeDef HAL_SBS_ConfigDebugLevel(uint32_t Level) +{ + /* Check the parameter */ + assert_param(IS_SBS_HDPL(Level)); + + if (Level != SBS_HDPL_VALUE_0) + { + MODIFY_REG(SBS->DBGCR, SBS_DBGCR_DBG_AUTH_HDPL, (Level << SBS_DBGCR_DBG_AUTH_HDPL_Pos)); + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Get the current value of the hide protection level. + * @note This function can be only used when device state is Closed. + * @retval Current hide protection level + * This value is one of @ref SBS_HDPL_Value + */ +uint32_t HAL_SBS_GetDebugLevel(void) +{ + return ((SBS->DBGCR & SBS_DBGCR_DBG_AUTH_HDPL) >> SBS_DBGCR_DBG_AUTH_HDPL_Pos); +} + +/** + * @brief Lock the access to the debug control register. + * @note This function can be only used when device state is Closed. + * @note locking the current debug configuration is released only by a reset. + * @retval None + */ +void HAL_SBS_LockDebugConfig(void) +{ + MODIFY_REG(SBS->DBGLOCKR, SBS_DBGLOCKR_DBGCFG_LOCK, SBS_DEBUG_LOCK_VALUE); +} + +#if defined(SBS_DBGCR_DBG_AUTH_SEC) +/** + * @brief Configure the authenticated debug security access. + * @param Control debug opening secure/non-secure or non-secure only + * This parameter can be one of the following values: + * @arg SBS_DEBUG_SEC_NSEC: debug opening for secure and non-secure. + * @arg SBS_DEBUG_NSEC: debug opening for non-secure only. + * @retval None + */ +void HAL_SBS_ConfigDebugSecurity(uint32_t Security) +{ + MODIFY_REG(SBS->DBGCR, SBS_DBGCR_DBG_AUTH_SEC, (Security << SBS_DBGCR_DBG_AUTH_SEC_Pos)); +} + +/** + * @brief Get the current value of the hide protection level. + * @note This function can be only used when device state is Closed. + * @retval Returned value can be one of the following values: + * @arg SBS_DEBUG_SEC_NSEC: debug opening for secure and non-secure. + * @arg SBS_DEBUG_NSEC: debug opening for non-secure only. + */ +uint32_t HAL_SBS_GetDebugSecurity(void) +{ + return ((SBS->DBGCR & SBS_DBGCR_DBG_AUTH_SEC) >> SBS_DBGCR_DBG_AUTH_SEC_Pos); +} +#endif /* SBS_DBGCR_DBG_AUTH_SEC */ + +/** + * @} + */ + +/** @defgroup HAL_Exported_Functions_Group9 HAL SBS lock management functions + * @brief SBS lock management functions. + * +@verbatim + ======================================================================================================================= + ##### SBS lock functions ##### + ======================================================================================================================= + +@endverbatim + * @{ + */ + +/** + * @brief Lock the SBS item(s). + * @note Setting lock(s) depends on privilege mode in secure/non-secure code + * Lock(s) cleared only at system reset + * @param Item Item(s) to set lock on. + * This parameter can be a combination of @ref SBS_Lock_items + * @retval None + */ +void HAL_SBS_Lock(uint32_t Item) +{ + /* Check the parameters */ + assert_param(IS_SBS_LOCK_ITEMS(Item)); + + /* Privilege secure/non-secure locks */ + SBS->CNSLCKR = (0xFFFFU & Item); /* non-secure lock item in 16 lowest bits */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + /* Privilege secure only locks */ + SBS->CSLCKR = ((0xFFFF0000U & Item) >> 16U); /* Secure-only lock item in 16 highest bits */ +#endif /* __ARM_FEATURE_CMSE */ +} + +/** + * @brief Get the lock state of SBS items. + * @note Getting lock(s) depends on privilege mode in secure/non-secure code + * @param pItem pointer to return locked items + * the return value can be a combination of @ref SBS_Lock_items + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SBS_GetLock(uint32_t *pItem) +{ + uint32_t tmp_lock; + + /* Check null pointer */ + if (pItem == NULL) + { + return HAL_ERROR; + } + + /* Get the non-secure lock state */ + tmp_lock = SBS->CNSLCKR; + + /* Get the secure lock state in secure code */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + tmp_lock |= (SBS->CSLCKR << 16U); +#endif /* __ARM_FEATURE_CMSE */ + + /* Return overall lock status */ + *pItem = tmp_lock; + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup HAL_Exported_Functions_Group10 HAL SBS attributes management functions + * @brief SBS attributes management functions. + * +@verbatim + ======================================================================================================================= + ##### SBS attributes functions ##### + ======================================================================================================================= + +@endverbatim + * @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Configure the SBS item attribute(s). + * @note Available attributes are to secure SBS items, so this function is + * only available in secure. + * SBS_FPU item attribute is only configurable through PRIVILEGE transaction. + * @param Item Item(s) to set attributes on. + * This parameter can be a one or a combination of @ref SBS_Attributes_items + * @param Attributes specifies the secure/non-secure attributes. + * @retval None + */ +void HAL_SBS_ConfigAttributes(uint32_t Item, uint32_t Attributes) +{ + uint32_t tmp; + + /* Check the parameters */ + assert_param(IS_SBS_ITEMS_ATTRIBUTES(Item)); + assert_param(IS_SBS_ATTRIBUTES(Attributes)); + + tmp = SBS->SECCFGR; + + /* Set or reset Item */ + if ((Attributes & SBS_SEC) != 0x00U) + { + tmp |= Item; + } + else + { + tmp &= ~Item; + } + + /* Set secure attributes */ + SBS->SECCFGR = tmp; +} + + +/** + * @brief Get the attribute of a SBS items. + * @note Available attributes have read restrictions, so this function is + * only available in secure + * @param Item Single item to get secure/non-secure attribute from. + * @param pAttributes pointer to return the attribute. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SBS_GetConfigAttributes(uint32_t Item, uint32_t *pAttributes) +{ + /* Check null pointer */ + if (pAttributes == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_SBS_ITEMS_ATTRIBUTES(Item)); + + /* Get the secure attribute state */ + if ((SBS->SECCFGR & Item) != 0U) + { + *pAttributes = SBS_SEC; + } + else + { + *pAttributes = SBS_NSEC; + } + + return HAL_OK; +} +#endif /* __ARM_FEATURE_CMSE */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_adc.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_adc.c new file mode 100644 index 0000000000..1441e27558 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_adc.c @@ -0,0 +1,3773 @@ +/** + ****************************************************************************** + * @file stm32h5xx_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 + * Other functions (extended functions) are available in file + * "stm32h5xx_hal_adc_ex.c". + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### ADC peripheral features ##### + ============================================================================== + [..] + (+) 12-bit, 10-bit, 8-bit or 6-bit configurable resolution. + + (+) Interrupt generation at the end of regular conversion and in case of + analog watchdog or overrun events. + + (+) Single and continuous conversion modes. + + (+) Scan mode for conversion of several channels sequentially. + + (+) Data alignment with in-built data coherency. + + (+) Programmable sampling time (channel wise) + + (+) External trigger (timer or EXTI) with configurable polarity + + (+) DMA request generation for transfer of conversions data of regular group. + + (+) Configurable delay between conversions in Dual interleaved mode. + + (+) ADC channels selectable single/differential input. + + (+) ADC offset shared on 4 offset instances. + (+) ADC calibration + + (+) ADC conversion of regular group. + + (+) ADC supply requirements: 1.62 V to 3.6 V. + + (+) ADC input range: from Vref- (connected to Vssa) to Vref+ (connected to + Vdda or to an external voltage reference). + + + ##### How to use this driver ##### + ============================================================================== + [..] + + *** Configuration of top level parameters related to ADC *** + ============================================================ + [..] + + (#) Enable the ADC interface + (++) As prerequisite, ADC clock must be configured at RCC top level. + + (++) Two clock settings are mandatory: + (+++) ADC clock (core clock, also possibly conversion clock). + + (+++) ADC clock (conversions clock). + Two possible clock sources: synchronous clock derived from AHB clock + or asynchronous clock derived from system clock or PLL. + + (+++) Example: + Into HAL_ADC_MspInit() (recommended code location) or with + other device clock parameters configuration: + (+++) __HAL_RCC_ADC_CLK_ENABLE(); (mandatory) + + RCC_ADCCLKSOURCE_PLL enable: (optional: if asynchronous clock selected) + (+++) RCC_PeriphClkInitTypeDef RCC_PeriphClkInit; + (+++) PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC; + (+++) PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_PLL; + (+++) HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit); + + (++) ADC clock source and clock prescaler are configured at ADC level with + parameter "ClockPrescaler" using function HAL_ADC_Init(). + + (#) ADC pins configuration + (++) Enable the clock for the ADC GPIOs + using macro __HAL_RCC_GPIOx_CLK_ENABLE() + (++) Configure these ADC pins in analog mode + using function HAL_GPIO_Init() + + (#) Optionally, in case of usage of ADC with interruptions: + (++) Configure the NVIC for ADC + using function HAL_NVIC_EnableIRQ(ADCx_IRQn) + (++) Insert the ADC interruption handler function HAL_ADC_IRQHandler() + into the function of corresponding ADC interruption vector + ADCx_IRQHandler(). + + (#) Optionally, in case of usage of DMA: + (++) Configure the DMA (DMA channel, mode normal or circular, ...) + using function HAL_DMA_Init(). + (++) Configure the NVIC for DMA + using function HAL_NVIC_EnableIRQ(DMAx_Channelx_IRQn) + (++) Insert the ADC interruption handler function HAL_ADC_IRQHandler() + into the function of corresponding DMA interruption vector + DMAx_Channelx_IRQHandler(). + + *** Configuration of ADC, group regular, 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 analog watchdog parameters (channels + monitored, thresholds, ...) + using function HAL_ADC_AnalogWDGConfig(). + + *** Execution of ADC conversions *** + ==================================== + [..] + + (#) Optionally, perform an automatic ADC calibration to improve the + conversion accuracy + using function HAL_ADCEx_Calibration_Start(). + + (#) ADC driver can be used among three modes: polling, interruption, + transfer by DMA. + + (++) ADC conversion by polling: + (+++) Activate the ADC peripheral and start conversions + using function HAL_ADC_Start() + (+++) Wait for ADC conversion completion + using function HAL_ADC_PollForConversion() + (+++) Retrieve conversion results + using function HAL_ADC_GetValue() + (+++) Stop conversion and disable the ADC peripheral + using function HAL_ADC_Stop() + + (++) ADC conversion by interruption: + (+++) Activate the ADC peripheral and start conversions + using function HAL_ADC_Start_IT() + (+++) Wait for ADC conversion completion by call of function + HAL_ADC_ConvCpltCallback() + (this function must be implemented in user program) + (+++) Retrieve conversion results + using function HAL_ADC_GetValue() + (+++) Stop conversion and disable the ADC peripheral + using function HAL_ADC_Stop_IT() + + (++) ADC conversion with transfer by DMA: + (+++) Activate the ADC peripheral and start conversions + using function HAL_ADC_Start_DMA() + (+++) Wait for ADC conversion completion by call of function + HAL_ADC_ConvCpltCallback() or HAL_ADC_ConvHalfCpltCallback() + (these functions must be implemented in user program) + (+++) Conversion results are automatically transferred by DMA into + destination variable address. + (+++) Stop conversion and disable the ADC peripheral + using function HAL_ADC_Stop_DMA() + + [..] + + (@) Callback functions must be implemented in user program: + (+@) HAL_ADC_ErrorCallback() + (+@) HAL_ADC_LevelOutOfWindowCallback() (callback of analog watchdog) + (+@) HAL_ADC_ConvCpltCallback() + (+@) HAL_ADC_ConvHalfCpltCallback + + *** 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 __ADCx_FORCE_RESET(), __ADCx_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: + (+++) RCC_OscInitStructure.OscillatorType = RCC_OSCILLATORTYPE_HSI14; + (+++) RCC_OscInitStructure.HSI14State = RCC_HSI14_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_EnableIRQ(ADCx_IRQn) + + (#) Optionally, in case of usage of DMA: + (++) Deinitialize the DMA + using function HAL_DMA_Init(). + (++) Disable the NVIC for DMA + using function HAL_NVIC_EnableIRQ(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 @ref HAL_ADC_RegisterCallback() + to register an interrupt callback. + [..] + + Function @ref 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 @ref HAL_ADC_UnRegisterCallback to reset a callback to the default + weak function. + [..] + + @ref 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 @ref HAL_ADC_Init() and when the state is @ref HAL_ADC_STATE_RESET + all callbacks are set to the corresponding weak functions: + examples @ref HAL_ADC_ConvCpltCallback(), @ref HAL_ADC_ErrorCallback(). + Exception done for MspInit and MspDeInit functions that are + reset to the legacy weak functions in the @ref HAL_ADC_Init()/ @ref HAL_ADC_DeInit() only when + these callbacks are null (not registered beforehand). + [..] + + If MspInit or MspDeInit are not null, the @ref HAL_ADC_Init()/ @ref HAL_ADC_DeInit() + keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state. + [..] + + Callbacks can be registered/unregistered in @ref HAL_ADC_STATE_READY state only. + Exception done MspInit/MspDeInit functions that can be registered/unregistered + in @ref HAL_ADC_STATE_READY or @ref 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 @ref HAL_ADC_RegisterCallback() before calling @ref HAL_ADC_DeInit() + or @ref 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 "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup ADC ADC + * @brief ADC HAL module driver + * @{ + */ + +#ifdef HAL_ADC_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/** @defgroup ADC_Private_Constants ADC Private Constants + * @{ + */ + +#define ADC_CFGR_FIELDS_1 (ADC_CFGR_RES | ADC_CFGR_ALIGN |\ + ADC_CFGR_CONT | ADC_CFGR_OVRMOD |\ + ADC_CFGR_DISCEN | ADC_CFGR_DISCNUM |\ + ADC_CFGR_EXTEN | ADC_CFGR_EXTSEL) /*!< ADC_CFGR fields of parameters that can + be updated when no regular conversion is on-going */ + +/* Timeout values for ADC operations (enable settling time, */ +/* disable settling time, ...). */ +/* Values defined to be higher than worst cases: low clock frequency, */ +/* maximum prescalers. */ +#define ADC_ENABLE_TIMEOUT (2UL) /*!< ADC enable time-out value */ +#define ADC_DISABLE_TIMEOUT (2UL) /*!< ADC disable time-out value */ + +/* Timeout to wait for current conversion on going to be completed. */ +/* Timeout fixed to longest ADC conversion possible, for 1 channel: */ +/* - maximum sampling time (640.5 adc_clk) */ +/* - ADC resolution (Tsar 12 bits= 12.5 adc_clk) */ +/* - System clock / ADC clock <= 4096 (hypothesis of maximum clock ratio) */ +/* - ADC oversampling ratio 256 */ +/* Calculation: 653 * 4096 * 256 CPU clock cycles max */ +/* Unit: cycles of CPU clock. */ +#define ADC_CONVERSION_TIME_MAX_CPU_CYCLES (653UL * 4096UL * 256UL) /*!< ADC conversion completion time-out value */ + + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup ADC_Exported_Functions ADC Exported Functions + * @{ + */ + +/** @defgroup ADC_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief ADC 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 Initialize the ADC peripheral and regular group according to + * parameters specified in structure "ADC_InitTypeDef". + * @note As prerequisite, ADC clock must be configured at RCC top level + * (refer to description of RCC configuration for ADC + * in header of this file). + * @note Possibility to update parameters on the fly: + * This function initializes the ADC MSP (HAL_ADC_MspInit()) only when + * coming from ADC state reset. Following calls to this function can + * be used to reconfigure some parameters of ADC_InitTypeDef + * structure on the fly, without modifying MSP configuration. If ADC + * MSP has to be modified again, HAL_ADC_DeInit() must be called + * before HAL_ADC_Init(). + * The setting of these parameters is conditioned to ADC state. + * For parameters constraints, see comments of structure + * "ADC_InitTypeDef". + * @note This function configures the ADC within 2 scopes: scope of entire + * ADC and scope of regular group. For parameters details, see comments + * of structure "ADC_InitTypeDef". + * @note Parameters related to common ADC registers (ADC clock mode) are set + * only if all ADCs are disabled. + * If this is not the case, these common parameters setting are + * bypassed without error reporting: it can be the intended behaviour in + * case of update of a parameter of ADC_InitTypeDef on the fly, + * without disabling the other ADCs. + * @param hadc ADC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef *hadc) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + uint32_t tmp_cfgr; + uint32_t tmp_adc_is_conversion_on_going_regular; + uint32_t tmp_adc_is_conversion_on_going_injected; + __IO uint32_t wait_loop_index = 0UL; + + /* 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_ADC_DATA_ALIGN(hadc->Init.DataAlign)); + assert_param(IS_ADC_SCAN_MODE(hadc->Init.ScanConvMode)); + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode)); + assert_param(IS_ADC_EXTTRIG_EDGE(hadc->Init.ExternalTrigConvEdge)); + assert_param(IS_ADC_EXTTRIG(hadc->Init.ExternalTrigConv)); + assert_param(IS_ADC_SAMPLINGMODE(hadc->Init.SamplingMode)); + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DMAContinuousRequests)); + assert_param(IS_ADC_EOC_SELECTION(hadc->Init.EOCSelection)); + assert_param(IS_ADC_OVERRUN(hadc->Init.Overrun)); + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.LowPowerAutoWait)); + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.OversamplingMode)); + + if (hadc->Init.ScanConvMode != ADC_SCAN_DISABLE) + { + assert_param(IS_ADC_REGULAR_NB_CONV(hadc->Init.NbrOfConversion)); + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DiscontinuousConvMode)); + + if (hadc->Init.DiscontinuousConvMode == ENABLE) + { + assert_param(IS_ADC_REGULAR_DISCONT_NUMBER(hadc->Init.NbrOfDiscConversion)); + } + } + + /* DISCEN and CONT bits cannot be set at the same time */ + assert_param(!((hadc->Init.DiscontinuousConvMode == ENABLE) && (hadc->Init.ContinuousConvMode == ENABLE))); + + /* Actions performed only if ADC is coming from state reset: */ + /* - Initialization of ADC MSP */ + 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 */ + hadc->InjectedQueueOverflowCallback = HAL_ADCEx_InjectedQueueOverflowCallback; /* Legacy weak callback */ + hadc->LevelOutOfWindow2Callback = HAL_ADCEx_LevelOutOfWindow2Callback; /* Legacy weak callback */ + hadc->LevelOutOfWindow3Callback = HAL_ADCEx_LevelOutOfWindow3Callback; /* Legacy weak callback */ + hadc->EndOfSamplingCallback = HAL_ADCEx_EndOfSamplingCallback; /* 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 */ + + /* Set ADC error code to none */ + ADC_CLEAR_ERRORCODE(hadc); + + /* Initialize Lock */ + hadc->Lock = HAL_UNLOCKED; + } + + /* - Exit from deep-power-down mode and ADC voltage regulator enable */ + if (LL_ADC_IsDeepPowerDownEnabled(hadc->Instance) != 0UL) + { + /* Disable ADC deep power down mode */ + LL_ADC_DisableDeepPowerDown(hadc->Instance); + + /* System was in deep power down mode, calibration must + be relaunched or a previously saved calibration factor + re-applied once the ADC voltage regulator is enabled */ + } + + if (LL_ADC_IsInternalRegulatorEnabled(hadc->Instance) == 0UL) + { + /* Enable ADC internal voltage regulator */ + LL_ADC_EnableInternalRegulator(hadc->Instance); + + /* Note: Variable divided by 2 to compensate partially */ + /* CPU processing cycles, scaling in us split to not */ + /* exceed 32 bits register capacity and handle low frequency. */ + wait_loop_index = ((LL_ADC_DELAY_INTERNAL_REGUL_STAB_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL)); + while (wait_loop_index != 0UL) + { + wait_loop_index--; + } + } + + /* Verification that ADC voltage regulator is correctly enabled, whether */ + /* or not ADC is coming from state reset (if any potential problem of */ + /* clocking, voltage regulator would not be enabled). */ + if (LL_ADC_IsInternalRegulatorEnabled(hadc->Instance) == 0UL) + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + + /* Set ADC error code to ADC peripheral internal error */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); + + tmp_hal_status = HAL_ERROR; + } + + /* Configuration of ADC parameters if previous preliminary actions are */ + /* correctly completed and if there is no conversion on going on regular */ + /* group (ADC may already be enabled at this point if HAL_ADC_Init() is */ + /* called to update a parameter on the fly). */ + tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance); + + if (((hadc->State & HAL_ADC_STATE_ERROR_INTERNAL) == 0UL) + && (tmp_adc_is_conversion_on_going_regular == 0UL) + ) + { + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_REG_BUSY, + HAL_ADC_STATE_BUSY_INTERNAL); + + /* Configuration of common ADC parameters */ + + /* Parameters update conditioned to ADC state: */ + /* Parameters that can be updated only when ADC is disabled: */ + /* - clock configuration */ + if (LL_ADC_IsEnabled(hadc->Instance) == 0UL) + { + if (__LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(__LL_ADC_COMMON_INSTANCE(hadc->Instance)) == 0UL) + { + /* Reset configuration of ADC common register CCR: */ + /* */ + /* - ADC clock mode and ACC prescaler (CKMODE and PRESC bits)are set */ + /* according to adc->Init.ClockPrescaler. It selects the clock */ + /* source and sets the clock division factor. */ + /* */ + /* Some parameters of this register are not reset, since they are set */ + /* by other functions and must be kept in case of usage of this */ + /* function on the fly (update of a parameter of ADC_InitTypeDef */ + /* without needing to reconfigure all other ADC groups/channels */ + /* parameters): */ + /* - when multimode feature is available, multimode-related */ + /* parameters: MDMA, DMACFG, DELAY, DUAL (set by API */ + /* HAL_ADCEx_MultiModeConfigChannel() ) */ + /* - internal measurement paths: Vbat, temperature sensor, Vref */ + /* (set into HAL_ADC_ConfigChannel() or */ + /* HAL_ADCEx_InjectedConfigChannel() ) */ + LL_ADC_SetCommonClock(__LL_ADC_COMMON_INSTANCE(hadc->Instance), hadc->Init.ClockPrescaler); + } + } + + /* Configuration of ADC: */ + /* - resolution Init.Resolution */ + /* - data alignment Init.DataAlign */ + /* - external trigger to start conversion Init.ExternalTrigConv */ + /* - external trigger polarity Init.ExternalTrigConvEdge */ + /* - continuous conversion mode Init.ContinuousConvMode */ + /* - overrun Init.Overrun */ + /* - discontinuous mode Init.DiscontinuousConvMode */ + /* - discontinuous mode channel count Init.NbrOfDiscConversion */ + tmp_cfgr = (ADC_CFGR_CONTINUOUS((uint32_t)hadc->Init.ContinuousConvMode) | + hadc->Init.Overrun | + hadc->Init.DataAlign | + hadc->Init.Resolution | + ADC_CFGR_REG_DISCONTINUOUS((uint32_t)hadc->Init.DiscontinuousConvMode)); + + if (hadc->Init.DiscontinuousConvMode == ENABLE) + { + tmp_cfgr |= ADC_CFGR_DISCONTINUOUS_NUM(hadc->Init.NbrOfDiscConversion); + } + + /* 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) + { + tmp_cfgr |= ((hadc->Init.ExternalTrigConv & ADC_CFGR_EXTSEL) + | hadc->Init.ExternalTrigConvEdge + ); + } + + /* Update Configuration Register CFGR */ + MODIFY_REG(hadc->Instance->CFGR, ADC_CFGR_FIELDS_1, tmp_cfgr); + + /* Configuration of sampling mode */ + MODIFY_REG(hadc->Instance->CFGR2, ADC_CFGR2_BULB | ADC_CFGR2_SMPTRIG, hadc->Init.SamplingMode); + + /* Parameters update conditioned to ADC state: */ + /* Parameters that can be updated when ADC is disabled or enabled without */ + /* conversion on going on regular and injected groups: */ + /* - DMA continuous request Init.DMAContinuousRequests */ + /* - LowPowerAutoWait feature Init.LowPowerAutoWait */ + /* - Oversampling parameters Init.Oversampling */ + tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance); + if ((tmp_adc_is_conversion_on_going_regular == 0UL) + && (tmp_adc_is_conversion_on_going_injected == 0UL) + ) + { + tmp_cfgr = ( + ADC_CFGR_AUTOWAIT((uint32_t)hadc->Init.LowPowerAutoWait) | + ADC_CFGR_DMACONTREQ((uint32_t)hadc->Init.DMAContinuousRequests)); + + MODIFY_REG(hadc->Instance->CFGR, ADC_CFGR_FIELDS_2, tmp_cfgr); + + if (hadc->Init.OversamplingMode == ENABLE) + { + assert_param(IS_ADC_OVERSAMPLING_RATIO(hadc->Init.Oversampling.Ratio)); + assert_param(IS_ADC_RIGHT_BIT_SHIFT(hadc->Init.Oversampling.RightBitShift)); + assert_param(IS_ADC_TRIGGERED_OVERSAMPLING_MODE(hadc->Init.Oversampling.TriggeredMode)); + assert_param(IS_ADC_REGOVERSAMPLING_MODE(hadc->Init.Oversampling.OversamplingStopReset)); + + /* Configuration of Oversampler: */ + /* - Oversampling Ratio */ + /* - Right bit shift */ + /* - Triggered mode */ + /* - Oversampling mode (continued/resumed) */ + MODIFY_REG(hadc->Instance->CFGR2, + ADC_CFGR2_OVSR | + ADC_CFGR2_OVSS | + ADC_CFGR2_TROVS | + ADC_CFGR2_ROVSM, + ADC_CFGR2_ROVSE | + hadc->Init.Oversampling.Ratio | + hadc->Init.Oversampling.RightBitShift | + hadc->Init.Oversampling.TriggeredMode | + hadc->Init.Oversampling.OversamplingStopReset + ); + } + else + { + /* Disable ADC oversampling scope on ADC group regular */ + CLEAR_BIT(hadc->Instance->CFGR2, ADC_CFGR2_ROVSE); + } + + } + + /* Configuration of regular group sequencer: */ + /* - if scan mode is disabled, regular channels sequence length is set to */ + /* 0x00: 1 channel converted (channel on regular rank 1) */ + /* Parameter "NbrOfConversion" is discarded. */ + /* Note: Scan mode is not present by hardware on this device, but */ + /* emulated by software for alignment over all STM32 devices. */ + /* - if scan mode is enabled, regular channels sequence length is set to */ + /* parameter "NbrOfConversion". */ + + if (hadc->Init.ScanConvMode == ADC_SCAN_ENABLE) + { + /* Set number of ranks in regular group sequencer */ + MODIFY_REG(hadc->Instance->SQR1, ADC_SQR1_L, (hadc->Init.NbrOfConversion - (uint8_t)1)); + } + else + { + CLEAR_BIT(hadc->Instance->SQR1, ADC_SQR1_L); + } + + /* Initialize the ADC state */ + /* Clear HAL_ADC_STATE_BUSY_INTERNAL bit, set HAL_ADC_STATE_READY bit */ + ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_BUSY_INTERNAL, HAL_ADC_STATE_READY); + } + else + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + + tmp_hal_status = HAL_ERROR; + } + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Deinitialize the ADC peripheral registers to their default reset + * values, with deinitialization of the ADC MSP. + * @note For devices with several ADCs: reset of ADC common registers is done + * only if all ADCs sharing the same common group are disabled. + * (function "HAL_ADC_MspDeInit()" is also called under the same conditions: + * all ADC instances use the same core clock at RCC level, disabling + * the core clock reset all ADC instances). + * If this is not the case, reset of these common parameters reset is + * bypassed without error reporting: it can be the intended behavior in + * case of reset of a single ADC while the other ADCs sharing the same + * common group is still running. + * @note By default, HAL_ADC_DeInit() set ADC in mode deep power-down: + * this saves more power by reducing leakage currents + * and is particularly interesting before entering MCU low-power modes. + * @param hadc ADC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef *hadc) +{ + HAL_StatusTypeDef tmp_hal_status; + + /* 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 */ + tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_INJECTED_GROUP); + + /* Disable ADC peripheral if conversions are effectively stopped */ + /* Flush register JSQR: reset the queue sequencer when injected */ + /* queue sequencer is enabled and ADC disabled. */ + /* The software and hardware triggers of the injected sequence are both */ + /* internally disabled just after the completion of the last valid */ + /* injected sequence. */ + SET_BIT(hadc->Instance->CFGR, ADC_CFGR_JQM); + + /* Disable ADC peripheral if conversions are effectively stopped */ + if (tmp_hal_status == HAL_OK) + { + /* Disable the ADC peripheral */ + tmp_hal_status = ADC_Disable(hadc); + + /* Check if ADC is effectively disabled */ + if (tmp_hal_status == HAL_OK) + { + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_READY; + } + } + + /* Note: HAL ADC deInit is done independently of ADC conversion stop */ + /* and disable return status. In case of status fail, attempt to */ + /* perform deinitialization anyway and it is up user code in */ + /* in HAL_ADC_MspDeInit() to reset the ADC peripheral using */ + /* system RCC hard reset. */ + + /* ========== Reset ADC registers ========== */ + /* Reset register IER */ + __HAL_ADC_DISABLE_IT(hadc, (ADC_IT_AWD3 | ADC_IT_AWD2 | ADC_IT_AWD1 | + ADC_IT_JQOVF | ADC_IT_OVR | + ADC_IT_JEOS | ADC_IT_JEOC | + ADC_IT_EOS | ADC_IT_EOC | + ADC_IT_EOSMP | ADC_IT_RDY)); + + /* Reset register ISR */ + __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_AWD3 | ADC_FLAG_AWD2 | ADC_FLAG_AWD1 | + ADC_FLAG_JQOVF | ADC_FLAG_OVR | + ADC_FLAG_JEOS | ADC_FLAG_JEOC | + ADC_FLAG_EOS | ADC_FLAG_EOC | + ADC_FLAG_EOSMP | ADC_FLAG_RDY)); + + /* Reset register CR */ + /* Bits ADC_CR_JADSTP, ADC_CR_ADSTP, ADC_CR_JADSTART, ADC_CR_ADSTART, + ADC_CR_ADCAL, ADC_CR_ADDIS and ADC_CR_ADEN are in access mode "read-set": + no direct reset applicable. + Update CR register to reset value where doable by software */ + CLEAR_BIT(hadc->Instance->CR, ADC_CR_ADVREGEN | ADC_CR_ADCALDIF); + SET_BIT(hadc->Instance->CR, ADC_CR_DEEPPWD); + + /* Reset register CFGR */ + CLEAR_BIT(hadc->Instance->CFGR, ADC_CFGR_FIELDS); + SET_BIT(hadc->Instance->CFGR, ADC_CFGR_JQDIS); + + /* Reset register CFGR2 */ + CLEAR_BIT(hadc->Instance->CFGR2, ADC_CFGR2_ROVSM | ADC_CFGR2_TROVS | ADC_CFGR2_OVSS | + ADC_CFGR2_OVSR | ADC_CFGR2_JOVSE | ADC_CFGR2_ROVSE); + + /* Reset register SMPR1 */ + CLEAR_BIT(hadc->Instance->SMPR1, ADC_SMPR1_FIELDS); + + /* Reset register SMPR2 */ + CLEAR_BIT(hadc->Instance->SMPR2, ADC_SMPR2_SMP18 | ADC_SMPR2_SMP17 | ADC_SMPR2_SMP16 | + ADC_SMPR2_SMP15 | ADC_SMPR2_SMP14 | ADC_SMPR2_SMP13 | + ADC_SMPR2_SMP12 | ADC_SMPR2_SMP11 | ADC_SMPR2_SMP10); + + /* Reset register TR1 */ + CLEAR_BIT(hadc->Instance->TR1, ADC_TR1_HT1 | ADC_TR1_LT1); + + /* Reset register TR2 */ + CLEAR_BIT(hadc->Instance->TR2, ADC_TR2_HT2 | ADC_TR2_LT2); + + /* Reset register TR3 */ + CLEAR_BIT(hadc->Instance->TR3, ADC_TR3_HT3 | ADC_TR3_LT3); + + /* Reset register SQR1 */ + CLEAR_BIT(hadc->Instance->SQR1, ADC_SQR1_SQ4 | ADC_SQR1_SQ3 | ADC_SQR1_SQ2 | + ADC_SQR1_SQ1 | ADC_SQR1_L); + + /* Reset register SQR2 */ + CLEAR_BIT(hadc->Instance->SQR2, ADC_SQR2_SQ9 | ADC_SQR2_SQ8 | ADC_SQR2_SQ7 | + ADC_SQR2_SQ6 | ADC_SQR2_SQ5); + + /* Reset register SQR3 */ + CLEAR_BIT(hadc->Instance->SQR3, ADC_SQR3_SQ14 | ADC_SQR3_SQ13 | ADC_SQR3_SQ12 | + ADC_SQR3_SQ11 | ADC_SQR3_SQ10); + + /* Reset register SQR4 */ + CLEAR_BIT(hadc->Instance->SQR4, ADC_SQR4_SQ16 | ADC_SQR4_SQ15); + + /* Register JSQR was reset when the ADC was disabled */ + + /* Reset register DR */ + /* bits in access mode read only, no direct reset applicable*/ + + /* Reset register OFR1 */ + CLEAR_BIT(hadc->Instance->OFR1, ADC_OFR1_OFFSET1_EN | ADC_OFR1_OFFSET1_CH | ADC_OFR1_OFFSET1); + /* Reset register OFR2 */ + CLEAR_BIT(hadc->Instance->OFR2, ADC_OFR2_OFFSET2_EN | ADC_OFR2_OFFSET2_CH | ADC_OFR2_OFFSET2); + /* Reset register OFR3 */ + CLEAR_BIT(hadc->Instance->OFR3, ADC_OFR3_OFFSET3_EN | ADC_OFR3_OFFSET3_CH | ADC_OFR3_OFFSET3); + /* Reset register OFR4 */ + CLEAR_BIT(hadc->Instance->OFR4, ADC_OFR4_OFFSET4_EN | ADC_OFR4_OFFSET4_CH | ADC_OFR4_OFFSET4); + + /* Reset registers JDR1, JDR2, JDR3, JDR4 */ + /* bits in access mode read only, no direct reset applicable*/ + + /* Reset register AWD2CR */ + CLEAR_BIT(hadc->Instance->AWD2CR, ADC_AWD2CR_AWD2CH); + + /* Reset register AWD3CR */ + CLEAR_BIT(hadc->Instance->AWD3CR, ADC_AWD3CR_AWD3CH); + + /* Reset register DIFSEL */ + CLEAR_BIT(hadc->Instance->DIFSEL, ADC_DIFSEL_DIFSEL); + + /* Reset register CALFACT */ + CLEAR_BIT(hadc->Instance->CALFACT, ADC_CALFACT_CALFACT_D | ADC_CALFACT_CALFACT_S); + + + /* ========== Reset common ADC registers ========== */ + + /* Software is allowed to change common parameters only when all the other + ADCs are disabled. */ + if (__LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(__LL_ADC_COMMON_INSTANCE(hadc->Instance)) == 0UL) + { + /* Reset configuration of ADC common register CCR: + - clock mode: CKMODE, PRESCEN + - multimode related parameters (when this feature is available): MDMA, + DMACFG, DELAY, DUAL (set by HAL_ADCEx_MultiModeConfigChannel() API) + - internal measurement paths: Vbat, temperature sensor, Vref (set into + HAL_ADC_ConfigChannel() or HAL_ADCEx_InjectedConfigChannel() ) + */ + ADC_CLEAR_COMMON_CONTROL_REGISTER(hadc); + + /* ========== Hard reset ADC peripheral ========== */ + /* Performs a global reset of the entire ADC peripherals instances */ + /* sharing the same common ADC instance: ADC state is forced to */ + /* a similar state as after device power-on. */ + /* Note: A possible implementation is to add RCC bus reset of ADC */ + /* (for example, using macro */ + /* __HAL_RCC_ADC..._FORCE_RESET()/..._RELEASE_RESET()/..._CLK_DISABLE()) */ + /* in function "void HAL_ADC_MspDeInit(ADC_HandleTypeDef *hadc)": */ +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + if (hadc->MspDeInitCallback == NULL) + { + hadc->MspDeInitCallback = HAL_ADC_MspDeInit; /* Legacy weak MspDeInit */ + } + + /* DeInit the low level hardware */ + hadc->MspDeInitCallback(hadc); +#else + /* DeInit the low level hardware */ + HAL_ADC_MspDeInit(hadc); +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + } + + /* Set ADC error code to none */ + ADC_CLEAR_ERRORCODE(hadc); + + /* Reset injected channel configuration parameters */ + hadc->InjectionConfig.ContextQueue = 0; + hadc->InjectionConfig.ChannelCount = 0; + + /* Set ADC state */ + hadc->State = HAL_ADC_STATE_RESET; + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Initialize the ADC MSP. + * @param hadc ADC handle + * @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, + function HAL_ADC_MspInit must be implemented in the user file. + */ +} + +/** + * @brief DeInitialize the ADC MSP. + * @param hadc ADC handle + * @note All ADC instances use the same core clock at RCC level, disabling + * the core clock reset all ADC instances). + * @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, + function HAL_ADC_MspDeInit must be implemented in the user file. + */ +} + +#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_INJ_QUEUE_OVEFLOW_CB_ID ADC group injected context queue overflow callback ID + * @arg @ref HAL_ADC_LEVEL_OUT_OF_WINDOW_2_CB_ID ADC analog watchdog 2 callback ID + * @arg @ref HAL_ADC_LEVEL_OUT_OF_WINDOW_3_CB_ID ADC analog watchdog 3 callback ID + * @arg @ref HAL_ADC_END_OF_SAMPLING_CB_ID ADC end of sampling 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 + * @arg @ref HAL_ADC_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_ADC_MSPDEINIT_CB_ID MspDeInit 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_INJ_QUEUE_OVEFLOW_CB_ID : + hadc->InjectedQueueOverflowCallback = pCallback; + break; + + case HAL_ADC_LEVEL_OUT_OF_WINDOW_2_CB_ID : + hadc->LevelOutOfWindow2Callback = pCallback; + break; + + case HAL_ADC_LEVEL_OUT_OF_WINDOW_3_CB_ID : + hadc->LevelOutOfWindow3Callback = pCallback; + break; + + case HAL_ADC_END_OF_SAMPLING_CB_ID : + hadc->EndOfSamplingCallback = 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_INJ_QUEUE_OVEFLOW_CB_ID ADC group injected context queue overflow callback ID + * @arg @ref HAL_ADC_LEVEL_OUT_OF_WINDOW_2_CB_ID ADC analog watchdog 2 callback ID + * @arg @ref HAL_ADC_LEVEL_OUT_OF_WINDOW_3_CB_ID ADC analog watchdog 3 callback ID + * @arg @ref HAL_ADC_END_OF_SAMPLING_CB_ID ADC end of sampling 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 + * @arg @ref HAL_ADC_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_ADC_MSPDEINIT_CB_ID MspDeInit 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_INJ_QUEUE_OVEFLOW_CB_ID : + hadc->InjectedQueueOverflowCallback = HAL_ADCEx_InjectedQueueOverflowCallback; + break; + + case HAL_ADC_LEVEL_OUT_OF_WINDOW_2_CB_ID : + hadc->LevelOutOfWindow2Callback = HAL_ADCEx_LevelOutOfWindow2Callback; + break; + + case HAL_ADC_LEVEL_OUT_OF_WINDOW_3_CB_ID : + hadc->LevelOutOfWindow3Callback = HAL_ADCEx_LevelOutOfWindow3Callback; + break; + + case HAL_ADC_END_OF_SAMPLING_CB_ID : + hadc->EndOfSamplingCallback = HAL_ADCEx_EndOfSamplingCallback; + 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 */ + +/** + * @} + */ + +/** @defgroup ADC_Exported_Functions_Group2 ADC Input and Output operation functions + * @brief ADC IO operation functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Start conversion of regular group. + (+) Stop conversion of regular group. + (+) Poll for conversion complete on regular group. + (+) Poll for conversion event. + (+) Get result of regular channel conversion. + (+) Start conversion of regular group and enable interruptions. + (+) Stop conversion of regular group and disable interruptions. + (+) Handle ADC interrupt request + (+) Start conversion of regular group and enable DMA transfer. + (+) Stop conversion of regular group and disable ADC DMA transfer. +@endverbatim + * @{ + */ + +/** + * @brief Enable ADC, start conversion of regular group. + * @note Interruptions enabled in this function: None. + * @note Case of multimode enabled (when multimode feature is available): + * if ADC is Slave, ADC is enabled but conversion is not started, + * if ADC is master, ADC is enabled and multimode conversion is started. + * @param hadc ADC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef *hadc) +{ + HAL_StatusTypeDef tmp_hal_status; +#if defined(ADC_MULTIMODE_SUPPORT) + const ADC_TypeDef *tmpADC_Master; + uint32_t tmp_multimode_config = LL_ADC_GetMultimode(__LL_ADC_COMMON_INSTANCE(hadc->Instance)); +#endif /* ADC_MULTIMODE_SUPPORT */ + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Perform ADC enable and conversion start if no conversion is on going */ + if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL) + { + /* Process locked */ + __HAL_LOCK(hadc); + + /* Enable the ADC peripheral */ + tmp_hal_status = ADC_Enable(hadc); + + /* Start conversion if ADC is effectively enabled */ + if (tmp_hal_status == HAL_OK) + { + /* Set ADC state */ + /* - Clear state bitfield related to regular group conversion results */ + /* - Set state bitfield related to regular 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_EOSMP, + HAL_ADC_STATE_REG_BUSY); + +#if defined(ADC_MULTIMODE_SUPPORT) + /* Reset HAL_ADC_STATE_MULTIMODE_SLAVE bit + - if ADC instance is master or if multimode feature is not available + - if multimode setting is disabled (ADC instance slave in independent mode) */ + if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance) + || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT) + ) + { + CLEAR_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE); + } +#endif /* ADC_MULTIMODE_SUPPORT */ + + /* Set ADC error code */ + /* Check if a conversion is on going on ADC group injected */ + if (HAL_IS_BIT_SET(hadc->State, HAL_ADC_STATE_INJ_BUSY)) + { + /* Reset ADC error code fields related to regular conversions only */ + CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA)); + } + else + { + /* Reset all ADC error code fields */ + ADC_CLEAR_ERRORCODE(hadc); + } + + /* Clear ADC group regular 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_EOS | ADC_FLAG_OVR)); + + /* Process unlocked */ + /* Unlock before starting ADC conversions: in case of potential */ + /* interruption, to let the process to ADC IRQ Handler. */ + __HAL_UNLOCK(hadc); + + /* Enable conversion of regular group. */ + /* If software start has been selected, conversion starts immediately. */ + /* If external trigger has been selected, conversion will start at next */ + /* trigger event. */ + /* Case of multimode enabled (when multimode feature is available): */ + /* - if ADC is slave and dual regular conversions are enabled, ADC is */ + /* enabled only (conversion is not started), */ + /* - if ADC is master, ADC is enabled and conversion is started. */ +#if defined(ADC_MULTIMODE_SUPPORT) + if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance) + || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT) + || (tmp_multimode_config == LL_ADC_MULTI_DUAL_INJ_SIMULT) + || (tmp_multimode_config == LL_ADC_MULTI_DUAL_INJ_ALTERN) + ) + { + /* ADC instance is not a multimode slave instance with multimode regular conversions enabled */ + if (READ_BIT(hadc->Instance->CFGR, ADC_CFGR_JAUTO) != 0UL) + { + ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY); + } + + /* Start ADC group regular conversion */ + LL_ADC_REG_StartConversion(hadc->Instance); + } + else + { + /* ADC instance is a multimode slave instance with multimode regular conversions enabled */ + SET_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE); + /* if Master ADC JAUTO bit is set, update Slave State in setting + HAL_ADC_STATE_INJ_BUSY bit and in resetting HAL_ADC_STATE_INJ_EOC bit */ + tmpADC_Master = __LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance); + if (READ_BIT(tmpADC_Master->CFGR, ADC_CFGR_JAUTO) != 0UL) + { + ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY); + } + + } +#else + if (READ_BIT(hadc->Instance->CFGR, ADC_CFGR_JAUTO) != 0UL) + { + ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY); + } + + /* Start ADC group regular conversion */ + LL_ADC_REG_StartConversion(hadc->Instance); +#endif /* ADC_MULTIMODE_SUPPORT */ + } + else + { + /* Process unlocked */ + __HAL_UNLOCK(hadc); + } + } + else + { + tmp_hal_status = HAL_BUSY; + } + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Stop ADC conversion of regular group (and injected channels in + * case of auto_injection mode), disable ADC peripheral. + * @note: ADC peripheral disable is forcing stop of potential + * conversion on injected group. If injected group is under use, it + * should be preliminarily stopped using HAL_ADCEx_InjectedStop function. + * @param hadc ADC handle + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef *hadc) +{ + HAL_StatusTypeDef tmp_hal_status; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* 1. Stop potential conversion on going, on ADC groups regular and injected */ + tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_INJECTED_GROUP); + + /* Disable ADC peripheral if conversions are effectively stopped */ + if (tmp_hal_status == HAL_OK) + { + /* 2. Disable the ADC peripheral */ + tmp_hal_status = ADC_Disable(hadc); + + /* Check if ADC is effectively disabled */ + if (tmp_hal_status == HAL_OK) + { + /* 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 Wait for regular group conversion to be completed. + * @note ADC conversion flags EOS (end of sequence) and EOC (end of + * conversion) are cleared by this function, with an exception: + * if low power feature "LowPowerAutoWait" is enabled, flags are + * not cleared to not interfere with this feature until data register + * is read using function HAL_ADC_GetValue(). + * @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 (ADC init + * parameter "EOCSelection" set to ADC_EOC_SEQ_CONV). + * @param hadc ADC handle + * @param Timeout Timeout value in millisecond. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef *hadc, uint32_t Timeout) +{ + uint32_t tickstart; + uint32_t tmp_Flag_End; + uint32_t tmp_cfgr; +#if defined(ADC_MULTIMODE_SUPPORT) + const ADC_TypeDef *tmpADC_Master; + uint32_t tmp_multimode_config = LL_ADC_GetMultimode(__LL_ADC_COMMON_INSTANCE(hadc->Instance)); +#endif /* ADC_MULTIMODE_SUPPORT */ + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* If end of conversion selected to end of sequence conversions */ + if (hadc->Init.EOCSelection == ADC_EOC_SEQ_CONV) + { + tmp_Flag_End = ADC_FLAG_EOS; + } + /* If end of conversion selected to end of unitary conversion */ + else /* ADC_EOC_SINGLE_CONV */ + { + /* 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 and polling for end of each conversion. */ +#if defined(ADC_MULTIMODE_SUPPORT) + if ((tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT) + || (tmp_multimode_config == LL_ADC_MULTI_DUAL_INJ_SIMULT) + || (tmp_multimode_config == LL_ADC_MULTI_DUAL_INJ_ALTERN) + ) + { + /* Check ADC DMA mode in independent mode on ADC group regular */ + if (READ_BIT(hadc->Instance->CFGR, ADC_CFGR_DMAEN) != 0UL) + { + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); + return HAL_ERROR; + } + else + { + tmp_Flag_End = (ADC_FLAG_EOC); + } + } + else + { + /* Check ADC DMA mode in multimode on ADC group regular */ + if (LL_ADC_GetMultiDMATransfer(__LL_ADC_COMMON_INSTANCE(hadc->Instance)) != LL_ADC_MULTI_REG_DMA_EACH_ADC) + { + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); + return HAL_ERROR; + } + else + { + tmp_Flag_End = (ADC_FLAG_EOC); + } + } +#else + /* Check ADC DMA mode */ + if (READ_BIT(hadc->Instance->CFGR, ADC_CFGR_DMAEN) != 0UL) + { + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); + return HAL_ERROR; + } + else + { + tmp_Flag_End = (ADC_FLAG_EOC); + } +#endif /* ADC_MULTIMODE_SUPPORT */ + } + + /* Get tick count */ + tickstart = HAL_GetTick(); + + /* Wait until End of unitary conversion or sequence conversions flag is raised */ + while ((hadc->Instance->ISR & tmp_Flag_End) == 0UL) + { + /* Check if timeout is disabled (set to infinite wait) */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL)) + { + /* New check to avoid false timeout detection in case of preemption */ + if ((hadc->Instance->ISR & tmp_Flag_End) == 0UL) + { + /* Update ADC state machine to timeout */ + SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + return HAL_TIMEOUT; + } + } + } + } + + /* 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. */ + if ((LL_ADC_REG_IsTriggerSourceSWStart(hadc->Instance) != 0UL) + && (hadc->Init.ContinuousConvMode == DISABLE) + ) + { + /* Check whether end of sequence is reached */ + if (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOS)) + { + /* Set ADC state */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY); + + if ((hadc->State & HAL_ADC_STATE_INJ_BUSY) == 0UL) + { + SET_BIT(hadc->State, HAL_ADC_STATE_READY); + } + } + } + + /* Get relevant register CFGR in ADC instance of ADC master or slave */ + /* in function of multimode state (for devices with multimode */ + /* available). */ +#if defined(ADC_MULTIMODE_SUPPORT) + if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance) + || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT) + || (tmp_multimode_config == LL_ADC_MULTI_DUAL_INJ_SIMULT) + || (tmp_multimode_config == LL_ADC_MULTI_DUAL_INJ_ALTERN) + ) + { + /* Retrieve handle ADC CFGR register */ + tmp_cfgr = READ_REG(hadc->Instance->CFGR); + } + else + { + /* Retrieve Master ADC CFGR register */ + tmpADC_Master = __LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance); + tmp_cfgr = READ_REG(tmpADC_Master->CFGR); + } +#else + /* Retrieve handle ADC CFGR register */ + tmp_cfgr = READ_REG(hadc->Instance->CFGR); +#endif /* ADC_MULTIMODE_SUPPORT */ + + /* Clear polled flag */ + if (tmp_Flag_End == ADC_FLAG_EOS) + { + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOS); + } + else + { + /* Clear end of conversion EOC flag of regular group if low power feature */ + /* "LowPowerAutoWait " is disabled, to not interfere with this feature */ + /* until data register is read using function HAL_ADC_GetValue(). */ + if (READ_BIT(tmp_cfgr, ADC_CFGR_AUTDLY) == 0UL) + { + __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOC | ADC_FLAG_EOS)); + } + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Poll for ADC event. + * @param hadc ADC handle + * @param EventType the ADC event type. + * This parameter can be one of the following values: + * @arg @ref ADC_EOSMP_EVENT ADC End of Sampling event + * @arg @ref ADC_AWD1_EVENT ADC Analog watchdog 1 event (main analog watchdog, present on + * all STM32 series) + * @arg @ref ADC_AWD2_EVENT ADC Analog watchdog 2 event (additional analog watchdog, not present on + * all STM32 series) + * @arg @ref ADC_AWD3_EVENT ADC Analog watchdog 3 event (additional analog watchdog, not present on + * all STM32 series) + * @arg @ref ADC_OVR_EVENT ADC Overrun event + * @arg @ref ADC_JQOVF_EVENT ADC Injected context queue overflow event + * @param Timeout Timeout value in millisecond. + * @note The relevant flag is cleared if found to be set, except for ADC_FLAG_OVR. + * Indeed, the latter is reset only if hadc->Init.Overrun field is set + * to ADC_OVR_DATA_OVERWRITTEN. Otherwise, data register may be potentially overwritten + * by a new converted data as soon as OVR is cleared. + * To reset OVR flag once the preserved data is retrieved, the user can resort + * to macro __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_OVR); + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_PollForEvent(ADC_HandleTypeDef *hadc, uint32_t EventType, uint32_t Timeout) +{ + uint32_t tickstart; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + assert_param(IS_ADC_EVENT_TYPE(EventType)); + + /* Get tick count */ + tickstart = HAL_GetTick(); + + /* Check selected event flag */ + while (__HAL_ADC_GET_FLAG(hadc, EventType) == 0UL) + { + /* Check if timeout is disabled (set to infinite wait) */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL)) + { + /* New check to avoid false timeout detection in case of preemption */ + if (__HAL_ADC_GET_FLAG(hadc, EventType) == 0UL) + { + /* Update ADC state machine to timeout */ + SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + return HAL_TIMEOUT; + } + } + } + } + + switch (EventType) + { + /* End Of Sampling event */ + case ADC_EOSMP_EVENT: + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOSMP); + + /* Clear the End Of Sampling flag */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOSMP); + + break; + + /* Analog watchdog (level out of window) event */ + /* Note: In case of several analog watchdog enabled, if needed to know */ + /* which one triggered and on which ADCx, test ADC state of analog watchdog */ + /* flags HAL_ADC_STATE_AWD1/2/3 using function "HAL_ADC_GetState()". */ + /* For example: */ + /* " if ((HAL_ADC_GetState(hadc1) & HAL_ADC_STATE_AWD1) != 0UL) " */ + /* " if ((HAL_ADC_GetState(hadc1) & HAL_ADC_STATE_AWD2) != 0UL) " */ + /* " if ((HAL_ADC_GetState(hadc1) & HAL_ADC_STATE_AWD3) != 0UL) " */ + + /* Check analog watchdog 1 flag */ + case 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_AWD1); + + break; + + /* Check analog watchdog 2 flag */ + case ADC_AWD2_EVENT: + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_AWD2); + + /* Clear ADC analog watchdog flag */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD2); + + break; + + /* Check analog watchdog 3 flag */ + case ADC_AWD3_EVENT: + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_AWD3); + + /* Clear ADC analog watchdog flag */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD3); + + break; + + /* Injected context queue overflow event */ + case ADC_JQOVF_EVENT: + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_INJ_JQOVF); + + /* Set ADC error code to Injected context queue overflow */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_JQOVF); + + /* Clear ADC Injected context queue overflow flag */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JQOVF); + + break; + + /* Overrun event */ + default: /* Case ADC_OVR_EVENT */ + /* If overrun is set to overwrite previous data, overrun event is not */ + /* considered as an error. */ + /* (cf ref manual "Managing conversions without using the DMA and without */ + /* overrun ") */ + if (hadc->Init.Overrun == ADC_OVR_DATA_PRESERVED) + { + /* 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); + } + else + { + /* Clear ADC Overrun flag only if Overrun is set to ADC_OVR_DATA_OVERWRITTEN + otherwise, data register is potentially overwritten by new converted data as soon + as OVR is cleared. */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_OVR); + } + break; + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Enable ADC, start conversion of regular group with interruption. + * @note Interruptions enabled in this function according to initialization + * setting : EOC (end of conversion), EOS (end of sequence), + * OVR overrun. + * Each of these interruptions has its dedicated callback function. + * @note Case of multimode enabled (when multimode feature is available): + * HAL_ADC_Start_IT() must be called for ADC Slave first, then for + * ADC Master. + * For ADC Slave, ADC is enabled only (conversion is not started). + * For ADC Master, ADC is enabled and multimode conversion is started. + * @note To guarantee a proper reset of all interruptions once all the needed + * conversions are obtained, HAL_ADC_Stop_IT() must be called to ensure + * a correct stop of the IT-based conversions. + * @note By default, HAL_ADC_Start_IT() does not enable the End Of Sampling + * interruption. If required (e.g. in case of oversampling with trigger + * mode), the user must: + * 1. first clear the EOSMP flag if set with macro __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOSMP) + * 2. then enable the EOSMP interrupt with macro __HAL_ADC_ENABLE_IT(hadc, ADC_IT_EOSMP) + * before calling HAL_ADC_Start_IT(). + * @param hadc ADC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef *hadc) +{ + HAL_StatusTypeDef tmp_hal_status; +#if defined(ADC_MULTIMODE_SUPPORT) + const ADC_TypeDef *tmpADC_Master; + uint32_t tmp_multimode_config = LL_ADC_GetMultimode(__LL_ADC_COMMON_INSTANCE(hadc->Instance)); +#endif /* ADC_MULTIMODE_SUPPORT */ + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Perform ADC enable and conversion start if no conversion is on going */ + if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL) + { + /* Process locked */ + __HAL_LOCK(hadc); + + /* Enable the ADC peripheral */ + tmp_hal_status = ADC_Enable(hadc); + + /* Start conversion if ADC is effectively enabled */ + if (tmp_hal_status == HAL_OK) + { + /* Set ADC state */ + /* - Clear state bitfield related to regular group conversion results */ + /* - Set state bitfield related to regular 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_EOSMP, + HAL_ADC_STATE_REG_BUSY); + +#if defined(ADC_MULTIMODE_SUPPORT) + /* Reset HAL_ADC_STATE_MULTIMODE_SLAVE bit + - if ADC instance is master or if multimode feature is not available + - if multimode setting is disabled (ADC instance slave in independent mode) */ + if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance) + || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT) + ) + { + CLEAR_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE); + } +#endif /* ADC_MULTIMODE_SUPPORT */ + + /* Set ADC error code */ + /* Check if a conversion is on going on ADC group injected */ + if ((hadc->State & HAL_ADC_STATE_INJ_BUSY) != 0UL) + { + /* Reset ADC error code fields related to regular conversions only */ + CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA)); + } + else + { + /* Reset all ADC error code fields */ + ADC_CLEAR_ERRORCODE(hadc); + } + + /* Clear ADC group regular 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_EOS | ADC_FLAG_OVR)); + + /* Process unlocked */ + /* Unlock before starting ADC conversions: in case of potential */ + /* interruption, to let the process to ADC IRQ Handler. */ + __HAL_UNLOCK(hadc); + + /* Disable all interruptions before enabling the desired ones */ + __HAL_ADC_DISABLE_IT(hadc, (ADC_IT_EOC | ADC_IT_EOS | ADC_IT_OVR)); + + /* Enable ADC end of conversion interrupt */ + switch (hadc->Init.EOCSelection) + { + case ADC_EOC_SEQ_CONV: + __HAL_ADC_ENABLE_IT(hadc, ADC_IT_EOS); + break; + /* case ADC_EOC_SINGLE_CONV */ + default: + __HAL_ADC_ENABLE_IT(hadc, ADC_IT_EOC); + break; + } + + /* Enable ADC overrun interrupt */ + /* If hadc->Init.Overrun is set to ADC_OVR_DATA_PRESERVED, only then is + ADC_IT_OVR enabled; otherwise data overwrite is considered as normal + behavior and no CPU time is lost for a non-processed interruption */ + if (hadc->Init.Overrun == ADC_OVR_DATA_PRESERVED) + { + __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR); + } + + /* Enable conversion of regular group. */ + /* If software start has been selected, conversion starts immediately. */ + /* If external trigger has been selected, conversion will start at next */ + /* trigger event. */ + /* Case of multimode enabled (when multimode feature is available): */ + /* - if ADC is slave and dual regular conversions are enabled, ADC is */ + /* enabled only (conversion is not started), */ + /* - if ADC is master, ADC is enabled and conversion is started. */ +#if defined(ADC_MULTIMODE_SUPPORT) + if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance) + || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT) + || (tmp_multimode_config == LL_ADC_MULTI_DUAL_INJ_SIMULT) + || (tmp_multimode_config == LL_ADC_MULTI_DUAL_INJ_ALTERN) + ) + { + /* ADC instance is not a multimode slave instance with multimode regular conversions enabled */ + if (READ_BIT(hadc->Instance->CFGR, ADC_CFGR_JAUTO) != 0UL) + { + ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY); + + /* Enable as well injected interruptions in case + HAL_ADCEx_InjectedStart_IT() has not been called beforehand. This + allows to start regular and injected conversions when JAUTO is + set with a single call to HAL_ADC_Start_IT() */ + switch (hadc->Init.EOCSelection) + { + case ADC_EOC_SEQ_CONV: + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC); + __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOS); + break; + /* case ADC_EOC_SINGLE_CONV */ + default: + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOS); + __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC); + break; + } + } + + /* Start ADC group regular conversion */ + LL_ADC_REG_StartConversion(hadc->Instance); + } + else + { + /* ADC instance is a multimode slave instance with multimode regular conversions enabled */ + SET_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE); + /* if Master ADC JAUTO bit is set, Slave injected interruptions + are enabled nevertheless (for same reason as above) */ + tmpADC_Master = __LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance); + if (READ_BIT(tmpADC_Master->CFGR, ADC_CFGR_JAUTO) != 0UL) + { + /* First, update Slave State in setting HAL_ADC_STATE_INJ_BUSY bit + and in resetting HAL_ADC_STATE_INJ_EOC bit */ + ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY); + /* Next, set Slave injected interruptions */ + switch (hadc->Init.EOCSelection) + { + case ADC_EOC_SEQ_CONV: + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC); + __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOS); + break; + /* case ADC_EOC_SINGLE_CONV */ + default: + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOS); + __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC); + break; + } + } + } +#else + /* ADC instance is not a multimode slave instance with multimode regular conversions enabled */ + if (READ_BIT(hadc->Instance->CFGR, ADC_CFGR_JAUTO) != 0UL) + { + ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY); + + /* Enable as well injected interruptions in case + HAL_ADCEx_InjectedStart_IT() has not been called beforehand. This + allows to start regular and injected conversions when JAUTO is + set with a single call to HAL_ADC_Start_IT() */ + switch (hadc->Init.EOCSelection) + { + case ADC_EOC_SEQ_CONV: + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC); + __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOS); + break; + /* case ADC_EOC_SINGLE_CONV */ + default: + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOS); + __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC); + break; + } + } + + /* Start ADC group regular conversion */ + LL_ADC_REG_StartConversion(hadc->Instance); +#endif /* ADC_MULTIMODE_SUPPORT */ + } + else + { + /* Process unlocked */ + __HAL_UNLOCK(hadc); + } + + } + else + { + tmp_hal_status = HAL_BUSY; + } + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Stop ADC conversion of regular group (and injected group in + * case of auto_injection mode), disable interrution of + * end-of-conversion, disable ADC peripheral. + * @param hadc ADC handle + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef *hadc) +{ + HAL_StatusTypeDef tmp_hal_status; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* 1. Stop potential conversion on going, on ADC groups regular and injected */ + tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_INJECTED_GROUP); + + /* Disable ADC peripheral if conversions are effectively stopped */ + if (tmp_hal_status == HAL_OK) + { + /* Disable ADC end of conversion interrupt for regular group */ + /* Disable ADC overrun interrupt */ + __HAL_ADC_DISABLE_IT(hadc, (ADC_IT_EOC | ADC_IT_EOS | ADC_IT_OVR)); + + /* 2. Disable the ADC peripheral */ + tmp_hal_status = ADC_Disable(hadc); + + /* Check if ADC is effectively disabled */ + if (tmp_hal_status == HAL_OK) + { + /* 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 Enable ADC, start conversion of regular group and transfer result through DMA. + * @note Interruptions enabled in this function: + * overrun (if applicable), DMA half transfer, DMA transfer complete. + * Each of these interruptions has its dedicated callback function. + * @note Case of multimode enabled (when multimode feature is available): HAL_ADC_Start_DMA() + * is designed for single-ADC mode only. For multimode, the dedicated + * HAL_ADCEx_MultiModeStart_DMA() function must be used. + * @param hadc ADC handle + * @param pData Destination Buffer address. + * @param Length Number 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) +{ + HAL_StatusTypeDef tmp_hal_status; +#if defined(ADC_MULTIMODE_SUPPORT) + uint32_t tmp_multimode_config = LL_ADC_GetMultimode(__LL_ADC_COMMON_INSTANCE(hadc->Instance)); +#endif /* ADC_MULTIMODE_SUPPORT */ + uint32_t length_bytes; + DMA_NodeConfTypeDef node_conf; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Perform ADC enable and conversion start if no conversion is on going */ + if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL) + { + /* Process locked */ + __HAL_LOCK(hadc); + +#if defined(ADC_MULTIMODE_SUPPORT) + /* Ensure that multimode regular conversions are not enabled. */ + /* Otherwise, dedicated API HAL_ADCEx_MultiModeStart_DMA() must be used. */ + if ((tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT) + || (tmp_multimode_config == LL_ADC_MULTI_DUAL_INJ_SIMULT) + || (tmp_multimode_config == LL_ADC_MULTI_DUAL_INJ_ALTERN) + ) +#endif /* ADC_MULTIMODE_SUPPORT */ + { + /* Enable the ADC peripheral */ + tmp_hal_status = ADC_Enable(hadc); + + /* Start conversion if ADC is effectively enabled */ + if (tmp_hal_status == HAL_OK) + { + /* Set ADC state */ + /* - Clear state bitfield related to regular group conversion results */ + /* - Set state bitfield related to regular 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_EOSMP, + HAL_ADC_STATE_REG_BUSY); + +#if defined(ADC_MULTIMODE_SUPPORT) + /* Reset HAL_ADC_STATE_MULTIMODE_SLAVE bit + - if ADC instance is master or if multimode feature is not available + - if multimode setting is disabled (ADC instance slave in independent mode) */ + if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance) + || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT) + ) + { + CLEAR_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE); + } +#endif /* ADC_MULTIMODE_SUPPORT */ + + /* Check if a conversion is on going on ADC group injected */ + if ((hadc->State & HAL_ADC_STATE_INJ_BUSY) != 0UL) + { + /* Reset ADC error code fields related to regular conversions only */ + CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA)); + } + else + { + /* Reset all ADC error code fields */ + ADC_CLEAR_ERRORCODE(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_EOS | ADC_FLAG_OVR)); + + /* Process unlocked */ + /* Unlock before starting ADC conversions: in case of potential */ + /* interruption, to let the process to ADC IRQ Handler. */ + __HAL_UNLOCK(hadc); + + /* With DMA, overrun event is always considered as an error even if + hadc->Init.Overrun is set to ADC_OVR_DATA_OVERWRITTEN. Therefore, + ADC_IT_OVR is enabled. */ + __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR); + + /* Enable ADC DMA mode */ + SET_BIT(hadc->Instance->CFGR, ADC_CFGR_DMAEN); + + /* Check linkedlist mode */ + if ((hadc->DMA_Handle->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hadc->DMA_Handle->LinkedListQueue != NULL) && (hadc->DMA_Handle->LinkedListQueue->Head != NULL)) + { + /* Length should be converted to number of bytes */ + if (HAL_DMAEx_List_GetNodeConfig(&node_conf, hadc->DMA_Handle->LinkedListQueue->Head) != HAL_OK) + { + return HAL_ERROR; + } + + /* Length should be converted to number of bytes */ + if (node_conf.Init.SrcDataWidth == DMA_SRC_DATAWIDTH_WORD) + { + /* Word -> Bytes */ + length_bytes = Length * 4U; + } + else if (node_conf.Init.SrcDataWidth == DMA_SRC_DATAWIDTH_HALFWORD) + { + /* Halfword -> Bytes */ + length_bytes = Length * 2U; + } + else /* Bytes */ + { + /* Same size already expressed in Bytes */ + length_bytes = Length; + } + + hadc->DMA_Handle->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = (uint32_t)length_bytes; + hadc->DMA_Handle->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = \ + (uint32_t)&hadc->Instance->DR; + hadc->DMA_Handle->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)pData; + tmp_hal_status = HAL_DMAEx_List_Start_IT(hadc->DMA_Handle); + } + else + { + return HAL_ERROR; + } + } + else + { + /* Length should be converted to number of bytes */ + if (hadc->DMA_Handle->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_WORD) + { + /* Word -> Bytes */ + length_bytes = Length * 4U; + } + else if (hadc->DMA_Handle->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_HALFWORD) + { + /* Halfword -> Bytes */ + length_bytes = Length * 2U; + } + else /* Bytes */ + { + /* Same size already expressed in Bytes */ + length_bytes = Length; + } + + /* Start the DMA channel */ + tmp_hal_status = HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&hadc->Instance->DR, (uint32_t)pData, \ + length_bytes); + } + + /* Enable conversion of regular group. */ + /* If software start has been selected, conversion starts immediately. */ + /* If external trigger has been selected, conversion will start at next */ + /* trigger event. */ + /* Start ADC group regular conversion */ + LL_ADC_REG_StartConversion(hadc->Instance); + } + else + { + /* Process unlocked */ + __HAL_UNLOCK(hadc); + } + + } +#if defined(ADC_MULTIMODE_SUPPORT) + else + { + tmp_hal_status = HAL_ERROR; + /* Process unlocked */ + __HAL_UNLOCK(hadc); + } +#endif /* ADC_MULTIMODE_SUPPORT */ + } + else + { + tmp_hal_status = HAL_BUSY; + } + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Stop ADC conversion of regular group (and injected group in + * case of auto_injection mode), disable ADC DMA transfer, disable + * ADC peripheral. + * @note: ADC peripheral disable is forcing stop of potential + * conversion on ADC group injected. If ADC group injected is under use, it + * should be preliminarily stopped using HAL_ADCEx_InjectedStop function. + * @note Case of multimode enabled (when multimode feature is available): + * HAL_ADC_Stop_DMA() function is dedicated to single-ADC mode only. + * For multimode, the dedicated HAL_ADCEx_MultiModeStop_DMA() API must be used. + * @param hadc ADC handle + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef *hadc) +{ + HAL_StatusTypeDef tmp_hal_status; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* 1. Stop potential ADC group regular conversion on going */ + tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_INJECTED_GROUP); + + /* Disable ADC peripheral if conversions are effectively stopped */ + if (tmp_hal_status == HAL_OK) + { + /* Disable ADC DMA (ADC DMA configuration of continuous requests is kept) */ + CLEAR_BIT(hadc->Instance->CFGR, ADC_CFGR_DMAEN); + + /* 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); + + /* 2. Disable the ADC peripheral */ + /* Update "tmp_hal_status" only if DMA channel disabling passed, */ + /* to keep in memory a potential failing status. */ + if (tmp_hal_status == HAL_OK) + { + tmp_hal_status = ADC_Disable(hadc); + } + else + { + (void)ADC_Disable(hadc); + } + + /* Check if ADC is effectively disabled */ + if (tmp_hal_status == HAL_OK) + { + /* 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 Get ADC regular group conversion result. + * @note Reading register DR automatically clears ADC flag EOC + * (ADC group regular end of unitary conversion). + * @note This function does not clear ADC flag EOS + * (ADC group regular end of sequence conversion). + * Occurrence of flag EOS rising: + * - If sequencer is composed of 1 rank, flag EOS is equivalent + * to flag EOC. + * - If sequencer is composed of several ranks, during the scan + * sequence flag EOC only is raised, at the end of the scan sequence + * both flags EOC and EOS are raised. + * To clear this flag, either use function: + * in programming model IT: @ref HAL_ADC_IRQHandler(), in programming + * model polling: @ref HAL_ADC_PollForConversion() + * or @ref __HAL_ADC_CLEAR_FLAG(&hadc, ADC_FLAG_EOS). + * @param hadc ADC handle + * @retval ADC group regular conversion data + */ +uint32_t HAL_ADC_GetValue(const ADC_HandleTypeDef *hadc) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Note: EOC flag is not cleared here by software because automatically */ + /* cleared by hardware when reading register DR. */ + + /* Return ADC converted value */ + return hadc->Instance->DR; +} + +/** + * @brief Start ADC conversion sampling phase of regular group + * @note: This function should only be called to start sampling when + * - @ref ADC_SAMPLING_MODE_TRIGGER_CONTROLED sampling + * mode has been selected + * - @ref ADC_SOFTWARE_START has been selected as trigger source + * @param hadc ADC handle + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_ADC_StartSampling(ADC_HandleTypeDef *hadc) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Start sampling */ + SET_BIT(hadc->Instance->CFGR2, ADC_CFGR2_SWTRIG); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stop ADC conversion sampling phase of regular group and start conversion + * @note: This function should only be called to stop sampling when + * - @ref ADC_SAMPLING_MODE_TRIGGER_CONTROLED sampling + * mode has been selected + * - @ref ADC_SOFTWARE_START has been selected as trigger source + * - after sampling has been started using @ref HAL_ADC_StartSampling. + * @param hadc ADC handle + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_ADC_StopSampling(ADC_HandleTypeDef *hadc) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Start sampling */ + CLEAR_BIT(hadc->Instance->CFGR2, ADC_CFGR2_SWTRIG); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Handle ADC interrupt request. + * @param hadc ADC handle + * @retval None + */ +void HAL_ADC_IRQHandler(ADC_HandleTypeDef *hadc) +{ + uint32_t overrun_error = 0UL; /* flag set if overrun occurrence has to be considered as an error */ + uint32_t tmp_isr = hadc->Instance->ISR; + uint32_t tmp_ier = hadc->Instance->IER; + uint32_t tmp_adc_inj_is_trigger_source_sw_start; + uint32_t tmp_adc_reg_is_trigger_source_sw_start; + uint32_t tmp_cfgr; +#if defined(ADC_MULTIMODE_SUPPORT) + const ADC_TypeDef *tmpADC_Master; + uint32_t tmp_multimode_config = LL_ADC_GetMultimode(__LL_ADC_COMMON_INSTANCE(hadc->Instance)); +#endif /* ADC_MULTIMODE_SUPPORT */ + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + assert_param(IS_ADC_EOC_SELECTION(hadc->Init.EOCSelection)); + + /* ========== Check End of Sampling flag for ADC group regular ========== */ + if (((tmp_isr & ADC_FLAG_EOSMP) == ADC_FLAG_EOSMP) && ((tmp_ier & ADC_IT_EOSMP) == ADC_IT_EOSMP)) + { + /* Update state machine on end of sampling status if not in error state */ + if ((hadc->State & HAL_ADC_STATE_ERROR_INTERNAL) == 0UL) + { + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOSMP); + } + + /* End Of Sampling callback */ +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + hadc->EndOfSamplingCallback(hadc); +#else + HAL_ADCEx_EndOfSamplingCallback(hadc); +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + + /* Clear regular group conversion flag */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOSMP); + } + + /* ====== Check ADC group regular end of unitary conversion sequence conversions ===== */ + if ((((tmp_isr & ADC_FLAG_EOC) == ADC_FLAG_EOC) && ((tmp_ier & ADC_IT_EOC) == ADC_IT_EOC)) || + (((tmp_isr & ADC_FLAG_EOS) == ADC_FLAG_EOS) && ((tmp_ier & ADC_IT_EOS) == ADC_IT_EOS))) + { + /* Update state machine on conversion status if not in error state */ + if ((hadc->State & HAL_ADC_STATE_ERROR_INTERNAL) == 0UL) + { + /* 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 */ + /* to disable interruption. */ + if (LL_ADC_REG_IsTriggerSourceSWStart(hadc->Instance) != 0UL) + { + /* Get relevant register CFGR in ADC instance of ADC master or slave */ + /* in function of multimode state (for devices with multimode */ + /* available). */ +#if defined(ADC_MULTIMODE_SUPPORT) + if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance) + || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT) + || (tmp_multimode_config == LL_ADC_MULTI_DUAL_INJ_SIMULT) + || (tmp_multimode_config == LL_ADC_MULTI_DUAL_INJ_ALTERN) + ) + { + /* check CONT bit directly in handle ADC CFGR register */ + tmp_cfgr = READ_REG(hadc->Instance->CFGR); + } + else + { + /* else need to check Master ADC CONT bit */ + tmpADC_Master = __LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance); + tmp_cfgr = READ_REG(tmpADC_Master->CFGR); + } +#else + tmp_cfgr = READ_REG(hadc->Instance->CFGR); +#endif /* ADC_MULTIMODE_SUPPORT */ + + /* Carry on if continuous mode is disabled */ + if (READ_BIT(tmp_cfgr, ADC_CFGR_CONT) != ADC_CFGR_CONT) + { + /* If End of Sequence is reached, disable interrupts */ + if (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOS)) + { + /* Allowed to modify bits ADC_IT_EOC/ADC_IT_EOS only if bit */ + /* ADSTART==0 (no conversion on going) */ + if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL) + { + /* Disable ADC end of sequence conversion interrupt */ + /* Note: Overrun interrupt was enabled with EOC interrupt in */ + /* HAL_Start_IT(), but is not disabled here because can be used */ + /* by overrun IRQ process below. */ + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC | ADC_IT_EOS); + + /* Set ADC state */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY); + + if ((hadc->State & HAL_ADC_STATE_INJ_BUSY) == 0UL) + { + SET_BIT(hadc->State, HAL_ADC_STATE_READY); + } + } + else + { + /* Change ADC state to error state */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + + /* Set ADC error code to ADC peripheral internal error */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); + } + } + } + } + + /* Conversion complete callback */ + /* Note: Into callback function "HAL_ADC_ConvCpltCallback()", */ + /* to determine if conversion has been triggered from EOC or EOS, */ + /* possibility to use: */ + /* " if ( __HAL_ADC_GET_FLAG(&hadc, ADC_FLAG_EOS)) " */ +#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 */ + /* Note: in case of overrun set to ADC_OVR_DATA_PRESERVED, end of */ + /* conversion flags clear induces the release of the preserved data.*/ + /* Therefore, if the preserved data value is needed, it must be */ + /* read preliminarily into HAL_ADC_ConvCpltCallback(). */ + __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOC | ADC_FLAG_EOS)); + } + + /* ====== Check ADC group injected end of unitary conversion sequence conversions ===== */ + if ((((tmp_isr & ADC_FLAG_JEOC) == ADC_FLAG_JEOC) && ((tmp_ier & ADC_IT_JEOC) == ADC_IT_JEOC)) || + (((tmp_isr & ADC_FLAG_JEOS) == ADC_FLAG_JEOS) && ((tmp_ier & ADC_IT_JEOS) == ADC_IT_JEOS))) + { + /* Update state machine on conversion status if not in error state */ + if ((hadc->State & HAL_ADC_STATE_ERROR_INTERNAL) == 0UL) + { + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_INJ_EOC); + } + + /* Retrieve ADC configuration */ + tmp_adc_inj_is_trigger_source_sw_start = LL_ADC_INJ_IsTriggerSourceSWStart(hadc->Instance); + tmp_adc_reg_is_trigger_source_sw_start = LL_ADC_REG_IsTriggerSourceSWStart(hadc->Instance); + /* Get relevant register CFGR in ADC instance of ADC master or slave */ + /* in function of multimode state (for devices with multimode */ + /* available). */ +#if defined(ADC_MULTIMODE_SUPPORT) + if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance) + || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT) + || (tmp_multimode_config == LL_ADC_MULTI_DUAL_REG_SIMULT) + || (tmp_multimode_config == LL_ADC_MULTI_DUAL_REG_INTERL) + ) + { + tmp_cfgr = READ_REG(hadc->Instance->CFGR); + } + else + { + tmpADC_Master = __LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance); + tmp_cfgr = READ_REG(tmpADC_Master->CFGR); + } +#else + tmp_cfgr = READ_REG(hadc->Instance->CFGR); +#endif /* ADC_MULTIMODE_SUPPORT */ + + /* Disable interruption if no further conversion upcoming by injected */ + /* external trigger or by automatic injected conversion with regular */ + /* group having no further conversion upcoming (same conditions as */ + /* regular group interruption disabling above), */ + /* and if injected scan sequence is completed. */ + if (tmp_adc_inj_is_trigger_source_sw_start != 0UL) + { + if ((READ_BIT(tmp_cfgr, ADC_CFGR_JAUTO) == 0UL) || + ((tmp_adc_reg_is_trigger_source_sw_start != 0UL) && + (READ_BIT(tmp_cfgr, ADC_CFGR_CONT) == 0UL))) + { + /* If End of Sequence is reached, disable interrupts */ + if (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOS)) + { + /* Particular case if injected contexts queue is enabled: */ + /* when the last context has been fully processed, JSQR is reset */ + /* by the hardware. Even if no injected conversion is planned to come */ + /* (queue empty, triggers are ignored), it can start again */ + /* immediately after setting a new context (JADSTART is still set). */ + /* Therefore, state of HAL ADC injected group is kept to busy. */ + if (READ_BIT(tmp_cfgr, ADC_CFGR_JQM) == 0UL) + { + /* Allowed to modify bits ADC_IT_JEOC/ADC_IT_JEOS only if bit */ + /* JADSTART==0 (no conversion on going) */ + if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL) + { + /* Disable ADC end of sequence conversion interrupt */ + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC | ADC_IT_JEOS); + + /* Set ADC state */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY); + + if ((hadc->State & HAL_ADC_STATE_REG_BUSY) == 0UL) + { + SET_BIT(hadc->State, HAL_ADC_STATE_READY); + } + } + else + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + + /* Set ADC error code to ADC peripheral internal error */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); + } + } + } + } + } + + /* Injected Conversion complete callback */ + /* Note: HAL_ADCEx_InjectedConvCpltCallback can resort to + if (__HAL_ADC_GET_FLAG(&hadc, ADC_FLAG_JEOS)) or + if (__HAL_ADC_GET_FLAG(&hadc, ADC_FLAG_JEOC)) to determine whether + interruption has been triggered by end of conversion or end of + sequence. */ +#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_JEOC | ADC_FLAG_JEOS); + } + + /* ========== Check Analog watchdog 1 flag ========== */ + if (((tmp_isr & ADC_FLAG_AWD1) == ADC_FLAG_AWD1) && ((tmp_ier & ADC_IT_AWD1) == ADC_IT_AWD1)) + { + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_AWD1); + + /* Level out of window 1 callback */ +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + hadc->LevelOutOfWindowCallback(hadc); +#else + HAL_ADC_LevelOutOfWindowCallback(hadc); +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + + /* Clear ADC analog watchdog flag */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD1); + } + + /* ========== Check analog watchdog 2 flag ========== */ + if (((tmp_isr & ADC_FLAG_AWD2) == ADC_FLAG_AWD2) && ((tmp_ier & ADC_IT_AWD2) == ADC_IT_AWD2)) + { + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_AWD2); + + /* Level out of window 2 callback */ +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + hadc->LevelOutOfWindow2Callback(hadc); +#else + HAL_ADCEx_LevelOutOfWindow2Callback(hadc); +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + + /* Clear ADC analog watchdog flag */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD2); + } + + /* ========== Check analog watchdog 3 flag ========== */ + if (((tmp_isr & ADC_FLAG_AWD3) == ADC_FLAG_AWD3) && ((tmp_ier & ADC_IT_AWD3) == ADC_IT_AWD3)) + { + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_AWD3); + + /* Level out of window 3 callback */ +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + hadc->LevelOutOfWindow3Callback(hadc); +#else + HAL_ADCEx_LevelOutOfWindow3Callback(hadc); +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + + /* Clear ADC analog watchdog flag */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD3); + } + + /* ========== Check Overrun flag ========== */ + if (((tmp_isr & ADC_FLAG_OVR) == ADC_FLAG_OVR) && ((tmp_ier & ADC_IT_OVR) == ADC_IT_OVR)) + { + /* If overrun is set to overwrite previous data (default setting), */ + /* overrun event is not considered as an error. */ + /* (cf ref manual "Managing conversions without using the DMA and without */ + /* overrun ") */ + /* Exception for usage with DMA overrun event always considered as an */ + /* error. */ + if (hadc->Init.Overrun == ADC_OVR_DATA_PRESERVED) + { + overrun_error = 1UL; + } + else + { + /* Check DMA configuration */ +#if defined(ADC_MULTIMODE_SUPPORT) + if (tmp_multimode_config != LL_ADC_MULTI_INDEPENDENT) + { + /* Multimode (when feature is available) is enabled, + Common Control Register MDMA bits must be checked. */ + if (LL_ADC_GetMultiDMATransfer(__LL_ADC_COMMON_INSTANCE(hadc->Instance)) != LL_ADC_MULTI_REG_DMA_EACH_ADC) + { + overrun_error = 1UL; + } + } + else +#endif /* ADC_MULTIMODE_SUPPORT */ + { + /* Multimode not set or feature not available or ADC independent */ + if ((hadc->Instance->CFGR & ADC_CFGR_DMAEN) != 0UL) + { + overrun_error = 1UL; + } + } + } + + if (overrun_error == 1UL) + { + /* Change ADC state to error state */ + SET_BIT(hadc->State, HAL_ADC_STATE_REG_OVR); + + /* Set ADC error code to overrun */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_OVR); + + /* Error callback */ + /* Note: In case of overrun, ADC conversion data is preserved until */ + /* flag OVR is reset. */ + /* Therefore, old ADC conversion data can be retrieved in */ + /* function "HAL_ADC_ErrorCallback()". */ +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + hadc->ErrorCallback(hadc); +#else + HAL_ADC_ErrorCallback(hadc); +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + } + + /* Clear ADC overrun flag */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_OVR); + } + + /* ========== Check Injected context queue overflow flag ========== */ + if (((tmp_isr & ADC_FLAG_JQOVF) == ADC_FLAG_JQOVF) && ((tmp_ier & ADC_IT_JQOVF) == ADC_IT_JQOVF)) + { + /* Change ADC state to overrun state */ + SET_BIT(hadc->State, HAL_ADC_STATE_INJ_JQOVF); + + /* Set ADC error code to Injected context queue overflow */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_JQOVF); + + /* Clear the Injected context queue overflow flag */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JQOVF); + + /* Injected context queue overflow callback */ +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + hadc->InjectedQueueOverflowCallback(hadc); +#else + HAL_ADCEx_InjectedQueueOverflowCallback(hadc); +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + } + +} + +/** + * @brief Conversion complete callback in non-blocking mode. + * @param hadc ADC handle + * @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, + function HAL_ADC_ConvCpltCallback must be implemented in the user file. + */ +} + +/** + * @brief Conversion DMA half-transfer callback in non-blocking mode. + * @param hadc ADC handle + * @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, + function HAL_ADC_ConvHalfCpltCallback must be implemented in the user file. + */ +} + +/** + * @brief Analog watchdog 1 callback in non-blocking mode. + * @param hadc ADC handle + * @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, + function HAL_ADC_LevelOutOfWindowCallback must be implemented in the user file. + */ +} + +/** + * @brief ADC error callback in non-blocking mode + * (ADC conversion with interruption or transfer by DMA). + * @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 ADC handle + * @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, + function HAL_ADC_ErrorCallback must 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 channels on regular group + (+) Configure the analog watchdog + +@endverbatim + * @{ + */ + +/** + * @brief Configure a channel to be assigned to ADC group regular. + * @note In case of usage of internal measurement channels: + * Vbat/VrefInt/TempSensor. + * These internal paths can be disabled using function + * HAL_ADC_DeInit(). + * @note Possibility to update parameters on the fly: + * This function initializes channel into ADC group regular, + * following calls to this function can be used to reconfigure + * some parameters of structure "ADC_ChannelConfTypeDef" on the fly, + * without resetting the ADC. + * The setting of these parameters is conditioned to ADC state: + * Refer to comments of structure "ADC_ChannelConfTypeDef". + * @param hadc ADC handle + * @param pConfig Structure of ADC channel assigned to ADC group regular. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef *hadc, const ADC_ChannelConfTypeDef *pConfig) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + uint32_t tmpOffsetShifted; + uint32_t tmp_config_internal_channel; + __IO uint32_t wait_loop_index = 0UL; + uint32_t tmp_adc_is_conversion_on_going_regular; + uint32_t tmp_adc_is_conversion_on_going_injected; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + assert_param(IS_ADC_REGULAR_RANK(pConfig->Rank)); + assert_param(IS_ADC_SAMPLE_TIME(pConfig->SamplingTime)); + assert_param(IS_ADC_SINGLE_DIFFERENTIAL(pConfig->SingleDiff)); + assert_param(IS_ADC_OFFSET_NUMBER(pConfig->OffsetNumber)); + assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), pConfig->Offset)); + + /* if ROVSE is set, the value of the OFFSETy_EN bit in ADCx_OFRy register is + ignored (considered as reset) */ + assert_param(!((pConfig->OffsetNumber != ADC_OFFSET_NONE) && (hadc->Init.OversamplingMode == ENABLE))); + + /* Verification of channel number */ + if (pConfig->SingleDiff != ADC_DIFFERENTIAL_ENDED) + { + assert_param(IS_ADC_CHANNEL(hadc, pConfig->Channel)); + } + else + { + assert_param(IS_ADC_DIFF_CHANNEL(hadc, pConfig->Channel)); + } + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Parameters update conditioned to ADC state: */ + /* Parameters that can be updated when ADC is disabled or enabled without */ + /* conversion on going on regular group: */ + /* - Channel number */ + /* - Channel rank */ + if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL) + { + if (pConfig->Channel == ADC_CHANNEL_0) + { + LL_ADC_EnableChannel0_GPIO(hadc->Instance); + } + + /* Set ADC group regular sequence: channel on the selected scan sequence rank */ + LL_ADC_REG_SetSequencerRanks(hadc->Instance, pConfig->Rank, pConfig->Channel); + + /* Parameters update conditioned to ADC state: */ + /* Parameters that can be updated when ADC is disabled or enabled without */ + /* conversion on going on regular group: */ + /* - Channel sampling time */ + /* - Channel offset */ + tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance); + tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance); + if ((tmp_adc_is_conversion_on_going_regular == 0UL) + && (tmp_adc_is_conversion_on_going_injected == 0UL) + ) + { + /* Manage specific case of sampling time 3.5 cycles replacing 2.5 cyles */ + if (pConfig->SamplingTime == ADC_SAMPLETIME_3CYCLES_5) + { + /* Set sampling time of the selected ADC channel */ + LL_ADC_SetChannelSamplingTime(hadc->Instance, pConfig->Channel, LL_ADC_SAMPLINGTIME_2CYCLES_5); + + /* Set ADC sampling time common configuration */ + LL_ADC_SetSamplingTimeCommonConfig(hadc->Instance, LL_ADC_SAMPLINGTIME_COMMON_3C5_REPL_2C5); + } + else + { + /* Set sampling time of the selected ADC channel */ + LL_ADC_SetChannelSamplingTime(hadc->Instance, pConfig->Channel, pConfig->SamplingTime); + + /* Set ADC sampling time common configuration */ + LL_ADC_SetSamplingTimeCommonConfig(hadc->Instance, LL_ADC_SAMPLINGTIME_COMMON_DEFAULT); + } + + /* Configure the offset: offset enable/disable, channel, offset value */ + + /* Shift the offset with respect to the selected ADC resolution. */ + /* Offset has to be left-aligned on bit 11, the LSB (right bits) are set to 0 */ + tmpOffsetShifted = ADC_OFFSET_SHIFT_RESOLUTION(hadc, (uint32_t)pConfig->Offset); + + if (pConfig->OffsetNumber != ADC_OFFSET_NONE) + { + /* Set ADC selected offset number */ + LL_ADC_SetOffset(hadc->Instance, pConfig->OffsetNumber, pConfig->Channel, tmpOffsetShifted); + + assert_param(IS_ADC_OFFSET_SIGN(pConfig->OffsetSign)); + assert_param(IS_FUNCTIONAL_STATE(pConfig->OffsetSaturation)); + /* Set ADC selected offset sign & saturation */ + LL_ADC_SetOffsetSign(hadc->Instance, pConfig->OffsetNumber, pConfig->OffsetSign); + LL_ADC_SetOffsetSaturation(hadc->Instance, pConfig->OffsetNumber, + (pConfig->OffsetSaturation == ENABLE) ? + LL_ADC_OFFSET_SATURATION_ENABLE : LL_ADC_OFFSET_SATURATION_DISABLE); + } + else + { + /* Scan each offset register to check if the selected channel is targeted. */ + /* If this is the case, the corresponding offset number is disabled. */ + if (__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_1)) + == __LL_ADC_CHANNEL_TO_DECIMAL_NB(pConfig->Channel)) + { + LL_ADC_SetOffsetState(hadc->Instance, LL_ADC_OFFSET_1, LL_ADC_OFFSET_DISABLE); + } + if (__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_2)) + == __LL_ADC_CHANNEL_TO_DECIMAL_NB(pConfig->Channel)) + { + LL_ADC_SetOffsetState(hadc->Instance, LL_ADC_OFFSET_2, LL_ADC_OFFSET_DISABLE); + } + if (__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_3)) + == __LL_ADC_CHANNEL_TO_DECIMAL_NB(pConfig->Channel)) + { + LL_ADC_SetOffsetState(hadc->Instance, LL_ADC_OFFSET_3, LL_ADC_OFFSET_DISABLE); + } + if (__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_4)) + == __LL_ADC_CHANNEL_TO_DECIMAL_NB(pConfig->Channel)) + { + LL_ADC_SetOffsetState(hadc->Instance, LL_ADC_OFFSET_4, LL_ADC_OFFSET_DISABLE); + } + } + } + + /* Parameters update conditioned to ADC state: */ + /* Parameters that can be updated only when ADC is disabled: */ + /* - Single or differential mode */ + if (LL_ADC_IsEnabled(hadc->Instance) == 0UL) + { + /* Set mode single-ended or differential input of the selected ADC channel */ + LL_ADC_SetChannelSingleDiff(hadc->Instance, pConfig->Channel, pConfig->SingleDiff); + + /* Configuration of differential mode */ + if (pConfig->SingleDiff == ADC_DIFFERENTIAL_ENDED) + { + /* Set sampling time of the selected ADC channel */ + /* Note: ADC channel number masked with value "0x1F" to ensure shift value within 32 bits range */ + LL_ADC_SetChannelSamplingTime(hadc->Instance, + (uint32_t)(__LL_ADC_DECIMAL_NB_TO_CHANNEL( + (__LL_ADC_CHANNEL_TO_DECIMAL_NB((uint32_t)pConfig->Channel) + + 1UL) & 0x1FUL)), + pConfig->SamplingTime); + } + + } + + /* Management of internal measurement channels: Vbat/VrefInt/TempSensor. */ + /* If internal channel selected, enable dedicated internal buffers and */ + /* paths. */ + /* Note: these internal measurement paths can be disabled using */ + /* HAL_ADC_DeInit(). */ + + if (__LL_ADC_IS_CHANNEL_INTERNAL(pConfig->Channel)) + { + tmp_config_internal_channel = LL_ADC_GetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance)); + + /* If the requested internal measurement path has already been enabled, */ + /* bypass the configuration processing. */ + if ((pConfig->Channel == ADC_CHANNEL_TEMPSENSOR) + && ((tmp_config_internal_channel & LL_ADC_PATH_INTERNAL_TEMPSENSOR) == 0UL)) + { + if (ADC_TEMPERATURE_SENSOR_INSTANCE(hadc)) + { + LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance), + LL_ADC_PATH_INTERNAL_TEMPSENSOR | tmp_config_internal_channel); + + /* Delay for temperature sensor stabilization time */ + /* Wait loop initialization and execution */ + /* Note: Variable divided by 2 to compensate partially */ + /* CPU processing cycles, scaling in us split to not */ + /* exceed 32 bits register capacity and handle low frequency. */ + wait_loop_index = ((LL_ADC_DELAY_TEMPSENSOR_STAB_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL)); + while (wait_loop_index != 0UL) + { + wait_loop_index--; + } + } + } + else if ((pConfig->Channel == ADC_CHANNEL_VBAT) + && ((tmp_config_internal_channel & LL_ADC_PATH_INTERNAL_VBAT) == 0UL)) + { + if (ADC_BATTERY_VOLTAGE_INSTANCE(hadc)) + { + LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance), + LL_ADC_PATH_INTERNAL_VBAT | tmp_config_internal_channel); + } + } + else if ((pConfig->Channel == ADC_CHANNEL_VREFINT) + && ((tmp_config_internal_channel & LL_ADC_PATH_INTERNAL_VREFINT) == 0UL)) + { + if (ADC_VREFINT_INSTANCE(hadc)) + { + LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance), + LL_ADC_PATH_INTERNAL_VREFINT | tmp_config_internal_channel); + } + } + else if (pConfig->Channel == ADC_CHANNEL_VDDCORE) + { + if (ADC_VDDCORE_INSTANCE(hadc)) + { + LL_ADC_EnableChannelVDDcore(hadc->Instance); + } + } + else + { + /* nothing to do */ + } + } + } + + /* If a conversion is on going on regular group, no update on regular */ + /* channel could be done on neither of the channel configuration structure */ + /* parameters. */ + 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 Configure the analog watchdog. + * @note Possibility to update parameters on the fly: + * This function initializes the selected analog watchdog, successive + * calls to this function can be used to reconfigure some parameters + * of structure "ADC_AnalogWDGConfTypeDef" on the fly, without resetting + * the ADC. + * The setting of these parameters is conditioned to ADC state. + * For parameters constraints, see comments of structure + * "ADC_AnalogWDGConfTypeDef". + * @note On this STM32 series, 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 ADC handle + * @param pAnalogWDGConfig Structure of ADC analog watchdog configuration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef *hadc, const ADC_AnalogWDGConfTypeDef *pAnalogWDGConfig) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + uint32_t tmp_awd_high_threshold_shifted; + uint32_t tmp_awd_low_threshold_shifted; + uint32_t tmp_adc_is_conversion_on_going_regular; + uint32_t tmp_adc_is_conversion_on_going_injected; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + assert_param(IS_ADC_ANALOG_WATCHDOG_NUMBER(pAnalogWDGConfig->WatchdogNumber)); + assert_param(IS_ADC_ANALOG_WATCHDOG_MODE(pAnalogWDGConfig->WatchdogMode)); + assert_param(IS_ADC_ANALOG_WATCHDOG_FILTERING_MODE(pAnalogWDGConfig->FilteringConfig)); + assert_param(IS_FUNCTIONAL_STATE(pAnalogWDGConfig->ITMode)); + + if ((pAnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REG) || + (pAnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_INJEC) || + (pAnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REGINJEC)) + { + assert_param(IS_ADC_CHANNEL(hadc, pAnalogWDGConfig->Channel)); + } + + /* Verify thresholds range */ + if (hadc->Init.OversamplingMode == ENABLE) + { + /* Case of oversampling enabled: depending on ratio and shift configuration, + analog watchdog thresholds can be higher than ADC resolution. + Verify if thresholds are within maximum thresholds range. */ + assert_param(IS_ADC_RANGE(ADC_RESOLUTION_12B, pAnalogWDGConfig->HighThreshold)); + assert_param(IS_ADC_RANGE(ADC_RESOLUTION_12B, pAnalogWDGConfig->LowThreshold)); + } + else + { + /* Verify if thresholds are within the selected ADC resolution */ + assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), pAnalogWDGConfig->HighThreshold)); + assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), pAnalogWDGConfig->LowThreshold)); + } + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Parameters update conditioned to ADC state: */ + /* Parameters that can be updated when ADC is disabled or enabled without */ + /* conversion on going on ADC groups regular and injected: */ + /* - Analog watchdog channels */ + tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance); + tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance); + if ((tmp_adc_is_conversion_on_going_regular == 0UL) + && (tmp_adc_is_conversion_on_going_injected == 0UL) + ) + { + /* Analog watchdog configuration */ + if (pAnalogWDGConfig->WatchdogNumber == ADC_ANALOGWATCHDOG_1) + { + /* Configuration of analog watchdog: */ + /* - Set the analog watchdog enable mode: one or overall group of */ + /* channels, on groups regular and-or injected. */ + switch (pAnalogWDGConfig->WatchdogMode) + { + case ADC_ANALOGWATCHDOG_SINGLE_REG: + LL_ADC_SetAnalogWDMonitChannels(hadc->Instance, LL_ADC_AWD1, + __LL_ADC_ANALOGWD_CHANNEL_GROUP(pAnalogWDGConfig->Channel, + LL_ADC_GROUP_REGULAR)); + break; + + case ADC_ANALOGWATCHDOG_SINGLE_INJEC: + LL_ADC_SetAnalogWDMonitChannels(hadc->Instance, LL_ADC_AWD1, + __LL_ADC_ANALOGWD_CHANNEL_GROUP(pAnalogWDGConfig->Channel, + LL_ADC_GROUP_INJECTED)); + break; + + case ADC_ANALOGWATCHDOG_SINGLE_REGINJEC: + LL_ADC_SetAnalogWDMonitChannels(hadc->Instance, LL_ADC_AWD1, + __LL_ADC_ANALOGWD_CHANNEL_GROUP(pAnalogWDGConfig->Channel, + LL_ADC_GROUP_REGULAR_INJECTED)); + break; + + case ADC_ANALOGWATCHDOG_ALL_REG: + LL_ADC_SetAnalogWDMonitChannels(hadc->Instance, LL_ADC_AWD1, LL_ADC_AWD_ALL_CHANNELS_REG); + break; + + case ADC_ANALOGWATCHDOG_ALL_INJEC: + LL_ADC_SetAnalogWDMonitChannels(hadc->Instance, LL_ADC_AWD1, LL_ADC_AWD_ALL_CHANNELS_INJ); + break; + + case ADC_ANALOGWATCHDOG_ALL_REGINJEC: + LL_ADC_SetAnalogWDMonitChannels(hadc->Instance, LL_ADC_AWD1, LL_ADC_AWD_ALL_CHANNELS_REG_INJ); + break; + + default: /* ADC_ANALOGWATCHDOG_NONE */ + LL_ADC_SetAnalogWDMonitChannels(hadc->Instance, LL_ADC_AWD1, LL_ADC_AWD_DISABLE); + break; + } + + /* Set the filtering configuration */ + MODIFY_REG(hadc->Instance->TR1, + ADC_TR1_AWDFILT, + pAnalogWDGConfig->FilteringConfig); + + /* Update state, clear previous result related to AWD1 */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_AWD1); + + /* Clear flag ADC analog watchdog */ + /* Note: Flag cleared Clear the ADC Analog watchdog flag to be ready */ + /* to use for HAL_ADC_IRQHandler() or HAL_ADC_PollForEvent() */ + /* (in case left enabled by previous ADC operations). */ + LL_ADC_ClearFlag_AWD1(hadc->Instance); + + /* Configure ADC analog watchdog interrupt */ + if (pAnalogWDGConfig->ITMode == ENABLE) + { + LL_ADC_EnableIT_AWD1(hadc->Instance); + } + else + { + LL_ADC_DisableIT_AWD1(hadc->Instance); + } + } + /* Case of ADC_ANALOGWATCHDOG_2 or ADC_ANALOGWATCHDOG_3 */ + else + { + switch (pAnalogWDGConfig->WatchdogMode) + { + case ADC_ANALOGWATCHDOG_SINGLE_REG: + case ADC_ANALOGWATCHDOG_SINGLE_INJEC: + case ADC_ANALOGWATCHDOG_SINGLE_REGINJEC: + /* Update AWD by bitfield to keep the possibility to monitor */ + /* several channels by successive calls of this function. */ + if (pAnalogWDGConfig->WatchdogNumber == ADC_ANALOGWATCHDOG_2) + { + SET_BIT(hadc->Instance->AWD2CR, + (1UL << (__LL_ADC_CHANNEL_TO_DECIMAL_NB(pAnalogWDGConfig->Channel) & 0x1FUL))); + } + else + { + SET_BIT(hadc->Instance->AWD3CR, + (1UL << (__LL_ADC_CHANNEL_TO_DECIMAL_NB(pAnalogWDGConfig->Channel) & 0x1FUL))); + } + break; + + case ADC_ANALOGWATCHDOG_ALL_REG: + case ADC_ANALOGWATCHDOG_ALL_INJEC: + case ADC_ANALOGWATCHDOG_ALL_REGINJEC: + LL_ADC_SetAnalogWDMonitChannels(hadc->Instance, + pAnalogWDGConfig->WatchdogNumber, LL_ADC_AWD_ALL_CHANNELS_REG_INJ); + break; + + default: /* ADC_ANALOGWATCHDOG_NONE */ + LL_ADC_SetAnalogWDMonitChannels(hadc->Instance, pAnalogWDGConfig->WatchdogNumber, LL_ADC_AWD_DISABLE); + break; + } + + if (pAnalogWDGConfig->WatchdogNumber == ADC_ANALOGWATCHDOG_2) + { + /* Update state, clear previous result related to AWD2 */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_AWD2); + + /* Clear flag ADC analog watchdog */ + /* Note: Flag cleared Clear the ADC Analog watchdog flag to be ready */ + /* to use for HAL_ADC_IRQHandler() or HAL_ADC_PollForEvent() */ + /* (in case left enabled by previous ADC operations). */ + LL_ADC_ClearFlag_AWD2(hadc->Instance); + + /* Configure ADC analog watchdog interrupt */ + if (pAnalogWDGConfig->ITMode == ENABLE) + { + LL_ADC_EnableIT_AWD2(hadc->Instance); + } + else + { + LL_ADC_DisableIT_AWD2(hadc->Instance); + } + } + /* (pAnalogWDGConfig->WatchdogNumber == ADC_ANALOGWATCHDOG_3) */ + else + { + /* Update state, clear previous result related to AWD3 */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_AWD3); + + /* Clear flag ADC analog watchdog */ + /* Note: Flag cleared Clear the ADC Analog watchdog flag to be ready */ + /* to use for HAL_ADC_IRQHandler() or HAL_ADC_PollForEvent() */ + /* (in case left enabled by previous ADC operations). */ + LL_ADC_ClearFlag_AWD3(hadc->Instance); + + /* Configure ADC analog watchdog interrupt */ + if (pAnalogWDGConfig->ITMode == ENABLE) + { + LL_ADC_EnableIT_AWD3(hadc->Instance); + } + else + { + LL_ADC_DisableIT_AWD3(hadc->Instance); + } + } + } + + } + + /* Analog watchdog thresholds configuration */ + if (pAnalogWDGConfig->WatchdogNumber == ADC_ANALOGWATCHDOG_1) + { + /* Shift the offset with respect to the selected ADC resolution: */ + /* Thresholds have to be left-aligned on bit 11, the LSB (right bits) */ + /* are set to 0. */ + tmp_awd_high_threshold_shifted = ADC_AWD1THRESHOLD_SHIFT_RESOLUTION(hadc, pAnalogWDGConfig->HighThreshold); + tmp_awd_low_threshold_shifted = ADC_AWD1THRESHOLD_SHIFT_RESOLUTION(hadc, pAnalogWDGConfig->LowThreshold); + } + /* Case of ADC_ANALOGWATCHDOG_2 and ADC_ANALOGWATCHDOG_3 */ + else + { + /* Shift the offset with respect to the selected ADC resolution: */ + /* Thresholds have to be left-aligned on bit 7, the LSB (right bits) */ + /* are set to 0. */ + tmp_awd_high_threshold_shifted = ADC_AWD23THRESHOLD_SHIFT_RESOLUTION(hadc, pAnalogWDGConfig->HighThreshold); + tmp_awd_low_threshold_shifted = ADC_AWD23THRESHOLD_SHIFT_RESOLUTION(hadc, pAnalogWDGConfig->LowThreshold); + } + + /* Set ADC analog watchdog thresholds value of both thresholds high and low */ + LL_ADC_ConfigAnalogWDThresholds(hadc->Instance, pAnalogWDGConfig->WatchdogNumber, tmp_awd_high_threshold_shifted, + tmp_awd_low_threshold_shifted); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return tmp_hal_status; +} + + +/** + * @} + */ + +/** @defgroup ADC_Exported_Functions_Group4 Peripheral State functions + * @brief ADC Peripheral State functions + * +@verbatim + =============================================================================== + ##### Peripheral state and errors functions ##### + =============================================================================== + [..] + This subsection provides functions to get in run-time the status of the + peripheral. + (+) Check the ADC state + (+) Check the ADC error code + +@endverbatim + * @{ + */ + +/** + * @brief Return the ADC handle state. + * @note ADC state machine is managed by bitfields, ADC status must be + * compared with states bits. + * For example: + * " if ((HAL_ADC_GetState(hadc1) & HAL_ADC_STATE_REG_BUSY) != 0UL) " + * " if ((HAL_ADC_GetState(hadc1) & HAL_ADC_STATE_AWD1) != 0UL) " + * @param hadc ADC handle + * @retval ADC handle state (bitfield on 32 bits) + */ +uint32_t HAL_ADC_GetState(const ADC_HandleTypeDef *hadc) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Return ADC handle state */ + return hadc->State; +} + +/** + * @brief Return the ADC error code. + * @param hadc ADC handle + * @retval ADC error code (bitfield on 32 bits) + */ +uint32_t HAL_ADC_GetError(const ADC_HandleTypeDef *hadc) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + return hadc->ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup ADC_Private_Functions ADC Private Functions + * @{ + */ + +/** + * @brief Stop ADC conversion. + * @param hadc ADC handle + * @param ConversionGroup ADC group regular and/or injected. + * This parameter can be one of the following values: + * @arg @ref ADC_REGULAR_GROUP ADC regular conversion type. + * @arg @ref ADC_INJECTED_GROUP ADC injected conversion type. + * @arg @ref ADC_REGULAR_INJECTED_GROUP ADC regular and injected conversion type. + * @retval HAL status. + */ +HAL_StatusTypeDef ADC_ConversionStop(ADC_HandleTypeDef *hadc, uint32_t ConversionGroup) +{ + uint32_t tickstart; + uint32_t Conversion_Timeout_CPU_cycles = 0UL; + uint32_t conversion_group_reassigned = ConversionGroup; + uint32_t tmp_ADC_CR_ADSTART_JADSTART; + uint32_t tmp_adc_is_conversion_on_going_regular; + uint32_t tmp_adc_is_conversion_on_going_injected; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + assert_param(IS_ADC_CONVERSION_GROUP(ConversionGroup)); + + /* Verification if ADC is not already stopped (on regular and injected */ + /* groups) to bypass this function if not needed. */ + tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance); + tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance); + if ((tmp_adc_is_conversion_on_going_regular != 0UL) + || (tmp_adc_is_conversion_on_going_injected != 0UL) + ) + { + /* Particular case of continuous auto-injection mode combined with */ + /* auto-delay mode. */ + /* In auto-injection mode, regular group stop ADC_CR_ADSTP is used (not */ + /* injected group stop ADC_CR_JADSTP). */ + /* Procedure to be followed: Wait until JEOS=1, clear JEOS, set ADSTP=1 */ + /* (see reference manual). */ + if (((hadc->Instance->CFGR & ADC_CFGR_JAUTO) != 0UL) + && (hadc->Init.ContinuousConvMode == ENABLE) + && (hadc->Init.LowPowerAutoWait == ENABLE) + ) + { + /* Use stop of regular group */ + conversion_group_reassigned = ADC_REGULAR_GROUP; + + /* Wait until JEOS=1 (maximum Timeout: 4 injected conversions) */ + while (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOS) == 0UL) + { + if (Conversion_Timeout_CPU_cycles >= (ADC_CONVERSION_TIME_MAX_CPU_CYCLES * 4UL)) + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + + /* Set ADC error code to ADC peripheral internal error */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); + + return HAL_ERROR; + } + Conversion_Timeout_CPU_cycles ++; + } + + /* Clear JEOS */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOS); + } + + /* Stop potential conversion on going on ADC group regular */ + if (conversion_group_reassigned != ADC_INJECTED_GROUP) + { + /* Software is allowed to set ADSTP only when ADSTART=1 and ADDIS=0 */ + if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) != 0UL) + { + if (LL_ADC_IsDisableOngoing(hadc->Instance) == 0UL) + { + /* Stop ADC group regular conversion */ + LL_ADC_REG_StopConversion(hadc->Instance); + } + } + } + + /* Stop potential conversion on going on ADC group injected */ + if (conversion_group_reassigned != ADC_REGULAR_GROUP) + { + /* Software is allowed to set JADSTP only when JADSTART=1 and ADDIS=0 */ + if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) != 0UL) + { + if (LL_ADC_IsDisableOngoing(hadc->Instance) == 0UL) + { + /* Stop ADC group injected conversion */ + LL_ADC_INJ_StopConversion(hadc->Instance); + } + } + } + + /* Selection of start and stop bits with respect to the regular or injected group */ + switch (conversion_group_reassigned) + { + case ADC_REGULAR_INJECTED_GROUP: + tmp_ADC_CR_ADSTART_JADSTART = (ADC_CR_ADSTART | ADC_CR_JADSTART); + break; + case ADC_INJECTED_GROUP: + tmp_ADC_CR_ADSTART_JADSTART = ADC_CR_JADSTART; + break; + /* Case ADC_REGULAR_GROUP only*/ + default: + tmp_ADC_CR_ADSTART_JADSTART = ADC_CR_ADSTART; + break; + } + + /* Wait for conversion effectively stopped */ + tickstart = HAL_GetTick(); + + while ((hadc->Instance->CR & tmp_ADC_CR_ADSTART_JADSTART) != 0UL) + { + if ((HAL_GetTick() - tickstart) > ADC_STOP_CONVERSION_TIMEOUT) + { + /* New check to avoid false timeout detection in case of preemption */ + if ((hadc->Instance->CR & tmp_ADC_CR_ADSTART_JADSTART) != 0UL) + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + + /* Set ADC error code to ADC peripheral internal error */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); + + return HAL_ERROR; + } + } + } + + } + + /* Return HAL status */ + return HAL_OK; +} + +/** + * @brief Enable the selected ADC. + * @note Prerequisite condition to use this function: ADC must be disabled + * and voltage regulator must be enabled (done into HAL_ADC_Init()). + * @param hadc ADC handle + * @retval HAL status. + */ +HAL_StatusTypeDef ADC_Enable(ADC_HandleTypeDef *hadc) +{ + uint32_t tickstart; + __IO uint32_t wait_loop_index = 0UL; + + /* ADC enable and wait for ADC ready (in case of ADC is disabled or */ + /* enabling phase not yet completed: flag ADC ready not yet set). */ + /* Timeout implemented to not be stuck if ADC cannot be enabled (possible */ + /* causes: ADC clock not running, ...). */ + if (LL_ADC_IsEnabled(hadc->Instance) == 0UL) + { + /* Check if conditions to enable the ADC are fulfilled */ + if ((hadc->Instance->CR & (ADC_CR_ADCAL | ADC_CR_JADSTP | ADC_CR_ADSTP | ADC_CR_JADSTART | ADC_CR_ADSTART + | ADC_CR_ADDIS | ADC_CR_ADEN)) != 0UL) + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + + /* Set ADC error code to ADC peripheral internal error */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); + + return HAL_ERROR; + } + + /* Enable the ADC peripheral */ + LL_ADC_Enable(hadc->Instance); + + if ((LL_ADC_GetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance)) + & LL_ADC_PATH_INTERNAL_TEMPSENSOR) != 0UL) + { + /* Delay for temperature sensor buffer stabilization time */ + /* Note: Value LL_ADC_DELAY_TEMPSENSOR_STAB_US used instead of */ + /* LL_ADC_DELAY_TEMPSENSOR_BUFFER_STAB_US because needed */ + /* in case of ADC enable after a system wake up */ + /* from low power mode. */ + + /* Wait loop initialization and execution */ + /* Note: Variable divided by 2 to compensate partially */ + /* CPU processing cycles, scaling in us split to not */ + /* exceed 32 bits register capacity and handle low frequency. */ + wait_loop_index = ((LL_ADC_DELAY_TEMPSENSOR_STAB_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL)); + while (wait_loop_index != 0UL) + { + wait_loop_index--; + } + } + + /* Wait for ADC effectively enabled */ + tickstart = HAL_GetTick(); + + while (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_RDY) == 0UL) + { + /* If ADEN bit is set less than 4 ADC clock cycles after the ADCAL bit + has been cleared (after a calibration), ADEN bit is reset by the + calibration logic. + The workaround is to continue setting ADEN until ADRDY is becomes 1. + Additionally, ADC_ENABLE_TIMEOUT is defined to encompass this + 4 ADC clock cycle duration */ + /* Note: Test of ADC enabled required due to hardware constraint to */ + /* not enable ADC if already enabled. */ + if (LL_ADC_IsEnabled(hadc->Instance) == 0UL) + { + LL_ADC_Enable(hadc->Instance); + } + + if ((HAL_GetTick() - tickstart) > ADC_ENABLE_TIMEOUT) + { + /* New check to avoid false timeout detection in case of preemption */ + if (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_RDY) == 0UL) + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + + /* Set ADC error code to ADC peripheral internal error */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); + + return HAL_ERROR; + } + } + } + } + + /* Return HAL status */ + return HAL_OK; +} + +/** + * @brief Disable the selected ADC. + * @note Prerequisite condition to use this function: ADC conversions must be + * stopped. + * @param hadc ADC handle + * @retval HAL status. + */ +HAL_StatusTypeDef ADC_Disable(ADC_HandleTypeDef *hadc) +{ + uint32_t tickstart; + const uint32_t tmp_adc_is_disable_on_going = LL_ADC_IsDisableOngoing(hadc->Instance); + + /* Verification if ADC is not already disabled: */ + /* Note: forbidden to disable ADC (set bit ADC_CR_ADDIS) if ADC is already */ + /* disabled. */ + if ((LL_ADC_IsEnabled(hadc->Instance) != 0UL) + && (tmp_adc_is_disable_on_going == 0UL) + ) + { + /* Check if conditions to disable the ADC are fulfilled */ + if ((hadc->Instance->CR & (ADC_CR_JADSTART | ADC_CR_ADSTART | ADC_CR_ADEN)) == ADC_CR_ADEN) + { + /* Disable the ADC peripheral */ + LL_ADC_Disable(hadc->Instance); + __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOSMP | ADC_FLAG_RDY)); + } + else + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + + /* Set ADC error code to ADC peripheral internal error */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); + + return HAL_ERROR; + } + + /* Wait for ADC effectively disabled */ + /* Get tick count */ + tickstart = HAL_GetTick(); + + while ((hadc->Instance->CR & ADC_CR_ADEN) != 0UL) + { + if ((HAL_GetTick() - tickstart) > ADC_DISABLE_TIMEOUT) + { + /* New check to avoid false timeout detection in case of preemption */ + if ((hadc->Instance->CR & ADC_CR_ADEN) != 0UL) + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + + /* Set ADC error code to ADC peripheral internal error */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); + + return HAL_ERROR; + } + } + } + } + + /* Return HAL status */ + return HAL_OK; +} + +/** + * @brief DMA transfer complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +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 ((hadc->State & (HAL_ADC_STATE_ERROR_INTERNAL | HAL_ADC_STATE_ERROR_DMA)) == 0UL) + { + /* 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 */ + /* to disable interruption. */ + /* Is it the end of the regular sequence ? */ + if ((hadc->Instance->ISR & ADC_FLAG_EOS) != 0UL) + { + /* Are conversions software-triggered ? */ + if (LL_ADC_REG_IsTriggerSourceSWStart(hadc->Instance) != 0UL) + { + /* Is CONT bit set ? */ + if (READ_BIT(hadc->Instance->CFGR, ADC_CFGR_CONT) == 0UL) + { + /* CONT bit is not set, no more conversions expected */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY); + if ((hadc->State & HAL_ADC_STATE_INJ_BUSY) == 0UL) + { + SET_BIT(hadc->State, HAL_ADC_STATE_READY); + } + } + } + } + else + { + /* DMA End of Transfer interrupt was triggered but conversions sequence + is not over. If DMACFG is set to 0, conversions are stopped. */ + if (READ_BIT(hadc->Instance->CFGR, ADC_CFGR_DMACFG) == 0UL) + { + /* DMACFG bit is not set, conversions are stopped. */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY); + if ((hadc->State & HAL_ADC_STATE_INJ_BUSY) == 0UL) + { + 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 ADC DMA error callback */ + hadc->DMA_Handle->XferErrorCallback(hdma); + } + } +} + +/** + * @brief DMA half transfer complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +void ADC_DMAHalfConvCplt(DMA_HandleTypeDef *hdma) +{ + /* Retrieve ADC handle corresponding to current DMA handle */ + 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 DMA handle. + * @retval None + */ +void ADC_DMAError(DMA_HandleTypeDef *hdma) +{ + /* Retrieve ADC handle corresponding to current DMA handle */ + ADC_HandleTypeDef *hadc = (ADC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_DMA); + + /* Set ADC error code to DMA error */ + SET_BIT(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/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_adc_ex.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_adc_ex.c new file mode 100644 index 0000000000..9fb60dca32 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_adc_ex.c @@ -0,0 +1,2452 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_adc_ex.c + * @author MCD Application Team + * @brief This file provides firmware functions to manage the following + * functionalities of the Analog to Digital Converter (ADC) + * peripheral: + * + Peripheral Control functions + * Other functions (generic functions) are available in file + * "stm32h5xx_hal_adc.c". + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + [..] + (@) Sections "ADC peripheral features" and "How to use this driver" are + available in file of generic functions "stm32h5xx_hal_adc.c". + [..] + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup ADCEx ADCEx + * @brief ADC Extended HAL module driver + * @{ + */ + +#ifdef HAL_ADC_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/** @defgroup ADCEx_Private_Constants ADC Extended Private Constants + * @{ + */ + +#define ADC_JSQR_FIELDS ((ADC_JSQR_JL | ADC_JSQR_JEXTSEL | ADC_JSQR_JEXTEN |\ + ADC_JSQR_JSQ1 | ADC_JSQR_JSQ2 |\ + ADC_JSQR_JSQ3 | ADC_JSQR_JSQ4 )) /*!< ADC_JSQR fields of parameters that can + be updated anytime once the ADC is enabled */ + +/* Fixed timeout value for ADC calibration. */ +/* Fixed timeout value for ADC calibration. */ +/* Values defined to be higher than worst cases: low clock frequency, */ +/* maximum prescalers. */ +/* Ex of profile low frequency : f_ADC at 0.125 Mhz (minimum value */ +/* according to Data sheet), calibration_time MAX = 165010 / f_ADC */ +/* 165010 / 125000 = 1.32s */ +/* At maximum CPU speed (480 MHz), this means */ +/* 1.32 * 480 MHz = 633600000 CPU cycles */ +#define ADC_CALIBRATION_TIMEOUT (633600000UL) /*!< ADC calibration time-out value */ + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup ADCEx_Exported_Functions ADC Extended Exported Functions + * @{ + */ + +/** @defgroup ADCEx_Exported_Functions_Group1 Extended Input and Output operation functions + * @brief Extended IO operation functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] This section provides functions allowing to: + + (+) Perform the ADC self-calibration for single or differential ending. + (+) Get calibration factors for single or differential ending. + (+) Set calibration factors for single or differential ending. + + (+) Start conversion of ADC group injected. + (+) Stop conversion of ADC group injected. + (+) Poll for conversion complete on ADC group injected. + (+) Get result of ADC group injected channel conversion. + (+) Start conversion of ADC group injected and enable interruptions. + (+) Stop conversion of ADC group injected and disable interruptions. + + (+) When multimode feature is available, start multimode and enable DMA transfer. + (+) Stop multimode and disable ADC DMA transfer. + (+) Get result of multimode conversion. + +@endverbatim + * @{ + */ + +/** + * @brief Perform an ADC automatic self-calibration + * Calibration prerequisite: ADC must be disabled (execute this + * function before HAL_ADC_Start() or after HAL_ADC_Stop() ). + * @param hadc ADC handle + * @param SingleDiff Selection of single-ended or differential input + * This parameter can be one of the following values: + * @arg @ref ADC_SINGLE_ENDED Channel in mode input single ended + * @arg @ref ADC_DIFFERENTIAL_ENDED Channel in mode input differential ended + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef *hadc, uint32_t SingleDiff) +{ + HAL_StatusTypeDef tmp_hal_status; + __IO uint32_t wait_loop_index = 0UL; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + assert_param(IS_ADC_SINGLE_DIFFERENTIAL(SingleDiff)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Calibration prerequisite: ADC must be disabled. */ + + /* Disable the ADC (if not already disabled) */ + tmp_hal_status = ADC_Disable(hadc); + + /* Check if ADC is effectively disabled */ + if (tmp_hal_status == HAL_OK) + { + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY, + HAL_ADC_STATE_BUSY_INTERNAL); + + /* Start ADC calibration in mode single-ended or differential */ + LL_ADC_StartCalibration(hadc->Instance, SingleDiff); + + /* Wait for calibration completion */ + while (LL_ADC_IsCalibrationOnGoing(hadc->Instance) != 0UL) + { + wait_loop_index++; + if (wait_loop_index >= ADC_CALIBRATION_TIMEOUT) + { + /* Update ADC state machine to error */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_BUSY_INTERNAL, + HAL_ADC_STATE_ERROR_INTERNAL); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + return HAL_ERROR; + } + } + + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_BUSY_INTERNAL, + HAL_ADC_STATE_READY); + } + else + { + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + + /* Note: No need to update variable "tmp_hal_status" here: already set */ + /* to state "HAL_ERROR" by function disabling the ADC. */ + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Get the calibration factor. + * @param hadc ADC handle. + * @param SingleDiff This parameter can be only: + * @arg @ref ADC_SINGLE_ENDED Channel in mode input single ended + * @arg @ref ADC_DIFFERENTIAL_ENDED Channel in mode input differential ended + * @retval Calibration value. + */ +uint32_t HAL_ADCEx_Calibration_GetValue(const ADC_HandleTypeDef *hadc, uint32_t SingleDiff) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + assert_param(IS_ADC_SINGLE_DIFFERENTIAL(SingleDiff)); + + /* Return the selected ADC calibration value */ + return LL_ADC_GetCalibrationFactor(hadc->Instance, SingleDiff); +} + +/** + * @brief Set the calibration factor to overwrite automatic conversion result. + * ADC must be enabled and no conversion is ongoing. + * @param hadc ADC handle + * @param SingleDiff This parameter can be only: + * @arg @ref ADC_SINGLE_ENDED Channel in mode input single ended + * @arg @ref ADC_DIFFERENTIAL_ENDED Channel in mode input differential ended + * @param CalibrationFactor Calibration factor (coded on 7 bits maximum) + * @retval HAL state + */ +HAL_StatusTypeDef HAL_ADCEx_Calibration_SetValue(ADC_HandleTypeDef *hadc, uint32_t SingleDiff, + uint32_t CalibrationFactor) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + uint32_t tmp_adc_is_conversion_on_going_regular; + uint32_t tmp_adc_is_conversion_on_going_injected; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + assert_param(IS_ADC_SINGLE_DIFFERENTIAL(SingleDiff)); + assert_param(IS_ADC_CALFACT(CalibrationFactor)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Verification of hardware constraints before modifying the calibration */ + /* factors register: ADC must be enabled, no conversion on going. */ + tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance); + tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance); + + if ((LL_ADC_IsEnabled(hadc->Instance) != 0UL) + && (tmp_adc_is_conversion_on_going_regular == 0UL) + && (tmp_adc_is_conversion_on_going_injected == 0UL) + ) + { + /* Set the selected ADC calibration value */ + LL_ADC_SetCalibrationFactor(hadc->Instance, SingleDiff, CalibrationFactor); + } + else + { + /* Update ADC state machine */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); + /* Update ADC error code */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); + + /* Update ADC state machine to error */ + tmp_hal_status = HAL_ERROR; + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Enable ADC, start conversion of injected group. + * @note Interruptions enabled in this function: None. + * @note Case of multimode enabled when multimode feature is available: + * HAL_ADCEx_InjectedStart() API must be called for ADC slave first, + * then for ADC master. + * For ADC slave, ADC is enabled only (conversion is not started). + * For ADC master, ADC is enabled and multimode conversion is started. + * @param hadc ADC handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADCEx_InjectedStart(ADC_HandleTypeDef *hadc) +{ + HAL_StatusTypeDef tmp_hal_status; + uint32_t tmp_config_injected_queue; +#if defined(ADC_MULTIMODE_SUPPORT) + uint32_t tmp_multimode_config = LL_ADC_GetMultimode(__LL_ADC_COMMON_INSTANCE(hadc->Instance)); +#endif /* ADC_MULTIMODE_SUPPORT */ + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) != 0UL) + { + return HAL_BUSY; + } + else + { + /* In case of software trigger detection enabled, JQDIS must be set + (which can be done only if ADSTART and JADSTART are both cleared). + If JQDIS is not set at that point, returns an error + - since software trigger detection is disabled. User needs to + resort to HAL_ADCEx_DisableInjectedQueue() API to set JQDIS. + - or (if JQDIS is intentionally reset) since JEXTEN = 0 which means + the queue is empty */ + tmp_config_injected_queue = READ_BIT(hadc->Instance->CFGR, ADC_CFGR_JQDIS); + + if ((READ_BIT(hadc->Instance->JSQR, ADC_JSQR_JEXTEN) == 0UL) + && (tmp_config_injected_queue == 0UL) + ) + { + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Enable the ADC peripheral */ + tmp_hal_status = ADC_Enable(hadc); + + /* Start conversion if ADC is effectively enabled */ + if (tmp_hal_status == HAL_OK) + { + /* Check if a regular conversion is ongoing */ + if ((hadc->State & HAL_ADC_STATE_REG_BUSY) != 0UL) + { + /* Reset ADC error code field related to injected conversions only */ + CLEAR_BIT(hadc->ErrorCode, HAL_ADC_ERROR_JQOVF); + } + else + { + /* Set ADC error code to none */ + ADC_CLEAR_ERRORCODE(hadc); + } + + /* 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); + +#if defined(ADC_MULTIMODE_SUPPORT) + /* Reset HAL_ADC_STATE_MULTIMODE_SLAVE bit + - if ADC instance is master or if multimode feature is not available + - if multimode setting is disabled (ADC instance slave in independent mode) */ + if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance) + || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT) + ) + { + CLEAR_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE); + } +#endif /* ADC_MULTIMODE_SUPPORT */ + + /* Clear ADC group injected group conversion flag */ + /* (To ensure of no unknown state from potential previous ADC operations) */ + __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_JEOC | ADC_FLAG_JEOS)); + + /* Process unlocked */ + /* Unlock before starting ADC conversions: in case of potential */ + /* interruption, to let the process to ADC IRQ Handler. */ + __HAL_UNLOCK(hadc); + + /* Enable conversion of injected group, if automatic injected conversion */ + /* is disabled. */ + /* If software start has been selected, conversion starts immediately. */ + /* If external trigger has been selected, conversion will start at next */ + /* trigger event. */ + /* Case of multimode enabled (when multimode feature is available): */ + /* if ADC is slave, */ + /* - ADC is enabled only (conversion is not started), */ + /* - if multimode only concerns regular conversion, ADC is enabled */ + /* and conversion is started. */ + /* If ADC is master or independent, */ + /* - ADC is enabled and conversion is started. */ +#if defined(ADC_MULTIMODE_SUPPORT) + if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance) + || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT) + || (tmp_multimode_config == LL_ADC_MULTI_DUAL_REG_SIMULT) + || (tmp_multimode_config == LL_ADC_MULTI_DUAL_REG_INTERL) + ) + { + /* ADC instance is not a multimode slave instance with multimode injected conversions enabled */ + if (LL_ADC_INJ_GetTrigAuto(hadc->Instance) == LL_ADC_INJ_TRIG_INDEPENDENT) + { + LL_ADC_INJ_StartConversion(hadc->Instance); + } + } + else + { + /* ADC instance is not a multimode slave instance with multimode injected conversions enabled */ + SET_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE); + } +#else + if (LL_ADC_INJ_GetTrigAuto(hadc->Instance) == LL_ADC_INJ_TRIG_INDEPENDENT) + { + /* Start ADC group injected conversion */ + LL_ADC_INJ_StartConversion(hadc->Instance); + } +#endif /* ADC_MULTIMODE_SUPPORT */ + + } + else + { + /* Process unlocked */ + __HAL_UNLOCK(hadc); + } + + /* Return function status */ + return tmp_hal_status; + } +} + +/** + * @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 multimode enabled (when multimode feature is available), + * HAL_ADCEx_InjectedStop() must be called for ADC master first, then for ADC slave. + * For ADC master, conversion is stopped and ADC is disabled. + * For ADC slave, ADC is disabled only (conversion stop of ADC master + * has already stopped conversion of ADC slave). + * @param hadc ADC handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADCEx_InjectedStop(ADC_HandleTypeDef *hadc) +{ + HAL_StatusTypeDef tmp_hal_status; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* 1. Stop potential conversion on going on injected group only. */ + tmp_hal_status = ADC_ConversionStop(hadc, ADC_INJECTED_GROUP); + + /* Disable ADC peripheral if injected conversions are effectively stopped */ + /* and if no conversion on regular group is on-going */ + if (tmp_hal_status == HAL_OK) + { + if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL) + { + /* 2. Disable the ADC peripheral */ + tmp_hal_status = ADC_Disable(hadc); + + /* Check if ADC is effectively disabled */ + if (tmp_hal_status == HAL_OK) + { + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY, + HAL_ADC_STATE_READY); + } + } + /* Conversion on injected group is stopped, but ADC not disabled since */ + /* conversion on regular group is still running. */ + else + { + /* Set ADC state */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY); + } + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Wait for injected group conversion to be completed. + * @param hadc ADC handle + * @param Timeout Timeout value in millisecond. + * @note Depending on hadc->Init.EOCSelection, JEOS or JEOC is + * checked and cleared depending on AUTDLY bit status. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADCEx_InjectedPollForConversion(ADC_HandleTypeDef *hadc, uint32_t Timeout) +{ + uint32_t tickstart; + uint32_t tmp_flag_end; + uint32_t tmp_adc_inj_is_trigger_source_sw_start; + uint32_t tmp_adc_reg_is_trigger_source_sw_start; + uint32_t tmp_cfgr; +#if defined(ADC_MULTIMODE_SUPPORT) + const ADC_TypeDef *tmpADC_Master; + uint32_t tmp_multimode_config = LL_ADC_GetMultimode(__LL_ADC_COMMON_INSTANCE(hadc->Instance)); +#endif /* ADC_MULTIMODE_SUPPORT */ + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* If end of sequence selected */ + if (hadc->Init.EOCSelection == ADC_EOC_SEQ_CONV) + { + tmp_flag_end = ADC_FLAG_JEOS; + } + else /* end of conversion selected */ + { + tmp_flag_end = ADC_FLAG_JEOC; + } + + /* Get timeout */ + tickstart = HAL_GetTick(); + + /* Wait until End of Conversion or Sequence flag is raised */ + while ((hadc->Instance->ISR & tmp_flag_end) == 0UL) + { + /* Check if timeout is disabled (set to infinite wait) */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL)) + { + /* New check to avoid false timeout detection in case of preemption */ + if ((hadc->Instance->ISR & tmp_flag_end) == 0UL) + { + /* Update ADC state machine to timeout */ + SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + return HAL_TIMEOUT; + } + } + } + } + + /* Retrieve ADC configuration */ + tmp_adc_inj_is_trigger_source_sw_start = LL_ADC_INJ_IsTriggerSourceSWStart(hadc->Instance); + tmp_adc_reg_is_trigger_source_sw_start = LL_ADC_REG_IsTriggerSourceSWStart(hadc->Instance); + /* Get relevant register CFGR in ADC instance of ADC master or slave */ + /* in function of multimode state (for devices with multimode */ + /* available). */ +#if defined(ADC_MULTIMODE_SUPPORT) + if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance) + || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT) + || (tmp_multimode_config == LL_ADC_MULTI_DUAL_REG_SIMULT) + || (tmp_multimode_config == LL_ADC_MULTI_DUAL_REG_INTERL) + ) + { + tmp_cfgr = READ_REG(hadc->Instance->CFGR); + } + else + { + tmpADC_Master = __LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance); + tmp_cfgr = READ_REG(tmpADC_Master->CFGR); + } +#else + tmp_cfgr = READ_REG(hadc->Instance->CFGR); +#endif /* ADC_MULTIMODE_SUPPORT */ + + /* 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 or by automatic injected conversion */ + /* from group regular. */ + if ((tmp_adc_inj_is_trigger_source_sw_start != 0UL) || + ((READ_BIT(tmp_cfgr, ADC_CFGR_JAUTO) == 0UL) && + ((tmp_adc_reg_is_trigger_source_sw_start != 0UL) && + (READ_BIT(tmp_cfgr, ADC_CFGR_CONT) == 0UL)))) + { + /* Check whether end of sequence is reached */ + if (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOS)) + { + /* Particular case if injected contexts queue is enabled: */ + /* when the last context has been fully processed, JSQR is reset */ + /* by the hardware. Even if no injected conversion is planned to come */ + /* (queue empty, triggers are ignored), it can start again */ + /* immediately after setting a new context (JADSTART is still set). */ + /* Therefore, state of HAL ADC injected group is kept to busy. */ + if (READ_BIT(tmp_cfgr, ADC_CFGR_JQM) == 0UL) + { + /* Set ADC state */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY); + + if ((hadc->State & HAL_ADC_STATE_REG_BUSY) == 0UL) + { + SET_BIT(hadc->State, HAL_ADC_STATE_READY); + } + } + } + } + + /* Clear polled flag */ + if (tmp_flag_end == ADC_FLAG_JEOS) + { + /* Clear end of sequence JEOS flag of injected group if low power feature */ + /* "LowPowerAutoWait " is disabled, to not interfere with this feature. */ + /* For injected groups, no new conversion will start before JEOS is */ + /* cleared. */ + if (READ_BIT(tmp_cfgr, ADC_CFGR_AUTDLY) == 0UL) + { + __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_JEOC | ADC_FLAG_JEOS)); + } + } + else + { + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC); + } + + /* Return API HAL status */ + return HAL_OK; +} + +/** + * @brief Enable ADC, start conversion of injected group with interruption. + * @note Interruptions enabled in this function according to initialization + * setting : JEOC (end of conversion) or JEOS (end of sequence) + * @note Case of multimode enabled (when multimode feature is enabled): + * HAL_ADCEx_InjectedStart_IT() API must be called for ADC slave first, + * then for ADC master. + * For ADC slave, ADC is enabled only (conversion is not started). + * For ADC master, ADC is enabled and multimode conversion is started. + * @param hadc ADC handle. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_ADCEx_InjectedStart_IT(ADC_HandleTypeDef *hadc) +{ + HAL_StatusTypeDef tmp_hal_status; + uint32_t tmp_config_injected_queue; +#if defined(ADC_MULTIMODE_SUPPORT) + uint32_t tmp_multimode_config = LL_ADC_GetMultimode(__LL_ADC_COMMON_INSTANCE(hadc->Instance)); +#endif /* ADC_MULTIMODE_SUPPORT */ + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) != 0UL) + { + return HAL_BUSY; + } + else + { + /* In case of software trigger detection enabled, JQDIS must be set + (which can be done only if ADSTART and JADSTART are both cleared). + If JQDIS is not set at that point, returns an error + - since software trigger detection is disabled. User needs to + resort to HAL_ADCEx_DisableInjectedQueue() API to set JQDIS. + - or (if JQDIS is intentionally reset) since JEXTEN = 0 which means + the queue is empty */ + tmp_config_injected_queue = READ_BIT(hadc->Instance->CFGR, ADC_CFGR_JQDIS); + + if ((READ_BIT(hadc->Instance->JSQR, ADC_JSQR_JEXTEN) == 0UL) + && (tmp_config_injected_queue == 0UL) + ) + { + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Enable the ADC peripheral */ + tmp_hal_status = ADC_Enable(hadc); + + /* Start conversion if ADC is effectively enabled */ + if (tmp_hal_status == HAL_OK) + { + /* Check if a regular conversion is ongoing */ + if ((hadc->State & HAL_ADC_STATE_REG_BUSY) != 0UL) + { + /* Reset ADC error code field related to injected conversions only */ + CLEAR_BIT(hadc->ErrorCode, HAL_ADC_ERROR_JQOVF); + } + else + { + /* Set ADC error code to none */ + ADC_CLEAR_ERRORCODE(hadc); + } + + /* 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); + +#if defined(ADC_MULTIMODE_SUPPORT) + /* Reset HAL_ADC_STATE_MULTIMODE_SLAVE bit + - if ADC instance is master or if multimode feature is not available + - if multimode setting is disabled (ADC instance slave in independent mode) */ + if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance) + || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT) + ) + { + CLEAR_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE); + } +#endif /* ADC_MULTIMODE_SUPPORT */ + + /* Clear ADC group injected group conversion flag */ + /* (To ensure of no unknown state from potential previous ADC operations) */ + __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_JEOC | ADC_FLAG_JEOS)); + + /* Process unlocked */ + /* Unlock before starting ADC conversions: in case of potential */ + /* interruption, to let the process to ADC IRQ Handler. */ + __HAL_UNLOCK(hadc); + + /* Enable ADC Injected context queue overflow interrupt if this feature */ + /* is enabled. */ + if ((hadc->Instance->CFGR & ADC_CFGR_JQM) != 0UL) + { + __HAL_ADC_ENABLE_IT(hadc, ADC_FLAG_JQOVF); + } + + /* Enable ADC end of conversion interrupt */ + switch (hadc->Init.EOCSelection) + { + case ADC_EOC_SEQ_CONV: + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC); + __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOS); + break; + /* case ADC_EOC_SINGLE_CONV */ + default: + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOS); + __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC); + break; + } + + /* Enable conversion of injected group, if automatic injected conversion */ + /* is disabled. */ + /* If software start has been selected, conversion starts immediately. */ + /* If external trigger has been selected, conversion will start at next */ + /* trigger event. */ + /* Case of multimode enabled (when multimode feature is available): */ + /* if ADC is slave, */ + /* - ADC is enabled only (conversion is not started), */ + /* - if multimode only concerns regular conversion, ADC is enabled */ + /* and conversion is started. */ + /* If ADC is master or independent, */ + /* - ADC is enabled and conversion is started. */ +#if defined(ADC_MULTIMODE_SUPPORT) + if ((__LL_ADC_MULTI_INSTANCE_MASTER(hadc->Instance) == hadc->Instance) + || (tmp_multimode_config == LL_ADC_MULTI_INDEPENDENT) + || (tmp_multimode_config == LL_ADC_MULTI_DUAL_REG_SIMULT) + || (tmp_multimode_config == LL_ADC_MULTI_DUAL_REG_INTERL) + ) + { + /* ADC instance is not a multimode slave instance with multimode injected conversions enabled */ + if (LL_ADC_INJ_GetTrigAuto(hadc->Instance) == LL_ADC_INJ_TRIG_INDEPENDENT) + { + LL_ADC_INJ_StartConversion(hadc->Instance); + } + } + else + { + /* ADC instance is not a multimode slave instance with multimode injected conversions enabled */ + SET_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE); + } +#else + if (LL_ADC_INJ_GetTrigAuto(hadc->Instance) == LL_ADC_INJ_TRIG_INDEPENDENT) + { + /* Start ADC group injected conversion */ + LL_ADC_INJ_StartConversion(hadc->Instance); + } +#endif /* ADC_MULTIMODE_SUPPORT */ + + } + else + { + /* Process unlocked */ + __HAL_UNLOCK(hadc); + } + + /* Return function status */ + return tmp_hal_status; + } +} + +/** + * @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. + * @note Case of multimode enabled (when multimode feature is available): + * HAL_ADCEx_InjectedStop_IT() API must be called for ADC master first, + * then for ADC slave. + * For ADC master, conversion is stopped and ADC is disabled. + * For ADC slave, ADC is disabled only (conversion stop of ADC master + * has already stopped conversion of ADC slave). + * @note In case of auto-injection mode, HAL_ADC_Stop() must be used. + * @param hadc ADC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADCEx_InjectedStop_IT(ADC_HandleTypeDef *hadc) +{ + HAL_StatusTypeDef tmp_hal_status; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* 1. Stop potential conversion on going on injected group only. */ + tmp_hal_status = ADC_ConversionStop(hadc, ADC_INJECTED_GROUP); + + /* Disable ADC peripheral if injected conversions are effectively stopped */ + /* and if no conversion on the other group (regular group) is intended to */ + /* continue. */ + if (tmp_hal_status == HAL_OK) + { + /* Disable ADC end of conversion interrupt for injected channels */ + __HAL_ADC_DISABLE_IT(hadc, (ADC_IT_JEOC | ADC_IT_JEOS | ADC_FLAG_JQOVF)); + + if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL) + { + /* 2. Disable the ADC peripheral */ + tmp_hal_status = ADC_Disable(hadc); + + /* Check if ADC is effectively disabled */ + if (tmp_hal_status == HAL_OK) + { + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY, + HAL_ADC_STATE_READY); + } + } + /* Conversion on injected group is stopped, but ADC not disabled since */ + /* conversion on regular group is still running. */ + else + { + /* Set ADC state */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY); + } + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return tmp_hal_status; +} + +#if defined(ADC_MULTIMODE_SUPPORT) +/** + * @brief Enable ADC, start MultiMode conversion and transfer regular results through DMA. + * @note Multimode must have been previously configured using + * HAL_ADCEx_MultiModeConfigChannel() function. + * Interruptions enabled in this function: + * overrun, DMA half transfer, DMA transfer complete. + * Each of these interruptions has its dedicated callback function. + * @note State field of Slave ADC handle is not updated in this configuration: + * user should not rely on it for information related to Slave regular + * conversions. + * @param hadc ADC handle of ADC master (handle of ADC slave must not be used) + * @param pData Destination Buffer address. + * @param Length Length of data to be transferred from ADC peripheral to memory (in bytes). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADCEx_MultiModeStart_DMA(ADC_HandleTypeDef *hadc, uint32_t *pData, uint32_t Length) +{ + HAL_StatusTypeDef tmp_hal_status; + ADC_HandleTypeDef tmp_hadc_slave; + ADC_Common_TypeDef *tmpADC_Common; + uint32_t length_bytes; + DMA_NodeConfTypeDef node_conf; + + /* Check the parameters */ + assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance)); + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode)); + assert_param(IS_ADC_EXTTRIG_EDGE(hadc->Init.ExternalTrigConvEdge)); + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DMAContinuousRequests)); + + if (LL_ADC_REG_IsConversionOngoing(hadc->Instance) != 0UL) + { + return HAL_BUSY; + } + else + { + /* Process locked */ + __HAL_LOCK(hadc); + + /* Temporary handle minimum initialization */ + __HAL_ADC_RESET_HANDLE_STATE(&tmp_hadc_slave); + ADC_CLEAR_ERRORCODE(&tmp_hadc_slave); + + /* Set a temporary handle of the ADC slave associated to the ADC master */ + ADC_MULTI_SLAVE(hadc, &tmp_hadc_slave); + + if (tmp_hadc_slave.Instance == NULL) + { + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + return HAL_ERROR; + } + + /* Enable the ADC peripherals: master and slave (in case if not already */ + /* enabled previously) */ + tmp_hal_status = ADC_Enable(hadc); + if (tmp_hal_status == HAL_OK) + { + tmp_hal_status = ADC_Enable(&tmp_hadc_slave); + } + + /* Start multimode conversion of ADCs pair */ + if (tmp_hal_status == HAL_OK) + { + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + (HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR | HAL_ADC_STATE_REG_EOSMP), + HAL_ADC_STATE_REG_BUSY); + + /* Set ADC error code to none */ + ADC_CLEAR_ERRORCODE(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 ; + + /* Pointer to the common control register */ + tmpADC_Common = __LL_ADC_COMMON_INSTANCE(hadc->Instance); + + /* 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_EOS | ADC_FLAG_OVR)); + + /* Process unlocked */ + /* Unlock before starting ADC conversions: in case of potential */ + /* interruption, to let the process to ADC IRQ Handler. */ + __HAL_UNLOCK(hadc); + + /* Enable ADC overrun interrupt */ + __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR); + + /* Check linkedlist mode */ + if ((hadc->DMA_Handle->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hadc->DMA_Handle->LinkedListQueue != NULL) && (hadc->DMA_Handle->LinkedListQueue->Head != NULL)) + { + /* Length should be converted to number of bytes */ + if (HAL_DMAEx_List_GetNodeConfig(&node_conf, hadc->DMA_Handle->LinkedListQueue->Head) != HAL_OK) + { + return HAL_ERROR; + } + + /* Length should be converted to number of bytes */ + if (node_conf.Init.SrcDataWidth == DMA_SRC_DATAWIDTH_WORD) + { + /* Word -> Bytes */ + length_bytes = Length * 4U; + } + else if (node_conf.Init.SrcDataWidth == DMA_SRC_DATAWIDTH_HALFWORD) + { + /* Halfword -> Bytes */ + length_bytes = Length * 2U; + } + else /* Bytes */ + { + /* Same size already expressed in Bytes */ + length_bytes = Length; + } + + hadc->DMA_Handle->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = (uint32_t)length_bytes; + hadc->DMA_Handle->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = \ + (uint32_t)&tmpADC_Common->CDR; + hadc->DMA_Handle->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)pData; + tmp_hal_status = HAL_DMAEx_List_Start_IT(hadc->DMA_Handle); + } + else + { + return HAL_ERROR; + } + } + else + { + /* Length should be converted to number of bytes */ + if (hadc->DMA_Handle->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_WORD) + { + /* Word -> Bytes */ + length_bytes = Length * 4U; + } + else if (hadc->DMA_Handle->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_HALFWORD) + { + /* Halfword -> Bytes */ + length_bytes = Length * 2U; + } + else /* Bytes */ + { + /* Same size already expressed in Bytes */ + length_bytes = Length; + } + + /* Start the DMA channel */ + tmp_hal_status = HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&tmpADC_Common->CDR, (uint32_t)pData, \ + length_bytes); + } + + /* Enable conversion of regular group. */ + /* If software start has been selected, conversion starts immediately. */ + /* If external trigger has been selected, conversion will start at next */ + /* trigger event. */ + /* Start ADC group regular conversion */ + LL_ADC_REG_StartConversion(hadc->Instance); + } + else + { + /* Process unlocked */ + __HAL_UNLOCK(hadc); + } + + /* Return function status */ + return tmp_hal_status; + } +} + +/** + * @brief Stop multimode ADC conversion, disable ADC DMA transfer, disable ADC peripheral. + * @note Multimode is kept enabled after this function. MultiMode DMA bits + * (MDMA and DMACFG bits of common CCR register) are maintained. To disable + * Multimode (set with HAL_ADCEx_MultiModeConfigChannel()), ADC must be + * reinitialized using HAL_ADC_Init() or HAL_ADC_DeInit(), or the user can + * resort to HAL_ADCEx_DisableMultiMode() API. + * @note In case of DMA configured in circular mode, function + * HAL_ADC_Stop_DMA() must be called after this function with handle of + * ADC slave, to properly disable the DMA channel. + * @param hadc ADC handle of ADC master (handle of ADC slave must not be used) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADCEx_MultiModeStop_DMA(ADC_HandleTypeDef *hadc) +{ + HAL_StatusTypeDef tmp_hal_status; + uint32_t tickstart; + ADC_HandleTypeDef tmp_hadc_slave; + uint32_t tmp_hadc_slave_conversion_on_going; + HAL_StatusTypeDef tmp_hadc_slave_disable_status; + + /* Check the parameters */ + assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* 1. Stop potential multimode conversion on going, on regular and injected groups */ + tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_INJECTED_GROUP); + + /* Disable ADC peripheral if conversions are effectively stopped */ + if (tmp_hal_status == HAL_OK) + { + /* Temporary handle minimum initialization */ + __HAL_ADC_RESET_HANDLE_STATE(&tmp_hadc_slave); + ADC_CLEAR_ERRORCODE(&tmp_hadc_slave); + + /* Set a temporary handle of the ADC slave associated to the ADC master */ + ADC_MULTI_SLAVE(hadc, &tmp_hadc_slave); + + if (tmp_hadc_slave.Instance == NULL) + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + return HAL_ERROR; + } + + /* Procedure to disable the ADC peripheral: wait for conversions */ + /* effectively stopped (ADC master and ADC slave), then disable ADC */ + + /* 1. Wait for ADC conversion completion for ADC master and ADC slave */ + tickstart = HAL_GetTick(); + + tmp_hadc_slave_conversion_on_going = LL_ADC_REG_IsConversionOngoing((&tmp_hadc_slave)->Instance); + while ((LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 1UL) + || (tmp_hadc_slave_conversion_on_going == 1UL) + ) + { + if ((HAL_GetTick() - tickstart) > ADC_STOP_CONVERSION_TIMEOUT) + { + /* New check to avoid false timeout detection in case of preemption */ + tmp_hadc_slave_conversion_on_going = LL_ADC_REG_IsConversionOngoing((&tmp_hadc_slave)->Instance); + if ((LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 1UL) + || (tmp_hadc_slave_conversion_on_going == 1UL) + ) + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + return HAL_ERROR; + } + } + + tmp_hadc_slave_conversion_on_going = LL_ADC_REG_IsConversionOngoing((&tmp_hadc_slave)->Instance); + } + + /* Disable the DMA channel (in case of DMA in circular mode or stop */ + /* while DMA transfer is on going) */ + /* Note: DMA channel of ADC slave should be stopped after this function */ + /* with HAL_ADC_Stop_DMA() API. */ + tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle); + + /* Check if DMA channel effectively disabled */ + if (tmp_hal_status == HAL_ERROR) + { + /* 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); + + /* 2. Disable the ADC peripherals: master and slave */ + /* Update "tmp_hal_status" only if DMA channel disabling passed, to keep in */ + /* memory a potential failing status. */ + if (tmp_hal_status == HAL_OK) + { + tmp_hadc_slave_disable_status = ADC_Disable(&tmp_hadc_slave); + if ((ADC_Disable(hadc) == HAL_OK) && + (tmp_hadc_slave_disable_status == HAL_OK)) + { + tmp_hal_status = HAL_OK; + } + } + else + { + /* In case of error, attempt to disable ADC master and slave without status assert */ + (void) ADC_Disable(hadc); + (void) ADC_Disable(&tmp_hadc_slave); + } + + /* Set ADC state (ADC master) */ + 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 Return the last ADC Master and Slave regular conversions results when in multimode configuration. + * @param hadc ADC handle of ADC Master (handle of ADC Slave must not be used) + * @retval The converted data values. + */ +uint32_t HAL_ADCEx_MultiModeGetValue(const ADC_HandleTypeDef *hadc) +{ + const ADC_Common_TypeDef *tmpADC_Common; + + /* Check the parameters */ + assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance)); + + /* Prevent unused argument(s) compilation warning if no assert_param check */ + /* and possible no usage in __LL_ADC_COMMON_INSTANCE() below */ + UNUSED(hadc); + + /* Pointer to the common control register */ + tmpADC_Common = __LL_ADC_COMMON_INSTANCE(hadc->Instance); + + /* Return the multi mode conversion value */ + return tmpADC_Common->CDR; +} +#endif /* ADC_MULTIMODE_SUPPORT */ + +/** + * @brief Get ADC injected group conversion result. + * @note Reading register JDRx automatically clears ADC flag JEOC + * (ADC group injected end of unitary conversion). + * @note This function does not clear ADC flag JEOS + * (ADC group injected end of sequence conversion) + * Occurrence of flag JEOS rising: + * - If sequencer is composed of 1 rank, flag JEOS is equivalent + * to flag JEOC. + * - If sequencer is composed of several ranks, during the scan + * sequence flag JEOC only is raised, at the end of the scan sequence + * both flags JEOC and EOS are raised. + * Flag JEOS must not be cleared by this function because + * it would not be compliant with low power features + * (feature low power auto-wait, not available on all STM32 series). + * To clear this flag, either use function: + * in programming model IT: @ref HAL_ADC_IRQHandler(), in programming + * model polling: @ref HAL_ADCEx_InjectedPollForConversion() + * or @ref __HAL_ADC_CLEAR_FLAG(&hadc, ADC_FLAG_JEOS). + * @param hadc ADC handle + * @param InjectedRank the converted ADC injected rank. + * This parameter can be one of the following values: + * @arg @ref ADC_INJECTED_RANK_1 ADC group injected rank 1 + * @arg @ref ADC_INJECTED_RANK_2 ADC group injected rank 2 + * @arg @ref ADC_INJECTED_RANK_3 ADC group injected rank 3 + * @arg @ref ADC_INJECTED_RANK_4 ADC group injected rank 4 + * @retval ADC group injected conversion data + */ +uint32_t HAL_ADCEx_InjectedGetValue(const ADC_HandleTypeDef *hadc, uint32_t InjectedRank) +{ + uint32_t tmp_jdr; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + assert_param(IS_ADC_INJECTED_RANK(InjectedRank)); + + /* Get ADC converted value */ + switch (InjectedRank) + { + case ADC_INJECTED_RANK_4: + tmp_jdr = hadc->Instance->JDR4; + break; + case ADC_INJECTED_RANK_3: + tmp_jdr = hadc->Instance->JDR3; + break; + case ADC_INJECTED_RANK_2: + tmp_jdr = hadc->Instance->JDR2; + break; + case ADC_INJECTED_RANK_1: + default: + tmp_jdr = hadc->Instance->JDR1; + break; + } + + /* Return ADC converted value */ + return tmp_jdr; +} + +/** + * @brief Injected conversion complete callback in non-blocking mode. + * @param hadc ADC handle + * @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, + function HAL_ADCEx_InjectedConvCpltCallback must be implemented in the user file. + */ +} + +/** + * @brief Injected context queue overflow callback. + * @note This callback is called if injected context queue is enabled + (parameter "QueueInjectedContext" in injected channel configuration) + and if a new injected context is set when queue is full (maximum 2 + contexts). + * @param hadc ADC handle + * @retval None + */ +__weak void HAL_ADCEx_InjectedQueueOverflowCallback(ADC_HandleTypeDef *hadc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hadc); + + /* NOTE : This function should not be modified. When the callback is needed, + function HAL_ADCEx_InjectedQueueOverflowCallback must be implemented in the user file. + */ +} + +/** + * @brief Analog watchdog 2 callback in non-blocking mode. + * @param hadc ADC handle + * @retval None + */ +__weak void HAL_ADCEx_LevelOutOfWindow2Callback(ADC_HandleTypeDef *hadc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hadc); + + /* NOTE : This function should not be modified. When the callback is needed, + function HAL_ADCEx_LevelOutOfWindow2Callback must be implemented in the user file. + */ +} + +/** + * @brief Analog watchdog 3 callback in non-blocking mode. + * @param hadc ADC handle + * @retval None + */ +__weak void HAL_ADCEx_LevelOutOfWindow3Callback(ADC_HandleTypeDef *hadc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hadc); + + /* NOTE : This function should not be modified. When the callback is needed, + function HAL_ADCEx_LevelOutOfWindow3Callback must be implemented in the user file. + */ +} + + +/** + * @brief End Of Sampling callback in non-blocking mode. + * @param hadc ADC handle + * @retval None + */ +__weak void HAL_ADCEx_EndOfSamplingCallback(ADC_HandleTypeDef *hadc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hadc); + + /* NOTE : This function should not be modified. When the callback is needed, + function HAL_ADCEx_EndOfSamplingCallback must be implemented in the user file. + */ +} + +/** + * @brief Stop ADC conversion of regular group (and injected channels in + * case of auto_injection mode), disable ADC peripheral if no + * conversion is on going on injected group. + * @param hadc ADC handle + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_ADCEx_RegularStop(ADC_HandleTypeDef *hadc) +{ + HAL_StatusTypeDef tmp_hal_status; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* 1. Stop potential regular conversion on going */ + tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_GROUP); + + /* Disable ADC peripheral if regular conversions are effectively stopped + and if no injected conversions are on-going */ + if (tmp_hal_status == HAL_OK) + { + /* Clear HAL_ADC_STATE_REG_BUSY bit */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY); + + if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL) + { + /* 2. Disable the ADC peripheral */ + tmp_hal_status = ADC_Disable(hadc); + + /* Check if ADC is effectively disabled */ + if (tmp_hal_status == HAL_OK) + { + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_INJ_BUSY, + HAL_ADC_STATE_READY); + } + } + /* Conversion on injected group is stopped, but ADC not disabled since */ + /* conversion on regular group is still running. */ + else + { + SET_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY); + } + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return tmp_hal_status; +} + + +/** + * @brief Stop ADC conversion of ADC groups regular and injected, + * disable interrution of end-of-conversion, + * disable ADC peripheral if no conversion is on going + * on injected group. + * @param hadc ADC handle + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_ADCEx_RegularStop_IT(ADC_HandleTypeDef *hadc) +{ + HAL_StatusTypeDef tmp_hal_status; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* 1. Stop potential regular conversion on going */ + tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_GROUP); + + /* Disable ADC peripheral if conversions are effectively stopped + and if no injected conversion is on-going */ + if (tmp_hal_status == HAL_OK) + { + /* Clear HAL_ADC_STATE_REG_BUSY bit */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY); + + /* Disable all regular-related interrupts */ + __HAL_ADC_DISABLE_IT(hadc, (ADC_IT_EOC | ADC_IT_EOS | ADC_IT_OVR)); + + /* 2. Disable ADC peripheral if no injected conversions are on-going */ + if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL) + { + tmp_hal_status = ADC_Disable(hadc); + /* if no issue reported */ + if (tmp_hal_status == HAL_OK) + { + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_INJ_BUSY, + HAL_ADC_STATE_READY); + } + } + else + { + SET_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY); + } + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Stop ADC conversion of regular group (and injected group in + * case of auto_injection mode), disable ADC DMA transfer, disable + * ADC peripheral if no conversion is on going + * on injected group. + * @note HAL_ADCEx_RegularStop_DMA() function is dedicated to single-ADC mode only. + * For multimode (when multimode feature is available), + * HAL_ADCEx_RegularMultiModeStop_DMA() API must be used. + * @param hadc ADC handle + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_ADCEx_RegularStop_DMA(ADC_HandleTypeDef *hadc) +{ + HAL_StatusTypeDef tmp_hal_status; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* 1. Stop potential regular conversion on going */ + tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_GROUP); + + /* Disable ADC peripheral if conversions are effectively stopped + and if no injected conversion is on-going */ + if (tmp_hal_status == HAL_OK) + { + /* Clear HAL_ADC_STATE_REG_BUSY bit */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY); + + /* Disable ADC DMA (ADC DMA configuration ADC_CFGR_DMACFG is kept) */ + CLEAR_BIT(hadc->Instance->CFGR, ADC_CFGR_DMAEN); + + /* Disable the DMA channel (in case of DMA in circular mode or stop while */ + /* while DMA transfer is on going) */ + 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); + + /* 2. Disable the ADC peripheral */ + /* Update "tmp_hal_status" only if DMA channel disabling passed, */ + /* to keep in memory a potential failing status. */ + if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL) + { + if (tmp_hal_status == HAL_OK) + { + tmp_hal_status = ADC_Disable(hadc); + } + else + { + (void)ADC_Disable(hadc); + } + + /* Check if ADC is effectively disabled */ + if (tmp_hal_status == HAL_OK) + { + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_INJ_BUSY, + HAL_ADC_STATE_READY); + } + } + else + { + SET_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY); + } + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return tmp_hal_status; +} + +#if defined(ADC_MULTIMODE_SUPPORT) +/** + * @brief Stop DMA-based multimode ADC conversion, disable ADC DMA transfer, disable ADC peripheral if no injected + * conversion is on-going. + * @note Multimode is kept enabled after this function. Multimode DMA bits + * (MDMA and DMACFG bits of common CCR register) are maintained. To disable + * multimode (set with HAL_ADCEx_MultiModeConfigChannel()), ADC must be + * reinitialized using HAL_ADC_Init() or HAL_ADC_DeInit(), or the user can + * resort to HAL_ADCEx_DisableMultiMode() API. + * @note In case of DMA configured in circular mode, function + * HAL_ADCEx_RegularStop_DMA() must be called after this function with handle of + * ADC slave, to properly disable the DMA channel. + * @param hadc ADC handle of ADC master (handle of ADC slave must not be used) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADCEx_RegularMultiModeStop_DMA(ADC_HandleTypeDef *hadc) +{ + HAL_StatusTypeDef tmp_hal_status; + uint32_t tickstart; + ADC_HandleTypeDef tmp_hadc_slave; + uint32_t tmp_hadc_slave_conversion_on_going; + + /* Check the parameters */ + assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance)); + + /* Process locked */ + __HAL_LOCK(hadc); + + + /* 1. Stop potential multimode conversion on going, on regular groups */ + tmp_hal_status = ADC_ConversionStop(hadc, ADC_REGULAR_GROUP); + + /* Disable ADC peripheral if conversions are effectively stopped */ + if (tmp_hal_status == HAL_OK) + { + /* Clear HAL_ADC_STATE_REG_BUSY bit */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY); + + /* Temporary handle minimum initialization */ + __HAL_ADC_RESET_HANDLE_STATE(&tmp_hadc_slave); + ADC_CLEAR_ERRORCODE(&tmp_hadc_slave); + + /* Set a temporary handle of the ADC slave associated to the ADC master */ + ADC_MULTI_SLAVE(hadc, &tmp_hadc_slave); + + if (tmp_hadc_slave.Instance == NULL) + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + return HAL_ERROR; + } + + /* Procedure to disable the ADC peripheral: wait for conversions */ + /* effectively stopped (ADC master and ADC slave), then disable ADC */ + + /* 1. Wait for ADC conversion completion for ADC master and ADC slave */ + tickstart = HAL_GetTick(); + + tmp_hadc_slave_conversion_on_going = LL_ADC_REG_IsConversionOngoing((&tmp_hadc_slave)->Instance); + while ((LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 1UL) + || (tmp_hadc_slave_conversion_on_going == 1UL) + ) + { + if ((HAL_GetTick() - tickstart) > ADC_STOP_CONVERSION_TIMEOUT) + { + /* New check to avoid false timeout detection in case of preemption */ + tmp_hadc_slave_conversion_on_going = LL_ADC_REG_IsConversionOngoing((&tmp_hadc_slave)->Instance); + if ((LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 1UL) + || (tmp_hadc_slave_conversion_on_going == 1UL) + ) + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + return HAL_ERROR; + } + } + + tmp_hadc_slave_conversion_on_going = LL_ADC_REG_IsConversionOngoing((&tmp_hadc_slave)->Instance); + } + + /* Disable the DMA channel (in case of DMA in circular mode or stop */ + /* while DMA transfer is on going) */ + /* Note: DMA channel of ADC slave should be stopped after this function */ + /* with HAL_ADCEx_RegularStop_DMA() API. */ + 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); + + /* 2. Disable the ADC peripherals: master and slave if no injected */ + /* conversion is on-going. */ + /* Update "tmp_hal_status" only if DMA channel disabling passed, to keep in */ + /* memory a potential failing status. */ + if (tmp_hal_status == HAL_OK) + { + if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL) + { + tmp_hal_status = ADC_Disable(hadc); + if (tmp_hal_status == HAL_OK) + { + if (LL_ADC_INJ_IsConversionOngoing((&tmp_hadc_slave)->Instance) == 0UL) + { + tmp_hal_status = ADC_Disable(&tmp_hadc_slave); + } + } + } + + if (tmp_hal_status == HAL_OK) + { + /* Both Master and Slave ADC's could be disabled. Update Master State */ + /* Clear HAL_ADC_STATE_INJ_BUSY bit, set HAL_ADC_STATE_READY bit */ + ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_BUSY, HAL_ADC_STATE_READY); + } + else + { + /* injected (Master or Slave) conversions are still on-going, + no Master State change */ + } + } + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return tmp_hal_status; +} +#endif /* ADC_MULTIMODE_SUPPORT */ + +/** + * @} + */ + +/** @defgroup ADCEx_Exported_Functions_Group2 ADC Extended Peripheral Control functions + * @brief ADC Extended Peripheral Control functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure channels on injected group + (+) Configure multimode when multimode feature is available + (+) Enable or Disable Injected Queue + (+) Disable ADC voltage regulator + (+) Enter ADC deep-power-down mode + +@endverbatim + * @{ + */ + +/** + * @brief Configure a channel to be assigned to ADC group injected. + * @note Possibility to update parameters on the fly: + * This function initializes injected group, following calls to this + * function can be used to reconfigure some parameters of structure + * "ADC_InjectionConfTypeDef" on the fly, without resetting the ADC. + * The setting of these parameters is conditioned to ADC state: + * Refer to comments of structure "ADC_InjectionConfTypeDef". + * @note In case of usage of internal measurement channels: + * Vbat/VrefInt/TempSensor. + * These internal paths can be disabled using function + * HAL_ADC_DeInit(). + * @note Caution: For Injected Context Queue use, a context must be fully + * defined before start of injected conversion. All channels are configured + * consecutively for the same ADC instance. Therefore, the number of calls to + * HAL_ADCEx_InjectedConfigChannel() must be equal to the value of parameter + * InjectedNbrOfConversion for each context. + * - Example 1: If 1 context is intended to be used (or if there is no use of the + * Injected Queue Context feature) and if the context contains 3 injected ranks + * (InjectedNbrOfConversion = 3), HAL_ADCEx_InjectedConfigChannel() must be + * called once for each channel (i.e. 3 times) before starting a conversion. + * This function must not be called to configure a 4th injected channel: + * it would start a new context into context queue. + * - Example 2: If 2 contexts are intended to be used and each of them contains + * 3 injected ranks (InjectedNbrOfConversion = 3), + * HAL_ADCEx_InjectedConfigChannel() must be called once for each channel and + * for each context (3 channels x 2 contexts = 6 calls). Conversion can + * start once the 1st context is set, that is after the first three + * HAL_ADCEx_InjectedConfigChannel() calls. The 2nd context can be set on the fly. + * @param hadc ADC handle + * @param pConfigInjected Structure of ADC injected group and ADC channel for + * injected group. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef *hadc, + const ADC_InjectionConfTypeDef *pConfigInjected) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + uint32_t tmp_offset_shifted; + uint32_t tmp_config_internal_channel; + uint32_t tmp_adc_is_conversion_on_going_regular; + uint32_t tmp_adc_is_conversion_on_going_injected; + __IO uint32_t wait_loop_index = 0; + + uint32_t tmp_jsqr_context_queue_being_built = 0U; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + assert_param(IS_ADC_SAMPLE_TIME(pConfigInjected->InjectedSamplingTime)); + assert_param(IS_ADC_SINGLE_DIFFERENTIAL(pConfigInjected->InjectedSingleDiff)); + assert_param(IS_FUNCTIONAL_STATE(pConfigInjected->AutoInjectedConv)); + assert_param(IS_FUNCTIONAL_STATE(pConfigInjected->QueueInjectedContext)); + assert_param(IS_ADC_EXTTRIGINJEC_EDGE(pConfigInjected->ExternalTrigInjecConvEdge)); + assert_param(IS_ADC_EXTTRIGINJEC(pConfigInjected->ExternalTrigInjecConv)); + assert_param(IS_ADC_OFFSET_NUMBER(pConfigInjected->InjectedOffsetNumber)); + assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), pConfigInjected->InjectedOffset)); + assert_param(IS_ADC_OFFSET_SIGN(pConfigInjected->InjectedOffsetSign)); + assert_param(IS_FUNCTIONAL_STATE(pConfigInjected->InjectedOffsetSaturation)); + assert_param(IS_FUNCTIONAL_STATE(pConfigInjected->InjecOversamplingMode)); + + if (hadc->Init.ScanConvMode != ADC_SCAN_DISABLE) + { + assert_param(IS_ADC_INJECTED_RANK(pConfigInjected->InjectedRank)); + assert_param(IS_ADC_INJECTED_NB_CONV(pConfigInjected->InjectedNbrOfConversion)); + assert_param(IS_FUNCTIONAL_STATE(pConfigInjected->InjectedDiscontinuousConvMode)); + } + + + /* if JOVSE is set, the value of the OFFSETy_EN bit in ADCx_OFRy register is + ignored (considered as reset) */ + assert_param(!((pConfigInjected->InjectedOffsetNumber != ADC_OFFSET_NONE) + && (pConfigInjected->InjecOversamplingMode == ENABLE))); + + /* JDISCEN and JAUTO bits can't be set at the same time */ + assert_param(!((pConfigInjected->InjectedDiscontinuousConvMode == ENABLE) + && (pConfigInjected->AutoInjectedConv == ENABLE))); + + /* DISCEN and JAUTO bits can't be set at the same time */ + assert_param(!((hadc->Init.DiscontinuousConvMode == ENABLE) && (pConfigInjected->AutoInjectedConv == ENABLE))); + + /* Verification of channel number */ + if (pConfigInjected->InjectedSingleDiff != ADC_DIFFERENTIAL_ENDED) + { + assert_param(IS_ADC_CHANNEL(hadc, pConfigInjected->InjectedChannel)); + } + else + { + assert_param(IS_ADC_DIFF_CHANNEL(hadc, pConfigInjected->InjectedChannel)); + } + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Configuration of injected group sequencer: */ + /* Hardware constraint: Must fully define injected context register JSQR */ + /* before make it entering into injected sequencer queue. */ + /* */ + /* - if scan mode is disabled: */ + /* * Injected channels sequence length is set to 0x00: 1 channel */ + /* converted (channel on injected rank 1) */ + /* Parameter "InjectedNbrOfConversion" is discarded. */ + /* * Injected context register JSQR setting is simple: register is fully */ + /* defined on one call of this function (for injected rank 1) and can */ + /* be entered into queue directly. */ + /* - if scan mode is enabled: */ + /* * Injected channels sequence length is set to parameter */ + /* "InjectedNbrOfConversion". */ + /* * Injected context register JSQR setting more complex: register is */ + /* fully defined over successive calls of this function, for each */ + /* injected channel rank. It is entered into queue only when all */ + /* injected ranks have been set. */ + /* Note: Scan mode is not present by hardware on this device, but used */ + /* by software for alignment over all STM32 devices. */ + + if ((hadc->Init.ScanConvMode == ADC_SCAN_DISABLE) || + (pConfigInjected->InjectedNbrOfConversion == 1U)) + { + /* Configuration of context register JSQR: */ + /* - number of ranks in injected group sequencer: fixed to 1st rank */ + /* (scan mode disabled, only rank 1 used) */ + /* - external trigger to start conversion */ + /* - external trigger polarity */ + /* - channel set to rank 1 (scan mode disabled, only rank 1 can be used) */ + + if (pConfigInjected->InjectedRank == ADC_INJECTED_RANK_1) + { + /* Enable external trigger if trigger selection is different of */ + /* software start. */ + /* Note: This configuration keeps the hardware feature of parameter */ + /* ExternalTrigInjecConvEdge "trigger edge none" equivalent to */ + /* software start. */ + if (pConfigInjected->ExternalTrigInjecConv != ADC_INJECTED_SOFTWARE_START) + { + tmp_jsqr_context_queue_being_built = (ADC_JSQR_RK(pConfigInjected->InjectedChannel, ADC_INJECTED_RANK_1) + | (pConfigInjected->ExternalTrigInjecConv & ADC_JSQR_JEXTSEL) + | pConfigInjected->ExternalTrigInjecConvEdge + ); + } + else + { + tmp_jsqr_context_queue_being_built = (ADC_JSQR_RK(pConfigInjected->InjectedChannel, ADC_INJECTED_RANK_1)); + } + + MODIFY_REG(hadc->Instance->JSQR, ADC_JSQR_FIELDS, tmp_jsqr_context_queue_being_built); + /* For debug and informative reasons, hadc handle saves JSQR setting */ + hadc->InjectionConfig.ContextQueue = tmp_jsqr_context_queue_being_built; + + } + } + else + { + /* Case of scan mode enabled, several channels to set into injected group */ + /* sequencer. */ + /* */ + /* Procedure to define injected context register JSQR over successive */ + /* calls of this function, for each injected channel rank: */ + /* 1. Start new context and set parameters related to all injected */ + /* channels: injected sequence length and trigger. */ + + /* if hadc->InjectionConfig.ChannelCount is equal to 0, this is the first */ + /* call of the context under setting */ + if (hadc->InjectionConfig.ChannelCount == 0U) + { + /* Initialize number of channels that will be configured on the context */ + /* being built */ + hadc->InjectionConfig.ChannelCount = pConfigInjected->InjectedNbrOfConversion; + /* Handle hadc saves the context under build up over each HAL_ADCEx_InjectedConfigChannel() + call, this context will be written in JSQR register at the last call. + At this point, the context is merely reset */ + hadc->InjectionConfig.ContextQueue = 0x00000000U; + + /* Configuration of context register JSQR: */ + /* - number of ranks in injected group sequencer */ + /* - external trigger to start conversion */ + /* - external trigger polarity */ + + /* Enable external trigger if trigger selection is different of */ + /* software start. */ + /* Note: This configuration keeps the hardware feature of parameter */ + /* ExternalTrigInjecConvEdge "trigger edge none" equivalent to */ + /* software start. */ + if (pConfigInjected->ExternalTrigInjecConv != ADC_INJECTED_SOFTWARE_START) + { + tmp_jsqr_context_queue_being_built = ((pConfigInjected->InjectedNbrOfConversion - 1U) + | (pConfigInjected->ExternalTrigInjecConv & ADC_JSQR_JEXTSEL) + | pConfigInjected->ExternalTrigInjecConvEdge + ); + } + else + { + tmp_jsqr_context_queue_being_built = ((pConfigInjected->InjectedNbrOfConversion - 1U)); + } + + } + + /* 2. Continue setting of context under definition with parameter */ + /* related to each channel: channel rank sequence */ + /* Clear the old JSQx bits for the selected rank */ + tmp_jsqr_context_queue_being_built &= ~ADC_JSQR_RK(ADC_SQR3_SQ10, pConfigInjected->InjectedRank); + + /* Set the JSQx bits for the selected rank */ + tmp_jsqr_context_queue_being_built |= ADC_JSQR_RK(pConfigInjected->InjectedChannel, pConfigInjected->InjectedRank); + + /* Decrease channel count */ + hadc->InjectionConfig.ChannelCount--; + + /* 3. tmp_jsqr_context_queue_being_built is fully built for this HAL_ADCEx_InjectedConfigChannel() + call, aggregate the setting to those already built during the previous + HAL_ADCEx_InjectedConfigChannel() calls (for the same context of course) */ + hadc->InjectionConfig.ContextQueue |= tmp_jsqr_context_queue_being_built; + + /* 4. End of context setting: if this is the last channel set, then write context + into register JSQR and make it enter into queue */ + if (hadc->InjectionConfig.ChannelCount == 0U) + { + MODIFY_REG(hadc->Instance->JSQR, ADC_JSQR_FIELDS, hadc->InjectionConfig.ContextQueue); + } + } + + /* Parameters update conditioned to ADC state: */ + /* Parameters that can be updated when ADC is disabled or enabled without */ + /* conversion on going on injected group: */ + /* - Injected context queue: Queue disable (active context is kept) or */ + /* enable (context decremented, up to 2 contexts queued) */ + /* - Injected discontinuous mode: can be enabled only if auto-injected */ + /* mode is disabled. */ + if (LL_ADC_INJ_IsConversionOngoing(hadc->Instance) == 0UL) + { + if (pConfigInjected->InjectedChannel == ADC_CHANNEL_0) + { + LL_ADC_EnableChannel0_GPIO(hadc->Instance); + } + + /* If auto-injected mode is disabled: no constraint */ + if (pConfigInjected->AutoInjectedConv == DISABLE) + { + MODIFY_REG(hadc->Instance->CFGR, + ADC_CFGR_JQM | ADC_CFGR_JDISCEN, + ADC_CFGR_INJECT_CONTEXT_QUEUE((uint32_t)pConfigInjected->QueueInjectedContext) | + ADC_CFGR_INJECT_DISCCONTINUOUS((uint32_t)pConfigInjected->InjectedDiscontinuousConvMode)); + } + /* If auto-injected mode is enabled: Injected discontinuous setting is */ + /* discarded. */ + else + { + MODIFY_REG(hadc->Instance->CFGR, + ADC_CFGR_JQM | ADC_CFGR_JDISCEN, + ADC_CFGR_INJECT_CONTEXT_QUEUE((uint32_t)pConfigInjected->QueueInjectedContext)); + } + + } + + /* Parameters update conditioned to ADC state: */ + /* Parameters that can be updated when ADC is disabled or enabled without */ + /* conversion on going on regular and injected groups: */ + /* - Automatic injected conversion: can be enabled if injected group */ + /* external triggers are disabled. */ + /* - Channel sampling time */ + /* - Channel offset */ + tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance); + tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance); + + if ((tmp_adc_is_conversion_on_going_regular == 0UL) + && (tmp_adc_is_conversion_on_going_injected == 0UL) + ) + { + /* If injected group external triggers are disabled (set to injected */ + /* software start): no constraint */ + if ((pConfigInjected->ExternalTrigInjecConv == ADC_INJECTED_SOFTWARE_START) + || (pConfigInjected->ExternalTrigInjecConvEdge == ADC_EXTERNALTRIGINJECCONV_EDGE_NONE)) + { + if (pConfigInjected->AutoInjectedConv == ENABLE) + { + SET_BIT(hadc->Instance->CFGR, ADC_CFGR_JAUTO); + } + else + { + CLEAR_BIT(hadc->Instance->CFGR, ADC_CFGR_JAUTO); + } + } + /* If Automatic injected conversion was intended to be set and could not */ + /* due to injected group external triggers enabled, error is reported. */ + else + { + if (pConfigInjected->AutoInjectedConv == ENABLE) + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); + + tmp_hal_status = HAL_ERROR; + } + else + { + CLEAR_BIT(hadc->Instance->CFGR, ADC_CFGR_JAUTO); + } + } + + if (pConfigInjected->InjecOversamplingMode == ENABLE) + { + assert_param(IS_ADC_OVERSAMPLING_RATIO(pConfigInjected->InjecOversampling.Ratio)); + assert_param(IS_ADC_RIGHT_BIT_SHIFT(pConfigInjected->InjecOversampling.RightBitShift)); + + /* JOVSE must be reset in case of triggered regular mode */ + assert_param(!(READ_BIT(hadc->Instance->CFGR2, ADC_CFGR2_ROVSE | ADC_CFGR2_TROVS) + == (ADC_CFGR2_ROVSE | ADC_CFGR2_TROVS))); + + /* Configuration of Injected Oversampler: */ + /* - Oversampling Ratio */ + /* - Right bit shift */ + + /* Enable OverSampling mode */ + MODIFY_REG(hadc->Instance->CFGR2, + ADC_CFGR2_JOVSE | + ADC_CFGR2_OVSR | + ADC_CFGR2_OVSS, + ADC_CFGR2_JOVSE | + pConfigInjected->InjecOversampling.Ratio | + pConfigInjected->InjecOversampling.RightBitShift + ); + } + else + { + /* Disable Regular OverSampling */ + CLEAR_BIT(hadc->Instance->CFGR2, ADC_CFGR2_JOVSE); + } + + /* Manage specific case of sampling time 3.5 cycles replacing 2.5 cyles */ + if (pConfigInjected->InjectedSamplingTime == ADC_SAMPLETIME_3CYCLES_5) + { + /* Set sampling time of the selected ADC channel */ + LL_ADC_SetChannelSamplingTime(hadc->Instance, pConfigInjected->InjectedChannel, LL_ADC_SAMPLINGTIME_2CYCLES_5); + + /* Set ADC sampling time common configuration */ + LL_ADC_SetSamplingTimeCommonConfig(hadc->Instance, LL_ADC_SAMPLINGTIME_COMMON_3C5_REPL_2C5); + } + else + { + /* Set sampling time of the selected ADC channel */ + LL_ADC_SetChannelSamplingTime(hadc->Instance, pConfigInjected->InjectedChannel, + pConfigInjected->InjectedSamplingTime); + + /* Set ADC sampling time common configuration */ + LL_ADC_SetSamplingTimeCommonConfig(hadc->Instance, LL_ADC_SAMPLINGTIME_COMMON_DEFAULT); + } + + /* Configure the offset: offset enable/disable, channel, offset value */ + + /* Shift the offset with respect to the selected ADC resolution. */ + /* Offset has to be left-aligned on bit 11, the LSB (right bits) are set to 0 */ + tmp_offset_shifted = ADC_OFFSET_SHIFT_RESOLUTION(hadc, pConfigInjected->InjectedOffset); + + if (pConfigInjected->InjectedOffsetNumber != ADC_OFFSET_NONE) + { + /* Set ADC selected offset number */ + LL_ADC_SetOffset(hadc->Instance, pConfigInjected->InjectedOffsetNumber, pConfigInjected->InjectedChannel, + tmp_offset_shifted); + + /* Set ADC selected offset sign & saturation */ + LL_ADC_SetOffsetSign(hadc->Instance, pConfigInjected->InjectedOffsetNumber, pConfigInjected->InjectedOffsetSign); + LL_ADC_SetOffsetSaturation(hadc->Instance, pConfigInjected->InjectedOffsetNumber, + (pConfigInjected->InjectedOffsetSaturation == ENABLE) ? + LL_ADC_OFFSET_SATURATION_ENABLE : LL_ADC_OFFSET_SATURATION_DISABLE); + } + else + { + /* Scan each offset register to check if the selected channel is targeted. */ + /* If this is the case, the corresponding offset number is disabled. */ + if (__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_1)) + == __LL_ADC_CHANNEL_TO_DECIMAL_NB(pConfigInjected->InjectedChannel)) + { + LL_ADC_SetOffsetState(hadc->Instance, LL_ADC_OFFSET_1, LL_ADC_OFFSET_DISABLE); + } + if (__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_2)) + == __LL_ADC_CHANNEL_TO_DECIMAL_NB(pConfigInjected->InjectedChannel)) + { + LL_ADC_SetOffsetState(hadc->Instance, LL_ADC_OFFSET_2, LL_ADC_OFFSET_DISABLE); + } + if (__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_3)) + == __LL_ADC_CHANNEL_TO_DECIMAL_NB(pConfigInjected->InjectedChannel)) + { + LL_ADC_SetOffsetState(hadc->Instance, LL_ADC_OFFSET_3, LL_ADC_OFFSET_DISABLE); + } + if (__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_GetOffsetChannel(hadc->Instance, LL_ADC_OFFSET_4)) + == __LL_ADC_CHANNEL_TO_DECIMAL_NB(pConfigInjected->InjectedChannel)) + { + LL_ADC_SetOffsetState(hadc->Instance, LL_ADC_OFFSET_4, LL_ADC_OFFSET_DISABLE); + } + } + + } + + /* Parameters update conditioned to ADC state: */ + /* Parameters that can be updated only when ADC is disabled: */ + /* - Single or differential mode */ + if (LL_ADC_IsEnabled(hadc->Instance) == 0UL) + { + /* Set mode single-ended or differential input of the selected ADC channel */ + LL_ADC_SetChannelSingleDiff(hadc->Instance, pConfigInjected->InjectedChannel, pConfigInjected->InjectedSingleDiff); + + /* Configuration of differential mode */ + /* Note: ADC channel number masked with value "0x1F" to ensure shift value within 32 bits range */ + if (pConfigInjected->InjectedSingleDiff == ADC_DIFFERENTIAL_ENDED) + { + /* Set sampling time of the selected ADC channel */ + LL_ADC_SetChannelSamplingTime(hadc->Instance, + (uint32_t)(__LL_ADC_DECIMAL_NB_TO_CHANNEL( + (__LL_ADC_CHANNEL_TO_DECIMAL_NB( + (uint32_t)pConfigInjected->InjectedChannel) + + 1UL) & 0x1FUL)), + pConfigInjected->InjectedSamplingTime); + } + + } + + /* Management of internal measurement channels: Vbat/VrefInt/TempSensor */ + /* internal measurement paths enable: If internal channel selected, */ + /* enable dedicated internal buffers and path. */ + /* Note: these internal measurement paths can be disabled using */ + /* HAL_ADC_DeInit(). */ + + if (__LL_ADC_IS_CHANNEL_INTERNAL(pConfigInjected->InjectedChannel)) + { + tmp_config_internal_channel = LL_ADC_GetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance)); + + /* If the requested internal measurement path has already been enabled, */ + /* bypass the configuration processing. */ + if ((pConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR) + && ((tmp_config_internal_channel & LL_ADC_PATH_INTERNAL_TEMPSENSOR) == 0UL)) + { + if (ADC_TEMPERATURE_SENSOR_INSTANCE(hadc)) + { + LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance), + LL_ADC_PATH_INTERNAL_TEMPSENSOR | tmp_config_internal_channel); + + /* Delay for temperature sensor stabilization time */ + /* Wait loop initialization and execution */ + /* Note: Variable divided by 2 to compensate partially */ + /* CPU processing cycles, scaling in us split to not */ + /* exceed 32 bits register capacity and handle low frequency. */ + wait_loop_index = ((LL_ADC_DELAY_TEMPSENSOR_STAB_US / 10UL) + * (((SystemCoreClock / (100000UL * 2UL)) + 1UL) + 1UL)); + while (wait_loop_index != 0UL) + { + wait_loop_index--; + } + } + } + else if ((pConfigInjected->InjectedChannel == ADC_CHANNEL_VBAT) + && ((tmp_config_internal_channel & LL_ADC_PATH_INTERNAL_VBAT) == 0UL)) + { + if (ADC_BATTERY_VOLTAGE_INSTANCE(hadc)) + { + LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance), + LL_ADC_PATH_INTERNAL_VBAT | tmp_config_internal_channel); + } + } + else if ((pConfigInjected->InjectedChannel == ADC_CHANNEL_VREFINT) + && ((tmp_config_internal_channel & LL_ADC_PATH_INTERNAL_VREFINT) == 0UL)) + { + if (ADC_VREFINT_INSTANCE(hadc)) + { + LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(hadc->Instance), + LL_ADC_PATH_INTERNAL_VREFINT | tmp_config_internal_channel); + } + } + else if (pConfigInjected->InjectedChannel == ADC_CHANNEL_VDDCORE) + { + if (ADC_VDDCORE_INSTANCE(hadc)) + { + LL_ADC_EnableChannelVDDcore(hadc->Instance); + } + } + else + { + /* nothing to do */ + } + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return tmp_hal_status; +} + +#if defined(ADC_MULTIMODE_SUPPORT) +/** + * @brief Enable ADC multimode and configure multimode parameters + * @note Possibility to update parameters on the fly: + * This function initializes multimode parameters, following + * calls to this function can be used to reconfigure some parameters + * of structure "ADC_MultiModeTypeDef" on the fly, without resetting + * the ADCs. + * The setting of these parameters is conditioned to ADC state. + * For parameters constraints, see comments of structure + * "ADC_MultiModeTypeDef". + * @note To move back configuration from multimode to single mode, ADC must + * be reset (using function HAL_ADC_Init() ). + * @param hadc Master ADC handle + * @param pMultimode Structure of ADC multimode configuration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADCEx_MultiModeConfigChannel(ADC_HandleTypeDef *hadc, const ADC_MultiModeTypeDef *pMultimode) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + ADC_Common_TypeDef *tmpADC_Common; + ADC_HandleTypeDef tmp_hadc_slave; + uint32_t tmp_hadc_slave_conversion_on_going; + + /* Check the parameters */ + assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance)); + assert_param(IS_ADC_MULTIMODE(pMultimode->Mode)); + if (pMultimode->Mode != ADC_MODE_INDEPENDENT) + { + assert_param(IS_ADC_DMA_ACCESS_MULTIMODE(pMultimode->DMAAccessMode)); + assert_param(IS_ADC_SAMPLING_DELAY(pMultimode->TwoSamplingDelay)); + } + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Temporary handle minimum initialization */ + __HAL_ADC_RESET_HANDLE_STATE(&tmp_hadc_slave); + ADC_CLEAR_ERRORCODE(&tmp_hadc_slave); + + ADC_MULTI_SLAVE(hadc, &tmp_hadc_slave); + + if (tmp_hadc_slave.Instance == NULL) + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + return HAL_ERROR; + } + + /* Parameters update conditioned to ADC state: */ + /* Parameters that can be updated when ADC is disabled or enabled without */ + /* conversion on going on regular group: */ + /* - Multimode DMA configuration */ + /* - Multimode DMA mode */ + tmp_hadc_slave_conversion_on_going = LL_ADC_REG_IsConversionOngoing((&tmp_hadc_slave)->Instance); + if ((LL_ADC_REG_IsConversionOngoing(hadc->Instance) == 0UL) + && (tmp_hadc_slave_conversion_on_going == 0UL)) + { + /* Pointer to the common control register */ + tmpADC_Common = __LL_ADC_COMMON_INSTANCE(hadc->Instance); + + /* If multimode is selected, configure all multimode parameters. */ + /* Otherwise, reset multimode parameters (can be used in case of */ + /* transition from multimode to independent mode). */ + if (pMultimode->Mode != ADC_MODE_INDEPENDENT) + { + MODIFY_REG(tmpADC_Common->CCR, ADC_CCR_MDMA | ADC_CCR_DMACFG, + pMultimode->DMAAccessMode | + ADC_CCR_MULTI_DMACONTREQ((uint32_t)hadc->Init.DMAContinuousRequests)); + + /* Parameters that can be updated only when ADC is disabled: */ + /* - Multimode mode selection */ + /* - Multimode delay */ + /* Note: Delay range depends on selected resolution: */ + /* from 1 to 12 clock cycles for 12 bits */ + /* from 1 to 10 clock cycles for 10 bits, */ + /* from 1 to 8 clock cycles for 8 bits */ + /* from 1 to 6 clock cycles for 6 bits */ + /* If a higher delay is selected, it will be clipped to maximum delay */ + /* range */ + if (__LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(__LL_ADC_COMMON_INSTANCE(hadc->Instance)) == 0UL) + { + MODIFY_REG(tmpADC_Common->CCR, + ADC_CCR_DUAL | + ADC_CCR_DELAY, + pMultimode->Mode | + pMultimode->TwoSamplingDelay + ); + } + } + else /* ADC_MODE_INDEPENDENT */ + { + CLEAR_BIT(tmpADC_Common->CCR, ADC_CCR_MDMA | ADC_CCR_DMACFG); + + /* Parameters that can be updated only when ADC is disabled: */ + /* - Multimode mode selection */ + /* - Multimode delay */ + if (__LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(__LL_ADC_COMMON_INSTANCE(hadc->Instance)) == 0UL) + { + CLEAR_BIT(tmpADC_Common->CCR, ADC_CCR_DUAL | ADC_CCR_DELAY); + } + } + } + /* If one of the ADC sharing the same common group is enabled, no update */ + /* could be done on neither of the multimode structure parameters. */ + 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; +} +#endif /* ADC_MULTIMODE_SUPPORT */ + +/** + * @brief Enable Injected Queue + * @note This function resets CFGR register JQDIS bit in order to enable the + * Injected Queue. JQDIS can be written only when ADSTART and JDSTART + * are both equal to 0 to ensure that no regular nor injected + * conversion is ongoing. + * @param hadc ADC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADCEx_EnableInjectedQueue(ADC_HandleTypeDef *hadc) +{ + HAL_StatusTypeDef tmp_hal_status; + uint32_t tmp_adc_is_conversion_on_going_regular; + uint32_t tmp_adc_is_conversion_on_going_injected; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance); + tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance); + + /* Parameter can be set only if no conversion is on-going */ + if ((tmp_adc_is_conversion_on_going_regular == 0UL) + && (tmp_adc_is_conversion_on_going_injected == 0UL) + ) + { + CLEAR_BIT(hadc->Instance->CFGR, ADC_CFGR_JQDIS); + + /* Update state, clear previous result related to injected queue overflow */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_JQOVF); + + tmp_hal_status = HAL_OK; + } + else + { + tmp_hal_status = HAL_ERROR; + } + + return tmp_hal_status; +} + +/** + * @brief Disable Injected Queue + * @note This function sets CFGR register JQDIS bit in order to disable the + * Injected Queue. JQDIS can be written only when ADSTART and JDSTART + * are both equal to 0 to ensure that no regular nor injected + * conversion is ongoing. + * @param hadc ADC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADCEx_DisableInjectedQueue(ADC_HandleTypeDef *hadc) +{ + HAL_StatusTypeDef tmp_hal_status; + uint32_t tmp_adc_is_conversion_on_going_regular; + uint32_t tmp_adc_is_conversion_on_going_injected; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + tmp_adc_is_conversion_on_going_regular = LL_ADC_REG_IsConversionOngoing(hadc->Instance); + tmp_adc_is_conversion_on_going_injected = LL_ADC_INJ_IsConversionOngoing(hadc->Instance); + + /* Parameter can be set only if no conversion is on-going */ + if ((tmp_adc_is_conversion_on_going_regular == 0UL) + && (tmp_adc_is_conversion_on_going_injected == 0UL) + ) + { + LL_ADC_INJ_SetQueueMode(hadc->Instance, LL_ADC_INJ_QUEUE_DISABLE); + tmp_hal_status = HAL_OK; + } + else + { + tmp_hal_status = HAL_ERROR; + } + + return tmp_hal_status; +} + +/** + * @brief Disable ADC voltage regulator. + * @note Disabling voltage regulator allows to save power. This operation can + * be carried out only when ADC is disabled. + * @note To enable again the voltage regulator, the user is expected to + * resort to HAL_ADC_Init() API. + * @param hadc ADC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADCEx_DisableVoltageRegulator(ADC_HandleTypeDef *hadc) +{ + HAL_StatusTypeDef tmp_hal_status; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Setting of this feature is conditioned to ADC state: ADC must be ADC disabled */ + if (LL_ADC_IsEnabled(hadc->Instance) == 0UL) + { + LL_ADC_DisableInternalRegulator(hadc->Instance); + tmp_hal_status = HAL_OK; + } + else + { + tmp_hal_status = HAL_ERROR; + } + + return tmp_hal_status; +} + +/** + * @brief Enter ADC deep-power-down mode + * @note This mode is achieved in setting DEEPPWD bit and allows to save power + * in reducing leakage currents. It is particularly interesting before + * entering stop modes. + * @note Setting DEEPPWD automatically clears ADVREGEN bit and disables the + * ADC voltage regulator. This means that this API encompasses + * HAL_ADCEx_DisableVoltageRegulator(). Additionally, the internal + * calibration is lost. + * @note To exit the ADC deep-power-down mode, the user is expected to + * resort to HAL_ADC_Init() API as well as to relaunch a calibration + * with HAL_ADCEx_Calibration_Start() API or to re-apply a previously + * saved calibration factor. + * @param hadc ADC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADCEx_EnterADCDeepPowerDownMode(ADC_HandleTypeDef *hadc) +{ + HAL_StatusTypeDef tmp_hal_status; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Setting of this feature is conditioned to ADC state: ADC must be ADC disabled */ + if (LL_ADC_IsEnabled(hadc->Instance) == 0UL) + { + LL_ADC_EnableDeepPowerDown(hadc->Instance); + tmp_hal_status = HAL_OK; + } + else + { + tmp_hal_status = HAL_ERROR; + } + + return tmp_hal_status; +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_ADC_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_cec.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_cec.c new file mode 100644 index 0000000000..47cca10f16 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_cec.c @@ -0,0 +1,997 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_cec.c + * @author MCD Application Team + * @brief CEC HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the High Definition Multimedia Interface + * Consumer Electronics Control Peripheral (CEC). + * + Initialization and de-initialization function + * + IO operation function + * + Peripheral Control function + * + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + =============================================================================== + ##### How to use this driver ##### + =============================================================================== + [..] + The CEC HAL driver can be used as follow: + + (#) Declare a CEC_HandleTypeDef handle structure. + (#) Initialize the CEC low level resources by implementing the HAL_CEC_MspInit ()API: + (##) Enable the CEC interface clock. + (##) CEC pins configuration: + (+++) Enable the clock for the CEC GPIOs. + (+++) Configure these CEC pins as alternate function pull-up. + (##) NVIC configuration if you need to use interrupt process (HAL_CEC_Transmit_IT() + and HAL_CEC_Receive_IT() APIs): + (+++) Configure the CEC interrupt priority. + (+++) Enable the NVIC CEC IRQ handle. + (+++) The specific CEC interrupts (Transmission complete interrupt, + RXNE interrupt and Error Interrupts) will be managed using the macros + __HAL_CEC_ENABLE_IT() and __HAL_CEC_DISABLE_IT() inside the transmit + and receive process. + + (#) Program the Signal Free Time (SFT) and SFT option, Tolerance, reception stop in + in case of Bit Rising Error, Error-Bit generation conditions, device logical + address and Listen mode in the hcec Init structure. + + (#) Initialize the CEC registers by calling the HAL_CEC_Init() API. + + [..] + (@) This API (HAL_CEC_Init()) configures also the low level Hardware (GPIO, CLOCK, CORTEX...etc) + by calling the customed HAL_CEC_MspInit() API. + *** Callback registration *** + ============================================= + + The compilation define USE_HAL_CEC_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + Use Functions HAL_CEC_RegisterCallback() or HAL_CEC_RegisterXXXCallback() + to register an interrupt callback. + + Function HAL_CEC_RegisterCallback() allows to register following callbacks: + (+) TxCpltCallback : Tx Transfer completed callback. + (+) ErrorCallback : callback for error detection. + (+) MspInitCallback : CEC MspInit. + (+) MspDeInitCallback : CEC MspDeInit. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + + For specific callback HAL_CEC_RxCpltCallback use dedicated register callbacks + HAL_CEC_RegisterRxCpltCallback(). + + Use function HAL_CEC_UnRegisterCallback() to reset a callback to the default + weak function. + HAL_CEC_UnRegisterCallback() takes as parameters the HAL peripheral handle, + and the Callback ID. + This function allows to reset following callbacks: + (+) TxCpltCallback : Tx Transfer completed callback. + (+) ErrorCallback : callback for error detection. + (+) MspInitCallback : CEC MspInit. + (+) MspDeInitCallback : CEC MspDeInit. + + For callback HAL_CEC_RxCpltCallback use dedicated unregister callback : + HAL_CEC_UnRegisterRxCpltCallback(). + + By default, after the HAL_CEC_Init() and when the state is HAL_CEC_STATE_RESET + all callbacks are set to the corresponding weak functions : + examples HAL_CEC_TxCpltCallback() , HAL_CEC_RxCpltCallback(). + Exception done for MspInit and MspDeInit functions that are + reset to the legacy weak function in the HAL_CEC_Init()/ HAL_CEC_DeInit() only when + these callbacks are null (not registered beforehand). + if not, MspInit or MspDeInit are not null, the HAL_CEC_Init() / HAL_CEC_DeInit() + keep and use the user MspInit/MspDeInit functions (registered beforehand) + + Callbacks can be registered/unregistered in HAL_CEC_STATE_READY state only. + Exception done MspInit/MspDeInit callbacks that can be registered/unregistered + in HAL_CEC_STATE_READY or HAL_CEC_STATE_RESET state, + thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. + In that case first register the MspInit/MspDeInit user callbacks + using HAL_CEC_RegisterCallback() before calling HAL_CEC_DeInit() + or HAL_CEC_Init() function. + + When the compilation define USE_HAL_CEC_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 "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup CEC CEC + * @brief HAL CEC module driver + * @{ + */ +#ifdef HAL_CEC_MODULE_ENABLED +#if defined (CEC) + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup CEC_Private_Constants CEC Private Constants + * @{ + */ +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup CEC_Private_Functions CEC Private Functions + * @{ + */ +/** + * @} + */ + +/* Exported functions ---------------------------------------------------------*/ + +/** @defgroup CEC_Exported_Functions CEC Exported Functions + * @{ + */ + +/** @defgroup CEC_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim +=============================================================================== + ##### Initialization and Configuration functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to initialize the CEC + (+) The following parameters need to be configured: + (++) SignalFreeTime + (++) Tolerance + (++) BRERxStop (RX stopped or not upon Bit Rising Error) + (++) BREErrorBitGen (Error-Bit generation in case of Bit Rising Error) + (++) LBPEErrorBitGen (Error-Bit generation in case of Long Bit Period Error) + (++) BroadcastMsgNoErrorBitGen (Error-bit generation in case of broadcast message error) + (++) SignalFreeTimeOption (SFT Timer start definition) + (++) OwnAddress (CEC device address) + (++) ListenMode + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the CEC mode according to the specified + * parameters in the CEC_InitTypeDef and creates the associated handle . + * @param hcec CEC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CEC_Init(CEC_HandleTypeDef *hcec) +{ + /* Check the CEC handle allocation */ + if ((hcec == NULL) || (hcec->Init.RxBuffer == NULL)) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_CEC_ALL_INSTANCE(hcec->Instance)); + assert_param(IS_CEC_SIGNALFREETIME(hcec->Init.SignalFreeTime)); + assert_param(IS_CEC_TOLERANCE(hcec->Init.Tolerance)); + assert_param(IS_CEC_BRERXSTOP(hcec->Init.BRERxStop)); + assert_param(IS_CEC_BREERRORBITGEN(hcec->Init.BREErrorBitGen)); + assert_param(IS_CEC_LBPEERRORBITGEN(hcec->Init.LBPEErrorBitGen)); + assert_param(IS_CEC_BROADCASTERROR_NO_ERRORBIT_GENERATION(hcec->Init.BroadcastMsgNoErrorBitGen)); + assert_param(IS_CEC_SFTOP(hcec->Init.SignalFreeTimeOption)); + assert_param(IS_CEC_LISTENING_MODE(hcec->Init.ListenMode)); + assert_param(IS_CEC_OWN_ADDRESS(hcec->Init.OwnAddress)); + +#if (USE_HAL_CEC_REGISTER_CALLBACKS == 1) + if (hcec->gState == HAL_CEC_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hcec->Lock = HAL_UNLOCKED; + + hcec->TxCpltCallback = HAL_CEC_TxCpltCallback; /* Legacy weak TxCpltCallback */ + hcec->RxCpltCallback = HAL_CEC_RxCpltCallback; /* Legacy weak RxCpltCallback */ + hcec->ErrorCallback = HAL_CEC_ErrorCallback; /* Legacy weak ErrorCallback */ + + if (hcec->MspInitCallback == NULL) + { + hcec->MspInitCallback = HAL_CEC_MspInit; /* Legacy weak MspInit */ + } + + /* Init the low level hardware */ + hcec->MspInitCallback(hcec); + } +#else + if (hcec->gState == HAL_CEC_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hcec->Lock = HAL_UNLOCKED; + /* Init the low level hardware : GPIO, CLOCK */ + HAL_CEC_MspInit(hcec); + } +#endif /* USE_HAL_CEC_REGISTER_CALLBACKS */ + + hcec->gState = HAL_CEC_STATE_BUSY; + + /* Disable the Peripheral */ + __HAL_CEC_DISABLE(hcec); + + /* Write to CEC Control Register */ + hcec->Instance->CFGR = hcec->Init.SignalFreeTime | hcec->Init.Tolerance | hcec->Init.BRERxStop | \ + hcec->Init.BREErrorBitGen | hcec->Init.LBPEErrorBitGen | \ + hcec->Init.BroadcastMsgNoErrorBitGen | \ + hcec->Init.SignalFreeTimeOption | ((uint32_t)(hcec->Init.OwnAddress) << 16U) | \ + hcec->Init.ListenMode; + + /* Enable the following CEC Transmission/Reception interrupts as + * well as the following CEC Transmission/Reception Errors interrupts + * Rx Byte Received IT + * End of Reception IT + * Rx overrun + * Rx bit rising error + * Rx short bit period error + * Rx long bit period error + * Rx missing acknowledge + * Tx Byte Request IT + * End of Transmission IT + * Tx Missing Acknowledge IT + * Tx-Error IT + * Tx-Buffer Underrun IT + * Tx arbitration lost */ + __HAL_CEC_ENABLE_IT(hcec, CEC_IT_RXBR | CEC_IT_RXEND | CEC_IER_RX_ALL_ERR | CEC_IT_TXBR | CEC_IT_TXEND | + CEC_IER_TX_ALL_ERR); + + /* Enable the CEC Peripheral */ + __HAL_CEC_ENABLE(hcec); + + hcec->ErrorCode = HAL_CEC_ERROR_NONE; + hcec->gState = HAL_CEC_STATE_READY; + hcec->RxState = HAL_CEC_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the CEC peripheral + * @param hcec CEC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CEC_DeInit(CEC_HandleTypeDef *hcec) +{ + /* Check the CEC handle allocation */ + if (hcec == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_CEC_ALL_INSTANCE(hcec->Instance)); + + hcec->gState = HAL_CEC_STATE_BUSY; + +#if (USE_HAL_CEC_REGISTER_CALLBACKS == 1) + if (hcec->MspDeInitCallback == NULL) + { + hcec->MspDeInitCallback = HAL_CEC_MspDeInit; /* Legacy weak MspDeInit */ + } + + /* DeInit the low level hardware */ + hcec->MspDeInitCallback(hcec); + +#else + /* DeInit the low level hardware */ + HAL_CEC_MspDeInit(hcec); +#endif /* USE_HAL_CEC_REGISTER_CALLBACKS */ + + /* Disable the Peripheral */ + __HAL_CEC_DISABLE(hcec); + + /* Clear Flags */ + __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TXEND | CEC_FLAG_TXBR | CEC_FLAG_RXBR | CEC_FLAG_RXEND | CEC_ISR_ALL_ERROR); + + /* Disable the following CEC Transmission/Reception interrupts as + * well as the following CEC Transmission/Reception Errors interrupts + * Rx Byte Received IT + * End of Reception IT + * Rx overrun + * Rx bit rising error + * Rx short bit period error + * Rx long bit period error + * Rx missing acknowledge + * Tx Byte Request IT + * End of Transmission IT + * Tx Missing Acknowledge IT + * Tx-Error IT + * Tx-Buffer Underrun IT + * Tx arbitration lost */ + __HAL_CEC_DISABLE_IT(hcec, CEC_IT_RXBR | CEC_IT_RXEND | CEC_IER_RX_ALL_ERR | CEC_IT_TXBR | CEC_IT_TXEND | + CEC_IER_TX_ALL_ERR); + + hcec->ErrorCode = HAL_CEC_ERROR_NONE; + hcec->gState = HAL_CEC_STATE_RESET; + hcec->RxState = HAL_CEC_STATE_RESET; + + /* Process Unlock */ + __HAL_UNLOCK(hcec); + + return HAL_OK; +} + +/** + * @brief Initializes the Own Address of the CEC device + * @param hcec CEC handle + * @param CEC_OwnAddress The CEC own address. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CEC_SetDeviceAddress(CEC_HandleTypeDef *hcec, uint16_t CEC_OwnAddress) +{ + /* Check the parameters */ + assert_param(IS_CEC_OWN_ADDRESS(CEC_OwnAddress)); + + if ((hcec->gState == HAL_CEC_STATE_READY) && (hcec->RxState == HAL_CEC_STATE_READY)) + { + /* Process Locked */ + __HAL_LOCK(hcec); + + hcec->gState = HAL_CEC_STATE_BUSY; + + /* Disable the Peripheral */ + __HAL_CEC_DISABLE(hcec); + + if (CEC_OwnAddress != CEC_OWN_ADDRESS_NONE) + { + hcec->Instance->CFGR |= ((uint32_t)CEC_OwnAddress << 16); + } + else + { + hcec->Instance->CFGR &= ~(CEC_CFGR_OAR); + } + + hcec->gState = HAL_CEC_STATE_READY; + hcec->ErrorCode = HAL_CEC_ERROR_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hcec); + + /* Enable the Peripheral */ + __HAL_CEC_ENABLE(hcec); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief CEC MSP Init + * @param hcec CEC handle + * @retval None + */ +__weak void HAL_CEC_MspInit(CEC_HandleTypeDef *hcec) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hcec); + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_CEC_MspInit can be implemented in the user file + */ +} + +/** + * @brief CEC MSP DeInit + * @param hcec CEC handle + * @retval None + */ +__weak void HAL_CEC_MspDeInit(CEC_HandleTypeDef *hcec) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hcec); + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_CEC_MspDeInit can be implemented in the user file + */ +} +#if (USE_HAL_CEC_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User CEC Callback + * To be used instead of the weak predefined callback + * @param hcec CEC handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg HAL_CEC_TX_CPLT_CB_ID Tx Complete callback ID + * @arg HAL_CEC_ERROR_CB_ID Error callback ID + * @arg HAL_CEC_MSPINIT_CB_ID MspInit callback ID + * @arg HAL_CEC_MSPDEINIT_CB_ID MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CEC_RegisterCallback(CEC_HandleTypeDef *hcec, HAL_CEC_CallbackIDTypeDef CallbackID, + pCEC_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + /* Process locked */ + __HAL_LOCK(hcec); + + if (hcec->gState == HAL_CEC_STATE_READY) + { + switch (CallbackID) + { + case HAL_CEC_TX_CPLT_CB_ID : + hcec->TxCpltCallback = pCallback; + break; + + case HAL_CEC_ERROR_CB_ID : + hcec->ErrorCallback = pCallback; + break; + + case HAL_CEC_MSPINIT_CB_ID : + hcec->MspInitCallback = pCallback; + break; + + case HAL_CEC_MSPDEINIT_CB_ID : + hcec->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (hcec->gState == HAL_CEC_STATE_RESET) + { + switch (CallbackID) + { + case HAL_CEC_MSPINIT_CB_ID : + hcec->MspInitCallback = pCallback; + break; + + case HAL_CEC_MSPDEINIT_CB_ID : + hcec->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hcec); + + return status; +} + +/** + * @brief Unregister an CEC Callback + * CEC callback is redirected to the weak predefined callback + * @param hcec uart handle + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg HAL_CEC_TX_CPLT_CB_ID Tx Complete callback ID + * @arg HAL_CEC_ERROR_CB_ID Error callback ID + * @arg HAL_CEC_MSPINIT_CB_ID MspInit callback ID + * @arg HAL_CEC_MSPDEINIT_CB_ID MspDeInit callback ID + * @retval status + */ +HAL_StatusTypeDef HAL_CEC_UnRegisterCallback(CEC_HandleTypeDef *hcec, HAL_CEC_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hcec); + + if (hcec->gState == HAL_CEC_STATE_READY) + { + switch (CallbackID) + { + case HAL_CEC_TX_CPLT_CB_ID : + hcec->TxCpltCallback = HAL_CEC_TxCpltCallback; /* Legacy weak TxCpltCallback */ + break; + + case HAL_CEC_ERROR_CB_ID : + hcec->ErrorCallback = HAL_CEC_ErrorCallback; /* Legacy weak ErrorCallback */ + break; + + case HAL_CEC_MSPINIT_CB_ID : + hcec->MspInitCallback = HAL_CEC_MspInit; + break; + + case HAL_CEC_MSPDEINIT_CB_ID : + hcec->MspDeInitCallback = HAL_CEC_MspDeInit; + break; + + default : + /* Update the error code */ + hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (hcec->gState == HAL_CEC_STATE_RESET) + { + switch (CallbackID) + { + case HAL_CEC_MSPINIT_CB_ID : + hcec->MspInitCallback = HAL_CEC_MspInit; + break; + + case HAL_CEC_MSPDEINIT_CB_ID : + hcec->MspDeInitCallback = HAL_CEC_MspDeInit; + break; + + default : + /* Update the error code */ + hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hcec); + + return status; +} + +/** + * @brief Register CEC RX complete Callback + * To be used instead of the weak HAL_CEC_RxCpltCallback() predefined callback + * @param hcec CEC handle + * @param pCallback pointer to the Rx transfer compelete Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CEC_RegisterRxCpltCallback(CEC_HandleTypeDef *hcec, pCEC_RxCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + /* Process locked */ + __HAL_LOCK(hcec); + + if (HAL_CEC_STATE_READY == hcec->RxState) + { + hcec->RxCpltCallback = pCallback; + } + else + { + /* Update the error code */ + hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hcec); + return status; +} + +/** + * @brief UnRegister CEC RX complete Callback + * CEC RX complete Callback is redirected to the weak HAL_CEC_RxCpltCallback() predefined callback + * @param hcec CEC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CEC_UnRegisterRxCpltCallback(CEC_HandleTypeDef *hcec) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hcec); + + if (HAL_CEC_STATE_READY == hcec->RxState) + { + hcec->RxCpltCallback = HAL_CEC_RxCpltCallback; /* Legacy weak CEC RxCpltCallback */ + } + else + { + /* Update the error code */ + hcec->ErrorCode |= HAL_CEC_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hcec); + return status; +} +#endif /* USE_HAL_CEC_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup CEC_Exported_Functions_Group2 Input and Output operation functions + * @brief CEC Transmit/Receive functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + This subsection provides a set of functions allowing to manage the CEC data transfers. + + (#) The CEC handle must contain the initiator (TX side) and the destination (RX side) + logical addresses (4-bit long addresses, 0xF for broadcast messages destination) + + (#) The communication is performed using Interrupts. + These API's return the HAL status. + The end of the data processing will be indicated through the + dedicated CEC IRQ when using Interrupt mode. + The HAL_CEC_TxCpltCallback(), HAL_CEC_RxCpltCallback() user callbacks + will be executed respectively at the end of the transmit or Receive process + The HAL_CEC_ErrorCallback() user callback will be executed when a communication + error is detected + + (#) API's with Interrupt are : + (+) HAL_CEC_Transmit_IT() + (+) HAL_CEC_IRQHandler() + + (#) A set of User Callbacks are provided: + (+) HAL_CEC_TxCpltCallback() + (+) HAL_CEC_RxCpltCallback() + (+) HAL_CEC_ErrorCallback() + +@endverbatim + * @{ + */ + +/** + * @brief Send data in interrupt mode + * @param hcec CEC handle + * @param InitiatorAddress Initiator address + * @param DestinationAddress destination logical address + * @param pData pointer to input byte data buffer + * @param Size amount of data to be sent in bytes (without counting the header). + * 0 means only the header is sent (ping operation). + * Maximum TX size is 15 bytes (1 opcode and up to 14 operands). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CEC_Transmit_IT(CEC_HandleTypeDef *hcec, uint8_t InitiatorAddress, uint8_t DestinationAddress, + const uint8_t *pData, uint32_t Size) +{ + /* if the peripheral isn't already busy and if there is no previous transmission + already pending due to arbitration lost */ + if (hcec->gState == HAL_CEC_STATE_READY) + { + if ((pData == NULL) && (Size > 0U)) + { + return HAL_ERROR; + } + + assert_param(IS_CEC_ADDRESS(DestinationAddress)); + assert_param(IS_CEC_ADDRESS(InitiatorAddress)); + assert_param(IS_CEC_MSGSIZE(Size)); + + /* Process Locked */ + __HAL_LOCK(hcec); + hcec->pTxBuffPtr = pData; + hcec->gState = HAL_CEC_STATE_BUSY_TX; + hcec->ErrorCode = HAL_CEC_ERROR_NONE; + + /* initialize the number of bytes to send, + * 0 means only one header is sent (ping operation) */ + hcec->TxXferCount = (uint16_t)Size; + + /* in case of no payload (Size = 0), sender is only pinging the system; + Set TX End of Message (TXEOM) bit, must be set before writing data to TXDR */ + if (Size == 0U) + { + __HAL_CEC_LAST_BYTE_TX_SET(hcec); + } + + /* send header block */ + hcec->Instance->TXDR = (uint32_t)(((uint32_t)InitiatorAddress << CEC_INITIATOR_LSB_POS) | DestinationAddress); + + /* Set TX Start of Message (TXSOM) bit */ + __HAL_CEC_FIRST_BYTE_TX_SET(hcec); + + /* Process Unlocked */ + __HAL_UNLOCK(hcec); + + return HAL_OK; + + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Get size of the received frame. + * @param hcec CEC handle + * @retval Frame size + */ +uint32_t HAL_CEC_GetLastReceivedFrameSize(const CEC_HandleTypeDef *hcec) +{ + return hcec->RxXferSize; +} + +/** + * @brief Change Rx Buffer. + * @param hcec CEC handle + * @param Rxbuffer Rx Buffer + * @note This function can be called only inside the HAL_CEC_RxCpltCallback() + * @retval Frame size + */ +void HAL_CEC_ChangeRxBuffer(CEC_HandleTypeDef *hcec, uint8_t *Rxbuffer) +{ + hcec->Init.RxBuffer = Rxbuffer; +} + +/** + * @brief This function handles CEC interrupt requests. + * @param hcec CEC handle + * @retval None + */ +void HAL_CEC_IRQHandler(CEC_HandleTypeDef *hcec) +{ + + /* save interrupts register for further error or interrupts handling purposes */ + uint32_t itflag; + itflag = hcec->Instance->ISR; + + + /* ----------------------------Arbitration Lost Management----------------------------------*/ + /* CEC TX arbitration error interrupt occurred --------------------------------------*/ + if (HAL_IS_BIT_SET(itflag, CEC_FLAG_ARBLST)) + { + hcec->ErrorCode = HAL_CEC_ERROR_ARBLST; + __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_ARBLST); + } + + /* ----------------------------Rx Management----------------------------------*/ + /* CEC RX byte received interrupt ---------------------------------------------------*/ + if (HAL_IS_BIT_SET(itflag, CEC_FLAG_RXBR)) + { + /* reception is starting */ + hcec->RxState = HAL_CEC_STATE_BUSY_RX; + hcec->RxXferSize++; + /* read received byte */ + *hcec->Init.RxBuffer = (uint8_t) hcec->Instance->RXDR; + hcec->Init.RxBuffer++; + __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RXBR); + } + + /* CEC RX end received interrupt ---------------------------------------------------*/ + if (HAL_IS_BIT_SET(itflag, CEC_FLAG_RXEND)) + { + /* clear IT */ + __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RXEND); + + /* Rx process is completed, restore hcec->RxState to Ready */ + hcec->RxState = HAL_CEC_STATE_READY; + hcec->ErrorCode = HAL_CEC_ERROR_NONE; + hcec->Init.RxBuffer -= hcec->RxXferSize; +#if (USE_HAL_CEC_REGISTER_CALLBACKS == 1U) + hcec->RxCpltCallback(hcec, hcec->RxXferSize); +#else + HAL_CEC_RxCpltCallback(hcec, hcec->RxXferSize); +#endif /* USE_HAL_CEC_REGISTER_CALLBACKS */ + hcec->RxXferSize = 0U; + } + + /* ----------------------------Tx Management----------------------------------*/ + /* CEC TX byte request interrupt ------------------------------------------------*/ + if (HAL_IS_BIT_SET(itflag, CEC_FLAG_TXBR)) + { + --hcec->TxXferCount; + if (hcec->TxXferCount == 0U) + { + /* if this is the last byte transmission, set TX End of Message (TXEOM) bit */ + __HAL_CEC_LAST_BYTE_TX_SET(hcec); + } + /* In all cases transmit the byte */ + hcec->Instance->TXDR = (uint8_t) * hcec->pTxBuffPtr; + hcec->pTxBuffPtr++; + /* clear Tx-Byte request flag */ + __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TXBR); + } + + /* CEC TX end interrupt ------------------------------------------------*/ + if (HAL_IS_BIT_SET(itflag, CEC_FLAG_TXEND)) + { + __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TXEND); + + /* Tx process is ended, restore hcec->gState to Ready */ + hcec->gState = HAL_CEC_STATE_READY; + /* Call the Process Unlocked before calling the Tx call back API to give the possibility to + start again the Transmission under the Tx call back API */ + __HAL_UNLOCK(hcec); + hcec->ErrorCode = HAL_CEC_ERROR_NONE; +#if (USE_HAL_CEC_REGISTER_CALLBACKS == 1U) + hcec->TxCpltCallback(hcec); +#else + HAL_CEC_TxCpltCallback(hcec); +#endif /* USE_HAL_CEC_REGISTER_CALLBACKS */ + } + + /* ----------------------------Rx/Tx Error Management----------------------------------*/ + if ((itflag & (CEC_ISR_RXOVR | CEC_ISR_BRE | CEC_ISR_SBPE | CEC_ISR_LBPE | CEC_ISR_RXACKE | CEC_ISR_TXUDR | + CEC_ISR_TXERR | CEC_ISR_TXACKE)) != 0U) + { + hcec->ErrorCode = itflag; + __HAL_CEC_CLEAR_FLAG(hcec, HAL_CEC_ERROR_RXOVR | HAL_CEC_ERROR_BRE | CEC_FLAG_LBPE | CEC_FLAG_SBPE | + HAL_CEC_ERROR_RXACKE | HAL_CEC_ERROR_TXUDR | HAL_CEC_ERROR_TXERR | HAL_CEC_ERROR_TXACKE); + + + if ((itflag & (CEC_ISR_RXOVR | CEC_ISR_BRE | CEC_ISR_SBPE | CEC_ISR_LBPE | CEC_ISR_RXACKE)) != 0U) + { + hcec->Init.RxBuffer -= hcec->RxXferSize; + hcec->RxXferSize = 0U; + hcec->RxState = HAL_CEC_STATE_READY; + } + else if (((itflag & CEC_ISR_ARBLST) == 0U) && ((itflag & (CEC_ISR_TXUDR | CEC_ISR_TXERR | CEC_ISR_TXACKE)) != 0U)) + { + /* Set the CEC state ready to be able to start again the process */ + hcec->gState = HAL_CEC_STATE_READY; + } + else + { + /* Nothing todo*/ + } +#if (USE_HAL_CEC_REGISTER_CALLBACKS == 1U) + hcec->ErrorCallback(hcec); +#else + /* Error Call Back */ + HAL_CEC_ErrorCallback(hcec); +#endif /* USE_HAL_CEC_REGISTER_CALLBACKS */ + } + else + { + /* Nothing todo*/ + } +} + +/** + * @brief Tx Transfer completed callback + * @param hcec CEC handle + * @retval None + */ +__weak void HAL_CEC_TxCpltCallback(CEC_HandleTypeDef *hcec) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hcec); + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_CEC_TxCpltCallback can be implemented in the user file + */ +} + +/** + * @brief Rx Transfer completed callback + * @param hcec CEC handle + * @param RxFrameSize Size of frame + * @retval None + */ +__weak void HAL_CEC_RxCpltCallback(CEC_HandleTypeDef *hcec, uint32_t RxFrameSize) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hcec); + UNUSED(RxFrameSize); + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_CEC_RxCpltCallback can be implemented in the user file + */ +} + +/** + * @brief CEC error callbacks + * @param hcec CEC handle + * @retval None + */ +__weak void HAL_CEC_ErrorCallback(CEC_HandleTypeDef *hcec) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hcec); + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_CEC_ErrorCallback can be implemented in the user file + */ +} +/** + * @} + */ + +/** @defgroup CEC_Exported_Functions_Group3 Peripheral Control function + * @brief CEC control functions + * +@verbatim + =============================================================================== + ##### Peripheral Control function ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the CEC. + (+) HAL_CEC_GetState() API can be helpful to check in run-time the state of the CEC peripheral. + (+) HAL_CEC_GetError() API can be helpful to check in run-time the error of the CEC peripheral. +@endverbatim + * @{ + */ +/** + * @brief return the CEC state + * @param hcec pointer to a CEC_HandleTypeDef structure that contains + * the configuration information for the specified CEC module. + * @retval HAL state + */ +HAL_CEC_StateTypeDef HAL_CEC_GetState(const CEC_HandleTypeDef *hcec) +{ + uint32_t temp1; + uint32_t temp2; + temp1 = hcec->gState; + temp2 = hcec->RxState; + + return (HAL_CEC_StateTypeDef)(temp1 | temp2); +} + +/** + * @brief Return the CEC error code + * @param hcec pointer to a CEC_HandleTypeDef structure that contains + * the configuration information for the specified CEC. + * @retval CEC Error Code + */ +uint32_t HAL_CEC_GetError(const CEC_HandleTypeDef *hcec) +{ + return hcec->ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ +#endif /* CEC */ +#endif /* HAL_CEC_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_comp.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_comp.c new file mode 100644 index 0000000000..6b12339b1c --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_comp.c @@ -0,0 +1,1192 @@ +/** + ********************************************************************************************************************** + * @file stm32h5xx_hal_comp.c + * @author MCD Application Team + * @brief COMP HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the COMP peripheral: + * + Initialization and de-initialization functions + * + Peripheral control functions + * + Peripheral state functions + ********************************************************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ********************************************************************************************************************** + @verbatim + ====================================================================================================================== + ##### COMP Peripheral features ##### + ====================================================================================================================== + + [..] + The STM32H5xx device family integrates one analog comparator instance: COMP1. + (#) Comparators input minus (inverting input) and input plus (non inverting input) + can be set to internal references or to GPIO pins + (refer to GPIO list in reference manual). + + (#) Comparators output level is available using HAL_COMP_GetOutputLevel() + and can be redirected to other peripherals: GPIO pins (in mode + alternate functions for comparator), timers. + (refer to GPIO list in reference manual). + + (#) The comparators have interrupt capability through direct line to NVIC (featuring + low latency interrupt). + Caution: Specific behavior for comparator of this STM32 series: comparator output triggers interruption + on high level + - triggering on level (instead of edge) implies to disable interrupt in comparator IRQ handler. + In case of further operation needed in interrupt mode, comparator interruption must be rearmed. + - triggering on high level implies that comparator output initial state must at low level. + Then, comparator can trig signal on rising edge. + Trigger a signal on falling edge is possible by inverting comparator polarity. + + ====================================================================================================================== + ##### How to use this driver ##### + ====================================================================================================================== + [..] + This driver provides functions to configure and program the comparator instances of + STM32H5xx devices. + + To use the comparator, perform the following steps: + + (#) Initialize the COMP low level resources by implementing the HAL_COMP_MspInit(): + (++) Configure the GPIO connected to comparator inputs plus and minus in analog mode + using HAL_GPIO_Init(). + (++) If needed, configure the GPIO connected to comparator output in alternate function mode + using HAL_GPIO_Init(). + (++) If required enable the COMP interrupt by configuring and enabling EXTI line in Interrupt mode and + selecting the desired sensitivity level using HAL_GPIO_Init() function. After that enable the comparator + interrupt vector using HAL_NVIC_EnableIRQ() function. + + (#) Configure the comparator using HAL_COMP_Init() function: + (++) Select the input minus (inverting input) + (++) Select the input plus (non-inverting input) + (++) Select the hysteresis + (++) Select the blanking source + (++) Select the output polarity + (++) Select the power mode + -@@- HAL_COMP_Init() calls "HAL_COMP_MspInit()", COMP clock enable using system RCC + must be implemented in this function. + + (#) Reconfiguration on-the-fly of comparator can be done by calling again + function HAL_COMP_Init() with new input structure parameters values. + + (#) Enable the comparator using HAL_COMP_Start(), HAL_COMP_Start_IT_OneShot() or HAL_COMP_Start_IT_AutoRearm() + Note: Using HAL_COMP_Start_IT_OneShot() or HAL_COMP_Start_IT_AutoRearm(), these functions can change + comparator output polarity to match initial comparator output level constraint. + Note: Using HAL_COMP_Start_IT_OneShot(), after each interruption triggered the interruption + is disabled in IRQ handler. If needed, comparartor interruption can be rearmed by calling again + start function. + Note: In case of comparator and interruption used to exit from low power mode, user most ensure of stable + comparator input voltage (risk would be that comparator trigs early and IT disabled in IRQ handler + before device entering in low power mode, inducing no further system wake up possible). + Most appropriate function is HAL_COMP_Start_IT_AutoRearm() because comparartor triggers remains enable, + ensuring system wake up capability. + + (#) Use HAL_COMP_TriggerCallback() or HAL_COMP_GetOutputLevel() functions + to manage comparator outputs (events and output level). + + (#) Disable the comparator using HAL_COMP_Stop() or HAL_COMP_Stop_IT() functions. + + (#) De-initialize the comparator using HAL_COMP_DeInit() function. + + (#) For safety purpose, comparator configuration can be locked using HAL_COMP_Lock() function. + The only way to unlock the comparator is a device hardware reset. + + *** Callback registration *** + ============================================= + [..] + + The compilation flag USE_HAL_COMP_REGISTER_CALLBACKS, when set to 1, + allows the user to configure dynamically the driver callbacks. + Use Functions HAL_COMP_RegisterCallback() + to register an interrupt callback. + [..] + + Function HAL_COMP_RegisterCallback() allows to register following callbacks: + (+) TriggerCallback : callback for COMP trigger. + (+) MspInitCallback : callback for Msp Init. + (+) MspDeInitCallback : callback for Msp DeInit. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + [..] + + Use function HAL_COMP_UnRegisterCallback to reset a callback to the default + weak function. + [..] + + HAL_COMP_UnRegisterCallback takes as parameters the HAL peripheral handle, + and the Callback ID. + This function allows to reset following callbacks: + (+) TriggerCallback : callback for COMP trigger. + (+) MspInitCallback : callback for Msp Init. + (+) MspDeInitCallback : callback for Msp DeInit. + [..] + + By default, after the HAL_COMP_Init() and when the state is HAL_COMP_STATE_RESET + all callbacks are set to the corresponding weak functions: + example HAL_COMP_TriggerCallback(). + Exception done for MspInit and MspDeInit functions that are + reset to the legacy weak functions in the HAL_COMP_Init() / HAL_COMP_DeInit() only when + these callbacks are null (not registered beforehand). + [..] + + If MspInit or MspDeInit are not null, the HAL_COMP_Init() / HAL_COMP_DeInit() + keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state. + [..] + + Callbacks can be registered/unregistered in HAL_COMP_STATE_READY state only. + Exception done MspInit/MspDeInit functions that can be registered/unregistered + in HAL_COMP_STATE_READY or HAL_COMP_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_COMP_RegisterCallback() before calling HAL_COMP_DeInit() + or HAL_COMP_Init() function. + [..] + + When the compilation flag USE_HAL_COMP_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 "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +#ifdef HAL_COMP_MODULE_ENABLED + +#if defined (COMP1) + +/** @defgroup COMP COMP + * @brief COMP HAL module driver + * @{ + */ + +/* Private typedef ---------------------------------------------------------------------------------------------------*/ +/* Private define ----------------------------------------------------------------------------------------------------*/ +/** @addtogroup COMP_Private_Constants + * @{ + */ + +/* Delay for COMP startup time. */ +/* Note: Delay required to reach propagation delay specification. */ +/* Literal set to maximum value (refer to device datasheet, */ +/* parameter "tSTART"). */ +/* Unit: us */ +#define COMP_DELAY_STARTUP_US (80UL) /*!< Delay for COMP startup time */ + +/* Delay for COMP voltage scaler stabilization time. */ +/* Literal set to maximum value (refer to device datasheet, */ +/* parameter "tSTART_SCALER"). */ +/* Unit: us */ +#define COMP_DELAY_VOLTAGE_SCALER_STAB_US (200UL) /*!< Delay for COMP voltage scaler stabilization time */ + + +/** + * @} + */ + +/* Private macro -----------------------------------------------------------------------------------------------------*/ +/* Private variables -------------------------------------------------------------------------------------------------*/ +/* Private function prototypes ---------------------------------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------------------------------------------------*/ + +/** @defgroup COMP_Exported_Functions COMP Exported Functions + * @{ + */ + +/** @defgroup COMP_Exported_Functions_Group1 Initialization/de-initialization functions + * @brief Initialization and de-initialization functions. + * +@verbatim + ======================================================================================================================= + ##### Initialization and de-initialization functions ##### + ======================================================================================================================= + [..] This section provides functions to initialize and de-initialize comparators + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the COMP according to the specified + * parameters in the COMP_InitTypeDef and initialize the associated handle. + * @note If the selected comparator is locked, initialization can't be performed. + * To unlock the configuration, perform a system reset. + * @param hcomp COMP handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_COMP_Init(COMP_HandleTypeDef *hcomp) +{ + uint32_t tmp_csr; + uint32_t exti_line; + uint32_t comp_voltage_scaler_initialized; /* Value "0" if comparator voltage scaler is not initialized */ + __IO uint32_t wait_loop_index = 0UL; + HAL_StatusTypeDef status = HAL_OK; + + /* Check the COMP handle allocation and lock status */ + if (hcomp == NULL) + { + status = HAL_ERROR; + } + else if (__HAL_COMP_IS_LOCKED(hcomp)) + { + status = HAL_ERROR; + } + else + { + /* Check the parameters */ + assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance)); + assert_param(IS_COMP_INPUT_PLUS(hcomp->Instance, hcomp->Init.InputPlus)); + assert_param(IS_COMP_INPUT_MINUS(hcomp->Instance, hcomp->Init.InputMinus)); + assert_param(IS_COMP_OUTPUTPOL(hcomp->Init.OutputPol)); + assert_param(IS_COMP_POWERMODE(hcomp->Init.Mode)); + assert_param(IS_COMP_HYSTERESIS(hcomp->Init.Hysteresis)); + assert_param(IS_COMP_BLANKINGSRCE(hcomp->Init.BlankingSrce)); + assert_param(IS_COMP_TRIGGERMODE(hcomp->Init.TriggerMode)); + + if (hcomp->State == HAL_COMP_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hcomp->Lock = HAL_UNLOCKED; + + /* Set COMP error code to none */ + COMP_CLEAR_ERRORCODE(hcomp); + + hcomp->InterruptAutoRearm = 0; + +#if (USE_HAL_COMP_REGISTER_CALLBACKS == 1U) + /* Init the COMP Callback settings */ + hcomp->TriggerCallback = HAL_COMP_TriggerCallback; /* Legacy weak callback */ + + if (hcomp->MspInitCallback == NULL) + { + hcomp->MspInitCallback = HAL_COMP_MspInit; /* Legacy weak MspInit */ + } + + /* Init the low level hardware */ + hcomp->MspInitCallback(hcomp); +#else + /* Init the low level hardware */ + HAL_COMP_MspInit(hcomp); +#endif /* USE_HAL_COMP_REGISTER_CALLBACKS */ + } + + /* Memorize voltage scaler state before initialization */ + comp_voltage_scaler_initialized = READ_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_SCALEN); + + /* Set COMP parameters */ + tmp_csr = (hcomp->Init.InputMinus + | hcomp->Init.InputPlus + | hcomp->Init.BlankingSrce + | hcomp->Init.Hysteresis + | hcomp->Init.OutputPol + | hcomp->Init.Mode); + + /* Set parameters in COMP register */ + /* Note: Update all bits except read-only, lock and enable bits */ + MODIFY_REG(hcomp->Instance->CFGR1, + COMP_CFGR1_PWRMODE | COMP_CFGR1_INMSEL | COMP_CFGR1_INPSEL1 + | COMP_CFGR1_INPSEL2 | COMP_CFGR1_POLARITY | COMP_CFGR1_HYST + | COMP_CFGR1_BLANKING | COMP_CFGR1_BRGEN | COMP_CFGR1_SCALEN, + tmp_csr + ); + + if (hcomp->Init.InputPlus == COMP_INPUT_PLUS_IO2) + { + MODIFY_REG(hcomp->Instance->CFGR2, COMP_CFGR2_INPSEL0, COMP_CFGR2_INPSEL0); + } + + /* Delay for COMP scaler bridge voltage stabilization */ + /* Apply the delay if voltage scaler bridge is enabled for the first time */ + if ((READ_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_SCALEN) != 0UL) && + (comp_voltage_scaler_initialized != 0UL)) + { + /* Wait loop initialization and execution */ + /* Note: Variable divided by 2 to compensate partially */ + /* CPU processing cycles, scaling in us split to not */ + /* exceed 32 bits register capacity and handle low frequency. */ + wait_loop_index = ((COMP_DELAY_VOLTAGE_SCALER_STAB_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL)); + while (wait_loop_index != 0UL) + { + wait_loop_index--; + } + } + + /* Get the EXTI line corresponding to the selected COMP instance */ + exti_line = COMP_GET_EXTI_LINE(hcomp->Instance); + + /* Manage EXTI settings */ + if ((hcomp->Init.TriggerMode & COMP_EXTI_IT) != 0UL) + { + LL_EXTI_EnableIT_0_31(exti_line); + } + else + { + /* Disable EXTI interrupt mode */ + LL_EXTI_DisableIT_0_31(exti_line); + } + + /* Set HAL COMP handle state */ + /* Note: Transition from state reset to state ready, */ + /* otherwise (coming from state ready or busy) no state update. */ + if (hcomp->State == HAL_COMP_STATE_RESET) + { + hcomp->State = HAL_COMP_STATE_READY; + } + } + + return status; +} + +/** + * @brief DeInitialize the COMP peripheral. + * @note Deinitialization cannot be performed if the COMP configuration is locked. + * To unlock the configuration, perform a system reset. + * @param hcomp COMP handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_COMP_DeInit(COMP_HandleTypeDef *hcomp) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the COMP handle allocation and lock status */ + if (hcomp == NULL) + { + status = HAL_ERROR; + } + else if (__HAL_COMP_IS_LOCKED(hcomp)) + { + status = HAL_ERROR; + } + else + { + /* Check the parameter */ + assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance)); + + /* Set configuration register to reset value */ + WRITE_REG(hcomp->Instance->CFGR1, 0x00000000UL); + +#if (USE_HAL_COMP_REGISTER_CALLBACKS == 1U) + if (hcomp->MspDeInitCallback == NULL) + { + hcomp->MspDeInitCallback = HAL_COMP_MspDeInit; /* Legacy weak MspDeInit */ + } + + /* DeInit the low level hardware */ + hcomp->MspDeInitCallback(hcomp); +#else + /* DeInit the low level hardware */ + HAL_COMP_MspDeInit(hcomp); +#endif /* USE_HAL_COMP_REGISTER_CALLBACKS */ + + /* Set HAL COMP handle state */ + hcomp->State = HAL_COMP_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hcomp); + } + + return status; +} + +/** + * @brief Initialize the COMP MSP. + * @param hcomp COMP handle + * @retval None + */ +__weak void HAL_COMP_MspInit(COMP_HandleTypeDef *hcomp) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hcomp); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_COMP_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitialize the COMP MSP. + * @param hcomp COMP handle + * @retval None + */ +__weak void HAL_COMP_MspDeInit(COMP_HandleTypeDef *hcomp) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hcomp); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_COMP_MspDeInit could be implemented in the user file + */ +} + +#if (USE_HAL_COMP_REGISTER_CALLBACKS == 1U) +/** + * @brief Register a User COMP Callback + * To be used instead of the weak predefined callback + * @param hcomp Pointer to a COMP_HandleTypeDef structure that contains + * the configuration information for the specified COMP. + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_COMP_TRIGGER_CB_ID Trigger callback ID + * @arg @ref HAL_COMP_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_COMP_MSPDEINIT_CB_ID MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_COMP_RegisterCallback(COMP_HandleTypeDef *hcomp, HAL_COMP_CallbackIDTypeDef CallbackID, + pCOMP_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + if (HAL_COMP_STATE_READY == hcomp->State) + { + switch (CallbackID) + { + case HAL_COMP_TRIGGER_CB_ID : + hcomp->TriggerCallback = pCallback; + break; + + case HAL_COMP_MSPINIT_CB_ID : + hcomp->MspInitCallback = pCallback; + break; + + case HAL_COMP_MSPDEINIT_CB_ID : + hcomp->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_COMP_STATE_RESET == hcomp->State) + { + switch (CallbackID) + { + case HAL_COMP_MSPINIT_CB_ID : + hcomp->MspInitCallback = pCallback; + break; + + case HAL_COMP_MSPDEINIT_CB_ID : + hcomp->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister a COMP Callback + * COMP callback is redirected to the weak predefined callback + * @param hcomp Pointer to a COMP_HandleTypeDef structure that contains + * the configuration information for the specified COMP. + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_COMP_TRIGGER_CB_ID Trigger callback ID + * @arg @ref HAL_COMP_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_COMP_MSPDEINIT_CB_ID MspDeInit callback ID + * @retval HAL status + */ +HAL_StatusTypeDef HAL_COMP_UnRegisterCallback(COMP_HandleTypeDef *hcomp, HAL_COMP_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (HAL_COMP_STATE_READY == hcomp->State) + { + switch (CallbackID) + { + case HAL_COMP_TRIGGER_CB_ID : + hcomp->TriggerCallback = HAL_COMP_TriggerCallback; /* Legacy weak callback */ + break; + + case HAL_COMP_MSPINIT_CB_ID : + hcomp->MspInitCallback = HAL_COMP_MspInit; /* Legacy weak MspInit */ + break; + + case HAL_COMP_MSPDEINIT_CB_ID : + hcomp->MspDeInitCallback = HAL_COMP_MspDeInit; /* Legacy weak MspDeInit */ + break; + + default : + /* Update the error code */ + hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_COMP_STATE_RESET == hcomp->State) + { + switch (CallbackID) + { + case HAL_COMP_MSPINIT_CB_ID : + hcomp->MspInitCallback = HAL_COMP_MspInit; /* Legacy weak MspInit */ + break; + + case HAL_COMP_MSPDEINIT_CB_ID : + hcomp->MspDeInitCallback = HAL_COMP_MspDeInit; /* Legacy weak MspDeInit */ + break; + + default : + /* Update the error code */ + hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +#endif /* USE_HAL_COMP_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup COMP_Exported_Functions_Group2 Start-Stop operation functions + * @brief Start-Stop operation functions. + * +@verbatim + ======================================================================================================================= + ##### IO operation functions ##### + ======================================================================================================================= + [..] This section provides functions allowing to: + (+) Start a comparator instance. + (+) Stop a comparator instance. + +@endverbatim + * @{ + */ + +/** + * @brief Start the comparator. + * @param hcomp COMP handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_COMP_Start(COMP_HandleTypeDef *hcomp) +{ + __IO uint32_t wait_loop_index = 0UL; + + HAL_StatusTypeDef status = HAL_OK; + + /* Check the COMP handle allocation and lock status */ + if (hcomp == NULL) + { + status = HAL_ERROR; + } + else if (__HAL_COMP_IS_LOCKED(hcomp)) + { + status = HAL_ERROR; + } + else + { + /* Check the parameter */ + assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance)); + + if ((hcomp->Init.TriggerMode & COMP_EXTI_IT) != 0UL) + { + /* Case of operation with interruption */ + /* Note: Specific to comparator of this STM32 series featuring IT with direct line only (low latency) */ + status = HAL_COMP_Start_IT_AutoRearm(hcomp); + } + else + { + if (hcomp->State == HAL_COMP_STATE_READY) + { + /* Enable the selected comparator */ + SET_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_EN); + + /* Set HAL COMP handle state */ + hcomp->State = HAL_COMP_STATE_BUSY; + + /* Delay for COMP startup time */ + /* Wait loop initialization and execution */ + /* Note: Variable divided by 2 to compensate partially */ + /* CPU processing cycles, scaling in us split to not */ + /* exceed 32 bits register capacity and handle low frequency. */ + wait_loop_index = ((COMP_DELAY_STARTUP_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL)); + while (wait_loop_index != 0UL) + { + wait_loop_index--; + } + } + else + { + status = HAL_ERROR; + } + } + } + + return status; +} + +/** + * @brief Stop the comparator. + * @param hcomp COMP handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_COMP_Stop(COMP_HandleTypeDef *hcomp) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the COMP handle allocation and lock status */ + if (hcomp == NULL) + { + status = HAL_ERROR; + } + else if (__HAL_COMP_IS_LOCKED(hcomp)) + { + status = HAL_ERROR; + } + else + { + /* Check the parameter */ + assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance)); + + /* Check compliant states: HAL_COMP_STATE_READY or HAL_COMP_STATE_BUSY */ + /* (all states except HAL_COMP_STATE_RESET and except locked status. */ + if (hcomp->State != HAL_COMP_STATE_RESET) + { + /* Disable the selected comparator */ + CLEAR_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_EN); + + /* Set HAL COMP handle state */ + hcomp->State = HAL_COMP_STATE_READY; + } + else + { + status = HAL_ERROR; + } + } + + return status; +} + +/** + * @brief Start the comparator with interruption low latency, interruption disabled at first trigger occurrence. + * @note Interruption low latency is achieved through direct line to NVIC (instead of going through EXTI). + * @note If needed, comparartor interruption can be rearmed by calling again this function. + * @note Specific to comparator of this STM32 series: comparator output triggers interruption on high level. + This function can change output polarity depending on initial output level. + * @param hcomp COMP handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_COMP_Start_IT_OneShot(COMP_HandleTypeDef *hcomp) +{ + __IO uint32_t wait_loop_index = 0UL; + uint32_t polarity_toggle = 0U; + HAL_StatusTypeDef status = HAL_OK; + + /* Check the COMP handle allocation and lock status */ + if (hcomp == NULL) + { + status = HAL_ERROR; + } + else if (__HAL_COMP_IS_LOCKED(hcomp)) + { + status = HAL_ERROR; + } + else + { + /* Check the parameter */ + assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance)); + + if (hcomp->State == HAL_COMP_STATE_READY) + { + /* Enable the selected comparator */ + SET_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_EN); + + /* Set HAL COMP handle state */ + hcomp->State = HAL_COMP_STATE_BUSY; + + /* Delay for COMP startup time */ + /* Wait loop initialization and execution */ + /* Note: Variable divided by 2 to compensate partially */ + /* CPU processing cycles, scaling in us split to not */ + /* exceed 32 bits register capacity and handle low frequency. */ + wait_loop_index = ((COMP_DELAY_STARTUP_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL)); + while (wait_loop_index != 0UL) + { + wait_loop_index--; + } + + /* Check whether initial comparator output level is compliant with interruption mode */ + if (hcomp->Init.TriggerMode == COMP_EXTI_FALLING) + { + if (HAL_COMP_GetOutputLevel(hcomp) != COMP_OUTPUT_LEVEL_HIGH) + { + polarity_toggle = 1U; + } + } + else /* COMP_EXTI_RISING */ + { + if (HAL_COMP_GetOutputLevel(hcomp) != COMP_OUTPUT_LEVEL_LOW) + { + polarity_toggle = 1U; + } + } + + if (polarity_toggle == 1U) + { + /* Toggle poarity */ + if (READ_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_POLARITY) == 0UL) + { + SET_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_POLARITY); + } + else + { + CLEAR_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_POLARITY); + } + } + + /* Enable comparator interruption */ + hcomp->InterruptAutoRearm = 0U; + __HAL_COMP_CLEAR_FLAG(COMP_CLEAR_C1IF); + SET_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_ITEN); + } + else + { + status = HAL_ERROR; + } + } + + return status; +} + +/** + * @brief Start the comparator with interruption low latency, interruption rearmed at each trigger occurrence. + * @note Interruption low latency is achieved through direct line to NVIC (instead of going through EXTI). + * @note If needed, comparartor interruption can be rearmed by calling again this function. + * @note Specific to comparator of this STM32 series: comparator output triggers interruption on high level. + This function can change output polarity depending on initial output level. + * @param hcomp COMP handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_COMP_Start_IT_AutoRearm(COMP_HandleTypeDef *hcomp) +{ + __IO uint32_t wait_loop_index = 0UL; + uint32_t polarity_toggle = 0U; + HAL_StatusTypeDef status = HAL_OK; + + /* Check the COMP handle allocation and lock status */ + if (hcomp == NULL) + { + status = HAL_ERROR; + } + else if (__HAL_COMP_IS_LOCKED(hcomp)) + { + status = HAL_ERROR; + } + else + { + /* Check the parameter */ + assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance)); + + if (hcomp->State == HAL_COMP_STATE_READY) + { + /* Enable the selected comparator */ + SET_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_EN); + + /* Set HAL COMP handle state */ + hcomp->State = HAL_COMP_STATE_BUSY; + + /* Delay for COMP startup time */ + /* Wait loop initialization and execution */ + /* Note: Variable divided by 2 to compensate partially */ + /* CPU processing cycles, scaling in us split to not */ + /* exceed 32 bits register capacity and handle low frequency. */ + wait_loop_index = ((COMP_DELAY_STARTUP_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL)); + while (wait_loop_index != 0UL) + { + wait_loop_index--; + } + + /* Check whether initial comparator output level is compliant with interruption mode */ + if (hcomp->Init.TriggerMode == COMP_EXTI_FALLING) + { + if (HAL_COMP_GetOutputLevel(hcomp) != COMP_OUTPUT_LEVEL_HIGH) + { + polarity_toggle = 1U; + } + } + else /* COMP_EXTI_RISING */ + { + if (HAL_COMP_GetOutputLevel(hcomp) != COMP_OUTPUT_LEVEL_LOW) + { + polarity_toggle = 1U; + } + } + + if (polarity_toggle == 1U) + { + /* Toggle poarity */ + if (READ_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_POLARITY) == 0UL) + { + SET_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_POLARITY); + } + else + { + CLEAR_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_POLARITY); + } + } + + /* Enable comparator interruption */ + hcomp->InterruptAutoRearm = 1U; + __HAL_COMP_CLEAR_FLAG(COMP_CLEAR_C1IF); + SET_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_ITEN); + } + else + { + status = HAL_ERROR; + } + } + + return status; +} + +/** + * @brief Disable the interrupt and Stop the comparator. + * @param hcomp COMP handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_COMP_Stop_IT(COMP_HandleTypeDef *hcomp) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the COMP handle allocation and lock status */ + if (hcomp == NULL) + { + status = HAL_ERROR; + } + else if (__HAL_COMP_IS_LOCKED(hcomp)) + { + status = HAL_ERROR; + } + else + { + /* Check the parameter */ + assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance)); + + /* Check compliant states: HAL_COMP_STATE_READY or HAL_COMP_STATE_BUSY */ + /* (all states except HAL_COMP_STATE_RESET and except locked status. */ + if (hcomp->State != HAL_COMP_STATE_RESET) + { + /* Disable the selected comparator */ + CLEAR_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_EN); + + /* Disable the EXTI Line interrupt mode */ + CLEAR_BIT(EXTI->IMR1, COMP_GET_EXTI_LINE(hcomp->Instance)); + + /* Disable the Interrupt comparator */ + CLEAR_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_ITEN); + + /* Set HAL COMP handle state */ + hcomp->State = HAL_COMP_STATE_READY; + } + else + { + status = HAL_ERROR; + } + } + + return status; +} + +/** + * @brief Comparator IRQ handler. + * @param hcomp COMP handle + * @retval None + */ +void HAL_COMP_IRQHandler(COMP_HandleTypeDef *hcomp) +{ + uint32_t polarity_toggle = 0U; + + /* Disable COMP interrupt */ + /* Note: Specific to comparator of this STM32 series: comparator output triggers interruption on high level. */ + __HAL_COMP_DISABLE_IT(hcomp, COMP_IT_EN); + + /* Clear COMP1 interrupt flag */ + __HAL_COMP_CLEAR_C1IFLAG(); + NVIC_ClearPendingIRQ(COMP1_IRQn); + + /* COMP trigger callback */ +#if (USE_HAL_COMP_REGISTER_CALLBACKS == 1U) + hcomp->TriggerCallback(hcomp); +#else + HAL_COMP_TriggerCallback(hcomp); +#endif /* USE_HAL_COMP_REGISTER_CALLBACKS */ + + if (hcomp->InterruptAutoRearm == 1U) + { + /* Check whether initial comparator output level is compliant with interruption mode */ + if (hcomp->Init.TriggerMode == COMP_EXTI_FALLING) + { + if (HAL_COMP_GetOutputLevel(hcomp) != COMP_OUTPUT_LEVEL_HIGH) + { + polarity_toggle = 1U; + } + } + else /* COMP_EXTI_RISING */ + { + if (HAL_COMP_GetOutputLevel(hcomp) != COMP_OUTPUT_LEVEL_LOW) + { + polarity_toggle = 1U; + } + } + + if (polarity_toggle == 1U) + { + /* Toggle poarity */ + if (READ_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_POLARITY) == 0UL) + { + SET_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_POLARITY); + } + else + { + CLEAR_BIT(hcomp->Instance->CFGR1, COMP_CFGR1_POLARITY); + } + } + + /* Enable COMP interrupt */ + __HAL_COMP_ENABLE_IT(hcomp, COMP_IT_EN); + } + else + { + /* Change COMP state */ + hcomp->State = HAL_COMP_STATE_READY; + } +} + +/** + * @} + */ + +/** @defgroup COMP_Exported_Functions_Group3 Peripheral Control functions + * @brief Management functions. + * +@verbatim + ======================================================================================================================= + ##### Peripheral Control functions ##### + ======================================================================================================================= + [..] + This subsection provides a set of functions allowing to control the comparators. + +@endverbatim + * @{ + */ + +/** + * @brief Lock the selected comparator configuration. + * @note A system reset is required to unlock the comparator configuration. + * @param hcomp COMP handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_COMP_Lock(COMP_HandleTypeDef *hcomp) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the COMP handle allocation and lock status */ + if (hcomp == NULL) + { + status = HAL_ERROR; + } + else if (__HAL_COMP_IS_LOCKED(hcomp)) + { + status = HAL_ERROR; + } + else + { + /* Check the parameter */ + assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance)); + + /* Set HAL COMP handle state */ + switch (hcomp->State) + { + case HAL_COMP_STATE_RESET: + hcomp->State = HAL_COMP_STATE_RESET_LOCKED; + break; + case HAL_COMP_STATE_READY: + hcomp->State = HAL_COMP_STATE_READY_LOCKED; + break; + default: /* HAL_COMP_STATE_BUSY */ + hcomp->State = HAL_COMP_STATE_BUSY_LOCKED; + break; + } + + /* Set the lock bit corresponding to selected comparator */ + __HAL_COMP_LOCK(hcomp); + } + return status; +} + +/** + * @brief Return the output level (high or low) of the selected comparator. + * @note The output level depends on the selected polarity. + * If the polarity is not inverted: + * - Comparator output is low when the input plus is at a lower + * voltage than the input minus + * - Comparator output is high when the input plus is at a higher + * voltage than the input minus + * If the polarity is inverted: + * - Comparator output is high when the input plus is at a lower + * voltage than the input minus + * - Comparator output is low when the input plus is at a higher + * voltage than the input minus + * @note Specific to comparator of this STM32 series: comparator output + * triggers interruption on high level. HAL_COMP_Start_x functions + * can change output polarity depending on initial output level. + * @param hcomp COMP handle + * @retval Returns the selected comparator output level: + * @arg @ref COMP_OUTPUT_LEVEL_LOW + * @arg @ref COMP_OUTPUT_LEVEL_HIGH + * + */ +uint32_t HAL_COMP_GetOutputLevel(const COMP_HandleTypeDef *hcomp) +{ + /* Check the parameter */ + assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance)); + + return (uint32_t)(READ_BIT(COMP1->SR, COMP_SR_C1VAL)); +} + +/** + * @brief Comparator trigger callback. + * @param hcomp COMP handle + * @retval None + */ +__weak void HAL_COMP_TriggerCallback(COMP_HandleTypeDef *hcomp) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hcomp); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_COMP_TriggerCallback should be implemented in the user file + */ +} + + +/** + * @} + */ + +/** @defgroup COMP_Exported_Functions_Group4 Peripheral State functions + * @brief Peripheral State functions. + * +@verbatim + ======================================================================================================================= + ##### Peripheral State functions ##### + ======================================================================================================================= + [..] + This subsection permit to get in run-time the status of the peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Return the COMP handle state. + * @param hcomp COMP handle + * @retval HAL state + */ +HAL_COMP_StateTypeDef HAL_COMP_GetState(const COMP_HandleTypeDef *hcomp) +{ + /* Check the COMP handle allocation */ + if (hcomp == NULL) + { + return HAL_COMP_STATE_RESET; + } + + /* Check the parameter */ + assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance)); + + /* Return HAL COMP handle state */ + return hcomp->State; +} + +/** + * @brief Return the COMP error code. + * @param hcomp COMP handle + * @retval COMP error code + */ +uint32_t HAL_COMP_GetError(const COMP_HandleTypeDef *hcomp) +{ + /* Check the parameters */ + assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance)); + + return hcomp->ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* COMP1 */ + +#endif /* HAL_COMP_MODULE_ENABLED */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_cordic.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_cordic.c new file mode 100644 index 0000000000..05cad67415 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_cordic.c @@ -0,0 +1,1357 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_cordic.c + * @author MCD Application Team + * @brief CORDIC HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the CORDIC peripheral: + * + Initialization and de-initialization functions + * + Peripheral Control functions + * + Callback functions + * + IRQ handler management + * + Peripheral State functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ================================================================================ + ##### How to use this driver ##### + ================================================================================ + [..] + The CORDIC HAL driver can be used as follows: + + (#) Initialize the CORDIC low level resources by implementing the HAL_CORDIC_MspInit(): + (++) Enable the CORDIC interface clock using __HAL_RCC_CORDIC_CLK_ENABLE() + (++) In case of using interrupts (e.g. HAL_CORDIC_Calculate_IT()) + (+++) Configure the CORDIC interrupt priority using HAL_NVIC_SetPriority() + (+++) Enable the CORDIC IRQ handler using HAL_NVIC_EnableIRQ() + (+++) In CORDIC IRQ handler, call HAL_CORDIC_IRQHandler() + (++) In case of using DMA to control data transfer (e.g. HAL_CORDIC_Calculate_DMA()) + (+++) Enable the DMA2 interface clock using + __HAL_RCC_DMA2_CLK_ENABLE() + (+++) Configure and enable two DMA channels one for managing data transfer from + memory to peripheral (input channel) and another channel for managing data + transfer from peripheral to memory (output channel) + (+++) Associate the initialized DMA handle to the CORDIC DMA handle + using __HAL_LINKDMA() + (+++) Configure the priority and enable the NVIC for the transfer complete + interrupt on the two DMA channels. + Resort to HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ() + + (#) Initialize the CORDIC HAL using HAL_CORDIC_Init(). This function + (++) resorts to HAL_CORDIC_MspInit() for low-level initialization, + + (#) Configure CORDIC processing (calculation) using HAL_CORDIC_Configure(). + This function configures: + (++) Processing functions: Cosine, Sine, Phase, Modulus, Arctangent, + Hyperbolic cosine, Hyperbolic sine, Hyperbolic arctangent, + Natural log, Square root + (++) Scaling factor: 1 to 2exp(-7) + (++) Width of input data: 32 bits input data size (Q1.31 format) or 16 bits + input data size (Q1.15 format) + (++) Width of output data: 32 bits output data size (Q1.31 format) or 16 bits + output data size (Q1.15 format) + (++) Number of 32-bit write expected for one calculation: One 32-bits write + or Two 32-bit write + (++) Number of 32-bit read expected after one calculation: One 32-bits read + or Two 32-bit read + (++) Precision: 1 to 15 cycles for calculation (the more cycles, the better precision) + + (#) Four processing (calculation) functions are available: + (++) Polling mode: processing API is blocking function + i.e. it processes the data and wait till the processing is finished + API is HAL_CORDIC_Calculate + (++) Polling Zero-overhead mode: processing API is blocking function + i.e. it processes the data and wait till the processing is finished + A bit faster than standard polling mode, but blocking also AHB bus + API is HAL_CORDIC_CalculateZO + (++) Interrupt mode: processing API is not blocking functions + i.e. it processes the data under interrupt + API is HAL_CORDIC_Calculate_IT + (++) DMA mode: processing API is not blocking functions and the CPU is + not used for data transfer, + i.e. the data transfer is ensured by DMA + API is HAL_CORDIC_Calculate_DMA + + (#) Call HAL_CORDIC_DeInit() to de-initialize the CORDIC peripheral. This function + (++) resorts to HAL_CORDIC_MspDeInit() for low-level de-initialization, + + *** Callback registration *** + ============================================= + + The compilation define USE_HAL_CORDIC_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + Use Function HAL_CORDIC_RegisterCallback() to register an interrupt callback. + + Function HAL_CORDIC_RegisterCallback() allows to register following callbacks: + (+) ErrorCallback : Error Callback. + (+) CalculateCpltCallback : Calculate complete Callback. + (+) MspInitCallback : CORDIC MspInit. + (+) MspDeInitCallback : CORDIC MspDeInit. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + + Use function HAL_CORDIC_UnRegisterCallback() to reset a callback to the default + weak function. + HAL_CORDIC_UnRegisterCallback takes as parameters the HAL peripheral handle, + and the Callback ID. + This function allows to reset following callbacks: + (+) ErrorCallback : Error Callback. + (+) CalculateCpltCallback : Calculate complete Callback. + (+) MspInitCallback : CORDIC MspInit. + (+) MspDeInitCallback : CORDIC MspDeInit. + + By default, after the HAL_CORDIC_Init() and when the state is HAL_CORDIC_STATE_RESET, + all callbacks are set to the corresponding weak functions: + examples HAL_CORDIC_ErrorCallback(), HAL_CORDIC_CalculateCpltCallback(). + Exception done for MspInit and MspDeInit functions that are + reset to the legacy weak function in the HAL_CORDIC_Init()/ HAL_CORDIC_DeInit() only when + these callbacks are null (not registered beforehand). + if not, MspInit or MspDeInit are not null, the HAL_CORDIC_Init()/ HAL_CORDIC_DeInit() + keep and use the user MspInit/MspDeInit callbacks (registered beforehand) + + Callbacks can be registered/unregistered in HAL_CORDIC_STATE_READY state only. + Exception done MspInit/MspDeInit that can be registered/unregistered + in HAL_CORDIC_STATE_READY or HAL_CORDIC_STATE_RESET state, + thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. + In that case first register the MspInit/MspDeInit user callbacks + using HAL_CORDIC_RegisterCallback() before calling HAL_CORDIC_DeInit() + or HAL_CORDIC_Init() function. + + When The compilation define USE_HAL_CORDIC_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 "stm32h5xx_hal.h" + +#if defined(CORDIC) +#ifdef HAL_CORDIC_MODULE_ENABLED + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup CORDIC CORDIC + * @brief CORDIC HAL driver modules. + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ + +/** @defgroup CORDIC_Private_Functions CORDIC Private Functions + * @{ + */ +static void CORDIC_WriteInDataIncrementPtr(const CORDIC_HandleTypeDef *hcordic, const int32_t **ppInBuff); +static void CORDIC_ReadOutDataIncrementPtr(const CORDIC_HandleTypeDef *hcordic, int32_t **ppOutBuff); +static void CORDIC_DMAInCplt(DMA_HandleTypeDef *hdma); +static void CORDIC_DMAOutCplt(DMA_HandleTypeDef *hdma); +static void CORDIC_DMAError(DMA_HandleTypeDef *hdma); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup CORDIC_Exported_Functions CORDIC Exported Functions + * @{ + */ + +/** @defgroup CORDIC_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 the CORDIC peripheral and the associated handle + (+) DeInitialize the CORDIC peripheral + (+) Initialize the CORDIC MSP (MCU Specific Package) + (+) De-Initialize the CORDIC MSP + + [..] + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the CORDIC peripheral and the associated handle. + * @param hcordic pointer to a CORDIC_HandleTypeDef structure. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CORDIC_Init(CORDIC_HandleTypeDef *hcordic) +{ + /* Check the CORDIC handle allocation */ + if (hcordic == NULL) + { + /* Return error status */ + return HAL_ERROR; + } + + /* Check the instance */ + assert_param(IS_CORDIC_ALL_INSTANCE(hcordic->Instance)); + +#if USE_HAL_CORDIC_REGISTER_CALLBACKS == 1 + if (hcordic->State == HAL_CORDIC_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hcordic->Lock = HAL_UNLOCKED; + + /* Reset callbacks to legacy functions */ + hcordic->ErrorCallback = HAL_CORDIC_ErrorCallback; /* Legacy weak ErrorCallback */ + hcordic->CalculateCpltCallback = HAL_CORDIC_CalculateCpltCallback; /* Legacy weak CalculateCpltCallback */ + + if (hcordic->MspInitCallback == NULL) + { + hcordic->MspInitCallback = HAL_CORDIC_MspInit; /* Legacy weak MspInit */ + } + + /* Initialize the low level hardware */ + hcordic->MspInitCallback(hcordic); + } +#else + if (hcordic->State == HAL_CORDIC_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hcordic->Lock = HAL_UNLOCKED; + + /* Initialize the low level hardware */ + HAL_CORDIC_MspInit(hcordic); + } +#endif /* (USE_HAL_CORDIC_REGISTER_CALLBACKS) */ + + /* Set CORDIC error code to none */ + hcordic->ErrorCode = HAL_CORDIC_ERROR_NONE; + + /* Reset pInBuff and pOutBuff */ + hcordic->pInBuff = NULL; + hcordic->pOutBuff = NULL; + + /* Reset NbCalcToOrder and NbCalcToGet */ + hcordic->NbCalcToOrder = 0U; + hcordic->NbCalcToGet = 0U; + + /* Reset DMADirection */ + hcordic->DMADirection = CORDIC_DMA_DIR_NONE; + + /* Change CORDIC peripheral state */ + hcordic->State = HAL_CORDIC_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief DeInitialize the CORDIC peripheral. + * @param hcordic pointer to a CORDIC_HandleTypeDef structure. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CORDIC_DeInit(CORDIC_HandleTypeDef *hcordic) +{ + /* Check the CORDIC handle allocation */ + if (hcordic == NULL) + { + /* Return error status */ + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_CORDIC_ALL_INSTANCE(hcordic->Instance)); + + /* Change CORDIC peripheral state */ + hcordic->State = HAL_CORDIC_STATE_BUSY; + +#if USE_HAL_CORDIC_REGISTER_CALLBACKS == 1 + if (hcordic->MspDeInitCallback == NULL) + { + hcordic->MspDeInitCallback = HAL_CORDIC_MspDeInit; + } + + /* De-Initialize the low level hardware */ + hcordic->MspDeInitCallback(hcordic); +#else + /* De-Initialize the low level hardware: CLOCK, NVIC, DMA */ + HAL_CORDIC_MspDeInit(hcordic); +#endif /* USE_HAL_CORDIC_REGISTER_CALLBACKS */ + + /* Set CORDIC error code to none */ + hcordic->ErrorCode = HAL_CORDIC_ERROR_NONE; + + /* Reset pInBuff and pOutBuff */ + hcordic->pInBuff = NULL; + hcordic->pOutBuff = NULL; + + /* Reset NbCalcToOrder and NbCalcToGet */ + hcordic->NbCalcToOrder = 0U; + hcordic->NbCalcToGet = 0U; + + /* Reset DMADirection */ + hcordic->DMADirection = CORDIC_DMA_DIR_NONE; + + /* Change CORDIC peripheral state */ + hcordic->State = HAL_CORDIC_STATE_RESET; + + /* Reset Lock */ + hcordic->Lock = HAL_UNLOCKED; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initialize the CORDIC MSP. + * @param hcordic CORDIC handle + * @retval None + */ +__weak void HAL_CORDIC_MspInit(CORDIC_HandleTypeDef *hcordic) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hcordic); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_CORDIC_MspInit can be implemented in the user file + */ +} + +/** + * @brief DeInitialize the CORDIC MSP. + * @param hcordic CORDIC handle + * @retval None + */ +__weak void HAL_CORDIC_MspDeInit(CORDIC_HandleTypeDef *hcordic) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hcordic); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_CORDIC_MspDeInit can be implemented in the user file + */ +} + +#if USE_HAL_CORDIC_REGISTER_CALLBACKS == 1 +/** + * @brief Register a CORDIC CallBack. + * To be used instead of the weak predefined callback. + * @param hcordic pointer to a CORDIC_HandleTypeDef structure that contains + * the configuration information for CORDIC module + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_CORDIC_ERROR_CB_ID error Callback ID + * @arg @ref HAL_CORDIC_CALCULATE_CPLT_CB_ID calculate complete Callback ID + * @arg @ref HAL_CORDIC_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_CORDIC_MSPDEINIT_CB_ID MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CORDIC_RegisterCallback(CORDIC_HandleTypeDef *hcordic, HAL_CORDIC_CallbackIDTypeDef CallbackID, + void (* pCallback)(CORDIC_HandleTypeDef *_hcordic)) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hcordic->ErrorCode |= HAL_CORDIC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + return HAL_ERROR; + } + + if (hcordic->State == HAL_CORDIC_STATE_READY) + { + switch (CallbackID) + { + case HAL_CORDIC_ERROR_CB_ID : + hcordic->ErrorCallback = pCallback; + break; + + case HAL_CORDIC_CALCULATE_CPLT_CB_ID : + hcordic->CalculateCpltCallback = pCallback; + break; + + case HAL_CORDIC_MSPINIT_CB_ID : + hcordic->MspInitCallback = pCallback; + break; + + case HAL_CORDIC_MSPDEINIT_CB_ID : + hcordic->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hcordic->ErrorCode |= HAL_CORDIC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (hcordic->State == HAL_CORDIC_STATE_RESET) + { + switch (CallbackID) + { + case HAL_CORDIC_MSPINIT_CB_ID : + hcordic->MspInitCallback = pCallback; + break; + + case HAL_CORDIC_MSPDEINIT_CB_ID : + hcordic->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hcordic->ErrorCode |= HAL_CORDIC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hcordic->ErrorCode |= HAL_CORDIC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} +#endif /* USE_HAL_CORDIC_REGISTER_CALLBACKS */ + +#if USE_HAL_CORDIC_REGISTER_CALLBACKS == 1 +/** + * @brief Unregister a CORDIC CallBack. + * CORDIC callback is redirected to the weak predefined callback. + * @param hcordic pointer to a CORDIC_HandleTypeDef structure that contains + * the configuration information for CORDIC module + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_CORDIC_ERROR_CB_ID error Callback ID + * @arg @ref HAL_CORDIC_CALCULATE_CPLT_CB_ID calculate complete Callback ID + * @arg @ref HAL_CORDIC_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_CORDIC_MSPDEINIT_CB_ID MspDeInit callback ID + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CORDIC_UnRegisterCallback(CORDIC_HandleTypeDef *hcordic, HAL_CORDIC_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (hcordic->State == HAL_CORDIC_STATE_READY) + { + switch (CallbackID) + { + case HAL_CORDIC_ERROR_CB_ID : + hcordic->ErrorCallback = HAL_CORDIC_ErrorCallback; + break; + + case HAL_CORDIC_CALCULATE_CPLT_CB_ID : + hcordic->CalculateCpltCallback = HAL_CORDIC_CalculateCpltCallback; + break; + + case HAL_CORDIC_MSPINIT_CB_ID : + hcordic->MspInitCallback = HAL_CORDIC_MspInit; + break; + + case HAL_CORDIC_MSPDEINIT_CB_ID : + hcordic->MspDeInitCallback = HAL_CORDIC_MspDeInit; + break; + + default : + /* Update the error code */ + hcordic->ErrorCode |= HAL_CORDIC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (hcordic->State == HAL_CORDIC_STATE_RESET) + { + switch (CallbackID) + { + case HAL_CORDIC_MSPINIT_CB_ID : + hcordic->MspInitCallback = HAL_CORDIC_MspInit; + break; + + case HAL_CORDIC_MSPDEINIT_CB_ID : + hcordic->MspDeInitCallback = HAL_CORDIC_MspDeInit; + break; + + default : + /* Update the error code */ + hcordic->ErrorCode |= HAL_CORDIC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hcordic->ErrorCode |= HAL_CORDIC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} +#endif /* USE_HAL_CORDIC_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup CORDIC_Exported_Functions_Group2 Peripheral Control functions + * @brief Control functions. + * +@verbatim + ============================================================================== + ##### Peripheral Control functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) Configure the CORDIC peripheral: function, precision, scaling factor, + number of input data and output data, size of input data and output data. + (+) Calculate output data of CORDIC processing on input date, using the + existing CORDIC configuration + [..] Four processing functions are available for calculation: + (+) Polling mode + (+) Polling mode, with Zero-Overhead register access + (+) Interrupt mode + (+) DMA mode + +@endverbatim + * @{ + */ + +/** + * @brief Configure the CORDIC processing according to the specified + parameters in the CORDIC_ConfigTypeDef structure. + * @param hcordic pointer to a CORDIC_HandleTypeDef structure that contains + * the configuration information for CORDIC module + * @param sConfig pointer to a CORDIC_ConfigTypeDef structure that + * contains the CORDIC configuration information. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CORDIC_Configure(CORDIC_HandleTypeDef *hcordic, const CORDIC_ConfigTypeDef *sConfig) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_CORDIC_FUNCTION(sConfig->Function)); + assert_param(IS_CORDIC_PRECISION(sConfig->Precision)); + assert_param(IS_CORDIC_SCALE(sConfig->Scale)); + assert_param(IS_CORDIC_NBWRITE(sConfig->NbWrite)); + assert_param(IS_CORDIC_NBREAD(sConfig->NbRead)); + assert_param(IS_CORDIC_INSIZE(sConfig->InSize)); + assert_param(IS_CORDIC_OUTSIZE(sConfig->OutSize)); + + /* Check handle state is ready */ + if (hcordic->State == HAL_CORDIC_STATE_READY) + { + /* Apply all configuration parameters in CORDIC control register */ + MODIFY_REG(hcordic->Instance->CSR, \ + (CORDIC_CSR_FUNC | CORDIC_CSR_PRECISION | CORDIC_CSR_SCALE | \ + CORDIC_CSR_NARGS | CORDIC_CSR_NRES | CORDIC_CSR_ARGSIZE | CORDIC_CSR_RESSIZE), \ + (sConfig->Function | sConfig->Precision | sConfig->Scale | \ + sConfig->NbWrite | sConfig->NbRead | sConfig->InSize | sConfig->OutSize)); + } + else + { + /* Set CORDIC error code */ + hcordic->ErrorCode |= HAL_CORDIC_ERROR_NOT_READY; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Return function status */ + return status; +} + +/** + * @brief Carry out data of CORDIC processing in polling mode, + * according to the existing CORDIC configuration. + * @param hcordic pointer to a CORDIC_HandleTypeDef structure that contains + * the configuration information for CORDIC module. + * @param pInBuff Pointer to buffer containing input data for CORDIC processing. + * @param pOutBuff Pointer to buffer where output data of CORDIC processing will be stored. + * @param NbCalc Number of CORDIC calculation to process. + * @param Timeout Specify Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CORDIC_Calculate(CORDIC_HandleTypeDef *hcordic, const int32_t *pInBuff, int32_t *pOutBuff, + uint32_t NbCalc, uint32_t Timeout) +{ + uint32_t tickstart; + uint32_t index; + const int32_t *p_tmp_in_buff = pInBuff; + int32_t *p_tmp_out_buff = pOutBuff; + + /* Check parameters setting */ + if ((pInBuff == NULL) || (pOutBuff == NULL) || (NbCalc == 0U)) + { + /* Update the error code */ + hcordic->ErrorCode |= HAL_CORDIC_ERROR_PARAM; + + /* Return error status */ + return HAL_ERROR; + } + + /* Check handle state is ready */ + if (hcordic->State == HAL_CORDIC_STATE_READY) + { + /* Reset CORDIC error code */ + hcordic->ErrorCode = HAL_CORDIC_ERROR_NONE; + + /* Change the CORDIC state */ + hcordic->State = HAL_CORDIC_STATE_BUSY; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Write of input data in Write Data register, and increment input buffer pointer */ + CORDIC_WriteInDataIncrementPtr(hcordic, &p_tmp_in_buff); + + /* Calculation is started. + Provide next set of input data, until number of calculation is achieved */ + for (index = (NbCalc - 1U); index > 0U; index--) + { + /* Write of input data in Write Data register, and increment input buffer pointer */ + CORDIC_WriteInDataIncrementPtr(hcordic, &p_tmp_in_buff); + + /* Wait for RRDY flag to be raised */ + do + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if ((HAL_GetTick() - tickstart) > Timeout) + { + /* Set CORDIC error code */ + hcordic->ErrorCode = HAL_CORDIC_ERROR_TIMEOUT; + + /* Change the CORDIC state */ + hcordic->State = HAL_CORDIC_STATE_READY; + + /* Return function status */ + return HAL_ERROR; + } + } + } while (HAL_IS_BIT_CLR(hcordic->Instance->CSR, CORDIC_CSR_RRDY)); + + /* Read output data from Read Data register, and increment output buffer pointer */ + CORDIC_ReadOutDataIncrementPtr(hcordic, &p_tmp_out_buff); + } + + /* Read output data from Read Data register, and increment output buffer pointer */ + CORDIC_ReadOutDataIncrementPtr(hcordic, &p_tmp_out_buff); + + /* Change the CORDIC state */ + hcordic->State = HAL_CORDIC_STATE_READY; + + /* Return function status */ + return HAL_OK; + } + else + { + /* Set CORDIC error code */ + hcordic->ErrorCode |= HAL_CORDIC_ERROR_NOT_READY; + + /* Return function status */ + return HAL_ERROR; + } +} + +/** + * @brief Carry out data of CORDIC processing in Zero-Overhead mode (output data being read + * soon as input data are written), according to the existing CORDIC configuration. + * @param hcordic pointer to a CORDIC_HandleTypeDef structure that contains + * the configuration information for CORDIC module. + * @param pInBuff Pointer to buffer containing input data for CORDIC processing. + * @param pOutBuff Pointer to buffer where output data of CORDIC processing will be stored. + * @param NbCalc Number of CORDIC calculation to process. + * @param Timeout Specify Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CORDIC_CalculateZO(CORDIC_HandleTypeDef *hcordic, const int32_t *pInBuff, int32_t *pOutBuff, + uint32_t NbCalc, uint32_t Timeout) +{ + uint32_t tickstart; + uint32_t index; + const int32_t *p_tmp_in_buff = pInBuff; + int32_t *p_tmp_out_buff = pOutBuff; + + /* Check parameters setting */ + if ((pInBuff == NULL) || (pOutBuff == NULL) || (NbCalc == 0U)) + { + /* Update the error code */ + hcordic->ErrorCode |= HAL_CORDIC_ERROR_PARAM; + + /* Return error status */ + return HAL_ERROR; + } + + /* Check handle state is ready */ + if (hcordic->State == HAL_CORDIC_STATE_READY) + { + /* Reset CORDIC error code */ + hcordic->ErrorCode = HAL_CORDIC_ERROR_NONE; + + /* Change the CORDIC state */ + hcordic->State = HAL_CORDIC_STATE_BUSY; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Write of input data in Write Data register, and increment input buffer pointer */ + CORDIC_WriteInDataIncrementPtr(hcordic, &p_tmp_in_buff); + + /* Calculation is started. + Provide next set of input data, until number of calculation is achieved */ + for (index = (NbCalc - 1U); index > 0U; index--) + { + /* Write of input data in Write Data register, and increment input buffer pointer */ + CORDIC_WriteInDataIncrementPtr(hcordic, &p_tmp_in_buff); + + /* Read output data from Read Data register, and increment output buffer pointer + The reading is performed in Zero-Overhead mode: + reading is ordered immediately without waiting result ready flag */ + CORDIC_ReadOutDataIncrementPtr(hcordic, &p_tmp_out_buff); + + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if ((HAL_GetTick() - tickstart) > Timeout) + { + /* Set CORDIC error code */ + hcordic->ErrorCode = HAL_CORDIC_ERROR_TIMEOUT; + + /* Change the CORDIC state */ + hcordic->State = HAL_CORDIC_STATE_READY; + + /* Return function status */ + return HAL_ERROR; + } + } + } + + /* Read output data from Read Data register, and increment output buffer pointer + The reading is performed in Zero-Overhead mode: + reading is ordered immediately without waiting result ready flag */ + CORDIC_ReadOutDataIncrementPtr(hcordic, &p_tmp_out_buff); + + /* Change the CORDIC state */ + hcordic->State = HAL_CORDIC_STATE_READY; + + /* Return function status */ + return HAL_OK; + } + else + { + /* Set CORDIC error code */ + hcordic->ErrorCode |= HAL_CORDIC_ERROR_NOT_READY; + + /* Return function status */ + return HAL_ERROR; + } +} + +/** + * @brief Carry out data of CORDIC processing in interrupt mode, + * according to the existing CORDIC configuration. + * @param hcordic pointer to a CORDIC_HandleTypeDef structure that contains + * the configuration information for CORDIC module. + * @param pInBuff Pointer to buffer containing input data for CORDIC processing. + * @param pOutBuff Pointer to buffer where output data of CORDIC processing will be stored. + * @param NbCalc Number of CORDIC calculation to process. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CORDIC_Calculate_IT(CORDIC_HandleTypeDef *hcordic, const int32_t *pInBuff, int32_t *pOutBuff, + uint32_t NbCalc) +{ + const int32_t *tmp_pInBuff = pInBuff; + + /* Check parameters setting */ + if ((pInBuff == NULL) || (pOutBuff == NULL) || (NbCalc == 0U)) + { + /* Update the error code */ + hcordic->ErrorCode |= HAL_CORDIC_ERROR_PARAM; + + /* Return error status */ + return HAL_ERROR; + } + + /* Check handle state is ready */ + if (hcordic->State == HAL_CORDIC_STATE_READY) + { + /* Reset CORDIC error code */ + hcordic->ErrorCode = HAL_CORDIC_ERROR_NONE; + + /* Change the CORDIC state */ + hcordic->State = HAL_CORDIC_STATE_BUSY; + + /* Store the buffers addresses and number of calculations in handle, + provisioning initial write of input data that will be done */ + if (HAL_IS_BIT_SET(hcordic->Instance->CSR, CORDIC_CSR_NARGS)) + { + /* Two writes of input data are expected */ + tmp_pInBuff++; + tmp_pInBuff++; + } + else + { + /* One write of input data is expected */ + tmp_pInBuff++; + } + hcordic->pInBuff = tmp_pInBuff; + hcordic->pOutBuff = pOutBuff; + hcordic->NbCalcToOrder = NbCalc - 1U; + hcordic->NbCalcToGet = NbCalc; + + /* Enable Result Ready Interrupt */ + __HAL_CORDIC_ENABLE_IT(hcordic, CORDIC_IT_IEN); + + /* Set back pointer to start of input data buffer */ + tmp_pInBuff = pInBuff; + + /* Initiate the processing by providing input data + in the Write Data register */ + WRITE_REG(hcordic->Instance->WDATA, (uint32_t)*tmp_pInBuff); + + /* Check if second write of input data is expected */ + if (HAL_IS_BIT_SET(hcordic->Instance->CSR, CORDIC_CSR_NARGS)) + { + /* Increment pointer to input data */ + tmp_pInBuff++; + + /* Perform second write of input data */ + WRITE_REG(hcordic->Instance->WDATA, (uint32_t)*tmp_pInBuff); + } + + /* Return function status */ + return HAL_OK; + } + else + { + /* Set CORDIC error code */ + hcordic->ErrorCode |= HAL_CORDIC_ERROR_NOT_READY; + + /* Return function status */ + return HAL_ERROR; + } +} + +/** + * @brief Carry out input and/or output data of CORDIC processing in DMA mode, + * according to the existing CORDIC configuration. + * @param hcordic pointer to a CORDIC_HandleTypeDef structure that contains + * the configuration information for CORDIC module. + * @param pInBuff Pointer to buffer containing input data for CORDIC processing. + * @param pOutBuff Pointer to buffer where output data of CORDIC processing will be stored. + * @param NbCalc Number of CORDIC calculation to process. + * @param DMADirection Direction of DMA transfers. + * This parameter can be one of the following values: + * @arg @ref CORDIC_DMA_Direction CORDIC DMA direction + * @note pInBuff or pOutBuff is unused in case of unique DMADirection transfer, and can + * be set to NULL value in this case. + * @note pInBuff and pOutBuff buffers must be 32-bit aligned to ensure a correct + * DMA transfer to and from the Peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CORDIC_Calculate_DMA(CORDIC_HandleTypeDef *hcordic, const int32_t *pInBuff, int32_t *pOutBuff, + uint32_t NbCalc, uint32_t DMADirection) +{ + uint32_t sizeinbuff; + uint32_t sizeoutbuff; + + /* Check the parameters */ + assert_param(IS_CORDIC_DMA_DIRECTION(DMADirection)); + + /* Check parameters setting */ + if (NbCalc == 0U) + { + /* Update the error code */ + hcordic->ErrorCode |= HAL_CORDIC_ERROR_PARAM; + + /* Return error status */ + return HAL_ERROR; + } + + /* Check if CORDIC DMA direction "Out" is requested */ + if ((DMADirection == CORDIC_DMA_DIR_OUT) || (DMADirection == CORDIC_DMA_DIR_IN_OUT)) + { + /* Check parameters setting */ + if (pOutBuff == NULL) + { + /* Update the error code */ + hcordic->ErrorCode |= HAL_CORDIC_ERROR_PARAM; + + /* Return error status */ + return HAL_ERROR; + } + } + + /* Check if CORDIC DMA direction "In" is requested */ + if ((DMADirection == CORDIC_DMA_DIR_IN) || (DMADirection == CORDIC_DMA_DIR_IN_OUT)) + { + /* Check parameters setting */ + if (pInBuff == NULL) + { + /* Update the error code */ + hcordic->ErrorCode |= HAL_CORDIC_ERROR_PARAM; + + /* Return error status */ + return HAL_ERROR; + } + } + + if (hcordic->State == HAL_CORDIC_STATE_READY) + { + /* Reset CORDIC error code */ + hcordic->ErrorCode = HAL_CORDIC_ERROR_NONE; + + /* Change the CORDIC state */ + hcordic->State = HAL_CORDIC_STATE_BUSY; + + /* Get DMA direction */ + hcordic->DMADirection = DMADirection; + + /* Check if CORDIC DMA direction "Out" is requested */ + if ((DMADirection == CORDIC_DMA_DIR_OUT) || (DMADirection == CORDIC_DMA_DIR_IN_OUT)) + { + /* Set the CORDIC DMA transfer complete callback */ + hcordic->hdmaOut->XferCpltCallback = CORDIC_DMAOutCplt; + /* Set the DMA error callback */ + hcordic->hdmaOut->XferErrorCallback = CORDIC_DMAError; + + /* Check number of output data at each calculation, + to retrieve the size of output data buffer */ + if (HAL_IS_BIT_SET(hcordic->Instance->CSR, CORDIC_CSR_NRES)) + { + sizeoutbuff = 2U * NbCalc; + } + else + { + sizeoutbuff = NbCalc; + } + + /* Convert the output buffer size into corresponding number of bytes. + This is necessary as the DMA handles the data at byte-level. */ + sizeoutbuff = 4U * sizeoutbuff; + + /* Enable the DMA stream managing CORDIC output data read */ + if (HAL_DMA_Start_IT(hcordic->hdmaOut, (uint32_t)&hcordic->Instance->RDATA, (uint32_t) pOutBuff, sizeoutbuff) + != HAL_OK) + { + /* Update the error code */ + hcordic->ErrorCode |= HAL_CORDIC_ERROR_DMA; + + /* Return error status */ + return HAL_ERROR; + } + + /* Enable output data Read DMA requests */ + SET_BIT(hcordic->Instance->CSR, CORDIC_DMA_REN); + } + + /* Check if CORDIC DMA direction "In" is requested */ + if ((DMADirection == CORDIC_DMA_DIR_IN) || (DMADirection == CORDIC_DMA_DIR_IN_OUT)) + { + /* Set the CORDIC DMA transfer complete callback */ + hcordic->hdmaIn->XferCpltCallback = CORDIC_DMAInCplt; + /* Set the DMA error callback */ + hcordic->hdmaIn->XferErrorCallback = CORDIC_DMAError; + + /* Check number of input data expected for each calculation, + to retrieve the size of input data buffer */ + if (HAL_IS_BIT_SET(hcordic->Instance->CSR, CORDIC_CSR_NARGS)) + { + sizeinbuff = 2U * NbCalc; + } + else + { + sizeinbuff = NbCalc; + } + + /* Convert the input buffer size into corresponding number of bytes. + This is necessary as the DMA handles the data at byte-level. */ + sizeinbuff = 4U * sizeinbuff; + + /* Enable the DMA stream managing CORDIC input data write */ + if (HAL_DMA_Start_IT(hcordic->hdmaIn, (uint32_t) pInBuff, (uint32_t)&hcordic->Instance->WDATA, sizeinbuff) + != HAL_OK) + { + /* Update the error code */ + hcordic->ErrorCode |= HAL_CORDIC_ERROR_DMA; + + /* Return error status */ + return HAL_ERROR; + } + + /* Enable input data Write DMA request */ + SET_BIT(hcordic->Instance->CSR, CORDIC_DMA_WEN); + } + + /* Return function status */ + return HAL_OK; + } + else + { + /* Set CORDIC error code */ + hcordic->ErrorCode |= HAL_CORDIC_ERROR_NOT_READY; + + /* Return function status */ + return HAL_ERROR; + } +} + +/** + * @} + */ + +/** @defgroup CORDIC_Exported_Functions_Group3 Callback functions + * @brief Callback functions. + * +@verbatim + ============================================================================== + ##### Callback functions ##### + ============================================================================== + [..] This section provides Interruption and DMA callback functions: + (+) DMA or Interrupt calculate complete + (+) DMA or Interrupt error + +@endverbatim + * @{ + */ + +/** + * @brief CORDIC error callback. + * @param hcordic pointer to a CORDIC_HandleTypeDef structure that contains + * the configuration information for CORDIC module + * @retval None + */ +__weak void HAL_CORDIC_ErrorCallback(CORDIC_HandleTypeDef *hcordic) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hcordic); + + /* NOTE : This function should not be modified; when the callback is needed, + the HAL_CORDIC_ErrorCallback can be implemented in the user file + */ +} + +/** + * @brief CORDIC calculate complete callback. + * @param hcordic pointer to a CORDIC_HandleTypeDef structure that contains + * the configuration information for CORDIC module + * @retval None + */ +__weak void HAL_CORDIC_CalculateCpltCallback(CORDIC_HandleTypeDef *hcordic) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hcordic); + + /* NOTE : This function should not be modified; when the callback is needed, + the HAL_CORDIC_CalculateCpltCallback can be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup CORDIC_Exported_Functions_Group4 IRQ handler management + * @brief IRQ handler. + * +@verbatim + ============================================================================== + ##### IRQ handler management ##### + ============================================================================== +[..] This section provides IRQ handler function. + +@endverbatim + * @{ + */ + +/** + * @brief Handle CORDIC interrupt request. + * @param hcordic pointer to a CORDIC_HandleTypeDef structure that contains + * the configuration information for CORDIC module + * @retval None + */ +void HAL_CORDIC_IRQHandler(CORDIC_HandleTypeDef *hcordic) +{ + /* Check if calculation complete interrupt is enabled and if result ready + flag is raised */ + if (__HAL_CORDIC_GET_IT_SOURCE(hcordic, CORDIC_IT_IEN) != 0U) + { + if (__HAL_CORDIC_GET_FLAG(hcordic, CORDIC_FLAG_RRDY) != 0U) + { + /* Decrement number of calculations to get */ + hcordic->NbCalcToGet--; + + /* Read output data from Read Data register, and increment output buffer pointer */ + CORDIC_ReadOutDataIncrementPtr(hcordic, &(hcordic->pOutBuff)); + + /* Check if calculations are still to be ordered */ + if (hcordic->NbCalcToOrder > 0U) + { + /* Decrement number of calculations to order */ + hcordic->NbCalcToOrder--; + + /* Continue the processing by providing another write of input data + in the Write Data register, and increment input buffer pointer */ + CORDIC_WriteInDataIncrementPtr(hcordic, &(hcordic->pInBuff)); + } + + /* Check if all calculations results are got */ + if (hcordic->NbCalcToGet == 0U) + { + /* Disable Result Ready Interrupt */ + __HAL_CORDIC_DISABLE_IT(hcordic, CORDIC_IT_IEN); + + /* Change the CORDIC state */ + hcordic->State = HAL_CORDIC_STATE_READY; + + /* Call calculation complete callback */ +#if USE_HAL_CORDIC_REGISTER_CALLBACKS == 1 + /*Call registered callback*/ + hcordic->CalculateCpltCallback(hcordic); +#else + /*Call legacy weak (surcharged) callback*/ + HAL_CORDIC_CalculateCpltCallback(hcordic); +#endif /* USE_HAL_CORDIC_REGISTER_CALLBACKS */ + } + } + } +} + +/** + * @} + */ + +/** @defgroup CORDIC_Exported_Functions_Group5 Peripheral State functions + * @brief Peripheral State functions. + * +@verbatim + ============================================================================== + ##### Peripheral State functions ##### + ============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Return the CORDIC handle state. + * @param hcordic pointer to a CORDIC_HandleTypeDef structure that contains + * the configuration information for CORDIC module + * @retval HAL state + */ +HAL_CORDIC_StateTypeDef HAL_CORDIC_GetState(const CORDIC_HandleTypeDef *hcordic) +{ + /* Return CORDIC handle state */ + return hcordic->State; +} + +/** + * @brief Return the CORDIC peripheral error. + * @param hcordic pointer to a CORDIC_HandleTypeDef structure that contains + * the configuration information for CORDIC module + * @note The returned error is a bit-map combination of possible errors + * @retval Error bit-map + */ +uint32_t HAL_CORDIC_GetError(const CORDIC_HandleTypeDef *hcordic) +{ + /* Return CORDIC error code */ + return hcordic->ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup CORDIC_Private_Functions + * @{ + */ + +/** + * @brief Write input data for CORDIC processing, and increment input buffer pointer. + * @param hcordic pointer to a CORDIC_HandleTypeDef structure that contains + * the configuration information for CORDIC module. + * @param ppInBuff Pointer to pointer to input buffer. + * @retval none + */ +static void CORDIC_WriteInDataIncrementPtr(const CORDIC_HandleTypeDef *hcordic, const int32_t **ppInBuff) +{ + /* First write of input data in the Write Data register */ + WRITE_REG(hcordic->Instance->WDATA, (uint32_t) **ppInBuff); + + /* Increment input data pointer */ + (*ppInBuff)++; + + /* Check if second write of input data is expected */ + if (HAL_IS_BIT_SET(hcordic->Instance->CSR, CORDIC_CSR_NARGS)) + { + /* Second write of input data in the Write Data register */ + WRITE_REG(hcordic->Instance->WDATA, (uint32_t) **ppInBuff); + + /* Increment input data pointer */ + (*ppInBuff)++; + } +} + +/** + * @brief Read output data of CORDIC processing, and increment output buffer pointer. + * @param hcordic pointer to a CORDIC_HandleTypeDef structure that contains + * the configuration information for CORDIC module. + * @param ppOutBuff Pointer to pointer to output buffer. + * @retval none + */ +static void CORDIC_ReadOutDataIncrementPtr(const CORDIC_HandleTypeDef *hcordic, int32_t **ppOutBuff) +{ + /* First read of output data from the Read Data register */ + **ppOutBuff = (int32_t)READ_REG(hcordic->Instance->RDATA); + + /* Increment output data pointer */ + (*ppOutBuff)++; + + /* Check if second read of output data is expected */ + if (HAL_IS_BIT_SET(hcordic->Instance->CSR, CORDIC_CSR_NRES)) + { + /* Second read of output data from the Read Data register */ + **ppOutBuff = (int32_t)READ_REG(hcordic->Instance->RDATA); + + /* Increment output data pointer */ + (*ppOutBuff)++; + } +} + +/** + * @brief DMA CORDIC Input Data process complete callback. + * @param hdma DMA handle. + * @retval None + */ +static void CORDIC_DMAInCplt(DMA_HandleTypeDef *hdma) +{ + CORDIC_HandleTypeDef *hcordic = (CORDIC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Disable the DMA transfer for input request */ + CLEAR_BIT(hcordic->Instance->CSR, CORDIC_DMA_WEN); + + /* Check if DMA direction is CORDIC Input only (no DMA for CORDIC Output) */ + if (hcordic->DMADirection == CORDIC_DMA_DIR_IN) + { + /* Change the CORDIC DMA direction to none */ + hcordic->DMADirection = CORDIC_DMA_DIR_NONE; + + /* Change the CORDIC state to ready */ + hcordic->State = HAL_CORDIC_STATE_READY; + + /* Call calculation complete callback */ +#if USE_HAL_CORDIC_REGISTER_CALLBACKS == 1 + /*Call registered callback*/ + hcordic->CalculateCpltCallback(hcordic); +#else + /*Call legacy weak (surcharged) callback*/ + HAL_CORDIC_CalculateCpltCallback(hcordic); +#endif /* USE_HAL_CORDIC_REGISTER_CALLBACKS */ + } +} + +/** + * @brief DMA CORDIC Output Data process complete callback. + * @param hdma DMA handle. + * @retval None + */ +static void CORDIC_DMAOutCplt(DMA_HandleTypeDef *hdma) +{ + CORDIC_HandleTypeDef *hcordic = (CORDIC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Disable the DMA transfer for output request */ + CLEAR_BIT(hcordic->Instance->CSR, CORDIC_DMA_REN); + + /* Change the CORDIC DMA direction to none */ + hcordic->DMADirection = CORDIC_DMA_DIR_NONE; + + /* Change the CORDIC state to ready */ + hcordic->State = HAL_CORDIC_STATE_READY; + + /* Call calculation complete callback */ +#if USE_HAL_CORDIC_REGISTER_CALLBACKS == 1 + /*Call registered callback*/ + hcordic->CalculateCpltCallback(hcordic); +#else + /*Call legacy weak (surcharged) callback*/ + HAL_CORDIC_CalculateCpltCallback(hcordic); +#endif /* USE_HAL_CORDIC_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA CORDIC communication error callback. + * @param hdma DMA handle. + * @retval None + */ +static void CORDIC_DMAError(DMA_HandleTypeDef *hdma) +{ + CORDIC_HandleTypeDef *hcordic = (CORDIC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Set CORDIC handle state to error */ + hcordic->State = HAL_CORDIC_STATE_READY; + + /* Set CORDIC handle error code to DMA error */ + hcordic->ErrorCode |= HAL_CORDIC_ERROR_DMA; + + /* Call user callback */ +#if USE_HAL_CORDIC_REGISTER_CALLBACKS == 1 + /*Call registered callback*/ + hcordic->ErrorCallback(hcordic); +#else + /*Call legacy weak (surcharged) callback*/ + HAL_CORDIC_ErrorCallback(hcordic); +#endif /* USE_HAL_CORDIC_REGISTER_CALLBACKS */ +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_CORDIC_MODULE_ENABLED */ +#endif /* CORDIC */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_cortex.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_cortex.c new file mode 100644 index 0000000000..cbdf45c667 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_cortex.c @@ -0,0 +1,738 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_cortex.c + * @author MCD Application Team + * @brief CORTEX HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the CORTEX: + * + Initialization and Configuration functions + * + Peripheral Control functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + + [..] + *** How to configure Interrupts using CORTEX HAL driver *** + =========================================================== + [..] + This section provides functions allowing to configure the NVIC interrupts (IRQ). + The Cortex-M33 exceptions are managed by CMSIS functions. + + (#) Configure the NVIC Priority Grouping using HAL_NVIC_SetPriorityGrouping() function. + (#) Configure the priority of the selected IRQ Channels using HAL_NVIC_SetPriority(). + (#) Enable the selected IRQ Channels using HAL_NVIC_EnableIRQ(). + + -@- When the NVIC_PRIORITYGROUP_0 is selected, IRQ pre-emption is no more possible. + The pending IRQ priority will be managed only by the sub priority. + + -@- IRQ priority order (sorted by highest to lowest priority): + (+@) Lowest pre-emption priority + (+@) Lowest sub priority + (+@) Lowest hardware priority (IRQ number) + + [..] + *** How to configure SysTick using CORTEX HAL driver *** + ======================================================== + [..] + Setup SysTick Timer for time base. + + (+) The HAL_SYSTICK_Config() function calls the SysTick_Config() function which + is a CMSIS function that: + (++) Configures the SysTick Reload register with value passed as function parameter. + (++) Configures the SysTick IRQ priority to the lowest value (0x0F). + (++) Resets the SysTick Counter register. + (++) Configures the SysTick Counter clock source to be Core Clock Source (HCLK). + (++) Enables the SysTick Interrupt. + (++) Starts the SysTick Counter. + + (+) You can change the SysTick Clock source to be HCLK_Div8 by calling the macro + __HAL_CORTEX_SYSTICKCLK_CONFIG(SYSTICK_CLKSOURCE_HCLK_DIV8) just after the + HAL_SYSTICK_Config() function call. The __HAL_CORTEX_SYSTICKCLK_CONFIG() macro is defined + inside the stm32h5xx_hal_cortex.h file. + + (+) You can change the SysTick IRQ priority by calling the + HAL_NVIC_SetPriority(SysTick_IRQn,...) function just after the HAL_SYSTICK_Config() function + call. The HAL_NVIC_SetPriority() call the NVIC_SetPriority() function which is a CMSIS function. + + (+) To adjust the SysTick time base, use the following formula: + + Reload Value = SysTick Counter Clock (Hz) x Desired Time base (s) + (++) Reload Value is the parameter to be passed for HAL_SYSTICK_Config() function + (++) Reload Value should not exceed 0xFFFFFF + + [..] + *** How to configure MPU (secure and non secure) using CORTEX HAL driver *** + =========================================================== + [..] + This section provides functions allowing to Enable and configure the MPU secure and non-secure. + + (#) Enable the MPU using HAL_MPU_Enable() function. + (#) Disable the MPU using HAL_MPU_Disable() function. + (#) Enable the MPU using HAL_MPU_Enable_NS() function to address the non secure MPU. + (#) Disable the MPU using HAL_MPU_Disable_NS() function to address the non secure MPU. + (#) Configure the MPU region using HAL_MPU_ConfigRegion() + and HAL_MPU_ConfigRegion_NS() to address the non secure MPU. + (#) Configure the MPU Memory attributes using HAL_MPU_ConfigMemoryAttributes() + and HAL_MPU_ConfigMemoryAttributes_NS() to address the non secure MPU. + + @endverbatim + ****************************************************************************** + + The table below gives the allowed values of the pre-emption priority and subpriority according + to the Priority Grouping configuration performed by HAL_NVIC_SetPriorityGrouping() function. + +======================================================================================================================== + NVIC_PriorityGroup | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority | Description +======================================================================================================================== + NVIC_PRIORITYGROUP_0 | 0 | 0-15 | 0 bit for pre-emption priority + | | | 4 bits for subpriority +------------------------------------------------------------------------------------------------------------------------ + NVIC_PRIORITYGROUP_1 | 0-1 | 0-7 | 1 bit for pre-emption priority + | | | 3 bits for subpriority +------------------------------------------------------------------------------------------------------------------------ + NVIC_PRIORITYGROUP_2 | 0-3 | 0-3 | 2 bits for pre-emption priority + | | | 2 bits for subpriority +------------------------------------------------------------------------------------------------------------------------ + NVIC_PRIORITYGROUP_3 | 0-7 | 0-1 | 3 bits for pre-emption priority + | | | 1 bit for subpriority +------------------------------------------------------------------------------------------------------------------------ + NVIC_PRIORITYGROUP_4 | 0-15 | 0 | 4 bits for pre-emption priority + | | | 0 bit for subpriority +======================================================================================================================== + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup CORTEX + * @{ + */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/** @defgroup CORTEX_Private_Functions CORTEX Private Functions + * @{ + */ +static void MPU_ConfigRegion(MPU_Type *MPUx, const MPU_Region_InitTypeDef *const pMPU_RegionInit); +static void MPU_ConfigMemoryAttributes(MPU_Type *MPUx, const MPU_Attributes_InitTypeDef *const pMPU_AttributesInit); +/** + * @} + */ +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup CORTEX_Exported_Functions + * @{ + */ + + +/** @addtogroup CORTEX_Exported_Functions_Group1 + * @brief NVIC functions + * +@verbatim + ============================================================================== + ##### NVIC functions ##### + ============================================================================== + [..] + This section provides the CORTEX HAL driver functions for NVIC functionalities + +@endverbatim + * @{ + */ + + +/** + * @brief Set the priority grouping field (pre-emption priority and subpriority) + * using the required unlock sequence. + * @param PriorityGroup: The priority grouping bits length. + * This parameter can be one of the following values: + * @arg NVIC_PRIORITYGROUP_0: 0 bit for pre-emption priority, + * 4 bits for subpriority + * @arg NVIC_PRIORITYGROUP_1: 1 bit for pre-emption priority, + * 3 bits for subpriority + * @arg NVIC_PRIORITYGROUP_2: 2 bits for pre-emption priority, + * 2 bits for subpriority + * @arg NVIC_PRIORITYGROUP_3: 3 bits for pre-emption priority, + * 1 bit for subpriority + * @arg NVIC_PRIORITYGROUP_4: 4 bits for pre-emption priority, + * 0 bit for subpriority + * @note When the NVIC_PRIORITYGROUP_0 is selected, IRQ pre-emption is no more possible. + * The pending IRQ priority will be managed only by the subpriority. + * @retval None + */ +void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + /* Check the parameters */ + assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup)); + + /* Set the PRIGROUP[10:8] bits according to the PriorityGroup parameter value */ + NVIC_SetPriorityGrouping(PriorityGroup); +} + +/** + * @brief Set the priority of an interrupt. + * @param IRQn: External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate + * CMSIS device file (stm32h5xxxx.h)) + * @param PreemptPriority: The pre-emption priority for the IRQn channel. + * This parameter can be a value between 0 and 15 + * A lower priority value indicates a higher priority + * @param SubPriority: the subpriority level for the IRQ channel. + * This parameter can be a value between 0 and 15 + * A lower priority value indicates a higher priority. + * @retval None + */ +void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t prioritygroup; + + /* Check the parameters */ + assert_param(IS_NVIC_SUB_PRIORITY(SubPriority)); + assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority)); + + prioritygroup = NVIC_GetPriorityGrouping(); + + NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority)); +} + +/** + * @brief Enable a device specific interrupt in the NVIC interrupt controller. + * @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig() + * function should be called before. + * @param IRQn External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate + * CMSIS device file (stm32h5xxxx.h)) + * @retval None + */ +void HAL_NVIC_EnableIRQ(IRQn_Type IRQn) +{ + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(IRQn)); + + /* Enable interrupt */ + NVIC_EnableIRQ(IRQn); +} + +/** + * @brief Disable a device specific interrupt in the NVIC interrupt controller. + * @param IRQn External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate + * CMSIS device file (stm32h5xxxx.h)) + * @retval None + */ +void HAL_NVIC_DisableIRQ(IRQn_Type IRQn) +{ + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(IRQn)); + + /* Disable interrupt */ + NVIC_DisableIRQ(IRQn); +} + +/** + * @brief Initiate a system reset request to reset the MCU. + * @retval None + */ +void HAL_NVIC_SystemReset(void) +{ + /* System Reset */ + NVIC_SystemReset(); +} + +/** + * @brief Get the priority grouping field from the NVIC Interrupt Controller. + * @retval Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field) + */ +uint32_t HAL_NVIC_GetPriorityGrouping(void) +{ + /* Get the PRIGROUP[10:8] field value */ + return NVIC_GetPriorityGrouping(); +} + +/** + * @brief Get the priority of an interrupt. + * @param IRQn: External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate + * CMSIS device file (stm32h5xxxx.h)) + * @param PriorityGroup: the priority grouping bits length. + * This parameter can be one of the following values: + * @arg NVIC_PRIORITYGROUP_0: 0 bit for pre-emption priority, + * 4 bits for subpriority + * @arg NVIC_PRIORITYGROUP_1: 1 bit for pre-emption priority, + * 3 bits for subpriority + * @arg NVIC_PRIORITYGROUP_2: 2 bits for pre-emption priority, + * 2 bits for subpriority + * @arg NVIC_PRIORITYGROUP_3: 3 bits for pre-emption priority, + * 1 bit for subpriority + * @arg NVIC_PRIORITYGROUP_4: 4 bits for pre-emption priority, + * 0 bit for subpriority + * @param pPreemptPriority: Pointer on the Preemptive priority value (starting from 0). + * @param pSubPriority: Pointer on the Subpriority value (starting from 0). + * @retval None + */ +void HAL_NVIC_GetPriority(IRQn_Type IRQn, uint32_t PriorityGroup, uint32_t *const pPreemptPriority, + uint32_t *const pSubPriority) +{ + /* Check the parameters */ + assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup)); + /* Get priority for Cortex-M system or device specific interrupts */ + NVIC_DecodePriority(NVIC_GetPriority(IRQn), PriorityGroup, pPreemptPriority, pSubPriority); +} + +/** + * @brief Set Pending bit of an external interrupt. + * @param IRQn External interrupt number + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate + * CMSIS device file (stm32h5xxxx.h)) + * @retval None + */ +void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + /* Set interrupt pending */ + NVIC_SetPendingIRQ(IRQn); +} + +/** + * @brief Get Pending Interrupt (read the pending register in the NVIC + * and return the pending bit for the specified interrupt). + * @param IRQn External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate + * CMSIS device file (stm32h5xxxx.h)) + * @retval status: - 0 Interrupt status is not pending. + * - 1 Interrupt status is pending. + */ +uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + /* Return 1 if pending else 0 */ + return NVIC_GetPendingIRQ(IRQn); +} + +/** + * @brief Clear the pending bit of an external interrupt. + * @param IRQn External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate + * CMSIS device file (stm32h5xxxx.h)) + * @retval None + */ +void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + /* Clear pending interrupt */ + NVIC_ClearPendingIRQ(IRQn); +} + +/** + * @brief Get active interrupt (read the active register in NVIC and return the active bit). + * @param IRQn External interrupt number + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate + * CMSIS device file (stm32h5xxxx.h)) + * @retval status: - 0 Interrupt status is not pending. + * - 1 Interrupt status is pending. + */ +uint32_t HAL_NVIC_GetActive(IRQn_Type IRQn) +{ + /* Return 1 if active else 0 */ + return NVIC_GetActive(IRQn); +} + +/** + * @} + */ + + +/** @addtogroup CORTEX_Exported_Functions_Group2 + * @brief SYSTICK functions + * +@verbatim + ============================================================================== + ##### SYSTICK functions ##### + ============================================================================== + [..] + This section provides the CORTEX HAL driver functions for SYSTICK functionalities + + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the System Timer with interrupt enabled and start the System Tick Timer (SysTick): + * Counter is in free running mode to generate periodic interrupts. + * @param TicksNumb: Specifies the ticks Number of ticks between two interrupts. + * @retval status: - 0 Function succeeded. + * - 1 Function failed. + */ +uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb) +{ + return SysTick_Config(TicksNumb); +} + +/** + * @brief Configure the SysTick clock source. + * @param CLKSource: specifies the SysTick clock source. + * This parameter can be one of the following values: + * @arg SYSTICK_CLKSOURCE_LSI: LSI clock selected as SysTick clock source. + * @arg SYSTICK_CLKSOURCE_LSE: LSE clock selected as SysTick clock source. + * @arg SYSTICK_CLKSOURCE_HCLK: AHB clock selected as SysTick clock source. + * @arg SYSTICK_CLKSOURCE_HCLK_DIV8: AHB clock divided by 8 selected as SysTick clock source. + * @retval None + */ +void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource) +{ + /* Check the parameters */ + assert_param(IS_SYSTICK_CLK_SOURCE(CLKSource)); + switch (CLKSource) + { + /* Select HCLK as Systick clock source */ + case SYSTICK_CLKSOURCE_HCLK: + SET_BIT(SysTick->CTRL, SYSTICK_CLKSOURCE_HCLK); + break; + /* Select HCLK_DIV8 as Systick clock source */ + case SYSTICK_CLKSOURCE_HCLK_DIV8: + CLEAR_BIT(SysTick->CTRL, SYSTICK_CLKSOURCE_HCLK); + MODIFY_REG(RCC->CCIPR4, RCC_CCIPR4_SYSTICKSEL, (0x00000000U)); + break; + /* Select LSI as Systick clock source */ + case SYSTICK_CLKSOURCE_LSI: + CLEAR_BIT(SysTick->CTRL, SYSTICK_CLKSOURCE_HCLK); + MODIFY_REG(RCC->CCIPR4, RCC_CCIPR4_SYSTICKSEL, RCC_CCIPR4_SYSTICKSEL_0); + break; + /* Select LSE as Systick clock source */ + case SYSTICK_CLKSOURCE_LSE: + CLEAR_BIT(SysTick->CTRL, SYSTICK_CLKSOURCE_HCLK); + MODIFY_REG(RCC->CCIPR4, RCC_CCIPR4_SYSTICKSEL, RCC_CCIPR4_SYSTICKSEL_1); + break; + default: + /* Nothing to do */ + break; + } +} + +/** + * @brief Handle SYSTICK interrupt request. + * @retval None + */ +void HAL_SYSTICK_IRQHandler(void) +{ + HAL_SYSTICK_Callback(); +} + +/** + * @brief SYSTICK callback. + * @retval None + */ +__weak void HAL_SYSTICK_Callback(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SYSTICK_Callback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @addtogroup CORTEX_Exported_Functions_Group3 + * @brief MPU functions + * +@verbatim + ============================================================================== + ##### MPU functions ##### + ============================================================================== + [..] + This section provides the CORTEX HAL driver functions for MPU functionalities + + +@endverbatim + * @{ + */ + +/** + * @brief Enable the MPU. + * @param MPU_Control: Specifies the control mode of the MPU during hard fault, + * NMI, FAULTMASK and privileged access to the default memory + * This parameter can be one of the following values: + * @arg MPU_HFNMI_PRIVDEF_NONE + * @arg MPU_HARDFAULT_NMI + * @arg MPU_PRIVILEGED_DEFAULT + * @arg MPU_HFNMI_PRIVDEF + * @retval None + */ +void HAL_MPU_Enable(uint32_t MPU_Control) +{ + __DMB(); /* Data Memory Barrier operation to force any outstanding writes to memory before enabling the MPU */ + + /* Enable the MPU */ + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; + + /* Enable fault exceptions */ + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; + + /* Follow ARM recommendation with */ + /* Data Synchronization and Instruction Synchronization Barriers to ensure MPU configuration */ + __DSB(); /* Ensure that the subsequent instruction is executed only after the write to memory */ + __ISB(); /* Flush and refill pipeline with updated MPU configuration settings */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Enable the non-secure MPU. + * @param MPU_Control: Specifies the control mode of the MPU during hard fault, + * NMI, FAULTMASK and privileged access to the default memory + * This parameter can be one of the following values: + * @arg MPU_HFNMI_PRIVDEF_NONE + * @arg MPU_HARDFAULT_NMI + * @arg MPU_PRIVILEGED_DEFAULT + * @arg MPU_HFNMI_PRIVDEF + * @retval None + */ +void HAL_MPU_Enable_NS(uint32_t MPU_Control) +{ + __DMB(); /* Data Memory Barrier operation to force any outstanding writes to memory before enabling the MPU */ + + /* Enable the MPU */ + MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; + + /* Enable fault exceptions */ + SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; + + /* Follow ARM recommendation with */ + /* Data Synchronization and Instruction Synchronization Barriers to ensure MPU configuration */ + __DSB(); /* Ensure that the subsequent instruction is executed only after the write to memory */ + __ISB(); /* Flush and refill pipeline with updated MPU configuration settings */ +} +#endif /* __ARM_FEATURE_CMSE */ + +/** + * @brief Disable the MPU. + * @retval None + */ +void HAL_MPU_Disable(void) +{ + __DMB(); /* Force any outstanding transfers to complete before disabling MPU */ + + /* Disable fault exceptions */ + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; + + /* Disable the MPU */ + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; + + /* Follow ARM recommendation with */ + /* Data Synchronization and Instruction Synchronization Barriers to ensure MPU configuration */ + __DSB(); /* Ensure that the subsequent instruction is executed only after the write to memory */ + __ISB(); /* Flush and refill pipeline with updated MPU configuration settings */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Disable the non-secure MPU. + * @retval None + */ +void HAL_MPU_Disable_NS(void) +{ + __DMB(); /* Force any outstanding transfers to complete before disabling MPU */ + + /* Disable fault exceptions */ + SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; + + /* Disable the MPU */ + MPU_NS->CTRL &= ~MPU_CTRL_ENABLE_Msk; + + /* Follow ARM recommendation with */ + /* Data Synchronization and Instruction Synchronization Barriers to ensure MPU configuration */ + __DSB(); /* Ensure that the subsequent instruction is executed only after the write to memory */ + __ISB(); /* Flush and refill pipeline with updated MPU configuration settings */ +} +#endif /* __ARM_FEATURE_CMSE */ + +/** + * @brief Initialize and configure the Region and the memory to be protected. + * @param pMPU_RegionInit: Pointer to a MPU_Region_InitTypeDef structure that contains + * the initialization and configuration information. + * @retval None + */ +void HAL_MPU_ConfigRegion(const MPU_Region_InitTypeDef *const pMPU_RegionInit) +{ + MPU_ConfigRegion(MPU, pMPU_RegionInit); +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Initialize and configure the Region and the memory to be protected for non-secure MPU. + * @param pMPU_RegionInit: Pointer to a MPU_Region_InitTypeDef structure that contains + * the initialization and configuration information. + * @retval None + */ +void HAL_MPU_ConfigRegion_NS(const MPU_Region_InitTypeDef *const pMPU_RegionInit) +{ + MPU_ConfigRegion(MPU_NS, pMPU_RegionInit); +} +#endif /* __ARM_FEATURE_CMSE */ + +/** + * @brief Initialize and configure the memory attributes. + * @param pMPU_AttributesInit: Pointer to a MPU_Attributes_InitTypeDef structure that contains + * the initialization and configuration information. + * @retval None + */ +void HAL_MPU_ConfigMemoryAttributes(const MPU_Attributes_InitTypeDef *const pMPU_AttributesInit) +{ + MPU_ConfigMemoryAttributes(MPU, pMPU_AttributesInit); +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Initialize and configure the memory attributes for non-secure MPU. + * @param pMPU_AttributesInit: Pointer to a MPU_Attributes_InitTypeDef structure that contains + * the initialization and configuration information. + * @retval None + */ +void HAL_MPU_ConfigMemoryAttributes_NS(const MPU_Attributes_InitTypeDef *const pMPU_AttributesInit) +{ + MPU_ConfigMemoryAttributes(MPU_NS, pMPU_AttributesInit); +} +#endif /* __ARM_FEATURE_CMSE */ + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup CORTEX_Private_Functions + * @{ + */ +/** + * @brief Initialize and configure the Region and the memory to be protected for MPU. + * @param MPUx: Pointer to MPU_Type structure + * This parameter can be one of the following values: + * @arg MPU + * @arg MPU_NS + * @param pMPU_RegionInit: Pointer to a MPU_Region_InitTypeDef structure that contains + * the initialization and configuration information. + * @retval None + */ +static void MPU_ConfigRegion(MPU_Type *MPUx, const MPU_Region_InitTypeDef *const pMPU_RegionInit) +{ + /* Check the parameters */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + assert_param(IS_MPU_INSTANCE(MPUx)); +#endif /* __ARM_FEATURE_CMSE */ + assert_param(IS_MPU_REGION_NUMBER(pMPU_RegionInit->Number)); + assert_param(IS_MPU_REGION_ENABLE(pMPU_RegionInit->Enable)); + + /* Follow ARM recommendation with Data Memory Barrier prior to MPU configuration */ + __DMB(); + + /* Set the Region number */ + MPUx->RNR = pMPU_RegionInit->Number; + + if (pMPU_RegionInit->Enable != MPU_REGION_DISABLE) + { + /* Check the parameters */ + assert_param(IS_MPU_INSTRUCTION_ACCESS(pMPU_RegionInit->DisableExec)); + assert_param(IS_MPU_REGION_PERMISSION_ATTRIBUTE(pMPU_RegionInit->AccessPermission)); + assert_param(IS_MPU_ACCESS_SHAREABLE(pMPU_RegionInit->IsShareable)); + + MPUx->RBAR = (((uint32_t)pMPU_RegionInit->BaseAddress & 0xFFFFFFE0UL) | + ((uint32_t)pMPU_RegionInit->IsShareable << MPU_RBAR_SH_Pos) | + ((uint32_t)pMPU_RegionInit->AccessPermission << MPU_RBAR_AP_Pos) | + ((uint32_t)pMPU_RegionInit->DisableExec << MPU_RBAR_XN_Pos)); + + MPUx->RLAR = (((uint32_t)pMPU_RegionInit->LimitAddress & 0xFFFFFFE0UL) | + ((uint32_t)pMPU_RegionInit->AttributesIndex << MPU_RLAR_AttrIndx_Pos) | + ((uint32_t)pMPU_RegionInit->Enable << MPU_RLAR_EN_Pos)); + } + else + { + MPUx->RLAR = 0U; + MPUx->RBAR = 0U; + } +} + +/** + * @brief Initialize and configure the memory attributes for MPU. + * @param MPUx: Pointer to MPU_Type structure + * This parameter can be one of the following values: + * @arg MPU + * @arg MPU_NS + * @param pMPU_AttributesInit: Pointer to a MPU_Attributes_InitTypeDef structure that contains + * the initialization and configuration information. + * @retval None + */ +static void MPU_ConfigMemoryAttributes(MPU_Type *MPUx, const MPU_Attributes_InitTypeDef *const pMPU_AttributesInit) +{ + __IO uint32_t *p_mair; + uint32_t attr_values; + uint32_t attr_number; + + /* Check the parameters */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + assert_param(IS_MPU_INSTANCE(MPUx)); +#endif /* __ARM_FEATURE_CMSE */ + assert_param(IS_MPU_ATTRIBUTES_NUMBER(pMPU_AttributesInit->Number)); + /* No need to check Attributes value as all 0x0..0xFF possible */ + + /* Follow ARM recommendation with Data Memory Barrier prior to MPUx configuration */ + __DMB(); + + if (pMPU_AttributesInit->Number < MPU_ATTRIBUTES_NUMBER4) + { + /* Program MPU_MAIR0 */ + p_mair = &(MPUx->MAIR0); + attr_number = pMPU_AttributesInit->Number; + } + else + { + /* Program MPU_MAIR1 */ + p_mair = &(MPUx->MAIR1); + attr_number = (uint32_t)pMPU_AttributesInit->Number - 4U; + } + + attr_values = *(p_mair); + attr_values &= ~(0xFFUL << (attr_number * 8U)); + *(p_mair) = attr_values | ((uint32_t)pMPU_AttributesInit->Attributes << (attr_number * 8U)); +} +/** + * @} + */ + +#endif /* HAL_CORTEX_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_crc.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_crc.c new file mode 100644 index 0000000000..279007d82d --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_crc.c @@ -0,0 +1,516 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_crc.c + * @author MCD Application Team + * @brief CRC HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Cyclic Redundancy Check (CRC) peripheral: + * + Initialization and de-initialization functions + * + Peripheral Control functions + * + Peripheral State functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + =============================================================================== + ##### How to use this driver ##### + =============================================================================== + [..] + (+) Enable CRC AHB clock using __HAL_RCC_CRC_CLK_ENABLE(); + (+) Initialize CRC calculator + (++) specify generating polynomial (peripheral default or non-default one) + (++) specify initialization value (peripheral default or non-default one) + (++) specify input data format + (++) specify input or output data inversion mode if any + (+) Use HAL_CRC_Accumulate() function to compute the CRC value of the + input data buffer starting with the previously computed CRC as + initialization value + (+) Use HAL_CRC_Calculate() function to compute the CRC value of the + input data buffer starting with the defined initialization value + (default or non-default) to initiate CRC calculation + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup CRC CRC + * @brief CRC HAL module driver. + * @{ + */ + +#ifdef HAL_CRC_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup CRC_Private_Functions CRC Private Functions + * @{ + */ +static uint32_t CRC_Handle_8(CRC_HandleTypeDef *hcrc, uint8_t pBuffer[], uint32_t BufferLength); +static uint32_t CRC_Handle_16(CRC_HandleTypeDef *hcrc, uint16_t pBuffer[], uint32_t BufferLength); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup CRC_Exported_Functions CRC Exported Functions + * @{ + */ + +/** @defgroup CRC_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 the CRC according to the specified parameters + in the CRC_InitTypeDef and create the associated handle + (+) DeInitialize the CRC peripheral + (+) Initialize the CRC MSP (MCU Specific Package) + (+) DeInitialize the CRC MSP + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the CRC according to the specified + * parameters in the CRC_InitTypeDef and create the associated handle. + * @param hcrc CRC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRC_Init(CRC_HandleTypeDef *hcrc) +{ + /* Check the CRC handle allocation */ + if (hcrc == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance)); + + if (hcrc->State == HAL_CRC_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hcrc->Lock = HAL_UNLOCKED; + /* Init the low level hardware */ + HAL_CRC_MspInit(hcrc); + } + + hcrc->State = HAL_CRC_STATE_BUSY; + + /* check whether or not non-default generating polynomial has been + * picked up by user */ + assert_param(IS_DEFAULT_POLYNOMIAL(hcrc->Init.DefaultPolynomialUse)); + if (hcrc->Init.DefaultPolynomialUse == DEFAULT_POLYNOMIAL_ENABLE) + { + /* initialize peripheral with default generating polynomial */ + WRITE_REG(hcrc->Instance->POL, DEFAULT_CRC32_POLY); + MODIFY_REG(hcrc->Instance->CR, CRC_CR_POLYSIZE, CRC_POLYLENGTH_32B); + } + else + { + /* initialize CRC peripheral with generating polynomial defined by user */ + if (HAL_CRCEx_Polynomial_Set(hcrc, hcrc->Init.GeneratingPolynomial, hcrc->Init.CRCLength) != HAL_OK) + { + return HAL_ERROR; + } + } + + /* check whether or not non-default CRC initial value has been + * picked up by user */ + assert_param(IS_DEFAULT_INIT_VALUE(hcrc->Init.DefaultInitValueUse)); + if (hcrc->Init.DefaultInitValueUse == DEFAULT_INIT_VALUE_ENABLE) + { + WRITE_REG(hcrc->Instance->INIT, DEFAULT_CRC_INITVALUE); + } + else + { + WRITE_REG(hcrc->Instance->INIT, hcrc->Init.InitValue); + } + + + /* set input data inversion mode */ + assert_param(IS_CRC_INPUTDATA_INVERSION_MODE(hcrc->Init.InputDataInversionMode)); + MODIFY_REG(hcrc->Instance->CR, CRC_CR_REV_IN, hcrc->Init.InputDataInversionMode); + + /* set output data inversion mode */ + assert_param(IS_CRC_OUTPUTDATA_INVERSION_MODE(hcrc->Init.OutputDataInversionMode)); + MODIFY_REG(hcrc->Instance->CR, CRC_CR_REV_OUT, hcrc->Init.OutputDataInversionMode); + + /* makes sure the input data format (bytes, halfwords or words stream) + * is properly specified by user */ + assert_param(IS_CRC_INPUTDATA_FORMAT(hcrc->InputDataFormat)); + + /* Change CRC peripheral state */ + hcrc->State = HAL_CRC_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief DeInitialize the CRC peripheral. + * @param hcrc CRC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRC_DeInit(CRC_HandleTypeDef *hcrc) +{ + /* Check the CRC handle allocation */ + if (hcrc == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance)); + + /* Check the CRC peripheral state */ + if (hcrc->State == HAL_CRC_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Change CRC peripheral state */ + hcrc->State = HAL_CRC_STATE_BUSY; + + /* Reset CRC calculation unit */ + __HAL_CRC_DR_RESET(hcrc); + + /* Reset IDR register content */ + CLEAR_BIT(hcrc->Instance->IDR, CRC_IDR_IDR); + + /* DeInit the low level hardware */ + HAL_CRC_MspDeInit(hcrc); + + /* Change CRC peripheral state */ + hcrc->State = HAL_CRC_STATE_RESET; + + /* Process unlocked */ + __HAL_UNLOCK(hcrc); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRC MSP. + * @param hcrc CRC handle + * @retval None + */ +__weak void HAL_CRC_MspInit(CRC_HandleTypeDef *hcrc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hcrc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_CRC_MspInit can be implemented in the user file + */ +} + +/** + * @brief DeInitialize the CRC MSP. + * @param hcrc CRC handle + * @retval None + */ +__weak void HAL_CRC_MspDeInit(CRC_HandleTypeDef *hcrc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hcrc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_CRC_MspDeInit can be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup CRC_Exported_Functions_Group2 Peripheral Control functions + * @brief management functions. + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer + using combination of the previous CRC value and the new one. + + [..] or + + (+) compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer + independently of the previous CRC value. + +@endverbatim + * @{ + */ + +/** + * @brief Compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer + * starting with the previously computed CRC as initialization value. + * @param hcrc CRC handle + * @param pBuffer pointer to the input data buffer, exact input data format is + * provided by hcrc->InputDataFormat. + * @param BufferLength input data buffer length (number of bytes if pBuffer + * type is * uint8_t, number of half-words if pBuffer type is * uint16_t, + * number of words if pBuffer type is * uint32_t). + * @note By default, the API expects a uint32_t pointer as input buffer parameter. + * Input buffer pointers with other types simply need to be cast in uint32_t + * and the API will internally adjust its input data processing based on the + * handle field hcrc->InputDataFormat. + * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits) + */ +uint32_t HAL_CRC_Accumulate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength) +{ + uint32_t index; /* CRC input data buffer index */ + uint32_t temp = 0U; /* CRC output (read from hcrc->Instance->DR register) */ + + /* Change CRC peripheral state */ + hcrc->State = HAL_CRC_STATE_BUSY; + + switch (hcrc->InputDataFormat) + { + case CRC_INPUTDATA_FORMAT_WORDS: + /* Enter Data to the CRC calculator */ + for (index = 0U; index < BufferLength; index++) + { + hcrc->Instance->DR = pBuffer[index]; + } + temp = hcrc->Instance->DR; + break; + + case CRC_INPUTDATA_FORMAT_BYTES: + temp = CRC_Handle_8(hcrc, (uint8_t *)pBuffer, BufferLength); + break; + + case CRC_INPUTDATA_FORMAT_HALFWORDS: + temp = CRC_Handle_16(hcrc, (uint16_t *)(void *)pBuffer, BufferLength); /* Derogation MisraC2012 R.11.5 */ + break; + default: + break; + } + + /* Change CRC peripheral state */ + hcrc->State = HAL_CRC_STATE_READY; + + /* Return the CRC computed value */ + return temp; +} + +/** + * @brief Compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer + * starting with hcrc->Instance->INIT as initialization value. + * @param hcrc CRC handle + * @param pBuffer pointer to the input data buffer, exact input data format is + * provided by hcrc->InputDataFormat. + * @param BufferLength input data buffer length (number of bytes if pBuffer + * type is * uint8_t, number of half-words if pBuffer type is * uint16_t, + * number of words if pBuffer type is * uint32_t). + * @note By default, the API expects a uint32_t pointer as input buffer parameter. + * Input buffer pointers with other types simply need to be cast in uint32_t + * and the API will internally adjust its input data processing based on the + * handle field hcrc->InputDataFormat. + * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits) + */ +uint32_t HAL_CRC_Calculate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength) +{ + uint32_t index; /* CRC input data buffer index */ + uint32_t temp = 0U; /* CRC output (read from hcrc->Instance->DR register) */ + + /* Change CRC peripheral state */ + hcrc->State = HAL_CRC_STATE_BUSY; + + /* Reset CRC Calculation Unit (hcrc->Instance->INIT is + * written in hcrc->Instance->DR) */ + __HAL_CRC_DR_RESET(hcrc); + + switch (hcrc->InputDataFormat) + { + case CRC_INPUTDATA_FORMAT_WORDS: + /* Enter 32-bit input data to the CRC calculator */ + for (index = 0U; index < BufferLength; index++) + { + hcrc->Instance->DR = pBuffer[index]; + } + temp = hcrc->Instance->DR; + break; + + case CRC_INPUTDATA_FORMAT_BYTES: + /* Specific 8-bit input data handling */ + temp = CRC_Handle_8(hcrc, (uint8_t *)pBuffer, BufferLength); + break; + + case CRC_INPUTDATA_FORMAT_HALFWORDS: + /* Specific 16-bit input data handling */ + temp = CRC_Handle_16(hcrc, (uint16_t *)(void *)pBuffer, BufferLength); /* Derogation MisraC2012 R.11.5 */ + break; + + default: + break; + } + + /* Change CRC peripheral state */ + hcrc->State = HAL_CRC_STATE_READY; + + /* Return the CRC computed value */ + return temp; +} + +/** + * @} + */ + +/** @defgroup CRC_Exported_Functions_Group3 Peripheral State functions + * @brief Peripheral State functions. + * +@verbatim + =============================================================================== + ##### Peripheral State functions ##### + =============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Return the CRC handle state. + * @param hcrc CRC handle + * @retval HAL state + */ +HAL_CRC_StateTypeDef HAL_CRC_GetState(const CRC_HandleTypeDef *hcrc) +{ + /* Return CRC handle state */ + return hcrc->State; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup CRC_Private_Functions + * @{ + */ + +/** + * @brief Enter 8-bit input data to the CRC calculator. + * Specific data handling to optimize processing time. + * @param hcrc CRC handle + * @param pBuffer pointer to the input data buffer + * @param BufferLength input data buffer length + * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits) + */ +static uint32_t CRC_Handle_8(CRC_HandleTypeDef *hcrc, uint8_t pBuffer[], uint32_t BufferLength) +{ + uint32_t i; /* input data buffer index */ + uint16_t data; + __IO uint16_t *pReg; + + /* Processing time optimization: 4 bytes are entered in a row with a single word write, + * last bytes must be carefully fed to the CRC calculator to ensure a correct type + * handling by the peripheral */ + for (i = 0U; i < (BufferLength / 4U); i++) + { + hcrc->Instance->DR = ((uint32_t)pBuffer[4U * i] << 24U) | \ + ((uint32_t)pBuffer[(4U * i) + 1U] << 16U) | \ + ((uint32_t)pBuffer[(4U * i) + 2U] << 8U) | \ + (uint32_t)pBuffer[(4U * i) + 3U]; + } + /* last bytes specific handling */ + if ((BufferLength % 4U) != 0U) + { + if ((BufferLength % 4U) == 1U) + { + *(__IO uint8_t *)(__IO void *)(&hcrc->Instance->DR) = pBuffer[4U * i]; /* Derogation MisraC2012 R.11.5 */ + } + if ((BufferLength % 4U) == 2U) + { + data = ((uint16_t)(pBuffer[4U * i]) << 8U) | (uint16_t)pBuffer[(4U * i) + 1U]; + pReg = (__IO uint16_t *)(__IO void *)(&hcrc->Instance->DR); /* Derogation MisraC2012 R.11.5 */ + *pReg = data; + } + if ((BufferLength % 4U) == 3U) + { + data = ((uint16_t)(pBuffer[4U * i]) << 8U) | (uint16_t)pBuffer[(4U * i) + 1U]; + pReg = (__IO uint16_t *)(__IO void *)(&hcrc->Instance->DR); /* Derogation MisraC2012 R.11.5 */ + *pReg = data; + + *(__IO uint8_t *)(__IO void *)(&hcrc->Instance->DR) = pBuffer[(4U * i) + 2U]; /* Derogation MisraC2012 R.11.5 */ + } + } + + /* Return the CRC computed value */ + return hcrc->Instance->DR; +} + +/** + * @brief Enter 16-bit input data to the CRC calculator. + * Specific data handling to optimize processing time. + * @param hcrc CRC handle + * @param pBuffer pointer to the input data buffer + * @param BufferLength input data buffer length + * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits) + */ +static uint32_t CRC_Handle_16(CRC_HandleTypeDef *hcrc, uint16_t pBuffer[], uint32_t BufferLength) +{ + uint32_t i; /* input data buffer index */ + __IO uint16_t *pReg; + + /* Processing time optimization: 2 HalfWords are entered in a row with a single word write, + * in case of odd length, last HalfWord must be carefully fed to the CRC calculator to ensure + * a correct type handling by the peripheral */ + for (i = 0U; i < (BufferLength / 2U); i++) + { + hcrc->Instance->DR = ((uint32_t)pBuffer[2U * i] << 16U) | (uint32_t)pBuffer[(2U * i) + 1U]; + } + if ((BufferLength % 2U) != 0U) + { + pReg = (__IO uint16_t *)(__IO void *)(&hcrc->Instance->DR); /* Derogation MisraC2012 R.11.5 */ + *pReg = pBuffer[2U * i]; + } + + /* Return the CRC computed value */ + return hcrc->Instance->DR; +} + +/** + * @} + */ + +#endif /* HAL_CRC_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_crc_ex.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_crc_ex.c new file mode 100644 index 0000000000..1116f6aece --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_crc_ex.c @@ -0,0 +1,232 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_crc_ex.c + * @author MCD Application Team + * @brief Extended CRC HAL module driver. + * This file provides firmware functions to manage the extended + * functionalities of the CRC peripheral. + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim +================================================================================ + ##### How to use this driver ##### +================================================================================ + [..] + (+) Set user-defined generating polynomial through HAL_CRCEx_Polynomial_Set() + (+) Configure Input or Output data inversion + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup CRCEx CRCEx + * @brief CRC Extended HAL module driver + * @{ + */ + +#ifdef HAL_CRC_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup CRCEx_Exported_Functions CRC Extended Exported Functions + * @{ + */ + +/** @defgroup CRCEx_Exported_Functions_Group1 Extended Initialization/de-initialization functions + * @brief Extended Initialization and Configuration functions. + * +@verbatim + =============================================================================== + ##### Extended configuration functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure the generating polynomial + (+) Configure the input data inversion + (+) Configure the output data inversion + +@endverbatim + * @{ + */ + + +/** + * @brief Initialize the CRC polynomial if different from default one. + * @param hcrc CRC handle + * @param Pol CRC generating polynomial (7, 8, 16 or 32-bit long). + * This parameter is written in normal representation, e.g. + * @arg for a polynomial of degree 7, X^7 + X^6 + X^5 + X^2 + 1 is written 0x65 + * @arg for a polynomial of degree 16, X^16 + X^12 + X^5 + 1 is written 0x1021 + * @param PolyLength CRC polynomial length. + * This parameter can be one of the following values: + * @arg @ref CRC_POLYLENGTH_7B 7-bit long CRC (generating polynomial of degree 7) + * @arg @ref CRC_POLYLENGTH_8B 8-bit long CRC (generating polynomial of degree 8) + * @arg @ref CRC_POLYLENGTH_16B 16-bit long CRC (generating polynomial of degree 16) + * @arg @ref CRC_POLYLENGTH_32B 32-bit long CRC (generating polynomial of degree 32) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRCEx_Polynomial_Set(CRC_HandleTypeDef *hcrc, uint32_t Pol, uint32_t PolyLength) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t msb = 31U; /* polynomial degree is 32 at most, so msb is initialized to max value */ + + /* Check the parameters */ + assert_param(IS_CRC_POL_LENGTH(PolyLength)); + + /* Ensure that the generating polynomial is odd */ + if ((Pol & (uint32_t)(0x1U)) == 0U) + { + status = HAL_ERROR; + } + else + { + /* check polynomial definition vs polynomial size: + * polynomial length must be aligned with polynomial + * definition. HAL_ERROR is reported if Pol degree is + * larger than that indicated by PolyLength. + * Look for MSB position: msb will contain the degree of + * the second to the largest polynomial member. E.g., for + * X^7 + X^6 + X^5 + X^2 + 1, msb = 6. */ + while ((msb-- > 0U) && ((Pol & ((uint32_t)(0x1U) << (msb & 0x1FU))) == 0U)) + { + } + + switch (PolyLength) + { + + case CRC_POLYLENGTH_7B: + if (msb >= HAL_CRC_LENGTH_7B) + { + status = HAL_ERROR; + } + break; + case CRC_POLYLENGTH_8B: + if (msb >= HAL_CRC_LENGTH_8B) + { + status = HAL_ERROR; + } + break; + case CRC_POLYLENGTH_16B: + if (msb >= HAL_CRC_LENGTH_16B) + { + status = HAL_ERROR; + } + break; + + case CRC_POLYLENGTH_32B: + /* no polynomial definition vs. polynomial length issue possible */ + break; + default: + status = HAL_ERROR; + break; + } + } + if (status == HAL_OK) + { + /* set generating polynomial */ + WRITE_REG(hcrc->Instance->POL, Pol); + + /* set generating polynomial size */ + MODIFY_REG(hcrc->Instance->CR, CRC_CR_POLYSIZE, PolyLength); + } + /* Return function status */ + return status; +} + +/** + * @brief Set the Reverse Input data mode. + * @param hcrc CRC handle + * @param InputReverseMode Input Data inversion mode. + * This parameter can be one of the following values: + * @arg @ref CRC_INPUTDATA_INVERSION_NONE no change in bit order (default value) + * @arg @ref CRC_INPUTDATA_INVERSION_BYTE Byte-wise bit reversal + * @arg @ref CRC_INPUTDATA_INVERSION_HALFWORD HalfWord-wise bit reversal + * @arg @ref CRC_INPUTDATA_INVERSION_WORD Word-wise bit reversal + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRCEx_Input_Data_Reverse(CRC_HandleTypeDef *hcrc, uint32_t InputReverseMode) +{ + /* Check the parameters */ + assert_param(IS_CRC_INPUTDATA_INVERSION_MODE(InputReverseMode)); + + /* Change CRC peripheral state */ + hcrc->State = HAL_CRC_STATE_BUSY; + + /* set input data inversion mode */ + MODIFY_REG(hcrc->Instance->CR, CRC_CR_REV_IN, InputReverseMode); + /* Change CRC peripheral state */ + hcrc->State = HAL_CRC_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Set the Reverse Output data mode. + * @param hcrc CRC handle + * @param OutputReverseMode Output Data inversion mode. + * This parameter can be one of the following values: + * @arg @ref CRC_OUTPUTDATA_INVERSION_DISABLE no CRC inversion (default value) + * @arg @ref CRC_OUTPUTDATA_INVERSION_ENABLE bit-level inversion (e.g. for a 8-bit CRC: 0xB5 becomes 0xAD) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRCEx_Output_Data_Reverse(CRC_HandleTypeDef *hcrc, uint32_t OutputReverseMode) +{ + /* Check the parameters */ + assert_param(IS_CRC_OUTPUTDATA_INVERSION_MODE(OutputReverseMode)); + + /* Change CRC peripheral state */ + hcrc->State = HAL_CRC_STATE_BUSY; + + /* set output data inversion mode */ + MODIFY_REG(hcrc->Instance->CR, CRC_CR_REV_OUT, OutputReverseMode); + + /* Change CRC peripheral state */ + hcrc->State = HAL_CRC_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + + + + +/** + * @} + */ + + +/** + * @} + */ + + +#endif /* HAL_CRC_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_cryp.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_cryp.c new file mode 100644 index 0000000000..e712ccc5e6 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_cryp.c @@ -0,0 +1,6302 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_cryp.c + * @author MCD Application Team + * @brief CRYP HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Cryptography (CRYP) peripheral: + * + Initialization, de-initialization, set config and get config functions + * + DMA callback functions + * + CRYP IRQ handler management + * + Peripheral State functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The CRYP HAL driver can be used as follows: + + (#)Initialize the CRYP low level resources by implementing the HAL_CRYP_MspInit(): + (##) Enable the CRYP interface clock using __HAL_RCC_CRYP_CLK_ENABLE()or __HAL_RCC_AES_CLK_ENABLE + (##) In case of using interrupts (e.g. HAL_CRYP_Encrypt_IT()) + (+++) Configure the CRYP interrupt priority using HAL_NVIC_SetPriority() + (+++) Enable the CRYP IRQ handler using HAL_NVIC_EnableIRQ() + (+++) In CRYP IRQ handler, call HAL_CRYP_IRQHandler() + (##) In case of using DMA to control data transfer (e.g. HAL_CRYP_Encrypt_DMA()) + (+++) Enable the DMAx interface clock using __RCC_DMAx_CLK_ENABLE() + (+++) Configure and enable two DMA channels one for managing data transfer from + memory to peripheral (input channel) and another channel for managing data + transfer from peripheral to memory (output channel) + (+++) 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 channels. The output channel should have higher + priority than the input channel HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ() + + (#)Initialize the CRYP according to the specified parameters : + (##) The data type: 1-bit, 8-bit, 16-bit or 32-bit. + (##) The key size: 128, 192 or 256. + (##) The AES Algorithm ECB/CBC/CTR/GCM or CCM. + (##) The initialization vector (counter). It is not used in ECB mode. + (##) The key buffer used for encryption/decryption. + (+++) In some specific configurations, the key is written by the application + code out of the HAL scope. In that case, user can still resort to the + HAL APIs as usual but must make sure that pKey pointer is set to NULL. + (##) The DataWidthUnit field. It specifies whether the data length (or the payload + length for authentication algorithms) is in words or bytes. + (##) The Header used only in AES GCM and CCM Algorithm for authentication. + (##) The HeaderSize used to give size of header buffer in word or bytes, depending upon HeaderWidthUnit field. + (##) The HeaderWidthUnit field. It specifies whether the header length + (for authentication algorithms) is in words or bytes. + (##) The B0 block is the first authentication block used only in AES CCM mode. + (##) The KeyIVConfigSkip used to process several messages in a row. + (##) The KeyMode used to special key operation modes (for SAES : wrapped key, shared key with AES peripheral). + (##) The KeySelect, Only for SAES, used to select key from different key source. + (##) The KeyProtection, Only for SAES, used for security context enforcement. + + (#)Three processing (encryption/decryption) functions are available: + (##) Polling mode: encryption and decryption APIs are blocking functions + i.e. they process the data and wait till the processing is finished, + e.g. HAL_CRYP_Encrypt & HAL_CRYP_Decrypt + (##) Interrupt mode: encryption and decryption APIs are not blocking functions + i.e. they process the data under interrupt, + e.g. HAL_CRYP_Encrypt_IT & HAL_CRYP_Decrypt_IT + (##) DMA mode: encryption and decryption APIs are not blocking functions + i.e. the data transfer is ensured by DMA, + e.g. HAL_CRYP_Encrypt_DMA & HAL_CRYP_Decrypt_DMA + + (#)When the processing function is called at first time after HAL_CRYP_Init() + the CRYP peripheral is configured and processes the buffer in input. + At second call, no need to Initialize the CRYP, user have to get current configuration via + HAL_CRYP_GetConfig() API, then only HAL_CRYP_SetConfig() is requested to set + new parameters, finally user can start encryption/decryption. + + (#)Call HAL_CRYP_DeInit() to deinitialize the CRYP peripheral. + + (#)To process a single message with consecutive calls to HAL_CRYP_Encrypt() or HAL_CRYP_Decrypt() + without having to configure again the Key or the Initialization Vector between each API call, + the field KeyIVConfigSkip of the initialization structure must be set to CRYP_KEYIVCONFIG_ONCE. + Same is true for consecutive calls of HAL_CRYP_Encrypt_IT(), HAL_CRYP_Decrypt_IT(), HAL_CRYP_Encrypt_DMA() + or HAL_CRYP_Decrypt_DMA(). + + [..] + The cryptographic processor supports following standards: + (#) The advanced encryption standard (AES) supported: + (##)128-bit data block processing + (##) chaining modes supported : + (+++) Electronic Code Book(ECB) + (+++) Cipher Block Chaining (CBC) + (+++) Counter mode (CTR) + (+++) Galois/counter mode (GCM/GMAC) + (+++) Counter with Cipher Block Chaining-Message(CCM) + (##) keys length Supported : 128-bit and 256-bit + + [..] + (@) Specific care must be taken to format the key and the Initialization Vector IV! + + [..] If the key is defined as a 128-bit long array key[127..0] = {b127 ... b0} where + b127 is the MSB and b0 the LSB, the key must be stored in MCU memory + (+) as a sequence of words where the MSB word comes first (occupies the + lowest memory address) + (++) address n+0 : 0b b127 .. b120 b119 .. b112 b111 .. b104 b103 .. b96 + (++) address n+4 : 0b b95 .. b88 b87 .. b80 b79 .. b72 b71 .. b64 + (++) address n+8 : 0b b63 .. b56 b55 .. b48 b47 .. b40 b39 .. b32 + (++) address n+C : 0b b31 .. b24 b23 .. b16 b15 .. b8 b7 .. b0 + [..] Hereafter, another illustration when considering a 128-bit long key made of 16 bytes {B15..B0}. + The 4 32-bit words that make the key must be stored as follows in MCU memory: + (+) address n+0 : 0x B15 B14 B13 B12 + (+) address n+4 : 0x B11 B10 B9 B8 + (+) address n+8 : 0x B7 B6 B5 B4 + (+) address n+C : 0x B3 B2 B1 B0 + [..] which leads to the expected setting + (+) AES_KEYR3 = 0x B15 B14 B13 B12 + (+) AES_KEYR2 = 0x B11 B10 B9 B8 + (+) AES_KEYR1 = 0x B7 B6 B5 B4 + (+) AES_KEYR0 = 0x B3 B2 B1 B0 + + [..] Same format must be applied for a 256-bit long key made of 32 bytes {B31..B0}. + The 8 32-bit words that make the key must be stored as follows in MCU memory: + (+) address n+00 : 0x B31 B30 B29 B28 + (+) address n+04 : 0x B27 B26 B25 B24 + (+) address n+08 : 0x B23 B22 B21 B20 + (+) address n+0C : 0x B19 B18 B17 B16 + (+) address n+10 : 0x B15 B14 B13 B12 + (+) address n+14 : 0x B11 B10 B9 B8 + (+) address n+18 : 0x B7 B6 B5 B4 + (+) address n+1C : 0x B3 B2 B1 B0 + [..] which leads to the expected setting + (+) AES_KEYR7 = 0x B31 B30 B29 B28 + (+) AES_KEYR6 = 0x B27 B26 B25 B24 + (+) AES_KEYR5 = 0x B23 B22 B21 B20 + (+) AES_KEYR4 = 0x B19 B18 B17 B16 + (+) AES_KEYR3 = 0x B15 B14 B13 B12 + (+) AES_KEYR2 = 0x B11 B10 B9 B8 + (+) AES_KEYR1 = 0x B7 B6 B5 B4 + (+) AES_KEYR0 = 0x B3 B2 B1 B0 + + [..] Initialization Vector IV (4 32-bit words) format must follow the same as + that of a 128-bit long key. + + [..] Note that key and IV registers are not sensitive to swap mode selection. + + [..] This section describes the AES Galois/counter mode (GCM) supported by the peripherals: + (#) Algorithm supported : + (##) Galois/counter mode (GCM) + (##) Galois message authentication code (GMAC) :is exactly the same as + GCM algorithm composed only by an header. + (#) Four phases are performed in GCM : + (##) Init phase: peripheral prepares the GCM hash subkey (H) and do the IV processing + (##) Header phase: peripheral processes the Additional Authenticated Data (AAD), with hash + computation only. + (##) Payload phase: peripheral processes the plaintext (P) with hash computation + keystream + encryption + data XORing. It works in a similar way for ciphertext (C). + (##) Final phase: peripheral generates the authenticated tag (T) using the last block of data. + HAL_CRYPEx_AESGCM_GenerateAuthTAG API used in this phase to generate 4 words which correspond + to the Tag. user should consider only part of this 4 words, if Tag length is less than 128 bits. + (#) structure of message construction in GCM is defined as below : + (##) 16 bytes Initial Counter Block (ICB)composed of IV and counter + (##) The authenticated header A (also knows as Additional Authentication Data AAD) + this part of the message is only authenticated, not encrypted. + (##) The plaintext message P is both authenticated and encrypted as ciphertext. + GCM standard specifies that ciphertext has same bit length as the plaintext. + (##) The last block is composed of the length of A (on 64 bits) and the length of ciphertext + (on 64 bits) + + [..] A more detailed description of the GCM message structure is available below. + + [..] This section describe The AES Counter with Cipher Block Chaining-Message + Authentication Code (CCM) supported by the peripheral: + (#) Specific parameters for CCM : + + (##) B0 block : follows NIST Special Publication 800-38C, + (##) B1 block (header) + (##) CTRx block : control blocks + + [..] A detailed description of the CCM message structure is available below. + + (#) CCM in peripheral: + (##) To perform message payload encryption or decryption AES is configured in CTR mode. + (##) For authentication two phases are performed : + - Header phase: peripheral processes the Additional Authenticated Data (AAD) first, then the cleartext message + only cleartext payload (not the ciphertext payload) is used and no output. + (##) Final phase: peripheral generates the authenticated tag (T) using the last block of data. + HAL_CRYPEx_AESCCM_GenerateAuthTAG API used in this phase to generate 4 words which correspond to the Tag. + user should consider only part of this 4 words, if Tag length is less than 128 bits + *** Callback registration *** + ============================= + + [..] + The compilation define USE_HAL_CRYP_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + Use Functions @ref HAL_CRYP_RegisterCallback() or HAL_CRYP_RegisterXXXCallback() + to register an interrupt callback. + + [..] + Function @ref HAL_CRYP_RegisterCallback() allows to register following callbacks: + (+) InCpltCallback : Input FIFO transfer completed callback. + (+) OutCpltCallback : Output FIFO transfer completed callback. + (+) ErrorCallback : callback for error detection. + (+) MspInitCallback : CRYP MspInit. + (+) MspDeInitCallback : CRYP MspDeInit. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + + [..] + Use function @ref HAL_CRYP_UnRegisterCallback() to reset a callback to the default + weak function. + @ref HAL_CRYP_UnRegisterCallback() takes as parameters the HAL peripheral handle, + and the Callback ID. + This function allows to reset following callbacks: + (+) InCpltCallback : Input FIFO transfer completed callback. + (+) OutCpltCallback : Output FIFO transfer completed callback. + (+) ErrorCallback : callback for error detection. + (+) MspInitCallback : CRYP MspInit. + (+) MspDeInitCallback : CRYP MspDeInit. + + [..] + By default, after the @ref HAL_CRYP_Init() and when the state is HAL_CRYP_STATE_RESET + all callbacks are set to the corresponding weak functions : + examples @ref HAL_CRYP_InCpltCallback() , @ref HAL_CRYP_OutCpltCallback(). + Exception done for MspInit and MspDeInit functions that are + reset to the legacy weak function in the @ref HAL_CRYP_Init()/ @ref HAL_CRYP_DeInit() only when + these callbacks are null (not registered beforehand). + if not, MspInit or MspDeInit are not null, the @ref HAL_CRYP_Init() / @ref HAL_CRYP_DeInit() + keep and use the user MspInit/MspDeInit functions (registered beforehand) + + [..] + Callbacks can be registered/unregistered in HAL_CRYP_STATE_READY state only. + Exception done MspInit/MspDeInit callbacks that can be registered/unregistered + in HAL_CRYP_STATE_READY or HAL_CRYP_STATE_RESET state, + thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. + In that case first register the MspInit/MspDeInit user callbacks + using @ref HAL_CRYP_RegisterCallback() before calling @ref HAL_CRYP_DeInit() + or @ref HAL_CRYP_Init() function. + + [..] + When The compilation define USE_HAL_CRYP_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. + + + *** Suspend/Resume feature *** + ============================== + + [..] + The compilation define USE_HAL_CRYP_SUSPEND_RESUME when set to 1 + allows the user to resort to the suspend/resume feature. + A low priority block processing can be suspended to process a high priority block + instead. When the high priority block processing is over, the low priority block + processing can be resumed, restarting from the point where it was suspended. This + feature is applicable only in non-blocking interrupt mode. + + [..] User must resort to HAL_CRYP_Suspend() to suspend the low priority block + processing. This API manages the hardware block processing suspension and saves all the + internal data that will be needed to restart later on. Upon HAL_CRYP_Suspend() completion, + the user can launch the processing of any other block (high priority block processing). + + [..] When the high priority block processing is over, user must invoke HAL_CRYP_Resume() + to resume the low priority block processing. Ciphering (or deciphering) restarts from + the suspension point and ends as usual. + + [..] HAL_CRYP_Suspend() reports an error when the suspension request is sent too late + (i.e when the low priority block processing is about to end). There is no use to + suspend the tag generation processing for authentication algorithms. + + [..] + (@) If the key is written out of HAL scope (case pKey pointer set to NULL by the user), + the block processing suspension/resumption mechanism is NOT applicable. + + [..] + (@) If the Key and Initialization Vector are configured only once and configuration is + skipped for consecutive processings (case KeyIVConfigSkip set to CRYP_KEYIVCONFIG_ONCE), + the block processing suspension/resumption mechanism is NOT applicable. + + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup CRYP + * @{ + */ + +#if defined(AES) +#ifdef HAL_CRYP_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup CRYP_Private_Defines + * @{ + */ +#define CRYP_GENERAL_TIMEOUT 82U +#define CRYP_TIMEOUT_KEYPREPARATION 82U /*!< The latency of key preparation operation is 82 clock cycles.*/ +#define CRYP_TIMEOUT_GCMCCMINITPHASE 299U /*!< The latency of GCM/CCM init phase to prepare hash subkey + is 299 clock cycles.*/ +#define CRYP_TIMEOUT_GCMCCMHEADERPHASE 290U /*!< The latency of GCM/CCM header phase is 290 clock cycles.*/ + +#define CRYP_PHASE_READY 0x00000001U /*!< CRYP peripheral is ready for initialization. */ +#define CRYP_PHASE_PROCESS 0x00000002U /*!< CRYP peripheral is in processing phase */ +#if (USE_HAL_CRYP_SUSPEND_RESUME == 1U) +#define CRYP_PHASE_HEADER_SUSPENDED 0x00000004U /*!< GCM/GMAC/CCM header phase is suspended */ +#define CRYP_PHASE_PAYLOAD_SUSPENDED 0x00000005U /*!< GCM/CCM payload phase is suspended */ +#endif /* USE_HAL_CRYP_SUSPEND_RESUME */ +#define CRYP_PHASE_HEADER_DMA_FEED 0x00000006U /*!< GCM/GMAC/CCM header is fed to the peripheral in DMA mode */ + +#define CRYP_OPERATINGMODE_ENCRYPT 0x00000000U /*!< Encryption mode(Mode 1) */ +#define CRYP_OPERATINGMODE_KEYDERIVATION AES_CR_MODE_0 /*!< Key derivation mode only used when performing ECB and CBC decryptions (Mode 2) */ +#define CRYP_OPERATINGMODE_DECRYPT AES_CR_MODE_1 /*!< Decryption (Mode 3) */ +#define CRYP_PHASE_INIT 0x00000000U /*!< GCM/GMAC (or CCM) init phase */ +#define CRYP_PHASE_HEADER AES_CR_GCMPH_0 /*!< GCM/GMAC or CCM header phase */ +#define CRYP_PHASE_PAYLOAD AES_CR_GCMPH_1 /*!< GCM(/CCM) payload phase */ +#define CRYP_PHASE_FINAL AES_CR_GCMPH /*!< GCM/GMAC or CCM final phase */ + +/* CTR1 information to use in CCM algorithm */ +#define CRYP_CCM_CTR1_0 0x07FFFFFFU +#define CRYP_CCM_CTR1_1 0xFFFFFF00U +#define CRYP_CCM_CTR1_2 0x00000001U + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/** @addtogroup CRYP_Private_Macros + * @{ + */ + +#define CRYP_SET_PHASE(__HANDLE__, __PHASE__)\ + MODIFY_REG((__HANDLE__)->Instance->CR, AES_CR_GCMPH, (uint32_t)(__PHASE__)) + +/** + * @} + */ + +/* Private struct -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup CRYP_Private_Functions + * @{ + */ + +static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr); +static HAL_StatusTypeDef CRYP_SetHeaderDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size); +static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma); +static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma); +static void CRYP_DMAError(DMA_HandleTypeDef *hdma); +static void CRYP_SetKey(CRYP_HandleTypeDef *hcryp, uint32_t KeySize); +static void CRYP_SetIV(CRYP_HandleTypeDef *hcryp); +static void CRYP_AES_IT(CRYP_HandleTypeDef *hcryp); +static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint32_t Timeout); +static void CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef *hcryp); +static void CRYP_GCMCCM_SetHeaderPhase_IT(CRYP_HandleTypeDef *hcryp); +static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase_DMA(CRYP_HandleTypeDef *hcryp); +static HAL_StatusTypeDef CRYP_GCMCCM_SetPayloadPhase_DMA(CRYP_HandleTypeDef *hcryp); +static HAL_StatusTypeDef CRYP_AESGCM_Process_DMA(CRYP_HandleTypeDef *hcryp); +static HAL_StatusTypeDef CRYP_AESGCM_Process_IT(CRYP_HandleTypeDef *hcryp); +static HAL_StatusTypeDef CRYP_AESGCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout); +static HAL_StatusTypeDef CRYP_AESCCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout); +static HAL_StatusTypeDef CRYP_AESCCM_Process_IT(CRYP_HandleTypeDef *hcryp); +static HAL_StatusTypeDef CRYP_AESCCM_Process_DMA(CRYP_HandleTypeDef *hcryp); +static void CRYP_AES_ProcessData(CRYP_HandleTypeDef *hcrypt, uint32_t Timeout); +static HAL_StatusTypeDef CRYP_AES_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout); +static HAL_StatusTypeDef CRYP_AES_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout); +static HAL_StatusTypeDef CRYP_AES_Decrypt_IT(CRYP_HandleTypeDef *hcryp); +static HAL_StatusTypeDef CRYP_AES_Encrypt_IT(CRYP_HandleTypeDef *hcryp); +static HAL_StatusTypeDef CRYP_AES_Decrypt_DMA(CRYP_HandleTypeDef *hcryp); +static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef *hcryp, uint32_t Timeout); +static void CRYP_ClearCCFlagWhenHigh(CRYP_HandleTypeDef *hcryp, uint32_t Timeout); +#if (USE_HAL_CRYP_SUSPEND_RESUME == 1U) +static void CRYP_Read_IVRegisters(CRYP_HandleTypeDef *hcryp, const uint32_t *Output); +static void CRYP_Write_IVRegisters(CRYP_HandleTypeDef *hcryp, const uint32_t *Input); +static void CRYP_Read_SuspendRegisters(CRYP_HandleTypeDef *hcryp, const uint32_t *Output); +static void CRYP_Write_SuspendRegisters(CRYP_HandleTypeDef *hcryp, const uint32_t *Input); +static void CRYP_Read_KeyRegisters(CRYP_HandleTypeDef *hcryp, const uint32_t *Output, uint32_t KeySize); +static void CRYP_Write_KeyRegisters(CRYP_HandleTypeDef *hcryp, const uint32_t *Input, uint32_t KeySize); +static void CRYP_PhaseProcessingResume(CRYP_HandleTypeDef *hcryp); +#endif /* USE_HAL_CRYP_SUSPEND_RESUME */ + + +/** + * @} + */ + +/* Exported functions ---------------------------------------------------------*/ + +/** @addtogroup CRYP_Exported_Functions + * @{ + */ + +/** @defgroup CRYP_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions. + * +@verbatim + ======================================================================================== + ##### Initialization, de-initialization and Set and Get configuration functions ##### + ======================================================================================== + [..] This section provides functions allowing to: + (+) Initialize the CRYP + (+) DeInitialize the CRYP + (+) Initialize the CRYP MSP + (+) DeInitialize the CRYP MSP + (+) configure CRYP (HAL_CRYP_SetConfig) with the specified parameters in the CRYP_ConfigTypeDef + Parameters which are configured in This section are : + (+) Key size + (+) Data Type : 32,16, 8 or 1bit + (+) AlgoMode : ECB,CBC,CTR,GCM/GMAC and CCM in AES Standard. + (+) Get CRYP configuration (HAL_CRYP_GetConfig) from the specified parameters in the CRYP_HandleTypeDef + (+) For interleave mode, API HAL_CRYP_SaveContext and HAL_CRYP_RestoreContext to be used to save then Restore CRYP + configuration and parameters. CRYP_IVCONFIG_ONCE should be selected for KeyIVConfigSkip parameter. + Only polling mode is supported, interleave mode should be used with HAL_CRYP_Encrypt and HAL_CRYP_Decrypt API. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the CRYP according to the specified + * parameters in the CRYP_ConfigTypeDef and creates the associated handle. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_Init(CRYP_HandleTypeDef *hcryp) +{ + uint32_t cr_value; +#if defined(SAES) + uint32_t tickstart; +#endif /* SAES */ + + /* Check the CRYP handle allocation */ + if (hcryp == NULL) + { + return HAL_ERROR; + } + + /* Check parameters */ + assert_param(IS_CRYP_KEYSIZE(hcryp->Init.KeySize)); + assert_param(IS_CRYP_DATATYPE(hcryp->Init.DataType)); + assert_param(IS_CRYP_ALGORITHM(hcryp->Init.Algorithm)); + assert_param(IS_CRYP_INIT(hcryp->Init.KeyIVConfigSkip)); + +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + if (hcryp->State == HAL_CRYP_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hcryp->Lock = HAL_UNLOCKED; + + hcryp->InCpltCallback = HAL_CRYP_InCpltCallback; /* Legacy weak InCpltCallback */ + hcryp->OutCpltCallback = HAL_CRYP_OutCpltCallback; /* Legacy weak OutCpltCallback */ + hcryp->ErrorCallback = HAL_CRYP_ErrorCallback; /* Legacy weak ErrorCallback */ + + if (hcryp->MspInitCallback == NULL) + { + hcryp->MspInitCallback = HAL_CRYP_MspInit; /* Legacy weak MspInit */ + } + + /* Init the low level hardware */ + hcryp->MspInitCallback(hcryp); + } +#else + if (hcryp->State == HAL_CRYP_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hcryp->Lock = HAL_UNLOCKED; + + /* Init the low level hardware */ + HAL_CRYP_MspInit(hcryp); + } +#endif /* (USE_HAL_CRYP_REGISTER_CALLBACKS) */ + + if (hcryp->Instance == AES) + { + /* Set the key size, data type and Algorithm */ + cr_value = (uint32_t)(hcryp->Init.DataType | hcryp->Init.KeySize | hcryp->Init.Algorithm | hcryp->Init.KeyMode); + /* Set the key size, data type, algorithm and mode */ + MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD | AES_CR_DATATYPE | AES_CR_KEYSIZE | AES_CR_CHMOD, cr_value); + } + else + { + /* SAES is initializing, fetching random number from the RNG */ + tickstart = HAL_GetTick(); + while (HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY)) + { + /* Check for the Timeout */ + if ((HAL_GetTick() - tickstart) > CRYP_GENERAL_TIMEOUT) + { + __HAL_CRYP_DISABLE(hcryp); + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } + /* SAES is initializing, no random number fetching error flagged */ + tickstart = HAL_GetTick(); + while (HAL_IS_BIT_SET(hcryp->Instance->ISR, CRYP_FLAG_RNGEIF)) + { + /* Check for the Timeout */ + if ((HAL_GetTick() - tickstart) > CRYP_GENERAL_TIMEOUT) + { + __HAL_CRYP_DISABLE(hcryp); + hcryp->ErrorCode |= HAL_CRYP_ERROR_RNG; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } + cr_value = (uint32_t)(hcryp->Init.KeyMode | hcryp->Init.DataType | hcryp->Init.KeySize | \ + hcryp->Init.Algorithm | hcryp->Init.KeySelect | hcryp->Init.KeyProtection); + /* Set the key size, data type, algorithm, Key selection and key protection */ + MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD | AES_CR_DATATYPE | AES_CR_KEYSIZE | AES_CR_CHMOD | AES_CR_KEYSEL | + AES_CR_KEYPROT, cr_value); + } + /* Reset Error Code field */ + hcryp->ErrorCode = HAL_CRYP_ERROR_NONE; + + /* Reset peripheral Key and IV configuration flag */ + hcryp->KeyIVConfig = 0U; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + + /* Set the default CRYP phase */ + hcryp->Phase = CRYP_PHASE_READY; + + return HAL_OK; +} + +/** + * @brief De-Initializes the CRYP peripheral. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_DeInit(CRYP_HandleTypeDef *hcryp) +{ + /* Check the CRYP handle allocation */ + if (hcryp == NULL) + { + return HAL_ERROR; + } + + /* Set the default CRYP phase */ + hcryp->Phase = CRYP_PHASE_READY; + + /* Reset CrypInCount and CrypOutCount */ + hcryp->CrypInCount = 0; + hcryp->CrypOutCount = 0; + hcryp->CrypHeaderCount = 0; + + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Set IPRST for software reset */ + SET_BIT(hcryp->Instance->CR, AES_CR_IPRST); + + /* Clear IPRST to allow writing registers */ + CLEAR_BIT(hcryp->Instance->CR, AES_CR_IPRST); + +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + if (hcryp->MspDeInitCallback == NULL) + { + hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit; /* Legacy weak MspDeInit */ + } + /* DeInit the low level hardware */ + hcryp->MspDeInitCallback(hcryp); +#else + /* DeInit the low level hardware: CLOCK, NVIC.*/ + HAL_CRYP_MspDeInit(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_RESET; + __HAL_UNLOCK(hcryp); + + return HAL_OK; +} + +/** + * @brief Configure the CRYP according to the specified + * parameters in the CRYP_ConfigTypeDef + * @param hcryp pointer to a CRYP_HandleTypeDef structure + * @param pConf pointer to a CRYP_ConfigTypeDef structure that contains + * the configuration information for CRYP module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_SetConfig(CRYP_HandleTypeDef *hcryp, CRYP_ConfigTypeDef *pConf) +{ + /* Check the CRYP handle allocation */ + if ((hcryp == NULL) || (pConf == NULL)) + { + return HAL_ERROR; + } + + /* Check parameters */ + assert_param(IS_CRYP_KEYSIZE(pConf->KeySize)); + assert_param(IS_CRYP_DATATYPE(pConf->DataType)); + assert_param(IS_CRYP_ALGORITHM(pConf->Algorithm)); + + if (hcryp->State == HAL_CRYP_STATE_READY) + { + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + __HAL_LOCK(hcryp); + + /* Set CRYP parameters */ + hcryp->Init.DataType = pConf->DataType; + hcryp->Init.pKey = pConf->pKey; + hcryp->Init.Algorithm = pConf->Algorithm; + hcryp->Init.KeySize = pConf->KeySize; + hcryp->Init.pInitVect = pConf->pInitVect; + hcryp->Init.Header = pConf->Header; + hcryp->Init.HeaderSize = pConf->HeaderSize; + hcryp->Init.B0 = pConf->B0; + hcryp->Init.DataWidthUnit = pConf->DataWidthUnit; + hcryp->Init.KeyMode = pConf->KeyMode; + hcryp->Init.HeaderWidthUnit = pConf->HeaderWidthUnit; + hcryp->Init.KeyIVConfigSkip = pConf->KeyIVConfigSkip; + + if (hcryp->Instance == AES) + { + /* Set the key size, data type, AlgoMode and operating mode */ + MODIFY_REG(hcryp->Instance->CR, AES_CR_DATATYPE | AES_CR_KEYSIZE | AES_CR_CHMOD | AES_CR_KMOD, + hcryp->Init.DataType | hcryp->Init.KeySize | hcryp->Init.Algorithm | hcryp->Init.KeyMode); + } + else + { + hcryp->Init.KeySelect = pConf->KeySelect; + hcryp->Init.KeyProtection = pConf->KeyProtection; + + /* In case of HSW, HW or SW key selection, we should specify Key mode selection (SAES_CR_KMOD) */ + if ((hcryp->Init.KeySelect != CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_WRAPPED)) + { + /* Disable AES to change key mode */ + __HAL_CRYP_DISABLE(hcryp); + /* Set key mode selection (Normal, Wrapped or Shared key )*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD, CRYP_KEYMODE_WRAPPED); + } + + /* Set the key size data type, AlgoMode and operating mode */ + MODIFY_REG(hcryp->Instance->CR, AES_CR_DATATYPE | AES_CR_KEYSIZE | AES_CR_CHMOD | \ + AES_CR_KEYSEL | AES_CR_KEYPROT | AES_CR_KMOD, hcryp->Init.DataType | hcryp->Init.KeySize | \ + hcryp->Init.Algorithm | hcryp->Init.KeySelect | hcryp->Init.KeyProtection | hcryp->Init.KeyMode); + /* Set to 0 the number of non-valid bytes using NPBLB field of CR register*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U); + } + /* Clear error flags */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_RWEIF); + __HAL_UNLOCK(hcryp); + + /* Reset Error Code field */ + hcryp->ErrorCode = HAL_CRYP_ERROR_NONE; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + + /* Set the default CRYP phase */ + hcryp->Phase = CRYP_PHASE_READY; + + return HAL_OK; + } + else + { + /* Busy error code field */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; + return HAL_ERROR; + } +} + +/** + * @brief Get CRYP Configuration parameters in associated handle. + * @param pConf pointer to a CRYP_ConfigTypeDef structure + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_GetConfig(CRYP_HandleTypeDef *hcryp, CRYP_ConfigTypeDef *pConf) +{ + /* Check the CRYP handle allocation */ + if ((hcryp == NULL) || (pConf == NULL)) + { + return HAL_ERROR; + } + + if (hcryp->State == HAL_CRYP_STATE_READY) + { + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + __HAL_LOCK(hcryp); + + /* Get CRYP parameters */ + pConf->DataType = hcryp->Init.DataType; + pConf->pKey = hcryp->Init.pKey; + pConf->Algorithm = hcryp->Init.Algorithm; + pConf->KeySize = hcryp->Init.KeySize; + pConf->pInitVect = hcryp->Init.pInitVect; + pConf->Header = hcryp->Init.Header; + pConf->HeaderSize = hcryp->Init.HeaderSize; + pConf->B0 = hcryp->Init.B0; + pConf->DataWidthUnit = hcryp->Init.DataWidthUnit; + pConf->KeyMode = hcryp->Init.KeyMode; + pConf->KeySelect = hcryp->Init.KeySelect; + pConf->KeyProtection = hcryp->Init.KeyProtection; + pConf->KeyIVConfigSkip = hcryp->Init.KeyIVConfigSkip; + pConf->HeaderWidthUnit = hcryp->Init.HeaderWidthUnit; + + __HAL_UNLOCK(hcryp); + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + + return HAL_OK; + } + else + { + /* Busy error code field */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; + return HAL_ERROR; + } +} +/** + * @brief Initializes the CRYP MSP. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @retval None + */ +__weak void HAL_CRYP_MspInit(CRYP_HandleTypeDef *hcryp) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hcryp); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_CRYP_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes CRYP MSP. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @retval None + */ +__weak void HAL_CRYP_MspDeInit(CRYP_HandleTypeDef *hcryp) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hcryp); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_CRYP_MspDeInit could be implemented in the user file + */ +} + +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) +/** + * @brief Register a User CRYP Callback + * To be used instead of the weak predefined callback + * @param hcryp cryp handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_CRYP_INPUT_COMPLETE_CB_ID Input FIFO transfer completed callback ID + * @arg @ref HAL_CRYP_OUTPUT_COMPLETE_CB_ID Output FIFO transfer completed callback ID + * @arg @ref HAL_CRYP_ERROR_CB_ID Error callback ID + * @arg @ref HAL_CRYP_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_CRYP_MSPDEINIT_CB_ID MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @retval status + */ +HAL_StatusTypeDef HAL_CRYP_RegisterCallback(CRYP_HandleTypeDef *hcryp, HAL_CRYP_CallbackIDTypeDef CallbackID, + pCRYP_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + if (hcryp->State == HAL_CRYP_STATE_READY) + { + switch (CallbackID) + { + case HAL_CRYP_INPUT_COMPLETE_CB_ID : + hcryp->InCpltCallback = pCallback; + break; + + case HAL_CRYP_OUTPUT_COMPLETE_CB_ID : + hcryp->OutCpltCallback = pCallback; + break; + + case HAL_CRYP_ERROR_CB_ID : + hcryp->ErrorCallback = pCallback; + break; + + case HAL_CRYP_MSPINIT_CB_ID : + hcryp->MspInitCallback = pCallback; + break; + + case HAL_CRYP_MSPDEINIT_CB_ID : + hcryp->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (hcryp->State == HAL_CRYP_STATE_RESET) + { + switch (CallbackID) + { + case HAL_CRYP_MSPINIT_CB_ID : + hcryp->MspInitCallback = pCallback; + break; + + case HAL_CRYP_MSPDEINIT_CB_ID : + hcryp->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister an CRYP Callback + * CRYP callback is redirected to the weak predefined callback + * @param hcryp cryp handle + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_CRYP_INPUT_COMPLETE_CB_ID Input FIFO transfer completed callback ID + * @arg @ref HAL_CRYP_OUTPUT_COMPLETE_CB_ID Output FIFO transfer completed callback ID + * @arg @ref HAL_CRYP_ERROR_CB_ID Error callback ID + * @arg @ref HAL_CRYP_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_CRYP_MSPDEINIT_CB_ID MspDeInit callback ID + * @retval status + */ +HAL_StatusTypeDef HAL_CRYP_UnRegisterCallback(CRYP_HandleTypeDef *hcryp, HAL_CRYP_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + + if (hcryp->State == HAL_CRYP_STATE_READY) + { + switch (CallbackID) + { + case HAL_CRYP_INPUT_COMPLETE_CB_ID : + hcryp->InCpltCallback = HAL_CRYP_InCpltCallback; /*!< Legacy weak InCpltCallback */ + break; + + case HAL_CRYP_OUTPUT_COMPLETE_CB_ID : + hcryp->OutCpltCallback = HAL_CRYP_OutCpltCallback; /*!< Legacy weak OutCpltCallback */ + break; + + case HAL_CRYP_ERROR_CB_ID : + hcryp->ErrorCallback = HAL_CRYP_ErrorCallback; /*!< Legacy weak ErrorCallback */ + break; + + case HAL_CRYP_MSPINIT_CB_ID : + hcryp->MspInitCallback = HAL_CRYP_MspInit; /*!< Legacy weak MspInit */ + break; + + case HAL_CRYP_MSPDEINIT_CB_ID : + hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit; /*!< Legacy weak MspDeInit */ + break; + + default : + /* Update the error code */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;/*!< Legacy weak ERROR INVALID CALLBACK */ + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (hcryp->State == HAL_CRYP_STATE_RESET) + { + switch (CallbackID) + { + case HAL_CRYP_MSPINIT_CB_ID : + hcryp->MspInitCallback = HAL_CRYP_MspInit; + break; + + case HAL_CRYP_MSPDEINIT_CB_ID : + hcryp->MspDeInitCallback = HAL_CRYP_MspDeInit; + break; + + default : + /* Update the error code */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_INVALID_CALLBACK;; + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + +#if (USE_HAL_CRYP_SUSPEND_RESUME == 1U) +/** + * @brief Request CRYP processing suspension when in interruption mode. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module. + * @note Set the handle field SuspendRequest to the appropriate value so that + * the on-going CRYP processing is suspended as soon as the required + * conditions are met. + * @note HAL_CRYP_ProcessSuspend() can only be invoked when the processing is done + * in non-blocking interrupt mode. + * @note It is advised not to suspend the CRYP processing when the DMA controller + * is managing the data transfer. + * @retval None + */ +void HAL_CRYP_ProcessSuspend(CRYP_HandleTypeDef *hcryp) +{ + /* Set Handle SuspendRequest field */ + hcryp->SuspendRequest = HAL_CRYP_SUSPEND; +} + +/** + * @brief CRYP processing suspension and peripheral internal parameters storage. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @note peripheral internal parameters are stored to be readily available when + * suspended processing is resumed later on. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_Suspend(CRYP_HandleTypeDef *hcryp) +{ + HAL_CRYP_STATETypeDef state; + + /* Request suspension */ + HAL_CRYP_ProcessSuspend(hcryp); + + do + { + state = HAL_CRYP_GetState(hcryp); + } while ((state != HAL_CRYP_STATE_SUSPENDED) && (state != HAL_CRYP_STATE_READY)); + + if (HAL_CRYP_GetState(hcryp) == HAL_CRYP_STATE_READY) + { + /* Processing was already over or was about to end. No suspension done */ + return HAL_ERROR; + } + else + { + /* Suspend Processing */ + + /* If authentication algorithms on-going, carry out first saving steps + before disable the peripheral */ + if ((hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC) || \ + (hcryp->Init.Algorithm == CRYP_AES_CCM)) + { + /* Save Suspension registers */ + CRYP_Read_SuspendRegisters(hcryp, hcryp->SUSPxR_saved); + /* Save Key */ + CRYP_Read_KeyRegisters(hcryp, hcryp->Key_saved, hcryp->Init.KeySize); + /* Save IV */ + CRYP_Read_IVRegisters(hcryp, hcryp->IV_saved); + } + /* Disable AES */ + __HAL_CRYP_DISABLE(hcryp); + + /* Save low-priority block CRYP handle parameters */ + hcryp->Init_saved = hcryp->Init; + hcryp->pCrypInBuffPtr_saved = hcryp->pCrypInBuffPtr; + hcryp->pCrypOutBuffPtr_saved = hcryp->pCrypOutBuffPtr; + hcryp->CrypInCount_saved = hcryp->CrypInCount; + hcryp->CrypOutCount_saved = hcryp->CrypOutCount; + hcryp->Phase_saved = hcryp->Phase; + hcryp->State_saved = hcryp->State; + hcryp->Size_saved = ((hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD)\ + ? (hcryp->Size / 4U) : hcryp->Size); + hcryp->SizesSum_saved = hcryp->SizesSum; + hcryp->CrypHeaderCount_saved = hcryp->CrypHeaderCount; + hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE; + + if ((hcryp->Init.Algorithm == CRYP_AES_CBC) || \ + (hcryp->Init.Algorithm == CRYP_AES_CTR)) + { + /* Save Initialisation Vector registers */ + CRYP_Read_IVRegisters(hcryp, hcryp->IV_saved); + } + + /* Save Control register */ + hcryp->CR_saved = hcryp->Instance->CR; + } + return HAL_OK; +} + +/** + * @brief CRYP processing resumption. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @note Processing restarts at the exact point where it was suspended, based + * on the parameters saved at suspension time. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_Resume(CRYP_HandleTypeDef *hcryp) +{ + /* Check the CRYP handle allocation */ + if (hcryp == NULL) + { + return HAL_ERROR; + } + + if (hcryp->State_saved != HAL_CRYP_STATE_SUSPENDED) + { + /* CRYP was not suspended */ + return HAL_ERROR; + } + else + { + /* Restore low-priority block CRYP handle parameters */ + hcryp->Init = hcryp->Init_saved; + hcryp->State = hcryp->State_saved; + + /* Chaining algorithms case */ + if ((hcryp->Init_saved.Algorithm == CRYP_AES_ECB) || \ + (hcryp->Init_saved.Algorithm == CRYP_AES_CBC) || \ + (hcryp->Init_saved.Algorithm == CRYP_AES_CTR)) + { + /* Restore low-priority block CRYP handle parameters */ + if ((hcryp->Init.Algorithm == CRYP_AES_CBC) || \ + (hcryp->Init.Algorithm == CRYP_AES_CTR)) + { + hcryp->Init.pInitVect = hcryp->IV_saved; + } + __HAL_CRYP_DISABLE(hcryp); + + (void) HAL_CRYP_Init(hcryp); + } + else /* Authentication algorithms case */ + { + /* Restore low-priority block CRYP handle parameters */ + hcryp->Phase = hcryp->Phase_saved; + hcryp->CrypHeaderCount = hcryp->CrypHeaderCount_saved; + hcryp->SizesSum = hcryp->SizesSum_saved; + + /* Disable AES and write-back SUSPxR registers */; + __HAL_CRYP_DISABLE(hcryp); + /* Restore AES Suspend Registers */ + CRYP_Write_SuspendRegisters(hcryp, hcryp->SUSPxR_saved); + /* Restore Control, Key and IV Registers, then enable AES */ + hcryp->Instance->CR = hcryp->CR_saved; + CRYP_Write_KeyRegisters(hcryp, hcryp->Key_saved, hcryp->Init.KeySize); + CRYP_Write_IVRegisters(hcryp, hcryp->IV_saved); + __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE); + __HAL_CRYP_ENABLE(hcryp); + + /* At the same time, set handle state back to READY to be able to resume the AES calculations + without the processing APIs returning HAL_BUSY when called. */ + hcryp->State = HAL_CRYP_STATE_READY; + } + + /* Resume low-priority block processing under IT */ + hcryp->ResumingFlag = 1U; + if (READ_BIT(hcryp->CR_saved, AES_CR_MODE) == CRYP_OPERATINGMODE_ENCRYPT) + { + if (HAL_CRYP_Encrypt_IT(hcryp, hcryp->pCrypInBuffPtr_saved, hcryp->Size_saved, + hcryp->pCrypOutBuffPtr_saved) != HAL_OK) + { + return HAL_ERROR; + } + } + else + { + if (HAL_CRYP_Decrypt_IT(hcryp, hcryp->pCrypInBuffPtr_saved, hcryp->Size_saved, + hcryp->pCrypOutBuffPtr_saved) != HAL_OK) + { + return HAL_ERROR; + } + } + } + return HAL_OK; +} +#endif /* defined (USE_HAL_CRYP_SUSPEND_RESUME) */ + +/** + * @brief CRYP peripheral parameters storage when processing Interleaved mode . + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pcont pointer to a CRYP_ContextTypeDef structure where CRYP parameters will be stored. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_SaveContext(CRYP_HandleTypeDef *hcryp, CRYP_ContextTypeDef *pcont) +{ + /* Check the CRYP handle allocation */ + if ((hcryp == NULL) || (pcont == NULL)) + { + return HAL_ERROR; + } + + if (hcryp->State == HAL_CRYP_STATE_READY) + { + /* Save CRYP handle parameters */ + pcont->DataType = (uint32_t)(hcryp->Init.DataType); + pcont->KeySize = (uint32_t)(hcryp->Init.KeySize); + pcont->pKey = hcryp->Init.pKey; + pcont->pInitVect = hcryp->Init.pInitVect; + pcont->Algorithm = (uint32_t)(hcryp->Init.Algorithm); + pcont->DataWidthUnit = (uint32_t)(hcryp->Init.DataWidthUnit); + pcont->KeyIVConfigSkip = (uint32_t)(hcryp->Init.KeyIVConfigSkip); + pcont->KeyMode = (uint32_t)(hcryp->Init.KeyMode); + pcont->Phase = (uint32_t)(hcryp->Phase); + pcont->KeyIVConfig = (uint32_t)(hcryp->KeyIVConfig); + + /* Save CRYP CR register content */ + pcont->CR_Reg = READ_REG(hcryp->Instance->CR); + + /* Save IER register content */ + pcont->IER_Reg = READ_BIT(hcryp->Instance->IER, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE); + + + if ((hcryp->Init.Algorithm == CRYP_AES_CBC) || \ + (hcryp->Init.Algorithm == CRYP_AES_CTR)) + { + /* Save Initialisation Vector registers */ + pcont->IVR0_Reg = READ_REG(hcryp->Instance->IVR0); + pcont->IVR1_Reg = READ_REG(hcryp->Instance->IVR1); + pcont->IVR2_Reg = READ_REG(hcryp->Instance->IVR2); + pcont->IVR3_Reg = READ_REG(hcryp->Instance->IVR3); + } + + /* To load Key for next piece of message */ + hcryp->KeyIVConfig = 0; + + return HAL_OK; + } + else + { + /* Busy error code field */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; + return HAL_ERROR; + } + +} + +/** + * @brief Restore CRYP parameters needed for Interleaved mode. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pcont pointer to a CRYP_ContextTypeDef structure that contains CRYP parameters stored. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_RestoreContext(CRYP_HandleTypeDef *hcryp, CRYP_ContextTypeDef *pcont) +{ + /* Check the CRYP handle allocation */ + if ((hcryp == NULL) || (pcont == NULL)) + { + return HAL_ERROR; + } + + if (hcryp->State == HAL_CRYP_STATE_READY) + { + /* Restore CRYP handle parameters */ + hcryp->Init.DataType = pcont->DataType; + hcryp->Init.KeySize = pcont->KeySize; + hcryp->Init.pKey = pcont->pKey; + hcryp->Init.pInitVect = pcont->pInitVect; + hcryp->Init.Algorithm = pcont->Algorithm; + hcryp->Init.DataWidthUnit = pcont->DataWidthUnit; + hcryp->Init.KeyIVConfigSkip = pcont->KeyIVConfigSkip; + hcryp->Init.KeyMode = pcont->KeyMode; + hcryp->Phase = pcont->Phase; + hcryp->KeyIVConfig = pcont->KeyIVConfig; + + /* Restore CRYP CR register content */ + WRITE_REG(hcryp->Instance->CR, (uint32_t)(pcont->CR_Reg)); + + /* Restore CRYP IER register content */ + WRITE_REG(hcryp->Instance->IER, (uint32_t)(pcont->IER_Reg)); + + if ((hcryp->Init.Algorithm == CRYP_AES_CBC) || \ + (hcryp->Init.Algorithm == CRYP_AES_CTR)) + { + /* Restore Initialisation Vector registers */ + WRITE_REG(hcryp->Instance->IVR0, (uint32_t)(pcont->IVR0_Reg)); + WRITE_REG(hcryp->Instance->IVR1, (uint32_t)(pcont->IVR1_Reg)); + WRITE_REG(hcryp->Instance->IVR2, (uint32_t)(pcont->IVR2_Reg)); + WRITE_REG(hcryp->Instance->IVR3, (uint32_t)(pcont->IVR3_Reg)); + } + return HAL_OK; + } + else + { + /* Busy error code field */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; + return HAL_ERROR; + } +} + +/** + * @} + */ + +/** @defgroup CRYP_Exported_Functions_Group2 Encryption Decryption functions + * @brief Encryption Decryption functions. + * +@verbatim + ============================================================================== + ##### Encrypt Decrypt functions ##### + ============================================================================== + [..] This section provides API allowing to Encrypt/Decrypt Data following + (+) Standard AES algorithms supported by the peripheral: + - Electronic Code Book(ECB) + - Cipher Block Chaining (CBC) + - Counter mode (CTR) + - Cipher Block Chaining (CBC) + - Counter mode (CTR) + - Galois/counter mode (GCM) + - Counter with Cipher Block Chaining-Message(CCM) + [..] Three processing functions are available: + (+) Polling mode : HAL_CRYP_Encrypt & HAL_CRYP_Decrypt + (+) Interrupt mode : HAL_CRYP_Encrypt_IT & HAL_CRYP_Decrypt_IT + (+) DMA mode : HAL_CRYP_Encrypt_DMA & HAL_CRYP_Decrypt_DMA + +@endverbatim + * @{ + */ + +/* GCM message structure additional details + + ICB + +-------------------------------------------------------+ + | Initialization vector (IV) | Counter | + |----------------|----------------|-----------|---------| + 127 95 63 31 0 + + + Bit Number Register Contents + ---------- --------------- ----------- + 127 ...96 CRYP_IV1R[31:0] ICB[127:96] + 95 ...64 CRYP_IV1L[31:0] B0[95:64] + 63 ... 32 CRYP_IV0R[31:0] ICB[63:32] + 31 ... 0 CRYP_IV0L[31:0] ICB[31:0], where 32-bit counter= 0x2 + + + GCM last block definition + +-------------------------------------------------------------------+ + | Bit[0] | Bit[32] | Bit[64] | Bit[96] | + |-----------|--------------------|-----------|----------------------| + | 0x0 | Header length[31:0]| 0x0 | Payload length[31:0] | + |-----------|--------------------|-----------|----------------------| +*/ + +/* CCM message blocks description + + (##) B0 block : According to NIST Special Publication 800-38C, + The first block B0 is formatted as follows, where l(m) is encoded in + most-significant-byte first order: + + Octet Number Contents + ------------ --------- + 0 Flags + 1 ... 15-q Nonce N + 16-q ... 15 Q + + the Flags field is formatted as follows: + + Bit Number Contents + ---------- ---------------------- + 7 Reserved (always zero) + 6 Adata + 5 ... 3 (t-2)/2 + 2 ... 0 [q-1]3 + + - Q: a bit string representation of the octet length of P (plaintext) + - q The octet length of the binary representation of the octet length of the payload + - A nonce (N), n The octet length of the where n+q=15. + - Flags: most significant octet containing four flags for control information, + - t The octet length of the MAC. + (##) B1 block (header) : associated data length(a) concatenated with Associated Data (A) + the associated data length expressed in bytes (a) defined as below: + - If 0 < a < 216-28, then it is encoded as [a]16, i.e. two octets + - If 216-28 < a < 232, then it is encoded as 0xff || 0xfe || [a]32, i.e. six octets + - If 232 < a < 264, then it is encoded as 0xff || 0xff || [a]64, i.e. ten octets + (##) CTRx block : control blocks + - Generation of CTR1 from first block B0 information : + equal to B0 with first 5 bits zeroed and most significant bits storing octet + length of P also zeroed, then incremented by one + + Bit Number Register Contents + ---------- --------------- ----------- + 127 ...96 CRYP_IV1R[31:0] B0[127:96], where Q length bits are set to 0, except for + bit 0 that is set to 1 + 95 ...64 CRYP_IV1L[31:0] B0[95:64] + 63 ... 32 CRYP_IV0R[31:0] B0[63:32] + 31 ... 0 CRYP_IV0L[31:0] B0[31:0], where flag bits set to 0 + + - Generation of CTR0: same as CTR1 with bit[0] set to zero. +*/ + +/** + * @brief Encryption mode. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pInput Pointer to the input buffer (plaintext) + * @param Size Length of the plaintext buffer either in word or in byte, according to DataWidthUnit + * @param pOutput Pointer to the output buffer(ciphertext) + * @param Timeout Specify Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint16_t Size, uint32_t *pOutput, + uint32_t Timeout) +{ + uint32_t algo; + HAL_StatusTypeDef status; +#ifdef USE_FULL_ASSERT + uint32_t algo_assert = (hcryp->Instance->CR) & AES_CR_CHMOD; + + /* Check input buffer size */ + assert_param(IS_CRYP_BUFFERSIZE(algo_assert, hcryp->Init.DataWidthUnit, Size)); +#endif /* USE_FULL_ASSERT */ + + if (hcryp->State == HAL_CRYP_STATE_READY) + { + /* Change state Busy */ + hcryp->State = HAL_CRYP_STATE_BUSY; + __HAL_LOCK(hcryp); + + /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters */ + hcryp->CrypInCount = 0U; + hcryp->CrypOutCount = 0U; + hcryp->pCrypInBuffPtr = pInput; + hcryp->pCrypOutBuffPtr = pOutput; + + /* Calculate Size parameter in Byte */ + if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD) + { + hcryp->Size = Size * 4U; + } + else + { + hcryp->Size = Size; + } + + if (hcryp->Instance == AES) + { + /* Set the operating mode */ + MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT); + } + else + { + /* Set the operating mode and normal key selection */ + MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE | AES_CR_KMOD, CRYP_OPERATINGMODE_ENCRYPT | CRYP_KEYMODE_NORMAL); + } + /* Algo get algorithm selected */ + algo = hcryp->Instance->CR & AES_CR_CHMOD; + + switch (algo) + { + case CRYP_AES_ECB: + case CRYP_AES_CBC: + case CRYP_AES_CTR: + /* AES encryption */ + status = CRYP_AES_Encrypt(hcryp, Timeout); + break; + + case CRYP_AES_GCM_GMAC: + /* AES GCM encryption */ + status = CRYP_AESGCM_Process(hcryp, Timeout); + break; + + case CRYP_AES_CCM: + /* AES CCM encryption */ + status = CRYP_AESCCM_Process(hcryp, Timeout); + break; + + default: + hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED; + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + } + } + else + { + /* Busy error code field */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; + status = HAL_ERROR; + } + return status; +} + +/** + * @brief Decryption mode. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pInput Pointer to the input buffer (ciphertext ) + * @param Size Length of the input buffer either in word or in byte, according to DataWidthUnit + * @param pOutput Pointer to the output buffer(plaintext) + * @param Timeout Specify Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint16_t Size, uint32_t *pOutput, + uint32_t Timeout) +{ + HAL_StatusTypeDef status; + uint32_t algo; +#ifdef USE_FULL_ASSERT + uint32_t algo_assert = (hcryp->Instance->CR) & AES_CR_CHMOD; + + /* Check input buffer size */ + assert_param(IS_CRYP_BUFFERSIZE(algo_assert, hcryp->Init.DataWidthUnit, Size)); +#endif /* USE_FULL_ASSERT */ + + if (hcryp->State == HAL_CRYP_STATE_READY) + { + /* Change state Busy */ + hcryp->State = HAL_CRYP_STATE_BUSY; + __HAL_LOCK(hcryp); + + /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters*/ + hcryp->CrypInCount = 0U; + hcryp->CrypOutCount = 0U; + hcryp->pCrypInBuffPtr = pInput; + hcryp->pCrypOutBuffPtr = pOutput; + + /* Calculate Size parameter in Byte*/ + if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD) + { + hcryp->Size = Size * 4U; + } + else + { + hcryp->Size = Size; + } + + /* Set Decryption operating mode*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT); + + /* algo get algorithm selected */ + algo = hcryp->Instance->CR & AES_CR_CHMOD; + + switch (algo) + { + case CRYP_AES_ECB: + case CRYP_AES_CBC: + case CRYP_AES_CTR: + /* AES decryption */ + status = CRYP_AES_Decrypt(hcryp, Timeout); + break; + + case CRYP_AES_GCM_GMAC: + /* AES GCM decryption */ + status = CRYP_AESGCM_Process(hcryp, Timeout); + break; + + case CRYP_AES_CCM: + /* AES CCM decryption */ + status = CRYP_AESCCM_Process(hcryp, Timeout); + break; + + default: + hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED; + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + } + } + else + { + /* Busy error code field */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Encryption in interrupt mode. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pInput Pointer to the input buffer (plaintext) + * @param Size Length of the input buffer either in word or in byte, according to DataWidthUnit + * @param pOutput Pointer to the output buffer(ciphertext) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint16_t Size, uint32_t *pOutput) +{ + HAL_StatusTypeDef status; + uint32_t algo; +#ifdef USE_FULL_ASSERT + uint32_t algo_assert = (hcryp->Instance->CR) & AES_CR_CHMOD; + + /* Check input buffer size */ + assert_param(IS_CRYP_BUFFERSIZE(algo_assert, hcryp->Init.DataWidthUnit, Size)); +#endif /* USE_FULL_ASSERT */ + + if (hcryp->State == HAL_CRYP_STATE_READY) + { + /* Change state Busy */ + hcryp->State = HAL_CRYP_STATE_BUSY; + __HAL_LOCK(hcryp); + + /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters*/ +#if (USE_HAL_CRYP_SUSPEND_RESUME == 1U) + if (hcryp->ResumingFlag == 1U) + { + hcryp->ResumingFlag = 0U; + if (hcryp->Phase != CRYP_PHASE_HEADER_SUSPENDED) + { + hcryp->CrypInCount = (uint16_t) hcryp->CrypInCount_saved; + hcryp->CrypOutCount = (uint16_t) hcryp->CrypOutCount_saved; + } + else + { + hcryp->CrypInCount = 0U; + hcryp->CrypOutCount = 0U; + } + } + else +#endif /* USE_HAL_CRYP_SUSPEND_RESUME */ + { + hcryp->CrypInCount = 0U; + hcryp->CrypOutCount = 0U; + } + + hcryp->pCrypInBuffPtr = pInput; + hcryp->pCrypOutBuffPtr = pOutput; + + /* Calculate Size parameter in Byte*/ + if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD) + { + hcryp->Size = Size * 4U; + } + else + { + hcryp->Size = Size; + } + + /* Set encryption operating mode*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT); + + /* algo get algorithm selected */ + algo = hcryp->Instance->CR & AES_CR_CHMOD; + + switch (algo) + { + + case CRYP_AES_ECB: + case CRYP_AES_CBC: + case CRYP_AES_CTR: + /* AES encryption */ + status = CRYP_AES_Encrypt_IT(hcryp); + break; + + case CRYP_AES_GCM_GMAC: + /* AES GCM encryption */ + status = CRYP_AESGCM_Process_IT(hcryp); + break; + + case CRYP_AES_CCM: + /* AES CCM encryption */ + status = CRYP_AESCCM_Process_IT(hcryp); + break; + + default: + hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED; + status = HAL_ERROR; + break; + } + } + else + { + /* Busy error code field */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Decryption in interrupt mode. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pInput Pointer to the input buffer (ciphertext ) + * @param Size Length of the input buffer either in word or in byte, according to DataWidthUnit + * @param pOutput Pointer to the output buffer(plaintext) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint16_t Size, uint32_t *pOutput) +{ + HAL_StatusTypeDef status; + uint32_t algo; +#ifdef USE_FULL_ASSERT + uint32_t algo_assert = (hcryp->Instance->CR) & AES_CR_CHMOD; + + /* Check input buffer size */ + assert_param(IS_CRYP_BUFFERSIZE(algo_assert, hcryp->Init.DataWidthUnit, Size)); +#endif /* USE_FULL_ASSERT */ + + if (hcryp->State == HAL_CRYP_STATE_READY) + { + /* Change state Busy */ + hcryp->State = HAL_CRYP_STATE_BUSY; + __HAL_LOCK(hcryp); + + /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters*/ +#if (USE_HAL_CRYP_SUSPEND_RESUME == 1U) + if (hcryp->ResumingFlag == 1U) + { + hcryp->ResumingFlag = 0U; + if (hcryp->Phase != CRYP_PHASE_HEADER_SUSPENDED) + { + hcryp->CrypInCount = (uint16_t) hcryp->CrypInCount_saved; + hcryp->CrypOutCount = (uint16_t) hcryp->CrypOutCount_saved; + } + else + { + hcryp->CrypInCount = 0U; + hcryp->CrypOutCount = 0U; + } + } + else +#endif /* USE_HAL_CRYP_SUSPEND_RESUME */ + { + hcryp->CrypInCount = 0U; + hcryp->CrypOutCount = 0U; + } + hcryp->pCrypInBuffPtr = pInput; + hcryp->pCrypOutBuffPtr = pOutput; + + /* Calculate Size parameter in Byte*/ + if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD) + { + hcryp->Size = Size * 4U; + } + else + { + hcryp->Size = Size; + } + + /* Set decryption operating mode*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT); + + /* algo get algorithm selected */ + algo = hcryp->Instance->CR & AES_CR_CHMOD; + + switch (algo) + { + case CRYP_AES_ECB: + case CRYP_AES_CBC: + case CRYP_AES_CTR: + /* AES decryption */ + status = CRYP_AES_Decrypt_IT(hcryp); + break; + + case CRYP_AES_GCM_GMAC: + /* AES GCM decryption */ + status = CRYP_AESGCM_Process_IT(hcryp); + break; + + case CRYP_AES_CCM: + /* AES CCM decryption */ + status = CRYP_AESCCM_Process_IT(hcryp); + break; + + default: + hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED; + status = HAL_ERROR; + break; + } + } + else + { + /* Busy error code field */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Encryption in DMA mode. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pInput Pointer to the input buffer (plaintext) + * @param Size Length of the input buffer either in word or in byte, according to DataWidthUnit + * @param pOutput Pointer to the output buffer(ciphertext) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint16_t Size, uint32_t *pOutput) +{ + HAL_StatusTypeDef status; + uint32_t count; + uint32_t algo; + uint32_t dokeyivconfig = 1U; /* By default, carry out peripheral Key and IV configuration */ +#ifdef USE_FULL_ASSERT + uint32_t algo_assert = (hcryp->Instance->CR) & AES_CR_CHMOD; + + /* Check input buffer size */ + assert_param(IS_CRYP_BUFFERSIZE(algo_assert, hcryp->Init.DataWidthUnit, Size)); +#endif /* USE_FULL_ASSERT */ + + if (hcryp->State == HAL_CRYP_STATE_READY) + { + /* Change state Busy */ + hcryp->State = HAL_CRYP_STATE_BUSY; + __HAL_LOCK(hcryp); + + /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters*/ + hcryp->CrypInCount = 0U; + hcryp->CrypOutCount = 0U; + hcryp->pCrypInBuffPtr = pInput; + hcryp->pCrypOutBuffPtr = pOutput; + + /* Calculate Size parameter in Byte*/ + if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD) + { + hcryp->Size = Size * 4U; + } + else + { + hcryp->Size = Size; + } + + /* Set encryption operating mode*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT); + + /* algo get algorithm selected */ + algo = hcryp->Instance->CR & AES_CR_CHMOD; + + switch (algo) + { + case CRYP_AES_ECB: + case CRYP_AES_CBC: + case CRYP_AES_CTR: + if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) + { + if (hcryp->KeyIVConfig == 1U) + { + /* If the Key and IV configuration has to be done only once + and if it has already been done, skip it */ + dokeyivconfig = 0U; + } + else + { + /* If the Key and IV configuration has to be done only once + and if it has not been done already, do it and set KeyIVConfig + to keep track it won't have to be done again next time */ + hcryp->KeyIVConfig = 1U; + } + } + + if ((dokeyivconfig == 1U) && (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG)) + { + if (hcryp->Instance == AES) + { + /* Set the Key */ + if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED) + { + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + else /* After sharing the key, AES should set KMOD[1:0] to 00.*/ + { + hcryp->Instance->CR &= ~CRYP_KEYMODE_SHARED; + } + } + else + { + /* We should re-write Key, in the case where we change key after first operation */ + if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL)) + { + /* Set the Key */ + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + /* Wait for KEYVALID flag to be set */ + count = CRYP_TIMEOUT_KEYPREPARATION; + do + { + count--; + if (count == 0U) + { + /* Disable the SAES peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change state */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_KEYVALID)); + } + /* Set the Initialization Vector */ + if (hcryp->Init.Algorithm != CRYP_AES_ECB) + { + CRYP_SetIV(hcryp); + } + } /* If (dokeyivconfig == 1U) */ + + /* Peripheral Key configuration to not do, IV to configure for CBC */ + if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYNOCONFIG) + { + if (hcryp->Init.Algorithm != CRYP_AES_ECB) + { + /* Set the Initialization Vector */ + CRYP_SetIV(hcryp); + } + } + + /* Set the phase */ + hcryp->Phase = CRYP_PHASE_PROCESS; + + /* Start DMA process transfer for AES */ + CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size), (uint32_t)(hcryp->pCrypOutBuffPtr)); + status = HAL_OK; + break; + + case CRYP_AES_GCM_GMAC: + /* AES GCM encryption */ + status = CRYP_AESGCM_Process_DMA(hcryp); + break; + + case CRYP_AES_CCM: + /* AES CCM encryption */ + status = CRYP_AESCCM_Process_DMA(hcryp); + break; + + default: + hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED; + status = HAL_ERROR; + break; + } + } + else + { + /* Busy error code field */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Decryption in DMA mode. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pInput Pointer to the input buffer (ciphertext ) + * @param Size Length of the input buffer either in word or in byte, according to DataWidthUnit + * @param pOutput Pointer to the output buffer(plaintext) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint16_t Size, uint32_t *pOutput) +{ + HAL_StatusTypeDef status; + uint32_t algo; +#ifdef USE_FULL_ASSERT + uint32_t algo_assert = (hcryp->Instance->CR) & AES_CR_CHMOD; + + /* Check input buffer size */ + assert_param(IS_CRYP_BUFFERSIZE(algo_assert, hcryp->Init.DataWidthUnit, Size)); +#endif /* USE_FULL_ASSERT */ + + if (hcryp->State == HAL_CRYP_STATE_READY) + { + + /* Change state Busy */ + hcryp->State = HAL_CRYP_STATE_BUSY; + __HAL_LOCK(hcryp); + + /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr, pCrypOutBuffPtr and Size parameters*/ + hcryp->CrypInCount = 0U; + hcryp->CrypOutCount = 0U; + hcryp->pCrypInBuffPtr = pInput; + hcryp->pCrypOutBuffPtr = pOutput; + + /* Calculate Size parameter in Byte*/ + if (hcryp->Init.DataWidthUnit == CRYP_DATAWIDTHUNIT_WORD) + { + hcryp->Size = Size * 4U; + } + else + { + hcryp->Size = Size; + } + + /* Set decryption operating mode*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT); + + /* algo get algorithm selected */ + algo = hcryp->Instance->CR & AES_CR_CHMOD; + + switch (algo) + { + case CRYP_AES_ECB: + case CRYP_AES_CBC: + case CRYP_AES_CTR: + /* AES decryption */ + status = CRYP_AES_Decrypt_DMA(hcryp); + break; + + case CRYP_AES_GCM_GMAC: + /* AES GCM decryption */ + status = CRYP_AESGCM_Process_DMA(hcryp); + break; + + case CRYP_AES_CCM: + /* AES CCM decryption */ + status = CRYP_AESCCM_Process_DMA(hcryp); + break; + + default: + hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED; + status = HAL_ERROR; + break; + } + } + else + { + /* Busy error code field */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; + status = HAL_ERROR; + } + return status; +} + +/** + * @} + */ + +/** @defgroup CRYP_Exported_Functions_Group3 CRYP IRQ handler management + * @brief CRYP IRQ handler. + * +@verbatim + ============================================================================== + ##### CRYP IRQ handler management ##### + ============================================================================== +[..] This section provides CRYP IRQ handler and callback functions. + (+) HAL_CRYP_IRQHandler CRYP interrupt request + (+) HAL_CRYP_InCpltCallback input data transfer complete callback + (+) HAL_CRYP_OutCpltCallback output data transfer complete callback + (+) HAL_CRYP_ErrorCallback CRYP error callback + (+) HAL_CRYP_GetState return the CRYP state + (+) HAL_CRYP_GetError return the CRYP error code +@endverbatim + * @{ + */ + +/** + * @brief This function handles cryptographic interrupt request. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @retval None + */ +void HAL_CRYP_IRQHandler(CRYP_HandleTypeDef *hcryp) +{ + /* Check if Read or write error occurred */ + if (__HAL_CRYP_GET_IT_SOURCE(hcryp, CRYP_IT_RWEIE) != RESET) + { + /* If write Error occurred */ + if (__HAL_CRYP_GET_FLAG(hcryp, CRYP_FLAG_WRERR) != RESET) + { + hcryp->ErrorCode |= HAL_CRYP_ERROR_WRITE; + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_RWEIF); + } + /* If read Error occurred */ + if (__HAL_CRYP_GET_FLAG(hcryp, CRYP_FLAG_RDERR) != RESET) + { + hcryp->ErrorCode |= HAL_CRYP_ERROR_READ; + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_RWEIF); + } + } + /* Check if Key error occurred */ + if (__HAL_CRYP_GET_IT_SOURCE(hcryp, CRYP_IT_KEIE) != RESET) + { + if (__HAL_CRYP_GET_FLAG(hcryp, CRYP_FLAG_KEIF) != RESET) + { + hcryp->ErrorCode |= HAL_CRYP_ERROR_KEY; + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_KEIF); + /*Call weak error callback*/ + HAL_CRYP_ErrorCallback(hcryp); + } + } + + if (__HAL_CRYP_GET_FLAG(hcryp, CRYP_FLAG_CCF) != RESET) + { + if (__HAL_CRYP_GET_IT_SOURCE(hcryp, CRYP_IT_CCFIE) != RESET) + { + /* Clear computation complete flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + + if ((hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC) || (hcryp->Init.Algorithm == CRYP_AES_CCM)) + { + /* if header phase */ + if ((hcryp->Instance->CR & CRYP_PHASE_HEADER) == CRYP_PHASE_HEADER) + { + CRYP_GCMCCM_SetHeaderPhase_IT(hcryp); + } + else /* if payload phase */ + { + CRYP_GCMCCM_SetPayloadPhase_IT(hcryp); + } + } + else /* AES Algorithm ECB,CBC or CTR*/ + { + CRYP_AES_IT(hcryp); + } + } + } +} + +/** + * @brief Return the CRYP error code. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for the CRYP peripheral + * @retval CRYP error code + */ +uint32_t HAL_CRYP_GetError(const CRYP_HandleTypeDef *hcryp) +{ + return hcryp->ErrorCode; +} + +/** + * @brief Returns the CRYP state. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module. + * @retval HAL state + */ +HAL_CRYP_STATETypeDef HAL_CRYP_GetState(const CRYP_HandleTypeDef *hcryp) +{ + return hcryp->State; +} + +/** + * @brief Input FIFO transfer completed callback. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module. + * @retval None + */ +__weak void HAL_CRYP_InCpltCallback(CRYP_HandleTypeDef *hcryp) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hcryp); + + /* NOTE : This function should not be modified; when the callback is needed, + the HAL_CRYP_InCpltCallback can be implemented in the user file + */ +} + +/** + * @brief Output FIFO transfer completed callback. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module. + * @retval None + */ +__weak void HAL_CRYP_OutCpltCallback(CRYP_HandleTypeDef *hcryp) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hcryp); + + /* NOTE : This function should not be modified; when the callback is needed, + the HAL_CRYP_OutCpltCallback can be implemented in the user file + */ +} + +/** + * @brief CRYP error callback. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module. + * @retval None + */ +__weak void HAL_CRYP_ErrorCallback(CRYP_HandleTypeDef *hcryp) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hcryp); + + /* NOTE : This function should not be modified; when the callback is needed, + the HAL_CRYP_ErrorCallback can be implemented in the user file + */ +} +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @addtogroup CRYP_Private_Functions + * @{ + */ + +/** + * @brief Encryption in ECB/CBC & CTR Algorithm with AES Standard + * @param hcryp pointer to a CRYP_HandleTypeDef structure + * @param Timeout specify Timeout value + * @retval HAL status + */ +static HAL_StatusTypeDef CRYP_AES_Encrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout) +{ + uint16_t incount; /* Temporary CrypInCount Value */ + uint16_t outcount; /* Temporary CrypOutCount Value */ + uint32_t dokeyivconfig = 1U; /* By default, carry out peripheral Key and IV configuration */ + uint32_t tickstart; + + if ((hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) || (hcryp->Init.KeyIVConfigSkip == CRYP_IVCONFIG_ONCE)) + { + if (hcryp->KeyIVConfig == 1U) + { + /* If the Key and IV configuration has to be done only once + and if it has already been done, skip it */ + dokeyivconfig = 0U; + } + else + { + /* If the Key and IV configuration has to be done only once + and if it has not been done already, do it and set KeyIVConfig + to keep track it won't have to be done again next time */ + hcryp->KeyIVConfig = 1U; + } + } + + if (dokeyivconfig == 1U) + { + if ((hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) || \ + (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ALWAYS)) + { + if (hcryp->Instance == AES) + { + /* Set the Key */ + if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED) + { + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + else /* After sharing the key, AES should set KMOD[1:0] to 00.*/ + { + hcryp->Instance->CR &= ~CRYP_KEYMODE_SHARED; + } + } + else + { + /* We should re-write Key, in the case where we change key after first operation */ + if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL)) + { + /* Set the Key */ + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + /* Get tick */ + tickstart = HAL_GetTick(); + + while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_KEYVALID)) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change state */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } + } + } + if (hcryp->Init.Algorithm != CRYP_AES_ECB) + { + /* Set the Initialization Vector */ + CRYP_SetIV(hcryp); + } + } + /* key & IV configuration for CBC and CTR in interleave mode */ + if (hcryp->Init.KeyIVConfigSkip == CRYP_IVCONFIG_ONCE) + { + /* Set the Key */ + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + if (hcryp->Init.Algorithm != CRYP_AES_ECB) + { + /* Set the Initialization Vector*/ + CRYP_SetIV(hcryp); + } + } + } /* If (dokeyivconfig == 1U) */ + else + { + /* interleave mode Key configuration */ + if (hcryp->Init.KeyIVConfigSkip == CRYP_IVCONFIG_ONCE) + { + /* Set the Key */ + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + } + /* Peripheral Key configuration to not do, IV to configure for CBC */ + if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYNOCONFIG) + { + if (hcryp->Init.Algorithm != CRYP_AES_ECB) + { + /* Set the Initialization Vector*/ + CRYP_SetIV(hcryp); + } + } + + /* Set the phase */ + hcryp->Phase = CRYP_PHASE_PROCESS; + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + incount = hcryp->CrypInCount; + outcount = hcryp->CrypOutCount; + while ((incount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U))) + { + /* Write plain data and get cipher data */ + CRYP_AES_ProcessData(hcryp, Timeout); + incount = hcryp->CrypInCount; + outcount = hcryp->CrypOutCount; + } + + /* Disable CRYP */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Encryption in ECB/CBC & CTR mode with AES Standard using interrupt mode + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @retval HAL status + */ +static HAL_StatusTypeDef CRYP_AES_Encrypt_IT(CRYP_HandleTypeDef *hcryp) +{ + uint32_t count; + uint32_t dokeyivconfig = 1U; /* By default, carry out peripheral Key and IV configuration */ + + if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) + { + if (hcryp->KeyIVConfig == 1U) + { + /* If the Key and IV configuration has to be done only once + and if it has already been done, skip it */ + dokeyivconfig = 0U; + } + else + { + /* If the Key and IV configuration has to be done only once + and if it has not been done already, do it and set KeyIVConfig + to keep track it won't have to be done again next time */ + hcryp->KeyIVConfig = 1U; + } + } + + if ((dokeyivconfig == 1U) && (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG)) + { + if (hcryp->Instance == AES) + { + /* Set the Key */ + if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED) + { + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + else /*after sharing the key, AES should set KMOD[1:0] to 00.*/ + { + hcryp->Instance->CR &= ~CRYP_KEYMODE_SHARED; + } + } + else + { + /* we should re-write Key, in the case where we change key after first operation*/ + if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL)) + { + /* Set the Key */ + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + /* Wait for KEYVALID flag to be set */ + count = CRYP_TIMEOUT_KEYPREPARATION; + do + { + count--; + if (count == 0U) + { + /* Disable the SAES peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change state */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_KEYVALID)); + } + if (hcryp->Init.Algorithm != CRYP_AES_ECB) + { + /* Set the Initialization Vector*/ + CRYP_SetIV(hcryp); + } + } /* if (dokeyivconfig == 1U) */ + /* Peripheral Key configuration to not do, IV to configure for CBC */ + if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYNOCONFIG) + { + if (hcryp->Init.Algorithm != CRYP_AES_ECB) + { + /* Set the Initialization Vector*/ + CRYP_SetIV(hcryp); + } + } + + /* Set the phase */ + hcryp->Phase = CRYP_PHASE_PROCESS; + + if (hcryp->Size != 0U) + { + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Write the input block in the IN FIFO */ + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + + /* Enable computation complete flag and Key, Read and Write error interrupts */ + __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE); + } + else + { + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + } + + return HAL_OK; +} + +/** + * @brief Decryption in ECB/CBC & CTR mode with AES Standard + * @param hcryp pointer to a CRYP_HandleTypeDef structure + * @param Timeout Specify Timeout value + * @retval HAL status + */ +static HAL_StatusTypeDef CRYP_AES_Decrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout) +{ + uint16_t incount; /* Temporary CrypInCount Value */ + uint16_t outcount; /* Temporary CrypOutCount Value */ + uint32_t dokeyivconfig = 1U; /* By default, carry out peripheral Key and IV configuration */ + + if ((hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) || (hcryp->Init.KeyIVConfigSkip == CRYP_IVCONFIG_ONCE)) + { + if (hcryp->KeyIVConfig == 1U) + { + /* If the Key and IV configuration has to be done only once + and if it has already been done, skip it */ + dokeyivconfig = 0U; + } + else + { + /* If the Key and IV configuration has to be done only once + and if it has not been done already, do it and set KeyIVConfig + to keep track it won't have to be done again next time */ + hcryp->KeyIVConfig = 1U; + } + } + + if (dokeyivconfig == 1U) + { + if (hcryp->Instance == AES) + { + /* Key preparation for ECB/CBC */ + if (hcryp->Init.Algorithm != CRYP_AES_CTR) /*ECB or CBC*/ + { + /* key preparation for decryption, operating mode 2*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD, CRYP_KEYMODE_NORMAL); + MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION); + + /* Set the Key */ + if ((hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) || \ + (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ALWAYS)) + { + if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED) + { + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + else /*after sharing the key, AES should set KMOD[1:0] to 00.*/ + { + hcryp->Instance->CR &= ~CRYP_KEYMODE_SHARED; + } + } + + /* interleave mode Key configuration */ + else if (hcryp->Init.KeyIVConfigSkip == CRYP_IVCONFIG_ONCE) + { + /* Set the Key */ + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + else + { + /* Nothing to do */ + } + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Wait for CCF flag to be raised */ + if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK) + { + return HAL_ERROR; + } + /* Clear CCF Flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + + /* Return to decryption operating mode(Mode 3)*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT); + } + else /*Algorithm CTR */ + { + /* Set the Key */ + if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG) + { + if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED) + { + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + else /*after sharing the key, AES should set KMOD[1:0] to 00.*/ + { + hcryp->Instance->CR &= ~CRYP_KEYMODE_SHARED; + } + } + } + } + else /*SAES*/ + { + if (hcryp->Init.Algorithm != CRYP_AES_CTR) /*ECB or CBC*/ + { + /* key preparation for decryption, operating mode 2*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION); + + /* we should re-write Key, in the case where we change key after first operation*/ + if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL)) + { + if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG) + { + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + } + + /* Enable SAES */ + __HAL_CRYP_ENABLE(hcryp); + + /* Wait for CCF flag to be raised */ + if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK) + { + return HAL_ERROR; + } + /* Clear CCF Flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + + /* End of Key preparation for ECB/CBC */ + /* Return to decryption operating mode(Mode 3)*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT); + } + else /*Algorithm CTR */ + { + /* we should re-write Key, in the case where we change key after first operation*/ + if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL)) + { + if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG) + { + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + } + } + } + /* Set IV */ + if (hcryp->Init.Algorithm != CRYP_AES_ECB) + { + /* Set the Initialization Vector*/ + CRYP_SetIV(hcryp); + } + } /* if (dokeyivconfig == 1U) */ + + else /* if (dokeyivconfig == 0U) */ + { + /* interleave mode Key configuration */ + if (hcryp->Init.KeyIVConfigSkip == CRYP_IVCONFIG_ONCE) + { + if (hcryp->Instance == AES) + { + /* Key preparation for ECB/CBC */ + if (hcryp->Init.Algorithm != CRYP_AES_CTR) /*ECB or CBC*/ + { + /* key preparation for decryption, operating mode 2*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD, CRYP_KEYMODE_NORMAL); + MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION); + + /* Set the Key */ + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Wait for CCF flag to be raised */ + if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK) + { + return HAL_ERROR; + } + /* Clear CCF Flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + + /* Return to decryption operating mode(Mode 3)*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT); + } + else /*Algorithm CTR */ + { + /* Set the Key */ + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + + } + } + } + + } + /* Set the phase */ + hcryp->Phase = CRYP_PHASE_PROCESS; + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + incount = hcryp->CrypInCount; + outcount = hcryp->CrypOutCount; + while ((incount < (hcryp->Size / 4U)) && (outcount < (hcryp->Size / 4U))) + { + /* Write plain data and get cipher data */ + CRYP_AES_ProcessData(hcryp, Timeout); + incount = hcryp->CrypInCount; + outcount = hcryp->CrypOutCount; + } + /* Disable CRYP */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + + return HAL_OK; +} +/** + * @brief Decryption in ECB/CBC & CTR mode with AES Standard using interrupt mode + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @retval HAL status + */ +static HAL_StatusTypeDef CRYP_AES_Decrypt_IT(CRYP_HandleTypeDef *hcryp) +{ + uint32_t count; + uint32_t dokeyivconfig = 1U; /* By default, carry out peripheral Key and IV configuration */ + + if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) + { + if (hcryp->KeyIVConfig == 1U) + { + /* If the Key and IV configuration has to be done only once + and if it has already been done, skip it */ + dokeyivconfig = 0U; + } + else + { + /* If the Key and IV configuration has to be done only once + and if it has not been done already, do it and set KeyIVConfig + to keep track it won't have to be done again next time */ + hcryp->KeyIVConfig = 1U; + } + } + + if (dokeyivconfig == 1U) + { + if (hcryp->Instance == AES) + { + /* Key preparation for ECB/CBC */ + if (hcryp->Init.Algorithm != CRYP_AES_CTR) + { + /* key preparation for decryption, operating mode 2*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD, CRYP_KEYMODE_NORMAL); + MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION); + + /* Set the Key */ + if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG) + { + if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED) + { + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + else /*after sharing the key, AES should set KMOD[1:0] to 00.*/ + { + hcryp->Instance->CR &= ~CRYP_KEYMODE_SHARED; + } + } + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Wait for CCF flag to be raised */ + count = CRYP_TIMEOUT_KEYPREPARATION; + do + { + count--; + if (count == 0U) + { + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change state */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF)); + + /* Clear CCF Flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + + /* Return to decryption operating mode(Mode 3)*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT); + } + + else /*Algorithm CTR */ + { + if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG) + { + if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED) + { + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + else /*after sharing the key, AES should set KMOD[1:0] to 00.*/ + { + hcryp->Instance->CR &= ~CRYP_KEYMODE_SHARED; + } + } + } + } + else /*SAES*/ + { + /* Key preparation for ECB/CBC */ + if (hcryp->Init.Algorithm != CRYP_AES_CTR) + { + /* key preparation for decryption, operating mode 2*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION); + + /* we should re-write Key, in the case where we change key after first operation*/ + if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL)) + { + if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG) + { + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + } + /* Enable SAES */ + __HAL_CRYP_ENABLE(hcryp); + + /* Wait for CCF flag to be raised */ + count = CRYP_TIMEOUT_KEYPREPARATION; + do + { + count--; + if (count == 0U) + { + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change state */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF)); + + /* Clear CCF Flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + + /* End of Key preparation for ECB/CBC */ + /* Return to decryption operating mode(Mode 3)*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT); + } + else /*Algorithm CTR */ + { + /* we should re-write Key, in the case where we change key after first operation*/ + if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL)) + { + if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG) + { + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + } + } + } + /* Set IV */ + if (hcryp->Init.Algorithm != CRYP_AES_ECB) + { + /* Set the Initialization Vector*/ + CRYP_SetIV(hcryp); + } + } /* if (dokeyivconfig == 1U) */ + + /* Set the phase */ + hcryp->Phase = CRYP_PHASE_PROCESS; + if (hcryp->Size != 0U) + { + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Write the input block in the IN FIFO */ + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + + /* Enable computation complete flag and error interrupts */ + __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE); + } + else + { + __HAL_UNLOCK(hcryp); + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + } + + return HAL_OK; +} +/** + * @brief Decryption in ECB/CBC & CTR mode with AES Standard using DMA mode + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @retval HAL status + */ +static HAL_StatusTypeDef CRYP_AES_Decrypt_DMA(CRYP_HandleTypeDef *hcryp) +{ + uint32_t count; + uint32_t dokeyivconfig = 1U; /* By default, carry out peripheral Key and IV configuration */ + + if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) + { + if (hcryp->KeyIVConfig == 1U) + { + /* If the Key and IV configuration has to be done only once + and if it has already been done, skip it */ + dokeyivconfig = 0U; + } + else + { + /* If the Key and IV configuration has to be done only once + and if it has not been done already, do it and set KeyIVConfig + to keep track it won't have to be done again next time */ + hcryp->KeyIVConfig = 1U; + } + } + + if (dokeyivconfig == 1U) + { + if (hcryp->Instance == AES) + { + /* Key preparation for ECB/CBC */ + if (hcryp->Init.Algorithm != CRYP_AES_CTR) + { + /* key preparation for decryption, operating mode 2*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD, CRYP_KEYMODE_NORMAL); + MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION); + + /* Set the Key */ + if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG) + { + if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED) + { + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + else /*after sharing the key, AES should set KMOD[1:0] to 00.*/ + { + hcryp->Instance->CR &= ~CRYP_KEYMODE_SHARED; + } + } + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Wait for CCF flag to be raised */ + count = CRYP_TIMEOUT_KEYPREPARATION; + do + { + count--; + if (count == 0U) + { + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change state */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF)); + + /* Clear CCF Flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + + /* Return to decryption operating mode(Mode 3)*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT); + } + else /*Algorithm CTR */ + { + /* Set the Key */ + if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG) + { + if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED) + { + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + else /*after sharing the key, AES should set KMOD[1:0] to 00.*/ + { + hcryp->Instance->CR &= ~CRYP_KEYMODE_SHARED; + } + } + } + } + else /*SAES*/ + { + /* Key preparation for ECB/CBC */ + if (hcryp->Init.Algorithm != CRYP_AES_CTR) + { + /* key preparation for decryption, operating mode 2*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION); + + /* we should re-write Key, in the case where we change key after first operation*/ + if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL)) + { + if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG) + { + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + } + /* Enable SAES */ + __HAL_CRYP_ENABLE(hcryp); + + /* Wait for CCF flag to be raised */ + count = CRYP_TIMEOUT_KEYPREPARATION; + do + { + count--; + if (count == 0U) + { + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change state */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF)); + + /* Clear CCF Flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + + /* End of Key preparation for ECB/CBC */ + /* Return to decryption operating mode(Mode 3)*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT); + } + else /*Algorithm CTR */ + { + /* we should re-write Key, in the case where we change key after first operation*/ + if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL)) + { + if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG) + { + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + } + } + } + + if (hcryp->Init.Algorithm != CRYP_AES_ECB) + { + /* Set the Initialization Vector*/ + CRYP_SetIV(hcryp); + } + } /* if (dokeyivconfig == 1U) */ + + /* Set the phase */ + hcryp->Phase = CRYP_PHASE_PROCESS; + + if (hcryp->Size != 0U) + { + /* Set the input and output addresses and start DMA transfer */ + CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (hcryp->Size), (uint32_t)(hcryp->pCrypOutBuffPtr)); + } + else + { + __HAL_UNLOCK(hcryp); + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + } + + return HAL_OK; +} + + +/** + * @brief DMA CRYP input data process complete callback. + * @param hdma DMA handle + * @retval None + */ +static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma) +{ + CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + uint32_t loopcounter; + uint32_t headersize_in_bytes; + uint32_t tmp; + const uint32_t mask[12] = {0x0U, 0xFF000000U, 0xFFFF0000U, 0xFFFFFF00U, /* 32-bit data type */ + 0x0U, 0x0000FF00U, 0x0000FFFFU, 0xFF00FFFFU, /* 16-bit data type */ + 0x0U, 0x000000FFU, 0x0000FFFFU, 0x00FFFFFFU + }; /* 8-bit data type */ + uint32_t algo; + + /* Disable the DMA transfer for input FIFO request by resetting the DIEN bit + in the DMACR register */ + CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAINEN); + + if (hcryp->Phase == CRYP_PHASE_HEADER_DMA_FEED) + { + /* DMA is disabled, CCF is meaningful. Wait for computation completion before moving forward */ + CRYP_ClearCCFlagWhenHigh(hcryp, CRYP_TIMEOUT_GCMCCMHEADERPHASE); + + /* Set the phase */ + hcryp->Phase = CRYP_PHASE_PROCESS; + + if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_WORD) + { + headersize_in_bytes = hcryp->Init.HeaderSize * 4U; + } + else + { + headersize_in_bytes = hcryp->Init.HeaderSize; + } + + if ((headersize_in_bytes % 16U) != 0U) + { + /* Write last words that couldn't be fed by DMA */ + hcryp->CrypHeaderCount = (uint16_t)((headersize_in_bytes / 16U) * 4U); + for (loopcounter = 0U; (loopcounter < ((headersize_in_bytes / 4U) % 4U)); loopcounter++) + { + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++ ; + } + /* If the header size is a multiple of words */ + if ((headersize_in_bytes % 4U) == 0U) + { + /* Pad the data with zeros to have a complete block */ + while (loopcounter < 4U) + { + hcryp->Instance->DINR = 0x0U; + loopcounter++; + } + } + else + { + /* Enter last bytes, padded with zeros */ + tmp = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + tmp &= mask[(hcryp->Init.DataType * 2U) + (headersize_in_bytes % 4U)]; + hcryp->Instance->DINR = tmp; + loopcounter++; + /* Pad the data with zeros to have a complete block */ + while (loopcounter < 4U) + { + hcryp->Instance->DINR = 0x0U; + loopcounter++; + } + } + + /* Wait for computation completion before moving forward */ + CRYP_ClearCCFlagWhenHigh(hcryp, CRYP_TIMEOUT_GCMCCMHEADERPHASE); + } /* if ((headersize_in_bytes % 16U) != 0U) */ + + /* Set to 0 the number of non-valid bytes using NPBLB register*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U); + + /* Select payload phase once the header phase is performed */ + CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); + + /* Initiate payload DMA IN and processed data DMA OUT transfers */ + (void)CRYP_GCMCCM_SetPayloadPhase_DMA(hcryp); + } + else + { + + /* ECB, CBC or CTR end of input data feeding or + end of GCM/CCM payload data feeding through DMA */ + algo = hcryp->Instance->CR & AES_CR_CHMOD; + + /* Don't call input data transfer complete callback only if + it remains some input data to write to the peripheral. + This case can only occur for GCM and CCM with a payload length + not a multiple of 16 bytes */ + if (!(((algo == CRYP_AES_GCM_GMAC) || (algo == CRYP_AES_CCM)) && \ + (((hcryp->Size) % 16U) != 0U))) + { + /* Call input data transfer complete callback */ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + /*Call registered Input complete callback*/ + hcryp->InCpltCallback(hcryp); +#else + /*Call legacy weak Input complete callback*/ + HAL_CRYP_InCpltCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + } + } /* if (hcryp->Phase == CRYP_PHASE_HEADER_DMA_FEED) */ +} + +/** + * @brief DMA CRYP output data process complete callback. + * @param hdma DMA handle + * @retval None + */ +static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma) +{ + uint32_t count; + uint32_t npblb; + uint32_t lastwordsize; + uint32_t temp[4]; /* Temporary CrypOutBuff */ + uint32_t mode; + + CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Disable the DMA transfer for output FIFO request by resetting + the DMAOUTEN bit in the CR register */ + + CLEAR_BIT(hcryp->Instance->CR, AES_CR_DMAOUTEN); + + /* Clear CCF flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + + /* Last block transfer in case of GCM or CCM with Size not %16*/ + if (((hcryp->Size) % 16U) != 0U) + { + /* set CrypInCount and CrypOutCount to exact number of word already computed via DMA */ + hcryp->CrypInCount = (hcryp->Size / 16U) * 4U; + hcryp->CrypOutCount = hcryp->CrypInCount; + + /* Compute the number of padding bytes in last block of payload */ + npblb = ((((uint32_t)hcryp->Size / 16U) + 1U) * 16U) - ((uint32_t)hcryp->Size); + + mode = hcryp->Instance->CR & AES_CR_MODE; + if (((mode == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC)) || + ((mode == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM))) + { + /* Specify the number of non-valid bytes using NPBLB register*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U); + } + + /* Number of valid words (lastwordsize) in last block */ + if ((npblb % 4U) == 0U) + { + lastwordsize = (16U - npblb) / 4U; + } + else + { + lastwordsize = ((16U - npblb) / 4U) + 1U; + } + + /* Last block optionally pad the data with zeros*/ + for (count = 0U; count < lastwordsize; count++) + { + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + } + while (count < 4U) + { + /* Pad the data with zeros to have a complete block */ + hcryp->Instance->DINR = 0x0U; + count++; + } + /* Call input data transfer complete callback */ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + /*Call registered Input complete callback*/ + hcryp->InCpltCallback(hcryp); +#else + /*Call legacy weak Input complete callback*/ + HAL_CRYP_InCpltCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + + /*Wait on CCF flag*/ + CRYP_ClearCCFlagWhenHigh(hcryp, CRYP_TIMEOUT_GCMCCMHEADERPHASE); + + /*Read the output block from the output FIFO */ + for (count = 0U; count < 4U; count++) + { + /* Read the output block from the output FIFO and put them in temporary buffer + then get CrypOutBuff from temporary buffer */ + temp[count] = hcryp->Instance->DOUTR; + } + + count = 0U; + while ((hcryp->CrypOutCount < ((hcryp->Size + 3U) / 4U)) && (count < 4U)) + { + *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[count]; + hcryp->CrypOutCount++; + count++; + } + } + + if (((hcryp->Init.Algorithm & CRYP_AES_GCM_GMAC) != CRYP_AES_GCM_GMAC) + && ((hcryp->Init.Algorithm & CRYP_AES_CCM) != CRYP_AES_CCM)) + { + /* Disable CRYP (not allowed in GCM)*/ + __HAL_CRYP_DISABLE(hcryp); + } + + /* Change the CRYP state to ready */ + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + + /* Call output data transfer complete callback */ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + /*Call registered Output complete callback*/ + hcryp->OutCpltCallback(hcryp); +#else + /*Call legacy weak Output complete callback*/ + HAL_CRYP_OutCpltCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA CRYP communication error callback. + * @param hdma DMA handle + * @retval None + */ +static void CRYP_DMAError(DMA_HandleTypeDef *hdma) +{ + CRYP_HandleTypeDef *hcryp = (CRYP_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_READY; + + /* DMA error code field */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA; + + /* Clear CCF flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + + /* Call error callback */ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + /*Call registered error callback*/ + hcryp->ErrorCallback(hcryp); +#else + /*Call legacy weak error callback*/ + HAL_CRYP_ErrorCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ +} + +/** + * @brief Set the DMA configuration and start the DMA transfer + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param inputaddr address of the input buffer + * @param Size size of the input and output buffers in words, must be a multiple of 4. + * @param outputaddr address of the output buffer + * @retval None + */ +static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr) +{ + HAL_StatusTypeDef status; + + /* Set the CRYP DMA transfer complete callback */ + hcryp->hdmain->XferCpltCallback = CRYP_DMAInCplt; + + /* Set the DMA input error callback */ + hcryp->hdmain->XferErrorCallback = CRYP_DMAError; + + /* Set the CRYP DMA transfer complete callback */ + hcryp->hdmaout->XferCpltCallback = CRYP_DMAOutCplt; + + /* Set the DMA output error callback */ + hcryp->hdmaout->XferErrorCallback = CRYP_DMAError; + + if ((hcryp->Init.Algorithm & CRYP_AES_GCM_GMAC) != CRYP_AES_GCM_GMAC) + { + /* Enable CRYP (not allowed in GCM & CCM)*/ + __HAL_CRYP_ENABLE(hcryp); + } + + /* Enable the DMA input channel */ + if ((hcryp->hdmain->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hcryp->hdmain->LinkedListQueue != NULL) && (hcryp->hdmain->LinkedListQueue->Head != NULL)) + { + /* Enable the DMA channel */ + hcryp->hdmain->LinkedListQueue->Head->\ + LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = Size; /* Set DMA data size */ + hcryp->hdmain->LinkedListQueue->Head->\ + LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = inputaddr; /* Set DMA source address */ + hcryp->hdmain->LinkedListQueue->Head->\ + LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)&hcryp->Instance->DINR; /* Set DMA destination address */ + + status = HAL_DMAEx_List_Start_IT(hcryp->hdmain); + } + else + { + /* Return error status */ + status = HAL_ERROR; + } + } + else + { + status = HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, Size); + } + + if (status != HAL_OK) + { + /* DMA error code field */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA; + + /*Call registered error callback*/ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + hcryp->ErrorCallback(hcryp); +#else + /*Call legacy weak error callback*/ + HAL_CRYP_ErrorCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + } + /* Enable the DMA output channel */ + if ((hcryp->hdmaout->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hcryp->hdmaout->LinkedListQueue != NULL) && (hcryp->hdmaout->LinkedListQueue->Head != NULL)) + { + /* Enable the DMA channel */ + hcryp->hdmaout->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = \ + Size; /* Set DMA data size */ + hcryp->hdmaout->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = \ + (uint32_t)&hcryp->Instance->DOUTR; /* Set DMA source address */ + hcryp->hdmaout->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = \ + outputaddr; /* Set DMA destination address */ + + status = HAL_DMAEx_List_Start_IT(hcryp->hdmaout); + } + else + { + /* Return error status */ + status = HAL_ERROR; + } + } + else + { + status = HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUTR, outputaddr, Size); + } + + if (status != HAL_OK) + { + /* DMA error code field */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA; + + /* Call error callback */ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + /*Call registered error callback*/ + hcryp->ErrorCallback(hcryp); +#else + /*Call legacy weak error callback*/ + HAL_CRYP_ErrorCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + } + /* Enable In and Out DMA requests */ + SET_BIT(hcryp->Instance->CR, (AES_CR_DMAINEN | AES_CR_DMAOUTEN)); +} + +/** + * @brief Set the DMA configuration and start the header DMA transfer + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param inputaddr address of the input buffer + * @param Size size of the input buffer in words, must be a multiple of 4 + * @retval None + */ +static HAL_StatusTypeDef CRYP_SetHeaderDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size) +{ + HAL_StatusTypeDef status; + + /* Set the CRYP DMA transfer complete callback */ + hcryp->hdmain->XferCpltCallback = CRYP_DMAInCplt; + + /* Set the DMA input error callback */ + hcryp->hdmain->XferErrorCallback = CRYP_DMAError; + + /* Mark that header is fed to the peripheral in DMA mode */ + hcryp->Phase = CRYP_PHASE_HEADER_DMA_FEED; + + /* Enable the DMA input channel */ + if ((hcryp->hdmain->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hcryp->hdmain->LinkedListQueue != NULL) && (hcryp->hdmain->LinkedListQueue->Head != NULL)) + { + /* Enable the DMA channel */ + hcryp->hdmain->LinkedListQueue->Head->\ + LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = Size; /* Set DMA data size */ + hcryp->hdmain->LinkedListQueue->Head->\ + LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = inputaddr; /* Set DMA source address */ + hcryp->hdmain->LinkedListQueue->Head->\ + LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)&hcryp->Instance->DINR; /* Set DMA destination address */ + + status = HAL_DMAEx_List_Start_IT(hcryp->hdmain); + } + else + { + /* Return error status */ + status = HAL_ERROR; + } + } + else + { + status = HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DINR, Size); + } + if (status != HAL_OK) + { + /* DMA error code field */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_DMA; + + /* Call error callback */ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + /*Call registered error callback*/ + hcryp->ErrorCallback(hcryp); +#else + /*Call legacy weak error callback*/ + HAL_CRYP_ErrorCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + } + + /* Enable IN DMA requests */ + SET_BIT(hcryp->Instance->CR, AES_CR_DMAINEN); + + return status; +} + +/** + * @brief Process Data: Write Input data in polling mode and used in AES functions. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param Timeout Specify Timeout value + * @retval None + */ +static void CRYP_AES_ProcessData(CRYP_HandleTypeDef *hcryp, uint32_t Timeout) +{ + + uint32_t temp[4]; /* Temporary CrypOutBuff */ + uint32_t i; + + /* Write the input block in the IN FIFO */ + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + + /* Wait for CCF flag to be raised */ + if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK) + { + /*Call registered error callback*/ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + hcryp->ErrorCallback(hcryp); +#else + /*Call legacy weak error callback*/ + HAL_CRYP_ErrorCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + } + + /* Clear CCF Flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + + /* Read the output block from the output FIFO and put them in temporary buffer then + get CrypOutBuff from temporary buffer*/ + for (i = 0U; i < 4U; i++) + { + temp[i] = hcryp->Instance->DOUTR; + } + i = 0U; + while ((hcryp->CrypOutCount < ((hcryp->Size + 3U) / 4U)) && (i < 4U)) + { + *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i]; + hcryp->CrypOutCount++; + i++; + } +} + +/** + * @brief Handle CRYP block input/output data handling under interruption. + * @note The function is called under interruption only, once + * interruptions have been enabled by HAL_CRYP_Encrypt_IT or HAL_CRYP_Decrypt_IT. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module. + * @retval HAL status + */ +static void CRYP_AES_IT(CRYP_HandleTypeDef *hcryp) +{ + uint32_t temp[4]; /* Temporary CrypOutBuff */ + uint32_t i; + + if (hcryp->State == HAL_CRYP_STATE_BUSY) + { + /* Read the output block from the output FIFO and put them in temporary buffer then + get CrypOutBuff from temporary buffer*/ + for (i = 0U; i < 4U; i++) + { + temp[i] = hcryp->Instance->DOUTR; + } + i = 0U; + while ((hcryp->CrypOutCount < ((hcryp->Size + 3U) / 4U)) && (i < 4U)) + { + *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i]; + hcryp->CrypOutCount++; + i++; + } + if (hcryp->CrypOutCount == (hcryp->Size / 4U)) + { + /* Disable Computation Complete flag and errors interrupts */ + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE); + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + + /* Disable CRYP */ + __HAL_CRYP_DISABLE(hcryp); + __HAL_UNLOCK(hcryp); + + /* Call Output transfer complete callback */ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + /*Call registered Output complete callback*/ + hcryp->OutCpltCallback(hcryp); +#else + /*Call legacy weak Output complete callback*/ + HAL_CRYP_OutCpltCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + } + else + { +#if (USE_HAL_CRYP_SUSPEND_RESUME == 1U) + /* If suspension flag has been raised, suspend processing + only if not already at the end of the payload */ + if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND) + { + /* Clear CCF Flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + + /* reset SuspendRequest */ + hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE; + /* Disable Computation Complete Flag and Errors Interrupts */ + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE); + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_SUSPENDED; + /* Mark that the payload phase is suspended */ + hcryp->Phase = CRYP_PHASE_PAYLOAD_SUSPENDED; + __HAL_UNLOCK(hcryp); + } + else +#endif /* USE_HAL_CRYP_SUSPEND_RESUME */ + { + /* Write the input block in the IN FIFO */ + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + + if (hcryp->CrypInCount == (hcryp->Size / 4U)) + { + /* Call Input transfer complete callback */ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + /*Call registered Input complete callback*/ + hcryp->InCpltCallback(hcryp); +#else + /*Call legacy weak Input complete callback*/ + HAL_CRYP_InCpltCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + } + } + } + } + else + { + /* Busy error code field */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + /*Call registered error callback*/ + hcryp->ErrorCallback(hcryp); +#else + /*Call legacy weak error callback*/ + HAL_CRYP_ErrorCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + } +} + +/** + * @brief Writes Key in Key registers. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param KeySize Size of Key + * @note If pKey is NULL, the Key registers are not written. + * @retval None + */ +static void CRYP_SetKey(CRYP_HandleTypeDef *hcryp, uint32_t KeySize) +{ + if (hcryp->Init.pKey != NULL) + { + switch (KeySize) + { + case CRYP_KEYSIZE_256B: + hcryp->Instance->KEYR7 = *(uint32_t *)(hcryp->Init.pKey); + hcryp->Instance->KEYR6 = *(uint32_t *)(hcryp->Init.pKey + 1U); + hcryp->Instance->KEYR5 = *(uint32_t *)(hcryp->Init.pKey + 2U); + hcryp->Instance->KEYR4 = *(uint32_t *)(hcryp->Init.pKey + 3U); + hcryp->Instance->KEYR3 = *(uint32_t *)(hcryp->Init.pKey + 4U); + hcryp->Instance->KEYR2 = *(uint32_t *)(hcryp->Init.pKey + 5U); + hcryp->Instance->KEYR1 = *(uint32_t *)(hcryp->Init.pKey + 6U); + hcryp->Instance->KEYR0 = *(uint32_t *)(hcryp->Init.pKey + 7U); + break; + case CRYP_KEYSIZE_128B: + hcryp->Instance->KEYR3 = *(uint32_t *)(hcryp->Init.pKey); + hcryp->Instance->KEYR2 = *(uint32_t *)(hcryp->Init.pKey + 1U); + hcryp->Instance->KEYR1 = *(uint32_t *)(hcryp->Init.pKey + 2U); + hcryp->Instance->KEYR0 = *(uint32_t *)(hcryp->Init.pKey + 3U); + break; + default: + break; + } + } +} + +/** + * @brief Writes initialization vector in IV registers. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @note If IV is NULL, the IV registers are not written. + * @retval None + */ +static void CRYP_SetIV(CRYP_HandleTypeDef *hcryp) +{ + if (hcryp->Init.pInitVect != NULL) + { + /* Set the Initialization Vector*/ + hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect); + hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U); + hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U); + hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U); + } +} + +/** + * @brief Encryption/Decryption process in AES GCM mode and prepare the authentication TAG + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param Timeout Timeout duration + * @retval HAL status + */ +static HAL_StatusTypeDef CRYP_AESGCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout) +{ + uint32_t tickstart; + uint32_t wordsize = ((uint32_t)hcryp->Size / 4U); + uint32_t npblb; + uint32_t temp[4]; /* Temporary CrypOutBuff */ + uint32_t index; + uint32_t lastwordsize; + uint32_t incount; /* Temporary CrypInCount Value */ + uint32_t outcount; /* Temporary CrypOutCount Value */ + uint32_t dokeyivconfig = 1U; /* By default, carry out peripheral Key and IV configuration */ + + if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) + { + if (hcryp->KeyIVConfig == 1U) + { + /* If the Key and IV configuration has to be done only once + and if it has already been done, skip it */ + dokeyivconfig = 0U; + hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */ + } + else + { + /* If the Key and IV configuration has to be done only once + and if it has not been done already, do it and set KeyIVConfig + to keep track it won't have to be done again next time */ + hcryp->KeyIVConfig = 1U; + hcryp->SizesSum = hcryp->Size; /* Merely store payload length */ + } + } + else + { + hcryp->SizesSum = hcryp->Size; + } + + if (dokeyivconfig == 1U) + { + + /* Reset CrypHeaderCount */ + hcryp->CrypHeaderCount = 0U; + + /****************************** Init phase **********************************/ + + CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT); + /* Set the Key */ + if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG) + { + if (hcryp->Instance == AES) + { + if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED) + { + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + else /*after sharing the key, AES should set KMOD[1:0] to 00.*/ + { + hcryp->Instance->CR &= ~CRYP_KEYMODE_SHARED; + } + } + else /*SAES*/ + { + /* We should re-write Key, in the case where we change key after first operation */ + if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL)) + { + /* Set the Key */ + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + /* Get tick */ + tickstart = HAL_GetTick(); + + while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_KEYVALID)) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change state */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } + } + } + } + /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/ + CRYP_SetIV(hcryp); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + /* just wait for hash computation */ + if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK) + { + return HAL_ERROR; + } + /* Clear CCF flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + + /************************ Header phase *************************************/ + + if (CRYP_GCMCCM_SetHeaderPhase(hcryp, Timeout) != HAL_OK) + { + return HAL_ERROR; + } + + /*************************Payload phase ************************************/ + + /* Set the phase */ + hcryp->Phase = CRYP_PHASE_PROCESS; + + /* Select payload phase once the header phase is performed */ + CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); + + /* Set to 0 the number of non-valid bytes using NPBLB register*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U); + + } /* if (dokeyivconfig == 1U) */ + + if ((hcryp->Size % 16U) != 0U) + { + /* recalculate wordsize */ + wordsize = ((wordsize / 4U) * 4U); + } + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Write input data and get output Data */ + incount = hcryp->CrypInCount; + outcount = hcryp->CrypOutCount; + while ((incount < wordsize) && (outcount < wordsize)) + { + /* Write plain data and get cipher data */ + CRYP_AES_ProcessData(hcryp, Timeout); + + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change state & error code */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } + incount = hcryp->CrypInCount; + outcount = hcryp->CrypOutCount; + } + + if ((hcryp->Size % 16U) != 0U) + { + /* Compute the number of padding bytes in last block of payload */ + npblb = ((((uint32_t)hcryp->Size / 16U) + 1U) * 16U) - ((uint32_t)hcryp->Size); + + /* Set Npblb in case of AES GCM payload encryption to get right tag*/ + if ((hcryp->Instance->CR & AES_CR_MODE) == CRYP_OPERATINGMODE_ENCRYPT) + { + /* Set to 0 the number of non-valid bytes using NPBLB register*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U); + } + /* Number of valid words (lastwordsize) in last block */ + if ((npblb % 4U) == 0U) + { + lastwordsize = (16U - npblb) / 4U; + } + else + { + lastwordsize = ((16U - npblb) / 4U) + 1U; + } + /* last block optionally pad the data with zeros*/ + for (index = 0U; index < lastwordsize; index ++) + { + /* Write the last Input block in the IN FIFO */ + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + } + while (index < 4U) + { + /* pad the data with zeros to have a complete block */ + hcryp->Instance->DINR = 0U; + index++; + } + /* Wait for CCF flag to be raised */ + if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK) + { +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + /*Call registered error callback*/ + hcryp->ErrorCallback(hcryp); +#else + /*Call legacy weak error callback*/ + HAL_CRYP_ErrorCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + } + + /* Clear CCF Flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + + /*Read the output block from the output FIFO */ + for (index = 0U; index < 4U; index++) + { + /* Read the output block from the output FIFO and put them in temporary buffer then + get CrypOutBuff from temporary buffer */ + temp[index] = hcryp->Instance->DOUTR; + } + for (index = 0U; index < lastwordsize; index++) + { + *(uint32_t *)(hcryp->pCrypOutBuffPtr + (hcryp->CrypOutCount)) = temp[index]; + hcryp->CrypOutCount++; + } + } + + return HAL_OK; +} + +/** + * @brief Encryption/Decryption process in AES GCM mode and prepare the authentication TAG in interrupt mode + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @retval HAL status + */ +static HAL_StatusTypeDef CRYP_AESGCM_Process_IT(CRYP_HandleTypeDef *hcryp) +{ + uint32_t count; + uint32_t loopcounter; + uint32_t lastwordsize; + uint32_t npblb; + uint32_t dokeyivconfig = 1U; /* By default, carry out peripheral Key and IV configuration */ + uint32_t headersize_in_bytes; + uint32_t tmp; + const uint32_t mask[12] = {0x0U, 0xFF000000U, 0xFFFF0000U, 0xFFFFFF00U, /* 32-bit data type */ + 0x0U, 0x0000FF00U, 0x0000FFFFU, 0xFF00FFFFU, /* 16-bit data type */ + 0x0U, 0x000000FFU, 0x0000FFFFU, 0x00FFFFFFU + }; /* 8-bit data type */ + +#if (USE_HAL_CRYP_SUSPEND_RESUME == 1U) + if ((hcryp->Phase == CRYP_PHASE_HEADER_SUSPENDED) || (hcryp->Phase == CRYP_PHASE_PAYLOAD_SUSPENDED)) + { + CRYP_PhaseProcessingResume(hcryp); + return HAL_OK; + } +#endif /* USE_HAL_CRYP_SUSPEND_RESUME */ + + /* Manage header size given in bytes to handle cases where + header size is not a multiple of 4 bytes */ + if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_WORD) + { + headersize_in_bytes = hcryp->Init.HeaderSize * 4U; + } + else + { + headersize_in_bytes = hcryp->Init.HeaderSize; + } + + if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) + { + if (hcryp->KeyIVConfig == 1U) + { + /* If the Key and IV configuration has to be done only once + and if it has already been done, skip it */ + dokeyivconfig = 0U; + hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */ + } + else + { + /* If the Key and IV configuration has to be done only once + and if it has not been done already, do it and set KeyIVConfig + to keep track it won't have to be done again next time */ + hcryp->KeyIVConfig = 1U; + hcryp->SizesSum = hcryp->Size; /* Merely store payload length */ + } + } + else + { + hcryp->SizesSum = hcryp->Size; + } + + /* Configure Key, IV and process message (header and payload) */ + if (dokeyivconfig == 1U) + { + /* Reset CrypHeaderCount */ + hcryp->CrypHeaderCount = 0U; + + /******************************* Init phase *********************************/ + + CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT); + /* Set the Key */ + if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG) + { + if (hcryp->Instance == AES) + { + if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED) + { + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + else /*after sharing the key, AES should set KMOD[1:0] to 00.*/ + { + hcryp->Instance->CR &= ~CRYP_KEYMODE_SHARED; + } + } + else /*SAES*/ + { + /* We should re-write Key, in the case where we change key after first operation */ + if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL)) + { + /* Set the Key */ + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + /* Wait for KEYVALID flag to be set */ + count = CRYP_TIMEOUT_KEYPREPARATION; + do + { + count--; + if (count == 0U) + { + /* Disable the SAES peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change state */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_KEYVALID)); + } + } + /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/ + CRYP_SetIV(hcryp); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + /* just wait for hash computation */ + count = CRYP_TIMEOUT_GCMCCMINITPHASE; + do + { + count--; + if (count == 0U) + { + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change state */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF)); + + /* Clear CCF flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + + /***************************** Header phase *********************************/ + + /* Select header phase */ + CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER); + + /* Enable computation complete flag and error interrupts */ + __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + if (hcryp->Init.HeaderSize == 0U) /*header phase is skipped*/ + { + /* Set the phase */ + hcryp->Phase = CRYP_PHASE_PROCESS; + + /* Select payload phase once the header phase is performed */ + MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_PAYLOAD); + + /* Set to 0 the number of non-valid bytes using NPBLB register*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U); + + /* Write the payload Input block in the IN FIFO */ + if (hcryp->Size == 0U) + { + /* Disable interrupts */ + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE); + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + } + else if (hcryp->Size >= 16U) + { + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + if ((hcryp->CrypInCount == (hcryp->Size / 4U)) && ((hcryp->Size % 16U) == 0U)) + { + /* Call Input transfer complete callback */ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + /*Call registered Input complete callback*/ + hcryp->InCpltCallback(hcryp); +#else + /*Call legacy weak Input complete callback*/ + HAL_CRYP_InCpltCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + } + } + else /* Size < 16Bytes : first block is the last block*/ + { + /* Size should be %4 otherwise Tag will be incorrectly generated for GCM Encryption: + Workaround is implemented in polling mode, so if last block of + payload <128bit do not use CRYP_Encrypt_IT otherwise TAG is incorrectly generated for GCM Encryption. */ + + + /* Compute the number of padding bytes in last block of payload */ + npblb = 16U - ((uint32_t)hcryp->Size); + + if ((hcryp->Instance->CR & AES_CR_MODE) == CRYP_OPERATINGMODE_ENCRYPT) + { + /* Set to 0 the number of non-valid bytes using NPBLB register*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U); + } + + /* Number of valid words (lastwordsize) in last block */ + if ((npblb % 4U) == 0U) + { + lastwordsize = (16U - npblb) / 4U; + } + else + { + lastwordsize = ((16U - npblb) / 4U) + 1U; + } + + /* last block optionally pad the data with zeros*/ + for (loopcounter = 0U; loopcounter < lastwordsize ; loopcounter++) + { + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + } + while (loopcounter < 4U) + { + /* pad the data with zeros to have a complete block */ + hcryp->Instance->DINR = 0x0U; + loopcounter++; + } + /* Call Input transfer complete callback */ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + /*Call registered Input complete callback*/ + hcryp->InCpltCallback(hcryp); +#else + /*Call legacy weak Input complete callback*/ + HAL_CRYP_InCpltCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + } + } + /* Enter header data */ + /* Cher first whether header length is small enough to enter the full header in one shot */ + else if (headersize_in_bytes <= 16U) + { + /* Write header data, padded with zeros if need be */ + for (loopcounter = 0U; (loopcounter < (headersize_in_bytes / 4U)); loopcounter++) + { + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++ ; + } + /* If the header size is a multiple of words */ + if ((headersize_in_bytes % 4U) == 0U) + { + /* Pad the data with zeros to have a complete block */ + while (loopcounter < 4U) + { + hcryp->Instance->DINR = 0x0U; + loopcounter++; + hcryp->CrypHeaderCount++; + } + } + else + { + /* Enter last bytes, padded with zeros */ + tmp = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + tmp &= mask[(hcryp->Init.DataType * 2U) + (headersize_in_bytes % 4U)]; + hcryp->Instance->DINR = tmp; + loopcounter++; + hcryp->CrypHeaderCount++ ; + /* Pad the data with zeros to have a complete block */ + while (loopcounter < 4U) + { + hcryp->Instance->DINR = 0x0U; + loopcounter++; + hcryp->CrypHeaderCount++; + } + } + /* Call Input transfer complete callback */ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + /*Call registered Input complete callback*/ + hcryp->InCpltCallback(hcryp); +#else + /*Call legacy weak Input complete callback*/ + HAL_CRYP_InCpltCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + } + else + { + /* Write the first input header block in the Input FIFO, + the following header data will be fed after interrupt occurrence */ + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++; + } + + } /* end of if (dokeyivconfig == 1U) */ + else /* Key and IV have already been configured, + header has already been processed; + only process here message payload */ + { + + /* Enable computation complete flag and error interrupts */ + __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE); + + /* Set to 0 the number of non-valid bytes using NPBLB register*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U); + + /* Write the payload Input block in the IN FIFO */ + if (hcryp->Size == 0U) + { + /* Disable interrupts */ + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE); + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + } + else if (hcryp->Size >= 16U) + { + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + if ((hcryp->CrypInCount == (hcryp->Size / 4U)) && ((hcryp->Size % 16U) == 0U)) + { + /* Call Input transfer complete callback */ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + /*Call registered Input complete callback*/ + hcryp->InCpltCallback(hcryp); +#else + /*Call legacy weak Input complete callback*/ + HAL_CRYP_InCpltCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + } + } + else /* Size < 16Bytes : first block is the last block*/ + { + /* Size should be %4 otherwise Tag will be incorrectly generated for GCM Encryption: + Workaround is implemented in polling mode, so if last block of + payload <128bit do not use CRYP_Encrypt_IT otherwise TAG is incorrectly generated for GCM Encryption. */ + + + /* Compute the number of padding bytes in last block of payload */ + npblb = 16U - ((uint32_t)hcryp->Size); + + if ((hcryp->Instance->CR & AES_CR_MODE) == CRYP_OPERATINGMODE_ENCRYPT) + { + /* Set to 0 the number of non-valid bytes using NPBLB register*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U); + } + + /* Number of valid words (lastwordsize) in last block */ + if ((npblb % 4U) == 0U) + { + lastwordsize = (16U - npblb) / 4U; + } + else + { + lastwordsize = ((16U - npblb) / 4U) + 1U; + } + + /* last block optionally pad the data with zeros*/ + for (loopcounter = 0U; loopcounter < lastwordsize ; loopcounter++) + { + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + } + while (loopcounter < 4U) + { + /* pad the data with zeros to have a complete block */ + hcryp->Instance->DINR = 0x0U; + loopcounter++; + } + /* Call Input transfer complete callback */ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + /*Call registered Input complete callback*/ + hcryp->InCpltCallback(hcryp); +#else + /*Call legacy weak Input complete callback*/ + HAL_CRYP_InCpltCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + } + } + + return HAL_OK; +} + + +/** + * @brief Encryption/Decryption process in AES GCM mode and prepare the authentication TAG using DMA + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @retval HAL status + */ +static HAL_StatusTypeDef CRYP_AESGCM_Process_DMA(CRYP_HandleTypeDef *hcryp) +{ + uint32_t count; + uint32_t dokeyivconfig = 1U; /* By default, carry out peripheral Key and IV configuration */ + + if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) + { + if (hcryp->KeyIVConfig == 1U) + { + /* If the Key and IV configuration has to be done only once + and if it has already been done, skip it */ + dokeyivconfig = 0U; + hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */ + } + else + { + /* If the Key and IV configuration has to be done only once + and if it has not been done already, do it and set KeyIVConfig + to keep track it won't have to be done again next time */ + hcryp->KeyIVConfig = 1U; + hcryp->SizesSum = hcryp->Size; /* Merely store payload length */ + } + } + else + { + hcryp->SizesSum = hcryp->Size; + } + + if (dokeyivconfig == 1U) + { + + /* Reset CrypHeaderCount */ + hcryp->CrypHeaderCount = 0U; + + /*************************** Init phase ************************************/ + + CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT); + /* Set the Key */ + if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG) + { + if (hcryp->Instance == AES) + { + if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED) + { + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + else /*after sharing the key, AES should set KMOD[1:0] to 00.*/ + { + hcryp->Instance->CR &= ~CRYP_KEYMODE_SHARED; + } + } + else /*SAES*/ + { + /* We should re-write Key, in the case where we change key after first operation */ + if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL)) + { + /* Set the Key */ + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + /* Wait for KEYVALID flag to be set */ + count = CRYP_TIMEOUT_KEYPREPARATION; + do + { + count--; + if (count == 0U) + { + /* Disable the SAES peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change state */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_KEYVALID)); + } + } + /* Set the initialization vector and the counter : Initial Counter Block (ICB)*/ + CRYP_SetIV(hcryp); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + /* just wait for hash computation */ + count = CRYP_TIMEOUT_GCMCCMINITPHASE; + do + { + count--; + if (count == 0U) + { + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change state */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF)); + + /* Clear CCF flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + + /************************ Header phase *************************************/ + + if (CRYP_GCMCCM_SetHeaderPhase_DMA(hcryp) != HAL_OK) + { + return HAL_ERROR; + } + + } + else + { + /* Initialization and header phases already done, only do payload phase */ + if (CRYP_GCMCCM_SetPayloadPhase_DMA(hcryp) != HAL_OK) + { + return HAL_ERROR; + } + } /* if (DoKeyIVConfig == 1U) */ + + return HAL_OK; +} + + +/** + * @brief AES CCM encryption/decryption processing in polling mode + * encrypt/decrypt are performed with authentication preparation. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param Timeout Timeout duration + * @retval HAL status + */ +static HAL_StatusTypeDef CRYP_AESCCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t Timeout) +{ + uint32_t tickstart; + uint32_t wordsize = ((uint32_t)hcryp->Size / 4U); + uint32_t loopcounter; + uint32_t npblb; + uint32_t lastwordsize; + uint32_t temp[4]; /* Temporary CrypOutBuff */ + uint32_t incount; /* Temporary CrypInCount Value */ + uint32_t outcount; /* Temporary CrypOutCount Value */ + uint32_t dokeyivconfig = 1U; /* By default, carry out peripheral Key and IV configuration */ + + if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) + { + if (hcryp->KeyIVConfig == 1U) + { + /* If the Key and IV configuration has to be done only once + and if it has already been done, skip it */ + dokeyivconfig = 0U; + hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */ + } + else + { + /* If the Key and IV configuration has to be done only once + and if it has not been done already, do it and set KeyIVConfig + to keep track it won't have to be done again next time */ + hcryp->KeyIVConfig = 1U; + hcryp->SizesSum = hcryp->Size; /* Merely store payload length */ + } + } + else + { + hcryp->SizesSum = hcryp->Size; + } + + if (dokeyivconfig == 1U) + { + /* Reset CrypHeaderCount */ + hcryp->CrypHeaderCount = 0U; + + /********************** Init phase ******************************************/ + + CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT); + /* Set the Key */ + if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG) + { + if (hcryp->Instance == AES) + { + if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED) + { + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + else /*after sharing the key, AES should set KMOD[1:0] to 00.*/ + { + hcryp->Instance->CR &= ~CRYP_KEYMODE_SHARED; + } + } + else /*SAES*/ + { + /* We should re-write Key, in the case where we change key after first operation */ + if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL)) + { + /* Set the Key */ + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + /* Get tick */ + tickstart = HAL_GetTick(); + + while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_KEYVALID)) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change state */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } + } + } + } + /* Set the initialization vector (IV) with B0 */ + hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.B0); + hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.B0 + 1U); + hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.B0 + 2U); + hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.B0 + 3U); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + /* just wait for hash computation */ + if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK) + { + return HAL_ERROR; + } + /* Clear CCF flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + + /************************ Header phase *************************************/ + /* Header block(B1) : associated data length expressed in bytes concatenated + with Associated Data (A)*/ + if (CRYP_GCMCCM_SetHeaderPhase(hcryp, Timeout) != HAL_OK) + { + return HAL_ERROR; + } + + /*************************Payload phase ************************************/ + + /* Set the phase */ + hcryp->Phase = CRYP_PHASE_PROCESS; + + /* Select payload phase once the header phase is performed */ + MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_PAYLOAD); + + /* Set to 0 the number of non-valid bytes using NPBLB register*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U); + + } /* if (dokeyivconfig == 1U) */ + + if ((hcryp->Size % 16U) != 0U) + { + /* recalculate wordsize */ + wordsize = ((wordsize / 4U) * 4U); + } + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Write input data and get output data */ + incount = hcryp->CrypInCount; + outcount = hcryp->CrypOutCount; + while ((incount < wordsize) && (outcount < wordsize)) + { + /* Write plain data and get cipher data */ + CRYP_AES_ProcessData(hcryp, Timeout); + + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change state */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } + incount = hcryp->CrypInCount; + outcount = hcryp->CrypOutCount; + } + + if ((hcryp->Size % 16U) != 0U) + { + /* Compute the number of padding bytes in last block of payload */ + npblb = ((((uint32_t)hcryp->Size / 16U) + 1U) * 16U) - ((uint32_t)hcryp->Size); + + if ((hcryp->Instance->CR & AES_CR_MODE) == CRYP_OPERATINGMODE_DECRYPT) + { + /* Set Npblb in case of AES CCM payload decryption to get right tag */ + MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20); + + } + /* Number of valid words (lastwordsize) in last block */ + if ((npblb % 4U) == 0U) + { + lastwordsize = (16U - npblb) / 4U; + } + else + { + lastwordsize = ((16U - npblb) / 4U) + 1U; + } + + /* Write the last input block in the IN FIFO */ + for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter ++) + { + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + } + + /* Pad the data with zeros to have a complete block */ + while (loopcounter < 4U) + { + hcryp->Instance->DINR = 0U; + loopcounter++; + } + /* just wait for hash computation */ + if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK) + { + return HAL_ERROR; + } + /* Clear CCF flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + + for (loopcounter = 0U; loopcounter < 4U; loopcounter++) + { + /* Read the output block from the output FIFO and put them in temporary buffer then + get CrypOutBuff from temporary buffer */ + temp[loopcounter] = hcryp->Instance->DOUTR; + } + for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter++) + { + *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[loopcounter]; + hcryp->CrypOutCount++; + } + } + + return HAL_OK; +} + +/** + * @brief AES CCM encryption/decryption process in interrupt mode + * encrypt/decrypt are performed with authentication preparation. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @retval HAL status + */ +static HAL_StatusTypeDef CRYP_AESCCM_Process_IT(CRYP_HandleTypeDef *hcryp) +{ + uint32_t count; + uint32_t loopcounter; + uint32_t lastwordsize; + uint32_t npblb; + uint32_t mode; + uint32_t dokeyivconfig = 1U; /* By default, carry out peripheral Key and IV configuration */ + uint32_t headersize_in_bytes; + uint32_t tmp; + const uint32_t mask[12] = {0x0U, 0xFF000000U, 0xFFFF0000U, 0xFFFFFF00U, /* 32-bit data type */ + 0x0U, 0x0000FF00U, 0x0000FFFFU, 0xFF00FFFFU, /* 16-bit data type */ + 0x0U, 0x000000FFU, 0x0000FFFFU, 0x00FFFFFFU + }; /* 8-bit data type */ + +#if (USE_HAL_CRYP_SUSPEND_RESUME == 1U) + if ((hcryp->Phase == CRYP_PHASE_HEADER_SUSPENDED) || (hcryp->Phase == CRYP_PHASE_PAYLOAD_SUSPENDED)) + { + CRYP_PhaseProcessingResume(hcryp); + return HAL_OK; + } +#endif /* USE_HAL_CRYP_SUSPEND_RESUME */ + + if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) + { + if (hcryp->KeyIVConfig == 1U) + { + /* If the Key and IV configuration has to be done only once + and if it has already been done, skip it */ + dokeyivconfig = 0U; + hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */ + } + else + { + /* If the Key and IV configuration has to be done only once + and if it has not been done already, do it and set KeyIVConfig + to keep track it won't have to be done again next time */ + hcryp->KeyIVConfig = 1U; + hcryp->SizesSum = hcryp->Size; /* Merely store payload length */ + } + } + else + { + hcryp->SizesSum = hcryp->Size; + } + + /* Configure Key, IV and process message (header and payload) */ + if (dokeyivconfig == 1U) + { + /* Reset CrypHeaderCount */ + hcryp->CrypHeaderCount = 0U; + + /********************** Init phase ******************************************/ + + CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT); + /* Set the Key */ + if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG) + { + if (hcryp->Instance == AES) + { + if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED) + { + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + else /*after sharing the key, AES should set KMOD[1:0] to 00.*/ + { + hcryp->Instance->CR &= ~CRYP_KEYMODE_SHARED; + } + } + else /*SAES*/ + { + /* We should re-write Key, in the case where we change key after first operation */ + if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL)) + { + /* Set the Key */ + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + /* Wait for KEYVALID flag to be set */ + count = CRYP_TIMEOUT_KEYPREPARATION; + do + { + count--; + if (count == 0U) + { + /* Disable the SAES peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change state */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_KEYVALID)); + } + } + /* Set the initialization vector (IV) with B0 */ + hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.B0); + hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.B0 + 1U); + hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.B0 + 2U); + hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.B0 + 3U); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + /* just wait for hash computation */ + count = CRYP_TIMEOUT_GCMCCMINITPHASE; + do + { + count--; + if (count == 0U) + { + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change state */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF)); + + /* Clear CCF flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + + /***************************** Header phase *********************************/ + + /* Select header phase */ + CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER); + + /* Enable computation complete flag and error interrupts */ + __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_WORD) + { + headersize_in_bytes = hcryp->Init.HeaderSize * 4U; + } + else + { + headersize_in_bytes = hcryp->Init.HeaderSize; + } + + if (headersize_in_bytes == 0U) /* Header phase is skipped */ + { + /* Set the phase */ + hcryp->Phase = CRYP_PHASE_PROCESS; + /* Select payload phase once the header phase is performed */ + CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); + /* Set to 0 the number of non-valid bytes using NPBLB register*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U); + + if (hcryp->Init.Algorithm == CRYP_AES_CCM) + { + /* Increment CrypHeaderCount to pass in CRYP_GCMCCM_SetPayloadPhase_IT */ + hcryp->CrypHeaderCount++; + } + /* Write the payload Input block in the IN FIFO */ + if (hcryp->Size == 0U) + { + /* Disable interrupts */ + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE); + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + } + else if (hcryp->Size >= 16U) + { + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + + if ((hcryp->CrypInCount == (hcryp->Size / 4U)) && ((hcryp->Size % 16U) == 0U)) + { + /* Call Input transfer complete callback */ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + /*Call registered Input complete callback*/ + hcryp->InCpltCallback(hcryp); +#else + /*Call legacy weak Input complete callback*/ + HAL_CRYP_InCpltCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + } + } + else /* Size < 4 words : first block is the last block*/ + { + /* Compute the number of padding bytes in last block of payload */ + npblb = 16U - (uint32_t)hcryp->Size; + + mode = hcryp->Instance->CR & AES_CR_MODE; + if (((mode == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC)) || + ((mode == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM))) + { + /* Specify the number of non-valid bytes using NPBLB register*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U); + } + + /* Number of valid words (lastwordsize) in last block */ + if ((npblb % 4U) == 0U) + { + lastwordsize = (16U - npblb) / 4U; + } + else + { + lastwordsize = ((16U - npblb) / 4U) + 1U; + } + + /* Last block optionally pad the data with zeros*/ + for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter++) + { + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + } + while (loopcounter < 4U) + { + /* Pad the data with zeros to have a complete block */ + hcryp->Instance->DINR = 0x0U; + loopcounter++; + } + /* Call Input transfer complete callback */ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + /*Call registered Input complete callback*/ + hcryp->InCpltCallback(hcryp); +#else + /*Call legacy weak Input complete callback*/ + HAL_CRYP_InCpltCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + } + } + /* Enter header data */ + /* Check first whether header length is small enough to enter the full header in one shot */ + else if (headersize_in_bytes <= 16U) + { + /* Last block optionally pad the data with zeros*/ + for (loopcounter = 0U; (loopcounter < (headersize_in_bytes / 4U)); loopcounter++) + { + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++; + } + /* If the header size is a multiple of words */ + if ((headersize_in_bytes % 4U) == 0U) + { + /* Pad the data with zeros to have a complete block */ + while (loopcounter < 4U) + { + hcryp->Instance->DINR = 0x0U; + loopcounter++; + } + } + else + { + /* Enter last bytes, padded with zeros */ + tmp = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + tmp &= mask[(hcryp->Init.DataType * 2U) + (headersize_in_bytes % 4U)]; + hcryp->Instance->DINR = tmp; + hcryp->CrypHeaderCount++; + loopcounter++; + /* Pad the data with zeros to have a complete block */ + while (loopcounter < 4U) + { + /* pad the data with zeros to have a complete block */ + hcryp->Instance->DINR = 0x0U; + loopcounter++; + } + } + /* Call Input transfer complete callback */ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + /*Call registered Input complete callback*/ + hcryp->InCpltCallback(hcryp); +#else + /*Call legacy weak Input complete callback*/ + HAL_CRYP_InCpltCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + } + else + { + /* Write the first input header block in the Input FIFO, + the following header data will be fed after interrupt occurrence */ + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++; + }/* if (hcryp->Init.HeaderSize == 0U) */ /* Header phase is skipped*/ + + } /* end of if (dokeyivconfig == 1U) */ + else /* Key and IV have already been configured, + header has already been processed; + only process here message payload */ + { + /* Write the payload Input block in the IN FIFO */ + if (hcryp->Size == 0U) + { + /* Disable interrupts */ + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE); + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + } + else if (hcryp->Size >= 16U) + { + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + + if ((hcryp->CrypInCount == (hcryp->Size / 4U)) && ((hcryp->Size % 16U) == 0U)) + { + /* Call Input transfer complete callback */ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + /*Call registered Input complete callback*/ + hcryp->InCpltCallback(hcryp); +#else + /*Call legacy weak Input complete callback*/ + HAL_CRYP_InCpltCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + } + } + else /* Size < 4 words : first block is the last block*/ + { + /* Compute the number of padding bytes in last block of payload */ + npblb = 16U - (uint32_t)hcryp->Size; + + mode = hcryp->Instance->CR & AES_CR_MODE; + if (((mode == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC)) || + ((mode == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM))) + { + /* Specify the number of non-valid bytes using NPBLB register*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U); + } + + /* Number of valid words (lastwordsize) in last block */ + if ((npblb % 4U) == 0U) + { + lastwordsize = (16U - npblb) / 4U; + } + else + { + lastwordsize = ((16U - npblb) / 4U) + 1U; + } + + /* Last block optionally pad the data with zeros*/ + for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter++) + { + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + } + while (loopcounter < 4U) + { + /* Pad the data with zeros to have a complete block */ + hcryp->Instance->DINR = 0x0U; + loopcounter++; + } + /* Call Input transfer complete callback */ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + /*Call registered Input complete callback*/ + hcryp->InCpltCallback(hcryp); +#else + /*Call legacy weak Input complete callback*/ + HAL_CRYP_InCpltCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + } + } + + return HAL_OK; +} + +/** + * @brief AES CCM encryption/decryption process in DMA mode + * encrypt/decrypt are performed with authentication preparation. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @retval HAL status + */ +static HAL_StatusTypeDef CRYP_AESCCM_Process_DMA(CRYP_HandleTypeDef *hcryp) +{ + uint32_t count; + uint32_t dokeyivconfig = 1U; /* By default, carry out peripheral Key and IV configuration */ + + if (hcryp->Init.KeyIVConfigSkip == CRYP_KEYIVCONFIG_ONCE) + { + if (hcryp->KeyIVConfig == 1U) + { + /* If the Key and IV configuration has to be done only once + and if it has already been done, skip it */ + dokeyivconfig = 0U; + hcryp->SizesSum += hcryp->Size; /* Compute message total payload length */ + } + else + { + /* If the Key and IV configuration has to be done only once + and if it has not been done already, do it and set KeyIVConfig + to keep track it won't have to be done again next time */ + hcryp->KeyIVConfig = 1U; + hcryp->SizesSum = hcryp->Size; /* Merely store payload length */ + } + } + else + { + hcryp->SizesSum = hcryp->Size; + } + + if (dokeyivconfig == 1U) + { + + /* Reset CrypHeaderCount */ + hcryp->CrypHeaderCount = 0U; + + + /********************** Init phase ******************************************/ + + CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT); + /* Set the Key */ + if (hcryp->Init.KeyIVConfigSkip != CRYP_KEYNOCONFIG) + { + if (hcryp->Instance == AES) + { + if (hcryp->Init.KeyMode != CRYP_KEYMODE_SHARED) + { + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + else /*after sharing the key, AES should set KMOD[1:0] to 00.*/ + { + hcryp->Instance->CR &= ~CRYP_KEYMODE_SHARED; + } + } + else /*SAES*/ + { + /* We should re-write Key, in the case where we change key after first operation */ + if ((hcryp->Init.KeySelect == CRYP_KEYSEL_NORMAL) && (hcryp->Init.KeyMode == CRYP_KEYMODE_NORMAL)) + { + /* Set the Key */ + CRYP_SetKey(hcryp, hcryp->Init.KeySize); + } + /* Wait for KEYVALID flag to be set */ + count = CRYP_TIMEOUT_KEYPREPARATION; + do + { + count--; + if (count == 0U) + { + /* Disable the SAES peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change state */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } while (HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_KEYVALID)); + } + } + /* Set the initialization vector (IV) with B0 */ + hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.B0); + hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.B0 + 1U); + hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.B0 + 2U); + hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.B0 + 3U); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + /* just wait for hash computation */ + count = CRYP_TIMEOUT_GCMCCMINITPHASE; + do + { + count--; + if (count == 0U) + { + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change state */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF)); + + /* Clear CCF flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + + + /********************* Header phase *****************************************/ + + if (CRYP_GCMCCM_SetHeaderPhase_DMA(hcryp) != HAL_OK) + { + return HAL_ERROR; + } + + } + else + { + /* Initialization and header phases already done, only do payload phase */ + if (CRYP_GCMCCM_SetPayloadPhase_DMA(hcryp) != HAL_OK) + { + return HAL_ERROR; + } + } /* if (DoKeyIVConfig == 1U) */ + + return HAL_OK; +} + +/** + * @brief Sets the payload phase in interrupt mode + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @retval state + */ +static void CRYP_GCMCCM_SetPayloadPhase_IT(CRYP_HandleTypeDef *hcryp) +{ + uint32_t loopcounter; + uint32_t temp[4]; /* Temporary CrypOutBuff */ + uint32_t lastwordsize; + uint32_t npblb; + uint32_t mode; + uint16_t incount; /* Temporary CrypInCount Value */ + uint16_t outcount; /* Temporary CrypOutCount Value */ + uint32_t i; + + /***************************** Payload phase *******************************/ + + /* Read the output block from the output FIFO and put them in temporary buffer then + get CrypOutBuff from temporary buffer*/ + for (i = 0U; i < 4U; i++) + { + temp[i] = hcryp->Instance->DOUTR; + } + i = 0U; + while ((hcryp->CrypOutCount < ((hcryp->Size + 3U) / 4U)) && (i < 4U)) + { + *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[i]; + hcryp->CrypOutCount++; + i++; + } + incount = hcryp->CrypInCount; + outcount = hcryp->CrypOutCount; + if ((outcount >= (hcryp->Size / 4U)) && ((incount * 4U) >= hcryp->Size)) + { + + /* When in CCM with Key and IV configuration skipped, don't disable interruptions */ + if (!((hcryp->Init.Algorithm == CRYP_AES_CCM) && (hcryp->KeyIVConfig == 1U))) + { + /* Disable computation complete flag and errors interrupts */ + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE); + } + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + + /* Call output transfer complete callback */ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + /*Call registered Output complete callback*/ + hcryp->OutCpltCallback(hcryp); +#else + /*Call legacy weak Output complete callback*/ + HAL_CRYP_OutCpltCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + } + + else if (((hcryp->Size / 4U) - (hcryp->CrypInCount)) >= 4U) + { + +#if (USE_HAL_CRYP_SUSPEND_RESUME == 1U) + /* If suspension flag has been raised, suspend processing + only if not already at the end of the payload */ + if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND) + { + /* Clear CCF Flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + + /* reset SuspendRequest */ + hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE; + /* Disable Computation Complete Flag and Errors Interrupts */ + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE); + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_SUSPENDED; + /* Mark that the payload phase is suspended */ + hcryp->Phase = CRYP_PHASE_PAYLOAD_SUSPENDED; + __HAL_UNLOCK(hcryp); + } + else +#endif /* USE_HAL_CRYP_SUSPEND_RESUME */ + { + /* Write the input block in the IN FIFO */ + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + if ((hcryp->CrypInCount == (hcryp->Size / 4U)) && ((hcryp->Size % 16U) == 0U)) + { + /* Call output transfer complete callback */ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + /*Call registered Input complete callback*/ + hcryp->InCpltCallback(hcryp); +#else + /*Call legacy weak Input complete callback*/ + HAL_CRYP_InCpltCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + } + } + } + else /* Last block of payload < 128bit*/ + { + /* Compute the number of padding bytes in last block of payload */ + npblb = ((((uint32_t)hcryp->Size / 16U) + 1U) * 16U) - ((uint32_t)hcryp->Size); + + mode = hcryp->Instance->CR & AES_CR_MODE; + if (((mode == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC)) || + ((mode == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM))) + { + /* Specify the number of non-valid bytes using NPBLB register*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U); + } + + /* Number of valid words (lastwordsize) in last block */ + if ((npblb % 4U) == 0U) + { + lastwordsize = (16U - npblb) / 4U; + } + else + { + lastwordsize = ((16U - npblb) / 4U) + 1U; + } + + /* Last block optionally pad the data with zeros*/ + for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter++) + { + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + } + while (loopcounter < 4U) + { + /* pad the data with zeros to have a complete block */ + hcryp->Instance->DINR = 0x0U; + loopcounter++; + } + } +} + +/** + * @brief Sets the payload phase in DMA mode + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @retval state + */ +static HAL_StatusTypeDef CRYP_GCMCCM_SetPayloadPhase_DMA(CRYP_HandleTypeDef *hcryp) +{ + uint32_t index; + uint32_t npblb; + uint32_t lastwordsize; + uint32_t temp[4]; /* Temporary CrypOutBuff */ + uint32_t count; + uint32_t reg; + + /************************ Payload phase ************************************/ + if (hcryp->Size == 0U) + { + /* Process unLocked */ + __HAL_UNLOCK(hcryp); + + /* Change the CRYP state and phase */ + hcryp->State = HAL_CRYP_STATE_READY; + } + else if (hcryp->Size >= 16U) + { + /*DMA transfer must not include the last block in case of Size is not %16 */ + CRYP_SetDMAConfig(hcryp, (uint32_t)(hcryp->pCrypInBuffPtr), (uint16_t)((hcryp->Size / 16U) * 16U), + (uint32_t)(hcryp->pCrypOutBuffPtr)); + } + else /* length of input data is < 16 */ + { + /* Compute the number of padding bytes in last block of payload */ + npblb = 16U - (uint32_t)hcryp->Size; + + /* Set Npblb in case of AES GCM payload encryption or AES CCM payload decryption to get right tag*/ + reg = hcryp->Instance->CR & (AES_CR_CHMOD | AES_CR_MODE); + if ((reg == (CRYP_AES_GCM_GMAC | CRYP_OPERATINGMODE_ENCRYPT)) || \ + (reg == (CRYP_AES_CCM | CRYP_OPERATINGMODE_DECRYPT))) + { + /* Specify the number of non-valid bytes using NPBLB register*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U); + } + + /* Number of valid words (lastwordsize) in last block */ + if ((npblb % 4U) == 0U) + { + lastwordsize = (16U - npblb) / 4U; + } + else + { + lastwordsize = ((16U - npblb) / 4U) + 1U; + } + + /* last block optionally pad the data with zeros*/ + for (index = 0U; index < lastwordsize; index ++) + { + /* Write the last Input block in the IN FIFO */ + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + } + while (index < 4U) + { + /* pad the data with zeros to have a complete block */ + hcryp->Instance->DINR = 0U; + index++; + } + /* Call the input data transfer complete callback */ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + /*Call registered Input complete callback*/ + hcryp->InCpltCallback(hcryp); +#else + /*Call legacy weak Input complete callback*/ + HAL_CRYP_InCpltCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + /* Wait for CCF flag to be raised */ + count = CRYP_TIMEOUT_GCMCCMHEADERPHASE; + do + { + count-- ; + if (count == 0U) + { + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change state */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF)); + + /* Clear CCF Flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + + /*Read the output block from the output FIFO */ + for (index = 0U; index < 4U; index++) + { + /* Read the output block from the output FIFO and put them in temporary + buffer then get CrypOutBuff from temporary buffer */ + temp[index] = hcryp->Instance->DOUTR; + } + for (index = 0U; index < lastwordsize; index++) + { + *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp[index]; + hcryp->CrypOutCount++; + } + + /* Change the CRYP state to ready */ + hcryp->State = HAL_CRYP_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hcryp); + /* Call Output transfer complete callback */ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + /*Call registered Output complete callback*/ + hcryp->OutCpltCallback(hcryp); +#else + /*Call legacy weak Output complete callback*/ + HAL_CRYP_OutCpltCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + } + + return HAL_OK; +} + +/** + * @brief Sets the header phase in polling mode + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module(Header & HeaderSize) + * @param Timeout Timeout value + * @retval state + */ +static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint32_t Timeout) +{ + uint32_t loopcounter; + uint32_t size_in_bytes; + uint32_t tmp; + const uint32_t mask[12] = {0x0U, 0xFF000000U, 0xFFFF0000U, 0xFFFFFF00U, /* 32-bit data type */ + 0x0U, 0x0000FF00U, 0x0000FFFFU, 0xFF00FFFFU, /* 16-bit data type */ + 0x0U, 0x000000FFU, 0x0000FFFFU, 0x00FFFFFFU + }; /* 8-bit data type */ + + /***************************** Header phase for GCM/GMAC or CCM *********************************/ + if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_WORD) + { + size_in_bytes = hcryp->Init.HeaderSize * 4U; + } + else + { + size_in_bytes = hcryp->Init.HeaderSize; + } + + if ((size_in_bytes != 0U)) + { + /* Select header phase */ + CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + /* If size_in_bytes is a multiple of blocks (a multiple of four 32-bits words ) */ + if ((size_in_bytes % 16U) == 0U) + { + /* No padding */ + for (loopcounter = 0U; (loopcounter < (size_in_bytes / 4U)); loopcounter += 4U) + { + /* Write the input block in the data input register */ + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++; + + if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK) + { + return HAL_ERROR; + } + /* Clear CCF flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + } + } + else + { + /* Write header block in the IN FIFO without last block */ + for (loopcounter = 0U; (loopcounter < ((size_in_bytes / 16U) * 4U)); loopcounter += 4U) + { + /* Write the input block in the data input register */ + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++; + + if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK) + { + return HAL_ERROR; + } + /* Clear CCF flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + } + /* Write last complete words */ + for (loopcounter = 0U; (loopcounter < ((size_in_bytes / 4U) % 4U)); loopcounter++) + { + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++; + } + /* If the header size is a multiple of words */ + if ((size_in_bytes % 4U) == 0U) + { + /* Pad the data with zeros to have a complete block */ + while (loopcounter < 4U) + { + hcryp->Instance->DINR = 0x0U; + loopcounter++; + } + } + else + { + /* Enter last bytes, padded with zeros */ + tmp = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + tmp &= mask[(hcryp->Init.DataType * 2U) + (size_in_bytes % 4U)]; + hcryp->Instance->DINR = tmp; + loopcounter++; + /* Pad the data with zeros to have a complete block */ + while (loopcounter < 4U) + { + hcryp->Instance->DINR = 0x0U; + loopcounter++; + } + } + + if (CRYP_WaitOnCCFlag(hcryp, Timeout) != HAL_OK) + { + return HAL_ERROR; + } + /* Clear CCF flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + } + } + else + { + /*Workaround 1: only AES, before re-enabling the peripheral, datatype can be configured.*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_DATATYPE, hcryp->Init.DataType); + + /* Select header phase */ + CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + } + + return HAL_OK; +} + +/** + * @brief Sets the header phase when using DMA in process + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module(Header & HeaderSize) + * @retval None + */ +static HAL_StatusTypeDef CRYP_GCMCCM_SetHeaderPhase_DMA(CRYP_HandleTypeDef *hcryp) +{ + uint32_t loopcounter; + uint32_t headersize_in_bytes; + uint32_t tmp; + const uint32_t mask[12] = {0x0U, 0xFF000000U, 0xFFFF0000U, 0xFFFFFF00U, /* 32-bit data type */ + 0x0U, 0x0000FF00U, 0x0000FFFFU, 0xFF00FFFFU, /* 16-bit data type */ + 0x0U, 0x000000FFU, 0x0000FFFFU, 0x00FFFFFFU + }; /* 8-bit data type */ + + /***************************** Header phase for GCM/GMAC or CCM *********************************/ + if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_WORD) + { + headersize_in_bytes = hcryp->Init.HeaderSize * 4U; + } + else + { + headersize_in_bytes = hcryp->Init.HeaderSize; + } + + /* Select header phase */ + CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + /* Set the phase */ + hcryp->Phase = CRYP_PHASE_PROCESS; + + /* If header size is at least equal to 16 bytes, feed the header through DMA. + If size_in_bytes is not a multiple of blocks (is not a multiple of four 32-bit words ), + last bytes feeding and padding will be done in CRYP_DMAInCplt() */ + if (headersize_in_bytes >= 16U) + { + /* Initiate header DMA transfer */ + if (CRYP_SetHeaderDMAConfig(hcryp, (uint32_t)(hcryp->Init.Header), + (uint16_t)((headersize_in_bytes / 16U) * 16U)) != HAL_OK) + { + return HAL_ERROR; + } + } + else + { + if (headersize_in_bytes != 0U) + { + /* Header length is larger than 0 and strictly less than 16 bytes */ + /* Write last complete words */ + for (loopcounter = 0U; (loopcounter < (headersize_in_bytes / 4U)); loopcounter++) + { + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++ ; + } + /* If the header size is a multiple of words */ + if ((headersize_in_bytes % 4U) == 0U) + { + /* Pad the data with zeros to have a complete block */ + while (loopcounter < 4U) + { + hcryp->Instance->DINR = 0x0U; + loopcounter++; + } + } + else + { + /* Enter last bytes, padded with zeros */ + tmp = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + tmp &= mask[(hcryp->Init.DataType * 2U) + (headersize_in_bytes % 4U)]; + hcryp->Instance->DINR = tmp; + loopcounter++; + /* Pad the data with zeros to have a complete block */ + while (loopcounter < 4U) + { + hcryp->Instance->DINR = 0x0U; + loopcounter++; + } + } + + if (CRYP_WaitOnCCFlag(hcryp, CRYP_TIMEOUT_GCMCCMHEADERPHASE) != HAL_OK) + { + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change state */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + /* Clear CCF flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + } /* if (headersize_in_bytes != 0U) */ + + /* Move to payload phase if header length is null or + if the header length was less than 16 and header written by software instead of DMA */ + + /* Set to 0 the number of non-valid bytes using NPBLB register*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U); + + /* Select payload phase once the header phase is performed */ + CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); + + /* Initiate payload DMA IN and processed data DMA OUT transfers */ + if (CRYP_GCMCCM_SetPayloadPhase_DMA(hcryp) != HAL_OK) + { + return HAL_ERROR; + } + } /* if (headersize_in_bytes >= 16U) */ + + return HAL_OK; +} + +/** + * @brief Sets the header phase in interrupt mode + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module(Header & HeaderSize) + * @retval None + */ +static void CRYP_GCMCCM_SetHeaderPhase_IT(CRYP_HandleTypeDef *hcryp) +{ + uint32_t loopcounter; + uint32_t lastwordsize; + uint32_t npblb; + uint32_t mode; + uint32_t headersize_in_bytes; + uint32_t tmp; + const uint32_t mask[12] = {0x0U, 0xFF000000U, 0xFFFF0000U, 0xFFFFFF00U, /* 32-bit data type */ + 0x0U, 0x0000FF00U, 0x0000FFFFU, 0xFF00FFFFU, /* 16-bit data type */ + 0x0U, 0x000000FFU, 0x0000FFFFU, 0x00FFFFFFU + }; /* 8-bit data type */ + + if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_WORD) + { + headersize_in_bytes = hcryp->Init.HeaderSize * 4U; + } + else + { + headersize_in_bytes = hcryp->Init.HeaderSize; + } + + /***************************** Header phase *********************************/ + /* Test whether or not the header phase is over. + If the test below is true, move to payload phase */ + if (headersize_in_bytes <= ((uint32_t)(hcryp->CrypHeaderCount) * 4U)) + { + /* Set the phase */ + hcryp->Phase = CRYP_PHASE_PROCESS; + /* Select payload phase */ + MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_PAYLOAD); + /* Set to 0 the number of non-valid bytes using NPBLB register*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U); + + if (hcryp->Init.Algorithm == CRYP_AES_CCM) + { + /* Increment CrypHeaderCount to pass in CRYP_GCMCCM_SetPayloadPhase_IT */ + hcryp->CrypHeaderCount++; + } + /* Write the payload Input block in the IN FIFO */ + if (hcryp->Size == 0U) + { + /* Disable interrupts */ + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE); + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + } + else if (hcryp->Size >= 16U) + { + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + + if ((hcryp->CrypInCount == (hcryp->Size / 4U)) && ((hcryp->Size % 16U) == 0U)) + { + /* Call the input data transfer complete callback */ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + /*Call registered Input complete callback*/ + hcryp->InCpltCallback(hcryp); +#else + /*Call legacy weak Input complete callback*/ + HAL_CRYP_InCpltCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + } + } + else /* Size < 4 words : first block is the last block*/ + { + /* Compute the number of padding bytes in last block of payload */ + npblb = 16U - ((uint32_t)hcryp->Size); + mode = hcryp->Instance->CR & AES_CR_MODE; + if (((mode == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC)) || + ((mode == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM))) + { + /* Specify the number of non-valid bytes using NPBLB register*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, npblb << 20U); + } + + /* Number of valid words (lastwordsize) in last block */ + if ((npblb % 4U) == 0U) + { + lastwordsize = (16U - npblb) / 4U; + } + else + { + lastwordsize = ((16U - npblb) / 4U) + 1U; + } + + /* Last block optionally pad the data with zeros*/ + for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter++) + { + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + } + while (loopcounter < 4U) + { + /* Pad the data with zeros to have a complete block */ + hcryp->Instance->DINR = 0x0U; + loopcounter++; + } + /* Call the input data transfer complete callback */ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + /*Call registered Input complete callback*/ + hcryp->InCpltCallback(hcryp); +#else + /*Call legacy weak Input complete callback*/ + HAL_CRYP_InCpltCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + } + } + else if ((((headersize_in_bytes / 4U) - (hcryp->CrypHeaderCount)) >= 4U)) + { + /* Can enter full 4 header words */ +#if (USE_HAL_CRYP_SUSPEND_RESUME == 1U) + /* If suspension flag has been raised, suspend processing + only if not already at the end of the header */ + if (hcryp->SuspendRequest == HAL_CRYP_SUSPEND) + { + /* Clear CCF Flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + + /* reset SuspendRequest */ + hcryp->SuspendRequest = HAL_CRYP_SUSPEND_NONE; + /* Disable Computation Complete Flag and Errors Interrupts */ + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE); + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_SUSPENDED; + /* Mark that the payload phase is suspended */ + hcryp->Phase = CRYP_PHASE_HEADER_SUSPENDED; + __HAL_UNLOCK(hcryp); + } + else +#endif /* USE_HAL_CRYP_SUSPEND_RESUME */ + { + /* Write the input block in the IN FIFO */ + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++; + } + } + else /* Write last header block (4 words), padded with zeros if needed */ + { + + for (loopcounter = 0U; (loopcounter < ((headersize_in_bytes / 4U) % 4U)); loopcounter++) + { + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++ ; + } + /* If the header size is a multiple of words */ + if ((headersize_in_bytes % 4U) == 0U) + { + /* Pad the data with zeros to have a complete block */ + while (loopcounter < 4U) + { + hcryp->Instance->DINR = 0x0U; + loopcounter++; + hcryp->CrypHeaderCount++; + } + } + else + { + /* Enter last bytes, padded with zeros */ + tmp = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + tmp &= mask[(hcryp->Init.DataType * 2U) + (headersize_in_bytes % 4U)]; + hcryp->Instance->DINR = tmp; + loopcounter++; + hcryp->CrypHeaderCount++; + /* Pad the data with zeros to have a complete block */ + while (loopcounter < 4U) + { + hcryp->Instance->DINR = 0x0U; + loopcounter++; + hcryp->CrypHeaderCount++; + } + } + } +} + +/** + * @brief Handle CRYP hardware block Timeout when waiting for CCF flag to be raised. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module. + * @param Timeout Timeout duration. + * @note This function can only be used in thread mode. + * @retval HAL status + */ +static HAL_StatusTypeDef CRYP_WaitOnCCFlag(CRYP_HandleTypeDef *hcryp, uint32_t Timeout) +{ + uint32_t tickstart; + + /* Get timeout */ + tickstart = HAL_GetTick(); + + while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF)) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + __HAL_CRYP_DISABLE(hcryp); + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } + } + return HAL_OK; +} + +/** + * @brief Wait for Computation Complete Flag (CCF) to raise then clear it. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module. + * @param Timeout Timeout duration. + * @note This function can be used in thread or handler mode. + * @retval HAL status + */ +static void CRYP_ClearCCFlagWhenHigh(CRYP_HandleTypeDef *hcryp, uint32_t Timeout) +{ + uint32_t count = Timeout; + + do + { + count-- ; + if (count == 0U) + { + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change state */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + + /* Process unlocked */ + __HAL_UNLOCK(hcryp); + hcryp->State = HAL_CRYP_STATE_READY; + +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1U) + /*Call registered error callback*/ + hcryp->ErrorCallback(hcryp); +#else + /*Call legacy weak error callback*/ + HAL_CRYP_ErrorCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + } + } while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF)); + + /* Clear CCF flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); +} + +#if (USE_HAL_CRYP_SUSPEND_RESUME == 1U) +/** + * @brief In case of message processing suspension, read the Initialization Vector. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module. + * @param Output Pointer to the buffer containing the saved Initialization Vector. + * @note This value has to be stored for reuse by writing the AES_IVRx registers + * as soon as the suspended processing has to be resumed. + * @retval None + */ +static void CRYP_Read_IVRegisters(CRYP_HandleTypeDef *hcryp, const uint32_t *Output) +{ + uint32_t outputaddr = (uint32_t)Output; + + *(uint32_t *)(outputaddr) = hcryp->Instance->IVR3; + outputaddr += 4U; + *(uint32_t *)(outputaddr) = hcryp->Instance->IVR2; + outputaddr += 4U; + *(uint32_t *)(outputaddr) = hcryp->Instance->IVR1; + outputaddr += 4U; + *(uint32_t *)(outputaddr) = hcryp->Instance->IVR0; +} + +/** + * @brief In case of message processing resumption, rewrite the Initialization + * Vector in the AES_IVRx registers. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module. + * @param Input Pointer to the buffer containing the saved Initialization Vector to + * write back in the CRYP hardware block. + * @note AES must be disabled when reconfiguring the IV values. + * @retval None + */ +static void CRYP_Write_IVRegisters(CRYP_HandleTypeDef *hcryp, const uint32_t *Input) +{ + uint32_t ivaddr = (uint32_t)Input; + + hcryp->Instance->IVR3 = *(uint32_t *)(ivaddr); + ivaddr += 4U; + hcryp->Instance->IVR2 = *(uint32_t *)(ivaddr); + ivaddr += 4U; + hcryp->Instance->IVR1 = *(uint32_t *)(ivaddr); + ivaddr += 4U; + hcryp->Instance->IVR0 = *(uint32_t *)(ivaddr); +} + +/** + * @brief In case of message GCM/GMAC/CCM processing suspension, + * read the Suspend Registers. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module. + * @param Output Pointer to the buffer containing the saved Suspend Registers. + * @note These values have to be stored for reuse by writing back the AES_SUSPxR registers + * as soon as the suspended processing has to be resumed. + * @retval None + */ +static void CRYP_Read_SuspendRegisters(CRYP_HandleTypeDef *hcryp, const uint32_t *Output) +{ + uint32_t outputaddr = (uint32_t)Output; + uint32_t count = 0U; + + /* In case of GCM payload phase encryption, check that suspension can be carried out */ + if (READ_BIT(hcryp->Instance->CR, (AES_CR_CHMOD | AES_CR_GCMPH | AES_CR_MODE)) == (CRYP_AES_GCM_GMAC | + AES_CR_GCMPH_1 | 0x0)) + { + + /* Wait for BUSY flag to be cleared */ + count = 0xFFF; + do + { + count--; + if (count == 0U) + { + /* Change state */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + HAL_CRYP_ErrorCallback(hcryp); + return; + } + } while (HAL_IS_BIT_SET(hcryp->Instance->SR, AES_SR_BUSY)); + + } + + *(uint32_t *)(outputaddr) = hcryp->Instance->SUSP7R; + outputaddr += 4U; + *(uint32_t *)(outputaddr) = hcryp->Instance->SUSP6R; + outputaddr += 4U; + *(uint32_t *)(outputaddr) = hcryp->Instance->SUSP5R; + outputaddr += 4U; + *(uint32_t *)(outputaddr) = hcryp->Instance->SUSP4R; + outputaddr += 4U; + *(uint32_t *)(outputaddr) = hcryp->Instance->SUSP3R; + outputaddr += 4U; + *(uint32_t *)(outputaddr) = hcryp->Instance->SUSP2R; + outputaddr += 4U; + *(uint32_t *)(outputaddr) = hcryp->Instance->SUSP1R; + outputaddr += 4U; + *(uint32_t *)(outputaddr) = hcryp->Instance->SUSP0R; +} + +/** + * @brief In case of message GCM/GMAC/CCM processing resumption, rewrite the Suspend + * Registers in the AES_SUSPxR registers. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module. + * @param Input Pointer to the buffer containing the saved suspend registers to + * write back in the CRYP hardware block. + * @note AES must be disabled when reconfiguring the suspend registers. + * @retval None + */ +static void CRYP_Write_SuspendRegisters(CRYP_HandleTypeDef *hcryp, const uint32_t *Input) +{ + uint32_t ivaddr = (uint32_t)Input; + + hcryp->Instance->SUSP7R = *(uint32_t *)(ivaddr); + ivaddr += 4U; + hcryp->Instance->SUSP6R = *(uint32_t *)(ivaddr); + ivaddr += 4U; + hcryp->Instance->SUSP5R = *(uint32_t *)(ivaddr); + ivaddr += 4U; + hcryp->Instance->SUSP4R = *(uint32_t *)(ivaddr); + ivaddr += 4U; + hcryp->Instance->SUSP3R = *(uint32_t *)(ivaddr); + ivaddr += 4U; + hcryp->Instance->SUSP2R = *(uint32_t *)(ivaddr); + ivaddr += 4U; + hcryp->Instance->SUSP1R = *(uint32_t *)(ivaddr); + ivaddr += 4U; + hcryp->Instance->SUSP0R = *(uint32_t *)(ivaddr); +} + +/** + * @brief In case of message GCM/GMAC/CCM processing suspension, read the Key Registers. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module. + * @param Output Pointer to the buffer containing the saved Key Registers. + * @param KeySize Indicates the key size (128 or 256 bits). + * @note These values have to be stored for reuse by writing back the AES_KEYRx registers + * as soon as the suspended processing has to be resumed. + * @retval None + */ +static void CRYP_Read_KeyRegisters(CRYP_HandleTypeDef *hcryp, const uint32_t *Output, uint32_t KeySize) +{ + uint32_t keyaddr = (uint32_t)Output; + + switch (KeySize) + { + case CRYP_KEYSIZE_256B: + *(uint32_t *)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey); + keyaddr += 4U; + *(uint32_t *)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 1U); + keyaddr += 4U; + *(uint32_t *)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 2U); + keyaddr += 4U; + *(uint32_t *)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 3U); + keyaddr += 4U; + *(uint32_t *)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 4U); + keyaddr += 4U; + *(uint32_t *)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 5U); + keyaddr += 4U; + *(uint32_t *)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 6U); + keyaddr += 4U; + *(uint32_t *)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 7U); + break; + case CRYP_KEYSIZE_128B: + *(uint32_t *)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey); + keyaddr += 4U; + *(uint32_t *)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 1U); + keyaddr += 4U; + *(uint32_t *)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 2U); + keyaddr += 4U; + *(uint32_t *)(keyaddr) = *(uint32_t *)(hcryp->Init.pKey + 3U); + break; + default: + break; + } +} + +/** + * @brief In case of message GCM/GMAC (CCM/CMAC when applicable) processing resumption, rewrite the Key + * Registers in the AES_KEYRx registers. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module. + * @param Input Pointer to the buffer containing the saved key registers to + * write back in the CRYP hardware block. + * @param KeySize Indicates the key size (128 or 256 bits) + * @note AES must be disabled when reconfiguring the Key registers. + * @retval None + */ +static void CRYP_Write_KeyRegisters(CRYP_HandleTypeDef *hcryp, const uint32_t *Input, uint32_t KeySize) +{ + uint32_t keyaddr = (uint32_t)Input; + + if (KeySize == CRYP_KEYSIZE_256B) + { + hcryp->Instance->KEYR7 = *(uint32_t *)(keyaddr); + keyaddr += 4U; + hcryp->Instance->KEYR6 = *(uint32_t *)(keyaddr); + keyaddr += 4U; + hcryp->Instance->KEYR5 = *(uint32_t *)(keyaddr); + keyaddr += 4U; + hcryp->Instance->KEYR4 = *(uint32_t *)(keyaddr); + keyaddr += 4U; + } + + hcryp->Instance->KEYR3 = *(uint32_t *)(keyaddr); + keyaddr += 4U; + hcryp->Instance->KEYR2 = *(uint32_t *)(keyaddr); + keyaddr += 4U; + hcryp->Instance->KEYR1 = *(uint32_t *)(keyaddr); + keyaddr += 4U; + hcryp->Instance->KEYR0 = *(uint32_t *)(keyaddr); +} + +/** + * @brief Authentication phase resumption in case of GCM/GMAC/CCM process in interrupt mode + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module(Header & HeaderSize) + * @retval None + */ +static void CRYP_PhaseProcessingResume(CRYP_HandleTypeDef *hcryp) +{ + uint32_t loopcounter; + uint16_t lastwordsize; + uint16_t npblb; + uint32_t cr_temp; + + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_RWEIF | CRYP_CLEAR_CCF); + + /* Enable computation complete flag and error interrupts */ + __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + /* Case of header phase resumption =================================================*/ + if (hcryp->Phase == CRYP_PHASE_HEADER_SUSPENDED) + { + /* Set the phase */ + hcryp->Phase = CRYP_PHASE_PROCESS; + + /* Select header phase */ + CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER); + + if (((hcryp->Init.HeaderSize) - (hcryp->CrypHeaderCount) >= 4U)) + { + /* Write the input block in the IN FIFO */ + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++; + } + else /*HeaderSize < 4 or HeaderSize >4 & HeaderSize %4 != 0*/ + { + /* Last block optionally pad the data with zeros*/ + for (loopcounter = 0U; loopcounter < (hcryp->Init.HeaderSize % 4U); loopcounter++) + { + hcryp->Instance->DINR = *(uint32_t *)(hcryp->Init.Header + hcryp->CrypHeaderCount); + hcryp->CrypHeaderCount++; + } + while (loopcounter < 4U) + { + /* pad the data with zeros to have a complete block */ + hcryp->Instance->DINR = 0x0U; + loopcounter++; + } + } + } + /* Case of payload phase resumption =================================================*/ + else + { + if (hcryp->Phase == CRYP_PHASE_PAYLOAD_SUSPENDED) + { + + /* Set the phase */ + hcryp->Phase = CRYP_PHASE_PROCESS; + + /* Select payload phase once the header phase is performed */ + MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_PAYLOAD); + + /* Set to 0 the number of non-valid bytes using NPBLB register*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, 0U); + + if (((hcryp->Size / 4U) - (hcryp->CrypInCount)) >= 4U) + { + /* Write the input block in the IN FIFO */ + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + if ((hcryp->CrypInCount == (hcryp->Size / 4U)) && ((hcryp->Size % 16U) == 0U)) + { + /* Call input transfer complete callback */ +#if (USE_HAL_CRYP_REGISTER_CALLBACKS == 1) + /*Call registered Input complete callback*/ + hcryp->InCpltCallback(hcryp); +#else + /*Call legacy weak Input complete callback*/ + HAL_CRYP_InCpltCallback(hcryp); +#endif /* USE_HAL_CRYP_REGISTER_CALLBACKS */ + } + } + else /* Last block of payload < 128bit*/ + { + /* Compute the number of padding bytes in last block of payload */ + npblb = (((hcryp->Size / 16U) + 1U) * 16U) - (hcryp->Size); + cr_temp = hcryp->Instance->CR; + if ((((cr_temp & AES_CR_MODE) == CRYP_OPERATINGMODE_ENCRYPT) && (hcryp->Init.Algorithm == CRYP_AES_GCM_GMAC)) || + (((cr_temp & AES_CR_MODE) == CRYP_OPERATINGMODE_DECRYPT) && (hcryp->Init.Algorithm == CRYP_AES_CCM))) + { + /* Specify the number of non-valid bytes using NPBLB register*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_NPBLB, ((uint32_t)npblb) << 20U); + } + + /* Number of valid words (lastwordsize) in last block */ + if ((npblb % 4U) == 0U) + { + lastwordsize = (16U - npblb) / 4U; + } + else + { + lastwordsize = ((16U - npblb) / 4U) + 1U; + } + + /* Last block optionally pad the data with zeros*/ + for (loopcounter = 0U; loopcounter < lastwordsize; loopcounter++) + { + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + } + while (loopcounter < 4U) + { + /* pad the data with zeros to have a complete block */ + hcryp->Instance->DINR = 0x0U; + loopcounter++; + } + } + } + } +} +#endif /* defined (USE_HAL_CRYP_SUSPEND_RESUME) */ +/** + * @} + */ + + +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#endif /* AES */ +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_cryp_ex.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_cryp_ex.c new file mode 100644 index 0000000000..3637c02260 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_cryp_ex.c @@ -0,0 +1,898 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_cryp_ex.c + * @author MCD Application Team + * @brief CRYPEx HAL module driver. + * This file provides firmware functions to manage the extended + * functionalities of the Cryptography (CRYP) peripheral. + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup CRYPEx + * @{ + */ + +#if defined(AES) + +#ifdef HAL_CRYP_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup CRYPEx_Private_Defines + * @{ + */ + +#define CRYP_PHASE_INIT 0x00000000U /*!< GCM/GMAC (or CCM) init phase */ +#define CRYP_PHASE_HEADER AES_CR_GCMPH_0 /*!< GCM/GMAC or CCM header phase */ +#define CRYP_PHASE_PAYLOAD AES_CR_GCMPH_1 /*!< GCM(/CCM) payload phase */ +#define CRYP_PHASE_FINAL AES_CR_GCMPH /*!< GCM/GMAC or CCM final phase */ + +#define CRYP_OPERATINGMODE_ENCRYPT 0x00000000U /*!< Encryption mode */ +#define CRYP_OPERATINGMODE_KEYDERIVATION AES_CR_MODE_0 /*!< Key derivation mode only used when performing ECB and CBC decryptions */ +#define CRYP_OPERATINGMODE_DECRYPT AES_CR_MODE_1 /*!< Decryption */ +#define CRYP_OPERATINGMODE_KEYDERIVATION_DECRYPT AES_CR_MODE /*!< Key derivation and decryption only used when performing ECB and CBC decryptions */ + +#define CRYPEx_PHASE_PROCESS 0x02U /*!< CRYP peripheral is in processing phase */ +#define CRYPEx_PHASE_FINAL 0x03U /*!< CRYP peripheral is in final phase this is relevant only with CCM and GCM modes */ + +/* CTR0 information to use in CCM algorithm */ +#define CRYP_CCM_CTR0_0 0x07FFFFFFU +#define CRYP_CCM_CTR0_3 0xFFFFFF00U + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +static HAL_StatusTypeDef CRYPEx_KeyDecrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout); +static HAL_StatusTypeDef CRYPEx_KeyEncrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout); +static HAL_StatusTypeDef CRYPEx_KeyGeneration(CRYP_HandleTypeDef *hcryp, uint32_t Timeout); +/* Exported functions---------------------------------------------------------*/ +/** @addtogroup CRYPEx_Exported_Functions + * @{ + */ + +/** @defgroup CRYPEx_Exported_Functions_Group1 Extended AES processing functions + * @brief Extended processing functions. + * +@verbatim + ============================================================================== + ##### Extended AES processing functions ##### + ============================================================================== + [..] This section provides functions allowing to generate the authentication + TAG in Polling mode + (#)HAL_CRYPEx_AESGCM_GenerateAuthTAG + (#)HAL_CRYPEx_AESCCM_GenerateAuthTAG + they should be used after Encrypt/Decrypt operation. + +@endverbatim + * @{ + */ + +/** + * @brief generate the GCM authentication TAG. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pAuthTag Pointer to the authentication buffer + * the pAuthTag generated here is 128bits length, if the TAG length is + * less than 128bits, user should consider only the valid part of pAuthTag + * buffer which correspond exactly to TAG length. + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYPEx_AESGCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, const uint32_t *pAuthTag, + uint32_t Timeout) +{ + /* Assume first Init.HeaderSize is in words */ + uint64_t headerlength = (uint64_t)hcryp->Init.HeaderSize * 32U; /* Header length in bits */ + uint64_t inputlength = (uint64_t)hcryp->SizesSum * 8U; /* Input length in bits */ + uint32_t tagaddr = (uint32_t)pAuthTag; + uint32_t i; + uint32_t tickstart; + + /* Correct headerlength if Init.HeaderSize is actually in bytes */ + if (hcryp->Init.HeaderWidthUnit == CRYP_HEADERWIDTHUNIT_BYTE) + { + headerlength /= 4U; + } + + if (hcryp->State == HAL_CRYP_STATE_READY) + { + __HAL_LOCK(hcryp); + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if (hcryp->Phase == CRYPEx_PHASE_PROCESS) + { + /* Change the CRYP phase */ + hcryp->Phase = CRYPEx_PHASE_FINAL; + + /* Select final phase */ + MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_FINAL); + + /* Write into the AES_DINR register the number of bits in header (64 bits) + followed by the number of bits in the payload */ + hcryp->Instance->DINR = 0U; + hcryp->Instance->DINR = (uint32_t)(headerlength); + hcryp->Instance->DINR = 0U; + hcryp->Instance->DINR = (uint32_t)(inputlength); + + /* Wait for CCF flag to be raised */ + tickstart = HAL_GetTick(); + while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF)) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change state */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } + } + + /* Read the authentication TAG in the output FIFO */ + for (i = 0U; i < 4U; i++) + { + *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR; + tagaddr += 4U; + } + + /* Clear CCF flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + + /* Disable the peripheral */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + } + else /* Initialization phase has not been performed */ + { + /* Disable the Peripheral */ + __HAL_CRYP_DISABLE(hcryp); + + /* Sequence error code field */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE; + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } + else + { + /* Busy error code field */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; + return HAL_ERROR; + } + /* Return function status */ + return HAL_OK; +} + +/** + * @brief AES CCM Authentication TAG generation. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pAuthTag Pointer to the authentication buffer + * the pAuthTag generated here is 128bits length, if the TAG length is + * less than 128bits, user should consider only the valid part of pAuthTag + * buffer which correspond exactly to TAG length. + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYPEx_AESCCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, const uint32_t *pAuthTag, + uint32_t Timeout) +{ + uint32_t tagaddr = (uint32_t)pAuthTag; + uint32_t i; + uint32_t tickstart; + + if (hcryp->State == HAL_CRYP_STATE_READY) + { + __HAL_LOCK(hcryp); + + /* Disable interrupts in case they were kept enabled to proceed + a single message in several iterations */ + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_CCFIE | CRYP_IT_RWEIE | CRYP_IT_KEIE); + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if (hcryp->Phase == CRYPEx_PHASE_PROCESS) + { + /* Change the CRYP phase */ + hcryp->Phase = CRYPEx_PHASE_FINAL; + /* Select final phase */ + MODIFY_REG(hcryp->Instance->CR, AES_CR_GCMPH, CRYP_PHASE_FINAL); + + /* Wait for CCF flag to be raised */ + tickstart = HAL_GetTick(); + while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF)) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + /* Disable the CRYP peripheral Clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change state */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } + } + + /* Read the authentication TAG in the output FIFO */ + for (i = 0U; i < 4U; i++) + { + *(uint32_t *)(tagaddr) = hcryp->Instance->DOUTR; + tagaddr += 4U; + } + + /* Clear CCF Flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + + /* Disable CRYP */ + __HAL_CRYP_DISABLE(hcryp); + } + else /* Initialization phase has not been performed */ + { + /* Disable the peripheral */ + __HAL_CRYP_DISABLE(hcryp); + + /* Sequence error code field */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE; + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } + else + { + /* Busy error code field */ + hcryp->ErrorCode = HAL_CRYP_ERROR_BUSY; + return HAL_ERROR; + } + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + + +/** @defgroup CRYPEx_Exported_Functions_Group2 Wrap and Unwrap key functions + * @brief Wrap and Unwrap key functions. + * +@verbatim + ============================================================================== + ##### Wrap and Unwrap key ##### + ============================================================================== + [..] This section provides API allowing to wrap (encrypt) and unwrap (decrypt) + key using one of the following keys, and AES Algorithm. + Key selection : + - Derived hardware unique key (DHUK) + - XOR of DHUK and BHK + - Boot hardware key (BHK) + +@endverbatim + * @{ + */ + +/** + * @brief Wrap (encrypt) application keys. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pInput Pointer to the Key buffer to encrypt in case of ECB or CBC + * @param pOutput Pointer to the Key buffer encrypted in case of ECB or CBC + * @param Timeout Specify Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYPEx_WrapKey(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint32_t *pOutput, uint32_t Timeout) +{ + HAL_StatusTypeDef status; + uint32_t algo; + + if (hcryp->State == HAL_CRYP_STATE_READY) + { + /* Change state Busy */ + hcryp->State = HAL_CRYP_STATE_BUSY; + __HAL_LOCK(hcryp); + + /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters*/ + hcryp->CrypInCount = 0U; + hcryp->CrypOutCount = 0U; + hcryp->pCrypInBuffPtr = pInput; + hcryp->pCrypOutBuffPtr = pOutput; + + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Set the operating mode*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD, CRYP_KEYMODE_WRAPPED); + + /* Encryption operating mode(Mode 0)*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT); + + + /* algo get algorithm selected */ + algo = hcryp->Instance->CR & AES_CR_CHMOD; + + switch (algo) + { + case CRYP_AES_ECB: + case CRYP_AES_CBC: + /* AES decryption */ + status = CRYPEx_KeyEncrypt(hcryp, Timeout); + break; + case CRYP_AES_CTR: + /* AES Key generation */ + status = CRYPEx_KeyGeneration(hcryp, Timeout); + break; + default: + hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED; + status = HAL_ERROR; + break; + } + } + else + { + /* Busy error code field */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; + status = HAL_ERROR; + } + /* Return function status */ + return status; +} + +/** + * @brief Unwrap (Decrypt) application keys. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pInput Pointer to the Key buffer to decrypt or generated key in case of CTR. + * @param Timeout Specify Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYPEx_UnwrapKey(CRYP_HandleTypeDef *hcryp, uint32_t *pInput, uint32_t Timeout) +{ + HAL_StatusTypeDef status; + uint32_t algo; + + if (hcryp->State == HAL_CRYP_STATE_READY) + { + /* Change state Busy */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + __HAL_LOCK(hcryp); + + /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters */ + hcryp->CrypInCount = 0U; + hcryp->CrypOutCount = 0U; + hcryp->pCrypInBuffPtr = pInput; + + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Set the operating mode*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD, CRYP_KEYMODE_WRAPPED); + + /* Decryption operating mode(Mode 3)*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT); + + /* algo get algorithm selected */ + algo = hcryp->Instance->CR & AES_CR_CHMOD; + + switch (algo) + { + case CRYP_AES_ECB: + case CRYP_AES_CBC: + /* AES decryption */ + status = CRYPEx_KeyDecrypt(hcryp, Timeout); + break; + + case CRYP_AES_CTR: + /* AES Key generation */ + status = CRYPEx_KeyGeneration(hcryp, Timeout); + break; + default: + hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED; + status = HAL_ERROR; + break; + } + } + else + { + /* Busy error code field */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; + status = HAL_ERROR; + } + /* Return function status */ + return status; +} + +/** + * @} + */ + +/** @defgroup CRYPEx_Exported_Functions_Group3 Encrypt and Decrypt Shared key functions + * @brief Encrypt and Decrypt Shared key functions. + * +@verbatim + ============================================================================== + ##### Encrypt and Decrypt Shared key functions ##### + ============================================================================== + [..] This section provides API allowing to Encrypt and Decrypt Shared key + +@endverbatim + * @{ + */ + +/** + * @brief Encrypt Shared key. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pKey Pointer to the Key buffer to share + * @param pOutput Pointer to the Key buffer encrypted + * @param ID Key share identification + * @param Timeout Specify Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYPEx_EncryptSharedKey(CRYP_HandleTypeDef *hcryp, uint32_t *pKey, uint32_t *pOutput, uint32_t ID, + uint32_t Timeout) +{ + HAL_StatusTypeDef status; + uint32_t algo; + + if (hcryp->State == HAL_CRYP_STATE_READY) + { + /* Change state Busy */ + hcryp->State = HAL_CRYP_STATE_BUSY; + __HAL_LOCK(hcryp); + + /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters */ + hcryp->CrypInCount = 0U; + hcryp->CrypOutCount = 0U; + hcryp->pCrypInBuffPtr = pKey; + hcryp->pCrypOutBuffPtr = pOutput; + + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Set the operating mode */ + MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD | AES_CR_KSHAREID, CRYP_KEYMODE_SHARED | ID); + + /* Encryption operating mode(Mode 0)*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_ENCRYPT); + + /* algo get algorithm selected */ + algo = hcryp->Instance->CR & AES_CR_CHMOD; + + switch (algo) + { + case CRYP_AES_ECB: + case CRYP_AES_CBC: + /* AES decryption */ + status = CRYPEx_KeyEncrypt(hcryp, Timeout); + break; + case CRYP_AES_CTR: + /* AES CTR key generation */ + status = CRYPEx_KeyGeneration(hcryp, Timeout); + break; + default: + hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED; + status = HAL_ERROR; + break; + } + } + else + { + /* Busy error code field */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; + status = HAL_ERROR; + } + /* Return function status */ + return status; +} + +/** + * @brief Decrypt Shared key. + * @param hcryp pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pKey Pointer to the Key buffer to share + * @param ID Key share identification + * @param Timeout Specify Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYPEx_DecryptSharedKey(CRYP_HandleTypeDef *hcryp, uint32_t *pKey, uint32_t ID, uint32_t Timeout) +{ + HAL_StatusTypeDef status; + uint32_t algo; + + if (hcryp->State == HAL_CRYP_STATE_READY) + { + /* Change state Busy */ + hcryp->State = HAL_CRYP_STATE_BUSY; + __HAL_LOCK(hcryp); + + /* Reset CrypInCount, CrypOutCount and Initialize pCrypInBuffPtr and pCrypOutBuffPtr parameters */ + hcryp->CrypInCount = 0U; + hcryp->CrypOutCount = 0U; + hcryp->pCrypInBuffPtr = pKey; + + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Set the operating mode */ + MODIFY_REG(hcryp->Instance->CR, AES_CR_KMOD | AES_CR_KSHAREID, CRYP_KEYMODE_SHARED | ID); + + /* Decryption operating mode(Mode 3)*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT); + + /* algo get algorithm selected */ + algo = hcryp->Instance->CR & AES_CR_CHMOD; + + switch (algo) + { + case CRYP_AES_ECB: + case CRYP_AES_CBC: + /* AES decryption */ + status = CRYPEx_KeyDecrypt(hcryp, Timeout); + break; + case CRYP_AES_CTR: + /* AES CTR key generation */ + status = CRYPEx_KeyGeneration(hcryp, Timeout); + break; + default: + hcryp->ErrorCode |= HAL_CRYP_ERROR_NOT_SUPPORTED; + status = HAL_ERROR; + break; + } + } + else + { + /* Busy error code field */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_BUSY; + status = HAL_ERROR; + } + /* Return function status */ + return status; +} + +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @addtogroup CRYP_Private_Functions + * @{ + */ +/** + * @brief Key Decryption + * @param hcryp pointer to a CRYP_HandleTypeDef structure + * @param Timeout specify Timeout value + * @note It is strongly recommended to select hardware secret keys + * @retval HAL status + */ +static HAL_StatusTypeDef CRYPEx_KeyDecrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout) +{ + uint32_t incount; /* Temporary CrypInCount Value */ + uint32_t i; + uint32_t tickstart; + + /* key preparation for decryption, operating mode 2*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_KEYDERIVATION); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Wait for CCF flag to be raised */ + tickstart = HAL_GetTick(); + while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF)) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change state */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } + } + /* Clear CCF Flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + + /* End of Key preparation for ECB/CBC */ + /* Return to decryption operating mode(Mode 3)*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_MODE, CRYP_OPERATINGMODE_DECRYPT); + + if (hcryp->Init.Algorithm != CRYP_AES_ECB) + { + /* Set the Initialization Vector */ + hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect); + hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U); + hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U); + hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U); + } + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Set the phase */ + hcryp->Phase = CRYPEx_PHASE_PROCESS; + + if (hcryp->Init.KeySize == CRYP_KEYSIZE_128B) + { + incount = 4U; + } + else + { + incount = 8U; + } + while (hcryp->CrypInCount < incount) + { + /* Write four times to input the key to encrypt */ + for (i = 0U; i < 4U; i++) + { + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + } + /* Wait for CCF flag to be raised */ + tickstart = HAL_GetTick(); + while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF)) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change state */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } + } + + /* Clear CCF Flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + } + + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_OK; +} + +/** + * @brief Key Encryption + * @param hcryp pointer to a CRYP_HandleTypeDef structure + * @param Timeout specify Timeout value + * @retval HAL status + */ +static HAL_StatusTypeDef CRYPEx_KeyEncrypt(CRYP_HandleTypeDef *hcryp, uint32_t Timeout) +{ + uint32_t incount; /* Temporary CrypInCount Value */ + uint32_t i; + uint32_t tickstart; + uint32_t temp; /* Temporary CrypOutBuff */ + + if (hcryp->Init.Algorithm != CRYP_AES_ECB) + { + /* Set the Initialization Vector */ + hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect); + hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U); + hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U); + hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U); + } + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Set the phase */ + hcryp->Phase = CRYPEx_PHASE_PROCESS; + + if (hcryp->Init.KeySize == CRYP_KEYSIZE_128B) + { + incount = 4U; + } + else + { + incount = 8U; + } + while (hcryp->CrypInCount < incount) + { + for (i = 0U; i < 4U; i++) + { + hcryp->Instance->DINR = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount); + hcryp->CrypInCount++; + } + /* Wait for CCF flag to be raised */ + tickstart = HAL_GetTick(); + while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF)) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change state */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } + } + + /* Clear CCF Flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + + /* Read the output block from the output FIFO and put them in temporary buffer then + get CrypOutBuff from temporary buffer */ + for (i = 0U; i < 4U; i++) + { + temp = hcryp->Instance->DOUTR; + *(uint32_t *)(hcryp->pCrypOutBuffPtr + hcryp->CrypOutCount) = temp; + hcryp->CrypOutCount++; + } + } + + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_OK; +} +/** + * @brief Key Generation + * @param hcryp pointer to a CRYP_HandleTypeDef structure + * @param Timeout specify Timeout value + * @retval HAL status + */ +static HAL_StatusTypeDef CRYPEx_KeyGeneration(CRYP_HandleTypeDef *hcryp, uint32_t Timeout) +{ + uint32_t tickstart; + + /* No swap, DATATYPE must be kept to 0x0.*/ + MODIFY_REG(hcryp->Instance->CR, AES_CR_DATATYPE, CRYP_NO_SWAP); + + /*Writes initialization vector in IV registers*/ + if (hcryp->Init.pInitVect != NULL) + { + /* Set the Initialization Vector*/ + hcryp->Instance->IVR3 = *(uint32_t *)(hcryp->Init.pInitVect); + hcryp->Instance->IVR2 = *(uint32_t *)(hcryp->Init.pInitVect + 1U); + hcryp->Instance->IVR1 = *(uint32_t *)(hcryp->Init.pInitVect + 2U); + /* Keeping the two least significant bit of SAES_IVR0 to 00 */ + hcryp->Instance->IVR0 = *(uint32_t *)(hcryp->Init.pInitVect + 3U); + hcryp->Instance->IVR0 &= 0xFFFFFFFCU ; + } + else + { + return HAL_ERROR; + } + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Wait for CCF flag to be raised */ + tickstart = HAL_GetTick(); + while (HAL_IS_BIT_CLR(hcryp->Instance->ISR, AES_ISR_CCF)) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change state */ + hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + return HAL_ERROR; + } + } + } + /* Clear CCF Flag */ + __HAL_CRYP_CLEAR_FLAG(hcryp, CRYP_CLEAR_CCF); + + /* Disable the CRYP peripheral clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_READY; + __HAL_UNLOCK(hcryp); + + return HAL_OK; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#endif /* AES */ +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dac.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dac.c new file mode 100644 index 0000000000..79388cd6b2 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dac.c @@ -0,0 +1,1833 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_dac.c + * @author MCD Application Team + * @brief DAC HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Digital to Analog Converter (DAC) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State and Errors functions + * + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### DAC Peripheral features ##### + ============================================================================== + [..] + *** DAC Channels *** + ==================== + [..] + STM32H5 devices integrate two 12-bit Digital Analog Converters + + The 2 converters (i.e. channel1 & channel2) + can be used independently or simultaneously (dual mode): + (#) DAC channel1 with DAC_OUT1 (PA4) as output or connected to on-chip + peripherals (ex. ADC). + (#) DAC channel2 with DAC_OUT2 (PA5) as output or connected to on-chip + peripherals (ex. ADC). + + *** DAC Triggers *** + ==================== + [..] + Digital to Analog conversion can be non-triggered using DAC_TRIGGER_NONE + and DAC_OUT1/DAC_OUT2 is available once writing to DHRx register. + [..] + Digital to Analog conversion can be triggered by: + (#) External event: EXTI Line 9 (any GPIOx_PIN_9) using DAC_TRIGGER_EXT_IT9. + The used pin (GPIOx_PIN_9) must be configured in input mode. + + (#) Timers TRGO: TIM1, TIM2, TIM3, TIM4, TIM5, TIM6, TIM7, TIM8 and TIM15 + (DAC_TRIGGER_T1_TRGO, DAC_TRIGGER_T2_TRGO...) + + (#) Low Power Timers CH1: LPTIM1 and LPTIM2 + (DAC_TRIGGER_LPTIM1_CH1, DAC_TRIGGER_LPTIM2_CH1) + + (#) Software using DAC_TRIGGER_SOFTWARE + [..] + The trigger selection depends on the PWR mode: + in stop0, stop1 and stop2 we should select DAC_TRIGGER_EXT_IT9, + DAC_TRIGGER_LPTIM1_CH1 or DAC_TRIGGER_LPTIM2_CH1.The other triggers + are not functional. + *** DAC Buffer mode feature *** + =============================== + [..] + Each DAC channel integrates an output buffer that can be used to + reduce the output impedance, and to drive external loads directly + without having to add an external operational amplifier. + To enable, the output buffer use + sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE; + [..] + (@) Refer to the device datasheet for more details about output + impedance value with and without output buffer. + + *** GPIO configurations guidelines *** + ===================== + [..] + When a DAC channel is used (ex channel1 on PA4) and the other is not + (ex channel2 on PA5 is configured in Analog and disabled). + Channel1 may disturb channel2 as coupling effect. + Note that there is no coupling on channel2 as soon as channel2 is turned on. + Coupling on adjacent channel could be avoided as follows: + when unused PA5 is configured as INPUT PULL-UP or DOWN. + PA5 is configured in ANALOG just before it is turned on. + + *** DAC Sample and Hold feature *** + ======================== + [..] + For each converter, 2 modes are supported: normal mode and + "sample and hold" mode (i.e. low power mode). + In the sample and hold mode, the DAC core converts data, then holds the + converted voltage on a capacitor. When not converting, the DAC cores and + buffer are completely turned off between samples and the DAC output is + tri-stated, therefore reducing the overall power consumption. A new + stabilization period is needed before each new conversion. + + The sample and hold allow setting internal or external voltage @ + low power consumption cost (output value can be at any given rate either + by CPU or DMA). + + The Sample and hold block and registers uses either LSI & run in + several power modes: run mode, sleep mode, low power run, low power sleep + mode & stop1 mode. + + Low power stop1 mode allows only static conversion. + + To enable Sample and Hold mode + Enable LSI using HAL_RCC_OscConfig with RCC_OSCILLATORTYPE_LSI & + RCC_LSI_ON parameters. + + Use DAC_InitStructure.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_ENABLE; + & DAC_ChannelConfTypeDef.DAC_SampleAndHoldConfig.DAC_SampleTime, + DAC_HoldTime & DAC_RefreshTime; + + *** DAC calibration feature *** + =================================== + [..] + (#) The 2 converters (channel1 & channel2) provide calibration capabilities. + (++) Calibration aims at correcting some offset of output buffer. + (++) The DAC uses either factory calibration settings OR user defined + calibration (trimming) settings (i.e. trimming mode). + (++) The user defined settings can be figured out using self calibration + handled by HAL_DACEx_SelfCalibrate. + (++) HAL_DACEx_SelfCalibrate: + (+++) Runs automatically the calibration. + (+++) Enables the user trimming mode + (+++) Updates a structure with trimming values with fresh calibration + results. + The user may store the calibration results for larger + (ex monitoring the trimming as a function of temperature + for instance) + + *** DAC wave generation feature *** + =================================== + [..] + Both DAC channels can be used to generate + (#) Noise wave + (#) Triangle wave + + *** DAC data format *** + ======================= + [..] + The DAC data format can be: + (#) 8-bit right alignment using DAC_ALIGN_8B_R + (#) 12-bit left alignment using DAC_ALIGN_12B_L + (#) 12-bit right alignment using DAC_ALIGN_12B_R + + *** DAC data value to voltage correspondence *** + ================================================ + [..] + The analog output voltage on each DAC channel pin is determined + by the following equation: + [..] + DAC_OUTx = VREF+ * DOR / 4095 + (+) with DOR is the Data Output Register + [..] + VREF+ is the input voltage reference (refer to the device datasheet) + [..] + e.g. To set DAC_OUT1 to 0.7V, use + (+) Assuming that VREF+ = 3.3V, DAC_OUT1 = (3.3 * 868) / 4095 = 0.7V + + *** DMA requests *** + ===================== + [..] + A DMA request can be generated when an external trigger (but not a software trigger) + occurs if DMA requests are enabled using HAL_DAC_Start_DMA(). + DMA requests are mapped as following: + GPDMA requests are mapped as following: + (+) DAC channel1 mapped on GPDMA request 2 (can be any GPDMA channel) + (+) DAC channel2 mapped on GPDMA request 3 (can be any GPDMA channel) + + *** High frequency interface mode *** + ===================================== + [..] + The high frequency interface informs DAC instance about the bus frequency in use. + It is mandatory information for DAC (as internal timing of DAC is bus frequency dependent) + provided thanks to parameter DAC_HighFrequency handled in HAL_DAC_ConfigChannel () function. + Use of DAC_HIGH_FREQUENCY_INTERFACE_MODE_AUTOMATIC value of DAC_HighFrequency is recommended + function figured out the correct setting. + The high frequency mode is same for all converters of a same DAC instance. Either same + parameter DAC_HighFrequency is used for all DAC converters or again self + DAC_HIGH_FREQUENCY_INTERFACE_MODE_AUTOMATIC detection parameter. + + [..] + (@) For Dual mode and specific signal (Triangle and noise) generation please + refer to Extended Features Driver description + + ##### How to use this driver ##### + ============================================================================== + [..] + (+) DAC APB clock must be enabled to get write access to DAC + registers using HAL_DAC_Init() + (+) Configure DAC_OUTx (DAC_OUT1: PA4, DAC_OUT2: PA5) in analog mode. + (+) Configure the DAC channel using HAL_DAC_ConfigChannel() function. + (+) Enable the DAC channel using HAL_DAC_Start() or HAL_DAC_Start_DMA() functions. + + *** Calibration mode IO operation *** + ====================================== + [..] + (+) Retrieve the factory trimming (calibration settings) using HAL_DACEx_GetTrimOffset() + (+) Run the calibration using HAL_DACEx_SelfCalibrate() + (+) Update the trimming while DAC running using HAL_DACEx_SetUserTrimming() + + *** Polling mode IO operation *** + ================================= + [..] + (+) Start the DAC peripheral using HAL_DAC_Start() + (+) To read the DAC last data output value, use the HAL_DAC_GetValue() function. + (+) Stop the DAC peripheral using HAL_DAC_Stop() + + *** DMA mode IO operation *** + ============================== + [..] + (+) Start the DAC peripheral using HAL_DAC_Start_DMA(), at this stage the user specify the length + of data to be transferred at each end of conversion + First issued trigger will start the conversion of the value previously set by HAL_DAC_SetValue(). + (+) At the middle of data transfer HAL_DAC_ConvHalfCpltCallbackCh1() or HAL_DACEx_ConvHalfCpltCallbackCh2() + function is executed and user can add his own code by customization of function pointer + HAL_DAC_ConvHalfCpltCallbackCh1() or HAL_DACEx_ConvHalfCpltCallbackCh2() + (+) At The end of data transfer HAL_DAC_ConvCpltCallbackCh1() or HAL_DACEx_ConvHalfCpltCallbackCh2() + function is executed and user can add his own code by customization of function pointer + HAL_DAC_ConvCpltCallbackCh1() or HAL_DACEx_ConvHalfCpltCallbackCh2() + (+) In case of transfer Error, HAL_DAC_ErrorCallbackCh1() function is executed and user can + add his own code by customization of function pointer HAL_DAC_ErrorCallbackCh1 + (+) In case of DMA underrun, DAC interruption triggers and execute internal function HAL_DAC_IRQHandler. + HAL_DAC_DMAUnderrunCallbackCh1() or HAL_DACEx_DMAUnderrunCallbackCh2() + function is executed and user can add his own code by customization of function pointer + HAL_DAC_DMAUnderrunCallbackCh1() or HAL_DACEx_DMAUnderrunCallbackCh2() and + add his own code by customization of function pointer HAL_DAC_ErrorCallbackCh1() + (+) Stop the DAC peripheral using HAL_DAC_Stop_DMA() + + *** Callback registration *** + ============================================= + [..] + The compilation define USE_HAL_DAC_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + + Use Functions HAL_DAC_RegisterCallback() to register a user callback, + it allows to register following callbacks: + (+) ConvCpltCallbackCh1 : callback when a half transfer is completed on Ch1. + (+) ConvHalfCpltCallbackCh1 : callback when a transfer is completed on Ch1. + (+) ErrorCallbackCh1 : callback when an error occurs on Ch1. + (+) DMAUnderrunCallbackCh1 : callback when an underrun error occurs on Ch1. + (+) ConvCpltCallbackCh2 : callback when a half transfer is completed on Ch2. + (+) ConvHalfCpltCallbackCh2 : callback when a transfer is completed on Ch2. + (+) ErrorCallbackCh2 : callback when an error occurs on Ch2. + (+) DMAUnderrunCallbackCh2 : callback when an underrun error occurs on Ch2. + (+) MspInitCallback : DAC MspInit. + (+) MspDeInitCallback : DAC MspdeInit. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + + Use function HAL_DAC_UnRegisterCallback() to reset a callback to the default + weak (overridden) function. It allows to reset following callbacks: + (+) ConvCpltCallbackCh1 : callback when a half transfer is completed on Ch1. + (+) ConvHalfCpltCallbackCh1 : callback when a transfer is completed on Ch1. + (+) ErrorCallbackCh1 : callback when an error occurs on Ch1. + (+) DMAUnderrunCallbackCh1 : callback when an underrun error occurs on Ch1. + (+) ConvCpltCallbackCh2 : callback when a half transfer is completed on Ch2. + (+) ConvHalfCpltCallbackCh2 : callback when a transfer is completed on Ch2. + (+) ErrorCallbackCh2 : callback when an error occurs on Ch2. + (+) DMAUnderrunCallbackCh2 : callback when an underrun error occurs on Ch2. + (+) MspInitCallback : DAC MspInit. + (+) MspDeInitCallback : DAC MspdeInit. + (+) All Callbacks + This function) takes as parameters the HAL peripheral handle and the Callback ID. + + By default, after the HAL_DAC_Init and if the state is HAL_DAC_STATE_RESET + all callbacks are reset to the corresponding legacy weak (overridden) functions. + Exception done for MspInit and MspDeInit callbacks that are respectively + reset to the legacy weak (overridden) functions in the HAL_DAC_Init + and HAL_DAC_DeInit only when these callbacks are null (not registered beforehand). + If not, MspInit or MspDeInit are not null, the HAL_DAC_Init and HAL_DAC_DeInit + keep and use the user MspInit/MspDeInit callbacks (registered beforehand) + + Callbacks can be registered/unregistered in READY state only. + Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered + in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used + during the Init/DeInit. + In that case first register the MspInit/MspDeInit user callbacks + using HAL_DAC_RegisterCallback before calling HAL_DAC_DeInit + or HAL_DAC_Init function. + + When The compilation define USE_HAL_DAC_REGISTER_CALLBACKS is set to 0 or + not defined, the callback registering feature is not available + and weak (overridden) callbacks are used. + + *** DAC HAL driver macros list *** + ============================================= + [..] + Below the list of most used macros in DAC HAL driver. + + (+) __HAL_DAC_ENABLE : Enable the DAC peripheral + (+) __HAL_DAC_DISABLE : Disable the DAC peripheral + (+) __HAL_DAC_CLEAR_FLAG: Clear the DAC's pending flags + (+) __HAL_DAC_GET_FLAG: Get the selected DAC's flag status + + [..] + (@) You can refer to the DAC HAL driver header file for more useful macros + +@endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +#ifdef HAL_DAC_MODULE_ENABLED +#if defined(DAC1) + +/** @defgroup DAC DAC + * @brief DAC driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @addtogroup DAC_Private_Constants DAC Private Constants + * @{ + */ +#define TIMEOUT_DAC_CALIBCONFIG 1U /* 1 ms */ +#define HFSEL_ENABLE_THRESHOLD_80MHZ 80000000U /* 80 MHz */ +#define HFSEL_ENABLE_THRESHOLD_160MHZ 160000000U /* 160 MHz */ + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions -------------------------------------------------------*/ + +/** @defgroup DAC_Exported_Functions DAC Exported Functions + * @{ + */ + +/** @defgroup DAC_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 DAC. + (+) De-initialize the DAC. + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the DAC peripheral according to the specified parameters + * in the DAC_InitStruct and initialize the associated handle. + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DAC_Init(DAC_HandleTypeDef *hdac) +{ + /* Check the DAC peripheral handle */ + if (hdac == NULL) + { + return HAL_ERROR; + } + /* Check the parameters */ + assert_param(IS_DAC_ALL_INSTANCE(hdac->Instance)); + + if (hdac->State == HAL_DAC_STATE_RESET) + { +#if (USE_HAL_DAC_REGISTER_CALLBACKS == 1) + /* Init the DAC Callback settings */ + hdac->ConvCpltCallbackCh1 = HAL_DAC_ConvCpltCallbackCh1; + hdac->ConvHalfCpltCallbackCh1 = HAL_DAC_ConvHalfCpltCallbackCh1; + hdac->ErrorCallbackCh1 = HAL_DAC_ErrorCallbackCh1; + hdac->DMAUnderrunCallbackCh1 = HAL_DAC_DMAUnderrunCallbackCh1; + + hdac->ConvCpltCallbackCh2 = HAL_DACEx_ConvCpltCallbackCh2; + hdac->ConvHalfCpltCallbackCh2 = HAL_DACEx_ConvHalfCpltCallbackCh2; + hdac->ErrorCallbackCh2 = HAL_DACEx_ErrorCallbackCh2; + hdac->DMAUnderrunCallbackCh2 = HAL_DACEx_DMAUnderrunCallbackCh2; + + if (hdac->MspInitCallback == NULL) + { + hdac->MspInitCallback = HAL_DAC_MspInit; + } +#endif /* USE_HAL_DAC_REGISTER_CALLBACKS */ + + /* Allocate lock resource and initialize it */ + hdac->Lock = HAL_UNLOCKED; + +#if (USE_HAL_DAC_REGISTER_CALLBACKS == 1) + /* Init the low level hardware */ + hdac->MspInitCallback(hdac); +#else + /* Init the low level hardware */ + HAL_DAC_MspInit(hdac); +#endif /* USE_HAL_DAC_REGISTER_CALLBACKS */ + } + + /* Initialize the DAC state*/ + hdac->State = HAL_DAC_STATE_BUSY; + + /* Set DAC error code to none */ + hdac->ErrorCode = HAL_DAC_ERROR_NONE; + + /* Initialize the DAC state*/ + hdac->State = HAL_DAC_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Deinitialize the DAC peripheral registers to their default reset values. + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DAC_DeInit(DAC_HandleTypeDef *hdac) +{ + /* Check the DAC peripheral handle */ + if (hdac == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DAC_ALL_INSTANCE(hdac->Instance)); + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_BUSY; + +#if (USE_HAL_DAC_REGISTER_CALLBACKS == 1) + if (hdac->MspDeInitCallback == NULL) + { + hdac->MspDeInitCallback = HAL_DAC_MspDeInit; + } + /* DeInit the low level hardware */ + hdac->MspDeInitCallback(hdac); +#else + /* DeInit the low level hardware */ + HAL_DAC_MspDeInit(hdac); +#endif /* USE_HAL_DAC_REGISTER_CALLBACKS */ + + /* Set DAC error code to none */ + hdac->ErrorCode = HAL_DAC_ERROR_NONE; + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hdac); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initialize the DAC MSP. + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval None + */ +__weak void HAL_DAC_MspInit(DAC_HandleTypeDef *hdac) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdac); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_DAC_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitialize the DAC MSP. + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval None + */ +__weak void HAL_DAC_MspDeInit(DAC_HandleTypeDef *hdac) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdac); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_DAC_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup DAC_Exported_Functions_Group2 IO operation functions + * @brief IO operation functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) Start conversion. + (+) Stop conversion. + (+) Start conversion and enable DMA transfer. + (+) Stop conversion and disable DMA transfer. + (+) Get result of conversion. + +@endverbatim + * @{ + */ + +/** + * @brief Enables DAC and starts conversion of channel. + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @param Channel The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DAC_Start(DAC_HandleTypeDef *hdac, uint32_t Channel) +{ + __IO uint32_t wait_loop_index; + + /* Check the DAC peripheral handle */ + if (hdac == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(Channel)); + + /* Process locked */ + __HAL_LOCK(hdac); + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_BUSY; + + /* Enable the Peripheral */ + __HAL_DAC_ENABLE(hdac, Channel); + /* Ensure minimum wait before using peripheral after enabling it */ + /* Wait loop initialization and execution */ + /* Note: Variable divided by 2 to compensate partially CPU processing cycles, scaling in us split to not exceed 32 */ + /* bits register capacity and handle low frequency. */ + wait_loop_index = ((DAC_DELAY_STARTUP_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL)); + while (wait_loop_index != 0UL) + { + wait_loop_index--; + } + + if (Channel == DAC_CHANNEL_1) + { + /* Check if software trigger enabled */ + if ((hdac->Instance->CR & (DAC_CR_TEN1 | DAC_CR_TSEL1)) == DAC_TRIGGER_SOFTWARE) + { + /* Enable the selected DAC software conversion */ + SET_BIT(hdac->Instance->SWTRIGR, DAC_SWTRIGR_SWTRIG1); + } + } + + else + { + /* Check if software trigger enabled */ + if ((hdac->Instance->CR & (DAC_CR_TEN2 | DAC_CR_TSEL2)) == (DAC_TRIGGER_SOFTWARE << (Channel & 0x10UL))) + { + /* Enable the selected DAC software conversion*/ + SET_BIT(hdac->Instance->SWTRIGR, DAC_SWTRIGR_SWTRIG2); + } + } + + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hdac); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Disables DAC and stop conversion of channel. + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @param Channel The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DAC_Stop(DAC_HandleTypeDef *hdac, uint32_t Channel) +{ + /* Check the DAC peripheral handle */ + if (hdac == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(Channel)); + + /* Disable the Peripheral */ + __HAL_DAC_DISABLE(hdac, Channel); + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Enables DAC and starts conversion of channel. + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @param Channel The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @param pData The source Buffer address. + * @param Length The length of data to be transferred from memory to DAC peripheral + * @param Alignment Specifies the data alignment for DAC channel. + * This parameter can be one of the following values: + * @arg DAC_ALIGN_8B_R: 8bit right data alignment selected + * @arg DAC_ALIGN_12B_L: 12bit left data alignment selected + * @arg DAC_ALIGN_12B_R: 12bit right data alignment selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DAC_Start_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel, const uint32_t *pData, uint32_t Length, + uint32_t Alignment) +{ + HAL_StatusTypeDef status; + uint32_t tmpreg; + uint32_t LengthInBytes; + DMA_NodeConfTypeDef node_conf; + __IO uint32_t wait_loop_index; + + /* Check the DAC peripheral handle */ + if (hdac == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(Channel)); + assert_param(IS_DAC_ALIGN(Alignment)); + + /* Process locked */ + __HAL_LOCK(hdac); + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_BUSY; + + if (Channel == DAC_CHANNEL_1) + { + /* Set the DMA transfer complete callback for channel1 */ + hdac->DMA_Handle1->XferCpltCallback = DAC_DMAConvCpltCh1; + + /* Set the DMA half transfer complete callback for channel1 */ + hdac->DMA_Handle1->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh1; + + /* Set the DMA error callback for channel1 */ + hdac->DMA_Handle1->XferErrorCallback = DAC_DMAErrorCh1; + + /* Enable the selected DAC channel1 DMA request */ + SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN1); + + /* Case of use of channel 1 */ + switch (Alignment) + { + case DAC_ALIGN_12B_R: + /* Get DHR12R1 address */ + tmpreg = (uint32_t)&hdac->Instance->DHR12R1; + break; + case DAC_ALIGN_12B_L: + /* Get DHR12L1 address */ + tmpreg = (uint32_t)&hdac->Instance->DHR12L1; + break; + default: /* case DAC_ALIGN_8B_R */ + /* Get DHR8R1 address */ + tmpreg = (uint32_t)&hdac->Instance->DHR8R1; + break; + } + } + + else + { + /* Set the DMA transfer complete callback for channel2 */ + hdac->DMA_Handle2->XferCpltCallback = DAC_DMAConvCpltCh2; + + /* Set the DMA half transfer complete callback for channel2 */ + hdac->DMA_Handle2->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh2; + + /* Set the DMA error callback for channel2 */ + hdac->DMA_Handle2->XferErrorCallback = DAC_DMAErrorCh2; + + /* Enable the selected DAC channel2 DMA request */ + SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN2); + + /* Case of use of channel 2 */ + switch (Alignment) + { + case DAC_ALIGN_12B_R: + /* Get DHR12R2 address */ + tmpreg = (uint32_t)&hdac->Instance->DHR12R2; + break; + case DAC_ALIGN_12B_L: + /* Get DHR12L2 address */ + tmpreg = (uint32_t)&hdac->Instance->DHR12L2; + break; + default: /* case DAC_ALIGN_8B_R */ + /* Get DHR8R2 address */ + tmpreg = (uint32_t)&hdac->Instance->DHR8R2; + break; + } + } + + if (Channel == DAC_CHANNEL_1) + { + /* Enable the DAC DMA underrun interrupt */ + __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR1); + + /* Enable the DMA channel */ + /* Check linkedlist mode */ + if ((hdac->DMA_Handle1->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hdac->DMA_Handle1->LinkedListQueue != NULL) && (hdac->DMA_Handle1->LinkedListQueue->Head != NULL)) + { + /* Length should be converted to number of bytes */ + if (HAL_DMAEx_List_GetNodeConfig(&node_conf, hdac->DMA_Handle1->LinkedListQueue->Head) != HAL_OK) + { + return HAL_ERROR; + } + + /* Length should be converted to number of bytes */ + if (node_conf.Init.SrcDataWidth == DMA_SRC_DATAWIDTH_WORD) + { + /* Word -> Bytes */ + LengthInBytes = Length * 4U; + } + else if (node_conf.Init.SrcDataWidth == DMA_SRC_DATAWIDTH_HALFWORD) + { + /* Halfword -> Bytes */ + LengthInBytes = Length * 2U; + } + else /* Bytes */ + { + /* Same size already expressed in Bytes */ + LengthInBytes = Length; + } + + /* Set DMA data size */ + hdac->DMA_Handle1->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = LengthInBytes; + + /* Set DMA source address */ + hdac->DMA_Handle1->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)pData; + + /* Set DMA destination address */ + hdac->DMA_Handle1->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = tmpreg; + + /* Enable the DMA channel */ + status = HAL_DMAEx_List_Start_IT(hdac->DMA_Handle1); + } + else + { + /* Return error status */ + return HAL_ERROR; + } + } + else + { + /* Length should be converted to number of bytes */ + if (hdac->DMA_Handle1->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_WORD) + { + /* Word -> Bytes */ + LengthInBytes = Length * 4U; + } + else if (hdac->DMA_Handle1->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_HALFWORD) + { + /* Halfword -> Bytes */ + LengthInBytes = Length * 2U; + } + else /* Bytes */ + { + /* Same size already expressed in Bytes */ + LengthInBytes = Length; + } + + /* Enable the DMA channel */ + status = HAL_DMA_Start_IT(hdac->DMA_Handle1, (uint32_t)pData, tmpreg, LengthInBytes); + } + } + + else + { + /* Enable the DAC DMA underrun interrupt */ + __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR2); + + /* Enable the DMA channel */ + /* Check linkedlist mode */ + if ((hdac->DMA_Handle2->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hdac->DMA_Handle2->LinkedListQueue != NULL) && (hdac->DMA_Handle2->LinkedListQueue->Head != NULL)) + { + /* Length should be converted to number of bytes */ + if (HAL_DMAEx_List_GetNodeConfig(&node_conf, hdac->DMA_Handle2->LinkedListQueue->Head) != HAL_OK) + { + return HAL_ERROR; + } + + /* Length should be converted to number of bytes */ + if (node_conf.Init.SrcDataWidth == DMA_SRC_DATAWIDTH_WORD) + { + /* Word -> Bytes */ + LengthInBytes = Length * 4U; + } + else if (node_conf.Init.SrcDataWidth == DMA_SRC_DATAWIDTH_HALFWORD) + { + /* Halfword -> Bytes */ + LengthInBytes = Length * 2U; + } + else /* Bytes */ + { + /* Same size already expressed in Bytes */ + LengthInBytes = Length; + } + + /* Set DMA data size */ + hdac->DMA_Handle2->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = LengthInBytes; + + /* Set DMA source address */ + hdac->DMA_Handle2->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)pData; + + /* Set DMA destination address */ + hdac->DMA_Handle2->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = tmpreg; + + /* Enable the DMA channel */ + status = HAL_DMAEx_List_Start_IT(hdac->DMA_Handle2); + } + else + { + /* Return error status */ + return HAL_ERROR; + } + } + else + { + /* Length should be converted to number of bytes */ + if (hdac->DMA_Handle2->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_WORD) + { + /* Word -> Bytes */ + LengthInBytes = Length * 4U; + } + else if (hdac->DMA_Handle2->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_HALFWORD) + { + /* Halfword -> Bytes */ + LengthInBytes = Length * 2U; + } + else /* Bytes */ + { + /* Same size already expressed in Bytes */ + LengthInBytes = Length; + } + + /* Enable the DMA channel */ + status = HAL_DMA_Start_IT(hdac->DMA_Handle2, (uint32_t)pData, tmpreg, LengthInBytes); + } + } + + + /* Process Unlocked */ + __HAL_UNLOCK(hdac); + + if (status == HAL_OK) + { + /* Enable the Peripheral */ + __HAL_DAC_ENABLE(hdac, Channel); + /* Ensure minimum wait before using peripheral after enabling it */ + /* Wait loop initialization and execution */ + /* Note: Variable divided by 2 to compensate partially */ + /* CPU processing cycles, scaling in us split to not */ + /* exceed 32 bits register capacity and handle low frequency. */ + wait_loop_index = ((DAC_DELAY_STARTUP_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL)); + while (wait_loop_index != 0UL) + { + wait_loop_index--; + } + } + else + { + hdac->ErrorCode |= HAL_DAC_ERROR_DMA; + } + + /* Return function status */ + return status; +} + +/** + * @brief Disables DAC and stop conversion of channel. + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @param Channel The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DAC_Stop_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel) +{ + /* Check the DAC peripheral handle */ + if (hdac == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(Channel)); + + /* Disable the selected DAC channel DMA request */ + hdac->Instance->CR &= ~(DAC_CR_DMAEN1 << (Channel & 0x10UL)); + + /* Disable the Peripheral */ + __HAL_DAC_DISABLE(hdac, Channel); + + /* Disable the DMA channel */ + + /* Channel1 is used */ + if (Channel == DAC_CHANNEL_1) + { + /* Disable the DMA channel */ + (void)HAL_DMA_Abort(hdac->DMA_Handle1); + + /* Disable the DAC DMA underrun interrupt */ + __HAL_DAC_DISABLE_IT(hdac, DAC_IT_DMAUDR1); + } + + else /* Channel2 is used for */ + { + /* Disable the DMA channel */ + (void)HAL_DMA_Abort(hdac->DMA_Handle2); + + /* Disable the DAC DMA underrun interrupt */ + __HAL_DAC_DISABLE_IT(hdac, DAC_IT_DMAUDR2); + } + + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Handles DAC interrupt request + * This function uses the interruption of DMA + * underrun. + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval None + */ +void HAL_DAC_IRQHandler(DAC_HandleTypeDef *hdac) +{ + uint32_t itsource = hdac->Instance->CR; + uint32_t itflag = hdac->Instance->SR; + + if ((itsource & DAC_IT_DMAUDR1) == DAC_IT_DMAUDR1) + { + /* Check underrun flag of DAC channel 1 */ + if ((itflag & DAC_FLAG_DMAUDR1) == DAC_FLAG_DMAUDR1) + { + /* Change DAC state to error state */ + hdac->State = HAL_DAC_STATE_ERROR; + + /* Set DAC error code to channel1 DMA underrun error */ + SET_BIT(hdac->ErrorCode, HAL_DAC_ERROR_DMAUNDERRUNCH1); + + /* Clear the underrun flag */ + __HAL_DAC_CLEAR_FLAG(hdac, DAC_FLAG_DMAUDR1); + + /* Disable the selected DAC channel1 DMA request */ + __HAL_DAC_DISABLE_IT(hdac, DAC_CR_DMAEN1); + + /* Error callback */ +#if (USE_HAL_DAC_REGISTER_CALLBACKS == 1) + hdac->DMAUnderrunCallbackCh1(hdac); +#else + HAL_DAC_DMAUnderrunCallbackCh1(hdac); +#endif /* USE_HAL_DAC_REGISTER_CALLBACKS */ + } + } + + + if ((itsource & DAC_IT_DMAUDR2) == DAC_IT_DMAUDR2) + { + /* Check underrun flag of DAC channel 2 */ + if ((itflag & DAC_FLAG_DMAUDR2) == DAC_FLAG_DMAUDR2) + { + /* Change DAC state to error state */ + hdac->State = HAL_DAC_STATE_ERROR; + + /* Set DAC error code to channel2 DMA underrun error */ + SET_BIT(hdac->ErrorCode, HAL_DAC_ERROR_DMAUNDERRUNCH2); + + /* Clear the underrun flag */ + __HAL_DAC_CLEAR_FLAG(hdac, DAC_FLAG_DMAUDR2); + + /* Disable the selected DAC channel2 DMA request */ + __HAL_DAC_DISABLE_IT(hdac, DAC_CR_DMAEN2); + + /* Error callback */ +#if (USE_HAL_DAC_REGISTER_CALLBACKS == 1) + hdac->DMAUnderrunCallbackCh2(hdac); +#else + HAL_DACEx_DMAUnderrunCallbackCh2(hdac); +#endif /* USE_HAL_DAC_REGISTER_CALLBACKS */ + } + } + +} + +/** + * @brief Set the specified data holding register value for DAC channel. + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @param Channel The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @param Alignment Specifies the data alignment. + * This parameter can be one of the following values: + * @arg DAC_ALIGN_8B_R: 8bit right data alignment selected + * @arg DAC_ALIGN_12B_L: 12bit left data alignment selected + * @arg DAC_ALIGN_12B_R: 12bit right data alignment selected + * @param Data Data to be loaded in the selected data holding register. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DAC_SetValue(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Alignment, uint32_t Data) +{ + __IO uint32_t tmp = 0UL; + + /* Check the DAC peripheral handle */ + if (hdac == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(Channel)); + assert_param(IS_DAC_ALIGN(Alignment)); + /* In case DMA Double data mode is activated, DATA range is almost full uin32_t one: no check */ + if ((hdac->Instance->MCR & (DAC_MCR_DMADOUBLE1 << (Channel & 0x10UL))) == 0UL) + { + assert_param(IS_DAC_DATA(Data)); + } + + tmp = (uint32_t)hdac->Instance; + if (Channel == DAC_CHANNEL_1) + { + tmp += DAC_DHR12R1_ALIGNMENT(Alignment); + } + + else + { + tmp += DAC_DHR12R2_ALIGNMENT(Alignment); + } + + + /* Set the DAC channel selected data holding register */ + *(__IO uint32_t *) tmp = Data; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Conversion complete callback in non-blocking mode for Channel1 + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval None + */ +__weak void HAL_DAC_ConvCpltCallbackCh1(DAC_HandleTypeDef *hdac) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdac); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_DAC_ConvCpltCallbackCh1 could be implemented in the user file + */ +} + +/** + * @brief Conversion half DMA transfer callback in non-blocking mode for Channel1 + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval None + */ +__weak void HAL_DAC_ConvHalfCpltCallbackCh1(DAC_HandleTypeDef *hdac) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdac); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_DAC_ConvHalfCpltCallbackCh1 could be implemented in the user file + */ +} + +/** + * @brief Error DAC callback for Channel1. + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval None + */ +__weak void HAL_DAC_ErrorCallbackCh1(DAC_HandleTypeDef *hdac) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdac); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_DAC_ErrorCallbackCh1 could be implemented in the user file + */ +} + +/** + * @brief DMA underrun DAC callback for channel1. + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval None + */ +__weak void HAL_DAC_DMAUnderrunCallbackCh1(DAC_HandleTypeDef *hdac) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdac); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_DAC_DMAUnderrunCallbackCh1 could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup DAC_Exported_Functions_Group3 Peripheral Control functions + * @brief Peripheral Control functions + * +@verbatim + ============================================================================== + ##### Peripheral Control functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) Configure channels. + (+) Set the specified data holding register value for DAC channel. + +@endverbatim + * @{ + */ + +/** + * @brief Returns the last data output value of the selected DAC channel. + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @param Channel The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @retval The selected DAC channel data output value. + */ +uint32_t HAL_DAC_GetValue(const DAC_HandleTypeDef *hdac, uint32_t Channel) +{ + uint32_t result; + + /* Check the DAC peripheral handle */ + assert_param(hdac != NULL); + + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(Channel)); + + if (Channel == DAC_CHANNEL_1) + { + result = hdac->Instance->DOR1; + } + + else + { + result = hdac->Instance->DOR2; + } + + /* Returns the DAC channel data output register value */ + return result; +} + +/** + * @brief Configures the selected DAC channel. + * @note By calling this function, the high frequency interface mode (HFSEL bits) + * will be set. This parameter scope is the DAC instance. As the function + * is called for each channel, the @ref DAC_HighFrequency of @arg sConfig + * must be the same at each call. + * (or DAC_HIGH_FREQUENCY_INTERFACE_MODE_AUTOMATIC self detect). + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @param sConfig DAC configuration structure. + * @param Channel The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DAC_ConfigChannel(DAC_HandleTypeDef *hdac, + const DAC_ChannelConfTypeDef *sConfig, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpreg1; + uint32_t tmpreg2; + uint32_t tickstart; + uint32_t hclkfreq; + uint32_t connectOnChip; + + /* Check the DAC peripheral handle and channel configuration struct */ + if ((hdac == NULL) || (sConfig == NULL)) + { + return HAL_ERROR; + } + + /* Check the DAC parameters */ + assert_param(IS_DAC_HIGH_FREQUENCY_MODE(sConfig->DAC_HighFrequency)); + assert_param(IS_DAC_TRIGGER(sConfig->DAC_Trigger)); + assert_param(IS_DAC_OUTPUT_BUFFER_STATE(sConfig->DAC_OutputBuffer)); + assert_param(IS_DAC_CHIP_CONNECTION(sConfig->DAC_ConnectOnChipPeripheral)); + assert_param(IS_DAC_TRIMMING(sConfig->DAC_UserTrimming)); + if ((sConfig->DAC_UserTrimming) == DAC_TRIMMING_USER) + { + assert_param(IS_DAC_TRIMMINGVALUE(sConfig->DAC_TrimmingValue)); + } + assert_param(IS_DAC_SAMPLEANDHOLD(sConfig->DAC_SampleAndHold)); + if ((sConfig->DAC_SampleAndHold) == DAC_SAMPLEANDHOLD_ENABLE) + { + assert_param(IS_DAC_SAMPLETIME(sConfig->DAC_SampleAndHoldConfig.DAC_SampleTime)); + assert_param(IS_DAC_HOLDTIME(sConfig->DAC_SampleAndHoldConfig.DAC_HoldTime)); + assert_param(IS_DAC_REFRESHTIME(sConfig->DAC_SampleAndHoldConfig.DAC_RefreshTime)); + } + assert_param(IS_DAC_CHANNEL(Channel)); + assert_param(IS_FUNCTIONAL_STATE(sConfig->DAC_DMADoubleDataMode)); + assert_param(IS_FUNCTIONAL_STATE(sConfig->DAC_SignedFormat)); + + /* Process locked */ + __HAL_LOCK(hdac); + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_BUSY; + + /* Sample and hold configuration */ + if (sConfig->DAC_SampleAndHold == DAC_SAMPLEANDHOLD_ENABLE) + { + /* Get timeout */ + tickstart = HAL_GetTick(); + + if (Channel == DAC_CHANNEL_1) + { + /* SHSR1 can be written when BWST1 is cleared */ + while (((hdac->Instance->SR) & DAC_SR_BWST1) != 0UL) + { + /* Check for the Timeout */ + if ((HAL_GetTick() - tickstart) > TIMEOUT_DAC_CALIBCONFIG) + { + /* New check to avoid false timeout detection in case of preemption */ + if (((hdac->Instance->SR) & DAC_SR_BWST1) != 0UL) + { + /* Update error code */ + SET_BIT(hdac->ErrorCode, HAL_DAC_ERROR_TIMEOUT); + + /* Change the DMA state */ + hdac->State = HAL_DAC_STATE_TIMEOUT; + + return HAL_TIMEOUT; + } + } + } + hdac->Instance->SHSR1 = sConfig->DAC_SampleAndHoldConfig.DAC_SampleTime; + } + + else /* Channel 2 */ + { + /* SHSR2 can be written when BWST2 is cleared */ + while (((hdac->Instance->SR) & DAC_SR_BWST2) != 0UL) + { + /* Check for the Timeout */ + if ((HAL_GetTick() - tickstart) > TIMEOUT_DAC_CALIBCONFIG) + { + /* New check to avoid false timeout detection in case of preemption */ + if (((hdac->Instance->SR) & DAC_SR_BWST2) != 0UL) + { + /* Update error code */ + SET_BIT(hdac->ErrorCode, HAL_DAC_ERROR_TIMEOUT); + + /* Change the DMA state */ + hdac->State = HAL_DAC_STATE_TIMEOUT; + + return HAL_TIMEOUT; + } + } + } + hdac->Instance->SHSR2 = sConfig->DAC_SampleAndHoldConfig.DAC_SampleTime; + } + + + /* HoldTime */ + MODIFY_REG(hdac->Instance->SHHR, DAC_SHHR_THOLD1 << (Channel & 0x10UL), + (sConfig->DAC_SampleAndHoldConfig.DAC_HoldTime) << (Channel & 0x10UL)); + /* RefreshTime */ + MODIFY_REG(hdac->Instance->SHRR, DAC_SHRR_TREFRESH1 << (Channel & 0x10UL), + (sConfig->DAC_SampleAndHoldConfig.DAC_RefreshTime) << (Channel & 0x10UL)); + } + + if (sConfig->DAC_UserTrimming == DAC_TRIMMING_USER) + /* USER TRIMMING */ + { + /* Get the DAC CCR value */ + tmpreg1 = hdac->Instance->CCR; + /* Clear trimming value */ + tmpreg1 &= ~(((uint32_t)(DAC_CCR_OTRIM1)) << (Channel & 0x10UL)); + /* Configure for the selected trimming offset */ + tmpreg2 = sConfig->DAC_TrimmingValue; + /* Calculate CCR register value depending on DAC_Channel */ + tmpreg1 |= tmpreg2 << (Channel & 0x10UL); + /* Write to DAC CCR */ + hdac->Instance->CCR = tmpreg1; + } + /* else factory trimming is used (factory setting are available at reset)*/ + /* SW Nothing has nothing to do */ + + /* Get the DAC MCR value */ + tmpreg1 = hdac->Instance->MCR; + /* Clear DAC_MCR_MODEx bits */ + tmpreg1 &= ~(((uint32_t)(DAC_MCR_MODE1)) << (Channel & 0x10UL)); + /* Configure for the selected DAC channel: mode, buffer output & on chip peripheral connect */ + +#if !defined(TIM8) + /* Devices STM32H503xx */ + /* On STM32H503EB (package WLCSP25) DAC channel 1 connection to GPIO is not available and should not be configured. + Package information is stored at the address PACKAGE_BASE, WLCSP25 correspond to the value 0xF (For more + information, please refer to the Reference Manual) */ + const __IO uint16_t *tmp_package = (uint16_t *)PACKAGE_BASE; + if ((*(tmp_package) & 0x1FUL) == 0x0FUL) + { + if ((Channel == DAC_CHANNEL_1) + && ((sConfig->DAC_ConnectOnChipPeripheral == DAC_CHIPCONNECT_EXTERNAL) + || (sConfig->DAC_ConnectOnChipPeripheral == DAC_CHIPCONNECT_BOTH))) + { + /* Update return status */ + status = HAL_ERROR; + + /* Change the DAC state */ + hdac->State = HAL_DAC_STATE_ERROR; + + /* Update error code */ + SET_BIT(hdac->ErrorCode, HAL_DAC_ERROR_INVALID_CONFIG); + } + } +#endif /* Devices STM32H503xx */ + + + if (sConfig->DAC_ConnectOnChipPeripheral == DAC_CHIPCONNECT_EXTERNAL) + { + connectOnChip = 0x00000000UL; + } + else if (sConfig->DAC_ConnectOnChipPeripheral == DAC_CHIPCONNECT_INTERNAL) + { + connectOnChip = DAC_MCR_MODE1_0; + } + else /* (sConfig->DAC_ConnectOnChipPeripheral == DAC_CHIPCONNECT_BOTH) */ + { + if (sConfig->DAC_OutputBuffer == DAC_OUTPUTBUFFER_ENABLE) + { + connectOnChip = DAC_MCR_MODE1_0; + } + else + { + connectOnChip = 0x00000000UL; + } + } + tmpreg2 = (sConfig->DAC_SampleAndHold | sConfig->DAC_OutputBuffer | connectOnChip); + /* Clear DAC_MCR_DMADOUBLEx */ + tmpreg1 &= ~(((uint32_t)(DAC_MCR_DMADOUBLE1)) << (Channel & 0x10UL)); + /* Configure for the selected DAC channel: DMA double data mode */ + tmpreg2 |= (sConfig->DAC_DMADoubleDataMode == ENABLE) ? DAC_MCR_DMADOUBLE1 : 0UL; + /* Clear DAC_MCR_SINFORMATx */ + tmpreg1 &= ~(((uint32_t)(DAC_MCR_SINFORMAT1)) << (Channel & 0x10UL)); + /* Configure for the selected DAC channel: Signed format */ + tmpreg2 |= (sConfig->DAC_SignedFormat == ENABLE) ? DAC_MCR_SINFORMAT1 : 0UL; + /* Clear DAC_MCR_HFSEL bits */ + tmpreg1 &= ~(DAC_MCR_HFSEL); + /* Configure for both DAC channels: high frequency mode */ + if (DAC_HIGH_FREQUENCY_INTERFACE_MODE_AUTOMATIC == sConfig->DAC_HighFrequency) + { + hclkfreq = HAL_RCC_GetHCLKFreq(); + if (hclkfreq > HFSEL_ENABLE_THRESHOLD_160MHZ) + { + tmpreg1 |= DAC_HIGH_FREQUENCY_INTERFACE_MODE_ABOVE_160MHZ; + } + else if (hclkfreq > HFSEL_ENABLE_THRESHOLD_80MHZ) + { + tmpreg1 |= DAC_HIGH_FREQUENCY_INTERFACE_MODE_ABOVE_80MHZ; + } + else + { + tmpreg1 |= DAC_HIGH_FREQUENCY_INTERFACE_MODE_DISABLE; + } + } + else + { + tmpreg1 |= sConfig->DAC_HighFrequency; + } + /* Calculate MCR register value depending on DAC_Channel */ + tmpreg1 |= tmpreg2 << (Channel & 0x10UL); + /* Write to DAC MCR */ + hdac->Instance->MCR = tmpreg1; + + /* DAC in normal operating mode hence clear DAC_CR_CENx bit */ + CLEAR_BIT(hdac->Instance->CR, DAC_CR_CEN1 << (Channel & 0x10UL)); + + /* Get the DAC CR value */ + tmpreg1 = hdac->Instance->CR; + /* Clear TENx, TSELx, WAVEx and MAMPx bits */ + tmpreg1 &= ~(((uint32_t)(DAC_CR_MAMP1 | DAC_CR_WAVE1 | DAC_CR_TSEL1 | DAC_CR_TEN1)) << (Channel & 0x10UL)); + /* Configure for the selected DAC channel: trigger */ + /* Set TSELx and TENx bits according to DAC_Trigger value */ + tmpreg2 = sConfig->DAC_Trigger; + /* Calculate CR register value depending on DAC_Channel */ + tmpreg1 |= tmpreg2 << (Channel & 0x10UL); + /* Write to DAC CR */ + hdac->Instance->CR = tmpreg1; + /* Disable wave generation */ + CLEAR_BIT(hdac->Instance->CR, (DAC_CR_WAVE1 << (Channel & 0x10UL))); + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hdac); + + /* Return function status */ + return status; +} + +/** + * @} + */ + +/** @defgroup DAC_Exported_Functions_Group4 Peripheral State and Errors functions + * @brief Peripheral State and Errors functions + * +@verbatim + ============================================================================== + ##### Peripheral State and Errors functions ##### + ============================================================================== + [..] + This subsection provides functions allowing to + (+) Check the DAC state. + (+) Check the DAC Errors. + +@endverbatim + * @{ + */ + +/** + * @brief return the DAC handle state + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval HAL state + */ +HAL_DAC_StateTypeDef HAL_DAC_GetState(const DAC_HandleTypeDef *hdac) +{ + /* Return DAC handle state */ + return hdac->State; +} + + +/** + * @brief Return the DAC error code + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval DAC Error Code + */ +uint32_t HAL_DAC_GetError(const DAC_HandleTypeDef *hdac) +{ + return hdac->ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup DAC_Exported_Functions + * @{ + */ + +/** @addtogroup DAC_Exported_Functions_Group1 + * @{ + */ +#if (USE_HAL_DAC_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User DAC Callback + * To be used instead of the weak (overridden) predefined callback + * @note The HAL_DAC_RegisterCallback() may be called before HAL_DAC_Init() in HAL_DAC_STATE_RESET to register + * callbacks for HAL_DAC_MSPINIT_CB_ID and HAL_DAC_MSPDEINIT_CB_ID + * @param hdac DAC handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_DAC_ERROR_INVALID_CALLBACK DAC Error Callback ID + * @arg @ref HAL_DAC_CH1_COMPLETE_CB_ID DAC CH1 Complete Callback ID + * @arg @ref HAL_DAC_CH1_HALF_COMPLETE_CB_ID DAC CH1 Half Complete Callback ID + * @arg @ref HAL_DAC_CH1_ERROR_ID DAC CH1 Error Callback ID + * @arg @ref HAL_DAC_CH1_UNDERRUN_CB_ID DAC CH1 UnderRun Callback ID + * @arg @ref HAL_DAC_CH2_COMPLETE_CB_ID DAC CH2 Complete Callback ID + * @arg @ref HAL_DAC_CH2_HALF_COMPLETE_CB_ID DAC CH2 Half Complete Callback ID + * @arg @ref HAL_DAC_CH2_ERROR_ID DAC CH2 Error Callback ID + * @arg @ref HAL_DAC_CH2_UNDERRUN_CB_ID DAC CH2 UnderRun Callback ID + * @arg @ref HAL_DAC_MSPINIT_CB_ID DAC MSP Init Callback ID + * @arg @ref HAL_DAC_MSPDEINIT_CB_ID DAC MSP DeInit Callback ID + * + * @param pCallback pointer to the Callback function + * @retval status + */ +HAL_StatusTypeDef HAL_DAC_RegisterCallback(DAC_HandleTypeDef *hdac, HAL_DAC_CallbackIDTypeDef CallbackID, + pDAC_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the DAC peripheral handle */ + if (hdac == NULL) + { + return HAL_ERROR; + } + + if (pCallback == NULL) + { + /* Update the error code */ + hdac->ErrorCode |= HAL_DAC_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + + if (hdac->State == HAL_DAC_STATE_READY) + { + switch (CallbackID) + { + case HAL_DAC_CH1_COMPLETE_CB_ID : + hdac->ConvCpltCallbackCh1 = pCallback; + break; + case HAL_DAC_CH1_HALF_COMPLETE_CB_ID : + hdac->ConvHalfCpltCallbackCh1 = pCallback; + break; + case HAL_DAC_CH1_ERROR_ID : + hdac->ErrorCallbackCh1 = pCallback; + break; + case HAL_DAC_CH1_UNDERRUN_CB_ID : + hdac->DMAUnderrunCallbackCh1 = pCallback; + break; + + case HAL_DAC_CH2_COMPLETE_CB_ID : + hdac->ConvCpltCallbackCh2 = pCallback; + break; + case HAL_DAC_CH2_HALF_COMPLETE_CB_ID : + hdac->ConvHalfCpltCallbackCh2 = pCallback; + break; + case HAL_DAC_CH2_ERROR_ID : + hdac->ErrorCallbackCh2 = pCallback; + break; + case HAL_DAC_CH2_UNDERRUN_CB_ID : + hdac->DMAUnderrunCallbackCh2 = pCallback; + break; + + case HAL_DAC_MSPINIT_CB_ID : + hdac->MspInitCallback = pCallback; + break; + case HAL_DAC_MSPDEINIT_CB_ID : + hdac->MspDeInitCallback = pCallback; + break; + default : + /* Update the error code */ + hdac->ErrorCode |= HAL_DAC_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else if (hdac->State == HAL_DAC_STATE_RESET) + { + switch (CallbackID) + { + case HAL_DAC_MSPINIT_CB_ID : + hdac->MspInitCallback = pCallback; + break; + case HAL_DAC_MSPDEINIT_CB_ID : + hdac->MspDeInitCallback = pCallback; + break; + default : + /* Update the error code */ + hdac->ErrorCode |= HAL_DAC_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hdac->ErrorCode |= HAL_DAC_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister a User DAC Callback + * DAC Callback is redirected to the weak (overridden) predefined callback + * @note The HAL_DAC_UnRegisterCallback() may be called before HAL_DAC_Init() in HAL_DAC_STATE_RESET to un-register + * callbacks for HAL_DAC_MSPINIT_CB_ID and HAL_DAC_MSPDEINIT_CB_ID + * @param hdac DAC handle + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_DAC_CH1_COMPLETE_CB_ID DAC CH1 transfer Complete Callback ID + * @arg @ref HAL_DAC_CH1_HALF_COMPLETE_CB_ID DAC CH1 Half Complete Callback ID + * @arg @ref HAL_DAC_CH1_ERROR_ID DAC CH1 Error Callback ID + * @arg @ref HAL_DAC_CH1_UNDERRUN_CB_ID DAC CH1 UnderRun Callback ID + * @arg @ref HAL_DAC_CH2_COMPLETE_CB_ID DAC CH2 Complete Callback ID + * @arg @ref HAL_DAC_CH2_HALF_COMPLETE_CB_ID DAC CH2 Half Complete Callback ID + * @arg @ref HAL_DAC_CH2_ERROR_ID DAC CH2 Error Callback ID + * @arg @ref HAL_DAC_CH2_UNDERRUN_CB_ID DAC CH2 UnderRun Callback ID + * @arg @ref HAL_DAC_MSPINIT_CB_ID DAC MSP Init Callback ID + * @arg @ref HAL_DAC_MSPDEINIT_CB_ID DAC MSP DeInit Callback ID + * @arg @ref HAL_DAC_ALL_CB_ID DAC All callbacks + * @retval status + */ +HAL_StatusTypeDef HAL_DAC_UnRegisterCallback(DAC_HandleTypeDef *hdac, HAL_DAC_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the DAC peripheral handle */ + if (hdac == NULL) + { + return HAL_ERROR; + } + + if (hdac->State == HAL_DAC_STATE_READY) + { + switch (CallbackID) + { + case HAL_DAC_CH1_COMPLETE_CB_ID : + hdac->ConvCpltCallbackCh1 = HAL_DAC_ConvCpltCallbackCh1; + break; + case HAL_DAC_CH1_HALF_COMPLETE_CB_ID : + hdac->ConvHalfCpltCallbackCh1 = HAL_DAC_ConvHalfCpltCallbackCh1; + break; + case HAL_DAC_CH1_ERROR_ID : + hdac->ErrorCallbackCh1 = HAL_DAC_ErrorCallbackCh1; + break; + case HAL_DAC_CH1_UNDERRUN_CB_ID : + hdac->DMAUnderrunCallbackCh1 = HAL_DAC_DMAUnderrunCallbackCh1; + break; + + case HAL_DAC_CH2_COMPLETE_CB_ID : + hdac->ConvCpltCallbackCh2 = HAL_DACEx_ConvCpltCallbackCh2; + break; + case HAL_DAC_CH2_HALF_COMPLETE_CB_ID : + hdac->ConvHalfCpltCallbackCh2 = HAL_DACEx_ConvHalfCpltCallbackCh2; + break; + case HAL_DAC_CH2_ERROR_ID : + hdac->ErrorCallbackCh2 = HAL_DACEx_ErrorCallbackCh2; + break; + case HAL_DAC_CH2_UNDERRUN_CB_ID : + hdac->DMAUnderrunCallbackCh2 = HAL_DACEx_DMAUnderrunCallbackCh2; + break; + + case HAL_DAC_MSPINIT_CB_ID : + hdac->MspInitCallback = HAL_DAC_MspInit; + break; + case HAL_DAC_MSPDEINIT_CB_ID : + hdac->MspDeInitCallback = HAL_DAC_MspDeInit; + break; + case HAL_DAC_ALL_CB_ID : + hdac->ConvCpltCallbackCh1 = HAL_DAC_ConvCpltCallbackCh1; + hdac->ConvHalfCpltCallbackCh1 = HAL_DAC_ConvHalfCpltCallbackCh1; + hdac->ErrorCallbackCh1 = HAL_DAC_ErrorCallbackCh1; + hdac->DMAUnderrunCallbackCh1 = HAL_DAC_DMAUnderrunCallbackCh1; + + hdac->ConvCpltCallbackCh2 = HAL_DACEx_ConvCpltCallbackCh2; + hdac->ConvHalfCpltCallbackCh2 = HAL_DACEx_ConvHalfCpltCallbackCh2; + hdac->ErrorCallbackCh2 = HAL_DACEx_ErrorCallbackCh2; + hdac->DMAUnderrunCallbackCh2 = HAL_DACEx_DMAUnderrunCallbackCh2; + + hdac->MspInitCallback = HAL_DAC_MspInit; + hdac->MspDeInitCallback = HAL_DAC_MspDeInit; + break; + default : + /* Update the error code */ + hdac->ErrorCode |= HAL_DAC_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else if (hdac->State == HAL_DAC_STATE_RESET) + { + switch (CallbackID) + { + case HAL_DAC_MSPINIT_CB_ID : + hdac->MspInitCallback = HAL_DAC_MspInit; + break; + case HAL_DAC_MSPDEINIT_CB_ID : + hdac->MspDeInitCallback = HAL_DAC_MspDeInit; + break; + default : + /* Update the error code */ + hdac->ErrorCode |= HAL_DAC_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hdac->ErrorCode |= HAL_DAC_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + } + + return status; +} +#endif /* USE_HAL_DAC_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup DAC_Private_Functions + * @{ + */ + +/** + * @brief DMA conversion complete callback. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +void DAC_DMAConvCpltCh1(DMA_HandleTypeDef *hdma) +{ + DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + +#if (USE_HAL_DAC_REGISTER_CALLBACKS == 1) + hdac->ConvCpltCallbackCh1(hdac); +#else + HAL_DAC_ConvCpltCallbackCh1(hdac); +#endif /* USE_HAL_DAC_REGISTER_CALLBACKS */ + + hdac->State = HAL_DAC_STATE_READY; +} + +/** + * @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 + */ +void DAC_DMAHalfConvCpltCh1(DMA_HandleTypeDef *hdma) +{ + DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + /* Conversion complete callback */ +#if (USE_HAL_DAC_REGISTER_CALLBACKS == 1) + hdac->ConvHalfCpltCallbackCh1(hdac); +#else + HAL_DAC_ConvHalfCpltCallbackCh1(hdac); +#endif /* USE_HAL_DAC_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 + */ +void DAC_DMAErrorCh1(DMA_HandleTypeDef *hdma) +{ + DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Set DAC error code to DMA error */ + hdac->ErrorCode |= HAL_DAC_ERROR_DMA; + +#if (USE_HAL_DAC_REGISTER_CALLBACKS == 1) + hdac->ErrorCallbackCh1(hdac); +#else + HAL_DAC_ErrorCallbackCh1(hdac); +#endif /* USE_HAL_DAC_REGISTER_CALLBACKS */ + + hdac->State = HAL_DAC_STATE_READY; +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* DAC1 */ + +#endif /* HAL_DAC_MODULE_ENABLED */ +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dac_ex.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dac_ex.c new file mode 100644 index 0000000000..8ba7fbfc74 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dac_ex.c @@ -0,0 +1,1010 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_dac_ex.c + * @author MCD Application Team + * @brief Extended DAC HAL module driver. + * This file provides firmware functions to manage the extended + * functionalities of the DAC peripheral. + * + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + *** Dual mode IO operation *** + ============================== + [..] + (+) Use HAL_DACEx_DualStart() to enable both channel and start conversion + for dual mode operation. + If software trigger is selected, using HAL_DACEx_DualStart() will start + the conversion of the value previously set by HAL_DACEx_DualSetValue(). + (+) Use HAL_DACEx_DualStop() to disable both channel and stop conversion + for dual mode operation. + (+) Use HAL_DACEx_DualStart_DMA() to enable both channel and start conversion + for dual mode operation using DMA to feed DAC converters. + First issued trigger will start the conversion of the value previously + set by HAL_DACEx_DualSetValue(). + The same callbacks that are used in single mode are called in dual mode to notify + transfer completion (half complete or complete), errors or underrun. + (+) Use HAL_DACEx_DualStop_DMA() to disable both channel and stop conversion + for dual mode operation using DMA to feed DAC converters. + (+) When Dual mode is enabled (i.e. DAC Channel1 and Channel2 are used simultaneously) : + Use HAL_DACEx_DualGetValue() to get digital data to be converted and use + HAL_DACEx_DualSetValue() to set digital value to converted simultaneously in + Channel 1 and Channel 2. + *** Signal generation operation *** + =================================== + [..] + (+) Use HAL_DACEx_TriangleWaveGenerate() to generate Triangle signal. + (+) Use HAL_DACEx_NoiseWaveGenerate() to generate Noise signal. + + (+) HAL_DACEx_SelfCalibrate to calibrate one DAC channel. + (+) HAL_DACEx_SetUserTrimming to set user trimming value. + (+) HAL_DACEx_GetTrimOffset to retrieve trimming value (factory setting + after reset, user setting if HAL_DACEx_SetUserTrimming have been used + at least one time after reset). + + @endverbatim + ****************************************************************************** + */ + + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +#ifdef HAL_DAC_MODULE_ENABLED + +#if defined(DAC1) + +/** @defgroup DACEx DACEx + * @brief DAC Extended HAL module driver + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/* Delay for DAC minimum trimming time. */ +/* Note: minimum time needed between two calibration steps */ +/* The delay below is specified under conditions: */ +/* - DAC channel output buffer enabled */ +/* Literal set to maximum value (refer to device datasheet, */ +/* electrical characteristics, parameter "tTRIM"). */ +/* Unit: us */ +#define DAC_DELAY_TRIM_US (50UL) /*!< Delay for DAC minimum trimming time */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup DACEx_Exported_Functions DACEx Exported Functions + * @{ + */ + +/** @defgroup DACEx_Exported_Functions_Group2 IO operation functions + * @brief Extended IO operation functions + * +@verbatim + ============================================================================== + ##### Extended features functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) Start conversion. + (+) Stop conversion. + (+) Start conversion and enable DMA transfer. + (+) Stop conversion and disable DMA transfer. + (+) Get result of conversion. + (+) Get result of dual mode conversion. + +@endverbatim + * @{ + */ + + +/** + * @brief Enables DAC and starts conversion of both channels. + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DACEx_DualStart(DAC_HandleTypeDef *hdac) +{ + uint32_t tmp_swtrig = 0UL; + __IO uint32_t wait_loop_index; + + /* Check the DAC peripheral handle */ + if (hdac == NULL) + { + return HAL_ERROR; + } + + + /* Process locked */ + __HAL_LOCK(hdac); + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_BUSY; + + /* Enable the Peripheral */ + __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_1); + __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_2); + /* Ensure minimum wait before using peripheral after enabling it */ + /* Wait loop initialization and execution */ + /* Note: Variable divided by 2 to compensate partially */ + /* CPU processing cycles, scaling in us split to not */ + /* exceed 32 bits register capacity and handle low frequency. */ + wait_loop_index = ((DAC_DELAY_STARTUP_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL)); + while (wait_loop_index != 0UL) + { + wait_loop_index--; + } + + /* Check if software trigger enabled */ + if ((hdac->Instance->CR & (DAC_CR_TEN1 | DAC_CR_TSEL1)) == DAC_TRIGGER_SOFTWARE) + { + tmp_swtrig |= DAC_SWTRIGR_SWTRIG1; + } + if ((hdac->Instance->CR & (DAC_CR_TEN2 | DAC_CR_TSEL2)) == (DAC_TRIGGER_SOFTWARE << (DAC_CHANNEL_2 & 0x10UL))) + { + tmp_swtrig |= DAC_SWTRIGR_SWTRIG2; + } + /* Enable the selected DAC software conversion*/ + SET_BIT(hdac->Instance->SWTRIGR, tmp_swtrig); + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hdac); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Disables DAC and stop conversion of both channels. + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DACEx_DualStop(DAC_HandleTypeDef *hdac) +{ + /* Check the DAC peripheral handle */ + if (hdac == NULL) + { + return HAL_ERROR; + } + + + /* Disable the Peripheral */ + __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_1); + __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_2); + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Enables DAC and starts conversion of both channel 1 and 2 of the same DAC. + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @param Channel The DAC channel that will request data from DMA. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @param pData The destination peripheral Buffer address. + * @param Length The length of data to be transferred from memory to DAC peripheral + * @param Alignment Specifies the data alignment for DAC channel. + * This parameter can be one of the following values: + * @arg DAC_ALIGN_8B_R: 8bit right data alignment selected + * @arg DAC_ALIGN_12B_L: 12bit left data alignment selected + * @arg DAC_ALIGN_12B_R: 12bit right data alignment selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DACEx_DualStart_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel, + const uint32_t *pData, uint32_t Length, uint32_t Alignment) +{ + HAL_StatusTypeDef status; + uint32_t tmpreg = 0UL; + __IO uint32_t wait_loop_index; + uint32_t LengthInBytes; + + /* Check the DAC peripheral handle */ + if (hdac == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(Channel)); + assert_param(IS_DAC_ALIGN(Alignment)); + + /* Process locked */ + __HAL_LOCK(hdac); + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_BUSY; + + if (Channel == DAC_CHANNEL_1) + { + /* Set the DMA transfer complete callback for channel1 */ + hdac->DMA_Handle1->XferCpltCallback = DAC_DMAConvCpltCh1; + + /* Set the DMA half transfer complete callback for channel1 */ + hdac->DMA_Handle1->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh1; + + /* Set the DMA error callback for channel1 */ + hdac->DMA_Handle1->XferErrorCallback = DAC_DMAErrorCh1; + + /* Enable the selected DAC channel1 DMA request */ + SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN1); + } + else + { + /* Set the DMA transfer complete callback for channel2 */ + hdac->DMA_Handle2->XferCpltCallback = DAC_DMAConvCpltCh2; + + /* Set the DMA half transfer complete callback for channel2 */ + hdac->DMA_Handle2->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh2; + + /* Set the DMA error callback for channel2 */ + hdac->DMA_Handle2->XferErrorCallback = DAC_DMAErrorCh2; + + /* Enable the selected DAC channel2 DMA request */ + SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN2); + } + + switch (Alignment) + { + case DAC_ALIGN_12B_R: + /* Get DHR12R1 address */ + tmpreg = (uint32_t)&hdac->Instance->DHR12RD; + break; + case DAC_ALIGN_12B_L: + /* Get DHR12L1 address */ + tmpreg = (uint32_t)&hdac->Instance->DHR12LD; + break; + case DAC_ALIGN_8B_R: + /* Get DHR8R1 address */ + tmpreg = (uint32_t)&hdac->Instance->DHR8RD; + break; + default: + break; + } + + /* Enable the DMA channel */ + if (Channel == DAC_CHANNEL_1) + { + /* Enable the DAC DMA underrun interrupt */ + __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR1); + + /* Length should be converted to number of bytes */ + LengthInBytes = Length * 4U; + + /* Check linkedlist mode */ + if ((hdac->DMA_Handle1->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hdac->DMA_Handle1->LinkedListQueue != NULL) && (hdac->DMA_Handle1->LinkedListQueue->Head != NULL)) + { + /* Set DMA data size */ + hdac->DMA_Handle1->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = LengthInBytes; + + /* Set DMA source address */ + hdac->DMA_Handle1->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)pData; + + /* Set DMA destination address */ + hdac->DMA_Handle1->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = tmpreg; + + /* Enable the DMA channel */ + status = HAL_DMAEx_List_Start_IT(hdac->DMA_Handle1); + } + else + { + /* Return error status */ + return HAL_ERROR; + } + } + else + { + /* Enable the DMA channel */ + status = HAL_DMA_Start_IT(hdac->DMA_Handle1, (uint32_t)pData, tmpreg, LengthInBytes); + } + } + else + { + /* Enable the DAC DMA underrun interrupt */ + __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR2); + + /* Length should be converted to number of bytes */ + LengthInBytes = Length * 4U; + + /* Check linkedlist mode */ + if ((hdac->DMA_Handle2->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hdac->DMA_Handle2->LinkedListQueue != NULL) && (hdac->DMA_Handle2->LinkedListQueue->Head != NULL)) + { + /* Set DMA data size */ + hdac->DMA_Handle2->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = LengthInBytes; + + /* Set DMA source address */ + hdac->DMA_Handle2->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)pData; + + /* Set DMA destination address */ + hdac->DMA_Handle2->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = tmpreg; + + /* Enable the DMA channel */ + status = HAL_DMAEx_List_Start_IT(hdac->DMA_Handle2); + } + else + { + /* Return error status */ + return HAL_ERROR; + } + } + else + { + /* Enable the DMA channel */ + status = HAL_DMA_Start_IT(hdac->DMA_Handle2, (uint32_t)pData, tmpreg, LengthInBytes); + } + } + + /* Process Unlocked */ + __HAL_UNLOCK(hdac); + + if (status == HAL_OK) + { + /* Enable the Peripheral */ + __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_1); + __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_2); + /* Ensure minimum wait before using peripheral after enabling it */ + /* Wait loop initialization and execution */ + /* Note: Variable divided by 2 to compensate partially */ + /* CPU processing cycles, scaling in us split to not */ + /* exceed 32 bits register capacity and handle low frequency. */ + wait_loop_index = ((DAC_DELAY_STARTUP_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL)); + while (wait_loop_index != 0UL) + { + wait_loop_index--; + } + } + else + { + hdac->ErrorCode |= HAL_DAC_ERROR_DMA; + } + + /* Return function status */ + return status; +} + +/** + * @brief Disables DAC and stop conversion both channel. + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @param Channel The DAC channel that requests data from DMA. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DACEx_DualStop_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel) +{ + HAL_StatusTypeDef status; + + /* Check the DAC peripheral handle */ + if (hdac == NULL) + { + return HAL_ERROR; + } + + + /* Disable the selected DAC channel DMA request */ + CLEAR_BIT(hdac->Instance->CR, DAC_CR_DMAEN2 | DAC_CR_DMAEN1); + + /* Disable the Peripheral */ + __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_1); + __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_2); + + /* Disable the DMA channel */ + + /* Channel1 is used */ + if (Channel == DAC_CHANNEL_1) + { + /* Disable the DMA channel */ + status = HAL_DMA_Abort(hdac->DMA_Handle1); + + /* Disable the DAC DMA underrun interrupt */ + __HAL_DAC_DISABLE_IT(hdac, DAC_IT_DMAUDR1); + } + else + { + /* Disable the DMA channel */ + status = HAL_DMA_Abort(hdac->DMA_Handle2); + + /* Disable the DAC DMA underrun interrupt */ + __HAL_DAC_DISABLE_IT(hdac, DAC_IT_DMAUDR2); + } + + /* Check if DMA Channel effectively disabled */ + if (status != HAL_OK) + { + /* Update DAC state machine to error */ + hdac->State = HAL_DAC_STATE_ERROR; + } + else + { + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_READY; + } + + /* Return function status */ + return status; +} + + +/** + * @brief Enable or disable the selected DAC channel wave generation. + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @param Channel The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @param Amplitude Select max triangle amplitude. + * This parameter can be one of the following values: + * @arg DAC_TRIANGLEAMPLITUDE_1: Select max triangle amplitude of 1 + * @arg DAC_TRIANGLEAMPLITUDE_3: Select max triangle amplitude of 3 + * @arg DAC_TRIANGLEAMPLITUDE_7: Select max triangle amplitude of 7 + * @arg DAC_TRIANGLEAMPLITUDE_15: Select max triangle amplitude of 15 + * @arg DAC_TRIANGLEAMPLITUDE_31: Select max triangle amplitude of 31 + * @arg DAC_TRIANGLEAMPLITUDE_63: Select max triangle amplitude of 63 + * @arg DAC_TRIANGLEAMPLITUDE_127: Select max triangle amplitude of 127 + * @arg DAC_TRIANGLEAMPLITUDE_255: Select max triangle amplitude of 255 + * @arg DAC_TRIANGLEAMPLITUDE_511: Select max triangle amplitude of 511 + * @arg DAC_TRIANGLEAMPLITUDE_1023: Select max triangle amplitude of 1023 + * @arg DAC_TRIANGLEAMPLITUDE_2047: Select max triangle amplitude of 2047 + * @arg DAC_TRIANGLEAMPLITUDE_4095: Select max triangle amplitude of 4095 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DACEx_TriangleWaveGenerate(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Amplitude) +{ + /* Check the DAC peripheral handle */ + if (hdac == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(Channel)); + assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude)); + + /* Process locked */ + __HAL_LOCK(hdac); + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_BUSY; + + /* Enable the triangle wave generation for the selected DAC channel */ + MODIFY_REG(hdac->Instance->CR, ((DAC_CR_WAVE1) | (DAC_CR_MAMP1)) << (Channel & 0x10UL), + (DAC_CR_WAVE1_1 | Amplitude) << (Channel & 0x10UL)); + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hdac); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Enable or disable the selected DAC channel wave generation. + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @param Channel The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @param Amplitude Unmask DAC channel LFSR for noise wave generation. + * This parameter can be one of the following values: + * @arg DAC_LFSRUNMASK_BIT0: Unmask DAC channel LFSR bit0 for noise wave generation + * @arg DAC_LFSRUNMASK_BITS1_0: Unmask DAC channel LFSR bit[1:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS2_0: Unmask DAC channel LFSR bit[2:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS3_0: Unmask DAC channel LFSR bit[3:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS4_0: Unmask DAC channel LFSR bit[4:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS5_0: Unmask DAC channel LFSR bit[5:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS6_0: Unmask DAC channel LFSR bit[6:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS7_0: Unmask DAC channel LFSR bit[7:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS8_0: Unmask DAC channel LFSR bit[8:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS9_0: Unmask DAC channel LFSR bit[9:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS10_0: Unmask DAC channel LFSR bit[10:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS11_0: Unmask DAC channel LFSR bit[11:0] for noise wave generation + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DACEx_NoiseWaveGenerate(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Amplitude) +{ + /* Check the DAC peripheral handle */ + if (hdac == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(Channel)); + assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude)); + + /* Process locked */ + __HAL_LOCK(hdac); + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_BUSY; + + /* Enable the noise wave generation for the selected DAC channel */ + MODIFY_REG(hdac->Instance->CR, ((DAC_CR_WAVE1) | (DAC_CR_MAMP1)) << (Channel & 0x10UL), + (DAC_CR_WAVE1_0 | Amplitude) << (Channel & 0x10UL)); + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hdac); + + /* Return function status */ + return HAL_OK; +} + + +/** + * @brief Set the specified data holding register value for dual DAC channel. + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @param Alignment Specifies the data alignment for dual channel DAC. + * This parameter can be one of the following values: + * DAC_ALIGN_8B_R: 8bit right data alignment selected + * DAC_ALIGN_12B_L: 12bit left data alignment selected + * DAC_ALIGN_12B_R: 12bit right data alignment selected + * @param Data1 Data for DAC Channel1 to be loaded in the selected data holding register. + * @param Data2 Data for DAC Channel2 to be loaded in the selected data holding register. + * @note In dual mode, a unique register access is required to write in both + * DAC channels at the same time. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DACEx_DualSetValue(DAC_HandleTypeDef *hdac, uint32_t Alignment, uint32_t Data1, uint32_t Data2) +{ + uint32_t data; + uint32_t tmp; + + /* Check the DAC peripheral handle */ + if (hdac == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DAC_ALIGN(Alignment)); + assert_param(IS_DAC_DATA(Data1)); + assert_param(IS_DAC_DATA(Data2)); + + /* Calculate and set dual DAC data holding register value */ + if (Alignment == DAC_ALIGN_8B_R) + { + data = ((uint32_t)Data2 << 8U) | Data1; + } + else + { + data = ((uint32_t)Data2 << 16U) | Data1; + } + + tmp = (uint32_t)hdac->Instance; + tmp += DAC_DHR12RD_ALIGNMENT(Alignment); + + /* Set the dual DAC selected data holding register */ + *(__IO uint32_t *)tmp = data; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Conversion complete callback in non-blocking mode for Channel2. + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval None + */ +__weak void HAL_DACEx_ConvCpltCallbackCh2(DAC_HandleTypeDef *hdac) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdac); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_DACEx_ConvCpltCallbackCh2 could be implemented in the user file + */ +} + +/** + * @brief Conversion half DMA transfer callback in non-blocking mode for Channel2. + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval None + */ +__weak void HAL_DACEx_ConvHalfCpltCallbackCh2(DAC_HandleTypeDef *hdac) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdac); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_DACEx_ConvHalfCpltCallbackCh2 could be implemented in the user file + */ +} + +/** + * @brief Error DAC callback for Channel2. + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval None + */ +__weak void HAL_DACEx_ErrorCallbackCh2(DAC_HandleTypeDef *hdac) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdac); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_DACEx_ErrorCallbackCh2 could be implemented in the user file + */ +} + +/** + * @brief DMA underrun DAC callback for Channel2. + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval None + */ +__weak void HAL_DACEx_DMAUnderrunCallbackCh2(DAC_HandleTypeDef *hdac) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdac); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_DACEx_DMAUnderrunCallbackCh2 could be implemented in the user file + */ +} + + +/** + * @brief Run the self calibration of one DAC channel. + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @param sConfig DAC channel configuration structure. + * @param Channel The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @retval Updates DAC_TrimmingValue. , DAC_UserTrimming set to DAC_UserTrimming + * @retval HAL status + * @note Calibration runs about 7 ms. + */ +HAL_StatusTypeDef HAL_DACEx_SelfCalibrate(DAC_HandleTypeDef *hdac, DAC_ChannelConfTypeDef *sConfig, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + + uint32_t trimmingvalue; + uint32_t delta; + __IO uint32_t wait_loop_index; + + /* store/restore channel configuration structure purpose */ + uint32_t oldmodeconfiguration; + + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(Channel)); + + /* Check the DAC handle allocation */ + /* Check if DAC running */ + if ((hdac == NULL) || (sConfig == NULL)) + { + status = HAL_ERROR; + } + else if (hdac->State == HAL_DAC_STATE_BUSY) + { + status = HAL_ERROR; + } + else + { + /* Process locked */ + __HAL_LOCK(hdac); + + /* Store configuration */ + oldmodeconfiguration = (hdac->Instance->MCR & (DAC_MCR_MODE1 << (Channel & 0x10UL))); + + /* Disable the selected DAC channel */ + CLEAR_BIT((hdac->Instance->CR), (DAC_CR_EN1 << (Channel & 0x10UL))); + /* Wait for ready bit to be de-asserted */ + HAL_Delay(1); + + /* Set mode in MCR for calibration */ + MODIFY_REG(hdac->Instance->MCR, (DAC_MCR_MODE1 << (Channel & 0x10UL)), 0U); + + /* Enable the selected DAC channel calibration */ + /* i.e. set DAC_CR_CENx bit */ + SET_BIT((hdac->Instance->CR), (DAC_CR_CEN1 << (Channel & 0x10UL))); + + /* Init trimming counter */ + /* Medium value */ + trimmingvalue = 16UL; + delta = 8UL; + while (delta != 0UL) + { + /* Set candidate trimming */ + MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (trimmingvalue << (Channel & 0x10UL))); + + /* Wait minimum time needed between two calibration steps (OTRIM) */ + /* Wait loop initialization and execution */ + /* Note: Variable divided by 2 to compensate partially CPU processing cycles, scaling in us split to not exceed */ + /* 32 bits register capacity and handle low frequency. */ + wait_loop_index = ((DAC_DELAY_TRIM_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL)); + while (wait_loop_index != 0UL) + { + wait_loop_index--; + } + + if ((hdac->Instance->SR & (DAC_SR_CAL_FLAG1 << (Channel & 0x10UL))) == (DAC_SR_CAL_FLAG1 << (Channel & 0x10UL))) + { + /* DAC_SR_CAL_FLAGx is HIGH try higher trimming */ + trimmingvalue -= delta; + } + else + { + /* DAC_SR_CAL_FLAGx is LOW try lower trimming */ + trimmingvalue += delta; + } + delta >>= 1UL; + } + + /* Still need to check if right calibration is current value or one step below */ + /* Indeed the first value that causes the DAC_SR_CAL_FLAGx bit to change from 0 to 1 */ + /* Set candidate trimming */ + MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (trimmingvalue << (Channel & 0x10UL))); + + /* Wait minimum time needed between two calibration steps (OTRIM) */ + /* Wait loop initialization and execution */ + /* Note: Variable divided by 2 to compensate partially CPU processing cycles, scaling in us split to not exceed */ + /* 32 bits register capacity and handle low frequency. */ + wait_loop_index = ((DAC_DELAY_TRIM_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL)); + while (wait_loop_index != 0UL) + { + wait_loop_index--; + } + + if ((hdac->Instance->SR & (DAC_SR_CAL_FLAG1 << (Channel & 0x10UL))) == 0UL) + { + /* Trimming is actually one value more */ + trimmingvalue++; + /* Set right trimming */ + MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (trimmingvalue << (Channel & 0x10UL))); + } + + /* Disable the selected DAC channel calibration */ + /* i.e. clear DAC_CR_CENx bit */ + CLEAR_BIT((hdac->Instance->CR), (DAC_CR_CEN1 << (Channel & 0x10UL))); + + sConfig->DAC_TrimmingValue = trimmingvalue; + sConfig->DAC_UserTrimming = DAC_TRIMMING_USER; + + /* Restore configuration */ + MODIFY_REG(hdac->Instance->MCR, (DAC_MCR_MODE1 << (Channel & 0x10UL)), oldmodeconfiguration); + + /* Process unlocked */ + __HAL_UNLOCK(hdac); + } + + return status; +} + +/** + * @brief Set the trimming mode and trimming value (user trimming mode applied). + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @param sConfig DAC configuration structure updated with new DAC trimming value. + * @param Channel The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @param NewTrimmingValue DAC new trimming value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DACEx_SetUserTrimming(DAC_HandleTypeDef *hdac, DAC_ChannelConfTypeDef *sConfig, uint32_t Channel, + uint32_t NewTrimmingValue) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(Channel)); + assert_param(IS_DAC_NEWTRIMMINGVALUE(NewTrimmingValue)); + + /* Check the DAC handle and channel configuration struct allocation */ + if ((hdac == NULL) || (sConfig == NULL)) + { + status = HAL_ERROR; + } + else + { + /* Process locked */ + __HAL_LOCK(hdac); + + /* Set new trimming */ + MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (NewTrimmingValue << (Channel & 0x10UL))); + + /* Update trimming mode */ + sConfig->DAC_UserTrimming = DAC_TRIMMING_USER; + sConfig->DAC_TrimmingValue = NewTrimmingValue; + + /* Process unlocked */ + __HAL_UNLOCK(hdac); + } + return status; +} + +/** + * @brief Return the DAC trimming value. + * @param hdac DAC handle + * @param Channel The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @retval Trimming value : range: 0->31 + * + */ +uint32_t HAL_DACEx_GetTrimOffset(const DAC_HandleTypeDef *hdac, uint32_t Channel) +{ + /* Check the parameter */ + assert_param(IS_DAC_CHANNEL(Channel)); + + /* Retrieve trimming */ + return ((hdac->Instance->CCR & (DAC_CCR_OTRIM1 << (Channel & 0x10UL))) >> (Channel & 0x10UL)); +} + +/** + * @} + */ + +/** @defgroup DACEx_Exported_Functions_Group3 Peripheral Control functions + * @brief Extended Peripheral Control functions + * +@verbatim + ============================================================================== + ##### Peripheral Control functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) Set the specified data holding register value for DAC channel. + +@endverbatim + * @{ + */ + + +/** + * @brief Return the last data output value of the selected DAC channel. + * @param hdac pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval The selected DAC channel data output value. + */ +uint32_t HAL_DACEx_DualGetValue(const DAC_HandleTypeDef *hdac) +{ + uint32_t tmp = 0UL; + + tmp |= hdac->Instance->DOR1; + + tmp |= hdac->Instance->DOR2 << 16UL; + + /* Returns the DAC channel data output register value */ + return tmp; +} + + +/** + * @} + */ +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup DACEx_Private_Functions DACEx private functions + * @brief Extended private functions + * @{ + */ + + +/** + * @brief DMA conversion complete callback. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +void DAC_DMAConvCpltCh2(DMA_HandleTypeDef *hdma) +{ + DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + +#if (USE_HAL_DAC_REGISTER_CALLBACKS == 1) + hdac->ConvCpltCallbackCh2(hdac); +#else + HAL_DACEx_ConvCpltCallbackCh2(hdac); +#endif /* USE_HAL_DAC_REGISTER_CALLBACKS */ + + hdac->State = HAL_DAC_STATE_READY; +} + +/** + * @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 + */ +void DAC_DMAHalfConvCpltCh2(DMA_HandleTypeDef *hdma) +{ + DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + /* Conversion complete callback */ +#if (USE_HAL_DAC_REGISTER_CALLBACKS == 1) + hdac->ConvHalfCpltCallbackCh2(hdac); +#else + HAL_DACEx_ConvHalfCpltCallbackCh2(hdac); +#endif /* USE_HAL_DAC_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 + */ +void DAC_DMAErrorCh2(DMA_HandleTypeDef *hdma) +{ + DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Set DAC error code to DMA error */ + hdac->ErrorCode |= HAL_DAC_ERROR_DMA; + +#if (USE_HAL_DAC_REGISTER_CALLBACKS == 1) + hdac->ErrorCallbackCh2(hdac); +#else + HAL_DACEx_ErrorCallbackCh2(hdac); +#endif /* USE_HAL_DAC_REGISTER_CALLBACKS */ + + hdac->State = HAL_DAC_STATE_READY; +} + + +/** + * @} + */ + +/** + * @} + */ + +#endif /* DAC1 */ + +#endif /* HAL_DAC_MODULE_ENABLED */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dcache.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dcache.c new file mode 100644 index 0000000000..5fd484fa6f --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dcache.c @@ -0,0 +1,1475 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_dcache.c + * @author MCD Application Team + * @brief DCACHE HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the DCACHE. + * + Initialization and Configuration + * + Cache coherency command + * + Monitoring management + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + =============================================================================== + ##### How to use this driver ##### + =============================================================================== + [..] + (#) Configure and enable the MPU to override default config if needed, please refers + to ARM manual for default memory attribute. Then enable DCACHE. + + [..] + (+) Use HAL_DCACHE_Invalidate() to invalidate the full cache content: + (++) Cache content is lost, and reloaded when needed. + (++) Used for complete invalidate of the DCACHE in case. + (++) Blocking call until operation is done. + (+) Use HAL_DCACHE_InvalidateByAddr() to invalidate cache content for specific range: + (++) Cache content for specific range is lost, and reloaded when needed. + (++) Used when excepting a buffer to be updated by a peripheral (typically DMA transfer) + (++) Blocking call until operation is done. + (+) Use HAL_DCACHE_CleanByAddr() to clean cache content for a specific range: + (++) Cache content for specific range is written back to memory. + (++) Used when buffer is updated by CPU before usage by a peripheral (typically DMA transfer) + (++) Blocking call until operation is done. + (+) Use HAL_DCACHE_CleanInvalidateByAddr() to clean and invalidate cache content for a specific range: + (++) Cache content for specific range is written back to memory, and reloaded when needed. + (++) Used when sharing buffer between CPU and other peripheral. + (++) Recommended to use for MPU reprogramming. + (++) Blocking call until operation is done. + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Configure the DCACHE interrupt priority using HAL_NVIC_SetPriority() + (+) Enable the DCACHE IRQ handler using HAL_NVIC_EnableIRQ() + (+) Override weak definition for following callbacks (if needed): + (++)HAL_DCACHE_CleanAndInvalidateByAddrCallback() + (++)HAL_DCACHE_InvalidateCompleteCallback() + (++)HAL_DCACHE_InvalidateByAddrCallback() + (++)HAL_DCACHE_CleanByAddrCallback() + (++)HAL_DCACHE_ErrorCallback() + (+) Use HAL_DCACHE__IT() to start a DCACHE operation with IT enabled. + (+) Use HAL_DCACHE_IRQHandler() called under DCACHEx_IRQHandler() Interrupt subroutine + + [..] Use HAL_DCACHE_GetState() function to return the DCACHE state and HAL_DCACHE_GetError() + in case of error detection. + + *** DCACHE HAL driver macros list *** + ============================================= + [..] + Below the list of macros defined in the DCACHE HAL driver. + + (+) __HAL_DCACHE_ENABLE_IT : Enable DCACHE interrupts. + (+) __HAL_DCACHE_DISABLE_IT : Disable DCACHE interrupts. + (+) __HAL_DCACHE_GET_IT_SOURCE: Check whether the specified DCACHE interrupt source is enabled or not. + (+) __HAL_DCACHE_GET_FLAG : Check whether the selected DCACHE flag is set or not. + (+) __HAL_DCACHE_CLEAR_FLAG : Clear the selected DCACHE flags. + + [..] + (@) You can refer to the header file of the DCACHE HAL driver for more useful macros. + + [..] + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup DCACHE DCACHE + * @brief HAL DCACHE module driver + * @{ + */ + +#if defined (DCACHE1) +#ifdef HAL_DCACHE_MODULE_ENABLED + +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/** @defgroup DCACHE_Private_Macros DCACHE Private Macros + * @{ + */ +#define IS_DCACHE_REGION_SIZE(__SIZE__) ((__SIZE__) > 0U) + +#define IS_DCACHE_MONITOR_TYPE(__TYPE__) (((__TYPE__) & ~DCACHE_MONITOR_ALL) == 0U) + +#define IS_DCACHE_SINGLE_MONITOR_TYPE(__TYPE__) (((__TYPE__) == DCACHE_MONITOR_READ_HIT) || \ + ((__TYPE__) == DCACHE_MONITOR_READ_MISS) || \ + ((__TYPE__) == DCACHE_MONITOR_WRITE_HIT) || \ + ((__TYPE__) == DCACHE_MONITOR_WRITE_MISS)) + +#define IS_DCACHE_READ_BURST_TYPE(__OUTPUTBURSTTYPE__) (((__OUTPUTBURSTTYPE__) == DCACHE_READ_BURST_WRAP) || \ + ((__OUTPUTBURSTTYPE__) == DCACHE_READ_BURST_INCR)) + +/** + * @} + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @addtogroup DCACHE_Private_Constants DCACHE Private Constants + * @{ + */ +#define DCACHE_COMMAND_TIMEOUT_VALUE 200U /* 200ms*/ +#define DCACHE_DISABLE_TIMEOUT_VALUE 1U /* 1ms */ + +#define DCACHE_COMMAND_INVALIDATE DCACHE_CR_CACHECMD_1 +#define DCACHE_COMMAND_CLEAN DCACHE_CR_CACHECMD_0 +#define DCACHE_COMMAND_CLEAN_INVALIDATE (DCACHE_CR_CACHECMD_0|DCACHE_CR_CACHECMD_1) + +#define DCACHE_POLLING_MODE 0U +#define DCACHE_IT_MODE 1U + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +static HAL_StatusTypeDef DCACHE_CommandByAddr(DCACHE_HandleTypeDef *hdcache, uint32_t Command, + const uint32_t *const pAddr, uint32_t dSize, uint32_t mode); + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup DCACHE_Exported_Functions DCACHE Exported Functions + * @{ + */ + +/** @addtogroup DCACHE_Exported_Functions_Group1 + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + deinitialize the DCACHEx peripheral: + + (+) User must implement HAL_DCACHE_MspInit() function in which he configures + all related peripherals resources (CLOCK, MPU, IT and NVIC ). + + (+) Call the function HAL_DCACHE_Init() to configure the selected device with + the selected configuration: + (++) ReadBurstType + + (+) Call the function HAL_DCACHE_DeInit() to restore the reset configuration + of the selected DCACHEx peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the DCACHE according to the specified parameters + * in the DCACHE_InitTypeDef and initialize the associated handle. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHE. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCACHE_Init(DCACHE_HandleTypeDef *hdcache) +{ + HAL_StatusTypeDef status; + + /* Check the DCACHE handle allocation */ + if (hdcache == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); + assert_param(IS_DCACHE_READ_BURST_TYPE(hdcache->Init.ReadBurstType)); + + if (hdcache->State == HAL_DCACHE_STATE_RESET) + { + /* Init the DCACHE Callback settings with legacy weak */ + hdcache->ErrorCallback = HAL_DCACHE_ErrorCallback; + hdcache->CleanByAddrCallback = HAL_DCACHE_CleanByAddrCallback; + hdcache->InvalidateByAddrCallback = HAL_DCACHE_InvalidateByAddrCallback; + hdcache->InvalidateCompleteCallback = HAL_DCACHE_InvalidateCompleteCallback; + hdcache->CleanAndInvalidateByAddrCallback = HAL_DCACHE_CleanAndInvalidateByAddrCallback; + + if (hdcache->MspInitCallback == NULL) + { + hdcache->MspInitCallback = HAL_DCACHE_MspInit; + } + + /* Init the low level hardware */ + hdcache->MspInitCallback(hdcache); + } + + /* Init the error code */ + hdcache->ErrorCode = HAL_DCACHE_ERROR_NONE; + + /* Init the DCACHE handle state */ + hdcache->State = HAL_DCACHE_STATE_READY; + + /* Set requested read burst type */ + MODIFY_REG(hdcache->Instance->CR, DCACHE_CR_HBURST, hdcache->Init.ReadBurstType); + + /* Enable the selected DCACHE peripheral */ + status = HAL_DCACHE_Enable(hdcache); + + return status; +} + +/** + * @brief DeInitialize the Data cache. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCACHE_DeInit(DCACHE_HandleTypeDef *hdcache) +{ + HAL_StatusTypeDef status; + + /* Check the dcache handle allocation */ + if (hdcache == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); + + /* Update the error code */ + hdcache->ErrorCode = HAL_DCACHE_ERROR_NONE; + + /* Return to the reset state */ + hdcache->State = HAL_DCACHE_STATE_RESET; + + /* Disable cache */ + status = HAL_DCACHE_Disable(hdcache); + + /* reset monitor values */ + (void)HAL_DCACHE_Monitor_Reset(hdcache, DCACHE_MONITOR_ALL); + + /* Reset all remaining bit */ + WRITE_REG(hdcache->Instance->CR, 0U); + WRITE_REG(hdcache->Instance->CMDRSADDRR, 0U); + WRITE_REG(hdcache->Instance->CMDREADDRR, 0U); + WRITE_REG(hdcache->Instance->FCR, DCACHE_FCR_CCMDENDF | DCACHE_FCR_CERRF | DCACHE_FCR_CBSYENDF); + + if (hdcache->MspDeInitCallback == NULL) + { + hdcache->MspDeInitCallback = HAL_DCACHE_MspDeInit; + } + + /* DeInitialize the low level hardware */ + hdcache->MspDeInitCallback(hdcache); + + return status; +} + +/** + * @brief Initialize the DCACHE MSP. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @retval None + */ +__weak void HAL_DCACHE_MspInit(DCACHE_HandleTypeDef *hdcache) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdcache); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_DCACHE_MspInit can be implemented in the user file + */ +} + +/** + * @brief DeInitialize the DCACHE MSP. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @retval None + */ +__weak void HAL_DCACHE_MspDeInit(DCACHE_HandleTypeDef *hdcache) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdcache); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_DCACHE_MspDeInit can be implemented in the user file + */ +} +/** + * @} + */ + +/** @addtogroup DCACHE_Exported_Functions_Group2 + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) Enable the Data cache. + (+) Disable the Data cache. + (+) Set Read Burst Type. + (+) Invalidate the Data cache. + (+) Invalidate the Data cache with interrupt. + (+) Clean the Data cache by Addr. + (+) Invalidate the Data cache by Addr. + (+) Clean and Invalidate the Data cache by Addr. + (+) Clean the Data cache by Addr with interrupt. + (+) Invalidate the Data cache by Addr with interrupt. + (+) Clean and Invalidate the Data cache by Addr with interrupt. + (+) Start the Data Cache performance monitoring. + (+) Stop the Data Cache performance monitoring. + (+) Reset the Data Cache performance monitoring values. + (+) Get the Data Cache performance Read Hit monitoring value. + (+) Get the Data Cache performance Read Miss monitoring value. + (+) Get the Data Cache performance Write Hit monitoring value. + (+) Get the Data Cache performance Write Miss monitoring value. +@endverbatim + * @{ + */ + +/** + * @brief Enable the Data cache. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCACHE_Enable(DCACHE_HandleTypeDef *hdcache) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the dcache handle allocation */ + if (hdcache == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); + + /* Check no ongoing operation */ + if (READ_BIT(hdcache->Instance->SR, (DCACHE_SR_BUSYF | DCACHE_SR_BUSYCMDF)) != 0U) + { + /* Return busy status */ + status = HAL_BUSY; + } + else + { + /* Update the error code */ + hdcache->ErrorCode = HAL_DCACHE_ERROR_NONE; + + /* Enable the selected DCACHE peripheral */ + SET_BIT(hdcache->Instance->CR, DCACHE_CR_EN); + } + + return status; +} + +/** + * @brief Disable the Data cache. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCACHE_Disable(DCACHE_HandleTypeDef *hdcache) +{ + HAL_StatusTypeDef status = HAL_OK; + + uint32_t tickstart; + + /* Check the dcache handle allocation */ + if (hdcache == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); + + /* Check DCACHE handle status */ + if (HAL_DCACHE_IsEnabled(hdcache) != 0U) + { + /* Update the error code */ + hdcache->ErrorCode = HAL_DCACHE_ERROR_NONE; + + /* Change DCACHE handle state */ + hdcache->State = HAL_DCACHE_STATE_READY; + + /* Disable the selected DCACHE peripheral */ + CLEAR_BIT(hdcache->Instance->CR, DCACHE_CR_EN); + + /* Get timeout */ + tickstart = HAL_GetTick(); + + /* Wait for end of data cache disabling */ + while (READ_BIT(hdcache->Instance->SR, (DCACHE_SR_BUSYF | DCACHE_SR_BUSYCMDF)) != 0U) + { + if ((HAL_GetTick() - tickstart) > DCACHE_DISABLE_TIMEOUT_VALUE) + { + if (READ_BIT(hdcache->Instance->SR, (DCACHE_SR_BUSYF | DCACHE_SR_BUSYCMDF)) != 0U) + { + /* Update error code */ + hdcache->ErrorCode = HAL_DCACHE_ERROR_TIMEOUT; + + /* Change the DCACHE handle state */ + hdcache->State = HAL_DCACHE_STATE_READY; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + } + } + + return status; +} +/** + * @brief Check whether the Data Cache is enabled or not. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @retval Status (0: disabled, 1: enabled) + */ +uint32_t HAL_DCACHE_IsEnabled(const DCACHE_HandleTypeDef *hdcache) +{ + return ((READ_BIT(hdcache->Instance->CR, DCACHE_CR_EN) != 0U) ? 1UL : 0UL); +} + +/** + * @brief Set Read Burst Type. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @param ReadBurstType Burst type to be applied for Data Cache + * DCACHE_READ_BURST_WRAP, DCACHE_READ_BURST_INC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCACHE_SetReadBurstType(DCACHE_HandleTypeDef *hdcache, uint32_t ReadBurstType) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the dcache handle allocation */ + if (hdcache == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); + assert_param(IS_DCACHE_READ_BURST_TYPE(ReadBurstType)); + + /* check DCACHE status */ + if (HAL_DCACHE_IsEnabled(hdcache) == 0U) + { + /* Set requested read burst type */ + MODIFY_REG(hdcache->Instance->CR, DCACHE_CR_HBURST, ReadBurstType); + } + else + { + /* Update the error code */ + hdcache->ErrorCode = HAL_DCACHE_ERROR_INVALID_OPERATION; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Invalidate the Data cache. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @note This function waits for end of full cache invalidation + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCACHE_Invalidate(DCACHE_HandleTypeDef *hdcache) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tickstart; + + /* Check the dcache handle allocation */ + if (hdcache == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); + + /* Check no ongoing operation */ + if (READ_BIT(hdcache->Instance->SR, (DCACHE_SR_BUSYF | DCACHE_SR_BUSYCMDF)) != 0U) + { + /* Return busy status */ + status = HAL_BUSY; + } + else + { + /* Update the error code */ + hdcache->ErrorCode = HAL_DCACHE_ERROR_NONE; + + /* Change DCACHE Handle state */ + hdcache->State = HAL_DCACHE_STATE_READY; + + /* Make sure flags are reset */ + WRITE_REG(hdcache->Instance->FCR, (DCACHE_FCR_CBSYENDF | DCACHE_FCR_CCMDENDF)); + + /* Set no operation on address range */ + MODIFY_REG(hdcache->Instance->CR, DCACHE_CR_CACHECMD, 0U); + + /* Launch cache invalidation */ + SET_BIT(hdcache->Instance->CR, DCACHE_CR_CACHEINV); + + /* Get timeout */ + tickstart = HAL_GetTick(); + + /* Wait for end of cache invalidation */ + while (READ_BIT(hdcache->Instance->SR, DCACHE_SR_BUSYF) != 0U) + { + if ((HAL_GetTick() - tickstart) > DCACHE_COMMAND_TIMEOUT_VALUE) + { + if (READ_BIT(hdcache->Instance->SR, DCACHE_SR_BUSYF) != 0U) + { + /* Update error code */ + hdcache->ErrorCode = HAL_DCACHE_ERROR_TIMEOUT; + + /* Change the DCACHE state */ + hdcache->State = HAL_DCACHE_STATE_ERROR; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + } + } + + return status; +} + +/** + * @brief Invalidate the Data cache for a specific region. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @param pAddr Start address of the region to be Invalidated + * @param dSize Size of the region to be Invalidated(in bytes) + * @note This function waits for end of cache Invalidation + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCACHE_InvalidateByAddr(DCACHE_HandleTypeDef *hdcache, const uint32_t *const pAddr, + uint32_t dSize) +{ + HAL_StatusTypeDef status; + + /* Check the dcache handle allocation */ + if (hdcache == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); + assert_param(IS_DCACHE_REGION_SIZE(dSize)); + + status = DCACHE_CommandByAddr(hdcache, DCACHE_COMMAND_INVALIDATE, pAddr, dSize, DCACHE_POLLING_MODE); + + return status; +} + +/** + * @brief Clean the Data cache by Addr. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @param pAddr Start address of the region to be Cleaned + * @param dSize Size of the region to be Cleaned (in bytes) + * @note This function waits for end of cache Clean + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCACHE_CleanByAddr(DCACHE_HandleTypeDef *hdcache, const uint32_t *const pAddr, uint32_t dSize) +{ + HAL_StatusTypeDef status; + + /* Check the dcache handle allocation */ + if (hdcache == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); + assert_param(IS_DCACHE_REGION_SIZE(dSize)); + + status = DCACHE_CommandByAddr(hdcache, DCACHE_COMMAND_CLEAN, pAddr, dSize, DCACHE_POLLING_MODE); + + return status; +} + +/** + * @brief Clean and Invalidate the Data cache by Addr. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @param pAddr Start address of the region to be Cleaned and Invalidated + * @param dSize Size of the region to be Cleaned and Invalidated (in bytes) + * @note This function waits for end of cache Clean and Invalidation + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCACHE_CleanInvalidByAddr(DCACHE_HandleTypeDef *hdcache, const uint32_t *const pAddr, + uint32_t dSize) +{ + HAL_StatusTypeDef status; + + /* Check the dcache handle allocation */ + if (hdcache == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); + assert_param(IS_DCACHE_REGION_SIZE(dSize)); + + status = DCACHE_CommandByAddr(hdcache, DCACHE_COMMAND_CLEAN_INVALIDATE, pAddr, dSize, DCACHE_POLLING_MODE); + + return status; +} + +/** + * @brief Invalidate the Data cache with interrupt. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @note This function launches maintenance operation and returns immediately. + * User application shall resort to interrupt generation to check + * the end of operation. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCACHE_Invalidate_IT(DCACHE_HandleTypeDef *hdcache) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the dcache handle allocation */ + if (hdcache == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); + + /* Check no ongoing operation */ + if (READ_BIT(hdcache->Instance->SR, (DCACHE_SR_BUSYF | DCACHE_SR_BUSYCMDF)) != 0U) + { + /* Return busy status */ + status = HAL_BUSY; + } + else + { + /* Update the error code */ + hdcache->ErrorCode = HAL_DCACHE_ERROR_NONE; + + /* Change DCACHE Handle state */ + hdcache->State = HAL_DCACHE_STATE_READY; + + /* Make sure BSYENDF is reset */ + WRITE_REG(hdcache->Instance->FCR, (DCACHE_FCR_CBSYENDF | DCACHE_FCR_CCMDENDF)); + + /* Set no operation on address range for callback under interrupt */ + MODIFY_REG(hdcache->Instance->CR, DCACHE_CR_CACHECMD, 0U); + + /* Enable end of cache invalidation interrupt */ + SET_BIT(hdcache->Instance->IER, DCACHE_IER_BSYENDIE); + + /* Launch cache invalidation */ + SET_BIT(hdcache->Instance->CR, DCACHE_CR_CACHEINV); + } + + return status; +} + +/** + * @brief Invalidate the Data cache by Addr with interrupt. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @param pAddr Start address of the region to be Invalidated + * @param dSize Size of the region to be Invalidated + * @note This function launches maintenance operation and returns immediately. + * User application shall resort to interrupt generation to check + * the end of operation. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCACHE_InvalidateByAddr_IT(DCACHE_HandleTypeDef *hdcache, const uint32_t *const pAddr, + uint32_t dSize) +{ + HAL_StatusTypeDef status; + + /* Check the dcache handle allocation */ + if (hdcache == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); + assert_param(IS_DCACHE_REGION_SIZE(dSize)); + + status = DCACHE_CommandByAddr(hdcache, DCACHE_COMMAND_INVALIDATE, pAddr, dSize, DCACHE_IT_MODE); + + return status; +} + +/** + * @brief Clean the Data cache by Addr with interrupt. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @param pAddr Start address of the region to be Cleaned + * @param dSize Size of the region to be Cleaned + * @note This function launches maintenance operation and returns immediately. + * User application shall resort to interrupt generation to check + * the end of operation. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCACHE_CleanByAddr_IT(DCACHE_HandleTypeDef *hdcache, const uint32_t *const pAddr, + uint32_t dSize) +{ + HAL_StatusTypeDef status; + + /* Check the dcache handle allocation */ + if (hdcache == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); + assert_param(IS_DCACHE_REGION_SIZE(dSize)); + + status = DCACHE_CommandByAddr(hdcache, DCACHE_COMMAND_CLEAN, pAddr, dSize, DCACHE_IT_MODE); + + return status; +} + +/** + * @brief Clean and Invalidate the Data cache by Addr with interrupt. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @param pAddr Start address of the region to be Cleaned and Invalidated + * @param dSize Size of the region to be Cleaned and Invalidated + * @note This function launches maintenance operation and returns immediately. + * User application shall resort to interrupt generation to check + * the end of operation. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCACHE_CleanInvalidByAddr_IT(DCACHE_HandleTypeDef *hdcache, const uint32_t *const pAddr, + uint32_t dSize) +{ + HAL_StatusTypeDef status; + + /* Check the dcache handle allocation */ + if (hdcache == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); + assert_param(IS_DCACHE_REGION_SIZE(dSize)); + + status = DCACHE_CommandByAddr(hdcache, DCACHE_COMMAND_CLEAN_INVALIDATE, pAddr, dSize, DCACHE_IT_MODE); + + return status; +} + +/** + * @brief Start the Data Cache performance monitoring. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @param MonitorType Monitoring type + * This parameter can be a combination of the following values: + * @arg DCACHE_MONITOR_READ_HIT + * @arg DCACHE_MONITOR_READ_MISS + * @arg DCACHE_MONITOR_WRITE_HIT + * @arg DCACHE_MONITOR_WRITE_MISS + * @arg DCACHE_MONITOR_ALL + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCACHE_Monitor_Start(DCACHE_HandleTypeDef *hdcache, uint32_t MonitorType) +{ + /* Check the dcache handle allocation */ + if (hdcache == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); + assert_param(IS_DCACHE_MONITOR_TYPE(MonitorType)); + + SET_BIT(hdcache->Instance->CR, MonitorType); + + return HAL_OK; +} + +/** + * @brief Stop the Data Cache performance monitoring. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @note Stopping the monitoring does not reset the values. + * @param MonitorType Monitoring type + * This parameter can be a combination of the following values: + * @arg DCACHE_MONITOR_READ_HIT + * @arg DCACHE_MONITOR_READ_MISS + * @arg DCACHE_MONITOR_WRITE_HIT + * @arg DCACHE_MONITOR_WRITE_MISS + * @arg DCACHE_MONITOR_ALL + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCACHE_Monitor_Stop(DCACHE_HandleTypeDef *hdcache, uint32_t MonitorType) +{ + /* Check the dcache handle allocation */ + if (hdcache == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); + assert_param(IS_DCACHE_MONITOR_TYPE(MonitorType)); + + CLEAR_BIT(hdcache->Instance->CR, MonitorType); + + return HAL_OK; +} + +/** + * @brief Reset the Data Cache performance monitoring values. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @param MonitorType Monitoring type + * This parameter can be a combination of the following values: + * @arg DCACHE_MONITOR_READ_HIT + * @arg DCACHE_MONITOR_READ_MISS + * @arg DCACHE_MONITOR_WRITE_HIT + * @arg DCACHE_MONITOR_WRITE_MISS + * @arg DCACHE_MONITOR_ALL + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCACHE_Monitor_Reset(DCACHE_HandleTypeDef *hdcache, uint32_t MonitorType) +{ + /* Check the dcache handle allocation */ + if (hdcache == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); + assert_param(IS_DCACHE_MONITOR_TYPE(MonitorType)); + + /* Force/Release reset */ + SET_BIT(hdcache->Instance->CR, (MonitorType << 2U)); + CLEAR_BIT(hdcache->Instance->CR, (MonitorType << 2U)); + + return HAL_OK; +} + +/** + * @brief Get the Data Cache performance Read Hit monitoring value. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @note Upon reaching the 32-bit maximum value, monitor does not wrap. + * @retval Read Hit monitoring value + */ +uint32_t HAL_DCACHE_Monitor_GetReadHitValue(const DCACHE_HandleTypeDef *hdcache) +{ + /* Check the parameters */ + assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); + + /*return the Read Hit monitor value*/ + return hdcache->Instance->RHMONR; +} + +/** + * @brief Get the Data Cache performance Read Miss monitoring value. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @note Upon reaching the 16-bit maximum value, monitor does not wrap. + * @retval Read Miss monitoring value + */ +uint32_t HAL_DCACHE_Monitor_GetReadMissValue(const DCACHE_HandleTypeDef *hdcache) +{ + /* Check the parameters */ + assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); + + /*return the Read Miss monitor value*/ + return hdcache->Instance->RMMONR; +} + +/** + * @brief Get the Data Cache performance Write Hit monitoring value. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @note Upon reaching the 32-bit maximum value, monitor does not wrap. + * @retval Write Hit monitoring value + */ +uint32_t HAL_DCACHE_Monitor_GetWriteHitValue(const DCACHE_HandleTypeDef *hdcache) +{ + /* Check the parameters */ + assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); + + /*return the Write Hit monitor value*/ + return hdcache->Instance->WHMONR; +} + +/** + * @brief Get the Data Cache performance Write Miss monitoring value. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @note Upon reaching the 16-bit maximum value, monitor does not wrap. + * @retval Write Miss monitoring value + */ +uint32_t HAL_DCACHE_Monitor_GetWriteMissValue(const DCACHE_HandleTypeDef *hdcache) +{ + /* Check the parameters */ + assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); + + /*return the Write Miss monitor value*/ + return hdcache->Instance->WMMONR; +} + +/** + * @brief Handle the Data Cache interrupt request. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @note This API should be called under the DCACHEx_IRQHandler(). + * @retval None + */ +void HAL_DCACHE_IRQHandler(DCACHE_HandleTypeDef *hdcache) +{ + uint32_t itflags; + uint32_t itsources; + + /* Check the parameters */ + assert_param(IS_DCACHE_ALL_INSTANCE(hdcache->Instance)); + + /* Get current interrupt flags and interrupt sources value */ + itflags = READ_REG(hdcache->Instance->SR); + itsources = READ_REG(hdcache->Instance->IER); + + /* Check Data cache Error interrupt flag */ + if (((itflags & itsources) & DCACHE_FLAG_ERROR) != 0U) + { + /* Clear DCACHE error pending flag */ + __HAL_DCACHE_CLEAR_FLAG(hdcache, DCACHE_FLAG_ERROR); + + /* Update data cache error code */ + hdcache->ErrorCode = HAL_DCACHE_ERROR_EVICTION_CLEAN; + + /* Data cache error interrupt user callback */ + hdcache->ErrorCallback(hdcache); + } + + /* Check for end of full invalidate operation */ + if (READ_BIT(hdcache->Instance->CR, DCACHE_CR_CACHECMD) == 0U) + { + /* Clear DCACHE busyend pending flag */ + __HAL_DCACHE_CLEAR_FLAG(hdcache, DCACHE_FLAG_BUSYEND); + + /* Data cache invalidate complete interrupt user callback */ + hdcache->InvalidateCompleteCallback(hdcache); + } + + /* Check for end of clean and invalidate by address operation */ + else if (READ_BIT(hdcache->Instance->CR, DCACHE_COMMAND_CLEAN_INVALIDATE) == \ + (DCACHE_COMMAND_CLEAN_INVALIDATE)) + { + /* Clear DCACHE cmdend pending flag */ + __HAL_DCACHE_CLEAR_FLAG(hdcache, DCACHE_FLAG_CMDEND); + + /* Data cache clean and invalidate range cmdend interrupt user callback */ + hdcache->CleanAndInvalidateByAddrCallback(hdcache); + } + + /* Check for end of clean by address operation */ + else if (READ_BIT(hdcache->Instance->CR, DCACHE_COMMAND_CLEAN) == DCACHE_COMMAND_CLEAN) + { + /* Clear DCACHE cmdend pending flag */ + __HAL_DCACHE_CLEAR_FLAG(hdcache, DCACHE_FLAG_CMDEND); + + /* Data cache clean range cmdend interrupt user callback */ + hdcache->CleanByAddrCallback(hdcache); + } + + /* Check for end of invalidate by address operation */ + else + { + /* Clear DCACHE cmdend pending flag */ + __HAL_DCACHE_CLEAR_FLAG(hdcache, DCACHE_FLAG_CMDEND); + + /* Data cache Invalidate range cmdend interrupt user callback */ + hdcache->InvalidateByAddrCallback(hdcache); + } +} + +/** + * @brief Register a User DCACHE Callback + * To be used instead of the weak predefined callback + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_DCACHE_CLEAN_BY_ADDRESS_CB_ID Clean By Addr callback ID + * @arg @ref HAL_DCACHE_INVALIDATE_BY_ADDRESS_CB_ID Invalidate By Addr callback ID + * @arg @ref HAL_DCACHE_CLEAN_AND_INVALIDATE_BY_ADDRESS_CB_ID Clean and Invalidate By Addr callback ID + * @arg @ref HAL_DCACHE_INVALIDATE_COMPLETE_CB_ID Invalidate Complete ID + * @arg @ref HAL_DCACHE_ERROR_CB_ID Error callback ID + * @arg @ref HAL_DCACHE_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_DCACHE_MSPDEINIT_CB_ID MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCACHE_RegisterCallback(DCACHE_HandleTypeDef *hdcache, HAL_DCACHE_CallbackIDTypeDef CallbackID, + pDCACHE_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the dcache handle allocation */ + if (hdcache == NULL) + { + return HAL_ERROR; + } + + if (pCallback == NULL) + { + /* Update the error code */ + hdcache->ErrorCode |= HAL_DCACHE_ERROR_INVALID_CALLBACK; + + /* Return error status */ + return HAL_ERROR; + } + + if (hdcache->State == HAL_DCACHE_STATE_READY) + { + switch (CallbackID) + { + case HAL_DCACHE_CLEAN_BY_ADDRESS_CB_ID : + hdcache->CleanByAddrCallback = pCallback; + break; + + case HAL_DCACHE_INVALIDATE_BY_ADDRESS_CB_ID : + hdcache->InvalidateByAddrCallback = pCallback; + break; + + case HAL_DCACHE_CLEAN_AND_INVALIDATE_BY_ADDRESS_CB_ID : + hdcache->CleanAndInvalidateByAddrCallback = pCallback; + break; + + case HAL_DCACHE_INVALIDATE_COMPLETE_CB_ID : + hdcache->InvalidateCompleteCallback = pCallback; + break; + + case HAL_DCACHE_ERROR_CB_ID : + hdcache->ErrorCallback = pCallback; + break; + + case HAL_DCACHE_MSPINIT_CB_ID : + hdcache->MspInitCallback = pCallback; + break; + + case HAL_DCACHE_MSPDEINIT_CB_ID : + hdcache->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hdcache->ErrorCode |= HAL_DCACHE_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (hdcache->State == HAL_DCACHE_STATE_RESET) + { + switch (CallbackID) + { + case HAL_DCACHE_MSPINIT_CB_ID : + hdcache->MspInitCallback = pCallback; + break; + + case HAL_DCACHE_MSPDEINIT_CB_ID : + hdcache->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hdcache->ErrorCode |= HAL_DCACHE_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hdcache->ErrorCode |= HAL_DCACHE_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister an DCACHE Callback + * DCACHE callback is redirected to the weak predefined callback + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_DCACHE_CLEAN_BY_ADDRESS_CB_ID Clean By Addr callback ID + * @arg @ref HAL_DCACHE_INVALIDATE_BY_ADDRESS_CB_ID Invalidate By Addr callback ID + * @arg @ref HAL_DCACHE_CLEAN_AND_INVALIDATE_BY_ADDRESS_CB_ID Clean and Invalidate By Addr callback ID + * @arg @ref HAL_DCACHE_INVALIDATE_COMPLETE_CB_ID Invalidate Complete callback ID + * @arg @ref HAL_DCACHE_ERROR_CB_ID Error callback ID + * @arg @ref HAL_DCACHE_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_DCACHE_MSPDEINIT_CB_ID MspDeInit callback ID + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCACHE_UnRegisterCallback(DCACHE_HandleTypeDef *hdcache, HAL_DCACHE_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the dcache handle allocation */ + if (hdcache == NULL) + { + return HAL_ERROR; + } + + if (hdcache->State == HAL_DCACHE_STATE_READY) + { + switch (CallbackID) + { + case HAL_DCACHE_CLEAN_BY_ADDRESS_CB_ID : + /* Legacy weak Clean By Addr Callback */ + hdcache->CleanByAddrCallback = HAL_DCACHE_CleanByAddrCallback; + break; + + case HAL_DCACHE_INVALIDATE_BY_ADDRESS_CB_ID : + /* Legacy weak Invalidate By Addr Callback */ + hdcache->InvalidateByAddrCallback = HAL_DCACHE_InvalidateByAddrCallback; + break; + + case HAL_DCACHE_CLEAN_AND_INVALIDATE_BY_ADDRESS_CB_ID : + /* Legacy weak Clean and Invalidate By Addr Callback */ + hdcache->CleanAndInvalidateByAddrCallback = HAL_DCACHE_CleanAndInvalidateByAddrCallback; + break; + + case HAL_DCACHE_INVALIDATE_COMPLETE_CB_ID : + /* Legacy weak Invalidate Complete Callback */ + hdcache->InvalidateCompleteCallback = HAL_DCACHE_InvalidateCompleteCallback; + break; + + case HAL_DCACHE_ERROR_CB_ID : + /* Legacy weak ErrorCallback */ + hdcache->ErrorCallback = HAL_DCACHE_ErrorCallback; + break; + + case HAL_DCACHE_MSPINIT_CB_ID : + /* Legacy weak MspInit */ + hdcache->MspInitCallback = HAL_DCACHE_MspInit; + break; + + case HAL_DCACHE_MSPDEINIT_CB_ID : + /* Legacy weak MspDeInit */ + hdcache->MspDeInitCallback = HAL_DCACHE_MspDeInit; + break; + + default : + /* Update the error code */ + hdcache->ErrorCode |= HAL_DCACHE_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_DCACHE_STATE_RESET == hdcache->State) + { + switch (CallbackID) + { + case HAL_DCACHE_MSPINIT_CB_ID : + /* Legacy weak MspInit */ + hdcache->MspInitCallback = HAL_DCACHE_MspInit; + break; + + case HAL_DCACHE_MSPDEINIT_CB_ID : + /* Legacy weak MspDeInit */ + hdcache->MspDeInitCallback = HAL_DCACHE_MspDeInit; + break; + + default : + /* Update the error code */ + hdcache->ErrorCode |= HAL_DCACHE_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hdcache->ErrorCode |= HAL_DCACHE_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Cache clean command by address callback. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @retval None + */ +__weak void HAL_DCACHE_CleanByAddrCallback(DCACHE_HandleTypeDef *hdcache) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdcache); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_DCACHE_CleanByAddrCallback() should be implemented in the user file + */ +} + +/** + * @brief Cache Invalidate command by address callback. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @retval None + */ +__weak void HAL_DCACHE_InvalidateByAddrCallback(DCACHE_HandleTypeDef *hdcache) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdcache); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_DCACHE_InvalidateByAddrCallback() should be implemented in the user file + */ +} + +/** + * @brief Cache clean and Invalidate command by address callback. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @retval None + */ +__weak void HAL_DCACHE_CleanAndInvalidateByAddrCallback(DCACHE_HandleTypeDef *hdcache) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdcache); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_DCACHE_CleanAndInvalidateByAddrCallback() should be implemented in the user file + */ +} + +/** + * @brief Cache full invalidation complete callback. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @retval None + */ +__weak void HAL_DCACHE_InvalidateCompleteCallback(DCACHE_HandleTypeDef *hdcache) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdcache); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_DCACHE_InvalidateCompleteCallback() should be implemented in the user file + */ +} + +/** + * @brief Error callback. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @retval None + */ +__weak void HAL_DCACHE_ErrorCallback(DCACHE_HandleTypeDef *hdcache) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdcache); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_DCACHE_ErrorCallback() should be implemented in the user file + */ +} + +/** + * @} + */ + +/** @addtogroup DCACHE_Exported_Functions_Group3 + * +@verbatim + =============================================================================== + ##### Peripheral State ##### + =============================================================================== + [..] + This subsection permit to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the DCACHE handle state. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @retval HAL state + */ +HAL_DCACHE_StateTypeDef HAL_DCACHE_GetState(const DCACHE_HandleTypeDef *hdcache) +{ + /* Return DCACHE handle state */ + return hdcache->State; +} + +/** + * @brief Return the DCACHE error code + * @param hdcache pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHE. + * @retval DCACHE Error Code + */ +uint32_t HAL_DCACHE_GetError(const DCACHE_HandleTypeDef *hdcache) +{ + /* Return DCACHE handle error code */ + return hdcache->ErrorCode; +} + +/** + * @} + */ + +/* Private functions -------------------------------------------------------------------------------------------------*/ +/** @defgroup DCACHE_Private_Functions DCACHE Private Functions + * @brief DCACHE Private Functions + * @{ + */ + +/** + * @brief Launch DCACHE command Clean, Invalidate or clean and invalidate by Addr. + * @param hdcache Pointer to a DCACHE_HandleTypeDef structure that contains + * the configuration information for the specified DCACHEx peripheral. + * @param Command command to be applied for the DCACHE + * DCACHE_COMMAND_INVALIDATE, DCACHE_COMMAND_CLEAN, DCACHE_COMMAND_CLEAN_INVALIDATE + * @param pAddr Start address of region to be Cleaned, Invalidated or Cleaned and Invalidated. + * @param dSize Size of the region to be Cleaned, Invalidated or Cleaned and Invalidated (in bytes). + * @param mode mode to be applied for the DCACHE + * DCACHE_IT_MODE, DCACHE_POLLING_MODE. + * @retval HAL status + */ +static HAL_StatusTypeDef DCACHE_CommandByAddr(DCACHE_HandleTypeDef *hdcache, uint32_t Command, + const uint32_t *const pAddr, uint32_t dSize, uint32_t mode) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t op_addr = (uint32_t)pAddr; + uint32_t tickstart; + + /* Check no ongoing operation */ + if (READ_BIT(hdcache->Instance->SR, (DCACHE_SR_BUSYF | DCACHE_SR_BUSYCMDF)) != 0U) + { + /* Return busy status */ + status = HAL_BUSY; + } + else + { + /* Update the error code */ + hdcache->ErrorCode = HAL_DCACHE_ERROR_NONE; + + /* Update the DCACHE handle State */ + hdcache->State = HAL_DCACHE_STATE_READY; + + /* Make sure flags are reset */ + WRITE_REG(hdcache->Instance->FCR, (DCACHE_FCR_CBSYENDF | DCACHE_FCR_CCMDENDF)); + + /* Fill area start address */ + WRITE_REG(hdcache->Instance->CMDRSADDRR, op_addr); + + /* Fill area end address */ + WRITE_REG(hdcache->Instance->CMDREADDRR, (op_addr + dSize - 1U)); + + /* Set command */ + MODIFY_REG(hdcache->Instance->CR, DCACHE_CR_CACHECMD, Command); + + /* Enable IT if required */ + if (mode == DCACHE_IT_MODE) + { + /* Enable end of cache command interrupt */ + SET_BIT(hdcache->Instance->IER, DCACHE_IER_CMDENDIE); + + /* Launch cache command */ + SET_BIT(hdcache->Instance->CR, DCACHE_CR_STARTCMD); + } + else + { + /* Make sure that end of cache command interrupt is disabled */ + CLEAR_BIT(hdcache->Instance->IER, DCACHE_IER_CMDENDIE); + + /* Launch cache command */ + SET_BIT(hdcache->Instance->CR, DCACHE_CR_STARTCMD); + + /* Get timeout */ + tickstart = HAL_GetTick(); + + /* Wait for end of cache command */ + while (READ_BIT(hdcache->Instance->SR, DCACHE_SR_CMDENDF) == 0U) + { + if ((HAL_GetTick() - tickstart) > DCACHE_COMMAND_TIMEOUT_VALUE) + { + if (READ_BIT(hdcache->Instance->SR, DCACHE_SR_CMDENDF) == 0U) + { + /* Update error code */ + hdcache->ErrorCode = HAL_DCACHE_ERROR_TIMEOUT; + + /* Change the DCACHE state */ + hdcache->State = HAL_DCACHE_STATE_ERROR; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + } + } + } + + return status; +} + +/** + * @} + */ + +#endif /* HAL_DCACHE_MODULE_ENABLED */ +#endif /* DCACHE1 */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dcmi.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dcmi.c new file mode 100644 index 0000000000..70917f5268 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dcmi.c @@ -0,0 +1,1374 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_dcmi.c + * @author MCD Application Team + * @brief DCMI HAL module driver + * This file provides firmware functions to manage the following + * functionalities of the Digital Camera Interface (DCMI) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State and Error functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The sequence below describes how to use this driver to capture image + from a camera module connected to the DCMI Interface. + This sequence does not take into account the configuration of the + camera module, which should be made before to configure and enable + the DCMI to capture images. + + (#) Program the required configuration through following parameters: + horizontal and vertical polarity, pixel clock polarity, Capture Rate, + Synchronization Mode, code of the frame delimiter and data width + using HAL_DCMI_Init() function. + + (#) Configure the selected DMA stream to transfer Data from DCMI DR + register to the destination memory buffer. + + (#) Program the required configuration through following parameters: + DCMI mode, destination memory Buffer address and the data length + and enable capture using HAL_DCMI_Start_DMA() function. + + (#) Optionally, configure and Enable the CROP feature to select a rectangular + window from the received image using HAL_DCMI_ConfigCrop() + and HAL_DCMI_EnableCrop() functions + + (#) The capture can be stopped using HAL_DCMI_Stop() function. + + (#) To control DCMI state you can use the function HAL_DCMI_GetState(). + + *** DCMI HAL driver macros list *** + ============================================= + [..] + Below the list of most used macros in DCMI HAL driver. + + (+) __HAL_DCMI_ENABLE: Enable the DCMI peripheral. + (+) __HAL_DCMI_DISABLE: Disable the DCMI peripheral. + (+) __HAL_DCMI_GET_FLAG: Get the DCMI pending flags. + (+) __HAL_DCMI_CLEAR_FLAG: Clear the DCMI pending flags. + (+) __HAL_DCMI_ENABLE_IT: Enable the specified DCMI interrupts. + (+) __HAL_DCMI_DISABLE_IT: Disable the specified DCMI interrupts. + (+) __HAL_DCMI_GET_IT_SOURCE: Check whether the specified DCMI interrupt has occurred or not. + + [..] + (@) You can refer to the DCMI HAL driver header file for more useful macros + + *** Callback registration *** + ============================= + + The compilation define USE_HAL_DCMI_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + Use functions HAL_DCMI_RegisterCallback() to register a user callback. + + Function HAL_DCMI_RegisterCallback() allows to register following callbacks: + (+) FrameEventCallback : callback for DCMI Frame Event. + (+) VsyncEventCallback : callback for DCMI Vsync Event. + (+) LineEventCallback : callback for DCMI Line Event. + (+) ErrorCallback : callback for DCMI error detection. + (+) MspInitCallback : callback for DCMI MspInit. + (+) MspDeInitCallback : callback for DCMI MspDeInit. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + + Use function HAL_DCMI_UnRegisterCallback() to reset a callback to the default + weak (surcharged) function. + HAL_DCMI_UnRegisterCallback() takes as parameters the HAL peripheral handle, + and the callback ID. + This function allows to reset following callbacks: + (+) FrameEventCallback : callback for DCMI Frame Event. + (+) VsyncEventCallback : callback for DCMI Vsync Event. + (+) LineEventCallback : callback for DCMI Line Event. + (+) ErrorCallback : callback for DCMI error. + (+) MspInitCallback : callback for DCMI MspInit. + (+) MspDeInitCallback : callback for DCMI MspDeInit. + + By default, after the HAL_DCMI_Init and if the state is HAL_DCMI_STATE_RESET + all callbacks are reset to the corresponding legacy weak (surcharged) functions: + examples FrameEventCallback(), HAL_DCMI_ErrorCallback(). + Exception done for MspInit and MspDeInit callbacks that are respectively + reset to the legacy weak (surcharged) functions in the HAL_DCMI_Init + and HAL_DCMI_DeInit only when these callbacks are null (not registered beforehand). + If not, MspInit or MspDeInit are not null, the HAL_DCMI_Init and HAL_DCMI_DeInit + keep and use the user MspInit/MspDeInit callbacks (registered beforehand). + + Callbacks can be registered/unregistered in READY state only. + Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered + in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used + during the Init/DeInit. + In that case first register the MspInit/MspDeInit user callbacks + using HAL_DCMI_RegisterCallback before calling HAL_DCMI_DeInit + or HAL_DCMI_Init function. + + When the compilation define USE_HAL_DCMI_REGISTER_CALLBACKS is set to 0 or + not defined, the callback registering feature is not available + and weak (surcharged) callbacks are used. + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" +#ifdef HAL_DCMI_MODULE_ENABLED +#if defined (DCMI) + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ +/** @defgroup DCMI DCMI + * @brief DCMI HAL module driver + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup DCMI_Private_Constants DCMI Private Constants + * @{ + */ + +/** @defgroup DCMI_Stop_TimeOut DCMI Stop Time Out + * @{ + */ +#define HAL_TIMEOUT_DCMI_STOP ((uint32_t)1000) /* Set timeout to 1s */ +/** + * @} + */ + +/** + * @} + */ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup DCMI_Private_Functions DCMI Private Functions + * @{ + */ +static void DCMI_DMAXferCplt(DMA_HandleTypeDef *hdma); +static void DCMI_DMAError(DMA_HandleTypeDef *hdma); + +/** + * @} + */ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup DCMI_Exported_Functions DCMI Exported Functions + * @{ + */ + +/** @defgroup DCMI_Exported_Functions_Group1 Initialization and Configuration functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and Configuration functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Initialize and configure the DCMI + (+) De-initialize the DCMI + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the DCMI according to the specified + * parameters in the DCMI_InitTypeDef and create the associated handle. + * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCMI_Init(DCMI_HandleTypeDef *hdcmi) +{ + /* Check the DCMI peripheral state */ + if (hdcmi == NULL) + { + return HAL_ERROR; + } + + /* Check function parameters */ + assert_param(IS_DCMI_ALL_INSTANCE(hdcmi->Instance)); + assert_param(IS_DCMI_PCKPOLARITY(hdcmi->Init.PCKPolarity)); + assert_param(IS_DCMI_VSPOLARITY(hdcmi->Init.VSPolarity)); + assert_param(IS_DCMI_HSPOLARITY(hdcmi->Init.HSPolarity)); + assert_param(IS_DCMI_SYNCHRO(hdcmi->Init.SynchroMode)); + assert_param(IS_DCMI_CAPTURE_RATE(hdcmi->Init.CaptureRate)); + assert_param(IS_DCMI_EXTENDED_DATA(hdcmi->Init.ExtendedDataMode)); + assert_param(IS_DCMI_MODE_JPEG(hdcmi->Init.JPEGMode)); + + assert_param(IS_DCMI_BYTE_SELECT_MODE(hdcmi->Init.ByteSelectMode)); + assert_param(IS_DCMI_BYTE_SELECT_START(hdcmi->Init.ByteSelectStart)); + assert_param(IS_DCMI_LINE_SELECT_MODE(hdcmi->Init.LineSelectMode)); + assert_param(IS_DCMI_LINE_SELECT_START(hdcmi->Init.LineSelectStart)); + + if (hdcmi->State == HAL_DCMI_STATE_RESET) + { + /* Init the DCMI Callback settings */ +#if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1) + /* Reset callback pointers to the weak predefined callbacks */ + hdcmi->FrameEventCallback = HAL_DCMI_FrameEventCallback; /* Legacy weak FrameEventCallback */ + hdcmi->VsyncEventCallback = HAL_DCMI_VsyncEventCallback; /* Legacy weak VsyncEventCallback */ + hdcmi->LineEventCallback = HAL_DCMI_LineEventCallback; /* Legacy weak LineEventCallback */ + hdcmi->ErrorCallback = HAL_DCMI_ErrorCallback; /* Legacy weak ErrorCallback */ + + if (hdcmi->MspInitCallback == NULL) + { + /* Legacy weak MspInit Callback */ + hdcmi->MspInitCallback = HAL_DCMI_MspInit; + } + /* Initialize the low level hardware (MSP) */ + hdcmi->MspInitCallback(hdcmi); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + HAL_DCMI_MspInit(hdcmi); +#endif /* (USE_HAL_DCMI_REGISTER_CALLBACKS) */ + } + + /* Change the DCMI state */ + hdcmi->State = HAL_DCMI_STATE_BUSY; + + if (hdcmi->Init.ExtendedDataMode != DCMI_EXTEND_DATA_8B) + { + /* Byte select mode must be programmed to the reset value if the extended mode + is not set to 8-bit data capture on every pixel clock */ + hdcmi->Init.ByteSelectMode = DCMI_BSM_ALL; + } + /* Configures the HS, VS, DE and PC polarity */ + hdcmi->Instance->CR &= ~(DCMI_CR_PCKPOL | DCMI_CR_HSPOL | DCMI_CR_VSPOL | DCMI_CR_EDM_0 | \ + DCMI_CR_EDM_1 | DCMI_CR_FCRC_0 | DCMI_CR_FCRC_1 | DCMI_CR_JPEG | \ + DCMI_CR_ESS | DCMI_CR_BSM_0 | DCMI_CR_BSM_1 | DCMI_CR_OEBS | \ + DCMI_CR_LSM | DCMI_CR_OELS); + + hdcmi->Instance->CR |= (uint32_t)(hdcmi->Init.SynchroMode | hdcmi->Init.CaptureRate | \ + hdcmi->Init.VSPolarity | hdcmi->Init.HSPolarity | \ + hdcmi->Init.PCKPolarity | hdcmi->Init.ExtendedDataMode | \ + hdcmi->Init.JPEGMode | hdcmi->Init.ByteSelectMode | \ + hdcmi->Init.ByteSelectStart | hdcmi->Init.LineSelectMode | \ + hdcmi->Init.LineSelectStart); + + if (hdcmi->Init.SynchroMode == DCMI_SYNCHRO_EMBEDDED) + { + hdcmi->Instance->ESCR = (((uint32_t)hdcmi->Init.SyncroCode.FrameStartCode) | \ + ((uint32_t)hdcmi->Init.SyncroCode.LineStartCode << DCMI_ESCR_LSC_Pos) | \ + ((uint32_t)hdcmi->Init.SyncroCode.LineEndCode << DCMI_ESCR_LEC_Pos) | \ + ((uint32_t)hdcmi->Init.SyncroCode.FrameEndCode << DCMI_ESCR_FEC_Pos)); + + } + + /* Enable the Line, Vsync, Error and Overrun interrupts */ + __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_LINE | DCMI_IT_VSYNC | DCMI_IT_ERR | DCMI_IT_OVR); + + /* Update error code */ + hdcmi->ErrorCode = HAL_DCMI_ERROR_NONE; + + /* Initialize the DCMI state*/ + hdcmi->State = HAL_DCMI_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Deinitializes the DCMI peripheral registers to their default reset + * values. + * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @retval HAL status + */ + +HAL_StatusTypeDef HAL_DCMI_DeInit(DCMI_HandleTypeDef *hdcmi) +{ +#if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1) + if (hdcmi->MspDeInitCallback == NULL) + { + hdcmi->MspDeInitCallback = HAL_DCMI_MspDeInit; + } + /* De-Initialize the low level hardware (MSP) */ + hdcmi->MspDeInitCallback(hdcmi); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */ + HAL_DCMI_MspDeInit(hdcmi); +#endif /* (USE_HAL_DCMI_REGISTER_CALLBACKS) */ + + /* Update error code */ + hdcmi->ErrorCode = HAL_DCMI_ERROR_NONE; + + /* Initialize the DCMI state*/ + hdcmi->State = HAL_DCMI_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hdcmi); + + return HAL_OK; +} + +/** + * @brief Initializes the DCMI MSP. + * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @retval None + */ +__weak void HAL_DCMI_MspInit(DCMI_HandleTypeDef *hdcmi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdcmi); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_DCMI_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes the DCMI MSP. + * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @retval None + */ +__weak void HAL_DCMI_MspDeInit(DCMI_HandleTypeDef *hdcmi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdcmi); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_DCMI_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ +/** @defgroup DCMI_Exported_Functions_Group2 IO operation functions + * @brief IO operation functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure destination address and data length and + Enables DCMI DMA request and enables DCMI capture + (+) Stop the DCMI capture. + (+) Handles DCMI interrupt request. + +@endverbatim + * @{ + */ + +/** + * @brief Enables DCMI DMA request and enables DCMI capture + * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @param DCMI_Mode DCMI capture mode snapshot or continuous grab. + * @param pData The destination memory Buffer address (LCD Frame buffer). + * @param Length The length of capture to be transferred. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCMI_Start_DMA(DCMI_HandleTypeDef *hdcmi, uint32_t DCMI_Mode, uint32_t pData, uint32_t Length) +{ + uint32_t tmp_length = Length; + HAL_StatusTypeDef status = HAL_OK; + uint32_t cllr_offset; + uint32_t tmp1; + uint32_t tmp2; + + /* Check function parameters */ + assert_param(IS_DCMI_CAPTURE_MODE(DCMI_Mode)); + + /* Process Locked */ + __HAL_LOCK(hdcmi); + + /* Lock the DCMI peripheral state */ + hdcmi->State = HAL_DCMI_STATE_BUSY; + + /* Enable DCMI by setting DCMIEN bit */ + __HAL_DCMI_ENABLE(hdcmi); + + /* Configure the DCMI Mode */ + hdcmi->Instance->CR &= ~(DCMI_CR_CM); + hdcmi->Instance->CR |= (uint32_t)(DCMI_Mode); + + /* Set the DMA memory0 conversion complete callback */ + hdcmi->DMA_Handle->XferCpltCallback = DCMI_DMAXferCplt; + + /* Set the DMA error callback */ + hdcmi->DMA_Handle->XferErrorCallback = DCMI_DMAError; + + /* Set the dma abort callback */ + hdcmi->DMA_Handle->XferAbortCallback = NULL; + + /* Reset transfer counters value */ + hdcmi->XferCount = 0; + hdcmi->XferTransferNumber = 0; + hdcmi->XferSize = 0; + hdcmi->pBuffPtr = 0; + + /* Length should be converted to number of bytes */ + tmp_length = tmp_length * 4U; + + if (tmp_length <= 0xFFFFU) + { + /* Continuoues Mode */ + /* Enable the DMA Stream */ + if ((hdcmi->DMA_Handle->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hdcmi->DMA_Handle->LinkedListQueue != 0U) && (hdcmi->DMA_Handle->LinkedListQueue->Head != 0U)) + { + /* Set Source , Destination , Length for DMA Xfer */ + + /* Set DMA data size */ + hdcmi->DMA_Handle->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = tmp_length; + /* Set DMA source address */ + hdcmi->DMA_Handle->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = \ + (uint32_t)&hdcmi->Instance->DR; + /* Set DMA destination address */ + hdcmi->DMA_Handle->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)pData; + + status = HAL_DMAEx_List_Start_IT(hdcmi->DMA_Handle); + } + else + { + /* Set Error Code */ + hdcmi->ErrorCode = HAL_DCMI_ERROR_DMA; + /* Change DCMI state */ + hdcmi->State = HAL_DCMI_STATE_READY; + /* Release Lock */ + __HAL_UNLOCK(hdcmi); + /* Return function status */ + status = HAL_ERROR; + } + } + else + { + status = HAL_DMA_Start_IT(hdcmi->DMA_Handle, (uint32_t)&hdcmi->Instance->DR, (uint32_t)pData, tmp_length); + } + } + else /* DCMI_DOUBLE_BUFFER Mode */ + { + /* Double buffering is used through 2 Nodes + Calculate the elementary size to be transferred by each node */ + + /* Initialize transfer parameters */ + hdcmi->XferCount = 1; + hdcmi->XferSize = tmp_length; + hdcmi->pBuffPtr = pData; + + /* Get the number of buffer */ + while (hdcmi->XferSize > 0xFFFFU) + { + hdcmi->XferSize = (hdcmi->XferSize / 2U); + hdcmi->XferCount = hdcmi->XferCount * 2U; + } + + /* Update DCMI counter and transfer number*/ + hdcmi->XferCount = (hdcmi->XferCount - 1U); + hdcmi->XferTransferNumber = hdcmi->XferCount; + + if ((hdcmi->DMA_Handle->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hdcmi->DMA_Handle->LinkedListQueue != 0U) && (hdcmi->DMA_Handle->LinkedListQueue->Head != 0U)) + { + /* Update first node */ + + /* Set DMA Data size */ + hdcmi->DMA_Handle->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hdcmi->XferSize ; + + /* Set DMA Source address */ + hdcmi->DMA_Handle->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = \ + (uint32_t)&hdcmi->Instance->DR; + + /* Set DMA Destination address */ + hdcmi->DMA_Handle->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)pData; + + /* Get CLLR offset */ + cllr_offset = (hdcmi->DMA_Handle->LinkedListQueue->Head->NodeInfo & NODE_CLLR_IDX) >> 8U; + + /* Update second node */ + if (hdcmi->DMA_Handle->LinkedListQueue->Head->LinkRegisters[cllr_offset] != 0U) + { + tmp1 = (uint32_t)hdcmi->DMA_Handle->LinkedListQueue->Head ; + tmp2 = hdcmi->DMA_Handle->LinkedListQueue->Head->LinkRegisters[cllr_offset]; + /* Update second node */ + + /* Set DMA Data size */ + ((DMA_NodeTypeDef *)((tmp1 & DMA_CLBAR_LBA) + \ + (tmp2 & DMA_CLLR_LA)))->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hdcmi->XferSize; + + /* Set DMA Source address */ + ((DMA_NodeTypeDef *)((tmp1 & DMA_CLBAR_LBA) + \ + (tmp2 & DMA_CLLR_LA)))->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = \ + (uint32_t)&hdcmi->Instance->DR; + + /* Set DMA Destination address */ + ((DMA_NodeTypeDef *)((tmp1 & DMA_CLBAR_LBA) + \ + (tmp2 & DMA_CLLR_LA)))->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = \ + (uint32_t)pData + hdcmi->XferSize; + + if (HAL_DMAEx_List_Start_IT(hdcmi->DMA_Handle) != HAL_OK) + { + /* Set Error Code */ + hdcmi->ErrorCode = HAL_DCMI_ERROR_DMA; + /* Change DCMI state */ + hdcmi->State = HAL_DCMI_STATE_READY; + /* Release Lock */ + __HAL_UNLOCK(hdcmi); + /* Return function status */ + status = HAL_ERROR; + } + } + else + { + /* Set Error Code */ + hdcmi->ErrorCode = HAL_DCMI_ERROR_DMA; + /* Change DCMI state */ + hdcmi->State = HAL_DCMI_STATE_READY; + /* Release Lock */ + __HAL_UNLOCK(hdcmi); + /* Return function status */ + status = HAL_ERROR; + } + } + else + { + /* Set Error Code */ + hdcmi->ErrorCode = HAL_DCMI_ERROR_DMA; + /* Change DCMI state */ + hdcmi->State = HAL_DCMI_STATE_READY; + /* Release Lock */ + __HAL_UNLOCK(hdcmi); + /* Return function status */ + status = HAL_ERROR; + } + } + else + { + /* Set Error Code */ + hdcmi->ErrorCode = HAL_DCMI_ERROR_DMA; + /* Change DCMI state */ + hdcmi->State = HAL_DCMI_STATE_READY; + /* Release Lock */ + __HAL_UNLOCK(hdcmi); + /* Return function status */ + status = HAL_ERROR; + } + } + if (status == HAL_OK) + { + /* Enable Capture */ + hdcmi->Instance->CR |= DCMI_CR_CAPTURE; + + /* Release Lock */ + __HAL_UNLOCK(hdcmi); + } + else + { + /* Set Error Code */ + hdcmi->ErrorCode = HAL_DCMI_ERROR_DMA; + /* Change DCMI state */ + hdcmi->State = HAL_DCMI_STATE_READY; + /* Release Lock */ + __HAL_UNLOCK(hdcmi); + /* Return function status */ + status = HAL_ERROR; + } + + /* Return function status */ + return status; +} + +/** + * @brief Disable DCMI DMA request and Disable DCMI capture + * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCMI_Stop(DCMI_HandleTypeDef *hdcmi) +{ + uint32_t count = HAL_TIMEOUT_DCMI_STOP * (SystemCoreClock / 8U / 1000U); + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hdcmi); + + /* Lock the DCMI peripheral state */ + hdcmi->State = HAL_DCMI_STATE_BUSY; + + /* Disable Capture */ + hdcmi->Instance->CR &= ~(DCMI_CR_CAPTURE); + + /* Check if the DCMI capture effectively disabled */ + do + { + count-- ; + if (count == 0U) + { + /* Update error code */ + hdcmi->ErrorCode |= HAL_DCMI_ERROR_TIMEOUT; + + status = HAL_TIMEOUT; + break; + } + } while ((hdcmi->Instance->CR & DCMI_CR_CAPTURE) != 0U); + + /* Disable the DCMI */ + __HAL_DCMI_DISABLE(hdcmi); + + /* Disable the DMA */ + (void)HAL_DMA_Abort(hdcmi->DMA_Handle); + + /* Update error code */ + hdcmi->ErrorCode |= HAL_DCMI_ERROR_NONE; + + /* Change DCMI state */ + hdcmi->State = HAL_DCMI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hdcmi); + + /* Return function status */ + return status; +} + +/** + * @brief Suspend DCMI capture + * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCMI_Suspend(DCMI_HandleTypeDef *hdcmi) +{ + uint32_t count = HAL_TIMEOUT_DCMI_STOP * (SystemCoreClock / 8U / 1000U); + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hdcmi); + + if (hdcmi->State == HAL_DCMI_STATE_BUSY) + { + /* Change DCMI state */ + hdcmi->State = HAL_DCMI_STATE_SUSPENDED; + + /* Disable Capture */ + hdcmi->Instance->CR &= ~(DCMI_CR_CAPTURE); + + /* Check if the DCMI capture effectively disabled */ + do + { + count-- ; + if (count == 0U) + { + /* Update error code */ + hdcmi->ErrorCode |= HAL_DCMI_ERROR_TIMEOUT; + + /* Change DCMI state */ + hdcmi->State = HAL_DCMI_STATE_READY; + + status = HAL_TIMEOUT; + break; + } + } while ((hdcmi->Instance->CR & DCMI_CR_CAPTURE) != 0U); + } + /* Process Unlocked */ + __HAL_UNLOCK(hdcmi); + + /* Return function status */ + return status; +} + +/** + * @brief Resume DCMI capture + * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCMI_Resume(DCMI_HandleTypeDef *hdcmi) +{ + /* Process locked */ + __HAL_LOCK(hdcmi); + + if (hdcmi->State == HAL_DCMI_STATE_SUSPENDED) + { + /* Change DCMI state */ + hdcmi->State = HAL_DCMI_STATE_BUSY; + + /* Enable Capture */ + hdcmi->Instance->CR |= DCMI_CR_CAPTURE; + } + /* Process Unlocked */ + __HAL_UNLOCK(hdcmi); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Handles DCMI interrupt request. + * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for the DCMI. + * @retval None + */ +void HAL_DCMI_IRQHandler(DCMI_HandleTypeDef *hdcmi) +{ + uint32_t isr_value = READ_REG(hdcmi->Instance->MISR); + + /* Synchronization error interrupt management *******************************/ + if ((isr_value & DCMI_FLAG_ERRRI) == DCMI_FLAG_ERRRI) + { + /* Clear the Synchronization error flag */ + __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_ERRRI); + + /* Update error code */ + hdcmi->ErrorCode |= HAL_DCMI_ERROR_SYNC; + + /* Change DCMI state */ + hdcmi->State = HAL_DCMI_STATE_ERROR; + + /* Set the synchronization error callback */ + hdcmi->DMA_Handle->XferAbortCallback = DCMI_DMAError; + + /* Abort the DMA Transfer */ + if (HAL_DMA_Abort_IT(hdcmi->DMA_Handle) != HAL_OK) + { + DCMI_DMAError(hdcmi->DMA_Handle); + } + } + /* Overflow interrupt management ********************************************/ + if ((isr_value & DCMI_FLAG_OVRRI) == DCMI_FLAG_OVRRI) + { + /* Clear the Overflow flag */ + __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_OVRRI); + + /* Update error code */ + hdcmi->ErrorCode |= HAL_DCMI_ERROR_OVR; + + /* Change DCMI state */ + hdcmi->State = HAL_DCMI_STATE_ERROR; + + /* Set the overflow callback */ + hdcmi->DMA_Handle->XferAbortCallback = DCMI_DMAError; + + /* Abort the DMA Transfer */ + if (HAL_DMA_Abort_IT(hdcmi->DMA_Handle) != HAL_OK) + { + DCMI_DMAError(hdcmi->DMA_Handle); + } + } + /* Line Interrupt management ************************************************/ + if ((isr_value & DCMI_FLAG_LINERI) == DCMI_FLAG_LINERI) + { + /* Clear the Line interrupt flag */ + __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_LINERI); + + /* Line interrupt Callback */ +#if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1) + /*Call registered DCMI line event callback*/ + hdcmi->LineEventCallback(hdcmi); +#else + HAL_DCMI_LineEventCallback(hdcmi); +#endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */ + } + /* VSYNC interrupt management ***********************************************/ + if ((isr_value & DCMI_FLAG_VSYNCRI) == DCMI_FLAG_VSYNCRI) + { + /* Clear the VSYNC flag */ + __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_VSYNCRI); + + /* VSYNC Callback */ +#if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1) + /*Call registered DCMI vsync event callback*/ + hdcmi->VsyncEventCallback(hdcmi); +#else + HAL_DCMI_VsyncEventCallback(hdcmi); +#endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */ + } + /* FRAME interrupt management ***********************************************/ + if ((isr_value & DCMI_FLAG_FRAMERI) == DCMI_FLAG_FRAMERI) + { + /* When snapshot mode, disable Vsync, Error and Overrun interrupts */ + if ((hdcmi->Instance->CR & DCMI_CR_CM) == DCMI_MODE_SNAPSHOT) + { + /* Disable the Line, Vsync, Error and Overrun interrupts */ + __HAL_DCMI_DISABLE_IT(hdcmi, DCMI_IT_LINE | DCMI_IT_VSYNC | DCMI_IT_ERR | DCMI_IT_OVR); + } + + /* Disable the Frame interrupt */ + __HAL_DCMI_DISABLE_IT(hdcmi, DCMI_IT_FRAME); + + /* Clear the End of Frame flag */ + __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_FRAMERI); + + /* Frame Callback */ +#if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1) + /*Call registered DCMI frame event callback*/ + hdcmi->FrameEventCallback(hdcmi); +#else + HAL_DCMI_FrameEventCallback(hdcmi); +#endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */ + } +} + +/** + * @brief Error DCMI callback. + * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @retval None + */ +__weak void HAL_DCMI_ErrorCallback(DCMI_HandleTypeDef *hdcmi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdcmi); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_DCMI_ErrorCallback could be implemented in the user file + */ +} + +/** + * @brief Line Event callback. + * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @retval None + */ +__weak void HAL_DCMI_LineEventCallback(DCMI_HandleTypeDef *hdcmi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdcmi); + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_DCMI_LineEventCallback could be implemented in the user file + */ +} + +/** + * @brief VSYNC Event callback. + * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @retval None + */ +__weak void HAL_DCMI_VsyncEventCallback(DCMI_HandleTypeDef *hdcmi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdcmi); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_DCMI_VsyncEventCallback could be implemented in the user file + */ +} + +/** + * @brief Frame Event callback. + * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @retval None + */ +__weak void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdcmi); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_DCMI_FrameEventCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup DCMI_Exported_Functions_Group3 Peripheral Control functions + * @brief Peripheral Control functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== +[..] This section provides functions allowing to: + (+) Configure the CROP feature. + (+) Enable/Disable the CROP feature. + (+) Set embedded synchronization delimiters unmasks. + +@endverbatim + * @{ + */ + +/** + * @brief Configure the DCMI CROP coordinate. + * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @param YSize DCMI Line number + * @param XSize DCMI Pixel per line + * @param X0 DCMI window X offset + * @param Y0 DCMI window Y offset + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCMI_ConfigCrop(DCMI_HandleTypeDef *hdcmi, uint32_t X0, uint32_t Y0, uint32_t XSize, + uint32_t YSize) +{ + /* Process Locked */ + __HAL_LOCK(hdcmi); + + /* Lock the DCMI peripheral state */ + hdcmi->State = HAL_DCMI_STATE_BUSY; + + /* Check the parameters */ + assert_param(IS_DCMI_WINDOW_COORDINATE(X0)); + assert_param(IS_DCMI_WINDOW_HEIGHT(Y0)); + assert_param(IS_DCMI_WINDOW_COORDINATE(XSize)); + assert_param(IS_DCMI_WINDOW_COORDINATE(YSize)); + + /* Configure CROP */ + hdcmi->Instance->CWSIZER = (XSize | (YSize << DCMI_CWSIZE_VLINE_Pos)); + hdcmi->Instance->CWSTRTR = (X0 | (Y0 << DCMI_CWSTRT_VST_Pos)); + + /* Initialize the DCMI state*/ + hdcmi->State = HAL_DCMI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hdcmi); + + return HAL_OK; +} + +/** + * @brief Disable the Crop feature. + * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCMI_DisableCrop(DCMI_HandleTypeDef *hdcmi) +{ + /* Process Locked */ + __HAL_LOCK(hdcmi); + + /* Lock the DCMI peripheral state */ + hdcmi->State = HAL_DCMI_STATE_BUSY; + + /* Disable DCMI Crop feature */ + hdcmi->Instance->CR &= ~(uint32_t)DCMI_CR_CROP; + + /* Change the DCMI state*/ + hdcmi->State = HAL_DCMI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hdcmi); + + return HAL_OK; +} + +/** + * @brief Enable the Crop feature. + * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCMI_EnableCrop(DCMI_HandleTypeDef *hdcmi) +{ + /* Process Locked */ + __HAL_LOCK(hdcmi); + + /* Lock the DCMI peripheral state */ + hdcmi->State = HAL_DCMI_STATE_BUSY; + + /* Enable DCMI Crop feature */ + hdcmi->Instance->CR |= (uint32_t)DCMI_CR_CROP; + + /* Change the DCMI state*/ + hdcmi->State = HAL_DCMI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hdcmi); + + return HAL_OK; +} + +/** + * @brief Set embedded synchronization delimiters unmasks. + * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @param SyncUnmask pointer to a DCMI_SyncUnmaskTypeDef structure that contains + * the embedded synchronization delimiters unmasks. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCMI_ConfigSyncUnmask(DCMI_HandleTypeDef *hdcmi, DCMI_SyncUnmaskTypeDef *SyncUnmask) +{ + /* Process Locked */ + __HAL_LOCK(hdcmi); + + /* Lock the DCMI peripheral state */ + hdcmi->State = HAL_DCMI_STATE_BUSY; + + /* Write DCMI embedded synchronization unmask register */ + hdcmi->Instance->ESUR = (((uint32_t)SyncUnmask->FrameStartUnmask) | \ + ((uint32_t)SyncUnmask->LineStartUnmask << DCMI_ESUR_LSU_Pos) | \ + ((uint32_t)SyncUnmask->LineEndUnmask << DCMI_ESUR_LEU_Pos) | \ + ((uint32_t)SyncUnmask->FrameEndUnmask << DCMI_ESUR_FEU_Pos)); + + /* Change the DCMI state*/ + hdcmi->State = HAL_DCMI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hdcmi); + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup DCMI_Exported_Functions_Group4 Peripheral State functions + * @brief Peripheral State functions + * +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection provides functions allowing to + (+) Check the DCMI state. + (+) Get the specific DCMI error flag. + +@endverbatim + * @{ + */ + +/** + * @brief Return the DCMI state + * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @retval HAL state + */ +HAL_DCMI_StateTypeDef HAL_DCMI_GetState(const DCMI_HandleTypeDef *hdcmi) +{ + return hdcmi->State; +} + +/** + * @brief Return the DCMI error code + * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @retval DCMI Error Code + */ +uint32_t HAL_DCMI_GetError(const DCMI_HandleTypeDef *hdcmi) +{ + return hdcmi->ErrorCode; +} + +#if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User DCMI Callback + * To be used instead of the weak predefined callback + * @param hdcmi DCMI handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_DCMI_LINE_EVENT_CB_ID Line Event callback ID + * @arg @ref HAL_DCMI_FRAME_EVENT_CB_ID Frame Event callback ID + * @arg @ref HAL_DCMI_VSYNC_EVENT_CB_ID Vsync Event callback ID + * @arg @ref HAL_DCMI_ERROR_CB_ID Error callback ID + * @arg @ref HAL_DCMI_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_DCMI_MSPDEINIT_CB_ID MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCMI_RegisterCallback(DCMI_HandleTypeDef *hdcmi, HAL_DCMI_CallbackIDTypeDef CallbackID, + pDCMI_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* update the error code */ + hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + } + else + { + if (hdcmi->State == HAL_DCMI_STATE_READY) + { + switch (CallbackID) + { + case HAL_DCMI_FRAME_EVENT_CB_ID : + hdcmi->FrameEventCallback = pCallback; + break; + + case HAL_DCMI_VSYNC_EVENT_CB_ID : + hdcmi->VsyncEventCallback = pCallback; + break; + + case HAL_DCMI_LINE_EVENT_CB_ID : + hdcmi->LineEventCallback = pCallback; + break; + + case HAL_DCMI_ERROR_CB_ID : + hdcmi->ErrorCallback = pCallback; + break; + + case HAL_DCMI_MSPINIT_CB_ID : + hdcmi->MspInitCallback = pCallback; + break; + + case HAL_DCMI_MSPDEINIT_CB_ID : + hdcmi->MspDeInitCallback = pCallback; + break; + + default : + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (hdcmi->State == HAL_DCMI_STATE_RESET) + { + switch (CallbackID) + { + case HAL_DCMI_MSPINIT_CB_ID : + hdcmi->MspInitCallback = pCallback; + break; + + case HAL_DCMI_MSPDEINIT_CB_ID : + hdcmi->MspDeInitCallback = pCallback; + break; + + default : + /* update the error code */ + hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* update the error code */ + hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + } + } + + return status; +} + +/** + * @brief Unregister a DCMI Callback + * DCMI callback is redirected to the weak predefined callback + * @param hdcmi DCMI handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_DCMI_LINE_EVENT_CB_ID Line Event callback ID + * @arg @ref HAL_DCMI_FRAME_EVENT_CB_ID Frame Event callback ID + * @arg @ref HAL_DCMI_VSYNC_EVENT_CB_ID Vsync Event callback ID + * @arg @ref HAL_DCMI_ERROR_CB_ID Error callback ID + * @arg @ref HAL_DCMI_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_DCMI_MSPDEINIT_CB_ID MspDeInit callback ID + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCMI_UnRegisterCallback(DCMI_HandleTypeDef *hdcmi, HAL_DCMI_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (hdcmi->State == HAL_DCMI_STATE_READY) + { + switch (CallbackID) + { + case HAL_DCMI_FRAME_EVENT_CB_ID : + hdcmi->FrameEventCallback = HAL_DCMI_FrameEventCallback; /* Legacy weak FrameEventCallback */ + break; + + case HAL_DCMI_VSYNC_EVENT_CB_ID : + hdcmi->VsyncEventCallback = HAL_DCMI_VsyncEventCallback; /* Legacy weak VsyncEventCallback */ + break; + + case HAL_DCMI_LINE_EVENT_CB_ID : + hdcmi->LineEventCallback = HAL_DCMI_LineEventCallback; /* Legacy weak LineEventCallback */ + break; + + case HAL_DCMI_ERROR_CB_ID : + hdcmi->ErrorCallback = HAL_DCMI_ErrorCallback; /* Legacy weak ErrorCallback */ + break; + + case HAL_DCMI_MSPINIT_CB_ID : + hdcmi->MspInitCallback = HAL_DCMI_MspInit; + break; + + case HAL_DCMI_MSPDEINIT_CB_ID : + hdcmi->MspDeInitCallback = HAL_DCMI_MspDeInit; + break; + + default : + /* update the error code */ + hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else if (hdcmi->State == HAL_DCMI_STATE_RESET) + { + switch (CallbackID) + { + case HAL_DCMI_MSPINIT_CB_ID : + hdcmi->MspInitCallback = HAL_DCMI_MspInit; + break; + + case HAL_DCMI_MSPDEINIT_CB_ID : + hdcmi->MspDeInitCallback = HAL_DCMI_MspDeInit; + break; + + default : + /* update the error code */ + hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* update the error code */ + hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + } + + return status; +} +#endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup DCMI_Private_Functions DCMI Private Functions + * @{ + */ +/** + * @brief DMA conversion complete callback. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void DCMI_DMAXferCplt(DMA_HandleTypeDef *hdma) +{ + + DCMI_HandleTypeDef *hdcmi = (DCMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + uint32_t tmp1; + uint32_t tmp2; + DMA_NodeTypeDef *pnode; + uint32_t pbuff; + uint32_t transfernumber; + uint32_t transfercount; + uint32_t transfersize ; + + /* Update Nodes destinations */ + if (hdcmi->XferSize != 0U) + { + pbuff = hdcmi->pBuffPtr; + transfernumber = hdcmi->XferTransferNumber; + transfercount = hdcmi->XferCount; + transfersize = hdcmi->XferSize; + + tmp1 = hdcmi->DMA_Handle->Instance->CLLR & DMA_CLLR_LA; + tmp2 = hdcmi->DMA_Handle->Instance->CLBAR & DMA_CLBAR_LBA; + pnode = (DMA_NodeTypeDef *)(uint32_t)(tmp1 | tmp2); + + if (hdcmi->XferCount > 1U) + { + pnode->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = pbuff + ((transfernumber - transfercount + 2U) * transfersize); + hdcmi->XferCount--; + } + + else if (hdcmi->XferCount == 1U) + { + pnode->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = hdcmi->pBuffPtr; + hdcmi->XferCount--; + } + else + { + pnode->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = hdcmi->pBuffPtr + hdcmi->XferSize; + + /* When Continuous mode, re-set dcmi XferCount */ + if ((hdcmi->Instance->CR & DCMI_CR_CM) == DCMI_MODE_CONTINUOUS) + { + hdcmi->XferCount = hdcmi->XferTransferNumber ; + } + /* When snapshot mode, set dcmi state to ready */ + else + { + hdcmi->State = HAL_DCMI_STATE_READY; + } + + __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_FRAME); + } + } + else /* Snapshot Mode */ + { + /* Enable the Frame interrupt */ + __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_FRAME); + + /* When snapshot mode, set dcmi state to ready */ + if ((hdcmi->Instance->CR & DCMI_CR_CM) == DCMI_MODE_SNAPSHOT) + { + hdcmi->State = HAL_DCMI_STATE_READY; + } + } +} + +/** + * @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 DCMI_DMAError(DMA_HandleTypeDef *hdma) +{ + DCMI_HandleTypeDef *hdcmi = (DCMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + if (hdcmi->DMA_Handle->ErrorCode != HAL_DMA_ERROR_ULE) + { + /* Initialize the DCMI state*/ + hdcmi->State = HAL_DCMI_STATE_READY; + + /* Set DCMI Error Code */ + hdcmi->ErrorCode |= HAL_DCMI_ERROR_DMA; + } + + /* DCMI error Callback */ +#if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1) + /*Call registered DCMI error callback*/ + hdcmi->ErrorCallback(hdcmi); +#else + HAL_DCMI_ErrorCallback(hdcmi); +#endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */ + +} + +/** + * @} + */ +#endif /* DCMI */ +#endif /* HAL_DCMI_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dma.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dma.c new file mode 100644 index 0000000000..98f3c89a5a --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dma.c @@ -0,0 +1,1710 @@ +/** + ********************************************************************************************************************** + * @file stm32h5xx_hal_dma.c + * @author MCD Application Team + * @brief This file provides firmware functions to manage the following functionalities of the Direct Memory Access + * (DMA) peripheral: + * + Initialization/De-Initialization Functions + * + I/O Operation Functions + * + State and Errors Functions + * + DMA Attributes Functions + * + ********************************************************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ********************************************************************************************************************** + @verbatim + ====================================================================================================================== + ############### How to use this driver ############### + ====================================================================================================================== + + + [..] + DMA transfer modes are divided to 2 major categories : + (+) Normal transfers (legacy) + (+) Linked-list transfers + + [..] + Normal transfers mode is initialized via the standard module and linked-list mode is configured via the extended + module. + + [..] + Additionally to linked-list capability, all advanced DMA features are managed and configured via the extended + module as extensions to normal mode. + Advanced features are : + (+) Repeated block feature. + (+) Trigger feature. + (+) Data handling feature. + + [..] + DMA Legacy circular transfer, is replaced by circular linked-list configuration. + + + *** Initialization and De-Initialization *** + ============================================ + [..] + For a given channel, enable and configure the peripheral to be connected to the DMA Channel (except for internal + SRAM/FLASH memories: no initialization is necessary) please refer to Reference manual for connection between + peripherals and DMA requests. + + [..] + For a given channel, use HAL_DMA_Init function to program the required configuration for normal transfer through + the following parameters: + + (+) Request : Specifies the DMA channel request + Request parameters : + (++) can be a value of DMA_Request_Selection + + (+) BlkHWRequest : Specifies the Block hardware request mode for DMA channel + (++) can be a value of DMA_Block_Request + + (+) Direction : Specifies the transfer direction for DMA channel + (++) can be a value of DMA_Transfer_Direction + + (+) SrcInc : Specifies the source increment mode for the DMA channel + (++) can be a value of DMA_Source_Increment_Mode + + (+) DestInc : Specifies the destination increment mode for the DMA channel + (++) can be a value of DMA_Destination_Increment_Mode + + (+) SrcDataWidth : Specifies the source data width for the DMA channel + (++) can be a value of DMA_Source_Data_Width + + (+) DestDataWidth : Specifies the destination data width for the DMA channel + (++) can be a value of DMA_Destination_Data_Width + + (+) Priority : Specifies the priority for the DMA channel + (++) can be a value of DMA_Priority_Level + + (+) SrcBurstLength : Specifies the source burst length (number of beats) for the DMA channel + (++) can be a value of between 1 and 64 + + (+) DestBurstLength : Specifies the destination burst length (number of beats) for the DMA channel + (++) can be a value of between 1 and 64 + + (+) TransferAllocatedPort : Specifies the source and destination allocated ports + (++) can be a value of DMA_Transfer_Allocated_Port + + (+) TransferEventMode : Specifies the transfer event mode for the DMA channel + (++) can be a value of DMA_Transfer_Event_Mode + + (+) Mode : Specifies the transfer mode for the DMA channel + (++) can be a value of DMA_Transfer_Mode + + + *** Polling mode IO operation *** + ================================= + [..] + (+) Use HAL_DMA_Start() to start a DMA normal transfer after the configuration of source address, destination + address and the size of data to be transferred. + + (+) Use HAL_DMA_PollForTransfer() to poll for selected transfer level. In this case a fixed Timeout can be + configured by User depending on his application. + Transfer level can be : + (++) HAL_DMA_HALF_TRANSFER + (++) HAL_DMA_FULL_TRANSFER + For circular transfer, this API returns an HAL_ERROR with HAL_DMA_ERROR_NOT_SUPPORTED error code. + + (+) Use HAL_DMA_Abort() function to abort any ongoing DMA transfer in blocking mode. + This API returns HAL_ERROR when there is no ongoing transfer or timeout is reached when disabling the DMA + channel. (This API should not be called from an interrupt service routine) + + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority() + + (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ() + + (+) Use HAL_DMA_RegisterCallback() function to register user callbacks from the following list : + (++) XferCpltCallback : transfer complete callback. + (++) XferHalfCpltCallback : half transfer complete callback. + (++) XferErrorCallback : transfer error callback. + (++) XferAbortCallback : transfer abort complete callback. + (++) XferSuspendCallback : transfer suspend complete callback. + + (+) Use HAL_DMA_Start_IT() to start the DMA transfer after the enable of DMA interrupts and the configuration + of source address,destination address and the size of data to be transferred. + + (+) Use HAL_DMA_IRQHandler() called under DMA_IRQHandler() interrupt subroutine to handle any DMA interrupt. + + (+) Use HAL_DMA_Abort_IT() function to abort any on-going DMA transfer in non-blocking mode. + This API will suspend immediately the DMA channel execution. When the transfer is effectively suspended, + an interrupt is generated and HAL_DMA_IRQHandler() will reset the channel and execute the callback + XferAbortCallback. (This API could be called from an interrupt service routine) + + + *** State and errors *** + ======================== + [..] + (+) Use HAL_DMA_GetState() function to get the DMA state. + (+) Use HAL_DMA_GetError() function to get the DMA error code. + + + *** Security and privilege attributes *** + ========================================= + [..] + (+) Use HAL_DMA_ConfigChannelAttributes() function to configure DMA channel security and privilege attributes. + (++) Security : at channel level, at source level and at destination level. + (++) Privilege : at channel level. + (+) Use HAL_DMA_GetConfigChannelAttributes() function to get the DMA channel attributes. + (+) Use HAL_DMA_LockChannelAttributes() function to lock the DMA channel security and privilege attributes + configuration. This API can be called once after each system boot. + If called again, HAL_DMA_ConfigChannelAttributes() API has no effect. + Unlock is done either by a system boot or a by an RCC reset. + (+) Use HAL_DMA_GetLockChannelAttributes() function to get the attributes lock status. + + + *** DMA HAL driver macros list *** + ================================== + [..] + Below the list of most used macros in DMA HAL driver. + + (+) __HAL_DMA_ENABLE : Enable the specified DMA Channel. + (+) __HAL_DMA_DISABLE : Disable the specified DMA Channel. + (+) __HAL_DMA_GET_FLAG : Get the DMA Channel pending flags. + (+) __HAL_DMA_CLEAR_FLAG : Clear the DMA Channel pending flags. + (+) __HAL_DMA_ENABLE_IT : Enable the specified DMA Channel interrupts. + (+) __HAL_DMA_DISABLE_IT : Disable the specified DMA Channel interrupts. + (+) __HAL_DMA_GET_IT_SOURCE : Check whether the specified DMA Channel interrupt has occurred or not. + + [..] + (@) You can refer to the header file of the DMA HAL driver for more useful macros. + + @endverbatim + ********************************************************************************************************************** + */ + +/* Includes ----------------------------------------------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup DMA DMA + * @brief DMA HAL module driver + * @{ + */ + +#ifdef HAL_DMA_MODULE_ENABLED + +/* Private typedef ---------------------------------------------------------------------------------------------------*/ +/* Private constants -------------------------------------------------------------------------------------------------*/ +/* Private macro -----------------------------------------------------------------------------------------------------*/ +/* Private variables -------------------------------------------------------------------------------------------------*/ +/* Private function prototypes ---------------------------------------------------------------------------------------*/ +static void DMA_SetConfig(DMA_HandleTypeDef const *const hdma, + uint32_t SrcAddress, + uint32_t DstAddress, + uint32_t SrcDataSize); +static void DMA_Init(DMA_HandleTypeDef const *const hdma); + +/* Exported functions ------------------------------------------------------------------------------------------------*/ + +/** @addtogroup DMA_Exported_Functions DMA Exported Functions + * @{ + */ + +/** @addtogroup DMA_Exported_Functions_Group1 + * +@verbatim + ====================================================================================================================== + ############### Initialization and de-initialization functions ############### + ====================================================================================================================== + [..] + This section provides functions allowing to initialize and de-initialize the DMA channel in normal mode. + + [..] + (+) The HAL_DMA_Init() function follows the DMA channel configuration procedures as described in reference manual. + (+) The HAL_DMA_DeInit() function allows to de-initialize the DMA channel. + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the DMA channel in normal mode according to the specified parameters in the DMA_InitTypeDef and + * create the associated handle. + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the + * specified DMA Channel. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *const hdma) +{ + /* Get tick number */ + uint32_t tickstart = HAL_GetTick(); + + /* Check the DMA peripheral handle parameter */ + if (hdma == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance)); + assert_param(IS_DMA_DIRECTION(hdma->Init.Direction)); + if ((hdma->Init.Direction == DMA_MEMORY_TO_PERIPH) || (hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)) + { + assert_param(IS_DMA_REQUEST(hdma->Init.Request)); + } + assert_param(IS_DMA_BLOCK_HW_REQUEST(hdma->Init.BlkHWRequest)); + assert_param(IS_DMA_SOURCE_INC(hdma->Init.SrcInc)); + assert_param(IS_DMA_DESTINATION_INC(hdma->Init.DestInc)); + assert_param(IS_DMA_SOURCE_DATA_WIDTH(hdma->Init.SrcDataWidth)); + assert_param(IS_DMA_DESTINATION_DATA_WIDTH(hdma->Init.DestDataWidth)); + assert_param(IS_DMA_PRIORITY(hdma->Init.Priority)); + assert_param(IS_DMA_TCEM_EVENT_MODE(hdma->Init.TransferEventMode)); + assert_param(IS_DMA_MODE(hdma->Init.Mode)); + /* Check DMA channel instance */ + if (IS_GPDMA_INSTANCE(hdma->Instance) != 0U) + { + assert_param(IS_DMA_BURST_LENGTH(hdma->Init.SrcBurstLength)); + assert_param(IS_DMA_BURST_LENGTH(hdma->Init.DestBurstLength)); + assert_param(IS_DMA_TRANSFER_ALLOCATED_PORT(hdma->Init.TransferAllocatedPort)); + } + + /* Allocate lock resource */ + __HAL_UNLOCK(hdma); + + /* Update the DMA channel state */ + hdma->State = HAL_DMA_STATE_BUSY; + + /* Disable the DMA channel */ + __HAL_DMA_DISABLE(hdma); + + /* Check if the DMA channel is effectively disabled */ + while ((hdma->Instance->CCR & DMA_CCR_EN) != 0U) + { + /* Check for the Timeout */ + if ((HAL_GetTick() - tickstart) > HAL_TIMEOUT_DMA_ABORT) + { + /* Update the DMA channel error code */ + hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT; + + /* Update the DMA channel state */ + hdma->State = HAL_DMA_STATE_ERROR; + + return HAL_ERROR; + } + } + + /* Initialize the DMA channel registers */ + DMA_Init(hdma); + + /* Update DMA channel operation mode */ + hdma->Mode = hdma->Init.Mode; + + /* Update the DMA channel error code */ + hdma->ErrorCode = HAL_DMA_ERROR_NONE; + + /* Update the DMA channel state */ + hdma->State = HAL_DMA_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitialize the DMA channel when it is configured in normal mode. + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the + * specified DMA Channel. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *const hdma) +{ + + DMA_TypeDef *p_dma_instance; + + uint32_t tickstart = HAL_GetTick(); + + /* Check the DMA peripheral handle parameter */ + if (hdma == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance)); + + /* Get DMA instance */ + p_dma_instance = GET_DMA_INSTANCE(hdma); + + /* Disable the selected DMA Channel */ + __HAL_DMA_DISABLE(hdma); + + /* Check if the DMA channel is effectively disabled */ + while ((hdma->Instance->CCR & DMA_CCR_EN) != 0U) + { + /* Check for the Timeout */ + if ((HAL_GetTick() - tickstart) > HAL_TIMEOUT_DMA_ABORT) + { + /* Update the DMA channel error code */ + hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT; + + /* Update the DMA channel state */ + hdma->State = HAL_DMA_STATE_ERROR; + + return HAL_ERROR; + } + } + + /* Reset DMA Channel registers */ + hdma->Instance->CLBAR = 0U; + hdma->Instance->CCR = 0U; + hdma->Instance->CTR1 = 0U; + hdma->Instance->CTR2 = 0U; + hdma->Instance->CBR1 = 0U; + hdma->Instance->CSAR = 0U; + hdma->Instance->CDAR = 0U; + hdma->Instance->CLLR = 0U; + + /* Reset 2D Addressing registers */ + if (IS_DMA_2D_ADDRESSING_INSTANCE(hdma->Instance) != 0U) + { + hdma->Instance->CTR3 = 0U; + hdma->Instance->CBR2 = 0U; + } + + /* Clear privilege attribute */ + CLEAR_BIT(p_dma_instance->PRIVCFGR, (1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU))); + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + /* Clear secure attribute */ + CLEAR_BIT(p_dma_instance->SECCFGR, (1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU))); +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + /* Clear all flags */ + __HAL_DMA_CLEAR_FLAG(hdma, (DMA_FLAG_TC | DMA_FLAG_HT | DMA_FLAG_DTE | DMA_FLAG_ULE | DMA_FLAG_USE | DMA_FLAG_SUSP | + DMA_FLAG_TO)); + + /* Clean all callbacks */ + hdma->XferCpltCallback = NULL; + hdma->XferHalfCpltCallback = NULL; + hdma->XferErrorCallback = NULL; + hdma->XferAbortCallback = NULL; + hdma->XferSuspendCallback = NULL; + + /* Clean DMA queue */ + hdma->LinkedListQueue = NULL; + + /* Clean DMA parent */ + if (hdma->Parent != NULL) + { + hdma->Parent = NULL; + } + + /* Update DMA channel operation mode */ + hdma->Mode = DMA_NORMAL; + + /* Update the DMA channel error code */ + hdma->ErrorCode = HAL_DMA_ERROR_NONE; + + /* Update the DMA channel state */ + hdma->State = HAL_DMA_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hdma); + + return HAL_OK; +} +/** + * @} + */ + +/** @addtogroup DMA_Exported_Functions_Group2 + * +@verbatim + ====================================================================================================================== + ############### IO operation functions ############### + ====================================================================================================================== + [..] + This section provides functions allowing to : + (+) Configure the source, destination address and data size and Start DMA transfer in normal mode + (+) Abort DMA transfer + (+) Poll for transfer complete + (+) Handle DMA interrupt request + (+) Register and Unregister DMA callbacks + + [..] + (+) The HAL_DMA_Start() function allows to start the DMA channel transfer in normal mode (Blocking mode). + (+) The HAL_DMA_Start_IT() function allows to start the DMA channel transfer in normal mode (Non-blocking mode). + (+) The HAL_DMA_Abort() function allows to abort any on-going transfer (Blocking mode). + (+) The HAL_DMA_Abort_IT() function allows to abort any on-going transfer (Non-blocking mode). + (+) The HAL_DMA_PollForTransfer() function allows to poll on half transfer and transfer complete (Blocking mode). + This API cannot be used for circular transfers. + (+) The HAL_DMA_IRQHandler() function allows to handle any DMA channel interrupt (Non-blocking mode). + (+) The HAL_DMA_RegisterCallback() and HAL_DMA_UnRegisterCallback() functions allow respectively to register and + unregister user customized callbacks. + User callbacks are called under HAL_DMA_IRQHandler(). + +@endverbatim + * @{ + */ + +/** + * @brief Start the DMA channel transfer in normal mode (Blocking mode). + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for + * the specified DMA Channel. + * @param SrcAddress : The source data address. + * @param DstAddress : The destination data address. + * @param SrcDataSize : The length of data to be transferred from source to destination in bytes. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *const hdma, + uint32_t SrcAddress, + uint32_t DstAddress, + uint32_t SrcDataSize) +{ + /* Check the DMA peripheral handle parameter */ + if (hdma == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DMA_BLOCK_SIZE(SrcDataSize)); + + /* Process locked */ + __HAL_LOCK(hdma); + + /* Check DMA channel state */ + if (hdma->State == HAL_DMA_STATE_READY) + { + /* Update the DMA channel state */ + hdma->State = HAL_DMA_STATE_BUSY; + + /* Update the DMA channel error code */ + hdma->ErrorCode = HAL_DMA_ERROR_NONE; + + /* Configure the source address, destination address, the data size and clear flags */ + DMA_SetConfig(hdma, SrcAddress, DstAddress, SrcDataSize); + + /* Enable DMA channel */ + __HAL_DMA_ENABLE(hdma); + } + else + { + /* Update the DMA channel error code */ + hdma->ErrorCode = HAL_DMA_ERROR_BUSY; + + /* Process unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Starts the DMA channel transfer in normal mode with interrupts enabled (Non-blocking mode). + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the + * specified DMA Channel. + * @param SrcAddress : The source data address. + * @param DstAddress : The destination data address. + * @param SrcDataSize : The length of data to be transferred from source to destination in bytes. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *const hdma, + uint32_t SrcAddress, + uint32_t DstAddress, + uint32_t SrcDataSize) +{ + /* Check the DMA peripheral handle parameter */ + if (hdma == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DMA_BLOCK_SIZE(SrcDataSize)); + + /* Process locked */ + __HAL_LOCK(hdma); + + /* Check DMA channel state */ + if (hdma->State == HAL_DMA_STATE_READY) + { + /* Update the DMA channel state */ + hdma->State = HAL_DMA_STATE_BUSY; + + /* Update the DMA channel error code */ + hdma->ErrorCode = HAL_DMA_ERROR_NONE; + + /* Configure the source address, destination address, the data size and clear flags */ + DMA_SetConfig(hdma, SrcAddress, DstAddress, SrcDataSize); + + /* Enable common interrupts: Transfer Complete and Transfer Errors ITs */ + __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_DTE | DMA_IT_ULE | DMA_IT_USE | DMA_IT_TO)); + + /* Check half transfer complete callback */ + if (hdma->XferHalfCpltCallback != NULL) + { + /* If Half Transfer complete callback is set, enable the corresponding IT */ + __HAL_DMA_ENABLE_IT(hdma, DMA_IT_HT); + } + + /* Check Half suspend callback */ + if (hdma->XferSuspendCallback != NULL) + { + /* If Transfer suspend callback is set, enable the corresponding IT */ + __HAL_DMA_ENABLE_IT(hdma, DMA_IT_SUSP); + } + + /* Enable DMA channel */ + __HAL_DMA_ENABLE(hdma); + } + else + { + /* Update the DMA channel error code */ + hdma->ErrorCode = HAL_DMA_ERROR_BUSY; + + /* Process unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Abort any on-going DMA channel transfer (Blocking mode). + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the + * specified DMA Channel. + * @note After suspending a DMA channel, a wait until the DMA channel is effectively stopped is added. If a channel + * is suspended while a data transfer is on-going, the current data will be transferred and the channel will be + * effectively suspended only after the transfer of any on-going data is finished. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *const hdma) +{ + /* Get tick number */ + uint32_t tickstart = HAL_GetTick(); + + /* Check the DMA peripheral handle parameter */ + if (hdma == NULL) + { + return HAL_ERROR; + } + + /* Check DMA channel state */ + if (hdma->State != HAL_DMA_STATE_BUSY) + { + /* Update the DMA channel error code */ + hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_ERROR; + } + else + { + /* Suspend the channel */ + hdma->Instance->CCR |= DMA_CCR_SUSP; + + /* Update the DMA channel state */ + hdma->State = HAL_DMA_STATE_SUSPEND; + + /* Check if the DMA Channel is suspended */ + while ((hdma->Instance->CSR & DMA_CSR_SUSPF) == 0U) + { + /* Check for the Timeout */ + if ((HAL_GetTick() - tickstart) > HAL_TIMEOUT_DMA_ABORT) + { + /* Update the DMA channel error code */ + hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT; + + /* Update the DMA channel state */ + hdma->State = HAL_DMA_STATE_ERROR; + + /* Check DMA channel transfer mode */ + if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + /* Update the linked-list queue state */ + hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_ERROR; + } + } + + /* Reset the channel */ + hdma->Instance->CCR |= DMA_CCR_RESET; + + /* Update the DMA channel state */ + hdma->State = HAL_DMA_STATE_ABORT; + + /* Clear all status flags */ + __HAL_DMA_CLEAR_FLAG(hdma, (DMA_FLAG_TC | DMA_FLAG_HT | DMA_FLAG_DTE | DMA_FLAG_ULE | DMA_FLAG_USE | DMA_FLAG_SUSP | + DMA_FLAG_TO)); + + /* Update the DMA channel state */ + hdma->State = HAL_DMA_STATE_READY; + + /* Check DMA channel transfer mode */ + if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + /* Update the linked-list queue state */ + hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY; + + /* Clear remaining data size to ensure loading linked-list from memory next start */ + hdma->Instance->CBR1 = 0U; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + } + + return HAL_OK; +} + +/** + * @brief Abort any on-going DMA channel transfer in interrupt mode (Non-blocking mode). + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the + * specified DMA Channel. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *const hdma) +{ + /* Check the DMA peripheral handle parameter */ + if (hdma == NULL) + { + return HAL_ERROR; + } + + /* Check DMA channel state */ + if (hdma->State != HAL_DMA_STATE_BUSY) + { + /* Update the DMA channel error code */ + hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER; + + return HAL_ERROR; + } + else + { + /* Update the DMA channel state */ + hdma->State = HAL_DMA_STATE_ABORT; + + /* Suspend the channel and activate suspend interrupt */ + hdma->Instance->CCR |= (DMA_CCR_SUSP | DMA_CCR_SUSPIE); + } + + return HAL_OK; +} + +/** + * @brief Polling for transfer status (Blocking mode). + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the + * specified DMA Channel. + * @param CompleteLevel : Specifies the DMA level complete. + * @param Timeout : Timeout duration. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *const hdma, + HAL_DMA_LevelCompleteTypeDef CompleteLevel, + uint32_t Timeout) +{ + /* Get tick number */ + uint32_t tickstart = HAL_GetTick(); + uint32_t level_flag; + uint32_t tmp_csr; + + /* Check the DMA peripheral handle parameter */ + if (hdma == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DMA_LEVEL_COMPLETE(CompleteLevel)); + + /* Check DMA channel state */ + if (hdma->State != HAL_DMA_STATE_BUSY) + { + /* Update the DMA channel error code */ + hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_ERROR; + } + + /* Polling mode is not supported in circular mode */ + if ((hdma->Mode & DMA_LINKEDLIST_CIRCULAR) == DMA_LINKEDLIST_CIRCULAR) + { + /* Update the DMA channel error code */ + hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED; + + return HAL_ERROR; + } + + /* Get the level transfer complete flag */ + level_flag = ((CompleteLevel == HAL_DMA_FULL_TRANSFER) ? DMA_FLAG_IDLE : DMA_FLAG_HT); + + /* Get DMA channel status */ + tmp_csr = hdma->Instance->CSR; + + while ((tmp_csr & level_flag) == 0U) + { + /* Check for the timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + /* Update the DMA channel error code */ + hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT; + + /* + If timeout, abort the current transfer. + Note that the Abort function will + - Clear all transfer flags. + - Unlock. + - Set the State. + */ + (void)HAL_DMA_Abort(hdma); + + return HAL_ERROR; + } + } + + /* Get a newer CSR register value */ + tmp_csr = hdma->Instance->CSR; + } + + /* Check trigger overrun flag */ + if ((tmp_csr & DMA_FLAG_TO) != 0U) + { + /* Update the DMA channel error code */ + hdma->ErrorCode |= HAL_DMA_ERROR_TO; + + /* Clear the error flag */ + __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_TO); + } + + /* Check error flags */ + if ((tmp_csr & (DMA_FLAG_DTE | DMA_FLAG_ULE | DMA_FLAG_USE)) != 0U) + { + /* Check the data transfer error flag */ + if ((tmp_csr & DMA_FLAG_DTE) != 0U) + { + /* Update the DMA channel error code */ + hdma->ErrorCode |= HAL_DMA_ERROR_DTE; + + /* Clear the error flag */ + __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_DTE); + } + + /* Check the update link error flag */ + if ((tmp_csr & DMA_FLAG_ULE) != 0U) + { + /* Update the DMA channel error code */ + hdma->ErrorCode |= HAL_DMA_ERROR_ULE; + + /* Clear the error flag */ + __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_ULE); + } + + /* Check the user setting error flag */ + if ((tmp_csr & DMA_FLAG_USE) != 0U) + { + /* Update the DMA channel error code */ + hdma->ErrorCode |= HAL_DMA_ERROR_USE; + + /* Clear the error flag */ + __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_USE); + } + + /* Reset the channel */ + hdma->Instance->CCR |= DMA_CCR_RESET; + + /* Update the DMA channel state */ + hdma->State = HAL_DMA_STATE_READY; + + /* Check DMA channel transfer mode */ + if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + /* Update the linked-list queue state */ + hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_ERROR; + } + + /* Clear the transfer level flag */ + if (CompleteLevel == HAL_DMA_HALF_TRANSFER) + { + /* Clear the Half Transfer flag */ + __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_HT); + } + else if (CompleteLevel == HAL_DMA_FULL_TRANSFER) + { + /* Clear the transfer flags */ + __HAL_DMA_CLEAR_FLAG(hdma, (DMA_FLAG_TC | DMA_FLAG_HT)); + + /* Update the DMA channel state */ + hdma->State = HAL_DMA_STATE_READY; + + /* Check DMA channel transfer mode */ + if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + /* Update the linked-list queue state */ + hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY; + } + + /* Process unlocked */ + __HAL_UNLOCK(hdma); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Handle DMA interrupt request (Non-blocking mode). + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the + * specified DMA Channel. + * @retval None. + */ +void HAL_DMA_IRQHandler(DMA_HandleTypeDef *const hdma) +{ + const DMA_TypeDef *p_dma_instance = GET_DMA_INSTANCE(hdma); + uint32_t global_it_flag = 1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU); + uint32_t global_active_flag_ns = IS_DMA_GLOBAL_ACTIVE_FLAG_NS(p_dma_instance, global_it_flag); +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + uint32_t global_active_flag_s = IS_DMA_GLOBAL_ACTIVE_FLAG_S(p_dma_instance, global_it_flag); +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + /* Global Interrupt Flag management *********************************************************************************/ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + if ((global_active_flag_s == 0U) && (global_active_flag_ns == 0U)) +#else + if (global_active_flag_ns == 0U) +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + { + return; /* the global interrupt flag for the current channel is down , nothing to do */ + } + + /* Data Transfer Error Interrupt management *************************************************************************/ + if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_DTE) != 0U)) + { + /* Check if interrupt source is enabled */ + if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DTE) != 0U) + { + /* Clear the transfer error flag */ + __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_DTE); + + /* Update the DMA channel error code */ + hdma->ErrorCode |= HAL_DMA_ERROR_DTE; + } + } + + /* Update Linked-list Error Interrupt management ********************************************************************/ + if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_ULE) != 0U)) + { + /* Check if interrupt source is enabled */ + if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_ULE) != 0U) + { + /* Clear the update linked-list error flag */ + __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_ULE); + + /* Update the DMA channel error code */ + hdma->ErrorCode |= HAL_DMA_ERROR_ULE; + } + } + + /* User Setting Error Interrupt management **************************************************************************/ + if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_USE) != 0U)) + { + /* Check if interrupt source is enabled */ + if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_USE) != 0U) + { + /* Clear the user setting error flag */ + __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_USE); + + /* Update the DMA channel error code */ + hdma->ErrorCode |= HAL_DMA_ERROR_USE; + } + } + + /* Trigger Overrun Interrupt management *****************************************************************************/ + if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_TO) != 0U)) + { + /* Check if interrupt source is enabled */ + if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TO) != 0U) + { + /* Clear the trigger overrun flag */ + __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_TO); + + /* Update the DMA channel error code */ + hdma->ErrorCode |= HAL_DMA_ERROR_TO; + } + } + + /* Half Transfer Complete Interrupt management **********************************************************************/ + if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_HT) != 0U)) + { + /* Check if interrupt source is enabled */ + if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != 0U) + { + /* Clear the half transfer flag */ + __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_HT); + + /* Check half transfer complete callback */ + if (hdma->XferHalfCpltCallback != NULL) + { + /* Half transfer callback */ + hdma->XferHalfCpltCallback(hdma); + } + } + } + + /* Suspend Transfer Interrupt management ****************************************************************************/ + if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_SUSP) != 0U)) + { + /* Check if interrupt source is enabled */ + if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_SUSP) != 0U) + { + /* Clear the block transfer complete flag */ + __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_SUSP); + + /* Check DMA channel state */ + if (hdma->State == HAL_DMA_STATE_ABORT) + { + /* Disable the suspend transfer interrupt */ + __HAL_DMA_DISABLE_IT(hdma, DMA_IT_SUSP); + + /* Reset the channel internal state and reset the FIFO */ + hdma->Instance->CCR |= DMA_CCR_RESET; + + if ((hdma->Instance->CCR & DMA_CCR_EN) != 0U) + { + /* Update the DMA channel state */ + hdma->State = HAL_DMA_STATE_ERROR; + } + else + { + /* Update the DMA channel state */ + hdma->State = HAL_DMA_STATE_READY; + } + + /* Check DMA channel transfer mode */ + if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + /* Update the linked-list queue state */ + hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY; + + /* Clear remaining data size to ensure loading linked-list from memory next start */ + hdma->Instance->CBR1 = 0U; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + /* Check transfer abort callback */ + if (hdma->XferAbortCallback != NULL) + { + /* Transfer abort callback */ + hdma->XferAbortCallback(hdma); + } + + return; + } + else + { + /* Update the DMA channel state */ + hdma->State = HAL_DMA_STATE_SUSPEND; + + /* Check transfer suspend callback */ + if (hdma->XferSuspendCallback != NULL) + { + /* Transfer suspend callback */ + hdma->XferSuspendCallback(hdma); + } + } + } + } + + /* Transfer Complete Interrupt management ***************************************************************************/ + if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_TC) != 0U)) + { + /* Check if interrupt source is enabled */ + if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != 0U) + { + /* Check DMA channel transfer mode */ + if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + /* If linked-list transfer */ + if (hdma->Instance->CLLR == 0U) + { + if (hdma->Instance->CBR1 == 0U) + { + /* Update the DMA channel state */ + hdma->State = HAL_DMA_STATE_READY; + + /* Update the linked-list queue state */ + hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY; + } + } + } + else + { + /* If normal transfer */ + if (hdma->Instance->CBR1 == 0U) + { + /* Update the DMA channel state */ + hdma->State = HAL_DMA_STATE_READY; + } + } + + /* Clear TC and HT transfer flags */ + __HAL_DMA_CLEAR_FLAG(hdma, (DMA_FLAG_TC | DMA_FLAG_HT)); + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + /* Check transfer complete callback */ + if (hdma->XferCpltCallback != NULL) + { + /* Channel Transfer Complete callback */ + hdma->XferCpltCallback(hdma); + } + } + } + + /* Manage error case ************************************************************************************************/ + if (hdma->ErrorCode != HAL_DMA_ERROR_NONE) + { + /* Reset the channel internal state and reset the FIFO */ + hdma->Instance->CCR |= DMA_CCR_RESET; + + if ((hdma->Instance->CCR & DMA_CCR_EN) != 0U) + { + /* Update the DMA channel state */ + hdma->State = HAL_DMA_STATE_ERROR; + } + else + { + /* Update the DMA channel state */ + hdma->State = HAL_DMA_STATE_READY; + } + + /* Check DMA channel transfer mode */ + if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + /* Update the linked-list queue state */ + hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + /* Check transfer error callback */ + if (hdma->XferErrorCallback != NULL) + { + /* Transfer error callback */ + hdma->XferErrorCallback(hdma); + } + } +} + +/** + * @brief Register callback according to specified ID. + * @note The HAL_DMA_RegisterCallback() may be called before HAL_DMA_Init() in HAL_DMA_STATE_RESET + * to register callbacks for HAL_DMA_MSPINIT_CB_ID and HAL_DMA_MSPDEINIT_CB_ID. + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the + * specified DMA Channel. + * @param CallbackID : User Callback identifier which could be a value of HAL_DMA_CallbackIDTypeDef enumeration. + * @param pCallback : Pointer to private callback function. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *const hdma, + HAL_DMA_CallbackIDTypeDef CallbackID, + void (*const pCallback)(DMA_HandleTypeDef *const _hdma)) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the DMA peripheral handle parameter */ + if (hdma == NULL) + { + return HAL_ERROR; + } + + /* Check DMA channel state */ + if (hdma->State == HAL_DMA_STATE_READY) + { + /* Check callback ID */ + switch (CallbackID) + { + case HAL_DMA_XFER_CPLT_CB_ID: + { + /* Register transfer complete callback */ + hdma->XferCpltCallback = pCallback; + break; + } + + case HAL_DMA_XFER_HALFCPLT_CB_ID: + { + /* Register half transfer callback */ + hdma->XferHalfCpltCallback = pCallback; + break; + } + + case HAL_DMA_XFER_ERROR_CB_ID: + { + /* Register transfer error callback */ + hdma->XferErrorCallback = pCallback; + break; + } + + case HAL_DMA_XFER_ABORT_CB_ID: + { + /* Register abort callback */ + hdma->XferAbortCallback = pCallback; + break; + } + + case HAL_DMA_XFER_SUSPEND_CB_ID: + { + /* Register suspend callback */ + hdma->XferSuspendCallback = pCallback; + break; + } + + default: + { + /* Update error status */ + status = HAL_ERROR; + break; + } + } + } + else + { + /* Update error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister callback according to specified ID. + * @note The HAL_DMA_UnRegisterCallback() may be called before HAL_DMA_Init() in HAL_DMA_STATE_RESET + * to un-register callbacks for HAL_DMA_MSPINIT_CB_ID and HAL_DMA_MSPDEINIT_CB_ID. + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the + * specified DMA Channel. + * @param CallbackID : User Callback identifier which could be a value of HAL_DMA_CallbackIDTypeDef enum. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *const hdma, + HAL_DMA_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the DMA peripheral handle parameter */ + if (hdma == NULL) + { + return HAL_ERROR; + } + + /* Check DMA channel state */ + if (hdma->State == HAL_DMA_STATE_READY) + { + /* Check callback ID */ + switch (CallbackID) + { + case HAL_DMA_XFER_CPLT_CB_ID: + { + /* UnRegister transfer complete callback */ + hdma->XferCpltCallback = NULL; + break; + } + + case HAL_DMA_XFER_HALFCPLT_CB_ID: + { + /* UnRegister half transfer callback */ + hdma->XferHalfCpltCallback = NULL; + break; + } + + case HAL_DMA_XFER_ERROR_CB_ID: + { + /* UnRegister transfer error callback */ + hdma->XferErrorCallback = NULL; + break; + } + + case HAL_DMA_XFER_ABORT_CB_ID: + { + /* UnRegister abort callback */ + hdma->XferAbortCallback = NULL; + break; + } + + case HAL_DMA_XFER_SUSPEND_CB_ID: + { + /* UnRegister suspend callback */ + hdma->XferSuspendCallback = NULL; + break; + } + + case HAL_DMA_XFER_ALL_CB_ID: + { + /* UnRegister all available callbacks */ + hdma->XferCpltCallback = NULL; + hdma->XferHalfCpltCallback = NULL; + hdma->XferErrorCallback = NULL; + hdma->XferAbortCallback = NULL; + hdma->XferSuspendCallback = NULL; + break; + } + + default: + { + /* Update error status */ + status = HAL_ERROR; + break; + } + } + } + else + { + /* Update error status */ + status = HAL_ERROR; + } + + return status; +} +/** + * @} + */ + +/** @addtogroup DMA_Exported_Functions_Group3 + * +@verbatim + ====================================================================================================================== + ############### State and Errors functions ############### + ====================================================================================================================== + [..] + This section provides functions allowing to : + (+) Check the DMA state + (+) Get error code + + [..] + (+) The HAL_DMA_GetState() function allows to get the DMA channel state. + (+) The HAL_DMA_DeInit() function allows to get the DMA channel error code. + +@endverbatim + * @{ + */ + +/** + * @brief Returns the DMA channel state. + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the + * specified DMA Channel. + * @retval DMA state. + */ +HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef const *const hdma) +{ + /* Return the DMA channel state */ + return hdma->State; +} + +/** + * @brief Return the DMA channel error code. + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the + * specified DMA Channel. + * @retval DMA Error Code. + */ +uint32_t HAL_DMA_GetError(DMA_HandleTypeDef const *const hdma) +{ + /* Return the DMA channel error code */ + return hdma->ErrorCode; +} +/** + * @} + */ + +/** @addtogroup DMA_Exported_Functions_Group4 + * +@verbatim + ====================================================================================================================== + ############### DMA Attributes functions ############### + ====================================================================================================================== + [..] + This section provides functions allowing to : + (+) Configure DMA channel secure and privilege attributes. + (+) Get DMA channel secure and privilege attributes. + (+) Lock DMA channel secure and privilege attributes configuration. + (+) Check whether DMA channel secure and privilege attributes configuration is locked or not. + + [..] + (+) The HAL_DMA_ConfigChannelAttributes() function allows to configure DMA channel security and privilege + attributes. + (+) The HAL_DMA_GetConfigChannelAttributes() function allows to get DMA channel security and privilege attributes + configuration. + (+) The HAL_DMA_LockChannelAttributes() function allows to lock the DMA channel security and privilege attributes. + (+) The HAL_DMA_GetLockChannelAttributes() function allows to get the DMA channel security and privilege + attributes lock status. + +@endverbatim + * @{ + */ + +/** + * @brief Configure the DMA channel security and privilege attribute(s). + * @note These attributes cannot be modified when the corresponding lock state is enabled. + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for + * the specified DMA Channel. + * @param ChannelAttributes : Specifies the DMA channel secure/privilege attributes. + * This parameter can be a one or a combination of @ref DMA_Channel_Attributes. + * @retval HAL Status. + */ +HAL_StatusTypeDef HAL_DMA_ConfigChannelAttributes(DMA_HandleTypeDef *const hdma, uint32_t ChannelAttributes) +{ + DMA_TypeDef *p_dma_instance; + uint32_t channel_idx; + + /* Check the DMA peripheral handle parameter */ + if (hdma == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DMA_ATTRIBUTES(ChannelAttributes)); + + /* Get DMA instance */ + p_dma_instance = GET_DMA_INSTANCE(hdma); + + /* Get channel index */ + channel_idx = 1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU); + + /* Check DMA channel privilege attribute management */ + if ((ChannelAttributes & DMA_CHANNEL_ATTR_PRIV_MASK) == DMA_CHANNEL_ATTR_PRIV_MASK) + { + /* Configure DMA channel privilege attribute */ + if ((ChannelAttributes & DMA_CHANNEL_PRIV) == DMA_CHANNEL_PRIV) + { + p_dma_instance->PRIVCFGR |= channel_idx; + } + else + { + p_dma_instance->PRIVCFGR &= (~channel_idx); + } + } + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + /* Check DMA channel security attribute management */ + if ((ChannelAttributes & DMA_CHANNEL_ATTR_SEC_MASK) == DMA_CHANNEL_ATTR_SEC_MASK) + { + /* Configure DMA channel security attribute */ + if ((ChannelAttributes & DMA_CHANNEL_SEC) == DMA_CHANNEL_SEC) + { + p_dma_instance->SECCFGR |= channel_idx; + } + else + { + p_dma_instance->SECCFGR &= (~channel_idx); + } + } + + /* Channel source security attribute management */ + if ((ChannelAttributes & DMA_CHANNEL_ATTR_SEC_SRC_MASK) == DMA_CHANNEL_ATTR_SEC_SRC_MASK) + { + /* Configure DMA channel source security attribute */ + if ((ChannelAttributes & DMA_CHANNEL_SRC_SEC) == DMA_CHANNEL_SRC_SEC) + { + hdma->Instance->CTR1 |= DMA_CTR1_SSEC; + } + else + { + hdma->Instance->CTR1 &= (~DMA_CTR1_SSEC); + } + } + + /* Channel destination security attribute management */ + if ((ChannelAttributes & DMA_CHANNEL_ATTR_SEC_DEST_MASK) == DMA_CHANNEL_ATTR_SEC_DEST_MASK) + { + /* Configure DMA channel destination security attribute */ + if ((ChannelAttributes & DMA_CHANNEL_DEST_SEC) == DMA_CHANNEL_DEST_SEC) + { + hdma->Instance->CTR1 |= DMA_CTR1_DSEC; + } + else + { + hdma->Instance->CTR1 &= (~DMA_CTR1_DSEC); + } + } +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + return HAL_OK; +} + +/** + * @brief Get the DMA channel security and privilege attributes. + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information + * for the specified DMA Channel. + * @param pChannelAttributes : Pointer to the returned attributes. + * @retval HAL Status. + */ +HAL_StatusTypeDef HAL_DMA_GetConfigChannelAttributes(DMA_HandleTypeDef const *const hdma, + uint32_t *const pChannelAttributes) +{ + const DMA_TypeDef *p_dma_instance; + uint32_t attributes; + uint32_t channel_idx; + + /* Check the DMA peripheral handle and channel attributes parameters */ + if ((hdma == NULL) || (pChannelAttributes == NULL)) + { + return HAL_ERROR; + } + + /* Get DMA instance */ + p_dma_instance = GET_DMA_INSTANCE(hdma); + + /* Get channel index */ + channel_idx = 1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU); + + /* Get DMA channel privilege attribute */ + attributes = ((p_dma_instance->PRIVCFGR & channel_idx) == 0U) ? DMA_CHANNEL_NPRIV : DMA_CHANNEL_PRIV; + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + /* Get DMA channel security attribute */ + attributes |= ((p_dma_instance->SECCFGR & channel_idx) == 0U) ? DMA_CHANNEL_NSEC : DMA_CHANNEL_SEC; + + /* Get DMA channel source security attribute */ + attributes |= ((hdma->Instance->CTR1 & DMA_CTR1_SSEC) == 0U) ? DMA_CHANNEL_SRC_NSEC : DMA_CHANNEL_SRC_SEC; + + /* Get DMA channel destination security attribute */ + attributes |= ((hdma->Instance->CTR1 & DMA_CTR1_DSEC) == 0U) ? DMA_CHANNEL_DEST_NSEC : DMA_CHANNEL_DEST_SEC; + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + /* return value */ + *pChannelAttributes = attributes; + + return HAL_OK; +} + + +#if defined (DMA_RCFGLOCKR_LOCK0) +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Lock the DMA channel security and privilege attribute(s). + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the + * specified DMA Channel. + * @retval HAL Status. + */ +HAL_StatusTypeDef HAL_DMA_LockChannelAttributes(DMA_HandleTypeDef const *const hdma) +{ + DMA_TypeDef *p_dma_instance; + uint32_t channel_idx; + + /* Check the DMA peripheral handle parameter */ + if (hdma == NULL) + { + return HAL_ERROR; + } + + /* Get DMA instance */ + p_dma_instance = GET_DMA_INSTANCE(hdma); + + /* Get channel index */ + channel_idx = 1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU); + + /* Lock the DMA channel privilege and security attributes */ + p_dma_instance->RCFGLOCKR |= channel_idx; + + return HAL_OK; +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/** + * @brief Get the security and privilege attribute lock state of a DMA channel. + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the + * specified DMA Channel. + * @param pLockState : Pointer to lock state (returned value can be DMA_CHANNEL_ATTRIBUTE_UNLOCKED or + * DMA_CHANNEL_ATTRIBUTE_LOCKED). + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMA_GetLockChannelAttributes(DMA_HandleTypeDef const *const hdma, uint32_t *const pLockState) +{ + DMA_TypeDef *p_dma_instance; + uint32_t channel_idx; + + /* Check the DMA peripheral handle and lock state parameters */ + if ((hdma == NULL) || (pLockState == NULL)) + { + return HAL_ERROR; + } + + /* Get DMA instance */ + p_dma_instance = GET_DMA_INSTANCE(hdma); + + /* Get channel index */ + channel_idx = 1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU); + + /* Get channel lock attribute state */ + *pLockState = ((p_dma_instance->RCFGLOCKR & channel_idx) == 0U) ? DMA_CHANNEL_ATTRIBUTE_UNLOCKED : \ + DMA_CHANNEL_ATTRIBUTE_LOCKED; + + return HAL_OK; +} +#endif /* defined (DMA_RCFGLOCKR_LOCK0) */ +/** + * @} + */ + +/** + * @} + */ + + +/* Private functions -------------------------------------------------------------------------------------------------*/ +/** @defgroup DMA_Private_Functions DMA Private Functions + * @brief DMA Private Functions + * @{ + */ + +/** + * @brief Set the DMA channel normal transfer parameters. + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the + * specified DMA Channel. + * @param SrcAddress : The source data address. + * @param DstAddress : The destination data address. + * @param SrcDataSize : The length of data to be transferred from source to destination in bytes. + * @retval None. + */ +static void DMA_SetConfig(DMA_HandleTypeDef const *const hdma, + uint32_t SrcAddress, + uint32_t DstAddress, + uint32_t SrcDataSize) +{ + /* Configure the DMA channel data size */ + MODIFY_REG(hdma->Instance->CBR1, DMA_CBR1_BNDT, (SrcDataSize & DMA_CBR1_BNDT)); + + /* Clear all interrupt flags */ + __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_TC | DMA_FLAG_HT | DMA_FLAG_DTE | DMA_FLAG_ULE | DMA_FLAG_USE | DMA_FLAG_SUSP | + DMA_FLAG_TO); + + /* Configure DMA channel source address */ + hdma->Instance->CSAR = SrcAddress; + + /* Configure DMA channel destination address */ + hdma->Instance->CDAR = DstAddress; +} + +/** + * @brief Initialize the DMA channel in normal mode according to the specified parameters in the DMA_InitTypeDef. + * @param hdma : pointer to a DMA_HandleTypeDef structure that contains the configuration information for the + * specified DMA Channel. + * @retval None. + */ +static void DMA_Init(DMA_HandleTypeDef const *const hdma) +{ + uint32_t tmpreg; + + /* Prepare DMA Channel Control Register (CCR) value *****************************************************************/ + tmpreg = hdma->Init.Priority; + + /* Write DMA Channel Control Register (CCR) */ + MODIFY_REG(hdma->Instance->CCR, DMA_CCR_PRIO | DMA_CCR_LAP | DMA_CCR_LSM, tmpreg); + + /* Prepare DMA Channel Transfer Register (CTR1) value ***************************************************************/ + tmpreg = hdma->Init.DestInc | hdma->Init.DestDataWidth | hdma->Init.SrcInc | hdma->Init.SrcDataWidth; + + /* Add parameters specific to GPDMA */ + if (IS_GPDMA_INSTANCE(hdma->Instance) != 0U) + { + tmpreg |= (hdma->Init.TransferAllocatedPort | + (((hdma->Init.DestBurstLength - 1U) << DMA_CTR1_DBL_1_Pos) & DMA_CTR1_DBL_1) | + (((hdma->Init.SrcBurstLength - 1U) << DMA_CTR1_SBL_1_Pos) & DMA_CTR1_SBL_1)); + } + + /* Write DMA Channel Transfer Register 1 (CTR1) */ +#if defined (DMA_CTR1_SSEC) + MODIFY_REG(hdma->Instance->CTR1, ~(DMA_CTR1_SSEC | DMA_CTR1_DSEC), tmpreg); +#else + WRITE_REG(hdma->Instance->CTR1, tmpreg); +#endif /* defined (DMA_CTR1_SSEC) */ + + /* Prepare DMA Channel Transfer Register 2 (CTR2) value *************************************************************/ + tmpreg = hdma->Init.BlkHWRequest | (hdma->Init.Request & DMA_CTR2_REQSEL) | hdma->Init.TransferEventMode; + + /* Memory to Peripheral Transfer */ + if ((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH) + { + if (IS_GPDMA_INSTANCE(hdma->Instance) != 0U) + { + tmpreg |= DMA_CTR2_DREQ; + } + } + /* Memory to Memory Transfer */ + else if ((hdma->Init.Direction) == DMA_MEMORY_TO_MEMORY) + { + tmpreg |= DMA_CTR2_SWREQ; + } + else + { + /* Nothing to do */ + } + + /* Set DMA channel operation mode */ + tmpreg |= hdma->Init.Mode; + + /* Write DMA Channel Transfer Register 2 (CTR2) */ + MODIFY_REG(hdma->Instance->CTR2, (DMA_CTR2_TCEM | DMA_CTR2_TRIGPOL | DMA_CTR2_TRIGSEL | DMA_CTR2_TRIGM | + DMA_CTR2_PFREQ | DMA_CTR2_BREQ | DMA_CTR2_DREQ | DMA_CTR2_SWREQ | + DMA_CTR2_REQSEL), tmpreg); + + + /* Write DMA Channel Block Register 1 (CBR1) ************************************************************************/ + WRITE_REG(hdma->Instance->CBR1, 0U); + + /* If 2D Addressing is supported by current channel */ + if (IS_DMA_2D_ADDRESSING_INSTANCE(hdma->Instance) != 0U) + { + /* Write DMA Channel Transfer Register 3 (CTR3) *******************************************************************/ + WRITE_REG(hdma->Instance->CTR3, 0U); + + /* Write DMA Channel Block Register 2 (CBR2) **********************************************************************/ + WRITE_REG(hdma->Instance->CBR2, 0U); + } + + /* Write DMA Channel linked-list address register (CLLR) ************************************************************/ + WRITE_REG(hdma->Instance->CLLR, 0U); +} +/** + * @} + */ + +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dma_ex.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dma_ex.c new file mode 100644 index 0000000000..af64585273 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dma_ex.c @@ -0,0 +1,4715 @@ +/** + ********************************************************************************************************************** + * @file stm32h5xx_hal_dma_ex.c + * @author MCD Application Team + * @brief DMA Extension HAL module driver + * This file provides firmware functions to manage the following functionalities of the DMA extension + * peripheral: + * + Linked-List Initialization and De-Initialization Functions + * + Linked-List I/O Operation Functions + * + Linked-List Management Functions + * + Data Handling, Repeated Block and Trigger Configuration Functions + * + Suspend and Resume Operation Functions + * + FIFO Status Function + * + ********************************************************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ********************************************************************************************************************** + @verbatim + ====================================================================================================================== + ############### How to use this driver ############### + ====================================================================================================================== + [..] + Alternatively to the normal programming mode, a DMA channel can be programmed by a list of transfers, known as + linked-list (list of Node items). Each node is defined by its data structure. + Each node specifies a standalone DMA channel. + When enabled, the DMA channel fetch the first linked-list node from SRAM (known as head node). When executed, the + next linked list node will be fetched and executed. This operation is repeated until the end of the whole + linked-list queue. Optionally, the linked-list can be linear where the last linked-list queue node is not linked + to another queue node or circular where the last linked-list node is linked to any linked-list queue node. + + (+) Linear linked-list: + The DMA channel fetch and execute all DMA linked-list queue from first node (head node) to last node + (tail node) ones. When the last node is completed, the DMA channel remains in idle state and another + transfer can be lunched. + + (+) Circular linked-list: + The DMA channel fetch and execute all DMA linked-list queue from first node (head node) to last node (tail + node). When last node is executed, the DMA channel fetches the first circular node another time and repeat + the same sequence in an infinite loop (Circular transfer). To stop the DMA channel, an abort operation is + required. This linked-list mode replaces the legacy circular transfers. + + [..] + In order to reduce linked-list queue executing time and power consumption, the DMA channel supports executing the + dynamic linked-list format. In fact, the DMA supports the execution of 2 types of linked-list formats : static and + dynamic. + + (+) Static linked-list: + The static linked-list format refers to the full linked-list node where all DMA channel parameters are + fetched and executed independently of the redundancy of information. + + (+) Dynamic linked-list: + The dynamic linked-list format refer to the customized linked-list node where only DMA channel necessary + parameters are fetched and executed (Example: data size = 20 on previous node, and data size = 20 on the + current node => No need to update it). + + For linked-list transfers, the DMA channel can execute the linked-list queue node by node. This feature is named + link step mode. When activated, enabling the DMA channel first time allows to fetch the head node from memory + then it stops. Then, another DMA channel enable is needed to execute the node. After that, keeping enabling the + DMA channel is needed to execute each node until the end of linked-list queue. When the linked-list queue is + circular, enabling the DMA channel in an infinite loop is required to keep the DMA channel running. This feature + is useful for debug purpose or asynchronously executing queue nodes. + + [..] + Each DMA channel transfer (normal or linked-list), is highly configurable according to DMA channel instance + integrated in devices. These configuration can be : + + (+) Repeated block configuration : + If the feature is supported, the DMA channel can performs a repeated block transfers. Named also 2 + dimension addressing transfers, this feature can transfer n iteration of programmed block transfer (Block + transfer is the legacy data size). Additional to the repeat count of a block, DMA channel addresses can + jump after at burst and block level. The jump length is a programmable parameter defined by DMA user. + (++) Jump at burst level : + The DMA channel keep an empty area, between each 2 consecutive bursts transmitted. + (++) Jump at block level : + The DMA channel keep an empty area, between each 2 consecutive blocks transmitted. + + (+) Trigger : + The DMA channel transfers can be conditioned by hardware signals edges (rising or falling) named hardware + triggers. Trigger condition can be applied at : + (++) Single/Burst level : + Each single/burst data transmission is conditioned by a signal trigger hit. + (++) Block level : + Each block data transmission is conditioned by a signal trigger hit. + (++) Repeated block level : + Each repeated block data transmission is conditioned by a signal trigger hit. + (++) Node level : + Each node execution is conditioned by a signal trigger hit. + The DMA channel can report a trigger overrun when detects more than 2 trigger signal edges before + executing the current transfer. + + (+) Data handling : + The data handling feature is a FIFO capability that can be : + (++) Padding pattern : + Padding selected pattern (zero padding or sign extension) when the source data width is smaller + than the destination data width at single level. + (++) Truncation : + Truncate section from the source data single when the source data width is bigger than the + destination data width. + (++) Pack/Unpack : + Pack a set of data when source data width is smaller than the destination data width. + Unpack a set of data when source data width is bigger than the destination data width. + (++) Exchange : + Exchange data at byte and half-word on the destination and at byte level on the source. + + [..] + Each DMA channel transfer (normal or linked-list) when it is active, can be suspended and resumed at run time + application. When trying to suspend an ongoing transfer, the DMA channel isn't suspended instantly but complete + the current ongoing single/burst then it stops. + When the DMA channel is suspended, the current transfer can be resumed instantly. + + [..] + The DMA channel that supports FIFO, can report in real time the number of beats remains on destination (Output) + FIFO level. + + *** Linked-List Initialization and De-Initialization operation *** + ================================================================== + [..] + Differently from normal transfers, DMA channel initialization and de-initialization need less parameters as the + remaining transfer parameters are defined by linked-list nodes. + + (+) Use HAL_DMAEx_List_Init() to initialize a DMA channel in linked-list mode according to programmed fields. + When called, the DMA channel will be ready to execute linked-list queues. + + (+) Use HAL_DMAEx_List_DeInit() to de-initialize a DMA channel in linked-list mode. + When called, the DMA channel will be in reset. It is mandatory to reinitialize it for next transfer. + + *** Linked-List I/O Operation *** + ================================= + [..] + (+) Use HAL_DMAEx_List_Start() to start a DMA transfer in linked-list mode after the configuration of + linked-list queue base address and offset in polling mode (Blocking mode). + + (+) Use HAL_DMAEx_List_Start_IT() to start a DMA transfer in linked-list mode after the configuration of + linked-list queue base address and offset in interrupt mode (Non-blocking mode). + + *** Linked-List Management *** + ============================== + [..] + The linked-list management is a software processing independently of DMA channel hardware. It allows to reset, + build, create, insert, remove, replace, circularize, convert both nodes and queue in order to perform DMA + channel transfers in linked-list mode. + Linked-list APIs and types are adapted to reduce memory footprint. + + *** Linked-list nodes building *** + [..] + At node level, the operations that can be done are building a new linked-list node or get a linked-list node + information from a built node. The linked-list nodes have two forms according to 2 dimensions addressing + capability. The linear addressing nodes contains the information of all DMA channel features except the 2 + dimension addressing features and the 2 dimensions addressing nodes contain the information of all available + features. + + (+) Use HAL_DMAEx_List_BuildNode() to build the DMA linked-list node according to the specified parameters. + Build operation allow to convert the specified parameter in values known by the DMA channel and place them + in memory. + Placing DMA linked-list in SRAM must be done in accordance to product specification to ensure that the + link access port can access to the specified SRAM. + (++) The DMA linked-list node parameter address should be 32bit aligned and should not exceed the 64 KByte + addressable space. + + (+) Use HAL_DMAEx_List_GetNodeConfig() to get the specified configuration parameter on building node. + This API can be used when need to change few parameter to build new node. + + *** Inserting nodes to linked-list queue *** + [..] + In order to build a sequence of DMA transaction with different configuration, we need to insert built node at + linked-list queue (node present an elementary DMA transaction) in linked-list queue on any position to have the + full flexibility of ordering nodes or extend the sequence of queue transactions. + + (+) Use HAL_DMAEx_List_InsertNode() to insert new built node in any queue position of linked-list queue + according to selecting previous node. When calling this API with previous node parameter is NULL, the + inserted node will be placed at the head of the linked-list queue. + (++) This API must be used after HAL_DMAEx_List_BuildNode() otherwise an error will be returned. + (++) This API must be called for static queues format. + (++) This API shall be avoided when adding new node at the head or the tail of queue (overhead of + footprint and performance : use HAL_DMAEx_List_InsertNode_Head() or HAL_DMAEx_List_InsertNode_Tail() + instead). + + (+) Use HAL_DMAEx_List_InsertNode_Head() to insert new built node at the head of linked-list queue. The head + node will not be overwritten but will be the second queue node. + (++) This API must be used after HAL_DMAEx_List_BuildNode() otherwise an error will be returned. + (++) This API must be called for static queues format. + + (+) Use HAL_DMAEx_List_InsertNode_Tail() to insert new built node at the tail of linked-list queue. The tail + node will not be overwritten but will be the penultimate queue node. + (++) This API must be used after HAL_DMAEx_List_BuildNode() otherwise an error will be returned. + (++) This API must be called for static queues format. + + *** Removing nodes from linked-list queue *** + [..] + There is some cases when removing a node from linked-list queue is needed (need to remove an elementary DMA + transaction). Removing node allows to unlink a node from DMA linked-list queue (NOT DELETED), so the removed node + can be reused for another queue or to be added to the same queue without need to rebuild it in next step. + + (+) Use HAL_DMAEx_List_RemoveNode() to remove any yet built and inserted node from linked-list queue according + to selected node. + (++) This API must be called for static queues format. + (++) This API shall be avoided when removing the head or the tail of linked-list queue (overhead of + footprint and performance : use HAL_DMAEx_List_RemoveNode_Head() or HAL_DMAEx_List_RemoveNode_Tail() + instead). + + (+) Use HAL_DMAEx_List_RemoveNode_Head() to remove the head node from linked-list queue. + (++) This API must be called for static queues format. + + (+) Use HAL_DMAEx_List_RemoveNode_Tail() to remove the tail node from linked-list queue. + (++) This API must be called for static queues format. + + *** Replacing nodes on linked-list queue *** + [..] + There is some cases when replacing a node from linked-list queue is needed (need to replace an elementary DMA + transfer, by another one that have not the same configuration). Replacing node allows to unlink the node to be + replaced from DMA linked-list queue (NOT DELETED) and link instead a new node. So the replaced node can be reused + for another queue or to be added to the same queue without need to rebuild it in next step and the new node cannot + be reused except when remove it or replaced in next step. + + (+) Use HAL_DMAEx_List_ReplaceNode() to replace any yet built and inserted node on linked-list queue according + to selected node. + (++) This API must be called for static queues format. + (++) This API shall be avoided when replacing the head or the tail linked-list queue (overhead of + footprint and performance : use HAL_DMAEx_List_ReplaceNode_Head() or + HAL_DMAEx_List_ReplaceNode_Tail() instead). + + (+) Use HAL_DMAEx_List_ReplaceNode_Head() to replace the head node of linked-list queue. + (++) This API must be called for static queues format. + + (+) Use HAL_DMAEx_List_ReplaceNode_Tail() to replace the tail node from linked-list queue. + (++) This API must be called for static queues format. + + *** Reset linked-list queue *** + [..] + After finishing using a linked-list queue, it can be reset and cleared and it's content nodes will be + unlinked (NOT DELETED) and reused on another queue. + + (+) Use HAL_DMAEx_List_ResetQ() to reset a linked-list queue and unlink all it's content nodes. + (++) This API must be called for ready state queues. + (++) This API must be called for static queues format. + + *** Inserting linked-list queue *** + [..] + To ensure the flexibility of building linked-list queue by their targeted functionalities (Example: 3 nodes for + action 1 and 5 nodes for action 2), it is possible to build a queue for action 1 that contains action 1 nodes and + a queue for action 2 that contains action 2 nodes then concatenating the 2 queues. So, there are some cases where + the management of linked-list at queue granularity is needed. + + (+) Use HAL_DMAEx_List_InsertQ() to insert source linked-list queue to a destination linked-list queue + according to selecting previous node. + (++) This API must be called for static queues format. + (++) This API shall be avoided when inserting source linked-list queue at the head or the tail of + destination queue (overhead of footprint and performance : use HAL_DMAEx_List_InsertQ_Head() or + HAL_DMAEx_List_InsertQ_Tail() instead). + + (+) Use HAL_DMAEx_List_InsertQ_Head() to insert a source linked-list queue at the head of linked-list + destination queue. + (++) This API must be called for static queues format. + + (+) Use HAL_DMAEx_List_InsertQ_Tail() to insert a source linked-list queue at the tail of linked-list + destination queue. + (++) This API must be called for static queues format. + + *** Circularizing linked-list queue *** + [..] + In order to perform tasks in infinite loop with DMA channel, it is possible to circularize the linked-list queues. + Circularizing queue allows to link last linked-list queue node to any previous node of the same queue (This node + is named first circular queue). When the first circular node is the head node, all linked-list queue nodes will be + executed in infinite loop. When the first circular node is not the head nodes, all precedent nodes are executed + once and all remaining nodes are executed in an infinite loop. + + (+) Use HAL_DMAEx_List_SetCircularModeConfig() to circularize the linked-list queue according to first + circular node selected. + (++) This API must be called for static queues format. + (++) This API shall be avoided when first circular node is the head linked-list queue node (overhead of + footprint and performance : use HAL_DMAEx_List_SetCircularMode() instead). + + (+) Use HAL_DMAEx_List_SetCircularMode() to circularize the linked-list queue with linking last queue node + with first queue node. + (++) This API must be called for static queues format. + + (+) Use HAL_DMAEx_List_ClearCircularMode() to clear any linked-list queue circular configuration. + (++) This API must be called for static queues format. + + + *** Converting linked-list queue *** + [..] + To have the best DMA channel linked-list queue execution, it is recommended to convert yet build linked-list queue + to dynamic format (Static is the default format). When linked-list queue becomes dynamic, all queue nodes are + optimized and only changed parameters will be updated between nodes. So, the DMA will fetch only changes + parameters instead of the whole node. + + (+) Use HAL_DMAEx_List_ConvertQToDynamic() to convert a linked-list queue to dynamic format. + (++) This API must be called for ready state queues. + (++) This API must be called for static queues format. + (++) This API must be called as the last API before starting the DMA channel in linked-list mode. + + (+) Use HAL_DMAEx_List_ConvertQToStatic() to convert a linked-list queue to static format. + (++) This API must be called for ready state queues. + (++) This API must be called for dynamic queues format. + (++) This API must be called as the first API after the full execution of linked-list queue when the + execution mode is linear (not circular) if it is dynamic and a linked-list queue management is + needed. + (++) This API must be called as the first API after the aborting the execution of the current linked-list + queue when the execution mode is linear (not circular) if it is dynamic and a linked-list queue + management is needed. + + [..] + When converting a circular queue to dynamic format and when the first circular node is the last queue node, it is + recommended to duplicate the last circular node in order to ensure the full optimization when calling + HAL_DMAEx_List_ConvertQToDynamic() API. In this case, updated information are only addresses which allow to reduce + 4 words of update for linear nodes per node execution and 6 words update for 2 dimensions addressing nodes per + node execution. + + + *** Linking linked-list queue to DMA channel *** + [..] + In order to have the possibility of the creation of an infinity queues (limited by available memory size), the + building of linked-list queue is fully independent from DMA channels. It is possible to build all needed queues if + their size is less then available memory at startup time, then linking each time when needed a linked-list queue + to an idle DMA channel. + + (+) Use HAL_DMAEx_List_LinkQ() to link a ready linked-list queue to ready DMA channel. + (++) This API supports the two format of linked-list (Static and dynamic). + (++) This API must be called for ready state queues and DMA channels. + + (+) Use HAL_DMAEx_List_ConvertQToStatic() to unlink a ready linked-list queue to ready DMA channel. + (++) This API supports the two format of linked-list (Static and dynamic). + (++) This API must be called for ready state queues and DMA channels. + + *** User sequence *** + [..] + To use cleanly the DMA linked-list library, ensure to apply the following call sequences : + + (+) Linear transfer : + Linked-list queue building + (++) HAL_DMAEx_List_BuildNode() + (++) HAL_DMAEx_List_InsertNode_Tail() + . + . + . + (++) HAL_DMAEx_List_BuildNode() + (++) HAL_DMAEx_List_InsertNode_Tail() + (++) HAL_DMAEx_List_ConvertQToDynamic() + Linked-list queue execution + (++) HAL_DMAEx_List_Init() + (++) HAL_DMAEx_List_LinkQ() + (++) HAL_DMAEx_List_Start() / HAL_DMAEx_List_Start_IT() + (++) HAL_DMAEx_List_UnLinkQ() + (++) HAL_DMAEx_List_DeInit() + + (+) Circular transfer : + Linked-list queue building + (++) HAL_DMAEx_List_BuildNode() + (++) HAL_DMAEx_List_InsertNode_Tail() + . + . + . + (++) HAL_DMAEx_List_BuildNode() + (++) HAL_DMAEx_List_InsertNode_Tail() + (++) HAL_DMAEx_List_SetCircularModeConfig() / HAL_DMAEx_List_SetCircularMode() + (++) HAL_DMAEx_List_ConvertQToDynamic() + Linked-list queue execution + (++) HAL_DMAEx_List_Init() + (++) HAL_DMAEx_List_LinkQ() + (++) HAL_DMAEx_List_Start() / HAL_DMAEx_List_Start_IT() + (++) HAL_DMA_Abort() / HAL_DMA_Abort_IT() + (++) HAL_DMAEx_List_UnLinkQ() + (++) HAL_DMAEx_List_DeInit() + + + *** Data Handling *** + ===================== + [..] + In order to avoid some CPU data processing in several cases, the DMA channel provides some features related to + FIFO capabilities titled data handling. + (++) Padding pattern + Padding selected pattern (zero padding or sign extension) when the source data width is smaller + than the destination data width at single level. + Zero padding (Source : 0xABAB ------> Destination : 0xABAB0000) + Sign bit extension (Source : 0x0ABA ------> Destination : 0x00000ABA) + (Source : 0xFABA ------> Destination : 0xFFFFFABA) + (++) Truncation : + Truncate section from the source data single when the source data width is bigger than the + destination data width. + Left truncation (Source : 0xABABCDCD ------> Destination : 0xCDCD) + Right truncation (Source : 0xABABCDCD ------> Destination : 0xABAB) + (++) Pack/Unpack : + Pack a set of data when source data width is smaller than the destination data width. + Unpack a set of data when source data width is bigger than the destination data width. + Pack (Source : 0xAB, 0xCD ------> Destination : 0xABCD) + UnPack (Source : 0xABCD ------> Destination : 0xAB, 0xCD) + (++) Exchange : + Exchange data at byte and half-word on the destination and at byte level on the source. + Considering source and destination are both word type. Exchange operation can be as follows. + In examples below, one exchange setting is enabled at a time. + Source byte exchange only (Source : 0xAB12CD34 ------> Destination : 0xABCD1234) + Destination byte exchange only (Source : 0xAB12CD34 ------> Destination : 0x12AB34CD) + Destination half-word exchange only (Source : 0xAB12CD34 ------> Destination : 0xCD34AB12) + + (+) Use HAL_DMAEx_ConfigDataHandling() to configure data handling features. Previous elementary explained + can be combined according to application needs. + (++) This API is complementary of normal transfers. + (++) This API must not be called for linked-list transfers as data handling information are configured at + node level. + + *** User sequence *** + [..] + To configure cleanly the DMA channel data handling, ensure to apply the following call sequence : + + (+) Linear transfer : + (++) HAL_DMA_Init() + (++) HAL_DMAEx_ConfigDataHandling() + (++) HAL_DMA_Start() + + *** Repeated Block *** + ====================== + [..] + When available, this feature is used when the data size is higher then 65535 bytes (Maximum block size) or for + scattering / gathering data. + (++) Gather data + Source Destination + 0xAA 0xAA + 0xBB 0xAA + 0xAA ==> 0xAA + 0xCC + 0xAA + (++) Scatter data + Source Destination + 0xAA 0xAA + 0xAA 0xBB + 0xAA ==> 0xAA + 0xBB + 0xAA + + (+) Use HAL_DMAEx_ConfigRepeatBlock() to configure data repeated block feature. Jump addresses and + incrementing or decrementing on source and destination can be combined to have the need application + behavior. + (++) This API is complementary of normal transfers. + (++) This API must not be called for linked-list transfers as repeated block information are configured at + node level. + (++) This API must be called only for DMA channel that supports repeated block feature. + + *** User sequence *** + [..] + To configure cleanly the DMA channel repeated block, ensure to apply the following call sequence : + + (+) Linear transfer : + (++) HAL_DMA_Init() + (++) HAL_DMAEx_ConfigRepeatBlock() + (++) HAL_DMA_Start() + + *** Trigger Configuration *** + ============================= + [..] + When application needs that DMA transfers are conditioned by internal or external events, the trigger feature can + do that. Trigger signals are a set of device signal that are linked to DMA trigger inputs that allows to start the + DMA transfers. + To setup a trigger transfers, three DMA channel parameters are needed: + + (+) Trigger mode + This parameter specifies the trig level. + (++) Block level + (++) Repeated block level + (++) Node level + (++) Single / Burst level + + (+) Trigger polarity + This parameter specifies the DMA trigger sensitivity (Rising or falling). + + (+) Trigger selection + This parameter specifies the DMA trigger hardware signal. + + (+) Use HAL_DMAEx_ConfigTrigger() to configure trigger feature. + (++) This API is complementary to normal transfers APIs. + (++) This API must not be called for linked-list transfers as trigger information are configured at + node level. + + *** User sequence *** + [..] + To configure cleanly the DMA channel trigger, ensure to apply the following call sequence : + (+) Linear transfer : + (++) HAL_DMA_Init() + (++) HAL_DMAEx_ConfigTrigger() + (++) HAL_DMA_Start() + + *** Suspend and resume operation *** + ==================================== + [..] + There are several cases when needs to suspend a DMA current transfer (Example: liberate bandwidth for more + priority DMA channel transfer). Suspending DMA channel (same as abort) is available in polling (blocking mode) and + interrupt (non-blocking mode) modes. When suspended, a DMA channel can be instantly resumed. + + (+) Use HAL_DMAEx_Suspend() to suspend an ongoing DMA channel transfer in polling mode (Blocking mode). + + (+) Use HAL_DMAEx_Suspend_IT() to suspend an ongoing DMA channel transfer in interrupt mode (Non-blocking + mode). + + (+) Use HAL_DMAEx_Resume() to resume a suspended DMA channel transfer execution. + + *** FIFO status *** + =================== + [..] + In several cases, the information of FIFO level is useful to inform at application level how to process remaining + data. When not empty, the DMA channel FIFO cannot be flashed only by reset. + + (+) Use HAL_DMAEx_GetFifoLevel() to get the DMA channel FIFO level (available beats in FIFO). + + @endverbatim + ********************************************************************************************************************** + */ + +/* Includes ----------------------------------------------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup DMAEx DMAEx + * @brief DMA Extended HAL module driver + * @{ + */ + +#ifdef HAL_DMA_MODULE_ENABLED + +/* Private types -----------------------------------------------------------------------------------------------------*/ +/* Private variables -------------------------------------------------------------------------------------------------*/ +/* Private Constants -------------------------------------------------------------------------------------------------*/ +/* Private macros ----------------------------------------------------------------------------------------------------*/ +/* Private function prototypes ---------------------------------------------------------------------------------------*/ +static void DMA_List_Init(DMA_HandleTypeDef const *const hdma); +static void DMA_List_BuildNode(DMA_NodeConfTypeDef const *const pNodeConfig, + DMA_NodeTypeDef *const pNode); +static void DMA_List_GetNodeConfig(DMA_NodeConfTypeDef *const pNodeConfig, + DMA_NodeTypeDef const *const pNode); +static uint32_t DMA_List_CheckNodesBaseAddresses(DMA_NodeTypeDef const *const pNode1, + DMA_NodeTypeDef const *const pNode2, + DMA_NodeTypeDef const *const pNode3); +static uint32_t DMA_List_CheckNodesTypes(DMA_NodeTypeDef const *const pNode1, + DMA_NodeTypeDef const *const pNode2, + DMA_NodeTypeDef const *const pNode3); +static void DMA_List_GetCLLRNodeInfo(DMA_NodeTypeDef const *const pNode, + uint32_t *const cllr_mask, + uint32_t *const cllr_offset); +static uint32_t DMA_List_FindNode(DMA_QListTypeDef const *const pQList, + DMA_NodeTypeDef const *const pNode, + DMA_NodeInQInfoTypeDef *const NodeInfo); +static void DMA_List_ResetQueueNodes(DMA_QListTypeDef const *const pQList, + DMA_NodeInQInfoTypeDef const *const NodeInfo); +static void DMA_List_FillNode(DMA_NodeTypeDef const *const pSrcNode, + DMA_NodeTypeDef *const pDestNode); +static void DMA_List_ConvertNodeToDynamic(uint32_t ContextNodeAddr, + uint32_t CurrentNodeAddr, + uint32_t RegisterNumber); +static void DMA_List_ConvertNodeToStatic(uint32_t ContextNodeAddr, + uint32_t CurrentNodeAddr, + uint32_t RegisterNumber); +static void DMA_List_UpdateDynamicQueueNodesCLLR(DMA_QListTypeDef const *const pQList, + uint32_t LastNode_IsCircular); +static void DMA_List_UpdateStaticQueueNodesCLLR(DMA_QListTypeDef const *const pQList, + uint32_t operation); +static void DMA_List_FormatNode(DMA_NodeTypeDef *const pNode, + uint32_t RegisterIdx, + uint32_t RegisterNumber, + uint32_t Format); +static void DMA_List_ClearUnusedFields(DMA_NodeTypeDef *const pNode, + uint32_t FirstUnusedField); +static void DMA_List_CleanQueue(DMA_QListTypeDef *const pQList); + +/* Exported functions ------------------------------------------------------------------------------------------------*/ + +/** @addtogroup DMAEx_Exported_Functions + * @{ + */ + +/** @addtogroup DMAEx_Exported_Functions_Group1 + * +@verbatim + ====================================================================================================================== + ############### Linked-List Initialization and De-Initialization Functions ############### + ====================================================================================================================== + [..] + This section provides functions allowing to initialize and de-initialize the DMA channel in linked-list mode. + [..] + (+) The HAL_DMAEx_List_Init() function follows the DMA channel linked-list mode configuration procedures as + described in reference manual. + (+) The HAL_DMAEx_List_DeInit() function allows to de-initialize the DMA channel in linked-list mode. + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the DMA channel in linked-list mode according to the specified parameters in the + * DMA_InitLinkedListTypeDef and create the associated handle. + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the + * specified DMA Channel. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_List_Init(DMA_HandleTypeDef *const hdma) +{ + /* Get tick number */ + uint32_t tickstart = HAL_GetTick(); + + /* Check the DMA channel handle parameter */ + if (hdma == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance)); + assert_param(IS_DMA_PRIORITY(hdma->InitLinkedList.Priority)); + assert_param(IS_DMA_LINK_STEP_MODE(hdma->InitLinkedList.LinkStepMode)); + assert_param(IS_DMA_TCEM_LINKEDLIST_EVENT_MODE(hdma->InitLinkedList.TransferEventMode)); + assert_param(IS_DMA_LINKEDLIST_MODE(hdma->InitLinkedList.LinkedListMode)); + /* Check DMA channel instance */ + if (IS_GPDMA_INSTANCE(hdma->Instance) != 0U) + { + assert_param(IS_DMA_LINK_ALLOCATED_PORT(hdma->InitLinkedList.LinkAllocatedPort)); + } + + /* Allocate lock resource */ + __HAL_UNLOCK(hdma); + + /* Change DMA peripheral state */ + hdma->State = HAL_DMA_STATE_BUSY; + + /* Disable the DMA channel */ + __HAL_DMA_DISABLE(hdma); + + /* Check if the DMA channel is effectively disabled */ + while ((hdma->Instance->CCR & DMA_CCR_EN) != 0U) + { + /* Check for the Timeout */ + if ((HAL_GetTick() - tickstart) > HAL_TIMEOUT_DMA_ABORT) + { + /* Update error code */ + hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT; + + /* Change the DMA state */ + hdma->State = HAL_DMA_STATE_ERROR; + + return HAL_ERROR; + } + } + + /* Initialize the DMA channel registers */ + DMA_List_Init(hdma); + + /* Update DMA channel operation mode */ + hdma->Mode = hdma->InitLinkedList.LinkedListMode; + + /* Update the DMA channel error code */ + hdma->ErrorCode = HAL_DMA_ERROR_NONE; + + /* Update the DMA channel state */ + hdma->State = HAL_DMA_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitialize the DMA channel when it is configured in linked-list mode. + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the + * specified DMA Channel. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_List_DeInit(DMA_HandleTypeDef *const hdma) +{ + + /* Get DMA instance */ + DMA_TypeDef *p_dma_instance; + + + /* Get tick number */ + uint32_t tickstart = HAL_GetTick(); + + /* Check the DMA peripheral handle parameter */ + if (hdma == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance)); + + + /* Get DMA instance */ + p_dma_instance = GET_DMA_INSTANCE(hdma); + + + /* Disable the selected DMA Channel */ + __HAL_DMA_DISABLE(hdma); + + /* Check if the DMA channel is effectively disabled */ + while ((hdma->Instance->CCR & DMA_CCR_EN) != 0U) + { + /* Check for the Timeout */ + if ((HAL_GetTick() - tickstart) > HAL_TIMEOUT_DMA_ABORT) + { + /* Update error code */ + hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT; + + /* Change the DMA state */ + hdma->State = HAL_DMA_STATE_ERROR; + + return HAL_ERROR; + } + } + + /* Reset DMA Channel registers */ + hdma->Instance->CCR = 0U; + hdma->Instance->CLBAR = 0U; + hdma->Instance->CTR1 = 0U; + hdma->Instance->CTR2 = 0U; + hdma->Instance->CBR1 = 0U; + hdma->Instance->CSAR = 0U; + hdma->Instance->CDAR = 0U; + hdma->Instance->CLLR = 0U; + + /* Reset 2D Addressing registers */ + if (IS_DMA_2D_ADDRESSING_INSTANCE(hdma->Instance) != 0U) + { + hdma->Instance->CTR3 = 0U; + hdma->Instance->CBR2 = 0U; + } + + + /* Clear privilege attribute */ + CLEAR_BIT(p_dma_instance->PRIVCFGR, (1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU))); + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + /* Clear secure attribute */ + CLEAR_BIT(p_dma_instance->SECCFGR, (1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU))); +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + /* Clear all flags */ + __HAL_DMA_CLEAR_FLAG(hdma, (DMA_FLAG_TC | DMA_FLAG_HT | DMA_FLAG_DTE | DMA_FLAG_ULE | DMA_FLAG_USE | DMA_FLAG_SUSP | + DMA_FLAG_TO)); + + /* Clean all callbacks */ + hdma->XferCpltCallback = NULL; + hdma->XferHalfCpltCallback = NULL; + hdma->XferErrorCallback = NULL; + hdma->XferAbortCallback = NULL; + hdma->XferSuspendCallback = NULL; + + /* Check the linked-list queue */ + if (hdma->LinkedListQueue != NULL) + { + /* Update the queue state and error code */ + hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY; + hdma->LinkedListQueue->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Clean DMA queue */ + hdma->LinkedListQueue = NULL; + } + + /* Clean DMA parent */ + if (hdma->Parent != NULL) + { + hdma->Parent = NULL; + } + + /* Update DMA channel operation mode */ + hdma->Mode = DMA_NORMAL; + + /* Update the DMA channel error code */ + hdma->ErrorCode = HAL_DMA_ERROR_NONE; + + /* Update the DMA channel state */ + hdma->State = HAL_DMA_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hdma); + + return HAL_OK; +} +/** + * @} + */ + +/** @addtogroup DMAEx_Exported_Functions_Group2 + * +@verbatim + ====================================================================================================================== + ############### Linked-List IO Operation Functions ############### + ====================================================================================================================== + [..] + This section provides functions allowing to : + (+) Configure to start DMA transfer in linked-list mode. + + [..] + (+) The HAL_DMAEx_List_Start() function allows to start the DMA channel transfer in linked-list mode (Blocking + mode). + (+) The HAL_DMAEx_List_Start_IT() function allows to start the DMA channel transfer in linked-list mode + (Non-blocking mode). + (++) It is mandatory to register a linked-list queue to be executed by a DMA channel before starting + transfer otherwise a HAL_ERROR will be returned. + +@endverbatim + * @{ + */ + +/** + * @brief Start the DMA channel transfer in linked-list mode (Blocking mode). + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the + * specified DMA Channel. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_List_Start(DMA_HandleTypeDef *const hdma) +{ + HAL_DMA_StateTypeDef dma_state; + uint32_t ccr_value; + uint32_t cllr_mask; + + /* Check the DMA peripheral handle and the linked-list queue parameters */ + if ((hdma == NULL) || (hdma->LinkedListQueue == NULL)) + { + return HAL_ERROR; + } + + /* Check DMA channel state */ + dma_state = hdma->State; + ccr_value = hdma->Instance->CCR & DMA_CCR_LSM; + if ((dma_state == HAL_DMA_STATE_READY) || ((dma_state == HAL_DMA_STATE_BUSY) && (ccr_value != 0U))) + { + /* Check DMA channel state is ready */ + if (hdma->State == HAL_DMA_STATE_READY) + { + /* Process locked */ + __HAL_LOCK(hdma); + + /* Update the DMA channel and the queue states */ + hdma->State = HAL_DMA_STATE_BUSY; + hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_BUSY; + + /* Update the DMA channel and the queue error codes */ + hdma->ErrorCode = HAL_DMA_ERROR_NONE; + hdma->LinkedListQueue->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Get CLLR register mask and offset */ + DMA_List_GetCLLRNodeInfo(hdma->LinkedListQueue->Head, &cllr_mask, NULL); + + /* Update DMA registers for linked-list transfer */ + hdma->Instance->CLBAR = ((uint32_t)hdma->LinkedListQueue->Head & DMA_CLBAR_LBA); + hdma->Instance->CLLR = ((uint32_t)hdma->LinkedListQueue->Head & DMA_CLLR_LA) | cllr_mask; + } + + /* Enable DMA channel */ + __HAL_DMA_ENABLE(hdma); + } + else + { + /* Update the DMA channel error code */ + hdma->ErrorCode = HAL_DMA_ERROR_BUSY; + + /* Process unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Starts the DMA channel transfer in linked-list mode with interrupts enabled (Non-blocking mode). + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the + * specified DMA Channel. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_List_Start_IT(DMA_HandleTypeDef *const hdma) +{ + HAL_DMA_StateTypeDef dma_state; + uint32_t ccr_value; + uint32_t cllr_mask; + + /* Check the DMA peripheral handle and the linked-list queue parameters */ + if ((hdma == NULL) || (hdma->LinkedListQueue == NULL)) + { + return HAL_ERROR; + } + + /* Check DMA channel state */ + dma_state = hdma->State; + ccr_value = hdma->Instance->CCR & DMA_CCR_LSM; + if ((dma_state == HAL_DMA_STATE_READY) || ((dma_state == HAL_DMA_STATE_BUSY) && (ccr_value != 0U))) + { + /* Check DMA channel state is ready */ + if (hdma->State == HAL_DMA_STATE_READY) + { + /* Process locked */ + __HAL_LOCK(hdma); + + /* Update the DMA channel and the queue states */ + hdma->State = HAL_DMA_STATE_BUSY; + hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_BUSY; + + /* Update the DMA channel and the queue error codes */ + hdma->ErrorCode = HAL_DMA_ERROR_NONE; + hdma->LinkedListQueue->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Enable common interrupts: Transfer Complete and Transfer Errors ITs */ + __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_DTE | DMA_IT_ULE | DMA_IT_USE | DMA_IT_TO)); + + /* Check half transfer complete callback */ + if (hdma->XferHalfCpltCallback != NULL) + { + /* If half transfer complete callback is set, enable the corresponding IT */ + __HAL_DMA_ENABLE_IT(hdma, DMA_IT_HT); + } + + /* Check suspend callback */ + if (hdma->XferSuspendCallback != NULL) + { + /* If transfer suspend callback is set, enable the corresponding IT */ + __HAL_DMA_ENABLE_IT(hdma, DMA_IT_SUSP); + } + + /* Get CLLR register mask and offset */ + DMA_List_GetCLLRNodeInfo(hdma->LinkedListQueue->Head, &cllr_mask, NULL); + + /* Update DMA registers for linked-list transfer */ + hdma->Instance->CLBAR = ((uint32_t)hdma->LinkedListQueue->Head & DMA_CLBAR_LBA); + hdma->Instance->CLLR = ((uint32_t)hdma->LinkedListQueue->Head & DMA_CLLR_LA) | cllr_mask; + } + + /* Enable DMA channel */ + __HAL_DMA_ENABLE(hdma); + } + else + { + /* Change the error code */ + hdma->ErrorCode = HAL_DMA_ERROR_BUSY; + + /* Process unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_ERROR; + } + + return HAL_OK; +} +/** + * @} + */ + +/** @addtogroup DMAEx_Exported_Functions_Group3 + * +@verbatim + ====================================================================================================================== + ############### Linked-List Management Functions ############### + ====================================================================================================================== + [..] + This section provides functions allowing to : + (+) Build linked-list node. + (+) Get linked-list node configuration. + (+) Insert node to linked-list queue in any queue position. + (+) Remove any node from linked-list queue. + (+) Replace any node from linked-list queue. + (+) Reset linked-list queue. + (+) Insert linked-list queue in any queue position. + (+) Set circular mode configuration to linked-list queue. + (+) Clear circular mode configuration from linked-list queue. + (+) Convert static linked-list queue to dynamic format. + (+) Convert dynamic linked-list queue to static format. + (+) Link linked-list queue to DMA channel. + (+) Unlink linked-list queue from DMA channel. + + [..] + (+) The HAL_DMAEx_List_BuildNode() function allows to build linked-list node. + Node type can be : + (++) 2 dimensions addressing node. + (++) Linear addressing node. + + (+) The HAL_DMAEx_List_GetNodeConfig() function allows to get the linked-list node configuration from built node. + + (+) The HAL_DMAEx_List_InsertNode() function allows to insert built linked-list node to static linked-list queue + according to selected position. + + (+) The HAL_DMAEx_List_InsertNode_Head() and HAL_DMAEx_List_InsertNode_Tail() functions allow to insert built + linked-list node to the head (respectively the tail) of static linked-list queue. + + (+) The HAL_DMAEx_List_RemoveNode() function allows to remove selected built linked-list node from static + linked-list queue. + + (+) The HAL_DMAEx_List_RemoveNode_Head() and HAL_DMAEx_List_RemoveNode_Tail() functions allow to remove the head + (respectively the tail) built linked-list node from static linked-list queue. + + (+) The HAL_DMAEx_List_ReplaceNode() function allows to replace selected built linked-list node from static + linked-list queue. + + (+) The HAL_DMAEx_List_ReplaceNode_Head() and HAL_DMAEx_List_ReplaceNode_Tail() functions allow to replace the + head (respectively the tail) built linked-list node of static linked-list queue. + + (+) The HAL_DMAEx_List_ResetQ() function allows to reset static linked-list queue and unlink all built linked-list + nodes. + + (+) The HAL_DMAEx_List_InsertQ() function allows to insert static linked-list source queue to static linked-list + destination queue according to selected position. + + (+) The HAL_DMAEx_List_InsertQ_Head() and HAL_DMAEx_List_InsertQ_Tail() functions allow to insert static + linked-list source queue to the head (respectively the tail) of static linked-list destination queue. + + (+) The HAL_DMAEx_List_SetCircularModeConfig() function allows to link the last static linked-list queue node to + the selected first circular node. + + (+) The HAL_DMAEx_List_SetCircularMode() function allows to link the last static linked-list queue node to the + first static linked-list queue node. + + (+) The HAL_DMAEx_List_ClearCircularMode() function allows to unlink the last static linked-list queue node from + any first circular node position. + + (+) The HAL_DMAEx_List_ConvertQToDynamic() function allows to convert the static linked-list queue to dynamic + format. (Optimized queue execution) + + (+) The HAL_DMAEx_List_ConvertQToStatic() function allows to convert the dynamic linked-list queue to static + format. (Not optimized queue execution) + + (+) The HAL_DMAEx_List_LinkQ() function allows to link the (Dynamic / Static) linked-list queue to DMA channel to + be executed. + + (+) The HAL_DMAEx_List_UnLinkQ() function allows to unlink the (Dynamic / Static) linked-list queue from DMA + channel when execution is completed. + +@endverbatim + * @{ + */ + +/** + * @brief Build a DMA channel node according to the specified parameters in the DMA_NodeConfTypeDef. + * @param pNodeConfig : Pointer to a DMA_NodeConfTypeDef structure that contains the configuration information for the + * specified DMA linked-list Node. + * @param pNode : Pointer to a DMA_NodeTypeDef structure that contains linked-list node registers + * configurations. + * @note The DMA linked-list node parameter address should be 32bit aligned and should not exceed the 64 KByte + * addressable space. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_List_BuildNode(DMA_NodeConfTypeDef const *const pNodeConfig, + DMA_NodeTypeDef *const pNode) +{ + /* Check the node configuration and physical node parameters */ + if ((pNodeConfig == NULL) || (pNode == NULL)) + { + return HAL_ERROR; + } + + /* Check node type parameter */ + assert_param(IS_DMA_NODE_TYPE(pNodeConfig->NodeType)); + + /* Check DMA channel basic transfer parameters */ + assert_param(IS_DMA_SOURCE_INC(pNodeConfig->Init.SrcInc)); + assert_param(IS_DMA_DESTINATION_INC(pNodeConfig->Init.DestInc)); + assert_param(IS_DMA_SOURCE_DATA_WIDTH(pNodeConfig->Init.SrcDataWidth)); + assert_param(IS_DMA_DESTINATION_DATA_WIDTH(pNodeConfig->Init.DestDataWidth)); + assert_param(IS_DMA_DATA_ALIGNMENT(pNodeConfig->DataHandlingConfig.DataAlignment)); + assert_param(IS_DMA_REQUEST(pNodeConfig->Init.Request)); + assert_param(IS_DMA_DIRECTION(pNodeConfig->Init.Direction)); + assert_param(IS_DMA_TCEM_EVENT_MODE(pNodeConfig->Init.TransferEventMode)); + assert_param(IS_DMA_BLOCK_HW_REQUEST(pNodeConfig->Init.BlkHWRequest)); + assert_param(IS_DMA_MODE(pNodeConfig->Init.Mode)); + + /* Check DMA channel parameters */ + if ((pNodeConfig->NodeType & DMA_CHANNEL_TYPE_GPDMA) == DMA_CHANNEL_TYPE_GPDMA) + { + assert_param(IS_DMA_BURST_LENGTH(pNodeConfig->Init.SrcBurstLength)); + assert_param(IS_DMA_BURST_LENGTH(pNodeConfig->Init.DestBurstLength)); + assert_param(IS_DMA_DATA_EXCHANGE(pNodeConfig->DataHandlingConfig.DataExchange)); + assert_param(IS_DMA_TRANSFER_ALLOCATED_PORT(pNodeConfig->Init.TransferAllocatedPort)); + } + + /* Check DMA channel trigger parameters */ + assert_param(IS_DMA_TRIGGER_POLARITY(pNodeConfig->TriggerConfig.TriggerPolarity)); + if (pNodeConfig->TriggerConfig.TriggerPolarity != DMA_TRIG_POLARITY_MASKED) + { + assert_param(IS_DMA_TRIGGER_MODE(pNodeConfig->TriggerConfig.TriggerMode)); + assert_param(IS_DMA_TRIGGER_SELECTION(pNodeConfig->TriggerConfig.TriggerSelection)); + } + + /* Check DMA channel repeated block parameters */ + if ((pNodeConfig->NodeType & DMA_CHANNEL_TYPE_2D_ADDR) == DMA_CHANNEL_TYPE_2D_ADDR) + { + assert_param(IS_DMA_REPEAT_COUNT(pNodeConfig->RepeatBlockConfig.RepeatCount)); + assert_param(IS_DMA_BURST_ADDR_OFFSET(pNodeConfig->RepeatBlockConfig.SrcAddrOffset)); + assert_param(IS_DMA_BURST_ADDR_OFFSET(pNodeConfig->RepeatBlockConfig.DestAddrOffset)); + assert_param(IS_DMA_BLOCK_ADDR_OFFSET(pNodeConfig->RepeatBlockConfig.BlkSrcAddrOffset)); + assert_param(IS_DMA_BLOCK_ADDR_OFFSET(pNodeConfig->RepeatBlockConfig.BlkDestAddrOffset)); + assert_param(IS_DMA_BURST_ADDR_OFFSET(pNodeConfig->RepeatBlockConfig.SrcAddrOffset)); + assert_param(IS_DMA_BURST_ADDR_OFFSET(pNodeConfig->RepeatBlockConfig.DestAddrOffset)); + assert_param(IS_DMA_BLOCK_ADDR_OFFSET(pNodeConfig->RepeatBlockConfig.BlkSrcAddrOffset)); + assert_param(IS_DMA_BLOCK_ADDR_OFFSET(pNodeConfig->RepeatBlockConfig.BlkDestAddrOffset)); + } + + /* Check DMA channel security and privilege attributes parameters */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + assert_param(IS_DMA_ATTRIBUTES(pNodeConfig->SrcSecure)); + assert_param(IS_DMA_ATTRIBUTES(pNodeConfig->DestSecure)); +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + /* Build the DMA channel node */ + DMA_List_BuildNode(pNodeConfig, pNode); + + return HAL_OK; +} + +/** + * @brief Get a DMA channel node configuration. + * @param pNodeConfig : Pointer to a DMA_NodeConfTypeDef structure that contains the configuration information for the + * specified DMA linked-list Node. + * @param pNode : Pointer to a DMA_NodeTypeDef structure that contains linked-list node registers + * configurations. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_List_GetNodeConfig(DMA_NodeConfTypeDef *const pNodeConfig, + DMA_NodeTypeDef const *const pNode) +{ + /* Check the node configuration and physical node parameters */ + if ((pNodeConfig == NULL) || (pNode == NULL)) + { + return HAL_ERROR; + } + + /* Get the DMA channel node configuration */ + DMA_List_GetNodeConfig(pNodeConfig, pNode); + + return HAL_OK; +} + +/** + * @brief Insert new node in any queue position of linked-list queue according to selecting previous node. + * @param pQList : Pointer to a DMA_QListTypeDef structure that contains queue information. + * @param pPrevNode : Pointer to a DMA_NodeTypeDef structure that contains linked-list previous node registers + * configurations. + * @param pNewNode : Pointer to a DMA_NodeTypeDef structure that contains linked-list new node registers + * configurations. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_List_InsertNode(DMA_QListTypeDef *const pQList, + DMA_NodeTypeDef *const pPrevNode, + DMA_NodeTypeDef *const pNewNode) +{ + uint32_t cllr_mask; + uint32_t cllr_offset; + DMA_NodeInQInfoTypeDef node_info; + + /* Check the queue and the new node parameters */ + if ((pQList == NULL) || (pNewNode == NULL)) + { + return HAL_ERROR; + } + + /* Check queue type */ + if (pQList->Type == QUEUE_TYPE_DYNAMIC) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + + /* Check nodes base addresses */ + if (DMA_List_CheckNodesBaseAddresses(pQList->Head, pPrevNode, pNewNode) != 0U) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_OUTOFRANGE; + + return HAL_ERROR; + } + + /* Check nodes types compatibility */ + if (DMA_List_CheckNodesTypes(pQList->Head, pPrevNode, pNewNode) != 0U) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_BUSY; + + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Get CLLR register mask and offset */ + DMA_List_GetCLLRNodeInfo(pNewNode, &cllr_mask, &cllr_offset); + + /* Empty queue */ + if (pQList->Head == NULL) + { + /* Add only new node to queue */ + if (pPrevNode == NULL) + { + pQList->Head = pNewNode; + pQList->NodeNumber = 1U; + } + /* Add previous node then new node to queue */ + else + { + pQList->Head = pPrevNode; + pPrevNode->LinkRegisters[cllr_offset] = ((uint32_t)pNewNode & DMA_CLLR_LA) | cllr_mask; + pQList->NodeNumber = 2U; + } + } + /* Not empty queue */ + else + { + /* Add new node at the head of queue */ + if (pPrevNode == NULL) + { + pNewNode->LinkRegisters[cllr_offset] = ((uint32_t)pQList->Head & DMA_CLLR_LA) | cllr_mask; + pQList->Head = pNewNode; + } + /* Add new node according to selected position */ + else + { + /* Find node and get its position in selected queue */ + node_info.cllr_offset = cllr_offset; + if (DMA_List_FindNode(pQList, pPrevNode, &node_info) == 0U) + { + /* Selected node is the last queue node */ + if (node_info.currentnode_pos == pQList->NodeNumber) + { + /* Check if queue is circular */ + if (pQList->FirstCircularNode != NULL) + { + pNewNode->LinkRegisters[cllr_offset] = ((uint32_t)pQList->FirstCircularNode & DMA_CLLR_LA) | cllr_mask; + } + + pPrevNode->LinkRegisters[cllr_offset] = ((uint32_t)pNewNode & DMA_CLLR_LA) | cllr_mask; + } + /* Selected node is not the last queue node */ + else + { + pNewNode->LinkRegisters[cllr_offset] = pPrevNode->LinkRegisters[cllr_offset]; + pPrevNode->LinkRegisters[cllr_offset] = ((uint32_t)pNewNode & DMA_CLLR_LA) | cllr_mask; + } + } + else + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NOTFOUND; + + return HAL_ERROR; + } + } + + /* Increment queue node number */ + pQList->NodeNumber++; + } + + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Insert new node at the head of linked-list queue. + * @param pQList : Pointer to a DMA_QListTypeDef structure that contains queue information. + * @param pNewNode : Pointer to a DMA_NodeTypeDef structure that contains linked-list new node registers + * configurations. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_List_InsertNode_Head(DMA_QListTypeDef *const pQList, + DMA_NodeTypeDef *const pNewNode) +{ + uint32_t cllr_mask; + uint32_t cllr_offset; + + /* Check the queue and the new node parameters */ + if ((pQList == NULL) || (pNewNode == NULL)) + { + return HAL_ERROR; + } + + /* Check queue type */ + if (pQList->Type == QUEUE_TYPE_DYNAMIC) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + + /* Check nodes base addresses */ + if (DMA_List_CheckNodesBaseAddresses(pQList->Head, pNewNode, NULL) != 0U) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_OUTOFRANGE; + + return HAL_ERROR; + } + + /* Check nodes types compatibility */ + if (DMA_List_CheckNodesTypes(pQList->Head, pNewNode, NULL) != 0U) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_BUSY; + + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Empty queue */ + if (pQList->Head == NULL) + { + pQList->Head = pNewNode; + } + /* Not empty queue */ + else + { + /* Get CLLR register mask and offset */ + DMA_List_GetCLLRNodeInfo(pNewNode, &cllr_mask, &cllr_offset); + + pNewNode->LinkRegisters[cllr_offset] = ((uint32_t)pQList->Head & DMA_CLLR_LA) | cllr_mask; + pQList->Head = pNewNode; + } + + /* Increment queue node number */ + pQList->NodeNumber++; + + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Insert new node at the tail of linked-list queue. + * @param pQList : Pointer to a DMA_QListTypeDef structure that contains queue information. + * @param pNewNode : Pointer to a DMA_NodeTypeDef structure that contains linked-list new node registers + * configurations. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_List_InsertNode_Tail(DMA_QListTypeDef *const pQList, + DMA_NodeTypeDef *const pNewNode) +{ + uint32_t cllr_mask; + uint32_t cllr_offset; + DMA_NodeInQInfoTypeDef node_info; + + /* Check the queue and the new node parameters */ + if ((pQList == NULL) || (pNewNode == NULL)) + { + return HAL_ERROR; + } + + /* Check queue type */ + if (pQList->Type == QUEUE_TYPE_DYNAMIC) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + + /* Check nodes base addresses */ + if (DMA_List_CheckNodesBaseAddresses(pQList->Head, pNewNode, NULL) != 0U) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_OUTOFRANGE; + + return HAL_ERROR; + } + + /* Check nodes types compatibility */ + if (DMA_List_CheckNodesTypes(pQList->Head, pNewNode, NULL) != 0U) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + + /* Empty queue */ + if (pQList->Head == NULL) + { + pQList->Head = pNewNode; + } + /* Not empty queue */ + else + { + /* Get CLLR register mask and offset */ + DMA_List_GetCLLRNodeInfo(pNewNode, &cllr_mask, &cllr_offset); + + /* Find node and get its position in selected queue */ + node_info.cllr_offset = cllr_offset; + (void)DMA_List_FindNode(pQList, NULL, &node_info); + + /* Check if queue is circular */ + if (pQList->FirstCircularNode != NULL) + { + pNewNode->LinkRegisters[cllr_offset] = ((uint32_t)pQList->FirstCircularNode & DMA_CLLR_LA) | cllr_mask; + } + + ((DMA_NodeTypeDef *)node_info.currentnode_addr)->LinkRegisters[cllr_offset] = + ((uint32_t)pNewNode & DMA_CLLR_LA) | cllr_mask; + } + + /* Increment queue node number */ + pQList->NodeNumber++; + + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_READY; + + /* Prevent MISRA-C2012-Rule-2.2_b */ + UNUSED(node_info); + + return HAL_OK; +} + +/** + * @brief Remove node from any linked-list queue position. + * @param pQList : Pointer to a DMA_QListTypeDef structure that contains queue information. + * @param pNode : Pointer to a DMA_NodeTypeDef structure that contains linked-list previous node registers + * configurations. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_List_RemoveNode(DMA_QListTypeDef *const pQList, + DMA_NodeTypeDef *const pNode) +{ + uint32_t previousnode_addr; + uint32_t cllr_offset; + DMA_NodeInQInfoTypeDef node_info; + + /* Check the queue and the node parameters */ + if ((pQList == NULL) || (pNode == NULL)) + { + return HAL_ERROR; + } + + /* Check the queue */ + if (pQList->Head == NULL) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_EMPTY; + + return HAL_ERROR; + } + + /* Check queue type */ + if (pQList->Type == QUEUE_TYPE_DYNAMIC) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_BUSY; + + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Get CLLR register mask and offset */ + DMA_List_GetCLLRNodeInfo(pNode, NULL, &cllr_offset); + + /* Find node and get its position in selected queue */ + node_info.cllr_offset = cllr_offset; + if (DMA_List_FindNode(pQList, pNode, &node_info) == 0U) + { + /* Removed node is the head node */ + if (node_info.currentnode_pos == 1U) + { + /* Check if first circular node queue is the first node */ + if (pQList->FirstCircularNode == ((DMA_NodeTypeDef *)node_info.currentnode_addr)) + { + /* Find last queue node */ + (void)DMA_List_FindNode(pQList, NULL, &node_info); + + /* Clear last node link */ + ((DMA_NodeTypeDef *)(node_info.currentnode_addr))->LinkRegisters[cllr_offset] = 0U; + + /* Clear first circular node */ + pQList->FirstCircularNode = NULL; + } + + /* Update the queue head node */ + pQList->Head = (DMA_NodeTypeDef *)(((uint32_t)pQList->Head & DMA_CLBAR_LBA) + + (pNode->LinkRegisters[cllr_offset] & DMA_CLLR_LA)); + /* Unlink node to be removed */ + pNode->LinkRegisters[cllr_offset] = 0U; + } + /* Removed node is the last node */ + else if (node_info.currentnode_pos == pQList->NodeNumber) + { + /* Clear CLLR for previous node */ + ((DMA_NodeTypeDef *)(node_info.previousnode_addr))->LinkRegisters[cllr_offset] = 0U; + + /* Clear CLLR for last node */ + ((DMA_NodeTypeDef *)(node_info.currentnode_addr))->LinkRegisters[cllr_offset] = 0U; + + /* Clear first circular node */ + pQList->FirstCircularNode = NULL; + } + /* Removed node is in the middle */ + else + { + /* Store previous node address to be updated later */ + previousnode_addr = node_info.previousnode_addr; + + /* Check if first circular node queue is the current node */ + if (pQList->FirstCircularNode == ((DMA_NodeTypeDef *)node_info.currentnode_addr)) + { + /* Find last queue node */ + (void)DMA_List_FindNode(pQList, NULL, &node_info); + + /* Clear last node link */ + ((DMA_NodeTypeDef *)(node_info.currentnode_addr))->LinkRegisters[cllr_offset] = 0U; + + /* Clear first circular node */ + pQList->FirstCircularNode = NULL; + } + + /* Link previous node */ + ((DMA_NodeTypeDef *)(previousnode_addr))->LinkRegisters[cllr_offset] = pNode->LinkRegisters[cllr_offset]; + + /* Unlink node to be removed */ + pNode->LinkRegisters[cllr_offset] = 0U; + } + + /* Decrement node number */ + pQList->NodeNumber--; + } + else + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NOTFOUND; + + return HAL_ERROR; + } + + /* Check if queue is empty */ + if (pQList->NodeNumber == 0U) + { + /* Clean empty queue parameter */ + DMA_List_CleanQueue(pQList); + } + else + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_READY; + } + + /* Prevent MISRA-C2012-Rule-2.2_b */ + UNUSED(node_info); + + return HAL_OK; +} + +/** + * @brief Remove the head node from linked-list queue. + * @param pQList : Pointer to a DMA_QListTypeDef structure that contains queue information. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_List_RemoveNode_Head(DMA_QListTypeDef *const pQList) +{ + uint32_t cllr_offset; + uint32_t current_addr; + DMA_NodeInQInfoTypeDef node_info; + + /* Check the queue parameter */ + if (pQList == NULL) + { + return HAL_ERROR; + } + + /* Check the queue */ + if (pQList->Head == NULL) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_EMPTY; + + return HAL_ERROR; + } + + /* Check queue type */ + if (pQList->Type == QUEUE_TYPE_DYNAMIC) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_BUSY; + + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Get CLLR register mask and offset */ + DMA_List_GetCLLRNodeInfo(pQList->Head, NULL, &cllr_offset); + + /* Queue contains only one node */ + if (pQList->NodeNumber == 1U) + { + pQList->Head->LinkRegisters[cllr_offset] = 0U; + pQList->FirstCircularNode = 0U; + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + } + /* Queue contains more then one node */ + else + { + /* Check if first circular node queue is the first node */ + if (pQList->FirstCircularNode == pQList->Head) + { + /* Find last queue node */ + node_info.cllr_offset = cllr_offset; + (void)DMA_List_FindNode(pQList, NULL, &node_info); + + /* Clear last node link */ + ((DMA_NodeTypeDef *)(node_info.currentnode_addr))->LinkRegisters[cllr_offset] = 0U; + + /* Clear first circular node */ + pQList->FirstCircularNode = NULL; + } + + current_addr = pQList->Head->LinkRegisters[cllr_offset] & DMA_CLLR_LA; + pQList->Head->LinkRegisters[cllr_offset] = 0U; + pQList->Head = ((DMA_NodeTypeDef *)(current_addr + ((uint32_t)pQList->Head & DMA_CLBAR_LBA))); + } + + /* Decrement node number */ + pQList->NodeNumber--; + + /* Check if queue is empty */ + if (pQList->NodeNumber == 0U) + { + /* Clean empty queue parameter */ + DMA_List_CleanQueue(pQList); + } + else + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_READY; + } + + /* Prevent MISRA-C2012-Rule-2.2_b */ + UNUSED(node_info); + + return HAL_OK; +} + +/** + * @brief Remove the tail node from linked-list queue. + * @param pQList : Pointer to a DMA_QListTypeDef structure that contains queue information. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_List_RemoveNode_Tail(DMA_QListTypeDef *const pQList) +{ + uint32_t cllr_offset; + DMA_NodeInQInfoTypeDef node_info; + + /* Check the queue parameter */ + if (pQList == NULL) + { + return HAL_ERROR; + } + + /* Check the queue */ + if (pQList->Head == NULL) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_EMPTY; + + return HAL_ERROR; + } + + /* Check queue type */ + if (pQList->Type == QUEUE_TYPE_DYNAMIC) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_BUSY; + + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Get CLLR register mask and offset */ + DMA_List_GetCLLRNodeInfo(pQList->Head, NULL, &cllr_offset); + + /* Queue contains only one node */ + if (pQList->NodeNumber == 1U) + { + pQList->Head->LinkRegisters[cllr_offset] = 0U; + pQList->FirstCircularNode = 0U; + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + } + /* Queue contains more then one node */ + else + { + /* Find node and get its position in selected queue */ + node_info.cllr_offset = cllr_offset; + (void)DMA_List_FindNode(pQList, NULL, &node_info); + + /* Clear CLLR for previous node */ + ((DMA_NodeTypeDef *)(node_info.previousnode_addr))->LinkRegisters[cllr_offset] = 0U; + + /* Clear CLLR for last node */ + ((DMA_NodeTypeDef *)(node_info.currentnode_addr))->LinkRegisters[cllr_offset] = 0U; + + /* Clear first circular node */ + pQList->FirstCircularNode = NULL; + } + + /* Decrement node number */ + pQList->NodeNumber--; + + /* Check if queue is empty */ + if (pQList->NodeNumber == 0U) + { + /* Clean empty queue parameter */ + DMA_List_CleanQueue(pQList); + } + else + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_READY; + } + + /* Prevent MISRA-C2012-Rule-2.2_b */ + UNUSED(node_info); + + return HAL_OK; +} + +/** + * @brief Replace node in linked-list queue. + * @param pQList : Pointer to a DMA_QListTypeDef structure that contains queue information. + * @param pOldNode : Pointer to a DMA_NodeTypeDef structure that contains linked-list old node registers + * configurations. + * @param pNewNode : Pointer to a DMA_NodeTypeDef structure that contains linked-list new node registers + * configurations. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_List_ReplaceNode(DMA_QListTypeDef *const pQList, + DMA_NodeTypeDef *const pOldNode, + DMA_NodeTypeDef *const pNewNode) +{ + uint32_t cllr_mask; + uint32_t cllr_offset; + DMA_NodeInQInfoTypeDef node_info; + + /* Check the queue and the nodes parameters */ + if ((pQList == NULL) || (pOldNode == NULL) || (pNewNode == NULL)) + { + return HAL_ERROR; + } + + /* Check the queue */ + if (pQList->Head == NULL) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_EMPTY; + + return HAL_ERROR; + } + + /* Check queue type */ + if (pQList->Type == QUEUE_TYPE_DYNAMIC) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + + /* Check nodes base addresses */ + if (DMA_List_CheckNodesBaseAddresses(pQList->Head, pOldNode, pNewNode) != 0U) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_OUTOFRANGE; + + return HAL_ERROR; + } + + /* Check nodes types compatibility */ + if (DMA_List_CheckNodesTypes(pQList->Head, pOldNode, pNewNode) != 0U) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_BUSY; + + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Get CLLR register mask and offset */ + DMA_List_GetCLLRNodeInfo(pNewNode, &cllr_mask, &cllr_offset); + + /* Find node and get its position in selected queue */ + node_info.cllr_offset = cllr_offset; + if (DMA_List_FindNode(pQList, pOldNode, &node_info) == 0U) + { + /* Replaced node is the head node */ + if (node_info.currentnode_pos == 1U) + { + pNewNode->LinkRegisters[cllr_offset] = + ((DMA_NodeTypeDef *)(node_info.currentnode_addr))->LinkRegisters[cllr_offset]; + pQList->Head = pNewNode; + ((DMA_NodeTypeDef *)(node_info.currentnode_addr))->LinkRegisters[cllr_offset] = 0U; + + /* Check if first circular node queue is the first node */ + if (pQList->FirstCircularNode == ((DMA_NodeTypeDef *)node_info.currentnode_addr)) + { + /* Find last queue node */ + (void)DMA_List_FindNode(pQList, NULL, &node_info); + + /* Clear last node link */ + ((DMA_NodeTypeDef *)(node_info.currentnode_addr))->LinkRegisters[cllr_offset] = + ((uint32_t)pNewNode & DMA_CLLR_LA) | cllr_mask; + + /* Set new node as first circular node */ + pQList->FirstCircularNode = pNewNode; + } + } + /* Replaced node is the last */ + else if (node_info.currentnode_pos == pQList->NodeNumber) + { + ((DMA_NodeTypeDef *)(node_info.previousnode_addr))->LinkRegisters[cllr_offset] = + ((uint32_t)pNewNode & DMA_CLLR_LA) | cllr_mask; + ((DMA_NodeTypeDef *)(node_info.currentnode_addr))->LinkRegisters[cllr_offset] = 0U; + + /* Check if first circular node queue is the last node */ + if (pQList->FirstCircularNode == ((DMA_NodeTypeDef *)(node_info.currentnode_addr))) + { + /* Link first circular node to new node */ + pNewNode->LinkRegisters[cllr_offset] = ((uint32_t)pNewNode & DMA_CLLR_LA) | cllr_mask; + + /* Set new node as first circular node */ + pQList->FirstCircularNode = pNewNode; + } + /* Check if first circular node queue is not the last node */ + else if (pQList->FirstCircularNode != NULL) + { + /* Link first circular node to new node */ + pNewNode->LinkRegisters[cllr_offset] = ((uint32_t)pQList->FirstCircularNode & DMA_CLLR_LA) | cllr_mask; + } + else + { + /* Prevent MISRA-C2012-Rule-15.7 */ + } + } + /* Replaced node is in the middle */ + else + { + ((DMA_NodeTypeDef *)(node_info.previousnode_addr))->LinkRegisters[cllr_offset] = + ((uint32_t)pNewNode & DMA_CLLR_LA) | cllr_mask; + pNewNode->LinkRegisters[cllr_offset] = + ((DMA_NodeTypeDef *)(node_info.currentnode_addr))->LinkRegisters[cllr_offset]; + ((DMA_NodeTypeDef *)(node_info.currentnode_addr))->LinkRegisters[cllr_offset] = 0U; + + /* Check if first circular node queue is the current node */ + if (pQList->FirstCircularNode == ((DMA_NodeTypeDef *)(node_info.currentnode_addr))) + { + /* Find last node and get its position in selected queue */ + (void)DMA_List_FindNode(pQList, NULL, &node_info); + + /* Link last queue node to new node */ + ((DMA_NodeTypeDef *)(node_info.currentnode_addr))->LinkRegisters[cllr_offset] = + ((uint32_t)pNewNode & DMA_CLLR_LA) | cllr_mask; + + /* Set new node as first circular node */ + pQList->FirstCircularNode = pNewNode; + } + } + } + else + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NOTFOUND; + + return HAL_ERROR; + } + + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_READY; + + /* Prevent MISRA-C2012-Rule-2.2_b */ + UNUSED(node_info); + + return HAL_OK; +} + +/** + * @brief Replace the head node of linked-list queue. + * @param pQList : Pointer to a DMA_QListTypeDef structure that contains queue information. + * @param pNewNode : Pointer to a DMA_NodeTypeDef structure that contains linked-list new node registers + * configurations. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_List_ReplaceNode_Head(DMA_QListTypeDef *const pQList, + DMA_NodeTypeDef *const pNewNode) +{ + uint32_t cllr_offset; + uint32_t cllr_mask; + DMA_NodeInQInfoTypeDef node_info; + + /* Check the queue and the new node parameters */ + if ((pQList == NULL) || (pNewNode == NULL)) + { + return HAL_ERROR; + } + + /* Check the queue */ + if (pQList->Head == NULL) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_EMPTY; + + return HAL_ERROR; + } + + /* Check queue type */ + if (pQList->Type == QUEUE_TYPE_DYNAMIC) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + + /* Check nodes base addresses */ + if (DMA_List_CheckNodesBaseAddresses(pQList->Head, pNewNode, NULL) != 0U) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_OUTOFRANGE; + + return HAL_ERROR; + } + + /* Check nodes types compatibility */ + if (DMA_List_CheckNodesTypes(pQList->Head, pNewNode, NULL) != 0U) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_BUSY; + + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Get CLLR register mask and offset */ + DMA_List_GetCLLRNodeInfo(pNewNode, &cllr_mask, &cllr_offset); + + /* Check if first circular node queue is the first node */ + if (pQList->FirstCircularNode == pQList->Head) + { + /* Find last queue node */ + node_info.cllr_offset = cllr_offset; + (void)DMA_List_FindNode(pQList, NULL, &node_info); + + /* Clear last node link */ + ((DMA_NodeTypeDef *)(node_info.currentnode_addr))->LinkRegisters[cllr_offset] = + ((uint32_t)pNewNode & DMA_CLLR_LA) | cllr_mask; + + /* Set new node as first circular node */ + pQList->FirstCircularNode = pNewNode; + } + + /* Replace head node */ + pNewNode->LinkRegisters[cllr_offset] = pQList->Head->LinkRegisters[cllr_offset]; + pQList->Head->LinkRegisters[cllr_offset] = 0U; + pQList->Head = pNewNode; + + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_READY; + + /* Prevent MISRA-C2012-Rule-2.2_b */ + UNUSED(node_info); + + return HAL_OK; +} + +/** + * @brief Replace the tail node of linked-list queue. + * @param pQList : Pointer to a DMA_QListTypeDef structure that contains queue information. + * @param pNewNode : Pointer to a DMA_NodeTypeDef structure that contains linked-list new node registers + * configurations. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_List_ReplaceNode_Tail(DMA_QListTypeDef *const pQList, + DMA_NodeTypeDef *const pNewNode) +{ + uint32_t cllr_mask; + uint32_t cllr_offset; + DMA_NodeInQInfoTypeDef node_info; + + /* Check the queue and the new node parameters */ + if ((pQList == NULL) || (pNewNode == NULL)) + { + return HAL_ERROR; + } + + /* Check the queue */ + if (pQList->Head == NULL) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_EMPTY; + + return HAL_ERROR; + } + + /* Check queue type */ + if (pQList->Type == QUEUE_TYPE_DYNAMIC) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_BUSY; + + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Get CLLR register mask and offset */ + DMA_List_GetCLLRNodeInfo(pNewNode, &cllr_mask, &cllr_offset); + + /* Find last node and get its position in selected queue */ + node_info.cllr_offset = cllr_offset; + (void)DMA_List_FindNode(pQList, NULL, &node_info); + + /* Link previous node to new node */ + ((DMA_NodeTypeDef *)(node_info.previousnode_addr))->LinkRegisters[cllr_offset] = + ((uint32_t)pNewNode & DMA_CLLR_LA) | cllr_mask; + + /* Clear CLLR for current node */ + ((DMA_NodeTypeDef *)(node_info.currentnode_addr))->LinkRegisters[cllr_offset] = 0U; + + /* Check if first circular node queue is the last node */ + if (pQList->FirstCircularNode == ((DMA_NodeTypeDef *)(node_info.currentnode_addr))) + { + /* Link first circular node to new node */ + pNewNode->LinkRegisters[cllr_offset] = ((uint32_t)pNewNode & DMA_CLLR_LA) | cllr_mask; + + /* Set new node as first circular node */ + pQList->FirstCircularNode = pNewNode; + } + /* Check if first circular node queue is not the last node */ + else if (pQList->FirstCircularNode != NULL) + { + /* Link first circular node to new node */ + pNewNode->LinkRegisters[cllr_offset] = ((uint32_t)pQList->FirstCircularNode & DMA_CLLR_LA) | cllr_mask; + } + else + { + /* Prevent MISRA-C2012-Rule-15.7 */ + } + + /* Check if queue contains one node */ + if (pQList->NodeNumber == 1U) + { + pQList->Head = pNewNode; + } + + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Reset the linked-list queue and unlink queue nodes. + * @param pQList : Pointer to a DMA_QListTypeDef structure that contains queue information. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_List_ResetQ(DMA_QListTypeDef *const pQList) +{ + uint32_t cllr_offset; + DMA_NodeInQInfoTypeDef node_info; + + /* Check the queue parameter */ + if (pQList == NULL) + { + return HAL_ERROR; + } + + /* Check queue state */ + if (pQList->State == HAL_DMA_QUEUE_STATE_BUSY) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_BUSY; + + return HAL_ERROR; + } + + /* Check queue type */ + if (pQList->Type == QUEUE_TYPE_DYNAMIC) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_BUSY; + + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Check the queue */ + if (pQList->Head != NULL) + { + /* Get CLLR register mask and offset */ + DMA_List_GetCLLRNodeInfo(pQList->Head, NULL, &cllr_offset); + + /* Reset selected queue nodes */ + node_info.cllr_offset = cllr_offset; + DMA_List_ResetQueueNodes(pQList, &node_info); + } + + /* Reset head node address */ + pQList->Head = NULL; + + /* Reset node number */ + pQList->NodeNumber = 0U; + + /* Reset first circular node */ + pQList->FirstCircularNode = NULL; + + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_RESET; + + return HAL_OK; +} + +/** + * @brief Insert a source linked-list queue to a destination linked-list queue according to selecting previous node. + * @param pSrcQList : Pointer to a DMA_QListTypeDef structure that contains source queue information. + * @param pPrevNode : Pointer to a DMA_NodeTypeDef structure that contains linked-list previous node registers + * configurations. + * @param pDestQList : Pointer to a DMA_QListTypeDef structure that contains destination queue information. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_List_InsertQ(DMA_QListTypeDef *const pSrcQList, + DMA_NodeTypeDef const *const pPrevNode, + DMA_QListTypeDef *const pDestQList) +{ + uint32_t cllr_mask; + uint32_t cllr_offset; + DMA_NodeInQInfoTypeDef src_q_node_info; + DMA_NodeInQInfoTypeDef dest_q_node_info; + + /* Check the source and destination queues and the previous node parameters */ + if ((pSrcQList == NULL) || (pDestQList == NULL)) + { + return HAL_ERROR; + } + + /* Check the source queue */ + if (pSrcQList->Head == NULL) + { + /* Update the queue error code */ + pSrcQList->ErrorCode = HAL_DMA_QUEUE_ERROR_EMPTY; + + return HAL_ERROR; + } + + /* Check the source queue type */ + if (pSrcQList->Type == QUEUE_TYPE_DYNAMIC) + { + /* Update the queue error code */ + pSrcQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + + /* Check the destination queue type */ + if (pDestQList->Type == QUEUE_TYPE_DYNAMIC) + { + /* Update the queue error code */ + pDestQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + + /* Check the source queue circularity */ + if (pSrcQList->FirstCircularNode != NULL) + { + /* Update the source queue error code */ + pSrcQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + + /* Check nodes base addresses */ + if (DMA_List_CheckNodesBaseAddresses(pSrcQList->Head, pPrevNode, pDestQList->Head) != 0U) + { + /* Update the source queue error code */ + pSrcQList->ErrorCode = HAL_DMA_QUEUE_ERROR_OUTOFRANGE; + + /* Update the destination queue error code */ + pDestQList->ErrorCode = HAL_DMA_QUEUE_ERROR_OUTOFRANGE; + + return HAL_ERROR; + } + + /* Check nodes types compatibility */ + if (DMA_List_CheckNodesTypes(pSrcQList->Head, pPrevNode, pDestQList->Head) != 0U) + { + /* Update the source queue error code */ + pSrcQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + /* Update the destination queue error code */ + pDestQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + + /* Update the source queue state */ + pSrcQList->State = HAL_DMA_QUEUE_STATE_BUSY; + + /* Update the source queue error code */ + pSrcQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Update the destination queue state */ + pDestQList->State = HAL_DMA_QUEUE_STATE_BUSY; + + /* Update the destination queue error code */ + pDestQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Get CLLR register mask and offset */ + DMA_List_GetCLLRNodeInfo(pSrcQList->Head, &cllr_mask, &cllr_offset); + + /* Empty destination queue */ + if (pDestQList->Head == NULL) + { + pDestQList->Head = pSrcQList->Head; + pDestQList->NodeNumber = pSrcQList->NodeNumber; + } + /* Not empty destination queue */ + else + { + /* Previous node is empty */ + if (pPrevNode == NULL) + { + /* Find node and get its position in selected queue */ + src_q_node_info.cllr_offset = cllr_offset; + (void)DMA_List_FindNode(pSrcQList, NULL, &src_q_node_info); + + /* Check if first circular node queue is the first node */ + if (pDestQList->FirstCircularNode == pDestQList->Head) + { + /* Find node and get its position in selected queue */ + dest_q_node_info.cllr_offset = cllr_offset; + (void)DMA_List_FindNode(pDestQList, NULL, &dest_q_node_info); + + /* Link destination queue tail node to new first circular node */ + ((DMA_NodeTypeDef *)dest_q_node_info.currentnode_addr)->LinkRegisters[cllr_offset] = + ((uint32_t)pSrcQList->Head & DMA_CLLR_LA) | cllr_mask; + + /* Set the head node of source queue as the first circular node */ + pDestQList->FirstCircularNode = pSrcQList->Head; + } + + /* Link the last node of source queue to the fist node of destination queue */ + ((DMA_NodeTypeDef *)(src_q_node_info.currentnode_addr))->LinkRegisters[cllr_offset] = + ((uint32_t)pDestQList->Head & DMA_CLLR_LA) | cllr_mask; + pDestQList->Head = pSrcQList->Head; + pDestQList->NodeNumber += pSrcQList->NodeNumber; + } + /* Previous node is not empty */ + else + { + /* Find node and get its position in selected queue */ + dest_q_node_info.cllr_offset = cllr_offset; + if (DMA_List_FindNode(pDestQList, pPrevNode, &dest_q_node_info) == 0U) + { + /* Selected node is the last destination queue node */ + if (dest_q_node_info.currentnode_pos == pDestQList->NodeNumber) + { + /* Link the first node of source queue to the last node of destination queue */ + ((DMA_NodeTypeDef *)(dest_q_node_info.currentnode_addr))->LinkRegisters[cllr_offset] = + ((uint32_t)pSrcQList->Head & DMA_CLLR_LA) | cllr_mask; + pDestQList->NodeNumber += pSrcQList->NodeNumber; + + /* Check if first circular node queue is not empty */ + if (pDestQList->FirstCircularNode != NULL) + { + /* Find node and get its position in selected queue */ + src_q_node_info.cllr_offset = cllr_offset; + (void)DMA_List_FindNode(pSrcQList, NULL, &src_q_node_info); + + /* Find first circular node */ + (void)DMA_List_FindNode(pDestQList, pDestQList->FirstCircularNode, &dest_q_node_info); + + /* Link last source queue node to first destination queue */ + ((DMA_NodeTypeDef *)src_q_node_info.currentnode_addr)->LinkRegisters[cllr_offset] = + (dest_q_node_info.currentnode_addr & DMA_CLLR_LA) | cllr_mask; + } + } + /* Selected node is not the last destination queue node */ + else + { + /* Link the first node of source queue to the previous node of destination queue */ + ((DMA_NodeTypeDef *)(dest_q_node_info.currentnode_addr))->LinkRegisters[cllr_offset] = + ((uint32_t)pSrcQList->Head & DMA_CLLR_LA) | cllr_mask; + + /* Find node and get its position in selected queue */ + src_q_node_info.cllr_offset = cllr_offset; + (void)DMA_List_FindNode(pSrcQList, NULL, &src_q_node_info); + + /* Link the last node of source queue to the next node of destination queue */ + ((DMA_NodeTypeDef *)(src_q_node_info.currentnode_addr))->LinkRegisters[cllr_offset] = + (dest_q_node_info.nextnode_addr & DMA_CLLR_LA) | cllr_mask; + + /* Update queues counter */ + pDestQList->NodeNumber += pSrcQList->NodeNumber; + } + } + else + { + /* Update the destination queue error code */ + pDestQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NOTFOUND; + + return HAL_ERROR; + } + } + } + + /* Clean the source queue variable as it is obsolete */ + DMA_List_CleanQueue(pSrcQList); + + /* Update the destination queue error code */ + pDestQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Update the destination queue state */ + pDestQList->State = HAL_DMA_QUEUE_STATE_READY; + + /* Prevent MISRA-C2012-Rule-2.2_b */ + UNUSED(src_q_node_info); + UNUSED(dest_q_node_info); + + return HAL_OK; +} + +/** + * @brief Insert a source linked-list queue at the head of destination queue. + * @param pSrcQList : Pointer to a DMA_QListTypeDef structure that contains source queue information. + * @param pDestQList : Pointer to a DMA_QListTypeDef structure that contains destination queue information. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_List_InsertQ_Head(DMA_QListTypeDef *const pSrcQList, + DMA_QListTypeDef *const pDestQList) +{ + uint32_t cllr_mask; + uint32_t cllr_offset; + DMA_NodeInQInfoTypeDef src_q_node_info; + DMA_NodeInQInfoTypeDef dest_q_node_info; + + /* Check the source and destination queues and the previous node parameters */ + if ((pSrcQList == NULL) || (pDestQList == NULL)) + { + return HAL_ERROR; + } + + /* Check the source queue */ + if (pSrcQList->Head == NULL) + { + /* Update the queue error code */ + pSrcQList->ErrorCode = HAL_DMA_QUEUE_ERROR_EMPTY; + + return HAL_ERROR; + } + + /* Check the source queue type */ + if (pSrcQList->Type == QUEUE_TYPE_DYNAMIC) + { + /* Update the queue error code */ + pSrcQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + + /* Check the destination queue type */ + if (pDestQList->Type == QUEUE_TYPE_DYNAMIC) + { + /* Update the queue error code */ + pDestQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + + /* Check nodes base addresses */ + if (DMA_List_CheckNodesBaseAddresses(pSrcQList->Head, pDestQList->Head, NULL) != 0U) + { + /* Update the source queue error code */ + pSrcQList->ErrorCode = HAL_DMA_QUEUE_ERROR_OUTOFRANGE; + + /* Update the destination queue error code */ + pDestQList->ErrorCode = HAL_DMA_QUEUE_ERROR_OUTOFRANGE; + + return HAL_ERROR; + } + + /* Check nodes types compatibility */ + if (DMA_List_CheckNodesTypes(pSrcQList->Head, pDestQList->Head, NULL) != 0U) + { + /* Update the source queue error code */ + pSrcQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + /* Update the destination queue error code */ + pDestQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + + /* Update the source queue state */ + pSrcQList->State = HAL_DMA_QUEUE_STATE_BUSY; + + /* Update the source queue error code */ + pSrcQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Update the destination queue state */ + pDestQList->State = HAL_DMA_QUEUE_STATE_BUSY; + + /* Update the destination queue error code */ + pDestQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Get CLLR register mask and offset */ + DMA_List_GetCLLRNodeInfo(pSrcQList->Head, &cllr_mask, &cllr_offset); + + /* Empty destination queue */ + if (pDestQList->Head == NULL) + { + pDestQList->Head = pSrcQList->Head; + pDestQList->NodeNumber = pSrcQList->NodeNumber; + } + /* Not empty destination queue */ + else + { + /* Find node and get its position in selected queue */ + src_q_node_info.cllr_offset = cllr_offset; + (void)DMA_List_FindNode(pSrcQList, NULL, &src_q_node_info); + + /* Check if first circular node queue is the first node */ + if (pDestQList->FirstCircularNode == pDestQList->Head) + { + /* Find node and get its position in selected queue */ + dest_q_node_info.cllr_offset = cllr_offset; + (void)DMA_List_FindNode(pDestQList, NULL, &dest_q_node_info); + + /* Link destination queue tail node to new first circular node */ + ((DMA_NodeTypeDef *)dest_q_node_info.currentnode_addr)->LinkRegisters[cllr_offset] = + ((uint32_t)pSrcQList->Head & DMA_CLLR_LA) | cllr_mask; + + /* Set the head node of source queue as the first circular node */ + pDestQList->FirstCircularNode = pSrcQList->Head; + } + + /* Link the last node of source queue to the fist node of destination queue */ + ((DMA_NodeTypeDef *)(src_q_node_info.currentnode_addr))->LinkRegisters[cllr_offset] = + ((uint32_t)pDestQList->Head & DMA_CLLR_LA) | cllr_mask; + pDestQList->Head = pSrcQList->Head; + pDestQList->NodeNumber += pSrcQList->NodeNumber; + } + + /* Clean the source queue variable as it is obsolete */ + DMA_List_CleanQueue(pSrcQList); + + /* Update the destination queue error code */ + pDestQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Update the destination queue state */ + pDestQList->State = HAL_DMA_QUEUE_STATE_READY; + + /* Prevent MISRA-C2012-Rule-2.2_b */ + UNUSED(src_q_node_info); + UNUSED(dest_q_node_info); + + return HAL_OK; +} + +/** + * @brief Insert a source linked-list queue at the tail of destination queue. + * @param pSrcQList : Pointer to a DMA_QListTypeDef structure that contains source queue information. + * @param pDestQList : Pointer to a DMA_QListTypeDef structure that contains destination queue information. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_List_InsertQ_Tail(DMA_QListTypeDef *const pSrcQList, + DMA_QListTypeDef *const pDestQList) +{ + uint32_t cllr_mask; + uint32_t cllr_offset; + DMA_NodeInQInfoTypeDef src_q_node_info; + DMA_NodeInQInfoTypeDef dest_q_node_info; + + /* Check the source and destination queues and the previous node parameters */ + if ((pSrcQList == NULL) || (pDestQList == NULL)) + { + return HAL_ERROR; + } + + /* Check the source queue */ + if (pSrcQList->Head == NULL) + { + /* Update the queue error code */ + pSrcQList->ErrorCode = HAL_DMA_QUEUE_ERROR_EMPTY; + + return HAL_ERROR; + } + + /* Check the source queue type */ + if (pSrcQList->Type == QUEUE_TYPE_DYNAMIC) + { + /* Update the queue error code */ + pSrcQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + + /* Check the destination queue type */ + if (pDestQList->Type == QUEUE_TYPE_DYNAMIC) + { + /* Update the queue error code */ + pDestQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + + /* Check nodes base addresses */ + if (DMA_List_CheckNodesBaseAddresses(pSrcQList->Head, pDestQList->Head, NULL) != 0U) + { + /* Update the source queue error code */ + pSrcQList->ErrorCode = HAL_DMA_QUEUE_ERROR_OUTOFRANGE; + + /* Update the destination queue error code */ + pDestQList->ErrorCode = HAL_DMA_QUEUE_ERROR_OUTOFRANGE; + + return HAL_ERROR; + } + + /* Check nodes types compatibility */ + if (DMA_List_CheckNodesTypes(pSrcQList->Head, pDestQList->Head, NULL) != 0U) + { + /* Update the source queue error code */ + pSrcQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + /* Update the destination queue error code */ + pDestQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + + /* Update the source queue state */ + pSrcQList->State = HAL_DMA_QUEUE_STATE_BUSY; + + /* Update the source queue error code */ + pSrcQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Update the destination queue state */ + pDestQList->State = HAL_DMA_QUEUE_STATE_BUSY; + + /* Update the destination queue error code */ + pDestQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Get CLLR register mask and offset */ + DMA_List_GetCLLRNodeInfo(pSrcQList->Head, &cllr_mask, &cllr_offset); + + /* Empty destination queue */ + if (pDestQList->Head == NULL) + { + pDestQList->Head = pSrcQList->Head; + pDestQList->NodeNumber = pSrcQList->NodeNumber; + } + /* Not empty destination queue */ + else + { + /* Find node and get its position in selected queue */ + dest_q_node_info.cllr_offset = cllr_offset; + (void)DMA_List_FindNode(pDestQList, NULL, &dest_q_node_info); + + /* Update source queue last node CLLR to link it with destination first node */ + ((DMA_NodeTypeDef *)(dest_q_node_info.currentnode_addr))->LinkRegisters[cllr_offset] = + ((uint32_t)pSrcQList->Head & DMA_CLLR_LA) | cllr_mask; + pDestQList->NodeNumber += pSrcQList->NodeNumber; + + /* Check if first circular node queue is not empty */ + if (pDestQList->FirstCircularNode != NULL) + { + /* Find node and get its position in selected queue */ + src_q_node_info.cllr_offset = cllr_offset; + (void)DMA_List_FindNode(pSrcQList, NULL, &src_q_node_info); + + /* Find first circular node */ + (void)DMA_List_FindNode(pDestQList, pDestQList->FirstCircularNode, &dest_q_node_info); + + /* Link last source queue node to first destination queue */ + ((DMA_NodeTypeDef *)src_q_node_info.currentnode_addr)->LinkRegisters[cllr_offset] = + (dest_q_node_info.currentnode_addr & DMA_CLLR_LA) | cllr_mask; + } + } + + /* Clean the source queue variable as it is obsolete */ + DMA_List_CleanQueue(pSrcQList); + + /* Update the destination queue error code */ + pDestQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Update the destination queue state */ + pDestQList->State = HAL_DMA_QUEUE_STATE_READY; + + /* Prevent MISRA-C2012-Rule-2.2_b */ + UNUSED(src_q_node_info); + + return HAL_OK; +} + +/** + * @brief Set circular mode configuration for linked-list queue. + * @param pQList : Pointer to a DMA_QListTypeDef structure that contains queue information. + * @param pFirstCircularNode : Pointer to a DMA_NodeTypeDef structure that contains linked-list first circular node + * registers configurations. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_List_SetCircularModeConfig(DMA_QListTypeDef *const pQList, + DMA_NodeTypeDef *const pFirstCircularNode) +{ + uint32_t cllr_mask; + uint32_t cllr_offset; + DMA_NodeInQInfoTypeDef node_info; + + /* Check the queue and the first circular node parameters */ + if ((pQList == NULL) || (pFirstCircularNode == NULL)) + { + return HAL_ERROR; + } + + /* Check the queue */ + if (pQList->Head == NULL) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_EMPTY; + + return HAL_ERROR; + } + + /* Check queue circular mode */ + if (pQList->FirstCircularNode != NULL) + { + if (pQList->FirstCircularNode == pFirstCircularNode) + { + return HAL_OK; + } + else + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + } + + /* Check queue type */ + if (pQList->Type == QUEUE_TYPE_DYNAMIC) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_BUSY; + + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Get CLLR register mask and offset */ + DMA_List_GetCLLRNodeInfo(pFirstCircularNode, &cllr_mask, &cllr_offset); + + /* Find the first circular node and get its position in selected queue */ + node_info.cllr_offset = cllr_offset; + if (DMA_List_FindNode(pQList, pFirstCircularNode, &node_info) == 0U) + { + /* Find the last queue node and get its position in selected queue */ + (void)DMA_List_FindNode(pQList, NULL, &node_info); + + /* Set circular mode */ + ((DMA_NodeTypeDef *)(node_info.currentnode_addr))->LinkRegisters[cllr_offset] = + ((uint32_t)pFirstCircularNode & DMA_CLLR_LA) | cllr_mask; + + /* Update first circular node in queue */ + pQList->FirstCircularNode = pFirstCircularNode; + } + else + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NOTFOUND; + + return HAL_ERROR; + } + + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_READY; + + /* Prevent MISRA-C2012-Rule-2.2_b */ + UNUSED(node_info); + + return HAL_OK; +} + +/** + * @brief Set circular mode for linked-list queue. + * @param pQList : Pointer to a DMA_QListTypeDef structure that contains queue information. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_List_SetCircularMode(DMA_QListTypeDef *const pQList) +{ + uint32_t cllr_mask; + uint32_t cllr_offset; + DMA_NodeInQInfoTypeDef node_info; + + /* Check the queue parameter */ + if (pQList == NULL) + { + return HAL_ERROR; + } + + /* Check the queue */ + if (pQList->Head == NULL) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_EMPTY; + + return HAL_ERROR; + } + + /* Check queue circular mode */ + if (pQList->FirstCircularNode != NULL) + { + if (pQList->FirstCircularNode == pQList->Head) + { + return HAL_OK; + } + else + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + } + + /* Check queue type */ + if (pQList->Type == QUEUE_TYPE_DYNAMIC) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_BUSY; + + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Get CLLR register mask and offset */ + DMA_List_GetCLLRNodeInfo(pQList->Head, &cllr_mask, &cllr_offset); + + /* Find the last queue node and get its position in selected queue */ + node_info.cllr_offset = cllr_offset; + (void)DMA_List_FindNode(pQList, NULL, &node_info); + + /* Set circular mode */ + ((DMA_NodeTypeDef *)(node_info.currentnode_addr))->LinkRegisters[cllr_offset] = + ((uint32_t)pQList->Head & DMA_CLLR_LA) | cllr_mask; + + /* Update linked-list circular state */ + pQList->FirstCircularNode = pQList->Head; + + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_READY; + + /* Prevent MISRA-C2012-Rule-2.2_b */ + UNUSED(node_info); + + return HAL_OK; +} + +/** + * @brief Clear circular mode for linked-list queue. + * @param pQList : Pointer to a DMA_QListTypeDef structure that contains queue information. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_List_ClearCircularMode(DMA_QListTypeDef *const pQList) +{ + uint32_t cllr_offset; + DMA_NodeInQInfoTypeDef node_info; + + /* Check the queue parameter */ + if (pQList == NULL) + { + return HAL_ERROR; + } + + /* Check the queue */ + if (pQList->Head == NULL) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_EMPTY; + + return HAL_ERROR; + } + + /* Check queue circular mode */ + if (pQList->FirstCircularNode == NULL) + { + return HAL_OK; + } + + /* Check queue type */ + if (pQList->Type == QUEUE_TYPE_DYNAMIC) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_BUSY; + + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Get CLLR register offset */ + DMA_List_GetCLLRNodeInfo(pQList->Head, NULL, &cllr_offset); + + /* Find the last queue node and get its position in selected queue */ + node_info.cllr_offset = cllr_offset; + (void)DMA_List_FindNode(pQList, NULL, &node_info); + + /* Clear circular mode */ + ((DMA_NodeTypeDef *)(node_info.currentnode_addr))->LinkRegisters[cllr_offset] = 0U; + + /* Update linked-list circular configuration */ + pQList->FirstCircularNode = NULL; + + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_READY; + + /* Prevent MISRA-C2012-Rule-2.2_b */ + UNUSED(node_info); + + return HAL_OK; +} + +/** + * @brief Convert a linked-list queue to dynamic (Optimized DMA queue execution). + * @param pQList : Pointer to a DMA_QListTypeDef structure that contains queue information. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_List_ConvertQToDynamic(DMA_QListTypeDef *const pQList) +{ + uint32_t cllr_offset; + uint32_t currentnode_addr; + DMA_NodeTypeDef context_node; + DMA_NodeInQInfoTypeDef node_info; + + /* Check the queue parameter */ + if (pQList == NULL) + { + return HAL_ERROR; + } + + /* Check the queue */ + if (pQList->Head == NULL) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_EMPTY; + + return HAL_ERROR; + } + + /* Check if queue is dynamic */ + if (pQList->Type == QUEUE_TYPE_DYNAMIC) + { + return HAL_OK; + } + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_BUSY; + + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Get CLLR register mask and offset */ + DMA_List_GetCLLRNodeInfo(pQList->Head, NULL, &cllr_offset); + + /* Check queue circularity */ + if (pQList->FirstCircularNode != 0U) + { + /* Find the last queue node and get its position in selected queue */ + node_info.cllr_offset = cllr_offset; + (void)DMA_List_FindNode(pQList, NULL, &node_info); + } + + /* Set current node address */ + currentnode_addr = (uint32_t)pQList->Head; + + /* Store register value */ + DMA_List_FillNode(pQList->Head, &context_node); + + /* Convert all nodes to dyncamic (Bypass head node) */ + for (uint32_t node_count = 1U; node_count < pQList->NodeNumber; node_count++) + { + /* Update node address */ + MODIFY_REG(currentnode_addr, DMA_CLLR_LA, (context_node.LinkRegisters[cllr_offset] & DMA_CLLR_LA)); + + /* Bypass the first circular node when first circular node isn't the last queue node */ + if (((uint32_t)pQList->FirstCircularNode != 0U) && + ((uint32_t)pQList->FirstCircularNode != node_info.currentnode_addr) && + ((uint32_t)pQList->FirstCircularNode == currentnode_addr)) + { + /* Copy first circular node to context node */ + DMA_List_FillNode(pQList->FirstCircularNode, &context_node); + } + else + { + /* Convert current node to dynamic */ + DMA_List_ConvertNodeToDynamic((uint32_t)&context_node, currentnode_addr, (cllr_offset + 1U)); + } + } + + /* Check if first circular node is the last node queue */ + if (((uint32_t)pQList->FirstCircularNode != 0U) && + ((uint32_t)pQList->FirstCircularNode != node_info.currentnode_addr)) + { + /* Update all queue nodes CLLR */ + DMA_List_UpdateDynamicQueueNodesCLLR(pQList, LASTNODE_ISNOT_CIRCULAR); + } + else + { + /* Update all queue nodes CLLR */ + DMA_List_UpdateDynamicQueueNodesCLLR(pQList, LASTNODE_IS_CIRCULAR); + } + + /* Set queue type */ + pQList->Type = QUEUE_TYPE_DYNAMIC; + + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Convert a linked-list queue to static (Not optimized DMA queue execution). + * @param pQList : Pointer to a DMA_QListTypeDef structure that contains queue information. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_List_ConvertQToStatic(DMA_QListTypeDef *const pQList) +{ + uint32_t cllr_offset; + uint32_t currentnode_addr; + DMA_NodeTypeDef context_node; + + /* Check the queue parameter */ + if (pQList == NULL) + { + return HAL_ERROR; + } + + /* Check the queue */ + if (pQList->Head == NULL) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_EMPTY; + + return HAL_ERROR; + } + + /* Check if queue is static */ + if (pQList->Type == QUEUE_TYPE_STATIC) + { + return HAL_OK; + } + + /* Set current node address */ + currentnode_addr = (uint32_t)pQList->Head; + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_BUSY; + + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Get CLLR register mask and offset */ + DMA_List_GetCLLRNodeInfo(pQList->Head, NULL, &cllr_offset); + + /* Set all CLLR queue nodes to their default positions */ + DMA_List_UpdateStaticQueueNodesCLLR(pQList, UPDATE_CLLR_POSITION); + + /* Convert all nodes to static (Bypass head node) */ + for (uint32_t node_count = 1U; node_count < pQList->NodeNumber; node_count++) + { + /* Update context node register values */ + DMA_List_FillNode((DMA_NodeTypeDef *)currentnode_addr, &context_node); + + /* Update node address */ + MODIFY_REG(currentnode_addr, DMA_CLLR_LA, (context_node.LinkRegisters[cllr_offset] & DMA_CLLR_LA)); + + /* Convert current node to static */ + DMA_List_ConvertNodeToStatic((uint32_t)&context_node, currentnode_addr, (cllr_offset + 1U)); + } + + /* Set all CLLR queue nodes to their default values */ + DMA_List_UpdateStaticQueueNodesCLLR(pQList, UPDATE_CLLR_VALUE); + + /* Set queue type */ + pQList->Type = QUEUE_TYPE_STATIC; + + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Update the queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Link linked-list queue to a DMA channel. + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the + * specified DMA Channel. + * @param pQList : Pointer to a DMA_QListTypeDef structure that contains queue information. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_List_LinkQ(DMA_HandleTypeDef *const hdma, + DMA_QListTypeDef *const pQList) +{ + HAL_DMA_StateTypeDef state; + + /* Check the DMA channel handle and the queue parameters */ + if ((hdma == NULL) || (pQList == NULL)) + { + return HAL_ERROR; + } + + /* Get DMA state */ + state = hdma->State; + + /* Check DMA channel state */ + if ((hdma->State == HAL_DMA_STATE_BUSY) || (state == HAL_DMA_STATE_SUSPEND)) + { + /* Update the DMA channel error code */ + hdma->ErrorCode = HAL_DMA_ERROR_BUSY; + + /* Process unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_ERROR; + } + + /* Check queue state */ + if (pQList->State == HAL_DMA_QUEUE_STATE_BUSY) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_BUSY; + + return HAL_ERROR; + } + + /* Check linearity compatibility */ + if ((IS_DMA_2D_ADDRESSING_INSTANCE(hdma->Instance) == 0U) && + ((pQList->Head->NodeInfo & DMA_CHANNEL_TYPE_2D_ADDR) == DMA_CHANNEL_TYPE_2D_ADDR)) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_UNSUPPORTED; + + return HAL_ERROR; + } + + /* Check circularity compatibility */ + if (hdma->Mode == DMA_LINKEDLIST_CIRCULAR) + { + /* Check first circular node */ + if (pQList->FirstCircularNode == NULL) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + } + else + { + /* Check first circular node */ + if (pQList->FirstCircularNode != NULL) + { + /* Update the queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_INVALIDTYPE; + + return HAL_ERROR; + } + } + + /* Register queue to DMA handle */ + hdma->LinkedListQueue = pQList; + + return HAL_OK; +} + +/** + * @brief Unlink linked-list queue from a DMA channel. + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the + * specified DMA Channel. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_List_UnLinkQ(DMA_HandleTypeDef *const hdma) +{ + HAL_DMA_StateTypeDef state; + + /* Check the DMA channel parameter */ + if (hdma == NULL) + { + return HAL_ERROR; + } + + /* Get DMA state */ + state = hdma->State; + + /* Check DMA channel state */ + if ((hdma->State == HAL_DMA_STATE_BUSY) || (state == HAL_DMA_STATE_SUSPEND)) + { + /* Update the DMA channel error code */ + hdma->ErrorCode = HAL_DMA_ERROR_BUSY; + + /* Process unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_ERROR; + } + + /* Clear queue information from DMA channel handle */ + hdma->LinkedListQueue = NULL; + + return HAL_OK; +} +/** + * @} + */ + +/** @addtogroup DMAEx_Exported_Functions_Group4 + * +@verbatim + ====================================================================================================================== + ############### Data handling, repeated block and trigger configuration functions ############### + ====================================================================================================================== + [..] + This section provides functions allowing to : + (+) Configure DMA channel data handling. + (+) Configure DMA channel repeated block. + (+) Configure DMA channel trigger. + + [..] + (+) The HAL_DMAEx_ConfigDataHandling() function allows to configure DMA channel data handling. + (++) GPDMA data handling : byte-based reordering, packing/unpacking, padding/truncation, sign extension + and left/right alignment. + + (+) The HAL_DMAEx_ConfigTrigger() function allows to configure DMA channel HW triggers. + + (+) The HAL_DMAEx_ConfigRepeatBlock() function allows to configure DMA channel repeated block. + (++) This feature is available only for channel that supports 2 dimensions addressing capability. + +@endverbatim + * @{ + */ + +/** + * @brief Configure the DMA channel data handling according to the specified parameters in the + * DMA_DataHandlingConfTypeDef. + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information + * for the specified DMA Channel. + * @param pConfigDataHandling : Pointer to a DMA_DataHandlingConfTypeDef structure that contains the data handling + * configuration. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_ConfigDataHandling(DMA_HandleTypeDef *const hdma, + DMA_DataHandlingConfTypeDef const *const pConfigDataHandling) +{ + /* Check the DMA peripheral handle and data handling parameters */ + if ((hdma == NULL) || (pConfigDataHandling == NULL)) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DMA_DATA_ALIGNMENT(pConfigDataHandling->DataAlignment)); + assert_param(IS_DMA_DATA_EXCHANGE(pConfigDataHandling->DataExchange)); + + /* Check DMA channel state */ + if (hdma->State == HAL_DMA_STATE_READY) + { + MODIFY_REG(hdma->Instance->CTR1, (DMA_CTR1_DHX | DMA_CTR1_DBX | DMA_CTR1_SBX | DMA_CTR1_PAM), + (pConfigDataHandling->DataAlignment | pConfigDataHandling->DataExchange)); + } + else + { + /* Update the DMA channel error code */ + hdma->ErrorCode = HAL_DMA_ERROR_BUSY; + + /* Process unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Configure the DMA channel trigger according to the specified parameters in the DMA_TriggerConfTypeDef. + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for + * the specified DMA Channel. + * @param pConfigTrigger : Pointer to a DMA_TriggerConfTypeDef structure that contains the trigger configuration. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_ConfigTrigger(DMA_HandleTypeDef *const hdma, + DMA_TriggerConfTypeDef const *const pConfigTrigger) +{ + /* Check the DMA peripheral handle and trigger parameters */ + if ((hdma == NULL) || (pConfigTrigger == NULL)) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance)); + assert_param(IS_DMA_TRIGGER_POLARITY(pConfigTrigger->TriggerPolarity)); + assert_param(IS_DMA_TRIGGER_MODE(pConfigTrigger->TriggerMode)); + assert_param(IS_DMA_TRIGGER_SELECTION(pConfigTrigger->TriggerSelection)); + + /* Check DMA channel state */ + if (hdma->State == HAL_DMA_STATE_READY) + { + MODIFY_REG(hdma->Instance->CTR2, (DMA_CTR2_TRIGPOL | DMA_CTR2_TRIGSEL | DMA_CTR2_TRIGM), + (pConfigTrigger->TriggerPolarity | pConfigTrigger->TriggerMode | + (pConfigTrigger->TriggerSelection << DMA_CTR2_TRIGSEL_Pos))); + } + else + { + /* Update the DMA channel error code */ + hdma->ErrorCode = HAL_DMA_ERROR_BUSY; + + /* Process unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Configure the DMA channel repeated block according to the specified parameters in the + * DMA_RepeatBlockConfTypeDef. + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information + * for the specified DMA Channel. + * @param pConfigRepeatBlock : Pointer to a DMA_RepeatBlockConfTypeDef structure that contains the repeated block + * configuration. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_ConfigRepeatBlock(DMA_HandleTypeDef *const hdma, + DMA_RepeatBlockConfTypeDef const *const pConfigRepeatBlock) +{ + uint32_t tmpreg1; + uint32_t tmpreg2; + + /* Check the DMA peripheral handle and repeated block parameters */ + if ((hdma == NULL) || (pConfigRepeatBlock == NULL)) + { + return HAL_ERROR; + } + + /* Check parameters */ + assert_param(IS_DMA_2D_ADDRESSING_INSTANCE(hdma->Instance)); + assert_param(IS_DMA_REPEAT_COUNT(pConfigRepeatBlock->RepeatCount)); + assert_param(IS_DMA_BURST_ADDR_OFFSET(pConfigRepeatBlock->SrcAddrOffset)); + assert_param(IS_DMA_BURST_ADDR_OFFSET(pConfigRepeatBlock->DestAddrOffset)); + assert_param(IS_DMA_BLOCK_ADDR_OFFSET(pConfigRepeatBlock->BlkSrcAddrOffset)); + assert_param(IS_DMA_BLOCK_ADDR_OFFSET(pConfigRepeatBlock->BlkDestAddrOffset)); + + /* Check DMA channel state */ + if (hdma->State == HAL_DMA_STATE_READY) + { + /* Store repeat block count */ + tmpreg1 = ((pConfigRepeatBlock->RepeatCount - 1U) << DMA_CBR1_BRC_Pos); + + /* Check the sign of single/burst destination address offset value */ + if (pConfigRepeatBlock->DestAddrOffset < 0) + { + /* Store single/burst destination address offset configuration (signed case) */ + tmpreg1 |= DMA_CBR1_DDEC; + tmpreg2 = (uint32_t)(- pConfigRepeatBlock->DestAddrOffset); + tmpreg2 = tmpreg2 << DMA_CTR3_DAO_Pos; + } + else + { + /* Store single/burst destination address offset configuration (unsigned case) */ + tmpreg2 = ((uint32_t)pConfigRepeatBlock->DestAddrOffset << DMA_CTR3_DAO_Pos); + } + + /* Check the sign of single/burst source address offset value */ + if (pConfigRepeatBlock->SrcAddrOffset < 0) + { + /* Store single/burst source address offset configuration (signed case) */ + tmpreg1 |= DMA_CBR1_SDEC; + tmpreg2 |= (uint32_t)(- pConfigRepeatBlock->SrcAddrOffset); + } + else + { + /* Store single/burst source address offset configuration (unsigned case) */ + tmpreg2 |= (uint32_t)pConfigRepeatBlock->SrcAddrOffset; + } + + /* Write DMA Channel Transfer Register 3 (CTR3) */ + WRITE_REG(hdma->Instance->CTR3, tmpreg2); + + /* Check the sign of block destination address offset value */ + if (pConfigRepeatBlock->BlkDestAddrOffset < 0) + { + /* Store block destination address offset configuration (signed case) */ + tmpreg1 |= DMA_CBR1_BRDDEC; + tmpreg2 = (uint32_t)(- pConfigRepeatBlock->BlkDestAddrOffset); + tmpreg2 = tmpreg2 << DMA_CBR2_BRDAO_Pos; + } + else + { + /* Store block destination address offset configuration (unsigned case) */ + tmpreg2 = ((uint32_t)pConfigRepeatBlock->BlkDestAddrOffset << DMA_CBR2_BRDAO_Pos); + } + + /* Check the sign of block source address offset value */ + if (pConfigRepeatBlock->BlkSrcAddrOffset < 0) + { + /* Store block source address offset configuration (signed case) */ + tmpreg1 |= DMA_CBR1_BRSDEC; + tmpreg2 |= (uint32_t)(- pConfigRepeatBlock->BlkSrcAddrOffset); + } + else + { + /* Store block source address offset configuration (unsigned case) */ + tmpreg2 |= (uint32_t)pConfigRepeatBlock->BlkSrcAddrOffset; + } + + /* Write DMA Channel block register 2 (CBR2) */ + WRITE_REG(hdma->Instance->CBR2, tmpreg2); + + /* Write DMA Channel block register 1 (CBR1) */ + WRITE_REG(hdma->Instance->CBR1, tmpreg1); + } + else + { + /* Update the DMA channel error code */ + hdma->ErrorCode = HAL_DMA_ERROR_BUSY; + + /* Process unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_ERROR; + } + + return HAL_OK; +} +/** + * @} + */ + +/** @addtogroup DMAEx_Exported_Functions_Group5 + * +@verbatim + ====================================================================================================================== + ############### Suspend and resume operation functions ############### + ====================================================================================================================== + [..] + This section provides functions allowing to : + (+) Suspend any ongoing DMA channel transfer. + (+) Resume any suspended DMA channel transfer. + + [..] + (+) The HAL_DMAEx_Suspend() function allows to suspend any ongoing DMA channel transfer in polling mode (Blocking + mode). + + (+) The HAL_DMAEx_Suspend_IT() function allows to suspend any ongoing DMA channel transfer in interrupt mode + (Non-blocking mode). + + (+) The HAL_DMAEx_Resume() function allows to resume any suspended DMA channel transfer. + +@endverbatim + * @{ + */ + +/** + * @brief Suspend any ongoing DMA channel transfer in polling mode (Blocking mode). + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the + * specified DMA channel. + * @note After suspending a DMA channel, a check for wait until the DMA channel is effectively suspended is added. If + * a channel is suspended while a data transfer is ongoing, the current data will be transferred and the + * channel will be effectively suspended only after the transfer of this single/burst data is finished. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_Suspend(DMA_HandleTypeDef *const hdma) +{ + /* Get tick number */ + uint32_t tickstart = HAL_GetTick(); + + /* Check the DMA peripheral handle */ + if (hdma == NULL) + { + return HAL_ERROR; + } + + /* Check DMA channel state */ + if (hdma->State != HAL_DMA_STATE_BUSY) + { + /* Update the DMA channel error code */ + hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER; + + /* Process unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_ERROR; + } + else + { + /* Suspend the channel */ + hdma->Instance->CCR |= DMA_CCR_SUSP; + + /* Check if the DMA channel is suspended */ + while ((hdma->Instance->CSR & DMA_CSR_SUSPF) == 0U) + { + /* Check for the timeout */ + if ((HAL_GetTick() - tickstart) > HAL_TIMEOUT_DMA_ABORT) + { + /* Update the DMA channel error code */ + hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT; + + /* Update the DMA channel state */ + hdma->State = HAL_DMA_STATE_ERROR; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_ERROR; + } + } + + /* Update the DMA channel state */ + hdma->State = HAL_DMA_STATE_SUSPEND; + } + + return HAL_OK; +} + +/** + * @brief Suspend any ongoing DMA channel transfer in polling mode (Non-blocking mode). + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the + * specified DMA Channel. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_Suspend_IT(DMA_HandleTypeDef *const hdma) +{ + /* Check the DMA peripheral handle parameter */ + if (hdma == NULL) + { + return HAL_ERROR; + } + + /* Check DMA channel state */ + if (hdma->State != HAL_DMA_STATE_BUSY) + { + /* Update the DMA channel error code */ + hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER; + + /* Process unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_ERROR; + } + else + { + /* Suspend the DMA channel and activate suspend interrupt */ + hdma->Instance->CCR |= (DMA_CCR_SUSP | DMA_CCR_SUSPIE); + } + + return HAL_OK; +} + +/** + * @brief Resume any suspended DMA channel transfer. + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the + * specified DMA Channel. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DMAEx_Resume(DMA_HandleTypeDef *const hdma) +{ + /* Check the DMA peripheral handle parameter */ + if (hdma == NULL) + { + return HAL_ERROR; + } + + /* Check DMA channel state */ + if (hdma->State != HAL_DMA_STATE_SUSPEND) + { + /* Update the DMA channel error code */ + hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER; + + /* Process unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_ERROR; + } + else + { + /* Resume the DMA channel */ + hdma->Instance->CCR &= (~DMA_CCR_SUSP); + + /* Clear the suspend flag */ + hdma->Instance->CFCR |= DMA_CFCR_SUSPF; + + /* Update the DMA channel state */ + hdma->State = HAL_DMA_STATE_BUSY; + } + + return HAL_OK; +} +/** + * @} + */ + +/** @addtogroup DMAEx_Exported_Functions_Group6 + * +@verbatim + ====================================================================================================================== + ############### Fifo status function ############### + ====================================================================================================================== + [..] + This section provides function allowing to get DMA channel FIFO level. + + [..] + (+) The HAL_DMAEx_GetFifoLevel() function allows to return the number of available write beats in the FIFO, in + units of the programmed destination data. + (++) This API is available only for DMA channels that supports FIFO. + +@endverbatim + * @{ + */ + +/** + * @brief Get and returns the DMA channel FIFO level. + * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the + * specified DMA Channel. + * @retval Returns the number of available beats in FIFO. + */ +uint32_t HAL_DMAEx_GetFifoLevel(DMA_HandleTypeDef const *const hdma) +{ + return ((hdma->Instance->CSR & DMA_CSR_FIFOL) >> DMA_CSR_FIFOL_Pos); +} +/** + * @} + */ + +/** + * @} + */ + +/* Private functions -------------------------------------------------------------------------------------------------*/ +/** @defgroup DMAEx_Private_Functions DMAEx Private Functions + * @brief DMAEx Private Functions + * @{ + */ + +/** + * @brief Initialize the DMA handle according to the specified parameters in the DMA_InitTypeDef. + * @param hdma : pointer to a DMA_HandleTypeDef structure that contains the configuration information for the + * specified DMA Channel. + * @retval None. + */ +static void DMA_List_Init(DMA_HandleTypeDef const *const hdma) +{ + uint32_t tmpreg; + + /* Prepare DMA Channel Control Register (CCR) value */ + tmpreg = hdma->InitLinkedList.Priority | hdma->InitLinkedList.LinkStepMode; + + /* Check DMA channel instance */ + if (IS_GPDMA_INSTANCE(hdma->Instance) != 0U) + { + tmpreg |= hdma->InitLinkedList.LinkAllocatedPort; + } + + /* Write DMA Channel Control Register (CCR) */ + MODIFY_REG(hdma->Instance->CCR, DMA_CCR_PRIO | DMA_CCR_LAP | DMA_CCR_LSM, tmpreg); + + /* Write DMA Channel Control Register (CTR1) */ + WRITE_REG(hdma->Instance->CTR1, 0U); + + /* Write DMA Channel Control Register (CTR2) */ + WRITE_REG(hdma->Instance->CTR2, hdma->InitLinkedList.TransferEventMode); + + /* Write DMA Channel Control Register (CBR1) */ + WRITE_REG(hdma->Instance->CBR1, 0U); + + /* Write DMA Channel Control Register (CSAR) */ + WRITE_REG(hdma->Instance->CSAR, 0U); + + /* Write DMA Channel Control Register (CDAR) */ + WRITE_REG(hdma->Instance->CDAR, 0U); + + /* If 2D Addressing is supported by current channel */ + if (IS_DMA_2D_ADDRESSING_INSTANCE(hdma->Instance) != 0U) + { + /* Write DMA Channel Control Register (CTR3) */ + WRITE_REG(hdma->Instance->CTR3, 0U); + + /* Write DMA Channel Control Register (CBR2) */ + WRITE_REG(hdma->Instance->CBR2, 0U); + } + + /* Write DMA Channel linked-list address register (CLLR) */ + WRITE_REG(hdma->Instance->CLLR, 0U); +} + +/** + * @brief Build a DMA channel node according to the specified parameters in the DMA_NodeConfTypeDef. + * @param pNodeConfig : Pointer to a DMA_NodeConfTypeDef structure that contains the configuration information for the + * specified DMA linked-list Node. + * @param pNode : Pointer to a DMA_NodeTypeDef structure that contains linked-list node registers + * configurations. + * @retval None. + */ +static void DMA_List_BuildNode(DMA_NodeConfTypeDef const *const pNodeConfig, + DMA_NodeTypeDef *const pNode) +{ + int32_t blockoffset; + + /* Update CTR1 register value ***************************************************************************************/ + /* Prepare DMA channel transfer register (CTR1) value */ + pNode->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] = pNodeConfig->Init.DestInc | + pNodeConfig->Init.DestDataWidth | + pNodeConfig->DataHandlingConfig.DataAlignment | + pNodeConfig->Init.SrcInc | + pNodeConfig->Init.SrcDataWidth; + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + /* set source channel security attribute */ + if (pNodeConfig->SrcSecure == DMA_CHANNEL_SRC_SEC) + { + pNode->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] |= DMA_CTR1_SSEC; + } + + /* set destination channel security attribute */ + if (pNodeConfig->DestSecure == DMA_CHANNEL_DEST_SEC) + { + pNode->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] |= DMA_CTR1_DSEC; + } +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + /* Add parameters related to DMA configuration */ + if ((pNodeConfig->NodeType & DMA_CHANNEL_TYPE_GPDMA) == DMA_CHANNEL_TYPE_GPDMA) + { + /* Prepare DMA channel transfer register (CTR1) value */ + pNode->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] |= + (pNodeConfig->Init.TransferAllocatedPort | pNodeConfig->DataHandlingConfig.DataExchange | + (((pNodeConfig->Init.DestBurstLength - 1U) << DMA_CTR1_DBL_1_Pos) & DMA_CTR1_DBL_1) | + (((pNodeConfig->Init.SrcBurstLength - 1U) << DMA_CTR1_SBL_1_Pos) & DMA_CTR1_SBL_1)); + } + /*********************************************************************************** CTR1 register value is updated */ + + + /* Update CTR2 register value ***************************************************************************************/ + /* Prepare DMA channel transfer register 2 (CTR2) value */ + pNode->LinkRegisters[NODE_CTR2_DEFAULT_OFFSET] = pNodeConfig->Init.TransferEventMode | + (pNodeConfig->Init.Request & (DMA_CTR2_REQSEL | DMA_CTR2_SWREQ)); + + /* Check for memory to peripheral transfer */ + if ((pNodeConfig->Init.Direction) == DMA_MEMORY_TO_PERIPH) + { + /* Check for GPDMA */ + if ((pNodeConfig->NodeType & DMA_CHANNEL_TYPE_GPDMA) == DMA_CHANNEL_TYPE_GPDMA) + { + pNode->LinkRegisters[NODE_CTR2_DEFAULT_OFFSET] |= DMA_CTR2_DREQ; + } + } + /* Memory to memory transfer */ + else if ((pNodeConfig->Init.Direction) == DMA_MEMORY_TO_MEMORY) + { + pNode->LinkRegisters[NODE_CTR2_DEFAULT_OFFSET] |= DMA_CTR2_SWREQ; + } + else + { + /* Prevent MISRA-C2012-Rule-15.7 */ + } + + /* Configure HW Peripheral flow control selection */ + pNode->LinkRegisters[NODE_CTR2_DEFAULT_OFFSET] |= pNodeConfig->Init.Mode; + + /* Check if trigger feature is active */ + if (pNodeConfig->TriggerConfig.TriggerPolarity != DMA_TRIG_POLARITY_MASKED) + { + /* Prepare DMA channel transfer register 2 (CTR2) value */ + pNode->LinkRegisters[NODE_CTR2_DEFAULT_OFFSET] |= + pNodeConfig->TriggerConfig.TriggerMode | pNodeConfig->TriggerConfig.TriggerPolarity | + ((pNodeConfig->TriggerConfig.TriggerSelection << DMA_CTR2_TRIGSEL_Pos) & DMA_CTR2_TRIGSEL); + } + /*********************************************************************************** CTR2 register value is updated */ + + + /* Update CBR1 register value ***************************************************************************************/ + /* Prepare DMA channel block register 1 (CBR1) value */ + pNode->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = (pNodeConfig->DataSize & DMA_CBR1_BNDT); + + /* If 2D addressing is supported by the selected DMA channel */ + if ((pNodeConfig->NodeType & DMA_CHANNEL_TYPE_2D_ADDR) == DMA_CHANNEL_TYPE_2D_ADDR) + { + /* Set the new CBR1 Register value */ + pNode->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] |= + (((pNodeConfig->RepeatBlockConfig.RepeatCount - 1U) << DMA_CBR1_BRC_Pos) & DMA_CBR1_BRC); + + /* If the source address offset is negative, set SDEC bit */ + if (pNodeConfig->RepeatBlockConfig.SrcAddrOffset < 0) + { + pNode->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] |= DMA_CBR1_SDEC; + } + else + { + pNode->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] &= (~DMA_CBR1_SDEC); + } + + /* If the destination address offset is negative, set DDEC bit */ + if (pNodeConfig->RepeatBlockConfig.DestAddrOffset < 0) + { + pNode->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] |= DMA_CBR1_DDEC; + } + else + { + pNode->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] &= (~DMA_CBR1_DDEC); + } + + /* If the repeated block source address offset is negative, set BRSEC bit */ + if (pNodeConfig->RepeatBlockConfig.BlkSrcAddrOffset < 0) + { + pNode->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] |= DMA_CBR1_BRSDEC; + } + else + { + pNode->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] &= (~DMA_CBR1_BRSDEC); + } + + /* if the repeated block destination address offset is negative, set BRDEC bit */ + if (pNodeConfig->RepeatBlockConfig.BlkDestAddrOffset < 0) + { + pNode->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] |= DMA_CBR1_BRDDEC; + } + else + { + pNode->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] &= (~DMA_CBR1_BRDDEC); + } + } + /*********************************************************************************** CBR1 register value is updated */ + + + /* Update CSAR register value ***************************************************************************************/ + pNode->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = pNodeConfig->SrcAddress; + /*********************************************************************************** CSAR register value is updated */ + + + /* Update CDAR register value ***************************************************************************************/ + pNode->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = pNodeConfig->DstAddress; + /*********************************************************************************** CDAR register value is updated */ + + /* Check if the selected channel is 2D addressing */ + if ((pNodeConfig->NodeType & DMA_CHANNEL_TYPE_2D_ADDR) == DMA_CHANNEL_TYPE_2D_ADDR) + { + /* Update CTR3 register value *************************************************************************************/ + /* Write new CTR3 Register value : source address offset */ + if (pNodeConfig->RepeatBlockConfig.SrcAddrOffset < 0) + { + blockoffset = (- pNodeConfig->RepeatBlockConfig.SrcAddrOffset); + pNode->LinkRegisters[NODE_CTR3_DEFAULT_OFFSET] = ((uint32_t)blockoffset & DMA_CTR3_SAO); + } + else + { + pNode->LinkRegisters[NODE_CTR3_DEFAULT_OFFSET] = + ((uint32_t)pNodeConfig->RepeatBlockConfig.SrcAddrOffset & DMA_CTR3_SAO); + } + + /* Write new CTR3 Register value : destination address offset */ + if (pNodeConfig->RepeatBlockConfig.DestAddrOffset < 0) + { + blockoffset = (- pNodeConfig->RepeatBlockConfig.DestAddrOffset); + pNode->LinkRegisters[NODE_CTR3_DEFAULT_OFFSET] |= (((uint32_t)blockoffset << DMA_CTR3_DAO_Pos) & DMA_CTR3_DAO); + } + else + { + pNode->LinkRegisters[NODE_CTR3_DEFAULT_OFFSET] |= + (((uint32_t)pNodeConfig->RepeatBlockConfig.DestAddrOffset << DMA_CTR3_DAO_Pos) & DMA_CTR3_DAO); + } + /********************************************************************************* CTR3 register value is updated */ + + + /* Update CBR2 register value *************************************************************************************/ + /* Write new CBR2 Register value : repeated block source address offset */ + if (pNodeConfig->RepeatBlockConfig.BlkSrcAddrOffset < 0) + { + blockoffset = (- pNodeConfig->RepeatBlockConfig.BlkSrcAddrOffset); + pNode->LinkRegisters[NODE_CBR2_DEFAULT_OFFSET] = ((uint32_t)blockoffset & DMA_CBR2_BRSAO); + } + else + { + pNode->LinkRegisters[NODE_CBR2_DEFAULT_OFFSET] = + ((uint32_t)pNodeConfig->RepeatBlockConfig.BlkSrcAddrOffset & DMA_CBR2_BRSAO); + } + + /* Write new CBR2 Register value : repeated block destination address offset */ + if (pNodeConfig->RepeatBlockConfig.BlkDestAddrOffset < 0) + { + blockoffset = (- pNodeConfig->RepeatBlockConfig.BlkDestAddrOffset); + pNode->LinkRegisters[NODE_CBR2_DEFAULT_OFFSET] |= + (((uint32_t)blockoffset & DMA_CBR2_BRSAO) << DMA_CBR2_BRDAO_Pos); + } + else + { + pNode->LinkRegisters[NODE_CBR2_DEFAULT_OFFSET] |= + (((uint32_t)pNodeConfig->RepeatBlockConfig.BlkDestAddrOffset << DMA_CBR2_BRDAO_Pos) & DMA_CBR2_BRDAO); + } + /********************************************************************************* CBR2 register value is updated */ + } + + + /* Update node information value ************************************************************************************/ + /* Set node information */ + pNode->NodeInfo = pNodeConfig->NodeType; + if ((pNodeConfig->NodeType & DMA_CHANNEL_TYPE_2D_ADDR) == DMA_CHANNEL_TYPE_2D_ADDR) + { + pNode->NodeInfo |= (NODE_CLLR_2D_DEFAULT_OFFSET << NODE_CLLR_IDX_POS); + } + else + { + pNode->NodeInfo |= (NODE_CLLR_LINEAR_DEFAULT_OFFSET << NODE_CLLR_IDX_POS); + } + /******************************************************************************** Node information value is updated */ +} + +/** + * @brief Get a DMA channel node configuration. + * @param pNodeConfig : Pointer to a DMA_NodeConfTypeDef structure that contains the configuration information for the + * specified DMA linked-list Node. + * @param pNode : Pointer to a DMA_NodeTypeDef structure that contains linked-list node registers + * configurations. + * @retval None. + */ +static void DMA_List_GetNodeConfig(DMA_NodeConfTypeDef *const pNodeConfig, + DMA_NodeTypeDef const *const pNode) +{ + uint16_t offset; + + /* Get node information *********************************************************************************************/ + pNodeConfig->NodeType = (pNode->NodeInfo & NODE_TYPE_MASK); + /*************************************************************************************** Node type value is updated */ + + + /* Get CTR1 fields values *******************************************************************************************/ + pNodeConfig->Init.SrcInc = pNode->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] & DMA_CTR1_SINC; + pNodeConfig->Init.DestInc = pNode->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] & DMA_CTR1_DINC; + pNodeConfig->Init.SrcDataWidth = pNode->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] & DMA_CTR1_SDW_LOG2; + pNodeConfig->Init.DestDataWidth = pNode->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] & DMA_CTR1_DDW_LOG2; + pNodeConfig->Init.SrcBurstLength = ((pNode->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] & + DMA_CTR1_SBL_1) >> DMA_CTR1_SBL_1_Pos) + 1U; + pNodeConfig->Init.DestBurstLength = ((pNode->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] & + DMA_CTR1_DBL_1) >> DMA_CTR1_DBL_1_Pos) + 1U; + pNodeConfig->Init.TransferAllocatedPort = pNode->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] & + (DMA_CTR1_SAP | DMA_CTR1_DAP); + pNodeConfig->DataHandlingConfig.DataExchange = pNode->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] & + (DMA_CTR1_SBX | DMA_CTR1_DBX | DMA_CTR1_DHX); + pNodeConfig->DataHandlingConfig.DataAlignment = pNode->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] & DMA_CTR1_PAM; +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + if ((pNode->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] & DMA_CTR1_SSEC) != 0U) + { + pNodeConfig->SrcSecure = DMA_CHANNEL_SRC_SEC; + } + else + { + pNodeConfig->SrcSecure = DMA_CHANNEL_SRC_NSEC; + } + + if ((pNode->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] & DMA_CTR1_DSEC) != 0U) + { + pNodeConfig->DestSecure = DMA_CHANNEL_DEST_SEC; + } + else + { + pNodeConfig->DestSecure = DMA_CHANNEL_DEST_NSEC; + } +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + /*********************************************************************************** CTR1 fields values are updated */ + + + /* Get CTR2 fields values *******************************************************************************************/ + if ((pNode->LinkRegisters[NODE_CTR2_DEFAULT_OFFSET] & DMA_CTR2_SWREQ) != 0U) + { + pNodeConfig->Init.Request = DMA_REQUEST_SW; + pNodeConfig->Init.Direction = DMA_MEMORY_TO_MEMORY; + } + else + { + pNodeConfig->Init.Request = pNode->LinkRegisters[NODE_CTR2_DEFAULT_OFFSET] & DMA_CTR2_REQSEL; + + if ((pNode->LinkRegisters[NODE_CTR2_DEFAULT_OFFSET] & DMA_CTR2_DREQ) != 0U) + { + pNodeConfig->Init.Direction = DMA_MEMORY_TO_PERIPH; + } + else + { + pNodeConfig->Init.Direction = DMA_PERIPH_TO_MEMORY; + } + } + + pNodeConfig->Init.BlkHWRequest = (pNode->LinkRegisters[NODE_CTR2_DEFAULT_OFFSET] & DMA_CTR2_BREQ); + pNodeConfig->TriggerConfig.TriggerMode = pNode->LinkRegisters[NODE_CTR2_DEFAULT_OFFSET] & DMA_CTR2_TRIGM; + pNodeConfig->TriggerConfig.TriggerPolarity = pNode->LinkRegisters[NODE_CTR2_DEFAULT_OFFSET] & DMA_CTR2_TRIGPOL; + pNodeConfig->TriggerConfig.TriggerSelection = (pNode->LinkRegisters[NODE_CTR2_DEFAULT_OFFSET] & + DMA_CTR2_TRIGSEL) >> DMA_CTR2_TRIGSEL_Pos; + pNodeConfig->Init.TransferEventMode = pNode->LinkRegisters[NODE_CTR2_DEFAULT_OFFSET] & DMA_CTR2_TCEM; + /*********************************************************************************** CTR2 fields values are updated */ + + + /* Get CBR1 fields **************************************************************************************************/ + pNodeConfig->DataSize = pNode->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] & DMA_CBR1_BNDT; + + if ((pNodeConfig->NodeType & DMA_CHANNEL_TYPE_2D_ADDR) == DMA_CHANNEL_TYPE_2D_ADDR) + { + pNodeConfig->RepeatBlockConfig.RepeatCount = + ((pNode->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] & DMA_CBR1_BRC) >> DMA_CBR1_BRC_Pos) + 1U; + } + else + { + pNodeConfig->RepeatBlockConfig.RepeatCount = 1U; + } + /*********************************************************************************** CBR1 fields values are updated */ + + + /* Get CSAR field ***************************************************************************************************/ + pNodeConfig->SrcAddress = pNode->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET]; + /************************************************************************************** CSAR field value is updated */ + + + /* Get CDAR field ***************************************************************************************************/ + pNodeConfig->DstAddress = pNode->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET]; + /************************************************************************************** CDAR field value is updated */ + + /* Check if the selected channel is 2D addressing */ + if ((pNodeConfig->NodeType & DMA_CHANNEL_TYPE_2D_ADDR) == DMA_CHANNEL_TYPE_2D_ADDR) + { + /* Get CTR3 field *************************************************************************************************/ + offset = (uint16_t)(pNode->LinkRegisters[NODE_CTR3_DEFAULT_OFFSET] & DMA_CTR3_SAO); + pNodeConfig->RepeatBlockConfig.SrcAddrOffset = (int32_t)offset; + + offset = (uint16_t)((pNode->LinkRegisters[NODE_CTR3_DEFAULT_OFFSET] & DMA_CTR3_DAO) >> DMA_CTR3_DAO_Pos); + pNodeConfig->RepeatBlockConfig.DestAddrOffset = (int32_t)offset; + + if ((pNode->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] & DMA_CBR1_SDEC) != 0U) + { + pNodeConfig->RepeatBlockConfig.SrcAddrOffset *= (-1); + } + + if ((pNode->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] & DMA_CBR1_DDEC) != 0U) + { + pNodeConfig->RepeatBlockConfig.DestAddrOffset *= (-1); + } + /************************************************************************************ CTR3 field value is updated */ + + + /* Get CBR2 fields ************************************************************************************************/ + offset = (uint16_t)(pNode->LinkRegisters[NODE_CBR2_DEFAULT_OFFSET] & DMA_CBR2_BRSAO); + pNodeConfig->RepeatBlockConfig.BlkSrcAddrOffset = (int32_t)offset; + + offset = (uint16_t)((pNode->LinkRegisters[NODE_CBR2_DEFAULT_OFFSET] & DMA_CBR2_BRDAO) >> DMA_CBR2_BRDAO_Pos); + pNodeConfig->RepeatBlockConfig.BlkDestAddrOffset = (int32_t)offset; + + if ((pNode->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] & DMA_CBR1_BRSDEC) != 0U) + { + pNodeConfig->RepeatBlockConfig.BlkSrcAddrOffset *= (-1); + } + + if ((pNode->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] & DMA_CBR1_BRDDEC) != 0U) + { + pNodeConfig->RepeatBlockConfig.BlkDestAddrOffset *= (-1); + } + /************************************************************************************ CBR2 field value is updated */ + } + else + { + /* Get CTR3 field *************************************************************************************************/ + pNodeConfig->RepeatBlockConfig.SrcAddrOffset = 0; + pNodeConfig->RepeatBlockConfig.DestAddrOffset = 0; + /************************************************************************************ CTR3 field value is updated */ + + + /* Get CBR2 fields ************************************************************************************************/ + pNodeConfig->RepeatBlockConfig.BlkSrcAddrOffset = 0; + pNodeConfig->RepeatBlockConfig.BlkDestAddrOffset = 0; + /************************************************************************************ CBR2 field value is updated */ + } +} + +/** + * @brief Check nodes base addresses compatibility. + * @param pNode1 : Pointer to a DMA_NodeTypeDef structure that contains linked-list node 1 registers configurations. + * @param pNode2 : Pointer to a DMA_NodeTypeDef structure that contains linked-list node 2 registers configurations. + * @param pNode3 : Pointer to a DMA_NodeTypeDef structure that contains linked-list node 3 registers configurations. + * @retval Return 0 when nodes addresses are compatible, 1 otherwise. + */ +static uint32_t DMA_List_CheckNodesBaseAddresses(DMA_NodeTypeDef const *const pNode1, + DMA_NodeTypeDef const *const pNode2, + DMA_NodeTypeDef const *const pNode3) +{ + uint32_t temp = (((uint32_t)pNode1 | (uint32_t)pNode2 | (uint32_t)pNode3) & DMA_CLBAR_LBA); + uint32_t ref = 0U; + + /* Check node 1 address */ + if ((uint32_t)pNode1 != 0U) + { + ref = (uint32_t)pNode1; + } + /* Check node 2 address */ + else if ((uint32_t)pNode2 != 0U) + { + ref = (uint32_t)pNode2; + } + /* Check node 3 address */ + else if ((uint32_t)pNode3 != 0U) + { + ref = (uint32_t)pNode3; + } + else + { + /* Prevent MISRA-C2012-Rule-15.7 */ + } + + /* Check addresses compatibility */ + if (temp != ((uint32_t)ref & DMA_CLBAR_LBA)) + { + return 1U; + } + + return 0U; +} + +/** + * @brief Check nodes types compatibility. + * @param pNode1 : Pointer to a DMA_NodeTypeDef structure that contains linked-list node 1 registers configurations. + * @param pNode2 : Pointer to a DMA_NodeTypeDef structure that contains linked-list node 2 registers configurations. + * @param pNode3 : Pointer to a DMA_NodeTypeDef structure that contains linked-list node 3 registers configurations. + * @retval Return 0 when nodes types are compatible, otherwise nodes types are not compatible. + */ +static uint32_t DMA_List_CheckNodesTypes(DMA_NodeTypeDef const *const pNode1, + DMA_NodeTypeDef const *const pNode2, + DMA_NodeTypeDef const *const pNode3) +{ + uint32_t ref = 0U; + + /* Check node 1 parameter */ + if (pNode1 != NULL) + { + ref = pNode1->NodeInfo & NODE_TYPE_MASK; + } + /* Check node 2 parameter */ + else if (pNode2 != NULL) + { + ref = pNode2->NodeInfo & NODE_TYPE_MASK; + } + /* Check node 3 parameter */ + else if (pNode3 != NULL) + { + ref = pNode3->NodeInfo & NODE_TYPE_MASK; + } + else + { + /* Prevent MISRA-C2012-Rule-15.7 */ + } + + /* Check node 2 parameter */ + if (pNode2 != NULL) + { + /* Check node type compatibility */ + if (ref != (pNode2->NodeInfo & NODE_TYPE_MASK)) + { + return 2U; + } + } + + /* Check node 3 parameter */ + if (pNode3 != NULL) + { + /* Check node type compatibility */ + if (ref != (pNode3->NodeInfo & NODE_TYPE_MASK)) + { + return 3U; + } + } + + return 0U; +} + +/** + * @brief Check nodes types compatibility. + * @param pNode : Pointer to a DMA_NodeTypeDef structure that contains linked-list node registers + * configurations. + * @param cllr_mask : Pointer to CLLR register mask value. + * @param cllr_offset : Pointer to CLLR register offset value. + * @retval None. + */ +static void DMA_List_GetCLLRNodeInfo(DMA_NodeTypeDef const *const pNode, + uint32_t *const cllr_mask, + uint32_t *const cllr_offset) +{ + /* Check node type */ + if ((pNode->NodeInfo & DMA_CHANNEL_TYPE_2D_ADDR) == DMA_CHANNEL_TYPE_2D_ADDR) + { + /* Update CLLR register mask value */ + if (cllr_mask != NULL) + { + *cllr_mask = DMA_CLLR_UT1 | DMA_CLLR_UT2 | DMA_CLLR_UB1 | DMA_CLLR_USA | DMA_CLLR_UDA | DMA_CLLR_UT3 | + DMA_CLLR_UB2 | DMA_CLLR_ULL; + } + + /* Update CLLR register offset */ + if (cllr_offset != NULL) + { + *cllr_offset = NODE_CLLR_2D_DEFAULT_OFFSET; + } + } + /* Update CLLR and register number for linear addressing node */ + else + { + /* Update CLLR register mask value */ + if (cllr_mask != NULL) + { + *cllr_mask = DMA_CLLR_UT1 | DMA_CLLR_UT2 | DMA_CLLR_UB1 | DMA_CLLR_USA | DMA_CLLR_UDA | DMA_CLLR_ULL; + } + + /* Update CLLR register offset */ + if (cllr_offset != NULL) + { + *cllr_offset = NODE_CLLR_LINEAR_DEFAULT_OFFSET; + } + } +} + +/** + * @brief Find node in queue. + * @param pQList : Pointer to a DMA_QListTypeDef structure that contains queue information. + * @param pNode : Pointer to a DMA_NodeTypeDef structure that contains linked-list node registers configurations. + * @param NodeInfo : Pointer to a DMA_NodeInQInfoTypeDef structure that contains node linked to queue information. + * @retval Return 0 when node is found in selected queue, otherwise node is not found. + */ +static uint32_t DMA_List_FindNode(DMA_QListTypeDef const *const pQList, + DMA_NodeTypeDef const *const pNode, + DMA_NodeInQInfoTypeDef *const NodeInfo) +{ + uint32_t node_idx = 0U; + uint32_t currentnode_address = 0U; + uint32_t previousnode_address = 0U; + uint32_t cllr_offset = NodeInfo->cllr_offset; + + /* Find last node in queue */ + if (pNode == NULL) + { + /* Check that previous node is linked to the selected queue */ + while (node_idx < pQList->NodeNumber) + { + /* Get head node address */ + if (node_idx == 0U) + { + currentnode_address = (uint32_t)pQList->Head & DMA_CLLR_LA; + } + /* Calculate nodes addresses */ + else + { + previousnode_address = currentnode_address; + currentnode_address = + ((DMA_NodeTypeDef *)(currentnode_address + + ((uint32_t)pQList->Head & DMA_CLBAR_LBA)))->LinkRegisters[cllr_offset] & DMA_CLLR_LA; + } + + /* Increment node index */ + node_idx++; + } + } + /* Find selected node node in queue */ + else + { + /* Check that previous node is linked to the selected queue */ + while ((node_idx < pQList->NodeNumber) && (currentnode_address != ((uint32_t)pNode & DMA_CLLR_LA))) + { + /* Get head node address */ + if (node_idx == 0U) + { + currentnode_address = (uint32_t)pQList->Head & DMA_CLLR_LA; + } + /* Calculate nodes addresses */ + else + { + previousnode_address = currentnode_address; + currentnode_address = + ((DMA_NodeTypeDef *)(currentnode_address + + ((uint32_t)pQList->Head & DMA_CLBAR_LBA)))->LinkRegisters[cllr_offset] & DMA_CLLR_LA; + } + + /* Increment node index */ + node_idx++; + } + } + + /* Check stored address */ + if (pNode != NULL) + { + if (currentnode_address != ((uint32_t)pNode & DMA_CLLR_LA)) + { + return 1U; + } + } + + /* Update current node position */ + NodeInfo->currentnode_pos = node_idx; + + /* Update previous node address */ + NodeInfo->previousnode_addr = previousnode_address | ((uint32_t)pQList->Head & DMA_CLBAR_LBA); + + /* Update current node address */ + NodeInfo->currentnode_addr = currentnode_address | ((uint32_t)pQList->Head & DMA_CLBAR_LBA); + + /* Update next node address */ + if (((DMA_NodeTypeDef *)NodeInfo->currentnode_addr)->LinkRegisters[cllr_offset] != 0U) + { + NodeInfo->nextnode_addr = (((DMA_NodeTypeDef *)NodeInfo->currentnode_addr)->LinkRegisters[cllr_offset] & + DMA_CLLR_LA) | ((uint32_t)pQList->Head & DMA_CLBAR_LBA); + } + + return 0U; +} + +/** + * @brief Reset queue nodes. + * @param pQList : Pointer to a DMA_QListTypeDef structure that contains queue information. + * @param NodeInfo : Pointer to a DMA_NodeInQInfoTypeDef structure that contains node linked to queue information. + * @retval None. + */ +static void DMA_List_ResetQueueNodes(DMA_QListTypeDef const *const pQList, + DMA_NodeInQInfoTypeDef const *const NodeInfo) +{ + uint32_t node_idx = 0U; + uint32_t currentnode_address = 0U; + uint32_t previousnode_address; + uint32_t cllr_offset = NodeInfo->cllr_offset; + + /* Check that previous node is linked to the selected queue */ + while (node_idx < pQList->NodeNumber) + { + /* Get head node address */ + if (node_idx == 0U) + { + previousnode_address = (uint32_t)pQList->Head & DMA_CLLR_LA; + currentnode_address = (pQList->Head->LinkRegisters[cllr_offset] & DMA_CLLR_LA); + } + /* Calculate nodes addresses */ + else + { + previousnode_address = currentnode_address; + currentnode_address = + ((DMA_NodeTypeDef *)(currentnode_address + + ((uint32_t)pQList->Head & DMA_CLBAR_LBA)))->LinkRegisters[cllr_offset] & DMA_CLLR_LA; + } + + /* Reset node */ + ((DMA_NodeTypeDef *)(previousnode_address + + ((uint32_t)pQList->Head & DMA_CLBAR_LBA)))->LinkRegisters[cllr_offset] = 0U; + + /* Increment node index */ + node_idx++; + } +} + +/** + * @brief Fill source node registers values by destination nodes registers values. + * @param pSrcNode : Pointer to a DMA_NodeTypeDef structure that contains linked-list source node registers + * configurations. + * @param pDestNode : Pointer to a DMA_NodeTypeDef structure that contains linked-list destination node registers + * configurations. + * @retval None. + */ +static void DMA_List_FillNode(DMA_NodeTypeDef const *const pSrcNode, + DMA_NodeTypeDef *const pDestNode) +{ + /* Repeat for all register nodes */ + for (uint32_t reg_idx = 0U; reg_idx < NODE_MAXIMUM_SIZE; reg_idx++) + { + pDestNode->LinkRegisters[reg_idx] = pSrcNode->LinkRegisters[reg_idx]; + } + + /* Fill node information */ + pDestNode->NodeInfo = pSrcNode->NodeInfo; +} + +/** + * @brief Convert node to dynamic. + * @param ContextNodeAddr : The context node address. + * @param CurrentNodeAddr : The current node address to be converted. + * @param RegisterNumber : The register number to be converted. + * @retval None. + */ +static void DMA_List_ConvertNodeToDynamic(uint32_t ContextNodeAddr, + uint32_t CurrentNodeAddr, + uint32_t RegisterNumber) +{ + uint32_t currentnode_reg_counter = 0U; + uint32_t contextnode_reg_counter = 0U; + uint32_t cllr_idx = RegisterNumber - 1U; + DMA_NodeTypeDef *context_node = (DMA_NodeTypeDef *)ContextNodeAddr; + DMA_NodeTypeDef *current_node = (DMA_NodeTypeDef *)CurrentNodeAddr; + uint32_t update_link[NODE_MAXIMUM_SIZE] = {DMA_CLLR_UT1, DMA_CLLR_UT2, DMA_CLLR_UB1, DMA_CLLR_USA, + DMA_CLLR_UDA, DMA_CLLR_UT3, DMA_CLLR_UB2, DMA_CLLR_ULL + }; + + /* Update ULL position according to register number */ + update_link[cllr_idx] = update_link[NODE_MAXIMUM_SIZE - 1U]; + + /* Repeat for all node registers */ + while (contextnode_reg_counter != RegisterNumber) + { + /* Check if register values are equal (exception for CSAR, CDAR and CLLR registers) */ + if ((context_node->LinkRegisters[contextnode_reg_counter] == + current_node->LinkRegisters[currentnode_reg_counter]) && + (contextnode_reg_counter != NODE_CSAR_DEFAULT_OFFSET) && + (contextnode_reg_counter != NODE_CDAR_DEFAULT_OFFSET) && + (contextnode_reg_counter != (RegisterNumber - 1U))) + { + /* Format the node according to unused registers */ + DMA_List_FormatNode(current_node, currentnode_reg_counter, RegisterNumber, NODE_DYNAMIC_FORMAT); + + /* Update CLLR index */ + cllr_idx --; + + /* Update CLLR fields */ + current_node->LinkRegisters[cllr_idx] &= ~update_link[contextnode_reg_counter]; + } + else + { + /* Update context node register fields with new values */ + context_node->LinkRegisters[contextnode_reg_counter] = current_node->LinkRegisters[currentnode_reg_counter]; + + /* Update CLLR fields */ + current_node->LinkRegisters[cllr_idx] |= update_link[contextnode_reg_counter]; + + /* Increment current node number register counter */ + currentnode_reg_counter++; + } + + /* Increment context node number register counter */ + contextnode_reg_counter++; + } + + /* Update node information */ + MODIFY_REG(current_node->NodeInfo, NODE_CLLR_IDX, ((currentnode_reg_counter - 1U) << NODE_CLLR_IDX_POS)); + + /* Clear unused node fields */ + DMA_List_ClearUnusedFields(current_node, currentnode_reg_counter); +} + +/** + * @brief Convert node to static. + * @param ContextNodeAddr : The context node address. + * @param CurrentNodeAddr : The current node address to be converted. + * @param RegisterNumber : The register number to be converted. + * @retval None. + */ +static void DMA_List_ConvertNodeToStatic(uint32_t ContextNodeAddr, + uint32_t CurrentNodeAddr, + uint32_t RegisterNumber) +{ + uint32_t contextnode_reg_counter = 0U; + uint32_t cllr_idx; + uint32_t cllr_mask; + DMA_NodeTypeDef *context_node = (DMA_NodeTypeDef *)ContextNodeAddr; + DMA_NodeTypeDef *current_node = (DMA_NodeTypeDef *)CurrentNodeAddr; + uint32_t update_link[NODE_MAXIMUM_SIZE] = {DMA_CLLR_UT1, DMA_CLLR_UT2, DMA_CLLR_UB1, DMA_CLLR_USA, + DMA_CLLR_UDA, DMA_CLLR_UT3, DMA_CLLR_UB2, DMA_CLLR_ULL + }; + + /* Update ULL position according to register number */ + update_link[RegisterNumber - 1U] = update_link[NODE_MAXIMUM_SIZE - 1U]; + + /* Get context node CLLR information */ + cllr_idx = (context_node->NodeInfo & NODE_CLLR_IDX) >> NODE_CLLR_IDX_POS; + cllr_mask = context_node->LinkRegisters[cllr_idx]; + + /* Repeat for all node registers */ + while (contextnode_reg_counter != RegisterNumber) + { + /* Check if node field is dynamic */ + if ((cllr_mask & update_link[contextnode_reg_counter]) == 0U) + { + /* Format the node according to unused registers */ + DMA_List_FormatNode(current_node, contextnode_reg_counter, RegisterNumber, NODE_STATIC_FORMAT); + + /* Update node field */ + current_node->LinkRegisters[contextnode_reg_counter] = context_node->LinkRegisters[contextnode_reg_counter]; + } + + /* Increment context node number register counter */ + contextnode_reg_counter++; + } + + /* Update node information */ + MODIFY_REG(current_node->NodeInfo, NODE_CLLR_IDX, ((RegisterNumber - 1U) << NODE_CLLR_IDX_POS)); +} + +/** + * @brief Format the node according to unused registers. + * @param pNode : Pointer to a DMA_NodeTypeDef structure that contains linked-list node registers + * configurations. + * @param RegisterIdx : The first register index to be formatted. + * @param RegisterNumber : The number of node registers. + * @param Format : The format type. + * @retval None. + */ +static void DMA_List_FormatNode(DMA_NodeTypeDef *const pNode, + uint32_t RegisterIdx, + uint32_t RegisterNumber, + uint32_t Format) +{ + if (Format == NODE_DYNAMIC_FORMAT) + { + /* Repeat for all registers to be formatted */ + for (uint32_t reg_idx = RegisterIdx; reg_idx < (RegisterNumber - 1U); reg_idx++) + { + pNode->LinkRegisters[reg_idx] = pNode->LinkRegisters[reg_idx + 1U]; + } + } + else + { + /* Repeat for all registers to be formatted */ + for (uint32_t reg_idx = (RegisterNumber - 2U); reg_idx > RegisterIdx; reg_idx--) + { + pNode->LinkRegisters[reg_idx] = pNode->LinkRegisters[reg_idx - 1U]; + } + } +} + +/** + * @brief Clear unused register fields. + * @param pNode : Pointer to a DMA_NodeTypeDef structure that contains linked-list node registers + * configurations. + * @param FirstUnusedField : The first unused field to be cleared. + * @retval None. + */ +static void DMA_List_ClearUnusedFields(DMA_NodeTypeDef *const pNode, + uint32_t FirstUnusedField) +{ + /* Repeat for all unused fields */ + for (uint32_t reg_idx = FirstUnusedField; reg_idx < NODE_MAXIMUM_SIZE; reg_idx++) + { + pNode->LinkRegisters[reg_idx] = 0U; + } +} + +/** + * @brief Update CLLR for all dynamic queue nodes. + * @param pQList : Pointer to a DMA_QListTypeDef structure that contains queue information. + * @param LastNode_IsCircular : The first circular node is the last queue node or not. + * @retval None. + */ +static void DMA_List_UpdateDynamicQueueNodesCLLR(DMA_QListTypeDef const *const pQList, + uint32_t LastNode_IsCircular) +{ + uint32_t previous_cllr_offset; + uint32_t current_cllr_offset = 0U; + uint32_t previousnode_addr; + uint32_t currentnode_addr = (uint32_t)pQList->Head; + uint32_t cllr_mask; + uint32_t node_idx = 0U; + + /* Repeat for all register nodes */ + while (node_idx < pQList->NodeNumber) + { + /* Get head node address */ + if (node_idx == 0U) + { + /* Get current node information */ + current_cllr_offset = (((DMA_NodeTypeDef *)currentnode_addr)->NodeInfo & NODE_CLLR_IDX) >> NODE_CLLR_IDX_POS; + } + /* Calculate nodes addresses */ + else + { + /* Get previous node information */ + previousnode_addr = currentnode_addr; + previous_cllr_offset = current_cllr_offset; + + /* Get current node information */ + currentnode_addr = (((DMA_NodeTypeDef *)(previousnode_addr))->LinkRegisters[previous_cllr_offset] & DMA_CLLR_LA) + + ((uint32_t)pQList->Head & DMA_CLBAR_LBA); + current_cllr_offset = (((DMA_NodeTypeDef *)currentnode_addr)->NodeInfo & NODE_CLLR_IDX) >> NODE_CLLR_IDX_POS; + + /* Calculate CLLR register value to be updated */ + cllr_mask = (((DMA_NodeTypeDef *)currentnode_addr)->LinkRegisters[current_cllr_offset] & ~DMA_CLLR_LA) | + (((DMA_NodeTypeDef *)(previousnode_addr))->LinkRegisters[previous_cllr_offset] & DMA_CLLR_LA); + + /* Set new CLLR value to previous node */ + ((DMA_NodeTypeDef *)(previousnode_addr))->LinkRegisters[previous_cllr_offset] = cllr_mask; + } + + /* Increment node index */ + node_idx++; + } + + /* Check queue circularity */ + if (pQList->FirstCircularNode != 0U) + { + /* First circular queue is not last queue node */ + if (LastNode_IsCircular == 0U) + { + /* Get CLLR node information */ + DMA_List_GetCLLRNodeInfo(((DMA_NodeTypeDef *)currentnode_addr), &cllr_mask, NULL); + + /* Update CLLR register for last circular node */ + ((DMA_NodeTypeDef *)currentnode_addr)->LinkRegisters[current_cllr_offset] = + ((uint32_t)pQList->Head & DMA_CLLR_LA) | cllr_mask; + } + /* First circular queue is last queue node */ + else + { + /* Disable CLLR updating */ + ((DMA_NodeTypeDef *)currentnode_addr)->LinkRegisters[current_cllr_offset] &= ~DMA_CLLR_ULL; + } + } + else + { + /* Clear CLLR register for last node */ + ((DMA_NodeTypeDef *)currentnode_addr)->LinkRegisters[current_cllr_offset] = 0U; + } +} + +/** + * @brief Update CLLR for all static queue nodes. + * @param pQList : Pointer to a DMA_QListTypeDef structure that contains queue information. + * @param operation : The operation type. + * @retval None. + */ +static void DMA_List_UpdateStaticQueueNodesCLLR(DMA_QListTypeDef const *const pQList, + uint32_t operation) +{ + uint32_t currentnode_addr = (uint32_t)pQList->Head; + uint32_t current_cllr_offset = ((uint32_t)pQList->Head->NodeInfo & NODE_CLLR_IDX) >> NODE_CLLR_IDX_POS; + uint32_t cllr_default_offset; + uint32_t cllr_default_mask; + uint32_t cllr_mask; + uint32_t node_idx = 0U; + + /* Get CLLR node information */ + DMA_List_GetCLLRNodeInfo(pQList->Head, &cllr_default_mask, &cllr_default_offset); + + /* Repeat for all register nodes (Bypass last queue node) */ + while (node_idx < pQList->NodeNumber) + { + if (operation == UPDATE_CLLR_POSITION) + { + /* Get CLLR value */ + cllr_mask = ((DMA_NodeTypeDef *)currentnode_addr)->LinkRegisters[current_cllr_offset]; + } + else + { + /* Calculate CLLR value */ + cllr_mask = (((DMA_NodeTypeDef *)currentnode_addr)->LinkRegisters[current_cllr_offset] & DMA_CLLR_LA) | + cllr_default_mask; + } + + /* Set new CLLR value to default position */ + if ((node_idx == (pQList->NodeNumber - 1U)) && (pQList->FirstCircularNode == NULL)) + { + ((DMA_NodeTypeDef *)(currentnode_addr))->LinkRegisters[cllr_default_offset] = 0U; + } + else + { + ((DMA_NodeTypeDef *)(currentnode_addr))->LinkRegisters[cllr_default_offset] = cllr_mask; + } + + /* Update current node address with next node address */ + currentnode_addr = (currentnode_addr & DMA_CLBAR_LBA) | (cllr_mask & DMA_CLLR_LA); + + /* Update current CLLR offset with next CLLR offset */ + current_cllr_offset = (((DMA_NodeTypeDef *)currentnode_addr)->NodeInfo & NODE_CLLR_IDX) >> NODE_CLLR_IDX_POS; + + /* Increment node index */ + node_idx++; + } +} + +/** + * @brief Clean linked-list queue variable. + * @param pQList : Pointer to a DMA_QListTypeDef structure that contains queue information. + * @retval None. + */ +static void DMA_List_CleanQueue(DMA_QListTypeDef *const pQList) +{ + /* Clear head node */ + pQList->Head = NULL; + + /* Clear first circular queue node */ + pQList->FirstCircularNode = NULL; + + /* Reset node number */ + pQList->NodeNumber = 0U; + + /* Reset queue state */ + pQList->State = HAL_DMA_QUEUE_STATE_RESET; + + /* Reset queue error code */ + pQList->ErrorCode = HAL_DMA_QUEUE_ERROR_NONE; + + /* Reset queue type */ + pQList->Type = QUEUE_TYPE_STATIC; +} +/** + * @} + */ + +#endif /* HAL_DMA_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dts.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dts.c new file mode 100644 index 0000000000..e69a103e3b --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_dts.c @@ -0,0 +1,1091 @@ +/** + ********************************************************************************************************************** + * @file stm32h5xx_hal_dts.c + * @author MCD Application Team + * @brief DTS HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the DTS peripheral: + * + Initialization and de-initialization functions + * + Start/Stop operation functions in polling mode. + * + Start/Stop operation functions in interrupt mode. + * + Peripheral Control functions + * + Peripheral State functions + * + ********************************************************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ********************************************************************************************************************** + @verbatim + ====================================================================================================================== + ##### DTS Peripheral features ##### + ====================================================================================================================== + + [..] + The STM32h5xx device family integrate one DTS sensor interface that converts the temperature into a square wave + which frequency is proportional to the temperature. + + (+) Temperature window comparator feature: + The DTS allows defining the high and low threshold that will be used for temperature comparison. + If the temperature data is equal or higher than the high threshold, or equal or lower than the low threshold, + an interrupt is generated and the corresponding flag. + + (+) Synchronous interrupts: + A global interrupt output line is available on the DTS block. The interrupt can be generated + at the end of measurement and/or when the measurement result is equal/higher or equal/lower than + a predefined threshold. + + (+) Asynchronous wakeup: + The DTS block provides an asynchronous interrupt line. It is used only when the LSE is selected as reference + clock. This line can generate a signal that wakes up the system from Sleep and stop mode at the end of + measurement and/or when the measurement result is equal/higher or equal/lower than a + predefined threshold. + + (+) Trigger inputs: + The temperature measurement can be triggered either by software or by an external event + as well as lowpower timer. + + (+) Measurement modes: + (++) Quick measure : measure without a calibration when a high precision is not required. + (++) Slow measure : measure with a calibration used when a high precision is required. + + (+) Sampling time: + The sampling time can be used to increase temperature measurement precision. + + (+) Prescaler: + When a calibration is ongoing, the counter clock must be slower than 1 MHz. This is + achieved by the PCLK clock prescaler embedded in the temperature sensor. + + (+) Operating Modes: + + (++) PCLK only : The temperature sensor registers can be accessed. The interface can consequently be + reconfigured and the measurement sequence is performed using PCLK clock. + + (++) PCLK and LSE : The temperature sensor registers can be accessed. The interface can consequently be + reconfigured and the measurement sequence is performed using the LSE clock. + + (++) LSE only : The registers cannot be accessed. The measurement can be performed using the LSE + clock This mode is used to exit from Sleep and stop mode by using hardware triggers + and the asynchronous interrupt line. + (+) Calibration: + The temperature sensor must run the calibration prior to any frequency measurement. The calibration is + performed automatically when the temperature measurement is triggered except for quick measurement mode. + + (+) Low power modes: + (++) Sleep mode: only works in LSE mode. + (++) Stop mode: only works in LSE mode. + + ====================================================================================================================== + ##### How to use this driver ##### + ====================================================================================================================== + [..] + This driver provides functions to configure and program the DTS instances of STM32H5xx devices. + + To use the DTS, perform the following steps: + + (+) Initialize the DTS low level resources by implementing the HAL_DTS_MspInit(): + + (++) If required enable the DTS interrupt by configuring and enabling EXTI line in Interrupt mode After that + enable the DTS interrupt vector using HAL_NVIC_EnableIRQ() function. + + (+) Configure the DTS using HAL_DTS_Init() function: + + (++) Select the quick measure option + (++) Select the reference clock. + (++) Select the trigger input. + (++) Select the sampling time. + (++) Select the high speed clock ratio divider. + (++) Select the low threshold + (++) Select the high threshold + + + (+) Use HAL_DTS_Start() to enable and start the DTS sensor in polling mode. + + (+) Use HAL_DTS_Start_IT() to enable and start the DTS sensor in interrupt mode. + + (+) Use HAL_DTS_GetTemperature() to get temperature from DTS. + + (+) Use HAL_DTS_Stop() to disable and stop the DTS sensor in polling mode. + + (+) Use HAL_DTS_Stop_IT() to disable and stop the DTS sensor in interrupt mode. + + (+) De-initialize the DTS using HAL_DTS_DeInit() function. + + *** Callback and interrupts *** + ============================================= + [..] + When the compilation flag USE_HAL_DTS_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. + + (+) Implement the weak function HAL_DTS_EndCallback() to get a callback at the end of the temperature measurement. + (+) Implement the weak function HAL_DTS_HighCallback() to get a callback when the temperature + exceed the high threshold. + (+) Implement the weak function HAL_DTS_LowCallback() to get a callback when the temperature + go down the low threshold. + (+) Implement the weak function HAL_DTS_AsyncEndCallback() to get a callback at the end + of an asynchronous temperature measurement. + (+) Implement the weak function HAL_DTS_AsyncHighCallback() to get a callback when the temperature + exceed the high threshold in an asynchronous measurement. + (+) Implement the weak function HAL_DTS_AsyncLowCallback() to get a callback when the temperature + go down the low threshold in an asynchronous measurement. + + [..] + The compilation flag USE_HAL_DTS_REGISTER_CALLBACKS, when set to 1, allows the user to configure dynamically + the driver callbacks. + + *** State *** + ============================================= + [..] + The driver permits to get in run time the status of the peripheral. + + (+) Use HAL_DTS_GetState() to get the state of the DTS. + + @endverbatim + ********************************************************************************************************************** + */ + +/* Includes ----------------------------------------------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +#ifdef HAL_DTS_MODULE_ENABLED + +#if defined(DTS) + +/** @defgroup DTS DTS + * @brief DTS HAL module driver + * @{ + */ + +/* Private typedef ---------------------------------------------------------------------------------------------------*/ +/* Private define ----------------------------------------------------------------------------------------------------*/ +/** @addtogroup DTS_Private_Constants + * @{ + */ + +/* @brief Delay for DTS startup time + * @note Delay required to get ready for DTS Block. + * @note Unit: ms + */ +#define DTS_DELAY_STARTUP (1UL) + +/* @brief DTS measure ready flag time out value. + * @note Maximal measurement time is when LSE is selected as ref_clock and + * maximal sampling time is used, taking calibration into account this + * is equivalent to ~620 us. Use 5 ms as arbitrary timeout + * @note Unit: ms + */ +#define TS_TIMEOUT_MS (5UL) + +/* @brief DTS factory temperatures + * @note Unit: degree Celsius + */ +#define DTS_FACTORY_TEMPERATURE1 (30UL) +#define DTS_FACTORY_TEMPERATURE2 (130UL) + +/** + * @} + */ + +/* Private macro -----------------------------------------------------------------------------------------------------*/ +/* Private variables -------------------------------------------------------------------------------------------------*/ +/* Private function prototypes ---------------------------------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------------------------------------------------*/ +/** @defgroup DTS_Exported_Functions DTS Exported Functions + * @{ + */ + +/** @defgroup DTS_Exported_Functions_Group1 Initialization/de-initialization functions + * @brief Initialization and de-initialization functions. + * +@verbatim + ======================================================================================================================= + ##### Initialization and de-initialization functions ##### + ======================================================================================================================= + [..] This section provides functions to initialize and de-initialize DTS + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the DTS according to the specified + * parameters in the DTS_InitTypeDef and initialize the associated handle. + * @param hdts DTS handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DTS_Init(DTS_HandleTypeDef *hdts) +{ + /* Check the DTS handle allocation */ + if (hdts == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DTS_ALL_INSTANCE(hdts->Instance)); + assert_param(IS_DTS_QUICKMEAS(hdts->Init.QuickMeasure)); + assert_param(IS_DTS_REFCLK(hdts->Init.RefClock)); + assert_param(IS_DTS_TRIGGERINPUT(hdts->Init.TriggerInput)); + assert_param(IS_DTS_SAMPLINGTIME(hdts->Init.SamplingTime)); + assert_param(IS_DTS_THRESHOLD(hdts->Init.HighThreshold)); + assert_param(IS_DTS_THRESHOLD(hdts->Init.LowThreshold)); + + if (hdts->State == HAL_DTS_STATE_RESET) + { +#if (USE_HAL_DTS_REGISTER_CALLBACKS == 1U) + /* Reset the DTS callback to the legacy weak callbacks */ + hdts->EndCallback = HAL_DTS_EndCallback; /* End measure Callback */ + hdts->LowCallback = HAL_DTS_LowCallback; /* low threshold Callback */ + hdts->HighCallback = HAL_DTS_HighCallback; /* high threshold Callback */ + hdts->AsyncEndCallback = HAL_DTS_AsyncEndCallback; /* Asynchronous end of measure Callback */ + hdts->AsyncLowCallback = HAL_DTS_AsyncLowCallback; /* Asynchronous low threshold Callback */ + hdts->AsyncHighCallback = HAL_DTS_AsyncHighCallback; /* Asynchronous high threshold Callback */ + + if (hdts->MspInitCallback == NULL) + { + hdts->MspInitCallback = HAL_DTS_MspInit; + } + + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + hdts->MspInitCallback(hdts); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + HAL_DTS_MspInit(hdts); +#endif /* USE_HAL_DTS_REGISTER_CALLBACKS */ + } + + /* Change the DTS state */ + hdts->State = HAL_DTS_STATE_BUSY; + + /* Check ramp coefficient */ + if (hdts->Instance->RAMPVALR == 0UL) + { + return HAL_ERROR; + } + + /* Check factory calibration temperature */ + if (hdts->Instance->T0VALR1 == 0UL) + { + return HAL_ERROR; + } + + /* Check Quick Measure option is enabled or disabled */ + if (hdts->Init.QuickMeasure == DTS_QUICKMEAS_DISABLE) + { + /* Check Reference clock selection */ + if (hdts->Init.RefClock == DTS_REFCLKSEL_PCLK) + { + assert_param(IS_DTS_DIVIDER_RATIO_NUMBER(hdts->Init.Divider)); + } + /* Quick measurement mode disabled */ + CLEAR_BIT(hdts->Instance->CFGR1, DTS_CFGR1_Q_MEAS_OPT); + } + else + { + /* DTS_QUICKMEAS_ENABLE shall be used only when the LSE clock is + selected as reference clock */ + if (hdts->Init.RefClock != DTS_REFCLKSEL_LSE) + { + return HAL_ERROR; + } + + /* Quick measurement mode enabled - no calibration needed */ + SET_BIT(hdts->Instance->CFGR1, DTS_CFGR1_Q_MEAS_OPT); + } + + /* set the DTS clk source */ + if (hdts->Init.RefClock == DTS_REFCLKSEL_LSE) + { + SET_BIT(hdts->Instance->CFGR1, DTS_CFGR1_REFCLK_SEL); + } + else + { + CLEAR_BIT(hdts->Instance->CFGR1, DTS_CFGR1_REFCLK_SEL); + } + + MODIFY_REG(hdts->Instance->CFGR1, DTS_CFGR1_HSREF_CLK_DIV, (hdts->Init.Divider << DTS_CFGR1_HSREF_CLK_DIV_Pos)); + MODIFY_REG(hdts->Instance->CFGR1, DTS_CFGR1_TS1_SMP_TIME, hdts->Init.SamplingTime); + MODIFY_REG(hdts->Instance->CFGR1, DTS_CFGR1_TS1_INTRIG_SEL, hdts->Init.TriggerInput); + MODIFY_REG(hdts->Instance->ITR1, DTS_ITR1_TS1_HITTHD, (hdts->Init.HighThreshold << DTS_ITR1_TS1_HITTHD_Pos)); + MODIFY_REG(hdts->Instance->ITR1, DTS_ITR1_TS1_LITTHD, hdts->Init.LowThreshold); + + /* Change the DTS state */ + hdts->State = HAL_DTS_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitialize the DTS peripheral. + * @note Deinitialization cannot be performed if the DTS configuration is locked. + * To unlock the configuration, perform a system reset. + * @param hdts DTS handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DTS_DeInit(DTS_HandleTypeDef *hdts) +{ + /* Check the DTS handle allocation */ + if (hdts == NULL) + { + return HAL_ERROR; + } + + /* Check the parameter */ + assert_param(IS_DTS_ALL_INSTANCE(hdts->Instance)); + + /* Set DTS_CFGR register to reset value */ + CLEAR_REG(hdts->Instance->CFGR1); + +#if (USE_HAL_DTS_REGISTER_CALLBACKS == 1U) + if (hdts->MspDeInitCallback == NULL) + { + hdts->MspDeInitCallback = HAL_DTS_MspDeInit; + } + + /* DeInit the low level hardware: CLOCK, NVIC.*/ + hdts->MspDeInitCallback(hdts); +#else + /* DeInit the low level hardware: CLOCK, NVIC.*/ + HAL_DTS_MspDeInit(hdts); +#endif /* USE_HAL_DTS_REGISTER_CALLBACKS */ + + hdts->State = HAL_DTS_STATE_RESET; + + return HAL_OK; +} + +/** + * @brief Initialize the DTS MSP. + * @param hdts DTS handle + * @retval None + */ +__weak void HAL_DTS_MspInit(DTS_HandleTypeDef *hdts) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdts); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_DTS_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitialize the DTS MSP. + * @param hdts DTS handle + * @retval None + */ +__weak void HAL_DTS_MspDeInit(DTS_HandleTypeDef *hdts) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdts); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_DTS_MspDeInit could be implemented in the user file + */ +} + +#if (USE_HAL_DTS_REGISTER_CALLBACKS == 1U) +/** + * @brief Register a user DTS callback to be used instead of the weak predefined callback. + * @param hdts DTS handle. + * @param CallbackID ID of the callback to be registered. + * This parameter can be one of the following values: + * @arg @ref HAL_DTS_MEAS_COMPLETE_CB_ID measure complete callback ID. + * @arg @ref HAL_DTS_ASYNC_MEAS_COMPLETE_CB_ID asynchronous measure complete callback ID. + * @arg @ref HAL_DTS_LOW_THRESHOLD_CB_ID low threshold detection callback ID. + * @arg @ref HAL_DTS_ASYNC_LOW_THRESHOLD_CB_ID asynchronous low threshold detection callback ID. + * @arg @ref HAL_DTS_HIGH_THRESHOLD_CB_ID high threshold detection callback ID. + * @arg @ref HAL_DTS_ASYNC_HIGH_THRESHOLD_CB_ID asynchronous high threshold detection callback ID. + * @arg @ref HAL_DTS_MSPINIT_CB_ID MSP init callback ID. + * @arg @ref HAL_DTS_MSPDEINIT_CB_ID MSP de-init callback ID. + * @param pCallback pointer to the callback function. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DTS_RegisterCallback(DTS_HandleTypeDef *hdts, + HAL_DTS_CallbackIDTypeDef CallbackID, + pDTS_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check parameters */ + if (pCallback == NULL) + { + /* Update status */ + status = HAL_ERROR; + } + else + { + if (hdts->State == HAL_DTS_STATE_READY) + { + switch (CallbackID) + { + case HAL_DTS_MEAS_COMPLETE_CB_ID : + hdts->EndCallback = pCallback; + break; + case HAL_DTS_ASYNC_MEAS_COMPLETE_CB_ID : + hdts->AsyncEndCallback = pCallback; + break; + case HAL_DTS_LOW_THRESHOLD_CB_ID : + hdts->LowCallback = pCallback; + break; + case HAL_DTS_ASYNC_LOW_THRESHOLD_CB_ID : + hdts->AsyncLowCallback = pCallback; + break; + case HAL_DTS_HIGH_THRESHOLD_CB_ID : + hdts->HighCallback = pCallback; + break; + case HAL_DTS_ASYNC_HIGH_THRESHOLD_CB_ID : + hdts->AsyncHighCallback = pCallback; + break; + case HAL_DTS_MSPINIT_CB_ID : + hdts->MspInitCallback = pCallback; + break; + case HAL_DTS_MSPDEINIT_CB_ID : + hdts->MspDeInitCallback = pCallback; + break; + default : + /* Update status */ + status = HAL_ERROR; + break; + } + } + else if (hdts->State == HAL_DTS_STATE_RESET) + { + switch (CallbackID) + { + case HAL_DTS_MSPINIT_CB_ID : + hdts->MspInitCallback = pCallback; + break; + case HAL_DTS_MSPDEINIT_CB_ID : + hdts->MspDeInitCallback = pCallback; + break; + default : + /* Update status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update status */ + status = HAL_ERROR; + } + } + + /* Return function status */ + return status; +} + +/** + * @brief Unregister a user DTS callback. + * DTS callback is redirected to the weak predefined callback. + * @param hdts DTS handle. + * @param CallbackID ID of the callback to be unregistered. + * This parameter can be one of the following values: + * @arg @ref HAL_DTS_MEAS_COMPLETE_CB_ID measure complete callback ID. + * @arg @ref HAL_DTS_ASYNC_MEAS_COMPLETE_CB_ID asynchronous measure complete callback ID. + * @arg @ref HAL_DTS_LOW_THRESHOLD_CB_ID low threshold detection callback ID. + * @arg @ref HAL_DTS_ASYNC_LOW_THRESHOLD_CB_ID asynchronous low threshold detection callback ID. + * @arg @ref HAL_DTS_HIGH_THRESHOLD_CB_ID high threshold detection callback ID. + * @arg @ref HAL_DTS_ASYNC_HIGH_THRESHOLD_CB_ID asynchronous high threshold detection callback ID. + * @arg @ref HAL_DTS_MSPINIT_CB_ID MSP init callback ID. + * @arg @ref HAL_DTS_MSPDEINIT_CB_ID MSP de-init callback ID. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_DTS_UnRegisterCallback(DTS_HandleTypeDef *hdts, + HAL_DTS_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (hdts->State == HAL_DTS_STATE_READY) + { + switch (CallbackID) + { + case HAL_DTS_MEAS_COMPLETE_CB_ID : + hdts->EndCallback = HAL_DTS_EndCallback; + break; + case HAL_DTS_ASYNC_MEAS_COMPLETE_CB_ID : + hdts->AsyncEndCallback = HAL_DTS_AsyncEndCallback; + break; + case HAL_DTS_LOW_THRESHOLD_CB_ID : + hdts->LowCallback = HAL_DTS_LowCallback; + break; + case HAL_DTS_ASYNC_LOW_THRESHOLD_CB_ID : + hdts->AsyncLowCallback = HAL_DTS_AsyncLowCallback; + break; + case HAL_DTS_HIGH_THRESHOLD_CB_ID : + hdts->HighCallback = HAL_DTS_HighCallback; + break; + case HAL_DTS_ASYNC_HIGH_THRESHOLD_CB_ID : + hdts->AsyncHighCallback = HAL_DTS_AsyncHighCallback; + break; + case HAL_DTS_MSPINIT_CB_ID : + hdts->MspInitCallback = HAL_DTS_MspInit; + break; + case HAL_DTS_MSPDEINIT_CB_ID : + hdts->MspDeInitCallback = HAL_DTS_MspDeInit; + break; + default : + /* Update status */ + status = HAL_ERROR; + break; + } + } + else if (hdts->State == HAL_DTS_STATE_RESET) + { + switch (CallbackID) + { + case HAL_DTS_MSPINIT_CB_ID : + hdts->MspInitCallback = HAL_DTS_MspInit; + break; + case HAL_DTS_MSPDEINIT_CB_ID : + hdts->MspDeInitCallback = HAL_DTS_MspDeInit; + break; + default : + /* Update status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update status */ + status = HAL_ERROR; + } + + /* Return function status */ + return status; +} +#endif /* USE_HAL_DTS_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup DTS_Exported_Functions_Group2 Start-Stop operation functions + * @brief Start-Stop operation functions. + * +@verbatim + ======================================================================================================================= + ##### DTS Start Stop operation functions ##### + ======================================================================================================================= + [..] This section provides functions allowing to: + (+) Start a DTS Sensor without interrupt. + (+) Stop a DTS Sensor without interrupt. + (+) Start a DTS Sensor with interrupt generation. + (+) Stop a DTS Sensor with interrupt generation. + +@endverbatim + * @{ + */ + +/** + * @brief Start the DTS sensor. + * @param hdts DTS handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DTS_Start(DTS_HandleTypeDef *hdts) +{ + uint32_t Ref_Time; + + /* Check the DTS handle allocation */ + if (hdts == NULL) + { + return HAL_ERROR; + } + + if (hdts->State == HAL_DTS_STATE_READY) + { + hdts->State = HAL_DTS_STATE_BUSY; + + /* Enable DTS sensor */ + __HAL_DTS_ENABLE(hdts); + + /* Get Start Tick*/ + Ref_Time = HAL_GetTick(); + + /* Wait till TS1_RDY flag is set */ + while (__HAL_DTS_GET_FLAG(hdts, DTS_FLAG_TS1_RDY) == RESET) + { + if ((HAL_GetTick() - Ref_Time) > DTS_DELAY_STARTUP) + { + return HAL_TIMEOUT; + } + } + + if (__HAL_DTS_GET_TRIGGER(hdts) == DTS_TRIGGER_HW_NONE) + { + /* Start continuous measures */ + SET_BIT(hdts->Instance->CFGR1, DTS_CFGR1_TS1_START); + + /* Ensure start is taken into account */ + HAL_Delay(TS_TIMEOUT_MS); + } + + hdts->State = HAL_DTS_STATE_READY; + } + else + { + return HAL_BUSY; + } + + return HAL_OK; +} + +/** + * @brief Stop the DTS Sensor. + * @param hdts DTS handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DTS_Stop(DTS_HandleTypeDef *hdts) +{ + /* Check the DTS handle allocation */ + if (hdts == NULL) + { + return HAL_ERROR; + } + + if (hdts->State == HAL_DTS_STATE_READY) + { + hdts->State = HAL_DTS_STATE_BUSY; + + if (__HAL_DTS_GET_TRIGGER(hdts) == DTS_TRIGGER_HW_NONE) + { + CLEAR_BIT(hdts->Instance->CFGR1, DTS_CFGR1_TS1_START); + } + + /* Disable the selected DTS sensor */ + __HAL_DTS_DISABLE(hdts); + + hdts->State = HAL_DTS_STATE_READY; + } + else + { + return HAL_BUSY; + } + + return HAL_OK; +} + +/** + * @brief Enable the interrupt(s) and start the DTS sensor + * @param hdts DTS handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DTS_Start_IT(DTS_HandleTypeDef *hdts) +{ + uint32_t Ref_Time; + + /* Check the DTS handle allocation */ + if (hdts == NULL) + { + return HAL_ERROR; + } + + if (hdts->State == HAL_DTS_STATE_READY) + { + hdts->State = HAL_DTS_STATE_BUSY; + + /* On Asynchronous mode enable the asynchronous IT */ + if (hdts->Init.RefClock == DTS_REFCLKSEL_LSE) + { + __HAL_DTS_ENABLE_IT(hdts, DTS_IT_TS1_AITE | DTS_IT_TS1_AITL | DTS_IT_TS1_AITH); + } + else + { + /* Enable the IT(s) */ + __HAL_DTS_ENABLE_IT(hdts, DTS_IT_TS1_ITE | DTS_IT_TS1_ITL | DTS_IT_TS1_ITH); + } + + /* Enable the selected DTS sensor */ + __HAL_DTS_ENABLE(hdts); + + /* Get Start Tick*/ + Ref_Time = HAL_GetTick(); + + /* Wait till TS1_RDY flag is set */ + while (__HAL_DTS_GET_FLAG(hdts, DTS_FLAG_TS1_RDY) == RESET) + { + if ((HAL_GetTick() - Ref_Time) > DTS_DELAY_STARTUP) + { + return HAL_TIMEOUT; + } + } + + if (__HAL_DTS_GET_TRIGGER(hdts) == DTS_TRIGGER_HW_NONE) + { + /* Start continuous measures */ + SET_BIT(hdts->Instance->CFGR1, DTS_CFGR1_TS1_START); + + /* Ensure start is taken into account */ + HAL_Delay(TS_TIMEOUT_MS); + } + + hdts->State = HAL_DTS_STATE_READY; + } + else + { + return HAL_BUSY; + } + + return HAL_OK; +} + +/** + * @brief Disable the interrupt(s) and stop the DTS sensor. + * @param hdts DTS handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DTS_Stop_IT(DTS_HandleTypeDef *hdts) +{ + /* Check the DTS handle allocation */ + if (hdts == NULL) + { + return HAL_ERROR; + } + + if (hdts->State == HAL_DTS_STATE_READY) + { + hdts->State = HAL_DTS_STATE_BUSY; + + /* On Asynchronous mode disable the asynchronous IT */ + if (hdts->Init.RefClock == DTS_REFCLKSEL_LSE) + { + __HAL_DTS_DISABLE_IT(hdts, DTS_IT_TS1_AITE | DTS_IT_TS1_AITL | DTS_IT_TS1_AITH); + } + else + { + /* Disable the IT(s) */ + __HAL_DTS_DISABLE_IT(hdts, DTS_IT_TS1_ITE | DTS_IT_TS1_ITL | DTS_IT_TS1_ITH); + } + + if (__HAL_DTS_GET_TRIGGER(hdts) == DTS_TRIGGER_HW_NONE) + { + CLEAR_BIT(hdts->Instance->CFGR1, DTS_CFGR1_TS1_START); + } + + /* Disable the selected DTS sensor */ + __HAL_DTS_DISABLE(hdts); + + hdts->State = HAL_DTS_STATE_READY; + } + else + { + return HAL_BUSY; + } + + return HAL_OK; +} + +/** + * @brief Get temperature from DTS + * @param hdts DTS handle + * @param Temperature Temperature in deg C + * @note This function retrieves latest available measure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DTS_GetTemperature(DTS_HandleTypeDef *hdts, int32_t *Temperature) +{ + uint32_t freq_meas; + uint32_t samples; + uint32_t t0_temp; + uint32_t t0_freq; + uint32_t ramp_coeff; + + if (hdts->State == HAL_DTS_STATE_READY) + { + hdts->State = HAL_DTS_STATE_BUSY; + + /* Get the total number of samples */ + samples = (hdts->Instance->DR & DTS_DR_TS1_MFREQ); + + if ((hdts->Init.SamplingTime == 0UL) || (samples == 0UL)) + { + hdts->State = HAL_DTS_STATE_READY; + return HAL_ERROR; + } + + if ((hdts->Init.RefClock) == DTS_REFCLKSEL_LSE) + { + /* Measured frequency On Hz */ + freq_meas = (LSE_VALUE * samples) / (hdts->Init.SamplingTime >> DTS_CFGR1_TS1_SMP_TIME_Pos); + } + else + { + /* Measured frequency On Hz */ + freq_meas = (HAL_RCC_GetPCLK1Freq() * (hdts->Init.SamplingTime >> DTS_CFGR1_TS1_SMP_TIME_Pos)) / samples; + } + + /* Read factory settings */ + t0_temp = hdts->Instance->T0VALR1 >> DTS_T0VALR1_TS1_T0_Pos; + + if (t0_temp == 0UL) + { + t0_temp = DTS_FACTORY_TEMPERATURE1; /* 30 deg C */ + } + else if (t0_temp == 1UL) + { + t0_temp = DTS_FACTORY_TEMPERATURE2; /* 130 deg C */ + } + else + { + hdts->State = HAL_DTS_STATE_READY; + return HAL_ERROR; + } + + t0_freq = (hdts->Instance->T0VALR1 & DTS_T0VALR1_TS1_FMT0) * 100UL; /* Hz */ + + ramp_coeff = hdts->Instance->RAMPVALR & DTS_RAMPVALR_TS1_RAMP_COEFF; /* deg C/Hz */ + + if (ramp_coeff == 0UL) + { + hdts->State = HAL_DTS_STATE_READY; + return HAL_ERROR; + } + + /* Figure out the temperature deg C */ + *Temperature = (int32_t)t0_temp + (((int32_t)freq_meas - (int32_t)t0_freq) / (int32_t)ramp_coeff); + + hdts->State = HAL_DTS_STATE_READY; + } + else + { + return HAL_BUSY; + } + + return HAL_OK; +} + +/** + * @brief DTS sensor IRQ Handler. + * @param hdts DTS handle + * @retval None + */ +void HAL_DTS_IRQHandler(DTS_HandleTypeDef *hdts) +{ + /* Check end of measure Asynchronous IT */ + if ((__HAL_DTS_GET_FLAG(hdts, DTS_FLAG_TS1_AITE)) != RESET) + { + __HAL_DTS_CLEAR_FLAG(hdts, DTS_FLAG_TS1_AITE); + +#if (USE_HAL_DTS_REGISTER_CALLBACKS == 1U) + hdts->AsyncEndCallback(hdts); +#else + HAL_DTS_AsyncEndCallback(hdts); +#endif /* USE_HAL_DTS_REGISTER_CALLBACKS */ + } + + /* Check low threshold Asynchronous IT */ + if ((__HAL_DTS_GET_FLAG(hdts, DTS_FLAG_TS1_AITL)) != RESET) + { + __HAL_DTS_CLEAR_FLAG(hdts, DTS_FLAG_TS1_AITL); + +#if (USE_HAL_DTS_REGISTER_CALLBACKS == 1U) + hdts->AsyncLowCallback(hdts); +#else + HAL_DTS_AsyncLowCallback(hdts); +#endif /* USE_HAL_DTS_REGISTER_CALLBACKS */ + } + + /* Check high threshold Asynchronous IT */ + if ((__HAL_DTS_GET_FLAG(hdts, DTS_FLAG_TS1_AITH)) != RESET) + { + __HAL_DTS_CLEAR_FLAG(hdts, DTS_FLAG_TS1_AITH); + +#if (USE_HAL_DTS_REGISTER_CALLBACKS == 1U) + hdts->AsyncHighCallback(hdts); +#else + HAL_DTS_AsyncHighCallback(hdts); +#endif /* USE_HAL_DTS_REGISTER_CALLBACKS */ + } + + /* Check end of measure IT */ + if ((__HAL_DTS_GET_FLAG(hdts, DTS_FLAG_TS1_ITE)) != RESET) + { + __HAL_DTS_CLEAR_FLAG(hdts, DTS_FLAG_TS1_ITE); + +#if (USE_HAL_DTS_REGISTER_CALLBACKS == 1U) + hdts->EndCallback(hdts); +#else + HAL_DTS_EndCallback(hdts); +#endif /* USE_HAL_DTS_REGISTER_CALLBACKS */ + } + + /* Check low threshold IT */ + if ((__HAL_DTS_GET_FLAG(hdts, DTS_FLAG_TS1_ITL)) != RESET) + { + __HAL_DTS_CLEAR_FLAG(hdts, DTS_FLAG_TS1_ITL); + +#if (USE_HAL_DTS_REGISTER_CALLBACKS == 1U) + hdts->LowCallback(hdts); +#else + HAL_DTS_LowCallback(hdts); +#endif /* USE_HAL_DTS_REGISTER_CALLBACKS */ + } + + /* Check high threshold IT */ + if ((__HAL_DTS_GET_FLAG(hdts, DTS_FLAG_TS1_ITH)) != RESET) + { + __HAL_DTS_CLEAR_FLAG(hdts, DTS_FLAG_TS1_ITH); + +#if (USE_HAL_DTS_REGISTER_CALLBACKS == 1U) + hdts->HighCallback(hdts); +#else + HAL_DTS_HighCallback(hdts); +#endif /* USE_HAL_DTS_REGISTER_CALLBACKS */ + } +} + +/** + * @brief DTS Sensor End measure callback. + * @param hdts DTS handle + * @retval None + */ +__weak void HAL_DTS_EndCallback(DTS_HandleTypeDef *hdts) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdts); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_DTS_EndCallback should be implemented in the user file + */ +} + +/** + * @brief DTS Sensor low threshold measure callback. + * @param hdts DTS handle + * @retval None + */ +__weak void HAL_DTS_LowCallback(DTS_HandleTypeDef *hdts) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdts); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_DTS_LowCallback should be implemented in the user file + */ +} + +/** + * @brief DTS Sensor high threshold measure callback. + * @param hdts DTS handle + * @retval None + */ +__weak void HAL_DTS_HighCallback(DTS_HandleTypeDef *hdts) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdts); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_DTS_HighCallback should be implemented in the user file + */ +} + +/** + * @brief DTS Sensor asynchronous end measure callback. + * @param hdts DTS handle + * @retval None + */ +__weak void HAL_DTS_AsyncEndCallback(DTS_HandleTypeDef *hdts) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdts); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_DTS_AsyncEndCallback should be implemented in the user file + */ +} + +/** + * @brief DTS Sensor asynchronous low threshold measure callback. + * @param hdts DTS handle + * @retval None + */ +__weak void HAL_DTS_AsyncLowCallback(DTS_HandleTypeDef *hdts) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdts); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_DTS_AsyncLowCallback should be implemented in the user file + */ +} + +/** + * @brief DTS Sensor asynchronous high threshold measure callback. + * @param hdts DTS handle + * @retval None + */ +__weak void HAL_DTS_AsyncHighCallback(DTS_HandleTypeDef *hdts) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdts); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_DTS_AsyncHighCallback should be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup DTS_Exported_Functions_Group3 Peripheral State functions + * @brief Peripheral State functions. + * +@verbatim + ======================================================================================================================= + ##### Peripheral State functions ##### + ======================================================================================================================= + [..] + This subsection permits to get in run-time the status of the peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Return the DTS handle state. + * @param hdts DTS handle + * @retval HAL state + */ +HAL_DTS_StateTypeDef HAL_DTS_GetState(const DTS_HandleTypeDef *hdts) +{ + /* Check the DTS handle allocation */ + if (hdts == NULL) + { + return HAL_DTS_STATE_RESET; + } + + /* Return DTS handle state */ + return hdts->State; +} +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* DTS */ + +#endif /* HAL_DTS_MODULE_ENABLED */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_eth.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_eth.c new file mode 100644 index 0000000000..6f650307a9 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_eth.c @@ -0,0 +1,3326 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_eth.c + * @author MCD Application Team + * @brief ETH HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Ethernet (ETH) peripheral: + * + Initialization and deinitialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State and Errors functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The ETH HAL driver can be used as follows: + + (#)Declare a ETH_HandleTypeDef handle structure, for example: + ETH_HandleTypeDef heth; + + (#)Fill parameters of Init structure in heth handle + + (#)Call HAL_ETH_Init() API to initialize the Ethernet peripheral (MAC, DMA, ...) + + (#)Initialize the ETH low level resources through the HAL_ETH_MspInit() API: + (##) Enable the Ethernet interface clock using + (+++) __HAL_RCC_ETH1MAC_CLK_ENABLE() + (+++) __HAL_RCC_ETH1TX_CLK_ENABLE() + (+++) __HAL_RCC_ETH1RX_CLK_ENABLE() + + (##) Initialize the related GPIO clocks + (##) Configure Ethernet pinout + (##) Configure Ethernet NVIC interrupt (in Interrupt mode) + + (#) Ethernet data reception is asynchronous, so call the following API + to start the listening mode: + (##) HAL_ETH_Start(): + This API starts the MAC and DMA transmission and reception process, + without enabling end of transfer interrupts, in this mode user + has to poll for data reception by calling HAL_ETH_ReadData() + (##) HAL_ETH_Start_IT(): + This API starts the MAC and DMA transmission and reception process, + end of transfer interrupts are enabled in this mode, + HAL_ETH_RxCpltCallback() will be executed when an Ethernet packet is received + + (#) When data is received user can call the following API to get received data: + (##) HAL_ETH_ReadData(): Read a received packet + + (#) For transmission path, two APIs are available: + (##) HAL_ETH_Transmit(): Transmit an ETH frame in blocking mode + (##) HAL_ETH_Transmit_IT(): Transmit an ETH frame in interrupt mode, + HAL_ETH_TxCpltCallback() will be executed when end of transfer occur + + (#) Communication with an external PHY device: + (##) HAL_ETH_ReadPHYRegister(): Read a register from an external PHY + (##) HAL_ETH_WritePHYRegister(): Write data to an external RHY register + + (#) Configure the Ethernet MAC after ETH peripheral initialization + (##) HAL_ETH_GetMACConfig(): Get MAC actual configuration into ETH_MACConfigTypeDef + (##) HAL_ETH_SetMACConfig(): Set MAC configuration based on ETH_MACConfigTypeDef + + (#) Configure the Ethernet DMA after ETH peripheral initialization + (##) HAL_ETH_GetDMAConfig(): Get DMA actual configuration into ETH_DMAConfigTypeDef + (##) HAL_ETH_SetDMAConfig(): Set DMA configuration based on ETH_DMAConfigTypeDef + + (#) Configure the Ethernet PTP after ETH peripheral initialization + (##) Define HAL_ETH_USE_PTP to use PTP APIs. + (##) HAL_ETH_PTP_GetConfig(): Get PTP actual configuration into ETH_PTP_ConfigTypeDef + (##) HAL_ETH_PTP_SetConfig(): Set PTP configuration based on ETH_PTP_ConfigTypeDef + (##) HAL_ETH_PTP_GetTime(): Get Seconds and Nanoseconds for the Ethernet PTP registers + (##) HAL_ETH_PTP_SetTime(): Set Seconds and Nanoseconds for the Ethernet PTP registers + (##) HAL_ETH_PTP_AddTimeOffset(): Add Seconds and Nanoseconds offset for the Ethernet PTP registers + (##) HAL_ETH_PTP_InsertTxTimestamp(): Insert Timestamp in transmission + (##) HAL_ETH_PTP_GetTxTimestamp(): Get transmission timestamp + (##) HAL_ETH_PTP_GetRxTimestamp(): Get reception timestamp + + -@- The ARP offload feature is not supported in this driver. + + -@- The PTP offload feature is not supported in this driver. + + *** Callback registration *** + ============================================= + + The compilation define USE_HAL_ETH_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + Use Function HAL_ETH_RegisterCallback() to register an interrupt callback. + + Function HAL_ETH_RegisterCallback() allows to register following callbacks: + (+) TxCpltCallback : Tx Complete Callback. + (+) RxCpltCallback : Rx Complete Callback. + (+) ErrorCallback : Error Callback. + (+) PMTCallback : Power Management Callback + (+) EEECallback : EEE Callback. + (+) WakeUpCallback : Wake UP Callback + (+) MspInitCallback : MspInit Callback. + (+) MspDeInitCallback: MspDeInit Callback. + + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + + For specific callbacks RxAllocateCallback use dedicated register callbacks: + respectively HAL_ETH_RegisterRxAllocateCallback(). + + For specific callbacks RxLinkCallback use dedicated register callbacks: + respectively HAL_ETH_RegisterRxLinkCallback(). + + For specific callbacks TxFreeCallback use dedicated register callbacks: + respectively HAL_ETH_RegisterTxFreeCallback(). + + For specific callbacks TxPtpCallback use dedicated register callbacks: + respectively HAL_ETH_RegisterTxPtpCallback(). + + Use function HAL_ETH_UnRegisterCallback() to reset a callback to the default + weak function. + HAL_ETH_UnRegisterCallback takes as parameters the HAL peripheral handle, + and the Callback ID. + This function allows to reset following callbacks: + (+) TxCpltCallback : Tx Complete Callback. + (+) RxCpltCallback : Rx Complete Callback. + (+) ErrorCallback : Error Callback. + (+) PMTCallback : Power Management Callback + (+) EEECallback : EEE Callback. + (+) WakeUpCallback : Wake UP Callback + (+) MspInitCallback : MspInit Callback. + (+) MspDeInitCallback: MspDeInit Callback. + + For specific callbacks RxAllocateCallback use dedicated unregister callbacks: + respectively HAL_ETH_UnRegisterRxAllocateCallback(). + + For specific callbacks RxLinkCallback use dedicated unregister callbacks: + respectively HAL_ETH_UnRegisterRxLinkCallback(). + + For specific callbacks TxFreeCallback use dedicated unregister callbacks: + respectively HAL_ETH_UnRegisterTxFreeCallback(). + + For specific callbacks TxPtpCallback use dedicated unregister callbacks: + respectively HAL_ETH_UnRegisterTxPtpCallback(). + + By default, after the HAL_ETH_Init and when the state is HAL_ETH_STATE_RESET + all callbacks are set to the corresponding weak functions: + examples HAL_ETH_TxCpltCallback(), HAL_ETH_RxCpltCallback(). + Exception done for MspInit and MspDeInit functions that are + reset to the legacy weak function in the HAL_ETH_Init/ HAL_ETH_DeInit only when + these callbacks are null (not registered beforehand). + if not, MspInit or MspDeInit are not null, the HAL_ETH_Init/ HAL_ETH_DeInit + keep and use the user MspInit/MspDeInit callbacks (registered beforehand) + + Callbacks can be registered/unregistered in HAL_ETH_STATE_READY state only. + Exception done MspInit/MspDeInit that can be registered/unregistered + in HAL_ETH_STATE_READY or HAL_ETH_STATE_RESET state, + thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. + In that case first register the MspInit/MspDeInit user callbacks + using HAL_ETH_RegisterCallback() before calling HAL_ETH_DeInit + or HAL_ETH_Init function. + + When The compilation define USE_HAL_ETH_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 "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ +#ifdef HAL_ETH_MODULE_ENABLED + +#if defined(ETH) + +/** @defgroup ETH ETH + * @brief ETH HAL module driver + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup ETH_Private_Constants ETH Private Constants + * @{ + */ +#define ETH_MACCR_MASK 0xFFFB7F7CU +#define ETH_MACECR_MASK 0x3F077FFFU +#define ETH_MACPFR_MASK 0x800007FFU +#define ETH_MACWTR_MASK 0x0000010FU +#define ETH_MACTFCR_MASK 0xFFFF00F2U +#define ETH_MACRFCR_MASK 0x00000003U +#define ETH_MTLTQOMR_MASK 0x00000072U +#define ETH_MTLRQOMR_MASK 0x0000007BU + +#define ETH_DMAMR_MASK 0x00007802U +#define ETH_DMASBMR_MASK 0x0000D001U +#define ETH_DMACCR_MASK 0x00013FFFU +#define ETH_DMACTCR_MASK 0x003F1010U +#define ETH_DMACRCR_MASK 0x803F0000U +#define ETH_MACPCSR_MASK (ETH_MACPCSR_PWRDWN | ETH_MACPCSR_RWKPKTEN | \ + ETH_MACPCSR_MGKPKTEN | ETH_MACPCSR_GLBLUCAST | \ + ETH_MACPCSR_RWKPFE) + +/* Timeout values */ +#define ETH_DMARXNDESCWBF_ERRORS_MASK ((uint32_t)(ETH_DMARXNDESCWBF_DE | ETH_DMARXNDESCWBF_RE | \ + ETH_DMARXNDESCWBF_OE | ETH_DMARXNDESCWBF_RWT |\ + ETH_DMARXNDESCWBF_GP | ETH_DMARXNDESCWBF_CE)) + +#define ETH_MACTSCR_MASK 0x0087FF2FU + +#define ETH_MACSTSUR_VALUE 0xFFFFFFFFU +#define ETH_MACSTNUR_VALUE 0xBB9ACA00U +#define ETH_SEGMENT_SIZE_DEFAULT 0x218U +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup ETH_Private_Macros ETH Private Macros + * @{ + */ +/* Helper macros for TX descriptor handling */ +#define INCR_TX_DESC_INDEX(inx, offset) do {\ + (inx) += (offset);\ + if ((inx) >= (uint32_t)ETH_TX_DESC_CNT){\ + (inx) = ((inx) - (uint32_t)ETH_TX_DESC_CNT);}\ + } while (0) + +/* Helper macros for RX descriptor handling */ +#define INCR_RX_DESC_INDEX(inx, offset) do {\ + (inx) += (offset);\ + if ((inx) >= (uint32_t)ETH_RX_DESC_CNT){\ + (inx) = ((inx) - (uint32_t)ETH_RX_DESC_CNT);}\ + } while (0) +/** + * @} + */ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup ETH_Private_Functions ETH Private Functions + * @{ + */ +static void ETH_SetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf); +static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf); +static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth); +static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth); +static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth); +static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, ETH_TxPacketConfig *pTxConfig, uint32_t ItMode); +static void ETH_UpdateDescriptor(ETH_HandleTypeDef *heth); + +#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) +static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth); +#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ +/** + * @} + */ + +/* Exported functions ---------------------------------------------------------*/ +/** @defgroup ETH_Exported_Functions ETH Exported Functions + * @{ + */ + +/** @defgroup ETH_Exported_Functions_Group1 Initialization and deinitialization functions + * @brief Initialization and Configuration functions + * +@verbatim +=============================================================================== + ##### Initialization and Configuration functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + deinitialize the ETH peripheral: + + (+) User must Implement HAL_ETH_MspInit() function in which he configures + all related peripherals resources (CLOCK, GPIO and NVIC ). + + (+) Call the function HAL_ETH_Init() to configure the selected device with + the selected configuration: + (++) MAC address + (++) Media interface (MII or RMII) + (++) Rx DMA Descriptors Tab + (++) Tx DMA Descriptors Tab + (++) Length of Rx Buffers + + (+) Call the function HAL_ETH_DeInit() to restore the default configuration + of the selected ETH peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the Ethernet peripheral registers. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth) +{ + uint32_t tickstart; + + if (heth == NULL) + { + return HAL_ERROR; + } + if (heth->gState == HAL_ETH_STATE_RESET) + { + heth->gState = HAL_ETH_STATE_BUSY; + +#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) + + ETH_InitCallbacksToDefault(heth); + + if (heth->MspInitCallback == NULL) + { + heth->MspInitCallback = HAL_ETH_MspInit; + } + + /* Init the low level hardware */ + heth->MspInitCallback(heth); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC. */ + HAL_ETH_MspInit(heth); + +#endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */ + } + + __HAL_RCC_SBS_CLK_ENABLE(); + + + if (heth->Init.MediaInterface == HAL_ETH_MII_MODE) + { + HAL_SBS_ETHInterfaceSelect(SBS_ETH_MII); + } + else + { + HAL_SBS_ETHInterfaceSelect(SBS_ETH_RMII); + } + + /* Dummy read to sync with ETH */ + (void)SBS->PMCR; + + /* Ethernet Software reset */ + /* Set the SWR bit: resets all MAC subsystem internal registers and logic */ + /* After reset all the registers holds their respective reset values */ + SET_BIT(heth->Instance->DMAMR, ETH_DMAMR_SWR); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait for software reset */ + while (READ_BIT(heth->Instance->DMAMR, ETH_DMAMR_SWR) > 0U) + { + if (((HAL_GetTick() - tickstart) > ETH_SWRESET_TIMEOUT)) + { + /* Set Error Code */ + heth->ErrorCode = HAL_ETH_ERROR_TIMEOUT; + /* Set State as Error */ + heth->gState = HAL_ETH_STATE_ERROR; + /* Return Error */ + return HAL_ERROR; + } + } + + /*------------------ MDIO CSR Clock Range Configuration --------------------*/ + HAL_ETH_SetMDIOClockRange(heth); + + /*------------------ MAC LPI 1US Tic Counter Configuration --------------------*/ + WRITE_REG(heth->Instance->MAC1USTCR, (((uint32_t)HAL_RCC_GetHCLKFreq() / ETH_MAC_US_TICK) - 1U)); + + /*------------------ MAC, MTL and DMA default Configuration ----------------*/ + ETH_MACDMAConfig(heth); + + /* SET DSL to 64 bit */ + MODIFY_REG(heth->Instance->DMACCR, ETH_DMACCR_DSL, ETH_DMACCR_DSL_64BIT); + + /* Set Receive Buffers Length (must be a multiple of 4) */ + if ((heth->Init.RxBuffLen % 0x4U) != 0x0U) + { + /* Set Error Code */ + heth->ErrorCode = HAL_ETH_ERROR_PARAM; + /* Set State as Error */ + heth->gState = HAL_ETH_STATE_ERROR; + /* Return Error */ + return HAL_ERROR; + } + else + { + MODIFY_REG(heth->Instance->DMACRCR, ETH_DMACRCR_RBSZ, ((heth->Init.RxBuffLen) << 1)); + } + + /*------------------ DMA Tx Descriptors Configuration ----------------------*/ + ETH_DMATxDescListInit(heth); + + /*------------------ DMA Rx Descriptors Configuration ----------------------*/ + ETH_DMARxDescListInit(heth); + + /*--------------------- ETHERNET MAC Address Configuration ------------------*/ + /* Set MAC addr bits 32 to 47 */ + heth->Instance->MACA0HR = (((uint32_t)(heth->Init.MACAddr[5]) << 8) | (uint32_t)heth->Init.MACAddr[4]); + /* Set MAC addr bits 0 to 31 */ + heth->Instance->MACA0LR = (((uint32_t)(heth->Init.MACAddr[3]) << 24) | ((uint32_t)(heth->Init.MACAddr[2]) << 16) | + ((uint32_t)(heth->Init.MACAddr[1]) << 8) | (uint32_t)heth->Init.MACAddr[0]); + + heth->ErrorCode = HAL_ETH_ERROR_NONE; + heth->gState = HAL_ETH_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the ETH peripheral. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth) +{ + /* Set the ETH peripheral state to BUSY */ + heth->gState = HAL_ETH_STATE_BUSY; + +#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) + + if (heth->MspDeInitCallback == NULL) + { + heth->MspDeInitCallback = HAL_ETH_MspDeInit; + } + /* DeInit the low level hardware */ + heth->MspDeInitCallback(heth); +#else + + /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */ + HAL_ETH_MspDeInit(heth); + +#endif /* (USE_HAL_ETH_REGISTER_CALLBACKS) */ + + /* Set ETH HAL state to Disabled */ + heth->gState = HAL_ETH_STATE_RESET; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the ETH MSP. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +__weak void HAL_ETH_MspInit(ETH_HandleTypeDef *heth) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(heth); + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ETH_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes ETH MSP. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +__weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(heth); + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ETH_MspDeInit could be implemented in the user file + */ +} + +#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User ETH Callback + * To be used instead of the weak predefined callback + * @param heth eth handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID + * @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID + * @arg @ref HAL_ETH_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_ETH_PMT_CB_ID Power Management Callback ID + * @arg @ref HAL_ETH_EEE_CB_ID EEE Callback ID + * @arg @ref HAL_ETH_WAKEUP_CB_ID Wake UP Callback ID + * @arg @ref HAL_ETH_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_ETH_MSPDEINIT_CB_ID MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @retval status + */ +HAL_StatusTypeDef HAL_ETH_RegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID, + pETH_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + + if (heth->gState == HAL_ETH_STATE_READY) + { + switch (CallbackID) + { + case HAL_ETH_TX_COMPLETE_CB_ID : + heth->TxCpltCallback = pCallback; + break; + + case HAL_ETH_RX_COMPLETE_CB_ID : + heth->RxCpltCallback = pCallback; + break; + + case HAL_ETH_ERROR_CB_ID : + heth->ErrorCallback = pCallback; + break; + + case HAL_ETH_PMT_CB_ID : + heth->PMTCallback = pCallback; + break; + + case HAL_ETH_EEE_CB_ID : + heth->EEECallback = pCallback; + break; + + case HAL_ETH_WAKEUP_CB_ID : + heth->WakeUpCallback = pCallback; + break; + + case HAL_ETH_MSPINIT_CB_ID : + heth->MspInitCallback = pCallback; + break; + + case HAL_ETH_MSPDEINIT_CB_ID : + heth->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (heth->gState == HAL_ETH_STATE_RESET) + { + switch (CallbackID) + { + case HAL_ETH_MSPINIT_CB_ID : + heth->MspInitCallback = pCallback; + break; + + case HAL_ETH_MSPDEINIT_CB_ID : + heth->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister an ETH Callback + * ETH callback is redirected to the weak predefined callback + * @param heth eth handle + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_ETH_TX_COMPLETE_CB_ID Tx Complete Callback ID + * @arg @ref HAL_ETH_RX_COMPLETE_CB_ID Rx Complete Callback ID + * @arg @ref HAL_ETH_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_ETH_PMT_CB_ID Power Management Callback ID + * @arg @ref HAL_ETH_EEE_CB_ID EEE Callback ID + * @arg @ref HAL_ETH_WAKEUP_CB_ID Wake UP Callback ID + * @arg @ref HAL_ETH_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_ETH_MSPDEINIT_CB_ID MspDeInit callback ID + * @retval status + */ +HAL_StatusTypeDef HAL_ETH_UnRegisterCallback(ETH_HandleTypeDef *heth, HAL_ETH_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (heth->gState == HAL_ETH_STATE_READY) + { + switch (CallbackID) + { + case HAL_ETH_TX_COMPLETE_CB_ID : + heth->TxCpltCallback = HAL_ETH_TxCpltCallback; + break; + + case HAL_ETH_RX_COMPLETE_CB_ID : + heth->RxCpltCallback = HAL_ETH_RxCpltCallback; + break; + + case HAL_ETH_ERROR_CB_ID : + heth->ErrorCallback = HAL_ETH_ErrorCallback; + break; + + case HAL_ETH_PMT_CB_ID : + heth->PMTCallback = HAL_ETH_PMTCallback; + break; + + case HAL_ETH_EEE_CB_ID : + heth->EEECallback = HAL_ETH_EEECallback; + break; + + case HAL_ETH_WAKEUP_CB_ID : + heth->WakeUpCallback = HAL_ETH_WakeUpCallback; + break; + + case HAL_ETH_MSPINIT_CB_ID : + heth->MspInitCallback = HAL_ETH_MspInit; + break; + + case HAL_ETH_MSPDEINIT_CB_ID : + heth->MspDeInitCallback = HAL_ETH_MspDeInit; + break; + + default : + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (heth->gState == HAL_ETH_STATE_RESET) + { + switch (CallbackID) + { + case HAL_ETH_MSPINIT_CB_ID : + heth->MspInitCallback = HAL_ETH_MspInit; + break; + + case HAL_ETH_MSPDEINIT_CB_ID : + heth->MspDeInitCallback = HAL_ETH_MspDeInit; + break; + + default : + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + heth->ErrorCode |= HAL_ETH_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} +#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup ETH_Exported_Functions_Group2 IO operation functions + * @brief ETH Transmit and Receive functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to manage the ETH + data transfer. + +@endverbatim + * @{ + */ + +/** + * @brief Enables Ethernet MAC and DMA reception and transmission + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth) +{ + if (heth->gState == HAL_ETH_STATE_READY) + { + heth->gState = HAL_ETH_STATE_BUSY; + + /* Set nombre of descriptors to build */ + heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT; + + /* Build all descriptors */ + ETH_UpdateDescriptor(heth); + + /* Enable the MAC transmission */ + SET_BIT(heth->Instance->MACCR, ETH_MACCR_TE); + + /* Enable the MAC reception */ + SET_BIT(heth->Instance->MACCR, ETH_MACCR_RE); + + /* Set the Flush Transmit FIFO bit */ + SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ); + + /* Enable the DMA transmission */ + SET_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_ST); + + /* Enable the DMA reception */ + SET_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR); + + /* Clear Tx and Rx process stopped flags */ + heth->Instance->DMACSR |= (ETH_DMACSR_TPS | ETH_DMACSR_RPS); + + heth->gState = HAL_ETH_STATE_STARTED; + + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Enables Ethernet MAC and DMA reception/transmission in Interrupt mode + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_Start_IT(ETH_HandleTypeDef *heth) +{ + if (heth->gState == HAL_ETH_STATE_READY) + { + heth->gState = HAL_ETH_STATE_BUSY; + + /* save IT mode to ETH Handle */ + heth->RxDescList.ItMode = 1U; + /* Disable Rx MMC Interrupts */ + SET_BIT(heth->Instance->MMCRIMR, ETH_MMCRIMR_RXLPITRCIM | ETH_MMCRIMR_RXLPIUSCIM | \ + ETH_MMCRIMR_RXUCGPIM | ETH_MMCRIMR_RXALGNERPIM | ETH_MMCRIMR_RXCRCERPIM); + + /* Disable Tx MMC Interrupts */ + SET_BIT(heth->Instance->MMCTIMR, ETH_MMCTIMR_TXLPITRCIM | ETH_MMCTIMR_TXLPIUSCIM | \ + ETH_MMCTIMR_TXGPKTIM | ETH_MMCTIMR_TXMCOLGPIM | ETH_MMCTIMR_TXSCOLGPIM); + + /* Set nombre of descriptors to build */ + heth->RxDescList.RxBuildDescCnt = ETH_RX_DESC_CNT; + + /* Build all descriptors */ + ETH_UpdateDescriptor(heth); + + /* Enable the MAC transmission */ + SET_BIT(heth->Instance->MACCR, ETH_MACCR_TE); + + /* Enable the MAC reception */ + SET_BIT(heth->Instance->MACCR, ETH_MACCR_RE); + + /* Set the Flush Transmit FIFO bit */ + SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ); + + /* Enable the DMA transmission */ + SET_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_ST); + + /* Enable the DMA reception */ + SET_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR); + + /* Clear Tx and Rx process stopped flags */ + heth->Instance->DMACSR |= (ETH_DMACSR_TPS | ETH_DMACSR_RPS); + /* Enable ETH DMA interrupts: + - Tx complete interrupt + - Rx complete interrupt + - Fatal bus interrupt + */ + __HAL_ETH_DMA_ENABLE_IT(heth, (ETH_DMACIER_NIE | ETH_DMACIER_RIE | ETH_DMACIER_TIE | + ETH_DMACIER_FBEE | ETH_DMACIER_AIE | ETH_DMACIER_RBUE)); + + heth->gState = HAL_ETH_STATE_STARTED; + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Stop Ethernet MAC and DMA reception/transmission + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth) +{ + if (heth->gState == HAL_ETH_STATE_STARTED) + { + /* Set the ETH peripheral state to BUSY */ + heth->gState = HAL_ETH_STATE_BUSY; + + /* Disable the DMA transmission */ + CLEAR_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_ST); + + /* Disable the DMA reception */ + CLEAR_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR); + + /* Disable the MAC reception */ + CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_RE); + + /* Set the Flush Transmit FIFO bit */ + SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ); + + /* Disable the MAC transmission */ + CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE); + + heth->gState = HAL_ETH_STATE_READY; + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Stop Ethernet MAC and DMA reception/transmission in Interrupt mode + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_Stop_IT(ETH_HandleTypeDef *heth) +{ + ETH_DMADescTypeDef *dmarxdesc; + uint32_t descindex; + + if (heth->gState == HAL_ETH_STATE_STARTED) + { + /* Set the ETH peripheral state to BUSY */ + heth->gState = HAL_ETH_STATE_BUSY; + + /* Disable interrupts: + - Tx complete interrupt + - Rx complete interrupt + - Fatal bus interrupt + */ + __HAL_ETH_DMA_DISABLE_IT(heth, (ETH_DMACIER_NIE | ETH_DMACIER_RIE | ETH_DMACIER_TIE | + ETH_DMACIER_FBEE | ETH_DMACIER_AIE | ETH_DMACIER_RBUE)); + + /* Disable the DMA transmission */ + CLEAR_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_ST); + + /* Disable the DMA reception */ + CLEAR_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_SR); + + /* Disable the MAC reception */ + CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_RE); + + /* Set the Flush Transmit FIFO bit */ + SET_BIT(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_FTQ); + + /* Disable the MAC transmission */ + CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_TE); + + /* Clear IOC bit to all Rx descriptors */ + for (descindex = 0; descindex < (uint32_t)ETH_RX_DESC_CNT; descindex++) + { + dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descindex]; + CLEAR_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCRF_IOC); + } + + heth->RxDescList.ItMode = 0U; + + heth->gState = HAL_ETH_STATE_READY; + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Sends an Ethernet Packet in polling mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pTxConfig: Hold the configuration of packet to be transmitted + * @param Timeout: timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_Transmit(ETH_HandleTypeDef *heth, ETH_TxPacketConfig *pTxConfig, uint32_t Timeout) +{ + uint32_t tickstart; + ETH_DMADescTypeDef *dmatxdesc; + + if (pTxConfig == NULL) + { + heth->ErrorCode |= HAL_ETH_ERROR_PARAM; + return HAL_ERROR; + } + + if (heth->gState == HAL_ETH_STATE_STARTED) + { + /* Config DMA Tx descriptor by Tx Packet info */ + if (ETH_Prepare_Tx_Descriptors(heth, pTxConfig, 0) != HAL_ETH_ERROR_NONE) + { + /* Set the ETH error code */ + heth->ErrorCode |= HAL_ETH_ERROR_BUSY; + return HAL_ERROR; + } + + /* Ensure completion of descriptor preparation before transmission start */ + __DSB(); + + dmatxdesc = (ETH_DMADescTypeDef *)(&heth->TxDescList)->TxDesc[heth->TxDescList.CurTxDesc]; + + /* Incr current tx desc index */ + INCR_TX_DESC_INDEX(heth->TxDescList.CurTxDesc, 1U); + + /* Start transmission */ + /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */ + WRITE_REG(heth->Instance->DMACTDTPR, (uint32_t)(heth->TxDescList.TxDesc[heth->TxDescList.CurTxDesc])); + + tickstart = HAL_GetTick(); + + /* Wait for data to be transmitted or timeout occurred */ + while ((dmatxdesc->DESC3 & ETH_DMATXNDESCWBF_OWN) != (uint32_t)RESET) + { + if ((heth->Instance->DMACSR & ETH_DMACSR_FBE) != (uint32_t)RESET) + { + heth->ErrorCode |= HAL_ETH_ERROR_DMA; + heth->DMAErrorCode = heth->Instance->DMACSR; + /* Return function status */ + return HAL_ERROR; + } + + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + heth->ErrorCode |= HAL_ETH_ERROR_TIMEOUT; + /* Clear TX descriptor so that we can proceed */ + dmatxdesc->DESC3 = (ETH_DMATXNDESCWBF_FD | ETH_DMATXNDESCWBF_LD); + return HAL_ERROR; + } + } + } + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Sends an Ethernet Packet in interrupt mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pTxConfig: Hold the configuration of packet to be transmitted + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_Transmit_IT(ETH_HandleTypeDef *heth, ETH_TxPacketConfig *pTxConfig) +{ + if (pTxConfig == NULL) + { + heth->ErrorCode |= HAL_ETH_ERROR_PARAM; + return HAL_ERROR; + } + + if (heth->gState == HAL_ETH_STATE_STARTED) + { + /* Save the packet pointer to release. */ + heth->TxDescList.CurrentPacketAddress = (uint32_t *)pTxConfig->pData; + + /* Config DMA Tx descriptor by Tx Packet info */ + if (ETH_Prepare_Tx_Descriptors(heth, pTxConfig, 1) != HAL_ETH_ERROR_NONE) + { + heth->ErrorCode |= HAL_ETH_ERROR_BUSY; + return HAL_ERROR; + } + + /* Ensure completion of descriptor preparation before transmission start */ + __DSB(); + + /* Incr current tx desc index */ + INCR_TX_DESC_INDEX(heth->TxDescList.CurTxDesc, 1U); + + /* Start transmission */ + /* issue a poll command to Tx DMA by writing address of next immediate free descriptor */ + WRITE_REG(heth->Instance->DMACTDTPR, (uint32_t)(heth->TxDescList.TxDesc[heth->TxDescList.CurTxDesc])); + + return HAL_OK; + + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Read a received packet. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pAppBuff: Pointer to an application buffer to receive the packet. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_ReadData(ETH_HandleTypeDef *heth, void **pAppBuff) +{ + uint32_t descidx; + ETH_DMADescTypeDef *dmarxdesc; + uint32_t desccnt = 0U; + uint32_t desccntmax; + uint32_t bufflength; + uint8_t rxdataready = 0U; + + if (pAppBuff == NULL) + { + heth->ErrorCode |= HAL_ETH_ERROR_PARAM; + return HAL_ERROR; + } + + if (heth->gState != HAL_ETH_STATE_STARTED) + { + return HAL_ERROR; + } + + descidx = heth->RxDescList.RxDescIdx; + dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx]; + desccntmax = ETH_RX_DESC_CNT - heth->RxDescList.RxBuildDescCnt; + + /* Check if descriptor is not owned by DMA */ + while ((READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_OWN) == (uint32_t)RESET) && (desccnt < desccntmax) + && (rxdataready == 0U)) + { + if (READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_CTXT) != (uint32_t)RESET) + { + /* Get timestamp high */ + heth->RxDescList.TimeStamp.TimeStampHigh = dmarxdesc->DESC1; + /* Get timestamp low */ + heth->RxDescList.TimeStamp.TimeStampLow = dmarxdesc->DESC0; + } + if ((READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_FD) != (uint32_t)RESET) || (heth->RxDescList.pRxStart != NULL)) + { + /* Check if first descriptor */ + if (READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_FD) != (uint32_t)RESET) + { + heth->RxDescList.RxDescCnt = 0; + heth->RxDescList.RxDataLength = 0; + } + + /* Check if last descriptor */ + bufflength = heth->Init.RxBuffLen; + if (READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_LD) != (uint32_t)RESET) + { + bufflength = READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_PL) - heth->RxDescList.RxDataLength; + + /* Save Last descriptor index */ + heth->RxDescList.pRxLastRxDesc = dmarxdesc->DESC3; + + /* Packet ready */ + rxdataready = 1; + } + + /* Link data */ +#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) + /*Call registered Link callback*/ + heth->rxLinkCallback(&heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd, + (uint8_t *)dmarxdesc->BackupAddr0, bufflength); +#else + /* Link callback */ + HAL_ETH_RxLinkCallback(&heth->RxDescList.pRxStart, &heth->RxDescList.pRxEnd, + (uint8_t *)dmarxdesc->BackupAddr0, (uint16_t) bufflength); +#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + heth->RxDescList.RxDescCnt++; + heth->RxDescList.RxDataLength += bufflength; + + /* Clear buffer pointer */ + dmarxdesc->BackupAddr0 = 0; + } + + /* Increment current rx descriptor index */ + INCR_RX_DESC_INDEX(descidx, 1U); + /* Get current descriptor address */ + dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx]; + desccnt++; + } + + heth->RxDescList.RxBuildDescCnt += desccnt; + if ((heth->RxDescList.RxBuildDescCnt) != 0U) + { + /* Update Descriptors */ + ETH_UpdateDescriptor(heth); + } + + heth->RxDescList.RxDescIdx = descidx; + + if (rxdataready == 1U) + { + /* Return received packet */ + *pAppBuff = heth->RxDescList.pRxStart; + /* Reset first element */ + heth->RxDescList.pRxStart = NULL; + + return HAL_OK; + } + + /* Packet not ready */ + return HAL_ERROR; +} + +/** + * @brief This function gives back Rx Desc of the last received Packet + * to the DMA, so ETH DMA will be able to use these descriptors + * to receive next Packets. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ +static void ETH_UpdateDescriptor(ETH_HandleTypeDef *heth) +{ + uint32_t descidx; + uint32_t desccount; + ETH_DMADescTypeDef *dmarxdesc; + uint8_t *buff = NULL; + uint8_t allocStatus = 1U; + + descidx = heth->RxDescList.RxBuildDescIdx; + dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx]; + desccount = heth->RxDescList.RxBuildDescCnt; + + while ((desccount > 0U) && (allocStatus != 0U)) + { + /* Check if a buffer's attached the descriptor */ + if (READ_REG(dmarxdesc->BackupAddr0) == 0U) + { + /* Get a new buffer. */ +#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) + /*Call registered Allocate callback*/ + heth->rxAllocateCallback(&buff); +#else + /* Allocate callback */ + HAL_ETH_RxAllocateCallback(&buff); +#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + if (buff == NULL) + { + allocStatus = 0U; + } + else + { + WRITE_REG(dmarxdesc->BackupAddr0, (uint32_t)buff); + WRITE_REG(dmarxdesc->DESC0, (uint32_t)buff); + } + } + + if (allocStatus != 0U) + { + /* Ensure rest of descriptor is written to RAM before the OWN bit */ + __DMB(); + + if (heth->RxDescList.ItMode != 0U) + { + WRITE_REG(dmarxdesc->DESC3, ETH_DMARXNDESCRF_OWN | ETH_DMARXNDESCRF_BUF1V | ETH_DMARXNDESCRF_IOC); + } + else + { + WRITE_REG(dmarxdesc->DESC3, ETH_DMARXNDESCRF_OWN | ETH_DMARXNDESCRF_BUF1V); + } + + /* Increment current rx descriptor index */ + INCR_RX_DESC_INDEX(descidx, 1U); + /* Get current descriptor address */ + dmarxdesc = (ETH_DMADescTypeDef *)heth->RxDescList.RxDesc[descidx]; + desccount--; + } + } + + if (heth->RxDescList.RxBuildDescCnt != desccount) + { + /* Set the Tail pointer address */ + WRITE_REG(heth->Instance->DMACRDTPR, 0U); + + heth->RxDescList.RxBuildDescIdx = descidx; + heth->RxDescList.RxBuildDescCnt = desccount; + } +} + +/** + * @brief Register the Rx alloc callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param rxAllocateCallback: pointer to function to alloc buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_RegisterRxAllocateCallback(ETH_HandleTypeDef *heth, + pETH_rxAllocateCallbackTypeDef rxAllocateCallback) +{ + if (rxAllocateCallback == NULL) + { + /* No buffer to save */ + return HAL_ERROR; + } + + /* Set function to allocate buffer */ + heth->rxAllocateCallback = rxAllocateCallback; + + return HAL_OK; +} + +/** + * @brief Unregister the Rx alloc callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_UnRegisterRxAllocateCallback(ETH_HandleTypeDef *heth) +{ + /* Set function to allocate buffer */ + heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback; + + return HAL_OK; +} + +/** + * @brief Rx Allocate callback. + * @param buff: pointer to allocated buffer + * @retval None + */ +__weak void HAL_ETH_RxAllocateCallback(uint8_t **buff) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(buff); + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ETH_RxAllocateCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Link callback. + * @param pStart: pointer to packet start + * @param pEnd: pointer to packet end + * @param buff: pointer to received data + * @param Length: received data length + * @retval None + */ +__weak void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(pStart); + UNUSED(pEnd); + UNUSED(buff); + UNUSED(Length); + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ETH_RxLinkCallback could be implemented in the user file + */ +} + +/** + * @brief Set the Rx link data function. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param rxLinkCallback: pointer to function to link data + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_RegisterRxLinkCallback(ETH_HandleTypeDef *heth, pETH_rxLinkCallbackTypeDef rxLinkCallback) +{ + if (rxLinkCallback == NULL) + { + /* No buffer to save */ + return HAL_ERROR; + } + + /* Set function to link data */ + heth->rxLinkCallback = rxLinkCallback; + + return HAL_OK; +} + +/** + * @brief Unregister the Rx link callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_UnRegisterRxLinkCallback(ETH_HandleTypeDef *heth) +{ + /* Set function to allocate buffer */ + heth->rxLinkCallback = HAL_ETH_RxLinkCallback; + + return HAL_OK; +} + +/** + * @brief Get the error state of the last received packet. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pErrorCode: pointer to uint32_t to hold the error code + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_GetRxDataErrorCode(ETH_HandleTypeDef *heth, uint32_t *pErrorCode) +{ + /* Get error bits. */ + *pErrorCode = READ_BIT(heth->RxDescList.pRxLastRxDesc, ETH_DMARXNDESCWBF_ERRORS_MASK); + + return HAL_OK; +} + +/** + * @brief Set the Tx free function. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param txFreeCallback: pointer to function to release the packet + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_RegisterTxFreeCallback(ETH_HandleTypeDef *heth, pETH_txFreeCallbackTypeDef txFreeCallback) +{ + if (txFreeCallback == NULL) + { + /* No buffer to save */ + return HAL_ERROR; + } + + /* Set function to free transmmitted packet */ + heth->txFreeCallback = txFreeCallback; + + return HAL_OK; +} + +/** + * @brief Unregister the Tx free callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_UnRegisterTxFreeCallback(ETH_HandleTypeDef *heth) +{ + /* Set function to allocate buffer */ + heth->txFreeCallback = HAL_ETH_TxFreeCallback; + + return HAL_OK; +} + +/** + * @brief Tx Free callback. + * @param buff: pointer to buffer to free + * @retval None + */ +__weak void HAL_ETH_TxFreeCallback(uint32_t *buff) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(buff); + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ETH_TxFreeCallback could be implemented in the user file + */ +} + +/** + * @brief Release transmitted Tx packets. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_ReleaseTxPacket(ETH_HandleTypeDef *heth) +{ + ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList; + uint32_t numOfBuf = dmatxdesclist->BuffersInUse; + uint32_t idx = dmatxdesclist->releaseIndex; + uint8_t pktTxStatus = 1U; + uint8_t pktInUse; +#ifdef HAL_ETH_USE_PTP + ETH_TimeStampTypeDef *timestamp = &heth->TxTimestamp; +#endif /* HAL_ETH_USE_PTP */ + + /* Loop through buffers in use. */ + while ((numOfBuf != 0U) && (pktTxStatus != 0U)) + { + pktInUse = 1U; + numOfBuf--; + /* If no packet, just examine the next packet. */ + if (dmatxdesclist->PacketAddress[idx] == NULL) + { + /* No packet in use, skip to next. */ + idx = (idx + 1U) & (ETH_TX_DESC_CNT - 1U); + pktInUse = 0U; + } + + if (pktInUse != 0U) + { + /* Determine if the packet has been transmitted. */ + if ((heth->Init.TxDesc[idx].DESC3 & ETH_DMATXNDESCRF_OWN) == 0U) + { +#ifdef HAL_ETH_USE_PTP + /* Disable Ptp transmission */ + CLEAR_BIT(heth->Init.TxDesc[idx].DESC3, (0x40000000U)); + + /* Get timestamp low */ + timestamp->TimeStampLow = heth->Init.TxDesc[idx].DESC0; + /* Get timestamp high */ + timestamp->TimeStampHigh = heth->Init.TxDesc[idx].DESC1; +#endif /* HAL_ETH_USE_PTP */ + +#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) + /*Call registered callbacks*/ +#ifdef HAL_ETH_USE_PTP + /* Handle Ptp */ + heth->txPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp); +#endif /* HAL_ETH_USE_PTP */ + /* Release the packet. */ + heth->txFreeCallback(dmatxdesclist->PacketAddress[idx]); +#else + /* Call callbacks */ +#ifdef HAL_ETH_USE_PTP + /* Handle Ptp */ + HAL_ETH_TxPtpCallback(dmatxdesclist->PacketAddress[idx], timestamp); +#endif /* HAL_ETH_USE_PTP */ + /* Release the packet. */ + HAL_ETH_TxFreeCallback(dmatxdesclist->PacketAddress[idx]); +#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + + /* Clear the entry in the in-use array. */ + dmatxdesclist->PacketAddress[idx] = NULL; + + /* Update the transmit relesae index and number of buffers in use. */ + idx = (idx + 1U) & (ETH_TX_DESC_CNT - 1U); + dmatxdesclist->BuffersInUse = numOfBuf; + dmatxdesclist->releaseIndex = idx; + } + else + { + /* Get out of the loop! */ + pktTxStatus = 0U; + } + } + } + return HAL_OK; +} + +#ifdef HAL_ETH_USE_PTP +/** + * @brief Set the Ethernet PTP configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains + * the configuration information for PTP + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_PTP_SetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig) +{ + uint32_t tmpTSCR; + ETH_TimeTypeDef time; + + if (ptpconfig == NULL) + { + return HAL_ERROR; + } + + tmpTSCR = ptpconfig->Timestamp | + ((uint32_t)ptpconfig->TimestampUpdate << ETH_MACTSCR_TSUPDT_Pos) | + ((uint32_t)ptpconfig->TimestampAll << ETH_MACTSCR_TSENALL_Pos) | + ((uint32_t)ptpconfig->TimestampRolloverMode << ETH_MACTSCR_TSCTRLSSR_Pos) | + ((uint32_t)ptpconfig->TimestampV2 << ETH_MACTSCR_TSVER2ENA_Pos) | + ((uint32_t)ptpconfig->TimestampEthernet << ETH_MACTSCR_TSIPENA_Pos) | + ((uint32_t)ptpconfig->TimestampIPv6 << ETH_MACTSCR_TSIPV6ENA_Pos) | + ((uint32_t)ptpconfig->TimestampIPv4 << ETH_MACTSCR_TSIPV4ENA_Pos) | + ((uint32_t)ptpconfig->TimestampEvent << ETH_MACTSCR_TSEVNTENA_Pos) | + ((uint32_t)ptpconfig->TimestampMaster << ETH_MACTSCR_TSMSTRENA_Pos) | + ((uint32_t)ptpconfig->TimestampSnapshots << ETH_MACTSCR_SNAPTYPSEL_Pos) | + ((uint32_t)ptpconfig->TimestampFilter << ETH_MACTSCR_TSENMACADDR_Pos) | + ((uint32_t)ptpconfig->TimestampChecksumCorrection << ETH_MACTSCR_CSC_Pos) | + ((uint32_t)ptpconfig->TimestampStatusMode << ETH_MACTSCR_TXTSSTSM_Pos); + + /* Write to MACTSCR */ + MODIFY_REG(heth->Instance->MACTSCR, ETH_MACTSCR_MASK, tmpTSCR); + + /* Enable Timestamp */ + SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSENA); + WRITE_REG(heth->Instance->MACSSIR, ptpconfig->TimestampSubsecondInc); + WRITE_REG(heth->Instance->MACTSAR, ptpconfig->TimestampAddend); + + /* Enable Timestamp */ + if (ptpconfig->TimestampAddendUpdate == ENABLE) + { + SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSADDREG); + while ((heth->Instance->MACTSCR & ETH_MACTSCR_TSADDREG) != 0) {} + } + + /* Enable Update mode */ + if (ptpconfig->TimestampUpdateMode == ENABLE) + { + SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSCFUPDT); + } + + /* Initialize Time */ + time.Seconds = 0; + time.NanoSeconds = 0; + HAL_ETH_PTP_SetTime(heth, &time); + + /* Ptp Init */ + SET_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSINIT); + + /* Set PTP Configuration done */ + heth->IsPtpConfigured = HAL_ETH_PTP_CONFIGURATED; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Get the Ethernet PTP configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param ptpconfig: pointer to a ETH_PTP_ConfigTypeDef structure that contains + * the configuration information for PTP + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_PTP_GetConfig(ETH_HandleTypeDef *heth, ETH_PTP_ConfigTypeDef *ptpconfig) +{ + if (ptpconfig == NULL) + { + return HAL_ERROR; + } + ptpconfig->Timestamp = READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSENA); + ptpconfig->TimestampUpdate = ((READ_BIT(heth->Instance->MACTSCR, + ETH_MACTSCR_TSCFUPDT) >> ETH_MACTSCR_TSUPDT_Pos) > 0U) ? ENABLE : DISABLE; + ptpconfig->TimestampAll = ((READ_BIT(heth->Instance->MACTSCR, + ETH_MACTSCR_TSENALL) >> ETH_MACTSCR_TSENALL_Pos) > 0U) ? ENABLE : DISABLE; + ptpconfig->TimestampRolloverMode = ((READ_BIT(heth->Instance->MACTSCR, + ETH_MACTSCR_TSCTRLSSR) >> ETH_MACTSCR_TSCTRLSSR_Pos) > 0U) + ? ENABLE : DISABLE; + ptpconfig->TimestampV2 = ((READ_BIT(heth->Instance->MACTSCR, + ETH_MACTSCR_TSVER2ENA) >> ETH_MACTSCR_TSVER2ENA_Pos) > 0U) ? ENABLE : DISABLE; + ptpconfig->TimestampEthernet = ((READ_BIT(heth->Instance->MACTSCR, + ETH_MACTSCR_TSIPENA) >> ETH_MACTSCR_TSIPENA_Pos) > 0U) ? ENABLE : DISABLE; + ptpconfig->TimestampIPv6 = ((READ_BIT(heth->Instance->MACTSCR, + ETH_MACTSCR_TSIPV6ENA) >> ETH_MACTSCR_TSIPV6ENA_Pos) > 0U) ? ENABLE : DISABLE; + ptpconfig->TimestampIPv4 = ((READ_BIT(heth->Instance->MACTSCR, + ETH_MACTSCR_TSIPV4ENA) >> ETH_MACTSCR_TSIPV4ENA_Pos) > 0U) ? ENABLE : DISABLE; + ptpconfig->TimestampEvent = ((READ_BIT(heth->Instance->MACTSCR, + ETH_MACTSCR_TSEVNTENA) >> ETH_MACTSCR_TSEVNTENA_Pos) > 0U) ? ENABLE : DISABLE; + ptpconfig->TimestampMaster = ((READ_BIT(heth->Instance->MACTSCR, + ETH_MACTSCR_TSMSTRENA) >> ETH_MACTSCR_TSMSTRENA_Pos) > 0U) ? ENABLE : DISABLE; + ptpconfig->TimestampSnapshots = ((READ_BIT(heth->Instance->MACTSCR, + ETH_MACTSCR_SNAPTYPSEL) >> ETH_MACTSCR_SNAPTYPSEL_Pos) > 0U) + ? ENABLE : DISABLE; + ptpconfig->TimestampFilter = ((READ_BIT(heth->Instance->MACTSCR, + ETH_MACTSCR_TSENMACADDR) >> ETH_MACTSCR_TSENMACADDR_Pos) > 0U) + ? ENABLE : DISABLE; + ptpconfig->TimestampChecksumCorrection = ((READ_BIT(heth->Instance->MACTSCR, + ETH_MACTSCR_CSC) >> ETH_MACTSCR_CSC_Pos) > 0U) ? ENABLE : DISABLE; + ptpconfig->TimestampStatusMode = ((READ_BIT(heth->Instance->MACTSCR, + ETH_MACTSCR_TXTSSTSM) >> ETH_MACTSCR_TXTSSTSM_Pos) > 0U) + ? ENABLE : DISABLE; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Set Seconds and Nanoseconds for the Ethernet PTP registers. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param heth: pointer to a ETH_TimeTypeDef structure that contains + * time to set + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_PTP_SetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time) +{ + if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED) + { + /* Set Seconds */ + heth->Instance->MACSTSUR = time->Seconds; + + /* Set NanoSeconds */ + heth->Instance->MACSTNUR = time->NanoSeconds; + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } +} + +/** + * @brief Get Seconds and Nanoseconds for the Ethernet PTP registers. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param heth: pointer to a ETH_TimeTypeDef structure that contains + * time to get + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_PTP_GetTime(ETH_HandleTypeDef *heth, ETH_TimeTypeDef *time) +{ + if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED) + { + /* Get Seconds */ + time->Seconds = heth->Instance->MACSTSUR; + + /* Get NanoSeconds */ + time->NanoSeconds = heth->Instance->MACSTNUR; + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } +} + +/** + * @brief Update time for the Ethernet PTP registers. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param timeupdate: pointer to a ETH_TIMEUPDATETypeDef structure that contains + * the time update information + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_PTP_AddTimeOffset(ETH_HandleTypeDef *heth, ETH_PtpUpdateTypeDef ptpoffsettype, + ETH_TimeTypeDef *timeoffset) +{ + if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED) + { + if (ptpoffsettype == HAL_ETH_PTP_NEGATIVE_UPDATE) + { + /* Set Seconds update */ + heth->Instance->MACSTSUR = ETH_MACSTSUR_VALUE - timeoffset->Seconds + 1U; + + if (READ_BIT(heth->Instance->MACTSCR, ETH_MACTSCR_TSCTRLSSR) == ETH_MACTSCR_TSCTRLSSR) + { + /* Set nanoSeconds update */ + heth->Instance->MACSTNUR = ETH_MACSTNUR_VALUE - timeoffset->NanoSeconds; + } + else + { + /* Set nanoSeconds update */ + heth->Instance->MACSTNUR = ETH_MACSTSUR_VALUE - timeoffset->NanoSeconds + 1U; + } + } + else + { + /* Set Seconds update */ + heth->Instance->MACSTSUR = timeoffset->Seconds; + /* Set nanoSeconds update */ + heth->Instance->MACSTNUR = timeoffset->NanoSeconds; + } + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } +} + +/** + * @brief Insert Timestamp in transmission. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param txtimestampconf: Enable or Disable timestamp in transmission + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_PTP_InsertTxTimestamp(ETH_HandleTypeDef *heth) +{ + ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList; + uint32_t descidx = dmatxdesclist->CurTxDesc; + ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; + + if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED) + { + /* Enable Time Stamp transmission */ + SET_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_TTSE); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } +} + +/** + * @brief Get transmission timestamp. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains + * transmission timestamp + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_PTP_GetTxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp) +{ + ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList; + uint32_t idx = dmatxdesclist->releaseIndex; + ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[idx]; + + if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED) + { + /* Get timestamp low */ + timestamp->TimeStampLow = dmatxdesc->DESC0; + /* Get timestamp high */ + timestamp->TimeStampHigh = dmatxdesc->DESC1; + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } +} + +/** + * @brief Get receive timestamp. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param timestamp: pointer to ETH_TIMESTAMPTypeDef structure that contains + * receive timestamp + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_PTP_GetRxTimestamp(ETH_HandleTypeDef *heth, ETH_TimeStampTypeDef *timestamp) +{ + if (heth->IsPtpConfigured == HAL_ETH_PTP_CONFIGURATED) + { + /* Get timestamp low */ + timestamp->TimeStampLow = heth->RxDescList.TimeStamp.TimeStampLow; + /* Get timestamp high */ + timestamp->TimeStampHigh = heth->RxDescList.TimeStamp.TimeStampHigh; + + /* Return function status */ + return HAL_OK; + } + else + { + /* Return function status */ + return HAL_ERROR; + } +} + +/** + * @brief Register the Tx Ptp callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param txPtpCallback: Function to handle Ptp transmission + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_RegisterTxPtpCallback(ETH_HandleTypeDef *heth, pETH_txPtpCallbackTypeDef txPtpCallback) +{ + if (txPtpCallback == NULL) + { + /* No buffer to save */ + return HAL_ERROR; + } + /* Set Function to handle Tx Ptp */ + heth->txPtpCallback = txPtpCallback; + + return HAL_OK; +} + +/** + * @brief Unregister the Tx Ptp callback. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_UnRegisterTxPtpCallback(ETH_HandleTypeDef *heth) +{ + /* Set function to allocate buffer */ + heth->txPtpCallback = HAL_ETH_TxPtpCallback; + + return HAL_OK; +} + +/** + * @brief Tx Ptp callback. + * @param buff: pointer to application buffer + * @retval None + */ +__weak void HAL_ETH_TxPtpCallback(uint32_t *buff, ETH_TimeStampTypeDef *timestamp) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(buff); + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ETH_TxPtpCallback could be implemented in the user file + */ +} +#endif /* HAL_ETH_USE_PTP */ + +/** + * @brief This function handles ETH interrupt request. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ +void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth) +{ + uint32_t macirqenable; + + /* Packet received */ + if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMACSR_RI)) + { + if (__HAL_ETH_DMA_GET_IT_SOURCE(heth, ETH_DMACIER_RIE)) + { + /* Clear the Eth DMA Rx IT pending bits */ + __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMACSR_RI | ETH_DMACSR_NIS); + +#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) + /*Call registered Receive complete callback*/ + heth->RxCpltCallback(heth); +#else + /* Receive complete callback */ + HAL_ETH_RxCpltCallback(heth); +#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + } + } + + /* Packet transmitted */ + if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMACSR_TI)) + { + if (__HAL_ETH_DMA_GET_IT_SOURCE(heth, ETH_DMACIER_TIE)) + { + /* Clear the Eth DMA Tx IT pending bits */ + __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMACSR_TI | ETH_DMACSR_NIS); + +#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) + /*Call registered Transmit complete callback*/ + heth->TxCpltCallback(heth); +#else + /* Transfer complete callback */ + HAL_ETH_TxCpltCallback(heth); +#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + } + } + + /* ETH DMA Error */ + if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMACSR_AIS)) + { + if (__HAL_ETH_DMA_GET_IT_SOURCE(heth, ETH_DMACIER_AIE)) + { + heth->ErrorCode |= HAL_ETH_ERROR_DMA; + /* if fatal bus error occurred */ + if (__HAL_ETH_DMA_GET_IT(heth, ETH_DMACSR_FBE)) + { + /* Get DMA error code */ + heth->DMAErrorCode = READ_BIT(heth->Instance->DMACSR, (ETH_DMACSR_FBE | ETH_DMACSR_TPS | ETH_DMACSR_RPS)); + + /* Disable all interrupts */ + __HAL_ETH_DMA_DISABLE_IT(heth, ETH_DMACIER_NIE | ETH_DMACIER_AIE); + + /* Set HAL state to ERROR */ + heth->gState = HAL_ETH_STATE_ERROR; + } + else + { + /* Get DMA error status */ + heth->DMAErrorCode = READ_BIT(heth->Instance->DMACSR, (ETH_DMACSR_CDE | ETH_DMACSR_ETI | ETH_DMACSR_RWT | + ETH_DMACSR_RBU | ETH_DMACSR_AIS)); + + /* Clear the interrupt summary flag */ + __HAL_ETH_DMA_CLEAR_IT(heth, (ETH_DMACSR_CDE | ETH_DMACSR_ETI | ETH_DMACSR_RWT | + ETH_DMACSR_RBU | ETH_DMACSR_AIS)); + } +#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) + /* Call registered Error callback*/ + heth->ErrorCallback(heth); +#else + /* Ethernet DMA Error callback */ + HAL_ETH_ErrorCallback(heth); +#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + + } + } + + /* ETH MAC Error IT */ + macirqenable = heth->Instance->MACIER; + if (((macirqenable & ETH_MACIER_RXSTSIE) == ETH_MACIER_RXSTSIE) || \ + ((macirqenable & ETH_MACIER_TXSTSIE) == ETH_MACIER_TXSTSIE)) + { + heth->ErrorCode |= HAL_ETH_ERROR_MAC; + + /* Get MAC Rx Tx status and clear Status register pending bit */ + heth->MACErrorCode = READ_REG(heth->Instance->MACRXTXSR); + + heth->gState = HAL_ETH_STATE_ERROR; + +#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) + /* Call registered Error callback*/ + heth->ErrorCallback(heth); +#else + /* Ethernet Error callback */ + HAL_ETH_ErrorCallback(heth); +#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + heth->MACErrorCode = (uint32_t)(0x0U); + } + + /* ETH PMT IT */ + if (__HAL_ETH_MAC_GET_IT(heth, ETH_MAC_PMT_IT)) + { + /* Get MAC Wake-up source and clear the status register pending bit */ + heth->MACWakeUpEvent = READ_BIT(heth->Instance->MACPCSR, (ETH_MACPCSR_RWKPRCVD | ETH_MACPCSR_MGKPRCVD)); + +#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) + /* Call registered PMT callback*/ + heth->PMTCallback(heth); +#else + /* Ethernet PMT callback */ + HAL_ETH_PMTCallback(heth); +#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + + heth->MACWakeUpEvent = (uint32_t)(0x0U); + } + + /* ETH EEE IT */ + if (__HAL_ETH_MAC_GET_IT(heth, ETH_MAC_LPI_IT)) + { + /* Get MAC LPI interrupt source and clear the status register pending bit */ + heth->MACLPIEvent = READ_BIT(heth->Instance->MACPCSR, 0x0000000FU); + +#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) + /* Call registered EEE callback*/ + heth->EEECallback(heth); +#else + /* Ethernet EEE callback */ + HAL_ETH_EEECallback(heth); +#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + + heth->MACLPIEvent = (uint32_t)(0x0U); + } + + /* check ETH WAKEUP exti flag */ + if (__HAL_ETH_WAKEUP_EXTI_GET_FLAG(ETH_WAKEUP_EXTI_LINE) != (uint32_t)RESET) + { + /* Clear ETH WAKEUP Exti pending bit */ + __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE); +#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) + /* Call registered WakeUp callback*/ + heth->WakeUpCallback(heth); +#else + /* ETH WAKEUP callback */ + HAL_ETH_WakeUpCallback(heth); +#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + } +} + +/** + * @brief Tx Transfer completed callbacks. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +__weak void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(heth); + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ETH_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Transfer completed callbacks. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +__weak void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(heth); + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ETH_RxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Ethernet transfer error callbacks + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +__weak void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(heth); + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ETH_ErrorCallback could be implemented in the user file + */ +} + +/** + * @brief Ethernet Power Management module IT callback + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +__weak void HAL_ETH_PMTCallback(ETH_HandleTypeDef *heth) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(heth); + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ETH_PMTCallback could be implemented in the user file + */ +} + +/** + * @brief Energy Efficient Etherent IT callback + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +__weak void HAL_ETH_EEECallback(ETH_HandleTypeDef *heth) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(heth); + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ETH_EEECallback could be implemented in the user file + */ +} + +/** + * @brief ETH WAKEUP interrupt callback + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +__weak void HAL_ETH_WakeUpCallback(ETH_HandleTypeDef *heth) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(heth); + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ETH_WakeUpCallback could be implemented in the user file + */ +} + +/** + * @brief Read a PHY register + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param PHYAddr: PHY port address, must be a value from 0 to 31 + * @param PHYReg: PHY register address, must be a value from 0 to 31 + * @param pRegValue: parameter to hold read value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, + uint32_t *pRegValue) +{ + uint32_t tickstart; + uint32_t tmpreg; + + /* Check for the Busy flag */ + if (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) != (uint32_t)RESET) + { + return HAL_ERROR; + } + + /* Get the MACMDIOAR value */ + WRITE_REG(tmpreg, heth->Instance->MACMDIOAR); + + /* Prepare the MDIO Address Register value + - Set the PHY device address + - Set the PHY register address + - Set the read mode + - Set the MII Busy bit */ + + MODIFY_REG(tmpreg, ETH_MACMDIOAR_PA, (PHYAddr << 21)); + MODIFY_REG(tmpreg, ETH_MACMDIOAR_RDA, (PHYReg << 16)); + MODIFY_REG(tmpreg, ETH_MACMDIOAR_MOC, ETH_MACMDIOAR_MOC_RD); + SET_BIT(tmpreg, ETH_MACMDIOAR_MB); + + /* Write the result value into the MDII Address register */ + WRITE_REG(heth->Instance->MACMDIOAR, tmpreg); + + tickstart = HAL_GetTick(); + + /* Wait for the Busy flag */ + while (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) > 0U) + { + if (((HAL_GetTick() - tickstart) > ETH_MDIO_BUS_TIMEOUT)) + { + return HAL_ERROR; + } + } + + /* Get MACMIIDR value */ + WRITE_REG(*pRegValue, (uint16_t)heth->Instance->MACMDIODR); + + return HAL_OK; +} + + +/** + * @brief Writes to a PHY register. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param PHYAddr: PHY port address, must be a value from 0 to 31 + * @param PHYReg: PHY register address, must be a value from 0 to 31 + * @param RegValue: the value to write + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_WritePHYRegister(const ETH_HandleTypeDef *heth, uint32_t PHYAddr, uint32_t PHYReg, + uint32_t RegValue) +{ + uint32_t tickstart; + uint32_t tmpreg; + + /* Check for the Busy flag */ + if (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) != (uint32_t)RESET) + { + return HAL_ERROR; + } + + /* Get the MACMDIOAR value */ + WRITE_REG(tmpreg, heth->Instance->MACMDIOAR); + + /* Prepare the MDIO Address Register value + - Set the PHY device address + - Set the PHY register address + - Set the write mode + - Set the MII Busy bit */ + + MODIFY_REG(tmpreg, ETH_MACMDIOAR_PA, (PHYAddr << 21)); + MODIFY_REG(tmpreg, ETH_MACMDIOAR_RDA, (PHYReg << 16)); + MODIFY_REG(tmpreg, ETH_MACMDIOAR_MOC, ETH_MACMDIOAR_MOC_WR); + SET_BIT(tmpreg, ETH_MACMDIOAR_MB); + + /* Give the value to the MII data register */ + WRITE_REG(ETH->MACMDIODR, (uint16_t)RegValue); + + /* Write the result value into the MII Address register */ + WRITE_REG(ETH->MACMDIOAR, tmpreg); + + tickstart = HAL_GetTick(); + + /* Wait for the Busy flag */ + while (READ_BIT(heth->Instance->MACMDIOAR, ETH_MACMDIOAR_MB) > 0U) + { + if (((HAL_GetTick() - tickstart) > ETH_MDIO_BUS_TIMEOUT)) + { + return HAL_ERROR; + } + } + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup ETH_Exported_Functions_Group3 Peripheral Control functions + * @brief ETH control functions + * +@verbatim + ============================================================================== + ##### Peripheral Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control the ETH + peripheral. + +@endverbatim + * @{ + */ +/** + * @brief Get the configuration of the MAC and MTL subsystems. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param macconf: pointer to a ETH_MACConfigTypeDef structure that will hold + * the configuration of the MAC. + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_ETH_GetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf) +{ + if (macconf == NULL) + { + return HAL_ERROR; + } + + /* Get MAC parameters */ + macconf->PreambleLength = READ_BIT(heth->Instance->MACCR, ETH_MACCR_PRELEN); + macconf->DeferralCheck = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DC) >> 4) > 0U) ? ENABLE : DISABLE; + macconf->BackOffLimit = READ_BIT(heth->Instance->MACCR, ETH_MACCR_BL); + macconf->RetryTransmission = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DR) >> 8) == 0U) ? ENABLE : DISABLE; + macconf->CarrierSenseDuringTransmit = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DCRS) >> 9) > 0U) + ? ENABLE : DISABLE; + macconf->ReceiveOwn = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_DO) >> 10) == 0U) ? ENABLE : DISABLE; + macconf->CarrierSenseBeforeTransmit = ((READ_BIT(heth->Instance->MACCR, + ETH_MACCR_ECRSFD) >> 11) > 0U) ? ENABLE : DISABLE; + macconf->LoopbackMode = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_LM) >> 12) > 0U) ? ENABLE : DISABLE; + macconf->DuplexMode = READ_BIT(heth->Instance->MACCR, ETH_MACCR_DM); + macconf->Speed = READ_BIT(heth->Instance->MACCR, ETH_MACCR_FES); + macconf->JumboPacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_JE) >> 16) > 0U) ? ENABLE : DISABLE; + macconf->Jabber = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_JD) >> 17) == 0U) ? ENABLE : DISABLE; + macconf->Watchdog = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_WD) >> 19) == 0U) ? ENABLE : DISABLE; + macconf->AutomaticPadCRCStrip = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_ACS) >> 20) > 0U) ? ENABLE : DISABLE; + macconf->CRCStripTypePacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_CST) >> 21) > 0U) ? ENABLE : DISABLE; + macconf->Support2KPacket = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_S2KP) >> 22) > 0U) ? ENABLE : DISABLE; + macconf->GiantPacketSizeLimitControl = ((READ_BIT(heth->Instance->MACCR, + ETH_MACCR_GPSLCE) >> 23) > 0U) ? ENABLE : DISABLE; + macconf->InterPacketGapVal = READ_BIT(heth->Instance->MACCR, ETH_MACCR_IPG); + macconf->ChecksumOffload = ((READ_BIT(heth->Instance->MACCR, ETH_MACCR_IPC) >> 27) > 0U) ? ENABLE : DISABLE; + macconf->SourceAddrControl = READ_BIT(heth->Instance->MACCR, ETH_MACCR_SARC); + + macconf->GiantPacketSizeLimit = READ_BIT(heth->Instance->MACECR, ETH_MACECR_GPSL); + macconf->CRCCheckingRxPackets = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_DCRCC) >> 16) == 0U) ? ENABLE : DISABLE; + macconf->SlowProtocolDetect = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_SPEN) >> 17) > 0U) ? ENABLE : DISABLE; + macconf->UnicastSlowProtocolPacketDetect = ((READ_BIT(heth->Instance->MACECR, + ETH_MACECR_USP) >> 18) > 0U) ? ENABLE : DISABLE; + macconf->ExtendedInterPacketGap = ((READ_BIT(heth->Instance->MACECR, ETH_MACECR_EIPGEN) >> 24) > 0U) + ? ENABLE : DISABLE; + macconf->ExtendedInterPacketGapVal = READ_BIT(heth->Instance->MACECR, ETH_MACECR_EIPG) >> 25; + + macconf->ProgrammableWatchdog = ((READ_BIT(heth->Instance->MACWTR, ETH_MACWTR_PWE) >> 8) > 0U) ? ENABLE : DISABLE; + macconf->WatchdogTimeout = READ_BIT(heth->Instance->MACWTR, ETH_MACWTR_WTO); + + macconf->TransmitFlowControl = ((READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_TFE) >> 1) > 0U) ? ENABLE : DISABLE; + macconf->ZeroQuantaPause = ((READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_DZPQ) >> 7) == 0U) ? ENABLE : DISABLE; + macconf->PauseLowThreshold = READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_PLT); + macconf->PauseTime = (READ_BIT(heth->Instance->MACTFCR, ETH_MACTFCR_PT) >> 16); + macconf->ReceiveFlowControl = (READ_BIT(heth->Instance->MACRFCR, ETH_MACRFCR_RFE) > 0U) ? ENABLE : DISABLE; + macconf->UnicastPausePacketDetect = ((READ_BIT(heth->Instance->MACRFCR, ETH_MACRFCR_UP) >> 1) > 0U) + ? ENABLE : DISABLE; + + macconf->TransmitQueueMode = READ_BIT(heth->Instance->MTLTQOMR, (ETH_MTLTQOMR_TTC | ETH_MTLTQOMR_TSF)); + + macconf->ReceiveQueueMode = READ_BIT(heth->Instance->MTLRQOMR, (ETH_MTLRQOMR_RTC | ETH_MTLRQOMR_RSF)); + macconf->ForwardRxUndersizedGoodPacket = ((READ_BIT(heth->Instance->MTLRQOMR, + ETH_MTLRQOMR_FUP) >> 3) > 0U) ? ENABLE : DISABLE; + macconf->ForwardRxErrorPacket = ((READ_BIT(heth->Instance->MTLRQOMR, ETH_MTLRQOMR_FEP) >> 4) > 0U) ? ENABLE : DISABLE; + macconf->DropTCPIPChecksumErrorPacket = ((READ_BIT(heth->Instance->MTLRQOMR, + ETH_MTLRQOMR_DISTCPEF) >> 6) == 0U) ? ENABLE : DISABLE; + + return HAL_OK; +} + +/** + * @brief Get the configuration of the DMA. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold + * the configuration of the ETH DMA. + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_ETH_GetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf) +{ + if (dmaconf == NULL) + { + return HAL_ERROR; + } + + dmaconf->AddressAlignedBeats = ((READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_AAL) >> 12) > 0U) ? ENABLE : DISABLE; + dmaconf->BurstMode = READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_FB | ETH_DMASBMR_MB); + dmaconf->RebuildINCRxBurst = ((READ_BIT(heth->Instance->DMASBMR, ETH_DMASBMR_RB) >> 15) > 0U) ? ENABLE : DISABLE; + + dmaconf->DMAArbitration = READ_BIT(heth->Instance->DMAMR, (ETH_DMAMR_TXPR | ETH_DMAMR_PR | ETH_DMAMR_DA)); + + dmaconf->PBLx8Mode = ((READ_BIT(heth->Instance->DMACCR, ETH_DMACCR_8PBL) >> 16) > 0U) ? ENABLE : DISABLE; + dmaconf->MaximumSegmentSize = READ_BIT(heth->Instance->DMACCR, ETH_DMACCR_MSS); + + dmaconf->FlushRxPacket = ((READ_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_RPF) >> 31) > 0U) ? ENABLE : DISABLE; + dmaconf->RxDMABurstLength = READ_BIT(heth->Instance->DMACRCR, ETH_DMACRCR_RPBL); + + dmaconf->SecondPacketOperate = ((READ_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_OSP) >> 4) > 0U) ? ENABLE : DISABLE; + dmaconf->TCPSegmentation = ((READ_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_TSE) >> 12) > 0U) ? ENABLE : DISABLE; + dmaconf->TxDMABurstLength = READ_BIT(heth->Instance->DMACTCR, ETH_DMACTCR_TPBL); + + + return HAL_OK; +} + +/** + * @brief Set the MAC configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param macconf: pointer to a ETH_MACConfigTypeDef structure that contains + * the configuration of the MAC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_SetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf) +{ + if (macconf == NULL) + { + return HAL_ERROR; + } + + if (heth->gState == HAL_ETH_STATE_READY) + { + ETH_SetMACConfig(heth, macconf); + + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Set the ETH DMA configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param dmaconf: pointer to a ETH_DMAConfigTypeDef structure that will hold + * the configuration of the ETH DMA. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_SetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf) +{ + if (dmaconf == NULL) + { + return HAL_ERROR; + } + + if (heth->gState == HAL_ETH_STATE_READY) + { + ETH_SetDMAConfig(heth, dmaconf); + + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Configures the Clock range of ETH MDIO interface. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +void HAL_ETH_SetMDIOClockRange(ETH_HandleTypeDef *heth) +{ + uint32_t hclk; + uint32_t tmpreg; + + /* Get the ETHERNET MACMDIOAR value */ + tmpreg = (heth->Instance)->MACMDIOAR; + + /* Clear CSR Clock Range bits */ + tmpreg &= ~ETH_MACMDIOAR_CR; + + /* Get hclk frequency value */ + hclk = HAL_RCC_GetHCLKFreq(); + + /* Set CR bits depending on hclk value */ + if ((hclk >= 20000000U) && (hclk < 35000000U)) + { + /* CSR Clock Range between 20-35 MHz */ + tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV16; + } + else if ((hclk >= 35000000U) && (hclk < 60000000U)) + { + /* CSR Clock Range between 35-60 MHz */ + tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV26; + } + else if ((hclk >= 60000000U) && (hclk < 100000000U)) + { + /* CSR Clock Range between 60-100 MHz */ + tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV42; + } + else if ((hclk >= 100000000U) && (hclk < 150000000U)) + { + /* CSR Clock Range between 100-150 MHz */ + tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV62; + } + else if ((hclk >= 150000000U) && (hclk <= 250000000U)) + { + /* CSR Clock Range between 150-200 MHz */ + tmpreg |= (uint32_t)ETH_MACMDIOAR_CR_DIV102; + } + else /*(hclk >= 250000000U) && (hclk <= 300000000U)*/ + { + /* CSR Clock Range between 250-300 MHz */ + tmpreg |= (uint32_t)(ETH_MACMDIOAR_CR_DIV124); + } + + /* Configure the CSR Clock Range */ + (heth->Instance)->MACMDIOAR = (uint32_t)tmpreg; +} + +/** + * @brief Set the ETH MAC (L2) Filters configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that contains + * the configuration of the ETH MAC filters. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_SetMACFilterConfig(ETH_HandleTypeDef *heth, const ETH_MACFilterConfigTypeDef *pFilterConfig) +{ + uint32_t filterconfig; + + if (pFilterConfig == NULL) + { + return HAL_ERROR; + } + + filterconfig = ((uint32_t)pFilterConfig->PromiscuousMode | + ((uint32_t)pFilterConfig->HashUnicast << 1) | + ((uint32_t)pFilterConfig->HashMulticast << 2) | + ((uint32_t)pFilterConfig->DestAddrInverseFiltering << 3) | + ((uint32_t)pFilterConfig->PassAllMulticast << 4) | + ((uint32_t)((pFilterConfig->BroadcastFilter == DISABLE) ? 1U : 0U) << 5) | + ((uint32_t)pFilterConfig->SrcAddrInverseFiltering << 8) | + ((uint32_t)pFilterConfig->SrcAddrFiltering << 9) | + ((uint32_t)pFilterConfig->HachOrPerfectFilter << 10) | + ((uint32_t)pFilterConfig->ReceiveAllMode << 31) | + pFilterConfig->ControlPacketsFilter); + + MODIFY_REG(heth->Instance->MACPFR, ETH_MACPFR_MASK, filterconfig); + + return HAL_OK; +} + +/** + * @brief Get the ETH MAC (L2) Filters configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pFilterConfig: pointer to a ETH_MACFilterConfigTypeDef structure that will hold + * the configuration of the ETH MAC filters. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_GetMACFilterConfig(ETH_HandleTypeDef *heth, ETH_MACFilterConfigTypeDef *pFilterConfig) +{ + if (pFilterConfig == NULL) + { + return HAL_ERROR; + } + + pFilterConfig->PromiscuousMode = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PR)) > 0U) ? ENABLE : DISABLE; + pFilterConfig->HashUnicast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HUC) >> 1) > 0U) ? ENABLE : DISABLE; + pFilterConfig->HashMulticast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HMC) >> 2) > 0U) ? ENABLE : DISABLE; + pFilterConfig->DestAddrInverseFiltering = ((READ_BIT(heth->Instance->MACPFR, + ETH_MACPFR_DAIF) >> 3) > 0U) ? ENABLE : DISABLE; + pFilterConfig->PassAllMulticast = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PM) >> 4) > 0U) ? ENABLE : DISABLE; + pFilterConfig->BroadcastFilter = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_DBF) >> 5) == 0U) ? ENABLE : DISABLE; + pFilterConfig->ControlPacketsFilter = READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_PCF); + pFilterConfig->SrcAddrInverseFiltering = ((READ_BIT(heth->Instance->MACPFR, + ETH_MACPFR_SAIF) >> 8) > 0U) ? ENABLE : DISABLE; + pFilterConfig->SrcAddrFiltering = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_SAF) >> 9) > 0U) ? ENABLE : DISABLE; + pFilterConfig->HachOrPerfectFilter = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_HPF) >> 10) > 0U) + ? ENABLE : DISABLE; + pFilterConfig->ReceiveAllMode = ((READ_BIT(heth->Instance->MACPFR, ETH_MACPFR_RA) >> 31) > 0U) ? ENABLE : DISABLE; + + return HAL_OK; +} + +/** + * @brief Set the source MAC Address to be matched. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param AddrNbr: The MAC address to configure + * This parameter must be a value of the following: + * ETH_MAC_ADDRESS1 + * ETH_MAC_ADDRESS2 + * ETH_MAC_ADDRESS3 + * @param pMACAddr: Pointer to MAC address buffer data (6 bytes) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_SetSourceMACAddrMatch(const ETH_HandleTypeDef *heth, uint32_t AddrNbr, + const uint8_t *pMACAddr) +{ + uint32_t macaddrlr; + uint32_t macaddrhr; + + if (pMACAddr == NULL) + { + return HAL_ERROR; + } + + /* Get mac addr high reg offset */ + macaddrhr = ((uint32_t) &(heth->Instance->MACA0HR) + AddrNbr); + /* Get mac addr low reg offset */ + macaddrlr = ((uint32_t) &(heth->Instance->MACA0LR) + AddrNbr); + + /* Set MAC addr bits 32 to 47 */ + (*(__IO uint32_t *)macaddrhr) = (((uint32_t)(pMACAddr[5]) << 8) | (uint32_t)pMACAddr[4]); + /* Set MAC addr bits 0 to 31 */ + (*(__IO uint32_t *)macaddrlr) = (((uint32_t)(pMACAddr[3]) << 24) | ((uint32_t)(pMACAddr[2]) << 16) | + ((uint32_t)(pMACAddr[1]) << 8) | (uint32_t)pMACAddr[0]); + + /* Enable address and set source address bit */ + (*(__IO uint32_t *)macaddrhr) |= (ETH_MACAHR_SA | ETH_MACAHR_AE); + + return HAL_OK; +} + +/** + * @brief Set the ETH Hash Table Value. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pHashTable: pointer to a table of two 32 bit values, that contains + * the 64 bits of the hash table. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_SetHashTable(ETH_HandleTypeDef *heth, uint32_t *pHashTable) +{ + if (pHashTable == NULL) + { + return HAL_ERROR; + } + + heth->Instance->MACHT0R = pHashTable[0]; + heth->Instance->MACHT1R = pHashTable[1]; + + return HAL_OK; +} + +/** + * @brief Set the VLAN Identifier for Rx packets + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param ComparisonBits: 12 or 16 bit comparison mode + must be a value of @ref ETH_VLAN_Tag_Comparison + * @param VLANIdentifier: VLAN Identifier value + * @retval None + */ +void HAL_ETH_SetRxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t ComparisonBits, uint32_t VLANIdentifier) +{ + if (ComparisonBits == ETH_VLANTAGCOMPARISON_16BIT) + { + MODIFY_REG(heth->Instance->MACVTR, ETH_MACVTR_VL, VLANIdentifier); + CLEAR_BIT(heth->Instance->MACVTR, ETH_MACVTR_ETV); + } + else + { + MODIFY_REG(heth->Instance->MACVTR, ETH_MACVTR_VL_VID, VLANIdentifier); + SET_BIT(heth->Instance->MACVTR, ETH_MACVTR_ETV); + } +} + +/** + * @brief Enters the Power down mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pPowerDownConfig: a pointer to ETH_PowerDownConfigTypeDef structure + * that contains the Power Down configuration + * @retval None. + */ +void HAL_ETH_EnterPowerDownMode(ETH_HandleTypeDef *heth, const ETH_PowerDownConfigTypeDef *pPowerDownConfig) +{ + uint32_t powerdownconfig; + + powerdownconfig = (((uint32_t)pPowerDownConfig->MagicPacket << 1) | + ((uint32_t)pPowerDownConfig->WakeUpPacket << 2) | + ((uint32_t)pPowerDownConfig->GlobalUnicast << 9) | + ((uint32_t)pPowerDownConfig->WakeUpForward << 10) | + ETH_MACPCSR_PWRDWN); + + /* Enable PMT interrupt */ + __HAL_ETH_MAC_ENABLE_IT(heth, ETH_MACIER_PMTIE); + + MODIFY_REG(heth->Instance->MACPCSR, ETH_MACPCSR_MASK, powerdownconfig); +} + +/** + * @brief Exits from the Power down mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None. + */ +void HAL_ETH_ExitPowerDownMode(ETH_HandleTypeDef *heth) +{ + /* clear wake up sources */ + CLEAR_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_RWKPKTEN | ETH_MACPCSR_MGKPKTEN | ETH_MACPCSR_GLBLUCAST | + ETH_MACPCSR_RWKPFE); + + if (READ_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_PWRDWN) != (uint32_t)RESET) + { + /* Exit power down mode */ + CLEAR_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_PWRDWN); + } + + /* Disable PMT interrupt */ + __HAL_ETH_MAC_DISABLE_IT(heth, ETH_MACIER_PMTIE); +} + +/** + * @brief Set the WakeUp filter. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pFilter: pointer to filter registers values + * @param Count: number of filter registers, must be from 1 to 8. + * @retval None. + */ +HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFilter, uint32_t Count) +{ + uint32_t regindex; + + if (pFilter == NULL) + { + return HAL_ERROR; + } + + /* Reset Filter Pointer */ + SET_BIT(heth->Instance->MACPCSR, ETH_MACPCSR_RWKFILTRST); + + /* Wake up packet filter config */ + for (regindex = 0; regindex < Count; regindex++) + { + /* Write filter regs */ + WRITE_REG(heth->Instance->MACRWKPFR, pFilter[regindex]); + } + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup ETH_Exported_Functions_Group4 Peripheral State and Errors functions + * @brief ETH State and Errors functions + * +@verbatim + ============================================================================== + ##### Peripheral State and Errors functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to return the State of + ETH communication process, return Peripheral Errors occurred during communication + process + + +@endverbatim + * @{ + */ + +/** + * @brief Returns the ETH state. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL state + */ +HAL_ETH_StateTypeDef HAL_ETH_GetState(const ETH_HandleTypeDef *heth) +{ + return heth->gState; +} + +/** + * @brief Returns the ETH error code + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval ETH Error Code + */ +uint32_t HAL_ETH_GetError(const ETH_HandleTypeDef *heth) +{ + return heth->ErrorCode; +} + +/** + * @brief Returns the ETH DMA error code + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval ETH DMA Error Code + */ +uint32_t HAL_ETH_GetDMAError(const ETH_HandleTypeDef *heth) +{ + return heth->DMAErrorCode; +} + +/** + * @brief Returns the ETH MAC error code + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval ETH MAC Error Code + */ +uint32_t HAL_ETH_GetMACError(const ETH_HandleTypeDef *heth) +{ + return heth->MACErrorCode; +} + +/** + * @brief Returns the ETH MAC WakeUp event source + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval ETH MAC WakeUp event source + */ +uint32_t HAL_ETH_GetMACWakeUpSource(const ETH_HandleTypeDef *heth) +{ + return heth->MACWakeUpEvent; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup ETH_Private_Functions ETH Private Functions + * @{ + */ + + +static void ETH_SetMACConfig(ETH_HandleTypeDef *heth, ETH_MACConfigTypeDef *macconf) +{ + uint32_t macregval; + + /*------------------------ MACCR Configuration --------------------*/ + macregval = (macconf->InterPacketGapVal | + macconf->SourceAddrControl | + ((uint32_t)macconf->ChecksumOffload << 27) | + ((uint32_t)macconf->GiantPacketSizeLimitControl << 23) | + ((uint32_t)macconf->Support2KPacket << 22) | + ((uint32_t)macconf->CRCStripTypePacket << 21) | + ((uint32_t)macconf->AutomaticPadCRCStrip << 20) | + ((uint32_t)((macconf->Watchdog == DISABLE) ? 1U : 0U) << 19) | + ((uint32_t)((macconf->Jabber == DISABLE) ? 1U : 0U) << 17) | + ((uint32_t)macconf->JumboPacket << 16) | + macconf->Speed | + macconf->DuplexMode | + ((uint32_t)macconf->LoopbackMode << 12) | + ((uint32_t)macconf->CarrierSenseBeforeTransmit << 11) | + ((uint32_t)((macconf->ReceiveOwn == DISABLE) ? 1U : 0U) << 10) | + ((uint32_t)macconf->CarrierSenseDuringTransmit << 9) | + ((uint32_t)((macconf->RetryTransmission == DISABLE) ? 1U : 0U) << 8) | + macconf->BackOffLimit | + ((uint32_t)macconf->DeferralCheck << 4) | + macconf->PreambleLength); + + /* Write to MACCR */ + MODIFY_REG(heth->Instance->MACCR, ETH_MACCR_MASK, macregval); + + /*------------------------ MACECR Configuration --------------------*/ + macregval = ((macconf->ExtendedInterPacketGapVal << 25) | + ((uint32_t)macconf->ExtendedInterPacketGap << 24) | + ((uint32_t)macconf->UnicastSlowProtocolPacketDetect << 18) | + ((uint32_t)macconf->SlowProtocolDetect << 17) | + ((uint32_t)((macconf->CRCCheckingRxPackets == DISABLE) ? 1U : 0U) << 16) | + macconf->GiantPacketSizeLimit); + + /* Write to MACECR */ + MODIFY_REG(heth->Instance->MACECR, ETH_MACECR_MASK, macregval); + + /*------------------------ MACWTR Configuration --------------------*/ + macregval = (((uint32_t)macconf->ProgrammableWatchdog << 8) | + macconf->WatchdogTimeout); + + /* Write to MACWTR */ + MODIFY_REG(heth->Instance->MACWTR, ETH_MACWTR_MASK, macregval); + + + /*------------------------ MACTFCR Configuration --------------------*/ + macregval = (((uint32_t)macconf->TransmitFlowControl << 1) | + macconf->PauseLowThreshold | + ((uint32_t)((macconf->ZeroQuantaPause == DISABLE) ? 1U : 0U) << 7) | + (macconf->PauseTime << 16)); + + /* Write to MACTFCR */ + MODIFY_REG(heth->Instance->MACTFCR, ETH_MACTFCR_MASK, macregval); + + /*------------------------ MACRFCR Configuration --------------------*/ + macregval = ((uint32_t)macconf->ReceiveFlowControl | + ((uint32_t)macconf->UnicastPausePacketDetect << 1)); + + /* Write to MACRFCR */ + MODIFY_REG(heth->Instance->MACRFCR, ETH_MACRFCR_MASK, macregval); + + /*------------------------ MTLTQOMR Configuration --------------------*/ + /* Write to MTLTQOMR */ + MODIFY_REG(heth->Instance->MTLTQOMR, ETH_MTLTQOMR_MASK, macconf->TransmitQueueMode); + + /*------------------------ MTLRQOMR Configuration --------------------*/ + macregval = (macconf->ReceiveQueueMode | + ((uint32_t)((macconf->DropTCPIPChecksumErrorPacket == DISABLE) ? 1U : 0U) << 6) | + ((uint32_t)macconf->ForwardRxErrorPacket << 4) | + ((uint32_t)macconf->ForwardRxUndersizedGoodPacket << 3)); + + /* Write to MTLRQOMR */ + MODIFY_REG(heth->Instance->MTLRQOMR, ETH_MTLRQOMR_MASK, macregval); +} + +static void ETH_SetDMAConfig(ETH_HandleTypeDef *heth, ETH_DMAConfigTypeDef *dmaconf) +{ + uint32_t dmaregval; + + /*------------------------ DMAMR Configuration --------------------*/ + MODIFY_REG(heth->Instance->DMAMR, ETH_DMAMR_MASK, dmaconf->DMAArbitration); + + /*------------------------ DMASBMR Configuration --------------------*/ + dmaregval = (((uint32_t)dmaconf->AddressAlignedBeats << 12) | + dmaconf->BurstMode | + ((uint32_t)dmaconf->RebuildINCRxBurst << 15)); + + MODIFY_REG(heth->Instance->DMASBMR, ETH_DMASBMR_MASK, dmaregval); + + /*------------------------ DMACCR Configuration --------------------*/ + dmaregval = (((uint32_t)dmaconf->PBLx8Mode << 16) | + dmaconf->MaximumSegmentSize); + MODIFY_REG(heth->Instance->DMACCR, ETH_DMACCR_MASK, dmaregval); + + /*------------------------ DMACTCR Configuration --------------------*/ + dmaregval = (dmaconf->TxDMABurstLength | + ((uint32_t)dmaconf->SecondPacketOperate << 4) | + ((uint32_t)dmaconf->TCPSegmentation << 12)); + + MODIFY_REG(heth->Instance->DMACTCR, ETH_DMACTCR_MASK, dmaregval); + + /*------------------------ DMACRCR Configuration --------------------*/ + dmaregval = (((uint32_t)dmaconf->FlushRxPacket << 31) | + dmaconf->RxDMABurstLength); + + /* Write to DMACRCR */ + MODIFY_REG(heth->Instance->DMACRCR, ETH_DMACRCR_MASK, dmaregval); +} + +/** + * @brief Configures Ethernet MAC and DMA with default parameters. + * called by HAL_ETH_Init() API. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ +static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth) +{ + ETH_MACConfigTypeDef macDefaultConf; + ETH_DMAConfigTypeDef dmaDefaultConf; + + /*--------------- ETHERNET MAC registers default Configuration --------------*/ + macDefaultConf.AutomaticPadCRCStrip = ENABLE; + macDefaultConf.BackOffLimit = ETH_BACKOFFLIMIT_10; + macDefaultConf.CarrierSenseBeforeTransmit = DISABLE; + macDefaultConf.CarrierSenseDuringTransmit = DISABLE; + macDefaultConf.ChecksumOffload = ENABLE; + macDefaultConf.CRCCheckingRxPackets = ENABLE; + macDefaultConf.CRCStripTypePacket = ENABLE; + macDefaultConf.DeferralCheck = DISABLE; + macDefaultConf.DropTCPIPChecksumErrorPacket = ENABLE; + macDefaultConf.DuplexMode = ETH_FULLDUPLEX_MODE; + macDefaultConf.ExtendedInterPacketGap = DISABLE; + macDefaultConf.ExtendedInterPacketGapVal = 0x0U; + macDefaultConf.ForwardRxErrorPacket = DISABLE; + macDefaultConf.ForwardRxUndersizedGoodPacket = DISABLE; + macDefaultConf.GiantPacketSizeLimit = 0x618U; + macDefaultConf.GiantPacketSizeLimitControl = DISABLE; + macDefaultConf.InterPacketGapVal = ETH_INTERPACKETGAP_96BIT; + macDefaultConf.Jabber = ENABLE; + macDefaultConf.JumboPacket = DISABLE; + macDefaultConf.LoopbackMode = DISABLE; + macDefaultConf.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS_4; + macDefaultConf.PauseTime = 0x0U; + macDefaultConf.PreambleLength = ETH_PREAMBLELENGTH_7; + macDefaultConf.ProgrammableWatchdog = DISABLE; + macDefaultConf.ReceiveFlowControl = DISABLE; + macDefaultConf.ReceiveOwn = ENABLE; + macDefaultConf.ReceiveQueueMode = ETH_RECEIVESTOREFORWARD; + macDefaultConf.RetryTransmission = ENABLE; + macDefaultConf.SlowProtocolDetect = DISABLE; + macDefaultConf.SourceAddrControl = ETH_SOURCEADDRESS_REPLACE_ADDR0; + macDefaultConf.Speed = ETH_SPEED_100M; + macDefaultConf.Support2KPacket = DISABLE; + macDefaultConf.TransmitQueueMode = ETH_TRANSMITSTOREFORWARD; + macDefaultConf.TransmitFlowControl = DISABLE; + macDefaultConf.UnicastPausePacketDetect = DISABLE; + macDefaultConf.UnicastSlowProtocolPacketDetect = DISABLE; + macDefaultConf.Watchdog = ENABLE; + macDefaultConf.WatchdogTimeout = ETH_MACWTR_WTO_2KB; + macDefaultConf.ZeroQuantaPause = ENABLE; + + /* MAC default configuration */ + ETH_SetMACConfig(heth, &macDefaultConf); + + /*--------------- ETHERNET DMA registers default Configuration --------------*/ + dmaDefaultConf.AddressAlignedBeats = ENABLE; + dmaDefaultConf.BurstMode = ETH_BURSTLENGTH_FIXED; + dmaDefaultConf.DMAArbitration = ETH_DMAARBITRATION_RX1_TX1; + dmaDefaultConf.FlushRxPacket = DISABLE; + dmaDefaultConf.PBLx8Mode = DISABLE; + dmaDefaultConf.RebuildINCRxBurst = DISABLE; + dmaDefaultConf.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT; + dmaDefaultConf.SecondPacketOperate = DISABLE; + dmaDefaultConf.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT; + dmaDefaultConf.TCPSegmentation = DISABLE; + dmaDefaultConf.MaximumSegmentSize = ETH_SEGMENT_SIZE_DEFAULT; + + /* DMA default configuration */ + ETH_SetDMAConfig(heth, &dmaDefaultConf); +} + + +/** + * @brief Initializes the DMA Tx descriptors. + * called by HAL_ETH_Init() API. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +static void ETH_DMATxDescListInit(ETH_HandleTypeDef *heth) +{ + ETH_DMADescTypeDef *dmatxdesc; + uint32_t i; + + /* Fill each DMATxDesc descriptor with the right values */ + for (i = 0; i < (uint32_t)ETH_TX_DESC_CNT; i++) + { + dmatxdesc = heth->Init.TxDesc + i; + + WRITE_REG(dmatxdesc->DESC0, 0x0U); + WRITE_REG(dmatxdesc->DESC1, 0x0U); + WRITE_REG(dmatxdesc->DESC2, 0x0U); + WRITE_REG(dmatxdesc->DESC3, 0x0U); + + WRITE_REG(heth->TxDescList.TxDesc[i], (uint32_t)dmatxdesc); + + } + + heth->TxDescList.CurTxDesc = 0; + + /* Set Transmit Descriptor Ring Length */ + WRITE_REG(heth->Instance->DMACTDRLR, (ETH_TX_DESC_CNT - 1U)); + + /* Set Transmit Descriptor List Address */ + WRITE_REG(heth->Instance->DMACTDLAR, (uint32_t) heth->Init.TxDesc); + + /* Set Transmit Descriptor Tail pointer */ + WRITE_REG(heth->Instance->DMACTDTPR, (uint32_t) heth->Init.TxDesc); +} + +/** + * @brief Initializes the DMA Rx descriptors in chain mode. + * called by HAL_ETH_Init() API. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +static void ETH_DMARxDescListInit(ETH_HandleTypeDef *heth) +{ + ETH_DMADescTypeDef *dmarxdesc; + uint32_t i; + + for (i = 0; i < (uint32_t)ETH_RX_DESC_CNT; i++) + { + dmarxdesc = heth->Init.RxDesc + i; + + WRITE_REG(dmarxdesc->DESC0, 0x0U); + WRITE_REG(dmarxdesc->DESC1, 0x0U); + WRITE_REG(dmarxdesc->DESC2, 0x0U); + WRITE_REG(dmarxdesc->DESC3, 0x0U); + WRITE_REG(dmarxdesc->BackupAddr0, 0x0U); + WRITE_REG(dmarxdesc->BackupAddr1, 0x0U); + + + /* Set Rx descritors addresses */ + WRITE_REG(heth->RxDescList.RxDesc[i], (uint32_t)dmarxdesc); + + } + + WRITE_REG(heth->RxDescList.RxDescIdx, 0U); + WRITE_REG(heth->RxDescList.RxDescCnt, 0U); + WRITE_REG(heth->RxDescList.RxBuildDescIdx, 0U); + WRITE_REG(heth->RxDescList.RxBuildDescCnt, 0U); + WRITE_REG(heth->RxDescList.ItMode, 0U); + + /* Set Receive Descriptor Ring Length */ + WRITE_REG(heth->Instance->DMACRDRLR, ((uint32_t)(ETH_RX_DESC_CNT - 1U))); + + /* Set Receive Descriptor List Address */ + WRITE_REG(heth->Instance->DMACRDLAR, (uint32_t) heth->Init.RxDesc); + + /* Set Receive Descriptor Tail pointer Address */ + WRITE_REG(heth->Instance->DMACRDTPR, ((uint32_t)(heth->Init.RxDesc + (uint32_t)(ETH_RX_DESC_CNT - 1U)))); +} + +/** + * @brief Prepare Tx DMA descriptor before transmission. + * called by HAL_ETH_Transmit_IT and HAL_ETH_Transmit_IT() API. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pTxConfig: Tx packet configuration + * @param ItMode: Enable or disable Tx EOT interrept + * @retval Status + */ +static uint32_t ETH_Prepare_Tx_Descriptors(ETH_HandleTypeDef *heth, ETH_TxPacketConfig *pTxConfig, uint32_t ItMode) +{ + ETH_TxDescListTypeDef *dmatxdesclist = &heth->TxDescList; + uint32_t descidx = dmatxdesclist->CurTxDesc; + uint32_t firstdescidx = dmatxdesclist->CurTxDesc; + uint32_t idx; + uint32_t descnbr = 0; + ETH_DMADescTypeDef *dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; + + ETH_BufferTypeDef *txbuffer = pTxConfig->TxBuffer; + uint32_t bd_count = 0; + + /* Current Tx Descriptor Owned by DMA: cannot be used by the application */ + if ((READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCWBF_OWN) == ETH_DMATXNDESCWBF_OWN) + || (dmatxdesclist->PacketAddress[descidx] != NULL)) + { + return HAL_ETH_ERROR_BUSY; + } + + /***************************************************************************/ + /***************** Context descriptor configuration (Optional) **********/ + /***************************************************************************/ + /* If VLAN tag is enabled for this packet */ + if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != (uint32_t)RESET) + { + /* Set vlan tag value */ + MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXCDESC_VT, pTxConfig->VlanTag); + /* Set vlan tag valid bit */ + SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_VLTV); + /* Set the descriptor as the vlan input source */ + SET_BIT(heth->Instance->MACVIR, ETH_MACVIR_VLTI); + + /* if inner VLAN is enabled */ + if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_INNERVLANTAG) != (uint32_t)RESET) + { + /* Set inner vlan tag value */ + MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXCDESC_IVT, (pTxConfig->InnerVlanTag << 16)); + /* Set inner vlan tag valid bit */ + SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_IVLTV); + + /* Set Vlan Tag control */ + MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXCDESC_IVTIR, pTxConfig->InnerVlanCtrl); + + /* Set the descriptor as the inner vlan input source */ + SET_BIT(heth->Instance->MACIVIR, ETH_MACIVIR_VLTI); + /* Enable double VLAN processing */ + SET_BIT(heth->Instance->MACVTR, ETH_MACVTR_EDVLP); + } + } + + /* if tcp segmentation is enabled for this packet */ + if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET) + { + /* Set MSS value */ + MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXCDESC_MSS, pTxConfig->MaxSegmentSize); + /* Set MSS valid bit */ + SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_TCMSSV); + } + + if ((READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != (uint32_t)RESET) + || (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET)) + { + /* Set as context descriptor */ + SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_CTXT); + /* Ensure rest of descriptor is written to RAM before the OWN bit */ + __DMB(); + /* Set own bit */ + SET_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_OWN); + /* Increment current tx descriptor index */ + INCR_TX_DESC_INDEX(descidx, 1U); + /* Get current descriptor address */ + dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; + + descnbr += 1U; + + /* Current Tx Descriptor Owned by DMA: cannot be used by the application */ + if (READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCWBF_OWN) == ETH_DMATXNDESCWBF_OWN) + { + dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[firstdescidx]; + /* Ensure rest of descriptor is written to RAM before the OWN bit */ + __DMB(); + /* Clear own bit */ + CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXCDESC_OWN); + + return HAL_ETH_ERROR_BUSY; + } + } + + /***************************************************************************/ + /***************** Normal descriptors configuration *****************/ + /***************************************************************************/ + + descnbr += 1U; + + /* Set header or buffer 1 address */ + WRITE_REG(dmatxdesc->DESC0, (uint32_t)txbuffer->buffer); + /* Set header or buffer 1 Length */ + MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B1L, txbuffer->len); + + if (txbuffer->next != NULL) + { + txbuffer = txbuffer->next; + /* Set buffer 2 address */ + WRITE_REG(dmatxdesc->DESC1, (uint32_t)txbuffer->buffer); + /* Set buffer 2 Length */ + MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, (txbuffer->len << 16)); + } + else + { + WRITE_REG(dmatxdesc->DESC1, 0x0U); + /* Set buffer 2 Length */ + MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U); + } + + if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET) + { + /* Set TCP Header length */ + MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_THL, (pTxConfig->TCPHeaderLen << 19)); + /* Set TCP payload length */ + MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TPL, pTxConfig->PayloadLen); + /* Set TCP Segmentation Enabled bit */ + SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TSE); + } + else + { + MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length); + + if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != (uint32_t)RESET) + { + MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CIC, pTxConfig->ChecksumCtrl); + } + + if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CRCPAD) != (uint32_t)RESET) + { + MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CPC, pTxConfig->CRCPadCtrl); + } + } + + if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_VLANTAG) != (uint32_t)RESET) + { + /* Set Vlan Tag control */ + MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_VTIR, pTxConfig->VlanCtrl); + } + + /* Mark it as First Descriptor */ + SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FD); + /* Mark it as NORMAL descriptor */ + CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CTXT); + /* Ensure rest of descriptor is written to RAM before the OWN bit */ + __DMB(); + /* set OWN bit of FIRST descriptor */ + SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN); + + /* If source address insertion/replacement is enabled for this packet */ + if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_SAIC) != (uint32_t)RESET) + { + MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_SAIC, pTxConfig->SrcAddrCtrl); + } + + /* only if the packet is split into more than one descriptors > 1 */ + while (txbuffer->next != NULL) + { + /* Clear the LD bit of previous descriptor */ + CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_LD); + /* Increment current tx descriptor index */ + INCR_TX_DESC_INDEX(descidx, 1U); + /* Get current descriptor address */ + dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; + + /* Clear the FD bit of new Descriptor */ + CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FD); + + /* Current Tx Descriptor Owned by DMA: cannot be used by the application */ + if ((READ_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN) == ETH_DMATXNDESCRF_OWN) + || (dmatxdesclist->PacketAddress[descidx] != NULL)) + { + descidx = firstdescidx; + dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; + + /* clear previous desc own bit */ + for (idx = 0; idx < descnbr; idx ++) + { + /* Ensure rest of descriptor is written to RAM before the OWN bit */ + __DMB(); + + CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN); + + /* Increment current tx descriptor index */ + INCR_TX_DESC_INDEX(descidx, 1U); + /* Get current descriptor address */ + dmatxdesc = (ETH_DMADescTypeDef *)dmatxdesclist->TxDesc[descidx]; + } + + return HAL_ETH_ERROR_BUSY; + } + + descnbr += 1U; + + /* Get the next Tx buffer in the list */ + txbuffer = txbuffer->next; + + /* Set header or buffer 1 address */ + WRITE_REG(dmatxdesc->DESC0, (uint32_t)txbuffer->buffer); + /* Set header or buffer 1 Length */ + MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B1L, txbuffer->len); + + if (txbuffer->next != NULL) + { + /* Get the next Tx buffer in the list */ + txbuffer = txbuffer->next; + /* Set buffer 2 address */ + WRITE_REG(dmatxdesc->DESC1, (uint32_t)txbuffer->buffer); + /* Set buffer 2 Length */ + MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, (txbuffer->len << 16)); + } + else + { + WRITE_REG(dmatxdesc->DESC1, 0x0U); + /* Set buffer 2 Length */ + MODIFY_REG(dmatxdesc->DESC2, ETH_DMATXNDESCRF_B2L, 0x0U); + } + + if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_TSO) != (uint32_t)RESET) + { + /* Set TCP payload length */ + MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TPL, pTxConfig->PayloadLen); + /* Set TCP Segmentation Enabled bit */ + SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_TSE); + } + else + { + /* Set the packet length */ + MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_FL, pTxConfig->Length); + + if (READ_BIT(pTxConfig->Attributes, ETH_TX_PACKETS_FEATURES_CSUM) != (uint32_t)RESET) + { + /* Checksum Insertion Control */ + MODIFY_REG(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CIC, pTxConfig->ChecksumCtrl); + } + } + + bd_count += 1U; + + /* Ensure rest of descriptor is written to RAM before the OWN bit */ + __DMB(); + /* Set Own bit */ + SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_OWN); + /* Mark it as NORMAL descriptor */ + CLEAR_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_CTXT); + } + + if (ItMode != ((uint32_t)RESET)) + { + /* Set Interrupt on completion bit */ + SET_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC); + } + else + { + /* Clear Interrupt on completion bit */ + CLEAR_BIT(dmatxdesc->DESC2, ETH_DMATXNDESCRF_IOC); + } + + /* Mark it as LAST descriptor */ + SET_BIT(dmatxdesc->DESC3, ETH_DMATXNDESCRF_LD); + /* Save the current packet address to expose it to the application */ + dmatxdesclist->PacketAddress[descidx] = dmatxdesclist->CurrentPacketAddress; + + dmatxdesclist->CurTxDesc = descidx; + /* disable the interrupt */ + __disable_irq(); + + dmatxdesclist->BuffersInUse += bd_count + 1U; + + /* Enable interrupts back */ + __enable_irq(); + + + /* Return function status */ + return HAL_ETH_ERROR_NONE; +} + +#if (USE_HAL_ETH_REGISTER_CALLBACKS == 1) +static void ETH_InitCallbacksToDefault(ETH_HandleTypeDef *heth) +{ + /* Init the ETH Callback settings */ + heth->TxCpltCallback = HAL_ETH_TxCpltCallback; /* Legacy weak TxCpltCallback */ + heth->RxCpltCallback = HAL_ETH_RxCpltCallback; /* Legacy weak RxCpltCallback */ + heth->ErrorCallback = HAL_ETH_ErrorCallback; /* Legacy weak ErrorCallback */ + heth->PMTCallback = HAL_ETH_PMTCallback; /* Legacy weak PMTCallback */ + heth->EEECallback = HAL_ETH_EEECallback; /* Legacy weak EEECallback */ + heth->WakeUpCallback = HAL_ETH_WakeUpCallback; /* Legacy weak WakeUpCallback */ + heth->rxLinkCallback = HAL_ETH_RxLinkCallback; /* Legacy weak RxLinkCallback */ + heth->txFreeCallback = HAL_ETH_TxFreeCallback; /* Legacy weak TxFreeCallback */ +#ifdef HAL_ETH_USE_PTP + heth->txPtpCallback = HAL_ETH_TxPtpCallback; /* Legacy weak TxPtpCallback */ +#endif /* HAL_ETH_USE_PTP */ + heth->rxAllocateCallback = HAL_ETH_RxAllocateCallback; /* Legacy weak RxAllocateCallback */ +} +#endif /* USE_HAL_ETH_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* ETH */ + +#endif /* HAL_ETH_MODULE_ENABLED */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_eth_ex.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_eth_ex.c new file mode 100644 index 0000000000..0a22cc5ae2 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_eth_ex.c @@ -0,0 +1,576 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_eth_ex.c + * @author MCD Application Team + * @brief ETH HAL Extended module driver. + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +#ifdef HAL_ETH_MODULE_ENABLED + +#if defined(ETH) + +/** @defgroup ETHEx ETHEx + * @brief ETH HAL Extended module driver + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup ETHEx_Private_Constants ETHEx Private Constants + * @{ + */ +#define ETH_MACL4CR_MASK (ETH_MACL3L4CR_L4PEN | ETH_MACL3L4CR_L4SPM | \ + ETH_MACL3L4CR_L4SPIM | ETH_MACL3L4CR_L4DPM | \ + ETH_MACL3L4CR_L4DPIM) + +#define ETH_MACL3CR_MASK (ETH_MACL3L4CR_L3PEN | ETH_MACL3L4CR_L3SAM | \ + ETH_MACL3L4CR_L3SAIM | ETH_MACL3L4CR_L3DAM | \ + ETH_MACL3L4CR_L3DAIM | ETH_MACL3L4CR_L3HSBM | \ + ETH_MACL3L4CR_L3HDBM) + +#define ETH_MACRXVLAN_MASK (ETH_MACVTR_EIVLRXS | ETH_MACVTR_EIVLS | \ + ETH_MACVTR_ERIVLT | ETH_MACVTR_EDVLP | \ + ETH_MACVTR_VTHM | ETH_MACVTR_EVLRXS | \ + ETH_MACVTR_EVLS | ETH_MACVTR_DOVLTC | \ + ETH_MACVTR_ERSVLM | ETH_MACVTR_ESVL | \ + ETH_MACVTR_VTIM | ETH_MACVTR_ETV) + +#define ETH_MACTXVLAN_MASK (ETH_MACVIR_VLTI | ETH_MACVIR_CSVL | \ + ETH_MACVIR_VLP | ETH_MACVIR_VLC) +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions ---------------------------------------------------------*/ +/** @defgroup ETHEx_Exported_Functions ETH Extended Exported Functions + * @{ + */ + +/** @defgroup ETHEx_Exported_Functions_Group1 Extended features functions + * @brief Extended features functions + * +@verbatim + =============================================================================== + ##### Extended features functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure ARP offload module + (+) Configure L3 and L4 filters + (+) Configure Extended VLAN features + (+) Configure Energy Efficient Ethernet module + +@endverbatim + * @{ + */ + +/** + * @brief Enables ARP Offload. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ + +void HAL_ETHEx_EnableARPOffload(ETH_HandleTypeDef *heth) +{ + SET_BIT(heth->Instance->MACCR, ETH_MACCR_ARP); +} + +/** + * @brief Disables ARP Offload. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +void HAL_ETHEx_DisableARPOffload(ETH_HandleTypeDef *heth) +{ + CLEAR_BIT(heth->Instance->MACCR, ETH_MACCR_ARP); +} + +/** + * @brief Set the ARP Match IP address + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param IpAddress: IP Address to be matched for incoming ARP requests + * @retval None + */ +void HAL_ETHEx_SetARPAddressMatch(ETH_HandleTypeDef *heth, uint32_t IpAddress) +{ + WRITE_REG(heth->Instance->MACARPAR, IpAddress); +} + +/** + * @brief Configures the L4 Filter, this function allow to: + * set the layer 4 protocol to be matched (TCP or UDP) + * enable/disable L4 source/destination port perfect/inverse match. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param Filter: L4 filter to configured, this parameter must be one of the following + * ETH_L4_FILTER_0 + * ETH_L4_FILTER_1 + * @param pL4FilterConfig: pointer to a ETH_L4FilterConfigTypeDef structure + * that contains L4 filter configuration. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETHEx_SetL4FilterConfig(ETH_HandleTypeDef *heth, uint32_t Filter, + ETH_L4FilterConfigTypeDef *pL4FilterConfig) +{ + __IO uint32_t *configreg = ((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)); + + if (pL4FilterConfig == NULL) + { + return HAL_ERROR; + } + + /* Write configuration to (MACL3L4C0R + filter )register */ + MODIFY_REG(*configreg, ETH_MACL4CR_MASK, (pL4FilterConfig->Protocol | + pL4FilterConfig->SrcPortFilterMatch | + pL4FilterConfig->DestPortFilterMatch)); + + configreg = ((__IO uint32_t *)(&(heth->Instance->MACL4A0R) + Filter)); + + /* Write configuration to (MACL4A0R + filter )register */ + MODIFY_REG(*configreg, (ETH_MACL4AR_L4DP | ETH_MACL4AR_L4SP), (pL4FilterConfig->SourcePort | + (pL4FilterConfig->DestinationPort << 16))); + + /* Enable L4 filter */ + SET_BIT(heth->Instance->MACPFR, ETH_MACPFR_IPFE); + + return HAL_OK; +} + +/** + * @brief Configures the L4 Filter, this function allow to: + * set the layer 4 protocol to be matched (TCP or UDP) + * enable/disable L4 source/destination port perfect/inverse match. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param Filter: L4 filter to configured, this parameter must be one of the following + * ETH_L4_FILTER_0 + * ETH_L4_FILTER_1 + * @param pL4FilterConfig: pointer to a ETH_L4FilterConfigTypeDef structure + * that contains L4 filter configuration. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETHEx_GetL4FilterConfig(ETH_HandleTypeDef *heth, uint32_t Filter, + ETH_L4FilterConfigTypeDef *pL4FilterConfig) +{ + if (pL4FilterConfig == NULL) + { + return HAL_ERROR; + } + + /* Get configuration to (MACL3L4C0R + filter )register */ + pL4FilterConfig->Protocol = READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)), + ETH_MACL3L4CR_L4PEN); + pL4FilterConfig->DestPortFilterMatch = READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)), + (ETH_MACL3L4CR_L4DPM | ETH_MACL3L4CR_L4DPIM)); + pL4FilterConfig->SrcPortFilterMatch = READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)), + (ETH_MACL3L4CR_L4SPM | ETH_MACL3L4CR_L4SPIM)); + + /* Get configuration to (MACL3L4C0R + filter )register */ + pL4FilterConfig->DestinationPort = (READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL4A0R) + Filter)), + ETH_MACL4AR_L4DP) >> 16); + pL4FilterConfig->SourcePort = READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL4A0R) + Filter)), ETH_MACL4AR_L4SP); + + return HAL_OK; +} + +/** + * @brief Configures the L3 Filter, this function allow to: + * set the layer 3 protocol to be matched (IPv4 or IPv6) + * enable/disable L3 source/destination port perfect/inverse match. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param Filter: L3 filter to configured, this parameter must be one of the following + * ETH_L3_FILTER_0 + * ETH_L3_FILTER_1 + * @param pL3FilterConfig: pointer to a ETH_L3FilterConfigTypeDef structure + * that contains L3 filter configuration. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETHEx_SetL3FilterConfig(ETH_HandleTypeDef *heth, uint32_t Filter, + ETH_L3FilterConfigTypeDef *pL3FilterConfig) +{ + __IO uint32_t *configreg = ((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)); + + if (pL3FilterConfig == NULL) + { + return HAL_ERROR; + } + + /* Write configuration to (MACL3L4C0R + filter )register */ + MODIFY_REG(*configreg, ETH_MACL3CR_MASK, (pL3FilterConfig->Protocol | + pL3FilterConfig->SrcAddrFilterMatch | + pL3FilterConfig->DestAddrFilterMatch | + (pL3FilterConfig->SrcAddrHigherBitsMatch << 6) | + (pL3FilterConfig->DestAddrHigherBitsMatch << 11))); + + /* Check if IPv6 protocol is selected */ + if (pL3FilterConfig->Protocol != ETH_L3_IPV4_MATCH) + { + /* Set the IPv6 address match */ + /* Set Bits[31:0] of 128-bit IP addr */ + *((__IO uint32_t *)(&(heth->Instance->MACL3A0R0R) + Filter)) = pL3FilterConfig->Ip6Addr[0]; + /* Set Bits[63:32] of 128-bit IP addr */ + *((__IO uint32_t *)(&(heth->Instance->MACL3A1R0R) + Filter)) = pL3FilterConfig->Ip6Addr[1]; + /* update Bits[95:64] of 128-bit IP addr */ + *((__IO uint32_t *)(&(heth->Instance->MACL3A2R0R) + Filter)) = pL3FilterConfig->Ip6Addr[2]; + /* update Bits[127:96] of 128-bit IP addr */ + *((__IO uint32_t *)(&(heth->Instance->MACL3A3R0R) + Filter)) = pL3FilterConfig->Ip6Addr[3]; + } + else /* IPv4 protocol is selected */ + { + /* Set the IPv4 source address match */ + *((__IO uint32_t *)(&(heth->Instance->MACL3A0R0R) + Filter)) = pL3FilterConfig->Ip4SrcAddr; + /* Set the IPv4 destination address match */ + *((__IO uint32_t *)(&(heth->Instance->MACL3A1R0R) + Filter)) = pL3FilterConfig->Ip4DestAddr; + } + + return HAL_OK; +} + +/** + * @brief Configures the L3 Filter, this function allow to: + * set the layer 3 protocol to be matched (IPv4 or IPv6) + * enable/disable L3 source/destination port perfect/inverse match. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param Filter: L3 filter to configured, this parameter must be one of the following + * ETH_L3_FILTER_0 + * ETH_L3_FILTER_1 + * @param pL3FilterConfig: pointer to a ETH_L3FilterConfigTypeDef structure + * that will contain the L3 filter configuration. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETHEx_GetL3FilterConfig(ETH_HandleTypeDef *heth, uint32_t Filter, + ETH_L3FilterConfigTypeDef *pL3FilterConfig) +{ + if (pL3FilterConfig == NULL) + { + return HAL_ERROR; + } + + pL3FilterConfig->Protocol = READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)), + ETH_MACL3L4CR_L3PEN); + pL3FilterConfig->SrcAddrFilterMatch = READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)), + (ETH_MACL3L4CR_L3SAM | ETH_MACL3L4CR_L3SAIM)); + pL3FilterConfig->DestAddrFilterMatch = READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)), + (ETH_MACL3L4CR_L3DAM | ETH_MACL3L4CR_L3DAIM)); + pL3FilterConfig->SrcAddrHigherBitsMatch = (READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)), + ETH_MACL3L4CR_L3HSBM) >> 6); + pL3FilterConfig->DestAddrHigherBitsMatch = (READ_BIT(*((__IO uint32_t *)(&(heth->Instance->MACL3L4C0R) + Filter)), + ETH_MACL3L4CR_L3HDBM) >> 11); + + if (pL3FilterConfig->Protocol != ETH_L3_IPV4_MATCH) + { + pL3FilterConfig->Ip6Addr[0] = *((__IO uint32_t *)(&(heth->Instance->MACL3A0R0R) + Filter)); + pL3FilterConfig->Ip6Addr[1] = *((__IO uint32_t *)(&(heth->Instance->MACL3A1R0R) + Filter)); + pL3FilterConfig->Ip6Addr[2] = *((__IO uint32_t *)(&(heth->Instance->MACL3A2R0R) + Filter)); + pL3FilterConfig->Ip6Addr[3] = *((__IO uint32_t *)(&(heth->Instance->MACL3A3R0R) + Filter)); + } + else + { + pL3FilterConfig->Ip4SrcAddr = *((__IO uint32_t *)(&(heth->Instance->MACL3A0R0R) + Filter)); + pL3FilterConfig->Ip4DestAddr = *((__IO uint32_t *)(&(heth->Instance->MACL3A1R0R) + Filter)); + } + + return HAL_OK; +} + +/** + * @brief Enables L3 and L4 filtering process. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None. + */ +void HAL_ETHEx_EnableL3L4Filtering(ETH_HandleTypeDef *heth) +{ + /* Enable L3/L4 filter */ + SET_BIT(heth->Instance->MACPFR, ETH_MACPFR_IPFE); +} + +/** + * @brief Disables L3 and L4 filtering process. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None. + */ +void HAL_ETHEx_DisableL3L4Filtering(ETH_HandleTypeDef *heth) +{ + /* Disable L3/L4 filter */ + CLEAR_BIT(heth->Instance->MACPFR, ETH_MACPFR_IPFE); +} + +/** + * @brief Get the VLAN Configuration for Receive Packets. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pVlanConfig: pointer to a ETH_RxVLANConfigTypeDef structure + * that will contain the VLAN filter configuration. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETHEx_GetRxVLANConfig(ETH_HandleTypeDef *heth, ETH_RxVLANConfigTypeDef *pVlanConfig) +{ + if (pVlanConfig == NULL) + { + return HAL_ERROR; + } + + pVlanConfig->InnerVLANTagInStatus = ((READ_BIT(heth->Instance->MACVTR, + ETH_MACVTR_EIVLRXS) >> 31) == 0U) ? DISABLE : ENABLE; + pVlanConfig->StripInnerVLANTag = READ_BIT(heth->Instance->MACVTR, ETH_MACVTR_EIVLS); + pVlanConfig->InnerVLANTag = ((READ_BIT(heth->Instance->MACVTR, ETH_MACVTR_ERIVLT) >> 27) == 0U) ? DISABLE : ENABLE; + pVlanConfig->DoubleVLANProcessing = ((READ_BIT(heth->Instance->MACVTR, + ETH_MACVTR_EDVLP) >> 26) == 0U) ? DISABLE : ENABLE; + pVlanConfig->VLANTagHashTableMatch = ((READ_BIT(heth->Instance->MACVTR, + ETH_MACVTR_VTHM) >> 25) == 0U) ? DISABLE : ENABLE; + pVlanConfig->VLANTagInStatus = ((READ_BIT(heth->Instance->MACVTR, ETH_MACVTR_EVLRXS) >> 24) == 0U) ? DISABLE : ENABLE; + pVlanConfig->StripVLANTag = READ_BIT(heth->Instance->MACVTR, ETH_MACVTR_EVLS); + pVlanConfig->VLANTypeCheck = READ_BIT(heth->Instance->MACVTR, + (ETH_MACVTR_DOVLTC | ETH_MACVTR_ERSVLM | ETH_MACVTR_ESVL)); + pVlanConfig->VLANTagInverceMatch = ((READ_BIT(heth->Instance->MACVTR, ETH_MACVTR_VTIM) >> 17) == 0U) + ? DISABLE : ENABLE; + + return HAL_OK; +} + +/** + * @brief Set the VLAN Configuration for Receive Packets. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param pVlanConfig: pointer to a ETH_RxVLANConfigTypeDef structure + * that contains VLAN filter configuration. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETHEx_SetRxVLANConfig(ETH_HandleTypeDef *heth, ETH_RxVLANConfigTypeDef *pVlanConfig) +{ + if (pVlanConfig == NULL) + { + return HAL_ERROR; + } + + /* Write config to MACVTR */ + MODIFY_REG(heth->Instance->MACVTR, ETH_MACRXVLAN_MASK, (((uint32_t)pVlanConfig->InnerVLANTagInStatus << 31) | + pVlanConfig->StripInnerVLANTag | + ((uint32_t)pVlanConfig->InnerVLANTag << 27) | + ((uint32_t)pVlanConfig->DoubleVLANProcessing << 26) | + ((uint32_t)pVlanConfig->VLANTagHashTableMatch << 25) | + ((uint32_t)pVlanConfig->VLANTagInStatus << 24) | + pVlanConfig->StripVLANTag | + pVlanConfig->VLANTypeCheck | + ((uint32_t)pVlanConfig->VLANTagInverceMatch << 17))); + + return HAL_OK; +} + +/** + * @brief Set the VLAN Hash Table + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param VLANHashTable: VLAN hash table 16 bit value + * @retval None + */ +void HAL_ETHEx_SetVLANHashTable(ETH_HandleTypeDef *heth, uint32_t VLANHashTable) +{ + MODIFY_REG(heth->Instance->MACVHTR, ETH_MACVHTR_VLHT, VLANHashTable); +} + +/** + * @brief Get the VLAN Configuration for Transmit Packets. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param VLANTag: Selects the vlan tag, this parameter must be one of the following + * ETH_OUTER_TX_VLANTAG + * ETH_INNER_TX_VLANTAG + * @param pVlanConfig: pointer to a ETH_TxVLANConfigTypeDef structure + * that will contain the Tx VLAN filter configuration. + * @retval HAL Status. + */ +HAL_StatusTypeDef HAL_ETHEx_GetTxVLANConfig(ETH_HandleTypeDef *heth, uint32_t VLANTag, + ETH_TxVLANConfigTypeDef *pVlanConfig) +{ + if (pVlanConfig == NULL) + { + return HAL_ERROR; + } + + if (VLANTag == ETH_INNER_TX_VLANTAG) + { + pVlanConfig->SourceTxDesc = ((READ_BIT(heth->Instance->MACIVIR, ETH_MACVIR_VLTI) >> 20) == 0U) ? DISABLE : ENABLE; + pVlanConfig->SVLANType = ((READ_BIT(heth->Instance->MACIVIR, ETH_MACVIR_CSVL) >> 19) == 0U) ? DISABLE : ENABLE; + pVlanConfig->VLANTagControl = READ_BIT(heth->Instance->MACIVIR, (ETH_MACVIR_VLP | ETH_MACVIR_VLC)); + } + else + { + pVlanConfig->SourceTxDesc = ((READ_BIT(heth->Instance->MACVIR, ETH_MACVIR_VLTI) >> 20) == 0U) ? DISABLE : ENABLE; + pVlanConfig->SVLANType = ((READ_BIT(heth->Instance->MACVIR, ETH_MACVIR_CSVL) >> 19) == 0U) ? DISABLE : ENABLE; + pVlanConfig->VLANTagControl = READ_BIT(heth->Instance->MACVIR, (ETH_MACVIR_VLP | ETH_MACVIR_VLC)); + } + + return HAL_OK;; +} + +/** + * @brief Set the VLAN Configuration for Transmit Packets. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param VLANTag: Selects the vlan tag, this parameter must be one of the following + * ETH_OUTER_TX_VLANTAG + * ETH_INNER_TX_VLANTAG + * @param pVlanConfig: pointer to a ETH_TxVLANConfigTypeDef structure + * that contains Tx VLAN filter configuration. + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_ETHEx_SetTxVLANConfig(ETH_HandleTypeDef *heth, uint32_t VLANTag, + ETH_TxVLANConfigTypeDef *pVlanConfig) +{ + if (VLANTag == ETH_INNER_TX_VLANTAG) + { + MODIFY_REG(heth->Instance->MACIVIR, ETH_MACTXVLAN_MASK, (((uint32_t)pVlanConfig->SourceTxDesc << 20) | + ((uint32_t)pVlanConfig->SVLANType << 19) | + pVlanConfig->VLANTagControl)); + /* Enable Double VLAN processing */ + SET_BIT(heth->Instance->MACVTR, ETH_MACVTR_EDVLP); + } + else + { + MODIFY_REG(heth->Instance->MACVIR, ETH_MACTXVLAN_MASK, (((uint32_t)pVlanConfig->SourceTxDesc << 20) | + ((uint32_t)pVlanConfig->SVLANType << 19) | + pVlanConfig->VLANTagControl)); + } + + return HAL_OK; +} + +/** + * @brief Set the VLAN Tag Identifier for Transmit Packets. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param VLANTag: Selects the vlan tag, this parameter must be one of the following + * ETH_OUTER_TX_VLANTAG + * ETH_INNER_TX_VLANTAG + * @param VLANIdentifier: VLAN Identifier 16 bit value + * @retval None + */ +void HAL_ETHEx_SetTxVLANIdentifier(ETH_HandleTypeDef *heth, uint32_t VLANTag, uint32_t VLANIdentifier) +{ + if (VLANTag == ETH_INNER_TX_VLANTAG) + { + MODIFY_REG(heth->Instance->MACIVIR, ETH_MACVIR_VLT, VLANIdentifier); + } + else + { + MODIFY_REG(heth->Instance->MACVIR, ETH_MACVIR_VLT, VLANIdentifier); + } +} + +/** + * @brief Enables the VLAN Tag Filtering process. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None. + */ +void HAL_ETHEx_EnableVLANProcessing(ETH_HandleTypeDef *heth) +{ + /* Enable VLAN processing */ + SET_BIT(heth->Instance->MACPFR, ETH_MACPFR_VTFE); +} + +/** + * @brief Disables the VLAN Tag Filtering process. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None. + */ +void HAL_ETHEx_DisableVLANProcessing(ETH_HandleTypeDef *heth) +{ + /* Disable VLAN processing */ + CLEAR_BIT(heth->Instance->MACPFR, ETH_MACPFR_VTFE); +} + +/** + * @brief Enters the Low Power Idle (LPI) mode + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param TxAutomate: Enable/Disable automate enter/exit LPI mode. + * @param TxClockStop: Enable/Disable Tx clock stop in LPI mode. + * @retval None + */ +void HAL_ETHEx_EnterLPIMode(ETH_HandleTypeDef *heth, FunctionalState TxAutomate, FunctionalState TxClockStop) +{ + /* Enable LPI Interrupts */ + __HAL_ETH_MAC_ENABLE_IT(heth, ETH_MACIER_LPIIE); + + /* Write to LPI Control register: Enter low power mode */ + MODIFY_REG(heth->Instance->MACLCSR, (ETH_MACLCSR_LPIEN | ETH_MACLCSR_LPITXA | ETH_MACLCSR_LPITCSE), + (((uint32_t)TxAutomate << 19) | + ((uint32_t)TxClockStop << 21) | + ETH_MACLCSR_LPIEN)); +} + +/** + * @brief Exits the Low Power Idle (LPI) mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +void HAL_ETHEx_ExitLPIMode(ETH_HandleTypeDef *heth) +{ + /* Clear the LPI Config and exit low power mode */ + CLEAR_BIT(heth->Instance->MACLCSR, (ETH_MACLCSR_LPIEN | ETH_MACLCSR_LPITXA | ETH_MACLCSR_LPITCSE)); + + /* Enable LPI Interrupts */ + __HAL_ETH_MAC_DISABLE_IT(heth, ETH_MACIER_LPIIE); +} + + +/** + * @brief Returns the ETH MAC LPI event + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval ETH MAC WakeUp event + */ +uint32_t HAL_ETHEx_GetMACLPIEvent(const ETH_HandleTypeDef *heth) +{ + return heth->MACLPIEvent; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* ETH */ + +#endif /* HAL_ETH_MODULE_ENABLED */ +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_exti.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_exti.c new file mode 100644 index 0000000000..dd7ee0af34 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_exti.c @@ -0,0 +1,874 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_exti.c + * @author MCD Application Team + * @brief EXTI HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the General Purpose Input/Output (EXTI) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### EXTI Peripheral features ##### + ============================================================================== + [..] + (+) Each Exti line can be configured within this driver. + + (+) Exti line can be configured in 3 different modes + (++) Interrupt + (++) Event + (++) Both of them + + (+) Configurable Exti lines can be configured with 3 different triggers + (++) Rising + (++) Falling + (++) Both of them + + (+) When set in interrupt mode, configurable Exti lines have two diffenrents + interrupt pending registers which allow to distinguish which transition + occurs: + (++) Rising edge pending interrupt + (++) Falling + + (+) Exti lines 0 to 15 are linked to gpio pin number 0 to 15. Gpio port can + be selected through multiplexer. + + ##### How to use this driver ##### + ============================================================================== + [..] + + (#) Configure the EXTI line using HAL_EXTI_SetConfigLine(). + (++) Choose the interrupt line number by setting "Line" member from + EXTI_ConfigTypeDef structure. + (++) Configure the interrupt and/or event mode using "Mode" member from + EXTI_ConfigTypeDef structure. + (++) For configurable lines, configure rising and/or falling trigger + "Trigger" member from EXTI_ConfigTypeDef structure. + (++) For Exti lines linked to gpio, choose gpio port using "GPIOSel" + member from GPIO_InitTypeDef structure. + + (#) Get current Exti configuration of a dedicated line using + HAL_EXTI_GetConfigLine(). + (++) Provide exiting handle as parameter. + (++) Provide pointer on EXTI_ConfigTypeDef structure as second parameter. + + (#) Clear Exti configuration of a dedicated line using HAL_EXTI_GetConfigLine(). + (++) Provide exiting handle as parameter. + + (#) Register callback to treat Exti interrupts using HAL_EXTI_RegisterCallback(). + (++) Provide exiting handle as first parameter. + (++) Provide which callback will be registered using one value from + EXTI_CallbackIDTypeDef. + (++) Provide callback function pointer. + + (#) Get interrupt pending bit using HAL_EXTI_GetPending(). + + (#) Clear interrupt pending bit using HAL_EXTI_GetPending(). + + (#) Generate software interrupt using HAL_EXTI_GenerateSWI(). + + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup EXTI + * @{ + */ + +#ifdef HAL_EXTI_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private defines ------------------------------------------------------------*/ +/** @defgroup EXTI_Private_Constants EXTI Private Constants + * @{ + */ +#define EXTI_MODE_OFFSET 0x04U /* 0x10: byte offset between: IMR1/EMR1 and IMR2/EMR2 registers */ +#define EXTI_CONFIG_OFFSET 0x08U /* 0x20: byte offset between Rising1/Falling1 and Rising2/Falling2 + configuration registers */ +#define EXTI_PRIVCFGR_OFFSET 0x08U /* 0x20: byte offset between PRIVCFGR1 and PRIVCFGR2 registers */ +#define EXTI_SECCFGR_OFFSET 0x08U /* 0x20: byte offset between SECCFGR1 and SECCFGR2 registers */ +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup EXTI_Exported_Functions + * @{ + */ + +/** @addtogroup EXTI_Exported_Functions_Group1 + * @brief Configuration functions + * +@verbatim + =============================================================================== + ##### Configuration functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Set configuration of a dedicated Exti line. + * @param hexti Exti handle. + * @param pExtiConfig Pointer on EXTI configuration to be set. + * @retval HAL Status. + */ +HAL_StatusTypeDef HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig) +{ + __IO uint32_t *regaddr; + uint32_t regval; + uint32_t linepos; + uint32_t maskline; + uint32_t offset; + + /* Check null pointer */ + if ((hexti == NULL) || (pExtiConfig == NULL)) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_EXTI_LINE(pExtiConfig->Line)); + assert_param(IS_EXTI_MODE(pExtiConfig->Mode)); + + /* Assign line number to handle */ + hexti->Line = pExtiConfig->Line; + + /* compute line register offset and line mask */ + offset = ((pExtiConfig->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT); + linepos = (pExtiConfig->Line & EXTI_PIN_MASK); + maskline = (1UL << linepos); + + /* Configure triggers for configurable lines */ + if ((pExtiConfig->Line & EXTI_CONFIG) != 0U) + { + assert_param(IS_EXTI_TRIGGER(pExtiConfig->Trigger)); + + /* Configure rising trigger */ + regaddr = (__IO uint32_t *)(&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset)); + regval = *regaddr; + + /* Mask or set line */ + if ((pExtiConfig->Trigger & EXTI_TRIGGER_RISING) != 0U) + { + regval |= maskline; + } + else + { + regval &= ~maskline; + } + + /* Store rising trigger mode */ + *regaddr = regval; + + /* Configure falling trigger */ + regaddr = (__IO uint32_t *)(&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset)); + regval = *regaddr; + + /* Mask or set line */ + if ((pExtiConfig->Trigger & EXTI_TRIGGER_FALLING) != 0U) + { + regval |= maskline; + } + else + { + regval &= ~maskline; + } + + /* Store falling trigger mode */ + *regaddr = regval; + + /* Configure gpio port selection in case of gpio exti line */ + if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO) + { + assert_param(IS_EXTI_GPIO_PORT(pExtiConfig->GPIOSel)); + assert_param(IS_EXTI_GPIO_PIN(linepos)); + + regval = EXTI->EXTICR[(linepos >> 2U) & 0x03UL]; + regval &= ~(EXTI_EXTICR1_EXTI0 << (EXTI_EXTICR1_EXTI1_Pos * (linepos & 0x03U))); + regval |= (pExtiConfig->GPIOSel << (EXTI_EXTICR1_EXTI1_Pos * (linepos & 0x03U))); + EXTI->EXTICR[(linepos >> 2U) & 0x03UL] = regval; + } + } + + /* Configure interrupt mode : read current mode */ + regaddr = (__IO uint32_t *)(&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset)); + regval = *regaddr; + + /* Mask or set line */ + if ((pExtiConfig->Mode & EXTI_MODE_INTERRUPT) != 0U) + { + regval |= maskline; + } + else + { + regval &= ~maskline; + } + + /* Store interrupt mode */ + *regaddr = regval; + + /* Configure event mode : read current mode */ + regaddr = (__IO uint32_t *)(&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset)); + regval = *regaddr; + + /* Mask or set line */ + if ((pExtiConfig->Mode & EXTI_MODE_EVENT) != 0U) + { + regval |= maskline; + } + else + { + regval &= ~maskline; + } + + /* Store event mode */ + *regaddr = regval; + + return HAL_OK; +} + + +/** + * @brief Get configuration of a dedicated Exti line. + * @param hexti Exti handle. + * @param pExtiConfig Pointer on structure to store Exti configuration. + * @retval HAL Status. + */ +HAL_StatusTypeDef HAL_EXTI_GetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig) +{ + const __IO uint32_t *regaddr; + uint32_t regval; + uint32_t linepos; + uint32_t maskline; + uint32_t offset; + + /* Check null pointer */ + if ((hexti == NULL) || (pExtiConfig == NULL)) + { + return HAL_ERROR; + } + + /* Check the parameter */ + assert_param(IS_EXTI_LINE(hexti->Line)); + + /* Store handle line number to configiguration structure */ + pExtiConfig->Line = hexti->Line; + + /* compute line register offset and line mask */ + offset = ((pExtiConfig->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT); + linepos = (pExtiConfig->Line & EXTI_PIN_MASK); + maskline = (1UL << linepos); + + /* 1] Get core mode : interrupt */ + regaddr = (__IO uint32_t *)(&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset)); + regval = *regaddr; + + /* Check if selected line is enable */ + if ((regval & maskline) != 0U) + { + pExtiConfig->Mode = EXTI_MODE_INTERRUPT; + } + else + { + pExtiConfig->Mode = EXTI_MODE_NONE; + } + + /* Get event mode */ + regaddr = (__IO uint32_t *)(&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset)); + regval = *regaddr; + + /* Check if selected line is enable */ + if ((regval & maskline) != 0U) + { + pExtiConfig->Mode |= EXTI_MODE_EVENT; + } + + /* 2] Get trigger for configurable lines : rising */ + if ((pExtiConfig->Line & EXTI_CONFIG) != 0U) + { + regaddr = (__IO uint32_t *)(&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset)); + regval = *regaddr; + + /* Get default Trigger and GPIOSel configuration */ + pExtiConfig->Trigger = EXTI_TRIGGER_NONE; + pExtiConfig->GPIOSel = 0x00u; + + /* Check if configuration of selected line is enable */ + if ((regval & maskline) != 0U) + { + pExtiConfig->Trigger = EXTI_TRIGGER_RISING; + } + + /* Get falling configuration */ + regaddr = (__IO uint32_t *)(&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset)); + regval = *regaddr; + + /* Check if configuration of selected line is enable */ + if ((regval & maskline) != 0U) + { + pExtiConfig->Trigger |= EXTI_TRIGGER_FALLING; + } + + /* Get Gpio port selection for gpio lines */ + if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO) + { + assert_param(IS_EXTI_GPIO_PIN(linepos)); + + regval = EXTI->EXTICR[(linepos >> 2U) & 0x03UL]; + pExtiConfig->GPIOSel = (regval >> (EXTI_EXTICR1_EXTI1_Pos * (linepos & 0x03u))) & EXTI_EXTICR1_EXTI0; + } + } + + return HAL_OK; +} + + +/** + * @brief Clear whole configuration of a dedicated Exti line. + * @param hexti Exti handle. + * @retval HAL Status. + */ +HAL_StatusTypeDef HAL_EXTI_ClearConfigLine(const EXTI_HandleTypeDef *hexti) +{ + __IO uint32_t *regaddr; + uint32_t regval; + uint32_t linepos; + uint32_t maskline; + uint32_t offset; + + /* Check null pointer */ + if (hexti == NULL) + { + return HAL_ERROR; + } + + /* Check the parameter */ + assert_param(IS_EXTI_LINE(hexti->Line)); + + /* compute line register offset and line mask */ + offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT); + linepos = (hexti->Line & EXTI_PIN_MASK); + maskline = (1UL << linepos); + + /* 1] Clear interrupt mode */ + regaddr = (__IO uint32_t *)(&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset)); + regval = (*regaddr & ~maskline); + *regaddr = regval; + + /* 2] Clear event mode */ + regaddr = (__IO uint32_t *)(&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset)); + regval = (*regaddr & ~maskline); + *regaddr = regval; + + /* 3] Clear triggers in case of configurable lines */ + if ((hexti->Line & EXTI_CONFIG) != 0U) + { + regaddr = (__IO uint32_t *)(&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset)); + regval = (*regaddr & ~maskline); + *regaddr = regval; + + regaddr = (__IO uint32_t *)(&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset)); + regval = (*regaddr & ~maskline); + *regaddr = regval; + + /* Get Gpio port selection for gpio lines */ + if ((hexti->Line & EXTI_GPIO) == EXTI_GPIO) + { + assert_param(IS_EXTI_GPIO_PIN(linepos)); + + regval = EXTI->EXTICR[(linepos >> 2U) & 0x03UL]; + regval &= ~(EXTI_EXTICR1_EXTI0 << (EXTI_EXTICR1_EXTI1_Pos * (linepos & 0x03U))); + EXTI->EXTICR[(linepos >> 2U) & 0x03UL] = regval; + } + } + + return HAL_OK; +} + + +/** + * @brief Register callback for a dedicaated Exti line. + * @param hexti Exti handle. + * @param CallbackID User callback identifier. + * This parameter can be one of @arg @ref EXTI_CallbackIDTypeDef values. + * @param pPendingCbfn function pointer to be stored as callback. + * @retval HAL Status. + */ +HAL_StatusTypeDef HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef *hexti, EXTI_CallbackIDTypeDef CallbackID, + void (*pPendingCbfn)(void)) +{ + HAL_StatusTypeDef status = HAL_OK; + + switch (CallbackID) + { + case HAL_EXTI_COMMON_CB_ID: + hexti->RisingCallback = pPendingCbfn; + hexti->FallingCallback = pPendingCbfn; + break; + + case HAL_EXTI_RISING_CB_ID: + hexti->RisingCallback = pPendingCbfn; + break; + + case HAL_EXTI_FALLING_CB_ID: + hexti->FallingCallback = pPendingCbfn; + break; + + default: + status = HAL_ERROR; + break; + } + + return status; +} + + +/** + * @brief Store line number as handle private field. + * @param hexti Exti handle. + * @param ExtiLine Exti line number. + * This parameter can be from 0 to @ref EXTI_LINE_NB. + * @retval HAL Status. + */ +HAL_StatusTypeDef HAL_EXTI_GetHandle(EXTI_HandleTypeDef *hexti, uint32_t ExtiLine) +{ + /* Check the parameters */ + assert_param(IS_EXTI_LINE(ExtiLine)); + + /* Check null pointer */ + if (hexti == NULL) + { + return HAL_ERROR; + } + else + { + /* Store line number as handle private field */ + hexti->Line = ExtiLine; + + return HAL_OK; + } +} + + +/** + * @} + */ + +/** @addtogroup EXTI_Exported_Functions_Group2 + * @brief EXTI IO functions. + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Handle EXTI interrupt request. + * @param hexti Exti handle. + * @retval none. + */ +void HAL_EXTI_IRQHandler(const EXTI_HandleTypeDef *hexti) +{ + __IO uint32_t *regaddr; + uint32_t regval; + uint32_t maskline; + uint32_t offset; + + /* Compute line register offset and line mask */ + offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT); + maskline = (1UL << (hexti->Line & EXTI_PIN_MASK)); + + /* Get rising edge pending bit */ + regaddr = (__IO uint32_t *)(&EXTI->RPR1 + (EXTI_CONFIG_OFFSET * offset)); + regval = (*regaddr & maskline); + + if (regval != 0U) + { + /* Clear pending bit */ + *regaddr = maskline; + + /* Call rising callback */ + if (hexti->RisingCallback != NULL) + { + hexti->RisingCallback(); + } + } + + /* Get falling edge pending bit */ + regaddr = (__IO uint32_t *)(&EXTI->FPR1 + (EXTI_CONFIG_OFFSET * offset)); + regval = (*regaddr & maskline); + + if (regval != 0U) + { + /* Clear pending bit */ + *regaddr = maskline; + + /* Call rising callback */ + if (hexti->FallingCallback != NULL) + { + hexti->FallingCallback(); + } + } +} + + +/** + * @brief Get interrupt pending bit of a dedicated line. + * @param hexti Exti handle. + * @param Edge Specify which pending edge as to be checked. + * This parameter can be one of the following values: + * @arg @ref EXTI_TRIGGER_RISING + * @arg @ref EXTI_TRIGGER_FALLING + * @retval 1 if interrupt is pending else 0. + */ +uint32_t HAL_EXTI_GetPending(const EXTI_HandleTypeDef *hexti, uint32_t Edge) +{ + const __IO uint32_t *regaddr; + uint32_t regval; + uint32_t linepos; + uint32_t maskline; + uint32_t offset; + + /* Check the parameters */ + assert_param(IS_EXTI_LINE(hexti->Line)); + assert_param(IS_EXTI_CONFIG_LINE(hexti->Line)); + assert_param(IS_EXTI_PENDING_EDGE(Edge)); + + /* compute line register offset and line mask */ + offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT); + linepos = (hexti->Line & EXTI_PIN_MASK); + maskline = (1UL << linepos); + + if (Edge != EXTI_TRIGGER_RISING) + { + /* Get falling edge pending bit */ + regaddr = (__IO uint32_t *)(&EXTI->FPR1 + (EXTI_CONFIG_OFFSET * offset)); + } + else + { + /* Get rising edge pending bit */ + regaddr = (__IO uint32_t *)(&EXTI->RPR1 + (EXTI_CONFIG_OFFSET * offset)); + } + + /* return 1 if bit is set else 0 */ + regval = ((*regaddr & maskline) >> linepos); + return regval; +} + + +/** + * @brief Clear interrupt pending bit of a dedicated line. + * @param hexti Exti handle. + * @param Edge Specify which pending edge as to be clear. + * This parameter can be one of the following values: + * @arg @ref EXTI_TRIGGER_RISING + * @arg @ref EXTI_TRIGGER_FALLING + * @retval None. + */ +void HAL_EXTI_ClearPending(const EXTI_HandleTypeDef *hexti, uint32_t Edge) +{ + __IO uint32_t *regaddr; + uint32_t maskline; + uint32_t offset; + + /* Check the parameters */ + assert_param(IS_EXTI_LINE(hexti->Line)); + assert_param(IS_EXTI_CONFIG_LINE(hexti->Line)); + assert_param(IS_EXTI_PENDING_EDGE(Edge)); + + /* compute line register offset and line mask */ + offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT); + maskline = (1UL << (hexti->Line & EXTI_PIN_MASK)); + + if (Edge != EXTI_TRIGGER_RISING) + { + /* Get falling edge pending register address */ + regaddr = (__IO uint32_t *)(&EXTI->FPR1 + (EXTI_CONFIG_OFFSET * offset)); + } + else + { + /* Get falling edge pending register address */ + regaddr = (__IO uint32_t *)(&EXTI->RPR1 + (EXTI_CONFIG_OFFSET * offset)); + } + + /* Clear Pending bit */ + *regaddr = maskline; +} + + +/** + * @brief Generate a software interrupt for a dedicated line. + * @param hexti Exti handle. + * @retval None. + */ +void HAL_EXTI_GenerateSWI(const EXTI_HandleTypeDef *hexti) +{ + __IO uint32_t *regaddr; + uint32_t maskline; + uint32_t offset; + + /* Check the parameters */ + assert_param(IS_EXTI_LINE(hexti->Line)); + assert_param(IS_EXTI_CONFIG_LINE(hexti->Line)); + + /* compute line register offset and line mask */ + offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT); + maskline = (1UL << (hexti->Line & EXTI_PIN_MASK)); + + regaddr = (__IO uint32_t *)(&EXTI->SWIER1 + (EXTI_CONFIG_OFFSET * offset)); + *regaddr = maskline; +} + + +/** + * @} + */ + +/** @defgroup EXTI_Exported_Functions_Group3 EXTI line attributes management functions + * @brief EXTI attributes management functions. + * +@verbatim + =============================================================================== + ##### EXTI attributes functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Configure the EXTI line attribute(s). + * @note Available attributes are to secure EXTI line and set EXT line as privileged. + * Default state is not secure and unprivileged access allowed. + * @note Secure and non-secure attributes can only be set from the secure + * state when the system implements the security (TZEN=1). + * @note Security and privilege attributes can be set independently. + * @param ExtiLine Exti line number. + * This parameter can be from 0 to @ref EXTI_LINE_NB. + * @param LineAttributes can be one or a combination of the following values: + * @arg @ref EXTI_LINE_PRIV Privileged-only access + * @arg @ref EXTI_LINE_NPRIV Privileged/Non-privileged access + * @arg @ref EXTI_LINE_SEC Secure-only access + * @arg @ref EXTI_LINE_NSEC Secure/Non-secure access + * @retval None + */ +void HAL_EXTI_ConfigLineAttributes(uint32_t ExtiLine, uint32_t LineAttributes) +{ + __IO uint32_t *regaddr; + uint32_t regval; + uint32_t linepos; + uint32_t maskline; + uint32_t offset; + + /* Check the parameters */ + assert_param(IS_EXTI_LINE(ExtiLine)); + assert_param(IS_EXTI_LINE_ATTRIBUTES(LineAttributes)); + + /* compute line register offset and line mask */ + offset = ((ExtiLine & EXTI_REG_MASK) >> EXTI_REG_SHIFT); + linepos = (ExtiLine & EXTI_PIN_MASK); + maskline = (1UL << linepos); + + /* Configure privilege or non-privilege attributes */ + regaddr = (__IO uint32_t *)(&EXTI->PRIVCFGR1 + (EXTI_PRIVCFGR_OFFSET * offset)); + regval = *regaddr; + + /* Mask or set line */ + if ((LineAttributes & EXTI_LINE_PRIV) == EXTI_LINE_PRIV) + { + regval |= maskline; + } + else if ((LineAttributes & EXTI_LINE_NPRIV) == EXTI_LINE_NPRIV) + { + regval &= ~maskline; + } + else + { + /* do nothing */ + } + + /* Store privilege or non-privilege attribute */ + *regaddr = regval; + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + + /* Configure secure or non-secure attributes */ + regaddr = (__IO uint32_t *)(&EXTI->SECCFGR1 + (EXTI_SECCFGR_OFFSET * offset)); + regval = *regaddr; + + /* Mask or set line */ + if ((LineAttributes & EXTI_LINE_SEC) == EXTI_LINE_SEC) + { + regval |= maskline; + } + else if ((LineAttributes & EXTI_LINE_NSEC) == EXTI_LINE_NSEC) + { + regval &= ~maskline; + } + else + { + /* do nothing */ + } + + /* Store secure or non-secure attribute */ + *regaddr = regval; + +#endif /* __ARM_FEATURE_CMSE */ +} + +/** + * @brief Get the EXTI line attribute(s). + * @note Secure and non-secure attributes are only available from secure state + * when the system implements the security (TZEN=1) + * @param ExtiLine Exti line number. + * This parameter can be from 0 to @ref EXTI_LINE_NB. + * @param pLineAttributes: pointer to return line attributes. + * @retval HAL Status. + */ +HAL_StatusTypeDef HAL_EXTI_GetConfigLineAttributes(uint32_t ExtiLine, uint32_t *pLineAttributes) +{ + const __IO uint32_t *regaddr; + uint32_t linepos; + uint32_t maskline; + uint32_t offset; + uint32_t attributes; + + /* Check null pointer */ + if (pLineAttributes == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_EXTI_LINE(ExtiLine)); + + /* Compute line register offset and line mask */ + offset = ((ExtiLine & EXTI_REG_MASK) >> EXTI_REG_SHIFT); + linepos = (ExtiLine & EXTI_PIN_MASK); + maskline = (1UL << linepos); + + /* Get privilege or non-privilege attribute */ + regaddr = (__IO uint32_t *)(&EXTI->PRIVCFGR1 + (EXTI_PRIVCFGR_OFFSET * offset)); + + if ((*regaddr & maskline) != 0U) + { + attributes = EXTI_LINE_PRIV; + } + else + { + attributes = EXTI_LINE_NPRIV; + } + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + + /* Get secure or non-secure attribute */ + regaddr = (__IO uint32_t *)(&EXTI->SECCFGR1 + (EXTI_SECCFGR_OFFSET * offset)); + + if ((*regaddr & maskline) != 0U) + { + attributes |= EXTI_LINE_SEC; + } + else + { + attributes |= EXTI_LINE_NSEC; + } + +#endif /* __ARM_FEATURE_CMSE */ + + /* return value */ + *pLineAttributes = attributes; + + return HAL_OK; +} +#if defined (EXTI_LOCKR_LOCK) +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Lock the global EXTI security and privilege configuration. + * @retval HAL Status. + */ +HAL_StatusTypeDef HAL_EXTI_LockConfigAttributes(void) +{ + EXTI->LOCKR = EXTI_ATTRIBUTES_LOCKED; + + return HAL_OK; +} + +/** + * @brief Get the global EXTI security and privilege lock configuration. + * @param pLockState : Pointer to returned security and privilege configuration + * @retval HAL Status. + */ +HAL_StatusTypeDef HAL_EXTI_GetLockConfigAttributes(uint32_t *const pLockState) +{ + uint32_t attributes; + const __IO uint32_t *regaddr; + + /* Check null pointer */ + if (pLockState == NULL) + { + return HAL_ERROR; + } + + /* Get security and privilege configuration */ + regaddr = (__IO uint32_t *)(&EXTI->LOCKR); + + if ((*regaddr & EXTI_LOCKR_LOCK) != 0U) + { + attributes = EXTI_ATTRIBUTES_LOCKED; + } + else + { + attributes = EXTI_ATTRIBUTES_UNLOCKED; + } + + /* return value */ + *pLockState = attributes; + + return HAL_OK; +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +#endif /* defined (EXTI_LOCKR_LOCK) */ +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_EXTI_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_fdcan.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_fdcan.c new file mode 100644 index 0000000000..7f07b83f0a --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_fdcan.c @@ -0,0 +1,3540 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_fdcan.c + * @author MCD Application Team + * @brief FDCAN HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Flexible DataRate Controller Area Network + * (FDCAN) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Configuration and Control functions + * + Peripheral State and Error functions + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Initialize the FDCAN peripheral using HAL_FDCAN_Init function. + + (#) If needed , configure the reception filters and optional features using + the following configuration functions: + (++) HAL_FDCAN_ConfigFilter + (++) HAL_FDCAN_ConfigGlobalFilter + (++) HAL_FDCAN_ConfigExtendedIdMask + (++) HAL_FDCAN_ConfigRxFifoOverwrite + (++) HAL_FDCAN_ConfigRamWatchdog + (++) HAL_FDCAN_ConfigTimestampCounter + (++) HAL_FDCAN_EnableTimestampCounter + (++) HAL_FDCAN_DisableTimestampCounter + (++) HAL_FDCAN_ConfigTimeoutCounter + (++) HAL_FDCAN_EnableTimeoutCounter + (++) HAL_FDCAN_DisableTimeoutCounter + (++) HAL_FDCAN_ConfigTxDelayCompensation + (++) HAL_FDCAN_EnableTxDelayCompensation + (++) HAL_FDCAN_DisableTxDelayCompensation + (++) HAL_FDCAN_EnableISOMode + (++) HAL_FDCAN_DisableISOMode + (++) HAL_FDCAN_EnableEdgeFiltering + (++) HAL_FDCAN_DisableEdgeFiltering + + (#) Start the FDCAN module using HAL_FDCAN_Start function. At this level + the node is active on the bus: it can send and receive messages. + + (#) The following Tx control functions can only be called when the FDCAN + module is started: + (++) HAL_FDCAN_AddMessageToTxFifoQ + (++) HAL_FDCAN_AbortTxRequest + + (#) After having submitted a Tx request in Tx Fifo or Queue, it is possible to + get Tx buffer location used to place the Tx request thanks to + HAL_FDCAN_GetLatestTxFifoQRequestBuffer API. + It is then possible to abort later on the corresponding Tx Request using + HAL_FDCAN_AbortTxRequest API. + + (#) When a message is received into the FDCAN message RAM, it can be + retrieved using the HAL_FDCAN_GetRxMessage function. + + (#) Calling the HAL_FDCAN_Stop function stops the FDCAN module by entering + it to initialization mode and re-enabling access to configuration + registers through the configuration functions listed here above. + + (#) All other control functions can be called any time after initialization + phase, no matter if the FDCAN module is started or stopped. + + *** Polling mode operation *** + ============================== + [..] + (#) Reception and transmission states can be monitored via the following + functions: + (++) HAL_FDCAN_IsTxBufferMessagePending + (++) HAL_FDCAN_GetRxFifoFillLevel + (++) HAL_FDCAN_GetTxFifoFreeLevel + + *** Interrupt mode operation *** + ================================ + [..] + (#) There are two interrupt lines: line 0 and 1. + By default, all interrupts are assigned to line 0. Interrupt lines + can be configured using HAL_FDCAN_ConfigInterruptLines function. + + (#) Notifications are activated using HAL_FDCAN_ActivateNotification + function. Then, the process can be controlled through one of the + available user callbacks: HAL_FDCAN_xxxCallback. + + *** Callback registration *** + ============================================= + + The compilation define USE_HAL_FDCAN_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + Use Function HAL_FDCAN_RegisterCallback() or HAL_FDCAN_RegisterXXXCallback() + to register an interrupt callback. + + Function HAL_FDCAN_RegisterCallback() allows to register following callbacks: + (+) TxFifoEmptyCallback : Tx Fifo Empty Callback. + (+) HighPriorityMessageCallback : High Priority Message Callback. + (+) TimestampWraparoundCallback : Timestamp Wraparound Callback. + (+) TimeoutOccurredCallback : Timeout Occurred Callback. + (+) ErrorCallback : Error Callback. + (+) MspInitCallback : FDCAN MspInit. + (+) MspDeInitCallback : FDCAN MspDeInit. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + + For specific callbacks TxEventFifoCallback, RxFifo0Callback, RxFifo1Callback, + TxBufferCompleteCallback, TxBufferAbortCallback and ErrorStatusCallback use dedicated + register callbacks: respectively HAL_FDCAN_RegisterTxEventFifoCallback(), + HAL_FDCAN_RegisterRxFifo0Callback(), HAL_FDCAN_RegisterRxFifo1Callback(), + HAL_FDCAN_RegisterTxBufferCompleteCallback(), HAL_FDCAN_RegisterTxBufferAbortCallback() + and HAL_FDCAN_RegisterErrorStatusCallback(). + + Use function HAL_FDCAN_UnRegisterCallback() to reset a callback to the default + weak function. + HAL_FDCAN_UnRegisterCallback takes as parameters the HAL peripheral handle, + and the Callback ID. + This function allows to reset following callbacks: + (+) TxFifoEmptyCallback : Tx Fifo Empty Callback. + (+) HighPriorityMessageCallback : High Priority Message Callback. + (+) TimestampWraparoundCallback : Timestamp Wraparound Callback. + (+) TimeoutOccurredCallback : Timeout Occurred Callback. + (+) ErrorCallback : Error Callback. + (+) MspInitCallback : FDCAN MspInit. + (+) MspDeInitCallback : FDCAN MspDeInit. + + For specific callbacks TxEventFifoCallback, RxFifo0Callback, RxFifo1Callback, + TxBufferCompleteCallback and TxBufferAbortCallback, use dedicated + unregister callbacks: respectively HAL_FDCAN_UnRegisterTxEventFifoCallback(), + HAL_FDCAN_UnRegisterRxFifo0Callback(), HAL_FDCAN_UnRegisterRxFifo1Callback(), + HAL_FDCAN_UnRegisterTxBufferCompleteCallback(), HAL_FDCAN_UnRegisterTxBufferAbortCallback() + and HAL_FDCAN_UnRegisterErrorStatusCallback(). + + By default, after the HAL_FDCAN_Init() and when the state is HAL_FDCAN_STATE_RESET, + all callbacks are set to the corresponding weak functions: + examples HAL_FDCAN_ErrorCallback(). + Exception done for MspInit and MspDeInit functions that are + reset to the legacy weak function in the HAL_FDCAN_Init()/ HAL_FDCAN_DeInit() only when + these callbacks are null (not registered beforehand). + if not, MspInit or MspDeInit are not null, the HAL_FDCAN_Init()/ HAL_FDCAN_DeInit() + keep and use the user MspInit/MspDeInit callbacks (registered beforehand) + + Callbacks can be registered/unregistered in HAL_FDCAN_STATE_READY state only. + Exception done MspInit/MspDeInit that can be registered/unregistered + in HAL_FDCAN_STATE_READY or HAL_FDCAN_STATE_RESET state, + thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. + In that case first register the MspInit/MspDeInit user callbacks + using HAL_FDCAN_RegisterCallback() before calling HAL_FDCAN_DeInit() + or HAL_FDCAN_Init() function. + + When The compilation define USE_HAL_FDCAN_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 "stm32h5xx_hal.h" + +#if defined(FDCAN1) + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup FDCAN FDCAN + * @brief FDCAN HAL module driver + * @{ + */ + +#ifdef HAL_FDCAN_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup FDCAN_Private_Constants + * @{ + */ +#define FDCAN_TIMEOUT_VALUE 10U + +#define FDCAN_TX_EVENT_FIFO_MASK (FDCAN_IR_TEFL | FDCAN_IR_TEFF | FDCAN_IR_TEFN) +#define FDCAN_RX_FIFO0_MASK (FDCAN_IR_RF0L | FDCAN_IR_RF0F | FDCAN_IR_RF0N) +#define FDCAN_RX_FIFO1_MASK (FDCAN_IR_RF1L | FDCAN_IR_RF1F | FDCAN_IR_RF1N) +#define FDCAN_ERROR_MASK (FDCAN_IR_ELO | FDCAN_IR_WDI | FDCAN_IR_PEA | FDCAN_IR_PED | FDCAN_IR_ARA) +#define FDCAN_ERROR_STATUS_MASK (FDCAN_IR_EP | FDCAN_IR_EW | FDCAN_IR_BO) + +#define FDCAN_ELEMENT_MASK_STDID ((uint32_t)0x1FFC0000U) /* Standard Identifier */ +#define FDCAN_ELEMENT_MASK_EXTID ((uint32_t)0x1FFFFFFFU) /* Extended Identifier */ +#define FDCAN_ELEMENT_MASK_RTR ((uint32_t)0x20000000U) /* Remote Transmission Request */ +#define FDCAN_ELEMENT_MASK_XTD ((uint32_t)0x40000000U) /* Extended Identifier */ +#define FDCAN_ELEMENT_MASK_ESI ((uint32_t)0x80000000U) /* Error State Indicator */ +#define FDCAN_ELEMENT_MASK_TS ((uint32_t)0x0000FFFFU) /* Timestamp */ +#define FDCAN_ELEMENT_MASK_DLC ((uint32_t)0x000F0000U) /* Data Length Code */ +#define FDCAN_ELEMENT_MASK_BRS ((uint32_t)0x00100000U) /* Bit Rate Switch */ +#define FDCAN_ELEMENT_MASK_FDF ((uint32_t)0x00200000U) /* FD Format */ +#define FDCAN_ELEMENT_MASK_EFC ((uint32_t)0x00800000U) /* Event FIFO Control */ +#define FDCAN_ELEMENT_MASK_MM ((uint32_t)0xFF000000U) /* Message Marker */ +#define FDCAN_ELEMENT_MASK_FIDX ((uint32_t)0x7F000000U) /* Filter Index */ +#define FDCAN_ELEMENT_MASK_ANMF ((uint32_t)0x80000000U) /* Accepted Non-matching Frame */ +#define FDCAN_ELEMENT_MASK_ET ((uint32_t)0x00C00000U) /* Event type */ + +#define SRAMCAN_FLS_NBR (28U) /* Max. Filter List Standard Number */ +#define SRAMCAN_FLE_NBR ( 8U) /* Max. Filter List Extended Number */ +#define SRAMCAN_RF0_NBR ( 3U) /* RX FIFO 0 Elements Number */ +#define SRAMCAN_RF1_NBR ( 3U) /* RX FIFO 1 Elements Number */ +#define SRAMCAN_TEF_NBR ( 3U) /* TX Event FIFO Elements Number */ +#define SRAMCAN_TFQ_NBR ( 3U) /* TX FIFO/Queue Elements Number */ + +#define SRAMCAN_FLS_SIZE ( 1U * 4U) /* Filter Standard Element Size in bytes */ +#define SRAMCAN_FLE_SIZE ( 2U * 4U) /* Filter Extended Element Size in bytes */ +#define SRAMCAN_RF0_SIZE (18U * 4U) /* RX FIFO 0 Elements Size in bytes */ +#define SRAMCAN_RF1_SIZE (18U * 4U) /* RX FIFO 1 Elements Size in bytes */ +#define SRAMCAN_TEF_SIZE ( 2U * 4U) /* TX Event FIFO Elements Size in bytes */ +#define SRAMCAN_TFQ_SIZE (18U * 4U) /* TX FIFO/Queue Elements Size in bytes */ + +#define SRAMCAN_FLSSA ((uint32_t)0) /* Filter List Standard Start + Address */ +#define SRAMCAN_FLESA ((uint32_t)(SRAMCAN_FLSSA + (SRAMCAN_FLS_NBR * SRAMCAN_FLS_SIZE))) /* Filter List Extended Start + Address */ +#define SRAMCAN_RF0SA ((uint32_t)(SRAMCAN_FLESA + (SRAMCAN_FLE_NBR * SRAMCAN_FLE_SIZE))) /* Rx FIFO 0 Start Address */ +#define SRAMCAN_RF1SA ((uint32_t)(SRAMCAN_RF0SA + (SRAMCAN_RF0_NBR * SRAMCAN_RF0_SIZE))) /* Rx FIFO 1 Start Address */ +#define SRAMCAN_TEFSA ((uint32_t)(SRAMCAN_RF1SA + (SRAMCAN_RF1_NBR * SRAMCAN_RF1_SIZE))) /* Tx Event FIFO Start + Address */ +#define SRAMCAN_TFQSA ((uint32_t)(SRAMCAN_TEFSA + (SRAMCAN_TEF_NBR * SRAMCAN_TEF_SIZE))) /* Tx FIFO/Queue Start + Address */ +#define SRAMCAN_SIZE ((uint32_t)(SRAMCAN_TFQSA + (SRAMCAN_TFQ_NBR * SRAMCAN_TFQ_SIZE))) /* Message RAM size */ + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/** @addtogroup FDCAN_Private_Variables + * @{ + */ +static const uint8_t DLCtoBytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64}; +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup FDCAN_Private_Functions_Prototypes + * @{ + */ +static void FDCAN_CalcultateRamBlockAddresses(FDCAN_HandleTypeDef *hfdcan); +static void FDCAN_CopyMessageToRAM(FDCAN_HandleTypeDef *hfdcan, const FDCAN_TxHeaderTypeDef *pTxHeader, + const uint8_t *pTxData, uint32_t BufferIndex); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup FDCAN_Exported_Functions FDCAN Exported Functions + * @{ + */ + +/** @defgroup FDCAN_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 FDCAN. + (+) De-initialize the FDCAN. + (+) Enter FDCAN peripheral in power down mode. + (+) Exit power down mode. + (+) Register callbacks. + (+) Unregister callbacks. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the FDCAN peripheral according to the specified + * parameters in the FDCAN_InitTypeDef structure. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_Init(FDCAN_HandleTypeDef *hfdcan) +{ + uint32_t tickstart; + + /* Check FDCAN handle */ + if (hfdcan == NULL) + { + return HAL_ERROR; + } + + /* Check function parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(hfdcan->Instance)); + if (hfdcan->Instance == FDCAN1) + { + assert_param(IS_FDCAN_CKDIV(hfdcan->Init.ClockDivider)); + } + assert_param(IS_FDCAN_FRAME_FORMAT(hfdcan->Init.FrameFormat)); + assert_param(IS_FDCAN_MODE(hfdcan->Init.Mode)); + assert_param(IS_FUNCTIONAL_STATE(hfdcan->Init.AutoRetransmission)); + assert_param(IS_FUNCTIONAL_STATE(hfdcan->Init.TransmitPause)); + assert_param(IS_FUNCTIONAL_STATE(hfdcan->Init.ProtocolException)); + assert_param(IS_FDCAN_NOMINAL_PRESCALER(hfdcan->Init.NominalPrescaler)); + assert_param(IS_FDCAN_NOMINAL_SJW(hfdcan->Init.NominalSyncJumpWidth)); + assert_param(IS_FDCAN_NOMINAL_TSEG1(hfdcan->Init.NominalTimeSeg1)); + assert_param(IS_FDCAN_NOMINAL_TSEG2(hfdcan->Init.NominalTimeSeg2)); + if (hfdcan->Init.FrameFormat == FDCAN_FRAME_FD_BRS) + { + assert_param(IS_FDCAN_DATA_PRESCALER(hfdcan->Init.DataPrescaler)); + assert_param(IS_FDCAN_DATA_SJW(hfdcan->Init.DataSyncJumpWidth)); + assert_param(IS_FDCAN_DATA_TSEG1(hfdcan->Init.DataTimeSeg1)); + assert_param(IS_FDCAN_DATA_TSEG2(hfdcan->Init.DataTimeSeg2)); + } + assert_param(IS_FDCAN_MAX_VALUE(hfdcan->Init.StdFiltersNbr, SRAMCAN_FLS_NBR)); + assert_param(IS_FDCAN_MAX_VALUE(hfdcan->Init.ExtFiltersNbr, SRAMCAN_FLE_NBR)); + assert_param(IS_FDCAN_TX_FIFO_QUEUE_MODE(hfdcan->Init.TxFifoQueueMode)); + +#if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1 + if (hfdcan->State == HAL_FDCAN_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hfdcan->Lock = HAL_UNLOCKED; + + /* Reset callbacks to legacy functions */ + hfdcan->TxEventFifoCallback = HAL_FDCAN_TxEventFifoCallback; /* TxEventFifoCallback */ + hfdcan->RxFifo0Callback = HAL_FDCAN_RxFifo0Callback; /* RxFifo0Callback */ + hfdcan->RxFifo1Callback = HAL_FDCAN_RxFifo1Callback; /* RxFifo1Callback */ + hfdcan->TxFifoEmptyCallback = HAL_FDCAN_TxFifoEmptyCallback; /* TxFifoEmptyCallback */ + hfdcan->TxBufferCompleteCallback = HAL_FDCAN_TxBufferCompleteCallback; /* TxBufferCompleteCallback */ + hfdcan->TxBufferAbortCallback = HAL_FDCAN_TxBufferAbortCallback; /* TxBufferAbortCallback */ + hfdcan->HighPriorityMessageCallback = HAL_FDCAN_HighPriorityMessageCallback; /* HighPriorityMessageCallback */ + hfdcan->TimestampWraparoundCallback = HAL_FDCAN_TimestampWraparoundCallback; /* TimestampWraparoundCallback */ + hfdcan->TimeoutOccurredCallback = HAL_FDCAN_TimeoutOccurredCallback; /* TimeoutOccurredCallback */ + hfdcan->ErrorCallback = HAL_FDCAN_ErrorCallback; /* ErrorCallback */ + hfdcan->ErrorStatusCallback = HAL_FDCAN_ErrorStatusCallback; /* ErrorStatusCallback */ + + if (hfdcan->MspInitCallback == NULL) + { + hfdcan->MspInitCallback = HAL_FDCAN_MspInit; /* Legacy weak MspInit */ + } + + /* Init the low level hardware: CLOCK, NVIC */ + hfdcan->MspInitCallback(hfdcan); + } +#else + if (hfdcan->State == HAL_FDCAN_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hfdcan->Lock = HAL_UNLOCKED; + + /* Init the low level hardware: CLOCK, NVIC */ + HAL_FDCAN_MspInit(hfdcan); + } +#endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */ + + /* Exit from Sleep mode */ + CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CSR); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Check Sleep mode acknowledge */ + while ((hfdcan->Instance->CCCR & FDCAN_CCCR_CSA) == FDCAN_CCCR_CSA) + { + if ((HAL_GetTick() - tickstart) > FDCAN_TIMEOUT_VALUE) + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT; + + /* Change FDCAN state */ + hfdcan->State = HAL_FDCAN_STATE_ERROR; + + return HAL_ERROR; + } + } + + /* Request initialisation */ + SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_INIT); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait until the INIT bit into CCCR register is set */ + while ((hfdcan->Instance->CCCR & FDCAN_CCCR_INIT) == 0U) + { + /* Check for the Timeout */ + if ((HAL_GetTick() - tickstart) > FDCAN_TIMEOUT_VALUE) + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT; + + /* Change FDCAN state */ + hfdcan->State = HAL_FDCAN_STATE_ERROR; + + return HAL_ERROR; + } + } + + /* Enable configuration change */ + SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CCE); + + /* Check FDCAN instance */ + if (hfdcan->Instance == FDCAN1) + { + /* Configure Clock divider */ + FDCAN_CONFIG->CKDIV = hfdcan->Init.ClockDivider; + } + + /* Set the no automatic retransmission */ + if (hfdcan->Init.AutoRetransmission == ENABLE) + { + CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_DAR); + } + else + { + SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_DAR); + } + + /* Set the transmit pause feature */ + if (hfdcan->Init.TransmitPause == ENABLE) + { + SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_TXP); + } + else + { + CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_TXP); + } + + /* Set the Protocol Exception Handling */ + if (hfdcan->Init.ProtocolException == ENABLE) + { + CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_PXHD); + } + else + { + SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_PXHD); + } + + /* Set FDCAN Frame Format */ + MODIFY_REG(hfdcan->Instance->CCCR, FDCAN_FRAME_FD_BRS, hfdcan->Init.FrameFormat); + + /* Reset FDCAN Operation Mode */ + CLEAR_BIT(hfdcan->Instance->CCCR, (FDCAN_CCCR_TEST | FDCAN_CCCR_MON | FDCAN_CCCR_ASM)); + CLEAR_BIT(hfdcan->Instance->TEST, FDCAN_TEST_LBCK); + + /* Set FDCAN Operating Mode: + | Normal | Restricted | Bus | Internal | External + | | Operation | Monitoring | LoopBack | LoopBack + CCCR.TEST | 0 | 0 | 0 | 1 | 1 + CCCR.MON | 0 | 0 | 1 | 1 | 0 + TEST.LBCK | 0 | 0 | 0 | 1 | 1 + CCCR.ASM | 0 | 1 | 0 | 0 | 0 + */ + if (hfdcan->Init.Mode == FDCAN_MODE_RESTRICTED_OPERATION) + { + /* Enable Restricted Operation mode */ + SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_ASM); + } + else if (hfdcan->Init.Mode != FDCAN_MODE_NORMAL) + { + if (hfdcan->Init.Mode != FDCAN_MODE_BUS_MONITORING) + { + /* Enable write access to TEST register */ + SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_TEST); + + /* Enable LoopBack mode */ + SET_BIT(hfdcan->Instance->TEST, FDCAN_TEST_LBCK); + + if (hfdcan->Init.Mode == FDCAN_MODE_INTERNAL_LOOPBACK) + { + SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_MON); + } + } + else + { + /* Enable bus monitoring mode */ + SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_MON); + } + } + else + { + /* Nothing to do: normal mode */ + } + + /* Set the nominal bit timing register */ + hfdcan->Instance->NBTP = ((((uint32_t)hfdcan->Init.NominalSyncJumpWidth - 1U) << FDCAN_NBTP_NSJW_Pos) | \ + (((uint32_t)hfdcan->Init.NominalTimeSeg1 - 1U) << FDCAN_NBTP_NTSEG1_Pos) | \ + (((uint32_t)hfdcan->Init.NominalTimeSeg2 - 1U) << FDCAN_NBTP_NTSEG2_Pos) | \ + (((uint32_t)hfdcan->Init.NominalPrescaler - 1U) << FDCAN_NBTP_NBRP_Pos)); + + /* If FD operation with BRS is selected, set the data bit timing register */ + if (hfdcan->Init.FrameFormat == FDCAN_FRAME_FD_BRS) + { + hfdcan->Instance->DBTP = ((((uint32_t)hfdcan->Init.DataSyncJumpWidth - 1U) << FDCAN_DBTP_DSJW_Pos) | \ + (((uint32_t)hfdcan->Init.DataTimeSeg1 - 1U) << FDCAN_DBTP_DTSEG1_Pos) | \ + (((uint32_t)hfdcan->Init.DataTimeSeg2 - 1U) << FDCAN_DBTP_DTSEG2_Pos) | \ + (((uint32_t)hfdcan->Init.DataPrescaler - 1U) << FDCAN_DBTP_DBRP_Pos)); + } + + /* Select between Tx FIFO and Tx Queue operation modes */ + SET_BIT(hfdcan->Instance->TXBC, hfdcan->Init.TxFifoQueueMode); + + /* Calculate each RAM block address */ + FDCAN_CalcultateRamBlockAddresses(hfdcan); + + /* Initialize the Latest Tx request buffer index */ + hfdcan->LatestTxFifoQRequest = 0U; + + /* Initialize the error code */ + hfdcan->ErrorCode = HAL_FDCAN_ERROR_NONE; + + /* Initialize the FDCAN state */ + hfdcan->State = HAL_FDCAN_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Deinitializes the FDCAN peripheral registers to their default reset values. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_DeInit(FDCAN_HandleTypeDef *hfdcan) +{ + /* Check FDCAN handle */ + if (hfdcan == NULL) + { + return HAL_ERROR; + } + + /* Check function parameters */ + assert_param(IS_FDCAN_ALL_INSTANCE(hfdcan->Instance)); + + /* Stop the FDCAN module: return value is voluntary ignored */ + (void)HAL_FDCAN_Stop(hfdcan); + + /* Disable Interrupt lines */ + CLEAR_BIT(hfdcan->Instance->ILE, (FDCAN_INTERRUPT_LINE0 | FDCAN_INTERRUPT_LINE1)); + +#if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1 + if (hfdcan->MspDeInitCallback == NULL) + { + hfdcan->MspDeInitCallback = HAL_FDCAN_MspDeInit; /* Legacy weak MspDeInit */ + } + + /* DeInit the low level hardware: CLOCK, NVIC */ + hfdcan->MspDeInitCallback(hfdcan); +#else + /* DeInit the low level hardware: CLOCK, NVIC */ + HAL_FDCAN_MspDeInit(hfdcan); +#endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */ + + /* Reset the FDCAN ErrorCode */ + hfdcan->ErrorCode = HAL_FDCAN_ERROR_NONE; + + /* Change FDCAN state */ + hfdcan->State = HAL_FDCAN_STATE_RESET; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the FDCAN MSP. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval None + */ +__weak void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef *hfdcan) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hfdcan); + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_FDCAN_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes the FDCAN MSP. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval None + */ +__weak void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef *hfdcan) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hfdcan); + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_FDCAN_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief Enter FDCAN peripheral in sleep mode. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_EnterPowerDownMode(FDCAN_HandleTypeDef *hfdcan) +{ + uint32_t tickstart; + + /* Request clock stop */ + SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CSR); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait until FDCAN is ready for power down */ + while ((hfdcan->Instance->CCCR & FDCAN_CCCR_CSA) == 0U) + { + if ((HAL_GetTick() - tickstart) > FDCAN_TIMEOUT_VALUE) + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT; + + /* Change FDCAN state */ + hfdcan->State = HAL_FDCAN_STATE_ERROR; + + return HAL_ERROR; + } + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Exit power down mode. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_ExitPowerDownMode(FDCAN_HandleTypeDef *hfdcan) +{ + uint32_t tickstart; + + /* Reset clock stop request */ + CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CSR); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait until FDCAN exits sleep mode */ + while ((hfdcan->Instance->CCCR & FDCAN_CCCR_CSA) == FDCAN_CCCR_CSA) + { + if ((HAL_GetTick() - tickstart) > FDCAN_TIMEOUT_VALUE) + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT; + + /* Change FDCAN state */ + hfdcan->State = HAL_FDCAN_STATE_ERROR; + + return HAL_ERROR; + } + } + + /* Enter normal operation */ + CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_INIT); + + /* Return function status */ + return HAL_OK; +} + +#if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1 +/** + * @brief Register a FDCAN CallBack. + * To be used instead of the weak predefined callback + * @param hfdcan pointer to a FDCAN_HandleTypeDef structure that contains + * the configuration information for FDCAN module + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_FDCAN_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty callback ID + * @arg @ref HAL_FDCAN_HIGH_PRIO_MESSAGE_CB_ID High priority message callback ID + * @arg @ref HAL_FDCAN_TIMESTAMP_WRAPAROUND_CB_ID Timestamp wraparound callback ID + * @arg @ref HAL_FDCAN_TIMEOUT_OCCURRED_CB_ID Timeout occurred callback ID + * @arg @ref HAL_FDCAN_ERROR_CALLBACK_CB_ID Error callback ID + * @arg @ref HAL_FDCAN_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_FDCAN_MSPDEINIT_CB_ID MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_RegisterCallback(FDCAN_HandleTypeDef *hfdcan, HAL_FDCAN_CallbackIDTypeDef CallbackID, + void (* pCallback)(FDCAN_HandleTypeDef *_hFDCAN)) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + switch (CallbackID) + { + case HAL_FDCAN_TX_FIFO_EMPTY_CB_ID : + hfdcan->TxFifoEmptyCallback = pCallback; + break; + + case HAL_FDCAN_HIGH_PRIO_MESSAGE_CB_ID : + hfdcan->HighPriorityMessageCallback = pCallback; + break; + + case HAL_FDCAN_TIMESTAMP_WRAPAROUND_CB_ID : + hfdcan->TimestampWraparoundCallback = pCallback; + break; + + case HAL_FDCAN_TIMEOUT_OCCURRED_CB_ID : + hfdcan->TimeoutOccurredCallback = pCallback; + break; + + case HAL_FDCAN_ERROR_CALLBACK_CB_ID : + hfdcan->ErrorCallback = pCallback; + break; + + case HAL_FDCAN_MSPINIT_CB_ID : + hfdcan->MspInitCallback = pCallback; + break; + + case HAL_FDCAN_MSPDEINIT_CB_ID : + hfdcan->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (hfdcan->State == HAL_FDCAN_STATE_RESET) + { + switch (CallbackID) + { + case HAL_FDCAN_MSPINIT_CB_ID : + hfdcan->MspInitCallback = pCallback; + break; + + case HAL_FDCAN_MSPDEINIT_CB_ID : + hfdcan->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister a FDCAN CallBack. + * FDCAN callback is redirected to the weak predefined callback + * @param hfdcan pointer to a FDCAN_HandleTypeDef structure that contains + * the configuration information for FDCAN module + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_FDCAN_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty callback ID + * @arg @ref HAL_FDCAN_HIGH_PRIO_MESSAGE_CB_ID High priority message callback ID + * @arg @ref HAL_FDCAN_TIMESTAMP_WRAPAROUND_CB_ID Timestamp wraparound callback ID + * @arg @ref HAL_FDCAN_TIMEOUT_OCCURRED_CB_ID Timeout occurred callback ID + * @arg @ref HAL_FDCAN_ERROR_CALLBACK_CB_ID Error callback ID + * @arg @ref HAL_FDCAN_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_FDCAN_MSPDEINIT_CB_ID MspDeInit callback ID + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_UnRegisterCallback(FDCAN_HandleTypeDef *hfdcan, HAL_FDCAN_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + switch (CallbackID) + { + case HAL_FDCAN_TX_FIFO_EMPTY_CB_ID : + hfdcan->TxFifoEmptyCallback = HAL_FDCAN_TxFifoEmptyCallback; + break; + + case HAL_FDCAN_HIGH_PRIO_MESSAGE_CB_ID : + hfdcan->HighPriorityMessageCallback = HAL_FDCAN_HighPriorityMessageCallback; + break; + + case HAL_FDCAN_TIMESTAMP_WRAPAROUND_CB_ID : + hfdcan->TimestampWraparoundCallback = HAL_FDCAN_TimestampWraparoundCallback; + break; + + case HAL_FDCAN_TIMEOUT_OCCURRED_CB_ID : + hfdcan->TimeoutOccurredCallback = HAL_FDCAN_TimeoutOccurredCallback; + break; + + case HAL_FDCAN_ERROR_CALLBACK_CB_ID : + hfdcan->ErrorCallback = HAL_FDCAN_ErrorCallback; + break; + + case HAL_FDCAN_MSPINIT_CB_ID : + hfdcan->MspInitCallback = HAL_FDCAN_MspInit; + break; + + case HAL_FDCAN_MSPDEINIT_CB_ID : + hfdcan->MspDeInitCallback = HAL_FDCAN_MspDeInit; + break; + + default : + /* Update the error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (hfdcan->State == HAL_FDCAN_STATE_RESET) + { + switch (CallbackID) + { + case HAL_FDCAN_MSPINIT_CB_ID : + hfdcan->MspInitCallback = HAL_FDCAN_MspInit; + break; + + case HAL_FDCAN_MSPDEINIT_CB_ID : + hfdcan->MspDeInitCallback = HAL_FDCAN_MspDeInit; + break; + + default : + /* Update the error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Register Tx Event Fifo FDCAN Callback + * To be used instead of the weak HAL_FDCAN_TxEventFifoCallback() predefined callback + * @param hfdcan FDCAN handle + * @param pCallback pointer to the Tx Event Fifo Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_RegisterTxEventFifoCallback(FDCAN_HandleTypeDef *hfdcan, + pFDCAN_TxEventFifoCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + hfdcan->TxEventFifoCallback = pCallback; + } + else + { + /* Update the error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief UnRegister the Tx Event Fifo FDCAN Callback + * Tx Event Fifo FDCAN Callback is redirected to the weak HAL_FDCAN_TxEventFifoCallback() predefined callback + * @param hfdcan FDCAN handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_UnRegisterTxEventFifoCallback(FDCAN_HandleTypeDef *hfdcan) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + hfdcan->TxEventFifoCallback = HAL_FDCAN_TxEventFifoCallback; /* Legacy weak TxEventFifoCallback */ + } + else + { + /* Update the error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Register Rx Fifo 0 FDCAN Callback + * To be used instead of the weak HAL_FDCAN_RxFifo0Callback() predefined callback + * @param hfdcan FDCAN handle + * @param pCallback pointer to the Rx Fifo 0 Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_RegisterRxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, + pFDCAN_RxFifo0CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + hfdcan->RxFifo0Callback = pCallback; + } + else + { + /* Update the error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief UnRegister the Rx Fifo 0 FDCAN Callback + * Rx Fifo 0 FDCAN Callback is redirected to the weak HAL_FDCAN_RxFifo0Callback() predefined callback + * @param hfdcan FDCAN handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_UnRegisterRxFifo0Callback(FDCAN_HandleTypeDef *hfdcan) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + hfdcan->RxFifo0Callback = HAL_FDCAN_RxFifo0Callback; /* Legacy weak RxFifo0Callback */ + } + else + { + /* Update the error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Register Rx Fifo 1 FDCAN Callback + * To be used instead of the weak HAL_FDCAN_RxFifo1Callback() predefined callback + * @param hfdcan FDCAN handle + * @param pCallback pointer to the Rx Fifo 1 Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_RegisterRxFifo1Callback(FDCAN_HandleTypeDef *hfdcan, + pFDCAN_RxFifo1CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + hfdcan->RxFifo1Callback = pCallback; + } + else + { + /* Update the error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief UnRegister the Rx Fifo 1 FDCAN Callback + * Rx Fifo 1 FDCAN Callback is redirected to the weak HAL_FDCAN_RxFifo1Callback() predefined callback + * @param hfdcan FDCAN handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_UnRegisterRxFifo1Callback(FDCAN_HandleTypeDef *hfdcan) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + hfdcan->RxFifo1Callback = HAL_FDCAN_RxFifo1Callback; /* Legacy weak RxFifo1Callback */ + } + else + { + /* Update the error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Register Tx Buffer Complete FDCAN Callback + * To be used instead of the weak HAL_FDCAN_TxBufferCompleteCallback() predefined callback + * @param hfdcan FDCAN handle + * @param pCallback pointer to the Tx Buffer Complete Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_RegisterTxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan, + pFDCAN_TxBufferCompleteCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + hfdcan->TxBufferCompleteCallback = pCallback; + } + else + { + /* Update the error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief UnRegister the Tx Buffer Complete FDCAN Callback + * Tx Buffer Complete FDCAN Callback is redirected to + * the weak HAL_FDCAN_TxBufferCompleteCallback() predefined callback + * @param hfdcan FDCAN handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_UnRegisterTxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + hfdcan->TxBufferCompleteCallback = HAL_FDCAN_TxBufferCompleteCallback; /* Legacy weak TxBufferCompleteCallback */ + } + else + { + /* Update the error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Register Tx Buffer Abort FDCAN Callback + * To be used instead of the weak HAL_FDCAN_TxBufferAbortCallback() predefined callback + * @param hfdcan FDCAN handle + * @param pCallback pointer to the Tx Buffer Abort Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_RegisterTxBufferAbortCallback(FDCAN_HandleTypeDef *hfdcan, + pFDCAN_TxBufferAbortCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + hfdcan->TxBufferAbortCallback = pCallback; + } + else + { + /* Update the error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief UnRegister the Tx Buffer Abort FDCAN Callback + * Tx Buffer Abort FDCAN Callback is redirected to + * the weak HAL_FDCAN_TxBufferAbortCallback() predefined callback + * @param hfdcan FDCAN handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_UnRegisterTxBufferAbortCallback(FDCAN_HandleTypeDef *hfdcan) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + hfdcan->TxBufferAbortCallback = HAL_FDCAN_TxBufferAbortCallback; /* Legacy weak TxBufferAbortCallback */ + } + else + { + /* Update the error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Register Error Status FDCAN Callback + * To be used instead of the weak HAL_FDCAN_ErrorStatusCallback() predefined callback + * @param hfdcan FDCAN handle + * @param pCallback pointer to the Error Status Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_RegisterErrorStatusCallback(FDCAN_HandleTypeDef *hfdcan, + pFDCAN_ErrorStatusCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + hfdcan->ErrorStatusCallback = pCallback; + } + else + { + /* Update the error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief UnRegister the Error Status FDCAN Callback + * Error Status FDCAN Callback is redirected to the weak HAL_FDCAN_ErrorStatusCallback() predefined callback + * @param hfdcan FDCAN handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_UnRegisterErrorStatusCallback(FDCAN_HandleTypeDef *hfdcan) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + hfdcan->ErrorStatusCallback = HAL_FDCAN_ErrorStatusCallback; /* Legacy weak ErrorStatusCallback */ + } + else + { + /* Update the error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +#endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup FDCAN_Exported_Functions_Group2 Configuration functions + * @brief FDCAN Configuration functions. + * +@verbatim + ============================================================================== + ##### Configuration functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) HAL_FDCAN_ConfigFilter : Configure the FDCAN reception filters + (+) HAL_FDCAN_ConfigGlobalFilter : Configure the FDCAN global filter + (+) HAL_FDCAN_ConfigExtendedIdMask : Configure the extended ID mask + (+) HAL_FDCAN_ConfigRxFifoOverwrite : Configure the Rx FIFO operation mode + (+) HAL_FDCAN_ConfigRamWatchdog : Configure the RAM watchdog + (+) HAL_FDCAN_ConfigTimestampCounter : Configure the timestamp counter + (+) HAL_FDCAN_EnableTimestampCounter : Enable the timestamp counter + (+) HAL_FDCAN_DisableTimestampCounter : Disable the timestamp counter + (+) HAL_FDCAN_GetTimestampCounter : Get the timestamp counter value + (+) HAL_FDCAN_ResetTimestampCounter : Reset the timestamp counter to zero + (+) HAL_FDCAN_ConfigTimeoutCounter : Configure the timeout counter + (+) HAL_FDCAN_EnableTimeoutCounter : Enable the timeout counter + (+) HAL_FDCAN_DisableTimeoutCounter : Disable the timeout counter + (+) HAL_FDCAN_GetTimeoutCounter : Get the timeout counter value + (+) HAL_FDCAN_ResetTimeoutCounter : Reset the timeout counter to its start value + (+) HAL_FDCAN_ConfigTxDelayCompensation : Configure the transmitter delay compensation + (+) HAL_FDCAN_EnableTxDelayCompensation : Enable the transmitter delay compensation + (+) HAL_FDCAN_DisableTxDelayCompensation : Disable the transmitter delay compensation + (+) HAL_FDCAN_EnableISOMode : Enable ISO 11898-1 protocol mode + (+) HAL_FDCAN_DisableISOMode : Disable ISO 11898-1 protocol mode + (+) HAL_FDCAN_EnableEdgeFiltering : Enable edge filtering during bus integration + (+) HAL_FDCAN_DisableEdgeFiltering : Disable edge filtering during bus integration + +@endverbatim + * @{ + */ + +/** + * @brief Configure the FDCAN reception filter according to the specified + * parameters in the FDCAN_FilterTypeDef structure. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param sFilterConfig pointer to an FDCAN_FilterTypeDef structure that + * contains the filter configuration information + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_ConfigFilter(FDCAN_HandleTypeDef *hfdcan, const FDCAN_FilterTypeDef *sFilterConfig) +{ + uint32_t FilterElementW1; + uint32_t FilterElementW2; + uint32_t *FilterAddress; + HAL_FDCAN_StateTypeDef state = hfdcan->State; + + if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY)) + { + /* Check function parameters */ + assert_param(IS_FDCAN_ID_TYPE(sFilterConfig->IdType)); + assert_param(IS_FDCAN_FILTER_CFG(sFilterConfig->FilterConfig)); + + if (sFilterConfig->IdType == FDCAN_STANDARD_ID) + { + /* Check function parameters */ + assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterIndex, (hfdcan->Init.StdFiltersNbr - 1U))); + assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterID1, 0x7FFU)); + assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterID2, 0x7FFU)); + assert_param(IS_FDCAN_STD_FILTER_TYPE(sFilterConfig->FilterType)); + + /* Build filter element */ + FilterElementW1 = ((sFilterConfig->FilterType << 30U) | + (sFilterConfig->FilterConfig << 27U) | + (sFilterConfig->FilterID1 << 16U) | + sFilterConfig->FilterID2); + + /* Calculate filter address */ + FilterAddress = (uint32_t *)(hfdcan->msgRam.StandardFilterSA + (sFilterConfig->FilterIndex * SRAMCAN_FLS_SIZE)); + + /* Write filter element to the message RAM */ + *FilterAddress = FilterElementW1; + } + else /* sFilterConfig->IdType == FDCAN_EXTENDED_ID */ + { + /* Check function parameters */ + assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterIndex, (hfdcan->Init.ExtFiltersNbr - 1U))); + assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterID1, 0x1FFFFFFFU)); + assert_param(IS_FDCAN_MAX_VALUE(sFilterConfig->FilterID2, 0x1FFFFFFFU)); + assert_param(IS_FDCAN_EXT_FILTER_TYPE(sFilterConfig->FilterType)); + + /* Build first word of filter element */ + FilterElementW1 = ((sFilterConfig->FilterConfig << 29U) | sFilterConfig->FilterID1); + + /* Build second word of filter element */ + FilterElementW2 = ((sFilterConfig->FilterType << 30U) | sFilterConfig->FilterID2); + + /* Calculate filter address */ + FilterAddress = (uint32_t *)(hfdcan->msgRam.ExtendedFilterSA + (sFilterConfig->FilterIndex * SRAMCAN_FLE_SIZE)); + + /* Write filter element to the message RAM */ + *FilterAddress = FilterElementW1; + FilterAddress++; + *FilterAddress = FilterElementW2; + } + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED; + + return HAL_ERROR; + } +} + +/** + * @brief Configure the FDCAN global filter. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param NonMatchingStd Defines how received messages with 11-bit IDs that + * do not match any element of the filter list are treated. + * This parameter can be a value of @arg FDCAN_Non_Matching_Frames. + * @param NonMatchingExt Defines how received messages with 29-bit IDs that + * do not match any element of the filter list are treated. + * This parameter can be a value of @arg FDCAN_Non_Matching_Frames. + * @param RejectRemoteStd Filter or reject all the remote 11-bit IDs frames. + * This parameter can be a value of @arg FDCAN_Reject_Remote_Frames. + * @param RejectRemoteExt Filter or reject all the remote 29-bit IDs frames. + * This parameter can be a value of @arg FDCAN_Reject_Remote_Frames. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_ConfigGlobalFilter(FDCAN_HandleTypeDef *hfdcan, + uint32_t NonMatchingStd, + uint32_t NonMatchingExt, + uint32_t RejectRemoteStd, + uint32_t RejectRemoteExt) +{ + /* Check function parameters */ + assert_param(IS_FDCAN_NON_MATCHING(NonMatchingStd)); + assert_param(IS_FDCAN_NON_MATCHING(NonMatchingExt)); + assert_param(IS_FDCAN_REJECT_REMOTE(RejectRemoteStd)); + assert_param(IS_FDCAN_REJECT_REMOTE(RejectRemoteExt)); + + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + /* Configure global filter */ + MODIFY_REG(hfdcan->Instance->RXGFC, (FDCAN_RXGFC_ANFS | + FDCAN_RXGFC_ANFE | + FDCAN_RXGFC_RRFS | + FDCAN_RXGFC_RRFE), + ((NonMatchingStd << FDCAN_RXGFC_ANFS_Pos) | + (NonMatchingExt << FDCAN_RXGFC_ANFE_Pos) | + (RejectRemoteStd << FDCAN_RXGFC_RRFS_Pos) | + (RejectRemoteExt << FDCAN_RXGFC_RRFE_Pos))); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY; + + return HAL_ERROR; + } +} + +/** + * @brief Configure the extended ID mask. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param Mask Extended ID Mask. + * This parameter must be a number between 0 and 0x1FFFFFFF. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_ConfigExtendedIdMask(FDCAN_HandleTypeDef *hfdcan, uint32_t Mask) +{ + /* Check function parameters */ + assert_param(IS_FDCAN_MAX_VALUE(Mask, 0x1FFFFFFFU)); + + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + /* Configure the extended ID mask */ + hfdcan->Instance->XIDAM = Mask; + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY; + + return HAL_ERROR; + } +} + +/** + * @brief Configure the Rx FIFO operation mode. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param RxFifo Rx FIFO. + * This parameter can be one of the following values: + * @arg FDCAN_RX_FIFO0: Rx FIFO 0 + * @arg FDCAN_RX_FIFO1: Rx FIFO 1 + * @param OperationMode operation mode. + * This parameter can be a value of @arg FDCAN_Rx_FIFO_operation_mode. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_ConfigRxFifoOverwrite(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo, uint32_t OperationMode) +{ + /* Check function parameters */ + assert_param(IS_FDCAN_RX_FIFO(RxFifo)); + assert_param(IS_FDCAN_RX_FIFO_MODE(OperationMode)); + + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + if (RxFifo == FDCAN_RX_FIFO0) + { + /* Select FIFO 0 Operation Mode */ + MODIFY_REG(hfdcan->Instance->RXGFC, FDCAN_RXGFC_F0OM, (OperationMode << FDCAN_RXGFC_F0OM_Pos)); + } + else /* RxFifo == FDCAN_RX_FIFO1 */ + { + /* Select FIFO 1 Operation Mode */ + MODIFY_REG(hfdcan->Instance->RXGFC, FDCAN_RXGFC_F1OM, (OperationMode << FDCAN_RXGFC_F1OM_Pos)); + } + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY; + + return HAL_ERROR; + } +} + +/** + * @brief Configure the RAM watchdog. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param CounterStartValue Start value of the Message RAM Watchdog Counter, + * This parameter must be a number between 0x00 and 0xFF, + * with the reset value of 0x00 the counter is disabled. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_ConfigRamWatchdog(FDCAN_HandleTypeDef *hfdcan, uint32_t CounterStartValue) +{ + /* Check function parameters */ + assert_param(IS_FDCAN_MAX_VALUE(CounterStartValue, 0xFFU)); + + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + /* Configure the RAM watchdog counter start value */ + MODIFY_REG(hfdcan->Instance->RWD, FDCAN_RWD_WDC, CounterStartValue); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY; + + return HAL_ERROR; + } +} + +/** + * @brief Configure the timestamp counter. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param TimestampPrescaler Timestamp Counter Prescaler. + * This parameter can be a value of @arg FDCAN_Timestamp_Prescaler. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_ConfigTimestampCounter(FDCAN_HandleTypeDef *hfdcan, uint32_t TimestampPrescaler) +{ + /* Check function parameters */ + assert_param(IS_FDCAN_TIMESTAMP_PRESCALER(TimestampPrescaler)); + + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + /* Configure prescaler */ + MODIFY_REG(hfdcan->Instance->TSCC, FDCAN_TSCC_TCP, TimestampPrescaler); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY; + + return HAL_ERROR; + } +} + +/** + * @brief Enable the timestamp counter. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param TimestampOperation Timestamp counter operation. + * This parameter can be a value of @arg FDCAN_Timestamp. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_EnableTimestampCounter(FDCAN_HandleTypeDef *hfdcan, uint32_t TimestampOperation) +{ + /* Check function parameters */ + assert_param(IS_FDCAN_TIMESTAMP(TimestampOperation)); + + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + /* Enable timestamp counter */ + MODIFY_REG(hfdcan->Instance->TSCC, FDCAN_TSCC_TSS, TimestampOperation); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY; + + return HAL_ERROR; + } +} + +/** + * @brief Disable the timestamp counter. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_DisableTimestampCounter(FDCAN_HandleTypeDef *hfdcan) +{ + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + /* Disable timestamp counter */ + CLEAR_BIT(hfdcan->Instance->TSCC, FDCAN_TSCC_TSS); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY; + + return HAL_ERROR; + } +} + +/** + * @brief Get the timestamp counter value. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval Timestamp counter value + */ +uint16_t HAL_FDCAN_GetTimestampCounter(const FDCAN_HandleTypeDef *hfdcan) +{ + return (uint16_t)(hfdcan->Instance->TSCV); +} + +/** + * @brief Reset the timestamp counter to zero. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_ResetTimestampCounter(FDCAN_HandleTypeDef *hfdcan) +{ + if ((hfdcan->Instance->TSCC & FDCAN_TSCC_TSS) != FDCAN_TIMESTAMP_EXTERNAL) + { + /* Reset timestamp counter. + Actually any write operation to TSCV clears the counter */ + CLEAR_REG(hfdcan->Instance->TSCV); + } + else + { + /* Update error code. + Unable to reset external counter */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED; + + return HAL_ERROR; + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Configure the timeout counter. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param TimeoutOperation Timeout counter operation. + * This parameter can be a value of @arg FDCAN_Timeout_Operation. + * @param TimeoutPeriod Start value of the timeout down-counter. + * This parameter must be a number between 0x0000 and 0xFFFF + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_ConfigTimeoutCounter(FDCAN_HandleTypeDef *hfdcan, uint32_t TimeoutOperation, + uint32_t TimeoutPeriod) +{ + /* Check function parameters */ + assert_param(IS_FDCAN_TIMEOUT(TimeoutOperation)); + assert_param(IS_FDCAN_MAX_VALUE(TimeoutPeriod, 0xFFFFU)); + + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + /* Select timeout operation and configure period */ + MODIFY_REG(hfdcan->Instance->TOCC, + (FDCAN_TOCC_TOS | FDCAN_TOCC_TOP), (TimeoutOperation | (TimeoutPeriod << FDCAN_TOCC_TOP_Pos))); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY; + + return HAL_ERROR; + } +} + +/** + * @brief Enable the timeout counter. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_EnableTimeoutCounter(FDCAN_HandleTypeDef *hfdcan) +{ + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + /* Enable timeout counter */ + SET_BIT(hfdcan->Instance->TOCC, FDCAN_TOCC_ETOC); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY; + + return HAL_ERROR; + } +} + +/** + * @brief Disable the timeout counter. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_DisableTimeoutCounter(FDCAN_HandleTypeDef *hfdcan) +{ + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + /* Disable timeout counter */ + CLEAR_BIT(hfdcan->Instance->TOCC, FDCAN_TOCC_ETOC); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY; + + return HAL_ERROR; + } +} + +/** + * @brief Get the timeout counter value. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval Timeout counter value + */ +uint16_t HAL_FDCAN_GetTimeoutCounter(const FDCAN_HandleTypeDef *hfdcan) +{ + return (uint16_t)(hfdcan->Instance->TOCV); +} + +/** + * @brief Reset the timeout counter to its start value. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_ResetTimeoutCounter(FDCAN_HandleTypeDef *hfdcan) +{ + if ((hfdcan->Instance->TOCC & FDCAN_TOCC_TOS) == FDCAN_TIMEOUT_CONTINUOUS) + { + /* Reset timeout counter to start value */ + CLEAR_REG(hfdcan->Instance->TOCV); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code. + Unable to reset counter: controlled only by FIFO empty state */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_SUPPORTED; + + return HAL_ERROR; + } +} + +/** + * @brief Configure the transmitter delay compensation. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param TdcOffset Transmitter Delay Compensation Offset. + * This parameter must be a number between 0x00 and 0x7F. + * @param TdcFilter Transmitter Delay Compensation Filter Window Length. + * This parameter must be a number between 0x00 and 0x7F. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_ConfigTxDelayCompensation(FDCAN_HandleTypeDef *hfdcan, uint32_t TdcOffset, + uint32_t TdcFilter) +{ + /* Check function parameters */ + assert_param(IS_FDCAN_MAX_VALUE(TdcOffset, 0x7FU)); + assert_param(IS_FDCAN_MAX_VALUE(TdcFilter, 0x7FU)); + + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + /* Configure TDC offset and filter window */ + hfdcan->Instance->TDCR = ((TdcFilter << FDCAN_TDCR_TDCF_Pos) | (TdcOffset << FDCAN_TDCR_TDCO_Pos)); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY; + + return HAL_ERROR; + } +} + +/** + * @brief Enable the transmitter delay compensation. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_EnableTxDelayCompensation(FDCAN_HandleTypeDef *hfdcan) +{ + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + /* Enable transmitter delay compensation */ + SET_BIT(hfdcan->Instance->DBTP, FDCAN_DBTP_TDC); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY; + + return HAL_ERROR; + } +} + +/** + * @brief Disable the transmitter delay compensation. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_DisableTxDelayCompensation(FDCAN_HandleTypeDef *hfdcan) +{ + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + /* Disable transmitter delay compensation */ + CLEAR_BIT(hfdcan->Instance->DBTP, FDCAN_DBTP_TDC); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY; + + return HAL_ERROR; + } +} + +/** + * @brief Enable ISO 11898-1 protocol mode. + * CAN FD frame format is according to ISO 11898-1 standard. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_EnableISOMode(FDCAN_HandleTypeDef *hfdcan) +{ + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + /* Disable Non ISO protocol mode */ + CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_NISO); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY; + + return HAL_ERROR; + } +} + +/** + * @brief Disable ISO 11898-1 protocol mode. + * CAN FD frame format is according to Bosch CAN FD specification V1.0. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_DisableISOMode(FDCAN_HandleTypeDef *hfdcan) +{ + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + /* Enable Non ISO protocol mode */ + SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_NISO); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY; + + return HAL_ERROR; + } +} + +/** + * @brief Enable edge filtering during bus integration. + * Two consecutive dominant tq are required to detect an edge for hard synchronization. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_EnableEdgeFiltering(FDCAN_HandleTypeDef *hfdcan) +{ + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + /* Enable edge filtering */ + SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_EFBI); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY; + + return HAL_ERROR; + } +} + +/** + * @brief Disable edge filtering during bus integration. + * One dominant tq is required to detect an edge for hard synchronization. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_DisableEdgeFiltering(FDCAN_HandleTypeDef *hfdcan) +{ + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + /* Disable edge filtering */ + CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_EFBI); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY; + + return HAL_ERROR; + } +} + +/** + * @} + */ + +/** @defgroup FDCAN_Exported_Functions_Group3 Control functions + * @brief Control functions + * +@verbatim + ============================================================================== + ##### Control functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) HAL_FDCAN_Start : Start the FDCAN module + (+) HAL_FDCAN_Stop : Stop the FDCAN module and enable access to configuration registers + (+) HAL_FDCAN_AddMessageToTxFifoQ : Add a message to the Tx FIFO/Queue and activate the corresponding + transmission request + (+) HAL_FDCAN_GetLatestTxFifoQRequestBuffer : Get Tx buffer index of latest Tx FIFO/Queue request + (+) HAL_FDCAN_AbortTxRequest : Abort transmission request + (+) HAL_FDCAN_GetRxMessage : Get an FDCAN frame from the Rx FIFO zone into the message RAM + (+) HAL_FDCAN_GetTxEvent : Get an FDCAN Tx event from the Tx Event FIFO zone + into the message RAM + (+) HAL_FDCAN_GetHighPriorityMessageStatus : Get high priority message status + (+) HAL_FDCAN_GetProtocolStatus : Get protocol status + (+) HAL_FDCAN_GetErrorCounters : Get error counter values + (+) HAL_FDCAN_IsTxBufferMessagePending : Check if a transmission request is pending + on the selected Tx buffer + (+) HAL_FDCAN_GetRxFifoFillLevel : Return Rx FIFO fill level + (+) HAL_FDCAN_GetTxFifoFreeLevel : Return Tx FIFO free level + (+) HAL_FDCAN_IsRestrictedOperationMode : Check if the FDCAN peripheral entered Restricted Operation Mode + (+) HAL_FDCAN_ExitRestrictedOperationMode : Exit Restricted Operation Mode + +@endverbatim + * @{ + */ + +/** + * @brief Start the FDCAN module. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_Start(FDCAN_HandleTypeDef *hfdcan) +{ + if (hfdcan->State == HAL_FDCAN_STATE_READY) + { + /* Change FDCAN peripheral state */ + hfdcan->State = HAL_FDCAN_STATE_BUSY; + + /* Request leave initialisation */ + CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_INIT); + + /* Reset the FDCAN ErrorCode */ + hfdcan->ErrorCode = HAL_FDCAN_ERROR_NONE; + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_READY; + + return HAL_ERROR; + } +} + +/** + * @brief Stop the FDCAN module and enable access to configuration registers. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_Stop(FDCAN_HandleTypeDef *hfdcan) +{ + uint32_t Counter = 0U; + + if (hfdcan->State == HAL_FDCAN_STATE_BUSY) + { + /* Request initialisation */ + SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_INIT); + + /* Wait until the INIT bit into CCCR register is set */ + while ((hfdcan->Instance->CCCR & FDCAN_CCCR_INIT) == 0U) + { + /* Check for the Timeout */ + if (Counter > FDCAN_TIMEOUT_VALUE) + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT; + + /* Change FDCAN state */ + hfdcan->State = HAL_FDCAN_STATE_ERROR; + + return HAL_ERROR; + } + + /* Increment counter */ + Counter++; + } + + /* Reset counter */ + Counter = 0U; + + /* Exit from Sleep mode */ + CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CSR); + + /* Wait until FDCAN exits sleep mode */ + while ((hfdcan->Instance->CCCR & FDCAN_CCCR_CSA) == FDCAN_CCCR_CSA) + { + /* Check for the Timeout */ + if (Counter > FDCAN_TIMEOUT_VALUE) + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_TIMEOUT; + + /* Change FDCAN state */ + hfdcan->State = HAL_FDCAN_STATE_ERROR; + + return HAL_ERROR; + } + + /* Increment counter */ + Counter++; + } + + /* Enable configuration change */ + SET_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_CCE); + + /* Reset Latest Tx FIFO/Queue Request Buffer Index */ + hfdcan->LatestTxFifoQRequest = 0U; + + /* Change FDCAN peripheral state */ + hfdcan->State = HAL_FDCAN_STATE_READY; + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED; + + return HAL_ERROR; + } +} + +/** + * @brief Add a message to the Tx FIFO/Queue and activate the corresponding transmission request + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param pTxHeader pointer to a FDCAN_TxHeaderTypeDef structure. + * @param pTxData pointer to a buffer containing the payload of the Tx frame. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_AddMessageToTxFifoQ(FDCAN_HandleTypeDef *hfdcan, const FDCAN_TxHeaderTypeDef *pTxHeader, + const uint8_t *pTxData) +{ + uint32_t PutIndex; + + /* Check function parameters */ + assert_param(IS_FDCAN_ID_TYPE(pTxHeader->IdType)); + if (pTxHeader->IdType == FDCAN_STANDARD_ID) + { + assert_param(IS_FDCAN_MAX_VALUE(pTxHeader->Identifier, 0x7FFU)); + } + else /* pTxHeader->IdType == FDCAN_EXTENDED_ID */ + { + assert_param(IS_FDCAN_MAX_VALUE(pTxHeader->Identifier, 0x1FFFFFFFU)); + } + assert_param(IS_FDCAN_FRAME_TYPE(pTxHeader->TxFrameType)); + assert_param(IS_FDCAN_DLC(pTxHeader->DataLength)); + assert_param(IS_FDCAN_ESI(pTxHeader->ErrorStateIndicator)); + assert_param(IS_FDCAN_BRS(pTxHeader->BitRateSwitch)); + assert_param(IS_FDCAN_FDF(pTxHeader->FDFormat)); + assert_param(IS_FDCAN_EFC(pTxHeader->TxEventFifoControl)); + assert_param(IS_FDCAN_MAX_VALUE(pTxHeader->MessageMarker, 0xFFU)); + + if (hfdcan->State == HAL_FDCAN_STATE_BUSY) + { + /* Check that the Tx FIFO/Queue is not full */ + if ((hfdcan->Instance->TXFQS & FDCAN_TXFQS_TFQF) != 0U) + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_FIFO_FULL; + + return HAL_ERROR; + } + else + { + /* Retrieve the Tx FIFO PutIndex */ + PutIndex = ((hfdcan->Instance->TXFQS & FDCAN_TXFQS_TFQPI) >> FDCAN_TXFQS_TFQPI_Pos); + + /* Add the message to the Tx FIFO/Queue */ + FDCAN_CopyMessageToRAM(hfdcan, pTxHeader, pTxData, PutIndex); + + /* Activate the corresponding transmission request */ + hfdcan->Instance->TXBAR = ((uint32_t)1 << PutIndex); + + /* Store the Latest Tx FIFO/Queue Request Buffer Index */ + hfdcan->LatestTxFifoQRequest = ((uint32_t)1 << PutIndex); + } + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED; + + return HAL_ERROR; + } +} + +/** + * @brief Get Tx buffer index of latest Tx FIFO/Queue request + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval Tx buffer index of last Tx FIFO/Queue request + * - Any value of @arg FDCAN_Tx_location if Tx request has been submitted. + * - 0 if no Tx FIFO/Queue request have been submitted. + */ +uint32_t HAL_FDCAN_GetLatestTxFifoQRequestBuffer(const FDCAN_HandleTypeDef *hfdcan) +{ + /* Return Last Tx FIFO/Queue Request Buffer */ + return hfdcan->LatestTxFifoQRequest; +} + +/** + * @brief Abort transmission request + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param BufferIndex buffer index. + * This parameter can be any combination of @arg FDCAN_Tx_location. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_AbortTxRequest(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndex) +{ + /* Check function parameters */ + assert_param(IS_FDCAN_TX_LOCATION_LIST(BufferIndex)); + + if (hfdcan->State == HAL_FDCAN_STATE_BUSY) + { + /* Add cancellation request */ + hfdcan->Instance->TXBCR = BufferIndex; + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED; + + return HAL_ERROR; + } +} + +/** + * @brief Get an FDCAN frame from the Rx FIFO zone into the message RAM. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param RxLocation Location of the received message to be read. + * This parameter can be a value of @arg FDCAN_Rx_location. + * @param pRxHeader pointer to a FDCAN_RxHeaderTypeDef structure. + * @param pRxData pointer to a buffer where the payload of the Rx frame will be stored. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_GetRxMessage(FDCAN_HandleTypeDef *hfdcan, uint32_t RxLocation, + FDCAN_RxHeaderTypeDef *pRxHeader, uint8_t *pRxData) +{ + uint32_t *RxAddress; + uint8_t *pData; + uint32_t ByteCounter; + uint32_t GetIndex = 0; + HAL_FDCAN_StateTypeDef state = hfdcan->State; + + /* Check function parameters */ + assert_param(IS_FDCAN_RX_FIFO(RxLocation)); + + if (state == HAL_FDCAN_STATE_BUSY) + { + if (RxLocation == FDCAN_RX_FIFO0) /* Rx element is assigned to the Rx FIFO 0 */ + { + /* Check that the Rx FIFO 0 is not empty */ + if ((hfdcan->Instance->RXF0S & FDCAN_RXF0S_F0FL) == 0U) + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_FIFO_EMPTY; + + return HAL_ERROR; + } + else + { + /* Check that the Rx FIFO 0 is full & overwrite mode is on */ + if (((hfdcan->Instance->RXF0S & FDCAN_RXF0S_F0F) >> FDCAN_RXF0S_F0F_Pos) == 1U) + { + if (((hfdcan->Instance->RXGFC & FDCAN_RXGFC_F0OM) >> FDCAN_RXGFC_F0OM_Pos) == FDCAN_RX_FIFO_OVERWRITE) + { + /* When overwrite status is on discard first message in FIFO */ + GetIndex = 1U; + } + } + + /* Calculate Rx FIFO 0 element index */ + GetIndex += ((hfdcan->Instance->RXF0S & FDCAN_RXF0S_F0GI) >> FDCAN_RXF0S_F0GI_Pos); + + /* Calculate Rx FIFO 0 element address */ + RxAddress = (uint32_t *)(hfdcan->msgRam.RxFIFO0SA + (GetIndex * SRAMCAN_RF0_SIZE)); + } + } + else /* Rx element is assigned to the Rx FIFO 1 */ + { + /* Check that the Rx FIFO 1 is not empty */ + if ((hfdcan->Instance->RXF1S & FDCAN_RXF1S_F1FL) == 0U) + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_FIFO_EMPTY; + + return HAL_ERROR; + } + else + { + /* Check that the Rx FIFO 1 is full & overwrite mode is on */ + if (((hfdcan->Instance->RXF1S & FDCAN_RXF1S_F1F) >> FDCAN_RXF1S_F1F_Pos) == 1U) + { + if (((hfdcan->Instance->RXGFC & FDCAN_RXGFC_F1OM) >> FDCAN_RXGFC_F1OM_Pos) == FDCAN_RX_FIFO_OVERWRITE) + { + /* When overwrite status is on discard first message in FIFO */ + GetIndex = 1U; + } + } + + /* Calculate Rx FIFO 1 element index */ + GetIndex += ((hfdcan->Instance->RXF1S & FDCAN_RXF1S_F1GI) >> FDCAN_RXF1S_F1GI_Pos); + /* Calculate Rx FIFO 1 element address */ + RxAddress = (uint32_t *)(hfdcan->msgRam.RxFIFO1SA + (GetIndex * SRAMCAN_RF1_SIZE)); + } + } + + /* Retrieve IdType */ + pRxHeader->IdType = *RxAddress & FDCAN_ELEMENT_MASK_XTD; + + /* Retrieve Identifier */ + if (pRxHeader->IdType == FDCAN_STANDARD_ID) /* Standard ID element */ + { + pRxHeader->Identifier = ((*RxAddress & FDCAN_ELEMENT_MASK_STDID) >> 18U); + } + else /* Extended ID element */ + { + pRxHeader->Identifier = (*RxAddress & FDCAN_ELEMENT_MASK_EXTID); + } + + /* Retrieve RxFrameType */ + pRxHeader->RxFrameType = (*RxAddress & FDCAN_ELEMENT_MASK_RTR); + + /* Retrieve ErrorStateIndicator */ + pRxHeader->ErrorStateIndicator = (*RxAddress & FDCAN_ELEMENT_MASK_ESI); + + /* Increment RxAddress pointer to second word of Rx FIFO element */ + RxAddress++; + + /* Retrieve RxTimestamp */ + pRxHeader->RxTimestamp = (*RxAddress & FDCAN_ELEMENT_MASK_TS); + + /* Retrieve DataLength */ + pRxHeader->DataLength = ((*RxAddress & FDCAN_ELEMENT_MASK_DLC) >> 16U); + + /* Retrieve BitRateSwitch */ + pRxHeader->BitRateSwitch = (*RxAddress & FDCAN_ELEMENT_MASK_BRS); + + /* Retrieve FDFormat */ + pRxHeader->FDFormat = (*RxAddress & FDCAN_ELEMENT_MASK_FDF); + + /* Retrieve FilterIndex */ + pRxHeader->FilterIndex = ((*RxAddress & FDCAN_ELEMENT_MASK_FIDX) >> 24U); + + /* Retrieve NonMatchingFrame */ + pRxHeader->IsFilterMatchingFrame = ((*RxAddress & FDCAN_ELEMENT_MASK_ANMF) >> 31U); + + /* Increment RxAddress pointer to payload of Rx FIFO element */ + RxAddress++; + + /* Retrieve Rx payload */ + pData = (uint8_t *)RxAddress; + for (ByteCounter = 0; ByteCounter < DLCtoBytes[pRxHeader->DataLength]; ByteCounter++) + { + pRxData[ByteCounter] = pData[ByteCounter]; + } + + if (RxLocation == FDCAN_RX_FIFO0) /* Rx element is assigned to the Rx FIFO 0 */ + { + /* Acknowledge the Rx FIFO 0 that the oldest element is read so that it increments the GetIndex */ + hfdcan->Instance->RXF0A = GetIndex; + } + else /* Rx element is assigned to the Rx FIFO 1 */ + { + /* Acknowledge the Rx FIFO 1 that the oldest element is read so that it increments the GetIndex */ + hfdcan->Instance->RXF1A = GetIndex; + } + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED; + + return HAL_ERROR; + } +} + +/** + * @brief Get an FDCAN Tx event from the Tx Event FIFO zone into the message RAM. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param pTxEvent pointer to a FDCAN_TxEventFifoTypeDef structure. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_GetTxEvent(FDCAN_HandleTypeDef *hfdcan, FDCAN_TxEventFifoTypeDef *pTxEvent) +{ + uint32_t *TxEventAddress; + uint32_t GetIndex; + HAL_FDCAN_StateTypeDef state = hfdcan->State; + + if (state == HAL_FDCAN_STATE_BUSY) + { + /* Check that the Tx event FIFO is not empty */ + if ((hfdcan->Instance->TXEFS & FDCAN_TXEFS_EFFL) == 0U) + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_FIFO_EMPTY; + + return HAL_ERROR; + } + + /* Calculate Tx event FIFO element address */ + GetIndex = ((hfdcan->Instance->TXEFS & FDCAN_TXEFS_EFGI) >> FDCAN_TXEFS_EFGI_Pos); + TxEventAddress = (uint32_t *)(hfdcan->msgRam.TxEventFIFOSA + (GetIndex * SRAMCAN_TEF_SIZE)); + + /* Retrieve IdType */ + pTxEvent->IdType = *TxEventAddress & FDCAN_ELEMENT_MASK_XTD; + + /* Retrieve Identifier */ + if (pTxEvent->IdType == FDCAN_STANDARD_ID) /* Standard ID element */ + { + pTxEvent->Identifier = ((*TxEventAddress & FDCAN_ELEMENT_MASK_STDID) >> 18U); + } + else /* Extended ID element */ + { + pTxEvent->Identifier = (*TxEventAddress & FDCAN_ELEMENT_MASK_EXTID); + } + + /* Retrieve TxFrameType */ + pTxEvent->TxFrameType = (*TxEventAddress & FDCAN_ELEMENT_MASK_RTR); + + /* Retrieve ErrorStateIndicator */ + pTxEvent->ErrorStateIndicator = (*TxEventAddress & FDCAN_ELEMENT_MASK_ESI); + + /* Increment TxEventAddress pointer to second word of Tx Event FIFO element */ + TxEventAddress++; + + /* Retrieve TxTimestamp */ + pTxEvent->TxTimestamp = (*TxEventAddress & FDCAN_ELEMENT_MASK_TS); + + /* Retrieve DataLength */ + pTxEvent->DataLength = ((*TxEventAddress & FDCAN_ELEMENT_MASK_DLC) >> 16U); + + /* Retrieve BitRateSwitch */ + pTxEvent->BitRateSwitch = (*TxEventAddress & FDCAN_ELEMENT_MASK_BRS); + + /* Retrieve FDFormat */ + pTxEvent->FDFormat = (*TxEventAddress & FDCAN_ELEMENT_MASK_FDF); + + /* Retrieve EventType */ + pTxEvent->EventType = (*TxEventAddress & FDCAN_ELEMENT_MASK_ET); + + /* Retrieve MessageMarker */ + pTxEvent->MessageMarker = ((*TxEventAddress & FDCAN_ELEMENT_MASK_MM) >> 24U); + + /* Acknowledge the Tx Event FIFO that the oldest element is read so that it increments the GetIndex */ + hfdcan->Instance->TXEFA = GetIndex; + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED; + + return HAL_ERROR; + } +} + +/** + * @brief Get high priority message status. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param HpMsgStatus pointer to an FDCAN_HpMsgStatusTypeDef structure. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_GetHighPriorityMessageStatus(const FDCAN_HandleTypeDef *hfdcan, + FDCAN_HpMsgStatusTypeDef *HpMsgStatus) +{ + HpMsgStatus->FilterList = ((hfdcan->Instance->HPMS & FDCAN_HPMS_FLST) >> FDCAN_HPMS_FLST_Pos); + HpMsgStatus->FilterIndex = ((hfdcan->Instance->HPMS & FDCAN_HPMS_FIDX) >> FDCAN_HPMS_FIDX_Pos); + HpMsgStatus->MessageStorage = (hfdcan->Instance->HPMS & FDCAN_HPMS_MSI); + HpMsgStatus->MessageIndex = (hfdcan->Instance->HPMS & FDCAN_HPMS_BIDX); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Get protocol status. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param ProtocolStatus pointer to an FDCAN_ProtocolStatusTypeDef structure. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_GetProtocolStatus(const FDCAN_HandleTypeDef *hfdcan, + FDCAN_ProtocolStatusTypeDef *ProtocolStatus) +{ + uint32_t StatusReg; + + /* Read the protocol status register */ + StatusReg = READ_REG(hfdcan->Instance->PSR); + + /* Fill the protocol status structure */ + ProtocolStatus->LastErrorCode = (StatusReg & FDCAN_PSR_LEC); + ProtocolStatus->DataLastErrorCode = ((StatusReg & FDCAN_PSR_DLEC) >> FDCAN_PSR_DLEC_Pos); + ProtocolStatus->Activity = (StatusReg & FDCAN_PSR_ACT); + ProtocolStatus->ErrorPassive = ((StatusReg & FDCAN_PSR_EP) >> FDCAN_PSR_EP_Pos); + ProtocolStatus->Warning = ((StatusReg & FDCAN_PSR_EW) >> FDCAN_PSR_EW_Pos); + ProtocolStatus->BusOff = ((StatusReg & FDCAN_PSR_BO) >> FDCAN_PSR_BO_Pos); + ProtocolStatus->RxESIflag = ((StatusReg & FDCAN_PSR_RESI) >> FDCAN_PSR_RESI_Pos); + ProtocolStatus->RxBRSflag = ((StatusReg & FDCAN_PSR_RBRS) >> FDCAN_PSR_RBRS_Pos); + ProtocolStatus->RxFDFflag = ((StatusReg & FDCAN_PSR_REDL) >> FDCAN_PSR_REDL_Pos); + ProtocolStatus->ProtocolException = ((StatusReg & FDCAN_PSR_PXE) >> FDCAN_PSR_PXE_Pos); + ProtocolStatus->TDCvalue = ((StatusReg & FDCAN_PSR_TDCV) >> FDCAN_PSR_TDCV_Pos); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Get error counter values. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param ErrorCounters pointer to an FDCAN_ErrorCountersTypeDef structure. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_GetErrorCounters(const FDCAN_HandleTypeDef *hfdcan, + FDCAN_ErrorCountersTypeDef *ErrorCounters) +{ + uint32_t CountersReg; + + /* Read the error counters register */ + CountersReg = READ_REG(hfdcan->Instance->ECR); + + /* Fill the error counters structure */ + ErrorCounters->TxErrorCnt = ((CountersReg & FDCAN_ECR_TEC) >> FDCAN_ECR_TEC_Pos); + ErrorCounters->RxErrorCnt = ((CountersReg & FDCAN_ECR_REC) >> FDCAN_ECR_REC_Pos); + ErrorCounters->RxErrorPassive = ((CountersReg & FDCAN_ECR_RP) >> FDCAN_ECR_RP_Pos); + ErrorCounters->ErrorLogging = ((CountersReg & FDCAN_ECR_CEL) >> FDCAN_ECR_CEL_Pos); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Check if a transmission request is pending on the selected Tx buffer. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param TxBufferIndex Tx buffer index. + * This parameter can be any combination of @arg FDCAN_Tx_location. + * @retval Status + * - 0 : No pending transmission request on TxBufferIndex list. + * - 1 : Pending transmission request on TxBufferIndex. + */ +uint32_t HAL_FDCAN_IsTxBufferMessagePending(const FDCAN_HandleTypeDef *hfdcan, uint32_t TxBufferIndex) +{ + /* Check function parameters */ + assert_param(IS_FDCAN_TX_LOCATION_LIST(TxBufferIndex)); + + /* Check pending transmission request on the selected buffer */ + if ((hfdcan->Instance->TXBRP & TxBufferIndex) == 0U) + { + return 0; + } + return 1; +} + +/** + * @brief Return Rx FIFO fill level. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param RxFifo Rx FIFO. + * This parameter can be one of the following values: + * @arg FDCAN_RX_FIFO0: Rx FIFO 0 + * @arg FDCAN_RX_FIFO1: Rx FIFO 1 + * @retval Rx FIFO fill level. + */ +uint32_t HAL_FDCAN_GetRxFifoFillLevel(const FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo) +{ + uint32_t FillLevel; + + /* Check function parameters */ + assert_param(IS_FDCAN_RX_FIFO(RxFifo)); + + if (RxFifo == FDCAN_RX_FIFO0) + { + FillLevel = hfdcan->Instance->RXF0S & FDCAN_RXF0S_F0FL; + } + else /* RxFifo == FDCAN_RX_FIFO1 */ + { + FillLevel = hfdcan->Instance->RXF1S & FDCAN_RXF1S_F1FL; + } + + /* Return Rx FIFO fill level */ + return FillLevel; +} + +/** + * @brief Return Tx FIFO free level: number of consecutive free Tx FIFO + * elements starting from Tx FIFO GetIndex. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval Tx FIFO free level. + */ +uint32_t HAL_FDCAN_GetTxFifoFreeLevel(const FDCAN_HandleTypeDef *hfdcan) +{ + uint32_t FreeLevel; + + FreeLevel = hfdcan->Instance->TXFQS & FDCAN_TXFQS_TFFL; + + /* Return Tx FIFO free level */ + return FreeLevel; +} + +/** + * @brief Check if the FDCAN peripheral entered Restricted Operation Mode. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval Status + * - 0 : Normal FDCAN operation. + * - 1 : Restricted Operation Mode active. + */ +uint32_t HAL_FDCAN_IsRestrictedOperationMode(const FDCAN_HandleTypeDef *hfdcan) +{ + uint32_t OperationMode; + + /* Get Operation Mode */ + OperationMode = ((hfdcan->Instance->CCCR & FDCAN_CCCR_ASM) >> FDCAN_CCCR_ASM_Pos); + + return OperationMode; +} + +/** + * @brief Exit Restricted Operation Mode. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_ExitRestrictedOperationMode(FDCAN_HandleTypeDef *hfdcan) +{ + HAL_FDCAN_StateTypeDef state = hfdcan->State; + + if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY)) + { + /* Exit Restricted Operation mode */ + CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_ASM); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED; + + return HAL_ERROR; + } +} + +/** + * @} + */ + +/** @defgroup FDCAN_Exported_Functions_Group4 Interrupts management + * @brief Interrupts management + * +@verbatim + ============================================================================== + ##### Interrupts management ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) HAL_FDCAN_ConfigInterruptLines : Assign interrupts to either Interrupt line 0 or 1 + (+) HAL_FDCAN_ActivateNotification : Enable interrupts + (+) HAL_FDCAN_DeactivateNotification : Disable interrupts + (+) HAL_FDCAN_IRQHandler : Handles FDCAN interrupt request + +@endverbatim + * @{ + */ + +/** + * @brief Assign interrupts to either Interrupt line 0 or 1. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param ITList indicates which interrupts group will be assigned to the selected interrupt line. + * This parameter can be any combination of @arg FDCAN_Interrupts_Group. + * @param InterruptLine Interrupt line. + * This parameter can be a value of @arg FDCAN_Interrupt_Line. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_ConfigInterruptLines(FDCAN_HandleTypeDef *hfdcan, uint32_t ITList, uint32_t InterruptLine) +{ + HAL_FDCAN_StateTypeDef state = hfdcan->State; + + /* Check function parameters */ + assert_param(IS_FDCAN_IT_GROUP(ITList)); + assert_param(IS_FDCAN_IT_LINE(InterruptLine)); + + if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY)) + { + /* Assign list of interrupts to the selected line */ + if (InterruptLine == FDCAN_INTERRUPT_LINE0) + { + CLEAR_BIT(hfdcan->Instance->ILS, ITList); + } + else /* InterruptLine == FDCAN_INTERRUPT_LINE1 */ + { + SET_BIT(hfdcan->Instance->ILS, ITList); + } + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED; + + return HAL_ERROR; + } +} + +/** + * @brief Enable interrupts. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param ActiveITs indicates which interrupts will be enabled. + * This parameter can be any combination of @arg FDCAN_Interrupts. + * @param BufferIndexes Tx Buffer Indexes. + * This parameter can be any combination of @arg FDCAN_Tx_location. + * This parameter is ignored if ActiveITs does not include one of the following: + * - FDCAN_IT_TX_COMPLETE + * - FDCAN_IT_TX_ABORT_COMPLETE + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_ActivateNotification(FDCAN_HandleTypeDef *hfdcan, uint32_t ActiveITs, + uint32_t BufferIndexes) +{ + HAL_FDCAN_StateTypeDef state = hfdcan->State; + uint32_t ITs_lines_selection; + + /* Check function parameters */ + assert_param(IS_FDCAN_IT(ActiveITs)); + if ((ActiveITs & (FDCAN_IT_TX_COMPLETE | FDCAN_IT_TX_ABORT_COMPLETE)) != 0U) + { + assert_param(IS_FDCAN_TX_LOCATION_LIST(BufferIndexes)); + } + + if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY)) + { + /* Get interrupts line selection */ + ITs_lines_selection = hfdcan->Instance->ILS; + + /* Enable Interrupt lines */ + if ((((ActiveITs & FDCAN_IT_LIST_RX_FIFO0) != 0U) + && (((ITs_lines_selection) & FDCAN_IT_GROUP_RX_FIFO0) == 0U)) || \ + (((ActiveITs & FDCAN_IT_LIST_RX_FIFO1) != 0U) + && (((ITs_lines_selection) & FDCAN_IT_GROUP_RX_FIFO1) == 0U)) || \ + (((ActiveITs & FDCAN_IT_LIST_SMSG) != 0U) + && (((ITs_lines_selection) & FDCAN_IT_GROUP_SMSG) == 0U)) || \ + (((ActiveITs & FDCAN_IT_LIST_TX_FIFO_ERROR) != 0U) + && (((ITs_lines_selection) & FDCAN_IT_GROUP_TX_FIFO_ERROR) == 0U)) || \ + (((ActiveITs & FDCAN_IT_LIST_MISC) != 0U) + && (((ITs_lines_selection) & FDCAN_IT_GROUP_MISC) == 0U)) || \ + (((ActiveITs & FDCAN_IT_LIST_BIT_LINE_ERROR) != 0U) + && (((ITs_lines_selection) & FDCAN_IT_GROUP_BIT_LINE_ERROR) == 0U)) || \ + (((ActiveITs & FDCAN_IT_LIST_PROTOCOL_ERROR) != 0U) + && (((ITs_lines_selection) & FDCAN_IT_GROUP_PROTOCOL_ERROR) == 0U))) + { + /* Enable Interrupt line 0 */ + SET_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE0); + } + if ((((ActiveITs & FDCAN_IT_LIST_RX_FIFO0) != 0U) + && (((ITs_lines_selection) & FDCAN_IT_GROUP_RX_FIFO0) != 0U)) || \ + (((ActiveITs & FDCAN_IT_LIST_RX_FIFO1) != 0U) + && (((ITs_lines_selection) & FDCAN_IT_GROUP_RX_FIFO1) != 0U)) || \ + (((ActiveITs & FDCAN_IT_LIST_SMSG) != 0U) + && (((ITs_lines_selection) & FDCAN_IT_GROUP_SMSG) != 0U)) || \ + (((ActiveITs & FDCAN_IT_LIST_TX_FIFO_ERROR) != 0U) + && (((ITs_lines_selection) & FDCAN_IT_GROUP_TX_FIFO_ERROR) != 0U)) || \ + (((ActiveITs & FDCAN_IT_LIST_MISC) != 0U) + && (((ITs_lines_selection) & FDCAN_IT_GROUP_MISC) != 0U)) || \ + (((ActiveITs & FDCAN_IT_LIST_BIT_LINE_ERROR) != 0U) + && (((ITs_lines_selection) & FDCAN_IT_GROUP_BIT_LINE_ERROR) != 0U)) || \ + (((ActiveITs & FDCAN_IT_LIST_PROTOCOL_ERROR) != 0U) + && (((ITs_lines_selection) & FDCAN_IT_GROUP_PROTOCOL_ERROR) != 0U))) + { + /* Enable Interrupt line 1 */ + SET_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE1); + } + + if ((ActiveITs & FDCAN_IT_TX_COMPLETE) != 0U) + { + /* Enable Tx Buffer Transmission Interrupt to set TC flag in IR register, + but interrupt will only occur if TC is enabled in IE register */ + SET_BIT(hfdcan->Instance->TXBTIE, BufferIndexes); + } + + if ((ActiveITs & FDCAN_IT_TX_ABORT_COMPLETE) != 0U) + { + /* Enable Tx Buffer Cancellation Finished Interrupt to set TCF flag in IR register, + but interrupt will only occur if TCF is enabled in IE register */ + SET_BIT(hfdcan->Instance->TXBCIE, BufferIndexes); + } + + /* Enable the selected interrupts */ + __HAL_FDCAN_ENABLE_IT(hfdcan, ActiveITs); + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED; + + return HAL_ERROR; + } +} + +/** + * @brief Disable interrupts. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param InactiveITs indicates which interrupts will be disabled. + * This parameter can be any combination of @arg FDCAN_Interrupts. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FDCAN_DeactivateNotification(FDCAN_HandleTypeDef *hfdcan, uint32_t InactiveITs) +{ + HAL_FDCAN_StateTypeDef state = hfdcan->State; + uint32_t ITs_enabled; + uint32_t ITs_lines_selection; + + /* Check function parameters */ + assert_param(IS_FDCAN_IT(InactiveITs)); + + if ((state == HAL_FDCAN_STATE_READY) || (state == HAL_FDCAN_STATE_BUSY)) + { + /* Disable the selected interrupts */ + __HAL_FDCAN_DISABLE_IT(hfdcan, InactiveITs); + + if ((InactiveITs & FDCAN_IT_TX_COMPLETE) != 0U) + { + /* Disable Tx Buffer Transmission Interrupts */ + CLEAR_REG(hfdcan->Instance->TXBTIE); + } + + if ((InactiveITs & FDCAN_IT_TX_ABORT_COMPLETE) != 0U) + { + /* Disable Tx Buffer Cancellation Finished Interrupt */ + CLEAR_REG(hfdcan->Instance->TXBCIE); + } + + /* Get interrupts enabled and interrupts line selection */ + ITs_enabled = hfdcan->Instance->IE; + ITs_lines_selection = hfdcan->Instance->ILS; + + /* Check if some interrupts are still enabled on interrupt line 0 */ + if ((((ITs_enabled & FDCAN_IT_LIST_RX_FIFO0) != 0U) + && (((ITs_lines_selection) & FDCAN_IT_GROUP_RX_FIFO0) == 0U)) || \ + (((ITs_enabled & FDCAN_IT_LIST_RX_FIFO1) != 0U) + && (((ITs_lines_selection) & FDCAN_IT_GROUP_RX_FIFO1) == 0U)) || \ + (((ITs_enabled & FDCAN_IT_LIST_SMSG) != 0U) + && (((ITs_lines_selection) & FDCAN_IT_GROUP_SMSG) == 0U)) || \ + (((ITs_enabled & FDCAN_IT_LIST_TX_FIFO_ERROR) != 0U) + && (((ITs_lines_selection) & FDCAN_IT_GROUP_TX_FIFO_ERROR) == 0U)) || \ + (((ITs_enabled & FDCAN_IT_LIST_MISC) != 0U) + && (((ITs_lines_selection) & FDCAN_IT_GROUP_MISC) == 0U)) || \ + (((ITs_enabled & FDCAN_IT_LIST_BIT_LINE_ERROR) != 0U) + && (((ITs_lines_selection) & FDCAN_IT_GROUP_BIT_LINE_ERROR) == 0U)) || \ + (((ITs_enabled & FDCAN_IT_LIST_PROTOCOL_ERROR) != 0U) + && (((ITs_lines_selection) & FDCAN_IT_GROUP_PROTOCOL_ERROR) == 0U))) + { + /* Do nothing */ + } + else /* no more interrupts enabled on interrupt line 0 */ + { + /* Disable interrupt line 0 */ + CLEAR_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE0); + } + + /* Check if some interrupts are still enabled on interrupt line 1 */ + if ((((ITs_enabled & FDCAN_IT_LIST_RX_FIFO0) != 0U) + && (((ITs_lines_selection) & FDCAN_IT_GROUP_RX_FIFO0) != 0U)) || \ + (((ITs_enabled & FDCAN_IT_LIST_RX_FIFO1) != 0U) + && (((ITs_lines_selection) & FDCAN_IT_GROUP_RX_FIFO1) != 0U)) || \ + (((ITs_enabled & FDCAN_IT_LIST_SMSG) != 0U) + && (((ITs_lines_selection) & FDCAN_IT_GROUP_SMSG) != 0U)) || \ + (((ITs_enabled & FDCAN_IT_LIST_TX_FIFO_ERROR) != 0U) + && (((ITs_lines_selection) & FDCAN_IT_GROUP_TX_FIFO_ERROR) != 0U)) || \ + (((ITs_enabled & FDCAN_IT_LIST_MISC) != 0U) + && (((ITs_lines_selection) & FDCAN_IT_GROUP_MISC) != 0U)) || \ + (((ITs_enabled & FDCAN_IT_LIST_BIT_LINE_ERROR) != 0U) + && (((ITs_lines_selection) & FDCAN_IT_GROUP_BIT_LINE_ERROR) != 0U)) || \ + (((ITs_enabled & FDCAN_IT_LIST_PROTOCOL_ERROR) != 0U) + && (((ITs_lines_selection) & FDCAN_IT_GROUP_PROTOCOL_ERROR) != 0U))) + { + /* Do nothing */ + } + else /* no more interrupts enabled on interrupt line 1 */ + { + /* Disable interrupt line 1 */ + CLEAR_BIT(hfdcan->Instance->ILE, FDCAN_INTERRUPT_LINE1); + } + + /* Return function status */ + return HAL_OK; + } + else + { + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_INITIALIZED; + + return HAL_ERROR; + } +} + +/** + * @brief Handles FDCAN interrupt request. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval HAL status + */ +void HAL_FDCAN_IRQHandler(FDCAN_HandleTypeDef *hfdcan) +{ + uint32_t TxEventFifoITs; + uint32_t RxFifo0ITs; + uint32_t RxFifo1ITs; + uint32_t Errors; + uint32_t ErrorStatusITs; + uint32_t TransmittedBuffers; + uint32_t AbortedBuffers; + uint32_t itsource; + uint32_t itflag; + + TxEventFifoITs = hfdcan->Instance->IR & FDCAN_TX_EVENT_FIFO_MASK; + TxEventFifoITs &= hfdcan->Instance->IE; + RxFifo0ITs = hfdcan->Instance->IR & FDCAN_RX_FIFO0_MASK; + RxFifo0ITs &= hfdcan->Instance->IE; + RxFifo1ITs = hfdcan->Instance->IR & FDCAN_RX_FIFO1_MASK; + RxFifo1ITs &= hfdcan->Instance->IE; + Errors = hfdcan->Instance->IR & FDCAN_ERROR_MASK; + Errors &= hfdcan->Instance->IE; + ErrorStatusITs = hfdcan->Instance->IR & FDCAN_ERROR_STATUS_MASK; + ErrorStatusITs &= hfdcan->Instance->IE; + itsource = hfdcan->Instance->IE; + itflag = hfdcan->Instance->IR; + + /* High Priority Message interrupt management *******************************/ + if (FDCAN_CHECK_FLAG(itflag, FDCAN_FLAG_RX_HIGH_PRIORITY_MSG) != RESET) + { + if (FDCAN_CHECK_IT_SOURCE(itsource, FDCAN_IT_RX_HIGH_PRIORITY_MSG) != RESET) + { + /* Clear the High Priority Message flag */ + __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_RX_HIGH_PRIORITY_MSG); + +#if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1 + /* Call registered callback*/ + hfdcan->HighPriorityMessageCallback(hfdcan); +#else + /* High Priority Message Callback */ + HAL_FDCAN_HighPriorityMessageCallback(hfdcan); +#endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */ + } + } + + /* Transmission Abort interrupt management **********************************/ + if (FDCAN_CHECK_FLAG(itflag, FDCAN_FLAG_TX_ABORT_COMPLETE) != RESET) + { + if (FDCAN_CHECK_IT_SOURCE(itsource, FDCAN_IT_TX_ABORT_COMPLETE) != RESET) + { + /* List of aborted monitored buffers */ + AbortedBuffers = hfdcan->Instance->TXBCF; + AbortedBuffers &= hfdcan->Instance->TXBCIE; + + /* Clear the Transmission Cancellation flag */ + __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_TX_ABORT_COMPLETE); + +#if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1 + /* Call registered callback*/ + hfdcan->TxBufferAbortCallback(hfdcan, AbortedBuffers); +#else + /* Transmission Cancellation Callback */ + HAL_FDCAN_TxBufferAbortCallback(hfdcan, AbortedBuffers); +#endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */ + } + } + + /* Tx event FIFO interrupts management **************************************/ + if (TxEventFifoITs != 0U) + { + /* Clear the Tx Event FIFO flags */ + __HAL_FDCAN_CLEAR_FLAG(hfdcan, TxEventFifoITs); + +#if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1 + /* Call registered callback*/ + hfdcan->TxEventFifoCallback(hfdcan, TxEventFifoITs); +#else + /* Tx Event FIFO Callback */ + HAL_FDCAN_TxEventFifoCallback(hfdcan, TxEventFifoITs); +#endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */ + } + + /* Rx FIFO 0 interrupts management ******************************************/ + if (RxFifo0ITs != 0U) + { + /* Clear the Rx FIFO 0 flags */ + __HAL_FDCAN_CLEAR_FLAG(hfdcan, RxFifo0ITs); + +#if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1 + /* Call registered callback*/ + hfdcan->RxFifo0Callback(hfdcan, RxFifo0ITs); +#else + /* Rx FIFO 0 Callback */ + HAL_FDCAN_RxFifo0Callback(hfdcan, RxFifo0ITs); +#endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */ + } + + /* Rx FIFO 1 interrupts management ******************************************/ + if (RxFifo1ITs != 0U) + { + /* Clear the Rx FIFO 1 flags */ + __HAL_FDCAN_CLEAR_FLAG(hfdcan, RxFifo1ITs); + +#if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1 + /* Call registered callback*/ + hfdcan->RxFifo1Callback(hfdcan, RxFifo1ITs); +#else + /* Rx FIFO 1 Callback */ + HAL_FDCAN_RxFifo1Callback(hfdcan, RxFifo1ITs); +#endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */ + } + + /* Tx FIFO empty interrupt management ***************************************/ + if (FDCAN_CHECK_FLAG(itflag, FDCAN_FLAG_TX_FIFO_EMPTY) != RESET) + { + if (FDCAN_CHECK_IT_SOURCE(itsource, FDCAN_IT_TX_FIFO_EMPTY) != RESET) + { + /* Clear the Tx FIFO empty flag */ + __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_TX_FIFO_EMPTY); + +#if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1 + /* Call registered callback*/ + hfdcan->TxFifoEmptyCallback(hfdcan); +#else + /* Tx FIFO empty Callback */ + HAL_FDCAN_TxFifoEmptyCallback(hfdcan); +#endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */ + } + } + + /* Transmission Complete interrupt management *******************************/ + if (FDCAN_CHECK_FLAG(itflag, FDCAN_FLAG_TX_COMPLETE) != RESET) + { + if (FDCAN_CHECK_IT_SOURCE(itsource, FDCAN_IT_TX_COMPLETE) != RESET) + { + /* List of transmitted monitored buffers */ + TransmittedBuffers = hfdcan->Instance->TXBTO; + TransmittedBuffers &= hfdcan->Instance->TXBTIE; + + /* Clear the Transmission Complete flag */ + __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_TX_COMPLETE); + +#if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1 + /* Call registered callback*/ + hfdcan->TxBufferCompleteCallback(hfdcan, TransmittedBuffers); +#else + /* Transmission Complete Callback */ + HAL_FDCAN_TxBufferCompleteCallback(hfdcan, TransmittedBuffers); +#endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */ + } + } + + /* Timestamp Wraparound interrupt management ********************************/ + if (FDCAN_CHECK_FLAG(itflag, FDCAN_FLAG_TIMESTAMP_WRAPAROUND) != RESET) + { + if (FDCAN_CHECK_IT_SOURCE(itsource, FDCAN_IT_TIMESTAMP_WRAPAROUND) != RESET) + { + /* Clear the Timestamp Wraparound flag */ + __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_TIMESTAMP_WRAPAROUND); + +#if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1 + /* Call registered callback*/ + hfdcan->TimestampWraparoundCallback(hfdcan); +#else + /* Timestamp Wraparound Callback */ + HAL_FDCAN_TimestampWraparoundCallback(hfdcan); +#endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */ + } + } + + /* Timeout Occurred interrupt management ************************************/ + if (FDCAN_CHECK_FLAG(itflag, FDCAN_FLAG_TIMEOUT_OCCURRED) != RESET) + { + if (FDCAN_CHECK_IT_SOURCE(itsource, FDCAN_IT_TIMEOUT_OCCURRED) != RESET) + { + /* Clear the Timeout Occurred flag */ + __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_TIMEOUT_OCCURRED); + +#if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1 + /* Call registered callback*/ + hfdcan->TimeoutOccurredCallback(hfdcan); +#else + /* Timeout Occurred Callback */ + HAL_FDCAN_TimeoutOccurredCallback(hfdcan); +#endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */ + } + } + + /* Message RAM access failure interrupt management **************************/ + if (FDCAN_CHECK_FLAG(itflag, FDCAN_FLAG_RAM_ACCESS_FAILURE) != RESET) + { + if (FDCAN_CHECK_IT_SOURCE(itsource, FDCAN_IT_RAM_ACCESS_FAILURE) != RESET) + { + /* Clear the Message RAM access failure flag */ + __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_RAM_ACCESS_FAILURE); + + /* Update error code */ + hfdcan->ErrorCode |= HAL_FDCAN_ERROR_RAM_ACCESS; + } + } + + /* Error Status interrupts management ***************************************/ + if (ErrorStatusITs != 0U) + { + /* Clear the Error flags */ + __HAL_FDCAN_CLEAR_FLAG(hfdcan, ErrorStatusITs); + +#if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1 + /* Call registered callback*/ + hfdcan->ErrorStatusCallback(hfdcan, ErrorStatusITs); +#else + /* Error Status Callback */ + HAL_FDCAN_ErrorStatusCallback(hfdcan, ErrorStatusITs); +#endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */ + } + + /* Error interrupts management **********************************************/ + if (Errors != 0U) + { + /* Clear the Error flags */ + __HAL_FDCAN_CLEAR_FLAG(hfdcan, Errors); + + /* Update error code */ + hfdcan->ErrorCode |= Errors; + } + + if (hfdcan->ErrorCode != HAL_FDCAN_ERROR_NONE) + { +#if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1 + /* Call registered callback*/ + hfdcan->ErrorCallback(hfdcan); +#else + /* Error Callback */ + HAL_FDCAN_ErrorCallback(hfdcan); +#endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */ + } +} + +/** + * @} + */ + +/** @defgroup FDCAN_Exported_Functions_Group5 Callback functions + * @brief FDCAN Callback functions + * +@verbatim + ============================================================================== + ##### Callback functions ##### + ============================================================================== + [..] + This subsection provides the following callback functions: + (+) HAL_FDCAN_TxEventFifoCallback + (+) HAL_FDCAN_RxFifo0Callback + (+) HAL_FDCAN_RxFifo1Callback + (+) HAL_FDCAN_TxFifoEmptyCallback + (+) HAL_FDCAN_TxBufferCompleteCallback + (+) HAL_FDCAN_TxBufferAbortCallback + (+) HAL_FDCAN_HighPriorityMessageCallback + (+) HAL_FDCAN_TimestampWraparoundCallback + (+) HAL_FDCAN_TimeoutOccurredCallback + (+) HAL_FDCAN_ErrorCallback + (+) HAL_FDCAN_ErrorStatusCallback + +@endverbatim + * @{ + */ + +/** + * @brief Tx Event callback. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param TxEventFifoITs indicates which Tx Event FIFO interrupts are signaled. + * This parameter can be any combination of @arg FDCAN_Tx_Event_Fifo_Interrupts. + * @retval None + */ +__weak void HAL_FDCAN_TxEventFifoCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t TxEventFifoITs) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hfdcan); + UNUSED(TxEventFifoITs); + + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_FDCAN_TxEventFifoCallback could be implemented in the user file + */ +} + +/** + * @brief Rx FIFO 0 callback. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param RxFifo0ITs indicates which Rx FIFO 0 interrupts are signaled. + * This parameter can be any combination of @arg FDCAN_Rx_Fifo0_Interrupts. + * @retval None + */ +__weak void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hfdcan); + UNUSED(RxFifo0ITs); + + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_FDCAN_RxFifo0Callback could be implemented in the user file + */ +} + +/** + * @brief Rx FIFO 1 callback. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param RxFifo1ITs indicates which Rx FIFO 1 interrupts are signaled. + * This parameter can be any combination of @arg FDCAN_Rx_Fifo1_Interrupts. + * @retval None + */ +__weak void HAL_FDCAN_RxFifo1Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo1ITs) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hfdcan); + UNUSED(RxFifo1ITs); + + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_FDCAN_RxFifo1Callback could be implemented in the user file + */ +} + +/** + * @brief Tx FIFO Empty callback. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval None + */ +__weak void HAL_FDCAN_TxFifoEmptyCallback(FDCAN_HandleTypeDef *hfdcan) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hfdcan); + + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_FDCAN_TxFifoEmptyCallback could be implemented in the user file + */ +} + +/** + * @brief Transmission Complete callback. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param BufferIndexes Indexes of the transmitted buffers. + * This parameter can be any combination of @arg FDCAN_Tx_location. + * @retval None + */ +__weak void HAL_FDCAN_TxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hfdcan); + UNUSED(BufferIndexes); + + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_FDCAN_TxBufferCompleteCallback could be implemented in the user file + */ +} + +/** + * @brief Transmission Cancellation callback. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param BufferIndexes Indexes of the aborted buffers. + * This parameter can be any combination of @arg FDCAN_Tx_location. + * @retval None + */ +__weak void HAL_FDCAN_TxBufferAbortCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hfdcan); + UNUSED(BufferIndexes); + + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_FDCAN_TxBufferAbortCallback could be implemented in the user file + */ +} + +/** + * @brief Timestamp Wraparound callback. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval None + */ +__weak void HAL_FDCAN_TimestampWraparoundCallback(FDCAN_HandleTypeDef *hfdcan) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hfdcan); + + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_FDCAN_TimestampWraparoundCallback could be implemented in the user file + */ +} + +/** + * @brief Timeout Occurred callback. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval None + */ +__weak void HAL_FDCAN_TimeoutOccurredCallback(FDCAN_HandleTypeDef *hfdcan) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hfdcan); + + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_FDCAN_TimeoutOccurredCallback could be implemented in the user file + */ +} + +/** + * @brief High Priority Message callback. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval None + */ +__weak void HAL_FDCAN_HighPriorityMessageCallback(FDCAN_HandleTypeDef *hfdcan) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hfdcan); + + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_FDCAN_HighPriorityMessageCallback could be implemented in the user file + */ +} + +/** + * @brief Error callback. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval None + */ +__weak void HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef *hfdcan) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hfdcan); + + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_FDCAN_ErrorCallback could be implemented in the user file + */ +} + +/** + * @brief Error status callback. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param ErrorStatusITs indicates which Error Status interrupts are signaled. + * This parameter can be any combination of @arg FDCAN_Error_Status_Interrupts. + * @retval None + */ +__weak void HAL_FDCAN_ErrorStatusCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t ErrorStatusITs) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hfdcan); + UNUSED(ErrorStatusITs); + + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_FDCAN_ErrorStatusCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup FDCAN_Exported_Functions_Group6 Peripheral State functions + * @brief FDCAN Peripheral State functions + * +@verbatim + ============================================================================== + ##### Peripheral State functions ##### + ============================================================================== + [..] + This subsection provides functions allowing to : + (+) HAL_FDCAN_GetState() : Return the FDCAN state. + (+) HAL_FDCAN_GetError() : Return the FDCAN error code if any. + +@endverbatim + * @{ + */ +/** + * @brief Return the FDCAN state + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval HAL state + */ +HAL_FDCAN_StateTypeDef HAL_FDCAN_GetState(const FDCAN_HandleTypeDef *hfdcan) +{ + /* Return FDCAN state */ + return hfdcan->State; +} + +/** + * @brief Return the FDCAN error code + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval FDCAN Error Code + */ +uint32_t HAL_FDCAN_GetError(const FDCAN_HandleTypeDef *hfdcan) +{ + /* Return FDCAN error code */ + return hfdcan->ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup FDCAN_Private_Functions FDCAN Private Functions + * @{ + */ + +/** + * @brief Calculate each RAM block start address and size + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @retval none + */ +static void FDCAN_CalcultateRamBlockAddresses(FDCAN_HandleTypeDef *hfdcan) +{ + uint32_t RAMcounter; + uint32_t SramCanInstanceBase = SRAMCAN_BASE; +#if defined(FDCAN2) + + if (hfdcan->Instance == FDCAN2) + { + SramCanInstanceBase += SRAMCAN_SIZE; + } +#endif /* FDCAN2 */ + + /* Standard filter list start address */ + hfdcan->msgRam.StandardFilterSA = SramCanInstanceBase + SRAMCAN_FLSSA; + + /* Standard filter elements number */ + MODIFY_REG(hfdcan->Instance->RXGFC, FDCAN_RXGFC_LSS, (hfdcan->Init.StdFiltersNbr << FDCAN_RXGFC_LSS_Pos)); + + /* Extended filter list start address */ + hfdcan->msgRam.ExtendedFilterSA = SramCanInstanceBase + SRAMCAN_FLESA; + + /* Extended filter elements number */ + MODIFY_REG(hfdcan->Instance->RXGFC, FDCAN_RXGFC_LSE, (hfdcan->Init.ExtFiltersNbr << FDCAN_RXGFC_LSE_Pos)); + + /* Rx FIFO 0 start address */ + hfdcan->msgRam.RxFIFO0SA = SramCanInstanceBase + SRAMCAN_RF0SA; + + /* Rx FIFO 1 start address */ + hfdcan->msgRam.RxFIFO1SA = SramCanInstanceBase + SRAMCAN_RF1SA; + + /* Tx event FIFO start address */ + hfdcan->msgRam.TxEventFIFOSA = SramCanInstanceBase + SRAMCAN_TEFSA; + + /* Tx FIFO/queue start address */ + hfdcan->msgRam.TxFIFOQSA = SramCanInstanceBase + SRAMCAN_TFQSA; + + /* Flush the allocated Message RAM area */ + for (RAMcounter = SramCanInstanceBase; RAMcounter < (SramCanInstanceBase + SRAMCAN_SIZE); RAMcounter += 4U) + { + *(uint32_t *)(RAMcounter) = 0x00000000U; + } +} + +/** + * @brief Copy Tx message to the message RAM. + * @param hfdcan pointer to an FDCAN_HandleTypeDef structure that contains + * the configuration information for the specified FDCAN. + * @param pTxHeader pointer to a FDCAN_TxHeaderTypeDef structure. + * @param pTxData pointer to a buffer containing the payload of the Tx frame. + * @param BufferIndex index of the buffer to be configured. + * @retval none + */ +static void FDCAN_CopyMessageToRAM(FDCAN_HandleTypeDef *hfdcan, const FDCAN_TxHeaderTypeDef *pTxHeader, + const uint8_t *pTxData, uint32_t BufferIndex) +{ + uint32_t TxElementW1; + uint32_t TxElementW2; + uint32_t *TxAddress; + uint32_t ByteCounter; + + /* Build first word of Tx header element */ + if (pTxHeader->IdType == FDCAN_STANDARD_ID) + { + TxElementW1 = (pTxHeader->ErrorStateIndicator | + FDCAN_STANDARD_ID | + pTxHeader->TxFrameType | + (pTxHeader->Identifier << 18U)); + } + else /* pTxHeader->IdType == FDCAN_EXTENDED_ID */ + { + TxElementW1 = (pTxHeader->ErrorStateIndicator | + FDCAN_EXTENDED_ID | + pTxHeader->TxFrameType | + pTxHeader->Identifier); + } + + /* Build second word of Tx header element */ + TxElementW2 = ((pTxHeader->MessageMarker << 24U) | + pTxHeader->TxEventFifoControl | + pTxHeader->FDFormat | + pTxHeader->BitRateSwitch | + (pTxHeader->DataLength << 16U)); + + /* Calculate Tx element address */ + TxAddress = (uint32_t *)(hfdcan->msgRam.TxFIFOQSA + (BufferIndex * SRAMCAN_TFQ_SIZE)); + + /* Write Tx element header to the message RAM */ + *TxAddress = TxElementW1; + TxAddress++; + *TxAddress = TxElementW2; + TxAddress++; + + /* Write Tx payload to the message RAM */ + for (ByteCounter = 0; ByteCounter < DLCtoBytes[pTxHeader->DataLength]; ByteCounter += 4U) + { + *TxAddress = (((uint32_t)pTxData[ByteCounter + 3U] << 24U) | + ((uint32_t)pTxData[ByteCounter + 2U] << 16U) | + ((uint32_t)pTxData[ByteCounter + 1U] << 8U) | + (uint32_t)pTxData[ByteCounter]); + TxAddress++; + } +} + +/** + * @} + */ +#endif /* HAL_FDCAN_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +#endif /* FDCAN1 */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_flash.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_flash.c new file mode 100644 index 0000000000..f656b915fb --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_flash.c @@ -0,0 +1,919 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_flash.c + * @author MCD Application Team + * @brief FLASH HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the internal FLASH memory: + * + Program operations functions + * + Memory Control functions + * + Peripheral Errors functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### FLASH peripheral features ##### + ============================================================================== + + [..] The Flash memory interface manages CPU AHB C-Bus accesses to the Flash memory. + It implements the erase and program Flash memory operations and the read + and write protection mechanisms. + + [..] The FLASH main features are: + (+) Flash memory read operations + (+) Flash memory program/erase operations + (+) Read / write protections + (+) Option bytes programming + (+) TrustZone aware + (+) Watermark-based area protection + (+) Block-based sector protection + (+) Error code correction (ECC) + + + ##### How to use this driver ##### + ============================================================================== + [..] + This driver provides functions and macros to configure and program the FLASH + memory of all STM32H5xx devices. + + (#) FLASH Memory IO Programming functions: + (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and + HAL_FLASH_Lock() functions + (++) Flash memory programming by 128 bits (user area, OBKeys) and 16 bits (OTP and Flash high-cycle + data area) + (++) There Two modes of programming : + (+++) Polling mode using HAL_FLASH_Program() function + (+++) Interrupt mode using HAL_FLASH_Program_IT() function + + (#) Interrupts and flags management functions : + (++) Handle FLASH interrupts by calling HAL_FLASH_IRQHandler() + (++) Callback functions are called when the flash operations are finished : + HAL_FLASH_EndOfOperationCallback() when everything is ok, otherwise + HAL_FLASH_OperationErrorCallback() + (++) Get error flag status by calling HAL_FLASH_GetError() + + (#) Option bytes management functions : + (++) Lock and Unlock the option bytes using HAL_FLASH_OB_Unlock() and + HAL_FLASH_OB_Lock() functions + (++) Launch the reload of the option bytes using HAL_FLASH_OB_Launch() function. + In this case, a reset is generated + [..] + In addition to these functions, this driver includes a set of macros allowing + to handle the following operations: + (+) Set the latency + (+) Enable/Disable the FLASH interrupts + (+) Monitor the FLASH flags status + [..] + (@) The contents of the Flash memory are not guaranteed if a device reset occurs during + a Flash memory operation. + + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup FLASH FLASH + * @brief FLASH HAL module driver + * @{ + */ + +#ifdef HAL_FLASH_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/** @defgroup FLASH_Private_Variables FLASH Private Variables + * @{ + */ +/** + * @brief Variable used for Program/Erase sectors under interruption + */ +FLASH_ProcessTypeDef pFlash = {.Lock = HAL_UNLOCKED, \ + .ErrorCode = HAL_FLASH_ERROR_NONE, \ + .ProcedureOnGoing = 0U, \ + .Address = 0U, \ + .Bank = FLASH_BANK_1, \ + .Sector = 0U, \ + .NbSectorsToErase = 0U + }; +/** + * @} + */ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup FLASH_Private_Functions FLASH Private Functions + * @{ + */ +static void FLASH_Program_QuadWord(uint32_t FlashAddress, uint32_t DataAddress); +#if defined (FLASH_SR_OBKERR) +static void FLASH_Program_QuadWord_OBK(uint32_t FlashAddress, uint32_t DataAddress); +#endif /* FLASH_SR_OBKERR */ +static void FLASH_Program_HalfWord(uint32_t FlashAddress, uint32_t DataAddress); + +/** + * @} + */ +/* Exported functions ---------------------------------------------------------*/ + +/** @defgroup FLASH_Exported_Functions FLASH Exported functions + * @{ + */ + +/** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions + * @brief Programming operation functions + * +@verbatim + =============================================================================== + ##### Programming operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the FLASH + program operations. + +@endverbatim + * @{ + */ + +/** + * @brief Program a quad-word at a specified address. + * @param TypeProgram Indicate the way to program at a specified address. + * This parameter can be a value of @ref FLASH_Type_Program + * @param FlashAddress specifies the address to be programmed. + * This parameter shall be aligned to the Flash word (128-bit) + * @param DataAddress specifies the address of data to be programmed + * This parameter shall be 32-bit aligned + * @retval HAL_StatusTypeDef HAL Status + */ +HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress) +{ + HAL_StatusTypeDef status; + __IO uint32_t *reg_cr; +#if defined (FLASH_SR_OBKERR) + __IO uint32_t *reg_obkcfgr; +#endif /* FLASH_SR_OBKERR */ + + /* Check the parameters */ + assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram)); + + /* Process Locked */ + __HAL_LOCK(&pFlash); + + /* Reset error code */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + + if (status == HAL_OK) + { + /* Set current operation type */ + pFlash.ProcedureOnGoing = TypeProgram; + + /* Access to SECCR or NSCR depends on operation type */ +#if defined (FLASH_OPTSR2_TZEN) + reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR); +#else + reg_cr = &(FLASH_NS->NSCR); +#endif /* FLASH_OPTSR2_TZEN */ + + if ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_QUADWORD) + { + /* Check the parameters */ + assert_param(IS_FLASH_USER_MEM_ADDRESS(FlashAddress)); + + /* Program a quad-word (128-bit) at a specified address */ + FLASH_Program_QuadWord(FlashAddress, DataAddress); + } +#if defined (FLASH_SR_OBKERR) + else if ((TypeProgram == FLASH_TYPEPROGRAM_QUADWORD_OBK) || (TypeProgram == FLASH_TYPEPROGRAM_QUADWORD_OBK_ALT)) + { + /* Check the parameters */ + assert_param(IS_FLASH_OBK_ADDRESS(FlashAddress)); + + /* Program a quad-word (128-bit) of OBK at a specified address */ + FLASH_Program_QuadWord_OBK(FlashAddress, DataAddress); + } +#endif /* FLASH_SR_OBKERR */ +#if defined (FLASH_EDATAR_EDATA_EN) + else if ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_HALFWORD_EDATA) + { + /* Check the parameters */ + assert_param(IS_FLASH_EDATA_ADDRESS(FlashAddress)); + + /* Program a Flash high-cycle data half-word at a specified address */ + FLASH_Program_HalfWord(FlashAddress, DataAddress); + } +#endif /* FLASH_EDATAR_EDATA_EN */ + else + { + /* Check the parameters */ + assert_param(IS_FLASH_OTP_ADDRESS(FlashAddress)); + + /* Program an OTP half-word at a specified address */ + FLASH_Program_HalfWord(FlashAddress, DataAddress); + } + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + +#if defined (FLASH_SR_OBKERR) + /* If the program operation is completed, disable the PG */ + CLEAR_BIT((*reg_cr), (TypeProgram & ~(FLASH_NON_SECURE_MASK | FLASH_OBK | FLASH_OTP | FLASH_OBKCFGR_ALT_SECT))); + + /* Clear alternate sector bit */ + if (TypeProgram == FLASH_TYPEPROGRAM_QUADWORD_OBK_ALT) + { + reg_obkcfgr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECOBKCFGR) : &(FLASH_NS->NSOBKCFGR); + CLEAR_BIT((*reg_obkcfgr), FLASH_OBKCFGR_ALT_SECT); + } +#else + /* If the program operation is completed, disable the PG */ + CLEAR_BIT((*reg_cr), (TypeProgram & ~(FLASH_NON_SECURE_MASK | FLASH_OTP))); +#endif /* FLASH_SR_OBKERR */ + } + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + + /* return status */ + return status; +} + +/** + * @brief Program a quad-word at a specified address with interrupt enabled. + * @param TypeProgram Indicate the way to program at a specified address. + * This parameter can be a value of @ref FLASH_Type_Program + * @param FlashAddress specifies the address to be programmed. + * This parameter shall be aligned to the Flash word (128-bit) + * @param DataAddress specifies the address of data to be programmed + * This parameter shall be 32-bit aligned + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress) +{ + HAL_StatusTypeDef status; + __IO uint32_t *reg_cr; + + /* Check the parameters */ + assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram)); + + /* Process Locked */ + __HAL_LOCK(&pFlash); + + /* Reset error code */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + + if (status != HAL_OK) + { + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + } + else + { + /* Set internal variables used by the IRQ handler */ + pFlash.ProcedureOnGoing = TypeProgram; + pFlash.Address = FlashAddress; + + /* Access to SECCR or NSCR depends on operation type */ +#if defined (FLASH_OPTSR2_TZEN) + reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR); +#else + reg_cr = &(FLASH_NS->NSCR); +#endif /* FLASH_OPTSR2_TZEN */ + + /* Enable End of Operation and Error interrupts */ +#if defined (FLASH_SR_OBKERR) + (*reg_cr) |= (FLASH_IT_EOP | FLASH_IT_WRPERR | FLASH_IT_PGSERR | \ + FLASH_IT_STRBERR | FLASH_IT_INCERR | FLASH_IT_OBKERR | \ + FLASH_IT_OBKWERR); +#else + (*reg_cr) |= (FLASH_IT_EOP | FLASH_IT_WRPERR | FLASH_IT_PGSERR | \ + FLASH_IT_STRBERR | FLASH_IT_INCERR); +#endif /* FLASH_SR_OBKERR */ + + if ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_QUADWORD) + { + /* Check the parameters */ + assert_param(IS_FLASH_USER_MEM_ADDRESS(FlashAddress)); + + /* Program a quad-word (128-bit) at a specified address */ + FLASH_Program_QuadWord(FlashAddress, DataAddress); + } +#if defined (FLASH_SR_OBKERR) + else if (((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_QUADWORD_OBK) || \ + ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_QUADWORD_OBK_ALT)) + { + /* Check the parameters */ + assert_param(IS_FLASH_OBK_ADDRESS(FlashAddress)); + + /* Program a quad-word (128-bit) of OBK at a specified address */ + FLASH_Program_QuadWord_OBK(FlashAddress, DataAddress); + } +#endif /* FLASH_SR_OBKERR */ +#if defined (FLASH_EDATAR_EDATA_EN) + else if ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_HALFWORD_EDATA) + { + /* Check the parameters */ + assert_param(IS_FLASH_EDATA_ADDRESS(FlashAddress)); + + /* Program a Flash high-cycle data half-word at a specified address */ + FLASH_Program_HalfWord(FlashAddress, DataAddress); + } +#endif /* FLASH_EDATAR_EDATA_EN */ + else + { + /* Check the parameters */ + assert_param(IS_FLASH_OTP_ADDRESS(FlashAddress)); + + /* Program an OTP word at a specified address */ + FLASH_Program_HalfWord(FlashAddress, DataAddress); + } + } + + /* return status */ + return status; +} + +/** + * @brief This function handles FLASH interrupt request. + * @retval None + */ +void HAL_FLASH_IRQHandler(void) +{ + uint32_t param = 0U; + uint32_t errorflag; + __IO uint32_t *reg_cr; + __IO uint32_t *reg_ccr; + const __IO uint32_t *reg_sr; + + /* Access to CR, CCR and SR registers depends on operation type */ +#if defined (FLASH_OPTSR2_TZEN) + reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR); + reg_ccr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCCR) : &(FLASH_NS->NSCCR); + reg_sr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECSR) : &(FLASH_NS->NSSR); +#else + reg_cr = &(FLASH_NS->NSCR); + reg_ccr = &(FLASH_NS->NSCCR); + reg_sr = &(FLASH_NS->NSSR); +#endif /* FLASH_OPTSR2_TZEN */ + + /* Save Flash errors */ + errorflag = (*reg_sr) & FLASH_FLAG_SR_ERRORS; + /* Add option byte error flag, if any */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + errorflag |= (FLASH->NSSR & FLASH_FLAG_OPTCHANGEERR); +#endif /* __ARM_FEATURE_CMSE */ + + /* Set parameter of the callback */ + if ((pFlash.ProcedureOnGoing & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEERASE_SECTORS) + { + param = pFlash.Sector; + } + else if ((pFlash.ProcedureOnGoing & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEERASE_MASSERASE) + { + param = pFlash.Bank; + } + else if ((pFlash.ProcedureOnGoing & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_QUADWORD) + { + param = pFlash.Address; + } + else + { + /* Empty statement (to be compliant MISRA 15.7) */ + } + + /* Clear operation bit on the on-going procedure */ + CLEAR_BIT((*reg_cr), (pFlash.ProcedureOnGoing & ~(FLASH_NON_SECURE_MASK))); + + /* Check FLASH operation error flags */ + if (errorflag != 0U) + { + /* Save the error code */ + pFlash.ErrorCode |= errorflag; + + /* Clear error programming flags */ + (*reg_ccr) = errorflag & FLASH_FLAG_SR_ERRORS; +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + if ((errorflag & FLASH_FLAG_OPTCHANGEERR) != 0U) + { + FLASH->NSCCR = FLASH_FLAG_OPTCHANGEERR; + } +#endif /* __ARM_FEATURE_CMSE */ + + /* Stop the procedure ongoing */ + pFlash.ProcedureOnGoing = 0U; + + /* FLASH error interrupt user callback */ + HAL_FLASH_OperationErrorCallback(param); + } + + /* Check FLASH End of Operation flag */ + if (((*reg_sr) & FLASH_FLAG_EOP) != 0U) + { + /* Clear FLASH End of Operation pending bit */ + (*reg_ccr) = FLASH_FLAG_EOP; + + if ((pFlash.ProcedureOnGoing & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEERASE_SECTORS) + { + /* Nb of sector to erased can be decreased */ + pFlash.NbSectorsToErase--; + + /* Check if there are still sectors to erase */ + if (pFlash.NbSectorsToErase != 0U) + { + /* Increment sector number */ + pFlash.Sector++; + FLASH_Erase_Sector(pFlash.Sector, pFlash.Bank); + } + else + { + /* No more sectors to erase */ + /* Reset sector parameter and stop erase sectors procedure */ + param = 0xFFFFFFFFU; + pFlash.ProcedureOnGoing = 0U; + } + } + else + { + /* Clear the procedure ongoing */ + pFlash.ProcedureOnGoing = 0U; + } + + /* FLASH EOP interrupt user callback */ + HAL_FLASH_EndOfOperationCallback(param); + } + + if (pFlash.ProcedureOnGoing == 0U) + { + /* Disable Flash Operation and Error source interrupt */ +#if defined (FLASH_SR_OBKERR) + (*reg_cr) &= ~(FLASH_IT_EOP | FLASH_IT_WRPERR | FLASH_IT_PGSERR | \ + FLASH_IT_STRBERR | FLASH_IT_INCERR | FLASH_IT_OBKERR | \ + FLASH_IT_OBKWERR | FLASH_IT_OPTCHANGEERR); +#else + (*reg_cr) &= ~(FLASH_IT_EOP | FLASH_IT_WRPERR | FLASH_IT_PGSERR | \ + FLASH_IT_STRBERR | FLASH_IT_INCERR | FLASH_IT_OPTCHANGEERR); +#endif /* FLASH_SR_OBKERR */ + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + } +} + +/** + * @brief FLASH end of operation interrupt callback + * @param ReturnValue The value saved in this parameter depends on the ongoing procedure + * Mass Erase: Bank number which has been requested to erase + * Sectors Erase: Sector which has been erased + * (if 0xFFFFFFFF, it means that all the selected sectors have been erased) + * Program: Address which was selected for data program + * @retval None + */ +__weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(ReturnValue); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_FLASH_EndOfOperationCallback could be implemented in the user file + */ +} + +/** + * @brief FLASH operation error interrupt callback + * @param ReturnValue The value saved in this parameter depends on the ongoing procedure + * Mass Erase: Bank number which has been requested to erase + * Sectors Erase: Sector number which returned an error + * Program: Address which was selected for data program + * @retval None + */ +__weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(ReturnValue); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_FLASH_OperationErrorCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions + * @brief Management functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the FLASH + memory operations. + +@endverbatim + * @{ + */ + +/** + * @brief Unlock the FLASH control registers access + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASH_Unlock(void) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (READ_BIT(FLASH->NSCR, FLASH_CR_LOCK) != 0U) + { + /* Authorize the FLASH Control Register access */ + WRITE_REG(FLASH->NSKEYR, FLASH_KEY1); + WRITE_REG(FLASH->NSKEYR, FLASH_KEY2); + + /* Verify Flash CR is unlocked */ + if (READ_BIT(FLASH->NSCR, FLASH_CR_LOCK) != 0U) + { + status = HAL_ERROR; + } + } + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + if (status == HAL_OK) + { + if (READ_BIT(FLASH->SECCR, FLASH_CR_LOCK) != 0U) + { + /* Authorize the FLASH Control Register access */ + WRITE_REG(FLASH->SECKEYR, FLASH_KEY1); + WRITE_REG(FLASH->SECKEYR, FLASH_KEY2); + + /* verify Flash CR is unlocked */ + if (READ_BIT(FLASH->SECCR, FLASH_CR_LOCK) != 0U) + { + status = HAL_ERROR; + } + } + } +#endif /* __ARM_FEATURE_CMSE */ + + return status; +} + +/** + * @brief Locks the FLASH control registers access + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASH_Lock(void) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Set the LOCK Bit to lock the FLASH Control Register access */ + SET_BIT(FLASH->NSCR, FLASH_CR_LOCK); + + /* Verify Flash is locked */ + if (READ_BIT(FLASH->NSCR, FLASH_CR_LOCK) == 0U) + { + status = HAL_ERROR; + } + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + if (status == HAL_OK) + { + /* Set the LOCK Bit to lock the FLASH Control Register access */ + SET_BIT(FLASH->SECCR, FLASH_CR_LOCK); + + /* verify Flash is locked */ + if (READ_BIT(FLASH->SECCR, FLASH_CR_LOCK) == 0U) + { + status = HAL_ERROR; + } + } +#endif /* __ARM_FEATURE_CMSE */ + + return status; +} + +/** + * @brief Unlock the FLASH Option Control Registers access. + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void) +{ + if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) != 0U) + { + /* Authorizes the Option Byte registers programming */ + WRITE_REG(FLASH->OPTKEYR, FLASH_OPT_KEY1); + WRITE_REG(FLASH->OPTKEYR, FLASH_OPT_KEY2); + + /* Verify that the Option Bytes are unlocked */ + if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) != 0U) + { + return HAL_ERROR; + } + } + + return HAL_OK; +} + +/** + * @brief Lock the FLASH Option Control Registers access. + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASH_OB_Lock(void) +{ + /* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */ + SET_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK); + + /* Verify that the Option Bytes are locked */ + if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) != 0U) + { + return HAL_OK; + } + + return HAL_ERROR; +} + +/** + * @brief Launch the option bytes loading. + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASH_OB_Launch(void) +{ + HAL_StatusTypeDef status; + + /* Set OPTSTRT Bit */ + SET_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTSTART); + + /* Wait for OB change operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + + return status; +} + +/** + * @} + */ + +/** @defgroup FLASH_Exported_Functions_Group3 Peripheral State and Errors functions + * @brief Peripheral Errors functions + * +@verbatim + =============================================================================== + ##### Peripheral Errors functions ##### + =============================================================================== + [..] + This subsection permits to get in run-time Errors of the FLASH peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Get the specific FLASH error flag. + * @retval HAL_FLASH_ERRORCode The returned value can be: + * @arg HAL_FLASH_ERROR_NONE : No error set + * @arg HAL_FLASH_ERROR_WRP : Write Protection Error + * @arg HAL_FLASH_ERROR_PGS : Program Sequence Error + * @arg HAL_FLASH_ERROR_STRB : Strobe Error + * @arg HAL_FLASH_ERROR_INC : Inconsistency Error + * @arg HAL_FLASH_ERROR_OBK : OBK Error + * @arg HAL_FLASH_ERROR_OBKW : OBK Write Error + * @arg HAL_FLASH_ERROR_OB_CHANGE : Option Byte Change Error + * @arg HAL_FLASH_ERROR_ECCC : ECC Single Correction Error + * @arg HAL_FLASH_ERROR_ECCD : ECC Double Detection Error + */ +uint32_t HAL_FLASH_GetError(void) +{ + return pFlash.ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ + +/** @addtogroup FLASH_Private_Functions + * @{ + */ + +/** + * @brief Wait for a FLASH operation to complete. + * @param Timeout maximum flash operation timeout + * @retval HAL_StatusTypeDef HAL Status + */ +HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout) +{ + /* Wait for the FLASH operation to complete by polling on BUSY, WBNE and DBNE flags to be reset. + Even if the FLASH operation fails, the BUSY, WBNE and DBNE flags will be reset and an error + flag will be set */ + + uint32_t errorflag; + const __IO uint32_t *reg_sr; + __IO uint32_t *reg_ccr; + + uint32_t tickstart = HAL_GetTick(); + + /* Access to SR register depends on operation type */ +#if defined (FLASH_OPTSR2_TZEN) + reg_sr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECSR) : &(FLASH_NS->NSSR); +#else + reg_sr = &(FLASH_NS->NSSR); +#endif /* FLASH_OPTSR2_TZEN */ + + /* Wait on BSY, WBNE and DBNE flags to be reset */ + while (((*reg_sr) & (FLASH_FLAG_BSY | FLASH_FLAG_WBNE | FLASH_FLAG_DBNE)) != 0U) + { + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + return HAL_TIMEOUT; + } + } + } + + /* Access to CCR register depends on operation type */ +#if defined (FLASH_OPTSR2_TZEN) + reg_ccr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCCR) : &(FLASH_NS->NSCCR); +#else + reg_ccr = &(FLASH_NS->NSCCR); +#endif /* FLASH_OPTSR2_TZEN */ + + /* Check FLASH operation error flags */ + errorflag = ((*reg_sr) & FLASH_FLAG_SR_ERRORS); + /* Add option byte error flag, if any */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + errorflag |= (FLASH->NSSR & FLASH_FLAG_OPTCHANGEERR); +#endif /* __ARM_FEATURE_CMSE */ + + /* In case of error reported in Flash SR or OPTSR registers */ + if (errorflag != 0U) + { + /*Save the error code*/ + pFlash.ErrorCode |= errorflag; + + /* Clear error flags */ + (*reg_ccr) = errorflag & FLASH_FLAG_SR_ERRORS; +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + if ((errorflag & FLASH_FLAG_OPTCHANGEERR) != 0U) + { + FLASH->NSCCR = FLASH_FLAG_OPTCHANGEERR; + } +#endif /* __ARM_FEATURE_CMSE */ + + return HAL_ERROR; + } + + /* Check FLASH End of Operation flag */ + if (((*reg_sr) & FLASH_FLAG_EOP) != 0U) + { + /* Clear FLASH End of Operation pending bit */ + (*reg_ccr) = FLASH_FLAG_EOP; + } + + /* If there is no error flag set */ + return HAL_OK; +} + +/** + * @brief Program a quad-word (128-bit) at a specified address. + * @param FlashAddress specifies the address to be programmed. + * @param DataAddress specifies the address of data to be programmed. + * @retval None + */ +static void FLASH_Program_QuadWord(uint32_t FlashAddress, uint32_t DataAddress) +{ + uint8_t index = 4; + uint32_t *dest_addr = (uint32_t *)FlashAddress; + uint32_t *src_addr = (uint32_t *)DataAddress; + uint32_t primask_bit; + __IO uint32_t *reg_cr; + + /* Access to SECCR or NSCR registers depends on operation type */ +#if defined (FLASH_OPTSR2_TZEN) + reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR); +#else + reg_cr = &(FLASH_NS->NSCR); +#endif /* FLASH_OPTSR2_TZEN */ + + /* Set PG bit */ + SET_BIT((*reg_cr), FLASH_CR_PG); + + /* Enter critical section: Disable interrupts to avoid any interruption during the loop */ + primask_bit = __get_PRIMASK(); + __disable_irq(); + + /* Program the quad-word */ + do + { + *dest_addr = *src_addr; + dest_addr++; + src_addr++; + index--; + } while (index != 0U); + + /* Exit critical section: restore previous priority mask */ + __set_PRIMASK(primask_bit); +} + +#if defined (FLASH_SR_OBKERR) +/** + * @brief Program a quad-word (128-bit) of OBK at a specified address. + * @param FlashAddress specifies the address to be programmed. + * @param DataAddress specifies the address of data to be programmed. + * @retval None + */ +static void FLASH_Program_QuadWord_OBK(uint32_t FlashAddress, uint32_t DataAddress) +{ + uint8_t index = 4; + uint32_t *dest_addr = (uint32_t *)FlashAddress; + uint32_t *src_addr = (uint32_t *)DataAddress; + uint32_t primask_bit; + __IO uint32_t *reg_cr; + __IO uint32_t *reg_obkcfgr; + + /* Access to SECCR or NSCR registers depends on operation type */ + reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR); + reg_obkcfgr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECOBKCFGR) : &(FLASH_NS->NSOBKCFGR); + + /* Set PG bit */ + SET_BIT((*reg_cr), FLASH_CR_PG); + + /* Set ALT_SECT bit */ + SET_BIT((*reg_obkcfgr), pFlash.ProcedureOnGoing & FLASH_OBKCFGR_ALT_SECT); + + /* Enter critical section: Disable interrupts to avoid any interruption during the loop */ + primask_bit = __get_PRIMASK(); + __disable_irq(); + + /* Program the quad-word */ + do + { + *dest_addr = *src_addr; + dest_addr++; + src_addr++; + index--; + } while (index != 0U); + + /* Exit critical section: restore previous priority mask */ + __set_PRIMASK(primask_bit); +} +#endif /* FLASH_SR_OBKERR */ + +/** + * @brief Program a half-word (16-bit) at a specified address. + * @param FlashAddress specifies the address to be programmed. + * @param DataAddress specifies the address of data to be programmed. + * @retval None + */ +static void FLASH_Program_HalfWord(uint32_t FlashAddress, uint32_t DataAddress) +{ + __IO uint32_t *reg_cr; + + /* Access to SECCR or NSCR registers depends on operation type */ +#if defined (FLASH_OPTSR2_TZEN) + reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR); +#else + reg_cr = &(FLASH_NS->NSCR); +#endif /* FLASH_OPTSR2_TZEN */ + + /* Set HalfWord_PG bit */ + SET_BIT((*reg_cr), FLASH_CR_PG); + + /* Program a halfword word (16 bits) */ + *(__IO uint16_t *)FlashAddress = *(__IO uint16_t *)DataAddress; +} + +/** + * @} + */ + +#endif /* HAL_FLASH_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_flash_ex.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_flash_ex.c new file mode 100644 index 0000000000..d1cdf324f6 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_flash_ex.c @@ -0,0 +1,1802 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_flash_ex.c + * @author MCD Application Team + * @brief Extended FLASH HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the FLASH extension peripheral: + * + Extended programming operations functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### Flash Extension features ##### + ============================================================================== + + [..] Comparing to other previous devices, the FLASH interface for STM32H5xx + devices contains the following additional features + + (+) Capacity up to 2 Mbyte with dual bank architecture supporting read-while-write + capability (RWW) + (+) Dual bank memory organization + (+) Product State protection + (+) Write protection + (+) Secure access only protection + (+) Bank / register swapping (when Dual-Bank) + (+) Watermark-based secure protection + (+) Block-based secure protection + (+) Block-based privilege protection + (+) Hide Protection areas + + ##### How to use this driver ##### + ============================================================================== + [..] This driver provides functions to configure and program the FLASH memory + of all STM32H5xx devices. It includes + (#) FLASH Memory Erase functions: + (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and + HAL_FLASH_Lock() functions + (++) Erase function: Sector erase, bank erase and dual-bank mass erase + (++) There are two modes of erase : + (+++) Polling Mode using HAL_FLASHEx_Erase() + (+++) Interrupt Mode using HAL_FLASHEx_Erase_IT() + + (#) Option Bytes Programming functions: Use HAL_FLASHEx_OBProgram() to: + (++) Configure the write protection per bank + (++) Set the Product State + (++) Program the user Option Bytes + (++) Configure the watermark security for each area + (++) Configure the Hide protection areas + (++) Configure the Boot addresses + + (#) Get Option Bytes Configuration function: Use HAL_FLASHEx_OBGetConfig() to: + (++) Get the value of a write protection area + (++) Get the Product State + (++) Get the value of the user Option Bytes + (++) Get the configuration of watermark security areas + (++) Get the configuration of Hide protection areas + (++) Get the value of a boot address + + (#) Block-based secure / privilege area configuration function: Use HAL_FLASHEx_ConfigBBAttributes() + (++) Bit-field allowing to secure or un-secure each sector + (++) Bit-field allowing to privilege or un-privilege each sector + + (#) Get the block-based secure / privilege area configuration function: Use HAL_FLASHEx_GetConfigBBAttributes() + (++) Return the configuration of the block-based security and privilege for all the sectors + + (#) Privilege mode configuration function: Use HAL_FLASHEx_ConfigPrivMode() + (++) FLASH register can be protected against non-privilege accesses + + (#) Get the privilege mode configuration function: Use HAL_FLASHEx_GetPrivMode() + (++) Return if the FLASH registers are protected against non-privilege accesses + + + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup FLASHEx FLASHEx + * @brief FLASH HAL Extension module driver + * @{ + */ + +#ifdef HAL_FLASH_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions + * @{ + */ +static void FLASH_MassErase(uint32_t Banks); +#if defined (FLASH_SR_OBKERR) +static void FLASH_OBKErase(void); +#endif /* FLASH_SR_OBKERR */ +static void FLASH_OB_EnableWRP(uint32_t WRPSector, uint32_t Banks); +static void FLASH_OB_DisableWRP(uint32_t WRPSector, uint32_t Bank); +static void FLASH_OB_GetWRP(uint32_t Bank, uint32_t *WRPState, uint32_t *WRPSector); +static void FLASH_OB_ProdStateConfig(uint32_t ProdStateConfig); +static uint32_t FLASH_OB_GetProdState(void); +static void FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig1, uint32_t UserConfig2); +static void FLASH_OB_GetUser(uint32_t *UserConfig1, uint32_t *UserConfig2); +static void FLASH_OB_BootAddrConfig(uint32_t BootOption, uint32_t BootAddress); +static void FLASH_OB_BootLockConfig(uint32_t BootLockOption, uint32_t BootLockConfig); +static void FLASH_OB_GetBootConfig(uint32_t BootOption, uint32_t *BootAddress, uint32_t *BootLockConfig); +static void FLASH_OB_OTP_LockConfig(uint32_t OTP_Block); +static uint32_t FLASH_OB_OTP_GetLock(void); +static void FLASH_OB_HDPConfig(uint32_t Banks, uint32_t HDPStartSector, uint32_t HDPEndSector); +static void FLASH_OB_GetHDP(uint32_t Bank, uint32_t *HDPStartSector, uint32_t *HDPEndSector); +#if defined(FLASH_EDATAR_EDATA_EN) +static void FLASH_OB_EDATAConfig(uint32_t Banks, uint32_t EDATASize); +static void FLASH_OB_GetEDATA(uint32_t Bank, uint32_t *EDATASize); +#endif /* FLASH_EDATAR_EDATA_EN */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +static void FLASH_OB_WMSECConfig(uint32_t Banks, uint32_t WMSecStartSector, uint32_t WMSecEndSector); +static void FLASH_OB_GetWMSEC(uint32_t Bank, uint32_t *WMSecStartSector, uint32_t *WMSecEndSector); +#endif /* __ARM_FEATURE_CMSE */ +/** + * @} + */ + +/* Exported functions ---------------------------------------------------------*/ +/** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions + * @{ + */ + +/** @defgroup FLASHEx_Exported_Functions_Group1 FLASHEx Extended IO operation functions + * @brief FLASHEx Extended IO operation functions + * +@verbatim + =============================================================================== + ##### Extended programming operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the Extended FLASH + programming operations Operations. + +@endverbatim + * @{ + */ +/** + * @brief Perform a mass erase or erase the specified FLASH memory sectors + * @param[in] pEraseInit pointer to an FLASH_EraseInitTypeDef structure that + * contains the configuration information for the erasing. + * + * @param[out] SectorError pointer to variable that contains the configuration + * information on faulty sector in case of error (0xFFFFFFFF means that all + * the sectors have been correctly erased). + * + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError) +{ + HAL_StatusTypeDef status; + uint32_t sector_index; + __IO uint32_t *reg_cr; + + /* Check the parameters */ + assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase)); + + /* Process Locked */ + __HAL_LOCK(&pFlash); + + /* Reset error code */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + + if (status == HAL_OK) + { + /* Current operation type */ + pFlash.ProcedureOnGoing = pEraseInit->TypeErase; + + /* Access to SECCR or NSCR depends on operation type */ +#if defined (FLASH_OPTSR2_TZEN) + reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR); +#else + reg_cr = &(FLASH_NS->NSCR); +#endif /* FLASH_OPTSR2_TZEN */ + + if ((pEraseInit->TypeErase & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEERASE_MASSERASE) + { + /* Mass erase to be done */ + FLASH_MassErase(pEraseInit->Banks); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + } +#if defined (FLASH_SR_OBKERR) + else if (pEraseInit->TypeErase == FLASH_TYPEERASE_OBK_ALT) + { + /* OBK erase to be done */ + FLASH_OBKErase(); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + } +#endif /* FLASH_SR_OBKERR */ + else + { + /* Initialization of SectorError variable */ + *SectorError = 0xFFFFFFFFU; + + /* Erase by sector by sector to be done*/ + for (sector_index = pEraseInit->Sector; sector_index < (pEraseInit->NbSectors + pEraseInit->Sector); \ + sector_index++) + { + FLASH_Erase_Sector(sector_index, pEraseInit->Banks); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + + if (status != HAL_OK) + { + /* In case of error, stop erase procedure and return the faulty sector */ + *SectorError = sector_index; + break; + } + } + } + + /* If the erase operation is completed, disable the associated bits */ + CLEAR_BIT((*reg_cr), (pEraseInit->TypeErase) & (~(FLASH_NON_SECURE_MASK))); + } + + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + + return status; +} + +/** + * @brief Perform a mass erase or erase the specified FLASH memory sectors with interrupt enabled + * @param pEraseInit pointer to an FLASH_EraseInitTypeDef structure that + * contains the configuration information for the erasing. + * + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit) +{ + HAL_StatusTypeDef status; + __IO uint32_t *reg_cr; + + /* Check the parameters */ + assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase)); + + /* Process Locked */ + __HAL_LOCK(&pFlash); + + /* Reset error code */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + + if (status != HAL_OK) + { + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + } + else + { + /* Set internal variables used by the IRQ handler */ + pFlash.ProcedureOnGoing = pEraseInit->TypeErase; + pFlash.Bank = pEraseInit->Banks; + + /* Access to SECCR or NSCR depends on operation type */ +#if defined (FLASH_OPTSR2_TZEN) + reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR); +#else + reg_cr = &(FLASH_NS->NSCR); +#endif /* FLASH_OPTSR2_TZEN */ + + /* Enable End of Operation and Error interrupts */ +#if defined (FLASH_SR_OBKERR) + (*reg_cr) |= (FLASH_IT_EOP | FLASH_IT_WRPERR | FLASH_IT_PGSERR | \ + FLASH_IT_STRBERR | FLASH_IT_INCERR | FLASH_IT_OBKERR | \ + FLASH_IT_OBKWERR); +#else + (*reg_cr) |= (FLASH_IT_EOP | FLASH_IT_WRPERR | FLASH_IT_PGSERR | \ + FLASH_IT_STRBERR | FLASH_IT_INCERR); +#endif /* FLASH_SR_OBKERR */ + + if ((pEraseInit->TypeErase & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEERASE_MASSERASE) + { + /* Mass erase to be done */ + FLASH_MassErase(pEraseInit->Banks); + } +#if defined (FLASH_SR_OBKERR) + else if (pEraseInit->TypeErase == FLASH_TYPEERASE_OBK_ALT) + { + /* OBK erase to be done */ + FLASH_OBKErase(); + } +#endif /* FLASH_SR_OBKERR */ + else + { + /* Erase by sector to be done */ + pFlash.NbSectorsToErase = pEraseInit->NbSectors; + pFlash.Sector = pEraseInit->Sector; + + /* Erase first sector and wait for IT */ + FLASH_Erase_Sector(pEraseInit->Sector, pEraseInit->Banks); + } + } + + return status; +} + +/** + * @brief Program option bytes + * @param pOBInit pointer to an FLASH_OBInitStruct structure that + * contains the configuration information for the programming. + * + * @note To configure any option bytes, the option lock bit OPTLOCK must be + * cleared with the call of HAL_FLASH_OB_Unlock() function. + * @note New option bytes configuration will be taken into account in two cases: + * - after an option bytes launch through the call of HAL_FLASH_OB_Launch() + * - after a power-on reset (BOR reset or exit from Standby/Shutdown modes) + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit) +{ + HAL_StatusTypeDef status; + + /* Check the parameters */ + assert_param(IS_OPTIONBYTE(pOBInit->OptionType)); + + /* Process Locked */ + __HAL_LOCK(&pFlash); + + /* Reset Error Code */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + + /* Current operation type */ + pFlash.ProcedureOnGoing = FLASH_TYPEPROGRAM_OB; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + + if (status == HAL_OK) + { + /*Write protection configuration*/ + if ((pOBInit->OptionType & OPTIONBYTE_WRP) != 0U) + { + assert_param(IS_WRPSTATE(pOBInit->WRPState)); + + if (pOBInit->WRPState == OB_WRPSTATE_ENABLE) + { + /* Enable write protection on the selected sectors */ + FLASH_OB_EnableWRP(pOBInit->WRPSector, pOBInit->Banks); + } + else + { + /* Disable write protection on the selected sectors */ + FLASH_OB_DisableWRP(pOBInit->WRPSector, pOBInit->Banks); + } + } + + /* Product State configuration */ + if ((pOBInit->OptionType & OPTIONBYTE_PROD_STATE) != 0U) + { + /* Configure the product state */ + FLASH_OB_ProdStateConfig(pOBInit->ProductState); + } + + /* User Configuration */ + if ((pOBInit->OptionType & OPTIONBYTE_USER) != 0U) + { + /* Configure the user option bytes */ + FLASH_OB_UserConfig(pOBInit->USERType, pOBInit->USERConfig, pOBInit->USERConfig2); + } + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + /* Watermark secure configuration */ + if ((pOBInit->OptionType & OPTIONBYTE_WMSEC) != 0U) + { + /* Configure the watermark-based secure area */ + FLASH_OB_WMSECConfig(pOBInit->Banks, pOBInit->WMSecStartSector, pOBInit->WMSecEndSector); + } +#endif /* __ARM_FEATURE_CMSE */ + + /* Boot Address configuration */ + if ((pOBInit->OptionType & OPTIONBYTE_BOOTADDR) != 0U) + { + FLASH_OB_BootAddrConfig(pOBInit->BootConfig, pOBInit->BootAddr); + } + + /* Unique boot entry point configuration */ + if ((pOBInit->OptionType & OPTIONBYTE_BOOT_LOCK) != 0U) + { + /* Configure the unique boot entry point */ + FLASH_OB_BootLockConfig(pOBInit->BootConfig, pOBInit->BootLock); + } + + /* OTP Block Lock configuration */ + if ((pOBInit->OptionType & OPTIONBYTE_OTP_LOCK) != 0U) + { + FLASH_OB_OTP_LockConfig(pOBInit->OTPBlockLock); + } + + /* Hide Protection area configuration */ + if ((pOBInit->OptionType & OPTIONBYTE_HDP) != 0U) + { + FLASH_OB_HDPConfig(pOBInit->Banks, pOBInit->HDPStartSector, pOBInit->HDPEndSector); + } + +#if defined(FLASH_EDATAR_EDATA_EN) + /* Flash high-cycle data area configuration */ + if ((pOBInit->OptionType & OPTIONBYTE_EDATA) != 0U) + { + FLASH_OB_EDATAConfig(pOBInit->Banks, pOBInit->EDATASize); + } +#endif /* FLASH_EDATAR_EDATA_EN */ + } + + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + + return status; +} + +/** + * @brief Get the Option byte configuration + * @param pOBInit pointer to an FLASH_OBInitStruct structure that + * contains the configuration information for the programming. + * @note The parameter Banks of the pOBInit structure must be set exclusively to FLASH_BANK_1 or FLASH_BANK_2, + * as this parameter is use to get the given Bank WRP, PCROP and secured area configuration. + * + * @retval None + */ +void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit) +{ + pOBInit->OptionType = (OPTIONBYTE_USER | OPTIONBYTE_PROD_STATE); + + /* Get Product State */ + pOBInit->ProductState = FLASH_OB_GetProdState(); + + /* Get the user option bytes */ + FLASH_OB_GetUser(&(pOBInit->USERConfig), &(pOBInit->USERConfig2)); + + if ((pOBInit->Banks == FLASH_BANK_1) || (pOBInit->Banks == FLASH_BANK_2)) + { + /* Get write protection on the selected area */ + pOBInit->OptionType |= OPTIONBYTE_WRP; + FLASH_OB_GetWRP(pOBInit->Banks, &(pOBInit->WRPState), &(pOBInit->WRPSector)); + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + /* Get the configuration of the watermark secure area for the selected area */ + pOBInit->OptionType |= OPTIONBYTE_WMSEC; + FLASH_OB_GetWMSEC(pOBInit->Banks, &(pOBInit->WMSecStartSector), &(pOBInit->WMSecEndSector)); +#endif /* __ARM_FEATURE_CMSE */ + + /* Get the configuration of the hide protection for the selected area */ + pOBInit->OptionType |= OPTIONBYTE_HDP; + FLASH_OB_GetHDP(pOBInit->Banks, &(pOBInit->HDPStartSector), &(pOBInit->HDPEndSector)); +#if defined (FLASH_EDATAR_EDATA_EN) + /* Get the Flash high-cycle data configuration for the selected area */ + pOBInit->OptionType |= OPTIONBYTE_EDATA; + FLASH_OB_GetEDATA(pOBInit->Banks, &(pOBInit->EDATASize)); +#endif /* FLASH_EDATAR_EDATA_EN */ + } + + /* Get boot configuration */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + if ((pOBInit->BootConfig == OB_BOOT_NS) || (pOBInit->BootConfig == OB_BOOT_SEC)) +#else + if (pOBInit->BootConfig == OB_BOOT_NS) +#endif /* __ARM_FEATURE_CMSE */ + { + pOBInit->OptionType |= OPTIONBYTE_BOOTADDR | OPTIONBYTE_BOOT_LOCK; + FLASH_OB_GetBootConfig(pOBInit->BootConfig, &(pOBInit->BootAddr), &(pOBInit->BootLock)); + } + + /* Get OTP Block Lock */ + pOBInit->OptionType |= OPTIONBYTE_OTP_LOCK; + pOBInit->OTPBlockLock = FLASH_OB_OTP_GetLock(); +} + +#if defined (FLASH_SR_OBKERR) +/** + * @brief Unlock the FLASH OBK register access + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_OBK_Unlock(void) +{ + HAL_StatusTypeDef status = HAL_OK; + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + if (READ_BIT(FLASH->SECOBKCFGR, FLASH_OBKCFGR_LOCK) != 0U) + { + /* Authorize the FLASH OBK Register access */ + WRITE_REG(FLASH->SECOBKKEYR, FLASH_OBK_KEY1); + WRITE_REG(FLASH->SECOBKKEYR, FLASH_OBK_KEY2); + + /* Verify Flash OBK Register is unlocked */ + if (READ_BIT(FLASH->SECOBKCFGR, FLASH_OBKCFGR_LOCK) != 0U) + { + status = HAL_ERROR; + } + } +#else + if (READ_BIT(FLASH->NSOBKCFGR, FLASH_OBKCFGR_LOCK) != 0U) + { + /* Authorize the FLASH OBK Register access */ + WRITE_REG(FLASH->NSOBKKEYR, FLASH_OBK_KEY1); + WRITE_REG(FLASH->NSOBKKEYR, FLASH_OBK_KEY2); + + /* Verify Flash OBK Register is unlocked */ + if (READ_BIT(FLASH->NSOBKCFGR, FLASH_OBKCFGR_LOCK) != 0U) + { + status = HAL_ERROR; + } + } +#endif /* __ARM_FEATURE_CMSE */ + + return status; +} + +/** + * @brief Locks the FLASH OBK register access + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_OBK_Lock(void) +{ + HAL_StatusTypeDef status = HAL_ERROR; + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + /* Set the LOCK Bit to lock the FLASH OBK Register access */ + SET_BIT(FLASH->SECOBKCFGR, FLASH_OBKCFGR_LOCK); + + /* verify Flash is locked */ + if (READ_BIT(FLASH->SECOBKCFGR, FLASH_OBKCFGR_LOCK) != 0U) + { + status = HAL_OK; + } +#else + /* Set the LOCK Bit to lock the FLASH OBK Register access */ + SET_BIT(FLASH->NSOBKCFGR, FLASH_OBKCFGR_LOCK); + + /* Verify Flash OBK is locked */ + if (READ_BIT(FLASH->NSOBKCFGR, FLASH_OBKCFGR_LOCK) != 0U) + { + status = HAL_OK; + } +#endif /* __ARM_FEATURE_CMSE */ + + return status; +} + +/** + * @brief Swap the FLASH Option Bytes Keys (OBK) + * @param SwapOffset Specifies the number of keys to be swapped. + * This parameter can be a value between 0 (no OBK data swapped) and 511 (all OBK data swapped). + * Typical value are available in @ref FLASH_OBK_SWAP_Offset + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_OBK_Swap(uint32_t SwapOffset) +{ + HAL_StatusTypeDef status; + __IO uint32_t *reg_obkcfgr; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + + if (status == HAL_OK) + { + /* Access to SECOBKCFGR or NSOBKCFGR registers depends on operation type */ + reg_obkcfgr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECOBKCFGR) : &(FLASH_NS->NSOBKCFGR); + + /* Set OBK swap offset */ + MODIFY_REG((*reg_obkcfgr), FLASH_OBKCFGR_SWAP_OFFSET, (SwapOffset << FLASH_OBKCFGR_SWAP_OFFSET_Pos)); + + /* Set OBK swap request */ + SET_BIT((*reg_obkcfgr), FLASH_OBKCFGR_SWAP_SECT_REQ); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + } + + return status; +} +#endif /* FLASH_SR_OBKERR */ + +/** + * @brief Return the on-going Flash Operation. After a system reset, return + * the interrupted Flash operation, if any. + * @param pFlashOperation [out] pointer to a FLASH_OperationTypeDef structure + * that contains the Flash operation information. + * @retval None + */ +void HAL_FLASHEx_GetOperation(FLASH_OperationTypeDef *pFlashOperation) +{ + uint32_t opsr_reg = FLASH->OPSR; + + /* Get Flash operation Type */ + pFlashOperation->OperationType = opsr_reg & FLASH_OPSR_CODE_OP; + + /* Get Flash operation memory */ +#if defined (FLASH_EDATAR_EDATA_EN) + pFlashOperation->FlashArea = opsr_reg & (FLASH_OPSR_DATA_OP | FLASH_OPSR_BK_OP | \ + FLASH_OPSR_SYSF_OP | FLASH_OPSR_OTP_OP); +#else + pFlashOperation->FlashArea = opsr_reg & (FLASH_OPSR_BK_OP | FLASH_OPSR_SYSF_OP | \ + FLASH_OPSR_OTP_OP); +#endif /* FLASH_EDATAR_EDATA_EN */ + /* Get Flash operation address */ + pFlashOperation->Address = opsr_reg & FLASH_OPSR_ADDR_OP; +} + +/** + * @} + */ + +/** @defgroup FLASHEx_Exported_Functions_Group2 FLASHEx Extension Protection configuration functions + * @brief Extension Protection configuration functions + * @{ + */ + +/** + * @brief Configure the block-based secure area. + * + * @param pBBAttributes pointer to an FLASH_BBAttributesTypeDef structure that + * contains the configuration information for the programming. + * + * @note The field pBBAttributes->Bank should indicate which area is requested + * for the block-based attributes. + * @note The field pBBAttributes->BBAttributesType should indicate which + * block-base attribute type is requested: Secure or Privilege. + * + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_ConfigBBAttributes(FLASH_BBAttributesTypeDef *pBBAttributes) +{ + HAL_StatusTypeDef status; + uint8_t index; + __IO uint32_t *reg; + + /* Check the parameters */ + assert_param(IS_FLASH_BANK_EXCLUSIVE(pBBAttributes->Bank)); + assert_param(IS_FLASH_BB_EXCLUSIVE(pBBAttributes->BBAttributesType)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + + if (status == HAL_OK) + { + /* Set the first Block-Based register to write */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + if (pBBAttributes->BBAttributesType == FLASH_BB_SEC) + { + if (pBBAttributes->Bank == FLASH_BANK_1) + { + reg = &(FLASH->SECBB1R1); + } + else + { + reg = &(FLASH->SECBB2R1); + } + } + else +#endif /* __ARM_FEATURE_CMSE */ + { + if (pBBAttributes->Bank == FLASH_BANK_1) + { + reg = &(FLASH->PRIVBB1R1); + } + else + { + reg = &(FLASH->PRIVBB2R1); + } + } + + /* Modify the register values and check that new attributes are taken in account */ + for (index = 0; index < FLASH_BLOCKBASED_NB_REG; index++) + { + *reg = pBBAttributes->BBAttributes_array[index] & FLASH_PRIVBBR_PRIVBB; + if ((*reg) != (pBBAttributes->BBAttributes_array[index] & FLASH_PRIVBBR_PRIVBB)) + { + status = HAL_ERROR; + } + reg++; + } + + /* ISB instruction is called to be sure next instructions are performed with correct attributes */ + __ISB(); + } + + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + + return status; +} + +/** + * @brief Return the block-based attributes. + * + * @param pBBAttributes [in/out] pointer to an FLASH_BBAttributesTypeDef structure + * that contains the configuration information. + * @note The field pBBAttributes->Bank should indicate which area is requested + * for the block-based attributes. + * @note The field pBBAttributes->BBAttributesType should indicate which + * block-base attribute type is requested: Secure or Privilege. + * + * @retval None + */ +void HAL_FLASHEx_GetConfigBBAttributes(FLASH_BBAttributesTypeDef *pBBAttributes) +{ + uint8_t index; + __IO uint32_t *reg; + + /* Check the parameters */ + assert_param(IS_FLASH_BANK_EXCLUSIVE(pBBAttributes->Bank)); + assert_param(IS_FLASH_BB_EXCLUSIVE(pBBAttributes->BBAttributesType)); + + /* Set the first Block-Based register to read */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + if (pBBAttributes->BBAttributesType == FLASH_BB_SEC) + { + if (pBBAttributes->Bank == FLASH_BANK_1) + { + reg = &(FLASH->SECBB1R1); + } + else + { + reg = &(FLASH->SECBB2R1); + } + } + else +#endif /* __ARM_FEATURE_CMSE */ + { + if (pBBAttributes->Bank == FLASH_BANK_1) + { + reg = &(FLASH->PRIVBB1R1); + } + else + { + reg = &(FLASH->PRIVBB2R1); + } + } + + /* Read the register values */ + for (index = 0; index < FLASH_BLOCKBASED_NB_REG; index++) + { + pBBAttributes->BBAttributes_array[index] = (*reg) & FLASH_PRIVBBR_PRIVBB; + reg++; + } +} + +/** + * @brief Configuration of the privilege attribute. + * + * @param PrivMode indicate privilege mode configuration + * This parameter can be one of the following values: + * @arg FLASH_SPRIV_GRANTED: access to secure Flash registers is granted to privileged or unprivileged access + * @arg FLASH_SPRIV_DENIED: access to secure Flash registers is denied to unprivileged access + * @arg FLASH_NSPRIV_GRANTED: access to non-secure Flash registers is granted to privileged or unprivileged access + * @arg FLASH_NSPRIV_DENIED: access to non-secure Flash registers is denied to unprivilege access + * + * @retval None + */ +void HAL_FLASHEx_ConfigPrivMode(uint32_t PrivMode) +{ + /* Check the parameters */ + assert_param(IS_FLASH_CFGPRIVMODE(PrivMode)); +#if defined (FLASH_PRIVCFGR_SPRIV) + MODIFY_REG(FLASH->PRIVCFGR, (FLASH_PRIVCFGR_SPRIV | FLASH_PRIVCFGR_NSPRIV), PrivMode); +#else + MODIFY_REG(FLASH->PRIVCFGR, FLASH_PRIVCFGR_NSPRIV, PrivMode); +#endif /* FLASH_PRIVCFGR_SPRIV */ +} + +/** + * @brief Return the value of the privilege attribute. + * + * @retval It indicates the privilege mode configuration. + * This return value can be one of the following values: + * @arg FLASH_SPRIV_GRANTED: access to secure Flash registers is granted to privileged or unprivileged access + * @arg FLASH_SPRIV_DENIED: access to secure Flash registers is denied to unprivileged access + * @arg FLASH_NSPRIV_GRANTED: access to non-secure Flash registers is granted to privileged or unprivileged access + * @arg FLASH_NSPRIV_DENIED: access to Flash registers is denied to unprivilege accessP + */ +uint32_t HAL_FLASHEx_GetPrivMode(void) +{ +#if defined (FLASH_PRIVCFGR_SPRIV) + return (FLASH->PRIVCFGR & (FLASH_PRIVCFGR_SPRIV | FLASH_PRIVCFGR_NSPRIV)); +#else + return (FLASH->PRIVCFGR & FLASH_PRIVCFGR_NSPRIV); +#endif /* FLASH_PRIVCFGR_SPRIV */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Configuration of the security inversion. + * + * @param SecInvState indicate the flash security state configuration + * This parameter can be one of the following values: + * @arg FLASH_SEC_INV_DISABLE: Security state of Flash is not inverted + * @arg FLASH_SEC_INV_ENABLE: Security state of Flash is inverted + * + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_ConfigSecInversion(uint32_t SecInvState) +{ + HAL_StatusTypeDef status; + + /* Check the parameters */ + assert_param(IS_FLASH_CFGSECINV(SecInvState)); + + /* Process Locked */ + __HAL_LOCK(&pFlash); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + + if (status == HAL_OK) + { + MODIFY_REG(FLASH->SECCR, FLASH_CR_INV, SecInvState); + } + + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + + return status; +} + +/** + * @brief Return the value of the security inversion. + * + * @retval It indicates the flash security state configuration + * This return value can be one of the following values: + * @arg FLASH_SEC_INV_DISABLE: Security state of Flash is not inverted + * @arg FLASH_SEC_INV_ENABLE: Security state of Flash is inverted + */ +uint32_t HAL_FLASHEx_GetSecInversion(void) +{ + return (FLASH->SECCR & FLASH_CR_INV); +} +#endif /* __ARM_FEATURE_CMSE */ + +/** + * @brief Configure the HDP extension area. + * + * @param pHDPExtension pointer to an FLASH_HDPExtentionTypeDef structure that + * contains the configuration information. + * + * @note The field pHDPExtension->Banks should indicate which area is requested + * for the HDP extension. + * @note The field pHDPExtension->NbSectors should indicate the number of + * sector to be added to the HDP area. + * + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_ConfigHDPExtension(const FLASH_HDPExtensionTypeDef *pHDPExtension) +{ + /* Check the parameters */ + assert_param(IS_FLASH_BANK(pHDPExtension->Banks)); + assert_param(IS_FLASH_SECTOR(pHDPExtension->NbSectors)); + + /* Set the HDP extension register */ + if (pHDPExtension->Banks == FLASH_BANK_1) + { + MODIFY_REG(FLASH->HDPEXTR, FLASH_HDPEXTR_HDP1_EXT, pHDPExtension->NbSectors); + } + else if (pHDPExtension->Banks == FLASH_BANK_2) + { + MODIFY_REG(FLASH->HDPEXTR, FLASH_HDPEXTR_HDP2_EXT, (pHDPExtension->NbSectors << FLASH_HDPEXTR_HDP2_EXT_Pos)); + } + else + { + FLASH->HDPEXTR = (pHDPExtension->NbSectors << FLASH_HDPEXTR_HDP2_EXT_Pos) | pHDPExtension->NbSectors; + } + + return HAL_OK; +} + +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ + +/** @addtogroup FLASHEx_Private_Functions + * @{ + */ + +/** + * @brief Mass erase of FLASH memory + * @param Banks Banks to be erased + * This parameter can be one of the following values: + * @arg FLASH_BANK_1: Bank1 to be erased + * @arg FLASH_BANK_2: Bank2 to be erased + * @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased + * @retval None + */ +static void FLASH_MassErase(uint32_t Banks) +{ + __IO uint32_t *reg_cr; + + /* Check the parameters */ + assert_param(IS_FLASH_BANK(Banks)); + + /* Access to SECCR or NSCR registers depends on operation type */ +#if defined (FLASH_OPTSR2_TZEN) + reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR); +#else + reg_cr = &(FLASH_NS->NSCR); +#endif /* FLASH_OPTSR2_TZEN */ + + /* Flash Mass Erase */ + if ((Banks & FLASH_BANK_BOTH) == FLASH_BANK_BOTH) + { + /* Set Mass Erase Bit */ + SET_BIT((*reg_cr), FLASH_CR_MER | FLASH_CR_START); + } + else + { + /* Proceed to erase Flash Bank */ + if ((Banks & FLASH_BANK_1) == FLASH_BANK_1) + { + /* Erase Bank1 */ + MODIFY_REG((*reg_cr), (FLASH_CR_BKSEL | FLASH_CR_BER | FLASH_CR_START), (FLASH_CR_BER | FLASH_CR_START)); + } + + if ((Banks & FLASH_BANK_2) == FLASH_BANK_2) + { + /* Erase Bank2 */ + SET_BIT((*reg_cr), (FLASH_CR_BER | FLASH_CR_BKSEL | FLASH_CR_START)); + } + } +} + +/** + * @brief Erase the specified FLASH memory sector + * @param Sector FLASH sector to erase + * This parameter can be a value of @ref FLASH_Sectors + * @param Banks Bank(s) where the sector will be erased + * This parameter can be one of the following values: + * @arg FLASH_BANK_1: Sector in bank 1 to be erased + * @arg FLASH_BANK_2: Sector in bank 2 to be erased + * @retval None + */ +void FLASH_Erase_Sector(uint32_t Sector, uint32_t Banks) +{ + __IO uint32_t *reg_cr; + + /* Check the parameters */ + assert_param(IS_FLASH_SECTOR(Sector)); + assert_param(IS_FLASH_BANK_EXCLUSIVE(Banks)); + + /* Access to SECCR or NSCR registers depends on operation type */ +#if defined (FLASH_OPTSR2_TZEN) + reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR); +#else + reg_cr = &(FLASH_NS->NSCR); +#endif /* FLASH_OPTSR2_TZEN */ + + if ((Banks & FLASH_BANK_1) == FLASH_BANK_1) + { + /* Reset Sector Number for Bank1 */ + (*reg_cr) &= ~(FLASH_CR_SNB | FLASH_CR_BKSEL); + + (*reg_cr) |= (FLASH_CR_SER | (Sector << FLASH_CR_SNB_Pos) | FLASH_CR_START); + } + else + { + /* Reset Sector Number for Bank2 */ + (*reg_cr) &= ~(FLASH_CR_SNB); + + (*reg_cr) |= (FLASH_CR_SER | FLASH_CR_BKSEL | (Sector << FLASH_CR_SNB_Pos) | FLASH_CR_START); + } +} + +#if defined (FLASH_SR_OBKERR) +/** + * @brief Erase of FLASH OBK + * @retval None + */ +static void FLASH_OBKErase() +{ + __IO uint32_t *reg_obkcfgr; + + /* Access to SECOBKCFGR or NSOBKCFGR registers depends on operation type */ + reg_obkcfgr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECOBKCFGR) : &(FLASH_NS->NSOBKCFGR); + + /* Set OBK Erase Bit */ + SET_BIT((*reg_obkcfgr), FLASH_OBKCFGR_ALT_SECT_ERASE); +} +#endif /* FLASH_SR_OBKERR */ + +/** + * @brief Enable the write protection of the desired bank1 or bank 2 sectors + * @param WRPSector specifies the sectors to be write protected. + * This parameter can be a value of @ref FLASH_OB_Write_Protection_Sectors + * + * @param Banks the specific bank to apply WRP sectors + * This parameter can be one of the following values: + * @arg FLASH_BANK_1: enable WRP on specified bank1 sectors + * @arg FLASH_BANK_2: enable WRP on specified bank2 sectors + * @arg FLASH_BANK_BOTH: enable WRP on both bank1 and bank2 specified sectors + * + * @retval None + */ +static void FLASH_OB_EnableWRP(uint32_t WRPSector, uint32_t Banks) +{ + /* Check the parameters */ + assert_param(IS_FLASH_BANK(Banks)); + + if ((Banks & FLASH_BANK_1) == FLASH_BANK_1) + { + /* Enable Write Protection for bank 1 */ + FLASH->WRP1R_PRG &= (~(WRPSector & FLASH_WRPR_WRPSG)); + } + + if ((Banks & FLASH_BANK_2) == FLASH_BANK_2) + { + /* Enable Write Protection for bank 2 */ + FLASH->WRP2R_PRG &= (~(WRPSector & FLASH_WRPR_WRPSG)); + } +} + +/** + * @brief Disable the write protection of the desired bank1 or bank 2 sectors + * @param WRPSector specifies the sectors to disable write protection. + * This parameter can be a value of @ref FLASH_OB_Write_Protection_Sectors + * + * @param Banks the specific bank to apply WRP sectors + * This parameter can be one of the following values: + * @arg FLASH_BANK_1: disable WRP on specified bank1 sectors + * @arg FLASH_BANK_2: disable WRP on specified bank2 sectors + * @arg FLASH_BANK_BOTH: disable WRP on both bank1 and bank2 specified sectors + * + * @retval None + */ +static void FLASH_OB_DisableWRP(uint32_t WRPSector, uint32_t Banks) +{ + /* Check the parameters */ + assert_param(IS_FLASH_BANK(Banks)); + + if ((Banks & FLASH_BANK_1) == FLASH_BANK_1) + { + /* Disable Write Protection for bank 1 */ + FLASH->WRP1R_PRG |= (WRPSector & FLASH_WRPR_WRPSG); + } + + if ((Banks & FLASH_BANK_2) == FLASH_BANK_2) + { + /* Disable Write Protection for bank 2 */ + FLASH->WRP2R_PRG |= (WRPSector & FLASH_WRPR_WRPSG); + } +} + +/** + * @brief Get the write protection of the given bank 1 or bank 2 sectors + * @param[in] Bank specifies the bank where to get the write protection sectors. + * This parameter can be exclusively one of the following values: + * @arg FLASH_BANK_1: Get bank1 WRP sectors + * @arg FLASH_BANK_2: Get bank2 WRP sectors + * + * @param[out] WRPState returns the write protection state of the returned sectors. + * This parameter can be one of the following values: + * @arg WRPState: OB_WRPSTATE_DISABLE or OB_WRPSTATE_ENABLE + + * @param[out] WRPSector returns the write protected sectors on the given bank . + * This parameter can be a value of @ref FLASH_OB_Write_Protection_Sectors + * + * @retval None + */ +static void FLASH_OB_GetWRP(uint32_t Bank, uint32_t *WRPState, uint32_t *WRPSector) +{ + uint32_t regvalue = 0U; + + if (Bank == FLASH_BANK_1) + { + regvalue = FLASH->WRP1R_CUR; + } + + if (Bank == FLASH_BANK_2) + { + regvalue = FLASH->WRP2R_CUR; + } + + (*WRPSector) = (~regvalue) & FLASH_WRPR_WRPSG; + + if (*WRPSector == 0U) + { + (*WRPState) = OB_WRPSTATE_DISABLE; + } + else + { + (*WRPState) = OB_WRPSTATE_ENABLE; + } +} + +/** + * @brief Set the product state. + * + * @note To configure the product state, the option lock bit OPTLOCK must be + * cleared with the call of the HAL_FLASH_OB_Unlock() function. + * @note To validate the product state, the option bytes must be reloaded + * through the call of the HAL_FLASH_OB_Launch() function. + * + * @param ProductState specifies the product state. + * This parameter can be a value of @ref FLASH_OB_Product_State + * + * @retval None + */ +static void FLASH_OB_ProdStateConfig(uint32_t ProductState) +{ + /* Check the parameters */ + assert_param(IS_OB_PRODUCT_STATE(ProductState)); + + /* Configure the Product State in the option bytes register */ + MODIFY_REG(FLASH->OPTSR_PRG, FLASH_OPTSR_PRODUCT_STATE, ProductState); +} + +/** + * @brief Get the the product state. + * @retval ProductState returns the product state. + * This returned value can a value of @ref FLASH_OB_Product_State + */ +static uint32_t FLASH_OB_GetProdState(void) +{ + return (FLASH->OPTSR_CUR & FLASH_OPTSR_PRODUCT_STATE); +} + +/** + * @brief Program the FLASH User Option Byte. + * + * @note To configure the user option bytes, the option lock bit OPTLOCK must + * be cleared with the call of the HAL_FLASH_OB_Unlock() function. + * @note To validate the user option bytes, the option bytes must be reloaded + * through the call of the HAL_FLASH_OB_Launch() function. + * + * @param UserType specifies The FLASH User Option Bytes to be modified. + * This parameter can be a combination of @ref FLASH_OB_USER_Type + * + * @param UserConfig1 specifies values of the selected User Option Bytes. + * This parameter can be a combination of @ref FLASH_OB_USER_BOR_LEVEL, + * @ref FLASH_OB_USER_BORH_EN, @ref FLASH_OB_USER_IWDG_SW, + * @ref FLASH_OB_USER_WWDG_SW, @ref FLASH_OB_USER_nRST_STOP, + * @ref FLASH_OB_USER_nRST_STANDBY, @ref FLASH_OB_USER_IO_VDD_HSLV, + * @ref FLASH_OB_USER_IO_VDDIO2_HSLV, @ref FLASH_OB_USER_IWDG_STOP, + * @ref FLASH_OB_USER_IWDG_STANDBY, @ref FLASH_OB_USER_BOOT_UBE and @ref OB_USER_SWAP_BANK. + * @param UserConfig2 specifies values of the selected User Option Bytes. + * @ref FLASH_OB_USER_SRAM1_3_RST, @ref FLASH_OB_USER_SRAM2_RST, + * @ref FLASH_OB_USER_BKPRAM_ECC, @ref FLASH_OB_USER_SRAM3_ECC, + * @ref FLASH_OB_USER_SRAM2_ECC, @ref FLASH_OB_USER_SRAM1_ECC, + * @ref FLASH_OB_USER_SRAM1_RST and @ref OB_USER_TZEN. + * @retval None + */ +static void FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig1, uint32_t UserConfig2) +{ + uint32_t optr_reg1_val = 0U; + uint32_t optr_reg1_mask = 0U; + uint32_t optr_reg2_val = 0U; + uint32_t optr_reg2_mask = 0U; + + /* Check the parameters */ + assert_param(IS_OB_USER_TYPE(UserType)); + + if ((UserType & OB_USER_BOR_LEV) != 0U) + { + /* BOR level option byte should be modified */ + assert_param(IS_OB_USER_BOR_LEVEL(UserConfig1 & FLASH_OPTSR_BOR_LEV)); + + /* Set value and mask for BOR level option byte */ + optr_reg1_val |= (UserConfig1 & FLASH_OPTSR_BOR_LEV); + optr_reg1_mask |= FLASH_OPTSR_BOR_LEV; + } + + if ((UserType & OB_USER_BORH_EN) != 0U) + { + /* BOR high enable status bit should be modified */ + assert_param(IS_OB_USER_BORH_EN(UserConfig1 & FLASH_OPTSR_BORH_EN)); + + /* Set value and mask for BOR high enable status bit */ + optr_reg1_val |= (UserConfig1 & FLASH_OPTSR_BORH_EN); + optr_reg1_mask |= FLASH_OPTSR_BORH_EN; + } + + if ((UserType & OB_USER_IWDG_SW) != 0U) + { + /* IWDG_SW option byte should be modified */ + assert_param(IS_OB_USER_IWDG(UserConfig1 & FLASH_OPTSR_IWDG_SW)); + + /* Set value and mask for IWDG_SW option byte */ + optr_reg1_val |= (UserConfig1 & FLASH_OPTSR_IWDG_SW); + optr_reg1_mask |= FLASH_OPTSR_IWDG_SW; + } + + if ((UserType & OB_USER_WWDG_SW) != 0U) + { + /* WWDG_SW option byte should be modified */ + assert_param(IS_OB_USER_WWDG(UserConfig1 & FLASH_OPTSR_WWDG_SW)); + + /* Set value and mask for WWDG_SW option byte */ + optr_reg1_val |= (UserConfig1 & FLASH_OPTSR_WWDG_SW); + optr_reg1_mask |= FLASH_OPTSR_WWDG_SW; + } + + if ((UserType & OB_USER_NRST_STOP) != 0U) + { + /* nRST_STOP option byte should be modified */ + assert_param(IS_OB_USER_STOP(UserConfig1 & FLASH_OPTSR_NRST_STOP)); + + /* Set value and mask for nRST_STOP option byte */ + optr_reg1_val |= (UserConfig1 & FLASH_OPTSR_NRST_STOP); + optr_reg1_mask |= FLASH_OPTSR_NRST_STOP; + } + + if ((UserType & OB_USER_NRST_STDBY) != 0U) + { + /* nRST_STDBY option byte should be modified */ + assert_param(IS_OB_USER_STANDBY(UserConfig1 & FLASH_OPTSR_NRST_STDBY)); + + /* Set value and mask for nRST_STDBY option byte */ + optr_reg1_val |= (UserConfig1 & FLASH_OPTSR_NRST_STDBY); + optr_reg1_mask |= FLASH_OPTSR_NRST_STDBY; + } + + if ((UserType & OB_USER_IO_VDD_HSLV) != 0U) + { + /* IO_VDD_HSLV option byte should be modified */ + assert_param(IS_OB_USER_IO_VDD_HSLV(UserConfig1 & FLASH_OPTSR_IO_VDD_HSLV)); + + /* Set value and mask for IO_VDD_HSLV option byte */ + optr_reg1_val |= (UserConfig1 & FLASH_OPTSR_IO_VDD_HSLV); + optr_reg1_mask |= FLASH_OPTSR_IO_VDD_HSLV; + } + + if ((UserType & OB_USER_IO_VDDIO2_HSLV) != 0U) + { + /* IO_VDD_HSLV option byte should be modified */ + assert_param(IS_OB_USER_IO_VDDIO2_HSLV(UserConfig1 & FLASH_OPTSR_IO_VDDIO2_HSLV)); + + /* Set value and mask for IO_VDD_HSLV option byte */ + optr_reg1_val |= (UserConfig1 & FLASH_OPTSR_IO_VDDIO2_HSLV); + optr_reg1_mask |= FLASH_OPTSR_IO_VDDIO2_HSLV; + } + + if ((UserType & OB_USER_IWDG_STOP) != 0U) + { + /* IWDG_STOP option byte should be modified */ + assert_param(IS_OB_USER_IWDG_STOP(UserConfig1 & FLASH_OPTSR_IWDG_STOP)); + + /* Set value and mask for IWDG_STOP option byte */ + optr_reg1_val |= (UserConfig1 & FLASH_OPTSR_IWDG_STOP); + optr_reg1_mask |= FLASH_OPTSR_IWDG_STOP; + } + + if ((UserType & OB_USER_IWDG_STDBY) != 0U) + { + /* IWDG_STDBY option byte should be modified */ + assert_param(IS_OB_USER_IWDG_STDBY(UserConfig1 & FLASH_OPTSR_IWDG_STDBY)); + + /* Set value and mask for IWDG_STDBY option byte */ + optr_reg1_val |= (UserConfig1 & FLASH_OPTSR_IWDG_STDBY); + optr_reg1_mask |= FLASH_OPTSR_IWDG_STDBY; + } + +#if defined (FLASH_OPTSR_BOOT_UBE) + if ((UserType & OB_USER_BOOT_UBE) != 0U) + { + /* SWAP_BANK option byte should be modified */ + assert_param(IS_OB_USER_BOOT_UBE(UserConfig1 & FLASH_OPTSR_BOOT_UBE)); + + /* Set value and mask for BOOT_UBE option byte */ + optr_reg1_val |= (UserConfig1 & FLASH_OPTSR_BOOT_UBE); + optr_reg1_mask |= FLASH_OPTSR_BOOT_UBE; + } +#endif /* FLASH_OPTSR_BOOT_UBE */ + + if ((UserType & OB_USER_SWAP_BANK) != 0U) + { + /* SWAP_BANK option byte should be modified */ + assert_param(IS_OB_USER_SWAP_BANK(UserConfig1 & FLASH_OPTSR_SWAP_BANK)); + + /* Set value and mask for SWAP_BANK option byte */ + optr_reg1_val |= (UserConfig1 & FLASH_OPTSR_SWAP_BANK); + optr_reg1_mask |= FLASH_OPTSR_SWAP_BANK; + } + +#if defined (FLASH_OPTSR2_SRAM1_3_RST) + if ((UserType & OB_USER_SRAM1_3_RST) != 0U) + { + /* SRAM13_RST option byte should be modified */ + assert_param(IS_OB_USER_SRAM1_3_RST(UserConfig2 & FLASH_OPTSR2_SRAM1_3_RST)); + + /* Set value and mask for SRAM13_RST option byte */ + optr_reg2_val |= (UserConfig2 & FLASH_OPTSR2_SRAM1_3_RST); + optr_reg2_mask |= FLASH_OPTSR2_SRAM1_3_RST; + } +#endif /* FLASH_OPTSR2_SRAM1_3_RST */ + +#if defined (FLASH_OPTSR2_SRAM1_RST) + if ((UserType & OB_USER_SRAM1_RST) != 0U) + { + /* SRAM1_RST option byte should be modified */ + assert_param(IS_OB_USER_SRAM1_RST(UserConfig2 & FLASH_OPTSR2_SRAM1_RST)); + + /* Set value and mask for SRAM1_RST option byte */ + optr_reg2_val |= (UserConfig2 & FLASH_OPTSR2_SRAM1_RST); + optr_reg2_mask |= FLASH_OPTSR2_SRAM1_RST; + } +#endif /* FLASH_OPTSR2_SRAM1_RST */ + + if ((UserType & OB_USER_SRAM2_RST) != 0U) + { + /* SRAM2_RST option byte should be modified */ + assert_param(IS_OB_USER_SRAM2_RST(UserConfig2 & FLASH_OPTSR2_SRAM2_RST)); + + /* Set value and mask for SRAM2_RST option byte */ + optr_reg2_val |= (UserConfig2 & FLASH_OPTSR2_SRAM2_RST); + optr_reg2_mask |= FLASH_OPTSR2_SRAM2_RST; + } + + if ((UserType & OB_USER_BKPRAM_ECC) != 0U) + { + /* BKPRAM_ECC option byte should be modified */ + assert_param(IS_OB_USER_BKPRAM_ECC(UserConfig2 & FLASH_OPTSR2_BKPRAM_ECC)); + + /* Set value and mask for BKPRAM_ECC option byte */ + optr_reg2_val |= (UserConfig2 & FLASH_OPTSR2_BKPRAM_ECC); + optr_reg2_mask |= FLASH_OPTSR2_BKPRAM_ECC; + } + +#if defined (FLASH_OPTSR2_SRAM3_ECC) + if ((UserType & OB_USER_SRAM3_ECC) != 0U) + { + /* SRAM3_ECC option byte should be modified */ + assert_param(IS_OB_USER_SRAM3_ECC(UserConfig2 & FLASH_OPTSR2_SRAM3_ECC)); + + /* Set value and mask for SRAM3_ECC option byte */ + optr_reg2_val |= (UserConfig2 & FLASH_OPTSR2_SRAM3_ECC); + optr_reg2_mask |= FLASH_OPTSR2_SRAM3_ECC; + } +#endif /* FLASH_OPTSR2_SRAM3_ECC */ + + if ((UserType & OB_USER_SRAM2_ECC) != 0U) + { + /* SRAM2_ECC option byte should be modified */ + assert_param(IS_OB_USER_SRAM2_ECC(UserConfig2 & FLASH_OPTSR2_SRAM2_ECC)); + + /* Set value and mask for SRAM2_ECC option byte */ + optr_reg2_val |= (UserConfig2 & FLASH_OPTSR2_SRAM2_ECC); + optr_reg2_mask |= FLASH_OPTSR2_SRAM2_ECC; + } + +#if defined (FLASH_OPTSR2_SRAM1_ECC) + if ((UserType & OB_USER_SRAM1_ECC) != 0U) + { + /* SRAM2_ECC option byte should be modified */ + assert_param(IS_OB_USER_SRAM1_ECC(UserConfig2 & FLASH_OPTSR2_SRAM1_ECC)); + + /* Set value and mask for SRAM2_ECC option byte */ + optr_reg2_val |= (UserConfig2 & FLASH_OPTSR2_SRAM1_ECC); + optr_reg2_mask |= FLASH_OPTSR2_SRAM1_ECC; + } +#endif /* FLASH_OPTSR2_SRAM1_ECC */ + +#if defined (FLASH_OPTSR2_TZEN) + if ((UserType & OB_USER_TZEN) != 0U) + { + /* TZEN option byte should be modified */ + assert_param(IS_OB_USER_TZEN(UserConfig2 & FLASH_OPTSR2_TZEN)); + + /* Set value and mask for TZEN option byte */ + optr_reg2_val |= (UserConfig2 & FLASH_OPTSR2_TZEN); + optr_reg2_mask |= FLASH_OPTSR2_TZEN; + } +#endif /* FLASH_OPTSR2_TZEN */ + + /* Check to write first User OB register or/and second one */ + if ((UserType & 0xFFFU) != 0U) + { + /* Configure the option bytes register */ + MODIFY_REG(FLASH->OPTSR_PRG, optr_reg1_mask, optr_reg1_val); + } + if ((UserType & 0xFF000U) != 0U) + { + /* Configure the option bytes register */ + MODIFY_REG(FLASH->OPTSR2_PRG, optr_reg2_mask, optr_reg2_val); + } +} + +/** + * @brief Return the FLASH User Option Byte values. + * @param UserConfig1 FLASH User Option Bytes values + * 2M: IWDG_SW(Bit3), WWDG_SW(Bit4), nRST_STOP(Bit 6), nRST_STDY(Bit 7), + * PRODUCT_STATE(Bit[8:15]), IO_VDD_HSLV(Bit 16), IO_VDDTO2_HSLV(Bit 17), + * IWDG_STOP(Bit 20), IWDG_STDBY (Bit 21), BOOT_UBE(Bit[22:29]) and SWAP_BANK(Bit 31). + * 128K: IWDG_SW(Bit3), WWDG_SW(Bit4), nRST_STOP(Bit 6), nRST_STDY(Bit 7), + * PRODUCT_STATE(Bit[8:15]), IO_VDD_HSLV(Bit16), IO_VDDIO2_HSLV(Bit17), IWDG_STOP(Bit 20), + * IWDG_STDBY (Bit 21) and SWAP_BANK(Bit 31). + * @param UserConfig2 FLASH User Option Bytes values + * 2M: SRAM1_3_RST(Bit2), SRAM2_RST(Bit 3), BKPRAM_ECC(Bit 4), SRAM3_ECC(Bit 5), + * SRAM2_ECC(Bit 6). + * 128K: SRAM2_RST(Bit 3), BKPRAM_ECC(Bit 4), SRAM2_ECC(Bit 6), + * SRAM1_RST(Bit9), SRAM1_ECC(Bit10). + * @retval None + */ +static void FLASH_OB_GetUser(uint32_t *UserConfig1, uint32_t *UserConfig2) +{ + (*UserConfig1) = FLASH->OPTSR_CUR & (~FLASH_OPTSR_PRODUCT_STATE); + + (*UserConfig2) = FLASH->OPTSR2_CUR; +} + +/** + * @brief Configure Boot address + * @param BootOption specifies the Boot address option byte to be programmed. + * This parameter can be one of the following values: + * @arg OB_BOOTADDR_NS: Non-secure boot address + * @arg OB_BOOTADDR_SEC: Secure boot address + * @param BootAddress: specifies the boot address value + * This parameter can be sector number between 0 and 0xFFFFFF00 + * @retval None + */ +static void FLASH_OB_BootAddrConfig(uint32_t BootOption, uint32_t BootAddress) +{ + /* Check the parameters */ + assert_param(IS_OB_BOOT_CONFIG(BootOption)); + + if (BootOption == OB_BOOT_NS) + { + MODIFY_REG(FLASH->NSBOOTR_PRG, FLASH_BOOTR_BOOTADD, BootAddress); + } +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + else if (BootOption == OB_BOOT_SEC) + { + MODIFY_REG(FLASH->SECBOOTR_PRG, FLASH_BOOTR_BOOTADD, BootAddress); + } +#endif /* __ARM_FEATURE_CMSE */ + else + { + /* Empty statement (to be compliant MISRA 15.7) */ + } +} + +/** + * @brief Configure the boot lock. + * + * @param BootOption select the BOOT_LOCK option: secure or non-secure. + * This parameter can be one of the following values: + * @arg OB_BOOT_LOCK_SEC: Boot Lock mode deactivated + * @arg OB_BOOT_LOCK_NS: Boot Lock mode activated + * + * @param BootLockConfig specifies the activation of the BOOT_LOCK. + * This parameter can be one of the following values: + * @arg OB_BOOT_LOCK_DISABLE: Boot Lock mode deactivated + * @arg OB_BOOT_LOCK_ENABLE: Boot Lock mode activated + * + * @retval None + */ +static void FLASH_OB_BootLockConfig(uint32_t BootOption, uint32_t BootLockConfig) +{ + /* Check the parameters */ + assert_param(IS_OB_BOOT_CONFIG(BootOption)); + assert_param(IS_OB_BOOT_LOCK(BootLockConfig)); + + /* Configure the option bytes register */ + if (BootOption == OB_BOOT_NS) + { + MODIFY_REG(FLASH->NSBOOTR_PRG, FLASH_BOOTR_BOOT_LOCK, BootLockConfig); + } +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + else if (BootOption == OB_BOOT_SEC) + { + MODIFY_REG(FLASH->SECBOOTR_PRG, FLASH_BOOTR_BOOT_LOCK, BootLockConfig); + } +#endif /* __ARM_FEATURE_CMSE */ + else + { + /* Empty statement (to be compliant MISRA 15.7) */ + } +} + +/** + * @brief Get the boot configuration + * @param[in] BootOption specifies the boot address option byte to be returned. + * This parameter can be one of the following values: + * @arg OB_BOOT_NS: Non-secure boot address + * @arg OB_BOOT_SEC: Secure boot address + * + * @param[out] BootAddress specifies the boot address value + * + * @param[out] BootLockConfig returns the activation of the BOOT_LOCK. + * This parameter can be one of the following values: + * @arg OB_BOOT_LOCK_DISABLE: Boot Lock mode deactivated + * @arg OB_BOOT_LOCK_ENABLE: Boot Lock mode activated + * @retval None + */ +static void FLASH_OB_GetBootConfig(uint32_t BootOption, uint32_t *BootAddress, uint32_t *BootLockConfig) +{ + if (BootOption == OB_BOOT_NS) + { + *BootAddress = FLASH->NSBOOTR_CUR & FLASH_BOOTR_BOOTADD; + *BootLockConfig = FLASH->NSBOOTR_CUR & FLASH_BOOTR_BOOT_LOCK; + } +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + else if (BootOption == OB_BOOT_SEC) + { + *BootAddress = (FLASH->SECBOOTR_CUR & FLASH_BOOTR_BOOTADD); + *BootLockConfig = (FLASH->SECBOOTR_CUR & FLASH_BOOTR_BOOT_LOCK); + } +#endif /* __ARM_FEATURE_CMSE */ + else + { + /* Empty statement (to be compliant MISRA 15.7) */ + } +} + +/** + * @brief Configure the OTP Block Lock. + * @param OTP_Block specifies the OTP Block to lock. + * This parameter can be a value of @ref FLASH_OTP_Blocks + * @retval None + */ +static void FLASH_OB_OTP_LockConfig(uint32_t OTP_Block) +{ + /* Configure the OTP Block lock in the option bytes register */ + FLASH->OTPBLR_PRG |= OTP_Block; +} + +/** + * @brief Get the OTP Block Lock. + * @retval OTP_Block specifies the OTP Block to lock. + * This return value can be a value of @ref FLASH_OTP_Blocks + */ +static uint32_t FLASH_OB_OTP_GetLock(void) +{ + return (FLASH->OTPBLR_CUR); +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Configure the watermark-based secure area. + * + * @param Banks specifies the bank where to apply Watermark protection + * This parameter can be one of the following values: + * @arg FLASH_BANK_1: configure Watermark on bank1 + * @arg FLASH_BANK_2: configure Watermark on bank2 + * @arg FLASH_BANK_BOTH: configure Watermark on both bank1 and bank2 + * + * @param WMSecStartSector specifies the start sector of the secure area + * This parameter can be sector number between 0 and (max number of sectors in the bank - 1) + * + * @param WMSecEndSector specifies the end sector of the secure area + * This parameter can be sector number between WMSecStartSector and WMSecEndSector(max number of sectors + * in the bank - 1) + * + * @retval None + */ +static void FLASH_OB_WMSECConfig(uint32_t Banks, uint32_t WMSecStartSector, uint32_t WMSecEndSector) +{ + /* Check the parameters */ + assert_param(IS_FLASH_BANK(Banks)); + assert_param(IS_FLASH_SECTOR(WMSecStartSector)); + assert_param(IS_FLASH_SECTOR(WMSecEndSector)); + + /* Write SECWM registers */ + if ((Banks & FLASH_BANK_1) == FLASH_BANK_1) + { + /* Configure Watermark Protection for bank 1 */ + FLASH->SECWM1R_PRG = ((WMSecEndSector << FLASH_SECWMR_SECWM_END_Pos) | WMSecStartSector); + } + + if ((Banks & FLASH_BANK_2) == FLASH_BANK_2) + { + /* Configure Watermark Protection for bank 2 */ + FLASH->SECWM2R_PRG = ((WMSecEndSector << FLASH_SECWMR_SECWM_END_Pos) | WMSecStartSector); + } +} + +/** + * @brief Return the watermark-based secure area configuration. + * + * @param Bank [in] specifies the bank where to get the watermark protection. + * This parameter can be exclusively one of the following values: + * @arg FLASH_BANK_1: Get bank1 watermark configuration + * @arg FLASH_BANK_2: Get bank2 watermark configuration + * + * @param WMSecStartSector [out] specifies the start sector of the secure area + * + * @param WMSecEndSector [out] specifies the end sector of the secure area + * + * @retval None + */ +static void FLASH_OB_GetWMSEC(uint32_t Bank, uint32_t *WMSecStartSector, uint32_t *WMSecEndSector) +{ + uint32_t regvalue = 0U; + + /* Read SECWM register */ + if (Bank == FLASH_BANK_1) + { + regvalue = FLASH->SECWM1R_CUR; + } + + if (Bank == FLASH_BANK_2) + { + regvalue = FLASH->SECWM2R_CUR; + } + + /* Get configuration of secure area */ + *WMSecStartSector = (regvalue & FLASH_SECWMR_SECWM_STRT); + *WMSecEndSector = ((regvalue & FLASH_SECWMR_SECWM_END) >> FLASH_SECWMR_SECWM_END_Pos); +} +#endif /* __ARM_FEATURE_CMSE */ + +/** + * @brief Configure the hide protection area. + * + * @param Banks specifies the bank where to apply hide protection + * This parameter can be one of the following values: + * @arg FLASH_BANK_1: configure HDP on bank1 + * @arg FLASH_BANK_2: configure HDP on bank2 + * @arg FLASH_BANK_BOTH: configure HDP on both bank1 and bank2 + * + * @param HDPStartSector specifies the start sector of the hide protection area + * This parameter can be sector number between 0 and (max number of sectors in the bank - 1) + * + * @param HDPEndSector specifies the end sector of the hide protection area + * This parameter can be sector number between HDPStartSector and HDPEndSector (max number of sectors + * in the bank - 1) + * + * @retval None + */ +static void FLASH_OB_HDPConfig(uint32_t Banks, uint32_t HDPStartSector, uint32_t HDPEndSector) +{ + /* Check the parameters */ + assert_param(IS_FLASH_BANK(Banks)); + assert_param(IS_FLASH_SECTOR(HDPStartSector)); + assert_param(IS_FLASH_SECTOR(HDPEndSector)); + + /* Write HDP registers */ + if ((Banks & FLASH_BANK_1) == FLASH_BANK_1) + { + /* Configure hide Protection for bank 1 */ + FLASH->HDP1R_PRG = ((HDPEndSector << FLASH_HDPR_HDP_END_Pos) | HDPStartSector); + } + + if ((Banks & FLASH_BANK_2) == FLASH_BANK_2) + { + /* Configure hide Protection for bank 2 */ + FLASH->HDP2R_PRG = ((HDPEndSector << FLASH_HDPR_HDP_END_Pos) | HDPStartSector); + } +} + +/** + * @brief Return the hide protection area configuration. + * + * @param Bank [in] specifies the bank where to get the HDP protection. + * This parameter can be exclusively one of the following values: + * @arg FLASH_BANK_1: Get bank1 HDP configuration + * @arg FLASH_BANK_2: Get bank2 HDP configuration + * + * @param HDPStartSector [out] specifies the start sector of the HDP area + * + * @param HDPEndSector [out] specifies the end sector of the HDP area + * + * @retval None + */ +static void FLASH_OB_GetHDP(uint32_t Bank, uint32_t *HDPStartSector, uint32_t *HDPEndSector) +{ + uint32_t regvalue = 0U; + + /* Read SECWM register */ + if (Bank == FLASH_BANK_1) + { + regvalue = FLASH->HDP1R_CUR; + } + + if (Bank == FLASH_BANK_2) + { + regvalue = FLASH->HDP2R_CUR; + } + + /* Get configuration of HDP area */ + *HDPStartSector = (regvalue & FLASH_HDPR_HDP_STRT); + *HDPEndSector = ((regvalue & FLASH_HDPR_HDP_END) >> FLASH_HDPR_HDP_END_Pos); +} + +#if defined(FLASH_EDATAR_EDATA_EN) +/** + * @brief Configure the Flash high-cycle area. + * + * @param Banks specifies the bank where to apply Flash high-cycle data area + * This parameter can be one of the following values: + * @arg FLASH_BANK_1: configure Flash high-cycle area on bank1 + * @arg FLASH_BANK_2: configure Flash high-cycle area on bank2 + * @arg FLASH_BANK_BOTH: configure Flash high-cycle area on both bank1 and bank2 + * + * @param EDATASize specifies the size (in sectors) of the Flash high-cycle data area + * This parameter can be sectors number between 0 and 8 + * + * @retval None + */ +static void FLASH_OB_EDATAConfig(uint32_t Banks, uint32_t EDATASize) +{ + /* Check the parameters */ + assert_param(IS_FLASH_BANK(Banks)); + assert_param(IS_FLASH_EDATA_SIZE(EDATASize)); + + if (EDATASize != 0U) + { + /* Write EDATA registers */ + if ((Banks & FLASH_BANK_1) == FLASH_BANK_1) + { + /* Configure Flash high-cycle data for bank 1 */ + FLASH->EDATA1R_PRG = (FLASH_EDATAR_EDATA_EN | (EDATASize - 1U)); + } + + if ((Banks & FLASH_BANK_2) == FLASH_BANK_2) + { + /* Configure Flash high-cycle data for bank 2 */ + FLASH->EDATA2R_PRG = (FLASH_EDATAR_EDATA_EN | (EDATASize - 1U)); + } + } + else + { + /* Write EDATA registers */ + if ((Banks & FLASH_BANK_1) == FLASH_BANK_1) + { + /* de-activate Flash high-cycle data for bank 1 */ + FLASH->EDATA1R_PRG = 0U; + } + + if ((Banks & FLASH_BANK_2) == FLASH_BANK_2) + { + /* de-activate Flash high-cycle data for bank 2 */ + FLASH->EDATA2R_PRG = 0U; + } + } +} + +/** + * @brief Return the Flash high-cycle data area configuration. + * + * @param Bank [in] specifies the bank where to get the Flash high-cycle data configuration. + * This parameter can be exclusively one of the following values: + * @arg FLASH_BANK_1: Get bank1 Flash high-cycle data configuration + * @arg FLASH_BANK_2: Get bank2 Flash high-cycle data configuration + * + * @param EDATASize [out] specifies the size (in sectors) of the Flash high-cycle data area + * + * @retval None + */ +static void FLASH_OB_GetEDATA(uint32_t Bank, uint32_t *EDATASize) +{ + uint32_t regvalue = 0U; + + /* Read SECWM register */ + if (Bank == FLASH_BANK_1) + { + regvalue = FLASH->EDATA1R_CUR; + } + + if (Bank == FLASH_BANK_2) + { + regvalue = FLASH->EDATA2R_CUR; + } + + /* Get configuration of secure area */ + *EDATASize = (regvalue & FLASH_EDATAR_EDATA_STRT); +} +#endif /* FLASH_EDATAR_EDATA_EN */ + +/** + * @} + */ + +#endif /* HAL_FLASH_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_fmac.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_fmac.c new file mode 100644 index 0000000000..6f9a6900dd --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_fmac.c @@ -0,0 +1,2725 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_fmac.c + * @author MCD Application Team + * @brief FMAC HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the FMAC peripheral: + * + Initialization and de-initialization functions + * + Peripheral Control functions + * + Callback functions + * + IRQ handler management + * + Peripheral State and Error functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + * + * @verbatim +================================================================================ + ##### How to use this driver ##### +================================================================================ + [..] + The FMAC HAL driver can be used as follows: + + (#) Initialize the FMAC low level resources by implementing the HAL_FMAC_MspInit(): + (++) Enable the FMAC interface clock using __HAL_RCC_FMAC_CLK_ENABLE(). + (++) In case of using interrupts (e.g. access configured as FMAC_BUFFER_ACCESS_IT): + (+++) Configure the FMAC interrupt priority using HAL_NVIC_SetPriority(). + (+++) Enable the FMAC IRQ handler using HAL_NVIC_EnableIRQ(). + (+++) In FMAC IRQ handler, call HAL_FMAC_IRQHandler(). + (++) In case of using DMA to control data transfer (e.g. access configured + as FMAC_BUFFER_ACCESS_DMA): + (+++) Enable the DMA interface clock using __HAL_RCC_DMA1_CLK_ENABLE() + or __HAL_RCC_DMA2_CLK_ENABLE() depending on the used DMA instance. + (+++) Enable the DMAMUX1 interface clock using __HAL_RCC_DMAMUX1_CLK_ENABLE(). + (+++) If the initialization of the internal buffers (coefficients, input, + output) is done via DMA, configure and enable one DMA channel for + managing data transfer from memory to memory (preload channel). + (+++) If the input buffer is accessed via DMA, configure and enable one + DMA channel for managing data transfer from memory to peripheral + (input channel). + (+++) If the output buffer is accessed via DMA, configure and enable + one DMA channel for managing data transfer from peripheral to + memory (output channel). + (+++) Associate the initialized DMA handle(s) to the FMAC DMA handle(s) + using __HAL_LINKDMA(). + (+++) Configure the priority and enable the NVIC for the transfer complete + interrupt on the enabled DMA channel(s) using HAL_NVIC_SetPriority() + and HAL_NVIC_EnableIRQ(). + + (#) Initialize the FMAC HAL using HAL_FMAC_Init(). This function + resorts to HAL_FMAC_MspInit() for low-level initialization. + + (#) Configure the FMAC processing (filter) using HAL_FMAC_FilterConfig() + or HAL_FMAC_FilterConfig_DMA(). + This function: + (++) Defines the memory area within the FMAC internal memory + (input, coefficients, output) and the associated threshold (input, output). + (++) Configures the filter and its parameters: + (+++) Finite Impulse Response (FIR) filter (also known as convolution). + (+++) Infinite Impulse Response (IIR) filter (direct form 1). + (++) Choose the way to access to the input and output buffers: none, polling, + DMA, IT. "none" means the input and/or output data will be handled by + another IP (ADC, DAC, etc.). + (++) Enable the error interruptions in the input access and/or the output + access is done through IT/DMA. If an error occurs, the interruption + will be triggered in loop. In order to recover, the user will have + to reset the IP with the sequence HAL_FMAC_DeInit / HAL_FMAC_Init. + Optionally, he can also disable the interrupt using __HAL_FMAC_DISABLE_IT; + the error status will be kept, but no more interrupt will be triggered. + (++) Write the provided coefficients into the internal memory using polling + mode ( HAL_FMAC_FilterConfig() ) or DMA ( HAL_FMAC_FilterConfig_DMA() ). + In the DMA case, HAL_FMAC_FilterConfigCallback() is called when + the handling is over. + + (#) Optionally, the user can enable the error interruption related to + saturation by calling __HAL_FMAC_ENABLE_IT. This helps in debugging the + filter. If a saturation occurs, the interruption will be triggered in loop. + In order to recover, the user will have to: + (++) Disable the interruption by calling __HAL_FMAC_DISABLE_IT if + the user wishes to continue all the same. + (++) Reset the IP with the sequence HAL_FMAC_DeInit / HAL_FMAC_Init. + + (#) Optionally, preload input (FIR, IIR) and output (IIR) data using + HAL_FMAC_FilterPreload() or HAL_FMAC_FilterPreload_DMA(). + In the DMA case, HAL_FMAC_FilterPreloadCallback() is called when + the handling is over. + This step is optional as the filter can be started without preloaded + data. + + (#) Start the FMAC processing (filter) using HAL_FMAC_FilterStart(). + This function also configures the output buffer that will be filled from + the circular internal output buffer. The function returns immediately + without updating the provided buffer. The IP processing will be active until + HAL_FMAC_FilterStop() is called. + + (#) If the input internal buffer is accessed via DMA, HAL_FMAC_HalfGetDataCallback() + will be called to indicate that half of the input buffer has been handled. + + (#) If the input internal buffer is accessed via DMA or interrupt, HAL_FMAC_GetDataCallback() + will be called to require new input data. It will be provided through + HAL_FMAC_AppendFilterData() if the DMA isn't in circular mode. + + (#) If the output internal buffer is accessed via DMA, HAL_FMAC_HalfOutputDataReadyCallback() + will be called to indicate that half of the output buffer has been handled. + + (#) If the output internal buffer is accessed via DMA or interrupt, + HAL_FMAC_OutputDataReadyCallback() will be called to require a new output + buffer. It will be provided through HAL_FMAC_ConfigFilterOutputBuffer() + if the DMA isn't in circular mode. + + (#) In all modes except none, provide new input data to be processed via HAL_FMAC_AppendFilterData(). + This function should only be called once the previous input data has been handled + (the preloaded input data isn't concerned). + + (#) In all modes except none, provide a new output buffer to be filled via + HAL_FMAC_ConfigFilterOutputBuffer(). This function should only be called once the previous + user's output buffer has been filled. + + (#) In polling mode, handle the input and output data using HAL_FMAC_PollFilterData(). + This function: + (++) Write the user's input data (provided via HAL_FMAC_AppendFilterData()) + into the FMAC input memory area. + (++) Read the FMAC output memory area and write it into the user's output buffer. + It will return either when: + (++) the user's output buffer is filled. + (++) the user's input buffer has been handled. + The unused data (unread input data or free output data) will not be saved. + The user will have to use the updated input and output sizes to keep track + of them. + + (#) Stop the FMAC processing (filter) using HAL_FMAC_FilterStop(). + + (#) Call HAL_FMAC_DeInit() to de-initialize the FMAC peripheral. This function + resorts to HAL_FMAC_MspDeInit() for low-level de-initialization. + + ##### Callback registration ##### + ================================== + + [..] + The compilation define USE_HAL_FMAC_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + + [..] + Use Function HAL_FMAC_RegisterCallback() to register a user callback. + Function HAL_FMAC_RegisterCallback() allows to register following callbacks: + (+) ErrorCallback : Error Callback. + (+) HalfGetDataCallback : Get Half Data Callback. + (+) GetDataCallback : Get Data Callback. + (+) HalfOutputDataReadyCallback : Half Output Data Ready Callback. + (+) OutputDataReadyCallback : Output Data Ready Callback. + (+) FilterConfigCallback : Filter Configuration Callback. + (+) FilterPreloadCallback : Filter Preload Callback. + (+) MspInitCallback : FMAC MspInit. + (+) MspDeInitCallback : FMAC MspDeInit. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + + [..] + Use function HAL_FMAC_UnRegisterCallback() to reset a callback to the default + weak (surcharged) function. + HAL_FMAC_UnRegisterCallback() takes as parameters the HAL peripheral handle + and the Callback ID. + This function allows to reset following callbacks: + (+) ErrorCallback : Error Callback. + (+) HalfGetDataCallback : Get Half Data Callback. + (+) GetDataCallback : Get Data Callback. + (+) HalfOutputDataReadyCallback : Half Output Data Ready Callback. + (+) OutputDataReadyCallback : Output Data Ready Callback. + (+) FilterConfigCallback : Filter Configuration Callback. + (+) FilterPreloadCallback : Filter Preload Callback. + (+) MspInitCallback : FMAC MspInit. + (+) MspDeInitCallback : FMAC MspDeInit. + + [..] + By default, after the HAL_FMAC_Init() and when the state is HAL_FMAC_STATE_RESET + all callbacks are set to the corresponding weak (surcharged) functions: + examples GetDataCallback(), OutputDataReadyCallback(). + Exception done for MspInit and MspDeInit functions that are respectively + reset to the legacy weak (surcharged) functions in the HAL_FMAC_Init() + and HAL_FMAC_DeInit() only when these callbacks are null (not registered beforehand). + If not, MspInit or MspDeInit are not null, the HAL_FMAC_Init() and HAL_FMAC_DeInit() + keep and use the user MspInit/MspDeInit callbacks (registered beforehand). + + [..] + Callbacks can be registered/unregistered in HAL_FMAC_STATE_READY state only. + Exception done MspInit/MspDeInit that can be registered/unregistered + in HAL_FMAC_STATE_READY or HAL_FMAC_STATE_RESET state, thus registered (user) + MspInit/DeInit callbacks can be used during the Init/DeInit. + In that case first register the MspInit/MspDeInit user callbacks + using HAL_FMAC_RegisterCallback() before calling HAL_FMAC_DeInit() + or HAL_FMAC_Init() function. + + [..] + When the compilation define USE_HAL_FMAC_REGISTER_CALLBACKS is set to 0 or + not defined, the callback registration feature is not available + and weak (surcharged) callbacks are used. + + + @endverbatim + * + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +#if defined(FMAC) +#ifdef HAL_FMAC_MODULE_ENABLED + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup FMAC FMAC + * @brief FMAC HAL driver module + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ +/** @defgroup FMAC_Private_Constants FMAC Private Constants + * @{ + */ + +#define MAX_FILTER_DATA_SIZE_TO_HANDLE ((uint16_t) 0xFFU) +#define MAX_PRELOAD_INDEX 0xFFU +#define PRELOAD_ACCESS_DMA 0x00U +#define PRELOAD_ACCESS_POLLING 0x01U +#define POLLING_DISABLED 0U +#define POLLING_ENABLED 1U +#define POLLING_NOT_STOPPED 0U +#define POLLING_STOPPED 1U +/* FMAC polling-based communications time-out value */ +#define HAL_FMAC_TIMEOUT_VALUE 1000U +/* FMAC reset time-out value */ +#define HAL_FMAC_RESET_TIMEOUT_VALUE 500U +/* DMA Read Requests Enable */ +#define FMAC_DMA_REN FMAC_CR_DMAREN +/* DMA Write Channel Enable */ +#define FMAC_DMA_WEN FMAC_CR_DMAWEN +/* FMAC Execution Enable */ +#define FMAC_START FMAC_PARAM_START + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup FMAC_Private_Macros FMAC Private Macros + * @{ + */ + +/** + * @brief Get the X1 memory area size. + * @param __HANDLE__ FMAC handle. + * @retval X1_BUF_SIZE + */ +#define FMAC_GET_X1_SIZE(__HANDLE__) \ + ((((__HANDLE__)->Instance->X1BUFCFG) & (FMAC_X1BUFCFG_X1_BUF_SIZE)) >> (FMAC_X1BUFCFG_X1_BUF_SIZE_Pos)) + +/** + * @brief Get the X1 watermark. + * @param __HANDLE__ FMAC handle. + * @retval FULL_WM + */ +#define FMAC_GET_X1_FULL_WM(__HANDLE__) \ + (((__HANDLE__)->Instance->X1BUFCFG) & (FMAC_X1BUFCFG_FULL_WM)) + +/** + * @brief Get the X2 memory area size. + * @param __HANDLE__ FMAC handle. + * @retval X2_BUF_SIZE + */ +#define FMAC_GET_X2_SIZE(__HANDLE__) \ + ((((__HANDLE__)->Instance->X2BUFCFG) & (FMAC_X2BUFCFG_X2_BUF_SIZE)) >> (FMAC_X2BUFCFG_X2_BUF_SIZE_Pos)) + +/** + * @brief Get the Y memory area size. + * @param __HANDLE__ FMAC handle. + * @retval Y_BUF_SIZE + */ +#define FMAC_GET_Y_SIZE(__HANDLE__) \ + ((((__HANDLE__)->Instance->YBUFCFG) & (FMAC_YBUFCFG_Y_BUF_SIZE)) >> (FMAC_YBUFCFG_Y_BUF_SIZE_Pos)) + +/** + * @brief Get the Y watermark. + * @param __HANDLE__ FMAC handle. + * @retval EMPTY_WM + */ +#define FMAC_GET_Y_EMPTY_WM(__HANDLE__) \ + (((__HANDLE__)->Instance->YBUFCFG) & (FMAC_YBUFCFG_EMPTY_WM)) + +/** + * @brief Get the start bit state. + * @param __HANDLE__ FMAC handle. + * @retval START + */ +#define FMAC_GET_START_BIT(__HANDLE__) \ + ((((__HANDLE__)->Instance->PARAM) & (FMAC_PARAM_START)) >> (FMAC_PARAM_START_Pos)) + +/** + * @brief Get the threshold matching the watermark. + * @param __WM__ Watermark value. + * @retval THRESHOLD + */ +#define FMAC_GET_THRESHOLD_FROM_WM(__WM__) (((__WM__) == FMAC_THRESHOLD_1)? 1U: \ + ((__WM__) == FMAC_THRESHOLD_2)? 2U: \ + ((__WM__) == FMAC_THRESHOLD_4)? 4U:8U) + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/* Global variables ----------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ + +static HAL_StatusTypeDef FMAC_Reset(FMAC_HandleTypeDef *hfmac); +static void FMAC_ResetDataPointers(FMAC_HandleTypeDef *hfmac); +static void FMAC_ResetOutputStateAndDataPointers(FMAC_HandleTypeDef *hfmac); +static void FMAC_ResetInputStateAndDataPointers(FMAC_HandleTypeDef *hfmac); +static HAL_StatusTypeDef FMAC_FilterConfig(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *pConfig, + uint8_t PreloadAccess); +static HAL_StatusTypeDef FMAC_FilterPreload(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize, + int16_t *pOutput, uint8_t OutputSize, uint8_t PreloadAccess); +static void FMAC_WritePreloadDataIncrementPtr(FMAC_HandleTypeDef *hfmac, int16_t **ppData, uint8_t Size); +static HAL_StatusTypeDef FMAC_WaitOnStartUntilTimeout(FMAC_HandleTypeDef *hfmac, uint32_t Tickstart, uint32_t Timeout); +static HAL_StatusTypeDef FMAC_AppendFilterDataUpdateState(FMAC_HandleTypeDef *hfmac, int16_t *pInput, + uint16_t *pInputSize); +static HAL_StatusTypeDef FMAC_ConfigFilterOutputBufferUpdateState(FMAC_HandleTypeDef *hfmac, int16_t *pOutput, + uint16_t *pOutputSize); +static void FMAC_WriteDataIncrementPtr(FMAC_HandleTypeDef *hfmac, uint16_t MaxSizeToWrite); +static void FMAC_ReadDataIncrementPtr(FMAC_HandleTypeDef *hfmac, uint16_t MaxSizeToRead); +static void FMAC_DMAHalfGetData(DMA_HandleTypeDef *hdma); +static void FMAC_DMAGetData(DMA_HandleTypeDef *hdma); +static void FMAC_DMAHalfOutputDataReady(DMA_HandleTypeDef *hdma); +static void FMAC_DMAOutputDataReady(DMA_HandleTypeDef *hdma); +static void FMAC_DMAFilterConfig(DMA_HandleTypeDef *hdma); +static void FMAC_DMAFilterPreload(DMA_HandleTypeDef *hdma); +static void FMAC_DMAError(DMA_HandleTypeDef *hdma); + +/* Functions Definition ------------------------------------------------------*/ + +/** @defgroup FMAC_Exported_Functions FMAC Exported Functions + * @{ + */ + +/** @defgroup FMAC_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 the FMAC peripheral and the associated handle + (+) DeInitialize the FMAC peripheral + (+) Initialize the FMAC MSP (MCU Specific Package) + (+) De-Initialize the FMAC MSP + (+) Register a User FMAC Callback + (+) Unregister a FMAC CallBack + + [..] + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the FMAC peripheral and the associated handle. + * @param hfmac pointer to a FMAC_HandleTypeDef structure. + * @retval HAL_StatusTypeDef HAL status + */ +HAL_StatusTypeDef HAL_FMAC_Init(FMAC_HandleTypeDef *hfmac) +{ + HAL_StatusTypeDef status; + + /* Check the FMAC handle allocation */ + if (hfmac == NULL) + { + return HAL_ERROR; + } + + /* Check the instance */ + assert_param(IS_FMAC_ALL_INSTANCE(hfmac->Instance)); + + if (hfmac->State == HAL_FMAC_STATE_RESET) + { + /* Initialize lock resource */ + hfmac->Lock = HAL_UNLOCKED; + +#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) + /* Register the default callback functions */ + hfmac->ErrorCallback = HAL_FMAC_ErrorCallback; + hfmac->HalfGetDataCallback = HAL_FMAC_HalfGetDataCallback; + hfmac->GetDataCallback = HAL_FMAC_GetDataCallback; + hfmac->HalfOutputDataReadyCallback = HAL_FMAC_HalfOutputDataReadyCallback; + hfmac->OutputDataReadyCallback = HAL_FMAC_OutputDataReadyCallback; + hfmac->FilterConfigCallback = HAL_FMAC_FilterConfigCallback; + hfmac->FilterPreloadCallback = HAL_FMAC_FilterPreloadCallback; + + if (hfmac->MspInitCallback == NULL) + { + hfmac->MspInitCallback = HAL_FMAC_MspInit; + } + + /* Init the low level hardware */ + hfmac->MspInitCallback(hfmac); +#else + /* Init the low level hardware */ + HAL_FMAC_MspInit(hfmac); +#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ + } + + /* Reset pInput and pOutput */ + hfmac->FilterParam = 0U; + FMAC_ResetDataPointers(hfmac); + + /* Reset FMAC unit (internal pointers) */ + if (FMAC_Reset(hfmac) == HAL_ERROR) + { + /* Update FMAC error code and FMAC peripheral state */ + hfmac->ErrorCode |= HAL_FMAC_ERROR_RESET; + hfmac->State = HAL_FMAC_STATE_TIMEOUT; + + status = HAL_ERROR; + } + else + { + /* Update FMAC error code and FMAC peripheral state */ + hfmac->ErrorCode = HAL_FMAC_ERROR_NONE; + hfmac->State = HAL_FMAC_STATE_READY; + + status = HAL_OK; + } + + __HAL_UNLOCK(hfmac); + + return status; +} + +/** + * @brief De-initialize the FMAC peripheral. + * @param hfmac pointer to a FMAC structure. + * @retval HAL_StatusTypeDef HAL status + */ +HAL_StatusTypeDef HAL_FMAC_DeInit(FMAC_HandleTypeDef *hfmac) +{ + /* Check the FMAC handle allocation */ + if (hfmac == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_FMAC_ALL_INSTANCE(hfmac->Instance)); + + /* Change FMAC peripheral state */ + hfmac->State = HAL_FMAC_STATE_BUSY; + + /* Set FMAC error code to none */ + hfmac->ErrorCode = HAL_FMAC_ERROR_NONE; + + /* Reset pInput and pOutput */ + hfmac->FilterParam = 0U; + FMAC_ResetDataPointers(hfmac); + +#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) + if (hfmac->MspDeInitCallback == NULL) + { + hfmac->MspDeInitCallback = HAL_FMAC_MspDeInit; + } + /* DeInit the low level hardware */ + hfmac->MspDeInitCallback(hfmac); +#else + /* DeInit the low level hardware: CLOCK, NVIC, DMA */ + HAL_FMAC_MspDeInit(hfmac); +#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ + + /* Change FMAC peripheral state */ + hfmac->State = HAL_FMAC_STATE_RESET; + + /* Always release Lock in case of de-initialization */ + __HAL_UNLOCK(hfmac); + + return HAL_OK; +} + +/** + * @brief Initialize the FMAC MSP. + * @param hfmac FMAC handle. + * @retval None + */ +__weak void HAL_FMAC_MspInit(FMAC_HandleTypeDef *hfmac) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hfmac); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_FMAC_MspInit can be implemented in the user file + */ +} + +/** + * @brief De-initialize the FMAC MSP. + * @param hfmac FMAC handle. + * @retval None + */ +__weak void HAL_FMAC_MspDeInit(FMAC_HandleTypeDef *hfmac) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hfmac); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_FMAC_MspDeInit can be implemented in the user file + */ +} + +#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User FMAC Callback. + * @note The User FMAC Callback is to be used instead of the weak predefined callback. + * @note The HAL_FMAC_RegisterCallback() may be called before HAL_FMAC_Init() in HAL_FMAC_STATE_RESET to register + * callbacks for HAL_FMAC_MSPINIT_CB_ID and HAL_FMAC_MSPDEINIT_CB_ID. + * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains + * the configuration information for FMAC module. + * @param CallbackID ID of the callback to be registered. + * This parameter can be one of the following values: + * @arg @ref HAL_FMAC_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_FMAC_HALF_GET_DATA_CB_ID Get Half Data Callback ID + * @arg @ref HAL_FMAC_GET_DATA_CB_ID Get Data Callback ID + * @arg @ref HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID Half Output Data Ready Callback ID + * @arg @ref HAL_FMAC_OUTPUT_DATA_READY_CB_ID Output Data Ready Callback ID + * @arg @ref HAL_FMAC_FILTER_CONFIG_CB_ID Filter Configuration Callback ID + * @arg @ref HAL_FMAC_FILTER_PRELOAD_CB_ID Filter Preload Callback ID + * @arg @ref HAL_FMAC_MSPINIT_CB_ID FMAC MspInit ID + * @arg @ref HAL_FMAC_MSPDEINIT_CB_ID FMAC MspDeInit ID + * @param pCallback pointer to the Callback function. + * @retval HAL_StatusTypeDef HAL status + */ +HAL_StatusTypeDef HAL_FMAC_RegisterCallback(FMAC_HandleTypeDef *hfmac, HAL_FMAC_CallbackIDTypeDef CallbackID, + pFMAC_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the FMAC handle allocation */ + if (hfmac == NULL) + { + return HAL_ERROR; + } + + if (pCallback == NULL) + { + /* Update the error code */ + hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + if (hfmac->State == HAL_FMAC_STATE_READY) + { + switch (CallbackID) + { + case HAL_FMAC_ERROR_CB_ID : + hfmac->ErrorCallback = pCallback; + break; + + case HAL_FMAC_HALF_GET_DATA_CB_ID : + hfmac->HalfGetDataCallback = pCallback; + break; + + case HAL_FMAC_GET_DATA_CB_ID : + hfmac->GetDataCallback = pCallback; + break; + + case HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID : + hfmac->HalfOutputDataReadyCallback = pCallback; + break; + + case HAL_FMAC_OUTPUT_DATA_READY_CB_ID : + hfmac->OutputDataReadyCallback = pCallback; + break; + + case HAL_FMAC_FILTER_CONFIG_CB_ID : + hfmac->FilterConfigCallback = pCallback; + break; + + case HAL_FMAC_FILTER_PRELOAD_CB_ID : + hfmac->FilterPreloadCallback = pCallback; + break; + + case HAL_FMAC_MSPINIT_CB_ID : + hfmac->MspInitCallback = pCallback; + break; + + case HAL_FMAC_MSPDEINIT_CB_ID : + hfmac->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (hfmac->State == HAL_FMAC_STATE_RESET) + { + switch (CallbackID) + { + case HAL_FMAC_MSPINIT_CB_ID : + hfmac->MspInitCallback = pCallback; + break; + + case HAL_FMAC_MSPDEINIT_CB_ID : + hfmac->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister a FMAC CallBack. + * @note The FMAC callback is redirected to the weak predefined callback. + * @note The HAL_FMAC_UnRegisterCallback() may be called before HAL_FMAC_Init() in HAL_FMAC_STATE_RESET to register + * callbacks for HAL_FMAC_MSPINIT_CB_ID and HAL_FMAC_MSPDEINIT_CB_ID. + * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains + * the configuration information for FMAC module + * @param CallbackID ID of the callback to be unregistered. + * This parameter can be one of the following values: + * @arg @ref HAL_FMAC_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_FMAC_HALF_GET_DATA_CB_ID Get Half Data Callback ID + * @arg @ref HAL_FMAC_GET_DATA_CB_ID Get Data Callback ID + * @arg @ref HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID Half Output Data Ready Callback ID + * @arg @ref HAL_FMAC_OUTPUT_DATA_READY_CB_ID Output Data Ready Callback ID + * @arg @ref HAL_FMAC_FILTER_CONFIG_CB_ID Filter Configuration Callback ID + * @arg @ref HAL_FMAC_FILTER_PRELOAD_CB_ID Filter Preload Callback ID + * @arg @ref HAL_FMAC_MSPINIT_CB_ID FMAC MspInit ID + * @arg @ref HAL_FMAC_MSPDEINIT_CB_ID FMAC MspDeInit ID + * @retval HAL_StatusTypeDef HAL status + */ +HAL_StatusTypeDef HAL_FMAC_UnRegisterCallback(FMAC_HandleTypeDef *hfmac, HAL_FMAC_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the FMAC handle allocation */ + if (hfmac == NULL) + { + return HAL_ERROR; + } + + if (hfmac->State == HAL_FMAC_STATE_READY) + { + switch (CallbackID) + { + case HAL_FMAC_ERROR_CB_ID : + hfmac->ErrorCallback = HAL_FMAC_ErrorCallback; /* Legacy weak ErrorCallback */ + break; + + case HAL_FMAC_HALF_GET_DATA_CB_ID : + hfmac->HalfGetDataCallback = HAL_FMAC_HalfGetDataCallback; /* Legacy weak HalfGetDataCallback */ + break; + + case HAL_FMAC_GET_DATA_CB_ID : + hfmac->GetDataCallback = HAL_FMAC_GetDataCallback; /* Legacy weak GetDataCallback */ + break; + + case HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID : + hfmac->HalfOutputDataReadyCallback = HAL_FMAC_HalfOutputDataReadyCallback; /* Legacy weak + HalfOutputDataReadyCallback */ + break; + + case HAL_FMAC_OUTPUT_DATA_READY_CB_ID : + hfmac->OutputDataReadyCallback = HAL_FMAC_OutputDataReadyCallback; /* Legacy weak + OutputDataReadyCallback */ + break; + + case HAL_FMAC_FILTER_CONFIG_CB_ID : + hfmac->FilterConfigCallback = HAL_FMAC_FilterConfigCallback; /* Legacy weak + FilterConfigCallback */ + break; + + case HAL_FMAC_FILTER_PRELOAD_CB_ID : + hfmac->FilterPreloadCallback = HAL_FMAC_FilterPreloadCallback; /* Legacy weak FilterPreloadCallba */ + break; + + case HAL_FMAC_MSPINIT_CB_ID : + hfmac->MspInitCallback = HAL_FMAC_MspInit; /* Legacy weak MspInitCallback */ + break; + + case HAL_FMAC_MSPDEINIT_CB_ID : + hfmac->MspDeInitCallback = HAL_FMAC_MspDeInit; /* Legacy weak MspDeInitCallback */ + break; + + default : + /* Update the error code */ + hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (hfmac->State == HAL_FMAC_STATE_RESET) + { + switch (CallbackID) + { + case HAL_FMAC_MSPINIT_CB_ID : + hfmac->MspInitCallback = HAL_FMAC_MspInit; + break; + + case HAL_FMAC_MSPDEINIT_CB_ID : + hfmac->MspDeInitCallback = HAL_FMAC_MspDeInit; + break; + + default : + /* Update the error code */ + hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} +#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup FMAC_Exported_Functions_Group2 Peripheral Control functions + * @brief Control functions. + * +@verbatim + ============================================================================== + ##### Peripheral Control functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) Configure the FMAC peripheral: memory area, filter type and parameters, + way to access to the input and output memory area (none, polling, IT, DMA). + (+) Start the FMAC processing (filter). + (+) Handle the input data that will be provided into FMAC. + (+) Handle the output data provided by FMAC. + (+) Stop the FMAC processing (filter). + +@endverbatim + * @{ + */ + +/** + * @brief Configure the FMAC filter. + * @note The configuration is done according to the parameters + * specified in the FMAC_FilterConfigTypeDef structure. + * The provided data will be loaded using polling mode. + * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains + * the configuration information for FMAC module. + * @param pConfig pointer to a FMAC_FilterConfigTypeDef structure that + * contains the FMAC configuration information. + * @retval HAL_StatusTypeDef HAL status + */ +HAL_StatusTypeDef HAL_FMAC_FilterConfig(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *pConfig) +{ + return (FMAC_FilterConfig(hfmac, pConfig, PRELOAD_ACCESS_POLLING)); +} + +/** + * @brief Configure the FMAC filter. + * @note The configuration is done according to the parameters + * specified in the FMAC_FilterConfigTypeDef structure. + * The provided data will be loaded using DMA. + * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains + * the configuration information for FMAC module. + * @param pConfig pointer to a FMAC_FilterConfigTypeDef structure that + * contains the FMAC configuration information. + * @retval HAL_StatusTypeDef HAL status + */ +HAL_StatusTypeDef HAL_FMAC_FilterConfig_DMA(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *pConfig) +{ + return (FMAC_FilterConfig(hfmac, pConfig, PRELOAD_ACCESS_DMA)); +} + +/** + * @brief Preload the input (FIR, IIR) and output data (IIR) of the FMAC filter. + * @note The set(s) of data will be used by FMAC as soon as @ref HAL_FMAC_FilterStart is called. + * The provided data will be loaded using polling mode. + * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains + * the configuration information for FMAC module. + * @param pInput Preloading of the first elements of the input buffer (X1). + * If not needed (no data available when starting), it should be set to NULL. + * @param InputSize Size of the input vector. + * As pInput is used for preloading data, it cannot be bigger than the input memory area. + * @param pOutput [IIR] Preloading of the first elements of the output vector (Y). + * If not needed, it should be set to NULL. + * @param OutputSize Size of the output vector. + * As pOutput is used for preloading data, it cannot be bigger than the output memory area. + * @note The input and the output buffers can be filled by calling several times @ref HAL_FMAC_FilterPreload + * (each call filling partly the buffers). In case of overflow (too much data provided through + * all these calls), an error will be returned. + * @retval HAL_StatusTypeDef HAL status + */ +HAL_StatusTypeDef HAL_FMAC_FilterPreload(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize, + int16_t *pOutput, uint8_t OutputSize) +{ + return (FMAC_FilterPreload(hfmac, pInput, InputSize, pOutput, OutputSize, PRELOAD_ACCESS_POLLING)); +} + +/** + * @brief Preload the input (FIR, IIR) and output data (IIR) of the FMAC filter. + * @note The set(s) of data will be used by FMAC as soon as @ref HAL_FMAC_FilterStart is called. + * The provided data will be loaded using DMA. + * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains + * the configuration information for FMAC module. + * @param pInput Preloading of the first elements of the input buffer (X1). + * If not needed (no data available when starting), it should be set to NULL. + * @param InputSize Size of the input vector. + * As pInput is used for preloading data, it cannot be bigger than the input memory area. + * @param pOutput [IIR] Preloading of the first elements of the output vector (Y). + * If not needed, it should be set to NULL. + * @param OutputSize Size of the output vector. + * As pOutput is used for preloading data, it cannot be bigger than the output memory area. + * @note The input and the output buffers can be filled by calling several times @ref HAL_FMAC_FilterPreload + * (each call filling partly the buffers). In case of overflow (too much data provided through + * all these calls), an error will be returned. + * @retval HAL_StatusTypeDef HAL status + */ +HAL_StatusTypeDef HAL_FMAC_FilterPreload_DMA(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize, + int16_t *pOutput, uint8_t OutputSize) +{ + return (FMAC_FilterPreload(hfmac, pInput, InputSize, pOutput, OutputSize, PRELOAD_ACCESS_DMA)); +} + + +/** + * @brief Start the FMAC processing according to the existing FMAC configuration. + * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains + * the configuration information for FMAC module. + * @param pOutput pointer to buffer where output data of FMAC processing will be stored + * in the next steps. + * If it is set to NULL, the output will not be read and it will be up to + * an external IP to empty the output buffer. + * @param pOutputSize pointer to the size of the output buffer. The number of read data will be written here. + * @retval HAL_StatusTypeDef HAL status + */ +HAL_StatusTypeDef HAL_FMAC_FilterStart(FMAC_HandleTypeDef *hfmac, int16_t *pOutput, uint16_t *pOutputSize) +{ + uint32_t tmpcr = 0U; + HAL_StatusTypeDef status; + + /* Check the START bit state */ + if (FMAC_GET_START_BIT(hfmac) != 0U) + { + return HAL_ERROR; + } + + /* Check that a valid configuration was done previously */ + if (hfmac->FilterParam == 0U) + { + return HAL_ERROR; + } + + /* Check handle state is ready */ + if (hfmac->State == HAL_FMAC_STATE_READY) + { + /* Change the FMAC state */ + hfmac->State = HAL_FMAC_STATE_BUSY; + + /* CR: Configure the input access (error interruptions enabled only for IT or DMA) */ + if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_DMA) + { + tmpcr |= FMAC_DMA_WEN; + } + else if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_IT) + { + tmpcr |= FMAC_IT_WIEN; + } + else + { + /* nothing to do */ + } + + /* CR: Configure the output access (error interruptions enabled only for IT or DMA) */ + if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_DMA) + { + tmpcr |= FMAC_DMA_REN; + } + else if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_IT) + { + tmpcr |= FMAC_IT_RIEN; + } + else + { + /* nothing to do */ + } + + /* CR: Write the configuration */ + MODIFY_REG(hfmac->Instance->CR, \ + FMAC_IT_RIEN | FMAC_IT_WIEN | FMAC_DMA_REN | FMAC_CR_DMAWEN, \ + tmpcr); + + /* Register the new output buffer */ + status = FMAC_ConfigFilterOutputBufferUpdateState(hfmac, pOutput, pOutputSize); + + if (status == HAL_OK) + { + /* PARAM: Start the filter ( this can generate interrupts before the end of the HAL_FMAC_FilterStart ) */ + WRITE_REG(hfmac->Instance->PARAM, (uint32_t)(hfmac->FilterParam)); + } + + /* Reset the busy flag (do not overwrite the possible write and read flag) */ + hfmac->State = HAL_FMAC_STATE_READY; + } + else + { + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Provide a new input buffer that will be loaded into the FMAC input memory area. + * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains + * the configuration information for FMAC module. + * @param pInput New input vector (additional input data). + * @param pInputSize Size of the input vector (if all the data can't be + * written, it will be updated with the number of data read from FMAC). + * @retval HAL_StatusTypeDef HAL status + */ +HAL_StatusTypeDef HAL_FMAC_AppendFilterData(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint16_t *pInputSize) +{ + HAL_StatusTypeDef status; + + /* Check the function parameters */ + if ((pInput == NULL) || (pInputSize == NULL)) + { + return HAL_ERROR; + } + if (*pInputSize == 0U) + { + return HAL_ERROR; + } + + /* Check the START bit state */ + if (FMAC_GET_START_BIT(hfmac) == 0U) + { + return HAL_ERROR; + } + + /* Check the FMAC configuration */ + if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_NONE) + { + return HAL_ERROR; + } + + /* Check whether the previous input vector has been handled */ + if ((hfmac->pInputSize != NULL) && (hfmac->InputCurrentSize < * (hfmac->pInputSize))) + { + return HAL_ERROR; + } + + /* Check that FMAC was initialized and that no writing is already ongoing */ + if (hfmac->WrState == HAL_FMAC_STATE_READY) + { + /* Register the new input buffer */ + status = FMAC_AppendFilterDataUpdateState(hfmac, pInput, pInputSize); + } + else + { + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Provide a new output buffer to be filled with the data computed by FMAC unit. + * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains + * the configuration information for FMAC module. + * @param pOutput New output vector. + * @param pOutputSize Size of the output vector (if the vector can't + * be entirely filled, pOutputSize will be updated with the number + * of data read from FMAC). + * @retval HAL_StatusTypeDef HAL status + */ +HAL_StatusTypeDef HAL_FMAC_ConfigFilterOutputBuffer(FMAC_HandleTypeDef *hfmac, int16_t *pOutput, uint16_t *pOutputSize) +{ + HAL_StatusTypeDef status; + + /* Check the function parameters */ + if ((pOutput == NULL) || (pOutputSize == NULL)) + { + return HAL_ERROR; + } + if (*pOutputSize == 0U) + { + return HAL_ERROR; + } + + /* Check the START bit state */ + if (FMAC_GET_START_BIT(hfmac) == 0U) + { + return HAL_ERROR; + } + + /* Check the FMAC configuration */ + if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_NONE) + { + return HAL_ERROR; + } + + /* Check whether the previous output vector has been handled */ + if ((hfmac->pOutputSize != NULL) && (hfmac->OutputCurrentSize < * (hfmac->pOutputSize))) + { + return HAL_ERROR; + } + + /* Check that FMAC was initialized and that not reading is already ongoing */ + if (hfmac->RdState == HAL_FMAC_STATE_READY) + { + /* Register the new output buffer */ + status = FMAC_ConfigFilterOutputBufferUpdateState(hfmac, pOutput, pOutputSize); + } + else + { + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Handle the input and/or output data in polling mode + * @note This function writes the previously provided user's input data and + * fills the previously provided user's output buffer, + * according to the existing FMAC configuration (polling mode only). + * The function returns when the input data has been handled or + * when the output data is filled. The possible unused data isn't + * kept. It will be up to the user to handle it. The previously + * provided pInputSize and pOutputSize will be used to indicate to the + * size of the read/written data to the user. + * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains + * the configuration information for FMAC module. + * @param Timeout timeout value. + * @retval HAL_StatusTypeDef HAL status + */ +HAL_StatusTypeDef HAL_FMAC_PollFilterData(FMAC_HandleTypeDef *hfmac, uint32_t Timeout) +{ + uint32_t tickstart; + uint8_t inpolling; + uint8_t inpollingover = POLLING_NOT_STOPPED; + uint8_t outpolling; + uint8_t outpollingover = POLLING_NOT_STOPPED; + HAL_StatusTypeDef status; + + /* Check the START bit state */ + if (FMAC_GET_START_BIT(hfmac) == 0U) + { + return HAL_ERROR; + } + + /* Check the configuration */ + + /* Get the input and output mode (if no buffer was previously provided, nothing will be read/written) */ + if ((hfmac->InputAccess == FMAC_BUFFER_ACCESS_POLLING) && (hfmac->pInput != NULL)) + { + inpolling = POLLING_ENABLED; + } + else + { + inpolling = POLLING_DISABLED; + } + if ((hfmac->OutputAccess == FMAC_BUFFER_ACCESS_POLLING) && (hfmac->pOutput != NULL)) + { + outpolling = POLLING_ENABLED; + } + else + { + outpolling = POLLING_DISABLED; + } + + /* Check the configuration */ + if ((inpolling == POLLING_DISABLED) && (outpolling == POLLING_DISABLED)) + { + return HAL_ERROR; + } + + /* Check handle state is ready */ + if (hfmac->State == HAL_FMAC_STATE_READY) + { + /* Change the FMAC state */ + hfmac->State = HAL_FMAC_STATE_BUSY; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Loop on reading and writing until timeout */ + while ((HAL_GetTick() - tickstart) < Timeout) + { + /* X1: Check the mode: polling or none */ + if (inpolling != POLLING_DISABLED) + { + FMAC_WriteDataIncrementPtr(hfmac, MAX_FILTER_DATA_SIZE_TO_HANDLE); + if (hfmac->InputCurrentSize == *(hfmac->pInputSize)) + { + inpollingover = POLLING_STOPPED; + } + } + + /* Y: Check the mode: polling or none */ + if (outpolling != POLLING_DISABLED) + { + FMAC_ReadDataIncrementPtr(hfmac, MAX_FILTER_DATA_SIZE_TO_HANDLE); + if (hfmac->OutputCurrentSize == *(hfmac->pOutputSize)) + { + outpollingover = POLLING_STOPPED; + } + } + + /* Exit if there isn't data to handle anymore on one side or another */ + if ((inpollingover != POLLING_NOT_STOPPED) || (outpollingover != POLLING_NOT_STOPPED)) + { + break; + } + } + + /* Change the FMAC state; update the input and output sizes; reset the indexes */ + if (inpolling != POLLING_DISABLED) + { + (*(hfmac->pInputSize)) = hfmac->InputCurrentSize; + FMAC_ResetInputStateAndDataPointers(hfmac); + } + if (outpolling != POLLING_DISABLED) + { + (*(hfmac->pOutputSize)) = hfmac->OutputCurrentSize; + FMAC_ResetOutputStateAndDataPointers(hfmac); + } + + /* Reset the busy flag (do not overwrite the possible write and read flag) */ + hfmac->State = HAL_FMAC_STATE_READY; + + if ((HAL_GetTick() - tickstart) >= Timeout) + { + hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT; + status = HAL_ERROR; + } + else + { + status = HAL_OK; + } + } + else + { + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Stop the FMAC processing. + * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains + * the configuration information for FMAC module. + * @retval HAL_StatusTypeDef HAL status + */ +HAL_StatusTypeDef HAL_FMAC_FilterStop(FMAC_HandleTypeDef *hfmac) +{ + HAL_StatusTypeDef status; + + /* Check handle state is ready */ + if (hfmac->State == HAL_FMAC_STATE_READY) + { + /* Change the FMAC state */ + hfmac->State = HAL_FMAC_STATE_BUSY; + + /* Set the START bit to 0 (stop the previously configured filter) */ + CLEAR_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START); + + /* Disable the interrupts in order to avoid crossing cases */ + CLEAR_BIT(hfmac->Instance->CR, FMAC_DMA_REN | FMAC_DMA_WEN | FMAC_IT_RIEN | FMAC_IT_WIEN); + + /* In case of IT, update the sizes */ + if ((hfmac->InputAccess == FMAC_BUFFER_ACCESS_IT) && (hfmac->pInput != NULL)) + { + (*(hfmac->pInputSize)) = hfmac->InputCurrentSize; + } + if ((hfmac->OutputAccess == FMAC_BUFFER_ACCESS_IT) && (hfmac->pOutput != NULL)) + { + (*(hfmac->pOutputSize)) = hfmac->OutputCurrentSize; + } + + /* Reset FMAC unit (internal pointers) */ + if (FMAC_Reset(hfmac) == HAL_ERROR) + { + /* Update FMAC error code and FMAC peripheral state */ + hfmac->ErrorCode = HAL_FMAC_ERROR_RESET; + hfmac->State = HAL_FMAC_STATE_TIMEOUT; + status = HAL_ERROR; + } + else + { + /* Reset the data pointers */ + FMAC_ResetDataPointers(hfmac); + + status = HAL_OK; + } + + /* Reset the busy flag */ + hfmac->State = HAL_FMAC_STATE_READY; + } + else + { + status = HAL_ERROR; + } + + return status; +} + +/** + * @} + */ + +/** @defgroup FMAC_Exported_Functions_Group3 Callback functions + * @brief Callback functions. + * +@verbatim + ============================================================================== + ##### Callback functions ##### + ============================================================================== + [..] This section provides Interruption and DMA callback functions: + (+) DMA or Interrupt: the user's input data is half written (DMA only) + or completely written. + (+) DMA or Interrupt: the user's output buffer is half filled (DMA only) + or completely filled. + (+) DMA or Interrupt: error handling. + +@endverbatim + * @{ + */ + +/** + * @brief FMAC error callback. + * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains + * the configuration information for FMAC module. + * @retval None + */ +__weak void HAL_FMAC_ErrorCallback(FMAC_HandleTypeDef *hfmac) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hfmac); + + /* NOTE : This function should not be modified; when the callback is needed, + the HAL_FMAC_ErrorCallback can be implemented in the user file. + */ +} + +/** + * @brief FMAC get half data callback. + * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains + * the configuration information for FMAC module. + * @retval None + */ +__weak void HAL_FMAC_HalfGetDataCallback(FMAC_HandleTypeDef *hfmac) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hfmac); + + /* NOTE : This function should not be modified; when the callback is needed, + the HAL_FMAC_HalfGetDataCallback can be implemented in the user file. + */ +} + +/** + * @brief FMAC get data callback. + * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains + * the configuration information for FMAC module. + * @retval None + */ +__weak void HAL_FMAC_GetDataCallback(FMAC_HandleTypeDef *hfmac) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hfmac); + + /* NOTE : This function should not be modified; when the callback is needed, + the HAL_FMAC_GetDataCallback can be implemented in the user file. + */ +} + +/** + * @brief FMAC half output data ready callback. + * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains + * the configuration information for FMAC module. + * @retval None + */ +__weak void HAL_FMAC_HalfOutputDataReadyCallback(FMAC_HandleTypeDef *hfmac) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hfmac); + + /* NOTE : This function should not be modified; when the callback is needed, + the HAL_FMAC_HalfOutputDataReadyCallback can be implemented in the user file. + */ +} + +/** + * @brief FMAC output data ready callback. + * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains + * the configuration information for FMAC module. + * @retval None + */ +__weak void HAL_FMAC_OutputDataReadyCallback(FMAC_HandleTypeDef *hfmac) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hfmac); + + /* NOTE : This function should not be modified; when the callback is needed, + the HAL_FMAC_OutputDataReadyCallback can be implemented in the user file. + */ +} + +/** + * @brief FMAC filter configuration callback. + * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains + * the configuration information for FMAC module. + * @retval None + */ +__weak void HAL_FMAC_FilterConfigCallback(FMAC_HandleTypeDef *hfmac) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hfmac); + + /* NOTE : This function should not be modified; when the callback is needed, + the HAL_FMAC_FilterConfigCallback can be implemented in the user file. + */ +} + +/** + * @brief FMAC filter preload callback. + * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains + * the configuration information for FMAC module. + * @retval None + */ +__weak void HAL_FMAC_FilterPreloadCallback(FMAC_HandleTypeDef *hfmac) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hfmac); + + /* NOTE : This function should not be modified; when the callback is needed, + the HAL_FMAC_FilterPreloadCallback can be implemented in the user file. + */ +} + +/** + * @} + */ + +/** @defgroup FMAC_Exported_Functions_Group4 IRQ handler management + * @brief IRQ handler. + * +@verbatim + ============================================================================== + ##### IRQ handler management ##### + ============================================================================== +[..] This section provides IRQ handler function. + +@endverbatim + * @{ + */ + +/** + * @brief Handle FMAC interrupt request. + * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains + * the configuration information for FMAC module. + * @retval None + */ +void HAL_FMAC_IRQHandler(FMAC_HandleTypeDef *hfmac) +{ + uint32_t itsource; + + /* Check if the read interrupt is enabled and if Y buffer empty flag isn't set */ + itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_RIEN); + if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_YEMPTY) == 0U) && (itsource != 0U)) + { + /* Read some data if possible (Y size is used as a pseudo timeout in order + to not get stuck too long under IT if FMAC keeps on processing input + data reloaded via DMA for instance). */ + if (hfmac->pOutput != NULL) + { + FMAC_ReadDataIncrementPtr(hfmac, (uint16_t)FMAC_GET_Y_SIZE(hfmac)); + } + + /* Indicate that data is ready to be read */ + if ((hfmac->pOutput == NULL) || (hfmac->OutputCurrentSize == *(hfmac->pOutputSize))) + { + /* Reset the pointers to indicate new data will be needed */ + FMAC_ResetOutputStateAndDataPointers(hfmac); + + /* Call the output data ready callback */ +#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) + hfmac->OutputDataReadyCallback(hfmac); +#else + HAL_FMAC_OutputDataReadyCallback(hfmac); +#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ + } + } + + /* Check if the write interrupt is enabled and if X1 buffer full flag isn't set */ + itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_WIEN); + if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_X1FULL) == 0U) && (itsource != 0U)) + { + /* Write some data if possible (X1 size is used as a pseudo timeout in order + to not get stuck too long under IT if FMAC keep on processing input + data whereas its output emptied via DMA for instance). */ + if (hfmac->pInput != NULL) + { + FMAC_WriteDataIncrementPtr(hfmac, (uint16_t)FMAC_GET_X1_SIZE(hfmac)); + } + + /* Indicate that new data will be needed */ + if ((hfmac->pInput == NULL) || (hfmac->InputCurrentSize == *(hfmac->pInputSize))) + { + /* Reset the pointers to indicate new data will be needed */ + FMAC_ResetInputStateAndDataPointers(hfmac); + + /* Call the get data callback */ +#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) + hfmac->GetDataCallback(hfmac); +#else + HAL_FMAC_GetDataCallback(hfmac); +#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ + } + } + + /* Check if the overflow error interrupt is enabled and if overflow error flag is raised */ + itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_OVFLIEN); + if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_OVFL) != 0U) && (itsource != 0U)) + { + hfmac->ErrorCode |= HAL_FMAC_ERROR_OVFL; + } + + /* Check if the underflow error interrupt is enabled and if underflow error flag is raised */ + itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_UNFLIEN); + if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_UNFL) != 0U) && (itsource != 0U)) + { + hfmac->ErrorCode |= HAL_FMAC_ERROR_UNFL; + } + + /* Check if the saturation error interrupt is enabled and if saturation error flag is raised */ + itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_SATIEN); + if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_SAT) != 0U) && (itsource != 0U)) + { + hfmac->ErrorCode |= HAL_FMAC_ERROR_SAT; + } + + /* Call the error callback if an error occurred */ + if (hfmac->ErrorCode != HAL_FMAC_ERROR_NONE) + { + /* Call the error callback */ +#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) + hfmac->ErrorCallback(hfmac); +#else + HAL_FMAC_ErrorCallback(hfmac); +#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ + } +} + +/** + * @} + */ + +/** @defgroup FMAC_Exported_Functions_Group5 Peripheral State and Error functions + * @brief Peripheral State and Error functions. + * +@verbatim + ============================================================================== + ##### Peripheral State and Error functions ##### + ============================================================================== + [..] This subsection provides functions allowing to + (+) Check the FMAC state + (+) Get error code + +@endverbatim + * @{ + */ + +/** + * @brief Return the FMAC state. + * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains + * the configuration information for FMAC module. + * @retval HAL_FMAC_StateTypeDef FMAC state + */ +HAL_FMAC_StateTypeDef HAL_FMAC_GetState(const FMAC_HandleTypeDef *hfmac) +{ + /* Return FMAC state */ + return hfmac->State; +} + +/** + * @brief Return the FMAC peripheral error. + * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains + * the configuration information for FMAC module. + * @note The returned error is a bit-map combination of possible errors. + * @retval uint32_t Error bit-map based on @ref FMAC_Error_Code + */ +uint32_t HAL_FMAC_GetError(const FMAC_HandleTypeDef *hfmac) +{ + /* Return FMAC error code */ + return hfmac->ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup FMAC_Private_Functions FMAC Private Functions + * @{ + */ + +/** + ============================================================================== + ##### FMAC Private Functions ##### + ============================================================================== + */ +/** + * @brief Perform a reset of the FMAC unit. + * @param hfmac FMAC handle. + * @retval HAL_StatusTypeDef HAL status + */ +static HAL_StatusTypeDef FMAC_Reset(FMAC_HandleTypeDef *hfmac) +{ + uint32_t tickstart; + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + /* Perform the reset */ + SET_BIT(hfmac->Instance->CR, FMAC_CR_RESET); + + /* Wait until flag is reset */ + while (READ_BIT(hfmac->Instance->CR, FMAC_CR_RESET) != 0U) + { + if ((HAL_GetTick() - tickstart) > HAL_FMAC_RESET_TIMEOUT_VALUE) + { + hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT; + return HAL_ERROR; + } + } + + hfmac->ErrorCode = HAL_FMAC_ERROR_NONE; + return HAL_OK; +} + +/** + * @brief Reset the data pointers of the FMAC unit. + * @param hfmac FMAC handle. + * @retval None + */ +static void FMAC_ResetDataPointers(FMAC_HandleTypeDef *hfmac) +{ + FMAC_ResetInputStateAndDataPointers(hfmac); + FMAC_ResetOutputStateAndDataPointers(hfmac); +} + +/** + * @brief Reset the input data pointers of the FMAC unit. + * @param hfmac FMAC handle. + * @retval None + */ +static void FMAC_ResetInputStateAndDataPointers(FMAC_HandleTypeDef *hfmac) +{ + hfmac->pInput = NULL; + hfmac->pInputSize = NULL; + hfmac->InputCurrentSize = 0U; + hfmac->WrState = HAL_FMAC_STATE_READY; +} + +/** + * @brief Reset the output data pointers of the FMAC unit. + * @param hfmac FMAC handle. + * @retval None + */ +static void FMAC_ResetOutputStateAndDataPointers(FMAC_HandleTypeDef *hfmac) +{ + hfmac->pOutput = NULL; + hfmac->pOutputSize = NULL; + hfmac->OutputCurrentSize = 0U; + hfmac->RdState = HAL_FMAC_STATE_READY; +} + +/** + * @brief Configure the FMAC filter. + * @note The configuration is done according to the parameters + * specified in the FMAC_FilterConfigTypeDef structure. + * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains + * the configuration information for FMAC module. + * @param pConfig pointer to a FMAC_FilterConfigTypeDef structure that + * contains the FMAC configuration information. + * @param PreloadAccess access mode used for the preload (polling or DMA). + * @retval HAL_StatusTypeDef HAL status + */ +static HAL_StatusTypeDef FMAC_FilterConfig(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *pConfig, + uint8_t PreloadAccess) +{ + uint32_t tickstart; + uint32_t tmpcr; + HAL_StatusTypeDef status; +#if defined(USE_FULL_ASSERT) + uint32_t x2size; +#endif /* USE_FULL_ASSERT */ + + /* Check the parameters */ + assert_param(IS_FMAC_THRESHOLD(pConfig->InputThreshold)); + assert_param(IS_FMAC_THRESHOLD(pConfig->OutputThreshold)); + assert_param(IS_FMAC_BUFFER_ACCESS(pConfig->InputAccess)); + assert_param(IS_FMAC_BUFFER_ACCESS(pConfig->OutputAccess)); + assert_param(IS_FMAC_CLIP_STATE(pConfig->Clip)); + assert_param(IS_FMAC_FILTER_FUNCTION(pConfig->Filter)); + assert_param(IS_FMAC_PARAM_P(pConfig->Filter, pConfig->P)); + assert_param(IS_FMAC_PARAM_Q(pConfig->Filter, pConfig->Q)); + assert_param(IS_FMAC_PARAM_R(pConfig->Filter, pConfig->R)); + + /* Check the START bit state */ + if (FMAC_GET_START_BIT(hfmac) != 0U) + { + return HAL_ERROR; + } + + /* Check handle state is ready */ + if (hfmac->State != HAL_FMAC_STATE_READY) + { + return HAL_ERROR; + } + + /* Change the FMAC state */ + hfmac->State = HAL_FMAC_STATE_BUSY; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Indicate that there is no valid configuration done */ + hfmac->FilterParam = 0U; + + /* FMAC_X1BUFCFG: Configure the input buffer within the internal memory if required */ + if (pConfig->InputBufferSize != 0U) + { + MODIFY_REG(hfmac->Instance->X1BUFCFG, \ + (FMAC_X1BUFCFG_X1_BASE | FMAC_X1BUFCFG_X1_BUF_SIZE), \ + (((((uint32_t)(pConfig->InputBaseAddress)) << FMAC_X1BUFCFG_X1_BASE_Pos) & FMAC_X1BUFCFG_X1_BASE) | \ + ((((uint32_t)(pConfig->InputBufferSize)) << FMAC_X1BUFCFG_X1_BUF_SIZE_Pos) & \ + FMAC_X1BUFCFG_X1_BUF_SIZE))); + } + + /* FMAC_X1BUFCFG: Configure the input threshold if valid when compared to the configured X1 size */ + if (pConfig->InputThreshold != FMAC_THRESHOLD_NO_VALUE) + { + /* Check the parameter */ + assert_param(IS_FMAC_THRESHOLD_APPLICABLE(FMAC_GET_X1_SIZE(hfmac), pConfig->InputThreshold, pConfig->InputAccess)); + + MODIFY_REG(hfmac->Instance->X1BUFCFG, \ + FMAC_X1BUFCFG_FULL_WM, \ + ((pConfig->InputThreshold) & FMAC_X1BUFCFG_FULL_WM)); + } + + /* FMAC_X2BUFCFG: Configure the coefficient buffer within the internal memory */ + if (pConfig->CoeffBufferSize != 0U) + { + MODIFY_REG(hfmac->Instance->X2BUFCFG, \ + (FMAC_X2BUFCFG_X2_BASE | FMAC_X2BUFCFG_X2_BUF_SIZE), \ + (((((uint32_t)(pConfig->CoeffBaseAddress)) << FMAC_X2BUFCFG_X2_BASE_Pos) & FMAC_X2BUFCFG_X2_BASE) | \ + ((((uint32_t)(pConfig->CoeffBufferSize)) << FMAC_X2BUFCFG_X2_BUF_SIZE_Pos) &\ + FMAC_X2BUFCFG_X2_BUF_SIZE))); + } + + /* FMAC_YBUFCFG: Configure the output buffer within the internal memory if required */ + if (pConfig->OutputBufferSize != 0U) + { + MODIFY_REG(hfmac->Instance->YBUFCFG, \ + (FMAC_YBUFCFG_Y_BASE | FMAC_YBUFCFG_Y_BUF_SIZE), \ + (((((uint32_t)(pConfig->OutputBaseAddress)) << FMAC_YBUFCFG_Y_BASE_Pos) & FMAC_YBUFCFG_Y_BASE) | \ + ((((uint32_t)(pConfig->OutputBufferSize)) << FMAC_YBUFCFG_Y_BUF_SIZE_Pos) & FMAC_YBUFCFG_Y_BUF_SIZE))); + } + + /* FMAC_YBUFCFG: Configure the output threshold if valid when compared to the configured Y size */ + if (pConfig->OutputThreshold != FMAC_THRESHOLD_NO_VALUE) + { + /* Check the parameter */ + assert_param(IS_FMAC_THRESHOLD_APPLICABLE(FMAC_GET_Y_SIZE(hfmac), pConfig->OutputThreshold, pConfig->OutputAccess)); + + MODIFY_REG(hfmac->Instance->YBUFCFG, \ + FMAC_YBUFCFG_EMPTY_WM, \ + ((pConfig->OutputThreshold) & FMAC_YBUFCFG_EMPTY_WM)); + } + + /* FMAC_CR: Configure the clip feature */ + tmpcr = pConfig->Clip & FMAC_CR_CLIPEN; + + /* FMAC_CR: If IT or DMA will be used, enable error interrupts. + * Being more a debugging feature, FMAC_CR_SATIEN isn't enabled by default. */ + if ((pConfig->InputAccess == FMAC_BUFFER_ACCESS_DMA) || (pConfig->InputAccess == FMAC_BUFFER_ACCESS_IT) || + (pConfig->OutputAccess == FMAC_BUFFER_ACCESS_DMA) || (pConfig->OutputAccess == FMAC_BUFFER_ACCESS_IT)) + { + tmpcr |= FMAC_IT_UNFLIEN | FMAC_IT_OVFLIEN; + } + + /* FMAC_CR: write the value */ + WRITE_REG(hfmac->Instance->CR, tmpcr); + + /* Save the input/output accesses in order to configure RIEN, WIEN, DMAREN and DMAWEN during filter start */ + hfmac->InputAccess = pConfig->InputAccess; + hfmac->OutputAccess = pConfig->OutputAccess; + + /* Check whether the configured X2 is big enough for the filter */ +#if defined(USE_FULL_ASSERT) + x2size = FMAC_GET_X2_SIZE(hfmac); +#endif /* USE_FULL_ASSERT */ + assert_param(((pConfig->Filter == FMAC_FUNC_CONVO_FIR) && (x2size >= pConfig->P)) || \ + ((pConfig->Filter == FMAC_FUNC_IIR_DIRECT_FORM_1) && \ + (x2size >= ((uint32_t)pConfig->P + (uint32_t)pConfig->Q)))); + + /* Build the PARAM value that will be used when starting the filter */ + hfmac->FilterParam = (FMAC_PARAM_START | pConfig->Filter | \ + ((((uint32_t)(pConfig->P)) << FMAC_PARAM_P_Pos) & FMAC_PARAM_P) | \ + ((((uint32_t)(pConfig->Q)) << FMAC_PARAM_Q_Pos) & FMAC_PARAM_Q) | \ + ((((uint32_t)(pConfig->R)) << FMAC_PARAM_R_Pos) & FMAC_PARAM_R)); + + /* Initialize the coefficient buffer if required (pCoeffA for FIR only) */ + if ((pConfig->pCoeffB != NULL) && (pConfig->CoeffBSize != 0U)) + { + /* FIR/IIR: The provided coefficients should match X2 size */ + assert_param(((uint32_t)pConfig->CoeffASize + (uint32_t)pConfig->CoeffBSize) <= x2size); + /* FIR/IIR: The size of pCoeffB should match the parameter P */ + assert_param(pConfig->CoeffBSize >= pConfig->P); + /* pCoeffA should be provided for IIR but not for FIR */ + /* IIR : if pCoeffB is provided, pCoeffA should also be there */ + /* IIR: The size of pCoeffA should match the parameter Q */ + assert_param(((pConfig->Filter == FMAC_FUNC_CONVO_FIR) && + (pConfig->pCoeffA == NULL) && (pConfig->CoeffASize == 0U)) || + ((pConfig->Filter == FMAC_FUNC_IIR_DIRECT_FORM_1) && + (pConfig->pCoeffA != NULL) && (pConfig->CoeffASize != 0U) && + (pConfig->CoeffASize >= pConfig->Q))); + + /* Write number of values to be loaded, the data load function and start the operation */ + WRITE_REG(hfmac->Instance->PARAM, \ + (((uint32_t)(pConfig->CoeffBSize) << FMAC_PARAM_P_Pos) | \ + ((uint32_t)(pConfig->CoeffASize) << FMAC_PARAM_Q_Pos) | \ + FMAC_FUNC_LOAD_X2 | FMAC_PARAM_START)); + + if (PreloadAccess == PRELOAD_ACCESS_POLLING) + { + /* Load the buffer into the internal memory */ + FMAC_WritePreloadDataIncrementPtr(hfmac, &(pConfig->pCoeffB), pConfig->CoeffBSize); + + /* Load pCoeffA if needed */ + if ((pConfig->pCoeffA != NULL) && (pConfig->CoeffASize != 0U)) + { + /* Load the buffer into the internal memory */ + FMAC_WritePreloadDataIncrementPtr(hfmac, &(pConfig->pCoeffA), pConfig->CoeffASize); + } + + /* Wait for the end of the writing */ + if (FMAC_WaitOnStartUntilTimeout(hfmac, tickstart, HAL_FMAC_TIMEOUT_VALUE) != HAL_OK) + { + hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT; + hfmac->State = HAL_FMAC_STATE_TIMEOUT; + return HAL_ERROR; + } + + /* Change the FMAC state */ + hfmac->State = HAL_FMAC_STATE_READY; + } + else + { + hfmac->pInput = pConfig->pCoeffA; + hfmac->InputCurrentSize = pConfig->CoeffASize; + + /* Set the FMAC DMA transfer complete callback */ + hfmac->hdmaPreload->XferHalfCpltCallback = NULL; + hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterConfig; + /* Set the DMA error callback */ + hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError; + + /* Enable the DMA stream managing FMAC preload data write */ + if ((hfmac->hdmaPreload->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hfmac->hdmaPreload->LinkedListQueue != NULL) && (hfmac->hdmaPreload->LinkedListQueue->Head != NULL)) + { + /* Enable the DMA channel */ + hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = + (uint32_t)(2UL * pConfig->CoeffBSize); /* Set DMA data size */ + hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = + (uint32_t)pConfig->pCoeffB; /* Set DMA source address */ + hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = + (uint32_t)&hfmac->Instance->WDATA; /* Set DMA destination address */ + + status = HAL_DMAEx_List_Start_IT(hfmac->hdmaPreload); + } + else + { + /* Return error status */ + return HAL_ERROR; + } + } + else + { + status = HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)pConfig->pCoeffB, \ + (uint32_t)&hfmac->Instance->WDATA, (uint32_t)(2UL * pConfig->CoeffBSize)); + } + + if (status != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + } + } + else + { + /* Change the FMAC state */ + hfmac->State = HAL_FMAC_STATE_READY; + } + + return HAL_OK; +} + +/** + * @brief Preload the input (FIR, IIR) and output data (IIR) of the FMAC filter. + * @note The set(s) of data will be used by FMAC as soon as @ref HAL_FMAC_FilterStart is called. + * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains + * the configuration information for FMAC module. + * @param pInput Preloading of the first elements of the input buffer (X1). + * If not needed (no data available when starting), it should be set to NULL. + * @param InputSize Size of the input vector. + * As pInput is used for preloading data, it cannot be bigger than the input memory area. + * @param pOutput [IIR] Preloading of the first elements of the output vector (Y). + * If not needed, it should be set to NULL. + * @param OutputSize Size of the output vector. + * As pOutput is used for preloading data, it cannot be bigger than the output memory area. + * @param PreloadAccess access mode used for the preload (polling or DMA). + * @note The input and the output buffers can be filled by calling several times @ref HAL_FMAC_FilterPreload + * (each call filling partly the buffers). In case of overflow (too much data provided through + * all these calls), an error will be returned. + * @retval HAL_StatusTypeDef HAL status + */ +static HAL_StatusTypeDef FMAC_FilterPreload(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize, + int16_t *pOutput, uint8_t OutputSize, uint8_t PreloadAccess) +{ + uint32_t tickstart; + HAL_StatusTypeDef status; + + /* Check the START bit state */ + if (FMAC_GET_START_BIT(hfmac) != 0U) + { + return HAL_ERROR; + } + + /* Check that a valid configuration was done previously */ + if (hfmac->FilterParam == 0U) + { + return HAL_ERROR; + } + + /* Check the preload input buffers isn't too big */ + if ((InputSize > FMAC_GET_X1_SIZE(hfmac)) && (pInput != NULL)) + { + return HAL_ERROR; + } + + /* Check the preload output buffer isn't too big */ + if ((OutputSize > FMAC_GET_Y_SIZE(hfmac)) && (pOutput != NULL)) + { + return HAL_ERROR; + } + + /* Check handle state is ready */ + if (hfmac->State != HAL_FMAC_STATE_READY) + { + return HAL_ERROR; + } + + /* Change the FMAC state */ + hfmac->State = HAL_FMAC_STATE_BUSY; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Preload the input buffer if required */ + if ((pInput != NULL) && (InputSize != 0U)) + { + /* Write number of values to be loaded, the data load function and start the operation */ + WRITE_REG(hfmac->Instance->PARAM, \ + (((uint32_t)InputSize << FMAC_PARAM_P_Pos) | FMAC_FUNC_LOAD_X1 | FMAC_PARAM_START)); + + if (PreloadAccess == PRELOAD_ACCESS_POLLING) + { + /* Load the buffer into the internal memory */ + FMAC_WritePreloadDataIncrementPtr(hfmac, &pInput, InputSize); + + /* Wait for the end of the writing */ + if (FMAC_WaitOnStartUntilTimeout(hfmac, tickstart, HAL_FMAC_TIMEOUT_VALUE) != HAL_OK) + { + hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT; + hfmac->State = HAL_FMAC_STATE_TIMEOUT; + return HAL_ERROR; + } + } + else + { + hfmac->pInput = pOutput; + hfmac->InputCurrentSize = OutputSize; + + /* Set the FMAC DMA transfer complete callback */ + hfmac->hdmaPreload->XferHalfCpltCallback = NULL; + hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterPreload; + /* Set the DMA error callback */ + hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError; + + /* Enable the DMA stream managing FMAC preload data write */ + if ((hfmac->hdmaPreload->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hfmac->hdmaPreload->LinkedListQueue != NULL) && (hfmac->hdmaPreload->LinkedListQueue->Head != NULL)) + { + /* Enable the DMA channel */ + hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = + (uint32_t)(2UL * InputSize); /* Set DMA data size */ + hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = + (uint32_t)pInput; /* Set DMA source address */ + hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = + (uint32_t)&hfmac->Instance->WDATA; /* Set DMA destination address */ + + return (HAL_DMAEx_List_Start_IT(hfmac->hdmaPreload)); + } + else + { + /* Return error status */ + return HAL_ERROR; + } + } + else + { + return (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)pInput, \ + (uint32_t)&hfmac->Instance->WDATA, (uint32_t)(2UL * InputSize))); + } + } + } + + /* Preload the output buffer if required */ + if ((pOutput != NULL) && (OutputSize != 0U)) + { + /* Write number of values to be loaded, the data load function and start the operation */ + WRITE_REG(hfmac->Instance->PARAM, \ + (((uint32_t)OutputSize << FMAC_PARAM_P_Pos) | FMAC_FUNC_LOAD_Y | FMAC_PARAM_START)); + + if (PreloadAccess == PRELOAD_ACCESS_POLLING) + { + /* Load the buffer into the internal memory */ + FMAC_WritePreloadDataIncrementPtr(hfmac, &pOutput, OutputSize); + + /* Wait for the end of the writing */ + if (FMAC_WaitOnStartUntilTimeout(hfmac, tickstart, HAL_FMAC_TIMEOUT_VALUE) != HAL_OK) + { + hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT; + hfmac->State = HAL_FMAC_STATE_TIMEOUT; + return HAL_ERROR; + } + } + else + { + hfmac->pInput = NULL; + hfmac->InputCurrentSize = 0U; + + /* Set the FMAC DMA transfer complete callback */ + hfmac->hdmaPreload->XferHalfCpltCallback = NULL; + hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterPreload; + /* Set the DMA error callback */ + hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError; + + /* Enable the DMA stream managing FMAC preload data write */ + if ((hfmac->hdmaPreload->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hfmac->hdmaPreload->LinkedListQueue != NULL) && (hfmac->hdmaPreload->LinkedListQueue->Head != NULL)) + { + /* Enable the DMA channel */ + hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = + (uint32_t)(2UL * OutputSize); /* Set DMA data size */ + hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = + (uint32_t)pOutput; /* Set DMA source address */ + hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = + (uint32_t)&hfmac->Instance->WDATA; /* Set DMA destination address */ + + return (HAL_DMAEx_List_Start_IT(hfmac->hdmaPreload)); + } + else + { + /* Return error status */ + return HAL_ERROR; + } + } + else + { + return (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)pOutput, \ + (uint32_t)&hfmac->Instance->WDATA, (uint32_t)(2UL * OutputSize))); + } + } + } + + /* Update the error codes */ + if (__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_OVFL)) + { + hfmac->ErrorCode |= HAL_FMAC_ERROR_OVFL; + } + if (__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_UNFL)) + { + hfmac->ErrorCode |= HAL_FMAC_ERROR_UNFL; + } + if (__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_SAT)) + { + hfmac->ErrorCode |= HAL_FMAC_ERROR_SAT; + } + + /* Change the FMAC state */ + hfmac->State = HAL_FMAC_STATE_READY; + + /* Return function status */ + if (hfmac->ErrorCode == HAL_FMAC_ERROR_NONE) + { + status = HAL_OK; + } + else + { + status = HAL_ERROR; + } + return status; +} + +/** + * @brief Write data into FMAC internal memory through WDATA and increment input buffer pointer. + * @note This function is only used with preload functions. + * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains + * the configuration information for FMAC module. + * @param ppData pointer to pointer to the data buffer. + * @param Size size of the data buffer. + * @retval None + */ +static void FMAC_WritePreloadDataIncrementPtr(FMAC_HandleTypeDef *hfmac, int16_t **ppData, uint8_t Size) +{ + uint8_t index; + + /* Load the buffer into the internal memory */ + for (index = Size; index > 0U; index--) + { + WRITE_REG(hfmac->Instance->WDATA, (((uint32_t)(*(*ppData))) & FMAC_WDATA_WDATA)); + (*ppData)++; + } +} + +/** + * @brief Handle FMAC Function Timeout. + * @param hfmac FMAC handle. + * @param Tickstart Tick start value. + * @param Timeout Timeout duration. + * @retval HAL_StatusTypeDef HAL status + */ +static HAL_StatusTypeDef FMAC_WaitOnStartUntilTimeout(FMAC_HandleTypeDef *hfmac, uint32_t Tickstart, uint32_t Timeout) +{ + /* Wait until flag changes */ + while (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) != 0U) + { + if ((HAL_GetTick() - Tickstart) > Timeout) + { + hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT; + + return HAL_ERROR; + } + } + return HAL_OK; +} + +/** + * @brief Register the new input buffer, update DMA configuration if needed and change the FMAC state. + * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains + * the configuration information for FMAC module. + * @param pInput New input vector (additional input data). + * @param pInputSize Size of the input vector (if all the data can't be + * written, it will be updated with the number of data read from FMAC). + * @retval HAL_StatusTypeDef HAL status + */ +static HAL_StatusTypeDef FMAC_AppendFilterDataUpdateState(FMAC_HandleTypeDef *hfmac, int16_t *pInput, + uint16_t *pInputSize) +{ + HAL_StatusTypeDef status; + /* Change the FMAC state */ + hfmac->WrState = HAL_FMAC_STATE_BUSY_WR; + + /* Reset the current size */ + hfmac->InputCurrentSize = 0U; + + /* Handle the pointer depending on the input access */ + if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_DMA) + { + hfmac->pInput = NULL; + hfmac->pInputSize = NULL; + + /* Set the FMAC DMA transfer complete callback */ + hfmac->hdmaIn->XferHalfCpltCallback = FMAC_DMAHalfGetData; + hfmac->hdmaIn->XferCpltCallback = FMAC_DMAGetData; + /* Set the DMA error callback */ + hfmac->hdmaIn->XferErrorCallback = FMAC_DMAError; + + /* Enable the DMA stream managing FMAC input data write */ + if ((hfmac->hdmaIn->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hfmac->hdmaIn->LinkedListQueue != NULL) && (hfmac->hdmaIn->LinkedListQueue->Head != NULL)) + { + /* Enable the DMA channel */ + hfmac->hdmaIn->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = + (uint32_t)(2UL * (*pInputSize)); /* Set DMA data size */ + hfmac->hdmaIn->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = + (uint32_t)pInput; /* Set DMA source address */ + hfmac->hdmaIn->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = + (uint32_t)&hfmac->Instance->WDATA;/* Set DMA destination address */ + + status = HAL_DMAEx_List_Start_IT(hfmac->hdmaIn); + } + else + { + /* Return error status */ + return HAL_ERROR; + } + } + else + { + status = HAL_DMA_Start_IT(hfmac->hdmaIn, (uint32_t)pInput, \ + (uint32_t)&hfmac->Instance->WDATA, (uint32_t)(2UL * (*pInputSize))); + } + + if (status != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + } + else + { + /* Update the input data information (polling, IT) */ + hfmac->pInput = pInput; + hfmac->pInputSize = pInputSize; + } + + return HAL_OK; +} + +/** + * @brief Register the new output buffer, update DMA configuration if needed and change the FMAC state. + * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains + * the configuration information for FMAC module. + * @param pOutput New output vector. + * @param pOutputSize Size of the output vector (if the vector can't + * be entirely filled, pOutputSize will be updated with the number + * of data read from FMAC). + * @retval HAL_StatusTypeDef HAL status + */ +static HAL_StatusTypeDef FMAC_ConfigFilterOutputBufferUpdateState(FMAC_HandleTypeDef *hfmac, int16_t *pOutput, + uint16_t *pOutputSize) +{ + HAL_StatusTypeDef status; + /* Reset the current size */ + hfmac->OutputCurrentSize = 0U; + + /* Check whether a valid pointer was provided */ + if ((pOutput == NULL) || (pOutputSize == NULL) || (*pOutputSize == 0U)) + { + /* The user will have to provide a valid configuration later */ + hfmac->pOutput = NULL; + hfmac->pOutputSize = NULL; + hfmac->RdState = HAL_FMAC_STATE_READY; + } + /* Handle the pointer depending on the input access */ + else if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_DMA) + { + hfmac->pOutput = NULL; + hfmac->pOutputSize = NULL; + hfmac->RdState = HAL_FMAC_STATE_BUSY_RD; + + /* Set the FMAC DMA transfer complete callback */ + hfmac->hdmaOut->XferHalfCpltCallback = FMAC_DMAHalfOutputDataReady; + hfmac->hdmaOut->XferCpltCallback = FMAC_DMAOutputDataReady; + /* Set the DMA error callback */ + hfmac->hdmaOut->XferErrorCallback = FMAC_DMAError; + + /* Enable the DMA stream managing FMAC output data read */ + if ((hfmac->hdmaOut->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hfmac->hdmaOut->LinkedListQueue != NULL) && (hfmac->hdmaOut->LinkedListQueue->Head != NULL)) + { + /* Enable the DMA channel */ + hfmac->hdmaOut->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = + (uint32_t)(4UL * (*pOutputSize)); /* Set DMA data size */ + hfmac->hdmaOut->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = + (uint32_t)&hfmac->Instance->RDATA;/* Set DMA source address */ + hfmac->hdmaOut->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = + (uint32_t)pOutput; /* Set DMA destination address */ + + status = HAL_DMAEx_List_Start_IT(hfmac->hdmaOut); + } + else + { + /* Return error status */ + return HAL_ERROR; + } + } + else + { + status = HAL_DMA_Start_IT(hfmac->hdmaOut, (uint32_t)&hfmac->Instance->RDATA, \ + (uint32_t)pOutput, (uint32_t)(4UL * (*pOutputSize))); + } + + if (status != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + } + else if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_NONE) + { + hfmac->pOutput = NULL; + hfmac->pOutputSize = NULL; + hfmac->RdState = HAL_FMAC_STATE_READY; + } + else + { + /* Update the output data information (polling, IT) */ + hfmac->pOutput = pOutput; + hfmac->pOutputSize = pOutputSize; + hfmac->RdState = HAL_FMAC_STATE_BUSY_RD; + } + + return HAL_OK; +} + +/** + * @brief Read available output data until Y EMPTY is set. + * @param hfmac FMAC handle. + * @param MaxSizeToRead Maximum number of data to read (this serves as a timeout + * if FMAC continuously writes into the output buffer). + * @retval None + */ +static void FMAC_ReadDataIncrementPtr(FMAC_HandleTypeDef *hfmac, uint16_t MaxSizeToRead) +{ + uint16_t maxsize; + uint16_t threshold; + uint32_t tmpvalue; + + /* Check if there is data to read */ + if (READ_BIT(hfmac->Instance->SR, FMAC_SR_YEMPTY) != 0U) + { + return; + } + + /* Get the maximum index (no wait allowed, no overstepping of the output buffer) */ + if ((hfmac->OutputCurrentSize + MaxSizeToRead) > *(hfmac->pOutputSize)) + { + maxsize = *(hfmac->pOutputSize); + } + else + { + maxsize = hfmac->OutputCurrentSize + MaxSizeToRead; + } + + /* Read until there is no more room or no more data */ + do + { + /* If there is no more room, return */ + if (!(hfmac->OutputCurrentSize < maxsize)) + { + return; + } + + /* Read the available data */ + tmpvalue = ((READ_REG(hfmac->Instance->RDATA))& FMAC_RDATA_RDATA); + *(hfmac->pOutput) = (int16_t)tmpvalue; + hfmac->pOutput++; + hfmac->OutputCurrentSize++; + } while (READ_BIT(hfmac->Instance->SR, FMAC_SR_YEMPTY) == 0U); + + /* Y buffer empty flag has just be raised, read the threshold */ + threshold = (uint16_t)FMAC_GET_THRESHOLD_FROM_WM(FMAC_GET_Y_EMPTY_WM(hfmac)) - 1U; + + /* Update the maximum size if needed (limited data available) */ + if ((hfmac->OutputCurrentSize + threshold) < maxsize) + { + maxsize = hfmac->OutputCurrentSize + threshold; + } + + /* Read the available data */ + while (hfmac->OutputCurrentSize < maxsize) + { + tmpvalue = ((READ_REG(hfmac->Instance->RDATA))& FMAC_RDATA_RDATA); + *(hfmac->pOutput) = (int16_t)tmpvalue; + hfmac->pOutput++; + hfmac->OutputCurrentSize++; + } +} + +/** + * @brief Write available input data until X1 FULL is set. + * @param hfmac FMAC handle. + * @param MaxSizeToWrite Maximum number of data to write (this serves as a timeout + * if FMAC continuously empties the input buffer). + * @retval None + */ +static void FMAC_WriteDataIncrementPtr(FMAC_HandleTypeDef *hfmac, uint16_t MaxSizeToWrite) +{ + uint16_t maxsize; + uint16_t threshold; + + /* Check if there is room in FMAC */ + if (READ_BIT(hfmac->Instance->SR, FMAC_SR_X1FULL) != 0U) + { + return; + } + + /* Get the maximum index (no wait allowed, no overstepping of the output buffer) */ + if ((hfmac->InputCurrentSize + MaxSizeToWrite) > *(hfmac->pInputSize)) + { + maxsize = *(hfmac->pInputSize); + } + else + { + maxsize = hfmac->InputCurrentSize + MaxSizeToWrite; + } + + /* Write until there is no more room or no more data */ + do + { + /* If there is no more room, return */ + if (!(hfmac->InputCurrentSize < maxsize)) + { + return; + } + + /* Write the available data */ + WRITE_REG(hfmac->Instance->WDATA, (((uint32_t)(*(hfmac->pInput))) & FMAC_WDATA_WDATA)); + hfmac->pInput++; + hfmac->InputCurrentSize++; + } while (READ_BIT(hfmac->Instance->SR, FMAC_SR_X1FULL) == 0U); + + /* X1 buffer full flag has just be raised, read the threshold */ + threshold = (uint16_t)FMAC_GET_THRESHOLD_FROM_WM(FMAC_GET_X1_FULL_WM(hfmac)) - 1U; + + /* Update the maximum size if needed (limited data available) */ + if ((hfmac->InputCurrentSize + threshold) < maxsize) + { + maxsize = hfmac->InputCurrentSize + threshold; + } + + /* Write the available data */ + while (hfmac->InputCurrentSize < maxsize) + { + WRITE_REG(hfmac->Instance->WDATA, (((uint32_t)(*(hfmac->pInput))) & FMAC_WDATA_WDATA)); + hfmac->pInput++; + hfmac->InputCurrentSize++; + } +} + +/** + * @brief DMA FMAC Input Data process half complete callback. + * @param hdma DMA handle. + * @retval None + */ +static void FMAC_DMAHalfGetData(DMA_HandleTypeDef *hdma) +{ + FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Call half get data callback */ +#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) + hfmac->HalfGetDataCallback(hfmac); +#else + HAL_FMAC_HalfGetDataCallback(hfmac); +#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA FMAC Input Data process complete callback. + * @param hdma DMA handle. + * @retval None + */ +static void FMAC_DMAGetData(DMA_HandleTypeDef *hdma) +{ + FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Reset the pointers to indicate new data will be needed */ + FMAC_ResetInputStateAndDataPointers(hfmac); + + /* Call get data callback */ +#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) + hfmac->GetDataCallback(hfmac); +#else + HAL_FMAC_GetDataCallback(hfmac); +#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA FMAC Output Data process half complete callback. + * @param hdma DMA handle. + * @retval None + */ +static void FMAC_DMAHalfOutputDataReady(DMA_HandleTypeDef *hdma) +{ + FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Call half output data ready callback */ +#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) + hfmac->HalfOutputDataReadyCallback(hfmac); +#else + HAL_FMAC_HalfOutputDataReadyCallback(hfmac); +#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA FMAC Output Data process complete callback. + * @param hdma DMA handle. + * @retval None + */ +static void FMAC_DMAOutputDataReady(DMA_HandleTypeDef *hdma) +{ + FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Reset the pointers to indicate new data will be needed */ + FMAC_ResetOutputStateAndDataPointers(hfmac); + + /* Call output data ready callback */ +#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) + hfmac->OutputDataReadyCallback(hfmac); +#else + HAL_FMAC_OutputDataReadyCallback(hfmac); +#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA FMAC Filter Configuration process complete callback. + * @param hdma DMA handle. + * @retval None + */ +static void FMAC_DMAFilterConfig(DMA_HandleTypeDef *hdma) +{ + HAL_StatusTypeDef status; + uint8_t index; + + FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* If needed, write CoeffA and exit */ + if (hfmac->pInput != NULL) + { + /* Set the FMAC DMA transfer complete callback */ + hfmac->hdmaPreload->XferHalfCpltCallback = NULL; + hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterConfig; + /* Set the DMA error callback */ + hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError; + + /* Enable the DMA stream managing FMAC preload data write */ + if ((hfmac->hdmaPreload->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hfmac->hdmaPreload->LinkedListQueue != NULL) && (hfmac->hdmaPreload->LinkedListQueue->Head != NULL)) + { + /* Enable the DMA channel */ + hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = + (uint32_t)(2UL * hfmac->InputCurrentSize);/* Set DMA data size */ + hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = + (uint32_t)hfmac->pInput; /* Set DMA source address */ + hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = + (uint32_t)&hfmac->Instance->WDATA; /* Set DMA destination address */ + + status = HAL_DMAEx_List_Start_IT(hfmac->hdmaPreload); + } + else + { + /* Return error status */ + status = HAL_ERROR; + } + } + else + { + status = HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)hfmac->pInput, \ + (uint32_t)&hfmac->Instance->WDATA, (uint32_t)(2UL * hfmac->InputCurrentSize)); + } + + if (status == HAL_OK) + { + hfmac->pInput = NULL; + hfmac->InputCurrentSize = 0U; + return; + } + + /* If not exited, there was an error: set FMAC handle state to error */ + hfmac->State = HAL_FMAC_STATE_ERROR; + } + else + { + /* Wait for the end of the writing */ + for (index = 0U; index < MAX_PRELOAD_INDEX; index++) + { + if (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) == 0U) + { + break; + } + } + + /* If 'START' is still set, there was a timeout: set FMAC handle state to timeout */ + if (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) != 0U) + { + hfmac->State = HAL_FMAC_STATE_TIMEOUT; + } + else + { + /* Change the FMAC state */ + hfmac->State = HAL_FMAC_STATE_READY; + + /* Call output data ready callback */ +#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) + hfmac->FilterConfigCallback(hfmac); +#else + HAL_FMAC_FilterConfigCallback(hfmac); +#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ + return; + } + } + + /* If not exited, there was an error: set FMAC handle error code to DMA error */ + hfmac->ErrorCode |= HAL_FMAC_ERROR_DMA; + + /* Call user callback */ +#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) + hfmac->ErrorCallback(hfmac); +#else + HAL_FMAC_ErrorCallback(hfmac); +#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ + +} + +/** + * @brief DMA FMAC Filter Configuration process complete callback. + * @param hdma DMA handle. + * @retval None + */ +static void FMAC_DMAFilterPreload(DMA_HandleTypeDef *hdma) +{ + HAL_StatusTypeDef status; + uint8_t index; + + FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Wait for the end of the X1 writing */ + for (index = 0U; index < MAX_PRELOAD_INDEX; index++) + { + if (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) == 0U) + { + break; + } + } + + /* If 'START' is still set, there was an error: set FMAC handle state to error */ + if (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) != 0U) + { + hfmac->State = HAL_FMAC_STATE_TIMEOUT; + hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT; + } + /* If needed, preload Y buffer */ + else if ((hfmac->pInput != NULL) && (hfmac->InputCurrentSize != 0U)) + { + /* Write number of values to be loaded, the data load function and start the operation */ + WRITE_REG(hfmac->Instance->PARAM, \ + (((uint32_t)(hfmac->InputCurrentSize) << FMAC_PARAM_P_Pos) | FMAC_FUNC_LOAD_Y | FMAC_PARAM_START)); + + /* Set the FMAC DMA transfer complete callback */ + hfmac->hdmaPreload->XferHalfCpltCallback = NULL; + hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterPreload; + /* Set the DMA error callback */ + hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError; + + /* Enable the DMA stream managing FMAC preload data write */ + if ((hfmac->hdmaPreload->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hfmac->hdmaPreload->LinkedListQueue != NULL) && (hfmac->hdmaPreload->LinkedListQueue->Head != NULL)) + { + /* Enable the DMA channel */ + hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = + (uint32_t)(2UL * hfmac->InputCurrentSize);/* Set DMA data size */ + hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = + (uint32_t)hfmac->pInput; /* Set DMA source address */ + hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = + (uint32_t)&hfmac->Instance->WDATA; /* Set DMA destination address */ + + status = HAL_DMAEx_List_Start_IT(hfmac->hdmaPreload); + } + else + { + /* Return error status */ + status = HAL_ERROR; + } + } + else + { + status = HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)hfmac->pInput, \ + (uint32_t)&hfmac->Instance->WDATA, (uint32_t)(2UL * hfmac->InputCurrentSize)); + } + + if (status == HAL_OK) + { + hfmac->pInput = NULL; + hfmac->InputCurrentSize = 0U; + return; + } + + /* If not exited, there was an error */ + hfmac->ErrorCode = HAL_FMAC_ERROR_DMA; + hfmac->State = HAL_FMAC_STATE_ERROR; + } + else + { + /* nothing to do */ + } + + if (hfmac->ErrorCode == HAL_FMAC_ERROR_NONE) + { + /* Change the FMAC state */ + hfmac->State = HAL_FMAC_STATE_READY; + + /* Call output data ready callback */ +#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) + hfmac->FilterPreloadCallback(hfmac); +#else + HAL_FMAC_FilterPreloadCallback(hfmac); +#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ + } + else + { + /* Call user callback */ +#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) + hfmac->ErrorCallback(hfmac); +#else + HAL_FMAC_ErrorCallback(hfmac); +#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ + } +} + + +/** + * @brief DMA FMAC communication error callback. + * @param hdma DMA handle. + * @retval None + */ +static void FMAC_DMAError(DMA_HandleTypeDef *hdma) +{ + FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Set FMAC handle state to error */ + hfmac->State = HAL_FMAC_STATE_ERROR; + + /* Set FMAC handle error code to DMA error */ + hfmac->ErrorCode |= HAL_FMAC_ERROR_DMA; + + /* Call user callback */ +#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) + hfmac->ErrorCallback(hfmac); +#else + HAL_FMAC_ErrorCallback(hfmac); +#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ +} +/** + * @} + */ + + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_FMAC_MODULE_ENABLED */ +#endif /* FMAC */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_gpio.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_gpio.c new file mode 100644 index 0000000000..12f9e46837 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_gpio.c @@ -0,0 +1,753 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_gpio.c + * @author MCD Application Team + * @brief GPIO HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the General Purpose Input/Output (GPIO) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### GPIO Peripheral features ##### + ============================================================================== + [..] + (+) Each port bit of the general-purpose I/O (GPIO) ports can be individually + configured by software in several modes: + (++) Input mode + (++) Analog mode + (++) Output mode + (++) Alternate function mode + (++) External interrupt/event lines + + (+) During and just after reset, the alternate functions and external interrupt + lines are not active and the I/O ports are configured in input floating mode. + + (+) All GPIO pins have weak internal pull-up and pull-down resistors, which can be + activated or not. + + (+) In Output or Alternate mode, each IO can be configured on open-drain or push-pull + type and the IO speed can be selected depending on the VDD value. + + (+) The microcontroller IO pins are connected to onboard peripherals/modules through a + multiplexer that allows only one peripheral alternate function (AF) connected + to an IO pin at a time. In this way, there can be no conflict between peripherals + sharing the same IO pin. + + (+) All ports have external interrupt/event capability. To use external interrupt + lines, the port must be configured in input mode. All available GPIO pins are + connected to the 16 external interrupt/event lines from EXTI0 to EXTI15. + + (+) The external interrupt/event controller consists of up to 39 edge detectors + (16 lines are connected to GPIO) for generating event/interrupt requests (each + input line can be independently configured to select the type (interrupt or event) + and the corresponding trigger event (rising or falling or both). Each line can + also be masked independently. + + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Enable the GPIO AHB clock using the following function: __HAL_RCC_GPIOx_CLK_ENABLE(). + + (#) Configure the GPIO pin(s) using HAL_GPIO_Init(). + (++) Configure the IO mode using "Mode" member from GPIO_InitTypeDef structure + (++) Activate Pull-up, Pull-down resistor using "Pull" member from GPIO_InitTypeDef + structure. + (++) In case of Output or alternate function mode selection: the speed is + configured through "Speed" member from GPIO_InitTypeDef structure. + (++) In alternate mode is selection, the alternate function connected to the IO + is configured through "Alternate" member from GPIO_InitTypeDef structure. + (++) Analog mode is required when a pin is to be used as ADC channel + or DAC output. + (++) In case of external interrupt/event selection the "Mode" member from + GPIO_InitTypeDef structure select the type (interrupt or event) and + the corresponding trigger event (rising or falling or both). + + (#) In case of external interrupt/event mode selection, configure NVIC IRQ priority + mapped to the EXTI line using HAL_NVIC_SetPriority() and enable it using + HAL_NVIC_EnableIRQ(). + + (#) To get the level of a pin configured in input mode use HAL_GPIO_ReadPin(). + + (#) To set/reset the level of a pin configured in output mode use + HAL_GPIO_WritePin()/HAL_GPIO_TogglePin(). + + (#) To set the level of several pins and reset level of several other pins in + same cycle, use HAL_GPIO_WriteMultipleStatePin(). + + (#) To lock pin configuration until next reset use HAL_GPIO_LockPin(). + + (#) During and just after reset, the alternate functions are not + active and the GPIO pins are configured in input floating mode (except JTAG + pins). + + (#) The LSE oscillator pins OSC32_IN and OSC32_OUT can be used as general purpose + (PC14 and PC15, respectively) when the LSE oscillator is off. The LSE has + priority over the GPIO function. + + (#) The HSE oscillator pins OSC_IN/OSC_OUT can be used as + general purpose PH0 and PH1, respectively, when the HSE oscillator is off. + The HSE has priority over the GPIO function. + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup GPIO GPIO + * @brief GPIO HAL module driver + * @{ + */ + +#ifdef HAL_GPIO_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ +/** @defgroup GPIO_Private_Defines GPIO Private Defines + * @{ + */ +#define GPIO_MODE (0x00000003U) +#define EXTI_MODE (0x10000000U) +#define GPIO_MODE_IT (0x00010000U) +#define GPIO_MODE_EVT (0x00020000U) +#define RISING_EDGE (0x00100000U) +#define FALLING_EDGE (0x00200000U) +#define GPIO_OUTPUT_TYPE (0x00000010U) +#define GPIO_NUMBER (16U) + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/** @defgroup GPIO_Private_Macros GPIO Private Macros + * @{ + */ +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup GPIO_Exported_Functions GPIO Exported Functions + * @{ + */ + +/** @defgroup GPIO_Exported_Functions_Group1 Initialization/de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the GPIOx peripheral according to the specified parameters in the pGPIO_Init. + * @note If GPIOx peripheral pin is used in EXTI_MODE and the pin is secure in case + * the system implements the security (TZEN=1), it is up to the secure application to + * insure that the corresponding EXTI line is set secure. + * @param GPIOx: where x can be (A..I) for stm32h56xxx and stm32h57xxx family lines and + * (A..D or H) for stm32h503xx family line to select the GPIO peripheral for STM32H5 family + * @param pGPIO_Init: pointer to a GPIO_InitTypeDef structure that contains + * the configuration information for the specified GPIO peripheral. + * @retval None + */ +void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, const GPIO_InitTypeDef *pGPIO_Init) +{ + uint32_t tmp; + uint32_t iocurrent; + uint32_t position = 0U; + + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_INSTANCE(GPIOx)); + assert_param(IS_GPIO_PIN(pGPIO_Init->Pin)); + assert_param(IS_GPIO_MODE(pGPIO_Init->Mode)); + assert_param(IS_GPIO_PULL(pGPIO_Init->Pull)); + + /* Configure the port pins */ + while (((pGPIO_Init->Pin) >> position) != 0U) + { + /* Get current io position */ + iocurrent = (pGPIO_Init->Pin) & (1UL << position); + + if (iocurrent != 0U) + { + /*--------------------- GPIO Mode Configuration ------------------------*/ + /* In case of Alternate function mode selection */ + if ((pGPIO_Init->Mode == GPIO_MODE_AF_PP) || (pGPIO_Init->Mode == GPIO_MODE_AF_OD)) + { + /* Check the Alternate function parameters */ + assert_param(IS_GPIO_AF_INSTANCE(GPIOx)); + assert_param(IS_GPIO_AF(pGPIO_Init->Alternate)); + + /* Configure Alternate function mapped with the current IO */ + tmp = GPIOx->AFR[position >> 3U]; + tmp &= ~(0x0FUL << ((position & 0x07U) * 4U)); + tmp |= ((pGPIO_Init->Alternate & 0x0FUL) << ((position & 0x07U) * 4U)); + GPIOx->AFR[position >> 3U] = tmp; + } + + /* Configure IO Direction mode (Input, Output, Alternate or Analog) */ + tmp = GPIOx->MODER; + tmp &= ~(GPIO_MODER_MODE0 << (position * 2U)); + tmp |= ((pGPIO_Init->Mode & GPIO_MODE) << (position * 2U)); + GPIOx->MODER = tmp; + + /* In case of Output or Alternate function mode selection */ + if ((pGPIO_Init->Mode == GPIO_MODE_OUTPUT_PP) || (pGPIO_Init->Mode == GPIO_MODE_AF_PP) || + (pGPIO_Init->Mode == GPIO_MODE_OUTPUT_OD) || (pGPIO_Init->Mode == GPIO_MODE_AF_OD)) + { + /* Check the Speed parameter */ + assert_param(IS_GPIO_SPEED(pGPIO_Init->Speed)); + + /* Configure the IO Speed */ + tmp = GPIOx->OSPEEDR; + tmp &= ~(GPIO_OSPEEDR_OSPEED0 << (position * 2U)); + tmp |= (pGPIO_Init->Speed << (position * 2U)); + GPIOx->OSPEEDR = tmp; + + /* Configure the IO Output Type */ + tmp = GPIOx->OTYPER; + tmp &= ~(GPIO_OTYPER_OT0 << position) ; + tmp |= (((pGPIO_Init->Mode & GPIO_OUTPUT_TYPE) >> 4U) << position); + GPIOx->OTYPER = tmp; + } + + if (pGPIO_Init->Mode != GPIO_MODE_ANALOG) + { + /* Check the Pull parameters */ + assert_param(IS_GPIO_PULL(pGPIO_Init->Pull)); + + /* Activate the Pull-up or Pull down resistor for the current IO */ + tmp = GPIOx->PUPDR; + tmp &= ~(GPIO_PUPDR_PUPD0 << (position * 2U)); + tmp |= ((pGPIO_Init->Pull) << (position * 2U)); + GPIOx->PUPDR = tmp; + } + + /*--------------------- EXTI Mode Configuration ------------------------*/ + /* Configure the External Interrupt or event for the current IO */ + if ((pGPIO_Init->Mode & EXTI_MODE) == EXTI_MODE) + { + tmp = EXTI->EXTICR[position >> 2U]; + tmp &= ~((0x0FUL) << (8U * (position & 0x03U))); + tmp |= (GPIO_GET_INDEX(GPIOx) << (8U * (position & 0x03U))); + EXTI->EXTICR[position >> 2U] = tmp; + + /* Clear Rising Falling edge configuration */ + tmp = EXTI->RTSR1; + tmp &= ~((uint32_t)iocurrent); + if ((pGPIO_Init->Mode & RISING_EDGE) == RISING_EDGE) + { + tmp |= iocurrent; + } + EXTI->RTSR1 = tmp; + + tmp = EXTI->FTSR1; + tmp &= ~((uint32_t)iocurrent); + if ((pGPIO_Init->Mode & FALLING_EDGE) == FALLING_EDGE) + { + tmp |= iocurrent; + } + EXTI->FTSR1 = tmp; + + /* Clear EXTI line configuration */ + tmp = EXTI->EMR1; + tmp &= ~((uint32_t)iocurrent); + if ((pGPIO_Init->Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT) + { + tmp |= iocurrent; + } + EXTI->EMR1 = tmp; + + tmp = EXTI->IMR1; + tmp &= ~((uint32_t)iocurrent); + if ((pGPIO_Init->Mode & GPIO_MODE_IT) == GPIO_MODE_IT) + { + tmp |= iocurrent; + } + EXTI->IMR1 = tmp; + } + } + + position++; + } +} + +/** + * @brief De-initialize the GPIOx peripheral registers to their default reset values. + * @param GPIOx: where x can be (A..I) for stm32h56xxx and stm32h57xxx family lines and + * (A..D or H) for stm32h503xx family line to select the GPIO peripheral for STM32H5 family + * @param GPIO_Pin: specifies the port bit to be written. + * This parameter can be one of GPIO_PIN_x where x can be (0..15). + * @retval None + */ +void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin) +{ + uint32_t tmp; + uint32_t iocurrent; + uint32_t position = 0U; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_INSTANCE(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + /* Configure the port pins */ + while ((GPIO_Pin >> position) != 0U) + { + /* Get current io position */ + iocurrent = (GPIO_Pin) & (1UL << position); + + if (iocurrent != 0U) + { + /*------------------------- EXTI Mode Configuration --------------------*/ + /* Clear the External Interrupt or Event for the current IO */ + tmp = EXTI->EXTICR[position >> 2U]; + tmp &= ((0x0FUL) << (8U * (position & 0x03U))); + if (tmp == (GPIO_GET_INDEX(GPIOx) << (8U * (position & 0x03U)))) + { + /* Clear EXTI line configuration */ + EXTI->IMR1 &= ~(iocurrent); + EXTI->EMR1 &= ~(iocurrent); + + /* Clear Rising Falling edge configuration */ + EXTI->RTSR1 &= ~(iocurrent); + EXTI->FTSR1 &= ~(iocurrent); + + tmp = (0x0FUL) << (8U * (position & 0x03U)); + EXTI->EXTICR[position >> 2U] &= ~tmp; + } + + /*------------------------- GPIO Mode Configuration --------------------*/ + /* Configure IO in Analog Mode */ + GPIOx->MODER |= (GPIO_MODER_MODE0 << (position * 2U)); + + /* Configure the default Alternate Function in current IO */ + GPIOx->AFR[position >> 3U] &= ~(0x0FUL << ((position & 0x07U) * 4U)); + + /* Configure the default value for IO Speed */ + GPIOx->OSPEEDR &= ~(GPIO_OSPEEDR_OSPEED0 << (position * 2U)); + + /* Configure the default value IO Output Type */ + GPIOx->OTYPER &= ~(GPIO_OTYPER_OT0 << position); + + /* Deactivate the Pull-up and Pull-down resistor for the current IO */ + GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPD0 << (position * 2U)); + } + + position++; + } +} + +/** + * @} + */ + +/** @defgroup GPIO_Exported_Functions_Group2 IO operation functions + * @brief GPIO Read, Write, Toggle, Lock and EXTI management functions. + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Read the specified input port pin. + * @param GPIOx: where x can be (A..I) for stm32h56xxx and stm32h57xxx family lines and + * (A..D or H) for stm32h503xx family line to select the GPIO peripheral for STM32H5 family + * @param GPIO_Pin: specifies the port bit to read. + * This parameter can be GPIO_PIN_x where x can be (0..15). + * @retval The input port pin value. + */ +GPIO_PinState HAL_GPIO_ReadPin(const GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin) +{ + GPIO_PinState bitstatus; + + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + if ((GPIOx->IDR & GPIO_Pin) != 0U) + { + bitstatus = GPIO_PIN_SET; + } + else + { + bitstatus = GPIO_PIN_RESET; + } + return bitstatus; +} + +/** + * @brief Set or clear the selected data port bit. + * + * @note This function uses GPIOx_BSRR and GPIOx_BRR registers to allow atomic read/modify + * accesses. In this way, there is no risk of an IRQ occurring between + * the read and the modify access. + * + * @param GPIOx: where x can be (A..I) for stm32h56xxx and stm32h57xxx family lines and + * (A..D or H) for stm32h503xx family line to select the GPIO peripheral for STM32H5 family + * @param GPIO_Pin: specifies the port bit to be written. + * This parameter can be one of GPIO_PIN_x where x can be (0..15). + * @param PinState: specifies the value to be written to the selected bit. + * This parameter can be one of the GPIO_PinState enum values: + * @arg GPIO_PIN_RESET: to clear the port pin + * @arg GPIO_PIN_SET: to set the port pin + * @retval None + */ +void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState) +{ + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + assert_param(IS_GPIO_PIN_ACTION(PinState)); + + if (PinState != GPIO_PIN_RESET) + { + GPIOx->BSRR = (uint32_t)GPIO_Pin; + } + else + { + GPIOx->BRR = (uint32_t)GPIO_Pin; + } +} + +/** + * @brief Set and clear several pins of a dedicated port in same cycle. + * @note This function uses GPIOx_BSRR and GPIOx_BRR registers to allow atomic read/modify + * accesses. + * @param GPIOx: where x can be (A..I) for stm32h56xxx and stm32h57xxx family lines and + * (A..D or H) for stm32h503xx family line to select the GPIO peripheral for STM32H5 family + * @param PinReset specifies the port bits to be reset + * This parameter can be any combination of GPIO_Pin_x where x can be (0..15) or zero. + * @param PinSet specifies the port bits to be set + * This parameter can be any combination of GPIO_Pin_x where x can be (0..15) or zero. + * @note Both PinReset and PinSet combinations shall not get any common bit, else + * assert would be triggered. + * @note At least one of the two parameters used to set or reset shall be different from zero. + * @retval None + */ +void HAL_GPIO_WriteMultipleStatePin(GPIO_TypeDef *GPIOx, uint16_t PinReset, uint16_t PinSet) +{ + uint32_t tmp; + + /* Check the parameters */ + /* Make sure at least one parameter is different from zero and that there is no common pin */ + assert_param(IS_GPIO_PIN((uint32_t)PinReset | (uint32_t)PinSet)); + assert_param(IS_GPIO_COMMON_PIN(PinReset, PinSet)); + + tmp = (((uint32_t)PinReset << 16) | PinSet); + GPIOx->BSRR = tmp; +} + +/** + * @brief Toggle the specified GPIO pin. + * @param GPIOx: where x can be (A..I) to select the GPIO peripheral for STM32H5 family + * @param GPIO_Pin: specifies the pin to be toggled. + * @retval None + */ +void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin) +{ + uint32_t odr; + + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + /* get current Output Data Register value */ + odr = GPIOx->ODR; + + /* Set selected pins that were at low level, and reset ones that were high */ + GPIOx->BSRR = ((odr & GPIO_Pin) << GPIO_NUMBER) | (~odr & GPIO_Pin); +} + +/** + * @brief Lock GPIO Pins configuration registers. + * @note The locked registers are GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR, + * GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH. + * @note The configuration of the locked GPIO pins can no longer be modified + * until the next reset. + * @param GPIOx: where x can be (A..I) for stm32h56xxx and stm32h57xxx family lines and + * (A..D or H) for stm32h503xx family line to select the GPIO peripheral for STM32H5 family + * @param GPIO_Pin: specifies the port bits to be locked. + * This parameter can be any combination of GPIO_Pin_x where x can be (0..15). + * @retval None + */ +HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin) +{ + __IO uint32_t tmp = GPIO_LCKR_LCKK; + + /* Check the parameters */ + assert_param(IS_GPIO_LOCK_INSTANCE(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + /* Apply lock key write sequence */ + tmp |= GPIO_Pin; + /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */ + GPIOx->LCKR = tmp; + /* Reset LCKx bit(s): LCKK='0' + LCK[15-0] */ + GPIOx->LCKR = GPIO_Pin; + /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */ + GPIOx->LCKR = tmp; + /* Read LCKK bit*/ + tmp = GPIOx->LCKR; + + /* read again in order to confirm lock is active */ + if ((GPIOx->LCKR & GPIO_LCKR_LCKK) != GPIO_LCKR_LCKK) + { + return HAL_ERROR; + } + return HAL_OK; +} + +/** + * @brief Enable speed optimization for several pin of dedicated port. + * @note Not all I/Os support the HSLV mode. Refer to the I/O structure in the corresponding + * datasheet for the list of I/Os supporting this feature. Other I/Os HSLV configuration must + * be kept at reset value. + * @note It must be used only if the I/O supply voltage is below 2.7 V. + * @param GPIOx: where x can be (A..I) for stm32h56xxx and stm32h57xxx family lines and + * (A..D or H) for stm32h503xx family line to select the GPIO peripheral for STM32H5 family + * @param GPIO_Pin: specifies the port bit to be written. + * This parameter can be any combination of GPIO_Pin_x where x can be (0..15). + * @retval None + */ +void HAL_GPIO_EnableHighSPeedLowVoltage(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin) +{ + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + assert_param(IS_GPIO_ALL_INSTANCE(GPIOx)); + + /* Set HSLVR gpio pin */ + SET_BIT(GPIOx->HSLVR, GPIO_Pin); +} + +/** + * @brief Disable speed optimization for several pin of dedicated port. + * @note Not all I/Os support the HSLV mode. Refer to the I/O structure in the corresponding + * datasheet for the list of I/Os supporting this feature. Other I/Os HSLV configuration must + * be kept at reset value. + * @note It must be used only if the I/O supply voltage is below 2.7 V. + * @param GPIOx: where x can be (A..I) for stm32h56xxx and stm32h57xxx family lines and + * (A..D or H) for stm32h503xx family line to select the GPIO peripheral for STM32H5 family + * @param GPIO_Pin: specifies the port bit to be written. + * This parameter can be any combination of GPIO_Pin_x where x can be (0..15). + * @retval None + */ +void HAL_GPIO_DisableHighSPeedLowVoltage(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin) +{ + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + assert_param(IS_GPIO_ALL_INSTANCE(GPIOx)); + + /* Clear HSLVR gpio pin */ + CLEAR_BIT(GPIOx->HSLVR, GPIO_Pin); +} + +/** + * @brief Handle EXTI interrupt request. + * @param GPIO_Pin: Specifies the port pin connected to corresponding EXTI line. + * @retval None + */ +void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin) +{ + /* EXTI line interrupt detected */ + if (__HAL_GPIO_EXTI_GET_RISING_IT(GPIO_Pin) != 0U) + { + __HAL_GPIO_EXTI_CLEAR_RISING_IT(GPIO_Pin); + HAL_GPIO_EXTI_Rising_Callback(GPIO_Pin); + } + + if (__HAL_GPIO_EXTI_GET_FALLING_IT(GPIO_Pin) != 0U) + { + __HAL_GPIO_EXTI_CLEAR_FALLING_IT(GPIO_Pin); + HAL_GPIO_EXTI_Falling_Callback(GPIO_Pin); + } +} + +/** + * @brief EXTI line rising detection callback. + * @param GPIO_Pin: Specifies the port pin connected to corresponding EXTI line. + * @retval None + */ +__weak void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(GPIO_Pin); + + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_GPIO_EXTI_Rising_Callback could be implemented in the user file + */ +} + +/** + * @brief EXTI line falling detection callback. + * @param GPIO_Pin: Specifies the port pin connected to corresponding EXTI line. + * @retval None + */ +__weak void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(GPIO_Pin); + + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_GPIO_EXTI_Falling_Callback could be implemented in the user file + */ +} + +/** + * @} + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** @defgroup GPIO_Exported_Functions_Group3 IO attributes management functions + * @brief GPIO attributes management functions. + * +@verbatim + =============================================================================== + ##### IO attributes functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Configure the GPIO pins attributes. + * @note Available attributes are to secure GPIO pin(s), so this function is + * only available in secure + * @param GPIOx: where x can be (A..I) for stm32h56xxx and stm32h57xxx family lines and + * (A..D or H) for stm32h503xx family line to select the GPIO peripheral for STM32H5 family + * @param GPIO_Pin: specifies the pin(s) to configure the secure attribute + * @param PinAttributes: specifies the pin(s) to be set in secure mode, other being set non secured. + * @retval None + */ +void HAL_GPIO_ConfigPinAttributes(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, uint32_t PinAttributes) +{ + uint32_t tmp; + uint32_t iocurrent; + uint32_t position = 0U; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_INSTANCE(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_Pin)); + assert_param(IS_GPIO_PIN_ATTRIBUTES(PinAttributes)); + + tmp = GPIOx->SECCFGR; + + /* Configure the port pins */ + while ((GPIO_Pin >> position) != 0U) + { + /* Get current io position */ + iocurrent = GPIO_Pin & (1UL << position); + + if (iocurrent != 0U) + { + /* Configure the IO secure attribute */ + tmp &= ~(GPIO_SECCFGR_SEC0 << position); + tmp |= (PinAttributes << position); + } + position++; + } + + /* Set secure attributes */ + GPIOx->SECCFGR = tmp; +} + +/** + * @brief Get the GPIO pins attributes. + * @note Available attributes are to secure GPIO pin(s), so this function is + * only available in secure + * @param GPIOx: where x can be (A..I) for stm32h56xxx and stm32h57xxx family lines and + * (A..D or H) for stm32h503xx family line to select the GPIO peripheral for STM32H5 family + * @param GPIO_Pin: specifies the single pin to get the secure attribute from + * @param pPinAttributes: pointer to return the pin attributes. + * @retval HAL Status. + */ +HAL_StatusTypeDef HAL_GPIO_GetConfigPinAttributes(const GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, + uint32_t *pPinAttributes) +{ + uint32_t iocurrent; + uint32_t position = 0U; + + /* Check null pointer */ + if (pPinAttributes == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_INSTANCE(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_Pin) && (GPIO_Pin != GPIO_PIN_ALL)); + + /* Get secure attribute of the port pin */ + while ((GPIO_Pin >> position) != 0U) + { + /* Get current io position */ + iocurrent = GPIO_Pin & (1UL << position); + + if (iocurrent != 0U) + { + /* Get the IO secure attribute */ + if ((GPIOx->SECCFGR & (GPIO_SECCFGR_SEC0 << position)) != 0U) + { + *pPinAttributes = GPIO_PIN_SEC; + } + else + { + *pPinAttributes = GPIO_PIN_NSEC; + } + + break; + } + position++; + } + + return HAL_OK; +} + +/** + * @} + */ + +#endif /* __ARM_FEATURE_CMSE */ + + +/** + * @} + */ + +#endif /* HAL_GPIO_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_gtzc.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_gtzc.c new file mode 100644 index 0000000000..409523d7f1 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_gtzc.c @@ -0,0 +1,1852 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_gtzc.c + * @author MCD Application Team + * @brief GTZC HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of GTZC peripheral: + * + TZSC Initialization and Configuration functions + * + TZSC-MPCWM Initialization and Configuration functions + * + MPCBB Initialization and Configuration functions + * + TZSC, TZSC-MPCWM and MPCBB Lock functions + * + TZIC Initialization and Configuration functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### GTZC main features ##### + ============================================================================== + [..] + (+) Global TrustZone Controller (GTZC) composed of three sub-blocks: + (++) TZSC: TrustZone security controller + This sub-block defines the secure/privileged state of master and slave + peripherals. It also controls the secure/privileged state of subregions + for the watermark memory peripheral controller (MPCWM). + (++) MPCBB: Block-Based memory protection controller + This sub-block defines the secure/privileged state of all blocks + (512-byte pages) of the associated SRAM. + (++) TZIC: TrustZone illegal access controller + This sub-block gathers all illegal access events in the system and + generates a secure interrupt towards NVIC. + + (+) These sub-blocks are used to configure TrustZone system security in + a product having bus agents with programmable-security and privileged + attributes (securable) such as: + (++) on-chip RAM with programmable secure and/or privilege blocks (pages) + (++) AHB and APB peripherals with programmable security and/or privilege access + (++) AHB master granted as secure and/or privilege + (++) off-chip memories with secure and/or privilege areas + + [..] + (+) TZIC accessible only with secure privileged transactions. + (+) Secure and non-secure access supported for privileged and unprivileged + part of TZSC and MPCBB + (+) Set of registers to define product security settings: + (++) Secure and privilege blocks for internal memories + (++) Secure and privilege regions for external memories + (++) Secure and privileged access mode for securable peripherals + + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The GTZC HAL driver can be used as follows: + + (#) Configure or get back securable peripherals attributes using + HAL_GTZC_TZSC_ConfigPeriphAttributes() / HAL_GTZC_TZSC_GetConfigPeriphAttributes() + + (#) Configure or get back MPCWM memories attributes using + HAL_GTZC_TZSC_MPCWM_ConfigMemAttributes() / HAL_GTZC_TZSC_MPCWM_GetConfigMemAttributes() + + (#) Lock TZSC sub-block or get lock status using HAL_GTZC_TZSC_Lock() / + HAL_GTZC_TZSC_GetLock() + + (#) Configure or get back MPCBB memories complete configuration using + HAL_GTZC_MPCBB_ConfigMem() / HAL_GTZC_MPCBB_GetConfigMem() + + (#) Configure or get back MPCBB memories attributes using + HAL_GTZC_MPCBB_ConfigMemAttributes() / HAL_GTZC_MPCBB_GetConfigMemAttributes() + + (#) Lock MPCBB configuration or get lock status using HAL_GTZC_MPCBB_Lock() / + HAL_GTZC_MPCBB_GetLock() + + (#) Lock MPCBB super-blocks or get lock status using HAL_GTZC_MPCBB_LockConfig() / + HAL_GTZC_MPCBB_GetLockConfig() + + (#) Illegal access detection can be configured through TZIC sub-block using + following functions: HAL_GTZC_TZIC_DisableIT() / HAL_GTZC_TZIC_EnableIT() + + (#) Illegal access flags can be retrieved through HAL_GTZC_TZIC_GetFlag() and + HAL_GTZC_TZIC_ClearFlag() functions + + (#) Illegal access interrupt service routines are served by HAL_GTZC_IRQHandler() + and user can add his own code using HAL_GTZC_TZIC_Callback() + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup GTZC GTZC + * @brief GTZC HAL module driver + * @{ + */ + +#ifdef HAL_GTZC_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ + +/** @defgroup GTZC_Private_Constants GTZC Private Constants + * @{ + */ + +/* Definitions for GTZC_TZSC_MPCWM */ +#if defined (OCTOSPI1) +#define GTZC_TZSC_MPCWM1_MEM_SIZE 0x10000000U /* 256MB max size */ +#endif /* defined (OCTOSPI1) */ +#if defined (FMC_BANK1) +#define GTZC_TZSC_MPCWM2_MEM_SIZE 0x10000000U /* 256MB max size */ +#endif /* defined (FMC_BANK1) */ +#if defined (FMC_BANK3) || defined(FMC_SDRAM_BANK_1) +#define GTZC_TZSC_MPCWM3_MEM_SIZE 0x10000000U /* 256MB max size */ +#endif /* defined (FMC_BANK3) || defined(FMC_SDRAM_BANK_1) */ +#if defined(BKPSRAM_BASE) +#define GTZC_TZSC_MPCWM4_MEM_SIZE BKPSRAM_SIZE +#endif /* defined (BKPSRAM_BASE) */ +#if defined(FMC_SDRAM_BANK_2) +#define GTZC_TZSC_MPCWM4_SDRAM_MEM_SIZE 0x10000000U /* 256MB max size */ +#endif /* defined(FMC_SDRAM_BANK_2) */ + +/* Definitions for GTZC TZSC & TZIC ALL register values */ +#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define TZSC1_SECCFGR1_ALL (0xFFFFFFFFUL) +#define TZSC1_SECCFGR2_ALL (0xFF0FFF07UL) +#define TZSC1_SECCFGR3_ALL (0x05FFFF03UL) +#endif /* defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#if defined (GTZC_TZIC1) +#define TZSC1_PRIVCFGR1_ALL (0xFFFFFFFFUL) +#define TZSC1_PRIVCFGR2_ALL (0xFF0FFF07UL) +#define TZSC1_PRIVCFGR3_ALL (0x05FFFF03UL) +#else +#define TZSC1_PRIVCFGR1_ALL (0xC21E7E33UL) +#define TZSC1_PRIVCFGR2_ALL (0x12080B19UL) +#define TZSC1_PRIVCFGR3_ALL (0x04065106UL) +#endif /* defined (GTZC_TZIC1) */ + +#if defined (GTZC_TZIC1) +#define TZIC1_IER1_ALL (0xFFFFFFFFUL) +#define TZIC1_IER2_ALL (0xFF0FFF07UL) +#define TZIC1_IER3_ALL (0x05FFFF03UL) +#define TZIC1_IER4_ALL (0x3F3F0FFFUL) + +#define TZIC1_FCR1_ALL (0xFFFFFFFFUL) +#define TZIC1_FCR2_ALL (0xFF0FFF07UL) +#define TZIC1_FCR3_ALL (0x05FFFF03UL) +#define TZIC1_FCR4_ALL (0x3F3F0FFFUL) +#endif /* defined (GTZC_TZIC1) */ +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ + +/** @defgroup GTZC_Private_Macros GTZC Private Macros + * @{ + */ + +#define IS_ADDRESS_IN(mem, address)\ + ( ( ( (uint32_t)(address) >= (uint32_t)GTZC_BASE_ADDRESS_NS(mem) ) \ + && ( (uint32_t)(address) < ((uint32_t)GTZC_BASE_ADDRESS_NS(mem) + (uint32_t)GTZC_MEM_SIZE(mem) ) ) ) \ + || ( ( (uint32_t)(address) >= (uint32_t)GTZC_BASE_ADDRESS_S(mem) ) \ + && ( (uint32_t)(address) < ((uint32_t)GTZC_BASE_ADDRESS_S(mem) + (uint32_t)GTZC_MEM_SIZE(mem) ) ) ) ) + +#define IS_ADDRESS_IN_S(mem, address)\ + ( ( (uint32_t)(address) >= (uint32_t)GTZC_BASE_ADDRESS_S(mem) ) \ + && ( (uint32_t)(address) < ((uint32_t)GTZC_BASE_ADDRESS_S(mem) + (uint32_t)GTZC_MEM_SIZE(mem) ) ) ) + +#define IS_ADDRESS_IN_NS(mem, address)\ + ( ( (uint32_t)(address) >= (uint32_t)GTZC_BASE_ADDRESS_NS(mem) ) \ + && ( (uint32_t)(address) < ((uint32_t)GTZC_BASE_ADDRESS_NS(mem) + (uint32_t)GTZC_MEM_SIZE(mem) ) ) ) + +#define GTZC_BASE_ADDRESS(mem)\ + ( mem ## _BASE ) + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup GTZC_Exported_Functions GTZC Exported Functions + * @{ + */ + +/** @defgroup GTZC_Exported_Functions_Group1 TZSC Configuration functions + * @brief TZSC Configuration functions + * + @verbatim + ============================================================================== + ##### TZSC Configuration functions ##### + ============================================================================== + [..] + This section provides functions allowing to configure TZSC + TZSC: TrustZone Security Controller +@endverbatim + * @{ + */ + +/** + * @brief Configure TZSC on a single peripheral or on all peripherals. + * @note Secure and non-secure attributes can only be set from the secure + * state when the system implements the security (TZEN=1). + * @note Privilege and non-privilege attributes can only be set from the + * privilege state when TZEN=0 or TZEN=1 + * @note Security and privilege attributes can be set independently. + * @note Default state is non-secure and unprivileged access allowed. + * @param PeriphId Peripheral identifier + * This parameter can be a value of @ref GTZC_TZSC_TZIC_PeriphId. + * Use GTZC_PERIPH_ALL to select all peripherals. + * @param PeriphAttributes Peripheral attributes, see @ref GTZC_TZSC_PeriphAttributes. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_GTZC_TZSC_ConfigPeriphAttributes(uint32_t PeriphId, + uint32_t PeriphAttributes) +{ + uint32_t register_address; + + /* check entry parameters */ +#if defined (GTZC_TZIC1) + if ((PeriphAttributes > (GTZC_TZSC_PERIPH_SEC | GTZC_TZSC_PERIPH_PRIV)) + || (HAL_GTZC_GET_ARRAY_INDEX(PeriphId) >= GTZC_TZSC_PERIPH_NUMBER) + || (((PeriphId & GTZC_PERIPH_ALL) != 0U) + && (HAL_GTZC_GET_ARRAY_INDEX(PeriphId) != 0U))) +#else + if ((PeriphAttributes > GTZC_TZSC_PERIPH_PRIV) + || (HAL_GTZC_GET_ARRAY_INDEX(PeriphId) >= GTZC_TZSC_PERIPH_NUMBER) + || (((PeriphId & GTZC_PERIPH_ALL) != 0U) + && (HAL_GTZC_GET_ARRAY_INDEX(PeriphId) != 0U))) +#endif /* defined (GTZC_TZIC1) */ + { + return HAL_ERROR; + } + + if ((PeriphId & GTZC_PERIPH_ALL) != 0U) + { + /* special case where same attributes are applied to all peripherals */ + +#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + /* secure configuration */ + if ((PeriphAttributes & GTZC_TZSC_PERIPH_SEC) == GTZC_TZSC_PERIPH_SEC) + { + SET_BIT(GTZC_TZSC1->SECCFGR1, TZSC1_SECCFGR1_ALL); + SET_BIT(GTZC_TZSC1->SECCFGR2, TZSC1_SECCFGR2_ALL); + SET_BIT(GTZC_TZSC1->SECCFGR3, TZSC1_SECCFGR3_ALL); + } + else if ((PeriphAttributes & GTZC_TZSC_PERIPH_NSEC) == GTZC_TZSC_PERIPH_NSEC) + { + CLEAR_BIT(GTZC_TZSC1->SECCFGR1, TZSC1_SECCFGR1_ALL); + CLEAR_BIT(GTZC_TZSC1->SECCFGR2, TZSC1_SECCFGR2_ALL); + CLEAR_BIT(GTZC_TZSC1->SECCFGR3, TZSC1_SECCFGR3_ALL); + } + else + { + /* do nothing */ + } +#endif /* defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + /* privilege configuration */ + if ((PeriphAttributes & GTZC_TZSC_PERIPH_PRIV) == GTZC_TZSC_PERIPH_PRIV) + { + SET_BIT(GTZC_TZSC1->PRIVCFGR1, TZSC1_PRIVCFGR1_ALL); + SET_BIT(GTZC_TZSC1->PRIVCFGR2, TZSC1_PRIVCFGR2_ALL); + SET_BIT(GTZC_TZSC1->PRIVCFGR3, TZSC1_PRIVCFGR3_ALL); + } + else if ((PeriphAttributes & GTZC_TZSC_PERIPH_NPRIV) == GTZC_TZSC_PERIPH_NPRIV) + { + CLEAR_BIT(GTZC_TZSC1->PRIVCFGR1, TZSC1_PRIVCFGR1_ALL); + CLEAR_BIT(GTZC_TZSC1->PRIVCFGR2, TZSC1_PRIVCFGR2_ALL); + CLEAR_BIT(GTZC_TZSC1->PRIVCFGR3, TZSC1_PRIVCFGR3_ALL); + } + else + { + /* do nothing */ + } + } + else + { + /* common case where only one peripheral is configured */ + +#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + /* secure configuration */ + register_address = (uint32_t) &(GTZC_TZSC1->SECCFGR1) + + (4U * GTZC_GET_REG_INDEX(PeriphId)); + if ((PeriphAttributes & GTZC_TZSC_PERIPH_SEC) == GTZC_TZSC_PERIPH_SEC) + { + SET_BIT(*(__IO uint32_t *)register_address, 1UL << GTZC_GET_PERIPH_POS(PeriphId)); + } + else if ((PeriphAttributes & GTZC_TZSC_PERIPH_NSEC) == GTZC_TZSC_PERIPH_NSEC) + { + CLEAR_BIT(*(__IO uint32_t *)register_address, 1UL << GTZC_GET_PERIPH_POS(PeriphId)); + } + else + { + /* do nothing */ + } +#endif /* defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + /* privilege configuration */ + register_address = (uint32_t) &(GTZC_TZSC1->PRIVCFGR1) + + (4U * GTZC_GET_REG_INDEX(PeriphId)); + if ((PeriphAttributes & GTZC_TZSC_PERIPH_PRIV) == GTZC_TZSC_PERIPH_PRIV) + { + SET_BIT(*(__IO uint32_t *)register_address, 1UL << GTZC_GET_PERIPH_POS(PeriphId)); + } + else if ((PeriphAttributes & GTZC_TZSC_PERIPH_NPRIV) == GTZC_TZSC_PERIPH_NPRIV) + { + CLEAR_BIT(*(__IO uint32_t *)register_address, 1UL << GTZC_GET_PERIPH_POS(PeriphId)); + } + else + { + /* do nothing */ + } + } + return HAL_OK; +} + +/** + * @brief Get TZSC configuration on a single peripheral or on all peripherals. + * @param PeriphId Peripheral identifier. + * This parameter can be a value of @ref GTZC_TZSC_TZIC_PeriphId. + * Use GTZC_PERIPH_ALL to select all peripherals. + * @param PeriphAttributes Peripheral attribute pointer. + * This parameter can be a value of @ref GTZC_TZSC_PeriphAttributes. + * If PeriphId target a single peripheral, pointer on a single element. + * If all peripherals selected (GTZC_PERIPH_ALL), pointer to an array of + * GTZC_TZSC_PERIPH_NUMBER elements is to be provided. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_GTZC_TZSC_GetConfigPeriphAttributes(uint32_t PeriphId, + uint32_t *PeriphAttributes) +{ + uint32_t i; + uint32_t reg_value; + uint32_t register_address; + + /* check entry parameters */ + if ((PeriphAttributes == NULL) + || (HAL_GTZC_GET_ARRAY_INDEX(PeriphId) >= GTZC_TZSC_PERIPH_NUMBER) + || (((PeriphId & GTZC_PERIPH_ALL) != 0U) + && (HAL_GTZC_GET_ARRAY_INDEX(PeriphId) != 0U))) + { + return HAL_ERROR; + } + + if ((PeriphId & GTZC_PERIPH_ALL) != 0U) + { +#if defined (GTZC_TZIC1) + /* get secure configuration: read each register and deploy each bit value + * of corresponding index in the destination array + */ + reg_value = READ_REG(GTZC_TZSC1->SECCFGR1); + for (i = 0U; i < 32U; i++) + { + if (((reg_value & (1UL << i)) >> i) != 0U) + { + PeriphAttributes[i] = GTZC_TZSC_PERIPH_SEC; + } + else + { + PeriphAttributes[i] = GTZC_TZSC_PERIPH_NSEC; + } + } + + reg_value = READ_REG(GTZC_TZSC1->SECCFGR2); + for (i = 32U; i < 64U; i++) + { + if (((reg_value & (1UL << (i - 32U))) >> (i - 32U)) != 0U) + { + PeriphAttributes[i] = GTZC_TZSC_PERIPH_SEC; + } + else + { + PeriphAttributes[i] = GTZC_TZSC_PERIPH_NSEC; + } + } + + reg_value = READ_REG(GTZC_TZSC1->SECCFGR3); + for (i = 64U; i < GTZC_TZSC_PERIPH_NUMBER; i++) + { + if (((reg_value & (1UL << (i - 64U))) >> (i - 64U)) != 0U) + { + PeriphAttributes[i] = GTZC_TZSC_PERIPH_SEC; + } + else + { + PeriphAttributes[i] = GTZC_TZSC_PERIPH_NSEC; + } + } +#endif /* defined (GTZC_TZIC1) */ + + /* get privilege configuration: read each register and deploy each bit value + * of corresponding index in the destination array + */ + reg_value = READ_REG(GTZC_TZSC1->PRIVCFGR1); + for (i = 0U; i < 32U; i++) + { + if (((reg_value & (1UL << i)) >> i) != 0U) + { + PeriphAttributes[i] |= GTZC_TZSC_PERIPH_PRIV; + } + else + { + PeriphAttributes[i] |= GTZC_TZSC_PERIPH_NPRIV; + } + } + + reg_value = READ_REG(GTZC_TZSC1->PRIVCFGR2); + for (i = 32U; i < 64U; i++) + { + if (((reg_value & (1UL << (i - 32U))) >> (i - 32U)) != 0U) + { + PeriphAttributes[i] |= GTZC_TZSC_PERIPH_PRIV; + } + else + { + PeriphAttributes[i] |= GTZC_TZSC_PERIPH_NPRIV; + } + } + + reg_value = READ_REG(GTZC_TZSC1->PRIVCFGR3); + for (i = 64U; i < GTZC_TZSC_PERIPH_NUMBER; i++) + { + if (((reg_value & (1UL << (i - 64U))) >> (i - 64U)) != 0U) + { + PeriphAttributes[i] |= GTZC_TZSC_PERIPH_PRIV; + } + else + { + PeriphAttributes[i] |= GTZC_TZSC_PERIPH_NPRIV; + } + } + } + else + { + /* common case where only one peripheral is configured */ +#if defined (GTZC_TZIC1) + /* secure configuration */ + register_address = (uint32_t) &(GTZC_TZSC1->SECCFGR1) + + (4U * GTZC_GET_REG_INDEX(PeriphId)); + + if (((READ_BIT(*(__IO uint32_t *)register_address, + 1UL << GTZC_GET_PERIPH_POS(PeriphId))) >> GTZC_GET_PERIPH_POS(PeriphId)) + != 0U) + { + *PeriphAttributes = GTZC_TZSC_PERIPH_SEC; + } + else + { + *PeriphAttributes = GTZC_TZSC_PERIPH_NSEC; + } +#endif /* defined (GTZC_TZIC1) */ + + /* privilege configuration */ + register_address = (uint32_t) &(GTZC_TZSC1->PRIVCFGR1) + + (4U * GTZC_GET_REG_INDEX(PeriphId)); + + if (((READ_BIT(*(__IO uint32_t *)register_address, + 1UL << GTZC_GET_PERIPH_POS(PeriphId))) >> GTZC_GET_PERIPH_POS(PeriphId)) + != 0U) + { + *PeriphAttributes |= GTZC_TZSC_PERIPH_PRIV; + } + else + { + *PeriphAttributes |= GTZC_TZSC_PERIPH_NPRIV; + } + } + return HAL_OK; +} + +/** + * @} + */ + + +/** @defgroup GTZC_Exported_Functions_Group2 MPCWM Configuration functions + * @brief MPCWM Configuration functions + * + @verbatim + ============================================================================== + ##### MPCWM Configuration functions ##### + ============================================================================== + [..] + This section provides functions allowing to configure MPCWM + MPCWM is Memory Protection Controller WaterMark +@endverbatim + * @{ + */ + +/** + * @brief Configure a TZSC-MPCWM area. + * @param MemBaseAddress WM identifier. + * @param pMPCWM_Desc TZSC-MPCWM descriptor pointer. + * The structure description is available in @ref GTZC_Exported_Types. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_GTZC_TZSC_MPCWM_ConfigMemAttributes(uint32_t MemBaseAddress, + const MPCWM_ConfigTypeDef *pMPCWM_Desc) +{ + uint32_t register_address; + uint32_t reg_value; + uint32_t size; + /* granularity value depends on selected memory */ + uint32_t granularity = (MemBaseAddress == BKPSRAM_BASE) ? \ + GTZC_TZSC_MPCWM_GRANULARITY_2 : GTZC_TZSC_MPCWM_GRANULARITY_1; + + /* check entry parameters */ + if ((pMPCWM_Desc->AreaId > GTZC_TZSC_MPCWM_ID2) +#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + || (((MemBaseAddress == FMC_BANK3) || (MemBaseAddress == BKPSRAM_BASE) || \ + (MemBaseAddress == FMC_SDRAM_BANK_1) || (MemBaseAddress == FMC_SDRAM_BANK_2)) +#else + || ((MemBaseAddress == BKPSRAM_BASE) +#endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + && (pMPCWM_Desc->AreaId == GTZC_TZSC_MPCWM_ID2)) + || ((pMPCWM_Desc->Offset % granularity) != 0U) + || ((pMPCWM_Desc->Length % granularity) != 0U)) + { + return HAL_ERROR; + } + + /* check descriptor content vs. memory capacity */ + switch (MemBaseAddress) + { +#if defined(OCTOSPI1) + case OCTOSPI1_BASE: + size = GTZC_TZSC_MPCWM1_MEM_SIZE; + if (pMPCWM_Desc->AreaId == GTZC_TZSC_MPCWM_ID1) + { + register_address = (uint32_t) &(GTZC_TZSC1->MPCWM1AR); + } + else + { + /* Here pMPCWM_Desc->AreaId == GTZC_TZSC_MPCWM_ID2 + * (Parameter already checked) + */ + register_address = (uint32_t) &(GTZC_TZSC1->MPCWM1BR); + } + break; +#endif /* (OCTOSPI1) */ +#if defined(FMC_BANK1) + case FMC_BANK1: + size = GTZC_TZSC_MPCWM2_MEM_SIZE; + if (pMPCWM_Desc->AreaId == GTZC_TZSC_MPCWM_ID1) + { + register_address = (uint32_t) &(GTZC_TZSC1->MPCWM2AR); + } + else + { + /* Here pMPCWM_Desc->AreaId == GTZC_TZSC_MPCWM_ID2 + * (Parameter already checked) + */ + register_address = (uint32_t) &(GTZC_TZSC1->MPCWM2BR); + } + break; +#endif /* defined(FMC_BANK1) */ +#if defined(FMC_BANK3) + case FMC_BANK3: + /* Here pMPCWM_Desc->AreaId == GTZC_TZSC_MPCWM_ID1 + * (Parameter already checked) + */ + size = GTZC_TZSC_MPCWM3_MEM_SIZE; + register_address = (uint32_t) &(GTZC_TZSC1->MPCWM3AR); + break; +#endif /* defined(FMC_BANK3) */ +#if defined(FMC_SDRAM_BANK_1) + case FMC_SDRAM_BANK_1: + /* Here pMPCWM_Desc->AreaId == GTZC_TZSC_MPCWM_ID1 + * (Parameter already checked) + */ + size = GTZC_TZSC_MPCWM3_MEM_SIZE; + register_address = (uint32_t) &(GTZC_TZSC1->MPCWM3AR); + break; +#endif /* (FMC_SDRAM_BANK_1) */ +#if defined(BKPSRAM_BASE) + case BKPSRAM_BASE: + /* Here pMPCWM_Desc->AreaId == GTZC_TZSC_MPCWM_ID1 + * (Parameter already checked) + */ + size = GTZC_TZSC_MPCWM4_MEM_SIZE; + register_address = (uint32_t) &(GTZC_TZSC1->MPCWM4AR); + break; +#endif /* (BKPSRAM_BASE) */ +#if defined(FMC_SDRAM_BANK_2) + case FMC_SDRAM_BANK_2: + /* Here pMPCWM_Desc->AreaId == GTZC_TZSC_MPCWM_ID1 + * (Parameter already checked) + */ + size = GTZC_TZSC_MPCWM4_SDRAM_MEM_SIZE ; + register_address = (uint32_t) &(GTZC_TZSC1->MPCWM4AR); + break; +#endif /* (FMC_SDRAM_BANK_2) */ + default: + return HAL_ERROR; + break; + } + + if ((pMPCWM_Desc->Offset > size) + || ((pMPCWM_Desc->Offset + + pMPCWM_Desc->Length) + > size)) + { + return HAL_ERROR; + } + + /* Write watermark start and length value */ + reg_value = ((pMPCWM_Desc->Offset / granularity) + << GTZC_TZSC_MPCWMR_SUBZ_START_Pos) & GTZC_TZSC_MPCWMR_SUBZ_START_Msk; + reg_value |= ((pMPCWM_Desc->Length / granularity) + << GTZC_TZSC_MPCWMR_SUBZ_LENGTH_Pos) & GTZC_TZSC_MPCWMR_SUBZ_LENGTH_Msk; + MODIFY_REG(*(__IO uint32_t *)register_address, GTZC_TZSC_MPCWMR_SUBZ_START_Msk | \ + GTZC_TZSC_MPCWMR_SUBZ_LENGTH_Msk, reg_value); + +#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + /* Write watermark configuration value */ + reg_value = (pMPCWM_Desc->Attribute << GTZC_TZSC_MPCWM_CFGR_SEC_Pos) | \ + pMPCWM_Desc->Lock | \ + pMPCWM_Desc->AreaStatus; + MODIFY_REG(*(__IO uint32_t *)(register_address - 4U), (GTZC_TZSC_MPCWM_CFGR_PRIV | GTZC_TZSC_MPCWM_CFGR_SEC | \ + GTZC_TZSC_MPCWM_CFGR_SRLOCK | GTZC_TZSC_MPCWM_CFGR_SREN), \ + reg_value); +#else + /* Write watermark configuration value */ + reg_value = (pMPCWM_Desc->Attribute << (GTZC_TZSC_MPCWM_CFGR_PRIV_Pos - 1U)) | \ + pMPCWM_Desc->Lock | \ + pMPCWM_Desc->AreaStatus; + MODIFY_REG(*(__IO uint32_t *)(register_address - 4U), (GTZC_TZSC_MPCWM_CFGR_PRIV | GTZC_TZSC_MPCWM_CFGR_SRLOCK | \ + GTZC_TZSC_MPCWM_CFGR_SREN), reg_value); +#endif /* (__ARM_FEATURE_CMSE) */ + + return HAL_OK; +} + +/** + * @brief Get a TZSC-MPCWM area configuration. + * @param MemBaseAddress WM identifier. + * @param pMPCWM_Desc pointer to a TZSC-MPCWM descriptor. + * When the WaterMark memory supports two sub-regions A and B. pMPCWM_Desc argument must point to an array of + * two MPCWM_ConfigTypeDef structures. + * The structure description is available in @ref GTZC_Exported_Types. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_GTZC_TZSC_MPCWM_GetConfigMemAttributes(uint32_t MemBaseAddress, MPCWM_ConfigTypeDef *pMPCWM_Desc) +{ + uint32_t register_address; + uint32_t reg_value; + uint32_t granularity = (MemBaseAddress == BKPSRAM_BASE) ? \ + GTZC_TZSC_MPCWM_GRANULARITY_2 : GTZC_TZSC_MPCWM_GRANULARITY_1; + + /* firstly take care of the first area, present on all MPCWM sub-blocks */ + switch (MemBaseAddress) + { +#if defined(OCTOSPI1) + case OCTOSPI1_BASE: + register_address = (uint32_t) &(GTZC_TZSC1->MPCWM1AR); + break; +#endif /* (OCTOSPI1) */ +#if defined(FMC_BANK1) + case FMC_BANK1: + register_address = (uint32_t) &(GTZC_TZSC1->MPCWM2AR); + break; +#endif /* defined(FMC_BANK1) */ +#if defined(FMC_BANK3) + case FMC_BANK3: + register_address = (uint32_t) &(GTZC_TZSC1->MPCWM3AR); + break; +#endif /* defined(FMC_BANK3) */ +#if defined(FMC_SDRAM_BANK_1) + case FMC_SDRAM_BANK_1: + register_address = (uint32_t) &(GTZC_TZSC1->MPCWM3AR); + break; +#endif /* (FMC_SDRAM_BANK_1) */ +#if defined(BKPSRAM_BASE) + case BKPSRAM_BASE: + register_address = (uint32_t) &(GTZC_TZSC1->MPCWM4AR); + break; +#endif /* (BKPSRAM_BASE) */ +#if defined(FMC_SDRAM_BANK_2) + case FMC_SDRAM_BANK_2: + register_address = (uint32_t) &(GTZC_TZSC1->MPCWM4AR); + break; +#endif /* (FMC_SDRAM_BANK_2) */ + default: + return HAL_ERROR; + break; + } + + /* read register and update the descriptor for first area*/ + reg_value = READ_REG(*(__IO uint32_t *)register_address); + pMPCWM_Desc[0].AreaId = GTZC_TZSC_MPCWM_ID1; + pMPCWM_Desc[0].Offset = ((reg_value & GTZC_TZSC_MPCWMR_SUBZ_START_Msk) + >> GTZC_TZSC_MPCWMR_SUBZ_START_Pos) * granularity; + pMPCWM_Desc[0].Length = ((reg_value & GTZC_TZSC_MPCWMR_SUBZ_LENGTH_Msk) + >> GTZC_TZSC_MPCWMR_SUBZ_LENGTH_Pos) * granularity; + + /* read configuration register and update the descriptor for first area*/ + reg_value = READ_REG(*(__IO uint32_t *)(register_address - 4U)); +#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + pMPCWM_Desc[0].Attribute = (reg_value & (GTZC_TZSC_MPCWM_CFGR_PRIV | \ + GTZC_TZSC_MPCWM_CFGR_SEC)) >> GTZC_TZSC_MPCWM_CFGR_SEC_Pos; +#else + pMPCWM_Desc[0].Attribute = (reg_value & GTZC_TZSC_MPCWM_CFGR_PRIV) >> (GTZC_TZSC_MPCWM_CFGR_PRIV_Pos - 1U); +#endif /* defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + pMPCWM_Desc[0].Lock = reg_value & GTZC_TZSC_MPCWM_CFGR_SRLOCK; + pMPCWM_Desc[0].AreaStatus = reg_value & GTZC_TZSC_MPCWM_CFGR_SREN; + +#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + if ((MemBaseAddress == OCTOSPI1_BASE) || (MemBaseAddress == FMC_BANK1)) + { + if (MemBaseAddress == OCTOSPI1_BASE) + { + register_address = (uint32_t) &(GTZC_TZSC1_S->MPCWM1BR); + } + else + { + register_address = (uint32_t) &(GTZC_TZSC1_S->MPCWM2BR); + } + + /* read register and update the descriptor for second area*/ + reg_value = READ_REG(*(__IO uint32_t *)register_address); + pMPCWM_Desc[1].AreaId = GTZC_TZSC_MPCWM_ID2; + pMPCWM_Desc[1].Offset = ((reg_value & GTZC_TZSC_MPCWMR_SUBZ_START_Msk) + >> GTZC_TZSC_MPCWMR_SUBZ_START_Pos) * granularity; + pMPCWM_Desc[1].Length = ((reg_value & GTZC_TZSC_MPCWMR_SUBZ_LENGTH_Msk) + >> GTZC_TZSC_MPCWMR_SUBZ_LENGTH_Pos) * granularity; + + /* read configuration register and update the descriptor for second area*/ + reg_value = READ_REG(*(__IO uint32_t *)(register_address - 4U)); + pMPCWM_Desc[1].Attribute = (reg_value & (GTZC_TZSC_MPCWM_CFGR_PRIV | \ + GTZC_TZSC_MPCWM_CFGR_SEC)) >> GTZC_TZSC_MPCWM_CFGR_SEC_Pos; + pMPCWM_Desc[1].Lock = reg_value & GTZC_TZSC_MPCWM_CFGR_SRLOCK; + pMPCWM_Desc[1].AreaStatus = reg_value & GTZC_TZSC_MPCWM_CFGR_SREN; + } +#endif /* defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + return HAL_OK; +} + +#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @} + */ + +/** @defgroup GTZC_Exported_Functions_Group3 TZSC Lock functions + * @brief TZSC Lock functions + * + @verbatim + ============================================================================== + ##### TZSC Lock functions ##### + ============================================================================== + [..] + This section provides functions allowing to manage the TZSC (TrustZone + Security Controller) lock. It includes lock enable, and current value read. +@endverbatim + * @{ + */ + +/** + * @brief Lock TZSC configuration. + * @note This function locks the configuration of TZSC_SECCFGRx and TZSC_PRIVCFGRx + * registers until next reset + * @param TZSC_Instance TZSC sub-block instance. + */ +void HAL_GTZC_TZSC_Lock(GTZC_TZSC_TypeDef *TZSC_Instance) +{ + SET_BIT(TZSC_Instance->CR, GTZC_TZSC_CR_LCK_Msk); +} + +/** + * @brief Get TZSC configuration lock state. + * @param TZSC_Instance TZSC sub-block instance. + * @retval Lock State (GTZC_TZSC_LOCK_OFF or GTZC_TZSC_LOCK_ON) + */ +uint32_t HAL_GTZC_TZSC_GetLock(const GTZC_TZSC_TypeDef *TZSC_Instance) +{ + return READ_BIT(TZSC_Instance->CR, GTZC_TZSC_CR_LCK_Msk); +} + +/** + * @} + */ +#endif /* defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/** @defgroup GTZC_Exported_Functions_Group4 MPCBB Configuration functions + * @brief MPCBB Configuration functions + * + @verbatim + ============================================================================== + ##### MPCBB Configuration functions ##### + ============================================================================== + [..] + This section provides functions allowing to configure MPCBB + MPCBB is Memory Protection Controller Block Base +@endverbatim + * @{ + */ + +/** + * @brief Set a complete MPCBB configuration on the SRAM passed as parameter. + * @param MemBaseAddress MPCBB identifier. + * @param pMPCBB_desc pointer to MPCBB descriptor. + * The structure description is available in @ref GTZC_Exported_Types. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_GTZC_MPCBB_ConfigMem(uint32_t MemBaseAddress, + const MPCBB_ConfigTypeDef *pMPCBB_desc) +{ + GTZC_MPCBB_TypeDef *mpcbb_ptr; + uint32_t mem_size; + uint32_t size_in_superblocks; + uint32_t i; + +#if defined (GTZC_MPCBB3) + /* check entry parameters */ + if ((!(IS_GTZC_BASE_ADDRESS(SRAM1, MemBaseAddress)) + && !(IS_GTZC_BASE_ADDRESS(SRAM2, MemBaseAddress)) + && !(IS_GTZC_BASE_ADDRESS(SRAM3, MemBaseAddress))) + || ((pMPCBB_desc->SecureRWIllegalMode != GTZC_MPCBB_SRWILADIS_ENABLE) + && (pMPCBB_desc->SecureRWIllegalMode != GTZC_MPCBB_SRWILADIS_DISABLE)) + || ((pMPCBB_desc->InvertSecureState != GTZC_MPCBB_INVSECSTATE_NOT_INVERTED) + && (pMPCBB_desc->InvertSecureState != GTZC_MPCBB_INVSECSTATE_INVERTED))) +#else + if ((!(IS_GTZC_BASE_ADDRESS(SRAM1, MemBaseAddress)) + && !(IS_GTZC_BASE_ADDRESS(SRAM2, MemBaseAddress))) + || ((pMPCBB_desc->SecureRWIllegalMode != GTZC_MPCBB_SRWILADIS_ENABLE) + && (pMPCBB_desc->SecureRWIllegalMode != GTZC_MPCBB_SRWILADIS_DISABLE)) + || ((pMPCBB_desc->InvertSecureState != GTZC_MPCBB_INVSECSTATE_NOT_INVERTED) + && (pMPCBB_desc->InvertSecureState != GTZC_MPCBB_INVSECSTATE_INVERTED))) +#endif /* defined (GTZC_MPCBB3) */ + { + return HAL_ERROR; + } + + if (IS_GTZC_BASE_ADDRESS(SRAM1, MemBaseAddress)) + { + mpcbb_ptr = GTZC_MPCBB1; + mem_size = GTZC_MEM_SIZE(SRAM1); + } +#if defined (GTZC_MPCBB3) + else if (IS_GTZC_BASE_ADDRESS(SRAM2, MemBaseAddress)) + { + mpcbb_ptr = GTZC_MPCBB2; + mem_size = GTZC_MEM_SIZE(SRAM2); + } + else + { + mpcbb_ptr = GTZC_MPCBB3; + mem_size = GTZC_MEM_SIZE(SRAM3); + } +#else + else + { + mpcbb_ptr = GTZC_MPCBB2; + mem_size = GTZC_MEM_SIZE(SRAM2); + } +#endif /* defined (GTZC_MPCBB3) */ + + /* translate mem_size in number of super-blocks */ + size_in_superblocks = (mem_size / GTZC_MPCBB_SUPERBLOCK_SIZE); + + /* write PRIVCFGR register information */ + for (i = 0U; i < size_in_superblocks; i++) + { + WRITE_REG(mpcbb_ptr->PRIVCFGR[i], + pMPCBB_desc->AttributeConfig.MPCBB_PrivConfig_array[i]); + } + +#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + uint32_t size_mask; + uint32_t reg_value; + + /* write InvertSecureState and SecureRWIllegalMode properties */ + reg_value = pMPCBB_desc->InvertSecureState; + reg_value |= pMPCBB_desc->SecureRWIllegalMode; + + /* write SECCFGR register information */ + for (i = 0U; i < size_in_superblocks; i++) + { + WRITE_REG(mpcbb_ptr->SECCFGR[i], + pMPCBB_desc->AttributeConfig.MPCBB_SecConfig_array[i]); + } + + if (size_in_superblocks == 32U) + { + size_mask = 0xFFFFFFFFU; + } + else + { + size_mask = (1UL << size_in_superblocks) - 1U; + } + /* limitation: code not portable with memory > 512K */ + MODIFY_REG(mpcbb_ptr->CFGLOCKR1, size_mask, pMPCBB_desc->AttributeConfig.MPCBB_LockConfig_array[0]); + + /* write configuration and lock register information */ + MODIFY_REG(mpcbb_ptr->CR, + GTZC_MPCBB_CR_INVSECSTATE_Msk | GTZC_MPCBB_CR_SRWILADIS_Msk, reg_value); + +#endif /* defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + return HAL_OK; +} + +/** + * @brief Get a complete MPCBB configuration on the SRAM passed as parameter. + * @param MemBaseAddress MPCBB identifier. + * @param pMPCBB_desc pointer to a MPCBB descriptor. + * The structure description is available in @ref GTZC_Exported_Types. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_GTZC_MPCBB_GetConfigMem(uint32_t MemBaseAddress, + MPCBB_ConfigTypeDef *pMPCBB_desc) +{ + GTZC_MPCBB_TypeDef *mpcbb_ptr; + uint32_t mem_size; + uint32_t size_in_superblocks; + uint32_t i; + + /* check entry parameters */ +#if defined (GTZC_MPCBB3) + if (!(IS_GTZC_BASE_ADDRESS(SRAM1, MemBaseAddress)) + && !(IS_GTZC_BASE_ADDRESS(SRAM2, MemBaseAddress)) + && !(IS_GTZC_BASE_ADDRESS(SRAM3, MemBaseAddress))) +#else + if (!(IS_GTZC_BASE_ADDRESS(SRAM1, MemBaseAddress)) + && !(IS_GTZC_BASE_ADDRESS(SRAM2, MemBaseAddress))) +#endif /* defined (GTZC_MPCBB3) */ + { + return HAL_ERROR; + } + + /* read InvertSecureState and SecureRWIllegalMode properties */ + /* assume their Position/Mask is identical for all sub-blocks */ + if (IS_GTZC_BASE_ADDRESS(SRAM1, MemBaseAddress)) + { + mpcbb_ptr = GTZC_MPCBB1; + mem_size = GTZC_MEM_SIZE(SRAM1); + } +#if defined (GTZC_MPCBB3) + else if (IS_GTZC_BASE_ADDRESS(SRAM2, MemBaseAddress)) + { + mpcbb_ptr = GTZC_MPCBB2; + mem_size = GTZC_MEM_SIZE(SRAM2); + } + else + { + mpcbb_ptr = GTZC_MPCBB3; + mem_size = GTZC_MEM_SIZE(SRAM3); + } +#else + else + { + mpcbb_ptr = GTZC_MPCBB2; + mem_size = GTZC_MEM_SIZE(SRAM2); + } +#endif /* */ + + /* translate mem_size in number of super-blocks */ + size_in_superblocks = (mem_size / GTZC_MPCBB_SUPERBLOCK_SIZE); + +#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + uint32_t reg_value; + uint32_t size_mask; + + /* read configuration and lock register information */ + reg_value = READ_REG(mpcbb_ptr->CR); + pMPCBB_desc->InvertSecureState = (reg_value & GTZC_MPCBB_CR_INVSECSTATE_Msk); + pMPCBB_desc->SecureRWIllegalMode = (reg_value & GTZC_MPCBB_CR_SRWILADIS_Msk); + if (size_in_superblocks == 32U) + { + size_mask = 0xFFFFFFFFU; + } + else + { + size_mask = (1UL << size_in_superblocks) - 1U; + } + /* limitation: code not portable with memory > 512K */ + pMPCBB_desc->AttributeConfig.MPCBB_LockConfig_array[0] = READ_REG(mpcbb_ptr->CFGLOCKR1) + & size_mask; +#endif /* defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + /* read SECCFGR / PRIVCFGR registers information */ + for (i = 0U; i < size_in_superblocks; i++) + { +#if defined (GTZC_TZIC1) + pMPCBB_desc->AttributeConfig.MPCBB_SecConfig_array[i] = mpcbb_ptr->SECCFGR[i]; +#endif /* defined (GTZC_TZIC1) */ + pMPCBB_desc->AttributeConfig.MPCBB_PrivConfig_array[i] = mpcbb_ptr->PRIVCFGR[i]; + } + + return HAL_OK; +} + +/** + * @brief Set a MPCBB attribute configuration on the SRAM passed as parameter + * for a number of blocks. + * @param MemAddress MPCBB identifier, and start block to configure + * (must be 512 Bytes aligned). + * @param NbBlocks Number of blocks to configure + * (Block size is 512 Bytes). + * @param pMemAttributes pointer to an array (containing "NbBlocks" elements), + * with each element must be GTZC_MPCBB_BLOCK_NSEC or GTZC_MPCBB_BLOCK_SEC, + * and GTZC_MPCBB_BLOCK_NPRIV or GTZC_MPCBB_BLOCK_PRIV. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_GTZC_MPCBB_ConfigMemAttributes(uint32_t MemAddress, + uint32_t NbBlocks, + const uint32_t *pMemAttributes) +{ + GTZC_MPCBB_TypeDef *mpcbb_ptr; + uint32_t base_address; + uint32_t end_address; + uint32_t block_start; + uint32_t offset_reg_start; + uint32_t offset_bit_start; + uint32_t i; + uint32_t do_attr_change; + + /* firstly check that MemAddress is well 512 Bytes aligned */ + if ((MemAddress % GTZC_MPCBB_BLOCK_SIZE) != 0U) + { + return HAL_ERROR; + } + + /* check entry parameters and deduce physical base address */ + end_address = MemAddress + (NbBlocks * GTZC_MPCBB_BLOCK_SIZE) - 1U; + if (((IS_ADDRESS_IN_NS(SRAM1, MemAddress)) + && (IS_ADDRESS_IN_NS(SRAM1, end_address))) != 0U) + { + mpcbb_ptr = GTZC_MPCBB1; + base_address = SRAM1_BASE_NS; + } +#if defined (GTZC_TZIC1) + else if (((IS_ADDRESS_IN_S(SRAM1, MemAddress)) + && (IS_ADDRESS_IN_S(SRAM1, end_address))) != 0U) + { + mpcbb_ptr = GTZC_MPCBB1; + base_address = SRAM1_BASE_S; + } +#endif /* defined (GTZC_TZIC1) */ + else if (((IS_ADDRESS_IN_NS(SRAM2, MemAddress)) + && (IS_ADDRESS_IN_NS(SRAM2, end_address))) != 0U) + { + mpcbb_ptr = GTZC_MPCBB2; + base_address = SRAM2_BASE_NS; + } +#if defined (GTZC_TZIC1) + else if (((IS_ADDRESS_IN_S(SRAM2, MemAddress)) + && (IS_ADDRESS_IN_S(SRAM2, end_address))) != 0U) + { + mpcbb_ptr = GTZC_MPCBB2; + base_address = SRAM2_BASE_S; + } +#endif /* defined (GTZC_TZIC1) */ +#if defined (GTZC_MPCBB3) + else if (((IS_ADDRESS_IN_NS(SRAM3, MemAddress)) + && (IS_ADDRESS_IN_NS(SRAM3, end_address))) != 0U) + { + mpcbb_ptr = GTZC_MPCBB3; + base_address = SRAM3_BASE_NS; + } + else if (((IS_ADDRESS_IN_S(SRAM3, MemAddress)) + && (IS_ADDRESS_IN_S(SRAM3, end_address))) != 0U) + { + mpcbb_ptr = GTZC_MPCBB3; + base_address = SRAM3_BASE_S; + } +#endif /* defined (GTZC_MPCBB3) */ + else + { + return HAL_ERROR; + } + + /* get start coordinates of the configuration */ + block_start = (MemAddress - base_address) / GTZC_MPCBB_BLOCK_SIZE; + offset_reg_start = block_start / 32U; + offset_bit_start = block_start % 32U; + + for (i = 0U; i < NbBlocks; i++) + { + /* Indicate change done for protection attributes */ + do_attr_change = 0U; + +#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + /* secure configuration */ + if ((pMemAttributes[i] & GTZC_MPCBB_BLOCK_SEC) == GTZC_MPCBB_BLOCK_SEC) + { + SET_BIT(mpcbb_ptr->SECCFGR[offset_reg_start], + 1UL << (offset_bit_start % 32U)); + do_attr_change = 1U; + } + else if ((pMemAttributes[i] & GTZC_MPCBB_BLOCK_NSEC) == GTZC_MPCBB_BLOCK_NSEC) + { + CLEAR_BIT(mpcbb_ptr->SECCFGR[offset_reg_start], + 1UL << (offset_bit_start % 32U)); + do_attr_change = 1U; + } + else + { + /* nothing to do */ + } +#endif /* defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + /* privilege configuration */ + if ((pMemAttributes[i] & GTZC_MPCBB_BLOCK_PRIV) == GTZC_MPCBB_BLOCK_PRIV) + { + SET_BIT(mpcbb_ptr->PRIVCFGR[offset_reg_start], + 1UL << (offset_bit_start % 32U)); + } + else if ((pMemAttributes[i] & GTZC_MPCBB_BLOCK_NPRIV) == GTZC_MPCBB_BLOCK_NPRIV) + { + CLEAR_BIT(mpcbb_ptr->PRIVCFGR[offset_reg_start], + 1UL << (offset_bit_start % 32U)); + } + else + { + /* if no change is done for security and privilege attributes: break the loop */ + if (do_attr_change == 0U) + { + break; + } + } + + offset_bit_start++; + if (offset_bit_start == 32U) + { + offset_bit_start = 0U; + offset_reg_start++; + } + } + + /* an unexpected value in pMemAttributes array leads to error status */ + if (i != NbBlocks) + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Get a MPCBB attribute configuration on the SRAM passed as parameter + * for a number of blocks. + * @param MemAddress MPCBB identifier, and start block to get configuration + * (must be 512 Bytes aligned). + * @param NbBlocks Number of blocks to get configuration. + * @param pMemAttributes pointer to an array (containing "NbBlocks" elements), + * with each element will be GTZC_MPCBB_BLOCK_NSEC or GTZC_MPCBB_BLOCK_SEC, + * and GTZC_MPCBB_BLOCK_NPRIV or GTZC_MPCBB_BLOCK_PRIV. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_GTZC_MPCBB_GetConfigMemAttributes(uint32_t MemAddress, + uint32_t NbBlocks, + uint32_t *pMemAttributes) +{ + GTZC_MPCBB_TypeDef *mpcbb_ptr; + uint32_t base_address; + uint32_t end_address; + uint32_t block_start; + uint32_t offset_reg_start; + uint32_t offset_bit_start; + uint32_t i; + + /* firstly check that MemAddress is well 512 Bytes aligned */ + if ((MemAddress % GTZC_MPCBB_BLOCK_SIZE) != 0U) + { + return HAL_ERROR; + } + + /* check entry parameters and deduce physical base address */ + end_address = MemAddress + (NbBlocks * GTZC_MPCBB_BLOCK_SIZE) - 1U; + if ((IS_ADDRESS_IN_NS(SRAM1, MemAddress)) + && (IS_ADDRESS_IN_NS(SRAM1, end_address))) + { + mpcbb_ptr = GTZC_MPCBB1_NS; + base_address = SRAM1_BASE_NS; + } +#if defined (GTZC_TZIC1) + else if ((IS_ADDRESS_IN_S(SRAM1, MemAddress)) + && (IS_ADDRESS_IN_S(SRAM1, end_address))) + { + mpcbb_ptr = GTZC_MPCBB1_S; + base_address = SRAM1_BASE_S; + } +#endif /* defined (GTZC_TZIC1) */ + else if ((IS_ADDRESS_IN_NS(SRAM2, MemAddress)) + && (IS_ADDRESS_IN_NS(SRAM2, end_address))) + { + mpcbb_ptr = GTZC_MPCBB2_NS; + base_address = SRAM2_BASE_NS; + } +#if defined (GTZC_TZIC1) + else if ((IS_ADDRESS_IN_S(SRAM2, MemAddress)) + && (IS_ADDRESS_IN_S(SRAM2, end_address))) + { + mpcbb_ptr = GTZC_MPCBB2_S; + base_address = SRAM2_BASE_S; + } +#endif /* defined (GTZC_TZIC1) */ +#if defined (GTZC_MPCBB3) + else if ((IS_ADDRESS_IN_NS(SRAM3, MemAddress)) + && (IS_ADDRESS_IN_NS(SRAM3, end_address))) + { + mpcbb_ptr = GTZC_MPCBB3_NS; + base_address = SRAM3_BASE_NS; + } + else if ((IS_ADDRESS_IN_S(SRAM3, MemAddress)) + && (IS_ADDRESS_IN_S(SRAM3, end_address))) + { + mpcbb_ptr = GTZC_MPCBB3_S; + base_address = SRAM3_BASE_S; + } +#endif /* defined (GTZC_MPCBB3) */ + else + { + return HAL_ERROR; + } + + /* get start coordinates of the configuration */ + block_start = (MemAddress - base_address) / GTZC_MPCBB_BLOCK_SIZE; + offset_reg_start = block_start / 32U; + offset_bit_start = block_start % 32U; + + for (i = 0U; i < NbBlocks; i++) + { +#if defined (GTZC_TZIC1) + pMemAttributes[i] = (READ_BIT(mpcbb_ptr->SECCFGR[offset_reg_start], + 1UL << (offset_bit_start % 32U)) + >> (offset_bit_start % 32U)) | GTZC_ATTR_SEC_MASK; +#endif /* defined (GTZC_TZIC1) */ + pMemAttributes[i] |= ((READ_BIT(mpcbb_ptr->PRIVCFGR[offset_reg_start], + 1UL << (offset_bit_start % 32U)) + >> (offset_bit_start % 32U)) << 1U) | GTZC_ATTR_PRIV_MASK; + + offset_bit_start++; + if (offset_bit_start == 32U) + { + offset_bit_start = 0U; + offset_reg_start++; + } + } + + return HAL_OK; +} + +#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Lock MPCBB super-blocks on the SRAM passed as parameter. + * @param MemAddress MPCBB start-address of super-block to configure + * (must be 16KBytes aligned). + * @param NbSuperBlocks Number of super-blocks to configure. + * @param pLockAttributes pointer to an array (containing "NbSuperBlocks" elements), + * with for each element: + * value 0 super-block is unlocked, value 1 super-block is locked + * (corresponds to GTZC_MPCBB_SUPERBLOCK_UNLOCKED and + * GTZC_MPCBB_SUPERBLOCK_LOCKED values). + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_GTZC_MPCBB_LockConfig(uint32_t MemAddress, + uint32_t NbSuperBlocks, + const uint32_t *pLockAttributes) +{ + __IO uint32_t *reg_mpcbb; + uint32_t base_address; + uint32_t superblock_start; + uint32_t offset_bit_start; + uint32_t i; + + /* firstly check that MemAddress is well 16KBytes aligned */ + if ((MemAddress % GTZC_MPCBB_SUPERBLOCK_SIZE) != 0U) + { + return HAL_ERROR; + } + + /* check entry parameters */ + if ((IS_ADDRESS_IN(SRAM1, MemAddress)) + && (IS_ADDRESS_IN(SRAM1, (MemAddress + + (NbSuperBlocks * GTZC_MPCBB_SUPERBLOCK_SIZE) + - 1U)))) + { + base_address = GTZC_BASE_ADDRESS(SRAM1); + /* limitation: code not portable with memory > 512K */ + reg_mpcbb = (__IO uint32_t *)>ZC_MPCBB1_S->CFGLOCKR1; + } + else if ((IS_ADDRESS_IN(SRAM2, MemAddress)) + && (IS_ADDRESS_IN(SRAM2, (MemAddress + + (NbSuperBlocks * GTZC_MPCBB_SUPERBLOCK_SIZE) + - 1U)))) + { + base_address = GTZC_BASE_ADDRESS(SRAM2); + /* limitation: code not portable with memory > 256K */ + reg_mpcbb = (__IO uint32_t *)>ZC_MPCBB2_S->CFGLOCKR1; + } + else if ((IS_ADDRESS_IN(SRAM3, MemAddress)) + && (IS_ADDRESS_IN(SRAM3, (MemAddress + + (NbSuperBlocks * GTZC_MPCBB_SUPERBLOCK_SIZE) + - 1U)))) + { + base_address = GTZC_BASE_ADDRESS(SRAM3); + /* limitation: code not portable with memory > 512K */ + reg_mpcbb = (__IO uint32_t *)>ZC_MPCBB3_S->CFGLOCKR1; + } + + else + { + return HAL_ERROR; + } + + /* get start coordinates of the configuration */ + superblock_start = (MemAddress - base_address) / GTZC_MPCBB_SUPERBLOCK_SIZE; + offset_bit_start = superblock_start % 32U; + + for (i = 0U; i < NbSuperBlocks; i++) + { + if (pLockAttributes[i] == GTZC_MPCBB_SUPERBLOCK_LOCKED) + { + SET_BIT(*reg_mpcbb, 1UL << (offset_bit_start % 32U)); + } + else if (pLockAttributes[i] == GTZC_MPCBB_SUPERBLOCK_UNLOCKED) + { + CLEAR_BIT(*reg_mpcbb, 1UL << (offset_bit_start % 32U)); + } + else + { + break; + } + + offset_bit_start++; + } + + /* an unexpected value in pLockAttributes array leads to an error status */ + if (i != NbSuperBlocks) + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Get MPCBB super-blocks lock configuration on the SRAM passed as parameter. + * @param MemAddress MPCBB start-address of super-block to get configuration + * (must be 16KBytes aligned). + * @param NbSuperBlocks Number of super-blocks to get configuration. + * @param pLockAttributes pointer to an array (containing "NbSuperBlocks" elements), + * with for each element: + * value 0 super-block is unlocked, value 1 super-block is locked + * (corresponds to GTZC_MPCBB_SUPERBLOCK_UNLOCKED and + * GTZC_MPCBB_SUPERBLOCK_LOCKED values). + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_GTZC_MPCBB_GetLockConfig(uint32_t MemAddress, + uint32_t NbSuperBlocks, + uint32_t *pLockAttributes) +{ + uint32_t reg_mpcbb; + uint32_t base_address; + uint32_t superblock_start; + uint32_t offset_bit_start; + uint32_t i; + + /* firstly check that MemAddress is well 16KBytes aligned */ + if ((MemAddress % GTZC_MPCBB_SUPERBLOCK_SIZE) != 0U) + { + return HAL_ERROR; + } + + /* check entry parameters */ + if ((IS_ADDRESS_IN(SRAM1, MemAddress)) + && (IS_ADDRESS_IN(SRAM1, (MemAddress + + (NbSuperBlocks * GTZC_MPCBB_SUPERBLOCK_SIZE) + - 1U)))) + { + base_address = GTZC_BASE_ADDRESS(SRAM1); + /* limitation: code not portable with memory > 512K */ + reg_mpcbb = GTZC_MPCBB1_S->CFGLOCKR1; + } + else if ((IS_ADDRESS_IN(SRAM2, MemAddress)) + && (IS_ADDRESS_IN(SRAM2, (MemAddress + + (NbSuperBlocks + * GTZC_MPCBB_SUPERBLOCK_SIZE) + - 1U)))) + { + base_address = GTZC_BASE_ADDRESS(SRAM2); + /* limitation: code not portable with memory > 512K */ + reg_mpcbb = GTZC_MPCBB2_S->CFGLOCKR1; + } + else if ((IS_ADDRESS_IN(SRAM3, MemAddress)) + && (IS_ADDRESS_IN(SRAM3, (MemAddress + + (NbSuperBlocks + * GTZC_MPCBB_SUPERBLOCK_SIZE) + - 1U)))) + { + base_address = GTZC_BASE_ADDRESS(SRAM3); + /* limitation: code not portable with memory > 512K */ + reg_mpcbb = GTZC_MPCBB3_S->CFGLOCKR1; + } + else + { + return HAL_ERROR; + } + + /* get start coordinates of the configuration */ + superblock_start = (MemAddress - base_address) / GTZC_MPCBB_SUPERBLOCK_SIZE; + offset_bit_start = superblock_start % 32U; + + for (i = 0U; i < NbSuperBlocks; i++) + { + pLockAttributes[i] = (reg_mpcbb & (1UL << (offset_bit_start % 32U))) + >> (offset_bit_start % 32U); + offset_bit_start++; + } + + return HAL_OK; +} + +/** + * @brief Lock a MPCBB configuration on the SRAM base address passed as parameter. + * @note This functions locks the control register of the MPCBB until next reset. + * @param MemBaseAddress MPCBB identifier. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_GTZC_MPCBB_Lock(uint32_t MemBaseAddress) +{ + /* check entry parameters */ + if (IS_GTZC_BASE_ADDRESS(SRAM1, MemBaseAddress)) + { + SET_BIT(GTZC_MPCBB1_S->CR, GTZC_MPCBB_CR_GLOCK_Msk); + } + else if (IS_GTZC_BASE_ADDRESS(SRAM2, MemBaseAddress)) + { + SET_BIT(GTZC_MPCBB2_S->CR, GTZC_MPCBB_CR_GLOCK_Msk); + } + else if (IS_GTZC_BASE_ADDRESS(SRAM3, MemBaseAddress)) + { + SET_BIT(GTZC_MPCBB3_S->CR, GTZC_MPCBB_CR_GLOCK_Msk); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Get MPCBB configuration lock state on the SRAM base address passed as parameter. + * @param MemBaseAddress MPCBB identifier. + * @param pLockState pointer to Lock State (GTZC_MPCBB_LOCK_OFF or GTZC_MPCBB_LOCK_ON). + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_GTZC_MPCBB_GetLock(uint32_t MemBaseAddress, + uint32_t *pLockState) +{ + /* check entry parameters */ + if (IS_GTZC_BASE_ADDRESS(SRAM1, MemBaseAddress)) + { + *pLockState = READ_BIT(GTZC_MPCBB1_S->CR, GTZC_MPCBB_CR_GLOCK_Msk); + } + else if (IS_GTZC_BASE_ADDRESS(SRAM2, MemBaseAddress)) + { + *pLockState = READ_BIT(GTZC_MPCBB2_S->CR, GTZC_MPCBB_CR_GLOCK_Msk); + } + else if (IS_GTZC_BASE_ADDRESS(SRAM3, MemBaseAddress)) + { + *pLockState = READ_BIT(GTZC_MPCBB3_S->CR, GTZC_MPCBB_CR_GLOCK_Msk); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup GTZC_Exported_Functions_Group5 TZIC Configuration and Control functions + * @brief TZIC Configuration and Control functions + * + @verbatim + ============================================================================== + ##### TZIC Configuration and Control functions ##### + ============================================================================== + [..] + This section provides functions allowing to configure and control TZIC + TZIC is Trust Zone Interrupt Controller +@endverbatim + * @{ + */ + +/** + * @brief Disable the interrupt associated to a single TZIC peripheral or on all peripherals. + * @param PeriphId Peripheral identifier. + * This parameter can be a value of @ref GTZC_TZSC_TZIC_PeriphId. + * Use GTZC_PERIPH_ALL to select all peripherals. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_GTZC_TZIC_DisableIT(uint32_t PeriphId) +{ + uint32_t register_address; + + /* check entry parameters */ + if ((HAL_GTZC_GET_ARRAY_INDEX(PeriphId) >= GTZC_TZIC_PERIPH_NUMBER) + || (((PeriphId & GTZC_PERIPH_ALL) != 0U) + && (HAL_GTZC_GET_ARRAY_INDEX(PeriphId) != 0U))) + { + return HAL_ERROR; + } + + if ((PeriphId & GTZC_PERIPH_ALL) != 0U) + { + /* same configuration is applied to all peripherals */ + WRITE_REG(GTZC_TZIC1->IER1, 0U); + WRITE_REG(GTZC_TZIC1->IER2, 0U); + WRITE_REG(GTZC_TZIC1->IER3, 0U); + WRITE_REG(GTZC_TZIC1->IER4, 0U); + } + else + { + /* common case where only one peripheral is configured */ + register_address = (uint32_t) &(GTZC_TZIC1->IER1) + + (4U * GTZC_GET_REG_INDEX(PeriphId)); + CLEAR_BIT(*(__IO uint32_t *)register_address, 1UL << GTZC_GET_PERIPH_POS(PeriphId)); + } + + return HAL_OK; +} + +/** + * @brief Enable the interrupt associated to a single TZIC peripheral or on all peripherals. + * @param PeriphId Peripheral identifier. + * This parameter can be a value of @ref GTZC_TZSC_TZIC_PeriphId. + * Use GTZC_PERIPH_ALL to select all peripherals. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_GTZC_TZIC_EnableIT(uint32_t PeriphId) +{ + uint32_t register_address; + + /* check entry parameters */ + if ((HAL_GTZC_GET_ARRAY_INDEX(PeriphId) >= GTZC_TZIC_PERIPH_NUMBER) + || (((PeriphId & GTZC_PERIPH_ALL) != 0U) + && (HAL_GTZC_GET_ARRAY_INDEX(PeriphId) != 0U))) + { + return HAL_ERROR; + } + + if ((PeriphId & GTZC_PERIPH_ALL) != 0U) + { + /* same configuration is applied to all peripherals */ + WRITE_REG(GTZC_TZIC1->IER1, TZIC1_IER1_ALL); + WRITE_REG(GTZC_TZIC1->IER2, TZIC1_IER2_ALL); + WRITE_REG(GTZC_TZIC1->IER3, TZIC1_IER3_ALL); + WRITE_REG(GTZC_TZIC1->IER4, TZIC1_IER4_ALL); + } + else + { + /* common case where only one peripheral is configured */ + register_address = (uint32_t) &(GTZC_TZIC1->IER1) + + (4U * GTZC_GET_REG_INDEX(PeriphId)); + SET_BIT(*(__IO uint32_t *)register_address, 1UL << GTZC_GET_PERIPH_POS(PeriphId)); + } + + return HAL_OK; +} + +/** + * @brief Get TZIC flag on a single TZIC peripheral or on all peripherals. + * @param PeriphId Peripheral identifier. + * This parameter can be a value of @ref GTZC_TZSC_TZIC_PeriphId. + * Use GTZC_PERIPH_ALL to select all peripherals. + * @param pFlag Pointer to the flags. + * If PeriphId target a single peripheral, pointer on a single element. + * If all peripherals selected (GTZC_PERIPH_ALL), pointer to an array + * of GTZC_TZIC_PERIPH_NUMBER elements. + * Element content is either GTZC_TZIC_NO_ILA_EVENT + * or GTZC_TZSC_ILA_EVENT_PENDING. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_GTZC_TZIC_GetFlag(uint32_t PeriphId, uint32_t *pFlag) +{ + uint32_t i; + uint32_t reg_value; + uint32_t register_address; + + /* check entry parameters */ + if ((HAL_GTZC_GET_ARRAY_INDEX(PeriphId) >= GTZC_TZIC_PERIPH_NUMBER) + || (((PeriphId & GTZC_PERIPH_ALL) != 0U) + && (HAL_GTZC_GET_ARRAY_INDEX(PeriphId) != 0U))) + { + return HAL_ERROR; + } + + if ((PeriphId & GTZC_PERIPH_ALL) != 0U) + { + /* special case where it is applied to all peripherals */ + reg_value = READ_REG(GTZC_TZIC1->SR1); + for (i = 0U; i < 32U; i++) + { + pFlag[i] = (reg_value & (1UL << i)) >> i; + } + + reg_value = READ_REG(GTZC_TZIC1->SR2); + for (i = 32U; i < 64U; i++) + { + pFlag[i] = (reg_value & (1UL << (i - 32U))) >> (i - 32U); + } + + reg_value = READ_REG(GTZC_TZIC1->SR3); + for (i = 64U; i < 96U; i++) + { + pFlag[i] = (reg_value & (1UL << (i - 64U))) >> (i - 64U); + } + + reg_value = READ_REG(GTZC_TZIC1->SR4); + for (i = 96U; i < 128U; i++) + { + pFlag[i] = (reg_value & (1UL << (i - 96U))) >> (i - 96U); + } + } + else + { + /* common case where only one peripheral is concerned */ + register_address = (uint32_t) &(GTZC_TZIC1->SR1) + + (4U * GTZC_GET_REG_INDEX(PeriphId)); + *pFlag = READ_BIT(*(__IO uint32_t *)register_address, + 1UL << GTZC_GET_PERIPH_POS(PeriphId)) >> GTZC_GET_PERIPH_POS(PeriphId); + } + + return HAL_OK; +} + +/** + * @brief Clear TZIC flag on a single TZIC peripheral or on all peripherals. + * @param PeriphId Peripheral identifier. + * This parameter can be a value of @ref GTZC_TZSC_TZIC_PeriphId. + * Use GTZC_PERIPH_ALL to select all peripherals. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_GTZC_TZIC_ClearFlag(uint32_t PeriphId) +{ + uint32_t register_address; + + /* check entry parameters */ + if ((HAL_GTZC_GET_ARRAY_INDEX(PeriphId) >= GTZC_TZIC_PERIPH_NUMBER) + || (((PeriphId & GTZC_PERIPH_ALL) != 0U) + && (HAL_GTZC_GET_ARRAY_INDEX(PeriphId) != 0U))) + { + return HAL_ERROR; + } + + if ((PeriphId & GTZC_PERIPH_ALL) != 0U) + { + /* same configuration is applied to all peripherals */ + WRITE_REG(GTZC_TZIC1->FCR1, TZIC1_FCR1_ALL); + WRITE_REG(GTZC_TZIC1->FCR2, TZIC1_FCR2_ALL); + WRITE_REG(GTZC_TZIC1->FCR3, TZIC1_FCR3_ALL); + WRITE_REG(GTZC_TZIC1->FCR4, TZIC1_FCR4_ALL); + } + else + { + /* common case where only one peripheral is configured */ + register_address = (uint32_t) &(GTZC_TZIC1->FCR1) + + (4U * GTZC_GET_REG_INDEX(PeriphId)); + SET_BIT(*(__IO uint32_t *)register_address, 1UL << GTZC_GET_PERIPH_POS(PeriphId)); + } + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup GTZC_Exported_Functions_Group6 IRQ related functions + * @brief IRQ related functions + * + @verbatim + ============================================================================== + ##### TZIC IRQ Handler and Callback functions ##### + ============================================================================== + [..] + This section provides functions allowing to treat ISR and provide user callback + @endverbatim + * @{ + */ + +/** + * @brief This function handles GTZC TZIC interrupt request. + * @retval None. + */ +void HAL_GTZC_IRQHandler(void) +{ + uint32_t position; + uint32_t flag; + uint32_t ier_itsources; + uint32_t sr_flags; + + /* Get current IT Flags and IT sources value on 1st register of TZIC1 */ + ier_itsources = READ_REG(GTZC_TZIC1_S->IER1); + sr_flags = READ_REG(GTZC_TZIC1_S->SR1); + + /* Get Mask interrupt and then clear them */ + flag = ier_itsources & sr_flags; + if (flag != 0U) + { + WRITE_REG(GTZC_TZIC1_S->FCR1, flag); + + /* Loop on flag to check, which ones have been raised */ + position = 0U; + while ((flag >> position) != 0U) + { + if ((flag & (1UL << position)) != 0U) + { + HAL_GTZC_TZIC_Callback(GTZC1_PERIPH_REG1 | position); + } + + /* Position bit to be updated */ + position++; + } + } + + /* Get current IT Flags and IT sources value on 2nd register of TZIC1 */ + ier_itsources = READ_REG(GTZC_TZIC1_S->IER2); + sr_flags = READ_REG(GTZC_TZIC1_S->SR2); + + /* Get Mask interrupt and then clear them */ + flag = ier_itsources & sr_flags; + if (flag != 0U) + { + WRITE_REG(GTZC_TZIC1_S->FCR2, flag); + + /* Loop on flag to check, which ones have been raised */ + position = 0U; + while ((flag >> position) != 0U) + { + if ((flag & (1UL << position)) != 0U) + { + HAL_GTZC_TZIC_Callback(GTZC1_PERIPH_REG2 | position); + } + + /* Position bit to be updated */ + position++; + } + } + + /* Get current IT Flags and IT sources value on 3rd register of TZIC1 */ + ier_itsources = READ_REG(GTZC_TZIC1_S->IER3); + sr_flags = READ_REG(GTZC_TZIC1_S->SR3); + + /* Get Mask interrupt and then clear them */ + flag = ier_itsources & sr_flags; + if (flag != 0U) + { + WRITE_REG(GTZC_TZIC1_S->FCR3, flag); + + /* Loop on flag to check, which ones have been raised */ + position = 0U; + while ((flag >> position) != 0U) + { + if ((flag & (1UL << position)) != 0U) + { + HAL_GTZC_TZIC_Callback(GTZC1_PERIPH_REG3 | position); + } + + /* Position bit to be updated */ + position++; + } + } + + /* Get current IT Flags and IT sources value on 4th register of TZIC1 */ + ier_itsources = READ_REG(GTZC_TZIC1_S->IER4); + sr_flags = READ_REG(GTZC_TZIC1_S->SR4); + + /* Get Mask interrupt and then clear them */ + flag = ier_itsources & sr_flags; + if (flag != 0U) + { + WRITE_REG(GTZC_TZIC1->FCR4, flag); + + /* Loop on flag to check, which ones have been raised */ + position = 0U; + while ((flag >> position) != 0U) + { + if ((flag & (1UL << position)) != 0U) + { + HAL_GTZC_TZIC_Callback(GTZC1_PERIPH_REG4 | position); + } + + /* Position bit to be updated */ + position++; + } + } +} + +/** + * @brief GTZC TZIC sub-block interrupt callback. + * @param PeriphId Peripheral identifier triggering the illegal access. + * This parameter can be a value of @ref GTZC_TZSC_TZIC_PeriphId + * @retval None. + */ +__weak void HAL_GTZC_TZIC_Callback(uint32_t PeriphId) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(PeriphId); + + /* NOTE: This function should not be modified. When the callback is needed, + * the HAL_GTZC_TZIC_Callback is to be implemented in the user file + */ +} + +/** + * @} + */ + +#endif /* defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/** + * @} + */ + +#endif /*HAL_GTZC_MODULE_ENABLED*/ + +/** + * @} + */ + +/** + * @} + */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_hash.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_hash.c new file mode 100644 index 0000000000..9c09db3fcc --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_hash.c @@ -0,0 +1,3133 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_hash.c + * @author MCD Application Team + * @brief HASH HAL module driver. + * This file provides firmware functions to manage HASH peripheral + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + =============================================================================== + ##### How to use this driver ##### + =============================================================================== + [..] + The HASH HAL driver can be used as follows: + + (#)Initialize the HASH low level resources by implementing the HAL_HASH_MspInit(): + (##) Enable the HASH interface clock using __HAL_RCC_HASH_CLK_ENABLE() + (##) When resorting to interrupt-based APIs (e.g. HAL_HASH_Start_IT()) + (+++) Configure the HASH interrupt priority using HAL_NVIC_SetPriority() + (+++) Enable the HASH IRQ handler using HAL_NVIC_EnableIRQ() + (+++) In HASH IRQ handler, call HAL_HASH_IRQHandler() API + (##) When resorting to DMA-based APIs (e.g. HAL_HASH_Start_DMA()) + (+++) Enable the DMA interface clock + (+++) Configure and enable one DMA to manage data transfer from + memory to peripheral (input DMA). Managing data transfer from + peripheral to memory can be performed only using CPU. + (+++) Associate the initialized DMA handle to the HASH DMA handle + using __HAL_LINKDMA() + (+++) Configure the priority and enable the NVIC for the transfer complete + interrupt on the DMA: use + HAL_NVIC_SetPriority() and + HAL_NVIC_EnableIRQ() + + (#)Initialize the HASH HAL using HAL_HASH_Init(). This function: + (##) resorts to HAL_HASH_MspInit() for low-level initialization, + (##) configures the data type: no swap, half word swap, bit swap or byte swap, + (##) configures the Algorithm : MD5, SHA1 or SHA2 + + (#)Three processing schemes are available: + (##) Polling mode: processing APIs are blocking functions + i.e. they process the data and wait till the digest computation is finished, + e.g. HAL_HASH_Start() for HASH or HAL_HMAC_Start() for HMAC + (##) Interrupt mode: processing APIs are not blocking functions + i.e. they process the data under interrupt, + e.g. HAL_HASH_Start_IT() for HASH or HAL_HMAC_Start_IT() for HMAC + (##) DMA mode: processing APIs are not blocking functions and the CPU is + not used for data transfer i.e. the data transfer is ensured by DMA, + e.g. HAL_HASH_Start_DMA() for HASH or HAL_HMAC_Start_DMA() for HMAC. + + (#)When the processing function is called after HAL_HASH_Init(), the HASH peripheral is + initialized and processes the buffer fed in input. When the input data have all been + fed to the Peripheral, the digest computation can start. + + (#)Multi-buffer processing HASH and HMAC are possible in polling, interrupt and DMA modes. + (##) In polling mode, API HAL_HASH_Accumulate()/HAL_HASH_HMAC_Accumulate() must be called + for each input buffer, except for the last one. + User must resort to HAL_HASH_AccumulateLast()/HAL_HASH_HMAC_AccumulateLast() + to enter the last one and retrieve as well the computed digest. + + (##) In interrupt mode, API HAL_HASH_Accumulate_IT()/HAL_HASH_HMAC_Accumulate_IT() must + be called for each input buffer, except for the last one. + User must resort to HAL_HASH_AccumulateLast_IT()/HAL_HASH_HMAC_AccumulateLast_IT() + to enter the last one and retrieve as well the computed digest. + + (##) In DMA mode, once initialization is done, MDMAT bit must be set through + __HAL_HASH_SET_MDMAT() macro. + From that point, each buffer can be fed to the Peripheral through HAL_HASH_Start_DMA() API + for HASH and HAL_HASH_HMAC_Start_DMA() API for HMAC . + Before entering the last buffer, reset the MDMAT bit with __HAL_HASH_RESET_MDMAT() + macro then wrap-up the HASH processing in feeding the last input buffer through the + same API HAL_HASH_Start_DMA()for HASH and HAL_HASH_HMAC_Start_DMA() API for HMAC and + retrieve as well the computed digest. + + (#)To use this driver (version 2.0.0) with application developed with old driver (version 1.0.0) user have to: + (##) Add Algorithm as parameter like DataType or KeySize. + (##) Use new API HAL_HASH_Start() for HASH and HAL_HASH_HMAC_Start() for HMAC processing instead of old API + like HAL_HASH_SHA1_Start and HAL_HMAC_SHA1_Start. + + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +#if defined (HASH) + +/** @defgroup HASH HASH + * @brief HASH HAL module driver. + * @{ + */ + +#ifdef HAL_HASH_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup HASH_Private_Defines HASH Private Defines + * @{ + */ +#define HASH_TIMEOUTVALUE 1000U /*!< Time-out value */ +#define BLOCK_64B 64U /*!< block Size equal to 64 bytes */ +#define BLOCK_128B 128U /*!< block Size equal to 128 bytes */ +/** + * @} + */ + +/** @defgroup HASH_Number_Of_CSR_Registers HASH Number of Context Swap Registers + * @{ + */ +#if defined(HASH_ALGOSELECTION_SHA512) +#define HASH_NUMBER_OF_CSR_REGISTERS 103U /*!< Number of Context Swap Registers */ +#else +#define HASH_NUMBER_OF_CSR_REGISTERS 54U /*!< Number of Context Swap Registers */ +#endif /* HASH_ALGOSELECTION_SHA512 */ +/** + * @} + */ + +/* Private Constants ---------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup HASH_Private_Functions HASH Private Functions + * @{ + */ +static void HASH_GetDigest(const HASH_HandleTypeDef *hhash, const uint8_t *pMsgDigest, uint8_t Size); +static void HASH_WriteData(HASH_HandleTypeDef *hhash, const uint8_t *pInBuffer, uint32_t Size); +static HAL_StatusTypeDef HASH_WriteData_IT(HASH_HandleTypeDef *hhash); +static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma); +static void HASH_DMAError(DMA_HandleTypeDef *hdma); +static HAL_StatusTypeDef HASH_WaitOnFlagUntilTimeout(HASH_HandleTypeDef *hhash, uint32_t Flag, FlagStatus Status, + uint32_t Timeout); +/** + * @} + */ + +/* Exported functions ---------------------------------------------------------*/ + +/** @defgroup HASH_Exported_Functions HASH Exported Functions + * @{ + */ + +/** @defgroup HASH_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 the HASH according to the specified parameters + in the HASH_InitTypeDef and create the associated handle + (+) DeInitialize the HASH peripheral + (+) Initialize the HASH MCU Specific Package (MSP) + (+) DeInitialize the HASH MSP + (+) Configure HASH (HAL_HASH_SetConfig) with the specified parameters in the HASH_ConfigTypeDef + Parameters which are configured in This section are : + (+) Data Type : no swap, half word swap, bit swap or byte swap + (+) Algorithm : MD5,SHA1 or SHA2 + (+) Get HASH configuration (HAL_HASH_GetConfig) from the specified parameters in the HASH_HandleTypeDef + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the HASH according to the specified parameters in the + HASH_HandleTypeDef and create the associated handle. + * @note Only Algorithm and DATATYPE bits of HASH Peripheral are set by HAL_HASH_Init(), + * other configuration bits are set by HASH or HMAC processing APIs. + * @param hhash pointer to a HASH_HandleTypeDef structure that contains + * the configuration information for HASH module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HASH_Init(HASH_HandleTypeDef *hhash) +{ + uint32_t cr_value; + + /* Check the hash handle allocation */ + if (hhash == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_HASH_DATATYPE(hhash->Init.DataType)); + assert_param(IS_HASH_ALGORITHM(hhash->Init.Algorithm)); + +#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1) + if (hhash->State == HAL_HASH_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hhash->Lock = HAL_UNLOCKED; + + /* Reset Callback pointers in HAL_HASH_STATE_RESET only */ + hhash->InCpltCallback = HAL_HASH_InCpltCallback; /* Legacy weak InCpltCallback */ + hhash->DgstCpltCallback = HAL_HASH_DgstCpltCallback; /* Legacy weak DgstCpltCallback */ + hhash->ErrorCallback = HAL_HASH_ErrorCallback; /* Legacy weak ErrorCallback */ + if (hhash->MspInitCallback == NULL) + { + hhash->MspInitCallback = HAL_HASH_MspInit; + } + + /* Init the low level hardware */ + hhash->MspInitCallback(hhash); + } +#else + if (hhash->State == HAL_HASH_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hhash->Lock = HAL_UNLOCKED; + + /* Init the low level hardware */ + HAL_HASH_MspInit(hhash); + } +#endif /* (USE_HAL_HASH_REGISTER_CALLBACKS) */ + + /* Set the key size, data type and Algorithm */ + cr_value = (uint32_t)(hhash->Init.DataType | hhash->Init.Algorithm); + /* Set the key size, data type, algorithm and mode */ + MODIFY_REG(hhash->Instance->CR, HASH_CR_DATATYPE | HASH_CR_ALGO | HASH_CR_INIT, cr_value); + + /* Change HASH phase to Ready */ + hhash->Phase = HAL_HASH_PHASE_READY; + + /* Change HASH state to Ready */ + hhash->State = HAL_HASH_STATE_READY; + + /* Reset error code field */ + hhash->ErrorCode = HAL_HASH_ERROR_NONE; + +#if (USE_HAL_HASH_SUSPEND_RESUME == 1U) + /* Reset suspension request flag */ + hhash->SuspendRequest = HAL_HASH_SUSPEND_NONE; +#endif /* (USE_HAL_HASH_SUSPEND_RESUME) */ + /* Return function status */ + return HAL_OK; +} + +/** + * @brief DeInitialize the HASH peripheral. + * @param hhash pointer to a HASH_HandleTypeDef structure that contains + * the configuration information for HASH module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HASH_DeInit(HASH_HandleTypeDef *hhash) +{ + /* Check the HASH handle allocation */ + if (hhash == NULL) + { + return HAL_ERROR; + } + + /* Change the default HASH phase */ + hhash->Phase = HAL_HASH_PHASE_READY; + + /* Reset HashInCount */ + hhash->HashInCount = 0U; + + /* Reset multi buffers accumulation flag */ + hhash->Accumulation = 0U; + +#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1) + if (hhash->MspDeInitCallback == NULL) + { + hhash->MspDeInitCallback = HAL_HASH_MspDeInit; + } + + /* DeInit the low level hardware */ + hhash->MspDeInitCallback(hhash); +#else + /* DeInit the low level hardware: CLOCK, NVIC */ + HAL_HASH_MspDeInit(hhash); +#endif /* (USE_HAL_HASH_REGISTER_CALLBACKS) */ + + /* Set the HASH state to Ready */ + hhash->State = HAL_HASH_STATE_RESET; + + __HAL_UNLOCK(hhash); + + return HAL_OK; +} + +/** + * @brief Configure the HASH according to the specified + * parameters in the HASH_ConfigTypeDef + * @param hhash pointer to a HASH_HandleTypeDef structure + * @param pConf pointer to a HASH_ConfigTypeDef structure that contains + * the configuration information for HASH module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HASH_SetConfig(HASH_HandleTypeDef *hhash, HASH_ConfigTypeDef *pConf) +{ + uint32_t cr_value; + + /* Check the HASH handle allocation */ + if ((hhash == NULL) || (pConf == NULL)) + { + return HAL_ERROR; + } + + /* Check parameters */ + assert_param(IS_HASH_DATATYPE(pConf->DataType)); + assert_param(IS_HASH_ALGORITHM(pConf->Algorithm)); + + if (hhash->State == HAL_HASH_STATE_READY) + { + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_BUSY; + __HAL_LOCK(hhash); + + /* Set HASH parameters */ + hhash->Init.DataType = pConf->DataType; + hhash->Init.pKey = pConf->pKey; + hhash->Init.Algorithm = pConf->Algorithm; + hhash->Init.KeySize = pConf->KeySize; + + /* Set the key size, data type and Algorithm */ + cr_value = (uint32_t)(hhash->Init.DataType | hhash->Init.Algorithm); + /* Set the key size, data type, algorithm and mode */ + MODIFY_REG(hhash->Instance->CR, HASH_CR_DATATYPE | HASH_CR_ALGO | HASH_CR_INIT, cr_value); + + /* Change HASH phase to Ready */ + hhash->Phase = HAL_HASH_PHASE_READY; + + /* Change HASH state to Ready */ + hhash->State = HAL_HASH_STATE_READY; + + /* Reset error code field */ + hhash->ErrorCode = HAL_HASH_ERROR_NONE; + + __HAL_UNLOCK(hhash); + + return HAL_OK; + + } + else + { + /* Busy error code field */ + hhash->ErrorCode |= HAL_HASH_ERROR_BUSY; + return HAL_ERROR; + } +} + +/** + * @brief Get HASH Configuration parameters in associated handle + * @param pConf pointer to a HASH_HandleTypeDef structure + * @param hhash pointer to a HASH_ConfigTypeDef structure that contains + * the configuration information for HASH module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HASH_GetConfig(HASH_HandleTypeDef *hhash, HASH_ConfigTypeDef *pConf) +{ + + /* Check the HASH handle allocation */ + if ((hhash == NULL) || (pConf == NULL)) + { + return HAL_ERROR; + } + + if (hhash->State == HAL_HASH_STATE_READY) + { + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_BUSY; + __HAL_LOCK(hhash); + + /* Set HASH parameters */ + pConf->DataType = hhash->Init.DataType; + pConf->pKey = hhash->Init.pKey; + pConf->Algorithm = hhash->Init.Algorithm; + pConf->KeySize = hhash->Init.KeySize; + + /* Change HASH state to Ready */ + hhash->State = HAL_HASH_STATE_READY; + __HAL_UNLOCK(hhash); + + return HAL_OK; + + } + else + { + /* Busy error code field */ + hhash->ErrorCode |= HAL_HASH_ERROR_BUSY; + return HAL_ERROR; + } +} + +/** + * @brief Initialize the HASH MSP. + * @param hhash pointer to a HASH_HandleTypeDef structure that contains + * the configuration information for HASH module. + * @retval None + */ +__weak void HAL_HASH_MspInit(HASH_HandleTypeDef *hhash) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhash); + + /* NOTE : This function should not be modified; when the callback is needed, + HAL_HASH_MspInit() can be implemented in the user file. + */ +} + +/** + * @brief DeInitialize the HASH MSP. + * @param hhash pointer to a HASH_HandleTypeDef structure that contains + * the configuration information for HASH module. + * @retval None + */ +__weak void HAL_HASH_MspDeInit(HASH_HandleTypeDef *hhash) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhash); + + /* NOTE : This function should not be modified; when the callback is needed, + HAL_HASH_MspDeInit() can be implemented in the user file. + */ +} + + +#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User HASH Callback + * To be used instead of the weak (overridden) predefined callback + * @param hhash HASH handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg HAL_HASH_INPUTCPLT_CB_ID input completion callback ID + * @arg HAL_HASH_DGSTCPLT_CB_ID digest computation completion callback ID + * @arg HAL_HASH_ERROR_CB_ID error callback ID + * @arg HAL_HASH_MSPINIT_CB_ID MspInit callback ID + * @arg HAL_HASH_MSPDEINIT_CB_ID MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @retval status + */ +HAL_StatusTypeDef HAL_HASH_RegisterCallback(HASH_HandleTypeDef *hhash, HAL_HASH_CallbackIDTypeDef CallbackID, + pHASH_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hhash->ErrorCode |= HAL_HASH_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + + if (hhash->State == HAL_HASH_STATE_READY) + { + switch (CallbackID) + { + case HAL_HASH_INPUTCPLT_CB_ID : + hhash->InCpltCallback = pCallback; + break; + + case HAL_HASH_DGSTCPLT_CB_ID : + hhash->DgstCpltCallback = pCallback; + break; + + case HAL_HASH_ERROR_CB_ID : + hhash->ErrorCallback = pCallback; + break; + + case HAL_HASH_MSPINIT_CB_ID : + hhash->MspInitCallback = pCallback; + break; + + case HAL_HASH_MSPDEINIT_CB_ID : + hhash->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hhash->ErrorCode |= HAL_HASH_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else if (hhash->State == HAL_HASH_STATE_RESET) + { + switch (CallbackID) + { + case HAL_HASH_MSPINIT_CB_ID : + hhash->MspInitCallback = pCallback; + break; + + case HAL_HASH_MSPDEINIT_CB_ID : + hhash->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hhash->ErrorCode |= HAL_HASH_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hhash->ErrorCode |= HAL_HASH_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister a HASH Callback + * HASH Callback is redirected to the weak (overridden) predefined callback + * @param hhash HASH handle + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg HAL_HASH_INPUTCPLT_CB_ID HASH input completion Callback ID + * @arg HAL_HASH_DGSTCPLT_CB_ID HASH digest computation completion Callback ID + * @arg HAL_HASH_ERROR_CB_ID HASH error Callback ID + * @arg HAL_HASH_MSPINIT_CB_ID HASH MspInit callback ID + * @arg HAL_HASH_MSPDEINIT_CB_ID HASH MspDeInit callback ID + * @retval status + */ +HAL_StatusTypeDef HAL_HASH_UnRegisterCallback(HASH_HandleTypeDef *hhash, HAL_HASH_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + + if (hhash->State == HAL_HASH_STATE_READY) + { + switch (CallbackID) + { + case HAL_HASH_INPUTCPLT_CB_ID : + hhash->InCpltCallback = HAL_HASH_InCpltCallback; /* Legacy weak input completion callback */ + break; + + case HAL_HASH_DGSTCPLT_CB_ID : + hhash->DgstCpltCallback = HAL_HASH_DgstCpltCallback; /* Legacy weak digest computation + completion callback */ + break; + + case HAL_HASH_ERROR_CB_ID : + hhash->ErrorCallback = HAL_HASH_ErrorCallback; /* Legacy weak error callback */ + break; + + case HAL_HASH_MSPINIT_CB_ID : + hhash->MspInitCallback = HAL_HASH_MspInit; /* Legacy weak MspInit Callback */ + break; + + case HAL_HASH_MSPDEINIT_CB_ID : + hhash->MspDeInitCallback = HAL_HASH_MspDeInit; /* Legacy weak MspDeInit Callback */ + break; + + default : + /* Update the error code */ + hhash->ErrorCode |= HAL_HASH_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else if (hhash->State == HAL_HASH_STATE_RESET) + { + switch (CallbackID) + { + case HAL_HASH_MSPINIT_CB_ID : + hhash->MspInitCallback = HAL_HASH_MspInit; /* Legacy weak MspInit Callback */ + break; + + case HAL_HASH_MSPDEINIT_CB_ID : + hhash->MspDeInitCallback = HAL_HASH_MspDeInit; /* Legacy weak MspDeInit Callback */ + break; + + default : + /* Update the error code */ + hhash->ErrorCode |= HAL_HASH_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hhash->ErrorCode |= HAL_HASH_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + } + + return status; +} +#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */ + +#if (USE_HAL_HASH_SUSPEND_RESUME == 1U) +/** + * @brief Save the HASH context in case of processing suspension. + * @param hhash HASH handle. + * @param pMemBuffer pointer to the memory buffer where the HASH context + * is saved. + * @note The IMR, STR, CR then all the CSR registers are saved + * in that order. Only the r/w bits are read to be restored later on. + * @note By default, all the context swap registers (there are + * HASH_NUMBER_OF_CSR_REGISTERS of those) are saved. + * @note pMemBuffer points to a buffer allocated by the user. The buffer size + * must be at least (HASH_NUMBER_OF_CSR_REGISTERS + 3) * 4 uint8 long. + * @retval None + */ +void HAL_HASH_Suspend(HASH_HandleTypeDef *hhash, uint8_t *pMemBuffer) +{ + uint32_t mem_ptr = (uint32_t)pMemBuffer; + uint32_t csr_ptr = (uint32_t)(hhash->Instance->CSR); + uint32_t i; + + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhash); + + /* Save IMR register content */ + *(uint32_t *)(mem_ptr) = READ_BIT(hhash->Instance->IMR, HASH_IT_DINI | HASH_IT_DCI); + mem_ptr += 4U; + /* Save STR register content */ + *(uint32_t *)(mem_ptr) = READ_BIT(hhash->Instance->STR, HASH_STR_NBLW); + mem_ptr += 4U; + /* Save CR register content */ + *(uint32_t *)(mem_ptr) = READ_BIT(hhash->Instance->CR, HASH_CR_DMAE | HASH_CR_DATATYPE | HASH_CR_MODE | HASH_CR_ALGO | + HASH_CR_LKEY | HASH_CR_MDMAT); + + mem_ptr += 4U; + /* By default, save all CSRs registers */ + for (i = HASH_NUMBER_OF_CSR_REGISTERS; i > 0U; i--) + { + *(uint32_t *)(mem_ptr) = *(uint32_t *)(csr_ptr); + mem_ptr += 4U; + csr_ptr += 4U; + } + /* Save low-priority block HASH handle parameters */ + hhash->Init_saved = hhash->Init; + hhash->pHashOutBuffPtr_saved = hhash->pHashOutBuffPtr; + hhash->HashInCount_saved = hhash->HashInCount; + hhash->Size_saved = hhash->Size; + hhash->pHashInBuffPtr_saved = hhash->pHashInBuffPtr; + hhash->Phase_saved = hhash->Phase; + hhash->pHashKeyBuffPtr_saved = hhash->pHashKeyBuffPtr; +} + + +/** + * @brief Restore the HASH context in case of processing resumption. + * @param hhash HASH handle. + * @param pMemBuffer pointer to the memory buffer where the HASH context + * is stored. + * @note The IMR, STR, CR then all the CSR registers are restored + * in that order. Only the r/w bits are restored. + * @note By default, all the context swap registers (HASH_NUMBER_OF_CSR_REGISTERS + * of those) are restored (all of them have been saved by default + * beforehand). + * @retval None + */ +void HAL_HASH_Resume(HASH_HandleTypeDef *hhash, uint8_t *pMemBuffer) +{ + uint32_t mem_ptr = (uint32_t)pMemBuffer; + uint32_t csr_ptr = (uint32_t)(hhash->Instance->CSR); + uint32_t i; + + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhash); + + /* Restore IMR register content */ + WRITE_REG(hhash->Instance->IMR, (*(uint32_t *)(mem_ptr))); + mem_ptr += 4U; + /* Restore STR register content */ + WRITE_REG(hhash->Instance->STR, (*(uint32_t *)(mem_ptr))); + mem_ptr += 4U; + /* Restore CR register content */ + WRITE_REG(hhash->Instance->CR, (*(uint32_t *)(mem_ptr))); + mem_ptr += 4U; + + /* Reset the HASH processor before restoring the Context + Swap Registers (CSR) */ + SET_BIT(hhash->Instance->CR, HASH_CR_INIT); + + + /* By default, restore all CSR registers */ + for (i = HASH_NUMBER_OF_CSR_REGISTERS; i > 0U; i--) + { + WRITE_REG((*(uint32_t *)(csr_ptr)), (*(uint32_t *)(mem_ptr))); + mem_ptr += 4U; + csr_ptr += 4U; + } + + /* Restore low-priority block HASH handle parameters */ + hhash->Init = hhash->Init_saved; + hhash->pHashOutBuffPtr = hhash->pHashOutBuffPtr_saved; + hhash->HashInCount = hhash->HashInCount_saved; + hhash->Size = hhash->Size_saved; + hhash->pHashInBuffPtr = hhash->pHashInBuffPtr_saved; + hhash->Phase = hhash->Phase_saved; + hhash->State = HAL_HASH_STATE_SUSPENDED; + hhash->pHashKeyBuffPtr = hhash->pHashKeyBuffPtr_saved; +} + +/** + * @brief Initiate HASH processing suspension when in interruption mode. + * @param hhash HASH handle. + * @note Set the handle field SuspendRequest to the appropriate value so that + * the on-going HASH processing is suspended as soon as the required + * conditions are met. Note that the actual suspension is carried out + * by the functions HASH_WriteData() in polling mode and HASH_IT() in + * interruption mode. + * @retval None + */ +HAL_StatusTypeDef HAL_HASH_ProcessSuspend(HASH_HandleTypeDef *hhash) +{ + uint32_t remainingwords; /*remaining number in of source block to be transferred.*/ + uint32_t nbbytePartialHash = (((hhash->Instance->SR) >> 16U) * 4U); /* Nb byte to enter in HASH fifo + to trig a partial HASH computation*/ + uint32_t sizeinwords;/* number in word of source block to be transferred.*/ + + /* suspension in DMA mode*/ + if (__HAL_HASH_GET_FLAG(hhash, HASH_FLAG_DMAS) != RESET) + { + if (hhash->State == HAL_HASH_STATE_READY) + { + return HAL_ERROR; + } + else + { + + /* Clear the DMAE bit to disable the DMA interface */ + CLEAR_BIT(HASH->CR, HASH_CR_DMAE); + + /* Wait until the last DMA transfer is complete (DMAS = 0 in the HASH_SR register) */ + if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DMAS, SET, HASH_TIMEOUTVALUE) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* At this point, DMA interface is disabled and no transfer is on-going */ + /* Retrieve from the DMA handle how many words remain to be written */ + /* DMA3 used, DMA_CBR1_BNDT in bytes, DMA_CSR_FIFOL in words */ + remainingwords = ((((DMA_Channel_TypeDef *)hhash->hdmain->Instance)->CBR1) \ + & DMA_CBR1_BNDT) / 4U; + remainingwords += ((((DMA_Channel_TypeDef *)hhash->hdmain->Instance)->CSR) \ + & DMA_CSR_FIFOL) >> DMA_CSR_FIFOL_Pos; + + if (remainingwords <= nbbytePartialHash) + { + /* No suspension attempted since almost to the end of the transferred data. */ + /* Best option for user code is to wrap up low priority message hashing */ + return HAL_ERROR; + } + + /* Disable DMA channel */ + /* Note that the Abort function will + - Clear the transfer error flags + - Unlock + - Set the State + */ + if (HAL_DMA_Abort(hhash->hdmain) != HAL_OK) + { + return HAL_ERROR; + } + + if (__HAL_HASH_GET_FLAG(hhash, HASH_FLAG_DCIS) != RESET) + { + return HAL_ERROR; + } + + /* Wait until the hash processor is ready (no block is being processed), that is wait for DINIS=1 in HASH_SR */ + if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DINIS, RESET, HASH_TIMEOUTVALUE) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Compute how many words were supposed to be transferred by DMA */ + sizeinwords = (((hhash->Size % 4U) != 0U) ? \ + ((hhash->Size + 3U) / 4U) : (hhash->Size / 4U)); + /* Accordingly, update the input pointer that points at the next word to be + transferred to the Peripheral by DMA */ + hhash->pHashInBuffPtr += 4U * (sizeinwords - remainingwords) ; + + /* And store in HashInCount the remaining size to transfer (in bytes) */ + hhash->HashInCount = 4U * remainingwords; + + + hhash->State = HAL_HASH_STATE_SUSPENDED; + __HAL_UNLOCK(hhash); + return HAL_OK; + } + + } + else /* suspension when in interruption mode*/ + { + /* Set Handle Suspend Request field */ + hhash->SuspendRequest = HAL_HASH_SUSPEND; + return HAL_OK; + } +} +#endif /* USE_HAL_HASH_SUSPEND_RESUME */ +/** + * @} + */ + + +/** @defgroup HASH_Exported_Functions_Group2 HASH processing functions + * @brief HASH processing functions using different mode. + * +@verbatim + =============================================================================== + ##### HASH processing functions ##### + =============================================================================== + [..] This section provides API allowing to calculate the hash value using + one of the HASH algorithms supported by the peripheral. + + [..] For a single buffer to be hashed, user can resort to one of three processing + functions available . + (+) Polling mode : HAL_HASH_Start() + (+) Interrupt mode : HAL_HASH_Start_IT() + (+) DMA mode : HAL_HASH_Start_DMA() + + [..] In case of multi-buffer HASH processing (a single digest is computed while + several buffers are fed to the Peripheral), the user can resort to successive calls + to : + (+) Polling mode : HAL_HASH_Accumulate() and wrap-up the digest computation by a call + to HAL_HASH_AccumulateLast() + (+) Interrupt mode : HAL_HASH_Accumulate_IT() and wrap-up the digest computation by a call + to HAL_HASH_AccumulateLast_IT() + (+) DMA mode : HAL_HASH_Start_DMA(), MDMAT bit must be set through __HAL_HASH_SET_MDMAT() macro, + before entering the last buffer, reset the MDMAT bit with __HAL_HASH_RESET_MDMAT() + macro then wrap-up the HASH processing in feeding the last input buffer through the + same API HAL_HASH_Start_DMA() + +@endverbatim + * @{ + */ + +/** + * @brief HASH peripheral processes in polling mode pInBuffer then reads the computed digest. + * @param hhash HASH handle. + * @param pInBuffer pointer to the input buffer (buffer to be hashed). + * @param Size length of the input buffer in bytes. + * @param pOutBuffer pointer to the computed digest. + * @param Timeout specify timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HASH_Start(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size, + uint8_t *const pOutBuffer, uint32_t Timeout) +{ + /* Check the hash handle allocation */ + if (hhash == NULL) + { + return HAL_ERROR; + } + + /* Check if peripheral is ready to start process */ + if (hhash->State == HAL_HASH_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hhash); + + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_BUSY; + + /* Reset HashInCount and Initialize Size, pHashInBuffPtr and pHashOutBuffPtr parameters */ + hhash->pHashInBuffPtr = pInBuffer; + hhash->pHashOutBuffPtr = pOutBuffer; + hhash->HashInCount = 0U; + hhash->Size = Size; + + /* Set HASH mode */ + CLEAR_BIT(hhash->Instance->CR, HASH_CR_MODE); + /* Reset the HASH processor core */ + MODIFY_REG(hhash->Instance->CR, HASH_CR_INIT, HASH_CR_INIT); + + /* Configure the number of valid bits in last word of the message */ + MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * (Size % 4U)); + + /* Set the phase */ + hhash->Phase = HAL_HASH_PHASE_PROCESS; + + HASH_WriteData(hhash, pInBuffer, Size); + + /* Start the message padding then the Digest calculation */ + SET_BIT(hhash->Instance->STR, HASH_STR_DCAL); + + /* Wait for digest calculation completion status(DCIS) flag to be set */ + if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DCIS, RESET, Timeout) != HAL_OK) + { + return HAL_ERROR; + } + + /* Read the message digest */ + HASH_GetDigest(hhash, pOutBuffer, HASH_DIGEST_LENGTH(hhash)); + + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_READY; + + /* Reset HASH state machine */ + hhash->Phase = HAL_HASH_PHASE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hhash); + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + + +/** + * @brief HASH peripheral processes in interrupt mode pInBuffer then reads the computed digest. + * @param hhash HASH handle. + * @param pInBuffer pointer to the input buffer (buffer to be hashed). + * @param Size length of the input buffer in bytes. + * @param pOutBuffer pointer to the computed digest. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HASH_Start_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size, + uint8_t *const pOutBuffer) +{ + HAL_StatusTypeDef status; + HAL_HASH_StateTypeDef temp_state; + + /* Check the hash handle allocation */ + if (hhash == NULL) + { + return HAL_ERROR; + } + + /* Check if peripheral is ready to start process or suspended */ + temp_state = hhash->State; + if ((temp_state == HAL_HASH_STATE_READY) || (temp_state == HAL_HASH_STATE_SUSPENDED)) + { + /* Process Locked */ + __HAL_LOCK(hhash); + + if (hhash->State == HAL_HASH_STATE_READY) + { + /* Reset HashInCount and Initialize Size, pHashInBuffPtr and pHashOutBuffPtr parameters */ + hhash->HashInCount = 0U; + hhash->pHashInBuffPtr = pInBuffer; + hhash->pHashOutBuffPtr = pOutBuffer; + hhash->Size = Size; + + /* Set HASH mode */ + CLEAR_BIT(hhash->Instance->CR, HASH_CR_MODE); + /* Reset the HASH processor core */ + MODIFY_REG(hhash->Instance->CR, HASH_CR_INIT, HASH_CR_INIT); + + /* Configure the number of valid bits in last word of the message */ + MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * (Size % 4U)); + } + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_BUSY; + /* Set the phase */ + hhash->Phase = HAL_HASH_PHASE_PROCESS; + + /* Enable the specified HASH interrupt*/ + __HAL_HASH_ENABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI); + + status = HASH_WriteData_IT(hhash); + } + else + { + status = HAL_BUSY; + } + /* Return function status */ + return status; +} + +/** + * @brief HASH peripheral processes in DMA mode pInBuffer then reads the computed digest. + * @note Multi-buffer HASH processing is possible, consecutive calls to HAL_HASH_Start_DMA + * (MDMAT bit must be set) can be used to feed several input buffers + * back-to-back to the Peripheral that will yield a single + * HASH signature once all buffers have been entered. Wrap-up of input + * buffers feeding and retrieval of digest is done by a call to + * HAL_HASH_Start_DMA (MDMAT bit must be reset). + * @param hhash HASH handle. + * @param pInBuffer pointer to the input buffer (buffer to be hashed). + * @param Size length of the input buffer in bytes (must be a multiple of 4 in + * case of Multi-buffer and not last buffer). + * @param pOutBuffer pointer to the computed digest. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HASH_Start_DMA(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size, + uint8_t *const pOutBuffer) +{ + HAL_StatusTypeDef status; + HAL_HASH_StateTypeDef temp_state; + + /* Check the hash handle allocation */ + if (hhash == NULL) + { + return HAL_ERROR; + } + + /* Check if peripheral is ready to start process or suspended */ + temp_state = hhash->State; + if ((temp_state == HAL_HASH_STATE_READY) || (temp_state == HAL_HASH_STATE_SUSPENDED)) + { + + /* Process Locked */ + __HAL_LOCK(hhash); + + /* Check if initialization phase has not been already performed */ + if (hhash->State == HAL_HASH_STATE_READY) + { + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_BUSY; + + /* Reset HashInCount and Initialize Size, pHashInBuffPtr and pHashOutBuffPtr parameters */ + hhash->HashInCount = 0U; + hhash->pHashInBuffPtr = pInBuffer; + hhash->pHashOutBuffPtr = pOutBuffer; + hhash->HashInCount = 0U; + hhash->Size = Size; + + /* Check if initialization phase has already been performed. + If Phase is already set to HAL_HASH_PHASE_PROCESS, this means the + API is processing a new input data message in case of multi-buffer HASH + computation. */ + if (hhash->Phase == HAL_HASH_PHASE_READY) + { + /* Set HASH mode */ + CLEAR_BIT(hhash->Instance->CR, HASH_CR_MODE); + /* Reset the HASH processor core */ + MODIFY_REG(hhash->Instance->CR, HASH_CR_INIT, HASH_CR_INIT); + + /* Set the phase */ + hhash->Phase = HAL_HASH_PHASE_PROCESS; + } + /* Configure the number of valid bits in last word of the message */ + if ((hhash->Instance->CR & HASH_CR_MDMAT) == 0U) + { + /* Configure the number of valid bits in last word of the message */ + MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Size) % 4U)); + } + else + { + /* Configure the number of valid bits in last word of the message */ + MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 0U); + } + + } + else /* HAL_HASH_STATE_SUSPENDED */ + { + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_BUSY; + /*only part not yet hashed to compute */ + hhash->Size = hhash->HashInCount; + } + /* Set the HASH DMA transfer complete callback */ + hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt; + /* Set the DMA error callback */ + hhash->hdmain->XferErrorCallback = HASH_DMAError; + + if ((hhash->hdmain->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hhash->hdmain->LinkedListQueue != NULL) && (hhash->hdmain->LinkedListQueue->Head != NULL)) + { + /* Enable the DMA channel */ + hhash->hdmain->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET]\ + = ((((hhash->Size) % 4U) != 0U) ? ((hhash->Size) + (4U - ((hhash->Size) % 4U))) : (hhash->Size)); + hhash->hdmain->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET]\ + = (uint32_t)(hhash->pHashInBuffPtr); /* Set DMA source address */ + hhash->hdmain->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET]\ + = (uint32_t)&hhash->Instance->DIN; /* Set DMA destination address */ + + status = HAL_DMAEx_List_Start_IT(hhash->hdmain); + } + else + { + /* Return error status */ + status = HAL_ERROR; + } + } + else + { + status = HAL_DMA_Start_IT(hhash->hdmain, (uint32_t)pInBuffer, (uint32_t)&hhash->Instance->DIN, \ + ((((hhash->Size) % 4U) != 0U) ? ((hhash->Size) + (4U - ((hhash->Size) % 4U))) : \ + (hhash->Size))); + } + if (status != HAL_OK) + { + /* DMA error code field */ + hhash->ErrorCode |= HAL_HASH_ERROR_DMA; + + /* Return error */ +#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1U) + /*Call registered error callback*/ + hhash->ErrorCallback(hhash); +#else + /*Call legacy weak error callback*/ + HAL_HASH_ErrorCallback(hhash); +#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */ + } + else + { + /* Enable DMA requests */ + SET_BIT(hhash->Instance->CR, HASH_CR_DMAE); + } + } + else + { + status = HAL_BUSY; + + } + + /* Return function status */ + return status; +} + + +/** + * @brief HASH peripheral processes in polling mode several input buffers. + * @note Consecutive calls to HAL_HASH_Accumulate() can be used to feed + * several input buffers back-to-back to the Peripheral that will yield a single + * HASH signature once all buffers have been entered. Wrap-up of input + * buffers feeding and retrieval of digest is done by a call to + * HAL_HASH_AccumulateLast() + * @param hhash HASH handle. + * @param pInBuffer pointer to the input buffer (buffer to be hashed). + * @param Size length of the input buffer in bytes and a multiple of 4. + * @param Timeout specify timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HASH_Accumulate(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size, + uint32_t Timeout) +{ + HAL_HASH_StateTypeDef temp_state; + + /* Check the hash handle allocation and buffer length multiple of 4 */ + if ((hhash == NULL) || ((Size % 4U) != 0U)) + { + return HAL_ERROR; + } + + /* Check if peripheral is ready to start process or suspended */ + temp_state = hhash->State; + if ((temp_state == HAL_HASH_STATE_READY) || (temp_state == HAL_HASH_STATE_SUSPENDED)) + { + /* Process Locked */ + __HAL_LOCK(hhash); + + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_BUSY; + + /* Reset HashInCount and Initialize Size, pHashInBuffPtr and pHashOutBuffPtr parameters */ + hhash->pHashInBuffPtr = pInBuffer; + hhash->HashInCount = 0U; + hhash->Size = Size; + + if (hhash->Phase == HAL_HASH_PHASE_READY) + { + /* Set HASH mode */ + CLEAR_BIT(hhash->Instance->CR, HASH_CR_MODE); + /* Reset the HASH processor core */ + MODIFY_REG(hhash->Instance->CR, HASH_CR_INIT, HASH_CR_INIT); + + /* Set the phase */ + hhash->Phase = HAL_HASH_PHASE_PROCESS; + } + HASH_WriteData(hhash, pInBuffer, Size); + + /* Wait for BUSY flag to be cleared */ + if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, Timeout) != HAL_OK) + { + return HAL_ERROR; + } + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hhash); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + + +/** + * @brief End computation of a single HASH signature after several calls to HAL_HASH_Accumulate() API. + * @note Digest is available in pOutBuffer + * @param hhash HASH handle. + * @param pInBuffer pointer to the input buffer (buffer to be hashed). + * @param Size length of the input buffer in bytes. + * @param pOutBuffer pointer to the computed digest. + * @param Timeout specify timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HASH_AccumulateLast(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size, + uint8_t *const pOutBuffer, uint32_t Timeout) +{ + HAL_HASH_StateTypeDef temp_state; + + /* Check the hash handle allocation */ + if (hhash == NULL) + { + return HAL_ERROR; + } + + /* Check if peripheral is ready to start process or suspended */ + temp_state = hhash->State; + if ((temp_state == HAL_HASH_STATE_READY) || (temp_state == HAL_HASH_STATE_SUSPENDED)) + { + /* Process Locked */ + __HAL_LOCK(hhash); + + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_BUSY; + + /* Reset HashInCount and Initialize Size, pHashInBuffPtr and pHashOutBuffPtr parameters */ + hhash->pHashInBuffPtr = pInBuffer; + hhash->pHashOutBuffPtr = pOutBuffer; + hhash->HashInCount = 0U; + hhash->Size = Size; + + if (hhash->Phase == HAL_HASH_PHASE_READY) + { + /* Set HASH mode */ + CLEAR_BIT(hhash->Instance->CR, HASH_CR_MODE); + /* Reset the HASH processor core */ + MODIFY_REG(hhash->Instance->CR, HASH_CR_INIT, HASH_CR_INIT); + + /* Set the phase */ + hhash->Phase = HAL_HASH_PHASE_PROCESS; + } + /* Configure the number of valid bits in last word of the message */ + MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * (Size % 4U)); + + + HASH_WriteData(hhash, pInBuffer, Size); + + /* Start the message padding then the Digest calculation */ + SET_BIT(hhash->Instance->STR, HASH_STR_DCAL); + + /* Wait for digest calculation completion status(DCIS) flag to be set */ + if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DCIS, RESET, Timeout) != HAL_OK) + { + return HAL_ERROR; + } + /* Read the message digest */ + HASH_GetDigest(hhash, pOutBuffer, HASH_DIGEST_LENGTH(hhash)); + + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_READY; + + /* Reset HASH state machine */ + hhash->Phase = HAL_HASH_PHASE_READY; + hhash->Accumulation = 0; + /* Process Unlocked */ + __HAL_UNLOCK(hhash); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief HASH peripheral processes in interrupt mode several input buffers. + * @note Consecutive calls to HAL_HASH_Accumulate_IT() can be used to feed + * several input buffers back-to-back to the Peripheral that will yield a single + * HASH signature once all buffers have been entered. Wrap-up of input + * buffers feeding and retrieval of digest is done by a call to + * HAL_HASH_AccumulateLast_IT() + * @param hhash HASH handle. + * @param pInBuffer pointer to the input buffer (buffer to be hashed). + * @param Size length of the input buffer in bytes and a multiple of 4. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HASH_Accumulate_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size) +{ + HAL_StatusTypeDef status; + + /* Check the hash handle allocation */ + if ((hhash == NULL) || ((Size % 4U) != 0U)) + { + return HAL_ERROR; + } + + /* Check if peripheral is ready to start process */ + if (hhash->State == HAL_HASH_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hhash); + + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_BUSY; + + /* Reset HashInCount and Initialize Size and pHashInBuffPtr parameters */ + hhash->pHashInBuffPtr = pInBuffer; + hhash->HashInCount = 0U; + hhash->Size = Size; + /* Set multi buffers accumulation flag */ + hhash->Accumulation = 1U; + + if (hhash->Phase == HAL_HASH_PHASE_READY) + { + /* Set HASH mode */ + CLEAR_BIT(hhash->Instance->CR, HASH_CR_MODE); + /* Reset the HASH processor core */ + MODIFY_REG(hhash->Instance->CR, HASH_CR_INIT, HASH_CR_INIT); + /* Set the phase */ + hhash->Phase = HAL_HASH_PHASE_PROCESS; + } + /* Enable the specified HASH interrupt*/ + __HAL_HASH_ENABLE_IT(hhash, HASH_IT_DINI); + + status = HASH_WriteData_IT(hhash); + + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hhash); + } + else + { + status = HAL_BUSY; + } + /* Return function status */ + return status; +} + + +/** + * @brief End computation of a single HASH signature after several calls to HAL_HASH_Accumulate_IT() API. + * @note Digest is available in pOutBuffer + * @param hhash HASH handle. + * @param pInBuffer pointer to the input buffer (buffer to be hashed). + * @param Size length of the input buffer in bytes. + * @param pOutBuffer pointer to the computed digest. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HASH_AccumulateLast_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size, + uint8_t *const pOutBuffer) +{ + HAL_StatusTypeDef status; + + /* Check the hash handle allocation */ + if (hhash == NULL) + { + return HAL_ERROR; + } + + /* Check if peripheral is ready to start process */ + if (hhash->State == HAL_HASH_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hhash); + + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_BUSY; + + /* Reset HashInCount and Initialize Size, pHashInBuffPtr and pHashOutBuffPtr parameters */ + hhash->pHashInBuffPtr = pInBuffer; + hhash->pHashOutBuffPtr = pOutBuffer; + hhash->HashInCount = 0U; + hhash->Size = Size; + if (hhash->Phase == HAL_HASH_PHASE_READY) + { + /* Set HASH mode */ + CLEAR_BIT(hhash->Instance->CR, HASH_CR_MODE); + /* Reset the HASH processor core */ + MODIFY_REG(hhash->Instance->CR, HASH_CR_INIT, HASH_CR_INIT); + + /* Set the phase */ + hhash->Phase = HAL_HASH_PHASE_PROCESS; + } + /* Configure the number of valid bits in last word of the message */ + MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * (Size % 4U)); + + /* Enable the specified HASH interrupt*/ + __HAL_HASH_ENABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI); + + status = HASH_WriteData_IT(hhash); + + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_READY; + + /* Reset HASH state machine */ + hhash->Phase = HAL_HASH_PHASE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hhash); + } + else + { + status = HAL_BUSY; + } + /* Return function status */ + return status; +} + +/** + * @} + */ + + +/** @defgroup HASH_Exported_Functions_Group3 HMAC processing functions + * @brief HMAC processing functions using different mode. + * +@verbatim + =============================================================================== + ##### HMAC processing functions ##### + =============================================================================== + [..] This section provides API allowing to calculate the HMAC (keyed-hash + message authentication code) value using: + (+) one of the algorithms supported by the peripheral + (+) Key selection + (++) Long key : HMAC key is longer than the block size + (++) Short key : HMAC key is shorter or equal to the block size + + [..] To calculate the HMAC for a single buffer, user can resort to one of three processing + functions available . + (+) Polling mode : HAL_HASH_HMAC_Start() + (+) Interrupt mode : HAL_HASH_HMAC_Start_IT() + (+) DMA mode : HAL_HASH_HMAC_Start_DMA() + + [..] In case of multi-buffer HMAC processing (a single digest is computed while + several buffers are fed to the Peripheral), the user can resort to successive calls + to : + (+) Polling mode : HAL_HASH_HMAC_Accumulate() and wrap-up the digest computation by a call + to HAL_HASH_HMAC_AccumulateLast() + (+) Interrupt mode : HAL_HASH_HMAC_Accumulate_IT() and wrap-up the digest computation by a call + to HAL_HASH_HMAC_AccumulateLast_IT() + (+) DMA mode : HAL_HASH_HMAC_Start_DMA(),MDMAT bit must be set through __HAL_HASH_SET_MDMAT() macro, + before entering the last buffer, reset the MDMAT bit with __HAL_HASH_RESET_MDMAT() + macro then wrap-up the HMAC processing in feeding the last input buffer through the + same API HAL_HASH_HMAC_Start_DMA() + +@endverbatim + * @{ + */ + +/** + * @brief HMAC in polling mode, HASH peripheral processes Key then pInBuffer then reads the computed digest. + * @param hhash HASH handle. + * @param pInBuffer pointer to the input buffer (buffer to be hashed). + * @param Size length of the input buffer in bytes. + * @param pOutBuffer pointer to the computed digest. + * @param Timeout specify timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HASH_HMAC_Start(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size, + uint8_t *const pOutBuffer, uint32_t Timeout) +{ + uint32_t blocksize; /* Block size in bytes */ + + /* Check the hash handle allocation */ + if (hhash == NULL) + { + return HAL_ERROR; + } + + /* Check if peripheral is ready to start process */ + if (hhash->State == HAL_HASH_STATE_READY) + { + + /* Process Locked */ + __HAL_LOCK(hhash); + + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_BUSY; + + /* Reset HASH Phase */ + hhash->Phase = HAL_HASH_PHASE_READY; + + /* Reset HashInCount and Initialize Size, pHashKeyBuffPtr, pHashInBuffPtr and pHashOutBuffPtr parameters */ + hhash->pHashInBuffPtr = pInBuffer; + hhash->pHashOutBuffPtr = pOutBuffer; + hhash->pHashKeyBuffPtr = hhash->Init.pKey; + hhash->HashInCount = 0U; + hhash->Size = Size; + + /* Check if key size is larger than block size of the algorithm, accordingly set LKEY and the other setting bits */ + if ((hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA1) || + (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA224) || + (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA256)) + { + blocksize = BLOCK_64B; + } + else + { + blocksize = BLOCK_128B; + } + if (hhash->Init.KeySize > blocksize) + { + MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT, + HASH_ALGOMODE_HMAC | HASH_LONGKEY | HASH_CR_INIT); + } + else + { + + MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT, + HASH_ALGOMODE_HMAC | HASH_CR_INIT); + } + + /* Configure the number of valid bits in last word of the Key */ + MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Init.KeySize) % 4U)); + + + /* Set the phase */ + hhash->Phase = HAL_HASH_PHASE_PROCESS; + /* Write Key */ + HASH_WriteData(hhash, hhash->Init.pKey, hhash->Init.KeySize); + + /* Start the Key padding then the Digest calculation */ + SET_BIT(hhash->Instance->STR, HASH_STR_DCAL); + + /* Wait for BUSY flag to be cleared */ + if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, Timeout) != HAL_OK) + { + return HAL_ERROR; + } + + /* Configure the number of valid bits in last word of the message */ + MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * (Size % 4U)); + + /* Write message */ + HASH_WriteData(hhash, pInBuffer, Size); + + /* Start the message padding then the Digest calculation */ + SET_BIT(hhash->Instance->STR, HASH_STR_DCAL); + + /* Wait for BUSY flag to be cleared */ + if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, Timeout) != HAL_OK) + { + return HAL_ERROR; + } + /* Configure the number of valid bits in last word of the Key */ + MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Init.KeySize) % 4U)); + + /* Write Key */ + HASH_WriteData(hhash, hhash->Init.pKey, hhash->Init.KeySize); + + /* Start the Key padding then the Digest calculation */ + SET_BIT(hhash->Instance->STR, HASH_STR_DCAL); + + /* Wait for digest calculation completion status(DCIS) flag to be set */ + if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DCIS, RESET, Timeout) != HAL_OK) + { + return HAL_ERROR; + } + + /* Read the message digest */ + HASH_GetDigest(hhash, pOutBuffer, HASH_DIGEST_LENGTH(hhash)); + + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_READY; + + /* Change the HASH phase */ + hhash->Phase = HAL_HASH_PHASE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hhash); + + /* Return function status */ + return HAL_OK; + + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief HMAC accumulate mode, HASH peripheral processes Key then several input buffers. + * @note Consecutive calls to HAL_HASH_HMAC_Accumulate() can be used to feed + * several input buffers back-to-back to the Peripheral that will yield a single + * HASH signature once all buffers have been entered. Wrap-up of input + * buffers feeding and retrieval of digest is done by a call to + * HAL_HASH_HMAC_AccumulateLast() + * @param hhash HASH handle. + * @param pInBuffer pointer to the input buffer (buffer to be hashed). + * @param Size length of the input buffer in bytes and a multiple of 4 + * @param Timeout specify timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HASH_HMAC_Accumulate(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size, + uint32_t Timeout) +{ + uint32_t blocksize; /* Block size in bytes */ + + /* Check the hash handle allocation and buffer length multiple of 4 */ + if ((hhash == NULL) || ((Size % 4U) != 0U)) + { + return HAL_ERROR; + } + + /* Check if peripheral is ready to start process */ + if (hhash->State == HAL_HASH_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hhash); + + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_BUSY; + + /* Initialize Size, pHashInBuffPtr and pHashKeyBuffPtr parameters */ + hhash->pHashInBuffPtr = pInBuffer; + hhash->pHashKeyBuffPtr = hhash->Init.pKey; + hhash->Size = Size; + + if (hhash->Phase == HAL_HASH_PHASE_READY) + { + /* Reset HashInCount parameter */ + hhash->HashInCount = 0U; + /* Check if key size is larger than 64 bytes, accordingly set LKEY and the other setting bits */ + /* Check if key size is larger than block size of the algorithm, accordingly set LKEY and the other setting */ + if ((hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA1) || + (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA224) || + (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA256)) + { + blocksize = BLOCK_64B; + } + else + { + blocksize = BLOCK_128B; + } + if (hhash->Init.KeySize > blocksize) + { + MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT, + HASH_ALGOMODE_HMAC | HASH_LONGKEY | HASH_CR_INIT); + } + else + { + + MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT, + HASH_ALGOMODE_HMAC | HASH_CR_INIT); + } + /* Set phase process */ + hhash->Phase = HAL_HASH_PHASE_PROCESS; + + /* Configure the number of valid bits in last word of the Key */ + MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Init.KeySize) % 4U)); + + /* Write Key */ + HASH_WriteData(hhash, hhash->Init.pKey, hhash->Init.KeySize); + + /* Start the Key padding then the Digest calculation */ + SET_BIT(hhash->Instance->STR, HASH_STR_DCAL); + + /* Wait for BUSY flag to be cleared */ + if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, Timeout) != HAL_OK) + { + return HAL_ERROR; + } + } + + /* Change the number of valid bits in last word of the message */ + MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 0U); + + /* Write message */ + HASH_WriteData(hhash, pInBuffer, Size); + + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hhash); + + /* Return function status */ + return HAL_OK; + + } + else + { + return HAL_BUSY; + } +} +/** + * @brief End computation of a single HMAC signature after several calls to HAL_HASH_HMAC_Accumulate() API. + * @note Digest is available in pOutBuffer + * @param hhash HASH handle. + * @param pInBuffer pointer to the input buffer (buffer to be hashed). + * @param Size length of the input buffer in bytes. + * @param pOutBuffer pointer to the computed digest. + * @param Timeout specify timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HASH_HMAC_AccumulateLast(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size, + uint8_t *const pOutBuffer, uint32_t Timeout) +{ + /* Check the hash handle allocation */ + if (hhash == NULL) + { + return HAL_ERROR; + } + + /* Check if peripheral is ready to start process */ + if (hhash->State == HAL_HASH_STATE_READY) + { + + /* Process Locked */ + __HAL_LOCK(hhash); + + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_BUSY; + + /* Initialize Size, pHashInBuffPtr, pHashKeyBuffPtr and pHashOutBuffPtr parameters */ + hhash->pHashInBuffPtr = pInBuffer; + hhash->pHashOutBuffPtr = pOutBuffer; + hhash->pHashKeyBuffPtr = hhash->Init.pKey; + hhash->Size = Size; + + if (hhash->Phase != HAL_HASH_PHASE_PROCESS) + { + return HAL_ERROR; + } + else + { + /* Configure the number of valid bits in last word of the message */ + MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * (Size % 4U)); + + /* Write message */ + HASH_WriteData(hhash, pInBuffer, Size); + + /* Start the message padding then the Digest calculation */ + SET_BIT(hhash->Instance->STR, HASH_STR_DCAL); + + /* Wait for BUSY flag to be cleared */ + if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, Timeout) != HAL_OK) + { + return HAL_ERROR; + } + /* Configure the number of valid bits in last word of the Key */ + MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Init.KeySize) % 4U)); + + /* Write Key */ + HASH_WriteData(hhash, hhash->Init.pKey, hhash->Init.KeySize); + + /* Start the Key padding then the Digest calculation */ + SET_BIT(hhash->Instance->STR, HASH_STR_DCAL); + + /* Wait for digest calculation completion status(DCIS) flag to be set */ + if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DCIS, RESET, Timeout) != HAL_OK) + { + return HAL_ERROR; + } + + /* Read the message digest */ + HASH_GetDigest(hhash, pOutBuffer, HASH_DIGEST_LENGTH(hhash)); + } + + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_READY; + + /* Reset HASH state machine */ + hhash->Phase = HAL_HASH_PHASE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hhash); + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief HMAC in interrupt mode, HASH peripheral process Key then pInBuffer then read the computed digest. + * @param hhash HASH handle. + * @param pInBuffer pointer to the input buffer (buffer to be hashed). + * @param Size length of the input buffer in bytes. + * @param pOutBuffer pointer to the computed digest. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HASH_HMAC_Start_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size, + uint8_t *const pOutBuffer) +{ + HAL_StatusTypeDef status; + uint32_t blocksize; /* Block size in bytes */ + + /* Check the hash handle allocation */ + if (hhash == NULL) + { + return HAL_ERROR; + } + + /* Check if peripheral is ready to start process */ + if (hhash->State == HAL_HASH_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hhash); + + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_BUSY; + + /* Reset HASH Phase */ + hhash->Phase = HAL_HASH_PHASE_READY; + + /* Reset HashInCount and Initialize Size, pHashKeyBuffPtr, pHashInBuffPtr and pHashOutBuffPtr parameters */ + hhash->pHashInBuffPtr = pInBuffer; + hhash->pHashOutBuffPtr = pOutBuffer; + hhash->pHashKeyBuffPtr = hhash->Init.pKey; + hhash->HashInCount = 0U; + hhash->Size = Size; + + /* Check if key size is larger than block size of the algorithm, accordingly set LKEY and the other setting bits */ + if ((hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA1) || + (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA224) || + (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA256)) + { + blocksize = BLOCK_64B; + } + else + { + blocksize = BLOCK_128B; + } + if (hhash->Init.KeySize > blocksize) + { + MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT, + HASH_ALGOMODE_HMAC | HASH_LONGKEY | HASH_CR_INIT); + } + else + { + + MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT, + HASH_ALGOMODE_HMAC | HASH_CR_INIT); + } + + /* Configure the number of valid bits in last word of the Key */ + MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Init.KeySize) % 4U)); + + /* Set the phase */ + hhash->Phase = HAL_HASH_PHASE_PROCESS; + } + else if (hhash->State == HAL_HASH_STATE_SUSPENDED) + { + /* Process Locked */ + __HAL_LOCK(hhash); + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_BUSY; + } + else + { + return HAL_BUSY; + } + + /* Enable the specified HASH interrupt*/ + __HAL_HASH_ENABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI); + + status = HASH_WriteData_IT(hhash); + + /* Return function status */ + return status; +} + +/** + * @brief HMAC accumulate in interrupt mode, HASH peripheral processes Key then several input buffers. + * @note Consecutive calls to HAL_HASH_HMAC_Accumulate_IT() can be used to feed + * several input buffers back-to-back to the Peripheral that will yield a single + * HASH signature once all buffers have been entered. Wrap-up of input + * buffers feeding and retrieval of digest is done by a call to + * HAL_HASH_HMAC_AccumulateLast_IT() + * @param hhash HASH handle. + * @param pInBuffer pointer to the input buffer (buffer to be hashed). + * @param Size length of the input buffer in bytes and a multiple of 4. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HASH_HMAC_Accumulate_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size) +{ + HAL_StatusTypeDef status; + uint32_t blocksize; /* Block size in bytes */ + + /* Check the hash handle allocation and buffer length multiple of 4 */ + if ((hhash == NULL) || ((Size % 4U) != 0U)) + { + return HAL_ERROR; + } + + /* Check if peripheral is ready to start process */ + if (hhash->State == HAL_HASH_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hhash); + + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_BUSY; + + /* Reset HashInCount and Initialize Size, pHashInBuffPtr and pHashOutBuffPtr parameters */ + hhash->pHashInBuffPtr = pInBuffer; + hhash->pHashKeyBuffPtr = hhash->Init.pKey; + hhash->HashInCount = 0U; + hhash->Size = Size; + /* Set multi buffers accumulation flag */ + hhash->Accumulation = 1U; + + if (hhash->Phase == HAL_HASH_PHASE_READY) + { + /* Check if key size is larger than block size of the algorithm, accordingly set LKEY and the other setting */ + if ((hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA1) || + (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA224) || + (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA256)) + { + blocksize = BLOCK_64B; + } + else + { + blocksize = BLOCK_128B; + } + if (hhash->Init.KeySize > blocksize) + { + MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT, + HASH_ALGOMODE_HMAC | HASH_LONGKEY | HASH_CR_INIT); + } + else + { + + MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT, + HASH_ALGOMODE_HMAC | HASH_CR_INIT); + } + + /* Configure the number of valid bits in last word of the Key */ + MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Init.KeySize) % 4U)); + + /* Set the phase */ + hhash->Phase = HAL_HASH_PHASE_PROCESS; + } + /* Enable the specified HASH interrupt*/ + __HAL_HASH_ENABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI); + + status = HASH_WriteData_IT(hhash); + } + else + { + status = HAL_BUSY; + } + /* Return function status */ + return status; +} +/** + * @brief End computation of a single HMAC signature in interrupt mode, after + * several calls to HAL_HASH_HMAC_Accumulate() API. + * @note Digest is available in pOutBuffer + * @param hhash HASH handle. + * @param pInBuffer pointer to the input buffer (buffer to be hashed). + * @param Size length of the input buffer in bytes. + * @param pOutBuffer pointer to the computed digest. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HASH_HMAC_AccumulateLast_IT(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, + uint32_t Size, uint8_t *const pOutBuffer) +{ + HAL_StatusTypeDef status; + + /* Check the hash handle allocation */ + if (hhash == NULL) + { + return HAL_ERROR; + } + + /* Check if peripheral is ready to start process*/ + if (hhash->State == HAL_HASH_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hhash); + + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_BUSY; + + /* Reset HashInCount and Initialize Size, pHashInBuffPtr and pHashOutBuffPtr parameters */ + hhash->pHashInBuffPtr = pInBuffer; + hhash->pHashOutBuffPtr = pOutBuffer; + hhash->pHashKeyBuffPtr = hhash->Init.pKey; + hhash->HashInCount = 0U; + hhash->Size = Size; + /* Set multi buffers accumulation flag */ + hhash->Accumulation = 0U; + /* Enable the specified HASH interrupt*/ + __HAL_HASH_ENABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI); + + status = HASH_WriteData_IT(hhash); + } + else + { + status = HAL_BUSY; + } + /* Return function status */ + return status; +} + +/** + * @brief HMAC in DMA mode,HASH peripheral processes Key then pInBuffer in DMA mode + * then read the computed digest. + * @note Multi-buffer HMAC processing is possible, consecutive calls to HAL_HASH_HMAC_Start_DMA + * (MDMAT bit must be set) can be used to feed several input buffers + * back-to-back to the Peripheral that will yield a single + * HASH signature once all buffers have been entered. Wrap-up of input + * buffers feeding and retrieval of digest is done by a call to + * HAL_HASH_HMAC_Start_DMA (MDMAT bit must be reset). + * @param hhash HASH handle. + * @param pInBuffer pointer to the input buffer (buffer to be hashed). + * @param Size length of the input buffer in bytes. + * @param pOutBuffer pointer to the computed digest. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HASH_HMAC_Start_DMA(HASH_HandleTypeDef *hhash, const uint8_t *const pInBuffer, uint32_t Size, + uint8_t *const pOutBuffer) +{ + HAL_StatusTypeDef status; + uint32_t count; + uint32_t blocksize; /* Block size in bytes */ + + /* Check the hash handle allocation */ + if (hhash == NULL) + { + return HAL_ERROR; + } + + /* Check if peripheral is ready to start process*/ + if (hhash->State == HAL_HASH_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hhash); + + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_BUSY; + + /* Reset HashInCount and Initialize Size, pHashInBuffPtr and pHashOutBuffPtr parameters */ + hhash->pHashInBuffPtr = pInBuffer; + hhash->pHashOutBuffPtr = pOutBuffer; + hhash->pHashKeyBuffPtr = hhash->Init.pKey; + hhash->HashInCount = 0U; + hhash->Size = Size; + + /* Set the phase */ + if (hhash->Phase == HAL_HASH_PHASE_READY) + { + /* Check if key size is larger than block size of the algorithm, accordingly set LKEY and the other setting */ + if ((hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA1) || + (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA224) || + (hhash->Init.Algorithm == HASH_ALGOSELECTION_SHA256)) + { + blocksize = BLOCK_64B; + } + else + { + blocksize = BLOCK_128B; + } + if (hhash->Init.KeySize > blocksize) + { + MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT, + HASH_ALGOMODE_HMAC | HASH_LONGKEY | HASH_CR_INIT); + } + else + { + + MODIFY_REG(hhash->Instance->CR, HASH_CR_LKEY | HASH_CR_MODE | HASH_CR_INIT, + HASH_ALGOMODE_HMAC | HASH_CR_INIT); + } + + /* Set the phase */ + hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_1; + + /* Configure the number of valid bits in last word of the Key */ + MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Init.KeySize) % 4U)); + + /* Write Key */ + HASH_WriteData(hhash, hhash->Init.pKey, hhash->Init.KeySize); + + /* Start the Key padding then the Digest calculation */ + SET_BIT(hhash->Instance->STR, HASH_STR_DCAL); + + /* Wait for DCIS flag to be set */ + count = HASH_TIMEOUTVALUE; + do + { + count--; + if (count == 0U) + { + /* Change state */ + hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT; + hhash->State = HAL_HASH_STATE_READY; + __HAL_UNLOCK(hhash); + return HAL_ERROR; + } + } while (HAL_IS_BIT_CLR(hhash->Instance->SR, HASH_FLAG_BUSY)); + } + + hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_2; + if ((hhash->Instance->CR & HASH_CR_MDMAT) == 0U) + { + /* Configure the number of valid bits in last word of the message */ + MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Size) % 4U)); + } + else + { + /* Configure the number of valid bits in last word of the message */ + MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 0U); + } + } + else if (hhash->State == HAL_HASH_STATE_SUSPENDED) + { + /* Process Locked */ + __HAL_LOCK(hhash); + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_BUSY; + + /*only part not yet hashed to compute */ + hhash->Size = hhash->HashInCount; + } + + else + { + /* Return busy status */ + return HAL_BUSY; + } + + /* Set the HASH DMA transfer complete callback */ + hhash->hdmain->XferCpltCallback = HASH_DMAXferCplt; + /* Set the DMA error callback */ + hhash->hdmain->XferErrorCallback = HASH_DMAError; + + if ((hhash->hdmain->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hhash->hdmain->LinkedListQueue != NULL) && (hhash->hdmain->LinkedListQueue->Head != NULL)) + { + /* Enable the DMA channel */ + hhash->hdmain->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET]\ + = ((((hhash->Size) % 4U) != 0U) ? ((hhash->Size) + (4U - ((hhash->Size) % 4U))) : ((hhash->Size))); + hhash->hdmain->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET]\ + = (uint32_t)(hhash->pHashInBuffPtr); /* Set DMA source address */ + hhash->hdmain->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET]\ + = (uint32_t)&hhash->Instance->DIN; /* Set DMA destination address */ + + status = HAL_DMAEx_List_Start_IT(hhash->hdmain); + } + else + { + /* Return error status */ + status = HAL_ERROR; + } + } + else + { + status = HAL_DMA_Start_IT(hhash->hdmain, (uint32_t)(hhash->pHashInBuffPtr), (uint32_t)&hhash->Instance->DIN, \ + ((((hhash->Size) % 4U) != 0U) ? ((hhash->Size) + (4U - ((hhash->Size) % 4U))) : \ + ((hhash->Size)))); + } + if (status != HAL_OK) + { + /* DMA error code field */ + hhash->ErrorCode |= HAL_HASH_ERROR_DMA; + + /* Return error */ +#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1U) + /*Call registered error callback*/ + hhash->ErrorCallback(hhash); +#else + /*Call legacy weak error callback*/ + HAL_HASH_ErrorCallback(hhash); +#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */ + } + else + { + /* Enable DMA requests */ + SET_BIT(hhash->Instance->CR, HASH_CR_DMAE); + } + + /* Return function status */ + return status; +} + + +/** + * @} + */ + +/** @defgroup HASH_Exported_Functions_Group4 HASH IRQ handler management + * @brief HASH IRQ handler. + * +@verbatim + ============================================================================== + ##### HASH IRQ handler management ##### + ============================================================================== +[..] This section provides HASH IRQ handler and callback functions. + (+) HAL_HASH_IRQHandler HASH interrupt request + (+) HAL_HASH_InCpltCallback input data transfer complete callback + (+) HAL_HASH_DgstCpltCallback digest computation complete callback + (+) HAL_HASH_ErrorCallback HASH error callback + (+) HAL_HASH_GetState return the HASH state + (+) HAL_HASH_GetError return the HASH error code +@endverbatim + * @{ + */ + +/** + * @brief Handle HASH interrupt request. + * @param hhash HASH handle. + * @note HAL_HASH_IRQHandler() handles interrupts in HMAC processing as well. + * @retval None + */ +void HAL_HASH_IRQHandler(HASH_HandleTypeDef *hhash) +{ + HAL_StatusTypeDef status; + uint32_t itsource = hhash->Instance->IMR; + uint32_t itflag = hhash->Instance->SR; + + /* If digest is ready */ + if ((itflag & HASH_FLAG_DCIS) == HASH_FLAG_DCIS) + { + /* Read the digest */ + HASH_GetDigest(hhash, hhash->pHashOutBuffPtr, HASH_DIGEST_LENGTH(hhash)); + + /* Disable Interrupts */ + __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI); + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_READY; + /* Reset HASH state machine */ + hhash->Phase = HAL_HASH_PHASE_READY; + /* Process Unlocked */ + __HAL_UNLOCK(hhash); + /* Call digest computation complete call back */ +#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1) + hhash->DgstCpltCallback(hhash); +#else + HAL_HASH_DgstCpltCallback(hhash); +#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */ + + } + /* If Peripheral ready to accept new data */ + if ((itflag & HASH_FLAG_DINIS) == HASH_FLAG_DINIS) + { + if ((itsource & HASH_IT_DINI) == HASH_IT_DINI) + { + status = HASH_WriteData_IT(hhash); + if (status != HAL_OK) + { + /* Call error callback */ +#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1) + hhash->ErrorCallback(hhash); +#else + HAL_HASH_ErrorCallback(hhash); +#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */ + } + } + } +} + +/** + * @brief Input data transfer complete call back. + * @note HAL_HASH_InCpltCallback() is called when the complete input message + * has been fed to the Peripheral. This API is invoked only when input data are + * entered under interruption or through DMA. + * @note In case of HASH or HMAC multi-buffer DMA feeding case (MDMAT bit set), + * HAL_HASH_InCpltCallback() is called at the end of each buffer feeding + * to the Peripheral. + * @param hhash pointer to a HASH_HandleTypeDef structure that contains + * the configuration information for HASH module. + * @retval None + */ +__weak void HAL_HASH_InCpltCallback(HASH_HandleTypeDef *hhash) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhash); + + /* NOTE : This function should not be modified; when the callback is needed, + HAL_HASH_InCpltCallback() can be implemented in the user file. + */ +} + +/** + * @brief Digest computation complete call back. + * @note HAL_HASH_DgstCpltCallback() is used under interruption, is not + * relevant with DMA. + * @param hhash pointer to a HASH_HandleTypeDef structure that contains + * the configuration information for HASH module. + * @retval None + */ +__weak void HAL_HASH_DgstCpltCallback(HASH_HandleTypeDef *hhash) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhash); + + /* NOTE : This function should not be modified; when the callback is needed, + HAL_HASH_DgstCpltCallback() can be implemented in the user file. + */ +} + +/** + * @brief HASH error callback. + * @note Code user can resort to hhash->Status (HAL_ERROR, HAL_TIMEOUT,...) + * to retrieve the error type. + * @param hhash pointer to a HASH_HandleTypeDef structure that contains + * the configuration information for HASH module. + * @retval None + */ +__weak void HAL_HASH_ErrorCallback(HASH_HandleTypeDef *hhash) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhash); + + /* NOTE : This function should not be modified; when the callback is needed, + HAL_HASH_ErrorCallback() can be implemented in the user file. + */ +} + +/** + * @brief Return the HASH handle state. + * @note The API yields the current state of the handle (BUSY, READY,...). + * @param hhash HASH handle. + * @retval HAL HASH state + */ +HAL_HASH_StateTypeDef HAL_HASH_GetState(const HASH_HandleTypeDef *hhash) +{ + return hhash->State; +} + +/** + * @brief Return the HASH handle error code. + * @param hhash pointer to a HASH_HandleTypeDef structure. + * @retval HASH Error Code + */ +uint32_t HAL_HASH_GetError(const HASH_HandleTypeDef *hhash) +{ + /* Return HASH Error Code */ + return hhash->ErrorCode; +} +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @addtogroup HASH_Private_Functions + * @{ + */ + +/** + * @brief DMA HASH Input Data transfer completion callback. + * @param hdma DMA handle. + * @retval None + */ +static void HASH_DMAXferCplt(DMA_HandleTypeDef *hdma) +{ + HASH_HandleTypeDef *hhash = (HASH_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + uint32_t count; + + if (READ_BIT(hhash->Instance->CR, HASH_CR_MODE) == 0U) + { + if ((hhash->Instance->CR & HASH_CR_MDMAT) == 0U) + { + /* Disable the DMA transfer */ + CLEAR_BIT(hhash->Instance->CR, HASH_CR_DMAE); + + + /* Wait for DCIS flag to be set */ + count = HASH_TIMEOUTVALUE; + do + { + count--; + if (count == 0U) + { + /* Change state */ + hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT; + hhash->State = HAL_HASH_STATE_READY; + __HAL_UNLOCK(hhash); +#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1) + hhash->ErrorCallback(hhash); +#else + HAL_HASH_ErrorCallback(hhash); +#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */ + } + } while (HAL_IS_BIT_CLR(hhash->Instance->SR, HASH_FLAG_DCIS)); + /* Call Input data transfer complete call back */ +#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1) + hhash->InCpltCallback(hhash); +#else + HAL_HASH_InCpltCallback(hhash); +#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */ + + /* Read the message digest */ + HASH_GetDigest(hhash, hhash->pHashOutBuffPtr, HASH_DIGEST_LENGTH(hhash)); + + /* Change the HASH state to ready */ + hhash->State = HAL_HASH_STATE_READY; + + /* Reset HASH state machine */ + hhash->Phase = HAL_HASH_PHASE_READY; + + /* Process UnLock */ + __HAL_UNLOCK(hhash); + + /* Call digest complete call back */ +#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1) + hhash->DgstCpltCallback(hhash); +#else + HAL_HASH_DgstCpltCallback(hhash); +#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */ + } + else + { + hhash->State = HAL_HASH_STATE_READY; + __HAL_UNLOCK(hhash); + } + } + else /*HMAC DMA*/ + { + if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2) + { + if ((hhash->Instance->CR & HASH_CR_MDMAT) == 0U) + { + /* Set the phase */ + hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_3; + /* Configure the number of valid bits in last word of the Key */ + MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Init.KeySize) % 4U)); + /* Write Key */ + HASH_WriteData(hhash, hhash->Init.pKey, hhash->Init.KeySize); + + /* Start the Key padding then the Digest calculation */ + SET_BIT(hhash->Instance->STR, HASH_STR_DCAL); + + /* Wait for DCIS flag to be set */ + count = HASH_TIMEOUTVALUE; + do + { + count--; + if (count == 0U) + { + /* Disable the DMA transfer */ + CLEAR_BIT(hhash->Instance->CR, HASH_CR_DMAE); + + /* Change state */ + hhash->ErrorCode |= HAL_HASH_ERROR_DMA; + hhash->State = HAL_HASH_STATE_READY; + __HAL_UNLOCK(hhash); +#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1) + hhash->ErrorCallback(hhash); +#else + HAL_HASH_ErrorCallback(hhash); +#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */ + } + } while (HAL_IS_BIT_CLR(hhash->Instance->SR, HASH_FLAG_DCIS)); + + /* Read the message digest */ + HASH_GetDigest(hhash, hhash->pHashOutBuffPtr, HASH_DIGEST_LENGTH(hhash)); + + /* Change the HASH state to ready */ + hhash->State = HAL_HASH_STATE_READY; + + /* Reset HASH state machine */ + hhash->Phase = HAL_HASH_PHASE_READY; + + /* Process UnLock */ + __HAL_UNLOCK(hhash); + + /* Call digest complete call back */ +#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1) + hhash->DgstCpltCallback(hhash); +#else + HAL_HASH_DgstCpltCallback(hhash); +#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */ + + } + else + { + hhash->State = HAL_HASH_STATE_READY; + __HAL_UNLOCK(hhash); + hhash->Accumulation = 1; + } + } + } +} + +/** + * @brief DMA HASH communication error callback. + * @param hdma DMA handle. + * @retval None + */ +static void HASH_DMAError(DMA_HandleTypeDef *hdma) +{ + HASH_HandleTypeDef *hhash = (HASH_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + hhash->ErrorCode |= HAL_HASH_ERROR_DMA; + /* Set HASH state to ready to prevent any blocking issue in user code + present in HAL_HASH_ErrorCallback() */ + hhash->State = HAL_HASH_STATE_READY; + +#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1) + hhash->ErrorCallback(hhash); +#else + HAL_HASH_ErrorCallback(hhash); +#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */ +} + +/** + * @brief Feed the input buffer to the HASH peripheral in polling. + * @param hhash HASH handle. + * @param pInBuffer pointer to input buffer. + * @param Size the size of input buffer in bytes. + * @retval HAL status + */ +static void HASH_WriteData(HASH_HandleTypeDef *hhash, const uint8_t *pInBuffer, uint32_t Size) +{ + uint32_t buffercounter; + __IO uint32_t inputaddr = (uint32_t) pInBuffer; + + + for (buffercounter = 0U; buffercounter < Size ; buffercounter += 4U) + { + /* Write input data 4 bytes at a time */ + hhash->Instance->DIN = *(uint32_t *)inputaddr; + inputaddr += 4U; + hhash->HashInCount += 4U; + } +} + +/** + * @brief Feed the input buffer to the HASH peripheral in interruption mode. + * @param hhash HASH handle. + * @retval HAL status + */ +static HAL_StatusTypeDef HASH_WriteData_IT(HASH_HandleTypeDef *hhash) +{ + uint32_t buffercounter; + uint32_t count; + __IO uint32_t keyaddr = (uint32_t)(hhash->pHashKeyBuffPtr); + __IO uint32_t inputaddr = (uint32_t)(hhash->pHashInBuffPtr); + uint32_t nbbytePartialHash = (((hhash->Instance->SR) >> 16U) * 4U); /* Nb byte to enter in HASH fifo to trig + a partial HASH computation*/ + + if (hhash->State == HAL_HASH_STATE_BUSY) + { + if ((hhash->Instance->CR & HASH_CR_MODE) == 0U) + { +#if (USE_HAL_HASH_SUSPEND_RESUME == 1U) + /* If suspension flag has been raised, suspend processing */ + if (hhash->SuspendRequest == HAL_HASH_SUSPEND) + { + /* reset SuspendRequest */ + hhash->SuspendRequest = HAL_HASH_SUSPEND_NONE; + /* Disable Computation Complete Flag and Errors Interrupts */ + __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI); + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_SUSPENDED; + __HAL_UNLOCK(hhash); + } + else + { +#endif /* USE_HAL_HASH_SUSPEND_RESUME */ + + if (((hhash->HashInCount) + nbbytePartialHash) < (hhash->Size)) + { + for (buffercounter = 0U; buffercounter < nbbytePartialHash ; buffercounter += 4U) + { + /* Write input data 4 bytes at a time */ + hhash->Instance->DIN = *(uint32_t *)inputaddr; + inputaddr += 4U; + hhash->HashInCount += 4U; + hhash->pHashInBuffPtr += 4U; + } + /* Wait for HASH_IT_DINI flag to be set */ + count = HASH_TIMEOUTVALUE; + do + { + count--; + if (count == 0U) + { + /* Disable Interrupts */ + __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI); + + /* Change state */ + hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT; + hhash->State = HAL_HASH_STATE_READY; + __HAL_UNLOCK(hhash); + return HAL_ERROR; + } + } while (HAL_IS_BIT_CLR(hhash->Instance->SR, HASH_FLAG_DINIS)); + } + else + { + while ((hhash->HashInCount) < hhash->Size) + { + /* Write input data 4 bytes at a time */ + hhash->Instance->DIN = *(uint32_t *)inputaddr; + inputaddr += 4U; + hhash->HashInCount += 4U; + hhash->pHashInBuffPtr += 4U; + } + /* Call Input transfer complete callback */ +#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1U) + /*Call registered Input complete callback*/ + hhash->InCpltCallback(hhash); +#else + /*Call legacy weak Input complete callback*/ + HAL_HASH_InCpltCallback(hhash); +#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */ + if (hhash->Accumulation == 0U) + { + if (__HAL_HASH_GET_IT_SOURCE(hhash, HASH_IT_DINI)) + { + /* Start the message padding then the Digest calculation */ + SET_BIT(hhash->Instance->STR, HASH_STR_DCAL); + + /* Wait for HASH_FLAG_DCIS flag to be set */ + count = HASH_TIMEOUTVALUE; + do + { + count--; + if (count == 0U) + { + /* Disable Interrupts */ + __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI); + + /* Change state */ + hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT; + hhash->State = HAL_HASH_STATE_READY; + __HAL_UNLOCK(hhash); + return HAL_ERROR; + } + } while (HAL_IS_BIT_CLR(hhash->Instance->SR, HASH_FLAG_DCIS)); + } + } + else + { + /* Reset multi buffers accumulation flag */ + hhash->Accumulation = 0U; + /* Disable Interrupts */ + __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI); + } + } +#if (USE_HAL_HASH_SUSPEND_RESUME == 1U) + } +#endif /* USE_HAL_HASH_SUSPEND_RESUME */ + } + else /*HMAC */ + { + if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2) /* loading input*/ + { +#if (USE_HAL_HASH_SUSPEND_RESUME == 1U) + /* If suspension flag has been raised, suspend processing */ + if (hhash->SuspendRequest == HAL_HASH_SUSPEND) + { + /* reset SuspendRequest */ + hhash->SuspendRequest = HAL_HASH_SUSPEND_NONE; + /* Disable Computation Complete Flag and Errors Interrupts */ + __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI); + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_SUSPENDED; + __HAL_UNLOCK(hhash); + } + else + { +#endif /* USE_HAL_HASH_SUSPEND_RESUME */ + if (hhash->Accumulation == 1U) + { + /* Configure the number of valid bits in last word of the message */ + MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 0U); + } + else + { + /* Configure the number of valid bits in last word of the message */ + MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * (hhash->Size % 4U)); + } + if (((hhash->HashInCount) + nbbytePartialHash) < (hhash->Size)) + { + for (buffercounter = 0U; buffercounter < nbbytePartialHash ; buffercounter += 4U) + { + /* Write input data 4 bytes at a time */ + hhash->Instance->DIN = *(uint32_t *)inputaddr; + inputaddr += 4U; + hhash->HashInCount += 4U; + hhash->pHashInBuffPtr += 4U; + } + /* Wait for HASH_IT_DINI flag to be set */ + count = HASH_TIMEOUTVALUE; + do + { + count--; + if (count == 0U) + { + /* Disable Interrupts */ + __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI); + + /* Change state */ + hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT; + hhash->State = HAL_HASH_STATE_READY; + __HAL_UNLOCK(hhash); + return HAL_ERROR; + } + } while (HAL_IS_BIT_CLR(hhash->Instance->SR, HASH_FLAG_DINIS)); + } + else + { + while ((hhash->HashInCount) < hhash->Size) + { + /* Write input data 4 bytes at a time */ + hhash->Instance->DIN = *(uint32_t *)inputaddr; + inputaddr += 4U; + hhash->HashInCount += 4U; + hhash->pHashInBuffPtr += 4U; + } + /* Call Input transfer complete callback */ +#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1U) + /*Call registered Input complete callback*/ + hhash->InCpltCallback(hhash); +#else + /*Call legacy weak Input complete callback*/ + HAL_HASH_InCpltCallback(hhash); +#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */ + + if (hhash->Accumulation == 0U) + { + if (__HAL_HASH_GET_IT_SOURCE(hhash, HASH_IT_DINI)) + { + /* Start the message padding then the Digest calculation */ + SET_BIT(hhash->Instance->STR, HASH_STR_DCAL); + + /* Wait for HASH_FLAG_BUSY flag to be set */ + count = HASH_TIMEOUTVALUE; + do + { + count--; + if (count == 0U) + { + /* Disable Interrupts */ + __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI); + + /* Change state */ + hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT; + hhash->State = HAL_HASH_STATE_READY; + __HAL_UNLOCK(hhash); + return HAL_ERROR; + } + } while (HAL_IS_BIT_SET(hhash->Instance->SR, HASH_FLAG_BUSY)); + + hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_3; + hhash->HashInCount = 0U; + hhash->pHashKeyBuffPtr = hhash->Init.pKey; + } + } + + else + { + /* Disable Interrupts */ + __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI); + hhash->State = HAL_HASH_STATE_READY; + __HAL_UNLOCK(hhash); + return HAL_OK; + } + } +#if (USE_HAL_HASH_SUSPEND_RESUME == 1U) + } +#endif /* USE_HAL_HASH_SUSPEND_RESUME */ + } + + else if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_3)/* loading Key*/ + { + + /* Configure the number of valid bits in last word of the Key */ + MODIFY_REG(hhash->Instance->STR, HASH_STR_NBLW, 8U * ((hhash->Init.KeySize) % 4U)); + + if (((hhash->HashInCount) + nbbytePartialHash) < (hhash->Init.KeySize)) + { + for (buffercounter = 0U; buffercounter < nbbytePartialHash ; buffercounter += 4U) + { + /* Write input data 4 bytes at a time */ + hhash->Instance->DIN = *(uint32_t *)keyaddr; + keyaddr += 4U; + hhash->HashInCount += 4U; + hhash->pHashKeyBuffPtr += 4U; + } + /* Wait for HASH_IT_DINI flag to be set */ + count = HASH_TIMEOUTVALUE; + do + { + count--; + if (count == 0U) + { + /* Disable Interrupts */ + __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI); + + /* Change state */ + hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT; + hhash->State = HAL_HASH_STATE_READY; + __HAL_UNLOCK(hhash); + return HAL_ERROR; + } + } while (HAL_IS_BIT_CLR(hhash->Instance->SR, HASH_FLAG_DINIS)); + } + else + { + while ((hhash->HashInCount) < (hhash->Init.KeySize)) + { + /* Write input data 4 bytes at a time */ + hhash->Instance->DIN = *(uint32_t *)keyaddr; + keyaddr += 4U; + hhash->HashInCount += 4U; + } + /* Start the message padding then the Digest calculation */ + SET_BIT(hhash->Instance->STR, HASH_STR_DCAL); + + /* Wait for HASH_FLAG_DCIS flag to be set */ + count = HASH_TIMEOUTVALUE; + do + { + count--; + if (count == 0U) + { + /* Disable Interrupts */ + __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI); + + /* Change state */ + hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT; + hhash->State = HAL_HASH_STATE_READY; + __HAL_UNLOCK(hhash); + return HAL_ERROR; + } + } while (HAL_IS_BIT_CLR(hhash->Instance->SR, HASH_FLAG_DCIS)); + } + } + else /*first step , loading key*/ + { + + hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_1; + + if (((hhash->HashInCount) + nbbytePartialHash) < (hhash->Init.KeySize)) + { + for (buffercounter = 0U; buffercounter < nbbytePartialHash ; buffercounter += 4U) + { + /* Write input data 4 bytes at a time */ + hhash->Instance->DIN = *(uint32_t *)keyaddr; + keyaddr += 4U; + hhash->HashInCount += 4U; + hhash->pHashKeyBuffPtr += 4U; + } + /* Wait for HASH_IT_DINI flag to be set */ + count = HASH_TIMEOUTVALUE; + do + { + count--; + if (count == 0U) + { + /* Disable Interrupts */ + __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI); + + /* Change state */ + hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT; + hhash->State = HAL_HASH_STATE_READY; + __HAL_UNLOCK(hhash); + return HAL_ERROR; + } + } while (HAL_IS_BIT_CLR(hhash->Instance->SR, HASH_FLAG_DINIS)); + } + else + { + while ((hhash->HashInCount) < (hhash->Init.KeySize)) + { + /* Write input data 4 bytes at a time */ + hhash->Instance->DIN = *(uint32_t *)keyaddr; + keyaddr += 4U; + hhash->HashInCount += 4U; + hhash->pHashKeyBuffPtr += 4U; + } + /* Start the message padding then the Digest calculation */ + SET_BIT(hhash->Instance->STR, HASH_STR_DCAL); + + /* Wait for HASH_FLAG_BUSY flag to be set */ + count = HASH_TIMEOUTVALUE; + do + { + count--; + if (count == 0U) + { + /* Disable Interrupts */ + __HAL_HASH_DISABLE_IT(hhash, HASH_IT_DINI | HASH_IT_DCI); + + /* Change state */ + hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT; + hhash->State = HAL_HASH_STATE_READY; + __HAL_UNLOCK(hhash); + return HAL_ERROR; + } + } while (HAL_IS_BIT_SET(hhash->Instance->SR, HASH_FLAG_BUSY)); + /*change Phase to step 2*/ + hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_2; + hhash->HashInCount = 0U; + } + } + } + } + else if ((hhash->State == HAL_HASH_STATE_SUSPENDED)) + { + return HAL_OK; + } + else + { + /* Busy error code field */ + hhash->ErrorCode |= HAL_HASH_ERROR_BUSY; +#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1U) + /*Call registered error callback*/ + hhash->ErrorCallback(hhash); +#else + /*Call legacy weak error callback*/ + HAL_HASH_ErrorCallback(hhash); +#endif /* USE_HAL_HASH_REGISTER_CALLBACKS */ + } + + return HAL_OK; +} + +/** + * @brief Retrieve the message digest. + * @param hhash HASH handle + * @param pMsgDigest pointer to the computed digest. + * @param Size message digest size in bytes. + * @retval None + */ +static void HASH_GetDigest(const HASH_HandleTypeDef *hhash, const uint8_t *pMsgDigest, uint8_t Size) +{ + uint32_t msgdigest = (uint32_t)pMsgDigest; + + switch (Size) + { + case 20: /* SHA1 */ + *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[0]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[1]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[2]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[3]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[4]); + break; + + case 28: /* SHA224 */ + *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[0]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[1]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[2]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[3]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[4]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[5]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[6]); + + break; + case 32: /* SHA256 */ + *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[0]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[1]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[2]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[3]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[4]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[5]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[6]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[7]); + break; +#if defined(HASH_ALGOSELECTION_SHA512) + case 48: /* SHA384 */ + *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[0]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[1]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[2]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[3]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[4]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[5]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[6]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[7]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[8]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[9]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[10]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[11]); + break; + + case 64: /* SHA 512 */ + *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[0]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[1]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[2]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[3]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(hhash->Instance->HR[4]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[5]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[6]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[7]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[8]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[9]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[10]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[11]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[12]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[13]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[14]); + msgdigest += 4U; + *(uint32_t *)(msgdigest) = __REV(HASH_DIGEST->HR[15]); + + break; +#endif /* defined(HASH_ALGOSELECTION_SHA512)*/ + default: + break; + } +} + +/** + * @brief Handle HASH processing Timeout. + * @param hhash HASH handle. + * @param Flag specifies the HASH flag to check. + * @param Status the Flag status (SET or RESET). + * @param Timeout Timeout duration. + * @retval HAL status + */ +static HAL_StatusTypeDef HASH_WaitOnFlagUntilTimeout(HASH_HandleTypeDef *hhash, uint32_t Flag, FlagStatus Status, + uint32_t Timeout) +{ + uint32_t tickstart = HAL_GetTick(); + + /* Wait until flag is set */ + if (Status == RESET) + { + while (__HAL_HASH_GET_FLAG(hhash, Flag) == RESET) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + /* Set State to Ready to be able to restart later on */ + hhash->State = HAL_HASH_STATE_READY; + hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT; + /* Process Unlocked */ + __HAL_UNLOCK(hhash); + return HAL_ERROR; + } + } + } + } + else + { + while (__HAL_HASH_GET_FLAG(hhash, Flag) != RESET) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + /* Set State to Ready to be able to restart later on */ + hhash->State = HAL_HASH_STATE_READY; + hhash->ErrorCode |= HAL_HASH_ERROR_TIMEOUT; + /* Process Unlocked */ + __HAL_UNLOCK(hhash); + + return HAL_ERROR; + } + } + } + } + return HAL_OK; +} + +/** + * @} + */ + + +#endif /* HAL_HASH_MODULE_ENABLED */ + +#endif /* HASH*/ +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_hcd.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_hcd.c new file mode 100644 index 0000000000..36498d018f --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_hcd.c @@ -0,0 +1,2868 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_hcd.c + * @author MCD Application Team + * @brief HCD HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the USB Peripheral Controller: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#)Declare a HCD_HandleTypeDef handle structure, for example: + HCD_HandleTypeDef hhcd; + + (#)Fill parameters of Init structure in HCD handle + + (#)Call HAL_HCD_Init() API to initialize the HCD peripheral (Core, Host core, ...) + + (#)Initialize the HCD low level resources through the HAL_HCD_MspInit() API: + (##) Enable the HCD/USB Low Level interface clock using the following macros + (+++) __HAL_RCC_USB_CLK_ENABLE(); + (##) Initialize the related GPIO clocks + (##) Configure HCD pin-out + (##) Configure HCD NVIC interrupt + + (#)Associate the Upper USB Host stack to the HAL HCD Driver: + (##) hhcd.pData = phost; + + (#)Enable HCD transmission and reception: + (##) HAL_HCD_Start(); + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +#ifdef HAL_HCD_MODULE_ENABLED +#if defined (USB_DRD_FS) + +/** @defgroup HCD HCD + * @brief HCD HAL module driver + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function ----------------------------------------------------------*/ +/** @defgroup HCD_Private_Functions HCD Private Functions + * @{ + */ +static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum); +static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum); +static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd); +static void HAL_HCD_ClearPhyChannel(HCD_HandleTypeDef *hhcd); +static uint8_t HAL_HCD_GetLogical_Channel(HCD_HandleTypeDef const *hhcd, uint8_t phy_chnum, uint8_t dir); +static uint8_t HAL_HCD_Check_usedChannel(HCD_HandleTypeDef const *hhcd, uint8_t ch_num); +static uint8_t HAL_HCD_Get_FreePhyChannel(HCD_HandleTypeDef *hhcd, uint8_t ch_num, uint8_t epnum, uint8_t ep_type); + +#if (USE_USB_DOUBLE_BUFFER == 1U) +static void HCD_HC_IN_BulkDb(HCD_HandleTypeDef *hhcd, uint8_t ch_num, uint8_t phy_chnum, uint32_t regvalue); +static void HCD_HC_OUT_BulkDb(HCD_HandleTypeDef *hhcd, uint8_t ch_num, uint8_t phy_chnum, uint32_t regvalue); +#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ + +static uint16_t HAL_HCD_GetFreePMA(HCD_HandleTypeDef *hhcd, uint16_t mps); +static HAL_StatusTypeDef HAL_HCD_PMAFree(HCD_HandleTypeDef *hhcd, uint32_t pma_base, uint16_t mps); +static void inline HCD_HC_IN_ISO(HCD_HandleTypeDef *hhcd, uint8_t ch_num, uint8_t phy_chnum, uint32_t regvalue); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup HCD_Exported_Functions HCD Exported Functions + * @{ + */ + +/** @defgroup HCD_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: + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the host driver. + * @param hhcd HCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd) +{ + /* Check the HCD handle allocation */ + if (hhcd == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_HCD_ALL_INSTANCE(hhcd->Instance)); + + if (hhcd->State == HAL_HCD_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hhcd->Lock = HAL_UNLOCKED; + +#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) + hhcd->SOFCallback = HAL_HCD_SOF_Callback; + hhcd->ConnectCallback = HAL_HCD_Connect_Callback; + hhcd->DisconnectCallback = HAL_HCD_Disconnect_Callback; + hhcd->PortEnabledCallback = HAL_HCD_PortEnabled_Callback; + hhcd->PortDisabledCallback = HAL_HCD_PortDisabled_Callback; + hhcd->HC_NotifyURBChangeCallback = HAL_HCD_HC_NotifyURBChange_Callback; + + if (hhcd->MspInitCallback == NULL) + { + hhcd->MspInitCallback = HAL_HCD_MspInit; + } + + /* Init the low level hardware */ + hhcd->MspInitCallback(hhcd); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC... */ + HAL_HCD_MspInit(hhcd); +#endif /* (USE_HAL_HCD_REGISTER_CALLBACKS) */ + } + hhcd->State = HAL_HCD_STATE_BUSY; + + /* Disable the Interrupts */ + (void)__HAL_HCD_DISABLE(hhcd); + + /* Dma not supported, force to zero */ + hhcd->Init.dma_enable = 0U; + + /* Init the Core (common init.) */ + (void)USB_CoreInit(hhcd->Instance, hhcd->Init); + + /* Force Host Mode */ + (void)USB_SetCurrentMode(hhcd->Instance, USB_HOST_MODE); + + /* Init Host */ + (void)USB_HostInit(hhcd->Instance, hhcd->Init); + + /* Deactivate the power down */ + hhcd->Instance->CNTR &= ~USB_CNTR_PDWN; + + hhcd->State = HAL_HCD_STATE_READY; + + /* Host Port State */ + hhcd->HostState = HCD_HCD_STATE_DISCONNECTED; + + /* Init PMA Address */ + (void)HAL_HCD_PMAReset(hhcd); + + hhcd->State = HAL_HCD_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Initialize a host channel. + * @param hhcd HCD handle + * @param ch_num Channel number. + * This parameter can be a value from 1 to 15 + * @param epnum Endpoint number. + * This parameter can be a value from 1 to 15 + * @param dev_address Current device address + * This parameter can be a value from 0 to 255 + * @param speed Current device speed. + * This parameter can be one of these values: + * HCD_DEVICE_SPEED_HIGH High speed mode, + * HCD_DEVICE_SPEED_FULL Full speed mode, + * HCD_DEVICE_SPEED_LOW Low speed mode + * @param ep_type Endpoint Type. + * This parameter can be one of these values: + * USBH_EP_CONTROL Control type, + * USBH_EP_ISO Isochronous type, + * USBH_EP_BULK Bulk type, + * USBH_EP_INTERRUPT Interrupt type + * @param mps Max Packet Size. + * This parameter can be a value from 0 to32K + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd, uint8_t ch_num, + uint8_t epnum, uint8_t dev_address, + uint8_t speed, uint8_t ep_type, uint16_t mps) +{ + HAL_StatusTypeDef status; + uint8_t used_channel; + uint8_t ep0_virtual_channel; + + __HAL_LOCK(hhcd); + + /* Check if the logical channel are already allocated */ + used_channel = HAL_HCD_Check_usedChannel(hhcd, ch_num); + + /* Check if the channel is not already opened */ + if (used_channel == 0U) + { + /* Allocate New Physical channel */ + hhcd->hc[ch_num & 0xFU].phy_ch_num = HAL_HCD_Get_FreePhyChannel(hhcd, ch_num, epnum, ep_type); + + /* No free Channel available, return error */ + if (hhcd->hc[ch_num & 0xFU].phy_ch_num == HCD_FREE_CH_NOT_FOUND) + { + return HAL_ERROR; + } + } + /* Channel already opened */ + else + { + /* Get Physical Channel number */ + hhcd->hc[ch_num & 0xFU].phy_ch_num = (used_channel & 0xF0U) >> 4U; + } + + if ((epnum & 0x80U) != 0U) + { + hhcd->hc[ch_num & 0xFU].ch_dir = CH_IN_DIR; + } + else + { + hhcd->hc[ch_num & 0xFU].ch_dir = CH_OUT_DIR; + } + + hhcd->hc[ch_num & 0xFU].dev_addr = dev_address; + hhcd->hc[ch_num & 0xFU].max_packet = mps; + hhcd->hc[ch_num & 0xFU].ep_type = ep_type; + hhcd->hc[ch_num & 0xFU].ep_num = epnum & 0x7FU; + hhcd->hc[ch_num & 0xFU].speed = speed; + + /* Check if the channel is not already opened */ + if (used_channel == 0U) + { + if (((ep_type == EP_TYPE_ISOC) && (hhcd->Init.iso_singlebuffer_enable == 0U)) || + ((ep_type == EP_TYPE_BULK) && (hhcd->Init.bulk_doublebuffer_enable == 1U))) + { + /* PMA Dynamic Allocation */ + status = HAL_HCD_PMAlloc(hhcd, ch_num, HCD_DBL_BUF, mps); + + if (status == HAL_ERROR) + { + return HAL_ERROR; + } + + /* Clear Channel DTOG_TX */ + HCD_CLEAR_TX_DTOG(hhcd->Instance, hhcd->hc[ch_num & 0xFU].phy_ch_num); + + /* Clear Channel DTOG RX */ + HCD_CLEAR_RX_DTOG(hhcd->Instance, hhcd->hc[ch_num & 0xFU].phy_ch_num); + + } + else + { + if (hhcd->hc[ch_num & 0xFU].ep_num != 0U) + { + status = HAL_HCD_PMAlloc(hhcd, ch_num, HCD_SNG_BUF, mps); + + if (status == HAL_ERROR) + { + return HAL_ERROR; + } + } + else + { + if (ch_num == 0U) + { + ep0_virtual_channel = (uint8_t)(hhcd->ep0_PmaAllocState & 0xFU); + + if ((ep0_virtual_channel != 0U) && (((hhcd->ep0_PmaAllocState & 0xF0U) >> 4) == CH_IN_DIR)) + { + if (hhcd->hc[ch_num & 0xFU].ch_dir == CH_OUT_DIR) + { + status = HAL_HCD_PMAlloc(hhcd, ch_num, HCD_SNG_BUF, 64U); + + if (status == HAL_ERROR) + { + return HAL_ERROR; + } + } + else + { + return HAL_ERROR; + } + } + else + { + /* PMA Dynamic Allocation for EP0 OUT direction */ + hhcd->hc[ch_num & 0xFU].ch_dir = CH_OUT_DIR; + status = HAL_HCD_PMAlloc(hhcd, ch_num, HCD_SNG_BUF, 64U); + + if (status == HAL_ERROR) + { + return HAL_ERROR; + } + + /* PMA Dynamic Allocation for EP0 IN direction */ + hhcd->hc[ch_num & 0xFU].ch_dir = CH_IN_DIR; + status = HAL_HCD_PMAlloc(hhcd, ch_num, HCD_SNG_BUF, 64U); + + if (status == HAL_ERROR) + { + return HAL_ERROR; + } + } + } + else + { + if (((hhcd->ep0_PmaAllocState & 0xF00U) >> 8) == 1U) + { + ep0_virtual_channel = (uint8_t)(hhcd->ep0_PmaAllocState & 0xFU); + + if (((hhcd->ep0_PmaAllocState & 0xF0U) >> 4) == CH_IN_DIR) + { + hhcd->hc[ch_num & 0xFU].pmaaddr1 = hhcd->hc[ep0_virtual_channel & 0xFU].pmaaddr1; + } + else + { + hhcd->hc[ch_num & 0xFU].pmaaddr0 = hhcd->hc[ep0_virtual_channel & 0xFU].pmaaddr0; + } + } + else + { + status = HAL_HCD_PMAlloc(hhcd, ch_num, HCD_SNG_BUF, 64U); + + if (status == HAL_ERROR) + { + return HAL_ERROR; + } + } + } + } + } + } + + if ((epnum & 0x80U) != 0U) + { + hhcd->hc[ch_num & 0xFU].ch_dir = CH_IN_DIR; + + if (hhcd->hc[ch_num & 0xFU].ep_num == 0U) + { + hhcd->hc[ch_num & 0xFU].pmaadress = hhcd->hc[ch_num & 0xFU].pmaaddr1; + } + } + else + { + hhcd->hc[ch_num & 0xFU].ch_dir = CH_OUT_DIR; + + if (hhcd->hc[ch_num & 0xFU].ep_num == 0U) + { + hhcd->hc[ch_num & 0xFU].pmaadress = hhcd->hc[ch_num & 0xFU].pmaaddr0; + } + } + + /* Init the USB Channel CHEPRx */ + status = USB_HC_Init(hhcd->Instance, hhcd->hc[ch_num & 0xFU].phy_ch_num, + epnum, dev_address, speed, ep_type, mps); + + /* check single buffer for isochronous channel */ + if (ep_type == EP_TYPE_ISOC) + { + if (hhcd->Init.iso_singlebuffer_enable == 1U) + { + (void)USB_HC_DoubleBuffer(hhcd->Instance, hhcd->hc[ch_num & 0xFU].phy_ch_num, + USB_DRD_ISOC_DBUFF_DISABLE); + } + } + + /* Bulk double buffer check */ + if (ep_type == EP_TYPE_BULK) + { + if (hhcd->Init.bulk_doublebuffer_enable == 1U) + { + (void)USB_HC_DoubleBuffer(hhcd->Instance, hhcd->hc[ch_num & 0xFU].phy_ch_num, + USB_DRD_BULK_DBUFF_ENBALE); + } + } + + __HAL_UNLOCK(hhcd); + + return status; +} + +/** + * @brief HAL_HCD_HC_Close Pipe + * @param hhcd HCD handle + * @param ch_num Channel number. + * This parameter can be a value from 1 to 15 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HCD_HC_Close(HCD_HandleTypeDef *hhcd, uint8_t ch_num) +{ + /* Stop the channel */ + (void) HAL_HCD_HC_Halt(hhcd, ch_num); + + HAL_Delay(3U); + + if (hhcd->hc[ch_num & 0xFU].ch_dir == CH_IN_DIR) + { + /* Free Allocated Channel */ + hhcd->phy_chin_state[hhcd->hc[ch_num & 0xFU].phy_ch_num] = 0U; + } + else + { + /* Free Allocated Channel */ + hhcd->phy_chout_state[hhcd->hc[ch_num & 0xFU].phy_ch_num] = 0U; + } + + /* Reset PMA Channel_Allocation */ + (void)HAL_HCD_PMADeAlloc(hhcd, ch_num); + + return HAL_OK; +} + +/** + * @brief Halt a host channel. + * @param hhcd HCD handle + * @param ch_num Channel number. + * This parameter can be a value from 1 to 15 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd, uint8_t ch_num) +{ + HAL_StatusTypeDef status = HAL_OK; + + __HAL_LOCK(hhcd); + if (hhcd->hc[ch_num & 0xFU].ch_dir == CH_IN_DIR) + { + (void)USB_HC_IN_Halt(hhcd->Instance, (uint8_t) hhcd->hc[ch_num & 0xFU].phy_ch_num); + } + else + { + (void)USB_HC_OUT_Halt(hhcd->Instance, (uint8_t) hhcd->hc[ch_num & 0xFU].phy_ch_num); + } + __HAL_UNLOCK(hhcd); + + return status; +} + +/** + * @brief DeInitialize the host driver. + * @param hhcd HCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd) +{ + uint8_t idx; + + /* Check the HCD handle allocation */ + if (hhcd == NULL) + { + return HAL_ERROR; + } + + /* Host Port State */ + hhcd->HostState = HCD_HCD_STATE_DISCONNECTED; + + /* Reset PMA Address */ + (void)HAL_HCD_PMAReset(hhcd); + + for (idx = 0U; idx < hhcd->Init.Host_channels; idx++) + { + hhcd->phy_chin_state[idx] = 0U; + hhcd->phy_chout_state[idx] = 0U; + } + + /* reset Ep0 Pma allocation state */ + hhcd->ep0_PmaAllocState = 0U; + + hhcd->State = HAL_HCD_STATE_BUSY; + +#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) + if (hhcd->MspDeInitCallback == NULL) + { + hhcd->MspDeInitCallback = HAL_HCD_MspDeInit; /* Legacy weak MspDeInit */ + } + + /* DeInit the low level hardware */ + hhcd->MspDeInitCallback(hhcd); +#else + /* DeInit the low level hardware: CLOCK, NVIC. */ + HAL_HCD_MspDeInit(hhcd); +#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ + + hhcd->State = HAL_HCD_STATE_RESET; + + return HAL_OK; +} + +/** + * @brief Initialize the HCD MSP. + * @param hhcd HCD handle + * @retval None + */ +__weak void HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhcd); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_HCD_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitialize the HCD MSP. + * @param hhcd HCD handle + * @retval None + */ +__weak void HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhcd); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_HCD_MspDeInit could be implemented in the user file + */ +} + +__weak void HAL_HCD_SuspendCallback(HCD_HandleTypeDef *hhcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhcd); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_HCD_SuspendCallback could be implemented in the user file + */ + +} + +__weak void HAL_HCD_ResumeCallback(HCD_HandleTypeDef *hhcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhcd); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_HCD_ResumeCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup HCD_Exported_Functions_Group2 Input and Output operation functions + * @brief HCD IO operation functions + * +@verbatim +=============================================================================== +##### IO operation functions ##### +=============================================================================== +[..] This subsection provides a set of functions allowing to manage the USB Host Data +Transfer + +@endverbatim + * @{ + */ + +/** + * @brief Submit a new URB for processing. + * @param hhcd HCD handle + * @param ch_num Channel number. + * This parameter can be a value from 1 to 15 + * @param direction Channel number. + * This parameter can be one of these values: + * 0 : Output / 1 : Input + * @param ep_type Endpoint Type. + * This parameter can be one of these values: + * USBH_EP_CONTROL : Control type/ + * USBH_EP_ISO : Isochronous type/ + * USBH_EP_BULK : Bulk type/ + * USBH_EP_INTERRUPT : Interrupt type/ + * @param token Endpoint Type. + * This parameter can be one of these values: + * 0: HC_PID_SETUP / 1: HC_PID_DATA1 + * @param pbuff pointer to URB data + * @param length Length of URB data + * @param do_ping activate do ping protocol (for high speed only). + * This parameter can be one of these values: + * 0 : do ping inactive / 1 : do ping active + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd, uint8_t ch_num, + uint8_t direction, uint8_t ep_type, + uint8_t token, uint8_t *pbuff, + uint16_t length, uint8_t do_ping) +{ + UNUSED(do_ping); + + if (token == 0U) + { + hhcd->hc[ch_num & 0xFU].data_pid = HC_PID_SETUP; + } + else + { + hhcd->hc[ch_num & 0xFU].data_pid = HC_PID_DATA1; + } + + /* Manage Data Toggle */ + switch (ep_type) + { + case EP_TYPE_CTRL: + if ((token == 1U) && (direction == 0U)) /* send data */ + { + if (length == 0U) + { + /* For Status OUT stage, Length==0, Status Out PID = 1 */ + hhcd->hc[ch_num & 0xFU].toggle_out = 1U; + } + + /* Set the Data Toggle bit as per the Flag */ + if (hhcd->hc[ch_num & 0xFU].toggle_out == 0U) + { + /* Put the PID 0 */ + hhcd->hc[ch_num & 0xFU].data_pid = HC_PID_DATA0; + } + else + { + /* Put the PID 1 */ + hhcd->hc[ch_num & 0xFU].data_pid = HC_PID_DATA1; + } + } + break; + + case EP_TYPE_BULK: + if (direction == 0U) + { + /* Set the Data Toggle bit as per the Flag */ + if (hhcd->hc[ch_num & 0xFU].toggle_out == 0U) + { + /* Put the PID 0 */ + hhcd->hc[ch_num & 0xFU].data_pid = HC_PID_DATA0; + } + else + { + /* Put the PID 1 */ + hhcd->hc[ch_num & 0xFU].data_pid = HC_PID_DATA1; + } + } + else + { + if (hhcd->hc[ch_num & 0xFU].toggle_in == 0U) + { + hhcd->hc[ch_num & 0xFU].data_pid = HC_PID_DATA0; + } + else + { + hhcd->hc[ch_num & 0xFU].data_pid = HC_PID_DATA1; + } + } + break; + + case EP_TYPE_INTR: + if (direction == 0U) + { + /* Set the Data Toggle bit as per the Flag */ + if (hhcd->hc[ch_num & 0xFU].toggle_out == 0U) + { + /* Put the PID 0 */ + hhcd->hc[ch_num & 0xFU].data_pid = HC_PID_DATA0; + } + else + { + /* Put the PID 1 */ + hhcd->hc[ch_num & 0xFU].data_pid = HC_PID_DATA1; + } + } + else + { + if (hhcd->hc[ch_num & 0xFU].toggle_in == 0U) + { + hhcd->hc[ch_num & 0xFU].data_pid = HC_PID_DATA0; + } + else + { + hhcd->hc[ch_num & 0xFU].data_pid = HC_PID_DATA1; + } + } + break; + + case EP_TYPE_ISOC: + hhcd->hc[ch_num & 0xFU].data_pid = HC_PID_DATA0; + break; + + default: + break; + } + + hhcd->hc[ch_num & 0xFU].xfer_buff = pbuff; + hhcd->hc[ch_num & 0xFU].xfer_len = length; + hhcd->hc[ch_num & 0xFU].xfer_len_db = length; + hhcd->hc[ch_num & 0xFU].urb_state = URB_IDLE; + hhcd->hc[ch_num & 0xFU].xfer_count = 0U; + hhcd->hc[ch_num & 0xFU].state = HC_IDLE; + + return USB_HC_StartXfer(hhcd->Instance, &hhcd->hc[ch_num & 0xFU]); +} +/** + * @brief Handle HCD interrupt request. + * @param hhcd HCD handle + * @retval None + */ +void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd) +{ + uint8_t phy_chnum; + uint8_t chnum; + uint32_t epch_reg; + uint32_t wIstr = USB_ReadInterrupts(hhcd->Instance); + + /* Port Change Detected (Connection/Disconnection) */ + if ((wIstr & USB_ISTR_DCON) == USB_ISTR_DCON) + { + /* Clear Flag */ + __HAL_HCD_CLEAR_FLAG(hhcd, USB_ISTR_DCON); + + /* Call Port IRQHandler */ + HCD_Port_IRQHandler(hhcd); + + return; + } + + /* Correct Transaction Detected -------*/ + if ((wIstr & USB_ISTR_CTR) == USB_ISTR_CTR) + { + /* Handle Host channel Interrupt */ + for (phy_chnum = 0U; phy_chnum < hhcd->Init.Host_channels; phy_chnum++) + { + if ((HCD_GET_CHANNEL(hhcd->Instance, phy_chnum) & USB_CH_VTRX) != 0U) + { + /* Get Logical channel to check if the channel is already opened */ + chnum = HAL_HCD_GetLogical_Channel(hhcd, phy_chnum, 1U); + + if (chnum != HCD_LOGICAL_CH_NOT_OPENED) + { + /* Call Channel_IN_IRQ() */ + HCD_HC_IN_IRQHandler(hhcd, chnum); + } + else + { + /*Channel was not closed correctly still have interrupt */ + epch_reg = HCD_GET_CHANNEL(hhcd->Instance, phy_chnum); + epch_reg = (epch_reg & (USB_CHEP_REG_MASK & (~USB_CH_ERRRX) & (~USB_CH_VTRX))) | + (USB_CH_VTTX | USB_CH_ERRTX); + + HCD_SET_CHANNEL(hhcd->Instance, phy_chnum, epch_reg); + } + } + + if ((HCD_GET_CHANNEL(hhcd->Instance, phy_chnum) & USB_CH_VTTX) != 0U) + { + /* Get Logical channel to check if the channel is already opened */ + chnum = HAL_HCD_GetLogical_Channel(hhcd, phy_chnum, 0U); + + if (chnum != HCD_LOGICAL_CH_NOT_OPENED) + { + /*Call Channel_OUT_IRQ()*/ + HCD_HC_OUT_IRQHandler(hhcd, chnum); + } + else + { + /* Clear Error & unwanted VTTX or Channel was not closed correctly */ + epch_reg = HCD_GET_CHANNEL(hhcd->Instance, phy_chnum); + epch_reg = (epch_reg & (USB_CHEP_REG_MASK & (~USB_CH_ERRTX) & (~USB_CH_VTTX))) | + (USB_CH_VTRX | USB_CH_ERRRX); + + HCD_SET_CHANNEL(hhcd->Instance, phy_chnum, epch_reg); + } + } + } + + return; + } + + /* Wakeup Flag Detected */ + if ((wIstr & USB_ISTR_WKUP) == USB_ISTR_WKUP) + { + if (hhcd->HostState == HCD_HCD_STATE_SUSPEND) + { + /* Set The L2Resume bit */ + hhcd->Instance->CNTR |= USB_CNTR_L2RES; + + /* Clear the wake-up flag */ + __HAL_HCD_CLEAR_FLAG(hhcd, USB_ISTR_WKUP); + + /* Update the USB Software state machine */ + HAL_HCD_ResumeCallback(hhcd); + hhcd->HostState = HCD_HCD_STATE_RESUME; + } + else + { + /* Clear the wake-up flag */ + __HAL_HCD_CLEAR_FLAG(hhcd, USB_ISTR_WKUP); + } + + return; + } + + /* Global Error Flag Detected */ + if ((wIstr & USB_ISTR_ERR) == USB_ISTR_ERR) + { + __HAL_HCD_CLEAR_FLAG(hhcd, USB_ISTR_ERR); + + return; + } + + /* PMA Overrun detected */ + if ((wIstr & USB_ISTR_PMAOVR) == USB_ISTR_PMAOVR) + { + __HAL_HCD_CLEAR_FLAG(hhcd, USB_ISTR_PMAOVR); + + return; + } + + /* Suspend Detected */ + if ((wIstr & USB_ISTR_SUSP) == USB_ISTR_SUSP) + { + /* Set HAL State to Suspend */ + hhcd->HostState = HCD_HCD_STATE_SUSPEND; + + /* Force low-power mode in the macrocell */ + hhcd->Instance->CNTR |= USB_CNTR_SUSPEN; + + /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ + __HAL_HCD_CLEAR_FLAG(hhcd, USB_ISTR_SUSP); + + /* Call suspend Callback */ + HAL_HCD_SuspendCallback(hhcd); + + return; + } + + /* Start Of Frame Detected */ + if ((wIstr & USB_ISTR_SOF) == USB_ISTR_SOF) + { +#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) + hhcd->SOFCallback(hhcd); +#else + HAL_HCD_SOF_Callback(hhcd); +#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ + + __HAL_HCD_CLEAR_FLAG(hhcd, USB_ISTR_SOF); + + /* when first SOF is detected after USB_RESET is asserted */ + if (hhcd->HostState == HCD_HCD_STATE_RESETED) + { + /* HAL State */ + hhcd->HostState = HCD_HCD_STATE_RUN; + +#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) + hhcd->PortEnabledCallback(hhcd); +#else + HAL_HCD_PortEnabled_Callback(hhcd); +#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ + } + + return; + } +} + +/** + * @brief SOF callback. + * @param hhcd HCD handle + * @retval None + */ +__weak void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhcd); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_HCD_SOF_Callback could be implemented in the user file + */ +} + +/** + * @brief Connection Event callback. + * @param hhcd HCD handle + * @retval None + */ +__weak void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhcd); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_HCD_Connect_Callback could be implemented in the user file + */ +} + +/** + * @brief Disconnection Event callback. + * @param hhcd HCD handle + * @retval None + */ +__weak void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhcd); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_HCD_Disconnect_Callback could be implemented in the user file + */ +} +/** + * @brief Port Enabled Event callback. + * @param hhcd HCD handle + * @retval None + */ +__weak void HAL_HCD_PortEnabled_Callback(HCD_HandleTypeDef *hhcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_HCD_Disconnect_Callback could be implemented in the user file + */ +} +/** + * @brief Port Disabled Event callback. + * @param hhcd HCD handle + * @retval None + */ +__weak void HAL_HCD_PortDisabled_Callback(HCD_HandleTypeDef *hhcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_HCD_Disconnect_Callback could be implemented in the user file + */ +} + +/** + * @brief Notify URB state change callback. + * @param hhcd HCD handle + * @param chnum Channel number. + * This parameter can be a value from 1 to 15 + * @param urb_state + * This parameter can be one of these values: + * URB_IDLE/ + * URB_DONE/ + * URB_NOTREADY/ + * URB_NYET/ + * URB_ERROR/ + * URB_STALL/ + * @retval None + */ +__weak void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, + uint8_t chnum, HCD_URBStateTypeDef urb_state) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hhcd); + UNUSED(chnum); + UNUSED(urb_state); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_HCD_HC_NotifyURBChange_Callback could be implemented in the user file + */ +} +#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) +/** + * @brief Register a User USB HCD Callback + * To be used instead of the weak predefined callback + * @param hhcd USB HCD handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_HCD_SOF_CB_ID USB HCD SOF callback ID + * @arg @ref HAL_HCD_CONNECT_CB_ID USB HCD Connect callback ID + * @arg @ref HAL_HCD_DISCONNECT_CB_ID HCD Disconnect callback ID + * @arg @ref HAL_HCD_PORT_ENABLED_CB_ID USB HCD Port Enable callback ID + * @arg @ref HAL_HCD_PORT_DISABLED_CB_ID USB HCD Port Disable callback ID + * @arg @ref HAL_HCD_MSPINIT_CB_ID MspDeInit callback ID + * @arg @ref HAL_HCD_MSPDEINIT_CB_ID MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HCD_RegisterCallback(HCD_HandleTypeDef *hhcd, + HAL_HCD_CallbackIDTypeDef CallbackID, + pHCD_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + /* Process locked */ + __HAL_LOCK(hhcd); + + if (hhcd->State == HAL_HCD_STATE_READY) + { + switch (CallbackID) + { + case HAL_HCD_SOF_CB_ID : + hhcd->SOFCallback = pCallback; + break; + + case HAL_HCD_CONNECT_CB_ID : + hhcd->ConnectCallback = pCallback; + break; + + case HAL_HCD_DISCONNECT_CB_ID : + hhcd->DisconnectCallback = pCallback; + break; + + case HAL_HCD_PORT_ENABLED_CB_ID : + hhcd->PortEnabledCallback = pCallback; + break; + + case HAL_HCD_PORT_DISABLED_CB_ID : + hhcd->PortDisabledCallback = pCallback; + break; + + case HAL_HCD_MSPINIT_CB_ID : + hhcd->MspInitCallback = pCallback; + break; + + case HAL_HCD_MSPDEINIT_CB_ID : + hhcd->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (hhcd->State == HAL_HCD_STATE_RESET) + { + switch (CallbackID) + { + case HAL_HCD_MSPINIT_CB_ID : + hhcd->MspInitCallback = pCallback; + break; + + case HAL_HCD_MSPDEINIT_CB_ID : + hhcd->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hhcd); + return status; +} + +/** + * @brief Unregister an USB HCD Callback + * USB HCD callback is redirected to the weak predefined callback + * @param hhcd USB HCD handle + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_HCD_SOF_CB_ID USB HCD SOF callback ID + * @arg @ref HAL_HCD_CONNECT_CB_ID USB HCD Connect callback ID + * @arg @ref HAL_HCD_DISCONNECT_CB_ID DRD HCD Disconnect callback ID + * @arg @ref HAL_HCD_PORT_ENABLED_CB_ID USB HCD Port Enabled callback ID + * @arg @ref HAL_HCD_PORT_DISABLED_CB_ID USB HCD Port Disabled callback ID + * @arg @ref HAL_HCD_MSPINIT_CB_ID MspDeInit callback ID + * @arg @ref HAL_HCD_MSPDEINIT_CB_ID MspDeInit callback ID + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HCD_UnRegisterCallback(HCD_HandleTypeDef *hhcd, + HAL_HCD_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hhcd); + + /* Setup Legacy weak Callbacks */ + if (hhcd->State == HAL_HCD_STATE_READY) + { + switch (CallbackID) + { + case HAL_HCD_SOF_CB_ID : + hhcd->SOFCallback = HAL_HCD_SOF_Callback; + break; + + case HAL_HCD_CONNECT_CB_ID : + hhcd->ConnectCallback = HAL_HCD_Connect_Callback; + break; + + case HAL_HCD_DISCONNECT_CB_ID : + hhcd->DisconnectCallback = HAL_HCD_Disconnect_Callback; + break; + + case HAL_HCD_PORT_ENABLED_CB_ID : + hhcd->PortEnabledCallback = HAL_HCD_PortEnabled_Callback; + break; + + case HAL_HCD_PORT_DISABLED_CB_ID : + hhcd->PortDisabledCallback = HAL_HCD_PortDisabled_Callback; + break; + + case HAL_HCD_MSPINIT_CB_ID : + hhcd->MspInitCallback = HAL_HCD_MspInit; + break; + + case HAL_HCD_MSPDEINIT_CB_ID : + hhcd->MspDeInitCallback = HAL_HCD_MspDeInit; + break; + + default : + /* Update the error code */ + hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (hhcd->State == HAL_HCD_STATE_RESET) + { + switch (CallbackID) + { + case HAL_HCD_MSPINIT_CB_ID : + hhcd->MspInitCallback = HAL_HCD_MspInit; + break; + + case HAL_HCD_MSPDEINIT_CB_ID : + hhcd->MspDeInitCallback = HAL_HCD_MspDeInit; + break; + + default : + /* Update the error code */ + hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hhcd); + return status; +} + +/** + * @brief Register USB HCD Host Channel Notify URB Change Callback + * To be used instead of the weak HAL_HCD_HC_NotifyURBChange_Callback() predefined callback + * @param hhcd HCD handle + * @param pCallback pointer to the USB HCD Host Channel Notify URB Change Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HCD_RegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd, + pHCD_HC_NotifyURBChangeCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hhcd); + + if (hhcd->State == HAL_HCD_STATE_READY) + { + hhcd->HC_NotifyURBChangeCallback = pCallback; + } + else + { + /* Update the error code */ + hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hhcd); + + return status; +} + +/** + * @brief Unregister the USB HCD Host Channel Notify URB Change Callback + * USB HCD Host Channel Notify URB Change Callback is redirected + * to the weak HAL_HCD_HC_NotifyURBChange_Callback() predefined callback + * @param hhcd HCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HCD_UnRegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hhcd); + + if (hhcd->State == HAL_HCD_STATE_READY) + { + hhcd->HC_NotifyURBChangeCallback = HAL_HCD_HC_NotifyURBChange_Callback; /* Legacy weak DataOutStageCallback */ + } + else + { + /* Update the error code */ + hhcd->ErrorCode |= HAL_HCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hhcd); + + return status; +} +#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ + + +/** + * @} + */ + +/** @defgroup HCD_Exported_Functions_Group3 Peripheral Control functions + * @brief Management functions + * +@verbatim +=============================================================================== +##### Peripheral Control functions ##### +=============================================================================== +[..] +This subsection provides a set of functions allowing to control the HCD data +transfers. + +@endverbatim + * @{ + */ + +/** + * @brief Start the host driver. + * @param hhcd HCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd) +{ + __HAL_LOCK(hhcd); + + /*Set the PullDown on the PHY */ + hhcd->Instance->BCDR |= USB_BCDR_DPPD; + + /* Clear Reset */ + hhcd->Instance->CNTR &= ~USB_CNTR_USBRST; + + /*Remove PowerDown */ + hhcd->Instance->CNTR &= ~USB_CNTR_PDWN; + + __HAL_UNLOCK(hhcd); + + return HAL_OK; +} + +/** + * @brief Stop the host driver. + * @param hhcd HCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd) +{ + __HAL_LOCK(hhcd); + /*Stop the Host IP: setting powerdown */ + (void)USB_StopHost(hhcd->Instance); + + /* clear all allocated virtual channel */ + HAL_HCD_ClearPhyChannel(hhcd); + + /* Reset the PMA current pointer */ + (void)HAL_HCD_PMAReset(hhcd); + + /* reset Ep0 Pma allocation state */ + hhcd->ep0_PmaAllocState = 0U; + + __HAL_UNLOCK(hhcd); + return HAL_OK; +} + +/** + * @brief Put the Device in suspend mode + * @param hhcd HCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HCD_Suspend(HCD_HandleTypeDef *hhcd) +{ + __IO uint32_t count = 0U; + + /* Set Suspend Mode */ + hhcd->Instance->CNTR |= USB_CNTR_SUSPEN; + + /* wait for Suspend Ready */ + while ((hhcd->Instance->CNTR & USB_CNTR_SUSPRDY) == 0U) + { + if (++count > 0xFFFFFFU) + { + return HAL_TIMEOUT; + } + } + + return HAL_OK; +} + +/** + * @brief Resume host port + * @param hhcd HCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HCD_Resume(HCD_HandleTypeDef *hhcd) +{ + /* Set Resume bit */ + hhcd->Instance->CNTR |= USB_CNTR_L2RES; + + return HAL_OK; +} + +/** + * @brief Reset the host port. + * @param hhcd HCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd) +{ + __HAL_LOCK(hhcd); + + /* Reset the USB Port by inserting an SE0 on the bus */ + (void)USB_ResetPort(hhcd->Instance); + + if (hhcd->HostState == HCD_HCD_STATE_CONNECTED) + { + hhcd->HostState = HCD_HCD_STATE_RESETED; + } + __HAL_UNLOCK(hhcd); + + return HAL_OK; +} + +/** + * @brief Resme the host port. + * @param hhcd HCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HCD_ResumePort(HCD_HandleTypeDef *hhcd) +{ + /* Set Resume bit */ + hhcd->Instance->CNTR |= USB_CNTR_L2RES; + HAL_Delay(30U); + + /* Clear Resume bit */ + hhcd->Instance->CNTR &= ~USB_CNTR_L2RES; + + return HAL_OK; +} + + +/** + * @} + */ + +/** @defgroup HCD_Exported_Functions_Group4 Peripheral State functions + * @brief Peripheral State functions + * +@verbatim +=============================================================================== +##### Peripheral State functions ##### +=============================================================================== +[..] +This subsection permits to get in run-time the status of the peripheral +and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the HCD handle state. + * @param hhcd HCD handle + * @retval HAL state + */ +HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef const *hhcd) +{ + return hhcd->State; +} + +/** + * @brief Return URB state for a channel. + * @param hhcd HCD handle + * @param chnum Channel number. + * This parameter can be a value from 1 to 15 + * @retval URB state. + * This parameter can be one of these values: + * URB_IDLE/ + * URB_DONE/ + * URB_NOTREADY/ + * URB_NYET/ + * URB_ERROR/ + * URB_STALL + */ +HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef const *hhcd, uint8_t chnum) +{ + return hhcd->hc[chnum].urb_state; +} + + +/** + * @brief Return the last host transfer size. + * @param hhcd HCD handle + * @param chnum Channel number. + * This parameter can be a value from 1 to 15 + * @retval last transfer size in byte + */ +uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef const *hhcd, uint8_t chnum) +{ + return hhcd->hc[chnum].xfer_count; +} + +/** + * @brief Return the Host Channel state. + * @param hhcd HCD handle + * @param chnum Channel number. + * This parameter can be a value from 1 to 15 + * @retval Host channel state + * This parameter can be one of these values: + * HC_IDLE/ + * HC_XFRC/ + * HC_HALTED/ + * HC_NYET/ + * HC_NAK/ + * HC_STALL/ + * HC_XACTERR/ + * HC_BBLERR/ + * HC_DATATGLERR + */ +HCD_HCStateTypeDef HAL_HCD_HC_GetState(HCD_HandleTypeDef const *hhcd, uint8_t chnum) +{ + return hhcd->hc[chnum].state; +} + +/** + * @brief Return the current Host frame number. + * @param hhcd HCD handle + * @retval Current Host frame number + */ +uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd) +{ + return (USB_GetCurrentFrame(hhcd->Instance)); +} + +/** + * @brief Return the Host enumeration speed. + * @param hhcd HCD handle + * @retval speed : Device speed after Host enumeration + * This parameter can be one of these values: + * @arg HCD_DEVICE_SPEED_FULL: Full speed mode + * @arg HCD_DEVICE_SPEED_LOW: Low speed mode + */ +uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd) +{ + return (USB_GetHostSpeed(hhcd->Instance)); +} + +/** + * @brief Set host channel Hub Information. + * @param hhcd HCD handle + * @param ch_num Channel number. + * This parameter can be a value from 1 to 8 + * @param addr Hub address + * @param PortNbr Hub port number + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HCD_HC_SetHubInfo(HCD_HandleTypeDef *hhcd, uint8_t ch_num, + uint8_t addr, uint8_t PortNbr) +{ + hhcd->hc[ch_num].hub_addr = addr; + hhcd->hc[ch_num].hub_port_nbr = PortNbr; + + return HAL_OK; +} + + +/** + * @brief Clear host channel hub information. + * @param hhcd HCD handle + * @param ch_num Channel number. + * This parameter can be a value from 1 to 8 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HCD_HC_ClearHubInfo(HCD_HandleTypeDef *hhcd, uint8_t ch_num) +{ + hhcd->hc[ch_num].hub_addr = 0U; + hhcd->hc[ch_num].hub_port_nbr = 0U; + + return HAL_OK; +} + +#if (USE_USB_DOUBLE_BUFFER == 1U) +/** + * @brief Handle Host Channel OUT Double Buffer Bulk requests. + * @param hhcd HCD handle + * @param ch_num Channel number This parameter can be a value from 1 to 15 + * @param phy_chnum Physical Channel number [0..7] + * @param regvalue contain Snapshot of the EPCHn register when ISR is detected + * @retval none + */ +static void HCD_HC_OUT_BulkDb(HCD_HandleTypeDef *hhcd, uint8_t ch_num, + uint8_t phy_chnum, uint32_t regvalue) +{ + uint16_t data_xfr; + uint16_t len; + + /* Send Buffer0 */ + if ((regvalue & USB_CH_DTOG_TX) != 0U) + { + data_xfr = (uint16_t)(((USB_DRD_PMA_BUFF + phy_chnum)->TXBD & 0x03FF0000U) >> 16U); + + if (hhcd->hc[ch_num & 0xFU].xfer_len >= data_xfr) + { + hhcd->hc[ch_num & 0xFU].xfer_len -= data_xfr; + } + else + { + hhcd->hc[ch_num & 0xFU].xfer_len = 0U; + } + + /* Transfer no yet finished only one packet of mps is transferred and ACKed from device */ + if (hhcd->hc[ch_num & 0xFU].xfer_len != 0U) + { + /* manage multiple Xfer */ + hhcd->hc[ch_num & 0xFU].xfer_count += data_xfr; + + /* check if we need to free user buffer */ + if ((regvalue & USB_CH_DTOG_RX) != 0U) + { + /* Toggle SwBuff */ + HCD_CLEAR_TX_DTOG(hhcd->Instance, phy_chnum); + HCD_CLEAR_RX_DTOG(hhcd->Instance, phy_chnum); + HCD_TX_DTOG(hhcd->Instance, phy_chnum); + } + + /* hhcd->hc[ch_num&0xFU].xfer_len_db==0 ==> when all data are written in the PMA to yet transferred */ + if (hhcd->hc[ch_num & 0xFU].xfer_len_db > 0U) /* Still data to fill in the buffer */ + { + hhcd->hc[ch_num & 0xFU].xfer_buff += data_xfr; + + /* calculate len of new buffer to fill */ + if (hhcd->hc[ch_num & 0xFU].xfer_len_db > hhcd->hc[ch_num & 0xFU].max_packet) + { + len = (uint16_t)hhcd->hc[ch_num & 0xFU].max_packet; + hhcd->hc[ch_num & 0xFU].xfer_len_db -= len; + } + else + { + len = (uint16_t)hhcd->hc[ch_num & 0xFU].xfer_len_db; + hhcd->hc[ch_num & 0xFU].xfer_len_db = 0U; /* end of fill buffer */ + } + + /* Write remaining data to Buffer0 */ + HCD_SET_CH_DBUF0_CNT(hhcd->Instance, phy_chnum, 1U, (uint16_t)len); + USB_WritePMA(hhcd->Instance, hhcd->hc[ch_num & 0xFU].xfer_buff, + hhcd->hc[ch_num & 0xFU].pmaaddr0, (uint16_t)len); + } + /* start a new transfer */ + HCD_SET_CH_TX_STATUS(hhcd->Instance, phy_chnum, USB_CH_TX_VALID); + } + else + { + /* Transfer complete state */ + hhcd->hc[ch_num & 0xFU].xfer_count += data_xfr; + hhcd->hc[ch_num & 0xFU].state = HC_XFRC; + hhcd->hc[ch_num & 0xFU].urb_state = URB_DONE; + hhcd->hc[ch_num & 0xFU].toggle_out ^= 1U; + /* Close the Channel */ + HCD_SET_CH_TX_STATUS(hhcd->Instance, phy_chnum, USB_CH_TX_DIS); + } + } + else + { + /* Send Buffer1 */ + data_xfr = (uint16_t)(((USB_DRD_PMA_BUFF + phy_chnum)->RXBD & 0x03FF0000U) >> 16U); + + if (hhcd->hc[ch_num & 0xFU].xfer_len >= data_xfr) /* updated */ + { + hhcd->hc[ch_num & 0xFU].xfer_len -= data_xfr; + } + + /* Transfer no yet finished only one packet of mps is transferred and ACKed from device */ + if (hhcd->hc[ch_num & 0xFU].xfer_len != 0U) + { + /* manage multiple Xfer */ + hhcd->hc[ch_num & 0xFU].xfer_count += data_xfr; + + /* check if we need to free user buffer */ + if ((regvalue & USB_CH_DTOG_RX) == 0U) + { + /* Toggle SwBuff */ + HCD_CLEAR_TX_DTOG(hhcd->Instance, phy_chnum); + HCD_CLEAR_RX_DTOG(hhcd->Instance, phy_chnum); + HCD_RX_DTOG(hhcd->Instance, phy_chnum); + } + + /* hhcd->hc[ch_num&0xFU].xfer_len_db==0 ==> when all data are written in the PMA to yet transferred */ + if (hhcd->hc[ch_num & 0xFU].xfer_len_db > 0U) /* Still data to fill in the buffer */ + { + hhcd->hc[ch_num & 0xFU].xfer_buff += data_xfr; + + /* calculate len of new buffer to fill */ + if (hhcd->hc[ch_num & 0xFU].xfer_len_db > hhcd->hc[ch_num & 0xFU].max_packet) + { + len = hhcd->hc[ch_num & 0xFU].max_packet; + hhcd->hc[ch_num & 0xFU].xfer_len_db -= len; + } + else + { + len = (uint16_t)hhcd->hc[ch_num & 0xFU].xfer_len_db; + hhcd->hc[ch_num & 0xFU].xfer_len_db = 0U; /* end of fill buffer */ + } + + /* Write remaining data to Buffer0 */ + HCD_SET_CH_DBUF1_CNT(hhcd->Instance, phy_chnum, 1U, (uint16_t)len); + + USB_WritePMA(hhcd->Instance, hhcd->hc[ch_num & 0xFU].xfer_buff, + hhcd->hc[ch_num & 0xFU].pmaaddr1, (uint16_t)len); + } + + /* start a new transfer */ + HCD_SET_CH_TX_STATUS(hhcd->Instance, phy_chnum, USB_CH_TX_VALID); + } + else + { + /* Transfer complete state */ + hhcd->hc[ch_num & 0xFU].xfer_count += data_xfr; + hhcd->hc[ch_num & 0xFU].state = HC_XFRC; + hhcd->hc[ch_num & 0xFU].urb_state = URB_DONE; + hhcd->hc[ch_num & 0xFU].toggle_out ^= 1U; + + /* Close the channel */ + HCD_SET_CH_TX_STATUS(hhcd->Instance, phy_chnum, USB_CH_TX_DIS); + } + } +} + + +/** + * @brief Handle Host Channel IN Double Buffer Bulk requests. + * @param hhcd HCD handle + * @param ch_num Channel number: This parameter can be a value from 1 to 15 + * @param phy_chnum Physical Channel number [0..7] + * @param regvalue contain Snapshot of the EPCHn register when ISR is detected + * @retval none + */ +static void HCD_HC_IN_BulkDb(HCD_HandleTypeDef *hhcd, + uint8_t ch_num, uint8_t phy_chnum, uint32_t regvalue) +{ + uint16_t received_bytes; + + /* Read from Buffer 0 */ + if ((regvalue & USB_CH_DTOG_RX) != 0U) + { + received_bytes = (uint16_t)HCD_GET_CH_DBUF0_CNT(hhcd->Instance, phy_chnum); + + if (hhcd->hc[ch_num & 0xFU].xfer_len <= received_bytes) + { + hhcd->hc[ch_num & 0xFU].xfer_len = 0U; + } + else + { + hhcd->hc[ch_num & 0xFU].xfer_len -= received_bytes; + } + + /* Check if we Need to free the other buffer for the IP */ + if ((hhcd->hc[ch_num & 0xFU].xfer_len != 0U) && ((regvalue & USB_CH_DTOG_TX) != 0U)) + { + /* Toggle SwBuff to Allow the IP to submit a new IN */ + HCD_FREE_USER_BUFFER(hhcd->Instance, phy_chnum, 0U); + } + + /* Read the byte from PMA to user Buffer(System Memory) */ + USB_ReadPMA(hhcd->Instance, hhcd->hc[ch_num & 0xFU].xfer_buff, + hhcd->hc[ch_num & 0xFU].pmaaddr0, (uint16_t)received_bytes); + } + else + { + /* Read from Buffer 1 */ + received_bytes = (uint16_t) HCD_GET_CH_DBUF1_CNT(hhcd->Instance, phy_chnum); + + if (hhcd->hc[ch_num & 0xFU].xfer_len <= received_bytes) + { + hhcd->hc[ch_num & 0xFU].xfer_len = 0U; + } + else + { + hhcd->hc[ch_num & 0xFU].xfer_len -= received_bytes; + } + + /* Check if we Need to free the other buffer for the IP */ + if ((hhcd->hc[ch_num & 0xFU].xfer_len != 0U) && ((regvalue & USB_CH_DTOG_TX) == 0U)) + { + /* Toggle SwBuff */ + HCD_FREE_USER_BUFFER(hhcd->Instance, phy_chnum, 0U); + } + + /* Read the byte from PMA to user Buffer(System Memory) */ + USB_ReadPMA(hhcd->Instance, hhcd->hc[ch_num & 0xFU].xfer_buff, + hhcd->hc[ch_num & 0xFU].pmaaddr1, (uint16_t)received_bytes); + } + + /* update the global number of all received bytes */ + hhcd->hc[ch_num & 0xFU].xfer_count += received_bytes; + + /* Transfer complete state */ + hhcd->hc[ch_num & 0xFU].state = HC_ACK; + hhcd->hc[ch_num & 0xFU].ErrCnt = 0U; + + if ((hhcd->hc[ch_num & 0xFU].xfer_len == 0U) || + ((received_bytes < hhcd->hc[ch_num & 0xFU].max_packet))) + { + hhcd->hc[ch_num & 0xFU].urb_state = URB_DONE; + hhcd->hc[ch_num & 0xFU].state = HC_XFRC; + + /* disable channel */ + HCD_SET_CH_RX_STATUS(hhcd->Instance, phy_chnum, USB_CH_RX_DIS); + } + else + { + hhcd->hc[ch_num & 0xFU].xfer_buff += received_bytes; + + /* Reactivate the Channel Submit an other URB since the Transfer is not yet completed */ + HCD_SET_CH_RX_STATUS(hhcd->Instance, phy_chnum, USB_CH_RX_STRX); + } +} +#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ + +/** + * @brief Handle Host Channel IN Isochronous Transaction + * @param hhcd HCD handle + * @param ch_num Channel number: This parameter can be a value from 1 to 15 + * @param phy_chnum Physical Channel number [0..7] + * @param regvalue contain Snapshot of the EPCHn register when ISR is detected + * @retval none + */ +static void inline HCD_HC_IN_ISO(HCD_HandleTypeDef *hhcd, uint8_t ch_num, + uint8_t phy_chnum, uint32_t regvalue) +{ + /* Check if Double buffer isochronous */ + if ((regvalue & USB_CH_KIND) != 0U) + { + /* Get Data IN Packet */ + hhcd->hc[ch_num & 0xFU].xfer_count = HCD_GET_CH_RX_CNT(hhcd->Instance, phy_chnum); + if (hhcd->hc[ch_num & 0xFU].xfer_count != 0U) + { + USB_ReadPMA(hhcd->Instance, hhcd->hc[ch_num & 0xFU].xfer_buff, + hhcd->hc[ch_num & 0xFU].pmaadress, + (uint16_t)hhcd->hc[ch_num & 0xFU].xfer_count); + + hhcd->hc[ch_num & 0xFU].urb_state = URB_DONE; + } + } +#if (USE_USB_DOUBLE_BUFFER == 1U) + else /* double buffer isochronous */ + { + /* Read from Buffer0 */ + if ((regvalue & USB_CH_DTOG_RX) != 0U) + { + /* Get number of Received byte in buffer0 */ + hhcd->hc[ch_num & 0xFU].xfer_count = HCD_GET_CH_DBUF0_CNT(hhcd->Instance, phy_chnum); + + if (hhcd->hc[ch_num & 0xFU].xfer_count != 0U) + { + /* Read from Buffer0 */ + USB_ReadPMA(hhcd->Instance, hhcd->hc[ch_num & 0xFU].xfer_buff, + hhcd->hc[ch_num & 0xFU].pmaaddr0, + (uint16_t)hhcd->hc[ch_num & 0xFU].xfer_count); + + hhcd->hc[ch_num & 0xFU].urb_state = URB_DONE; + } + } + else + { + /* Get number of Received byte in buffer1 */ + hhcd->hc[ch_num & 0xFU].xfer_count = HCD_GET_CH_DBUF1_CNT(hhcd->Instance, phy_chnum); + + if (hhcd->hc[ch_num & 0xFU].xfer_count != 0U) + { + /* Read from Buffer1 */ + USB_ReadPMA(hhcd->Instance, hhcd->hc[ch_num & 0xFU].xfer_buff, + hhcd->hc[ch_num & 0xFU].pmaaddr1, + (uint16_t)hhcd->hc[ch_num & 0xFU].xfer_count); + + hhcd->hc[ch_num & 0xFU].urb_state = URB_DONE; + } + } + } +#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ + + /* Transfer complete state */ + hhcd->hc[ch_num & 0xFU].state = HC_XFRC; + + /* Clear VTRX */ + HCD_CLEAR_RX_CH_CTR(hhcd->Instance, phy_chnum); +} + +/** + * @brief Handle Host Channel IN interrupt requests. + * @param hhcd HCD handle + * @param ch_num Channel number + * This parameter can be a value from 1 to 15 + * @retval none + */ +static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t ch_num) +{ + uint16_t received_bytes; + uint8_t phy_chnum = (uint8_t)__HAL_HCD_GET_CHNUM(hhcd); + + /*Take a Flag snapshot from the CHEP register, due to STRX bits are used for both control and status */ + uint32_t ch_reg = HCD_GET_CHANNEL(hhcd->Instance, phy_chnum); + + /* Manage Correct Transaction */ + if ((ch_reg & USB_CH_ERRRX) == 0U) + { + /* Isochronous Channel */ + if ((ch_reg & USB_CH_UTYPE) == USB_EP_ISOCHRONOUS) + { + HCD_HC_IN_ISO(hhcd, ch_num, phy_chnum, ch_reg); + } + else + { + /* manage ACK response single buffer */ + if (((ch_reg) & USB_CH_RX_STRX) == USB_CH_RX_ACK_SBUF) + { + /* Get Control Data OUT Packet */ + received_bytes = (uint16_t)HCD_GET_CH_RX_CNT(hhcd->Instance, phy_chnum); + + /* Read the byte from PMA to user Buffer(System Memory) */ + USB_ReadPMA(hhcd->Instance, hhcd->hc[ch_num & 0xFU].xfer_buff, + hhcd->hc[ch_num & 0xFU].pmaadress, (uint16_t)received_bytes); + + /* update the global number of all received bytes */ + hhcd->hc[ch_num & 0xFU].xfer_count += received_bytes; + + /* Transfer complete state */ + hhcd->hc[ch_num & 0xFU].state = HC_ACK; + hhcd->hc[ch_num & 0xFU].ErrCnt = 0U; + + if (hhcd->hc[ch_num & 0xFU].xfer_len <= received_bytes) + { + hhcd->hc[ch_num & 0xFU].xfer_len = 0U; + } + else + { + hhcd->hc[ch_num & 0xFU].xfer_len -= received_bytes; + } + + if ((hhcd->hc[ch_num & 0xFU].xfer_len == 0U) || + ((received_bytes < hhcd->hc[ch_num & 0xFU].max_packet))) + { + hhcd->hc[ch_num & 0xFU].urb_state = URB_DONE; + hhcd->hc[ch_num & 0xFU].state = HC_XFRC; + } + else + { + hhcd->hc[ch_num & 0xFU].xfer_buff += received_bytes; + + /* Reactivate the Channel to Submit another URB since the Transfer is not yet completed */ + HCD_SET_CH_RX_STATUS(hhcd->Instance, phy_chnum, USB_CH_RX_STRX); + } + + if ((hhcd->hc[ch_num & 0xFU].ep_type == EP_TYPE_BULK) || + (hhcd->hc[ch_num & 0xFU].ep_type == EP_TYPE_INTR)) + { + hhcd->hc[ch_num & 0xFU].toggle_out ^= 1U; + } + } + /* manage NACK Response */ + else if (((ch_reg & USB_CH_RX_STRX) == USB_CH_RX_NAK) + && (hhcd->hc[ch_num & 0xFU].urb_state != URB_DONE)) + { + hhcd->hc[ch_num & 0xFU].urb_state = URB_NOTREADY; + hhcd->hc[ch_num & 0xFU].ErrCnt = 0U; + hhcd->hc[ch_num & 0xFU].state = HC_NAK; + } + /* manage STALL Response */ + else if ((ch_reg & USB_CH_RX_STRX) == USB_CH_RX_STALL) + { + (void)HAL_HCD_HC_Halt(hhcd, ch_num); + hhcd->hc[ch_num & 0xFU].state = HC_STALL; + hhcd->hc[ch_num & 0xFU].urb_state = URB_STALL; + + /* Close the channel */ + HCD_SET_CH_RX_STATUS(hhcd->Instance, phy_chnum, USB_CH_RX_DIS); + } +#if (USE_USB_DOUBLE_BUFFER == 1U) + /* Double Buffer Management in case of Bulk Transaction */ + else if (((ch_reg & USB_CH_RX_STRX) == USB_CH_RX_ACK_DBUF) + && ((ch_reg & USB_CH_KIND) != 0U)) + { + /* Bulk IN Double Buffer ISR */ + HCD_HC_IN_BulkDb(hhcd, ch_num, phy_chnum, ch_reg); + } +#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ + else + { + /*....*/ + /* not defined state: STRX=11 in single buffer no iso is not defined */ + } + +#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) + hhcd->HC_NotifyURBChangeCallback(hhcd, ch_num, hhcd->hc[ch_num & 0xFU].urb_state); +#else + HAL_HCD_HC_NotifyURBChange_Callback(hhcd, ch_num, hhcd->hc[ch_num & 0xFU].urb_state); +#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ + + /*Clear VTRX */ + HCD_CLEAR_RX_CH_CTR(hhcd->Instance, phy_chnum); + } + } + else /* Error detected during last transaction */ + { + /* Set URB Error State */ + hhcd->hc[ch_num & 0xFU].urb_state = URB_NOTREADY; + hhcd->hc[ch_num & 0xFU].ErrCnt++; + hhcd->hc[ch_num & 0xFU].state = HC_XACTERR; + + /* Clear VTTRX & ERR_RX */ + HCD_CLEAR_RX_CH_ERR(hhcd->Instance, phy_chnum); + + /* Check Error number */ + if (hhcd->hc[ch_num & 0xFU].ErrCnt > 3U) + { + hhcd->hc[ch_num & 0xFU].urb_state = URB_ERROR; + HCD_SET_CH_RX_STATUS(hhcd->Instance, phy_chnum, USB_CH_RX_DIS); + + /* Clear pending err_tx */ + HCD_CLEAR_RX_CH_ERR(hhcd->Instance, phy_chnum); + } + +#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) + hhcd->HC_NotifyURBChangeCallback(hhcd, ch_num, hhcd->hc[ch_num & 0xFU].urb_state); +#else + HAL_HCD_HC_NotifyURBChange_Callback(hhcd, ch_num, hhcd->hc[ch_num & 0xFU].urb_state); +#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ + } +} + + +/** + * @brief Handle Host Channel OUT interrupt requests. + * @param hhcd HCD handle + * @param chnum Channel number + * This parameter can be a value from 1 to 15 + * @retval none + */ +static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum) +{ + uint16_t data_xfr; + __IO uint32_t WregCh; + + /* Get Physical Channel number */ + uint32_t phy_chnum = (uint8_t)__HAL_HCD_GET_CHNUM(hhcd); + + /* Take a Flag snapshot from the CHEP register, due to STRX bits are used for both control &status */ + uint32_t ch_reg = *(__IO uint32_t *)(&(hhcd->Instance->CHEP0R) + phy_chnum); + + /*------ Manage Correct Transaction ------*/ + if ((ch_reg & USB_CH_ERRTX) == 0U) + { + /* Handle Isochronous channel */ + if ((ch_reg & USB_CH_UTYPE) == USB_EP_ISOCHRONOUS) + { + /* correct transaction */ + if ((hhcd->Instance->ISTR & USB_ISTR_ERR) == 0U) + { + /* Double buffer isochronous out */ + if ((ch_reg & USB_CH_KIND) != 0U) + { + HCD_SET_CH_TX_CNT(hhcd->Instance, phy_chnum, 0U); + } +#if (USE_USB_DOUBLE_BUFFER == 1U) + else /* double buffer isochronous out */ + { + /* Odd Transaction */ + if ((ch_reg & USB_CH_DTOG_TX) != 0U) + { + HCD_SET_CH_TX_CNT(hhcd->Instance, phy_chnum, 0U); + } + /* Even Transaction */ + else + { + HCD_SET_CH_RX_CNT(hhcd->Instance, phy_chnum, 0U); + } + + USB_DRD_SET_CHEP_TX_STATUS(hhcd->Instance, phy_chnum, USB_CH_TX_DIS); + } +#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ + + /* Transfer complete state */ + hhcd->hc[chnum & 0xFU].state = HC_XFRC; + hhcd->hc[chnum & 0xFU].urb_state = URB_DONE; + } + + /*Clear Correct Transfer */ + HCD_CLEAR_TX_CH_CTR(hhcd->Instance, phy_chnum); + + /*TX COMPLETE*/ +#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) + hhcd->HC_NotifyURBChangeCallback(hhcd, (uint8_t)chnum, hhcd->hc[chnum & 0xFU].urb_state); +#else + HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)chnum, hhcd->hc[chnum & 0xFU].urb_state); +#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ + + } + else /* Manage all Non Isochronous Transaction */ + { + /* Check ACK response */ + if ((ch_reg & USB_CH_TX_STTX) == USB_CH_TX_ACK_SBUF) + { + data_xfr = (uint16_t)(((USB_DRD_PMA_BUFF + phy_chnum)->TXBD & 0x03FF0000U) >> 16U); + + if (hhcd->hc[chnum & 0xFU].xfer_len >= data_xfr) + { + hhcd->hc[chnum & 0xFU].xfer_len -= data_xfr; + } + else + { + hhcd->hc[chnum & 0xFU].xfer_len = 0U; + } + + /* Transfer no yet finished only one packet of mps is transferred and ACKed from device */ + if (hhcd->hc[chnum & 0xFU].xfer_len != 0U) + { + /* manage multiple Xfer */ + hhcd->hc[chnum & 0xFU].xfer_buff += data_xfr; + hhcd->hc[chnum & 0xFU].xfer_count += data_xfr; + + /* start a new transfer */ + (void) USB_HC_StartXfer(hhcd->Instance, &hhcd->hc[chnum & 0xFU]); + } + else + { + /* Transfer complete */ + hhcd->hc[chnum & 0xFU].xfer_count += data_xfr; + hhcd->hc[chnum & 0xFU].state = HC_XFRC; + hhcd->hc[chnum & 0xFU].urb_state = URB_DONE; + + if ((hhcd->hc[chnum & 0xFU].ep_type == EP_TYPE_BULK) || + (hhcd->hc[chnum & 0xFU].ep_type == EP_TYPE_INTR)) + { + hhcd->hc[chnum & 0xFU].toggle_out ^= 1U; + } + } + } + /* Check NACK Response */ + else if (((ch_reg & USB_CHEP_NAK) == USB_CHEP_NAK) || + ((ch_reg & USB_CH_TX_STTX) == USB_CH_TX_NAK)) + { + /* Update Channel status */ + hhcd->hc[chnum & 0xFU].state = HC_NAK; + hhcd->hc[chnum & 0xFU].urb_state = URB_NOTREADY; + hhcd->hc[chnum & 0xFU].ErrCnt = 0U; + + /* Get Channel register value */ + WregCh = *(__IO uint32_t *)(&(hhcd->Instance->CHEP0R) + phy_chnum); + + /*clear NAK status*/ + WregCh &= ~USB_CHEP_NAK & USB_CHEP_REG_MASK; + + /* Update channel register Value */ + HCD_SET_CHANNEL(hhcd->Instance, phy_chnum, WregCh); + + if (hhcd->hc[chnum & 0xFU].doublebuffer == 0U) + { +#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) + hhcd->HC_NotifyURBChangeCallback(hhcd, (uint8_t)chnum, hhcd->hc[chnum & 0xFU].urb_state); +#else + HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)chnum, hhcd->hc[chnum & 0xFU].urb_state); +#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ + } + } + /* Check STALL Response */ + else if ((ch_reg & USB_CH_TX_STTX) == USB_CH_TX_STALL) + { + (void) HAL_HCD_HC_Halt(hhcd, (uint8_t)chnum); + hhcd->hc[chnum & 0xFU].state = HC_STALL; + hhcd->hc[chnum & 0xFU].urb_state = URB_STALL; + } +#if (USE_USB_DOUBLE_BUFFER == 1U) + /* Check double buffer ACK in case of bulk transaction */ + else if ((ch_reg & USB_CH_TX_STTX) == USB_CH_TX_ACK_DBUF) + { + /* Double buffer management Bulk Out */ + (void) HCD_HC_OUT_BulkDb(hhcd, chnum, (uint8_t)phy_chnum, ch_reg); + } +#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ + else + { + /*...*/ + } + + if ((ch_reg & USB_CH_TX_STTX) != USB_CH_TX_NAK) + { +#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) + hhcd->HC_NotifyURBChangeCallback(hhcd, (uint8_t)chnum, hhcd->hc[chnum & 0xFU].urb_state); +#else + HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)chnum, hhcd->hc[chnum & 0xFU].urb_state); +#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ + } + + HCD_CLEAR_TX_CH_CTR(hhcd->Instance, phy_chnum); + } /* end no isochronous */ + } + /*------ Manage Transaction Error------*/ + else + { + hhcd->hc[chnum & 0xFU].ErrCnt++; + if (hhcd->hc[chnum & 0xFU].ErrCnt > 3U) + { + HCD_SET_CH_TX_STATUS(hhcd->Instance, phy_chnum, USB_CH_TX_DIS); + hhcd->hc[chnum & 0xFU].urb_state = URB_ERROR; + } + else + { + hhcd->hc[chnum & 0xFU].urb_state = URB_NOTREADY; + } + + hhcd->hc[chnum & 0xFU].state = HC_XACTERR; + + /*Clear ERR_TX*/ + HCD_CLEAR_TX_CH_ERR(hhcd->Instance, phy_chnum); + +#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) + hhcd->HC_NotifyURBChangeCallback(hhcd, (uint8_t)chnum, hhcd->hc[chnum & 0xFU].urb_state); +#else + HAL_HCD_HC_NotifyURBChange_Callback(hhcd, (uint8_t)chnum, hhcd->hc[chnum & 0xFU].urb_state); +#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ + } +} + + +/** + * @brief Handle Host Port interrupt requests. + * @param hhcd HCD handle + * @retval None + */ +static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd) +{ + uint32_t FnrReg = hhcd->Instance->FNR; + uint32_t IstrReg = hhcd->Instance->ISTR; + + /* SE0 detected USB Disconnected state */ + if ((FnrReg & (USB_FNR_RXDP | USB_FNR_RXDM)) == 0U) + { + /* Host Port State */ + hhcd->HostState = HCD_HCD_STATE_DISCONNECTED; + + /* clear all allocated virtual channel */ + HAL_HCD_ClearPhyChannel(hhcd); + + /* Reset the PMA current pointer */ + (void)HAL_HCD_PMAReset(hhcd); + + /* reset Ep0 Pma allocation state */ + hhcd->ep0_PmaAllocState = 0U; + + /* Disconnection Callback */ +#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) + hhcd->DisconnectCallback(hhcd); +#else + HAL_HCD_Disconnect_Callback(hhcd); +#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ + + return; + } + + if ((hhcd->HostState == HCD_HCD_STATE_DISCONNECTED) != 0U) + { + /* J-state or K-state detected & LastState=Disconnected */ + if (((FnrReg & USB_FNR_RXDP) != 0U) || ((IstrReg & USB_ISTR_LS_DCONN) != 0U)) + { + hhcd->HostState = HCD_HCD_STATE_CONNECTED; + +#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) + hhcd->ConnectCallback(hhcd); +#else + HAL_HCD_Connect_Callback(hhcd); +#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ + } + } + else + { + /* J-state or K-state detected & lastState=Connected: a Missed disconnection is detected */ + if (((FnrReg & USB_FNR_RXDP) != 0U) || ((IstrReg & USB_ISTR_LS_DCONN) != 0U)) + { + /* Host Port State */ + hhcd->HostState = HCD_HCD_STATE_DISCONNECTED; + + /* clear all allocated virtual channel */ + HAL_HCD_ClearPhyChannel(hhcd); + + /* Reset the PMA current pointer */ + (void)HAL_HCD_PMAReset(hhcd); + + /* reset Ep0 PMA allocation state */ + hhcd->ep0_PmaAllocState = 0U; + + /* Disconnection Callback */ +#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U) + hhcd->DisconnectCallback(hhcd); +#else + HAL_HCD_Disconnect_Callback(hhcd); +#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */ + } + } +} + + +/** + * @brief Check if the ch_num are already reserved to a physical channel + * @param hhcd HCD handle + * @param ch_num Channel number + * This parameter can be a value from 1 to 15 + * @retval HAL status + */ +static uint8_t HAL_HCD_Check_usedChannel(HCD_HandleTypeDef const *hhcd, uint8_t ch_num) +{ + uint8_t idx; + + /* Check if the logical channel are already opened */ + for (idx = 0U; idx < hhcd->Init.Host_channels; idx++) + { + if ((((hhcd->phy_chin_state[idx] & 0xF0U) >> 4U) == ((uint16_t)ch_num + 1U)) && + (hhcd->phy_chin_state[idx] != 0U)) + { + return (1U | (idx << 4U)); + } + + if ((((hhcd->phy_chout_state[idx] & 0xF0U) >> 4U) == ((uint16_t)ch_num + 1U)) && + (hhcd->phy_chout_state[idx] != 0U)) + { + return (1U | (idx << 4U)); + } + } + + return 0U; +} + + +/** + * @brief Get a Logical Channel number from physical Channel + * @param hhcd HCD handle + * @param phy_chnum + * This parameter can be a value from 1 to 15 + * @param dir Channel direction + * -0 OUT_Channel + * -1 IN_Channel + * @retval HAL status + */ +static uint8_t HAL_HCD_GetLogical_Channel(HCD_HandleTypeDef const *hhcd, + uint8_t phy_chnum, uint8_t dir) +{ + /* Out Channel Direction */ + if (dir == 0U) + { + if (((hhcd->phy_chout_state[phy_chnum & 0x7U] & 0x00F0U) >> 4U) != 0U) + { + return ((uint8_t)((hhcd->phy_chout_state[phy_chnum & 0x7U] & 0x00F0U) >> 4U) - 1U); + } + else + { + /* Channel not registered Error */ + return HCD_LOGICAL_CH_NOT_OPENED; + } + } + /* IN Channel Direction */ + else + { + if (((hhcd->phy_chin_state[phy_chnum & 0x7U] & 0x00F0U) >> 4U) != 0U) + { + return ((uint8_t)((hhcd->phy_chin_state[phy_chnum & 0x7U] & 0x00F0U) >> 4U) - 1U); + } + else + { + /* Channel not registered Error */ + return HCD_LOGICAL_CH_NOT_OPENED; + } + } +} + + +/** + * @brief Get a free physical Channel number according to the direction + * @param hhcd HCD handle + * @param ch_num Channel number + * This parameter can be a value from 1 to 15 + * @param epnum Endpoint number + * This parameter can be a value from 1 to 15 + * @param ep_type Endpoint Type + * This parameter can be one of these values: + * EP_TYPE_CTRL Control type, + * EP_TYPE_ISOC Isochronous type, + * EP_TYPE_BULK Bulk type, + * EP_TYPE_INTR Interrupt type + * @retval if physical channel is available return Phy_channel number + else return HCD_FREE_CH_NOT_FOUND + */ +static uint8_t HAL_HCD_Get_FreePhyChannel(HCD_HandleTypeDef *hhcd, uint8_t ch_num, + uint8_t epnum, uint8_t ep_type) +{ + uint8_t idx; + + if ((epnum & 0x7FU) == 0U) + { + idx = 0U; + + if (ch_num == 0U) + { + if (hhcd->phy_chin_state[idx] == 0U) + { + /* chin_state to store the ep_type to be used for the same channel in OUT direction + * adding + 1 to ep_type avoid starting with a 0 value. ep_type take by default (0/1/2/3) */ + hhcd->phy_chin_state[idx] = (((uint16_t)ch_num + 1U) << 4U) | + ((uint16_t)ep_type + 1U) | + (((uint16_t)epnum & 0x0FU) << 8U); + } + + if (hhcd->phy_chout_state[idx] == 0U) + { + /* chout_state will store the ep_type to be used for the same channel in IN direction + * adding + 1 to ep_type avoid starting with a 0 value. ep_type take by default (0/1/2/3) */ + hhcd->phy_chout_state[idx] = (((uint16_t)ch_num + 1U) << 4U) | + ((uint16_t)ep_type + 1U) | + (((uint16_t)epnum & 0x0FU) << 8U); + } + } + else + { + if ((epnum & 0x80U) != 0U) + { + if (((hhcd->phy_chin_state[idx] & 0xF0U) >> 4U) != ((uint16_t)ch_num + 1U)) + { + /* chin_state to store the ep_type to be used for the same channel in OUT direction + * adding + 1 to ep_type avoid starting with a 0 value. ep_type take by default (0/1/2/3) */ + hhcd->phy_chin_state[idx] = (((uint16_t)ch_num + 1U) << 4U) | + ((uint16_t)ep_type + 1U) | + (((uint16_t)epnum & 0x0FU) << 8U); + } + } + else + { + if (((hhcd->phy_chout_state[idx] & 0xF0U) >> 4U) != ((uint16_t)ch_num + 1U)) + { + /* chout_state will store the ep_type to be used for the same channel in IN direction + * adding + 1 to ep_type avoid starting with a 0 value. ep_type take by default (0/1/2/3) */ + hhcd->phy_chout_state[idx] = (((uint16_t)ch_num + 1U) << 4U) | + ((uint16_t)ep_type + 1U) | + (((uint16_t)epnum & 0x0FU) << 8U); + } + } + } + + return idx; + } + + if ((epnum & 0x80U) != 0U) + { + /* Find a new available physical in channel */ + for (idx = 1U; idx < hhcd->Init.Host_channels; idx++) + { + /* Check if the same epnum is allocated then allocate the same physical channel OUT for IN Logical Channel */ + if ((hhcd->phy_chin_state[idx] == 0U) && + ((((hhcd->phy_chout_state[idx] & 0x000FU) == ((uint16_t)ep_type + 1U)) && + (((hhcd->phy_chout_state[idx] & 0x0F00U) == ((uint16_t)epnum & 0x0FU)))) || + (hhcd->phy_chout_state[idx] == 0U))) + { + /* chin_state to store the ep_type to be used for the same channel in OUT direction + * adding + 1 to ep_type avoid starting with a 0 value. ep_type take by default (0/1/2/3) */ + hhcd->phy_chin_state[idx] = (((uint16_t)ch_num + 1U) << 4U) | + ((uint16_t)ep_type + 1U) | + (((uint16_t)epnum & 0x0FU) << 8U); + + return idx; + } + } + } + else + { + /* Find a new available physical out channel */ + for (idx = 1U; idx < hhcd->Init.Host_channels; idx++) + { + /* Check if the same epnum is allocated then allocate the same physical channel IN for OUT Logical Channel */ + if ((hhcd->phy_chout_state[idx] == 0U) && + ((((hhcd->phy_chin_state[idx] & 0x0FU) == ((uint16_t)ep_type + 1U)) && + ((hhcd->phy_chin_state[idx] & 0x0F00U) == ((uint16_t)epnum & 0x0FU))) || + (hhcd->phy_chin_state[idx] == 0U))) + { + /* chout_state will store the ep_type to be used for the same channel in IN direction + * adding + 1 to ep_type avoid starting with a 0 value. ep_type take by default (0/1/2/3) */ + hhcd->phy_chout_state[idx] = (((uint16_t)ch_num + 1U) << 4U) | + ((uint16_t)ep_type + 1U) | + (((uint16_t)epnum & 0x0FU) << 8U); + + return idx; + } + } + } + + /* in case of Error */ + return HCD_FREE_CH_NOT_FOUND; +} + +/** + * @brief Free All Channel allocation + * @param hhcd HCD handle + * @retval HAL status + */ +static void HAL_HCD_ClearPhyChannel(HCD_HandleTypeDef *hhcd) +{ + uint8_t idx; + + for (idx = 0U; idx < hhcd->Init.Host_channels; idx++) + { + /*Reset channel allocation value */ + hhcd->phy_chout_state[idx] = 0U; + hhcd->phy_chin_state[idx] = 0U; + } +} + +/*---------------------- PMA Allocation Section --------------------- */ +/* + __col31________________col0__ Column-- > + lin0 | entry31.|....... | entry0 | Line + |---------|---------|--------| | + line1| entry63.|....... | entry32| | + |---------|---------|--------| \|/ + | entry127|....... | entry64| + |---------|---------|--------| + | entry256|...... |entry128| + ---------------------------- + an allocation space of 64byte need 8 Free contiguous Entry in the Matrix + - a Free Entry is a bit with 0 Value/ a busy entry is a bit with 1 value. */ + +/** + * @brief Fetch in the PMA_LockupTable free space of number of mps byte + * @param hhcd Host instance + * @param mps Channel Max Packet Size + * @retval PMA_Address of the first free block containing mps byte + 0xFFFF in case of no space available + */ +static uint16_t HAL_HCD_GetFreePMA(HCD_HandleTypeDef *hhcd, uint16_t mps) +{ + uint32_t Entry; + uint32_t FreeBlocks = 0U; + uint8_t FirstFreeBlock_col = 0U; + uint8_t FirstFreeBlock_line = 0U; + uint8_t ColIndex; + uint16_t NbrReqBlocks; + uint16_t mps_t = mps; + + /* since PMA buffer descriptor RXBD allocate address according to BLSIZE, BLSIZE=1==> mps>64 + allocation in PMA is done in 32Bytes each entry */ + if ((mps_t > 64U) && ((mps_t % 32U) != 0U)) + { + /* Align the mps to 32byte block to match the allocation in PMA, + check Definition of allocation buffer memory in usb user spec */ + mps_t = (uint16_t)(((mps_t / 32U) + 1U) * 32U); + } + + /* calculate the number of block(8byte) to allocate */ + NbrReqBlocks = mps_t / 8U; + + /* check if we need remaining Block */ + if ((mps_t % 8U) != 0U) + { + NbrReqBlocks++; + } + + /* Look For NbrReqBlocks * Empty Block */ + for (uint8_t i = 0U; ((i < PMA_BLOCKS) && (FreeBlocks != NbrReqBlocks)); i++) + { + Entry = hhcd->PMALookupTable[i]; + + /* when parse is in progress, check the first col to look for a contiguous block */ + if ((FreeBlocks != 0U) && ((Entry & (uint32_t)1U) != 0U)) + { + FreeBlocks = 0U; + } + uint8_t j = 0U; + while ((j <= 31U) && (FreeBlocks != NbrReqBlocks)) + { + /* check if block j is free */ + if ((Entry & ((uint32_t)1U << j)) == 0U) + { + if (FreeBlocks == 0U) + { + FirstFreeBlock_col = j; + FirstFreeBlock_line = i; + FreeBlocks++; + } + j++; + + /* Parse Column PMALockTable */ + while ((j <= 31U) && ((Entry & ((uint32_t)1U << j)) == 0U) && (FreeBlocks < NbrReqBlocks)) + { + FreeBlocks++; + j++; + } + + /* Free contiguous Blocks not found */ + if (((FreeBlocks < NbrReqBlocks) && (j < 31U)) || + ((j == 31U) && ((Entry & ((uint32_t)1U << j)) != 0U))) + { + FreeBlocks = 0U; + } + } + j++; + } /* end for j */ + } /* end for i */ + + /* Free block found */ + if (FreeBlocks >= NbrReqBlocks) + { + ColIndex = FirstFreeBlock_col; + + for (uint8_t i = FirstFreeBlock_line; ((i < PMA_BLOCKS) && (FreeBlocks > 0U)); i++) + { + for (uint8_t j = ColIndex; j <= 31U; j++) + { + hhcd->PMALookupTable[i] |= ((uint32_t)1U << j); + if (--FreeBlocks == 0U) + { + break; + } + } + ColIndex = 0U; + } + + return (uint16_t)((FirstFreeBlock_line * (uint16_t)256U) + (FirstFreeBlock_col * (uint16_t)8U)); + } + else + { + return 0xFFFFU; + } +} + +/** + * @brief Allocate PMA buffer for Channel + * This API will fetch a free space + * @param hhcd Host instance + * @param ch_num Channel number + * @param ch_kind endpoint Kind + * USB_SNG_BUF Single Buffer used + * USB_DBL_BUF Double Buffer used + * @param mps Channel Max Packet Size + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HCD_PMAlloc(HCD_HandleTypeDef *hhcd, uint8_t ch_num, + uint16_t ch_kind, uint16_t mps) +{ + uint16_t pma_addr0; +#if (USE_USB_DOUBLE_BUFFER == 1U) + uint16_t pma_addr1; /* used for double buffer mode if enabled */ +#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ + + /* Host Channel */ + HCD_HCTypeDef *hc = &(hhcd->hc[ch_num]); + + /* Get a FreePMA Address */ + pma_addr0 = HAL_HCD_GetFreePMA(hhcd, mps); + + /* if there is no free space to allocate */ + if (pma_addr0 == 0xFFFFU) + { + return HAL_ERROR; + } + else + { + /* Here we check if the endpoint is single or double Buffer */ + if (ch_kind == HCD_SNG_BUF) + { + /* Single Buffer */ + hc->doublebuffer = 0U; + + if (hc->ep_num == 0U) + { + hhcd->ep0_PmaAllocState = ch_num; + hhcd->ep0_PmaAllocState |= (1U << 8); + } + + /* Configure the PMA */ + if (hc->ch_dir == CH_IN_DIR) + { + hc->pmaaddr1 = pma_addr0; + (USB_DRD_PMA_BUFF + hc->phy_ch_num)->RXBD = hc->pmaaddr1; + + if (hc->ep_num == 0U) + { + hhcd->ep0_PmaAllocState |= (CH_IN_DIR << 4); + } + } + else + { + hc->pmaaddr0 = pma_addr0; + (USB_DRD_PMA_BUFF + hc->phy_ch_num)->TXBD = hc->pmaaddr0; + } + + /* Set the PmaAddress */ + hc->pmaadress = pma_addr0; + } +#if (USE_USB_DOUBLE_BUFFER == 1U) + else /* USB_DBL_BUF */ + { + /* Double Buffer Endpoint */ + hc->doublebuffer = 1U; + + /* Get a FreePMA Address for buffer 2 */ + pma_addr1 = HAL_HCD_GetFreePMA(hhcd, mps); + + if (pma_addr1 == 0xFFFFU) + { + /* Free the first buffer */ + (void)HAL_HCD_PMAFree(hhcd, pma_addr0, mps); + return HAL_ERROR; + } + else + { + /* Configure the PMA */ + hc->pmaaddr0 = (uint16_t)(pma_addr0); + hc->pmaaddr1 = (uint16_t)(pma_addr1); + + /* Set Buffer0 pma address */ + (USB_DRD_PMA_BUFF + hc->phy_ch_num)->TXBD = pma_addr0; + + /* Set Buffer1 pma address */ + (USB_DRD_PMA_BUFF + hc->phy_ch_num)->RXBD = pma_addr1; + + /* Used for Bulk DB MPS < 64bytes */ + if (hc->ch_dir == CH_IN_DIR) + { + hc->pmaadress = hc->pmaaddr1; + } + else + { + hc->pmaadress = hc->pmaaddr0; + } + } + } +#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ + } + + return HAL_OK; +} + +/** + * @brief PMA De-Allocation for Channel Free the reserved block in the PMA-LookupTable + * @param hhcd Host instance + * @param ch_num Channel number + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HCD_PMADeAlloc(HCD_HandleTypeDef *hhcd, uint8_t ch_num) +{ + HAL_StatusTypeDef status; + +#if (USE_USB_DOUBLE_BUFFER == 1U) + uint8_t Err = 0U; +#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ + + /* Host Channel */ + HCD_HCTypeDef *hc = &(hhcd->hc[ch_num]); + + /* Single Buffer */ + if (hc->doublebuffer == 0U) + { + status = HAL_HCD_PMAFree(hhcd, hc->pmaadress, hc->max_packet); + } + else /* Double buffer */ + { +#if (USE_USB_DOUBLE_BUFFER == 1U) + status = HAL_HCD_PMAFree(hhcd, hc->pmaaddr0, hc->max_packet); + if (status != HAL_OK) + { + Err++; + } + + status = HAL_HCD_PMAFree(hhcd, hc->pmaaddr1, hc->max_packet); + if (status != HAL_OK) + { + Err++; + } + + if (Err != 0U) + { + return HAL_ERROR; + } +#else + status = HAL_ERROR; +#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ + } + + return status; +} + + +/** + * @brief PMA Reset + * @param hhcd Host instance + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HCD_PMAReset(HCD_HandleTypeDef *hhcd) +{ + /* Reset All PMA Entry */ + for (uint8_t i = 0U; i < PMA_BLOCKS; i++) + { + hhcd->PMALookupTable[i] = 0U; + } + + /* Allocate a Space for buffer descriptor table depending on the Host channel number */ + for (uint8_t i = 0U; i < hhcd->Init.Host_channels; i++) + { + hhcd->PMALookupTable[0] |= ((uint32_t)1U << i); + } + + return HAL_OK; +} + +/** + * @brief PMA Free + * @param hhcd Host instance + * @param pma_base PMA base offset stored in hhcd->hc.pmaaddr + * @param mps Max Packet Size + * @retval HAL status + */ +static HAL_StatusTypeDef HAL_HCD_PMAFree(HCD_HandleTypeDef *hhcd, uint32_t pma_base, uint16_t mps) +{ + uint32_t block_nbr; + uint8_t ColIndex; + uint8_t LineIndex; + uint16_t mps_t = mps; + + /* since PMA buffer descriptor RXBD allocate address according to BLSIZE, BLSIZE=1==> mps>64 + allocation in PMA is done in 32Bytes each entry */ + if ((mps_t > 64U) && ((mps_t % 32U) != 0U)) + { + /* Align the mps to 32byte block to match the allocation in PMA, + check Definition of allocation buffer memory in usb user spec */ + mps_t = (uint16_t)(((mps_t / 32U) + 1U) * 32U); + } + + /* Calculate the number of needed block to Free */ + if ((mps_t / 8U) != 0U) + { + block_nbr = ((uint32_t)mps_t / 8U); + + if ((mps_t % 8U) != 0U) + { + block_nbr++; + } + } + else + { + block_nbr = 1U; + } + + /* Decode Col/Line of PMA_Base position in the PMA_LookupTable */ + if (pma_base > 256U) + { + LineIndex = (uint8_t)(pma_base / 256U); + ColIndex = (uint8_t)((pma_base - ((uint32_t)LineIndex * 256U)) / 8U); + } + else + { + LineIndex = 0U; + ColIndex = (uint8_t)(pma_base / 8U); + } + + /* Reset the corresponding bit in the lookupTable */ + for (uint8_t i = LineIndex; ((i < PMA_BLOCKS) && (block_nbr > 0U)); i++) + { + for (uint8_t j = ColIndex; j <= 31U; j++) + { + /* Check if the block is not already reserved or it was already closed */ + if ((hhcd->PMALookupTable[i] & ((uint32_t)1U << j)) == 0U) + { + return HAL_ERROR; + } + /* Free the reserved block by resetting the corresponding bit */ + hhcd->PMALookupTable[i] &= ~(1U << j); + + if (--block_nbr == 0U) + { + break; + } + } + ColIndex = 0U; + } + + return HAL_OK; +} + +/** + * @} + */ + +/** + * @} + */ +#endif /* defined (USB_DRD_FS) */ +#endif /* HAL_HCD_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_i2c.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_i2c.c new file mode 100644 index 0000000000..27673574c2 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_i2c.c @@ -0,0 +1,7719 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_i2c.c + * @author MCD Application Team + * @brief I2C HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Inter Integrated Circuit (I2C) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral State and Errors functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The I2C HAL driver can be used as follows: + + (#) Declare a I2C_HandleTypeDef handle structure, for example: + I2C_HandleTypeDef hi2c; + + (#)Initialize the I2C low level resources by implementing the HAL_I2C_MspInit() API: + (##) Enable the I2Cx interface clock + (##) I2C pins configuration + (+++) Enable the clock for the I2C GPIOs + (+++) Configure I2C pins as alternate function open-drain + (##) NVIC configuration if you need to use interrupt process + (+++) Configure the I2Cx interrupt priority + (+++) Enable the NVIC I2C IRQ Channel + (##) DMA Configuration if you need to use DMA process + (+++) Declare a DMA_HandleTypeDef handle structure for + the transmit or receive channel + (+++) Enable the DMAx interface clock using + (+++) Configure the DMA handle parameters + (+++) Configure the DMA Tx or Rx channel + (+++) Associate the initialized DMA handle to the hi2c DMA Tx or Rx handle + (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on + the DMA Tx or Rx channel + + (#) Configure the Communication Clock Timing, Own Address1, Master Addressing mode, Dual Addressing mode, + Own Address2, Own Address2 Mask, General call and Nostretch mode in the hi2c Init structure. + + (#) Initialize the I2C registers by calling the HAL_I2C_Init(), configures also the low level Hardware + (GPIO, CLOCK, NVIC...etc) by calling the customized HAL_I2C_MspInit(&hi2c) API. + + (#) To check if target device is ready for communication, use the function HAL_I2C_IsDeviceReady() + + (#) For I2C IO and IO MEM operations, three operation modes are available within this driver : + + *** Polling mode IO operation *** + ================================= + [..] + (+) Transmit in master mode an amount of data in blocking mode using HAL_I2C_Master_Transmit() + (+) Receive in master mode an amount of data in blocking mode using HAL_I2C_Master_Receive() + (+) Transmit in slave mode an amount of data in blocking mode using HAL_I2C_Slave_Transmit() + (+) Receive in slave mode an amount of data in blocking mode using HAL_I2C_Slave_Receive() + + *** Polling mode IO MEM operation *** + ===================================== + [..] + (+) Write an amount of data in blocking mode to a specific memory address using HAL_I2C_Mem_Write() + (+) Read an amount of data in blocking mode from a specific memory address using HAL_I2C_Mem_Read() + + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Transmit in master mode an amount of data in non-blocking mode using HAL_I2C_Master_Transmit_IT() + (+) At transmission end of transfer, HAL_I2C_MasterTxCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_I2C_MasterTxCpltCallback() + (+) Receive in master mode an amount of data in non-blocking mode using HAL_I2C_Master_Receive_IT() + (+) At reception end of transfer, HAL_I2C_MasterRxCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_I2C_MasterRxCpltCallback() + (+) Transmit in slave mode an amount of data in non-blocking mode using HAL_I2C_Slave_Transmit_IT() + (+) At transmission end of transfer, HAL_I2C_SlaveTxCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback() + (+) Receive in slave mode an amount of data in non-blocking mode using HAL_I2C_Slave_Receive_IT() + (+) At reception end of transfer, HAL_I2C_SlaveRxCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback() + (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and users can + add their own code by customization of function pointer HAL_I2C_ErrorCallback() + (+) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT() + (+) End of abort process, HAL_I2C_AbortCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_I2C_AbortCpltCallback() + (+) Discard a slave I2C process communication using __HAL_I2C_GENERATE_NACK() macro. + This action will inform Master to generate a Stop condition to discard the communication. + + + *** Interrupt mode or DMA mode IO sequential operation *** + ========================================================== + [..] + (@) These interfaces allow to manage a sequential transfer with a repeated start condition + when a direction change during transfer + [..] + (+) A specific option field manage the different steps of a sequential transfer + (+) Option field values are defined through I2C_XFEROPTIONS and are listed below: + (++) I2C_FIRST_AND_LAST_FRAME: No sequential usage, functional is same as associated interfaces in + no sequential mode + (++) I2C_FIRST_FRAME: Sequential usage, this option allow to manage a sequence with start condition, address + and data to transfer without a final stop condition + (++) I2C_FIRST_AND_NEXT_FRAME: Sequential usage (Master only), this option allow to manage a sequence with + start condition, address and data to transfer without a final stop condition, + an then permit a call the same master sequential interface several times + (like HAL_I2C_Master_Seq_Transmit_IT() then HAL_I2C_Master_Seq_Transmit_IT() + or HAL_I2C_Master_Seq_Transmit_DMA() then HAL_I2C_Master_Seq_Transmit_DMA()) + (++) I2C_NEXT_FRAME: Sequential usage, this option allow to manage a sequence with a restart condition, address + and with new data to transfer if the direction change or manage only the new data to + transfer + if no direction change and without a final stop condition in both cases + (++) I2C_LAST_FRAME: Sequential usage, this option allow to manage a sequance with a restart condition, address + and with new data to transfer if the direction change or manage only the new data to + transfer + if no direction change and with a final stop condition in both cases + (++) I2C_LAST_FRAME_NO_STOP: Sequential usage (Master only), this option allow to manage a restart condition + after several call of the same master sequential interface several times + (link with option I2C_FIRST_AND_NEXT_FRAME). + Usage can, transfer several bytes one by one using + HAL_I2C_Master_Seq_Transmit_IT + or HAL_I2C_Master_Seq_Receive_IT + or HAL_I2C_Master_Seq_Transmit_DMA + or HAL_I2C_Master_Seq_Receive_DMA + with option I2C_FIRST_AND_NEXT_FRAME then I2C_NEXT_FRAME. + Then usage of this option I2C_LAST_FRAME_NO_STOP at the last Transmit or + Receive sequence permit to call the opposite interface Receive or Transmit + without stopping the communication and so generate a restart condition. + (++) I2C_OTHER_FRAME: Sequential usage (Master only), this option allow to manage a restart condition after + each call of the same master sequential + interface. + Usage can, transfer several bytes one by one with a restart with slave address between + each bytes using + HAL_I2C_Master_Seq_Transmit_IT + or HAL_I2C_Master_Seq_Receive_IT + or HAL_I2C_Master_Seq_Transmit_DMA + or HAL_I2C_Master_Seq_Receive_DMA + with option I2C_FIRST_FRAME then I2C_OTHER_FRAME. + Then usage of this option I2C_OTHER_AND_LAST_FRAME at the last frame to help automatic + generation of STOP condition. + + (+) Different sequential I2C interfaces are listed below: + (++) Sequential transmit in master I2C mode an amount of data in non-blocking mode using + HAL_I2C_Master_Seq_Transmit_IT() or using HAL_I2C_Master_Seq_Transmit_DMA() + (+++) At transmission end of current frame transfer, HAL_I2C_MasterTxCpltCallback() is executed and + users can add their own code by customization of function pointer HAL_I2C_MasterTxCpltCallback() + (++) Sequential receive in master I2C mode an amount of data in non-blocking mode using + HAL_I2C_Master_Seq_Receive_IT() or using HAL_I2C_Master_Seq_Receive_DMA() + (+++) At reception end of current frame transfer, HAL_I2C_MasterRxCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_I2C_MasterRxCpltCallback() + (++) Abort a master IT or DMA I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT() + (+++) End of abort process, HAL_I2C_AbortCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_I2C_AbortCpltCallback() + (++) Enable/disable the Address listen mode in slave I2C mode using HAL_I2C_EnableListen_IT() + HAL_I2C_DisableListen_IT() + (+++) When address slave I2C match, HAL_I2C_AddrCallback() is executed and users can + add their own code to check the Address Match Code and the transmission direction request by master + (Write/Read). + (+++) At Listen mode end HAL_I2C_ListenCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_I2C_ListenCpltCallback() + (++) Sequential transmit in slave I2C mode an amount of data in non-blocking mode using + HAL_I2C_Slave_Seq_Transmit_IT() or using HAL_I2C_Slave_Seq_Transmit_DMA() + (+++) At transmission end of current frame transfer, HAL_I2C_SlaveTxCpltCallback() is executed and + users can add their own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback() + (++) Sequential receive in slave I2C mode an amount of data in non-blocking mode using + HAL_I2C_Slave_Seq_Receive_IT() or using HAL_I2C_Slave_Seq_Receive_DMA() + (+++) At reception end of current frame transfer, HAL_I2C_SlaveRxCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback() + (++) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and users can + add their own code by customization of function pointer HAL_I2C_ErrorCallback() + (++) Discard a slave I2C process communication using __HAL_I2C_GENERATE_NACK() macro. + This action will inform Master to generate a Stop condition to discard the communication. + + *** Interrupt mode IO MEM operation *** + ======================================= + [..] + (+) Write an amount of data in non-blocking mode with Interrupt to a specific memory address using + HAL_I2C_Mem_Write_IT() + (+) At Memory end of write transfer, HAL_I2C_MemTxCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_I2C_MemTxCpltCallback() + (+) Read an amount of data in non-blocking mode with Interrupt from a specific memory address using + HAL_I2C_Mem_Read_IT() + (+) At Memory end of read transfer, HAL_I2C_MemRxCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_I2C_MemRxCpltCallback() + (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and users can + add their own code by customization of function pointer HAL_I2C_ErrorCallback() + + *** DMA mode IO operation *** + ============================== + [..] + (+) Transmit in master mode an amount of data in non-blocking mode (DMA) using + HAL_I2C_Master_Transmit_DMA() + (+) At transmission end of transfer, HAL_I2C_MasterTxCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_I2C_MasterTxCpltCallback() + (+) Receive in master mode an amount of data in non-blocking mode (DMA) using + HAL_I2C_Master_Receive_DMA() + (+) At reception end of transfer, HAL_I2C_MasterRxCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_I2C_MasterRxCpltCallback() + (+) Transmit in slave mode an amount of data in non-blocking mode (DMA) using + HAL_I2C_Slave_Transmit_DMA() + (+) At transmission end of transfer, HAL_I2C_SlaveTxCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback() + (+) Receive in slave mode an amount of data in non-blocking mode (DMA) using + HAL_I2C_Slave_Receive_DMA() + (+) At reception end of transfer, HAL_I2C_SlaveRxCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback() + (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and users can + add their own code by customization of function pointer HAL_I2C_ErrorCallback() + (+) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT() + (+) End of abort process, HAL_I2C_AbortCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_I2C_AbortCpltCallback() + (+) Discard a slave I2C process communication using __HAL_I2C_GENERATE_NACK() macro. + This action will inform Master to generate a Stop condition to discard the communication. + + *** DMA mode IO MEM operation *** + ================================= + [..] + (+) Write an amount of data in non-blocking mode with DMA to a specific memory address using + HAL_I2C_Mem_Write_DMA() + (+) At Memory end of write transfer, HAL_I2C_MemTxCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_I2C_MemTxCpltCallback() + (+) Read an amount of data in non-blocking mode with DMA from a specific memory address using + HAL_I2C_Mem_Read_DMA() + (+) At Memory end of read transfer, HAL_I2C_MemRxCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_I2C_MemRxCpltCallback() + (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and users can + add their own code by customization of function pointer HAL_I2C_ErrorCallback() + + + *** I2C HAL driver macros list *** + ================================== + [..] + Below the list of most used macros in I2C HAL driver. + + (+) __HAL_I2C_ENABLE: Enable the I2C peripheral + (+) __HAL_I2C_DISABLE: Disable the I2C peripheral + (+) __HAL_I2C_GENERATE_NACK: Generate a Non-Acknowledge I2C peripheral in Slave mode + (+) __HAL_I2C_GET_FLAG: Check whether the specified I2C flag is set or not + (+) __HAL_I2C_CLEAR_FLAG: Clear the specified I2C pending flag + (+) __HAL_I2C_ENABLE_IT: Enable the specified I2C interrupt + (+) __HAL_I2C_DISABLE_IT: Disable the specified I2C interrupt + + *** Callback registration *** + ============================================= + [..] + The compilation flag USE_HAL_I2C_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + Use Functions HAL_I2C_RegisterCallback() or HAL_I2C_RegisterAddrCallback() + to register an interrupt callback. + [..] + Function HAL_I2C_RegisterCallback() allows to register following callbacks: + (+) MasterTxCpltCallback : callback for Master transmission end of transfer. + (+) MasterRxCpltCallback : callback for Master reception end of transfer. + (+) SlaveTxCpltCallback : callback for Slave transmission end of transfer. + (+) SlaveRxCpltCallback : callback for Slave reception end of transfer. + (+) ListenCpltCallback : callback for end of listen mode. + (+) MemTxCpltCallback : callback for Memory transmission end of transfer. + (+) MemRxCpltCallback : callback for Memory reception end of transfer. + (+) ErrorCallback : callback for error detection. + (+) AbortCpltCallback : callback for abort completion process. + (+) MspInitCallback : callback for Msp Init. + (+) MspDeInitCallback : callback for Msp DeInit. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + [..] + For specific callback AddrCallback use dedicated register callbacks : HAL_I2C_RegisterAddrCallback(). + [..] + Use function HAL_I2C_UnRegisterCallback to reset a callback to the default + weak function. + HAL_I2C_UnRegisterCallback takes as parameters the HAL peripheral handle, + and the Callback ID. + This function allows to reset following callbacks: + (+) MasterTxCpltCallback : callback for Master transmission end of transfer. + (+) MasterRxCpltCallback : callback for Master reception end of transfer. + (+) SlaveTxCpltCallback : callback for Slave transmission end of transfer. + (+) SlaveRxCpltCallback : callback for Slave reception end of transfer. + (+) ListenCpltCallback : callback for end of listen mode. + (+) MemTxCpltCallback : callback for Memory transmission end of transfer. + (+) MemRxCpltCallback : callback for Memory reception end of transfer. + (+) ErrorCallback : callback for error detection. + (+) AbortCpltCallback : callback for abort completion process. + (+) MspInitCallback : callback for Msp Init. + (+) MspDeInitCallback : callback for Msp DeInit. + [..] + For callback AddrCallback use dedicated register callbacks : HAL_I2C_UnRegisterAddrCallback(). + [..] + By default, after the HAL_I2C_Init() and when the state is HAL_I2C_STATE_RESET + all callbacks are set to the corresponding weak functions: + examples HAL_I2C_MasterTxCpltCallback(), HAL_I2C_MasterRxCpltCallback(). + Exception done for MspInit and MspDeInit functions that are + reset to the legacy weak functions in the HAL_I2C_Init()/ HAL_I2C_DeInit() only when + these callbacks are null (not registered beforehand). + If MspInit or MspDeInit are not null, the HAL_I2C_Init()/ HAL_I2C_DeInit() + keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state. + [..] + Callbacks can be registered/unregistered in HAL_I2C_STATE_READY state only. + Exception done MspInit/MspDeInit functions that can be registered/unregistered + in HAL_I2C_STATE_READY or HAL_I2C_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_I2C_RegisterCallback() before calling HAL_I2C_DeInit() + or HAL_I2C_Init() function. + [..] + When the compilation flag USE_HAL_I2C_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. + + [..] + (@) You can refer to the I2C HAL driver header file for more useful macros + + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup I2C I2C + * @brief I2C HAL module driver + * @{ + */ + +#ifdef HAL_I2C_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/** @defgroup I2C_Private_Define I2C Private Define + * @{ + */ +#define TIMING_CLEAR_MASK (0xF0FFFFFFU) /*!< I2C TIMING clear register Mask */ +#define I2C_TIMEOUT_ADDR (10000U) /*!< 10 s */ +#define I2C_TIMEOUT_BUSY (25U) /*!< 25 ms */ +#define I2C_TIMEOUT_DIR (25U) /*!< 25 ms */ +#define I2C_TIMEOUT_RXNE (25U) /*!< 25 ms */ +#define I2C_TIMEOUT_STOPF (25U) /*!< 25 ms */ +#define I2C_TIMEOUT_TC (25U) /*!< 25 ms */ +#define I2C_TIMEOUT_TCR (25U) /*!< 25 ms */ +#define I2C_TIMEOUT_TXIS (25U) /*!< 25 ms */ +#define I2C_TIMEOUT_FLAG (25U) /*!< 25 ms */ + +#define MAX_NBYTE_SIZE 255U +#define SLAVE_ADDR_SHIFT 7U +#define SLAVE_ADDR_MSK 0x06U + +/* Private define for @ref PreviousState usage */ +#define I2C_STATE_MSK ((uint32_t)((uint32_t)((uint32_t)HAL_I2C_STATE_BUSY_TX | \ + (uint32_t)HAL_I2C_STATE_BUSY_RX) & \ + (uint32_t)(~((uint32_t)HAL_I2C_STATE_READY)))) +/*!< Mask State define, keep only RX and TX bits */ +#define I2C_STATE_NONE ((uint32_t)(HAL_I2C_MODE_NONE)) +/*!< Default Value */ +#define I2C_STATE_MASTER_BUSY_TX ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | \ + (uint32_t)HAL_I2C_MODE_MASTER)) +/*!< Master Busy TX, combinaison of State LSB and Mode enum */ +#define I2C_STATE_MASTER_BUSY_RX ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | \ + (uint32_t)HAL_I2C_MODE_MASTER)) +/*!< Master Busy RX, combinaison of State LSB and Mode enum */ +#define I2C_STATE_SLAVE_BUSY_TX ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | \ + (uint32_t)HAL_I2C_MODE_SLAVE)) +/*!< Slave Busy TX, combinaison of State LSB and Mode enum */ +#define I2C_STATE_SLAVE_BUSY_RX ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | \ + (uint32_t)HAL_I2C_MODE_SLAVE)) +/*!< Slave Busy RX, combinaison of State LSB and Mode enum */ +#define I2C_STATE_MEM_BUSY_TX ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | \ + (uint32_t)HAL_I2C_MODE_MEM)) +/*!< Memory Busy TX, combinaison of State LSB and Mode enum */ +#define I2C_STATE_MEM_BUSY_RX ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | \ + (uint32_t)HAL_I2C_MODE_MEM)) +/*!< Memory Busy RX, combinaison of State LSB and Mode enum */ + + +/* Private define to centralize the enable/disable of Interrupts */ +#define I2C_XFER_TX_IT (uint16_t)(0x0001U) /*!< Bit field can be combinated with + @ref I2C_XFER_LISTEN_IT */ +#define I2C_XFER_RX_IT (uint16_t)(0x0002U) /*!< Bit field can be combinated with + @ref I2C_XFER_LISTEN_IT */ +#define I2C_XFER_LISTEN_IT (uint16_t)(0x8000U) /*!< Bit field can be combinated with @ref I2C_XFER_TX_IT + and @ref I2C_XFER_RX_IT */ + +#define I2C_XFER_ERROR_IT (uint16_t)(0x0010U) /*!< Bit definition to manage addition of global Error + and NACK treatment */ +#define I2C_XFER_CPLT_IT (uint16_t)(0x0020U) /*!< Bit definition to manage only STOP evenement */ +#define I2C_XFER_RELOAD_IT (uint16_t)(0x0040U) /*!< Bit definition to manage only Reload of NBYTE */ + +/* Private define Sequential Transfer Options default/reset value */ +#define I2C_NO_OPTION_FRAME (0xFFFF0000U) +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup I2C_Private_Macro + * @{ + */ +#if defined(HAL_DMA_MODULE_ENABLED) +/* Macro to get remaining data to transfer on DMA side */ +#define I2C_GET_DMA_REMAIN_DATA(__HANDLE__) (__HAL_DMA_GET_COUNTER(__HANDLE__) + HAL_DMAEx_GetFifoLevel(__HANDLE__)) +#endif /* HAL_DMA_MODULE_ENABLED */ +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ + +/** @defgroup I2C_Private_Functions I2C Private Functions + * @{ + */ +#if defined(HAL_DMA_MODULE_ENABLED) +/* Private functions to handle DMA transfer */ +static void I2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma); +static void I2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma); +static void I2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma); +static void I2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma); +static void I2C_DMAError(DMA_HandleTypeDef *hdma); +static void I2C_DMAAbort(DMA_HandleTypeDef *hdma); + +#endif /* HAL_DMA_MODULE_ENABLED */ + +/* Private functions to handle IT transfer */ +static void I2C_ITAddrCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags); +static void I2C_ITMasterSeqCplt(I2C_HandleTypeDef *hi2c); +static void I2C_ITSlaveSeqCplt(I2C_HandleTypeDef *hi2c); +static void I2C_ITMasterCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags); +static void I2C_ITSlaveCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags); +static void I2C_ITListenCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags); +static void I2C_ITError(I2C_HandleTypeDef *hi2c, uint32_t ErrorCode); + +/* Private functions to handle IT transfer */ +static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, + uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, + uint32_t Tickstart); +static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, + uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, + uint32_t Tickstart); + +/* Private functions for I2C transfer IRQ handler */ +static HAL_StatusTypeDef I2C_Master_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, + uint32_t ITSources); +static HAL_StatusTypeDef I2C_Mem_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, + uint32_t ITSources); +static HAL_StatusTypeDef I2C_Slave_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, + uint32_t ITSources); +#if defined(HAL_DMA_MODULE_ENABLED) +static HAL_StatusTypeDef I2C_Master_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, + uint32_t ITSources); +static HAL_StatusTypeDef I2C_Mem_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, + uint32_t ITSources); +static HAL_StatusTypeDef I2C_Slave_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, + uint32_t ITSources); +#endif /* HAL_DMA_MODULE_ENABLED */ + +/* Private functions to handle flags during polling transfer */ +static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, + uint32_t Timeout, uint32_t Tickstart); +static HAL_StatusTypeDef I2C_WaitOnTXISFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, + uint32_t Tickstart); +static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, + uint32_t Tickstart); +static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, + uint32_t Tickstart); +static HAL_StatusTypeDef I2C_IsErrorOccurred(I2C_HandleTypeDef *hi2c, uint32_t Timeout, + uint32_t Tickstart); + +/* Private functions to centralize the enable/disable of Interrupts */ +static void I2C_Enable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest); +static void I2C_Disable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest); + +/* Private function to treat different error callback */ +static void I2C_TreatErrorCallback(I2C_HandleTypeDef *hi2c); + +/* Private function to flush TXDR register */ +static void I2C_Flush_TXDR(I2C_HandleTypeDef *hi2c); + +/* Private function to handle start, restart or stop a transfer */ +static void I2C_TransferConfig(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode, + uint32_t Request); + +/* Private function to Convert Specific options */ +static void I2C_ConvertOtherXferOptions(I2C_HandleTypeDef *hi2c); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup I2C_Exported_Functions I2C Exported Functions + * @{ + */ + +/** @defgroup I2C_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + deinitialize the I2Cx peripheral: + + (+) User must Implement HAL_I2C_MspInit() function in which he configures + all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ). + + (+) Call the function HAL_I2C_Init() to configure the selected device with + the selected configuration: + (++) Clock Timing + (++) Own Address 1 + (++) Addressing mode (Master, Slave) + (++) Dual Addressing mode + (++) Own Address 2 + (++) Own Address 2 Mask + (++) General call mode + (++) Nostretch mode + + (+) Call the function HAL_I2C_DeInit() to restore the default configuration + of the selected I2Cx peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the I2C according to the specified parameters + * in the I2C_InitTypeDef and initialize the associated handle. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c) +{ + /* Check the I2C handle allocation */ + if (hi2c == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); + assert_param(IS_I2C_OWN_ADDRESS1(hi2c->Init.OwnAddress1)); + assert_param(IS_I2C_ADDRESSING_MODE(hi2c->Init.AddressingMode)); + assert_param(IS_I2C_DUAL_ADDRESS(hi2c->Init.DualAddressMode)); + assert_param(IS_I2C_OWN_ADDRESS2(hi2c->Init.OwnAddress2)); + assert_param(IS_I2C_OWN_ADDRESS2_MASK(hi2c->Init.OwnAddress2Masks)); + assert_param(IS_I2C_GENERAL_CALL(hi2c->Init.GeneralCallMode)); + assert_param(IS_I2C_NO_STRETCH(hi2c->Init.NoStretchMode)); + + if (hi2c->State == HAL_I2C_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hi2c->Lock = HAL_UNLOCKED; + +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + /* Init the I2C Callback settings */ + hi2c->MasterTxCpltCallback = HAL_I2C_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */ + hi2c->MasterRxCpltCallback = HAL_I2C_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */ + hi2c->SlaveTxCpltCallback = HAL_I2C_SlaveTxCpltCallback; /* Legacy weak SlaveTxCpltCallback */ + hi2c->SlaveRxCpltCallback = HAL_I2C_SlaveRxCpltCallback; /* Legacy weak SlaveRxCpltCallback */ + hi2c->ListenCpltCallback = HAL_I2C_ListenCpltCallback; /* Legacy weak ListenCpltCallback */ + hi2c->MemTxCpltCallback = HAL_I2C_MemTxCpltCallback; /* Legacy weak MemTxCpltCallback */ + hi2c->MemRxCpltCallback = HAL_I2C_MemRxCpltCallback; /* Legacy weak MemRxCpltCallback */ + hi2c->ErrorCallback = HAL_I2C_ErrorCallback; /* Legacy weak ErrorCallback */ + hi2c->AbortCpltCallback = HAL_I2C_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ + hi2c->AddrCallback = HAL_I2C_AddrCallback; /* Legacy weak AddrCallback */ + + if (hi2c->MspInitCallback == NULL) + { + hi2c->MspInitCallback = HAL_I2C_MspInit; /* Legacy weak MspInit */ + } + + /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ + hi2c->MspInitCallback(hi2c); +#else + /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ + HAL_I2C_MspInit(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + + hi2c->State = HAL_I2C_STATE_BUSY; + + /* Disable the selected I2C peripheral */ + __HAL_I2C_DISABLE(hi2c); + + /*---------------------------- I2Cx TIMINGR Configuration ------------------*/ + /* Configure I2Cx: Frequency range */ + hi2c->Instance->TIMINGR = hi2c->Init.Timing & TIMING_CLEAR_MASK; + + /*---------------------------- I2Cx OAR1 Configuration ---------------------*/ + /* Disable Own Address1 before set the Own Address1 configuration */ + hi2c->Instance->OAR1 &= ~I2C_OAR1_OA1EN; + + /* Configure I2Cx: Own Address1 and ack own address1 mode */ + if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) + { + hi2c->Instance->OAR1 = (I2C_OAR1_OA1EN | hi2c->Init.OwnAddress1); + } + else /* I2C_ADDRESSINGMODE_10BIT */ + { + hi2c->Instance->OAR1 = (I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE | hi2c->Init.OwnAddress1); + } + + /*---------------------------- I2Cx CR2 Configuration ----------------------*/ + /* Configure I2Cx: Addressing Master mode */ + if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT) + { + SET_BIT(hi2c->Instance->CR2, I2C_CR2_ADD10); + } + else + { + /* Clear the I2C ADD10 bit */ + CLEAR_BIT(hi2c->Instance->CR2, I2C_CR2_ADD10); + } + /* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process */ + hi2c->Instance->CR2 |= (I2C_CR2_AUTOEND | I2C_CR2_NACK); + + /*---------------------------- I2Cx OAR2 Configuration ---------------------*/ + /* Disable Own Address2 before set the Own Address2 configuration */ + hi2c->Instance->OAR2 &= ~I2C_DUALADDRESS_ENABLE; + + /* Configure I2Cx: Dual mode and Own Address2 */ + hi2c->Instance->OAR2 = (hi2c->Init.DualAddressMode | hi2c->Init.OwnAddress2 | \ + (hi2c->Init.OwnAddress2Masks << 8)); + + /*---------------------------- I2Cx CR1 Configuration ----------------------*/ + /* Configure I2Cx: Generalcall and NoStretch mode */ + hi2c->Instance->CR1 = (hi2c->Init.GeneralCallMode | hi2c->Init.NoStretchMode); + + /* Enable the selected I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + hi2c->State = HAL_I2C_STATE_READY; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->Mode = HAL_I2C_MODE_NONE; + + return HAL_OK; +} + +/** + * @brief DeInitialize the I2C peripheral. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c) +{ + /* Check the I2C handle allocation */ + if (hi2c == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); + + hi2c->State = HAL_I2C_STATE_BUSY; + + /* Disable the I2C Peripheral Clock */ + __HAL_I2C_DISABLE(hi2c); + +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + if (hi2c->MspDeInitCallback == NULL) + { + hi2c->MspDeInitCallback = HAL_I2C_MspDeInit; /* Legacy weak MspDeInit */ + } + + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + hi2c->MspDeInitCallback(hi2c); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + HAL_I2C_MspDeInit(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + hi2c->State = HAL_I2C_STATE_RESET; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Release Lock */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; +} + +/** + * @brief Initialize the I2C MSP. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitialize the I2C MSP. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_MspDeInit could be implemented in the user file + */ +} + +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User I2C Callback + * To be used instead of the weak predefined callback + * @note The HAL_I2C_RegisterCallback() may be called before HAL_I2C_Init() in HAL_I2C_STATE_RESET + * to register callbacks for HAL_I2C_MSPINIT_CB_ID and HAL_I2C_MSPDEINIT_CB_ID. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_I2C_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID + * @arg @ref HAL_I2C_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID + * @arg @ref HAL_I2C_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID + * @arg @ref HAL_I2C_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID + * @arg @ref HAL_I2C_LISTEN_COMPLETE_CB_ID Listen Complete callback ID + * @arg @ref HAL_I2C_MEM_TX_COMPLETE_CB_ID Memory Tx Transfer callback ID + * @arg @ref HAL_I2C_MEM_RX_COMPLETE_CB_ID Memory Rx Transfer completed callback ID + * @arg @ref HAL_I2C_ERROR_CB_ID Error callback ID + * @arg @ref HAL_I2C_ABORT_CB_ID Abort callback ID + * @arg @ref HAL_I2C_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_I2C_MSPDEINIT_CB_ID MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_RegisterCallback(I2C_HandleTypeDef *hi2c, HAL_I2C_CallbackIDTypeDef CallbackID, + pI2C_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + if (HAL_I2C_STATE_READY == hi2c->State) + { + switch (CallbackID) + { + case HAL_I2C_MASTER_TX_COMPLETE_CB_ID : + hi2c->MasterTxCpltCallback = pCallback; + break; + + case HAL_I2C_MASTER_RX_COMPLETE_CB_ID : + hi2c->MasterRxCpltCallback = pCallback; + break; + + case HAL_I2C_SLAVE_TX_COMPLETE_CB_ID : + hi2c->SlaveTxCpltCallback = pCallback; + break; + + case HAL_I2C_SLAVE_RX_COMPLETE_CB_ID : + hi2c->SlaveRxCpltCallback = pCallback; + break; + + case HAL_I2C_LISTEN_COMPLETE_CB_ID : + hi2c->ListenCpltCallback = pCallback; + break; + + case HAL_I2C_MEM_TX_COMPLETE_CB_ID : + hi2c->MemTxCpltCallback = pCallback; + break; + + case HAL_I2C_MEM_RX_COMPLETE_CB_ID : + hi2c->MemRxCpltCallback = pCallback; + break; + + case HAL_I2C_ERROR_CB_ID : + hi2c->ErrorCallback = pCallback; + break; + + case HAL_I2C_ABORT_CB_ID : + hi2c->AbortCpltCallback = pCallback; + break; + + case HAL_I2C_MSPINIT_CB_ID : + hi2c->MspInitCallback = pCallback; + break; + + case HAL_I2C_MSPDEINIT_CB_ID : + hi2c->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_I2C_STATE_RESET == hi2c->State) + { + switch (CallbackID) + { + case HAL_I2C_MSPINIT_CB_ID : + hi2c->MspInitCallback = pCallback; + break; + + case HAL_I2C_MSPDEINIT_CB_ID : + hi2c->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister an I2C Callback + * I2C callback is redirected to the weak predefined callback + * @note The HAL_I2C_UnRegisterCallback() may be called before HAL_I2C_Init() in HAL_I2C_STATE_RESET + * to un-register callbacks for HAL_I2C_MSPINIT_CB_ID and HAL_I2C_MSPDEINIT_CB_ID. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * This parameter can be one of the following values: + * @arg @ref HAL_I2C_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID + * @arg @ref HAL_I2C_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID + * @arg @ref HAL_I2C_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID + * @arg @ref HAL_I2C_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID + * @arg @ref HAL_I2C_LISTEN_COMPLETE_CB_ID Listen Complete callback ID + * @arg @ref HAL_I2C_MEM_TX_COMPLETE_CB_ID Memory Tx Transfer callback ID + * @arg @ref HAL_I2C_MEM_RX_COMPLETE_CB_ID Memory Rx Transfer completed callback ID + * @arg @ref HAL_I2C_ERROR_CB_ID Error callback ID + * @arg @ref HAL_I2C_ABORT_CB_ID Abort callback ID + * @arg @ref HAL_I2C_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_I2C_MSPDEINIT_CB_ID MspDeInit callback ID + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_UnRegisterCallback(I2C_HandleTypeDef *hi2c, HAL_I2C_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (HAL_I2C_STATE_READY == hi2c->State) + { + switch (CallbackID) + { + case HAL_I2C_MASTER_TX_COMPLETE_CB_ID : + hi2c->MasterTxCpltCallback = HAL_I2C_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */ + break; + + case HAL_I2C_MASTER_RX_COMPLETE_CB_ID : + hi2c->MasterRxCpltCallback = HAL_I2C_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */ + break; + + case HAL_I2C_SLAVE_TX_COMPLETE_CB_ID : + hi2c->SlaveTxCpltCallback = HAL_I2C_SlaveTxCpltCallback; /* Legacy weak SlaveTxCpltCallback */ + break; + + case HAL_I2C_SLAVE_RX_COMPLETE_CB_ID : + hi2c->SlaveRxCpltCallback = HAL_I2C_SlaveRxCpltCallback; /* Legacy weak SlaveRxCpltCallback */ + break; + + case HAL_I2C_LISTEN_COMPLETE_CB_ID : + hi2c->ListenCpltCallback = HAL_I2C_ListenCpltCallback; /* Legacy weak ListenCpltCallback */ + break; + + case HAL_I2C_MEM_TX_COMPLETE_CB_ID : + hi2c->MemTxCpltCallback = HAL_I2C_MemTxCpltCallback; /* Legacy weak MemTxCpltCallback */ + break; + + case HAL_I2C_MEM_RX_COMPLETE_CB_ID : + hi2c->MemRxCpltCallback = HAL_I2C_MemRxCpltCallback; /* Legacy weak MemRxCpltCallback */ + break; + + case HAL_I2C_ERROR_CB_ID : + hi2c->ErrorCallback = HAL_I2C_ErrorCallback; /* Legacy weak ErrorCallback */ + break; + + case HAL_I2C_ABORT_CB_ID : + hi2c->AbortCpltCallback = HAL_I2C_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ + break; + + case HAL_I2C_MSPINIT_CB_ID : + hi2c->MspInitCallback = HAL_I2C_MspInit; /* Legacy weak MspInit */ + break; + + case HAL_I2C_MSPDEINIT_CB_ID : + hi2c->MspDeInitCallback = HAL_I2C_MspDeInit; /* Legacy weak MspDeInit */ + break; + + default : + /* Update the error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_I2C_STATE_RESET == hi2c->State) + { + switch (CallbackID) + { + case HAL_I2C_MSPINIT_CB_ID : + hi2c->MspInitCallback = HAL_I2C_MspInit; /* Legacy weak MspInit */ + break; + + case HAL_I2C_MSPDEINIT_CB_ID : + hi2c->MspDeInitCallback = HAL_I2C_MspDeInit; /* Legacy weak MspDeInit */ + break; + + default : + /* Update the error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Register the Slave Address Match I2C Callback + * To be used instead of the weak HAL_I2C_AddrCallback() predefined callback + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pCallback pointer to the Address Match Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_RegisterAddrCallback(I2C_HandleTypeDef *hi2c, pI2C_AddrCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + if (HAL_I2C_STATE_READY == hi2c->State) + { + hi2c->AddrCallback = pCallback; + } + else + { + /* Update the error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief UnRegister the Slave Address Match I2C Callback + * Info Ready I2C Callback is redirected to the weak HAL_I2C_AddrCallback() predefined callback + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_UnRegisterAddrCallback(I2C_HandleTypeDef *hi2c) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (HAL_I2C_STATE_READY == hi2c->State) + { + hi2c->AddrCallback = HAL_I2C_AddrCallback; /* Legacy weak AddrCallback */ + } + else + { + /* Update the error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup I2C_Exported_Functions_Group2 Input and Output operation functions + * @brief Data transfers functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the I2C data + transfers. + + (#) There are two modes of transfer: + (++) Blocking mode : The communication is performed in the polling mode. + The status of all data processing is returned by the same function + after finishing transfer. + (++) No-Blocking mode : The communication is performed using Interrupts + or DMA. These functions return the status of the transfer startup. + The end of the data processing will be indicated through the + dedicated I2C IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + + (#) Blocking mode functions are : + (++) HAL_I2C_Master_Transmit() + (++) HAL_I2C_Master_Receive() + (++) HAL_I2C_Slave_Transmit() + (++) HAL_I2C_Slave_Receive() + (++) HAL_I2C_Mem_Write() + (++) HAL_I2C_Mem_Read() + (++) HAL_I2C_IsDeviceReady() + + (#) No-Blocking mode functions with Interrupt are : + (++) HAL_I2C_Master_Transmit_IT() + (++) HAL_I2C_Master_Receive_IT() + (++) HAL_I2C_Slave_Transmit_IT() + (++) HAL_I2C_Slave_Receive_IT() + (++) HAL_I2C_Mem_Write_IT() + (++) HAL_I2C_Mem_Read_IT() + (++) HAL_I2C_Master_Seq_Transmit_IT() + (++) HAL_I2C_Master_Seq_Receive_IT() + (++) HAL_I2C_Slave_Seq_Transmit_IT() + (++) HAL_I2C_Slave_Seq_Receive_IT() + (++) HAL_I2C_EnableListen_IT() + (++) HAL_I2C_DisableListen_IT() + (++) HAL_I2C_Master_Abort_IT() + + (#) No-Blocking mode functions with DMA are : + (++) HAL_I2C_Master_Transmit_DMA() + (++) HAL_I2C_Master_Receive_DMA() + (++) HAL_I2C_Slave_Transmit_DMA() + (++) HAL_I2C_Slave_Receive_DMA() + (++) HAL_I2C_Mem_Write_DMA() + (++) HAL_I2C_Mem_Read_DMA() + (++) HAL_I2C_Master_Seq_Transmit_DMA() + (++) HAL_I2C_Master_Seq_Receive_DMA() + (++) HAL_I2C_Slave_Seq_Transmit_DMA() + (++) HAL_I2C_Slave_Seq_Receive_DMA() + + (#) A set of Transfer Complete Callbacks are provided in non Blocking mode: + (++) HAL_I2C_MasterTxCpltCallback() + (++) HAL_I2C_MasterRxCpltCallback() + (++) HAL_I2C_SlaveTxCpltCallback() + (++) HAL_I2C_SlaveRxCpltCallback() + (++) HAL_I2C_MemTxCpltCallback() + (++) HAL_I2C_MemRxCpltCallback() + (++) HAL_I2C_AddrCallback() + (++) HAL_I2C_ListenCpltCallback() + (++) HAL_I2C_ErrorCallback() + (++) HAL_I2C_AbortCpltCallback() + +@endverbatim + * @{ + */ + +/** + * @brief Transmits in master mode an amount of data in blocking mode. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, + uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart; + + if (hi2c->State == HAL_I2C_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferISR = NULL; + + /* Send Slave Address */ + /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, + I2C_GENERATE_START_WRITE); + } + else + { + hi2c->XferSize = hi2c->XferCount; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, + I2C_GENERATE_START_WRITE); + } + + while (hi2c->XferCount > 0U) + { + /* Wait until TXIS flag is set */ + if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + /* Write data to TXDR */ + hi2c->Instance->TXDR = *hi2c->pBuffPtr; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + hi2c->XferCount--; + hi2c->XferSize--; + + if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U)) + { + /* Wait until TCR flag is set */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, + I2C_NO_STARTSTOP); + } + else + { + hi2c->XferSize = hi2c->XferCount; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, + I2C_NO_STARTSTOP); + } + } + } + + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is set */ + if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Clear STOP Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + I2C_RESET_CR2(hi2c); + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receives in master mode an amount of data in blocking mode. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, + uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart; + + if (hi2c->State == HAL_I2C_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferISR = NULL; + + /* Send Slave Address */ + /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, + I2C_GENERATE_START_READ); + } + else + { + hi2c->XferSize = hi2c->XferCount; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, + I2C_GENERATE_START_READ); + } + + while (hi2c->XferCount > 0U) + { + /* Wait until RXNE flag is set */ + if (I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Read data from RXDR */ + *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + hi2c->XferSize--; + hi2c->XferCount--; + + if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U)) + { + /* Wait until TCR flag is set */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, + I2C_NO_STARTSTOP); + } + else + { + hi2c->XferSize = hi2c->XferCount; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, + I2C_NO_STARTSTOP); + } + } + } + + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is set */ + if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Clear STOP Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + I2C_RESET_CR2(hi2c); + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmits in slave mode an amount of data in blocking mode. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, + uint32_t Timeout) +{ + uint32_t tickstart; + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferISR = NULL; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR2 &= ~I2C_CR2_NACK; + + /* Wait until ADDR flag is set */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + return HAL_ERROR; + } + + /* Preload TX data if no stretch enable */ + if (hi2c->Init.NoStretchMode == I2C_NOSTRETCH_ENABLE) + { + /* Preload TX register */ + /* Write data to TXDR */ + hi2c->Instance->TXDR = *hi2c->pBuffPtr; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + hi2c->XferCount--; + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); + + /* If 10bit addressing mode is selected */ + if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT) + { + /* Wait until ADDR flag is set */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + return HAL_ERROR; + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); + } + + /* Wait until DIR flag is set Transmitter mode */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_DIR, RESET, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + return HAL_ERROR; + } + + while (hi2c->XferCount > 0U) + { + /* Wait until TXIS flag is set */ + if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + return HAL_ERROR; + } + + /* Write data to TXDR */ + hi2c->Instance->TXDR = *hi2c->pBuffPtr; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + hi2c->XferCount--; + } + + /* Wait until AF flag is set */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_AF, RESET, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + return HAL_ERROR; + } + + /* Flush TX register */ + I2C_Flush_TXDR(hi2c); + + /* Clear AF flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Wait until STOP flag is set */ + if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + + return HAL_ERROR; + } + + /* Clear STOP flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + + /* Wait until BUSY flag is reset */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + return HAL_ERROR; + } + + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in slave mode an amount of data in blocking mode + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, + uint32_t Timeout) +{ + uint32_t tickstart; + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferSize = hi2c->XferCount; + hi2c->XferISR = NULL; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR2 &= ~I2C_CR2_NACK; + + /* Wait until ADDR flag is set */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + return HAL_ERROR; + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); + + /* Wait until DIR flag is reset Receiver mode */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_DIR, SET, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + return HAL_ERROR; + } + + while (hi2c->XferCount > 0U) + { + /* Wait until RXNE flag is set */ + if (I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + + /* Store Last receive data if any */ + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) + { + /* Read data from RXDR */ + *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + hi2c->XferCount--; + hi2c->XferSize--; + } + + return HAL_ERROR; + } + + /* Read data from RXDR */ + *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + hi2c->XferCount--; + hi2c->XferSize--; + } + + /* Wait until STOP flag is set */ + if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + return HAL_ERROR; + } + + /* Clear STOP flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + + /* Wait until BUSY flag is reset */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + return HAL_ERROR; + } + + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit in master mode an amount of data in non-blocking mode with Interrupt + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, + uint16_t Size) +{ + uint32_t xfermode; + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferISR = I2C_Master_ISR_IT; + + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + xfermode = I2C_RELOAD_MODE; + } + else + { + hi2c->XferSize = hi2c->XferCount; + xfermode = I2C_AUTOEND_MODE; + } + + /* Send Slave Address */ + /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, I2C_GENERATE_START_WRITE); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable ERR, TC, STOP, NACK, TXI interrupt */ + /* possible to enable all of these */ + /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | + I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */ + I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in master mode an amount of data in non-blocking mode with Interrupt + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, + uint16_t Size) +{ + uint32_t xfermode; + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferISR = I2C_Master_ISR_IT; + + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + xfermode = I2C_RELOAD_MODE; + } + else + { + hi2c->XferSize = hi2c->XferCount; + xfermode = I2C_AUTOEND_MODE; + } + + /* Send Slave Address */ + /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, I2C_GENERATE_START_READ); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable ERR, TC, STOP, NACK, RXI interrupt */ + /* possible to enable all of these */ + /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | + I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */ + I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit in slave mode an amount of data in non-blocking mode with Interrupt + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) +{ + if (hi2c->State == HAL_I2C_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR2 &= ~I2C_CR2_NACK; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferSize = hi2c->XferCount; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferISR = I2C_Slave_ISR_IT; + + /* Preload TX data if no stretch enable */ + if (hi2c->Init.NoStretchMode == I2C_NOSTRETCH_ENABLE) + { + /* Preload TX register */ + /* Write data to TXDR */ + hi2c->Instance->TXDR = *hi2c->pBuffPtr; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + hi2c->XferCount--; + hi2c->XferSize--; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable ERR, TC, STOP, NACK, TXI interrupt */ + /* possible to enable all of these */ + /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | + I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */ + I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT | I2C_XFER_LISTEN_IT); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in slave mode an amount of data in non-blocking mode with Interrupt + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) +{ + if (hi2c->State == HAL_I2C_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR2 &= ~I2C_CR2_NACK; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferSize = hi2c->XferCount; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferISR = I2C_Slave_ISR_IT; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable ERR, TC, STOP, NACK, RXI interrupt */ + /* possible to enable all of these */ + /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | + I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */ + I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT | I2C_XFER_LISTEN_IT); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief Transmit in master mode an amount of data in non-blocking mode with DMA + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, + uint16_t Size) +{ + uint32_t xfermode; + HAL_StatusTypeDef dmaxferstatus; + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferISR = I2C_Master_ISR_DMA; + + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + xfermode = I2C_RELOAD_MODE; + } + else + { + hi2c->XferSize = hi2c->XferCount; + xfermode = I2C_AUTOEND_MODE; + } + + if (hi2c->XferSize > 0U) + { + if (hi2c->hdmatx != NULL) + { + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmatx->XferCpltCallback = I2C_DMAMasterTransmitCplt; + + /* Set the DMA error callback */ + hi2c->hdmatx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmatx->XferHalfCpltCallback = NULL; + hi2c->hdmatx->XferAbortCallback = NULL; + + /* Enable the DMA channel */ + if ((hi2c->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hi2c->hdmatx->LinkedListQueue != NULL) + { + /* Set DMA data size */ + hi2c->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hi2c->XferSize; + + /* Set DMA source address */ + hi2c->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)pData; + + /* Set DMA destination address */ + hi2c->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] \ + = (uint32_t)&hi2c->Instance->TXDR; + + dmaxferstatus = HAL_DMAEx_List_Start_IT(hi2c->hdmatx); + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + else + { + dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->TXDR, + hi2c->XferSize); + } + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + if (dmaxferstatus == HAL_OK) + { + /* Send Slave Address */ + /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, I2C_GENERATE_START_WRITE); + + /* Update XferCount value */ + hi2c->XferCount -= hi2c->XferSize; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR and NACK interrupts */ + I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT); + + /* Enable DMA Request */ + hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN; + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + else + { + /* Update Transfer ISR function pointer */ + hi2c->XferISR = I2C_Master_ISR_IT; + + /* Send Slave Address */ + /* Set NBYTES to write and generate START condition */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, + I2C_GENERATE_START_WRITE); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR, TC, STOP, NACK, TXI interrupt */ + /* possible to enable all of these */ + /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | + I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */ + I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT); + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in master mode an amount of data in non-blocking mode with DMA + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, + uint16_t Size) +{ + uint32_t xfermode; + HAL_StatusTypeDef dmaxferstatus; + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferISR = I2C_Master_ISR_DMA; + + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + xfermode = I2C_RELOAD_MODE; + } + else + { + hi2c->XferSize = hi2c->XferCount; + xfermode = I2C_AUTOEND_MODE; + } + + if (hi2c->XferSize > 0U) + { + if (hi2c->hdmarx != NULL) + { + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmarx->XferCpltCallback = I2C_DMAMasterReceiveCplt; + + /* Set the DMA error callback */ + hi2c->hdmarx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmarx->XferHalfCpltCallback = NULL; + hi2c->hdmarx->XferAbortCallback = NULL; + + /* Enable the DMA channel */ + if ((hi2c->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hi2c->hdmarx->LinkedListQueue != NULL) + { + /* Set DMA data size */ + hi2c->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hi2c->XferSize; + + /* Set DMA source address */ + hi2c->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] \ + = (uint32_t)&hi2c->Instance->RXDR; + + /* Set DMA destination address */ + hi2c->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)pData; + + dmaxferstatus = HAL_DMAEx_List_Start_IT(hi2c->hdmarx); + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + else + { + dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData, + hi2c->XferSize); + } + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + if (dmaxferstatus == HAL_OK) + { + /* Send Slave Address */ + /* Set NBYTES to read and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, I2C_GENERATE_START_READ); + + /* Update XferCount value */ + hi2c->XferCount -= hi2c->XferSize; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR and NACK interrupts */ + I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT); + + /* Enable DMA Request */ + hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN; + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + else + { + /* Update Transfer ISR function pointer */ + hi2c->XferISR = I2C_Master_ISR_IT; + + /* Send Slave Address */ + /* Set NBYTES to read and generate START condition */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, + I2C_GENERATE_START_READ); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR, TC, STOP, NACK, RXI interrupt */ + /* possible to enable all of these */ + /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | + I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */ + I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT); + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit in slave mode an amount of data in non-blocking mode with DMA + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) +{ + HAL_StatusTypeDef dmaxferstatus; + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferSize = hi2c->XferCount; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferISR = I2C_Slave_ISR_DMA; + + /* Preload TX data if no stretch enable */ + if (hi2c->Init.NoStretchMode == I2C_NOSTRETCH_ENABLE) + { + /* Preload TX register */ + /* Write data to TXDR */ + hi2c->Instance->TXDR = *hi2c->pBuffPtr; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + hi2c->XferCount--; + hi2c->XferSize--; + } + + if (hi2c->XferCount != 0U) + { + if (hi2c->hdmatx != NULL) + { + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmatx->XferCpltCallback = I2C_DMASlaveTransmitCplt; + + /* Set the DMA error callback */ + hi2c->hdmatx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmatx->XferHalfCpltCallback = NULL; + hi2c->hdmatx->XferAbortCallback = NULL; + + /* Enable the DMA channel */ + if ((hi2c->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hi2c->hdmatx->LinkedListQueue != NULL) + { + /* Set DMA data size */ + hi2c->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hi2c->XferSize; + + /* Set DMA source address */ + hi2c->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)hi2c->pBuffPtr; + + /* Set DMA destination address */ + hi2c->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] \ + = (uint32_t)&hi2c->Instance->TXDR; + + dmaxferstatus = HAL_DMAEx_List_Start_IT(hi2c->hdmatx); + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_LISTEN; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + else + { + dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, + (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->TXDR, + hi2c->XferSize); + } + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_LISTEN; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + if (dmaxferstatus == HAL_OK) + { + /* Enable Address Acknowledge */ + hi2c->Instance->CR2 &= ~I2C_CR2_NACK; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR, STOP, NACK, ADDR interrupts */ + I2C_Enable_IRQ(hi2c, I2C_XFER_LISTEN_IT); + + /* Enable DMA Request */ + hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN; + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_LISTEN; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + else + { + /* Enable Address Acknowledge */ + hi2c->Instance->CR2 &= ~I2C_CR2_NACK; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR, STOP, NACK, ADDR interrupts */ + I2C_Enable_IRQ(hi2c, I2C_XFER_LISTEN_IT); + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in slave mode an amount of data in non-blocking mode with DMA + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) +{ + HAL_StatusTypeDef dmaxferstatus; + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferSize = hi2c->XferCount; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferISR = I2C_Slave_ISR_DMA; + + if (hi2c->hdmarx != NULL) + { + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmarx->XferCpltCallback = I2C_DMASlaveReceiveCplt; + + /* Set the DMA error callback */ + hi2c->hdmarx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmarx->XferHalfCpltCallback = NULL; + hi2c->hdmarx->XferAbortCallback = NULL; + + /* Enable the DMA channel */ + if ((hi2c->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hi2c->hdmarx->LinkedListQueue != NULL) + { + /* Set DMA data size */ + hi2c->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hi2c->XferSize; + + /* Set DMA source address */ + hi2c->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] \ + = (uint32_t)&hi2c->Instance->RXDR; + + /* Set DMA destination address */ + hi2c->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)pData; + + dmaxferstatus = HAL_DMAEx_List_Start_IT(hi2c->hdmarx); + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_LISTEN; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + else + { + dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData, + hi2c->XferSize); + } + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_LISTEN; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + if (dmaxferstatus == HAL_OK) + { + /* Enable Address Acknowledge */ + hi2c->Instance->CR2 &= ~I2C_CR2_NACK; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR, STOP, NACK, ADDR interrupts */ + I2C_Enable_IRQ(hi2c, I2C_XFER_LISTEN_IT); + + /* Enable DMA Request */ + hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN; + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_LISTEN; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Write an amount of data in blocking mode to a specific memory address + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, + uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart; + + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MEM; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferISR = NULL; + + /* Send Slave Address and Memory Address */ + if (I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + + /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE */ + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP); + } + else + { + hi2c->XferSize = hi2c->XferCount; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); + } + + do + { + /* Wait until TXIS flag is set */ + if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Write data to TXDR */ + hi2c->Instance->TXDR = *hi2c->pBuffPtr; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + hi2c->XferCount--; + hi2c->XferSize--; + + if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U)) + { + /* Wait until TCR flag is set */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, + I2C_NO_STARTSTOP); + } + else + { + hi2c->XferSize = hi2c->XferCount; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, + I2C_NO_STARTSTOP); + } + } + + } while (hi2c->XferCount > 0U); + + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is reset */ + if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Clear STOP Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + I2C_RESET_CR2(hi2c); + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Read an amount of data in blocking mode from a specific memory address + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, + uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart; + + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MEM; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferISR = NULL; + + /* Send Slave Address and Memory Address */ + if (I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + + /* Send Slave Address */ + /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, + I2C_GENERATE_START_READ); + } + else + { + hi2c->XferSize = hi2c->XferCount; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, + I2C_GENERATE_START_READ); + } + + do + { + /* Wait until RXNE flag is set */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_RXNE, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Read data from RXDR */ + *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + hi2c->XferSize--; + hi2c->XferCount--; + + if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U)) + { + /* Wait until TCR flag is set */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t) hi2c->XferSize, I2C_RELOAD_MODE, + I2C_NO_STARTSTOP); + } + else + { + hi2c->XferSize = hi2c->XferCount; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, + I2C_NO_STARTSTOP); + } + } + } while (hi2c->XferCount > 0U); + + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is reset */ + if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Clear STOP Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + I2C_RESET_CR2(hi2c); + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} +/** + * @brief Write an amount of data in non-blocking mode with Interrupt to a specific memory address + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, + uint16_t MemAddSize, uint8_t *pData, uint16_t Size) +{ + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MEM; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->XferSize = 0U; + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferISR = I2C_Mem_ISR_IT; + hi2c->Devaddress = DevAddress; + + /* If Memory address size is 8Bit */ + if (MemAddSize == I2C_MEMADD_SIZE_8BIT) + { + /* Prefetch Memory Address */ + hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress); + + /* Reset Memaddress content */ + hi2c->Memaddress = 0xFFFFFFFFU; + } + /* If Memory address size is 16Bit */ + else + { + /* Prefetch Memory Address (MSB part, LSB will be manage through interrupt) */ + hi2c->Instance->TXDR = I2C_MEM_ADD_MSB(MemAddress); + + /* Prepare Memaddress buffer for LSB part */ + hi2c->Memaddress = I2C_MEM_ADD_LSB(MemAddress); + } + /* Send Slave Address and Memory Address */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)MemAddSize, I2C_RELOAD_MODE, I2C_GENERATE_START_WRITE); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable ERR, TC, STOP, NACK, TXI interrupt */ + /* possible to enable all of these */ + /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | + I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */ + I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Read an amount of data in non-blocking mode with Interrupt from a specific memory address + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, + uint16_t MemAddSize, uint8_t *pData, uint16_t Size) +{ + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MEM; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferISR = I2C_Mem_ISR_IT; + hi2c->Devaddress = DevAddress; + + /* If Memory address size is 8Bit */ + if (MemAddSize == I2C_MEMADD_SIZE_8BIT) + { + /* Prefetch Memory Address */ + hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress); + + /* Reset Memaddress content */ + hi2c->Memaddress = 0xFFFFFFFFU; + } + /* If Memory address size is 16Bit */ + else + { + /* Prefetch Memory Address (MSB part, LSB will be manage through interrupt) */ + hi2c->Instance->TXDR = I2C_MEM_ADD_MSB(MemAddress); + + /* Prepare Memaddress buffer for LSB part */ + hi2c->Memaddress = I2C_MEM_ADD_LSB(MemAddress); + } + /* Send Slave Address and Memory Address */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)MemAddSize, I2C_SOFTEND_MODE, I2C_GENERATE_START_WRITE); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable ERR, TC, STOP, NACK, TXI interrupt */ + /* possible to enable all of these */ + /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | + I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */ + I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief Write an amount of data in non-blocking mode with DMA to a specific memory address + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, + uint16_t MemAddSize, uint8_t *pData, uint16_t Size) +{ + HAL_StatusTypeDef dmaxferstatus; + + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MEM; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferISR = I2C_Mem_ISR_DMA; + hi2c->Devaddress = DevAddress; + + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + } + else + { + hi2c->XferSize = hi2c->XferCount; + } + + /* If Memory address size is 8Bit */ + if (MemAddSize == I2C_MEMADD_SIZE_8BIT) + { + /* Prefetch Memory Address */ + hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress); + + /* Reset Memaddress content */ + hi2c->Memaddress = 0xFFFFFFFFU; + } + /* If Memory address size is 16Bit */ + else + { + /* Prefetch Memory Address (MSB part, LSB will be manage through interrupt) */ + hi2c->Instance->TXDR = I2C_MEM_ADD_MSB(MemAddress); + + /* Prepare Memaddress buffer for LSB part */ + hi2c->Memaddress = I2C_MEM_ADD_LSB(MemAddress); + } + + if (hi2c->hdmatx != NULL) + { + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmatx->XferCpltCallback = I2C_DMAMasterTransmitCplt; + + /* Set the DMA error callback */ + hi2c->hdmatx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmatx->XferHalfCpltCallback = NULL; + hi2c->hdmatx->XferAbortCallback = NULL; + + /* Enable the DMA channel */ + if ((hi2c->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hi2c->hdmatx->LinkedListQueue != NULL) + { + /* Set DMA data size */ + hi2c->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hi2c->XferSize; + + /* Set DMA source address */ + hi2c->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)pData; + + /* Set DMA destination address */ + hi2c->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] \ + = (uint32_t)&hi2c->Instance->TXDR; + + dmaxferstatus = HAL_DMAEx_List_Start_IT(hi2c->hdmatx); + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + else + { + dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->TXDR, + hi2c->XferSize); + } + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + if (dmaxferstatus == HAL_OK) + { + /* Send Slave Address and Memory Address */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)MemAddSize, I2C_RELOAD_MODE, I2C_GENERATE_START_WRITE); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR, TC, STOP, NACK, TXI interrupt */ + /* possible to enable all of these */ + /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | + I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */ + I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT); + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Reads an amount of data in non-blocking mode with DMA from a specific memory address. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param pData Pointer to data buffer + * @param Size Amount of data to be read + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, + uint16_t MemAddSize, uint8_t *pData, uint16_t Size) +{ + HAL_StatusTypeDef dmaxferstatus; + + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MEM; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferISR = I2C_Mem_ISR_DMA; + hi2c->Devaddress = DevAddress; + + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + } + else + { + hi2c->XferSize = hi2c->XferCount; + } + + /* If Memory address size is 8Bit */ + if (MemAddSize == I2C_MEMADD_SIZE_8BIT) + { + /* Prefetch Memory Address */ + hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress); + + /* Reset Memaddress content */ + hi2c->Memaddress = 0xFFFFFFFFU; + } + /* If Memory address size is 16Bit */ + else + { + /* Prefetch Memory Address (MSB part, LSB will be manage through interrupt) */ + hi2c->Instance->TXDR = I2C_MEM_ADD_MSB(MemAddress); + + /* Prepare Memaddress buffer for LSB part */ + hi2c->Memaddress = I2C_MEM_ADD_LSB(MemAddress); + } + + if (hi2c->hdmarx != NULL) + { + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmarx->XferCpltCallback = I2C_DMAMasterReceiveCplt; + + /* Set the DMA error callback */ + hi2c->hdmarx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmarx->XferHalfCpltCallback = NULL; + hi2c->hdmarx->XferAbortCallback = NULL; + + /* Enable the DMA channel */ + if ((hi2c->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hi2c->hdmarx->LinkedListQueue != NULL) + { + /* Set DMA data size */ + hi2c->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hi2c->XferSize; + + /* Set DMA source address */ + hi2c->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] \ + = (uint32_t)&hi2c->Instance->RXDR; + + /* Set DMA destination address */ + hi2c->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)pData; + + dmaxferstatus = HAL_DMAEx_List_Start_IT(hi2c->hdmarx); + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + else + { + dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData, + hi2c->XferSize); + } + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + if (dmaxferstatus == HAL_OK) + { + /* Send Slave Address and Memory Address */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)MemAddSize, I2C_SOFTEND_MODE, I2C_GENERATE_START_WRITE); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR, TC, STOP, NACK, TXI interrupt */ + /* possible to enable all of these */ + /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | + I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */ + I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT); + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Checks if target device is ready for communication. + * @note This function is used with Memory devices + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param Trials Number of trials + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, + uint32_t Timeout) +{ + uint32_t tickstart; + + __IO uint32_t I2C_Trials = 0UL; + + FlagStatus tmp1; + FlagStatus tmp2; + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + do + { + /* Generate Start */ + hi2c->Instance->CR2 = I2C_GENERATE_START(hi2c->Init.AddressingMode, DevAddress); + + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is set or a NACK flag is set*/ + tickstart = HAL_GetTick(); + + tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF); + tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF); + + while ((tmp1 == RESET) && (tmp2 == RESET)) + { + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + + tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF); + tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF); + } + + /* Check if the NACKF flag has not been set */ + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == RESET) + { + /* Wait until STOPF flag is reset */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Clear STOP Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + + /* Device is ready */ + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + /* Wait until STOPF flag is reset */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Clear NACK Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Clear STOP Flag, auto generated with autoend*/ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + } + + /* Increment Trials */ + I2C_Trials++; + } while (I2C_Trials < Trials); + + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Sequential transmit in master I2C mode an amount of data in non-blocking mode with Interrupt. + * @note This interface allow to manage repeated start condition when a direction change during transfer + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, + uint16_t Size, uint32_t XferOptions) +{ + uint32_t xfermode; + uint32_t xferrequest = I2C_GENERATE_START_WRITE; + + /* Check the parameters */ + assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = XferOptions; + hi2c->XferISR = I2C_Master_ISR_IT; + + /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */ + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + xfermode = I2C_RELOAD_MODE; + } + else + { + hi2c->XferSize = hi2c->XferCount; + xfermode = hi2c->XferOptions; + } + + /* If transfer direction not change and there is no request to start another frame, + do not generate Restart Condition */ + /* Mean Previous state is same as current state */ + if ((hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) && \ + (IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0)) + { + xferrequest = I2C_NO_STARTSTOP; + } + else + { + /* Convert OTHER_xxx XferOptions if any */ + I2C_ConvertOtherXferOptions(hi2c); + + /* Update xfermode accordingly if no reload is necessary */ + if (hi2c->XferCount <= MAX_NBYTE_SIZE) + { + xfermode = hi2c->XferOptions; + } + } + + /* Send Slave Address and set NBYTES to write */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, xferrequest); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR, TC, STOP, NACK, TXI interrupt */ + /* possible to enable all of these */ + /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | + I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */ + I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief Sequential transmit in master I2C mode an amount of data in non-blocking mode with DMA. + * @note This interface allow to manage repeated start condition when a direction change during transfer + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, + uint16_t Size, uint32_t XferOptions) +{ + uint32_t xfermode; + uint32_t xferrequest = I2C_GENERATE_START_WRITE; + HAL_StatusTypeDef dmaxferstatus; + + /* Check the parameters */ + assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = XferOptions; + hi2c->XferISR = I2C_Master_ISR_DMA; + + /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */ + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + xfermode = I2C_RELOAD_MODE; + } + else + { + hi2c->XferSize = hi2c->XferCount; + xfermode = hi2c->XferOptions; + } + + /* If transfer direction not change and there is no request to start another frame, + do not generate Restart Condition */ + /* Mean Previous state is same as current state */ + if ((hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) && \ + (IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0)) + { + xferrequest = I2C_NO_STARTSTOP; + } + else + { + /* Convert OTHER_xxx XferOptions if any */ + I2C_ConvertOtherXferOptions(hi2c); + + /* Update xfermode accordingly if no reload is necessary */ + if (hi2c->XferCount <= MAX_NBYTE_SIZE) + { + xfermode = hi2c->XferOptions; + } + } + + if (hi2c->XferSize > 0U) + { + if (hi2c->hdmatx != NULL) + { + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmatx->XferCpltCallback = I2C_DMAMasterTransmitCplt; + + /* Set the DMA error callback */ + hi2c->hdmatx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmatx->XferHalfCpltCallback = NULL; + hi2c->hdmatx->XferAbortCallback = NULL; + + /* Enable the DMA channel */ + if ((hi2c->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hi2c->hdmatx->LinkedListQueue != NULL) + { + /* Set DMA data size */ + hi2c->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hi2c->XferSize; + + /* Set DMA source address */ + hi2c->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)pData; + + /* Set DMA destination address */ + hi2c->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] \ + = (uint32_t)&hi2c->Instance->TXDR; + + dmaxferstatus = HAL_DMAEx_List_Start_IT(hi2c->hdmatx); + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + else + { + dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->TXDR, + hi2c->XferSize); + } + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + if (dmaxferstatus == HAL_OK) + { + /* Send Slave Address and set NBYTES to write */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, xferrequest); + + /* Update XferCount value */ + hi2c->XferCount -= hi2c->XferSize; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR and NACK interrupts */ + I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT); + + /* Enable DMA Request */ + hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN; + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + else + { + /* Update Transfer ISR function pointer */ + hi2c->XferISR = I2C_Master_ISR_IT; + + /* Send Slave Address */ + /* Set NBYTES to write and generate START condition */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, + I2C_GENERATE_START_WRITE); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR, TC, STOP, NACK, TXI interrupt */ + /* possible to enable all of these */ + /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | + I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */ + I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT); + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Sequential receive in master I2C mode an amount of data in non-blocking mode with Interrupt + * @note This interface allow to manage repeated start condition when a direction change during transfer + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, + uint16_t Size, uint32_t XferOptions) +{ + uint32_t xfermode; + uint32_t xferrequest = I2C_GENERATE_START_READ; + + /* Check the parameters */ + assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = XferOptions; + hi2c->XferISR = I2C_Master_ISR_IT; + + /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */ + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + xfermode = I2C_RELOAD_MODE; + } + else + { + hi2c->XferSize = hi2c->XferCount; + xfermode = hi2c->XferOptions; + } + + /* If transfer direction not change and there is no request to start another frame, + do not generate Restart Condition */ + /* Mean Previous state is same as current state */ + if ((hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX) && \ + (IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0)) + { + xferrequest = I2C_NO_STARTSTOP; + } + else + { + /* Convert OTHER_xxx XferOptions if any */ + I2C_ConvertOtherXferOptions(hi2c); + + /* Update xfermode accordingly if no reload is necessary */ + if (hi2c->XferCount <= MAX_NBYTE_SIZE) + { + xfermode = hi2c->XferOptions; + } + } + + /* Send Slave Address and set NBYTES to read */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, xferrequest); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief Sequential receive in master I2C mode an amount of data in non-blocking mode with DMA + * @note This interface allow to manage repeated start condition when a direction change during transfer + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, + uint16_t Size, uint32_t XferOptions) +{ + uint32_t xfermode; + uint32_t xferrequest = I2C_GENERATE_START_READ; + HAL_StatusTypeDef dmaxferstatus; + + /* Check the parameters */ + assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = XferOptions; + hi2c->XferISR = I2C_Master_ISR_DMA; + + /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */ + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + xfermode = I2C_RELOAD_MODE; + } + else + { + hi2c->XferSize = hi2c->XferCount; + xfermode = hi2c->XferOptions; + } + + /* If transfer direction not change and there is no request to start another frame, + do not generate Restart Condition */ + /* Mean Previous state is same as current state */ + if ((hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX) && \ + (IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0)) + { + xferrequest = I2C_NO_STARTSTOP; + } + else + { + /* Convert OTHER_xxx XferOptions if any */ + I2C_ConvertOtherXferOptions(hi2c); + + /* Update xfermode accordingly if no reload is necessary */ + if (hi2c->XferCount <= MAX_NBYTE_SIZE) + { + xfermode = hi2c->XferOptions; + } + } + + if (hi2c->XferSize > 0U) + { + if (hi2c->hdmarx != NULL) + { + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmarx->XferCpltCallback = I2C_DMAMasterReceiveCplt; + + /* Set the DMA error callback */ + hi2c->hdmarx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmarx->XferHalfCpltCallback = NULL; + hi2c->hdmarx->XferAbortCallback = NULL; + + /* Enable the DMA channel */ + if ((hi2c->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hi2c->hdmarx->LinkedListQueue != NULL) + { + /* Set DMA data size */ + hi2c->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hi2c->XferSize; + + /* Set DMA source address */ + hi2c->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] \ + = (uint32_t)&hi2c->Instance->RXDR; + + /* Set DMA destination address */ + hi2c->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)pData; + + dmaxferstatus = HAL_DMAEx_List_Start_IT(hi2c->hdmarx); + } + else + { + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + else + { + dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData, + hi2c->XferSize); + } + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + if (dmaxferstatus == HAL_OK) + { + /* Send Slave Address and set NBYTES to read */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, xferrequest); + + /* Update XferCount value */ + hi2c->XferCount -= hi2c->XferSize; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR and NACK interrupts */ + I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT); + + /* Enable DMA Request */ + hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN; + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + else + { + /* Update Transfer ISR function pointer */ + hi2c->XferISR = I2C_Master_ISR_IT; + + /* Send Slave Address */ + /* Set NBYTES to read and generate START condition */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, + I2C_GENERATE_START_READ); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR, TC, STOP, NACK, RXI interrupt */ + /* possible to enable all of these */ + /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | + I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */ + I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT); + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Sequential transmit in slave/device I2C mode an amount of data in non-blocking mode with Interrupt + * @note This interface allow to manage repeated start condition when a direction change during transfer + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, + uint32_t XferOptions) +{ + /* Declaration of tmp to prevent undefined behavior of volatile usage */ + FlagStatus tmp; + + /* Check the parameters */ + assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN) + { + if ((pData == NULL) || (Size == 0U)) + { + hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + + /* Disable Interrupts, to prevent preemption during treatment in case of multicall */ + I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_TX_IT); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* I2C cannot manage full duplex exchange so disable previous IT enabled if any */ + /* and then toggle the HAL slave RX state to TX state */ + if (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN) + { + /* Disable associated Interrupts */ + I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT); + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Abort DMA Xfer if any */ + if ((hi2c->Instance->CR1 & I2C_CR1_RXDMAEN) == I2C_CR1_RXDMAEN) + { + hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN; + + if (hi2c->hdmarx != NULL) + { + /* Set the I2C DMA Abort callback : + will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */ + hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort; + + /* Abort DMA RX */ + if (HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK) + { + /* Call Directly XferAbortCallback function in case of error */ + hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx); + } + } + } +#endif /* HAL_DMA_MODULE_ENABLED */ + } + + hi2c->State = HAL_I2C_STATE_BUSY_TX_LISTEN; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR2 &= ~I2C_CR2_NACK; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferSize = hi2c->XferCount; + hi2c->XferOptions = XferOptions; + hi2c->XferISR = I2C_Slave_ISR_IT; + + tmp = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR); + if ((I2C_GET_DIR(hi2c) == I2C_DIRECTION_RECEIVE) && (tmp != RESET)) + { + /* Clear ADDR flag after prepare the transfer parameters */ + /* This action will generate an acknowledge to the Master */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* REnable ADDR interrupt */ + I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT | I2C_XFER_LISTEN_IT); + + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief Sequential transmit in slave/device I2C mode an amount of data in non-blocking mode with DMA + * @note This interface allow to manage repeated start condition when a direction change during transfer + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Seq_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, + uint32_t XferOptions) +{ + /* Declaration of tmp to prevent undefined behavior of volatile usage */ + FlagStatus tmp; + HAL_StatusTypeDef dmaxferstatus; + + /* Check the parameters */ + assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN) + { + if ((pData == NULL) || (Size == 0U)) + { + hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Disable Interrupts, to prevent preemption during treatment in case of multicall */ + I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_TX_IT); + + /* I2C cannot manage full duplex exchange so disable previous IT enabled if any */ + /* and then toggle the HAL slave RX state to TX state */ + if (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN) + { + /* Disable associated Interrupts */ + I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT); + + if ((hi2c->Instance->CR1 & I2C_CR1_RXDMAEN) == I2C_CR1_RXDMAEN) + { + /* Abort DMA Xfer if any */ + if (hi2c->hdmarx != NULL) + { + hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN; + + /* Set the I2C DMA Abort callback : + will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */ + hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort; + + /* Abort DMA RX */ + if (HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK) + { + /* Call Directly XferAbortCallback function in case of error */ + hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx); + } + } + } + } + else if (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN) + { + if ((hi2c->Instance->CR1 & I2C_CR1_TXDMAEN) == I2C_CR1_TXDMAEN) + { + hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN; + + /* Abort DMA Xfer if any */ + if (hi2c->hdmatx != NULL) + { + /* Set the I2C DMA Abort callback : + will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */ + hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort; + + /* Abort DMA TX */ + if (HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK) + { + /* Call Directly XferAbortCallback function in case of error */ + hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx); + } + } + } + } + else + { + /* Nothing to do */ + } + + hi2c->State = HAL_I2C_STATE_BUSY_TX_LISTEN; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR2 &= ~I2C_CR2_NACK; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferSize = hi2c->XferCount; + hi2c->XferOptions = XferOptions; + hi2c->XferISR = I2C_Slave_ISR_DMA; + + if (hi2c->hdmatx != NULL) + { + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmatx->XferCpltCallback = I2C_DMASlaveTransmitCplt; + + /* Set the DMA error callback */ + hi2c->hdmatx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmatx->XferHalfCpltCallback = NULL; + hi2c->hdmatx->XferAbortCallback = NULL; + + /* Enable the DMA channel */ + if ((hi2c->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hi2c->hdmatx->LinkedListQueue != NULL) + { + /* Set DMA data size */ + hi2c->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hi2c->XferSize; + + /* Set DMA source address */ + hi2c->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)pData; + + /* Set DMA destination address */ + hi2c->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] \ + = (uint32_t)&hi2c->Instance->TXDR; + + dmaxferstatus = HAL_DMAEx_List_Start_IT(hi2c->hdmatx); + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_LISTEN; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + else + { + dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->TXDR, + hi2c->XferSize); + } + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_LISTEN; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + if (dmaxferstatus == HAL_OK) + { + /* Update XferCount value */ + hi2c->XferCount -= hi2c->XferSize; + + /* Reset XferSize */ + hi2c->XferSize = 0; + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_LISTEN; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + tmp = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR); + if ((I2C_GET_DIR(hi2c) == I2C_DIRECTION_RECEIVE) && (tmp != RESET)) + { + /* Clear ADDR flag after prepare the transfer parameters */ + /* This action will generate an acknowledge to the Master */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Enable DMA Request */ + hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN; + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR, STOP, NACK, ADDR interrupts */ + I2C_Enable_IRQ(hi2c, I2C_XFER_LISTEN_IT); + + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Sequential receive in slave/device I2C mode an amount of data in non-blocking mode with Interrupt + * @note This interface allow to manage repeated start condition when a direction change during transfer + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, + uint32_t XferOptions) +{ + /* Declaration of tmp to prevent undefined behavior of volatile usage */ + FlagStatus tmp; + + /* Check the parameters */ + assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN) + { + if ((pData == NULL) || (Size == 0U)) + { + hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + + /* Disable Interrupts, to prevent preemption during treatment in case of multicall */ + I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_RX_IT); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* I2C cannot manage full duplex exchange so disable previous IT enabled if any */ + /* and then toggle the HAL slave TX state to RX state */ + if (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN) + { + /* Disable associated Interrupts */ + I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT); + +#if defined(HAL_DMA_MODULE_ENABLED) + if ((hi2c->Instance->CR1 & I2C_CR1_TXDMAEN) == I2C_CR1_TXDMAEN) + { + hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN; + + /* Abort DMA Xfer if any */ + if (hi2c->hdmatx != NULL) + { + /* Set the I2C DMA Abort callback : + will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */ + hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort; + + /* Abort DMA TX */ + if (HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK) + { + /* Call Directly XferAbortCallback function in case of error */ + hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx); + } + } + } +#endif /* HAL_DMA_MODULE_ENABLED */ + } + + hi2c->State = HAL_I2C_STATE_BUSY_RX_LISTEN; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR2 &= ~I2C_CR2_NACK; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferSize = hi2c->XferCount; + hi2c->XferOptions = XferOptions; + hi2c->XferISR = I2C_Slave_ISR_IT; + + tmp = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR); + if ((I2C_GET_DIR(hi2c) == I2C_DIRECTION_TRANSMIT) && (tmp != RESET)) + { + /* Clear ADDR flag after prepare the transfer parameters */ + /* This action will generate an acknowledge to the Master */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* REnable ADDR interrupt */ + I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT | I2C_XFER_LISTEN_IT); + + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief Sequential receive in slave/device I2C mode an amount of data in non-blocking mode with DMA + * @note This interface allow to manage repeated start condition when a direction change during transfer + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Seq_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, + uint32_t XferOptions) +{ + /* Declaration of tmp to prevent undefined behavior of volatile usage */ + FlagStatus tmp; + HAL_StatusTypeDef dmaxferstatus; + + /* Check the parameters */ + assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN) + { + if ((pData == NULL) || (Size == 0U)) + { + hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + + /* Disable Interrupts, to prevent preemption during treatment in case of multicall */ + I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_RX_IT); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* I2C cannot manage full duplex exchange so disable previous IT enabled if any */ + /* and then toggle the HAL slave TX state to RX state */ + if (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN) + { + /* Disable associated Interrupts */ + I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT); + + if ((hi2c->Instance->CR1 & I2C_CR1_TXDMAEN) == I2C_CR1_TXDMAEN) + { + /* Abort DMA Xfer if any */ + if (hi2c->hdmatx != NULL) + { + hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN; + + /* Set the I2C DMA Abort callback : + will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */ + hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort; + + /* Abort DMA TX */ + if (HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK) + { + /* Call Directly XferAbortCallback function in case of error */ + hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx); + } + } + } + } + else if (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN) + { + if ((hi2c->Instance->CR1 & I2C_CR1_RXDMAEN) == I2C_CR1_RXDMAEN) + { + hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN; + + /* Abort DMA Xfer if any */ + if (hi2c->hdmarx != NULL) + { + /* Set the I2C DMA Abort callback : + will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */ + hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort; + + /* Abort DMA RX */ + if (HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK) + { + /* Call Directly XferAbortCallback function in case of error */ + hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx); + } + } + } + } + else + { + /* Nothing to do */ + } + + hi2c->State = HAL_I2C_STATE_BUSY_RX_LISTEN; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR2 &= ~I2C_CR2_NACK; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferSize = hi2c->XferCount; + hi2c->XferOptions = XferOptions; + hi2c->XferISR = I2C_Slave_ISR_DMA; + + if (hi2c->hdmarx != NULL) + { + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmarx->XferCpltCallback = I2C_DMASlaveReceiveCplt; + + /* Set the DMA error callback */ + hi2c->hdmarx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmarx->XferHalfCpltCallback = NULL; + hi2c->hdmarx->XferAbortCallback = NULL; + + /* Enable the DMA channel */ + if ((hi2c->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hi2c->hdmarx->LinkedListQueue != NULL) + { + /* Set DMA data size */ + hi2c->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hi2c->XferSize; + + /* Set DMA source address */ + hi2c->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] \ + = (uint32_t)&hi2c->Instance->RXDR; + + /* Set DMA destination address */ + hi2c->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)pData; + + dmaxferstatus = HAL_DMAEx_List_Start_IT(hi2c->hdmarx); + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_LISTEN; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + else + { + dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData, + hi2c->XferSize); + } + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_LISTEN; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + if (dmaxferstatus == HAL_OK) + { + /* Update XferCount value */ + hi2c->XferCount -= hi2c->XferSize; + + /* Reset XferSize */ + hi2c->XferSize = 0; + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_LISTEN; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + tmp = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR); + if ((I2C_GET_DIR(hi2c) == I2C_DIRECTION_TRANSMIT) && (tmp != RESET)) + { + /* Clear ADDR flag after prepare the transfer parameters */ + /* This action will generate an acknowledge to the Master */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Enable DMA Request */ + hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN; + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* REnable ADDR interrupt */ + I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT | I2C_XFER_LISTEN_IT); + + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Enable the Address listen mode with Interrupt. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c) +{ + if (hi2c->State == HAL_I2C_STATE_READY) + { + hi2c->State = HAL_I2C_STATE_LISTEN; + hi2c->XferISR = I2C_Slave_ISR_IT; + + /* Enable the Address Match interrupt */ + I2C_Enable_IRQ(hi2c, I2C_XFER_LISTEN_IT); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Disable the Address listen mode with Interrupt. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c) +{ + /* Declaration of tmp to prevent undefined behavior of volatile usage */ + uint32_t tmp; + + /* Disable Address listen mode only if a transfer is not ongoing */ + if (hi2c->State == HAL_I2C_STATE_LISTEN) + { + tmp = (uint32_t)(hi2c->State) & I2C_STATE_MSK; + hi2c->PreviousState = tmp | (uint32_t)(hi2c->Mode); + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + hi2c->XferISR = NULL; + + /* Disable the Address Match interrupt */ + I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Abort a master I2C IT or DMA process communication with Interrupt. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress) +{ + if (hi2c->Mode == HAL_I2C_MODE_MASTER) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Disable Interrupts and Store Previous state */ + if (hi2c->State == HAL_I2C_STATE_BUSY_TX) + { + I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT); + hi2c->PreviousState = I2C_STATE_MASTER_BUSY_TX; + } + else if (hi2c->State == HAL_I2C_STATE_BUSY_RX) + { + I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT); + hi2c->PreviousState = I2C_STATE_MASTER_BUSY_RX; + } + else + { + /* Do nothing */ + } + + /* Set State at HAL_I2C_STATE_ABORT */ + hi2c->State = HAL_I2C_STATE_ABORT; + + /* Set NBYTES to 1 to generate a dummy read on I2C peripheral */ + /* Set AUTOEND mode, this will generate a NACK then STOP condition to abort the current transfer */ + I2C_TransferConfig(hi2c, DevAddress, 1, I2C_AUTOEND_MODE, I2C_GENERATE_STOP); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT); + + return HAL_OK; + } + else + { + /* Wrong usage of abort function */ + /* This function should be used only in case of abort monitored by master device */ + return HAL_ERROR; + } +} + +/** + * @} + */ + +/** @defgroup I2C_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @{ + */ + +/** + * @brief This function handles I2C event interrupt request. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c) /* Derogation MISRAC2012-Rule-8.13 */ +{ + /* Get current IT Flags and IT sources value */ + uint32_t itflags = READ_REG(hi2c->Instance->ISR); + uint32_t itsources = READ_REG(hi2c->Instance->CR1); + + /* I2C events treatment -------------------------------------*/ + if (hi2c->XferISR != NULL) + { + hi2c->XferISR(hi2c, itflags, itsources); + } +} + +/** + * @brief This function handles I2C error interrupt request. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c) +{ + uint32_t itflags = READ_REG(hi2c->Instance->ISR); + uint32_t itsources = READ_REG(hi2c->Instance->CR1); + uint32_t tmperror; + + /* I2C Bus error interrupt occurred ------------------------------------*/ + if ((I2C_CHECK_FLAG(itflags, I2C_FLAG_BERR) != RESET) && \ + (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_ERRI) != RESET)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_BERR; + + /* Clear BERR flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_BERR); + } + + /* I2C Over-Run/Under-Run interrupt occurred ----------------------------------------*/ + if ((I2C_CHECK_FLAG(itflags, I2C_FLAG_OVR) != RESET) && \ + (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_ERRI) != RESET)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_OVR; + + /* Clear OVR flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_OVR); + } + + /* I2C Arbitration Loss error interrupt occurred -------------------------------------*/ + if ((I2C_CHECK_FLAG(itflags, I2C_FLAG_ARLO) != RESET) && \ + (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_ERRI) != RESET)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_ARLO; + + /* Clear ARLO flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ARLO); + } + + /* Store current volatile hi2c->ErrorCode, misra rule */ + tmperror = hi2c->ErrorCode; + + /* Call the Error Callback in case of Error detected */ + if ((tmperror & (HAL_I2C_ERROR_BERR | HAL_I2C_ERROR_OVR | HAL_I2C_ERROR_ARLO)) != HAL_I2C_ERROR_NONE) + { + I2C_ITError(hi2c, tmperror); + } +} + +/** + * @brief Master Tx Transfer completed callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_MasterTxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Master Rx Transfer completed callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_MasterRxCpltCallback could be implemented in the user file + */ +} + +/** @brief Slave Tx Transfer completed callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_SlaveTxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Slave Rx Transfer completed callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_SlaveRxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Slave Address Match callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param TransferDirection Master request Transfer Direction (Write/Read), value of @ref I2C_XFERDIRECTION + * @param AddrMatchCode Address Match Code + * @retval None + */ +__weak void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + UNUSED(TransferDirection); + UNUSED(AddrMatchCode); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_AddrCallback() could be implemented in the user file + */ +} + +/** + * @brief Listen Complete callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_ListenCpltCallback() could be implemented in the user file + */ +} + +/** + * @brief Memory Tx Transfer completed callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_MemTxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Memory Rx Transfer completed callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_MemRxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief I2C error callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_ErrorCallback could be implemented in the user file + */ +} + +/** + * @brief I2C abort callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_AbortCpltCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup I2C_Exported_Functions_Group3 Peripheral State, Mode and Error functions + * @brief Peripheral State, Mode and Error functions + * +@verbatim + =============================================================================== + ##### Peripheral State, Mode and Error functions ##### + =============================================================================== + [..] + This subsection permit to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the I2C handle state. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval HAL state + */ +HAL_I2C_StateTypeDef HAL_I2C_GetState(const I2C_HandleTypeDef *hi2c) +{ + /* Return I2C handle state */ + return hi2c->State; +} + +/** + * @brief Returns the I2C Master, Slave, Memory or no mode. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL mode + */ +HAL_I2C_ModeTypeDef HAL_I2C_GetMode(const I2C_HandleTypeDef *hi2c) +{ + return hi2c->Mode; +} + +/** + * @brief Return the I2C error code. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval I2C Error Code + */ +uint32_t HAL_I2C_GetError(const I2C_HandleTypeDef *hi2c) +{ + return hi2c->ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup I2C_Private_Functions + * @{ + */ + +/** + * @brief Interrupt Sub-Routine which handle the Interrupt Flags Master Mode with Interrupt. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param ITFlags Interrupt flags to handle. + * @param ITSources Interrupt sources enabled. + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Master_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, + uint32_t ITSources) +{ + uint16_t devaddress; + uint32_t tmpITFlags = ITFlags; + + /* Process Locked */ + __HAL_LOCK(hi2c); + + if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_AF) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_NACKI) != RESET)) + { + /* Clear NACK Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Set corresponding Error Code */ + /* No need to generate STOP, it is automatically done */ + /* Error callback will be send during stop flag treatment */ + hi2c->ErrorCode |= HAL_I2C_ERROR_AF; + + /* Flush TX register */ + I2C_Flush_TXDR(hi2c); + } + else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_RXNE) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_RXI) != RESET)) + { + /* Remove RXNE flag on temporary variable as read done */ + tmpITFlags &= ~I2C_FLAG_RXNE; + + /* Read data from RXDR */ + *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + hi2c->XferSize--; + hi2c->XferCount--; + } + else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TXIS) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TXI) != RESET)) + { + /* Write data to TXDR */ + hi2c->Instance->TXDR = *hi2c->pBuffPtr; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + hi2c->XferSize--; + hi2c->XferCount--; + } + else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TCR) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET)) + { + if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U)) + { + devaddress = (uint16_t)(hi2c->Instance->CR2 & I2C_CR2_SADD); + + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + I2C_TransferConfig(hi2c, devaddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP); + } + else + { + hi2c->XferSize = hi2c->XferCount; + if (hi2c->XferOptions != I2C_NO_OPTION_FRAME) + { + I2C_TransferConfig(hi2c, devaddress, (uint8_t)hi2c->XferSize, + hi2c->XferOptions, I2C_NO_STARTSTOP); + } + else + { + I2C_TransferConfig(hi2c, devaddress, (uint8_t)hi2c->XferSize, + I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); + } + } + } + else + { + /* Call TxCpltCallback() if no stop mode is set */ + if (I2C_GET_STOP_MODE(hi2c) != I2C_AUTOEND_MODE) + { + /* Call I2C Master Sequential complete process */ + I2C_ITMasterSeqCplt(hi2c); + } + else + { + /* Wrong size Status regarding TCR flag event */ + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE); + } + } + } + else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TC) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET)) + { + if (hi2c->XferCount == 0U) + { + if (I2C_GET_STOP_MODE(hi2c) != I2C_AUTOEND_MODE) + { + /* Generate a stop condition in case of no transfer option */ + if (hi2c->XferOptions == I2C_NO_OPTION_FRAME) + { + /* Generate Stop */ + hi2c->Instance->CR2 |= I2C_CR2_STOP; + } + else + { + /* Call I2C Master Sequential complete process */ + I2C_ITMasterSeqCplt(hi2c); + } + } + } + else + { + /* Wrong size Status regarding TC flag event */ + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE); + } + } + else + { + /* Nothing to do */ + } + + if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_STOPF) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_STOPI) != RESET)) + { + /* Call I2C Master complete process */ + I2C_ITMasterCplt(hi2c, tmpITFlags); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; +} + +/** + * @brief Interrupt Sub-Routine which handle the Interrupt Flags Memory Mode with Interrupt. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param ITFlags Interrupt flags to handle. + * @param ITSources Interrupt sources enabled. + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Mem_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, + uint32_t ITSources) +{ + uint32_t direction = I2C_GENERATE_START_WRITE; + uint32_t tmpITFlags = ITFlags; + + /* Process Locked */ + __HAL_LOCK(hi2c); + + if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_AF) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_NACKI) != RESET)) + { + /* Clear NACK Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Set corresponding Error Code */ + /* No need to generate STOP, it is automatically done */ + /* Error callback will be send during stop flag treatment */ + hi2c->ErrorCode |= HAL_I2C_ERROR_AF; + + /* Flush TX register */ + I2C_Flush_TXDR(hi2c); + } + else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_RXNE) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_RXI) != RESET)) + { + /* Remove RXNE flag on temporary variable as read done */ + tmpITFlags &= ~I2C_FLAG_RXNE; + + /* Read data from RXDR */ + *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + hi2c->XferSize--; + hi2c->XferCount--; + } + else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TXIS) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TXI) != RESET)) + { + if (hi2c->Memaddress == 0xFFFFFFFFU) + { + /* Write data to TXDR */ + hi2c->Instance->TXDR = *hi2c->pBuffPtr; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + hi2c->XferSize--; + hi2c->XferCount--; + } + else + { + /* Write LSB part of Memory Address */ + hi2c->Instance->TXDR = hi2c->Memaddress; + + /* Reset Memaddress content */ + hi2c->Memaddress = 0xFFFFFFFFU; + } + } + else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TCR) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET)) + { + if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U)) + { + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + I2C_TransferConfig(hi2c, (uint16_t)hi2c->Devaddress, (uint8_t)hi2c->XferSize, + I2C_RELOAD_MODE, I2C_NO_STARTSTOP); + } + else + { + hi2c->XferSize = hi2c->XferCount; + I2C_TransferConfig(hi2c, (uint16_t)hi2c->Devaddress, (uint8_t)hi2c->XferSize, + I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); + } + } + else + { + /* Wrong size Status regarding TCR flag event */ + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE); + } + } + else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TC) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET)) + { + /* Disable Interrupt related to address step */ + I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT); + + /* Enable ERR, TC, STOP, NACK and RXI interrupts */ + I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT); + + if (hi2c->State == HAL_I2C_STATE_BUSY_RX) + { + direction = I2C_GENERATE_START_READ; + } + + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + + /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ + I2C_TransferConfig(hi2c, (uint16_t)hi2c->Devaddress, (uint8_t)hi2c->XferSize, + I2C_RELOAD_MODE, direction); + } + else + { + hi2c->XferSize = hi2c->XferCount; + + /* Set NBYTES to write and generate RESTART */ + I2C_TransferConfig(hi2c, (uint16_t)hi2c->Devaddress, (uint8_t)hi2c->XferSize, + I2C_AUTOEND_MODE, direction); + } + } + else + { + /* Nothing to do */ + } + + if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_STOPF) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_STOPI) != RESET)) + { + /* Call I2C Master complete process */ + I2C_ITMasterCplt(hi2c, tmpITFlags); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; +} + +/** + * @brief Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode with Interrupt. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param ITFlags Interrupt flags to handle. + * @param ITSources Interrupt sources enabled. + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Slave_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, + uint32_t ITSources) +{ + uint32_t tmpoptions = hi2c->XferOptions; + uint32_t tmpITFlags = ITFlags; + + /* Process locked */ + __HAL_LOCK(hi2c); + + /* Check if STOPF is set */ + if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_STOPF) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_STOPI) != RESET)) + { + /* Call I2C Slave complete process */ + I2C_ITSlaveCplt(hi2c, tmpITFlags); + } + + if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_AF) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_NACKI) != RESET)) + { + /* Check that I2C transfer finished */ + /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */ + /* Mean XferCount == 0*/ + /* So clear Flag NACKF only */ + if (hi2c->XferCount == 0U) + { + if ((hi2c->State == HAL_I2C_STATE_LISTEN) && (tmpoptions == I2C_FIRST_AND_LAST_FRAME)) + /* Same action must be done for (tmpoptions == I2C_LAST_FRAME) which removed for + Warning[Pa134]: left and right operands are identical */ + { + /* Call I2C Listen complete process */ + I2C_ITListenCplt(hi2c, tmpITFlags); + } + else if ((hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN) && (tmpoptions != I2C_NO_OPTION_FRAME)) + { + /* Clear NACK Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Flush TX register */ + I2C_Flush_TXDR(hi2c); + + /* Last Byte is Transmitted */ + /* Call I2C Slave Sequential complete process */ + I2C_ITSlaveSeqCplt(hi2c); + } + else + { + /* Clear NACK Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + } + } + else + { + /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/ + /* Clear NACK Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Set ErrorCode corresponding to a Non-Acknowledge */ + hi2c->ErrorCode |= HAL_I2C_ERROR_AF; + + if ((tmpoptions == I2C_FIRST_FRAME) || (tmpoptions == I2C_NEXT_FRAME)) + { + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c, hi2c->ErrorCode); + } + } + } + else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_RXNE) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_RXI) != RESET)) + { + if (hi2c->XferCount > 0U) + { + /* Read data from RXDR */ + *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + hi2c->XferSize--; + hi2c->XferCount--; + } + + if ((hi2c->XferCount == 0U) && \ + (tmpoptions != I2C_NO_OPTION_FRAME)) + { + /* Call I2C Slave Sequential complete process */ + I2C_ITSlaveSeqCplt(hi2c); + } + } + else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_ADDR) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_ADDRI) != RESET)) + { + I2C_ITAddrCplt(hi2c, tmpITFlags); + } + else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TXIS) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TXI) != RESET)) + { + /* Write data to TXDR only if XferCount not reach "0" */ + /* A TXIS flag can be set, during STOP treatment */ + /* Check if all Data have already been sent */ + /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */ + if (hi2c->XferCount > 0U) + { + /* Write data to TXDR */ + hi2c->Instance->TXDR = *hi2c->pBuffPtr; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + hi2c->XferCount--; + hi2c->XferSize--; + } + else + { + if ((tmpoptions == I2C_NEXT_FRAME) || (tmpoptions == I2C_FIRST_FRAME)) + { + /* Last Byte is Transmitted */ + /* Call I2C Slave Sequential complete process */ + I2C_ITSlaveSeqCplt(hi2c); + } + } + } + else + { + /* Nothing to do */ + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; +} + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief Interrupt Sub-Routine which handle the Interrupt Flags Master Mode with DMA. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param ITFlags Interrupt flags to handle. + * @param ITSources Interrupt sources enabled. + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Master_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, + uint32_t ITSources) +{ + uint16_t devaddress; + uint32_t xfermode; + + /* Process Locked */ + __HAL_LOCK(hi2c); + + if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_AF) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_NACKI) != RESET)) + { + /* Clear NACK Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Set corresponding Error Code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_AF; + + /* No need to generate STOP, it is automatically done */ + /* But enable STOP interrupt, to treat it */ + /* Error callback will be send during stop flag treatment */ + I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT); + + /* Flush TX register */ + I2C_Flush_TXDR(hi2c); + } + else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_TCR) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET)) + { + /* Disable TC interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_TCI); + + if (hi2c->XferCount != 0U) + { + /* Recover Slave address */ + devaddress = (uint16_t)(hi2c->Instance->CR2 & I2C_CR2_SADD); + + /* Prepare the new XferSize to transfer */ + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + xfermode = I2C_RELOAD_MODE; + } + else + { + hi2c->XferSize = hi2c->XferCount; + if (hi2c->XferOptions != I2C_NO_OPTION_FRAME) + { + xfermode = hi2c->XferOptions; + } + else + { + xfermode = I2C_AUTOEND_MODE; + } + } + + /* Set the new XferSize in Nbytes register */ + I2C_TransferConfig(hi2c, devaddress, (uint8_t)hi2c->XferSize, xfermode, I2C_NO_STARTSTOP); + + /* Update XferCount value */ + hi2c->XferCount -= hi2c->XferSize; + + /* Enable DMA Request */ + if (hi2c->State == HAL_I2C_STATE_BUSY_RX) + { + hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN; + } + else + { + hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN; + } + } + else + { + /* Call TxCpltCallback() if no stop mode is set */ + if (I2C_GET_STOP_MODE(hi2c) != I2C_AUTOEND_MODE) + { + /* Call I2C Master Sequential complete process */ + I2C_ITMasterSeqCplt(hi2c); + } + else + { + /* Wrong size Status regarding TCR flag event */ + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE); + } + } + } + else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_TC) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET)) + { + if (hi2c->XferCount == 0U) + { + if (I2C_GET_STOP_MODE(hi2c) != I2C_AUTOEND_MODE) + { + /* Generate a stop condition in case of no transfer option */ + if (hi2c->XferOptions == I2C_NO_OPTION_FRAME) + { + /* Generate Stop */ + hi2c->Instance->CR2 |= I2C_CR2_STOP; + } + else + { + /* Call I2C Master Sequential complete process */ + I2C_ITMasterSeqCplt(hi2c); + } + } + } + else + { + /* Wrong size Status regarding TC flag event */ + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE); + } + } + else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_STOPF) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_STOPI) != RESET)) + { + /* Call I2C Master complete process */ + I2C_ITMasterCplt(hi2c, ITFlags); + } + else + { + /* Nothing to do */ + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; +} + +/** + * @brief Interrupt Sub-Routine which handle the Interrupt Flags Memory Mode with DMA. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param ITFlags Interrupt flags to handle. + * @param ITSources Interrupt sources enabled. + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Mem_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, + uint32_t ITSources) +{ + uint32_t direction = I2C_GENERATE_START_WRITE; + + /* Process Locked */ + __HAL_LOCK(hi2c); + + if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_AF) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_NACKI) != RESET)) + { + /* Clear NACK Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Set corresponding Error Code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_AF; + + /* No need to generate STOP, it is automatically done */ + /* But enable STOP interrupt, to treat it */ + /* Error callback will be send during stop flag treatment */ + I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT); + + /* Flush TX register */ + I2C_Flush_TXDR(hi2c); + } + else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_TXIS) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TXI) != RESET)) + { + /* Write LSB part of Memory Address */ + hi2c->Instance->TXDR = hi2c->Memaddress; + + /* Reset Memaddress content */ + hi2c->Memaddress = 0xFFFFFFFFU; + } + else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_TCR) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET)) + { + /* Disable Interrupt related to address step */ + I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT); + + /* Enable only Error interrupt */ + I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT); + + if (hi2c->XferCount != 0U) + { + /* Prepare the new XferSize to transfer */ + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + I2C_TransferConfig(hi2c, (uint16_t)hi2c->Devaddress, (uint8_t)hi2c->XferSize, + I2C_RELOAD_MODE, I2C_NO_STARTSTOP); + } + else + { + hi2c->XferSize = hi2c->XferCount; + I2C_TransferConfig(hi2c, (uint16_t)hi2c->Devaddress, (uint8_t)hi2c->XferSize, + I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); + } + + /* Update XferCount value */ + hi2c->XferCount -= hi2c->XferSize; + + /* Enable DMA Request */ + if (hi2c->State == HAL_I2C_STATE_BUSY_RX) + { + hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN; + } + else + { + hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN; + } + } + else + { + /* Wrong size Status regarding TCR flag event */ + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE); + } + } + else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_TC) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET)) + { + /* Disable Interrupt related to address step */ + I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT); + + /* Enable only Error and NACK interrupt for data transfer */ + I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT); + + if (hi2c->State == HAL_I2C_STATE_BUSY_RX) + { + direction = I2C_GENERATE_START_READ; + } + + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + + /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ + I2C_TransferConfig(hi2c, (uint16_t)hi2c->Devaddress, (uint8_t)hi2c->XferSize, + I2C_RELOAD_MODE, direction); + } + else + { + hi2c->XferSize = hi2c->XferCount; + + /* Set NBYTES to write and generate RESTART */ + I2C_TransferConfig(hi2c, (uint16_t)hi2c->Devaddress, (uint8_t)hi2c->XferSize, + I2C_AUTOEND_MODE, direction); + } + + /* Update XferCount value */ + hi2c->XferCount -= hi2c->XferSize; + + /* Enable DMA Request */ + if (hi2c->State == HAL_I2C_STATE_BUSY_RX) + { + hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN; + } + else + { + hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN; + } + } + else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_STOPF) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_STOPI) != RESET)) + { + /* Call I2C Master complete process */ + I2C_ITMasterCplt(hi2c, ITFlags); + } + else + { + /* Nothing to do */ + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; +} + +/** + * @brief Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode with DMA. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param ITFlags Interrupt flags to handle. + * @param ITSources Interrupt sources enabled. + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Slave_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, + uint32_t ITSources) +{ + uint32_t tmpoptions = hi2c->XferOptions; + uint32_t treatdmanack = 0U; + HAL_I2C_StateTypeDef tmpstate; + + /* Process locked */ + __HAL_LOCK(hi2c); + + /* Check if STOPF is set */ + if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_STOPF) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_STOPI) != RESET)) + { + /* Call I2C Slave complete process */ + I2C_ITSlaveCplt(hi2c, ITFlags); + } + + if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_AF) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_NACKI) != RESET)) + { + /* Check that I2C transfer finished */ + /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */ + /* Mean XferCount == 0 */ + /* So clear Flag NACKF only */ + if ((I2C_CHECK_IT_SOURCE(ITSources, I2C_CR1_TXDMAEN) != RESET) || + (I2C_CHECK_IT_SOURCE(ITSources, I2C_CR1_RXDMAEN) != RESET)) + { + /* Split check of hdmarx, for MISRA compliance */ + if (hi2c->hdmarx != NULL) + { + if (I2C_CHECK_IT_SOURCE(ITSources, I2C_CR1_RXDMAEN) != RESET) + { + if (I2C_GET_DMA_REMAIN_DATA(hi2c->hdmarx) == 0U) + { + treatdmanack = 1U; + } + } + } + + /* Split check of hdmatx, for MISRA compliance */ + if (hi2c->hdmatx != NULL) + { + if (I2C_CHECK_IT_SOURCE(ITSources, I2C_CR1_TXDMAEN) != RESET) + { + if (I2C_GET_DMA_REMAIN_DATA(hi2c->hdmatx) == 0U) + { + treatdmanack = 1U; + } + } + } + + if (treatdmanack == 1U) + { + if ((hi2c->State == HAL_I2C_STATE_LISTEN) && (tmpoptions == I2C_FIRST_AND_LAST_FRAME)) + /* Same action must be done for (tmpoptions == I2C_LAST_FRAME) which removed for + Warning[Pa134]: left and right operands are identical */ + { + /* Call I2C Listen complete process */ + I2C_ITListenCplt(hi2c, ITFlags); + } + else if ((hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN) && (tmpoptions != I2C_NO_OPTION_FRAME)) + { + /* Clear NACK Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Flush TX register */ + I2C_Flush_TXDR(hi2c); + + /* Last Byte is Transmitted */ + /* Call I2C Slave Sequential complete process */ + I2C_ITSlaveSeqCplt(hi2c); + } + else + { + /* Clear NACK Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + } + } + else + { + /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/ + /* Clear NACK Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Set ErrorCode corresponding to a Non-Acknowledge */ + hi2c->ErrorCode |= HAL_I2C_ERROR_AF; + + /* Store current hi2c->State, solve MISRA2012-Rule-13.5 */ + tmpstate = hi2c->State; + + if ((tmpoptions == I2C_FIRST_FRAME) || (tmpoptions == I2C_NEXT_FRAME)) + { + if ((tmpstate == HAL_I2C_STATE_BUSY_TX) || (tmpstate == HAL_I2C_STATE_BUSY_TX_LISTEN)) + { + hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX; + } + else if ((tmpstate == HAL_I2C_STATE_BUSY_RX) || (tmpstate == HAL_I2C_STATE_BUSY_RX_LISTEN)) + { + hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_RX; + } + else + { + /* Do nothing */ + } + + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c, hi2c->ErrorCode); + } + } + } + else + { + /* Only Clear NACK Flag, no DMA treatment is pending */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + } + } + else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_ADDR) != RESET) && \ + (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_ADDRI) != RESET)) + { + I2C_ITAddrCplt(hi2c, ITFlags); + } + else + { + /* Nothing to do */ + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Master sends target device address followed by internal memory address for write request. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, + uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, + uint32_t Tickstart) +{ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)MemAddSize, I2C_RELOAD_MODE, I2C_GENERATE_START_WRITE); + + /* Wait until TXIS flag is set */ + if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* If Memory address size is 8Bit */ + if (MemAddSize == I2C_MEMADD_SIZE_8BIT) + { + /* Send Memory Address */ + hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress); + } + /* If Memory address size is 16Bit */ + else + { + /* Send MSB of Memory Address */ + hi2c->Instance->TXDR = I2C_MEM_ADD_MSB(MemAddress); + + /* Wait until TXIS flag is set */ + if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Send LSB of Memory Address */ + hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress); + } + + /* Wait until TCR flag is set */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, Tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Master sends target device address followed by internal memory address for read request. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, + uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, + uint32_t Tickstart) +{ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)MemAddSize, I2C_SOFTEND_MODE, I2C_GENERATE_START_WRITE); + + /* Wait until TXIS flag is set */ + if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* If Memory address size is 8Bit */ + if (MemAddSize == I2C_MEMADD_SIZE_8BIT) + { + /* Send Memory Address */ + hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress); + } + /* If Memory address size is 16Bit */ + else + { + /* Send MSB of Memory Address */ + hi2c->Instance->TXDR = I2C_MEM_ADD_MSB(MemAddress); + + /* Wait until TXIS flag is set */ + if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Send LSB of Memory Address */ + hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress); + } + + /* Wait until TC flag is set */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TC, RESET, Timeout, Tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief I2C Address complete process callback. + * @param hi2c I2C handle. + * @param ITFlags Interrupt flags to handle. + * @retval None + */ +static void I2C_ITAddrCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags) +{ + uint8_t transferdirection; + uint16_t slaveaddrcode; + uint16_t ownadd1code; + uint16_t ownadd2code; + + /* Prevent unused argument(s) compilation warning */ + UNUSED(ITFlags); + + /* In case of Listen state, need to inform upper layer of address match code event */ + if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN) + { + transferdirection = I2C_GET_DIR(hi2c); + slaveaddrcode = I2C_GET_ADDR_MATCH(hi2c); + ownadd1code = I2C_GET_OWN_ADDRESS1(hi2c); + ownadd2code = I2C_GET_OWN_ADDRESS2(hi2c); + + /* If 10bits addressing mode is selected */ + if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT) + { + if ((slaveaddrcode & SLAVE_ADDR_MSK) == ((ownadd1code >> SLAVE_ADDR_SHIFT) & SLAVE_ADDR_MSK)) + { + slaveaddrcode = ownadd1code; + hi2c->AddrEventCount++; + if (hi2c->AddrEventCount == 2U) + { + /* Reset Address Event counter */ + hi2c->AddrEventCount = 0U; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call Slave Addr callback */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->AddrCallback(hi2c, transferdirection, slaveaddrcode); +#else + HAL_I2C_AddrCallback(hi2c, transferdirection, slaveaddrcode); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + } + else + { + slaveaddrcode = ownadd2code; + + /* Disable ADDR Interrupts */ + I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call Slave Addr callback */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->AddrCallback(hi2c, transferdirection, slaveaddrcode); +#else + HAL_I2C_AddrCallback(hi2c, transferdirection, slaveaddrcode); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + } + /* else 7 bits addressing mode is selected */ + else + { + /* Disable ADDR Interrupts */ + I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call Slave Addr callback */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->AddrCallback(hi2c, transferdirection, slaveaddrcode); +#else + HAL_I2C_AddrCallback(hi2c, transferdirection, slaveaddrcode); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + } + /* Else clear address flag only */ + else + { + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + } +} + +/** + * @brief I2C Master sequential complete process. + * @param hi2c I2C handle. + * @retval None + */ +static void I2C_ITMasterSeqCplt(I2C_HandleTypeDef *hi2c) +{ + /* Reset I2C handle mode */ + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* No Generate Stop, to permit restart mode */ + /* The stop will be done at the end of transfer, when I2C_AUTOEND_MODE enable */ + if (hi2c->State == HAL_I2C_STATE_BUSY_TX) + { + hi2c->State = HAL_I2C_STATE_READY; + hi2c->PreviousState = I2C_STATE_MASTER_BUSY_TX; + hi2c->XferISR = NULL; + + /* Disable Interrupts */ + I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->MasterTxCpltCallback(hi2c); +#else + HAL_I2C_MasterTxCpltCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + /* hi2c->State == HAL_I2C_STATE_BUSY_RX */ + else + { + hi2c->State = HAL_I2C_STATE_READY; + hi2c->PreviousState = I2C_STATE_MASTER_BUSY_RX; + hi2c->XferISR = NULL; + + /* Disable Interrupts */ + I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->MasterRxCpltCallback(hi2c); +#else + HAL_I2C_MasterRxCpltCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } +} + +/** + * @brief I2C Slave sequential complete process. + * @param hi2c I2C handle. + * @retval None + */ +static void I2C_ITSlaveSeqCplt(I2C_HandleTypeDef *hi2c) +{ + uint32_t tmpcr1value = READ_REG(hi2c->Instance->CR1); + + /* Reset I2C handle mode */ + hi2c->Mode = HAL_I2C_MODE_NONE; + +#if defined(HAL_DMA_MODULE_ENABLED) + /* If a DMA is ongoing, Update handle size context */ + if (I2C_CHECK_IT_SOURCE(tmpcr1value, I2C_CR1_TXDMAEN) != RESET) + { + /* Disable DMA Request */ + hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN; + } + else if (I2C_CHECK_IT_SOURCE(tmpcr1value, I2C_CR1_RXDMAEN) != RESET) + { + /* Disable DMA Request */ + hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN; + } + else + { + /* Do nothing */ + } +#endif /* HAL_DMA_MODULE_ENABLED */ + + if (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN) + { + /* Remove HAL_I2C_STATE_SLAVE_BUSY_TX, keep only HAL_I2C_STATE_LISTEN */ + hi2c->State = HAL_I2C_STATE_LISTEN; + hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX; + + /* Disable Interrupts */ + I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->SlaveTxCpltCallback(hi2c); +#else + HAL_I2C_SlaveTxCpltCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + + else if (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN) + { + /* Remove HAL_I2C_STATE_SLAVE_BUSY_RX, keep only HAL_I2C_STATE_LISTEN */ + hi2c->State = HAL_I2C_STATE_LISTEN; + hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_RX; + + /* Disable Interrupts */ + I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->SlaveRxCpltCallback(hi2c); +#else + HAL_I2C_SlaveRxCpltCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + else + { + /* Nothing to do */ + } +} + +/** + * @brief I2C Master complete process. + * @param hi2c I2C handle. + * @param ITFlags Interrupt flags to handle. + * @retval None + */ +static void I2C_ITMasterCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags) +{ + uint32_t tmperror; + uint32_t tmpITFlags = ITFlags; + __IO uint32_t tmpreg; + + /* Clear STOP Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + + /* Disable Interrupts and Store Previous state */ + if (hi2c->State == HAL_I2C_STATE_BUSY_TX) + { + I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT); + hi2c->PreviousState = I2C_STATE_MASTER_BUSY_TX; + } + else if (hi2c->State == HAL_I2C_STATE_BUSY_RX) + { + I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT); + hi2c->PreviousState = I2C_STATE_MASTER_BUSY_RX; + } + else + { + /* Do nothing */ + } + + /* Clear Configuration Register 2 */ + I2C_RESET_CR2(hi2c); + + /* Reset handle parameters */ + hi2c->XferISR = NULL; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + + if (I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_AF) != RESET) + { + /* Clear NACK Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Set acknowledge error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_AF; + } + + /* Fetch Last receive data if any */ + if ((hi2c->State == HAL_I2C_STATE_ABORT) && (I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_RXNE) != RESET)) + { + /* Read data from RXDR */ + tmpreg = (uint8_t)hi2c->Instance->RXDR; + UNUSED(tmpreg); + } + + /* Flush TX register */ + I2C_Flush_TXDR(hi2c); + + /* Store current volatile hi2c->ErrorCode, misra rule */ + tmperror = hi2c->ErrorCode; + + /* Call the corresponding callback to inform upper layer of End of Transfer */ + if ((hi2c->State == HAL_I2C_STATE_ABORT) || (tmperror != HAL_I2C_ERROR_NONE)) + { + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c, hi2c->ErrorCode); + } + /* hi2c->State == HAL_I2C_STATE_BUSY_TX */ + else if (hi2c->State == HAL_I2C_STATE_BUSY_TX) + { + hi2c->State = HAL_I2C_STATE_READY; + hi2c->PreviousState = I2C_STATE_NONE; + + if (hi2c->Mode == HAL_I2C_MODE_MEM) + { + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->MemTxCpltCallback(hi2c); +#else + HAL_I2C_MemTxCpltCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + else + { + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->MasterTxCpltCallback(hi2c); +#else + HAL_I2C_MasterTxCpltCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + } + /* hi2c->State == HAL_I2C_STATE_BUSY_RX */ + else if (hi2c->State == HAL_I2C_STATE_BUSY_RX) + { + hi2c->State = HAL_I2C_STATE_READY; + hi2c->PreviousState = I2C_STATE_NONE; + + if (hi2c->Mode == HAL_I2C_MODE_MEM) + { + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->MemRxCpltCallback(hi2c); +#else + HAL_I2C_MemRxCpltCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + else + { + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->MasterRxCpltCallback(hi2c); +#else + HAL_I2C_MasterRxCpltCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + } + else + { + /* Nothing to do */ + } +} + +/** + * @brief I2C Slave complete process. + * @param hi2c I2C handle. + * @param ITFlags Interrupt flags to handle. + * @retval None + */ +static void I2C_ITSlaveCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags) +{ + uint32_t tmpcr1value = READ_REG(hi2c->Instance->CR1); + uint32_t tmpITFlags = ITFlags; + HAL_I2C_StateTypeDef tmpstate = hi2c->State; + + /* Clear STOP Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + + /* Disable Interrupts and Store Previous state */ + if ((tmpstate == HAL_I2C_STATE_BUSY_TX) || (tmpstate == HAL_I2C_STATE_BUSY_TX_LISTEN)) + { + I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_TX_IT); + hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX; + } + else if ((tmpstate == HAL_I2C_STATE_BUSY_RX) || (tmpstate == HAL_I2C_STATE_BUSY_RX_LISTEN)) + { + I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_RX_IT); + hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_RX; + } + else if (tmpstate == HAL_I2C_STATE_LISTEN) + { + I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_TX_IT | I2C_XFER_RX_IT); + hi2c->PreviousState = I2C_STATE_NONE; + } + else + { + /* Do nothing */ + } + + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + + /* Clear Configuration Register 2 */ + I2C_RESET_CR2(hi2c); + + /* Flush TX register */ + I2C_Flush_TXDR(hi2c); + +#if defined(HAL_DMA_MODULE_ENABLED) + /* If a DMA is ongoing, Update handle size context */ + if (I2C_CHECK_IT_SOURCE(tmpcr1value, I2C_CR1_TXDMAEN) != RESET) + { + /* Disable DMA Request */ + hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN; + + if (hi2c->hdmatx != NULL) + { + hi2c->XferCount = (uint16_t)I2C_GET_DMA_REMAIN_DATA(hi2c->hdmatx); + } + } + else if (I2C_CHECK_IT_SOURCE(tmpcr1value, I2C_CR1_RXDMAEN) != RESET) + { + /* Disable DMA Request */ + hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN; + + if (hi2c->hdmarx != NULL) + { + hi2c->XferCount = (uint16_t)I2C_GET_DMA_REMAIN_DATA(hi2c->hdmarx); + } + } + else + { + /* Do nothing */ + } +#endif /* HAL_DMA_MODULE_ENABLED */ + + /* Store Last receive data if any */ + if (I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_RXNE) != RESET) + { + /* Remove RXNE flag on temporary variable as read done */ + tmpITFlags &= ~I2C_FLAG_RXNE; + + /* Read data from RXDR */ + *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + if ((hi2c->XferSize > 0U)) + { + hi2c->XferSize--; + hi2c->XferCount--; + } + } + + /* All data are not transferred, so set error code accordingly */ + if (hi2c->XferCount != 0U) + { + /* Set ErrorCode corresponding to a Non-Acknowledge */ + hi2c->ErrorCode |= HAL_I2C_ERROR_AF; + } + + hi2c->Mode = HAL_I2C_MODE_NONE; + hi2c->XferISR = NULL; + + if (hi2c->ErrorCode != HAL_I2C_ERROR_NONE) + { + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c, hi2c->ErrorCode); + + /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ + if (hi2c->State == HAL_I2C_STATE_LISTEN) + { + /* Call I2C Listen complete process */ + I2C_ITListenCplt(hi2c, tmpITFlags); + } + } + else if (hi2c->XferOptions != I2C_NO_OPTION_FRAME) + { + /* Call the Sequential Complete callback, to inform upper layer of the end of Transfer */ + I2C_ITSlaveSeqCplt(hi2c); + + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->State = HAL_I2C_STATE_READY; + hi2c->PreviousState = I2C_STATE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->ListenCpltCallback(hi2c); +#else + HAL_I2C_ListenCpltCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + /* Call the corresponding callback to inform upper layer of End of Transfer */ + else if (hi2c->State == HAL_I2C_STATE_BUSY_RX) + { + hi2c->State = HAL_I2C_STATE_READY; + hi2c->PreviousState = I2C_STATE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->SlaveRxCpltCallback(hi2c); +#else + HAL_I2C_SlaveRxCpltCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + else + { + hi2c->State = HAL_I2C_STATE_READY; + hi2c->PreviousState = I2C_STATE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->SlaveTxCpltCallback(hi2c); +#else + HAL_I2C_SlaveTxCpltCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } +} + +/** + * @brief I2C Listen complete process. + * @param hi2c I2C handle. + * @param ITFlags Interrupt flags to handle. + * @retval None + */ +static void I2C_ITListenCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags) +{ + /* Reset handle parameters */ + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + hi2c->XferISR = NULL; + + /* Store Last receive data if any */ + if (I2C_CHECK_FLAG(ITFlags, I2C_FLAG_RXNE) != RESET) + { + /* Read data from RXDR */ + *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + if ((hi2c->XferSize > 0U)) + { + hi2c->XferSize--; + hi2c->XferCount--; + + /* Set ErrorCode corresponding to a Non-Acknowledge */ + hi2c->ErrorCode |= HAL_I2C_ERROR_AF; + } + } + + /* Disable all Interrupts*/ + I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_RX_IT | I2C_XFER_TX_IT); + + /* Clear NACK Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->ListenCpltCallback(hi2c); +#else + HAL_I2C_ListenCpltCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ +} + +/** + * @brief I2C interrupts error process. + * @param hi2c I2C handle. + * @param ErrorCode Error code to handle. + * @retval None + */ +static void I2C_ITError(I2C_HandleTypeDef *hi2c, uint32_t ErrorCode) +{ + HAL_I2C_StateTypeDef tmpstate = hi2c->State; + +#if defined(HAL_DMA_MODULE_ENABLED) + uint32_t tmppreviousstate; +#endif /* HAL_DMA_MODULE_ENABLED */ + + /* Reset handle parameters */ + hi2c->Mode = HAL_I2C_MODE_NONE; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferCount = 0U; + + /* Set new error code */ + hi2c->ErrorCode |= ErrorCode; + + /* Disable Interrupts */ + if ((tmpstate == HAL_I2C_STATE_LISTEN) || + (tmpstate == HAL_I2C_STATE_BUSY_TX_LISTEN) || + (tmpstate == HAL_I2C_STATE_BUSY_RX_LISTEN)) + { + /* Disable all interrupts, except interrupts related to LISTEN state */ + I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT | I2C_XFER_TX_IT); + + /* keep HAL_I2C_STATE_LISTEN if set */ + hi2c->State = HAL_I2C_STATE_LISTEN; + hi2c->XferISR = I2C_Slave_ISR_IT; + } + else + { + /* Disable all interrupts */ + I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_RX_IT | I2C_XFER_TX_IT); + + /* Flush TX register */ + I2C_Flush_TXDR(hi2c); + + /* If state is an abort treatment on going, don't change state */ + /* This change will be do later */ + if (hi2c->State != HAL_I2C_STATE_ABORT) + { + /* Set HAL_I2C_STATE_READY */ + hi2c->State = HAL_I2C_STATE_READY; + + /* Check if a STOPF is detected */ + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET) + { + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) + { + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + hi2c->ErrorCode |= HAL_I2C_ERROR_AF; + } + + /* Clear STOP Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + } + + } + hi2c->XferISR = NULL; + } + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Abort DMA TX transfer if any */ + tmppreviousstate = hi2c->PreviousState; + + if ((hi2c->hdmatx != NULL) && ((tmppreviousstate == I2C_STATE_MASTER_BUSY_TX) || \ + (tmppreviousstate == I2C_STATE_SLAVE_BUSY_TX))) + { + if ((hi2c->Instance->CR1 & I2C_CR1_TXDMAEN) == I2C_CR1_TXDMAEN) + { + hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN; + } + + if (HAL_DMA_GetState(hi2c->hdmatx) != HAL_DMA_STATE_READY) + { + /* Set the I2C DMA Abort callback : + will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */ + hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Abort DMA TX */ + if (HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK) + { + /* Call Directly XferAbortCallback function in case of error */ + hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx); + } + } + else + { + I2C_TreatErrorCallback(hi2c); + } + } + /* Abort DMA RX transfer if any */ + else if ((hi2c->hdmarx != NULL) && ((tmppreviousstate == I2C_STATE_MASTER_BUSY_RX) || \ + (tmppreviousstate == I2C_STATE_SLAVE_BUSY_RX))) + { + if ((hi2c->Instance->CR1 & I2C_CR1_RXDMAEN) == I2C_CR1_RXDMAEN) + { + hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN; + } + + if (HAL_DMA_GetState(hi2c->hdmarx) != HAL_DMA_STATE_READY) + { + /* Set the I2C DMA Abort callback : + will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */ + hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Abort DMA RX */ + if (HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK) + { + /* Call Directly hi2c->hdmarx->XferAbortCallback function in case of error */ + hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx); + } + } + else + { + I2C_TreatErrorCallback(hi2c); + } + } + else +#endif /* HAL_DMA_MODULE_ENABLED */ + { + I2C_TreatErrorCallback(hi2c); + } +} + +/** + * @brief I2C Error callback treatment. + * @param hi2c I2C handle. + * @retval None + */ +static void I2C_TreatErrorCallback(I2C_HandleTypeDef *hi2c) +{ + if (hi2c->State == HAL_I2C_STATE_ABORT) + { + hi2c->State = HAL_I2C_STATE_READY; + hi2c->PreviousState = I2C_STATE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->AbortCpltCallback(hi2c); +#else + HAL_I2C_AbortCpltCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + else + { + hi2c->PreviousState = I2C_STATE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->ErrorCallback(hi2c); +#else + HAL_I2C_ErrorCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } +} + +/** + * @brief I2C Tx data register flush process. + * @param hi2c I2C handle. + * @retval None + */ +static void I2C_Flush_TXDR(I2C_HandleTypeDef *hi2c) +{ + /* If a pending TXIS flag is set */ + /* Write a dummy data in TXDR to clear it */ + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) != RESET) + { + hi2c->Instance->TXDR = 0x00U; + } + + /* Flush TX register if not empty */ + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE) == RESET) + { + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_TXE); + } +} + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief DMA I2C master transmit process complete callback. + * @param hdma DMA handle + * @retval None + */ +static void I2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma) +{ + HAL_StatusTypeDef dmaxferstatus = HAL_OK; + /* Derogation MISRAC2012-Rule-11.5 */ + I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); + + /* Disable DMA Request */ + hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN; + + /* If last transfer, enable STOP interrupt */ + if (hi2c->XferCount == 0U) + { + /* Enable STOP interrupt */ + I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT); + } + /* else prepare a new DMA transfer and enable TCReload interrupt */ + else + { + /* Update Buffer pointer */ + hi2c->pBuffPtr += hi2c->XferSize; + + /* Set the XferSize to transfer */ + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + } + else + { + hi2c->XferSize = hi2c->XferCount; + } + + /* Enable the DMA channel */ + if ((hi2c->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hi2c->hdmatx->LinkedListQueue != NULL) + { + /* Set DMA data size */ + hi2c->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hi2c->XferSize; + + /* Set DMA source address */ + hi2c->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)hi2c->pBuffPtr; + + /* Set DMA destination address */ + hi2c->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)&hi2c->Instance->TXDR; + + dmaxferstatus = HAL_DMAEx_List_Start_IT(hi2c->hdmatx); + } + else + { + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c, HAL_I2C_ERROR_DMA); + } + } + else + { + dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->TXDR, + hi2c->XferSize); + } + + if (dmaxferstatus != HAL_OK) + { + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c, HAL_I2C_ERROR_DMA); + } + else + { + /* Enable TC interrupts */ + I2C_Enable_IRQ(hi2c, I2C_XFER_RELOAD_IT); + } + } +} + + +/** + * @brief DMA I2C slave transmit process complete callback. + * @param hdma DMA handle + * @retval None + */ +static void I2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma) +{ + /* Derogation MISRAC2012-Rule-11.5 */ + I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); + uint32_t tmpoptions = hi2c->XferOptions; + + if ((tmpoptions == I2C_NEXT_FRAME) || (tmpoptions == I2C_FIRST_FRAME)) + { + /* Disable DMA Request */ + hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN; + + /* Last Byte is Transmitted */ + /* Call I2C Slave Sequential complete process */ + I2C_ITSlaveSeqCplt(hi2c); + } + else + { + /* No specific action, Master fully manage the generation of STOP condition */ + /* Mean that this generation can arrive at any time, at the end or during DMA process */ + /* So STOP condition should be manage through Interrupt treatment */ + } +} + + +/** + * @brief DMA I2C master receive process complete callback. + * @param hdma DMA handle + * @retval None + */ +static void I2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma) +{ + HAL_StatusTypeDef dmaxferstatus = HAL_OK; + /* Derogation MISRAC2012-Rule-11.5 */ + I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); + + /* Disable DMA Request */ + hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN; + + /* If last transfer, enable STOP interrupt */ + if (hi2c->XferCount == 0U) + { + /* Enable STOP interrupt */ + I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT); + } + /* else prepare a new DMA transfer and enable TCReload interrupt */ + else + { + /* Update Buffer pointer */ + hi2c->pBuffPtr += hi2c->XferSize; + + /* Set the XferSize to transfer */ + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + } + else + { + hi2c->XferSize = hi2c->XferCount; + } + + /* Enable the DMA channel */ + if ((hi2c->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hi2c->hdmarx->LinkedListQueue != NULL) + { + /* Set DMA data size */ + hi2c->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hi2c->XferSize; + + /* Set DMA source address */ + hi2c->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)&hi2c->Instance->RXDR; + + /* Set DMA destination address */ + hi2c->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)hi2c->pBuffPtr; + + dmaxferstatus = HAL_DMAEx_List_Start_IT(hi2c->hdmarx); + } + else + { + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c, HAL_I2C_ERROR_DMA); + } + } + else + { + dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)hi2c->pBuffPtr, + hi2c->XferSize); + } + + if (dmaxferstatus != HAL_OK) + { + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c, HAL_I2C_ERROR_DMA); + } + else + { + /* Enable TC interrupts */ + I2C_Enable_IRQ(hi2c, I2C_XFER_RELOAD_IT); + } + } +} + + +/** + * @brief DMA I2C slave receive process complete callback. + * @param hdma DMA handle + * @retval None + */ +static void I2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma) +{ + /* Derogation MISRAC2012-Rule-11.5 */ + I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); + uint32_t tmpoptions = hi2c->XferOptions; + + if ((I2C_GET_DMA_REMAIN_DATA(hi2c->hdmarx) == 0U) && \ + (tmpoptions != I2C_NO_OPTION_FRAME)) + { + /* Disable DMA Request */ + hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN; + + /* Call I2C Slave Sequential complete process */ + I2C_ITSlaveSeqCplt(hi2c); + } + else + { + /* No specific action, Master fully manage the generation of STOP condition */ + /* Mean that this generation can arrive at any time, at the end or during DMA process */ + /* So STOP condition should be manage through Interrupt treatment */ + } +} + + +/** + * @brief DMA I2C communication error callback. + * @param hdma DMA handle + * @retval None + */ +static void I2C_DMAError(DMA_HandleTypeDef *hdma) +{ + /* Derogation MISRAC2012-Rule-11.5 */ + I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); + + /* Disable Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c, HAL_I2C_ERROR_DMA); +} + + +/** + * @brief DMA I2C communication abort callback + * (To be called at end of DMA Abort procedure). + * @param hdma DMA handle. + * @retval None + */ +static void I2C_DMAAbort(DMA_HandleTypeDef *hdma) +{ + /* Derogation MISRAC2012-Rule-11.5 */ + I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); + + /* Reset AbortCpltCallback */ + if (hi2c->hdmatx != NULL) + { + hi2c->hdmatx->XferAbortCallback = NULL; + } + if (hi2c->hdmarx != NULL) + { + hi2c->hdmarx->XferAbortCallback = NULL; + } + + I2C_TreatErrorCallback(hi2c); +} + +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief This function handles I2C Communication Timeout. It waits + * until a flag is no longer in the specified status. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param Flag Specifies the I2C flag to check. + * @param Status The actual Flag status (SET or RESET). + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, + uint32_t Timeout, uint32_t Tickstart) +{ + while (__HAL_I2C_GET_FLAG(hi2c, Flag) == Status) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + { + if ((__HAL_I2C_GET_FLAG(hi2c, Flag) == Status)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + } + } + } + return HAL_OK; +} + +/** + * @brief This function handles I2C Communication Timeout for specific usage of TXIS flag. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_WaitOnTXISFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, + uint32_t Tickstart) +{ + while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) == RESET) + { + /* Check if an error is detected */ + if (I2C_IsErrorOccurred(hi2c, Timeout, Tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + { + if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) == RESET)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + } + } + return HAL_OK; +} + +/** + * @brief This function handles I2C Communication Timeout for specific usage of STOP flag. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, + uint32_t Tickstart) +{ + while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET) + { + /* Check if an error is detected */ + if (I2C_IsErrorOccurred(hi2c, Timeout, Tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Check for the Timeout */ + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + { + if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + } + return HAL_OK; +} + +/** + * @brief This function handles I2C Communication Timeout for specific usage of RXNE flag. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, + uint32_t Tickstart) +{ + while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == RESET) + { + /* Check if an error is detected */ + if (I2C_IsErrorOccurred(hi2c, Timeout, Tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Check if a STOPF is detected */ + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET) + { + /* Check if an RXNE is pending */ + /* Store Last receive data if any */ + if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) && (hi2c->XferSize > 0U)) + { + /* Return HAL_OK */ + /* The Reading of data from RXDR will be done in caller function */ + return HAL_OK; + } + else + { + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) + { + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + hi2c->ErrorCode = HAL_I2C_ERROR_AF; + } + else + { + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + } + + /* Clear STOP Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + I2C_RESET_CR2(hi2c); + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + + /* Check for the Timeout */ + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + { + if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == RESET)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + } + return HAL_OK; +} + +/** + * @brief This function handles errors detection during an I2C Communication. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_IsErrorOccurred(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t itflag = hi2c->Instance->ISR; + uint32_t error_code = 0; + uint32_t tickstart = Tickstart; + uint32_t tmp1; + HAL_I2C_ModeTypeDef tmp2; + + if (HAL_IS_BIT_SET(itflag, I2C_FLAG_AF)) + { + /* Clear NACKF Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Wait until STOP Flag is set or timeout occurred */ + /* AutoEnd should be initiate after AF */ + while ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET) && (status == HAL_OK)) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + tmp1 = (uint32_t)(hi2c->Instance->CR2 & I2C_CR2_STOP); + tmp2 = hi2c->Mode; + + /* In case of I2C still busy, try to regenerate a STOP manually */ + if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET) && \ + (tmp1 != I2C_CR2_STOP) && \ + (tmp2 != HAL_I2C_MODE_SLAVE)) + { + /* Generate Stop */ + hi2c->Instance->CR2 |= I2C_CR2_STOP; + + /* Update Tick with new reference */ + tickstart = HAL_GetTick(); + } + + while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET) + { + /* Check for the Timeout */ + if ((HAL_GetTick() - tickstart) > I2C_TIMEOUT_STOPF) + { + error_code |= HAL_I2C_ERROR_TIMEOUT; + + status = HAL_ERROR; + + break; + } + } + } + } + } + + /* In case STOP Flag is detected, clear it */ + if (status == HAL_OK) + { + /* Clear STOP Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + } + + error_code |= HAL_I2C_ERROR_AF; + + status = HAL_ERROR; + } + + /* Refresh Content of Status register */ + itflag = hi2c->Instance->ISR; + + /* Then verify if an additional errors occurs */ + /* Check if a Bus error occurred */ + if (HAL_IS_BIT_SET(itflag, I2C_FLAG_BERR)) + { + error_code |= HAL_I2C_ERROR_BERR; + + /* Clear BERR flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_BERR); + + status = HAL_ERROR; + } + + /* Check if an Over-Run/Under-Run error occurred */ + if (HAL_IS_BIT_SET(itflag, I2C_FLAG_OVR)) + { + error_code |= HAL_I2C_ERROR_OVR; + + /* Clear OVR flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_OVR); + + status = HAL_ERROR; + } + + /* Check if an Arbitration Loss error occurred */ + if (HAL_IS_BIT_SET(itflag, I2C_FLAG_ARLO)) + { + error_code |= HAL_I2C_ERROR_ARLO; + + /* Clear ARLO flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ARLO); + + status = HAL_ERROR; + } + + if (status != HAL_OK) + { + /* Flush TX register */ + I2C_Flush_TXDR(hi2c); + + /* Clear Configuration Register 2 */ + I2C_RESET_CR2(hi2c); + + hi2c->ErrorCode |= error_code; + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + } + + return status; +} + +/** + * @brief Handles I2Cx communication when starting transfer or during transfer (TC or TCR flag are set). + * @param hi2c I2C handle. + * @param DevAddress Specifies the slave address to be programmed. + * @param Size Specifies the number of bytes to be programmed. + * This parameter must be a value between 0 and 255. + * @param Mode New state of the I2C START condition generation. + * This parameter can be one of the following values: + * @arg @ref I2C_RELOAD_MODE Enable Reload mode . + * @arg @ref I2C_AUTOEND_MODE Enable Automatic end mode. + * @arg @ref I2C_SOFTEND_MODE Enable Software end mode. + * @param Request New state of the I2C START condition generation. + * This parameter can be one of the following values: + * @arg @ref I2C_NO_STARTSTOP Don't Generate stop and start condition. + * @arg @ref I2C_GENERATE_STOP Generate stop condition (Size should be set to 0). + * @arg @ref I2C_GENERATE_START_READ Generate Restart for read request. + * @arg @ref I2C_GENERATE_START_WRITE Generate Restart for write request. + * @retval None + */ +static void I2C_TransferConfig(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode, + uint32_t Request) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); + assert_param(IS_TRANSFER_MODE(Mode)); + assert_param(IS_TRANSFER_REQUEST(Request)); + + /* Declaration of tmp to prevent undefined behavior of volatile usage */ + uint32_t tmp = ((uint32_t)(((uint32_t)DevAddress & I2C_CR2_SADD) | \ + (((uint32_t)Size << I2C_CR2_NBYTES_Pos) & I2C_CR2_NBYTES) | \ + (uint32_t)Mode | (uint32_t)Request) & (~0x80000000U)); + + /* update CR2 register */ + MODIFY_REG(hi2c->Instance->CR2, \ + ((I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | \ + (I2C_CR2_RD_WRN & (uint32_t)(Request >> (31U - I2C_CR2_RD_WRN_Pos))) | \ + I2C_CR2_START | I2C_CR2_STOP)), tmp); +} + +/** + * @brief Manage the enabling of Interrupts. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param InterruptRequest Value of @ref I2C_Interrupt_configuration_definition. + * @retval None + */ +static void I2C_Enable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest) +{ + uint32_t tmpisr = 0U; + +#if defined(HAL_DMA_MODULE_ENABLED) + if ((hi2c->XferISR != I2C_Master_ISR_DMA) && \ + (hi2c->XferISR != I2C_Slave_ISR_DMA) && \ + (hi2c->XferISR != I2C_Mem_ISR_DMA)) +#endif /* HAL_DMA_MODULE_ENABLED */ + { + if ((InterruptRequest & I2C_XFER_LISTEN_IT) == I2C_XFER_LISTEN_IT) + { + /* Enable ERR, STOP, NACK and ADDR interrupts */ + tmpisr |= I2C_IT_ADDRI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI; + } + + if ((InterruptRequest & I2C_XFER_TX_IT) == I2C_XFER_TX_IT) + { + /* Enable ERR, TC, STOP, NACK and TXI interrupts */ + tmpisr |= I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_TXI; + } + + if ((InterruptRequest & I2C_XFER_RX_IT) == I2C_XFER_RX_IT) + { + /* Enable ERR, TC, STOP, NACK and RXI interrupts */ + tmpisr |= I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_RXI; + } + + if (InterruptRequest == I2C_XFER_ERROR_IT) + { + /* Enable ERR and NACK interrupts */ + tmpisr |= I2C_IT_ERRI | I2C_IT_NACKI; + } + + if (InterruptRequest == I2C_XFER_CPLT_IT) + { + /* Enable STOP interrupts */ + tmpisr |= I2C_IT_STOPI; + } + } + +#if defined(HAL_DMA_MODULE_ENABLED) + else + { + if ((InterruptRequest & I2C_XFER_LISTEN_IT) == I2C_XFER_LISTEN_IT) + { + /* Enable ERR, STOP, NACK and ADDR interrupts */ + tmpisr |= I2C_IT_ADDRI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI; + } + + if ((InterruptRequest & I2C_XFER_TX_IT) == I2C_XFER_TX_IT) + { + /* Enable ERR, TC, STOP, NACK and TXI interrupts */ + tmpisr |= I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_TXI; + } + + if ((InterruptRequest & I2C_XFER_RX_IT) == I2C_XFER_RX_IT) + { + /* Enable ERR, TC, STOP, NACK and RXI interrupts */ + tmpisr |= I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_RXI; + } + + if (InterruptRequest == I2C_XFER_ERROR_IT) + { + /* Enable ERR and NACK interrupts */ + tmpisr |= I2C_IT_ERRI | I2C_IT_NACKI; + } + + if (InterruptRequest == I2C_XFER_CPLT_IT) + { + /* Enable STOP interrupts */ + tmpisr |= (I2C_IT_STOPI | I2C_IT_TCI); + } + + if (InterruptRequest == I2C_XFER_RELOAD_IT) + { + /* Enable TC interrupts */ + tmpisr |= I2C_IT_TCI; + } + } +#endif /* HAL_DMA_MODULE_ENABLED */ + + /* Enable interrupts only at the end */ + /* to avoid the risk of I2C interrupt handle execution before */ + /* all interrupts requested done */ + __HAL_I2C_ENABLE_IT(hi2c, tmpisr); +} + +/** + * @brief Manage the disabling of Interrupts. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param InterruptRequest Value of @ref I2C_Interrupt_configuration_definition. + * @retval None + */ +static void I2C_Disable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest) +{ + uint32_t tmpisr = 0U; + + if ((InterruptRequest & I2C_XFER_TX_IT) == I2C_XFER_TX_IT) + { + /* Disable TC and TXI interrupts */ + tmpisr |= I2C_IT_TCI | I2C_IT_TXI; + + if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) != (uint32_t)HAL_I2C_STATE_LISTEN) + { + /* Disable NACK and STOP interrupts */ + tmpisr |= I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI; + } + } + + if ((InterruptRequest & I2C_XFER_RX_IT) == I2C_XFER_RX_IT) + { + /* Disable TC and RXI interrupts */ + tmpisr |= I2C_IT_TCI | I2C_IT_RXI; + + if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) != (uint32_t)HAL_I2C_STATE_LISTEN) + { + /* Disable NACK and STOP interrupts */ + tmpisr |= I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI; + } + } + + if ((InterruptRequest & I2C_XFER_LISTEN_IT) == I2C_XFER_LISTEN_IT) + { + /* Disable ADDR, NACK and STOP interrupts */ + tmpisr |= I2C_IT_ADDRI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI; + } + + if (InterruptRequest == I2C_XFER_ERROR_IT) + { + /* Enable ERR and NACK interrupts */ + tmpisr |= I2C_IT_ERRI | I2C_IT_NACKI; + } + + if (InterruptRequest == I2C_XFER_CPLT_IT) + { + /* Enable STOP interrupts */ + tmpisr |= I2C_IT_STOPI; + } + + if (InterruptRequest == I2C_XFER_RELOAD_IT) + { + /* Enable TC interrupts */ + tmpisr |= I2C_IT_TCI; + } + + /* Disable interrupts only at the end */ + /* to avoid a breaking situation like at "t" time */ + /* all disable interrupts request are not done */ + __HAL_I2C_DISABLE_IT(hi2c, tmpisr); +} + +/** + * @brief Convert I2Cx OTHER_xxx XferOptions to functional XferOptions. + * @param hi2c I2C handle. + * @retval None + */ +static void I2C_ConvertOtherXferOptions(I2C_HandleTypeDef *hi2c) +{ + /* if user set XferOptions to I2C_OTHER_FRAME */ + /* it request implicitly to generate a restart condition */ + /* set XferOptions to I2C_FIRST_FRAME */ + if (hi2c->XferOptions == I2C_OTHER_FRAME) + { + hi2c->XferOptions = I2C_FIRST_FRAME; + } + /* else if user set XferOptions to I2C_OTHER_AND_LAST_FRAME */ + /* it request implicitly to generate a restart condition */ + /* then generate a stop condition at the end of transfer */ + /* set XferOptions to I2C_FIRST_AND_LAST_FRAME */ + else if (hi2c->XferOptions == I2C_OTHER_AND_LAST_FRAME) + { + hi2c->XferOptions = I2C_FIRST_AND_LAST_FRAME; + } + else + { + /* Nothing to do */ + } +} + +/** + * @} + */ + +#endif /* HAL_I2C_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_i2c_ex.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_i2c_ex.c new file mode 100644 index 0000000000..7538ab3ac0 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_i2c_ex.c @@ -0,0 +1,359 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_i2c_ex.c + * @author MCD Application Team + * @brief I2C Extended HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of I2C Extended peripheral: + * + Filter Mode Functions + * + WakeUp Mode Functions + * + FastModePlus Functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### I2C peripheral Extended features ##### + ============================================================================== + + [..] Comparing to other previous devices, the I2C interface for STM32H5xx + devices contains the following additional features + + (+) Possibility to disable or enable Analog Noise Filter + (+) Use of a configured Digital Noise Filter + (+) Disable or enable wakeup from Stop mode(s) + (+) Disable or enable Fast Mode Plus + + ##### How to use this driver ##### + ============================================================================== + [..] This driver provides functions to configure Noise Filter and Wake Up Feature + (#) Configure I2C Analog noise filter using the function HAL_I2CEx_ConfigAnalogFilter() + (#) Configure I2C Digital noise filter using the function HAL_I2CEx_ConfigDigitalFilter() + (#) Configure the enable or disable of I2C Wake Up Mode using the functions : + (++) HAL_I2CEx_EnableWakeUp() + (++) HAL_I2CEx_DisableWakeUp() + (#) Configure the enable or disable of fast mode plus driving capability using the functions : + (++) HAL_I2CEx_ConfigFastModePlus() + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup I2CEx I2CEx + * @brief I2C Extended HAL module driver + * @{ + */ + +#ifdef HAL_I2C_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup I2CEx_Exported_Functions I2C Extended Exported Functions + * @{ + */ + +/** @defgroup I2CEx_Exported_Functions_Group1 Filter Mode Functions + * @brief Filter Mode Functions + * +@verbatim + =============================================================================== + ##### Filter Mode Functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure Noise Filters + +@endverbatim + * @{ + */ + +/** + * @brief Configure I2C Analog noise filter. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2Cx peripheral. + * @param AnalogFilter New state of the Analog filter. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); + assert_param(IS_I2C_ANALOG_FILTER(AnalogFilter)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY; + + /* Disable the selected I2C peripheral */ + __HAL_I2C_DISABLE(hi2c); + + /* Reset I2Cx ANOFF bit */ + hi2c->Instance->CR1 &= ~(I2C_CR1_ANFOFF); + + /* Set analog filter bit*/ + hi2c->Instance->CR1 |= AnalogFilter; + + __HAL_I2C_ENABLE(hi2c); + + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Configure I2C Digital noise filter. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2Cx peripheral. + * @param DigitalFilter Coefficient of digital noise filter between Min_Data=0x00 and Max_Data=0x0F. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_t DigitalFilter) +{ + uint32_t tmpreg; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); + assert_param(IS_I2C_DIGITAL_FILTER(DigitalFilter)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY; + + /* Disable the selected I2C peripheral */ + __HAL_I2C_DISABLE(hi2c); + + /* Get the old register value */ + tmpreg = hi2c->Instance->CR1; + + /* Reset I2Cx DNF bits [11:8] */ + tmpreg &= ~(I2C_CR1_DNF); + + /* Set I2Cx DNF coefficient */ + tmpreg |= DigitalFilter << 8U; + + /* Store the new register value */ + hi2c->Instance->CR1 = tmpreg; + + __HAL_I2C_ENABLE(hi2c); + + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} +/** + * @} + */ + +/** @defgroup I2CEx_Exported_Functions_Group2 WakeUp Mode Functions + * @brief WakeUp Mode Functions + * +@verbatim + =============================================================================== + ##### WakeUp Mode Functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure Wake Up Feature + +@endverbatim + * @{ + */ + +/** + * @brief Enable I2C wakeup from Stop mode(s). + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2Cx peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2CEx_EnableWakeUp(I2C_HandleTypeDef *hi2c) +{ + /* Check the parameters */ + assert_param(IS_I2C_WAKEUP_FROMSTOP_INSTANCE(hi2c->Instance)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY; + + /* Disable the selected I2C peripheral */ + __HAL_I2C_DISABLE(hi2c); + + /* Enable wakeup from stop mode */ + hi2c->Instance->CR1 |= I2C_CR1_WUPEN; + + __HAL_I2C_ENABLE(hi2c); + + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Disable I2C wakeup from Stop mode(s). + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2Cx peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2CEx_DisableWakeUp(I2C_HandleTypeDef *hi2c) +{ + /* Check the parameters */ + assert_param(IS_I2C_WAKEUP_FROMSTOP_INSTANCE(hi2c->Instance)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY; + + /* Disable the selected I2C peripheral */ + __HAL_I2C_DISABLE(hi2c); + + /* Enable wakeup from stop mode */ + hi2c->Instance->CR1 &= ~(I2C_CR1_WUPEN); + + __HAL_I2C_ENABLE(hi2c); + + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} +/** + * @} + */ + +/** @defgroup I2CEx_Exported_Functions_Group3 Fast Mode Plus Functions + * @brief Fast Mode Plus Functions + * +@verbatim + =============================================================================== + ##### Fast Mode Plus Functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure Fast Mode Plus + +@endverbatim + * @{ + */ + +/** + * @brief Configure I2C Fast Mode Plus. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2Cx peripheral. + * @param FastModePlus New state of the Fast Mode Plus. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2CEx_ConfigFastModePlus(I2C_HandleTypeDef *hi2c, uint32_t FastModePlus) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); + assert_param(IS_I2C_FASTMODEPLUS(FastModePlus)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY; + + /* Disable the selected I2C peripheral */ + __HAL_I2C_DISABLE(hi2c); + + if (FastModePlus == I2C_FASTMODEPLUS_ENABLE) + { + /* Set I2Cx FMP bit */ + hi2c->Instance->CR1 |= (I2C_CR1_FMP); + } + else + { + /* Reset I2Cx FMP bit */ + hi2c->Instance->CR1 &= ~(I2C_CR1_FMP); + } + + __HAL_I2C_ENABLE(hi2c); + + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @} + */ +/** + * @} + */ + +#endif /* HAL_I2C_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_i2s.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_i2s.c new file mode 100644 index 0000000000..52cbea823d --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_i2s.c @@ -0,0 +1,2710 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_i2s.c + * @author MCD Application Team + * @brief I2S HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Integrated Interchip Sound (I2S) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral State and Errors functions + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + =============================================================================== + ##### How to use this driver ##### + =============================================================================== + [..] + The I2S HAL driver can be used as follow: + + (#) Declare a I2S_HandleTypeDef handle structure. + (#) Initialize the I2S low level resources by implement the HAL_I2S_MspInit() API: + (##) Enable the SPIx interface clock. + (##) I2S pins configuration: + (+++) Enable the clock for the I2S GPIOs. + (+++) Configure these I2S pins as alternate function pull-up. + (##) NVIC configuration if you need to use interrupt process (HAL_I2S_Transmit_IT() + and HAL_I2S_Receive_IT() APIs). + (+++) Configure the I2Sx interrupt priority. + (+++) Enable the NVIC I2S IRQ handle. + (##) DMA Configuration if you need to use DMA process (HAL_I2S_Transmit_DMA() + and HAL_I2S_Receive_DMA() APIs: + (+++) Declare a DMA handle structure for the Tx/Rx Stream/Channel. + (+++) Enable the DMAx interface clock. + (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. + (+++) Configure the DMA Tx/Rx Stream/Channel. + (+++) Associate the initialized DMA handle to the I2S DMA Tx/Rx handle. + (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the + DMA Tx/Rx Stream/Channel. + + (#) Program the Mode, Standard, Data Format, MCLK Output, Audio frequency and Polarity + using HAL_I2S_Init() function. + + -@- The specific I2S interrupts (Transmission complete interrupt, + RXNE interrupt and Error Interrupts) will be managed using the macros + __HAL_I2S_ENABLE_IT() and __HAL_I2S_DISABLE_IT() inside the transmit and receive process. + + (+@) External clock source is configured after setting correctly + the define constant EXTERNAL_CLOCK_VALUE in the stm32h5xx_hal_conf.h file. + + (#) Three mode of operations are available within this driver : + + *** Polling mode IO operation *** + ================================= + [..] + (+) Send an amount of data in blocking mode using HAL_I2S_Transmit() + (+) Receive an amount of data in blocking mode using HAL_I2S_Receive() + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Send an amount of data in non blocking mode using HAL_I2S_Transmit_IT() + (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback + (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2S_TxCpltCallback + (+) Receive an amount of data in non blocking mode using HAL_I2S_Receive_IT() + (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback + (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2S_RxCpltCallback + (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_I2S_ErrorCallback + + *** DMA mode IO operation *** + ============================== + [..] + (+) Send an amount of data in non blocking mode (DMA) using HAL_I2S_Transmit_DMA() + (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback + (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2S_TxCpltCallback + (+) Receive an amount of data in non blocking mode (DMA) using HAL_I2S_Receive_DMA() + (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback + (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2S_RxCpltCallback + (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_I2S_ErrorCallback + (+) Pause the DMA Transfer using HAL_I2S_DMAPause() + (+) Resume the DMA Transfer using HAL_I2S_DMAResume() + (+) Stop the DMA Transfer using HAL_I2S_DMAStop() + + *** I2S HAL driver macros list *** + =================================== + [..] + Below the list of most used macros in I2S HAL driver. + + (+) __HAL_I2S_ENABLE: Enable the specified SPI peripheral (in I2S mode) + (+) __HAL_I2S_DISABLE: Disable the specified SPI peripheral (in I2S mode) + (+) __HAL_I2S_ENABLE_IT : Enable the specified I2S interrupts + (+) __HAL_I2S_DISABLE_IT : Disable the specified I2S interrupts + (+) __HAL_I2S_GET_FLAG: Check whether the specified I2S flag is set or not + + [..] + (@) You can refer to the I2S HAL driver header file for more useful macros + + *** I2S HAL driver macros list *** + =================================== + [..] + Callback registration: + + (#) The compilation flag USE_HAL_I2S_REGISTER_CALLBACKS when set to 1UL + allows the user to configure dynamically the driver callbacks. + Use Functions HAL_I2S_RegisterCallback() to register an interrupt callback. + + Function HAL_I2S_RegisterCallback() allows to register following callbacks: + (+) TxCpltCallback : I2S Tx Completed callback + (+) RxCpltCallback : I2S Rx Completed callback + (+) TxRxCpltCallback : I2S TxRx Completed callback + (+) TxHalfCpltCallback : I2S Tx Half Completed callback + (+) RxHalfCpltCallback : I2S Rx Half Completed callback + (+) TxRxHalfCpltCallback : I2S TxRx Half Completed callback + (+) ErrorCallback : I2S Error callback + (+) MspInitCallback : I2S Msp Init callback + (+) MspDeInitCallback : I2S 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_I2S_UnRegisterCallback to reset a callback to the default + weak function. + HAL_I2S_UnRegisterCallback takes as parameters the HAL peripheral handle, + and the Callback ID. + This function allows to reset following callbacks: + (+) TxCpltCallback : I2S Tx Completed callback + (+) RxCpltCallback : I2S Rx Completed callback + (+) TxRxCpltCallback : I2S TxRx Completed callback + (+) TxHalfCpltCallback : I2S Tx Half Completed callback + (+) RxHalfCpltCallback : I2S Rx Half Completed callback + (+) TxRxHalfCpltCallback : I2S TxRx Half Completed callback + (+) ErrorCallback : I2S Error callback + (+) MspInitCallback : I2S Msp Init callback + (+) MspDeInitCallback : I2S Msp DeInit callback + + By default, after the HAL_I2S_Init() and when the state is HAL_I2S_STATE_RESET + all callbacks are set to the corresponding weak functions: + examples HAL_I2S_MasterTxCpltCallback(), HAL_I2S_MasterRxCpltCallback(). + Exception done for MspInit and MspDeInit functions that are + reset to the legacy weak functions in the HAL_I2S_Init()/ HAL_I2S_DeInit() only when + these callbacks are null (not registered beforehand). + If MspInit or MspDeInit are not null, the HAL_I2S_Init()/ HAL_I2S_DeInit() + keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state. + + Callbacks can be registered/unregistered in HAL_I2S_STATE_READY state only. + Exception done MspInit/MspDeInit functions that can be registered/unregistered + in HAL_I2S_STATE_READY or HAL_I2S_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_I2S_RegisterCallback() before calling HAL_I2S_DeInit() + or HAL_I2S_Init() function. + + When The compilation define USE_HAL_I2S_REGISTER_CALLBACKS is set to 0 or + not defined, the callback registering feature is not available + and weak (surcharged) callbacks are used. + + + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +#ifdef HAL_I2S_MODULE_ENABLED + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup I2S I2S + * @brief I2S HAL module driver + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup I2S_Private_Define I2S Private Define + * @{ + */ +#define I2S_TIMEOUT 0xFFFFUL +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup I2S_Private_Functions I2S Private Functions + * @{ + */ +static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma); +static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma); +static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma); +static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma); +static void I2SEx_DMATxRxCplt(DMA_HandleTypeDef *hdma); +static void I2SEx_DMATxRxHalfCplt(DMA_HandleTypeDef *hdma); +static void I2S_DMAError(DMA_HandleTypeDef *hdma); +static void I2S_Transmit_16Bit_IT(I2S_HandleTypeDef *hi2s); +static void I2S_Transmit_32Bit_IT(I2S_HandleTypeDef *hi2s); +static void I2S_Receive_16Bit_IT(I2S_HandleTypeDef *hi2s); +static void I2S_Receive_32Bit_IT(I2S_HandleTypeDef *hi2s); +static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, FlagStatus State, + uint32_t Tickstart, uint32_t Timeout); +/** + * @} + */ + +/* Exported functions ---------------------------------------------------------*/ + +/** @defgroup I2S_Exported_Functions I2S Exported Functions + * @{ + */ + +/** @defgroup I2S_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + de-initialize the I2Sx peripheral in simplex mode: + + (+) User must Implement HAL_I2S_MspInit() function in which he configures + all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ). + + (+) Call the function HAL_I2S_Init() to configure the selected device with + the selected configuration: + (++) Mode + (++) Standard + (++) Data Format + (++) MCLK Output + (++) Audio frequency + (++) Polarity + + (+) Call the function HAL_I2S_DeInit() to restore the default configuration + of the selected I2Sx peripheral. + @endverbatim + * @{ + */ + +/** + * @brief Initializes the I2S according to the specified parameters + * in the I2S_InitTypeDef and create the associated handle. + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2S_Init(I2S_HandleTypeDef *hi2s) +{ + uint32_t i2sdiv; + uint32_t i2sodd; + uint32_t packetlength; + uint32_t tmp; + uint32_t i2sclk; + uint32_t ispcm; + + /* Check the I2S handle allocation */ + if (hi2s == NULL) + { + return HAL_ERROR; + } + + /* Check the I2S parameters */ + assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance)); + assert_param(IS_I2S_MODE(hi2s->Init.Mode)); + assert_param(IS_I2S_STANDARD(hi2s->Init.Standard)); + assert_param(IS_I2S_DATA_FORMAT(hi2s->Init.DataFormat)); + assert_param(IS_I2S_MCLK_OUTPUT(hi2s->Init.MCLKOutput)); + assert_param(IS_I2S_AUDIO_FREQ(hi2s->Init.AudioFreq)); + assert_param(IS_I2S_CPOL(hi2s->Init.CPOL)); + assert_param(IS_I2S_FIRST_BIT(hi2s->Init.FirstBit)); + assert_param(IS_I2S_WS_INVERSION(hi2s->Init.WSInversion)); + assert_param(IS_I2S_DATA_24BIT_ALIGNMENT(hi2s->Init.Data24BitAlignment)); + assert_param(IS_I2S_MASTER_KEEP_IO_STATE(hi2s->Init.MasterKeepIOState)); + + if (hi2s->State == HAL_I2S_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hi2s->Lock = HAL_UNLOCKED; + +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL) + /* Init the I2S Callback settings */ + hi2s->TxCpltCallback = HAL_I2S_TxCpltCallback; /* Legacy weak TxCpltCallback */ + hi2s->RxCpltCallback = HAL_I2S_RxCpltCallback; /* Legacy weak RxCpltCallback */ + hi2s->TxRxCpltCallback = HAL_I2SEx_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */ + hi2s->TxHalfCpltCallback = HAL_I2S_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */ + hi2s->RxHalfCpltCallback = HAL_I2S_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */ + hi2s->TxRxHalfCpltCallback = HAL_I2SEx_TxRxHalfCpltCallback; /* Legacy weak TxRxHalfCpltCallback */ + hi2s->ErrorCallback = HAL_I2S_ErrorCallback; /* Legacy weak ErrorCallback */ + + if (hi2s->MspInitCallback == NULL) + { + hi2s->MspInitCallback = HAL_I2S_MspInit; /* Legacy weak MspInit */ + } + + /* Init the low level hardware : GPIO, CLOCK, NVIC... */ + hi2s->MspInitCallback(hi2s); +#else + /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ + HAL_I2S_MspInit(hi2s); +#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ + } + + hi2s->State = HAL_I2S_STATE_BUSY; + + /* Disable the selected I2S peripheral */ + if ((hi2s->Instance->CR1 & SPI_CR1_SPE) == SPI_CR1_SPE) + { + /* Disable I2S peripheral */ + __HAL_I2S_DISABLE(hi2s); + } + + /* Clear I2S configuration register */ + CLEAR_REG(hi2s->Instance->I2SCFGR); + + if (IS_I2S_MASTER(hi2s->Init.Mode)) + { + /*------------------------- I2SDIV and ODD Calculation ---------------------*/ + /* If the requested audio frequency is not the default, compute the prescaler */ + if (hi2s->Init.AudioFreq != I2S_AUDIOFREQ_DEFAULT) + { + /* Check the frame length (For the Prescaler computing) ********************/ + if (hi2s->Init.DataFormat != I2S_DATAFORMAT_16B) + { + /* Channel length is 32 bits */ + packetlength = 2UL; + } + else + { + /* Channel length is 16 bits */ + packetlength = 1UL; + } + + /* Check if PCM standard is used */ + if ((hi2s->Init.Standard == I2S_STANDARD_PCM_SHORT) || + (hi2s->Init.Standard == I2S_STANDARD_PCM_LONG)) + { + ispcm = 1UL; + } + else + { + ispcm = 0UL; + } + + /* Get the source clock value: based on System Clock value */ + if (hi2s->Instance == SPI1) + { + i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI1); + } + else if (hi2s->Instance == SPI2) + { + i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI2); + } + else /* SPI3 source clock */ + { + i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI3); + } + + /* Compute the Real divider depending on the MCLK output state, with a floating point */ + if (hi2s->Init.MCLKOutput == I2S_MCLKOUTPUT_ENABLE) + { + /* MCLK output is enabled */ + tmp = (uint32_t)((((i2sclk / (256UL >> ispcm)) * 10UL) / hi2s->Init.AudioFreq) + 5UL); + } + else + { + /* MCLK output is disabled */ + tmp = (uint32_t)((((i2sclk / ((32UL >> ispcm) * packetlength)) * 10UL) / hi2s->Init.AudioFreq) + 5UL); + } + + /* Remove the flatting point */ + tmp = tmp / 10UL; + + /* Check the parity of the divider */ + i2sodd = (uint32_t)(tmp & (uint32_t)1UL); + + /* Compute the i2sdiv prescaler */ + i2sdiv = (uint32_t)((tmp - i2sodd) / 2UL); + } + else + { + /* Set the default values */ + i2sdiv = 2UL; + i2sodd = 0UL; + } + + /* Test if the obtain values are forbidden or out of range */ + if (((i2sodd == 1UL) && (i2sdiv == 1UL)) || (i2sdiv > 0xFFUL)) + { + /* Set the error code */ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_PRESCALER); + return HAL_ERROR; + } + + /* Force i2smod to 1 just to be sure that (2xi2sdiv + i2sodd) is always higher than 0 */ + if (i2sdiv == 0UL) + { + i2sodd = 1UL; + } + + MODIFY_REG(hi2s->Instance->I2SCFGR, (SPI_I2SCFGR_I2SDIV | SPI_I2SCFGR_ODD), + ((i2sdiv << SPI_I2SCFGR_I2SDIV_Pos) | (i2sodd << SPI_I2SCFGR_ODD_Pos))); + } + + /*-------------------------- I2Sx I2SCFGR Configuration --------------------*/ + /* Configure I2SMOD, I2SCFG, I2SSTD, PCMSYNC, DATLEN ,CHLEN ,CKPOL, WSINV, DATAFMT, I2SDIV, ODD and MCKOE bits bits */ + /* And configure the I2S with the I2S_InitStruct values */ + MODIFY_REG(hi2s->Instance->I2SCFGR, (SPI_I2SCFGR_I2SMOD | SPI_I2SCFGR_I2SCFG | \ + SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC | \ + SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN | \ + SPI_I2SCFGR_CKPOL | SPI_I2SCFGR_WSINV | \ + SPI_I2SCFGR_DATFMT | SPI_I2SCFGR_MCKOE), + (SPI_I2SCFGR_I2SMOD | hi2s->Init.Mode | \ + hi2s->Init.Standard | hi2s->Init.DataFormat | \ + hi2s->Init.CPOL | hi2s->Init.WSInversion | \ + hi2s->Init.Data24BitAlignment | hi2s->Init.MCLKOutput)); + /*Clear status register*/ + WRITE_REG(hi2s->Instance->IFCR, 0x0FF8); + + /*---------------------------- I2Sx CFG2 Configuration ----------------------*/ + + /* Unlock the AF configuration to configure CFG2 register*/ + CLEAR_BIT(hi2s->Instance->CR1, SPI_CR1_IOLOCK); + + MODIFY_REG(hi2s->Instance->CFG2, SPI_CFG2_LSBFRST, hi2s->Init.FirstBit); + + /* Insure that AFCNTR is managed only by Master */ + if (IS_I2S_MASTER(hi2s->Init.Mode)) + { + /* Alternate function GPIOs control */ + MODIFY_REG(hi2s->Instance->CFG2, SPI_CFG2_AFCNTR, (hi2s->Init.MasterKeepIOState)); + } + + hi2s->ErrorCode = HAL_I2S_ERROR_NONE; + hi2s->State = HAL_I2S_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the I2S peripheral + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2S_DeInit(I2S_HandleTypeDef *hi2s) +{ + /* Check the I2S handle allocation */ + if (hi2s == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance)); + + hi2s->State = HAL_I2S_STATE_BUSY; + + /* Disable the I2S Peripheral Clock */ + __HAL_I2S_DISABLE(hi2s); + +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL) + if (hi2s->MspDeInitCallback == NULL) + { + hi2s->MspDeInitCallback = HAL_I2S_MspDeInit; /* Legacy weak MspDeInit */ + } + + /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */ + hi2s->MspDeInitCallback(hi2s); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */ + HAL_I2S_MspDeInit(hi2s); +#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ + + hi2s->ErrorCode = HAL_I2S_ERROR_NONE; + hi2s->State = HAL_I2S_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hi2s); + + return HAL_OK; +} + +/** + * @brief I2S MSP Init + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval None + */ +__weak void HAL_I2S_MspInit(I2S_HandleTypeDef *hi2s) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2s); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2S_MspInit could be implemented in the user file + */ +} + +/** + * @brief I2S MSP DeInit + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval None + */ +__weak void HAL_I2S_MspDeInit(I2S_HandleTypeDef *hi2s) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2s); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2S_MspDeInit could be implemented in the user file + */ +} + +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL) +/** + * @brief Register a User I2S Callback + * To be used instead of the weak predefined callback + * @param hi2s Pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for the specified I2S. + * @param CallbackID ID of the callback to be registered + * @param pCallback pointer to the Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2S_RegisterCallback(I2S_HandleTypeDef *hi2s, HAL_I2S_CallbackIDTypeDef CallbackID, + pI2S_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hi2s->ErrorCode |= HAL_I2S_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + /* Process locked */ + __HAL_LOCK(hi2s); + + if (HAL_I2S_STATE_READY == hi2s->State) + { + switch (CallbackID) + { + case HAL_I2S_TX_COMPLETE_CB_ID : + hi2s->TxCpltCallback = pCallback; + break; + + case HAL_I2S_RX_COMPLETE_CB_ID : + hi2s->RxCpltCallback = pCallback; + break; + + case HAL_I2S_TX_RX_COMPLETE_CB_ID : + hi2s->TxRxCpltCallback = pCallback; + break; + + case HAL_I2S_TX_HALF_COMPLETE_CB_ID : + hi2s->TxHalfCpltCallback = pCallback; + break; + + case HAL_I2S_RX_HALF_COMPLETE_CB_ID : + hi2s->RxHalfCpltCallback = pCallback; + break; + + + case HAL_I2S_TX_RX_HALF_COMPLETE_CB_ID : + hi2s->TxRxHalfCpltCallback = pCallback; + break; + + case HAL_I2S_ERROR_CB_ID : + hi2s->ErrorCallback = pCallback; + break; + + case HAL_I2S_MSPINIT_CB_ID : + hi2s->MspInitCallback = pCallback; + break; + + case HAL_I2S_MSPDEINIT_CB_ID : + hi2s->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK); + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_I2S_STATE_RESET == hi2s->State) + { + switch (CallbackID) + { + case HAL_I2S_MSPINIT_CB_ID : + hi2s->MspInitCallback = pCallback; + break; + + case HAL_I2S_MSPDEINIT_CB_ID : + hi2s->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK); + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK); + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hi2s); + return status; +} + +/** + * @brief Unregister an I2S Callback + * I2S callback is redirected to the weak predefined callback + * @param hi2s Pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for the specified I2S. + * @param CallbackID ID of the callback to be unregistered + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2S_UnRegisterCallback(I2S_HandleTypeDef *hi2s, HAL_I2S_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hi2s); + + if (HAL_I2S_STATE_READY == hi2s->State) + { + switch (CallbackID) + { + case HAL_I2S_TX_COMPLETE_CB_ID : + hi2s->TxCpltCallback = HAL_I2S_TxCpltCallback; /* Legacy weak TxCpltCallback */ + break; + + case HAL_I2S_RX_COMPLETE_CB_ID : + hi2s->RxCpltCallback = HAL_I2S_RxCpltCallback; /* Legacy weak RxCpltCallback */ + break; + + case HAL_I2S_TX_RX_COMPLETE_CB_ID : + hi2s->TxRxCpltCallback = HAL_I2SEx_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */ + break; + + case HAL_I2S_TX_HALF_COMPLETE_CB_ID : + hi2s->TxHalfCpltCallback = HAL_I2S_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */ + break; + + case HAL_I2S_RX_HALF_COMPLETE_CB_ID : + hi2s->RxHalfCpltCallback = HAL_I2S_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */ + break; + + case HAL_I2S_TX_RX_HALF_COMPLETE_CB_ID : + hi2s->TxRxHalfCpltCallback = HAL_I2SEx_TxRxHalfCpltCallback; /* Legacy weak TxRxHalfCpltCallback */ + break; + + case HAL_I2S_ERROR_CB_ID : + hi2s->ErrorCallback = HAL_I2S_ErrorCallback; /* Legacy weak ErrorCallback */ + break; + + case HAL_I2S_MSPINIT_CB_ID : + hi2s->MspInitCallback = HAL_I2S_MspInit; /* Legacy weak MspInit */ + break; + + case HAL_I2S_MSPDEINIT_CB_ID : + hi2s->MspDeInitCallback = HAL_I2S_MspDeInit; /* Legacy weak MspDeInit */ + break; + + default : + /* Update the error code */ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK); + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_I2S_STATE_RESET == hi2s->State) + { + switch (CallbackID) + { + case HAL_I2S_MSPINIT_CB_ID : + hi2s->MspInitCallback = HAL_I2S_MspInit; /* Legacy weak MspInit */ + break; + + case HAL_I2S_MSPDEINIT_CB_ID : + hi2s->MspDeInitCallback = HAL_I2S_MspDeInit; /* Legacy weak MspDeInit */ + break; + + default : + /* Update the error code */ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK); + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK); + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hi2s); + return status; +} +#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @defgroup I2S_Exported_Functions_Group2 IO operation functions + * @brief Data transfers functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the I2S data + transfers. + + (#) There are two modes of transfer: + (++) Blocking mode : The communication is performed in the polling mode. + The status of all data processing is returned by the same function + after finishing transfer. + (++) No-Blocking mode : The communication is performed using Interrupts + or DMA. These functions return the status of the transfer startup. + The end of the data processing will be indicated through the + dedicated I2S IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + + (#) Blocking mode functions are : + (++) HAL_I2S_Transmit() + (++) HAL_I2S_Receive() + (++) HAL_I2SEx_TransmitReceive() + + (#) No-Blocking mode functions with Interrupt are : + (++) HAL_I2S_Transmit_IT() + (++) HAL_I2S_Receive_IT() + (++) HAL_I2SEx_TransmitReceive_IT() + + (#) No-Blocking mode functions with DMA are : + (++) HAL_I2S_Transmit_DMA() + (++) HAL_I2S_Receive_DMA() + (++) HAL_I2SEx_TransmitReceive_DMA() + + (#) A set of Transfer Complete Callbacks are provided in non Blocking mode: + (++) HAL_I2S_TxCpltCallback() + (++) HAL_I2S_RxCpltCallback() + (++) HAL_I2SEx_TxRxCpltCallback() + (++) HAL_I2S_ErrorCallback() + +@endverbatim + * @{ + */ + +/** + * @brief Transmit an amount of data in blocking mode + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @param pData a 16-bit pointer to data buffer. + * @param Size number of data sample to be sent: + * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S + * configuration phase, the Size parameter means the number of 16-bit data length + * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected + * the Size parameter means the number of 16-bit data length. + * @param Timeout Timeout duration + * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization + * between Master and Slave(example: audio streaming). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2S_Transmit(I2S_HandleTypeDef *hi2s, const uint16_t *pData, uint16_t Size, uint32_t Timeout) +{ +#if defined (__GNUC__) + __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->TXDR)); +#endif /* __GNUC__ */ + uint32_t tickstart; + + if ((pData == NULL) || (Size == 0UL)) + { + return HAL_ERROR; + } + + if (hi2s->State != HAL_I2S_STATE_READY) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2s); + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + /* Set state and reset error code */ + hi2s->State = HAL_I2S_STATE_BUSY_TX; + hi2s->ErrorCode = HAL_I2S_ERROR_NONE; + hi2s->pTxBuffPtr = (const uint16_t *)pData; + hi2s->TxXferSize = Size; + hi2s->TxXferCount = Size; + + /* Initialize fields not used in handle to zero */ + hi2s->pRxBuffPtr = NULL; + hi2s->RxXferSize = (uint16_t) 0UL; + hi2s->RxXferCount = (uint16_t) 0UL; + + /* Check if the I2S is already enabled */ + if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) + { + /* Enable I2S peripheral */ + __HAL_I2S_ENABLE(hi2s); + } + + /* Start the transfer */ + SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART); + + + /* Wait until TXP flag is set */ + if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXP, SET, tickstart, Timeout) != HAL_OK) + { + /* Set the error code */ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT); + hi2s->State = HAL_I2S_STATE_READY; + __HAL_UNLOCK(hi2s); + return HAL_TIMEOUT; + } + + while (hi2s->TxXferCount > 0UL) + { + if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B)) + { + /* Transmit data in 32 Bit mode */ + hi2s->Instance->TXDR = *((const uint32_t *)hi2s->pTxBuffPtr); + hi2s->pTxBuffPtr += 2; + hi2s->TxXferCount--; + } + else + { + /* Transmit data in 16 Bit mode */ +#if defined (__GNUC__) + *ptxdr_16bits = *((const uint16_t *)hi2s->pTxBuffPtr); +#else + *((__IO uint16_t *)&hi2s->Instance->TXDR) = *((const uint16_t *)hi2s->pTxBuffPtr); +#endif /* __GNUC__ */ + + hi2s->pTxBuffPtr++; + hi2s->TxXferCount--; + } + + /* Wait until TXP flag is set */ + if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXP, SET, tickstart, Timeout) != HAL_OK) + { + /* Set the error code */ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT); + hi2s->State = HAL_I2S_STATE_READY; + __HAL_UNLOCK(hi2s); + return HAL_TIMEOUT; + } + + /* Check if an underrun occurs */ + if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET) + { + /* Clear underrun flag */ + __HAL_I2S_CLEAR_UDRFLAG(hi2s); + + /* Set the error code */ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR); + } + } + + hi2s->State = HAL_I2S_STATE_READY; + __HAL_UNLOCK(hi2s); + return HAL_OK; +} + +/** + * @brief Receive an amount of data in blocking mode + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @param pData a 16-bit pointer to data buffer. + * @param Size number of data sample to be sent: + * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S + * configuration phase, the Size parameter means the number of 16-bit data length + * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected + * the Size parameter means the number of 16-bit data length. + * @param Timeout Timeout duration + * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization + * between Master and Slave(example: audio streaming). + * @note In I2S Master Receiver mode, just after enabling the peripheral the clock will be generate + * in continuous way and as the I2S is not disabled at the end of the I2S transaction. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2S_Receive(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout) +{ +#if defined (__GNUC__) + __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->RXDR)); +#endif /* __GNUC__ */ + uint32_t tickstart; + + if ((pData == NULL) || (Size == 0UL)) + { + return HAL_ERROR; + } + + if (hi2s->State != HAL_I2S_STATE_READY) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2s); + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + /* Set state and reset error code */ + hi2s->State = HAL_I2S_STATE_BUSY_RX; + hi2s->ErrorCode = HAL_I2S_ERROR_NONE; + hi2s->pRxBuffPtr = pData; + hi2s->RxXferSize = Size; + hi2s->RxXferCount = Size; + + /* Initialize fields not used in handle to zero */ + hi2s->pTxBuffPtr = NULL; + hi2s->TxXferSize = (uint16_t) 0UL; + hi2s->TxXferCount = (uint16_t) 0UL; + + /* Check if the I2S is already enabled */ + if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) + { + /* Enable I2S peripheral */ + __HAL_I2S_ENABLE(hi2s); + } + + /* Start the transfer */ + SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART); + + /* Receive data */ + while (hi2s->RxXferCount > 0UL) + { + /* Wait until RXP flag is set */ + if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXP, SET, tickstart, Timeout) != HAL_OK) + { + /* Set the error code */ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT); + hi2s->State = HAL_I2S_STATE_READY; + __HAL_UNLOCK(hi2s); + return HAL_TIMEOUT; + } + + if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B)) + { + /* Receive data in 32 Bit mode */ + *((uint32_t *)hi2s->pRxBuffPtr) = hi2s->Instance->RXDR; + hi2s->pRxBuffPtr += 2; + hi2s->RxXferCount--; + } + else + { + /* Receive data in 16 Bit mode */ +#if defined (__GNUC__) + *((uint16_t *)hi2s->pRxBuffPtr) = *prxdr_16bits; +#else + *((uint16_t *)hi2s->pRxBuffPtr) = *((__IO uint16_t *)&hi2s->Instance->RXDR); +#endif /* __GNUC__ */ + hi2s->pRxBuffPtr++; + hi2s->RxXferCount--; + } + + /* Check if an overrun occurs */ + if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET) + { + /* Clear overrun flag */ + __HAL_I2S_CLEAR_OVRFLAG(hi2s); + + /* Set the error code */ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR); + } + } + + hi2s->State = HAL_I2S_STATE_READY; + __HAL_UNLOCK(hi2s); + return HAL_OK; +} + +/** + * @brief Full-Duplex Transmit/Receive data in blocking mode. + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @param pTxData a 16-bit pointer to the Transmit data buffer. + * @param pRxData a 16-bit pointer to the Receive data buffer. + * @param Size number of data sample to be sent: + * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S + * configuration phase, the Size parameter means the number of 16-bit data length + * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected + * the Size parameter means the number of 16-bit data length. + * @param Timeout Timeout duration + * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization + * between Master and Slave(example: audio streaming). + * @retval HAL status + */ + +HAL_StatusTypeDef HAL_I2SEx_TransmitReceive(I2S_HandleTypeDef *hi2s, const uint16_t *pTxData, uint16_t *pRxData, + uint16_t Size, uint32_t Timeout) +{ + uint32_t tmp_TxXferCount; + uint32_t tmp_RxXferCount; + uint32_t tickstart; + +#if defined (__GNUC__) + __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->TXDR)); + __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->RXDR)); +#endif /* __GNUC__ */ + + if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + if (hi2s->State != HAL_I2S_STATE_READY) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2s); + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + hi2s->TxXferSize = Size; + hi2s->TxXferCount = Size; + hi2s->pTxBuffPtr = (const uint16_t *)pTxData; + hi2s->RxXferSize = Size; + hi2s->RxXferCount = Size; + hi2s->pRxBuffPtr = pRxData; + + tmp_TxXferCount = hi2s->TxXferCount; + tmp_RxXferCount = hi2s->RxXferCount; + + /* Set state and reset error code */ + hi2s->ErrorCode = HAL_I2S_ERROR_NONE; + hi2s->State = HAL_I2S_STATE_BUSY_TX_RX; + + /* Check if the I2S is already enabled */ + if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) + { + /* Enable I2S peripheral */ + __HAL_I2S_ENABLE(hi2s); + } + + /* Start the transfer */ + SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART); + + while ((tmp_TxXferCount > 0UL) || (tmp_RxXferCount > 0UL)) + { + if ((__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_TXP) == SET) && (tmp_TxXferCount != 0UL)) + { + if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B)) + { + /* Transmit data in 32 Bit mode */ + hi2s->Instance->TXDR = *((const uint32_t *)hi2s->pTxBuffPtr); + hi2s->pTxBuffPtr += 2; + tmp_TxXferCount--; + } + else + { + /* Transmit data in 16 Bit mode */ +#if defined (__GNUC__) + *ptxdr_16bits = *((const uint16_t *)hi2s->pTxBuffPtr); +#else + *((__IO uint16_t *)&hi2s->Instance->TXDR) = *((const uint16_t *)hi2s->pTxBuffPtr); +#endif /* __GNUC__ */ + + hi2s->pTxBuffPtr++; + tmp_TxXferCount--; + } + + /* Check if an underrun occurs */ + if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET) + { + /* Clear underrun flag */ + __HAL_I2S_CLEAR_UDRFLAG(hi2s); + + /* Set the error code */ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR); + } + } + + if ((__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_RXP) == SET) && (tmp_RxXferCount != 0UL)) + { + if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B)) + { + /* Receive data in 32 Bit mode */ + *((uint32_t *)hi2s->pRxBuffPtr) = hi2s->Instance->RXDR; + hi2s->pRxBuffPtr += 2; + tmp_RxXferCount--; + } + else + { + /* Receive data in 16 Bit mode */ +#if defined (__GNUC__) + *((uint16_t *)hi2s->pRxBuffPtr) = *prxdr_16bits; +#else + *((uint16_t *)hi2s->pRxBuffPtr) = *((__IO uint16_t *)&hi2s->Instance->RXDR); +#endif /* __GNUC__ */ + hi2s->pRxBuffPtr++; + tmp_RxXferCount--; + } + + /* Check if an overrun occurs */ + if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET) + { + /* Clear overrun flag */ + __HAL_I2S_CLEAR_OVRFLAG(hi2s); + + /* Set the error code */ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR); + } + } + + /* Timeout management */ + if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U)) + { + /* Set the error code */ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT); + hi2s->State = HAL_I2S_STATE_READY; + __HAL_UNLOCK(hi2s); + return HAL_TIMEOUT; + } + } + + hi2s->State = HAL_I2S_STATE_READY; + __HAL_UNLOCK(hi2s); + return HAL_OK; +} + +/** + * @brief Transmit an amount of data in non-blocking mode with Interrupt + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @param pData a 16-bit pointer to data buffer. + * @param Size number of data sample to be sent: + * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S + * configuration phase, the Size parameter means the number of 16-bit data length + * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected + * the Size parameter means the number of 16-bit data length. + * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization + * between Master and Slave(example: audio streaming). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, const uint16_t *pData, uint16_t Size) +{ + if ((pData == NULL) || (Size == 0UL)) + { + return HAL_ERROR; + } + + if (hi2s->State != HAL_I2S_STATE_READY) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2s); + + /* Set state and reset error code */ + hi2s->State = HAL_I2S_STATE_BUSY_TX; + hi2s->ErrorCode = HAL_I2S_ERROR_NONE; + hi2s->pTxBuffPtr = (const uint16_t *)pData; + hi2s->TxXferSize = Size; + hi2s->TxXferCount = Size; + + /* Initialize fields not used in handle to zero */ + hi2s->pRxBuffPtr = NULL; + hi2s->RxXferSize = (uint16_t) 0UL; + hi2s->RxXferCount = (uint16_t) 0UL; + + /* Set the function for IT treatment */ + if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B)) + { + hi2s->TxISR = I2S_Transmit_32Bit_IT; + } + else + { + hi2s->TxISR = I2S_Transmit_16Bit_IT; + } + + /* Check if the I2S is already enabled */ + if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) + { + /* Enable I2S peripheral */ + __HAL_I2S_ENABLE(hi2s); + } + + /* Enable TXP and UDR interrupt */ + __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_UDR)); + + /* Enable TIFRE interrupt if the mode is Slave */ + if (hi2s->Init.Mode == I2S_MODE_SLAVE_TX) + { + __HAL_I2S_ENABLE_IT(hi2s, I2S_IT_FRE); + } + + /* Start the transfer */ + SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART); + + __HAL_UNLOCK(hi2s); + return HAL_OK; +} + +/** + * @brief Receive an amount of data in non-blocking mode with Interrupt + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @param pData a 16-bit pointer to the Receive data buffer. + * @param Size number of data sample to be sent: + * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S + * configuration phase, the Size parameter means the number of 16-bit data length + * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected + * the Size parameter means the number of 16-bit data length. + * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization + * between Master and Slave(example: audio streaming). + * @note It is recommended to use DMA for the I2S receiver to avoid de-synchronization + * between Master and Slave otherwise the I2S interrupt should be optimized. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2S_Receive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size) +{ + if ((pData == NULL) || (Size == 0UL)) + { + return HAL_ERROR; + } + + if (hi2s->State != HAL_I2S_STATE_READY) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2s); + + /* Set state and reset error code */ + hi2s->State = HAL_I2S_STATE_BUSY_RX; + hi2s->ErrorCode = HAL_I2S_ERROR_NONE; + hi2s->pRxBuffPtr = pData; + hi2s->RxXferSize = Size; + hi2s->RxXferCount = Size; + + /* Initialize fields not used in handle to zero */ + hi2s->pTxBuffPtr = NULL; + hi2s->TxXferSize = (uint16_t) 0UL; + hi2s->TxXferCount = (uint16_t) 0UL; + + /* Set the function for IT treatment */ + if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B)) + { + hi2s->RxISR = I2S_Receive_32Bit_IT; + } + else + { + hi2s->RxISR = I2S_Receive_16Bit_IT; + } + + /* Check if the I2S is already enabled */ + if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) + { + /* Enable I2S peripheral */ + __HAL_I2S_ENABLE(hi2s); + } + /* Enable RXP and ERR interrupt */ + __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXP | I2S_IT_OVR)); + + /* Enable TIFRE interrupt if the mode is Slave */ + if (hi2s->Init.Mode == I2S_MODE_SLAVE_RX) + { + __HAL_I2S_ENABLE_IT(hi2s, I2S_IT_FRE); + } + + /* Start the transfer */ + SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART); + + __HAL_UNLOCK(hi2s); + return HAL_OK; +} + +/** + * @brief Full-Duplex Transmit/Receive data in non-blocking mode using Interrupt + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @param pTxData a 16-bit pointer to the Transmit data buffer. + * @param pRxData a 16-bit pointer to the Receive data buffer. + * @param Size number of data sample to be sent: + * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S + * configuration phase, the Size parameter means the number of 16-bit data length + * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected + * the Size parameter means the number of 16-bit data length. + * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization + * between Master and Slave(example: audio streaming). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s, const uint16_t *pTxData, uint16_t *pRxData, + uint16_t Size) +{ + if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + if (hi2s->State != HAL_I2S_STATE_READY) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2s); + + hi2s->pTxBuffPtr = (const uint16_t *)pTxData; + hi2s->pRxBuffPtr = pRxData; + + hi2s->TxXferSize = Size; + hi2s->TxXferCount = Size; + hi2s->RxXferSize = Size; + hi2s->RxXferCount = Size; + + hi2s->ErrorCode = HAL_I2S_ERROR_NONE; + hi2s->State = HAL_I2S_STATE_BUSY_TX_RX; + + + /* Set the function for IT treatment */ + if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B)) + { + hi2s->TxISR = I2S_Transmit_32Bit_IT; + hi2s->RxISR = I2S_Receive_32Bit_IT; + } + else + { + hi2s->TxISR = I2S_Transmit_16Bit_IT; + hi2s->RxISR = I2S_Receive_16Bit_IT; + } + + /* Check if the I2S is already enabled */ + if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) + { + /* Enable I2S peripheral */ + __HAL_I2S_ENABLE(hi2s); + } + + /* Enable TXP, RXP, DXP, UDR, OVR interrupts */ + __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_RXP | I2S_IT_DXP | I2S_IT_UDR | I2S_IT_OVR)); + + /* Enable TIFRE interrupt if the mode is Slave */ + if (hi2s->Init.Mode == I2S_MODE_SLAVE_FULLDUPLEX) + { + __HAL_I2S_ENABLE_IT(hi2s, I2S_IT_FRE); + } + + /* Start the transfer */ + SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART); + + __HAL_UNLOCK(hi2s); + return HAL_OK; + +} + +/** + * @brief Transmit an amount of data in non-blocking mode with DMA + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @param pData a 16-bit pointer to the Transmit data buffer. + * @param Size number of data sample to be sent: + * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S + * configuration phase, the Size parameter means the number of 16-bit data length + * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected + * the Size parameter means the number of 16-bit data length. + * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization + * between Master and Slave(example: audio streaming). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2S_Transmit_DMA(I2S_HandleTypeDef *hi2s, const uint16_t *pData, uint16_t Size) +{ + HAL_StatusTypeDef errorcode; + + if ((pData == NULL) || (Size == 0UL)) + { + return HAL_ERROR; + } + + if (hi2s->State != HAL_I2S_STATE_READY) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2s); + + /* Set state and reset error code */ + hi2s->State = HAL_I2S_STATE_BUSY_TX; + hi2s->ErrorCode = HAL_I2S_ERROR_NONE; + hi2s->pTxBuffPtr = (const uint16_t *)pData; + hi2s->TxXferSize = Size; + hi2s->TxXferCount = Size; + + /* Init field not used in handle to zero */ + hi2s->pRxBuffPtr = NULL; + hi2s->RxXferSize = (uint16_t)0UL; + hi2s->RxXferCount = (uint16_t)0UL; + + /* Set the I2S Tx DMA Half transfer complete callback */ + hi2s->hdmatx->XferHalfCpltCallback = I2S_DMATxHalfCplt; + + /* Set the I2S Tx DMA transfer complete callback */ + hi2s->hdmatx->XferCpltCallback = I2S_DMATxCplt; + + /* Set the DMA error callback */ + hi2s->hdmatx->XferErrorCallback = I2S_DMAError; + + if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_16B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_16B_EXTENDED)) + { + hi2s->TxXferCount = Size * 2U; + } + else + { + hi2s->TxXferCount = Size * 4U; + } + + /* Enable the Tx DMA Stream/Channel */ + if ((hi2s->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hi2s->hdmatx->LinkedListQueue != NULL) + { + /* Set DMA data size */ + hi2s->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hi2s->TxXferCount; + + /* Set DMA source address */ + hi2s->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)hi2s->pTxBuffPtr; + + /* Set DMA destination address */ + hi2s->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)&hi2s->Instance->TXDR; + + errorcode = HAL_DMAEx_List_Start_IT(hi2s->hdmatx); + } + else + { + /* Update SPI error code */ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA); + + /* Unlock the process */ + __HAL_UNLOCK(hi2s); + + hi2s->State = HAL_I2S_STATE_READY; + errorcode = HAL_ERROR; + return errorcode; + } + } + else + { + errorcode = HAL_DMA_Start_IT(hi2s->hdmatx, (uint32_t)hi2s->pTxBuffPtr, (uint32_t)&hi2s->Instance->TXDR, + hi2s->TxXferCount); + } + + /* Check status */ + if (errorcode != HAL_OK) + { + /* Update I2S error code */ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA); + hi2s->State = HAL_I2S_STATE_READY; + + __HAL_UNLOCK(hi2s); + errorcode = HAL_ERROR; + return errorcode; + } + + /* Check if the I2S Tx request is already enabled */ + if (HAL_IS_BIT_CLR(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN)) + { + /* Enable Tx DMA Request */ + SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN); + } + + /* Check if the I2S is already enabled */ + if (HAL_IS_BIT_CLR(hi2s->Instance->CR1, SPI_CR1_SPE)) + { + /* Enable I2S peripheral */ + __HAL_I2S_ENABLE(hi2s); + } + + /* Start the transfer */ + SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART); + + __HAL_UNLOCK(hi2s); + return errorcode; +} + +/** + * @brief Receive an amount of data in non-blocking mode with DMA + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @param pData a 16-bit pointer to the Receive data buffer. + * @param Size number of data sample to be sent: + * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S + * configuration phase, the Size parameter means the number of 16-bit data length + * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected + * the Size parameter means the number of 16-bit data length. + * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization + * between Master and Slave(example: audio streaming). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2S_Receive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size) +{ + HAL_StatusTypeDef errorcode; + + if ((pData == NULL) || (Size == 0UL)) + { + return HAL_ERROR; + } + + if (hi2s->State != HAL_I2S_STATE_READY) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2s); + + /* Set state and reset error code */ + hi2s->State = HAL_I2S_STATE_BUSY_RX; + hi2s->ErrorCode = HAL_I2S_ERROR_NONE; + hi2s->pRxBuffPtr = pData; + hi2s->RxXferSize = Size; + hi2s->RxXferCount = Size; + + /* Init field not used in handle to zero */ + hi2s->pTxBuffPtr = NULL; + hi2s->TxXferSize = (uint16_t)0UL; + hi2s->TxXferCount = (uint16_t)0UL; + + + /* Set the I2S Rx DMA Half transfer complete callback */ + hi2s->hdmarx->XferHalfCpltCallback = I2S_DMARxHalfCplt; + + /* Set the I2S Rx DMA transfer complete callback */ + hi2s->hdmarx->XferCpltCallback = I2S_DMARxCplt; + + /* Set the DMA error callback */ + hi2s->hdmarx->XferErrorCallback = I2S_DMAError; + + if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_16B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_16B_EXTENDED)) + { + hi2s->RxXferCount = Size * 2U; + } + else + { + hi2s->RxXferCount = Size * 4U; + } + + /* Enable the Rx DMA Stream/Channel */ + if ((hi2s->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hi2s->hdmarx->LinkedListQueue != NULL) + { + /* Set DMA data size */ + hi2s->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hi2s->RxXferCount; + + /* Set DMA source address */ + hi2s->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)&hi2s->Instance->RXDR; + + /* Set DMA destination address */ + hi2s->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)hi2s->pRxBuffPtr; + + errorcode = HAL_DMAEx_List_Start_IT(hi2s->hdmarx); + } + else + { + /* Update SPI error code */ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA); + + /* Unlock the process */ + __HAL_UNLOCK(hi2s); + + hi2s->State = HAL_I2S_STATE_READY; + errorcode = HAL_ERROR; + return errorcode; + } + } + else + { + errorcode = HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->RXDR, (uint32_t)hi2s->pRxBuffPtr, + hi2s->RxXferCount); + } + + /* Check status */ + if (errorcode != HAL_OK) + { + /* Update I2S error code */ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA); + hi2s->State = HAL_I2S_STATE_READY; + errorcode = HAL_ERROR; + __HAL_UNLOCK(hi2s); + return errorcode; + } + + /* Check if the I2S Rx request is already enabled */ + if (HAL_IS_BIT_CLR(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN)) + { + /* Enable Rx DMA Request */ + SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN); + } + + /* Check if the I2S is already enabled */ + if (HAL_IS_BIT_CLR(hi2s->Instance->CR1, SPI_CR1_SPE)) + { + /* Enable I2S peripheral */ + __HAL_I2S_ENABLE(hi2s); + } + + /* Start the transfer */ + SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART); + + __HAL_UNLOCK(hi2s); + return errorcode; +} + +/** + * @brief Full-Duplex Transmit/Receive data in non-blocking mode using DMA + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @param pTxData a 16-bit pointer to the Transmit data buffer. + * @param pRxData a 16-bit pointer to the Receive data buffer. + * @param Size number of data sample to be sent: + * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S + * configuration phase, the Size parameter means the number of 16-bit data length + * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected + * the Size parameter means the number of 16-bit data length. + * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization + * between Master and Slave(example: audio streaming). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_DMA(I2S_HandleTypeDef *hi2s, const uint16_t *pTxData, uint16_t *pRxData, + uint16_t Size) +{ + HAL_StatusTypeDef errorcode; + + + if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + if (hi2s->State != HAL_I2S_STATE_READY) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2s); + + hi2s->pTxBuffPtr = (const uint16_t *)pTxData; + hi2s->pRxBuffPtr = pRxData; + + hi2s->TxXferSize = Size; + hi2s->TxXferCount = Size; + hi2s->RxXferSize = Size; + hi2s->RxXferCount = Size; + + hi2s->ErrorCode = HAL_I2S_ERROR_NONE; + hi2s->State = HAL_I2S_STATE_BUSY_TX_RX; + + /* Reset the Tx/Rx DMA bits */ + CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN); + + /* Set the I2S Rx DMA Half transfer complete callback */ + hi2s->hdmarx->XferHalfCpltCallback = I2SEx_DMATxRxHalfCplt; + + /* Set the I2S Rx DMA transfer complete callback */ + hi2s->hdmarx->XferCpltCallback = I2SEx_DMATxRxCplt; + + /* Set the I2S Rx DMA error callback */ + hi2s->hdmarx->XferErrorCallback = I2S_DMAError; + if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_16B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_16B_EXTENDED)) + { + hi2s->TxXferCount = Size * 2U; + } + else + { + hi2s->TxXferCount = Size * 4U; + } + + /* Enable the Tx DMA Stream/Channel */ + if ((hi2s->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hi2s->hdmatx->LinkedListQueue != NULL) + { + /* Set DMA data size */ + hi2s->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hi2s->TxXferCount; + + /* Set DMA source address */ + hi2s->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)hi2s->pTxBuffPtr; + + /* Set DMA destination address */ + hi2s->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)&hi2s->Instance->TXDR; + + errorcode = HAL_DMAEx_List_Start_IT(hi2s->hdmatx); + } + else + { + /* Update SPI error code */ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA); + + /* Unlock the process */ + __HAL_UNLOCK(hi2s); + + hi2s->State = HAL_I2S_STATE_READY; + errorcode = HAL_ERROR; + return errorcode; + } + } + else + { + errorcode = HAL_DMA_Start_IT(hi2s->hdmatx, (uint32_t)hi2s->pTxBuffPtr, (uint32_t)&hi2s->Instance->TXDR, + hi2s->TxXferCount); + } + + /* Check status */ + if (errorcode != HAL_OK) + { + /* Update I2S error code */ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA); + hi2s->State = HAL_I2S_STATE_READY; + + __HAL_UNLOCK(hi2s); + errorcode = HAL_ERROR; + return errorcode; + } + + /* Check if the I2S Tx request is already enabled */ + if (HAL_IS_BIT_CLR(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN)) + { + /* Enable Tx DMA Request */ + SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN); + } + + if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_16B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_16B_EXTENDED)) + { + hi2s->RxXferCount = Size * 2U; + } + else + { + hi2s->RxXferCount = Size * 4U; + } + + /* Enable the Rx DMA Stream/Channel */ + if ((hi2s->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hi2s->hdmarx->LinkedListQueue != NULL) + { + /* Set DMA data size */ + hi2s->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hi2s->RxXferCount; + + /* Set DMA source address */ + hi2s->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)&hi2s->Instance->RXDR; + + /* Set DMA destination address */ + hi2s->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)hi2s->pRxBuffPtr; + + errorcode = HAL_DMAEx_List_Start_IT(hi2s->hdmarx); + } + else + { + /* Update SPI error code */ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA); + + /* Unlock the process */ + __HAL_UNLOCK(hi2s); + + hi2s->State = HAL_I2S_STATE_READY; + errorcode = HAL_ERROR; + return errorcode; + } + } + else + { + errorcode = HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->RXDR, (uint32_t)hi2s->pRxBuffPtr, + hi2s->RxXferCount); + } + + /* Check status */ + if (errorcode != HAL_OK) + { + /* Update I2S error code */ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA); + hi2s->State = HAL_I2S_STATE_READY; + errorcode = HAL_ERROR; + __HAL_UNLOCK(hi2s); + return errorcode; + } + + /* Check if the I2S Rx request is already enabled */ + if (HAL_IS_BIT_CLR(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN)) + { + /* Enable Rx DMA Request */ + SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN); + } + + /* Check if the I2S is already enabled */ + if (HAL_IS_BIT_CLR(hi2s->Instance->CR1, SPI_CR1_SPE)) + { + /* Enable I2S peripheral */ + __HAL_I2S_ENABLE(hi2s); + } + + /* Start the transfer */ + SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART); + + __HAL_UNLOCK(hi2s); + return errorcode; +} + +/** + * @brief Pauses the audio DMA Stream/Channel playing from the Media. + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2S_DMAPause(I2S_HandleTypeDef *hi2s) +{ + /* Process Locked */ + __HAL_LOCK(hi2s); + + uint32_t tickstart; + + /* Get tick */ + tickstart = HAL_GetTick(); + + + /* Check if the I2S peripheral is in master mode */ + if (IS_I2S_MASTER(hi2s->Init.Mode)) + { + /* Check if there is a transfer on-going */ + if (HAL_IS_BIT_SET(hi2s->Instance->CR1, SPI_CR1_CSTART) == 0UL) + { + /* Set error code to no on going transfer */ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_NO_OGT); + hi2s->State = HAL_I2S_STATE_READY; + + __HAL_UNLOCK(hi2s); + return HAL_ERROR; + } + + SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSUSP); + + while (HAL_IS_BIT_SET(hi2s->Instance->CR1, SPI_CR1_CSTART) != 0UL) + { + if ((((HAL_GetTick() - tickstart) >= I2S_TIMEOUT) && (I2S_TIMEOUT != HAL_MAX_DELAY)) || (I2S_TIMEOUT == 0U)) + { + /* Set the I2S State ready */ + hi2s->State = HAL_I2S_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT); + hi2s->State = HAL_I2S_STATE_READY; + return HAL_TIMEOUT; + } + } + + /* Disable I2S peripheral */ + __HAL_I2S_DISABLE(hi2s); + + hi2s->State = HAL_I2S_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + + return HAL_OK; + } + else + { + /* Set error code to not supported */ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_NOT_SUPPORTED); + hi2s->State = HAL_I2S_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + + return HAL_ERROR; + } +} + +/** + * @brief Resumes the audio DMA Stream/Channel playing from the Media. + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2S_DMAResume(I2S_HandleTypeDef *hi2s) +{ + /* Process Locked */ + __HAL_LOCK(hi2s); + + if (hi2s->State != HAL_I2S_STATE_READY) + { + hi2s->State = HAL_I2S_STATE_READY; + + __HAL_UNLOCK(hi2s); + return HAL_ERROR; + } + + /* Set state and reset error code */ + hi2s->State = HAL_I2S_STATE_BUSY; + hi2s->ErrorCode = HAL_I2S_ERROR_NONE; + + /* Enable I2S peripheral */ + __HAL_I2S_ENABLE(hi2s); + + /* Start the transfer */ + SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + + return HAL_OK; +} + +/** + * @brief Stops the audio DMA Stream/Channel playing from the Media. + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s) +{ + HAL_StatusTypeDef errorcode = HAL_OK; + /* The Lock is not implemented on this API to allow the user application + to call the HAL I2S API under callbacks HAL_I2S_TxCpltCallback() or HAL_I2S_RxCpltCallback() + when calling HAL_DMA_Abort() API the DMA TX or RX Transfer complete interrupt is generated + and the correspond call back is executed HAL_I2S_TxCpltCallback() or HAL_I2S_RxCpltCallback() + */ + + /* Disable the I2S Tx/Rx DMA requests */ + CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN); + CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN); + + /* Abort the I2S DMA tx Stream/Channel */ + if (hi2s->hdmatx != NULL) + { + /* Disable the I2S DMA tx Stream/Channel */ + if (HAL_OK != HAL_DMA_Abort(hi2s->hdmatx)) + { + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA); + errorcode = HAL_ERROR; + } + } + + /* Abort the I2S DMA rx Stream/Channel */ + if (hi2s->hdmarx != NULL) + { + /* Disable the I2S DMA rx Stream/Channel */ + if (HAL_OK != HAL_DMA_Abort(hi2s->hdmarx)) + { + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA); + errorcode = HAL_ERROR; + } + } + + /* Disable I2S peripheral */ + __HAL_I2S_DISABLE(hi2s); + + hi2s->State = HAL_I2S_STATE_READY; + + return errorcode; +} + +/** + * @brief This function handles I2S interrupt request. + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval None + */ +void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s) +{ + uint32_t i2sier = hi2s->Instance->IER; + uint32_t i2ssr = hi2s->Instance->SR; + uint32_t trigger = i2sier & i2ssr; + + if (hi2s->State == HAL_I2S_STATE_BUSY_RX) + { + /* I2S in mode Receiver ------------------------------------------------*/ + if (HAL_IS_BIT_SET(trigger, I2S_FLAG_RXP) && HAL_IS_BIT_CLR(trigger, I2S_FLAG_OVR)) + { + hi2s->RxISR(hi2s); + } + + /* I2S Overrun error interrupt occurred -------------------------------------*/ + if (HAL_IS_BIT_SET(trigger, I2S_FLAG_OVR)) + { + /* Disable RXP and ERR interrupt */ + __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXP | I2S_IT_ERR)); + + /* Clear Overrun flag */ + __HAL_I2S_CLEAR_OVRFLAG(hi2s); + + /* Set the I2S State ready */ + hi2s->State = HAL_I2S_STATE_READY; + + + /* Set the error code and execute error callback*/ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR); + /* Call user error callback */ +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL) + hi2s->ErrorCallback(hi2s); +#else + HAL_I2S_ErrorCallback(hi2s); +#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ + } + } + + if (hi2s->State == HAL_I2S_STATE_BUSY_TX) + { + /* I2S in mode Transmitter -----------------------------------------------*/ + if (HAL_IS_BIT_SET(trigger, I2S_FLAG_TXP) && HAL_IS_BIT_CLR(trigger, I2S_FLAG_UDR)) + { + hi2s->TxISR(hi2s); + } + + /* I2S Underrun error interrupt occurred --------------------------------*/ + if (HAL_IS_BIT_SET(trigger, I2S_FLAG_UDR)) + { + /* Disable TXP and ERR interrupt */ + __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_ERR)); + + /* Clear Underrun flag */ + __HAL_I2S_CLEAR_UDRFLAG(hi2s); + + /* Set the I2S State ready */ + hi2s->State = HAL_I2S_STATE_READY; + + /* Set the error code and execute error callback*/ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR); + /* Call user error callback */ +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL) + hi2s->ErrorCallback(hi2s); +#else + HAL_I2S_ErrorCallback(hi2s); +#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ + } + } + if (hi2s->State == HAL_I2S_STATE_BUSY_TX_RX) + { + /* I2S in mode Transmitter -----------------------------------------------*/ + if (HAL_IS_BIT_SET(trigger, I2S_FLAG_DXP)) + { + hi2s->TxISR(hi2s); + hi2s->RxISR(hi2s); + } + /* I2S in mode Receiver ------------------------------------------------*/ + if (HAL_IS_BIT_SET(trigger, I2S_FLAG_RXP) && HAL_IS_BIT_CLR(trigger, I2S_FLAG_DXP)) + { + hi2s->RxISR(hi2s); + } + /* I2S in mode Transmitter -----------------------------------------------*/ + if (HAL_IS_BIT_SET(trigger, I2S_FLAG_TXP) && HAL_IS_BIT_CLR(trigger, I2S_FLAG_DXP)) + { + hi2s->TxISR(hi2s); + } + + /* I2S Underrun error interrupt occurred --------------------------------*/ + if (HAL_IS_BIT_SET(trigger, I2S_FLAG_UDR)) + { + /* Disable TXP, RXP and ERR interrupt */ + __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_RXP | I2S_IT_ERR)); + + /* Clear Underrun flag */ + __HAL_I2S_CLEAR_UDRFLAG(hi2s); + + /* Set the I2S State ready */ + hi2s->State = HAL_I2S_STATE_READY; + + /* Set the error code and execute error callback*/ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR); + /* Call user error callback */ +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL) + hi2s->ErrorCallback(hi2s); +#else + HAL_I2S_ErrorCallback(hi2s); +#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ + } + + /* I2S Overrun error interrupt occurred -------------------------------------*/ + if (HAL_IS_BIT_SET(trigger, I2S_FLAG_OVR)) + { + /* Disable TXP, RXP and ERR interrupt */ + __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_RXP | I2S_IT_ERR)); + + /* Clear Overrun flag */ + __HAL_I2S_CLEAR_OVRFLAG(hi2s); + + /* Set the I2S State ready */ + hi2s->State = HAL_I2S_STATE_READY; + + + /* Set the error code and execute error callback*/ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR); + + /* Call user error callback */ +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL) + hi2s->ErrorCallback(hi2s); +#else + HAL_I2S_ErrorCallback(hi2s); +#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ + } + } +} + +/** + * @brief Tx Transfer Half completed callbacks + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval None + */ +__weak void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2s); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2S_TxHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Tx Transfer completed callbacks + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval None + */ +__weak void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2s); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2S_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Transfer half completed callbacks + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval None + */ +__weak void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2s); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2S_RxHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Transfer completed callbacks + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval None + */ +__weak void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2s); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2S_RxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Transfer half completed callbacks + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval None + */ +__weak void HAL_I2SEx_TxRxHalfCpltCallback(I2S_HandleTypeDef *hi2s) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2s); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2S_RxHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Transfer completed callbacks + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval None + */ +__weak void HAL_I2SEx_TxRxCpltCallback(I2S_HandleTypeDef *hi2s) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2s); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2S_RxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief I2S error callbacks + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval None + */ +__weak void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2s); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2S_ErrorCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup I2S_Exported_Functions_Group3 Peripheral State and Errors functions + * @brief Peripheral State functions + * +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the I2S state + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval HAL state + */ +HAL_I2S_StateTypeDef HAL_I2S_GetState(const I2S_HandleTypeDef *hi2s) +{ + return hi2s->State; +} + +/** + * @brief Return the I2S error code + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval I2S Error Code + */ +uint32_t HAL_I2S_GetError(const I2S_HandleTypeDef *hi2s) +{ + return hi2s->ErrorCode; +} +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup I2S_Private_Functions + * @{ + */ +/** + * @brief DMA I2S transmit process complete callback + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma) +{ + /* Derogation MISRAC2012-Rule-11.5 */ + I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* if DMA is configured in DMA_NORMAL Mode */ + if (hdma->Init.Mode == DMA_NORMAL) + { + /* Disable Tx DMA Request */ + CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN); + + hi2s->TxXferCount = (uint16_t) 0UL; + hi2s->State = HAL_I2S_STATE_READY; + } + /* Call user Tx complete callback */ +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL) + hi2s->TxCpltCallback(hi2s); +#else + HAL_I2S_TxCpltCallback(hi2s); +#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA I2S transmit process half complete callback + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma) +{ + /* Derogation MISRAC2012-Rule-11.5 */ + I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Call user Tx half complete callback */ +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL) + hi2s->TxHalfCpltCallback(hi2s); +#else + HAL_I2S_TxHalfCpltCallback(hi2s); +#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA I2S receive process complete callback + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma) +{ + /* Derogation MISRAC2012-Rule-11.5 */ + I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* if DMA is configured in DMA_NORMAL Mode */ + if (hdma->Init.Mode == DMA_NORMAL) + { + /* Disable Rx DMA Request */ + CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN); + hi2s->RxXferCount = (uint16_t)0UL; + hi2s->State = HAL_I2S_STATE_READY; + } + /* Call user Rx complete callback */ +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL) + hi2s->RxCpltCallback(hi2s); +#else + HAL_I2S_RxCpltCallback(hi2s); +#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA I2S receive process half complete callback + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma) +{ + /* Derogation MISRAC2012-Rule-11.5 */ + I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Call user Rx half complete callback */ +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL) + hi2s->RxHalfCpltCallback(hi2s); +#else + HAL_I2S_RxHalfCpltCallback(hi2s); +#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA I2S transmit receive process complete callback + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void I2SEx_DMATxRxCplt(DMA_HandleTypeDef *hdma) +{ + I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* if DMA is configured in DMA_NORMAL Mode */ + if (hdma->Init.Mode == DMA_NORMAL) + { + /* Disable Tx DMA Request */ + CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN); + hi2s->TxXferCount = (uint16_t) 0UL; + + /* Disable Rx DMA Request */ + CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN); + hi2s->RxXferCount = (uint16_t)0UL; + + /* Updated HAL State */ + hi2s->State = HAL_I2S_STATE_READY; + } + + /* Call user TxRx complete callback */ +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U) + hi2s->TxRxCpltCallback(hi2s); +#else + HAL_I2SEx_TxRxCpltCallback(hi2s); +#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA I2S transmit receive process half complete callback + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void I2SEx_DMATxRxHalfCplt(DMA_HandleTypeDef *hdma) +{ + I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Call user TxRx Half complete callback */ +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U) + hi2s->TxRxHalfCpltCallback(hi2s); +#else + HAL_I2SEx_TxRxHalfCpltCallback(hi2s); +#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA I2S communication error callback + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void I2S_DMAError(DMA_HandleTypeDef *hdma) +{ + /* Derogation MISRAC2012-Rule-11.5 */ + I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Disable Rx and Tx DMA Request */ + CLEAR_BIT(hi2s->Instance->CFG1, (SPI_CFG1_RXDMAEN | SPI_CFG1_TXDMAEN)); + hi2s->TxXferCount = (uint16_t) 0UL; + hi2s->RxXferCount = (uint16_t) 0UL; + + hi2s->State = HAL_I2S_STATE_READY; + + /* Set the error code and execute error callback*/ + SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA); + /* Call user error callback */ +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL) + hi2s->ErrorCallback(hi2s); +#else + HAL_I2S_ErrorCallback(hi2s); +#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ +} + +/** + * @brief Manage the transmission 16-bit in Interrupt context + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval None + */ +static void I2S_Transmit_16Bit_IT(I2S_HandleTypeDef *hi2s) +{ + /* Transmit data */ +#if defined (__GNUC__) + __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->TXDR)); + + *ptxdr_16bits = *((const uint16_t *)hi2s->pTxBuffPtr); +#else + *((__IO uint16_t *)&hi2s->Instance->TXDR) = *((const uint16_t *)hi2s->pTxBuffPtr); +#endif /* __GNUC__ */ + hi2s->pTxBuffPtr++; + hi2s->TxXferCount--; + + if (hi2s->TxXferCount == 0UL) + { + /* Disable TXP and ERR interrupt */ + __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_ERR)); + + if ((hi2s->Init.Mode == I2S_MODE_SLAVE_TX) || (hi2s->Init.Mode == I2S_MODE_MASTER_TX)) + { + hi2s->State = HAL_I2S_STATE_READY; + + /* Call user Tx complete callback */ +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL) + hi2s->TxCpltCallback(hi2s); +#else + HAL_I2S_TxCpltCallback(hi2s); +#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ + } + } +} + +/** + * @brief Manage the transmission 32-bit in Interrupt context + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval None + */ +static void I2S_Transmit_32Bit_IT(I2S_HandleTypeDef *hi2s) +{ + /* Transmit data */ + hi2s->Instance->TXDR = *((const uint32_t *)hi2s->pTxBuffPtr); + hi2s->pTxBuffPtr += 2; + hi2s->TxXferCount--; + + if (hi2s->TxXferCount == 0UL) + { + /* Disable TXP and ERR interrupt */ + __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_ERR)); + + if ((hi2s->Init.Mode == I2S_MODE_SLAVE_TX) || (hi2s->Init.Mode == I2S_MODE_MASTER_TX)) + { + hi2s->State = HAL_I2S_STATE_READY; + + /* Call user Tx complete callback */ +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL) + hi2s->TxCpltCallback(hi2s); +#else + HAL_I2S_TxCpltCallback(hi2s); +#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ + } + } +} + +/** + * @brief Manage the reception 16-bit in Interrupt context + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval None + */ +static void I2S_Receive_16Bit_IT(I2S_HandleTypeDef *hi2s) +{ + /* Receive data */ +#if defined (__GNUC__) + __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->RXDR)); + + *((uint16_t *)hi2s->pRxBuffPtr) = *prxdr_16bits; +#else + *((uint16_t *)hi2s->pRxBuffPtr) = *((__IO uint16_t *)&hi2s->Instance->RXDR); +#endif /* __GNUC__ */ + hi2s->pRxBuffPtr++; + hi2s->RxXferCount--; + + if (hi2s->RxXferCount == 0UL) + { + if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode)) + { + /* Disable TXP, RXP, DXP, ERR interrupts */ + __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_RXP | I2S_IT_DXP | I2S_IT_ERR)); + } + else + { + /* Disable RXP and ERR interrupt */ + __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXP | I2S_IT_ERR)); + } + + hi2s->State = HAL_I2S_STATE_READY; + /* Call user Rx complete callback */ +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL) + if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode)) + { + hi2s->TxRxCpltCallback(hi2s); + } + else + { + hi2s->RxCpltCallback(hi2s); + } +#else + if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode)) + { + HAL_I2SEx_TxRxCpltCallback(hi2s); + } + else + { + HAL_I2S_RxCpltCallback(hi2s); + } +#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ + } +} + +/** + * @brief Manage the reception 32-bit in Interrupt context + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval None + */ +static void I2S_Receive_32Bit_IT(I2S_HandleTypeDef *hi2s) +{ + /* Receive data */ + *((uint32_t *)hi2s->pRxBuffPtr) = hi2s->Instance->RXDR; + hi2s->pRxBuffPtr += 2; + hi2s->RxXferCount--; + + if (hi2s->RxXferCount == 0UL) + { + if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode)) + { + /* Disable TXP, RXP, DXP, ERR interrupts */ + __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_RXP | I2S_IT_DXP | I2S_IT_ERR)); + } + else + { + /* Disable RXP and ERR interrupt */ + __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXP | I2S_IT_ERR)); + } + + hi2s->State = HAL_I2S_STATE_READY; + /* Call user Rx complete callback */ +#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL) + if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode)) + { + hi2s->TxRxCpltCallback(hi2s); + } + else + { + hi2s->RxCpltCallback(hi2s); + } +#else + if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode)) + { + HAL_I2SEx_TxRxCpltCallback(hi2s); + } + else + { + HAL_I2S_RxCpltCallback(hi2s); + } +#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */ + } +} + +/** + * @brief This function handles I2S Communication Timeout. + * @param hi2s pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @param Flag Flag checked + * @param State Value of the flag expected + * @param Tickstart Tick start value + * @param Timeout Duration of the timeout + * @retval HAL status + */ +static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, FlagStatus State, + uint32_t Tickstart, uint32_t Timeout) +{ + /* Wait until flag is set to status*/ + while (((__HAL_I2S_GET_FLAG(hi2s, Flag)) ? SET : RESET) != State) + { + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - Tickstart) >= Timeout) || (Timeout == 0UL)) + { + /* Set the I2S State ready */ + hi2s->State = HAL_I2S_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + + return HAL_TIMEOUT; + } + } + } + return HAL_OK; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_I2S_MODULE_ENABLED */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_i2s_ex.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_i2s_ex.c new file mode 100644 index 0000000000..4894fb9897 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_i2s_ex.c @@ -0,0 +1,31 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_i2s_ex.c + * @author MCD Application Team + * @brief I2S HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of I2S extension peripheral: + * + Extension features Functions + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/** + ****************************************************************************** + ===== I2S FULL DUPLEX FEATURE ===== + I2S Full Duplex APIs are available in stm32h5xx_hal_i2s.c/.h + ****************************************************************************** + */ + + + + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_i3c.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_i3c.c new file mode 100644 index 0000000000..1d43699e5c --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_i3c.c @@ -0,0 +1,9263 @@ +/** + ********************************************************************************************************************** + * @file stm32h5xx_hal_i3c.c + * @author MCD Application Team + * @brief I3C HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Improvement Inter Integrated Circuit (I3C) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral State and Errors functions + * + ********************************************************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ********************************************************************************************************************** + @verbatim + ====================================================================================================================== + ##### How to use this driver ##### + ====================================================================================================================== + [..] + The I3C HAL driver can be used as follows: + + (#) Declare a I3C_HandleTypeDef handle structure, for example: + I3C_HandleTypeDef hi3c; + + (#) Declare a I3C_XferTypeDef transfer descriptor structure, for example: + I3C_XferTypeDef ContextBuffers; + + (#)Initialize the I3C low level resources by implementing the HAL_I3C_MspInit() API: + (##) Enable the I3Cx interface clock + (##) I3C pins configuration + (+++) Enable the clock for the I3C GPIOs + (+++) Configure I3C pins as alternate function push-pull with no-pull + (##) NVIC configuration if you need to use interrupt process + (+++) Configure the I3Cx interrupt priority + (+++) Enable the NVIC I3C IRQ Channel + (##) DMA Configuration if you need to use DMA process + (+++) Declare a DMA_HandleTypeDef handle structure for + the Command Common Code (CCC) management channel + (+++) Declare a DMA_HandleTypeDef handle structure for + the transmit channel + (+++) Declare a DMA_HandleTypeDef handle structure for + the receive channel + (+++) Declare a DMA_HandleTypeDef handle structure for + the status channel + (+++) Enable the DMAx interface clock + (+++) Configure the DMA handle parameters + (+++) Configure the DMA Command Common Code (CCC) channel + (+++) Configure the DMA Tx channel + (+++) Configure the DMA Rx channel + (+++) Configure the DMA Status channel + (+++) Associate the initialized DMA handle to the hi3c DMA CCC, Tx, Rx or Status handle as necessary + (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on + the DMA CCC, Tx, Rx or Status instance + + (#) Configure the HAL I3C Communication Mode as Controller or Target in the hi3c Init structure. + + (#) Configure the Controller Communication Bus characterics for Controller mode. + This mean, configure the parameters SDAHoldTime, WaitTime, SCLPPLowDuration, + SCLI3CHighDuration, SCLODLowDuration, SCLI2CHighDuration, BusFreeDuration, + BusIdleDuration in the LL_I3C_CtrlBusConfTypeDef structure through h3c Init structure. + + (#) Configure the Target Communication Bus characterics for Target mode. + This mean, configure the parameter BusAvailableDuration in the LL_I3C_TgtBusConfTypeDef structure + through h3c Init structure. + + All these parameters for Controller or Target can be configured directly in user code or + by using CubeMx generation. + To help the computation of the different parameters, the recommendation is to use CubeMx. + + Those parameters can be modified after the hi3c initialization by using + HAL_I3C_Ctrl_BusCharacteristicConfig() for controller and + HAL_I3C_Tgt_BusCharacteristicConfig() for target. + + (#) Initialize the I3C registers by calling the HAL_I3C_Init(), configures also the low level Hardware + (GPIO, CLOCK, NVIC...etc) by calling the customized HAL_I3C_MspInit(&hi3c) API. + + (#) Configure the different FIFO parameters in I3C_FifoConfTypeDef structure as RxFifoThreshold, TxFifoThreshold + for Controller or Target mode. + And enable/disable the Control or Status FIFO only for Controller Mode. + Use HAL_I3C_SetConfigFifo() function to finalize the configuration, and HAL_I3C_GetConfigFifo() to retrieve + FIFO configuration. + Possibility to clear the FIFO configuration by using HAL_I3C_ClearConfigFifo() which reset the configuration + FIFO to their default hardware value + + (#) Configure the different additional Controller configuration in I3C_CtrlConfTypeDef structure as DynamicAddr, + StallTime, HotJoinAllowed, ACKStallState, CCCStallState, TxStallState, RxStallState, HighKeeperSDA. + Use HAL_I3C_Ctrl_Config() function to finalize the Controller configuration. + + (#) Configure the different additional Target configuration in I3C_TgtConfTypeDef structure as Identifier, + MIPIIdentifier, CtrlRoleRequest, HotJoinRequest, IBIRequest, IBIPayload, IBIPayloadSize, MaxReadDataSize, + MaxWriteDataSize, CtrlCapability, GroupAddrCapability, DataTurnAroundDuration, MaxReadTurnAround, + MaxDataSpeed, MaxSpeedLimitation, HandOffActivityState, HandOffDelay, PendingReadMDB. + Use HAL_I3C_Tgt_Config() function to finalize the Target configuration. + + (#) Before initiate any IO operation, the application must launch an assignment of the different + Target dynamic address by using HAL_I3C_Ctrl_DynAddrAssign() in polling mode or + HAL_I3C_Ctrl_DynAddrAssign_IT() in interrupt mode. + This procedure is named Enter Dynamic Address Assignment (ENTDAA CCC command). + For the initiation of ENTDAA procedure from the controller, each target connected and powered on the I3C bus + must repond to this particular Command Common Code by sending its proper Payload (a amount of 48bits which + contain the target characteristics) + Each time a target responds to ENTDAA sequence, the application is informed through + HAL_I3C_TgtReqDynamicAddrCallback() of the reception of the target paylaod. + And then application must send a associated dynamic address through HAL_I3C_Ctrl_SetDynAddr(). + This procedure in loop automatically in hardware side until a target respond to repeated ENTDAA sequence. + The application is informed of the end of the procedure at reception of HAL_I3C_CtrlDAACpltCallback(). + At the end of procedure, the function HAL_I3C_Ctrl_ConfigBusDevices() must be called to store in hardware + register part the target capabilities as Dynamic address, IBI support with or without additional data byte, + Controller role request support, Controller stop transfer after IBI through I3C_DeviceConfTypeDef structure. + + (#) Other action to be done, before initiate any IO operation, the application must prepare the different frame + descriptor with its associated buffer allocation in their side. + Configure the different information related to CCC transfer through I3C_CCCTypeDef structure + Configure the different information related to Private or I2C transfer through I3C_PrivateTypeDef structure + Configure the different buffer pointers and associated size needed for the driver communication + through I3C_XferTypeDef structure + The I3C_XferTypeDef structure contains different parameters about Control, Status buffer, + and Transmit and Receive buffer. + Use HAL_I3C_AddDescToFrame() function each time application add a descriptor in the frame before call + an IO operation interface + One element of the frame descriptor correspond to one frame to manage through IO operation. + + (#) To check if I3C target device is ready for communication, use the function HAL_I3C_Ctrl_IsDeviceI3C_Ready() + + (#) To check if I2C target device is ready for communication, use the function HAL_I3C_Ctrl_IsDeviceI2C_Ready() + + (#) For I3C IO operations, three operation modes are available within this driver : + + *** Polling mode IO operation *** + ================================= + [..] + (+) Activate asynchronous event in controller or target mode a Common Command Code in a broadcast + or a direct communication in blocking mode using HAL_I3C_Ctrl_TransmitCCC() + (+) Transmit in controller mode a Common Command Code in a broadcast or a direct communication in blocking mode + using HAL_I3C_Ctrl_TransmitCCC() + (+) Receive in controller mode a Common Command Code in a direct communication in blocking mode + using HAL_I3C_Ctrl_ReceiveCCC() + (+) Transmit in controller mode an amount of private data in an I3C or an I2C communication in blocking mode + using HAL_I3C_Ctrl_Transmit() + (+) Receive in controller mode an amount of private data in an I3C or an I2C communication in blocking mode + using HAL_I3C_Ctrl_Receive() + (+) Transmit in target mode an amount of private data in an I3C communication in blocking mode + using HAL_I3C_Tgt_Transmit() + (+) Receive in target mode an amount of private data in an I3C communication in blocking mode + using HAL_I3C_Tgt_Receive() + (+) At the end of a transfer, the different FIFO can be flushed if necessary by using HAL_I3C_FlushAllFifo() for + flush all the FIFO, or flush individually y using HAL_I3C_FlushTxFifo(), HAL_I3C_FlushRxFifo(), + HAL_I3C_FlushControlFifo(), HAL_I3C_FlushStatusFifo(). + (+) Request a HotJoin in target mode in blocking mode using HAL_I3C_Tgt_HotJoinReq() + (+) Request a In Band Interrupt in target mode in blocking mode using HAL_I3C_Tgt_IBIReq() + (+) Request a Controller Role in target mode in blocking mode using HAL_I3C_Tgt_ControlRoleReq() + + + *** DMA and Interrupt mode IO operation *** + =================================== + [..] + (+) Transmit in controller mode a Common Command Code in a broadcast or a direct communication in non-blocking + mode using HAL_I3C_Ctrl_TransmitCCC_IT() or HAL_I3C_Ctrl_TransmitCCC_DMA() + (+) At transmission end of transfer, HAL_I3C_CtrlTxCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_I3C_CtrlTxCpltCallback() + (+) Receive in controller mode a Common Command Code in a direct communication in non-blocking + mode using HAL_I3C_Ctrl_ReceiveCCC_IT() or HAL_I3C_Ctrl_ReceiveCCC_DMA() + (+) At reception end of transfer, HAL_I3C_CtrlRxCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_I3C_CtrlRxCpltCallback() + (+) Transmit in controller mode an amount of private data in an I3C or an I2C communication in non-blocking mode + using HAL_I3C_Ctrl_Transmit_IT() or HAL_I3C_Ctrl_Transmit_DMA() + (+) At transmission end of transfer, HAL_I3C_CtrlTxCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_I3C_CtrlTxCpltCallback() + (+) Receive in controller mode an amount of private data in an I3C or an I2C communication in non-blocking mode + using HAL_I3C_Ctrl_Receive_IT() or HAL_I3C_Ctrl_Receive_DMA() + (+) At reception end of transfer, HAL_I3C_CtrlRxCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_I3C_CtrlRxCpltCallback() + (+) Transfer in multiple direction (transmit/receive) in controller mode a Common Command Code in a direct + communication or an amount of private data in an I2C or I3C communication in non-blocking mode using + HAL_I3C_Ctrl_MultipleTransfer_IT() or HAL_I3C_Ctrl_MultipleTransfer_DMA() + (+) At the end of transfer, HAL_I3C_CtrlMultipleXferCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_I3C_CtrlMultipleXferCpltCallback() + (+) Transmit in target mode an amount of private data in an I3C communication in non-blocking mode + using HAL_I3C_Tgt_Transmit_IT() or HAL_I3C_Tgt_Transmit_DMA() + (+) At transmission end of transfer, HAL_I3C_TgtTxCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_I3C_TgtTxCpltCallback() + (+) Receive in target mode an amount of private data in an I3C communication in non-blocking mode + using HAL_I3C_Tgt_Receive_IT() or HAL_I3C_Tgt_Receive_DMA() + (+) At reception end of transfer, HAL_I3C_TgtRxCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_I3C_TgtRxCpltCallback() + (+) To treat asynchronous event, HAL_I3C_ActivateNotification() or HAL_I3C_DeactivateNotification() function is + used for enable or disable one or more notification related to specific asynchronous event. + Each time one or more event detected by hardware the associated HAL_I3C_NotifyCallback() is executed + and users can add their own code by customization of function pointer HAL_I3C_NotifyCallback(). + Then application can easily retrieve some specific associated event data through HAL_I3C_GetCCCInfo() function + (+) At the end of a transfer, the different FIFO can be flushed if necessary by using HAL_I3C_FlushAllFifo() for + flush all the FIFO, or flush individually y using HAL_I3C_FlushTxFifo(), HAL_I3C_FlushRxFifo(), + HAL_I3C_FlushControlFifo(), HAL_I3C_FlushStatusFifo(). + (+) Request a HotJoin in target mode in non-blocking mode using HAL_I3C_Tgt_HotJoinReq_IT + (+) At completion, HAL_I3C_TgtHotJoinCallback() is executed and users can + add their own code by customization of function pointer HAL_I3C_TgtHotJoinCallback() + (+) Request an In Band Interrupt in target mode in non-blocking mode using HAL_I3C_Tgt_IBIReq_IT() + (+) At completion, HAL_I3C_NotifyCallback() is executed and users can + add their own code by customization of function pointer HAL_I3C_NotifyCallback() + (+) Request a Controller Role in target mode in non-blocking mode using HAL_I3C_Tgt_ControlRoleReq_IT() + (+) At completion, HAL_I3C_NotifyCallback() is executed and users can + add their own code by customization of function pointer HAL_I3C_NotifyCallback() + (+) To manage the wakeup capability, HAL_I3C_ActivateNotification() or HAL_I3C_DeactivateNotification() function + is used for enable or disable Wake Up interrupt. + At wakeup detection the associated HAL_I3C_NotifyCallback() is executed. + (+) In case of transfer Error, HAL_I3C_ErrorCallback() function is executed and users can + add their own code by customization of function pointer HAL_I3C_ErrorCallback() + (+) Abort an I3C process communication with Interrupt using HAL_I3C_Abort_IT() + (+) End of abort process, HAL_I3C_AbortCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_I3C_AbortCpltCallback() + + + *** I3C HAL driver macros list *** + ================================== + [..] + Below the list of most used macros in I3C HAL driver. + + (+) __HAL_I3C_ENABLE: Enable the I3C peripheral + (+) __HAL_I3C_DISABLE: Disable the I3C peripheral + (+) __HAL_I3C_RESET_HANDLE_STATE: Reset the I3C handle state + (+) __HAL_I3C_GET_FLAG: Check whether the specified I3C flag is set or not + + *** Callback registration *** + ============================================= + [..] + The compilation flag USE_HAL_I3C_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + Use Functions HAL_I3C_RegisterCallback() or HAL_I3C_RegisterNotifyCallback() + or HAL_I3C_RegisterTgtReqDynamicAddrCallback() or HAL_I3C_RegisterTgtHotJoinCallback() + to register an interrupt callback. + [..] + Function HAL_I3C_RegisterCallback() allows to register following callbacks: + (+) CtrlTxCpltCallback : callback for Controller transmission CCC, I3C private or I2C end of transfer. + (+) CtrlRxCpltCallback : callback for Controller reception CCC, I3C private or I2C end of transfer. + (+) CtrlMultipleXferCpltCallback : callback for Controller multiple Direct CCC, I3C private or I2C + end of transfer. + (+) CtrlDAACpltCallback : callback for Controller Enter Dynamic Address Assignment end of transfer. + (+) TgtTxCpltCallback : callback for Target transmission I3C private end of transfer. + (+) TgtRxCpltCallback : callback for Target reception I3C private end of transfer. + (+) ErrorCallback : callback for error detection. + (+) AbortCpltCallback : callback for abort completion process. + (+) MspInitCallback : callback for Msp Init. + (+) MspDeInitCallback : callback for Msp DeInit. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + [..] + For specific callback NotifyCallback + use dedicated register callbacks : HAL_I3C_RegisterNotifyCallback(). + [..] + For specific callback TgtReqDynamicAddrCallback + use dedicated register callbacks : HAL_I3C_RegisterTgtReqDynamicAddrCallback(). + [..] + For specific callback TgtHotJoinCallback + use dedicated register callbacks : HAL_I3C_RegisterTgtHotJoinCallback(). + [..] + Use function HAL_I3C_UnRegisterCallback to reset a callback to the default + weak function. + HAL_I3C_UnRegisterCallback takes as parameters the HAL peripheral handle, + and the Callback ID. + This function allows to reset following callbacks: + (+) CtrlTxCpltCallback : callback for Controller transmission CCC, I3C private or I2C end of transfer. + (+) CtrlRxCpltCallback : callback for Controller reception CCC, I3C private or I2C end of transfer. + (+) CtrlMultipleXferCpltCallback : callback for Controller multiple Direct CCC, I3C private or I2C + end of transfer. + (+) CtrlDAACpltCallback : callback for Controller Enter Dynamic Address Assignment end of transfer. + (+) TgtTxCpltCallback : callback for Target transmission I3C private end of transfer. + (+) TgtRxCpltCallback : callback for Target reception I3C private end of transfer. + (+) ErrorCallback : callback for error detection. + (+) AbortCpltCallback : callback for abort completion process. + (+) MspInitCallback : callback for Msp Init. + (+) MspDeInitCallback : callback for Msp DeInit. + (+) NotifyCallback : callback for Controller and Target notification process. + (+) TgtReqDynamicAddrCallback : callback for controller application + when a target sent its payload to the controller during Dynamic Address Assignment process. + (+) TgtHotJoinCallback : callback for Target Hotjoin completion process. + [..] + By default, after the HAL_I3C_Init() and when the state is HAL_I3C_STATE_RESET + all callbacks are set to the corresponding weak functions: + examples HAL_I3C_CtrlTxCpltCallback(), HAL_I3C_CtrlRxCpltCallback(). + Exception done for MspInit and MspDeInit functions that are + reset to the legacy weak functions in the HAL_I3C_Init()/ HAL_I3C_DeInit() only when + these callbacks are null (not registered beforehand). + If MspInit or MspDeInit are not null, the HAL_I3C_Init()/ HAL_I3C_DeInit() + keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state. + [..] + Callbacks can be registered/unregistered in HAL_I3C_STATE_READY state only. + Exception done MspInit/MspDeInit functions that can be registered/unregistered + in HAL_I3C_STATE_READY or HAL_I3C_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_I3C_RegisterCallback() before calling HAL_I3C_DeInit() + or HAL_I3C_Init() function. + [..] + When the compilation flag USE_HAL_I3C_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. + + [..] + (@) You can refer to the I3C HAL driver header file for more useful macros + + @endverbatim + ********************************************************************************************************************** + */ + +/* Includes ----------------------------------------------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup I3C I3C + * @brief I3C HAL module driver + * @{ + */ + +#ifdef HAL_I3C_MODULE_ENABLED + +/* Private typedef ---------------------------------------------------------------------------------------------------*/ +/* Private define ----------------------------------------------------------------------------------------------------*/ +/** @defgroup I3C_Private_Define I3C Private Define + * @{ + */ + +/* Private define to centralize the enable/disable of Interrupts */ +#define I3C_XFER_LISTEN_IT (0x00000001U) +#define I3C_XFER_TARGET_TX_IT (0x00000002U) +#define I3C_XFER_TARGET_RX_IT (0x00000004U) +#define I3C_XFER_DMA (0x00000008U) +#define I3C_XFER_TARGET_CTRLROLE (0x00000010U) +#define I3C_XFER_TARGET_HOTJOIN (0x00000020U) +#define I3C_XFER_TARGET_IBI (0x00000040U) +#define I3C_XFER_CONTROLLER_TX_IT (0x00000080U) +#define I3C_XFER_CONTROLLER_RX_IT (0x00000100U) +#define I3C_XFER_CONTROLLER_RX_CCC_IT (0x00000400U) +#define I3C_XFER_CONTROLLER_DAA_IT (0x00001000U) + +/* Private defines for control buffer prior preparation */ +#define I3C_OPERATION_TYPE_MASK (0x78000000U) +#define I3C_RESTART_STOP_MASK (0x80000000U) +#define I3C_ARBITRATION_HEADER_MASK (0x00000004U) +#define I3C_DEFINE_BYTE_MASK (0x00000001U) + +/* Private define for CCC command */ +#define I3C_BROADCAST_RSTDAA (0x00000006U) +#define I3C_BROADCAST_ENTDAA (0x00000007U) + +/** + * @} + */ + +/* Private macro -----------------------------------------------------------------------------------------------------*/ +/* Private variables -------------------------------------------------------------------------------------------------*/ +/** @addtogroup I3C_Private_Variables + * @{ + */ +/* Structure containing address device and message type used for the private function I3C_Ctrl_IsDevice_Ready() */ +typedef struct +{ + uint8_t Address; /* Dynamic or Static target Address */ + uint32_t MessageType; /* Message Type */ + +} I3C_DeviceTypeDef; +/** + * @} + */ + +/* Private function prototypes ---------------------------------------------------------------------------------------*/ +/** @addtogroup I3C_Private_Functions + * @{ + */ +static HAL_StatusTypeDef I3C_Tgt_Event_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources); +static HAL_StatusTypeDef I3C_Ctrl_Event_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources); +static HAL_StatusTypeDef I3C_Tgt_Tx_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources); +static HAL_StatusTypeDef I3C_Tgt_Rx_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources); +#if defined(HAL_DMA_MODULE_ENABLED) +static HAL_StatusTypeDef I3C_Tgt_Tx_DMA_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources); +static HAL_StatusTypeDef I3C_Tgt_Rx_DMA_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources); +#endif /* HAL_DMA_MODULE_ENABLED */ +static HAL_StatusTypeDef I3C_Tgt_HotJoin_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources); +static HAL_StatusTypeDef I3C_Tgt_CtrlRole_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources); +static HAL_StatusTypeDef I3C_Tgt_IBI_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources); +static HAL_StatusTypeDef I3C_Ctrl_Tx_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources); +static HAL_StatusTypeDef I3C_Ctrl_Rx_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources); +static HAL_StatusTypeDef I3C_Ctrl_Multiple_Xfer_ISR(struct __I3C_HandleTypeDef *hi3c, + uint32_t itFlags, + uint32_t itSources); +#if defined(HAL_DMA_MODULE_ENABLED) +static HAL_StatusTypeDef I3C_Ctrl_Tx_DMA_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources); +static HAL_StatusTypeDef I3C_Ctrl_Rx_DMA_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources); +static HAL_StatusTypeDef I3C_Ctrl_Multiple_Xfer_DMA_ISR(struct __I3C_HandleTypeDef *hi3c, + uint32_t itFlags, + uint32_t itSources); +#endif /* HAL_DMA_MODULE_ENABLED */ +static HAL_StatusTypeDef I3C_Ctrl_DAA_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources); +static HAL_StatusTypeDef I3C_Abort_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources); +static HAL_StatusTypeDef I3C_WaitOnDAAUntilTimeout(I3C_HandleTypeDef *hi3c, uint32_t timeout, uint32_t tickstart); +static HAL_StatusTypeDef I3C_WaitOnFlagUntilTimeout(I3C_HandleTypeDef *hi3c, uint32_t flag, FlagStatus flagstatus, + uint32_t timeout, uint32_t tickstart); +static void I3C_TransmitByteTreatment(I3C_HandleTypeDef *hi3c); +static void I3C_TransmitWordTreatment(I3C_HandleTypeDef *hi3c); +static void I3C_ReceiveByteTreatment(I3C_HandleTypeDef *hi3c); +static void I3C_ReceiveWordTreatment(I3C_HandleTypeDef *hi3c); +static void I3C_ControlDataTreatment(I3C_HandleTypeDef *hi3c); +static void I3C_ErrorTreatment(I3C_HandleTypeDef *hi3c); +static void I3C_GetErrorSources(I3C_HandleTypeDef *hi3c); +static void I3C_StateUpdate(I3C_HandleTypeDef *hi3c); +#if defined(HAL_DMA_MODULE_ENABLED) +static void I3C_DMAAbort(DMA_HandleTypeDef *hdma); +static void I3C_DMAControlTransmitCplt(DMA_HandleTypeDef *hdma); +static void I3C_DMADataTransmitCplt(DMA_HandleTypeDef *hdma); +static void I3C_DMADataReceiveCplt(DMA_HandleTypeDef *hdma); +static void I3C_DMAError(DMA_HandleTypeDef *hdma); +#endif /* HAL_DMA_MODULE_ENABLED */ +static void I3C_Enable_IRQ(I3C_HandleTypeDef *hi3c, uint32_t InterruptRequest); +static void I3C_Disable_IRQ(I3C_HandleTypeDef *hi3c, uint32_t InterruptRequest); +static HAL_StatusTypeDef I3C_Xfer_PriorPreparation(I3C_HandleTypeDef *hi3c, uint8_t counter, uint32_t option); +static uint32_t I3C_FillTxBuffer_CCC(I3C_HandleTypeDef *hi3c, + uint32_t indexDesc, + uint32_t txSize, + uint32_t txCurrentIndex); +static uint32_t I3C_FillTxBuffer_Private(I3C_HandleTypeDef *hi3c, + uint32_t indexDesc, + uint32_t txSize, + uint32_t txCurrentIndex); +static HAL_StatusTypeDef I3C_ControlBuffer_PriorPreparation(I3C_HandleTypeDef *hi3c, + uint8_t counter, + uint32_t option); +static HAL_StatusTypeDef I3C_Ctrl_IsDevice_Ready(I3C_HandleTypeDef *hi3c, + const I3C_DeviceTypeDef *pDevice, + uint32_t trials, + uint32_t timeout); +static void I3C_TreatErrorCallback(I3C_HandleTypeDef *hi3c); +/** + * @} + */ + +/* Exported functions ------------------------------------------------------------------------------------------------*/ +/** @addtogroup I3C_Exported_Functions I3C Exported Functions + * @{ + */ + +/** @defgroup I3C_Exported_Functions_Group1 Initialization and de-initialization functions. + * @brief I3C initialization and de-initialization functions + * +@verbatim + ======================================================================================================================= + ##### Initialization and de-initialization functions ##### + ======================================================================================================================= + [..] This subsection provides a set of functions allowing to initialize and deinitialize the I3Cx peripheral: + + (+) Users must implement HAL_I3C_MspInit() function in which they configure all related peripherals + resources (APB and Kernel CLOCK, GPIO, DMA, IT and NVIC). + + (+) Call the function HAL_I3C_Init() to configure the bus characteristic depends on the device mode + with the selected configuration below: + + (++) Controller mode, Serial source clock wave form configuration: + (+++) SCL push pull low duration + (+++) SCL I3C high duration + (+++) SCL open drain low duration + (+++) SCL I2C high duration + + (++) Controller mode, Bus timing configuration: + (+++) SDA hold time + (+++) Wait time + (+++) Bus free duration + (+++) Bus available duration + + (++) Target mode, Bus timing configuration: + (+++) Bus available duration + + (+) Call the function HAL_I3C_DeInit() to restore the default configuration of the selected I3Cx peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the I3C instance by activating the low-level hardware and configuring the bus + * characteristic according to the specified parameters in the I3C_InitTypeDef. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Init(I3C_HandleTypeDef *hi3c) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t waveform_value; + uint32_t timing_value; + + /* Check the I3C handle allocation */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Check the I3C state */ + if (hi3c->State == HAL_I3C_STATE_RESET) + { +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + /* Init the I3C Callback settings */ + /* Legacy weak CtrlTxCpltCallback */ + hi3c->CtrlTxCpltCallback = HAL_I3C_CtrlTxCpltCallback; + /* Legacy weak CtrlRxCpltCallback */ + hi3c->CtrlRxCpltCallback = HAL_I3C_CtrlRxCpltCallback; + /* Legacy weak CtrlMultipleXferCpltCallback */ + hi3c->CtrlMultipleXferCpltCallback = HAL_I3C_CtrlMultipleXferCpltCallback; + /* Legacy weak CtrlDAACpltCallback */ + hi3c->CtrlDAACpltCallback = HAL_I3C_CtrlDAACpltCallback; + /* Legacy weak TgtReqDynamicAddrCallback */ + hi3c->TgtReqDynamicAddrCallback = HAL_I3C_TgtReqDynamicAddrCallback; + /* Legacy weak TgtTxCpltCallback */ + hi3c->TgtTxCpltCallback = HAL_I3C_TgtTxCpltCallback; + /* Legacy weak TgtRxCpltCallback */ + hi3c->TgtRxCpltCallback = HAL_I3C_TgtRxCpltCallback; + /* Legacy weak TgtHotJoinCallback */ + hi3c->TgtHotJoinCallback = HAL_I3C_TgtHotJoinCallback; + /* Legacy weak NotifyCallback */ + hi3c->NotifyCallback = HAL_I3C_NotifyCallback; + /* Legacy weak ErrorCallback */ + hi3c->ErrorCallback = HAL_I3C_ErrorCallback; + /* Legacy weak AbortCpltCallback */ + hi3c->AbortCpltCallback = HAL_I3C_AbortCpltCallback; + + /* Check on the MSP init callback */ + if (hi3c->MspInitCallback == NULL) + { + /* Legacy weak MspInit */ + hi3c->MspInitCallback = HAL_I3C_MspInit; + } + + /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ + hi3c->MspInitCallback(hi3c); +#else + /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ + HAL_I3C_MspInit(hi3c); + +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS */ + } + + /* Update the I3C state to busy */ + hi3c->State = HAL_I3C_STATE_BUSY; + + /* Disable the selected I3C peripheral */ + LL_I3C_Disable(hi3c->Instance); + + /* Check on the I3C mode: initialization depends on the mode */ + if (hi3c->Mode == HAL_I3C_MODE_CONTROLLER) + { + /* Check the parameters */ + assert_param(IS_I3C_SDAHOLDTIME_VALUE(hi3c->Init.CtrlBusCharacteristic.SDAHoldTime)); + assert_param(IS_I3C_WAITTIME_VALUE(hi3c->Init.CtrlBusCharacteristic.WaitTime)); + + /* Set Controller mode */ + LL_I3C_SetMode(hi3c->Instance, LL_I3C_MODE_CONTROLLER); + + /*----------------- SCL signal waveform configuration : I3C timing register 0 (I3C_TIMINGR0) ------------------ */ + /* Set the controller SCL waveform */ + waveform_value = ((uint32_t)hi3c->Init.CtrlBusCharacteristic.SCLPPLowDuration | + ((uint32_t)hi3c->Init.CtrlBusCharacteristic.SCLI3CHighDuration << I3C_TIMINGR0_SCLH_I3C_Pos) | + ((uint32_t)hi3c->Init.CtrlBusCharacteristic.SCLODLowDuration << I3C_TIMINGR0_SCLL_OD_Pos) | + ((uint32_t)hi3c->Init.CtrlBusCharacteristic.SCLI2CHighDuration << I3C_TIMINGR0_SCLH_I2C_Pos)); + + LL_I3C_ConfigClockWaveForm(hi3c->Instance, waveform_value); + + /*------------------ Timing configuration : I3C timing register 1 (I3C_TIMINGR1) ------------------------------ */ + /* Set SDA hold time, activity state, bus free duration and bus available duration */ + timing_value = ((uint32_t)hi3c->Init.CtrlBusCharacteristic.SDAHoldTime | + (uint32_t)hi3c->Init.CtrlBusCharacteristic.WaitTime | + ((uint32_t)hi3c->Init.CtrlBusCharacteristic.BusFreeDuration << I3C_TIMINGR1_FREE_Pos) | + (uint32_t)hi3c->Init.CtrlBusCharacteristic.BusIdleDuration); + + LL_I3C_SetCtrlBusCharacteristic(hi3c->Instance, timing_value); + } + else + { + /* Set target mode */ + LL_I3C_SetMode(hi3c->Instance, LL_I3C_MODE_TARGET); + + /*------------------ Timing configuration : I3C timing register 1 (I3C_TIMINGR1) ------------------------------ */ + /* Set the number of kernel clocks cycles for the bus available condition time */ + LL_I3C_SetAvalTiming(hi3c->Instance, hi3c->Init.TgtBusCharacteristic.BusAvailableDuration); + } + + /* Enable the selected I3C peripheral */ + LL_I3C_Enable(hi3c->Instance); + + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + + /* Update I3C state */ + hi3c->State = HAL_I3C_STATE_READY; + hi3c->PreviousState = HAL_I3C_STATE_READY; + } + + return status; +} + +/** + * @brief DeInitialize the I3C peripheral. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_DeInit(I3C_HandleTypeDef *hi3c) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the I3C handle allocation */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + + /* Update the I3C state to busy */ + hi3c->State = HAL_I3C_STATE_BUSY; + + /* Disable the selected I3C peripheral */ + LL_I3C_Disable(hi3c->Instance); + +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + /* Check on the MSP init callback */ + if (hi3c->MspDeInitCallback == NULL) + { + /* Legacy weak MspDeInit */ + hi3c->MspDeInitCallback = HAL_I3C_MspDeInit; + } + + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + hi3c->MspDeInitCallback(hi3c); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + HAL_I3C_MspDeInit(hi3c); + +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS */ + + /* Update the I3C Error code, state and mode */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_RESET; + hi3c->PreviousState = HAL_I3C_STATE_RESET; + hi3c->Mode = HAL_I3C_MODE_NONE; + } + + return status; +} + +/** + * @brief Initialize the I3C MSP. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @retval None + */ +__weak void HAL_I3C_MspInit(I3C_HandleTypeDef *hi3c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi3c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I3C_MspInit could be implemented in the user file */ +} + +/** + * @brief DeInitialize the I3C MSP. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @retval None + */ +__weak void HAL_I3C_MspDeInit(I3C_HandleTypeDef *hi3c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi3c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I3C_MspDeInit could be implemented in the user file */ +} +/** + * @} + */ + +/** @defgroup I3C_Exported_Functions_Group2 Interrupt and callback functions. + * @brief I3C interrupt and callback functions. + * +@verbatim + ======================================================================================================================= + ##### Interrupt and callback functions ##### + ======================================================================================================================= + [..] This subsection provides a set of functions allowing to manage callbacks and interrupts request: + + (+) Register/Unregister callback function: + (++) Call the function HAL_I3C_RegisterCallback() to register an I3C user callback. + (++) Call the function HAL_I3C_RegisterNotifyCallback() to register an I3C user notification callback. + (++) Call the function HAL_I3C_RegisterDynamicAddrCallback() to register an I3C user address callback. + (++) Call the function HAL_I3C_RegisterHotJoinCallback() to register an I3C user hot join callback. + (++) Call the function HAL_I3C_UnRegisterCallback() to unregister an I3C user callback. + + (+) Notification management function: + (++) Call the function HAL_I3C_ActivateNotification() to activate the I3C notifications. + (++) Call the function HAL_I3C_DeactivateNotification() to deactivate the I3C notifications. + + (+) Controller callback functions: + (++) Users must implement HAL_I3C_CtrlTxCpltCallback() function when the transmission of private data or + Tx CCC transfer is completed. + (++) Users must implement HAL_I3C_CtrlRxCpltCallback() function when the reception of private data or + Rx CCC transfer is completed. + (++) Users must implement HAL_I3C_CtrlMultipleXferCpltCallback() function when the multiple + transfer of CCC, I3C private or I2C transfer is completed. + (++) Users must implement HAL_I3C_CtrlDAACpltCallback() function when Dynamic Address Assignment + procedure is completed. + (++) Users must implement HAL_I3C_TgtReqDynamicAddrCallback() function in the controller application + when a target sent its payload to the controller during Dynamic Address Assignment procedure. + + (+) Target callback functions: + (++) Users must implement HAL_I3C_TgtTxCpltCallback() function when the transmission of private + data is completed. + (++) Users must implement HAL_I3C_TgtRxCpltCallback() function when the reception of private + data is completed. + (++) Users must implement HAL_I3C_TgtHotJoinCallback() function when a target hot join process + is completed. + + (+) Common callback functions: + (++) Users must implement HAL_I3C_NotifyCallback() function when the device receives + an asynchronous event like IBI, a Hot-join, CCC command for target... + (++) Users must implement HAL_I3C_AbortCpltCallback() function when an abort process is completed. + (++) Users must implement HAL_I3C_ErrorCallback() function when an error is occurred. + + (+) Interrupt and event function: + (++) Call the function HAL_I3C_ER_IRQHandler() in the ISR file to handle I3C error interrupts request. + (++) Call the function HAL_I3C_EV_IRQHandler() in the ISR file to handle I3C event interrupts request. +@endverbatim + * @{ + */ + +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) +/** + * @brief Register a User I3C Callback to be used instead of the weak predefined callback. + * @note The HAL_I3C_RegisterCallback() may be called before HAL_I3C_Init() in HAL_I3C_STATE_RESET + * to register callbacks for HAL_I3C_MSPINIT_CB_ID and HAL_I3C_MSPDEINIT_CB_ID + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param callbackID : [IN] ID of the callback to be registered. + * This parameter can be one of the following values: + * @arg @ref HAL_I3C_CTRL_TX_COMPLETE_CB_ID + * @arg @ref HAL_I3C_CTRL_RX_COMPLETE_CB_ID + * @arg @ref HAL_I3C_CTRL_MULTIPLE_XFER_COMPLETE_CB_ID + * @arg @ref HAL_I3C_CTRL_DAA_COMPLETE_CB_ID + * @arg @ref HAL_I3C_TGT_TX_COMPLETE_CB_ID + * @arg @ref HAL_I3C_TGT_RX_COMPLETE_CB_ID + * @arg @ref HAL_I3C_ERROR_CB_ID + * @arg @ref HAL_I3C_ABORT_CB_ID + * @arg @ref HAL_I3C_MSPINIT_CB_ID + * @arg @ref HAL_I3C_MSPDEINIT_CB_ID + * @param pCallback : [IN] Pointer to the Callback function. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_RegisterCallback(I3C_HandleTypeDef *hi3c, + HAL_I3C_CallbackIDTypeDef callbackID, + pI3C_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the I3C handle allocation */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the user callback allocation */ + if (pCallback == NULL) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + else if (HAL_I3C_STATE_READY == hi3c->State) + { + switch (callbackID) + { + case HAL_I3C_CTRL_TX_COMPLETE_CB_ID : + hi3c->CtrlTxCpltCallback = pCallback; + break; + + case HAL_I3C_CTRL_RX_COMPLETE_CB_ID : + hi3c->CtrlRxCpltCallback = pCallback; + break; + + case HAL_I3C_CTRL_MULTIPLE_XFER_COMPLETE_CB_ID : + hi3c->CtrlMultipleXferCpltCallback = pCallback; + break; + + case HAL_I3C_CTRL_DAA_COMPLETE_CB_ID : + hi3c->CtrlDAACpltCallback = pCallback; + break; + + case HAL_I3C_TGT_TX_COMPLETE_CB_ID : + hi3c->TgtTxCpltCallback = pCallback; + break; + + case HAL_I3C_TGT_RX_COMPLETE_CB_ID : + hi3c->TgtRxCpltCallback = pCallback; + break; + + case HAL_I3C_ERROR_CB_ID : + hi3c->ErrorCallback = pCallback; + break; + + case HAL_I3C_ABORT_CB_ID : + hi3c->AbortCpltCallback = pCallback; + break; + + case HAL_I3C_MSPINIT_CB_ID : + hi3c->MspInitCallback = pCallback; + break; + + case HAL_I3C_MSPDEINIT_CB_ID : + hi3c->MspDeInitCallback = pCallback; + break; + + default : + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_CALLBACK; + status = HAL_ERROR; + break; + } + } + else if (HAL_I3C_STATE_RESET == hi3c->State) + { + switch (callbackID) + { + case HAL_I3C_MSPINIT_CB_ID : + hi3c->MspInitCallback = pCallback; + break; + + case HAL_I3C_MSPDEINIT_CB_ID : + hi3c->MspDeInitCallback = pCallback; + break; + + default : + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_CALLBACK; + status = HAL_ERROR; + break; + } + } + else + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + } + + return status; +} + +/** + * @brief Register a User I3C Notify Callback to be used instead of the weak predefined callback. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @param pNotifyCallback : [IN] Pointer to the Callback function. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_RegisterNotifyCallback(I3C_HandleTypeDef *hi3c, pI3C_NotifyCallbackTypeDef pNotifyCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the I3C handle allocation */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the user callback allocation */ + if (pNotifyCallback == NULL) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + else if (HAL_I3C_STATE_READY == hi3c->State) + { + hi3c->NotifyCallback = pNotifyCallback; + } + else + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + } + + return status; +} + +/** + * @brief Register a User I3C dynamic address Callback to be used instead of the weak predefined callback. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @param pTgtReqAddrCallback : [IN] Pointer to the Callback function. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_RegisterTgtReqDynamicAddrCallback(I3C_HandleTypeDef *hi3c, + pI3C_TgtReqDynamicAddrCallbackTypeDef pTgtReqAddrCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the I3C handle allocation */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the user callback allocation */ + if (pTgtReqAddrCallback == NULL) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + else if (HAL_I3C_STATE_READY == hi3c->State) + { + hi3c->TgtReqDynamicAddrCallback = pTgtReqAddrCallback; + } + else + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + } + + return status; +} + +/** + * @brief Register a User I3C hot join Callback to be used instead of the weak predefined callback. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @param pTgtHotJoinCallback : [IN] Pointer to the Callback function. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_RegisterTgtHotJoinCallback(I3C_HandleTypeDef *hi3c, + pI3C_TgtHotJoinCallbackTypeDef pTgtHotJoinCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the I3C handle allocation */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the user callback allocation */ + if (pTgtHotJoinCallback == NULL) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + else if (HAL_I3C_STATE_READY == hi3c->State) + { + hi3c->TgtHotJoinCallback = pTgtHotJoinCallback; + } + else + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + } + + return status; +} + +/** + * @brief Unregister a user I3C Callback. + * The I3C callback is redirected to the weak predefined callback + * @note The HAL_I3C_UnRegisterCallback() may be called before HAL_I3C_Init() in HAL_I3C_STATE_RESET + * to un-register callbacks for HAL_I3C_MSPINIT_CB_ID and HAL_I3C_MSPDEINIT_CB_ID + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param callbackID : [IN] ID of the callback to be unregistered. + * This parameter can be one of the following values: + * @arg @ref HAL_I3C_CTRL_TX_COMPLETE_CB_ID + * @arg @ref HAL_I3C_CTRL_RX_COMPLETE_CB_ID + * @arg @ref HAL_I3C_CTRL_MULTIPLE_XFER_COMPLETE_CB_ID + * @arg @ref HAL_I3C_CTRL_DAA_COMPLETE_CB_ID + * @arg @ref HAL_I3C_TGT_REQ_DYNAMIC_ADDR_CB_ID + * @arg @ref HAL_I3C_TGT_TX_COMPLETE_CB_ID + * @arg @ref HAL_I3C_TGT_RX_COMPLETE_CB_ID + * @arg @ref HAL_I3C_TGT_HOTJOIN_CB_ID + * @arg @ref HAL_I3C_NOTIFY_CB_ID + * @arg @ref HAL_I3C_ERROR_CB_ID + * @arg @ref HAL_I3C_ABORT_CB_ID + * @arg @ref HAL_I3C_MSPINIT_CB_ID + * @arg @ref HAL_I3C_MSPDEINIT_CB_ID + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_UnRegisterCallback(I3C_HandleTypeDef *hi3c, HAL_I3C_CallbackIDTypeDef callbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the I3C handle allocation */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + if (HAL_I3C_STATE_READY == hi3c->State) + { + switch (callbackID) + { + case HAL_I3C_CTRL_TX_COMPLETE_CB_ID : + /* Legacy weak CtrlTxCpltCallback */ + hi3c->CtrlTxCpltCallback = HAL_I3C_CtrlTxCpltCallback; + break; + + case HAL_I3C_CTRL_RX_COMPLETE_CB_ID : + /* Legacy weak CtrlRxCpltCallback */ + hi3c->CtrlRxCpltCallback = HAL_I3C_CtrlRxCpltCallback; + break; + + case HAL_I3C_CTRL_MULTIPLE_XFER_COMPLETE_CB_ID : + /* Legacy weak CtrlMultipleXferCpltCallback */ + hi3c->CtrlMultipleXferCpltCallback = HAL_I3C_CtrlMultipleXferCpltCallback; + break; + + case HAL_I3C_CTRL_DAA_COMPLETE_CB_ID : + /* Legacy weak CtrlDAACpltCallback */ + hi3c->CtrlDAACpltCallback = HAL_I3C_CtrlDAACpltCallback; + break; + + case HAL_I3C_TGT_REQ_DYNAMIC_ADDR_CB_ID : + /*Legacy weak TgtReqDynamicAddrCallback */ + hi3c->TgtReqDynamicAddrCallback = HAL_I3C_TgtReqDynamicAddrCallback; + break; + + case HAL_I3C_TGT_TX_COMPLETE_CB_ID : + /* Legacy weak TgtTxCpltCallback */ + hi3c->TgtTxCpltCallback = HAL_I3C_TgtTxCpltCallback; + break; + + case HAL_I3C_TGT_RX_COMPLETE_CB_ID : + /* Legacy weak TgtRxCpltCallback */ + hi3c->TgtRxCpltCallback = HAL_I3C_TgtRxCpltCallback; + break; + + case HAL_I3C_TGT_HOTJOIN_CB_ID : + /* Legacy weak TgtHotJoinCallback */ + hi3c->TgtHotJoinCallback = HAL_I3C_TgtHotJoinCallback; + break; + + case HAL_I3C_NOTIFY_CB_ID : + /* Legacy weak NotifyCallback */ + hi3c->NotifyCallback = HAL_I3C_NotifyCallback; + break; + + case HAL_I3C_ERROR_CB_ID : + /* Legacy weak ErrorCallback */ + hi3c->ErrorCallback = HAL_I3C_ErrorCallback; + break; + + case HAL_I3C_ABORT_CB_ID : + /* Legacy weak AbortCpltCallback */ + hi3c->AbortCpltCallback = HAL_I3C_AbortCpltCallback; + break; + + case HAL_I3C_MSPINIT_CB_ID : + /* Legacy weak MspInit */ + hi3c->MspInitCallback = HAL_I3C_MspInit; + break; + + case HAL_I3C_MSPDEINIT_CB_ID : + /* Legacy weak MspDeInit */ + hi3c->MspDeInitCallback = HAL_I3C_MspDeInit; + break; + + default : + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_CALLBACK; + status = HAL_ERROR; + break; + } + } + else if (HAL_I3C_STATE_RESET == hi3c->State) + { + switch (callbackID) + { + case HAL_I3C_MSPINIT_CB_ID : + /* Legacy weak MspInit */ + hi3c->MspInitCallback = HAL_I3C_MspInit; + break; + + case HAL_I3C_MSPDEINIT_CB_ID : + /* Legacy weak MspDeInit */ + hi3c->MspDeInitCallback = HAL_I3C_MspDeInit; + break; + + default : + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_CALLBACK; + status = HAL_ERROR; + break; + } + } + else + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + } + + return status; +} +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + +/** + * @brief This function permits to activate the I3C notifications. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @param pXferData : [IN/OUT] Pointer to an I3C_XferTypeDef structure that contains the reception buffer to + * retrieve data during broadcast CCC DEFTGTS and DEFGRPA when Target mode only. + * @param interruptMask : [IN] Parameter indicates which interrupts will be enabled. + * This parameter can be any combination of @arg I3C_TARGET_INTERRUPT when + * the I3C is in target mode or a combination of @arg I3C_CONTROLLER_INTERRUPT + * when it is in controller mode. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_ActivateNotification(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData, + uint32_t interruptMask) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + assert_param(IS_I3C_INTERRUPTMASK(hi3c->Mode, interruptMask)); + + /* Check the I3C state and mode */ + if ((hi3c->State == HAL_I3C_STATE_RESET) || + ((hi3c->Mode != HAL_I3C_MODE_CONTROLLER) && (hi3c->Mode != HAL_I3C_MODE_TARGET))) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* Check the I3C mode */ + else if ((hi3c->Mode == HAL_I3C_MODE_TARGET) && + ((interruptMask & (HAL_I3C_IT_DEFIE | HAL_I3C_IT_GRPIE)) != 0U) && + (pXferData == NULL)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + else + { + /* Check the I3C mode */ + if (hi3c->Mode == HAL_I3C_MODE_TARGET) + { + if ((interruptMask & (HAL_I3C_IT_DEFIE | HAL_I3C_IT_GRPIE)) != 0U) + { + hi3c->pXferData = pXferData; + hi3c->RxXferCount = hi3c->pXferData->RxBuf.Size; + + /* Check on the Rx threshold to know the Rx treatment process : byte or word */ + if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4) + { + /* Set byte treatment function pointer */ + hi3c->ptrRxFunc = &I3C_ReceiveByteTreatment; + } + else + { + /* Set word treatment function pointer */ + hi3c->ptrRxFunc = &I3C_ReceiveWordTreatment; + } + } + /* Store the target event treatment function */ + hi3c->XferISR = I3C_Tgt_Event_ISR; + } + else + { + /* Store the controller event treatment function */ + hi3c->XferISR = I3C_Ctrl_Event_ISR; + } + + /* Update handle parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_LISTEN; + hi3c->PreviousState = HAL_I3C_STATE_LISTEN; + + /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk + of I3C interrupt handle execution before current process unlock */ + /* Enable selected notifications */ + I3C_Enable_IRQ(hi3c, (interruptMask | I3C_XFER_LISTEN_IT)); + } + } + + return status; +} + +/** + * @brief This function permits to deactivate the I3C notifications. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @param interruptMask : [IN] Parameter indicates which interrupts will be disabled. + * This parameter can be any combination of @arg I3C_TARGET_INTERRUPT when + * the I3C is in target mode or a combination of @arg I3C_CONTROLLER_INTERRUPT + * when it is in controller mode. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_DeactivateNotification(I3C_HandleTypeDef *hi3c, uint32_t interruptMask) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance parameter */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + + /* Check on the State */ + if (hi3c->State == HAL_I3C_STATE_RESET) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + else + { + /* Disable selected notifications */ + I3C_Disable_IRQ(hi3c, (interruptMask | I3C_XFER_LISTEN_IT)); + + if (READ_REG(hi3c->Instance->IER) == 0U) + { + /* Update the XferISR pointer */ + hi3c->XferISR = NULL; + + /* Update I3C state */ + hi3c->State = HAL_I3C_STATE_READY; + hi3c->PreviousState = HAL_I3C_STATE_READY; + } + } + } + + return status; +} + +/** + * @brief Controller Transmission Complete callback. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @retval None + */ +__weak void HAL_I3C_CtrlTxCpltCallback(I3C_HandleTypeDef *hi3c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi3c); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I3C_CtrlTxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Controller Reception Complete callback. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @retval None + */ +__weak void HAL_I3C_CtrlRxCpltCallback(I3C_HandleTypeDef *hi3c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi3c); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I3C_CtrlRxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Controller multiple Direct CCC Command, I3C private or I2C transfer Complete callback. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @retval None + */ +__weak void HAL_I3C_CtrlMultipleXferCpltCallback(I3C_HandleTypeDef *hi3c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi3c); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I3C_CtrlMultipleXferCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Controller dynamic address assignment Complete callback. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @retval None + */ +__weak void HAL_I3C_CtrlDAACpltCallback(I3C_HandleTypeDef *hi3c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi3c); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I3C_CtrlDAACpltCallback could be implemented in the user file + */ +} + +/** + * @brief Target Request Dynamic Address callback. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param targetPayload : [IN] Parameter indicates the target payload. + * @retval None + */ +__weak void HAL_I3C_TgtReqDynamicAddrCallback(I3C_HandleTypeDef *hi3c, uint64_t targetPayload) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi3c); + UNUSED(targetPayload); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I3C_TgtReqDynamicAddrCallback could be implemented in the user file + */ +} + +/** + * @brief Target Transmission Complete callback. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @retval None + */ +__weak void HAL_I3C_TgtTxCpltCallback(I3C_HandleTypeDef *hi3c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi3c); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I3C_TgtTxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Target Reception Complete callback. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @retval None + */ +__weak void HAL_I3C_TgtRxCpltCallback(I3C_HandleTypeDef *hi3c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi3c); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I3C_TgtRxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Target Hot join process Complete callback. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @param dynamicAddress : [IN] The returned dynamic address value after the hot join process. + * @retval None + */ +__weak void HAL_I3C_TgtHotJoinCallback(I3C_HandleTypeDef *hi3c, uint8_t dynamicAddress) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi3c); + UNUSED(dynamicAddress); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I3C_TgtHotJoinCallback could be implemented in the user file + */ +} + +/** + * @brief Target/Controller Notification event callback. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param eventId : [IN] Parameter indicates which notification is signaled. + * It can be a combination value of @ref HAL_I3C_Notification_ID_definition. + * @retval None + */ +__weak void HAL_I3C_NotifyCallback(I3C_HandleTypeDef *hi3c, uint32_t eventId) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi3c); + UNUSED(eventId); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I3C_NotifyCallback could be implemented in the user file + */ +} + +/** + * @brief Abort complete callback. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @retval None + */ +__weak void HAL_I3C_AbortCpltCallback(I3C_HandleTypeDef *hi3c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi3c); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I3C_AbortCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Error callback. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @retval None + */ +__weak void HAL_I3C_ErrorCallback(I3C_HandleTypeDef *hi3c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi3c); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I3C_ErrorCallback could be implemented in the user file + */ +} + +/** + * @brief This function handles I3C error interrupt request. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @retval None + */ +void HAL_I3C_ER_IRQHandler(I3C_HandleTypeDef *hi3c) +{ + uint32_t it_flag = READ_REG(hi3c->Instance->EVR); + uint32_t it_source = READ_REG(hi3c->Instance->IER); + + /* Check on the error interrupt flag and source */ + if ((I3C_CHECK_FLAG(it_flag, HAL_I3C_FLAG_ERRF) != RESET) && + (I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_ERRIE) != RESET)) + { + /* Clear the error flag */ + LL_I3C_ClearFlag_ERR(hi3c->Instance); + + if (hi3c->State != HAL_I3C_STATE_ABORT) + { + /* Get error sources */ + I3C_GetErrorSources(hi3c); + } + + /* Errors treatment */ + I3C_ErrorTreatment(hi3c); + } +} + +/** + * @brief This function handles I3C event interrupt request. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @retval None + */ +void HAL_I3C_EV_IRQHandler(I3C_HandleTypeDef *hi3c) /* Derogation MISRAC2012-Rule-8.13 */ +{ + uint32_t it_flags = READ_REG(hi3c->Instance->EVR); + uint32_t it_sources = READ_REG(hi3c->Instance->IER); + + /* I3C events treatment */ + if (hi3c->XferISR != NULL) + { + hi3c->XferISR(hi3c, it_flags, it_sources); + } +} +/** + * @} + */ + +/** @defgroup I3C_Exported_Functions_Group3 Configuration functions. + * @brief I3C configuration functions. + * +@verbatim + ======================================================================================================================= + ##### Configuration functions ##### + ======================================================================================================================= + [..] This subsection provides a set of functions allowing to configure the I3C instances. + + (+) Call the function HAL_I3C_Ctrl_BusCharacteristicConfig() to modify the controller Bus Characteristics + after initialize the bus through HAL_I3C_Init. + + (+) Call the function HAL_I3C_Tgt_BusCharacteristicConfig() to modify the target Bus Characteristics + after initialize the bus through HAL_I3C_Init. + + (+) Call the function HAL_I3C_SetConfigFifo() to set FIFOs configuration (enabled FIFOs and + threshold level) with the selected parameters in the configuration structure I3C_FifoConfTypeDef. + + (+) Call the function HAL_I3C_Ctrl_Config() to configure the I3C Controller instances with the selected + parameters in the configuration structure I3C_CtrlConfTypeDef. + This function is called only when mode is Controller. + + (+) Call the function HAL_I3C_Tgt_Config() to configure the I3C Target instances with the selected + parameters in the configuration structure I3C_TgtConfTypeDef. + This function is called only when mode is Target. + + (+) Call the function HAL_I3C_Ctrl_ConfigBusDevices() to configure Hardware device characteristics register + with Devices capabilities present on the Bus. + All different characteristics must be fill through structure I3C_DeviceConfTypeDef. + This function is called only when mode is Controller. + + (+) Call the function HAL_I3C_AddDescToFrame() to prepare the full transfer usecase in a transfer descriptor + which contained different buffer pointers and their associated size through I3C_XferTypeDef. + This function must be called before initiate any communication transfer. + [..] + (@) Users must call all above functions after I3C initialization. + +@endverbatim + * @{ + */ + +/** + * @brief Configure the Controller Bus characterics. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param pConfig : [IN] Pointer to an LL_I3C_CtrlBusConfTypeDef structure contains controller bus configuration. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Ctrl_BusCharacteristicConfig(I3C_HandleTypeDef *hi3c, + const LL_I3C_CtrlBusConfTypeDef *pConfig) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t waveform_value; + uint32_t timing_value; + + /* Check the I3C handle allocation */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Check on user parameters */ + if (pConfig == NULL) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* Check the I3C state and mode */ + else if ((hi3c->State != HAL_I3C_STATE_READY) || (hi3c->Mode != HAL_I3C_MODE_CONTROLLER)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + else + { + /* Check the parameters */ + assert_param(IS_I3C_SDAHOLDTIME_VALUE(pConfig->SDAHoldTime)); + assert_param(IS_I3C_WAITTIME_VALUE(pConfig->WaitTime)); + + /* Disable the selected I3C peripheral */ + LL_I3C_Disable(hi3c->Instance); + + /*----------------- SCL signal waveform configuration : I3C timing register 0 (I3C_TIMINGR0) ------------------ */ + /* Set the controller SCL waveform */ + waveform_value = ((uint32_t)pConfig->SCLPPLowDuration | + ((uint32_t)pConfig->SCLI3CHighDuration << I3C_TIMINGR0_SCLH_I3C_Pos) | + ((uint32_t)pConfig->SCLODLowDuration << I3C_TIMINGR0_SCLL_OD_Pos) | + ((uint32_t)pConfig->SCLI2CHighDuration << I3C_TIMINGR0_SCLH_I2C_Pos)); + + LL_I3C_ConfigClockWaveForm(hi3c->Instance, waveform_value); + + /*------------------ Timing configuration : I3C timing register 1 (I3C_TIMINGR1) ------------------------------ */ + /* Set SDA hold time, activity state, bus free duration and bus available duration */ + timing_value = ((uint32_t)pConfig->SDAHoldTime | + (uint32_t)pConfig->WaitTime | + ((uint32_t)pConfig->BusFreeDuration << I3C_TIMINGR1_FREE_Pos) | + (uint32_t)pConfig->BusIdleDuration); + + LL_I3C_SetCtrlBusCharacteristic(hi3c->Instance, timing_value); + + /* Enable the selected I3C peripheral */ + LL_I3C_Enable(hi3c->Instance); + } + } + + return status; +} + +/** + * @brief Configure the target Bus characterics. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param pConfig : [IN] Pointer to an LL_I3C_TgtBusConfTypeDef structure contains target bus configuration. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Tgt_BusCharacteristicConfig(I3C_HandleTypeDef *hi3c, + const LL_I3C_TgtBusConfTypeDef *pConfig) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the I3C handle allocation */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check on user parameters */ + if (pConfig == NULL) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Check the I3C state and mode */ + if ((hi3c->State != HAL_I3C_STATE_READY) || (hi3c->Mode != HAL_I3C_MODE_TARGET)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + else + { + /* Disable the selected I3C peripheral */ + LL_I3C_Disable(hi3c->Instance); + + /*------------------ Timing configuration : I3C timing register 1 (I3C_TIMINGR1) ---------------------------- */ + /* Set the number of kernel clocks cycles for the bus available condition time */ + LL_I3C_SetAvalTiming(hi3c->Instance, pConfig->BusAvailableDuration); + + /* Enable the selected I3C peripheral */ + LL_I3C_Enable(hi3c->Instance); + } + } + } + + return status; +} + +/** + * @brief Set I3C FIFOs configuration. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param pConfig : [IN] Pointer to an I3C_FifoConfTypeDef structure contains FIFOs configuration. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_SetConfigFifo(I3C_HandleTypeDef *hi3c, const I3C_FifoConfTypeDef *pConfig) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t cfgr_value; + uint32_t cfgr_mask; + + /* Check the I3C handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check on user parameters */ + if (pConfig == NULL) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* Check the I3C state */ + else if (hi3c->State == HAL_I3C_STATE_RESET) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Check configuration parameters */ + assert_param(IS_I3C_TXFIFOTHRESHOLD_VALUE(pConfig->TxFifoThreshold)); + assert_param(IS_I3C_RXFIFOTHRESHOLD_VALUE(pConfig->RxFifoThreshold)); + + /* Set Tx and Rx Fifo threshold */ + cfgr_value = (pConfig->TxFifoThreshold | pConfig->RxFifoThreshold); + cfgr_mask = (I3C_CFGR_TXTHRES | I3C_CFGR_RXTHRES); + + /* Check on the I3C mode: Control and status FIFOs available only with controller mode */ + if (hi3c->Mode == HAL_I3C_MODE_CONTROLLER) + { + /* Check configuration parameters */ + assert_param(IS_I3C_CONTROLFIFOSTATE_VALUE(pConfig->ControlFifo)); + assert_param(IS_I3C_STATUSFIFOSTATE_VALUE(pConfig->StatusFifo)); + + /* Set Control and Status Fifo states */ + cfgr_value |= (pConfig->StatusFifo | pConfig->ControlFifo); + cfgr_mask |= (I3C_CFGR_TMODE | I3C_CFGR_SMODE); + } + + /* Set configuration in the CFGR register */ + MODIFY_REG(hi3c->Instance->CFGR, cfgr_mask, cfgr_value); + } + } + + return status; +} + +/** + * @brief Set I3C controller configuration. + * @note This function is called only when the I3C instance is initialized as controller. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param pConfig : [IN] Pointer to an I3C_CtrlConfTypeDef structure that contains controller configuration. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Ctrl_Config(I3C_HandleTypeDef *hi3c, const I3C_CtrlConfTypeDef *pConfig) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t timing2_value; + uint32_t cfgr_value; + + /* Check the I3C handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Check on user parameters */ + if (pConfig == NULL) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* Check the I3C state and mode */ + else if ((hi3c->State == HAL_I3C_STATE_RESET) || (hi3c->Mode != HAL_I3C_MODE_CONTROLLER)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + else + { + /* Check configuration parameters values */ + assert_param(IS_I3C_DYNAMICADDRESS_VALUE(pConfig->DynamicAddr)); + assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->HighKeeperSDA)); + assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->HotJoinAllowed)); + assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->ACKStallState)); + assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->CCCStallState)); + assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->TxStallState)); + assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->RxStallState)); + + /* Disable the selected I3C peripheral */ + LL_I3C_Disable(hi3c->Instance); + + /* Calculate value to be written in timing register 2 */ + timing2_value = (((uint32_t)pConfig->StallTime << I3C_TIMINGR2_STALL_Pos) | + ((uint32_t)pConfig->ACKStallState << I3C_TIMINGR2_STALLA_Pos) | + ((uint32_t)pConfig->CCCStallState << I3C_TIMINGR2_STALLC_Pos) | + ((uint32_t)pConfig->TxStallState << I3C_TIMINGR2_STALLD_Pos) | + ((uint32_t)pConfig->RxStallState << I3C_TIMINGR2_STALLT_Pos)); + + /* Set value in timing 2 register */ + WRITE_REG(hi3c->Instance->TIMINGR2, timing2_value); + + /* Calculate value to be written in CFGR register */ + cfgr_value = (((uint32_t)pConfig->HighKeeperSDA << I3C_CFGR_HKSDAEN_Pos) | + ((uint32_t)pConfig->HotJoinAllowed << I3C_CFGR_HJACK_Pos)); + + /* Set hot join acknowledge and high keeper values */ + MODIFY_REG(hi3c->Instance->CFGR, I3C_CFGR_HKSDAEN | I3C_CFGR_HJACK, cfgr_value); + + /* Set dynamic address value */ + LL_I3C_SetOwnDynamicAddress(hi3c->Instance, pConfig->DynamicAddr); + + /* Validate the controller dynamic address */ + LL_I3C_EnableOwnDynAddress(hi3c->Instance); + + /* Enable the selected I3C peripheral */ + LL_I3C_Enable(hi3c->Instance); + } + } + + return status; +} + +/** + * @brief Set I3C target configuration. + * @note This function is called only when the I3C instance is initialized as target. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param pConfig : [IN] Pointer to an I3C_TgtConfTypeDef structure that contains target configuration. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Tgt_Config(I3C_HandleTypeDef *hi3c, const I3C_TgtConfTypeDef *pConfig) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t getmxdsr_value; + uint32_t maxrlr_value; + uint32_t crccapr_value; + uint32_t bcr_value; + uint32_t devr0_value; + + /* Check the I3C handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Check on user parameters */ + if (pConfig == NULL) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* Check the I3C state and mode */ + else if ((hi3c->State == HAL_I3C_STATE_RESET) || (hi3c->Mode != HAL_I3C_MODE_TARGET)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + else + { + /* Check configuration parameters values */ + assert_param(IS_I3C_HANDOFFACTIVITYSTATE_VALUE(pConfig->HandOffActivityState)); + assert_param(IS_I3C_TSCOTIME_VALUE(pConfig->DataTurnAroundDuration)); + assert_param(IS_I3C_MAXSPEEDDATA_VALUE(pConfig->MaxDataSpeed)); + assert_param(IS_I3C_IBIPAYLOADSIZE_VALUE(pConfig->IBIPayloadSize)); + assert_param(IS_I3C_MIPIIDENTIFIER_VALUE(pConfig->MIPIIdentifier)); + assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->HandOffDelay)); + assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->GroupAddrCapability)); + assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->PendingReadMDB)); + assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->IBIPayload)); + assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->MaxSpeedLimitation)); + assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->CtrlCapability)); + assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->IBIRequest)); + assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->CtrlRoleRequest)); + assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pConfig->HotJoinRequest)); + + /* Disable the selected I3C peripheral */ + LL_I3C_Disable(hi3c->Instance); + + /* Calculate value to be written in the GETMXDSR register */ + getmxdsr_value = (pConfig->HandOffActivityState | pConfig->MaxDataSpeed | pConfig->DataTurnAroundDuration | + ((uint32_t)pConfig->MaxReadTurnAround << I3C_GETMXDSR_RDTURN_Pos)); + + /* Set value in GETMXDSR register */ + WRITE_REG(hi3c->Instance->GETMXDSR, getmxdsr_value); + + /* Calculate value to be written in MAXRLR register */ + maxrlr_value = (pConfig->IBIPayloadSize | (pConfig->MaxReadDataSize & I3C_MAXRLR_MRL)); + + /* Set payload size and max read data size in MAXRLR register */ + WRITE_REG(hi3c->Instance->MAXRLR, maxrlr_value); + + /* Set max write data size in MAXWLR register */ + LL_I3C_SetMaxWriteLength(hi3c->Instance, pConfig->MaxWriteDataSize); + + /* Set MIPI identifier value in EPIDR register */ + LL_I3C_SetMIPIInstanceID(hi3c->Instance, pConfig->MIPIIdentifier); + + /* Set identifier value in DCR register */ + LL_I3C_SetDeviceCharacteristics(hi3c->Instance, pConfig->Identifier); + + /* Calculate value to be written in CRCCAPR register */ + crccapr_value = (((uint32_t)pConfig->HandOffDelay << I3C_CRCAPR_CAPDHOFF_Pos) | + ((uint32_t)pConfig->GroupAddrCapability << I3C_CRCAPR_CAPGRP_Pos)); + + /* Set hand off dealy and group address capability in CRCCAPR register */ + WRITE_REG(hi3c->Instance->CRCAPR, crccapr_value); + + /* Set pending read MDB notification value in GETCAPR register */ + LL_I3C_SetPendingReadMDB(hi3c->Instance, ((uint32_t)pConfig->PendingReadMDB << I3C_GETCAPR_CAPPEND_Pos)); + + /* Calculate value to be written in BCR register */ + bcr_value = (((uint32_t)pConfig->MaxSpeedLimitation << I3C_BCR_BCR0_Pos) | + ((uint32_t)pConfig->IBIPayload << I3C_BCR_BCR2_Pos) | + ((uint32_t)pConfig->CtrlCapability << I3C_BCR_BCR6_Pos)); + + /* Set control capability, IBI payload support and max speed limitation in BCR register */ + WRITE_REG(hi3c->Instance->BCR, bcr_value); + + /* Calculate value to be written in CFGR register */ + devr0_value = (((uint32_t)pConfig->IBIRequest << I3C_DEVR0_IBIEN_Pos) | + ((uint32_t)pConfig->CtrlRoleRequest << I3C_DEVR0_CREN_Pos) | + ((uint32_t)pConfig->HotJoinRequest << I3C_DEVR0_HJEN_Pos)); + + /* Set IBI request, control role request and hot join request in DEVR0 register */ + MODIFY_REG(hi3c->Instance->DEVR0, (I3C_DEVR0_HJEN | I3C_DEVR0_IBIEN | I3C_DEVR0_CREN), devr0_value); + + /* Enable the selected I3C peripheral */ + LL_I3C_Enable(hi3c->Instance); + } + } + + return status; +} + +/** + * @brief Set I3C bus devices configuration. + * @note This function is called only when the I3C instance is initialized as controller. + * This function can be called by the controller application to help the automatic treatment when target have + * capability of IBI and/or Control-Role. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param pDesc : [IN] Pointer to an I3C_DeviceConfTypeDef descriptor that contains the bus devices + * configurations. + * @param nbDevice : [IN] Value specifies the number of devices to be treated. + * This parameter must be a number between Min_Data=1U and Max_Data=4U. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Ctrl_ConfigBusDevices(I3C_HandleTypeDef *hi3c, + const I3C_DeviceConfTypeDef *pDesc, + uint8_t nbDevice) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t write_value; + + /* Check the I3C handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check on user parameters */ + if (pDesc == NULL) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* Check the I3C state and mode */ + else if ((hi3c->State == HAL_I3C_STATE_RESET) || (hi3c->Mode != HAL_I3C_MODE_CONTROLLER)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + assert_param(IS_I3C_DEVICE_VALUE(nbDevice)); + + /* Loop on the nbDevice to be treated */ + for (uint32_t index = 0U; index < nbDevice; index++) + { + /* Check configuration parameters values */ + assert_param(IS_I3C_DEVICE_VALUE(pDesc[index].DeviceIndex)); + assert_param(IS_I3C_DYNAMICADDRESS_VALUE(pDesc[index].TargetDynamicAddr)); + assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pDesc[index].IBIAck)); + assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pDesc[index].CtrlRoleReqAck)); + assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pDesc[index].CtrlStopTransfer)); + assert_param(IS_I3C_FUNCTIONALSTATE_VALUE(pDesc[index].IBIPayload)); + + /* Set value to be written */ + write_value = (((uint32_t)pDesc[index].TargetDynamicAddr << I3C_DEVRX_DA_Pos) | + ((uint32_t)pDesc[index].IBIAck << I3C_DEVRX_IBIACK_Pos) | + ((uint32_t)pDesc[index].CtrlRoleReqAck << I3C_DEVRX_CRACK_Pos) | + ((uint32_t)pDesc[index].CtrlStopTransfer << I3C_DEVRX_SUSP_Pos) | + ((uint32_t)pDesc[index].IBIPayload << I3C_DEVRX_IBIDEN_Pos)); + + /* Write configuration in the DEVRx register */ + WRITE_REG(hi3c->Instance->DEVRX[(pDesc[index].DeviceIndex - 1U)], write_value); + } + } + } + + return status; +} + +/** + * @brief Add Private or CCC descriptor in the user data transfer descriptor. + * @note This function must be called before initiate any communication transfer. This function help the preparation + * of the full transfer usecase in a transfer descriptor which contained different buffer pointers + * and their associated size through I3C_XferTypeDef. + * @note The Tx FIFO threshold @ref HAL_I3C_TXFIFO_THRESHOLD_4_4 is not allowed when the transfer descriptor contains + * multiple transmission frames. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param pCCCDesc : [IN] Pointer to an I3C_CCCTypeDef structure that contains the CCC descriptor information. + * @param pPrivateDesc : [IN] Pointer to an I3C_PrivateTypeDef structure that contains the transfer descriptor. + * @param pXferData : [IN/OUT] Pointer to an I3C_XferTypeDef structure that contains required transmission buffers + * (control buffer, data buffer and status buffer). + * @param nbFrame : [IN] The number of CCC commands or the number of device to treat. + * @param option : [IN] Value indicates the transfer option. It can be one value of @ref I3C_OPTION_DEFINITION + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_AddDescToFrame(I3C_HandleTypeDef *hi3c, + const I3C_CCCTypeDef *pCCCDesc, + const I3C_PrivateTypeDef *pPrivateDesc, + I3C_XferTypeDef *pXferData, + uint8_t nbFrame, + uint32_t option) +{ + HAL_I3C_StateTypeDef handle_state; + HAL_StatusTypeDef status = HAL_OK; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* Set handle transfer parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->pCCCDesc = pCCCDesc; + hi3c->pPrivateDesc = pPrivateDesc; + hi3c->pXferData = pXferData; + hi3c->RxXferCount = 0; + hi3c->TxXferCount = 0; + + /* Prepare Direction, and Check on user parameters */ + if (((option & I3C_OPERATION_TYPE_MASK) == LL_I3C_CONTROLLER_MTYPE_CCC) || + ((option & I3C_OPERATION_TYPE_MASK) == LL_I3C_CONTROLLER_MTYPE_DIRECT)) + { + /* Check on user parameters */ + if ((pCCCDesc == NULL) || + (pXferData == NULL) || + (nbFrame < 1U) || + (((option & (I3C_OPERATION_TYPE_MASK | I3C_DEFINE_BYTE_MASK)) == \ + (LL_I3C_CONTROLLER_MTYPE_DIRECT | I3C_DEFINE_BYTE_MASK)) && (pCCCDesc->CCCBuf.Size == 0U))) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + } + else + { + /* Check on user parameters */ + if ((pPrivateDesc == NULL) || (pXferData == NULL) || (nbFrame <= 0U)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + } + + if (status == HAL_OK) + { + /* check on the State */ + if ((handle_state == HAL_I3C_STATE_READY) || (handle_state == HAL_I3C_STATE_LISTEN)) + { + /* I3C control buffer prior preparation */ + if (I3C_ControlBuffer_PriorPreparation(hi3c, nbFrame, option) != HAL_OK) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + + /* I3C Tx Buffer prior preparation, set and check RxCount */ + if (I3C_Xfer_PriorPreparation(hi3c, nbFrame, option) != HAL_OK) + { + status = HAL_ERROR; + } + } + else + { + status = HAL_BUSY; + } + } + } + + return status; +} + +/** + * @} + */ + +/** @defgroup I3C_Exported_Functions_Group4 FIFO Management functions. + * @brief I3C FIFO management functions. + * +@verbatim + ======================================================================================================================= + ##### FIFO Management functions ##### + ======================================================================================================================= + [..] This subsection provides a set of functions allowing to manage I3C FIFOs. + + (+) Call the function HAL_I3C_FlushAllFifo() to flush the content of all used FIFOs (Control, Status, + Tx and Rx FIFO). + (+) Call the function HAL_I3C_FlushTxFifo() to flush only the content of Tx FIFO. + (+) Call the function HAL_I3C_FlushRxFifo() to flush only the content of Rx FIFO. + (+) Call the function HAL_I3C_FlushControlFifo() to flush only the content of Control FIFO. + This function is called only when mode is controller. + (+) Call the function HAL_I3C_FlushStatusFifo() to flush only the content of Status FIFO. + This function is called only when mode is controller. + (+) Call the function HAL_I3C_ClearConfigFifo() to clear the FIFOs configuration and set it to default values. + (+) Call the function HAL_I3C_GetConfigFifo() to get the current FIFOs configuration (enabled FIFOs and + threshold level). + + (+) Users must not call all above functions before I3C initialization. + + (+) Users should call Flush APIs after an end of process, before starting a transfer or in case of bus + failure and error detection. + +@endverbatim + * @{ + */ + +/** + * @brief Flush all I3C FIFOs content. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_FlushAllFifo(I3C_HandleTypeDef *hi3c) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t cfgr_value; + + /* Check the I3C handle allocation */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Check the I3C state */ + if (hi3c->State == HAL_I3C_STATE_RESET) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + else + { + /* Flush the content of Tx and Rx Fifo */ + cfgr_value = (I3C_CFGR_TXFLUSH | I3C_CFGR_RXFLUSH); + + /* Check on the I3C mode: Control and status FIFOs available only with controller mode */ + if (hi3c->Mode == HAL_I3C_MODE_CONTROLLER) + { + /* Flush the content of Control and Status Fifo */ + cfgr_value = (I3C_CFGR_SFLUSH | I3C_CFGR_CFLUSH); + } + + /* Set configuration in the CFGR register */ + MODIFY_REG(hi3c->Instance->CFGR, cfgr_value, cfgr_value); + } + } + + return status; +} + +/** + * @brief Flush I3C Tx FIFO content. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_FlushTxFifo(I3C_HandleTypeDef *hi3c) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the I3C handle allocation */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Check the I3C state */ + if (hi3c->State == HAL_I3C_STATE_RESET) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + else + { + /* Flush the content of Tx Fifo */ + LL_I3C_RequestTxFIFOFlush(hi3c->Instance); + } + } + + return status; +} + +/** + * @brief Flush I3C Rx FIFO content. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_FlushRxFifo(I3C_HandleTypeDef *hi3c) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the I3C handle allocation */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Check the I3C state */ + if (hi3c->State == HAL_I3C_STATE_RESET) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + else + { + /* Flush the content of Rx Fifo */ + LL_I3C_RequestRxFIFOFlush(hi3c->Instance); + } + } + + return status; +} + +/** + * @brief Flush I3C control FIFO content. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_FlushControlFifo(I3C_HandleTypeDef *hi3c) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the I3C handle allocation */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Check the I3C state and mode */ + if ((hi3c->State == HAL_I3C_STATE_RESET) || (hi3c->Mode != HAL_I3C_MODE_CONTROLLER)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + else + { + /* Flush the content of Control Fifo */ + LL_I3C_RequestControlFIFOFlush(hi3c->Instance); + } + } + + return status; +} + +/** + * @brief Flush I3C status FIFO content. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_FlushStatusFifo(I3C_HandleTypeDef *hi3c) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the I3C handle allocation */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Check the I3C state and mode */ + if ((hi3c->State == HAL_I3C_STATE_RESET) || (hi3c->Mode != HAL_I3C_MODE_CONTROLLER)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + else + { + /* Flush the content of Control Fifo */ + LL_I3C_RequestStatusFIFOFlush(hi3c->Instance); + } + } + + return status; +} + +/** + * @brief Clear I3C FIFOs configuration and set it to default values. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_ClearConfigFifo(I3C_HandleTypeDef *hi3c) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t cfgr_value; + uint32_t cfgr_mask; + + /* Check the I3C handle allocation */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Check the I3C state */ + if (hi3c->State == HAL_I3C_STATE_RESET) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + else + { + /* Clear Tx Fifo and Rx Fifo threshold and set it to default value */ + cfgr_value = (LL_I3C_TXFIFO_THRESHOLD_1_4 | LL_I3C_RXFIFO_THRESHOLD_1_4); + cfgr_mask = (I3C_CFGR_TXTHRES | I3C_CFGR_RXTHRES); + + /* Check on the I3C mode: Control and status FIFOs available only with controller mode */ + if (hi3c->Mode == HAL_I3C_MODE_CONTROLLER) + { + /* Disable the status and Control Fifo state */ + cfgr_value |= (HAL_I3C_STATUSFIFO_DISABLE | HAL_I3C_CONTROLFIFO_DISABLE); + cfgr_mask |= (I3C_CFGR_TMODE | I3C_CFGR_SMODE); + } + + /* Set configuration in the CFGR register */ + MODIFY_REG(hi3c->Instance->CFGR, cfgr_mask, cfgr_value); + } + } + + return status; +} + +/** + * @brief Get I3C FIFOs current configuration. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param pConfig : [IN/OUT] Pointer to an I3C_FifoConfTypeDef structure that returns current FIFOs configuration. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_GetConfigFifo(I3C_HandleTypeDef *hi3c, I3C_FifoConfTypeDef *pConfig) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the I3C handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Check on user parameters */ + if (pConfig == NULL) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* Check the I3C state */ + else if (hi3c->State == HAL_I3C_STATE_RESET) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + else + { + /* Get Tx Fifo threshold */ + pConfig->TxFifoThreshold = LL_I3C_GetTxFIFOThreshold(hi3c->Instance); + + /* Get Rx Fifo threshold */ + pConfig->RxFifoThreshold = LL_I3C_GetRxFIFOThreshold(hi3c->Instance); + + /* Get the Control Fifo state */ + pConfig->ControlFifo = (uint32_t)(LL_I3C_IsEnabledControlFIFO(hi3c->Instance) << I3C_CFGR_TMODE_Pos); + + /* Get the status Fifo state */ + pConfig->StatusFifo = (uint32_t)(LL_I3C_IsEnabledStatusFIFO(hi3c->Instance) << I3C_CFGR_SMODE_Pos); + } + } + + return status; +} +/** + * @} + */ + +/** @defgroup I3C_Exported_Functions_Group5 Controller operational functions. + * @brief I3C controller operational functions. + * +@verbatim + ======================================================================================================================= + ##### Controller operational functions ##### + ======================================================================================================================= + [..] This subsection provides a set of functions allowing to manage controller I3C operation. + + (+) Call the function HAL_I3C_Ctrl_TransmitCCC() to transmit direct write or a broadcast + CCC command in polling mode. + (+) Call the function HAL_I3C_Ctrl_TransmitCCC_IT() to transmit direct write or a broadcast + CCC command in interrupt mode. + (+) Call the function HAL_I3C_Ctrl_TransmitCCC_DMA() to transmit direct write or a broadcast + CCC command in DMA mode. + (+) Call the function HAL_I3C_Ctrl_ReceiveCCC() to transmit direct read CCC command in polling mode. + (+) Call the function HAL_I3C_Ctrl_ReceiveCCC_IT() to transmit direct read CCC command in interrupt mode. + (+) Call the function HAL_I3C_Ctrl_ReceiveCCC_DMA() to transmit direct read CCC command in DMA mode. + (+) Call the function HAL_I3C_Ctrl_Transmit() to transmit private data in polling mode. + (+) Call the function HAL_I3C_Ctrl_Transmit_IT() to transmit private data in interrupt mode. + (+) Call the function HAL_I3C_Ctrl_Transmit_DMA() to transmit private data in DMA mode. + (+) Call the function HAL_I3C_Ctrl_Receive() to receive private data in polling mode. + (+) Call the function HAL_I3C_Ctrl_Receive_IT() to receive private data in interrupt mode. + (+) Call the function HAL_I3C_Ctrl_Receive_DMA() to receive private data in DMA mode. + (+) Call the function HAL_I3C_Ctrl_MultipleTransfer_IT() to transfer I3C or I2C private data or CCC command + in multiple direction in interrupt mode. + (+) Call the function HAL_I3C_Ctrl_MultipleTransfer_DMA() to transfer I3C or I2C private data or CCC command + in multiple direction in DMA mode. + (+) Call the function HAL_I3C_Ctrl_DynAddrAssign() to send a broadcast ENTDAA CCC + command in polling mode. + (+) Call the function HAL_I3C_Ctrl_DynAddrAssign_IT() to send a broadcast ENTDAA CCC + command in interrupt mode. + (+) Call the function HAL_I3C_Ctrl_SetDynAddr() to set, asscociate the target dynamic address + during the Dynamic Address Assignment processus. + (+) Call the function HAL_I3C_Ctrl_IsDeviceI3C_Ready() to check if I3C target device is ready. + (+) Call the function HAL_I3C_Ctrl_IsDeviceI2C_Ready() to check if I2C target device is ready. + + (+) Those functions are called only when mode is Controller. + +@endverbatim + * @{ + */ + +/** + * @brief Controller transmit direct write or a broadcast CCC command in polling mode. + * @note The function @ref HAL_I3C_AddDescToFrame() must be called before initiate a transfer. + * @note The Tx FIFO threshold @ref HAL_I3C_TXFIFO_THRESHOLD_4_4 is not allowed when the transfer descriptor contains + * multiple transmission frames. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmission buffers + * (control buffer, data buffer and status buffer). + * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame(). + * @param timeout : [IN] Timeout duration in millisecond. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Ctrl_TransmitCCC(I3C_HandleTypeDef *hi3c, + I3C_XferTypeDef *pXferData, + uint32_t timeout) +{ + uint32_t tickstart; + uint32_t exit_condition; + HAL_StatusTypeDef status = HAL_OK; + HAL_I3C_StateTypeDef handle_state; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* Check on user parameters */ + if ((pXferData == NULL) || + ((pXferData->TxBuf.pBuffer == NULL) && (hi3c->TxXferCount != 0U))) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* check on the Mode */ + else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* check on the State */ + else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN)) + { + /* Update returned status value */ + status = HAL_BUSY; + } + else + { + /* Set handle transfer parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY_TX; + hi3c->pXferData = pXferData; + + /* Check on the Tx threshold to know the Tx treatment process : byte or word */ + if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4) + { + /* Set byte treatment function pointer */ + hi3c->ptrTxFunc = &I3C_TransmitByteTreatment; + } + else + { + /* Set word treatment function pointer */ + hi3c->ptrTxFunc = &I3C_TransmitWordTreatment; + } + + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + + /* Check on control FIFO enable/disable state */ + if (LL_I3C_IsEnabledControlFIFO(hi3c->Instance) == 1U) + { + /* Initiate a Start condition */ + LL_I3C_RequestTransfer(hi3c->Instance); + } + else + { + /* Decrement remaining control buffer data counter */ + hi3c->ControlXferCount--; + + /* Initiate a start condition by writing in the CR register */ + WRITE_REG(hi3c->Instance->CR, *hi3c->pXferData->CtrlBuf.pBuffer); + + /* Increment Buffer pointer */ + hi3c->pXferData->CtrlBuf.pBuffer++; + } + + /* Do while until FC (Frame Complete) is set or timeout */ + do + { + /* Check if hardware asks for control data */ + if (hi3c->ControlXferCount > 0U) + { + /* Call control data treatment function */ + I3C_ControlDataTreatment(hi3c); + } + + /* Check if hardware asks for Tx data */ + if (hi3c->TxXferCount > 0U) + { + /* Call transmit treatment function */ + hi3c->ptrTxFunc(hi3c); + } + + /* Check for the timeout */ + if (timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > timeout) || (timeout == 0U)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_TIMEOUT; + status = HAL_TIMEOUT; + break; + } + } + + if ((__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_FCF) == SET) && (hi3c->ControlXferCount > 0U)) + { + /* Clear frame complete flag */ + LL_I3C_ClearFlag_FC(hi3c->Instance); + + /* Then Initiate a Start condition */ + LL_I3C_RequestTransfer(hi3c->Instance); + } + + /* Calculate exit_condition value based on Frame complete and error flags */ + exit_condition = (READ_REG(hi3c->Instance->EVR) & (I3C_EVR_FCF | I3C_EVR_ERRF)); + } while ((exit_condition == 0U) || + ((exit_condition == I3C_EVR_FCF) && (hi3c->ControlXferCount > 0U))); + + /* Clear frame complete flag */ + if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_FCF) == SET) + { + LL_I3C_ClearFlag_FC(hi3c->Instance); + } + + /* Check on error flag */ + if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET) + { + /* Clear error flag */ + LL_I3C_ClearFlag_ERR(hi3c->Instance); + + /* Update handle error code parameter */ + I3C_GetErrorSources(hi3c); + + /* Update returned status value */ + status = HAL_ERROR; + } + + /* At the end of Tx process update state to Previous state */ + I3C_StateUpdate(hi3c); + } + } + + return status; +} + +/** + * @brief Controller transmit direct write or a broadcast CCC command in interrupt mode. + * @note The function @ref HAL_I3C_AddDescToFrame() must be called before initiate a transfer. + * @note The Tx FIFO threshold @ref HAL_I3C_TXFIFO_THRESHOLD_4_4 is not allowed when the transfer descriptor contains + * multiple transmission frames. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmission buffers + * (control buffer, data buffer and status buffer). + * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame(). + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Ctrl_TransmitCCC_IT(I3C_HandleTypeDef *hi3c, + I3C_XferTypeDef *pXferData) +{ + HAL_I3C_StateTypeDef handle_state; + HAL_StatusTypeDef status = HAL_OK; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* Check on user parameters */ + if ((pXferData == NULL) || + ((pXferData->TxBuf.pBuffer == NULL) && (hi3c->TxXferCount != 0U))) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* check on the Mode */ + else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* check on the State */ + else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN)) + { + status = HAL_BUSY; + } + else + { + /* Set handle transfer parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY_TX; + hi3c->pXferData = pXferData; + hi3c->XferISR = I3C_Ctrl_Tx_ISR; + + /* Check on the Tx threshold to know the Tx treatment process : byte or word */ + if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4) + { + /* Set byte treatment function pointer */ + hi3c->ptrTxFunc = &I3C_TransmitByteTreatment; + } + else + { + /* Set word treatment function pointer */ + hi3c->ptrTxFunc = &I3C_TransmitWordTreatment; + } + + /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk + of I3C interrupt handle execution before current process unlock */ + + /* Enable Tx process interrupts */ + I3C_Enable_IRQ(hi3c, I3C_XFER_CONTROLLER_TX_IT); + + /* Initiate a Start condition */ + LL_I3C_RequestTransfer(hi3c->Instance); + } + } + + return status; +} + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief Controller transmit direct write or a broadcast CCC command in DMA mode. + * @note The function @ref HAL_I3C_AddDescToFrame() must be called before initiate a transfer. + * @note The Tx FIFO threshold @ref HAL_I3C_TXFIFO_THRESHOLD_4_4 is not allowed when the transfer descriptor contains + * multiple transmission frames. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmission buffers + * (control buffer, data buffer and status buffer). + * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame(). + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Ctrl_TransmitCCC_DMA(I3C_HandleTypeDef *hi3c, + I3C_XferTypeDef *pXferData) +{ + HAL_StatusTypeDef control_dma_status; + HAL_StatusTypeDef tx_dma_status = HAL_OK; + HAL_I3C_StateTypeDef handle_state; + HAL_StatusTypeDef status = HAL_OK; + uint32_t size_align_word; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* Check on user parameters */ + if ((pXferData == NULL) || + ((pXferData->TxBuf.pBuffer == NULL) && (hi3c->TxXferCount != 0U))) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* Check on hdmatx and hdmacr handle */ + else if ((hi3c->hdmatx == NULL) || (hi3c->hdmacr == NULL)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_DMA_PARAM; + status = HAL_ERROR; + } + /* check on the Mode */ + else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* check on the State */ + else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN)) + { + status = HAL_BUSY; + } + else + { + /* Set handle transfer parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY_TX; + hi3c->pXferData = pXferData; + hi3c->XferISR = I3C_Ctrl_Tx_DMA_ISR; + + /*------------------------------------ I3C DMA channel for Control Data ----------------------------------------*/ + /* Set the I3C DMA transfer complete callback */ + hi3c->hdmacr->XferCpltCallback = I3C_DMAControlTransmitCplt; + + /* Set the DMA error callback */ + hi3c->hdmacr->XferErrorCallback = I3C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi3c->hdmacr->XferHalfCpltCallback = NULL; + hi3c->hdmacr->XferAbortCallback = NULL; + + /* assert that DMA source and destination width are configured in word */ + assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmacr->Init.SrcDataWidth)); + assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmacr->Init.DestDataWidth)); + + /* Enable the control data DMA channel */ + control_dma_status = HAL_DMA_Start_IT(hi3c->hdmacr, (uint32_t)hi3c->pXferData->CtrlBuf.pBuffer, + (uint32_t)&hi3c->Instance->CR, (hi3c->ControlXferCount * 4U)); + + /*------------------------------------ I3C DMA channel for the Tx Data -----------------------------------------*/ + /* Check if Tx counter different from zero */ + if (hi3c->TxXferCount != 0U) + { + /* Set the I3C DMA transfer complete callback */ + hi3c->hdmatx->XferCpltCallback = I3C_DMADataTransmitCplt; + + /* Set the DMA error callback */ + hi3c->hdmatx->XferErrorCallback = I3C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi3c->hdmatx->XferHalfCpltCallback = NULL; + hi3c->hdmatx->XferAbortCallback = NULL; + + /* Check on the Tx threshold to know the Tx treatment process : byte or word */ + if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4) + { + /* assert that DMA source and destination width are configured in byte */ + assert_param(IS_I3C_DMASOURCEBYTE_VALUE(hi3c->hdmatx->Init.SrcDataWidth)); + assert_param(IS_I3C_DMADESTINATIONBYTE_VALUE(hi3c->hdmatx->Init.DestDataWidth)); + + /* Enable the Tx data DMA channel */ + tx_dma_status = HAL_DMA_Start_IT(hi3c->hdmatx, (uint32_t)hi3c->pXferData->TxBuf.pBuffer, + (uint32_t)&hi3c->Instance->TDR, hi3c->pXferData->TxBuf.Size); + } + else + { + /* assert that DMA source and destination width are configured in word */ + assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmatx->Init.SrcDataWidth)); + assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmatx->Init.DestDataWidth)); + + /* Check to align data size in words */ + if ((hi3c->pXferData->TxBuf.Size % 4U) == 0U) + { + /* Keep the same size */ + size_align_word = hi3c->pXferData->TxBuf.Size; + } + else + { + /* Modify size to be multiple of 4 */ + size_align_word = ((hi3c->pXferData->TxBuf.Size + 4U) - (hi3c->pXferData->TxBuf.Size % 4U)); + } + + /* Enable the Tx data DMA channel */ + tx_dma_status = HAL_DMA_Start_IT(hi3c->hdmatx, (uint32_t)hi3c->pXferData->TxBuf.pBuffer, + (uint32_t)&hi3c->Instance->TDWR, size_align_word); + } + } + + /* Check if DMA process is well started */ + if ((control_dma_status == HAL_OK) && (tx_dma_status == HAL_OK)) + { + /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk + of I3C interrupt handle execution before current process unlock */ + + /* Enable Tx process interrupts */ + I3C_Enable_IRQ(hi3c, I3C_XFER_DMA); + + /* Update the number of remaining data bytes */ + hi3c->ControlXferCount = 0U; + + /* Enable control DMA Request */ + LL_I3C_EnableDMAReq_Control(hi3c->Instance); + + /* Check if Tx counter different from zero */ + if (hi3c->TxXferCount != 0U) + { + /* Update the number of remaining data bytes */ + hi3c->TxXferCount = 0U; + + /* Enable Tx data DMA Request */ + LL_I3C_EnableDMAReq_TX(hi3c->Instance); + } + + /* Initiate a Start condition */ + LL_I3C_RequestTransfer(hi3c->Instance); + } + else + { + /* Set callback to NULL if DMA started */ + if (HAL_DMA_Abort(hi3c->hdmacr) == HAL_OK) + { + hi3c->hdmacr->XferCpltCallback = NULL; + hi3c->hdmacr->XferErrorCallback = NULL; + } + + /* Set callback to NULL if DMA started */ + if (HAL_DMA_Abort(hi3c->hdmatx) == HAL_OK) + { + hi3c->hdmatx->XferCpltCallback = NULL; + hi3c->hdmatx->XferErrorCallback = NULL; + } + + hi3c->ErrorCode = HAL_I3C_ERROR_DMA; + status = HAL_ERROR; + + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + } + } + } + + return status; +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Controller transmit direct read CCC command in polling mode. + * @note The function @ref HAL_I3C_AddDescToFrame() must be called before initiate a transfer. + * @note The RxBuf.Size must be equal to the sum of all RxBuf.Size exist in the descriptor. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmission buffers + * (control buffer, data buffer and status buffer). + * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame(). + * @param timeout : [IN] Timeout duration in millisecond. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Ctrl_ReceiveCCC(I3C_HandleTypeDef *hi3c, + I3C_XferTypeDef *pXferData, + uint32_t timeout) +{ + uint32_t tickstart; + uint32_t exit_condition; + HAL_StatusTypeDef status = HAL_OK; + HAL_I3C_StateTypeDef handle_state; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* Check on user parameters */ + if ((pXferData == NULL) || + (pXferData->RxBuf.pBuffer == NULL) || + ((pXferData->TxBuf.pBuffer == NULL) && (hi3c->TxXferCount != 0U))) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* check on the Mode */ + else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* check on the State */ + else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN)) + { + status = HAL_BUSY; + } + else + { + /* Set handle transfer parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY_RX; + hi3c->pXferData = pXferData; + hi3c->RxXferCount = hi3c->pXferData->RxBuf.Size; + + /* Check on CCC defining byte */ + if (hi3c->TxXferCount != 0U) + { + /* Check on the Tx threshold to know the Tx treatment process : byte or word */ + if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4) + { + /* Set byte treatment function pointer */ + hi3c->ptrTxFunc = &I3C_TransmitByteTreatment; + } + else + { + /* Set word treatment function pointer */ + hi3c->ptrTxFunc = &I3C_TransmitWordTreatment; + } + } + + /* Check on the Rx threshold to know the Rx treatment process : byte or word */ + if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4) + { + /* Set byte treatment function pointer */ + hi3c->ptrRxFunc = &I3C_ReceiveByteTreatment; + } + else + { + /* Set word treatment function pointer */ + hi3c->ptrRxFunc = &I3C_ReceiveWordTreatment; + } + + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + + /* Check on control FIFO enable/disable state */ + if (LL_I3C_IsEnabledControlFIFO(hi3c->Instance) == 1U) + { + /* Initiate a Start condition */ + LL_I3C_RequestTransfer(hi3c->Instance); + } + else + { + /* Decrement remaining control buffer data counter */ + hi3c->ControlXferCount--; + + /* Initiate a start condition by writing in the CR register */ + WRITE_REG(hi3c->Instance->CR, *hi3c->pXferData->CtrlBuf.pBuffer); + + /* Increment Buffer pointer */ + hi3c->pXferData->CtrlBuf.pBuffer++; + } + + /* Do while until FC (Frame Complete) is set or timeout */ + do + { + /* Call control data treatment function */ + I3C_ControlDataTreatment(hi3c); + + if (hi3c->TxXferCount != 0U) + { + /* Call transmit treatment function */ + hi3c->ptrTxFunc(hi3c); + } + + /* Call receive treatment function */ + hi3c->ptrRxFunc(hi3c); + + /* Check for the timeout */ + if (timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > timeout) || (timeout == 0U)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_TIMEOUT; + status = HAL_TIMEOUT; + + break; + } + } + + if ((__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_FCF) == SET) && (hi3c->ControlXferCount > 0U)) + { + /* Clear frame complete flag */ + LL_I3C_ClearFlag_FC(hi3c->Instance); + + /* Then Initiate a Start condition */ + LL_I3C_RequestTransfer(hi3c->Instance); + } + + /* Calculate exit_condition value based on Frame complete and error flags */ + exit_condition = (READ_REG(hi3c->Instance->EVR) & (I3C_EVR_FCF | I3C_EVR_ERRF)); + } while ((exit_condition == 0U) || + ((exit_condition == I3C_EVR_FCF) && (hi3c->ControlXferCount > 0U))); + + /* Clear frame complete flag */ + if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_FCF) == SET) + { + LL_I3C_ClearFlag_FC(hi3c->Instance); + } + + /* Check if all data bytes are received */ + if ((hi3c->RxXferCount != 0U) && (status == HAL_OK)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_SIZE; + status = HAL_ERROR; + } + + /* Check on error flag */ + if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET) + { + /* Clear error flag */ + LL_I3C_ClearFlag_ERR(hi3c->Instance); + + /* Update handle error code parameter */ + I3C_GetErrorSources(hi3c); + + /* Update returned status value */ + status = HAL_ERROR; + } + + /* At the end of Rx process update state to Previous state */ + I3C_StateUpdate(hi3c); + } + } + + return status; +} + +/** + * @brief Controller transmit direct read CCC command in interrupt mode. + * @note The function @ref HAL_I3C_AddDescToFrame() must be called before initiate a transfer. + * @note The RxBuf.Size must be equal to the sum of all RxBuf.Size exist in the descriptor. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmission buffers + * (control buffer, data buffer and status buffer). + * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame(). + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Ctrl_ReceiveCCC_IT(I3C_HandleTypeDef *hi3c, + I3C_XferTypeDef *pXferData) +{ + HAL_I3C_StateTypeDef handle_state; + HAL_StatusTypeDef status = HAL_OK; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* Check on user parameters */ + if ((pXferData == NULL) || + (pXferData->RxBuf.pBuffer == NULL) || + ((pXferData->TxBuf.pBuffer == NULL) && (hi3c->TxXferCount != 0U))) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* check on the Mode */ + else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* check on the State */ + else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN)) + { + status = HAL_BUSY; + } + else + { + /* Set handle transfer parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY_RX; + hi3c->pXferData = pXferData; + hi3c->RxXferCount = pXferData->RxBuf.Size; + hi3c->XferISR = I3C_Ctrl_Rx_ISR; + + /* Check on CCC defining byte */ + if (hi3c->TxXferCount != 0U) + { + /* Check on the Tx threshold to know the Tx treatment process : byte or word */ + if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4) + { + /* Set byte treatment function pointer */ + hi3c->ptrTxFunc = &I3C_TransmitByteTreatment; + } + else + { + /* Set word treatment function pointer */ + hi3c->ptrTxFunc = &I3C_TransmitWordTreatment; + } + } + + /* Check on the Rx threshold to know the Rx treatment process : byte or word */ + if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4) + { + /* Set byte treatment function pointer */ + hi3c->ptrRxFunc = &I3C_ReceiveByteTreatment; + } + else + { + /* Set word treatment function pointer */ + hi3c->ptrRxFunc = &I3C_ReceiveWordTreatment; + } + + /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk + of I3C interrupt handle execution before current process unlock */ + + /* Enable Rx process interrupts */ + I3C_Enable_IRQ(hi3c, I3C_XFER_CONTROLLER_RX_CCC_IT); + + /* Initiate a Start condition */ + LL_I3C_RequestTransfer(hi3c->Instance); + + } + } + + return status; +} + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief Controller transmit direct read CCC command in DMA mode. + * @note The function @ref HAL_I3C_AddDescToFrame() must be called before initiate a transfer. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmission buffers + * (control buffer, data buffer and status buffer). + * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame(). + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Ctrl_ReceiveCCC_DMA(I3C_HandleTypeDef *hi3c, + I3C_XferTypeDef *pXferData) +{ + HAL_I3C_StateTypeDef handle_state; + HAL_StatusTypeDef status = HAL_OK; + HAL_StatusTypeDef control_dma_status; + HAL_StatusTypeDef tx_dma_status = HAL_OK; + HAL_StatusTypeDef rx_dma_status = HAL_OK; + uint32_t size_align_word; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* Check on user parameters */ + if ((pXferData == NULL) || + (pXferData->RxBuf.pBuffer == NULL) || + ((pXferData->TxBuf.pBuffer == NULL) && (hi3c->TxXferCount != 0U))) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* Check on hdmarx and hdmacr handle */ + else if ((hi3c->hdmarx == NULL) || (hi3c->hdmacr == NULL)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_DMA_PARAM; + status = HAL_ERROR; + } + else if ((hi3c->TxXferCount != 0U) && (hi3c->hdmatx == NULL)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_DMA_PARAM; + status = HAL_ERROR; + } + /* check on the Mode */ + else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* check on the State */ + else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN)) + { + status = HAL_BUSY; + } + else + { + /* Set handle transfer parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY_RX; + hi3c->pXferData = pXferData; + hi3c->RxXferCount = hi3c->pXferData->RxBuf.Size; + hi3c->XferISR = I3C_Ctrl_Rx_DMA_ISR; + + /*------------------------------------ I3C DMA channel for Control Data ----------------------------------------*/ + /* Set the I3C DMA transfer complete callback */ + hi3c->hdmacr->XferCpltCallback = I3C_DMAControlTransmitCplt; + + /* Set the DMA error callback */ + hi3c->hdmacr->XferErrorCallback = I3C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi3c->hdmacr->XferHalfCpltCallback = NULL; + hi3c->hdmacr->XferAbortCallback = NULL; + + /* assert that DMA source and destination width are configured in word */ + assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmacr->Init.SrcDataWidth)); + assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmacr->Init.DestDataWidth)); + + /* Enable the control data DMA channel */ + control_dma_status = HAL_DMA_Start_IT(hi3c->hdmacr, (uint32_t)hi3c->pXferData->CtrlBuf.pBuffer, + (uint32_t)&hi3c->Instance->CR, (hi3c->ControlXferCount * 4U)); + + /*------------------------------------ I3C DMA channel for defining byte ---------------------------------------*/ + /* Check if Tx counter different from zero */ + if (hi3c->TxXferCount != 0U) + { + /* Set the I3C DMA transfer complete callback */ + hi3c->hdmatx->XferCpltCallback = I3C_DMADataTransmitCplt; + + /* Set the DMA error callback */ + hi3c->hdmatx->XferErrorCallback = I3C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi3c->hdmatx->XferHalfCpltCallback = NULL; + hi3c->hdmatx->XferAbortCallback = NULL; + + /* Check on the Tx threshold to know the Tx treatment process : byte or word */ + if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4) + { + /* assert that DMA source and destination width are configured in byte */ + assert_param(IS_I3C_DMASOURCEBYTE_VALUE(hi3c->hdmatx->Init.SrcDataWidth)); + assert_param(IS_I3C_DMADESTINATIONBYTE_VALUE(hi3c->hdmatx->Init.DestDataWidth)); + + /* Enable the Tx data DMA channel */ + tx_dma_status = HAL_DMA_Start_IT(hi3c->hdmatx, (uint32_t)hi3c->pXferData->TxBuf.pBuffer, + (uint32_t)&hi3c->Instance->TDR, hi3c->pXferData->TxBuf.Size); + } + else + { + /* assert that DMA source and destination width are configured in word */ + assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmatx->Init.SrcDataWidth)); + assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmatx->Init.DestDataWidth)); + + /* Modify size to be multiple of 4 */ + size_align_word = ((hi3c->pXferData->TxBuf.Size + 4U) - (hi3c->pXferData->TxBuf.Size % 4U)); + + /* Enable the Tx data DMA channel */ + tx_dma_status = HAL_DMA_Start_IT(hi3c->hdmatx, (uint32_t)hi3c->pXferData->TxBuf.pBuffer, + (uint32_t)&hi3c->Instance->TDWR, size_align_word); + } + } + /*------------------------------------ I3C DMA channel for the Rx Data -----------------------------------------*/ + /* Check if Rx counter different from zero */ + if (hi3c->RxXferCount != 0U) + { + /* Set the I3C DMA transfer complete callback */ + hi3c->hdmarx->XferCpltCallback = I3C_DMADataReceiveCplt; + + /* Set the DMA error callback */ + hi3c->hdmarx->XferErrorCallback = I3C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi3c->hdmarx->XferHalfCpltCallback = NULL; + hi3c->hdmarx->XferAbortCallback = NULL; + + /* Check on the Rx threshold to know the Rx treatment process : byte or word */ + if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4) + { + /* assert that DMA source and destination width are configured in byte */ + assert_param(IS_I3C_DMASOURCEBYTE_VALUE(hi3c->hdmarx->Init.SrcDataWidth)); + assert_param(IS_I3C_DMADESTINATIONBYTE_VALUE(hi3c->hdmarx->Init.DestDataWidth)); + + /* Enable the Rx data DMA channel */ + rx_dma_status = HAL_DMA_Start_IT(hi3c->hdmarx, (uint32_t)&hi3c->Instance->RDR, + (uint32_t)hi3c->pXferData->RxBuf.pBuffer, hi3c->pXferData->RxBuf.Size); + } + else + { + /* assert that DMA source and destination width are configured in word */ + assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmarx->Init.SrcDataWidth)); + assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmarx->Init.DestDataWidth)); + + /* Check to align data size in words */ + if ((hi3c->pXferData->RxBuf.Size % 4U) == 0U) + { + /* Keep the same size */ + size_align_word = hi3c->pXferData->RxBuf.Size; + } + else + { + /* Modify size to be multiple of 4 */ + size_align_word = ((hi3c->pXferData->RxBuf.Size + 4U) - (hi3c->pXferData->RxBuf.Size % 4U)); + } + + /* Enable the Rx data DMA channel */ + rx_dma_status = HAL_DMA_Start_IT(hi3c->hdmarx, (uint32_t)&hi3c->Instance->RDWR, + (uint32_t)hi3c->pXferData->RxBuf.pBuffer, size_align_word); + } + } + + /* Check if DMA process is well started */ + if ((control_dma_status == HAL_OK) && (tx_dma_status == HAL_OK) && (rx_dma_status == HAL_OK)) + { + /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk + of I3C interrupt handle execution before current process unlock */ + + /* Enable Rx process interrupts */ + I3C_Enable_IRQ(hi3c, I3C_XFER_DMA); + + /* Update the number of remaining data bytes */ + hi3c->ControlXferCount = 0U; + + /* Enable control DMA Request */ + LL_I3C_EnableDMAReq_Control(hi3c->Instance); + + /* Check if Tx counter different from zero */ + if (hi3c->TxXferCount != 0U) + { + /* Update the number of remaining data bytes */ + hi3c->TxXferCount = 0U; + + /* Enable Tx data DMA Request */ + LL_I3C_EnableDMAReq_TX(hi3c->Instance); + } + + /* Check if Rx counter different from zero */ + if (hi3c->RxXferCount != 0U) + { + /* Update the number of remaining data bytes */ + hi3c->RxXferCount = 0U; + + /* Enable Rx data DMA Request */ + LL_I3C_EnableDMAReq_RX(hi3c->Instance); + } + + /* Initiate a Start condition */ + LL_I3C_RequestTransfer(hi3c->Instance); + } + else + { + /* Set callback to NULL if DMA started */ + if (HAL_DMA_Abort(hi3c->hdmacr) == HAL_OK) + { + hi3c->hdmacr->XferCpltCallback = NULL; + hi3c->hdmacr->XferErrorCallback = NULL; + } + + /* Set callback to NULL if DMA started */ + if (HAL_DMA_Abort(hi3c->hdmatx) == HAL_OK) + { + hi3c->hdmatx->XferCpltCallback = NULL; + hi3c->hdmatx->XferErrorCallback = NULL; + } + + /* Set callback to NULL if DMA started */ + if (HAL_DMA_Abort(hi3c->hdmarx) == HAL_OK) + { + hi3c->hdmarx->XferCpltCallback = NULL; + hi3c->hdmarx->XferErrorCallback = NULL; + } + + hi3c->ErrorCode = HAL_I3C_ERROR_DMA; + status = HAL_ERROR; + + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + } + } + } + + return status; +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Controller private write in polling mode. + * @note The function @ref HAL_I3C_AddDescToFrame() must be called before initiate a transfer. + * @note The Tx FIFO threshold @ref HAL_I3C_TXFIFO_THRESHOLD_4_4 is not allowed when the transfer descriptor contains + * multiple transmission frames. + * @note The TxBuf.Size must be equal to the sum of all TxBuf.Size exist in the descriptor. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmission buffers + * (control buffer, data buffer and status buffer). + * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame(). + * @param timeout : [IN] Timeout duration in millisecond. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Ctrl_Transmit(I3C_HandleTypeDef *hi3c, + I3C_XferTypeDef *pXferData, + uint32_t timeout) +{ + uint32_t tickstart; + uint32_t exit_condition; + HAL_StatusTypeDef status = HAL_OK; + HAL_I3C_StateTypeDef handle_state; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* Check on user parameters */ + if ((pXferData == NULL) || + ((pXferData->TxBuf.pBuffer == NULL) && (hi3c->TxXferCount != 0U))) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* check on the Mode */ + else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* check on the State */ + else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN)) + { + status = HAL_BUSY; + } + else + { + /* Set handle transfer parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY_TX; + hi3c->pXferData = pXferData; + hi3c->TxXferCount = hi3c->pXferData->TxBuf.Size; + + /* Check on the Tx threshold to know the Tx treatment process : byte or word */ + if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4) + { + /* Set byte treatment function pointer */ + hi3c->ptrTxFunc = &I3C_TransmitByteTreatment; + } + else + { + /* Set word treatment function pointer */ + hi3c->ptrTxFunc = &I3C_TransmitWordTreatment; + } + + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + + /* Check on control FIFO enable/disable state */ + if (LL_I3C_IsEnabledControlFIFO(hi3c->Instance) == 1U) + { + /* Initiate a Start condition */ + LL_I3C_RequestTransfer(hi3c->Instance); + } + else + { + /* Decrement remaining control buffer data counter */ + hi3c->ControlXferCount--; + + /* Initiate a start condition by writing in the CR register */ + WRITE_REG(hi3c->Instance->CR, *hi3c->pXferData->CtrlBuf.pBuffer); + + /* Increment Buffer pointer */ + hi3c->pXferData->CtrlBuf.pBuffer++; + } + + /* Do while until FC (Frame Complete) is set or timeout */ + do + { + /* Call control data treatment function */ + I3C_ControlDataTreatment(hi3c); + + /* Call transmit treatment function */ + hi3c->ptrTxFunc(hi3c); + + /* Check for the timeout */ + if (timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > timeout) || (timeout == 0U)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_TIMEOUT; + status = HAL_TIMEOUT; + + break; + } + } + + if ((__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_FCF) == SET) && (hi3c->ControlXferCount > 0U)) + { + /* Clear frame complete flag */ + LL_I3C_ClearFlag_FC(hi3c->Instance); + + /* Then Initiate a Start condition */ + LL_I3C_RequestTransfer(hi3c->Instance); + } + + /* Calculate exit_condition value based on Frame complete and error flags */ + exit_condition = (READ_REG(hi3c->Instance->EVR) & (I3C_EVR_FCF | I3C_EVR_ERRF)); + } while ((exit_condition == 0U) || + ((exit_condition == I3C_EVR_FCF) && (hi3c->ControlXferCount > 0U))); + + /* Clear frame complete flag */ + if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_FCF) == SET) + { + LL_I3C_ClearFlag_FC(hi3c->Instance); + } + + /* Check if all data bytes are transmitted */ + if ((hi3c->TxXferCount != 0U) && (status == HAL_OK)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_SIZE; + status = HAL_ERROR; + } + + /* Check on error flag */ + if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET) + { + /* Clear error flag */ + LL_I3C_ClearFlag_ERR(hi3c->Instance); + + /* Update handle error code parameter */ + I3C_GetErrorSources(hi3c); + + /* Update returned status value */ + status = HAL_ERROR; + } + + /* At the end of Tx process update state to Previous state */ + I3C_StateUpdate(hi3c); + } + } + + return status; +} + +/** + * @brief Controller private write in interrupt mode. + * @note The function @ref HAL_I3C_AddDescToFrame() must be called before initiate a transfer. + * @note The Tx FIFO threshold @ref HAL_I3C_TXFIFO_THRESHOLD_4_4 is not allowed when the transfer descriptor contains + * multiple transmission frames. + * @note The TxBuf.Size must be equal to the sum of all TxBuf.Size exist in the descriptor. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmission buffers + * (control buffer, data buffer and status buffer). + * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame(). + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Ctrl_Transmit_IT(I3C_HandleTypeDef *hi3c, + I3C_XferTypeDef *pXferData) +{ + HAL_I3C_StateTypeDef handle_state; + HAL_StatusTypeDef status = HAL_OK; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* Check on user parameters */ + if ((pXferData == NULL) || + ((pXferData->TxBuf.pBuffer == NULL) && (hi3c->TxXferCount != 0U))) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* check on the Mode */ + else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* check on the State */ + else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN)) + { + status = HAL_BUSY; + } + else + { + /* Set handle transfer parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY_TX; + hi3c->pXferData = pXferData; + hi3c->TxXferCount = hi3c->pXferData->TxBuf.Size; + hi3c->XferISR = I3C_Ctrl_Tx_ISR; + + /* Check on the Tx threshold to know the Tx treatment process : byte or word */ + if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4) + { + /* Set byte treatment function pointer */ + hi3c->ptrTxFunc = &I3C_TransmitByteTreatment; + } + else + { + /* Set word treatment function pointer */ + hi3c->ptrTxFunc = &I3C_TransmitWordTreatment; + } + + /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk + of I3C interrupt handle execution before current process unlock */ + + /* Enable Tx process interrupts */ + I3C_Enable_IRQ(hi3c, I3C_XFER_CONTROLLER_TX_IT); + + /* Initiate a Start condition */ + LL_I3C_RequestTransfer(hi3c->Instance); + } + } + + return status; +} + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief Controller private write in DMA mode. + * @note The function @ref HAL_I3C_AddDescToFrame() must be called before initiate a transfer. + * @note The Tx FIFO threshold @ref HAL_I3C_TXFIFO_THRESHOLD_4_4 is not allowed when the transfer descriptor contains + * multiple transmission frames. + * @note The TxBuf.Size must be equal to the sum of all TxBuf.Size exist in the descriptor. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmission buffers + * (control buffer, data buffer and status buffer). + * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame(). + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Ctrl_Transmit_DMA(I3C_HandleTypeDef *hi3c, + I3C_XferTypeDef *pXferData) +{ + HAL_StatusTypeDef control_dma_status; + HAL_StatusTypeDef tx_dma_status = HAL_OK; + HAL_I3C_StateTypeDef handle_state; + HAL_StatusTypeDef status = HAL_OK; + uint32_t size_align_word; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* Check on user parameters */ + if ((pXferData == NULL) || + ((pXferData->TxBuf.pBuffer == NULL) && (hi3c->TxXferCount != 0U))) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* Check on hdmatx and hdmacr handle */ + else if ((hi3c->hdmatx == NULL) || (hi3c->hdmacr == NULL)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_DMA_PARAM; + status = HAL_ERROR; + } + /* check on the Mode */ + else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* check on the State */ + else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN)) + { + status = HAL_BUSY; + } + else + { + /* Set handle transfer parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY_TX; + hi3c->pXferData = pXferData; + hi3c->TxXferCount = hi3c->pXferData->TxBuf.Size; + hi3c->XferISR = I3C_Ctrl_Tx_DMA_ISR; + + /*------------------------------------ I3C DMA channel for Control Data ----------------------------------------*/ + /* Set the I3C DMA transfer complete callback */ + hi3c->hdmacr->XferCpltCallback = I3C_DMAControlTransmitCplt; + + /* Set the DMA error callback */ + hi3c->hdmacr->XferErrorCallback = I3C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi3c->hdmacr->XferHalfCpltCallback = NULL; + hi3c->hdmacr->XferAbortCallback = NULL; + + /* assert that DMA source and destination width are configured in word */ + assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmacr->Init.SrcDataWidth)); + assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmacr->Init.DestDataWidth)); + + /* Enable the control data DMA channel */ + control_dma_status = HAL_DMA_Start_IT(hi3c->hdmacr, (uint32_t)hi3c->pXferData->CtrlBuf.pBuffer, + (uint32_t)&hi3c->Instance->CR, (hi3c->ControlXferCount * 4U)); + + /*------------------------------------ I3C DMA channel for the Tx Data -----------------------------------------*/ + /* Check if Tx counter different from zero */ + if (hi3c->TxXferCount != 0U) + { + /* Set the I3C DMA transfer complete callback */ + hi3c->hdmatx->XferCpltCallback = I3C_DMADataTransmitCplt; + + /* Set the DMA error callback */ + hi3c->hdmatx->XferErrorCallback = I3C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi3c->hdmatx->XferHalfCpltCallback = NULL; + hi3c->hdmatx->XferAbortCallback = NULL; + + /* Check on the Tx threshold to know the Tx treatment process : byte or word */ + if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4) + { + /* assert that DMA source and destination width are configured in byte */ + assert_param(IS_I3C_DMASOURCEBYTE_VALUE(hi3c->hdmatx->Init.SrcDataWidth)); + assert_param(IS_I3C_DMADESTINATIONBYTE_VALUE(hi3c->hdmatx->Init.DestDataWidth)); + + /* Enable the Tx data DMA channel */ + tx_dma_status = HAL_DMA_Start_IT(hi3c->hdmatx, (uint32_t)hi3c->pXferData->TxBuf.pBuffer, + (uint32_t)&hi3c->Instance->TDR, hi3c->pXferData->TxBuf.Size); + } + else + { + /* assert that DMA source and destination width are configured in word */ + assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmatx->Init.SrcDataWidth)); + assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmatx->Init.DestDataWidth)); + + /* Check to align data size in words */ + if ((hi3c->pXferData->TxBuf.Size % 4U) == 0U) + { + /* Keep the same size */ + size_align_word = hi3c->pXferData->TxBuf.Size; + } + else + { + /* Modify size to be multiple of 4 */ + size_align_word = ((hi3c->pXferData->TxBuf.Size + 4U) - (hi3c->pXferData->TxBuf.Size % 4U)); + } + + /* Enable the Tx data DMA channel */ + tx_dma_status = HAL_DMA_Start_IT(hi3c->hdmatx, (uint32_t)hi3c->pXferData->TxBuf.pBuffer, + (uint32_t)&hi3c->Instance->TDWR, size_align_word); + } + } + + /* Check if DMA process is well started */ + if ((control_dma_status == HAL_OK) && (tx_dma_status == HAL_OK)) + { + /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk + of I3C interrupt handle execution before current process unlock */ + + /* Enable Tx process interrupts */ + I3C_Enable_IRQ(hi3c, I3C_XFER_DMA); + + /* Update the number of remaining data bytes */ + hi3c->ControlXferCount = 0U; + + /* Enable control DMA Request */ + LL_I3C_EnableDMAReq_Control(hi3c->Instance); + + /* Check if Tx counter different from zero */ + if (hi3c->TxXferCount != 0U) + { + /* Update the number of remaining data bytes */ + hi3c->TxXferCount = 0U; + + /* Enable Tx data DMA Request */ + LL_I3C_EnableDMAReq_TX(hi3c->Instance); + } + + /* Initiate a Start condition */ + LL_I3C_RequestTransfer(hi3c->Instance); + } + else + { + /* Set callback to NULL if DMA started */ + if (HAL_DMA_Abort(hi3c->hdmacr) == HAL_OK) + { + hi3c->hdmacr->XferCpltCallback = NULL; + hi3c->hdmacr->XferErrorCallback = NULL; + } + + /* Set callback to NULL if DMA started */ + if (HAL_DMA_Abort(hi3c->hdmatx) == HAL_OK) + { + hi3c->hdmatx->XferCpltCallback = NULL; + hi3c->hdmatx->XferErrorCallback = NULL; + } + + hi3c->ErrorCode = HAL_I3C_ERROR_DMA; + status = HAL_ERROR; + + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + } + } + } + + return status; +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Controller private read in polling mode. + * @note The function @ref HAL_I3C_AddDescToFrame() must be called before initiate a transfer. + * @note The RxBuf.Size must be equal to the sum of all RxBuf.Size exist in the descriptor. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required reception buffers + * (control buffer, data buffer and status buffer). + * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame(). + * @param timeout : [IN] Timeout duration in millisecond. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Ctrl_Receive(I3C_HandleTypeDef *hi3c, + I3C_XferTypeDef *pXferData, + uint32_t timeout) +{ + uint32_t tickstart; + uint32_t exit_condition; + HAL_StatusTypeDef status = HAL_OK; + HAL_I3C_StateTypeDef handle_state; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* Check on user parameters */ + if ((pXferData == NULL) || (pXferData->RxBuf.pBuffer == NULL)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* check on the Mode */ + else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* check on the State */ + else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN)) + { + status = HAL_BUSY; + } + else + { + /* Set handle transfer parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY_RX; + hi3c->pXferData = pXferData; + hi3c->RxXferCount = hi3c->pXferData->RxBuf.Size; + + /* Check on the Rx threshold to know the Rx treatment process : byte or word */ + if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4) + { + /* Set byte treatment function pointer */ + hi3c->ptrRxFunc = &I3C_ReceiveByteTreatment; + } + else + { + /* Set word treatment function pointer */ + hi3c->ptrRxFunc = &I3C_ReceiveWordTreatment; + } + + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + + /* Check on control FIFO enable/disable state */ + if (LL_I3C_IsEnabledControlFIFO(hi3c->Instance) == 1U) + { + /* Initiate a Start condition */ + LL_I3C_RequestTransfer(hi3c->Instance); + } + else + { + /* Decrement remaining control buffer data counter */ + hi3c->ControlXferCount--; + + /* Initiate a start condition by writing in the CR register */ + WRITE_REG(hi3c->Instance->CR, *hi3c->pXferData->CtrlBuf.pBuffer); + + /* Increment Buffer pointer */ + hi3c->pXferData->CtrlBuf.pBuffer++; + } + + /* Do while until FC (Frame Complete) is set or timeout */ + do + { + /* Call control data treatment function */ + I3C_ControlDataTreatment(hi3c); + + /* Call receive treatment function */ + hi3c->ptrRxFunc(hi3c); + + /* Check for the timeout */ + if (timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > timeout) || (timeout == 0U)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_TIMEOUT; + status = HAL_TIMEOUT; + + break; + } + } + + if ((__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_FCF) == SET) && (hi3c->ControlXferCount > 0U)) + { + /* Clear frame complete flag */ + LL_I3C_ClearFlag_FC(hi3c->Instance); + + /* Then Initiate a Start condition */ + LL_I3C_RequestTransfer(hi3c->Instance); + } + + /* Calculate exit_condition value based on Frame complete and error flags */ + exit_condition = (READ_REG(hi3c->Instance->EVR) & (I3C_EVR_FCF | I3C_EVR_ERRF)); + } while ((exit_condition == 0U) || + ((exit_condition == I3C_EVR_FCF) && (hi3c->ControlXferCount > 0U))); + + /* Clear frame complete flag */ + if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_FCF) == SET) + { + LL_I3C_ClearFlag_FC(hi3c->Instance); + } + + /* Check if all data bytes are received */ + if ((hi3c->RxXferCount != 0U) && (status == HAL_OK)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_SIZE; + status = HAL_ERROR; + } + + /* Check on error flag */ + if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET) + { + /* Clear error flag */ + LL_I3C_ClearFlag_ERR(hi3c->Instance); + + /* Update handle error code parameter */ + I3C_GetErrorSources(hi3c); + + /* Update returned status value */ + status = HAL_ERROR; + } + + /* At the end of Rx process update state to Previous state */ + I3C_StateUpdate(hi3c); + } + } + + return status; +} + +/** + * @brief Controller private read in interrupt mode. + * @note The function @ref HAL_I3C_AddDescToFrame() must be called before initiate a transfer. + * @note The RxBuf.Size must be equal to the sum of all RxBuf.Size exist in the descriptor. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required reception buffers + * (control buffer, data buffer and status buffer). + * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame(). + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Ctrl_Receive_IT(I3C_HandleTypeDef *hi3c, + I3C_XferTypeDef *pXferData) +{ + HAL_I3C_StateTypeDef handle_state; + HAL_StatusTypeDef status = HAL_OK; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* Check on user parameters */ + if ((pXferData == NULL) || (pXferData->RxBuf.pBuffer == NULL)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* check on the Mode */ + else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* check on the State */ + else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN)) + { + status = HAL_BUSY; + } + else + { + /* Set handle transfer parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY_RX; + hi3c->pXferData = pXferData; + hi3c->RxXferCount = hi3c->pXferData->RxBuf.Size; + hi3c->XferISR = I3C_Ctrl_Rx_ISR; + + /* Check on the Rx threshold to know the Rx treatment process : byte or word */ + if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4) + { + /* Set byte treatment function pointer */ + hi3c->ptrRxFunc = &I3C_ReceiveByteTreatment; + } + else + { + /* Set word treatment function pointer */ + hi3c->ptrRxFunc = &I3C_ReceiveWordTreatment; + } + + /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk + of I3C interrupt handle execution before current process unlock */ + + /* Enable Rx process interrupts */ + I3C_Enable_IRQ(hi3c, I3C_XFER_CONTROLLER_RX_IT); + + /* Initiate a Start condition */ + LL_I3C_RequestTransfer(hi3c->Instance); + } + } + + return status; +} + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief Controller private read in DMA mode. + * @note The function @ref HAL_I3C_AddDescToFrame() must be called before initiate a transfer. + * @note The RxBuf.Size must be equal to the sum of all RxBuf.Size exist in the descriptor. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required reception buffers + * (control buffer, data buffer and status buffer). + * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame(). + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Ctrl_Receive_DMA(I3C_HandleTypeDef *hi3c, + I3C_XferTypeDef *pXferData) +{ + HAL_StatusTypeDef control_dma_status; + HAL_StatusTypeDef rx_dma_status = HAL_OK; + HAL_I3C_StateTypeDef handle_state; + HAL_StatusTypeDef status = HAL_OK; + uint32_t size_align_word; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* Check on user parameters */ + if ((pXferData == NULL) || (pXferData->RxBuf.pBuffer == NULL)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* Check on hdmarx and hdmacr handle */ + else if ((hi3c->hdmarx == NULL) || (hi3c->hdmacr == NULL)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_DMA_PARAM; + status = HAL_ERROR; + } + /* check on the Mode */ + else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* check on the State */ + else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN)) + { + status = HAL_BUSY; + } + else + { + /* Set handle transfer parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY_RX; + hi3c->pXferData = pXferData; + hi3c->RxXferCount = hi3c->pXferData->RxBuf.Size; + hi3c->XferISR = I3C_Ctrl_Rx_DMA_ISR; + + /*------------------------------------ I3C DMA channel for Control Data ----------------------------------------*/ + /* Set the I3C DMA transfer complete callback */ + hi3c->hdmacr->XferCpltCallback = I3C_DMAControlTransmitCplt; + + /* Set the DMA error callback */ + hi3c->hdmacr->XferErrorCallback = I3C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi3c->hdmacr->XferHalfCpltCallback = NULL; + hi3c->hdmacr->XferAbortCallback = NULL; + + /* assert that DMA source and destination width are configured in word */ + assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmacr->Init.SrcDataWidth)); + assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmacr->Init.DestDataWidth)); + + /* Enable the control data DMA channel */ + control_dma_status = HAL_DMA_Start_IT(hi3c->hdmacr, (uint32_t)hi3c->pXferData->CtrlBuf.pBuffer, + (uint32_t)&hi3c->Instance->CR, (hi3c->ControlXferCount * 4U)); + + /*------------------------------------ I3C DMA channel for the Rx Data -----------------------------------------*/ + /* Check if Rx counter different from zero */ + if (hi3c->RxXferCount != 0U) + { + /* Set the I3C DMA transfer complete callback */ + hi3c->hdmarx->XferCpltCallback = I3C_DMADataReceiveCplt; + + /* Set the DMA error callback */ + hi3c->hdmarx->XferErrorCallback = I3C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi3c->hdmarx->XferHalfCpltCallback = NULL; + hi3c->hdmarx->XferAbortCallback = NULL; + + /* Check on the Rx threshold to know the Rx treatment process : byte or word */ + if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4) + { + /* assert that DMA source and destination width are configured in byte */ + assert_param(IS_I3C_DMASOURCEBYTE_VALUE(hi3c->hdmarx->Init.SrcDataWidth)); + assert_param(IS_I3C_DMADESTINATIONBYTE_VALUE(hi3c->hdmarx->Init.DestDataWidth)); + + /* Enable the Rx data DMA channel */ + rx_dma_status = HAL_DMA_Start_IT(hi3c->hdmarx, (uint32_t)&hi3c->Instance->RDR, + (uint32_t)hi3c->pXferData->RxBuf.pBuffer, hi3c->pXferData->RxBuf.Size); + } + else + { + /* assert that DMA source and destination width are configured in word */ + assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmarx->Init.SrcDataWidth)); + assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmarx->Init.DestDataWidth)); + + /* Check to align data size in words */ + if ((hi3c->pXferData->RxBuf.Size % 4U) == 0U) + { + /* Keep the same size */ + size_align_word = hi3c->pXferData->RxBuf.Size; + } + else + { + /* Modify size to be multiple of 4 */ + size_align_word = ((hi3c->pXferData->RxBuf.Size + 4U) - (hi3c->pXferData->RxBuf.Size % 4U)); + } + + /* Enable the Rx data DMA channel */ + rx_dma_status = HAL_DMA_Start_IT(hi3c->hdmarx, (uint32_t)&hi3c->Instance->RDWR, + (uint32_t)hi3c->pXferData->RxBuf.pBuffer, size_align_word); + } + } + + /* Check if DMA process is well started */ + if ((control_dma_status == HAL_OK) && (rx_dma_status == HAL_OK)) + { + /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk + of I3C interrupt handle execution before current process unlock */ + + /* Enable Rx process interrupts */ + I3C_Enable_IRQ(hi3c, I3C_XFER_DMA); + + /* Update the number of remaining data bytes */ + hi3c->ControlXferCount = 0U; + + /* Enable control DMA Request */ + LL_I3C_EnableDMAReq_Control(hi3c->Instance); + + /* Check if Rx counter different from zero */ + if (hi3c->RxXferCount != 0U) + { + /* Update the number of remaining data bytes */ + hi3c->RxXferCount = 0U; + + /* Enable Rx data DMA Request */ + LL_I3C_EnableDMAReq_RX(hi3c->Instance); + } + + /* Initiate a Start condition */ + LL_I3C_RequestTransfer(hi3c->Instance); + } + else + { + /* Set callback to NULL if DMA started */ + if (HAL_DMA_Abort(hi3c->hdmacr) == HAL_OK) + { + hi3c->hdmacr->XferCpltCallback = NULL; + hi3c->hdmacr->XferErrorCallback = NULL; + } + + /* Set callback to NULL if DMA started */ + if (HAL_DMA_Abort(hi3c->hdmarx) == HAL_OK) + { + hi3c->hdmarx->XferCpltCallback = NULL; + hi3c->hdmarx->XferErrorCallback = NULL; + } + + hi3c->ErrorCode = HAL_I3C_ERROR_DMA; + status = HAL_ERROR; + + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + } + + } + } + + return status; +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Controller multiple Direct CCC Command, I3C private or I2C transfer in interrupt mode. + * @note The function @ref HAL_I3C_AddDescToFrame() must be called before initiate a transfer. + * @note The Tx FIFO threshold @ref HAL_I3C_TXFIFO_THRESHOLD_4_4 is not allowed when the transfer descriptor contains + * multiple transmission frames. + * @note This function must be called to transfer read/write I3C or I2C private data or a direct read/write CCC. + * @note The TxBuf.Size must be equal to the sum of all TxBuf.Size exist in the descriptor. + * @note The RxBuf.Size must be equal to the sum of all RxBuf.Size exist in the descriptor. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmit and receive + * buffers (control buffer, data buffers and status buffer). + * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame(). + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Ctrl_MultipleTransfer_IT(I3C_HandleTypeDef *hi3c, + I3C_XferTypeDef *pXferData) +{ + HAL_I3C_StateTypeDef handle_state; + HAL_StatusTypeDef status = HAL_OK; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* Check on user parameters */ + if ((pXferData == NULL) || + ((pXferData->RxBuf.pBuffer == NULL) && (hi3c->RxXferCount != 0U)) || + ((pXferData->TxBuf.pBuffer == NULL) && (hi3c->TxXferCount != 0U))) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* check on the Mode */ + else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* check on the State */ + else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN)) + { + status = HAL_BUSY; + } + else + { + /* Set handle transfer parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY_TX_RX; + hi3c->pXferData = pXferData; + hi3c->TxXferCount = hi3c->pXferData->TxBuf.Size; + hi3c->RxXferCount = hi3c->pXferData->RxBuf.Size; + hi3c->XferISR = I3C_Ctrl_Multiple_Xfer_ISR; + + /* Check on the Tx threshold to know the Tx treatment process : byte or word */ + if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4) + { + /* Set byte treatment function pointer */ + hi3c->ptrTxFunc = &I3C_TransmitByteTreatment; + } + else + { + /* Set word treatment function pointer */ + hi3c->ptrTxFunc = &I3C_TransmitWordTreatment; + } + + /* Check on the Rx threshold to know the Rx treatment process : byte or word */ + if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4) + { + /* Set byte treatment function pointer */ + hi3c->ptrRxFunc = &I3C_ReceiveByteTreatment; + } + else + { + /* Set word treatment function pointer */ + hi3c->ptrRxFunc = &I3C_ReceiveWordTreatment; + } + + /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk + of I3C interrupt handle execution before current process unlock */ + + /* Enable Tx and Rx process interrupts */ + I3C_Enable_IRQ(hi3c, (I3C_XFER_CONTROLLER_TX_IT | I3C_XFER_CONTROLLER_RX_IT)); + + /* Initiate a Start condition */ + LL_I3C_RequestTransfer(hi3c->Instance); + } + } + return status; +} + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief Controller multiple Direct CCC Command, I3C private or I2C transfer in DMA mode. + * @note The function @ref HAL_I3C_AddDescToFrame() must be called before initiate a transfer. + * @note The Tx FIFO threshold @ref HAL_I3C_TXFIFO_THRESHOLD_4_4 is not allowed when the transfer descriptor contains + * multiple transmission frames. + * @note The TxBuf.Size must be equal to the sum of all TxBuf.Size exist in the descriptor. + * @note The RxBuf.Size must be equal to the sum of all RxBuf.Size exist in the descriptor. + * @note This function must be called to transfer read/write private data or a direct read/write CCC command. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmit and receive + * buffers(control buffer, data buffer and status buffer). + * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame(). + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Ctrl_MultipleTransfer_DMA(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData) +{ + HAL_StatusTypeDef control_dma_status; + HAL_StatusTypeDef tx_dma_status = HAL_OK; + HAL_StatusTypeDef rx_dma_status = HAL_OK; + HAL_I3C_StateTypeDef handle_state; + HAL_StatusTypeDef status = HAL_OK; + uint32_t size_align_word; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* Check on user parameters */ + if ((pXferData == NULL) || + ((pXferData->RxBuf.pBuffer == NULL) && (hi3c->RxXferCount != 0U)) || + ((pXferData->TxBuf.pBuffer == NULL) && (hi3c->TxXferCount != 0U))) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* Check on hdmatx, hdmarx and hdmacr handle */ + else if ((hi3c->hdmatx == NULL) || (hi3c->hdmacr == NULL) || (hi3c->hdmarx == NULL)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_DMA_PARAM; + status = HAL_ERROR; + } + /* check on the Mode */ + else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* check on the State */ + else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN)) + { + status = HAL_BUSY; + } + else + { + /* Set handle transfer parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY_TX_RX; + hi3c->pXferData = pXferData; + hi3c->RxXferCount = hi3c->pXferData->RxBuf.Size; + hi3c->TxXferCount = hi3c->pXferData->TxBuf.Size; + hi3c->XferISR = I3C_Ctrl_Multiple_Xfer_DMA_ISR; + + /*------------------------------------ I3C DMA channel for Control Data -------------------------------------*/ + /* Set the I3C DMA transfer complete callback */ + hi3c->hdmacr->XferCpltCallback = I3C_DMAControlTransmitCplt; + + /* Set the DMA error callback */ + hi3c->hdmacr->XferErrorCallback = I3C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi3c->hdmacr->XferHalfCpltCallback = NULL; + hi3c->hdmacr->XferAbortCallback = NULL; + + /* assert that DMA source and destination width are configured in word */ + assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmacr->Init.SrcDataWidth)); + assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmacr->Init.DestDataWidth)); + + /* Enable the control data DMA channel */ + control_dma_status = HAL_DMA_Start_IT(hi3c->hdmacr, (uint32_t)hi3c->pXferData->CtrlBuf.pBuffer, + (uint32_t)&hi3c->Instance->CR, (hi3c->ControlXferCount * 4U)); + + /*------------------------------------ I3C DMA channel for the Rx Data --------------------------------*/ + /* Check if Rx counter different from zero */ + if (hi3c->RxXferCount != 0U) + { + /* Set the I3C DMA transfer complete callback */ + hi3c->hdmarx->XferCpltCallback = I3C_DMADataReceiveCplt; + + /* Set the DMA error callback */ + hi3c->hdmarx->XferErrorCallback = I3C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi3c->hdmarx->XferHalfCpltCallback = NULL; + hi3c->hdmarx->XferAbortCallback = NULL; + + /* Check on the Rx threshold to know the Rx treatment process : byte or word */ + if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4) + { + /* assert that DMA source and destination width are configured in byte */ + assert_param(IS_I3C_DMASOURCEBYTE_VALUE(hi3c->hdmarx->Init.SrcDataWidth)); + assert_param(IS_I3C_DMADESTINATIONBYTE_VALUE(hi3c->hdmarx->Init.DestDataWidth)); + + /* Enable the Rx data DMA channel */ + rx_dma_status = HAL_DMA_Start_IT(hi3c->hdmarx, (uint32_t)&hi3c->Instance->RDR, + (uint32_t)hi3c->pXferData->RxBuf.pBuffer, hi3c->pXferData->RxBuf.Size); + } + else + { + /* assert that DMA source and destination width are configured in word */ + assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmarx->Init.SrcDataWidth)); + assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmarx->Init.DestDataWidth)); + + /* Check to align data size in words */ + if ((hi3c->pXferData->RxBuf.Size % 4U) == 0U) + { + /* Keep the same size */ + size_align_word = hi3c->pXferData->RxBuf.Size; + } + else + { + /* Modify size to be multiple of 4 */ + size_align_word = ((hi3c->pXferData->RxBuf.Size + 4U) - (hi3c->pXferData->RxBuf.Size % 4U)); + } + + /* Enable the Rx data DMA channel */ + rx_dma_status = HAL_DMA_Start_IT(hi3c->hdmarx, (uint32_t)&hi3c->Instance->RDWR, + (uint32_t)hi3c->pXferData->RxBuf.pBuffer, size_align_word); + } + } + + /*------------------------------------ I3C DMA channel for the Tx Data --------------------------------*/ + /* Check if Tx counter different from zero */ + if (hi3c->TxXferCount != 0U) + { + /* Set the I3C DMA transfer complete callback */ + hi3c->hdmatx->XferCpltCallback = I3C_DMADataTransmitCplt; + + /* Set the DMA error callback */ + hi3c->hdmatx->XferErrorCallback = I3C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi3c->hdmatx->XferHalfCpltCallback = NULL; + hi3c->hdmatx->XferAbortCallback = NULL; + + /* Check on the Tx threshold to know the Tx treatment process : byte or word */ + if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4) + { + /* assert that DMA source and destination width are configured in byte */ + assert_param(IS_I3C_DMASOURCEBYTE_VALUE(hi3c->hdmatx->Init.SrcDataWidth)); + assert_param(IS_I3C_DMADESTINATIONBYTE_VALUE(hi3c->hdmatx->Init.DestDataWidth)); + + /* Enable the Tx data DMA channel */ + tx_dma_status = HAL_DMA_Start_IT(hi3c->hdmatx, (uint32_t)hi3c->pXferData->TxBuf.pBuffer, + (uint32_t)&hi3c->Instance->TDR, hi3c->pXferData->TxBuf.Size); + } + else + { + /* assert that DMA source and destination width are configured in word */ + assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmatx->Init.SrcDataWidth)); + assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmatx->Init.DestDataWidth)); + + /* Check to align data size in words */ + if ((hi3c->pXferData->TxBuf.Size % 4U) == 0U) + { + /* Keep the same size */ + size_align_word = hi3c->pXferData->TxBuf.Size; + } + else + { + /* Modify size to be multiple of 4 */ + size_align_word = ((hi3c->pXferData->TxBuf.Size + 4U) - (hi3c->pXferData->TxBuf.Size % 4U)); + } + + /* Enable the Tx data DMA channel */ + tx_dma_status = HAL_DMA_Start_IT(hi3c->hdmatx, (uint32_t)hi3c->pXferData->TxBuf.pBuffer, + (uint32_t)&hi3c->Instance->TDWR, size_align_word); + } + } + + /* Check if DMA process is well started */ + if ((control_dma_status == HAL_OK) && (tx_dma_status == HAL_OK) && (rx_dma_status == HAL_OK)) + { + /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk + of I3C interrupt handle execution before current process unlock */ + + /* Enable Tx process interrupts */ + I3C_Enable_IRQ(hi3c, I3C_XFER_DMA); + + /* Update the number of remaining data bytes */ + hi3c->ControlXferCount = 0U; + + /* Enable control DMA Request */ + LL_I3C_EnableDMAReq_Control(hi3c->Instance); + + /* Check if Rx counter different from zero */ + if (hi3c->RxXferCount != 0U) + { + /* Update the number of remaining data bytes */ + hi3c->RxXferCount = 0U; + + /* Enable Rx data DMA Request */ + LL_I3C_EnableDMAReq_RX(hi3c->Instance); + } + + /* Check if Tx counter different from zero */ + if (hi3c->TxXferCount != 0U) + { + /* Update the number of remaining data bytes */ + hi3c->TxXferCount = 0U; + + /* Enable Tx data DMA Request */ + LL_I3C_EnableDMAReq_TX(hi3c->Instance); + } + + /* Initiate a Start condition */ + LL_I3C_RequestTransfer(hi3c->Instance); + } + else + { + /* Set callback to NULL if DMA started */ + if (HAL_DMA_Abort(hi3c->hdmacr) == HAL_OK) + { + hi3c->hdmacr->XferCpltCallback = NULL; + hi3c->hdmacr->XferErrorCallback = NULL; + } + + /* Set callback to NULL if DMA started */ + if (HAL_DMA_Abort(hi3c->hdmatx) == HAL_OK) + { + hi3c->hdmatx->XferCpltCallback = NULL; + hi3c->hdmatx->XferErrorCallback = NULL; + } + + /* Set callback to NULL if DMA started */ + if (HAL_DMA_Abort(hi3c->hdmarx) == HAL_OK) + { + hi3c->hdmarx->XferCpltCallback = NULL; + hi3c->hdmarx->XferErrorCallback = NULL; + } + + hi3c->ErrorCode = HAL_I3C_ERROR_DMA; + status = HAL_ERROR; + + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + } + } + } + return status; +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Controller assign dynamic address (send a broadcast ENTDAA CCC command) in polling mode. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @param target_payload : [IN/OUT] Pointer to the returned target payload value. + * @param dynOption : [IN] Parameter indicates the Dynamic address assignment option. + * It can be one value of @ref I3C_DYNAMIC_ADDRESS_OPTION_DEFINITION. + * @param timeout : [IN] Timeout duration in millisecond. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Ctrl_DynAddrAssign(I3C_HandleTypeDef *hi3c, + uint64_t *target_payload, + uint32_t dynOption, + uint32_t timeout) +{ + uint32_t tickstart; + HAL_I3C_StateTypeDef handle_state; + HAL_StatusTypeDef status = HAL_OK; + + /* check on parameters */ + assert_param(IS_I3C_ENTDAA_OPTION(dynOption)); + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Get I3C handle state */ + handle_state = hi3c->State; + + if (target_payload == NULL) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* check on the Mode */ + else if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + else + { + /* Launch a RSTDAA procedure before launch ENTDAA */ + if ((dynOption == I3C_RSTDAA_THEN_ENTDAA) && + ((handle_state == HAL_I3C_STATE_READY) || (handle_state == HAL_I3C_STATE_LISTEN))) + { + /* Set handle transfer parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY_DAA; + + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + + /* Enable arbitration header */ + LL_I3C_EnableArbitrationHeader(hi3c->Instance); + + /* Write CCC information in the control register */ + LL_I3C_ControllerHandleCCC(hi3c->Instance, I3C_BROADCAST_RSTDAA, 0U, LL_I3C_GENERATE_STOP); + + /* Wait Frame completion flag */ + status = I3C_WaitOnFlagUntilTimeout(hi3c, HAL_I3C_FLAG_FCF, RESET, timeout, tickstart); + + /* Clear frame complete flag */ + if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_FCF) == SET) + { + LL_I3C_ClearFlag_FC(hi3c->Instance); + } + + /* Check on error flag */ + if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET) + { + /* Clear error flag */ + LL_I3C_ClearFlag_ERR(hi3c->Instance); + + /* Update handle error code parameter */ + I3C_GetErrorSources(hi3c); + + status = HAL_ERROR; + } + + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + } + + if (status == HAL_OK) + { + /* check on the State */ + if ((handle_state == HAL_I3C_STATE_READY) || (handle_state == HAL_I3C_STATE_LISTEN) || + (handle_state == HAL_I3C_STATE_BUSY_DAA)) + { + /* Check on the state */ + if (handle_state != HAL_I3C_STATE_BUSY_DAA) + { + /* Set handle transfer parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY_DAA; + + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + + /* Enable arbitration header */ + LL_I3C_EnableArbitrationHeader(hi3c->Instance); + + /* Write CCC information in the control register */ + LL_I3C_ControllerHandleCCC(hi3c->Instance, I3C_BROADCAST_ENTDAA, 0U, LL_I3C_GENERATE_STOP); + } + else + { + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + } + + /* Wait frame complete flag or TX FIFO not full flag until timeout */ + status = I3C_WaitOnDAAUntilTimeout(hi3c, timeout, tickstart); + + /* Check TX FIFO not full flag */ + if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_TXFNFF) == SET) + { + /* Check on the Rx FIFO threshold to know the Rx treatment process : byte or word */ + if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4) + { + /* For loop to get target payload */ + for (uint32_t index = 0U; index < 8U; index++) + { + /* Retrieve payload byte by byte */ + *target_payload |= (uint64_t)((uint64_t)LL_I3C_ReceiveData8(hi3c->Instance) << (index * 8U)); + } + } + else + { + /* Retrieve first 32 bits payload */ + *target_payload = (uint64_t)LL_I3C_ReceiveData32(hi3c->Instance); + + /* Retrieve second 32 bits payload */ + *target_payload |= (uint64_t)((uint64_t)LL_I3C_ReceiveData32(hi3c->Instance) << 32U); + } + + status = HAL_BUSY; + } + /* Check on frame complete flag */ + else + { + /* Clear frame complete flag */ + if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_FCF) == SET) + { + /* Clear frame complete flag */ + LL_I3C_ClearFlag_FC(hi3c->Instance); + } + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + } + } + else + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + } + } + } + + return status; +} + +/** + * @brief Controller assign dynamic address (send a broadcast ENTDAA CCC command) in interrupt mode. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param dynOption : [IN] Parameter indicates the Dynamic address assignment option. + * It can be one value of @ref I3C_DYNAMIC_ADDRESS_OPTION_DEFINITION. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Ctrl_DynAddrAssign_IT(I3C_HandleTypeDef *hi3c, uint32_t dynOption) +{ + HAL_I3C_StateTypeDef handle_state; + HAL_StatusTypeDef status = HAL_OK; + + /* check on parameters */ + assert_param(IS_I3C_ENTDAA_OPTION(dynOption)); + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* check on the Mode */ + if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* check on the State */ + else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN)) + { + status = HAL_BUSY; + } + else + { + /* Set handle transfer parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY_DAA; + hi3c->XferISR = I3C_Ctrl_DAA_ISR; + + /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk + of I3C interrupt handle execution before current process unlock */ + + /* Enable Dynamic Address Assignment process interrupts */ + I3C_Enable_IRQ(hi3c, I3C_XFER_CONTROLLER_DAA_IT); + + /* Enable arbitration header */ + LL_I3C_EnableArbitrationHeader(hi3c->Instance); + + /* Launch a RSTDAA procedure before launch ENTDAA */ + if (dynOption == I3C_RSTDAA_THEN_ENTDAA) + { + /* Write RSTDAA CCC information in the control register */ + LL_I3C_ControllerHandleCCC(hi3c->Instance, I3C_BROADCAST_RSTDAA, 0U, LL_I3C_GENERATE_RESTART); + } + else + { + /* Write ENTDAA CCC information in the control register */ + LL_I3C_ControllerHandleCCC(hi3c->Instance, I3C_BROADCAST_ENTDAA, 0U, LL_I3C_GENERATE_STOP); + } + } + } + + return status; +} + +/** + * @brief Controller set dynamic address. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param devAddress : [IN] Value of the dynamic address to be assigned. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Ctrl_SetDynAddr(I3C_HandleTypeDef *hi3c, uint8_t devAddress) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check if Tx FIFO requests data */ + if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_TXFNFF) == SET) + { + /* Write device address in the TDR register */ + LL_I3C_TransmitData8(hi3c->Instance, devAddress); + } + else + { + status = HAL_ERROR; + } + } + + return status; +} + +/** + * @brief Check if I3C target device is ready for communication. + * @param hi3c : [IN] Pointer to a I3C_HandleTypeDef structure that contains + * the configuration information for the specified I3C. + * @param devAddress : [IN] Value of the device dynamic address. + * @param trials : [IN] Number of trials + * @param timeout : [IN] Timeout duration + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Ctrl_IsDeviceI3C_Ready(I3C_HandleTypeDef *hi3c, + uint8_t devAddress, + uint32_t trials, + uint32_t timeout) +{ + I3C_DeviceTypeDef device; + HAL_StatusTypeDef status; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Initiate a device address */ + device.Address = devAddress; + + /* Initiate a message type */ + device.MessageType = LL_I3C_CONTROLLER_MTYPE_PRIVATE; + + /* Check if the device is ready*/ + status = I3C_Ctrl_IsDevice_Ready(hi3c, &device, trials, timeout); + } + + return status; +} + +/** + * @brief Check if I2C target device is ready for communication. + * @param hi3c : [IN] Pointer to a I3C_HandleTypeDef structure that contains + * the configuration information for the specified I3C. + * @param devAddress : [IN] Value of the device dynamic address. + * @param trials : [IN] Number of trials + * @param timeout : [IN] Timeout duration + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Ctrl_IsDeviceI2C_Ready(I3C_HandleTypeDef *hi3c, + uint8_t devAddress, + uint32_t trials, + uint32_t timeout) +{ + I3C_DeviceTypeDef device; + HAL_StatusTypeDef status; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Initiate a device address */ + device.Address = devAddress; + + /* Initiate a message type */ + device.MessageType = LL_I3C_CONTROLLER_MTYPE_LEGACY_I2C; + + /* Check if the device is ready*/ + status = I3C_Ctrl_IsDevice_Ready(hi3c, &device, trials, timeout); + } + + return status; +} +/** + * @} + */ + +/** @defgroup I3C_Exported_Functions_Group6 Target operational functions. + * @brief I3C target operational functions. + * +@verbatim + ======================================================================================================================= + ##### Target operational functions ##### + ======================================================================================================================= + [..] This subsection provides a set of functions allowing to manage target I3C operation. + + (+) Call the function HAL_I3C_Tgt_Transmit() to transmit private data in polling mode. + (+) Call the function HAL_I3C_Tgt_Transmit_IT() to transmit private data in interrupt mode. + (+) Call the function HAL_I3C_Tgt_Transmit_DMA() to transmit private data in DMA mode. + (+) Call the function HAL_I3C_Tgt_Receive() to receive private data in polling mode. + (+) Call the function HAL_I3C_Tgt_Receive_IT() to receive private data in interrupt mode. + (+) Call the function HAL_I3C_Tgt_Receive_DMA() to receive private data in DMA mode. + (+) Call the function HAL_I3C_Tgt_ControlRoleReq() to send a control-role request in polling mode. + (+) Call the function HAL_I3C_Tgt_ControlRoleReq_IT() to send a control-role request in interrupt mode. + (+) Call the function HAL_I3C_Tgt_HotJoinReq() to send a Hot-Join request in polling mode. + (+) Call the function HAL_I3C_Tgt_HotJoinReq_IT() to send a Hot-Join request in interrupt mode. + (+) Call the function HAL_I3C_Tgt_IBIReq() to send an IBI request in polling mode. + (+) Call the function HAL_I3C_Tgt_IBIReq_IT() to send an IBI request in interrupt mode. + + (+) Those functions are called only when mode is Target. + +@endverbatim + * @{ + */ + +/** + * @brief Target transmit private data in polling mode. + * @note Target FIFO preload data is forced within this API for timing purpose. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmission buffers + * information (Pointer to the Tx buffer (TxBuf.pBuffer) and size of data + * to transmit in bytes (TxBuf.Size)). + * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame(). + * @param timeout : [IN] Timeout duration in millisecond. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Tgt_Transmit(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData, uint32_t timeout) +{ + uint32_t tickstart; + HAL_StatusTypeDef status = HAL_OK; + HAL_I3C_StateTypeDef handle_state; + uint32_t it_source; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + it_source = READ_REG(hi3c->Instance->IER); + + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* Check on user parameters */ + if ((pXferData == NULL) || (pXferData->TxBuf.pBuffer == NULL) || (pXferData->TxBuf.Size == 0U)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* check on the Mode */ + else if (hi3c->Mode != HAL_I3C_MODE_TARGET) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* check on the State */ + else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN)) + { + status = HAL_BUSY; + } + /* check if DEF or GRP CCC notifications are enabled */ + else if ((I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_DEFIE) != RESET) || + (I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_GRPIE) != RESET)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* Verify the dynamic address validity */ + else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + else + { + /* Set handle transfer parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY_TX; + hi3c->pXferData = pXferData; + hi3c->TxXferCount = pXferData->TxBuf.Size; + + /* Check on the Tx threshold to know the Tx treatment process : byte or word */ + if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4) + { + /* Set byte treatment function pointer */ + hi3c->ptrTxFunc = &I3C_TransmitByteTreatment; + } + else + { + /* Set word treatment function pointer */ + hi3c->ptrTxFunc = &I3C_TransmitWordTreatment; + } + + /* Set Preload information */ + LL_I3C_ConfigTxPreload(hi3c->Instance, (uint16_t)hi3c->pXferData->TxBuf.Size); + + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + + /* Do while until FC (Frame Complete) is set or timeout */ + do + { + /* Call transmit treatment function */ + hi3c->ptrTxFunc(hi3c); + + /* Check for the Timeout */ + if (timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > timeout) || (timeout == 0U)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_TIMEOUT; + status = HAL_TIMEOUT; + + break; + } + } + /* Exit loop on Frame complete or error flags */ + } while ((READ_REG(hi3c->Instance->EVR) & (I3C_EVR_FCF | I3C_EVR_ERRF)) == 0U); + + /* Clear frame complete flag */ + if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_FCF) == SET) + { + LL_I3C_ClearFlag_FC(hi3c->Instance); + } + + /* Check if all data bytes are transmitted */ + if ((LL_I3C_GetXferDataCount(hi3c->Instance) != hi3c->pXferData->TxBuf.Size) && (status == HAL_OK)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_SIZE; + status = HAL_ERROR; + } + + /* Check on error flag */ + if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET) + { + /* Clear error flag */ + LL_I3C_ClearFlag_ERR(hi3c->Instance); + + /* Update handle error code parameter */ + I3C_GetErrorSources(hi3c); + + /* Update returned status value */ + status = HAL_ERROR; + } + + /* At the end of Tx process update state to Previous state */ + I3C_StateUpdate(hi3c); + } + } + + return status; +} + +/** + * @brief Target transmit private data in interrupt mode. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmission buffers + * information (Pointer to the Tx buffer (TxBuf.pBuffer) and size of data + * to transmit in bytes (TxBuf.Size)). + * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame(). + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Tgt_Transmit_IT(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData) +{ + HAL_I3C_StateTypeDef handle_state; + HAL_StatusTypeDef status = HAL_OK; + uint32_t it_source; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + it_source = READ_REG(hi3c->Instance->IER); + + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* Check on user parameters */ + if ((pXferData == NULL) || (pXferData->TxBuf.pBuffer == NULL) || (pXferData->TxBuf.Size == 0U)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* check on the Mode */ + else if (hi3c->Mode != HAL_I3C_MODE_TARGET) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* check on the State */ + else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN)) + { + status = HAL_BUSY; + } + /* check if DEF and GRP CCC notifications are enabled */ + else if ((I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_DEFIE) != RESET) || + (I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_GRPIE) != RESET)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* Verify the dynamic address validity */ + else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + + status = HAL_ERROR; + } + else + { + /* Set handle transfer parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY_TX; + hi3c->pXferData = pXferData; + hi3c->TxXferCount = pXferData->TxBuf.Size; + hi3c->XferISR = I3C_Tgt_Tx_ISR; + + /* Check on the Tx threshold to know the Tx treatment process : byte or word */ + if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4) + { + /* Set byte treatment function pointer */ + hi3c->ptrTxFunc = &I3C_TransmitByteTreatment; + } + else + { + /* Set word treatment function pointer */ + hi3c->ptrTxFunc = &I3C_TransmitWordTreatment; + } + + /* Set Preload information */ + LL_I3C_ConfigTxPreload(hi3c->Instance, (uint16_t)hi3c->pXferData->TxBuf.Size); + + /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk + of I3C interrupt handle execution before current process unlock */ + + /* Enable Tx process interrupts */ + I3C_Enable_IRQ(hi3c, I3C_XFER_TARGET_TX_IT); + } + } + + return status; +} + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief Target transmit private data in DMA mode. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required transmission buffers + * information (Pointer to the Tx buffer (TxBuf.pBuffer) and size of data + * to transmit in bytes (TxBuf.Size)). + * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame(). + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Tgt_Transmit_DMA(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData) +{ + HAL_StatusTypeDef tx_dma_status; + HAL_I3C_StateTypeDef handle_state; + HAL_StatusTypeDef status = HAL_OK; + uint32_t size_align_word; + uint32_t it_source; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + it_source = READ_REG(hi3c->Instance->IER); + + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* Check on user parameters */ + if ((pXferData == NULL) || (pXferData->TxBuf.pBuffer == NULL) || (pXferData->TxBuf.Size == 0U)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* Check on hdmatx handle */ + else if (hi3c->hdmatx == NULL) + { + hi3c->ErrorCode = HAL_I3C_ERROR_DMA_PARAM; + status = HAL_ERROR; + } + /* check on the Mode */ + else if (hi3c->Mode != HAL_I3C_MODE_TARGET) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* check on the State */ + else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN)) + { + status = HAL_BUSY; + } + /* check if DEF and GRP CCC notifications are enabled */ + else if ((I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_DEFIE) != RESET) || + (I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_GRPIE) != RESET)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* Verify the dynamic address validity */ + else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + else + { + /* Set handle transfer parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY_TX; + hi3c->pXferData = pXferData; + hi3c->TxXferCount = pXferData->TxBuf.Size; + hi3c->XferISR = I3C_Tgt_Tx_DMA_ISR; + + /* Set Preload information */ + LL_I3C_ConfigTxPreload(hi3c->Instance, (uint16_t)hi3c->pXferData->TxBuf.Size); + + /*------------------------------------ I3C DMA channel for the Tx Data -----------------------------------------*/ + /* Set the I3C DMA transfer complete callback */ + hi3c->hdmatx->XferCpltCallback = I3C_DMADataTransmitCplt; + + /* Set the DMA error callback */ + hi3c->hdmatx->XferErrorCallback = I3C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi3c->hdmatx->XferHalfCpltCallback = NULL; + hi3c->hdmatx->XferAbortCallback = NULL; + + /* Check on the Tx threshold to know the Tx treatment process : byte or word */ + if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_1_4) + { + /* assert that DMA source and destination width are configured in byte */ + assert_param(IS_I3C_DMASOURCEBYTE_VALUE(hi3c->hdmatx->Init.SrcDataWidth)); + assert_param(IS_I3C_DMADESTINATIONBYTE_VALUE(hi3c->hdmatx->Init.DestDataWidth)); + + /* Enable the Tx data DMA channel */ + tx_dma_status = HAL_DMA_Start_IT(hi3c->hdmatx, (uint32_t)hi3c->pXferData->TxBuf.pBuffer, + (uint32_t)&hi3c->Instance->TDR, hi3c->pXferData->TxBuf.Size); + } + else + { + /* assert that DMA source and destination width are configured in word */ + assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmatx->Init.SrcDataWidth)); + assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmatx->Init.DestDataWidth)); + + /* Check to align data size in words */ + if ((hi3c->pXferData->TxBuf.Size % 4U) == 0U) + { + /* Keep the same size */ + size_align_word = hi3c->pXferData->TxBuf.Size; + } + else + { + /* Modify size to be multiple of 4 */ + size_align_word = ((hi3c->pXferData->TxBuf.Size + 4U) - (hi3c->pXferData->TxBuf.Size % 4U)); + } + + /* Enable the Tx data DMA channel */ + tx_dma_status = HAL_DMA_Start_IT(hi3c->hdmatx, (uint32_t)hi3c->pXferData->TxBuf.pBuffer, + (uint32_t)&hi3c->Instance->TDWR, size_align_word); + } + + /* Check if DMA process is well started */ + if (tx_dma_status == HAL_OK) + { + /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk + of I3C interrupt handle execution before current process unlock */ + + /* Enable Tx process interrupts */ + I3C_Enable_IRQ(hi3c, I3C_XFER_DMA); + + /* Update the number of remaining data bytes */ + hi3c->TxXferCount = 0U; + + /* Enable Tx data DMA Request */ + LL_I3C_EnableDMAReq_TX(hi3c->Instance); + } + else + { + /* Set callback to NULL if DMA started */ + hi3c->hdmatx->XferCpltCallback = NULL; + hi3c->hdmatx->XferErrorCallback = NULL; + + hi3c->ErrorCode = HAL_I3C_ERROR_DMA; + status = HAL_ERROR; + + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + } + } + } + + return status; +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Target receive private data in polling mode. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required reception buffers + * information (Pointer to the Rx buffer (RxBuf.pBuffer) and size of data + * to be received in bytes (RxBuf.Size)). + * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame(). + * @param timeout : [IN] Timeout duration in millisecond. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Tgt_Receive(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData, uint32_t timeout) +{ + uint32_t tickstart; + HAL_StatusTypeDef status = HAL_OK; + HAL_I3C_StateTypeDef handle_state; + uint32_t it_source; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + it_source = READ_REG(hi3c->Instance->IER); + + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* Check on user parameters */ + if ((pXferData == NULL) || (pXferData->RxBuf.pBuffer == NULL) || (pXferData->RxBuf.Size == 0U)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* check on the Mode */ + else if (hi3c->Mode != HAL_I3C_MODE_TARGET) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* check on the State */ + else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN)) + { + status = HAL_BUSY; + } + /* check if DEF and GRP CCC notifications are enabled */ + else if ((I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_DEFIE) != RESET) || + (I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_GRPIE) != RESET)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* Verify the dynamic address validity */ + else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + else + { + /* Set handle transfer parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY_RX; + hi3c->pXferData = pXferData; + hi3c->RxXferCount = pXferData->RxBuf.Size; + + /* Check on the Rx threshold to know the Rx treatment process : byte or word */ + if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4) + { + /* Set byte treatment function pointer */ + hi3c->ptrRxFunc = &I3C_ReceiveByteTreatment; + } + else + { + /* Set word treatment function pointer */ + hi3c->ptrRxFunc = &I3C_ReceiveWordTreatment; + } + + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + + /* Do while until FC (Frame Complete) is set or timeout */ + do + { + if (hi3c->RxXferCount > 0U) + { + /* Call receive treatment function */ + hi3c->ptrRxFunc(hi3c); + } + + /* Check for the Timeout */ + if (timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > timeout) || (timeout == 0U)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_TIMEOUT; + status = HAL_TIMEOUT; + + break; + } + } + /* Exit loop on Frame complete or error flags */ + } while ((READ_REG(hi3c->Instance->EVR) & (I3C_EVR_FCF | I3C_EVR_ERRF)) == 0U); + + /* Clear frame complete flag */ + if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_FCF) == SET) + { + LL_I3C_ClearFlag_FC(hi3c->Instance); + } + + /* Check if all data bytes are received */ + if ((LL_I3C_GetXferDataCount(hi3c->Instance) != hi3c->pXferData->RxBuf.Size) && (status == HAL_OK)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_SIZE; + status = HAL_ERROR; + } + + /* Check on error flag */ + if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET) + { + /* Clear error flag */ + LL_I3C_ClearFlag_ERR(hi3c->Instance); + + /* Update handle error code parameter */ + I3C_GetErrorSources(hi3c); + + status = HAL_ERROR; + } + + /* At the end of Rx process update state to previous state */ + I3C_StateUpdate(hi3c); + } + } + + return status; +} + +/** + * @brief Target receive private data in interrupt mode. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required reception buffers + * information (Pointer to the Rx buffer (RxBuf.pBuffer) and size of data + * to be received in bytes (RxBuf.Size)). + * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame(). + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Tgt_Receive_IT(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData) +{ + HAL_I3C_StateTypeDef handle_state; + HAL_StatusTypeDef status = HAL_OK; + uint32_t it_source; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + it_source = READ_REG(hi3c->Instance->IER); + + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* Check on user parameters */ + if ((pXferData == NULL) || (pXferData->RxBuf.pBuffer == NULL) || (pXferData->RxBuf.Size == 0U)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* check on the Mode */ + else if (hi3c->Mode != HAL_I3C_MODE_TARGET) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* check on the State */ + else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN)) + { + status = HAL_BUSY; + } + /* check if DEF and GRP CCC notifications are enabled */ + else if ((I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_DEFIE) != RESET) || + (I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_GRPIE) != RESET)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* Verify the dynamic address validity */ + else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + else + { + /* Set handle transfer parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY_RX; + hi3c->pXferData = pXferData; + hi3c->RxXferCount = pXferData->RxBuf.Size; + hi3c->XferISR = I3C_Tgt_Rx_ISR; + + /* Check on the Rx threshold to know the Rx treatment process : byte or word */ + if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4) + { + /* Set byte treatment function pointer */ + hi3c->ptrRxFunc = &I3C_ReceiveByteTreatment; + } + else + { + /* Set word treatment function pointer */ + hi3c->ptrRxFunc = &I3C_ReceiveWordTreatment; + } + + /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk + of I3C interrupt handle execution before current process unlock */ + + /* Enable Rx process interrupts */ + I3C_Enable_IRQ(hi3c, I3C_XFER_TARGET_RX_IT); + } + } + + return status; +} + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief Target receive private data in DMA mode. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param pXferData : [IN] Pointer to an I3C_XferTypeDef structure that contains required reception buffers + * information (Pointer to the Rx buffer (RxBuf.pBuffer) and size of data + * to be received in bytes (RxBuf.Size)). + * This value contain transfer data after called @ref HAL_I3C_AddDescToFrame(). + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Tgt_Receive_DMA(I3C_HandleTypeDef *hi3c, I3C_XferTypeDef *pXferData) +{ + HAL_StatusTypeDef rx_dma_status; + HAL_I3C_StateTypeDef handle_state; + HAL_StatusTypeDef status = HAL_OK; + uint32_t size_align_word; + uint32_t it_source; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + it_source = READ_REG(hi3c->Instance->IER); + + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* Check on user parameters */ + if ((pXferData == NULL) || (pXferData->RxBuf.pBuffer == NULL) || (pXferData->RxBuf.Size == 0U)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* Check on hdmarx handle */ + else if (hi3c->hdmarx == NULL) + { + hi3c->ErrorCode = HAL_I3C_ERROR_DMA_PARAM; + status = HAL_ERROR; + + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + } + /* check on the Mode */ + else if (hi3c->Mode != HAL_I3C_MODE_TARGET) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* check on the State */ + else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN)) + { + status = HAL_BUSY; + } + /* check if DEF and GRP CCC notifications are enabled */ + else if ((I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_DEFIE) != RESET) || + (I3C_CHECK_IT_SOURCE(it_source, HAL_I3C_IT_GRPIE) != RESET)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* Verify the dynamic address validity */ + else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + else + { + /* Set handle transfer parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY_RX; + hi3c->pXferData = pXferData; + hi3c->RxXferCount = pXferData->RxBuf.Size; + hi3c->XferISR = I3C_Tgt_Rx_DMA_ISR; + + /*------------------------------------ I3C DMA channel for the Rx Data ---------------------------------------*/ + /* Set the I3C DMA transfer complete callback */ + hi3c->hdmarx->XferCpltCallback = I3C_DMADataReceiveCplt; + + /* Set the DMA error callback */ + hi3c->hdmarx->XferErrorCallback = I3C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi3c->hdmarx->XferHalfCpltCallback = NULL; + hi3c->hdmarx->XferAbortCallback = NULL; + + /* Check on the Rx threshold to know the Rx treatment process : byte or word */ + if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4) + { + /* assert that DMA source and destination width are configured in byte */ + assert_param(IS_I3C_DMASOURCEBYTE_VALUE(hi3c->hdmarx->Init.SrcDataWidth)); + assert_param(IS_I3C_DMADESTINATIONBYTE_VALUE(hi3c->hdmarx->Init.DestDataWidth)); + + /* Enable the Rx data DMA channel */ + rx_dma_status = HAL_DMA_Start_IT(hi3c->hdmarx, (uint32_t)&hi3c->Instance->RDR, + (uint32_t)hi3c->pXferData->RxBuf.pBuffer, hi3c->pXferData->RxBuf.Size); + } + else + { + /* assert that DMA source and destination width are configured in word */ + assert_param(IS_I3C_DMASOURCEWORD_VALUE(hi3c->hdmarx->Init.SrcDataWidth)); + assert_param(IS_I3C_DMADESTINATIONWORD_VALUE(hi3c->hdmarx->Init.DestDataWidth)); + + /* Check to align data size in words */ + if ((hi3c->pXferData->RxBuf.Size % 4U) == 0U) + { + /* Keep the same size */ + size_align_word = hi3c->pXferData->RxBuf.Size; + } + else + { + /* Modify size to be multiple of 4 */ + size_align_word = ((hi3c->pXferData->RxBuf.Size + 4U) - (hi3c->pXferData->RxBuf.Size % 4U)); + } + + /* Enable the Rx data DMA channel */ + rx_dma_status = HAL_DMA_Start_IT(hi3c->hdmarx, (uint32_t)&hi3c->Instance->RDWR, + (uint32_t)hi3c->pXferData->RxBuf.pBuffer, size_align_word); + } + + if (rx_dma_status == HAL_OK) + { + /* Note : The I3C interrupts must be enabled after unlocking current process to avoid the risk + of I3C interrupt handle execution before current process unlock */ + + /* Enable Rx process interrupts */ + I3C_Enable_IRQ(hi3c, I3C_XFER_DMA); + + /* Update the number of remaining data bytes */ + hi3c->RxXferCount = 0U; + + /* Enable Rx data DMA Request */ + LL_I3C_EnableDMAReq_RX(hi3c->Instance); + } + else + { + /* Set callback to NULL if DMA started */ + hi3c->hdmarx->XferCpltCallback = NULL; + hi3c->hdmarx->XferErrorCallback = NULL; + + hi3c->ErrorCode = HAL_I3C_ERROR_DMA; + status = HAL_ERROR; + + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + } + } + } + + return status; +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Target send control role request in polling mode. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param timeout : [IN] Timeout duration in millisecond. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Tgt_ControlRoleReq(I3C_HandleTypeDef *hi3c, uint32_t timeout) +{ + uint32_t tickstart; + HAL_I3C_StateTypeDef handle_state; + HAL_StatusTypeDef status = HAL_OK; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* check on the Mode */ + if (hi3c->Mode != HAL_I3C_MODE_TARGET) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* check on the State */ + else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN)) + { + status = HAL_BUSY; + } + /* Verify the dynamic address validity */ + else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + else + { + /* Verify if control role request feature is enabled */ + if (LL_I3C_IsEnabledControllerRoleReq(hi3c->Instance) != 1U) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + } + + if (status == HAL_OK) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY; + + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + + /* Request Controllership */ + LL_I3C_TargetHandleMessage(hi3c->Instance, LL_I3C_TARGET_MTYPE_CONTROLLER_ROLE_REQ, 0U); + + /* Wait Controllership completion confirmation flag */ + status = I3C_WaitOnFlagUntilTimeout(hi3c, HAL_I3C_FLAG_CRUPDF, RESET, timeout, tickstart); + + /* Clear Control role request flag */ + if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_CRUPDF) == SET) + { + LL_I3C_ClearFlag_CRUPD(hi3c->Instance); + } + + /* Check on error flag */ + if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET) + { + /* Clear error flag */ + LL_I3C_ClearFlag_ERR(hi3c->Instance); + + /* Update handle error code parameter */ + I3C_GetErrorSources(hi3c); + + /* Update handle state parameter to previous state */ + I3C_StateUpdate(hi3c); + + status = HAL_ERROR; + } + else + { + /* Update handle state parameter to previous state */ + I3C_StateUpdate(hi3c); + } + } + } + + return status; +} + +/** + * @brief Target send control role request in interrupt mode. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Tgt_ControlRoleReq_IT(I3C_HandleTypeDef *hi3c) +{ + HAL_I3C_StateTypeDef handle_state; + HAL_StatusTypeDef status = HAL_OK; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* Check on the Mode */ + if (hi3c->Mode != HAL_I3C_MODE_TARGET) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* check on the State */ + else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN)) + { + status = HAL_BUSY; + } + /* Verify the dynamic address validity */ + else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + else + { + /* Verify if control role request feature is enabled */ + if (LL_I3C_IsEnabledControllerRoleReq(hi3c->Instance) != 1U) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + } + + if (status == HAL_OK) + { + /* Update handle parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY; + hi3c->XferISR = I3C_Tgt_CtrlRole_ISR; + + /* Enable controller-role update and error interrupts */ + I3C_Enable_IRQ(hi3c, I3C_XFER_TARGET_CTRLROLE); + + /* Request Controllership */ + LL_I3C_TargetHandleMessage(hi3c->Instance, LL_I3C_TARGET_MTYPE_CONTROLLER_ROLE_REQ, 0U); + } + } + + return status; +} + +/** + * @brief Target send hot join request in polling mode. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @param pAddress : [IN/OUT] Pointer to the target own dynamic address assigned by the controller. + * @param timeout : [IN] Timeout duration in millisecond. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Tgt_HotJoinReq(I3C_HandleTypeDef *hi3c, uint8_t *pAddress, uint32_t timeout) +{ + uint32_t tickstart; + HAL_I3C_StateTypeDef handle_state; + uint32_t valid_dynamic_address; + HAL_StatusTypeDef status = HAL_OK; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* Check on the pAddress value */ + if (pAddress == NULL) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* Check on the Mode */ + else if (hi3c->Mode != HAL_I3C_MODE_TARGET) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* check on the State */ + else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN)) + { + status = HAL_BUSY; + } + else + { + /* Check on the hot join request feature */ + if (LL_I3C_IsEnabledHotJoin(hi3c->Instance) != 1U) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + } + + if (status == HAL_OK) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY; + + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + + /* Request hot join */ + LL_I3C_TargetHandleMessage(hi3c->Instance, LL_I3C_TARGET_MTYPE_HOT_JOIN, 0U); + + /* Wait hot join completion confirmation flag */ + status = I3C_WaitOnFlagUntilTimeout(hi3c, HAL_I3C_FLAG_DAUPDF, RESET, timeout, tickstart); + + /* Clear dynamic address update flag */ + if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_DAUPDF) == SET) + { + LL_I3C_ClearFlag_DAUPD(hi3c->Instance); + } + + /* Get dynamic address validity flag */ + valid_dynamic_address = LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance); + + /* Check the validity of the own dynamic address */ + if (valid_dynamic_address == 0U) + { + hi3c->ErrorCode = HAL_I3C_ERROR_DYNAMIC_ADDR; + status = HAL_ERROR; + + /* Update handle state parameter to previous state */ + I3C_StateUpdate(hi3c); + } + /* Check on error flag */ + else if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET) + { + /* Clear error flag */ + LL_I3C_ClearFlag_ERR(hi3c->Instance); + + /* Update handle error code parameter */ + I3C_GetErrorSources(hi3c); + + /* Update handle state parameter to previous state */ + I3C_StateUpdate(hi3c); + + status = HAL_ERROR; + } + else + { + /* Update handle state parameter to previous state */ + I3C_StateUpdate(hi3c); + + /* Get assigned dynamic address */ + *pAddress = LL_I3C_GetOwnDynamicAddress(hi3c->Instance); + } + } + } + + return status; +} + +/** + * @brief Target send hot join request in interrupt mode. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Tgt_HotJoinReq_IT(I3C_HandleTypeDef *hi3c) +{ + HAL_I3C_StateTypeDef handle_state; + HAL_StatusTypeDef status = HAL_OK; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* Check on the Mode */ + if (hi3c->Mode != HAL_I3C_MODE_TARGET) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* check on the State */ + else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN)) + { + status = HAL_BUSY; + } + /* Check on the hot join request feature */ + else if (LL_I3C_IsEnabledHotJoin(hi3c->Instance) != 1U) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + else + { + /* Update handle parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY; + hi3c->XferISR = I3C_Tgt_HotJoin_ISR; + + /* Enable dynamic address update and error interrupts */ + I3C_Enable_IRQ(hi3c, I3C_XFER_TARGET_HOTJOIN); + + /* Request hot join */ + LL_I3C_TargetHandleMessage(hi3c->Instance, LL_I3C_TARGET_MTYPE_HOT_JOIN, 0U); + } + } + + return status; +} + +/** + * @brief Target send IBI request in polling mode. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @param pPayload : [IN] Pointer to the buffer contains the payload data. + * @param payloadSize : [IN] Payload buffer size in bytes. + * @param timeout : [IN] Timeout duration in millisecond. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Tgt_IBIReq(I3C_HandleTypeDef *hi3c, const uint8_t *pPayload, + uint8_t payloadSize, uint32_t timeout) +{ + uint32_t tickstart; + uint32_t payload_value = 0U; + HAL_I3C_StateTypeDef handle_state; + HAL_StatusTypeDef status = HAL_OK; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* Check on the Mode */ + if (hi3c->Mode != HAL_I3C_MODE_TARGET) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* check on the State */ + else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN)) + { + status = HAL_BUSY; + } + /* Verify the dynamic address validity */ + else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + else + { + /* Verify if IBI request feature is enabled*/ + if ((LL_I3C_IsEnabledIBI(hi3c->Instance) != 1U)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + } + + if (status == HAL_OK) + { + /* Update handle parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY; + + /* Check on the IBI additional data */ + if (LL_I3C_GetDeviceIBIPayload(hi3c->Instance) == LL_I3C_IBI_ADDITIONAL_DATA) + { + /* Check on the pPayload and payloadSize values */ + if ((pPayload == NULL) || (payloadSize == 0U)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + } + else + { + /* For loop to calculate the payload value */ + for (uint32_t index = 0U; index < payloadSize; index++) + { + payload_value |= ((uint32_t)pPayload[index] << (index * 8U)); + } + + /* Load IBI payload data */ + LL_I3C_SetIBIPayload(hi3c->Instance, payload_value); + } + } + + if (status == HAL_OK) + { + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + + /* Request IBI */ + LL_I3C_TargetHandleMessage(hi3c->Instance, LL_I3C_TARGET_MTYPE_IBI, payloadSize); + + /* Wait IBI completion confirmation flag */ + status = I3C_WaitOnFlagUntilTimeout(hi3c, HAL_I3C_FLAG_IBIENDF, RESET, timeout, tickstart); + + if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_IBIENDF) == SET) + { + /* Clear IBI end process flag */ + LL_I3C_ClearFlag_IBIEND(hi3c->Instance); + } + + /* Check on error flag value */ + if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET) + { + /* Clear error flag */ + LL_I3C_ClearFlag_ERR(hi3c->Instance); + + /* Update handle error code parameter */ + I3C_GetErrorSources(hi3c); + + /* Update handle state parameter to previous state */ + I3C_StateUpdate(hi3c); + + status = HAL_ERROR; + } + else + { + /* Update handle state parameter to previous state */ + I3C_StateUpdate(hi3c); + } + } + } + } + + return status; +} + +/** + * @brief Target send IBI request in interrupt mode. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @param pPayload : [IN] Pointer to the buffer contains the payload data. + * @param payloadSize : [IN] Payload buffer size in bytes. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Tgt_IBIReq_IT(I3C_HandleTypeDef *hi3c, const uint8_t *pPayload, uint8_t payloadSize) +{ + uint32_t payload_value = 0U; + HAL_I3C_StateTypeDef handle_state; + HAL_StatusTypeDef status = HAL_OK; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check the instance and the mode parameters */ + assert_param(IS_I3C_ALL_INSTANCE(hi3c->Instance)); + assert_param(IS_I3C_MODE(hi3c->Mode)); + + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* Check on the Mode */ + if (hi3c->Mode != HAL_I3C_MODE_TARGET) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* check on the State */ + else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN)) + { + status = HAL_BUSY; + } + /* Verify the dynamic address validity */ + else if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) != 1U) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + else + { + /* Verify if IBI request feature is enabled */ + if (LL_I3C_IsEnabledIBI(hi3c->Instance) != 1U) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + } + + if (status == HAL_OK) + { + /* Update handle parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY; + hi3c->XferISR = I3C_Tgt_IBI_ISR; + + /* Check on the IBI additional data */ + if (LL_I3C_GetDeviceIBIPayload(hi3c->Instance) == LL_I3C_IBI_ADDITIONAL_DATA) + { + /* Check on the pPayload and payloadSize values */ + if ((pPayload == NULL) || (payloadSize == 0U)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + } + else + { + /* For loop to calculate the payload value */ + for (uint32_t index = 0U; index < payloadSize; index++) + { + payload_value |= ((uint32_t)pPayload[index] << (index * 8U)); + } + + /* Load IBI payload data */ + LL_I3C_SetIBIPayload(hi3c->Instance, payload_value); + } + } + + /* Enable IBI end and error interrupts */ + I3C_Enable_IRQ(hi3c, I3C_XFER_TARGET_IBI); + + /* Request IBI */ + LL_I3C_TargetHandleMessage(hi3c->Instance, LL_I3C_TARGET_MTYPE_IBI, payloadSize); + } + } + + return status; +} +/** + * @} + */ + +/** @defgroup I3C_Exported_Functions_Group7 Generic and Common functions. + * @brief I3C generic and common functions. + * +@verbatim + ======================================================================================================================= + ##### Generic and Common functions ##### + ======================================================================================================================= + [..] This subsection provides a set of functions allowing to Abort transfer or to get in run-time the status + of the peripheral. + + (+) Call the function HAL_I3C_Abort_IT() to abort the current transfer either in DMA or IT. + (+) Call the function HAL_I3C_GetState() to get the I3C handle state. + (+) Call the function HAL_I3C_GetMode() to get the I3C handle mode. + (+) Call the function HAL_I3C_GetError() to get the error code. + +@endverbatim + * @{ + */ + +/** + * @brief Abort an I3C IT or DMA process communication with Interrupt. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +HAL_StatusTypeDef HAL_I3C_Abort_IT(I3C_HandleTypeDef *hi3c) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + if (hi3c->State != HAL_I3C_STATE_ABORT) + { + /* Set State at HAL_I3C_STATE_ABORT */ + hi3c->State = HAL_I3C_STATE_ABORT; + + /* Disable Error Interrupts */ + __HAL_I3C_DISABLE_IT(hi3c, HAL_I3C_IT_ERRIE); + + hi3c->XferISR = I3C_Abort_ISR; + + /* Flush the different Fifos to generate an automatic stop mode link to underflow or overflow detection timeout */ + /* Flush the content of Tx Fifo */ + LL_I3C_RequestTxFIFOFlush(hi3c->Instance); + + /* Flush the content of Rx Fifo */ + LL_I3C_RequestRxFIFOFlush(hi3c->Instance); + + /* Check on the I3C mode: Control and status FIFOs available only with controller mode */ + if (hi3c->Mode == HAL_I3C_MODE_CONTROLLER) + { + /* Flush the content of Control Fifo */ + LL_I3C_RequestControlFIFOFlush(hi3c->Instance); + + /* Flush the content of Status Fifo */ + LL_I3C_RequestStatusFIFOFlush(hi3c->Instance); + } + + /* Disable all DMA Requests */ + LL_I3C_DisableDMAReq_Control(hi3c->Instance); + LL_I3C_DisableDMAReq_RX(hi3c->Instance); + LL_I3C_DisableDMAReq_TX(hi3c->Instance); + LL_I3C_DisableDMAReq_Status(hi3c->Instance); + + if (hi3c->Mode == HAL_I3C_MODE_CONTROLLER) + { + /* Note : The I3C interrupts must be enabled after unlocking current process + to avoid the risk of I3C interrupt handle execution before current + process unlock */ + I3C_Enable_IRQ(hi3c, I3C_XFER_CONTROLLER_RX_CCC_IT); + } + else + { + /* Note : The I3C interrupts must be enabled after unlocking current process + to avoid the risk of I3C interrupt handle execution before current + process unlock */ + I3C_Enable_IRQ(hi3c, I3C_XFER_TARGET_RX_IT); + } + } + else + { + return HAL_BUSY; + } + } + + return status; +} + +/** + * @brief Return the I3C handle state. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @retval HAL State : [OUT] Value from HAL_I3C_StateTypeDef enumeration. + */ +HAL_I3C_StateTypeDef HAL_I3C_GetState(const I3C_HandleTypeDef *hi3c) +{ + return hi3c->State; +} + +/** + * @brief Returns the I3C handle mode. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @retval HAL Mode : [OUT] Value from HAL_I3C_ModeTypeDef enumeration. + */ +HAL_I3C_ModeTypeDef HAL_I3C_GetMode(const I3C_HandleTypeDef *hi3c) +{ + return hi3c->Mode; +} + +/** + * @brief Return the I3C error code. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @retval I3C Error Code : [OUT] Value from @ref I3C_ERROR_CODE_DEFINITION. + */ +uint32_t HAL_I3C_GetError(const I3C_HandleTypeDef *hi3c) +{ + return hi3c->ErrorCode; +} + +/** + * @brief Target/Controller Get Common Command Code Information updated after event. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param notifyId : [IN] Parameter indicates which notification is signaled. + * It can be a combination of value of @ref HAL_I3C_Notification_ID_definition. + * @param pCCCInfo : [IN/OUT] Pointer to an I3C_CCCInfoTypeDef structure that contains the CCC information + * updated after CCC event. + * @retval None + */ +HAL_StatusTypeDef HAL_I3C_GetCCCInfo(I3C_HandleTypeDef *hi3c, + uint32_t notifyId, + I3C_CCCInfoTypeDef *pCCCInfo) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* check on the handle */ + if (hi3c == NULL) + { + status = HAL_ERROR; + } + else + { + /* Check on user parameters */ + if (pCCCInfo == NULL) + { + /* Update handle error code parameter */ + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + /* Check the I3C state */ + else if (hi3c->State == HAL_I3C_STATE_RESET) + { + /* Update handle error code parameter */ + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + else + { + /* Retrieve Target Dynamic Address value and Validity (target/controller) */ + if ((notifyId & EVENT_ID_DAU) == EVENT_ID_DAU) + { + pCCCInfo->DynamicAddrValid = LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance); + pCCCInfo->DynamicAddr = LL_I3C_GetOwnDynamicAddress(hi3c->Instance); + } + + /* Retrieve Maximum Write Data Length (target) */ + if ((notifyId & EVENT_ID_SETMWL) == EVENT_ID_SETMWL) + { + pCCCInfo->MaxWriteLength = LL_I3C_GetMaxWriteLength(hi3c->Instance); + } + + /* Retrieve Maximum Read Data Length (target) */ + if ((notifyId & EVENT_ID_SETMRL) == EVENT_ID_SETMRL) + { + pCCCInfo->MaxReadLength = LL_I3C_GetMaxReadLength(hi3c->Instance); + } + + /* Retrieve Reset Action/Level on received reset pattern (target) */ + if ((notifyId & EVENT_ID_RSTACT) == EVENT_ID_RSTACT) + { + pCCCInfo->ResetAction = LL_I3C_GetResetAction(hi3c->Instance); + } + + /* Retrieve Activity State (target) */ + if ((notifyId & EVENT_ID_ENTASx) == EVENT_ID_ENTASx) + { + pCCCInfo->ActivityState = LL_I3C_GetActivityState(hi3c->Instance); + } + + /* Retrieve Interrupt allowed status (target) */ + if ((notifyId & EVENT_ID_ENEC_DISEC) == EVENT_ID_ENEC_DISEC) + { + pCCCInfo->HotJoinAllowed = LL_I3C_IsEnabledHotJoin(hi3c->Instance); + pCCCInfo->InBandAllowed = LL_I3C_IsEnabledIBI(hi3c->Instance); + pCCCInfo->CtrlRoleAllowed = LL_I3C_IsEnabledControllerRoleReq(hi3c->Instance); + } + + /* Retrieve In Band Interrupt information (controller) */ + if ((notifyId & EVENT_ID_IBI) == EVENT_ID_IBI) + { + pCCCInfo->IBICRTgtAddr = LL_I3C_GetIBITargetAddr(hi3c->Instance); + pCCCInfo->IBITgtNbPayload = LL_I3C_GetNbIBIAddData(hi3c->Instance); + pCCCInfo->IBITgtPayload = LL_I3C_GetIBIPayload(hi3c->Instance); + } + + /* Retrieve Controller role request Interrupt information (controller) */ + if ((notifyId & EVENT_ID_CR) == EVENT_ID_CR) + { + pCCCInfo->IBICRTgtAddr = LL_I3C_GetIBITargetAddr(hi3c->Instance); + } + } + } + + return status; +} +/** + * @} + */ + +/** + * @} + */ + +/* Private functions -------------------------------------------------------------------------------------------------*/ +/** @defgroup I3C_Private_Functions I3C Private Functions + * @{ + */ + +/** + * @brief Interrupt Sub-Routine which handles target received events. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param itFlags : [IN] Interrupt flags to handle. + * @param itSources : [IN] Interrupt sources enabled. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +static HAL_StatusTypeDef I3C_Tgt_Event_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources) +{ + uint32_t tmpevent = 0U; + + /* I3C Rx FIFO not empty interrupt Check */ + if ((I3C_CHECK_FLAG(itFlags, HAL_I3C_FLAG_RXFNEF) != RESET) && + (I3C_CHECK_IT_SOURCE(itSources, HAL_I3C_IT_RXFNEIE) != RESET)) + { + /* Call receive treatment function */ + hi3c->ptrRxFunc(hi3c); + } + + /* I3C target complete controller-role hand-off procedure (direct GETACCR CCC) event management --------------------*/ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_CRUPDF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_CRUPDIE) != RESET)) + { + /* Clear controller-role update flag */ + LL_I3C_ClearFlag_CRUPD(hi3c->Instance); + + /* Set Identifier EVENT_ID_GETACCCR */ + tmpevent |= EVENT_ID_GETACCCR; + } + + /* I3C target receive any direct GETxxx CCC event management -------------------------------------------------------*/ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_GETF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_GETIE) != RESET)) + { + /* Clear GETxxx CCC flag */ + LL_I3C_ClearFlag_GET(hi3c->Instance); + + /* Set Identifier EVENT_ID_GETx */ + tmpevent |= EVENT_ID_GETx; + } + + /* I3C target receive get status command (direct GETSTATUS CCC) event management -----------------------------------*/ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_STAF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_STAIE) != RESET)) + { + /* Clear GETSTATUS CCC flag */ + LL_I3C_ClearFlag_STA(hi3c->Instance); + + /* Set Identifier EVENT_ID_GETSTATUS */ + tmpevent |= EVENT_ID_GETSTATUS; + } + + /* I3C target receive a dynamic address update (ENTDAA/RSTDAA/SETNEWDA CCC) event management -----------------------*/ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_DAUPDF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_DAUPDIE) != RESET)) + { + /* Clear dynamic address update flag */ + LL_I3C_ClearFlag_DAUPD(hi3c->Instance); + + /* Set Identifier EVENT_ID_DAU */ + tmpevent |= EVENT_ID_DAU; + } + + /* I3C target receive maximum write length update (direct SETMWL CCC) event management -----------------------------*/ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_MWLUPDF) != RESET) && + (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_MWLUPDIE) != RESET)) + { + /* Clear SETMWL CCC flag */ + LL_I3C_ClearFlag_MWLUPD(hi3c->Instance); + + /* Set Identifier EVENT_ID_SETMWL */ + tmpevent |= EVENT_ID_SETMWL; + } + + /* I3C target receive maximum read length update(direct SETMRL CCC) event management -------------------------------*/ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_MRLUPDF) != RESET) && + (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_MRLUPDIE) != RESET)) + { + /* Clear SETMRL CCC flag */ + LL_I3C_ClearFlag_MRLUPD(hi3c->Instance); + + /* Set Identifier EVENT_ID_SETMRL */ + tmpevent |= EVENT_ID_SETMRL; + } + + /* I3C target detect reset pattern (broadcast or direct RSTACT CCC) event management -------------------------------*/ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_RSTF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_RSTIE) != RESET)) + { + /* Clear reset pattern flag */ + LL_I3C_ClearFlag_RST(hi3c->Instance); + + /* Set Identifier EVENT_ID_RSTACT */ + tmpevent |= EVENT_ID_RSTACT; + } + + /* I3C target receive activity state update (direct or broadcast ENTASx) CCC event management ----------------------*/ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_ASUPDF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_ASUPDIE) != RESET)) + { + /* Clear ENTASx CCC flag */ + LL_I3C_ClearFlag_ASUPD(hi3c->Instance); + + /* Set Identifier EVENT_ID_ENTASx */ + tmpevent |= EVENT_ID_ENTASx; + } + + /* I3C target receive a direct or broadcast ENEC/DISEC CCC event management ----------------------------------------*/ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_INTUPDF) != RESET) && + (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_INTUPDIE) != RESET)) + { + /* Clear ENEC/DISEC CCC flag */ + LL_I3C_ClearFlag_INTUPD(hi3c->Instance); + + /* Set Identifier EVENT_ID_ENEC_DISEC */ + tmpevent |= EVENT_ID_ENEC_DISEC; + } + + /* I3C target receive a broadcast DEFTGTS CCC event management -----------------------------------------------------*/ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_DEFF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_DEFIE) != RESET)) + { + /* Clear DEFTGTS CCC flag */ + LL_I3C_ClearFlag_DEF(hi3c->Instance); + + /* Set Identifier EVENT_ID_DEFTGTS */ + tmpevent |= EVENT_ID_DEFTGTS; + } + + /* I3C target receive a group addressing (broadcast DEFGRPA CCC) event management ----------------------------------*/ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_GRPF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_GRPIE) != RESET)) + { + /* Clear DEFGRPA CCC flag */ + LL_I3C_ClearFlag_GRP(hi3c->Instance); + + /* Set Identifier EVENT_ID_DEFGRPA */ + tmpevent |= EVENT_ID_DEFGRPA; + } + + /* I3C target wakeup event management ----------------------------------*/ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_WKPF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_WKPIE) != RESET)) + { + /* Clear WKP flag */ + LL_I3C_ClearFlag_WKP(hi3c->Instance); + + /* Set Identifier EVENT_ID_WKP */ + tmpevent |= EVENT_ID_WKP; + } + + if (tmpevent != 0U) + { +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + /* Call registered callback */ + hi3c->NotifyCallback(hi3c, tmpevent); +#else + /* Asynchronous receive CCC event Callback */ + HAL_I3C_NotifyCallback(hi3c, tmpevent); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + } + + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + + return HAL_OK; +} + +/** + * @brief Interrupt Sub-Routine which handles Controller received events. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param itFlags : [IN] Interrupt flags to handle. + * @param itSources : [IN] Interrupt sources enabled. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +static HAL_StatusTypeDef I3C_Ctrl_Event_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources) +{ + /* I3C controller receive IBI event management ---------------------------------------------------------------------*/ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_IBIF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_IBIIE) != RESET)) + { + /* Clear IBI request flag */ + LL_I3C_ClearFlag_IBI(hi3c->Instance); + +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + /* Call registered callback */ + hi3c->NotifyCallback(hi3c, EVENT_ID_IBI); +#else + /* Asynchronous IBI event Callback */ + HAL_I3C_NotifyCallback(hi3c, EVENT_ID_IBI); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + } + + /* I3C controller controller-role request event management ---------------------------------------------------------*/ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_CRF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_CRIE) != RESET)) + { + /* Clear controller-role request flag */ + LL_I3C_ClearFlag_CR(hi3c->Instance); + +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + /* Call registered callback */ + hi3c->NotifyCallback(hi3c, EVENT_ID_CR); +#else + /* Asynchronous controller-role event Callback */ + HAL_I3C_NotifyCallback(hi3c, EVENT_ID_CR); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + } + + /* I3C controller hot-join event management ------------------------------------------------------------------------*/ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_HJF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_HJIE) != RESET)) + { + /* Clear hot-join flag */ + LL_I3C_ClearFlag_HJ(hi3c->Instance); + +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + /* Call registered callback */ + hi3c->NotifyCallback(hi3c, EVENT_ID_HJ); +#else + /* Asynchronous hot-join event Callback */ + HAL_I3C_NotifyCallback(hi3c, EVENT_ID_HJ); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + } + + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + + return HAL_OK; +} + +/** + * @brief Interrupt Sub-Routine which handles target hot join event. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param itFlags : [IN] Interrupt flags to handle. + * @param itSources : [IN] Interrupt sources enabled. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +static HAL_StatusTypeDef I3C_Tgt_HotJoin_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources) +{ + /* I3C target receive a dynamic address update event management */ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_DAUPDF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_DAUPDIE) != RESET)) + { + /* Clear dynamic address update flag */ + LL_I3C_ClearFlag_DAUPD(hi3c->Instance); + + /* Disable dynamic address update and error interrupts */ + I3C_Disable_IRQ(hi3c, I3C_XFER_TARGET_HOTJOIN); + + /* Check the validity of the own dynamic address */ + if (LL_I3C_IsEnabledOwnDynAddress(hi3c->Instance) == 1U) + { + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + /* Call registered callback */ + hi3c->TgtHotJoinCallback(hi3c, (uint8_t)LL_I3C_GetOwnDynamicAddress(hi3c->Instance)); +#else + /* Asynchronous receive ENTDAA/RSTDAA/SETNEWDA CCC event Callback */ + HAL_I3C_TgtHotJoinCallback(hi3c, (uint8_t)LL_I3C_GetOwnDynamicAddress(hi3c->Instance)); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + } + else + { + hi3c->ErrorCode = HAL_I3C_ERROR_DYNAMIC_ADDR; + + /* Call error treatment function */ + I3C_ErrorTreatment(hi3c); + } + } + return HAL_OK; +} + +/** + * @brief Interrupt Sub-Routine which handles target control role event. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param itFlags : [IN] Interrupt flags to handle. + * @param itSources : [IN] Interrupt sources enabled. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +static HAL_StatusTypeDef I3C_Tgt_CtrlRole_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources) +{ + /* I3C target complete controller-role hand-off procedure (direct GETACCR CCC) event management -------------------*/ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_CRUPDF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_CRUPDIE) != RESET)) + { + /* Clear controller-role update flag */ + LL_I3C_ClearFlag_CRUPD(hi3c->Instance); + + /* Disable controller-role update and error interrupts */ + I3C_Disable_IRQ(hi3c, I3C_XFER_TARGET_CTRLROLE); + + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + /* Call registered callback */ + hi3c->NotifyCallback(hi3c, EVENT_ID_GETACCCR); +#else + /* Asynchronous receive GETACCR CCC event Callback */ + HAL_I3C_NotifyCallback(hi3c, EVENT_ID_GETACCCR); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + } + return HAL_OK; +} + +/** + * @brief Interrupt Sub-Routine which handles target IBI event. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param itFlags : [IN] Interrupt flags to handle. + * @param itSources : [IN] Interrupt sources enabled. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +static HAL_StatusTypeDef I3C_Tgt_IBI_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources) +{ + /* I3C target IBI end process event management ---------------------------------------------------------------------*/ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_IBIENDF) != RESET) && + (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_IBIENDIE) != RESET)) + { + /* Clear IBI end flag */ + LL_I3C_ClearFlag_IBIEND(hi3c->Instance); + + /* Disable IBI end and error interrupts */ + I3C_Disable_IRQ(hi3c, I3C_XFER_TARGET_IBI); + + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + /* Call registered callback */ + hi3c->NotifyCallback(hi3c, EVENT_ID_IBIEND); +#else + /* Asynchronous IBI end event Callback */ + HAL_I3C_NotifyCallback(hi3c, EVENT_ID_IBIEND); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + } + return HAL_OK; +} + +/** + * @brief Interrupt Sub-Routine which handles target transmit data in Interrupt mode. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param itFlags : [IN] Interrupt flags to handle. + * @param itSources : [IN] Interrupt sources enabled. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +static HAL_StatusTypeDef I3C_Tgt_Tx_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources) +{ + /* Check that a Tx process is ongoing */ + if (hi3c->State == HAL_I3C_STATE_BUSY_TX) + { + /* I3C Tx FIFO not full interrupt Check */ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_TXFNFF) != RESET) && + (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_TXFNFIE) != RESET)) + { + if (hi3c->TxXferCount > 0U) + { + /* Call transmit treatment function */ + hi3c->ptrTxFunc(hi3c); + } + } + + /* I3C target frame complete event Check */ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_FCF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_FCIE) != RESET)) + { + /* Clear frame complete flag */ + LL_I3C_ClearFlag_FC(hi3c->Instance); + + /* Check if all data bytes are transmitted */ + if (LL_I3C_GetXferDataCount(hi3c->Instance) == hi3c->pXferData->TxBuf.Size) + { + /* Disable Tx process interrupts */ + I3C_Disable_IRQ(hi3c, I3C_XFER_TARGET_TX_IT); + + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + + /* Call the transmit complete callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + hi3c->TgtTxCpltCallback(hi3c); +#else + HAL_I3C_TgtTxCpltCallback(hi3c); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + } + else + { + hi3c->ErrorCode = HAL_I3C_ERROR_SIZE; + + /* Call error treatment function */ + I3C_ErrorTreatment(hi3c); + } + } + + /* I3C target wakeup event management ----------------------------------*/ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_WKPF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_WKPIE) != RESET)) + { + /* Clear WKP flag */ + LL_I3C_ClearFlag_WKP(hi3c->Instance); + +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + /* Call registered callback */ + hi3c->NotifyCallback(hi3c, EVENT_ID_WKP); +#else + /* Asynchronous receive CCC event Callback */ + HAL_I3C_NotifyCallback(hi3c, EVENT_ID_WKP); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + } + } + + return HAL_OK; +} + +/** + * @brief Interrupt Sub-Routine which handles target receive data in Interrupt mode. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param itFlags : [IN] Interrupt flags to handle. + * @param itSources : [IN] Interrupt sources enabled. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +static HAL_StatusTypeDef I3C_Tgt_Rx_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources) +{ + /* Check that an Rx process is ongoing */ + if (hi3c->State == HAL_I3C_STATE_BUSY_RX) + { + /* I3C Rx FIFO not empty interrupt Check */ + if ((I3C_CHECK_FLAG(itFlags, HAL_I3C_FLAG_RXFNEF) != RESET) && + (I3C_CHECK_IT_SOURCE(itSources, HAL_I3C_IT_RXFNEIE) != RESET)) + { + if (hi3c->RxXferCount > 0U) + { + /* Call receive treatment function */ + hi3c->ptrRxFunc(hi3c); + } + } + + /* I3C target frame complete event Check */ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_FCF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_FCIE) != RESET)) + { + /* Clear frame complete flag */ + LL_I3C_ClearFlag_FC(hi3c->Instance); + + /* Check if all data bytes are received */ + if (LL_I3C_GetXferDataCount(hi3c->Instance) == hi3c->pXferData->RxBuf.Size) + { + /* Disable Rx process interrupts */ + I3C_Disable_IRQ(hi3c, I3C_XFER_TARGET_RX_IT); + + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + + /* Call the receive complete callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + hi3c->TgtRxCpltCallback(hi3c); +#else + HAL_I3C_TgtRxCpltCallback(hi3c); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + } + else + { + hi3c->ErrorCode = HAL_I3C_ERROR_SIZE; + + /* Call error treatment function */ + I3C_ErrorTreatment(hi3c); + } + } + + /* I3C target wakeup event management ----------------------------------*/ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_WKPF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_WKPIE) != RESET)) + { + /* Clear WKP flag */ + LL_I3C_ClearFlag_WKP(hi3c->Instance); + +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + /* Call registered callback */ + hi3c->NotifyCallback(hi3c, EVENT_ID_WKP); +#else + /* Asynchronous receive CCC event Callback */ + HAL_I3C_NotifyCallback(hi3c, EVENT_ID_WKP); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + } + } + + return HAL_OK; +} + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief Interrupt Sub-Routine which handles target transmit data in DMA mode. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param itFlags : [IN] Interrupt flags to handle. + * @param itSources : [IN] Interrupt sources enabled. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +static HAL_StatusTypeDef I3C_Tgt_Tx_DMA_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources) +{ + /* Check that a Tx process is ongoing */ + if (hi3c->State == HAL_I3C_STATE_BUSY_TX) + { + /* I3C target frame complete event Check */ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_FCF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_FCIE) != RESET)) + { + /* Clear frame complete flag */ + LL_I3C_ClearFlag_FC(hi3c->Instance); + + /* Check if all data bytes are transmitted */ + if (I3C_GET_DMA_REMAIN_DATA(hi3c->hdmatx) == 0U) + { + /* Disable Tx process interrupts */ + I3C_Disable_IRQ(hi3c, I3C_XFER_DMA); + + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + + /* Update the number of remaining data bytes */ + hi3c->TxXferCount = 0U; + + /* Call target transmit complete callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + hi3c->TgtTxCpltCallback(hi3c); +#else + HAL_I3C_TgtTxCpltCallback(hi3c); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + } + else + { + hi3c->ErrorCode = HAL_I3C_ERROR_SIZE; + + /* Call error treatment function */ + I3C_ErrorTreatment(hi3c); + } + } + + /* I3C target wakeup event management ----------------------------------*/ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_WKPF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_WKPIE) != RESET)) + { + /* Clear WKP flag */ + LL_I3C_ClearFlag_WKP(hi3c->Instance); + +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + /* Call registered callback */ + hi3c->NotifyCallback(hi3c, EVENT_ID_WKP); +#else + /* Asynchronous receive CCC event Callback */ + HAL_I3C_NotifyCallback(hi3c, EVENT_ID_WKP); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + } + } + + return HAL_OK; +} + +/** + * @brief Interrupt Sub-Routine which handles target receive data in DMA mode. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param itFlags : [IN] Interrupt flags to handle. + * @param itSources : [IN] Interrupt sources enabled. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +static HAL_StatusTypeDef I3C_Tgt_Rx_DMA_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources) +{ + /* Check that a Rx process is ongoing */ + if (hi3c->State == HAL_I3C_STATE_BUSY_RX) + { + /* I3C target frame complete event Check */ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_FCF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_FCIE) != RESET)) + { + /* Clear frame complete flag */ + LL_I3C_ClearFlag_FC(hi3c->Instance); + + /* Check if all data bytes are received */ + if (I3C_GET_DMA_REMAIN_DATA(hi3c->hdmarx) == 0U) + { + /* Disable Rx process interrupts */ + I3C_Disable_IRQ(hi3c, I3C_XFER_DMA); + + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + + /* Update the number of remaining data bytes */ + hi3c->RxXferCount = 0U; + + /* Call target receive complete callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + hi3c->TgtRxCpltCallback(hi3c); +#else + HAL_I3C_TgtRxCpltCallback(hi3c); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + } + else + { + hi3c->ErrorCode = HAL_I3C_ERROR_SIZE; + + /* Call error treatment function */ + I3C_ErrorTreatment(hi3c); + } + } + + /* I3C target wakeup event management ----------------------------------*/ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_WKPF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_WKPIE) != RESET)) + { + /* Clear WKP flag */ + LL_I3C_ClearFlag_WKP(hi3c->Instance); + +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + /* Call registered callback */ + hi3c->NotifyCallback(hi3c, EVENT_ID_WKP); +#else + /* Asynchronous receive CCC event Callback */ + HAL_I3C_NotifyCallback(hi3c, EVENT_ID_WKP); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + } + } + + return HAL_OK; +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Interrupt Sub-Routine which handles controller transmission in interrupt mode. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param itFlags : [IN] Interrupt flags to handle. + * @param itSources : [IN] Interrupt sources enabled. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +static HAL_StatusTypeDef I3C_Ctrl_Tx_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources) +{ + /* Check that a Tx process is ongoing */ + if (hi3c->State == HAL_I3C_STATE_BUSY_TX) + { + /* Check if Control FIFO requests data */ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_CFNFF) != RESET) && + (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_CFNFIE) != RESET)) + { + if (hi3c->ControlXferCount > 0U) + { + /* Call control data treatment function */ + I3C_ControlDataTreatment(hi3c); + } + } + + /* I3C Tx FIFO not full interrupt Check */ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_TXFNFF) != RESET) && + (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_TXFNFIE) != RESET)) + { + if (hi3c->TxXferCount > 0U) + { + /* Call Transmit treatment function */ + hi3c->ptrTxFunc(hi3c); + } + } + + /* I3C target frame complete event Check */ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_FCF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_FCIE) != RESET)) + { + /* Clear frame complete flag */ + LL_I3C_ClearFlag_FC(hi3c->Instance); + + if (hi3c->ControlXferCount == 0U) + { + /* Disable Tx process interrupts */ + I3C_Disable_IRQ(hi3c, I3C_XFER_CONTROLLER_TX_IT); + + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + + /* Call the transmit complete callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + hi3c->CtrlTxCpltCallback(hi3c); +#else + HAL_I3C_CtrlTxCpltCallback(hi3c); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + } + else + { + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + + /* Call the transmit complete callback */ +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + hi3c->CtrlTxCpltCallback(hi3c); +#else + HAL_I3C_CtrlTxCpltCallback(hi3c); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + + /* Then Initiate a Start condition */ + LL_I3C_RequestTransfer(hi3c->Instance); + + } + } + } + return HAL_OK; +} + +/** + * @brief Interrupt Sub-Routine which handles controller reception in interrupt mode. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param itFlags : [IN] Interrupt flags to handle. + * @param itSources : [IN] Interrupt sources enabled. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +static HAL_StatusTypeDef I3C_Ctrl_Rx_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources) +{ + /* Check that an Rx process is ongoing */ + if (hi3c->State == HAL_I3C_STATE_BUSY_RX) + { + /* Check if Control FIFO requests data */ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_CFNFF) != RESET) && + (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_CFNFIE) != RESET)) + { + if (hi3c->ControlXferCount > 0U) + { + /* Call control data treatment function */ + I3C_ControlDataTreatment(hi3c); + } + } + + /* I3C Rx FIFO not empty interrupt Check */ + if ((I3C_CHECK_FLAG(itFlags, HAL_I3C_FLAG_RXFNEF) != RESET) && + (I3C_CHECK_IT_SOURCE(itSources, HAL_I3C_IT_RXFNEIE) != RESET)) + { + if (hi3c->RxXferCount > 0U) + { + /* Call receive treatment function */ + hi3c->ptrRxFunc(hi3c); + } + } + + /* I3C Tx FIFO not full interrupt Check */ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_TXFNFF) != RESET) && + (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_TXFNFIE) != RESET)) + { + if (hi3c->TxXferCount > 0U) + { + /* Call Transmit treatment function */ + hi3c->ptrTxFunc(hi3c); + } + } + + /* I3C target frame complete event Check */ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_FCF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_FCIE) != RESET)) + { + /* Clear frame complete flag */ + LL_I3C_ClearFlag_FC(hi3c->Instance); + + if (hi3c->ControlXferCount == 0U) + { + /* Disable Rx process interrupts */ + I3C_Disable_IRQ(hi3c, I3C_XFER_CONTROLLER_RX_CCC_IT); + + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + + /* Call the receive complete callback */ +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + hi3c->CtrlRxCpltCallback(hi3c); +#else + HAL_I3C_CtrlRxCpltCallback(hi3c); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + } + else + { + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + + /* Call the receive complete callback */ +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + hi3c->CtrlRxCpltCallback(hi3c); +#else + HAL_I3C_CtrlRxCpltCallback(hi3c); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + + /* Then Initiate a Start condition */ + LL_I3C_RequestTransfer(hi3c->Instance); + } + } + } + return HAL_OK; +} + +/** + * @brief Interrupt Sub-Routine which handles controller multiple transmission/reception in interrupt mode. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param itFlags : [IN] Interrupt flags to handle. + * @param itSources : [IN] Interrupt sources enabled. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +static HAL_StatusTypeDef I3C_Ctrl_Multiple_Xfer_ISR(struct __I3C_HandleTypeDef *hi3c, + uint32_t itFlags, + uint32_t itSources) +{ + /* Check that a Tx/Rx process is ongoing */ + if (hi3c->State == HAL_I3C_STATE_BUSY_TX_RX) + { + /* Check if Control FIFO requests data */ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_CFNFF) != RESET) && + (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_CFNFIE) != RESET)) + { + if (hi3c->ControlXferCount > 0U) + { + /* Call control data treatment function */ + I3C_ControlDataTreatment(hi3c); + } + } + + /* I3C Tx FIFO not full interrupt Check */ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_TXFNFF) != RESET) && + (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_TXFNFIE) != RESET)) + { + if (hi3c->TxXferCount > 0U) + { + /* Call Transmit treatment function */ + hi3c->ptrTxFunc(hi3c); + } + } + + /* I3C Rx FIFO not empty interrupt Check */ + if ((I3C_CHECK_FLAG(itFlags, HAL_I3C_FLAG_RXFNEF) != RESET) && + (I3C_CHECK_IT_SOURCE(itSources, HAL_I3C_IT_RXFNEIE) != RESET)) + { + if (hi3c->RxXferCount > 0U) + { + /* Call receive treatment function */ + hi3c->ptrRxFunc(hi3c); + } + } + + /* I3C target frame complete event Check */ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_FCF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_FCIE) != RESET)) + { + /* Clear frame complete flag */ + LL_I3C_ClearFlag_FC(hi3c->Instance); + + if (hi3c->ControlXferCount == 0U) + { + /* Disable Tx process interrupts */ + I3C_Disable_IRQ(hi3c, I3C_XFER_CONTROLLER_TX_IT); + + /* Disable Rx process interrupts */ + I3C_Disable_IRQ(hi3c, I3C_XFER_CONTROLLER_RX_CCC_IT); + + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + + /* Call the transmit, receive complete callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + hi3c->CtrlMultipleXferCpltCallback(hi3c); +#else + HAL_I3C_CtrlMultipleXferCpltCallback(hi3c); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + } + else + { + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + + /* Then Initiate a Start condition */ + LL_I3C_RequestTransfer(hi3c->Instance); + } + } + } + return HAL_OK; +} + +/** + * @brief Interrupt Sub-Routine which handles controller CCC Dynamic Address Assignment command in interrupt mode. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param itFlags : [IN] Interrupt flags to handle. + * @param itSources : [IN] Interrupt sources enabled. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +static HAL_StatusTypeDef I3C_Ctrl_DAA_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources) +{ + uint64_t target_payload = 0U; + + /* Check that a Dynamic Address Assignment process is ongoing */ + if (hi3c->State == HAL_I3C_STATE_BUSY_DAA) + { + /* I3C Control FIFO not full interrupt Check */ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_CFNFF) != RESET) && + (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_CFNFIE) != RESET)) + { + /* Write ENTDAA CCC information in the control register */ + LL_I3C_ControllerHandleCCC(hi3c->Instance, I3C_BROADCAST_ENTDAA, 0U, LL_I3C_GENERATE_STOP); + } + + /* I3C Tx FIFO not full interrupt Check */ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_TXFNFF) != RESET) && + (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_TXFNFIE) != RESET)) + { + /* Check on the Rx FIFO threshold to know the Dynamic Address Assignment treatment process : byte or word */ + if (LL_I3C_GetRxFIFOThreshold(hi3c->Instance) == LL_I3C_RXFIFO_THRESHOLD_1_4) + { + /* For loop to get target payload */ + for (uint32_t index = 0U; index < 8U; index++) + { + /* Retrieve payload byte by byte */ + target_payload |= (uint64_t)((uint64_t)LL_I3C_ReceiveData8(hi3c->Instance) << (index * 8U)); + } + } + else + { + /* Retrieve first 32 bits payload */ + target_payload = (uint64_t)LL_I3C_ReceiveData32(hi3c->Instance); + + /* Retrieve second 32 bits payload */ + target_payload |= (uint64_t)((uint64_t)LL_I3C_ReceiveData32(hi3c->Instance) << 32U); + } + + /* Call the corresponding callback */ +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + hi3c->TgtReqDynamicAddrCallback(hi3c, target_payload); +#else + HAL_I3C_TgtReqDynamicAddrCallback(hi3c, target_payload); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS */ + } + + /* I3C frame complete event Check */ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_FCF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_FCIE) != RESET)) + { + /* Clear frame complete flag */ + LL_I3C_ClearFlag_FC(hi3c->Instance); + + /* Disable Dynamic Address Assignment process interrupts */ + I3C_Disable_IRQ(hi3c, I3C_XFER_CONTROLLER_DAA_IT); + + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + + /* Call the Dynamic Address Assignment complete callback */ +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + hi3c->CtrlDAACpltCallback(hi3c); +#else + HAL_I3C_CtrlDAACpltCallback(hi3c); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + } + } + return HAL_OK; +} + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief Interrupt Sub-Routine which handles controller transmit data in DMA mode. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param itFlags : [IN] Interrupt flags to handle. + * @param itSources : [IN] Interrupt sources enabled. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +static HAL_StatusTypeDef I3C_Ctrl_Tx_DMA_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources) +{ + /* Check that a Tx process is ongoing */ + if (hi3c->State == HAL_I3C_STATE_BUSY_TX) + { + /* I3C target frame complete event Check */ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_FCF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_FCIE) != RESET)) + { + /* Clear frame complete flag */ + LL_I3C_ClearFlag_FC(hi3c->Instance); + + if (I3C_GET_DMA_REMAIN_DATA(hi3c->hdmacr) == 0U) + { + /* Check if all data bytes are transmitted */ + if (I3C_GET_DMA_REMAIN_DATA(hi3c->hdmatx) == 0U) + { + /* Disable Tx process interrupts */ + I3C_Disable_IRQ(hi3c, I3C_XFER_DMA); + + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + + /* Update the number of remaining data bytes */ + hi3c->TxXferCount = 0U; + + /* Call controller transmit complete callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + hi3c->CtrlTxCpltCallback(hi3c); +#else + HAL_I3C_CtrlTxCpltCallback(hi3c); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + } + else + { + hi3c->ErrorCode = HAL_I3C_ERROR_SIZE; + + /* Call error treatment function */ + I3C_ErrorTreatment(hi3c); + } + } + else + { + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + + /* Call the transmit complete callback */ +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + hi3c->CtrlTxCpltCallback(hi3c); +#else + HAL_I3C_CtrlTxCpltCallback(hi3c); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + + /* Then Initiate a Start condition */ + LL_I3C_RequestTransfer(hi3c->Instance); + } + } + } + return HAL_OK; +} + +/** + * @brief Interrupt Sub-Routine which handles controller receive data in DMA mode. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param itFlags : [IN] Interrupt flags to handle. + * @param itSources : [IN] Interrupt sources enabled. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +static HAL_StatusTypeDef I3C_Ctrl_Rx_DMA_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources) +{ + /* Check that an Rx process is ongoing */ + if (hi3c->State == HAL_I3C_STATE_BUSY_RX) + { + /* I3C target frame complete event Check */ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_FCF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_FCIE) != RESET)) + { + /* Clear frame complete flag */ + LL_I3C_ClearFlag_FC(hi3c->Instance); + + if (I3C_GET_DMA_REMAIN_DATA(hi3c->hdmacr) == 0U) + { + /* Check if all data bytes are received */ + if (I3C_GET_DMA_REMAIN_DATA(hi3c->hdmarx) == 0U) + { + /* Disable Rx process interrupts */ + I3C_Disable_IRQ(hi3c, I3C_XFER_DMA); + + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + + /* Update the number of remaining data bytes */ + hi3c->RxXferCount = 0U; + + /* Call controller receive complete callback */ +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + hi3c->CtrlRxCpltCallback(hi3c); +#else + HAL_I3C_CtrlRxCpltCallback(hi3c); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + } + else + { + hi3c->ErrorCode = HAL_I3C_ERROR_SIZE; + + /* Call error treatment function */ + I3C_ErrorTreatment(hi3c); + } + } + else + { + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + + /* Call the receive complete callback */ +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + hi3c->CtrlRxCpltCallback(hi3c); +#else + HAL_I3C_CtrlRxCpltCallback(hi3c); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + + /* Then Initiate a Start condition */ + LL_I3C_RequestTransfer(hi3c->Instance); + } + } + } + return HAL_OK; +} + +/** + * @brief Interrupt Sub-Routine which handles controller multiple receive and transmit data in DMA mode. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param itFlags : [IN] Interrupt flags to handle. + * @param itSources : [IN] Interrupt sources enabled. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +static HAL_StatusTypeDef I3C_Ctrl_Multiple_Xfer_DMA_ISR(struct __I3C_HandleTypeDef *hi3c, + uint32_t itFlags, + uint32_t itSources) +{ + /* Check that an Rx or Tx process is ongoing */ + if (hi3c->State == HAL_I3C_STATE_BUSY_TX_RX) + { + /* I3C target frame complete event Check */ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_FCF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_FCIE) != RESET)) + { + /* Clear frame complete flag */ + LL_I3C_ClearFlag_FC(hi3c->Instance); + + if (I3C_GET_DMA_REMAIN_DATA(hi3c->hdmacr) == 0U) + { + /* Check if all data bytes are received or transmitted */ + if (I3C_GET_DMA_REMAIN_DATA(hi3c->hdmarx) == 0U) + { + if (I3C_GET_DMA_REMAIN_DATA(hi3c->hdmatx) == 0U) + { + /* Disable transfer Tx/Rx process interrupts */ + I3C_Disable_IRQ(hi3c, I3C_XFER_DMA); + + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + + /* Update the number of remaining data bytes */ + hi3c->RxXferCount = 0U; + + /* Update the number of remaining data bytes */ + hi3c->TxXferCount = 0U; + + /* Call controller transmit, receive complete callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1U) + hi3c->CtrlMultipleXferCpltCallback(hi3c); +#else + HAL_I3C_CtrlMultipleXferCpltCallback(hi3c); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS == 1U */ + } + else + { + hi3c->ErrorCode = HAL_I3C_ERROR_SIZE; + + /* Call error treatment function */ + I3C_ErrorTreatment(hi3c); + } + } + else + { + hi3c->ErrorCode = HAL_I3C_ERROR_SIZE; + + /* Call error treatment function */ + I3C_ErrorTreatment(hi3c); + } + } + else + { + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + + /* Then Initiate a Start condition */ + LL_I3C_RequestTransfer(hi3c->Instance); + } + } + } + return HAL_OK; +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Interrupt Sub-Routine which handles abort process in interrupt mode. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information + * for the specified I3C. + * @param itFlags : [IN] Interrupt flags to handle. + * @param itSources : [IN] Interrupt sources enabled. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +static HAL_StatusTypeDef I3C_Abort_ISR(struct __I3C_HandleTypeDef *hi3c, uint32_t itFlags, uint32_t itSources) +{ + /* Check that an Abort process is ongoing */ + if (hi3c->State == HAL_I3C_STATE_ABORT) + { + /* I3C Rx FIFO not empty interrupt Check */ + if ((I3C_CHECK_FLAG(itFlags, HAL_I3C_FLAG_RXFNEF) != RESET) && + (I3C_CHECK_IT_SOURCE(itSources, HAL_I3C_IT_RXFNEIE) != RESET)) + { + if (LL_I3C_IsActiveFlag_DOVR(hi3c->Instance) == 1U) + { + /* Flush remaining Rx data */ + LL_I3C_RequestRxFIFOFlush(hi3c->Instance); + } + } + + /* I3C Abort frame complete event Check */ + /* Evenif abort is called, the Frame completion can arrive if abort is requested at the end of the processus */ + /* Evenif completion occurs, treat this end of processus as abort completion process */ + if ((I3C_CHECK_FLAG(itFlags, I3C_EVR_FCF) != RESET) && (I3C_CHECK_IT_SOURCE(itSources, I3C_IER_FCIE) != RESET)) + { + /* Clear frame complete flag */ + LL_I3C_ClearFlag_FC(hi3c->Instance); + + /* Call error treatment function */ + I3C_ErrorTreatment(hi3c); + } + } + return HAL_OK; +} + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief DMA I3C control transmit process complete callback. + * @param hdma : [IN] Pointer to a DMA_HandleTypeDef structure that contains the configuration information + * for the specified DMA channel. + * @retval None + */ +static void I3C_DMAControlTransmitCplt(DMA_HandleTypeDef *hdma) +{ + /* Get the address of the I3C handle : Derogation MISRAC2012-Rule-11.5 */ + I3C_HandleTypeDef *hi3c = (I3C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); + + /* Disable control DMA Request */ + LL_I3C_DisableDMAReq_Control(hi3c->Instance); +} + +/** + * @brief DMA I3C transmit data process complete callback. + * @param hdma : [IN] Pointer to a DMA_HandleTypeDef structure that contains the configuration information + * for the specified DMA channel. + * @retval None + */ +static void I3C_DMADataTransmitCplt(DMA_HandleTypeDef *hdma) +{ + /* Get the address of the I3C handle : Derogation MISRAC2012-Rule-11.5 */ + I3C_HandleTypeDef *hi3c = (I3C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); + + /* Disable Tx DMA Request */ + LL_I3C_DisableDMAReq_TX(hi3c->Instance); +} + +/** + * @brief DMA I3C receive data process complete callback. + * @param hdma : [IN] Pointer to a DMA_HandleTypeDef structure that contains the configuration information + * for the specified DMA channel. + * @retval None + */ +static void I3C_DMADataReceiveCplt(DMA_HandleTypeDef *hdma) +{ + /* Get the address of the I3C handle : Derogation MISRAC2012-Rule-11.5 */ + I3C_HandleTypeDef *hi3c = (I3C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); + + /* Disable Rx DMA Request */ + LL_I3C_DisableDMAReq_RX(hi3c->Instance); +} + +/** + * @brief DMA I3C communication error callback. + * @param hdma : [IN] Pointer to a DMA_HandleTypeDef structure that contains the configuration information + * for the specified DMA channel. + * @retval None + */ +static void I3C_DMAError(DMA_HandleTypeDef *hdma) +{ + /* Just to solve MisraC error then to be removed */ + /* Derogation MISRAC2012-Rule-11.5 */ + I3C_HandleTypeDef *hi3c = (I3C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); + + hi3c->ErrorCode |= HAL_I3C_ERROR_DMA; +} + +/** + * @brief DMA I3C communication abort callback to be called at end of DMA Abort procedure. + * @param hdma : [IN] Pointer to a DMA_HandleTypeDef structure that contains the configuration information + * for the specified DMA channel. + * @retval None + */ +static void I3C_DMAAbort(DMA_HandleTypeDef *hdma) +{ + /* Derogation MISRAC2012-Rule-11.5 */ + I3C_HandleTypeDef *hi3c = (I3C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); + + /* Reset Tx DMA AbortCpltCallback */ + if (hi3c->hdmatx != NULL) + { + hi3c->hdmatx->XferAbortCallback = NULL; + } + + /* Reset Rx DMA AbortCpltCallback */ + if (hi3c->hdmarx != NULL) + { + hi3c->hdmarx->XferAbortCallback = NULL; + } + + /* Reset control DMA AbortCpltCallback */ + if (hi3c->hdmacr != NULL) + { + hi3c->hdmacr->XferAbortCallback = NULL; + } + + I3C_TreatErrorCallback(hi3c); +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief This function handles I3C Communication Timeout. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @param flag : [IN] Specifies the I3C flag to check. + * @param flagstatus : [IN] The new Flag status (SET or RESET). + * @param timeout : [IN] Timeout duration in millisecond. + * @param tickstart : [IN] Tick start value + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +static HAL_StatusTypeDef I3C_WaitOnFlagUntilTimeout(I3C_HandleTypeDef *hi3c, uint32_t flag, FlagStatus flagstatus, + uint32_t timeout, uint32_t tickstart) +{ + HAL_StatusTypeDef status = HAL_OK; + + while ((__HAL_I3C_GET_FLAG(hi3c, flag) == flagstatus) && (status == HAL_OK)) + { + /* Check for the Timeout */ + if (timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > timeout) || (timeout == 0U)) + { + if (__HAL_I3C_GET_FLAG(hi3c, flag) == flagstatus) + { + hi3c->ErrorCode = HAL_I3C_ERROR_TIMEOUT; + status = HAL_TIMEOUT; + } + } + } + + /* Check if an error occurs during Flag waiting */ + if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET) + { + /* Clear error flag */ + LL_I3C_ClearFlag_ERR(hi3c->Instance); + + /* Update handle error code parameter */ + I3C_GetErrorSources(hi3c); + + status = HAL_ERROR; + } + } + return status; +} + +/** + * @brief This function handles I3C Dynamic Address Assignment timeout. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @param timeout : [IN] Timeout duration in millisecond. + * @param tickstart : [IN] Tick start value + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +static HAL_StatusTypeDef I3C_WaitOnDAAUntilTimeout(I3C_HandleTypeDef *hi3c, uint32_t timeout, uint32_t tickstart) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t active_flags = READ_REG(hi3c->Instance->EVR); + + while (((active_flags & (HAL_I3C_FLAG_FCF | HAL_I3C_FLAG_TXFNFF)) == 0U) && (status == HAL_OK)) + { + /* Check for the Timeout */ + if (timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > timeout) || (timeout == 0U)) + { + if ((active_flags & (HAL_I3C_FLAG_FCF | HAL_I3C_FLAG_TXFNFF)) == 0U) + { + hi3c->ErrorCode |= HAL_I3C_ERROR_TIMEOUT; + status = HAL_TIMEOUT; + } + } + } + + /* Check if an error occurs during Flag waiting */ + if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_ERRF) == SET) + { + /* Clear error flag */ + LL_I3C_ClearFlag_ERR(hi3c->Instance); + + /* Update handle error code parameter */ + I3C_GetErrorSources(hi3c); + + status = HAL_ERROR; + } + + /* Read active flags from EVR register */ + active_flags = READ_REG(hi3c->Instance->EVR); + } + return status; +} + +/** + * @brief I3C transmit by byte. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @retval None + */ +static void I3C_TransmitByteTreatment(I3C_HandleTypeDef *hi3c) +{ + /* Check TX FIFO not full flag */ + while ((__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_TXFNFF) == SET) && (hi3c->TxXferCount > 0U)) + { + /* Write Tx buffer data to transmit register */ + LL_I3C_TransmitData8(hi3c->Instance, *hi3c->pXferData->TxBuf.pBuffer); + + /* Increment Buffer pointer */ + hi3c->pXferData->TxBuf.pBuffer++; + + /* Decrement remaining bytes counter */ + hi3c->TxXferCount--; + } +} + +/** + * @brief I3C transmit by word. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @retval None + */ +static void I3C_TransmitWordTreatment(I3C_HandleTypeDef *hi3c) +{ + /* Check TX FIFO not full flag */ + while (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_TXFNFF) == SET) + { + /* Write Tx buffer data to transmit register */ + LL_I3C_TransmitData32(hi3c->Instance, *((uint32_t *)hi3c->pXferData->TxBuf.pBuffer)); + + /* Increment Buffer pointer */ + hi3c->pXferData->TxBuf.pBuffer += sizeof(uint32_t); + + if (hi3c->TxXferCount < sizeof(uint32_t)) + { + hi3c->TxXferCount = 0U; + } + else + { + /* Decrement remaining bytes counter */ + hi3c->TxXferCount -= sizeof(uint32_t); + } + } +} + +/** + * @brief I3C receive by byte. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @retval None + */ +static void I3C_ReceiveByteTreatment(I3C_HandleTypeDef *hi3c) +{ + /* Check RX FIFO not empty flag */ + while (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_RXFNEF) == SET) + { + /* Store received bytes in the Rx buffer */ + *hi3c->pXferData->RxBuf.pBuffer = LL_I3C_ReceiveData8(hi3c->Instance); + + /* Increment Buffer pointer */ + hi3c->pXferData->RxBuf.pBuffer++; + + /* Decrement remaining bytes counter */ + hi3c->RxXferCount--; + } +} + +/** + * @brief I3C receive by word. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @retval None + */ +static void I3C_ReceiveWordTreatment(I3C_HandleTypeDef *hi3c) +{ + /* Check RX FIFO not empty flag */ + while (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_RXFNEF) == SET) + { + /* Store received bytes in the Rx buffer */ + *((uint32_t *)hi3c->pXferData->RxBuf.pBuffer) = LL_I3C_ReceiveData32(hi3c->Instance); + + /* Increment Buffer pointer */ + hi3c->pXferData->RxBuf.pBuffer += sizeof(uint32_t); + + if (hi3c->RxXferCount > sizeof(uint32_t)) + { + /* Decrement remaining bytes counter */ + hi3c->RxXferCount -= sizeof(uint32_t); + } + else + { + /* Reset counter as last modulo word Rx data received */ + hi3c->RxXferCount = 0U; + } + } +} + +/** + * @brief I3C Control data treatment. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @retval None + */ +static void I3C_ControlDataTreatment(I3C_HandleTypeDef *hi3c) +{ + /* Check if Control FIFO requests data */ + if (__HAL_I3C_GET_FLAG(hi3c, HAL_I3C_FLAG_CFNFF) == SET) + { + /* Decrement remaining control buffer data counter */ + hi3c->ControlXferCount--; + + /* Write Control buffer data to control register */ + WRITE_REG(hi3c->Instance->CR, *hi3c->pXferData->CtrlBuf.pBuffer); + + /* Increment Buffer pointer */ + hi3c->pXferData->CtrlBuf.pBuffer++; + } +} + +/** + * @brief I3C state update. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @retval None + */ +static void I3C_StateUpdate(I3C_HandleTypeDef *hi3c) +{ + /* Check on previous state */ + if (hi3c->PreviousState == HAL_I3C_STATE_LISTEN) + { + /* Set state to listen */ + hi3c->State = HAL_I3C_STATE_LISTEN; + + /* Check the I3C mode */ + if (hi3c->Mode == HAL_I3C_MODE_TARGET) + { + /* Store the target event treatment function */ + hi3c->XferISR = I3C_Tgt_Event_ISR; + } + else + { + /* Store the controller event treatment function */ + hi3c->XferISR = I3C_Ctrl_Event_ISR; + } + } + else + { + /* Set state to ready */ + hi3c->State = HAL_I3C_STATE_READY; + + /* Reset XferISR */ + hi3c->XferISR = NULL; + } +} + +/** + * @brief I3C get error source. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @retval None + */ +static void I3C_GetErrorSources(I3C_HandleTypeDef *hi3c) +{ + /* Check on the I3C mode */ + switch (hi3c->Mode) + { + case HAL_I3C_MODE_CONTROLLER: + { + /* I3C data error during controller-role hand-off procedure */ + if (LL_I3C_IsActiveFlag_DERR(hi3c->Instance) == 1U) + { + hi3c->ErrorCode |= HAL_I3C_ERROR_DATA_HAND_OFF; + } + + /* I3C data not acknowledged error */ + if (LL_I3C_IsActiveFlag_DNACK(hi3c->Instance) == 1U) + { + hi3c->ErrorCode |= HAL_I3C_ERROR_DATA_NACK; + } + + /* I3C address not acknowledged error */ + if (LL_I3C_IsActiveFlag_ANACK(hi3c->Instance) == 1U) + { + hi3c->ErrorCode |= HAL_I3C_ERROR_ADDRESS_NACK; + } + + /* I3C Status FIFO Over-Run or Control FIFO Under-Run error */ + if (LL_I3C_IsActiveFlag_COVR(hi3c->Instance) == 1U) + { + hi3c->ErrorCode |= HAL_I3C_ERROR_COVR; + } + + break; + } + + case HAL_I3C_MODE_TARGET: + { + /* I3C SCL stall error */ + if (LL_I3C_IsActiveFlag_STALL(hi3c->Instance) == 1U) + { + hi3c->ErrorCode |= HAL_I3C_ERROR_STALL; + } + + break; + } + + default: + { + break; + } + } + + /* I3C Rx FIFO Over-Run or Tx FIFO Under-Run error */ + if (LL_I3C_IsActiveFlag_DOVR(hi3c->Instance) == 1U) + { + hi3c->ErrorCode |= HAL_I3C_ERROR_DOVR; + } + + /* I3C Protocol error */ + if (LL_I3C_IsActiveFlag_PERR(hi3c->Instance) == 1U) + { + hi3c->ErrorCode |= (I3C_SER_PERR | LL_I3C_GetMessageErrorCode(hi3c->Instance)); + } +} + +/** + * @brief I3C transfer prior preparation. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @param counter : [IN] Number of devices or commands to treat. + * @param option : [IN] Parameter indicates the transfer option. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +static HAL_StatusTypeDef I3C_Xfer_PriorPreparation(I3C_HandleTypeDef *hi3c, uint8_t counter, uint32_t option) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t current_tx_index = 0U; + uint32_t global_tx_size = 0U; + uint32_t global_rx_size = 0U; + uint32_t nb_tx_frame = 0U; + uint32_t direction; + + for (uint32_t descr_index = 0U; descr_index < counter; descr_index++) + { + /* Direct CCC command */ + if ((option & I3C_OPERATION_TYPE_MASK) == LL_I3C_CONTROLLER_MTYPE_DIRECT) + { + /* Update direction of frame */ + direction = hi3c->pCCCDesc[descr_index].Direction; + + /* Direction read with Define byte */ + if (((option & I3C_DEFINE_BYTE_MASK) != 0U) && (direction == HAL_I3C_DIRECTION_READ)) + { + nb_tx_frame += 1U; + + global_tx_size += 1U; + + global_rx_size += hi3c->pCCCDesc[descr_index].CCCBuf.Size - 1U; + + /* Check on the global size and on the Tx buffer pointer */ + if ((global_tx_size > hi3c->pXferData->TxBuf.Size) || \ + (current_tx_index > hi3c->pXferData->TxBuf.Size) || \ + (hi3c->pXferData->TxBuf.pBuffer == NULL)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + + status = HAL_ERROR; + } + else + { + /* Fill global Tx buffer with data and update the current index of the Tx buffer */ + current_tx_index = I3C_FillTxBuffer_CCC(hi3c, descr_index, 1U, current_tx_index); + } + } + else if (direction == HAL_I3C_DIRECTION_WRITE) + { + nb_tx_frame += 1U; + + global_tx_size += hi3c->pCCCDesc[descr_index].CCCBuf.Size; + + /* Check on the global size and on the Tx buffer pointer */ + if ((global_tx_size > hi3c->pXferData->TxBuf.Size) || \ + (current_tx_index > hi3c->pXferData->TxBuf.Size) || \ + (hi3c->pXferData->TxBuf.pBuffer == NULL)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + + status = HAL_ERROR; + } + else + { + /* Fill global Tx buffer with data and update the current index of the Tx buffer */ + current_tx_index = I3C_FillTxBuffer_CCC(hi3c, + descr_index, + hi3c->pCCCDesc[descr_index].CCCBuf.Size, + current_tx_index); + } + } + /* Direction read without Define byte */ + else + { + global_rx_size += hi3c->pCCCDesc[descr_index].CCCBuf.Size; + } + } + /* Broadcast CCC command */ + else if ((option & I3C_OPERATION_TYPE_MASK) == LL_I3C_CONTROLLER_MTYPE_CCC) + { + /* Update direction of frame */ + direction = hi3c->pCCCDesc[descr_index].Direction; + + if (direction == HAL_I3C_DIRECTION_WRITE) + { + nb_tx_frame += 1U; + + global_tx_size += hi3c->pCCCDesc[descr_index].CCCBuf.Size; + + /* Check on the global size and on the Tx buffer pointer */ + if ((global_tx_size > hi3c->pXferData->TxBuf.Size) || \ + (current_tx_index > hi3c->pXferData->TxBuf.Size) || \ + (hi3c->pXferData->TxBuf.pBuffer == NULL)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + + status = HAL_ERROR; + } + else + { + /* Fill global Tx buffer with data and update the current index of the Tx buffer */ + current_tx_index = I3C_FillTxBuffer_CCC(hi3c, + descr_index, + hi3c->pCCCDesc[descr_index].CCCBuf.Size, + current_tx_index); + } + } + else + { + status = HAL_ERROR; + } + } + /* Private */ + else + { + /* Update direction of frame */ + direction = hi3c->pPrivateDesc[descr_index].Direction; + + if (direction == HAL_I3C_DIRECTION_WRITE) + { + nb_tx_frame += 1U; + + global_tx_size += hi3c->pPrivateDesc[descr_index].TxBuf.Size; + + /* Check on the global size and on the Tx buffer pointer */ + if ((global_tx_size > hi3c->pXferData->TxBuf.Size) || \ + (current_tx_index > hi3c->pXferData->TxBuf.Size) || \ + (hi3c->pXferData->TxBuf.pBuffer == NULL)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + + status = HAL_ERROR; + } + else + { + /* Fill global Tx buffer with data and update the current index of the Tx buffer */ + current_tx_index = I3C_FillTxBuffer_Private(hi3c, + descr_index, + hi3c->pPrivateDesc[descr_index].TxBuf.Size, + current_tx_index); + } + } + else + { + global_rx_size += hi3c->pPrivateDesc[descr_index].RxBuf.Size; + } + } + + /* Check if there is an error in the Tx Buffer*/ + if (status == HAL_ERROR) + { + break; + } + } + + if (status == HAL_OK) + { + /* Check on the Tx threshold and the number of Tx frame */ + if (LL_I3C_GetTxFIFOThreshold(hi3c->Instance) == LL_I3C_TXFIFO_THRESHOLD_4_4) + { + /* LL_I3C_TXFIFO_THRESHOLD_4_4 is not allowed when the transfer descriptor contains + multiple transmission frames */ + if (nb_tx_frame > 1U) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + } + } + + if (status == HAL_OK) + { + /* Check on the size Rx buffer */ + if (global_rx_size > hi3c->pXferData->RxBuf.Size) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + else + { + hi3c->RxXferCount = global_rx_size; + } + + /* Set handle transfer parameters */ + hi3c->TxXferCount = global_tx_size; + } + + return status; +} + +/** + * @brief I3C fill Tx Buffer with data from CCC Descriptor. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @param indexDesc : [IN] Index of descriptor. + * @param txSize : [IN] Size of Tx data. + * @param txCurrentIndex : [IN] Current Index of TxBuffer. + * @retval index_tx : [OUT] New current Index of TxBuffer. + */ +static uint32_t I3C_FillTxBuffer_CCC(I3C_HandleTypeDef *hi3c, + uint32_t indexDesc, + uint32_t txSize, + uint32_t txCurrentIndex) +{ + uint32_t index_tx = txCurrentIndex; + + for (uint32_t index = 0U; index < txSize; index++) + { + hi3c->pXferData->TxBuf.pBuffer[index_tx] = hi3c->pCCCDesc[indexDesc].CCCBuf.pBuffer[index]; + + index_tx++; + } + + return index_tx; +} + +/** + * @brief I3C fill Tx Buffer with data from Private Descriptor. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @param indexDesc : [IN] Index of descriptor. + * @param txSize : [IN] Size of Tx data. + * @param txCurrentIndex : [IN] Current Index of TxBuffer. + * @retval index_tx : [OUT] New current Index of TxBuffer. + */ +static uint32_t I3C_FillTxBuffer_Private(I3C_HandleTypeDef *hi3c, + uint32_t indexDesc, + uint32_t txSize, + uint32_t txCurrentIndex) +{ + uint32_t index_tx = txCurrentIndex; + + for (uint32_t index = 0U; index < txSize; index++) + { + hi3c->pXferData->TxBuf.pBuffer[index_tx] = hi3c->pPrivateDesc[indexDesc].TxBuf.pBuffer[index]; + + index_tx++; + } + + return index_tx; +} + +/** + * @brief I3C Control buffer prior preparation. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @param counter : [IN] Number of devices or commands to treat. + * @param option : [IN] Parameter indicates the transfer option. + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +static HAL_StatusTypeDef I3C_ControlBuffer_PriorPreparation(I3C_HandleTypeDef *hi3c, + uint8_t counter, + uint32_t option) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t nb_define_bytes; + uint32_t stop_condition; + uint32_t nb_data_bytes; + uint32_t index; + + /* Check on the control buffer pointer */ + if (hi3c->pXferData->CtrlBuf.pBuffer == NULL) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + else + { + /* Extract from option required information */ + nb_define_bytes = (option & I3C_DEFINE_BYTE_MASK); + stop_condition = (option & I3C_RESTART_STOP_MASK); + + /* Check on the deactivation of the arbitration */ + if ((option & I3C_ARBITRATION_HEADER_MASK) == I3C_ARBITRATION_HEADER_MASK) + { + /* Disable arbitration header */ + LL_I3C_DisableArbitrationHeader(hi3c->Instance); + } + else + { + /* Enable arbitration header */ + LL_I3C_EnableArbitrationHeader(hi3c->Instance); + } + + /* Check on the operation type */ + if ((option & I3C_OPERATION_TYPE_MASK) == LL_I3C_CONTROLLER_MTYPE_CCC) + { + /*------------------------------------------ Broadcast CCC -----------------------------------------------------*/ + /* Check on the control buffer size */ + if (hi3c->pXferData->CtrlBuf.Size < (uint32_t)counter) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + else + { + /* Set remaining control buffer data counter */ + hi3c->ControlXferCount = (uint32_t)counter; + + /* For loop on the number of commands */ + for (index = 0U; index < ((uint32_t)counter - 1U); index++) + { + /* Update control buffer value */ + hi3c->pXferData->CtrlBuf.pBuffer[index] = ((uint32_t)hi3c->pCCCDesc[index].CCCBuf.Size | + ((uint32_t)hi3c->pCCCDesc[index].CCC << I3C_CR_CCC_Pos) | + LL_I3C_CONTROLLER_MTYPE_CCC | stop_condition); + } + + /* At the last device we should generate a stop condition */ + hi3c->pXferData->CtrlBuf.pBuffer[index] = ((uint32_t)hi3c->pCCCDesc[index].CCCBuf.Size | + ((uint32_t)hi3c->pCCCDesc[index].CCC << I3C_CR_CCC_Pos) | + LL_I3C_CONTROLLER_MTYPE_CCC | LL_I3C_GENERATE_STOP); + } + } + else if ((option & I3C_OPERATION_TYPE_MASK) == LL_I3C_CONTROLLER_MTYPE_DIRECT) + { + /*------------------------------------------ Direct CCC --------------------------------------------------------*/ + /* Check on the control buffer size */ + if (hi3c->pXferData->CtrlBuf.Size < ((uint32_t)counter * 2U)) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + else + { + /* Set remaining control buffer data counter */ + hi3c->ControlXferCount = ((uint32_t)counter * 2U); + + /* For loop on the number of (devices or commands) * 2 */ + for (index = 0U; index < (((uint32_t)counter * 2U) - 2U); index += 2U) + { + /* Step 1 : update control buffer value for the CCC command */ + hi3c->pXferData->CtrlBuf.pBuffer[index] = (nb_define_bytes | + ((uint32_t)hi3c->pCCCDesc[index / 2U].CCC << I3C_CR_CCC_Pos) | + LL_I3C_CONTROLLER_MTYPE_CCC | LL_I3C_GENERATE_RESTART); + + /* Step 2 : update control buffer value for target address */ + hi3c->pXferData->CtrlBuf.pBuffer[index + 1U] = + (((uint32_t)hi3c->pCCCDesc[index / 2U].CCCBuf.Size - nb_define_bytes) | + hi3c->pCCCDesc[index / 2U].Direction | + ((uint32_t)hi3c->pCCCDesc[index / 2U].TargetAddr << I3C_CR_ADD_Pos) | + LL_I3C_CONTROLLER_MTYPE_DIRECT | stop_condition); + } + + /* Update control buffer value for the last CCC command */ + hi3c->pXferData->CtrlBuf.pBuffer[index] = (nb_define_bytes | + ((uint32_t)hi3c->pCCCDesc[index / 2U].CCC << I3C_CR_CCC_Pos) | + LL_I3C_CONTROLLER_MTYPE_CCC | LL_I3C_GENERATE_RESTART); + + /* At the last device we should generate a stop condition */ + hi3c->pXferData->CtrlBuf.pBuffer[index + 1U] = + (((uint32_t)hi3c->pCCCDesc[index / 2U].CCCBuf.Size - nb_define_bytes) | + hi3c->pCCCDesc[index / 2U].Direction | + ((uint32_t)hi3c->pCCCDesc[index / 2U].TargetAddr << I3C_CR_ADD_Pos) | + LL_I3C_CONTROLLER_MTYPE_DIRECT | LL_I3C_GENERATE_STOP); + } + } + else + { + /*------------------------------------------ Private I3C/I2C ---------------------------------------------------*/ + /* Check on the control buffer size */ + if (hi3c->pXferData->CtrlBuf.Size < (uint32_t)counter) + { + hi3c->ErrorCode = HAL_I3C_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + else + { + /* Set remaining control buffer data counter */ + hi3c->ControlXferCount = (uint32_t)counter; + + /* For loop on the number of devices */ + for (index = 0U; index < ((uint32_t)counter - 1U); index++) + { + /* Check on transfer direction */ + if (hi3c->pPrivateDesc[index].Direction == HAL_I3C_DIRECTION_READ) + { + nb_data_bytes = hi3c->pPrivateDesc[index].RxBuf.Size; + } + else + { + nb_data_bytes = hi3c->pPrivateDesc[index].TxBuf.Size; + } + + /* Update control buffer value */ + hi3c->pXferData->CtrlBuf.pBuffer[index] = + (nb_data_bytes | hi3c->pPrivateDesc[index].Direction | + ((uint32_t)hi3c->pPrivateDesc[index].TargetAddr << I3C_CR_ADD_Pos) | + (option & I3C_OPERATION_TYPE_MASK) | stop_condition); + } + + /* Check on transfer direction */ + if (hi3c->pPrivateDesc[index].Direction == HAL_I3C_DIRECTION_READ) + { + nb_data_bytes = hi3c->pPrivateDesc[index].RxBuf.Size; + } + else + { + nb_data_bytes = hi3c->pPrivateDesc[index].TxBuf.Size; + } + + /* At the last device we should generate a stop condition */ + hi3c->pXferData->CtrlBuf.pBuffer[index] = + (nb_data_bytes | hi3c->pPrivateDesc[index].Direction | + ((uint32_t)hi3c->pPrivateDesc[index].TargetAddr << I3C_CR_ADD_Pos) | + (option & I3C_OPERATION_TYPE_MASK) | LL_I3C_GENERATE_STOP); + } + } + } + + return status; +} + +/** + * @brief Check if target device is ready for communication. + * @param hi3c : Pointer to a I3C_HandleTypeDef structure that contains + * the configuration information for the specified I3C. + * @param pDevice : [IN] Structure to define the device address and the device type. + * @param trials : [IN] Number of trials + * @param timeout : [IN] Timeout duration + * @retval HAL Status : Value from HAL_StatusTypeDef enumeration. + */ +static HAL_StatusTypeDef I3C_Ctrl_IsDevice_Ready(I3C_HandleTypeDef *hi3c, + const I3C_DeviceTypeDef *pDevice, + uint32_t trials, + uint32_t timeout) +{ + __IO uint32_t I3C_Trials = 0UL; + __IO uint32_t exit_condition; + uint32_t CR_tmp; + uint32_t tickstart; + HAL_StatusTypeDef status = HAL_OK; + HAL_I3C_StateTypeDef handle_state; + uint32_t arbitration_previous_state; + + /* Get I3C handle state */ + handle_state = hi3c->State; + + /* check on the Mode */ + if (hi3c->Mode != HAL_I3C_MODE_CONTROLLER) + { + hi3c->ErrorCode = HAL_I3C_ERROR_NOT_ALLOWED; + status = HAL_ERROR; + } + /* check on the State */ + else if ((handle_state != HAL_I3C_STATE_READY) && (handle_state != HAL_I3C_STATE_LISTEN)) + { + status = HAL_BUSY; + } + else + { + /* Set handle transfer parameters */ + hi3c->ErrorCode = HAL_I3C_ERROR_NONE; + hi3c->State = HAL_I3C_STATE_BUSY; + + /* Before modify the arbitration, get the current arbitration state */ + arbitration_previous_state = LL_I3C_IsEnabledArbitrationHeader(hi3c->Instance); + + /* Disable arbitration header */ + LL_I3C_DisableArbitrationHeader(hi3c->Instance); + + CR_tmp = (HAL_I3C_DIRECTION_WRITE | + ((uint32_t)pDevice->Address << I3C_CR_ADD_Pos) | + pDevice->MessageType | LL_I3C_GENERATE_STOP); + + do + { + /* Initiate a start condition by writing in the CR register */ + WRITE_REG(hi3c->Instance->CR, CR_tmp); + + /* Calculate exit_condition value based on Frame complete and error flags */ + exit_condition = (READ_REG(hi3c->Instance->EVR) & (I3C_EVR_FCF | I3C_EVR_ERRF)); + + tickstart = HAL_GetTick(); + + while (exit_condition == 0U) + { + if (timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > timeout) || (timeout == 0U)) + { + /* Update I3C error code */ + hi3c->ErrorCode |= HAL_I3C_ERROR_TIMEOUT; + status = HAL_TIMEOUT; + + break; + } + } + /* Calculate exit_condition value based on Frame complete and error flags */ + exit_condition = (READ_REG(hi3c->Instance->EVR) & (I3C_EVR_FCF | I3C_EVR_ERRF)); + } + + if (status == HAL_OK) + { + /* Check if the FCF flag has been set */ + if (__HAL_I3C_GET_FLAG(hi3c, I3C_EVR_FCF) == SET) + { + /* Clear frame complete flag */ + LL_I3C_ClearFlag_FC(hi3c->Instance); + + /* Device is ready */ + break; + } + else + { + /* Clear ERR flag */ + LL_I3C_ClearFlag_ERR(hi3c->Instance); + } + } + + /* Increment Trials */ + I3C_Trials++; + + } while ((I3C_Trials < trials) && (status == HAL_OK)); + + /* Device is not ready */ + if (trials == I3C_Trials) + { + hi3c->ErrorCode = HAL_I3C_ERROR_ADDRESS_NACK; + status = HAL_ERROR; + } + + /* update state to Previous state */ + I3C_StateUpdate(hi3c); + + /* Check if previous arbitration state is enabled */ + if (arbitration_previous_state == 1U) + { + LL_I3C_EnableArbitrationHeader(hi3c->Instance); + } + } + + return status; +} + +/** + * @brief Manage the enabling of Interrupts. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @param InterruptRequest : [IN] Value of the interrupt request + * @retval None + */ +static void I3C_Enable_IRQ(I3C_HandleTypeDef *hi3c, uint32_t InterruptRequest) +{ + uint32_t tmpisr = 0U; + + /* Check if requested interrupts are related to listening mode */ + if ((InterruptRequest & I3C_XFER_LISTEN_IT) != 0U) + { + tmpisr |= ((InterruptRequest & (~I3C_XFER_LISTEN_IT)) | HAL_I3C_IT_ERRIE); + } + + /* Check if requested interrupts are related to target transmit in IT mode */ + if ((InterruptRequest & I3C_XFER_TARGET_TX_IT) != 0U) + { + /* Enable frame complete, transmit FIFO not full and error interrupts */ + tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_TXFNFIE | HAL_I3C_IT_ERRIE); + } + + /* Check if requested interrupts are related to target receive in IT mode */ + if ((InterruptRequest & I3C_XFER_TARGET_RX_IT) != 0U) + { + /* Enable frame complete, receive FIFO not empty and error interrupts */ + tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_RXFNEIE | HAL_I3C_IT_ERRIE) ; + } + + /* Check if requested interrupts are related to transmit/receive in DMA mode */ + if ((InterruptRequest & I3C_XFER_DMA) != 0U) + { + /* Enable frame complete and error interrupts */ + tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_ERRIE); + } + + /* Check if requested interrupts are related to target hot join */ + if ((InterruptRequest & I3C_XFER_TARGET_HOTJOIN) != 0U) + { + /* Enable dynamic address update and error interrupts */ + tmpisr |= (HAL_I3C_IT_DAUPDIE | HAL_I3C_IT_ERRIE); + } + + /* Check if requested interrupts are related to target control role */ + if ((InterruptRequest & I3C_XFER_TARGET_CTRLROLE) != 0U) + { + /* Enable control role update and error interrupts */ + tmpisr |= (HAL_I3C_IT_CRUPDIE | HAL_I3C_IT_ERRIE); + } + + /* Check if requested interrupts are related to target in band interrupt */ + if ((InterruptRequest & I3C_XFER_TARGET_IBI) != 0U) + { + /* Enable IBI end and error interrupts */ + tmpisr |= (HAL_I3C_IT_IBIENDIE | HAL_I3C_IT_ERRIE); + } + + /* Check if requested interrupts are related to controller transmit in IT mode */ + if ((InterruptRequest & I3C_XFER_CONTROLLER_TX_IT) != 0U) + { + /* Enable frame complete, control FIFO not full, transmit FIFO not full and error interrupts */ + tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_CFNFIE | HAL_I3C_IT_TXFNFIE | HAL_I3C_IT_ERRIE); + } + + /* Check if requested interrupts are related to controller receive in IT mode */ + if ((InterruptRequest & I3C_XFER_CONTROLLER_RX_IT) != 0U) + { + /* Enable frame complete, control FIFO not full, receive FIFO not empty and error interrupts */ + tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_CFNFIE | HAL_I3C_IT_RXFNEIE | HAL_I3C_IT_ERRIE); + } + + /* Check if requested interrupts are related to controller transmit read or a broadcast CCC in IT mode */ + if ((InterruptRequest & I3C_XFER_CONTROLLER_RX_CCC_IT) != 0U) + { + /* Enable frame complete, transmit FIFO not full, control FIFO not full, + receive FIFO not empty and error interrupts */ + tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_TXFNFIE | HAL_I3C_IT_CFNFIE | HAL_I3C_IT_RXFNEIE | HAL_I3C_IT_ERRIE); + } + + /* Check if requested interrupts are related to controller transmit broadcast ENTDAA CCC in IT mode */ + if ((InterruptRequest & I3C_XFER_CONTROLLER_DAA_IT) != 0U) + { + /* Enable frame complete, control FIFO not full, transmit FIFO not full and error interrupts */ + tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_CFNFIE | HAL_I3C_IT_TXFNFIE | HAL_I3C_IT_ERRIE); + } + + /* Enable requested interrupts */ + __HAL_I3C_ENABLE_IT(hi3c, tmpisr); +} + +/** + * @brief Manage the disabling of Interrupts. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @param InterruptRequest : [IN] Value of the interrupt request + * @retval None + */ +static void I3C_Disable_IRQ(I3C_HandleTypeDef *hi3c, uint32_t InterruptRequest) +{ + uint32_t tmpisr = 0U; + + /* Check if requested interrupts are related to listening mode */ + if ((InterruptRequest & I3C_XFER_LISTEN_IT) != 0U) + { + tmpisr |= ((InterruptRequest & (~I3C_XFER_LISTEN_IT)) | HAL_I3C_IT_ERRIE); + } + + /* Check if requested interrupts are related to target transmit mode */ + if ((InterruptRequest & I3C_XFER_TARGET_TX_IT) != 0U) + { + /* Disable frame complete, transmit FIFO not full and error interrupts */ + tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_TXFNFIE | HAL_I3C_IT_ERRIE); + } + + /* Check if requested interrupts are related to target receive mode */ + if ((InterruptRequest & I3C_XFER_TARGET_RX_IT) != 0U) + { + /* Disable frame complete, receive FIFO not empty and error interrupts */ + tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_RXFNEIE | HAL_I3C_IT_ERRIE); + } + + /* Check if requested interrupts are related to transmit/receive in DMA mode */ + if ((InterruptRequest & I3C_XFER_DMA) != 0U) + { + /* Disable frame complete and error interrupts */ + tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_ERRIE); + } + + /* Check if requested interrupts are related to target hot join */ + if ((InterruptRequest & I3C_XFER_TARGET_HOTJOIN) != 0U) + { + /* Disable dynamic address update and error interrupts */ + tmpisr |= (HAL_I3C_IT_DAUPDIE | HAL_I3C_IT_ERRIE); + } + + /* Check if requested interrupts are related to target control role */ + if ((InterruptRequest & I3C_XFER_TARGET_CTRLROLE) != 0U) + { + /* Disable control role update and error interrupts */ + tmpisr |= (HAL_I3C_IT_CRUPDIE | HAL_I3C_IT_ERRIE); + } + + /* Check if requested interrupts are related to target in band interrupt */ + if ((InterruptRequest & I3C_XFER_TARGET_IBI) != 0U) + { + /* Disable IBI end and error interrupts */ + tmpisr |= (HAL_I3C_IT_IBIENDIE | HAL_I3C_IT_ERRIE); + } + + /* Check if requested interrupts are related to controller transmit in IT mode */ + if ((InterruptRequest & I3C_XFER_CONTROLLER_TX_IT) != 0U) + { + /* Disable frame complete, control FIFO not full, transmit FIFO not full and error interrupts */ + tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_CFNFIE | HAL_I3C_IT_TXFNFIE | HAL_I3C_IT_ERRIE); + } + + /* Check if requested interrupts are related to controller transmit read or a broadcast CCC in IT mode */ + if ((InterruptRequest & I3C_XFER_CONTROLLER_RX_CCC_IT) != 0U) + { + /* Disable frame complete, transmit FIFO not full, control FIFO not full, + receive FIFO not empty and error interrupts */ + tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_TXFNFIE | HAL_I3C_IT_CFNFIE | HAL_I3C_IT_RXFNEIE | HAL_I3C_IT_ERRIE); + } + + /* Check if requested interrupts are related to controller transmit broadcast ENTDAA CCC in IT mode */ + if ((InterruptRequest & I3C_XFER_CONTROLLER_DAA_IT) != 0U) + { + /* Disable frame complete, control FIFO not full, transmit FIFO not full and error interrupts */ + tmpisr |= (HAL_I3C_IT_FCIE | HAL_I3C_IT_CFNFIE | HAL_I3C_IT_TXFNFIE | HAL_I3C_IT_ERRIE); + } + + /* Disable requested interrupts */ + __HAL_I3C_DISABLE_IT(hi3c, tmpisr); +} + +/** + * @brief I3C error treatment. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @retval None + */ +static void I3C_ErrorTreatment(I3C_HandleTypeDef *hi3c) +{ + HAL_I3C_StateTypeDef tmpstate = hi3c->State; + uint32_t dmaabortongoing = 0U; + + /* Check on the state */ + if (tmpstate == HAL_I3C_STATE_BUSY) + { + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + + /* Disable all interrupts related to busy state */ + I3C_Disable_IRQ(hi3c, (I3C_XFER_TARGET_IBI | I3C_XFER_TARGET_HOTJOIN | I3C_XFER_TARGET_CTRLROLE)); + } + else + { + /* Disable all interrupts related to busy Tx and Rx state */ + I3C_Disable_IRQ(hi3c, I3C_XFER_CONTROLLER_RX_CCC_IT); + + /* Reset Tx counter */ + hi3c->TxXferCount = 0U; + + /* Reset Rx counter */ + hi3c->RxXferCount = 0U; + + /* Reset Control counter */ + hi3c->ControlXferCount = 0U; + + /* Reset Tx function pointer */ + hi3c->ptrTxFunc = NULL; + + /* Reset Rx function pointer */ + hi3c->ptrRxFunc = NULL; + + /* Reset Context pointer */ + hi3c->pXferData = NULL; + hi3c->pCCCDesc = NULL; + hi3c->pPrivateDesc = NULL; + + /* Flush all FIFOs */ + /* Flush the content of Tx Fifo */ + LL_I3C_RequestTxFIFOFlush(hi3c->Instance); + + /* Flush the content of Rx Fifo */ + LL_I3C_RequestRxFIFOFlush(hi3c->Instance); + + /* Check on the I3C mode: Control and status FIFOs available only with controller mode */ + if (hi3c->Mode == HAL_I3C_MODE_CONTROLLER) + { + /* Flush the content of Control Fifo */ + LL_I3C_RequestControlFIFOFlush(hi3c->Instance); + + /* Flush the content of Status Fifo */ + LL_I3C_RequestStatusFIFOFlush(hi3c->Instance); + } + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Abort control DMA transfer if any */ + if (hi3c->hdmacr != NULL) + { + /* Disable control DMA Request */ + LL_I3C_DisableDMAReq_Control(hi3c->Instance); + + /* Check DMA state */ + if (HAL_DMA_GetState(hi3c->hdmacr) != HAL_DMA_STATE_READY) + { + /* Set the I3C DMA Abort callback : will lead to call HAL_I3C_AbortCpltCallback() + at end of DMA abort procedure */ + + /* DMA abort on going */ + dmaabortongoing = 1U; + + /* Abort control DMA */ + if (HAL_DMA_Abort_IT(hi3c->hdmacr) != HAL_OK) + { + /* Call Directly XferAbortCallback function in case of error */ + hi3c->hdmacr->XferAbortCallback(hi3c->hdmacr); + } + } + } + + /* Abort RX DMA transfer if any */ + if (hi3c->hdmarx != NULL) + { + /* Disable Rx DMA Request */ + LL_I3C_DisableDMAReq_RX(hi3c->Instance); + + /* Check DMA state */ + if (HAL_DMA_GetState(hi3c->hdmarx) != HAL_DMA_STATE_READY) + { + /* Set the I3C DMA Abort callback : will lead to call HAL_I3C_AbortCpltCallback() + at end of DMA abort procedure */ + hi3c->hdmarx->XferAbortCallback = I3C_DMAAbort; + + /* DMA abort on going */ + dmaabortongoing = 1U; + + /* Abort DMA RX */ + if (HAL_DMA_Abort_IT(hi3c->hdmarx) != HAL_OK) + { + /* Call Directly XferAbortCallback function in case of error */ + hi3c->hdmarx->XferAbortCallback(hi3c->hdmarx); + } + } + } + + /* Abort TX DMA transfer if any */ + if (hi3c->hdmatx != NULL) + { + /* Disable Tx DMA Request */ + LL_I3C_DisableDMAReq_TX(hi3c->Instance); + + /* Check DMA state */ + if (HAL_DMA_GetState(hi3c->hdmatx) != HAL_DMA_STATE_READY) + { + /* Set the I3C DMA Abort callback : will lead to call HAL_I3C_AbortCpltCallback() + at end of DMA abort procedure */ + hi3c->hdmatx->XferAbortCallback = I3C_DMAAbort; + + /* DMA abort on going */ + dmaabortongoing = 1U; + + /* Abort DMA TX */ + if (HAL_DMA_Abort_IT(hi3c->hdmatx) != HAL_OK) + { + /* Call Directly XferAbortCallback function in case of error */ + hi3c->hdmatx->XferAbortCallback(hi3c->hdmatx); + } + } + } +#endif /* HAL_DMA_MODULE_ENABLED */ + } + + /* Call Error callback if there is no DMA abort on going */ + if (dmaabortongoing == 0U) + { + I3C_TreatErrorCallback(hi3c); + } +} + +/** + * @brief I3C Error callback treatment. + * @param hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration + * information for the specified I3C. + * @retval None + */ +static void I3C_TreatErrorCallback(I3C_HandleTypeDef *hi3c) +{ + if (hi3c->State == HAL_I3C_STATE_ABORT) + { + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1) + hi3c->AbortCpltCallback(hi3c); +#else + HAL_I3C_AbortCpltCallback(hi3c); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS */ + } + else + { + /* Update handle state parameter */ + I3C_StateUpdate(hi3c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I3C_REGISTER_CALLBACKS == 1) + hi3c->ErrorCallback(hi3c); +#else + HAL_I3C_ErrorCallback(hi3c); +#endif /* USE_HAL_I3C_REGISTER_CALLBACKS */ + } +} + +/** + * @} + */ + +#endif /* HAL_I3C_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_icache.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_icache.c new file mode 100644 index 0000000000..00b580252f --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_icache.c @@ -0,0 +1,659 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_icache.c + * @author MCD Application Team + * @brief ICACHE HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Instruction Cache (ICACHE). + * + Initialization and Configuration + * + Invalidate functions + * + Monitoring management + * + Memory address remap management + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### ICACHE main features ##### + ============================================================================== + [..] + The Instruction Cache (ICACHE) is introduced on C-AHB code bus of + Cortex-M33 processor to improve performance when fetching instruction + and data from both internal and external memories. It allows close to + zero wait states performance. + + (+) The ICACHE provides two performance counters (Hit and Miss), + cache invalidate maintenance operation, error management and TrustZone + security support. + + (+) The ICACHE provides additionally the possibility to remap input address + falling into up to four memory regions (used to remap aliased code in + external memories to the internal Code region, for execution) + + =============================================================================== + ##### How to use this driver ##### + =============================================================================== + [..] + The ICACHE HAL driver can be used as follows: + + (#) Optionally configure the Instruction Cache mode with + HAL_ICACHE_ConfigAssociativityMode() if the default configuration + does not suit the application requirements. + + (#) Enable and disable the Instruction Cache with respectively + HAL_ICACHE_Enable() and HAL_ICACHE_Disable(). + Use HAL_ICACHE_IsEnabled() to get the Instruction Cache status. + + (#) Initiate the cache maintenance invalidation procedure with either + HAL_ICACHE_Invalidate() (blocking mode) or HAL_ICACHE_Invalidate_IT() + (interrupt mode). When interrupt mode is used, the callback function + HAL_ICACHE_InvalidateCompleteCallback() is called when the invalidate + procedure is complete. The function HAL_ICACHE_WaitForInvalidateComplete() + may be called to wait for the end of the invalidate procedure automatically + initiated when disabling the Instruction Cache with HAL_ICACHE_Disable(). + The cache operation is bypassed during the invalidation procedure. + + (#) Use the performance monitoring counters for Hit and Miss with the following + functions: HAL_ICACHE_Monitor_Start(), HAL_ICACHE_Monitor_Stop(), + HAL_ICACHE_Monitor_Reset(), HAL_ICACHE_Monitor_GetHitValue() and + HAL_ICACHE_Monitor_GetMissValue() + + (#) Enable and disable up to four regions to remap input address from external + memories to the internal Code region for execution with + HAL_ICACHE_EnableRemapRegion() and HAL_ICACHE_DisableRemapRegion() + + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup ICACHE ICACHE + * @brief HAL ICACHE module driver + * @{ + */ +#if defined(ICACHE) && defined (HAL_ICACHE_MODULE_ENABLED) + +/* Private typedef -----------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @addtogroup ICACHE_Private_Constants ICACHE Private Constants + * @{ + */ +#define ICACHE_INVALIDATE_TIMEOUT_VALUE 1U /* 1ms */ +#define ICACHE_DISABLE_TIMEOUT_VALUE 1U /* 1ms */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup ICACHE_Private_Macros ICACHE Private Macros + * @{ + */ + +#define IS_ICACHE_ASSOCIATIVITY_MODE(__MODE__) (((__MODE__) == ICACHE_1WAY) || \ + ((__MODE__) == ICACHE_2WAYS)) + +#define IS_ICACHE_MONITOR_TYPE(__TYPE__) (((__TYPE__) == ICACHE_MONITOR_HIT_MISS) || \ + ((__TYPE__) == ICACHE_MONITOR_HIT) || \ + ((__TYPE__) == ICACHE_MONITOR_MISS)) + +#if defined(ICACHE_CRRx_REN) +#define IS_ICACHE_REGION_NUMBER(__NUMBER__) ((__NUMBER__) < 4U) + +#define IS_ICACHE_REGION_SIZE(__SIZE__) (((__SIZE__) == ICACHE_REGIONSIZE_2MB) || \ + ((__SIZE__) == ICACHE_REGIONSIZE_4MB) || \ + ((__SIZE__) == ICACHE_REGIONSIZE_8MB) || \ + ((__SIZE__) == ICACHE_REGIONSIZE_16MB) || \ + ((__SIZE__) == ICACHE_REGIONSIZE_32MB) || \ + ((__SIZE__) == ICACHE_REGIONSIZE_64MB) || \ + ((__SIZE__) == ICACHE_REGIONSIZE_128MB)) + +#define IS_ICACHE_REGION_TRAFFIC_ROUTE(__TRAFFICROUTE__) (((__TRAFFICROUTE__) == ICACHE_MASTER1_PORT) || \ + ((__TRAFFICROUTE__) == ICACHE_MASTER2_PORT)) + +#define IS_ICACHE_REGION_OUTPUT_BURST_TYPE(__OUTPUTBURSTTYPE_) (((__OUTPUTBURSTTYPE_) == ICACHE_OUTPUT_BURST_WRAP) || \ + ((__OUTPUTBURSTTYPE_) == ICACHE_OUTPUT_BURST_INCR)) + +#endif /* ICACHE_CRRx_REN */ +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup ICACHE_Exported_Functions ICACHE Exported Functions + * @{ + */ + +/** @defgroup ICACHE_Exported_Functions_Group1 Initialization and control functions + * @brief Initialization and control functions + * + @verbatim + ============================================================================== + ##### Initialization and control functions ##### + ============================================================================== + [..] + This section provides functions allowing to initialize and control the + Instruction Cache (mode, invalidate procedure, performance counters). + @endverbatim + * @{ + */ + +/** + * @brief Configure the Instruction Cache cache associativity mode selection. + * @param AssociativityMode Associativity mode selection + * This parameter can be one of the following values: + * @arg ICACHE_1WAY 1-way cache (direct mapped cache) + * @arg ICACHE_2WAYS 2-ways set associative cache (default) + * @retval HAL status (HAL_OK/HAL_ERROR) + */ +HAL_StatusTypeDef HAL_ICACHE_ConfigAssociativityMode(uint32_t AssociativityMode) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_ICACHE_ASSOCIATIVITY_MODE(AssociativityMode)); + + /* Check cache is not enabled */ + if (READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U) + { + status = HAL_ERROR; + } + else + { + MODIFY_REG(ICACHE->CR, ICACHE_CR_WAYSEL, AssociativityMode); + } + + return status; +} + +/** + * @brief DeInitialize the Instruction Cache. + * @retval HAL status (HAL_OK/HAL_TIMEOUT) + */ +HAL_StatusTypeDef HAL_ICACHE_DeInit(void) +{ + HAL_StatusTypeDef status; + + /* Disable cache with reset value for 2-ways set associative mode */ + WRITE_REG(ICACHE->CR, ICACHE_CR_WAYSEL); + + /* Stop monitor and reset monitor values */ + (void)HAL_ICACHE_Monitor_Stop(ICACHE_MONITOR_HIT_MISS); + (void)HAL_ICACHE_Monitor_Reset(ICACHE_MONITOR_HIT_MISS); + +#if defined(ICACHE_CRRx_REN) + /* No remapped regions */ + (void)HAL_ICACHE_DisableRemapRegion(ICACHE_REGION_0); + (void)HAL_ICACHE_DisableRemapRegion(ICACHE_REGION_1); + (void)HAL_ICACHE_DisableRemapRegion(ICACHE_REGION_2); + (void)HAL_ICACHE_DisableRemapRegion(ICACHE_REGION_3); +#endif /* ICACHE_CRRx_REN */ + + /* Wait for end of invalidate cache procedure */ + status = HAL_ICACHE_WaitForInvalidateComplete(); + + /* Clear any pending flags */ + WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF | ICACHE_FCR_CERRF); + + return status; +} + +/** + * @brief Enable the Instruction Cache. + * @note This function always returns HAL_OK even if there is any ongoing + * cache operation. The Instruction Cache is bypassed until the + * cache operation completes. + * @retval HAL status (HAL_OK) + */ +HAL_StatusTypeDef HAL_ICACHE_Enable(void) +{ + SET_BIT(ICACHE->CR, ICACHE_CR_EN); + + return HAL_OK; +} + +/** + * @brief Disable the Instruction Cache. + * @note This function waits for the cache being disabled but + * not for the end of the automatic cache invalidation procedure. + * @retval HAL status (HAL_OK/HAL_TIMEOUT) + */ +HAL_StatusTypeDef HAL_ICACHE_Disable(void) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tickstart; + + /* Make sure BSYENDF is reset before to disable the instruction cache */ + /* as it automatically starts a cache invalidation procedure */ + WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF); + + CLEAR_BIT(ICACHE->CR, ICACHE_CR_EN); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait for instruction cache being disabled */ + while (READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U) + { + if ((HAL_GetTick() - tickstart) > ICACHE_DISABLE_TIMEOUT_VALUE) + { + /* New check to avoid false timeout detection in case of preemption */ + if (READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U) + { + status = HAL_TIMEOUT; + break; + } + } + } + + return status; +} + +/** + * @brief Check whether the Instruction Cache is enabled or not. + * @retval Status (0: disabled, 1: enabled) + */ +uint32_t HAL_ICACHE_IsEnabled(void) +{ + return ((READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U) ? 1UL : 0UL); +} + +/** + * @brief Invalidate the Instruction Cache. + * @note This function waits for the end of cache invalidation procedure + * and clears the associated BSYENDF flag. + * @retval HAL status (HAL_OK/HAL_ERROR/HAL_TIMEOUT) + */ +HAL_StatusTypeDef HAL_ICACHE_Invalidate(void) +{ + HAL_StatusTypeDef status; + + /* Check no ongoing operation */ + if (READ_BIT(ICACHE->SR, ICACHE_SR_BUSYF) != 0U) + { + status = HAL_ERROR; + } + else + { + /* Make sure BSYENDF is reset before to start cache invalidation */ + WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF); + + /* Launch cache invalidation */ + SET_BIT(ICACHE->CR, ICACHE_CR_CACHEINV); + + status = HAL_ICACHE_WaitForInvalidateComplete(); + } + + return status; +} + +/** + * @brief Invalidate the Instruction Cache with interrupt. + * @note This function launches cache invalidation and returns. + * User application shall resort to interrupt generation to check + * the end of the cache invalidation with the BSYENDF flag and the + * HAL_ICACHE_InvalidateCompleteCallback() callback. + * @retval HAL status (HAL_OK/HAL_ERROR) + */ +HAL_StatusTypeDef HAL_ICACHE_Invalidate_IT(void) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check no ongoing operation */ + if (READ_BIT(ICACHE->SR, ICACHE_SR_BUSYF) != 0U) + { + status = HAL_ERROR; + } + else + { + /* Make sure BSYENDF is reset before to start cache invalidation */ + WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF); + + /* Enable end of cache invalidation interrupt */ + SET_BIT(ICACHE->IER, ICACHE_IER_BSYENDIE); + + /* Launch cache invalidation */ + SET_BIT(ICACHE->CR, ICACHE_CR_CACHEINV); + } + + return status; +} + +/** + * @brief Wait for the end of the Instruction Cache invalidate procedure. + * @note This function checks and clears the BSYENDF flag when set. + * @retval HAL status (HAL_OK/HAL_TIMEOUT) + */ +HAL_StatusTypeDef HAL_ICACHE_WaitForInvalidateComplete(void) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tickstart; + + /* Check if ongoing invalidation operation */ + if (READ_BIT(ICACHE->SR, ICACHE_SR_BUSYF) != 0U) + { + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait for end of cache invalidation */ + while (READ_BIT(ICACHE->SR, ICACHE_SR_BSYENDF) == 0U) + { + if ((HAL_GetTick() - tickstart) > ICACHE_INVALIDATE_TIMEOUT_VALUE) + { + /* New check to avoid false timeout detection in case of preemption */ + if (READ_BIT(ICACHE->SR, ICACHE_SR_BSYENDF) == 0U) + { + status = HAL_TIMEOUT; + break; + } + } + } + } + + /* Clear BSYENDF */ + WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF); + + return status; +} + + +/** + * @brief Start the Instruction Cache performance monitoring. + * @param MonitorType Monitoring type + * This parameter can be one of the following values: + * @arg ICACHE_MONITOR_HIT_MISS Hit & Miss monitoring + * @arg ICACHE_MONITOR_HIT Hit monitoring + * @arg ICACHE_MONITOR_MISS Miss monitoring + * @retval HAL status (HAL_OK) + */ +HAL_StatusTypeDef HAL_ICACHE_Monitor_Start(uint32_t MonitorType) +{ + /* Check the parameters */ + assert_param(IS_ICACHE_MONITOR_TYPE(MonitorType)); + + SET_BIT(ICACHE->CR, MonitorType); + + return HAL_OK; +} + +/** + * @brief Stop the Instruction Cache performance monitoring. + * @note Stopping the monitoring does not reset the values. + * @param MonitorType Monitoring type + * This parameter can be one of the following values: + * @arg ICACHE_MONITOR_HIT_MISS Hit & Miss monitoring + * @arg ICACHE_MONITOR_HIT Hit monitoring + * @arg ICACHE_MONITOR_MISS Miss monitoring + * @retval HAL status (HAL_OK) + */ +HAL_StatusTypeDef HAL_ICACHE_Monitor_Stop(uint32_t MonitorType) +{ + /* Check the parameters */ + assert_param(IS_ICACHE_MONITOR_TYPE(MonitorType)); + + CLEAR_BIT(ICACHE->CR, MonitorType); + + return HAL_OK; +} + +/** + * @brief Reset the Instruction Cache performance monitoring values. + * @param MonitorType Monitoring type + * This parameter can be one of the following values: + * @arg ICACHE_MONITOR_HIT_MISS Hit & Miss monitoring + * @arg ICACHE_MONITOR_HIT Hit monitoring + * @arg ICACHE_MONITOR_MISS Miss monitoring + * @retval HAL status (HAL_OK) + */ +HAL_StatusTypeDef HAL_ICACHE_Monitor_Reset(uint32_t MonitorType) +{ + /* Check the parameters */ + assert_param(IS_ICACHE_MONITOR_TYPE(MonitorType)); + + /* Force/Release reset */ + SET_BIT(ICACHE->CR, (MonitorType << 2U)); + CLEAR_BIT(ICACHE->CR, (MonitorType << 2U)); + + return HAL_OK; +} + +/** + * @brief Get the Instruction Cache performance Hit monitoring value. + * @note Upon reaching the 32-bit maximum value, monitor does not wrap. + * @retval Hit monitoring value + */ +uint32_t HAL_ICACHE_Monitor_GetHitValue(void) +{ + return (ICACHE->HMONR); +} + +/** + * @brief Get the Instruction Cache performance Miss monitoring value. + * @note Upon reaching the 32-bit maximum value, monitor does not wrap. + * @retval Miss monitoring value + */ +uint32_t HAL_ICACHE_Monitor_GetMissValue(void) +{ + return (ICACHE->MMONR); +} + +/** + * @} + */ + +/** @defgroup ICACHE_Exported_Functions_Group2 IRQ and callback functions + * @brief IRQ and callback functions + * + @verbatim + ============================================================================== + ##### IRQ and callback functions ##### + ============================================================================== + [..] + This section provides functions allowing to handle ICACHE global interrupt + and the associated callback functions. + @endverbatim + * @{ + */ + +/** + * @brief Handle the Instruction Cache interrupt request. + * @note This function should be called under the ICACHE_IRQHandler(). + * @note This function respectively disables the interrupt and clears the + * flag of any pending flag before calling the associated user callback. + * @retval None + */ +void HAL_ICACHE_IRQHandler(void) +{ + /* Get current interrupt flags and interrupt sources value */ + uint32_t itflags = READ_REG(ICACHE->SR); + uint32_t itsources = READ_REG(ICACHE->IER); + + /* Check Instruction cache Error interrupt flag */ + if (((itflags & itsources) & ICACHE_FLAG_ERROR) != 0U) + { + /* Disable error interrupt */ + CLEAR_BIT(ICACHE->IER, ICACHE_IER_ERRIE); + + /* Clear ERR pending flag */ + WRITE_REG(ICACHE->FCR, ICACHE_FCR_CERRF); + + /* Instruction cache error interrupt user callback */ + HAL_ICACHE_ErrorCallback(); + } + + /* Check Instruction cache BusyEnd interrupt flag */ + if (((itflags & itsources) & ICACHE_FLAG_BUSYEND) != 0U) + { + /* Disable end of cache invalidation interrupt */ + CLEAR_BIT(ICACHE->IER, ICACHE_IER_BSYENDIE); + + /* Clear BSYENDF pending flag */ + WRITE_REG(ICACHE->FCR, ICACHE_FCR_CBSYENDF); + + /* Instruction cache busyend interrupt user callback */ + HAL_ICACHE_InvalidateCompleteCallback(); + } +} + +/** + * @brief Cache invalidation complete callback. + */ +__weak void HAL_ICACHE_InvalidateCompleteCallback(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_ICACHE_InvalidateCompleteCallback() should be implemented in the user file + */ +} + +/** + * @brief Error callback. + */ +__weak void HAL_ICACHE_ErrorCallback(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_ICACHE_ErrorCallback() should be implemented in the user file + */ +} + +/** + * @} + */ + +#if defined(ICACHE_CRRx_REN) +/** @defgroup ICACHE_Exported_Functions_Group3 Memory remapped regions functions + * @brief Memory remapped regions functions + * + @verbatim + ============================================================================== + ##### Memory remapped regions functions ##### + ============================================================================== + [..] + This section provides functions allowing to manage the remapping of + external memories to internal Code for execution. + @endverbatim + * @{ + */ + +/** + * @brief Configure and enable a region for memory remapping. + * @note The Instruction Cache and the region must be disabled. + * @param Region Region number + This parameter can be a value of @arg @ref ICACHE_Region + * @param pRegionConfig Pointer to structure of ICACHE region configuration parameters + * @retval HAL status (HAL_OK/HAL_ERROR) + */ +HAL_StatusTypeDef HAL_ICACHE_EnableRemapRegion(uint32_t Region, const ICACHE_RegionConfigTypeDef *const pRegionConfig) +{ + HAL_StatusTypeDef status = HAL_OK; + __IO uint32_t *p_reg; + uint32_t value; + + /* Check the parameters */ + assert_param(IS_ICACHE_REGION_NUMBER(Region)); + assert_param(IS_ICACHE_REGION_SIZE(pRegionConfig->Size)); + assert_param(IS_ICACHE_REGION_TRAFFIC_ROUTE(pRegionConfig->TrafficRoute)); + assert_param(IS_ICACHE_REGION_OUTPUT_BURST_TYPE(pRegionConfig->OutputBurstType)); + + /* Check cache is not enabled */ + if (READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U) + { + status = HAL_ERROR; + } + else + { + /* Get region control register address */ + p_reg = &(ICACHE->CRR0) + (1U * Region); + + /* Check region is not already enabled */ + if ((*p_reg & ICACHE_CRRx_REN) != 0U) + { + status = HAL_ERROR; + } + else + { + /* Region 2MB: BaseAddress size 8 bits, RemapAddress size 11 bits */ + /* Region 4MB: BaseAddress size 7 bits, RemapAddress size 10 bits */ + /* Region 8MB: BaseAddress size 6 bits, RemapAddress size 9 bits */ + /* Region 16MB: BaseAddress size 5 bits, RemapAddress size 8 bits */ + /* Region 32MB: BaseAddress size 4 bits, RemapAddress size 7 bits */ + /* Region 64MB: BaseAddress size 3 bits, RemapAddress size 6 bits */ + /* Region 128MB: BaseAddress size 2 bits, RemapAddress size 5 bits */ + value = ((pRegionConfig->BaseAddress & 0x1FFFFFFFU) >> 21U) & \ + (0xFFU & ~(pRegionConfig->Size - 1U)); + value |= ((pRegionConfig->RemapAddress >> 5U) & \ + ((uint32_t)(0x7FFU & ~(pRegionConfig->Size - 1U)) << ICACHE_CRRx_REMAPADDR_Pos)); + value |= (pRegionConfig->Size << ICACHE_CRRx_RSIZE_Pos) | pRegionConfig->TrafficRoute | \ + pRegionConfig->OutputBurstType; + *p_reg = (value | ICACHE_CRRx_REN); + } + } + + return status; +} + +/** + * @brief Disable the memory remapping for a predefined region. + * @param Region Region number + This parameter can be a value of @arg @ref ICACHE_Region + * @retval HAL status (HAL_OK/HAL_ERROR) + */ +HAL_StatusTypeDef HAL_ICACHE_DisableRemapRegion(uint32_t Region) +{ + HAL_StatusTypeDef status = HAL_OK; + __IO uint32_t *p_reg; + + /* Check the parameters */ + assert_param(IS_ICACHE_REGION_NUMBER(Region)); + + /* Check cache is not enabled */ + if (READ_BIT(ICACHE->CR, ICACHE_CR_EN) != 0U) + { + status = HAL_ERROR; + } + else + { + /* Get region control register address */ + p_reg = &(ICACHE->CRR0) + (1U * Region); + + *p_reg &= ~ICACHE_CRRx_REN; + } + + return status; +} + + +/** + * @} + */ +#endif /* ICACHE_CRRx_REN */ + +/** + * @} + */ + +#endif /* ICACHE && HAL_ICACHE_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_irda.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_irda.c new file mode 100644 index 0000000000..4a8f3108df --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_irda.c @@ -0,0 +1,3023 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_irda.c + * @author MCD Application Team + * @brief IRDA HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the IrDA (Infrared Data Association) Peripheral + * (IRDA) + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral State and Errors functions + * + Peripheral Control functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The IRDA HAL driver can be used as follows: + + (#) Declare a IRDA_HandleTypeDef handle structure (eg. IRDA_HandleTypeDef hirda). + (#) Initialize the IRDA low level resources by implementing the HAL_IRDA_MspInit() API + in setting the associated USART or UART in IRDA mode: + (++) Enable the USARTx/UARTx interface clock. + (++) USARTx/UARTx pins configuration: + (+++) Enable the clock for the USARTx/UARTx GPIOs. + (+++) Configure these USARTx/UARTx pins (TX as alternate function pull-up, RX as alternate function Input). + (++) NVIC configuration if you need to use interrupt process (HAL_IRDA_Transmit_IT() + and HAL_IRDA_Receive_IT() APIs): + (+++) Configure the USARTx/UARTx interrupt priority. + (+++) Enable the NVIC USARTx/UARTx IRQ handle. + (+++) The specific IRDA interrupts (Transmission complete interrupt, + RXNE interrupt and Error Interrupts) will be managed using the macros + __HAL_IRDA_ENABLE_IT() and __HAL_IRDA_DISABLE_IT() inside the transmit and receive process. + + (++) DMA Configuration if you need to use DMA process (HAL_IRDA_Transmit_DMA() + and HAL_IRDA_Receive_DMA() APIs): + (+++) Declare a DMA handle structure for the Tx/Rx channel. + (+++) Enable the DMAx interface clock. + (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. + (+++) Configure the DMA Tx/Rx channel. + (+++) Associate the initialized DMA handle to the IRDA DMA Tx/Rx handle. + (+++) Configure the priority and enable the NVIC for the transfer + complete interrupt on the DMA Tx/Rx channel. + + (#) Program the Baud Rate, Word Length and Parity and Mode(Receiver/Transmitter), + the normal or low power mode and the clock prescaler in the hirda handle Init structure. + + (#) Initialize the IRDA registers by calling the HAL_IRDA_Init() API: + (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc) + by calling the customized HAL_IRDA_MspInit() API. + + -@@- The specific IRDA interrupts (Transmission complete interrupt, + RXNE interrupt and Error Interrupts) will be managed using the macros + __HAL_IRDA_ENABLE_IT() and __HAL_IRDA_DISABLE_IT() inside the transmit and receive process. + + (#) Three operation modes are available within this driver : + + *** Polling mode IO operation *** + ================================= + [..] + (+) Send an amount of data in blocking mode using HAL_IRDA_Transmit() + (+) Receive an amount of data in blocking mode using HAL_IRDA_Receive() + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Send an amount of data in non-blocking mode using HAL_IRDA_Transmit_IT() + (+) At transmission end of transfer HAL_IRDA_TxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_IRDA_TxCpltCallback() + (+) Receive an amount of data in non-blocking mode using HAL_IRDA_Receive_IT() + (+) At reception end of transfer HAL_IRDA_RxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_IRDA_RxCpltCallback() + (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_IRDA_ErrorCallback() + + *** DMA mode IO operation *** + ============================== + [..] + (+) Send an amount of data in non-blocking mode (DMA) using HAL_IRDA_Transmit_DMA() + (+) At transmission half of transfer HAL_IRDA_TxHalfCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_IRDA_TxHalfCpltCallback() + (+) At transmission end of transfer HAL_IRDA_TxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_IRDA_TxCpltCallback() + (+) Receive an amount of data in non-blocking mode (DMA) using HAL_IRDA_Receive_DMA() + (+) At reception half of transfer HAL_IRDA_RxHalfCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_IRDA_RxHalfCpltCallback() + (+) At reception end of transfer HAL_IRDA_RxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_IRDA_RxCpltCallback() + (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_IRDA_ErrorCallback() + + *** IRDA HAL driver macros list *** + ==================================== + [..] + Below the list of most used macros in IRDA HAL driver. + + (+) __HAL_IRDA_ENABLE: Enable the IRDA peripheral + (+) __HAL_IRDA_DISABLE: Disable the IRDA peripheral + (+) __HAL_IRDA_GET_FLAG : Check whether the specified IRDA flag is set or not + (+) __HAL_IRDA_CLEAR_FLAG : Clear the specified IRDA pending flag + (+) __HAL_IRDA_ENABLE_IT: Enable the specified IRDA interrupt + (+) __HAL_IRDA_DISABLE_IT: Disable the specified IRDA interrupt + (+) __HAL_IRDA_GET_IT_SOURCE: Check whether or not the specified IRDA interrupt is enabled + + [..] + (@) You can refer to the IRDA HAL driver header file for more useful macros + + ##### Callback registration ##### + ================================== + + [..] + The compilation define USE_HAL_IRDA_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + + [..] + Use Function HAL_IRDA_RegisterCallback() to register a user callback. + Function HAL_IRDA_RegisterCallback() allows to register following callbacks: + (+) TxHalfCpltCallback : Tx Half Complete Callback. + (+) TxCpltCallback : Tx Complete Callback. + (+) RxHalfCpltCallback : Rx Half Complete Callback. + (+) RxCpltCallback : Rx Complete Callback. + (+) ErrorCallback : Error Callback. + (+) AbortCpltCallback : Abort Complete Callback. + (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback. + (+) AbortReceiveCpltCallback : Abort Receive Complete Callback. + (+) MspInitCallback : IRDA MspInit. + (+) MspDeInitCallback : IRDA MspDeInit. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + + [..] + Use function HAL_IRDA_UnRegisterCallback() to reset a callback to the default + weak function. + HAL_IRDA_UnRegisterCallback() takes as parameters the HAL peripheral handle, + and the Callback ID. + This function allows to reset following callbacks: + (+) TxHalfCpltCallback : Tx Half Complete Callback. + (+) TxCpltCallback : Tx Complete Callback. + (+) RxHalfCpltCallback : Rx Half Complete Callback. + (+) RxCpltCallback : Rx Complete Callback. + (+) ErrorCallback : Error Callback. + (+) AbortCpltCallback : Abort Complete Callback. + (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback. + (+) AbortReceiveCpltCallback : Abort Receive Complete Callback. + (+) MspInitCallback : IRDA MspInit. + (+) MspDeInitCallback : IRDA MspDeInit. + + [..] + By default, after the HAL_IRDA_Init() and when the state is HAL_IRDA_STATE_RESET + all callbacks are set to the corresponding weak functions: + examples HAL_IRDA_TxCpltCallback(), HAL_IRDA_RxHalfCpltCallback(). + Exception done for MspInit and MspDeInit functions that are respectively + reset to the legacy weak functions in the HAL_IRDA_Init() + and HAL_IRDA_DeInit() only when these callbacks are null (not registered beforehand). + If not, MspInit or MspDeInit are not null, the HAL_IRDA_Init() and HAL_IRDA_DeInit() + keep and use the user MspInit/MspDeInit callbacks (registered beforehand). + + [..] + Callbacks can be registered/unregistered in HAL_IRDA_STATE_READY state only. + Exception done MspInit/MspDeInit that can be registered/unregistered + in HAL_IRDA_STATE_READY or HAL_IRDA_STATE_RESET state, thus registered (user) + MspInit/DeInit callbacks can be used during the Init/DeInit. + In that case first register the MspInit/MspDeInit user callbacks + using HAL_IRDA_RegisterCallback() before calling HAL_IRDA_DeInit() + or HAL_IRDA_Init() function. + + [..] + When The compilation define USE_HAL_IRDA_REGISTER_CALLBACKS is set to 0 or + not defined, the callback registration feature is not available + and weak callbacks are used. + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup IRDA IRDA + * @brief HAL IRDA module driver + * @{ + */ + +#ifdef HAL_IRDA_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup IRDA_Private_Constants IRDA Private Constants + * @{ + */ +#define IRDA_TEACK_REACK_TIMEOUT 1000U /*!< IRDA TX or RX enable acknowledge time-out value */ + +#define IRDA_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE \ + | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE)) /*!< UART or USART CR1 fields of parameters set by IRDA_SetConfig API */ + +#define USART_BRR_MIN 0x10U /*!< USART BRR minimum authorized value */ + +#define USART_BRR_MAX 0x0000FFFFU /*!< USART BRR maximum authorized value */ +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup IRDA_Private_Macros IRDA Private Macros + * @{ + */ +/** @brief BRR division operation to set BRR register in 16-bit oversampling mode. + * @param __PCLK__ IRDA clock source. + * @param __BAUD__ Baud rate set by the user. + * @param __PRESCALER__ IRDA clock prescaler value. + * @retval Division result + */ +#define IRDA_DIV_SAMPLING16(__PCLK__, __BAUD__, __PRESCALER__) ((((__PCLK__)/IRDAPrescTable[(__PRESCALER__)])\ + + ((__BAUD__)/2U)) / (__BAUD__)) +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup IRDA_Private_Functions + * @{ + */ +#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) +void IRDA_InitCallbacksToDefault(IRDA_HandleTypeDef *hirda); +#endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */ +static HAL_StatusTypeDef IRDA_SetConfig(IRDA_HandleTypeDef *hirda); +static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda); +static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, + uint32_t Tickstart, uint32_t Timeout); +#if defined(HAL_DMA_MODULE_ENABLED) +static void IRDA_EndTxTransfer(IRDA_HandleTypeDef *hirda); +#endif /* HAL_DMA_MODULE_ENABLED */ +static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda); +#if defined(HAL_DMA_MODULE_ENABLED) +static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma); +static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma); +static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma); +static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma); +static void IRDA_DMAError(DMA_HandleTypeDef *hdma); +static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma); +static void IRDA_DMATxAbortCallback(DMA_HandleTypeDef *hdma); +static void IRDA_DMARxAbortCallback(DMA_HandleTypeDef *hdma); +static void IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma); +static void IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma); +#endif /* HAL_DMA_MODULE_ENABLED */ +static void IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda); +static void IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda); +static void IRDA_Receive_IT(IRDA_HandleTypeDef *hirda); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup IRDA_Exported_Functions IRDA Exported Functions + * @{ + */ + +/** @defgroup IRDA_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + ============================================================================== + ##### Initialization and Configuration functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to initialize the USARTx + in asynchronous IRDA mode. + (+) For the asynchronous mode only these parameters can be configured: + (++) Baud Rate + (++) Word Length + (++) Parity: If the parity is enabled, then the MSB bit of the data written + in the data register is transmitted but is changed by the parity bit. + (++) Power mode + (++) Prescaler setting + (++) Receiver/transmitter modes + + [..] + The HAL_IRDA_Init() API follows the USART asynchronous configuration procedures + (details for the procedures are available in reference manual). + +@endverbatim + + Depending on the frame length defined by the M1 and M0 bits (7-bit, + 8-bit or 9-bit), the possible IRDA frame formats are listed in the + following table. + + Table 1. IRDA frame format. + +-----------------------------------------------------------------------+ + | M1 bit | M0 bit | PCE bit | IRDA frame | + |---------|---------|-----------|---------------------------------------| + | 0 | 0 | 0 | | SB | 8 bit data | STB | | + |---------|---------|-----------|---------------------------------------| + | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | | + |---------|---------|-----------|---------------------------------------| + | 0 | 1 | 0 | | SB | 9 bit data | STB | | + |---------|---------|-----------|---------------------------------------| + | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | | + |---------|---------|-----------|---------------------------------------| + | 1 | 0 | 0 | | SB | 7 bit data | STB | | + |---------|---------|-----------|---------------------------------------| + | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | | + +-----------------------------------------------------------------------+ + + * @{ + */ + +/** + * @brief Initialize the IRDA mode according to the specified + * parameters in the IRDA_InitTypeDef and initialize the associated handle. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_Init(IRDA_HandleTypeDef *hirda) +{ + /* Check the IRDA handle allocation */ + if (hirda == NULL) + { + return HAL_ERROR; + } + + /* Check the USART/UART associated to the IRDA handle */ + assert_param(IS_IRDA_INSTANCE(hirda->Instance)); + + if (hirda->gState == HAL_IRDA_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hirda->Lock = HAL_UNLOCKED; + +#if USE_HAL_IRDA_REGISTER_CALLBACKS == 1 + IRDA_InitCallbacksToDefault(hirda); + + if (hirda->MspInitCallback == NULL) + { + hirda->MspInitCallback = HAL_IRDA_MspInit; + } + + /* Init the low level hardware */ + hirda->MspInitCallback(hirda); +#else + /* Init the low level hardware : GPIO, CLOCK */ + HAL_IRDA_MspInit(hirda); +#endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */ + } + + hirda->gState = HAL_IRDA_STATE_BUSY; + + /* Disable the Peripheral to update the configuration registers */ + __HAL_IRDA_DISABLE(hirda); + + /* Set the IRDA Communication parameters */ + if (IRDA_SetConfig(hirda) == HAL_ERROR) + { + return HAL_ERROR; + } + + /* In IRDA mode, the following bits must be kept cleared: + - LINEN, STOP and CLKEN bits in the USART_CR2 register, + - SCEN and HDSEL bits in the USART_CR3 register.*/ + CLEAR_BIT(hirda->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN | USART_CR2_STOP)); + CLEAR_BIT(hirda->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL)); + + /* set the UART/USART in IRDA mode */ + hirda->Instance->CR3 |= USART_CR3_IREN; + + /* Enable the Peripheral */ + __HAL_IRDA_ENABLE(hirda); + + /* TEACK and/or REACK to check before moving hirda->gState and hirda->RxState to Ready */ + return (IRDA_CheckIdleState(hirda)); +} + +/** + * @brief DeInitialize the IRDA peripheral. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda) +{ + /* Check the IRDA handle allocation */ + if (hirda == NULL) + { + return HAL_ERROR; + } + + /* Check the USART/UART associated to the IRDA handle */ + assert_param(IS_IRDA_INSTANCE(hirda->Instance)); + + hirda->gState = HAL_IRDA_STATE_BUSY; + + /* DeInit the low level hardware */ +#if USE_HAL_IRDA_REGISTER_CALLBACKS == 1 + if (hirda->MspDeInitCallback == NULL) + { + hirda->MspDeInitCallback = HAL_IRDA_MspDeInit; + } + /* DeInit the low level hardware */ + hirda->MspDeInitCallback(hirda); +#else + HAL_IRDA_MspDeInit(hirda); +#endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */ + /* Disable the Peripheral */ + __HAL_IRDA_DISABLE(hirda); + + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + hirda->gState = HAL_IRDA_STATE_RESET; + hirda->RxState = HAL_IRDA_STATE_RESET; + + /* Process Unlock */ + __HAL_UNLOCK(hirda); + + return HAL_OK; +} + +/** + * @brief Initialize the IRDA MSP. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ +__weak void HAL_IRDA_MspInit(IRDA_HandleTypeDef *hirda) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hirda); + + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_IRDA_MspInit can be implemented in the user file + */ +} + +/** + * @brief DeInitialize the IRDA MSP. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ +__weak void HAL_IRDA_MspDeInit(IRDA_HandleTypeDef *hirda) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hirda); + + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_IRDA_MspDeInit can be implemented in the user file + */ +} + +#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User IRDA Callback + * To be used to override the weak predefined callback + * @note The HAL_IRDA_RegisterCallback() may be called before HAL_IRDA_Init() in HAL_IRDA_STATE_RESET + * to register callbacks for HAL_IRDA_MSPINIT_CB_ID and HAL_IRDA_MSPDEINIT_CB_ID + * @param hirda irda handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_IRDA_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID + * @arg @ref HAL_IRDA_TX_COMPLETE_CB_ID Tx Complete Callback ID + * @arg @ref HAL_IRDA_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID + * @arg @ref HAL_IRDA_RX_COMPLETE_CB_ID Rx Complete Callback ID + * @arg @ref HAL_IRDA_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_IRDA_ABORT_COMPLETE_CB_ID Abort Complete Callback ID + * @arg @ref HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID + * @arg @ref HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID + * @arg @ref HAL_IRDA_MSPINIT_CB_ID MspInit Callback ID + * @arg @ref HAL_IRDA_MSPDEINIT_CB_ID MspDeInit Callback ID + * @param pCallback pointer to the Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_RegisterCallback(IRDA_HandleTypeDef *hirda, HAL_IRDA_CallbackIDTypeDef CallbackID, + pIRDA_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + if (hirda->gState == HAL_IRDA_STATE_READY) + { + switch (CallbackID) + { + case HAL_IRDA_TX_HALFCOMPLETE_CB_ID : + hirda->TxHalfCpltCallback = pCallback; + break; + + case HAL_IRDA_TX_COMPLETE_CB_ID : + hirda->TxCpltCallback = pCallback; + break; + + case HAL_IRDA_RX_HALFCOMPLETE_CB_ID : + hirda->RxHalfCpltCallback = pCallback; + break; + + case HAL_IRDA_RX_COMPLETE_CB_ID : + hirda->RxCpltCallback = pCallback; + break; + + case HAL_IRDA_ERROR_CB_ID : + hirda->ErrorCallback = pCallback; + break; + + case HAL_IRDA_ABORT_COMPLETE_CB_ID : + hirda->AbortCpltCallback = pCallback; + break; + + case HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID : + hirda->AbortTransmitCpltCallback = pCallback; + break; + + case HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID : + hirda->AbortReceiveCpltCallback = pCallback; + break; + + case HAL_IRDA_MSPINIT_CB_ID : + hirda->MspInitCallback = pCallback; + break; + + case HAL_IRDA_MSPDEINIT_CB_ID : + hirda->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (hirda->gState == HAL_IRDA_STATE_RESET) + { + switch (CallbackID) + { + case HAL_IRDA_MSPINIT_CB_ID : + hirda->MspInitCallback = pCallback; + break; + + case HAL_IRDA_MSPDEINIT_CB_ID : + hirda->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister an IRDA callback + * IRDA callback is redirected to the weak predefined callback + * @note The HAL_IRDA_UnRegisterCallback() may be called before HAL_IRDA_Init() in HAL_IRDA_STATE_RESET + * to un-register callbacks for HAL_IRDA_MSPINIT_CB_ID and HAL_IRDA_MSPDEINIT_CB_ID + * @param hirda irda handle + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_IRDA_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID + * @arg @ref HAL_IRDA_TX_COMPLETE_CB_ID Tx Complete Callback ID + * @arg @ref HAL_IRDA_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID + * @arg @ref HAL_IRDA_RX_COMPLETE_CB_ID Rx Complete Callback ID + * @arg @ref HAL_IRDA_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_IRDA_ABORT_COMPLETE_CB_ID Abort Complete Callback ID + * @arg @ref HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID + * @arg @ref HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID + * @arg @ref HAL_IRDA_MSPINIT_CB_ID MspInit Callback ID + * @arg @ref HAL_IRDA_MSPDEINIT_CB_ID MspDeInit Callback ID + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_UnRegisterCallback(IRDA_HandleTypeDef *hirda, HAL_IRDA_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (HAL_IRDA_STATE_READY == hirda->gState) + { + switch (CallbackID) + { + case HAL_IRDA_TX_HALFCOMPLETE_CB_ID : + hirda->TxHalfCpltCallback = HAL_IRDA_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */ + break; + + case HAL_IRDA_TX_COMPLETE_CB_ID : + hirda->TxCpltCallback = HAL_IRDA_TxCpltCallback; /* Legacy weak TxCpltCallback */ + break; + + case HAL_IRDA_RX_HALFCOMPLETE_CB_ID : + hirda->RxHalfCpltCallback = HAL_IRDA_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */ + break; + + case HAL_IRDA_RX_COMPLETE_CB_ID : + hirda->RxCpltCallback = HAL_IRDA_RxCpltCallback; /* Legacy weak RxCpltCallback */ + break; + + case HAL_IRDA_ERROR_CB_ID : + hirda->ErrorCallback = HAL_IRDA_ErrorCallback; /* Legacy weak ErrorCallback */ + break; + + case HAL_IRDA_ABORT_COMPLETE_CB_ID : + hirda->AbortCpltCallback = HAL_IRDA_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ + break; + + case HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID : + hirda->AbortTransmitCpltCallback = HAL_IRDA_AbortTransmitCpltCallback; /* Legacy weak + AbortTransmitCpltCallback */ + break; + + case HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID : + hirda->AbortReceiveCpltCallback = HAL_IRDA_AbortReceiveCpltCallback; /* Legacy weak + AbortReceiveCpltCallback */ + break; + + case HAL_IRDA_MSPINIT_CB_ID : + hirda->MspInitCallback = HAL_IRDA_MspInit; /* Legacy weak MspInitCallback */ + break; + + case HAL_IRDA_MSPDEINIT_CB_ID : + hirda->MspDeInitCallback = HAL_IRDA_MspDeInit; /* Legacy weak MspDeInitCallback */ + break; + + default : + /* Update the error code */ + hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_IRDA_STATE_RESET == hirda->gState) + { + switch (CallbackID) + { + case HAL_IRDA_MSPINIT_CB_ID : + hirda->MspInitCallback = HAL_IRDA_MspInit; + break; + + case HAL_IRDA_MSPDEINIT_CB_ID : + hirda->MspDeInitCallback = HAL_IRDA_MspDeInit; + break; + + default : + /* Update the error code */ + hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} +#endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup IRDA_Exported_Functions_Group2 IO operation functions + * @brief IRDA Transmit and Receive functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the IRDA data transfers. + + [..] + IrDA is a half duplex communication protocol. If the Transmitter is busy, any data + on the IrDA receive line will be ignored by the IrDA decoder and if the Receiver + is busy, data on the TX from the USART to IrDA will not be encoded by IrDA. + While receiving data, transmission should be avoided as the data to be transmitted + could be corrupted. + + [..] + (#) There are two modes of transfer: + (++) Blocking mode: the communication is performed in polling mode. + The HAL status of all data processing is returned by the same function + after finishing transfer. + (++) Non-Blocking mode: the communication is performed using Interrupts + or DMA, these API's return the HAL status. + The end of the data processing will be indicated through the + dedicated IRDA IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + The HAL_IRDA_TxCpltCallback(), HAL_IRDA_RxCpltCallback() user callbacks + will be executed respectively at the end of the Transmit or Receive process + The HAL_IRDA_ErrorCallback() user callback will be executed when a communication error is detected + + (#) Blocking mode APIs are : + (++) HAL_IRDA_Transmit() + (++) HAL_IRDA_Receive() + + (#) Non Blocking mode APIs with Interrupt are : + (++) HAL_IRDA_Transmit_IT() + (++) HAL_IRDA_Receive_IT() + (++) HAL_IRDA_IRQHandler() + + (#) Non Blocking mode functions with DMA are : + (++) HAL_IRDA_Transmit_DMA() + (++) HAL_IRDA_Receive_DMA() + (++) HAL_IRDA_DMAPause() + (++) HAL_IRDA_DMAResume() + (++) HAL_IRDA_DMAStop() + + (#) A set of Transfer Complete Callbacks are provided in Non Blocking mode: + (++) HAL_IRDA_TxHalfCpltCallback() + (++) HAL_IRDA_TxCpltCallback() + (++) HAL_IRDA_RxHalfCpltCallback() + (++) HAL_IRDA_RxCpltCallback() + (++) HAL_IRDA_ErrorCallback() + + (#) Non-Blocking mode transfers could be aborted using Abort API's : + (++) HAL_IRDA_Abort() + (++) HAL_IRDA_AbortTransmit() + (++) HAL_IRDA_AbortReceive() + (++) HAL_IRDA_Abort_IT() + (++) HAL_IRDA_AbortTransmit_IT() + (++) HAL_IRDA_AbortReceive_IT() + + (#) For Abort services based on interrupts (HAL_IRDA_Abortxxx_IT), a set of Abort Complete Callbacks are provided: + (++) HAL_IRDA_AbortCpltCallback() + (++) HAL_IRDA_AbortTransmitCpltCallback() + (++) HAL_IRDA_AbortReceiveCpltCallback() + + (#) In Non-Blocking mode transfers, possible errors are split into 2 categories. + Errors are handled as follows : + (++) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is + to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error + in Interrupt mode reception . + Received character is then retrieved and stored in Rx buffer, Error code is set to allow user + to identify error type, and HAL_IRDA_ErrorCallback() user callback is executed. + Transfer is kept ongoing on IRDA side. + If user wants to abort it, Abort services should be called by user. + (++) Error is considered as Blocking : Transfer could not be completed properly and is aborted. + This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode. + Error code is set to allow user to identify error type, and + HAL_IRDA_ErrorCallback() user callback is executed. + +@endverbatim + * @{ + */ + +/** + * @brief Send an amount of data in blocking mode. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * the sent data is handled as a set of u16. In this case, Size must reflect the number + * of u16 available through pData. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @param pData Pointer to data buffer (u8 or u16 data elements). + * @param Size Amount of data elements (u8 or u16) to be sent. + * @param Timeout Specify timeout value. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, const uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + const uint8_t *pdata8bits; + const uint16_t *pdata16bits; + uint32_t tickstart; + + /* Check that a Tx process is not already ongoing */ + if (hirda->gState == HAL_IRDA_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hirda); + + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + hirda->gState = HAL_IRDA_STATE_BUSY_TX; + + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + + hirda->TxXferSize = Size; + hirda->TxXferCount = Size; + + /* In case of 9bits/No Parity transfer, pData needs to be handled as a uint16_t pointer */ + if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE)) + { + pdata8bits = NULL; + pdata16bits = (const uint16_t *) pData; /* Derogation R.11.3 */ + } + else + { + pdata8bits = pData; + pdata16bits = NULL; + } + + while (hirda->TxXferCount > 0U) + { + hirda->TxXferCount--; + + if (IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + if (pdata8bits == NULL) + { + hirda->Instance->TDR = (uint16_t)(*pdata16bits & 0x01FFU); + pdata16bits++; + } + else + { + hirda->Instance->TDR = (uint8_t)(*pdata8bits & 0xFFU); + pdata8bits++; + } + } + + if (IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* At end of Tx process, restore hirda->gState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hirda); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in blocking mode. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * the received data is handled as a set of u16. In this case, Size must reflect the number + * of u16 available through pData. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @param pData Pointer to data buffer (u8 or u16 data elements). + * @param Size Amount of data elements (u8 or u16) to be received. + * @param Timeout Specify timeout value. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint8_t *pdata8bits; + uint16_t *pdata16bits; + uint16_t uhMask; + uint32_t tickstart; + + /* Check that a Rx process is not already ongoing */ + if (hirda->RxState == HAL_IRDA_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hirda); + + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + hirda->RxState = HAL_IRDA_STATE_BUSY_RX; + + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + + hirda->RxXferSize = Size; + hirda->RxXferCount = Size; + + /* Computation of the mask to apply to RDR register + of the UART associated to the IRDA */ + IRDA_MASK_COMPUTATION(hirda); + uhMask = hirda->Mask; + + /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */ + if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE)) + { + pdata8bits = NULL; + pdata16bits = (uint16_t *) pData; /* Derogation R.11.3 */ + } + else + { + pdata8bits = pData; + pdata16bits = NULL; + } + + /* Check data remaining to be received */ + while (hirda->RxXferCount > 0U) + { + hirda->RxXferCount--; + + if (IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + if (pdata8bits == NULL) + { + *pdata16bits = (uint16_t)(hirda->Instance->RDR & uhMask); + pdata16bits++; + } + else + { + *pdata8bits = (uint8_t)(hirda->Instance->RDR & (uint8_t)uhMask); + pdata8bits++; + } + } + + /* At end of Rx process, restore hirda->RxState to Ready */ + hirda->RxState = HAL_IRDA_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hirda); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Send an amount of data in interrupt mode. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * the sent data is handled as a set of u16. In this case, Size must reflect the number + * of u16 available through pData. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @param pData Pointer to data buffer (u8 or u16 data elements). + * @param Size Amount of data elements (u8 or u16) to be sent. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda, const uint8_t *pData, uint16_t Size) +{ + /* Check that a Tx process is not already ongoing */ + if (hirda->gState == HAL_IRDA_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hirda); + + hirda->pTxBuffPtr = pData; + hirda->TxXferSize = Size; + hirda->TxXferCount = Size; + + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + hirda->gState = HAL_IRDA_STATE_BUSY_TX; + + /* Process Unlocked */ + __HAL_UNLOCK(hirda); + + /* Enable the IRDA Transmit Data Register Empty Interrupt */ + SET_BIT(hirda->Instance->CR1, USART_CR1_TXEIE_TXFNFIE); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in interrupt mode. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * the received data is handled as a set of u16. In this case, Size must reflect the number + * of u16 available through pData. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @param pData Pointer to data buffer (u8 or u16 data elements). + * @param Size Amount of data elements (u8 or u16) to be received. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_Receive_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size) +{ + /* Check that a Rx process is not already ongoing */ + if (hirda->RxState == HAL_IRDA_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hirda); + + hirda->pRxBuffPtr = pData; + hirda->RxXferSize = Size; + hirda->RxXferCount = Size; + + /* Computation of the mask to apply to the RDR register + of the UART associated to the IRDA */ + IRDA_MASK_COMPUTATION(hirda); + + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + hirda->RxState = HAL_IRDA_STATE_BUSY_RX; + + /* Process Unlocked */ + __HAL_UNLOCK(hirda); + + if (hirda->Init.Parity != IRDA_PARITY_NONE) + { + /* Enable the IRDA Parity Error and Data Register not empty Interrupts */ + SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE); + } + else + { + /* Enable the IRDA Data Register not empty Interrupts */ + SET_BIT(hirda->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE); + } + + /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */ + SET_BIT(hirda->Instance->CR3, USART_CR3_EIE); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief Send an amount of data in DMA mode. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * the sent data is handled as a set of u16. In this case, Size must reflect the number + * of u16 available through pData. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @param pData pointer to data buffer (u8 or u16 data elements). + * @param Size Amount of data elements (u8 or u16) to be sent. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef *hirda, const uint8_t *pData, uint16_t Size) +{ + HAL_StatusTypeDef status; + uint16_t nbByte = Size; + + /* Check that a Tx process is not already ongoing */ + if (hirda->gState == HAL_IRDA_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hirda); + + hirda->pTxBuffPtr = pData; + hirda->TxXferSize = Size; + hirda->TxXferCount = Size; + + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + hirda->gState = HAL_IRDA_STATE_BUSY_TX; + + /* Set the IRDA DMA transfer complete callback */ + hirda->hdmatx->XferCpltCallback = IRDA_DMATransmitCplt; + + /* Set the IRDA DMA half transfer complete callback */ + hirda->hdmatx->XferHalfCpltCallback = IRDA_DMATransmitHalfCplt; + + /* Set the DMA error callback */ + hirda->hdmatx->XferErrorCallback = IRDA_DMAError; + + /* Set the DMA abort callback */ + hirda->hdmatx->XferAbortCallback = NULL; + + /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter + should be aligned on a u16 frontier, so nbByte should be equal to Size multiplied by 2 */ + if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE)) + { + nbByte = Size * 2U; + } + + /* Check linked list mode */ + if ((hirda->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hirda->hdmatx->LinkedListQueue != NULL) && (hirda->hdmatx->LinkedListQueue->Head != NULL)) + { + /* Set DMA data size */ + hirda->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = nbByte; + + /* Set DMA source address */ + hirda->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = + (uint32_t)hirda->pTxBuffPtr; + + /* Set DMA destination address */ + hirda->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = + (uint32_t)&hirda->Instance->TDR; + + /* Enable the IRDA transmit DMA channel */ + status = HAL_DMAEx_List_Start_IT(hirda->hdmatx); + } + else + { + /* Update status */ + status = HAL_ERROR; + } + } + else + { + /* Enable the IRDA transmit DMA channel */ + status = HAL_DMA_Start_IT(hirda->hdmatx, (uint32_t)hirda->pTxBuffPtr, (uint32_t)&hirda->Instance->TDR, nbByte); + } + + if (status == HAL_OK) + { + /* Clear the TC flag in the ICR register */ + __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_TCF); + + /* Process Unlocked */ + __HAL_UNLOCK(hirda); + + /* Enable the DMA transfer for transmit request by setting the DMAT bit + in the USART CR3 register */ + SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT); + + return HAL_OK; + } + else + { + /* Set error code to DMA */ + hirda->ErrorCode = HAL_IRDA_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hirda); + + /* Restore hirda->gState to ready */ + hirda->gState = HAL_IRDA_STATE_READY; + + return HAL_ERROR; + } + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in DMA mode. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * the received data is handled as a set of u16. In this case, Size must reflect the number + * of u16 available through pData. + * @note When the IRDA parity is enabled (PCE = 1), the received data contains + * the parity bit (MSB position). + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @param pData Pointer to data buffer (u8 or u16 data elements). + * @param Size Amount of data elements (u8 or u16) to be received. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size) +{ + HAL_StatusTypeDef status; + uint16_t nbByte = Size; + + /* Check that a Rx process is not already ongoing */ + if (hirda->RxState == HAL_IRDA_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hirda); + + hirda->pRxBuffPtr = pData; + hirda->RxXferSize = Size; + + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + hirda->RxState = HAL_IRDA_STATE_BUSY_RX; + + /* Set the IRDA DMA transfer complete callback */ + hirda->hdmarx->XferCpltCallback = IRDA_DMAReceiveCplt; + + /* Set the IRDA DMA half transfer complete callback */ + hirda->hdmarx->XferHalfCpltCallback = IRDA_DMAReceiveHalfCplt; + + /* Set the DMA error callback */ + hirda->hdmarx->XferErrorCallback = IRDA_DMAError; + + /* Set the DMA abort callback */ + hirda->hdmarx->XferAbortCallback = NULL; + + /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter + should be aligned on a u16 frontier, so nbByte should be equal to Size multiplied by 2 */ + if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE)) + { + nbByte = Size * 2U; + } + + /* Check linked list mode */ + if ((hirda->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hirda->hdmarx->LinkedListQueue != NULL) && (hirda->hdmarx->LinkedListQueue->Head != NULL)) + { + /* Set DMA data size */ + hirda->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = nbByte; + + /* Set DMA source address */ + hirda->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = + (uint32_t)&hirda->Instance->RDR; + + /* Set DMA destination address */ + hirda->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)hirda->pRxBuffPtr; + + /* Enable the DMA channel */ + status = HAL_DMAEx_List_Start_IT(hirda->hdmarx); + } + else + { + /* Update status */ + status = HAL_ERROR; + } + } + else + { + /* Enable the DMA channel */ + status = HAL_DMA_Start_IT(hirda->hdmarx, (uint32_t)&hirda->Instance->RDR, (uint32_t)hirda->pRxBuffPtr, nbByte); + } + + if (status == HAL_OK) + { + /* Process Unlocked */ + __HAL_UNLOCK(hirda); + + if (hirda->Init.Parity != IRDA_PARITY_NONE) + { + /* Enable the UART Parity Error Interrupt */ + SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE); + } + + /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ + SET_BIT(hirda->Instance->CR3, USART_CR3_EIE); + + /* Enable the DMA transfer for the receiver request by setting the DMAR bit + in the USART CR3 register */ + SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR); + + return HAL_OK; + } + else + { + /* Set error code to DMA */ + hirda->ErrorCode = HAL_IRDA_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hirda); + + /* Restore hirda->RxState to ready */ + hirda->RxState = HAL_IRDA_STATE_READY; + + return HAL_ERROR; + } + } + else + { + return HAL_BUSY; + } +} + + +/** + * @brief Pause the DMA Transfer. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_DMAPause(IRDA_HandleTypeDef *hirda) +{ + /* Process Locked */ + __HAL_LOCK(hirda); + + if (hirda->gState == HAL_IRDA_STATE_BUSY_TX) + { + if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT)) + { + /* Disable the IRDA DMA Tx request */ + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); + } + } + if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX) + { + if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) + { + /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE); + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); + + /* Disable the IRDA DMA Rx request */ + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); + } + } + + /* Process Unlocked */ + __HAL_UNLOCK(hirda); + + return HAL_OK; +} + +/** + * @brief Resume the DMA Transfer. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_DMAResume(IRDA_HandleTypeDef *hirda) +{ + /* Process Locked */ + __HAL_LOCK(hirda); + + if (hirda->gState == HAL_IRDA_STATE_BUSY_TX) + { + /* Enable the IRDA DMA Tx request */ + SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT); + } + if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX) + { + /* Clear the Overrun flag before resuming the Rx transfer*/ + __HAL_IRDA_CLEAR_OREFLAG(hirda); + + /* Re-enable PE and ERR (Frame error, noise error, overrun error) interrupts */ + if (hirda->Init.Parity != IRDA_PARITY_NONE) + { + SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE); + } + SET_BIT(hirda->Instance->CR3, USART_CR3_EIE); + + /* Enable the IRDA DMA Rx request */ + SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hirda); + + return HAL_OK; +} + +/** + * @brief Stop the DMA Transfer. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_DMAStop(IRDA_HandleTypeDef *hirda) +{ + /* The Lock is not implemented on this API to allow the user application + to call the HAL IRDA API under callbacks HAL_IRDA_TxCpltCallback() / HAL_IRDA_RxCpltCallback() / + HAL_IRDA_TxHalfCpltCallback / HAL_IRDA_RxHalfCpltCallback: + indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete + interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of + the stream and the corresponding call back is executed. */ + + /* Stop IRDA DMA Tx request if ongoing */ + if (hirda->gState == HAL_IRDA_STATE_BUSY_TX) + { + if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT)) + { + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); + + /* Abort the IRDA DMA Tx channel */ + if (hirda->hdmatx != NULL) + { + if (HAL_DMA_Abort(hirda->hdmatx) != HAL_OK) + { + if (HAL_DMA_GetError(hirda->hdmatx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + hirda->ErrorCode = HAL_IRDA_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + } + + IRDA_EndTxTransfer(hirda); + } + } + + /* Stop IRDA DMA Rx request if ongoing */ + if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX) + { + if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); + + /* Abort the IRDA DMA Rx channel */ + if (hirda->hdmarx != NULL) + { + if (HAL_DMA_Abort(hirda->hdmarx) != HAL_OK) + { + if (HAL_DMA_GetError(hirda->hdmarx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + hirda->ErrorCode = HAL_IRDA_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + } + + IRDA_EndRxTransfer(hirda); + } + } + + return HAL_OK; +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Abort ongoing transfers (blocking mode). + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable IRDA Interrupts (Tx and Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_Abort(IRDA_HandleTypeDef *hirda) +{ + /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | \ + USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE)); + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Disable the IRDA DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT)) + { + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); + + /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */ + if (hirda->hdmatx != NULL) + { + /* Set the IRDA DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + hirda->hdmatx->XferAbortCallback = NULL; + + if (HAL_DMA_Abort(hirda->hdmatx) != HAL_OK) + { + if (HAL_DMA_GetError(hirda->hdmatx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + hirda->ErrorCode = HAL_IRDA_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + } + } + + /* Disable the IRDA DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); + + /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */ + if (hirda->hdmarx != NULL) + { + /* Set the IRDA DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + hirda->hdmarx->XferAbortCallback = NULL; + + if (HAL_DMA_Abort(hirda->hdmarx) != HAL_OK) + { + if (HAL_DMA_GetError(hirda->hdmarx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + hirda->ErrorCode = HAL_IRDA_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + } + } +#endif /* HAL_DMA_MODULE_ENABLED */ + + /* Reset Tx and Rx transfer counters */ + hirda->TxXferCount = 0U; + hirda->RxXferCount = 0U; + + /* Clear the Error flags in the ICR register */ + __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF); + + /* Restore hirda->gState and hirda->RxState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; + hirda->RxState = HAL_IRDA_STATE_READY; + + /* Reset Handle ErrorCode to No Error */ + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + + return HAL_OK; +} + +/** + * @brief Abort ongoing Transmit transfer (blocking mode). + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable IRDA Interrupts (Tx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_AbortTransmit(IRDA_HandleTypeDef *hirda) +{ + /* Disable TXEIE and TCIE interrupts */ + CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE)); + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Disable the IRDA DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT)) + { + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); + + /* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */ + if (hirda->hdmatx != NULL) + { + /* Set the IRDA DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + hirda->hdmatx->XferAbortCallback = NULL; + + if (HAL_DMA_Abort(hirda->hdmatx) != HAL_OK) + { + if (HAL_DMA_GetError(hirda->hdmatx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + hirda->ErrorCode = HAL_IRDA_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + } + } +#endif /* HAL_DMA_MODULE_ENABLED */ + + /* Reset Tx transfer counter */ + hirda->TxXferCount = 0U; + + /* Restore hirda->gState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Abort ongoing Receive transfer (blocking mode). + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable IRDA Interrupts (Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_AbortReceive(IRDA_HandleTypeDef *hirda) +{ + /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Disable the IRDA DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); + + /* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */ + if (hirda->hdmarx != NULL) + { + /* Set the IRDA DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + hirda->hdmarx->XferAbortCallback = NULL; + + if (HAL_DMA_Abort(hirda->hdmarx) != HAL_OK) + { + if (HAL_DMA_GetError(hirda->hdmarx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + hirda->ErrorCode = HAL_IRDA_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + } + } +#endif /* HAL_DMA_MODULE_ENABLED */ + + /* Reset Rx transfer counter */ + hirda->RxXferCount = 0U; + + /* Clear the Error flags in the ICR register */ + __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF); + + /* Restore hirda->RxState to Ready */ + hirda->RxState = HAL_IRDA_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Abort ongoing transfers (Interrupt mode). + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable IRDA Interrupts (Tx and Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_Abort_IT(IRDA_HandleTypeDef *hirda) +{ + uint32_t abortcplt = 1U; + + /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | \ + USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE)); + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); + +#if defined(HAL_DMA_MODULE_ENABLED) + /* If DMA Tx and/or DMA Rx Handles are associated to IRDA Handle, DMA Abort complete callbacks should be initialised + before any call to DMA Abort functions */ + /* DMA Tx Handle is valid */ + if (hirda->hdmatx != NULL) + { + /* Set DMA Abort Complete callback if IRDA DMA Tx request if enabled. + Otherwise, set it to NULL */ + if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT)) + { + hirda->hdmatx->XferAbortCallback = IRDA_DMATxAbortCallback; + } + else + { + hirda->hdmatx->XferAbortCallback = NULL; + } + } + /* DMA Rx Handle is valid */ + if (hirda->hdmarx != NULL) + { + /* Set DMA Abort Complete callback if IRDA DMA Rx request if enabled. + Otherwise, set it to NULL */ + if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) + { + hirda->hdmarx->XferAbortCallback = IRDA_DMARxAbortCallback; + } + else + { + hirda->hdmarx->XferAbortCallback = NULL; + } + } + + /* Disable the IRDA DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT)) + { + /* Disable DMA Tx at UART level */ + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); + + /* Abort the IRDA DMA Tx channel : use non blocking DMA Abort API (callback) */ + if (hirda->hdmatx != NULL) + { + /* IRDA Tx DMA Abort callback has already been initialised : + will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */ + + /* Abort DMA TX */ + if (HAL_DMA_Abort_IT(hirda->hdmatx) != HAL_OK) + { + hirda->hdmatx->XferAbortCallback = NULL; + } + else + { + abortcplt = 0U; + } + } + } + + /* Disable the IRDA DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); + + /* Abort the IRDA DMA Rx channel : use non blocking DMA Abort API (callback) */ + if (hirda->hdmarx != NULL) + { + /* IRDA Rx DMA Abort callback has already been initialised : + will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */ + + /* Abort DMA RX */ + if (HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK) + { + hirda->hdmarx->XferAbortCallback = NULL; + abortcplt = 1U; + } + else + { + abortcplt = 0U; + } + } + } +#endif /* HAL_DMA_MODULE_ENABLED */ + + /* if no DMA abort complete callback execution is required => call user Abort Complete callback */ + if (abortcplt == 1U) + { + /* Reset Tx and Rx transfer counters */ + hirda->TxXferCount = 0U; + hirda->RxXferCount = 0U; + + /* Reset errorCode */ + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + + /* Clear the Error flags in the ICR register */ + __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF); + + /* Restore hirda->gState and hirda->RxState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; + hirda->RxState = HAL_IRDA_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ +#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) + /* Call registered Abort complete callback */ + hirda->AbortCpltCallback(hirda); +#else + /* Call legacy weak Abort complete callback */ + HAL_IRDA_AbortCpltCallback(hirda); +#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ + } + + return HAL_OK; +} + +/** + * @brief Abort ongoing Transmit transfer (Interrupt mode). + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable IRDA Interrupts (Tx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_AbortTransmit_IT(IRDA_HandleTypeDef *hirda) +{ + /* Disable TXEIE and TCIE interrupts */ + CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE)); + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Disable the IRDA DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT)) + { + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); + + /* Abort the IRDA DMA Tx channel : use non blocking DMA Abort API (callback) */ + if (hirda->hdmatx != NULL) + { + /* Set the IRDA DMA Abort callback : + will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */ + hirda->hdmatx->XferAbortCallback = IRDA_DMATxOnlyAbortCallback; + + /* Abort DMA TX */ + if (HAL_DMA_Abort_IT(hirda->hdmatx) != HAL_OK) + { + /* Call Directly hirda->hdmatx->XferAbortCallback function in case of error */ + hirda->hdmatx->XferAbortCallback(hirda->hdmatx); + } + } + else + { + /* Reset Tx transfer counter */ + hirda->TxXferCount = 0U; + + /* Restore hirda->gState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ +#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) + /* Call registered Abort Transmit Complete Callback */ + hirda->AbortTransmitCpltCallback(hirda); +#else + /* Call legacy weak Abort Transmit Complete Callback */ + HAL_IRDA_AbortTransmitCpltCallback(hirda); +#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ + } + } + else +#endif /* HAL_DMA_MODULE_ENABLED */ + { + /* Reset Tx transfer counter */ + hirda->TxXferCount = 0U; + + /* Restore hirda->gState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ +#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) + /* Call registered Abort Transmit Complete Callback */ + hirda->AbortTransmitCpltCallback(hirda); +#else + /* Call legacy weak Abort Transmit Complete Callback */ + HAL_IRDA_AbortTransmitCpltCallback(hirda); +#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ + } + + return HAL_OK; +} + +/** + * @brief Abort ongoing Receive transfer (Interrupt mode). + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable IRDA Interrupts (Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_AbortReceive_IT(IRDA_HandleTypeDef *hirda) +{ + /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Disable the IRDA DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); + + /* Abort the IRDA DMA Rx channel : use non blocking DMA Abort API (callback) */ + if (hirda->hdmarx != NULL) + { + /* Set the IRDA DMA Abort callback : + will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */ + hirda->hdmarx->XferAbortCallback = IRDA_DMARxOnlyAbortCallback; + + /* Abort DMA RX */ + if (HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK) + { + /* Call Directly hirda->hdmarx->XferAbortCallback function in case of error */ + hirda->hdmarx->XferAbortCallback(hirda->hdmarx); + } + } + else + { + /* Reset Rx transfer counter */ + hirda->RxXferCount = 0U; + + /* Clear the Error flags in the ICR register */ + __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF); + + /* Restore hirda->RxState to Ready */ + hirda->RxState = HAL_IRDA_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ +#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) + /* Call registered Abort Receive Complete Callback */ + hirda->AbortReceiveCpltCallback(hirda); +#else + /* Call legacy weak Abort Receive Complete Callback */ + HAL_IRDA_AbortReceiveCpltCallback(hirda); +#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ + } + } + else +#endif /* HAL_DMA_MODULE_ENABLED */ + { + /* Reset Rx transfer counter */ + hirda->RxXferCount = 0U; + + /* Clear the Error flags in the ICR register */ + __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF); + + /* Restore hirda->RxState to Ready */ + hirda->RxState = HAL_IRDA_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ +#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) + /* Call registered Abort Receive Complete Callback */ + hirda->AbortReceiveCpltCallback(hirda); +#else + /* Call legacy weak Abort Receive Complete Callback */ + HAL_IRDA_AbortReceiveCpltCallback(hirda); +#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ + } + + return HAL_OK; +} + +/** + * @brief Handle IRDA interrupt request. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ +void HAL_IRDA_IRQHandler(IRDA_HandleTypeDef *hirda) +{ + uint32_t isrflags = READ_REG(hirda->Instance->ISR); + uint32_t cr1its = READ_REG(hirda->Instance->CR1); + uint32_t cr3its; + uint32_t errorflags; + uint32_t errorcode; + + /* If no error occurs */ + errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE)); + if (errorflags == 0U) + { + /* IRDA in mode Receiver ---------------------------------------------------*/ + if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U) && ((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U)) + { + IRDA_Receive_IT(hirda); + return; + } + } + + /* If some errors occur */ + cr3its = READ_REG(hirda->Instance->CR3); + if ((errorflags != 0U) + && (((cr3its & USART_CR3_EIE) != 0U) + || ((cr1its & (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)) != 0U))) + { + /* IRDA parity error interrupt occurred -------------------------------------*/ + if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U)) + { + __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_PEF); + + hirda->ErrorCode |= HAL_IRDA_ERROR_PE; + } + + /* IRDA frame error interrupt occurred --------------------------------------*/ + if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) + { + __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_FEF); + + hirda->ErrorCode |= HAL_IRDA_ERROR_FE; + } + + /* IRDA noise error interrupt occurred --------------------------------------*/ + if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) + { + __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_NEF); + + hirda->ErrorCode |= HAL_IRDA_ERROR_NE; + } + + /* IRDA Over-Run interrupt occurred -----------------------------------------*/ + if (((isrflags & USART_ISR_ORE) != 0U) && + (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) || ((cr3its & USART_CR3_EIE) != 0U))) + { + __HAL_IRDA_CLEAR_IT(hirda, IRDA_CLEAR_OREF); + + hirda->ErrorCode |= HAL_IRDA_ERROR_ORE; + } + + /* Call IRDA Error Call back function if need be --------------------------*/ + if (hirda->ErrorCode != HAL_IRDA_ERROR_NONE) + { + /* IRDA in mode Receiver ---------------------------------------------------*/ + if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U) && ((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U)) + { + IRDA_Receive_IT(hirda); + } + + /* If Overrun error occurs, or if any error occurs in DMA mode reception, + consider error as blocking */ + errorcode = hirda->ErrorCode; + if ((HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) || + ((errorcode & HAL_IRDA_ERROR_ORE) != 0U)) + { + /* Blocking error : transfer is aborted + Set the IRDA state ready to be able to start again the process, + Disable Rx Interrupts, and disable Rx DMA request, if ongoing */ + IRDA_EndRxTransfer(hirda); + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Disable the IRDA DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); + + /* Abort the IRDA DMA Rx channel */ + if (hirda->hdmarx != NULL) + { + /* Set the IRDA DMA Abort callback : + will lead to call HAL_IRDA_ErrorCallback() at end of DMA abort procedure */ + hirda->hdmarx->XferAbortCallback = IRDA_DMAAbortOnError; + + /* Abort DMA RX */ + if (HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK) + { + /* Call Directly hirda->hdmarx->XferAbortCallback function in case of error */ + hirda->hdmarx->XferAbortCallback(hirda->hdmarx); + } + } + else + { +#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) + /* Call registered user error callback */ + hirda->ErrorCallback(hirda); +#else + /* Call legacy weak user error callback */ + HAL_IRDA_ErrorCallback(hirda); +#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ + } + } + else +#endif /* HAL_DMA_MODULE_ENABLED */ + { +#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) + /* Call registered user error callback */ + hirda->ErrorCallback(hirda); +#else + /* Call legacy weak user error callback */ + HAL_IRDA_ErrorCallback(hirda); +#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ + } + } + else + { + /* Non Blocking error : transfer could go on. + Error is notified to user through user error callback */ +#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) + /* Call registered user error callback */ + hirda->ErrorCallback(hirda); +#else + /* Call legacy weak user error callback */ + HAL_IRDA_ErrorCallback(hirda); +#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + } + } + return; + + } /* End if some error occurs */ + + /* IRDA in mode Transmitter ------------------------------------------------*/ + if (((isrflags & USART_ISR_TXE_TXFNF) != 0U) && ((cr1its & USART_CR1_TXEIE_TXFNFIE) != 0U)) + { + IRDA_Transmit_IT(hirda); + return; + } + + /* IRDA in mode Transmitter (transmission end) -----------------------------*/ + if (((isrflags & USART_ISR_TC) != 0U) && ((cr1its & USART_CR1_TCIE) != 0U)) + { + IRDA_EndTransmit_IT(hirda); + return; + } + +} + +/** + * @brief Tx Transfer completed callback. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ +__weak void HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef *hirda) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hirda); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_IRDA_TxCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief Tx Half Transfer completed callback. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @retval None + */ +__weak void HAL_IRDA_TxHalfCpltCallback(IRDA_HandleTypeDef *hirda) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hirda); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_IRDA_TxHalfCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief Rx Transfer completed callback. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ +__weak void HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef *hirda) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hirda); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_IRDA_RxCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief Rx Half Transfer complete callback. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ +__weak void HAL_IRDA_RxHalfCpltCallback(IRDA_HandleTypeDef *hirda) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hirda); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_IRDA_RxHalfCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief IRDA error callback. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ +__weak void HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef *hirda) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hirda); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_IRDA_ErrorCallback can be implemented in the user file. + */ +} + +/** + * @brief IRDA Abort Complete callback. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ +__weak void HAL_IRDA_AbortCpltCallback(IRDA_HandleTypeDef *hirda) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hirda); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_IRDA_AbortCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief IRDA Abort Complete callback. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ +__weak void HAL_IRDA_AbortTransmitCpltCallback(IRDA_HandleTypeDef *hirda) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hirda); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_IRDA_AbortTransmitCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief IRDA Abort Receive Complete callback. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ +__weak void HAL_IRDA_AbortReceiveCpltCallback(IRDA_HandleTypeDef *hirda) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hirda); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_IRDA_AbortReceiveCpltCallback can be implemented in the user file. + */ +} + +/** + * @} + */ + +/** @defgroup IRDA_Exported_Functions_Group4 Peripheral State and Error functions + * @brief IRDA State and Errors functions + * +@verbatim + ============================================================================== + ##### Peripheral State and Error functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to return the State of IrDA + communication process and also return Peripheral Errors occurred during communication process + (+) HAL_IRDA_GetState() API can be helpful to check in run-time the state + of the IRDA peripheral handle. + (+) HAL_IRDA_GetError() checks in run-time errors that could occur during + communication. + +@endverbatim + * @{ + */ + +/** + * @brief Return the IRDA handle state. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval HAL state + */ +HAL_IRDA_StateTypeDef HAL_IRDA_GetState(const IRDA_HandleTypeDef *hirda) +{ + /* Return IRDA handle state */ + uint32_t temp1; + uint32_t temp2; + temp1 = (uint32_t)hirda->gState; + temp2 = (uint32_t)hirda->RxState; + + return (HAL_IRDA_StateTypeDef)(temp1 | temp2); +} + +/** + * @brief Return the IRDA handle error code. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval IRDA Error Code + */ +uint32_t HAL_IRDA_GetError(const IRDA_HandleTypeDef *hirda) +{ + return hirda->ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup IRDA_Private_Functions IRDA Private Functions + * @{ + */ + +#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) +/** + * @brief Initialize the callbacks to their default values. + * @param hirda IRDA handle. + * @retval none + */ +void IRDA_InitCallbacksToDefault(IRDA_HandleTypeDef *hirda) +{ + /* Init the IRDA Callback settings */ + hirda->TxHalfCpltCallback = HAL_IRDA_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */ + hirda->TxCpltCallback = HAL_IRDA_TxCpltCallback; /* Legacy weak TxCpltCallback */ + hirda->RxHalfCpltCallback = HAL_IRDA_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */ + hirda->RxCpltCallback = HAL_IRDA_RxCpltCallback; /* Legacy weak RxCpltCallback */ + hirda->ErrorCallback = HAL_IRDA_ErrorCallback; /* Legacy weak ErrorCallback */ + hirda->AbortCpltCallback = HAL_IRDA_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ + hirda->AbortTransmitCpltCallback = HAL_IRDA_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */ + hirda->AbortReceiveCpltCallback = HAL_IRDA_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */ + +} +#endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */ + +/** + * @brief Configure the IRDA peripheral. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval HAL status + */ +static HAL_StatusTypeDef IRDA_SetConfig(IRDA_HandleTypeDef *hirda) +{ + uint32_t tmpreg; + IRDA_ClockSourceTypeDef clocksource; + HAL_StatusTypeDef ret = HAL_OK; + static const uint16_t IRDAPrescTable[12] = {1U, 2U, 4U, 6U, 8U, 10U, 12U, 16U, 32U, 64U, 128U, 256U}; + PLL2_ClocksTypeDef pll2_clocks; +#if defined(RCC_CR_PLL3ON) + PLL3_ClocksTypeDef pll3_clocks; +#endif /* RCC_CR_PLL3ON */ + uint32_t pclk; + + /* Check the communication parameters */ + assert_param(IS_IRDA_BAUDRATE(hirda->Init.BaudRate)); + assert_param(IS_IRDA_WORD_LENGTH(hirda->Init.WordLength)); + assert_param(IS_IRDA_PARITY(hirda->Init.Parity)); + assert_param(IS_IRDA_TX_RX_MODE(hirda->Init.Mode)); + assert_param(IS_IRDA_PRESCALER(hirda->Init.Prescaler)); + assert_param(IS_IRDA_POWERMODE(hirda->Init.PowerMode)); + assert_param(IS_IRDA_CLOCKPRESCALER(hirda->Init.ClockPrescaler)); + + /*-------------------------- USART CR1 Configuration -----------------------*/ + /* Configure the IRDA Word Length, Parity and transfer Mode: + Set the M bits according to hirda->Init.WordLength value + Set PCE and PS bits according to hirda->Init.Parity value + Set TE and RE bits according to hirda->Init.Mode value */ + tmpreg = (uint32_t)hirda->Init.WordLength | hirda->Init.Parity | hirda->Init.Mode ; + + MODIFY_REG(hirda->Instance->CR1, IRDA_CR1_FIELDS, tmpreg); + + /*-------------------------- USART CR3 Configuration -----------------------*/ + MODIFY_REG(hirda->Instance->CR3, USART_CR3_IRLP, hirda->Init.PowerMode); + + /*--------------------- USART clock PRESC Configuration ----------------*/ + /* Configure + * - IRDA Clock Prescaler: set PRESCALER according to hirda->Init.ClockPrescaler value */ + MODIFY_REG(hirda->Instance->PRESC, USART_PRESC_PRESCALER, hirda->Init.ClockPrescaler); + + /*-------------------------- USART GTPR Configuration ----------------------*/ + MODIFY_REG(hirda->Instance->GTPR, (uint16_t)USART_GTPR_PSC, (uint16_t)hirda->Init.Prescaler); + + /*-------------------------- USART BRR Configuration -----------------------*/ + IRDA_GETCLOCKSOURCE(hirda, clocksource); + tmpreg = 0U; + switch (clocksource) + { + case IRDA_CLOCKSOURCE_PLL2Q: + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(pll2_clocks.PLL2_Q_Frequency, + hirda->Init.BaudRate, hirda->Init.ClockPrescaler)); + break; +#if defined(RCC_CR_PLL3ON) + case IRDA_CLOCKSOURCE_PLL3Q: + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(pll3_clocks.PLL3_Q_Frequency, hirda->Init.BaudRate, + hirda->Init.ClockPrescaler)); + break; +#endif /* RCC_CR_PLL3ON */ + case IRDA_CLOCKSOURCE_CSI: + tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(CSI_VALUE, hirda->Init.BaudRate, hirda->Init.ClockPrescaler)); + break; + case IRDA_CLOCKSOURCE_PCLK1: + pclk = HAL_RCC_GetPCLK1Freq(); + tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(pclk, hirda->Init.BaudRate, hirda->Init.ClockPrescaler)); + break; + case IRDA_CLOCKSOURCE_PCLK2: + pclk = HAL_RCC_GetPCLK2Freq(); + tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(pclk, hirda->Init.BaudRate, hirda->Init.ClockPrescaler)); + break; + case IRDA_CLOCKSOURCE_HSI: + tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16(HSI_VALUE, hirda->Init.BaudRate, hirda->Init.ClockPrescaler)); + break; + case IRDA_CLOCKSOURCE_LSE: + tmpreg = (uint32_t)(IRDA_DIV_SAMPLING16((uint32_t)LSE_VALUE, hirda->Init.BaudRate, hirda->Init.ClockPrescaler)); + break; + default: + ret = HAL_ERROR; + break; + } + + /* USARTDIV must be greater than or equal to 0d16 */ + if ((tmpreg >= USART_BRR_MIN) && (tmpreg <= USART_BRR_MAX)) + { + hirda->Instance->BRR = (uint16_t)tmpreg; + } + else + { + ret = HAL_ERROR; + } + + return ret; +} + +/** + * @brief Check the IRDA Idle State. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval HAL status + */ +static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda) +{ + uint32_t tickstart; + + /* Initialize the IRDA ErrorCode */ + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + + /* Check if the Transmitter is enabled */ + if ((hirda->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE) + { + /* Wait until TEACK flag is set */ + if (IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_TEACK, RESET, tickstart, IRDA_TEACK_REACK_TIMEOUT) != HAL_OK) + { + /* Timeout occurred */ + return HAL_TIMEOUT; + } + } + /* Check if the Receiver is enabled */ + if ((hirda->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE) + { + /* Wait until REACK flag is set */ + if (IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_REACK, RESET, tickstart, IRDA_TEACK_REACK_TIMEOUT) != HAL_OK) + { + /* Timeout occurred */ + return HAL_TIMEOUT; + } + } + + /* Initialize the IRDA state*/ + hirda->gState = HAL_IRDA_STATE_READY; + hirda->RxState = HAL_IRDA_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hirda); + + return HAL_OK; +} + +/** + * @brief Handle IRDA Communication Timeout. It waits + * until a flag is no longer in the specified status. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @param Flag Specifies the IRDA flag to check. + * @param Status The actual Flag status (SET or RESET) + * @param Tickstart Tick start value + * @param Timeout Timeout duration + * @retval HAL status + */ +static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, + uint32_t Tickstart, uint32_t Timeout) +{ + /* Wait until flag is set */ + while ((__HAL_IRDA_GET_FLAG(hirda, Flag) ? SET : RESET) == Status) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + { + /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) + interrupts for the interrupt process */ + CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE)); + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); + + hirda->gState = HAL_IRDA_STATE_READY; + hirda->RxState = HAL_IRDA_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hirda); + return HAL_TIMEOUT; + } + } + } + return HAL_OK; +} + + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief End ongoing Tx transfer on IRDA peripheral (following error detection or Transmit completion). + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ +static void IRDA_EndTxTransfer(IRDA_HandleTypeDef *hirda) +{ + /* Disable TXEIE and TCIE interrupts */ + CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE)); + + /* At end of Tx process, restore hirda->gState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief End ongoing Rx transfer on UART peripheral (following error detection or Reception completion). + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ +static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda) +{ + /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); + + /* At end of Rx process, restore hirda->RxState to Ready */ + hirda->RxState = HAL_IRDA_STATE_READY; +} + + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief DMA IRDA transmit process complete callback. + * @param hdma Pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent); + + /* DMA Normal mode */ + if (hdma->Mode != DMA_LINKEDLIST_CIRCULAR) + { + hirda->TxXferCount = 0U; + + /* Disable the DMA transfer for transmit request by resetting the DMAT bit + in the IRDA CR3 register */ + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); + + /* Enable the IRDA Transmit Complete Interrupt */ + SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE); + } + /* DMA Circular mode */ + else + { +#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) + /* Call registered Tx complete callback */ + hirda->TxCpltCallback(hirda); +#else + /* Call legacy weak Tx complete callback */ + HAL_IRDA_TxCpltCallback(hirda); +#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ + } + +} + +/** + * @brief DMA IRDA transmit process half complete callback. + * @param hdma Pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent); + +#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) + /* Call registered Tx Half complete callback */ + hirda->TxHalfCpltCallback(hirda); +#else + /* Call legacy weak Tx complete callback */ + HAL_IRDA_TxHalfCpltCallback(hirda); +#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ +} + +/** + * @brief DMA IRDA receive process complete callback. + * @param hdma Pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent); + + /* DMA Normal mode */ + if (hdma->Mode != DMA_LINKEDLIST_CIRCULAR) + { + hirda->RxXferCount = 0U; + + /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE); + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); + + /* Disable the DMA transfer for the receiver request by resetting the DMAR bit + in the IRDA CR3 register */ + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); + + /* At end of Rx process, restore hirda->RxState to Ready */ + hirda->RxState = HAL_IRDA_STATE_READY; + } + +#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) + /* Call registered Rx complete callback */ + hirda->RxCpltCallback(hirda); +#else + /* Call legacy weak Rx complete callback */ + HAL_IRDA_RxCpltCallback(hirda); +#endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA IRDA receive process half complete callback. + * @param hdma Pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent); + +#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) + /*Call registered Rx Half complete callback*/ + hirda->RxHalfCpltCallback(hirda); +#else + /* Call legacy weak Rx Half complete callback */ + HAL_IRDA_RxHalfCpltCallback(hirda); +#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ +} + +/** + * @brief DMA IRDA communication error callback. + * @param hdma Pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void IRDA_DMAError(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent); + + /* Stop IRDA DMA Tx request if ongoing */ + if (hirda->gState == HAL_IRDA_STATE_BUSY_TX) + { + if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT)) + { + hirda->TxXferCount = 0U; + IRDA_EndTxTransfer(hirda); + } + } + + /* Stop IRDA DMA Rx request if ongoing */ + if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX) + { + if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR)) + { + hirda->RxXferCount = 0U; + IRDA_EndRxTransfer(hirda); + } + } + + hirda->ErrorCode |= HAL_IRDA_ERROR_DMA; +#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) + /* Call registered user error callback */ + hirda->ErrorCallback(hirda); +#else + /* Call legacy weak user error callback */ + HAL_IRDA_ErrorCallback(hirda); +#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ +} + +/** + * @brief DMA IRDA communication abort callback, when initiated by HAL services on Error + * (To be called at end of DMA Abort procedure following error occurrence). + * @param hdma DMA handle. + * @retval None + */ +static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent); + hirda->RxXferCount = 0U; + hirda->TxXferCount = 0U; + +#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) + /* Call registered user error callback */ + hirda->ErrorCallback(hirda); +#else + /* Call legacy weak user error callback */ + HAL_IRDA_ErrorCallback(hirda); +#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ +} + +/** + * @brief DMA IRDA Tx communication abort callback, when initiated by user + * (To be called at end of DMA Tx Abort procedure following user abort request). + * @note When this callback is executed, User Abort complete call back is called only if no + * Abort still ongoing for Rx DMA Handle. + * @param hdma DMA handle. + * @retval None + */ +static void IRDA_DMATxAbortCallback(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent); + + hirda->hdmatx->XferAbortCallback = NULL; + + /* Check if an Abort process is still ongoing */ + if (hirda->hdmarx != NULL) + { + if (hirda->hdmarx->XferAbortCallback != NULL) + { + return; + } + } + + /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ + hirda->TxXferCount = 0U; + hirda->RxXferCount = 0U; + + /* Reset errorCode */ + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + + /* Clear the Error flags in the ICR register */ + __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF); + + /* Restore hirda->gState and hirda->RxState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; + hirda->RxState = HAL_IRDA_STATE_READY; + + /* Call user Abort complete callback */ +#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) + /* Call registered Abort complete callback */ + hirda->AbortCpltCallback(hirda); +#else + /* Call legacy weak Abort complete callback */ + HAL_IRDA_AbortCpltCallback(hirda); +#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ +} + + +/** + * @brief DMA IRDA Rx communication abort callback, when initiated by user + * (To be called at end of DMA Rx Abort procedure following user abort request). + * @note When this callback is executed, User Abort complete call back is called only if no + * Abort still ongoing for Tx DMA Handle. + * @param hdma DMA handle. + * @retval None + */ +static void IRDA_DMARxAbortCallback(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent); + + hirda->hdmarx->XferAbortCallback = NULL; + + /* Check if an Abort process is still ongoing */ + if (hirda->hdmatx != NULL) + { + if (hirda->hdmatx->XferAbortCallback != NULL) + { + return; + } + } + + /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ + hirda->TxXferCount = 0U; + hirda->RxXferCount = 0U; + + /* Reset errorCode */ + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + + /* Clear the Error flags in the ICR register */ + __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF); + + /* Restore hirda->gState and hirda->RxState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; + hirda->RxState = HAL_IRDA_STATE_READY; + + /* Call user Abort complete callback */ +#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) + /* Call registered Abort complete callback */ + hirda->AbortCpltCallback(hirda); +#else + /* Call legacy weak Abort complete callback */ + HAL_IRDA_AbortCpltCallback(hirda); +#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ +} + + +/** + * @brief DMA IRDA Tx communication abort callback, when initiated by user by a call to + * HAL_IRDA_AbortTransmit_IT API (Abort only Tx transfer) + * (This callback is executed at end of DMA Tx Abort procedure following user abort request, + * and leads to user Tx Abort Complete callback execution). + * @param hdma DMA handle. + * @retval None + */ +static void IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)(hdma->Parent); + + hirda->TxXferCount = 0U; + + /* Restore hirda->gState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; + + /* Call user Abort complete callback */ +#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) + /* Call registered Abort Transmit Complete Callback */ + hirda->AbortTransmitCpltCallback(hirda); +#else + /* Call legacy weak Abort Transmit Complete Callback */ + HAL_IRDA_AbortTransmitCpltCallback(hirda); +#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ +} + +/** + * @brief DMA IRDA Rx communication abort callback, when initiated by user by a call to + * HAL_IRDA_AbortReceive_IT API (Abort only Rx transfer) + * (This callback is executed at end of DMA Rx Abort procedure following user abort request, + * and leads to user Rx Abort Complete callback execution). + * @param hdma DMA handle. + * @retval None + */ +static void IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + hirda->RxXferCount = 0U; + + /* Clear the Error flags in the ICR register */ + __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_CLEAR_OREF | IRDA_CLEAR_NEF | IRDA_CLEAR_PEF | IRDA_CLEAR_FEF); + + /* Restore hirda->RxState to Ready */ + hirda->RxState = HAL_IRDA_STATE_READY; + + /* Call user Abort complete callback */ +#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) + /* Call registered Abort Receive Complete Callback */ + hirda->AbortReceiveCpltCallback(hirda); +#else + /* Call legacy weak Abort Receive Complete Callback */ + HAL_IRDA_AbortReceiveCpltCallback(hirda); +#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Send an amount of data in interrupt mode. + * @note Function is called under interruption only, once + * interruptions have been enabled by HAL_IRDA_Transmit_IT(). + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ +static void IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda) +{ + const uint16_t *tmp; + + /* Check that a Tx process is ongoing */ + if (hirda->gState == HAL_IRDA_STATE_BUSY_TX) + { + if (hirda->TxXferCount == 0U) + { + /* Disable the IRDA Transmit Data Register Empty Interrupt */ + CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TXEIE_TXFNFIE); + + /* Enable the IRDA Transmit Complete Interrupt */ + SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE); + } + else + { + if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE)) + { + tmp = (const uint16_t *) hirda->pTxBuffPtr; /* Derogation R.11.3 */ + hirda->Instance->TDR = (uint16_t)(*tmp & 0x01FFU); + hirda->pTxBuffPtr += 2U; + } + else + { + hirda->Instance->TDR = (uint8_t)(*hirda->pTxBuffPtr & 0xFFU); + hirda->pTxBuffPtr++; + } + hirda->TxXferCount--; + } + } +} + +/** + * @brief Wrap up transmission in non-blocking mode. + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ +static void IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda) +{ + /* Disable the IRDA Transmit Complete Interrupt */ + CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TCIE); + + /* Tx process is ended, restore hirda->gState to Ready */ + hirda->gState = HAL_IRDA_STATE_READY; + +#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) + /* Call registered Tx complete callback */ + hirda->TxCpltCallback(hirda); +#else + /* Call legacy weak Tx complete callback */ + HAL_IRDA_TxCpltCallback(hirda); +#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */ +} + +/** + * @brief Receive an amount of data in interrupt mode. + * @note Function is called under interruption only, once + * interruptions have been enabled by HAL_IRDA_Receive_IT() + * @param hirda Pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ +static void IRDA_Receive_IT(IRDA_HandleTypeDef *hirda) +{ + uint16_t *tmp; + uint16_t uhMask = hirda->Mask; + uint16_t uhdata; + + /* Check that a Rx process is ongoing */ + if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX) + { + uhdata = (uint16_t) READ_REG(hirda->Instance->RDR); + if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE)) + { + tmp = (uint16_t *) hirda->pRxBuffPtr; /* Derogation R.11.3 */ + *tmp = (uint16_t)(uhdata & uhMask); + hirda->pRxBuffPtr += 2U; + } + else + { + *hirda->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask); + hirda->pRxBuffPtr++; + } + + hirda->RxXferCount--; + if (hirda->RxXferCount == 0U) + { + /* Disable the IRDA Parity Error Interrupt and RXNE interrupt */ + CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); + + /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */ + CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE); + + /* Rx process is completed, restore hirda->RxState to Ready */ + hirda->RxState = HAL_IRDA_STATE_READY; + +#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1) + /* Call registered Rx complete callback */ + hirda->RxCpltCallback(hirda); +#else + /* Call legacy weak Rx complete callback */ + HAL_IRDA_RxCpltCallback(hirda); +#endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */ + } + } + else + { + /* Clear RXNE interrupt flag */ + __HAL_IRDA_SEND_REQ(hirda, IRDA_RXDATA_FLUSH_REQUEST); + } +} + +/** + * @} + */ + +#endif /* HAL_IRDA_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_iwdg.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_iwdg.c new file mode 100644 index 0000000000..8ff2dbbfc6 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_iwdg.c @@ -0,0 +1,510 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_iwdg.c + * @author MCD Application Team + * @brief IWDG HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Independent Watchdog (IWDG) peripheral: + * + Initialization and Start functions + * + IO operation functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### IWDG Generic features ##### + ============================================================================== + [..] + (+) The IWDG can be started by either software or hardware (configurable + through option byte). + + (+) The IWDG is clocked by the Low-Speed Internal clock (LSI) and thus stays + active even if the main clock fails. + + (+) Once the IWDG is started, the LSI is forced ON and both cannot be + disabled. The counter starts counting down from the reset value (0xFFF). + When it reaches the end of count value (0x000) a reset signal is + generated (IWDG reset). + + (+) Whenever the key value 0x0000 AAAA is written in the IWDG_KR register, + the IWDG_RLR value is reloaded into the counter and the watchdog reset + is prevented. + + (+) The IWDG is implemented in the VDD voltage domain that is still functional + in STOP and STANDBY mode (IWDG reset can wake up the CPU from STANDBY). + IWDGRST flag in RCC_CSR register can be used to inform when an IWDG + reset occurs. + + (+) Debug mode: When the microcontroller enters debug mode (core halted), + the IWDG counter either continues to work normally or stops, depending + on DBG_IWDG_STOP configuration bit in DBG module, accessible through + __HAL_DBGMCU_FREEZE_IWDG() and __HAL_DBGMCU_UNFREEZE_IWDG() macros. + + [..] Min-max timeout value @32KHz (LSI): ~125us / ~131.04s + The IWDG timeout may vary due to LSI clock frequency dispersion. + STM32H5xx devices provide the capability to measure the LSI clock + frequency (LSI clock is internally connected to TIM16 CH1 input capture). + The measured value can be used to have an IWDG timeout with an + acceptable accuracy. + + [..] Default timeout value (necessary for IWDG_SR status register update): + Constant LSI_VALUE is defined based on the nominal LSI clock frequency. + This frequency being subject to variations as mentioned above, the + default timeout value (defined through constant HAL_IWDG_DEFAULT_TIMEOUT + below) may become too short or too long. + In such cases, this default timeout value can be tuned by redefining + the constant LSI_VALUE at user-application level (based, for instance, + on the measured LSI clock frequency as explained above). + + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Register callback to treat Iwdg interrupt and MspInit using HAL_IWDG_RegisterCallback(). + (++) Provide exiting handle as first parameter. + (++) Provide which callback will be registered using one value from + HAL_IWDG_CallbackIDTypeDef. + (++) Provide callback function pointer. + + (#) Use IWDG using HAL_IWDG_Init() function to : + (++) Enable instance by writing Start keyword in IWDG_KEY register. LSI + clock is forced ON and IWDG counter starts counting down. + (++) Enable write access to configuration registers: + IWDG_PR, IWDG_RLR, IWDG_WINR and EWCR. + (++) Configure the IWDG prescaler and counter reload value. This reload + value will be loaded in the IWDG counter each time the watchdog is + reloaded, then the IWDG will start counting down from this value. + (++) Depending on window parameter: + (+++) If Window Init parameter is same as Window register value, + nothing more is done but reload counter value in order to exit + function with exact time base. + (+++) Else modify Window register. This will automatically reload + watchdog counter. + (++) Depending on Early Wakeup Interrupt parameter: + (+++) If EWI is set to disable, comparator is set to 0, interrupt is + disable & flag is clear. + (+++) Else modify EWCR register, setting comparator value, enable + interrupt & clear flag. + (++) Wait for status flags to be reset. + + (#) Then the application program must refresh the IWDG counter at regular + intervals during normal operation to prevent an MCU reset, using + HAL_IWDG_Refresh() function. + + *** IWDG HAL driver macros list *** + ==================================== + [..] + Below the list of most used macros in IWDG HAL driver: + (+) __HAL_IWDG_START: Enable the IWDG peripheral + (+) __HAL_IWDG_RELOAD_COUNTER: Reloads IWDG counter with value defined in + the reload register + + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +#ifdef HAL_IWDG_MODULE_ENABLED +/** @addtogroup IWDG + * @brief IWDG HAL module driver. + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup IWDG_Private_Defines IWDG Private Defines + * @{ + */ +/* Status register needs up to 5 LSI clock periods to be updated. However a + synchronisation is added on prescaled LSI clock rising edge, so we only + consider a highest prescaler cycle. + The timeout value is calculated using the highest prescaler (1024) and + the LSI_VALUE constant. The value of this constant can be changed by the user + to take into account possible LSI clock period variations. + The timeout value is multiplied by 1000 to be converted in milliseconds. + LSI startup time is also considered here by adding LSI_STARTUP_TIME + converted in milliseconds. */ +#define HAL_IWDG_DEFAULT_TIMEOUT (((1UL * 1024UL * 1000UL) / LSI_VALUE) + ((LSI_STARTUP_TIME / 1000UL) + 1UL)) +#define IWDG_KERNEL_UPDATE_FLAGS (IWDG_SR_EWU | IWDG_SR_WVU | IWDG_SR_RVU | IWDG_SR_PVU) +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup IWDG_Exported_Functions + * @{ + */ + +/** @addtogroup IWDG_Exported_Functions_Group1 + * @brief Initialization and Start functions. + * +@verbatim + =============================================================================== + ##### Initialization and Start functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Initialize the IWDG according to the specified parameters in the + IWDG_InitTypeDef of associated handle. + (+) Manage Window option. + (+) Once initialization is performed in HAL_IWDG_Init function, Watchdog + is reloaded in order to exit function with correct time base. + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the IWDG according to the specified parameters in the + * IWDG_InitTypeDef and start watchdog. Before exiting function, + * watchdog is refreshed in order to have correct time base. + * @param hiwdg pointer to a IWDG_HandleTypeDef structure that contains + * the configuration information for the specified IWDG module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg) +{ + uint32_t tickstart; + + /* Check the IWDG handle allocation */ + if (hiwdg == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_IWDG_ALL_INSTANCE(hiwdg->Instance)); + assert_param(IS_IWDG_PRESCALER(hiwdg->Init.Prescaler)); + assert_param(IS_IWDG_RELOAD(hiwdg->Init.Reload)); + assert_param(IS_IWDG_WINDOW(hiwdg->Init.Window)); + assert_param(IS_IWDG_EWI(hiwdg->Init.EWI)); + +#if (USE_HAL_IWDG_REGISTER_CALLBACKS == 1) + /* Reset Callback pointers */ + if (hiwdg->EwiCallback == NULL) + { + hiwdg->EwiCallback = HAL_IWDG_EarlyWakeupCallback; + } + if (hiwdg->MspInitCallback == NULL) + { + hiwdg->MspInitCallback = HAL_IWDG_MspInit; + } + + /* Init the low level hardware */ + hiwdg->MspInitCallback(hiwdg); +#else + /* Init the low level hardware */ + HAL_IWDG_MspInit(hiwdg); +#endif /* USE_HAL_IWDG_REGISTER_CALLBACKS */ + + /* Enable IWDG. LSI is turned on automatically */ + __HAL_IWDG_START(hiwdg); + + /* Enable write access to IWDG_PR, IWDG_RLR, IWDG_WINR and EWCR registers by writing + 0x5555 in KR */ + IWDG_ENABLE_WRITE_ACCESS(hiwdg); + + /* Write to IWDG registers the Prescaler & Reload values to work with */ + hiwdg->Instance->PR = hiwdg->Init.Prescaler; + hiwdg->Instance->RLR = hiwdg->Init.Reload; + + /* Check Reload update flag, before performing any reload of the counter, else previous value + will be taken. */ + tickstart = HAL_GetTick(); + + /* Wait for register to be updated */ + while ((hiwdg->Instance->SR & IWDG_SR_RVU) != 0x00u) + { + if ((HAL_GetTick() - tickstart) > HAL_IWDG_DEFAULT_TIMEOUT) + { + if ((hiwdg->Instance->SR & IWDG_SR_RVU) != 0x00u) + { + return HAL_TIMEOUT; + } + } + } + + if (hiwdg->Init.EWI == IWDG_EWI_DISABLE) + { + /* EWI comparator value equal 0, disable the early wakeup interrupt + * acknowledge the early wakeup interrupt in any cases. it clears the EWIF flag in SR register + * Set Watchdog Early Wakeup Comparator to 0x00 */ + hiwdg->Instance->EWCR = IWDG_EWCR_EWIC; + } + else + { + /* EWI comparator value different from 0, enable the early wakeup interrupt, + * acknowledge the early wakeup interrupt in any cases. it clears the EWIF flag in SR register + * Set Watchdog Early Wakeup Comparator value */ + hiwdg->Instance->EWCR = IWDG_EWCR_EWIE | IWDG_EWCR_EWIC | hiwdg->Init.EWI; + } + + /* Check pending flag, if previous update not done, return timeout */ + tickstart = HAL_GetTick(); + + /* Wait for register to be updated */ + while ((hiwdg->Instance->SR & IWDG_KERNEL_UPDATE_FLAGS) != 0x00u) + { + if ((HAL_GetTick() - tickstart) > HAL_IWDG_DEFAULT_TIMEOUT) + { + if ((hiwdg->Instance->SR & IWDG_KERNEL_UPDATE_FLAGS) != 0x00u) + { + return HAL_TIMEOUT; + } + } + } + + /* If window parameter is different than current value, modify window + register */ + if (hiwdg->Instance->WINR != hiwdg->Init.Window) + { + /* Write to IWDG WINR the IWDG_Window value to compare with. In any case, + even if window feature is disabled, Watchdog will be reloaded by writing + windows register */ + hiwdg->Instance->WINR = hiwdg->Init.Window; + } + else + { + /* Reload IWDG counter with value defined in the reload register */ + __HAL_IWDG_RELOAD_COUNTER(hiwdg); + } + + /* Return function status */ + return HAL_OK; +} + + +/** + * @brief Initialize the IWDG MSP. + * @param hiwdg pointer to a IWDG_HandleTypeDef structure that contains + * the configuration information for the specified IWDG module. + * @note When rewriting this function in user file, mechanism may be added + * to avoid multiple initialize when HAL_IWDG_Init function is called + * again to change parameters. + * @retval None + */ +__weak void HAL_IWDG_MspInit(IWDG_HandleTypeDef *hiwdg) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hiwdg); + + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_IWDG_MspInit could be implemented in the user file + */ +} + + +#if (USE_HAL_IWDG_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User IWDG Callback + * To be used instead of the weak (surcharged) predefined callback + * @param hiwdg IWDG handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_IWDG_EWI_CB_ID Early WakeUp Interrupt Callback ID + * @arg @ref HAL_IWDG_MSPINIT_CB_ID MspInit callback ID + * @param pCallback pointer to the Callback function + * @retval status + */ +HAL_StatusTypeDef HAL_IWDG_RegisterCallback(IWDG_HandleTypeDef *hiwdg, HAL_IWDG_CallbackIDTypeDef CallbackID, + pIWDG_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + status = HAL_ERROR; + } + else + { + switch (CallbackID) + { + case HAL_IWDG_EWI_CB_ID: + hiwdg->EwiCallback = pCallback; + break; + case HAL_IWDG_MSPINIT_CB_ID: + hiwdg->MspInitCallback = pCallback; + break; + + default: + status = HAL_ERROR; + break; + } + } + + return status; +} + + +/** + * @brief Unregister a IWDG Callback + * IWDG Callback is redirected to the weak (surcharged) predefined callback + * @param hiwdg IWDG handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_IWDG_EWI_CB_ID Early WakeUp Interrupt Callback ID + * @arg @ref HAL_IWDG_MSPINIT_CB_ID MspInit callback ID + * @retval status + */ +HAL_StatusTypeDef HAL_IWDG_UnRegisterCallback(IWDG_HandleTypeDef *hiwdg, HAL_IWDG_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + switch (CallbackID) + { + case HAL_IWDG_EWI_CB_ID: + hiwdg->EwiCallback = HAL_IWDG_EarlyWakeupCallback; + break; + case HAL_IWDG_MSPINIT_CB_ID: + hiwdg->MspInitCallback = HAL_IWDG_MspInit; + break; + + default: + status = HAL_ERROR; + break; + } + + return status; +} +#endif /* USE_HAL_IWDG_REGISTER_CALLBACKS */ + + +/** + * @} + */ + + +/** @addtogroup IWDG_Exported_Functions_Group2 + * @brief IO operation functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Refresh the IWDG. + +@endverbatim + * @{ + */ + +/** + * @brief Refresh the IWDG. + * @param hiwdg pointer to a IWDG_HandleTypeDef structure that contains + * the configuration information for the specified IWDG module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg) +{ + /* Reload IWDG counter with value defined in the reload register */ + __HAL_IWDG_RELOAD_COUNTER(hiwdg); + + /* Return function status */ + return HAL_OK; +} + + +/** + * @brief Get back IWDG running status + * @note This API allows to know if IWDG has been started by other master, thread + * or by hardware. + * @param hiwdg pointer to a IWDG_HandleTypeDef structure that contains + * the configuration information for the specified IWDG module. + * @retval can be one of following value : + * @arg @ref IWDG_STATUS_DISABLE + * @arg @ref IWDG_STATUS_ENABLE + */ +uint32_t HAL_IWDG_GetActiveStatus(const IWDG_HandleTypeDef *hiwdg) +{ + uint32_t status; + + /* Get back ONF flag */ + status = (hiwdg->Instance->SR & IWDG_SR_ONF); + + /* Return status */ + return status; +} + + +/** + * @brief Handle IWDG interrupt request. + * @note The Early Wakeup Interrupt (EWI) can be used if specific safety operations + * or data logging must be performed before the actual reset is generated. + * The EWI interrupt is enabled by calling HAL_IWDG_Init function with + * EWIMode set to IWDG_EWI_ENABLE. + * When the downcounter reaches the value 0x40, and EWI interrupt is + * generated and the corresponding Interrupt Service Routine (ISR) can + * be used to trigger specific actions (such as communications or data + * logging), before resetting the device. + * @param hiwdg pointer to a IWDG_HandleTypeDef structure that contains + * the configuration information for the specified IWDG module. + * @retval None + */ +void HAL_IWDG_IRQHandler(IWDG_HandleTypeDef *hiwdg) +{ + /* Check if IWDG Early Wakeup Interrupt occurred */ + if ((hiwdg->Instance->SR & IWDG_SR_EWIF) != 0x00u) + { + /* Clear the IWDG Early Wakeup flag */ + hiwdg->Instance->EWCR |= IWDG_EWCR_EWIC; + +#if (USE_HAL_IWDG_REGISTER_CALLBACKS == 1) + /* Early Wakeup registered callback */ + hiwdg->EwiCallback(hiwdg); +#else + /* Early Wakeup callback */ + HAL_IWDG_EarlyWakeupCallback(hiwdg); +#endif /* USE_HAL_IWDG_REGISTER_CALLBACKS */ + } +} + + +/** + * @brief IWDG Early Wakeup callback. + * @param hiwdg pointer to a IWDG_HandleTypeDef structure that contains + * the configuration information for the specified IWDG module. + * @retval None + */ +__weak void HAL_IWDG_EarlyWakeupCallback(IWDG_HandleTypeDef *hiwdg) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hiwdg); + + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_IWDG_EarlyWakeupCallback could be implemented in the user file + */ +} + + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_IWDG_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_lptim.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_lptim.c new file mode 100644 index 0000000000..6ff4680438 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_lptim.c @@ -0,0 +1,3747 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_lptim.c + * @author MCD Application Team + * @brief LPTIM HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Low Power Timer (LPTIM) peripheral: + * + Initialization and de-initialization functions. + * + Start/Stop operation functions in polling mode. + * + Start/Stop operation functions in interrupt mode. + * + Reading operation functions. + * + Peripheral State functions. + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The LPTIM HAL driver can be used as follows: + + (#)Initialize the LPTIM low level resources by implementing the + HAL_LPTIM_MspInit(): + (++) Enable the LPTIM interface clock using __HAL_RCC_LPTIMx_CLK_ENABLE(). + (++) In case of using interrupts (e.g. HAL_LPTIM_PWM_Start_IT()): + (+++) Configure the LPTIM interrupt priority using HAL_NVIC_SetPriority(). + (+++) Enable the LPTIM IRQ handler using HAL_NVIC_EnableIRQ(). + (+++) In LPTIM IRQ handler, call HAL_LPTIM_IRQHandler(). + + (#)Initialize the LPTIM HAL using HAL_LPTIM_Init(). This function + configures mainly: + (++) The instance: LPTIM1, LPTIM2, LPTIM3, LPTIM4, LPTIM5 or LPTIM6. + (++) Clock: the counter clock. + (+++) Source : it can be either the ULPTIM input (IN1) or one of + the internal clock; (APB, LSE, LSI or CSI). + (+++) Prescaler: select the clock divider. + (++) UltraLowPowerClock : To be used only if the ULPTIM is selected + as counter clock source. + (+++) Polarity: polarity of the active edge for the counter unit + if the ULPTIM input is selected. + (+++) SampleTime: clock sampling time to configure the clock glitch + filter. + (++) Trigger: How the counter start. + (+++) Source: trigger can be software or one of the hardware triggers. + (+++) ActiveEdge : only for hardware trigger. + (+++) SampleTime : trigger sampling time to configure the trigger + glitch filter. + (++) OutputPolarity : 2 opposite polarities are possible. + (++) UpdateMode: specifies whether the update of the autoreload and + the compare values is done immediately or after the end of current + period. + (++) Input1Source: Source selected for input1 (GPIO or comparator output). + (++) Input2Source: Source selected for input2 (GPIO or comparator output). + Input2 is used only for encoder feature so is used only for LPTIM1 instance. + + (#)Six modes are available: + + (++) PWM Mode: To generate a PWM signal with specified period and pulse, + call HAL_LPTIM_PWM_Start() or HAL_LPTIM_PWM_Start_IT() for interruption + mode. + + (++) One Pulse Mode: To generate pulse with specified width in response + to a stimulus, call HAL_LPTIM_OnePulse_Start() or + HAL_LPTIM_OnePulse_Start_IT() for interruption mode. + + (++) Set once Mode: In this mode, the output changes the level (from + low level to high level if the output polarity is configured high, else + the opposite) when a compare match occurs. To start this mode, call + HAL_LPTIM_SetOnce_Start() or HAL_LPTIM_SetOnce_Start_IT() for + interruption mode. + + (++) Encoder Mode: To use the encoder interface call + HAL_LPTIM_Encoder_Start() or HAL_LPTIM_Encoder_Start_IT() for + interruption mode. Only available for LPTIM1 instance. + + (++) Time out Mode: an active edge on one selected trigger input rests + the counter. The first trigger event will start the timer, any + successive trigger event will reset the counter and the timer will + restart. To start this mode call HAL_LPTIM_TimeOut_Start_IT() or + HAL_LPTIM_TimeOut_Start_IT() for interruption mode. + + (++) Counter Mode: counter can be used to count external events on + the LPTIM Input1 or it can be used to count internal clock cycles. + To start this mode, call HAL_LPTIM_Counter_Start() or + HAL_LPTIM_Counter_Start_IT() for interruption mode. + + + (#) User can stop any process by calling the corresponding API: + HAL_LPTIM_Xxx_Stop() or HAL_LPTIM_Xxx_Stop_IT() if the process is + already started in interruption mode. + + (#) De-initialize the LPTIM peripheral using HAL_LPTIM_DeInit(). + + *** Callback registration *** + ============================================= + [..] + The compilation define USE_HAL_LPTIM_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + [..] + Use Function HAL_LPTIM_RegisterCallback() to register a callback. + HAL_LPTIM_RegisterCallback() takes as parameters the HAL peripheral handle, + the Callback ID and a pointer to the user callback function. + [..] + Use function HAL_LPTIM_UnRegisterCallback() to reset a callback to the + default weak function. + HAL_LPTIM_UnRegisterCallback takes as parameters the HAL peripheral handle, + and the Callback ID. + [..] + These functions allow to register/unregister following callbacks: + + (+) MspInitCallback : LPTIM Base Msp Init Callback. + (+) MspDeInitCallback : LPTIM Base Msp DeInit Callback. + (+) CompareMatchCallback : Compare match Callback. + (+) AutoReloadMatchCallback : Auto-reload match Callback. + (+) TriggerCallback : External trigger event detection Callback. + (+) CompareWriteCallback : Compare register write complete Callback. + (+) AutoReloadWriteCallback : Auto-reload register write complete Callback. + (+) DirectionUpCallback : Up-counting direction change Callback. + (+) DirectionDownCallback : Down-counting direction change Callback. + (+) UpdateEventCallback : Update event detection Callback. + (+) RepCounterWriteCallback : Repetition counter register write complete Callback. + + [..] + By default, after the Init and when the state is HAL_LPTIM_STATE_RESET + all interrupt callbacks are set to the corresponding weak functions: + examples HAL_LPTIM_TriggerCallback(), HAL_LPTIM_CompareMatchCallback(). + + [..] + Exception done for MspInit and MspDeInit functions that are reset to the legacy weak + functionalities in the Init/DeInit only when these callbacks are null + (not registered beforehand). If not, MspInit or MspDeInit are not null, the Init/DeInit + keep and use the user MspInit/MspDeInit callbacks (registered beforehand) + + [..] + Callbacks can be registered/unregistered in HAL_LPTIM_STATE_READY state only. + Exception done MspInit/MspDeInit that can be registered/unregistered + in HAL_LPTIM_STATE_READY or HAL_LPTIM_STATE_RESET state, + thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. + In that case first register the MspInit/MspDeInit user callbacks + using HAL_LPTIM_RegisterCallback() before calling DeInit or Init function. + + [..] + When The compilation define USE_HAL_LPTIM_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 "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup LPTIM LPTIM + * @brief LPTIM HAL module driver. + * @{ + */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + +#if defined (LPTIM1) || defined (LPTIM2) || defined (LPTIM3) || defined (LPTIM4) || defined (LPTIM5) || defined (LPTIM6) + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup LPTIM_Private_Constants + * @{ + */ +#define TIMEOUT 1000UL /* Timeout is 1s */ +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +static HAL_StatusTypeDef LPTIM_OC1_SetConfig(LPTIM_HandleTypeDef *hlptim, const LPTIM_OC_ConfigTypeDef *sConfig); +static HAL_StatusTypeDef LPTIM_OC2_SetConfig(LPTIM_HandleTypeDef *hlptim, const LPTIM_OC_ConfigTypeDef *sConfig); +static void LPTIM_IC1_SetConfig(LPTIM_HandleTypeDef *hlptim, const LPTIM_IC_ConfigTypeDef *sConfig); +static void LPTIM_IC2_SetConfig(LPTIM_HandleTypeDef *hlptim, const LPTIM_IC_ConfigTypeDef *sConfig); +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) +static void LPTIM_ResetCallback(LPTIM_HandleTypeDef *lptim); +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ +static HAL_StatusTypeDef LPTIM_WaitForFlag(const LPTIM_HandleTypeDef *hlptim, uint32_t flag); +void LPTIM_DMAError(DMA_HandleTypeDef *hdma); +void LPTIM_DMACaptureCplt(DMA_HandleTypeDef *hdma); +void LPTIM_DMACaptureHalfCplt(DMA_HandleTypeDef *hdma); +void LPTIM_DMAUpdateEventCplt(DMA_HandleTypeDef *hdma); +void LPTIM_DMAUpdateEventHalfCplt(DMA_HandleTypeDef *hdma); +HAL_StatusTypeDef LPTIM_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t src, uint32_t dst, + uint32_t length); + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup LPTIM_Exported_Functions LPTIM Exported Functions + * @{ + */ + +/** @defgroup LPTIM_Exported_Functions_Group1 Initialization/de-initialization functions + * @brief Initialization and Configuration functions. + * +@verbatim + ============================================================================== + ##### Initialization and de-initialization functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) Initialize the LPTIM according to the specified parameters in the + LPTIM_InitTypeDef and initialize the associated handle. + (+) DeInitialize the LPTIM peripheral. + (+) Initialize the LPTIM MSP. + (+) DeInitialize the LPTIM MSP. + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the LPTIM according to the specified parameters in the + * LPTIM_InitTypeDef and initialize the associated handle. + * @param hlptim LPTIM handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_Init(LPTIM_HandleTypeDef *hlptim) +{ + uint32_t tmpcfgr; + + /* Check the LPTIM handle allocation */ + if (hlptim == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_LPTIM_INSTANCE(hlptim->Instance)); + assert_param(IS_LPTIM_PERIOD(hlptim->Init.Period)); + + assert_param(IS_LPTIM_CLOCK_SOURCE(hlptim->Init.Clock.Source)); + assert_param(IS_LPTIM_CLOCK_PRESCALER(hlptim->Init.Clock.Prescaler)); + if ((hlptim->Init.Clock.Source == LPTIM_CLOCKSOURCE_ULPTIM) + || (hlptim->Init.CounterSource == LPTIM_COUNTERSOURCE_EXTERNAL)) + { + assert_param(IS_LPTIM_CLOCK_POLARITY(hlptim->Init.UltraLowPowerClock.Polarity)); + assert_param(IS_LPTIM_CLOCK_SAMPLE_TIME(hlptim->Init.UltraLowPowerClock.SampleTime)); + } + assert_param(IS_LPTIM_TRG_SOURCE(hlptim->Init.Trigger.Source)); + if (hlptim->Init.Trigger.Source != LPTIM_TRIGSOURCE_SOFTWARE) + { + assert_param(IS_LPTIM_EXT_TRG_POLARITY(hlptim->Init.Trigger.ActiveEdge)); + assert_param(IS_LPTIM_TRIG_SAMPLE_TIME(hlptim->Init.Trigger.SampleTime)); + } + assert_param(IS_LPTIM_UPDATE_MODE(hlptim->Init.UpdateMode)); + assert_param(IS_LPTIM_COUNTER_SOURCE(hlptim->Init.CounterSource)); + assert_param(IS_LPTIM_REPETITION(hlptim->Init.RepetitionCounter)); + + if (hlptim->State == HAL_LPTIM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hlptim->Lock = HAL_UNLOCKED; + +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) + /* Reset interrupt callbacks to legacy weak callbacks */ + LPTIM_ResetCallback(hlptim); + + if (hlptim->MspInitCallback == NULL) + { + hlptim->MspInitCallback = HAL_LPTIM_MspInit; + } + + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + hlptim->MspInitCallback(hlptim); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + HAL_LPTIM_MspInit(hlptim); +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ + } + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Enable the Peripheral */ + __HAL_LPTIM_ENABLE(hlptim); + + /* Clear flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_REPOK); + + /* Set the repetition counter */ + __HAL_LPTIM_REPETITIONCOUNTER_SET(hlptim, hlptim->Init.RepetitionCounter); + + /* Wait for the completion of the write operation to the LPTIM_RCR register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_REPOK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + + + /* Clear flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_ARROK); + + /* Set LPTIM Period */ + __HAL_LPTIM_AUTORELOAD_SET(hlptim, hlptim->Init.Period); + + /* Wait for the completion of the write operation to the LPTIM_ARR register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_ARROK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + + /* Disable the Peripheral */ + __HAL_LPTIM_DISABLE(hlptim); + + /* Get the LPTIMx CFGR value */ + tmpcfgr = hlptim->Instance->CFGR; + + if ((hlptim->Init.Clock.Source == LPTIM_CLOCKSOURCE_ULPTIM) + || (hlptim->Init.CounterSource == LPTIM_COUNTERSOURCE_EXTERNAL)) + { + tmpcfgr &= (uint32_t)(~(LPTIM_CFGR_CKPOL | LPTIM_CFGR_CKFLT)); + } + if (hlptim->Init.Trigger.Source != LPTIM_TRIGSOURCE_SOFTWARE) + { + tmpcfgr &= (uint32_t)(~(LPTIM_CFGR_TRGFLT | LPTIM_CFGR_TRIGSEL)); + } + + /* Clear CKSEL, PRESC, TRIGEN, TRGFLT, WAVPOL, PRELOAD & COUNTMODE bits */ + tmpcfgr &= (uint32_t)(~(LPTIM_CFGR_CKSEL | LPTIM_CFGR_TRIGEN | LPTIM_CFGR_PRELOAD | + LPTIM_CFGR_PRESC | LPTIM_CFGR_COUNTMODE)); + + /* Set initialization parameters */ + tmpcfgr |= (hlptim->Init.Clock.Source | + hlptim->Init.Clock.Prescaler | + hlptim->Init.UpdateMode | + hlptim->Init.CounterSource); + + /* Glitch filters for internal triggers and external inputs are configured + * only if an internal clock source is provided to the LPTIM + */ + if (hlptim->Init.Clock.Source == LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC) + { + tmpcfgr |= (hlptim->Init.Trigger.SampleTime | + hlptim->Init.UltraLowPowerClock.SampleTime); + } + + /* Configure LPTIM external clock polarity and digital filter */ + if ((hlptim->Init.Clock.Source == LPTIM_CLOCKSOURCE_ULPTIM) + || (hlptim->Init.CounterSource == LPTIM_COUNTERSOURCE_EXTERNAL)) + { + tmpcfgr |= (hlptim->Init.UltraLowPowerClock.Polarity | + hlptim->Init.UltraLowPowerClock.SampleTime); + } + + /* Configure LPTIM external trigger */ + if (hlptim->Init.Trigger.Source != LPTIM_TRIGSOURCE_SOFTWARE) + { + /* Enable External trigger and set the trigger source */ + tmpcfgr |= (hlptim->Init.Trigger.Source | + hlptim->Init.Trigger.ActiveEdge | + hlptim->Init.Trigger.SampleTime); + } + + /* Write to LPTIMx CFGR */ + hlptim->Instance->CFGR = tmpcfgr; + + /* Configure LPTIM input sources */ + if ((hlptim->Instance == LPTIM1) || (hlptim->Instance == LPTIM2)) + { + /* Check LPTIM Input1 and Input2 sources */ + assert_param(IS_LPTIM_INPUT1_SOURCE(hlptim->Instance, hlptim->Init.Input1Source)); + assert_param(IS_LPTIM_INPUT2_SOURCE(hlptim->Instance, hlptim->Init.Input2Source)); + + /* Configure LPTIM Input1 and Input2 sources */ + hlptim->Instance->CFGR2 = (hlptim->Init.Input1Source | hlptim->Init.Input2Source); + } + else + { + /* Check LPTIM2 Input1 source */ + assert_param(IS_LPTIM_INPUT1_SOURCE(hlptim->Instance, hlptim->Init.Input1Source)); + + /* Configure LPTIM2 Input1 source */ + hlptim->Instance->CFGR2 = hlptim->Init.Input1Source; + } + + /* Initialize the LPTIM channels state */ + LPTIM_CHANNEL_STATE_SET_ALL(hlptim, HAL_LPTIM_CHANNEL_STATE_READY); + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief DeInitialize the LPTIM peripheral. + * @param hlptim LPTIM handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_DeInit(LPTIM_HandleTypeDef *hlptim) +{ + /* Check the LPTIM handle allocation */ + if (hlptim == NULL) + { + return HAL_ERROR; + } + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + __HAL_LPTIM_ENABLE(hlptim); + if (IS_LPTIM_CC2_INSTANCE(hlptim->Instance)) + { + hlptim->Instance->CCMR1 = 0; + } + + /* Clear flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_CMP1OK); + + __HAL_LPTIM_COMPARE_SET(hlptim, LPTIM_CHANNEL_1, 0); + /* Wait for the completion of the write operation to the LPTIM_CCR1 register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_CMP1OK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + + if (IS_LPTIM_CC2_INSTANCE(hlptim->Instance)) + { + /* Clear flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_CMP2OK); + + __HAL_LPTIM_COMPARE_SET(hlptim, LPTIM_CHANNEL_2, 0); + /* Wait for the completion of the write operation to the LPTIM_CCR2 register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_CMP2OK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + } + + /* Clear flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_ARROK); + + __HAL_LPTIM_AUTORELOAD_SET(hlptim, 0); + + /* Wait for the completion of the write operation to the LPTIM_ARR register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_ARROK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + + /* Disable the LPTIM Peripheral Clock */ + __HAL_LPTIM_DISABLE(hlptim); + + hlptim->Instance->CFGR = 0; + hlptim->Instance->CFGR2 = 0; + +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) + if (hlptim->MspDeInitCallback == NULL) + { + hlptim->MspDeInitCallback = HAL_LPTIM_MspDeInit; + } + + /* DeInit the low level hardware: CLOCK, NVIC.*/ + hlptim->MspDeInitCallback(hlptim); +#else + /* DeInit the low level hardware: CLOCK, NVIC.*/ + HAL_LPTIM_MspDeInit(hlptim); +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ + + /* Change the LPTIM channels state */ + LPTIM_CHANNEL_STATE_SET_ALL(hlptim, HAL_LPTIM_CHANNEL_STATE_RESET); + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hlptim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initialize the LPTIM MSP. + * @param hlptim LPTIM handle + * @retval None + */ +__weak void HAL_LPTIM_MspInit(LPTIM_HandleTypeDef *hlptim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hlptim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_LPTIM_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitialize LPTIM MSP. + * @param hlptim LPTIM handle + * @retval None + */ +__weak void HAL_LPTIM_MspDeInit(LPTIM_HandleTypeDef *hlptim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hlptim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_LPTIM_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup LPTIM_Exported_Functions_Group2 LPTIM Start-Stop operation functions + * @brief Start-Stop operation functions. + * +@verbatim + ============================================================================== + ##### LPTIM Start Stop operation functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) Start the PWM mode. + (+) Stop the PWM mode. + (+) Start the One pulse mode. + (+) Stop the One pulse mode. + (+) Start the Set once mode. + (+) Stop the Set once mode. + (+) Start the Encoder mode. + (+) Stop the Encoder mode. + (+) Start the Timeout mode. + (+) Stop the Timeout mode. + (+) Start the Counter mode. + (+) Stop the Counter mode. + + +@endverbatim + * @{ + */ + +/** + * @brief Start the LPTIM PWM generation. + * @param hlptim LPTIM handle + * @param Channel LPTIM Channel to be enabled + * This parameter can be one of the following values: + * @arg LPTIM_CHANNEL_1: LPTIM Channel 1 selected + * @arg LPTIM_CHANNEL_2: LPTIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_PWM_Start(LPTIM_HandleTypeDef *hlptim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_CCX_INSTANCE(hlptim->Instance, Channel)); + + /* Check LPTIM channel state */ + if (LPTIM_CHANNEL_STATE_GET(hlptim, Channel) != HAL_LPTIM_CHANNEL_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Set the LPTIM channel state */ + LPTIM_CHANNEL_STATE_SET(hlptim, Channel, HAL_LPTIM_CHANNEL_STATE_BUSY); + + /* Reset WAVE bit to set PWM mode */ + hlptim->Instance->CFGR &= ~LPTIM_CFGR_WAVE; + + /* Enable the Peripheral */ + __HAL_LPTIM_ENABLE(hlptim); + + /* Enable LPTIM signal on the corresponding output pin */ + __HAL_LPTIM_CAPTURE_COMPARE_ENABLE(hlptim, Channel); + + /* Start timer in continuous mode */ + __HAL_LPTIM_START_CONTINUOUS(hlptim); + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stop the LPTIM PWM generation. + * @param hlptim LPTIM handle + * @param Channel LPTIM Channel to be disabled + * This parameter can be one of the following values: + * @arg LPTIM_CHANNEL_1: LPTIM Channel 1 selected + * @arg LPTIM_CHANNEL_2: LPTIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_PWM_Stop(LPTIM_HandleTypeDef *hlptim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_CCX_INSTANCE(hlptim->Instance, Channel)); + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Disable LPTIM signal from the corresponding output pin */ + __HAL_LPTIM_CAPTURE_COMPARE_DISABLE(hlptim, Channel); + + /* Disable the Peripheral */ + __HAL_LPTIM_DISABLE(hlptim); + + /* Set the LPTIM channel state */ + LPTIM_CHANNEL_STATE_SET(hlptim, Channel, HAL_LPTIM_CHANNEL_STATE_READY); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Start the LPTIM PWM generation in interrupt mode. + * @param hlptim LPTIM handle + * @param Channel LPTIM Channel to be enabled + * This parameter can be one of the following values: + * @arg LPTIM_CHANNEL_1: LPTIM Channel 1 selected + * @arg LPTIM_CHANNEL_2: LPTIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_PWM_Start_IT(LPTIM_HandleTypeDef *hlptim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_CCX_INSTANCE(hlptim->Instance, Channel)); + + /* Check LPTIM channel state */ + if (LPTIM_CHANNEL_STATE_GET(hlptim, Channel) != HAL_LPTIM_CHANNEL_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Set the LPTIM channel state */ + LPTIM_CHANNEL_STATE_SET(hlptim, Channel, HAL_LPTIM_CHANNEL_STATE_BUSY); + + /* Reset WAVE bit to set PWM mode */ + hlptim->Instance->CFGR &= ~LPTIM_CFGR_WAVE; + + /* Enable the Peripheral */ + __HAL_LPTIM_ENABLE(hlptim); + /* Clear flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_DIEROK); + + switch (Channel) + { + case LPTIM_CHANNEL_1: + /* Enable interrupt */ + __HAL_LPTIM_ENABLE_IT(hlptim, LPTIM_IT_CMP1OK | LPTIM_IT_CC1 | LPTIM_IT_ARROK | LPTIM_IT_ARRM | LPTIM_IT_REPOK | + LPTIM_IT_UPDATE); + break; + case LPTIM_CHANNEL_2: + /* Enable interrupt */ + __HAL_LPTIM_ENABLE_IT(hlptim, LPTIM_IT_CMP2OK | LPTIM_IT_CC2 | LPTIM_IT_ARROK | LPTIM_IT_ARRM | LPTIM_IT_REPOK | + LPTIM_IT_UPDATE); + break; + default: + break; + } + + /* Wait for the completion of the write operation to the LPTIM_DIER register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_DIEROK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + + /* If external trigger source is used, then enable external trigger interrupt */ + if ((hlptim->Init.Trigger.Source) != LPTIM_TRIGSOURCE_SOFTWARE) + { + /* Clear flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_DIEROK); + + /* Enable external trigger interrupt */ + __HAL_LPTIM_ENABLE_IT(hlptim, LPTIM_IT_EXTTRIG); + + /* Wait for the completion of the write operation to the LPTIM_DIER register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_DIEROK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + } + + __HAL_LPTIM_CAPTURE_COMPARE_ENABLE(hlptim, Channel); + + /* Start timer in continuous mode */ + __HAL_LPTIM_START_CONTINUOUS(hlptim); + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stop the LPTIM PWM generation in interrupt mode. + * @param hlptim LPTIM handle + * @param Channel LPTIM Channel to be disabled + * This parameter can be one of the following values: + * @arg LPTIM_CHANNEL_1: LPTIM Channel 1 selected + * @arg LPTIM_CHANNEL_2: LPTIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_PWM_Stop_IT(LPTIM_HandleTypeDef *hlptim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_CCX_INSTANCE(hlptim->Instance, Channel)); + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Disable LPTIM signal from the corresponding output pin */ + __HAL_LPTIM_CAPTURE_COMPARE_DISABLE(hlptim, Channel); + + /* Disable the Peripheral */ + __HAL_LPTIM_DISABLE(hlptim); + + /* Enable the Peripheral */ + __HAL_LPTIM_ENABLE(hlptim); + + /* Clear flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_DIEROK); + + switch (Channel) + { + case LPTIM_CHANNEL_1: + /* Disable interrupt */ + __HAL_LPTIM_DISABLE_IT(hlptim, LPTIM_IT_CMP1OK | LPTIM_IT_CC1 | LPTIM_IT_ARROK | LPTIM_IT_ARRM | LPTIM_IT_REPOK | + LPTIM_IT_UPDATE); + break; + case LPTIM_CHANNEL_2: + /* Disable interrupt */ + __HAL_LPTIM_DISABLE_IT(hlptim, LPTIM_IT_CMP2OK | LPTIM_IT_CC2 | LPTIM_IT_ARROK | LPTIM_IT_ARRM | LPTIM_IT_REPOK | + LPTIM_IT_UPDATE); + break; + default: + break; + } + + /* Wait for the completion of the write operation to the LPTIM_DIER register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_DIEROK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + + /* If external trigger source is used, then enable external trigger interrupt */ + if ((hlptim->Init.Trigger.Source) != LPTIM_TRIGSOURCE_SOFTWARE) + { + /* Clear flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_DIEROK); + + /* Enable external trigger interrupt */ + __HAL_LPTIM_DISABLE_IT(hlptim, LPTIM_IT_EXTTRIG); + + /* Wait for the completion of the write operation to the LPTIM_DIER register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_DIEROK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + } + + /* Disable the Peripheral */ + __HAL_LPTIM_DISABLE(hlptim); + + /* Set the LPTIM channel state */ + LPTIM_CHANNEL_STATE_SET(hlptim, Channel, HAL_LPTIM_CHANNEL_STATE_READY); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Start the LPTIM PWM generation in DMA mode. + * @param hlptim LPTIM handle + * @param Channel LPTIM Channel to be enabled + * This parameter can be one of the following values: + * @arg LPTIM_CHANNEL_1: LPTIM Channel 1 selected + * @arg LPTIM_CHANNEL_2: LPTIM Channel 2 selected + * @param pData The destination Buffer address + * @param Length The length of data to be transferred from LPTIM peripheral to memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_PWM_Start_DMA(LPTIM_HandleTypeDef *hlptim, uint32_t Channel, const uint32_t *pData, + uint32_t Length) +{ + DMA_HandleTypeDef *hdma; + + /* Check the parameters */ + assert_param(IS_LPTIM_DMA_INSTANCE(hlptim->Instance)); + assert_param(IS_LPTIM_CCX_INSTANCE(hlptim->Instance, Channel)); + + if ((pData == NULL) || (Length == 0U)) + { + return HAL_ERROR; + } + + /* Check LPTIM channel state */ + if (LPTIM_CHANNEL_STATE_GET(hlptim, Channel) != HAL_LPTIM_CHANNEL_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Set the LPTIM channel state */ + LPTIM_CHANNEL_STATE_SET(hlptim, Channel, HAL_LPTIM_CHANNEL_STATE_BUSY); + + /* Reset WAVE bit to set PWM mode */ + hlptim->Instance->CFGR &= ~LPTIM_CFGR_WAVE; + + /* Enable the Peripheral */ + __HAL_LPTIM_ENABLE(hlptim); + + /* Enable update event DMA request */ + __HAL_LPTIM_ENABLE_DMA(hlptim, LPTIM_DMA_UPDATE); + + /* Wait for the completion of the write operation to the LPTIM_DIER register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_DIEROK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + + switch (Channel) + { + case LPTIM_CHANNEL_1: + /* Set the DMA update event callbacks */ + hlptim->hdma[LPTIM_DMA_ID_CC1]->XferCpltCallback = LPTIM_DMAUpdateEventCplt; + hlptim->hdma[LPTIM_DMA_ID_CC1]->XferHalfCpltCallback = LPTIM_DMAUpdateEventHalfCplt; + + /* Set the DMA error callback */ + hlptim->hdma[LPTIM_DMA_ID_CC1]->XferErrorCallback = LPTIM_DMAError; + + /* Enable the DMA Channel */ + hdma = hlptim->hdma[LPTIM_DMA_ID_CC1]; + if (LPTIM_DMA_Start_IT(hdma, (uint32_t)pData, (uint32_t)&hlptim->Instance->CCR1, Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + break; + case LPTIM_CHANNEL_2: + /* Set the DMA update event callbacks */ + hlptim->hdma[LPTIM_DMA_ID_CC2]->XferCpltCallback = LPTIM_DMAUpdateEventCplt; + hlptim->hdma[LPTIM_DMA_ID_CC2]->XferHalfCpltCallback = LPTIM_DMAUpdateEventHalfCplt; + + /* Set the DMA error callback */ + hlptim->hdma[LPTIM_DMA_ID_CC2]->XferErrorCallback = LPTIM_DMAError; + + /* Enable the DMA Channel */ + hdma = hlptim->hdma[LPTIM_DMA_ID_CC2]; + if (LPTIM_DMA_Start_IT(hdma, (uint32_t)pData, (uint32_t)&hlptim->Instance->CCR2, Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + break; + default: + break; + } + + /* Enable LPTIM signal on the corresponding output pin */ + __HAL_LPTIM_CAPTURE_COMPARE_ENABLE(hlptim, Channel); + + /* Start timer in continuous mode */ + __HAL_LPTIM_START_CONTINUOUS(hlptim); + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stop the LPTIM PWM generation in DMA mode. + * @param hlptim LPTIM handle + * @param Channel LPTIM Channel to be disabled + * This parameter can be one of the following values: + * @arg LPTIM_CHANNEL_1: LPTIM Channel 1 selected + * @arg LPTIM_CHANNEL_2: LPTIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_PWM_Stop_DMA(LPTIM_HandleTypeDef *hlptim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_DMA_INSTANCE(hlptim->Instance)); + assert_param(IS_LPTIM_CCX_INSTANCE(hlptim->Instance, Channel)); + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Disable update event DMA request */ + __HAL_LPTIM_DISABLE_DMA(hlptim, LPTIM_DMA_UPDATE); + + switch (Channel) + { + case LPTIM_CHANNEL_1: + /* Disable update event DMA request */ + (void)HAL_DMA_Abort_IT(hlptim->hdma[LPTIM_DMA_ID_CC1]); + break; + case LPTIM_CHANNEL_2: + /* Disable update event DMA request */ + (void)HAL_DMA_Abort_IT(hlptim->hdma[LPTIM_DMA_ID_CC2]); + break; + default: + break; + } + + /* Disable LPTIM signal from the corresponding output pin */ + __HAL_LPTIM_CAPTURE_COMPARE_DISABLE(hlptim, Channel); + + /* Disable the Peripheral */ + __HAL_LPTIM_DISABLE(hlptim); + + /* Set the LPTIM channel state */ + LPTIM_CHANNEL_STATE_SET(hlptim, Channel, HAL_LPTIM_CHANNEL_STATE_READY); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Start the LPTIM One pulse generation. + * @param hlptim LPTIM handle + * @param Channel LPTIM Channel to be enabled + * This parameter can be one of the following values: + * @arg LPTIM_CHANNEL_1: LPTIM Channel 1 selected + * @arg LPTIM_CHANNEL_2: LPTIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_OnePulse_Start(LPTIM_HandleTypeDef *hlptim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_CCX_INSTANCE(hlptim->Instance, Channel)); + + /* Check LPTIM channel state */ + if (LPTIM_CHANNEL_STATE_GET(hlptim, Channel) != HAL_LPTIM_CHANNEL_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Set the LPTIM channel state */ + LPTIM_CHANNEL_STATE_SET(hlptim, Channel, HAL_LPTIM_CHANNEL_STATE_BUSY); + + /* Reset WAVE bit to set one pulse mode */ + hlptim->Instance->CFGR &= ~LPTIM_CFGR_WAVE; + + /* Enable the Peripheral */ + __HAL_LPTIM_ENABLE(hlptim); + + /* Enable LPTIM signal on the corresponding output pin */ + __HAL_LPTIM_CAPTURE_COMPARE_ENABLE(hlptim, Channel); + + /* Start timer in single (one shot) mode */ + __HAL_LPTIM_START_SINGLE(hlptim); + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stop the LPTIM One pulse generation. + * @param hlptim LPTIM handle + * @param Channel LPTIM Channel to be disabled + * This parameter can be one of the following values: + * @arg LPTIM_CHANNEL_1: LPTIM Channel 1 selected + * @arg LPTIM_CHANNEL_2: LPTIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_OnePulse_Stop(LPTIM_HandleTypeDef *hlptim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_CCX_INSTANCE(hlptim->Instance, Channel)); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Disable LPTIM signal on the corresponding output pin */ + __HAL_LPTIM_CAPTURE_COMPARE_DISABLE(hlptim, Channel); + + /* Disable the Peripheral */ + __HAL_LPTIM_DISABLE(hlptim); + + /* Set the LPTIM channel state */ + LPTIM_CHANNEL_STATE_SET(hlptim, Channel, HAL_LPTIM_CHANNEL_STATE_READY); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Start the LPTIM One pulse generation in interrupt mode. + * @param hlptim LPTIM handle + * @param Channel LPTIM Channel to be enabled + * This parameter can be one of the following values: + * @arg LPTIM_CHANNEL_1: LPTIM Channel 1 selected + * @arg LPTIM_CHANNEL_2: LPTIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_OnePulse_Start_IT(LPTIM_HandleTypeDef *hlptim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_CCX_INSTANCE(hlptim->Instance, Channel)); + + /* Check LPTIM channel state */ + if (LPTIM_CHANNEL_STATE_GET(hlptim, Channel) != HAL_LPTIM_CHANNEL_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Set the LPTIM channel state */ + LPTIM_CHANNEL_STATE_SET(hlptim, Channel, HAL_LPTIM_CHANNEL_STATE_BUSY); + + /* Reset WAVE bit to set one pulse mode */ + hlptim->Instance->CFGR &= ~LPTIM_CFGR_WAVE; + + /* Enable the Peripheral */ + __HAL_LPTIM_ENABLE(hlptim); + + /* Clear flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_DIEROK); + + switch (Channel) + { + case LPTIM_CHANNEL_1: + /* Enable interrupt */ + __HAL_LPTIM_ENABLE_IT(hlptim, LPTIM_IT_CMP1OK | LPTIM_IT_CC1 | LPTIM_IT_ARROK | LPTIM_IT_ARRM | LPTIM_IT_REPOK | + LPTIM_IT_UPDATE); + break; + case LPTIM_CHANNEL_2: + /* Enable interrupt */ + __HAL_LPTIM_ENABLE_IT(hlptim, LPTIM_IT_CMP2OK | LPTIM_IT_CC2 | LPTIM_IT_ARROK | LPTIM_IT_ARRM | LPTIM_IT_REPOK | + LPTIM_IT_UPDATE); + break; + default: + break; + } + + /* Wait for the completion of the write operation to the LPTIM_DIER register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_DIEROK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + + /* If external trigger source is used, then enable external trigger interrupt */ + if ((hlptim->Init.Trigger.Source) != LPTIM_TRIGSOURCE_SOFTWARE) + { + /* Clear flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_DIEROK); + /* Enable external trigger interrupt */ + __HAL_LPTIM_ENABLE_IT(hlptim, LPTIM_IT_EXTTRIG); + /* Wait for the completion of the write operation to the LPTIM_DIER register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_DIEROK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + } + + /* Enable LPTIM signal on the corresponding output pin */ + __HAL_LPTIM_CAPTURE_COMPARE_ENABLE(hlptim, Channel); + + /* Start timer in single (one shot) mode */ + __HAL_LPTIM_START_SINGLE(hlptim); + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stop the LPTIM One pulse generation in interrupt mode. + * @param hlptim LPTIM handle + * @param Channel LPTIM Channel to be disabled + * This parameter can be one of the following values: + * @arg LPTIM_CHANNEL_1: LPTIM Channel 1 selected + * @arg LPTIM_CHANNEL_2: LPTIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_OnePulse_Stop_IT(LPTIM_HandleTypeDef *hlptim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_CCX_INSTANCE(hlptim->Instance, Channel)); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Disable LPTIM signal on the corresponding output pin */ + __HAL_LPTIM_CAPTURE_COMPARE_DISABLE(hlptim, Channel); + + /* Disable the Peripheral */ + __HAL_LPTIM_DISABLE(hlptim); + + + /* Enable the Peripheral */ + __HAL_LPTIM_ENABLE(hlptim); + + /* Clear flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_DIEROK); + + switch (Channel) + { + case LPTIM_CHANNEL_1: + /* Disable interrupt */ + __HAL_LPTIM_DISABLE_IT(hlptim, LPTIM_IT_CMP1OK | LPTIM_IT_CC1 | LPTIM_IT_ARROK | LPTIM_IT_ARRM | LPTIM_IT_REPOK | + LPTIM_IT_UPDATE); + break; + case LPTIM_CHANNEL_2: + /* Disable interrupt */ + __HAL_LPTIM_DISABLE_IT(hlptim, LPTIM_IT_CMP2OK | LPTIM_IT_CC2 | LPTIM_IT_ARROK | LPTIM_IT_ARRM | LPTIM_IT_REPOK | + LPTIM_IT_UPDATE); + break; + default: + break; + } + + /* Wait for the completion of the write operation to the LPTIM_DIER register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_DIEROK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + + /* If external trigger source is used, then enable external trigger interrupt */ + if ((hlptim->Init.Trigger.Source) != LPTIM_TRIGSOURCE_SOFTWARE) + { + /* Clear flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_DIEROK); + /* Enable external trigger interrupt */ + __HAL_LPTIM_DISABLE_IT(hlptim, LPTIM_IT_EXTTRIG); + /* Wait for the completion of the write operation to the LPTIM_DIER register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_DIEROK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + } + + /* Disable the Peripheral */ + __HAL_LPTIM_DISABLE(hlptim); + + /* Set the LPTIM channel state */ + LPTIM_CHANNEL_STATE_SET(hlptim, Channel, HAL_LPTIM_CHANNEL_STATE_READY); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Start the LPTIM in Set once mode. + * @param hlptim LPTIM handle + * @param Channel LPTIM Channel to be enabled + * This parameter can be one of the following values: + * @arg LPTIM_CHANNEL_1: LPTIM Channel 1 selected + * @arg LPTIM_CHANNEL_2: LPTIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_SetOnce_Start(LPTIM_HandleTypeDef *hlptim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_CCX_INSTANCE(hlptim->Instance, Channel)); + + /* Check LPTIM channel state */ + if (LPTIM_CHANNEL_STATE_GET(hlptim, Channel) != HAL_LPTIM_CHANNEL_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Set the LPTIM channel state */ + LPTIM_CHANNEL_STATE_SET(hlptim, Channel, HAL_LPTIM_CHANNEL_STATE_BUSY); + + /* Set WAVE bit to enable the set once mode */ + hlptim->Instance->CFGR |= LPTIM_CFGR_WAVE; + + /* Enable the Peripheral */ + __HAL_LPTIM_ENABLE(hlptim); + + /* Enable LPTIM signal on the corresponding output pin */ + __HAL_LPTIM_CAPTURE_COMPARE_ENABLE(hlptim, Channel); + + /* Start timer in single (one shot) mode */ + __HAL_LPTIM_START_SINGLE(hlptim); + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stop the LPTIM Set once mode. + * @param hlptim LPTIM handle + * @param Channel LPTIM Channel to be disabled + * This parameter can be one of the following values: + * @arg LPTIM_CHANNEL_1: LPTIM Channel 1 selected + * @arg LPTIM_CHANNEL_2: LPTIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_SetOnce_Stop(LPTIM_HandleTypeDef *hlptim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_CCX_INSTANCE(hlptim->Instance, Channel)); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Disable LPTIM signal on the corresponding output pin */ + __HAL_LPTIM_CAPTURE_COMPARE_DISABLE(hlptim, Channel); + + /* Disable the Peripheral */ + __HAL_LPTIM_DISABLE(hlptim); + + /* Set the LPTIM channel state */ + LPTIM_CHANNEL_STATE_SET(hlptim, Channel, HAL_LPTIM_CHANNEL_STATE_READY); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Start the LPTIM Set once mode in interrupt mode. + * @param hlptim LPTIM handle + * @param Channel LPTIM Channel to be enabled + * This parameter can be one of the following values: + * @arg LPTIM_CHANNEL_1: LPTIM Channel 1 selected + * @arg LPTIM_CHANNEL_2: LPTIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_SetOnce_Start_IT(LPTIM_HandleTypeDef *hlptim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_CCX_INSTANCE(hlptim->Instance, Channel)); + + /* Check LPTIM channel state */ + if (LPTIM_CHANNEL_STATE_GET(hlptim, Channel) != HAL_LPTIM_CHANNEL_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Set the LPTIM channel state */ + LPTIM_CHANNEL_STATE_SET(hlptim, Channel, HAL_LPTIM_CHANNEL_STATE_BUSY); + + /* Set WAVE bit to enable the set once mode */ + hlptim->Instance->CFGR |= LPTIM_CFGR_WAVE; + + /* Enable the Peripheral */ + __HAL_LPTIM_ENABLE(hlptim); + + /* Clear flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_DIEROK); + + switch (Channel) + { + case LPTIM_CHANNEL_1: + /* Enable interrupt */ + __HAL_LPTIM_ENABLE_IT(hlptim, LPTIM_IT_CMP1OK | LPTIM_IT_CC1 | LPTIM_IT_ARROK | LPTIM_IT_ARRM | LPTIM_IT_UPDATE); + break; + case LPTIM_CHANNEL_2: + /* Enable interrupt */ + __HAL_LPTIM_ENABLE_IT(hlptim, LPTIM_IT_CMP2OK | LPTIM_IT_CC2 | LPTIM_IT_ARROK | LPTIM_IT_ARRM | LPTIM_IT_UPDATE); + break; + default: + break; + } + + /* Wait for the completion of the write operation to the LPTIM_DIER register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_DIEROK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + + /* If external trigger source is used, then enable external trigger interrupt */ + if ((hlptim->Init.Trigger.Source) != LPTIM_TRIGSOURCE_SOFTWARE) + { + /* Clear flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_DIEROK); + /* Enable external trigger interrupt */ + __HAL_LPTIM_ENABLE_IT(hlptim, LPTIM_IT_EXTTRIG); + /* Wait for the completion of the write operation to the LPTIM_DIER register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_DIEROK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + } + + /* Enable LPTIM signal on the corresponding output pin */ + __HAL_LPTIM_CAPTURE_COMPARE_ENABLE(hlptim, Channel); + + /* Start timer in single (one shot) mode */ + __HAL_LPTIM_START_SINGLE(hlptim); + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stop the LPTIM Set once mode in interrupt mode. + * @param hlptim LPTIM handle + * @param Channel LPTIM Channel to be disabled + * This parameter can be one of the following values: + * @arg LPTIM_CHANNEL_1: LPTIM Channel 1 selected + * @arg LPTIM_CHANNEL_2: LPTIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_SetOnce_Stop_IT(LPTIM_HandleTypeDef *hlptim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_CCX_INSTANCE(hlptim->Instance, Channel)); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Disable LPTIM signal on the corresponding output pin */ + __HAL_LPTIM_CAPTURE_COMPARE_DISABLE(hlptim, Channel); + + /* Disable the Peripheral */ + __HAL_LPTIM_DISABLE(hlptim); + + /* Enable the Peripheral */ + __HAL_LPTIM_ENABLE(hlptim); + + /* Clear flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_DIEROK); + + switch (Channel) + { + case LPTIM_CHANNEL_1: + /* Disable interrupt */ + __HAL_LPTIM_DISABLE_IT(hlptim, LPTIM_IT_CMP1OK | LPTIM_IT_CC1 | LPTIM_IT_ARROK | LPTIM_IT_ARRM); + break; + case LPTIM_CHANNEL_2: + /* Disable interrupt */ + __HAL_LPTIM_DISABLE_IT(hlptim, LPTIM_IT_CMP2OK | LPTIM_IT_CC2 | LPTIM_IT_ARROK | LPTIM_IT_ARRM); + break; + default: + break; + } + + /* Wait for the completion of the write operation to the LPTIM_DIER register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_DIEROK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + + /* If external trigger source is used, then enable external trigger interrupt */ + if ((hlptim->Init.Trigger.Source) != LPTIM_TRIGSOURCE_SOFTWARE) + { + /* Clear flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_DIEROK); + /* Enable external trigger interrupt */ + __HAL_LPTIM_DISABLE_IT(hlptim, LPTIM_IT_EXTTRIG); + + /* Wait for the completion of the write operation to the LPTIM_DIER register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_DIEROK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + } + + /* Disable the Peripheral */ + __HAL_LPTIM_DISABLE(hlptim); + + /* Set the LPTIM channel state */ + LPTIM_CHANNEL_STATE_SET(hlptim, Channel, HAL_LPTIM_CHANNEL_STATE_READY); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Start the Encoder interface. + * @param hlptim LPTIM handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_Encoder_Start(LPTIM_HandleTypeDef *hlptim) +{ + uint32_t tmpcfgr; + + /* Check the parameters */ + assert_param(IS_LPTIM_ENCODER_INTERFACE_INSTANCE(hlptim->Instance)); + assert_param(hlptim->Init.Clock.Source == LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC); + assert_param(hlptim->Init.Clock.Prescaler == LPTIM_PRESCALER_DIV1); + assert_param(IS_LPTIM_CLOCK_POLARITY(hlptim->Init.UltraLowPowerClock.Polarity)); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Get the LPTIMx CFGR value */ + tmpcfgr = hlptim->Instance->CFGR; + + /* Clear CKPOL bits */ + tmpcfgr &= (uint32_t)(~LPTIM_CFGR_CKPOL); + + /* Set Input polarity */ + tmpcfgr |= hlptim->Init.UltraLowPowerClock.Polarity; + + /* Write to LPTIMx CFGR */ + hlptim->Instance->CFGR = tmpcfgr; + + /* Set ENC bit to enable the encoder interface */ + hlptim->Instance->CFGR |= LPTIM_CFGR_ENC; + + /* Enable the Peripheral */ + __HAL_LPTIM_ENABLE(hlptim); + + /* Start timer in continuous mode */ + __HAL_LPTIM_START_CONTINUOUS(hlptim); + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stop the Encoder interface. + * @param hlptim LPTIM handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_Encoder_Stop(LPTIM_HandleTypeDef *hlptim) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_ENCODER_INTERFACE_INSTANCE(hlptim->Instance)); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Disable the Peripheral */ + __HAL_LPTIM_DISABLE(hlptim); + + /* Reset ENC bit to disable the encoder interface */ + hlptim->Instance->CFGR &= ~LPTIM_CFGR_ENC; + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Start the Encoder interface in interrupt mode. + * @param hlptim LPTIM handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_Encoder_Start_IT(LPTIM_HandleTypeDef *hlptim) +{ + uint32_t tmpcfgr; + + /* Check the parameters */ + assert_param(IS_LPTIM_ENCODER_INTERFACE_INSTANCE(hlptim->Instance)); + assert_param(hlptim->Init.Clock.Source == LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC); + assert_param(hlptim->Init.Clock.Prescaler == LPTIM_PRESCALER_DIV1); + assert_param(IS_LPTIM_CLOCK_POLARITY(hlptim->Init.UltraLowPowerClock.Polarity)); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Configure edge sensitivity for encoder mode */ + /* Get the LPTIMx CFGR value */ + tmpcfgr = hlptim->Instance->CFGR; + + /* Clear CKPOL bits */ + tmpcfgr &= (uint32_t)(~LPTIM_CFGR_CKPOL); + + /* Set Input polarity */ + tmpcfgr |= hlptim->Init.UltraLowPowerClock.Polarity; + + /* Write to LPTIMx CFGR */ + hlptim->Instance->CFGR = tmpcfgr; + + /* Set ENC bit to enable the encoder interface */ + hlptim->Instance->CFGR |= LPTIM_CFGR_ENC; + + /* Enable the Peripheral */ + __HAL_LPTIM_ENABLE(hlptim); + + /* Clear flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_DIEROK); + + /* Enable "switch to up/down direction" interrupt */ + __HAL_LPTIM_ENABLE_IT(hlptim, LPTIM_IT_UP | LPTIM_IT_DOWN); + + /* Wait for the completion of the write operation to the LPTIM_DIER register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_DIEROK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + + + /* Start timer in continuous mode */ + __HAL_LPTIM_START_CONTINUOUS(hlptim); + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stop the Encoder interface in interrupt mode. + * @param hlptim LPTIM handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_Encoder_Stop_IT(LPTIM_HandleTypeDef *hlptim) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_ENCODER_INTERFACE_INSTANCE(hlptim->Instance)); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Disable the Peripheral */ + __HAL_LPTIM_DISABLE(hlptim); + + /* Reset ENC bit to disable the encoder interface */ + hlptim->Instance->CFGR &= ~LPTIM_CFGR_ENC; + /* Enable the Peripheral */ + __HAL_LPTIM_ENABLE(hlptim); + + /* Clear flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_DIEROK); + + /* Disable "switch to down/up direction" interrupt */ + __HAL_LPTIM_DISABLE_IT(hlptim, LPTIM_IT_UP | LPTIM_IT_DOWN); + + /* Wait for the completion of the write operation to the LPTIM_DIER register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_DIEROK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + + /* Disable the Peripheral */ + __HAL_LPTIM_DISABLE(hlptim); + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Start the Timeout function. + * @note The first trigger event will start the timer, any successive + * trigger event will reset the counter and the timer restarts. + * @param hlptim LPTIM handle + * @param Timeout Specifies the TimeOut value to reset the counter. + * This parameter must be a value between 0x0000 and 0xFFFF. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_TimeOut_Start(LPTIM_HandleTypeDef *hlptim, uint32_t Timeout) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_INSTANCE(hlptim->Instance)); + assert_param(IS_LPTIM_PULSE(Timeout)); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Set TIMOUT bit to enable the timeout function */ + hlptim->Instance->CFGR |= LPTIM_CFGR_TIMOUT; + + /* Enable the Peripheral */ + __HAL_LPTIM_ENABLE(hlptim); + + /* Clear flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_CMP1OK); + + /* Load the Timeout value in the compare register */ + __HAL_LPTIM_COMPARE_SET(hlptim, LPTIM_CHANNEL_1, Timeout); + + /* Wait for the completion of the write operation to the LPTIM_CCR1 register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_CMP1OK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + + /* Start timer in continuous mode */ + __HAL_LPTIM_START_CONTINUOUS(hlptim); + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stop the Timeout function. + * @param hlptim LPTIM handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_TimeOut_Stop(LPTIM_HandleTypeDef *hlptim) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_INSTANCE(hlptim->Instance)); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Disable the Peripheral */ + __HAL_LPTIM_DISABLE(hlptim); + + /* Reset TIMOUT bit to enable the timeout function */ + hlptim->Instance->CFGR &= ~LPTIM_CFGR_TIMOUT; + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Start the Timeout function in interrupt mode. + * @note The first trigger event will start the timer, any successive + * trigger event will reset the counter and the timer restarts. + * @param hlptim LPTIM handle + * @param Timeout Specifies the TimeOut value to reset the counter. + * This parameter must be a value between 0x0000 and 0xFFFF. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_TimeOut_Start_IT(LPTIM_HandleTypeDef *hlptim, uint32_t Timeout) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_INSTANCE(hlptim->Instance)); + assert_param(IS_LPTIM_PULSE(Timeout)); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Set TIMOUT bit to enable the timeout function */ + hlptim->Instance->CFGR |= LPTIM_CFGR_TIMOUT; + + /* Enable the Peripheral */ + __HAL_LPTIM_ENABLE(hlptim); + + /* Clear flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_DIEROK); + + /* Enable Compare match CH1 interrupt */ + __HAL_LPTIM_ENABLE_IT(hlptim, LPTIM_IT_CC1); + + /* Wait for the completion of the write operation to the LPTIM_DIER register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_DIEROK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + + /* Clear flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_CMP1OK); + + /* Load the Timeout value in the compare register */ + __HAL_LPTIM_COMPARE_SET(hlptim, LPTIM_CHANNEL_1, Timeout); + + /* Wait for the completion of the write operation to the LPTIM_CCR1 register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_CMP1OK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + + /* Start timer in continuous mode */ + __HAL_LPTIM_START_CONTINUOUS(hlptim); + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stop the Timeout function in interrupt mode. + * @param hlptim LPTIM handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_TimeOut_Stop_IT(LPTIM_HandleTypeDef *hlptim) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_INSTANCE(hlptim->Instance)); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Disable the Peripheral */ + __HAL_LPTIM_DISABLE(hlptim); + + /* Reset TIMOUT bit to enable the timeout function */ + hlptim->Instance->CFGR &= ~LPTIM_CFGR_TIMOUT; + + /* Enable the Peripheral */ + __HAL_LPTIM_ENABLE(hlptim); + + /* Clear flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_DIEROK); + + /* Disable Compare match CH1 interrupt */ + __HAL_LPTIM_DISABLE_IT(hlptim, LPTIM_IT_CC1); + + /* Wait for the completion of the write operation to the LPTIM_DIER register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_DIEROK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + + /* Disable the Peripheral */ + __HAL_LPTIM_DISABLE(hlptim); + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Start the Counter mode. + * @param hlptim LPTIM handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_Counter_Start(LPTIM_HandleTypeDef *hlptim) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_INSTANCE(hlptim->Instance)); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* If clock source is not ULPTIM clock and counter source is external, then it must not be prescaled */ + if ((hlptim->Init.Clock.Source != LPTIM_CLOCKSOURCE_ULPTIM) + && (hlptim->Init.CounterSource == LPTIM_COUNTERSOURCE_EXTERNAL)) + { + /* Check if clock is prescaled */ + assert_param(IS_LPTIM_CLOCK_PRESCALERDIV1(hlptim->Init.Clock.Prescaler)); + /* Set clock prescaler to 0 */ + hlptim->Instance->CFGR &= ~LPTIM_CFGR_PRESC; + } + + /* Enable the Peripheral */ + __HAL_LPTIM_ENABLE(hlptim); + + /* Start timer in continuous mode */ + __HAL_LPTIM_START_CONTINUOUS(hlptim); + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stop the Counter mode. + * @param hlptim LPTIM handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_Counter_Stop(LPTIM_HandleTypeDef *hlptim) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_INSTANCE(hlptim->Instance)); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Disable the Peripheral */ + __HAL_LPTIM_DISABLE(hlptim); + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Start the Counter mode in interrupt mode. + * @param hlptim LPTIM handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_Counter_Start_IT(LPTIM_HandleTypeDef *hlptim) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_INSTANCE(hlptim->Instance)); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* If clock source is not ULPTIM clock and counter source is external, then it must not be prescaled */ + if ((hlptim->Init.Clock.Source != LPTIM_CLOCKSOURCE_ULPTIM) + && (hlptim->Init.CounterSource == LPTIM_COUNTERSOURCE_EXTERNAL)) + { + /* Check if clock is prescaled */ + assert_param(IS_LPTIM_CLOCK_PRESCALERDIV1(hlptim->Init.Clock.Prescaler)); + /* Set clock prescaler to 0 */ + hlptim->Instance->CFGR &= ~LPTIM_CFGR_PRESC; + } + + /* Enable the Peripheral */ + __HAL_LPTIM_ENABLE(hlptim); + + /* Clear flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_DIEROK); + + /* Enable interrupt */ + __HAL_LPTIM_ENABLE_IT(hlptim, LPTIM_IT_ARROK | LPTIM_IT_ARRM | LPTIM_IT_REPOK | LPTIM_IT_UPDATE); + + /* Wait for the completion of the write operation to the LPTIM_DIER register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_DIEROK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + + /* Start timer in continuous mode */ + __HAL_LPTIM_START_CONTINUOUS(hlptim); + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stop the Counter mode in interrupt mode. + * @param hlptim LPTIM handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_Counter_Stop_IT(LPTIM_HandleTypeDef *hlptim) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_INSTANCE(hlptim->Instance)); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Disable the Peripheral */ + __HAL_LPTIM_DISABLE(hlptim); + + + /* Enable the Peripheral */ + __HAL_LPTIM_ENABLE(hlptim); + + /* Clear flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_DIEROK); + + /* Disable interrupt */ + __HAL_LPTIM_DISABLE_IT(hlptim, LPTIM_IT_ARROK | LPTIM_IT_ARRM | LPTIM_IT_REPOK | LPTIM_IT_UPDATE); + + /* Wait for the completion of the write operation to the LPTIM_DIER register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_DIEROK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + + /* Disable the Peripheral */ + __HAL_LPTIM_DISABLE(hlptim); + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the LPTIM Input Capture measurement. + * @param hlptim LPTIM Input Capture handle + * @param Channel LPTIM Channels to be enabled + * This parameter can be one of the following values: + * @arg LPTIM_CHANNEL_1: TIM Channel 1 selected + * @arg LPTIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_IC_Start(LPTIM_HandleTypeDef *hlptim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_INPUT_CAPTURE_INSTANCE(hlptim->Instance)); + assert_param(IS_LPTIM_CCX_INSTANCE(hlptim->Instance, Channel)); + + /* Check LPTIM channel state */ + if (LPTIM_CHANNEL_STATE_GET(hlptim, Channel) != HAL_LPTIM_CHANNEL_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Set the LPTIM channel state */ + LPTIM_CHANNEL_STATE_SET(hlptim, Channel, HAL_LPTIM_CHANNEL_STATE_BUSY); + + /* Enable the Peripheral */ + __HAL_LPTIM_ENABLE(hlptim); + + /* Start timer in continuous mode */ + __HAL_LPTIM_START_CONTINUOUS(hlptim); + + /* Enable capture */ + __HAL_LPTIM_CAPTURE_COMPARE_ENABLE(hlptim, Channel); + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the LPTIM Input Capture measurement. + * @param hlptim LPTIM Input Capture handle + * @param Channel LPTIM Channels to be disabled + * This parameter can be one of the following values: + * @arg LPTIM_CHANNEL_1: TIM Channel 1 selected + * @arg LPTIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_IC_Stop(LPTIM_HandleTypeDef *hlptim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_INPUT_CAPTURE_INSTANCE(hlptim->Instance)); + assert_param(IS_LPTIM_CCX_INSTANCE(hlptim->Instance, Channel)); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Disable capture */ + __HAL_LPTIM_CAPTURE_COMPARE_DISABLE(hlptim, Channel); + + /* Disable the Peripheral */ + __HAL_LPTIM_DISABLE(hlptim); + + /* Set the LPTIM channel state */ + LPTIM_CHANNEL_STATE_SET(hlptim, Channel, HAL_LPTIM_CHANNEL_STATE_READY); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the LPTIM Input Capture measurement in interrupt mode. + * @param hlptim LPTIM Input Capture handle + * @param Channel LPTIM Channels to be enabled + * This parameter can be one of the following values: + * @arg LPTIM_CHANNEL_1: TIM Channel 1 selected + * @arg LPTIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_IC_Start_IT(LPTIM_HandleTypeDef *hlptim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_INPUT_CAPTURE_INSTANCE(hlptim->Instance)); + assert_param(IS_LPTIM_CCX_INSTANCE(hlptim->Instance, Channel)); + + /* Check LPTIM channel state */ + if (LPTIM_CHANNEL_STATE_GET(hlptim, Channel) != HAL_LPTIM_CHANNEL_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Set the LPTIM channel state */ + LPTIM_CHANNEL_STATE_SET(hlptim, Channel, HAL_LPTIM_CHANNEL_STATE_BUSY); + + /* Enable the Peripheral */ + __HAL_LPTIM_ENABLE(hlptim); + + switch (Channel) + { + case LPTIM_CHANNEL_1: + /* Enable Capture/Compare 1 interrupt */ + __HAL_LPTIM_ENABLE_IT(hlptim, LPTIM_IT_CC1); + break; + case LPTIM_CHANNEL_2: + /* Disable Capture/Compare 2 interrupt */ + __HAL_LPTIM_ENABLE_IT(hlptim, LPTIM_IT_CC2); + break; + default: + break; + } + + /* Wait for the completion of the write operation to the LPTIM_DIER register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_DIEROK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + + /* Start timer in continuous mode */ + __HAL_LPTIM_START_CONTINUOUS(hlptim); + + /* Enable capture */ + __HAL_LPTIM_CAPTURE_COMPARE_ENABLE(hlptim, Channel); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the LPTIM Input Capture measurement in interrupt mode. + * @param hlptim LPTIM Input Capture handle + * @param Channel LPTIM Channels to be disabled + * This parameter can be one of the following values: + * @arg LPTIM_CHANNEL_1: TIM Channel 1 selected + * @arg LPTIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_IC_Stop_IT(LPTIM_HandleTypeDef *hlptim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_INPUT_CAPTURE_INSTANCE(hlptim->Instance)); + assert_param(IS_LPTIM_CCX_INSTANCE(hlptim->Instance, Channel)); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + switch (Channel) + { + case LPTIM_CHANNEL_1: + /* Disable Capture/Compare 1 interrupt */ + __HAL_LPTIM_DISABLE_IT(hlptim, LPTIM_IT_CC1); + break; + case LPTIM_CHANNEL_2: + /* Disable Capture/Compare 2 interrupt */ + __HAL_LPTIM_DISABLE_IT(hlptim, LPTIM_IT_CC2); + break; + default: + return HAL_ERROR; + break; + } + /* Disable capture */ + __HAL_LPTIM_CAPTURE_COMPARE_DISABLE(hlptim, Channel); + + /* Disable the Peripheral */ + __HAL_LPTIM_DISABLE(hlptim); + + /* Set the LPTIM channel state */ + LPTIM_CHANNEL_STATE_SET(hlptim, Channel, HAL_LPTIM_CHANNEL_STATE_READY); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the LPTIM Input Capture measurement in DMA mode. + * @param hlptim LPTIM Input Capture handle + * @param Channel LPTIM Channels to be enabled + * This parameter can be one of the following values: + * @arg LPTIM_CHANNEL_1: TIM Channel 1 selected + * @arg LPTIM_CHANNEL_2: TIM Channel 2 selected + * @param pData The destination Buffer address + * @param Length The length of data to be transferred from LPTIM peripheral to memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_IC_Start_DMA(LPTIM_HandleTypeDef *hlptim, uint32_t Channel, uint32_t *pData, + uint32_t Length) +{ + DMA_HandleTypeDef *hdma; + + /* Check the parameters */ + assert_param(IS_LPTIM_DMA_INSTANCE(hlptim->Instance)); + assert_param(IS_LPTIM_CCX_INSTANCE(hlptim->Instance, Channel)); + + if ((pData == NULL) || (Length == 0U)) + { + return HAL_ERROR; + } + + /* Check LPTIM channel state */ + if (LPTIM_CHANNEL_STATE_GET(hlptim, Channel) != HAL_LPTIM_CHANNEL_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + /* Set the LPTIM channel state */ + LPTIM_CHANNEL_STATE_SET(hlptim, Channel, HAL_LPTIM_CHANNEL_STATE_BUSY); + + /* Enable the Peripheral */ + __HAL_LPTIM_ENABLE(hlptim); + + switch (Channel) + { + case LPTIM_CHANNEL_1: + /* Set the DMA capture callbacks */ + hlptim->hdma[LPTIM_DMA_ID_CC1]->XferCpltCallback = LPTIM_DMACaptureCplt; + hlptim->hdma[LPTIM_DMA_ID_CC1]->XferHalfCpltCallback = LPTIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + hlptim->hdma[LPTIM_DMA_ID_CC1]->XferErrorCallback = LPTIM_DMAError; + + /* Enable the DMA Channel */ + hdma = hlptim->hdma[LPTIM_DMA_ID_CC1]; + if (LPTIM_DMA_Start_IT(hdma, (uint32_t)&hlptim->Instance->CCR1, (uint32_t)pData, Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + + /* Enable Capture/Compare 1 DMA request */ + __HAL_LPTIM_ENABLE_DMA(hlptim, LPTIM_DMA_CC1); + break; + + case LPTIM_CHANNEL_2: + /* Set the DMA capture callbacks */ + hlptim->hdma[LPTIM_DMA_ID_CC2]->XferCpltCallback = LPTIM_DMACaptureCplt; + hlptim->hdma[LPTIM_DMA_ID_CC2]->XferHalfCpltCallback = LPTIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + hlptim->hdma[LPTIM_DMA_ID_CC2]->XferErrorCallback = LPTIM_DMAError; + + /* Enable the DMA Channel */ + hdma = hlptim->hdma[LPTIM_DMA_ID_CC2]; + if (LPTIM_DMA_Start_IT(hdma, (uint32_t)&hlptim->Instance->CCR2, (uint32_t)pData, Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + + /* Enable Capture/Compare 2 DMA request */ + __HAL_LPTIM_ENABLE_DMA(hlptim, LPTIM_DMA_CC2); + break; + + default: + break; + } + + /* Wait for the completion of the write operation to the LPTIM_DIER register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_DIEROK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + + /* Start timer in continuous mode */ + __HAL_LPTIM_START_CONTINUOUS(hlptim); + + /* Enable capture */ + __HAL_LPTIM_CAPTURE_COMPARE_ENABLE(hlptim, Channel); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the LPTIM Input Capture measurement in DMA mode. + * @param hlptim LPTIM Input Capture handle + * @param Channel LPTIM Channels to be disabled + * This parameter can be one of the following values: + * @arg LPTIM_CHANNEL_1: TIM Channel 1 selected + * @arg LPTIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_IC_Stop_DMA(LPTIM_HandleTypeDef *hlptim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_DMA_INSTANCE(hlptim->Instance)); + assert_param(IS_LPTIM_CCX_INSTANCE(hlptim->Instance, Channel)); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_BUSY; + + switch (Channel) + { + case LPTIM_CHANNEL_1: + /* Disable Capture/Compare 1 DMA request */ + __HAL_LPTIM_DISABLE_DMA(hlptim, LPTIM_DMA_CC1); + (void)HAL_DMA_Abort_IT(hlptim->hdma[LPTIM_DMA_ID_CC1]); + break; + + case LPTIM_CHANNEL_2: + /* Disable Capture/Compare 2 DMA request */ + __HAL_LPTIM_DISABLE_DMA(hlptim, LPTIM_DMA_CC2); + (void)HAL_DMA_Abort_IT(hlptim->hdma[LPTIM_DMA_ID_CC2]); + break; + default: + return HAL_ERROR; + break; + } + + /* Disable capture */ + __HAL_LPTIM_CAPTURE_COMPARE_DISABLE(hlptim, Channel); + + /* Disable the Peripheral */ + __HAL_LPTIM_DISABLE(hlptim); + + /* Set the LPTIM channel state */ + LPTIM_CHANNEL_STATE_SET(hlptim, Channel, HAL_LPTIM_CHANNEL_STATE_READY); + + /* Set the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} +/** + * @} + */ + +/** @defgroup LPTIM_Exported_Functions_Group3 LPTIM Read operation functions + * @brief Read operation functions. + * +@verbatim + ============================================================================== + ##### LPTIM Read operation functions ##### + ============================================================================== +[..] This section provides LPTIM Reading functions. + (+) Read the counter value. + (+) Read the period (Auto-reload) value. + (+) Read the pulse (Compare)value. +@endverbatim + * @{ + */ + +/** + * @brief Return the current counter value. + * @param hlptim LPTIM handle + * @retval Counter value. + */ +uint32_t HAL_LPTIM_ReadCounter(const LPTIM_HandleTypeDef *hlptim) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_INSTANCE(hlptim->Instance)); + + return (hlptim->Instance->CNT); +} + +/** + * @brief Return the current Autoreload (Period) value. + * @param hlptim LPTIM handle + * @retval Autoreload value. + */ +uint32_t HAL_LPTIM_ReadAutoReload(const LPTIM_HandleTypeDef *hlptim) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_INSTANCE(hlptim->Instance)); + + return (hlptim->Instance->ARR); +} + +/** + * @brief Return the current Compare (Pulse) value. + * @param hlptim LPTIM handle + * @param Channel LPTIM Channel to be selected + * This parameter can be one of the following values: + * @arg LPTIM_CHANNEL_1: LPTIM Channel 1 selected + * @arg LPTIM_CHANNEL_2: LPTIM Channel 2 selected + * @retval Compare value. + */ +uint32_t HAL_LPTIM_ReadCapturedValue(const LPTIM_HandleTypeDef *hlptim, uint32_t Channel) +{ + uint32_t tmpccr; + + /* Check the parameters */ + assert_param(IS_LPTIM_CCX_INSTANCE(hlptim->Instance, Channel)); + + switch (Channel) + { + case LPTIM_CHANNEL_1: + tmpccr = hlptim->Instance->CCR1; + break; + case LPTIM_CHANNEL_2: + tmpccr = hlptim->Instance->CCR2; + break; + default: + tmpccr = 0; + break; + } + return tmpccr; +} + +/** + * @brief LPTimer Input Capture Get Offset(in counter step unit) + * @note The real capture value corresponding to the input capture trigger can be calculated using + * the formula hereafter : Real capture value = captured(LPTIM_CCRx) - offset + * The Offset value is depending on the glitch filter value for the channel + * and the value of the prescaler for the kernel clock. + * Please check Errata Sheet V1_8 for more details under "variable latency + * on input capture channel" section. + * @param hlptim pointer to a LPTIM_HandleTypeDef structure that contains + * the configuration information for LPTIM module. + * @param Channel This parameter can be one of the following values: + * @arg LPTIM_CHANNEL_1: LPTIM Channel 1 selected + * @arg LPTIM_CHANNEL_2: LPTIM Channel 2 selected + * @retval The offset value + */ +uint8_t HAL_LPTIM_IC_GetOffset(const LPTIM_HandleTypeDef *hlptim, uint32_t Channel) +{ + + uint8_t offset ; + uint32_t prescaler; + uint32_t filter ; + + /* Get prescaler value */ + prescaler = LL_LPTIM_GetPrescaler(hlptim->Instance); + + /* Get filter value */ + filter = LL_LPTIM_IC_GetFilter(hlptim->Instance, Channel); + + /* Get offset value */ + offset = LL_LPTIM_IC_GET_OFFSET(prescaler, filter); + + /* return offset value */ + return offset; +} + +/** + * @} + */ +/** @defgroup LPTIM_Exported_Functions_Group5 LPTIM Config function + * @brief Config channel + * +@verbatim + ============================================================================== + ##### LPTIM Config function ##### + ============================================================================== +[..] This section provides LPTIM Config function. + (+) Configure channel: Output Compare mode, Period, Polarity. +@endverbatim + * @{ + */ + +/** + * @brief + * @param hlptim LPTIM handle + * @param sConfig The output configuration structure + * @param Channel LPTIM Channel to be configured + * This parameter can be one of the following values: + * @arg LPTIM_CHANNEL_1: LPTIM Channel 1 selected + * @arg LPTIM_CHANNEL_2: LPTIM Channel 2 selected + * @note Successive calls to HAL_LPTIM_OC_ConfigChannel can only be performed + * after a delay that must be greater or equal than the value of + * (PRESC x 3) kernel clock cycles, PRESC[2:0] being the clock decimal + * division factor (1, 2, 4, ..., 128). Any successive call violating + * this delay, leads to unpredictable results. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_OC_ConfigChannel(LPTIM_HandleTypeDef *hlptim, const LPTIM_OC_ConfigTypeDef *sConfig, + uint32_t Channel) +{ + HAL_StatusTypeDef status; + /* Check the parameters */ + assert_param(IS_LPTIM_CCX_INSTANCE(hlptim->Instance, Channel)); + assert_param(IS_LPTIM_OC_POLARITY(sConfig->OCPolarity)); + assert_param(IS_LPTIM_PULSE(sConfig->Pulse)); + + hlptim->State = HAL_LPTIM_STATE_BUSY; + + switch (Channel) + { + case LPTIM_CHANNEL_1: + { + /* Check the parameters */ + assert_param(IS_LPTIM_CC1_INSTANCE(hlptim->Instance)); + + /* Configure the LPTIM Channel 1 in Output Compare */ + status = LPTIM_OC1_SetConfig(hlptim, sConfig); + if (status != HAL_OK) + { + return status; + } + break; + } + case LPTIM_CHANNEL_2: + { + /* Check the parameters */ + assert_param(IS_LPTIM_CC2_INSTANCE(hlptim->Instance)); + + /* Configure the LPTIM Channel 2 in Output Compare */ + status = LPTIM_OC2_SetConfig(hlptim, sConfig); + if (status != HAL_OK) + { + return status; + } + break; + } + default: + break; + } + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief + * @param hlptim LPTIM handle + * @param sConfig The input configuration structure + * @param Channel LPTIM Channel to be configured + * This parameter can be one of the following values: + * @arg LPTIM_CHANNEL_1: LPTIM Channel 1 selected + * @arg LPTIM_CHANNEL_2: LPTIM Channel 2 selected + * @note Successive calls to HAL_LPTIM_IC_ConfigChannel can only be performed + * after a delay that must be greater or equal than the value of + * (PRESC x 3) kernel clock cycles, PRESC[2:0] being the clock decimal + * division factor (1, 2, 4, ..., 128). Any successive call violating + * this delay, leads to unpredictable results. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LPTIM_IC_ConfigChannel(LPTIM_HandleTypeDef *hlptim, const LPTIM_IC_ConfigTypeDef *sConfig, + uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_LPTIM_CCX_INSTANCE(hlptim->Instance, Channel)); + assert_param(IS_LPTIM_IC_PRESCALER(sConfig->ICPrescaler)); + assert_param(IS_LPTIM_IC_POLARITY(sConfig->ICPolarity)); + assert_param(IS_LPTIM_IC_FILTER(sConfig->ICFilter)); + + hlptim->State = HAL_LPTIM_STATE_BUSY; + + switch (Channel) + { + case LPTIM_CHANNEL_1: + { + /* Check the parameters */ + assert_param(IS_LPTIM_CC1_INSTANCE(hlptim->Instance)); + assert_param(IS_LPTIM_IC1_SOURCE(hlptim->Instance, sConfig->ICInputSource)); + + /* Configure the LPTIM Channel 1 in Input Capture */ + LPTIM_IC1_SetConfig(hlptim, sConfig); + break; + } + case LPTIM_CHANNEL_2: + { + /* Check the parameters */ + assert_param(IS_LPTIM_CC2_INSTANCE(hlptim->Instance)); + assert_param(IS_LPTIM_IC2_SOURCE(hlptim->Instance, sConfig->ICInputSource)); + + /* Configure the LPTIM Channel 2 in Input Capture */ + LPTIM_IC2_SetConfig(hlptim, sConfig); + break; + } + default: + break; + } + + /* Change the LPTIM state */ + hlptim->State = HAL_LPTIM_STATE_READY; + /* Return function status */ + return HAL_OK; +} +/** + * @} + */ + +/** @defgroup LPTIM_Exported_Functions_Group4 LPTIM IRQ handler and callbacks + * @brief LPTIM IRQ handler. + * +@verbatim + ============================================================================== + ##### LPTIM IRQ handler and callbacks ##### + ============================================================================== +[..] This section provides LPTIM IRQ handler and callback functions called within + the IRQ handler: + (+) LPTIM interrupt request handler + (+) Compare match Callback + (+) Auto-reload match Callback + (+) External trigger event detection Callback + (+) Compare register write complete Callback + (+) Auto-reload register write complete Callback + (+) Up-counting direction change Callback + (+) Down-counting direction change Callback + +@endverbatim + * @{ + */ + +/** + * @brief Handle LPTIM interrupt request. + * @param hlptim LPTIM handle + * @retval None + */ +void HAL_LPTIM_IRQHandler(LPTIM_HandleTypeDef *hlptim) +{ + /* Capture Compare 1 interrupt */ + if (__HAL_LPTIM_GET_FLAG(hlptim, LPTIM_FLAG_CC1) != RESET) + { + if (__HAL_LPTIM_GET_IT_SOURCE(hlptim, LPTIM_FLAG_CC1) != RESET) + { + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_CC1); + hlptim->Channel = HAL_LPTIM_ACTIVE_CHANNEL_1; + + /* Input capture event */ + if ((hlptim->Instance->CCMR1 & LPTIM_CCMR1_CC1SEL) != 0x00U) + { +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) + hlptim->IC_CaptureCallback(hlptim); +#else + HAL_LPTIM_IC_CaptureCallback(hlptim); +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ + } + /* Output compare event */ + else + { +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) + hlptim->CompareMatchCallback(hlptim); +#else + HAL_LPTIM_CompareMatchCallback(hlptim); +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ + } + hlptim->Channel = HAL_LPTIM_ACTIVE_CHANNEL_CLEARED; + } + } + + /* Capture Compare 2 interrupt */ + if (__HAL_LPTIM_GET_FLAG(hlptim, LPTIM_FLAG_CC2) != RESET) + { + if (__HAL_LPTIM_GET_IT_SOURCE(hlptim, LPTIM_FLAG_CC2) != RESET) + { + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_CC2); + hlptim->Channel = HAL_LPTIM_ACTIVE_CHANNEL_2; + + /* Input capture event */ + if ((hlptim->Instance->CCMR1 & LPTIM_CCMR1_CC2SEL) != 0x00U) + { +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) + hlptim->IC_CaptureCallback(hlptim); +#else + HAL_LPTIM_IC_CaptureCallback(hlptim); +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ + } + /* Output compare event */ + else + { +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) + hlptim->CompareMatchCallback(hlptim); +#else + HAL_LPTIM_CompareMatchCallback(hlptim); +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ + } + hlptim->Channel = HAL_LPTIM_ACTIVE_CHANNEL_CLEARED; + } + } + + /* Over Capture 1 interrupt */ + if (__HAL_LPTIM_GET_FLAG(hlptim, LPTIM_FLAG_CC1O) != RESET) + { + if (__HAL_LPTIM_GET_IT_SOURCE(hlptim, LPTIM_FLAG_CC1O) != RESET) + { + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_CC1O); + hlptim->Channel = HAL_LPTIM_ACTIVE_CHANNEL_1; + + /* Over capture event */ +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) + hlptim->IC_OverCaptureCallback(hlptim); +#else + HAL_LPTIM_IC_OverCaptureCallback(hlptim); +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ + hlptim->Channel = HAL_LPTIM_ACTIVE_CHANNEL_CLEARED; + } + } + + /* Over Capture 2 interrupt */ + if (__HAL_LPTIM_GET_FLAG(hlptim, LPTIM_FLAG_CC2O) != RESET) + { + if (__HAL_LPTIM_GET_IT_SOURCE(hlptim, LPTIM_FLAG_CC2O) != RESET) + { + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_CC2O); + hlptim->Channel = HAL_LPTIM_ACTIVE_CHANNEL_2; + + /* Over capture event */ +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) + hlptim->IC_OverCaptureCallback(hlptim); +#else + HAL_LPTIM_IC_OverCaptureCallback(hlptim); +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ + hlptim->Channel = HAL_LPTIM_ACTIVE_CHANNEL_CLEARED; + } + } + + /* Autoreload match interrupt */ + if (__HAL_LPTIM_GET_FLAG(hlptim, LPTIM_FLAG_ARRM) != RESET) + { + if (__HAL_LPTIM_GET_IT_SOURCE(hlptim, LPTIM_IT_ARRM) != RESET) + { + /* Clear Autoreload match flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_ARRM); + + /* Autoreload match Callback */ +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) + hlptim->AutoReloadMatchCallback(hlptim); +#else + HAL_LPTIM_AutoReloadMatchCallback(hlptim); +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ + } + } + + /* Trigger detected interrupt */ + if (__HAL_LPTIM_GET_FLAG(hlptim, LPTIM_FLAG_EXTTRIG) != RESET) + { + if (__HAL_LPTIM_GET_IT_SOURCE(hlptim, LPTIM_IT_EXTTRIG) != RESET) + { + /* Clear Trigger detected flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_EXTTRIG); + + /* Trigger detected callback */ +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) + hlptim->TriggerCallback(hlptim); +#else + HAL_LPTIM_TriggerCallback(hlptim); +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ + } + } + + /* Compare write interrupt */ + if (__HAL_LPTIM_GET_FLAG(hlptim, LPTIM_FLAG_CMP1OK) != RESET) + { + if (__HAL_LPTIM_GET_IT_SOURCE(hlptim, LPTIM_IT_CMP1OK) != RESET) + { + /* Clear Compare write flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_CMP1OK); + hlptim->Channel = HAL_LPTIM_ACTIVE_CHANNEL_1; + /* Compare write Callback */ +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) + hlptim->CompareWriteCallback(hlptim); +#else + HAL_LPTIM_CompareWriteCallback(hlptim); +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ + } + } + + /* Compare write interrupt */ + if (__HAL_LPTIM_GET_FLAG(hlptim, LPTIM_FLAG_CMP2OK) != RESET) + { + if (__HAL_LPTIM_GET_IT_SOURCE(hlptim, LPTIM_IT_CMP2OK) != RESET) + { + /* Clear Compare write flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_CMP2OK); + hlptim->Channel = HAL_LPTIM_ACTIVE_CHANNEL_2; + /* Compare write Callback */ +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) + hlptim->CompareWriteCallback(hlptim); +#else + HAL_LPTIM_CompareWriteCallback(hlptim); +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ + } + } + + /* Autoreload write interrupt */ + if (__HAL_LPTIM_GET_FLAG(hlptim, LPTIM_FLAG_ARROK) != RESET) + { + if (__HAL_LPTIM_GET_IT_SOURCE(hlptim, LPTIM_IT_ARROK) != RESET) + { + /* Clear Autoreload write flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_ARROK); + + /* Autoreload write Callback */ +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) + hlptim->AutoReloadWriteCallback(hlptim); +#else + HAL_LPTIM_AutoReloadWriteCallback(hlptim); +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ + } + } + + /* Direction counter changed from Down to Up interrupt */ + if (__HAL_LPTIM_GET_FLAG(hlptim, LPTIM_FLAG_UP) != RESET) + { + if (__HAL_LPTIM_GET_IT_SOURCE(hlptim, LPTIM_IT_UP) != RESET) + { + /* Clear Direction counter changed from Down to Up flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_UP); + + /* Direction counter changed from Down to Up Callback */ +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) + hlptim->DirectionUpCallback(hlptim); +#else + HAL_LPTIM_DirectionUpCallback(hlptim); +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ + } + } + + /* Direction counter changed from Up to Down interrupt */ + if (__HAL_LPTIM_GET_FLAG(hlptim, LPTIM_FLAG_DOWN) != RESET) + { + if (__HAL_LPTIM_GET_IT_SOURCE(hlptim, LPTIM_IT_DOWN) != RESET) + { + /* Clear Direction counter changed from Up to Down flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_DOWN); + + /* Direction counter changed from Up to Down Callback */ +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) + hlptim->DirectionDownCallback(hlptim); +#else + HAL_LPTIM_DirectionDownCallback(hlptim); +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ + } + } + + /* Repetition counter underflowed (or contains zero) and the LPTIM counter + overflowed */ + if (__HAL_LPTIM_GET_FLAG(hlptim, LPTIM_FLAG_UPDATE) != RESET) + { + if (__HAL_LPTIM_GET_IT_SOURCE(hlptim, LPTIM_IT_UPDATE) != RESET) + { + /* Clear update event flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_UPDATE); + + /* Update event Callback */ +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) + hlptim->UpdateEventCallback(hlptim); +#else + HAL_LPTIM_UpdateEventCallback(hlptim); +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ + } + } + + /* Successful APB bus write to repetition counter register */ + if (__HAL_LPTIM_GET_FLAG(hlptim, LPTIM_FLAG_REPOK) != RESET) + { + if (__HAL_LPTIM_GET_IT_SOURCE(hlptim, LPTIM_IT_REPOK) != RESET) + { + /* Clear successful APB bus write to repetition counter flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_REPOK); + + /* Successful APB bus write to repetition counter Callback */ +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) + hlptim->RepCounterWriteCallback(hlptim); +#else + HAL_LPTIM_RepCounterWriteCallback(hlptim); +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ + } + } +} + +/** + * @brief Compare match callback in non-blocking mode. + * @param hlptim LPTIM handle + * @retval None + */ +__weak void HAL_LPTIM_CompareMatchCallback(LPTIM_HandleTypeDef *hlptim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hlptim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_LPTIM_CompareMatchCallback could be implemented in the user file + */ +} + +/** + * @brief Autoreload match callback in non-blocking mode. + * @param hlptim LPTIM handle + * @retval None + */ +__weak void HAL_LPTIM_AutoReloadMatchCallback(LPTIM_HandleTypeDef *hlptim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hlptim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_LPTIM_AutoReloadMatchCallback could be implemented in the user file + */ +} + +/** + * @brief Trigger detected callback in non-blocking mode. + * @param hlptim LPTIM handle + * @retval None + */ +__weak void HAL_LPTIM_TriggerCallback(LPTIM_HandleTypeDef *hlptim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hlptim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_LPTIM_TriggerCallback could be implemented in the user file + */ +} + +/** + * @brief Compare write callback in non-blocking mode. + * @param hlptim LPTIM handle + * @retval None + */ +__weak void HAL_LPTIM_CompareWriteCallback(LPTIM_HandleTypeDef *hlptim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hlptim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_LPTIM_CompareWriteCallback could be implemented in the user file + */ +} + +/** + * @brief Autoreload write callback in non-blocking mode. + * @param hlptim LPTIM handle + * @retval None + */ +__weak void HAL_LPTIM_AutoReloadWriteCallback(LPTIM_HandleTypeDef *hlptim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hlptim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_LPTIM_AutoReloadWriteCallback could be implemented in the user file + */ +} + +/** + * @brief Direction counter changed from Down to Up callback in non-blocking mode. + * @param hlptim LPTIM handle + * @retval None + */ +__weak void HAL_LPTIM_DirectionUpCallback(LPTIM_HandleTypeDef *hlptim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hlptim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_LPTIM_DirectionUpCallback could be implemented in the user file + */ +} + +/** + * @brief Direction counter changed from Up to Down callback in non-blocking mode. + * @param hlptim LPTIM handle + * @retval None + */ +__weak void HAL_LPTIM_DirectionDownCallback(LPTIM_HandleTypeDef *hlptim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hlptim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_LPTIM_DirectionDownCallback could be implemented in the user file + */ +} + +/** + * @brief Repetition counter underflowed (or contains zero) and LPTIM counter overflowed callback in non-blocking mode. + * @param hlptim LPTIM handle + * @retval None + */ +__weak void HAL_LPTIM_UpdateEventCallback(LPTIM_HandleTypeDef *hlptim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hlptim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_LPTIM_UpdateEventCallback could be implemented in the user file + */ +} + +/** + * @brief Successful APB bus write to repetition counter register callback in non-blocking mode. + * @param hlptim LPTIM handle + * @retval None + */ +__weak void HAL_LPTIM_RepCounterWriteCallback(LPTIM_HandleTypeDef *hlptim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hlptim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_LPTIM_RepCounterWriteCallback could be implemented in the user file + */ +} + +/** + * @brief Input Capture callback in non-blocking mode + * @param hlptim LPTIM handle + * @retval None + */ +__weak void HAL_LPTIM_IC_CaptureCallback(LPTIM_HandleTypeDef *hlptim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hlptim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_LPTIM_IC_CaptureCallback could be implemented in the user file + */ +} + +/** + * @brief Over Capture callback in non-blocking mode + * @param hlptim LPTIM handle + * @retval None + */ +__weak void HAL_LPTIM_IC_OverCaptureCallback(LPTIM_HandleTypeDef *hlptim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hlptim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_LPTIM_IC_OverCaptureCallback could be implemented in the user file + */ +} + +/** + * @brief Input Capture half complete callback in non-blocking mode + * @param hlptim LPTIM IC handle + * @retval None + */ +__weak void HAL_LPTIM_IC_CaptureHalfCpltCallback(LPTIM_HandleTypeDef *hlptim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hlptim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_LPTIM_IC_CaptureHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Update event half complete callback in non-blocking mode + * @param hlptim LPTIM handle + * @retval None + */ +__weak void HAL_LPTIM_UpdateEventHalfCpltCallback(LPTIM_HandleTypeDef *hlptim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hlptim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_LPTIM_UpdateEventHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Error callback in non-blocking mode + * @param hlptim LPTIM handle + * @retval None + */ +__weak void HAL_LPTIM_ErrorCallback(LPTIM_HandleTypeDef *hlptim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hlptim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_LPTIM_ErrorCallback could be implemented in the user file + */ +} + + +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User LPTIM callback to be used instead of the weak predefined callback + * @param hlptim LPTIM handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_LPTIM_MSPINIT_CB_ID LPTIM Base Msp Init Callback ID + * @arg @ref HAL_LPTIM_MSPDEINIT_CB_ID LPTIM Base Msp DeInit Callback ID + * @arg @ref HAL_LPTIM_COMPARE_MATCH_CB_ID Compare match Callback ID + * @arg @ref HAL_LPTIM_AUTORELOAD_MATCH_CB_ID Auto-reload match Callback ID + * @arg @ref HAL_LPTIM_TRIGGER_CB_ID External trigger event detection Callback ID + * @arg @ref HAL_LPTIM_COMPARE_WRITE_CB_ID Compare register write complete Callback ID + * @arg @ref HAL_LPTIM_AUTORELOAD_WRITE_CB_ID Auto-reload register write complete Callback ID + * @arg @ref HAL_LPTIM_DIRECTION_UP_CB_ID Up-counting direction change Callback ID + * @arg @ref HAL_LPTIM_DIRECTION_DOWN_CB_ID Down-counting direction change Callback ID + * @arg @ref HAL_LPTIM_UPDATE_EVENT_CB_ID Update event detection Callback ID + * @arg @ref HAL_LPTIM_REP_COUNTER_WRITE_CB_ID Repetition counter register write complete Callback ID + * @arg @ref HAL_LPTIM_UPDATE_EVENT_HALF_CB_ID Update event Half detection Callback ID + * @arg @ref HAL_LPTIM_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_LPTIM_IC_CAPTURE_CB_ID Input Capture Callback ID + * @arg @ref HAL_LPTIM_IC_CAPTURE_HALF_CB_ID Input Capture half complete Callback ID + * @arg @ref HAL_LPTIM_OVER_CAPTURE_CB_ID Over Capture Callback ID + * @param pCallback pointer to the callback function + * @retval status + */ +HAL_StatusTypeDef HAL_LPTIM_RegisterCallback(LPTIM_HandleTypeDef *hlptim, + HAL_LPTIM_CallbackIDTypeDef CallbackID, + pLPTIM_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + return HAL_ERROR; + } + + if (hlptim->State == HAL_LPTIM_STATE_READY) + { + switch (CallbackID) + { + case HAL_LPTIM_MSPINIT_CB_ID : + hlptim->MspInitCallback = pCallback; + break; + + case HAL_LPTIM_MSPDEINIT_CB_ID : + hlptim->MspDeInitCallback = pCallback; + break; + + case HAL_LPTIM_COMPARE_MATCH_CB_ID : + hlptim->CompareMatchCallback = pCallback; + break; + + case HAL_LPTIM_AUTORELOAD_MATCH_CB_ID : + hlptim->AutoReloadMatchCallback = pCallback; + break; + + case HAL_LPTIM_TRIGGER_CB_ID : + hlptim->TriggerCallback = pCallback; + break; + + case HAL_LPTIM_COMPARE_WRITE_CB_ID : + hlptim->CompareWriteCallback = pCallback; + break; + + case HAL_LPTIM_AUTORELOAD_WRITE_CB_ID : + hlptim->AutoReloadWriteCallback = pCallback; + break; + + case HAL_LPTIM_DIRECTION_UP_CB_ID : + hlptim->DirectionUpCallback = pCallback; + break; + + case HAL_LPTIM_DIRECTION_DOWN_CB_ID : + hlptim->DirectionDownCallback = pCallback; + break; + + case HAL_LPTIM_UPDATE_EVENT_CB_ID : + hlptim->UpdateEventCallback = pCallback; + break; + + case HAL_LPTIM_REP_COUNTER_WRITE_CB_ID : + hlptim->RepCounterWriteCallback = pCallback; + break; + + case HAL_LPTIM_UPDATE_EVENT_HALF_CB_ID : + hlptim->UpdateEventHalfCpltCallback = pCallback; + break; + + case HAL_LPTIM_ERROR_CB_ID : + hlptim->ErrorCallback = pCallback; + break; + + case HAL_LPTIM_IC_CAPTURE_CB_ID : + hlptim->IC_CaptureCallback = pCallback; + break; + + case HAL_LPTIM_IC_CAPTURE_HALF_CB_ID : + hlptim->IC_CaptureHalfCpltCallback = pCallback; + break; + + case HAL_LPTIM_OVER_CAPTURE_CB_ID : + hlptim->IC_OverCaptureCallback = pCallback; + break; + + default : + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (hlptim->State == HAL_LPTIM_STATE_RESET) + { + switch (CallbackID) + { + case HAL_LPTIM_MSPINIT_CB_ID : + hlptim->MspInitCallback = pCallback; + break; + + case HAL_LPTIM_MSPDEINIT_CB_ID : + hlptim->MspDeInitCallback = pCallback; + break; + + default : + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister a LPTIM callback + * LLPTIM callback is redirected to the weak predefined callback + * @param hlptim LPTIM handle + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_LPTIM_MSPINIT_CB_ID LPTIM Base Msp Init Callback ID + * @arg @ref HAL_LPTIM_MSPDEINIT_CB_ID LPTIM Base Msp DeInit Callback ID + * @arg @ref HAL_LPTIM_COMPARE_MATCH_CB_ID Compare match Callback ID + * @arg @ref HAL_LPTIM_AUTORELOAD_MATCH_CB_ID Auto-reload match Callback ID + * @arg @ref HAL_LPTIM_TRIGGER_CB_ID External trigger event detection Callback ID + * @arg @ref HAL_LPTIM_COMPARE_WRITE_CB_ID Compare register write complete Callback ID + * @arg @ref HAL_LPTIM_AUTORELOAD_WRITE_CB_ID Auto-reload register write complete Callback ID + * @arg @ref HAL_LPTIM_DIRECTION_UP_CB_ID Up-counting direction change Callback ID + * @arg @ref HAL_LPTIM_DIRECTION_DOWN_CB_ID Down-counting direction change Callback ID + * @arg @ref HAL_LPTIM_UPDATE_EVENT_CB_ID Update event detection Callback ID + * @arg @ref HAL_LPTIM_REP_COUNTER_WRITE_CB_ID Repetition counter register write complete Callback ID + * @arg @ref HAL_LPTIM_UPDATE_EVENT_HALF_CB_ID Update event Half detection Callback ID + * @arg @ref HAL_LPTIM_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_LPTIM_IC_CAPTURE_CB_ID Input Capture Callback ID + * @arg @ref HAL_LPTIM_IC_CAPTURE_HALF_CB_ID Input Capture half complete Callback ID + * @arg @ref HAL_LPTIM_OVER_CAPTURE_CB_ID Over Capture Callback ID + * @retval status + */ +HAL_StatusTypeDef HAL_LPTIM_UnRegisterCallback(LPTIM_HandleTypeDef *hlptim, + HAL_LPTIM_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (hlptim->State == HAL_LPTIM_STATE_READY) + { + switch (CallbackID) + { + case HAL_LPTIM_MSPINIT_CB_ID : + /* Legacy weak MspInit Callback */ + hlptim->MspInitCallback = HAL_LPTIM_MspInit; + break; + + case HAL_LPTIM_MSPDEINIT_CB_ID : + /* Legacy weak Msp DeInit Callback */ + hlptim->MspDeInitCallback = HAL_LPTIM_MspDeInit; + break; + + case HAL_LPTIM_COMPARE_MATCH_CB_ID : + /* Legacy weak Compare match Callback */ + hlptim->CompareMatchCallback = HAL_LPTIM_CompareMatchCallback; + break; + + case HAL_LPTIM_AUTORELOAD_MATCH_CB_ID : + /* Legacy weak Auto-reload match Callback */ + hlptim->AutoReloadMatchCallback = HAL_LPTIM_AutoReloadMatchCallback; + break; + + case HAL_LPTIM_TRIGGER_CB_ID : + /* Legacy weak External trigger event detection Callback */ + hlptim->TriggerCallback = HAL_LPTIM_TriggerCallback; + break; + + case HAL_LPTIM_COMPARE_WRITE_CB_ID : + /* Legacy weak Compare register write complete Callback */ + hlptim->CompareWriteCallback = HAL_LPTIM_CompareWriteCallback; + break; + + case HAL_LPTIM_AUTORELOAD_WRITE_CB_ID : + /* Legacy weak Auto-reload register write complete Callback */ + hlptim->AutoReloadWriteCallback = HAL_LPTIM_AutoReloadWriteCallback; + break; + + case HAL_LPTIM_DIRECTION_UP_CB_ID : + /* Legacy weak Up-counting direction change Callback */ + hlptim->DirectionUpCallback = HAL_LPTIM_DirectionUpCallback; + break; + + case HAL_LPTIM_DIRECTION_DOWN_CB_ID : + /* Legacy weak Down-counting direction change Callback */ + hlptim->DirectionDownCallback = HAL_LPTIM_DirectionDownCallback; + break; + + case HAL_LPTIM_UPDATE_EVENT_CB_ID : + /* Legacy weak Update event detection Callback */ + hlptim->UpdateEventCallback = HAL_LPTIM_UpdateEventCallback; + break; + + case HAL_LPTIM_REP_COUNTER_WRITE_CB_ID : + /* Legacy weak Repetition counter register write complete Callback */ + hlptim->RepCounterWriteCallback = HAL_LPTIM_RepCounterWriteCallback; + break; + + case HAL_LPTIM_UPDATE_EVENT_HALF_CB_ID : + /* Legacy weak Update event half complete detection Callback */ + hlptim->UpdateEventHalfCpltCallback = HAL_LPTIM_UpdateEventHalfCpltCallback; + break; + + case HAL_LPTIM_ERROR_CB_ID : + /* Legacy weak error Callback */ + hlptim->ErrorCallback = HAL_LPTIM_ErrorCallback; + break; + + case HAL_LPTIM_IC_CAPTURE_CB_ID : + /* Legacy weak IC Capture Callback */ + hlptim->IC_CaptureCallback = HAL_LPTIM_IC_CaptureCallback; + break; + + case HAL_LPTIM_IC_CAPTURE_HALF_CB_ID : + /* Legacy weak IC Capture half complete Callback */ + hlptim->IC_CaptureHalfCpltCallback = HAL_LPTIM_IC_CaptureHalfCpltCallback; + break; + + case HAL_LPTIM_OVER_CAPTURE_CB_ID : + /* Legacy weak IC over capture Callback */ + hlptim->IC_OverCaptureCallback = HAL_LPTIM_IC_OverCaptureCallback; + break; + + default : + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (hlptim->State == HAL_LPTIM_STATE_RESET) + { + switch (CallbackID) + { + case HAL_LPTIM_MSPINIT_CB_ID : + /* Legacy weak MspInit Callback */ + hlptim->MspInitCallback = HAL_LPTIM_MspInit; + break; + + case HAL_LPTIM_MSPDEINIT_CB_ID : + /* Legacy weak Msp DeInit Callback */ + hlptim->MspDeInitCallback = HAL_LPTIM_MspDeInit; + break; + + default : + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup LPTIM_Group5 Peripheral State functions + * @brief Peripheral State functions. + * +@verbatim + ============================================================================== + ##### Peripheral State functions ##### + ============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Return the LPTIM handle state. + * @param hlptim LPTIM handle + * @retval HAL state + */ +HAL_LPTIM_StateTypeDef HAL_LPTIM_GetState(const LPTIM_HandleTypeDef *hlptim) +{ + /* Return LPTIM handle state */ + return hlptim->State; +} + +/** + * @} + */ + + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup LPTIM_Private_Functions LPTIM Private Functions + * @{ + */ +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) +/** + * @brief Reset interrupt callbacks to the legacy weak callbacks. + * @param lptim pointer to a LPTIM_HandleTypeDef structure that contains + * the configuration information for LPTIM module. + * @retval None + */ +static void LPTIM_ResetCallback(LPTIM_HandleTypeDef *lptim) +{ + /* Reset the LPTIM callback to the legacy weak callbacks */ + lptim->CompareMatchCallback = HAL_LPTIM_CompareMatchCallback; + lptim->AutoReloadMatchCallback = HAL_LPTIM_AutoReloadMatchCallback; + lptim->TriggerCallback = HAL_LPTIM_TriggerCallback; + lptim->CompareWriteCallback = HAL_LPTIM_CompareWriteCallback; + lptim->AutoReloadWriteCallback = HAL_LPTIM_AutoReloadWriteCallback; + lptim->DirectionUpCallback = HAL_LPTIM_DirectionUpCallback; + lptim->DirectionDownCallback = HAL_LPTIM_DirectionDownCallback; + lptim->UpdateEventCallback = HAL_LPTIM_UpdateEventCallback; + lptim->RepCounterWriteCallback = HAL_LPTIM_RepCounterWriteCallback; + lptim->UpdateEventHalfCpltCallback = HAL_LPTIM_UpdateEventHalfCpltCallback; + lptim->IC_CaptureCallback = HAL_LPTIM_IC_CaptureCallback; + lptim->IC_CaptureHalfCpltCallback = HAL_LPTIM_IC_CaptureHalfCpltCallback; + lptim->IC_OverCaptureCallback = HAL_LPTIM_IC_OverCaptureCallback; + lptim->ErrorCallback = HAL_LPTIM_ErrorCallback; +} +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ + +/** + * @brief LPTimer Wait for flag set + * @param hlptim pointer to a LPTIM_HandleTypeDef structure that contains + * the configuration information for LPTIM module. + * @param flag The lptim flag + * @retval HAL status + */ +static HAL_StatusTypeDef LPTIM_WaitForFlag(const LPTIM_HandleTypeDef *hlptim, uint32_t flag) +{ + HAL_StatusTypeDef result = HAL_OK; + uint32_t count = TIMEOUT * (SystemCoreClock / 20UL / 1000UL); + do + { + count--; + if (count == 0UL) + { + result = HAL_TIMEOUT; + } + } while ((!(__HAL_LPTIM_GET_FLAG((hlptim), (flag)))) && (count != 0UL)); + + return result; +} + +/** + * @brief LPTIM DMA error callback + * @param hdma pointer to DMA handle. + * @retval None + */ +void LPTIM_DMAError(DMA_HandleTypeDef *hdma) +{ + LPTIM_HandleTypeDef *hlptim = (LPTIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + hlptim->State = HAL_LPTIM_STATE_READY; + +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) + hlptim->ErrorCallback(hlptim); +#else + HAL_LPTIM_ErrorCallback(hlptim); +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ +} + +/** + * @brief LPTIM DMA Capture complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +void LPTIM_DMACaptureCplt(DMA_HandleTypeDef *hdma) +{ + LPTIM_HandleTypeDef *hlptim = (LPTIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + hlptim->State = HAL_LPTIM_STATE_READY; + + if (hdma == hlptim->hdma[LPTIM_DMA_ID_CC1]) + { + hlptim->Channel = HAL_LPTIM_ACTIVE_CHANNEL_1; + } + else if (hdma == hlptim->hdma[LPTIM_DMA_ID_CC2]) + { + hlptim->Channel = HAL_LPTIM_ACTIVE_CHANNEL_2; + } + else + { + /* nothing to do */ + } + +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) + hlptim->IC_CaptureCallback(hlptim); +#else + HAL_LPTIM_IC_CaptureCallback(hlptim); +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ + + hlptim->Channel = HAL_LPTIM_ACTIVE_CHANNEL_CLEARED; +} + +/** + * @brief LPTIM DMA Capture half complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +void LPTIM_DMACaptureHalfCplt(DMA_HandleTypeDef *hdma) +{ + LPTIM_HandleTypeDef *hlptim = (LPTIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + hlptim->State = HAL_LPTIM_STATE_READY; + + if (hdma == hlptim->hdma[LPTIM_DMA_ID_CC1]) + { + hlptim->Channel = HAL_LPTIM_ACTIVE_CHANNEL_1; + } + else if (hdma == hlptim->hdma[LPTIM_DMA_ID_CC2]) + { + hlptim->Channel = HAL_LPTIM_ACTIVE_CHANNEL_2; + } + else + { + /* nothing to do */ + } + +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) + hlptim->IC_CaptureHalfCpltCallback(hlptim); +#else + HAL_LPTIM_IC_CaptureHalfCpltCallback(hlptim); +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ + + hlptim->Channel = HAL_LPTIM_ACTIVE_CHANNEL_CLEARED; +} + +/** + * @brief LPTIM DMA Update event complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +void LPTIM_DMAUpdateEventCplt(DMA_HandleTypeDef *hdma) +{ + LPTIM_HandleTypeDef *hlptim = (LPTIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + hlptim->State = HAL_LPTIM_STATE_READY; + + if (hdma == hlptim->hdma[LPTIM_DMA_ID_CC1]) + { + hlptim->Channel = HAL_LPTIM_ACTIVE_CHANNEL_1; + } + else if (hdma == hlptim->hdma[LPTIM_DMA_ID_CC2]) + { + hlptim->Channel = HAL_LPTIM_ACTIVE_CHANNEL_2; + } + else + { + /* nothing to do */ + } + +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) + hlptim->UpdateEventCallback(hlptim); +#else + HAL_LPTIM_UpdateEventCallback(hlptim); +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ + + hlptim->Channel = HAL_LPTIM_ACTIVE_CHANNEL_CLEARED; +} + +/** + * @brief LPTIM DMA Capture half complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +void LPTIM_DMAUpdateEventHalfCplt(DMA_HandleTypeDef *hdma) +{ + LPTIM_HandleTypeDef *hlptim = (LPTIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + hlptim->State = HAL_LPTIM_STATE_READY; + + if (hdma == hlptim->hdma[LPTIM_DMA_ID_CC1]) + { + hlptim->Channel = HAL_LPTIM_ACTIVE_CHANNEL_1; + } + else if (hdma == hlptim->hdma[LPTIM_DMA_ID_CC2]) + { + hlptim->Channel = HAL_LPTIM_ACTIVE_CHANNEL_2; + } + else + { + /* nothing to do */ + } + +#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1) + hlptim->UpdateEventHalfCpltCallback(hlptim); +#else + HAL_LPTIM_UpdateEventHalfCpltCallback(hlptim); +#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */ + + hlptim->Channel = HAL_LPTIM_ACTIVE_CHANNEL_CLEARED; +} +/** + * @brief LPTimer Output Compare 1 configuration + * @param hlptim pointer to a LPTIM_HandleTypeDef structure that contains + * the configuration information for LPTIM module. + * @param sConfig The output configuration structure + * @retval None + */ +static HAL_StatusTypeDef LPTIM_OC1_SetConfig(LPTIM_HandleTypeDef *hlptim, const LPTIM_OC_ConfigTypeDef *sConfig) +{ + uint32_t tmpccmr1; +#if !defined(LPTIM4) +#else + uint32_t tmpcfgr; +#endif /* !LPTIM4 */ + + tmpccmr1 = hlptim->Instance->CCMR1; + tmpccmr1 &= ~(LPTIM_CCMR1_CC1P_Msk | LPTIM_CCMR1_CC1SEL_Msk); + +#if defined(LPTIM4) + if (hlptim->Instance == LPTIM4) + { + tmpcfgr = hlptim->Instance->CFGR; + tmpcfgr &= ~LPTIM_CFGR_WAVPOL_Msk; + tmpcfgr |= sConfig->OCPolarity << LPTIM_CFGR_WAVPOL_Pos; + + /* Write to CFGR register */ + hlptim->Instance->CFGR = tmpcfgr; + } + else +#endif /* LPTIM4 */ + { + tmpccmr1 |= sConfig->OCPolarity << LPTIM_CCMR1_CC1P_Pos; + } + + /* Enable the Peripheral */ + __HAL_LPTIM_ENABLE(hlptim); + + /* Clear flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_CMP1OK); + + /* Write to CCR1 register */ + __HAL_LPTIM_COMPARE_SET(hlptim, LPTIM_CHANNEL_1, sConfig->Pulse); + + /* Wait for the completion of the write operation to the LPTIM_CCR1 register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_CMP1OK) == HAL_TIMEOUT) + { + return HAL_TIMEOUT; + } + + /* Disable the Peripheral */ + __HAL_LPTIM_DISABLE(hlptim); + + /* Write to CCMR1 register */ + hlptim->Instance->CCMR1 = tmpccmr1; + + return HAL_OK; +} + +/** + * @brief LPTimer Output Compare 2 configuration + * @param hlptim pointer to a LPTIM_HandleTypeDef structure that contains + * the configuration information for LPTIM module. + * @param sConfig The output configuration structure + * @retval None + */ +static HAL_StatusTypeDef LPTIM_OC2_SetConfig(LPTIM_HandleTypeDef *hlptim, const LPTIM_OC_ConfigTypeDef *sConfig) +{ + uint32_t tmpccmr1; + + tmpccmr1 = hlptim->Instance->CCMR1; + tmpccmr1 &= ~(LPTIM_CCMR1_CC2P_Msk | LPTIM_CCMR1_CC2SEL_Msk); + tmpccmr1 |= sConfig->OCPolarity << LPTIM_CCMR1_CC2P_Pos; + + /* Enable the Peripheral */ + __HAL_LPTIM_ENABLE(hlptim); + + /* Clear flag */ + __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_CMP2OK); + + /* Write to CCR2 register */ + __HAL_LPTIM_COMPARE_SET(hlptim, LPTIM_CHANNEL_2, sConfig->Pulse); + + /* Wait for the completion of the write operation to the LPTIM_CCR2 register */ + if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_CMP2OK) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Disable the Peripheral */ + __HAL_LPTIM_DISABLE(hlptim); + + /* Write to CCMR1 register */ + hlptim->Instance->CCMR1 = tmpccmr1; + + return HAL_OK; +} + +/** + * @brief LPTimer Input Capture 1 configuration + * @param hlptim pointer to a LPTIM_HandleTypeDef structure that contains + * the configuration information for LPTIM module. + * @param sConfig The input configuration structure + * @retval None + */ +static void LPTIM_IC1_SetConfig(LPTIM_HandleTypeDef *hlptim, const LPTIM_IC_ConfigTypeDef *sConfig) +{ + uint32_t tmpccmr1; + uint32_t tmpcfgr2; + + tmpccmr1 = hlptim->Instance->CCMR1; + tmpccmr1 &= ~(LPTIM_CCMR1_IC1PSC_Msk | LPTIM_CCMR1_CC1P_Msk | LPTIM_CCMR1_IC1F_Msk); + tmpccmr1 |= sConfig->ICPrescaler | + sConfig->ICPolarity | + sConfig->ICFilter | + LPTIM_CCMR1_CC1SEL; + + tmpcfgr2 = hlptim->Instance->CFGR2; + tmpcfgr2 &= ~(LPTIM_CFGR2_IC1SEL_Msk); + tmpcfgr2 |= sConfig->ICInputSource; + + /* Write to CCMR1 register */ + hlptim->Instance->CCMR1 = tmpccmr1; + + /* Write to CFGR2 register */ + hlptim->Instance->CFGR2 = tmpcfgr2; +} + +/** + * @brief LPTimer Input Capture 2 configuration + * @param hlptim pointer to a LPTIM_HandleTypeDef structure that contains + * the configuration information for LPTIM module. + * @param sConfig The input configuration structure + * @retval None + */ +static void LPTIM_IC2_SetConfig(LPTIM_HandleTypeDef *hlptim, const LPTIM_IC_ConfigTypeDef *sConfig) +{ + uint32_t tmpccmr1; + uint32_t tmpcfgr2; + + tmpccmr1 = hlptim->Instance->CCMR1; + tmpccmr1 &= ~(LPTIM_CCMR1_IC2PSC_Msk | LPTIM_CCMR1_CC2P_Msk | LPTIM_CCMR1_IC2F_Msk); + tmpccmr1 |= (sConfig->ICPrescaler << (LPTIM_CCMR1_IC2PSC_Pos - LPTIM_CCMR1_IC1PSC_Pos)) | + (sConfig->ICPolarity << (LPTIM_CCMR1_CC2P_Pos - LPTIM_CCMR1_CC1P_Pos)) | + (sConfig->ICFilter << (LPTIM_CCMR1_IC2F_Pos - LPTIM_CCMR1_IC1F_Pos)) | + LPTIM_CCMR1_CC2SEL; + + tmpcfgr2 = hlptim->Instance->CFGR2; + tmpcfgr2 &= ~(LPTIM_CFGR2_IC2SEL_Msk); + tmpcfgr2 |= sConfig->ICInputSource; + + /* Write to CCMR1 register */ + hlptim->Instance->CCMR1 = tmpccmr1; + + /* Write to CFGR2 register */ + hlptim->Instance->CFGR2 = tmpcfgr2; +} + +/** + * @brief Start the DMA data transfer. + * @param hdma DMA handle + * @param src The source memory Buffer address. + * @param dst The destination memory Buffer address. + * @param length The size of a source block transfer in byte. + * @retval HAL status + */ +HAL_StatusTypeDef LPTIM_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t src, uint32_t dst, + uint32_t length) +{ + HAL_StatusTypeDef status; + + /* Enable the DMA channel */ + if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hdma->LinkedListQueue != 0U) && (hdma->LinkedListQueue->Head != 0U)) + { + /* Enable the DMA channel */ + hdma->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = length; + hdma->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)src; + hdma->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)dst; + + status = HAL_DMAEx_List_Start_IT(hdma); + } + else + { + status = HAL_ERROR; + } + } + else + { + status = HAL_DMA_Start_IT(hdma, src, dst, length); + } + + return status; +} +/** + * @} + */ +#endif /* LPTIM1 || LPTIM2 || LPTIM3 || LPTIM4 || LPTIM5 || LPTIM6 */ + +#endif /* HAL_LPTIM_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_mmc.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_mmc.c new file mode 100644 index 0000000000..2b6c22cb98 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_mmc.c @@ -0,0 +1,4310 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_mmc.c + * @author MCD Application Team + * @brief MMC card HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Secure Digital (MMC) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + MMC card Control functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + This driver implements a high level communication layer for read and write from/to + this memory. The needed STM32 hardware resources (SDMMC and GPIO) are performed by + the user in HAL_MMC_MspInit() function (MSP layer). + Basically, the MSP layer configuration should be the same as we provide in the + examples. + You can easily tailor this configuration according to hardware resources. + + [..] + This driver is a generic layered driver for SDMMC memories which uses the HAL + SDMMC driver functions to interface with MMC and eMMC cards devices. + It is used as follows: + + (#)Initialize the SDMMC low level resources by implement the HAL_MMC_MspInit() API: + (##) Enable the SDMMC interface clock using __HAL_RCC_SDMMC_CLK_ENABLE(); + (##) SDMMC pins configuration for MMC card + (+++) Enable the clock for the SDMMC GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE(); + (+++) Configure these SDMMC pins as alternate function pull-up using HAL_GPIO_Init() + and according to your pin assignment; + (##) NVIC configuration if you need to use interrupt process (HAL_MMC_ReadBlocks_IT() + and HAL_MMC_WriteBlocks_IT() APIs). + (+++) Configure the SDMMC interrupt priorities using function HAL_NVIC_SetPriority(); + (+++) Enable the NVIC SDMMC IRQs using function HAL_NVIC_EnableIRQ() + (+++) SDMMC interrupts are managed using the macros __HAL_MMC_ENABLE_IT() + and __HAL_MMC_DISABLE_IT() inside the communication process. + (+++) SDMMC interrupts pending bits are managed using the macros __HAL_MMC_GET_IT() + and __HAL_MMC_CLEAR_IT() + (##) No general propose DMA Configuration is needed, an Internal DMA for SDMMC Peripheral are used. + + (#) At this stage, you can perform MMC read/write/erase operations after MMC card initialization + + + *** MMC Card Initialization and configuration *** + ================================================ + [..] + To initialize the MMC Card, use the HAL_MMC_Init() function. It Initializes + SDMMC Peripheral (STM32 side) and the MMC Card, and put it into StandBy State (Ready for data transfer). + This function provide the following operations: + + (#) Initialize the SDMMC peripheral interface with default configuration. + The initialization process is done at 400KHz. You can change or adapt + this frequency by adjusting the "ClockDiv" field. + The MMC Card frequency (SDMMC_CK) is computed as follows: + + SDMMC_CK = SDMMCCLK / (2 * ClockDiv) + + In initialization mode and according to the MMC Card standard, + make sure that the SDMMC_CK frequency doesn't exceed 400KHz. + + This phase of initialization is done through SDMMC_Init() and + SDMMC_PowerState_ON() SDMMC low level APIs. + + (#) Initialize the MMC card. The API used is HAL_MMC_InitCard(). + This phase allows the card initialization and identification + and check the MMC Card type (Standard Capacity or High Capacity) + The initialization flow is compatible with MMC standard. + + This API (HAL_MMC_InitCard()) could be used also to reinitialize the card in case + of plug-off plug-in. + + (#) Configure the MMC Card Data transfer frequency. By Default, the card transfer + frequency by adjusting the "ClockDiv" field. + In transfer mode and according to the MMC Card standard, make sure that the + SDMMC_CK frequency doesn't exceed 25MHz and 100MHz in High-speed mode switch. + + (#) Select the corresponding MMC Card according to the address read with the step 2. + + (#) Configure the MMC Card in wide bus mode: 4-bits data. + + *** MMC Card Read operation *** + ============================== + [..] + (+) You can read from MMC card in polling mode by using function HAL_MMC_ReadBlocks(). + This function support only 512-bytes block length (the block size should be + chosen as 512 bytes). + You can choose either one block read operation or multiple block read operation + by adjusting the "NumberOfBlocks" parameter. + After this, you have to ensure that the transfer is done correctly. The check is done + through HAL_MMC_GetCardState() function for MMC card state. + + (+) You can read from MMC card in DMA mode by using function HAL_MMC_ReadBlocks_DMA(). + This function support only 512-bytes block length (the block size should be + chosen as 512 bytes). + You can choose either one block read operation or multiple block read operation + by adjusting the "NumberOfBlocks" parameter. + After this, you have to ensure that the transfer is done correctly. The check is done + through HAL_MMC_GetCardState() function for MMC card state. + You could also check the DMA transfer process through the MMC Rx interrupt event. + + (+) You can read from MMC card in Interrupt mode by using function HAL_MMC_ReadBlocks_IT(). + This function allows the read of 512 bytes blocks. + You can choose either one block read operation or multiple block read operation + by adjusting the "NumberOfBlocks" parameter. + After this, you have to ensure that the transfer is done correctly. The check is done + through HAL_MMC_GetCardState() function for MMC card state. + You could also check the IT transfer process through the MMC Rx interrupt event. + + *** MMC Card Write operation *** + =============================== + [..] + (+) You can write to MMC card in polling mode by using function HAL_MMC_WriteBlocks(). + This function support only 512-bytes block length (the block size should be + chosen as 512 bytes). + You can choose either one block read operation or multiple block read operation + by adjusting the "NumberOfBlocks" parameter. + After this, you have to ensure that the transfer is done correctly. The check is done + through HAL_MMC_GetCardState() function for MMC card state. + + (+) You can write to MMC card in DMA mode by using function HAL_MMC_WriteBlocks_DMA(). + This function support only 512-bytes block length (the block size should be + chosen as 512 byte). + You can choose either one block read operation or multiple block read operation + by adjusting the "NumberOfBlocks" parameter. + After this, you have to ensure that the transfer is done correctly. The check is done + through HAL_MMC_GetCardState() function for MMC card state. + You could also check the DMA transfer process through the MMC Tx interrupt event. + + (+) You can write to MMC card in Interrupt mode by using function HAL_MMC_WriteBlocks_IT(). + This function allows the read of 512 bytes blocks. + You can choose either one block read operation or multiple block read operation + by adjusting the "NumberOfBlocks" parameter. + After this, you have to ensure that the transfer is done correctly. The check is done + through HAL_MMC_GetCardState() function for MMC card state. + You could also check the IT transfer process through the MMC Tx interrupt event. + + *** MMC card information *** + =========================== + [..] + (+) To get MMC card information, you can use the function HAL_MMC_GetCardInfo(). + It returns useful information about the MMC card such as block size, card type, + block number ... + + *** MMC card CSD register *** + ============================ + [..] + (+) The HAL_MMC_GetCardCSD() API allows to get the parameters of the CSD register. + Some of the CSD parameters are useful for card initialization and identification. + + *** MMC card CID register *** + ============================ + [..] + (+) The HAL_MMC_GetCardCID() API allows to get the parameters of the CID register. + Some of the CID parameters are useful for card initialization and identification. + + *** MMC HAL driver macros list *** + ================================== + [..] + Below the list of most used macros in MMC HAL driver. + + (+) __HAL_MMC_ENABLE_IT: Enable the MMC device interrupt + (+) __HAL_MMC_DISABLE_IT: Disable the MMC device interrupt + (+) __HAL_MMC_GET_FLAG:Check whether the specified MMC flag is set or not + (+) __HAL_MMC_CLEAR_FLAG: Clear the MMC's pending flags + + [..] + (@) You can refer to the MMC HAL driver header file for more useful macros + + *** Callback registration *** + ============================================= + [..] + The compilation define USE_HAL_MMC_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + + Use Functions HAL_MMC_RegisterCallback() to register a user callback, + it allows to register following callbacks: + (+) TxCpltCallback : callback when a transmission transfer is completed. + (+) RxCpltCallback : callback when a reception transfer is completed. + (+) ErrorCallback : callback when error occurs. + (+) AbortCpltCallback : callback when abort is completed. + (+) Read_DMALnkLstBufCpltCallback : callback when the DMA reception of linked list node buffer is completed. + (+) Write_DMALnkLstBufCpltCallback : callback when the DMA transmission of linked list node buffer is completed. + (+) MspInitCallback : MMC MspInit. + (+) MspDeInitCallback : MMC MspDeInit. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + + Use function HAL_MMC_UnRegisterCallback() to reset a callback to the default + weak (overridden) function. It allows to reset following callbacks: + (+) TxCpltCallback : callback when a transmission transfer is completed. + (+) RxCpltCallback : callback when a reception transfer is completed. + (+) ErrorCallback : callback when error occurs. + (+) AbortCpltCallback : callback when abort is completed. + (+) Read_DMADblBuf0CpltCallback : callback when the DMA reception of first buffer is completed. + (+) Read_DMADblBuf1CpltCallback : callback when the DMA reception of second buffer is completed. + (+) Write_DMADblBuf0CpltCallback : callback when the DMA transmission of first buffer is completed. + (+) Write_DMADblBuf1CpltCallback : callback when the DMA transmission of second buffer is completed. + (+) MspInitCallback : MMC MspInit. + (+) MspDeInitCallback : MMC MspDeInit. + This function) takes as parameters the HAL peripheral handle and the Callback ID. + + By default, after the HAL_MMC_Init and if the state is HAL_MMC_STATE_RESET + all callbacks are reset to the corresponding legacy weak (overridden) functions. + Exception done for MspInit and MspDeInit callbacks that are respectively + reset to the legacy weak (overridden) functions in the HAL_MMC_Init + and HAL_MMC_DeInit only when these callbacks are null (not registered beforehand). + If not, MspInit or MspDeInit are not null, the HAL_MMC_Init and HAL_MMC_DeInit + keep and use the user MspInit/MspDeInit callbacks (registered beforehand) + + Callbacks can be registered/unregistered in READY state only. + Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered + in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used + during the Init/DeInit. + In that case first register the MspInit/MspDeInit user callbacks + using HAL_MMC_RegisterCallback before calling HAL_MMC_DeInit + or HAL_MMC_Init function. + + When The compilation define USE_HAL_MMC_REGISTER_CALLBACKS is set to 0 or + not defined, the callback registering feature is not available + and weak (overridden) callbacks are used. + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup MMC MMC + * @brief MMC HAL module driver + * @{ + */ + +#if defined (SDMMC1) || defined (SDMMC2) +#ifdef HAL_MMC_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup MMC_Private_Defines + * @{ + */ +#if defined (VDD_VALUE) && (VDD_VALUE <= 1950U) +#define MMC_VOLTAGE_RANGE EMMC_LOW_VOLTAGE_RANGE + +#define MMC_EXT_CSD_PWR_CL_26_INDEX 201 +#define MMC_EXT_CSD_PWR_CL_52_INDEX 200 +#define MMC_EXT_CSD_PWR_CL_DDR_52_INDEX 238 + +#define MMC_EXT_CSD_PWR_CL_26_POS 8 +#define MMC_EXT_CSD_PWR_CL_52_POS 0 +#define MMC_EXT_CSD_PWR_CL_DDR_52_POS 16 +#else +#define MMC_VOLTAGE_RANGE EMMC_HIGH_VOLTAGE_RANGE + +#define MMC_EXT_CSD_PWR_CL_26_INDEX 203 +#define MMC_EXT_CSD_PWR_CL_52_INDEX 202 +#define MMC_EXT_CSD_PWR_CL_DDR_52_INDEX 239 + +#define MMC_EXT_CSD_PWR_CL_26_POS 24 +#define MMC_EXT_CSD_PWR_CL_52_POS 16 +#define MMC_EXT_CSD_PWR_CL_DDR_52_POS 24 +#endif /* (VDD_VALUE) && (VDD_VALUE <= 1950U)*/ + +#define MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_INDEX 216 +#define MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_POS 0 +#define MMC_EXT_CSD_S_A_TIMEOUT_INDEX 217 +#define MMC_EXT_CSD_S_A_TIMEOUT_POS 8 + +/* Frequencies used in the driver for clock divider calculation */ +#define MMC_INIT_FREQ 400000U /* Initialization phase : 400 kHz max */ +#define MMC_HIGH_SPEED_FREQ 52000000U /* High speed phase : 52 MHz max */ + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/** @defgroup MMC_Private_Functions MMC Private Functions + * @{ + */ +static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc); +static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc); +static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus); +static void MMC_PowerOFF(MMC_HandleTypeDef *hmmc); +static void MMC_Write_IT(MMC_HandleTypeDef *hmmc); +static void MMC_Read_IT(MMC_HandleTypeDef *hmmc); +static uint32_t MMC_HighSpeed(MMC_HandleTypeDef *hmmc, FunctionalState state); +static uint32_t MMC_DDR_Mode(MMC_HandleTypeDef *hmmc, FunctionalState state); +static HAL_StatusTypeDef MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData, uint16_t FieldIndex, + uint32_t Timeout); +static uint32_t MMC_PwrClassUpdate(MMC_HandleTypeDef *hmmc, uint32_t Wide, uint32_t Speed); + +/** + * @} + */ +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup MMC_Exported_Functions + * @{ + */ + +/** @addtogroup MMC_Exported_Functions_Group1 + * @brief Initialization and de-initialization functions + * +@verbatim + ============================================================================== + ##### Initialization and de-initialization functions ##### + ============================================================================== + [..] + This section provides functions allowing to initialize/de-initialize the MMC + card device to be ready for use. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the MMC according to the specified parameters in the + MMC_HandleTypeDef and create the associated handle. + * @param hmmc: Pointer to the MMC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMC_Init(MMC_HandleTypeDef *hmmc) +{ + /* Check the MMC handle allocation */ + if (hmmc == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_SDMMC_ALL_INSTANCE(hmmc->Instance)); + assert_param(IS_SDMMC_CLOCK_EDGE(hmmc->Init.ClockEdge)); + assert_param(IS_SDMMC_CLOCK_POWER_SAVE(hmmc->Init.ClockPowerSave)); + assert_param(IS_SDMMC_BUS_WIDE(hmmc->Init.BusWide)); + assert_param(IS_SDMMC_HARDWARE_FLOW_CONTROL(hmmc->Init.HardwareFlowControl)); + assert_param(IS_SDMMC_CLKDIV(hmmc->Init.ClockDiv)); + + if (hmmc->State == HAL_MMC_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hmmc->Lock = HAL_UNLOCKED; +#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) + /* Reset Callback pointers in HAL_MMC_STATE_RESET only */ + hmmc->TxCpltCallback = HAL_MMC_TxCpltCallback; + hmmc->RxCpltCallback = HAL_MMC_RxCpltCallback; + hmmc->ErrorCallback = HAL_MMC_ErrorCallback; + hmmc->AbortCpltCallback = HAL_MMC_AbortCallback; + hmmc->Read_DMALnkLstBufCpltCallback = HAL_MMCEx_Read_DMALnkLstBufCpltCallback; + hmmc->Write_DMALnkLstBufCpltCallback = HAL_MMCEx_Write_DMALnkLstBufCpltCallback; + + if (hmmc->MspInitCallback == NULL) + { + hmmc->MspInitCallback = HAL_MMC_MspInit; + } + + /* Init the low level hardware */ + hmmc->MspInitCallback(hmmc); +#else + /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ + HAL_MMC_MspInit(hmmc); +#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */ + } + + hmmc->State = HAL_MMC_STATE_BUSY; + + /* Initialize the Card parameters */ + if (HAL_MMC_InitCard(hmmc) == HAL_ERROR) + { + return HAL_ERROR; + } + + /* Initialize the error code */ + hmmc->ErrorCode = HAL_DMA_ERROR_NONE; + + /* Initialize the MMC operation */ + hmmc->Context = MMC_CONTEXT_NONE; + + /* Initialize the MMC state */ + hmmc->State = HAL_MMC_STATE_READY; + + /* Configure bus width */ + if (hmmc->Init.BusWide != SDMMC_BUS_WIDE_1B) + { + if (HAL_MMC_ConfigWideBusOperation(hmmc, hmmc->Init.BusWide) != HAL_OK) + { + return HAL_ERROR; + } + } + + return HAL_OK; +} + +/** + * @brief Initializes the MMC Card. + * @param hmmc: Pointer to MMC handle + * @note This function initializes the MMC card. It could be used when a card + re-initialization is needed. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMC_InitCard(MMC_HandleTypeDef *hmmc) +{ + uint32_t errorstate; + MMC_InitTypeDef Init; + uint32_t sdmmc_clk; + + /* Default SDMMC peripheral configuration for MMC card initialization */ + Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING; + Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE; + Init.BusWide = SDMMC_BUS_WIDE_1B; + Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE; + + /* Init Clock should be less or equal to 400Khz*/ + if (hmmc->Instance == SDMMC1) + { + sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC1); + } +#if defined (SDMMC2) + else if (hmmc->Instance == SDMMC2) + { + sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC2); + } +#endif /* SDMMC2 */ + else + { + sdmmc_clk = 0; + } + if (sdmmc_clk == 0U) + { + hmmc->State = HAL_MMC_STATE_READY; + hmmc->ErrorCode = SDMMC_ERROR_INVALID_PARAMETER; + return HAL_ERROR; + } + Init.ClockDiv = sdmmc_clk / (2U * MMC_INIT_FREQ); + +#if (USE_SD_TRANSCEIVER != 0U) + Init.TranceiverPresent = SDMMC_TRANSCEIVER_NOT_PRESENT; +#endif /* USE_SD_TRANSCEIVER */ + + /* Initialize SDMMC peripheral interface with default configuration */ + (void)SDMMC_Init(hmmc->Instance, Init); + + /* Set Power State to ON */ + (void)SDMMC_PowerState_ON(hmmc->Instance); + + /* wait 74 Cycles: required power up waiting time before starting + the MMC initialization sequence */ + if (Init.ClockDiv != 0U) + { + sdmmc_clk = sdmmc_clk / (2U * Init.ClockDiv); + } + + if (sdmmc_clk != 0U) + { + HAL_Delay(1U + (74U * 1000U / (sdmmc_clk))); + } + + /* Identify card operating voltage */ + errorstate = MMC_PowerON(hmmc); + if (errorstate != HAL_MMC_ERROR_NONE) + { + hmmc->State = HAL_MMC_STATE_READY; + hmmc->ErrorCode |= errorstate; + return HAL_ERROR; + } + + /* Card initialization */ + errorstate = MMC_InitCard(hmmc); + if (errorstate != HAL_MMC_ERROR_NONE) + { + hmmc->State = HAL_MMC_STATE_READY; + hmmc->ErrorCode |= errorstate; + return HAL_ERROR; + } + + /* Set Block Size for Card */ + errorstate = SDMMC_CmdBlockLength(hmmc->Instance, MMC_BLOCKSIZE); + if (errorstate != HAL_MMC_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= errorstate; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief De-Initializes the MMC card. + * @param hmmc: Pointer to MMC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMC_DeInit(MMC_HandleTypeDef *hmmc) +{ + /* Check the MMC handle allocation */ + if (hmmc == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_SDMMC_ALL_INSTANCE(hmmc->Instance)); + + hmmc->State = HAL_MMC_STATE_BUSY; + + /* Set MMC power state to off */ + MMC_PowerOFF(hmmc); + +#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) + if (hmmc->MspDeInitCallback == NULL) + { + hmmc->MspDeInitCallback = HAL_MMC_MspDeInit; + } + + /* DeInit the low level hardware */ + hmmc->MspDeInitCallback(hmmc); +#else + /* De-Initialize the MSP layer */ + HAL_MMC_MspDeInit(hmmc); +#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */ + + hmmc->ErrorCode = HAL_MMC_ERROR_NONE; + hmmc->State = HAL_MMC_STATE_RESET; + + return HAL_OK; +} + + +/** + * @brief Initializes the MMC MSP. + * @param hmmc: Pointer to MMC handle + * @retval None + */ +__weak void HAL_MMC_MspInit(MMC_HandleTypeDef *hmmc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hmmc); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_MMC_MspInit could be implemented in the user file + */ +} + +/** + * @brief De-Initialize MMC MSP. + * @param hmmc: Pointer to MMC handle + * @retval None + */ +__weak void HAL_MMC_MspDeInit(MMC_HandleTypeDef *hmmc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hmmc); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_MMC_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @addtogroup MMC_Exported_Functions_Group2 + * @brief Data transfer functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to manage the data + transfer from/to MMC card. + +@endverbatim + * @{ + */ + +/** + * @brief Reads block(s) from a specified address in a card. The Data transfer + * is managed by polling mode. + * @note This API should be followed by a check on the card state through + * HAL_MMC_GetCardState(). + * @param hmmc: Pointer to MMC handle + * @param pData: pointer to the buffer that will contain the received data + * @param BlockAdd: Block Address from where data is to be read + * @param NumberOfBlocks: Number of MMC blocks to read + * @param Timeout: Specify timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMC_ReadBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, + uint32_t NumberOfBlocks, + uint32_t Timeout) +{ + SDMMC_DataInitTypeDef config; + uint32_t errorstate; + uint32_t tickstart = HAL_GetTick(); + uint32_t count; + uint32_t data; + uint32_t dataremaining; + uint32_t add = BlockAdd; + uint8_t *tempbuff = pData; + + if (NULL == pData) + { + hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; + return HAL_ERROR; + } + + if (hmmc->State == HAL_MMC_STATE_READY) + { + hmmc->ErrorCode = HAL_MMC_ERROR_NONE; + + if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr)) + { + hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; + return HAL_ERROR; + } + + /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */ + if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) + & 0x000000FFU) != 0x0U) + { + if ((NumberOfBlocks % 8U) != 0U) + { + /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */ + hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR; + return HAL_ERROR; + } + + if ((BlockAdd % 8U) != 0U) + { + /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */ + hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED; + return HAL_ERROR; + } + } + + hmmc->State = HAL_MMC_STATE_BUSY; + + /* Initialize data control register */ + hmmc->Instance->DCTRL = 0U; + + if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD) + { + add *= MMC_BLOCKSIZE; + } + + /* Configure the MMC DPSM (Data Path State Machine) */ + config.DataTimeOut = SDMMC_DATATIMEOUT; + config.DataLength = NumberOfBlocks * MMC_BLOCKSIZE; + config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; + config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + config.DPSM = SDMMC_DPSM_DISABLE; + (void)SDMMC_ConfigData(hmmc->Instance, &config); + __SDMMC_CMDTRANS_ENABLE(hmmc->Instance); + + /* Read block(s) in polling mode */ + if (NumberOfBlocks > 1U) + { + hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK; + + /* Read Multi Block command */ + errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add); + } + else + { + hmmc->Context = MMC_CONTEXT_READ_SINGLE_BLOCK; + + /* Read Single Block command */ + errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add); + } + if (errorstate != HAL_MMC_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= errorstate; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + + /* Poll on SDMMC flags */ + dataremaining = config.DataLength; + while (!__HAL_MMC_GET_FLAG(hmmc, + SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND)) + { + if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= SDMMC_FIFO_SIZE)) + { + /* Read data from SDMMC Rx FIFO */ + for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++) + { + data = SDMMC_ReadFIFO(hmmc->Instance); + *tempbuff = (uint8_t)(data & 0xFFU); + tempbuff++; + *tempbuff = (uint8_t)((data >> 8U) & 0xFFU); + tempbuff++; + *tempbuff = (uint8_t)((data >> 16U) & 0xFFU); + tempbuff++; + *tempbuff = (uint8_t)((data >> 24U) & 0xFFU); + tempbuff++; + } + dataremaining -= SDMMC_FIFO_SIZE; + } + + if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U)) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_TIMEOUT; + } + } + __SDMMC_CMDTRANS_DISABLE(hmmc->Instance); + + /* Send stop transmission command in case of multiblock read */ + if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U)) + { + /* Send stop transmission command */ + errorstate = SDMMC_CmdStopTransfer(hmmc->Instance); + if (errorstate != HAL_MMC_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= errorstate; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + } + + /* Get error state */ + if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT)) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL)) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR)) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + else + { + /* Nothing to do */ + } + + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS); + + hmmc->State = HAL_MMC_STATE_READY; + + return HAL_OK; + } + else + { + hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY; + return HAL_ERROR; + } +} + +/** + * @brief Allows to write block(s) to a specified address in a card. The Data + * transfer is managed by polling mode. + * @note This API should be followed by a check on the card state through + * HAL_MMC_GetCardState(). + * @param hmmc: Pointer to MMC handle + * @param pData: pointer to the buffer that will contain the data to transmit + * @param BlockAdd: Block Address where data will be written + * @param NumberOfBlocks: Number of MMC blocks to write + * @param Timeout: Specify timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMC_WriteBlocks(MMC_HandleTypeDef *hmmc, const uint8_t *pData, uint32_t BlockAdd, + uint32_t NumberOfBlocks, uint32_t Timeout) +{ + SDMMC_DataInitTypeDef config; + uint32_t errorstate; + uint32_t tickstart = HAL_GetTick(); + uint32_t count; + uint32_t data; + uint32_t dataremaining; + uint32_t add = BlockAdd; + const uint8_t *tempbuff = pData; + + if (NULL == pData) + { + hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; + return HAL_ERROR; + } + + if (hmmc->State == HAL_MMC_STATE_READY) + { + hmmc->ErrorCode = HAL_MMC_ERROR_NONE; + + if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr)) + { + hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; + return HAL_ERROR; + } + + /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */ + if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U) + { + if ((NumberOfBlocks % 8U) != 0U) + { + /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */ + hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR; + return HAL_ERROR; + } + + if ((BlockAdd % 8U) != 0U) + { + /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */ + hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED; + return HAL_ERROR; + } + } + + hmmc->State = HAL_MMC_STATE_BUSY; + + /* Initialize data control register */ + hmmc->Instance->DCTRL = 0U; + + if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD) + { + add *= MMC_BLOCKSIZE; + } + + /* Configure the MMC DPSM (Data Path State Machine) */ + config.DataTimeOut = SDMMC_DATATIMEOUT; + config.DataLength = NumberOfBlocks * MMC_BLOCKSIZE; + config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; + config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD; + config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + config.DPSM = SDMMC_DPSM_DISABLE; + (void)SDMMC_ConfigData(hmmc->Instance, &config); + __SDMMC_CMDTRANS_ENABLE(hmmc->Instance); + + /* Write Blocks in Polling mode */ + if (NumberOfBlocks > 1U) + { + hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK; + + /* Write Multi Block command */ + errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add); + } + else + { + hmmc->Context = MMC_CONTEXT_WRITE_SINGLE_BLOCK; + + /* Write Single Block command */ + errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add); + } + if (errorstate != HAL_MMC_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= errorstate; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + + /* Write block(s) in polling mode */ + dataremaining = config.DataLength; + while (!__HAL_MMC_GET_FLAG(hmmc, + SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND)) + { + if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= SDMMC_FIFO_SIZE)) + { + /* Write data to SDMMC Tx FIFO */ + for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++) + { + data = (uint32_t)(*tempbuff); + tempbuff++; + data |= ((uint32_t)(*tempbuff) << 8U); + tempbuff++; + data |= ((uint32_t)(*tempbuff) << 16U); + tempbuff++; + data |= ((uint32_t)(*tempbuff) << 24U); + tempbuff++; + (void)SDMMC_WriteFIFO(hmmc->Instance, &data); + } + dataremaining -= SDMMC_FIFO_SIZE; + } + + if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U)) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= errorstate; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_TIMEOUT; + } + } + __SDMMC_CMDTRANS_DISABLE(hmmc->Instance); + + /* Send stop transmission command in case of multiblock write */ + if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U)) + { + /* Send stop transmission command */ + errorstate = SDMMC_CmdStopTransfer(hmmc->Instance); + if (errorstate != HAL_MMC_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= errorstate; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + } + + /* Get error state */ + if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT)) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL)) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR)) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + else + { + /* Nothing to do */ + } + + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS); + + hmmc->State = HAL_MMC_STATE_READY; + + return HAL_OK; + } + else + { + hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY; + return HAL_ERROR; + } +} + +/** + * @brief Reads block(s) from a specified address in a card. The Data transfer + * is managed in interrupt mode. + * @note This API should be followed by a check on the card state through + * HAL_MMC_GetCardState(). + * @note You could also check the IT transfer process through the MMC Rx + * interrupt event. + * @param hmmc: Pointer to MMC handle + * @param pData: Pointer to the buffer that will contain the received data + * @param BlockAdd: Block Address from where data is to be read + * @param NumberOfBlocks: Number of blocks to read. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, + uint32_t NumberOfBlocks) +{ + SDMMC_DataInitTypeDef config; + uint32_t errorstate; + uint32_t add = BlockAdd; + + if (NULL == pData) + { + hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; + return HAL_ERROR; + } + + if (hmmc->State == HAL_MMC_STATE_READY) + { + hmmc->ErrorCode = HAL_MMC_ERROR_NONE; + + if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr)) + { + hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; + return HAL_ERROR; + } + + /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */ + if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U) + { + if ((NumberOfBlocks % 8U) != 0U) + { + /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */ + hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR; + return HAL_ERROR; + } + + if ((BlockAdd % 8U) != 0U) + { + /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */ + hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED; + return HAL_ERROR; + } + } + + hmmc->State = HAL_MMC_STATE_BUSY; + + /* Initialize data control register */ + hmmc->Instance->DCTRL = 0U; + + hmmc->pRxBuffPtr = pData; + hmmc->RxXferSize = MMC_BLOCKSIZE * NumberOfBlocks; + + if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD) + { + add *= MMC_BLOCKSIZE; + } + + /* Configure the MMC DPSM (Data Path State Machine) */ + config.DataTimeOut = SDMMC_DATATIMEOUT; + config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks; + config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; + config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + config.DPSM = SDMMC_DPSM_DISABLE; + (void)SDMMC_ConfigData(hmmc->Instance, &config); + __SDMMC_CMDTRANS_ENABLE(hmmc->Instance); + + /* Read Blocks in IT mode */ + if (NumberOfBlocks > 1U) + { + hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_IT); + + /* Read Multi Block command */ + errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add); + } + else + { + hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_IT); + + /* Read Single Block command */ + errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add); + } + + if (errorstate != HAL_MMC_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= errorstate; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + + __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND | + SDMMC_FLAG_RXFIFOHF)); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Writes block(s) to a specified address in a card. The Data transfer + * is managed in interrupt mode. + * @note This API should be followed by a check on the card state through + * HAL_MMC_GetCardState(). + * @note You could also check the IT transfer process through the MMC Tx + * interrupt event. + * @param hmmc: Pointer to MMC handle + * @param pData: Pointer to the buffer that will contain the data to transmit + * @param BlockAdd: Block Address where data will be written + * @param NumberOfBlocks: Number of blocks to write + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef *hmmc, const uint8_t *pData, + uint32_t BlockAdd, uint32_t NumberOfBlocks) +{ + SDMMC_DataInitTypeDef config; + uint32_t errorstate; + uint32_t add = BlockAdd; + + if (NULL == pData) + { + hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; + return HAL_ERROR; + } + + if (hmmc->State == HAL_MMC_STATE_READY) + { + hmmc->ErrorCode = HAL_MMC_ERROR_NONE; + + if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr)) + { + hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; + return HAL_ERROR; + } + + /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */ + if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U) + { + if ((NumberOfBlocks % 8U) != 0U) + { + /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */ + hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR; + return HAL_ERROR; + } + + if ((BlockAdd % 8U) != 0U) + { + /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */ + hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED; + return HAL_ERROR; + } + } + + hmmc->State = HAL_MMC_STATE_BUSY; + + /* Initialize data control register */ + hmmc->Instance->DCTRL = 0U; + + hmmc->pTxBuffPtr = pData; + hmmc->TxXferSize = MMC_BLOCKSIZE * NumberOfBlocks; + + if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD) + { + add *= MMC_BLOCKSIZE; + } + + /* Configure the MMC DPSM (Data Path State Machine) */ + config.DataTimeOut = SDMMC_DATATIMEOUT; + config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks; + config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; + config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD; + config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + config.DPSM = SDMMC_DPSM_DISABLE; + (void)SDMMC_ConfigData(hmmc->Instance, &config); + + __SDMMC_CMDTRANS_ENABLE(hmmc->Instance); + + /* Write Blocks in Polling mode */ + if (NumberOfBlocks > 1U) + { + hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_IT); + + /* Write Multi Block command */ + errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add); + } + else + { + hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_IT); + + /* Write Single Block command */ + errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add); + } + if (errorstate != HAL_MMC_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= errorstate; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + + /* Enable transfer interrupts */ + __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND | + SDMMC_FLAG_TXFIFOHE)); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Reads block(s) from a specified address in a card. The Data transfer + * is managed by DMA mode. + * @note This API should be followed by a check on the card state through + * HAL_MMC_GetCardState(). + * @note You could also check the DMA transfer process through the MMC Rx + * interrupt event. + * @param hmmc: Pointer MMC handle + * @param pData: Pointer to the buffer that will contain the received data + * @param BlockAdd: Block Address from where data is to be read + * @param NumberOfBlocks: Number of blocks to read. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, + uint32_t NumberOfBlocks) +{ + SDMMC_DataInitTypeDef config; + uint32_t errorstate; + uint32_t add = BlockAdd; + + if (NULL == pData) + { + hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; + return HAL_ERROR; + } + + if (hmmc->State == HAL_MMC_STATE_READY) + { + hmmc->ErrorCode = HAL_DMA_ERROR_NONE; + + if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr)) + { + hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; + return HAL_ERROR; + } + + /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */ + if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U) + { + if ((NumberOfBlocks % 8U) != 0U) + { + /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */ + hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR; + return HAL_ERROR; + } + + if ((BlockAdd % 8U) != 0U) + { + /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */ + hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED; + return HAL_ERROR; + } + } + + hmmc->State = HAL_MMC_STATE_BUSY; + + /* Initialize data control register */ + hmmc->Instance->DCTRL = 0U; + + hmmc->pRxBuffPtr = pData; + hmmc->RxXferSize = MMC_BLOCKSIZE * NumberOfBlocks; + + if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD) + { + add *= MMC_BLOCKSIZE; + } + + /* Configure the MMC DPSM (Data Path State Machine) */ + config.DataTimeOut = SDMMC_DATATIMEOUT; + config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks; + config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; + config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + config.DPSM = SDMMC_DPSM_DISABLE; + (void)SDMMC_ConfigData(hmmc->Instance, &config); + + __SDMMC_CMDTRANS_ENABLE(hmmc->Instance); + hmmc->Instance->IDMABASER = (uint32_t) pData ; + hmmc->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_SINGLE_BUFF; + + /* Read Blocks in DMA mode */ + if (NumberOfBlocks > 1U) + { + hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA); + + /* Read Multi Block command */ + errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add); + } + else + { + hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_DMA); + + /* Read Single Block command */ + errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add); + } + if (errorstate != HAL_MMC_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode = errorstate; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + + /* Enable transfer interrupts */ + __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND)); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Writes block(s) to a specified address in a card. The Data transfer + * is managed by DMA mode. + * @note This API should be followed by a check on the card state through + * HAL_MMC_GetCardState(). + * @note You could also check the DMA transfer process through the MMC Tx + * interrupt event. + * @param hmmc: Pointer to MMC handle + * @param pData: Pointer to the buffer that will contain the data to transmit + * @param BlockAdd: Block Address where data will be written + * @param NumberOfBlocks: Number of blocks to write + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef *hmmc, const uint8_t *pData, + uint32_t BlockAdd, uint32_t NumberOfBlocks) +{ + SDMMC_DataInitTypeDef config; + uint32_t errorstate; + uint32_t add = BlockAdd; + + if (NULL == pData) + { + hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; + return HAL_ERROR; + } + + if (hmmc->State == HAL_MMC_STATE_READY) + { + hmmc->ErrorCode = HAL_MMC_ERROR_NONE; + + if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr)) + { + hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; + return HAL_ERROR; + } + + /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */ + if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U) + { + if ((NumberOfBlocks % 8U) != 0U) + { + /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */ + hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR; + return HAL_ERROR; + } + + if ((BlockAdd % 8U) != 0U) + { + /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */ + hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED; + return HAL_ERROR; + } + } + + hmmc->State = HAL_MMC_STATE_BUSY; + + /* Initialize data control register */ + hmmc->Instance->DCTRL = 0U; + + hmmc->pTxBuffPtr = pData; + hmmc->TxXferSize = MMC_BLOCKSIZE * NumberOfBlocks; + + if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD) + { + add *= MMC_BLOCKSIZE; + } + + /* Configure the MMC DPSM (Data Path State Machine) */ + config.DataTimeOut = SDMMC_DATATIMEOUT; + config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks; + config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; + config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD; + config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + config.DPSM = SDMMC_DPSM_DISABLE; + (void)SDMMC_ConfigData(hmmc->Instance, &config); + + __SDMMC_CMDTRANS_ENABLE(hmmc->Instance); + + hmmc->Instance->IDMABASER = (uint32_t) pData ; + hmmc->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_SINGLE_BUFF; + + /* Write Blocks in Polling mode */ + if (NumberOfBlocks > 1U) + { + hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_DMA); + + /* Write Multi Block command */ + errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add); + } + else + { + hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_DMA); + + /* Write Single Block command */ + errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add); + } + if (errorstate != HAL_MMC_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= errorstate; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + + /* Enable transfer interrupts */ + __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND)); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Erases the specified memory area of the given MMC card. + * @note This API should be followed by a check on the card state through + * HAL_MMC_GetCardState(). + * @param hmmc: Pointer to MMC handle + * @param BlockStartAdd: Start Block address + * @param BlockEndAdd: End Block address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMC_Erase(MMC_HandleTypeDef *hmmc, uint32_t BlockStartAdd, uint32_t BlockEndAdd) +{ + uint32_t errorstate; + uint32_t start_add = BlockStartAdd; + uint32_t end_add = BlockEndAdd; + + if (hmmc->State == HAL_MMC_STATE_READY) + { + hmmc->ErrorCode = HAL_MMC_ERROR_NONE; + + if (end_add < start_add) + { + hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; + return HAL_ERROR; + } + + if (end_add > (hmmc->MmcCard.LogBlockNbr)) + { + hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; + return HAL_ERROR; + } + + /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */ + if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) + & 0x000000FFU) != 0x0U) + { + if (((start_add % 8U) != 0U) || ((end_add % 8U) != 0U)) + { + /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */ + hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED; + return HAL_ERROR; + } + } + + hmmc->State = HAL_MMC_STATE_BUSY; + + /* Check if the card command class supports erase command */ + if (((hmmc->MmcCard.Class) & SDMMC_CCCC_ERASE) == 0U) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + + if ((SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + + if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD) + { + start_add *= MMC_BLOCKSIZE; + end_add *= MMC_BLOCKSIZE; + } + + /* Send CMD35 MMC_ERASE_GRP_START with argument as addr */ + errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, start_add); + if (errorstate != HAL_MMC_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= errorstate; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + + /* Send CMD36 MMC_ERASE_GRP_END with argument as addr */ + errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, end_add); + if (errorstate != HAL_MMC_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= errorstate; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + + /* Send CMD38 ERASE */ + errorstate = SDMMC_CmdErase(hmmc->Instance, 0UL); + if (errorstate != HAL_MMC_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= errorstate; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + + hmmc->State = HAL_MMC_STATE_READY; + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief This function handles MMC card interrupt request. + * @param hmmc: Pointer to MMC handle + * @retval None + */ +void HAL_MMC_IRQHandler(MMC_HandleTypeDef *hmmc) +{ + uint32_t errorstate; + uint32_t context = hmmc->Context; + + /* Check for SDMMC interrupt flags */ + if ((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) != RESET) && ((context & MMC_CONTEXT_IT) != 0U)) + { + MMC_Read_IT(hmmc); + } + + else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) != RESET) + { + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_DATAEND); + + __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | \ + SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR | SDMMC_IT_TXFIFOHE | \ + SDMMC_IT_RXFIFOHF); + + __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_IDMABTC); + __SDMMC_CMDTRANS_DISABLE(hmmc->Instance); + + if ((context & MMC_CONTEXT_DMA) != 0U) + { + hmmc->Instance->DLEN = 0; + hmmc->Instance->DCTRL = 0; + hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA ; + + /* Stop Transfer for Write Multi blocks or Read Multi blocks */ + if (((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)) + { + errorstate = SDMMC_CmdStopTransfer(hmmc->Instance); + if (errorstate != HAL_MMC_ERROR_NONE) + { + hmmc->ErrorCode |= errorstate; +#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) + hmmc->ErrorCallback(hmmc); +#else + HAL_MMC_ErrorCallback(hmmc); +#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */ + } + } + + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS); + + hmmc->State = HAL_MMC_STATE_READY; + if (((context & MMC_CONTEXT_WRITE_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)) + { +#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) + hmmc->TxCpltCallback(hmmc); +#else + HAL_MMC_TxCpltCallback(hmmc); +#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */ + } + if (((context & MMC_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U)) + { +#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) + hmmc->RxCpltCallback(hmmc); +#else + HAL_MMC_RxCpltCallback(hmmc); +#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */ + } + } + else if ((context & MMC_CONTEXT_IT) != 0U) + { + /* Stop Transfer for Write Multi blocks or Read Multi blocks */ + if (((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)) + { + errorstate = SDMMC_CmdStopTransfer(hmmc->Instance); + if (errorstate != HAL_MMC_ERROR_NONE) + { + hmmc->ErrorCode |= errorstate; +#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) + hmmc->ErrorCallback(hmmc); +#else + HAL_MMC_ErrorCallback(hmmc); +#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */ + } + } + + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS); + + hmmc->State = HAL_MMC_STATE_READY; + if (((context & MMC_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U)) + { +#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) + hmmc->RxCpltCallback(hmmc); +#else + HAL_MMC_RxCpltCallback(hmmc); +#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */ + } + else + { +#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) + hmmc->TxCpltCallback(hmmc); +#else + HAL_MMC_TxCpltCallback(hmmc); +#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */ + } + } + else + { + /* Nothing to do */ + } + } + + else if ((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) != RESET) && ((context & MMC_CONTEXT_IT) != 0U)) + { + MMC_Write_IT(hmmc); + } + + else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL | + SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_RXOVERR | SDMMC_FLAG_TXUNDERR) != RESET) + { + /* Set Error code */ + if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_DCRCFAIL) != RESET) + { + hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL; + } + if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_DTIMEOUT) != RESET) + { + hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT; + } + if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_RXOVERR) != RESET) + { + hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN; + } + if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_TXUNDERR) != RESET) + { + hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN; + } + + /* Clear All flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS); + + /* Disable all interrupts */ + __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | \ + SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR); + + __SDMMC_CMDTRANS_DISABLE(hmmc->Instance); + hmmc->Instance->DCTRL |= SDMMC_DCTRL_FIFORST; + hmmc->Instance->CMD |= SDMMC_CMD_CMDSTOP; + hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance); + hmmc->Instance->CMD &= ~(SDMMC_CMD_CMDSTOP); + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_DABORT); + + if ((context & MMC_CONTEXT_IT) != 0U) + { + /* Set the MMC state to ready to be able to start again the process */ + hmmc->State = HAL_MMC_STATE_READY; +#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) + hmmc->ErrorCallback(hmmc); +#else + HAL_MMC_ErrorCallback(hmmc); +#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */ + } + else if ((context & MMC_CONTEXT_DMA) != 0U) + { + if (hmmc->ErrorCode != HAL_MMC_ERROR_NONE) + { + /* Disable Internal DMA */ + __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_IDMABTC); + hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA; + + /* Set the MMC state to ready to be able to start again the process */ + hmmc->State = HAL_MMC_STATE_READY; +#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) + hmmc->ErrorCallback(hmmc); +#else + HAL_MMC_ErrorCallback(hmmc); +#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */ + } + } + else + { + /* Nothing to do */ + } + } + + else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_IDMABTC) != RESET) + { + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_IT_IDMABTC); + + if ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U) + { +#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) + hmmc->Write_DMALnkLstBufCpltCallback(hmmc); +#else + HAL_MMCEx_Write_DMALnkLstBufCpltCallback(hmmc); +#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */ + } + else /* MMC_CONTEXT_READ_MULTIPLE_BLOCK */ + { +#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) + hmmc->Read_DMALnkLstBufCpltCallback(hmmc); +#else + HAL_MMCEx_Read_DMALnkLstBufCpltCallback(hmmc); +#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */ + } + } + + else + { + /* Nothing to do */ + } +} + +/** + * @brief return the MMC state + * @param hmmc: Pointer to mmc handle + * @retval HAL state + */ +HAL_MMC_StateTypeDef HAL_MMC_GetState(const MMC_HandleTypeDef *hmmc) +{ + return hmmc->State; +} + +/** + * @brief Return the MMC error code + * @param hmmc : Pointer to a MMC_HandleTypeDef structure that contains + * the configuration information. + * @retval MMC Error Code + */ +uint32_t HAL_MMC_GetError(const MMC_HandleTypeDef *hmmc) +{ + return hmmc->ErrorCode; +} + +/** + * @brief Tx Transfer completed callbacks + * @param hmmc: Pointer to MMC handle + * @retval None + */ +__weak void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hmmc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_MMC_TxCpltCallback can be implemented in the user file + */ +} + +/** + * @brief Rx Transfer completed callbacks + * @param hmmc: Pointer MMC handle + * @retval None + */ +__weak void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hmmc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_MMC_RxCpltCallback can be implemented in the user file + */ +} + +/** + * @brief MMC error callbacks + * @param hmmc: Pointer MMC handle + * @retval None + */ +__weak void HAL_MMC_ErrorCallback(MMC_HandleTypeDef *hmmc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hmmc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_MMC_ErrorCallback can be implemented in the user file + */ +} + +/** + * @brief MMC Abort callbacks + * @param hmmc: Pointer MMC handle + * @retval None + */ +__weak void HAL_MMC_AbortCallback(MMC_HandleTypeDef *hmmc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hmmc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_MMC_AbortCallback can be implemented in the user file + */ +} + +#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) +/** + * @brief Register a User MMC Callback + * To be used instead of the weak (overridden) predefined callback + * @note The HAL_MMC_RegisterCallback() may be called before HAL_MMC_Init() in + * HAL_MMC_STATE_RESET to register callbacks for HAL_MMC_MSP_INIT_CB_ID + * and HAL_MMC_MSP_DEINIT_CB_ID. + * @param hmmc : MMC handle + * @param CallbackId : ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_MMC_TX_CPLT_CB_ID MMC Tx Complete Callback ID + * @arg @ref HAL_MMC_RX_CPLT_CB_ID MMC Rx Complete Callback ID + * @arg @ref HAL_MMC_ERROR_CB_ID MMC Error Callback ID + * @arg @ref HAL_MMC_ABORT_CB_ID MMC Abort Callback ID + * @arg @ref HAL_MMC_READ_DMA_LNKLST_BUF_CPLT_CB_ID MMC DMA Rx Linked List Node buffer Callback ID + * @arg @ref HAL_MMC_WRITE_DMA_LNKLST_BUF_CPLT_CB_ID MMC DMA Tx Linked List Node buffer Callback ID + * @arg @ref HAL_MMC_MSP_INIT_CB_ID MMC MspInit Callback ID + * @arg @ref HAL_MMC_MSP_DEINIT_CB_ID MMC MspDeInit Callback ID + * @param pCallback : pointer to the Callback function + * @retval status + */ +HAL_StatusTypeDef HAL_MMC_RegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId, + pMMC_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + + if (hmmc->State == HAL_MMC_STATE_READY) + { + switch (CallbackId) + { + case HAL_MMC_TX_CPLT_CB_ID : + hmmc->TxCpltCallback = pCallback; + break; + case HAL_MMC_RX_CPLT_CB_ID : + hmmc->RxCpltCallback = pCallback; + break; + case HAL_MMC_ERROR_CB_ID : + hmmc->ErrorCallback = pCallback; + break; + case HAL_MMC_ABORT_CB_ID : + hmmc->AbortCpltCallback = pCallback; + break; + case HAL_MMC_READ_DMA_LNKLST_BUF_CPLT_CB_ID : + hmmc->Read_DMALnkLstBufCpltCallback = pCallback; + break; + case HAL_MMC_WRITE_DMA_LNKLST_BUF_CPLT_CB_ID : + hmmc->Write_DMALnkLstBufCpltCallback = pCallback; + break; + case HAL_MMC_MSP_INIT_CB_ID : + hmmc->MspInitCallback = pCallback; + break; + case HAL_MMC_MSP_DEINIT_CB_ID : + hmmc->MspDeInitCallback = pCallback; + break; + default : + /* Update the error code */ + hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else if (hmmc->State == HAL_MMC_STATE_RESET) + { + switch (CallbackId) + { + case HAL_MMC_MSP_INIT_CB_ID : + hmmc->MspInitCallback = pCallback; + break; + case HAL_MMC_MSP_DEINIT_CB_ID : + hmmc->MspDeInitCallback = pCallback; + break; + default : + /* Update the error code */ + hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister a User MMC Callback + * MMC Callback is redirected to the weak (overridden) predefined callback + * @note The HAL_MMC_UnRegisterCallback() may be called before HAL_MMC_Init() in + * HAL_MMC_STATE_RESET to register callbacks for HAL_MMC_MSP_INIT_CB_ID + * and HAL_MMC_MSP_DEINIT_CB_ID. + * @param hmmc : MMC handle + * @param CallbackId : ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_MMC_TX_CPLT_CB_ID MMC Tx Complete Callback ID + * @arg @ref HAL_MMC_RX_CPLT_CB_ID MMC Rx Complete Callback ID + * @arg @ref HAL_MMC_ERROR_CB_ID MMC Error Callback ID + * @arg @ref HAL_MMC_ABORT_CB_ID MMC Abort Callback ID + * @arg @ref HAL_MMC_READ_DMA_LNKLST_BUF_CPLT_CB_ID MMC DMA Rx Linked List Node buffer Callback ID + * @arg @ref HAL_MMC_WRITE_DMA_LNKLST_BUF_CPLT_CB_ID MMC DMA Tx Linked List Node buffer Callback ID + * @arg @ref HAL_MMC_MSP_INIT_CB_ID MMC MspInit Callback ID + * @arg @ref HAL_MMC_MSP_DEINIT_CB_ID MMC MspDeInit Callback ID + * @retval status + */ +HAL_StatusTypeDef HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (hmmc->State == HAL_MMC_STATE_READY) + { + switch (CallbackId) + { + case HAL_MMC_TX_CPLT_CB_ID : + hmmc->TxCpltCallback = HAL_MMC_TxCpltCallback; + break; + case HAL_MMC_RX_CPLT_CB_ID : + hmmc->RxCpltCallback = HAL_MMC_RxCpltCallback; + break; + case HAL_MMC_ERROR_CB_ID : + hmmc->ErrorCallback = HAL_MMC_ErrorCallback; + break; + case HAL_MMC_ABORT_CB_ID : + hmmc->AbortCpltCallback = HAL_MMC_AbortCallback; + break; + case HAL_MMC_READ_DMA_LNKLST_BUF_CPLT_CB_ID : + hmmc->Read_DMALnkLstBufCpltCallback = HAL_MMCEx_Read_DMALnkLstBufCpltCallback; + break; + case HAL_MMC_WRITE_DMA_LNKLST_BUF_CPLT_CB_ID : + hmmc->Write_DMALnkLstBufCpltCallback = HAL_MMCEx_Write_DMALnkLstBufCpltCallback; + break; + case HAL_MMC_MSP_INIT_CB_ID : + hmmc->MspInitCallback = HAL_MMC_MspInit; + break; + case HAL_MMC_MSP_DEINIT_CB_ID : + hmmc->MspDeInitCallback = HAL_MMC_MspDeInit; + break; + default : + /* Update the error code */ + hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else if (hmmc->State == HAL_MMC_STATE_RESET) + { + switch (CallbackId) + { + case HAL_MMC_MSP_INIT_CB_ID : + hmmc->MspInitCallback = HAL_MMC_MspInit; + break; + case HAL_MMC_MSP_DEINIT_CB_ID : + hmmc->MspDeInitCallback = HAL_MMC_MspDeInit; + break; + default : + /* Update the error code */ + hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + } + + return status; +} +#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @addtogroup MMC_Exported_Functions_Group3 + * @brief management functions + * +@verbatim + ============================================================================== + ##### Peripheral Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control the MMC card + operations and get the related information + +@endverbatim + * @{ + */ + +/** + * @brief Returns information the information of the card which are stored on + * the CID register. + * @param hmmc: Pointer to MMC handle + * @param pCID: Pointer to a HAL_MMC_CIDTypedef structure that + * contains all CID register parameters + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMC_GetCardCID(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID) +{ + pCID->ManufacturerID = (uint8_t)((hmmc->CID[0] & 0xFF000000U) >> 24U); + + pCID->OEM_AppliID = (uint16_t)((hmmc->CID[0] & 0x00FFFF00U) >> 8U); + + pCID->ProdName1 = (((hmmc->CID[0] & 0x000000FFU) << 24U) | ((hmmc->CID[1] & 0xFFFFFF00U) >> 8U)); + + pCID->ProdName2 = (uint8_t)(hmmc->CID[1] & 0x000000FFU); + + pCID->ProdRev = (uint8_t)((hmmc->CID[2] & 0xFF000000U) >> 24U); + + pCID->ProdSN = (((hmmc->CID[2] & 0x00FFFFFFU) << 8U) | ((hmmc->CID[3] & 0xFF000000U) >> 24U)); + + pCID->Reserved1 = (uint8_t)((hmmc->CID[3] & 0x00F00000U) >> 20U); + + pCID->ManufactDate = (uint16_t)((hmmc->CID[3] & 0x000FFF00U) >> 8U); + + pCID->CID_CRC = (uint8_t)((hmmc->CID[3] & 0x000000FEU) >> 1U); + + pCID->Reserved2 = 1U; + + return HAL_OK; +} + +/** + * @brief Returns information the information of the card which are stored on + * the CSD register. + * @param hmmc: Pointer to MMC handle + * @param pCSD: Pointer to a HAL_MMC_CardCSDTypeDef structure that + * contains all CSD register parameters + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMC_GetCardCSD(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCSDTypeDef *pCSD) +{ + uint32_t block_nbr = 0; + + pCSD->CSDStruct = (uint8_t)((hmmc->CSD[0] & 0xC0000000U) >> 30U); + + pCSD->SysSpecVersion = (uint8_t)((hmmc->CSD[0] & 0x3C000000U) >> 26U); + + pCSD->Reserved1 = (uint8_t)((hmmc->CSD[0] & 0x03000000U) >> 24U); + + pCSD->TAAC = (uint8_t)((hmmc->CSD[0] & 0x00FF0000U) >> 16U); + + pCSD->NSAC = (uint8_t)((hmmc->CSD[0] & 0x0000FF00U) >> 8U); + + pCSD->MaxBusClkFrec = (uint8_t)(hmmc->CSD[0] & 0x000000FFU); + + pCSD->CardComdClasses = (uint16_t)((hmmc->CSD[1] & 0xFFF00000U) >> 20U); + + pCSD->RdBlockLen = (uint8_t)((hmmc->CSD[1] & 0x000F0000U) >> 16U); + + pCSD->PartBlockRead = (uint8_t)((hmmc->CSD[1] & 0x00008000U) >> 15U); + + pCSD->WrBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00004000U) >> 14U); + + pCSD->RdBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00002000U) >> 13U); + + pCSD->DSRImpl = (uint8_t)((hmmc->CSD[1] & 0x00001000U) >> 12U); + + pCSD->Reserved2 = 0U; /*!< Reserved */ + + if (MMC_ReadExtCSD(hmmc, &block_nbr, 212, 0x0FFFFFFFU) != HAL_OK) /* Field SEC_COUNT [215:212] */ + { + return HAL_ERROR; + } + + if (hmmc->MmcCard.CardType == MMC_LOW_CAPACITY_CARD) + { + pCSD->DeviceSize = (((hmmc->CSD[1] & 0x000003FFU) << 2U) | ((hmmc->CSD[2] & 0xC0000000U) >> 30U)); + + pCSD->MaxRdCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x38000000U) >> 27U); + + pCSD->MaxRdCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x07000000U) >> 24U); + + pCSD->MaxWrCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x00E00000U) >> 21U); + + pCSD->MaxWrCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x001C0000U) >> 18U); + + pCSD->DeviceSizeMul = (uint8_t)((hmmc->CSD[2] & 0x00038000U) >> 15U); + + hmmc->MmcCard.BlockNbr = (pCSD->DeviceSize + 1U) ; + hmmc->MmcCard.BlockNbr *= (1UL << ((pCSD->DeviceSizeMul & 0x07U) + 2U)); + hmmc->MmcCard.BlockSize = (1UL << (pCSD->RdBlockLen & 0x0FU)); + + hmmc->MmcCard.LogBlockNbr = (hmmc->MmcCard.BlockNbr) * ((hmmc->MmcCard.BlockSize) / MMC_BLOCKSIZE); + hmmc->MmcCard.LogBlockSize = MMC_BLOCKSIZE; + } + else if (hmmc->MmcCard.CardType == MMC_HIGH_CAPACITY_CARD) + { + hmmc->MmcCard.BlockNbr = block_nbr; + hmmc->MmcCard.LogBlockNbr = hmmc->MmcCard.BlockNbr; + hmmc->MmcCard.BlockSize = MMC_BLOCKSIZE; + hmmc->MmcCard.LogBlockSize = hmmc->MmcCard.BlockSize; + } + else + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + + pCSD->EraseGrSize = (uint8_t)((hmmc->CSD[2] & 0x00004000U) >> 14U); + + pCSD->EraseGrMul = (uint8_t)((hmmc->CSD[2] & 0x00003F80U) >> 7U); + + pCSD->WrProtectGrSize = (uint8_t)(hmmc->CSD[2] & 0x0000007FU); + + pCSD->WrProtectGrEnable = (uint8_t)((hmmc->CSD[3] & 0x80000000U) >> 31U); + + pCSD->ManDeflECC = (uint8_t)((hmmc->CSD[3] & 0x60000000U) >> 29U); + + pCSD->WrSpeedFact = (uint8_t)((hmmc->CSD[3] & 0x1C000000U) >> 26U); + + pCSD->MaxWrBlockLen = (uint8_t)((hmmc->CSD[3] & 0x03C00000U) >> 22U); + + pCSD->WriteBlockPaPartial = (uint8_t)((hmmc->CSD[3] & 0x00200000U) >> 21U); + + pCSD->Reserved3 = 0; + + pCSD->ContentProtectAppli = (uint8_t)((hmmc->CSD[3] & 0x00010000U) >> 16U); + + pCSD->FileFormatGroup = (uint8_t)((hmmc->CSD[3] & 0x00008000U) >> 15U); + + pCSD->CopyFlag = (uint8_t)((hmmc->CSD[3] & 0x00004000U) >> 14U); + + pCSD->PermWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00002000U) >> 13U); + + pCSD->TempWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00001000U) >> 12U); + + pCSD->FileFormat = (uint8_t)((hmmc->CSD[3] & 0x00000C00U) >> 10U); + + pCSD->ECC = (uint8_t)((hmmc->CSD[3] & 0x00000300U) >> 8U); + + pCSD->CSD_CRC = (uint8_t)((hmmc->CSD[3] & 0x000000FEU) >> 1U); + + pCSD->Reserved4 = 1; + + return HAL_OK; +} + +/** + * @brief Gets the MMC card info. + * @param hmmc: Pointer to MMC handle + * @param pCardInfo: Pointer to the HAL_MMC_CardInfoTypeDef structure that + * will contain the MMC card status information + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMC_GetCardInfo(MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo) +{ + pCardInfo->CardType = (uint32_t)(hmmc->MmcCard.CardType); + pCardInfo->Class = (uint32_t)(hmmc->MmcCard.Class); + pCardInfo->RelCardAdd = (uint32_t)(hmmc->MmcCard.RelCardAdd); + pCardInfo->BlockNbr = (uint32_t)(hmmc->MmcCard.BlockNbr); + pCardInfo->BlockSize = (uint32_t)(hmmc->MmcCard.BlockSize); + pCardInfo->LogBlockNbr = (uint32_t)(hmmc->MmcCard.LogBlockNbr); + pCardInfo->LogBlockSize = (uint32_t)(hmmc->MmcCard.LogBlockSize); + + return HAL_OK; +} + +/** + * @brief Returns information the information of the card which are stored on + * the Extended CSD register. + * @param hmmc Pointer to MMC handle + * @param pExtCSD Pointer to a memory area (512 bytes) that contains all + * Extended CSD register parameters + * @param Timeout Specify timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMC_GetCardExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pExtCSD, uint32_t Timeout) +{ + SDMMC_DataInitTypeDef config; + uint32_t errorstate; + uint32_t tickstart = HAL_GetTick(); + uint32_t count; + uint32_t *tmp_buf; + + if (NULL == pExtCSD) + { + hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; + return HAL_ERROR; + } + + if (hmmc->State == HAL_MMC_STATE_READY) + { + hmmc->ErrorCode = HAL_MMC_ERROR_NONE; + + hmmc->State = HAL_MMC_STATE_BUSY; + + /* Initialize data control register */ + hmmc->Instance->DCTRL = 0; + + /* Initiaize the destination pointer */ + tmp_buf = pExtCSD; + + /* Configure the MMC DPSM (Data Path State Machine) */ + config.DataTimeOut = SDMMC_DATATIMEOUT; + config.DataLength = MMC_BLOCKSIZE; + config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; + config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + config.DPSM = SDMMC_DPSM_DISABLE; + (void)SDMMC_ConfigData(hmmc->Instance, &config); + __SDMMC_CMDTRANS_ENABLE(hmmc->Instance); + + /* Send ExtCSD Read command to Card */ + errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0); + if (errorstate != HAL_MMC_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= errorstate; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + + /* Poll on SDMMC flags */ + while (!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR | + SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND)) + { + if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF)) + { + /* Read data from SDMMC Rx FIFO */ + for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++) + { + *tmp_buf = SDMMC_ReadFIFO(hmmc->Instance); + tmp_buf++; + } + } + + if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U)) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_TIMEOUT; + } + } + + __SDMMC_CMDTRANS_DISABLE(hmmc->Instance); + + /* Get error state */ + if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT)) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL)) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR)) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + else + { + /* Nothing to do */ + } + + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS); + hmmc->State = HAL_MMC_STATE_READY; + } + + return HAL_OK; +} + +/** + * @brief Enables wide bus operation for the requested card if supported by + * card. + * @param hmmc: Pointer to MMC handle + * @param WideMode: Specifies the MMC card wide bus mode + * This parameter can be one of the following values: + * @arg SDMMC_BUS_WIDE_8B: 8-bit data transfer + * @arg SDMMC_BUS_WIDE_4B: 4-bit data transfer + * @arg SDMMC_BUS_WIDE_1B: 1-bit data transfer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef *hmmc, uint32_t WideMode) +{ + uint32_t count; + SDMMC_InitTypeDef Init; + uint32_t errorstate; + uint32_t response = 0U; + + /* Check the parameters */ + assert_param(IS_SDMMC_BUS_WIDE(WideMode)); + + /* Change State */ + hmmc->State = HAL_MMC_STATE_BUSY; + + /* Check and update the power class if needed */ + if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U) + { + if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U) + { + errorstate = MMC_PwrClassUpdate(hmmc, WideMode, SDMMC_SPEED_MODE_DDR); + } + else + { + errorstate = MMC_PwrClassUpdate(hmmc, WideMode, SDMMC_SPEED_MODE_HIGH); + } + } + else + { + errorstate = MMC_PwrClassUpdate(hmmc, WideMode, SDMMC_SPEED_MODE_DEFAULT); + } + + if (errorstate == HAL_MMC_ERROR_NONE) + { + if (WideMode == SDMMC_BUS_WIDE_8B) + { + errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U); + } + else if (WideMode == SDMMC_BUS_WIDE_4B) + { + errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U); + } + else if (WideMode == SDMMC_BUS_WIDE_1B) + { + errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70000U); + } + else + { + /* WideMode is not a valid argument*/ + errorstate = HAL_MMC_ERROR_PARAM; + } + + /* Check for switch error and violation of the trial number of sending CMD 13 */ + if (errorstate == HAL_MMC_ERROR_NONE) + { + /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ + count = SDMMC_MAX_TRIAL; + do + { + errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); + if (errorstate != HAL_MMC_ERROR_NONE) + { + break; + } + + /* Get command response */ + response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1); + count--; + } while (((response & 0x100U) == 0U) && (count != 0U)); + + /* Check the status after the switch command execution */ + if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE)) + { + /* Check the bit SWITCH_ERROR of the device status */ + if ((response & 0x80U) != 0U) + { + errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR; + } + else + { + /* Configure the SDMMC peripheral */ + Init = hmmc->Init; + Init.BusWide = WideMode; + (void)SDMMC_Init(hmmc->Instance, Init); + } + } + else if (count == 0U) + { + errorstate = SDMMC_ERROR_TIMEOUT; + } + else + { + /* Nothing to do */ + } + } + } + + /* Change State */ + hmmc->State = HAL_MMC_STATE_READY; + + if (errorstate != HAL_MMC_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= errorstate; + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Configure the speed bus mode + * @param hmmc: Pointer to the MMC handle + * @param SpeedMode: Specifies the MMC card speed bus mode + * This parameter can be one of the following values: + * @arg SDMMC_SPEED_MODE_AUTO: Max speed mode supported by the card + * @arg SDMMC_SPEED_MODE_DEFAULT: Default Speed (MMC @ 26MHz) + * @arg SDMMC_SPEED_MODE_HIGH: High Speed (MMC @ 52 MHz) + * @arg SDMMC_SPEED_MODE_DDR: High Speed DDR (MMC DDR @ 52 MHz) + * @retval HAL status + */ + +HAL_StatusTypeDef HAL_MMC_ConfigSpeedBusOperation(MMC_HandleTypeDef *hmmc, uint32_t SpeedMode) +{ + uint32_t tickstart; + HAL_StatusTypeDef status = HAL_OK; + uint32_t device_type; + uint32_t errorstate; + + /* Check the parameters */ + assert_param(IS_SDMMC_SPEED_MODE(SpeedMode)); + + /* Change State */ + hmmc->State = HAL_MMC_STATE_BUSY; + + /* Field DEVICE_TYPE [196 = 49*4] of Extended CSD register */ + device_type = (hmmc->Ext_CSD[49] & 0x000000FFU); + + switch (SpeedMode) + { + case SDMMC_SPEED_MODE_AUTO: + { + if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS) != 0U) && ((device_type & 0x04U) != 0U)) + { + /* High Speed DDR mode allowed */ + errorstate = MMC_HighSpeed(hmmc, ENABLE); + if (errorstate != HAL_MMC_ERROR_NONE) + { + hmmc->ErrorCode |= errorstate; + } + else + { + if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_CLKDIV) != 0U) + { + /* DDR mode not supported with CLKDIV = 0 */ + errorstate = MMC_DDR_Mode(hmmc, ENABLE); + if (errorstate != HAL_MMC_ERROR_NONE) + { + hmmc->ErrorCode |= errorstate; + } + } + } + } + else if ((device_type & 0x02U) != 0U) + { + /* High Speed mode allowed */ + errorstate = MMC_HighSpeed(hmmc, ENABLE); + if (errorstate != HAL_MMC_ERROR_NONE) + { + hmmc->ErrorCode |= errorstate; + } + } + else + { + /* Nothing to do : keep current speed */ + } + break; + } + case SDMMC_SPEED_MODE_DDR: + { + if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS) != 0U) && ((device_type & 0x04U) != 0U)) + { + /* High Speed DDR mode allowed */ + errorstate = MMC_HighSpeed(hmmc, ENABLE); + if (errorstate != HAL_MMC_ERROR_NONE) + { + hmmc->ErrorCode |= errorstate; + } + else + { + if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_CLKDIV) != 0U) + { + /* DDR mode not supported with CLKDIV = 0 */ + errorstate = MMC_DDR_Mode(hmmc, ENABLE); + if (errorstate != HAL_MMC_ERROR_NONE) + { + hmmc->ErrorCode |= errorstate; + } + } + } + } + else + { + /* High Speed DDR mode not allowed */ + hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE; + status = HAL_ERROR; + } + break; + } + case SDMMC_SPEED_MODE_HIGH: + { + if ((device_type & 0x02U) != 0U) + { + /* High Speed mode allowed */ + errorstate = MMC_HighSpeed(hmmc, ENABLE); + if (errorstate != HAL_MMC_ERROR_NONE) + { + hmmc->ErrorCode |= errorstate; + } + } + else + { + /* High Speed mode not allowed */ + hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE; + status = HAL_ERROR; + } + break; + } + case SDMMC_SPEED_MODE_DEFAULT: + { + if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U) + { + /* High Speed DDR mode activated */ + errorstate = MMC_DDR_Mode(hmmc, DISABLE); + if (errorstate != HAL_MMC_ERROR_NONE) + { + hmmc->ErrorCode |= errorstate; + } + } + if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U) + { + /* High Speed mode activated */ + errorstate = MMC_HighSpeed(hmmc, DISABLE); + if (errorstate != HAL_MMC_ERROR_NONE) + { + hmmc->ErrorCode |= errorstate; + } + } + break; + } + default: + hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; + status = HAL_ERROR; + break; + } + + /* Verify that MMC card is ready to use after Speed mode switch*/ + tickstart = HAL_GetTick(); + while ((HAL_MMC_GetCardState(hmmc) != HAL_MMC_CARD_TRANSFER)) + { + if ((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT) + { + hmmc->ErrorCode = HAL_MMC_ERROR_TIMEOUT; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_TIMEOUT; + } + } + + /* Change State */ + hmmc->State = HAL_MMC_STATE_READY; + return status; +} + +/** + * @brief Gets the current mmc card data state. + * @param hmmc: pointer to MMC handle + * @retval Card state + */ +HAL_MMC_CardStateTypeDef HAL_MMC_GetCardState(MMC_HandleTypeDef *hmmc) +{ + uint32_t cardstate; + uint32_t errorstate; + uint32_t resp1 = 0U; + + errorstate = MMC_SendStatus(hmmc, &resp1); + if (errorstate != HAL_MMC_ERROR_NONE) + { + hmmc->ErrorCode |= errorstate; + } + + cardstate = ((resp1 >> 9U) & 0x0FU); + + return (HAL_MMC_CardStateTypeDef)cardstate; +} + +/** + * @brief Abort the current transfer and disable the MMC. + * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains + * the configuration information for MMC module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMC_Abort(MMC_HandleTypeDef *hmmc) +{ + uint32_t error_code; + uint32_t tickstart; + + if (hmmc->State == HAL_MMC_STATE_BUSY) + { + /* DIsable All interrupts */ + __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | \ + SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR); + __SDMMC_CMDTRANS_DISABLE(hmmc->Instance); + + /*we will send the CMD12 in all cases in order to stop the data transfers*/ + /*In case the data transfer just finished, the external memory will not respond + and will return HAL_MMC_ERROR_CMD_RSP_TIMEOUT*/ + /*In case the data transfer aborted , the external memory will respond and will return HAL_MMC_ERROR_NONE*/ + /*Other scenario will return HAL_ERROR*/ + + hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance); + error_code = hmmc->ErrorCode; + if ((error_code != HAL_MMC_ERROR_NONE) && (error_code != HAL_MMC_ERROR_CMD_RSP_TIMEOUT)) + { + return HAL_ERROR; + } + + tickstart = HAL_GetTick(); + if ((hmmc->Instance->DCTRL & SDMMC_DCTRL_DTDIR) == SDMMC_TRANSFER_DIR_TO_CARD) + { + if (hmmc->ErrorCode == HAL_MMC_ERROR_NONE) + { + while (!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DABORT | SDMMC_FLAG_BUSYD0END)) + { + if ((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT) + { + hmmc->ErrorCode = HAL_MMC_ERROR_TIMEOUT; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_TIMEOUT; + } + } + } + + if (hmmc->ErrorCode == HAL_MMC_ERROR_CMD_RSP_TIMEOUT) + { + while (!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND)) + { + if ((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT) + { + hmmc->ErrorCode = HAL_MMC_ERROR_TIMEOUT; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_TIMEOUT; + } + } + } + } + else if ((hmmc->Instance->DCTRL & SDMMC_DCTRL_DTDIR) == SDMMC_TRANSFER_DIR_TO_SDMMC) + { + while (!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DABORT | SDMMC_FLAG_DATAEND)) + { + if ((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT) + { + hmmc->ErrorCode = HAL_MMC_ERROR_TIMEOUT; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_TIMEOUT; + } + } + } + else + { + /* Nothing to do*/ + } + + /*The reason of all these while conditions previously is that we need to wait the SDMMC and clear + the appropriate flags that will be set depending of the abort/non abort of the memory */ + /*Not waiting the SDMMC flags will cause the next SDMMC_DISABLE_IDMA to not get cleared and will result + in next SDMMC read/write operation to fail */ + + /*SDMMC ready for clear data flags*/ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END); + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS); + /* If IDMA Context, disable Internal DMA */ + hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA; + + hmmc->State = HAL_MMC_STATE_READY; + + /* Initialize the MMC operation */ + hmmc->Context = MMC_CONTEXT_NONE; + } + return HAL_OK; +} +/** + * @brief Abort the current transfer and disable the MMC (IT mode). + * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains + * the configuration information for MMC module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMC_Abort_IT(MMC_HandleTypeDef *hmmc) +{ + HAL_MMC_CardStateTypeDef CardState; + + /* DIsable All interrupts */ + __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | \ + SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR); + + /* If IDMA Context, disable Internal DMA */ + hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA; + + /* Clear All flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS); + + CardState = HAL_MMC_GetCardState(hmmc); + hmmc->State = HAL_MMC_STATE_READY; + + if ((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING)) + { + hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance); + } + if (hmmc->ErrorCode != HAL_MMC_ERROR_NONE) + { + return HAL_ERROR; + } + else + { +#if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) + hmmc->AbortCpltCallback(hmmc); +#else + HAL_MMC_AbortCallback(hmmc); +#endif /* USE_HAL_MMC_REGISTER_CALLBACKS */ + } + + return HAL_OK; +} + +/** + * @brief Perform specific commands sequence for the different type of erase. + * @note This API should be followed by a check on the card state through + * HAL_MMC_GetCardState(). + * @param hmmc Pointer to MMC handle + * @param EraseType Specifies the type of erase to be performed + * This parameter can be one of the following values: + * @arg HAL_MMC_TRIM Erase the write blocks identified by CMD35 & 36 + * @arg HAL_MMC_ERASE Erase the erase groups identified by CMD35 & 36 + * @arg HAL_MMC_DISCARD Discard the write blocks identified by CMD35 & 36 + * @arg HAL_MMC_SECURE_ERASE Perform a secure purge according SRT on the erase groups identified + * by CMD35 & 36 + * @arg HAL_MMC_SECURE_TRIM_STEP1 Mark the write blocks identified by CMD35 & 36 for secure erase + * @arg HAL_MMC_SECURE_TRIM_STEP2 Perform a secure purge according SRT on the write blocks + * previously identified + * @param BlockStartAdd Start Block address + * @param BlockEndAdd End Block address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMC_EraseSequence(MMC_HandleTypeDef *hmmc, uint32_t EraseType, + uint32_t BlockStartAdd, uint32_t BlockEndAdd) +{ + uint32_t errorstate; + uint32_t start_add = BlockStartAdd; + uint32_t end_add = BlockEndAdd; + uint32_t tickstart = HAL_GetTick(); + + /* Check the erase type value is correct */ + assert_param(IS_MMC_ERASE_TYPE(EraseType)); + + /* Check the coherence between start and end address */ + if (end_add < start_add) + { + hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; + return HAL_ERROR; + } + + /* Check that the end address is not out of range of device memory */ + if (end_add > (hmmc->MmcCard.LogBlockNbr)) + { + hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; + return HAL_ERROR; + } + + /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */ + if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U) + { + if (((start_add % 8U) != 0U) || ((end_add % 8U) != 0U)) + { + /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */ + hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED; + return HAL_ERROR; + } + } + + /* Check if the card command class supports erase command */ + if (((hmmc->MmcCard.Class) & SDMMC_CCCC_ERASE) == 0U) + { + hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE; + return HAL_ERROR; + } + + /* Check the state of the driver */ + if (hmmc->State == HAL_MMC_STATE_READY) + { + /* Change State */ + hmmc->State = HAL_MMC_STATE_BUSY; + + /* Check that the card is not locked */ + if ((SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED) + { + hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + + /* In case of low capacity card, the address is not block number but bytes */ + if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD) + { + start_add *= MMC_BLOCKSIZE; + end_add *= MMC_BLOCKSIZE; + } + + /* Send CMD35 MMC_ERASE_GRP_START with start address as argument */ + errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, start_add); + if (errorstate == HAL_MMC_ERROR_NONE) + { + /* Send CMD36 MMC_ERASE_GRP_END with end address as argument */ + errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, end_add); + if (errorstate == HAL_MMC_ERROR_NONE) + { + /* Send CMD38 ERASE with erase type as argument */ + errorstate = SDMMC_CmdErase(hmmc->Instance, EraseType); + if (errorstate == HAL_MMC_ERROR_NONE) + { + if ((EraseType == HAL_MMC_SECURE_ERASE) || (EraseType == HAL_MMC_SECURE_TRIM_STEP2)) + { + /* Wait that the device is ready by checking the D0 line */ + while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE)) + { + if ((HAL_GetTick() - tickstart) >= SDMMC_MAXERASETIMEOUT) + { + errorstate = HAL_MMC_ERROR_TIMEOUT; + } + } + + /* Clear the flag corresponding to end D0 bus line */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END); + } + } + } + } + + /* Change State */ + hmmc->State = HAL_MMC_STATE_READY; + + /* Manage errors */ + if (errorstate != HAL_MMC_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= errorstate; + + if (errorstate != HAL_MMC_ERROR_TIMEOUT) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + else + { + return HAL_OK; + } + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Perform sanitize operation on the device. + * @note This API should be followed by a check on the card state through + * HAL_MMC_GetCardState(). + * @param hmmc Pointer to MMC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMC_Sanitize(MMC_HandleTypeDef *hmmc) +{ + uint32_t errorstate; + uint32_t response = 0U; + uint32_t count; + uint32_t tickstart = HAL_GetTick(); + + /* Check the state of the driver */ + if (hmmc->State == HAL_MMC_STATE_READY) + { + /* Change State */ + hmmc->State = HAL_MMC_STATE_BUSY; + + /* Index : 165 - Value : 0x01 */ + errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03A50100U); + if (errorstate == HAL_MMC_ERROR_NONE) + { + /* Wait that the device is ready by checking the D0 line */ + while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE)) + { + if ((HAL_GetTick() - tickstart) >= SDMMC_MAXERASETIMEOUT) + { + errorstate = HAL_MMC_ERROR_TIMEOUT; + } + } + + /* Clear the flag corresponding to end D0 bus line */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END); + + if (errorstate == HAL_MMC_ERROR_NONE) + { + /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ + count = SDMMC_MAX_TRIAL; + do + { + errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); + if (errorstate != HAL_MMC_ERROR_NONE) + { + break; + } + + /* Get command response */ + response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1); + count--; + } while (((response & 0x100U) == 0U) && (count != 0U)); + + /* Check the status after the switch command execution */ + if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE)) + { + /* Check the bit SWITCH_ERROR of the device status */ + if ((response & 0x80U) != 0U) + { + errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR; + } + } + else if (count == 0U) + { + errorstate = SDMMC_ERROR_TIMEOUT; + } + else + { + /* Nothing to do */ + } + } + } + + /* Change State */ + hmmc->State = HAL_MMC_STATE_READY; + + /* Manage errors */ + if (errorstate != HAL_MMC_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= errorstate; + + if (errorstate != HAL_MMC_ERROR_TIMEOUT) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + else + { + return HAL_OK; + } + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Configure the Secure Removal Type (SRT) in the Extended CSD register. + * @note This API should be followed by a check on the card state through + * HAL_MMC_GetCardState(). + * @param hmmc Pointer to MMC handle + * @param SRTMode Specifies the type of erase to be performed + * This parameter can be one of the following values: + * @arg HAL_MMC_SRT_ERASE Information removed by an erase + * @arg HAL_MMC_SRT_WRITE_CHAR_ERASE Information removed by an overwriting with a character + * followed by an erase + * @arg HAL_MMC_SRT_WRITE_CHAR_COMPL_RANDOM Information removed by an overwriting with a character, + * its complement then a random character + * @arg HAL_MMC_SRT_VENDOR_DEFINED Information removed using a vendor defined + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMC_ConfigSecRemovalType(MMC_HandleTypeDef *hmmc, uint32_t SRTMode) +{ + uint32_t srt; + uint32_t errorstate; + uint32_t response = 0U; + uint32_t count; + + /* Check the erase type value is correct */ + assert_param(IS_MMC_SRT_TYPE(SRTMode)); + + /* Check the state of the driver */ + if (hmmc->State == HAL_MMC_STATE_READY) + { + /* Get the supported values by the device */ + if (HAL_MMC_GetSupportedSecRemovalType(hmmc, &srt) == HAL_OK) + { + /* Change State */ + hmmc->State = HAL_MMC_STATE_BUSY; + + /* Check the value passed as parameter is supported by the device */ + if ((SRTMode & srt) != 0U) + { + /* Index : 16 - Value : SRTMode */ + srt |= ((POSITION_VAL(SRTMode)) << 4U); + errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03100000U | (srt << 8U))); + if (errorstate == HAL_MMC_ERROR_NONE) + { + /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ + count = SDMMC_MAX_TRIAL; + do + { + errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); + if (errorstate != HAL_MMC_ERROR_NONE) + { + break; + } + + /* Get command response */ + response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1); + count--; + } while (((response & 0x100U) == 0U) && (count != 0U)); + + /* Check the status after the switch command execution */ + if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE)) + { + /* Check the bit SWITCH_ERROR of the device status */ + if ((response & 0x80U) != 0U) + { + errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR; + } + } + else if (count == 0U) + { + errorstate = SDMMC_ERROR_TIMEOUT; + } + else + { + /* Nothing to do */ + } + } + } + else + { + errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE; + } + + /* Change State */ + hmmc->State = HAL_MMC_STATE_READY; + } + else + { + errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR; + } + + /* Manage errors */ + if (errorstate != HAL_MMC_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= errorstate; + return HAL_ERROR; + } + else + { + return HAL_OK; + } + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Gets the supported values of the the Secure Removal Type (SRT). + * @param hmmc pointer to MMC handle + * @param SupportedSRT pointer for supported SRT value + * This parameter is a bit field of the following values: + * @arg HAL_MMC_SRT_ERASE Information removed by an erase + * @arg HAL_MMC_SRT_WRITE_CHAR_ERASE Information removed by an overwriting with a character followed + * by an erase + * @arg HAL_MMC_SRT_WRITE_CHAR_COMPL_RANDOM Information removed by an overwriting with a character, + * its complement then a random character + * @arg HAL_MMC_SRT_VENDOR_DEFINED Information removed using a vendor defined + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMC_GetSupportedSecRemovalType(MMC_HandleTypeDef *hmmc, uint32_t *SupportedSRT) +{ + /* Check the state of the driver */ + if (hmmc->State == HAL_MMC_STATE_READY) + { + /* Change State */ + hmmc->State = HAL_MMC_STATE_BUSY; + + /* Read field SECURE_REMOVAL_TYPE [16 = 4*4] of the Extended CSD register */ + *SupportedSRT = (hmmc->Ext_CSD[4] & 0x0000000FU); /* Bits [3:0] of field 16 */ + + /* Change State */ + hmmc->State = HAL_MMC_STATE_READY; + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Switch the device from Standby State to Sleep State. + * @param hmmc pointer to MMC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMC_SleepDevice(MMC_HandleTypeDef *hmmc) +{ + uint32_t errorstate, + sleep_timeout, + timeout, + count, + response = 0U ; + uint32_t tickstart = HAL_GetTick(); + + /* Check the state of the driver */ + if (hmmc->State == HAL_MMC_STATE_READY) + { + /* Change State */ + hmmc->State = HAL_MMC_STATE_BUSY; + + /* Set the power-off notification to powered-on : Ext_CSD[34] = 1 */ + errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03220100U)); + if (errorstate == HAL_MMC_ERROR_NONE) + { + /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ + count = SDMMC_MAX_TRIAL; + do + { + errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); + if (errorstate != HAL_MMC_ERROR_NONE) + { + break; + } + + /* Get command response */ + response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1); + count--; + } while (((response & 0x100U) == 0U) && (count != 0U)); + + /* Check the status after the switch command execution */ + if (count == 0U) + { + errorstate = SDMMC_ERROR_TIMEOUT; + } + else if (errorstate == HAL_MMC_ERROR_NONE) + { + /* Check the bit SWITCH_ERROR of the device status */ + if ((response & 0x80U) != 0U) + { + errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE; + } + else + { + /* Set the power-off notification to sleep notification : Ext_CSD[34] = 4 */ + errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03220400U)); + if (errorstate == HAL_MMC_ERROR_NONE) + { + /* Field SLEEP_NOTIFICATION_TIME [216] */ + sleep_timeout = ((hmmc->Ext_CSD[(MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_INDEX / 4)] >> + MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_POS) & 0x000000FFU); + + /* Sleep/Awake Timeout = 10us * 2^SLEEP_NOTIFICATION_TIME */ + /* In HAL, the tick interrupt occurs each ms */ + if ((sleep_timeout == 0U) || (sleep_timeout > 0x17U)) + { + sleep_timeout = 0x17U; /* Max register value defined is 0x17 */ + } + timeout = (((1UL << sleep_timeout) / 100U) + 1U); + + /* Wait that the device is ready by checking the D0 line */ + while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE)) + { + if ((HAL_GetTick() - tickstart) >= timeout) + { + errorstate = SDMMC_ERROR_TIMEOUT; + } + } + + /* Clear the flag corresponding to end D0 bus line */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END); + + if (errorstate == HAL_MMC_ERROR_NONE) + { + /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ + count = SDMMC_MAX_TRIAL; + do + { + errorstate = SDMMC_CmdSendStatus(hmmc->Instance, + (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); + if (errorstate != HAL_MMC_ERROR_NONE) + { + break; + } + + /* Get command response */ + response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1); + count--; + } while (((response & 0x100U) == 0U) && (count != 0U)); + + /* Check the status after the switch command execution */ + if (count == 0U) + { + errorstate = SDMMC_ERROR_TIMEOUT; + } + else if (errorstate == HAL_MMC_ERROR_NONE) + { + /* Check the bit SWITCH_ERROR of the device status */ + if ((response & 0x80U) != 0U) + { + errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE; + } + else + { + /* Switch the device in stand-by mode */ + (void)SDMMC_CmdSelDesel(hmmc->Instance, 0U); + + /* Field S_A_TIEMOUT [217] */ + sleep_timeout = ((hmmc->Ext_CSD[(MMC_EXT_CSD_S_A_TIMEOUT_INDEX / 4)] >> + MMC_EXT_CSD_S_A_TIMEOUT_POS) & 0x000000FFU); + + /* Sleep/Awake Timeout = 100ns * 2^S_A_TIMEOUT */ + /* In HAL, the tick interrupt occurs each ms */ + if ((sleep_timeout == 0U) || (sleep_timeout > 0x17U)) + { + sleep_timeout = 0x17U; /* Max register value defined is 0x17 */ + } + timeout = (((1UL << sleep_timeout) / 10000U) + 1U); + + if (HAL_MMC_GetCardState(hmmc) == HAL_MMC_CARD_STANDBY) + { + /* Send CMD5 CMD_MMC_SLEEP_AWAKE with RCA and SLEEP as argument */ + errorstate = SDMMC_CmdSleepMmc(hmmc->Instance, + ((hmmc->MmcCard.RelCardAdd << 16U) | (0x1U << 15U))); + if (errorstate == HAL_MMC_ERROR_NONE) + { + /* Wait that the device is ready by checking the D0 line */ + while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE)) + { + if ((HAL_GetTick() - tickstart) >= timeout) + { + errorstate = SDMMC_ERROR_TIMEOUT; + } + } + + /* Clear the flag corresponding to end D0 bus line */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END); + } + } + else + { + errorstate = SDMMC_ERROR_REQUEST_NOT_APPLICABLE; + } + } + } + else + { + /* Nothing to do */ + } + } + } + } + } + else + { + /* Nothing to do */ + } + } + + /* Change State */ + hmmc->State = HAL_MMC_STATE_READY; + + /* Manage errors */ + if (errorstate != HAL_MMC_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= errorstate; + + if (errorstate != HAL_MMC_ERROR_TIMEOUT) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + else + { + return HAL_OK; + } + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Switch the device from Sleep State to Standby State. + * @param hmmc pointer to MMC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMC_AwakeDevice(MMC_HandleTypeDef *hmmc) +{ + uint32_t errorstate; + uint32_t sleep_timeout; + uint32_t timeout; + uint32_t count; + uint32_t response = 0U; + uint32_t tickstart = HAL_GetTick(); + + /* Check the state of the driver */ + if (hmmc->State == HAL_MMC_STATE_READY) + { + /* Change State */ + hmmc->State = HAL_MMC_STATE_BUSY; + + /* Field S_A_TIEMOUT [217] */ + sleep_timeout = ((hmmc->Ext_CSD[(MMC_EXT_CSD_S_A_TIMEOUT_INDEX / 4)] >> MMC_EXT_CSD_S_A_TIMEOUT_POS) & + 0x000000FFU); + + /* Sleep/Awake Timeout = 100ns * 2^S_A_TIMEOUT */ + /* In HAL, the tick interrupt occurs each ms */ + if ((sleep_timeout == 0U) || (sleep_timeout > 0x17U)) + { + sleep_timeout = 0x17U; /* Max register value defined is 0x17 */ + } + timeout = (((1UL << sleep_timeout) / 10000U) + 1U); + + /* Send CMD5 CMD_MMC_SLEEP_AWAKE with RCA and AWAKE as argument */ + errorstate = SDMMC_CmdSleepMmc(hmmc->Instance, (hmmc->MmcCard.RelCardAdd << 16U)); + if (errorstate == HAL_MMC_ERROR_NONE) + { + /* Wait that the device is ready by checking the D0 line */ + while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE)) + { + if ((HAL_GetTick() - tickstart) >= timeout) + { + errorstate = SDMMC_ERROR_TIMEOUT; + } + } + + /* Clear the flag corresponding to end D0 bus line */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END); + + if (errorstate == HAL_MMC_ERROR_NONE) + { + if (HAL_MMC_GetCardState(hmmc) == HAL_MMC_CARD_STANDBY) + { + /* Switch the device in transfer mode */ + errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (hmmc->MmcCard.RelCardAdd << 16U)); + if (errorstate == HAL_MMC_ERROR_NONE) + { + if (HAL_MMC_GetCardState(hmmc) == HAL_MMC_CARD_TRANSFER) + { + /* Set the power-off notification to powered-on : Ext_CSD[34] = 1 */ + errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03220100U)); + if (errorstate == HAL_MMC_ERROR_NONE) + { + /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ + count = SDMMC_MAX_TRIAL; + do + { + errorstate = SDMMC_CmdSendStatus(hmmc->Instance, + (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); + if (errorstate != HAL_MMC_ERROR_NONE) + { + break; + } + + /* Get command response */ + response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1); + count--; + } while (((response & 0x100U) == 0U) && (count != 0U)); + + /* Check the status after the switch command execution */ + if (count == 0U) + { + errorstate = SDMMC_ERROR_TIMEOUT; + } + else if (errorstate == HAL_MMC_ERROR_NONE) + { + /* Check the bit SWITCH_ERROR of the device status */ + if ((response & 0x80U) != 0U) + { + errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE; + } + } + else + { + /* NOthing to do */ + } + } + } + else + { + errorstate = SDMMC_ERROR_REQUEST_NOT_APPLICABLE; + } + } + } + else + { + errorstate = SDMMC_ERROR_REQUEST_NOT_APPLICABLE; + } + } + } + + /* Change State */ + hmmc->State = HAL_MMC_STATE_READY; + + /* Manage errors */ + if (errorstate != HAL_MMC_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= errorstate; + + if (errorstate != HAL_MMC_ERROR_TIMEOUT) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + else + { + return HAL_OK; + } + } + else + { + return HAL_BUSY; + } +} +/** + * @} + */ + +/** + * @} + */ + +/* Private function ----------------------------------------------------------*/ +/** @addtogroup MMC_Private_Functions + * @{ + */ + + +/** + * @brief Initializes the mmc card. + * @param hmmc: Pointer to MMC handle + * @retval MMC Card error state + */ +static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc) +{ + HAL_MMC_CardCSDTypeDef CSD; + uint32_t errorstate; + uint16_t mmc_rca = 2U; + MMC_InitTypeDef Init; + + /* Check the power State */ + if (SDMMC_GetPowerState(hmmc->Instance) == 0U) + { + /* Power off */ + return HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE; + } + + /* Send CMD2 ALL_SEND_CID */ + errorstate = SDMMC_CmdSendCID(hmmc->Instance); + if (errorstate != HAL_MMC_ERROR_NONE) + { + return errorstate; + } + else + { + /* Get Card identification number data */ + hmmc->CID[0U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1); + hmmc->CID[1U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2); + hmmc->CID[2U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP3); + hmmc->CID[3U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP4); + } + + /* Send CMD3 SET_REL_ADDR with RCA = 2 (should be greater than 1) */ + /* MMC Card publishes its RCA. */ + errorstate = SDMMC_CmdSetRelAddMmc(hmmc->Instance, mmc_rca); + if (errorstate != HAL_MMC_ERROR_NONE) + { + return errorstate; + } + + /* Get the MMC card RCA */ + hmmc->MmcCard.RelCardAdd = mmc_rca; + + /* Send CMD9 SEND_CSD with argument as card's RCA */ + errorstate = SDMMC_CmdSendCSD(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U)); + if (errorstate != HAL_MMC_ERROR_NONE) + { + return errorstate; + } + else + { + /* Get Card Specific Data */ + hmmc->CSD[0U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1); + hmmc->CSD[1U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2); + hmmc->CSD[2U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP3); + hmmc->CSD[3U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP4); + } + + /* Get the Card Class */ + hmmc->MmcCard.Class = (SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2) >> 20U); + + /* Select the Card */ + errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); + if (errorstate != HAL_MMC_ERROR_NONE) + { + return errorstate; + } + + /* Get CSD parameters */ + if (HAL_MMC_GetCardCSD(hmmc, &CSD) != HAL_OK) + { + return hmmc->ErrorCode; + } + + /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ + errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); + if (errorstate != HAL_MMC_ERROR_NONE) + { + hmmc->ErrorCode |= errorstate; + } + + + /* Get Extended CSD parameters */ + if (HAL_MMC_GetCardExtCSD(hmmc, hmmc->Ext_CSD, SDMMC_DATATIMEOUT) != HAL_OK) + { + return hmmc->ErrorCode; + } + + /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ + errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); + if (errorstate != HAL_MMC_ERROR_NONE) + { + hmmc->ErrorCode |= errorstate; + } + + /* Configure the SDMMC peripheral */ + Init = hmmc->Init; + Init.BusWide = SDMMC_BUS_WIDE_1B; + (void)SDMMC_Init(hmmc->Instance, Init); + + /* All cards are initialized */ + return HAL_MMC_ERROR_NONE; +} + +/** + * @brief Enquires cards about their operating voltage and configures clock + * controls and stores MMC information that will be needed in future + * in the MMC handle. + * @param hmmc: Pointer to MMC handle + * @retval error state + */ +static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc) +{ + __IO uint32_t count = 0U; + uint32_t response = 0U; + uint32_t validvoltage = 0U; + uint32_t errorstate; + + /* CMD0: GO_IDLE_STATE */ + errorstate = SDMMC_CmdGoIdleState(hmmc->Instance); + if (errorstate != HAL_MMC_ERROR_NONE) + { + return errorstate; + } + + while (validvoltage == 0U) + { + if (count++ == SDMMC_MAX_VOLT_TRIAL) + { + return HAL_MMC_ERROR_INVALID_VOLTRANGE; + } + + /* SEND CMD1 APP_CMD with voltage range as argument */ + errorstate = SDMMC_CmdOpCondition(hmmc->Instance, MMC_VOLTAGE_RANGE); + if (errorstate != HAL_MMC_ERROR_NONE) + { + return HAL_MMC_ERROR_UNSUPPORTED_FEATURE; + } + + /* Get command response */ + response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1); + + /* Get operating voltage*/ + validvoltage = (((response >> 31U) == 1U) ? 1U : 0U); + } + + /* When power routine is finished and command returns valid voltage */ + if (((response & (0xFF000000U)) >> 24) == 0xC0U) + { + hmmc->MmcCard.CardType = MMC_HIGH_CAPACITY_CARD; + } + else + { + hmmc->MmcCard.CardType = MMC_LOW_CAPACITY_CARD; + } + + return HAL_MMC_ERROR_NONE; +} + +/** + * @brief Turns the SDMMC output signals off. + * @param hmmc: Pointer to MMC handle + * @retval None + */ +static void MMC_PowerOFF(MMC_HandleTypeDef *hmmc) +{ + /* Set Power State to OFF */ + (void)SDMMC_PowerState_OFF(hmmc->Instance); +} + +/** + * @brief Returns the current card's status. + * @param hmmc: Pointer to MMC handle + * @param pCardStatus: pointer to the buffer that will contain the MMC card + * status (Card Status register) + * @retval error state + */ +static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus) +{ + uint32_t errorstate; + + if (pCardStatus == NULL) + { + return HAL_MMC_ERROR_PARAM; + } + + /* Send Status command */ + errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U)); + if (errorstate != HAL_MMC_ERROR_NONE) + { + return errorstate; + } + + /* Get MMC card status */ + *pCardStatus = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1); + + return HAL_MMC_ERROR_NONE; +} + +/** + * @brief Reads extended CSD register to get the sectors number of the device + * @param hmmc: Pointer to MMC handle + * @param pFieldData: Pointer to the read buffer + * @param FieldIndex: Index of the field to be read + * @param Timeout: Specify timeout value + * @retval HAL status + */ +static HAL_StatusTypeDef MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData, + uint16_t FieldIndex, uint32_t Timeout) +{ + SDMMC_DataInitTypeDef config; + uint32_t errorstate; + uint32_t tickstart = HAL_GetTick(); + uint32_t count; + uint32_t i = 0; + uint32_t tmp_data; + + hmmc->ErrorCode = HAL_MMC_ERROR_NONE; + + /* Initialize data control register */ + hmmc->Instance->DCTRL = 0; + + /* Configure the MMC DPSM (Data Path State Machine) */ + config.DataTimeOut = SDMMC_DATATIMEOUT; + config.DataLength = MMC_BLOCKSIZE; + config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; + config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + config.DPSM = SDMMC_DPSM_ENABLE; + (void)SDMMC_ConfigData(hmmc->Instance, &config); + + /* Set Block Size for Card */ + errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0); + if (errorstate != HAL_MMC_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= errorstate; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + + /* Poll on SDMMC flags */ + while (!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | + SDMMC_FLAG_DATAEND)) + { + if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF)) + { + /* Read data from SDMMC Rx FIFO */ + for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++) + { + tmp_data = SDMMC_ReadFIFO(hmmc->Instance); + /* eg : SEC_COUNT : FieldIndex = 212 => i+count = 53 */ + /* DEVICE_TYPE : FieldIndex = 196 => i+count = 49 */ + if ((i + count) == ((uint32_t)FieldIndex / 4U)) + { + *pFieldData = tmp_data; + } + } + i += 8U; + } + + if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U)) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_TIMEOUT; + } + } + + /* Get error state */ + if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT)) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL)) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR)) + { + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); + hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN; + hmmc->State = HAL_MMC_STATE_READY; + return HAL_ERROR; + } + else + { + /* Nothing to do */ + } + + /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ + errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16)); + if (errorstate != HAL_MMC_ERROR_NONE) + { + hmmc->ErrorCode |= errorstate; + } + + /* Clear all the static flags */ + __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS); + + hmmc->State = HAL_MMC_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Wrap up reading in non-blocking mode. + * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains + * the configuration information. + * @retval None + */ +static void MMC_Read_IT(MMC_HandleTypeDef *hmmc) +{ + uint32_t count; + uint32_t data; + uint8_t *tmp; + + tmp = hmmc->pRxBuffPtr; + + + if (hmmc->RxXferSize >= SDMMC_FIFO_SIZE) + { + /* Read data from SDMMC Rx FIFO */ + for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++) + { + data = SDMMC_ReadFIFO(hmmc->Instance); + *tmp = (uint8_t)(data & 0xFFU); + tmp++; + *tmp = (uint8_t)((data >> 8U) & 0xFFU); + tmp++; + *tmp = (uint8_t)((data >> 16U) & 0xFFU); + tmp++; + *tmp = (uint8_t)((data >> 24U) & 0xFFU); + tmp++; + } + + hmmc->pRxBuffPtr = tmp; + hmmc->RxXferSize -= SDMMC_FIFO_SIZE; + } +} + +/** + * @brief Wrap up writing in non-blocking mode. + * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains + * the configuration information. + * @retval None + */ +static void MMC_Write_IT(MMC_HandleTypeDef *hmmc) +{ + uint32_t count; + uint32_t data; + const uint8_t *tmp; + + tmp = hmmc->pTxBuffPtr; + + if (hmmc->TxXferSize >= SDMMC_FIFO_SIZE) + { + /* Write data to SDMMC Tx FIFO */ + for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++) + { + data = (uint32_t)(*tmp); + tmp++; + data |= ((uint32_t)(*tmp) << 8U); + tmp++; + data |= ((uint32_t)(*tmp) << 16U); + tmp++; + data |= ((uint32_t)(*tmp) << 24U); + tmp++; + (void)SDMMC_WriteFIFO(hmmc->Instance, &data); + } + + hmmc->pTxBuffPtr = tmp; + hmmc->TxXferSize -= SDMMC_FIFO_SIZE; + } +} + +/** + * @brief Switches the MMC card to high speed mode. + * @param hmmc: MMC handle + * @param state: State of high speed mode + * @retval MMC Card error state + */ +static uint32_t MMC_HighSpeed(MMC_HandleTypeDef *hmmc, FunctionalState state) +{ + uint32_t errorstate = HAL_MMC_ERROR_NONE; + uint32_t response = 0U; + uint32_t count; + uint32_t sdmmc_clk; + SDMMC_InitTypeDef Init; + + if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U) && (state == DISABLE)) + { + errorstate = MMC_PwrClassUpdate(hmmc, (hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS), SDMMC_SPEED_MODE_DEFAULT); + if (errorstate == HAL_MMC_ERROR_NONE) + { + /* Index : 185 - Value : 0 */ + errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B90000U); + } + } + + if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) == 0U) && (state != DISABLE)) + { + errorstate = MMC_PwrClassUpdate(hmmc, (hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS), SDMMC_SPEED_MODE_HIGH); + if (errorstate == HAL_MMC_ERROR_NONE) + { + /* Index : 185 - Value : 1 */ + errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B90100U); + } + } + + if (errorstate == HAL_MMC_ERROR_NONE) + { + /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ + count = SDMMC_MAX_TRIAL; + do + { + errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); + if (errorstate != HAL_MMC_ERROR_NONE) + { + break; + } + + /* Get command response */ + response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1); + count--; + } while (((response & 0x100U) == 0U) && (count != 0U)); + + /* Check the status after the switch command execution */ + if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE)) + { + /* Check the bit SWITCH_ERROR of the device status */ + if ((response & 0x80U) != 0U) + { + errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE; + } + else + { + /* Configure high speed */ + Init.ClockEdge = hmmc->Init.ClockEdge; + Init.ClockPowerSave = hmmc->Init.ClockPowerSave; + Init.BusWide = (hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS); + Init.HardwareFlowControl = hmmc->Init.HardwareFlowControl; + + if (state == DISABLE) + { + Init.ClockDiv = hmmc->Init.ClockDiv; + (void)SDMMC_Init(hmmc->Instance, Init); + + CLEAR_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_BUSSPEED); + } + else + { + /* High Speed Clock should be less or equal to 52MHz*/ + if (hmmc->Instance == SDMMC1) + { + sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC1); + } +#if defined (SDMMC2) + else if (hmmc->Instance == SDMMC2) + { + sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC2); + } +#endif /* SDMMC2 */ + else + { + sdmmc_clk = 0; + } + + if (sdmmc_clk == 0U) + { + errorstate = SDMMC_ERROR_INVALID_PARAMETER; + } + else + { + if (sdmmc_clk <= MMC_HIGH_SPEED_FREQ) + { + Init.ClockDiv = 0; + } + else + { + Init.ClockDiv = (sdmmc_clk / (2U * MMC_HIGH_SPEED_FREQ)) + 1U; + } + (void)SDMMC_Init(hmmc->Instance, Init); + + SET_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_BUSSPEED); + } + } + } + } + else if (count == 0U) + { + errorstate = SDMMC_ERROR_TIMEOUT; + } + else + { + /* Nothing to do */ + } + } + + return errorstate; +} + +/** + * @brief Switches the MMC card to Double Data Rate (DDR) mode. + * @param hmmc: MMC handle + * @param state: State of DDR mode + * @retval MMC Card error state + */ +static uint32_t MMC_DDR_Mode(MMC_HandleTypeDef *hmmc, FunctionalState state) +{ + uint32_t errorstate = HAL_MMC_ERROR_NONE; + uint32_t response = 0U; + uint32_t count; + + if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U) && (state == DISABLE)) + { + if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS_0) != 0U) + { + errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_4B, SDMMC_SPEED_MODE_HIGH); + if (errorstate == HAL_MMC_ERROR_NONE) + { + /* Index : 183 - Value : 1 */ + errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U); + } + } + else + { + errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_8B, SDMMC_SPEED_MODE_HIGH); + if (errorstate == HAL_MMC_ERROR_NONE) + { + /* Index : 183 - Value : 2 */ + errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U); + } + } + } + + if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) == 0U) && (state != DISABLE)) + { + if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS_0) != 0U) + { + errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_4B, SDMMC_SPEED_MODE_DDR); + if (errorstate == HAL_MMC_ERROR_NONE) + { + /* Index : 183 - Value : 5 */ + errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70500U); + } + } + else + { + errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_8B, SDMMC_SPEED_MODE_DDR); + if (errorstate == HAL_MMC_ERROR_NONE) + { + /* Index : 183 - Value : 6 */ + errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70600U); + } + } + } + + if (errorstate == HAL_MMC_ERROR_NONE) + { + /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ + count = SDMMC_MAX_TRIAL; + do + { + errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); + if (errorstate != HAL_MMC_ERROR_NONE) + { + break; + } + + /* Get command response */ + response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1); + count--; + } while (((response & 0x100U) == 0U) && (count != 0U)); + + /* Check the status after the switch command execution */ + if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE)) + { + /* Check the bit SWITCH_ERROR of the device status */ + if ((response & 0x80U) != 0U) + { + errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE; + } + else + { + /* Configure DDR mode */ + if (state == DISABLE) + { + CLEAR_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_DDR); + } + else + { + SET_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_DDR); + } + } + } + else if (count == 0U) + { + errorstate = SDMMC_ERROR_TIMEOUT; + } + else + { + /* Nothing to do */ + } + } + + return errorstate; +} + +/** + * @brief Update the power class of the device. + * @param hmmc MMC handle + * @param Wide Wide of MMC bus + * @param Speed Speed of the MMC bus + * @retval MMC Card error state + */ +static uint32_t MMC_PwrClassUpdate(MMC_HandleTypeDef *hmmc, uint32_t Wide, uint32_t Speed) +{ + uint32_t count; + uint32_t response = 0U; + uint32_t errorstate = HAL_MMC_ERROR_NONE; + uint32_t power_class; + uint32_t supported_pwr_class; + + if ((Wide == SDMMC_BUS_WIDE_8B) || (Wide == SDMMC_BUS_WIDE_4B)) + { + power_class = 0U; /* Default value after power-on or software reset */ + + /* Read the PowerClass field of the Extended CSD register */ + if (MMC_ReadExtCSD(hmmc, &power_class, 187, SDMMC_DATATIMEOUT) != HAL_OK) /* Field POWER_CLASS [187] */ + { + errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR; + } + else + { + power_class = ((power_class >> 24U) & 0x000000FFU); + } + + /* Get the supported PowerClass field of the Extended CSD register */ + if (Speed == SDMMC_SPEED_MODE_DDR) + { + /* Field PWR_CL_DDR_52_xxx [238 or 239] */ + supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_DDR_52_INDEX / 4)] >> MMC_EXT_CSD_PWR_CL_DDR_52_POS) & + 0x000000FFU); + } + else if (Speed == SDMMC_SPEED_MODE_HIGH) + { + /* Field PWR_CL_52_xxx [200 or 202] */ + supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_52_INDEX / 4)] >> MMC_EXT_CSD_PWR_CL_52_POS) & + 0x000000FFU); + } + else + { + /* Field PWR_CL_26_xxx [201 or 203] */ + supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_26_INDEX / 4)] >> MMC_EXT_CSD_PWR_CL_26_POS) & + 0x000000FFU); + } + + if (errorstate == HAL_MMC_ERROR_NONE) + { + if (Wide == SDMMC_BUS_WIDE_8B) + { + /* Bit [7:4]: power class for 8-bits bus configuration - Bit [3:0]: power class for 4-bits bus configuration */ + supported_pwr_class = (supported_pwr_class >> 4U); + } + + if ((power_class & 0x0FU) != (supported_pwr_class & 0x0FU)) + { + /* Need to change current power class */ + errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03BB0000U | ((supported_pwr_class & 0x0FU) << 8U))); + + if (errorstate == HAL_MMC_ERROR_NONE) + { + /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ + count = SDMMC_MAX_TRIAL; + do + { + errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); + if (errorstate != HAL_MMC_ERROR_NONE) + { + break; + } + + /* Get command response */ + response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1); + count--; + } while (((response & 0x100U) == 0U) && (count != 0U)); + + /* Check the status after the switch command execution */ + if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE)) + { + /* Check the bit SWITCH_ERROR of the device status */ + if ((response & 0x80U) != 0U) + { + errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE; + } + } + else if (count == 0U) + { + errorstate = SDMMC_ERROR_TIMEOUT; + } + else + { + /* Nothing to do */ + } + } + } + } + } + + return errorstate; +} + +/** + * @brief Read DMA Linked list node Transfer completed callbacks + * @param hmmc: MMC handle + * @retval None + */ +__weak void HAL_MMCEx_Read_DMALnkLstBufCpltCallback(MMC_HandleTypeDef *hmmc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hmmc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_MMCEx_Read_DMALnkLstBufCpltCallback can be implemented in the user file + */ +} +/** + * @brief Read DMA Linked list node Transfer completed callbacks + * @param hmmc: MMC handle + * @retval None + */ +__weak void HAL_MMCEx_Write_DMALnkLstBufCpltCallback(MMC_HandleTypeDef *hmmc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hmmc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_MMCEx_Write_DMALnkLstBufCpltCallback can be implemented in the user file + */ +} + +/** + * @} + */ + +#endif /* HAL_MMC_MODULE_ENABLED */ +#endif /* SDMMC1 || SDMMC2 */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_mmc_ex.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_mmc_ex.c new file mode 100644 index 0000000000..a40a12bfee --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_mmc_ex.c @@ -0,0 +1,448 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_mmc_ex.c + * @author MCD Application Team + * @brief MMC card Extended HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Secure Digital (MMC) peripheral: + * + Extended features functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The MMC Extension HAL driver can be used as follows: + (+) Configure Buffer0 and Buffer1 start address and Buffer size using HAL_MMCEx_ConfigDMAMultiBuffer() function. + + (+) Start Read and Write for multibuffer mode using HAL_MMCEx_ReadBlocksDMAMultiBuffer() and + HAL_MMCEx_WriteBlocksDMAMultiBuffer() functions. + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup MMCEx MMCEx + * @brief MMC Extended HAL module driver + * @{ + */ + +#if defined (SDMMC1) || defined (SDMMC2) +#ifdef HAL_MMC_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup MMCEx_Exported_Functions + * @{ + */ + + + +/** @addtogroup MMCEx_Exported_Functions_Group1 + * @brief Linked List management functions + * +@verbatim + =============================================================================== + ##### Linked List management functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the needed functions. + +@endverbatim + * @{ + */ + +/** + * @brief Build Linked List node. + * @param pNode: Pointer to new node to add. + * @param pNodeConf: Pointer to configuration parameters for new node to add. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMCEx_DMALinkedList_BuildNode(MMC_DMALinkNodeTypeDef *pNode, + MMC_DMALinkNodeConfTypeDef *pNodeConf) +{ + + if (SDMMC_DMALinkedList_BuildNode(pNode, pNodeConf) != SDMMC_ERROR_NONE) + { + return (HAL_ERROR); + } + else + { + return (HAL_OK); + } + +} +/** + * @brief Insert Linked List node. + * @param pLinkedList: Pointer to the linkedlist that contains transfer nodes + * @param pPrevNode: Pointer to previous node. + * @param pNewNode: Pointer to new node to insert. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMCEx_DMALinkedList_InsertNode(MMC_DMALinkedListTypeDef *pLinkedList, + MMC_DMALinkNodeTypeDef *pPrevNode, + MMC_DMALinkNodeTypeDef *pNewNode) +{ + + if (SDMMC_DMALinkedList_InsertNode(pLinkedList, pPrevNode, pNewNode) != SDMMC_ERROR_NONE) + { + return (HAL_ERROR); + } + else + { + return (HAL_OK); + } + +} +/** + * @brief Remove Linked List node. + * @param pLinkedList: Pointer to the linkedlist that contains transfer nodes + * @param pNode: Pointer to node to remove. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMCEx_DMALinkedList_RemoveNode(MMC_DMALinkedListTypeDef *pLinkedList, + MMC_DMALinkNodeTypeDef *pNode) +{ + + if (SDMMC_DMALinkedList_RemoveNode(pLinkedList, pNode) != SDMMC_ERROR_NONE) + { + return (HAL_ERROR); + } + else + { + return (HAL_OK); + } +} + +/** + * @brief Lock Linked List node. + * @param pNode: Pointer to node to remove. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMCEx_DMALinkedList_LockNode(MMC_DMALinkNodeTypeDef *pNode) +{ + + if (SDMMC_DMALinkedList_LockNode(pNode) != SDMMC_ERROR_NONE) + { + return HAL_ERROR; + } + else + { + return HAL_OK; + } +} + +/** + * @brief Unlock Linked List node. + * @param pNode: Pointer to node to remove. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMCEx_DMALinkedList_UnlockNode(MMC_DMALinkNodeTypeDef *pNode) +{ + + if (SDMMC_DMALinkedList_UnlockNode(pNode) != SDMMC_ERROR_NONE) + { + return HAL_ERROR; + } + else + { + return HAL_OK; + } +} + +/** + * @brief Enable Circular mode for DMA Linked List mode. + * @param pLinkedList: Pointer to the linkedlist that contains transfer nodes + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMCEx_DMALinkedList_EnableCircularMode(MMC_DMALinkedListTypeDef *pLinkedList) +{ + + if (SDMMC_DMALinkedList_EnableCircularMode(pLinkedList) != SDMMC_ERROR_NONE) + { + return HAL_ERROR; + } + else + { + return HAL_OK; + } +} +/** + * @brief Disable Circular mode for DMA Linked List mode. + * @param pLinkedList: Pointer to the linkedlist that contains transfer nodes + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMCEx_DMALinkedList_DisableCircularMode(MMC_DMALinkedListTypeDef *pLinkedList) +{ + + if (SDMMC_DMALinkedList_DisableCircularMode(pLinkedList) != SDMMC_ERROR_NONE) + { + return HAL_ERROR; + } + else + { + return HAL_OK; + } +} + + +/** + * @brief Reads block(s) from a specified address in a card. The received Data will be stored in linked list buffers. + * linked list should be prepared before call this function . + * @param hmmc: MMC handle + * @param pLinkedList: pointer to first linked list node + * @param BlockAdd: Block Address from where data is to be read + * @param NumberOfBlocks: Total number of blocks to read + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMCEx_DMALinkedList_ReadBlocks(MMC_HandleTypeDef *hmmc, MMC_DMALinkedListTypeDef *pLinkedList, + uint32_t BlockAdd, uint32_t NumberOfBlocks) +{ + SDMMC_DataInitTypeDef config; + uint32_t DmaBase0_reg; + uint32_t DmaBase1_reg; + uint32_t errorstate; + uint32_t add = BlockAdd; + + if (hmmc->State == HAL_MMC_STATE_READY) + { + if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr)) + { + hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; + return HAL_ERROR; + } + + /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */ + if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U) + { + if ((NumberOfBlocks % 8U) != 0U) + { + /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */ + hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR; + return HAL_ERROR; + } + + if ((BlockAdd % 8U) != 0U) + { + /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */ + hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED; + return HAL_ERROR; + } + } + + hmmc->Instance->IDMABASER = (uint32_t) pLinkedList->pHeadNode->IDMABASER; + hmmc->Instance->IDMABSIZE = (uint32_t) pLinkedList->pHeadNode->IDMABSIZE; + hmmc->Instance->IDMABAR = (uint32_t) pLinkedList->pHeadNode; + hmmc->Instance->IDMALAR = (uint32_t) SDMMC_IDMALAR_ABR | SDMMC_IDMALAR_ULS | SDMMC_IDMALAR_ULA | + sizeof(SDMMC_DMALinkNodeTypeDef) ; /* Initial configuration */ + + DmaBase0_reg = hmmc->Instance->IDMABASER; + DmaBase1_reg = hmmc->Instance->IDMABAR; + + if ((hmmc->Instance->IDMABSIZE == 0U) || (DmaBase0_reg == 0U) || (DmaBase1_reg == 0U)) + { + hmmc->ErrorCode = HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; + return HAL_ERROR; + } + + /* Initialize data control register */ + hmmc->Instance->DCTRL = 0; + + hmmc->ErrorCode = HAL_MMC_ERROR_NONE; + hmmc->State = HAL_MMC_STATE_BUSY; + + if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD) + { + add *= 512U; + } + + /* Configure the MMC DPSM (Data Path State Machine) */ + config.DataTimeOut = SDMMC_DATATIMEOUT; + config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks; + config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; + config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + config.DPSM = SDMMC_DPSM_DISABLE; + (void)SDMMC_ConfigData(hmmc->Instance, &config); + + hmmc->Instance->DCTRL |= SDMMC_DCTRL_FIFORST; + + __SDMMC_CMDTRANS_ENABLE(hmmc->Instance); + + hmmc->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_DOUBLE_BUFF0; + + /* Read Blocks in DMA mode */ + hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA); + + /* Read Multi Block command */ + errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add); + if (errorstate != HAL_MMC_ERROR_NONE) + { + hmmc->State = HAL_MMC_STATE_READY; + hmmc->ErrorCode |= errorstate; + return HAL_ERROR; + } + + __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND | + SDMMC_FLAG_IDMATE | SDMMC_FLAG_IDMABTC)); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } + +} + +/** + * @brief Write block(s) to a specified address in a card. The transferred Data are stored linked list nodes buffers . + * linked list should be prepared before call this function . + * @param hmmc: MMC handle + * @param pLinkedList: pointer to first linked list node + * @param BlockAdd: Block Address from where data is to be read + * @param NumberOfBlocks: Total number of blocks to read + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MMCEx_DMALinkedList_WriteBlocks(MMC_HandleTypeDef *hmmc, MMC_DMALinkedListTypeDef *pLinkedList, + uint32_t BlockAdd, uint32_t NumberOfBlocks) +{ + SDMMC_DataInitTypeDef config; + uint32_t errorstate; + uint32_t DmaBase0_reg; + uint32_t DmaBase1_reg; + uint32_t add = BlockAdd; + + if (hmmc->State == HAL_MMC_STATE_READY) + { + if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr)) + { + hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; + return HAL_ERROR; + } + + /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */ + if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U) + { + if ((NumberOfBlocks % 8U) != 0U) + { + /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */ + hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR; + return HAL_ERROR; + } + + if ((BlockAdd % 8U) != 0U) + { + /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */ + hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED; + return HAL_ERROR; + } + } + + hmmc->Instance->IDMABASER = (uint32_t) pLinkedList->pHeadNode->IDMABASER; + hmmc->Instance->IDMABSIZE = (uint32_t) pLinkedList->pHeadNode->IDMABSIZE; + + hmmc->Instance->IDMABAR = (uint32_t) pLinkedList->pHeadNode; + hmmc->Instance->IDMALAR = (uint32_t) SDMMC_IDMALAR_ABR | SDMMC_IDMALAR_ULS | SDMMC_IDMALAR_ULA | + sizeof(SDMMC_DMALinkNodeTypeDef) ; /* Initial configuration */ + + DmaBase0_reg = hmmc->Instance->IDMABASER; + DmaBase1_reg = hmmc->Instance->IDMABAR; + + if ((hmmc->Instance->IDMABSIZE == 0U) || (DmaBase0_reg == 0U) || (DmaBase1_reg == 0U)) + { + hmmc->ErrorCode = HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; + return HAL_ERROR; + } + + /* Initialize data control register */ + hmmc->Instance->DCTRL = 0; + + hmmc->ErrorCode = HAL_MMC_ERROR_NONE; + + hmmc->State = HAL_MMC_STATE_BUSY; + + if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD) + { + add *= 512U; + } + + /* Configure the MMC DPSM (Data Path State Machine) */ + config.DataTimeOut = SDMMC_DATATIMEOUT; + config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks; + config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; + config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD; + config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + config.DPSM = SDMMC_DPSM_DISABLE; + (void)SDMMC_ConfigData(hmmc->Instance, &config); + + __SDMMC_CMDTRANS_ENABLE(hmmc->Instance); + + hmmc->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_DOUBLE_BUFF0; + + /* Write Blocks in DMA mode */ + hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_DMA); + + /* Write Multi Block command */ + errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add); + if (errorstate != HAL_MMC_ERROR_NONE) + { + hmmc->State = HAL_MMC_STATE_READY; + hmmc->ErrorCode |= errorstate; + return HAL_ERROR; + } + + __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND | + SDMMC_FLAG_IDMATE | SDMMC_FLAG_IDMABTC)); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + + + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_MMC_MODULE_ENABLED */ +#endif /* SDMMC1 || SDMMC2 */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_msp_template.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_msp_template.c new file mode 100644 index 0000000000..0f0a717454 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_msp_template.c @@ -0,0 +1,99 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_msp_template.c + * @author MCD Application Team + * @brief HAL MSP module. + * This file template is located in the HAL folder and should be copied + * to the user folder. + * + @verbatim + =============================================================================== + ##### How to use this driver ##### + =============================================================================== + [..] + + @endverbatim + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup HAL_MSP HAL MSP module driver + * @brief HAL MSP module. + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup HAL_MSP_Private_Functions HAL MSP Private Functions + * @{ + */ + +/** + * @brief Initializes the Global MSP. + * @retval None + */ +void HAL_MspInit(void) +{ + +} + +/** + * @brief DeInitializes the Global MSP. + * @retval None + */ +void HAL_MspDeInit(void) +{ + +} + +/** + * @brief Initializes the PPP MSP. + * @retval None + */ +void HAL_PPP_MspInit(void) +{ + +} + +/** + * @brief DeInitializes the PPP MSP. + * @retval None + */ +void HAL_PPP_MspDeInit(void) +{ + +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_nand.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_nand.c new file mode 100644 index 0000000000..ff123ebce2 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_nand.c @@ -0,0 +1,2233 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_nand.c + * @author MCD Application Team + * @brief NAND HAL module driver. + * This file provides a generic firmware to drive NAND memories mounted + * as external device. + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2022 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 ##### + ============================================================================== + [..] + This driver is a generic layered driver which contains a set of APIs used to + control NAND flash memories. It uses the FMC layer functions to interface + with NAND devices. This driver is used as follows: + + (+) NAND flash memory configuration sequence using the function HAL_NAND_Init() + with control and timing parameters for both common and attribute spaces. + + (+) Read NAND flash memory maker and device IDs using the function + HAL_NAND_Read_ID(). The read information is stored in the NAND_ID_TypeDef + structure declared by the function caller. + + (+) Access NAND flash memory by read/write operations using the functions + HAL_NAND_Read_Page_8b()/HAL_NAND_Read_SpareArea_8b(), + HAL_NAND_Write_Page_8b()/HAL_NAND_Write_SpareArea_8b(), + HAL_NAND_Read_Page_16b()/HAL_NAND_Read_SpareArea_16b(), + HAL_NAND_Write_Page_16b()/HAL_NAND_Write_SpareArea_16b() + to read/write page(s)/spare area(s). These functions use specific device + information (Block, page size..) predefined by the user in the NAND_DeviceConfigTypeDef + structure. The read/write address information is contained by the Nand_Address_Typedef + structure passed as parameter. + + (+) Perform NAND flash Reset chip operation using the function HAL_NAND_Reset(). + + (+) Perform NAND flash erase block operation using the function HAL_NAND_Erase_Block(). + The erase block address information is contained in the Nand_Address_Typedef + structure passed as parameter. + + (+) Read the NAND flash status operation using the function HAL_NAND_Read_Status(). + + (+) You can also control the NAND device by calling the control APIs HAL_NAND_ECC_Enable()/ + HAL_NAND_ECC_Disable() to respectively enable/disable the ECC code correction + feature or the function HAL_NAND_GetECC() to get the ECC correction code. + + (+) You can monitor the NAND device HAL state by calling the function + HAL_NAND_GetState() + + [..] + (@) This driver is a set of generic APIs which handle standard NAND flash operations. + If a NAND flash device contains different operations and/or implementations, + it should be implemented separately. + + *** Callback registration *** + ============================================= + [..] + The compilation define USE_HAL_NAND_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + + Use Functions HAL_NAND_RegisterCallback() to register a user callback, + it allows to register following callbacks: + (+) MspInitCallback : NAND MspInit. + (+) MspDeInitCallback : NAND MspDeInit. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + + Use function HAL_NAND_UnRegisterCallback() to reset a callback to the default + weak (overridden) function. It allows to reset following callbacks: + (+) MspInitCallback : NAND MspInit. + (+) MspDeInitCallback : NAND MspDeInit. + This function) takes as parameters the HAL peripheral handle and the Callback ID. + + By default, after the HAL_NAND_Init and if the state is HAL_NAND_STATE_RESET + all callbacks are reset to the corresponding legacy weak (overridden) functions. + Exception done for MspInit and MspDeInit callbacks that are respectively + reset to the legacy weak (overridden) functions in the HAL_NAND_Init + and HAL_NAND_DeInit only when these callbacks are null (not registered beforehand). + If not, MspInit or MspDeInit are not null, the HAL_NAND_Init and HAL_NAND_DeInit + keep and use the user MspInit/MspDeInit callbacks (registered beforehand) + + Callbacks can be registered/unregistered in READY state only. + Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered + in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used + during the Init/DeInit. + In that case first register the MspInit/MspDeInit user callbacks + using HAL_NAND_RegisterCallback before calling HAL_NAND_DeInit + or HAL_NAND_Init function. + + When The compilation define USE_HAL_NAND_REGISTER_CALLBACKS is set to 0 or + not defined, the callback registering feature is not available + and weak (overridden) callbacks are used. + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +#if defined(FMC_BANK3) + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +#ifdef HAL_NAND_MODULE_ENABLED + +/** @defgroup NAND NAND + * @brief NAND HAL module driver + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private Constants ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions ---------------------------------------------------------*/ + +/** @defgroup NAND_Exported_Functions NAND Exported Functions + * @{ + */ + +/** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * + @verbatim + ============================================================================== + ##### NAND Initialization and de-initialization functions ##### + ============================================================================== + [..] + This section provides functions allowing to initialize/de-initialize + the NAND memory + +@endverbatim + * @{ + */ + +/** + * @brief Perform NAND memory Initialization sequence + * @param hnand pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @param ComSpace_Timing pointer to Common space timing structure + * @param AttSpace_Timing pointer to Attribute space timing structure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NAND_Init(NAND_HandleTypeDef *hnand, FMC_NAND_PCC_TimingTypeDef *ComSpace_Timing, + FMC_NAND_PCC_TimingTypeDef *AttSpace_Timing) +{ + /* Check the NAND handle state */ + if (hnand == NULL) + { + return HAL_ERROR; + } + + if (hnand->State == HAL_NAND_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hnand->Lock = HAL_UNLOCKED; + +#if (USE_HAL_NAND_REGISTER_CALLBACKS == 1) + if (hnand->MspInitCallback == NULL) + { + hnand->MspInitCallback = HAL_NAND_MspInit; + } + hnand->ItCallback = HAL_NAND_ITCallback; + + /* Init the low level hardware */ + hnand->MspInitCallback(hnand); +#else + /* Initialize the low level hardware (MSP) */ + HAL_NAND_MspInit(hnand); +#endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */ + } + + /* Initialize NAND control Interface */ + (void)FMC_NAND_Init(hnand->Instance, &(hnand->Init)); + + /* Initialize NAND common space timing Interface */ + (void)FMC_NAND_CommonSpace_Timing_Init(hnand->Instance, ComSpace_Timing, hnand->Init.NandBank); + + /* Initialize NAND attribute space timing Interface */ + (void)FMC_NAND_AttributeSpace_Timing_Init(hnand->Instance, AttSpace_Timing, hnand->Init.NandBank); + + /* Enable the NAND device */ + __FMC_NAND_ENABLE(hnand->Instance); + + /* Enable FMC Peripheral */ + __FMC_ENABLE(); + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Perform NAND memory De-Initialization sequence + * @param hnand pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand) +{ +#if (USE_HAL_NAND_REGISTER_CALLBACKS == 1) + if (hnand->MspDeInitCallback == NULL) + { + hnand->MspDeInitCallback = HAL_NAND_MspDeInit; + } + + /* DeInit the low level hardware */ + hnand->MspDeInitCallback(hnand); +#else + /* Initialize the low level hardware (MSP) */ + HAL_NAND_MspDeInit(hnand); +#endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */ + + /* Configure the NAND registers with their reset values */ + (void)FMC_NAND_DeInit(hnand->Instance, hnand->Init.NandBank); + + /* Reset the NAND controller state */ + hnand->State = HAL_NAND_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hnand); + + return HAL_OK; +} + +/** + * @brief NAND MSP Init + * @param hnand pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @retval None + */ +__weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hnand); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_NAND_MspInit could be implemented in the user file + */ +} + +/** + * @brief NAND MSP DeInit + * @param hnand pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @retval None + */ +__weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hnand); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_NAND_MspDeInit could be implemented in the user file + */ +} + + +/** + * @brief This function handles NAND device interrupt request. + * @param hnand pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @retval HAL status + */ +void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand) +{ + /* Check NAND interrupt Rising edge flag */ + if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE)) + { + /* NAND interrupt callback*/ +#if (USE_HAL_NAND_REGISTER_CALLBACKS == 1) + hnand->ItCallback(hnand); +#else + HAL_NAND_ITCallback(hnand); +#endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */ + + /* Clear NAND interrupt Rising edge pending bit */ + __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_RISING_EDGE); + } + + /* Check NAND interrupt Level flag */ + if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL)) + { + /* NAND interrupt callback*/ +#if (USE_HAL_NAND_REGISTER_CALLBACKS == 1) + hnand->ItCallback(hnand); +#else + HAL_NAND_ITCallback(hnand); +#endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */ + + /* Clear NAND interrupt Level pending bit */ + __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_LEVEL); + } + + /* Check NAND interrupt Falling edge flag */ + if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE)) + { + /* NAND interrupt callback*/ +#if (USE_HAL_NAND_REGISTER_CALLBACKS == 1) + hnand->ItCallback(hnand); +#else + HAL_NAND_ITCallback(hnand); +#endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */ + + /* Clear NAND interrupt Falling edge pending bit */ + __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FALLING_EDGE); + } + + /* Check NAND interrupt FIFO empty flag */ + if (__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT)) + { + /* NAND interrupt callback*/ +#if (USE_HAL_NAND_REGISTER_CALLBACKS == 1) + hnand->ItCallback(hnand); +#else + HAL_NAND_ITCallback(hnand); +#endif /* (USE_HAL_NAND_REGISTER_CALLBACKS) */ + + /* Clear NAND interrupt FIFO empty pending bit */ + __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FEMPT); + } + +} + +/** + * @brief NAND interrupt feature callback + * @param hnand pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @retval None + */ +__weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hnand); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_NAND_ITCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup NAND_Exported_Functions_Group2 Input and Output functions + * @brief Input Output and memory control functions + * + @verbatim + ============================================================================== + ##### NAND Input and Output functions ##### + ============================================================================== + [..] + This section provides functions allowing to use and control the NAND + memory + +@endverbatim + * @{ + */ + +/** + * @brief Read the NAND memory electronic signature + * @param hnand pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @param pNAND_ID NAND ID structure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID) +{ + __IO uint32_t data = 0; + __IO uint32_t data1 = 0; + uint32_t deviceaddress; + + /* Check the NAND controller state */ + if (hnand->State == HAL_NAND_STATE_BUSY) + { + return HAL_BUSY; + } + else if (hnand->State == HAL_NAND_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hnand); + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_BUSY; + + /* Identify the device address */ + deviceaddress = NAND_DEVICE; + + /* Send Read ID command sequence */ + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_READID; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00; + __DSB(); + + /* Read the electronic signature from NAND flash */ + if (hnand->Init.MemoryDataWidth == FMC_NAND_MEM_BUS_WIDTH_8) + { + data = *(__IO uint32_t *)deviceaddress; + + /* Return the data read */ + pNAND_ID->Maker_Id = ADDR_1ST_CYCLE(data); + pNAND_ID->Device_Id = ADDR_2ND_CYCLE(data); + pNAND_ID->Third_Id = ADDR_3RD_CYCLE(data); + pNAND_ID->Fourth_Id = ADDR_4TH_CYCLE(data); + } + else + { + data = *(__IO uint32_t *)deviceaddress; + data1 = *((__IO uint32_t *)deviceaddress + 4); + + /* Return the data read */ + pNAND_ID->Maker_Id = ADDR_1ST_CYCLE(data); + pNAND_ID->Device_Id = ADDR_3RD_CYCLE(data); + pNAND_ID->Third_Id = ADDR_1ST_CYCLE(data1); + pNAND_ID->Fourth_Id = ADDR_3RD_CYCLE(data1); + } + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnand); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief NAND memory reset + * @param hnand pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand) +{ + uint32_t deviceaddress; + + /* Check the NAND controller state */ + if (hnand->State == HAL_NAND_STATE_BUSY) + { + return HAL_BUSY; + } + else if (hnand->State == HAL_NAND_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hnand); + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_BUSY; + + /* Identify the device address */ + deviceaddress = NAND_DEVICE; + + /* Send NAND reset command */ + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = 0xFF; + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnand); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; + +} + +/** + * @brief Configure the device: Enter the physical parameters of the device + * @param hnand pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @param pDeviceConfig pointer to NAND_DeviceConfigTypeDef structure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NAND_ConfigDevice(NAND_HandleTypeDef *hnand, NAND_DeviceConfigTypeDef *pDeviceConfig) +{ + hnand->Config.PageSize = pDeviceConfig->PageSize; + hnand->Config.SpareAreaSize = pDeviceConfig->SpareAreaSize; + hnand->Config.BlockSize = pDeviceConfig->BlockSize; + hnand->Config.BlockNbr = pDeviceConfig->BlockNbr; + hnand->Config.PlaneSize = pDeviceConfig->PlaneSize; + hnand->Config.PlaneNbr = pDeviceConfig->PlaneNbr; + hnand->Config.ExtraCommandEnable = pDeviceConfig->ExtraCommandEnable; + + return HAL_OK; +} + +/** + * @brief Read Page(s) from NAND memory block (8-bits addressing) + * @param hnand pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @param pAddress pointer to NAND address structure + * @param pBuffer pointer to destination read buffer + * @param NumPageToRead number of pages to read from block + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NAND_Read_Page_8b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress, + uint8_t *pBuffer, uint32_t NumPageToRead) +{ + uint32_t index; + uint32_t tickstart; + uint32_t deviceaddress; + uint32_t numpagesread = 0U; + uint32_t nandaddress; + uint32_t nbpages = NumPageToRead; + uint8_t *buff = pBuffer; + + /* Check the NAND controller state */ + if (hnand->State == HAL_NAND_STATE_BUSY) + { + return HAL_BUSY; + } + else if (hnand->State == HAL_NAND_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hnand); + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_BUSY; + + /* Identify the device address */ + deviceaddress = NAND_DEVICE; + + /* NAND raw address calculation */ + nandaddress = ARRAY_ADDRESS(pAddress, hnand); + + /* Page(s) read loop */ + while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)))) + { + /* Send read page command sequence */ + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A; + __DSB(); + + /* Cards with page size <= 512 bytes */ + if ((hnand->Config.PageSize) <= 512U) + { + if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + } + else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); + __DSB(); + } + } + else /* (hnand->Config.PageSize) > 512 */ + { + if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + } + else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); + __DSB(); + } + } + + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1; + __DSB(); + + + if (hnand->Config.ExtraCommandEnable == ENABLE) + { + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Read status until NAND is ready */ + while (HAL_NAND_Read_Status(hnand) != NAND_READY) + { + if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT) + { + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_ERROR; + + /* Process unlocked */ + __HAL_UNLOCK(hnand); + + return HAL_TIMEOUT; + } + } + + /* Go back to read mode */ + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00); + __DSB(); + } + + /* Get Data into Buffer */ + for (index = 0U; index < hnand->Config.PageSize; index++) + { + *buff = *(uint8_t *)deviceaddress; + buff++; + } + + /* Increment read pages number */ + numpagesread++; + + /* Decrement pages to read */ + nbpages--; + + /* Increment the NAND address */ + nandaddress = (uint32_t)(nandaddress + 1U); + } + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnand); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Read Page(s) from NAND memory block (16-bits addressing) + * @param hnand pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @param pAddress pointer to NAND address structure + * @param pBuffer pointer to destination read buffer. pBuffer should be 16bits aligned + * @param NumPageToRead number of pages to read from block + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NAND_Read_Page_16b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress, + uint16_t *pBuffer, uint32_t NumPageToRead) +{ + uint32_t index; + uint32_t tickstart; + uint32_t deviceaddress; + uint32_t numpagesread = 0U; + uint32_t nandaddress; + uint32_t nbpages = NumPageToRead; + uint16_t *buff = pBuffer; + + /* Check the NAND controller state */ + if (hnand->State == HAL_NAND_STATE_BUSY) + { + return HAL_BUSY; + } + else if (hnand->State == HAL_NAND_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hnand); + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_BUSY; + + /* Identify the device address */ + deviceaddress = NAND_DEVICE; + + /* NAND raw address calculation */ + nandaddress = ARRAY_ADDRESS(pAddress, hnand); + + /* Page(s) read loop */ + while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)))) + { + /* Send read page command sequence */ + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A; + __DSB(); + + /* Cards with page size <= 512 bytes */ + if ((hnand->Config.PageSize) <= 512U) + { + if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + } + else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); + __DSB(); + } + } + else /* (hnand->Config.PageSize) > 512 */ + { + if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + } + else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); + __DSB(); + } + } + + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1; + __DSB(); + + if (hnand->Config.ExtraCommandEnable == ENABLE) + { + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Read status until NAND is ready */ + while (HAL_NAND_Read_Status(hnand) != NAND_READY) + { + if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT) + { + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_ERROR; + + /* Process unlocked */ + __HAL_UNLOCK(hnand); + + return HAL_TIMEOUT; + } + } + + /* Go back to read mode */ + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00); + __DSB(); + } + + /* Calculate PageSize */ + if (hnand->Init.MemoryDataWidth == FMC_NAND_MEM_BUS_WIDTH_8) + { + hnand->Config.PageSize = hnand->Config.PageSize / 2U; + } + else + { + /* Do nothing */ + /* Keep the same PageSize for FMC_NAND_MEM_BUS_WIDTH_16*/ + } + + /* Get Data into Buffer */ + for (index = 0U; index < hnand->Config.PageSize; index++) + { + *buff = *(uint16_t *)deviceaddress; + buff++; + } + + /* Increment read pages number */ + numpagesread++; + + /* Decrement pages to read */ + nbpages--; + + /* Increment the NAND address */ + nandaddress = (uint32_t)(nandaddress + 1U); + } + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnand); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Write Page(s) to NAND memory block (8-bits addressing) + * @param hnand pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @param pAddress pointer to NAND address structure + * @param pBuffer pointer to source buffer to write + * @param NumPageToWrite number of pages to write to block + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NAND_Write_Page_8b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress, + const uint8_t *pBuffer, uint32_t NumPageToWrite) +{ + uint32_t index; + uint32_t tickstart; + uint32_t deviceaddress; + uint32_t numpageswritten = 0U; + uint32_t nandaddress; + uint32_t nbpages = NumPageToWrite; + const uint8_t *buff = pBuffer; + + /* Check the NAND controller state */ + if (hnand->State == HAL_NAND_STATE_BUSY) + { + return HAL_BUSY; + } + else if (hnand->State == HAL_NAND_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hnand); + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_BUSY; + + /* Identify the device address */ + deviceaddress = NAND_DEVICE; + + /* NAND raw address calculation */ + nandaddress = ARRAY_ADDRESS(pAddress, hnand); + + /* Page(s) write loop */ + while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)))) + { + /* Send write page command sequence */ + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0; + __DSB(); + + /* Cards with page size <= 512 bytes */ + if ((hnand->Config.PageSize) <= 512U) + { + if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + } + else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); + __DSB(); + } + } + else /* (hnand->Config.PageSize) > 512 */ + { + if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + } + else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); + __DSB(); + } + } + + /* Write data to memory */ + for (index = 0U; index < hnand->Config.PageSize; index++) + { + *(__IO uint8_t *)deviceaddress = *buff; + buff++; + __DSB(); + } + + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1; + __DSB(); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Read status until NAND is ready */ + while (HAL_NAND_Read_Status(hnand) != NAND_READY) + { + if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT) + { + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_ERROR; + + /* Process unlocked */ + __HAL_UNLOCK(hnand); + + return HAL_TIMEOUT; + } + } + + /* Increment written pages number */ + numpageswritten++; + + /* Decrement pages to write */ + nbpages--; + + /* Increment the NAND address */ + nandaddress = (uint32_t)(nandaddress + 1U); + } + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnand); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Write Page(s) to NAND memory block (16-bits addressing) + * @param hnand pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @param pAddress pointer to NAND address structure + * @param pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned + * @param NumPageToWrite number of pages to write to block + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NAND_Write_Page_16b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress, + const uint16_t *pBuffer, uint32_t NumPageToWrite) +{ + uint32_t index; + uint32_t tickstart; + uint32_t deviceaddress; + uint32_t numpageswritten = 0U; + uint32_t nandaddress; + uint32_t nbpages = NumPageToWrite; + const uint16_t *buff = pBuffer; + + /* Check the NAND controller state */ + if (hnand->State == HAL_NAND_STATE_BUSY) + { + return HAL_BUSY; + } + else if (hnand->State == HAL_NAND_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hnand); + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_BUSY; + + /* Identify the device address */ + deviceaddress = NAND_DEVICE; + + /* NAND raw address calculation */ + nandaddress = ARRAY_ADDRESS(pAddress, hnand); + + /* Page(s) write loop */ + while ((nbpages != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)))) + { + /* Send write page command sequence */ + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0; + __DSB(); + + /* Cards with page size <= 512 bytes */ + if ((hnand->Config.PageSize) <= 512U) + { + if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + } + else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); + __DSB(); + } + } + else /* (hnand->Config.PageSize) > 512 */ + { + if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + } + else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); + __DSB(); + } + } + + /* Calculate PageSize */ + if (hnand->Init.MemoryDataWidth == FMC_NAND_MEM_BUS_WIDTH_8) + { + hnand->Config.PageSize = hnand->Config.PageSize / 2U; + } + else + { + /* Do nothing */ + /* Keep the same PageSize for FMC_NAND_MEM_BUS_WIDTH_16*/ + } + + /* Write data to memory */ + for (index = 0U; index < hnand->Config.PageSize; index++) + { + *(__IO uint16_t *)deviceaddress = *buff; + buff++; + __DSB(); + } + + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1; + __DSB(); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Read status until NAND is ready */ + while (HAL_NAND_Read_Status(hnand) != NAND_READY) + { + if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT) + { + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_ERROR; + + /* Process unlocked */ + __HAL_UNLOCK(hnand); + + return HAL_TIMEOUT; + } + } + + /* Increment written pages number */ + numpageswritten++; + + /* Decrement pages to write */ + nbpages--; + + /* Increment the NAND address */ + nandaddress = (uint32_t)(nandaddress + 1U); + } + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnand); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Read Spare area(s) from NAND memory (8-bits addressing) + * @param hnand pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @param pAddress pointer to NAND address structure + * @param pBuffer pointer to source buffer to write + * @param NumSpareAreaToRead Number of spare area to read + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NAND_Read_SpareArea_8b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress, + uint8_t *pBuffer, uint32_t NumSpareAreaToRead) +{ + uint32_t index; + uint32_t tickstart; + uint32_t deviceaddress; + uint32_t numsparearearead = 0U; + uint32_t nandaddress; + uint32_t columnaddress; + uint32_t nbspare = NumSpareAreaToRead; + uint8_t *buff = pBuffer; + + /* Check the NAND controller state */ + if (hnand->State == HAL_NAND_STATE_BUSY) + { + return HAL_BUSY; + } + else if (hnand->State == HAL_NAND_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hnand); + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_BUSY; + + /* Identify the device address */ + deviceaddress = NAND_DEVICE; + + /* NAND raw address calculation */ + nandaddress = ARRAY_ADDRESS(pAddress, hnand); + + /* Column in page address */ + columnaddress = COLUMN_ADDRESS(hnand); + + /* Spare area(s) read loop */ + while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)))) + { + /* Cards with page size <= 512 bytes */ + if ((hnand->Config.PageSize) <= 512U) + { + /* Send read spare area command sequence */ + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C; + __DSB(); + + if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + } + else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); + __DSB(); + } + } + else /* (hnand->Config.PageSize) > 512 */ + { + /* Send read spare area command sequence */ + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A; + __DSB(); + + if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + } + else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); + __DSB(); + } + } + + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1; + __DSB(); + + if (hnand->Config.ExtraCommandEnable == ENABLE) + { + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Read status until NAND is ready */ + while (HAL_NAND_Read_Status(hnand) != NAND_READY) + { + if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT) + { + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_ERROR; + + /* Process unlocked */ + __HAL_UNLOCK(hnand); + + return HAL_TIMEOUT; + } + } + + /* Go back to read mode */ + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00); + __DSB(); + } + + /* Get Data into Buffer */ + for (index = 0U; index < hnand->Config.SpareAreaSize; index++) + { + *buff = *(uint8_t *)deviceaddress; + buff++; + } + + /* Increment read spare areas number */ + numsparearearead++; + + /* Decrement spare areas to read */ + nbspare--; + + /* Increment the NAND address */ + nandaddress = (uint32_t)(nandaddress + 1U); + } + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnand); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Read Spare area(s) from NAND memory (16-bits addressing) + * @param hnand pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @param pAddress pointer to NAND address structure + * @param pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned. + * @param NumSpareAreaToRead Number of spare area to read + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NAND_Read_SpareArea_16b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress, + uint16_t *pBuffer, uint32_t NumSpareAreaToRead) +{ + uint32_t index; + uint32_t tickstart; + uint32_t deviceaddress; + uint32_t numsparearearead = 0U; + uint32_t nandaddress; + uint32_t columnaddress; + uint32_t nbspare = NumSpareAreaToRead; + uint16_t *buff = pBuffer; + + /* Check the NAND controller state */ + if (hnand->State == HAL_NAND_STATE_BUSY) + { + return HAL_BUSY; + } + else if (hnand->State == HAL_NAND_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hnand); + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_BUSY; + + /* Identify the device address */ + deviceaddress = NAND_DEVICE; + + /* NAND raw address calculation */ + nandaddress = ARRAY_ADDRESS(pAddress, hnand); + + /* Column in page address */ + columnaddress = (uint32_t)(COLUMN_ADDRESS(hnand)); + + /* Spare area(s) read loop */ + while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)))) + { + /* Cards with page size <= 512 bytes */ + if ((hnand->Config.PageSize) <= 512U) + { + /* Send read spare area command sequence */ + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C; + __DSB(); + + if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + } + else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); + __DSB(); + } + } + else /* (hnand->Config.PageSize) > 512 */ + { + /* Send read spare area command sequence */ + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A; + __DSB(); + + if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + } + else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); + __DSB(); + } + } + + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1; + __DSB(); + + if (hnand->Config.ExtraCommandEnable == ENABLE) + { + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Read status until NAND is ready */ + while (HAL_NAND_Read_Status(hnand) != NAND_READY) + { + if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT) + { + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_ERROR; + + /* Process unlocked */ + __HAL_UNLOCK(hnand); + + return HAL_TIMEOUT; + } + } + + /* Go back to read mode */ + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00); + __DSB(); + } + + /* Get Data into Buffer */ + for (index = 0U; index < hnand->Config.SpareAreaSize; index++) + { + *buff = *(uint16_t *)deviceaddress; + buff++; + } + + /* Increment read spare areas number */ + numsparearearead++; + + /* Decrement spare areas to read */ + nbspare--; + + /* Increment the NAND address */ + nandaddress = (uint32_t)(nandaddress + 1U); + } + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnand); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Write Spare area(s) to NAND memory (8-bits addressing) + * @param hnand pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @param pAddress pointer to NAND address structure + * @param pBuffer pointer to source buffer to write + * @param NumSpareAreaTowrite number of spare areas to write to block + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NAND_Write_SpareArea_8b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress, + const uint8_t *pBuffer, uint32_t NumSpareAreaTowrite) +{ + uint32_t index; + uint32_t tickstart; + uint32_t deviceaddress; + uint32_t numspareareawritten = 0U; + uint32_t nandaddress; + uint32_t columnaddress; + uint32_t nbspare = NumSpareAreaTowrite; + const uint8_t *buff = pBuffer; + + /* Check the NAND controller state */ + if (hnand->State == HAL_NAND_STATE_BUSY) + { + return HAL_BUSY; + } + else if (hnand->State == HAL_NAND_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hnand); + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_BUSY; + + /* Identify the device address */ + deviceaddress = NAND_DEVICE; + + /* Page address calculation */ + nandaddress = ARRAY_ADDRESS(pAddress, hnand); + + /* Column in page address */ + columnaddress = COLUMN_ADDRESS(hnand); + + /* Spare area(s) write loop */ + while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)))) + { + /* Cards with page size <= 512 bytes */ + if ((hnand->Config.PageSize) <= 512U) + { + /* Send write Spare area command sequence */ + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0; + __DSB(); + + if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + } + else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); + __DSB(); + } + } + else /* (hnand->Config.PageSize) > 512 */ + { + /* Send write Spare area command sequence */ + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0; + __DSB(); + + if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + } + else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); + __DSB(); + } + } + + /* Write data to memory */ + for (index = 0U; index < hnand->Config.SpareAreaSize; index++) + { + *(__IO uint8_t *)deviceaddress = *buff; + buff++; + __DSB(); + } + + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1; + __DSB(); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Read status until NAND is ready */ + while (HAL_NAND_Read_Status(hnand) != NAND_READY) + { + if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT) + { + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_ERROR; + + /* Process unlocked */ + __HAL_UNLOCK(hnand); + + return HAL_TIMEOUT; + } + } + + /* Increment written spare areas number */ + numspareareawritten++; + + /* Decrement spare areas to write */ + nbspare--; + + /* Increment the NAND address */ + nandaddress = (uint32_t)(nandaddress + 1U); + } + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnand); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Write Spare area(s) to NAND memory (16-bits addressing) + * @param hnand pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @param pAddress pointer to NAND address structure + * @param pBuffer pointer to source buffer to write. pBuffer should be 16bits aligned. + * @param NumSpareAreaTowrite number of spare areas to write to block + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NAND_Write_SpareArea_16b(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress, + const uint16_t *pBuffer, uint32_t NumSpareAreaTowrite) +{ + uint32_t index; + uint32_t tickstart; + uint32_t deviceaddress; + uint32_t numspareareawritten = 0U; + uint32_t nandaddress; + uint32_t columnaddress; + uint32_t nbspare = NumSpareAreaTowrite; + const uint16_t *buff = pBuffer; + + /* Check the NAND controller state */ + if (hnand->State == HAL_NAND_STATE_BUSY) + { + return HAL_BUSY; + } + else if (hnand->State == HAL_NAND_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hnand); + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_BUSY; + + /* Identify the device address */ + deviceaddress = NAND_DEVICE; + + /* NAND raw address calculation */ + nandaddress = ARRAY_ADDRESS(pAddress, hnand); + + /* Column in page address */ + columnaddress = (uint32_t)(COLUMN_ADDRESS(hnand)); + + /* Spare area(s) write loop */ + while ((nbspare != 0U) && (nandaddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)))) + { + /* Cards with page size <= 512 bytes */ + if ((hnand->Config.PageSize) <= 512U) + { + /* Send write Spare area command sequence */ + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0; + __DSB(); + + if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + } + else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00U; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); + __DSB(); + } + } + else /* (hnand->Config.PageSize) > 512 */ + { + /* Send write Spare area command sequence */ + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0; + __DSB(); + + if (((hnand->Config.BlockSize) * (hnand->Config.BlockNbr)) <= 65535U) + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + } + else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */ + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_1ST_CYCLE(columnaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = COLUMN_2ND_CYCLE(columnaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress); + __DSB(); + } + } + + /* Write data to memory */ + for (index = 0U; index < hnand->Config.SpareAreaSize; index++) + { + *(__IO uint16_t *)deviceaddress = *buff; + buff++; + __DSB(); + } + + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1; + __DSB(); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Read status until NAND is ready */ + while (HAL_NAND_Read_Status(hnand) != NAND_READY) + { + if ((HAL_GetTick() - tickstart) > NAND_WRITE_TIMEOUT) + { + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_ERROR; + + /* Process unlocked */ + __HAL_UNLOCK(hnand); + + return HAL_TIMEOUT; + } + } + + /* Increment written spare areas number */ + numspareareawritten++; + + /* Decrement spare areas to write */ + nbspare--; + + /* Increment the NAND address */ + nandaddress = (uint32_t)(nandaddress + 1U); + } + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnand); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief NAND memory Block erase + * @param hnand pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @param pAddress pointer to NAND address structure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, const NAND_AddressTypeDef *pAddress) +{ + uint32_t deviceaddress; + + /* Check the NAND controller state */ + if (hnand->State == HAL_NAND_STATE_BUSY) + { + return HAL_BUSY; + } + else if (hnand->State == HAL_NAND_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hnand); + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_BUSY; + + /* Identify the device address */ + deviceaddress = NAND_DEVICE; + + /* Send Erase block command sequence */ + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE0; + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand)); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand)); + __DSB(); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand)); + __DSB(); + + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE1; + __DSB(); + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnand); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Increment the NAND memory address + * @param hnand pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @param pAddress pointer to NAND address structure + * @retval The new status of the increment address operation. It can be: + * - NAND_VALID_ADDRESS: When the new address is valid address + * - NAND_INVALID_ADDRESS: When the new address is invalid address + */ +uint32_t HAL_NAND_Address_Inc(const NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress) +{ + uint32_t status = NAND_VALID_ADDRESS; + + /* Increment page address */ + pAddress->Page++; + + /* Check NAND address is valid */ + if (pAddress->Page == hnand->Config.BlockSize) + { + pAddress->Page = 0; + pAddress->Block++; + + if (pAddress->Block == hnand->Config.PlaneSize) + { + pAddress->Block = 0; + pAddress->Plane++; + + if (pAddress->Plane == (hnand->Config.PlaneNbr)) + { + status = NAND_INVALID_ADDRESS; + } + } + } + + return (status); +} + +#if (USE_HAL_NAND_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User NAND Callback + * To be used to override the weak predefined callback + * @param hnand : NAND handle + * @param CallbackId : ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_NAND_MSP_INIT_CB_ID NAND MspInit callback ID + * @arg @ref HAL_NAND_MSP_DEINIT_CB_ID NAND MspDeInit callback ID + * @arg @ref HAL_NAND_IT_CB_ID NAND IT callback ID + * @param pCallback : pointer to the Callback function + * @retval status + */ +HAL_StatusTypeDef HAL_NAND_RegisterCallback(NAND_HandleTypeDef *hnand, HAL_NAND_CallbackIDTypeDef CallbackId, + pNAND_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + return HAL_ERROR; + } + + if (hnand->State == HAL_NAND_STATE_READY) + { + switch (CallbackId) + { + case HAL_NAND_MSP_INIT_CB_ID : + hnand->MspInitCallback = pCallback; + break; + case HAL_NAND_MSP_DEINIT_CB_ID : + hnand->MspDeInitCallback = pCallback; + break; + case HAL_NAND_IT_CB_ID : + hnand->ItCallback = pCallback; + break; + default : + /* update return status */ + status = HAL_ERROR; + break; + } + } + else if (hnand->State == HAL_NAND_STATE_RESET) + { + switch (CallbackId) + { + case HAL_NAND_MSP_INIT_CB_ID : + hnand->MspInitCallback = pCallback; + break; + case HAL_NAND_MSP_DEINIT_CB_ID : + hnand->MspDeInitCallback = pCallback; + break; + default : + /* update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* update return status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister a User NAND Callback + * NAND Callback is redirected to the weak predefined callback + * @param hnand : NAND handle + * @param CallbackId : ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_NAND_MSP_INIT_CB_ID NAND MspInit callback ID + * @arg @ref HAL_NAND_MSP_DEINIT_CB_ID NAND MspDeInit callback ID + * @arg @ref HAL_NAND_IT_CB_ID NAND IT callback ID + * @retval status + */ +HAL_StatusTypeDef HAL_NAND_UnRegisterCallback(NAND_HandleTypeDef *hnand, HAL_NAND_CallbackIDTypeDef CallbackId) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (hnand->State == HAL_NAND_STATE_READY) + { + switch (CallbackId) + { + case HAL_NAND_MSP_INIT_CB_ID : + hnand->MspInitCallback = HAL_NAND_MspInit; + break; + case HAL_NAND_MSP_DEINIT_CB_ID : + hnand->MspDeInitCallback = HAL_NAND_MspDeInit; + break; + case HAL_NAND_IT_CB_ID : + hnand->ItCallback = HAL_NAND_ITCallback; + break; + default : + /* update return status */ + status = HAL_ERROR; + break; + } + } + else if (hnand->State == HAL_NAND_STATE_RESET) + { + switch (CallbackId) + { + case HAL_NAND_MSP_INIT_CB_ID : + hnand->MspInitCallback = HAL_NAND_MspInit; + break; + case HAL_NAND_MSP_DEINIT_CB_ID : + hnand->MspDeInitCallback = HAL_NAND_MspDeInit; + break; + default : + /* update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* update return status */ + status = HAL_ERROR; + } + + return status; +} +#endif /* USE_HAL_NAND_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions + * @brief management functions + * +@verbatim + ============================================================================== + ##### NAND Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control dynamically + the NAND interface. + +@endverbatim + * @{ + */ + + +/** + * @brief Enables dynamically NAND ECC feature. + * @param hnand pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand) +{ + /* Check the NAND controller state */ + if (hnand->State == HAL_NAND_STATE_BUSY) + { + return HAL_BUSY; + } + else if (hnand->State == HAL_NAND_STATE_READY) + { + /* Update the NAND state */ + hnand->State = HAL_NAND_STATE_BUSY; + + /* Enable ECC feature */ + (void)FMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank); + + /* Update the NAND state */ + hnand->State = HAL_NAND_STATE_READY; + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Disables dynamically FMC_NAND ECC feature. + * @param hnand pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand) +{ + /* Check the NAND controller state */ + if (hnand->State == HAL_NAND_STATE_BUSY) + { + return HAL_BUSY; + } + else if (hnand->State == HAL_NAND_STATE_READY) + { + /* Update the NAND state */ + hnand->State = HAL_NAND_STATE_BUSY; + + /* Disable ECC feature */ + (void)FMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank); + + /* Update the NAND state */ + hnand->State = HAL_NAND_STATE_READY; + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Disables dynamically NAND ECC feature. + * @param hnand pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @param ECCval pointer to ECC value + * @param Timeout maximum timeout to wait + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout) +{ + HAL_StatusTypeDef status; + + /* Check the NAND controller state */ + if (hnand->State == HAL_NAND_STATE_BUSY) + { + return HAL_BUSY; + } + else if (hnand->State == HAL_NAND_STATE_READY) + { + /* Update the NAND state */ + hnand->State = HAL_NAND_STATE_BUSY; + + /* Get NAND ECC value */ + status = FMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout); + + /* Update the NAND state */ + hnand->State = HAL_NAND_STATE_READY; + } + else + { + return HAL_ERROR; + } + + return status; +} + +/** + * @} + */ + + +/** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions + * @brief Peripheral State functions + * +@verbatim + ============================================================================== + ##### NAND State functions ##### + ============================================================================== + [..] + This subsection permits to get in run-time the status of the NAND controller + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief return the NAND state + * @param hnand pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @retval HAL state + */ +HAL_NAND_StateTypeDef HAL_NAND_GetState(const NAND_HandleTypeDef *hnand) +{ + return hnand->State; +} + +/** + * @brief NAND memory read status + * @param hnand pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @retval NAND status + */ +uint32_t HAL_NAND_Read_Status(const NAND_HandleTypeDef *hnand) +{ + uint32_t data; + uint32_t deviceaddress; + UNUSED(hnand); + + /* Identify the device address */ + deviceaddress = NAND_DEVICE; + + /* Send Read status operation command */ + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_STATUS; + + /* Read status register data */ + data = *(__IO uint8_t *)deviceaddress; + + /* Return the status */ + if ((data & NAND_ERROR) == NAND_ERROR) + { + return NAND_ERROR; + } + else if ((data & NAND_READY) == NAND_READY) + { + return NAND_READY; + } + else + { + return NAND_BUSY; + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_NAND_MODULE_ENABLED */ + +/** + * @} + */ + +#endif /* FMC_BANK3 */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_nor.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_nor.c new file mode 100644 index 0000000000..517c6fa684 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_nor.c @@ -0,0 +1,1644 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_nor.c + * @author MCD Application Team + * @brief NOR HAL module driver. + * This file provides a generic firmware to drive NOR memories mounted + * as external device. + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2022 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 ##### + ============================================================================== + [..] + This driver is a generic layered driver which contains a set of APIs used to + control NOR flash memories. It uses the FMC layer functions to interface + with NOR devices. This driver is used as follows: + + (+) NOR flash memory configuration sequence using the function HAL_NOR_Init() + with control and timing parameters for both normal and extended mode. + + (+) Read NOR flash memory manufacturer code and device IDs using the function + HAL_NOR_Read_ID(). The read information is stored in the NOR_ID_TypeDef + structure declared by the function caller. + + (+) Access NOR flash memory by read/write data unit operations using the functions + HAL_NOR_Read(), HAL_NOR_Program(). + + (+) Perform NOR flash erase block/chip operations using the functions + HAL_NOR_Erase_Block() and HAL_NOR_Erase_Chip(). + + (+) Read the NOR flash CFI (common flash interface) IDs using the function + HAL_NOR_Read_CFI(). The read information is stored in the NOR_CFI_TypeDef + structure declared by the function caller. + + (+) You can also control the NOR device by calling the control APIs HAL_NOR_WriteOperation_Enable()/ + HAL_NOR_WriteOperation_Disable() to respectively enable/disable the NOR write operation + + (+) You can monitor the NOR device HAL state by calling the function + HAL_NOR_GetState() + [..] + (@) This driver is a set of generic APIs which handle standard NOR flash operations. + If a NOR flash device contains different operations and/or implementations, + it should be implemented separately. + + *** NOR HAL driver macros list *** + ============================================= + [..] + Below the list of most used macros in NOR HAL driver. + + (+) NOR_WRITE : NOR memory write data to specified address + + *** Callback registration *** + ============================================= + [..] + The compilation define USE_HAL_NOR_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + + Use Functions HAL_NOR_RegisterCallback() to register a user callback, + it allows to register following callbacks: + (+) MspInitCallback : NOR MspInit. + (+) MspDeInitCallback : NOR MspDeInit. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + + Use function HAL_NOR_UnRegisterCallback() to reset a callback to the default + weak (overridden) function. It allows to reset following callbacks: + (+) MspInitCallback : NOR MspInit. + (+) MspDeInitCallback : NOR MspDeInit. + This function) takes as parameters the HAL peripheral handle and the Callback ID. + + By default, after the HAL_NOR_Init and if the state is HAL_NOR_STATE_RESET + all callbacks are reset to the corresponding legacy weak (overridden) functions. + Exception done for MspInit and MspDeInit callbacks that are respectively + reset to the legacy weak (overridden) functions in the HAL_NOR_Init + and HAL_NOR_DeInit only when these callbacks are null (not registered beforehand). + If not, MspInit or MspDeInit are not null, the HAL_NOR_Init and HAL_NOR_DeInit + keep and use the user MspInit/MspDeInit callbacks (registered beforehand) + + Callbacks can be registered/unregistered in READY state only. + Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered + in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used + during the Init/DeInit. + In that case first register the MspInit/MspDeInit user callbacks + using HAL_NOR_RegisterCallback before calling HAL_NOR_DeInit + or HAL_NOR_Init function. + + When The compilation define USE_HAL_NOR_REGISTER_CALLBACKS is set to 0 or + not defined, the callback registering feature is not available + and weak (overridden) callbacks are used. + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +#if defined(FMC_BANK1) + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +#ifdef HAL_NOR_MODULE_ENABLED + +/** @defgroup NOR NOR + * @brief NOR driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/** @defgroup NOR_Private_Defines NOR Private Defines + * @{ + */ + +/* Constants to define address to set to write a command */ +#define NOR_CMD_ADDRESS_FIRST_BYTE (uint16_t)0x0AAA +#define NOR_CMD_ADDRESS_FIRST_CFI_BYTE (uint16_t)0x00AA +#define NOR_CMD_ADDRESS_SECOND_BYTE (uint16_t)0x0555 +#define NOR_CMD_ADDRESS_THIRD_BYTE (uint16_t)0x0AAA + +#define NOR_CMD_ADDRESS_FIRST (uint16_t)0x0555 +#define NOR_CMD_ADDRESS_FIRST_CFI (uint16_t)0x0055 +#define NOR_CMD_ADDRESS_SECOND (uint16_t)0x02AA +#define NOR_CMD_ADDRESS_THIRD (uint16_t)0x0555 +#define NOR_CMD_ADDRESS_FOURTH (uint16_t)0x0555 +#define NOR_CMD_ADDRESS_FIFTH (uint16_t)0x02AA +#define NOR_CMD_ADDRESS_SIXTH (uint16_t)0x0555 + +/* Constants to define data to program a command */ +#define NOR_CMD_DATA_READ_RESET (uint16_t)0x00F0 +#define NOR_CMD_DATA_FIRST (uint16_t)0x00AA +#define NOR_CMD_DATA_SECOND (uint16_t)0x0055 +#define NOR_CMD_DATA_AUTO_SELECT (uint16_t)0x0090 +#define NOR_CMD_DATA_PROGRAM (uint16_t)0x00A0 +#define NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD (uint16_t)0x0080 +#define NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH (uint16_t)0x00AA +#define NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH (uint16_t)0x0055 +#define NOR_CMD_DATA_CHIP_ERASE (uint16_t)0x0010 +#define NOR_CMD_DATA_CFI (uint16_t)0x0098 + +#define NOR_CMD_DATA_BUFFER_AND_PROG (uint8_t)0x25 +#define NOR_CMD_DATA_BUFFER_AND_PROG_CONFIRM (uint8_t)0x29 +#define NOR_CMD_DATA_BLOCK_ERASE (uint8_t)0x30 + +#define NOR_CMD_READ_ARRAY (uint16_t)0x00FF +#define NOR_CMD_WORD_PROGRAM (uint16_t)0x0040 +#define NOR_CMD_BUFFERED_PROGRAM (uint16_t)0x00E8 +#define NOR_CMD_CONFIRM (uint16_t)0x00D0 +#define NOR_CMD_BLOCK_ERASE (uint16_t)0x0020 +#define NOR_CMD_BLOCK_UNLOCK (uint16_t)0x0060 +#define NOR_CMD_READ_STATUS_REG (uint16_t)0x0070 +#define NOR_CMD_CLEAR_STATUS_REG (uint16_t)0x0050 + +/* Mask on NOR STATUS REGISTER */ +#define NOR_MASK_STATUS_DQ4 (uint16_t)0x0010 +#define NOR_MASK_STATUS_DQ5 (uint16_t)0x0020 +#define NOR_MASK_STATUS_DQ6 (uint16_t)0x0040 +#define NOR_MASK_STATUS_DQ7 (uint16_t)0x0080 + +/* Address of the primary command set */ +#define NOR_ADDRESS_COMMAND_SET (uint16_t)0x0013 + +/* Command set code assignment (defined in JEDEC JEP137B version may 2004) */ +#define NOR_INTEL_SHARP_EXT_COMMAND_SET (uint16_t)0x0001 /* Supported in this driver */ +#define NOR_AMD_FUJITSU_COMMAND_SET (uint16_t)0x0002 /* Supported in this driver */ +#define NOR_INTEL_STANDARD_COMMAND_SET (uint16_t)0x0003 /* Not Supported in this driver */ +#define NOR_AMD_FUJITSU_EXT_COMMAND_SET (uint16_t)0x0004 /* Not Supported in this driver */ +#define NOR_WINDBOND_STANDARD_COMMAND_SET (uint16_t)0x0006 /* Not Supported in this driver */ +#define NOR_MITSUBISHI_STANDARD_COMMAND_SET (uint16_t)0x0100 /* Not Supported in this driver */ +#define NOR_MITSUBISHI_EXT_COMMAND_SET (uint16_t)0x0101 /* Not Supported in this driver */ +#define NOR_PAGE_WRITE_COMMAND_SET (uint16_t)0x0102 /* Not Supported in this driver */ +#define NOR_INTEL_PERFORMANCE_COMMAND_SET (uint16_t)0x0200 /* Not Supported in this driver */ +#define NOR_INTEL_DATA_COMMAND_SET (uint16_t)0x0210 /* Not Supported in this driver */ + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/** @defgroup NOR_Private_Variables NOR Private Variables + * @{ + */ + +static uint32_t uwNORMemoryDataWidth = NOR_MEMORY_8B; + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @defgroup NOR_Exported_Functions NOR Exported Functions + * @{ + */ + +/** @defgroup NOR_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * + @verbatim + ============================================================================== + ##### NOR Initialization and de_initialization functions ##### + ============================================================================== + [..] + This section provides functions allowing to initialize/de-initialize + the NOR memory + +@endverbatim + * @{ + */ + +/** + * @brief Perform the NOR memory Initialization sequence + * @param hnor pointer to a NOR_HandleTypeDef structure that contains + * the configuration information for NOR module. + * @param Timing pointer to NOR control timing structure + * @param ExtTiming pointer to NOR extended mode timing structure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NOR_Init(NOR_HandleTypeDef *hnor, FMC_NORSRAM_TimingTypeDef *Timing, + FMC_NORSRAM_TimingTypeDef *ExtTiming) +{ + uint32_t deviceaddress; + HAL_StatusTypeDef status = HAL_OK; + + /* Check the NOR handle parameter */ + if (hnor == NULL) + { + return HAL_ERROR; + } + + if (hnor->State == HAL_NOR_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hnor->Lock = HAL_UNLOCKED; + +#if (USE_HAL_NOR_REGISTER_CALLBACKS == 1) + if (hnor->MspInitCallback == NULL) + { + hnor->MspInitCallback = HAL_NOR_MspInit; + } + + /* Init the low level hardware */ + hnor->MspInitCallback(hnor); +#else + /* Initialize the low level hardware (MSP) */ + HAL_NOR_MspInit(hnor); +#endif /* (USE_HAL_NOR_REGISTER_CALLBACKS) */ + } + + /* Initialize NOR control Interface */ + (void)FMC_NORSRAM_Init(hnor->Instance, &(hnor->Init)); + + /* Initialize NOR timing Interface */ + (void)FMC_NORSRAM_Timing_Init(hnor->Instance, Timing, hnor->Init.NSBank); + + /* Initialize NOR extended mode timing Interface */ + (void)FMC_NORSRAM_Extended_Timing_Init(hnor->Extended, ExtTiming, + hnor->Init.NSBank, hnor->Init.ExtendedMode); + + /* Enable the NORSRAM device */ + __FMC_NORSRAM_ENABLE(hnor->Instance, hnor->Init.NSBank); + + /* Initialize NOR Memory Data Width*/ + if (hnor->Init.MemoryDataWidth == FMC_NORSRAM_MEM_BUS_WIDTH_8) + { + uwNORMemoryDataWidth = NOR_MEMORY_8B; + } + else + { + uwNORMemoryDataWidth = NOR_MEMORY_16B; + } + + /* Enable FMC Peripheral */ + __FMC_ENABLE(); + + /* Initialize the NOR controller state */ + hnor->State = HAL_NOR_STATE_READY; + + /* Select the NOR device address */ + if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) + { + deviceaddress = NOR_MEMORY_ADRESS1; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) + { + deviceaddress = NOR_MEMORY_ADRESS2; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) + { + deviceaddress = NOR_MEMORY_ADRESS3; + } + else /* FMC_NORSRAM_BANK4 */ + { + deviceaddress = NOR_MEMORY_ADRESS4; + } + + if (hnor->Init.WriteOperation == FMC_WRITE_OPERATION_DISABLE) + { + (void)FMC_NORSRAM_WriteOperation_Disable(hnor->Instance, hnor->Init.NSBank); + + /* Update the NOR controller state */ + hnor->State = HAL_NOR_STATE_PROTECTED; + } + else + { + /* Get the value of the command set */ + if (uwNORMemoryDataWidth == NOR_MEMORY_8B) + { + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_CFI_BYTE), + NOR_CMD_DATA_CFI); + } + else + { + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_CFI), NOR_CMD_DATA_CFI); + } + + hnor->CommandSet = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_ADDRESS_COMMAND_SET); + + status = HAL_NOR_ReturnToReadMode(hnor); + } + + return status; +} + +/** + * @brief Perform NOR memory De-Initialization sequence + * @param hnor pointer to a NOR_HandleTypeDef structure that contains + * the configuration information for NOR module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NOR_DeInit(NOR_HandleTypeDef *hnor) +{ +#if (USE_HAL_NOR_REGISTER_CALLBACKS == 1) + if (hnor->MspDeInitCallback == NULL) + { + hnor->MspDeInitCallback = HAL_NOR_MspDeInit; + } + + /* DeInit the low level hardware */ + hnor->MspDeInitCallback(hnor); +#else + /* De-Initialize the low level hardware (MSP) */ + HAL_NOR_MspDeInit(hnor); +#endif /* (USE_HAL_NOR_REGISTER_CALLBACKS) */ + + /* Configure the NOR registers with their reset values */ + (void)FMC_NORSRAM_DeInit(hnor->Instance, hnor->Extended, hnor->Init.NSBank); + + /* Reset the NOR controller state */ + hnor->State = HAL_NOR_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hnor); + + return HAL_OK; +} + +/** + * @brief NOR MSP Init + * @param hnor pointer to a NOR_HandleTypeDef structure that contains + * the configuration information for NOR module. + * @retval None + */ +__weak void HAL_NOR_MspInit(NOR_HandleTypeDef *hnor) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hnor); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_NOR_MspInit could be implemented in the user file + */ +} + +/** + * @brief NOR MSP DeInit + * @param hnor pointer to a NOR_HandleTypeDef structure that contains + * the configuration information for NOR module. + * @retval None + */ +__weak void HAL_NOR_MspDeInit(NOR_HandleTypeDef *hnor) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hnor); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_NOR_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief NOR MSP Wait for Ready/Busy signal + * @param hnor pointer to a NOR_HandleTypeDef structure that contains + * the configuration information for NOR module. + * @param Timeout Maximum timeout value + * @retval None + */ +__weak void HAL_NOR_MspWait(NOR_HandleTypeDef *hnor, uint32_t Timeout) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hnor); + UNUSED(Timeout); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_NOR_MspWait could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup NOR_Exported_Functions_Group2 Input and Output functions + * @brief Input Output and memory control functions + * + @verbatim + ============================================================================== + ##### NOR Input and Output functions ##### + ============================================================================== + [..] + This section provides functions allowing to use and control the NOR memory + +@endverbatim + * @{ + */ + +/** + * @brief Read NOR flash IDs + * @param hnor pointer to a NOR_HandleTypeDef structure that contains + * the configuration information for NOR module. + * @param pNOR_ID pointer to NOR ID structure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NOR_Read_ID(NOR_HandleTypeDef *hnor, NOR_IDTypeDef *pNOR_ID) +{ + uint32_t deviceaddress; + HAL_NOR_StateTypeDef state; + HAL_StatusTypeDef status = HAL_OK; + + /* Check the NOR controller state */ + state = hnor->State; + if (state == HAL_NOR_STATE_BUSY) + { + return HAL_BUSY; + } + else if (state == HAL_NOR_STATE_PROTECTED) + { + return HAL_ERROR; + } + else if (state == HAL_NOR_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hnor); + + /* Update the NOR controller state */ + hnor->State = HAL_NOR_STATE_BUSY; + + /* Select the NOR device address */ + if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) + { + deviceaddress = NOR_MEMORY_ADRESS1; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) + { + deviceaddress = NOR_MEMORY_ADRESS2; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) + { + deviceaddress = NOR_MEMORY_ADRESS3; + } + else /* FMC_NORSRAM_BANK4 */ + { + deviceaddress = NOR_MEMORY_ADRESS4; + } + + /* Send read ID command */ + if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET) + { + if (uwNORMemoryDataWidth == NOR_MEMORY_8B) + { + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_BYTE), + NOR_CMD_DATA_FIRST); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND_BYTE), + NOR_CMD_DATA_SECOND); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD_BYTE), + NOR_CMD_DATA_AUTO_SELECT); + } + else + { + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), + NOR_CMD_DATA_AUTO_SELECT); + } + } + else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET) + { + NOR_WRITE(deviceaddress, NOR_CMD_DATA_AUTO_SELECT); + } + else + { + /* Primary command set not supported by the driver */ + status = HAL_ERROR; + } + + if (status != HAL_ERROR) + { + /* Read the NOR IDs */ + pNOR_ID->Manufacturer_Code = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, MC_ADDRESS); + pNOR_ID->Device_Code1 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, + DEVICE_CODE1_ADDR); + pNOR_ID->Device_Code2 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, + DEVICE_CODE2_ADDR); + pNOR_ID->Device_Code3 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, + DEVICE_CODE3_ADDR); + } + + /* Check the NOR controller state */ + hnor->State = state; + + /* Process unlocked */ + __HAL_UNLOCK(hnor); + } + else + { + return HAL_ERROR; + } + + return status; +} + +/** + * @brief Returns the NOR memory to Read mode. + * @param hnor pointer to a NOR_HandleTypeDef structure that contains + * the configuration information for NOR module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NOR_ReturnToReadMode(NOR_HandleTypeDef *hnor) +{ + uint32_t deviceaddress; + HAL_NOR_StateTypeDef state; + HAL_StatusTypeDef status = HAL_OK; + + /* Check the NOR controller state */ + state = hnor->State; + if (state == HAL_NOR_STATE_BUSY) + { + return HAL_BUSY; + } + else if (state == HAL_NOR_STATE_PROTECTED) + { + return HAL_ERROR; + } + else if (state == HAL_NOR_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hnor); + + /* Update the NOR controller state */ + hnor->State = HAL_NOR_STATE_BUSY; + + /* Select the NOR device address */ + if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) + { + deviceaddress = NOR_MEMORY_ADRESS1; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) + { + deviceaddress = NOR_MEMORY_ADRESS2; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) + { + deviceaddress = NOR_MEMORY_ADRESS3; + } + else /* FMC_NORSRAM_BANK4 */ + { + deviceaddress = NOR_MEMORY_ADRESS4; + } + + if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET) + { + NOR_WRITE(deviceaddress, NOR_CMD_DATA_READ_RESET); + } + else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET) + { + NOR_WRITE(deviceaddress, NOR_CMD_READ_ARRAY); + } + else + { + /* Primary command set not supported by the driver */ + status = HAL_ERROR; + } + + /* Check the NOR controller state */ + hnor->State = state; + + /* Process unlocked */ + __HAL_UNLOCK(hnor); + } + else + { + return HAL_ERROR; + } + + return status; +} + +/** + * @brief Read data from NOR memory + * @param hnor pointer to a NOR_HandleTypeDef structure that contains + * the configuration information for NOR module. + * @param pAddress pointer to Device address + * @param pData pointer to read data + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NOR_Read(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData) +{ + uint32_t deviceaddress; + HAL_NOR_StateTypeDef state; + HAL_StatusTypeDef status = HAL_OK; + + /* Check the NOR controller state */ + state = hnor->State; + if (state == HAL_NOR_STATE_BUSY) + { + return HAL_BUSY; + } + else if (state == HAL_NOR_STATE_PROTECTED) + { + return HAL_ERROR; + } + else if (state == HAL_NOR_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hnor); + + /* Update the NOR controller state */ + hnor->State = HAL_NOR_STATE_BUSY; + + /* Select the NOR device address */ + if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) + { + deviceaddress = NOR_MEMORY_ADRESS1; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) + { + deviceaddress = NOR_MEMORY_ADRESS2; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) + { + deviceaddress = NOR_MEMORY_ADRESS3; + } + else /* FMC_NORSRAM_BANK4 */ + { + deviceaddress = NOR_MEMORY_ADRESS4; + } + + /* Send read data command */ + if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET) + { + if (uwNORMemoryDataWidth == NOR_MEMORY_8B) + { + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_BYTE), + NOR_CMD_DATA_FIRST); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND_BYTE), + NOR_CMD_DATA_SECOND); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD_BYTE), + NOR_CMD_DATA_READ_RESET); + } + else + { + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), + NOR_CMD_DATA_READ_RESET); + } + } + else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET) + { + NOR_WRITE(pAddress, NOR_CMD_READ_ARRAY); + } + else + { + /* Primary command set not supported by the driver */ + status = HAL_ERROR; + } + + if (status != HAL_ERROR) + { + /* Read the data */ + *pData = (uint16_t)(*(__IO uint32_t *)pAddress); + } + + /* Check the NOR controller state */ + hnor->State = state; + + /* Process unlocked */ + __HAL_UNLOCK(hnor); + } + else + { + return HAL_ERROR; + } + + return status; +} + +/** + * @brief Program data to NOR memory + * @param hnor pointer to a NOR_HandleTypeDef structure that contains + * the configuration information for NOR module. + * @param pAddress Device address + * @param pData pointer to the data to write + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NOR_Program(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData) +{ + uint32_t deviceaddress; + HAL_StatusTypeDef status = HAL_OK; + + /* Check the NOR controller state */ + if (hnor->State == HAL_NOR_STATE_BUSY) + { + return HAL_BUSY; + } + else if (hnor->State == HAL_NOR_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hnor); + + /* Update the NOR controller state */ + hnor->State = HAL_NOR_STATE_BUSY; + + /* Select the NOR device address */ + if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) + { + deviceaddress = NOR_MEMORY_ADRESS1; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) + { + deviceaddress = NOR_MEMORY_ADRESS2; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) + { + deviceaddress = NOR_MEMORY_ADRESS3; + } + else /* FMC_NORSRAM_BANK4 */ + { + deviceaddress = NOR_MEMORY_ADRESS4; + } + + /* Send program data command */ + if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET) + { + if (uwNORMemoryDataWidth == NOR_MEMORY_8B) + { + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_BYTE), + NOR_CMD_DATA_FIRST); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND_BYTE), + NOR_CMD_DATA_SECOND); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD_BYTE), + NOR_CMD_DATA_PROGRAM); + } + else + { + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_PROGRAM); + } + } + else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET) + { + NOR_WRITE(pAddress, NOR_CMD_WORD_PROGRAM); + } + else + { + /* Primary command set not supported by the driver */ + status = HAL_ERROR; + } + + if (status != HAL_ERROR) + { + /* Write the data */ + NOR_WRITE(pAddress, *pData); + } + + /* Check the NOR controller state */ + hnor->State = HAL_NOR_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnor); + } + else + { + return HAL_ERROR; + } + + return status; +} + +/** + * @brief Reads a half-word buffer from the NOR memory. + * @param hnor pointer to the NOR handle + * @param uwAddress NOR memory internal address to read from. + * @param pData pointer to the buffer that receives the data read from the + * NOR memory. + * @param uwBufferSize number of Half word to read. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NOR_ReadBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData, + uint32_t uwBufferSize) +{ + uint32_t deviceaddress; + uint32_t size = uwBufferSize; + uint32_t address = uwAddress; + uint16_t *data = pData; + HAL_NOR_StateTypeDef state; + HAL_StatusTypeDef status = HAL_OK; + + /* Check the NOR controller state */ + state = hnor->State; + if (state == HAL_NOR_STATE_BUSY) + { + return HAL_BUSY; + } + else if (state == HAL_NOR_STATE_PROTECTED) + { + return HAL_ERROR; + } + else if (state == HAL_NOR_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hnor); + + /* Update the NOR controller state */ + hnor->State = HAL_NOR_STATE_BUSY; + + /* Select the NOR device address */ + if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) + { + deviceaddress = NOR_MEMORY_ADRESS1; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) + { + deviceaddress = NOR_MEMORY_ADRESS2; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) + { + deviceaddress = NOR_MEMORY_ADRESS3; + } + else /* FMC_NORSRAM_BANK4 */ + { + deviceaddress = NOR_MEMORY_ADRESS4; + } + + /* Send read data command */ + if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET) + { + if (uwNORMemoryDataWidth == NOR_MEMORY_8B) + { + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_BYTE), + NOR_CMD_DATA_FIRST); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND_BYTE), + NOR_CMD_DATA_SECOND); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD_BYTE), + NOR_CMD_DATA_READ_RESET); + } + else + { + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), + NOR_CMD_DATA_READ_RESET); + } + } + else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET) + { + NOR_WRITE(deviceaddress, NOR_CMD_READ_ARRAY); + } + else + { + /* Primary command set not supported by the driver */ + status = HAL_ERROR; + } + + if (status != HAL_ERROR) + { + /* Read buffer */ + while (size > 0U) + { + *data = *(__IO uint16_t *)address; + data++; + address += 2U; + size--; + } + } + + /* Check the NOR controller state */ + hnor->State = state; + + /* Process unlocked */ + __HAL_UNLOCK(hnor); + } + else + { + return HAL_ERROR; + } + + return status; +} + +/** + * @brief Writes a half-word buffer to the NOR memory. This function must be used + only with S29GL128P NOR memory. + * @param hnor pointer to the NOR handle + * @param uwAddress NOR memory internal start write address + * @param pData pointer to source data buffer. + * @param uwBufferSize Size of the buffer to write + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NOR_ProgramBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData, + uint32_t uwBufferSize) +{ + uint16_t *p_currentaddress; + const uint16_t *p_endaddress; + uint16_t *data = pData; + uint32_t deviceaddress; + HAL_StatusTypeDef status = HAL_OK; + + /* Check the NOR controller state */ + if (hnor->State == HAL_NOR_STATE_BUSY) + { + return HAL_BUSY; + } + else if (hnor->State == HAL_NOR_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hnor); + + /* Update the NOR controller state */ + hnor->State = HAL_NOR_STATE_BUSY; + + /* Select the NOR device address */ + if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) + { + deviceaddress = NOR_MEMORY_ADRESS1; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) + { + deviceaddress = NOR_MEMORY_ADRESS2; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) + { + deviceaddress = NOR_MEMORY_ADRESS3; + } + else /* FMC_NORSRAM_BANK4 */ + { + deviceaddress = NOR_MEMORY_ADRESS4; + } + + /* Initialize variables */ + p_currentaddress = (uint16_t *)(deviceaddress + uwAddress); + p_endaddress = (uint16_t *)(deviceaddress + uwAddress + (2U * (uwBufferSize - 1U))); + + if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET) + { + if (uwNORMemoryDataWidth == NOR_MEMORY_8B) + { + /* Issue unlock command sequence */ + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_BYTE), + NOR_CMD_DATA_FIRST); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND_BYTE), + NOR_CMD_DATA_SECOND); + } + else + { + /* Issue unlock command sequence */ + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); + } + /* Write Buffer Load Command */ + NOR_WRITE((deviceaddress + uwAddress), NOR_CMD_DATA_BUFFER_AND_PROG); + NOR_WRITE((deviceaddress + uwAddress), (uint16_t)(uwBufferSize - 1U)); + } + else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET) + { + /* Write Buffer Load Command */ + NOR_WRITE((deviceaddress + uwAddress), NOR_CMD_BUFFERED_PROGRAM); + NOR_WRITE((deviceaddress + uwAddress), (uint16_t)(uwBufferSize - 1U)); + } + else + { + /* Primary command set not supported by the driver */ + status = HAL_ERROR; + } + + if (status != HAL_ERROR) + { + /* Load Data into NOR Buffer */ + while (p_currentaddress <= p_endaddress) + { + NOR_WRITE(p_currentaddress, *data); + + data++; + p_currentaddress ++; + } + + if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET) + { + NOR_WRITE((deviceaddress + uwAddress), NOR_CMD_DATA_BUFFER_AND_PROG_CONFIRM); + } + else /* => hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET */ + { + NOR_WRITE((deviceaddress + uwAddress), NOR_CMD_CONFIRM); + } + } + + /* Check the NOR controller state */ + hnor->State = HAL_NOR_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnor); + } + else + { + return HAL_ERROR; + } + + return status; + +} + +/** + * @brief Erase the specified block of the NOR memory + * @param hnor pointer to a NOR_HandleTypeDef structure that contains + * the configuration information for NOR module. + * @param BlockAddress Block to erase address + * @param Address Device address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NOR_Erase_Block(NOR_HandleTypeDef *hnor, uint32_t BlockAddress, uint32_t Address) +{ + uint32_t deviceaddress; + HAL_StatusTypeDef status = HAL_OK; + + /* Check the NOR controller state */ + if (hnor->State == HAL_NOR_STATE_BUSY) + { + return HAL_BUSY; + } + else if (hnor->State == HAL_NOR_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hnor); + + /* Update the NOR controller state */ + hnor->State = HAL_NOR_STATE_BUSY; + + /* Select the NOR device address */ + if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) + { + deviceaddress = NOR_MEMORY_ADRESS1; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) + { + deviceaddress = NOR_MEMORY_ADRESS2; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) + { + deviceaddress = NOR_MEMORY_ADRESS3; + } + else /* FMC_NORSRAM_BANK4 */ + { + deviceaddress = NOR_MEMORY_ADRESS4; + } + + /* Send block erase command sequence */ + if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET) + { + if (uwNORMemoryDataWidth == NOR_MEMORY_8B) + { + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_BYTE), + NOR_CMD_DATA_FIRST); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND_BYTE), + NOR_CMD_DATA_SECOND); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD_BYTE), + NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD); + } + else + { + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), + NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FOURTH), + NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIFTH), + NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH); + } + NOR_WRITE((uint32_t)(BlockAddress + Address), NOR_CMD_DATA_BLOCK_ERASE); + } + else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET) + { + NOR_WRITE((BlockAddress + Address), NOR_CMD_BLOCK_UNLOCK); + NOR_WRITE((BlockAddress + Address), NOR_CMD_CONFIRM); + NOR_WRITE((BlockAddress + Address), NOR_CMD_BLOCK_ERASE); + NOR_WRITE((BlockAddress + Address), NOR_CMD_CONFIRM); + } + else + { + /* Primary command set not supported by the driver */ + status = HAL_ERROR; + } + + /* Check the NOR memory status and update the controller state */ + hnor->State = HAL_NOR_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnor); + } + else + { + return HAL_ERROR; + } + + return status; + +} + +/** + * @brief Erase the entire NOR chip. + * @param hnor pointer to a NOR_HandleTypeDef structure that contains + * the configuration information for NOR module. + * @param Address Device address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NOR_Erase_Chip(NOR_HandleTypeDef *hnor, uint32_t Address) +{ + uint32_t deviceaddress; + HAL_StatusTypeDef status = HAL_OK; + UNUSED(Address); + + /* Check the NOR controller state */ + if (hnor->State == HAL_NOR_STATE_BUSY) + { + return HAL_BUSY; + } + else if (hnor->State == HAL_NOR_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hnor); + + /* Update the NOR controller state */ + hnor->State = HAL_NOR_STATE_BUSY; + + /* Select the NOR device address */ + if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) + { + deviceaddress = NOR_MEMORY_ADRESS1; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) + { + deviceaddress = NOR_MEMORY_ADRESS2; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) + { + deviceaddress = NOR_MEMORY_ADRESS3; + } + else /* FMC_NORSRAM_BANK4 */ + { + deviceaddress = NOR_MEMORY_ADRESS4; + } + + /* Send NOR chip erase command sequence */ + if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET) + { + if (uwNORMemoryDataWidth == NOR_MEMORY_8B) + { + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_BYTE), + NOR_CMD_DATA_FIRST); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND_BYTE), + NOR_CMD_DATA_SECOND); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD_BYTE), + NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD); + } + else + { + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), + NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FOURTH), + NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIFTH), + NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SIXTH), + NOR_CMD_DATA_CHIP_ERASE); + } + } + else + { + /* Primary command set not supported by the driver */ + status = HAL_ERROR; + } + + /* Check the NOR memory status and update the controller state */ + hnor->State = HAL_NOR_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnor); + } + else + { + return HAL_ERROR; + } + + return status; +} + +/** + * @brief Read NOR flash CFI IDs + * @param hnor pointer to a NOR_HandleTypeDef structure that contains + * the configuration information for NOR module. + * @param pNOR_CFI pointer to NOR CFI IDs structure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NOR_Read_CFI(NOR_HandleTypeDef *hnor, NOR_CFITypeDef *pNOR_CFI) +{ + uint32_t deviceaddress; + HAL_NOR_StateTypeDef state; + + /* Check the NOR controller state */ + state = hnor->State; + if (state == HAL_NOR_STATE_BUSY) + { + return HAL_BUSY; + } + else if (state == HAL_NOR_STATE_PROTECTED) + { + return HAL_ERROR; + } + else if (state == HAL_NOR_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hnor); + + /* Update the NOR controller state */ + hnor->State = HAL_NOR_STATE_BUSY; + + /* Select the NOR device address */ + if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) + { + deviceaddress = NOR_MEMORY_ADRESS1; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) + { + deviceaddress = NOR_MEMORY_ADRESS2; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) + { + deviceaddress = NOR_MEMORY_ADRESS3; + } + else /* FMC_NORSRAM_BANK4 */ + { + deviceaddress = NOR_MEMORY_ADRESS4; + } + + /* Send read CFI query command */ + if (uwNORMemoryDataWidth == NOR_MEMORY_8B) + { + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_CFI_BYTE), + NOR_CMD_DATA_CFI); + } + else + { + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_CFI), NOR_CMD_DATA_CFI); + } + /* read the NOR CFI information */ + pNOR_CFI->CFI_1 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI1_ADDRESS); + pNOR_CFI->CFI_2 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI2_ADDRESS); + pNOR_CFI->CFI_3 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI3_ADDRESS); + pNOR_CFI->CFI_4 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI4_ADDRESS); + + /* Check the NOR controller state */ + hnor->State = state; + + /* Process unlocked */ + __HAL_UNLOCK(hnor); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +#if (USE_HAL_NOR_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User NOR Callback + * To be used to override the weak predefined callback + * @param hnor : NOR handle + * @param CallbackId : ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_NOR_MSP_INIT_CB_ID NOR MspInit callback ID + * @arg @ref HAL_NOR_MSP_DEINIT_CB_ID NOR MspDeInit callback ID + * @param pCallback : pointer to the Callback function + * @retval status + */ +HAL_StatusTypeDef HAL_NOR_RegisterCallback(NOR_HandleTypeDef *hnor, HAL_NOR_CallbackIDTypeDef CallbackId, + pNOR_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + HAL_NOR_StateTypeDef state; + + if (pCallback == NULL) + { + return HAL_ERROR; + } + + state = hnor->State; + if ((state == HAL_NOR_STATE_READY) || (state == HAL_NOR_STATE_RESET) || (state == HAL_NOR_STATE_PROTECTED)) + { + switch (CallbackId) + { + case HAL_NOR_MSP_INIT_CB_ID : + hnor->MspInitCallback = pCallback; + break; + case HAL_NOR_MSP_DEINIT_CB_ID : + hnor->MspDeInitCallback = pCallback; + break; + default : + /* update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* update return status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister a User NOR Callback + * NOR Callback is redirected to the weak predefined callback + * @param hnor : NOR handle + * @param CallbackId : ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_NOR_MSP_INIT_CB_ID NOR MspInit callback ID + * @arg @ref HAL_NOR_MSP_DEINIT_CB_ID NOR MspDeInit callback ID + * @retval status + */ +HAL_StatusTypeDef HAL_NOR_UnRegisterCallback(NOR_HandleTypeDef *hnor, HAL_NOR_CallbackIDTypeDef CallbackId) +{ + HAL_StatusTypeDef status = HAL_OK; + HAL_NOR_StateTypeDef state; + + state = hnor->State; + if ((state == HAL_NOR_STATE_READY) || (state == HAL_NOR_STATE_RESET) || (state == HAL_NOR_STATE_PROTECTED)) + { + switch (CallbackId) + { + case HAL_NOR_MSP_INIT_CB_ID : + hnor->MspInitCallback = HAL_NOR_MspInit; + break; + case HAL_NOR_MSP_DEINIT_CB_ID : + hnor->MspDeInitCallback = HAL_NOR_MspDeInit; + break; + default : + /* update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* update return status */ + status = HAL_ERROR; + } + + return status; +} +#endif /* (USE_HAL_NOR_REGISTER_CALLBACKS) */ + +/** + * @} + */ + +/** @defgroup NOR_Exported_Functions_Group3 NOR Control functions + * @brief management functions + * +@verbatim + ============================================================================== + ##### NOR Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control dynamically + the NOR interface. + +@endverbatim + * @{ + */ + +/** + * @brief Enables dynamically NOR write operation. + * @param hnor pointer to a NOR_HandleTypeDef structure that contains + * the configuration information for NOR module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NOR_WriteOperation_Enable(NOR_HandleTypeDef *hnor) +{ + /* Check the NOR controller state */ + if (hnor->State == HAL_NOR_STATE_PROTECTED) + { + /* Process Locked */ + __HAL_LOCK(hnor); + + /* Update the NOR controller state */ + hnor->State = HAL_NOR_STATE_BUSY; + + /* Enable write operation */ + (void)FMC_NORSRAM_WriteOperation_Enable(hnor->Instance, hnor->Init.NSBank); + + /* Update the NOR controller state */ + hnor->State = HAL_NOR_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnor); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Disables dynamically NOR write operation. + * @param hnor pointer to a NOR_HandleTypeDef structure that contains + * the configuration information for NOR module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NOR_WriteOperation_Disable(NOR_HandleTypeDef *hnor) +{ + /* Check the NOR controller state */ + if (hnor->State == HAL_NOR_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hnor); + + /* Update the NOR controller state */ + hnor->State = HAL_NOR_STATE_BUSY; + + /* Disable write operation */ + (void)FMC_NORSRAM_WriteOperation_Disable(hnor->Instance, hnor->Init.NSBank); + + /* Update the NOR controller state */ + hnor->State = HAL_NOR_STATE_PROTECTED; + + /* Process unlocked */ + __HAL_UNLOCK(hnor); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup NOR_Exported_Functions_Group4 NOR State functions + * @brief Peripheral State functions + * +@verbatim + ============================================================================== + ##### NOR State functions ##### + ============================================================================== + [..] + This subsection permits to get in run-time the status of the NOR controller + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief return the NOR controller state + * @param hnor pointer to a NOR_HandleTypeDef structure that contains + * the configuration information for NOR module. + * @retval NOR controller state + */ +HAL_NOR_StateTypeDef HAL_NOR_GetState(const NOR_HandleTypeDef *hnor) +{ + return hnor->State; +} + +/** + * @brief Returns the NOR operation status. + * @param hnor pointer to a NOR_HandleTypeDef structure that contains + * the configuration information for NOR module. + * @param Address Device address + * @param Timeout NOR programming Timeout + * @retval NOR_Status The returned value can be: HAL_NOR_STATUS_SUCCESS, HAL_NOR_STATUS_ERROR + * or HAL_NOR_STATUS_TIMEOUT + */ +HAL_NOR_StatusTypeDef HAL_NOR_GetStatus(NOR_HandleTypeDef *hnor, uint32_t Address, uint32_t Timeout) +{ + HAL_NOR_StatusTypeDef status = HAL_NOR_STATUS_ONGOING; + uint16_t tmpsr1; + uint16_t tmpsr2; + uint32_t tickstart; + + /* Poll on NOR memory Ready/Busy signal ------------------------------------*/ + HAL_NOR_MspWait(hnor, Timeout); + + /* Get the NOR memory operation status -------------------------------------*/ + + /* Get tick */ + tickstart = HAL_GetTick(); + + if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET) + { + while ((status != HAL_NOR_STATUS_SUCCESS) && (status != HAL_NOR_STATUS_TIMEOUT)) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + status = HAL_NOR_STATUS_TIMEOUT; + } + } + + /* Read NOR status register (DQ6 and DQ5) */ + tmpsr1 = *(__IO uint16_t *)Address; + tmpsr2 = *(__IO uint16_t *)Address; + + /* If DQ6 did not toggle between the two reads then return HAL_NOR_STATUS_SUCCESS */ + if ((tmpsr1 & NOR_MASK_STATUS_DQ6) == (tmpsr2 & NOR_MASK_STATUS_DQ6)) + { + return HAL_NOR_STATUS_SUCCESS ; + } + + if ((tmpsr1 & NOR_MASK_STATUS_DQ5) == NOR_MASK_STATUS_DQ5) + { + status = HAL_NOR_STATUS_ONGOING; + } + + tmpsr1 = *(__IO uint16_t *)Address; + tmpsr2 = *(__IO uint16_t *)Address; + + /* If DQ6 did not toggle between the two reads then return HAL_NOR_STATUS_SUCCESS */ + if ((tmpsr1 & NOR_MASK_STATUS_DQ6) == (tmpsr2 & NOR_MASK_STATUS_DQ6)) + { + return HAL_NOR_STATUS_SUCCESS; + } + if ((tmpsr1 & NOR_MASK_STATUS_DQ5) == NOR_MASK_STATUS_DQ5) + { + return HAL_NOR_STATUS_ERROR; + } + } + } + else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET) + { + do + { + NOR_WRITE(Address, NOR_CMD_READ_STATUS_REG); + tmpsr2 = *(__IO uint16_t *)(Address); + + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + return HAL_NOR_STATUS_TIMEOUT; + } + } + } while ((tmpsr2 & NOR_MASK_STATUS_DQ7) == 0U); + + NOR_WRITE(Address, NOR_CMD_READ_STATUS_REG); + tmpsr1 = *(__IO uint16_t *)(Address); + if ((tmpsr1 & (NOR_MASK_STATUS_DQ5 | NOR_MASK_STATUS_DQ4)) != 0U) + { + /* Clear the Status Register */ + NOR_WRITE(Address, NOR_CMD_READ_STATUS_REG); + status = HAL_NOR_STATUS_ERROR; + } + else + { + status = HAL_NOR_STATUS_SUCCESS; + } + } + else + { + /* Primary command set not supported by the driver */ + status = HAL_NOR_STATUS_ERROR; + } + + /* Return the operation status */ + return status; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_NOR_MODULE_ENABLED */ + +/** + * @} + */ + +#endif /* FMC_BANK1 */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_opamp.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_opamp.c new file mode 100644 index 0000000000..c4490094e1 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_opamp.c @@ -0,0 +1,1169 @@ +/** + ********************************************************************************************************************** + * @file stm32h5xx_hal_opamp.c + * @author MCD Application Team + * @brief OPAMP HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the operational amplifier(s) peripheral: + * + OPAMP configuration + * + OPAMP calibration + * Thanks to + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State functions + * + ********************************************************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ********************************************************************************************************************** + @verbatim + ====================================================================================================================== + ##### OPAMP Peripheral Features ##### + ====================================================================================================================== + + [..] The device integrates one operational amplifiers OPAMP1 + + (#) The OPAMP provides several exclusive running modes. + (++) Standalone mode + (++) Programmable Gain Amplifier (PGA) modes + (++) Follower mode + + (#) Each OPAMP(s) can be configured in normal and high speed mode. + + (#) The OPAMP(s) provide(s) calibration capabilities. + (++) Calibration aims at correcting some offset for running mode. + (++) The OPAMP uses either factory calibration settings OR user defined + calibration (trimming) settings (i.e. trimming mode). + (++) The user defined settings can be figured out using self calibration + handled by HAL_OPAMP_SelfCalibrate + (++) HAL_OPAMP_SelfCalibrate: + (+++) Runs automatically the calibration in 2 steps. + (90% of VDDA for NMOS transistors, 10% of VDDA for PMOS transistors). + (As OPAMP is Rail-to-rail input/output, these 2 steps calibration is + appropriate and enough in most cases). + (+++) Runs automatically the calibration. + (+++) Enables the user trimming mode + (+++) Updates the init structure with trimming values with fresh calibration + results. + The user may store the calibration results for larger + (ex monitoring the trimming as a function of temperature + for instance) + + (#) Running mode: Standalone mode + (++) Gain is set externally (gain depends on external loads). + (++) Follower mode also possible externally by connecting the inverting input to + the output. + + (#) Running mode: Follower mode + (++) No Inverting Input is connected. + + (#) Running mode: Programmable Gain Amplifier (PGA) mode + (Resistor feedback output) + (#) The OPAMP(s) output(s) can be internally connected to resistor feedback + output. + (#) OPAMP gain can be selected as : + + (##) Gain of x2, x4, x8 or x16 for non inverting mode with: + (+++) VREF- referenced. + (+++) Filtering on VINM0, VREF- referenced. + (+++) VINM0 node for bias voltage and VINP0 for input signal. + (+++) VINM0 node for bias voltage and VINP0 for input signal, VINM1 node for filtering. + + (##) Gain of x-1, x-3, x-7 or x-15 for inverting mode with: + (+++) VINM0 node for input signal and VINP0 for bias. + (+++) VINM0 node for input signal and VINP0 for bias voltage, VINM1 node for filtering. + + (#) The OPAMPs inverting input can be selected according to the Reference Manual + "OPAMP functional description" chapter. + + (#) The OPAMPs non inverting input can be selected according to the Reference Manual + "OPAMP functional description" chapter. + + ====================================================================================================================== + ##### How to use this driver ##### + ====================================================================================================================== + [..] + + *** High speed / normal power mode *** + ============================================ + [..] To run in high speed mode: + + (#) Configure the OPAMP using HAL_OPAMP_Init() function: + (++) Select OPAMP_POWERMODE_HIGHSPEED + (++) Otherwise select OPAMP_POWERMODE_NORMAL + + *** Calibration *** + ============================================ + [..] To run the OPAMP calibration self calibration: + + (#) Start calibration using HAL_OPAMP_SelfCalibrate. + Store the calibration results. + + *** Running mode *** + ============================================ + + [..] To use the OPAMP, perform the following steps: + + (#) Fill in the HAL_OPAMP_MspInit() to + (++) Enable the OPAMP Peripheral clock using macro __HAL_RCC_OPAMP_CLK_ENABLE() + (++) Configure the OPAMP input AND output in analog mode using + HAL_GPIO_Init() to map the OPAMP output to the GPIO pin. + + (#) Registrate Callbacks + (++) The compilation define USE_HAL_OPAMP_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + + (++) Use Functions HAL_OPAMP_RegisterCallback() to register a user callback, + it allows to register following callbacks: + (+++) MspInitCallback : OPAMP MspInit. + (+++) MspDeInitCallback : OPAMP MspDeInit. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + + (++) Use function HAL_OPAMP_UnRegisterCallback() to reset a callback to the default + weak (overridden) function. It allows to reset following callbacks: + (+++) MspInitCallback : OPAMP MspInit. + (+++) MspDeInitCallback : OPAMP MspDeInit. + (+++) All Callbacks + (#) Configure the OPAMP using HAL_OPAMP_Init() function: + (++) Select the mode + (++) Select the inverting input + (++) Select the non-inverting input + (++) If PGA mode is enabled, Select if inverting input is connected. + (++) Select either factory or user defined trimming mode. + (++) If the user-defined trimming mode is enabled, select PMOS & NMOS trimming values + (typically values set by HAL_OPAMP_SelfCalibrate function). + + (#) Enable the OPAMP using HAL_OPAMP_Start() function. + + (#) Disable the OPAMP using HAL_OPAMP_Stop() function. + + (#) Lock the OPAMP in running mode using HAL_OPAMP_Lock() function. + Caution: On STM32H5, HAL OPAMP lock is software lock only (not + hardware lock as on some other STM32 devices) + + (#) If needed, unlock the OPAMP using HAL_OPAMPEx_Unlock() function. + + *** Running mode: change of configuration while OPAMP ON *** + ============================================================ + [..] To Re-configure OPAMP when OPAMP is ON (change on the fly) + (#) If needed, fill in the HAL_OPAMP_MspInit() + (++) This is the case for instance if you wish to use new OPAMP I/O + + (#) Configure the OPAMP using HAL_OPAMP_Init() function: + (++) As in configure case, select first the parameters you wish to modify. + + (#) Change from high speed mode to normal power mode (& vice versa) requires + first HAL_OPAMP_DeInit() (force OPAMP OFF) and then HAL_OPAMP_Init(). + In other words, of OPAMP is ON, HAL_OPAMP_Init can NOT change power mode + alone. + + *** OPAMP pinout *** + ============================================ + Table 1. OPAMPs inverting/non-inverting inputs for the STM32H5 devices: + + +--------------------------------------------------- + | | | OPAMP1 | + |-----------------|---------|----------------------| + | Inverting Input | VM_SEL | VINM0-> PC5 | + | | | VINM1-> PB1 | + | | | Internal: | + | | | ADC1_INP8 | + | | | ADC1_INP5 | + | | | ADC1_INM4 | + | | | COMP1_INM6 | + | | | OPAMP1_OUT | + | | | PGA mode | + |-----------------|---------|----------------------| + | Non Inverting | VP_SEL | | + | | | VP0 -> PB0 (GPIO) | + | | | VP2 -> PA0 (GPIO) | + | | | Internal: | + | Input | | DAC1_CH1_int | + | | | ADC1_INM5 | + | | | ADC1_INM1 | + | | | ADC1_INP9 | + | | | ADC1_INP0 | + | | | COMP1_INP1 | + +--------------------------------------------------- + + + [..] Table 2. OPAMPs outputs for the STM32H5 devices: + + +--------------------------------------------------- + | | | OPAMP1 | + |-----------------|--------|-----------------------| + | Output | VOUT | External : | + | | | PA7 | + | | | | + | | | Internal : | + | | | ADC1_INM3 | + | | | ADC1_INP7 | + |-----------------|--------|-----------------------| + + @endverbatim + ********************************************************************************************************************** + */ + +/* Includes ----------------------------------------------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup OPAMP OPAMP + * @brief OPAMP module driver + * @{ + */ + +#ifdef HAL_OPAMP_MODULE_ENABLED + +#if defined (OPAMP1) + +/* Private types -----------------------------------------------------------------------------------------------------*/ +/* Private variables -------------------------------------------------------------------------------------------------*/ +/* Private constants -------------------------------------------------------------------------------------------------*/ +/** @addtogroup OPAMP_Private_Constants + * @{ + */ + +/* CSR register reset value */ +#define OPAMP_CSR_RESET_VALUE 0x00000000U + +/* CSR Init masks */ +#define OPAMP_CSR_INIT_MASK_PGA (OPAMP_CSR_OPAHSM | OPAMP_CSR_VMSEL | OPAMP_CSR_PGGAIN | OPAMP_CSR_PGGAIN \ + | OPAMP_CSR_VPSEL | OPAMP_CSR_USERTRIM) + + +#define OPAMP_CSR_INIT_MASK_FOLLOWER (OPAMP_CSR_OPAHSM | OPAMP_CSR_VMSEL| OPAMP_CSR_VPSEL \ + | OPAMP_CSR_USERTRIM) + + +#define OPAMP_CSR_INIT_MASK_STANDALONE (OPAMP_CSR_OPAHSM | OPAMP_CSR_VMSEL | OPAMP_CSR_VPSEL \ + | OPAMP_CSR_VMSEL | OPAMP_CSR_USERTRIM) +/** + * @} + */ + +/* Private macros ----------------------------------------------------------------------------------------------------*/ +/* Private functions -------------------------------------------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------------------------------------------------*/ + +/** @defgroup OPAMP_Exported_Functions OPAMP Exported Functions + * @{ + */ + +/** @defgroup OPAMP_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + ====================================================================================================================== + ##### Initialization and de-initialization functions ##### + ====================================================================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the OPAMP according to the specified + * parameters in the OPAMP_InitTypeDef and initialize the associated handle. + * @note If the selected opamp is locked, initialization can't be performed. + * To unlock the configuration, perform a system reset. + * @param hopamp OPAMP handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_OPAMP_Init(OPAMP_HandleTypeDef *hopamp) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t updateotrlpotr; + + /* Check the OPAMP handle allocation and lock status */ + /* Init not allowed if calibration is ongoing */ + if (hopamp == NULL) + { + return HAL_ERROR; + } + else if (hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED) + { + return HAL_ERROR; + } + else if (hopamp->State == HAL_OPAMP_STATE_CALIBBUSY) + { + return HAL_ERROR; + } + else + { + /* Check the parameter */ + assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance)); + + /* Set OPAMP parameters */ + assert_param(IS_OPAMP_POWERMODE(hopamp->Init.PowerMode)); + assert_param(IS_OPAMP_FUNCTIONAL_NORMALMODE(hopamp->Init.Mode)); + assert_param(IS_OPAMP_NONINVERTING_INPUT(hopamp->Init.NonInvertingInput)); + +#if (USE_HAL_OPAMP_REGISTER_CALLBACKS == 1U) + if (hopamp->State == HAL_OPAMP_STATE_RESET) + { + if (hopamp->MspInitCallback == NULL) + { + hopamp->MspInitCallback = HAL_OPAMP_MspInit; + } + } +#endif /* USE_HAL_OPAMP_REGISTER_CALLBACKS */ + if ((hopamp->Init.Mode) == OPAMP_STANDALONE_MODE) + { + assert_param(IS_OPAMP_INVERTING_INPUT_STANDALONE(hopamp->Init.InvertingInput)); + } + + if ((hopamp->Init.Mode) == OPAMP_PGA_MODE) + { + assert_param(IS_OPAMP_PGA_GAIN(hopamp->Init.PgaGain)); + assert_param(IS_OPAMP_PGACONNECT(hopamp->Init.PgaConnect)); + } + + + assert_param(IS_OPAMP_TRIMMING(hopamp->Init.UserTrimming)); + + if ((hopamp->Init.UserTrimming) == OPAMP_TRIMMING_USER) + { + if (hopamp->Init.PowerMode == OPAMP_POWERMODE_NORMAL) + { + assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValueP)); + assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValueN)); + } + else + { + assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValuePHighSpeed)); + assert_param(IS_OPAMP_TRIMMINGVALUE(hopamp->Init.TrimmingValueNHighSpeed)); + } + } + + if (hopamp->State == HAL_OPAMP_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hopamp->Lock = HAL_UNLOCKED; + } + +#if (USE_HAL_OPAMP_REGISTER_CALLBACKS == 1U) + hopamp->MspInitCallback(hopamp); +#else + /* Call MSP init function */ + HAL_OPAMP_MspInit(hopamp); +#endif /* USE_HAL_OPAMP_REGISTER_CALLBACKS */ + + /* Set operating mode */ + CLEAR_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALON); + /* In PGA mode InvertingInput is Not Applicable */ + if (hopamp->Init.Mode == OPAMP_PGA_MODE) + { + MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_INIT_MASK_PGA, \ + hopamp->Init.PowerMode | \ + hopamp->Init.Mode | \ + hopamp->Init.PgaGain | \ + hopamp->Init.PgaConnect | \ + hopamp->Init.NonInvertingInput | \ + hopamp->Init.UserTrimming); + } + + if (hopamp->Init.Mode == OPAMP_FOLLOWER_MODE) + { + /* In Follower mode InvertingInput is Not Applicable */ + MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_INIT_MASK_FOLLOWER, \ + hopamp->Init.PowerMode | \ + hopamp->Init.Mode | \ + hopamp->Init.NonInvertingInput | \ + hopamp->Init.UserTrimming); + } + + if (hopamp->Init.Mode == OPAMP_STANDALONE_MODE) + { + MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_INIT_MASK_STANDALONE, \ + hopamp->Init.PowerMode | \ + hopamp->Init.Mode | \ + hopamp->Init.InvertingInput | \ + hopamp->Init.NonInvertingInput | \ + hopamp->Init.UserTrimming); + } + + if (hopamp->Init.UserTrimming == OPAMP_TRIMMING_USER) + { + /* Set power mode and associated calibration parameters */ + if (hopamp->Init.PowerMode != OPAMP_POWERMODE_HIGHSPEED) + { + /* OPAMP_POWERMODE_NORMAL */ + /* Set calibration mode (factory or user) and values for */ + /* transistors differential pair high (PMOS) and low (NMOS) for */ + /* normal mode. */ + updateotrlpotr = (((hopamp->Init.TrimmingValueP) << (OPAMP_INPUT_NONINVERTING)) \ + | (hopamp->Init.TrimmingValueN)); + MODIFY_REG(hopamp->Instance->OTR, OPAMP_OTR_TRIMOFFSETN | OPAMP_OTR_TRIMOFFSETP, updateotrlpotr); + } + else + { + /* OPAMP_POWERMODE_HIGHSPEED*/ + /* transistors differential pair high (PMOS) and low (NMOS) for */ + /* high speed mode. */ + updateotrlpotr = (((hopamp->Init.TrimmingValuePHighSpeed) << (OPAMP_INPUT_NONINVERTING)) \ + | (hopamp->Init.TrimmingValueNHighSpeed)); + MODIFY_REG(hopamp->Instance->HSOTR, OPAMP_OTR_TRIMOFFSETN | OPAMP_OTR_TRIMOFFSETP, updateotrlpotr); + } + } + + /* Update the OPAMP state*/ + if (hopamp->State == HAL_OPAMP_STATE_RESET) + { + /* From RESET state to READY State */ + hopamp->State = HAL_OPAMP_STATE_READY; + } + /* else: remain in READY or BUSY state (no update) */ + return status; + } +} + +/** + * @brief DeInitialize the OPAMP peripheral + * @note Deinitialization can be performed if the OPAMP configuration is locked. + * (the lock is SW in H7) + * @param hopamp OPAMP handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_OPAMP_DeInit(OPAMP_HandleTypeDef *hopamp) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the OPAMP handle allocation */ + /* DeInit not allowed if calibration is on going */ + if (hopamp == NULL) + { + status = HAL_ERROR; + } + else if (hopamp->State == HAL_OPAMP_STATE_CALIBBUSY) + { + status = HAL_ERROR; + } + else + { + /* Check the parameter */ + assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance)); + + /* Set OPAMP_CSR register to reset value */ + WRITE_REG(hopamp->Instance->CSR, OPAMP_CSR_RESET_VALUE); + + /* DeInit the low level hardware */ +#if (USE_HAL_OPAMP_REGISTER_CALLBACKS == 1U) + if (hopamp->MspDeInitCallback == NULL) + { + hopamp->MspDeInitCallback = HAL_OPAMP_MspDeInit; + } + /* DeInit the low level hardware */ + hopamp->MspDeInitCallback(hopamp); +#else + HAL_OPAMP_MspDeInit(hopamp); +#endif /* USE_HAL_OPAMP_REGISTER_CALLBACKS */ + + /* Update the OPAMP state*/ + hopamp->State = HAL_OPAMP_STATE_RESET; + /* Process unlocked */ + __HAL_UNLOCK(hopamp); + + } + + return status; +} + + +/** + * @brief Initialize the OPAMP MSP. + * @param hopamp OPAMP handle + * @retval None + */ +__weak void HAL_OPAMP_MspInit(OPAMP_HandleTypeDef *hopamp) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hopamp); + + /* NOTE : This function should not be modified, when the callback is needed, + the function "HAL_OPAMP_MspInit()" must be implemented in the user file. + */ +} + +/** + * @brief DeInitialize OPAMP MSP. + * @param hopamp OPAMP handle + * @retval None + */ +__weak void HAL_OPAMP_MspDeInit(OPAMP_HandleTypeDef *hopamp) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hopamp); + /* NOTE : This function should not be modified, when the callback is needed, + the function "HAL_OPAMP_MspDeInit()" must be implemented in the user file. + */ +} + +/** + * @} + */ + + +/** @defgroup OPAMP_Exported_Functions_Group2 IO operation functions + * @brief IO operation functions + * +@verbatim + ======================================================================================================================= + ##### IO operation functions ##### + ======================================================================================================================= + [..] + This subsection provides a set of functions allowing to manage the OPAMP + start, stop and calibration actions. + +@endverbatim + * @{ + */ + +/** + * @brief Start the OPAMP. + * @param hopamp OPAMP handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_OPAMP_Start(OPAMP_HandleTypeDef *hopamp) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the OPAMP handle allocation */ + /* Check if OPAMP locked */ + if (hopamp == NULL) + { + status = HAL_ERROR; + } + else if (hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED) + { + status = HAL_ERROR; + } + else + { + /* Check the parameter */ + assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance)); + + if (hopamp->State == HAL_OPAMP_STATE_READY) + { + /* Enable the selected opamp */ + SET_BIT(hopamp->Instance->CSR, OPAMP_CSR_OPAMPxEN); + + /* Update the OPAMP state*/ + /* From HAL_OPAMP_STATE_READY to HAL_OPAMP_STATE_BUSY */ + hopamp->State = HAL_OPAMP_STATE_BUSY; + } + else + { + status = HAL_ERROR; + } + + } + return status; +} + +/** + * @brief Stop the OPAMP. + * @param hopamp OPAMP handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_OPAMP_Stop(OPAMP_HandleTypeDef *hopamp) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the OPAMP handle allocation */ + /* Check if OPAMP locked */ + /* Check if OPAMP calibration ongoing */ + if (hopamp == NULL) + { + status = HAL_ERROR; + } + else if (hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED) + { + status = HAL_ERROR; + } + else if (hopamp->State == HAL_OPAMP_STATE_CALIBBUSY) + { + status = HAL_ERROR; + } + else + { + /* Check the parameter */ + assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance)); + + if (hopamp->State == HAL_OPAMP_STATE_BUSY) + { + /* Disable the selected opamp */ + CLEAR_BIT(hopamp->Instance->CSR, OPAMP_CSR_OPAMPxEN); + + /* Update the OPAMP state*/ + /* From HAL_OPAMP_STATE_BUSY to HAL_OPAMP_STATE_READY*/ + hopamp->State = HAL_OPAMP_STATE_READY; + } + else + { + status = HAL_ERROR; + } + } + return status; +} + +/** + * @brief Run the self calibration of one OPAMP. + * @note Calibration is performed in the mode specified in OPAMP init + * structure (mode normal or high-speed). To perform calibration for + * both modes, repeat this function twice after OPAMP init structure + * accordingly updated. + * @param hopamp handle + * @retval Updated offset trimming values (PMOS & NMOS), user trimming is enabled + * @retval HAL status + */ +HAL_StatusTypeDef HAL_OPAMP_SelfCalibrate(OPAMP_HandleTypeDef *hopamp) +{ + + HAL_StatusTypeDef status = HAL_OK; + + uint32_t trimmingvaluen; + uint32_t trimmingvaluep; + uint32_t delta; + uint32_t opampmode; + + /* Selection of register of trimming depending on power mode: OTR or HSOTR */ + __IO uint32_t *tmp_opamp_reg_trimming; + + /* Check the OPAMP handle allocation */ + /* Check if OPAMP locked */ + if (hopamp == NULL) + { + status = HAL_ERROR; + } + else if (hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED) + { + status = HAL_ERROR; + } + else + { + + /* Check if OPAMP in calibration mode and calibration not yet enable */ + if (hopamp->State == HAL_OPAMP_STATE_READY) + { + /* Check the parameter */ + assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance)); + assert_param(IS_OPAMP_POWERMODE(hopamp->Init.PowerMode)); + + opampmode = READ_BIT(hopamp->Instance->CSR, OPAMP_CSR_VMSEL); + + /* Use of standalone mode */ + MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_VMSEL, OPAMP_STANDALONE_MODE); + /* user trimming values are used for offset calibration */ + SET_BIT(hopamp->Instance->CSR, OPAMP_CSR_USERTRIM); + + /* Select trimming settings depending on power mode */ + if (hopamp->Init.PowerMode == OPAMP_POWERMODE_NORMAL) + { + tmp_opamp_reg_trimming = &hopamp->Instance->OTR; + + } + else + { + /* high speed Mode */ + tmp_opamp_reg_trimming = &hopamp->Instance->HSOTR; + } + + + /* Enable calibration */ + SET_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALON); + + /* Force internal reference on VP */ + SET_BIT(hopamp->Instance->CSR, OPAMP_CSR_FORCEVP); + + /* 1st calibration - N */ + MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_CALSEL, OPAMP_VREF_90VDDA); + + /* Enable the selected opamp */ + SET_BIT(hopamp->Instance->CSR, OPAMP_CSR_OPAMPxEN); + + /* Init trimming counter */ + /* Medium value */ + trimmingvaluen = 16U; + delta = 8U; + + while (delta != 0U) + { + /* Set candidate trimming */ + /* OPAMP_POWERMODE_NORMAL */ + MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OTR_TRIMOFFSETN, trimmingvaluen); + + /* OFFTRIMmax delay 2 ms as per datasheet (electrical characteristics */ + /* Offset trim time: during calibration, minimum time needed between */ + /* two steps to have 1 mV accuracy */ + HAL_Delay(OPAMP_TRIMMING_DELAY); + + if (READ_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALOUT) != 0U) + { + /* OPAMP_CSR_CALOUT is HIGH try higher trimming */ + trimmingvaluen += delta; + } + else + { + /* OPAMP_CSR_CALOUT is LOW try lower trimming */ + trimmingvaluen -= delta; + } + /* Divide range by 2 to continue dichotomy sweep */ + delta >>= 1; + } + + /* Still need to check if right calibration is current value or one step below */ + /* Indeed the first value that causes the OUTCAL bit to change from 1 to 0 */ + + MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OTR_TRIMOFFSETN, trimmingvaluen); + + /* OFFTRIMmax delay 2 ms as per datasheet (electrical characteristics */ + /* Offset trim time: during calibration, minimum time needed between */ + /* two steps to have 1 mV accuracy */ + HAL_Delay(OPAMP_TRIMMING_DELAY); + + if ((READ_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALOUT)) != 0U) + { + /* Trimming value is actually one value more */ + trimmingvaluen++; + /* Set right trimming */ + MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OTR_TRIMOFFSETN, trimmingvaluen); + } + + /* 2nd calibration - P */ + MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_CALSEL, OPAMP_VREF_10VDDA); + + /* Init trimming counter */ + /* Medium value */ + trimmingvaluep = 16U; + delta = 8U; + + while (delta != 0U) + { + /* Set candidate trimming */ + /* OPAMP_POWERMODE_NORMAL */ + MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OTR_TRIMOFFSETP, (trimmingvaluep << OPAMP_INPUT_NONINVERTING)); + + /* OFFTRIMmax delay 2 ms as per datasheet (electrical characteristics */ + /* Offset trim time: during calibration, minimum time needed between */ + /* two steps to have 1 mV accuracy */ + HAL_Delay(OPAMP_TRIMMING_DELAY); + + if (READ_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALOUT) != 0U) + { + /* OPAMP_CSR_CALOUT is HIGH try higher trimming */ + trimmingvaluep += delta; + } + else + { + /* OPAMP_CSR_CALOUT is LOW try lower trimming */ + trimmingvaluep -= delta; + } + + /* Divide range by 2 to continue dichotomy sweep */ + delta >>= 1U; + } + + /* Still need to check if right calibration is current value or one step below */ + /* Indeed the first value that causes the OUTCAL bit to change from 1 to 0 */ + /* Set candidate trimming */ + MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OTR_TRIMOFFSETP, (trimmingvaluep << OPAMP_INPUT_NONINVERTING)); + + /* OFFTRIMmax delay 2 ms as per datasheet (electrical characteristics */ + /* Offset trim time: during calibration, minimum time needed between */ + /* two steps to have 1 mV accuracy */ + HAL_Delay(OPAMP_TRIMMING_DELAY); + + if (READ_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALOUT) != 0U) + { + /* Trimming value is actually one value more */ + trimmingvaluep++; + MODIFY_REG(*tmp_opamp_reg_trimming, OPAMP_OTR_TRIMOFFSETP, (trimmingvaluep << OPAMP_INPUT_NONINVERTING)); + } + + /* Disable calibration & set normal mode (operating mode) */ + CLEAR_BIT(hopamp->Instance->CSR, OPAMP_CSR_CALON); + + /* Disable the OPAMP */ + CLEAR_BIT(hopamp->Instance->CSR, OPAMP_CSR_OPAMPxEN); + + /* Set operating mode back */ + CLEAR_BIT(hopamp->Instance->CSR, OPAMP_CSR_FORCEVP); + + /* Self calibration is successful */ + /* Store calibration(user trimming) results in init structure. */ + + /* Set user trimming mode */ + hopamp->Init.UserTrimming = OPAMP_TRIMMING_USER; + + /* Affect calibration parameters depending on mode normal/high speed */ + if (hopamp->Init.PowerMode != OPAMP_POWERMODE_HIGHSPEED) + { + /* Write calibration result N */ + hopamp->Init.TrimmingValueN = trimmingvaluen; + /* Write calibration result P */ + hopamp->Init.TrimmingValueP = trimmingvaluep; + } + else + { + /* Write calibration result N */ + hopamp->Init.TrimmingValueNHighSpeed = trimmingvaluen; + /* Write calibration result P */ + hopamp->Init.TrimmingValuePHighSpeed = trimmingvaluep; + } + /* Restore OPAMP mode after calibration */ + MODIFY_REG(hopamp->Instance->CSR, OPAMP_CSR_VMSEL, opampmode); + } + + else + { + /* OPAMP can not be calibrated from this mode */ + status = HAL_ERROR; + } + } + return status; +} + +/** + * @} + */ + +/** @defgroup OPAMP_Exported_Functions_Group3 Peripheral Control functions + * @brief Peripheral Control functions + * +@verbatim + ======================================================================================================================= + ##### Peripheral Control functions ##### + ======================================================================================================================= + [..] + This subsection provides a set of functions allowing to control the OPAMP data + transfers. + + + +@endverbatim + * @{ + */ + +/** + * @brief Lock the selected OPAMP configuration. + * @note On STM32H5, HAL OPAMP lock is software lock only (in + * contrast of hardware lock available on some other STM32 + * devices) + * @param hopamp OPAMP handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_OPAMP_Lock(OPAMP_HandleTypeDef *hopamp) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the OPAMP handle allocation */ + /* Check if OPAMP locked */ + /* OPAMP can be locked when enabled and running in normal mode */ + /* It is meaningless otherwise */ + if (hopamp == NULL) + { + status = HAL_ERROR; + } + + else if (hopamp->State != HAL_OPAMP_STATE_BUSY) + { + status = HAL_ERROR; + } + else + { + /* Check the parameter */ + assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance)); + + /* OPAMP state changed to locked */ + hopamp->State = HAL_OPAMP_STATE_BUSYLOCKED; + } + return status; +} + +/** + * @brief Return the OPAMP factory trimming value. + * @note On STM32H5 OPAMP, user can retrieve factory trimming if + * OPAMP has never been set to user trimming before. + * Therefore, this function must be called when OPAMP init + * parameter "UserTrimming" is set to trimming factory, + * and before OPAMP calibration (function + * "HAL_OPAMP_SelfCalibrate()"). + * Otherwise, factory trimming value cannot be retrieved and + * error status is returned. + * @param hopamp OPAMP handle + * @param trimmingoffset Trimming offset (P or N) + * This parameter must be a value of @ref OPAMP_FactoryTrimming + * @note Calibration parameter retrieved is corresponding to the mode + * specified in OPAMP init structure (mode normal or high-speed). + * To retrieve calibration parameters for both modes, repeat this + * function after OPAMP init structure accordingly updated. + * @retval Trimming value (P or N): range: 0->31 + * or OPAMP_FACTORYTRIMMING_DUMMY if trimming value is not available + * + */ +HAL_OPAMP_TrimmingValueTypeDef HAL_OPAMP_GetTrimOffset(const OPAMP_HandleTypeDef *hopamp, uint32_t trimmingoffset) +{ + HAL_OPAMP_TrimmingValueTypeDef trimmingvalue; + + /* Selection of register of trimming depending on power mode: OTR or LPOTR */ + __IO const uint32_t *tmp_opamp_reg_trimming; + + /* Check the OPAMP handle allocation */ + /* Value can be retrieved in HAL_OPAMP_STATE_READY state */ + if (hopamp == NULL) + { + return OPAMP_FACTORYTRIMMING_DUMMY; + } + + if (hopamp->State == HAL_OPAMP_STATE_READY) + { + /* Check the parameter */ + assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance)); + assert_param(IS_OPAMP_FACTORYTRIMMING(trimmingoffset)); + assert_param(IS_OPAMP_POWERMODE(hopamp->Init.PowerMode)); + + /* Check the trimming mode */ + if (READ_BIT(hopamp->Instance->CSR, OPAMP_CSR_USERTRIM) != 0U) + { + /* This function must called when OPAMP init parameter "UserTrimming" */ + /* is set to trimming factory, and before OPAMP calibration (function */ + /* "HAL_OPAMP_SelfCalibrate()"). */ + /* Otherwise, factory trimming value cannot be retrieved and error */ + /* status is returned. */ + trimmingvalue = OPAMP_FACTORYTRIMMING_DUMMY; + } + else + { + /* Select trimming settings depending on power mode */ + if (hopamp->Init.PowerMode == OPAMP_POWERMODE_NORMAL) + { + tmp_opamp_reg_trimming = &hopamp->Instance->OTR; + } + else + { + tmp_opamp_reg_trimming = &hopamp->Instance->HSOTR; + } + + /* Get factory trimming */ + if (trimmingoffset == OPAMP_FACTORYTRIMMING_P) + { + /* OPAMP_FACTORYTRIMMING_P */ + trimmingvalue = ((*tmp_opamp_reg_trimming) & OPAMP_OTR_TRIMOFFSETP) >> OPAMP_INPUT_NONINVERTING; + } + else + { + /* OPAMP_FACTORYTRIMMING_N */ + trimmingvalue = (*tmp_opamp_reg_trimming) & OPAMP_OTR_TRIMOFFSETN; + } + } + } + else + { + return OPAMP_FACTORYTRIMMING_DUMMY; + } + + return trimmingvalue; +} + +/** + * @} + */ + + +/** @defgroup OPAMP_Exported_Functions_Group4 Peripheral State functions + * @brief Peripheral State functions + * +@verbatim + ======================================================================================================================= + ##### Peripheral State functions ##### + ======================================================================================================================= + [..] + This subsection permits to get in run-time the status of the peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Return the OPAMP handle state. + * @param hopamp OPAMP handle + * @retval HAL state + */ +HAL_OPAMP_StateTypeDef HAL_OPAMP_GetState(const OPAMP_HandleTypeDef *hopamp) +{ + /* Check the OPAMP handle allocation */ + if (hopamp == NULL) + { + return HAL_OPAMP_STATE_RESET; + } + + /* Check the parameter */ + assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance)); + + /* Return OPAMP handle state */ + return hopamp->State; +} + +/** + * @} + */ + +#if (USE_HAL_OPAMP_REGISTER_CALLBACKS == 1U) +/** + * @brief Register a User OPAMP Callback + * To be used instead of the weak (overridden) predefined callback + * @note The HAL_OPAMP_RegisterCallback() may be called before HAL_OPAMP_Init() in HAL_OPAMP_STATE_RESET to register + * callbacks for HAL_OPAMP_MSPINIT_CB_ID and HAL_OPAMP_MSPDEINIT_CB_ID + * @param hopamp OPAMP handle + * @param CallbackId ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_OPAMP_MSPINIT_CB_ID OPAMP MspInit callback ID + * @arg @ref HAL_OPAMP_MSPDEINIT_CB_ID OPAMP MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @retval status + */ +HAL_StatusTypeDef HAL_OPAMP_RegisterCallback(OPAMP_HandleTypeDef *hopamp, HAL_OPAMP_CallbackIDTypeDef CallbackId, + pOPAMP_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + return HAL_ERROR; + } + + if (hopamp->State == HAL_OPAMP_STATE_READY) + { + switch (CallbackId) + { + case HAL_OPAMP_MSPINIT_CB_ID : + hopamp->MspInitCallback = pCallback; + break; + case HAL_OPAMP_MSPDEINIT_CB_ID : + hopamp->MspDeInitCallback = pCallback; + break; + default : + /* update return status */ + status = HAL_ERROR; + break; + } + } + else if (hopamp->State == HAL_OPAMP_STATE_RESET) + { + switch (CallbackId) + { + case HAL_OPAMP_MSPINIT_CB_ID : + hopamp->MspInitCallback = pCallback; + break; + case HAL_OPAMP_MSPDEINIT_CB_ID : + hopamp->MspDeInitCallback = pCallback; + break; + default : + /* update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* update return status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister a User OPAMP Callback + * OPAMP Callback is redirected to the weak (overridden) predefined callback + * @note The HAL_OPAMP_UnRegisterCallback() may be called before HAL_OPAMP_Init() in HAL_OPAMP_STATE_RESET to + * un-register callbacks for HAL_OPAMP_MSPINIT_CB_ID and HAL_OPAMP_MSPDEINIT_CB_ID + * @param hopamp OPAMP handle + * @param CallbackId ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_OPAMP_MSPINIT_CB_ID OPAMP MSP Init Callback ID + * @arg @ref HAL_OPAMP_MSPDEINIT_CB_ID OPAMP MSP DeInit Callback ID + * @arg @ref HAL_OPAMP_ALL_CB_ID OPAMP All Callbacks + * @retval status + */ +HAL_StatusTypeDef HAL_OPAMP_UnRegisterCallback(OPAMP_HandleTypeDef *hopamp, HAL_OPAMP_CallbackIDTypeDef CallbackId) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (hopamp->State == HAL_OPAMP_STATE_READY) + { + switch (CallbackId) + { + case HAL_OPAMP_MSPINIT_CB_ID : + hopamp->MspInitCallback = HAL_OPAMP_MspInit; + break; + case HAL_OPAMP_MSPDEINIT_CB_ID : + hopamp->MspDeInitCallback = HAL_OPAMP_MspDeInit; + break; + case HAL_OPAMP_ALL_CB_ID : + hopamp->MspInitCallback = HAL_OPAMP_MspInit; + hopamp->MspDeInitCallback = HAL_OPAMP_MspDeInit; + break; + default : + /* update return status */ + status = HAL_ERROR; + break; + } + } + else if (hopamp->State == HAL_OPAMP_STATE_RESET) + { + switch (CallbackId) + { + case HAL_OPAMP_MSPINIT_CB_ID : + hopamp->MspInitCallback = HAL_OPAMP_MspInit; + break; + case HAL_OPAMP_MSPDEINIT_CB_ID : + hopamp->MspDeInitCallback = HAL_OPAMP_MspDeInit; + break; + default : + /* update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* update return status */ + status = HAL_ERROR; + } + + return status; +} + +#endif /* USE_HAL_OPAMP_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** + * @} + */ + +#endif /* OPAMP1 */ + +#endif /* HAL_OPAMP_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_opamp_ex.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_opamp_ex.c new file mode 100644 index 0000000000..5a20c1a146 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_opamp_ex.c @@ -0,0 +1,118 @@ +/** + ********************************************************************************************************************** + * @file stm32h5xx_hal_opamp_ex.c + * @author MCD Application Team + * @brief Extended OPAMP HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the operational amplifier(s) peripheral: + * + Extended Initialization and de-initialization functions + * + Extended Peripheral Control functions + * + @verbatim + ********************************************************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ********************************************************************************************************************** + */ + +/* Includes ----------------------------------------------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup OPAMPEx OPAMPEx + * @brief OPAMP Extended HAL module driver + * @{ + */ + +#ifdef HAL_OPAMP_MODULE_ENABLED + +#if defined (OPAMP1) + +/* Private typedef ---------------------------------------------------------------------------------------------------*/ +/* Private define ----------------------------------------------------------------------------------------------------*/ +/* Private macro -----------------------------------------------------------------------------------------------------*/ +/* Private variables -------------------------------------------------------------------------------------------------*/ +/* Private function prototypes ---------------------------------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------------------------------------------------*/ + +/** @defgroup OPAMPEx_Exported_Functions OPAMP Extended Exported Functions + * @{ + */ + +/** @defgroup OPAMPEx_Exported_Functions_Group1 Peripheral Control functions + * @brief Peripheral Control functions + * +@verbatim + ======================================================================================================================= + ##### Peripheral Control functions ##### + ======================================================================================================================= + [..] + (+) OPAMP unlock. + +@endverbatim + * @{ + */ + +/** + * @brief Unlock the selected OPAMP configuration. + * @note This function must be called only when OPAMP is in state "locked". + * @param hopamp: OPAMP handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_OPAMPEx_Unlock(OPAMP_HandleTypeDef *hopamp) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the OPAMP handle allocation */ + /* Check if OPAMP locked */ + if (hopamp == NULL) + { + status = HAL_ERROR; + } + /* Check the OPAMP handle allocation */ + /* Check if OPAMP locked */ + else if (hopamp->State == HAL_OPAMP_STATE_BUSYLOCKED) + { + /* Check the parameter */ + assert_param(IS_OPAMP_ALL_INSTANCE(hopamp->Instance)); + + /* OPAMP state changed to locked */ + hopamp->State = HAL_OPAMP_STATE_BUSY; + } + else + { + status = HAL_ERROR; + } + + return status; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* OPAMP1 */ + +#endif /* HAL_OPAMP_MODULE_ENABLED */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_otfdec.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_otfdec.c new file mode 100644 index 0000000000..880e9e62b0 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_otfdec.c @@ -0,0 +1,1154 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_otfdec.c + * @author MCD Application Team + * @brief OTFDEC HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the On-The-Fly Decryption/Encryption (OTFDEC) + * peripheral: + * + Initialization and de-initialization functions + * + Region setting/enable functions + * + Peripheral State functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The OTFDEC HAL driver can be used as follows: + + (#) Declare an OTFDEC_HandleTypeDef handle structure (eg. OTFDEC_HandleTypeDef hotfdec). + + (#) Initialize the OTFDEC low level resources by implementing the HAL_OTFDEC_MspInit() API: + (++) Enable the OTFDEC interface clock. + (++) NVIC configuration if interrupts are used + (+++) Configure the OTFDEC interrupt priority. + (+++) Enable the NVIC OTFDEC IRQ handle. + + (#) Initialize the OTFDEC peripheral by calling the HAL_OTFDEC_Init() API. + + (#) In the case of encryption, enable ciphering mode for the peripheral + + (#) For each region, + + (++) Configure the region deciphering mode by calling the HAL_OTFDEC_RegionSetMode() API. + + (++) Write the region Key by calling the HAL_OTFDEC_RegionSetKey() API. If desired, + read the key CRC by calling HAL_OTFDEC_RegionGetKeyCRC() API and compare the + result with the theoretically expected CRC. + + (++) Initialize the OTFDEC region config structure with the Nonce, protected + region start and end addresses and firmware version, and wrap-up the region + configuration by calling HAL_OTFDEC_RegionConfig() API. + + (#) At this point, the OTFDEC region configuration is done and the deciphering + or enciphering enabled. The region can be deciphered on the fly after + having made sure the OctoSPI is configured in memory-mapped mode or data can + be enciphered by calling HAL_OTFDEC_Cipher() API. + + [..] + (@) Warning: the OTFDEC en/deciphering is based on a different endianness compared + to the AES-CTR as implemented in the AES peripheral. E.g., if the OTFEC + resorts to the Key (B0, B1, B2, B3) where Bi are 32-bit longwords and B0 + is the Least Significant Word, the AES has to be configured with the Key + (B3, B2, B1, B0) to report the same result (with the same swapping applied + to the Initialization Vector). + + [..] + + *** Callback registration *** + ============================================= + [..] + + The compilation flag USE_HAL_OTFDEC_REGISTER_CALLBACKS, when set to 1, + allows the user to configure dynamically the driver callbacks. + Use Functions @ref HAL_OTFDEC_RegisterCallback() + to register an interrupt callback. + [..] + + Function @ref HAL_OTFDEC_RegisterCallback() allows to register following callbacks: + (+) ErrorCallback : OTFDEC error callback + (+) MspInitCallback : OTFDEC Msp Init callback + (+) MspDeInitCallback : OTFDEC 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 @ref HAL_OTFDEC_UnRegisterCallback to reset a callback to the default + weak function. + [..] + + @ref HAL_OTFDEC_UnRegisterCallback takes as parameters the HAL peripheral handle, + and the Callback ID. + This function allows to reset following callbacks: + (+) ErrorCallback : OTFDEC error callback + (+) MspInitCallback : OTFDEC Msp Init callback + (+) MspDeInitCallback : OTFDEC Msp DeInit callback + [..] + + By default, after the @ref HAL_OTFDEC_Init() and when the state is @ref HAL_OTFDEC_STATE_RESET + all callbacks are set to the corresponding weak functions: + example @ref HAL_OTFDEC_ErrorCallback(). + Exception done for MspInit and MspDeInit functions that are + reset to the legacy weak functions in the @ref HAL_OTFDEC_Init()/ @ref HAL_OTFDEC_DeInit() only when + these callbacks are null (not registered beforehand). + [..] + + If MspInit or MspDeInit are not null, the @ref HAL_OTFDEC_Init()/ @ref HAL_OTFDEC_DeInit() + keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state. + [..] + + Callbacks can be registered/unregistered in @ref HAL_OTFDEC_STATE_READY state only. + Exception done MspInit/MspDeInit functions that can be registered/unregistered + in @ref HAL_OTFDEC_STATE_READY or @ref HAL_OTFDEC_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 @ref HAL_OTFDEC_RegisterCallback() before calling @ref HAL_OTFDEC_DeInit() + or @ref HAL_OTFDEC_Init() function. + [..] + + When the compilation flag USE_HAL_OTFDEC_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 "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup OTFDEC OTFDEC + * @brief OTFDEC HAL module driver. + * @{ + */ + + +#ifdef HAL_OTFDEC_MODULE_ENABLED + +#if defined(OTFDEC1) + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup OTFDEC_Exported_Functions + * @{ + */ + +/** @defgroup OTFDEC_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions. + * +@verbatim + ============================================================================== + ##### Initialization and de-initialization functions ##### + ============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the OTFDEC peripheral and create the associated handle. + * @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains + * the configuration information for OTFDEC module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_OTFDEC_Init(OTFDEC_HandleTypeDef *hotfdec) +{ + /* Check the OTFDEC handle allocation */ + if (hotfdec == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance)); + + if (hotfdec->State == HAL_OTFDEC_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + __HAL_UNLOCK(hotfdec); + +#if (USE_HAL_OTFDEC_REGISTER_CALLBACKS == 1) + /* Init the OTFDEC Callback settings */ + hotfdec->ErrorCallback = HAL_OTFDEC_ErrorCallback; /* Legacy weak callback */ + + if (hotfdec->MspInitCallback == NULL) + { + hotfdec->MspInitCallback = HAL_OTFDEC_MspInit; /* Legacy weak MspInit */ + } + + /* Init the low level hardware */ + hotfdec->MspInitCallback(hotfdec); +#else + /* Init the low level hardware */ + HAL_OTFDEC_MspInit(hotfdec); +#endif /* USE_HAL_OTFDEC_REGISTER_CALLBACKS */ + } + + /* Change the OTFDEC state */ + hotfdec->State = HAL_OTFDEC_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief DeInitialize the OTFDEC peripheral. + * @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains + * the configuration information for OTFDEC module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_OTFDEC_DeInit(OTFDEC_HandleTypeDef *hotfdec) +{ + /* Check the OTFDEC handle allocation */ + if (hotfdec == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance)); + + /* Change the OTFDEC state */ + hotfdec->State = HAL_OTFDEC_STATE_BUSY; + +#if (USE_HAL_OTFDEC_REGISTER_CALLBACKS == 1) + if (hotfdec->MspDeInitCallback == NULL) + { + hotfdec->MspDeInitCallback = HAL_OTFDEC_MspDeInit; /* Legacy weak MspDeInit */ + } + + /* DeInit the low level hardware: CLOCK, NVIC */ + hotfdec->MspDeInitCallback(hotfdec); +#else + /* DeInit the low level hardware: CLOCK, NVIC */ + HAL_OTFDEC_MspDeInit(hotfdec); +#endif /* USE_HAL_OTFDEC_REGISTER_CALLBACKS */ + + /* Change the OTFDEC state */ + hotfdec->State = HAL_OTFDEC_STATE_RESET; + + /* Reset OTFDEC error status */ + hotfdec->ErrorCode = HAL_OTFDEC_ERROR_NONE; + + /* Release Lock */ + __HAL_UNLOCK(hotfdec); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initialize the OTFDEC MSP. + * @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains + * the configuration information for OTFDEC module + * @retval None + */ +__weak void HAL_OTFDEC_MspInit(OTFDEC_HandleTypeDef *hotfdec) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hotfdec); + + /* NOTE : This function should not be modified; when the callback is needed, + the HAL_OTFDEC_MspInit can be implemented in the user file. + */ +} + +/** + * @brief DeInitialize OTFDEC MSP. + * @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains + * the configuration information for OTFDEC module + * @retval None + */ +__weak void HAL_OTFDEC_MspDeInit(OTFDEC_HandleTypeDef *hotfdec) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hotfdec); + + /* NOTE : This function should not be modified; when the callback is needed, + the HAL_OTFDEC_MspDeInit can be implemented in the user file. + */ +} + +#if (USE_HAL_OTFDEC_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User OTFDEC Callback + * To be used instead of the weak predefined callback + * @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains + * the configuration information for OTFDEC module + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_OTFDEC_ERROR_CB_ID OTFDEC error callback ID + * @arg @ref HAL_OTFDEC_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_OTFDEC_MSPDEINIT_CB_ID MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_OTFDEC_RegisterCallback(OTFDEC_HandleTypeDef *hotfdec, HAL_OTFDEC_CallbackIDTypeDef CallbackID, + pOTFDEC_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hotfdec->ErrorCode |= HAL_OTFDEC_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + if (hotfdec->State == HAL_OTFDEC_STATE_READY) + { + switch (CallbackID) + { + case HAL_OTFDEC_ERROR_CB_ID : + hotfdec->ErrorCallback = pCallback; + break; + + case HAL_OTFDEC_MSPINIT_CB_ID : + hotfdec->MspInitCallback = pCallback; + break; + + case HAL_OTFDEC_MSPDEINIT_CB_ID : + hotfdec->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hotfdec->ErrorCode |= HAL_OTFDEC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_OTFDEC_STATE_RESET == hotfdec->State) + { + switch (CallbackID) + { + case HAL_OTFDEC_MSPINIT_CB_ID : + hotfdec->MspInitCallback = pCallback; + break; + + case HAL_OTFDEC_MSPDEINIT_CB_ID : + hotfdec->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hotfdec->ErrorCode |= HAL_OTFDEC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hotfdec->ErrorCode |= HAL_OTFDEC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister a OTFDEC Callback + * OTFDEC callback is redirected to the weak predefined callback + * @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains + * the configuration information for OTFDEC module + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_OTFDEC_ERROR_CB_ID OTFDEC error callback ID + * @arg @ref HAL_OTFDEC_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_OTFDEC_MSPDEINIT_CB_ID MspDeInit callback ID + * @retval HAL status + */ +HAL_StatusTypeDef HAL_OTFDEC_UnRegisterCallback(OTFDEC_HandleTypeDef *hotfdec, HAL_OTFDEC_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (hotfdec->State == HAL_OTFDEC_STATE_READY) + { + switch (CallbackID) + { + case HAL_OTFDEC_ERROR_CB_ID : + hotfdec->ErrorCallback = HAL_OTFDEC_ErrorCallback; + break; + + case HAL_OTFDEC_MSPINIT_CB_ID : + hotfdec->MspInitCallback = HAL_OTFDEC_MspInit; /* Legacy weak MspInit */ + break; + + case HAL_OTFDEC_MSPDEINIT_CB_ID : + hotfdec->MspDeInitCallback = HAL_OTFDEC_MspDeInit; /* Legacy weak MspDeInit */ + break; + + default : + /* Update the error code */ + hotfdec->ErrorCode |= HAL_OTFDEC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_OTFDEC_STATE_RESET == hotfdec->State) + { + switch (CallbackID) + { + case HAL_OTFDEC_MSPINIT_CB_ID : + hotfdec->MspInitCallback = HAL_OTFDEC_MspInit; /* Legacy weak MspInit */ + break; + + case HAL_OTFDEC_MSPDEINIT_CB_ID : + hotfdec->MspDeInitCallback = HAL_OTFDEC_MspDeInit; /* Legacy weak MspDeInit */ + break; + + default : + /* Update the error code */ + hotfdec->ErrorCode |= HAL_OTFDEC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hotfdec->ErrorCode |= HAL_OTFDEC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +#endif /* USE_HAL_OTFDEC_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup OTFDEC_Exported_Functions_Group2 OTFDEC IRQ handler management + * @brief OTFDEC IRQ handler. + * +@verbatim + ============================================================================== + ##### OTFDEC IRQ handler management ##### + ============================================================================== +[..] This section provides OTFDEC IRQ handler function. + +@endverbatim + * @{ + */ + +/** + * @brief Handle OTFDEC interrupt request. + * @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains + * the configuration information for OTFDEC module + * @retval None + */ +void HAL_OTFDEC_IRQHandler(OTFDEC_HandleTypeDef *hotfdec) +{ + uint32_t isr_reg; + + isr_reg = READ_REG(hotfdec->Instance->ISR); + if ((isr_reg & OTFDEC_ISR_SEIF) == OTFDEC_ISR_SEIF) + { + SET_BIT(hotfdec->Instance->ICR, OTFDEC_ICR_SEIF); + hotfdec->ErrorCode |= HAL_OTFDEC_SECURITY_ERROR; + } + if ((isr_reg & OTFDEC_ISR_XONEIF) == OTFDEC_ISR_XONEIF) + { + SET_BIT(hotfdec->Instance->ICR, OTFDEC_ICR_XONEIF); + hotfdec->ErrorCode |= HAL_OTFDEC_EXECUTE_ERROR; + } + if ((isr_reg & OTFDEC_ISR_KEIF) == OTFDEC_ISR_KEIF) + { + SET_BIT(hotfdec->Instance->ICR, OTFDEC_ICR_KEIF); + hotfdec->ErrorCode |= HAL_OTFDEC_KEY_ERROR; + } + +#if (USE_HAL_OTFDEC_REGISTER_CALLBACKS == 1) + hotfdec->ErrorCallback(hotfdec); +#else + HAL_OTFDEC_ErrorCallback(hotfdec); +#endif /* USE_HAL_OTFDEC_REGISTER_CALLBACKS */ +} + +/** + * @brief OTFDEC error callback. + * @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains + * the configuration information for OTFDEC module + * @retval None + */ +__weak void HAL_OTFDEC_ErrorCallback(OTFDEC_HandleTypeDef *hotfdec) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hotfdec); + + /* NOTE : This function should not be modified; when the callback is needed, + the HAL_OTFDEC_ErrorCallback can be implemented in the user file. + */ +} + +/** + * @} + */ + + + + +/** @defgroup OTFDEC_Exported_Functions_Group3 Peripheral Control functions + * @brief Peripheral control functions. + * +@verbatim + ============================================================================== + ##### Peripheral Control functions ##### + ============================================================================== + [..] + This subsection permits to configure the OTFDEC peripheral + +@endverbatim + * @{ + */ + +/** + * @brief Lock region keys. + * @note Writes to this region KEYRx registers are ignored until next OTFDEC reset. + * @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains + * the configuration information for OTFDEC module + * @param RegionIndex index of region the keys of which are locked + * @retval HAL state + */ +HAL_StatusTypeDef HAL_OTFDEC_RegionKeyLock(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex) +{ + OTFDEC_Region_TypeDef *region; + uint32_t address; + + /* Check the parameters */ + assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance)); + assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex)); + + /* Take Lock */ + __HAL_LOCK(hotfdec); + + address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex); + region = (OTFDEC_Region_TypeDef *)address; + + SET_BIT(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_KEYLOCK); + + /* Release Lock */ + __HAL_UNLOCK(hotfdec); + + /* Status is okay */ + return HAL_OK; +} + +/** + * @brief Set region keys. + * @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains + * the configuration information for OTFDEC module + * @param RegionIndex index of region the keys of which are set + * @param pKey pointer at set of keys + * @note The API reads the key CRC computed by the peripheral and compares it with that + * theoretically expected. An error is reported if they are different. + * @retval HAL state + */ +HAL_StatusTypeDef HAL_OTFDEC_RegionSetKey(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex, uint32_t *pKey) +{ + OTFDEC_Region_TypeDef *region; + uint32_t address; + + /* Check the parameters */ + assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance)); + assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex)); + + if (pKey == NULL) + { + return HAL_ERROR; + } + else + { + /* Take Lock */ + __HAL_LOCK(hotfdec); + + address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex); + region = (OTFDEC_Region_TypeDef *)address; + + /* Set Key */ + WRITE_REG(region->REG_KEYR0, pKey[0]); + + __DSB(); + __ISB(); + + WRITE_REG(region->REG_KEYR1, pKey[1]); + + __DSB(); + __ISB(); + + WRITE_REG(region->REG_KEYR2, pKey[2]); + + __DSB(); + __ISB(); + + WRITE_REG(region->REG_KEYR3, pKey[3]); + + /* Compute theoretically expected CRC and compare it with that reported by the peripheral */ + if (HAL_OTFDEC_KeyCRCComputation(pKey) != HAL_OTFDEC_RegionGetKeyCRC(hotfdec, RegionIndex)) + { + /* Release Lock */ + __HAL_UNLOCK(hotfdec); + + /* Status is okay */ + return HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hotfdec); + + /* Status is okay */ + return HAL_OK; + } +} + +/** + * @brief Set region mode. + * @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains + * the configuration information for OTFDEC module + * @param RegionIndex index of region the mode of which is set + * @param mode This parameter can be only: + * @arg @ref OTFDEC_REG_MODE_INSTRUCTION_OR_DATA_ACCESSES + All read accesses are decrypted (instruction or data) + * @arg @ref OTFDEC_REG_MODE_INSTRUCTION_ACCESSES_ONLY_WITH_CIPHER + Only instruction accesses are decrypted with proprietary cipher activated + * @retval HAL state + */ +HAL_StatusTypeDef HAL_OTFDEC_RegionSetMode(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex, uint32_t mode) +{ + OTFDEC_Region_TypeDef *region; + uint32_t address; + + /* Check the parameters */ + assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance)); + assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex)); + assert_param(IS_OTFDEC_REGION_OPERATING_MODE(mode)); + + /* Take Lock */ + __HAL_LOCK(hotfdec); + + address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex); + region = (OTFDEC_Region_TypeDef *)address; + + /* Set mode */ + MODIFY_REG(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_MODE, mode); + + /* Release Lock */ + __HAL_UNLOCK(hotfdec); + + /* Status is okay */ + return HAL_OK; +} + +/** + * @brief Set region configuration. + * @note Region enciphering/deciphering is enabled at the end of this function + * @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains + * the configuration information for OTFDEC module + * @param RegionIndex index of region that is configured + * @param Config pointer on structure containing the region configuration parameters + * @param lock configuration lock enable or disable parameter + * This parameter can be one of the following values: + * @arg @ref OTFDEC_REG_CONFIGR_LOCK_DISABLE OTFDEC region configuration is not locked + * @arg @ref OTFDEC_REG_CONFIGR_LOCK_ENABLE OTFDEC region configuration is locked + * @retval HAL state + */ +HAL_StatusTypeDef HAL_OTFDEC_RegionConfig(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex, + const OTFDEC_RegionConfigTypeDef *Config, uint32_t lock) +{ + OTFDEC_Region_TypeDef *region; + uint32_t address; + + /* Check the parameters */ + assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance)); + assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex)); + assert_param(IS_OTFDEC_REGION_CONFIG_LOCK(lock)); + + if (Config == NULL) + { + return HAL_ERROR; + } + else + { + + /* Take Lock */ + __HAL_LOCK(hotfdec); + + address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex); + region = (OTFDEC_Region_TypeDef *)address; + + /* Set Nonce */ + WRITE_REG(region->REG_NONCER0, Config->Nonce[0]); + + WRITE_REG(region->REG_NONCER1, Config->Nonce[1]); + + /* Write region protected area start and end addresses */ + WRITE_REG(region->REG_START_ADDR, Config->StartAddress); + + WRITE_REG(region->REG_END_ADDR, Config->EndAddress); + + /* Write Version */ + MODIFY_REG(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_VERSION, + (uint32_t)(Config->Version) << OTFDEC_REG_CONFIGR_VERSION_Pos); + + /* Enable region deciphering or enciphering (depending of OTFDEC_CR ENC bit setting) */ + SET_BIT(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_REG_ENABLE); + + /* Lock the region configuration according to lock parameter value */ + if (lock == OTFDEC_REG_CONFIGR_LOCK_ENABLE) + { + SET_BIT(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_LOCK_ENABLE); + } + + /* Release Lock */ + __HAL_UNLOCK(hotfdec); + + /* Status is okay */ + return HAL_OK; + } +} + +/** + * @brief Configure OTFDEC attributes. + * @note This function sets or resets regions privileged access protection. + * @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains + * the configuration information for OTFDEC module + * @param Attributes This parameter can be only: + * @arg @ref OTFDEC_ATTRIBUTE_PRIV Set privileged access protection + * @arg @ref OTFDEC_ATTRIBUTE_NPRIV Reset privileged access protection + * @retval HAL state + */ +HAL_StatusTypeDef HAL_OTFDEC_ConfigAttributes(OTFDEC_HandleTypeDef *hotfdec, uint32_t Attributes) +{ + /* Check the parameters */ + assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance)); + assert_param(IS_OTFDEC_ATTRIBUTE(Attributes)); + + /* Take Lock */ + __HAL_LOCK(hotfdec); + + MODIFY_REG(hotfdec->Instance->PRIVCFGR, OTFDEC_PRIVCFGR_PRIV, Attributes); + + /* Release Lock */ + __HAL_UNLOCK(hotfdec); + + /* Status is okay */ + return HAL_OK; +} + +/** + * @brief Compute Key CRC + * @param pKey pointer at set of keys + * @retval CRC value + */ +uint32_t HAL_OTFDEC_KeyCRCComputation(const uint32_t *pKey) +{ + uint8_t crc7_poly = 0x7; + const uint32_t key_strobe[4] = {0xAA55AA55U, 0x3U, 0x18U, 0xC0U}; + uint8_t i; + uint8_t crc = 0; + uint32_t j; + uint32_t keyval; + uint32_t k; + const uint32_t *temp = pKey; + + for (j = 0U; j < 4U; j++) + { + keyval = *temp; + temp++; + if (j == 0U) + { + keyval ^= key_strobe[0]; + } + else + { + keyval ^= (key_strobe[j] << 24) | ((uint32_t)crc << 16) | (key_strobe[j] << 8) | crc; + } + + crc = 0; + for (i = 0; i < (uint8_t)32; i++) + { + k = ((((uint32_t)crc >> 7) ^ ((keyval >> ((uint8_t)31 - i)) & ((uint8_t)0xF)))) & 1U; + crc <<= 1; + if (k != 0U) + { + crc ^= crc7_poly; + } + } + + crc ^= (uint8_t)0x55; + } + + return (uint32_t) crc; +} + +/** + * @brief Enable peripheral enciphering. + * @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains + * the configuration information for OTFDEC module + * @note By default, deciphering mode is enabled at reset + * @retval HAL state + */ +HAL_StatusTypeDef HAL_OTFDEC_EnableEnciphering(OTFDEC_HandleTypeDef *hotfdec) +{ + /* Take Lock */ + __HAL_LOCK(hotfdec); + + SET_BIT(hotfdec->Instance->CR, OTFDEC_CR_ENC); + + /* Release Lock */ + __HAL_UNLOCK(hotfdec); + + /* Status is okay */ + return HAL_OK; +} + +/** + * @brief Disable peripheral enciphering. + * @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains + * the configuration information for OTFDEC module + * @retval HAL state + */ +HAL_StatusTypeDef HAL_OTFDEC_DisableEnciphering(OTFDEC_HandleTypeDef *hotfdec) +{ + /* Take Lock */ + __HAL_LOCK(hotfdec); + + CLEAR_BIT(hotfdec->Instance->CR, OTFDEC_CR_ENC); + + /* Release Lock */ + __HAL_UNLOCK(hotfdec); + + /* Status is okay */ + return HAL_OK; +} + + +/** + * @brief Cipher data. + * @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains + * the configuration information for OTFDEC module + * @param RegionIndex index of region the configuration of which is used to encipher + * @param input plain data + * @param output ciphered data + * @param size plain data size in words + * @param start_address starting address in the external memory area + where the enciphered data will be eventually stored + * @note Region configuration parameters and OTFDEC_CR ENC bit must be set. + * @note output pointer points at a temporary area in RAM to store the ciphered data. It is up to the user code + * to copy the ciphered data in external RAM once the enciphering process is over. + * @retval HAL state + */ +HAL_StatusTypeDef HAL_OTFDEC_Cipher(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex, + const uint32_t *input, uint32_t *output, uint32_t size, uint32_t start_address) +{ + uint32_t j; + __IO uint32_t *extMem_ptr = (uint32_t *)start_address; + const uint32_t *in_ptr = input; + uint32_t *out_ptr = output; + + /* Check the parameters */ + assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance)); + assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex)); + + if ((input == NULL) || (output == NULL) || (size == 0U)) + { + return HAL_ERROR; + } + else + { + /* Take Lock */ + __HAL_LOCK(hotfdec); + + for (j = 0; j < size; j++) + { + *extMem_ptr = *in_ptr; + in_ptr++; + *out_ptr = *extMem_ptr; + out_ptr++; + extMem_ptr++; + } + + /* Release Lock */ + __HAL_UNLOCK(hotfdec); + + /* Status is okay */ + return HAL_OK; + } +} + +/** + * @brief Enable region processing (enciphering or deciphering). + * @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains + * the configuration information for OTFDEC module + * @param RegionIndex index of region the enciphering or deciphering is enabled + * @note An error is reported when the configuration is locked. + * @retval HAL state + */ +HAL_StatusTypeDef HAL_OTFDEC_RegionEnable(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex) +{ + OTFDEC_Region_TypeDef *region; + uint32_t address; + + /* Check the parameters */ + assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance)); + assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex)); + + /* Take Lock */ + __HAL_LOCK(hotfdec); + + address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex); + region = (OTFDEC_Region_TypeDef *)address; + + if (READ_BIT(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_LOCK_ENABLE) == OTFDEC_REG_CONFIGR_LOCK_ENABLE) + { + /* Configuration is locked, REG_EN bit can't be modified */ + __HAL_UNLOCK(hotfdec); + + return HAL_ERROR; + } + + /* Enable region processing */ + SET_BIT(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_REG_ENABLE); + + /* Release Lock */ + __HAL_UNLOCK(hotfdec); + + /* Status is okay */ + return HAL_OK; +} + +/** + * @brief Disable region processing (enciphering or deciphering). + * @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains + * the configuration information for OTFDEC module + * @param RegionIndex index of region the enciphering or deciphering is disabled + * @note An error is reported when the configuration is locked. + * @retval HAL state + */ +HAL_StatusTypeDef HAL_OTFDEC_RegionDisable(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex) +{ + OTFDEC_Region_TypeDef *region; + uint32_t address; + + /* Check the parameters */ + assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance)); + assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex)); + + /* Take Lock */ + __HAL_LOCK(hotfdec); + + address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex); + region = (OTFDEC_Region_TypeDef *)address; + + if (READ_BIT(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_LOCK_ENABLE) == OTFDEC_REG_CONFIGR_LOCK_ENABLE) + { + /* Configuration is locked, REG_EN bit can't be modified */ + __HAL_UNLOCK(hotfdec); + + return HAL_ERROR; + } + + /* Disable region processing */ + CLEAR_BIT(region->REG_CONFIGR, OTFDEC_REG_CONFIGR_REG_ENABLE); + + /* Release Lock */ + __HAL_UNLOCK(hotfdec); + + /* Status is okay */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup OTFDEC_Exported_Functions_Group4 Peripheral State and Status functions + * @brief Peripheral State functions. + * +@verbatim + ============================================================================== + ##### Peripheral State functions ##### + ============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Return the OTFDEC state. + * @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains + * the configuration information for OTFDEC module + * @retval HAL state + */ +HAL_OTFDEC_StateTypeDef HAL_OTFDEC_GetState(const OTFDEC_HandleTypeDef *hotfdec) +{ + return hotfdec->State; +} + +/** + * @brief Get OTFDEC configuration attributes. + * @note This function returns whether or not the regions access protection is in privileged mode. + * @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains + * the configuration information for OTFDEC module + * @param Attributes pointer to attributes variable. This parameter can be only: + * @arg @ref OTFDEC_ATTRIBUTE_PRIV Set privileged access protection + * @arg @ref OTFDEC_ATTRIBUTE_NPRIV Reset privileged access protection + * @retval HAL state + */ +HAL_StatusTypeDef HAL_OTFDEC_GetConfigAttributes(OTFDEC_HandleTypeDef *hotfdec, uint32_t *Attributes) +{ + /* Check the parameters */ + assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance)); + + /* Take Lock */ + __HAL_LOCK(hotfdec); + + *Attributes = READ_BIT(hotfdec->Instance->PRIVCFGR, OTFDEC_PRIVCFGR_PRIV); + + /* Release Lock */ + __HAL_UNLOCK(hotfdec); + + /* Status is okay */ + return HAL_OK; +} + +/** + * @brief Return region keys CRC. + * @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains + * the configuration information for OTFDEC module + * @param RegionIndex index of region the keys CRC of which is read + * @retval Key CRC + */ +uint32_t HAL_OTFDEC_RegionGetKeyCRC(const OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex) +{ + const OTFDEC_Region_TypeDef *region; + uint32_t address; + uint32_t keycrc; + + /* Check the parameters */ + assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance)); + assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex)); + + address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex); + region = (OTFDEC_Region_TypeDef *)address; + + keycrc = (READ_REG(region->REG_CONFIGR)) & OTFDEC_REG_CONFIGR_KEYCRC; + + keycrc >>= OTFDEC_REG_CONFIGR_KEYCRC_Pos; + + return keycrc; +} + +/** + * @brief Return region configuration parameters. + * @param hotfdec pointer to an OTFDEC_HandleTypeDef structure that contains + * the configuration information for OTFDEC module + * @param RegionIndex index of region the configuration of which is read + * @param Config pointer on structure that will be filled up with the region configuration parameters + * @retval HAL state + */ +HAL_StatusTypeDef HAL_OTFDEC_RegionGetConfig(OTFDEC_HandleTypeDef *hotfdec, uint32_t RegionIndex, + OTFDEC_RegionConfigTypeDef *Config) +{ + OTFDEC_Region_TypeDef *region; + uint32_t address; + + /* Check the parameters */ + assert_param(IS_OTFDEC_ALL_INSTANCE(hotfdec->Instance)); + assert_param(IS_OTFDEC_REGIONINDEX(RegionIndex)); + + if (Config == NULL) + { + return HAL_ERROR; + } + else + { + /* Take Lock */ + __HAL_LOCK(hotfdec); + + address = (uint32_t)(hotfdec->Instance) + 0x20U + (0x30U * RegionIndex); + region = (OTFDEC_Region_TypeDef *)address; + + /* Read Nonce */ + Config->Nonce[0] = READ_REG(region->REG_NONCER0); + Config->Nonce[1] = READ_REG(region->REG_NONCER1); + + /* Read Addresses */ + Config->StartAddress = READ_REG(region->REG_START_ADDR); + Config->EndAddress = READ_REG(region->REG_END_ADDR); + + /* Read Version */ + Config->Version = (uint16_t)(READ_REG(region->REG_CONFIGR) & + OTFDEC_REG_CONFIGR_VERSION) >> OTFDEC_REG_CONFIGR_VERSION_Pos; + + /* Release Lock */ + __HAL_UNLOCK(hotfdec); + + /* Status is okay */ + return HAL_OK; + } +} + + +/** + * @} + */ + +/** + * @} + */ + +#endif /* OTFDEC1 */ + +#endif /* HAL_OTFDEC_MODULE_ENABLED */ + + +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pcd.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pcd.c new file mode 100644 index 0000000000..8e18b71017 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pcd.c @@ -0,0 +1,2234 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_pcd.c + * @author MCD Application Team + * @brief PCD HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the USB Peripheral Controller: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The PCD HAL driver can be used as follows: + + (#) Declare a PCD_HandleTypeDef handle structure, for example: + PCD_HandleTypeDef hpcd; + + (#) Fill parameters of Init structure in HCD handle + + (#) Call HAL_PCD_Init() API to initialize the PCD peripheral (Core, Device core, ...) + + (#) Initialize the PCD low level resources through the HAL_PCD_MspInit() API: + (##) Enable the PCD/USB Low Level interface clock using + (+++) __HAL_RCC_USB_CLK_ENABLE(); For USB Device FS peripheral + + (##) Initialize the related GPIO clocks + (##) Configure PCD pin-out + (##) Configure PCD NVIC interrupt + + (#)Associate the Upper USB device stack to the HAL PCD Driver: + (##) hpcd.pData = pdev; + + (#)Enable PCD transmission and reception: + (##) HAL_PCD_Start(); + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup PCD PCD + * @brief PCD HAL module driver + * @{ + */ + +#ifdef HAL_PCD_MODULE_ENABLED + +#if defined (USB_DRD_FS) + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup PCD_Private_Macros PCD Private Macros + * @{ + */ +#define PCD_MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define PCD_MAX(a, b) (((a) > (b)) ? (a) : (b)) +/** + * @} + */ + +/* Private functions prototypes ----------------------------------------------*/ +/** @defgroup PCD_Private_Functions PCD Private Functions + * @{ + */ + +static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd); +#if (USE_USB_DOUBLE_BUFFER == 1U) +static HAL_StatusTypeDef HAL_PCD_EP_DB_Transmit(PCD_HandleTypeDef *hpcd, PCD_EPTypeDef *ep, uint16_t wEPVal); +static uint16_t HAL_PCD_EP_DB_Receive(PCD_HandleTypeDef *hpcd, PCD_EPTypeDef *ep, uint16_t wEPVal); +#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup PCD_Exported_Functions PCD Exported Functions + * @{ + */ + +/** @defgroup PCD_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: + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the PCD according to the specified + * parameters in the PCD_InitTypeDef and initialize the associated handle. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd) +{ + uint8_t i; + + /* Check the PCD handle allocation */ + if (hpcd == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance)); + + if (hpcd->State == HAL_PCD_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hpcd->Lock = HAL_UNLOCKED; + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->SOFCallback = HAL_PCD_SOFCallback; + hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback; + hpcd->ResetCallback = HAL_PCD_ResetCallback; + hpcd->SuspendCallback = HAL_PCD_SuspendCallback; + hpcd->ResumeCallback = HAL_PCD_ResumeCallback; + hpcd->ConnectCallback = HAL_PCD_ConnectCallback; + hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback; + hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback; + hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback; + hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback; + hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback; + hpcd->LPMCallback = HAL_PCDEx_LPM_Callback; + hpcd->BCDCallback = HAL_PCDEx_BCD_Callback; + + if (hpcd->MspInitCallback == NULL) + { + hpcd->MspInitCallback = HAL_PCD_MspInit; + } + + /* Init the low level hardware */ + hpcd->MspInitCallback(hpcd); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC... */ + HAL_PCD_MspInit(hpcd); +#endif /* (USE_HAL_PCD_REGISTER_CALLBACKS) */ + } + + hpcd->State = HAL_PCD_STATE_BUSY; + + /* Disable the Interrupts */ + __HAL_PCD_DISABLE(hpcd); + + /* Init endpoints structures */ + for (i = 0U; i < hpcd->Init.dev_endpoints; i++) + { + /* Init ep structure */ + hpcd->IN_ep[i].is_in = 1U; + hpcd->IN_ep[i].num = i; + /* Control until ep is activated */ + hpcd->IN_ep[i].type = EP_TYPE_CTRL; + hpcd->IN_ep[i].maxpacket = 0U; + hpcd->IN_ep[i].xfer_buff = 0U; + hpcd->IN_ep[i].xfer_len = 0U; + } + + for (i = 0U; i < hpcd->Init.dev_endpoints; i++) + { + hpcd->OUT_ep[i].is_in = 0U; + hpcd->OUT_ep[i].num = i; + /* Control until ep is activated */ + hpcd->OUT_ep[i].type = EP_TYPE_CTRL; + hpcd->OUT_ep[i].maxpacket = 0U; + hpcd->OUT_ep[i].xfer_buff = 0U; + hpcd->OUT_ep[i].xfer_len = 0U; + } + + /* Init Device */ + (void)USB_DevInit(hpcd->Instance, hpcd->Init); + + hpcd->USB_Address = 0U; + hpcd->State = HAL_PCD_STATE_READY; + + /* Activate LPM */ + if (hpcd->Init.lpm_enable == 1U) + { + (void)HAL_PCDEx_ActivateLPM(hpcd); + } + + return HAL_OK; +} + +/** + * @brief DeInitializes the PCD peripheral. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd) +{ + /* Check the PCD handle allocation */ + if (hpcd == NULL) + { + return HAL_ERROR; + } + + hpcd->State = HAL_PCD_STATE_BUSY; + + /* Stop Device */ + if (USB_StopDevice(hpcd->Instance) != HAL_OK) + { + return HAL_ERROR; + } + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + if (hpcd->MspDeInitCallback == NULL) + { + hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; /* Legacy weak MspDeInit */ + } + + /* DeInit the low level hardware */ + hpcd->MspDeInitCallback(hpcd); +#else + /* DeInit the low level hardware: CLOCK, NVIC.*/ + HAL_PCD_MspDeInit(hpcd); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + + hpcd->State = HAL_PCD_STATE_RESET; + + return HAL_OK; +} + +/** + * @brief Initializes the PCD MSP. + * @param hpcd PCD handle + * @retval None + */ +__weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes PCD MSP. + * @param hpcd PCD handle + * @retval None + */ +__weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_MspDeInit could be implemented in the user file + */ +} + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) +/** + * @brief Register a User USB PCD Callback + * To be used instead of the weak predefined callback + * @param hpcd USB PCD handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID + * @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID + * @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID + * @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID + * @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID + * @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID + * @arg @ref HAL_PCD_DISCONNECT_CB_ID USB PCD Disconnect callback ID + * @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID + * @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd, + HAL_PCD_CallbackIDTypeDef CallbackID, + pPCD_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + switch (CallbackID) + { + case HAL_PCD_SOF_CB_ID : + hpcd->SOFCallback = pCallback; + break; + + case HAL_PCD_SETUPSTAGE_CB_ID : + hpcd->SetupStageCallback = pCallback; + break; + + case HAL_PCD_RESET_CB_ID : + hpcd->ResetCallback = pCallback; + break; + + case HAL_PCD_SUSPEND_CB_ID : + hpcd->SuspendCallback = pCallback; + break; + + case HAL_PCD_RESUME_CB_ID : + hpcd->ResumeCallback = pCallback; + break; + + case HAL_PCD_CONNECT_CB_ID : + hpcd->ConnectCallback = pCallback; + break; + + case HAL_PCD_DISCONNECT_CB_ID : + hpcd->DisconnectCallback = pCallback; + break; + + case HAL_PCD_MSPINIT_CB_ID : + hpcd->MspInitCallback = pCallback; + break; + + case HAL_PCD_MSPDEINIT_CB_ID : + hpcd->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (hpcd->State == HAL_PCD_STATE_RESET) + { + switch (CallbackID) + { + case HAL_PCD_MSPINIT_CB_ID : + hpcd->MspInitCallback = pCallback; + break; + + case HAL_PCD_MSPDEINIT_CB_ID : + hpcd->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + return status; +} + +/** + * @brief Unregister an USB PCD Callback + * USB PCD callback is redirected to the weak predefined callback + * @param hpcd USB PCD handle + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID + * @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID + * @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID + * @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID + * @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID + * @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID + * @arg @ref HAL_PCD_DISCONNECT_CB_ID USB PCD Disconnect callback ID + * @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID + * @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hpcd); + + /* Setup Legacy weak Callbacks */ + if (hpcd->State == HAL_PCD_STATE_READY) + { + switch (CallbackID) + { + case HAL_PCD_SOF_CB_ID : + hpcd->SOFCallback = HAL_PCD_SOFCallback; + break; + + case HAL_PCD_SETUPSTAGE_CB_ID : + hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback; + break; + + case HAL_PCD_RESET_CB_ID : + hpcd->ResetCallback = HAL_PCD_ResetCallback; + break; + + case HAL_PCD_SUSPEND_CB_ID : + hpcd->SuspendCallback = HAL_PCD_SuspendCallback; + break; + + case HAL_PCD_RESUME_CB_ID : + hpcd->ResumeCallback = HAL_PCD_ResumeCallback; + break; + + case HAL_PCD_CONNECT_CB_ID : + hpcd->ConnectCallback = HAL_PCD_ConnectCallback; + break; + + case HAL_PCD_DISCONNECT_CB_ID : + hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback; + break; + + case HAL_PCD_MSPINIT_CB_ID : + hpcd->MspInitCallback = HAL_PCD_MspInit; + break; + + case HAL_PCD_MSPDEINIT_CB_ID : + hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; + break; + + default : + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (hpcd->State == HAL_PCD_STATE_RESET) + { + switch (CallbackID) + { + case HAL_PCD_MSPINIT_CB_ID : + hpcd->MspInitCallback = HAL_PCD_MspInit; + break; + + case HAL_PCD_MSPDEINIT_CB_ID : + hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; + break; + + default : + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + return status; +} + +/** + * @brief Register USB PCD Data OUT Stage Callback + * To be used instead of the weak HAL_PCD_DataOutStageCallback() predefined callback + * @param hpcd PCD handle + * @param pCallback pointer to the USB PCD Data OUT Stage Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd, + pPCD_DataOutStageCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->DataOutStageCallback = pCallback; + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief Unregister the USB PCD Data OUT Stage Callback + * USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataOutStageCallback() predefined callback + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback; /* Legacy weak DataOutStageCallback */ + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief Register USB PCD Data IN Stage Callback + * To be used instead of the weak HAL_PCD_DataInStageCallback() predefined callback + * @param hpcd PCD handle + * @param pCallback pointer to the USB PCD Data IN Stage Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd, + pPCD_DataInStageCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->DataInStageCallback = pCallback; + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief Unregister the USB PCD Data IN Stage Callback + * USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataInStageCallback() predefined callback + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback; /* Legacy weak DataInStageCallback */ + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief Register USB PCD Iso OUT incomplete Callback + * To be used instead of the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback + * @param hpcd PCD handle + * @param pCallback pointer to the USB PCD Iso OUT incomplete Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd, + pPCD_IsoOutIncpltCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->ISOOUTIncompleteCallback = pCallback; + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief Unregister the USB PCD Iso OUT incomplete Callback + * USB PCD Iso OUT incomplete Callback is redirected + * to the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback; /* Legacy weak ISOOUTIncompleteCallback */ + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief Register USB PCD Iso IN incomplete Callback + * To be used instead of the weak HAL_PCD_ISOINIncompleteCallback() predefined callback + * @param hpcd PCD handle + * @param pCallback pointer to the USB PCD Iso IN incomplete Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd, + pPCD_IsoInIncpltCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->ISOINIncompleteCallback = pCallback; + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief Unregister the USB PCD Iso IN incomplete Callback + * USB PCD Iso IN incomplete Callback is redirected + * to the weak HAL_PCD_ISOINIncompleteCallback() predefined callback + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback; /* Legacy weak ISOINIncompleteCallback */ + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief Register USB PCD BCD Callback + * To be used instead of the weak HAL_PCDEx_BCD_Callback() predefined callback + * @param hpcd PCD handle + * @param pCallback pointer to the USB PCD BCD Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_RegisterBcdCallback(PCD_HandleTypeDef *hpcd, pPCD_BcdCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->BCDCallback = pCallback; + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief Unregister the USB PCD BCD Callback + * USB BCD Callback is redirected to the weak HAL_PCDEx_BCD_Callback() predefined callback + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_UnRegisterBcdCallback(PCD_HandleTypeDef *hpcd) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->BCDCallback = HAL_PCDEx_BCD_Callback; /* Legacy weak HAL_PCDEx_BCD_Callback */ + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief Register USB PCD LPM Callback + * To be used instead of the weak HAL_PCDEx_LPM_Callback() predefined callback + * @param hpcd PCD handle + * @param pCallback pointer to the USB PCD LPM Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_RegisterLpmCallback(PCD_HandleTypeDef *hpcd, pPCD_LpmCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->LPMCallback = pCallback; + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief Unregister the USB PCD LPM Callback + * USB LPM Callback is redirected to the weak HAL_PCDEx_LPM_Callback() predefined callback + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_UnRegisterLpmCallback(PCD_HandleTypeDef *hpcd) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->LPMCallback = HAL_PCDEx_LPM_Callback; /* Legacy weak HAL_PCDEx_LPM_Callback */ + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions + * @brief Data transfers functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the PCD data + transfers. + +@endverbatim + * @{ + */ + +/** + * @brief Start the USB device + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd) +{ + __HAL_LOCK(hpcd); + __HAL_PCD_ENABLE(hpcd); + (void)USB_DevConnect(hpcd->Instance); + __HAL_UNLOCK(hpcd); + + return HAL_OK; +} + +/** + * @brief Stop the USB device. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd) +{ + __HAL_LOCK(hpcd); + __HAL_PCD_DISABLE(hpcd); + (void)USB_DevDisconnect(hpcd->Instance); + __HAL_UNLOCK(hpcd); + + return HAL_OK; +} + + +/** + * @brief This function handles PCD interrupt request. + * @param hpcd PCD handle + * @retval HAL status + */ +void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd) +{ + uint32_t wIstr = USB_ReadInterrupts(hpcd->Instance); + + if ((wIstr & USB_ISTR_CTR) == USB_ISTR_CTR) + { + /* servicing of the endpoint correct transfer interrupt */ + /* clear of the CTR flag into the sub */ + (void)PCD_EP_ISR_Handler(hpcd); + + return; + } + + if ((wIstr & USB_ISTR_RESET) == USB_ISTR_RESET) + { + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET); + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->ResetCallback(hpcd); +#else + HAL_PCD_ResetCallback(hpcd); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + + (void)HAL_PCD_SetAddress(hpcd, 0U); + + return; + } + + if ((wIstr & USB_ISTR_PMAOVR) == USB_ISTR_PMAOVR) + { + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR); + + return; + } + + if ((wIstr & USB_ISTR_ERR) == USB_ISTR_ERR) + { + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR); + + return; + } + + if ((wIstr & USB_ISTR_WKUP) == USB_ISTR_WKUP) + { + hpcd->Instance->CNTR &= ~(USB_CNTR_SUSPRDY); + hpcd->Instance->CNTR &= ~(USB_CNTR_SUSPEN); + + if (hpcd->LPM_State == LPM_L1) + { + hpcd->LPM_State = LPM_L0; +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->LPMCallback(hpcd, PCD_LPM_L0_ACTIVE); +#else + HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->ResumeCallback(hpcd); +#else + HAL_PCD_ResumeCallback(hpcd); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP); + + return; + } + + if ((wIstr & USB_ISTR_SUSP) == USB_ISTR_SUSP) + { + /* Force low-power mode in the macrocell */ + hpcd->Instance->CNTR |= USB_CNTR_SUSPEN; + + /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP); + + hpcd->Instance->CNTR |= USB_CNTR_SUSPRDY; + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->SuspendCallback(hpcd); +#else + HAL_PCD_SuspendCallback(hpcd); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + + return; + } + + /* Handle LPM Interrupt */ + if ((wIstr & USB_ISTR_L1REQ) == USB_ISTR_L1REQ) + { + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_L1REQ); + if (hpcd->LPM_State == LPM_L0) + { + /* Force suspend and low-power mode before going to L1 state*/ + hpcd->Instance->CNTR |= USB_CNTR_SUSPRDY; + hpcd->Instance->CNTR |= USB_CNTR_SUSPEN; + + hpcd->LPM_State = LPM_L1; + hpcd->BESL = ((uint32_t)hpcd->Instance->LPMCSR & USB_LPMCSR_BESL) >> 2; +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->LPMCallback(hpcd, PCD_LPM_L1_ACTIVE); +#else + HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + else + { +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->SuspendCallback(hpcd); +#else + HAL_PCD_SuspendCallback(hpcd); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + + return; + } + + if ((wIstr & USB_ISTR_SOF) == USB_ISTR_SOF) + { + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF); + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->SOFCallback(hpcd); +#else + HAL_PCD_SOFCallback(hpcd); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + + return; + } + + if ((wIstr & USB_ISTR_ESOF) == USB_ISTR_ESOF) + { + /* clear ESOF flag in ISTR */ + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF); + + return; + } +} + + +/** + * @brief Data OUT stage callback. + * @param hpcd PCD handle + * @param epnum endpoint number + * @retval None + */ +__weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + UNUSED(epnum); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_DataOutStageCallback could be implemented in the user file + */ +} + +/** + * @brief Data IN stage callback + * @param hpcd PCD handle + * @param epnum endpoint number + * @retval None + */ +__weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + UNUSED(epnum); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_DataInStageCallback could be implemented in the user file + */ +} +/** + * @brief Setup stage callback + * @param hpcd PCD handle + * @retval None + */ +__weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_SetupStageCallback could be implemented in the user file + */ +} + +/** + * @brief USB Start Of Frame callback. + * @param hpcd PCD handle + * @retval None + */ +__weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_SOFCallback could be implemented in the user file + */ +} + +/** + * @brief USB Reset callback. + * @param hpcd PCD handle + * @retval None + */ +__weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_ResetCallback could be implemented in the user file + */ +} + +/** + * @brief Suspend event callback. + * @param hpcd PCD handle + * @retval None + */ +__weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_SuspendCallback could be implemented in the user file + */ +} + +/** + * @brief Resume event callback. + * @param hpcd PCD handle + * @retval None + */ +__weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_ResumeCallback could be implemented in the user file + */ +} + +/** + * @brief Incomplete ISO OUT callback. + * @param hpcd PCD handle + * @param epnum endpoint number + * @retval None + */ +__weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + UNUSED(epnum); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file + */ +} + +/** + * @brief Incomplete ISO IN callback. + * @param hpcd PCD handle + * @param epnum endpoint number + * @retval None + */ +__weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + UNUSED(epnum); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file + */ +} + +/** + * @brief Connection event callback. + * @param hpcd PCD handle + * @retval None + */ +__weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_ConnectCallback could be implemented in the user file + */ +} + +/** + * @brief Disconnection event callback. + * @param hpcd PCD handle + * @retval None + */ +__weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_DisconnectCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions + * @brief management functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the PCD data + transfers. + +@endverbatim + * @{ + */ + +/** + * @brief Connect the USB device + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd) +{ + __HAL_LOCK(hpcd); + (void)USB_DevConnect(hpcd->Instance); + __HAL_UNLOCK(hpcd); + + return HAL_OK; +} + +/** + * @brief Disconnect the USB device. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd) +{ + __HAL_LOCK(hpcd); + (void)USB_DevDisconnect(hpcd->Instance); + __HAL_UNLOCK(hpcd); + + return HAL_OK; +} + +/** + * @brief Set the USB Device address. + * @param hpcd PCD handle + * @param address new device address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address) +{ + __HAL_LOCK(hpcd); + hpcd->USB_Address = address; + (void)USB_SetDevAddress(hpcd->Instance, address); + __HAL_UNLOCK(hpcd); + + return HAL_OK; +} +/** + * @brief Open and configure an endpoint. + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @param ep_mps endpoint max packet size + * @param ep_type endpoint type + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, + uint16_t ep_mps, uint8_t ep_type) +{ + HAL_StatusTypeDef ret = HAL_OK; + PCD_EPTypeDef *ep; + + if ((ep_addr & 0x80U) == 0x80U) + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 1U; + } + else + { + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 0U; + } + + ep->num = ep_addr & EP_ADDR_MSK; + ep->maxpacket = ep_mps; + ep->type = ep_type; + + /* Set initial data PID. */ + if (ep_type == EP_TYPE_BULK) + { + ep->data_pid_start = 0U; + } + + __HAL_LOCK(hpcd); + (void)USB_ActivateEndpoint(hpcd->Instance, ep); + __HAL_UNLOCK(hpcd); + + return ret; +} + +/** + * @brief Deactivate an endpoint. + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + PCD_EPTypeDef *ep; + + if ((ep_addr & 0x80U) == 0x80U) + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 1U; + } + else + { + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 0U; + } + ep->num = ep_addr & EP_ADDR_MSK; + + __HAL_LOCK(hpcd); + (void)USB_DeactivateEndpoint(hpcd->Instance, ep); + __HAL_UNLOCK(hpcd); + return HAL_OK; +} + + +/** + * @brief Receive an amount of data. + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @param pBuf pointer to the reception buffer + * @param len amount of data to be received + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len) +{ + PCD_EPTypeDef *ep; + + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + + /*setup and start the Xfer */ + ep->xfer_buff = pBuf; + ep->xfer_len = len; + ep->xfer_count = 0U; + ep->is_in = 0U; + ep->num = ep_addr & EP_ADDR_MSK; + + (void)USB_EPStartXfer(hpcd->Instance, ep); + + return HAL_OK; +} + +/** + * @brief Get Received Data Size + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval Data Size + */ +uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef const *hpcd, uint8_t ep_addr) +{ + return hpcd->OUT_ep[ep_addr & EP_ADDR_MSK].xfer_count; +} +/** + * @brief Send an amount of data + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @param pBuf pointer to the transmission buffer + * @param len amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len) +{ + PCD_EPTypeDef *ep; + + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + + /*setup and start the Xfer */ + ep->xfer_buff = pBuf; + ep->xfer_len = len; + ep->xfer_fill_db = 1U; + ep->xfer_len_db = len; + ep->xfer_count = 0U; + ep->is_in = 1U; + ep->num = ep_addr & EP_ADDR_MSK; + + (void)USB_EPStartXfer(hpcd->Instance, ep); + + return HAL_OK; +} + +/** + * @brief Set a STALL condition over an endpoint + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + PCD_EPTypeDef *ep; + + if (((uint32_t)ep_addr & EP_ADDR_MSK) > hpcd->Init.dev_endpoints) + { + return HAL_ERROR; + } + + if ((0x80U & ep_addr) == 0x80U) + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 1U; + } + else + { + ep = &hpcd->OUT_ep[ep_addr]; + ep->is_in = 0U; + } + + ep->is_stall = 1U; + ep->num = ep_addr & EP_ADDR_MSK; + + __HAL_LOCK(hpcd); + + (void)USB_EPSetStall(hpcd->Instance, ep); + + __HAL_UNLOCK(hpcd); + + return HAL_OK; +} + +/** + * @brief Clear a STALL condition over in an endpoint + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + PCD_EPTypeDef *ep; + + if (((uint32_t)ep_addr & 0x0FU) > hpcd->Init.dev_endpoints) + { + return HAL_ERROR; + } + + if ((0x80U & ep_addr) == 0x80U) + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 1U; + } + else + { + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 0U; + } + + ep->is_stall = 0U; + ep->num = ep_addr & EP_ADDR_MSK; + + __HAL_LOCK(hpcd); + (void)USB_EPClearStall(hpcd->Instance, ep); + __HAL_UNLOCK(hpcd); + + return HAL_OK; +} + +/** + * @brief Abort an USB EP transaction. + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Abort(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + HAL_StatusTypeDef ret; + PCD_EPTypeDef *ep; + + if ((0x80U & ep_addr) == 0x80U) + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + } + else + { + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + } + + /* Stop Xfer */ + ret = USB_EPStopXfer(hpcd->Instance, ep); + + return ret; +} + +/** + * @brief Flush an endpoint + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef const *hpcd, uint8_t ep_addr) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + UNUSED(ep_addr); + + return HAL_OK; +} + +/** + * @brief Activate remote wakeup signalling + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd) +{ + return (USB_ActivateRemoteWakeup(hpcd->Instance)); +} + +/** + * @brief De-activate remote wakeup signalling. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd) +{ + return (USB_DeActivateRemoteWakeup(hpcd->Instance)); +} + +/** + * @} + */ + +/** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions + * @brief Peripheral State functions + * +@verbatim + =============================================================================== + ##### Peripheral State functions ##### + =============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the PCD handle state. + * @param hpcd PCD handle + * @retval HAL state + */ +PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef const *hpcd) +{ + return hpcd->State; +} + +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @addtogroup PCD_Private_Functions + * @{ + */ + + +/** + * @brief This function handles PCD Endpoint interrupt request. + * @param hpcd PCD handle + * @retval HAL status + */ +static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd) +{ + PCD_EPTypeDef *ep; + uint16_t count; + uint16_t wIstr; + uint16_t wEPVal; + uint16_t TxPctSize; + uint8_t epindex; + +#if (USE_USB_DOUBLE_BUFFER != 1U) + count = 0U; +#endif /* USE_USB_DOUBLE_BUFFER */ + + /* stay in loop while pending interrupts */ + while ((hpcd->Instance->ISTR & USB_ISTR_CTR) != 0U) + { + wIstr = (uint16_t)hpcd->Instance->ISTR; + + /* extract highest priority endpoint number */ + epindex = (uint8_t)(wIstr & USB_ISTR_IDN); + + if (epindex == 0U) + { + /* Decode and service control endpoint interrupt */ + + /* DIR bit = origin of the interrupt */ + if ((wIstr & USB_ISTR_DIR) == 0U) + { + /* DIR = 0 */ + + /* DIR = 0 => IN int */ + /* DIR = 0 implies that (EP_CTR_TX = 1) always */ + PCD_CLEAR_TX_EP_CTR(hpcd->Instance, PCD_ENDP0); + ep = &hpcd->IN_ep[0]; + + ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num); + ep->xfer_buff += ep->xfer_count; + + /* TX COMPLETE */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->DataInStageCallback(hpcd, 0U); +#else + HAL_PCD_DataInStageCallback(hpcd, 0U); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + + if ((hpcd->USB_Address > 0U) && (ep->xfer_len == 0U)) + { + hpcd->Instance->DADDR = ((uint16_t)hpcd->USB_Address | USB_DADDR_EF); + hpcd->USB_Address = 0U; + } + } + else + { + /* DIR = 1 */ + + /* DIR = 1 & CTR_RX => SETUP or OUT int */ + /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */ + ep = &hpcd->OUT_ep[0]; + wEPVal = (uint16_t)PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0); + + if ((wEPVal & USB_EP_SETUP) != 0U) + { + /* Get SETUP Packet */ + ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num); + + USB_ReadPMA(hpcd->Instance, (uint8_t *)hpcd->Setup, + ep->pmaadress, (uint16_t)ep->xfer_count); + + /* SETUP bit kept frozen while CTR_RX = 1 */ + PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0); + + /* Process SETUP Packet*/ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->SetupStageCallback(hpcd); +#else + HAL_PCD_SetupStageCallback(hpcd); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + else if ((wEPVal & USB_EP_VTRX) != 0U) + { + PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0); + + /* Get Control Data OUT Packet */ + ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num); + + if ((ep->xfer_count != 0U) && (ep->xfer_buff != 0U)) + { + USB_ReadPMA(hpcd->Instance, ep->xfer_buff, + ep->pmaadress, (uint16_t)ep->xfer_count); + + ep->xfer_buff += ep->xfer_count; + + /* Process Control Data OUT Packet */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->DataOutStageCallback(hpcd, 0U); +#else + HAL_PCD_DataOutStageCallback(hpcd, 0U); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + + wEPVal = (uint16_t)PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0); + + if (((wEPVal & USB_EP_SETUP) == 0U) && ((wEPVal & USB_EP_RX_STRX) != USB_EP_RX_VALID)) + { + PCD_SET_EP_RX_CNT(hpcd->Instance, PCD_ENDP0, ep->maxpacket); + PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID); + } + } + } + } + else + { + /* Decode and service non control endpoints interrupt */ + /* process related endpoint register */ + wEPVal = (uint16_t)PCD_GET_ENDPOINT(hpcd->Instance, epindex); + + if ((wEPVal & USB_EP_VTRX) != 0U) + { + /* clear int flag */ + PCD_CLEAR_RX_EP_CTR(hpcd->Instance, epindex); + ep = &hpcd->OUT_ep[epindex]; + + /* OUT Single Buffering */ + if (ep->doublebuffer == 0U) + { + count = (uint16_t)PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num); + + if (count != 0U) + { + USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, count); + } + } +#if (USE_USB_DOUBLE_BUFFER == 1U) + else + { + /* manage double buffer bulk out */ + if (ep->type == EP_TYPE_BULK) + { + count = HAL_PCD_EP_DB_Receive(hpcd, ep, wEPVal); + } + else /* manage double buffer iso out */ + { + /* free EP OUT Buffer */ + PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 0U); + + if ((PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_RX) != 0U) + { + /* read from endpoint BUF0Addr buffer */ + count = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num); + + if (count != 0U) + { + USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count); + } + } + else + { + /* read from endpoint BUF1Addr buffer */ + count = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num); + + if (count != 0U) + { + USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count); + } + } + } + } +#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ + + /* multi-packet on the NON control OUT endpoint */ + ep->xfer_count += count; + ep->xfer_buff += count; + + if ((ep->xfer_len == 0U) || (count < ep->maxpacket)) + { + /* RX COMPLETE */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->DataOutStageCallback(hpcd, ep->num); +#else + HAL_PCD_DataOutStageCallback(hpcd, ep->num); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + else + { + (void)USB_EPStartXfer(hpcd->Instance, ep); + } + } + + if ((wEPVal & USB_EP_VTTX) != 0U) + { + ep = &hpcd->IN_ep[epindex]; + + /* clear int flag */ + PCD_CLEAR_TX_EP_CTR(hpcd->Instance, epindex); + + if (ep->type == EP_TYPE_ISOC) + { + ep->xfer_len = 0U; + +#if (USE_USB_DOUBLE_BUFFER == 1U) + if (ep->doublebuffer != 0U) + { + if ((wEPVal & USB_EP_DTOG_TX) != 0U) + { + PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, 0U); + } + else + { + PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, 0U); + } + } +#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ + + /* TX COMPLETE */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->DataInStageCallback(hpcd, ep->num); +#else + HAL_PCD_DataInStageCallback(hpcd, ep->num); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + else + { + /* Manage Single Buffer Transaction */ + if ((wEPVal & USB_EP_KIND) == 0U) + { + /* multi-packet on the NON control IN endpoint */ + TxPctSize = (uint16_t)PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num); + + if (ep->xfer_len > TxPctSize) + { + ep->xfer_len -= TxPctSize; + } + else + { + ep->xfer_len = 0U; + } + + /* Zero Length Packet? */ + if (ep->xfer_len == 0U) + { + /* TX COMPLETE */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->DataInStageCallback(hpcd, ep->num); +#else + HAL_PCD_DataInStageCallback(hpcd, ep->num); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + else + { + /* Transfer is not yet Done */ + ep->xfer_buff += TxPctSize; + ep->xfer_count += TxPctSize; + (void)USB_EPStartXfer(hpcd->Instance, ep); + } + } +#if (USE_USB_DOUBLE_BUFFER == 1U) + /* Double Buffer bulk IN (bulk transfer Len > Ep_Mps) */ + else + { + (void)HAL_PCD_EP_DB_Transmit(hpcd, ep, wEPVal); + } +#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ + } + } + } + } + + return HAL_OK; +} + + +#if (USE_USB_DOUBLE_BUFFER == 1U) +/** + * @brief Manage double buffer bulk out transaction from ISR + * @param hpcd PCD handle + * @param ep current endpoint handle + * @param wEPVal Last snapshot of EPRx register value taken in ISR + * @retval HAL status + */ +static uint16_t HAL_PCD_EP_DB_Receive(PCD_HandleTypeDef *hpcd, + PCD_EPTypeDef *ep, uint16_t wEPVal) +{ + uint16_t count; + + /* Manage Buffer0 OUT */ + if ((wEPVal & USB_EP_DTOG_RX) != 0U) + { + /* Get count of received Data on buffer0 */ + count = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num); + + if (ep->xfer_len >= count) + { + ep->xfer_len -= count; + } + else + { + ep->xfer_len = 0U; + } + + if (ep->xfer_len == 0U) + { + /* set NAK to OUT endpoint since double buffer is enabled */ + PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_NAK); + } + + /* Check if Buffer1 is in blocked state which requires to toggle */ + if ((wEPVal & USB_EP_DTOG_TX) != 0U) + { + PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 0U); + } + + if (count != 0U) + { + USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count); + } + } + /* Manage Buffer 1 DTOG_RX=0 */ + else + { + /* Get count of received data */ + count = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num); + + if (ep->xfer_len >= count) + { + ep->xfer_len -= count; + } + else + { + ep->xfer_len = 0U; + } + + if (ep->xfer_len == 0U) + { + /* set NAK on the current endpoint */ + PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_NAK); + } + + /*Need to FreeUser Buffer*/ + if ((wEPVal & USB_EP_DTOG_TX) == 0U) + { + PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 0U); + } + + if (count != 0U) + { + USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count); + } + } + + return count; +} + + +/** + * @brief Manage double buffer bulk IN transaction from ISR + * @param hpcd PCD handle + * @param ep current endpoint handle + * @param wEPVal Last snapshot of EPRx register value taken in ISR + * @retval HAL status + */ +static HAL_StatusTypeDef HAL_PCD_EP_DB_Transmit(PCD_HandleTypeDef *hpcd, + PCD_EPTypeDef *ep, uint16_t wEPVal) +{ + uint32_t len; + uint16_t TxPctSize; + + /* Data Buffer0 ACK received */ + if ((wEPVal & USB_EP_DTOG_TX) != 0U) + { + /* multi-packet on the NON control IN endpoint */ + TxPctSize = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num); + + if (ep->xfer_len > TxPctSize) + { + ep->xfer_len -= TxPctSize; + } + else + { + ep->xfer_len = 0U; + } + + /* Transfer is completed */ + if (ep->xfer_len == 0U) + { + PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, 0U); + PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, 0U); + + /* TX COMPLETE */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->DataInStageCallback(hpcd, ep->num); +#else + HAL_PCD_DataInStageCallback(hpcd, ep->num); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + + if ((wEPVal & USB_EP_DTOG_RX) != 0U) + { + PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 1U); + } + } + else /* Transfer is not yet Done */ + { + /* need to Free USB Buff */ + if ((wEPVal & USB_EP_DTOG_RX) != 0U) + { + PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 1U); + } + + /* Still there is data to Fill in the next Buffer */ + if (ep->xfer_fill_db == 1U) + { + ep->xfer_buff += TxPctSize; + ep->xfer_count += TxPctSize; + + /* Calculate the len of the new buffer to fill */ + if (ep->xfer_len_db >= ep->maxpacket) + { + len = ep->maxpacket; + ep->xfer_len_db -= len; + } + else if (ep->xfer_len_db == 0U) + { + len = TxPctSize; + ep->xfer_fill_db = 0U; + } + else + { + ep->xfer_fill_db = 0U; + len = ep->xfer_len_db; + ep->xfer_len_db = 0U; + } + + /* Write remaining Data to Buffer */ + /* Set the Double buffer counter for pma buffer1 */ + PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, len); + + /* Copy user buffer to USB PMA */ + USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, (uint16_t)len); + } + } + } + else /* Data Buffer1 ACK received */ + { + /* multi-packet on the NON control IN endpoint */ + TxPctSize = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num); + + if (ep->xfer_len >= TxPctSize) + { + ep->xfer_len -= TxPctSize; + } + else + { + ep->xfer_len = 0U; + } + + /* Transfer is completed */ + if (ep->xfer_len == 0U) + { + PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, 0U); + PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, 0U); + + /* TX COMPLETE */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->DataInStageCallback(hpcd, ep->num); +#else + HAL_PCD_DataInStageCallback(hpcd, ep->num); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + + /* need to Free USB Buff */ + if ((wEPVal & USB_EP_DTOG_RX) == 0U) + { + PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 1U); + } + } + else /* Transfer is not yet Done */ + { + /* need to Free USB Buff */ + if ((wEPVal & USB_EP_DTOG_RX) == 0U) + { + PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 1U); + } + + /* Still there is data to Fill in the next Buffer */ + if (ep->xfer_fill_db == 1U) + { + ep->xfer_buff += TxPctSize; + ep->xfer_count += TxPctSize; + + /* Calculate the len of the new buffer to fill */ + if (ep->xfer_len_db >= ep->maxpacket) + { + len = ep->maxpacket; + ep->xfer_len_db -= len; + } + else if (ep->xfer_len_db == 0U) + { + len = TxPctSize; + ep->xfer_fill_db = 0U; + } + else + { + len = ep->xfer_len_db; + ep->xfer_len_db = 0U; + ep->xfer_fill_db = 0; + } + + /* Set the Double buffer counter for pmabuffer1 */ + PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, len); + + /* Copy the user buffer to USB PMA */ + USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, (uint16_t)len); + } + } + } + + /*enable endpoint IN*/ + PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_VALID); + + return HAL_OK; +} +#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ + + + +/** + * @} + */ +#endif /* defined (USB_DRD_FS) */ +#endif /* HAL_PCD_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pcd_ex.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pcd_ex.c new file mode 100644 index 0000000000..e9e7bc0cbe --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pcd_ex.c @@ -0,0 +1,333 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_pcd_ex.c + * @author MCD Application Team + * @brief PCD Extended HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the USB Peripheral Controller: + * + Extended features functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup PCDEx PCDEx + * @brief PCD Extended HAL module driver + * @{ + */ + +#ifdef HAL_PCD_MODULE_ENABLED + +#if defined (USB_DRD_FS) +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup PCDEx_Exported_Functions PCDEx Exported Functions + * @{ + */ + +/** @defgroup PCDEx_Exported_Functions_Group1 Peripheral Control functions + * @brief PCDEx control functions + * +@verbatim + =============================================================================== + ##### Extended features functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Update FIFO configuration + +@endverbatim + * @{ + */ + +/** + * @brief Configure PMA for EP + * @param hpcd Device instance + * @param ep_addr endpoint address + * @param ep_kind endpoint Kind + * USB_SNG_BUF: Single Buffer used + * USB_DBL_BUF: Double Buffer used + * @param pmaadress: EP address in The PMA: In case of single buffer endpoint + * this parameter is 16-bit value providing the address + * in PMA allocated to endpoint. + * In case of double buffer endpoint this parameter + * is a 32-bit value providing the endpoint buffer 0 address + * in the LSB part of 32-bit value and endpoint buffer 1 address + * in the MSB part of 32-bit value. + * @retval HAL status + */ + +HAL_StatusTypeDef HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd, uint16_t ep_addr, + uint16_t ep_kind, uint32_t pmaadress) +{ + PCD_EPTypeDef *ep; + + /* initialize ep structure*/ + if ((0x80U & ep_addr) == 0x80U) + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + } + else + { + ep = &hpcd->OUT_ep[ep_addr]; + } + + /* Here we check if the endpoint is single or double Buffer*/ + if (ep_kind == PCD_SNG_BUF) + { + /* Single Buffer */ + ep->doublebuffer = 0U; + /* Configure the PMA */ + ep->pmaadress = (uint16_t)pmaadress; + } +#if (USE_USB_DOUBLE_BUFFER == 1U) + else /* USB_DBL_BUF */ + { + /* Double Buffer Endpoint */ + ep->doublebuffer = 1U; + /* Configure the PMA */ + ep->pmaaddr0 = (uint16_t)(pmaadress & 0xFFFFU); + ep->pmaaddr1 = (uint16_t)((pmaadress & 0xFFFF0000U) >> 16); + } +#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ + + return HAL_OK; +} + +/** + * @brief Activate BatteryCharging feature. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef *hpcd) +{ + USB_DRD_TypeDef *USBx = hpcd->Instance; + hpcd->battery_charging_active = 1U; + + /* Enable BCD feature */ + USBx->BCDR |= USB_BCDR_BCDEN; + + /* Enable DCD : Data Contact Detect */ + USBx->BCDR &= ~(USB_BCDR_PDEN); + USBx->BCDR &= ~(USB_BCDR_SDEN); + USBx->BCDR |= USB_BCDR_DCDEN; + + return HAL_OK; +} + +/** + * @brief Deactivate BatteryCharging feature. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef *hpcd) +{ + USB_DRD_TypeDef *USBx = hpcd->Instance; + hpcd->battery_charging_active = 0U; + + /* Disable BCD feature */ + USBx->BCDR &= ~(USB_BCDR_BCDEN); + + return HAL_OK; +} + +/** + * @brief Handle BatteryCharging Process. + * @param hpcd PCD handle + * @retval HAL status + */ +void HAL_PCDEx_BCD_VBUSDetect(PCD_HandleTypeDef *hpcd) +{ + USB_DRD_TypeDef *USBx = hpcd->Instance; + uint32_t tickstart = HAL_GetTick(); + + /* Wait for Min DCD Timeout */ + HAL_Delay(300U); + + /* Data Pin Contact ? Check Detect flag */ + if ((USBx->BCDR & USB_BCDR_DCDET) == USB_BCDR_DCDET) + { +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->BCDCallback(hpcd, PCD_BCD_CONTACT_DETECTION); +#else + HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CONTACT_DETECTION); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + /* Primary detection: checks if connected to Standard Downstream Port + (without charging capability) */ + USBx->BCDR &= ~(USB_BCDR_DCDEN); + HAL_Delay(50U); + USBx->BCDR |= (USB_BCDR_PDEN); + HAL_Delay(50U); + + /* If Charger detect ? */ + if ((USBx->BCDR & USB_BCDR_PDET) == USB_BCDR_PDET) + { + /* Start secondary detection to check connection to Charging Downstream + Port or Dedicated Charging Port */ + USBx->BCDR &= ~(USB_BCDR_PDEN); + HAL_Delay(50U); + USBx->BCDR |= (USB_BCDR_SDEN); + HAL_Delay(50U); + + /* If CDP ? */ + if ((USBx->BCDR & USB_BCDR_SDET) == USB_BCDR_SDET) + { + /* Dedicated Downstream Port DCP */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->BCDCallback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT); +#else + HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + else + { + /* Charging Downstream Port CDP */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->BCDCallback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT); +#else + HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + } + else /* NO */ + { + /* Standard Downstream Port */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->BCDCallback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT); +#else + HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + + /* Battery Charging capability discovery finished Start Enumeration */ + (void)HAL_PCDEx_DeActivateBCD(hpcd); + + /* Check for the Timeout, else start USB Device */ + if ((HAL_GetTick() - tickstart) > 1000U) + { +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->BCDCallback(hpcd, PCD_BCD_ERROR); +#else + HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_ERROR); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + else + { +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->BCDCallback(hpcd, PCD_BCD_DISCOVERY_COMPLETED); +#else + HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DISCOVERY_COMPLETED); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } +} + + +/** + * @brief Activate LPM feature. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef *hpcd) +{ + + USB_DRD_TypeDef *USBx = hpcd->Instance; + hpcd->lpm_active = 1U; + hpcd->LPM_State = LPM_L0; + + USBx->LPMCSR |= USB_LPMCSR_LMPEN; + USBx->LPMCSR |= USB_LPMCSR_LPMACK; + + return HAL_OK; +} + +/** + * @brief Deactivate LPM feature. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef *hpcd) +{ + USB_DRD_TypeDef *USBx = hpcd->Instance; + + hpcd->lpm_active = 0U; + + USBx->LPMCSR &= ~(USB_LPMCSR_LMPEN); + USBx->LPMCSR &= ~(USB_LPMCSR_LPMACK); + + return HAL_OK; +} + + + +/** + * @brief Send LPM message to user layer callback. + * @param hpcd PCD handle + * @param msg LPM message + * @retval HAL status + */ +__weak void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + UNUSED(msg); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCDEx_LPM_Callback could be implemented in the user file + */ +} + +/** + * @brief Send BatteryCharging message to user layer callback. + * @param hpcd PCD handle + * @param msg LPM message + * @retval HAL status + */ +__weak void HAL_PCDEx_BCD_Callback(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + UNUSED(msg); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCDEx_BCD_Callback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** + * @} + */ +#endif /* defined (USB_DRD_FS) */ +#endif /* HAL_PCD_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pka.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pka.c new file mode 100644 index 0000000000..4d77c6b31d --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pka.c @@ -0,0 +1,2963 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_pka.c + * @author MCD Application Team + * @brief PKA HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of public key accelerator(PKA): + * + Initialization and de-initialization functions + * + Start an operation + * + Retrieve the operation result + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The PKA HAL driver can be used as follows: + + (#) Declare a PKA_HandleTypeDef handle structure, for example: PKA_HandleTypeDef hpka; + + (#) Initialize the PKA low level resources by implementing the HAL_PKA_MspInit() API: + (##) Enable the PKA interface clock + (##) NVIC configuration if you need to use interrupt process + (+++) Configure the PKA interrupt priority + (+++) Enable the NVIC PKA IRQ Channel + + (#) Initialize the PKA registers by calling the HAL_PKA_Init() API which trig + HAL_PKA_MspInit(). + + (#) Fill entirely the input structure corresponding to your operation: + For instance: PKA_ModExpInTypeDef for HAL_PKA_ModExp(). + + (#) Execute the operation (in polling or interrupt) and check the returned value. + + (#) Retrieve the result of the operation (For instance, HAL_PKA_ModExp_GetResult for + HAL_PKA_ModExp operation). The function to gather the result is different for each + kind of operation. The correspondence can be found in the following section. + + (#) Call the function HAL_PKA_DeInit() to restore the default configuration which trig + HAL_PKA_MspDeInit(). + + *** High level operation *** + ================================= + [..] + (+) Input structure requires buffers as uint8_t array. + + (+) Output structure requires buffers as uint8_t array. + + (+) Modular exponentiation using: + (++) HAL_PKA_ModExp(). + (++) HAL_PKA_ModExp_IT(). + (++) HAL_PKA_ModExpFastMode(). + (++) HAL_PKA_ModExpFastMode_IT(). + (++) HAL_PKA_ModExpProtectMode(). + (++) HAL_PKA_ModExpProtectMode_IT(). + (++) HAL_PKA_ModExp_GetResult() to retrieve the result of the operation. + + (+) RSA Chinese Remainder Theorem (CRT) using: + (++) HAL_PKA_RSACRTExp(). + (++) HAL_PKA_RSACRTExp_IT(). + (++) HAL_PKA_RSACRTExp_GetResult() to retrieve the result of the operation. + + (+) ECC Point Check using: + (++) HAL_PKA_PointCheck(). + (++) HAL_PKA_PointCheck_IT(). + (++) HAL_PKA_PointCheck_IsOnCurve() to retrieve the result of the operation. + + (+) ECDSA Sign + (++) HAL_PKA_ECDSASign(). + (++) HAL_PKA_ECDSASign_IT(). + (++) HAL_PKA_ECDSASign_GetResult() to retrieve the result of the operation. + + (+) ECDSA Verify + (++) HAL_PKA_ECDSAVerif(). + (++) HAL_PKA_ECDSAVerif_IT(). + (++) HAL_PKA_ECDSAVerif_IsValidSignature() to retrieve the result of the operation. + + (+) ECC Scalar Multiplication using: + (++) HAL_PKA_ECCMul(). + (++) HAL_PKA_ECCMul_IT(). + (++) HAL_PKA_ECCMul_GetResult() to retrieve the result of the operation. + + (+) ECC double base ladder using: + (++) HAL_PKA_ECCDoubleBaseLadder(). + (++) HAL_PKA_ECCDoubleBaseLadder_IT(). + (++) HAL_PKA_ECCDoubleBaseLadder_GetResult() to retrieve the result of the operation. + + (+) ECC projective to affine using: + (++) HAL_PKA_ECCProjective2Affine(). + (++) HAL_PKA_ECCProjective2Affine_IT(). + (++) HAL_PKA_ECCProjective2Affine_GetResult() to retrieve the result of the operation. + + (+) ECC complete addition using: + (++) HAL_PKA_ECCCompleteAddition(). + (++) HAL_PKA_ECCCompleteAddition_IT(). + (++) HAL_PKA_ECCCompleteAddition_GetResult() to retrieve the result of the operation. + + *** Low level operation *** + ================================= + [..] + (+) Input structure requires buffers as uint32_t array. + + (+) Output structure requires buffers as uint32_t array. + + (+) Arithmetic addition using: + (++) HAL_PKA_Add(). + (++) HAL_PKA_Add_IT(). + (++) HAL_PKA_Arithmetic_GetResult() to retrieve the result of the operation. + The resulting size can be the input parameter or the input parameter size + 1 (overflow). + + (+) Arithmetic subtraction using: + (++) HAL_PKA_Sub(). + (++) HAL_PKA_Sub_IT(). + (++) HAL_PKA_Arithmetic_GetResult() to retrieve the result of the operation. + + (+) Arithmetic multiplication using: + (++) HAL_PKA_Mul(). + (++) HAL_PKA_Mul_IT(). + (++) HAL_PKA_Arithmetic_GetResult() to retrieve the result of the operation. + + (+) Comparison using: + (++) HAL_PKA_Cmp(). + (++) HAL_PKA_Cmp_IT(). + (++) HAL_PKA_Arithmetic_GetResult() to retrieve the result of the operation. + + (+) Modular addition using: + (++) HAL_PKA_ModAdd(). + (++) HAL_PKA_ModAdd_IT(). + (++) HAL_PKA_Arithmetic_GetResult() to retrieve the result of the operation. + + (+) Modular subtraction using: + (++) HAL_PKA_ModSub(). + (++) HAL_PKA_ModSub_IT(). + (++) HAL_PKA_Arithmetic_GetResult() to retrieve the result of the operation. + + (+) Modular inversion using: + (++) HAL_PKA_ModInv(). + (++) HAL_PKA_ModInv_IT(). + (++) HAL_PKA_Arithmetic_GetResult() to retrieve the result of the operation. + + (+) Modular reduction using: + (++) HAL_PKA_ModRed(). + (++) HAL_PKA_ModRed_IT(). + (++) HAL_PKA_Arithmetic_GetResult() to retrieve the result of the operation. + + (+) Montgomery multiplication using: + (++) HAL_PKA_MontgomeryMul(). + (++) HAL_PKA_MontgomeryMul_IT(). + (++) HAL_PKA_Arithmetic_GetResult() to retrieve the result of the operation. + + *** Montgomery parameter *** + ================================= + (+) For some operation, the computation of the Montgomery parameter is a prerequisite. + (+) Input structure requires buffers as uint8_t array. + (+) Output structure requires buffers as uint32_t array.(Only used inside PKA). + (+) You can compute the Montgomery parameter using: + (++) HAL_PKA_MontgomeryParam(). + (++) HAL_PKA_MontgomeryParam_IT(). + (++) HAL_PKA_MontgomeryParam_GetResult() to retrieve the result of the operation. + + *** Polling mode operation *** + =================================== + [..] + (+) When an operation is started in polling mode, the function returns when: + (++) A timeout is encounter. + (++) The operation is completed. + + *** Interrupt mode operation *** + =================================== + [..] + (+) Add HAL_PKA_IRQHandler to the IRQHandler of PKA. + (+) Enable the IRQ using HAL_NVIC_EnableIRQ(). + (+) When an operation is started in interrupt mode, the function returns immediately. + (+) When the operation is completed, the callback HAL_PKA_OperationCpltCallback is called. + (+) When an error is encountered, the callback HAL_PKA_ErrorCallback is called. + (+) To stop any operation in interrupt mode, use HAL_PKA_Abort(). + + *** Utilities *** + =================================== + [..] + (+) To clear the PKA RAM, use HAL_PKA_RAMReset(). + (+) To get current state, use HAL_PKA_GetState(). + (+) To get current error, use HAL_PKA_GetError(). + + *** Callback registration *** + ============================================= + [..] + + The compilation flag USE_HAL_PKA_REGISTER_CALLBACKS, when set to 1, + allows the user to configure dynamically the driver callbacks. + Use Functions HAL_PKA_RegisterCallback() + to register an interrupt callback. + [..] + + Function HAL_PKA_RegisterCallback() allows to register following callbacks: + (+) OperationCpltCallback : callback for End of operation. + (+) ErrorCallback : callback for error detection. + (+) MspInitCallback : callback for Msp Init. + (+) MspDeInitCallback : callback for Msp DeInit. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + [..] + + Use function HAL_PKA_UnRegisterCallback to reset a callback to the default + weak function. + [..] + + HAL_PKA_UnRegisterCallback takes as parameters the HAL peripheral handle, + and the Callback ID. + This function allows to reset following callbacks: + (+) OperationCpltCallback : callback for End of operation. + (+) ErrorCallback : callback for error detection. + (+) MspInitCallback : callback for Msp Init. + (+) MspDeInitCallback : callback for Msp DeInit. + [..] + + By default, after the HAL_PKA_Init() and when the state is HAL_PKA_STATE_RESET + all callbacks are set to the corresponding weak functions: + examples HAL_PKA_OperationCpltCallback(), HAL_PKA_ErrorCallback(). + Exception done for MspInit and MspDeInit functions that are + reset to the legacy weak functions in the HAL_PKA_Init()/ HAL_PKA_DeInit() only when + these callbacks are null (not registered beforehand). + [..] + + If MspInit or MspDeInit are not null, the HAL_PKA_Init()/ HAL_PKA_DeInit() + keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state. + [..] + + Callbacks can be registered/unregistered in HAL_PKA_STATE_READY state only. + Exception done MspInit/MspDeInit functions that can be registered/unregistered + in HAL_PKA_STATE_READY or HAL_PKA_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_PKA_RegisterCallback() before calling HAL_PKA_DeInit() + or HAL_PKA_Init() function. + [..] + + When the compilation flag USE_HAL_PKA_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 "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +#if defined(PKA) && defined(HAL_PKA_MODULE_ENABLED) + +/** @defgroup PKA PKA + * @brief PKA HAL module driver. + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup PKA_Private_Define PKA Private Define + * @{ + */ +#define PKA_RAM_SIZE 1334U + +/* Private macro -------------------------------------------------------------*/ +#define __PKA_RAM_PARAM_END(TAB,INDEX) do{ \ + TAB[INDEX] = 0UL; \ + TAB[INDEX + 1U] = 0UL; \ + } while(0) +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +static uint32_t primeordersize; +static uint32_t opsize; +static uint32_t modulussize; +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup PKA_Private_Functions PKA Private Functions + * @{ + */ +uint32_t PKA_GetMode(const PKA_HandleTypeDef *hpka); +HAL_StatusTypeDef PKA_PollEndOfOperation(const PKA_HandleTypeDef *hpka, uint32_t Timeout, uint32_t Tickstart); +uint32_t PKA_CheckError(const PKA_HandleTypeDef *hpka, uint32_t mode); +uint32_t PKA_GetBitSize_u8(uint32_t byteNumber); +uint32_t PKA_GetOptBitSize_u8(uint32_t byteNumber, uint8_t msb); +uint32_t PKA_GetBitSize_u32(uint32_t wordNumber); +uint32_t PKA_GetArraySize_u8(uint32_t bitSize); +void PKA_Memcpy_u32_to_u8(uint8_t dst[], __IO const uint32_t src[], size_t n); +void PKA_Memcpy_u8_to_u32(__IO uint32_t dst[], const uint8_t src[], size_t n); +void PKA_Memcpy_u32_to_u32(__IO uint32_t dst[], __IO const uint32_t src[], size_t n); +HAL_StatusTypeDef PKA_Process(PKA_HandleTypeDef *hpka, uint32_t mode, uint32_t Timeout); +HAL_StatusTypeDef PKA_Process_IT(PKA_HandleTypeDef *hpka, uint32_t mode); +void PKA_ModExp_Set(PKA_HandleTypeDef *hpka, PKA_ModExpInTypeDef *in); +void PKA_ModExpFastMode_Set(PKA_HandleTypeDef *hpka, PKA_ModExpFastModeInTypeDef *in); +void PKA_ModExpProtectMode_Set(PKA_HandleTypeDef *hpka, PKA_ModExpProtectModeInTypeDef *in); +void PKA_ECDSASign_Set(PKA_HandleTypeDef *hpka, PKA_ECDSASignInTypeDef *in); +void PKA_ECDSAVerif_Set(PKA_HandleTypeDef *hpka, PKA_ECDSAVerifInTypeDef *in); +void PKA_RSACRTExp_Set(PKA_HandleTypeDef *hpka, PKA_RSACRTExpInTypeDef *in); +void PKA_PointCheck_Set(PKA_HandleTypeDef *hpka, PKA_PointCheckInTypeDef *in); +void PKA_ECCMul_Set(PKA_HandleTypeDef *hpka, PKA_ECCMulInTypeDef *in); +void PKA_ModRed_Set(PKA_HandleTypeDef *hpka, PKA_ModRedInTypeDef *in); +void PKA_ModInv_Set(PKA_HandleTypeDef *hpka, PKA_ModInvInTypeDef *in); +void PKA_MontgomeryParam_Set(PKA_HandleTypeDef *hpka, const uint32_t size, const uint8_t *pOp1); +void PKA_ARI_Set(PKA_HandleTypeDef *hpka, const uint32_t size, const uint32_t *pOp1, const uint32_t *pOp2, + const uint8_t *pOp3); +void PKA_ECCDoubleBaseLadder_Set(PKA_HandleTypeDef *hpka, PKA_ECCDoubleBaseLadderInTypeDef *in); +void PKA_ECCProjective2Affine_Set(PKA_HandleTypeDef *hpka, PKA_ECCProjective2AffineInTypeDef *in); +void PKA_ECCCompleteAddition_Set(PKA_HandleTypeDef *hpka, PKA_ECCCompleteAdditionInTypeDef *in); +HAL_StatusTypeDef PKA_WaitOnFlagUntilTimeout(PKA_HandleTypeDef *hpka, uint32_t Flag, FlagStatus Status, + uint32_t Tickstart, uint32_t Timeout); +uint32_t PKA_Result_GetSize(const PKA_HandleTypeDef *hpka, uint32_t Startindex, uint32_t Maxsize); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup PKA_Exported_Functions PKA Exported Functions + * @{ + */ + +/** @defgroup PKA_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and de-initialization functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + deinitialize the PKAx peripheral: + + (+) User must implement HAL_PKA_MspInit() function in which he configures + all related peripherals resources (CLOCK, IT and NVIC ). + + (+) Call the function HAL_PKA_Init() to configure the device. + + (+) Call the function HAL_PKA_DeInit() to restore the default configuration + of the selected PKAx peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the PKA according to the specified + * parameters in the PKA_InitTypeDef and initialize the associated handle. + * @param hpka PKA handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_Init(PKA_HandleTypeDef *hpka) +{ + HAL_StatusTypeDef err = HAL_OK; + uint32_t tickstart; + + /* Check the PKA handle allocation */ + if (hpka != NULL) + { + /* Check the parameters */ + assert_param(IS_PKA_ALL_INSTANCE(hpka->Instance)); + + if (hpka->State == HAL_PKA_STATE_RESET) + { + +#if (USE_HAL_PKA_REGISTER_CALLBACKS == 1) + /* Init the PKA Callback settings */ + hpka->OperationCpltCallback = HAL_PKA_OperationCpltCallback; /* Legacy weak OperationCpltCallback */ + hpka->ErrorCallback = HAL_PKA_ErrorCallback; /* Legacy weak ErrorCallback */ + + if (hpka->MspInitCallback == NULL) + { + hpka->MspInitCallback = HAL_PKA_MspInit; /* Legacy weak MspInit */ + } + + /* Init the low level hardware */ + hpka->MspInitCallback(hpka); +#else + /* Init the low level hardware */ + HAL_PKA_MspInit(hpka); +#endif /* USE_HAL_PKA_REGISTER_CALLBACKS */ + } + + /* Set the state to busy */ + hpka->State = HAL_PKA_STATE_BUSY; + + /* Reset the control register and enable the PKA */ + hpka->Instance->CR = PKA_CR_EN; + + /* Get current tick */ + tickstart = HAL_GetTick(); + + /* Wait the INITOK flag Setting */ + if (PKA_WaitOnFlagUntilTimeout(hpka, PKA_SR_INITOK, RESET, tickstart, 5000) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Reset any pending flag */ + SET_BIT(hpka->Instance->CLRFR, PKA_CLRFR_PROCENDFC | PKA_CLRFR_RAMERRFC | PKA_CLRFR_ADDRERRFC | PKA_CLRFR_OPERRFC); + + /* Initialize the error code */ + hpka->ErrorCode = HAL_PKA_ERROR_NONE; + + /* Set the state to ready */ + hpka->State = HAL_PKA_STATE_READY; + } + else + { + err = HAL_ERROR; + } + + return err; +} + +/** + * @brief DeInitialize the PKA peripheral. + * @param hpka PKA handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_DeInit(PKA_HandleTypeDef *hpka) +{ + HAL_StatusTypeDef err = HAL_OK; + + /* Check the PKA handle allocation */ + if (hpka != NULL) + { + /* Check the parameters */ + assert_param(IS_PKA_ALL_INSTANCE(hpka->Instance)); + + /* Set the state to busy */ + hpka->State = HAL_PKA_STATE_BUSY; + + /* Reset the control register */ + /* This abort any operation in progress (PKA RAM content is not guaranteed in this case) */ + hpka->Instance->CR = 0; + + /* Reset any pending flag */ + SET_BIT(hpka->Instance->CLRFR, PKA_CLRFR_PROCENDFC | PKA_CLRFR_RAMERRFC | PKA_CLRFR_ADDRERRFC | PKA_CLRFR_OPERRFC); + +#if (USE_HAL_PKA_REGISTER_CALLBACKS == 1) + if (hpka->MspDeInitCallback == NULL) + { + hpka->MspDeInitCallback = HAL_PKA_MspDeInit; /* Legacy weak MspDeInit */ + } + + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + hpka->MspDeInitCallback(hpka); +#else + /* DeInit the low level hardware: CLOCK, NVIC */ + HAL_PKA_MspDeInit(hpka); +#endif /* USE_HAL_PKA_REGISTER_CALLBACKS */ + + /* Reset the error code */ + hpka->ErrorCode = HAL_PKA_ERROR_NONE; + + /* Reset the state */ + hpka->State = HAL_PKA_STATE_RESET; + } + else + { + err = HAL_ERROR; + } + + return err; +} + +/** + * @brief Initialize the PKA MSP. + * @param hpka PKA handle + * @retval None + */ +__weak void HAL_PKA_MspInit(PKA_HandleTypeDef *hpka) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpka); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PKA_MspInit can be implemented in the user file + */ +} + +/** + * @brief DeInitialize the PKA MSP. + * @param hpka PKA handle + * @retval None + */ +__weak void HAL_PKA_MspDeInit(PKA_HandleTypeDef *hpka) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpka); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PKA_MspDeInit can be implemented in the user file + */ +} + +#if (USE_HAL_PKA_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User PKA Callback + * To be used instead of the weak predefined callback + * @param hpka Pointer to a PKA_HandleTypeDef structure that contains + * the configuration information for the specified PKA. + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_PKA_OPERATION_COMPLETE_CB_ID End of operation callback ID + * @arg @ref HAL_PKA_ERROR_CB_ID Error callback ID + * @arg @ref HAL_PKA_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_PKA_MSPDEINIT_CB_ID MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_RegisterCallback(PKA_HandleTypeDef *hpka, HAL_PKA_CallbackIDTypeDef CallbackID, + pPKA_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hpka->ErrorCode |= HAL_PKA_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + if (HAL_PKA_STATE_READY == hpka->State) + { + switch (CallbackID) + { + case HAL_PKA_OPERATION_COMPLETE_CB_ID : + hpka->OperationCpltCallback = pCallback; + break; + + case HAL_PKA_ERROR_CB_ID : + hpka->ErrorCallback = pCallback; + break; + + case HAL_PKA_MSPINIT_CB_ID : + hpka->MspInitCallback = pCallback; + break; + + case HAL_PKA_MSPDEINIT_CB_ID : + hpka->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hpka->ErrorCode |= HAL_PKA_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_PKA_STATE_RESET == hpka->State) + { + switch (CallbackID) + { + case HAL_PKA_MSPINIT_CB_ID : + hpka->MspInitCallback = pCallback; + break; + + case HAL_PKA_MSPDEINIT_CB_ID : + hpka->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hpka->ErrorCode |= HAL_PKA_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hpka->ErrorCode |= HAL_PKA_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister a PKA Callback + * PKA callback is redirected to the weak predefined callback + * @param hpka Pointer to a PKA_HandleTypeDef structure that contains + * the configuration information for the specified PKA. + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_PKA_OPERATION_COMPLETE_CB_ID End of operation callback ID + * @arg @ref HAL_PKA_ERROR_CB_ID Error callback ID + * @arg @ref HAL_PKA_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_PKA_MSPDEINIT_CB_ID MspDeInit callback ID + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_UnRegisterCallback(PKA_HandleTypeDef *hpka, HAL_PKA_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (HAL_PKA_STATE_READY == hpka->State) + { + switch (CallbackID) + { + case HAL_PKA_OPERATION_COMPLETE_CB_ID : + hpka->OperationCpltCallback = HAL_PKA_OperationCpltCallback; /* Legacy weak OperationCpltCallback */ + break; + + case HAL_PKA_ERROR_CB_ID : + hpka->ErrorCallback = HAL_PKA_ErrorCallback; /* Legacy weak ErrorCallback */ + break; + + case HAL_PKA_MSPINIT_CB_ID : + hpka->MspInitCallback = HAL_PKA_MspInit; /* Legacy weak MspInit */ + break; + + case HAL_PKA_MSPDEINIT_CB_ID : + hpka->MspDeInitCallback = HAL_PKA_MspDeInit; /* Legacy weak MspDeInit */ + break; + + default : + /* Update the error code */ + hpka->ErrorCode |= HAL_PKA_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_PKA_STATE_RESET == hpka->State) + { + switch (CallbackID) + { + case HAL_PKA_MSPINIT_CB_ID : + hpka->MspInitCallback = HAL_PKA_MspInit; /* Legacy weak MspInit */ + break; + + case HAL_PKA_MSPDEINIT_CB_ID : + hpka->MspDeInitCallback = HAL_PKA_MspDeInit; /* Legacy weak MspDeInit */ + break; + + default : + /* Update the error code */ + hpka->ErrorCode |= HAL_PKA_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hpka->ErrorCode |= HAL_PKA_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +#endif /* USE_HAL_PKA_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup PKA_Exported_Functions_Group2 IO operation functions + * @brief IO operation functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the PKA operations. + + (#) There are two modes of operation: + + (++) Blocking mode : The operation is performed in the polling mode. + These functions return when data operation is completed. + (++) No-Blocking mode : The operation is performed using Interrupts. + These functions return immediately. + The end of the operation is indicated by HAL_PKA_ErrorCallback in case of error. + The end of the operation is indicated by HAL_PKA_OperationCpltCallback in case of success. + To stop any operation in interrupt mode, use HAL_PKA_Abort(). + + (#) Blocking mode functions are : + + (++) HAL_PKA_ModExp() + (++) HAL_PKA_ModExpFastMode() + (++) HAL_PKA_ModExpProtectMode() + (++) HAL_PKA_ModExp_GetResult(); + + (++) HAL_PKA_ECDSASign() + (++) HAL_PKA_ECDSASign_GetResult(); + + (++) HAL_PKA_ECDSAVerif() + (++) HAL_PKA_ECDSAVerif_IsValidSignature(); + + (++) HAL_PKA_RSACRTExp() + (++) HAL_PKA_RSACRTExp_GetResult(); + + (++) HAL_PKA_PointCheck() + (++) HAL_PKA_PointCheck_IsOnCurve(); + + (++) HAL_PKA_ECCMul() + (++) HAL_PKA_ECCMulFastMode() + (++) HAL_PKA_ECCMul_GetResult(); + + (++) HAL_PKA_ECCDoubleBaseLadder() + (++) HAL_PKA_ECCDoubleBaseLadder_GetResult(); + (++) HAL_PKA_ECCProjective2Affine() + (++) HAL_PKA_ECCProjective2Affine_GetResult(); + (++) HAL_PKA_ECCCompleteAddition() + (++) HAL_PKA_ECCCompleteAddition_GetResult(); + + (++) HAL_PKA_Add() + (++) HAL_PKA_Sub() + (++) HAL_PKA_Cmp() + (++) HAL_PKA_Mul() + (++) HAL_PKA_ModAdd() + (++) HAL_PKA_ModSub() + (++) HAL_PKA_ModInv() + (++) HAL_PKA_ModRed() + (++) HAL_PKA_MontgomeryMul() + (++) HAL_PKA_Arithmetic_GetResult(P); + + (++) HAL_PKA_MontgomeryParam() + (++) HAL_PKA_MontgomeryParam_GetResult(); + + (#) No-Blocking mode functions with Interrupt are : + + (++) HAL_PKA_ModExp_IT(); + (++) HAL_PKA_ModExpFastMode_IT(); + (++) HAL_PKA_ModExpProtectMode_IT() + (++) HAL_PKA_ModExp_GetResult(); + + (++) HAL_PKA_ECDSASign_IT(); + (++) HAL_PKA_ECDSASign_GetResult(); + + (++) HAL_PKA_ECDSAVerif_IT(); + (++) HAL_PKA_ECDSAVerif_IsValidSignature(); + + (++) HAL_PKA_RSACRTExp_IT(); + (++) HAL_PKA_RSACRTExp_GetResult(); + + (++) HAL_PKA_PointCheck_IT(); + (++) HAL_PKA_PointCheck_IsOnCurve(); + + (++) HAL_PKA_ECCMul_IT(); + (++) HAL_PKA_ECCMulFastMode_IT(); + (++) HAL_PKA_ECCMul_GetResult(); + + (++) HAL_PKA_ECCDoubleBaseLadder_IT() + (++) HAL_PKA_ECCDoubleBaseLadder_GetResult(); + (++) HAL_PKA_ECCProjective2Affine_IT() + (++) HAL_PKA_ECCProjective2Affine_GetResult(); + (++) HAL_PKA_ECCCompleteAddition_IT() + (++) HAL_PKA_ECCCompleteAddition_GetResult(); + (++) HAL_PKA_Add_IT(); + (++) HAL_PKA_Sub_IT(); + (++) HAL_PKA_Cmp_IT(); + (++) HAL_PKA_Mul_IT(); + (++) HAL_PKA_ModAdd_IT(); + (++) HAL_PKA_ModSub_IT(); + (++) HAL_PKA_ModInv_IT(); + (++) HAL_PKA_ModRed_IT(); + (++) HAL_PKA_MontgomeryMul_IT(); + (++) HAL_PKA_Arithmetic_GetResult(); + + (++) HAL_PKA_MontgomeryParam_IT(); + (++) HAL_PKA_MontgomeryParam_GetResult(); + + (++) HAL_PKA_Abort(); + +@endverbatim + * @{ + */ + +/** + * @brief Modular exponentiation in blocking mode. + * @param hpka PKA handle + * @param in Input information + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_ModExp(PKA_HandleTypeDef *hpka, PKA_ModExpInTypeDef *in, uint32_t Timeout) +{ + /* Set input parameter in PKA RAM */ + PKA_ModExp_Set(hpka, in); + + opsize = in->OpSize; + + /* Start the operation */ + return PKA_Process(hpka, PKA_MODE_MODULAR_EXP, Timeout); +} + +/** + * @brief Modular exponentiation in non-blocking mode with Interrupt. + * @param hpka PKA handle + * @param in Input information + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_ModExp_IT(PKA_HandleTypeDef *hpka, PKA_ModExpInTypeDef *in) +{ + /* Set input parameter in PKA RAM */ + PKA_ModExp_Set(hpka, in); + + opsize = in->OpSize; + + /* Start the operation */ + return PKA_Process_IT(hpka, PKA_MODE_MODULAR_EXP); +} + +/** + * @brief Modular exponentiation in blocking mode. + * @param hpka PKA handle + * @param in Input information + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_ModExpFastMode(PKA_HandleTypeDef *hpka, PKA_ModExpFastModeInTypeDef *in, uint32_t Timeout) +{ + /* Set input parameter in PKA RAM */ + PKA_ModExpFastMode_Set(hpka, in); + + opsize = in->OpSize; + + /* Start the operation */ + return PKA_Process(hpka, PKA_MODE_MODULAR_EXP_FAST_MODE, Timeout); +} + +/** + * @brief Modular exponentiation in non-blocking mode with Interrupt. + * @param hpka PKA handle + * @param in Input information + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_ModExpFastMode_IT(PKA_HandleTypeDef *hpka, PKA_ModExpFastModeInTypeDef *in) +{ + /* Set input parameter in PKA RAM */ + PKA_ModExpFastMode_Set(hpka, in); + + opsize = in->OpSize; + + /* Start the operation */ + return PKA_Process_IT(hpka, PKA_MODE_MODULAR_EXP_FAST_MODE); +} + +/** + * @brief Modular exponentiation (protected) in blocking mode. + * Useful when a secret information is involved (RSA decryption) + * @param hpka PKA handle + * @param in Input information + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_ModExpProtectMode(PKA_HandleTypeDef *hpka, PKA_ModExpProtectModeInTypeDef *in, + uint32_t Timeout) +{ + /* Set input parameter in PKA RAM */ + PKA_ModExpProtectMode_Set(hpka, in); + + opsize = in->OpSize; + + return PKA_Process(hpka, PKA_MODE_MODULAR_EXP_PROTECT, Timeout); +} + +/** + * @brief Modular exponentiation (protected) in non-blocking mode with Interrupt. + * Useful when a secret information is involved (RSA decryption) + * @param hpka PKA handle + * @param in Input information + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_ModExpProtectMode_IT(PKA_HandleTypeDef *hpka, PKA_ModExpProtectModeInTypeDef *in) +{ + /* Set input parameter in PKA RAM */ + PKA_ModExpProtectMode_Set(hpka, in); + + opsize = in->OpSize; + + return PKA_Process_IT(hpka, PKA_MODE_MODULAR_EXP_PROTECT); +} + +/** + * @brief Retrieve operation result. + * @param hpka PKA handle + * @param pRes Output buffer + * @retval HAL status + */ +void HAL_PKA_ModExp_GetResult(PKA_HandleTypeDef *hpka, uint8_t *pRes) +{ + uint32_t size; + + /* Get output result size */ + size = opsize; + + /* Move the result to appropriate location (indicated in out parameter) */ + PKA_Memcpy_u32_to_u8(pRes, &hpka->Instance->RAM[PKA_MODULAR_EXP_OUT_RESULT], size); +} + +/** + * @brief Sign a message using elliptic curves over prime fields in blocking mode. + * @param hpka PKA handle + * @param in Input information + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_ECDSASign(PKA_HandleTypeDef *hpka, PKA_ECDSASignInTypeDef *in, uint32_t Timeout) +{ + /* Set input parameter in PKA RAM */ + PKA_ECDSASign_Set(hpka, in); + + primeordersize = in->primeOrderSize; + + /* Start the operation */ + return PKA_Process(hpka, PKA_MODE_ECDSA_SIGNATURE, Timeout); +} + +/** + * @brief Sign a message using elliptic curves over prime fields in non-blocking mode with Interrupt. + * @param hpka PKA handle + * @param in Input information + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_ECDSASign_IT(PKA_HandleTypeDef *hpka, PKA_ECDSASignInTypeDef *in) +{ + /* Set input parameter in PKA RAM */ + PKA_ECDSASign_Set(hpka, in); + + primeordersize = in->primeOrderSize; + + /* Start the operation */ + return PKA_Process_IT(hpka, PKA_MODE_ECDSA_SIGNATURE); +} + +/** + * @brief Retrieve operation result. + * @param hpka PKA handle + * @param out Output information + * @param outExt Additional Output information (facultative) + */ +void HAL_PKA_ECDSASign_GetResult(PKA_HandleTypeDef *hpka, PKA_ECDSASignOutTypeDef *out, + PKA_ECDSASignOutExtParamTypeDef *outExt) +{ + uint32_t size; + + /* Get output result size */ + size = primeordersize; + + + if (out != NULL) + { + PKA_Memcpy_u32_to_u8(out->RSign, &hpka->Instance->RAM[PKA_ECDSA_SIGN_OUT_SIGNATURE_R], size); + PKA_Memcpy_u32_to_u8(out->SSign, &hpka->Instance->RAM[PKA_ECDSA_SIGN_OUT_SIGNATURE_S], size); + } + + /* If user requires the additional information */ + if (outExt != NULL) + { + /* Move the result to appropriate location (indicated in outExt parameter) */ + PKA_Memcpy_u32_to_u8(outExt->ptX, &hpka->Instance->RAM[PKA_ECDSA_SIGN_OUT_FINAL_POINT_X], size); + PKA_Memcpy_u32_to_u8(outExt->ptY, &hpka->Instance->RAM[PKA_ECDSA_SIGN_OUT_FINAL_POINT_Y], size); + } +} + +/** + * @brief Verify the validity of a signature using elliptic curves over prime fields in blocking mode. + * @param hpka PKA handle + * @param in Input information + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_ECDSAVerif(PKA_HandleTypeDef *hpka, PKA_ECDSAVerifInTypeDef *in, uint32_t Timeout) +{ + /* Set input parameter in PKA RAM */ + PKA_ECDSAVerif_Set(hpka, in); + + /* Start the operation */ + return PKA_Process(hpka, PKA_MODE_ECDSA_VERIFICATION, Timeout); +} + +/** + * @brief Verify the validity of a signature using elliptic curves + * over prime fields in non-blocking mode with Interrupt. + * @param hpka PKA handle + * @param in Input information + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_ECDSAVerif_IT(PKA_HandleTypeDef *hpka, PKA_ECDSAVerifInTypeDef *in) +{ + /* Set input parameter in PKA RAM */ + PKA_ECDSAVerif_Set(hpka, in); + + /* Start the operation */ + return PKA_Process_IT(hpka, PKA_MODE_ECDSA_VERIFICATION); +} + +/** + * @brief Return the result of the ECDSA verification operation. + * @param hpka PKA handle + * @retval 1 if signature is verified, 0 in other case + */ +uint32_t HAL_PKA_ECDSAVerif_IsValidSignature(PKA_HandleTypeDef const *const hpka) +{ + return (hpka->Instance->RAM[PKA_ECDSA_VERIF_OUT_RESULT] == 0xD60DU) ? 1UL : 0UL; +} + +/** + * @brief RSA CRT exponentiation in blocking mode. + * @param hpka PKA handle + * @param in Input information + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_RSACRTExp(PKA_HandleTypeDef *hpka, PKA_RSACRTExpInTypeDef *in, uint32_t Timeout) +{ + /* Set input parameter in PKA RAM */ + PKA_RSACRTExp_Set(hpka, in); + + /* Start the operation */ + return PKA_Process(hpka, PKA_MODE_RSA_CRT_EXP, Timeout); +} + +/** + * @brief RSA CRT exponentiation in non-blocking mode with Interrupt. + * @param hpka PKA handle + * @param in Input information + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_RSACRTExp_IT(PKA_HandleTypeDef *hpka, PKA_RSACRTExpInTypeDef *in) +{ + /* Set input parameter in PKA RAM */ + PKA_RSACRTExp_Set(hpka, in); + + /* Start the operation */ + return PKA_Process_IT(hpka, PKA_MODE_RSA_CRT_EXP); +} + +/** + * @brief Retrieve operation result. + * @param hpka PKA handle + * @param pRes Pointer to memory location to receive the result of the operation + * @retval HAL status + */ +void HAL_PKA_RSACRTExp_GetResult(PKA_HandleTypeDef *hpka, uint8_t *pRes) +{ + uint32_t size; + + /* Move the result to appropriate location (indicated in out parameter) */ + size = (hpka->Instance->RAM[PKA_RSA_CRT_EXP_IN_MOD_NB_BITS] + 7UL) / 8UL; + + PKA_Memcpy_u32_to_u8(pRes, &hpka->Instance->RAM[PKA_RSA_CRT_EXP_OUT_RESULT], size); +} + +/** + * @brief Point on elliptic curve check in blocking mode. + * @param hpka PKA handle + * @param in Input information + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_PointCheck(PKA_HandleTypeDef *hpka, PKA_PointCheckInTypeDef *in, uint32_t Timeout) +{ + /* Set input parameter in PKA RAM */ + PKA_PointCheck_Set(hpka, in); + + /* Start the operation */ + return PKA_Process(hpka, PKA_MODE_POINT_CHECK, Timeout); +} + +/** + * @brief Point on elliptic curve check in non-blocking mode with Interrupt. + * @param hpka PKA handle + * @param in Input information + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_PointCheck_IT(PKA_HandleTypeDef *hpka, PKA_PointCheckInTypeDef *in) +{ + /* Set input parameter in PKA RAM */ + PKA_PointCheck_Set(hpka, in); + + /* Start the operation */ + return PKA_Process_IT(hpka, PKA_MODE_POINT_CHECK); +} + +/** + * @brief Return the result of the point check operation. + * @param hpka PKA handle + * @retval 1 if point is on curve, 0 in other case + */ +uint32_t HAL_PKA_PointCheck_IsOnCurve(PKA_HandleTypeDef const *const hpka) +{ +#define PKA_POINT_IS_ON_CURVE 0xD60DUL + /* Invert the value of the PKA RAM containing the result of the operation */ + return (hpka->Instance->RAM[PKA_POINT_CHECK_OUT_ERROR] == PKA_POINT_IS_ON_CURVE) ? 1UL : 0UL; +} + +/** + * @brief ECC scalar multiplication in blocking mode. + * @param hpka PKA handle + * @param in Input information + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_ECCMul(PKA_HandleTypeDef *hpka, PKA_ECCMulInTypeDef *in, uint32_t Timeout) +{ + /* Set input parameter in PKA RAM */ + PKA_ECCMul_Set(hpka, in); + + modulussize = in->modulusSize; + + /* Start the operation */ + return PKA_Process(hpka, PKA_MODE_ECC_MUL, Timeout); +} + +/** + * @brief ECC scalar multiplication in non-blocking mode with Interrupt. + * @param hpka PKA handle + * @param in Input information + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_ECCMul_IT(PKA_HandleTypeDef *hpka, PKA_ECCMulInTypeDef *in) +{ + /* Set input parameter in PKA RAM */ + PKA_ECCMul_Set(hpka, in); + + modulussize = in->modulusSize; + + /* Start the operation */ + return PKA_Process_IT(hpka, PKA_MODE_ECC_MUL); +} +/** + * @brief Retrieve operation result. + * @param hpka PKA handle + * @param out Output information + * @retval HAL status + */ +void HAL_PKA_ECCMul_GetResult(PKA_HandleTypeDef *hpka, PKA_ECCMulOutTypeDef *out) +{ + uint32_t size; + + /* Get output result size */ + size = modulussize; + + /* If a destination buffer is provided */ + if (out != NULL) + { + /* Move the result to appropriate location (indicated in out parameter) */ + PKA_Memcpy_u32_to_u8(out->ptX, &hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_OUT_RESULT_X], size); + PKA_Memcpy_u32_to_u8(out->ptY, &hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_OUT_RESULT_Y], size); + } +} + +/** + * @brief Arithmetic addition in blocking mode. + * @param hpka PKA handle + * @param in Input information + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_Add(PKA_HandleTypeDef *hpka, PKA_AddInTypeDef *in, uint32_t Timeout) +{ + /* Set input parameter in PKA RAM */ + PKA_ARI_Set(hpka, in->size, in->pOp1, in->pOp2, NULL); + + /* Start the operation */ + return PKA_Process(hpka, PKA_MODE_ARITHMETIC_ADD, Timeout); +} + +/** + * @brief Arithmetic addition in non-blocking mode with Interrupt. + * @param hpka PKA handle + * @param in Input information + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_Add_IT(PKA_HandleTypeDef *hpka, PKA_AddInTypeDef *in) +{ + /* Set input parameter in PKA RAM */ + PKA_ARI_Set(hpka, in->size, in->pOp1, in->pOp2, NULL); + + /* Start the operation */ + return PKA_Process_IT(hpka, PKA_MODE_ARITHMETIC_ADD); +} + +/** + * @brief Arithmetic subtraction in blocking mode. + * @param hpka PKA handle + * @param in Input information + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_Sub(PKA_HandleTypeDef *hpka, PKA_SubInTypeDef *in, uint32_t Timeout) +{ + /* Set input parameter in PKA RAM */ + PKA_ARI_Set(hpka, in->size, in->pOp1, in->pOp2, NULL); + + /* Start the operation */ + return PKA_Process(hpka, PKA_MODE_ARITHMETIC_SUB, Timeout); +} + +/** + * @brief Arithmetic subtraction in non-blocking mode with Interrupt. + * @param hpka PKA handle + * @param in Input information + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_Sub_IT(PKA_HandleTypeDef *hpka, PKA_SubInTypeDef *in) +{ + /* Set input parameter in PKA RAM */ + PKA_ARI_Set(hpka, in->size, in->pOp1, in->pOp2, NULL); + + /* Start the operation */ + return PKA_Process_IT(hpka, PKA_MODE_ARITHMETIC_SUB); +} + +/** + * @brief Arithmetic multiplication in blocking mode. + * @param hpka PKA handle + * @param in Input information + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_Mul(PKA_HandleTypeDef *hpka, PKA_MulInTypeDef *in, uint32_t Timeout) +{ + /* Set input parameter in PKA RAM */ + PKA_ARI_Set(hpka, in->size, in->pOp1, in->pOp2, NULL); + + /* Start the operation */ + return PKA_Process(hpka, PKA_MODE_ARITHMETIC_MUL, Timeout); +} + +/** + * @brief Arithmetic multiplication in non-blocking mode with Interrupt. + * @param hpka PKA handle + * @param in Input information + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_Mul_IT(PKA_HandleTypeDef *hpka, PKA_MulInTypeDef *in) +{ + /* Set input parameter in PKA RAM */ + PKA_ARI_Set(hpka, in->size, in->pOp1, in->pOp2, NULL); + + /* Start the operation */ + return PKA_Process_IT(hpka, PKA_MODE_ARITHMETIC_MUL); +} + +/** + * @brief Comparison in blocking mode. + * @param hpka PKA handle + * @param in Input information + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_Cmp(PKA_HandleTypeDef *hpka, PKA_CmpInTypeDef *in, uint32_t Timeout) +{ + /* Set input parameter in PKA RAM */ + PKA_ARI_Set(hpka, in->size, in->pOp1, in->pOp2, NULL); + + /* Start the operation */ + return PKA_Process(hpka, PKA_MODE_COMPARISON, Timeout); +} + +/** + * @brief Comparison in non-blocking mode with Interrupt. + * @param hpka PKA handle + * @param in Input information + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_Cmp_IT(PKA_HandleTypeDef *hpka, PKA_CmpInTypeDef *in) +{ + /* Set input parameter in PKA RAM */ + PKA_ARI_Set(hpka, in->size, in->pOp1, in->pOp2, NULL); + + /* Start the operation */ + return PKA_Process_IT(hpka, PKA_MODE_COMPARISON); +} + +/** + * @brief Modular addition in blocking mode. + * @param hpka PKA handle + * @param in Input information + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_ModAdd(PKA_HandleTypeDef *hpka, PKA_ModAddInTypeDef *in, uint32_t Timeout) +{ + /* Set input parameter in PKA RAM */ + PKA_ARI_Set(hpka, in->size, in->pOp1, in->pOp2, in->pOp3); + + /* Start the operation */ + return PKA_Process(hpka, PKA_MODE_MODULAR_ADD, Timeout); +} + +/** + * @brief Modular addition in non-blocking mode with Interrupt. + * @param hpka PKA handle + * @param in Input information + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_ModAdd_IT(PKA_HandleTypeDef *hpka, PKA_ModAddInTypeDef *in) +{ + /* Set input parameter in PKA RAM */ + PKA_ARI_Set(hpka, in->size, in->pOp1, in->pOp2, in->pOp3); + + /* Start the operation */ + return PKA_Process_IT(hpka, PKA_MODE_MODULAR_ADD); +} + +/** + * @brief Modular inversion in blocking mode. + * @param hpka PKA handle + * @param in Input information + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_ModInv(PKA_HandleTypeDef *hpka, PKA_ModInvInTypeDef *in, uint32_t Timeout) +{ + /* Set input parameter in PKA RAM */ + PKA_ModInv_Set(hpka, in); + + /* Start the operation */ + return PKA_Process(hpka, PKA_MODE_MODULAR_INV, Timeout); +} + +/** + * @brief Modular inversion in non-blocking mode with Interrupt. + * @param hpka PKA handle + * @param in Input information + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_ModInv_IT(PKA_HandleTypeDef *hpka, PKA_ModInvInTypeDef *in) +{ + /* Set input parameter in PKA RAM */ + PKA_ModInv_Set(hpka, in); + + /* Start the operation */ + return PKA_Process_IT(hpka, PKA_MODE_MODULAR_INV); +} + +/** + * @brief Modular subtraction in blocking mode. + * @param hpka PKA handle + * @param in Input information + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_ModSub(PKA_HandleTypeDef *hpka, PKA_ModSubInTypeDef *in, uint32_t Timeout) +{ + /* Set input parameter in PKA RAM */ + PKA_ARI_Set(hpka, in->size, in->pOp1, in->pOp2, in->pOp3); + + /* Start the operation */ + return PKA_Process(hpka, PKA_MODE_MODULAR_SUB, Timeout); +} + +/** + * @brief Modular subtraction in non-blocking mode with Interrupt. + * @param hpka PKA handle + * @param in Input information + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_ModSub_IT(PKA_HandleTypeDef *hpka, PKA_ModSubInTypeDef *in) +{ + /* Set input parameter in PKA RAM */ + PKA_ARI_Set(hpka, in->size, in->pOp1, in->pOp2, in->pOp3); + + /* Start the operation */ + return PKA_Process_IT(hpka, PKA_MODE_MODULAR_SUB); +} + +/** + * @brief Modular reduction in blocking mode. + * @param hpka PKA handle + * @param in Input information + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_ModRed(PKA_HandleTypeDef *hpka, PKA_ModRedInTypeDef *in, uint32_t Timeout) +{ + /* Set input parameter in PKA RAM */ + PKA_ModRed_Set(hpka, in); + + /* Start the operation */ + return PKA_Process(hpka, PKA_MODE_MODULAR_RED, Timeout); +} + +/** + * @brief Modular reduction in non-blocking mode with Interrupt. + * @param hpka PKA handle + * @param in Input information + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_ModRed_IT(PKA_HandleTypeDef *hpka, PKA_ModRedInTypeDef *in) +{ + /* Set input parameter in PKA RAM */ + PKA_ModRed_Set(hpka, in); + + /* Start the operation */ + return PKA_Process_IT(hpka, PKA_MODE_MODULAR_RED); +} + +/** + * @brief Montgomery multiplication in blocking mode. + * @param hpka PKA handle + * @param in Input information + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_MontgomeryMul(PKA_HandleTypeDef *hpka, PKA_MontgomeryMulInTypeDef *in, uint32_t Timeout) +{ + /* Set input parameter in PKA RAM */ + PKA_ARI_Set(hpka, in->size, in->pOp1, in->pOp2, in->pOp3); + + /* Start the operation */ + return PKA_Process(hpka, PKA_MODE_MONTGOMERY_MUL, Timeout); +} + +/** + * @brief Montgomery multiplication in non-blocking mode with Interrupt. + * @param hpka PKA handle + * @param in Input information + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_MontgomeryMul_IT(PKA_HandleTypeDef *hpka, PKA_MontgomeryMulInTypeDef *in) +{ + /* Set input parameter in PKA RAM */ + PKA_ARI_Set(hpka, in->size, in->pOp1, in->pOp2, in->pOp3); + + /* Start the operation */ + return PKA_Process_IT(hpka, PKA_MODE_MONTGOMERY_MUL); +} + +/** + * @brief Retrieve operation result. + * @param hpka PKA handle + * @param pRes Pointer to memory location to receive the result of the operation + */ +void HAL_PKA_Arithmetic_GetResult(PKA_HandleTypeDef *hpka, uint32_t *pRes) +{ + uint32_t mode = (hpka->Instance->CR & PKA_CR_MODE_Msk) >> PKA_CR_MODE_Pos; + uint32_t size = 0; + + /* Move the result to appropriate location (indicated in pRes parameter) */ + switch (mode) + { + case PKA_MODE_MONTGOMERY_PARAM: + case PKA_MODE_ARITHMETIC_SUB: + case PKA_MODE_MODULAR_ADD: + case PKA_MODE_MODULAR_RED: + case PKA_MODE_MODULAR_INV: + case PKA_MODE_MONTGOMERY_MUL: + size = hpka->Instance->RAM[2] / 32UL; + break; + case PKA_MODE_ARITHMETIC_ADD: + case PKA_MODE_MODULAR_SUB: + size = hpka->Instance->RAM[PKA_ARITHMETIC_ALL_OPS_NB_BITS] / 32UL; + + /* Manage the overflow of the addition */ + if (hpka->Instance->RAM[PKA_ARITHMETIC_ALL_OPS_OUT_RESULT + size] != 0UL) + { + size += 1UL; + } + + break; + case PKA_MODE_COMPARISON: + size = 1; + break; + case PKA_MODE_ARITHMETIC_MUL: + size = hpka->Instance->RAM[PKA_ARITHMETIC_MUL_NB_BITS] / 32UL * 2UL; + break; + default: + break; + } + + if (pRes != NULL) + { + switch (mode) + { + case PKA_MODE_ARITHMETIC_SUB: + case PKA_MODE_MODULAR_ADD: + case PKA_MODE_MODULAR_RED: + case PKA_MODE_MODULAR_INV: + case PKA_MODE_MODULAR_SUB: + case PKA_MODE_MONTGOMERY_MUL: + case PKA_MODE_ARITHMETIC_ADD: + case PKA_MODE_COMPARISON: + case PKA_MODE_ARITHMETIC_MUL: + PKA_Memcpy_u32_to_u32(pRes, &hpka->Instance->RAM[PKA_ARITHMETIC_ALL_OPS_OUT_RESULT], size); + break; + default: + break; + } + } +} + +/** + * @brief Montgomery parameter computation in blocking mode. + * @param hpka PKA handle + * @param in Input information + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_MontgomeryParam(PKA_HandleTypeDef *hpka, PKA_MontgomeryParamInTypeDef *in, uint32_t Timeout) +{ + /* Set input parameter in PKA RAM */ + PKA_MontgomeryParam_Set(hpka, in->size, in->pOp1); + + /* Start the operation */ + return PKA_Process(hpka, PKA_MODE_MONTGOMERY_PARAM, Timeout); +} + +/** + * @brief Montgomery parameter computation in non-blocking mode with Interrupt. + * @param hpka PKA handle + * @param in Input information + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_MontgomeryParam_IT(PKA_HandleTypeDef *hpka, PKA_MontgomeryParamInTypeDef *in) +{ + /* Set input parameter in PKA RAM */ + PKA_MontgomeryParam_Set(hpka, in->size, in->pOp1); + + /* Start the operation */ + return PKA_Process_IT(hpka, PKA_MODE_MONTGOMERY_PARAM); +} + +/** + * @brief ECC double base ladder in blocking mode. + * @param hpka PKA handle + * @param in Input information + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_ECCDoubleBaseLadder(PKA_HandleTypeDef *hpka, PKA_ECCDoubleBaseLadderInTypeDef *in, + uint32_t Timeout) +{ + /* Set input parameter in PKA RAM */ + PKA_ECCDoubleBaseLadder_Set(hpka, in); + + return PKA_Process(hpka, PKA_MODE_DOUBLE_BASE_LADDER, Timeout); +} + +/** + * @brief ECC double base ladder in non-blocking mode with Interrupt. + * @param hpka PKA handle + * @param in Input information + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_ECCDoubleBaseLadder_IT(PKA_HandleTypeDef *hpka, PKA_ECCDoubleBaseLadderInTypeDef *in) +{ + /* Set input parameter in PKA RAM */ + PKA_ECCDoubleBaseLadder_Set(hpka, in); + + return PKA_Process_IT(hpka, PKA_MODE_DOUBLE_BASE_LADDER); +} + +/** + * @brief ECC projective to affine in blocking mode. + * @param hpka PKA handle + * @param in Input information + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_ECCProjective2Affine(PKA_HandleTypeDef *hpka, PKA_ECCProjective2AffineInTypeDef *in, + uint32_t Timeout) +{ + /* Set input parameter in PKA RAM */ + PKA_ECCProjective2Affine_Set(hpka, in); + + return PKA_Process(hpka, PKA_MODE_ECC_PROJECTIVE_AFF, Timeout); +} + +/** + * @brief ECC projective to affine in non-blocking mode with Interrupt. + * @param hpka PKA handle + * @param in Input information + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_ECCProjective2Affine_IT(PKA_HandleTypeDef *hpka, PKA_ECCProjective2AffineInTypeDef *in) +{ + /* Set input parameter in PKA RAM */ + PKA_ECCProjective2Affine_Set(hpka, in); + + return PKA_Process_IT(hpka, PKA_MODE_ECC_PROJECTIVE_AFF); +} + +/** + * @brief ECC complete addition in blocking mode. + * @param hpka PKA handle + * @param in Input information + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_ECCCompleteAddition(PKA_HandleTypeDef *hpka, PKA_ECCCompleteAdditionInTypeDef *in, + uint32_t Timeout) +{ + /* Set input parameter in PKA RAM */ + PKA_ECCCompleteAddition_Set(hpka, in); + + return PKA_Process(hpka, PKA_MODE_ECC_COMPLETE_ADD, Timeout); +} + +/** + * @brief ECC complete addition in non-blocking mode with Interrupt. + * @param hpka PKA handle + * @param in Input information + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_ECCCompleteAddition_IT(PKA_HandleTypeDef *hpka, PKA_ECCCompleteAdditionInTypeDef *in) +{ + /* Set input parameter in PKA RAM */ + PKA_ECCCompleteAddition_Set(hpka, in); + + return PKA_Process_IT(hpka, PKA_MODE_ECC_COMPLETE_ADD); +} + +/** + * @brief Retrieve operation result. + * @param hpka PKA handle + * @param pRes pointer to buffer where the result will be copied + * @retval HAL status + */ +void HAL_PKA_MontgomeryParam_GetResult(PKA_HandleTypeDef *hpka, uint32_t *pRes) +{ + uint32_t size; + + /* Retrieve the size of the buffer from the PKA RAM */ + size = (hpka->Instance->RAM[PKA_MONTGOMERY_PARAM_IN_MOD_NB_BITS] + 31UL) / 32UL; + + /* Move the result to appropriate location (indicated in out parameter) */ + PKA_Memcpy_u32_to_u32(pRes, &hpka->Instance->RAM[PKA_MONTGOMERY_PARAM_OUT_PARAMETER], size); +} + +/** + * @brief Abort any ongoing operation. + * @param hpka PKA handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PKA_Abort(PKA_HandleTypeDef *hpka) +{ + HAL_StatusTypeDef err = HAL_OK; + + /* Clear EN bit */ + /* This abort any operation in progress (PKA RAM content is not guaranteed in this case) */ + CLEAR_BIT(hpka->Instance->CR, PKA_CR_EN); + SET_BIT(hpka->Instance->CR, PKA_CR_EN); + + /* Reset any pending flag */ + SET_BIT(hpka->Instance->CLRFR, PKA_CLRFR_PROCENDFC | PKA_CLRFR_RAMERRFC | PKA_CLRFR_ADDRERRFC | PKA_CLRFR_OPERRFC); + + /* Reset the error code */ + hpka->ErrorCode = HAL_PKA_ERROR_NONE; + + /* Reset the state */ + hpka->State = HAL_PKA_STATE_READY; + + return err; +} + +/** + * @brief Reset the PKA RAM. + * @param hpka PKA handle + * @retval None + */ +void HAL_PKA_RAMReset(PKA_HandleTypeDef *hpka) +{ + uint32_t index; + + /* For each element in the PKA RAM */ + for (index = 0; index < PKA_RAM_SIZE; index++) + { + /* Clear the content */ + hpka->Instance->RAM[index] = 0UL; + } +} + +/** + * @brief This function handles PKA event interrupt request. + * @param hpka PKA handle + * @retval None + */ +void HAL_PKA_IRQHandler(PKA_HandleTypeDef *hpka) +{ + uint32_t mode = PKA_GetMode(hpka); + FlagStatus addErrFlag = __HAL_PKA_GET_FLAG(hpka, PKA_FLAG_ADDRERR); + FlagStatus ramErrFlag = __HAL_PKA_GET_FLAG(hpka, PKA_FLAG_RAMERR); + FlagStatus procEndFlag = __HAL_PKA_GET_FLAG(hpka, PKA_FLAG_PROCEND); + FlagStatus operErrFlag = __HAL_PKA_GET_FLAG(hpka, PKA_FLAG_OPERR); + + /* Address error interrupt occurred */ + if ((__HAL_PKA_GET_IT_SOURCE(hpka, PKA_IT_ADDRERR) == SET) && (addErrFlag == SET)) + { + hpka->ErrorCode |= HAL_PKA_ERROR_ADDRERR; + + /* Clear ADDRERR flag */ + __HAL_PKA_CLEAR_FLAG(hpka, PKA_FLAG_ADDRERR); + } + + /* RAM access error interrupt occurred */ + if ((__HAL_PKA_GET_IT_SOURCE(hpka, PKA_IT_RAMERR) == SET) && (ramErrFlag == SET)) + { + hpka->ErrorCode |= HAL_PKA_ERROR_RAMERR; + + /* Clear RAMERR flag */ + __HAL_PKA_CLEAR_FLAG(hpka, PKA_FLAG_RAMERR); + } + + /* OPERATION access error interrupt occurred */ + if ((__HAL_PKA_GET_IT_SOURCE(hpka, PKA_FLAG_OPERR) == SET) && (operErrFlag == SET)) + { + hpka->ErrorCode |= HAL_PKA_ERROR_OPERATION; + + /* Clear OPERR flag */ + __HAL_PKA_CLEAR_FLAG(hpka, PKA_FLAG_OPERR); + } + + /* Check the operation success in case of ECDSA signature */ + switch (mode) + { + case PKA_MODE_ECDSA_SIGNATURE : + /* If error output result is different from no error, operation need to be repeated */ + if (hpka->Instance->RAM[PKA_ECDSA_SIGN_OUT_ERROR] != PKA_NO_ERROR) + { + hpka->ErrorCode |= HAL_PKA_ERROR_OPERATION; + } + break; + + case PKA_MODE_DOUBLE_BASE_LADDER : + /* If error output result is different from no error, operation need to be repeated */ + if (hpka->Instance->RAM[PKA_ECC_DOUBLE_LADDER_OUT_ERROR] != PKA_NO_ERROR) + { + hpka->ErrorCode |= HAL_PKA_ERROR_OPERATION; + } + break; + + case PKA_MODE_ECC_PROJECTIVE_AFF : + /* If error output result is different from no error, operation need to be repeated */ + if (hpka->Instance->RAM[PKA_ECC_PROJECTIVE_AFF_OUT_ERROR] != PKA_NO_ERROR) + { + hpka->ErrorCode |= HAL_PKA_ERROR_OPERATION; + } + break; + + case PKA_MODE_ECC_MUL : + /* If error output result is different from no error, operation need to be repeated */ + if (hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_OUT_ERROR] != PKA_NO_ERROR) + { + hpka->ErrorCode |= HAL_PKA_ERROR_OPERATION; + } + break; + + case PKA_MODE_MODULAR_EXP_PROTECT : + /* If error output result is different from no error, operation need to be repeated */ + if (hpka->Instance->RAM[PKA_MODULAR_EXP_OUT_ERROR] != PKA_NO_ERROR) + { + hpka->ErrorCode |= HAL_PKA_ERROR_OPERATION; + } + break; + default : + break; + } + /* Trigger the error callback if an error is present */ + if (hpka->ErrorCode != HAL_PKA_ERROR_NONE) + { +#if (USE_HAL_PKA_REGISTER_CALLBACKS == 1) + hpka->ErrorCallback(hpka); +#else + HAL_PKA_ErrorCallback(hpka); +#endif /* USE_HAL_PKA_REGISTER_CALLBACKS */ + } + + /* End Of Operation interrupt occurred */ + if ((__HAL_PKA_GET_IT_SOURCE(hpka, PKA_IT_PROCEND) == SET) && (procEndFlag == SET)) + { + /* Clear PROCEND flag */ + __HAL_PKA_CLEAR_FLAG(hpka, PKA_FLAG_PROCEND); + + /* Set the state to ready */ + hpka->State = HAL_PKA_STATE_READY; + +#if (USE_HAL_PKA_REGISTER_CALLBACKS == 1) + hpka->OperationCpltCallback(hpka); +#else + HAL_PKA_OperationCpltCallback(hpka); +#endif /* USE_HAL_PKA_REGISTER_CALLBACKS */ + } +} + +/** + * @brief Process completed callback. + * @param hpka PKA handle + * @retval None + */ +__weak void HAL_PKA_OperationCpltCallback(PKA_HandleTypeDef *hpka) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpka); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PKA_OperationCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Error callback. + * @param hpka PKA handle + * @retval None + */ +__weak void HAL_PKA_ErrorCallback(PKA_HandleTypeDef *hpka) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpka); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PKA_ErrorCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup PKA_Exported_Functions_Group3 Peripheral State and Error functions + * @brief Peripheral State and Error functions + * + @verbatim + =============================================================================== + ##### Peripheral State and Error functions ##### + =============================================================================== + [..] + This subsection permit to get in run-time the status of the peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Return the PKA handle state. + * @param hpka PKA handle + * @retval HAL status + */ +HAL_PKA_StateTypeDef HAL_PKA_GetState(const PKA_HandleTypeDef *hpka) +{ + /* Return PKA handle state */ + return hpka->State; +} + +/** + * @brief Return the PKA error code. + * @param hpka PKA handle + * @retval PKA error code + */ +uint32_t HAL_PKA_GetError(const PKA_HandleTypeDef *hpka) +{ + /* Return PKA handle error code */ + return hpka->ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup PKA_Private_Functions + * @{ + */ + +/** + * @brief Get PKA operating mode. + * @param hpka PKA handle + * @retval Return the current mode + */ +uint32_t PKA_GetMode(const PKA_HandleTypeDef *hpka) +{ + /* return the shifted PKA_CR_MODE value */ + return (uint32_t)(READ_BIT(hpka->Instance->CR, PKA_CR_MODE) >> PKA_CR_MODE_Pos); +} + +/** + * @brief Wait for operation completion or timeout. + * @param hpka PKA handle + * @param Timeout Timeout duration in millisecond. + * @param Tickstart Tick start value + * @retval HAL status + */ +HAL_StatusTypeDef PKA_PollEndOfOperation(const PKA_HandleTypeDef *hpka, uint32_t Timeout, uint32_t Tickstart) +{ + /* Wait for the end of operation or timeout */ + while ((hpka->Instance->SR & PKA_SR_PROCENDF) == 0UL) + { + /* Check if timeout is disabled (set to infinite wait) */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0UL)) + { + return HAL_TIMEOUT; + } + } + } + return HAL_OK; +} + +/** + * @brief Return a hal error code based on PKA error flags. + * @param hpka PKA handle + * @param mode PKA operating mode + * @retval error code + */ +uint32_t PKA_CheckError(const PKA_HandleTypeDef *hpka, uint32_t mode) +{ + uint32_t err = HAL_PKA_ERROR_NONE; + + /* Check RAMERR error */ + if (__HAL_PKA_GET_FLAG(hpka, PKA_FLAG_RAMERR) == SET) + { + err |= HAL_PKA_ERROR_RAMERR; + } + + /* Check ADDRERR error */ + if (__HAL_PKA_GET_FLAG(hpka, PKA_FLAG_ADDRERR) == SET) + { + err |= HAL_PKA_ERROR_ADDRERR; + } + + /* Check OPEERR error */ + if (__HAL_PKA_GET_FLAG(hpka, PKA_FLAG_OPERR) == SET) + { + err |= HAL_PKA_ERROR_OPERATION; + } + + /* Check the operation success in case of ECDSA signature */ + if (mode == PKA_MODE_ECDSA_SIGNATURE) + { +#define EDCSA_SIGN_NOERROR PKA_NO_ERROR + /* If error output result is different from no error, ecsa sign operation need to be repeated */ + if (hpka->Instance->RAM[PKA_ECDSA_SIGN_OUT_ERROR] != EDCSA_SIGN_NOERROR) + { + err |= HAL_PKA_ERROR_OPERATION; + } + } + + /* Check the operation success in case of ECC double base ladder*/ + if (mode == PKA_MODE_DOUBLE_BASE_LADDER) + { + /* If error output result is different from no error, PKA operation need to be repeated */ + if (hpka->Instance->RAM[PKA_ECC_DOUBLE_LADDER_OUT_ERROR] != PKA_NO_ERROR) + { + err |= HAL_PKA_ERROR_OPERATION; + } + } + + /* Check the operation success in case of ECC projective to affine*/ + if (mode == PKA_MODE_ECC_PROJECTIVE_AFF) + { + /* If error output result is different from no error, PKA operation need to be repeated */ + if (hpka->Instance->RAM[PKA_ECC_PROJECTIVE_AFF_OUT_ERROR] != PKA_NO_ERROR) + { + err |= HAL_PKA_ERROR_OPERATION; + } + } + + /* Check the operation success in case of ECC Fp scalar multiplication*/ + if (mode == PKA_MODE_ECC_MUL) + { + /* If error output result is different from no error, PKA operation need to be repeated */ + if (hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_OUT_ERROR] != PKA_NO_ERROR) + { + err |= HAL_PKA_ERROR_OPERATION; + } + } + + /* Check the operation success in case of protected modular exponentiation*/ + if (mode == PKA_MODE_MODULAR_EXP_PROTECT) + { + /* If error output result is different from no error, PKA operation need to be repeated */ + if (hpka->Instance->RAM[PKA_MODULAR_EXP_OUT_ERROR] != PKA_NO_ERROR) + { + err |= HAL_PKA_ERROR_OPERATION; + } + } + + return err; +} + +/** + * @brief Get number of bits inside an array of u8. + * @param byteNumber Number of u8 inside the array + */ +uint32_t PKA_GetBitSize_u8(uint32_t byteNumber) +{ + /* Convert from number of uint8_t in an array to the associated number of bits in this array */ + return byteNumber * 8UL; +} + +/** + * @brief Get optimal number of bits inside an array of u8. + * @param byteNumber Number of u8 inside the array + * @param msb Most significant uint8_t of the array + */ +uint32_t PKA_GetOptBitSize_u8(uint32_t byteNumber, uint8_t msb) +{ + uint32_t position; + + position = 32UL - __CLZ(msb); + + return (((byteNumber - 1UL) * 8UL) + position); +} + +/** + * @brief Get number of bits inside an array of u32. + * @param wordNumber Number of u32 inside the array + */ +uint32_t PKA_GetBitSize_u32(uint32_t wordNumber) +{ + /* Convert from number of uint32_t in an array to the associated number of bits in this array */ + return wordNumber * 32UL; +} + +/** + * @brief Get number of uint8_t element in an array of bitSize bits. + * @param bitSize Number of bits in an array + */ +uint32_t PKA_GetArraySize_u8(uint32_t bitSize) +{ + /* Manage the non aligned on uint8_t bitsize: */ + /* 512 bits requires 64 uint8_t */ + /* 521 bits requires 66 uint8_t */ + return ((bitSize + 7UL) / 8UL); +} + +/** + * @brief Copy uint32_t array to uint8_t array to fit PKA number representation. + * @param dst Pointer to destination + * @param src Pointer to source + * @param n Number of uint8_t to copy + * @retval dst + */ +void PKA_Memcpy_u32_to_u8(uint8_t dst[], __IO const uint32_t src[], size_t n) +{ + if (dst != NULL) + { + if (src != NULL) + { + uint32_t index_uint32_t = 0UL; /* This index is used outside of the loop */ + + for (; index_uint32_t < (n / 4UL); index_uint32_t++) + { + /* Avoid casting from uint8_t* to uint32_t* by copying 4 uint8_t in a row */ + /* Apply __REV equivalent */ + uint32_t index_uint8_t = n - 4UL - (index_uint32_t * 4UL); + dst[index_uint8_t + 3UL] = (uint8_t)((src[index_uint32_t] & 0x000000FFU)); + dst[index_uint8_t + 2UL] = (uint8_t)((src[index_uint32_t] & 0x0000FF00U) >> 8UL); + dst[index_uint8_t + 1UL] = (uint8_t)((src[index_uint32_t] & 0x00FF0000U) >> 16UL); + dst[index_uint8_t + 0UL] = (uint8_t)((src[index_uint32_t] & 0xFF000000U) >> 24UL); + } + + /* Manage the buffers not aligned on uint32_t */ + if ((n % 4UL) == 1UL) + { + dst[0UL] = (uint8_t)((src[index_uint32_t] & 0x000000FFU)); + } + else if ((n % 4UL) == 2UL) + { + dst[1UL] = (uint8_t)((src[index_uint32_t] & 0x000000FFU)); + dst[0UL] = (uint8_t)((src[index_uint32_t] & 0x0000FF00U) >> 8UL); + } + else if ((n % 4UL) == 3UL) + { + dst[2UL] = (uint8_t)((src[index_uint32_t] & 0x000000FFU)); + dst[1UL] = (uint8_t)((src[index_uint32_t] & 0x0000FF00U) >> 8UL); + dst[0UL] = (uint8_t)((src[index_uint32_t] & 0x00FF0000U) >> 16UL); + } + else + { + /* The last element is already handle in the loop */ + } + } + } +} + +/** + * @brief Copy uint8_t array to uint32_t array to fit PKA number representation. + * @param dst Pointer to destination + * @param src Pointer to source + * @param n Number of uint8_t to copy (must be multiple of 4) + * @retval dst + */ +void PKA_Memcpy_u8_to_u32(__IO uint32_t dst[], const uint8_t src[], size_t n) +{ + if (dst != NULL) + { + if (src != NULL) + { + uint32_t index = 0UL; /* This index is used outside of the loop */ + + for (; index < (n / 4UL); index++) + { + /* Apply the equivalent of __REV from uint8_t to uint32_t */ + dst[index] = ((uint32_t)src[(n - (index * 4UL) - 1UL)]) \ + | ((uint32_t)src[(n - (index * 4UL) - 2UL)] << 8UL) \ + | ((uint32_t)src[(n - (index * 4UL) - 3UL)] << 16UL) \ + | ((uint32_t)src[(n - (index * 4UL) - 4UL)] << 24UL); + } + + /* Manage the buffers not aligned on uint32_t */ + if ((n % 4UL) == 1UL) + { + dst[index] = (uint32_t)src[(n - (index * 4UL) - 1UL)]; + } + else if ((n % 4UL) == 2UL) + { + dst[index] = ((uint32_t)src[(n - (index * 4UL) - 1UL)]) \ + | ((uint32_t)src[(n - (index * 4UL) - 2UL)] << 8UL); + } + else if ((n % 4UL) == 3UL) + { + dst[index] = ((uint32_t)src[(n - (index * 4UL) - 1UL)]) \ + | ((uint32_t)src[(n - (index * 4UL) - 2UL)] << 8UL) \ + | ((uint32_t)src[(n - (index * 4UL) - 3UL)] << 16UL); + } + else + { + /* The last element is already handle in the loop */ + } + } + } +} + +/** + * @brief Copy uint32_t array to uint32_t array. + * @param dst Pointer to destination + * @param src Pointer to source + * @param n Number of u32 to be handled + * @retval dst + */ +void PKA_Memcpy_u32_to_u32(__IO uint32_t dst[], __IO const uint32_t src[], size_t n) +{ + /* If a destination buffer is provided */ + if (dst != NULL) + { + /* If a source buffer is provided */ + if (src != NULL) + { + /* For each element in the array */ + for (uint32_t index = 0UL; index < n; index++) + { + /* Copy the content */ + dst[index] = src[index]; + } + } + } +} + +/** + * @brief Generic function to start a PKA operation in blocking mode. + * @param hpka PKA handle + * @param mode PKA operation + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef PKA_Process(PKA_HandleTypeDef *hpka, uint32_t mode, uint32_t Timeout) +{ + HAL_StatusTypeDef err = HAL_OK; + uint32_t tickstart; + + if (hpka->State == HAL_PKA_STATE_READY) + { + /* Set the state to busy */ + hpka->State = HAL_PKA_STATE_BUSY; + + /* Clear any pending error */ + hpka->ErrorCode = HAL_PKA_ERROR_NONE; + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + /* Set the mode and deactivate the interrupts */ + MODIFY_REG(hpka->Instance->CR, PKA_CR_MODE | PKA_CR_PROCENDIE | PKA_CR_RAMERRIE | PKA_CR_ADDRERRIE | PKA_CR_OPERRIE, + mode << PKA_CR_MODE_Pos); + + /* Start the computation */ + hpka->Instance->CR |= PKA_CR_START; + + /* Wait for the end of operation or timeout */ + if (PKA_PollEndOfOperation(hpka, Timeout, tickstart) != HAL_OK) + { + /* Abort any ongoing operation */ + CLEAR_BIT(hpka->Instance->CR, PKA_CR_EN); + + hpka->ErrorCode |= HAL_PKA_ERROR_TIMEOUT; + + /* Make ready for the next operation */ + SET_BIT(hpka->Instance->CR, PKA_CR_EN); + } + + /* Check error */ + hpka->ErrorCode |= PKA_CheckError(hpka, mode); + + /* Clear all flags */ + hpka->Instance->CLRFR |= (PKA_CLRFR_PROCENDFC | PKA_CLRFR_RAMERRFC | PKA_CLRFR_ADDRERRFC | PKA_CLRFR_OPERRFC); + + /* Set the state to ready */ + hpka->State = HAL_PKA_STATE_READY; + + /* Manage the result based on encountered errors */ + if (hpka->ErrorCode != HAL_PKA_ERROR_NONE) + { + err = HAL_ERROR; + } + } + else + { + err = HAL_ERROR; + } + return err; +} + +/** + * @brief Generic function to start a PKA operation in non-blocking mode with Interrupt. + * @param hpka PKA handle + * @param mode PKA operation + * @retval HAL status + */ +HAL_StatusTypeDef PKA_Process_IT(PKA_HandleTypeDef *hpka, uint32_t mode) +{ + HAL_StatusTypeDef err = HAL_OK; + + if (hpka->State == HAL_PKA_STATE_READY) + { + /* Set the state to busy */ + hpka->State = HAL_PKA_STATE_BUSY; + + /* Clear any pending error */ + hpka->ErrorCode = HAL_PKA_ERROR_NONE; + + /* Set the mode and activate interrupts */ + MODIFY_REG(hpka->Instance->CR, PKA_CR_MODE | PKA_CR_PROCENDIE | PKA_CR_RAMERRIE | PKA_CR_ADDRERRIE | PKA_CR_OPERRIE, + (mode << PKA_CR_MODE_Pos) | PKA_CR_PROCENDIE | PKA_CR_RAMERRIE | PKA_CR_ADDRERRIE | PKA_CR_OPERRIE); + + /* Start the computation */ + hpka->Instance->CR |= PKA_CR_START; + } + else + { + err = HAL_ERROR; + } + return err; +} + +/** + * @brief Set input parameters. + * @param hpka PKA handle + * @param in Input information + */ +void PKA_ModExp_Set(PKA_HandleTypeDef *hpka, PKA_ModExpInTypeDef *in) +{ + /* Get the number of bit per operand */ + hpka->Instance->RAM[PKA_MODULAR_EXP_IN_OP_NB_BITS] = PKA_GetBitSize_u8(in->OpSize); + + /* Get the number of bit of the exponent */ + hpka->Instance->RAM[PKA_MODULAR_EXP_IN_EXP_NB_BITS] = PKA_GetBitSize_u8(in->expSize); + + /* Move the input parameters pOp1 to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_MODULAR_EXP_IN_EXPONENT_BASE], in->pOp1, in->OpSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_MODULAR_EXP_IN_EXPONENT_BASE + ((in->OpSize + 3UL) / 4UL)); + + /* Move the exponent to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_MODULAR_EXP_IN_EXPONENT], in->pExp, in->expSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_MODULAR_EXP_IN_EXPONENT + ((in->expSize + 3UL) / 4UL)); + + /* Move the modulus to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_MODULAR_EXP_IN_MODULUS], in->pMod, in->OpSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_MODULAR_EXP_IN_MODULUS + ((in->OpSize + 3UL) / 4UL)); +} + +/** + * @brief Set input parameters. + * @param hpka PKA handle + * @param in Input information + */ +void PKA_ModExpFastMode_Set(PKA_HandleTypeDef *hpka, PKA_ModExpFastModeInTypeDef *in) +{ + /* Get the number of bit per operand */ + hpka->Instance->RAM[PKA_MODULAR_EXP_IN_OP_NB_BITS] = PKA_GetBitSize_u8(in->OpSize); + + /* Get the number of bit of the exponent */ + hpka->Instance->RAM[PKA_MODULAR_EXP_IN_EXP_NB_BITS] = PKA_GetBitSize_u8(in->expSize); + + /* Move the input parameters pOp1 to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_MODULAR_EXP_IN_EXPONENT_BASE], in->pOp1, in->OpSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_MODULAR_EXP_IN_EXPONENT_BASE + (in->OpSize / 4UL)); + + /* Move the exponent to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_MODULAR_EXP_IN_EXPONENT], in->pExp, in->expSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_MODULAR_EXP_IN_EXPONENT + (in->expSize / 4UL)); + + /* Move the modulus to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_MODULAR_EXP_IN_MODULUS], in->pMod, in->OpSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_MODULAR_EXP_IN_MODULUS + (in->OpSize / 4UL)); + + /* Move the Montgomery parameter to PKA RAM */ + PKA_Memcpy_u32_to_u32(&hpka->Instance->RAM[PKA_MODULAR_EXP_IN_MONTGOMERY_PARAM], in->pMontgomeryParam, + in->OpSize / 4UL); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_MODULAR_EXP_IN_MONTGOMERY_PARAM + (in->OpSize / 4UL)); +} + +/** + * @brief Set input parameters. + * @param hpka PKA handle + * @param in Input information + */ +void PKA_ModExpProtectMode_Set(PKA_HandleTypeDef *hpka, PKA_ModExpProtectModeInTypeDef *in) +{ + /* Get the number of bit per operand */ + hpka->Instance->RAM[PKA_MODULAR_EXP_IN_OP_NB_BITS] = PKA_GetBitSize_u8(in->OpSize); + + /* Get the number of bit of the exponent */ + hpka->Instance->RAM[PKA_MODULAR_EXP_IN_EXP_NB_BITS] = PKA_GetBitSize_u8(in->expSize); + + /* Move the input parameters pOp1 to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_MODULAR_EXP_PROTECT_IN_EXPONENT_BASE], in->pOp1, in->OpSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_MODULAR_EXP_PROTECT_IN_EXPONENT_BASE + (in->OpSize / 4UL)); + + /* Move the exponent to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_MODULAR_EXP_PROTECT_IN_EXPONENT], in->pExp, in->expSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_MODULAR_EXP_PROTECT_IN_EXPONENT + (in->expSize / 4UL)); + + /* Move the modulus to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_MODULAR_EXP_PROTECT_IN_MODULUS], in->pMod, in->OpSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_MODULAR_EXP_PROTECT_IN_MODULUS + (in->OpSize / 4UL)); + + /* Move Phi value to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_MODULAR_EXP_PROTECT_IN_PHI], in->pPhi, in->OpSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_MODULAR_EXP_PROTECT_IN_PHI + (in->OpSize / 4UL)); +} + +/** + * @brief Set input parameters. + * @param hpka PKA handle + * @param in Input information + * @note If the modulus size is bigger than the hash size (with a curve SECP521R1 when using a SHA256 hash + * for example)the hash value should be written at the end of the buffer with zeros padding at beginning. + */ +void PKA_ECDSASign_Set(PKA_HandleTypeDef *hpka, PKA_ECDSASignInTypeDef *in) +{ + /* Get the prime order n length */ + hpka->Instance->RAM[PKA_ECDSA_SIGN_IN_ORDER_NB_BITS] = PKA_GetOptBitSize_u8(in->primeOrderSize, *(in->primeOrder)); + + /* Get the modulus p length */ + hpka->Instance->RAM[PKA_ECDSA_SIGN_IN_MOD_NB_BITS] = PKA_GetOptBitSize_u8(in->modulusSize, *(in->modulus)); + + /* Get the coefficient a sign */ + hpka->Instance->RAM[PKA_ECDSA_SIGN_IN_A_COEFF_SIGN] = in->coefSign; + + /* Move the input parameters coefficient |a| to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_SIGN_IN_A_COEFF], in->coef, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_SIGN_IN_A_COEFF + ((in->modulusSize + 3UL) / 4UL)); + + /* Move the input parameters coefficient B to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_SIGN_IN_B_COEFF], in->coefB, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_SIGN_IN_B_COEFF + ((in->modulusSize + 3UL) / 4UL)); + + /* Move the input parameters modulus value p to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_SIGN_IN_MOD_GF], in->modulus, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_SIGN_IN_MOD_GF + ((in->modulusSize + 3UL) / 4UL)); + + /* Move the input parameters integer k to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_SIGN_IN_K], in->integer, in->primeOrderSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_SIGN_IN_K + ((in->primeOrderSize + 3UL) / 4UL)); + + /* Move the input parameters base point G coordinate x to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_SIGN_IN_INITIAL_POINT_X], in->basePointX, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_SIGN_IN_INITIAL_POINT_X + ((in->modulusSize + 3UL) / 4UL)); + + /* Move the input parameters base point G coordinate y to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_SIGN_IN_INITIAL_POINT_Y], in->basePointY, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_SIGN_IN_INITIAL_POINT_Y + ((in->modulusSize + 3UL) / 4UL)); + + /* Move the input parameters hash of message z to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_SIGN_IN_HASH_E], in->hash, in->primeOrderSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_SIGN_IN_HASH_E + ((in->primeOrderSize + 3UL) / 4UL)); + + /* Move the input parameters private key d to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_SIGN_IN_PRIVATE_KEY_D], in->privateKey, in->primeOrderSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_SIGN_IN_PRIVATE_KEY_D + ((in->primeOrderSize + 3UL) / 4UL)); + + /* Move the input parameters prime order n to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_SIGN_IN_ORDER_N], in->primeOrder, in->primeOrderSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_SIGN_IN_ORDER_N + ((in->primeOrderSize + 3UL) / 4UL)); +} + +/** + * @brief Set input parameters. + * @param hpka PKA handle + * @param in Input information + */ +void PKA_ECDSAVerif_Set(PKA_HandleTypeDef *hpka, PKA_ECDSAVerifInTypeDef *in) +{ + /* Get the prime order n length */ + hpka->Instance->RAM[PKA_ECDSA_VERIF_IN_ORDER_NB_BITS] = PKA_GetOptBitSize_u8(in->primeOrderSize, *(in->primeOrder)); + + /* Get the modulus p length */ + hpka->Instance->RAM[PKA_ECDSA_VERIF_IN_MOD_NB_BITS] = PKA_GetOptBitSize_u8(in->modulusSize, *(in->modulus)); + + /* Get the coefficient a sign */ + hpka->Instance->RAM[PKA_ECDSA_VERIF_IN_A_COEFF_SIGN] = in->coefSign; + + /* Move the input parameters coefficient |a| to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_VERIF_IN_A_COEFF], in->coef, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_VERIF_IN_A_COEFF + ((in->modulusSize + 3UL) / 4UL)); + + /* Move the input parameters modulus value p to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_VERIF_IN_MOD_GF], in->modulus, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_VERIF_IN_MOD_GF + ((in->modulusSize + 3UL) / 4UL)); + + /* Move the input parameters base point G coordinate x to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_VERIF_IN_INITIAL_POINT_X], in->basePointX, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_VERIF_IN_INITIAL_POINT_X + ((in->modulusSize + 3UL) / 4UL)); + + /* Move the input parameters base point G coordinate y to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_VERIF_IN_INITIAL_POINT_Y], in->basePointY, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_VERIF_IN_INITIAL_POINT_Y + ((in->modulusSize + 3UL) / 4UL)); + + /* Move the input parameters public-key curve point Q coordinate xQ to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_VERIF_IN_PUBLIC_KEY_POINT_X], in->pPubKeyCurvePtX, + in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_VERIF_IN_PUBLIC_KEY_POINT_X + ((in->modulusSize + 3UL) / 4UL)); + + /* Move the input parameters public-key curve point Q coordinate xQ to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_VERIF_IN_PUBLIC_KEY_POINT_Y], in->pPubKeyCurvePtY, + in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_VERIF_IN_PUBLIC_KEY_POINT_Y + ((in->modulusSize + 3UL) / 4UL)); + + /* Move the input parameters signature part r to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_VERIF_IN_SIGNATURE_R], in->RSign, in->primeOrderSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_VERIF_IN_SIGNATURE_R + ((in->primeOrderSize + 3UL) / 4UL)); + + /* Move the input parameters signature part s to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_VERIF_IN_SIGNATURE_S], in->SSign, in->primeOrderSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_VERIF_IN_SIGNATURE_S + ((in->primeOrderSize + 3UL) / 4UL)); + + /* Move the input parameters hash of message z to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_VERIF_IN_HASH_E], in->hash, in->primeOrderSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_VERIF_IN_HASH_E + ((in->primeOrderSize + 3UL) / 4UL)); + + /* Move the input parameters curve prime order n to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECDSA_VERIF_IN_ORDER_N], in->primeOrder, in->primeOrderSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECDSA_VERIF_IN_ORDER_N + ((in->primeOrderSize + 3UL) / 4UL)); +} + +/** + * @brief Set input parameters. + * @param hpka PKA handle + * @param in Input information + */ +void PKA_RSACRTExp_Set(PKA_HandleTypeDef *hpka, PKA_RSACRTExpInTypeDef *in) +{ + /* Get the operand length M */ + hpka->Instance->RAM[PKA_RSA_CRT_EXP_IN_MOD_NB_BITS] = PKA_GetBitSize_u8(in->size); + + /* Move the input parameters operand dP to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_RSA_CRT_EXP_IN_DP_CRT], in->pOpDp, in->size / 2UL); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_RSA_CRT_EXP_IN_DP_CRT + (in->size / 8UL)); + + /* Move the input parameters operand dQ to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_RSA_CRT_EXP_IN_DQ_CRT], in->pOpDq, in->size / 2UL); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_RSA_CRT_EXP_IN_DQ_CRT + (in->size / 8UL)); + + /* Move the input parameters operand qinv to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_RSA_CRT_EXP_IN_QINV_CRT], in->pOpQinv, in->size / 2UL); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_RSA_CRT_EXP_IN_QINV_CRT + (in->size / 8UL)); + + /* Move the input parameters prime p to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_RSA_CRT_EXP_IN_PRIME_P], in->pPrimeP, in->size / 2UL); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_RSA_CRT_EXP_IN_PRIME_P + (in->size / 8UL)); + + /* Move the input parameters prime q to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_RSA_CRT_EXP_IN_PRIME_Q], in->pPrimeQ, in->size / 2UL); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_RSA_CRT_EXP_IN_PRIME_Q + (in->size / 8UL)); + + /* Move the input parameters operand A to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_RSA_CRT_EXP_IN_EXPONENT_BASE], in->popA, in->size); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_RSA_CRT_EXP_IN_EXPONENT_BASE + (in->size / 4UL)); +} + +/** + * @brief Set input parameters. + * @param hpka PKA handle + * @param in Input information + */ +void PKA_PointCheck_Set(PKA_HandleTypeDef *hpka, PKA_PointCheckInTypeDef *in) +{ + /* Get the modulus length */ + hpka->Instance->RAM[PKA_POINT_CHECK_IN_MOD_NB_BITS] = PKA_GetOptBitSize_u8(in->modulusSize, *(in->modulus)); + + /* Get the coefficient a sign */ + hpka->Instance->RAM[PKA_POINT_CHECK_IN_A_COEFF_SIGN] = in->coefSign; + + /* Move the input parameters coefficient |a| to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_POINT_CHECK_IN_A_COEFF], in->coefA, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_POINT_CHECK_IN_A_COEFF + ((in->modulusSize + 3UL) / 4UL)); + + /* Move the input parameters coefficient b to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_POINT_CHECK_IN_B_COEFF], in->coefB, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_POINT_CHECK_IN_B_COEFF + ((in->modulusSize + 3UL) / 4UL)); + + /* Move the input parameters modulus value p to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_POINT_CHECK_IN_MOD_GF], in->modulus, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_POINT_CHECK_IN_MOD_GF + ((in->modulusSize + 3UL) / 4UL)); + + /* Move the input parameters Point P coordinate x to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_POINT_CHECK_IN_INITIAL_POINT_X], in->pointX, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_POINT_CHECK_IN_INITIAL_POINT_X + ((in->modulusSize + 3UL) / 4UL)); + + /* Move the input parameters Point P coordinate y to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_POINT_CHECK_IN_INITIAL_POINT_Y], in->pointY, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_POINT_CHECK_IN_INITIAL_POINT_Y + ((in->modulusSize + 3UL) / 4UL)); + + /* Move the input parameters montgomery param R2 modulus N to PKA RAM */ + PKA_Memcpy_u32_to_u32(&hpka->Instance->RAM[PKA_POINT_CHECK_IN_MONTGOMERY_PARAM], in->pMontgomeryParam, + (in->modulusSize / 4UL)); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_POINT_CHECK_IN_MONTGOMERY_PARAM + ((in->modulusSize + 3UL) / 4UL)); +} + +/** + * @brief Set input parameters. + * @param hpka PKA handle + * @param in Input information + */ +void PKA_ECCMul_Set(PKA_HandleTypeDef *hpka, PKA_ECCMulInTypeDef *in) +{ + /* Get the prime order n length */ + hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_IN_EXP_NB_BITS] = PKA_GetOptBitSize_u8(in->scalarMulSize, *(in->primeOrder)); + + /* Get the modulus length */ + hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_IN_OP_NB_BITS] = PKA_GetOptBitSize_u8(in->modulusSize, *(in->modulus)); + + /* Get the coefficient a sign */ + hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_IN_A_COEFF_SIGN] = in->coefSign; + + /* Move the input parameters coefficient |a| to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_IN_A_COEFF], in->coefA, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_SCALAR_MUL_IN_A_COEFF + ((in->modulusSize + 3UL) / 4UL)); + + /* Move the input parameters coefficient b to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_IN_B_COEFF], in->coefB, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_SCALAR_MUL_IN_B_COEFF + ((in->modulusSize + 3UL) / 4UL)); + + /* Move the input parameters modulus value p to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_IN_MOD_GF], in->modulus, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_SCALAR_MUL_IN_MOD_GF + ((in->modulusSize + 3UL) / 4UL)); + + /* Move the input parameters scalar multiplier k to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_IN_K], in->scalarMul, in->scalarMulSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_SCALAR_MUL_IN_K + ((in->scalarMulSize + 3UL) / 4UL)); + + /* Move the input parameters Point P coordinate x to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_IN_INITIAL_POINT_X], in->pointX, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_SCALAR_MUL_IN_INITIAL_POINT_X + ((in->modulusSize + 3UL) / 4UL)); + + /* Move the input parameters Point P coordinate y to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_IN_INITIAL_POINT_Y], in->pointY, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_SCALAR_MUL_IN_INITIAL_POINT_Y + ((in->modulusSize + 3UL) / 4UL)); + + /* Move the input parameters curve prime order N to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_SCALAR_MUL_IN_N_PRIME_ORDER], in->primeOrder, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_SCALAR_MUL_IN_N_PRIME_ORDER + ((in->modulusSize + 3UL) / 4UL)); +} + + +/** + * @brief Set input parameters. + * @param hpka PKA handle + * @param in Input information + */ +void PKA_ModInv_Set(PKA_HandleTypeDef *hpka, PKA_ModInvInTypeDef *in) +{ + /* Get the number of bit per operand */ + hpka->Instance->RAM[PKA_MODULAR_INV_NB_BITS] = PKA_GetBitSize_u32(in->size); + + /* Move the input parameters operand A to PKA RAM */ + PKA_Memcpy_u32_to_u32(&hpka->Instance->RAM[PKA_MODULAR_INV_IN_OP1], in->pOp1, in->size); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_MODULAR_INV_IN_OP1 + in->size); + + /* Move the input parameters modulus value n to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_MODULAR_INV_IN_OP2_MOD], in->pMod, in->size * 4UL); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_MODULAR_INV_IN_OP2_MOD + in->size); +} + +/** + * @brief Set input parameters. + * @param hpka PKA handle + * @param in Input information + */ +void PKA_ModRed_Set(PKA_HandleTypeDef *hpka, PKA_ModRedInTypeDef *in) +{ + /* Get the number of bit per operand */ + hpka->Instance->RAM[PKA_MODULAR_REDUC_IN_OP_LENGTH] = PKA_GetBitSize_u32(in->OpSize); + + /* Get the number of bit per modulus */ + hpka->Instance->RAM[PKA_MODULAR_REDUC_IN_MOD_LENGTH] = PKA_GetBitSize_u8(in->modSize); + + /* Move the input parameters operand A to PKA RAM */ + PKA_Memcpy_u32_to_u32(&hpka->Instance->RAM[PKA_MODULAR_REDUC_IN_OPERAND], in->pOp1, in->OpSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_MODULAR_REDUC_IN_OPERAND + in->OpSize); + + /* Move the input parameters modulus value n to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_MODULAR_REDUC_IN_MODULUS], in->pMod, in->modSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_MODULAR_REDUC_IN_MODULUS + ((in->modSize + 3UL) / 4UL)); +} + +/** + * @brief Set input parameters. + * @param hpka PKA handle + * @param size Size of the operand + * @param pOp1 Generic pointer to input data + */ +void PKA_MontgomeryParam_Set(PKA_HandleTypeDef *hpka, const uint32_t size, const uint8_t *pOp1) +{ + uint32_t bytetoskip = 0UL; + uint32_t newSize; + + if (pOp1 != NULL) + { + /* Count the number of zero bytes */ + while ((bytetoskip < size) && (pOp1[bytetoskip] == 0UL)) + { + bytetoskip++; + } + + /* Get new size after skipping zero bytes */ + newSize = size - bytetoskip; + + /* Get the number of bit per operand */ + hpka->Instance->RAM[PKA_MONTGOMERY_PARAM_IN_MOD_NB_BITS] = PKA_GetOptBitSize_u8(newSize, pOp1[bytetoskip]); + + /* Move the input parameters pOp1 to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_MONTGOMERY_PARAM_IN_MODULUS], pOp1, size); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_MONTGOMERY_PARAM_IN_MODULUS + ((size + 3UL) / 4UL)); + } +} + +/** + * @brief Set input parameters. + * @param hpka PKA handle + * @param in Input information + */ +void PKA_ECCDoubleBaseLadder_Set(PKA_HandleTypeDef *hpka, PKA_ECCDoubleBaseLadderInTypeDef *in) +{ + /* Get the prime order n length */ + hpka->Instance->RAM[PKA_ECC_DOUBLE_LADDER_IN_PRIME_ORDER_NB_BITS] = PKA_GetBitSize_u8(in->primeOrderSize); + + /* Get the modulus p length */ + hpka->Instance->RAM[PKA_ECC_DOUBLE_LADDER_IN_MOD_NB_BITS] = PKA_GetBitSize_u8(in->modulusSize); + + /* Get the coefficient a sign */ + hpka->Instance->RAM[PKA_ECC_DOUBLE_LADDER_IN_A_COEFF_SIGN] = in->coefSign; + + /* Move the input parameters coefficient |a| to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_DOUBLE_LADDER_IN_A_COEFF], in->coefA, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_DOUBLE_LADDER_IN_A_COEFF + (in->modulusSize / 4UL)); + + /* Move the input parameters modulus value p to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_DOUBLE_LADDER_IN_MOD_P], in->modulus, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_DOUBLE_LADDER_IN_MOD_P + (in->modulusSize / 4UL)); + + /* Move the input parameters integer k to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_DOUBLE_LADDER_IN_K_INTEGER], in->integerK, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_DOUBLE_LADDER_IN_K_INTEGER + (in->modulusSize / 4UL)); + + /* Move the input parameters integer m to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_DOUBLE_LADDER_IN_M_INTEGER], in->integerM, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_DOUBLE_LADDER_IN_M_INTEGER + (in->modulusSize / 4UL)); + + /* Move the input parameters first point coordinate x to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_DOUBLE_LADDER_IN_POINT1_X], in->basePointX1, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_DOUBLE_LADDER_IN_POINT1_X + (in->modulusSize / 4UL)); + + /* Move the input parameters first point coordinate y to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_DOUBLE_LADDER_IN_POINT1_Y], in->basePointY1, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_DOUBLE_LADDER_IN_POINT1_Y + (in->modulusSize / 4UL)); + + /* Move the input parameters first point coordinate z to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_DOUBLE_LADDER_IN_POINT1_Z], in->basePointZ1, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_DOUBLE_LADDER_IN_POINT1_Z + (in->modulusSize / 4UL)); + + /* Move the input parameters second point coordinate x to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_DOUBLE_LADDER_IN_POINT2_X], in->basePointX2, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_DOUBLE_LADDER_IN_POINT2_X + (in->modulusSize / 4UL)); + + /* Move the input parameters second point coordinate y to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_DOUBLE_LADDER_IN_POINT2_Y], in->basePointY2, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_DOUBLE_LADDER_IN_POINT2_Y + (in->modulusSize / 4UL)); + + /* Move the input parameters second point coordinate z to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_DOUBLE_LADDER_IN_POINT2_Z], in->basePointZ2, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_DOUBLE_LADDER_IN_POINT2_Z + (in->modulusSize / 4UL)); +} + +/** + * @brief Retrieve operation result. + * @param hpka PKA handle + * @param out Output information + * @retval HAL status + */ +void HAL_PKA_ECCDoubleBaseLadder_GetResult(PKA_HandleTypeDef *hpka, PKA_ECCDoubleBaseLadderOutTypeDef *out) +{ + uint32_t size; + + /* Move the result to appropriate location (indicated in out parameter) */ + size = hpka->Instance->RAM[PKA_ECC_DOUBLE_LADDER_IN_MOD_NB_BITS] / 8UL; + if (out != NULL) + { + PKA_Memcpy_u32_to_u8(out->ptX, &hpka->Instance->RAM[PKA_ECC_DOUBLE_LADDER_OUT_RESULT_X], size); + PKA_Memcpy_u32_to_u8(out->ptY, &hpka->Instance->RAM[PKA_ECC_DOUBLE_LADDER_OUT_RESULT_Y], size); + } +} + +/** + * @brief Set input parameters. + * @param hpka PKA handle + * @param in Input information + */ +void PKA_ECCProjective2Affine_Set(PKA_HandleTypeDef *hpka, PKA_ECCProjective2AffineInTypeDef *in) +{ + /* Get the modulus p length */ + hpka->Instance->RAM[PKA_ECC_PROJECTIVE_AFF_IN_MOD_NB_BITS] = PKA_GetBitSize_u8(in->modulusSize); + + /* Move the input parameters modulus value p to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_PROJECTIVE_AFF_IN_MOD_P], in->modulus, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_PROJECTIVE_AFF_IN_MOD_P + (in->modulusSize / 4UL)); + + /* Move the input parameters point coordinate x to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_PROJECTIVE_AFF_IN_POINT_X], in->basePointX, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_PROJECTIVE_AFF_IN_POINT_X + (in->modulusSize / 4UL)); + + /* Move the input parameters point coordinate y to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_PROJECTIVE_AFF_IN_POINT_Y], in->basePointY, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_PROJECTIVE_AFF_IN_POINT_Y + (in->modulusSize / 4UL)); + + /* Move the input parameters point coordinate z to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_PROJECTIVE_AFF_IN_POINT_Z], in->basePointZ, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_PROJECTIVE_AFF_IN_POINT_Z + (in->modulusSize / 4UL)); + + /* Move the input parameters montgomery parameter R2 modulus n to PKA RAM */ + PKA_Memcpy_u32_to_u32(&hpka->Instance->RAM[PKA_ECC_PROJECTIVE_AFF_IN_MONTGOMERY_PARAM_R2], in->pMontgomeryParam, + (in->modulusSize / 4UL)); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_PROJECTIVE_AFF_IN_MONTGOMERY_PARAM_R2 + (in->modulusSize / 4UL)); +} + +/** + * @brief Retrieve operation result. + * @param hpka PKA handle + * @param out Output information + * @retval HAL status + */ +void HAL_PKA_ECCProjective2Affine_GetResult(PKA_HandleTypeDef *hpka, PKA_ECCProjective2AffineOutTypeDef *out) +{ + uint32_t size; + + /* Move the result to appropriate location (indicated in out parameter) */ + size = hpka->Instance->RAM[PKA_ECC_PROJECTIVE_AFF_IN_MOD_NB_BITS] / 8UL; + if (out != NULL) + { + PKA_Memcpy_u32_to_u8(out->ptX, &hpka->Instance->RAM[PKA_ECC_PROJECTIVE_AFF_OUT_RESULT_X], size); + PKA_Memcpy_u32_to_u8(out->ptY, &hpka->Instance->RAM[PKA_ECC_PROJECTIVE_AFF_OUT_RESULT_Y], size); + } +} + +/** + * @brief Set input parameters. + * @param hpka PKA handle + * @param in Input information + */ +void PKA_ECCCompleteAddition_Set(PKA_HandleTypeDef *hpka, PKA_ECCCompleteAdditionInTypeDef *in) +{ + /* Get the modulus p length */ + hpka->Instance->RAM[PKA_ECC_COMPLETE_ADD_IN_MOD_NB_BITS] = PKA_GetBitSize_u8(in->modulusSize); + + /* Get the coefficient a sign */ + hpka->Instance->RAM[PKA_ECC_DOUBLE_LADDER_IN_A_COEFF_SIGN] = in->coefSign; + + /* Move the input parameters modulus value p to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_COMPLETE_ADD_IN_MOD_P], in->modulus, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_COMPLETE_ADD_IN_MOD_P + (in->modulusSize / 4UL)); + + /* Move the input parameters coefA value to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_COMPLETE_ADD_IN_A_COEFF], in->coefA, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_COMPLETE_ADD_IN_A_COEFF + (in->modulusSize / 4UL)); + + /* Move the input parameters first point x value to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_COMPLETE_ADD_IN_POINT1_X], in->basePointX1, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_COMPLETE_ADD_IN_POINT1_X + (in->modulusSize / 4UL)); + + /* Move the input parameters first point y value to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_COMPLETE_ADD_IN_POINT1_Y], in->basePointY1, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_COMPLETE_ADD_IN_POINT1_Y + (in->modulusSize / 4UL)); + + /* Move the input parameters first point z value to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_COMPLETE_ADD_IN_POINT1_Z], in->basePointZ1, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_COMPLETE_ADD_IN_POINT1_Z + (in->modulusSize / 4UL)); + + /* Move the input parameters second point x value to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_COMPLETE_ADD_IN_POINT2_X], in->basePointX2, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_COMPLETE_ADD_IN_POINT2_X + (in->modulusSize / 4UL)); + + /* Move the input parameters second point y value to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_COMPLETE_ADD_IN_POINT2_Y], in->basePointY2, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_COMPLETE_ADD_IN_POINT2_Y + (in->modulusSize / 4UL)); + + /* Move the input parameters second point z value to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ECC_COMPLETE_ADD_IN_POINT2_Z], in->basePointZ2, in->modulusSize); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ECC_COMPLETE_ADD_IN_POINT2_Z + (in->modulusSize / 4UL)); +} + +/** + * @brief Retrieve operation result. + * @param hpka PKA handle + * @param out Output information + * @retval HAL status + */ +void HAL_PKA_ECCCompleteAddition_GetResult(PKA_HandleTypeDef *hpka, PKA_ECCCompleteAdditionOutTypeDef *out) +{ + uint32_t size; + + /* Move the result to appropriate location (indicated in out parameter) */ + size = (hpka->Instance->RAM[PKA_ECC_COMPLETE_ADD_IN_MOD_NB_BITS] + 7UL) / 8UL; + if (out != NULL) + { + PKA_Memcpy_u32_to_u8(out->ptX, &hpka->Instance->RAM[PKA_ECC_COMPLETE_ADD_OUT_RESULT_X], size); + PKA_Memcpy_u32_to_u8(out->ptY, &hpka->Instance->RAM[PKA_ECC_COMPLETE_ADD_OUT_RESULT_Y], size); + PKA_Memcpy_u32_to_u8(out->ptZ, &hpka->Instance->RAM[PKA_ECC_COMPLETE_ADD_OUT_RESULT_Z], size); + } +} +/** + * @brief Generic function to set input parameters. + * @param hpka PKA handle + * @param size Size of the operand + * @param pOp1 Generic pointer to input data + * @param pOp2 Generic pointer to input data + * @param pOp3 Generic pointer to input data + */ +void PKA_ARI_Set(PKA_HandleTypeDef *hpka, const uint32_t size, const uint32_t *pOp1, const uint32_t *pOp2, + const uint8_t *pOp3) +{ + /* Get the number of bit per operand */ + hpka->Instance->RAM[PKA_ARITHMETIC_ALL_OPS_NB_BITS] = PKA_GetBitSize_u32(size); + + if (pOp1 != NULL) + { + /* Move the input parameters pOp1 to PKA RAM */ + PKA_Memcpy_u32_to_u32(&hpka->Instance->RAM[PKA_ARITHMETIC_ALL_OPS_IN_OP1], pOp1, size); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ARITHMETIC_ALL_OPS_IN_OP1 + size); + } + + if (pOp2 != NULL) + { + /* Move the input parameters pOp2 to PKA RAM */ + PKA_Memcpy_u32_to_u32(&hpka->Instance->RAM[PKA_ARITHMETIC_ALL_OPS_IN_OP2], pOp2, size); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ARITHMETIC_ALL_OPS_IN_OP2 + size); + } + + if (pOp3 != NULL) + { + /* Move the input parameters pOp3 to PKA RAM */ + PKA_Memcpy_u8_to_u32(&hpka->Instance->RAM[PKA_ARITHMETIC_ALL_OPS_IN_OP3], pOp3, size * 4UL); + __PKA_RAM_PARAM_END(hpka->Instance->RAM, PKA_ARITHMETIC_ALL_OPS_IN_OP3 + size); + } +} +/** + * @brief Handle PKA init Timeout. + * @param hpka PKA handle. + * @param Flag Specifies the PKA flag to check + * @param Status Flag status (SET or RESET) + * @param Tickstart Tick start value + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef PKA_WaitOnFlagUntilTimeout(PKA_HandleTypeDef *hpka, uint32_t Flag, FlagStatus Status, + uint32_t Tickstart, uint32_t Timeout) +{ + /* Wait until flag is set */ + while (__HAL_PKA_GET_FLAG(hpka, Flag) == Status) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + { + /* Set the state to ready */ + hpka->State = HAL_PKA_STATE_READY; + + /* Set the error code to timeout error */ + hpka->ErrorCode = HAL_PKA_ERROR_TIMEOUT; + + return HAL_TIMEOUT; + } + } + } + return HAL_OK; +} + +/** + * @brief Get the size of output result. + * @param hpka PKA handle + * @param Startindex Specifies the start index of the result in the PKA RAM + * @param Maxsize Specifies the possible max size of the result in words + * @retval size + */ +uint32_t PKA_Result_GetSize(const PKA_HandleTypeDef *hpka, uint32_t Startindex, uint32_t Maxsize) +{ + uint32_t size; + uint32_t current_index = Maxsize - 1UL; + + /* Determinate the last index of the result in the PKA RAM */ + while ((hpka->Instance->RAM[Startindex + current_index] == 0UL) && (current_index != 0UL)) + { + current_index--; + } + /* Get the size in bytes */ + size = (current_index + 1UL) * 4UL; + + return size; +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined(PKA) && defined(HAL_PKA_MODULE_ENABLED) */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pssi.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pssi.c new file mode 100644 index 0000000000..8f44a72181 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pssi.c @@ -0,0 +1,1870 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_pssi.c + * @author MCD Application Team + * @brief PSSI HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Parallel Synchronous Slave Interface (PSSI) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral State and Errors functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The PSSI HAL driver can be used as follows: + + (#) Declare a PSSI_HandleTypeDef handle structure, for example: + PSSI_HandleTypeDef hpssi; + + (#) Initialize the PSSI low level resources by implementing the @ref HAL_PSSI_MspInit() API: + (##) Enable the PSSIx interface clock + (##) PSSI pins configuration + (+++) Enable the clock for the PSSI GPIOs + (+++) Configure PSSI pins as alternate function open-drain + (##) NVIC configuration if you need to use interrupt process + (+++) Configure the PSSIx interrupt priority + (+++) Enable the NVIC PSSI IRQ Channel + (##) DMA Configuration if you need to use DMA process + (+++) Declare DMA_HandleTypeDef handles structure for the transmit and receive + (+++) Enable the DMAx interface clock + (+++) Configure the DMA handle parameters + (+++) Configure the DMA Tx and Rx + (+++) Associate the initialized DMA handle to the hpssi DMA Tx and Rx handle + (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on + the DMA Tx and Rx + + (#) Configure the Communication Bus Width, Control Signals, Input Polarity and Output Polarity + in the hpssi Init structure. + + (#) Initialize the PSSI registers by calling the @ref HAL_PSSI_Init(), configure also the low level Hardware + (GPIO, CLOCK, NVIC...etc) by calling the customized @ref HAL_PSSI_MspInit(&hpssi) API. + + + (#) For PSSI IO operations, two operation modes are available within this driver : + + *** Polling mode IO operation *** + ================================= + [..] + (+) Transmit an amount of data by byte in blocking mode using @ref HAL_PSSI_Transmit() + (+) Receive an amount of data by byte in blocking mode using @ref HAL_PSSI_Receive() + + *** DMA mode IO operation *** + ============================== + [..] + (+) Transmit an amount of data in non-blocking mode (DMA) using + @ref HAL_PSSI_Transmit_DMA() + (+) At transmission end of transfer, @ref HAL_PSSI_TxCpltCallback() is executed and user can + add his own code by customization of function pointer @ref HAL_PSSI_TxCpltCallback() + (+) Receive an amount of data in non-blocking mode (DMA) using + @ref HAL_PSSI_Receive_DMA() + (+) At reception end of transfer, @ref HAL_PSSI_RxCpltCallback() is executed and user can + add his own code by customization of function pointer @ref HAL_PSSI_RxCpltCallback() + (+) In case of transfer Error, @ref HAL_PSSI_ErrorCallback() function is executed and user can + add his own code by customization of function pointer @ref HAL_PSSI_ErrorCallback() + (+) Abort a PSSI process communication with Interrupt using @ref HAL_PSSI_Abort_IT() + (+) End of abort process, @ref HAL_PSSI_AbortCpltCallback() is executed and user can + add his own code by customization of function pointer @ref HAL_PSSI_AbortCpltCallback() + + *** PSSI HAL driver macros list *** + ================================== + [..] + Below the list of most used macros in PSSI HAL driver. + + (+) @ref HAL_PSSI_ENABLE : Enable the PSSI peripheral + (+) @ref HAL_PSSI_DISABLE : Disable the PSSI peripheral + (+) @ref HAL_PSSI_GET_FLAG : Check whether the specified PSSI flag is set or not + (+) @ref HAL_PSSI_CLEAR_FLAG : Clear the specified PSSI pending flag + (+) @ref HAL_PSSI_ENABLE_IT : Enable the specified PSSI interrupt + (+) @ref HAL_PSSI_DISABLE_IT : Disable the specified PSSI interrupt + + *** Callback registration *** + ============================================= + Use Functions @ref HAL_PSSI_RegisterCallback() or @ref HAL_PSSI_RegisterAddrCallback() + to register an interrupt callback. + + Function @ref HAL_PSSI_RegisterCallback() allows to register following callbacks: + (+) TxCpltCallback : callback for transmission end of transfer. + (+) RxCpltCallback : callback for reception end of transfer. + (+) ErrorCallback : callback for error detection. + (+) AbortCpltCallback : callback for abort completion process. + (+) MspInitCallback : callback for Msp Init. + (+) MspDeInitCallback : callback for Msp DeInit. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + + + Use function @ref HAL_PSSI_UnRegisterCallback to reset a callback to the default + weak function. + @ref HAL_PSSI_UnRegisterCallback takes as parameters the HAL peripheral handle, + and the Callback ID. + This function allows to reset following callbacks: + (+) TxCpltCallback : callback for transmission end of transfer. + (+) RxCpltCallback : callback for reception end of transfer. + (+) ErrorCallback : callback for error detection. + (+) AbortCpltCallback : callback for abort completion process. + (+) MspInitCallback : callback for Msp Init. + (+) MspDeInitCallback : callback for Msp DeInit. + + + By default, after the @ref HAL_PSSI_Init() and when the state is @ref HAL_PSSI_STATE_RESET + all callbacks are set to the corresponding weak functions: + examples @ref HAL_PSSI_TxCpltCallback(), @ref HAL_PSSI_RxCpltCallback(). + Exception done for MspInit and MspDeInit functions that are + reset to the legacy weak functions in the @ref HAL_PSSI_Init()/ @ref HAL_PSSI_DeInit() only when + these callbacks are null (not registered beforehand). + If MspInit or MspDeInit are not null, the @ref HAL_PSSI_Init()/ @ref HAL_PSSI_DeInit() + keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state. + + Callbacks can be registered/unregistered in @ref HAL_PSSI_STATE_READY state only. + Exception done MspInit/MspDeInit functions that can be registered/unregistered + in @ref HAL_PSSI_STATE_READY or @ref HAL_PSSI_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 @ref HAL_PSSI_RegisterCallback() before calling @ref HAL_PSSI_DeInit() + or @ref HAL_PSSI_Init() function. + + + [..] + (@) You can refer to the PSSI HAL driver header file for more useful macros + + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup PSSI PSSI + * @brief PSSI HAL module driver + * @{ + */ + +#ifdef HAL_PSSI_MODULE_ENABLED +#if defined(PSSI) +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/** @defgroup PSSI_Private_Define PSSI Private Define + * @{ + */ + + + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ + +/** @defgroup PSSI_Private_Functions PSSI Private Functions + * @{ + */ +/* Private functions to handle DMA transfer */ +#if defined(HAL_DMA_MODULE_ENABLED) +void PSSI_DMATransmitCplt(DMA_HandleTypeDef *hdma); +void PSSI_DMAReceiveCplt(DMA_HandleTypeDef *hdma); +void PSSI_DMAError(DMA_HandleTypeDef *hdma); +void PSSI_DMAAbort(DMA_HandleTypeDef *hdma); +#endif /*HAL_DMA_MODULE_ENABLED*/ + +/* Private functions to handle IT transfer */ +static void PSSI_Error(PSSI_HandleTypeDef *hpssi, uint32_t ErrorCode); + + +/* Private functions for PSSI transfer IRQ handler */ + + +/* Private functions to handle flags during polling transfer */ +static HAL_StatusTypeDef PSSI_WaitOnStatusUntilTimeout(PSSI_HandleTypeDef *hpssi, uint32_t Flag, FlagStatus Status, + uint32_t Timeout, uint32_t Tickstart); + +/* Private functions to centralize the enable/disable of Interrupts */ + + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup PSSI_Exported_Functions PSSI Exported Functions + * @{ + */ + +/** @defgroup PSSI_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + deinitialize the PSSIx peripheral: + + (+) User must implement HAL_PSSI_MspInit() function in which he configures + all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ). + + (+) Call the function HAL_PSSI_Init() to configure the selected device with + the selected configuration: + (++) Data Width + (++) Control Signals + (++) Input Clock polarity + (++) Output Clock polarity + + (+) Call the function HAL_PSSI_DeInit() to restore the default configuration + of the selected PSSIx peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the PSSI according to the specified parameters + * in the PSSI_InitTypeDef and initialize the associated handle. + * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains + * the configuration information for the specified PSSI. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PSSI_Init(PSSI_HandleTypeDef *hpssi) +{ + /* Check the PSSI handle allocation */ + if (hpssi == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_PSSI_ALL_INSTANCE(hpssi->Instance)); + assert_param(IS_PSSI_CONTROL_SIGNAL(hpssi->Init.ControlSignal)); + assert_param(IS_PSSI_BUSWIDTH(hpssi->Init.BusWidth)); + assert_param(IS_PSSI_CLOCK_POLARITY(hpssi->Init.ClockPolarity)); + assert_param(IS_PSSI_DE_POLARITY(hpssi->Init.DataEnablePolarity)); + assert_param(IS_PSSI_RDY_POLARITY(hpssi->Init.ReadyPolarity)); + + if (hpssi->State == HAL_PSSI_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hpssi->Lock = HAL_UNLOCKED; + +#if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1) + /* Init the PSSI Callback settings */ + hpssi->TxCpltCallback = HAL_PSSI_TxCpltCallback; /* Legacy weak TxCpltCallback */ + hpssi->RxCpltCallback = HAL_PSSI_RxCpltCallback; /* Legacy weak RxCpltCallback */ + hpssi->ErrorCallback = HAL_PSSI_ErrorCallback; /* Legacy weak ErrorCallback */ + hpssi->AbortCpltCallback = HAL_PSSI_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ + + if (hpssi->MspInitCallback == NULL) + { + hpssi->MspInitCallback = HAL_PSSI_MspInit; /* Legacy weak MspInit */ + } + + /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ + hpssi->MspInitCallback(hpssi); +#else + /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ + HAL_PSSI_MspInit(hpssi); +#endif /*USE_HAL_PSSI_REGISTER_CALLBACKS*/ + } + + hpssi->State = HAL_PSSI_STATE_BUSY; + + /* Disable the selected PSSI peripheral */ + HAL_PSSI_DISABLE(hpssi); + + /*---------------------------- PSSIx CR Configuration ----------------------*/ + /* Configure PSSIx: Control Signal and Bus Width*/ + + MODIFY_REG(hpssi->Instance->CR, PSSI_CR_DERDYCFG | PSSI_CR_EDM | PSSI_CR_DEPOL | PSSI_CR_RDYPOL, + hpssi->Init.ControlSignal | hpssi->Init.DataEnablePolarity | + hpssi->Init.ReadyPolarity | hpssi->Init.BusWidth); + + hpssi->ErrorCode = HAL_PSSI_ERROR_NONE; + hpssi->State = HAL_PSSI_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitialize the PSSI peripheral. + * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains + * the configuration information for the specified PSSI. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PSSI_DeInit(PSSI_HandleTypeDef *hpssi) +{ + /* Check the PSSI handle allocation */ + if (hpssi == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_PSSI_ALL_INSTANCE(hpssi->Instance)); + + hpssi->State = HAL_PSSI_STATE_BUSY; + + /* Disable the PSSI Peripheral Clock */ + HAL_PSSI_DISABLE(hpssi); + +#if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1) + if (hpssi->MspDeInitCallback == NULL) + { + hpssi->MspDeInitCallback = HAL_PSSI_MspDeInit; /* Legacy weak MspDeInit */ + } + + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + hpssi->MspDeInitCallback(hpssi); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + HAL_PSSI_MspDeInit(hpssi); +#endif /*USE_HAL_PSSI_REGISTER_CALLBACKS*/ + + hpssi->ErrorCode = HAL_PSSI_ERROR_NONE; + hpssi->State = HAL_PSSI_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hpssi); + + return HAL_OK; +} + +/** + * @brief Initialize the PSSI MSP. + * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains + * the configuration information for the specified PSSI. + * @retval None + */ +__weak void HAL_PSSI_MspInit(PSSI_HandleTypeDef *hpssi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpssi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PSSI_MspInit can be implemented in the user file + */ +} + +/** + * @brief De-Initialize the PSSI MSP. + * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains + * the configuration information for the specified PSSI. + * @retval None + */ +__weak void HAL_PSSI_MspDeInit(PSSI_HandleTypeDef *hpssi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpssi); + + /* NOTE : This function should not be modified; when the callback is needed, + the HAL_PSSI_MspDeInit can be implemented in the user file + */ +} + +#if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User PSSI Callback + * To be used instead of the weak predefined callback + * @note The HAL_PSSI_RegisterCallback() may be called before HAL_PSSI_Init() in + * HAL_PSSI_STATE_RESET to register callbacks for HAL_PSSI_MSPINIT_CB_ID + * and HAL_PSSI_MSPDEINIT_CB_ID. + * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains + * the configuration information for the specified PSSI. + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_PSSI_TX_COMPLETE_CB_ID Tx Transfer completed callback ID + * @arg @ref HAL_PSSI_RX_COMPLETE_CB_ID Rx Transfer completed callback ID + * @arg @ref HAL_PSSI_ERROR_CB_ID Error callback ID + * @arg @ref HAL_PSSI_ABORT_CB_ID Abort callback ID + * @arg @ref HAL_PSSI_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_PSSI_MSPDEINIT_CB_ID MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PSSI_RegisterCallback(PSSI_HandleTypeDef *hpssi, HAL_PSSI_CallbackIDTypeDef CallbackID, + pPSSI_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hpssi->ErrorCode |= HAL_PSSI_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + if (HAL_PSSI_STATE_READY == hpssi->State) + { + switch (CallbackID) + { + case HAL_PSSI_TX_COMPLETE_CB_ID : + hpssi->TxCpltCallback = pCallback; + break; + + case HAL_PSSI_RX_COMPLETE_CB_ID : + hpssi->RxCpltCallback = pCallback; + break; + + case HAL_PSSI_ERROR_CB_ID : + hpssi->ErrorCallback = pCallback; + break; + + case HAL_PSSI_ABORT_CB_ID : + hpssi->AbortCpltCallback = pCallback; + break; + + case HAL_PSSI_MSPINIT_CB_ID : + hpssi->MspInitCallback = pCallback; + break; + + case HAL_PSSI_MSPDEINIT_CB_ID : + hpssi->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hpssi->ErrorCode |= HAL_PSSI_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_PSSI_STATE_RESET == hpssi->State) + { + switch (CallbackID) + { + case HAL_PSSI_MSPINIT_CB_ID : + hpssi->MspInitCallback = pCallback; + break; + + case HAL_PSSI_MSPDEINIT_CB_ID : + hpssi->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hpssi->ErrorCode |= HAL_PSSI_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hpssi->ErrorCode |= HAL_PSSI_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister an PSSI Callback + * PSSI callback is redirected to the weak predefined callback + * @note The HAL_PSSI_UnRegisterCallback() may be called before HAL_PSSI_Init() in + * HAL_PSSI_STATE_RESET to un-register callbacks for HAL_PSSI_MSPINIT_CB_ID + * and HAL_PSSI_MSPDEINIT_CB_ID. + * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains + * the configuration information for the specified PSSI. + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_PSSI_TX_COMPLETE_CB_ID Tx Transfer completed callback ID + * @arg @ref HAL_PSSI_RX_COMPLETE_CB_ID Rx Transfer completed callback ID + * @arg @ref HAL_PSSI_ERROR_CB_ID Error callback ID + * @arg @ref HAL_PSSI_ABORT_CB_ID Abort callback ID + * @arg @ref HAL_PSSI_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_PSSI_MSPDEINIT_CB_ID MspDeInit callback ID + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PSSI_UnRegisterCallback(PSSI_HandleTypeDef *hpssi, HAL_PSSI_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (HAL_PSSI_STATE_READY == hpssi->State) + { + switch (CallbackID) + { + case HAL_PSSI_TX_COMPLETE_CB_ID : + hpssi->TxCpltCallback = HAL_PSSI_TxCpltCallback; /* Legacy weak TxCpltCallback */ + break; + + case HAL_PSSI_RX_COMPLETE_CB_ID : + hpssi->RxCpltCallback = HAL_PSSI_RxCpltCallback; /* Legacy weak RxCpltCallback */ + break; + + case HAL_PSSI_ERROR_CB_ID : + hpssi->ErrorCallback = HAL_PSSI_ErrorCallback; /* Legacy weak ErrorCallback */ + break; + + case HAL_PSSI_ABORT_CB_ID : + hpssi->AbortCpltCallback = HAL_PSSI_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ + break; + + case HAL_PSSI_MSPINIT_CB_ID : + hpssi->MspInitCallback = HAL_PSSI_MspInit; /* Legacy weak MspInit */ + break; + + case HAL_PSSI_MSPDEINIT_CB_ID : + hpssi->MspDeInitCallback = HAL_PSSI_MspDeInit; /* Legacy weak MspDeInit */ + break; + + default : + /* Update the error code */ + hpssi->ErrorCode |= HAL_PSSI_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_PSSI_STATE_RESET == hpssi->State) + { + switch (CallbackID) + { + case HAL_PSSI_MSPINIT_CB_ID : + hpssi->MspInitCallback = HAL_PSSI_MspInit; /* Legacy weak MspInit */ + break; + + case HAL_PSSI_MSPDEINIT_CB_ID : + hpssi->MspDeInitCallback = HAL_PSSI_MspDeInit; /* Legacy weak MspDeInit */ + break; + + default : + /* Update the error code */ + hpssi->ErrorCode |= HAL_PSSI_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hpssi->ErrorCode |= HAL_PSSI_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup PSSI_Exported_Functions_Group2 Input and Output operation functions + * @brief Data transfers functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the PSSI data + transfers. + + (#) There are two modes of transfer: + (++) Blocking mode : The communication is performed in the polling mode. + The status of all data processing is returned by the same function + after finishing transfer. + (++) No-Blocking mode : The communication is performed using DMA. + These functions return the status of the transfer startup. + The end of the data processing will be indicated through the + dedicated the DMA IRQ . + + (#) Blocking mode functions are : + (++) HAL_PSSI_Transmit() + (++) HAL_PSSI_Receive() + + (#) No-Blocking mode functions with DMA are : + (++) HAL_PSSI_Transmit_DMA() + (++) HAL_PSSI_Receive_DMA() + + (#) A set of Transfer Complete Callbacks are provided in non Blocking mode: + (++) HAL_PSSI_TxCpltCallback() + (++) HAL_PSSI_RxCpltCallback() + (++) HAL_PSSI_ErrorCallback() + (++) HAL_PSSI_AbortCpltCallback() + +@endverbatim + * @{ + */ + +/** + * @brief Transmits in master mode an amount of data in blocking mode. + * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains + * the configuration information for the specified PSSI. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent (in bytes) + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PSSI_Transmit(PSSI_HandleTypeDef *hpssi, uint8_t *pData, uint32_t Size, uint32_t Timeout) +{ + uint32_t tickstart; + uint32_t transfer_size = Size; + + if (((hpssi->Init.DataWidth == HAL_PSSI_8BITS) && (hpssi->Init.BusWidth != HAL_PSSI_8LINES)) || + ((hpssi->Init.DataWidth == HAL_PSSI_16BITS) && ((Size % 2U) != 0U)) || + ((hpssi->Init.DataWidth == HAL_PSSI_32BITS) && ((Size % 4U) != 0U))) + { + hpssi->ErrorCode = HAL_PSSI_ERROR_NOT_SUPPORTED; + return HAL_ERROR; + } + if (hpssi->State == HAL_PSSI_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hpssi); + + hpssi->State = HAL_PSSI_STATE_BUSY; + hpssi->ErrorCode = HAL_PSSI_ERROR_NONE; + + /* Disable the selected PSSI peripheral */ + HAL_PSSI_DISABLE(hpssi); + + /* Configure transfer parameters */ + hpssi->Instance->CR |= PSSI_CR_OUTEN_OUTPUT | + ((hpssi->Init.ClockPolarity == HAL_PSSI_RISING_EDGE) ? 0U : PSSI_CR_CKPOL); + +#if defined(HAL_DMA_MODULE_ENABLED) + /* DMA Disable */ + hpssi->Instance->CR &= PSSI_CR_DMA_DISABLE; +#endif /*HAL_DMA_MODULE_ENABLED*/ + + /* Enable the selected PSSI peripheral */ + HAL_PSSI_ENABLE(hpssi); + + if (hpssi->Init.DataWidth == HAL_PSSI_8BITS) + { + uint8_t *pbuffer = pData; + while (transfer_size > 0U) + { + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + /* Wait until Fifo is ready to transfer one byte flag is set */ + if (PSSI_WaitOnStatusUntilTimeout(hpssi, PSSI_FLAG_RTT1B, RESET, Timeout, tickstart) != HAL_OK) + { + hpssi->ErrorCode = HAL_PSSI_ERROR_TIMEOUT; + hpssi->State = HAL_PSSI_STATE_READY; + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + return HAL_ERROR; + } + /* Write data to DR */ + *(__IO uint8_t *)(&hpssi->Instance->DR) = *(uint8_t *)pbuffer; + + /* Increment Buffer pointer */ + pbuffer++; + + transfer_size--; + } + } + else if (hpssi->Init.DataWidth == HAL_PSSI_16BITS) + { + uint16_t *pbuffer = (uint16_t *)pData; + __IO uint16_t *dr = (__IO uint16_t *)(&hpssi->Instance->DR); + + while (transfer_size > 0U) + { + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + /* Wait until Fifo is ready to transfer four bytes flag is set */ + if (PSSI_WaitOnStatusUntilTimeout(hpssi, PSSI_FLAG_RTT4B, RESET, Timeout, tickstart) != HAL_OK) + { + hpssi->ErrorCode = HAL_PSSI_ERROR_TIMEOUT; + hpssi->State = HAL_PSSI_STATE_READY; + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + return HAL_ERROR; + } + /* Write data to DR */ + *dr = *pbuffer; + + /* Increment Buffer pointer */ + pbuffer++; + transfer_size -= 2U; + } + } + else if (hpssi->Init.DataWidth == HAL_PSSI_32BITS) + { + uint32_t *pbuffer = (uint32_t *)pData; + while (transfer_size > 0U) + { + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + /* Wait until Fifo is ready to transfer four bytes flag is set */ + if (PSSI_WaitOnStatusUntilTimeout(hpssi, PSSI_FLAG_RTT4B, RESET, Timeout, tickstart) != HAL_OK) + { + hpssi->ErrorCode = HAL_PSSI_ERROR_TIMEOUT; + hpssi->State = HAL_PSSI_STATE_READY; + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + return HAL_ERROR; + } + /* Write data to DR */ + *(__IO uint32_t *)(&hpssi->Instance->DR) = *pbuffer; + + /* Increment Buffer pointer */ + pbuffer++; + transfer_size -= 4U; + } + } + else + { + hpssi->ErrorCode = HAL_PSSI_ERROR_NOT_SUPPORTED; + hpssi->State = HAL_PSSI_STATE_READY; + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + return HAL_ERROR; + } + + /* Check Errors Flags */ + if (HAL_PSSI_GET_FLAG(hpssi, PSSI_FLAG_OVR_RIS) != 0U) + { + HAL_PSSI_CLEAR_FLAG(hpssi, PSSI_FLAG_OVR_RIS); + HAL_PSSI_DISABLE(hpssi); + hpssi->ErrorCode = HAL_PSSI_ERROR_UNDER_RUN; + hpssi->State = HAL_PSSI_STATE_READY; + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + return HAL_ERROR; + } + + hpssi->State = HAL_PSSI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receives an amount of data in blocking mode. + * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains + * the configuration information for the specified PSSI. + * @param pData Pointer to data buffer + * @param Size Amount of data to be received (in bytes) + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PSSI_Receive(PSSI_HandleTypeDef *hpssi, uint8_t *pData, uint32_t Size, uint32_t Timeout) +{ + uint32_t tickstart; + uint32_t transfer_size = Size; + + if (((hpssi->Init.DataWidth == HAL_PSSI_8BITS) && (hpssi->Init.BusWidth != HAL_PSSI_8LINES)) || + ((hpssi->Init.DataWidth == HAL_PSSI_16BITS) && ((Size % 2U) != 0U)) || + ((hpssi->Init.DataWidth == HAL_PSSI_32BITS) && ((Size % 4U) != 0U))) + { + hpssi->ErrorCode = HAL_PSSI_ERROR_NOT_SUPPORTED; + return HAL_ERROR; + } + + if (hpssi->State == HAL_PSSI_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hpssi); + + hpssi->State = HAL_PSSI_STATE_BUSY; + hpssi->ErrorCode = HAL_PSSI_ERROR_NONE; + + /* Disable the selected PSSI peripheral */ + HAL_PSSI_DISABLE(hpssi); + /* Configure transfer parameters */ + hpssi->Instance->CR |= PSSI_CR_OUTEN_INPUT | + ((hpssi->Init.ClockPolarity == HAL_PSSI_FALLING_EDGE) ? 0U : PSSI_CR_CKPOL); + +#if defined(HAL_DMA_MODULE_ENABLED) + /* DMA Disable */ + hpssi->Instance->CR &= PSSI_CR_DMA_DISABLE; +#endif /*HAL_DMA_MODULE_ENABLED*/ + + /* Enable the selected PSSI peripheral */ + HAL_PSSI_ENABLE(hpssi); + if (hpssi->Init.DataWidth == HAL_PSSI_8BITS) + { + uint8_t *pbuffer = pData; + + while (transfer_size > 0U) + { + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + /* Wait until Fifo is ready to receive one byte flag is set */ + if (PSSI_WaitOnStatusUntilTimeout(hpssi, PSSI_FLAG_RTT1B, RESET, Timeout, tickstart) != HAL_OK) + { + hpssi->ErrorCode = HAL_PSSI_ERROR_TIMEOUT; + hpssi->State = HAL_PSSI_STATE_READY; + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + return HAL_ERROR; + } + /* Read data from DR */ + *pbuffer = *(__IO uint8_t *)(&hpssi->Instance->DR); + pbuffer++; + transfer_size--; + } + } + else if (hpssi->Init.DataWidth == HAL_PSSI_16BITS) + { + uint16_t *pbuffer = (uint16_t *)pData; + __IO uint16_t *dr = (__IO uint16_t *)(&hpssi->Instance->DR); + + while (transfer_size > 0U) + { + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + /* Wait until Fifo is ready to receive four bytes flag is set */ + if (PSSI_WaitOnStatusUntilTimeout(hpssi, PSSI_FLAG_RTT4B, RESET, Timeout, tickstart) != HAL_OK) + { + hpssi->ErrorCode = HAL_PSSI_ERROR_TIMEOUT; + hpssi->State = HAL_PSSI_STATE_READY; + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + return HAL_ERROR; + } + + /* Read data from DR */ + *pbuffer = *dr; + pbuffer++; + transfer_size -= 2U; + } + } + else if (hpssi->Init.DataWidth == HAL_PSSI_32BITS) + { + uint32_t *pbuffer = (uint32_t *)pData; + + while (transfer_size > 0U) + { + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + /* Wait until Fifo is ready to receive four bytes flag is set */ + if (PSSI_WaitOnStatusUntilTimeout(hpssi, PSSI_FLAG_RTT4B, RESET, Timeout, tickstart) != HAL_OK) + { + hpssi->ErrorCode = HAL_PSSI_ERROR_TIMEOUT; + hpssi->State = HAL_PSSI_STATE_READY; + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + return HAL_ERROR; + } + + /* Read data from DR */ + *pbuffer = *(__IO uint32_t *)(&hpssi->Instance->DR); + pbuffer++; + transfer_size -= 4U; + } + } + else + { + hpssi->ErrorCode = HAL_PSSI_ERROR_NOT_SUPPORTED; + hpssi->State = HAL_PSSI_STATE_READY; + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + return HAL_ERROR; + } + /* Check Errors Flags */ + + if (HAL_PSSI_GET_FLAG(hpssi, PSSI_FLAG_OVR_RIS) != 0U) + { + HAL_PSSI_CLEAR_FLAG(hpssi, PSSI_FLAG_OVR_RIS); + hpssi->ErrorCode = HAL_PSSI_ERROR_OVER_RUN; + __HAL_UNLOCK(hpssi); + return HAL_ERROR; + } + + hpssi->State = HAL_PSSI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief Transmit an amount of data in non-blocking mode with DMA + * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains + * the configuration information for the specified PSSI. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent (in bytes) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PSSI_Transmit_DMA(PSSI_HandleTypeDef *hpssi, uint32_t *pData, uint32_t Size) +{ + HAL_StatusTypeDef dmaxferstatus; + + if (hpssi->State == HAL_PSSI_STATE_READY) + { + + /* Process Locked */ + __HAL_LOCK(hpssi); + + hpssi->State = HAL_PSSI_STATE_BUSY_TX; + hpssi->ErrorCode = HAL_PSSI_ERROR_NONE; + + /* Disable the selected PSSI peripheral */ + HAL_PSSI_DISABLE(hpssi); + + /* Prepare transfer parameters */ + hpssi->pBuffPtr = pData; + hpssi->XferCount = Size; + + if (hpssi->XferCount > PSSI_MAX_NBYTE_SIZE) + { + hpssi->XferSize = PSSI_MAX_NBYTE_SIZE; + } + else + { + hpssi->XferSize = hpssi->XferCount; + } + + if (hpssi->XferSize > 0U) + { + if (hpssi->hdmatx != NULL) + { + + /* Configure BusWidth */ + if (hpssi->hdmatx->Init.DestDataWidth == DMA_DEST_DATAWIDTH_BYTE) + { + MODIFY_REG(hpssi->Instance->CR, PSSI_CR_DMAEN | PSSI_CR_OUTEN | PSSI_CR_CKPOL, + PSSI_CR_DMA_ENABLE | PSSI_CR_OUTEN_OUTPUT | + ((hpssi->Init.ClockPolarity == HAL_PSSI_RISING_EDGE) ? 0U : PSSI_CR_CKPOL)); + } + else + { + MODIFY_REG(hpssi->Instance->CR, PSSI_CR_DMAEN | PSSI_CR_OUTEN | PSSI_CR_CKPOL, + PSSI_CR_DMA_ENABLE | hpssi->Init.BusWidth | PSSI_CR_OUTEN_OUTPUT | + ((hpssi->Init.ClockPolarity == HAL_PSSI_RISING_EDGE) ? 0U : PSSI_CR_CKPOL)); + } + + /* Set the PSSI DMA transfer complete callback */ + hpssi->hdmatx->XferCpltCallback = PSSI_DMATransmitCplt; + + /* Set the DMA error callback */ + hpssi->hdmatx->XferErrorCallback = PSSI_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hpssi->hdmatx->XferHalfCpltCallback = NULL; + hpssi->hdmatx->XferAbortCallback = NULL; + + /* Enable the DMA */ + if ((hpssi->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hpssi->hdmatx->LinkedListQueue != NULL) + { + /* Enable the DMA channel */ + /* Set DMA data size */ + hpssi->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hpssi->XferSize; + /* Set DMA source address */ + hpssi->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)pData; + /* Set DMA destination address */ + hpssi->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = + (uint32_t)&hpssi->Instance->DR; + + dmaxferstatus = HAL_DMAEx_List_Start_IT(hpssi->hdmatx); + } + else + { + /* Return error status */ + return HAL_ERROR; + } + } + else + { + dmaxferstatus = HAL_DMA_Start_IT(hpssi->hdmatx, (uint32_t)pData, (uint32_t)&hpssi->Instance->DR, + hpssi->XferSize); + } + } + else + { + /* Update PSSI state */ + hpssi->State = HAL_PSSI_STATE_READY; + + /* Update PSSI error code */ + hpssi->ErrorCode |= HAL_PSSI_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + + return HAL_ERROR; + } + + if (dmaxferstatus == HAL_OK) + { + /* Update XferCount value */ + hpssi->XferCount -= hpssi->XferSize; + + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + + /* Note : The PSSI interrupts must be enabled after unlocking current process + to avoid the risk of PSSI interrupt handle execution before current + process unlock */ + /* Enable ERR interrupt */ + HAL_PSSI_ENABLE_IT(hpssi, PSSI_FLAG_OVR_RIS); + + /* Enable DMA Request */ + hpssi->Instance->CR |= PSSI_CR_DMA_ENABLE; + /* Enable the selected PSSI peripheral */ + HAL_PSSI_ENABLE(hpssi); + } + else + { + /* Update PSSI state */ + hpssi->State = HAL_PSSI_STATE_READY; + + /* Update PSSI error code */ + hpssi->ErrorCode |= HAL_PSSI_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + + return HAL_ERROR; + } + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + + /* Note : The PSSI interrupts must be enabled after unlocking current process + to avoid the risk of PSSI interrupt handle execution before current + process unlock */ + /* Enable ERRinterrupt */ + /* possible to enable all of these */ + + HAL_PSSI_ENABLE_IT(hpssi, PSSI_FLAG_OVR_RIS); + } + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in non-blocking mode with DMA + * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains + * the configuration information for the specified PSSI. + * @param pData Pointer to data buffer + * @param Size Amount of data to be received (in bytes) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PSSI_Receive_DMA(PSSI_HandleTypeDef *hpssi, uint32_t *pData, uint32_t Size) +{ + + HAL_StatusTypeDef dmaxferstatus; + + if (hpssi->State == HAL_PSSI_STATE_READY) + { + + /* Disable the selected PSSI peripheral */ + HAL_PSSI_DISABLE(hpssi); + /* Process Locked */ + __HAL_LOCK(hpssi); + + hpssi->State = HAL_PSSI_STATE_BUSY_RX; + hpssi->ErrorCode = HAL_PSSI_ERROR_NONE; + + /* Prepare transfer parameters */ + hpssi->pBuffPtr = pData; + hpssi->XferCount = Size; + + if (hpssi->XferCount > PSSI_MAX_NBYTE_SIZE) + { + hpssi->XferSize = PSSI_MAX_NBYTE_SIZE; + } + else + { + hpssi->XferSize = hpssi->XferCount; + } + + if (hpssi->XferSize > 0U) + { + if (hpssi->hdmarx != NULL) + { + /* Configure BusWidth */ + if (hpssi->hdmatx->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_BYTE) + { + MODIFY_REG(hpssi->Instance->CR, PSSI_CR_DMAEN | PSSI_CR_OUTEN | PSSI_CR_CKPOL, PSSI_CR_DMA_ENABLE | + ((hpssi->Init.ClockPolarity == HAL_PSSI_RISING_EDGE) ? PSSI_CR_CKPOL : 0U)); + } + else + { + MODIFY_REG(hpssi->Instance->CR, PSSI_CR_DMAEN | PSSI_CR_OUTEN | PSSI_CR_CKPOL, + PSSI_CR_DMA_ENABLE | hpssi->Init.BusWidth | + ((hpssi->Init.ClockPolarity == HAL_PSSI_RISING_EDGE) ? PSSI_CR_CKPOL : 0U)); + } + + /* Set the PSSI DMA transfer complete callback */ + hpssi->hdmarx->XferCpltCallback = PSSI_DMAReceiveCplt; + + /* Set the DMA error callback */ + hpssi->hdmarx->XferErrorCallback = PSSI_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hpssi->hdmarx->XferHalfCpltCallback = NULL; + hpssi->hdmarx->XferAbortCallback = NULL; + + /* Enable the DMA */ + if ((hpssi->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hpssi->hdmarx->LinkedListQueue != NULL) + { + /* Enable the DMA channel */ + /* Set DMA data size */ + hpssi->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hpssi->XferSize; + /* Set DMA source address */ + hpssi->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = + (uint32_t)&hpssi->Instance->DR; + /* Set DMA destination address */ + hpssi->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)pData; + + dmaxferstatus = HAL_DMAEx_List_Start_IT(hpssi->hdmarx); + } + else + { + /* Return error status */ + return HAL_ERROR; + } + } + else + { + dmaxferstatus = HAL_DMA_Start_IT(hpssi->hdmarx, (uint32_t)&hpssi->Instance->DR, (uint32_t)pData, + hpssi->XferSize); + } + } + else + { + /* Update PSSI state */ + hpssi->State = HAL_PSSI_STATE_READY; + + /* Update PSSI error code */ + hpssi->ErrorCode |= HAL_PSSI_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + + return HAL_ERROR; + } + + if (dmaxferstatus == HAL_OK) + { + /* Update XferCount value */ + hpssi->XferCount -= hpssi->XferSize; + + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + + /* Note : The PSSI interrupts must be enabled after unlocking current process + to avoid the risk of PSSI interrupt handle execution before current + process unlock */ + /* Enable ERR interrupt */ + HAL_PSSI_ENABLE_IT(hpssi, PSSI_FLAG_OVR_RIS); + + /* Enable DMA Request */ + hpssi->Instance->CR |= PSSI_CR_DMA_ENABLE; + /* Enable the selected PSSI peripheral */ + HAL_PSSI_ENABLE(hpssi); + } + else + { + /* Update PSSI state */ + hpssi->State = HAL_PSSI_STATE_READY; + + /* Update PSSI error code */ + hpssi->ErrorCode |= HAL_PSSI_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + + return HAL_ERROR; + } + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + + /* Enable ERR,interrupt */ + HAL_PSSI_ENABLE_IT(hpssi, PSSI_FLAG_OVR_RIS); + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Abort a DMA process communication with Interrupt. + * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains + * the configuration information for the specified PSSI. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PSSI_Abort_DMA(PSSI_HandleTypeDef *hpssi) +{ + /* Process Locked */ + __HAL_LOCK(hpssi); + + /* Disable Interrupts */ + HAL_PSSI_DISABLE_IT(hpssi, PSSI_FLAG_OVR_RIS); + + /* Set State at HAL_PSSI_STATE_ABORT */ + hpssi->State = HAL_PSSI_STATE_ABORT; + + /* Abort DMA TX transfer if any */ + if ((hpssi->Instance->CR & PSSI_CR_DMAEN) == PSSI_CR_DMAEN) + { + if (hpssi->State == HAL_PSSI_STATE_BUSY_TX) + { + hpssi->Instance->CR &= ~PSSI_CR_DMAEN; + + if (hpssi->hdmatx != NULL) + { + /* Set the PSSI DMA Abort callback : + will lead to call HAL_PSSI_ErrorCallback() at end of DMA abort procedure */ + hpssi->hdmatx->XferAbortCallback = PSSI_DMAAbort; + + /* Abort DMA TX */ + if (HAL_DMA_Abort_IT(hpssi->hdmatx) != HAL_OK) + { + /* Call Directly XferAbortCallback function in case of error */ + hpssi->hdmatx->XferAbortCallback(hpssi->hdmatx); + } + } + } + /* Abort DMA RX transfer if any */ + else if (hpssi->State == HAL_PSSI_STATE_BUSY_RX) + { + hpssi->Instance->CR &= ~PSSI_CR_DMAEN; + + if (hpssi->hdmarx != NULL) + { + /* Set the PSSI DMA Abort callback : + will lead to call HAL_PSSI_ErrorCallback() at end of DMA abort procedure */ + hpssi->hdmarx->XferAbortCallback = PSSI_DMAAbort; + + /* Abort DMA RX */ + if (HAL_DMA_Abort_IT(hpssi->hdmarx) != HAL_OK) + { + /* Call Directly hpssi->hdma->XferAbortCallback function in case of error */ + hpssi->hdmarx->XferAbortCallback(hpssi->hdmarx); + } + } + } + else + { + + /* Call the error callback */ +#if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1) + hpssi->ErrorCallback(hpssi); +#else + HAL_PSSI_ErrorCallback(hpssi); +#endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */ + } + } + + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + + /* Note : The PSSI interrupts must be enabled after unlocking current process + to avoid the risk of PSSI interrupt handle execution before current + process unlock */ + HAL_PSSI_ENABLE_IT(hpssi, PSSI_FLAG_OVR_RIS); + + return HAL_OK; +} +#endif /*HAL_DMA_MODULE_ENABLED*/ + +/** + * @} + */ + +/** @addtogroup PSSI_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @{ + */ + +/** + * @brief This function handles PSSI event interrupt request. + * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains + * the configuration information for the specified PSSI. + * @retval None + */ +void HAL_PSSI_IRQHandler(PSSI_HandleTypeDef *hpssi) +{ + /* Overrun/ Underrun Errors */ + if (HAL_PSSI_GET_FLAG(hpssi, PSSI_FLAG_OVR_MIS) != 0U) + { + /* Reset handle parameters */ + hpssi->XferCount = 0U; + + /* Disable all interrupts */ + HAL_PSSI_DISABLE_IT(hpssi, PSSI_FLAG_OVR_RIS); + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Abort DMA TX transfer if any */ + if ((hpssi->Instance->CR & PSSI_CR_DMAEN) == PSSI_CR_DMAEN) + { + if (hpssi->State == HAL_PSSI_STATE_BUSY_TX) + { + /* Set new error code */ + hpssi->ErrorCode |= HAL_PSSI_ERROR_UNDER_RUN; + + hpssi->Instance->CR &= ~PSSI_CR_DMAEN; + + if (hpssi->hdmatx != NULL) + { + /* Set the PSSI DMA Abort callback : + will lead to call HAL_PSSI_ErrorCallback() at end of DMA abort procedure */ + hpssi->hdmatx->XferAbortCallback = PSSI_DMAAbort; + + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + + /* Abort DMA TX */ + if (HAL_DMA_Abort_IT(hpssi->hdmatx) != HAL_OK) + { + /* Call Directly XferAbortCallback function in case of error */ + hpssi->hdmatx->XferAbortCallback(hpssi->hdmatx); + } + } + } + /* Abort DMA RX transfer if any */ + else if (hpssi->State == HAL_PSSI_STATE_BUSY_RX) + { + /* Set new error code */ + hpssi->ErrorCode |= HAL_PSSI_ERROR_OVER_RUN; + + hpssi->Instance->CR &= ~PSSI_CR_DMAEN; + + if (hpssi->hdmarx != NULL) + { + /* Set the PSSI DMA Abort callback : + will lead to call HAL_PSSI_ErrorCallback() at end of DMA abort procedure */ + hpssi->hdmarx->XferAbortCallback = PSSI_DMAAbort; + + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + + /* Abort DMA RX */ + if (HAL_DMA_Abort_IT(hpssi->hdmarx) != HAL_OK) + { + /* Call Directly hpssi->hdma->XferAbortCallback function in case of error */ + hpssi->hdmarx->XferAbortCallback(hpssi->hdmarx); + } + } + } + else + { +#if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1) + /* Call the corresponding callback to inform upper layer of the error */ + hpssi->ErrorCallback(hpssi); +#else + HAL_PSSI_ErrorCallback(hpssi); +#endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */ + } + } +#endif /*HAL_DMA_MODULE_ENABLED*/ + + /* If state is an abort treatment on going, don't change state */ + if (hpssi->State == HAL_PSSI_STATE_ABORT) + { + hpssi->State = HAL_PSSI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + +#if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1) + /* Call the corresponding callback to inform upper layer of End of Transfer */ + hpssi->AbortCpltCallback(hpssi); +#else + HAL_PSSI_AbortCpltCallback(hpssi); +#endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */ + } + else + { + /* Set HAL_PSSI_STATE_READY */ + hpssi->State = HAL_PSSI_STATE_READY; + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + +#if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1) + /* Call the corresponding callback to inform upper layer of End of Transfer */ + hpssi->ErrorCallback(hpssi); +#else + HAL_PSSI_ErrorCallback(hpssi); +#endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */ + } + } +} + +/** + * @brief Tx Transfer complete callback. + * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains + * the configuration information for the specified PSSI. + * @retval None + */ +__weak void HAL_PSSI_TxCpltCallback(PSSI_HandleTypeDef *hpssi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpssi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PSSI_TxCpltCallback can be implemented in the user file + */ +} + +/** + * @brief Rx Transfer complete callback. + * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains + * the configuration information for the specified PSSI. + * @retval None + */ +__weak void HAL_PSSI_RxCpltCallback(PSSI_HandleTypeDef *hpssi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpssi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PSSI_RxCpltCallback can be implemented in the user file + */ +} + +/** + * @brief PSSI error callback. + * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains + * the configuration information for the specified PSSI. + * @retval None + */ +__weak void HAL_PSSI_ErrorCallback(PSSI_HandleTypeDef *hpssi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpssi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PSSI_ErrorCallback could be implemented in the user file + */ +} + +/** + * @brief PSSI abort callback. + * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains + * the configuration information for the specified PSSI. + * @retval None + */ +__weak void HAL_PSSI_AbortCpltCallback(PSSI_HandleTypeDef *hpssi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpssi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PSSI_AbortCpltCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup PSSI_Exported_Functions_Group3 Peripheral State and Error functions + * @brief Peripheral State, Mode and Error functions + * +@verbatim + =============================================================================== + ##### Peripheral State, Mode and Error functions ##### + =============================================================================== + [..] + This subsection permit to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the PSSI handle state. + * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains + * the configuration information for the specified PSSI. + * @retval HAL state + */ +HAL_PSSI_StateTypeDef HAL_PSSI_GetState(const PSSI_HandleTypeDef *hpssi) +{ + /* Return PSSI handle state */ + return hpssi->State; +} + +/** + * @brief Return the PSSI error code. + * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains + * the configuration information for the specified PSSI. + * @retval PSSI Error Code + */ +uint32_t HAL_PSSI_GetError(const PSSI_HandleTypeDef *hpssi) +{ + return hpssi->ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup PSSI_Private_Functions + * @{ + */ + +/** + * @brief PSSI Errors process. + * @param hpssi PSSI handle. + * @param ErrorCode Error code to handle. + * @retval None + */ +static void PSSI_Error(PSSI_HandleTypeDef *hpssi, uint32_t ErrorCode) +{ + /* Reset handle parameters */ + hpssi->XferCount = 0U; + + /* Set new error code */ + hpssi->ErrorCode |= ErrorCode; + + /* Disable all interrupts */ + HAL_PSSI_DISABLE_IT(hpssi, PSSI_FLAG_OVR_RIS); + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Abort DMA TX transfer if any */ + if ((hpssi->Instance->CR & PSSI_CR_DMAEN) == PSSI_CR_DMAEN) + { + if (hpssi->State == HAL_PSSI_STATE_BUSY_TX) + { + hpssi->Instance->CR &= ~PSSI_CR_DMAEN; + + if (hpssi->hdmatx != NULL) + { + /* Set the PSSI DMA Abort callback : + will lead to call HAL_PSSI_ErrorCallback() at end of DMA abort procedure */ + hpssi->hdmatx->XferAbortCallback = PSSI_DMAAbort; + + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + + /* Abort DMA TX */ + if (HAL_DMA_Abort_IT(hpssi->hdmatx) != HAL_OK) + { + /* Call Directly XferAbortCallback function in case of error */ + hpssi->hdmatx->XferAbortCallback(hpssi->hdmatx); + } + } + } + /* Abort DMA RX transfer if any */ + else if (hpssi->State == HAL_PSSI_STATE_BUSY_RX) + { + hpssi->Instance->CR &= ~PSSI_CR_DMAEN; + + if (hpssi->hdmarx != NULL) + { + /* Set the PSSI DMA Abort callback : + will lead to call HAL_PSSI_ErrorCallback() at end of DMA abort procedure */ + hpssi->hdmarx->XferAbortCallback = PSSI_DMAAbort; + + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + + /* Abort DMA RX */ + if (HAL_DMA_Abort_IT(hpssi->hdmarx) != HAL_OK) + { + /* Call Directly hpssi->hdma->XferAbortCallback function in case of error */ + hpssi->hdmarx->XferAbortCallback(hpssi->hdmarx); + } + } + } + else + { + /*Nothing to do*/ + } + } +#endif /*HAL_DMA_MODULE_ENABLED*/ + + /* If state is an abort treatment on going, don't change state */ + if (hpssi->State == HAL_PSSI_STATE_ABORT) + { + hpssi->State = HAL_PSSI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1) + hpssi->AbortCpltCallback(hpssi); +#else + HAL_PSSI_AbortCpltCallback(hpssi); +#endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */ + } + else + { + /* Set HAL_PSSI_STATE_READY */ + hpssi->State = HAL_PSSI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1) + hpssi->ErrorCallback(hpssi); +#else + HAL_PSSI_ErrorCallback(hpssi); +#endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */ + } +} + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief DMA PSSI slave transmit process complete callback. + * @param hdma DMA handle + * @retval None + */ +void PSSI_DMATransmitCplt(DMA_HandleTypeDef *hdma) +{ + /* Derogation MISRAC2012-Rule-11.5 */ + PSSI_HandleTypeDef *hpssi = (PSSI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); + + uint32_t tmperror; + + /* Disable Interrupts */ + HAL_PSSI_DISABLE_IT(hpssi, PSSI_FLAG_OVR_RIS); + + /* Store current volatile hpssi->ErrorCode, misra rule */ + tmperror = hpssi->ErrorCode; + + /* Call the corresponding callback to inform upper layer of End of Transfer */ + if ((hpssi->State == HAL_PSSI_STATE_ABORT) || (tmperror != HAL_PSSI_ERROR_NONE)) + { + /* Call the corresponding callback to inform upper layer of End of Transfer */ + PSSI_Error(hpssi, hpssi->ErrorCode); + } + /* hpssi->State == HAL_PSSI_STATE_BUSY_TX */ + else + { + hpssi->State = HAL_PSSI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1) + hpssi->TxCpltCallback(hpssi); +#else + HAL_PSSI_TxCpltCallback(hpssi); +#endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */ + } +} + +/** + * @brief DMA PSSI master receive process complete callback. + * @param hdma DMA handle + * @retval None + */ +void PSSI_DMAReceiveCplt(DMA_HandleTypeDef *hdma) +{ + /* Derogation MISRAC2012-Rule-11.5 */ + PSSI_HandleTypeDef *hpssi = (PSSI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); + + uint32_t tmperror; + + /* Disable Interrupts */ + HAL_PSSI_DISABLE_IT(hpssi, PSSI_FLAG_OVR_RIS); + + /* Store current volatile hpssi->ErrorCode, misra rule */ + tmperror = hpssi->ErrorCode; + + /* Call the corresponding callback to inform upper layer of End of Transfer */ + if ((hpssi->State == HAL_PSSI_STATE_ABORT) || (tmperror != HAL_PSSI_ERROR_NONE)) + { + /* Call the corresponding callback to inform upper layer of End of Transfer */ + PSSI_Error(hpssi, hpssi->ErrorCode); + } + /* hpssi->State == HAL_PSSI_STATE_BUSY_RX */ + else + { + hpssi->State = HAL_PSSI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1) + hpssi->RxCpltCallback(hpssi); +#else + HAL_PSSI_RxCpltCallback(hpssi); +#endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */ + } +} + +/** + * @brief DMA PSSI communication abort callback + * (To be called at end of DMA Abort procedure). + * @param hdma DMA handle. + * @retval None + */ +void PSSI_DMAAbort(DMA_HandleTypeDef *hdma) +{ + /* Derogation MISRAC2012-Rule-11.5 */ + PSSI_HandleTypeDef *hpssi = (PSSI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); + + /* Reset AbortCpltCallback */ + hpssi->hdmatx->XferAbortCallback = NULL; + hpssi->hdmarx->XferAbortCallback = NULL; + + /* Check if come from abort from user */ + if (hpssi->State == HAL_PSSI_STATE_ABORT) + { + hpssi->State = HAL_PSSI_STATE_READY; + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1) + hpssi->AbortCpltCallback(hpssi); +#else + HAL_PSSI_AbortCpltCallback(hpssi); +#endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */ + } + else + { + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1) + hpssi->ErrorCallback(hpssi); +#else + HAL_PSSI_ErrorCallback(hpssi); +#endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */ + } +} +#endif /*HAL_DMA_MODULE_ENABLED*/ + +/** + * @brief This function handles PSSI Communication Timeout. + * @param hpssi Pointer to a PSSI_HandleTypeDef structure that contains + * the configuration information for the specified PSSI. + * @param Flag Specifies the PSSI flag to check. + * @param Status The new Flag status (SET or RESET). + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef PSSI_WaitOnStatusUntilTimeout(PSSI_HandleTypeDef *hpssi, uint32_t Flag, FlagStatus Status, + uint32_t Timeout, uint32_t Tickstart) +{ + while ((HAL_PSSI_GET_STATUS(hpssi, Flag) & Flag) == (uint32_t)Status) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + { + hpssi->ErrorCode |= HAL_PSSI_ERROR_TIMEOUT; + hpssi->State = HAL_PSSI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + + return HAL_ERROR; + } + } + } + return HAL_OK; +} + +#if defined(HAL_DMA_MODULE_ENABLED) +void PSSI_DMAError(DMA_HandleTypeDef *hdma) +{ + /* Derogation MISRAC2012-Rule-11.5 */ + PSSI_HandleTypeDef *hpssi = (PSSI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); + + uint32_t tmperror; + + /* Disable the selected PSSI peripheral */ + HAL_PSSI_DISABLE(hpssi); + + /* Disable Interrupts */ + HAL_PSSI_DISABLE_IT(hpssi, PSSI_FLAG_OVR_RIS); + + /* Store current volatile hpssi->ErrorCode, misra rule */ + tmperror = hpssi->ErrorCode; + + /* Call the corresponding callback to inform upper layer of End of Transfer */ + if ((hpssi->State == HAL_PSSI_STATE_ABORT) || (tmperror != HAL_PSSI_ERROR_NONE)) + { + /* Call the corresponding callback to inform upper layer of End of Transfer */ + PSSI_Error(hpssi, hpssi->ErrorCode); + } + else + { + hpssi->State = HAL_PSSI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hpssi); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_PSSI_REGISTER_CALLBACKS == 1) + hpssi->ErrorCallback(hpssi); +#else + HAL_PSSI_ErrorCallback(hpssi); +#endif /* USE_HAL_PSSI_REGISTER_CALLBACKS */ + } +} +#endif /*HAL_DMA_MODULE_ENABLED*/ + + +/** + * @} + */ +#endif /* PSSI */ +#endif /* HAL_PSSI_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pwr.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pwr.c new file mode 100644 index 0000000000..669efbc1e8 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pwr.c @@ -0,0 +1,666 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_pwr.c + * @author MCD Application Team + * @brief PWR HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Power Controller (PWR) peripheral: + * + Initialization/De-Initialization Functions. + * + Peripheral Control Functions. + * + PWR Attributes Functions. + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup PWR PWR + * @brief PWR HAL module driver + * @{ + */ + +#if defined (HAL_PWR_MODULE_ENABLED) + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/** @defgroup PWR_Private_Defines PWR Private Defines + * @{ + */ + +/** @defgroup PWR_PVD_Mode_Mask PWR PVD Mode Mask + * @{ + */ +#define PVD_RISING_EDGE (0x01U) /*!< Mask for rising edge set as PVD + trigger */ +#define PVD_FALLING_EDGE (0x02U) /*!< Mask for falling edge set as PVD + trigger */ +#define PVD_MODE_IT (0x04U) /*!< Mask for interruption yielded by PVD + threshold crossing */ +#define PVD_MODE_EVT (0x08U) /*!< Mask for event yielded by PVD threshold + crossing */ +/** + * @} + */ + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup PWR_Exported_Functions PWR Exported Functions + * @{ + */ + +/** @defgroup PWR_Exported_Functions_Group1 Initialization and De-Initialization Functions + * @brief Initialization and de-Initialization functions + * +@verbatim + =============================================================================== + ##### Initialization and De-Initialization Functions ##### + =============================================================================== + [..] +@endverbatim + * @{ + */ + +/** + * @brief Deinitialize the HAL PWR peripheral registers to their default reset + * values. + * @note This functionality is not available in this product. + * The prototype is kept just to maintain compatibility with other + * products. + * @retval None. + */ +void HAL_PWR_DeInit(void) +{ +} + +/** + * @brief Enable access to the backup domain (RCC Backup domain control + * register RCC_BDCR, RTC registers, TAMP registers, backup registers + * and backup SRAM). + * @note After a system reset, the backup domain is protected against + * possible unwanted write accesses. + * @retval None. + */ +void HAL_PWR_EnableBkUpAccess(void) +{ + SET_BIT(PWR->DBPCR, PWR_DBPCR_DBP); +} + +/** + * @brief Disable access to the backup domain (RCC Backup domain control + * register RCC_BDCR, RTC registers, TAMP registers, backup registers + * and backup SRAM). + * @retval None + */ +void HAL_PWR_DisableBkUpAccess(void) +{ + CLEAR_BIT(PWR->DBPCR, PWR_DBPCR_DBP); +} +/** + * @} + */ + +/** @defgroup PWR_Exported_Functions_Group2 Peripheral Control Functions + * @brief Low power modes configuration functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] +@endverbatim + * @{ + */ + +/** + * @brief Configure the voltage threshold detected by the Programmed Voltage + * Detector (PVD). + * @param sConfigPVD : Pointer to a PWR_PVDTypeDef structure that contains the + * PVD configuration information (PVDLevel and EventMode). + * @retval None. + */ +HAL_StatusTypeDef HAL_PWR_ConfigPVD(const PWR_PVDTypeDef *sConfigPVD) +{ + /* Check the parameters */ + assert_param(IS_PWR_PVD_LEVEL(sConfigPVD->PVDLevel)); + assert_param(IS_PWR_PVD_MODE(sConfigPVD->Mode)); + + /* Set PLS[3:1] bits according to PVDLevel value */ + MODIFY_REG(PWR->VMCR, PWR_VMCR_PLS, sConfigPVD->PVDLevel); + + /* Disable PVD Event/Interrupt */ + __HAL_PWR_PVD_EXTI_DISABLE_EVENT(); + __HAL_PWR_PVD_EXTI_DISABLE_IT(); + __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE(); + __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE(); + + /* Configure the PVD in interrupt mode */ + if ((sConfigPVD->Mode & PVD_MODE_IT) == PVD_MODE_IT) + { + __HAL_PWR_PVD_EXTI_ENABLE_IT(); + } + + /* Configure the PVD in event mode */ + if ((sConfigPVD->Mode & PVD_MODE_EVT) == PVD_MODE_EVT) + { + __HAL_PWR_PVD_EXTI_ENABLE_EVENT(); + } + + /* Configure the PVD in rising edge */ + if ((sConfigPVD->Mode & PVD_RISING_EDGE) == PVD_RISING_EDGE) + { + __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE(); + } + + /* Configure the PVD in falling edge */ + if ((sConfigPVD->Mode & PVD_FALLING_EDGE) == PVD_FALLING_EDGE) + { + __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE(); + } + + return HAL_OK; +} + +/** + * @brief Enable the programmable voltage detector (PVD). + * @retval None. + */ +void HAL_PWR_EnablePVD(void) +{ + SET_BIT(PWR->VMCR, PWR_VMCR_PVDEN); +} + +/** + * @brief Disable the programmable voltage detector (PVD). + * @retval None. + */ +void HAL_PWR_DisablePVD(void) +{ + CLEAR_BIT(PWR->VMCR, PWR_VMCR_PVDEN); +} + +/** + * @brief Enable the WakeUp PINx functionality. + * @param WakeUpPinPolarity : Specifies which Wake-Up pin to enable. + * This parameter can be one of the following legacy values, which + * sets the default (rising edge): + * @arg PWR_WAKEUP_PIN1, PWR_WAKEUP_PIN2, PWR_WAKEUP_PIN3,PWR_WAKEUP_PIN4, + * PWR_WAKEUP_PIN5, PWR_WAKEUP_PIN6, PWR_WAKEUP_PIN7.PWR_WAKEUP_PIN8. + * or one of the following values where the user can explicitly states + * the enabled pin and the chosen polarity: + * @arg PWR_WAKEUP_PIN1_HIGH, PWR_WAKEUP_PIN1_LOW, + * PWR_WAKEUP_PIN2_HIGH, PWR_WAKEUP_PIN2_LOW, + * PWR_WAKEUP_PIN3_HIGH, PWR_WAKEUP_PIN3_LOW, + * PWR_WAKEUP_PIN4_HIGH, PWR_WAKEUP_PIN4_LOW, + * PWR_WAKEUP_PIN5_HIGH, PWR_WAKEUP_PIN5_LOW, + * PWR_WAKEUP_PIN6_HIGH, PWR_WAKEUP_PIN6_LOW, + * PWR_WAKEUP_PIN7_HIGH, PWR_WAKEUP_PIN7_LOW, + * PWR_WAKEUP_PIN8_HIGH, PWR_WAKEUP_PIN8_LOW. + * @note PWR_WAKEUP_PINx and PWR_WAKEUP_PINx_HIGH are equivalent. + * @note The PWR_WAKEUP_PIN6_HIGH, PWR_WAKEUP_PIN6_LOW, PWR_WAKEUP_PIN7_HIGH, PWR_WAKEUP_PIN7_LOW, + * PWR_WAKEUP_PIN8_HIGH and PWR_WAKEUP_PIN8_LOW are not available for STM32H503xx devices. + * @retval None. + */ +void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinPolarity) +{ + /* Check the parameters */ + assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinPolarity)); + + /* + Enable and Specify the Wake-Up pin polarity and the pull configuration + for the event detection (rising or falling edge). + */ + MODIFY_REG(PWR->WUCR, PWR_EWUP_MASK, WakeUpPinPolarity); +} + +/** + * @brief Disable the WakeUp PINx functionality. + * @param WakeUpPinx : Specifies the Power Wake-Up pin to disable. + * This parameter can be one of the following values: + * @arg PWR_WAKEUP_PIN1, PWR_WAKEUP_PIN2, PWR_WAKEUP_PIN3,PWR_WAKEUP_PIN4, + * PWR_WAKEUP_PIN5, PWR_WAKEUP_PIN6, PWR_WAKEUP_PIN7.PWR_WAKEUP_PIN8. + * or one of the following values where the user can explicitly states + * the enabled pin and the chosen polarity: + * @arg PWR_WAKEUP_PIN1_HIGH, PWR_WAKEUP_PIN1_LOW, + * PWR_WAKEUP_PIN2_HIGH, PWR_WAKEUP_PIN2_LOW, + * PWR_WAKEUP_PIN3_HIGH, PWR_WAKEUP_PIN3_LOW, + * PWR_WAKEUP_PIN4_HIGH, PWR_WAKEUP_PIN4_LOW, + * PWR_WAKEUP_PIN5_HIGH, PWR_WAKEUP_PIN5_LOW, + * PWR_WAKEUP_PIN6_HIGH, PWR_WAKEUP_PIN6_LOW, + * PWR_WAKEUP_PIN7_HIGH, PWR_WAKEUP_PIN7_LOW, + * PWR_WAKEUP_PIN8_HIGH, PWR_WAKEUP_PIN8_LOW. + * @note The PWR_WAKEUP_PIN6_HIGH, PWR_WAKEUP_PIN6_LOW, PWR_WAKEUP_PIN7_HIGH, PWR_WAKEUP_PIN7_LOW, + * PWR_WAKEUP_PIN8_HIGH and PWR_WAKEUP_PIN8_LOW are not available for STM32H503xx devices. + * @retval None. + */ +void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx) +{ + /* Check the parameters */ + assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx)); + + /* Disable the wake up pin selected */ + CLEAR_BIT(PWR->WUCR, (PWR_WUCR_WUPEN & WakeUpPinx)); +} + +/** + * @brief Enter the CPU in SLEEP mode. + * @note In SLEEP mode, all I/O pins keep the same state as in Run mode. + * @note CPU clock is off and all peripherals including Cortex-M33 core such + * as NVIC and SysTick can run and wake up the CPU when an interrupt + * or an event occurs. + * @param Regulator : Specifies the regulator state in Sleep mode. + * This parameter can be one of the following values : + * @arg @ref PWR_MAINREGULATOR_ON + * @arg @ref PWR_LOWPOWERREGULATOR_ON + * @note This parameter is not available in this product. + * The parameter is kept just to maintain compatibility with other + * products. + * @param SLEEPEntry : Specifies if SLEEP mode is entered with WFI or WFE + * instruction. + * This parameter can be one of the following values : + * @arg @ref PWR_SLEEPENTRY_WFI enter SLEEP mode with Wait + * For Interrupt request. + * @arg @ref PWR_SLEEPENTRY_WFE enter SLEEP mode with Wait + * For Event request. + * @note When WFI entry is used, ticks interrupt must be disabled to avoid + * unexpected CPU wake up. + * @retval None. + */ +void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry) +{ + UNUSED(Regulator); + + /* Check the parameter */ + assert_param(IS_PWR_SLEEP_ENTRY(SLEEPEntry)); + + /* Clear SLEEPDEEP bit of Cortex System Control Register */ + CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); + + /* Select SLEEP mode entry */ + if (SLEEPEntry == PWR_SLEEPENTRY_WFI) + { + /* Wait For Interrupt Request */ + __WFI(); + } + else + { + /* Wait For Event Request */ + __SEV(); + __WFE(); + __WFE(); + } +} + +/** + * @brief Enter the whole system to STOP mode. + * @note In STOP mode, the regulator remains in main regulator mode, + * allowing a very fast wakeup time but with much higher consumption + * comparing to other STOP modes. + * @note STOP offers the largest number of active peripherals and wakeup + * sources, a smaller wakeup time but a higher consumption. + * STOP mode achieves the lowest power consumption while retaining + * the content of SRAM and registers. All clocks in the VCORE domain + * are stopped. The PLL, the HSI, the CSI and the HSE crystal oscillators + * are disabled. The LSE or LSI is still running. + * @note The system clock when exiting from Stop mode can be either HSI + * or CSI, depending on software configuration. + * @param Regulator : Specifies the regulator state in Sleep mode. + * This parameter can be one of the following values : + * @arg @ref PWR_MAINREGULATOR_ON + * @arg @ref PWR_LOWPOWERREGULATOR_ON + * @note This parameter is not available in this product. + * The parameter is kept just to maintain compatibility with other + * products. + * @param STOPEntry : Specifies if STOP mode is entered with WFI or WFE + * instruction. + * This parameter can be one of the following values : + * @arg @ref PWR_STOPENTRY_WFI enter STOP mode with Wait + * For Interrupt request. + * @arg @ref PWR_STOPENTRY_WFE enter STOP mode with Wait + * For Event request. + * @retval None. + */ +void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry) +{ + UNUSED(Regulator); + + /* Check the parameter */ + assert_param(IS_PWR_STOP_ENTRY(STOPEntry)); + + /* Select STOP mode */ + CLEAR_BIT(PWR->PMCR, PWR_PMCR_LPMS); + + /* Set SLEEPDEEP bit of Cortex System Control Register */ + SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); + + /* Select STOP mode entry */ + if (STOPEntry == PWR_STOPENTRY_WFI) + { + /* Wait For Interrupt Request */ + __WFI(); + } + else + { + /* Wait For Event Request */ + __SEV(); + __WFE(); + __WFE(); + } + + /* Reset SLEEPDEEP bit of Cortex System Control Register */ + CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); +} + +/** + * @brief Enter the whole system to STANDBY mode. + * @note The STANDBY mode is used to achieve the lowest power consumption + * with BOR. The internal regulator is switched off so that the VCORE + * domain is powered off. The PLL, the HSI, the CSI and the HSE crystal + * oscillators are also switched off. + * @note After entering STANDBY mode, SRAMs and register contents are lost + * except for registers and backup SRAM in the Backup domain and + * STANDBY circuitry. + * @retval None. + */ +void HAL_PWR_EnterSTANDBYMode(void) +{ + /* Select STANDBY mode */ + SET_BIT(PWR->PMCR, PWR_PMCR_LPMS); + + /* Set SLEEPDEEP bit of Cortex System Control Register */ + SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); + + /* This option is used to ensure that store operations are completed */ +#if defined ( __CC_ARM) + __force_stores(); +#endif /* __CC_ARM */ + + /* Wait For Interrupt Request */ + __WFI(); +} + +/** + * @brief Indicate SLEEP-ON-EXIT feature when returning from handler mode to + * thread mode. + * @note Set SLEEPONEXIT bit of SCR register. When this bit is set, the + * processor re-enters SLEEP mode when an interruption handling is over. + * Setting this bit is useful when the processor is expected to run + * only on interruptions handling. + * @retval None. + */ +void HAL_PWR_EnableSleepOnExit(void) +{ + /* Set SLEEPONEXIT bit of Cortex-M33 System Control Register */ + SET_BIT(SCB->SCR, SCB_SCR_SLEEPONEXIT_Msk); +} + +/** + * @brief Disable SLEEP-ON-EXIT feature when returning from handler mode to + * thread mode. + * @note Clears SLEEPONEXIT bit of SCR register. When this bit is set, the + * processor re-enters SLEEP mode when an interruption handling is over. + * @retval None. + */ +void HAL_PWR_DisableSleepOnExit(void) +{ + /* Clear SLEEPONEXIT bit of Cortex-M33 System Control Register */ + CLEAR_BIT(SCB->SCR, SCB_SCR_SLEEPONEXIT_Msk); +} + +/** + * @brief Enable CORTEX SEV-ON-PEND feature. + * @note Sets SEVONPEND bit of SCR register. When this bit is set, any + * pending event / interrupt even if it's disabled or has insufficient + * priority to cause exception entry wakes up the Cortex-M33. + * @retval None. + */ +void HAL_PWR_EnableSEVOnPend(void) +{ + /* Set SEVONPEND bit of Cortex-M33 System Control Register */ + SET_BIT(SCB->SCR, SCB_SCR_SEVONPEND_Msk); +} + +/** + * @brief Disable CORTEX SEVONPEND feature. + * @note Resets SEVONPEND bit of SCR register. When this bit is reset, only + * enabled pending causes exception entry wakes up the Cortex-M33. + * @retval None. + */ +void HAL_PWR_DisableSEVOnPend(void) +{ + /* Clear SEVONPEND bit of Cortex-M33 System Control Register */ + CLEAR_BIT(SCB->SCR, SCB_SCR_SEVONPEND_Msk); +} + +/** + * @brief This function handles the PWR PVD interrupt request. + * @note This API should be called under the PVD_AVD_IRQHandler(). + * @note The use of this API is only when we activate the PVD. + * @note When the PVD and AVD are activated at the same time you must use this API: + * HAL_PWREx_PVD_AVD_IRQHandler. + * @retval None. + */ +void HAL_PWR_PVD_IRQHandler(void) +{ + uint32_t rising_flag; + uint32_t falling_flag; + + /* Get pending flags */ + rising_flag = READ_REG(EXTI->RPR1); + falling_flag = READ_REG(EXTI->FPR1); + + /* Check PWR EXTI flags for PVD */ + if (((rising_flag | falling_flag) & PWR_EXTI_LINE_PVD) != 0U) + { + /* PWR PVD interrupt user callback */ + HAL_PWR_PVDCallback(); + + /* Clear PVD EXTI pending bit */ + WRITE_REG(EXTI->RPR1, PWR_EXTI_LINE_PVD); + WRITE_REG(EXTI->FPR1, PWR_EXTI_LINE_PVD); + } +} + +/** + * @brief PWR PVD interrupt callback. + * @retval None. + */ +__weak void HAL_PWR_PVDCallback(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PWR_PVDCallback can be implemented in the user file + */ +} +/** + * @} + */ + +/** @defgroup PWR_Exported_Functions_Group3 Attributes Management Functions + * @brief Attributes management functions + * +@verbatim + =============================================================================== + ##### PWR Attributes Functions ##### + =============================================================================== + [..] +@endverbatim + * @{ + */ + +/** + * @brief Configure the PWR item attributes. + * @note Available attributes are security and privilege protection. + * @note Security attribute can only be set only by secure access. + * @note Privilege attribute for secure items can be managed only by a secure + * privileged access. + * @note Privilege attribute for nsecure items can be managed by a secure + * privileged access or by a nsecure privileged access. + * @param Item : Specifies the item(s) to set attributes on. + * This parameter can be a combination of @ref PWR_Items. + * @param Attributes : Specifies the available attribute(s). + * This parameter can be one of @ref PWR_Attributes. + * @retval None. + */ +void HAL_PWR_ConfigAttributes(uint32_t Item, uint32_t Attributes) +{ + /* Check the parameters */ + assert_param(IS_PWR_ATTRIBUTES(Attributes)); + +#if defined (PWR_SECCFGR_WUP1SEC) + assert_param(IS_PWR_ITEMS_ATTRIBUTES(Item)); + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + /* Secure item management (TZEN = 1) */ + if ((Attributes & PWR_ITEM_ATTR_SEC_PRIV_MASK) == PWR_ITEM_ATTR_SEC_PRIV_MASK) + { + /* Privilege item management */ + if ((Attributes & PWR_SEC_PRIV) == PWR_SEC_PRIV) + { + SET_BIT(PWR->SECCFGR, Item); + SET_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_SPRIV); + } + else + { + SET_BIT(PWR->SECCFGR, Item); + CLEAR_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_SPRIV); + } + } + /* NSecure item management */ + else + { + /* Privilege item management */ + if ((Attributes & PWR_NSEC_PRIV) == PWR_NSEC_PRIV) + { + CLEAR_BIT(PWR->SECCFGR, Item); + SET_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_NSPRIV); + } + else + { + CLEAR_BIT(PWR->SECCFGR, Item); + CLEAR_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_NSPRIV); + } + } +#else + /* NSecure item management (TZEN = 0) */ + if ((Attributes & PWR_ITEM_ATTR_NSEC_PRIV_MASK) == PWR_ITEM_ATTR_NSEC_PRIV_MASK) + { + /* Privilege item management */ + if ((Attributes & PWR_NSEC_PRIV) == PWR_NSEC_PRIV) + { + SET_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_NSPRIV); + } + else + { + CLEAR_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_NSPRIV); + } + } +#endif /* __ARM_FEATURE_CMSE */ + +#else /* PWR_SECCFGR_WUP1SEC */ + /* Prevent unused argument(s) compilation warning */ + UNUSED(Item); + + /* NSecure item management (TZEN = 0) */ + if ((Attributes & PWR_ITEM_ATTR_NSEC_PRIV_MASK) == PWR_ITEM_ATTR_NSEC_PRIV_MASK) + { + /* Privilege item management */ + if ((Attributes & PWR_PRIV) == PWR_PRIV) + { + SET_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_PRIV); + } + else + { + CLEAR_BIT(PWR->PRIVCFGR, PWR_PRIVCFGR_PRIV); + } + } +#endif /* PWR_SECCFGR_WUP1SEC */ +} + +/** + * @brief Get attribute(s) of a PWR item. + * @param Item : Specifies the item(s) to set attributes on. + * This parameter can be one of @ref PWR_Items. + * @param pAttributes : Pointer to return attribute(s). + * Returned value could be on of @ref PWR_Attributes. + * @retval HAL Status. + */ +HAL_StatusTypeDef HAL_PWR_GetConfigAttributes(uint32_t Item, uint32_t *pAttributes) +{ + uint32_t attributes; + + /* Check attribute pointer */ + if (pAttributes == NULL) + { + return HAL_ERROR; + } +#if defined (PWR_SECCFGR_WUP1SEC) + /* Check the parameter */ + assert_param(IS_PWR_ITEMS_ATTRIBUTES(Item)); +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + /* Check item security */ + if ((PWR->SECCFGR & Item) == Item) + { + /* Get Secure privileges attribute */ + attributes = ((PWR->PRIVCFGR & PWR_PRIVCFGR_SPRIV) == 0U) ? PWR_SEC_NPRIV : PWR_SEC_PRIV; + } + else + { + /* Get Non-Secure privileges attribute */ + attributes = ((PWR->PRIVCFGR & PWR_PRIVCFGR_NSPRIV) == 0U) ? PWR_NSEC_NPRIV : PWR_NSEC_PRIV; + } +#else + /* Get Non-Secure privileges attribute */ + attributes = ((PWR->PRIVCFGR & PWR_PRIVCFGR_NSPRIV) == 0U) ? PWR_NSEC_NPRIV : PWR_NSEC_PRIV; +#endif /* __ARM_FEATURE_CMSE */ + +#else /* PWR_SECCFGR_WUP1SEC*/ + /* Prevent unused argument(s) compilation warning */ + UNUSED(Item); + + /* Get Non-Secure privileges attribute */ + attributes = ((PWR->PRIVCFGR & PWR_PRIVCFGR_PRIV) == 0U) ? PWR_NPRIV : PWR_PRIV; +#endif /* PWR_SECCFGR_WUP1SEC */ + + /* return value */ + *pAttributes = attributes; + + return HAL_OK; +} +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined (HAL_PWR_MODULE_ENABLED) */ +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pwr_ex.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pwr_ex.c new file mode 100644 index 0000000000..f59fbd1dbd --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_pwr_ex.c @@ -0,0 +1,824 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_pwr_ex.c + * @author MCD Application Team + * @brief Extended PWR HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Power Controller extension peripheral : + * + Power Supply Control Functions + * + Voltage Monitoring Functions + * + Wakeup Pins configuration Functions + * + Memories Retention Functions + * + IO and JTAG Retention Functions + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup PWREx PWREx + * @brief PWR Extended HAL module driver + * @{ + */ + +#if defined (HAL_PWR_MODULE_ENABLED) + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/** @defgroup PWR_Extended_Private_Defines PWR Extended Private Defines + * @{ + */ +/* PORTI pins mask */ +#define PWR_PORTI_AVAILABLE_PINS (0xFFU) +/*!< Time out value of flags setting */ +#define PWR_FLAG_SETTING_DELAY (0x32U) + +/** @defgroup PWR_PVM_Mode_Mask PWR PVM Mode Mask + * @{ + */ +#define PVM_RISING_EDGE (0x01U) /*!< Mask for rising edge set as PVM trigger */ +#define PVM_FALLING_EDGE (0x02U) /*!< Mask for falling edge set as PVM trigger */ +#define PVM_MODE_IT (0x04U) /*!< Mask for interruption yielded by PVM threshold crossing */ +#define PVM_MODE_EVT (0x08U) /*!< Mask for event yielded by PVM threshold crossing */ +/** + * @} + */ + +/** @defgroup PWREx_WakeUp_Pins_Offsets PWREx Wake-Up Pins offsets + * @{ + */ + +/* Wake-Up Pins PWR Pin Pull shift offsets */ +#define PWR_WAKEUP_PINS_PULL_SHIFT_OFFSET (2U) + +/** + * @} + */ + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup PWREx_Exported_Functions PWR Extended Exported Functions + * @{ + */ + +/** @defgroup PWREx_Exported_Functions_Group1 Power Supply Control Functions + * @brief Power supply control functions + * +@verbatim + =============================================================================== + ##### Power supply control functions ##### + =============================================================================== + [..] +@endverbatim + * @{ + */ + +/** + * @brief Configure the system Power Supply. + * @param SupplySource : Specifies the Power Supply source to set after a + * system startup. + * This parameter can be one of the following values : + * @arg PWR_EXTERNAL_SOURCE_SUPPLY : The SMPS and the LDO are + * Bypassed. The Vcore Power + * Domains are supplied from + * external source. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_PWREx_ConfigSupply(uint32_t SupplySource) +{ + uint32_t tickstart; + + /* Check the parameters */ + assert_param(IS_PWR_SUPPLY(SupplySource)); + + if ((PWR->SCCR & PWR_SCCR_BYPASS) != (PWR_SCCR_BYPASS)) + { + /* Set the power supply configuration */ + MODIFY_REG(PWR->SCCR, PWR_SUPPLY_CONFIG_MASK, SupplySource); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait till voltage level flag is set */ + while (__HAL_PWR_GET_FLAG(PWR_FLAG_ACTVOSRDY) == 0U) + { + if ((HAL_GetTick() - tickstart) > PWR_FLAG_SETTING_DELAY) + { + return HAL_ERROR; + } + } + } + + return HAL_OK; +} + +/** + * @brief Get the power supply configuration. + * @retval The supply configuration. + */ +uint32_t HAL_PWREx_GetSupplyConfig(void) +{ + return (PWR->SCCR & PWR_SUPPLY_CONFIG_MASK); +} + +/** + * @brief Configure the main internal regulator output voltage. + * @param VoltageScaling : Specifies the regulator output voltage to achieve + * a tradeoff between performance and power + * consumption. + * This parameter can be one of the following values : + * @arg PWR_REGULATOR_VOLTAGE_SCALE0 : Regulator voltage output + * Scale 0 mode. + * @arg PWR_REGULATOR_VOLTAGE_SCALE1 : Regulator voltage output + * range 1 mode. + * @arg PWR_REGULATOR_VOLTAGE_SCALE2 : Regulator voltage output + * range 2 mode. + * @arg PWR_REGULATOR_VOLTAGE_SCALE3 : Regulator voltage output + * range 3 mode. + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_PWREx_ControlVoltageScaling(uint32_t VoltageScaling) +{ + uint32_t tickstart = HAL_GetTick(); + + /* Check the parameters */ + assert_param(IS_PWR_VOLTAGE_SCALING_RANGE(VoltageScaling)); + + /* Get the voltage scaling */ + if ((PWR->VOSSR & PWR_VOSSR_ACTVOS) == (VoltageScaling << 10U)) + { + /* Old and new voltage scaling configuration match : nothing to do */ + return HAL_OK; + } + + /* Set the voltage range */ + MODIFY_REG(PWR->VOSCR, PWR_VOSCR_VOS, VoltageScaling); + + /* Wait till voltage level flag is set */ + while (__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY) == 0U) + { + if ((HAL_GetTick() - tickstart) > PWR_FLAG_SETTING_DELAY) + { + return HAL_ERROR; + } + } + + return HAL_OK; +} + +/** + * @brief Get the main internal regulator output voltage. Reflecting the last + * VOS value applied to the PMU. + * @retval The current applied VOS selection. + */ +uint32_t HAL_PWREx_GetVoltageRange(void) +{ + /* Get the active voltage scaling */ + return (PWR->VOSSR & PWR_VOSSR_ACTVOS); +} + +/** + * @brief Configure the main internal regulator output voltage in STOP mode. + * @param VoltageScaling : Specifies the regulator output voltage when the + * system enters Stop mode to achieve a tradeoff between performance + * and power consumption. + * This parameter can be one of the following values: + * @arg PWR_REGULATOR_SVOS_SCALE3 : Regulator voltage output range + * 3 mode. + * @arg PWR_REGULATOR_SVOS_SCALE4 : Regulator voltage output range + * 4 mode. + * @arg PWR_REGULATOR_SVOS_SCALE5 : Regulator voltage output range + * 5 mode. + * @note The Stop mode voltage scaling for SVOS4 and SVOS5 sets the voltage + * regulator in Low-power (LP) mode to further reduce power consumption. + * When preselecting SVOS3, the use of the voltage regulator low-power + * mode (LP) can be selected by LPDS register bit. + * @note The selected SVOS4 and SVOS5 levels add an additional startup delay + * when exiting from system Stop mode. + * @retval HAL Status. + */ +HAL_StatusTypeDef HAL_PWREx_ControlStopModeVoltageScaling(uint32_t VoltageScaling) +{ + /* Check the parameters */ + assert_param(IS_PWR_STOP_MODE_REGULATOR_VOLTAGE(VoltageScaling)); + + /* Return the stop mode voltage range */ + MODIFY_REG(PWR->PMCR, PWR_PMCR_SVOS, VoltageScaling); + + return HAL_OK; +} + +/** + * @brief Get the main internal regulator output voltage in STOP mode. + * @retval The actual applied VOS selection. + */ +uint32_t HAL_PWREx_GetStopModeVoltageRange(void) +{ + /* Return the stop voltage scaling */ + return (PWR->PMCR & PWR_PMCR_SVOS); +} +/** + * @} + */ + +/** @defgroup PWREx_Exported_Functions_Group2 Voltage Monitoring Functions + * @brief Voltage monitoring functions + * +@verbatim + =============================================================================== + ##### Voltage Monitoring Functions ##### + =============================================================================== + [..] +@endverbatim + * @{ + */ + +/** + * @brief Configure the event mode and the voltage threshold detected by the + * Analog Voltage Detector (AVD). + * @param sConfigAVD : Pointer to an PWREx_AVDTypeDef structure that contains + * the configuration information for the AVD. + * @note Refer to the electrical characteristics of your device datasheet for + * more details about the voltage threshold corresponding to each + * detection level. + * @retval None. + */ +void HAL_PWREx_ConfigAVD(const PWREx_AVDTypeDef *sConfigAVD) +{ + /* Check the parameters */ + assert_param(IS_PWR_AVD_LEVEL(sConfigAVD->AVDLevel)); + assert_param(IS_PWR_AVD_MODE(sConfigAVD->Mode)); + + /* Set the ALS[10:9] bits according to AVDLevel value */ + MODIFY_REG(PWR->VMCR, PWR_VMCR_ALS, sConfigAVD->AVDLevel); + + /* Clear any previous config */ + __HAL_PWR_AVD_EXTI_DISABLE_EVENT(); + __HAL_PWR_AVD_EXTI_DISABLE_IT(); + __HAL_PWR_AVD_EXTI_DISABLE_RISING_EDGE(); + __HAL_PWR_AVD_EXTI_DISABLE_FALLING_EDGE(); + + /* Configure the interrupt mode */ + if ((sConfigAVD->Mode & AVD_MODE_IT) == AVD_MODE_IT) + { + __HAL_PWR_AVD_EXTI_ENABLE_IT(); + } + + /* Configure the event mode */ + if ((sConfigAVD->Mode & AVD_MODE_EVT) == AVD_MODE_EVT) + { + __HAL_PWR_AVD_EXTI_ENABLE_EVENT(); + } + + /* Rising edge configuration */ + if ((sConfigAVD->Mode & AVD_RISING_EDGE) == AVD_RISING_EDGE) + { + __HAL_PWR_AVD_EXTI_ENABLE_RISING_EDGE(); + } + + /* Falling edge configuration */ + if ((sConfigAVD->Mode & AVD_FALLING_EDGE) == AVD_FALLING_EDGE) + { + __HAL_PWR_AVD_EXTI_ENABLE_FALLING_EDGE(); + } +} + +/** + * @brief Enable the Analog Voltage Detector (AVD). + * @retval None. + */ +void HAL_PWREx_EnableAVD(void) +{ + /* Enable the Analog Voltage Detector */ + SET_BIT(PWR->VMCR, PWR_VMCR_AVDEN); +} + +/** + * @brief Disable the Analog Voltage Detector(AVD). + * @retval None. + */ +void HAL_PWREx_DisableAVD(void) +{ + /* Disable the Analog Voltage Detector */ + CLEAR_BIT(PWR->VMCR, PWR_VMCR_AVDEN); +} + +#if defined (PWR_USBSCR_USB33DEN) +/** + * @brief Enable the USB voltage level detector. + * @retval None. + */ +void HAL_PWREx_EnableUSBVoltageDetector(void) +{ + /* Enable the USB voltage detector */ + SET_BIT(PWR->USBSCR, PWR_USBSCR_USB33DEN); +} + +/** + * @brief Disable the USB voltage level detector. + * @retval None. + */ +void HAL_PWREx_DisableUSBVoltageDetector(void) +{ + /* Disable the USB voltage detector */ + CLEAR_BIT(PWR->USBSCR, PWR_USBSCR_USB33DEN); +} + +/** + * @brief Enable VDDUSB supply. + * @note Remove VDDUSB electrical and logical isolation, once VDDUSB supply + * is present for consumption saving. + * @retval None. + */ +void HAL_PWREx_EnableVddUSB(void) +{ + SET_BIT(PWR->USBSCR, PWR_USBSCR_USB33SV); +} + +/** + * @brief Disable VDDUSB supply. + * @retval None. + */ +void HAL_PWREx_DisableVddUSB(void) +{ + CLEAR_BIT(PWR->USBSCR, PWR_USBSCR_USB33SV); +} +#endif /* PWR_USBSCR_USB33DEN */ + +/** + * @brief Enable the VBAT and temperature monitoring. + * @retval None. + */ +void HAL_PWREx_EnableMonitoring(void) +{ + SET_BIT(PWR->BDCR, PWR_BDCR_MONEN); +} + +/** + * @brief Disable the VBAT and temperature monitoring. + * @retval None. + */ +void HAL_PWREx_DisableMonitoring(void) +{ + CLEAR_BIT(PWR->BDCR, PWR_BDCR_MONEN); +} + +#if defined (PWR_UCPDR_UCPD_STBY) +/** + * @brief Enable UCPD configuration memorization in Standby mode. + * @retval None. + */ +void HAL_PWREx_EnableUCPDStandbyMode(void) +{ + SET_BIT(PWR->UCPDR, PWR_UCPDR_UCPD_STBY); +} + +/** + * @brief Disable UCPD configuration memorization in Standby mode. + * @note This function must be called on exiting the Standby mode and before + * any UCPD configuration update. + * @retval None. + */ +void HAL_PWREx_DisableUCPDStandbyMode(void) +{ + CLEAR_BIT(PWR->UCPDR, PWR_UCPDR_UCPD_STBY); +} +#endif /* PWR_UCPDR_UCPD_STBY */ + +#if defined (PWR_UCPDR_UCPD_DBDIS) +/** + * @brief Enable dead battery behavior. + * @note After exiting reset, the USB Type-C (dead battery) behavior is + * enabled, which may have a pull-down effect on CC1 and CC2 pins. + * It is recommended to disable it in all cases, either to stop this + * pull-down or to handover control to the UCPD (the UCPD must be + * initialized before doing the disable). + * @retval None. + */ +void HAL_PWREx_EnableUCPDDeadBattery(void) +{ + CLEAR_BIT(PWR->UCPDR, PWR_UCPDR_UCPD_DBDIS); +} + +/** + * @brief Disable dead battery behavior. + * @note After exiting reset, the USB Type-C (dead battery) behavior is + * enabled, which may have a pull-down effect on CC1 and CC2 pins. + * It is recommended to disable it in all cases, either to stop this + * pull-down or to handover control to the UCPD (the UCPD must be + * initialized before doing the disable). + * @retval None. + */ +void HAL_PWREx_DisableUCPDDeadBattery(void) +{ + SET_BIT(PWR->UCPDR, PWR_UCPDR_UCPD_DBDIS); +} +#endif /* PWR_UCPDR_UCPD_DBDIS */ + +/** + * @brief Enable the Battery charging. + * @note When VDD is present, charge the external battery through an internal + * resistor. + * @param ResistorValue : Specifies the charging resistor. + * This parameter can be one of the following values : + * @arg PWR_BATTERY_CHARGING_RESISTOR_5 : 5 KOhm resistor. + * @arg PWR_BATTERY_CHARGING_RESISTOR_1_5 : 1.5 KOhm resistor. + * @retval None. + */ +void HAL_PWREx_EnableBatteryCharging(uint32_t ResistorValue) +{ + /* Check the parameter */ + assert_param(IS_PWR_BATTERY_RESISTOR_SELECT(ResistorValue)); + + /* Specify the charging resistor */ + MODIFY_REG(PWR->BDCR, PWR_BDCR_VBRS, ResistorValue); + + /* Enable the Battery charging */ + SET_BIT(PWR->BDCR, PWR_BDCR_VBE); +} + +/** + * @brief Disable the Battery charging. + * @retval None. + */ +void HAL_PWREx_DisableBatteryCharging(void) +{ + CLEAR_BIT(PWR->BDCR, PWR_BDCR_VBE); +} + +/** + * @brief Enable the booster to guarantee the analog switch AC performance when + * the VDD supply voltage is below 2V7. + * @note The VDD supply voltage can be monitored through the PVD and the PLS + * field bits. + * @retval None. + */ +void HAL_PWREx_EnableAnalogBooster(void) +{ + /* Enable the Analog voltage */ + SET_BIT(PWR->PMCR, PWR_PMCR_AVD_READY); + + /* Enable VDDA booster */ + SET_BIT(PWR->PMCR, PWR_PMCR_BOOSTE); +} + +/** + * @brief Disable the analog booster. + * @retval None. + */ +void HAL_PWREx_DisableAnalogBooster(void) +{ + /* Disable VDDA booster */ + CLEAR_BIT(PWR->PMCR, PWR_PMCR_BOOSTE); + + /* Disable the Analog voltage */ + CLEAR_BIT(PWR->PMCR, PWR_PMCR_AVD_READY); +} + +/** + * @brief This function handles the PWR PVD/AVD interrupt request. + * @note This API should be called under the PVD_AVD_IRQHandler(). + * @note The use of this API is when the PVD and AVD are activated at the same time. + * @retval None + */ +void HAL_PWREx_PVD_AVD_IRQHandler(void) +{ + /* Check PWR PVD AVD EXTI Rising flag */ + if (__HAL_PWR_PVD_AVD_EXTI_GET_RISING_FLAG() != 0U) + { + /* Clear PWR PVD AVD EXTI Rising pending bit */ + WRITE_REG(EXTI->RPR1, PWR_EXTI_LINE_AVD); + + /* PWR PVD AVD Rising interrupt user callback */ + HAL_PWREx_PVD_AVD_Rising_Callback(); + } + + /* Check PWR PVD AVD EXTI Falling flag */ + if (__HAL_PWR_PVD_AVD_EXTI_GET_FALLING_FLAG() != 0U) + { + /* Clear PWR PVD AVD EXTI Falling pending bit */ + WRITE_REG(EXTI->FPR1, PWR_EXTI_LINE_AVD); + + /* PWR PVD AVD Falling interrupt user callback */ + HAL_PWREx_PVD_AVD_Falling_Callback(); + } +} + +/** + * @brief PWR PVD AVD Rising interrupt callback. + * @retval None. + */ +__weak void HAL_PWREx_PVD_AVD_Rising_Callback(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PWR_AVDCallback can be implemented in the user file + */ +} + +/** + * @brief PWR PVD AVD Falling interrupt callback. + * @retval None. + */ +__weak void HAL_PWREx_PVD_AVD_Falling_Callback(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PWR_AVDCallback can be implemented in the user file + */ +} +/** + * @} + */ + +/** @defgroup PWREx_Exported_Functions_Group3 Wakeup Pins configuration Functions + * @brief Wakeup Pins configuration functions + * +@verbatim + =============================================================================== + ##### Wakeup Pins configuration Functions ##### + =============================================================================== + [..] +@endverbatim + * @{ + */ + +/** + * @brief Enable the Wake-up PINx functionality. + * @param sPinParams : Pointer to a PWREx_WakeupPinTypeDef structure that + * contains the configuration information for the wake-up + * Pin. + * @retval None. + */ +void HAL_PWREx_EnableWakeUpPin(const PWREx_WakeupPinTypeDef *sPinParams) +{ + uint32_t pinConfig; + uint32_t regMask; + const uint32_t pullMask = PWR_WUCR_WUPPUPD1; + + /* Check the parameters */ + assert_param(IS_PWR_WAKEUP_PIN(sPinParams->WakeUpPin)); + assert_param(IS_PWR_WAKEUP_PIN_POLARITY(sPinParams->PinPolarity)); + assert_param(IS_PWR_WAKEUP_PIN_PULL(sPinParams->PinPull)); + + pinConfig = sPinParams->WakeUpPin | \ + (sPinParams->PinPolarity << ((POSITION_VAL(sPinParams->WakeUpPin) + PWR_WUCR_WUPP1_Pos) & 0x1FU)) | \ + (sPinParams->PinPull << (((POSITION_VAL(sPinParams->WakeUpPin) * PWR_WAKEUP_PINS_PULL_SHIFT_OFFSET) \ + + PWR_WUCR_WUPPUPD1_Pos) & 0x1FU)); + + regMask = sPinParams->WakeUpPin | \ + (PWR_WUCR_WUPP1 << (POSITION_VAL(sPinParams->WakeUpPin) & 0x1FU)) | \ + (pullMask << ((POSITION_VAL(sPinParams->WakeUpPin) * PWR_WAKEUP_PINS_PULL_SHIFT_OFFSET) & 0x1FU)); + + /* Enable and Specify the Wake-Up pin polarity and the pull configuration + for the event detection (rising or falling edge) */ + MODIFY_REG(PWR->WUCR, regMask, pinConfig); +} + +/** + * @brief Disable the Wake-up PINx functionality. + * @param WakeUpPinx : Specifies the Wake-Up pin to be disabled. + * This parameter can be one of the following values: + * @arg PWR_WAKEUP_PIN1 + * @arg PWR_WAKEUP_PIN2 + * @arg PWR_WAKEUP_PIN3 + * @arg PWR_WAKEUP_PIN4 + * @arg PWR_WAKEUP_PIN5 + * @arg PWR_WAKEUP_PIN6 + * @arg PWR_WAKEUP_PIN7 + * @arg PWR_WAKEUP_PIN8 + * @note The PWR_WAKEUP_PIN6, PWR_WAKEUP_PIN7 and PWR_WAKEUP_PIN8 are not available for + * STM32H503xx devices. + * @retval None + */ +void HAL_PWREx_DisableWakeUpPin(uint32_t WakeUpPinx) +{ + /* Check the parameter */ + assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx)); + + /* Disable the WakeUpPin */ + CLEAR_BIT(PWR->WUCR, (PWR_WUCR_WUPEN & WakeUpPinx)); +} + +/** + * @} + */ + +/** @defgroup PWREx_Exported_Functions_Group4 Memories Retention Functions + * @brief Memories retention functions + * +@verbatim + =============================================================================== + ##### Memories Retention Functions ##### + =============================================================================== + [..] +@endverbatim + * @{ + */ + +/** + * @brief Enable the Flash Power Down in Stop mode. + * @note When Flash Power Down is enabled the Flash memory enters low-power + * mode. This feature allows to + * obtain the best trade-off between low-power consumption and restart + * time when exiting from Stop mode. + * @retval None. + */ +void HAL_PWREx_EnableFlashPowerDown(void) +{ + /* Enable the Flash Power Down */ + SET_BIT(PWR->PMCR, PWR_PMCR_FLPS); +} + +/** + * @brief Disable the Flash Power Down in Stop mode. + * @note When Flash Power Down is disabled the Flash memory is kept on + * normal mode. This feature allows + * to obtain the best trade-off between low-power consumption and + * restart time when exiting from Stop mode. + * @retval None. + */ +void HAL_PWREx_DisableFlashPowerDown(void) +{ + /* Disable the Flash Power Down */ + CLEAR_BIT(PWR->PMCR, PWR_PMCR_FLPS); +} + +/** + * @brief Enable memory block shut-off in Stop mode + * @note In Stop mode, the content of the memory blocks is + * maintained. Further power optimization can be obtained by switching + * off some memory blocks. This optimization implies loss of the memory + * content. The user can select which memory is discarded during STOP + * mode by means of xxSO bits. + * @param MemoryBlock : Specifies the memory block to shut-off during Stop mode. + * This parameter can be one of the following values: + * @arg PWR_ETHERNET_MEMORY_BLOCK PWR_PMCR_ETHERNETSO : Ethernet shut-off control in Stop mode + * @arg PWR_RAM3_MEMORY_BLOCK PWR_PMCR_SRAM3SO : RAM3 shut-off control in Stop mode + * @arg PWR_RAM2_16_MEMORY_BLOCK PWR_PMCR_SRAM2_16SO : RAM2 16k byte shut-off control in Stop mode + * @arg PWR_RAM2_48_MEMORY_BLOCK PWR_PMCR_SRAM2_48SO : RAM2 48k byte shut-off control in Stop mode + * @arg PWR_RAM1_MEMORY_BLOCK PWR_PMCR_SRAM1SO : RAM1 shut-off control in Stop mode + * @note The PWR_ETHERNET_MEMORY_BLOCK is not available for STM32H503xx devices. + * @retval None. + */ +void HAL_PWREx_EnableMemoryShutOff(uint32_t MemoryBlock) +{ + /* Check the parameter */ + assert_param(IS_PWR_MEMORY_BLOCK(MemoryBlock)); + + /* Enable memory block shut-off */ + SET_BIT(PWR->PMCR, MemoryBlock); +} + +/** + * @brief Disable memory block shut-off in Stop mode + * @param MemoryBlock : Specifies the memory block to keep content during + * Stop mode. + * This parameter can be one of the following values: + * @arg PWR_ETHERNET_MEMORY_BLOCK PWR_PMCR_ETHERNETSO : Ethernet shut-off control in Stop mode + * @arg PWR_RAM3_MEMORY_BLOCK PWR_PMCR_SRAM3SO : RAM3 shut-off control in Stop mode + * @arg PWR_RAM2_16_MEMORY_BLOCK PWR_PMCR_SRAM2_16SO : RAM2 16k byte shut-off control in Stop mode + * @arg PWR_RAM2_48_MEMORY_BLOCK PWR_PMCR_SRAM2_48SO : RAM2 48k byte shut-off control in Stop mode + * @arg PWR_RAM1_MEMORY_BLOCK PWR_PMCR_SRAM1SO : RAM1 shut-off control in Stop mode + * @note The PWR_ETHERNET_MEMORY_BLOCK is not available for STM32H503xx devices. + * @retval None. + */ +void HAL_PWREx_DisableMemoryShutOff(uint32_t MemoryBlock) +{ + /* Check the parameter */ + assert_param(IS_PWR_MEMORY_BLOCK(MemoryBlock)); + + /* Disable memory block shut-off */ + CLEAR_BIT(PWR->PMCR, MemoryBlock); +} + +/** + * @brief Enable the Backup RAM retention in Standby and VBAT modes. + * @note If BREN is reset, the backup RAM can still be used in Run, Sleep and + * Stop modes. However, its content is lost in Standby, Shutdown and + * VBAT modes. This bit can be writte + * @retval None. + */ +HAL_StatusTypeDef HAL_PWREx_EnableBkupRAMRetention(void) +{ + SET_BIT(PWR->BDCR, PWR_BDCR_BREN); + + return HAL_OK; +} + +/** + * @brief Disable the Backup RAM retention in Standby and VBAT modes. + * @note If BREN is reset, the backup RAM can still be used in Run, Sleep and + * Stop modes. However, its content is lost in Standby, Shutdown and + * VBAT modes. This bit can be write + * @retval None. + */ +void HAL_PWREx_DisableBkupRAMRetention(void) +{ + CLEAR_BIT(PWR->BDCR, PWR_BDCR_BREN); +} +/** + * @} + */ + +/** @defgroup PWREx_Exported_Functions_Group5 IO and JTAG Retention Functions + * @brief IO and JTAG Retention functions + * +@verbatim + =============================================================================== + ##### IO and JTAG Retention Functions ##### + =============================================================================== + [..] + In the Standby mode, the I/Os are by default in floating state. If the IORETEN bit in the + PWR_IORETR register is set, the I/Os output state is retained. IO Retention mode is + enabled for all IO except the IO support the standby functionality and JTAG IOs (PA13, + PA14, PA15 and PB4). When entering into Standby mode, the state of the output is + sampled, and pull-up or pull-down resistor are set to maintain the IO output during Standby + mode. + If the JTAGIORETEN bit in the PWR_IORETR register is set, the I/Os output state is + retained. IO Retention mode is enabled for PA13, PA14, PA15 and PB4 (default JTAG pullup/ + pull-down after wakeup are not enabled). +@endverbatim + * @{ + */ + +/** + * @brief Enable GPIO state retention in Standby mode. + * @note When entering into standby mode, the output is sampled, and applied to the output IO during + * the standby power mode + * @retval None. + */ +void HAL_PWREx_EnableStandbyIORetention(void) +{ + /* Enable GPIO state retention */ + SET_BIT(PWR->IORETR, PWR_IORETR_IORETEN); +} + +/** + * @brief Disable GPIO state retention in Standby mode. + * @retval None. + */ +void HAL_PWREx_DisableStandbyIORetention(void) +{ + /* Disable GPIO state retention */ + CLEAR_BIT(PWR->IORETR, PWR_IORETR_IORETEN); +} + +/** + * @brief Enable JTAG IOs state retention in Standby mode. + * @note when entering into standby mode, the output is sampled, and applied to the output IO during + * the standby power mode + * @retval None. + */ +void HAL_PWREx_EnableStandbyJTAGIORetention(void) +{ + /* Enable JTAG IOs state retention */ + SET_BIT(PWR->IORETR, PWR_IORETR_JTAGIORETEN); +} + +/** + * @brief Disable JTAG IOs state retention in Standby mode. + * @retval None. + */ +void HAL_PWREx_DisableStandbyJTAGIORetention(void) +{ + /* Enable JTAG IOs state retention */ + CLEAR_BIT(PWR->IORETR, PWR_IORETR_JTAGIORETEN); +} + +/** + * @} + */ +#endif /* defined (HAL_PWR_MODULE_ENABLED) */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_ramcfg.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_ramcfg.c new file mode 100644 index 0000000000..c66d70d6db --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_ramcfg.c @@ -0,0 +1,1084 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_ramcfg.c + * @author MCD Application Team + * @brief RAMCFG HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the RAMs configuration controller peripheral: + * + RAMCFG Initialization and De-initialization Functions. + * + RAMCFG ECC Operation Functions. + * + RAMCFG Configure Wait State Functions. + * + RAMCFG Write Protection Functions. + * + RAMCFG Erase Operation Functions. + * + RAMCFG Handle Interrupt and Callbacks Functions. + * + RAMCFG State and Error Functions. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### RAMCFG Peripheral features ##### + ============================================================================== + [..] + (+) Each SRAM is managed by a RAMCFG instance. + + (+) Each SRAM can be erased independently through its RAMCFG instance. + + (+) The wait state value for each SRAM can be configured independently + through its RAMCFG instance. + + (+) SRAM2 is divided to 64 pages with 1 kB granularity. Each page can be + write protected independently through its RAMCFG instance. + + (+) SRAM2, SRAM3 and BKPRAM support ECC correction feature. This mechanism + adopts the Single Error Correction Double Error Detection (SECDED) + algorithm. This feature provides the following information: + (++) Single error address. + (++) Double error address. + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Call HAL_RAMCFG_Init() to initialize the RAMCFG peripheral before using + any feature. Call HAL_RAMCFG_DeInit() to de-initialize the RAMCFG when + using this peripheral is no more needed or a hardware issue has occurred. + (+) HAL_RAMCFG_Init() and HAL_RAMCFG_DeInit() APIs do not change the + activation status of ECC feature. It is managed by + HAL_RAMCFG_StartECC(), HAL_RAMCFG_StopECC() or option bytes (When + available on the device). + + *** ECC feature *** + =================== + [..] + (+) Call HAL_RAMCFG_StartECC() and HAL_RAMCFG_StopECC() to enable and + disable ECC hardware mechanism. + (++) When ECC feature is previously enabled (case of option + byte activation), calling HAL_RAMCFG_StartECC() is + recommended to enable the ECC address latching feature. + + (+) Call HAL_RAMCFG_EnableNotification() and HAL_RAMCFG_DisableNotification() + to enable and disable ECC interrupts. Interrupts can be: + (++) Single error interrupt. + (++) Double error interrupt. + (++) Double error interrupt redirected to Non maskable + interrupt (NMI). + + (+) Call HAL_RAMCFG_GetSingleErrorAddress() to get the address of the + last fail RAM word detected (only for single error) and + call HAL_RAMCFG_GetDoubleErrorAddress() to get the address of the + last fail RAM word detected (only for double error). + + (+) Call HAL_RAMCFG_IsECCErrorDetected() to check if an ECC single/double + error was detected. This API is used in silent mode (No ECC interrupt + is enabled). + + *** Write protection feature *** + ================================ + [..] + (+) Call HAL_RAMCFG_EnableWriteProtection() to enable the write + protection for the given SRAM2 page(s). + + (+) There is no API to disable write protection as this feature can + be disabled only by a global peripheral reset or system reset. + + (+) Any write access to a write protected area of SRAM2 causes a + HardFault interrupt. + + *** Erase feature *** + ===================== + [..] + (+) Call HAL_RAMCFG_Erase() to launch a hardware erase for the given + SRAM. + + (+) The erase value is equal to 0 when launching erase hardware through + RAMCFG. + + (+) SRAM2 write protected pages are erased when performing an erase + through RAMCFG. + + *** RAMCFG HAL driver macros list *** + ===================================== + [..] + Below the list of used macros in RAMCFG HAL driver. + + (+) __HAL_RAMCFG_ENABLE_IT : Enable the specified RAMCFG interrupts. + (+) __HAL_RAMCFG_DISABLE_IT : Disable the specified RAMCFG interrupts. + (+) __HAL_RAMCFG_GET_FLAG : Get the RAMCFG pending flags. + (+) __HAL_RAMCFG_CLEAR_FLAG : Clear the RAMCFG pending flags. + (+) __HAL_RAMCFG_GET_IT_SOURCE : Check whether the specified RAMCFG + interrupt source is enabled or not. + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup RAMCFG RAMCFG + * @brief RAMCFG HAL module driver + * @{ + */ + +#ifdef HAL_RAMCFG_MODULE_ENABLED + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ + +/** @addtogroup RAMCFG_Private_Constants + * @{ + */ +#define RAMCFG_TIMEOUT_VALUE 50000U +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup RAMCFG_Exported_Functions + * @{ + */ + +/** @addtogroup RAMCFG_Exported_Functions_Group1 + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization Functions ##### + =============================================================================== + [..] + This section provides functions allowing to initialize and de-initialize the + RAMCFG instance. + [..] + The HAL_RAMCFG_Init() function follows the RAMCFG instance configuration + procedures as described in the reference manual. + The HAL_RAMCFG_DeInit() function allows to deinitialize the RAMCFG instance. + HAL_RAMCFG_Init() and HAL_RAMCFG_DeInit() APIs do not change the activation + status of ECC feature. It is managed by HAL_RAMCFG_StartECC(), + HAL_RAMCFG_StopECC() or option bytes (When available on the device). + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the RAMCFG by clearing flags and disabling interrupts. + * @param hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that contains + * the configuration information for the specified RAMCFG + * instance. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_RAMCFG_Init(RAMCFG_HandleTypeDef *hramcfg) +{ + /* Check the RAMCFG peripheral handle */ + if (hramcfg == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_RAMCFG_ALL_INSTANCE(hramcfg->Instance)); + + /* Update RAMCFG peripheral state */ + hramcfg->State = HAL_RAMCFG_STATE_BUSY; + +#if (USE_HAL_RAMCFG_REGISTER_CALLBACKS == 1) + /* Check if a valid MSP API was registered */ + if (hramcfg->MspInitCallback == NULL) + { + /* Init the low level hardware */ + hramcfg->MspInitCallback = HAL_RAMCFG_MspInit; + } + + /* Init the low level hardware */ + hramcfg->MspInitCallback(hramcfg); +#else + HAL_RAMCFG_MspInit(hramcfg); +#endif /* USE_HAL_RAMCFG_REGISTER_CALLBACKS */ + + /* Disable the ECC Address latch */ + hramcfg->Instance->CR &= ~(RAMCFG_CR_ALE); + + /* Disable all RAMCFG interrupts */ + __HAL_RAMCFG_DISABLE_IT(hramcfg, RAMCFG_IT_ALL); + + /* Clear RAMCFG monitor flags */ + __HAL_RAMCFG_CLEAR_FLAG(hramcfg, RAMCFG_FLAGS_ALL); + + /* Initialise the RAMCFG error code */ + hramcfg->ErrorCode = HAL_RAMCFG_ERROR_NONE; + + /* Initialize the RAMCFG state */ + hramcfg->State = HAL_RAMCFG_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitialize the RAMCFG peripheral. + * @param hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that contains + * the configuration information for the specified RAMCFG + * instance. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_RAMCFG_DeInit(RAMCFG_HandleTypeDef *hramcfg) +{ + /* Check the RAMCFG peripheral handle */ + if (hramcfg == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_RAMCFG_ALL_INSTANCE(hramcfg->Instance)); + + /* Disable the ECC Address latch */ + hramcfg->Instance->CR &= ~(RAMCFG_CR_ALE); + + /* Disable all RAMCFG interrupts */ + __HAL_RAMCFG_DISABLE_IT(hramcfg, RAMCFG_IT_ALL); + + /* Clear RAMCFG monitor flags */ + __HAL_RAMCFG_CLEAR_FLAG(hramcfg, RAMCFG_FLAGS_ALL); + +#if (USE_HAL_RAMCFG_REGISTER_CALLBACKS == 1) + /* Check if a valid MSP API was registered */ + if (hramcfg->MspDeInitCallback != NULL) + { + /* Init the low level hardware */ + hramcfg->MspDeInitCallback(hramcfg); + } + + /* Clean callbacks */ + hramcfg->DetectSingleErrorCallback = NULL; + hramcfg->DetectDoubleErrorCallback = NULL; +#else + HAL_RAMCFG_MspDeInit(hramcfg); +#endif /* USE_HAL_RAMCFG_REGISTER_CALLBACKS */ + + /* Reset the RAMCFG error code */ + hramcfg->ErrorCode = HAL_RAMCFG_ERROR_NONE; + + /* Reset the RAMCFG state */ + hramcfg->State = HAL_RAMCFG_STATE_RESET; + + return HAL_OK; +} + +/** + * @brief Initialize the RAMCFG MSP. + * @param hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that contains + * the configuration information for the specified RAMCFG. + * @retval None. + */ +__weak void HAL_RAMCFG_MspInit(RAMCFG_HandleTypeDef *hramcfg) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hramcfg); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RAMCFG_MspInit can be implemented in the user file */ +} + +/** + * @brief DeInitialize the RAMCFG MSP. + * @param hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that contains + * the configuration information for the specified RAMCFG. + * @retval None. + */ +__weak void HAL_RAMCFG_MspDeInit(RAMCFG_HandleTypeDef *hramcfg) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hramcfg); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RAMCFG_MspDeInit can be implemented in the user file */ +} +/** + * @} + */ + +/** @addtogroup RAMCFG_Exported_Functions_Group2 + * +@verbatim + =============================================================================== + ##### ECC Operations Functions ##### + =============================================================================== + [..] + This section provides functions allowing to manage ECC feature provided by + the RAMCFG peripheral. + [..] + The HAL_RAMCFG_StartECC() function allows starting the ECC mechanism and + enabling ECC address latching for the selected RAMCFG instance. + The HAL_RAMCFG_StopECC() function allows stopping the ECC mechanism and + disabling ECC address latching for the selected RAMCFG instance. + The HAL_RAMCFG_EnableNotification() function allows enabling interrupts + for single ECC error, double ECC error and NMI error. + The HAL_RAMCFG_DisableNotification() function allows disabling interrupts + for single ECC error, double ECC error. When NMI interrupt is enabled it + can only be disabled by a global peripheral reset or by a system reset. + The HAL_RAMCFG_IsECCErrorDetected() function allows to check if an ECC error + has occurred. + The HAL_RAMCFG_GetSingleErrorAddress() function allows to get the address of + the last single ECC error detected. + The HAL_RAMCFG_GetDoubleErrorAddress() function allows to get the address of + the last double ECC error detected. + +@endverbatim + * @{ + */ + +/** + * @brief Start ECC mechanism for the given SRAM. + * @param hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that contains + * the configuration information for the specified RAMCFG + * instance. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_RAMCFG_StartECC(RAMCFG_HandleTypeDef *hramcfg) +{ + HAL_StatusTypeDef status = HAL_OK; + /* Check the parameters */ + assert_param(IS_RAMCFG_ECC_INSTANCE(hramcfg->Instance)); + + /* Check RAMCFG state */ + if (hramcfg->State == HAL_RAMCFG_STATE_READY) + { + /* Update RAMCFG peripheral state */ + hramcfg->State = HAL_RAMCFG_STATE_BUSY; + + /* Check if ECC mechanism is non active */ + if ((hramcfg->Instance->CR & RAMCFG_CR_ECCE) != RAMCFG_CR_ECCE) + { + /* Start the SRAM ECC mechanism and latching the error address */ + hramcfg->Instance->CR |= (RAMCFG_CR_ECCE | RAMCFG_CR_ALE); + + /* Update the RAMCFG state */ + hramcfg->State = HAL_RAMCFG_STATE_READY; + } + } + else + { + /* Update the RAMCFG error code and return error */ + hramcfg->ErrorCode = HAL_RAMCFG_ERROR_BUSY; + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Stop ECC mechanism for the given SRAM. + * @param hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that contains + * the configuration information for the specified RAMCFG + * instance. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_RAMCFG_StopECC(RAMCFG_HandleTypeDef *hramcfg) +{ + HAL_StatusTypeDef status = HAL_OK; + /* Check the parameters */ + assert_param(IS_RAMCFG_ECC_INSTANCE(hramcfg->Instance)); + + /* Check RAMCFG state */ + if (hramcfg->State == HAL_RAMCFG_STATE_READY) + { + /* Update RAMCFG peripheral state */ + hramcfg->State = HAL_RAMCFG_STATE_BUSY; + + /* Check if ECC mechanism is active */ + if ((hramcfg->Instance->CR & RAMCFG_CR_ECCE) == RAMCFG_CR_ECCE) + { + /* Unlock the SRAM ECC bit */ + WRITE_REG(hramcfg->Instance->ECCKEY, RAMCFG_ECC_KEY1); + WRITE_REG(hramcfg->Instance->ECCKEY, RAMCFG_ECC_KEY2); + + /* Stop the SRAM ECC mechanism and latching the error address */ + hramcfg->Instance->CR &= ~(RAMCFG_CR_ECCE | RAMCFG_CR_ALE); + + /* Update the RAMCFG state */ + hramcfg->State = HAL_RAMCFG_STATE_READY; + } + } + else + { + /* Update the RAMCFG error code and return error */ + hramcfg->ErrorCode = HAL_RAMCFG_ERROR_BUSY; + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Enable the RAMCFG error interrupts. + * @param hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that + * contains the configuration information for the + * specified RAMCFG instance. + * @param Notifications : Select the notification to be enabled. + * This parameter can be any value of @ref + * RAMCFG_Interrupt group. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_RAMCFG_EnableNotification(RAMCFG_HandleTypeDef *hramcfg, uint32_t Notifications) +{ + HAL_StatusTypeDef status = HAL_OK; + /* Check the parameters */ + assert_param(IS_RAMCFG_ECC_INSTANCE(hramcfg->Instance)); + assert_param(IS_RAMCFG_INTERRUPT(Notifications)); + + /* Check RAMCFG state */ + if (hramcfg->State == HAL_RAMCFG_STATE_READY) + { + /* Update RAMCFG peripheral state */ + hramcfg->State = HAL_RAMCFG_STATE_BUSY; + + /* Enable RAMCFG interrupts */ + __HAL_RAMCFG_ENABLE_IT(hramcfg, Notifications); + + /* Update the RAMCFG state */ + hramcfg->State = HAL_RAMCFG_STATE_READY; + + } + else + { + /* Update the RAMCFG error code and return error */ + hramcfg->ErrorCode = HAL_RAMCFG_ERROR_BUSY; + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Disable the RAMCFG error interrupts. + * @param hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that + * contains the configuration information for the + * specified RAMCFG instance. + * @param Notifications : Select the notification to be disabled. + * This parameter can be : + * RAMCFG_IT_SINGLEERR : Single Error Interrupt. + * RAMCFG_IT_DOUBLEERR : Double Error Interrupt. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_RAMCFG_DisableNotification(RAMCFG_HandleTypeDef *hramcfg, uint32_t Notifications) +{ + HAL_StatusTypeDef status = HAL_OK; + /* Check the parameters */ + assert_param(IS_RAMCFG_ECC_INSTANCE(hramcfg->Instance)); + assert_param(IS_RAMCFG_INTERRUPT(Notifications)); + + /* Check RAMCFG state */ + if (hramcfg->State == HAL_RAMCFG_STATE_READY) + { + /* Update RAMCFG peripheral state */ + hramcfg->State = HAL_RAMCFG_STATE_BUSY; + + /* Disable RAMCFG interrupts */ + __HAL_RAMCFG_DISABLE_IT(hramcfg, Notifications); + + /* Update the RAMCFG state */ + hramcfg->State = HAL_RAMCFG_STATE_READY; + } + else + { + /* Update the RAMCFG error code and return error */ + hramcfg->ErrorCode = HAL_RAMCFG_ERROR_BUSY; + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Check if an ECC single error has occurred. + * @param hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that + * contains the configuration information for the + * specified RAMCFG instance. + * @retval State of bit (1 or 0). + */ +uint32_t HAL_RAMCFG_IsECCSingleErrorDetected(const RAMCFG_HandleTypeDef *hramcfg) +{ + /* Check the parameters */ + assert_param(IS_RAMCFG_ECC_INSTANCE(hramcfg->Instance)); + + /* Return the state of SEDC flag */ + return ((READ_BIT(hramcfg->Instance->ISR, RAMCFG_FLAG_SINGLEERR) == (RAMCFG_FLAG_SINGLEERR)) ? 1UL : 0UL); +} + +/** + * @brief Check if an ECC double error was occurred. + * @param hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that + * contains the configuration information for the + * specified RAMCFG instance. + * @retval State of bit (1 or 0). + */ +uint32_t HAL_RAMCFG_IsECCDoubleErrorDetected(const RAMCFG_HandleTypeDef *hramcfg) +{ + /* Check the parameters */ + assert_param(IS_RAMCFG_ECC_INSTANCE(hramcfg->Instance)); + + /* Return the state of DEDC flag */ + return ((READ_BIT(hramcfg->Instance->ISR, RAMCFG_FLAG_DOUBLEERR) == (RAMCFG_FLAG_DOUBLEERR)) ? 1UL : 0UL); +} + +/** + * @brief Get the RAMCFG single error address. + * @param hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that + * contains the configuration information for the + * specified RAMCFG instance. + * @retval Single error address offset. + */ +uint32_t HAL_RAMCFG_GetSingleErrorAddress(const RAMCFG_HandleTypeDef *hramcfg) +{ + /* Check the parameters */ + assert_param(IS_RAMCFG_ECC_INSTANCE(hramcfg->Instance)); + + return hramcfg->Instance->SEAR; +} + +/** + * @brief Get the RAMCFG double error address. + * @param hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that + * contains the configuration information for the + * specified RAMCFG instance. + * @retval Double error address offset. + */ +uint32_t HAL_RAMCFG_GetDoubleErrorAddress(const RAMCFG_HandleTypeDef *hramcfg) +{ + /* Check the parameters */ + assert_param(IS_RAMCFG_ECC_INSTANCE(hramcfg->Instance)); + + return hramcfg->Instance->DEAR; +} +/** + * @} + */ + +/** @addtogroup RAMCFG_Exported_Functions_Group4 + * +@verbatim + =============================================================================== + ##### Write Protection Functions ##### + =============================================================================== + [..] + This section provides functions to enable write protection feature for + the page(s) of SRAM2. + [..] + The HAL_RAMCFG_EnableWriteProtection() function allows the user to enable the write + protection for the page(s) of SRAM2. + Disabling SRAM2 page(s) protection is performed only by a global + peripheral reset or a by a system reset. + +@endverbatim + * @{ + */ + +/** + * @brief Enable write protection for the given page(s). + * Write protection feature can be disabled only by system reset. + * @param hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that + * contains the configuration information for the + * specified RAMCFG instance. + * @param StartPage : Select the start page number. + * @param NbPage : Number of page to be protected. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_RAMCFG_EnableWriteProtection(RAMCFG_HandleTypeDef *hramcfg, uint32_t StartPage, uint32_t NbPage) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t page_mask_0 = 0U; + uint32_t page_mask_1 = 0U; + + /* Check the parameters */ + assert_param(IS_RAMCFG_WP_INSTANCE(hramcfg->Instance)); + assert_param(IS_RAMCFG_WRITEPROTECTION_PAGE(StartPage + NbPage)); + + /* Check RAMCFG state */ + if (hramcfg->State == HAL_RAMCFG_STATE_READY) + { + /* Update RAMCFG peripheral state */ + hramcfg->State = HAL_RAMCFG_STATE_BUSY; + + /* Repeat for page number to be protected */ + for (uint32_t count = 0U; count < NbPage; count++) + { + if ((StartPage + count) < 32U) + { + page_mask_0 |= (1UL << (StartPage + count)); + } + else + { + page_mask_1 |= (1UL << ((StartPage + count) - 32U)); + } + } + + /* Apply mask to protect pages */ + SET_BIT(hramcfg->Instance->WPR1, page_mask_0); + SET_BIT(hramcfg->Instance->WPR2, page_mask_1); + + /* Update the RAMCFG state */ + hramcfg->State = HAL_RAMCFG_STATE_READY; + } + else + { + /* Update the RAMCFG error code and return error */ + hramcfg->ErrorCode = HAL_RAMCFG_ERROR_BUSY; + status = HAL_ERROR; + } + + return status; +} +/** + * @} + */ + +/** @addtogroup RAMCFG_Exported_Functions_Group5 + * +@verbatim + =============================================================================== + ##### Erase Operation Functions ##### + =============================================================================== + [..] + This section provides functions allowing a hardware erase for the given SRAM. + [..] + The HAL_RAMCFG_Erase() function allows a hardware mass erase for the given + SRAM. The erase value for all SRAMs is 0. + +@endverbatim + * @{ + */ + +/** + * @brief Launch a Mass Erase for the given SRAM. + * @param hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that + * contains the configuration information for the + * specified RAMCFG instance. + + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_RAMCFG_Erase(RAMCFG_HandleTypeDef *hramcfg) +{ + uint32_t tickstart = HAL_GetTick(); + + /* Check the parameters */ + assert_param(IS_RAMCFG_ALL_INSTANCE(hramcfg->Instance)); + + /* Check RAMCFG state */ + if (hramcfg->State == HAL_RAMCFG_STATE_READY) + { + /* Update RAMCFG peripheral state */ + hramcfg->State = HAL_RAMCFG_STATE_BUSY; + + /* Unlock the RAMCFG erase bit */ + WRITE_REG(hramcfg->Instance->ERKEYR, RAMCFG_ERASE_KEY1); + WRITE_REG(hramcfg->Instance->ERKEYR, RAMCFG_ERASE_KEY2); + + /* Start the SRAM erase operation */ + hramcfg->Instance->CR |= RAMCFG_CR_SRAMER; + + /* + Wait for the SRAM hardware erase operation to complete by polling on + SRAMBUSY flag to be reset. + */ + while (__HAL_RAMCFG_GET_FLAG(hramcfg, RAMCFG_FLAG_SRAMBUSY) != 0U) + { + if ((HAL_GetTick() - tickstart) > RAMCFG_TIMEOUT_VALUE) + { + /* Update the RAMCFG error code */ + hramcfg->ErrorCode = HAL_RAMCFG_ERROR_TIMEOUT; + + /* Update the RAMCFG state and return error status */ + hramcfg->State = HAL_RAMCFG_STATE_ERROR; + return HAL_ERROR; + } + } + } + else + { + /* Update the error code and return error status */ + hramcfg->ErrorCode = HAL_RAMCFG_ERROR_BUSY; + return HAL_ERROR; + } + + /* Update the RAMCFG state */ + hramcfg->State = HAL_RAMCFG_STATE_READY; + + return HAL_OK; +} +/** + * @} + */ + +/** @addtogroup RAMCFG_Exported_Functions_Group6 + * +@verbatim + =============================================================================== + ##### Handle Interrupt and Callbacks Functions ##### + =============================================================================== + [..] + This section provides functions to handle RAMCFG interrupts and + Register / UnRegister the different callbacks. + [..] + The HAL_RAMCFG_IRQHandler() function allows the user to handle the active RAMCFG + interrupt request. + The HAL_RAMCFG_RegisterCallback() function allows the user to register the selected + RAMCFG callbacks. + The HAL_RAMCFG_UnRegisterCallback() function allows the user to unregister the + selected RAMCFG callbacks. +@endverbatim + * @{ + */ + +/** + * @brief Handles RAMCFG interrupt request. + * @param hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that + * contains the configuration information for the + * specified RAMCFG instance. + * @retval None. + */ +void HAL_RAMCFG_IRQHandler(RAMCFG_HandleTypeDef *hramcfg) +{ + /* Single Error Interrupt Management ****************************************/ + if (__HAL_RAMCFG_GET_IT_SOURCE(hramcfg, RAMCFG_IT_SINGLEERR) != 0U) + { + if (__HAL_RAMCFG_GET_FLAG(hramcfg, RAMCFG_FLAG_SINGLEERR) != 0U) + { + /* Clear active flags */ + __HAL_RAMCFG_CLEAR_FLAG(hramcfg, RAMCFG_FLAG_SINGLEERR); + +#if (USE_HAL_RAMCFG_REGISTER_CALLBACKS == 1) + /* Check if a valid single error callback is registered */ + if (hramcfg->DetectSingleErrorCallback != NULL) + { + /* Single error detection callback */ + hramcfg->DetectSingleErrorCallback(hramcfg); + } +#else + HAL_RAMCFG_DetectSingleErrorCallback(hramcfg); +#endif /* USE_HAL_RAMCFG_REGISTER_CALLBACKS */ + } + } + + /* Double Error Interrupt Management ****************************************/ + if (__HAL_RAMCFG_GET_IT_SOURCE(hramcfg, RAMCFG_IT_DOUBLEERR) != 0U) + { + if (__HAL_RAMCFG_GET_FLAG(hramcfg, RAMCFG_FLAG_DOUBLEERR) != 0U) + { + /* Clear active flags */ + __HAL_RAMCFG_CLEAR_FLAG(hramcfg, RAMCFG_FLAG_DOUBLEERR); + +#if (USE_HAL_RAMCFG_REGISTER_CALLBACKS == 1) + /* Check if a valid double error callback is registered */ + if (hramcfg->DetectDoubleErrorCallback != NULL) + { + /* Double error detection callback */ + hramcfg->DetectDoubleErrorCallback(hramcfg); + } +#else + HAL_RAMCFG_DetectDoubleErrorCallback(hramcfg); +#endif /* USE_HAL_RAMCFG_REGISTER_CALLBACKS */ + } + } +} + +/** + * @brief RAMCFG single error detection callback. + * @param hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that contains + * the configuration information for the specified RAMCFG. + * @retval None. + */ +__weak void HAL_RAMCFG_DetectSingleErrorCallback(RAMCFG_HandleTypeDef *hramcfg) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hramcfg); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RAMCFG_DetectSingleErrorCallback can be implemented in + the user file. */ +} + +/** + * @brief RAMCFG double error detection callback. + * @param hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that contains + * the configuration information for the specified RAMCFG. + * @retval None. + */ +__weak void HAL_RAMCFG_DetectDoubleErrorCallback(RAMCFG_HandleTypeDef *hramcfg) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hramcfg); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RAMCFG_DetectDoubleErrorCallback can be implemented in + the user file. */ +} + +#if (USE_HAL_RAMCFG_REGISTER_CALLBACKS == 1) +/** + * @brief Register RAMCFG callbacks. + * @param hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that + * contains the configuration information for the + * specified RAMCFG instance. + * @param CallbackID : User Callback identifier a HAL_RAMCFG_CallbackIDTypeDef + * ENUM as parameter. + * @param pCallback : Pointer to private callback function. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_RAMCFG_RegisterCallback(RAMCFG_HandleTypeDef *hramcfg, + HAL_RAMCFG_CallbackIDTypeDef CallbackID, + void (* pCallback)(RAMCFG_HandleTypeDef *_hramcfg)) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_RAMCFG_ALL_INSTANCE(hramcfg->Instance)); + + if (pCallback == NULL) + { + /* Update the error code and return error */ + hramcfg->ErrorCode |= HAL_RAMCFG_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + + /* Check RAMCFG state */ + if (hramcfg->State == HAL_RAMCFG_STATE_READY) + { + switch (CallbackID) + { + case HAL_RAMCFG_SE_DETECT_CB_ID: + /* Register single error callback */ + hramcfg->DetectSingleErrorCallback = pCallback; + break; + + case HAL_RAMCFG_DE_DETECT_CB_ID: + /* Register double error callback */ + hramcfg->DetectDoubleErrorCallback = pCallback; + break; + + case HAL_RAMCFG_MSPINIT_CB_ID : + /* Register msp init callback */ + hramcfg->MspInitCallback = pCallback; + break; + + case HAL_RAMCFG_MSPDEINIT_CB_ID : + /* Register msp de-init callback */ + hramcfg->MspDeInitCallback = pCallback; + break; + + default: + /* Update the error code and return error */ + hramcfg->ErrorCode |= HAL_RAMCFG_ERROR_INVALID_CALLBACK; + status = HAL_ERROR; + break; + } + } + else if (hramcfg->State == HAL_RAMCFG_STATE_RESET) + { + switch (CallbackID) + { + case HAL_RAMCFG_MSPINIT_CB_ID : + /* Register msp init callback */ + hramcfg->MspInitCallback = pCallback; + break; + + case HAL_RAMCFG_MSPDEINIT_CB_ID : + /* Register msp de-init callback */ + hramcfg->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code and return error */ + hramcfg->ErrorCode |= HAL_RAMCFG_ERROR_INVALID_CALLBACK; + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code and return error */ + hramcfg->ErrorCode = HAL_RAMCFG_ERROR_INVALID_CALLBACK; + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief UnRegister RAMCFG callbacks. + * @param hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that + * contains the configuration information for the + * specified RAMCFG instance. + * @param CallbackID : User Callback identifier a HAL_RAMCFG_CallbackIDTypeDef + * ENUM as parameter. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_RAMCFG_UnRegisterCallback(RAMCFG_HandleTypeDef *hramcfg, HAL_RAMCFG_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_RAMCFG_ALL_INSTANCE(hramcfg->Instance)); + + /* Check RAMCFG state */ + if (hramcfg->State == HAL_RAMCFG_STATE_READY) + { + switch (CallbackID) + { + case HAL_RAMCFG_SE_DETECT_CB_ID: + /* UnRegister single error callback */ + hramcfg->DetectSingleErrorCallback = NULL; + break; + + case HAL_RAMCFG_DE_DETECT_CB_ID: + /* UnRegister double error callback */ + hramcfg->DetectDoubleErrorCallback = NULL; + break; + + case HAL_RAMCFG_MSPINIT_CB_ID : + /* UnRegister msp init callback */ + hramcfg->MspInitCallback = NULL; + break; + + case HAL_RAMCFG_MSPDEINIT_CB_ID : + /* UnRegister msp de-init callback */ + hramcfg->MspDeInitCallback = NULL; + break; + + case HAL_RAMCFG_ALL_CB_ID: + /* UnRegister all available callbacks */ + hramcfg->DetectSingleErrorCallback = NULL; + hramcfg->DetectDoubleErrorCallback = NULL; + hramcfg->MspDeInitCallback = NULL; + hramcfg->MspInitCallback = NULL; + break; + + default: + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (hramcfg->State == HAL_RAMCFG_STATE_RESET) + { + switch (CallbackID) + { + case HAL_RAMCFG_MSPINIT_CB_ID : + /* UnRegister msp init callback */ + hramcfg->MspInitCallback = NULL; + break; + + case HAL_RAMCFG_MSPDEINIT_CB_ID : + /* UnRegister msp de-init callback */ + hramcfg->MspDeInitCallback = NULL; + break; + + case HAL_RAMCFG_ALL_CB_ID: + /* UnRegister all available callbacks */ + hramcfg->MspDeInitCallback = NULL; + hramcfg->MspInitCallback = NULL; + break; + + default : + /* Update the error code */ + hramcfg->ErrorCode |= HAL_RAMCFG_ERROR_INVALID_CALLBACK; + + /* Update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code and return error */ + hramcfg->ErrorCode = HAL_RAMCFG_ERROR_INVALID_CALLBACK; + status = HAL_ERROR; + } + + return status; +} +/** + * @} + */ +#endif /* USE_HAL_RAMCFG_REGISTER_CALLBACKS */ + +/** @addtogroup RAMCFG_Exported_Functions_Group7 + * +@verbatim + =============================================================================== + ##### State and Error Functions ##### + =============================================================================== + [..] + This section provides functions to check and get the RAMCFG state + and the error code. + [..] + The HAL_RAMCFG_GetState() function allows the user to get the RAMCFG peripheral + state. + The HAL_RAMCFG_GetError() function allows the user to get the RAMCFG peripheral error + code. + +@endverbatim + * @{ + */ + +/** + * @brief Get the RAMCFG peripheral state. + * @param hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that + * contains the configuration information for the + * specified RAMCFG instance. + * @retval RAMCFG state. + */ +HAL_RAMCFG_StateTypeDef HAL_RAMCFG_GetState(const RAMCFG_HandleTypeDef *hramcfg) +{ + /* Check the parameters */ + assert_param(IS_RAMCFG_ALL_INSTANCE(hramcfg->Instance)); + + /* Return the RAMCFG state */ + return hramcfg->State; +} + +/** + * @brief Get the RAMCFG peripheral error code. + * @param hramcfg : Pointer to a RAMCFG_HandleTypeDef structure that + * contains the configuration information for the + * specified RAMCFG instance. + * @retval RAMCFG error code. + */ +uint32_t HAL_RAMCFG_GetError(const RAMCFG_HandleTypeDef *hramcfg) +{ + /* Check the parameters */ + assert_param(IS_RAMCFG_ALL_INSTANCE(hramcfg->Instance)); + + /* Return the RAMCFG error code */ + return hramcfg->ErrorCode; +} +/** + * @} + */ + + +#endif /* HAL_RAMCFG_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rcc.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rcc.c new file mode 100644 index 0000000000..d3b96c185a --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rcc.c @@ -0,0 +1,1894 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_rcc.c + * @author MCD Application Team + * @brief RCC HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Reset and Clock Control (RCC) peripheral: + * + Initialization and de-initialization functions + * + Peripheral Control functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### RCC specific features ##### + ============================================================================== + [..] + After reset the device is running from High Speed Internal oscillator + (64 MHz) with Flash 3 wait states. Flash prefetch buffer, D-Cache + and I-Cache are disabled, and all peripherals are off except internal + SRAM, Flash and JTAG. + + (+) There is no prescaler on High speed (AHBs) and Low speed (APBs) busses: + all peripherals mapped on these busses are running at HSI speed. + (+) The clock for all peripherals is switched off, except the SRAM and FLASH. + (+) All GPIOs are in analog mode, except the JTAG pins which + are assigned to be used for debug purpose. + + [..] + Once the device started from reset, the user application has to: + (+) Configure the clock source to be used to drive the System clock + (if the application needs higher frequency/performance) + (+) Configure the System clock frequency and Flash settings + (+) Configure the AHB and APB busses prescalers + (+) Enable the clock for the peripheral(s) to be used + (+) Configure the clock source(s) for peripherals which clocks are not + derived from the System clock (SAIx, RTC, ADC, USB, SDMMC, etc.) + + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup RCC RCC + * @brief RCC HAL module driver + * @{ + */ + +#ifdef HAL_RCC_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup RCC_Private_Constants RCC Private Constants + * @{ + */ + +/** @defgroup RCC_Timeout_Value Timeout Values + * @{ + */ +#define RCC_LSI_TIMEOUT_VALUE ((uint32_t)2U) /* 2 ms (minimum Tick + 1) */ +#define RCC_HSI48_TIMEOUT_VALUE ((uint32_t)2U) /* 2 ms (minimum Tick + 1) */ +#define RCC_PLL_TIMEOUT_VALUE ((uint32_t)2U) /* 2 ms (minimum Tick + 1) */ +#define RCC_CLOCKSWITCH_TIMEOUT_VALUE ((uint32_t)5000U) /* 5 s */ +#define RCC_PLL_FRAC_WAIT_VALUE 1U /* PLL Fractional part waiting time before new latch enable : 1 ms */ +/** + * @} + */ + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/** @defgroup RCC_Private_Macros RCC Private Macros + * @{ + */ + +#define MCO1_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define MCO1_GPIO_PORT GPIOA +#define MCO1_PIN GPIO_PIN_8 + +#define MCO2_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE() +#define MCO2_GPIO_PORT GPIOC +#define MCO2_PIN GPIO_PIN_9 + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ + +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup RCC_Exported_Functions RCC Exported Functions + * @{ + */ + +/** @defgroup RCC_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 configure the internal and external oscillators + (HSE, HSI, LSE, CSI, LSI, PLL1, HSE CSS and MCOs) and the System busses clocks (SYSCLK, AHB, APB1, APB2 + and APB3). + + [..] Internal/external clock and PLL configuration + (+) HSI (high-speed internal): 64 MHz factory-trimmed RC used directly or through + the PLL as System clock source. + + (#) CSI is a low-power RC oscillator which can be used directly as system clock, peripheral + clock, or PLL input. But even with frequency calibration, is less accurate than an + external crystal oscillator or ceramic resonator. + + (+) LSI (low-speed internal): 32 KHz low consumption RC used as IWDG and/or RTC + clock source. + + (+) HSE (high-speed external): 4 to 48 MHz crystal oscillator used directly or + through the PLL as System clock source. Can be used also optionally as RTC clock source. + + (+) LSE (low-speed external): 32.768 KHz oscillator used optionally as RTC clock source. + + (+) PLL1 (clocked by HSI, HSE or CSI) providing up to three independent output clocks: + (++) The first output is used to generate the high speed system clock (up to 250MHz). + (++) The second output is used to generate the clock for the USB (48 MHz), the FDCAN1/2, + the SPI1/2/3, the OCTOSPI, the RNG (<=48 MHz), the SDMMC1/2 and to generate an accurate + clock to achieve high-quality audio performance on SAI1/2 interface. + + (+) PLL2 (clocked by HSI, HSE or CSI) providing up to three independent output clocks: + (++) The first output is used to generate the clock for the LPTIMs, the SPI1/2/3 and to generate + an accurate clock to achieve high-quality audio performance on SAI1/2 interface. + (++) The second output is used to generate the clock for USARTs, the UARTs, the LPUART1, + the FDCAN1/2, the SPI4/5/6 and the USB. + (++) The third output is used to generate the clock the SDMMC1/2, the ADC/DAC, the I2C1/2, + the I3C1/2 and the OCTOSPI. + + (+) PLL3 (clocked by HSI , HSE or CSI) providing up to three independent output clocks: + (++) The first output is used to generate the clock for SPI1/2/3 and to generate an accurate + clock to achieve high-quality audio performance on SAI1/2 interface. + (++) The second output is used to generate the clock for USARTs, the UARTs, the LPUART1, + the SPI4/5/6 and the USB. + (++) The third output is used to generate the clock for the I2Cs, the I3Cs and the LPTIMs. + + (+) HSE CSS (HSE Clock Security System): once enabled, if a HSE clock failure occurs + (HSE used directly or through PLL1 as System clock source), the System clock + is automatically switched to HSI and an interrupt is generated if enabled. + The interrupt is linked to the Cortex-M33 NMI (Non-Maskable Interrupt) + exception vector. + + (#) MCO1 (micro controller clock output1), used to output HSI, LSE, HSE, PLL1(PLL1_Q) + or HSI48 clock (through a configurable pre-scaler) on PA8 pin. + + (#) MCO2 (micro controller clock output2), used to output HSE, PLL2(PLL2_P), SYSCLK, + LSI, CSI, or PLL1(PLL1_P) clock (through a configurable pre-scaler) on PC9 pin. + + [..] System, AHB and APB busses clocks configuration + (+) Several clock sources can be used to drive the System clock (SYSCLK): CSI, HSI, HSE and the main PLL. + The AHB clock (HCLK) is derived from System clock through configurable + prescaler and used to clock the CPU, memory and peripherals mapped + on AHB bus (DMA, GPIO...). APB1 (PCLK1), APB2 (PCLK2) and APB3 (PCLK3) clocks are derived + from AHB clock through configurable prescalers and used to clock + the peripherals mapped on these busses. You can use + "HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks. + + -@- All the peripheral clocks are derived from the System clock (SYSCLK) except: + + (+@) SAI: the SAI clock can be derived either from specific PLL (PLL1, PLL2 or PLL3), + the per_ck clock (HSE, HSI or CSI) or from an external clock mapped on the SAI_CKIN pin. + You have to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock. + (+@) SPI/I2S: the SPI1/2/3 clock can be derived either from specific PLL (PLL1, PLL2 or PLL3), + the per_ck clock (HSE, HSI or CSI) or from an external clock mapped on the SPI_CKIN pin. + You have to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock. + (+@) RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock + divided by 2 to 31. + You have to use __HAL_RCC_RTC_ENABLE() and HAL_RCCEx_PeriphCLKConfig() function + to configure this clock. + (+@) USB: USB requires a frequency equal to 48 MHz to work correctly. This clock is derived + of the main PLL or PLL2 through PLLQ divider. You have to use HAL_RCCEx_PeriphCLKConfig() + function to configure this clock. + (+@) UCPD: the UCPD clock is derived from HSI (divided by 4) clock. + (+@) SDMMC: SDMMC1/2 peripherals require a frequency equal or lower than 48 MHz. + This clock is derived from the PLL1 or PLL2 through PLL1Q or PLL2R divider. You have + to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock. + (+@) IWDG clock which is always the LSI clock. You have to use HAL_RCCEx_PeriphCLKConfig() + function to configure this clock. + (+@) RNG: the RNG clock can be derived either from PLL1Q, HSI48, LSE or LSI clock. You have + to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock. + (+@) DAC: the DAC clock can be derived either from LSE or LSI clock. You have + to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock. + (+@) FDCAN: the FDCAN1/2 clock can be derived either from HSE, PLL1Q or PLL2Q clock. You have + to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock. + (+@) CEC: the CEC clock can be derived either from LSE, LSI or CSI (divided by 122) clock.You have + to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock. + (+@) ETH: the Ethernet clock is derived from PLL1Q clock. + + + + (+) The maximum frequency of the SYSCLK, HCLK, PCLK1, PCLK2 and PCLK3 is 250 MHz. + The clock source frequency should be adapted depending on the device voltage range + as listed in the Reference Manual "Clock source frequency versus voltage scaling" chapter. + + @endverbatim + + + Table 1. HCLK clock frequency for STM32H5xx devices + +-----------------------------------------------------------------------------------------------+ + | Latency | HCLK clock frequency (MHz) | + | |-----------------------------------------------------------------------------| + | | voltage range 0 | voltage range 1 | voltage range 2 | voltage range 3 | + | | 1.26 - 1.35V | 1.15 - 1.26V | 1.05 - 1.15V | 0,95 - 1,05V | + |-----------------|-------------------|------------------|------------------|-------------------| + |0WS(1 CPU cycles)| 0 < HCLK <= 38 | 0 < HCLK <= 32 | 0 < HCLK <= 26 | 0 < HCLK <= 16 | + |-----------------|-------------------|------------------|------------------|-------------------| + |1WS(2 CPU cycles)| 38 < HCLK <= 76 | 32 < HCLK <= 64 | 26 < HCLK <= 50 | 16 < HCLK <= 32 | + |-----------------|-------------------|------------------|------------------|-------------------| + |2WS(3 CPU cycles)| 76 < HCLK <= 114 | 64 < HCLK <= 96 | 50 < HCLK <= 80 | 32 < HCLK <= 50 | + |-----------------|-------------------|------------------|------------------|-------------------| + |3WS(4 CPU cycles)| 114 < HCLK <= 152 | 96 < HCLK <= 128 | 80 < HCLK <= 106 | 50 < HCLK <= 65 | + |-----------------|-------------------|------------------|------------------|-------------------| + |4WS(5 CPU cycles)| 152 < HCLK <= 190| 128 < HCLK <= 160| 106 < HCLK <= 130| 65 < HCLK <= 80 | + |-----------------|-------------------|------------------|------------------|-------------------| + |5WS(6 CPU cycles)| 190 < HCLK <= 250| 160 < HCLK <= 180| NA | NA | + +-----------------+-------------------+------------------+------------------+-------------------+ + * @{ + */ + +/** + * @brief Reset the RCC clock configuration to the default reset state. + * @note The default reset state of the clock configuration is given below: + * - HSI ON and used as system clock source + * - HSE, CSI, PLL, PLL2 and PLL3 OFF + * - AHB, APB1 and APB2 prescaler set to 1. + * - HSECSS, MCO1 and MCO2 OFF + * - All interrupts disabled + * @note This function doesn't modify the configuration of the + * - Peripheral clocks + * - LSI, LSE and RTC clocks + * @retval HAL Status. + */ + +HAL_StatusTypeDef HAL_RCC_DeInit(void) +{ + uint32_t tickstart; + + /* Increasing the CPU frequency */ + if (FLASH_LATENCY_DEFAULT > __HAL_FLASH_GET_LATENCY()) + { + /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */ + __HAL_FLASH_SET_LATENCY(FLASH_LATENCY_DEFAULT); + + /* Check that the new number of wait states is taken into account to access the Flash + memory by reading the FLASH_ACR register */ + if (__HAL_FLASH_GET_LATENCY() != FLASH_LATENCY_DEFAULT) + { + return HAL_ERROR; + } + + } + + /* Get start tick*/ + tickstart = HAL_GetTick(); + + /* Set HSION bit */ + SET_BIT(RCC->CR, RCC_CR_HSION); + + /* Wait till HSI is ready */ + while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_HSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Set HSIDIV Default value */ + CLEAR_BIT(RCC->CR, RCC_CR_HSIDIV); + + /* Set HSITRIM default value */ + WRITE_REG(RCC->HSICFGR, RCC_HSICFGR_HSITRIM_6); + + + /* Adapt Systick interrupt period */ + if (HAL_InitTick(uwTickPrio) != HAL_OK) + { + return HAL_ERROR; + } + + /* Get start tick*/ + tickstart = HAL_GetTick(); + + /* Reset CFGR register (HSI is selected as system clock source) */ + CLEAR_REG(RCC->CFGR1); + CLEAR_REG(RCC->CFGR2); + + /* Wait till clock switch is ready */ + while (READ_BIT(RCC->CFGR1, RCC_CFGR1_SWS) != 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_CLOCKSWITCH_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Reset HSECSSON, HSEON, HSIKERON, CSION, CSIKERON and HSI48ON bits */ + CLEAR_BIT(RCC->CR, RCC_CR_CSION | RCC_CR_CSIKERON | RCC_CR_HSECSSON | RCC_CR_HSIKERON | RCC_CR_HSI48ON | \ + RCC_CR_HSEON); + + /* Reset HSEEXT bit*/ + CLEAR_BIT(RCC->CR, RCC_CR_HSEEXT); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Clear PLL1ON bit */ + CLEAR_BIT(RCC->CR, RCC_CR_PLL1ON); + + /* Wait till PLL1 is disabled */ + while (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) != 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_PLL_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Reset PLL2N bit */ + CLEAR_BIT(RCC->CR, RCC_CR_PLL2ON); + + /* Wait till PLL2 is disabled */ + while (READ_BIT(RCC->CR, RCC_CR_PLL2RDY) != 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_PLL_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + +#if defined(RCC_CR_PLL3ON) + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Reset PLL3 bit */ + CLEAR_BIT(RCC->CR, RCC_CR_PLL3ON); + + /* Wait till PLL3 is disabled */ + while (READ_BIT(RCC->CR, RCC_CR_PLL3RDY) != 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_PLL_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } +#endif /* RCC_CR_PLL3ON */ + + /* Reset PLL1CFGR register */ + CLEAR_REG(RCC->PLL1CFGR); + + /* Reset PLL1DIVR register */ + WRITE_REG(RCC->PLL1DIVR, 0x01010280U); + + /* Reset PLL1FRACR register */ + CLEAR_REG(RCC->PLL1FRACR); + + /* Reset PLL2CFGR register */ + CLEAR_REG(RCC->PLL2CFGR); + + /* Reset PLL2DIVR register */ + WRITE_REG(RCC->PLL2DIVR, 0x01010280U); + + /* Reset PLL2FRACR register */ + CLEAR_REG(RCC->PLL2FRACR); + +#if defined(RCC_CR_PLL3ON) + /* Reset PLL3CFGR register */ + CLEAR_REG(RCC->PLL3CFGR); + + /* Reset PLL3DIVR register */ + WRITE_REG(RCC->PLL3DIVR, 0x01010280U); + + /* Reset PLL3FRACR register */ + CLEAR_REG(RCC->PLL3FRACR); +#endif /* RCC_CR_PLL3ON */ + + /* Reset HSEBYP bit */ + CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP); + + /* Disable all interrupts */ + CLEAR_REG(RCC->CIER); + + /* Clear all interrupts flags */ + WRITE_REG(RCC->CICR, 0xFFFFFFFFU); + + /* Reset all RSR flags */ + SET_BIT(RCC->RSR, RCC_RSR_RMVF); + + /* Update the SystemCoreClock global variable */ + SystemCoreClock = HSI_VALUE; + + /* Decreasing the number of wait states because of lower CPU frequency */ + if (FLASH_LATENCY_DEFAULT < __HAL_FLASH_GET_LATENCY()) + { + /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */ + __HAL_FLASH_SET_LATENCY(FLASH_LATENCY_DEFAULT); + + /* Check that the new number of wait states is taken into account to access the Flash + memory by reading the FLASH_ACR register */ + if (__HAL_FLASH_GET_LATENCY() != FLASH_LATENCY_DEFAULT) + { + return HAL_ERROR; + } + } + + /* Adapt Systick interrupt period */ + if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK) + { + return HAL_ERROR; + } + else + { + return HAL_OK; + } +} + +/** + * @brief Initialize the RCC Oscillators according to the specified parameters in the + * RCC_OscInitTypeDef. + * @param pOscInitStruct pointer to an RCC_OscInitTypeDef structure that + * contains the configuration information for the RCC Oscillators. + * @note The PLL is not disabled when used as system clock. + * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not + * supported by this macro. User should request a transition to LSE Off + * first and then LSE On or LSE Bypass. + * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not + * supported by this macro. User should request a transition to HSE Off + * first and then HSE On or HSE Bypass. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RCC_OscConfig(const RCC_OscInitTypeDef *pOscInitStruct) +{ + uint32_t tickstart; + uint32_t temp_sysclksrc; + uint32_t temp_pllckselr; + uint32_t temp1_pllckcfg; + uint32_t temp2_pllckcfg; + + /* Check Null pointer */ + if (pOscInitStruct == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_RCC_OSCILLATORTYPE(pOscInitStruct->OscillatorType)); + temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE(); + temp_pllckselr = __HAL_RCC_GET_PLL1_OSCSOURCE(); + + /*----------------------------- CSI Configuration --------------------------*/ + if (((pOscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_CSI) == RCC_OSCILLATORTYPE_CSI) + { + /* Check the parameters */ + assert_param(IS_RCC_CSI(pOscInitStruct->CSIState)); + assert_param(IS_RCC_CSICALIBRATION_VALUE(pOscInitStruct->CSICalibrationValue)); + + /* When the CSI is used as system clock it will not be disabled */ + if ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_CSI) || + ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (temp_pllckselr == RCC_PLL1_SOURCE_CSI))) + { + if (pOscInitStruct->CSIState == RCC_CSI_OFF) + { + return HAL_ERROR; + } + + /* Otherwise, just the calibration and CSI is allowed */ + else + { + /* Adjusts the Internal Low-power oscillator (CSI) calibration value.*/ + __HAL_RCC_CSI_CALIBRATIONVALUE_ADJUST(pOscInitStruct->CSICalibrationValue); + } + } + else + { + /* Check the CSI State */ + if ((pOscInitStruct->CSIState) != RCC_CSI_OFF) + { + /* Enable the Internal High Speed oscillator (CSI). */ + __HAL_RCC_CSI_ENABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till CSI is ready */ + while (READ_BIT(RCC->CR, RCC_CR_CSIRDY) == 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_CSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Adjusts the Internal High Speed oscillator (CSI) calibration value.*/ + __HAL_RCC_CSI_CALIBRATIONVALUE_ADJUST(pOscInitStruct->CSICalibrationValue); + } + else + { + /* Disable the Internal High Speed oscillator (CSI). */ + __HAL_RCC_CSI_DISABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till CSI is disabled */ + while (READ_BIT(RCC->CR, RCC_CR_CSIRDY) != 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_CSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + } + /*------------------------------- HSE Configuration ------------------------*/ + if (((pOscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE) + { + /* Check the parameters */ + assert_param(IS_RCC_HSE(pOscInitStruct->HSEState)); + + /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */ + if ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSE) || + ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (temp_pllckselr == RCC_PLL1_SOURCE_HSE))) + { + if (pOscInitStruct->HSEState == RCC_HSE_OFF) + { + return HAL_ERROR; + } + } + else + { + /* Set the new HSE configuration ---------------------------------------*/ + __HAL_RCC_HSE_CONFIG(pOscInitStruct->HSEState); + + /* Check the HSE State */ + if (pOscInitStruct->HSEState != RCC_HSE_OFF) + { + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till HSE is ready */ + while (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_HSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till HSE is disabled */ + while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_HSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + } + /*----------------------------- HSI Configuration --------------------------*/ + if (((pOscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI) + { + /* Check the parameters */ + assert_param(IS_RCC_HSI(pOscInitStruct->HSIState)); + assert_param(IS_RCC_HSIDIV(pOscInitStruct->HSIDiv)); + assert_param(IS_RCC_HSI_CALIBRATION_VALUE(pOscInitStruct->HSICalibrationValue)); + + /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */ + if ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSI) || + ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (temp_pllckselr == RCC_PLL1_SOURCE_HSI))) + { + /* When HSI is used as system clock it will not be disabled */ + if (pOscInitStruct->HSIState == RCC_HSI_OFF) + { + return HAL_ERROR; + } + /* Otherwise, HSI calibration and division may be allowed */ + else + { + + /* HSI division is allowed if HSI is used as system clock */ + if (temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSI) + { + if (__HAL_RCC_GET_HSI_DIVIDER() != (pOscInitStruct->HSIDiv)) + { + /* Adjust the HSI division factor */ + __HAL_RCC_HSI_DIVIDER_CONFIG(pOscInitStruct->HSIDiv); + + /* Update the SystemCoreClock global variable with new HSI value */ + (void) HAL_RCC_GetHCLKFreq(); + + /* Configure the source of time base considering new system clocks settings*/ + if (HAL_InitTick(uwTickPrio) != HAL_OK) + { + return HAL_ERROR; + } + } + } + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till HSI is ready */ + while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_HSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/ + __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(pOscInitStruct->HSICalibrationValue); + } + } + else + { + /* Check the HSI State */ + if (pOscInitStruct->HSIState != RCC_HSI_OFF) + { + /* Adjust the HSI division factor */ + __HAL_RCC_HSI_DIVIDER_CONFIG(pOscInitStruct->HSIDiv); + + /* Enable the HSI oscillator */ + __HAL_RCC_HSI_ENABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till HSI is ready */ + while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_HSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Adjust the Internal High Speed oscillator (HSI) calibration value.*/ + __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(pOscInitStruct->HSICalibrationValue); + } + else + { + /* Disable the Internal High Speed oscillator (HSI). */ + __HAL_RCC_HSI_DISABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till HSI is disabled */ + while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_HSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + } + /*------------------------------ LSI Configuration -------------------------*/ + if (((pOscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI) + { + + /* Check the parameters */ + assert_param(IS_RCC_LSI(pOscInitStruct->LSIState)); + + /* Update LSI configuration in Backup Domain control register */ + + /* Check the LSI State */ + if (pOscInitStruct->LSIState != RCC_LSI_OFF) + { + /* Enable the Internal Low Speed oscillator (LSI). */ + __HAL_RCC_LSI_ENABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till LSI is ready */ + while (READ_BIT(RCC->BDCR, RCC_BDCR_LSIRDY) == 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_LSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + /* Disable the Internal Low Speed oscillator (LSI). */ + __HAL_RCC_LSI_DISABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till LSI is disabled */ + while (READ_BIT(RCC->BDCR, RCC_BDCR_LSIRDY) != 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_LSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + + } + /*------------------------------ LSE Configuration -------------------------*/ + if (((pOscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE) + { + + /* Check the parameters */ + assert_param(IS_RCC_LSE(pOscInitStruct->LSEState)); + + /* Update LSE configuration in Backup Domain control register */ + /* Requires to enable write access to Backup Domain */ + if (HAL_IS_BIT_CLR(PWR->DBPCR, PWR_DBPCR_DBP)) + { + /* Enable write access to Backup domain */ + SET_BIT(PWR->DBPCR, PWR_DBPCR_DBP); + + /* Wait for Backup domain Write protection disable */ + tickstart = HAL_GetTick(); + + while (HAL_IS_BIT_CLR(PWR->DBPCR, PWR_DBPCR_DBP)) + { + if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + + /* Set the new LSE configuration -----------------------------------------*/ + __HAL_RCC_LSE_CONFIG(pOscInitStruct->LSEState); + + /* Check the LSE State */ + if (pOscInitStruct->LSEState != RCC_LSE_OFF) + { + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till LSE is ready */ + while (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till LSE is disabled */ + while (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) != 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + + } + /*------------------------------ HSI48 Configuration -----------------------*/ + if (((pOscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48) + { + /* Check the parameters */ + assert_param(IS_RCC_HSI48(pOscInitStruct->HSI48State)); + + /* Check the HSI48 State */ + if (pOscInitStruct->HSI48State != RCC_HSI48_OFF) + { + /* Enable the Internal High Speed oscillator (HSI48). */ + __HAL_RCC_HSI48_ENABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till HSI48 is ready */ + while (READ_BIT(RCC->CR, RCC_CR_HSI48RDY) == 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_HSI48_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + /* Disable the Internal High Speed oscillator (HSI48). */ + __HAL_RCC_HSI48_DISABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till HSI48 is disabled */ + while (READ_BIT(RCC->CR, RCC_CR_HSI48RDY) != 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_HSI48_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + + /*-------------------------------- PLL1 Configuration -----------------------*/ + /* Check the parameters */ + assert_param(IS_RCC_PLL(pOscInitStruct->PLL.PLLState)); + + if ((pOscInitStruct->PLL.PLLState) != RCC_PLL_NONE) + { + /* Check if the PLL1 is used as system clock or not */ + if (temp_sysclksrc != RCC_SYSCLKSOURCE_STATUS_PLLCLK) + { + if ((pOscInitStruct->PLL.PLLState) == RCC_PLL_ON) + { + /* Check the parameters */ + assert_param(IS_RCC_PLL1_SOURCE(pOscInitStruct->PLL.PLLSource)); + assert_param(IS_RCC_PLL1_DIVM_VALUE(pOscInitStruct->PLL.PLLM)); + assert_param(IS_RCC_PLL1_MULN_VALUE(pOscInitStruct->PLL.PLLN)); + assert_param(IS_RCC_PLL1_DIVP_VALUE(pOscInitStruct->PLL.PLLP)); + assert_param(IS_RCC_PLL1_DIVQ_VALUE(pOscInitStruct->PLL.PLLQ)); + assert_param(IS_RCC_PLL1_DIVR_VALUE(pOscInitStruct->PLL.PLLR)); + + /* Disable the PLL1. */ + __HAL_RCC_PLL1_DISABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till PLL1 is disabled */ + while (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) != 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_PLL_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Configure the PLL1 clock source, multiplication and division factors. */ + __HAL_RCC_PLL1_CONFIG(pOscInitStruct->PLL.PLLSource, + pOscInitStruct->PLL.PLLM, + pOscInitStruct->PLL.PLLN, + pOscInitStruct->PLL.PLLP, + pOscInitStruct->PLL.PLLQ, + pOscInitStruct->PLL.PLLR); + + assert_param(IS_RCC_PLL1_FRACN_VALUE(pOscInitStruct->PLL.PLLFRACN)); + + /* Disable PLL1FRACN . */ + __HAL_RCC_PLL1_FRACN_DISABLE(); + + /* Configure PLL PLL1FRACN */ + __HAL_RCC_PLL1_FRACN_CONFIG(pOscInitStruct->PLL.PLLFRACN); + + /* Enable PLL1FRACN . */ + __HAL_RCC_PLL1_FRACN_ENABLE(); + + assert_param(IS_RCC_PLL1_VCIRGE_VALUE(pOscInitStruct->PLL.PLLRGE)); + + /* Select PLL1 input reference frequency range: VCI */ + __HAL_RCC_PLL1_VCIRANGE(pOscInitStruct->PLL.PLLRGE) ; + + assert_param(IS_RCC_PLL1_VCORGE_VALUE(pOscInitStruct->PLL.PLLVCOSEL)); + + /* Select PLL1 output frequency range : VCO */ + __HAL_RCC_PLL1_VCORANGE(pOscInitStruct->PLL.PLLVCOSEL) ; + + /* Enable PLL1 System Clock output. */ + __HAL_RCC_PLL1_CLKOUT_ENABLE(RCC_PLL1_DIVP); + + /* Enable the PLL1. */ + __HAL_RCC_PLL1_ENABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till PLL1 is ready */ + while (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) == 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_PLL_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + /* Disable the PLL1. */ + __HAL_RCC_PLL1_DISABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till PLL1 is disabled */ + while (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) != 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_PLL_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Unselect PLL1 clock source and disable all PLL1 outputs to save power */ + RCC->PLL1CFGR &= ~(RCC_PLL1CFGR_PLL1SRC | RCC_PLL1CFGR_PLL1PEN | RCC_PLL1CFGR_PLL1QEN | RCC_PLL1CFGR_PLL1REN); + + } + } + else + { + /* Do not return HAL_ERROR if request repeats the current configuration */ + temp1_pllckcfg = RCC->PLL1CFGR; + temp2_pllckcfg = RCC->PLL1DIVR; + if (((pOscInitStruct->PLL.PLLState) == RCC_PLL_OFF) || + (READ_BIT(temp1_pllckcfg, RCC_PLL1CFGR_PLL1SRC) != pOscInitStruct->PLL.PLLSource) || + ((READ_BIT(temp1_pllckcfg, RCC_PLL1CFGR_PLL1M) >> \ + RCC_PLL1CFGR_PLL1M_Pos) != (pOscInitStruct->PLL.PLLM)) || + (READ_BIT(temp2_pllckcfg, RCC_PLL1DIVR_PLL1N) != (pOscInitStruct->PLL.PLLN - 1U)) || + ((READ_BIT(temp2_pllckcfg, RCC_PLL1DIVR_PLL1P) >> \ + RCC_PLL1DIVR_PLL1P_Pos) != (pOscInitStruct->PLL.PLLP - 1U)) || + ((READ_BIT(temp2_pllckcfg, RCC_PLL1DIVR_PLL1Q) >> \ + RCC_PLL1DIVR_PLL1Q_Pos) != (pOscInitStruct->PLL.PLLQ - 1U)) || + ((READ_BIT(temp2_pllckcfg, RCC_PLL1DIVR_PLL1R) >> \ + RCC_PLL1DIVR_PLL1R_Pos) != (pOscInitStruct->PLL.PLLR - 1U))) + { + return HAL_ERROR; + } + + /* FRACN1 on-the-fly value update */ + if ((READ_BIT(RCC->PLL1FRACR, RCC_PLL1FRACR_PLL1FRACN) >> \ + RCC_PLL1FRACR_PLL1FRACN_Pos) != (pOscInitStruct->PLL.PLLFRACN)) + { + assert_param(IS_RCC_PLL1_FRACN_VALUE(pOscInitStruct->PLL.PLLFRACN)); + + /* Disable PLL1FRACN . */ + __HAL_RCC_PLL1_FRACN_DISABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait at least 2 CK_REF (PLL input source divided by M) period to make sure next latched value + will be taken into account. */ + while ((HAL_GetTick() - tickstart) < RCC_PLL_FRAC_WAIT_VALUE) + { + } + + /* Configure PLL PLL1FRACN */ + __HAL_RCC_PLL1_FRACN_CONFIG(pOscInitStruct->PLL.PLLFRACN); + + /* Enable PLL1FRACN to latch the new value. */ + __HAL_RCC_PLL1_FRACN_ENABLE(); + } + + } + } + return HAL_OK; +} + +/** + * @brief Initialize the CPU, AHB and APB busses clocks according to the specified + * parameters in the pClkInitStruct. + * @param pClkInitStruct pointer to an RCC_OscInitTypeDef structure that + * contains the configuration information for the RCC peripheral. + * @param FLatency FLASH Latency + * This parameter can be one of the following values: + * @arg FLASH_LATENCY_0 FLASH 0 Latency cycle + * @arg FLASH_LATENCY_1 FLASH 1 Latency cycle + * @arg FLASH_LATENCY_2 FLASH 2 Latency cycles + * @arg FLASH_LATENCY_3 FLASH 3 Latency cycles + * @arg FLASH_LATENCY_4 FLASH 4 Latency cycles + * @arg FLASH_LATENCY_5 FLASH 5 Latency cycles + * + * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency + * and updated by HAL_RCC_GetHCLKFreq() function called within this function + * + * @note The HSI is used by default as system clock source after + * startup from Reset, wake-up from STANDBY mode. After restart from Reset, + * the HSI frequency is set to its default value 64 MHz. + * + * @note The HSI or CSI can be selected as system clock source after wake-up + * from STOP modes or in case of failure of the HSE when used directly or indirectly + * as system clock (if the Clock Security System CSS is enabled). + * + * @note A switch from one clock source to another occurs only if the target + * clock source is ready (clock stable after startup delay or PLL locked). + * If a clock source which is not yet ready is selected, the switch will + * occur when the clock source is ready. + * + * @note You can use HAL_RCC_GetClockConfig() function to know which clock is + * currently used as system clock source. + * + * @retval HAL Status. + */ +HAL_StatusTypeDef HAL_RCC_ClockConfig(const RCC_ClkInitTypeDef *pClkInitStruct, uint32_t FLatency) +{ + HAL_StatusTypeDef halstatus; + uint32_t tickstart; + + /* Check Null pointer */ + if (pClkInitStruct == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_RCC_CLOCKTYPE(pClkInitStruct->ClockType)); + assert_param(IS_FLASH_LATENCY(FLatency)); + + /* To correctly read data from FLASH memory, the number of wait states (LATENCY) + must be correctly programmed according to the frequency of the CPU clock + (HCLK) and the supply voltage of the device. */ + + /* Increasing the number of wait states because of higher CPU frequency */ + if (FLatency > __HAL_FLASH_GET_LATENCY()) + { + /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */ + __HAL_FLASH_SET_LATENCY(FLatency); + + /* Check that the new number of wait states is taken into account to access the Flash + memory by reading the FLASH_ACR register */ + if (__HAL_FLASH_GET_LATENCY() != FLatency) + { + return HAL_ERROR; + } + } + + /* Increasing the BUS frequency divider */ + /*-------------------------- PCLK3 Configuration ---------------------------*/ + if (((pClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK3) == RCC_CLOCKTYPE_PCLK3) + { + if ((pClkInitStruct->APB3CLKDivider) > ((RCC->CFGR2 & RCC_CFGR2_PPRE3) >> 8)) + { + assert_param(IS_RCC_PCLK(pClkInitStruct->APB3CLKDivider)); + MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE3, ((pClkInitStruct->APB3CLKDivider) << 8)); + } + } + /*-------------------------- PCLK2 Configuration ---------------------------*/ + if (((pClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2) + { + if ((pClkInitStruct->APB2CLKDivider) > ((RCC->CFGR2 & RCC_CFGR2_PPRE2) >> 4)) + { + assert_param(IS_RCC_PCLK(pClkInitStruct->APB2CLKDivider)); + MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE2, ((pClkInitStruct->APB2CLKDivider) << 4)); + } + } + + /*-------------------------- PCLK1 Configuration ---------------------------*/ + if (((pClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1) + { + if ((pClkInitStruct->APB1CLKDivider) > (RCC->CFGR2 & RCC_CFGR2_PPRE1)) + { + assert_param(IS_RCC_PCLK(pClkInitStruct->APB1CLKDivider)); + MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE1, pClkInitStruct->APB1CLKDivider); + } + } + + /*-------------------------- HCLK Configuration --------------------------*/ + if (((pClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) + { + if ((pClkInitStruct->AHBCLKDivider) > (RCC->CFGR2 & RCC_CFGR2_HPRE)) + { + assert_param(IS_RCC_HCLK(pClkInitStruct->AHBCLKDivider)); + MODIFY_REG(RCC->CFGR2, RCC_CFGR2_HPRE, pClkInitStruct->AHBCLKDivider); + } + } + + /*------------------------- SYSCLK Configuration ---------------------------*/ + if (((pClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK) + { + assert_param(IS_RCC_SYSCLKSOURCE(pClkInitStruct->SYSCLKSource)); + + /* PLL is selected as System Clock Source */ + if (pClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK) + { + /* Check the PLL ready flag */ + if (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) == 0U) + { + return HAL_ERROR; + } + } + else + { + /* HSE is selected as System Clock Source */ + if (pClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE) + { + /* Check the HSE ready flag */ + if (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U) + { + return HAL_ERROR; + } + } + /* CSI is selected as System Clock Source */ + else if (pClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_CSI) + { + /* Check the CSI ready flag */ + if (READ_BIT(RCC->CR, RCC_CR_CSIRDY) == 0U) + { + return HAL_ERROR; + } + } + /* HSI is selected as System Clock Source */ + else + { + /* Check the HSI ready flag */ + if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U) + { + return HAL_ERROR; + } + } + } + + MODIFY_REG(RCC->CFGR1, RCC_CFGR1_SW, pClkInitStruct->SYSCLKSource); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + if (pClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK) + { + while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK) + { + if ((HAL_GetTick() - tickstart) > RCC_CLOCKSWITCH_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + if (pClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE) + { + while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSE) + { + if ((HAL_GetTick() - tickstart) > RCC_CLOCKSWITCH_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else if (pClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_CSI) + { + while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_CSI) + { + if ((HAL_GetTick() - tickstart) > RCC_CLOCKSWITCH_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSI) + { + if ((HAL_GetTick() - tickstart) > RCC_CLOCKSWITCH_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + } + + /* Decreasing the BUS frequency divider */ + /*-------------------------- HCLK Configuration --------------------------*/ + if (((pClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) + { + if ((pClkInitStruct->AHBCLKDivider) < (RCC->CFGR2 & RCC_CFGR2_HPRE)) + { + assert_param(IS_RCC_HCLK(pClkInitStruct->AHBCLKDivider)); + MODIFY_REG(RCC->CFGR2, RCC_CFGR2_HPRE, pClkInitStruct->AHBCLKDivider); + } + } + + /* Decreasing the number of wait states because of lower CPU frequency */ + if (FLatency < __HAL_FLASH_GET_LATENCY()) + { + /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */ + __HAL_FLASH_SET_LATENCY(FLatency); + + /* Check that the new number of wait states is taken into account to access the Flash + memory by reading the FLASH_ACR register */ + if (__HAL_FLASH_GET_LATENCY() != FLatency) + { + return HAL_ERROR; + } + } + + /*-------------------------- PCLK1 Configuration ---------------------------*/ + if (((pClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1) + { + if ((pClkInitStruct->APB1CLKDivider) < (RCC->CFGR2 & RCC_CFGR2_PPRE1)) + { + assert_param(IS_RCC_PCLK(pClkInitStruct->APB1CLKDivider)); + MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE1, pClkInitStruct->APB1CLKDivider); + } + } + + /*-------------------------- PCLK2 Configuration ---------------------------*/ + if (((pClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2) + { + if ((pClkInitStruct->APB2CLKDivider) < ((RCC->CFGR2 & RCC_CFGR2_PPRE2) >> 4)) + { + assert_param(IS_RCC_PCLK(pClkInitStruct->APB2CLKDivider)); + MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE2, ((pClkInitStruct->APB2CLKDivider) << 4)); + } + } + + /*-------------------------- PCLK3 Configuration ---------------------------*/ + if (((pClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK3) == RCC_CLOCKTYPE_PCLK3) + { + if ((pClkInitStruct->APB3CLKDivider) < ((RCC->CFGR2 & RCC_CFGR2_PPRE3) >> 8)) + { + assert_param(IS_RCC_PCLK(pClkInitStruct->APB3CLKDivider)); + MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE3, ((pClkInitStruct->APB3CLKDivider) << 8)); + } + } + + /* Update the SystemCoreClock global variable */ + SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR2 & RCC_CFGR2_HPRE) >> RCC_CFGR2_HPRE_Pos]; + + /* Configure the source of time base considering new system clocks settings*/ + halstatus = HAL_InitTick(uwTickPrio); + + return halstatus; +} + +/** + * @} + */ + +/** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions + * @brief RCC clocks control functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to: + + (+) Output clock to MCO pin. + (+) Retrieve current clock frequencies. + (+) Enable the Clock Security System. + +@endverbatim + * @{ + */ + +/** + * @brief Select the clock source to output on MCO1 pin(PA8) or on MCO2 pin(PC9). + * @note PA8/PC9 should be configured in alternate function mode. + * @param RCC_MCOx specifies the output direction for the clock source. + * For STM32H5xx family this parameter can have only one value: + * @arg @ref RCC_MCO1 Clock source to output on MCO1 pin(PA8). + * @arg @ref RCC_MCO2 Clock source to output on MCO2 pin(PC9). + * @param RCC_MCOSource specifies the clock source to output. + * This parameter can be one of the following values: + * @arg RCC_MCO1SOURCE_HSI: HSI clock selected as MCO1 source + * @arg RCC_MCO1SOURCE_LSE: LSE clock selected as MCO1 source + * @arg RCC_MCO1SOURCE_HSE: HSE clock selected as MCO1 source + * @arg RCC_MCO1SOURCE_PLL1QCLK: PLL1Q clock selected as MCO1 source + * @arg RCC_MCO1SOURCE_HSI48: HSI48 (48MHZ) selected as MCO1 source + * @arg RCC_MCO2SOURCE_SYSCLK: System clock (SYSCLK) selected as MCO2 source + * @arg RCC_MCO2SOURCE_PLL2PCLK: PLL2P clock selected as MCO2 source + * @arg RCC_MCO2SOURCE_HSE: HSE clock selected as MCO2 source + * @arg RCC_MCO2SOURCE_PLL1PCLK: PLL1P clock selected as MCO2 source + * @arg RCC_MCO2SOURCE_CSI: CSI clock selected as MCO2 source + * @arg RCC_MCO2SOURCE_LSI: LSI clock selected as MCO2 source + * @param RCC_MCODiv specifies the MCO prescaler. + * This parameter can be one of the following values: + * @arg RCC_MCODIV_1 up to RCC_MCODIV_15 : divider applied to MCOx clock + * @retval None + */ +void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv) +{ + GPIO_InitTypeDef GPIO_InitStruct; + /* Check the parameters */ + assert_param(IS_RCC_MCO(RCC_MCOx)); + assert_param(IS_RCC_MCODIV(RCC_MCODiv)); + /* RCC_MCO1 */ + if (RCC_MCOx == RCC_MCO1) + { + assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource)); + + /* MCO1 Clock Enable */ + MCO1_CLK_ENABLE(); + + /* Configure the MCO1 pin in alternate function mode */ + GPIO_InitStruct.Pin = MCO1_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Alternate = GPIO_AF0_MCO; + HAL_GPIO_Init(MCO1_GPIO_PORT, &GPIO_InitStruct); + + /* Mask MCO1 and MCO1PRE[3:0] bits then Select MCO1 clock source and pre-scaler */ + MODIFY_REG(RCC->CFGR1, (RCC_CFGR1_MCO1SEL | RCC_CFGR1_MCO1PRE), (RCC_MCOSource | RCC_MCODiv)); + } + else + { + assert_param(IS_RCC_MCO2SOURCE(RCC_MCOSource)); + + /* MCO2 Clock Enable */ + MCO2_CLK_ENABLE(); + + /* Configure the MCO2 pin in alternate function mode */ + GPIO_InitStruct.Pin = MCO2_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Alternate = GPIO_AF0_MCO; + HAL_GPIO_Init(MCO2_GPIO_PORT, &GPIO_InitStruct); + + /* Mask MCO2 and MCO2PRE[3:0] bits then Select MCO2 clock source and pre-scaler */ + MODIFY_REG(RCC->CFGR1, (RCC_CFGR1_MCO2SEL | RCC_CFGR1_MCO2PRE), (RCC_MCOSource | (RCC_MCODiv << 7U))); + } +} + +/** + * @brief Return the SYSCLK frequency. + * + * @note The system frequency computed by this function may not be the real + * frequency in the chip. It is calculated based on the predefined + * constants of the selected clock source: + * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*) + * @note If SYSCLK source is CSI, function returns values based on CSI_VALUE(**) + * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(***) + * @note If SYSCLK source is PLL, function returns values based on HSI_VALUE(*), CSI_VALUE(**) + * or HSE_VALUE(***) multiplied/divided by the PLL factors. + * @note (*) HSI_VALUE is a constant defined in stm32h5xx_hal_conf.h file (default value + * 64 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * @note (**) CSI_VALUE is a constant defined in stm32h5xx_hal_conf.h file (default value + * 4 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * @note (***) HSE_VALUE is a constant defined in stm32h5xx_hal_conf.h file (default value + * 24 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * + * @note The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @note This function can be used by the user application to compute the + * baudrate for the communication peripherals or configure other parameters. + * + * @note Each time SYSCLK changes, this function must be called to update the + * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect. + * + * + * @retval SYSCLK frequency + */ +uint32_t HAL_RCC_GetSysClockFreq(void) +{ + uint32_t pllsource; + uint32_t pllp; + uint32_t pllm; + uint32_t pllfracen; + uint32_t sysclockfreq; + uint32_t hsivalue; + float_t fracn1; + float_t pllvco; + + if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_CSI) + { + /* CSI used as system clock source */ + sysclockfreq = CSI_VALUE; + } + else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI) + { + /* HSI used as system clock source */ + if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIDIVF) != 0U) + { + sysclockfreq = (uint32_t)(HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else + { + sysclockfreq = (uint32_t) HSI_VALUE; + } + } + else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSE) + { + /* HSE used as system clock source */ + sysclockfreq = HSE_VALUE; + } + + else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) + { + /* PLL used as system clock source */ + + /* PLL_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN + SYSCLK = PLL_VCO / PLLR + */ + pllsource = (RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1SRC); + pllm = ((RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1M) >> RCC_PLL1CFGR_PLL1M_Pos); + pllfracen = ((RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1FRACEN) >> RCC_PLL1CFGR_PLL1FRACEN_Pos); + fracn1 = (float_t)(uint32_t)(pllfracen * ((RCC->PLL1FRACR & \ + RCC_PLL1FRACR_PLL1FRACN) >> RCC_PLL1FRACR_PLL1FRACN_Pos)); + + if (pllm != 0U) + { + switch (pllsource) + { + case RCC_PLL1_SOURCE_HSI: /* HSI used as PLL1 clock source */ + + if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIDIVF) != 0U) + { + hsivalue = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + pllvco = ((float_t)hsivalue / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \ + (fracn1 / (float_t)0x2000) + (float_t)1); + } + else + { + pllvco = ((float_t)HSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \ + (fracn1 / (float_t)0x2000) + (float_t)1); + } + + break; + + case RCC_PLL1_SOURCE_HSE: /* HSE used as PLL1 clock source */ + pllvco = ((float_t)HSE_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \ + (fracn1 / (float_t)0x2000) + (float_t)1); + + break; + + case RCC_PLL1_SOURCE_CSI: /* CSI used as PLL1 clock source */ + default: + pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \ + (fracn1 / (float_t)0x2000) + (float_t)1); + break; + } + + pllp = (((RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1P) >> RCC_PLL1DIVR_PLL1P_Pos) + 1U) ; + sysclockfreq = (uint32_t)(float_t)(pllvco / (float_t)pllp); + } + else + { + sysclockfreq = 0; + } + } + + else + { + /* HSI is the default system clock source */ + sysclockfreq = (uint32_t) HSI_VALUE; + } + + return sysclockfreq; +} + +/** + * @brief Return the HCLK frequency. + * @note Each time HCLK changes, this function must be called to update the + * right HCLK value. Otherwise, any configuration based on this function will be incorrect. + * + * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency. + * @retval HCLK frequency in Hz + */ +uint32_t HAL_RCC_GetHCLKFreq(void) +{ + + SystemCoreClock = HAL_RCC_GetSysClockFreq() >> (AHBPrescTable[(RCC->CFGR2 & RCC_CFGR2_HPRE) \ + >> RCC_CFGR2_HPRE_Pos] & 0x1FU); + + return SystemCoreClock; +} + +/** + * @brief Return the PCLK1 frequency. + * @note Each time PCLK1 changes, this function must be called to update the + * right PCLK1 value. Otherwise, any configuration based on this function will be incorrect. + * @retval PCLK1 frequency in Hz + */ +uint32_t HAL_RCC_GetPCLK1Freq(void) +{ + /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/ + return (HAL_RCC_GetHCLKFreq() >> ((APBPrescTable[(RCC->CFGR2 & RCC_CFGR2_PPRE1) >> RCC_CFGR2_PPRE1_Pos]) & 0x1FU)); +} + +/** + * @brief Return the PCLK2 frequency. + * @note Each time PCLK2 changes, this function must be called to update the + * right PCLK2 value. Otherwise, any configuration based on this function will be incorrect. + * @retval PCLK2 frequency in Hz + */ +uint32_t HAL_RCC_GetPCLK2Freq(void) +{ + /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/ + return (HAL_RCC_GetHCLKFreq() >> ((APBPrescTable[(RCC->CFGR2 & RCC_CFGR2_PPRE2) >> RCC_CFGR2_PPRE2_Pos]) & 0x1FU)); +} + +/** + * @brief Return the PCLK3 frequency. + * @note Each time PCLK3 changes, this function must be called to update the + * right PCLK3 value. Otherwise, any configuration based on this function will be incorrect. + * @retval PCLK3 frequency in Hz + */ +uint32_t HAL_RCC_GetPCLK3Freq(void) +{ + /* Get HCLK source and Compute PCLK3 frequency ---------------------------*/ + return (HAL_RCC_GetHCLKFreq() >> ((APBPrescTable[(RCC->CFGR2 & RCC_CFGR2_PPRE3) >> RCC_CFGR2_PPRE3_Pos]) & 0x1FU)); +} +/** + * @brief Configure the pOscInitStruct according to the internal + * RCC configuration registers. + * @param pOscInitStruct pointer to an RCC_OscInitTypeDef structure that + * will be configured. + * @retval None + */ +void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *pOscInitStruct) +{ + uint32_t regval; + uint32_t reg1val; + uint32_t reg2val; + + /* Check the parameters */ + assert_param(pOscInitStruct != (void *)NULL); + + /* Set all possible values for the Oscillator type parameter ---------------*/ + pOscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_CSI | \ + RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSI48; + + /* Get Control register */ + regval = RCC->CR; + + /* Get the HSE configuration -----------------------------------------------*/ + pOscInitStruct->HSEState = (regval & (RCC_CR_HSEON | RCC_CR_HSEBYP | RCC_CR_HSEEXT)); + + /* Get the CSI configuration -----------------------------------------------*/ + pOscInitStruct->CSIState = regval & RCC_CR_CSION; + + /* Get the HSI configuration -----------------------------------------------*/ + pOscInitStruct->HSIState = regval & RCC_CR_HSION; + pOscInitStruct->HSIDiv = regval & RCC_CR_HSIDIV; + pOscInitStruct->HSICalibrationValue = (uint32_t)(READ_BIT(RCC->HSICFGR, \ + RCC_HSICFGR_HSITRIM) >> RCC_HSICFGR_HSITRIM_Pos); + + /* Get BDCR register */ + regval = RCC->BDCR; + + /* Get the LSE configuration -----------------------------------------------*/ + pOscInitStruct->LSEState = (regval & (RCC_BDCR_LSEON | RCC_BDCR_LSEBYP | RCC_BDCR_LSEEXT)); + + /* Get the LSI configuration -----------------------------------------------*/ + pOscInitStruct->LSIState = regval & RCC_BDCR_LSION; + + /* Get Control register */ + regval = RCC->CR; + + /* Get the HSI48 configuration ---------------------------------------------*/ + pOscInitStruct->HSI48State = regval & RCC_CR_HSI48ON; + + /* Get the PLL configuration -----------------------------------------------*/ + if ((regval & RCC_CR_PLL1ON) == RCC_CR_PLL1ON) + { + pOscInitStruct->PLL.PLLState = RCC_PLL_ON; + } + else + { + pOscInitStruct->PLL.PLLState = RCC_PLL_OFF; + } + + /* Get PLL configuration register */ + reg1val = RCC->PLL1CFGR; + reg2val = RCC->PLL1DIVR; + + pOscInitStruct->PLL.PLLSource = (uint32_t)(reg1val & RCC_PLL1CFGR_PLL1SRC); + pOscInitStruct->PLL.PLLM = (uint32_t)((reg1val & RCC_PLL1CFGR_PLL1M) >> RCC_PLL1CFGR_PLL1M_Pos); + pOscInitStruct->PLL.PLLN = (uint32_t)(((reg2val & RCC_PLL1DIVR_PLL1N) >> RCC_PLL1DIVR_PLL1N_Pos) + 1U); + pOscInitStruct->PLL.PLLQ = (uint32_t)(((reg2val & RCC_PLL1DIVR_PLL1Q) >> RCC_PLL1DIVR_PLL1Q_Pos) + 1U); + pOscInitStruct->PLL.PLLR = (uint32_t)(((reg2val & RCC_PLL1DIVR_PLL1R) >> RCC_PLL1DIVR_PLL1R_Pos) + 1U); + pOscInitStruct->PLL.PLLP = (uint32_t)(((reg2val & RCC_PLL1DIVR_PLL1P) >> RCC_PLL1DIVR_PLL1P_Pos) + 1U); + pOscInitStruct->PLL.PLLRGE = (uint32_t)((reg1val & RCC_PLL1CFGR_PLL1RGE)); + pOscInitStruct->PLL.PLLVCOSEL = (uint32_t)((reg1val & RCC_PLL1CFGR_PLL1VCOSEL) >> RCC_PLL1CFGR_PLL1VCOSEL_Pos); + pOscInitStruct->PLL.PLLFRACN = (uint32_t)(((RCC->PLL1FRACR & RCC_PLL1FRACR_PLL1FRACN) \ + >> RCC_PLL1FRACR_PLL1FRACN_Pos)); +} + +/** + * @brief Configure the pClkInitStruct according to the internal + * RCC configuration registers. + * @param pClkInitStruct pointer to an RCC_ClkInitTypeDef structure that + * will be configured. + * @param pFLatency Pointer on the Flash Latency. + * @retval None + */ +void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *pClkInitStruct, uint32_t *pFLatency) +{ + uint32_t regval; + + /* Check the parameters */ + assert_param(pClkInitStruct != (void *)NULL); + assert_param(pFLatency != (void *)NULL); + + /* Set all possible values for the Clock type parameter --------------------*/ + pClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | \ + RCC_CLOCKTYPE_PCLK3; + + /* Get the SYSCLK configuration --------------------------------------------*/ + pClkInitStruct->SYSCLKSource = (uint32_t)(RCC->CFGR1 & RCC_CFGR1_SW); + + /* Get the HCLK configuration ----------------------------------------------*/ + regval = RCC->CFGR2; + pClkInitStruct->AHBCLKDivider = (uint32_t)(regval & RCC_CFGR2_HPRE); + + /* Get the APB1 configuration ----------------------------------------------*/ + pClkInitStruct->APB1CLKDivider = (uint32_t)(regval & RCC_CFGR2_PPRE1); + + /* Get the APB2 configuration ----------------------------------------------*/ + pClkInitStruct->APB2CLKDivider = (uint32_t)((regval & RCC_CFGR2_PPRE2) >> 4); + + /* Get the APB3 configuration ----------------------------------------------*/ + pClkInitStruct->APB3CLKDivider = (uint32_t)((regval & RCC_CFGR2_PPRE3) >> 8); + + /* Get the Flash Wait State (Latency) configuration ------------------------*/ + *pFLatency = (uint32_t)(FLASH->ACR & FLASH_ACR_LATENCY); +} + +/** + * @brief Get and clear reset flags + * @note Once reset flags are retrieved, this API is clearing them in order + * to isolate next reset reason. + * @retval can be a combination of @ref RCC_Reset_Flag + */ +uint32_t HAL_RCC_GetResetSource(void) +{ + uint32_t reset; + + /* Get all reset flags */ + reset = RCC->RSR & RCC_RESET_FLAG_ALL; + + /* Clear Reset flags */ + RCC->RSR |= RCC_RSR_RMVF; + + return reset; +} + +/** + * @brief Enable the HSE Clock Security System. + * @note If a failure is detected on the HSE oscillator clock, this oscillator + * is automatically disabled and an interrupt is generated to inform the + * software about the failure (Clock Security System Interrupt, CSSI), + * allowing the MCU to perform rescue operations. The CSSI is linked to + * the Cortex-M NMI (Non-Maskable Interrupt) exception vector. + * @note The Clock Security System can only be cleared by reset. + * @retval None + */ +void HAL_RCC_EnableCSS(void) +{ + SET_BIT(RCC->CR, RCC_CR_HSECSSON); +} + +/** + * @brief Handle the RCC Clock Security System interrupt request. + * @note This API should be called under the NMI_Handler(). + * @retval None + */ +void HAL_RCC_NMI_IRQHandler(void) +{ + /* Check RCC CSSF interrupt flag */ + if (__HAL_RCC_GET_IT(RCC_IT_HSECSS)) + { + /* RCC Clock Security System interrupt user callback */ + HAL_RCC_CSSCallback(); + + /* Clear RCC CSS pending bit */ + __HAL_RCC_CLEAR_IT(RCC_IT_HSECSS); + } +} + +/** + * @brief RCC HSE Clock Security System interrupt callback. + * @retval none + */ +__weak void HAL_RCC_CSSCallback(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RCC_CSSCallback should be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup RCC_Exported_Functions_Group3 Attributes management functions + * @brief Attributes management functions. + * +@verbatim + =============================================================================== + ##### RCC attributes functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to: + + (+) Configure the RCC item(s) attributes. + (+) Get the attribute of an RCC item. + +@endverbatim + * @{ + */ +/** + * @brief Configure the RCC item(s) attribute(s). + * @note Available attributes are to secure items and set RCC as privileged (*). + * Default state is non-secure and unprivileged access allowed. + * @note Secure and non-secure attributes can only be set from the secure + * state when the system implements the security (TZEN=1). + * @param Item Item(s) to set attributes on. + * This parameter can be a one or a combination of @ref RCC_items (**). + * @param Attributes specifies the RCC secure/privilege attributes. + * This parameter can be a value of @ref RCC_attributes + * @retval None + * + * (*) : For stm32h503xx devices, attributes specifies the privilege attribute only (no items). + * (**) : For stm32h503xx devices, this parameter is unused, it can take 0 or any other numerical value. + */ +void HAL_RCC_ConfigAttributes(uint32_t Item, uint32_t Attributes) +{ + + /* Check the parameters */ + assert_param(IS_RCC_ATTRIBUTES(Attributes)); + +#if defined(RCC_SECCFGR_HSISEC) + assert_param(IS_RCC_ITEM_ATTRIBUTES(Item)); + + switch (Attributes) + { +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + /* Secure Privilege attribute */ + case RCC_SEC_PRIV: + SET_BIT(RCC->SECCFGR, Item); + SET_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_SPRIV); + break; + /* Secure Non-Privilege attribute */ + case RCC_SEC_NPRIV: + SET_BIT(RCC->SECCFGR, Item); + CLEAR_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_SPRIV); + break; + /* Non-secure Privilege attribute */ + case RCC_NSEC_PRIV: + CLEAR_BIT(RCC->SECCFGR, Item); + SET_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_NSPRIV); + break; + /* Non-secure Non-Privilege attribute */ + case RCC_NSEC_NPRIV: + CLEAR_BIT(RCC->SECCFGR, Item); + CLEAR_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_NSPRIV); + break; +#else /* __ARM_FEATURE_CMSE */ + /* Non-secure Privilege attribute */ + case RCC_NSEC_PRIV: + SET_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_NSPRIV); + break; + /* Non-secure Non-Privilege attribute */ + case RCC_NSEC_NPRIV: + CLEAR_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_NSPRIV); + break; +#endif /* __ARM_FEATURE_CMSE */ + default: + /* Nothing to do */ + break; + } + +#else /* RCC_SECCFGR_HSISEC */ + + UNUSED(Item); + + switch (Attributes) + { + /* Privilege attribute */ + case RCC_PRIV: + SET_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_PRIV); + break; + /* Non-secure Non-Privilege attribute */ + case RCC_NPRIV: + CLEAR_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_PRIV); + break; + default: + /* Nothing to do */ + break; + } + +#endif /* RCC_SECCFGR_HSISEC */ +} + +/** + * @brief Get the attribute of an RCC item. + * @note Secure and non-secure attributes are only available from secure state + * when the system implements the security (TZEN=1) + * @param Item Single item to get secure/non-secure and privilege/non-privilege attribute from. + * This parameter can be a one value of @ref RCC_items except RCC_ALL. (*) + * @param pAttributes pointer to return the attributes. + * @retval HAL Status. + * + * (*) : This parameter is unused for stm32h503xx devices, it can take 0 or any other numerical value. + */ +HAL_StatusTypeDef HAL_RCC_GetConfigAttributes(uint32_t Item, uint32_t *pAttributes) +{ + uint32_t attributes; + + /* Check null pointer */ + if (pAttributes == NULL) + { + return HAL_ERROR; + } + +#if defined(RCC_SECCFGR_HSISEC) + /* Check the parameters */ + assert_param(IS_RCC_SINGLE_ITEM_ATTRIBUTES(Item)); + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + + /* Check item security */ + if ((RCC->SECCFGR & Item) == Item) + { + /* Get Secure privileges attribute */ + attributes = ((RCC->PRIVCFGR & RCC_PRIVCFGR_SPRIV) == 0U) ? RCC_SEC_NPRIV : RCC_SEC_PRIV; + } + else + { + /* Get Non-Secure privileges attribute */ + attributes = ((RCC->PRIVCFGR & RCC_PRIVCFGR_NSPRIV) == 0U) ? RCC_NSEC_NPRIV : RCC_NSEC_PRIV; + } +#else /* __ARM_FEATURE_CMSE */ + attributes = ((RCC->PRIVCFGR & RCC_PRIVCFGR_NSPRIV) == 0U) ? RCC_NSEC_NPRIV : RCC_NSEC_PRIV; +#endif /* __ARM_FEATURE_CMSE */ + +#else /* RCC_SECCFGR_HSISEC */ + UNUSED(Item); + /* Get privileges attribute */ + attributes = ((RCC->PRIVCFGR & RCC_PRIVCFGR_PRIV) == 0U) ? RCC_NPRIV : RCC_PRIV; +#endif /* RCC_SECCFGR_HSISEC */ + + /* return value */ + *pAttributes = attributes; + + return HAL_OK; +} + +/** + * @} + */ + +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +#endif /* HAL_RCC_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rcc_ex.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rcc_ex.c new file mode 100644 index 0000000000..70da9ff5a5 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rcc_ex.c @@ -0,0 +1,6273 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_rcc_ex.c + * @author MCD Application Team + * @brief Extended RCC HAL module driver. + * This file provides firmware functions to manage the following + * functionalities RCC extended peripheral: + * + Extended Peripheral Control functions + * + Extended Clock management functions + * + Extended Clock Recovery System Control functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup RCCEx RCCEx + * @brief RCC Extended HAL module driver + * @{ + */ + +#ifdef HAL_RCC_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ +/** @defgroup RCCEx_Private_Constants RCCEx Private Constants + * @{ + */ +#define PLL1_TIMEOUT_VALUE ((uint32_t)2U) /* 2 ms (minimum Tick + 1) */ +#define PLL2_TIMEOUT_VALUE ((uint32_t)2U) /* 2 ms (minimum Tick + 1) */ +#if defined(RCC_CR_PLL3ON) +#define PLL3_TIMEOUT_VALUE ((uint32_t)2U) /* 2 ms (minimum Tick + 1) */ +#endif /* RCC_CR_PLL3ON */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup RCCEx_Private_Functions RCCEx Private Functions + * @{ + */ +static HAL_StatusTypeDef RCCEx_PLLSource_Enable(uint32_t PllSource); +static HAL_StatusTypeDef RCCEx_PLL2_Config(const RCC_PLL2InitTypeDef *Pll2); +#if defined(RCC_CR_PLL3ON) +static HAL_StatusTypeDef RCCEx_PLL3_Config(const RCC_PLL3InitTypeDef *Pll3); +#endif /* RCC_CR_PLL3ON */ +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions + * @{ + */ + +/** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions + * @brief Extended Peripheral Control functions + * +@verbatim + =============================================================================== + ##### Extended Peripheral Control functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the RCC Clocks + frequencies. + [..] + (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to + select the RTC clock source; in this case the Backup domain will be reset in + order to modify the RTC Clock source, as consequence RTC registers (including + the backup registers) are set to their reset values. + +@endverbatim + * @{ + */ +/** + * @brief Initialize the RCC extended peripherals clocks according to the specified + * parameters in the RCC_PeriphCLKInitTypeDef. + * @param pPeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that + * contains a field PeriphClockSelection which can be a combination of the following values: + * @arg @ref RCC_PERIPHCLK_USART1 USART1 peripheral clock + * @arg @ref RCC_PERIPHCLK_USART2 USART2 peripheral clock + * @arg @ref RCC_PERIPHCLK_USART3 USART3 peripheral clock + * @arg @ref RCC_PERIPHCLK_UART4 UART4 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_UART5 UART5 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_USART6 USART6 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_UART7 UART7 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_UART8 UART8 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_UART9 UART9 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_USART10 USART10 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_USART11 USART11 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_UART12 UART12 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_LPUART1 LPUART1 peripheral clock + * @arg @ref RCC_PERIPHCLK_I2C1 I2C1 peripheral clock + * @arg @ref RCC_PERIPHCLK_I2C2 I2C2 peripheral clock + * @arg @ref RCC_PERIPHCLK_I2C3 I2C3 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_I2C4 I2C4 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_I3C1 I3C1 peripheral clock + * @arg @ref RCC_PERIPHCLK_I3C2 I3C2 peripheral clock (***) + * @arg @ref RCC_PERIPHCLK_LPTIM1 LPTIM1 peripheral clock + * @arg @ref RCC_PERIPHCLK_LPTIM2 LPTIM2 peripheral clock + * @arg @ref RCC_PERIPHCLK_SAI1 SAI1 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_SAI2 SAI2 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_ADCDAC ADCDAC peripheral clock + * @arg @ref RCC_PERIPHCLK_ADC ADC peripheral clock + * @arg @ref RCC_PERIPHCLK_SDMMC1 SDMMC1 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_SDMMC2 SDMMC2 peripheral clock (**) + * @arg @ref RCC_PERIPHCLK_CKPER CKPER peripheral clock + * @arg @ref RCC_PERIPHCLK_RTC RTC peripheral clock + * @arg @ref RCC_PERIPHCLK_RNG RNG peripheral clock + * @arg @ref RCC_PERIPHCLK_SPI1 SPI1 peripheral clock + * @arg @ref RCC_PERIPHCLK_SPI2 SPI2 peripheral clock + * @arg @ref RCC_PERIPHCLK_SPI3 SPI3 peripheral clock + * @arg @ref RCC_PERIPHCLK_SPI4 SPI4 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_SPI5 SPI5 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_SPI6 SPI6 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_OSPI OCTOSPI peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_FDCAN FDCAN peripheral clock + * @arg @ref RCC_PERIPHCLK_CEC CEC peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock + * @arg @ref RCC_PERIPHCLK_LPTIM3 LPTIM3 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_LPTIM4 LPTIM4 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_LPTIM5 LPTIM5 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_LPTIM6 LPTIM6 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_DAC_LP DAC peripheral low-power clock + * @arg @ref RCC_PERIPHCLK_TIM TIM peripheral clock + * + * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select + * the RTC clock source: in this case the access to Backup domain is enabled. + * + * @retval HAL status + * + * (*) : For stm32h56xxx and stm32h57xxx family lines only. + * (**) : For stm32h563xx and stm32h57xxx family lines only. + * (***) : For stm32h503xx family line only. + */ +HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(const RCC_PeriphCLKInitTypeDef *pPeriphClkInit) +{ + uint32_t tmpregister; + uint32_t tickstart; + HAL_StatusTypeDef ret = HAL_OK; /* Intermediate status */ + HAL_StatusTypeDef status = HAL_OK; /* Final status */ + + /* Check the parameters */ + assert_param(IS_RCC_PERIPHCLOCK(pPeriphClkInit->PeriphClockSelection)); + + /*------------------------------------ CKPER configuration --------------------------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CKPER) == RCC_PERIPHCLK_CKPER) + { + /* Check the parameters */ + assert_param(IS_RCC_CLKPSOURCE(pPeriphClkInit->CkperClockSelection)); + + /* Configure the CKPER clock source */ + __HAL_RCC_CLKP_CONFIG(pPeriphClkInit->CkperClockSelection); + } + + /*-------------------------- USART1 clock source configuration -------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1) + { + /* Check the parameters */ + assert_param(IS_RCC_USART1CLKSOURCE(pPeriphClkInit->Usart1ClockSelection)); + + switch (pPeriphClkInit->Usart1ClockSelection) + { + case RCC_USART1CLKSOURCE_PCLK2: /* PCLK2 is used as clock source for USART1*/ + + /* USART1 clock source config set later after clock selection check */ + break; + + case RCC_USART1CLKSOURCE_PLL2Q: /* PLL2 is used as clock source for USART1*/ + /* PLL2 input clock, parameters M, N & Q configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + /* USART1 clock source config set later after clock selection check */ + break; +#if defined(RCC_USART1CLKSOURCE_PLL3Q) + case RCC_USART1CLKSOURCE_PLL3Q: /* PLL3 is used as clock source for USART1*/ + /* PLL3 input clock, parameters M, N & Q configuration clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + /* USART1 clock source config set later after clock selection check */ + break; +#endif /* RCC_CR_PLL3ON */ + + case RCC_USART1CLKSOURCE_HSI: /* HSI clock is used as source of USART1 clock*/ + /* USART1 clock source config set later after clock selection check */ + break; + + case RCC_USART1CLKSOURCE_CSI: /* CSI clock is used as source of USART1 clock*/ + /* USART1 clock source config set later after clock selection check */ + break; + + case RCC_USART1CLKSOURCE_LSE: /* LSE clock is used as source of USART1 clock*/ + /* USART1 clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of USART1 clock*/ + __HAL_RCC_USART1_CONFIG(pPeriphClkInit->Usart1ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*-------------------------- USART2 clock source configuration -------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART2) == RCC_PERIPHCLK_USART2) + { + /* Check the parameters */ + assert_param(IS_RCC_USART2CLKSOURCE(pPeriphClkInit->Usart2ClockSelection)); + + switch (pPeriphClkInit->Usart2ClockSelection) + { + case RCC_USART2CLKSOURCE_PCLK1: /* PCLK1 is used as clock source for USART2*/ + + /* USART2 clock source config set later after clock selection check */ + break; + + case RCC_USART2CLKSOURCE_PLL2Q: /* PLL2 is used as clock source for USART2*/ + /* PLL2 input clock, parameters M, N & Q configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + /* USART2 clock source config set later after clock selection check */ + break; + +#if defined(RCC_USART2CLKSOURCE_PLL3Q) + case RCC_USART2CLKSOURCE_PLL3Q: /* PLL3 is used as clock source for USART2*/ + /* PLL3 input clock, parameters M, N & Q configuration clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + /* USART2 clock source config set later after clock selection check */ + break; +#endif /* RCC_USART2CLKSOURCE_PLL3 */ + + case RCC_USART2CLKSOURCE_HSI: /* HSI clock is used as source of USART2 clock*/ + /* USART2 clock source config set later after clock selection check */ + break; + + case RCC_USART2CLKSOURCE_CSI: /* CSI clock is used as source of USART2 clock*/ + /* USART2 clock source config set later after clock selection check */ + break; + + case RCC_USART2CLKSOURCE_LSE: /* LSE clock is used as source of USART2 clock*/ + /* USART2 clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of USART2 clock*/ + __HAL_RCC_USART2_CONFIG(pPeriphClkInit->Usart2ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*-------------------------- USART3 clock source configuration -------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART3) == RCC_PERIPHCLK_USART3) + { + /* Check the parameters */ + assert_param(IS_RCC_USART3CLKSOURCE(pPeriphClkInit->Usart3ClockSelection)); + + switch (pPeriphClkInit->Usart3ClockSelection) + { + case RCC_USART3CLKSOURCE_PCLK1: /* PCLK1 is used as clock source for USART3*/ + + /* USART3 clock source config set later after clock selection check */ + break; + + case RCC_USART3CLKSOURCE_PLL2Q: /* PLL2 is used as clock source for USART3*/ + /* PLL2 input clock, parameters M, N & Q configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + /* USART3 clock source config set later after clock selection check */ + break; + +#if defined(RCC_USART3CLKSOURCE_PLL3Q) + case RCC_USART3CLKSOURCE_PLL3Q: /* PLL3 is used as clock source for USART3*/ + /* PLL3 input clock, parameters M, N & Q configuration clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + /* USART3 clock source config set later after clock selection check */ + break; +#endif /* RCC_USART3CLKSOURCE_PLL3 */ + + case RCC_USART3CLKSOURCE_HSI: /* HSI clock is used as source of USART3 clock*/ + /* USART3 clock source config set later after clock selection check */ + break; + + case RCC_USART3CLKSOURCE_CSI: /* CSI clock is used as source of USART3 clock*/ + /* USART3 clock source config set later after clock selection check */ + break; + + case RCC_USART3CLKSOURCE_LSE: /* LSE clock is used as source of USART3 clock*/ + /* USART3 clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of USART3 clock*/ + __HAL_RCC_USART3_CONFIG(pPeriphClkInit->Usart3ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + +#if defined(UART4) + /*-------------------------- UART4 clock source configuration --------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART4) == RCC_PERIPHCLK_UART4) + { + /* Check the parameters */ + assert_param(IS_RCC_UART4CLKSOURCE(pPeriphClkInit->Uart4ClockSelection)); + + switch (pPeriphClkInit->Uart4ClockSelection) + { + case RCC_UART4CLKSOURCE_PCLK1: /* PCLK1 is used as clock source for UART4*/ + + /* UART4 clock source config set later after clock selection check */ + break; + + case RCC_UART4CLKSOURCE_PLL2Q: /* PLL2 is used as clock source for UART4*/ + /* PLL2 input clock, parameters M, N & Q configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + /* UART4 clock source config set later after clock selection check */ + break; + + case RCC_UART4CLKSOURCE_PLL3Q: /* PLL3 is used as clock source for UART4*/ + /* PLL3 input clock, parameters M, N & Q configuration clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + /* UART4 clock source config set later after clock selection check */ + break; + + case RCC_UART4CLKSOURCE_HSI: /* HSI clock is used as source of UART4 clock*/ + /* UART4 clock source config set later after clock selection check */ + break; + + case RCC_UART4CLKSOURCE_CSI: /* CSI clock is used as source of UART4 clock*/ + /* UART4 clock source config set later after clock selection check */ + break; + + case RCC_UART4CLKSOURCE_LSE: /* LSE clock is used as source of UART4 clock*/ + /* UART4 clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of UART4 clock*/ + __HAL_RCC_UART4_CONFIG(pPeriphClkInit->Uart4ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } +#endif /* UART4 */ + +#if defined(UART5) + /*-------------------------- UART5 clock source configuration --------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART5) == RCC_PERIPHCLK_UART5) + { + /* Check the parameters */ + assert_param(IS_RCC_UART5CLKSOURCE(pPeriphClkInit->Uart5ClockSelection)); + + switch (pPeriphClkInit->Uart5ClockSelection) + { + case RCC_UART5CLKSOURCE_PCLK1: /* PCLK1 is used as clock source for UART5*/ + + /* UART5 clock source config set later after clock selection check */ + break; + + case RCC_UART5CLKSOURCE_PLL2Q: /* PLL2 is used as clock source for UART5*/ + /* PLL2 input clock, parameters M, N & Q configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + /* UART5 clock source config set later after clock selection check */ + break; + + case RCC_UART5CLKSOURCE_PLL3Q: /* PLL3 is used as clock source for UART5*/ + /* PLL3 input clock, parameters M, N & Q configuration clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + /* UART5 clock source config set later after clock selection check */ + break; + + case RCC_UART5CLKSOURCE_HSI: /* HSI clock is used as source of UART5 clock*/ + /* UART5 clock source config set later after clock selection check */ + break; + + case RCC_UART5CLKSOURCE_CSI: /* CSI clock is used as source of UART5 clock*/ + /* UART5 clock source config set later after clock selection check */ + break; + + case RCC_UART5CLKSOURCE_LSE: /* LSE clock is used as source of UART5 clock*/ + /* UART5 clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of UART5 clock*/ + __HAL_RCC_UART5_CONFIG(pPeriphClkInit->Uart5ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } +#endif /* UART5 */ + +#if defined(USART6) + /*-------------------------- USART6 clock source configuration -------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART6) == RCC_PERIPHCLK_USART6) + { + /* Check the parameters */ + assert_param(IS_RCC_USART6CLKSOURCE(pPeriphClkInit->Usart6ClockSelection)); + + switch (pPeriphClkInit->Usart6ClockSelection) + { + case RCC_USART6CLKSOURCE_PCLK1: /* PCLK1 is used as clock source for USART6*/ + + /* USART6 clock source config set later after clock selection check */ + break; + + case RCC_USART6CLKSOURCE_PLL2Q: /* PLL2 is used as clock source for USART6*/ + /* PLL2 input clock, parameters M, N & Q configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + /* USART6 clock source config set later after clock selection check */ + break; + + case RCC_USART6CLKSOURCE_PLL3Q: /* PLL3 is used as clock source for USART6*/ + /* PLL3 input clock, parameters M, N & Q configuration clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + /* USART6 clock source config set later after clock selection check */ + break; + + case RCC_USART6CLKSOURCE_HSI: /* HSI clock is used as source of USART6 clock*/ + /* USART6 clock source config set later after clock selection check */ + break; + + case RCC_USART6CLKSOURCE_CSI: /* CSI clock is used as source of USART6 clock*/ + /* USART6 clock source config set later after clock selection check */ + break; + + case RCC_USART6CLKSOURCE_LSE: /* LSE clock is used as source of USART6 clock*/ + /* USART6 clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of USART6 clock*/ + __HAL_RCC_USART6_CONFIG(pPeriphClkInit->Usart6ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } +#endif /* USART6 */ + +#if defined(UART7) + /*-------------------------- UART7 clock source configuration -------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART7) == RCC_PERIPHCLK_UART7) + { + /* Check the parameters */ + assert_param(IS_RCC_UART7CLKSOURCE(pPeriphClkInit->Uart7ClockSelection)); + + switch (pPeriphClkInit->Uart7ClockSelection) + { + case RCC_UART7CLKSOURCE_PCLK1: /* PCLK1 is used as clock source for UART7*/ + + /* UART7 clock source config set later after clock selection check */ + break; + + case RCC_UART7CLKSOURCE_PLL2Q: /* PLL2 is used as clock source for UART7*/ + /* PLL2 input clock, parameters M, N & Q configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + /* UART7 clock source config set later after clock selection check */ + break; + + case RCC_UART7CLKSOURCE_PLL3Q: /* PLL3 is used as clock source for UART7*/ + /* PLL3 input clock, parameters M, N & Q configuration clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + /* UART7 clock source config set later after clock selection check */ + break; + + case RCC_UART7CLKSOURCE_HSI: /* HSI clock is used as source of UART7 clock*/ + /* UART7 clock source config set later after clock selection check */ + break; + + case RCC_UART7CLKSOURCE_CSI: /* CSI clock is used as source of UART7 clock*/ + /* UART7 clock source config set later after clock selection check */ + break; + + case RCC_UART7CLKSOURCE_LSE: /* LSE clock is used as source of UART7 clock*/ + /* UART7 clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of UART7 clock*/ + __HAL_RCC_UART7_CONFIG(pPeriphClkInit->Uart7ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } +#endif /* UART7 */ + +#if defined(UART8) + /*-------------------------- UART8 clock source configuration -------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART8) == RCC_PERIPHCLK_UART8) + { + /* Check the parameters */ + assert_param(IS_RCC_UART8CLKSOURCE(pPeriphClkInit->Uart8ClockSelection)); + + switch (pPeriphClkInit->Uart8ClockSelection) + { + case RCC_UART8CLKSOURCE_PCLK1: /* PCLK1 is used as clock source for UART8*/ + + /* UART8 clock source config set later after clock selection check */ + break; + + case RCC_UART8CLKSOURCE_PLL2Q: /* PLL2 is used as clock source for UART8*/ + /* PLL2 input clock, parameters M, N & Q configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + /* UART8 clock source config set later after clock selection check */ + break; + + case RCC_UART8CLKSOURCE_PLL3Q: /* PLL3 is used as clock source for UART8*/ + /* PLL3 input clock, parameters M, N & Q configuration clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + /* UART8 clock source config set later after clock selection check */ + break; + + case RCC_UART8CLKSOURCE_HSI: /* HSI clock is used as source of UART8 clock*/ + /* UART8 clock source config set later after clock selection check */ + break; + + case RCC_UART8CLKSOURCE_CSI: /* CSI clock is used as source of UART8 clock*/ + /* UART8 clock source config set later after clock selection check */ + break; + + case RCC_UART8CLKSOURCE_LSE: /* LSE clock is used as source of UART8 clock*/ + /* UART8 clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of UART8 clock*/ + __HAL_RCC_UART8_CONFIG(pPeriphClkInit->Uart8ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } +#endif /* UART9 */ + +#if defined(UART9) + /*-------------------------- UART9 clock source configuration -------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART9) == RCC_PERIPHCLK_UART9) + { + /* Check the parameters */ + assert_param(IS_RCC_UART9CLKSOURCE(pPeriphClkInit->Uart9ClockSelection)); + + switch (pPeriphClkInit->Uart9ClockSelection) + { + case RCC_UART9CLKSOURCE_PCLK1: /* PCLK1 is used as clock source for UART9*/ + + /* UART9 clock source config set later after clock selection check */ + break; + + case RCC_UART9CLKSOURCE_PLL2Q: /* PLL2 is used as clock source for UART9*/ + /* PLL2 input clock, parameters M, N & Q configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + /* UART9 clock source config set later after clock selection check */ + break; + + case RCC_UART9CLKSOURCE_PLL3Q: /* PLL3 is used as clock source for UART9*/ + /* PLL3 input clock, parameters M, N & Q configuration clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + /* UART9 clock source config set later after clock selection check */ + break; + + case RCC_UART9CLKSOURCE_HSI: /* HSI clock is used as source of UART9 clock*/ + /* UART9 clock source config set later after clock selection check */ + break; + + case RCC_UART9CLKSOURCE_CSI: /* CSI clock is used as source of UART9 clock*/ + /* UART9 clock source config set later after clock selection check */ + break; + + case RCC_UART9CLKSOURCE_LSE: /* LSE clock is used as source of UART9 clock*/ + /* UART9 clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of UART9 clock*/ + __HAL_RCC_UART9_CONFIG(pPeriphClkInit->Uart9ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } +#endif /* UART9 */ + +#if defined(USART10) + /*-------------------------- USART10 clock source configuration -------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART10) == RCC_PERIPHCLK_USART10) + { + /* Check the parameters */ + assert_param(IS_RCC_USART10CLKSOURCE(pPeriphClkInit->Usart10ClockSelection)); + + switch (pPeriphClkInit->Usart10ClockSelection) + { + case RCC_USART10CLKSOURCE_PCLK1: /* PCLK1 is used as clock source for USART10*/ + + /* USART10 clock source config set later after clock selection check */ + break; + + case RCC_USART10CLKSOURCE_PLL2Q: /* PLL2 is used as clock source for USART10*/ + /* PLL2 input clock, parameters M, N & Q configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + /* USART10 clock source config set later after clock selection check */ + break; + + case RCC_USART10CLKSOURCE_PLL3Q: /* PLL3 is used as clock source for USART10*/ + /* PLL3 input clock, parameters M, N & Q configuration clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + /* USART10 clock source config set later after clock selection check */ + break; + + case RCC_USART10CLKSOURCE_HSI: /* HSI clock is used as source of USART10 clock*/ + /* USART10 clock source config set later after clock selection check */ + break; + + case RCC_USART10CLKSOURCE_CSI: /* CSI clock is used as source of USART10 clock*/ + /* USART10 clock source config set later after clock selection check */ + break; + + case RCC_USART10CLKSOURCE_LSE: /* LSE clock is used as source of USART10 clock*/ + /* USART10 clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of USART10 clock*/ + __HAL_RCC_USART10_CONFIG(pPeriphClkInit->Usart10ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } +#endif /* USART10 */ + +#if defined(USART11) + /*-------------------------- USART11 clock source configuration -------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART11) == RCC_PERIPHCLK_USART11) + { + /* Check the parameters */ + assert_param(IS_RCC_USART11CLKSOURCE(pPeriphClkInit->Usart11ClockSelection)); + + switch (pPeriphClkInit->Usart11ClockSelection) + { + case RCC_USART11CLKSOURCE_PCLK1: /* PCLK1 is used as clock source for USART11*/ + + /* USART11 clock source config set later after clock selection check */ + break; + + case RCC_USART11CLKSOURCE_PLL2Q: /* PLL2 is used as clock source for USART11*/ + /* PLL2 input clock, parameters M, N & Q configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + /* USART11 clock source config set later after clock selection check */ + break; + + case RCC_USART11CLKSOURCE_PLL3Q: /* PLL3 is used as clock source for USART11*/ + /* PLL3 input clock, parameters M, N & Q configuration clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + /* USART11 clock source config set later after clock selection check */ + break; + + case RCC_USART11CLKSOURCE_HSI: /* HSI clock is used as source of USART11 clock*/ + /* USART11 clock source config set later after clock selection check */ + break; + + case RCC_USART11CLKSOURCE_CSI: /* CSI clock is used as source of USART11 clock*/ + /* USART11 clock source config set later after clock selection check */ + break; + + case RCC_USART11CLKSOURCE_LSE: /* LSE clock is used as source of USART11 clock*/ + /* USART11 clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of USART11 clock*/ + __HAL_RCC_USART11_CONFIG(pPeriphClkInit->Usart11ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } +#endif /*USART11*/ + +#if defined(UART12) + /*-------------------------- UART12 clock source configuration -------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART12) == RCC_PERIPHCLK_UART12) + { + /* Check the parameters */ + assert_param(IS_RCC_UART12CLKSOURCE(pPeriphClkInit->Uart12ClockSelection)); + + switch (pPeriphClkInit->Uart12ClockSelection) + { + case RCC_UART12CLKSOURCE_PCLK1: /* PCLK1 is used as clock source for UART12*/ + + /* UART12 clock source config set later after clock selection check */ + break; + + case RCC_UART12CLKSOURCE_PLL2Q: /* PLL2 is used as clock source for UART12*/ + /* PLL2 input clock, parameters M, N & Q configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + /* UART12 clock source config set later after clock selection check */ + break; + + case RCC_UART12CLKSOURCE_PLL3Q: /* PLL3 is used as clock source for UART12*/ + /* PLL3 input clock, parameters M, N & Q configuration clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + /* UART12 clock source config set later after clock selection check */ + break; + + case RCC_UART12CLKSOURCE_HSI: /* HSI clock is used as source of UART12 clock*/ + /* UART12 clock source config set later after clock selection check */ + break; + + case RCC_UART12CLKSOURCE_CSI: /* CSI clock is used as source of UART12 clock*/ + /* UART12 clock source config set later after clock selection check */ + break; + + case RCC_UART12CLKSOURCE_LSE: /* LSE clock is used as source of UART12 clock*/ + /* UART12 clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of UART12 clock*/ + __HAL_RCC_UART12_CONFIG(pPeriphClkInit->Uart12ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } +#endif /* UART12 */ + + /*-------------------------- LPUART1 clock source configuration ------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPUART1) == RCC_PERIPHCLK_LPUART1) + { + /* Check the parameters */ + assert_param(IS_RCC_LPUART1CLKSOURCE(pPeriphClkInit->Lpuart1ClockSelection)); + + switch (pPeriphClkInit->Lpuart1ClockSelection) + { + case RCC_LPUART1CLKSOURCE_PCLK3: /* PCLK3 is used as clock source for LPUART1*/ + + /* LPUART1 clock source config set later after clock selection check */ + break; + + case RCC_LPUART1CLKSOURCE_PLL2Q: /* PLL2 is used as clock source for LPUART1*/ + /* PLL2 input clock, parameters M, N & Q configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + /* LPUART1 clock source config set later after clock selection check */ + break; + +#if defined(RCC_LPUART1CLKSOURCE_PLL3Q) + case RCC_LPUART1CLKSOURCE_PLL3Q: /* PLL3 is used as clock source for LPUART1*/ + /* PLL3 input clock, parameters M, N & Q configuration clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + /* LPUART1 clock source config set later after clock selection check */ + break; +#endif /* RCC_LPUART1CLKSOURCE_PLL3Q */ + + case RCC_LPUART1CLKSOURCE_HSI: /* HSI clock is used as source of LPUART1 clock*/ + /* LPUART1 clock source config set later after clock selection check */ + break; + + case RCC_LPUART1CLKSOURCE_CSI: /* CSI clock is used as source of LPUART1 clock*/ + /* LPUART1 clock source config set later after clock selection check */ + break; + + case RCC_LPUART1CLKSOURCE_LSE: /* LSE clock is used as source of LPUART1 clock*/ + /* LPUART1 clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of LPUART1 clock*/ + __HAL_RCC_LPUART1_CONFIG(pPeriphClkInit->Lpuart1ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*-------------------------- I2C1 clock source configuration ---------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1) + { + /* Check the parameters */ + assert_param(IS_RCC_I2C1CLKSOURCE(pPeriphClkInit->I2c1ClockSelection)); + + switch (pPeriphClkInit->I2c1ClockSelection) + { + case RCC_I2C1CLKSOURCE_PCLK1: /* PCLK1 is used as clock source for I2C1*/ + + /* I2C1 clock source config set later after clock selection check */ + break; + +#if defined(RCC_I2C1CLKSOURCE_PLL3R) + case RCC_I2C1CLKSOURCE_PLL3R: /* PLL3 is used as clock source for I2C1*/ + /* PLL3 input clock, parameters M, N & R configuration clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); +#else + case RCC_I2C1CLKSOURCE_PLL2R: /* PLL2 is used as clock source for I2C1*/ + /* PLL2 input clock, parameters M, N & R configuration clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); +#endif /* RCC_I2C1CLKSOURCE_PLL3R */ + /* I2C1 clock source config set later after clock selection check */ + break; + + + case RCC_I2C1CLKSOURCE_HSI: /* HSI clock is used as source of I2C1 clock*/ + /* I2C1 clock source config set later after clock selection check */ + break; + + case RCC_I2C1CLKSOURCE_CSI: /* CSI clock is used as source of I2C1 clock*/ + /* I2C1 clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of I2C1 clock*/ + __HAL_RCC_I2C1_CONFIG(pPeriphClkInit->I2c1ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*-------------------------- I2C2 clock source configuration ---------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C2) == RCC_PERIPHCLK_I2C2) + { + /* Check the parameters */ + assert_param(IS_RCC_I2C2CLKSOURCE(pPeriphClkInit->I2c2ClockSelection)); + + switch (pPeriphClkInit->I2c2ClockSelection) + { + case RCC_I2C2CLKSOURCE_PCLK1: /* PCLK1 is used as clock source for I2C2*/ + + /* I2C2 clock source config set later after clock selection check */ + break; + +#if defined(RCC_I2C2CLKSOURCE_PLL3R) + case RCC_I2C2CLKSOURCE_PLL3R: /* PLL3 is used as clock source for I2C2*/ + /* PLL3 input clock, parameters M, N & R configuration clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); +#else + case RCC_I2C2CLKSOURCE_PLL2R: /* PLL32 is used as clock source for I2C2*/ + /* PLL2 input clock, parameters M, N & R configuration clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); +#endif /* RCC_I2C2CLKSOURCE_PLL3R */ + /* I2C2 clock source config set later after clock selection check */ + break; + + case RCC_I2C2CLKSOURCE_HSI: /* HSI clock is used as source of I2C2 clock*/ + /* I2C2 clock source config set later after clock selection check */ + break; + + case RCC_I2C2CLKSOURCE_CSI: /* CSI clock is used as source of I2C2 clock*/ + /* I2C2 clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of I2C2 clock*/ + __HAL_RCC_I2C2_CONFIG(pPeriphClkInit->I2c2ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + +#if defined(I2C3) + /*-------------------------- I2C3 clock source configuration ---------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C3) == RCC_PERIPHCLK_I2C3) + { + /* Check the parameters */ + assert_param(IS_RCC_I2C3CLKSOURCE(pPeriphClkInit->I2c3ClockSelection)); + + switch (pPeriphClkInit->I2c3ClockSelection) + { + case RCC_I2C3CLKSOURCE_PCLK3: /* PCLK3 is used as clock source for I2C3*/ + + /* I2C3 clock source config set later after clock selection check */ + break; + + case RCC_I2C3CLKSOURCE_PLL3R: /* PLL3 is used as clock source for I2C3*/ + /* PLL3 input clock, parameters M, N & R configuration clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + /* I2C3 clock source config set later after clock selection check */ + break; + + case RCC_I2C3CLKSOURCE_HSI: /* HSI clock is used as source of I2C3 clock*/ + /* I2C3 clock source config set later after clock selection check */ + break; + + case RCC_I2C3CLKSOURCE_CSI: /* CSI clock is used as source of I2C3 clock*/ + /* I2C3 clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of I2C3 clock*/ + __HAL_RCC_I2C3_CONFIG(pPeriphClkInit->I2c3ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } +#endif /* I2C3 */ + +#if defined(I2C4) + /*-------------------------- I2C4 clock source configuration ---------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C4) == RCC_PERIPHCLK_I2C4) + { + /* Check the parameters */ + assert_param(IS_RCC_I2C4CLKSOURCE(pPeriphClkInit->I2c4ClockSelection)); + + switch (pPeriphClkInit->I2c4ClockSelection) + { + case RCC_I2C4CLKSOURCE_PCLK3: /* PCLK3 is used as clock source for I2C4*/ + + /* I2C4 clock source config set later after clock selection check */ + break; + + case RCC_I2C4CLKSOURCE_PLL3R: /* PLL3 is used as clock source for I2C4*/ + /* PLL3 input clock, parameters M, N & R configuration clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + /* I2C4 clock source config set later after clock selection check */ + break; + + case RCC_I2C4CLKSOURCE_HSI: /* HSI clock is used as source of I2C4 clock*/ + /* I2C4 clock source config set later after clock selection check */ + break; + + case RCC_I2C4CLKSOURCE_CSI: /* CSI clock is used as source of I2C4 clock*/ + /* I2C4 clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of I2C4 clock*/ + __HAL_RCC_I2C4_CONFIG(pPeriphClkInit->I2c4ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } +#endif /* I2C4 */ + + /*-------------------------- I3C1 clock source configuration ---------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I3C1) == RCC_PERIPHCLK_I3C1) + { + /* Check the parameters */ + assert_param(IS_RCC_I3C1CLKSOURCE(pPeriphClkInit->I3c1ClockSelection)); + + switch (pPeriphClkInit->I3c1ClockSelection) + { + case RCC_I3C1CLKSOURCE_PCLK1: /* PCLK1 is used as clock source for I3C1*/ + + /* I3C1 clock source config set later after clock selection check */ + break; + +#if defined(RCC_I3C1CLKSOURCE_PLL3R) + case RCC_I3C1CLKSOURCE_PLL3R: /* PLL3 is used as clock source for I3C1*/ + /* PLL3 input clock, parameters M, N & R configuration clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); +#else + case RCC_I3C1CLKSOURCE_PLL2R: /* PLL2 is used as clock source for I3C1*/ + /* PLL2 input clock, parameters M, N & R configuration clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); +#endif /* RCC_I3C1CLKSOURCE_PLL3R */ + /* I3C1 clock source config set later after clock selection check */ + break; + + case RCC_I3C1CLKSOURCE_HSI: /* HSI clock is used as source of I3C1 clock*/ + /* I3C1 clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of I3C1 clock*/ + __HAL_RCC_I3C1_CONFIG(pPeriphClkInit->I3c1ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + +#if defined (I3C2) + /*-------------------------- I3C2 clock source configuration ---------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I3C2) == RCC_PERIPHCLK_I3C2) + { + /* Check the parameters */ + assert_param(IS_RCC_I3C2CLKSOURCE(pPeriphClkInit->I3c2ClockSelection)); + + switch (pPeriphClkInit->I3c2ClockSelection) + { + case RCC_I3C2CLKSOURCE_PCLK3: /* PCLK1 is used as clock source for I3C2*/ + + /* I3C2 clock source config set later after clock selection check */ + break; + + case RCC_I3C2CLKSOURCE_PLL2R: /* PLL2 is used as clock source for I3C2*/ + /* PLL2 input clock, parameters M, N & R configuration clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + /* I3C2 clock source config set later after clock selection check */ + break; + + case RCC_I3C2CLKSOURCE_HSI: /* HSI clock is used as source of I3C2 clock*/ + /* I3C2 clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of I3C2 clock*/ + __HAL_RCC_I3C2_CONFIG(pPeriphClkInit->I3c2ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } +#endif /* I3C2 */ + + /*------------------------------------ TIM configuration --------------------------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == RCC_PERIPHCLK_TIM) + { + /* Check the parameters */ + assert_param(IS_RCC_TIMPRES(pPeriphClkInit->TimPresSelection)); + + /* Configure Timer Prescaler */ + __HAL_RCC_TIMCLKPRESCALER(pPeriphClkInit->TimPresSelection); + } + + /*-------------------------- LPTIM1 clock source configuration ---------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == RCC_PERIPHCLK_LPTIM1) + { + /* Check the parameters */ + assert_param(IS_RCC_LPTIM1CLK(pPeriphClkInit->Lptim1ClockSelection)); + + switch (pPeriphClkInit->Lptim1ClockSelection) + { + case RCC_LPTIM1CLKSOURCE_PCLK3: /* PCLK3 is used as clock source for LPTIM1*/ + + /* LPTIM1 clock source config set later after clock selection check */ + break; + + case RCC_LPTIM1CLKSOURCE_PLL2P: /* PLL2 is used as clock source for LPTIM1*/ + /* PLL2 P input clock, parameters M, N & P configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + /* LPTIM1 clock source config set later after clock selection check */ + break; + +#if defined(RCC_LPTIM1CLKSOURCE_PLL3R) + case RCC_LPTIM1CLKSOURCE_PLL3R: /* PLL3 is used as clock source for LPTIM1*/ + /* PLL3 R input clock, parameters M, N & R configuration clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + /* LPTIM1 clock source config set later after clock selection check */ + break; +#endif /* RCC_LPTIM1CLKSOURCE_PLL3R */ + + case RCC_LPTIM1CLKSOURCE_LSE: /* LSE clock is used as source of LPTIM1 clock*/ + /* LPTIM1 clock source config set later after clock selection check */ + break; + + case RCC_LPTIM1CLKSOURCE_LSI: /* LSI clock is used as source of LPTIM1 clock*/ + /* LPTIM1 clock source config set later after clock selection check */ + break; + + case RCC_LPTIM1CLKSOURCE_CLKP: /* CLKP is used as source of LPTIM1 clock*/ + /* LPTIM1 clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of LPTIM1 clock*/ + __HAL_RCC_LPTIM1_CONFIG(pPeriphClkInit->Lptim1ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*-------------------------- LPTIM2 clock source configuration ---------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM2) == RCC_PERIPHCLK_LPTIM2) + { + /* Check the parameters */ + assert_param(IS_RCC_LPTIM2CLK(pPeriphClkInit->Lptim2ClockSelection)); + + switch (pPeriphClkInit->Lptim2ClockSelection) + { + case RCC_LPTIM2CLKSOURCE_PCLK1: /* PCLK1 is used as clock source for LPTIM2*/ + + /* LPTIM2 clock source config set later after clock selection check */ + break; + + case RCC_LPTIM2CLKSOURCE_PLL2P: /* PLL2 is used as clock source for LPTIM2*/ + /* PLL2 P input clock, parameters M, N & P configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + /* LPTIM2 clock source config set later after clock selection check */ + break; + +#if defined(RCC_LPTIM2CLKSOURCE_PLL3R) + case RCC_LPTIM2CLKSOURCE_PLL3R: /* PLL3 is used as clock source for LPTIM2*/ + /* PLL3 R input clock, parameters M, N & R configuration clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + /* LPTIM2 clock source config set later after clock selection check */ + break; +#endif /* RCC_LPTIM2CLKSOURCE_PLL3R */ + + case RCC_LPTIM2CLKSOURCE_LSE: /* LSE clock is used as source of LPTIM2 clock*/ + /* LPTIM2 clock source config set later after clock selection check */ + break; + + case RCC_LPTIM2CLKSOURCE_LSI: /* LSI clock is used as source of LPTIM2 clock*/ + /* LPTIM2 clock source config set later after clock selection check */ + break; + + case RCC_LPTIM2CLKSOURCE_CLKP: /* CLKP is used as source of LPTIM2 clock*/ + /* LPTIM2 clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of LPTIM2 clock*/ + __HAL_RCC_LPTIM2_CONFIG(pPeriphClkInit->Lptim2ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + +#if defined(LPTIM3) + /*-------------------------- LPTIM3 clock source configuration ---------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM3) == RCC_PERIPHCLK_LPTIM3) + { + /* Check the parameters */ + assert_param(IS_RCC_LPTIM3CLK(pPeriphClkInit->Lptim3ClockSelection)); + + switch (pPeriphClkInit->Lptim3ClockSelection) + { + case RCC_LPTIM3CLKSOURCE_PCLK3: /* PCLK3 is used as clock source for LPTIM3*/ + + /* LPTIM3 clock source config set later after clock selection check */ + break; + + case RCC_LPTIM3CLKSOURCE_PLL2P: /* PLL2 is used as clock source for LPTIM3*/ + /* PLL2 P input clock, parameters M, N & P configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + /* LPTIM3 clock source config set later after clock selection check */ + break; + + case RCC_LPTIM3CLKSOURCE_PLL3R: /* PLL3 is used as clock source for LPTIM3*/ + /* PLL3 R input clock, parameters M, N & R configuration clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + /* LPTIM3 clock source config set later after clock selection check */ + break; + + case RCC_LPTIM3CLKSOURCE_LSE: /* LSE clock is used as source of LPTIM3 clock*/ + /* LPTIM3 clock source config set later after clock selection check */ + break; + + case RCC_LPTIM3CLKSOURCE_LSI: /* LSI clock is used as source of LPTIM3 clock*/ + /* LPTIM3 clock source config set later after clock selection check */ + break; + + case RCC_LPTIM3CLKSOURCE_CLKP: /* CLKP is used as source of LPTIM3 clock*/ + /* LPTIM3 clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of LPTIM3 clock*/ + __HAL_RCC_LPTIM3_CONFIG(pPeriphClkInit->Lptim3ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } +#endif /* LPTIM3 */ + +#if defined(LPTIM4) + /*-------------------------- LPTIM4 clock source configuration ---------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM4) == RCC_PERIPHCLK_LPTIM4) + { + /* Check the parameters */ + assert_param(IS_RCC_LPTIM4CLK(pPeriphClkInit->Lptim4ClockSelection)); + + switch (pPeriphClkInit->Lptim4ClockSelection) + { + case RCC_LPTIM4CLKSOURCE_PCLK3: /* PCLK3 is used as clock source for LPTIM4*/ + + /* LPTIM4 clock source config set later after clock selection check */ + break; + + case RCC_LPTIM4CLKSOURCE_PLL2P: /* PLL2 is used as clock source for LPTIM4*/ + /* PLL2 P input clock, parameters M, N & P configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + /* LPTIM4 clock source config set later after clock selection check */ + break; + + case RCC_LPTIM4CLKSOURCE_PLL3R: /* PLL3 is used as clock source for LPTIM4*/ + /* PLL3 R input clock, parameters M, N & R configuration clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + /* LPTIM4 clock source config set later after clock selection check */ + break; + + case RCC_LPTIM4CLKSOURCE_LSE: /* LSE clock is used as source of LPTIM4 clock*/ + /* LPTIM4 clock source config set later after clock selection check */ + break; + + case RCC_LPTIM4CLKSOURCE_LSI: /* LSI clock is used as source of LPTIM4 clock*/ + /* LPTIM4 clock source config set later after clock selection check */ + break; + + case RCC_LPTIM4CLKSOURCE_CLKP: /* CLKP is used as source of LPTIM4 clock*/ + /* LPTIM4 clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of LPTIM4 clock*/ + __HAL_RCC_LPTIM4_CONFIG(pPeriphClkInit->Lptim4ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } +#endif /* LPTIM4 */ + +#if defined(LPTIM5) + /*-------------------------- LPTIM5 clock source configuration ---------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM5) == RCC_PERIPHCLK_LPTIM5) + { + /* Check the parameters */ + assert_param(IS_RCC_LPTIM5CLK(pPeriphClkInit->Lptim5ClockSelection)); + + switch (pPeriphClkInit->Lptim5ClockSelection) + { + case RCC_LPTIM5CLKSOURCE_PCLK3: /* PCLK3 is used as clock source for LPTIM5*/ + + /* LPTIM5 clock source config set later after clock selection check */ + break; + + case RCC_LPTIM5CLKSOURCE_PLL2P: /* PLL2 is used as clock source for LPTIM5*/ + /* PLL2 P input clock, parameters M, N & P configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + /* LPTIM5 clock source config set later after clock selection check */ + break; + + case RCC_LPTIM5CLKSOURCE_PLL3R: /* PLL3 is used as clock source for LPTIM5*/ + /* PLL3 R input clock, parameters M, N & R configuration clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + /* LPTIM5 clock source config set later after clock selection check */ + break; + + case RCC_LPTIM5CLKSOURCE_LSE: /* LSE clock is used as source of LPTIM5 clock*/ + /* LPTIM5 clock source config set later after clock selection check */ + break; + + case RCC_LPTIM5CLKSOURCE_LSI: /* LSI clock is used as source of LPTIM5 clock*/ + /* LPTIM5 clock source config set later after clock selection check */ + break; + + case RCC_LPTIM5CLKSOURCE_CLKP: /* CLKP is used as source of LPTIM5 clock*/ + /* LPTIM5 clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of LPTIM5 clock*/ + __HAL_RCC_LPTIM5_CONFIG(pPeriphClkInit->Lptim5ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } +#endif /* LPTIM5 */ + +#if defined(LPTIM6) + /*-------------------------- LPTIM6 clock source configuration ---------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM6) == RCC_PERIPHCLK_LPTIM6) + { + /* Check the parameters */ + assert_param(IS_RCC_LPTIM6CLK(pPeriphClkInit->Lptim6ClockSelection)); + + switch (pPeriphClkInit->Lptim6ClockSelection) + { + case RCC_LPTIM6CLKSOURCE_PCLK3: /* PCLK3 is used as clock source for LPTIM6*/ + + /* LPTIM6 clock source config set later after clock selection check */ + break; + + case RCC_LPTIM6CLKSOURCE_PLL2P: /* PLL2 is used as clock source for LPTIM6*/ + /* PLL2 P input clock, parameters M, N & P configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + /* LPTIM6 clock source config set later after clock selection check */ + break; + + case RCC_LPTIM6CLKSOURCE_PLL3R: /* PLL3 is used as clock source for LPTIM6*/ + /* PLL3 R input clock, parameters M, N & R configuration clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + /* LPTIM6 clock source config set later after clock selection check */ + break; + + case RCC_LPTIM6CLKSOURCE_LSE: /* LSE clock is used as source of LPTIM6 clock*/ + /* LPTIM6 clock source config set later after clock selection check */ + break; + + case RCC_LPTIM6CLKSOURCE_LSI: /* LSI clock is used as source of LPTIM6 clock*/ + /* LPTIM6 clock source config set later after clock selection check */ + break; + + case RCC_LPTIM6CLKSOURCE_CLKP: /* CLKP is used as source of LPTIM6 clock*/ + /* LPTIM6 clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of LPTIM6 clock*/ + __HAL_RCC_LPTIM6_CONFIG(pPeriphClkInit->Lptim6ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } +#endif /* LPTIM6 */ + +#if defined(SAI1) + /*-------------------------- SAI1 clock source configuration ---------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1) + { + /* Check the parameters */ + assert_param(IS_RCC_SAI1CLK(pPeriphClkInit->Sai1ClockSelection)); + + switch (pPeriphClkInit->Sai1ClockSelection) + { + case RCC_SAI1CLKSOURCE_PLL1Q: /* PLL is used as clock source for SAI1*/ + /* Enable SAI Clock output generated from System PLL . */ + __HAL_RCC_PLL1_CLKOUT_ENABLE(RCC_PLL1_DIVQ); + /* SAI1 clock source config set later after clock selection check */ + break; + + case RCC_SAI1CLKSOURCE_PLL2P: /* PLL2 is used as clock source for SAI1*/ + /* PLL2 P input clock, parameters M, N & P configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + /* SAI1 clock source config set later after clock selection check */ + break; + + case RCC_SAI1CLKSOURCE_PLL3P: /* PLL3 is used as clock source for SAI1*/ + /* PLL3 P input clock, parameters M, N & P configuration clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + /* SAI1 clock source config set later after clock selection check */ + break; + + case RCC_SAI1CLKSOURCE_PIN: /* External clock is used as source of SAI1 clock*/ + break; + + case RCC_SAI1CLKSOURCE_CLKP: /* CLKP is used as source of SAI1 clock*/ + /* SAI1 clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of SAI1 clock*/ + __HAL_RCC_SAI1_CONFIG(pPeriphClkInit->Sai1ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } +#endif /* SAI1*/ + +#if defined(SAI2) + /*-------------------------- SAI2 clock source configuration ---------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) + { + /* Check the parameters */ + assert_param(IS_RCC_SAI2CLK(pPeriphClkInit->Sai2ClockSelection)); + + switch (pPeriphClkInit->Sai2ClockSelection) + { + case RCC_SAI2CLKSOURCE_PLL1Q: /* PLL is used as clock source for SAI2*/ + /* Enable SAI Clock output generated from System PLL . */ + __HAL_RCC_PLL1_CLKOUT_ENABLE(RCC_PLL1_DIVQ); + /* SAI2 clock source config set later after clock selection check */ + break; + + case RCC_SAI2CLKSOURCE_PLL2P: /* PLL2 is used as clock source for SAI2*/ + /* PLL2 P input clock, parameters M, N & P configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + /* SAI2 clock source config set later after clock selection check */ + break; + + case RCC_SAI2CLKSOURCE_PLL3P: /* PLL3 is used as clock source for SAI2*/ + /* PLL3 P input clock, parameters M, N & P configuration and clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + /* SAI2 clock source config set later after clock selection check */ + break; + + case RCC_SAI2CLKSOURCE_PIN: /* External clock is used as source of SAI2 clock*/ + case RCC_SAI2CLKSOURCE_CLKP: /* CLKP is used as source of SAI2 clock*/ + /* SAI2 clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of SAI2 clock*/ + __HAL_RCC_SAI2_CONFIG(pPeriphClkInit->Sai2ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } +#endif /* SAI2*/ + + /*-------------------------- ADCDAC clock source configuration ----------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_ADCDAC) == RCC_PERIPHCLK_ADCDAC) + { + /* Check the parameters */ + assert_param(IS_RCC_ADCDACCLKSOURCE(pPeriphClkInit->AdcDacClockSelection)); + + switch (pPeriphClkInit->AdcDacClockSelection) + { + + case RCC_ADCDACCLKSOURCE_HCLK: /* Bus clock is used as source of ADCDAC clock*/ + case RCC_ADCDACCLKSOURCE_SYSCLK: /* System clock is used as source of ADCDAC clock*/ + /* ADCDAC clock source config set later after clock selection check */ + break; + + case RCC_ADCDACCLKSOURCE_PLL2R: + /* PLL2 input clock, parameters M, N & R configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + break; + + case RCC_ADCDACCLKSOURCE_HSE:/* HSE clock is used as source of ADCDAC clock*/ + case RCC_ADCDACCLKSOURCE_HSI:/* HSI clock is used as source of ADCDAC clock*/ + case RCC_ADCDACCLKSOURCE_CSI:/* CSI clock is used as source of ADCDAC clock*/ + /* ADCDAC clock source configuration done later after clock selection check */ + break; + + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Configure the ADCDAC interface clock source */ + __HAL_RCC_ADCDAC_CONFIG(pPeriphClkInit->AdcDacClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + + } + + /*-------------------------- DAC low-power clock source configuration ----------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DAC_LP) == RCC_PERIPHCLK_DAC_LP) + { + /* Check the parameters */ + assert_param(IS_RCC_DACLPCLKSOURCE(pPeriphClkInit->DacLowPowerClockSelection)); + + switch (pPeriphClkInit->DacLowPowerClockSelection) + { + + case RCC_DACLPCLKSOURCE_LSE: + /* LSE oscillator is used as source of DAC low-power clock */ + /* DAC clock source configuration done later after clock selection check */ + break; + + case RCC_DACLPCLKSOURCE_LSI: + /* LSI is used as clock source for DAC low-power clock */ + /* DAC clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Configure the DAC low-power interface clock source */ + __HAL_RCC_DAC_LP_CONFIG(pPeriphClkInit->DacLowPowerClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + + } + + /*-------------------------- RTC clock source configuration ----------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC) + { + + /* Check for RTC Parameters used to output RTCCLK */ + assert_param(IS_RCC_RTCCLKSOURCE(pPeriphClkInit->RTCClockSelection)); + + /* Enable write access to Backup domain */ + SET_BIT(PWR->DBPCR, PWR_DBPCR_DBP); + + /* Wait for Backup domain Write protection disable */ + tickstart = HAL_GetTick(); + + while (HAL_IS_BIT_CLR(PWR->DBPCR, PWR_DBPCR_DBP)) + { + if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE) + { + ret = HAL_TIMEOUT; + break; + } + } + + if (ret == HAL_OK) + { + /* Reset the Backup domain only if the RTC Clock source selection is modified from default */ + tmpregister = READ_BIT(RCC->BDCR, RCC_BDCR_RTCSEL); + + if ((tmpregister != RCC_RTCCLKSOURCE_NO_CLK) && (tmpregister != pPeriphClkInit->RTCClockSelection)) + { + /* Store the content of BDCR register before the reset of Backup Domain */ + tmpregister = READ_BIT(RCC->BDCR, ~(RCC_BDCR_RTCSEL)); + /* RTC Clock selection can be changed only if the Backup Domain is reset */ + __HAL_RCC_BACKUPRESET_FORCE(); + __HAL_RCC_BACKUPRESET_RELEASE(); + /* Restore the Content of BDCR register */ + RCC->BDCR = tmpregister; + } + + /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */ + if (HAL_IS_BIT_SET(tmpregister, RCC_BDCR_LSEON)) + { + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till LSE is ready */ + while (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) + { + ret = HAL_TIMEOUT; + break; + } + } + } + + if (ret == HAL_OK) + { + /* Apply new RTC clock source selection */ + __HAL_RCC_RTC_CONFIG(pPeriphClkInit->RTCClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + else + { + /* set overall return value */ + status = ret; + } + + } + + /*------------------------------ RNG Configuration -------------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RNG) == RCC_PERIPHCLK_RNG) + { + + /* Check the parameters */ + assert_param(IS_RCC_RNGCLKSOURCE(pPeriphClkInit->RngClockSelection)); + + switch (pPeriphClkInit->RngClockSelection) + { + + case RCC_RNGCLKSOURCE_HSI48: /* HSI48 is used as clock source for RNG*/ + + /* RNG clock source configuration done later after clock selection check */ + break; + + case RCC_RNGCLKSOURCE_PLL1Q: /* PLL1 is used as clock source for RNG*/ + /* Enable PLL1Q Clock output generated from System PLL . */ + __HAL_RCC_PLL1_CLKOUT_ENABLE(RCC_PLL1_DIVQ); + /* RNG clock source configuration done later after clock selection check */ + break; + case RCC_RNGCLKSOURCE_LSE: + /* LSE oscillator is used as source of RNG clock */ + /* RNG clock source configuration done later after clock selection check */ + break; + + case RCC_RNGCLKSOURCE_LSI: /* HSI48 is used as clock source for RNG*/ + + /* RNG clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of RNG clock*/ + __HAL_RCC_RNG_CONFIG(pPeriphClkInit->RngClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + + } + +#if defined(SDMMC1) + /*-------------------------- SDMMC1 clock source configuration -------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDMMC1) == RCC_PERIPHCLK_SDMMC1) + { + + /* Check the parameters */ + assert_param(IS_RCC_SDMMC1CLKSOURCE(pPeriphClkInit->Sdmmc1ClockSelection)); + + switch (pPeriphClkInit->Sdmmc1ClockSelection) + { + case RCC_SDMMC1CLKSOURCE_PLL1Q: /* PLL1 is used as clock source for SDMMC1 kernel clock*/ + /* Enable PLL1Q Clock output generated from System PLL . */ + __HAL_RCC_PLL1_CLKOUT_ENABLE(RCC_PLL1_DIVQ); + /* SDMMC1 kernel clock source config set later after clock selection check */ + break; + + case RCC_SDMMC1CLKSOURCE_PLL2R: /* PLL2 is used as clock source for SDMMC1 kernel clock*/ + /* PLL2R input clock, parameters M, N & R configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + /* SDMMC1 kernel clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Configure the SDMMC1 clock source */ + __HAL_RCC_SDMMC1_CONFIG(pPeriphClkInit->Sdmmc1ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + + } +#endif /* SDMMC1 */ + +#if defined(SDMMC2) + /*-------------------------- SDMMC2 clock source configuration -------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDMMC2) == RCC_PERIPHCLK_SDMMC2) + { + + /* Check the parameters */ + assert_param(IS_RCC_SDMMC2CLKSOURCE(pPeriphClkInit->Sdmmc2ClockSelection)); + + switch (pPeriphClkInit->Sdmmc2ClockSelection) + { + case RCC_SDMMC2CLKSOURCE_PLL1Q: /* PLL1 is used as clock source for SDMMC2 kernel clock*/ + /* Enable PLL1Q Clock output generated from System PLL . */ + __HAL_RCC_PLL1_CLKOUT_ENABLE(RCC_PLL1_DIVQ); + /* SDMMC2 kernel clock source config set later after clock selection check */ + break; + + case RCC_SDMMC2CLKSOURCE_PLL2R: /* PLL2 is used as clock source for SDMMC2 kernel clock*/ + /* PLL2R input clock, parameters M, N & R configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + /* SDMMC2 kernel clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Configure the SDMMC2 clock source */ + __HAL_RCC_SDMMC2_CONFIG(pPeriphClkInit->Sdmmc2ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + + } +#endif /* SDMMC2 */ + + /*-------------------------- SPI1 clock source configuration ----------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPI1) == RCC_PERIPHCLK_SPI1) + { + + /* Check the parameters */ + assert_param(IS_RCC_SPI1CLKSOURCE(pPeriphClkInit->Spi1ClockSelection)); + + switch (pPeriphClkInit->Spi1ClockSelection) + { + case RCC_SPI1CLKSOURCE_PLL1Q: /* PLL1 is used as clock source for SPI1 */ + /* Enable SPI Clock output generated from System PLL . */ + __HAL_RCC_PLL1_CLKOUT_ENABLE(RCC_PLL1_DIVQ); + + /* SPI1 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI1CLKSOURCE_PLL2P: /* PLL2 is used as clock source for SPI1*/ + /* PLL2 P input clock, parameters M, N & P configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + + /* SPI1 clock source configuration done later after clock selection check */ + break; + +#if defined(RCC_SPI1CLKSOURCE_PLL3P) + case RCC_SPI1CLKSOURCE_PLL3P: /* PLL3 is used as clock source for SPI1 */ + /* PLL3 P input clock, parameters M, N & P configuration and clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + + /* SPI1 clock source configuration done later after clock selection check */ + break; +#endif /* RCC_SPI1CLKSOURCE_PLL3P */ + + case RCC_SPI1CLKSOURCE_PIN: + /* External clock is used as source of SPI1 clock*/ + /* SPI1 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI1CLKSOURCE_CLKP: + /* HSI, HSE, or CSI oscillator is used as source of SPI1 clock */ + /* SPI1 clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Configure the SPI1 clock source */ + __HAL_RCC_SPI1_CONFIG(pPeriphClkInit->Spi1ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + + } + + /*-------------------------- SPI2 clock source configuration ----------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPI2) == RCC_PERIPHCLK_SPI2) + { + + /* Check the parameters */ + assert_param(IS_RCC_SPI2CLKSOURCE(pPeriphClkInit->Spi2ClockSelection)); + + switch (pPeriphClkInit->Spi2ClockSelection) + { + case RCC_SPI2CLKSOURCE_PLL1Q: /* PLL1 is used as clock source for SPI2 */ + /* Enable SPI Clock output generated from System PLL . */ + __HAL_RCC_PLL1_CLKOUT_ENABLE(RCC_PLL1_DIVQ); + + /* SPI2 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI2CLKSOURCE_PLL2P: /* PLL2 is used as clock source for SPI2*/ + /* PLL2 P input clock, parameters M, N & P configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + + /* SPI2 clock source configuration done later after clock selection check */ + break; + +#if defined(RCC_SPI2CLKSOURCE_PLL3P) + case RCC_SPI2CLKSOURCE_PLL3P: /* PLL3 is used as clock source for SPI2 */ + /* PLL3 P input clock, parameters M, N & P configuration and clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + + /* SPI2 clock source configuration done later after clock selection check */ + break; +#endif /* RCC_SPI2CLKSOURCE_PLL3P */ + + case RCC_SPI2CLKSOURCE_PIN: + /* External clock is used as source of SPI2 clock*/ + /* SPI2 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI2CLKSOURCE_CLKP: + /* HSI, HSE, or CSI oscillator is used as source of SPI2 clock */ + /* SPI2 clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Configure the SPI2 clock source */ + __HAL_RCC_SPI2_CONFIG(pPeriphClkInit->Spi2ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + + } + + /*-------------------------- SPI3 clock source configuration ----------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPI3) == RCC_PERIPHCLK_SPI3) + { + + /* Check the parameters */ + assert_param(IS_RCC_SPI3CLKSOURCE(pPeriphClkInit->Spi3ClockSelection)); + + switch (pPeriphClkInit->Spi3ClockSelection) + { + case RCC_SPI3CLKSOURCE_PLL1Q: /* PLL1 is used as clock source for SPI3 */ + /* Enable SPI Clock output generated from System PLL . */ + __HAL_RCC_PLL1_CLKOUT_ENABLE(RCC_PLL1_DIVQ); + + /* SPI3 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI3CLKSOURCE_PLL2P: /* PLL2 is used as clock source for SPI3*/ + /* PLL2 P input clock, parameters M, N & P configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + + /* SPI3 clock source configuration done later after clock selection check */ + break; + +#if defined(RCC_SPI3CLKSOURCE_PLL3P) + case RCC_SPI3CLKSOURCE_PLL3P: /* PLL3 is used as clock source for SPI3 */ + /* PLL3 P input clock, parameters M, N & P configuration and clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + + /* SPI3 clock source configuration done later after clock selection check */ + break; +#endif /* RCC_SPI3CLKSOURCE_PLL3P */ + + case RCC_SPI3CLKSOURCE_PIN: + /* External clock is used as source of SPI3 clock*/ + /* SPI3 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI3CLKSOURCE_CLKP: + /* HSI, HSE, or CSI oscillator is used as source of SPI3 clock */ + /* SPI3 clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Configure the SPI3 clock source */ + __HAL_RCC_SPI3_CONFIG(pPeriphClkInit->Spi3ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + + } + +#if defined(SPI4) + /*-------------------------- SPI4 clock source configuration ----------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPI4) == RCC_PERIPHCLK_SPI4) + { + + /* Check the parameters */ + assert_param(IS_RCC_SPI4CLKSOURCE(pPeriphClkInit->Spi4ClockSelection)); + + switch (pPeriphClkInit->Spi4ClockSelection) + { + case RCC_SPI4CLKSOURCE_PCLK2: /* PCLK2 (APB2 Clock) is used as clock source for SPI4 */ + /* SPI4 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI4CLKSOURCE_PLL2Q: /* PLL2 is used as clock source for SPI4*/ + /* PLL2 Q input clock, parameters M, N & P configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + + /* SPI4 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI4CLKSOURCE_PLL3Q: /* PLL3 is used as clock source for SPI4 */ + /* PLL3 Q input clock, parameters M, N & P configuration and clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + + /* SPI4 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI4CLKSOURCE_HSI: + /* HSI oscillator is used as source of SPI4 clock*/ + /* SPI4 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI4CLKSOURCE_CSI: + /* CSI oscillator is used as source of SPI4 clock */ + /* SPI4 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI4CLKSOURCE_HSE: + /* HSE oscillator is used as source of SPI4 clock */ + /* SPI4 clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Configure the SPI4 clock source */ + __HAL_RCC_SPI4_CONFIG(pPeriphClkInit->Spi4ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + + } +#endif /* SPI4 */ + +#if defined(SPI5) + /*-------------------------- SPI5 clock source configuration ----------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPI5) == RCC_PERIPHCLK_SPI5) + { + + /* Check the parameters */ + assert_param(IS_RCC_SPI5CLKSOURCE(pPeriphClkInit->Spi5ClockSelection)); + + switch (pPeriphClkInit->Spi5ClockSelection) + { + case RCC_SPI5CLKSOURCE_PCLK3: /* PCLK3 (APB3 Clock) is used as clock source for SPI5 */ + /* SPI5 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI5CLKSOURCE_PLL2Q: /* PLL2 is used as clock source for SPI5*/ + /* PLL2 Q input clock, parameters M, N & P configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + + /* SPI5 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI5CLKSOURCE_PLL3Q: /* PLL3 is used as clock source for SPI5 */ + /* PLL3 Q input clock, parameters M, N & P configuration and clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + + /* SPI5 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI5CLKSOURCE_HSI: + /* HSI oscillator is used as source of SPI5 clock*/ + /* SPI5 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI5CLKSOURCE_CSI: + /* CSI oscillator is used as source of SPI5 clock */ + /* SPI5 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI5CLKSOURCE_HSE: + /* HSE oscillator is used as source of SPI5 clock */ + /* SPI5 clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Configure the SPI5 clock source */ + __HAL_RCC_SPI5_CONFIG(pPeriphClkInit->Spi5ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + + } +#endif /* SPI5 */ + +#if defined(SPI6) + /*-------------------------- SPI6 clock source configuration ----------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPI6) == RCC_PERIPHCLK_SPI6) + { + + /* Check the parameters */ + assert_param(IS_RCC_SPI6CLKSOURCE(pPeriphClkInit->Spi6ClockSelection)); + + switch (pPeriphClkInit->Spi6ClockSelection) + { + case RCC_SPI6CLKSOURCE_PCLK2: /* PCLK2 (APB2 Clock) is used as clock source for SPI6 */ + /* SPI6 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI6CLKSOURCE_PLL2Q: /* PLL2 is used as clock source for SPI6*/ + /* PLL2 Q input clock, parameters M, N & P configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + + /* SPI6 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI6CLKSOURCE_PLL3Q: /* PLL3 is used as clock source for SPI6 */ + /* PLL3 Q input clock, parameters M, N & P configuration and clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); + + /* SPI6 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI6CLKSOURCE_HSI: + /* HSI oscillator is used as source of SPI6 clock*/ + /* SPI6 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI6CLKSOURCE_CSI: + /* CSI oscillator is used as source of SPI6 clock */ + /* SPI6 clock source configuration done later after clock selection check */ + break; + + case RCC_SPI6CLKSOURCE_HSE: + /* HSE oscillator is used as source of SPI6 clock */ + /* SPI6 clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Configure the SPI6 clock source */ + __HAL_RCC_SPI6_CONFIG(pPeriphClkInit->Spi6ClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + + } +#endif /* SPI6 */ + +#if defined(OCTOSPI1) + /*-------------------------- OctoSPIx clock source configuration ----------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_OSPI) == RCC_PERIPHCLK_OSPI) + { + /* Check the parameters */ + assert_param(IS_RCC_OSPICLKSOURCE(pPeriphClkInit->OspiClockSelection)); + + switch (pPeriphClkInit->OspiClockSelection) + { + case RCC_OSPICLKSOURCE_HCLK: /* HCLK is used as clock source for OCTOSPI */ + + /* OCTOSPI clock source config set later after clock selection check */ + break; + + case RCC_OSPICLKSOURCE_PLL1Q: /* PLL1 Q is used as clock source for OCTOSPI*/ + + /* Enable PLL1 Q CLK output */ + __HAL_RCC_PLL1_CLKOUT_ENABLE(RCC_PLL1_DIVQ); + break; + + case RCC_OSPICLKSOURCE_PLL2R: /* PLL2 is used as clock source for OCTOSPI*/ + /* PLL2 R input clock, parameters M, N & R configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + /* OCTOSPI clock source config set later after clock selection check */ + break; + + case RCC_OSPICLKSOURCE_CLKP: /* CLKP is used as source of OCTOSPI clock*/ + /* OCTOSPI clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Configure the OctoSPI clock source */ + __HAL_RCC_OSPI_CONFIG(pPeriphClkInit->OspiClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } +#endif /* OCTOSPI1*/ + + /*-------------------------- FDCAN kernel clock source configuration -------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_FDCAN) == RCC_PERIPHCLK_FDCAN) + { + assert_param(IS_RCC_FDCANCLK(pPeriphClkInit->FdcanClockSelection)); + + switch (pPeriphClkInit->FdcanClockSelection) + { + case RCC_FDCANCLKSOURCE_HSE: /* HSE is used as source of FDCAN kernel clock*/ + /* FDCAN kernel clock source config set later after clock selection check */ + break; + + case RCC_FDCANCLKSOURCE_PLL1Q: /* PLL1 is used as clock source for FDCAN kernel clock*/ + /* Enable PLL1Q Clock output generated from System PLL . */ + __HAL_RCC_PLL1_CLKOUT_ENABLE(RCC_PLL1_DIVQ); + /* FDCAN kernel clock source config set later after clock selection check */ + break; + + case RCC_FDCANCLKSOURCE_PLL2Q: /* PLL2 is used as clock source for FDCAN kernel clock*/ + /* PLL2Q input clock, parameters M, N & Q configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); + /* FDCAN kernel clock source config set later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of FDCAN kernel clock*/ + __HAL_RCC_FDCAN_CONFIG(pPeriphClkInit->FdcanClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + } + + /*------------------------------ USB Configuration -------------------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == RCC_PERIPHCLK_USB) + { + + /* Check the parameters */ + assert_param(IS_RCC_USBCLKSOURCE(pPeriphClkInit->UsbClockSelection)); + + switch (pPeriphClkInit->UsbClockSelection) + { + case RCC_USBCLKSOURCE_PLL1Q: /* PLL is used as clock source for USB*/ + /* Enable USB Clock output generated form System USB . */ + __HAL_RCC_PLL1_CLKOUT_ENABLE(RCC_PLL1_DIVQ); + + /* USB clock source configuration done later after clock selection check */ + break; + +#if defined(RCC_USBCLKSOURCE_PLL3Q) + case RCC_USBCLKSOURCE_PLL3Q: /* PLL3 is used as clock source for USB*/ + /* PLL3Q input clock, parameters M, N & Q configuration and clock output (PLL3ClockOut) */ + ret = RCCEx_PLL3_Config(&(pPeriphClkInit->PLL3)); +#else + case RCC_USBCLKSOURCE_PLL2Q: /* PLL2 is used as clock source for USB*/ + /* PLL2Q input clock, parameters M, N & Q configuration and clock output (PLL2ClockOut) */ + ret = RCCEx_PLL2_Config(&(pPeriphClkInit->PLL2)); +#endif /* RCC_USBCLKSOURCE_PLL3Q */ + /* USB clock source configuration done later after clock selection check */ + break; + + case RCC_USBCLKSOURCE_HSI48: + /* HSI48 oscillator is used as source of USB clock */ + /* USB clock source configuration done later after clock selection check */ + break; + + default: + ret = HAL_ERROR; + break; + } + + if (ret == HAL_OK) + { + /* Set the source of USB clock*/ + __HAL_RCC_USB_CONFIG(pPeriphClkInit->UsbClockSelection); + } + else + { + /* set overall return value */ + status = ret; + } + + } + +#if defined(CEC) + /*-------------------------- CEC clock source configuration ----------------*/ + if (((pPeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CEC) == RCC_PERIPHCLK_CEC) + { + + /* Check the parameters */ + assert_param(IS_RCC_CECCLKSOURCE(pPeriphClkInit->CecClockSelection)); + + /* Configure the CEC clock source */ + __HAL_RCC_CEC_CONFIG(pPeriphClkInit->CecClockSelection); + + } +#endif /* CEC */ + + return status; +} + + + +/** + * @brief Get the pPeriphClkInit according to the internal RCC configuration registers. + * @param pPeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that + * returns the configuration information for the Extended Peripherals + * clocks (ADC12, DAC, SDMMC1, SDMMC2, OCTOSPI1, TIM, LPTIM1, LPTIM2, LPTIM3, LPTIM4, LPTIM5, LPTIM6, + * SPI1, SPI2, SPI3, SPI4, SPI5, SPI6, USART1, USART2, USART3, UART4, UART5, USART6, UART7, UART8, + * UART9, USART10, USART11, UART12, LPUART1, I2C1, I2C2, I2C3, I2C4, I3C1, I3C2, CEC, FDCAN, SAI1, + * SAI2, USB,), PLL2 and PLL3. + * @retval None + */ +void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *pPeriphClkInit) +{ + /* Set all possible values for the extended clock type parameter------------*/ + pPeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | \ + RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | \ + RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_ADCDAC | \ + RCC_PERIPHCLK_DAC_LP | RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_RNG | \ + RCC_PERIPHCLK_I3C1 | RCC_PERIPHCLK_SPI1 | RCC_PERIPHCLK_SPI2 | \ + RCC_PERIPHCLK_SPI3 | RCC_PERIPHCLK_CKPER | RCC_PERIPHCLK_USB; + +#if defined(UART4) + pPeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_UART4; +#endif /* UART4 */ +#if defined(UART5) + pPeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_UART5; +#endif /* UART5 */ +#if defined(USART6) + pPeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USART6; +#endif /* UART6 */ +#if defined(UART7) + pPeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_UART7; +#endif /* UART7 */ +#if defined(UART8) + pPeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_UART8; +#endif /* UART8 */ +#if defined(UART9) + pPeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_UART9; +#endif /* UART9 */ +#if defined(USART10) + pPeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USART10; +#endif /* UART10 */ +#if defined(USART11) + pPeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USART11; +#endif /* UART11 */ +#if defined(UART12) + pPeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_UART12; +#endif /* UART12 */ +#if defined(I2C3) + pPeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2C3; +#endif /* I2C3 */ +#if defined(I2C4) + pPeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2C4; +#endif /* I2C4 */ +#if defined(I3C2) + pPeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I3C2; +#endif /* I3C2 */ +#if defined(LPTIM3) + pPeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_LPTIM3; +#endif /* LPTIM3 */ +#if defined(LPTIM4) + pPeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_LPTIM4; +#endif /* LPTIM4 */ +#if defined(LPTIM5) + pPeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_LPTIM5; +#endif /* LPTIM5 */ +#if defined(LPTIM6) + pPeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_LPTIM6; +#endif /* LPTIM6 */ +#if defined(SPI4) + pPeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_SPI4; +#endif /* SPI4 */ +#if defined(SPI5) + pPeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_SPI5; +#endif /* SPI5 */ +#if defined(SPI6) + pPeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_SPI6; +#endif /* SPI6 */ +#if defined(SAI1) + pPeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_SAI1; +#endif /* SAI1 */ +#if defined(SAI2) + pPeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_SAI2; +#endif /* SAI2 */ + pPeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_FDCAN; +#if defined(SDMMC1) + pPeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_SDMMC1; +#endif /* SDMMC1*/ +#if defined(SDMMC2) + pPeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_SDMMC2; +#endif /* SDMMC2*/ +#if defined(OCTOSPI1) + pPeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_OSPI; +#endif /* OCTOSPI1 */ +#if defined(CEC) + pPeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_CEC; +#endif /* CEC */ + + /* Get the PLL2 Clock configuration -----------------------------------------------*/ + pPeriphClkInit->PLL2.PLL2Source = (uint32_t)((RCC->PLL2CFGR & RCC_PLL2CFGR_PLL2SRC) >> RCC_PLL2CFGR_PLL2SRC_Pos); + pPeriphClkInit->PLL2.PLL2M = (uint32_t)((RCC->PLL2CFGR & RCC_PLL2CFGR_PLL2M) >> RCC_PLL2CFGR_PLL2M_Pos); + pPeriphClkInit->PLL2.PLL2N = (uint32_t)((RCC->PLL2DIVR & RCC_PLL2DIVR_PLL2N) >> RCC_PLL2DIVR_PLL2N_Pos) + 1U; + pPeriphClkInit->PLL2.PLL2P = (uint32_t)((RCC->PLL2DIVR & RCC_PLL2DIVR_PLL2P) >> RCC_PLL2DIVR_PLL2P_Pos) + 1U; + pPeriphClkInit->PLL2.PLL2Q = (uint32_t)((RCC->PLL2DIVR & RCC_PLL2DIVR_PLL2Q) >> RCC_PLL2DIVR_PLL2Q_Pos) + 1U; + pPeriphClkInit->PLL2.PLL2R = (uint32_t)((RCC->PLL2DIVR & RCC_PLL2DIVR_PLL2R) >> RCC_PLL2DIVR_PLL2R_Pos) + 1U; + pPeriphClkInit->PLL2.PLL2RGE = (uint32_t)((RCC->PLL2CFGR & RCC_PLL2CFGR_PLL2RGE) >> RCC_PLL2CFGR_PLL2RGE_Pos); + pPeriphClkInit->PLL2.PLL2FRACN = (uint32_t)((RCC->PLL2FRACR & RCC_PLL2FRACR_PLL2FRACN) >> \ + RCC_PLL2FRACR_PLL2FRACN_Pos); + +#if defined(RCC_CR_PLL3ON) + /* Get the PLL3 Clock configuration -----------------------------------------------*/ + pPeriphClkInit->PLL3.PLL3Source = (uint32_t)((RCC->PLL3CFGR & RCC_PLL3CFGR_PLL3SRC) >> RCC_PLL3CFGR_PLL3SRC_Pos); + pPeriphClkInit->PLL3.PLL3M = (uint32_t)((RCC->PLL3CFGR & RCC_PLL3CFGR_PLL3M) >> RCC_PLL3CFGR_PLL3M_Pos); + pPeriphClkInit->PLL3.PLL3N = (uint32_t)((RCC->PLL3DIVR & RCC_PLL3DIVR_PLL3N) >> RCC_PLL3DIVR_PLL3N_Pos) + 1U; + pPeriphClkInit->PLL3.PLL3P = (uint32_t)((RCC->PLL3DIVR & RCC_PLL3DIVR_PLL3P) >> RCC_PLL3DIVR_PLL3P_Pos) + 1U; + pPeriphClkInit->PLL3.PLL3Q = (uint32_t)((RCC->PLL3DIVR & RCC_PLL3DIVR_PLL3Q) >> RCC_PLL3DIVR_PLL3Q_Pos) + 1U; + pPeriphClkInit->PLL3.PLL3R = (uint32_t)((RCC->PLL3DIVR & RCC_PLL3DIVR_PLL3R) >> RCC_PLL3DIVR_PLL3R_Pos) + 1U; + pPeriphClkInit->PLL3.PLL3RGE = (uint32_t)((RCC->PLL3CFGR & RCC_PLL3CFGR_PLL3RGE) >> RCC_PLL3CFGR_PLL3RGE_Pos); + pPeriphClkInit->PLL3.PLL3FRACN = (uint32_t)((RCC->PLL3FRACR & RCC_PLL3FRACR_PLL3FRACN) >> \ + RCC_PLL3FRACR_PLL3FRACN_Pos); +#endif /* RCC_CR_PLL3ON */ + + /* Get the USART1 clock source ---------------------------------------------*/ + pPeriphClkInit->Usart1ClockSelection = __HAL_RCC_GET_USART1_SOURCE(); + + /* Get the USART2 clock source ---------------------------------------------*/ + pPeriphClkInit->Usart2ClockSelection = __HAL_RCC_GET_USART2_SOURCE(); + + /* Get the USART3 clock source ---------------------------------------------*/ + pPeriphClkInit->Usart3ClockSelection = __HAL_RCC_GET_USART3_SOURCE(); + +#if defined(UART4) + /* Get the UART4 clock source ----------------------------------------------*/ + pPeriphClkInit->Uart4ClockSelection = __HAL_RCC_GET_UART4_SOURCE(); +#endif /* UART4 */ + +#if defined(UART5) + /* Get the UART5 clock source ----------------------------------------------*/ + pPeriphClkInit->Uart5ClockSelection = __HAL_RCC_GET_UART5_SOURCE(); +#endif /* UART5 */ + +#if defined(USART6) + /* Get the USART6 clock source ---------------------------------------------*/ + pPeriphClkInit->Usart6ClockSelection = __HAL_RCC_GET_USART6_SOURCE(); +#endif /* USART6 */ + +#if defined(UART7) + /* Get the UART7 clock source ---------------------------------------------*/ + pPeriphClkInit->Uart7ClockSelection = __HAL_RCC_GET_UART7_SOURCE(); +#endif /* UART7 */ + +#if defined(UART8) + /* Get the UART8 clock source ---------------------------------------------*/ + pPeriphClkInit->Uart8ClockSelection = __HAL_RCC_GET_UART8_SOURCE(); +#endif /* UART8 */ + +#if defined(UART9) + /* Get the UART9 clock source ---------------------------------------------*/ + pPeriphClkInit->Uart9ClockSelection = __HAL_RCC_GET_UART9_SOURCE(); +#endif /* UART9 */ + +#if defined(USART10) + /* Get the USART10 clock source ---------------------------------------------*/ + pPeriphClkInit->Usart10ClockSelection = __HAL_RCC_GET_USART10_SOURCE(); +#endif /* USART10 */ + +#if defined(USART11) + /* Get the USART11 clock source ---------------------------------------------*/ + pPeriphClkInit->Usart11ClockSelection = __HAL_RCC_GET_USART11_SOURCE(); +#endif /* USART11 */ + +#if defined(UART12) + /* Get the UART12 clock source ---------------------------------------------*/ + pPeriphClkInit->Uart12ClockSelection = __HAL_RCC_GET_UART12_SOURCE(); +#endif /* UART12 */ + + /* Get the LPUART1 clock source --------------------------------------------*/ + pPeriphClkInit->Lpuart1ClockSelection = __HAL_RCC_GET_LPUART1_SOURCE(); + + /* Get the I2C1 clock source -----------------------------------------------*/ + pPeriphClkInit->I2c1ClockSelection = __HAL_RCC_GET_I2C1_SOURCE(); + + /* Get the I2C2 clock source -----------------------------------------------*/ + pPeriphClkInit->I2c2ClockSelection = __HAL_RCC_GET_I2C2_SOURCE(); + +#if defined(I2C3) + /* Get the I2C3 clock source -----------------------------------------------*/ + pPeriphClkInit->I2c3ClockSelection = __HAL_RCC_GET_I2C3_SOURCE(); +#endif /* I2C3 */ + +#if defined(I2C4) + /* Get the I2C4 clock source -----------------------------------------------*/ + pPeriphClkInit->I2c4ClockSelection = __HAL_RCC_GET_I2C4_SOURCE(); +#endif /* I2C4 */ + + /* Get the I3C1 clock source -----------------------------------------------*/ + pPeriphClkInit->I3c1ClockSelection = __HAL_RCC_GET_I3C1_SOURCE(); + +#if defined(I3C2) + /* Get the I3C2 clock source -----------------------------------------------*/ + pPeriphClkInit->I3c2ClockSelection = __HAL_RCC_GET_I3C2_SOURCE(); +#endif /* I3C2 */ + + /* Get the LPTIM1 clock source ---------------------------------------------*/ + pPeriphClkInit->Lptim1ClockSelection = __HAL_RCC_GET_LPTIM1_SOURCE(); + + /* Get the LPTIM2 clock source ---------------------------------------------*/ + pPeriphClkInit->Lptim2ClockSelection = __HAL_RCC_GET_LPTIM2_SOURCE(); + +#if defined(LPTIM3) + /* Get the LPTIM3 clock source ---------------------------------------------*/ + pPeriphClkInit->Lptim3ClockSelection = __HAL_RCC_GET_LPTIM3_SOURCE(); +#endif /* LPTIM3 */ + +#if defined(LPTIM4) + /* Get the LPTIM4 clock source ---------------------------------------------*/ + pPeriphClkInit->Lptim4ClockSelection = __HAL_RCC_GET_LPTIM4_SOURCE(); +#endif /* LPTIM4 */ + +#if defined(LPTIM5) + /* Get the LPTIM5 clock source ---------------------------------------------*/ + pPeriphClkInit->Lptim5ClockSelection = __HAL_RCC_GET_LPTIM5_SOURCE(); +#endif /* LPTIM5 */ + +#if defined(LPTIM6) + /* Get the LPTIM6 clock source ---------------------------------------------*/ + pPeriphClkInit->Lptim6ClockSelection = __HAL_RCC_GET_LPTIM6_SOURCE(); +#endif /* LPTIM6 */ + + /* Get the FDCAN clock source ---------------------------------------------*/ + pPeriphClkInit->FdcanClockSelection = __HAL_RCC_GET_FDCAN_SOURCE(); + +#if defined(SAI1) + /* Get the SAI1 clock source -----------------------------------------------*/ + pPeriphClkInit->Sai1ClockSelection = __HAL_RCC_GET_SAI1_SOURCE(); +#endif /* SAI1 */ + +#if defined(SAI2) + /* Get the SAI2 clock source -----------------------------------------------*/ + pPeriphClkInit->Sai2ClockSelection = __HAL_RCC_GET_SAI2_SOURCE(); +#endif /* SAI2 */ + +#if defined(SDMMC1) + /* Get the SDMMC1 clock source ----------------------------------------------*/ + pPeriphClkInit->Sdmmc1ClockSelection = __HAL_RCC_GET_SDMMC1_SOURCE(); +#endif /* SDMMC1 */ + +#if defined(SDMMC2) + /* Get the SDMMC2 clock source ----------------------------------------------*/ + pPeriphClkInit->Sdmmc2ClockSelection = __HAL_RCC_GET_SDMMC2_SOURCE(); +#endif /* SDMMC2 */ + + /* Get the ADCDAC clock source ---------------------------------------------*/ + pPeriphClkInit->AdcDacClockSelection = __HAL_RCC_GET_ADCDAC_SOURCE(); + + /* Get the DAC low-power clock source ---------------------------------------------*/ + pPeriphClkInit->DacLowPowerClockSelection = __HAL_RCC_GET_DAC_LP_SOURCE(); + +#if defined(OCTOSPI1) + /* Get the OSPI clock source -----------------------------------------------*/ + pPeriphClkInit->OspiClockSelection = __HAL_RCC_GET_OSPI_SOURCE(); +#endif /* OCTOSPI1 */ + + /* Get the SPI1 clock source -----------------------------------------------*/ + pPeriphClkInit->Spi1ClockSelection = __HAL_RCC_GET_SPI1_SOURCE(); + + /* Get the SPI2 clock source -----------------------------------------------*/ + pPeriphClkInit->Spi2ClockSelection = __HAL_RCC_GET_SPI2_SOURCE(); + + /* Get the SPI3 clock source -----------------------------------------------*/ + pPeriphClkInit->Spi3ClockSelection = __HAL_RCC_GET_SPI3_SOURCE(); + +#if defined(SPI4) + /* Get the SPI4 clock source -----------------------------------------------*/ + pPeriphClkInit->Spi4ClockSelection = __HAL_RCC_GET_SPI4_SOURCE(); +#endif /* SPI4 */ + +#if defined(SPI5) + /* Get the SPI5 clock source -----------------------------------------------*/ + pPeriphClkInit->Spi5ClockSelection = __HAL_RCC_GET_SPI5_SOURCE(); +#endif /* SPI5 */ + +#if defined(SPI6) + /* Get the SPI6 clock source -----------------------------------------------*/ + pPeriphClkInit->Spi6ClockSelection = __HAL_RCC_GET_SPI6_SOURCE(); +#endif /* SPI6 */ + + /* Get the RTC clock source ------------------------------------------------*/ + pPeriphClkInit->RTCClockSelection = __HAL_RCC_GET_RTC_SOURCE(); + + /* Get the RNG clock source ------------------------------------------------*/ + pPeriphClkInit->RngClockSelection = __HAL_RCC_GET_RNG_SOURCE(); + + /* Get the CKPER clock source ------------------------------------------------*/ + pPeriphClkInit->CkperClockSelection = __HAL_RCC_GET_CLKP_SOURCE(); + +#if defined(CEC) + /* Get the CEC clock source ------------------------------------------------*/ + pPeriphClkInit->CecClockSelection = __HAL_RCC_GET_CEC_SOURCE(); +#endif /* CEC */ + + /* Get the USB clock source ------------------------------------------------*/ + pPeriphClkInit->UsbClockSelection = __HAL_RCC_GET_USB_SOURCE(); + + /* Get the TIM Prescaler configuration -------------------------------------*/ + if ((RCC->CFGR1 & RCC_CFGR1_TIMPRE) == 0U) + { + pPeriphClkInit->TimPresSelection = RCC_TIMPRES_DEACTIVATED; + } + else + { + pPeriphClkInit->TimPresSelection = RCC_TIMPRES_ACTIVATED; + } +} + +/** + * @brief Returns the PLL1 clock frequencies : PLL1_P_Frequency, PLL1_R_Frequency and PLL1_Q_Frequency + * @note The PLL1 clock frequencies computed by this function may not be the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * @note The function returns values based on HSE_VALUE, HSI_VALUE or CSI Value multiplied/divided by + the PLL factors. + * @note This function can be used by the user application to compute the + * baud-rate for the communication peripherals or configure other parameters. + * + * @note Each time PLL1CLK changes, this function must be called to update the + * right PLL1CLK value. Otherwise, any configuration based on this function will be incorrect. + * @param pPLL1_Clocks pointer to PLL1_ClocksTypeDef structure. + * @retval None + */ +void HAL_RCCEx_GetPLL1ClockFreq(PLL1_ClocksTypeDef *pPLL1_Clocks) +{ + uint32_t pll1source; + uint32_t pll1m; + uint32_t pll1n; + uint32_t pll1fracen; + uint32_t hsivalue; + float_t fracn1; + float_t pll1vco; + + /* PLL_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLL1M) * PLL1N + PLL1xCLK = PLL1_VCO / PLL1x + */ + + pll1n = (RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N); + pll1source = (RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1SRC); + pll1m = ((RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1M) >> RCC_PLL1CFGR_PLL1M_Pos); + pll1fracen = RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1FRACEN; + fracn1 = (float_t)(uint32_t)(pll1fracen * ((RCC->PLL1FRACR & RCC_PLL1FRACR_PLL1FRACN) >> \ + RCC_PLL1FRACR_PLL1FRACN_Pos)); + + if (pll1m != 0U) + { + switch (pll1source) + { + + case RCC_PLL1_SOURCE_HSI: /* HSI used as PLL1 clock source */ + hsivalue = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + pll1vco = ((float_t)hsivalue / (float_t)pll1m) * ((float_t)(uint32_t)pll1n + (fracn1 / (float_t)0x2000) + \ + (float_t)1); + break; + + case RCC_PLL1_SOURCE_CSI: /* CSI used as PLL1 clock source */ + pll1vco = ((float_t)CSI_VALUE / (float_t)pll1m) * ((float_t)(uint32_t)pll1n + (fracn1 / (float_t)0x2000) + \ + (float_t)1); + break; + + case RCC_PLL1_SOURCE_HSE: /* HSE used as PLL1 clock source */ + pll1vco = ((float_t)HSE_VALUE / (float_t)pll1m) * ((float_t)(uint32_t)pll1n + (fracn1 / (float_t)0x2000) + \ + (float_t)1); + break; + + default: + hsivalue = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + pll1vco = ((float_t)hsivalue / (float_t)pll1m) * ((float_t)(uint32_t)pll1n + (fracn1 / (float_t)0x2000) + \ + (float_t)1); + break; + } + + if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL1RDY)) + { + if (__HAL_RCC_GET_PLL1_CLKOUT_CONFIG(RCC_PLL1_DIVP) != 0U) + { + pPLL1_Clocks->PLL1_P_Frequency = \ + (uint32_t)(float_t)(pll1vco / \ + ((float_t)(uint32_t)((RCC->PLL1DIVR & \ + RCC_PLL1DIVR_PLL1P) >> \ + RCC_PLL1DIVR_PLL1P_Pos) + \ + (float_t)1)); + } + else + { + pPLL1_Clocks->PLL1_P_Frequency = 0U; + } + } + else + { + pPLL1_Clocks->PLL1_P_Frequency = 0U; + } + + if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL1RDY)) + { + if (__HAL_RCC_GET_PLL1_CLKOUT_CONFIG(RCC_PLL1_DIVQ) != 0U) + { + pPLL1_Clocks->PLL1_Q_Frequency = \ + (uint32_t)(float_t)(pll1vco / \ + ((float_t)(uint32_t)((RCC->PLL1DIVR & \ + RCC_PLL1DIVR_PLL1Q) >> \ + RCC_PLL1DIVR_PLL1Q_Pos) + \ + (float_t)1)); + } + else + { + pPLL1_Clocks->PLL1_Q_Frequency = 0U; + } + } + else + { + pPLL1_Clocks->PLL1_Q_Frequency = 0U; + } + + if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL1RDY)) + { + if (__HAL_RCC_GET_PLL1_CLKOUT_CONFIG(RCC_PLL1_DIVR) != 0U) + { + pPLL1_Clocks->PLL1_R_Frequency = \ + (uint32_t)(float_t)(pll1vco / \ + ((float_t)(uint32_t)((RCC->PLL1DIVR & \ + RCC_PLL1DIVR_PLL1R) >> \ + RCC_PLL1DIVR_PLL1R_Pos) + \ + (float_t)1)) ; + } + else + { + pPLL1_Clocks->PLL1_R_Frequency = 0U; + } + } + else + { + pPLL1_Clocks->PLL1_R_Frequency = 0U; + } + + } + else + { + pPLL1_Clocks->PLL1_P_Frequency = 0U; + pPLL1_Clocks->PLL1_Q_Frequency = 0U; + pPLL1_Clocks->PLL1_R_Frequency = 0U; + } + +} + +/** + * @brief Returns the PLL2 clock frequencies: PLL2_P_Frequency, PLL2_R_Frequency and PLL2_Q_Frequency + * @note The PLL2 clock frequencies computed by this function may not be the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * @note The function returns values based on HSE_VALUE, HSI_VALUE or CSI Value multiplied/divided by + the PLL factors. + * @note This function can be used by the user application to compute the + * baud-rate for the communication peripherals or configure other parameters. + * + * @note Each time PLL2CLK changes, this function must be called to update the + * right PLL2CLK value. Otherwise, any configuration based on this function will be incorrect. + * @param pPLL2_Clocks pointer to PLL2_ClocksTypeDef structure. + * @retval None + */ +void HAL_RCCEx_GetPLL2ClockFreq(PLL2_ClocksTypeDef *pPLL2_Clocks) +{ + uint32_t pll2source; + uint32_t pll2m; + uint32_t pll2n; + uint32_t pll2fracen; + uint32_t hsivalue; + float_t fracn2; + float_t pll2vco; + + /* PLL_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLL2M) * PLL2N + PLL2xCLK = PLL2_VCO / PLL2x + */ + pll2n = (RCC->PLL2DIVR & RCC_PLL2DIVR_PLL2N); + pll2source = (RCC->PLL2CFGR & RCC_PLL2CFGR_PLL2SRC); + pll2m = ((RCC->PLL2CFGR & RCC_PLL2CFGR_PLL2M) >> RCC_PLL2CFGR_PLL2M_Pos); + pll2fracen = RCC->PLL2CFGR & RCC_PLL2CFGR_PLL2FRACEN; + fracn2 = (float_t)(uint32_t)(pll2fracen * ((RCC->PLL2FRACR & RCC_PLL2FRACR_PLL2FRACN) >> \ + RCC_PLL2FRACR_PLL2FRACN_Pos)); + + if (pll2m != 0U) + { + switch (pll2source) + { + case RCC_PLL2_SOURCE_HSI: /* HSI used as PLL clock source */ + hsivalue = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + pll2vco = ((float_t)hsivalue / (float_t)pll2m) * ((float_t)(uint32_t)pll2n + (fracn2 / (float_t)0x2000) + \ + (float_t)1); + break; + + case RCC_PLL2_SOURCE_CSI: /* CSI used as PLL clock source */ + pll2vco = ((float_t)CSI_VALUE / (float_t)pll2m) * ((float_t)(uint32_t)pll2n + (fracn2 / (float_t)0x2000) + \ + (float_t)1); + break; + + case RCC_PLL2_SOURCE_HSE: /* HSE used as PLL clock source */ + pll2vco = ((float_t)HSE_VALUE / (float_t)pll2m) * ((float_t)(uint32_t)pll2n + (fracn2 / (float_t)0x2000) + \ + (float_t)1); + break; + + default: + hsivalue = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + pll2vco = ((float_t)hsivalue / (float_t)pll2m) * ((float_t)(uint32_t)pll2n + (fracn2 / (float_t)0x2000) + \ + (float_t)1); + break; + } + + if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL2RDY)) + { + if (__HAL_RCC_GET_PLL2_CLKOUT_CONFIG(RCC_PLL2_DIVP) != 0U) + { + pPLL2_Clocks->PLL2_P_Frequency = \ + (uint32_t)(float_t)(pll2vco / \ + ((float_t)(uint32_t)((RCC->PLL2DIVR & \ + RCC_PLL2DIVR_PLL2P) >> \ + RCC_PLL2DIVR_PLL2P_Pos) + \ + (float_t)1)); + } + else + { + pPLL2_Clocks->PLL2_P_Frequency = 0U; + } + } + else + { + pPLL2_Clocks->PLL2_P_Frequency = 0U; + } + + if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL2RDY)) + { + if (__HAL_RCC_GET_PLL2_CLKOUT_CONFIG(RCC_PLL2_DIVQ) != 0U) + { + pPLL2_Clocks->PLL2_Q_Frequency = \ + (uint32_t)(float_t)(pll2vco / \ + ((float_t)(uint32_t)((RCC->PLL2DIVR & \ + RCC_PLL2DIVR_PLL2Q) >> \ + RCC_PLL2DIVR_PLL2Q_Pos) + \ + (float_t)1)); + } + else + { + pPLL2_Clocks->PLL2_Q_Frequency = 0U; + } + } + else + { + pPLL2_Clocks->PLL2_Q_Frequency = 0U; + } + + if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL2RDY)) + { + if (__HAL_RCC_GET_PLL2_CLKOUT_CONFIG(RCC_PLL2_DIVR) != 0U) + { + pPLL2_Clocks->PLL2_R_Frequency = \ + (uint32_t)(float_t)(pll2vco / \ + ((float_t)(uint32_t)((RCC->PLL2DIVR & \ + RCC_PLL2DIVR_PLL2R) >> \ + RCC_PLL2DIVR_PLL2R_Pos) + \ + (float_t)1)); + } + else + { + pPLL2_Clocks->PLL2_R_Frequency = 0U; + } + } + else + { + pPLL2_Clocks->PLL2_R_Frequency = 0U; + } + } + else + { + pPLL2_Clocks->PLL2_P_Frequency = 0U; + pPLL2_Clocks->PLL2_Q_Frequency = 0U; + pPLL2_Clocks->PLL2_R_Frequency = 0U; + } +} + +#if defined(RCC_CR_PLL3ON) +/** + * @brief Returns the PLL3 clock frequencies: PLL3_P_Frequency, PLL3_R_Frequency and PLL3_Q_Frequency + * @note The PLL3 clock frequencies computed by this function may not be the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * @note The function returns values based on HSE_VALUE, HSI_VALUE or CSI Value multiplied/divided by + the PLL factors. + * @note This function can be used by the user application to compute the + * baud-rate for the communication peripherals or configure other parameters. + * + * @note Each time PLL3CLK changes, this function must be called to update the + * right PLL3CLK value. Otherwise, any configuration based on this function will be incorrect. + * @param pPLL3_Clocks pointer to PLL3_ClocksTypeDef structure. + * @retval None + */ +void HAL_RCCEx_GetPLL3ClockFreq(PLL3_ClocksTypeDef *pPLL3_Clocks) +{ + uint32_t pll3source; + uint32_t pll3m; + uint32_t pll3n; + uint32_t pll3fracen; + uint32_t hsivalue; + float_t fracn3; + float_t pll3vco; + + /* PLL_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLL3M) * PLL3N + PLL3xCLK = PLL3_VCO / PLL3x + */ + pll3n = (RCC->PLL3DIVR & RCC_PLL3DIVR_PLL3N); + pll3source = (RCC->PLL3CFGR & RCC_PLL3CFGR_PLL3SRC); + pll3m = ((RCC->PLL3CFGR & RCC_PLL3CFGR_PLL3M) >> RCC_PLL3CFGR_PLL3M_Pos); + pll3fracen = RCC->PLL3CFGR & RCC_PLL3CFGR_PLL3FRACEN; + fracn3 = (float_t)(uint32_t)(pll3fracen * ((RCC->PLL3FRACR & RCC_PLL3FRACR_PLL3FRACN) >> \ + RCC_PLL3FRACR_PLL3FRACN_Pos)); + + if (pll3m != 0U) + { + switch (pll3source) + { + case RCC_PLL3_SOURCE_HSI: /* HSI used as PLL clock source */ + hsivalue = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + pll3vco = ((float_t)hsivalue / (float_t)pll3m) * ((float_t)(uint32_t)pll3n + (fracn3 / (float_t)0x2000) + \ + (float_t)1); + break; + + case RCC_PLL3_SOURCE_CSI: /* CSI used as PLL clock source */ + pll3vco = ((float_t)CSI_VALUE / (float_t)pll3m) * ((float_t)(uint32_t)pll3n + (fracn3 / (float_t)0x2000) + \ + (float_t)1); + break; + + case RCC_PLL3_SOURCE_HSE: /* HSE used as PLL clock source */ + pll3vco = ((float_t)HSE_VALUE / (float_t)pll3m) * ((float_t)(uint32_t)pll3n + (fracn3 / (float_t)0x2000) + \ + (float_t)1); + break; + + default: + hsivalue = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + pll3vco = ((float_t)hsivalue / (float_t)pll3m) * ((float_t)(uint32_t)pll3n + (fracn3 / (float_t)0x2000) + \ + (float_t)1); + break; + } + + if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3RDY)) + { + if (__HAL_RCC_GET_PLL3_CLKOUT_CONFIG(RCC_PLL3_DIVP) != 0U) + { + pPLL3_Clocks->PLL3_P_Frequency = \ + (uint32_t)(float_t)(pll3vco / \ + ((float_t)(uint32_t)((RCC->PLL3DIVR & \ + RCC_PLL3DIVR_PLL3P) >> \ + RCC_PLL3DIVR_PLL3P_Pos) + \ + (float_t)1)); + } + else + { + pPLL3_Clocks->PLL3_P_Frequency = 0U; + } + } + else + { + pPLL3_Clocks->PLL3_P_Frequency = 0U; + } + + if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3RDY)) + { + if (__HAL_RCC_GET_PLL3_CLKOUT_CONFIG(RCC_PLL3_DIVQ) != 0U) + { + pPLL3_Clocks->PLL3_Q_Frequency = \ + (uint32_t)(float_t)(pll3vco / \ + ((float_t)(uint32_t)((RCC->PLL3DIVR & \ + RCC_PLL3DIVR_PLL3Q) >> \ + RCC_PLL3DIVR_PLL3Q_Pos) + \ + (float_t)1)); + } + else + { + pPLL3_Clocks->PLL3_Q_Frequency = 0U; + } + } + else + { + pPLL3_Clocks->PLL3_Q_Frequency = 0U; + } + + if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3RDY)) + { + if (__HAL_RCC_GET_PLL3_CLKOUT_CONFIG(RCC_PLL3_DIVR) != 0U) + { + pPLL3_Clocks->PLL3_R_Frequency = \ + (uint32_t)(float_t)(pll3vco / \ + ((float_t)(uint32_t)((RCC->PLL3DIVR & \ + RCC_PLL3DIVR_PLL3R) >> \ + RCC_PLL3DIVR_PLL3R_Pos) + \ + (float_t)1)); + } + else + { + pPLL3_Clocks->PLL3_R_Frequency = 0U; + } + } + else + { + pPLL3_Clocks->PLL3_R_Frequency = 0U; + } + } + else + { + pPLL3_Clocks->PLL3_P_Frequency = 0U; + pPLL3_Clocks->PLL3_Q_Frequency = 0U; + pPLL3_Clocks->PLL3_R_Frequency = 0U; + } +} +#endif /* RCC_CR_PLL3ON */ + +/** + * @brief Return the peripheral clock frequency for peripherals + * @note Return 0 if peripheral clock identifier not managed by this API + * @param PeriphClk Peripheral clock identifier + * This parameter can be one of the following values: + * @arg @ref RCC_PERIPHCLK_USART1 USART1 peripheral clock + * @arg @ref RCC_PERIPHCLK_USART2 USART2 peripheral clock + * @arg @ref RCC_PERIPHCLK_USART3 USART3 peripheral clock + * @arg @ref RCC_PERIPHCLK_UART4 UART4 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_UART5 UART5 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_USART6 USART6 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_UART7 UART7 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_UART8 UART8 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_UART9 UART9 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_USART10 USART10 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_USART11 USART11 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_UART12 UART12 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_LPUART1 LPUART1 peripheral clock + * @arg @ref RCC_PERIPHCLK_I2C1 I2C1 peripheral clock + * @arg @ref RCC_PERIPHCLK_I2C2 I2C2 peripheral clock + * @arg @ref RCC_PERIPHCLK_I2C3 I2C3 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_I2C4 I2C4 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_I3C1 I3C1 peripheral clock + * @arg @ref RCC_PERIPHCLK_I3C2 I3C2 peripheral clock (***) + * @arg @ref RCC_PERIPHCLK_LPTIM1 LPTIM1 peripheral clock + * @arg @ref RCC_PERIPHCLK_LPTIM2 LPTIM2 peripheral clock + * @arg @ref RCC_PERIPHCLK_SAI1 SAI1 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_SAI2 SAI2 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_ADCDAC ADCDAC peripheral clock + * @arg @ref RCC_PERIPHCLK_ADC ADC peripheral clock + * @arg @ref RCC_PERIPHCLK_SDMMC1 SDMMC1 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_SDMMC2 SDMMC2 peripheral clock (**) + * @arg @ref RCC_PERIPHCLK_CKPER CKPER peripheral clock + * @arg @ref RCC_PERIPHCLK_RTC RTC peripheral clock + * @arg @ref RCC_PERIPHCLK_RNG RNG peripheral clock + * @arg @ref RCC_PERIPHCLK_SPI1 SPI1 peripheral clock + * @arg @ref RCC_PERIPHCLK_SPI2 SPI2 peripheral clock + * @arg @ref RCC_PERIPHCLK_SPI3 SPI3 peripheral clock + * @arg @ref RCC_PERIPHCLK_SPI4 SPI4 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_SPI5 SPI5 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_SPI6 SPI6 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_OSPI OCTOSPI peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_FDCAN FDCAN peripheral clock + * @arg @ref RCC_PERIPHCLK_CEC CEC peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock + * @arg @ref RCC_PERIPHCLK_LPTIM3 LPTIM3 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_LPTIM4 LPTIM4 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_LPTIM5 LPTIM5 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_LPTIM6 LPTIM6 peripheral clock (*) + * @arg @ref RCC_PERIPHCLK_DAC_LP DAC low-power peripheral clock + * @arg @ref RCC_PERIPHCLK_TIM TIM peripheral clock + * + * @retval Frequency in Hz + * + * (*) : For stm32h56xxx and stm32h57xxx family lines only. + * (**) : For stm32h563xx and stm32h57xxx family lines only. + * (***) : For stm32h503xx family line only. + */ +uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint64_t PeriphClk) +{ + PLL1_ClocksTypeDef pll1_clocks; + PLL2_ClocksTypeDef pll2_clocks; +#if defined(RCC_CR_PLL3ON) + PLL3_ClocksTypeDef pll3_clocks; +#endif /* RCC_CR_PLL3ON */ + + uint32_t frequency; + uint32_t ckpclocksource; + uint32_t srcclk; + + /* Check the parameters */ + assert_param(IS_RCC_PERIPHCLOCK(PeriphClk)); + + if (PeriphClk == RCC_PERIPHCLK_RTC) + { + /* Get the current RTC source */ + srcclk = __HAL_RCC_GET_RTC_SOURCE(); + + /* Check if LSE is ready and if RTC clock selection is LSE */ + if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_RTCCLKSOURCE_LSE)) + { + frequency = LSE_VALUE; + } + /* Check if LSI is ready and if RTC clock selection is LSI */ + else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSIRDY)) && (srcclk == RCC_RTCCLKSOURCE_LSI)) + { + frequency = LSI_VALUE; + } + /* Check if HSE is ready and if RTC clock selection is HSE_DIVx*/ + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)) && (srcclk == RCC_RTCCLKSOURCE_HSE_DIVx)) + { + if (__HAL_RCC_GET_RTC_HSE_PRESCALER() >= RCC_RTC_HSE_DIV2) + { + frequency = (HSE_VALUE / ((uint32_t)(__HAL_RCC_GET_RTC_HSE_PRESCALER() >> RCC_CFGR1_RTCPRE_Pos))); + } + else + { + frequency = 0U; + } + + } + /* Clock not enabled for RTC*/ + else + { + frequency = 0U; + } + } + else + { + /* Other external peripheral clock source than RTC */ + switch (PeriphClk) + { +#if defined (SAI1) + case RCC_PERIPHCLK_SAI1: + + srcclk = __HAL_RCC_GET_SAI1_SOURCE(); + + switch (srcclk) + { + case RCC_SAI1CLKSOURCE_PLL1Q: /* PLL1Q is the clock source for SAI1 */ + { + HAL_RCCEx_GetPLL1ClockFreq(&pll1_clocks); + frequency = pll1_clocks.PLL1_Q_Frequency; + break; + } + case RCC_SAI1CLKSOURCE_PLL2P: /* PLL2P is the clock source for SAI1 */ + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_P_Frequency; + break; + } + case RCC_SAI1CLKSOURCE_PLL3P: /* PLLI3P is the clock source for SAI1 */ + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_P_Frequency; + break; + } + case RCC_SAI1CLKSOURCE_PIN: + { + frequency = EXTERNAL_CLOCK_VALUE; + break; + } + case RCC_SAI1CLKSOURCE_CLKP: /* CLKP is the clock source for SAI1 */ + { + + ckpclocksource = __HAL_RCC_GET_CLKP_SOURCE(); + + if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY) && (ckpclocksource == RCC_CLKPSOURCE_HSI)) + { + /* In Case the CKPER Source is HSI */ + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + + else if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY) && (ckpclocksource == RCC_CLKPSOURCE_CSI)) + { + /* In Case the CKPER Source is CSI */ + frequency = CSI_VALUE; + } + + else if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY) && (ckpclocksource == RCC_CLKPSOURCE_HSE)) + { + /* In Case the CKPER Source is HSE */ + frequency = HSE_VALUE; + } + + else + { + /* In Case the CKPER is disabled*/ + frequency = 0U; + } + + break; + } + default : + { + frequency = 0U; + break; + } + } + break; +#endif /*SAI1*/ + +#if defined(SAI2) + case RCC_PERIPHCLK_SAI2: + + srcclk = __HAL_RCC_GET_SAI2_SOURCE(); + + switch (srcclk) + { + case RCC_SAI2CLKSOURCE_PLL1Q: /* PLL1Q is the clock source for SAI2 */ + { + HAL_RCCEx_GetPLL1ClockFreq(&pll1_clocks); + frequency = pll1_clocks.PLL1_Q_Frequency; + break; + } + case RCC_SAI2CLKSOURCE_PLL2P: /* PLL2P is the clock source for SAI2 */ + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_P_Frequency; + break; + } + case RCC_SAI2CLKSOURCE_PLL3P: /* PLLI3P is the clock source for SAI2 */ + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_P_Frequency; + break; + } + case RCC_SAI2CLKSOURCE_PIN: + { + frequency = EXTERNAL_CLOCK_VALUE; + break; + } + case RCC_SAI2CLKSOURCE_CLKP: /* CLKP is the clock source for SAI2 */ + { + + ckpclocksource = __HAL_RCC_GET_CLKP_SOURCE(); + + if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY) && (ckpclocksource == RCC_CLKPSOURCE_HSI)) + { + /* In Case the CKPER Source is HSI */ + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + + else if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY) && (ckpclocksource == RCC_CLKPSOURCE_CSI)) + { + /* In Case the CKPER Source is CSI */ + frequency = CSI_VALUE; + } + + else if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY) && (ckpclocksource == RCC_CLKPSOURCE_HSE)) + { + /* In Case the CKPER Source is HSE */ + frequency = HSE_VALUE; + } + + else + { + /* In Case the CKPER is disabled*/ + frequency = 0U; + } + + break; + } + default : + { + frequency = 0U; + break; + } + } + break; +#endif /* SAI2 */ + +#if defined(SDMMC1) + case RCC_PERIPHCLK_SDMMC1: + srcclk = __HAL_RCC_GET_SDMMC1_SOURCE(); + if (srcclk == RCC_SDMMC1CLKSOURCE_PLL1Q) + { + HAL_RCCEx_GetPLL1ClockFreq(&pll1_clocks); + frequency = pll1_clocks.PLL1_Q_Frequency; + } + else if (srcclk == RCC_SDMMC1CLKSOURCE_PLL2R) + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_R_Frequency; + } + else + { + frequency = 0U; + } + break; +#endif /* SDMMC1 */ + +#if defined(SDMMC2) + case RCC_PERIPHCLK_SDMMC2: + srcclk = __HAL_RCC_GET_SDMMC2_SOURCE(); + if (srcclk == RCC_SDMMC2CLKSOURCE_PLL1Q) + { + HAL_RCCEx_GetPLL1ClockFreq(&pll1_clocks); + frequency = pll1_clocks.PLL1_Q_Frequency; + } + else if (srcclk == RCC_SDMMC2CLKSOURCE_PLL2R) + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_R_Frequency; + } + else + { + frequency = 0U; + } + break; +#endif /* SDMMC2 */ + + case RCC_PERIPHCLK_USART1: + /* Get the current USART1 source */ + srcclk = __HAL_RCC_GET_USART1_SOURCE(); + + if (srcclk == RCC_USART1CLKSOURCE_PCLK2) + { + frequency = HAL_RCC_GetPCLK2Freq(); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL2RDY)) && (srcclk == RCC_USART1CLKSOURCE_PLL2Q)) + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_Q_Frequency; + } +#if defined(RCC_USART1CLKSOURCE_PLL3Q) + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3RDY)) && (srcclk == RCC_USART1CLKSOURCE_PLL3Q)) + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_Q_Frequency; + } +#endif /* RCC_USART1CLKSOURCE_PLL3Q */ + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_USART1CLKSOURCE_HSI)) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY)) && (srcclk == RCC_USART1CLKSOURCE_CSI)) + { + frequency = CSI_VALUE; + } + else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_USART1CLKSOURCE_LSE)) + { + frequency = LSE_VALUE; + } + /* Clock not enabled for USART1 */ + else + { + frequency = 0U; + } + break; + + case RCC_PERIPHCLK_USART2: + /* Get the current USART2 source */ + srcclk = __HAL_RCC_GET_USART2_SOURCE(); + + if (srcclk == RCC_USART2CLKSOURCE_PCLK1) + { + frequency = HAL_RCC_GetPCLK1Freq(); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL2RDY)) && (srcclk == RCC_USART2CLKSOURCE_PLL2Q)) + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_Q_Frequency; + } +#if defined(RCC_USART2CLKSOURCE_PLL3Q) + else if ((srcclk == RCC_USART2CLKSOURCE_PLL3Q)) + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_Q_Frequency; + } +#endif /* RCC_USART2CLKSOURCE_PLL3Q */ + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_USART2CLKSOURCE_HSI)) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY)) && (srcclk == RCC_USART2CLKSOURCE_CSI)) + { + frequency = CSI_VALUE; + } + else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_USART2CLKSOURCE_LSE)) + { + frequency = LSE_VALUE; + } + /* Clock not enabled for USART2 */ + else + { + frequency = 0U; + } + break; + + case RCC_PERIPHCLK_USART3: + /* Get the current USART3 source */ + srcclk = __HAL_RCC_GET_USART3_SOURCE(); + + if (srcclk == RCC_USART3CLKSOURCE_PCLK1) + { + frequency = HAL_RCC_GetPCLK1Freq(); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL2RDY)) && (srcclk == RCC_USART3CLKSOURCE_PLL2Q)) + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_Q_Frequency; + } +#if defined(RCC_USART3CLKSOURCE_PLL3Q) + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3RDY)) && (srcclk == RCC_USART3CLKSOURCE_PLL3Q)) + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_Q_Frequency; + } +#endif /* RCC_USART3CLKSOURCE_PLL3S */ + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_USART3CLKSOURCE_HSI)) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY)) && (srcclk == RCC_USART3CLKSOURCE_CSI)) + { + frequency = CSI_VALUE; + } + else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_USART3CLKSOURCE_LSE)) + { + frequency = LSE_VALUE; + } + /* Clock not enabled for USART3 */ + else + { + frequency = 0U; + } + break; + +#if defined(UART4) + case RCC_PERIPHCLK_UART4: + /* Get the current UART4 source */ + srcclk = __HAL_RCC_GET_UART4_SOURCE(); + + if (srcclk == RCC_UART4CLKSOURCE_PCLK1) + { + frequency = HAL_RCC_GetPCLK1Freq(); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL2RDY)) && (srcclk == RCC_UART4CLKSOURCE_PLL2Q)) + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_Q_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3RDY)) && (srcclk == RCC_UART4CLKSOURCE_PLL3Q)) + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_Q_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_UART4CLKSOURCE_HSI)) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY)) && (srcclk == RCC_UART4CLKSOURCE_CSI)) + { + frequency = CSI_VALUE; + } + else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_UART4CLKSOURCE_LSE)) + { + frequency = LSE_VALUE; + } + /* Clock not enabled for UART4 */ + else + { + frequency = 0U; + } + break; +#endif /* UART4 */ + +#if defined(UART5) + case RCC_PERIPHCLK_UART5: + /* Get the current UART5 source */ + srcclk = __HAL_RCC_GET_UART5_SOURCE(); + + if (srcclk == RCC_UART5CLKSOURCE_PCLK1) + { + frequency = HAL_RCC_GetPCLK1Freq(); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL2RDY)) && (srcclk == RCC_UART5CLKSOURCE_PLL2Q)) + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_Q_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3RDY)) && (srcclk == RCC_UART5CLKSOURCE_PLL3Q)) + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_Q_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_UART5CLKSOURCE_HSI)) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY)) && (srcclk == RCC_UART5CLKSOURCE_CSI)) + { + frequency = CSI_VALUE; + } + else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_UART5CLKSOURCE_LSE)) + { + frequency = LSE_VALUE; + } + /* Clock not enabled for UART5 */ + else + { + frequency = 0U; + } + break; +#endif /* UART5 */ + +#if defined(USART6) + case RCC_PERIPHCLK_USART6: + /* Get the current USART6 source */ + srcclk = __HAL_RCC_GET_USART6_SOURCE(); + + if (srcclk == RCC_USART6CLKSOURCE_PCLK1) + { + frequency = HAL_RCC_GetPCLK1Freq(); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL2RDY)) && (srcclk == RCC_USART6CLKSOURCE_PLL2Q)) + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_Q_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3RDY)) && (srcclk == RCC_USART6CLKSOURCE_PLL3Q)) + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_Q_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_USART6CLKSOURCE_HSI)) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY)) && (srcclk == RCC_USART6CLKSOURCE_CSI)) + { + frequency = CSI_VALUE; + } + else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_USART6CLKSOURCE_LSE)) + { + frequency = LSE_VALUE; + } + /* Clock not enabled for USART6 */ + else + { + frequency = 0U; + } + break; +#endif /* USART6 */ + +#if defined(UART7) + case RCC_PERIPHCLK_UART7: + /* Get the current UART7 source */ + srcclk = __HAL_RCC_GET_UART7_SOURCE(); + + if (srcclk == RCC_UART7CLKSOURCE_PCLK1) + { + frequency = HAL_RCC_GetPCLK1Freq(); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL2RDY)) && (srcclk == RCC_UART7CLKSOURCE_PLL2Q)) + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_Q_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3RDY)) && (srcclk == RCC_UART7CLKSOURCE_PLL3Q)) + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_Q_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_UART7CLKSOURCE_HSI)) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY)) && (srcclk == RCC_UART7CLKSOURCE_CSI)) + { + frequency = CSI_VALUE; + } + else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_UART7CLKSOURCE_LSE)) + { + frequency = LSE_VALUE; + } + /* Clock not enabled for UART7 */ + else + { + frequency = 0U; + } + break; +#endif /* UART7 */ + +#if defined(UART8) + case RCC_PERIPHCLK_UART8: + /* Get the current UART8 source */ + srcclk = __HAL_RCC_GET_UART8_SOURCE(); + + if (srcclk == RCC_UART8CLKSOURCE_PCLK1) + { + frequency = HAL_RCC_GetPCLK1Freq(); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL2RDY)) && (srcclk == RCC_UART8CLKSOURCE_PLL2Q)) + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_Q_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3RDY)) && (srcclk == RCC_UART8CLKSOURCE_PLL3Q)) + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_Q_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_UART8CLKSOURCE_HSI)) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY)) && (srcclk == RCC_UART8CLKSOURCE_CSI)) + { + frequency = CSI_VALUE; + } + else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_UART8CLKSOURCE_LSE)) + { + frequency = LSE_VALUE; + } + /* Clock not enabled for UART8 */ + else + { + frequency = 0U; + } + break; +#endif /* UART8 */ + +#if defined(UART9) + case RCC_PERIPHCLK_UART9: + /* Get the current UART9 source */ + srcclk = __HAL_RCC_GET_UART9_SOURCE(); + + if (srcclk == RCC_UART9CLKSOURCE_PCLK1) + { + frequency = HAL_RCC_GetPCLK1Freq(); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL2RDY)) && (srcclk == RCC_UART9CLKSOURCE_PLL2Q)) + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_Q_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3RDY)) && (srcclk == RCC_UART9CLKSOURCE_PLL3Q)) + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_Q_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_UART9CLKSOURCE_HSI)) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY)) && (srcclk == RCC_UART9CLKSOURCE_CSI)) + { + frequency = CSI_VALUE; + } + else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_UART9CLKSOURCE_LSE)) + { + frequency = LSE_VALUE; + } + /* Clock not enabled for UART9 */ + else + { + frequency = 0U; + } + break; +#endif /* UART9 */ + +#if defined(USART10) + case RCC_PERIPHCLK_USART10: + /* Get the current USART10 source */ + srcclk = __HAL_RCC_GET_USART10_SOURCE(); + + if (srcclk == RCC_USART10CLKSOURCE_PCLK1) + { + frequency = HAL_RCC_GetPCLK1Freq(); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL2RDY)) && (srcclk == RCC_USART10CLKSOURCE_PLL2Q)) + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_Q_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3RDY)) && (srcclk == RCC_USART10CLKSOURCE_PLL3Q)) + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_Q_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_USART10CLKSOURCE_HSI)) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY)) && (srcclk == RCC_USART10CLKSOURCE_CSI)) + { + frequency = CSI_VALUE; + } + else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_USART10CLKSOURCE_LSE)) + { + frequency = LSE_VALUE; + } + /* Clock not enabled for USART10 */ + else + { + frequency = 0U; + } + break; +#endif /* USART10 */ + +#if defined(USART11) + case RCC_PERIPHCLK_USART11: + /* Get the current USART11 source */ + srcclk = __HAL_RCC_GET_USART11_SOURCE(); + + if (srcclk == RCC_USART11CLKSOURCE_PCLK1) + { + frequency = HAL_RCC_GetPCLK1Freq(); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL2RDY)) && (srcclk == RCC_USART11CLKSOURCE_PLL2Q)) + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_Q_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3RDY)) && (srcclk == RCC_USART11CLKSOURCE_PLL3Q)) + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_Q_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_USART11CLKSOURCE_HSI)) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY)) && (srcclk == RCC_USART11CLKSOURCE_CSI)) + { + frequency = CSI_VALUE; + } + else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_USART11CLKSOURCE_LSE)) + { + frequency = LSE_VALUE; + } + /* Clock not enabled for USART11 */ + else + { + frequency = 0U; + } + break; +#endif /* USART11 */ + +#if defined(UART12) + case RCC_PERIPHCLK_UART12: + /* Get the current UART12 source */ + srcclk = __HAL_RCC_GET_UART12_SOURCE(); + + if (srcclk == RCC_UART12CLKSOURCE_PCLK1) + { + frequency = HAL_RCC_GetPCLK1Freq(); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL2RDY)) && (srcclk == RCC_UART12CLKSOURCE_PLL2Q)) + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_Q_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3RDY)) && (srcclk == RCC_UART12CLKSOURCE_PLL3Q)) + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_Q_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_UART12CLKSOURCE_HSI)) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY)) && (srcclk == RCC_UART12CLKSOURCE_CSI)) + { + frequency = CSI_VALUE; + } + else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_UART12CLKSOURCE_LSE)) + { + frequency = LSE_VALUE; + } + /* Clock not enabled for UART12 */ + else + { + frequency = 0U; + } + break; +#endif /* UART12 */ + + case RCC_PERIPHCLK_LPUART1: + /* Get the current LPUART1 source */ + srcclk = __HAL_RCC_GET_LPUART1_SOURCE(); + + if (srcclk == RCC_LPUART1CLKSOURCE_PCLK3) + { + frequency = HAL_RCC_GetPCLK3Freq(); + } + else if (srcclk == RCC_LPUART1CLKSOURCE_PLL2Q) + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_Q_Frequency; + } +#if defined(RCC_LPUART1CLKSOURCE_PLL3Q) + else if (srcclk == RCC_LPUART1CLKSOURCE_PLL3Q) + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_Q_Frequency; + } +#endif /* RCC_LPUART1CLKSOURCE_PLL3Q */ + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_LPUART1CLKSOURCE_HSI)) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY)) && (srcclk == RCC_LPUART1CLKSOURCE_CSI)) + { + frequency = CSI_VALUE; + } + else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_LPUART1CLKSOURCE_LSE)) + { + frequency = LSE_VALUE; + } + /* Clock not enabled for LPUART1 */ + else + { + frequency = 0U; + } + break; + + case RCC_PERIPHCLK_ADCDAC: + /* Get the current ADCDAC source */ + srcclk = __HAL_RCC_GET_ADCDAC_SOURCE(); + + if (srcclk == RCC_ADCDACCLKSOURCE_HCLK) + { + frequency = HAL_RCC_GetHCLKFreq(); + } + else if (srcclk == RCC_ADCDACCLKSOURCE_SYSCLK) + { + frequency = HAL_RCC_GetSysClockFreq(); + } + else if (srcclk == RCC_ADCDACCLKSOURCE_PLL2R) + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_R_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)) && (srcclk == RCC_ADCDACCLKSOURCE_HSE)) + { + frequency = HSE_VALUE; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_ADCDACCLKSOURCE_HSI)) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY)) && (srcclk == RCC_ADCDACCLKSOURCE_CSI)) + { + frequency = CSI_VALUE; + } + /* Clock not enabled for ADCDAC */ + else + { + frequency = 0U; + } + break; + + + case RCC_PERIPHCLK_DAC_LP: + /* Get the current DAC low-power source */ + srcclk = __HAL_RCC_GET_DAC_LP_SOURCE(); + + if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_DACLPCLKSOURCE_LSE)) + { + frequency = LSE_VALUE; + } + else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSIRDY)) && (srcclk == RCC_DACLPCLKSOURCE_LSI)) + { + frequency = LSI_VALUE; + } + + /* Clock not enabled for DAC */ + else + { + frequency = 0U; + } + break; + + case RCC_PERIPHCLK_I2C1: + /* Get the current I2C1 source */ + srcclk = __HAL_RCC_GET_I2C1_SOURCE(); + + if (srcclk == RCC_I2C1CLKSOURCE_PCLK1) + { + frequency = HAL_RCC_GetPCLK1Freq(); + } +#if defined(RCC_I2C1CLKSOURCE_PLL3R) + else if (srcclk == RCC_I2C1CLKSOURCE_PLL3R) + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_R_Frequency; + } +#else + else if (srcclk == RCC_I2C1CLKSOURCE_PLL2R) + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_R_Frequency; + } +#endif /* RCC_I2C1CLKSOURCE_PLL3R */ + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_I2C1CLKSOURCE_HSI)) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY)) && (srcclk == RCC_I2C1CLKSOURCE_CSI)) + { + frequency = CSI_VALUE; + } + /* Clock not enabled for I2C1 */ + else + { + frequency = 0U; + } + break; + + case RCC_PERIPHCLK_I2C2: + /* Get the current I2C2 source */ + srcclk = __HAL_RCC_GET_I2C2_SOURCE(); + + if (srcclk == RCC_I2C2CLKSOURCE_PCLK1) + { + frequency = HAL_RCC_GetPCLK1Freq(); + } +#if defined(RCC_I2C2CLKSOURCE_PLL3R) + else if (srcclk == RCC_I2C2CLKSOURCE_PLL3R) + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_R_Frequency; + } +#else + else if (srcclk == RCC_I2C2CLKSOURCE_PLL2R) + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_R_Frequency; + } +#endif /* RCC_I2C2CLKSOURCE_PLL3R */ + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_I2C2CLKSOURCE_HSI)) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY)) && (srcclk == RCC_I2C2CLKSOURCE_CSI)) + { + frequency = CSI_VALUE; + } + /* Clock not enabled for I2C2 */ + else + { + frequency = 0U; + } + break; + +#if defined(I2C3) + case RCC_PERIPHCLK_I2C3: + /* Get the current I2C3 source */ + srcclk = __HAL_RCC_GET_I2C3_SOURCE(); + + if (srcclk == RCC_I2C3CLKSOURCE_PCLK3) + { + frequency = HAL_RCC_GetPCLK3Freq(); + } + else if (srcclk == RCC_I2C3CLKSOURCE_PLL3R) + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_R_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_I2C3CLKSOURCE_HSI)) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY)) && (srcclk == RCC_I2C3CLKSOURCE_CSI)) + { + frequency = CSI_VALUE; + } + /* Clock not enabled for I2C3 */ + else + { + frequency = 0U; + } + break; +#endif /* I2C3 */ + +#if defined(I2C4) + case RCC_PERIPHCLK_I2C4: + /* Get the current I2C4 source */ + srcclk = __HAL_RCC_GET_I2C4_SOURCE(); + + if (srcclk == RCC_I2C4CLKSOURCE_PCLK3) + { + frequency = HAL_RCC_GetPCLK3Freq(); + } + else if (srcclk == RCC_I2C4CLKSOURCE_PLL3R) + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_R_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_I2C4CLKSOURCE_HSI)) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY)) && (srcclk == RCC_I2C4CLKSOURCE_CSI)) + { + frequency = CSI_VALUE; + } + /* Clock not enabled for I2C4 */ + else + { + frequency = 0U; + } + break; +#endif /* I2C4 */ + + case RCC_PERIPHCLK_I3C1: + /* Get the current I3C1 source */ + srcclk = __HAL_RCC_GET_I3C1_SOURCE(); + + if (srcclk == RCC_I3C1CLKSOURCE_PCLK1) + { + frequency = HAL_RCC_GetPCLK1Freq(); + } +#if defined(RCC_I3C1CLKSOURCE_PLL3R) + else if (srcclk == RCC_I3C1CLKSOURCE_PLL3R) + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_R_Frequency; + } +#else + else if (srcclk == RCC_I3C1CLKSOURCE_PLL2R) + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_R_Frequency; + } +#endif /* RCC_I3C1CLKSOURCE_PLL3R */ + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_I3C1CLKSOURCE_HSI)) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + /* Clock not enabled for I3C1 */ + else + { + frequency = 0U; + } + break; + +#if defined(I3C2) + case RCC_PERIPHCLK_I3C2: + /* Get the current I3C2 source */ + srcclk = __HAL_RCC_GET_I3C2_SOURCE(); + + if (srcclk == RCC_I3C2CLKSOURCE_PCLK3) + { + frequency = HAL_RCC_GetPCLK3Freq(); + } + else if (srcclk == RCC_I3C2CLKSOURCE_PLL2R) + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_R_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_I3C2CLKSOURCE_HSI)) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + /* Clock not enabled for I3C2 */ + else + { + frequency = 0U; + } + break; +#endif /* I3C2*/ + + case RCC_PERIPHCLK_LPTIM1: + /* Get the current LPTIM1 source */ + srcclk = __HAL_RCC_GET_LPTIM1_SOURCE(); + + switch (srcclk) + { + case RCC_LPTIM1CLKSOURCE_PCLK3: + { + frequency = HAL_RCC_GetPCLK3Freq(); + break; + } + case RCC_LPTIM1CLKSOURCE_PLL2P: + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_P_Frequency; + break; + } +#if defined(RCC_LPTIM1CLKSOURCE_PLL3R) + case RCC_LPTIM1CLKSOURCE_PLL3R: + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_R_Frequency; + break; + } +#endif /* RCC_LPTIM1CLKSOURCE_PLL3R */ + case RCC_LPTIM1CLKSOURCE_LSE: + { + if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) + { + frequency = LSE_VALUE; + } + else + { + frequency = 0; + } + break; + } + case RCC_LPTIM1CLKSOURCE_LSI: + { + if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSIRDY)) + { + frequency = LSI_VALUE; + } + else + { + frequency = 0; + } + break; + } + case RCC_LPTIM1CLKSOURCE_CLKP: /* CLKP is the clock source for LPTIM1 */ + { + ckpclocksource = __HAL_RCC_GET_CLKP_SOURCE(); + + if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY) && (ckpclocksource == RCC_CLKPSOURCE_HSI)) + { + /* In Case the CKPER Source is HSI */ + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + + else if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY) && (ckpclocksource == RCC_CLKPSOURCE_CSI)) + { + /* In Case the CKPER Source is CSI */ + frequency = CSI_VALUE; + } + + else if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY) && (ckpclocksource == RCC_CLKPSOURCE_HSE)) + { + /* In Case the CKPER Source is HSE */ + frequency = HSE_VALUE; + } + + else + { + /* In Case the CKPER is disabled*/ + frequency = 0; + } + + break; + } + default : + { + frequency = 0U; + break; + } + } + break; + + case RCC_PERIPHCLK_LPTIM2: + /* Get the current LPTIM2 source */ + srcclk = __HAL_RCC_GET_LPTIM2_SOURCE(); + + switch (srcclk) + { + case RCC_LPTIM2CLKSOURCE_PCLK1: + { + frequency = HAL_RCC_GetPCLK1Freq(); + break; + } + case RCC_LPTIM2CLKSOURCE_PLL2P: + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_P_Frequency; + break; + } +#if defined(RCC_LPTIM2CLKSOURCE_PLL3R) + case RCC_LPTIM2CLKSOURCE_PLL3R: + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_R_Frequency; + break; + } +#endif /* RCC_LPTIM2CLKSOURCE_PLL3R */ + case RCC_LPTIM2CLKSOURCE_LSE: + { + if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) + { + frequency = LSE_VALUE; + } + else + { + frequency = 0; + } + break; + } + case RCC_LPTIM2CLKSOURCE_LSI: + { + if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSIRDY)) + { + frequency = LSI_VALUE; + } + else + { + frequency = 0; + } + break; + } + case RCC_LPTIM2CLKSOURCE_CLKP: /* CLKP is the clock source for LPTIM2 */ + { + ckpclocksource = __HAL_RCC_GET_CLKP_SOURCE(); + + if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY) && (ckpclocksource == RCC_CLKPSOURCE_HSI)) + { + /* In Case the CKPER Source is HSI */ + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + + else if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY) && (ckpclocksource == RCC_CLKPSOURCE_CSI)) + { + /* In Case the CKPER Source is CSI */ + frequency = CSI_VALUE; + } + + else if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY) && (ckpclocksource == RCC_CLKPSOURCE_HSE)) + { + /* In Case the CKPER Source is HSE */ + frequency = HSE_VALUE; + } + + else + { + /* In Case the CKPER is disabled*/ + frequency = 0; + } + + break; + } + default : + { + frequency = 0U; + break; + } + } + break; + +#if defined(LPTIM3) + case RCC_PERIPHCLK_LPTIM3: + /* Get the current LPTIM3 source */ + srcclk = __HAL_RCC_GET_LPTIM3_SOURCE(); + + switch (srcclk) + { + case RCC_LPTIM3CLKSOURCE_PCLK3: + { + frequency = HAL_RCC_GetPCLK3Freq(); + break; + } + case RCC_LPTIM3CLKSOURCE_PLL2P: + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_P_Frequency; + break; + } + case RCC_LPTIM3CLKSOURCE_PLL3R: + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_R_Frequency; + break; + } + case RCC_LPTIM3CLKSOURCE_LSE: + { + if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) + { + frequency = LSE_VALUE; + } + else + { + frequency = 0; + } + break; + } + case RCC_LPTIM3CLKSOURCE_LSI: + { + if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSIRDY)) + { + frequency = LSI_VALUE; + } + else + { + frequency = 0; + } + break; + } + case RCC_LPTIM3CLKSOURCE_CLKP: /* CLKP is the clock source for LPTIM3 */ + { + ckpclocksource = __HAL_RCC_GET_CLKP_SOURCE(); + + if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY) && (ckpclocksource == RCC_CLKPSOURCE_HSI)) + { + /* In Case the CKPER Source is HSI */ + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + + else if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY) && (ckpclocksource == RCC_CLKPSOURCE_CSI)) + { + /* In Case the CKPER Source is CSI */ + frequency = CSI_VALUE; + } + + else if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY) && (ckpclocksource == RCC_CLKPSOURCE_HSE)) + { + /* In Case the CKPER Source is HSE */ + frequency = HSE_VALUE; + } + + else + { + /* In Case the CKPER is disabled*/ + frequency = 0; + } + + break; + } + default : + { + frequency = 0U; + break; + } + } + break; +#endif /* LPTIM3 */ + +#if defined(LPTIM4) + case RCC_PERIPHCLK_LPTIM4: + /* Get the current LPTIM4 source */ + srcclk = __HAL_RCC_GET_LPTIM4_SOURCE(); + + switch (srcclk) + { + case RCC_LPTIM4CLKSOURCE_PCLK3: + { + frequency = HAL_RCC_GetPCLK3Freq(); + break; + } + case RCC_LPTIM4CLKSOURCE_PLL2P: + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_P_Frequency; + break; + } + case RCC_LPTIM4CLKSOURCE_PLL3R: + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_R_Frequency; + break; + } + case RCC_LPTIM4CLKSOURCE_LSE: + { + if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) + { + frequency = LSE_VALUE; + } + else + { + frequency = 0; + } + break; + } + case RCC_LPTIM4CLKSOURCE_LSI: + { + if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSIRDY)) + { + frequency = LSI_VALUE; + } + else + { + frequency = 0; + } + break; + } + case RCC_LPTIM4CLKSOURCE_CLKP: /* CLKP is the clock source for LPTIM4 */ + { + ckpclocksource = __HAL_RCC_GET_CLKP_SOURCE(); + + if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY) && (ckpclocksource == RCC_CLKPSOURCE_HSI)) + { + /* In Case the CKPER Source is HSI */ + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + + else if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY) && (ckpclocksource == RCC_CLKPSOURCE_CSI)) + { + /* In Case the CKPER Source is CSI */ + frequency = CSI_VALUE; + } + + else if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY) && (ckpclocksource == RCC_CLKPSOURCE_HSE)) + { + /* In Case the CKPER Source is HSE */ + frequency = HSE_VALUE; + } + + else + { + /* In Case the CKPER is disabled*/ + frequency = 0; + } + + break; + } + default : + { + frequency = 0U; + break; + } + } + break; +#endif /* LPTIM4 */ + +#if defined(LPTIM5) + case RCC_PERIPHCLK_LPTIM5: + /* Get the current LPTIM5 source */ + srcclk = __HAL_RCC_GET_LPTIM5_SOURCE(); + + switch (srcclk) + { + case RCC_LPTIM5CLKSOURCE_PCLK3: + { + frequency = HAL_RCC_GetPCLK3Freq(); + break; + } + case RCC_LPTIM5CLKSOURCE_PLL2P: + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_P_Frequency; + break; + } + case RCC_LPTIM5CLKSOURCE_PLL3R: + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_R_Frequency; + break; + } + case RCC_LPTIM5CLKSOURCE_LSE: + { + if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) + { + frequency = LSE_VALUE; + } + else + { + frequency = 0; + } + break; + } + case RCC_LPTIM5CLKSOURCE_LSI: + { + if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSIRDY)) + { + frequency = LSI_VALUE; + } + else + { + frequency = 0; + } + break; + } + case RCC_LPTIM5CLKSOURCE_CLKP: /* CLKP is the clock source for LPTIM5 */ + { + ckpclocksource = __HAL_RCC_GET_CLKP_SOURCE(); + + if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY) && (ckpclocksource == RCC_CLKPSOURCE_HSI)) + { + /* In Case the CKPER Source is HSI */ + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + + else if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY) && (ckpclocksource == RCC_CLKPSOURCE_CSI)) + { + /* In Case the CKPER Source is CSI */ + frequency = CSI_VALUE; + } + + else if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY) && (ckpclocksource == RCC_CLKPSOURCE_HSE)) + { + /* In Case the CKPER Source is HSE */ + frequency = HSE_VALUE; + } + + else + { + /* In Case the CKPER is disabled*/ + frequency = 0; + } + + break; + } + default : + { + frequency = 0U; + break; + } + } + break; +#endif /* LPTIM5 */ + +#if defined(LPTIM6) + case RCC_PERIPHCLK_LPTIM6: + /* Get the current LPTIM6 source */ + srcclk = __HAL_RCC_GET_LPTIM6_SOURCE(); + + switch (srcclk) + { + case RCC_LPTIM6CLKSOURCE_PCLK3: + { + frequency = HAL_RCC_GetPCLK3Freq(); + break; + } + case RCC_LPTIM6CLKSOURCE_PLL2P: + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_P_Frequency; + break; + } + case RCC_LPTIM6CLKSOURCE_PLL3R: + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_R_Frequency; + break; + } + case RCC_LPTIM6CLKSOURCE_LSE: + { + if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) + { + frequency = LSE_VALUE; + } + else + { + frequency = 0; + } + break; + } + case RCC_LPTIM6CLKSOURCE_LSI: + { + if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSIRDY)) + { + frequency = LSI_VALUE; + } + else + { + frequency = 0; + } + break; + } + case RCC_LPTIM6CLKSOURCE_CLKP: /* CLKP is the clock source for LPTIM6 */ + { + ckpclocksource = __HAL_RCC_GET_CLKP_SOURCE(); + + if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY) && (ckpclocksource == RCC_CLKPSOURCE_HSI)) + { + /* In Case the CKPER Source is HSI */ + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + + else if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY) && (ckpclocksource == RCC_CLKPSOURCE_CSI)) + { + /* In Case the CKPER Source is CSI */ + frequency = CSI_VALUE; + } + + else if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY) && (ckpclocksource == RCC_CLKPSOURCE_HSE)) + { + /* In Case the CKPER Source is HSE */ + frequency = HSE_VALUE; + } + + else + { + /* In Case the CKPER is disabled*/ + frequency = 0; + } + + break; + } + default : + { + frequency = 0U; + break; + } + } + break; +#endif /* LPTIM6 */ + + case RCC_PERIPHCLK_FDCAN: + /* Get the current FDCAN kernel source */ + srcclk = __HAL_RCC_GET_FDCAN_SOURCE(); + + if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)) && (srcclk == RCC_FDCANCLKSOURCE_HSE)) + { + frequency = HSE_VALUE; + } + else if (srcclk == RCC_FDCANCLKSOURCE_PLL1Q) + { + HAL_RCCEx_GetPLL1ClockFreq(&pll1_clocks); + frequency = pll1_clocks.PLL1_Q_Frequency; + } + else if (srcclk == RCC_FDCANCLKSOURCE_PLL2Q) + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_Q_Frequency; + } + /* Clock not enabled for FDCAN */ + else + { + frequency = 0U; + } + break; + + case RCC_PERIPHCLK_SPI1: + /* Get the current SPI1 kernel source */ + srcclk = __HAL_RCC_GET_SPI1_SOURCE(); + switch (srcclk) + { + case RCC_SPI1CLKSOURCE_PLL1Q: + { + HAL_RCCEx_GetPLL1ClockFreq(&pll1_clocks); + frequency = pll1_clocks.PLL1_Q_Frequency; + break; + } + case RCC_SPI1CLKSOURCE_PLL2P: + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_P_Frequency; + break; + } +#if defined(RCC_SPI1CLKSOURCE_PLL3P) + case RCC_SPI1CLKSOURCE_PLL3P: + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_P_Frequency; + break; + } +#endif /* RCC_SPI1CLKSOURCE_PLL3P */ + case RCC_SPI1CLKSOURCE_PIN: + { + frequency = EXTERNAL_CLOCK_VALUE; + break; + } + case RCC_SPI1CLKSOURCE_CLKP: + { + ckpclocksource = __HAL_RCC_GET_CLKP_SOURCE(); + + if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY) && (ckpclocksource == RCC_CLKPSOURCE_HSI)) + { + /* In Case the CKPER Source is HSI */ + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + + else if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY) && (ckpclocksource == RCC_CLKPSOURCE_CSI)) + { + /* In Case the CKPER Source is CSI */ + frequency = CSI_VALUE; + } + + else if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY) && (ckpclocksource == RCC_CLKPSOURCE_HSE)) + { + /* In Case the CKPER Source is HSE */ + frequency = HSE_VALUE; + } + + else + { + /* In Case the CKPER is disabled*/ + frequency = 0; + } + + break; + } + default: + { + frequency = 0; + break; + } + } + break; + + case RCC_PERIPHCLK_SPI2: + /* Get the current SPI2 kernel source */ + srcclk = __HAL_RCC_GET_SPI2_SOURCE(); + switch (srcclk) + { + case RCC_SPI2CLKSOURCE_PLL1Q: + { + HAL_RCCEx_GetPLL1ClockFreq(&pll1_clocks); + frequency = pll1_clocks.PLL1_Q_Frequency; + break; + } + case RCC_SPI2CLKSOURCE_PLL2P: + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_P_Frequency; + break; + } +#if defined(RCC_SPI2CLKSOURCE_PLL3P) + case RCC_SPI2CLKSOURCE_PLL3P: + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_P_Frequency; + break; + } +#endif /* RCC_SPI2CLKSOURCE_PLL3P */ + case RCC_SPI2CLKSOURCE_PIN: + { + frequency = EXTERNAL_CLOCK_VALUE; + break; + } + case RCC_SPI2CLKSOURCE_CLKP: + { + ckpclocksource = __HAL_RCC_GET_CLKP_SOURCE(); + + if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY) && (ckpclocksource == RCC_CLKPSOURCE_HSI)) + { + /* In Case the CKPER Source is HSI */ + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + + else if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY) && (ckpclocksource == RCC_CLKPSOURCE_CSI)) + { + /* In Case the CKPER Source is CSI */ + frequency = CSI_VALUE; + } + + else if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY) && (ckpclocksource == RCC_CLKPSOURCE_HSE)) + { + /* In Case the CKPER Source is HSE */ + frequency = HSE_VALUE; + } + + else + { + /* In Case the CKPER is disabled*/ + frequency = 0; + } + + break; + } + default: + { + frequency = 0; + break; + } + } + break; + + case RCC_PERIPHCLK_SPI3: + /* Get the current SPI3 kernel source */ + srcclk = __HAL_RCC_GET_SPI3_SOURCE(); + switch (srcclk) + { + case RCC_SPI3CLKSOURCE_PLL1Q: + { + HAL_RCCEx_GetPLL1ClockFreq(&pll1_clocks); + frequency = pll1_clocks.PLL1_Q_Frequency; + break; + } + case RCC_SPI3CLKSOURCE_PLL2P: + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_P_Frequency; + break; + } +#if defined(RCC_SPI3CLKSOURCE_PLL3P) + case RCC_SPI3CLKSOURCE_PLL3P: + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_P_Frequency; + break; + } +#endif /* RCC_SPI3CLKSOURCE_PLL3P */ + case RCC_SPI3CLKSOURCE_PIN: + { + frequency = EXTERNAL_CLOCK_VALUE; + break; + } + case RCC_SPI3CLKSOURCE_CLKP: + { + ckpclocksource = __HAL_RCC_GET_CLKP_SOURCE(); + + if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY) && (ckpclocksource == RCC_CLKPSOURCE_HSI)) + { + /* In Case the CKPER Source is HSI */ + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + + else if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY) && (ckpclocksource == RCC_CLKPSOURCE_CSI)) + { + /* In Case the CKPER Source is CSI */ + frequency = CSI_VALUE; + } + + else if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY) && (ckpclocksource == RCC_CLKPSOURCE_HSE)) + { + /* In Case the CKPER Source is HSE */ + frequency = HSE_VALUE; + } + + else + { + /* In Case the CKPER is disabled*/ + frequency = 0; + } + + break; + } + default: + { + frequency = 0; + break; + } + } + break; + +#if defined(SPI4) + case RCC_PERIPHCLK_SPI4: + /* Get the current SPI4 kernel source */ + srcclk = __HAL_RCC_GET_SPI4_SOURCE(); + + if (srcclk == RCC_SPI4CLKSOURCE_PCLK2) + { + frequency = HAL_RCC_GetPCLK2Freq(); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL2RDY)) && (srcclk == RCC_SPI4CLKSOURCE_PLL2Q)) + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_Q_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3RDY)) && (srcclk == RCC_SPI4CLKSOURCE_PLL3Q)) + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_Q_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_SPI4CLKSOURCE_HSI)) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY)) && (srcclk == RCC_SPI4CLKSOURCE_CSI)) + { + frequency = CSI_VALUE; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)) && (srcclk == RCC_SPI4CLKSOURCE_HSE)) + { + frequency = HSE_VALUE; + } + /* Clock not enabled for SPI4 */ + else + { + frequency = 0U; + } + + break; +#endif /* SPI4 */ + +#if defined(SPI5) + case RCC_PERIPHCLK_SPI5: + /* Get the current SPI5 kernel source */ + srcclk = __HAL_RCC_GET_SPI5_SOURCE(); + + if (srcclk == RCC_SPI5CLKSOURCE_PCLK3) + { + frequency = HAL_RCC_GetPCLK3Freq(); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL2RDY)) && (srcclk == RCC_SPI5CLKSOURCE_PLL2Q)) + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_Q_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3RDY)) && (srcclk == RCC_SPI5CLKSOURCE_PLL3Q)) + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_Q_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_SPI5CLKSOURCE_HSI)) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY)) && (srcclk == RCC_SPI5CLKSOURCE_CSI)) + { + frequency = CSI_VALUE; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)) && (srcclk == RCC_SPI5CLKSOURCE_HSE)) + { + frequency = HSE_VALUE; + } + /* Clock not enabled for SPI5 */ + else + { + frequency = 0U; + } + + break; +#endif /* SPI5 */ + +#if defined(SPI6) + case RCC_PERIPHCLK_SPI6: + /* Get the current SPI6 kernel source */ + srcclk = __HAL_RCC_GET_SPI6_SOURCE(); + + if (srcclk == RCC_SPI6CLKSOURCE_PCLK2) + { + frequency = HAL_RCC_GetPCLK2Freq(); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL2RDY)) && (srcclk == RCC_SPI6CLKSOURCE_PLL2Q)) + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_Q_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3RDY)) && (srcclk == RCC_SPI6CLKSOURCE_PLL3Q)) + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_Q_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_SPI6CLKSOURCE_HSI)) + { + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY)) && (srcclk == RCC_SPI6CLKSOURCE_CSI)) + { + frequency = CSI_VALUE; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)) && (srcclk == RCC_SPI6CLKSOURCE_HSE)) + { + frequency = HSE_VALUE; + } + /* Clock not enabled for SPI6 */ + else + { + frequency = 0U; + } + + break; +#endif /* SPI6 */ + +#if defined(OCTOSPI1) + case RCC_PERIPHCLK_OSPI: + /* Get the current OSPI kernel source */ + srcclk = __HAL_RCC_GET_OSPI_SOURCE(); + + switch (srcclk) + { + case RCC_OSPICLKSOURCE_HCLK: + { + frequency = HAL_RCC_GetHCLKFreq(); + break; + } + case RCC_OSPICLKSOURCE_PLL1Q: + { + HAL_RCCEx_GetPLL1ClockFreq(&pll1_clocks); + frequency = pll1_clocks.PLL1_Q_Frequency; + break; + } + case RCC_OSPICLKSOURCE_PLL2R: + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_R_Frequency; + break; + } + case RCC_OSPICLKSOURCE_CLKP: + { + ckpclocksource = __HAL_RCC_GET_CLKP_SOURCE(); + + if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY) && (ckpclocksource == RCC_CLKPSOURCE_HSI)) + { + /* In Case the CKPER Source is HSI */ + frequency = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos)); + } + + else if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY) && (ckpclocksource == RCC_CLKPSOURCE_CSI)) + { + /* In Case the CKPER Source is CSI */ + frequency = CSI_VALUE; + } + + else if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY) && (ckpclocksource == RCC_CLKPSOURCE_HSE)) + { + /* In Case the CKPER Source is HSE */ + frequency = HSE_VALUE; + } + + else + { + /* In Case the CKPER is disabled*/ + frequency = 0U; + } + + break; + } + default: + { + frequency = 0U; + break; + } + } + break; +#endif /* OCTOSPI1*/ + +#if defined(CEC) + case RCC_PERIPHCLK_CEC: + /* Get the current CEC source */ + srcclk = __HAL_RCC_GET_CEC_SOURCE(); + + if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_CECCLKSOURCE_LSE)) + { + frequency = LSE_VALUE; + } + else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSIRDY)) && (srcclk == RCC_CECCLKSOURCE_LSI)) + { + frequency = LSI_VALUE; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_CSIRDY)) && (srcclk == RCC_CECCLKSOURCE_CSI_DIV122)) + { + frequency = CSI_VALUE / 122U; + } + + /* Clock not enabled for CEC */ + else + { + frequency = 0U; + } + break; +#endif /* CEC */ + + case RCC_PERIPHCLK_RNG: + /* Get the current RNG source */ + srcclk = __HAL_RCC_GET_RNG_SOURCE(); + + if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSI48RDY)) && (srcclk == RCC_RNGCLKSOURCE_HSI48)) + { + frequency = HSI48_VALUE; + } + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL1RDY)) && (srcclk == RCC_RNGCLKSOURCE_PLL1Q)) + { + HAL_RCCEx_GetPLL1ClockFreq(&pll1_clocks); + frequency = pll1_clocks.PLL1_Q_Frequency; + } + else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_RNGCLKSOURCE_LSE)) + { + frequency = LSE_VALUE; + } + else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSIRDY)) && (srcclk == RCC_RNGCLKSOURCE_LSI)) + { + frequency = LSI_VALUE; + } + + /* Clock not enabled for RNG */ + else + { + frequency = 0U; + } + break; + + case RCC_PERIPHCLK_USB: + /* Get the current USB kernel source */ + srcclk = __HAL_RCC_GET_USB_SOURCE(); + + if (srcclk == RCC_USBCLKSOURCE_PLL1Q) + { + HAL_RCCEx_GetPLL1ClockFreq(&pll1_clocks); + frequency = pll1_clocks.PLL1_Q_Frequency; + break; + } +#if defined(RCC_USBCLKSOURCE_PLL3Q) + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3RDY)) && (srcclk == RCC_USBCLKSOURCE_PLL3Q)) + { + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + frequency = pll3_clocks.PLL3_Q_Frequency; + } +#else + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL2RDY)) && (srcclk == RCC_USBCLKSOURCE_PLL2Q)) + { + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + frequency = pll2_clocks.PLL2_Q_Frequency; + } +#endif /* RCC_USBCLKSOURCE_PLL3 */ + else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSI48RDY)) && (srcclk == RCC_USBCLKSOURCE_HSI48)) + { + frequency = HSI48_VALUE; + } + /* Clock not enabled for USB */ + else + { + frequency = 0U; + } + + break; + + + default: + frequency = 0U; + break; + } + } + + return (frequency); +} + +/** + * @} + */ + +/** @defgroup RCCEx_Exported_Functions_Group2 Extended Clock management functions + * @brief Extended Clock management functions + * +@verbatim + =============================================================================== + ##### Extended clock management functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the + activation or deactivation of PLL2, PLL3, LSE CSS, + Low speed clock output and clock after wake-up from STOP mode. +@endverbatim + * @{ + */ + +/** + * @brief Initialize and Enable the PLL2 according to the specified + * parameters in the RCC_PLL2InitTypeDef. + * @param pPLL2Init pointer to an RCC_PLL2InitTypeDef structure that + * contains the configuration information for the PLL2 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RCCEx_EnablePLL2(RCC_PLL2InitTypeDef *pPLL2Init) +{ + uint32_t tickstart; + HAL_StatusTypeDef status = HAL_OK; + + /* check for PLL2 Parameters used to output PLL2CLK */ + assert_param(IS_RCC_PLL2_SOURCE(pPLL2Init->PLL2Source)); + assert_param(IS_RCC_PLL2_DIVM_VALUE(pPLL2Init->PLL2M)); + assert_param(IS_RCC_PLL2_MULN_VALUE(pPLL2Init->PLL2N)); + assert_param(IS_RCC_PLL2_DIVP_VALUE(pPLL2Init->PLL2P)); + assert_param(IS_RCC_PLL2_DIVQ_VALUE(pPLL2Init->PLL2Q)); + assert_param(IS_RCC_PLL2_DIVR_VALUE(pPLL2Init->PLL2R)); + assert_param(IS_RCC_PLL2_CLOCKOUT_VALUE(pPLL2Init->PLL2ClockOut)); + assert_param(IS_RCC_PLL2_VCIRGE_VALUE(pPLL2Init->PLL2RGE)); + assert_param(IS_RCC_PLL2_VCORGE_VALUE(pPLL2Init->PLL2VCOSEL)); + assert_param(IS_RCC_PLL2_FRACN_VALUE(pPLL2Init->PLL2FRACN)); + + /* Disable the PLL2 */ + __HAL_RCC_PLL2_DISABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till PLL2 is ready to be updated */ + while (READ_BIT(RCC->CR, RCC_CR_PLL2RDY) != 0U) + { + if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE) + { + status = HAL_TIMEOUT; + break; + } + } + + if (status == HAL_OK) + { + /* Make sure PLL2Source is ready */ + status = RCCEx_PLLSource_Enable(pPLL2Init->PLL2Source); + + if (status == HAL_OK) + { + /* Configure the PLL2 clock source, multiplication factor N, */ + /* and division factors M, P, Q and R */ + __HAL_RCC_PLL2_CONFIG(pPLL2Init->PLL2Source, pPLL2Init->PLL2M, pPLL2Init->PLL2N, + pPLL2Init->PLL2P, pPLL2Init->PLL2Q, pPLL2Init->PLL2R); + + /* Disable PLL2FRACN . */ + __HAL_RCC_PLL2_FRACN_DISABLE(); + + /* Configure PLL2 FRACN */ + __HAL_RCC_PLL2_FRACN_CONFIG(pPLL2Init->PLL2FRACN); + + /* Enable PLL2FRACN */ + __HAL_RCC_PLL2_FRACN_ENABLE(); + + /* Select PLL2 input reference frequency range: VCI */ + __HAL_RCC_PLL2_VCIRANGE(pPLL2Init->PLL2RGE); + + /* Select PLL2 output frequency range : VCO */ + __HAL_RCC_PLL2_VCORANGE(pPLL2Init->PLL2VCOSEL); + + /* Configure the PLL2 Clock output(s) */ + __HAL_RCC_PLL2_CLKOUT_ENABLE(pPLL2Init->PLL2ClockOut); + + /* Enable the PLL2 again by setting PLL2ON to 1*/ + __HAL_RCC_PLL2_ENABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till PLL2 is ready */ + while (READ_BIT(RCC->CR, RCC_CR_PLL2RDY) == 0U) + { + if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE) + { + status = HAL_TIMEOUT; + break; + } + } + } + } + + return status; +} + +/** + * @brief Disable PLL2. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RCCEx_DisablePLL2(void) +{ + uint32_t tickstart; + HAL_StatusTypeDef status = HAL_OK; + + /* Disable the PLL2 */ + __HAL_RCC_PLL2_DISABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till PLL2 is disabled */ + while (READ_BIT(RCC->CR, RCC_CR_PLL2RDY) != 0U) + { + if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE) + { + status = HAL_TIMEOUT; + break; + } + } + + /* To save power, disable the PLL2 Source, FRACN and Clock outputs */ + CLEAR_BIT(RCC->PLL2CFGR, RCC_PLL2CFGR_PLL2PEN | RCC_PLL2CFGR_PLL2QEN | RCC_PLL2CFGR_PLL2REN | RCC_PLL2CFGR_PLL2SRC | + RCC_PLL2CFGR_PLL2FRACEN); + + return status; +} + +#if defined(RCC_CR_PLL3ON) +/** + * @brief Initialize and Enable the PLL3 according to the specified + * parameters in the RCC_PLL3InitTypeDef. + * @param pPLL3Init pointer to an RCC_PLL3InitTypeDef structure that + * contains the configuration information for the PLL3 + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_RCCEx_EnablePLL3(RCC_PLL3InitTypeDef *pPLL3Init) +{ + uint32_t tickstart; + HAL_StatusTypeDef status = HAL_OK; + + /* check for PLL3 Parameters used to output PLL3CLK */ + assert_param(IS_RCC_PLL3_SOURCE(pPLL3Init->PLL3Source)); + assert_param(IS_RCC_PLL3_DIVM_VALUE(pPLL3Init->PLL3M)); + assert_param(IS_RCC_PLL3_MULN_VALUE(pPLL3Init->PLL3N)); + assert_param(IS_RCC_PLL3_DIVP_VALUE(pPLL3Init->PLL3P)); + assert_param(IS_RCC_PLL3_DIVQ_VALUE(pPLL3Init->PLL3Q)); + assert_param(IS_RCC_PLL3_DIVR_VALUE(pPLL3Init->PLL3R)); + assert_param(IS_RCC_PLL3_CLOCKOUT_VALUE(pPLL3Init->PLL3ClockOut)); + assert_param(IS_RCC_PLL3_VCIRGE_VALUE(pPLL3Init->PLL3RGE)); + assert_param(IS_RCC_PLL3_VCORGE_VALUE(pPLL3Init->PLL3VCOSEL)); + assert_param(IS_RCC_PLL3_FRACN_VALUE(pPLL3Init->PLL3FRACN)); + + /* Disable the PLL3 */ + __HAL_RCC_PLL3_DISABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till PLL3 is ready to be updated */ + while (READ_BIT(RCC->CR, RCC_CR_PLL3RDY) != 0U) + { + if ((HAL_GetTick() - tickstart) > PLL3_TIMEOUT_VALUE) + { + status = HAL_TIMEOUT; + break; + } + } + + if (status == HAL_OK) + { + /* Make sure PLL3Source is ready */ + status = RCCEx_PLLSource_Enable(pPLL3Init->PLL3Source); + + if (status == HAL_OK) + { + /* Configure the PLL3 clock source, multiplication factor N, */ + /* and division factors M and P */ + __HAL_RCC_PLL3_CONFIG(pPLL3Init->PLL3Source, pPLL3Init->PLL3M, pPLL3Init->PLL3N, pPLL3Init->PLL3P, + pPLL3Init->PLL3Q, pPLL3Init->PLL3R); + + /* Disable PLL3FRACN . */ + __HAL_RCC_PLL3_FRACN_DISABLE(); + + /* Configure PLL3 FRACN */ + __HAL_RCC_PLL3_FRACN_CONFIG(pPLL3Init->PLL3FRACN); + + /* Enable PLL3FRACN . */ + __HAL_RCC_PLL3_FRACN_ENABLE(); + + /* Select PLL3 input reference frequency range: VCI */ + __HAL_RCC_PLL3_VCIRANGE(pPLL3Init->PLL3RGE); + + /* Select PLL3 output frequency range : VCO */ + __HAL_RCC_PLL3_VCORANGE(pPLL3Init->PLL3VCOSEL); + + /* Configure the PLL3 Clock output(s) */ + __HAL_RCC_PLL3_CLKOUT_ENABLE(pPLL3Init->PLL3ClockOut); + + /* Enable the PLL3 again by setting PLL3ON to 1*/ + __HAL_RCC_PLL3_ENABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till PLL3 is ready */ + while (READ_BIT(RCC->CR, RCC_CR_PLL3RDY) == 0U) + { + if ((HAL_GetTick() - tickstart) > PLL3_TIMEOUT_VALUE) + { + status = HAL_TIMEOUT; + break; + } + } + } + } + + return status; +} + + +/** + * @brief Disable PLL3. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_RCCEx_DisablePLL3(void) +{ + uint32_t tickstart; + HAL_StatusTypeDef status = HAL_OK; + + /* Disable the PLL3 */ + __HAL_RCC_PLL3_DISABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till PLL3 is ready */ + while (READ_BIT(RCC->CR, RCC_CR_PLL3RDY) != 0U) + { + if ((HAL_GetTick() - tickstart) > PLL3_TIMEOUT_VALUE) + { + status = HAL_TIMEOUT; + break; + } + } + + /* To save power, disable the PLL3 Source and Clock outputs */ + CLEAR_BIT(RCC->PLL3CFGR, RCC_PLL3CFGR_PLL3PEN | RCC_PLL3CFGR_PLL3QEN | RCC_PLL3CFGR_PLL3REN | RCC_PLL3CFGR_PLL3SRC | + RCC_PLL3CFGR_PLL3FRACEN); + + return status; +} +#endif /* RCC_CR_PLL3ON */ + +/** + * @brief Configure the oscillator clock source for wakeup from Stop and HSE CSS backup clock. + * @param WakeUpClk Wakeup clock + * This parameter can be one of the following values: + * @arg @ref RCC_STOP_WAKEUPCLOCK_HSI HSI oscillator selection + * @arg @ref RCC_STOP_WAKEUPCLOCK_CSI CSI oscillator selection + * @note This function shall not be called after the Clock Security System on HSE has been + * enabled. + * @retval None + */ +void HAL_RCCEx_WakeUpStopCLKConfig(uint32_t WakeUpClk) +{ + assert_param(IS_RCC_STOP_WAKEUPCLOCK(WakeUpClk)); + + __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(WakeUpClk); +} + +/** + * @brief Configure the oscillator Kernel clock source for wakeup from Stop + * @param WakeUpClk: Kernel Wakeup clock + * This parameter can be one of the following values: + * @arg RCC_STOP_KERWAKEUPCLOCK_HSI: HSI oscillator selection + * @arg RCC_STOP_KERWAKEUPCLOCK_CSI: CSI oscillator selection + * @retval None + */ +void HAL_RCCEx_KerWakeUpStopCLKConfig(uint32_t WakeUpClk) +{ + assert_param(IS_RCC_STOP_KERWAKEUPCLOCK(WakeUpClk)); + + __HAL_RCC_KERWAKEUPSTOP_CLK_CONFIG(WakeUpClk); +} + +/** + * @brief Enable the LSE Clock Security System. + * @note Prior to enable the LSE Clock Security System, LSE oscillator is to be enabled + * with HAL_RCC_OscConfig() and the LSE oscillator clock is to be selected as RTC + * clock with HAL_RCCEx_PeriphCLKConfig(). + * @retval None + */ +void HAL_RCCEx_EnableLSECSS(void) +{ + SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON); +} + +/** + * @brief Disable the LSE Clock Security System. + * @note LSE Clock Security System can only be disabled after a LSE failure detection. + * @retval None + */ +void HAL_RCCEx_DisableLSECSS(void) +{ + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSECSSON); +} + +/** + * @brief Handle the RCC LSE Clock Security System interrupt request. + * @retval None + */ +void HAL_RCCEx_LSECSS_IRQHandler(void) +{ + if (READ_BIT(RCC->BDCR, RCC_BDCR_LSECSSD) != 0U) + { + /* RCC LSE Clock Security System interrupt user callback */ + HAL_RCCEx_LSECSS_Callback(); + } +} + +/** + * @brief RCCEx LSE Clock Security System interrupt callback. + * @retval none + */ +__weak void HAL_RCCEx_LSECSS_Callback(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the @ref HAL_RCCEx_LSECSS_Callback should be implemented in the user file + */ +} + +/** + * @brief Select the Low Speed Microcontroller Clock source to output on LSCO pin (PB2). + * @param LSCOSource specifies the Low Speed clock source to output. + * This parameter can be one of the following values: + * @arg @ref RCC_LSCOSOURCE_LSI LSI clock selected as LSCO source + * @arg @ref RCC_LSCOSOURCE_LSE LSE clock selected as LSCO source + * @retval None + */ +void HAL_RCCEx_EnableLSCO(uint32_t LSCOSource) +{ + FlagStatus backupchanged = RESET; + + /* Check the parameters */ + assert_param(IS_RCC_LSCOSOURCE(LSCOSource)); + + /* Update LSCOSEL clock source in Backup Domain control register */ + if (HAL_IS_BIT_CLR(PWR->DBPCR, PWR_DBPCR_DBP)) + { + HAL_PWR_EnableBkUpAccess(); + backupchanged = SET; + } + + MODIFY_REG(RCC->BDCR, RCC_BDCR_LSCOSEL | RCC_BDCR_LSCOEN, LSCOSource | RCC_BDCR_LSCOEN); + + if (backupchanged == SET) + { + HAL_PWR_DisableBkUpAccess(); + } +} + +/** + * @brief Disable the Low Speed Microcontroller Clock Output. + * @retval None + */ +void HAL_RCCEx_DisableLSCO(void) +{ + FlagStatus backupchanged = RESET; + + /* Update LSCOEN bit in Backup Domain control register */ + if (HAL_IS_BIT_CLR(PWR->DBPCR, PWR_DBPCR_DBP)) + { + /* Enable access to the backup domain */ + HAL_PWR_EnableBkUpAccess(); + backupchanged = SET; + } + + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSCOEN); + + /* Restore previous configuration */ + if (backupchanged == SET) + { + /* Disable access to the backup domain */ + HAL_PWR_DisableBkUpAccess(); + } +} + +/** + * @} + */ + +#if defined(CRS) + +/** @defgroup RCCEx_Exported_Functions_Group3 Extended Clock Recovery System Control functions + * @brief Extended Clock Recovery System Control functions + * +@verbatim + =============================================================================== + ##### Extended Clock Recovery System Control functions ##### + =============================================================================== + [..] + For devices with Clock Recovery System feature (CRS), RCC Extension HAL driver can be used as follows: + + (#) In System clock config, HSI48 needs to be enabled + + (#) Enable CRS clock in IP MSP init which will use CRS functions + + (#) Call CRS functions as follows: + (##) Prepare synchronization configuration necessary for HSI48 calibration + (+++) Default values can be set for frequency Error Measurement (reload and error limit) + and also HSI48 oscillator smooth trimming. + (+++) Macro __HAL_RCC_CRS_RELOADVALUE_CALCULATE can be also used to calculate + directly reload value with target and synchronization frequencies values + (##) Call function HAL_RCCEx_CRSConfig which + (+++) Resets CRS registers to their default values. + (+++) Configures CRS registers with synchronization configuration + (+++) Enables automatic calibration and frequency error counter feature + Note: When using USB LPM (Link Power Management) and the device is in Sleep mode, the + periodic USB SOF will not be generated by the host. No SYNC signal will therefore be + provided to the CRS to calibrate the HSI48 on the run. To guarantee the required clock + precision after waking up from Sleep mode, the LSE or reference clock on the GPIOs + should be used as SYNC signal. + + (##) A polling function is provided to wait for complete synchronization + (+++) Call function HAL_RCCEx_CRSWaitSynchronization() + (+++) According to CRS status, user can decide to adjust again the calibration or continue + application if synchronization is OK + + (#) User can retrieve information related to synchronization in calling function + HAL_RCCEx_CRSGetSynchronizationInfo() + + (#) Regarding synchronization status and synchronization information, user can try a new calibration + in changing synchronization configuration and call again HAL_RCCEx_CRSConfig. + Note: When the SYNC event is detected during the downcounting phase (before reaching the zero value), + it means that the actual frequency is lower than the target (and so, that the TRIM value should be + incremented), while when it is detected during the upcounting phase it means that the actual frequency + is higher (and that the TRIM value should be decremented). + + (#) In interrupt mode, user can resort to the available macros (__HAL_RCC_CRS_XXX_IT). Interrupts will go + through CRS Handler (CRS_IRQn/CRS_IRQHandler) + (++) Call function HAL_RCCEx_CRSConfig() + (++) Enable CRS_IRQn (thanks to NVIC functions) + (++) Enable CRS interrupt (__HAL_RCC_CRS_ENABLE_IT) + (++) Implement CRS status management in the following user callbacks called from + HAL_RCCEx_CRS_IRQHandler(): + (+++) HAL_RCCEx_CRS_SyncOkCallback() + (+++) HAL_RCCEx_CRS_SyncWarnCallback() + (+++) HAL_RCCEx_CRS_ExpectedSyncCallback() + (+++) HAL_RCCEx_CRS_ErrorCallback() + + (#) To force a SYNC EVENT, user can use the function HAL_RCCEx_CRSSoftwareSynchronizationGenerate(). + This function can be called before calling HAL_RCCEx_CRSConfig (for instance in Systick handler) + +@endverbatim + * @{ + */ + +/** + * @brief Start automatic synchronization for polling mode + * @param pInit Pointer on RCC_CRSInitTypeDef structure + * @retval None + */ +void HAL_RCCEx_CRSConfig(const RCC_CRSInitTypeDef *pInit) +{ + uint32_t value; + + /* Check the parameters */ + assert_param(IS_RCC_CRS_SYNC_DIV(pInit->Prescaler)); + assert_param(IS_RCC_CRS_SYNC_SOURCE(pInit->Source)); + assert_param(IS_RCC_CRS_SYNC_POLARITY(pInit->Polarity)); + assert_param(IS_RCC_CRS_RELOADVALUE(pInit->ReloadValue)); + assert_param(IS_RCC_CRS_ERRORLIMIT(pInit->ErrorLimitValue)); + assert_param(IS_RCC_CRS_HSI48CALIBRATION(pInit->HSI48CalibrationValue)); + + /* CONFIGURATION */ + + /* Before configuration, reset CRS registers to their default values*/ + __HAL_RCC_CRS_FORCE_RESET(); + __HAL_RCC_CRS_RELEASE_RESET(); + + /* Set the SYNCDIV[2:0] bits according to Prescaler value */ + /* Set the SYNCSRC[1:0] bits according to Source value */ + /* Set the SYNCSPOL bit according to Polarity value */ + value = (pInit->Prescaler | pInit->Source | pInit->Polarity); + /* Set the RELOAD[15:0] bits according to ReloadValue value */ + value |= pInit->ReloadValue; + /* Set the FELIM[7:0] bits according to ErrorLimitValue value */ + value |= (pInit->ErrorLimitValue << CRS_CFGR_FELIM_Pos); + WRITE_REG(CRS->CFGR, value); + + /* Adjust HSI48 oscillator smooth trimming */ + /* Set the TRIM[5:0] bits according to RCC_CRS_HSI48CalibrationValue value */ + MODIFY_REG(CRS->CR, CRS_CR_TRIM, (pInit->HSI48CalibrationValue << CRS_CR_TRIM_Pos)); + + /* START AUTOMATIC SYNCHRONIZATION*/ + + /* Enable Automatic trimming & Frequency error counter */ + SET_BIT(CRS->CR, CRS_CR_AUTOTRIMEN | CRS_CR_CEN); +} + +/** + * @brief Generate the software synchronization event + * @retval None + */ +void HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void) +{ + SET_BIT(CRS->CR, CRS_CR_SWSYNC); +} + +/** + * @brief Return synchronization info + * @param pSynchroInfo Pointer on RCC_CRSSynchroInfoTypeDef structure + * @retval None + */ +void HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef *pSynchroInfo) +{ + /* Check the parameter */ + assert_param(pSynchroInfo != (void *)NULL); + + /* Get the reload value */ + pSynchroInfo->ReloadValue = (uint32_t)(READ_BIT(CRS->CFGR, CRS_CFGR_RELOAD)); + + /* Get HSI48 oscillator smooth trimming */ + pSynchroInfo->HSI48CalibrationValue = (uint32_t)(READ_BIT(CRS->CR, CRS_CR_TRIM) >> CRS_CR_TRIM_Pos); + + /* Get Frequency error capture */ + pSynchroInfo->FreqErrorCapture = (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FECAP) >> CRS_ISR_FECAP_Pos); + + /* Get Frequency error direction */ + pSynchroInfo->FreqErrorDirection = (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FEDIR)); +} + +/** + * @brief Wait for CRS Synchronization status. + * @param Timeout Duration of the timeout + * @note Timeout is based on the maximum time to receive a SYNC event based on synchronization + * frequency. + * @note If Timeout set to HAL_MAX_DELAY, HAL_TIMEOUT will be never returned. + * @retval Combination of Synchronization status + * This parameter can be a combination of the following values: + * @arg @ref RCC_CRS_TIMEOUT + * @arg @ref RCC_CRS_SYNCOK + * @arg @ref RCC_CRS_SYNCWARN + * @arg @ref RCC_CRS_SYNCERR + * @arg @ref RCC_CRS_SYNCMISS + * @arg @ref RCC_CRS_TRIMOVF + */ +uint32_t HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout) +{ + uint32_t crsstatus = RCC_CRS_NONE; + uint32_t tickstart; + + /* Get timeout */ + tickstart = HAL_GetTick(); + + /* Wait for CRS flag or timeout detection */ + do + { + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + crsstatus = RCC_CRS_TIMEOUT; + } + } + /* Check CRS SYNCOK flag */ + if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCOK)) + { + /* CRS SYNC event OK */ + crsstatus |= RCC_CRS_SYNCOK; + + /* Clear CRS SYNC event OK bit */ + __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCOK); + } + + /* Check CRS SYNCWARN flag */ + if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCWARN)) + { + /* CRS SYNC warning */ + crsstatus |= RCC_CRS_SYNCWARN; + + /* Clear CRS SYNCWARN bit */ + __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCWARN); + } + + /* Check CRS TRIM overflow flag */ + if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_TRIMOVF)) + { + /* CRS SYNC Error */ + crsstatus |= RCC_CRS_TRIMOVF; + + /* Clear CRS Error bit */ + __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_TRIMOVF); + } + + /* Check CRS Error flag */ + if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCERR)) + { + /* CRS SYNC Error */ + crsstatus |= RCC_CRS_SYNCERR; + + /* Clear CRS Error bit */ + __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCERR); + } + + /* Check CRS SYNC Missed flag */ + if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCMISS)) + { + /* CRS SYNC Missed */ + crsstatus |= RCC_CRS_SYNCMISS; + + /* Clear CRS SYNC Missed bit */ + __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCMISS); + } + + /* Check CRS Expected SYNC flag */ + if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_ESYNC)) + { + /* frequency error counter reached a zero value */ + __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_ESYNC); + } + } while (RCC_CRS_NONE == crsstatus); + + return crsstatus; +} + +/** + * @brief Handle the Clock Recovery System interrupt request. + * @retval None + */ +void HAL_RCCEx_CRS_IRQHandler(void) +{ + uint32_t crserror = RCC_CRS_NONE; + /* Get current IT flags and IT sources values */ + uint32_t itflags = READ_REG(CRS->ISR); + uint32_t itsources = READ_REG(CRS->CR); + + /* Check CRS SYNCOK flag */ + if (((itflags & RCC_CRS_FLAG_SYNCOK) != 0U) && ((itsources & RCC_CRS_IT_SYNCOK) != 0U)) + { + /* Clear CRS SYNC event OK flag */ + WRITE_REG(CRS->ICR, CRS_ICR_SYNCOKC); + + /* user callback */ + HAL_RCCEx_CRS_SyncOkCallback(); + } + /* Check CRS SYNCWARN flag */ + else if (((itflags & RCC_CRS_FLAG_SYNCWARN) != 0U) && ((itsources & RCC_CRS_IT_SYNCWARN) != 0U)) + { + /* Clear CRS SYNCWARN flag */ + WRITE_REG(CRS->ICR, CRS_ICR_SYNCWARNC); + + /* user callback */ + HAL_RCCEx_CRS_SyncWarnCallback(); + } + /* Check CRS Expected SYNC flag */ + else if (((itflags & RCC_CRS_FLAG_ESYNC) != 0U) && ((itsources & RCC_CRS_IT_ESYNC) != 0U)) + { + /* frequency error counter reached a zero value */ + WRITE_REG(CRS->ICR, CRS_ICR_ESYNCC); + + /* user callback */ + HAL_RCCEx_CRS_ExpectedSyncCallback(); + } + /* Check CRS Error flags */ + else + { + if (((itflags & RCC_CRS_FLAG_ERR) != 0U) && ((itsources & RCC_CRS_IT_ERR) != 0U)) + { + if ((itflags & RCC_CRS_FLAG_SYNCERR) != 0U) + { + crserror |= RCC_CRS_SYNCERR; + } + if ((itflags & RCC_CRS_FLAG_SYNCMISS) != 0U) + { + crserror |= RCC_CRS_SYNCMISS; + } + if ((itflags & RCC_CRS_FLAG_TRIMOVF) != 0U) + { + crserror |= RCC_CRS_TRIMOVF; + } + + /* Clear CRS Error flags */ + WRITE_REG(CRS->ICR, CRS_ICR_ERRC); + + /* user error callback */ + HAL_RCCEx_CRS_ErrorCallback(crserror); + } + } +} + +/** + * @brief RCCEx Clock Recovery System SYNCOK interrupt callback. + * @retval none + */ +__weak void HAL_RCCEx_CRS_SyncOkCallback(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the @ref HAL_RCCEx_CRS_SyncOkCallback should be implemented in the user file + */ +} + +/** + * @brief RCCEx Clock Recovery System SYNCWARN interrupt callback. + * @retval none + */ +__weak void HAL_RCCEx_CRS_SyncWarnCallback(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the @ref HAL_RCCEx_CRS_SyncWarnCallback should be implemented in the user file + */ +} + +/** + * @brief RCCEx Clock Recovery System Expected SYNC interrupt callback. + * @retval none + */ +__weak void HAL_RCCEx_CRS_ExpectedSyncCallback(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the @ref HAL_RCCEx_CRS_ExpectedSyncCallback should be implemented in the user file + */ +} + +/** + * @brief RCCEx Clock Recovery System Error interrupt callback. + * @param Error Combination of Error status. + * This parameter can be a combination of the following values: + * @arg @ref RCC_CRS_SYNCERR + * @arg @ref RCC_CRS_SYNCMISS + * @arg @ref RCC_CRS_TRIMOVF + * @retval none + */ +__weak void HAL_RCCEx_CRS_ErrorCallback(uint32_t Error) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(Error); + + /* NOTE : This function should not be modified, when the callback is needed, + the @ref HAL_RCCEx_CRS_ErrorCallback should be implemented in the user file + */ +} + +/** + * @} + */ + +#endif /* CRS */ + +/** + * @} + */ + +/** @addtogroup RCCEx_Private_Functions + * @{ + */ + +/** + * @brief Enable PLLx source clock and check ready flag + * @param PllSource contains the selected PLLx source clock (HSE, HSI or CSI) + * @retval HAL status + */ +static HAL_StatusTypeDef RCCEx_PLLSource_Enable(uint32_t PllSource) +{ + uint32_t tickstart; + HAL_StatusTypeDef status = HAL_OK; + + switch (PllSource) + { + case RCC_PLL1_SOURCE_CSI: + /* Check whether CSI in not ready and enable it */ + if (READ_BIT(RCC->CR, RCC_CR_CSIRDY) == 0U) + { + /* Enable the Internal Low power oscillator (CSI). */ + __HAL_RCC_CSI_ENABLE(); + + /* Get timeout */ + tickstart = HAL_GetTick(); + + /* Wait till CSI is ready */ + while (READ_BIT(RCC->CR, RCC_CR_CSIRDY) == 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_CSI_TIMEOUT_VALUE) + { + status = HAL_TIMEOUT; + break; + } + } + } + break; + + case RCC_PLL1_SOURCE_HSI: + /* Check whether HSI in not ready and enable it */ + if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U) + { + /* Enable the Internal High Speed oscillator (HSI). */ + __HAL_RCC_HSI_ENABLE(); + + /* Get timeout */ + tickstart = HAL_GetTick(); + + /* Wait till HSI is ready */ + while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_HSI_TIMEOUT_VALUE) + { + status = HAL_TIMEOUT; + break; + } + } + } + break; + + case RCC_PLL1_SOURCE_HSE: + /* Check whether HSE in not ready and enable it */ + if (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U) + { + /* Enable the External High Speed oscillator (HSE). */ + SET_BIT(RCC->CR, RCC_CR_HSEON); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till HSE is ready */ + while (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_HSE_TIMEOUT_VALUE) + { + status = HAL_TIMEOUT; + break; + } + } + } + break; + + default: + status = HAL_ERROR; + break; + } + + return status; +} + +/** + * @brief Configure the PLL2 VCI/VCO ranges, multiplication and division factors and its output clock(s) + * @param pll2 pointer to an RCC_PLL2InitTypeDef structure that + * contains the configuration parameters M, N, FRACN, VCI/VCO ranges as well as PLL2 output clocks dividers + * @note PLL2 is temporary disabled to apply new parameters + * @retval HAL status + */ +static HAL_StatusTypeDef RCCEx_PLL2_Config(const RCC_PLL2InitTypeDef *pll2) +{ + + uint32_t tickstart; + assert_param(IS_RCC_PLL2_SOURCE(pll2->PLL2Source)); + assert_param(IS_RCC_PLL2_DIVM_VALUE(pll2->PLL2M)); + assert_param(IS_RCC_PLL2_MULN_VALUE(pll2->PLL2N)); + assert_param(IS_RCC_PLL2_DIVP_VALUE(pll2->PLL2P)); + assert_param(IS_RCC_PLL2_DIVQ_VALUE(pll2->PLL2Q)); + assert_param(IS_RCC_PLL2_DIVR_VALUE(pll2->PLL2R)); + assert_param(IS_RCC_PLL2_CLOCKOUT_VALUE(pll2->PLL2ClockOut)); + assert_param(IS_RCC_PLL2_VCIRGE_VALUE(pll2->PLL2RGE)); + assert_param(IS_RCC_PLL2_VCORGE_VALUE(pll2->PLL2VCOSEL)); + assert_param(IS_RCC_PLL2_FRACN_VALUE(pll2->PLL2FRACN)); + + /* Disable PLL2. */ + __HAL_RCC_PLL2_DISABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till PLL2 is disabled */ + while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) != 0U) + { + if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Configure PLL2 multiplication and division factors. */ + __HAL_RCC_PLL2_CONFIG(pll2->PLL2Source, + pll2->PLL2M, + pll2->PLL2N, + pll2->PLL2P, + pll2->PLL2Q, + pll2->PLL2R); + + /* Select PLL2 input reference frequency range: VCI */ + __HAL_RCC_PLL2_VCIRANGE(pll2->PLL2RGE); + + /* Select PLL2 output frequency range : VCO */ + __HAL_RCC_PLL2_VCORANGE(pll2->PLL2VCOSEL); + + /* Configure the PLL2 Clock output(s) */ + __HAL_RCC_PLL2_CLKOUT_ENABLE(pll2->PLL2ClockOut); + + /* Disable PLL2FRACN . */ + __HAL_RCC_PLL2_FRACN_DISABLE(); + + /* Configures PLL2 clock Fractional Part Of The Multiplication Factor */ + __HAL_RCC_PLL2_FRACN_CONFIG(pll2->PLL2FRACN); + + /* Enable PLL2FRACN . */ + __HAL_RCC_PLL2_FRACN_ENABLE(); + + /* Enable PLL2. */ + __HAL_RCC_PLL2_ENABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till PLL2 is ready */ + while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) == 0U) + { + if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + return HAL_OK; + +} + +#if defined(RCC_CR_PLL3ON) +/** + * @brief Configure the PLL3 VCI/VCO ranges, multiplication and division factors and its output clock(s) + * @param pll3 pointer to an RCC_PLL3InitTypeDef structure that + * contains the configuration parameters M, N, FRACN, VCI/VCO ranges as well as PLL3 output clocks dividers + * @note PLL3 is temporary disabled to apply new parameters + * @retval HAL status. + */ +static HAL_StatusTypeDef RCCEx_PLL3_Config(const RCC_PLL3InitTypeDef *pll3) +{ + + uint32_t tickstart; + assert_param(IS_RCC_PLL3_SOURCE(pll3->PLL3Source)); + assert_param(IS_RCC_PLL3_DIVM_VALUE(pll3->PLL3M)); + assert_param(IS_RCC_PLL3_MULN_VALUE(pll3->PLL3N)); + assert_param(IS_RCC_PLL3_DIVP_VALUE(pll3->PLL3P)); + assert_param(IS_RCC_PLL3_DIVQ_VALUE(pll3->PLL3Q)); + assert_param(IS_RCC_PLL3_DIVR_VALUE(pll3->PLL3R)); + assert_param(IS_RCC_PLL3_CLOCKOUT_VALUE(pll3->PLL3ClockOut)); + assert_param(IS_RCC_PLL3_VCIRGE_VALUE(pll3->PLL3RGE)); + assert_param(IS_RCC_PLL3_VCORGE_VALUE(pll3->PLL3VCOSEL)); + assert_param(IS_RCC_PLL3_FRACN_VALUE(pll3->PLL3FRACN)); + + /* Disable PLL3. */ + __HAL_RCC_PLL3_DISABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till PLL3 is disabled */ + while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL3RDY) != 0U) + { + if ((HAL_GetTick() - tickstart) > PLL3_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Configure PLL3 multiplication and division factors. */ + __HAL_RCC_PLL3_CONFIG(pll3->PLL3Source, + pll3->PLL3M, + pll3->PLL3N, + pll3->PLL3P, + pll3->PLL3Q, + pll3->PLL3R); + + /* Select PLL3 input reference frequency range: VCI */ + __HAL_RCC_PLL3_VCIRANGE(pll3->PLL3RGE) ; + + /* Select PLL3 output frequency range : VCO */ + __HAL_RCC_PLL3_VCORANGE(pll3->PLL3VCOSEL); + + /* Configure the PLL3 Clock output(s) */ + __HAL_RCC_PLL3_CLKOUT_ENABLE(pll3->PLL3ClockOut); + + /* Disable PLL3FRACN . */ + __HAL_RCC_PLL3_FRACN_DISABLE(); + + /* Configures PLL3 clock Fractional Part Of The Multiplication Factor */ + __HAL_RCC_PLL3_FRACN_CONFIG(pll3->PLL3FRACN); + + /* Enable PLL3FRACN . */ + __HAL_RCC_PLL3_FRACN_ENABLE(); + + /* Enable PLL3. */ + __HAL_RCC_PLL3_ENABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till PLL3 is ready */ + while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL3RDY) == 0U) + { + if ((HAL_GetTick() - tickstart) > PLL3_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + return HAL_OK; +} +#endif /* RCC_CR_PLL3ON */ + +/** + * @} + */ + +#endif /* HAL_RCC_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rng.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rng.c new file mode 100644 index 0000000000..6baba1d269 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rng.c @@ -0,0 +1,1027 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_rng.c + * @author MCD Application Team + * @brief RNG HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Random Number Generator (RNG) peripheral: + * + Initialization and configuration functions + * + Peripheral Control functions + * + Peripheral State functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The RNG HAL driver can be used as follows: + + (#) Enable the RNG controller clock using __HAL_RCC_RNG_CLK_ENABLE() macro + in HAL_RNG_MspInit(). + (#) Activate the RNG peripheral using HAL_RNG_Init() function. + (#) Wait until the 32 bit Random Number Generator contains a valid + random data using (polling/interrupt) mode. + (#) Get the 32 bit random number using HAL_RNG_GenerateRandomNumber() function. + + ##### Callback registration ##### + ================================== + + [..] + The compilation define USE_HAL_RNG_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + + [..] + Use Function HAL_RNG_RegisterCallback() to register a user callback. + Function HAL_RNG_RegisterCallback() allows to register following callbacks: + (+) ErrorCallback : RNG Error Callback. + (+) MspInitCallback : RNG MspInit. + (+) MspDeInitCallback : RNG MspDeInit. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + + [..] + Use function HAL_RNG_UnRegisterCallback() to reset a callback to the default + weak (overridden) function. + HAL_RNG_UnRegisterCallback() takes as parameters the HAL peripheral handle, + and the Callback ID. + This function allows to reset following callbacks: + (+) ErrorCallback : RNG Error Callback. + (+) MspInitCallback : RNG MspInit. + (+) MspDeInitCallback : RNG MspDeInit. + + [..] + For specific callback ReadyDataCallback, use dedicated register callbacks: + respectively HAL_RNG_RegisterReadyDataCallback() , HAL_RNG_UnRegisterReadyDataCallback(). + + [..] + By default, after the HAL_RNG_Init() and when the state is HAL_RNG_STATE_RESET + all callbacks are set to the corresponding weak (overridden) functions: + example HAL_RNG_ErrorCallback(). + Exception done for MspInit and MspDeInit functions that are respectively + reset to the legacy weak (overridden) functions in the HAL_RNG_Init() + and HAL_RNG_DeInit() only when these callbacks are null (not registered beforehand). + If not, MspInit or MspDeInit are not null, the HAL_RNG_Init() and HAL_RNG_DeInit() + keep and use the user MspInit/MspDeInit callbacks (registered beforehand). + + [..] + Callbacks can be registered/unregistered in HAL_RNG_STATE_READY state only. + Exception done MspInit/MspDeInit that can be registered/unregistered + in HAL_RNG_STATE_READY or HAL_RNG_STATE_RESET state, thus registered (user) + MspInit/DeInit callbacks can be used during the Init/DeInit. + In that case first register the MspInit/MspDeInit user callbacks + using HAL_RNG_RegisterCallback() before calling HAL_RNG_DeInit() + or HAL_RNG_Init() function. + + [..] + When The compilation define USE_HAL_RNG_REGISTER_CALLBACKS is set to 0 or + not defined, the callback registration feature is not available + and weak (overridden) callbacks are used. + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +#if defined (RNG) + +/** @addtogroup RNG + * @brief RNG HAL module driver. + * @{ + */ + +#ifdef HAL_RNG_MODULE_ENABLED + +/* Private types -------------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup RNG_Private_Constants RNG Private Constants + * @{ + */ +#define RNG_TIMEOUT_VALUE 4U +/** + * @} + */ +/* Private macros ------------------------------------------------------------*/ +/* Private functions prototypes ----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup RNG_Exported_Functions + * @{ + */ + +/** @addtogroup RNG_Exported_Functions_Group1 + * @brief Initialization and configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and configuration functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Initialize the RNG according to the specified parameters + in the RNG_InitTypeDef and create the associated handle + (+) DeInitialize the RNG peripheral + (+) Initialize the RNG MSP + (+) DeInitialize RNG MSP + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the RNG peripheral and creates the associated handle. + * @param hrng pointer to a RNG_HandleTypeDef structure that contains + * the configuration information for RNG. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RNG_Init(RNG_HandleTypeDef *hrng) +{ + uint32_t tickstart; + /* Check the RNG handle allocation */ + if (hrng == NULL) + { + return HAL_ERROR; + } + /* Check the parameters */ + assert_param(IS_RNG_ALL_INSTANCE(hrng->Instance)); + assert_param(IS_RNG_CED(hrng->Init.ClockErrorDetection)); + +#if (USE_HAL_RNG_REGISTER_CALLBACKS == 1) + if (hrng->State == HAL_RNG_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hrng->Lock = HAL_UNLOCKED; + + hrng->ReadyDataCallback = HAL_RNG_ReadyDataCallback; /* Legacy weak ReadyDataCallback */ + hrng->ErrorCallback = HAL_RNG_ErrorCallback; /* Legacy weak ErrorCallback */ + + if (hrng->MspInitCallback == NULL) + { + hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit */ + } + + /* Init the low level hardware */ + hrng->MspInitCallback(hrng); + } +#else + if (hrng->State == HAL_RNG_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hrng->Lock = HAL_UNLOCKED; + + /* Init the low level hardware */ + HAL_RNG_MspInit(hrng); + } +#endif /* USE_HAL_RNG_REGISTER_CALLBACKS */ + + /* Change RNG peripheral state */ + hrng->State = HAL_RNG_STATE_BUSY; + + /* Disable RNG */ + __HAL_RNG_DISABLE(hrng); + + /* Clock Error Detection Configuration when CONDRT bit is set to 1 */ + MODIFY_REG(hrng->Instance->CR, RNG_CR_CED | RNG_CR_CONDRST, hrng->Init.ClockErrorDetection | RNG_CR_CONDRST); + + /* Writing bit CONDRST=0 */ + CLEAR_BIT(hrng->Instance->CR, RNG_CR_CONDRST); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait for conditioning reset process to be completed */ + while (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST)) + { + if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE) + { + /* New check to avoid false timeout detection in case of preemption */ + if (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST)) + { + hrng->State = HAL_RNG_STATE_READY; + hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT; + return HAL_ERROR; + } + } + } + + /* Enable the RNG Peripheral */ + __HAL_RNG_ENABLE(hrng); + + /* verify that no seed error */ + if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET) + { + hrng->State = HAL_RNG_STATE_ERROR; + return HAL_ERROR; + } + /* Get tick */ + tickstart = HAL_GetTick(); + /* Check if data register contains valid random data */ + while (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_SECS) != RESET) + { + if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE) + { + /* New check to avoid false timeout detection in case of preemption */ + if (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_SECS) != RESET) + { + hrng->State = HAL_RNG_STATE_ERROR; + hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT; + return HAL_ERROR; + } + } + } + + /* Initialize the RNG state */ + hrng->State = HAL_RNG_STATE_READY; + + /* Initialise the error code */ + hrng->ErrorCode = HAL_RNG_ERROR_NONE; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief DeInitializes the RNG peripheral. + * @param hrng pointer to a RNG_HandleTypeDef structure that contains + * the configuration information for RNG. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RNG_DeInit(RNG_HandleTypeDef *hrng) +{ + uint32_t tickstart; + + /* Check the RNG handle allocation */ + if (hrng == NULL) + { + return HAL_ERROR; + } + + /* Clear Clock Error Detection bit when CONDRT bit is set to 1 */ + MODIFY_REG(hrng->Instance->CR, RNG_CR_CED | RNG_CR_CONDRST, RNG_CED_ENABLE | RNG_CR_CONDRST); + + /* Writing bit CONDRST=0 */ + CLEAR_BIT(hrng->Instance->CR, RNG_CR_CONDRST); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait for conditioning reset process to be completed */ + while (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST)) + { + if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE) + { + /* New check to avoid false timeout detection in case of preemption */ + if (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST)) + { + hrng->State = HAL_RNG_STATE_READY; + hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT; + /* Process Unlocked */ + __HAL_UNLOCK(hrng); + return HAL_ERROR; + } + } + } + + /* Disable the RNG Peripheral */ + CLEAR_BIT(hrng->Instance->CR, RNG_CR_IE | RNG_CR_RNGEN); + + /* Clear RNG interrupt status flags */ + CLEAR_BIT(hrng->Instance->SR, RNG_SR_CEIS | RNG_SR_SEIS); + +#if (USE_HAL_RNG_REGISTER_CALLBACKS == 1) + if (hrng->MspDeInitCallback == NULL) + { + hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspDeInit */ + } + + /* DeInit the low level hardware */ + hrng->MspDeInitCallback(hrng); +#else + /* DeInit the low level hardware */ + HAL_RNG_MspDeInit(hrng); +#endif /* USE_HAL_RNG_REGISTER_CALLBACKS */ + + /* Update the RNG state */ + hrng->State = HAL_RNG_STATE_RESET; + + /* Initialise the error code */ + hrng->ErrorCode = HAL_RNG_ERROR_NONE; + + /* Release Lock */ + __HAL_UNLOCK(hrng); + + /* Return the function status */ + return HAL_OK; +} + +/** + * @brief Initializes the RNG MSP. + * @param hrng pointer to a RNG_HandleTypeDef structure that contains + * the configuration information for RNG. + * @retval None + */ +__weak void HAL_RNG_MspInit(RNG_HandleTypeDef *hrng) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrng); + /* NOTE : This function should not be modified. When the callback is needed, + function HAL_RNG_MspInit must be implemented in the user file. + */ +} + +/** + * @brief DeInitializes the RNG MSP. + * @param hrng pointer to a RNG_HandleTypeDef structure that contains + * the configuration information for RNG. + * @retval None + */ +__weak void HAL_RNG_MspDeInit(RNG_HandleTypeDef *hrng) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrng); + /* NOTE : This function should not be modified. When the callback is needed, + function HAL_RNG_MspDeInit must be implemented in the user file. + */ +} + +#if (USE_HAL_RNG_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User RNG Callback + * To be used instead of the weak predefined callback + * @param hrng RNG handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_RNG_ERROR_CB_ID Error callback ID + * @arg @ref HAL_RNG_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_RNG_MSPDEINIT_CB_ID MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RNG_RegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID, + pRNG_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + + if (HAL_RNG_STATE_READY == hrng->State) + { + switch (CallbackID) + { + case HAL_RNG_ERROR_CB_ID : + hrng->ErrorCallback = pCallback; + break; + + case HAL_RNG_MSPINIT_CB_ID : + hrng->MspInitCallback = pCallback; + break; + + case HAL_RNG_MSPDEINIT_CB_ID : + hrng->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_RNG_STATE_RESET == hrng->State) + { + switch (CallbackID) + { + case HAL_RNG_MSPINIT_CB_ID : + hrng->MspInitCallback = pCallback; + break; + + case HAL_RNG_MSPDEINIT_CB_ID : + hrng->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister an RNG Callback + * RNG callback is redirected to the weak predefined callback + * @param hrng RNG handle + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_RNG_ERROR_CB_ID Error callback ID + * @arg @ref HAL_RNG_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_RNG_MSPDEINIT_CB_ID MspDeInit callback ID + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RNG_UnRegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + + if (HAL_RNG_STATE_READY == hrng->State) + { + switch (CallbackID) + { + case HAL_RNG_ERROR_CB_ID : + hrng->ErrorCallback = HAL_RNG_ErrorCallback; /* Legacy weak ErrorCallback */ + break; + + case HAL_RNG_MSPINIT_CB_ID : + hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit */ + break; + + case HAL_RNG_MSPDEINIT_CB_ID : + hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspDeInit */ + break; + + default : + /* Update the error code */ + hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_RNG_STATE_RESET == hrng->State) + { + switch (CallbackID) + { + case HAL_RNG_MSPINIT_CB_ID : + hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit */ + break; + + case HAL_RNG_MSPDEINIT_CB_ID : + hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspInit */ + break; + + default : + /* Update the error code */ + hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Register Data Ready RNG Callback + * To be used instead of the weak HAL_RNG_ReadyDataCallback() predefined callback + * @param hrng RNG handle + * @param pCallback pointer to the Data Ready Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RNG_RegisterReadyDataCallback(RNG_HandleTypeDef *hrng, pRNG_ReadyDataCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + /* Process locked */ + __HAL_LOCK(hrng); + + if (HAL_RNG_STATE_READY == hrng->State) + { + hrng->ReadyDataCallback = pCallback; + } + else + { + /* Update the error code */ + hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hrng); + return status; +} + +/** + * @brief UnRegister the Data Ready RNG Callback + * Data Ready RNG Callback is redirected to the weak HAL_RNG_ReadyDataCallback() predefined callback + * @param hrng RNG handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RNG_UnRegisterReadyDataCallback(RNG_HandleTypeDef *hrng) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hrng); + + if (HAL_RNG_STATE_READY == hrng->State) + { + hrng->ReadyDataCallback = HAL_RNG_ReadyDataCallback; /* Legacy weak ReadyDataCallback */ + } + else + { + /* Update the error code */ + hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hrng); + return status; +} + +#endif /* USE_HAL_RNG_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @addtogroup RNG_Exported_Functions_Group2 + * @brief Peripheral Control functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Get the 32 bit Random number + (+) Get the 32 bit Random number with interrupt enabled + (+) Handle RNG interrupt request + +@endverbatim + * @{ + */ + +/** + * @brief Generates a 32-bit random number. + * @note This function checks value of RNG_FLAG_DRDY flag to know if valid + * random number is available in the DR register (RNG_FLAG_DRDY flag set + * whenever a random number is available through the RNG_DR register). + * After transitioning from 0 to 1 (random number available), + * RNG_FLAG_DRDY flag remains high until output buffer becomes empty after reading + * four words from the RNG_DR register, i.e. further function calls + * will immediately return a new u32 random number (additional words are + * available and can be read by the application, till RNG_FLAG_DRDY flag remains high). + * @note When no more random number data is available in DR register, RNG_FLAG_DRDY + * flag is automatically cleared. + * @param hrng pointer to a RNG_HandleTypeDef structure that contains + * the configuration information for RNG. + * @param random32bit pointer to generated random number variable if successful. + * @retval HAL status + */ + +HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef *hrng, uint32_t *random32bit) +{ + uint32_t tickstart; + HAL_StatusTypeDef status = HAL_OK; + + /* Process Locked */ + __HAL_LOCK(hrng); + + /* Check RNG peripheral state */ + if (hrng->State == HAL_RNG_STATE_READY) + { + /* Change RNG peripheral state */ + hrng->State = HAL_RNG_STATE_BUSY; + /* Check if there is a seed error */ + if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET) + { + /* Update the error code */ + hrng->ErrorCode = HAL_RNG_ERROR_SEED; + /* Reset from seed error */ + status = RNG_RecoverSeedError(hrng); + if (status == HAL_ERROR) + { + return status; + } + } + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Check if data register contains valid random data */ + while (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_DRDY) == RESET) + { + if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE) + { + /* New check to avoid false timeout detection in case of preemption */ + if (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_DRDY) == RESET) + { + hrng->State = HAL_RNG_STATE_READY; + hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT; + /* Process Unlocked */ + __HAL_UNLOCK(hrng); + return HAL_ERROR; + } + } + } + + /* Get a 32bit Random number */ + hrng->RandomNumber = hrng->Instance->DR; + /* In case of seed error, the value available in the RNG_DR register must not + be used as it may not have enough entropy */ + if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET) + { + /* Update the error code and status */ + hrng->ErrorCode = HAL_RNG_ERROR_SEED; + status = HAL_ERROR; + /* Clear bit DRDY */ + CLEAR_BIT(hrng->Instance->SR, RNG_FLAG_DRDY); + } + else /* No seed error */ + { + *random32bit = hrng->RandomNumber; + } + hrng->State = HAL_RNG_STATE_READY; + } + else + { + hrng->ErrorCode = HAL_RNG_ERROR_BUSY; + status = HAL_ERROR; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hrng); + + return status; +} + +/** + * @brief Generates a 32-bit random number in interrupt mode. + * @param hrng pointer to a RNG_HandleTypeDef structure that contains + * the configuration information for RNG. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber_IT(RNG_HandleTypeDef *hrng) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process Locked */ + __HAL_LOCK(hrng); + + /* Check RNG peripheral state */ + if (hrng->State == HAL_RNG_STATE_READY) + { + /* Change RNG peripheral state */ + hrng->State = HAL_RNG_STATE_BUSY; + + /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */ + __HAL_RNG_ENABLE_IT(hrng); + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hrng); + + hrng->ErrorCode = HAL_RNG_ERROR_BUSY; + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Handles RNG interrupt request. + * @note In the case of a clock error, the RNG is no more able to generate + * random numbers because the PLL48CLK clock is not correct. User has + * to check that the clock controller is correctly configured to provide + * the RNG clock and clear the CEIS bit using __HAL_RNG_CLEAR_IT(). + * The clock error has no impact on the previously generated + * random numbers, and the RNG_DR register contents can be used. + * @note In the case of a seed error, the generation of random numbers is + * interrupted as long as the SECS bit is '1'. If a number is + * available in the RNG_DR register, it must not be used because it may + * not have enough entropy. In this case, it is recommended to clear the + * SEIS bit using __HAL_RNG_CLEAR_IT(), then disable and enable + * the RNG peripheral to reinitialize and restart the RNG. + * @note User-written HAL_RNG_ErrorCallback() API is called once whether SEIS + * or CEIS are set. + * @param hrng pointer to a RNG_HandleTypeDef structure that contains + * the configuration information for RNG. + * @retval None + + */ +void HAL_RNG_IRQHandler(RNG_HandleTypeDef *hrng) +{ + uint32_t rngclockerror = 0U; + uint32_t itflag = hrng->Instance->SR; + + /* RNG clock error interrupt occurred */ + if ((itflag & RNG_IT_CEI) == RNG_IT_CEI) + { + /* Update the error code */ + hrng->ErrorCode = HAL_RNG_ERROR_CLOCK; + rngclockerror = 1U; + } + else if ((itflag & RNG_IT_SEI) == RNG_IT_SEI) + { + /* Check if Seed Error Current Status (SECS) is set */ + if ((itflag & RNG_FLAG_SECS) != RNG_FLAG_SECS) + { + /* RNG IP performed the reset automatically (auto-reset) */ + /* Clear bit SEIS */ + CLEAR_BIT(hrng->Instance->SR, RNG_IT_SEI); + } + else + { + /* Seed Error has not been recovered : Update the error code */ + hrng->ErrorCode = HAL_RNG_ERROR_SEED; + rngclockerror = 1U; + /* Disable the IT */ + __HAL_RNG_DISABLE_IT(hrng); + } + } + else + { + /* Nothing to do */ + } + + if (rngclockerror == 1U) + { + /* Change RNG peripheral state */ + hrng->State = HAL_RNG_STATE_ERROR; + +#if (USE_HAL_RNG_REGISTER_CALLBACKS == 1) + /* Call registered Error callback */ + hrng->ErrorCallback(hrng); +#else + /* Call legacy weak Error callback */ + HAL_RNG_ErrorCallback(hrng); +#endif /* USE_HAL_RNG_REGISTER_CALLBACKS */ + + /* Clear the clock error flag */ + __HAL_RNG_CLEAR_IT(hrng, RNG_IT_CEI | RNG_IT_SEI); + + return; + } + + /* Check RNG data ready interrupt occurred */ + if ((itflag & RNG_IT_DRDY) == RNG_IT_DRDY) + { + /* Generate random number once, so disable the IT */ + __HAL_RNG_DISABLE_IT(hrng); + + /* Get the 32bit Random number (DRDY flag automatically cleared) */ + hrng->RandomNumber = hrng->Instance->DR; + + if (hrng->State != HAL_RNG_STATE_ERROR) + { + /* Change RNG peripheral state */ + hrng->State = HAL_RNG_STATE_READY; + /* Process Unlocked */ + __HAL_UNLOCK(hrng); + +#if (USE_HAL_RNG_REGISTER_CALLBACKS == 1) + /* Call registered Data Ready callback */ + hrng->ReadyDataCallback(hrng, hrng->RandomNumber); +#else + /* Call legacy weak Data Ready callback */ + HAL_RNG_ReadyDataCallback(hrng, hrng->RandomNumber); +#endif /* USE_HAL_RNG_REGISTER_CALLBACKS */ + } + } +} + +/** + * @brief Read latest generated random number. + * @param hrng pointer to a RNG_HandleTypeDef structure that contains + * the configuration information for RNG. + * @retval random value + */ +uint32_t HAL_RNG_ReadLastRandomNumber(const RNG_HandleTypeDef *hrng) +{ + return (hrng->RandomNumber); +} + +/** + * @brief Data Ready callback in non-blocking mode. + * @note When RNG_FLAG_DRDY flag value is set, first random number has been read + * from DR register in IRQ Handler and is provided as callback parameter. + * Depending on valid data available in the conditioning output buffer, + * additional words can be read by the application from DR register till + * DRDY bit remains high. + * @param hrng pointer to a RNG_HandleTypeDef structure that contains + * the configuration information for RNG. + * @param random32bit generated random number. + * @retval None + */ +__weak void HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef *hrng, uint32_t random32bit) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrng); + UNUSED(random32bit); + /* NOTE : This function should not be modified. When the callback is needed, + function HAL_RNG_ReadyDataCallback must be implemented in the user file. + */ +} + +/** + * @brief RNG error callbacks. + * @param hrng pointer to a RNG_HandleTypeDef structure that contains + * the configuration information for RNG. + * @retval None + */ +__weak void HAL_RNG_ErrorCallback(RNG_HandleTypeDef *hrng) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrng); + /* NOTE : This function should not be modified. When the callback is needed, + function HAL_RNG_ErrorCallback must be implemented in the user file. + */ +} +/** + * @} + */ + + +/** @addtogroup RNG_Exported_Functions_Group3 + * @brief Peripheral State functions + * +@verbatim + =============================================================================== + ##### Peripheral State functions ##### + =============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Returns the RNG state. + * @param hrng pointer to a RNG_HandleTypeDef structure that contains + * the configuration information for RNG. + * @retval HAL state + */ +HAL_RNG_StateTypeDef HAL_RNG_GetState(const RNG_HandleTypeDef *hrng) +{ + return hrng->State; +} + +/** + * @brief Return the RNG handle error code. + * @param hrng: pointer to a RNG_HandleTypeDef structure. + * @retval RNG Error Code + */ +uint32_t HAL_RNG_GetError(const RNG_HandleTypeDef *hrng) +{ + /* Return RNG Error Code */ + return hrng->ErrorCode; +} +/** + * @} + */ + +/** + * @} + */ +/* Private functions ---------------------------------------------------------*/ +/** @addtogroup RNG_Private_Functions + * @{ + */ + +/** + * @brief RNG sequence to recover from a seed error + * @param hrng pointer to a RNG_HandleTypeDef structure. + * @retval HAL status + */ +HAL_StatusTypeDef RNG_RecoverSeedError(RNG_HandleTypeDef *hrng) +{ + __IO uint32_t count = 0U; + + /*Check if seed error current status (SECS)is set */ + if (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_SECS) == RESET) + { + /* RNG performed the reset automatically (auto-reset) */ + /* Clear bit SEIS */ + CLEAR_BIT(hrng->Instance->SR, RNG_IT_SEI); + } + else /* Sequence to fully recover from a seed error*/ + { + /* Writing bit CONDRST=1*/ + SET_BIT(hrng->Instance->CR, RNG_CR_CONDRST); + /* Writing bit CONDRST=0*/ + CLEAR_BIT(hrng->Instance->CR, RNG_CR_CONDRST); + + /* Wait for conditioning reset process to be completed */ + count = RNG_TIMEOUT_VALUE; + do + { + count-- ; + if (count == 0U) + { + hrng->State = HAL_RNG_STATE_READY; + hrng->ErrorCode |= HAL_RNG_ERROR_TIMEOUT; + /* Process Unlocked */ + __HAL_UNLOCK(hrng); +#if (USE_HAL_RNG_REGISTER_CALLBACKS == 1) + /* Call registered Error callback */ + hrng->ErrorCallback(hrng); +#else + /* Call legacy weak Error callback */ + HAL_RNG_ErrorCallback(hrng); +#endif /* USE_HAL_RNG_REGISTER_CALLBACKS */ + return HAL_ERROR; + } + } while (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST)); + + if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET) + { + /* Clear bit SEIS */ + CLEAR_BIT(hrng->Instance->SR, RNG_IT_SEI); + } + + /* Wait for SECS to be cleared */ + count = RNG_TIMEOUT_VALUE; + do + { + count-- ; + if (count == 0U) + { + hrng->State = HAL_RNG_STATE_READY; + hrng->ErrorCode |= HAL_RNG_ERROR_TIMEOUT; + /* Process Unlocked */ + __HAL_UNLOCK(hrng); +#if (USE_HAL_RNG_REGISTER_CALLBACKS == 1) + /* Call registered Error callback */ + hrng->ErrorCallback(hrng); +#else + /* Call legacy weak Error callback */ + HAL_RNG_ErrorCallback(hrng); +#endif /* USE_HAL_RNG_REGISTER_CALLBACKS */ + return HAL_ERROR; + } + } while (HAL_IS_BIT_SET(hrng->Instance->SR, RNG_FLAG_SECS)); + } + /* Update the error code */ + hrng->ErrorCode &= ~ HAL_RNG_ERROR_SEED; + return HAL_OK; +} + +/** + * @} + */ + + +#endif /* HAL_RNG_MODULE_ENABLED */ +/** + * @} + */ + +#endif /* RNG */ + +/** + * @} + */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rng_ex.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rng_ex.c new file mode 100644 index 0000000000..167ed03fdb --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rng_ex.c @@ -0,0 +1,339 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_rng_ex.c + * @author MCD Application Team + * @brief Extended RNG HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Random Number Generator (RNG) peripheral: + * + Lock configuration functions + * + Reset the RNG + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +#if defined(RNG) + +/** @addtogroup RNG_Ex + * @brief RNG Extended HAL module driver. + * @{ + */ + +#ifdef HAL_RNG_MODULE_ENABLED +#if defined(RNG_CR_CONDRST) +/* Private types -------------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @addtogroup RNG_Ex_Private_Constants + * @{ + */ +#define RNG_TIMEOUT_VALUE 2U +/** + * @} + */ +/* Private macros ------------------------------------------------------------*/ +/* Private functions prototypes ----------------------------------------------*/ +/* Private functions --------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup RNG_Ex_Exported_Functions RNG_Ex Exported Functions + * @{ + */ + +/** @defgroup RNG_Ex_Exported_Functions_Group1 Configuration and lock functions + * @brief Configuration functions + * +@verbatim + =============================================================================== + ##### Configuration and lock functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure the RNG with the specified parameters in the RNG_ConfigTypeDef + (+) Lock RNG configuration Allows user to lock a configuration until next reset. + +@endverbatim + * @{ + */ + +/** + * @brief Configure the RNG with the specified parameters in the + * RNG_ConfigTypeDef. + * @param hrng pointer to a RNG_HandleTypeDef structure that contains + * the configuration information for RNG. + * @param pConf pointer to a RNG_ConfigTypeDef structure that contains + * the configuration information for RNG module + + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RNGEx_SetConfig(RNG_HandleTypeDef *hrng, const RNG_ConfigTypeDef *pConf) +{ + uint32_t tickstart; + uint32_t cr_value; + HAL_StatusTypeDef status ; + + /* Check the RNG handle allocation */ + if ((hrng == NULL) || (pConf == NULL)) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_RNG_ALL_INSTANCE(hrng->Instance)); + assert_param(IS_RNG_CLOCK_DIVIDER(pConf->ClockDivider)); + assert_param(IS_RNG_NIST_COMPLIANCE(pConf->NistCompliance)); + assert_param(IS_RNG_CONFIG1(pConf->Config1)); + assert_param(IS_RNG_CONFIG2(pConf->Config2)); + assert_param(IS_RNG_CONFIG3(pConf->Config3)); + assert_param(IS_RNG_ARDIS(pConf->AutoReset)); + + /* Check RNG peripheral state */ + if (hrng->State == HAL_RNG_STATE_READY) + { + /* Change RNG peripheral state */ + hrng->State = HAL_RNG_STATE_BUSY; + + /* Disable RNG */ + __HAL_RNG_DISABLE(hrng); + + /* RNG CR register configuration. Set value in CR register for : + - NIST Compliance setting + - Clock divider value + - Automatic reset to clear SECS bit + - CONFIG 1, CONFIG 2 and CONFIG 3 values */ + cr_value = (uint32_t)(pConf->ClockDivider | pConf->NistCompliance | pConf->AutoReset + | (pConf->Config1 << RNG_CR_RNG_CONFIG1_Pos) + | (pConf->Config2 << RNG_CR_RNG_CONFIG2_Pos) + | (pConf->Config3 << RNG_CR_RNG_CONFIG3_Pos)); + + MODIFY_REG(hrng->Instance->CR, RNG_CR_NISTC | RNG_CR_CLKDIV | RNG_CR_RNG_CONFIG1 + | RNG_CR_RNG_CONFIG2 | RNG_CR_RNG_CONFIG3 | RNG_CR_ARDIS, + (uint32_t)(RNG_CR_CONDRST | cr_value)); + + /* RNG health test control in accordance with NIST */ + WRITE_REG(hrng->Instance->HTCR, pConf->HealthTest); + + /* Writing bit CONDRST=0*/ + CLEAR_BIT(hrng->Instance->CR, RNG_CR_CONDRST); + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait for conditioning reset process to be completed */ + while (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST)) + { + if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE) + { + /* New check to avoid false timeout detection in case of prememption */ + if (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST)) + { + hrng->State = HAL_RNG_STATE_READY; + hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT; + return HAL_ERROR; + } + } + } + + /* Enable RNG */ + __HAL_RNG_ENABLE(hrng); + + /* Initialize the RNG state */ + hrng->State = HAL_RNG_STATE_READY; + + /* function status */ + status = HAL_OK; + } + else + { + hrng->ErrorCode = HAL_RNG_ERROR_BUSY; + status = HAL_ERROR; + } + + /* Return the function status */ + return status; +} + +/** + * @brief Get the RNG Configuration and fill parameters in the + * RNG_ConfigTypeDef. + * @param hrng pointer to a RNG_HandleTypeDef structure that contains + * the configuration information for RNG. + * @param pConf pointer to a RNG_ConfigTypeDef structure that contains + * the configuration information for RNG module + + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RNGEx_GetConfig(RNG_HandleTypeDef *hrng, RNG_ConfigTypeDef *pConf) +{ + + HAL_StatusTypeDef status ; + + /* Check the RNG handle allocation */ + if ((hrng == NULL) || (pConf == NULL)) + { + return HAL_ERROR; + } + + /* Check RNG peripheral state */ + if (hrng->State == HAL_RNG_STATE_READY) + { + /* Change RNG peripheral state */ + hrng->State = HAL_RNG_STATE_BUSY; + + /* Get RNG parameters */ + pConf->Config1 = (uint32_t)((hrng->Instance->CR & RNG_CR_RNG_CONFIG1) >> RNG_CR_RNG_CONFIG1_Pos) ; + pConf->Config2 = (uint32_t)((hrng->Instance->CR & RNG_CR_RNG_CONFIG2) >> RNG_CR_RNG_CONFIG2_Pos); + pConf->Config3 = (uint32_t)((hrng->Instance->CR & RNG_CR_RNG_CONFIG3) >> RNG_CR_RNG_CONFIG3_Pos); + pConf->ClockDivider = (hrng->Instance->CR & RNG_CR_CLKDIV); + pConf->NistCompliance = (hrng->Instance->CR & RNG_CR_NISTC); + pConf->AutoReset = (hrng->Instance->CR & RNG_CR_ARDIS); + pConf->HealthTest = (hrng->Instance->HTCR); + + /* Initialize the RNG state */ + hrng->State = HAL_RNG_STATE_READY; + + /* function status */ + status = HAL_OK; + } + else + { + hrng->ErrorCode |= HAL_RNG_ERROR_BUSY; + status = HAL_ERROR; + } + + /* Return the function status */ + return status; +} + +/** + * @brief RNG current configuration lock. + * @note This function allows to lock RNG peripheral configuration. + * Once locked, HW RNG reset has to be performed prior any further + * configuration update. + * @param hrng pointer to a RNG_HandleTypeDef structure that contains + * the configuration information for RNG. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RNGEx_LockConfig(RNG_HandleTypeDef *hrng) +{ + HAL_StatusTypeDef status; + + /* Check the RNG handle allocation */ + if (hrng == NULL) + { + return HAL_ERROR; + } + + /* Check RNG peripheral state */ + if (hrng->State == HAL_RNG_STATE_READY) + { + /* Change RNG peripheral state */ + hrng->State = HAL_RNG_STATE_BUSY; + + /* Perform RNG configuration Lock */ + MODIFY_REG(hrng->Instance->CR, RNG_CR_CONFIGLOCK, RNG_CR_CONFIGLOCK); + + /* Change RNG peripheral state */ + hrng->State = HAL_RNG_STATE_READY; + + /* function status */ + status = HAL_OK; + } + else + { + hrng->ErrorCode = HAL_RNG_ERROR_BUSY; + status = HAL_ERROR; + } + + /* Return the function status */ + return status; +} + + +/** + * @} + */ + +/** @defgroup RNG_Ex_Exported_Functions_Group2 Recover from seed error function + * @brief Recover from seed error function + * +@verbatim + =============================================================================== + ##### Recover from seed error function ##### + =============================================================================== + [..] This section provide function allowing to: + (+) Recover from a seed error + +@endverbatim + * @{ + */ + +/** + * @brief RNG sequence to recover from a seed error + * @param hrng: pointer to a RNG_HandleTypeDef structure. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RNGEx_RecoverSeedError(RNG_HandleTypeDef *hrng) +{ + HAL_StatusTypeDef status; + + /* Check the RNG handle allocation */ + if (hrng == NULL) + { + return HAL_ERROR; + } + + /* Check RNG peripheral state */ + if (hrng->State == HAL_RNG_STATE_READY) + { + /* Change RNG peripheral state */ + hrng->State = HAL_RNG_STATE_BUSY; + + /* sequence to fully recover from a seed error */ + status = RNG_RecoverSeedError(hrng); + } + else + { + hrng->ErrorCode = HAL_RNG_ERROR_BUSY; + status = HAL_ERROR; + } + + /* Return the function status */ + return status; +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* RNG_CR_CONDRST */ +#endif /* HAL_RNG_MODULE_ENABLED */ +/** + * @} + */ + +#endif /* RNG */ + +/** + * @} + */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rtc.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rtc.c new file mode 100644 index 0000000000..c42258d479 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rtc.c @@ -0,0 +1,2341 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_rtc.c + * @author MCD Application Team + * @brief RTC HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Real-Time Clock (RTC) peripheral: + * + Initialization/de-initialization functions + * + Calendar (Time and Date) configuration + * + Alarms (Alarm A and Alarm B) configuration + * + WakeUp Timer configuration + * + TimeStamp configuration + * + Tampers configuration + * + Backup Data Registers configuration + * + RTC Tamper and TimeStamp Pins Selection + * + Interrupts and flags management + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + =============================================================================== + ##### RTC Operating Condition ##### + =============================================================================== + [..] The real-time clock (RTC) and the RTC backup registers can be powered + from the VBAT voltage when the main VDD supply is powered off. + To retain the content of the RTC backup registers and supply the RTC + when VDD is turned off, VBAT pin can be connected to an optional + standby voltage supplied by a battery or by another source. + + ##### Backup Domain Reset ##### + =============================================================================== + [..] The backup domain reset sets all RTC registers and the RCC_BDCR register + to their reset values. + A backup domain reset is generated when one of the following events occurs: + (#) Software reset, triggered by setting the BDRST bit in the + RCC Backup domain control register (RCC_BDCR). + (#) VDD or VBAT power on, if both supplies have previously been powered off. + (#) Tamper detection event resets all data backup registers. + + ##### Backup Domain Access ##### + ================================================================== + [..] After reset, the backup domain (RTC registers and RTC backup data registers) + is protected against possible unwanted write accesses. + [..] To enable access to the RTC Domain and RTC registers, proceed as follows: + (+) Enable access to RTC domain using the HAL_PWR_EnableBkUpAccess() function. + (+) Call the function HAL_RCCEx_PeriphCLKConfig with RCC_PERIPHCLK_RTC for + PeriphClockSelection and select RTCClockSelection (LSE, LSI or HSEdiv32) + (+) Enable RTC Clock using the __HAL_RCC_RTC_ENABLE() function. + + ##### How to use RTC Driver ##### + =================================================================== + [..] + (+) Enable the RTC domain access (see description in the section above). + (+) Configure the RTC Prescaler (Asynchronous and Synchronous) and RTC hour + format using the HAL_RTC_Init() function. + + *** Time and Date configuration *** + =================================== + [..] + (+) To configure the RTC Calendar (Time and Date) use the HAL_RTC_SetTime() + and HAL_RTC_SetDate() functions. + (+) To read the RTC Calendar, use the HAL_RTC_GetTime() and HAL_RTC_GetDate() functions. + + *** Alarm configuration *** + =========================== + [..] + (+) To configure the RTC Alarm use the HAL_RTC_SetAlarm() function. + You can also configure the RTC Alarm with interrupt mode using the + HAL_RTC_SetAlarm_IT() function. + (+) To read the RTC Alarm, use the HAL_RTC_GetAlarm() function. + + ##### RTC and low power modes ##### + ================================================================== + [..] The MCU can be woken up from a low power mode by an RTC alternate + function. + [..] The RTC alternate functions are the RTC alarms (Alarm A and Alarm B), + RTC wakeup, RTC tamper event detection and RTC time stamp event detection. + These RTC alternate functions can wake up the system from the Stop and + Standby low power modes. + [..] The system can also wake up from low power modes without depending + on an external interrupt (Auto-wakeup mode), by using the RTC alarm + or the RTC wakeup events. + [..] The RTC provides a programmable time base for waking up from the + Stop or Standby mode at regular intervals. + Wakeup from STOP and STANDBY modes is possible only when the RTC clock source + is LSE or LSI. + + *** Callback registration *** + ============================================= + When The compilation define USE_HAL_RTC_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. This is the recommended configuration + in order to optimize memory/code consumption footprint/performances. + + The compilation define USE_RTC_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + Use Function HAL_RTC_RegisterCallback() to register an interrupt callback. + + Function HAL_RTC_RegisterCallback() allows to register following callbacks: + (+) AlarmAEventCallback : RTC Alarm A Event callback. + (+) AlarmBEventCallback : RTC Alarm B Event callback. + (+) TimeStampEventCallback : RTC TimeStamp Event callback. + (+) WakeUpTimerEventCallback : RTC WakeUpTimer Event callback. + (+) SSRUEventCallback : RTC SSRU Event callback. + (+) Tamper1EventCallback : RTC Tamper 1 Event callback. + (+) Tamper2EventCallback : RTC Tamper 2 Event callback. + (+) Tamper3EventCallback : RTC Tamper 3 Event callback. + (+) Tamper4EventCallback : RTC Tamper 4 Event callback. + (+) Tamper5EventCallback : RTC Tamper 5 Event callback. + (+) Tamper6EventCallback : RTC Tamper 6 Event callback. + (+) Tamper7EventCallback : RTC Tamper 7 Event callback. + (+) Tamper8EventCallback : RTC Tamper 8 Event callback. + (+) InternalTamper1EventCallback : RTC InternalTamper 1 Event callback. + (+) InternalTamper2EventCallback : RTC InternalTamper 2 Event callback. + (+) InternalTamper3EventCallback : RTC InternalTamper 3 Event callback. + (+) InternalTamper4EventCallback : RTC InternalTamper 4 Event callback. + (+) InternalTamper5EventCallback : RTC InternalTamper 5 Event callback. + (+) InternalTamper6EventCallback : RTC InternalTamper 6 Event callback. + (+) InternalTamper7EventCallback : RTC InternalTamper 7 Event callback. + (+) InternalTamper8EventCallback : RTC InternalTamper 8 Event callback. + (+) InternalTamper9EventCallback : RTC InternalTamper 9 Event callback. + (+) InternalTamper11EventCallback : RTC InternalTamper 11 Event callback. + (+) InternalTamper12EventCallback : RTC InternalTamper 12 Event callback. + (+) InternalTamper13EventCallback : RTC InternalTamper 13 Event callback. + (+) InternalTamper15EventCallback : RTC InternalTamper 15 Event callback. + (+) MspInitCallback : RTC MspInit callback. + (+) MspDeInitCallback : RTC MspDeInit callback. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + + Use function HAL_RTC_UnRegisterCallback() to reset a callback to the default + weak function. + HAL_RTC_UnRegisterCallback() takes as parameters the HAL peripheral handle, + and the Callback ID. + This function allows to reset following callbacks: + (+) AlarmAEventCallback : RTC Alarm A Event callback. + (+) AlarmBEventCallback : RTC Alarm B Event callback. + (+) TimeStampEventCallback : RTC TimeStamp Event callback. + (+) WakeUpTimerEventCallback : RTC WakeUpTimer Event callback. + (+) SSRUEventCallback : RTC SSRU Event callback. + (+) Tamper1EventCallback : RTC Tamper 1 Event callback. + (+) Tamper2EventCallback : RTC Tamper 2 Event callback. + (+) Tamper3EventCallback : RTC Tamper 3 Event callback. + (+) Tamper4EventCallback : RTC Tamper 4 Event callback. + (+) Tamper5EventCallback : RTC Tamper 5 Event callback. + (+) Tamper6EventCallback : RTC Tamper 6 Event callback. + (+) Tamper7EventCallback : RTC Tamper 7 Event callback. + (+) Tamper8EventCallback : RTC Tamper 8 Event callback. + (+) InternalTamper1EventCallback : RTC InternalTamper 1 Event callback. + (+) InternalTamper2EventCallback : RTC InternalTamper 2 Event callback. + (+) InternalTamper3EventCallback : RTC InternalTamper 3 Event callback. + (+) InternalTamper4EventCallback : RTC InternalTamper 4 Event callback. + (+) InternalTamper5EventCallback : RTC InternalTamper 5 Event callback. + (+) InternalTamper6EventCallback : RTC InternalTamper 6 Event callback. + (+) InternalTamper7EventCallback : RTC InternalTamper 7 Event callback. + (+) InternalTamper8EventCallback : RTC InternalTamper 8 Event callback. + (+) InternalTamper9EventCallback : RTC InternalTamper 9 Event callback. + (+) InternalTamper11EventCallback : RTC InternalTamper 11 Event callback. + (+) InternalTamper12EventCallback : RTC InternalTamper 12 Event callback. + (+) InternalTamper13EventCallback : RTC InternalTamper 13 Event callback. + (+) InternalTamper15EventCallback : RTC InternalTamper 15 Event callback. + (+) MspInitCallback : RTC MspInit callback. + (+) MspDeInitCallback : RTC MspDeInit callback. + + By default, after the HAL_RTC_Init() and when the state is HAL_RTC_STATE_RESET, + all callbacks are set to the corresponding weak functions : + examples AlarmAEventCallback(), TimeStampEventCallback(). + Exception done for MspInit and MspDeInit callbacks that are reset to the legacy weak function + in the HAL_RTC_Init()/HAL_RTC_DeInit() only when these callbacks are null + (not registered beforehand). + If not, MspInit or MspDeInit are not null, HAL_RTC_Init()/HAL_RTC_DeInit() + keep and use the user MspInit/MspDeInit callbacks (registered beforehand) + + Callbacks can be registered/unregistered in HAL_RTC_STATE_READY state only. + Exception done MspInit/MspDeInit that can be registered/unregistered + in HAL_RTC_STATE_READY or HAL_RTC_STATE_RESET state, + thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. + In that case first register the MspInit/MspDeInit user callbacks + using HAL_RTC_RegisterCallback() before calling HAL_RTC_DeInit() + or HAL_RTC_Init() function. + + When The compilation define USE_HAL_RTC_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 "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + + +/** @addtogroup RTC + * @brief RTC HAL module driver + * @{ + */ + +#ifdef HAL_RTC_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup RTC_Exported_Functions + * @{ + */ + +/** @addtogroup RTC_Exported_Functions_Group1 + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This section provides functions allowing to initialize and configure the + RTC Prescaler (Synchronous and Asynchronous), RTC Hour format, disable + RTC registers Write protection, enter and exit the RTC initialization mode, + RTC registers synchronization check and reference clock detection enable. + (#) The RTC Prescaler is programmed to generate the RTC 1Hz time base. + It is split into 2 programmable prescalers to minimize power consumption. + (++) A 7-bit asynchronous prescaler and a 15-bit synchronous prescaler. + (++) When both prescalers are used, it is recommended to configure the + asynchronous prescaler to a high value to minimize power consumption. + (#) All RTC registers are Write protected. Writing to the RTC registers + is enabled by writing a key into the Write Protection register, RTC_WPR. + (#) To configure the RTC Calendar, user application should enter + initialization mode. In this mode, the calendar counter is stopped + and its value can be updated. When the initialization sequence is + complete, the calendar restarts counting after 4 RTCCLK cycles. + (#) To read the calendar through the shadow registers after Calendar + initialization, calendar update or after wakeup from low power modes + the software must first clear the RSF flag. The software must then + wait until it is set again before reading the calendar, which means + that the calendar registers have been correctly copied into the + RTC_TR and RTC_DR shadow registers. The HAL_RTC_WaitForSynchro() function + implements the above software sequence (RSF clear and RSF check). + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the RTC peripheral + * @param hrtc RTC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTC_Init(RTC_HandleTypeDef *hrtc) +{ + HAL_StatusTypeDef status = HAL_ERROR; + + /* Check the RTC peripheral state */ + if (hrtc != NULL) + { + /* Check the parameters */ + assert_param(IS_RTC_ALL_INSTANCE(hrtc->Instance)); + assert_param(IS_RTC_HOUR_FORMAT(hrtc->Init.HourFormat)); + assert_param(IS_RTC_ASYNCH_PREDIV(hrtc->Init.AsynchPrediv)); + assert_param(IS_RTC_SYNCH_PREDIV(hrtc->Init.SynchPrediv)); +#if defined(RTC_CR_OSEL) + assert_param(IS_RTC_OUTPUT(hrtc->Init.OutPut)); + assert_param(IS_RTC_OUTPUT_POL(hrtc->Init.OutPutPolarity)); + assert_param(IS_RTC_OUTPUT_TYPE(hrtc->Init.OutPutType)); + assert_param(IS_RTC_OUTPUT_PULLUP(hrtc->Init.OutPutPullUp)); +#endif /* RTC_CR_OSEL */ +#if defined(RTC_CR_OUT2EN) + assert_param(IS_RTC_OUTPUT_REMAP(hrtc->Init.OutPutRemap)); +#endif /* RTC_CR_OUT2EN */ + assert_param(IS_RTC_BINARY_MODE(hrtc->Init.BinMode)); + assert_param(IS_RTC_BINARY_MIX_BCDU(hrtc->Init.BinMixBcdU)); + +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + if (hrtc->State == HAL_RTC_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hrtc->Lock = HAL_UNLOCKED; + + /* Legacy weak AlarmAEventCallback */ + hrtc->AlarmAEventCallback = HAL_RTC_AlarmAEventCallback; + /* Legacy weak AlarmBEventCallback */ + hrtc->AlarmBEventCallback = HAL_RTCEx_AlarmBEventCallback; + /* Legacy weak TimeStampEventCallback */ + hrtc->TimeStampEventCallback = HAL_RTCEx_TimeStampEventCallback; + /* Legacy weak WakeUpTimerEventCallback */ + hrtc->WakeUpTimerEventCallback = HAL_RTCEx_WakeUpTimerEventCallback; + /* Legacy weak SSRUEventCallback */ + hrtc->SSRUEventCallback = HAL_RTCEx_SSRUEventCallback; + /* Legacy weak Tamper1EventCallback */ + hrtc->Tamper1EventCallback = HAL_RTCEx_Tamper1EventCallback; + /* Legacy weak Tamper2EventCallback */ + hrtc->Tamper2EventCallback = HAL_RTCEx_Tamper2EventCallback; + /* Legacy weak Tamper3EventCallback */ + hrtc->Tamper3EventCallback = HAL_RTCEx_Tamper3EventCallback; + /* Legacy weak Tamper4EventCallback */ + hrtc->Tamper4EventCallback = HAL_RTCEx_Tamper4EventCallback; + /* Legacy weak Tamper5EventCallback */ + hrtc->Tamper5EventCallback = HAL_RTCEx_Tamper5EventCallback; + /* Legacy weak Tamper6EventCallback */ + hrtc->Tamper6EventCallback = HAL_RTCEx_Tamper6EventCallback; + /* Legacy weak Tamper7EventCallback */ + hrtc->Tamper7EventCallback = HAL_RTCEx_Tamper7EventCallback; + /* Legacy weak Tamper8EventCallback */ + hrtc->Tamper8EventCallback = HAL_RTCEx_Tamper8EventCallback; + /* Legacy weak InternalTamper1EventCallback */ + hrtc->InternalTamper1EventCallback = HAL_RTCEx_InternalTamper1EventCallback; + /* Legacy weak InternalTamper2EventCallback */ + hrtc->InternalTamper2EventCallback = HAL_RTCEx_InternalTamper2EventCallback; + /* Legacy weak InternalTamper3EventCallback */ + hrtc->InternalTamper3EventCallback = HAL_RTCEx_InternalTamper3EventCallback; + /* Legacy weak InternalTamper4EventCallback */ + hrtc->InternalTamper4EventCallback = HAL_RTCEx_InternalTamper4EventCallback; + /* Legacy weak InternalTamper5EventCallback */ + hrtc->InternalTamper5EventCallback = HAL_RTCEx_InternalTamper5EventCallback; + /* Legacy weak InternalTamper6EventCallback */ + hrtc->InternalTamper6EventCallback = HAL_RTCEx_InternalTamper6EventCallback; + /* Legacy weak InternalTamper7EventCallback */ + hrtc->InternalTamper7EventCallback = HAL_RTCEx_InternalTamper7EventCallback; + /* Legacy weak InternalTamper8EventCallback */ + hrtc->InternalTamper8EventCallback = HAL_RTCEx_InternalTamper8EventCallback; + /* Legacy weak InternalTamper9EventCallback */ + hrtc->InternalTamper9EventCallback = HAL_RTCEx_InternalTamper9EventCallback; + /* Legacy weak InternalTamper11EventCallback */ + hrtc->InternalTamper11EventCallback = HAL_RTCEx_InternalTamper11EventCallback; + /* Legacy weak InternalTamper12EventCallback */ + hrtc->InternalTamper12EventCallback = HAL_RTCEx_InternalTamper12EventCallback; + /* Legacy weak InternalTamper13EventCallback */ + hrtc->InternalTamper13EventCallback = HAL_RTCEx_InternalTamper13EventCallback; + /* Legacy weak InternalTamper15EventCallback */ + hrtc->InternalTamper15EventCallback = HAL_RTCEx_InternalTamper15EventCallback; + + if (hrtc->MspInitCallback == NULL) + { + hrtc->MspInitCallback = HAL_RTC_MspInit; + } + /* Init the low level hardware */ + hrtc->MspInitCallback(hrtc); + + if (hrtc->MspDeInitCallback == NULL) + { + hrtc->MspDeInitCallback = HAL_RTC_MspDeInit; + } + } +#else + if (hrtc->State == HAL_RTC_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hrtc->Lock = HAL_UNLOCKED; + + /* Initialize RTC MSP */ + HAL_RTC_MspInit(hrtc); + } +#endif /* (USE_HAL_RTC_REGISTER_CALLBACKS) */ + + /* Set RTC state */ + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Check if the calendar has been not initialized */ + if (__HAL_RTC_IS_CALENDAR_INITIALIZED(hrtc) == 0U) + { + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Enter Initialization mode */ + status = RTC_EnterInitMode(hrtc); + if (status == HAL_OK) + { +#if defined(RTC_CR_OSEL) + /* Clear RTC_CR FMT, OSEL and POL Bits */ + CLEAR_BIT(RTC->CR, (RTC_CR_FMT | RTC_CR_POL | RTC_CR_OSEL | RTC_CR_TAMPOE)); + + /* Set RTC_CR register */ + SET_BIT(RTC->CR, (hrtc->Init.HourFormat | hrtc->Init.OutPut | hrtc->Init.OutPutPolarity)); +#else + /* Clear RTC_CR FMT Bits */ + CLEAR_BIT(RTC->CR, RTC_CR_FMT); + + /* Set RTC_CR register */ + SET_BIT(RTC->CR, hrtc->Init.HourFormat); +#endif /* RTC_CR_OSEL */ + + /* Configure the RTC PRER */ + WRITE_REG(RTC->PRER, ((hrtc->Init.SynchPrediv) | (hrtc->Init.AsynchPrediv << RTC_PRER_PREDIV_A_Pos))); + + /* Configure the Binary mode */ + MODIFY_REG(RTC->ICSR, RTC_ICSR_BIN | RTC_ICSR_BCDU, hrtc->Init.BinMode | hrtc->Init.BinMixBcdU); + + /* Exit Initialization mode */ + status = RTC_ExitInitMode(hrtc); + +#if defined(RTC_CR_OSEL) + if (status == HAL_OK) + { +#if defined(RTC_CR_OUT2EN) + MODIFY_REG(RTC->CR, \ + RTC_CR_TAMPALRM_PU | RTC_CR_TAMPALRM_TYPE | RTC_CR_OUT2EN, \ + hrtc->Init.OutPutPullUp | hrtc->Init.OutPutType | hrtc->Init.OutPutRemap); +#else + MODIFY_REG(RTC->CR, \ + RTC_CR_TAMPALRM_PU | RTC_CR_TAMPALRM_TYPE, \ + hrtc->Init.OutPutPullUp | hrtc->Init.OutPutType); +#endif /* RTC_CR_OUT2EN */ + } +#endif /* RTC_CR_OSEL */ + } + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + } + else + { + /* Calendar is already initialized */ + /* Set flag to OK */ + status = HAL_OK; + } + + if (status == HAL_OK) + { + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + } + } + + return status; +} + +/** + * @brief DeInitialize the RTC peripheral. + * @note This function does not reset the RTC Backup Data registers. + * @param hrtc RTC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTC_DeInit(RTC_HandleTypeDef *hrtc) +{ + HAL_StatusTypeDef status; + + /* Set RTC state */ + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Enter Initialization mode */ + status = RTC_EnterInitMode(hrtc); + if (status == HAL_OK) + { + /* Reset all RTC CR register bits */ + CLEAR_REG(RTC->CR); + WRITE_REG(RTC->DR, (uint32_t)(RTC_DR_WDU_0 | RTC_DR_MU_0 | RTC_DR_DU_0)); + CLEAR_REG(RTC->TR); + WRITE_REG(RTC->WUTR, RTC_WUTR_WUT); + WRITE_REG(RTC->PRER, ((uint32_t)(RTC_PRER_PREDIV_A | 0xFFU))); + CLEAR_REG(RTC->ALRMAR); + CLEAR_REG(RTC->ALRMBR); + CLEAR_REG(RTC->SHIFTR); + CLEAR_REG(RTC->CALR); + CLEAR_REG(RTC->ALRMASSR); + CLEAR_REG(RTC->ALRMBSSR); + CLEAR_BIT(RTC->ICSR, (RTC_ICSR_BCDU_Msk | RTC_ICSR_BIN_Msk)); + WRITE_REG(RTC->SCR, RTC_SCR_CITSF | RTC_SCR_CTSOVF | RTC_SCR_CTSF | RTC_SCR_CWUTF | RTC_SCR_CALRBF | \ + RTC_SCR_CALRAF); +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + CLEAR_REG(RTC->SECCFGR); +#endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +#if defined (RTC_PRIVCFGR_ALRAPRIV) + CLEAR_REG(RTC->PRIVCFGR); +#endif /* RTC_PRIVCFGR_ALRAPRIV */ + + /* Exit initialization mode */ + status = RTC_ExitInitMode(hrtc); + if (status == HAL_OK) + { + /* Reset TAMP registers */ + CLEAR_REG(TAMP->CR1); + CLEAR_REG(TAMP->CR2); + CLEAR_REG(TAMP->CR3); + CLEAR_REG(TAMP->FLTCR); + WRITE_REG(TAMP->ATCR1, TAMP_ATCR1_ATCKSEL); + CLEAR_REG(TAMP->ATOR); + CLEAR_REG(TAMP->ATCR2); + CLEAR_REG(TAMP->SECCFGR); +#if defined (TAMP_PRIVCFGR_TAMPPRIV) + CLEAR_REG(TAMP->PRIVCFGR); +#endif /* TAMP_PRIVCFGR_TAMPPRIV */ + } + } + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + if (status == HAL_OK) + { +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + if (hrtc->MspDeInitCallback == NULL) + { + hrtc->MspDeInitCallback = HAL_RTC_MspDeInit; + } + + /* DeInit the low level hardware: CLOCK, NVIC.*/ + hrtc->MspDeInitCallback(hrtc); + +#else + /* De-Initialize RTC MSP */ + HAL_RTC_MspDeInit(hrtc); +#endif /* (USE_HAL_RTC_REGISTER_CALLBACKS) */ + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_RESET; + } + + /* Release Lock */ + __HAL_UNLOCK(hrtc); + + return status; +} + +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User RTC Callback + * To be used instead of the weak predefined callback + * @param hrtc RTC handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_RTC_ALARM_A_EVENT_CB_ID Alarm A Event Callback ID + * @arg @ref HAL_RTC_ALARM_B_EVENT_CB_ID Alarm B Event Callback ID + * @arg @ref HAL_RTC_TIMESTAMP_EVENT_CB_ID TimeStamp Event Callback ID + * @arg @ref HAL_RTC_WAKEUPTIMER_EVENT_CB_ID WakeUp Timer Event Callback ID + * @arg @ref HAL_RTC_TAMPER1_EVENT_CB_ID Tamper 1 Callback ID + * @arg @ref HAL_RTC_TAMPER2_EVENT_CB_ID Tamper 2 Callback ID + * @arg @ref HAL_RTC_TAMPER3_EVENT_CB_ID Tamper 3 Callback ID + * @arg @ref HAL_RTC_TAMPER4_EVENT_CB_ID Tamper 4 Callback ID + * @arg @ref HAL_RTC_TAMPER5_EVENT_CB_ID Tamper 5 Callback ID + * @arg @ref HAL_RTC_TAMPER6_EVENT_CB_ID Tamper 6 Callback ID + * @arg @ref HAL_RTC_TAMPER7_EVENT_CB_ID Tamper 7 Callback ID + * @arg @ref HAL_RTC_TAMPER8_EVENT_CB_ID Tamper 8 Callback ID + * @arg @ref HAL_RTC_INTERNAL_TAMPER1_EVENT_CB_ID Internal Tamper 1 Callback ID + * @arg @ref HAL_RTC_INTERNAL_TAMPER2_EVENT_CB_ID Internal Tamper 2 Callback ID + * @arg @ref HAL_RTC_INTERNAL_TAMPER3_EVENT_CB_ID Internal Tamper 3 Callback ID + * @arg @ref HAL_RTC_INTERNAL_TAMPER4_EVENT_CB_ID Internal Tamper 4 Callback ID + * @arg @ref HAL_RTC_INTERNAL_TAMPER5_EVENT_CB_ID Internal Tamper 5 Callback ID + * @arg @ref HAL_RTC_INTERNAL_TAMPER6_EVENT_CB_ID Internal Tamper 6 Callback ID + * @arg @ref HAL_RTC_INTERNAL_TAMPER7_EVENT_CB_ID Internal Tamper 7 Callback ID + * @arg @ref HAL_RTC_INTERNAL_TAMPER8_EVENT_CB_ID Internal Tamper 8 Callback ID + * @arg @ref HAL_RTC_INTERNAL_TAMPER9_EVENT_CB_ID Internal Tamper 9 Callback ID + * @arg @ref HAL_RTC_INTERNAL_TAMPER11_EVENT_CB_ID Internal Tamper 11 Callback ID + * @arg @ref HAL_RTC_INTERNAL_TAMPER12_EVENT_CB_ID Internal Tamper 12 Callback ID + * @arg @ref HAL_RTC_INTERNAL_TAMPER13_EVENT_CB_ID Internal Tamper 13 Callback ID + * @arg @ref HAL_RTC_INTERNAL_TAMPER15_EVENT_CB_ID Internal Tamper 15 Callback ID + * @arg @ref HAL_RTC_MSPINIT_CB_ID Msp Init callback ID + * @arg @ref HAL_RTC_MSPDEINIT_CB_ID Msp DeInit callback ID + * @param pCallback pointer to the Callback function + * @note The HAL_RTC_RegisterCallback() may be called before HAL_RTC_Init() in HAL_RTC_STATE_RESET + * to register callbacks for HAL_RTC_MSPINIT_CB_ID and HAL_RTC_MSPDEINIT_CB_ID. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTC_RegisterCallback(RTC_HandleTypeDef *hrtc, HAL_RTC_CallbackIDTypeDef CallbackID, + pRTC_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + return HAL_ERROR; + } + + if (HAL_RTC_STATE_READY == hrtc->State) + { + switch (CallbackID) + { + case HAL_RTC_ALARM_A_EVENT_CB_ID : + hrtc->AlarmAEventCallback = pCallback; + break; + + case HAL_RTC_ALARM_B_EVENT_CB_ID : + hrtc->AlarmBEventCallback = pCallback; + break; + + case HAL_RTC_TIMESTAMP_EVENT_CB_ID : + hrtc->TimeStampEventCallback = pCallback; + break; + + case HAL_RTC_WAKEUPTIMER_EVENT_CB_ID : + hrtc->WakeUpTimerEventCallback = pCallback; + break; + + case HAL_RTC_SSRU_EVENT_CB_ID : + hrtc->SSRUEventCallback = pCallback; + break; + + case HAL_RTC_TAMPER1_EVENT_CB_ID : + hrtc->Tamper1EventCallback = pCallback; + break; + + case HAL_RTC_TAMPER2_EVENT_CB_ID : + hrtc->Tamper2EventCallback = pCallback; + break; + + case HAL_RTC_TAMPER3_EVENT_CB_ID : + hrtc->Tamper3EventCallback = pCallback; + break; + + case HAL_RTC_TAMPER4_EVENT_CB_ID : + hrtc->Tamper4EventCallback = pCallback; + break; + + case HAL_RTC_TAMPER5_EVENT_CB_ID : + hrtc->Tamper5EventCallback = pCallback; + break; + + case HAL_RTC_TAMPER6_EVENT_CB_ID : + hrtc->Tamper6EventCallback = pCallback; + break; + + case HAL_RTC_TAMPER7_EVENT_CB_ID : + hrtc->Tamper7EventCallback = pCallback; + break; + + case HAL_RTC_TAMPER8_EVENT_CB_ID : + hrtc->Tamper8EventCallback = pCallback; + break; + + case HAL_RTC_INTERNAL_TAMPER1_EVENT_CB_ID : + hrtc->InternalTamper1EventCallback = pCallback; + break; + + case HAL_RTC_INTERNAL_TAMPER2_EVENT_CB_ID : + hrtc->InternalTamper2EventCallback = pCallback; + break; + + case HAL_RTC_INTERNAL_TAMPER3_EVENT_CB_ID : + hrtc->InternalTamper3EventCallback = pCallback; + break; + + case HAL_RTC_INTERNAL_TAMPER4_EVENT_CB_ID : + hrtc->InternalTamper4EventCallback = pCallback; + break; + + case HAL_RTC_INTERNAL_TAMPER5_EVENT_CB_ID : + hrtc->InternalTamper5EventCallback = pCallback; + break; + + case HAL_RTC_INTERNAL_TAMPER6_EVENT_CB_ID : + hrtc->InternalTamper6EventCallback = pCallback; + break; + + case HAL_RTC_INTERNAL_TAMPER7_EVENT_CB_ID : + hrtc->InternalTamper7EventCallback = pCallback; + break; + + case HAL_RTC_INTERNAL_TAMPER8_EVENT_CB_ID : + hrtc->InternalTamper8EventCallback = pCallback; + break; + + case HAL_RTC_INTERNAL_TAMPER9_EVENT_CB_ID : + hrtc->InternalTamper9EventCallback = pCallback; + break; + + case HAL_RTC_INTERNAL_TAMPER11_EVENT_CB_ID : + hrtc->InternalTamper11EventCallback = pCallback; + break; + + case HAL_RTC_INTERNAL_TAMPER12_EVENT_CB_ID : + hrtc->InternalTamper12EventCallback = pCallback; + break; + + case HAL_RTC_INTERNAL_TAMPER13_EVENT_CB_ID : + hrtc->InternalTamper13EventCallback = pCallback; + break; + + case HAL_RTC_INTERNAL_TAMPER15_EVENT_CB_ID : + hrtc->InternalTamper15EventCallback = pCallback; + break; + + case HAL_RTC_MSPINIT_CB_ID : + hrtc->MspInitCallback = pCallback; + break; + + case HAL_RTC_MSPDEINIT_CB_ID : + hrtc->MspDeInitCallback = pCallback; + break; + + default : + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_RTC_STATE_RESET == hrtc->State) + { + switch (CallbackID) + { + case HAL_RTC_MSPINIT_CB_ID : + hrtc->MspInitCallback = pCallback; + break; + + case HAL_RTC_MSPDEINIT_CB_ID : + hrtc->MspDeInitCallback = pCallback; + break; + + default : + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister an RTC Callback + * RTC callback is redirected to the weak predefined callback + * @param hrtc RTC handle + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * This parameter can be one of the following values: + * @arg @ref HAL_RTC_ALARM_A_EVENT_CB_ID Alarm A Event Callback ID + * @arg @ref HAL_RTC_ALARM_B_EVENT_CB_ID Alarm B Event Callback ID + * @arg @ref HAL_RTC_TIMESTAMP_EVENT_CB_ID TimeStamp Event Callback ID + * @arg @ref HAL_RTC_SSRU_EVENT_CB_ID SSRU Callback ID + * @arg @ref HAL_RTC_WAKEUPTIMER_EVENT_CB_ID WakeUp Timer Event Callback ID + * @arg @ref HAL_RTC_TAMPER1_EVENT_CB_ID Tamper 1 Callback ID + * @arg @ref HAL_RTC_TAMPER2_EVENT_CB_ID Tamper 2 Callback ID + * @arg @ref HAL_RTC_TAMPER3_EVENT_CB_ID Tamper 3 Callback ID + * @arg @ref HAL_RTC_TAMPER4_EVENT_CB_ID Tamper 4 Callback ID + * @arg @ref HAL_RTC_TAMPER5_EVENT_CB_ID Tamper 5 Callback ID + * @arg @ref HAL_RTC_TAMPER6_EVENT_CB_ID Tamper 6 Callback ID + * @arg @ref HAL_RTC_TAMPER7_EVENT_CB_ID Tamper 7 Callback ID + * @arg @ref HAL_RTC_TAMPER8_EVENT_CB_ID Tamper 8 Callback ID + * @arg @ref HAL_RTC_INTERNAL_TAMPER1_EVENT_CB_ID Internal Tamper 1 Callback ID + * @arg @ref HAL_RTC_INTERNAL_TAMPER2_EVENT_CB_ID Internal Tamper 2 Callback ID + * @arg @ref HAL_RTC_INTERNAL_TAMPER3_EVENT_CB_ID Internal Tamper 3 Callback ID + * @arg @ref HAL_RTC_INTERNAL_TAMPER4_EVENT_CB_ID Internal Tamper 4 Callback ID + * @arg @ref HAL_RTC_INTERNAL_TAMPER5_EVENT_CB_ID Internal Tamper 5 Callback ID + * @arg @ref HAL_RTC_INTERNAL_TAMPER6_EVENT_CB_ID Internal Tamper 6 Callback ID + * @arg @ref HAL_RTC_INTERNAL_TAMPER7_EVENT_CB_ID Internal Tamper 7 Callback ID + * @arg @ref HAL_RTC_INTERNAL_TAMPER8_EVENT_CB_ID Internal Tamper 8 Callback ID + * @arg @ref HAL_RTC_INTERNAL_TAMPER9_EVENT_CB_ID Internal Tamper 9 Callback ID + * @arg @ref HAL_RTC_INTERNAL_TAMPER11_EVENT_CB_ID Internal Tamper 11 Callback ID + * @arg @ref HAL_RTC_INTERNAL_TAMPER12_EVENT_CB_ID Internal Tamper 12 Callback ID + * @arg @ref HAL_RTC_INTERNAL_TAMPER13_EVENT_CB_ID Internal Tamper 13 Callback ID + * @arg @ref HAL_RTC_INTERNAL_TAMPER15_EVENT_CB_ID Internal Tamper 15 Callback ID + * @arg @ref HAL_RTC_MSPINIT_CB_ID Msp Init callback ID + * @arg @ref HAL_RTC_MSPDEINIT_CB_ID Msp DeInit callback ID + * @note The HAL_RTC_UnRegisterCallback() may be called before HAL_RTC_Init() in HAL_RTC_STATE_RESET + * to un-register callbacks for HAL_RTC_MSPINIT_CB_ID and HAL_RTC_MSPDEINIT_CB_ID. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTC_UnRegisterCallback(RTC_HandleTypeDef *hrtc, HAL_RTC_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (HAL_RTC_STATE_READY == hrtc->State) + { + switch (CallbackID) + { + case HAL_RTC_ALARM_A_EVENT_CB_ID : + /* Legacy weak AlarmAEventCallback */ + hrtc->AlarmAEventCallback = HAL_RTC_AlarmAEventCallback; + break; + + case HAL_RTC_ALARM_B_EVENT_CB_ID : + /* Legacy weak AlarmBEventCallback */ + hrtc->AlarmBEventCallback = HAL_RTCEx_AlarmBEventCallback; + break; + + case HAL_RTC_TIMESTAMP_EVENT_CB_ID : + /* Legacy weak TimeStampEventCallback */ + hrtc->TimeStampEventCallback = HAL_RTCEx_TimeStampEventCallback; + break; + + case HAL_RTC_WAKEUPTIMER_EVENT_CB_ID : + /* Legacy weak WakeUpTimerEventCallback */ + hrtc->WakeUpTimerEventCallback = HAL_RTCEx_WakeUpTimerEventCallback; + break; + + case HAL_RTC_SSRU_EVENT_CB_ID : + /* Legacy weak SSRUEventCallback */ + hrtc->SSRUEventCallback = HAL_RTCEx_SSRUEventCallback; + break; + + case HAL_RTC_TAMPER1_EVENT_CB_ID : + /* Legacy weak Tamper1EventCallback */ + hrtc->Tamper1EventCallback = HAL_RTCEx_Tamper1EventCallback; + break; + + case HAL_RTC_TAMPER2_EVENT_CB_ID : + /* Legacy weak Tamper2EventCallback */ + hrtc->Tamper2EventCallback = HAL_RTCEx_Tamper2EventCallback; + break; + + case HAL_RTC_TAMPER3_EVENT_CB_ID : + /* Legacy weak Tamper3EventCallback */ + hrtc->Tamper3EventCallback = HAL_RTCEx_Tamper3EventCallback; + break; + + case HAL_RTC_TAMPER4_EVENT_CB_ID : + /* Legacy weak Tamper4EventCallback */ + hrtc->Tamper4EventCallback = HAL_RTCEx_Tamper4EventCallback; + break; + + case HAL_RTC_TAMPER5_EVENT_CB_ID : + /* Legacy weak Tamper5EventCallback */ + hrtc->Tamper5EventCallback = HAL_RTCEx_Tamper5EventCallback; + break; + + case HAL_RTC_TAMPER6_EVENT_CB_ID : + /* Legacy weak Tamper6EventCallback */ + hrtc->Tamper6EventCallback = HAL_RTCEx_Tamper6EventCallback; + break; + + case HAL_RTC_TAMPER7_EVENT_CB_ID : + /* Legacy weak Tamper7EventCallback */ + hrtc->Tamper7EventCallback = HAL_RTCEx_Tamper7EventCallback; + break; + + case HAL_RTC_TAMPER8_EVENT_CB_ID : + /* Legacy weak Tamper8EventCallback */ + hrtc->Tamper8EventCallback = HAL_RTCEx_Tamper8EventCallback; + break; + + case HAL_RTC_INTERNAL_TAMPER1_EVENT_CB_ID : + /* Legacy weak InternalTamper1EventCallback */ + hrtc->InternalTamper1EventCallback = HAL_RTCEx_InternalTamper1EventCallback; + break; + + case HAL_RTC_INTERNAL_TAMPER2_EVENT_CB_ID : + /* Legacy weak InternalTamper2EventCallback */ + hrtc->InternalTamper2EventCallback = HAL_RTCEx_InternalTamper2EventCallback; + break; + + case HAL_RTC_INTERNAL_TAMPER3_EVENT_CB_ID : + /* Legacy weak InternalTamper3EventCallback */ + hrtc->InternalTamper3EventCallback = HAL_RTCEx_InternalTamper3EventCallback; + break; + + case HAL_RTC_INTERNAL_TAMPER4_EVENT_CB_ID : + /* Legacy weak InternalTamper4EventCallback */ + hrtc->InternalTamper4EventCallback = HAL_RTCEx_InternalTamper4EventCallback; + break; + + case HAL_RTC_INTERNAL_TAMPER5_EVENT_CB_ID : + /* Legacy weak InternalTamper5EventCallback */ + hrtc->InternalTamper5EventCallback = HAL_RTCEx_InternalTamper5EventCallback; + break; + + case HAL_RTC_INTERNAL_TAMPER6_EVENT_CB_ID : + /* Legacy weak InternalTamper6EventCallback */ + hrtc->InternalTamper6EventCallback = HAL_RTCEx_InternalTamper6EventCallback; + break; + + case HAL_RTC_INTERNAL_TAMPER7_EVENT_CB_ID : + /* Legacy weak InternalTamper7EventCallback */ + hrtc->InternalTamper7EventCallback = HAL_RTCEx_InternalTamper7EventCallback; + break; + + case HAL_RTC_INTERNAL_TAMPER8_EVENT_CB_ID : + /* Legacy weak InternalTamper8EventCallback */ + hrtc->InternalTamper8EventCallback = HAL_RTCEx_InternalTamper8EventCallback; + break; + + case HAL_RTC_INTERNAL_TAMPER9_EVENT_CB_ID : + /* Legacy weak InternalTamper9EventCallback */ + hrtc->InternalTamper9EventCallback = HAL_RTCEx_InternalTamper9EventCallback; + break; + + case HAL_RTC_INTERNAL_TAMPER11_EVENT_CB_ID : + /* Legacy weak InternalTamper11EventCallback */ + hrtc->InternalTamper11EventCallback = HAL_RTCEx_InternalTamper11EventCallback; + break; + + case HAL_RTC_INTERNAL_TAMPER12_EVENT_CB_ID : + /* Legacy weak InternalTamper12EventCallback */ + hrtc->InternalTamper12EventCallback = HAL_RTCEx_InternalTamper12EventCallback; + break; + + case HAL_RTC_INTERNAL_TAMPER13_EVENT_CB_ID : + /* Legacy weak InternalTamper13EventCallback */ + hrtc->InternalTamper13EventCallback = HAL_RTCEx_InternalTamper13EventCallback; + break; + + case HAL_RTC_INTERNAL_TAMPER15_EVENT_CB_ID : + /* Legacy weak InternalTamper15EventCallback */ + hrtc->InternalTamper15EventCallback = HAL_RTCEx_InternalTamper15EventCallback; + break; + + case HAL_RTC_MSPINIT_CB_ID : + hrtc->MspInitCallback = HAL_RTC_MspInit; + break; + + case HAL_RTC_MSPDEINIT_CB_ID : + hrtc->MspDeInitCallback = HAL_RTC_MspDeInit; + break; + + default : + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_RTC_STATE_RESET == hrtc->State) + { + switch (CallbackID) + { + case HAL_RTC_MSPINIT_CB_ID : + hrtc->MspInitCallback = HAL_RTC_MspInit; + break; + + case HAL_RTC_MSPDEINIT_CB_ID : + hrtc->MspDeInitCallback = HAL_RTC_MspDeInit; + break; + + default : + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + +/** + * @brief Initialize the RTC MSP. + * @param hrtc RTC handle + * @retval None + */ +__weak void HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RTC_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitialize the RTC MSP. + * @param hrtc RTC handle + * @retval None + */ +__weak void HAL_RTC_MspDeInit(RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RTC_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @addtogroup RTC_Exported_Functions_Group2 + * @brief RTC Time and Date functions + * +@verbatim + =============================================================================== + ##### RTC Time and Date functions ##### + =============================================================================== + + [..] This section provides functions allowing to configure Time and Date features + +@endverbatim + * @{ + */ + +/** + * @brief Set RTC current time. + * @param hrtc RTC handle + * @param sTime Pointer to Time structure + * if Binary mode is RTC_BINARY_ONLY, this parameter is not used and RTC_SSR will be automatically + * reset to 0xFFFFFFFF + * else sTime->SubSeconds is not used and RTC_SSR will be automatically reset to the + * A 7-bit async prescaler (RTC_PRER_PREDIV_A) + * @param Format Format of sTime->Hours, sTime->Minutes and sTime->Seconds. + * if Binary mode is RTC_BINARY_ONLY, this parameter is not used + * else this parameter can be one of the following values + * @arg RTC_FORMAT_BIN: Binary format + * @arg RTC_FORMAT_BCD: BCD format + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTC_SetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format) +{ + uint32_t tmpreg; + HAL_StatusTypeDef status; + +#ifdef USE_FULL_ASSERT + /* Check the parameters depending of the Binary mode with 32-bit free-running counter configuration */ + if (READ_BIT(RTC->ICSR, RTC_ICSR_BIN) == RTC_BINARY_NONE) + { + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(Format)); + } +#endif /* USE_FULL_ASSERT */ + + /* Process Locked */ + __HAL_LOCK(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Enter Initialization mode */ + status = RTC_EnterInitMode(hrtc); + if (status == HAL_OK) + { + /* Check Binary mode ((32-bit free-running counter) */ + if (READ_BIT(RTC->ICSR, RTC_ICSR_BIN) != RTC_BINARY_ONLY) + { + if (Format == RTC_FORMAT_BIN) + { + if (READ_BIT(RTC->CR, RTC_CR_FMT) != 0U) + { + assert_param(IS_RTC_HOUR12(sTime->Hours)); + assert_param(IS_RTC_HOURFORMAT12(sTime->TimeFormat)); + } + else + { + sTime->TimeFormat = 0x00U; + assert_param(IS_RTC_HOUR24(sTime->Hours)); + } + assert_param(IS_RTC_MINUTES(sTime->Minutes)); + assert_param(IS_RTC_SECONDS(sTime->Seconds)); + + tmpreg = (uint32_t)(((uint32_t)RTC_ByteToBcd2(sTime->Hours) << RTC_TR_HU_Pos) | \ + ((uint32_t)RTC_ByteToBcd2(sTime->Minutes) << RTC_TR_MNU_Pos) | \ + ((uint32_t)RTC_ByteToBcd2(sTime->Seconds) << RTC_TR_SU_Pos) | \ + (((uint32_t)sTime->TimeFormat) << RTC_TR_PM_Pos)); + } + else + { + if (READ_BIT(RTC->CR, RTC_CR_FMT) != 0U) + { + assert_param(IS_RTC_HOUR12(RTC_Bcd2ToByte(sTime->Hours))); + assert_param(IS_RTC_HOURFORMAT12(sTime->TimeFormat)); + } + else + { + sTime->TimeFormat = 0x00U; + assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sTime->Hours))); + } + assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sTime->Minutes))); + assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sTime->Seconds))); + tmpreg = (((uint32_t)(sTime->Hours) << RTC_TR_HU_Pos) | \ + ((uint32_t)(sTime->Minutes) << RTC_TR_MNU_Pos) | \ + ((uint32_t)(sTime->Seconds) << RTC_TR_SU_Pos) | \ + ((uint32_t)(sTime->TimeFormat) << RTC_TR_PM_Pos)); + } + + /* Set the RTC_TR register */ + WRITE_REG(RTC->TR, (tmpreg & RTC_TR_RESERVED_MASK)); + + /* Clear the bits to be configured */ + CLEAR_BIT(RTC->CR, RTC_CR_BKP); + } + + /* Exit Initialization mode */ + status = RTC_ExitInitMode(hrtc); + } + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + if (status == HAL_OK) + { + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return status; +} + +/** + * @brief Get RTC current time. + * @note You can use SubSeconds and SecondFraction (sTime structure fields returned) to convert SubSeconds + * value in second fraction ratio with time unit following generic formula: + * Second fraction ratio * time_unit= [(SecondFraction-SubSeconds)/(SecondFraction+1)] * time_unit + * This conversion can be performed only if no shift operation is pending (ie. SHFP=0) when PREDIV_S >= SS + * @note You must call HAL_RTC_GetDate() after HAL_RTC_GetTime() to unlock the values + * in the higher-order calendar shadow registers to ensure consistency between the time and date values. + * Reading RTC current time locks the values in calendar shadow registers until Current date is read + * to ensure consistency between the time and date values. + * @param hrtc RTC handle + * @param sTime + * if Binary mode is RTC_BINARY_ONLY, sTime->SubSeconds only is updated + * else + * Pointer to Time structure with Hours, Minutes and Seconds fields returned + * with input format (BIN or BCD), also SubSeconds field returning the + * RTC_SSR register content and SecondFraction field the Synchronous pre-scaler + * factor to be used for second fraction ratio computation. + * @param Format Format of sTime->Hours, sTime->Minutes and sTime->Seconds. + * if Binary mode is RTC_BINARY_ONLY, this parameter is not used + * else this parameter can be one of the following values: + * @arg RTC_FORMAT_BIN: Binary format + * @arg RTC_FORMAT_BCD: BCD format + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTC_GetTime(const RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format) +{ + uint32_t tmpreg; + + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* Get subseconds structure field from the corresponding register */ + sTime->SubSeconds = READ_REG(RTC->SSR); + + if (READ_BIT(RTC->ICSR, RTC_ICSR_BIN) != RTC_BINARY_ONLY) + { + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(Format)); + + /* Get SecondFraction structure field from the corresponding register field */ + sTime->SecondFraction = (uint32_t)(READ_REG(RTC->PRER) & RTC_PRER_PREDIV_S); + + /* Get the TR register */ + tmpreg = (uint32_t)(READ_REG(RTC->TR) & RTC_TR_RESERVED_MASK); + + /* Fill the structure fields with the read parameters */ + sTime->Hours = (uint8_t)((tmpreg & (RTC_TR_HT | RTC_TR_HU)) >> RTC_TR_HU_Pos); + sTime->Minutes = (uint8_t)((tmpreg & (RTC_TR_MNT | RTC_TR_MNU)) >> RTC_TR_MNU_Pos); + sTime->Seconds = (uint8_t)((tmpreg & (RTC_TR_ST | RTC_TR_SU)) >> RTC_TR_SU_Pos); + sTime->TimeFormat = (uint8_t)((tmpreg & (RTC_TR_PM)) >> RTC_TR_PM_Pos); + + /* Check the input parameters format */ + if (Format == RTC_FORMAT_BIN) + { + /* Convert the time structure parameters to Binary format */ + sTime->Hours = (uint8_t)RTC_Bcd2ToByte(sTime->Hours); + sTime->Minutes = (uint8_t)RTC_Bcd2ToByte(sTime->Minutes); + sTime->Seconds = (uint8_t)RTC_Bcd2ToByte(sTime->Seconds); + } + } + + return HAL_OK; +} + +/** + * @brief Set RTC current date. + * @param hrtc RTC handle + * @param sDate Pointer to date structure + * @param Format Format of sDate->Year, sDate->Month and sDate->Weekday. + * This parameter can be one of the following values: + * @arg RTC_FORMAT_BIN: Binary format + * @arg RTC_FORMAT_BCD: BCD format + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTC_SetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format) +{ + uint32_t datetmpreg; + HAL_StatusTypeDef status; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(Format)); + + /* Process Locked */ + __HAL_LOCK(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_BUSY; + + if ((Format == RTC_FORMAT_BIN) && ((sDate->Month & 0x10U) == 0x10U)) + { + sDate->Month = (uint8_t)((sDate->Month & (uint8_t)~(0x10U)) + (uint8_t)0x0AU); + } + + assert_param(IS_RTC_WEEKDAY(sDate->WeekDay)); + + if (Format == RTC_FORMAT_BIN) + { + assert_param(IS_RTC_YEAR(sDate->Year)); + assert_param(IS_RTC_MONTH(sDate->Month)); + assert_param(IS_RTC_DATE(sDate->Date)); + + datetmpreg = (((uint32_t)RTC_ByteToBcd2(sDate->Year) << RTC_DR_YU_Pos) | \ + ((uint32_t)RTC_ByteToBcd2(sDate->Month) << RTC_DR_MU_Pos) | \ + ((uint32_t)RTC_ByteToBcd2(sDate->Date) << RTC_DR_DU_Pos) | \ + ((uint32_t)sDate->WeekDay << RTC_DR_WDU_Pos)); + } + else + { + assert_param(IS_RTC_YEAR(RTC_Bcd2ToByte(sDate->Year))); + assert_param(IS_RTC_MONTH(RTC_Bcd2ToByte(sDate->Month))); + assert_param(IS_RTC_DATE(RTC_Bcd2ToByte(sDate->Date))); + + datetmpreg = ((((uint32_t)sDate->Year) << RTC_DR_YU_Pos) | \ + (((uint32_t)sDate->Month) << RTC_DR_MU_Pos) | \ + (((uint32_t)sDate->Date) << RTC_DR_DU_Pos) | \ + (((uint32_t)sDate->WeekDay) << RTC_DR_WDU_Pos)); + } + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Enter Initialization mode */ + status = RTC_EnterInitMode(hrtc); + if (status == HAL_OK) + { + /* Set the RTC_DR register */ + WRITE_REG(RTC->DR, (uint32_t)(datetmpreg & RTC_DR_RESERVED_MASK)); + + /* Exit Initialization mode */ + status = RTC_ExitInitMode(hrtc); + } + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + if (status == HAL_OK) + { + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return status; +} + +/** + * @brief Get RTC current date. + * @note You must call HAL_RTC_GetDate() after HAL_RTC_GetTime() to unlock the values + * in the higher-order calendar shadow registers to ensure consistency between the time and date values. + * Reading RTC current time locks the values in calendar shadow registers until Current date is read. + * @param hrtc RTC handle + * @param sDate Pointer to Date structure + * @param Format Format of sDate->Year, sDate->Month and sDate->Weekday. + * This parameter can be one of the following values: + * @arg RTC_FORMAT_BIN: Binary format + * @arg RTC_FORMAT_BCD: BCD format + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTC_GetDate(const RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format) +{ + uint32_t datetmpreg; + + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(Format)); + + /* Get the DR register */ + datetmpreg = (uint32_t)(READ_REG(RTC->DR) & RTC_DR_RESERVED_MASK); + + /* Fill the structure fields with the read parameters */ + sDate->Year = (uint8_t)((datetmpreg & (RTC_DR_YT | RTC_DR_YU)) >> RTC_DR_YU_Pos); + sDate->Month = (uint8_t)((datetmpreg & (RTC_DR_MT | RTC_DR_MU)) >> RTC_DR_MU_Pos); + sDate->Date = (uint8_t)((datetmpreg & (RTC_DR_DT | RTC_DR_DU)) >> RTC_DR_DU_Pos); + sDate->WeekDay = (uint8_t)((datetmpreg & (RTC_DR_WDU)) >> RTC_DR_WDU_Pos); + + /* Check the input parameters format */ + if (Format == RTC_FORMAT_BIN) + { + /* Convert the date structure parameters to Binary format */ + sDate->Year = (uint8_t)RTC_Bcd2ToByte(sDate->Year); + sDate->Month = (uint8_t)RTC_Bcd2ToByte(sDate->Month); + sDate->Date = (uint8_t)RTC_Bcd2ToByte(sDate->Date); + } + return HAL_OK; +} + +/** + * @brief Daylight Saving Time, Add one hour to the calendar in one single operation + * without going through the initialization procedure. + * @param hrtc RTC handle + * @retval None + */ +void HAL_RTC_DST_Add1Hour(const RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Set RTC_CR_ADD1H Bit */ + SET_BIT(RTC->CR, RTC_CR_ADD1H); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); +} + +/** + * @brief Daylight Saving Time, Subtract one hour from the calendar in one + * single operation without going through the initialization procedure. + * @param hrtc RTC handle + * @retval None + */ +void HAL_RTC_DST_Sub1Hour(const RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Set RTC_CR_SUB1H Bit */ + SET_BIT(RTC->CR, RTC_CR_SUB1H); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); +} + +/** + * @brief Daylight Saving Time, Set the store operation bit. + * @note It can be used by the software in order to memorize the DST status. + * @param hrtc RTC handle + * @retval None + */ +void HAL_RTC_DST_SetStoreOperation(const RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Set RTC_CR_BKP Bit */ + SET_BIT(RTC->CR, RTC_CR_BKP); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); +} + +/** + * @brief Daylight Saving Time, Clear the store operation bit. + * @param hrtc RTC handle + * @retval None + */ +void HAL_RTC_DST_ClearStoreOperation(const RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Clear RTC_CR_BKP Bit */ + CLEAR_BIT(RTC->CR, RTC_CR_BKP); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); +} + +/** + * @brief Daylight Saving Time, Read the store operation bit. + * @param hrtc RTC handle + * @retval operation see RTC_StoreOperation_Definitions + */ +uint32_t HAL_RTC_DST_ReadStoreOperation(const RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* Get RTC_CR_BKP Bit */ + return READ_BIT(RTC->CR, RTC_CR_BKP); +} + + +/** + * @} + */ + +/** @addtogroup RTC_Exported_Functions_Group3 + * @brief RTC Alarm functions + * +@verbatim + =============================================================================== + ##### RTC Alarm functions ##### + =============================================================================== + + [..] This section provides functions allowing to configure Alarm feature + +@endverbatim + * @{ + */ +/** + * @brief Set the specified RTC Alarm. + * @param hrtc RTC handle + * @param sAlarm Pointer to Alarm structure + * if Binary mode is RTC_BINARY_ONLY, 3 fields only are used + * sAlarm->AlarmTime.SubSeconds + * sAlarm->AlarmSubSecondMask + * sAlarm->BinaryAutoClr + * @param Format of the entered parameters. + * if Binary mode is RTC_BINARY_ONLY, this parameter is not used + * else this parameter can be one of the following values + * @arg RTC_FORMAT_BIN: Binary format + * @arg RTC_FORMAT_BCD: BCD format + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTC_SetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format) +{ + uint32_t tmpreg = 0; + uint32_t binary_mode; + + /* Process Locked */ + __HAL_LOCK(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_BUSY; + +#ifdef USE_FULL_ASSERT + /* Check the parameters depending of the Binary mode (32-bit free-running counter configuration) */ + if (READ_BIT(RTC->ICSR, RTC_ICSR_BIN) == RTC_BINARY_NONE) + { + assert_param(IS_RTC_FORMAT(Format)); + assert_param(IS_RTC_ALARM(sAlarm->Alarm)); + assert_param(IS_RTC_ALARM_MASK(sAlarm->AlarmMask)); + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_SEL(sAlarm->AlarmDateWeekDaySel)); + assert_param(IS_RTC_ALARM_SUB_SECOND_VALUE(sAlarm->AlarmTime.SubSeconds)); + assert_param(IS_RTC_ALARM_SUB_SECOND_MASK(sAlarm->AlarmSubSecondMask)); + } + else if (READ_BIT(RTC->ICSR, RTC_ICSR_BIN) == RTC_BINARY_ONLY) + { + assert_param(IS_RTC_ALARM_SUB_SECOND_BINARY_MASK(sAlarm->AlarmSubSecondMask)); + assert_param(IS_RTC_ALARMSUBSECONDBIN_AUTOCLR(sAlarm->BinaryAutoClr)); + } + else /* RTC_BINARY_MIX */ + { + assert_param(IS_RTC_FORMAT(Format)); + assert_param(IS_RTC_ALARM(sAlarm->Alarm)); + assert_param(IS_RTC_ALARM_MASK(sAlarm->AlarmMask)); + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_SEL(sAlarm->AlarmDateWeekDaySel)); + /* In Binary Mix Mode, the RTC can not generate an alarm on a match + involving all calendar items + the upper SSR bits */ + assert_param((sAlarm->AlarmSubSecondMask >> RTC_ALRMASSR_MASKSS_Pos) <= + (8U + (READ_BIT(RTC->ICSR, RTC_ICSR_BCDU) >> RTC_ICSR_BCDU_Pos))); + } +#endif /* USE_FULL_ASSERT */ + + /* Get Binary mode (32-bit free-running counter configuration) */ + binary_mode = READ_BIT(RTC->ICSR, RTC_ICSR_BIN); + + if (binary_mode != RTC_BINARY_ONLY) + { + if (Format == RTC_FORMAT_BIN) + { + if (READ_BIT(RTC->CR, RTC_CR_FMT) != 0U) + { + assert_param(IS_RTC_HOUR12(sAlarm->AlarmTime.Hours)); + assert_param(IS_RTC_HOURFORMAT12(sAlarm->AlarmTime.TimeFormat)); + } + else + { + sAlarm->AlarmTime.TimeFormat = 0x00U; + assert_param(IS_RTC_HOUR24(sAlarm->AlarmTime.Hours)); + } + assert_param(IS_RTC_MINUTES(sAlarm->AlarmTime.Minutes)); + assert_param(IS_RTC_SECONDS(sAlarm->AlarmTime.Seconds)); + + if (sAlarm->AlarmDateWeekDaySel == RTC_ALARMDATEWEEKDAYSEL_DATE) + { + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(sAlarm->AlarmDateWeekDay)); + } + else + { + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(sAlarm->AlarmDateWeekDay)); + } + tmpreg = (((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Hours) << RTC_ALRMAR_HU_Pos) | \ + ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Minutes) << RTC_ALRMAR_MNU_Pos) | \ + ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Seconds) << RTC_ALRMAR_SU_Pos) | \ + ((uint32_t)(sAlarm->AlarmTime.TimeFormat) << RTC_ALRMAR_PM_Pos) | \ + ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmDateWeekDay) << RTC_ALRMAR_DU_Pos) | \ + ((uint32_t)sAlarm->AlarmDateWeekDaySel) | \ + ((uint32_t)sAlarm->AlarmMask)); + } + else /* format BCD */ + { + if (READ_BIT(RTC->CR, RTC_CR_FMT) != 0U) + { + assert_param(IS_RTC_HOUR12(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours))); + assert_param(IS_RTC_HOURFORMAT12(sAlarm->AlarmTime.TimeFormat)); + } + else + { + sAlarm->AlarmTime.TimeFormat = 0x00U; + assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours))); + } + + assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes))); + assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds))); + +#ifdef USE_FULL_ASSERT + if (sAlarm->AlarmDateWeekDaySel == RTC_ALARMDATEWEEKDAYSEL_DATE) + { + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(RTC_Bcd2ToByte(sAlarm->AlarmDateWeekDay))); + } + else + { + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(RTC_Bcd2ToByte(sAlarm->AlarmDateWeekDay))); + } + +#endif /* USE_FULL_ASSERT */ + tmpreg = (((uint32_t)(sAlarm->AlarmTime.Hours) << RTC_ALRMAR_HU_Pos) | \ + ((uint32_t)(sAlarm->AlarmTime.Minutes) << RTC_ALRMAR_MNU_Pos) | \ + ((uint32_t)(sAlarm->AlarmTime.Seconds) << RTC_ALRMAR_SU_Pos) | \ + ((uint32_t)(sAlarm->AlarmTime.TimeFormat) << RTC_ALRMAR_PM_Pos) | \ + ((uint32_t)(sAlarm->AlarmDateWeekDay) << RTC_ALRMAR_DU_Pos) | \ + ((uint32_t)sAlarm->AlarmDateWeekDaySel) | \ + ((uint32_t)sAlarm->AlarmMask)); + } + } + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Configure the Alarm register */ + if (sAlarm->Alarm == RTC_ALARM_A) + { + /* Disable the Alarm A interrupt */ + + /* In case of interrupt mode is used, the interrupt source must disabled */ + CLEAR_BIT(RTC->CR, (RTC_CR_ALRAE | RTC_CR_ALRAIE)); + + /* Clear flag alarm A */ + WRITE_REG(RTC->SCR, RTC_SCR_CALRAF); + + if (binary_mode == RTC_BINARY_ONLY) + { + WRITE_REG(RTC->ALRMASSR, sAlarm->AlarmSubSecondMask | sAlarm->BinaryAutoClr); + } + else + { + WRITE_REG(RTC->ALRMAR, tmpreg); + WRITE_REG(RTC->ALRMASSR, sAlarm->AlarmSubSecondMask); + } + + WRITE_REG(RTC->ALRABINR, sAlarm->AlarmTime.SubSeconds); + + if (sAlarm->FlagAutoClr == ALARM_FLAG_AUTOCLR_ENABLE) + { + /* Configure the Alarm A output clear */ + SET_BIT(RTC->CR, RTC_CR_ALRAFCLR); + } + else + { + /* Disable the Alarm A output clear */ + CLEAR_BIT(RTC->CR, RTC_CR_ALRAFCLR); + } + /* Configure the Alarm state: Enable Alarm */ + SET_BIT(RTC->CR, RTC_CR_ALRAE); + } + else + { + /* Disable the Alarm B interrupt */ + + /* In case of interrupt mode is used, the interrupt source must disabled */ + CLEAR_BIT(RTC->CR, (RTC_CR_ALRBE | RTC_CR_ALRBIE)); + + /* Clear flag alarm B */ + WRITE_REG(RTC->SCR, RTC_SCR_CALRBF); + + if (binary_mode == RTC_BINARY_ONLY) + { + WRITE_REG(RTC->ALRMBSSR, sAlarm->AlarmSubSecondMask | sAlarm->BinaryAutoClr); + } + else + { + WRITE_REG(RTC->ALRMBR, tmpreg); + + WRITE_REG(RTC->ALRMBSSR, sAlarm->AlarmSubSecondMask); + } + + WRITE_REG(RTC->ALRBBINR, sAlarm->AlarmTime.SubSeconds); + + if (sAlarm->FlagAutoClr == ALARM_FLAG_AUTOCLR_ENABLE) + { + /* Configure the Alarm B output clear */ + SET_BIT(RTC->CR, RTC_CR_ALRBFCLR); + } + else + { + /* Disable the Alarm B output clear */ + CLEAR_BIT(RTC->CR, RTC_CR_ALRBFCLR); + } + + /* Configure the Alarm state: Enable Alarm */ + SET_BIT(RTC->CR, RTC_CR_ALRBE); + } + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Set the specified RTC Alarm with Interrupt. + * @note The application must ensure that the EXTI RTC interrupt line is enabled. + * @param hrtc RTC handle + * @param sAlarm Pointer to Alarm structure + * if Binary mode is RTC_BINARY_ONLY, 3 fields only are used + * sAlarm->AlarmTime.SubSeconds + * sAlarm->AlarmSubSecondMask + * sAlarm->BinaryAutoClr + * @param Format Specifies the format of the entered parameters. + * if Binary mode is RTC_BINARY_ONLY, this parameter is not used + * else this parameter can be one of the following values + * @arg RTC_FORMAT_BIN: Binary format + * @arg RTC_FORMAT_BCD: BCD format + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTC_SetAlarm_IT(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format) +{ + uint32_t tmpreg = 0; + uint32_t binary_mode; + + /* Process Locked */ + __HAL_LOCK(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_BUSY; + +#ifdef USE_FULL_ASSERT + /* Check the parameters depending of the Binary mode (32-bit free-running counter configuration) */ + if (READ_BIT(RTC->ICSR, RTC_ICSR_BIN) == RTC_BINARY_NONE) + { + assert_param(IS_RTC_FORMAT(Format)); + assert_param(IS_RTC_ALARM(sAlarm->Alarm)); + assert_param(IS_RTC_ALARM_MASK(sAlarm->AlarmMask)); + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_SEL(sAlarm->AlarmDateWeekDaySel)); + assert_param(IS_RTC_ALARM_SUB_SECOND_VALUE(sAlarm->AlarmTime.SubSeconds)); + assert_param(IS_RTC_ALARM_SUB_SECOND_MASK(sAlarm->AlarmSubSecondMask)); + } + else if (READ_BIT(RTC->ICSR, RTC_ICSR_BIN) == RTC_BINARY_ONLY) + { + assert_param(IS_RTC_ALARM_SUB_SECOND_BINARY_MASK(sAlarm->AlarmSubSecondMask)); + assert_param(IS_RTC_ALARMSUBSECONDBIN_AUTOCLR(sAlarm->BinaryAutoClr)); + } + else /* RTC_BINARY_MIX */ + { + assert_param(IS_RTC_FORMAT(Format)); + assert_param(IS_RTC_ALARM(sAlarm->Alarm)); + assert_param(IS_RTC_ALARM_MASK(sAlarm->AlarmMask)); + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_SEL(sAlarm->AlarmDateWeekDaySel)); + /* In Binary Mix Mode, the RTC can not generate an alarm on a match + involving all calendar items + the upper SSR bits */ + assert_param((sAlarm->AlarmSubSecondMask >> RTC_ALRMASSR_MASKSS_Pos) <= + (8U + (READ_BIT(RTC->ICSR, RTC_ICSR_BCDU) >> RTC_ICSR_BCDU_Pos))); + } +#endif /* USE_FULL_ASSERT */ + + /* Get Binary mode (32-bit free-running counter configuration) */ + binary_mode = READ_BIT(RTC->ICSR, RTC_ICSR_BIN); + + if (binary_mode != RTC_BINARY_ONLY) + { + if (Format == RTC_FORMAT_BIN) + { + if (READ_BIT(RTC->CR, RTC_CR_FMT) != 0U) + { + assert_param(IS_RTC_HOUR12(sAlarm->AlarmTime.Hours)); + assert_param(IS_RTC_HOURFORMAT12(sAlarm->AlarmTime.TimeFormat)); + } + else + { + sAlarm->AlarmTime.TimeFormat = 0x00U; + assert_param(IS_RTC_HOUR24(sAlarm->AlarmTime.Hours)); + } + assert_param(IS_RTC_MINUTES(sAlarm->AlarmTime.Minutes)); + assert_param(IS_RTC_SECONDS(sAlarm->AlarmTime.Seconds)); + + if (sAlarm->AlarmDateWeekDaySel == RTC_ALARMDATEWEEKDAYSEL_DATE) + { + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(sAlarm->AlarmDateWeekDay)); + } + else + { + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(sAlarm->AlarmDateWeekDay)); + } + tmpreg = (((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Hours) << RTC_ALRMAR_HU_Pos) | \ + ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Minutes) << RTC_ALRMAR_MNU_Pos) | \ + ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Seconds) << RTC_ALRMAR_SU_Pos) | \ + ((uint32_t)(sAlarm->AlarmTime.TimeFormat) << RTC_ALRMAR_PM_Pos) | \ + ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmDateWeekDay) << RTC_ALRMAR_DU_Pos) | \ + ((uint32_t)sAlarm->AlarmDateWeekDaySel) | \ + ((uint32_t)sAlarm->AlarmMask)); + } + else /* Format BCD */ + { + if (READ_BIT(RTC->CR, RTC_CR_FMT) != 0U) + { + assert_param(IS_RTC_HOUR12(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours))); + assert_param(IS_RTC_HOURFORMAT12(sAlarm->AlarmTime.TimeFormat)); + } + else + { + sAlarm->AlarmTime.TimeFormat = 0x00U; + assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours))); + } + + assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes))); + assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds))); + +#ifdef USE_FULL_ASSERT + if (sAlarm->AlarmDateWeekDaySel == RTC_ALARMDATEWEEKDAYSEL_DATE) + { + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(RTC_Bcd2ToByte(sAlarm->AlarmDateWeekDay))); + } + else + { + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(RTC_Bcd2ToByte(sAlarm->AlarmDateWeekDay))); + } + +#endif /* USE_FULL_ASSERT */ + tmpreg = (((uint32_t)(sAlarm->AlarmTime.Hours) << RTC_ALRMAR_HU_Pos) | \ + ((uint32_t)(sAlarm->AlarmTime.Minutes) << RTC_ALRMAR_MNU_Pos) | \ + ((uint32_t)(sAlarm->AlarmTime.Seconds) << RTC_ALRMAR_SU_Pos) | \ + ((uint32_t)(sAlarm->AlarmTime.TimeFormat) << RTC_ALRMAR_PM_Pos) | \ + ((uint32_t)(sAlarm->AlarmDateWeekDay) << RTC_ALRMAR_DU_Pos) | \ + ((uint32_t)sAlarm->AlarmDateWeekDaySel) | \ + ((uint32_t)sAlarm->AlarmMask)); + + } + } + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Configure the Alarm registers */ + if (sAlarm->Alarm == RTC_ALARM_A) + { + /* Disable the Alarm A interrupt */ + CLEAR_BIT(RTC->CR, RTC_CR_ALRAE | RTC_CR_ALRAIE); + + /* Clear flag alarm A */ + WRITE_REG(RTC->SCR, RTC_SCR_CALRAF); + + if (binary_mode == RTC_BINARY_ONLY) + { + RTC->ALRMASSR = sAlarm->AlarmSubSecondMask | sAlarm->BinaryAutoClr; + } + else + { + WRITE_REG(RTC->ALRMAR, tmpreg); + + WRITE_REG(RTC->ALRMASSR, sAlarm->AlarmSubSecondMask); + } + + WRITE_REG(RTC->ALRABINR, sAlarm->AlarmTime.SubSeconds); + + if (sAlarm->FlagAutoClr == ALARM_FLAG_AUTOCLR_ENABLE) + { + /* Configure the Alarm A output clear */ + SET_BIT(RTC->CR, RTC_CR_ALRAFCLR); + } + else + { + /* Disable the Alarm A output clear */ + CLEAR_BIT(RTC->CR, RTC_CR_ALRAFCLR); + } + + /* Configure the Alarm interrupt */ + SET_BIT(RTC->CR, RTC_CR_ALRAE | RTC_CR_ALRAIE); + } + else + { + /* Disable the Alarm B interrupt */ + CLEAR_BIT(RTC->CR, RTC_CR_ALRBE | RTC_CR_ALRBIE); + + /* Clear flag alarm B */ + WRITE_REG(RTC->SCR, RTC_SCR_CALRBF); + + if (binary_mode == RTC_BINARY_ONLY) + { + WRITE_REG(RTC->ALRMBSSR, sAlarm->AlarmSubSecondMask | sAlarm->BinaryAutoClr); + } + else + { + WRITE_REG(RTC->ALRMBR, tmpreg); + + WRITE_REG(RTC->ALRMBSSR, sAlarm->AlarmSubSecondMask); + } + + WRITE_REG(RTC->ALRBBINR, sAlarm->AlarmTime.SubSeconds); + + if (sAlarm->FlagAutoClr == ALARM_FLAG_AUTOCLR_ENABLE) + { + /* Configure the Alarm B Output clear */ + SET_BIT(RTC->CR, RTC_CR_ALRBFCLR); + } + else + { + /* Disable the Alarm B Output clear */ + CLEAR_BIT(RTC->CR, RTC_CR_ALRBFCLR); + } + + /* Configure the Alarm interrupt */ + SET_BIT(RTC->CR, RTC_CR_ALRBE | RTC_CR_ALRBIE); + } + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Deactivate the specified RTC Alarm. + * @param hrtc RTC handle + * @param Alarm Specifies the Alarm. + * This parameter can be one of the following values: + * @arg RTC_ALARM_A: AlarmA + * @arg RTC_ALARM_B: AlarmB + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTC_DeactivateAlarm(RTC_HandleTypeDef *hrtc, uint32_t Alarm) +{ + /* Check the parameters */ + assert_param(IS_RTC_ALARM(Alarm)); + + /* Process Locked */ + __HAL_LOCK(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* In case of interrupt mode is used, the interrupt source must disabled */ + if (Alarm == RTC_ALARM_A) + { + CLEAR_BIT(RTC->CR, RTC_CR_ALRAE | RTC_CR_ALRAIE); + + /* AlarmA, Clear SSCLR */ + CLEAR_BIT(RTC->ALRMASSR, RTC_ALRMASSR_SSCLR); + } + else + { + CLEAR_BIT(RTC->CR, RTC_CR_ALRBE | RTC_CR_ALRBIE); + + /* AlarmB, Clear SSCLR */ + CLEAR_BIT(RTC->ALRMBSSR, RTC_ALRMBSSR_SSCLR); + } + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Get the RTC Alarm value and masks. + * @param hrtc RTC handle + * @param sAlarm Pointer to Date structure + * @param Alarm Specifies the Alarm. + * This parameter can be one of the following values: + * @arg RTC_ALARM_A: AlarmA + * @arg RTC_ALARM_B: AlarmB + * @param Format Specifies the format of the entered parameters. + * This parameter can be one of the following values: + * @arg RTC_FORMAT_BIN: Binary format + * @arg RTC_FORMAT_BCD: BCD format + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTC_GetAlarm(const RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Alarm, + uint32_t Format) +{ + uint32_t tmpreg; + uint32_t subsecondtmpreg; + + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(Format)); + assert_param(IS_RTC_ALARM(Alarm)); + + if (Alarm == RTC_ALARM_A) + { + /* AlarmA */ + sAlarm->Alarm = RTC_ALARM_A; + + tmpreg = READ_REG(RTC->ALRMAR); + subsecondtmpreg = (uint32_t)(READ_REG(RTC->ALRMASSR) & RTC_ALRMASSR_SS); + + /* Fill the structure with the read parameters */ + sAlarm->AlarmTime.Hours = (uint8_t)((tmpreg & (RTC_ALRMAR_HT | RTC_ALRMAR_HU)) >> RTC_ALRMAR_HU_Pos); + sAlarm->AlarmTime.Minutes = (uint8_t)((tmpreg & (RTC_ALRMAR_MNT | RTC_ALRMAR_MNU)) >> RTC_ALRMAR_MNU_Pos); + sAlarm->AlarmTime.Seconds = (uint8_t)((tmpreg & (RTC_ALRMAR_ST | RTC_ALRMAR_SU)) >> RTC_ALRMAR_SU_Pos); + sAlarm->AlarmTime.TimeFormat = (uint8_t)((tmpreg & RTC_ALRMAR_PM) >> RTC_ALRMAR_PM_Pos); + sAlarm->AlarmTime.SubSeconds = (uint32_t) subsecondtmpreg; + sAlarm->AlarmDateWeekDay = (uint8_t)((tmpreg & (RTC_ALRMAR_DT | RTC_ALRMAR_DU)) >> RTC_ALRMAR_DU_Pos); + sAlarm->AlarmDateWeekDaySel = (uint32_t)(tmpreg & RTC_ALRMAR_WDSEL); + sAlarm->AlarmMask = (uint32_t)(tmpreg & RTC_ALARMMASK_ALL); + } + else + { + sAlarm->Alarm = RTC_ALARM_B; + + tmpreg = READ_REG(RTC->ALRMBR); + subsecondtmpreg = (uint32_t)(READ_REG(RTC->ALRMBSSR) & RTC_ALRMBSSR_SS); + + /* Fill the structure with the read parameters */ + sAlarm->AlarmTime.Hours = (uint8_t)((tmpreg & (RTC_ALRMBR_HT | RTC_ALRMBR_HU)) >> RTC_ALRMBR_HU_Pos); + sAlarm->AlarmTime.Minutes = (uint8_t)((tmpreg & (RTC_ALRMBR_MNT | RTC_ALRMBR_MNU)) >> RTC_ALRMBR_MNU_Pos); + sAlarm->AlarmTime.Seconds = (uint8_t)((tmpreg & (RTC_ALRMBR_ST | RTC_ALRMBR_SU)) >> RTC_ALRMBR_SU_Pos); + sAlarm->AlarmTime.TimeFormat = (uint8_t)((tmpreg & RTC_ALRMBR_PM) >> RTC_ALRMBR_PM_Pos); + sAlarm->AlarmTime.SubSeconds = (uint32_t) subsecondtmpreg; + sAlarm->AlarmDateWeekDay = (uint8_t)((tmpreg & (RTC_ALRMBR_DT | RTC_ALRMBR_DU)) >> RTC_ALRMBR_DU_Pos); + sAlarm->AlarmDateWeekDaySel = (uint32_t)(tmpreg & RTC_ALRMBR_WDSEL); + sAlarm->AlarmMask = (uint32_t)(tmpreg & RTC_ALARMMASK_ALL); + } + + if (Format == RTC_FORMAT_BIN) + { + sAlarm->AlarmTime.Hours = RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours); + sAlarm->AlarmTime.Minutes = RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes); + sAlarm->AlarmTime.Seconds = RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds); + sAlarm->AlarmDateWeekDay = RTC_Bcd2ToByte(sAlarm->AlarmDateWeekDay); + } + + return HAL_OK; +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Handle Alarm secure interrupt request. + * @param hrtc RTC handle + * @retval None + */ +void HAL_RTC_AlarmIRQHandler(RTC_HandleTypeDef *hrtc) +{ + /* Get interrupt status */ + uint32_t tmp = READ_REG(RTC->SMISR); + + if ((tmp & RTC_SMISR_ALRAMF) != 0U) + { + /* Clear the AlarmA interrupt pending bit */ + WRITE_REG(RTC->SCR, RTC_SCR_CALRAF); + +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + /* Call Compare Match registered Callback */ + hrtc->AlarmAEventCallback(hrtc); +#else + HAL_RTC_AlarmAEventCallback(hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + } + + if ((tmp & RTC_SMISR_ALRBMF) != 0U) + { + /* Clear the AlarmB interrupt pending bit */ + WRITE_REG(RTC->SCR, RTC_SCR_CALRBF); + +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + /* Call Compare Match registered Callback */ + hrtc->AlarmBEventCallback(hrtc); +#else + HAL_RTCEx_AlarmBEventCallback(hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + + } + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; +} + +#else /* #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/** + * @brief Handle Alarm non-secure interrupt request. + * @note Alarm non-secure is available in non-secure driver. + * @param hrtc RTC handle + * @retval None + */ +void HAL_RTC_AlarmIRQHandler(RTC_HandleTypeDef *hrtc) +{ + /* Get interrupt status */ + uint32_t tmp = READ_REG(RTC->MISR); + + if ((tmp & RTC_MISR_ALRAMF) != 0U) + { + /* Clear the AlarmA interrupt pending bit */ + WRITE_REG(RTC->SCR, RTC_SCR_CALRAF); + +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + /* Call Compare Match registered Callback */ + hrtc->AlarmAEventCallback(hrtc); +#else + HAL_RTC_AlarmAEventCallback(hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + } + + if ((tmp & RTC_MISR_ALRBMF) != 0U) + { + /* Clear the AlarmB interrupt pending bit */ + WRITE_REG(RTC->SCR, RTC_SCR_CALRBF); + +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + /* Call Compare Match registered Callback */ + hrtc->AlarmBEventCallback(hrtc); +#else + HAL_RTCEx_AlarmBEventCallback(hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + } + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; +} +#endif /* #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/** + * @brief Alarm A secure callback. + * @param hrtc RTC handle + * @retval None + */ +__weak void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* NOTE : This function should not be modified, when the secure callback is needed, + the HAL_RTC_AlarmAEventCallback could be implemented in the user file + */ +} + +/** + * @brief Handle Alarm A Polling request. + * @param hrtc RTC handle + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTC_PollForAlarmAEvent(const RTC_HandleTypeDef *hrtc, uint32_t Timeout) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + uint32_t tickstart = HAL_GetTick(); + + while (READ_BIT(RTC->SR, RTC_SR_ALRAF) == 0U) + { + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + /* New check to avoid false timeout detection in case of preemption */ + if (READ_BIT(RTC->SR, RTC_SR_ALRAF) == 0U) + { + return HAL_TIMEOUT; + } + else + { + break; + } + } + } + } + + /* Clear the Alarm interrupt pending bit */ + WRITE_REG(RTC->SCR, RTC_SCR_CALRAF); + + return HAL_OK; +} + +/** + * @} + */ + +/** @addtogroup RTC_Exported_Functions_Group4 + * @brief Peripheral Control functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] + This subsection provides functions allowing to + (+) Wait for RTC Time and Date Synchronization + +@endverbatim + * @{ + */ + +/** + * @brief Wait until the RTC Time and Date registers (RTC_TR and RTC_DR) are + * synchronized with RTC APB clock. + * @note The RTC Resynchronization mode is write protected, use the + * __HAL_RTC_WRITEPROTECTION_DISABLE() before calling this function. + * @note To read the calendar through the shadow registers after Calendar + * initialization, calendar update or after wakeup from low power modes + * the software must first clear the RSF flag. + * The software must then wait until it is set again before reading + * the calendar, which means that the calendar registers have been + * correctly copied into the RTC_TR and RTC_DR shadow registers. + * @param hrtc RTC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTC_WaitForSynchro(RTC_HandleTypeDef *hrtc) +{ + uint32_t tickstart; + + /* Clear RSF flag */ + CLEAR_BIT(RTC->ICSR, RTC_ICSR_RSF); + + tickstart = HAL_GetTick(); + + /* Wait the registers to be synchronised */ + while (READ_BIT(RTC->ICSR, RTC_ICSR_RSF) == 0U) + { + if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE) + { + /* New check to avoid false timeout detection in case of preemption */ + if (READ_BIT(RTC->ICSR, RTC_ICSR_RSF) == 0U) + { + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_TIMEOUT; + return HAL_TIMEOUT; + } + else + { + break; + } + } + } + + return HAL_OK; +} + +/** + * @} + */ + +/** @addtogroup RTC_Exported_Functions_Group5 + * @brief Peripheral State functions + * +@verbatim + =============================================================================== + ##### Peripheral State functions ##### + =============================================================================== + [..] + This subsection provides functions allowing to + (+) Get RTC state + +@endverbatim + * @{ + */ +/** + * @brief Return the RTC handle state. + * @param hrtc RTC handle + * @retval HAL state + */ +HAL_RTCStateTypeDef HAL_RTC_GetState(const RTC_HandleTypeDef *hrtc) +{ + /* Return RTC handle state */ + return hrtc->State; +} + +/** + * @} + */ +/** + * @} + */ + +/** @addtogroup RTC_Private_Functions + * @{ + */ +/** + * @brief Enter the RTC Initialization mode. + * @note The RTC Initialization mode is write protected, use the + * __HAL_RTC_WRITEPROTECTION_DISABLE() before calling this function. + * @param hrtc RTC handle + * @retval HAL status + */ +HAL_StatusTypeDef RTC_EnterInitMode(RTC_HandleTypeDef *hrtc) +{ + uint32_t tickstart; + HAL_StatusTypeDef status = HAL_OK; + + /* Check if the Initialization mode is set */ + if (READ_BIT(RTC->ICSR, RTC_ICSR_INITF) == 0U) + { + /* Set the Initialization mode */ + SET_BIT(RTC->ICSR, RTC_ICSR_INIT); + + tickstart = HAL_GetTick(); + /* Wait till RTC is in INIT state and if Time out is reached exit */ + while ((READ_BIT(RTC->ICSR, RTC_ICSR_INITF) == 0U) && (status != HAL_TIMEOUT)) + { + if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE) + { + /* New check to avoid false timeout detection in case of preemption */ + if (READ_BIT(RTC->ICSR, RTC_ICSR_INITF) == 0U) + { + status = HAL_TIMEOUT; + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_TIMEOUT; + } + else + { + break; + } + } + } + } + + return status; +} + +/** + * @brief Exit the RTC Initialization mode. + * @param hrtc RTC handle + * @retval HAL status + */ +HAL_StatusTypeDef RTC_ExitInitMode(RTC_HandleTypeDef *hrtc) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Exit Initialization mode */ + CLEAR_BIT(RTC->ICSR, RTC_ICSR_INIT); + + /* If CR_BYPSHAD bit = 0, wait for synchro */ + if (READ_BIT(RTC->CR, RTC_CR_BYPSHAD) == 0U) + { + if (HAL_RTC_WaitForSynchro(hrtc) != HAL_OK) + { + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_TIMEOUT; + status = HAL_TIMEOUT; + } + } + else /* WA 2.9.6 Calendar initialization may fail in case of consecutive INIT mode entry. */ + { + /* Clear BYPSHAD bit */ + CLEAR_BIT(RTC->CR, RTC_CR_BYPSHAD); + if (HAL_RTC_WaitForSynchro(hrtc) != HAL_OK) + { + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_TIMEOUT; + status = HAL_TIMEOUT; + } + /* Restore BYPSHAD bit */ + SET_BIT(RTC->CR, RTC_CR_BYPSHAD); + } + return status; +} + +/** + * @brief Convert a 2 digit decimal to BCD format. + * @param Value Byte to be converted + * @retval Converted byte + */ +uint8_t RTC_ByteToBcd2(uint8_t Value) +{ + uint32_t bcd_high = 0U; + uint8_t tmp_value = Value; + + while (tmp_value >= 10U) + { + bcd_high++; + tmp_value -= 10U; + } + + return ((uint8_t)(bcd_high << 4U) | tmp_value); +} + +/** + * @brief Convert from 2 digit BCD to Binary. + * @param Value BCD value to be converted + * @retval Converted word + */ +uint8_t RTC_Bcd2ToByte(uint8_t Value) +{ + uint32_t tmp; + + tmp = (((uint32_t)Value & 0xF0U) >> 4) * 10U; + + return (uint8_t)(tmp + ((uint32_t)Value & 0x0FU)); +} + +/** + * @} + */ + +#endif /* HAL_RTC_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rtc_ex.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rtc_ex.c new file mode 100644 index 0000000000..27ca166af3 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_rtc_ex.c @@ -0,0 +1,3271 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_rtc_ex.c + * @author MCD Application Team + * @brief Extended RTC HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Real Time Clock (RTC) Extended peripheral: + * + RTC Time Stamp functions + * + RTC Tamper functions + * + RTC Wake-up functions + * + Extended Control functions + * + Extended RTC features functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (+) Enable the RTC domain access. + (+) Configure the RTC Prescaler (Asynchronous and Synchronous) and RTC hour + format using the HAL_RTC_Init() function. + + *** RTC Wakeup configuration *** + ================================ + [..] + (+) To configure the RTC Wakeup Clock source and Counter use the HAL_RTCEx_SetWakeUpTimer() + function. You can also configure the RTC Wakeup timer with interrupt mode + using the HAL_RTCEx_SetWakeUpTimer_IT() function. + (+) To read the RTC WakeUp Counter register, use the HAL_RTCEx_GetWakeUpTimer() + function. + + *** Outputs configuration *** + ============================= + [..] The RTC has 2 outputs pins (RTC_OUT1 & RTC_OUT2). + To configure the outputs, use the HAL_RTC_Init() function. + (+) RTC_OUT1 and RTC_OUT2 which select one of the following two outputs: + (+) CALIB: 512Hz or 1Hz clock output (with an LSE frequency of 32.768kHz). + To enable the CALIB, use the HAL_RTCEx_SetCalibrationOutPut() function. + (+) TAMPALRM: This output is the OR between rtc_tamp_evt and ALARM signals. + ALARM is enabled by configuring the OSEL[1:0] bits in the RTC_CR register + which select the alarm A, alarm B or wakeup outputs. + rtc_tamp_evt is enabled by setting the TAMPOE bit + in the RTC_CR register which selects the tamper event outputs. + + *** Smooth digital Calibration configuration *** + ================================================ + [..] + (+) Configure the RTC Original Digital Calibration Value and the corresponding + calibration cycle period (32s,16s and 8s) using the HAL_RTCEx_SetSmoothCalib() + function. + + *** RTC synchronization *** + ================================================ + [..] + (+) The RTC can be finely adjusted using HAL_RTCEx_SetSynchroShift() function. + Writing to RTC_SHIFTR can shift (either delay or advance) the clock with + a resolution of 1 ck_apre period. + The shift operation consists in adding the SUBFS[14:0] value to the synchronous + prescaler counter SS[15:0]: this delays the clock. + + *** Bypass shadow registers *** + ================================================ + [..] + (+) Enable bypass shadow registers using the HAL_RTCEx_EnableBypassShadow(). + When the Bypass Shadow is enabled the calendar value are taken directly + from the Calendar counter. + Thus eliminating the need to wait for the RSF bit to be set. + This is especially useful after exiting from low-power modes (Stop or Standby), + since the shadow registers are not updated during these modes. + + *** RTC ultra-low-power mode *** + ================================================ + [..] + (+) Configure the RTC ultra-low-power mode using HAL_RTCEx_SetLowPowerCalib() function. + In this case, the calibration mechanism is applied on ck_apre instead of RTCCLK. + The resulting accuracy is the same, but the calibration is performed during a + calibration cycle of about 220 x PREDIV_A x RTCCLK pulses instead of 220 RTCCLK pulses. + + *** RTC subsecond register underflow interruption *** + ================================================ + [..] + (+) Enable the RTC SSRU interruption mode using HAL_RTCEx_SetSSRU_IT() function. + In this case, when the SSR rolls under 0, an SSRU interruption is triggered. + Disable the RTC SSRU interruption mode using HAL_RTCEx_DeactivateSSRU() function. + + *** TimeStamp configuration *** + =============================== + [..] + (+) Enable the RTC TimeStamp using the HAL_RTCEx_SetTimeStamp() function. + You can also configure the RTC TimeStamp with interrupt mode using the + HAL_RTCEx_SetTimeStamp_IT() function. + (+) To read the RTC TimeStamp Time and Date register, use the HAL_RTCEx_GetTimeStamp() + function. + + *** Internal TimeStamp configuration *** + =============================== + [..] + (+) Enable the RTC internal TimeStamp using the HAL_RTCEx_SetInternalTimeStamp() function. + User has to check internal timestamp occurrence using __HAL_RTC_INTERNAL_TIMESTAMP_GET_FLAG. + (+) To read the RTC TimeStamp Time and Date register, use the HAL_RTCEx_GetTimeStamp() + function. + + *** Tamper configuration *** + ============================ + [..] + (+) Enable the RTC Tamper and configure the Tamper filter count, trigger Edge + or Level according to the Tamper filter (if equal to 0 Edge else Level) + value, sampling frequency, NoErase, MaskFlag, precharge or discharge and + Pull-UP using the HAL_RTCEx_SetTamper() function. You can configure RTC Tamper + with interrupt mode using HAL_RTCEx_SetTamper_IT() function. + (+) The default configuration of the Tamper erases the backup registers. To avoid + erase, enable the NoErase field on the TAMP_CR2 register. + (+) With new RTC tamper configuration, you have to call HAL_RTC_Init() in order to + perform TAMP base address offset calculation. + (+) Enable Internal tamper using HAL_RTCEx_SetInternalTamper. IT mode can be chosen using + setting Interrupt field. + + *** Backup Data Registers and Device Secrets configuration *** + =========================================== + [..] + (+) To write to the RTC Backup Data registers, use the HAL_RTCEx_BKUPWrite() + function. + (+) To read the RTC Backup registers, use the HAL_RTCEx_BKUPRead() + function. + (+) To reset the RTC Backup registers and erase the device secrets, + use HAL_RTCEx_BKUPErase() function. + (+) Enable the lock of the Boot hardware Key using the HAL_RTCEx_LockBootHardwareKey() + function. + The backup registers from TAMP_BKP0R to TAMP_BKP7R cannot be accessed neither in + read nor in write (they are read as 0 and write ignore). + (+) Configure the erase of the Device Secrets using HAL_RTCEx_ConfigEraseDeviceSecrets() + function. + (+) Block the access to the RTC Backup registers and all the device secrets + using HAL_RTCEx_BKUPBlock() function. + + *** Monotonic counter *** + ================================================ + [..] + (+) To increment the Monotonic counter, use the HAL_RTCEx_MonotonicCounterIncrement() + function. + (+) To get the current value of the Monotonic counter, use the HAL_RTCEx_MonotonicCounterGet() + function. + + *** RTC & TAMP secure protection modes *** + ================================================ + [..] + (+) Set the security level of the RTC/TAMP/Backup registers using HAL_RTCEx_SecureModeSet() + function. + +) Get the security level of the RTC/TAMP/Backup registers using HAL_RTCEx_SecureModeGet() + function. + + *** RTC & TAMP privilege protection modes *** + ================================================ + [..] + (+) Set the privilege level of the RTC/TAMP/Backup registers using HAL_RTCEx_PrivilegeModeSet() + function. + +) Get the privilege level of the RTC/TAMP/Backup registers using HAL_RTCEx_PrivilegeModeGet() + function. + + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup RTCEx + * @brief RTC Extended HAL module driver + * @{ + */ + +#ifdef HAL_RTC_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define TAMP_ALL RTC_TAMPER_ALL + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup RTCEx_Exported_Functions + * @{ + */ + + +/** @addtogroup RTCEx_Exported_Functions_Group1 + * @brief RTC TimeStamp and Tamper functions + * +@verbatim + =============================================================================== + ##### RTC TimeStamp and Tamper functions ##### + =============================================================================== + + [..] This section provides functions allowing to configure TimeStamp feature + +@endverbatim + * @{ + */ + +#ifdef RTC_CR_TSE +/** + * @brief Set TimeStamp. + * @note This API must be called before enabling the TimeStamp feature. + * @param hrtc RTC handle + * @param TimeStampEdge Specifies the pin edge on which the TimeStamp is + * activated. + * This parameter can be one of the following values: + * @arg RTC_TIMESTAMPEDGE_RISING: the Time stamp event occurs on the + * rising edge of the related pin. + * @arg RTC_TIMESTAMPEDGE_FALLING: the Time stamp event occurs on the + * falling edge of the related pin. + * @param RTC_TimeStampPin specifies the RTC TimeStamp Pin. + * This parameter can be one of the following values: + * @arg RTC_TIMESTAMPPIN_DEFAULT: PC13 is selected as RTC TimeStamp Pin. + * The RTC TimeStamp Pin is per default PC13, but for reasons of + * compatibility, this parameter is required. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_SetTimeStamp(RTC_HandleTypeDef *hrtc, uint32_t TimeStampEdge, uint32_t RTC_TimeStampPin) +{ + /* Check the parameters */ +#if defined(RTC_CR_TSEDGE) + assert_param(IS_TIMESTAMP_EDGE(TimeStampEdge)); +#endif /* RTC_CR_TSEDGE */ + assert_param(IS_RTC_TIMESTAMP_PIN(RTC_TimeStampPin)); + UNUSED(RTC_TimeStampPin); + + /* Process Locked */ + __HAL_LOCK(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Get the RTC_CR register and clear the bits to be configured */ +#if defined(RTC_CR_TSEDGE) + CLEAR_BIT(RTC->CR, (RTC_CR_TSEDGE | RTC_CR_TSE)); +#else + CLEAR_BIT(RTC->CR, RTC_CR_TSE); +#endif /* RTC_CR_TSEDGE */ + + /* Configure the Time Stamp TSEDGE and Enable bits */ + SET_BIT(RTC->CR, (uint32_t)TimeStampEdge | RTC_CR_TSE); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Set TimeStamp with Interrupt. + * @note This API must be called before enabling the TimeStamp feature. + * @note The application must ensure that the EXTI RTC interrupt line is enabled. + * @param hrtc RTC handle + * @param TimeStampEdge Specifies the pin edge on which the TimeStamp is + * activated. + * This parameter can be one of the following values: + * @arg RTC_TIMESTAMPEDGE_RISING: the Time stamp event occurs on the + * rising edge of the related pin. + * @arg RTC_TIMESTAMPEDGE_FALLING: the Time stamp event occurs on the + * falling edge of the related pin. + * @param RTC_TimeStampPin Specifies the RTC TimeStamp Pin. + * This parameter can be one of the following values: + * @arg RTC_TIMESTAMPPIN_DEFAULT: PC13 is selected as RTC TimeStamp Pin. + * The RTC TimeStamp Pin is per default PC13, but for reasons of + * compatibility, this parameter is required. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_SetTimeStamp_IT(RTC_HandleTypeDef *hrtc, uint32_t TimeStampEdge, uint32_t RTC_TimeStampPin) +{ + /* Check the parameters */ +#if defined(RTC_CR_TSEDGE) + assert_param(IS_TIMESTAMP_EDGE(TimeStampEdge)); +#endif /* RTC_CR_TSEDGE */ + assert_param(IS_RTC_TIMESTAMP_PIN(RTC_TimeStampPin)); + UNUSED(RTC_TimeStampPin); + + /* Process Locked */ + __HAL_LOCK(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Get the RTC_CR register and clear the bits to be configured */ +#if defined(RTC_CR_TSEDGE) + CLEAR_BIT(RTC->CR, (RTC_CR_TSEDGE | RTC_CR_TSE | RTC_CR_TSIE)); +#else + CLEAR_BIT(RTC->CR, (RTC_CR_TSE | RTC_CR_TSIE)); +#endif /* RTC_CR_TSEDGE */ + + /* Configure the Time Stamp TSEDGE before Enable bit to avoid unwanted TSF setting. */ + SET_BIT(RTC->CR, (uint32_t)TimeStampEdge); + + /* Enable timestamp and IT */ + SET_BIT(RTC->CR, RTC_CR_TSE | RTC_CR_TSIE); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Deactivate TimeStamp. + * @param hrtc RTC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_DeactivateTimeStamp(RTC_HandleTypeDef *hrtc) +{ + /* Process Locked */ + __HAL_LOCK(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* In case of interrupt mode is used, the interrupt source must disabled */ +#if defined(RTC_CR_TSEDGE) + CLEAR_BIT(RTC->CR, (RTC_CR_TSEDGE | RTC_CR_TSE | RTC_CR_TSIE)); +#else + CLEAR_BIT(RTC->CR, (RTC_CR_TSE | RTC_CR_TSIE)); +#endif /* RTC_CR_TSEDGE */ + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} +#endif /* RTC_CR_TSE */ + +/** + * @brief Set Internal TimeStamp. + * @note This API must be called before enabling the internal TimeStamp feature. + * @param hrtc RTC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_SetInternalTimeStamp(RTC_HandleTypeDef *hrtc) +{ + /* Process Locked */ + __HAL_LOCK(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Configure the internal Time Stamp Enable bits */ + SET_BIT(RTC->CR, RTC_CR_ITSE); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Deactivate Internal TimeStamp. + * @param hrtc RTC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_DeactivateInternalTimeStamp(RTC_HandleTypeDef *hrtc) +{ + /* Process Locked */ + __HAL_LOCK(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Configure the internal Time Stamp Enable bits */ + CLEAR_BIT(RTC->CR, RTC_CR_ITSE); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Get the RTC TimeStamp value. + * @param hrtc RTC handle + * @param sTimeStamp Pointer to Time structure + * @param sTimeStampDate Pointer to Date structure + * @param Format specifies the format of the entered parameters. + * This parameter can be one of the following values: + * @arg RTC_FORMAT_BIN: Binary data format + * @arg RTC_FORMAT_BCD: BCD data format + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_GetTimeStamp(const RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTimeStamp, + RTC_DateTypeDef *sTimeStampDate, uint32_t Format) +{ + uint32_t tmptime; + uint32_t tmpdate; + + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(Format)); + + /* Get the TimeStamp time and date registers values */ + tmptime = READ_BIT(RTC->TSTR, RTC_TR_RESERVED_MASK); + tmpdate = READ_BIT(RTC->TSDR, RTC_DR_RESERVED_MASK); + + /* Fill the Time structure fields with the read parameters */ + sTimeStamp->Hours = (uint8_t)((tmptime & (RTC_TSTR_HT | RTC_TSTR_HU)) >> RTC_TSTR_HU_Pos); + sTimeStamp->Minutes = (uint8_t)((tmptime & (RTC_TSTR_MNT | RTC_TSTR_MNU)) >> RTC_TSTR_MNU_Pos); + sTimeStamp->Seconds = (uint8_t)((tmptime & (RTC_TSTR_ST | RTC_TSTR_SU)) >> RTC_TSTR_SU_Pos); + sTimeStamp->TimeFormat = (uint8_t)((tmptime & (RTC_TSTR_PM)) >> RTC_TSTR_PM_Pos); + sTimeStamp->SubSeconds = READ_BIT(RTC->TSSSR, RTC_TSSSR_SS); + + /* Fill the Date structure fields with the read parameters */ + sTimeStampDate->Year = 0U; + sTimeStampDate->Month = (uint8_t)((tmpdate & (RTC_TSDR_MT | RTC_TSDR_MU)) >> RTC_TSDR_MU_Pos); + sTimeStampDate->Date = (uint8_t)(tmpdate & (RTC_TSDR_DT | RTC_TSDR_DU)); + sTimeStampDate->WeekDay = (uint8_t)((tmpdate & (RTC_TSDR_WDU)) >> RTC_TSDR_WDU_Pos); + + /* Check the input parameters format */ + if (Format == RTC_FORMAT_BIN) + { + /* Convert the TimeStamp structure parameters to Binary format */ + sTimeStamp->Hours = (uint8_t)RTC_Bcd2ToByte(sTimeStamp->Hours); + sTimeStamp->Minutes = (uint8_t)RTC_Bcd2ToByte(sTimeStamp->Minutes); + sTimeStamp->Seconds = (uint8_t)RTC_Bcd2ToByte(sTimeStamp->Seconds); + + /* Convert the DateTimeStamp structure parameters to Binary format */ + sTimeStampDate->Month = (uint8_t)RTC_Bcd2ToByte(sTimeStampDate->Month); + sTimeStampDate->Date = (uint8_t)RTC_Bcd2ToByte(sTimeStampDate->Date); + sTimeStampDate->WeekDay = (uint8_t)RTC_Bcd2ToByte(sTimeStampDate->WeekDay); + } + + /* Clear the TIMESTAMP Flags */ + WRITE_REG(RTC->SCR, (RTC_SCR_CITSF | RTC_SCR_CTSF)); + + return HAL_OK; +} + +/** + * @brief Handle TimeStamp interrupt request. + * @param hrtc RTC handle + * @retval None + */ +void HAL_RTCEx_TimeStampIRQHandler(RTC_HandleTypeDef *hrtc) +{ + /* Get the pending status of the TimeStamp Interrupt */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + if (READ_BIT(RTC->SMISR, RTC_SMISR_TSMF) != 0U) +#else + if (READ_BIT(RTC->MISR, RTC_MISR_TSMF) != 0U) +#endif /* #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + { +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + /* Call TimeStampEvent registered Callback */ + hrtc->TimeStampEventCallback(hrtc); +#else + HAL_RTCEx_TimeStampEventCallback(hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + + /* Clearing flags after the Callback because the content of RTC_TSTR and RTC_TSDR are cleared when + TSF bit is reset.*/ + WRITE_REG(RTC->SCR, RTC_SCR_CITSF | RTC_SCR_CTSF); + } + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; +} + +/** + * @brief TimeStamp callback. + * @param hrtc RTC handle + * @retval None + */ +__weak void HAL_RTCEx_TimeStampEventCallback(RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RTCEx_TimeStampEventCallback could be implemented in the user file + */ +} + +/** + * @brief Handle TimeStamp polling request. + * @param hrtc RTC handle + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_PollForTimeStampEvent(const RTC_HandleTypeDef *hrtc, uint32_t Timeout) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + uint32_t tickstart = HAL_GetTick(); + + while (READ_BIT(RTC->SR, RTC_SR_TSF) == 0U) + { + if (READ_BIT(RTC->SR, RTC_SR_TSOVF) != 0U) + { + /* Clear the TIMESTAMP OverRun Flag */ + WRITE_REG(RTC->SCR, RTC_SCR_CTSOVF); + + return HAL_ERROR; + } + + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + /* New check to avoid false timeout detection in case of preemption */ + if (READ_BIT(RTC->SR, RTC_SR_TSF) == 0U) + { + return HAL_TIMEOUT; + } + else + { + break; + } + } + } + } + + return HAL_OK; +} + +/** + * @} + */ + +/** @addtogroup RTCEx_Exported_Functions_Group2 + * @brief RTC Wake-up functions + * +@verbatim + =============================================================================== + ##### RTC Wake-up functions ##### + =============================================================================== + + [..] This section provides functions allowing to configure Wake-up feature + +@endverbatim + * @{ + */ + +/** + * @brief Set wake up timer. + * @param hrtc RTC handle + * @param WakeUpCounter Wake up counter + * @param WakeUpClock Wake up clock + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_SetWakeUpTimer(RTC_HandleTypeDef *hrtc, uint32_t WakeUpCounter, uint32_t WakeUpClock) +{ + uint32_t tickstart; + + /* Check the parameters */ + assert_param(IS_RTC_WAKEUP_CLOCK(WakeUpClock)); + assert_param(IS_RTC_WAKEUP_COUNTER(WakeUpCounter)); + + /* Process Locked */ + __HAL_LOCK(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Clear WUTE in RTC_CR to disable the wakeup timer */ + CLEAR_BIT(RTC->CR, RTC_CR_WUTE); + + /* Poll WUTWF until it is set in RTC_ICSR to make sure the access to wakeup autoreload + counter and to WUCKSEL[2:0] bits is allowed. This step must be skipped in + calendar initialization mode. */ + if (READ_BIT(RTC->ICSR, RTC_ICSR_INITF) == 0U) + { + tickstart = HAL_GetTick(); + + while (READ_BIT(RTC->ICSR, RTC_ICSR_WUTWF) == 0U) + { + if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE) + { + /* New check to avoid false timeout detection in case of preemption */ + if (READ_BIT(RTC->ICSR, RTC_ICSR_WUTWF) == 0U) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_TIMEOUT; + } + else + { + break; + } + } + } + } + + /* Configure the clock source */ + MODIFY_REG(RTC->CR, RTC_CR_WUCKSEL, (uint32_t)WakeUpClock); + + /* Configure the Wakeup Timer counter */ + WRITE_REG(RTC->WUTR, (uint32_t)WakeUpCounter); + + /* Enable the Wakeup Timer */ + SET_BIT(RTC->CR, RTC_CR_WUTE); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Set wake up timer with interrupt. + * @note The application must ensure that the EXTI RTC interrupt line is enabled. + * @param hrtc RTC handle + * @param WakeUpCounter Wake up counter + * @param WakeUpClock Wake up clock + * @param WakeUpAutoClr Wake up auto clear value (look at WUTOCLR in reference manual) + * - No effect if WakeUpAutoClr is set to zero + * - This feature is meaningful in case of Low power mode to avoid any RTC software execution + * after Wake Up. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_SetWakeUpTimer_IT(RTC_HandleTypeDef *hrtc, uint32_t WakeUpCounter, uint32_t WakeUpClock, + uint32_t WakeUpAutoClr) +{ + uint32_t tickstart; + + /* Check the parameters */ + assert_param(IS_RTC_WAKEUP_CLOCK(WakeUpClock)); + assert_param(IS_RTC_WAKEUP_COUNTER(WakeUpCounter)); + /* (0x0000<=WUTOCLR<=WUT) */ + assert_param(WakeUpAutoClr <= WakeUpCounter); + + /* Process Locked */ + __HAL_LOCK(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Clear WUTE in RTC_CR to disable the wakeup timer */ + CLEAR_BIT(RTC->CR, RTC_CR_WUTE); + + /* Clear flag Wake-Up */ + WRITE_REG(RTC->SCR, RTC_SCR_CWUTF); + + /* Poll WUTWF until it is set in RTC_ICSR to make sure the access to wakeup autoreload + counter and to WUCKSEL[2:0] bits is allowed. This step must be skipped in + calendar initialization mode. */ + if (READ_BIT(RTC->ICSR, RTC_ICSR_INITF) == 0U) + { + tickstart = HAL_GetTick(); + while (READ_BIT(RTC->ICSR, RTC_ICSR_WUTWF) == 0U) + { + if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE) + { + /* New check to avoid false timeout detection in case of preemption */ + if (READ_BIT(RTC->ICSR, RTC_ICSR_WUTWF) == 0U) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_TIMEOUT; + } + else + { + break; + } + } + } + } + + /* Configure the Wakeup Timer counter and auto clear value */ + WRITE_REG(RTC->WUTR, (uint32_t)(WakeUpCounter | (WakeUpAutoClr << RTC_WUTR_WUTOCLR_Pos))); + + /* Configure the clock source */ + MODIFY_REG(RTC->CR, RTC_CR_WUCKSEL, (uint32_t)WakeUpClock); + + /* Configure the Interrupt in the RTC_CR register and Enable the Wakeup Timer*/ + SET_BIT(RTC->CR, (RTC_CR_WUTIE | RTC_CR_WUTE)); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Deactivate wake up timer counter. + * @param hrtc RTC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_DeactivateWakeUpTimer(RTC_HandleTypeDef *hrtc) +{ + uint32_t tickstart; + + /* Process Locked */ + __HAL_LOCK(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Disable the Wakeup Timer */ + /* In case of interrupt mode is used, the interrupt source must disabled */ + CLEAR_BIT(RTC->CR, (RTC_CR_WUTE | RTC_CR_WUTIE)); + + tickstart = HAL_GetTick(); + + /* Wait till RTC WUTWF flag is set and if Time out is reached exit */ + while (READ_BIT(RTC->ICSR, RTC_ICSR_WUTWF) == 0U) + { + if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE) + { + /* New check to avoid false timeout detection in case of preemption */ + if (READ_BIT(RTC->ICSR, RTC_ICSR_WUTWF) == 0U) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_TIMEOUT; + } + else + { + break; + } + } + } + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Get wake up timer counter. + * @param hrtc RTC handle + * @retval Counter value + */ +uint32_t HAL_RTCEx_GetWakeUpTimer(const RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* Get the counter value */ + return (uint32_t)(READ_BIT(RTC->WUTR, RTC_WUTR_WUT)); +} + +/** + * @brief Handle Wake Up Timer interrupt request. + * @param hrtc RTC handle + * @retval None + */ +void HAL_RTCEx_WakeUpTimerIRQHandler(RTC_HandleTypeDef *hrtc) +{ + /* Get the pending status of the Wake-Up Timer Interrupt */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + if (READ_BIT(RTC->SMISR, RTC_SMISR_WUTMF) != 0U) +#else + if (READ_BIT(RTC->MISR, RTC_MISR_WUTMF) != 0U) +#endif /* #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + { + /* Immediately clear flags */ + WRITE_REG(RTC->SCR, RTC_SCR_CWUTF); +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + /* Call wake up timer registered Callback */ + hrtc->WakeUpTimerEventCallback(hrtc); +#else + HAL_RTCEx_WakeUpTimerEventCallback(hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + } + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; +} + +/** + * @brief Wake Up Timer callback. + * @param hrtc RTC handle + * @retval None + */ +__weak void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RTCEx_WakeUpTimerEventCallback could be implemented in the user file + */ +} + +/** + * @brief Handle Wake Up Timer Polling. + * @param hrtc RTC handle + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_PollForWakeUpTimerEvent(const RTC_HandleTypeDef *hrtc, uint32_t Timeout) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + uint32_t tickstart = HAL_GetTick(); + + while (READ_BIT(RTC->SR, RTC_SR_WUTF) == 0U) + { + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + /* New check to avoid false timeout detection in case of preemption */ + if (READ_BIT(RTC->SR, RTC_SR_WUTF) == 0U) + { + return HAL_TIMEOUT; + } + else + { + break; + } + } + } + } + + /* Clear the WAKEUPTIMER Flag */ + WRITE_REG(RTC->SCR, RTC_SCR_CWUTF); + + return HAL_OK; +} + +/** + * @} + */ + +/** @addtogroup RTCEx_Exported_Functions_Group3 + * @brief Extended Peripheral Control functions + * +@verbatim + =============================================================================== + ##### Extended Peripheral Control functions ##### + =============================================================================== + [..] + This subsection provides functions allowing to + (+) Write a data in a specified RTC Backup data register + (+) Read a data in a specified RTC Backup data register + (+) Set the Coarse calibration parameters. + (+) Deactivate the Coarse calibration parameters + (+) Set the Smooth calibration parameters. + (+) Set Low Power calibration parameter. + (+) Configure the Synchronization Shift Control Settings. + (+) Configure the Calibration Pinout (RTC_CALIB) Selection (1Hz or 512Hz). + (+) Deactivate the Calibration Pinout (RTC_CALIB) Selection (1Hz or 512Hz). + (+) Enable the RTC reference clock detection. + (+) Disable the RTC reference clock detection. + (+) Enable the Bypass Shadow feature. + (+) Disable the Bypass Shadow feature. + +@endverbatim + * @{ + */ + +/** + * @brief Set the Smooth calibration parameters. + * @note To deactivate the smooth calibration, the field SmoothCalibPlusPulses + * must be equal to SMOOTHCALIB_PLUSPULSES_RESET and the field + * SmoothCalibMinusPulsesValue must be equal to 0. + * @param hrtc RTC handle + * @param SmoothCalibPeriod Select the Smooth Calibration Period. + * This parameter can be one of the following values : + * @arg RTC_SMOOTHCALIB_PERIOD_32SEC: The smooth calibration period is 32s. + * @arg RTC_SMOOTHCALIB_PERIOD_16SEC: The smooth calibration period is 16s. + * @arg RTC_SMOOTHCALIB_PERIOD_8SEC: The smooth calibration period is 8s. + * @param SmoothCalibPlusPulses Select to Set or reset the CALP bit. + * This parameter can be one of the following values: + * @arg RTC_SMOOTHCALIB_PLUSPULSES_SET: Add one RTCCLK pulse every 2*11 pulses. + * @arg RTC_SMOOTHCALIB_PLUSPULSES_RESET: No RTCCLK pulses are added. + * @param SmoothCalibMinusPulsesValue Select the value of CALM[8:0] bits. + * This parameter can be one any value from 0 to 0x000001FF. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_SetSmoothCalib(RTC_HandleTypeDef *hrtc, uint32_t SmoothCalibPeriod, + uint32_t SmoothCalibPlusPulses, uint32_t SmoothCalibMinusPulsesValue) +{ + uint32_t tickstart; + + /* Check the parameters */ + assert_param(IS_RTC_SMOOTH_CALIB_PERIOD(SmoothCalibPeriod)); + assert_param(IS_RTC_SMOOTH_CALIB_PLUS(SmoothCalibPlusPulses)); + assert_param(IS_RTC_SMOOTH_CALIB_MINUS(SmoothCalibMinusPulsesValue)); + + /* Process Locked */ + __HAL_LOCK(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + tickstart = HAL_GetTick(); + + /* check if a calibration is pending */ + while (READ_BIT(RTC->ICSR, RTC_ICSR_RECALPF) != 0U) + { + if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE) + { + /* New check to avoid false timeout detection in case of preemption */ + if (READ_BIT(RTC->ICSR, RTC_ICSR_RECALPF) != 0U) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_TIMEOUT; + } + else + { + break; + } + } + } + + /* Configure the Smooth calibration settings */ + MODIFY_REG(RTC->CALR, (RTC_CALR_CALP | RTC_CALR_CALW8 | RTC_CALR_CALW16 | RTC_CALR_CALM), + (uint32_t)(SmoothCalibPeriod | SmoothCalibPlusPulses | SmoothCalibMinusPulsesValue)); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Select the low power Calibration mode. + * @param hrtc: RTC handle + * @param LowPowerCalib: Low power Calibration mode. + * This parameter can be one of the following values : + * @arg RTC_LPCAL_SET: Low power mode. + * @arg RTC_LPCAL_RESET: High consumption mode. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_SetLowPowerCalib(RTC_HandleTypeDef *hrtc, uint32_t LowPowerCalib) +{ + /* Check the parameters */ + assert_param(IS_RTC_LOW_POWER_CALIB(LowPowerCalib)); + + /* Process Locked */ + __HAL_LOCK(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Configure the Smooth calibration settings */ + MODIFY_REG(RTC->CALR, RTC_CALR_LPCAL, LowPowerCalib); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Configure the Synchronization Shift Control Settings. + * @note When REFCKON is set, firmware must not write to Shift control register. + * @param hrtc RTC handle + * @param ShiftAdd1S Select to add or not 1 second to the time calendar. + * This parameter can be one of the following values: + * @arg RTC_SHIFTADD1S_SET: Add one second to the clock calendar. + * @arg RTC_SHIFTADD1S_RESET: No effect. + * @param ShiftSubFS Select the number of Second Fractions to substitute. + * This parameter can be one any value from 0 to 0x7FFF. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_SetSynchroShift(RTC_HandleTypeDef *hrtc, uint32_t ShiftAdd1S, uint32_t ShiftSubFS) +{ + uint32_t tickstart; + + /* Check the parameters */ + assert_param(IS_RTC_SHIFT_ADD1S(ShiftAdd1S)); + assert_param(IS_RTC_SHIFT_SUBFS(ShiftSubFS)); + + /* Process Locked */ + __HAL_LOCK(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + tickstart = HAL_GetTick(); + + /* Wait until the shift is completed */ + while (READ_BIT(RTC->ICSR, RTC_ICSR_SHPF) != 0U) + { + if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE) + { + /* New check to avoid false timeout detection in case of preemption */ + if (READ_BIT(RTC->ICSR, RTC_ICSR_SHPF) != 0U) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_TIMEOUT; + } + else + { + break; + } + } + } + +#if defined(RTC_CR_REFCKON) + /* Check if the reference clock detection is disabled */ + if (READ_BIT(RTC->CR, RTC_CR_REFCKON) == 0U) + { +#endif /* RTC_CR_REFCKON */ + /* Configure the Shift settings */ + MODIFY_REG(RTC->SHIFTR, RTC_SHIFTR_SUBFS, (uint32_t)(ShiftSubFS) | (uint32_t)(ShiftAdd1S)); + + /* If RTC_CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */ + if (READ_BIT(RTC->CR, RTC_CR_BYPSHAD) == 0U) + { + if (HAL_RTC_WaitForSynchro(hrtc) != HAL_OK) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_ERROR; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_ERROR; + } + } +#if defined(RTC_CR_REFCKON) + } + else + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_ERROR; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_ERROR; + } +#endif /* RTC_CR_REFCKON */ + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +#if defined(RTC_CR_COSEL) +/** + * @brief Configure the Calibration Pinout (RTC_CALIB) Selection (1Hz or 512Hz). + * @param hrtc RTC handle + * @param CalibOutput Select the Calibration output Selection . + * This parameter can be one of the following values: + * @arg RTC_CALIBOUTPUT_512HZ: A signal has a regular waveform at 512Hz. + * @arg RTC_CALIBOUTPUT_1HZ: A signal has a regular waveform at 1Hz. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_SetCalibrationOutPut(RTC_HandleTypeDef *hrtc, uint32_t CalibOutput) +{ + /* Check the parameters */ + assert_param(IS_RTC_CALIB_OUTPUT(CalibOutput)); + + /* Process Locked */ + __HAL_LOCK(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Configure the RTC_CR register */ + MODIFY_REG(RTC->CR, RTC_CR_COSEL, CalibOutput); + + /* Enable calibration output */ + SET_BIT(RTC->CR, RTC_CR_COE); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Deactivate the Calibration Pinout (RTC_CALIB) Selection (1Hz or 512Hz). + * @param hrtc RTC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_DeactivateCalibrationOutPut(RTC_HandleTypeDef *hrtc) +{ + /* Process Locked */ + __HAL_LOCK(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Disable calibration output */ + CLEAR_BIT(RTC->CR, RTC_CR_COE); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} +#endif /* RTC_CR_COSEL */ + +#if defined(RTC_CR_REFCKON) +/** + * @brief Enable the RTC reference clock detection. + * @param hrtc RTC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_SetRefClock(RTC_HandleTypeDef *hrtc) +{ + HAL_StatusTypeDef status; + + /* Process Locked */ + __HAL_LOCK(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Enter Initialization mode */ + status = RTC_EnterInitMode(hrtc); + if (status == HAL_OK) + { + /* Enable clockref detection */ + SET_BIT(RTC->CR, RTC_CR_REFCKON); + + /* Exit Initialization mode */ + status = RTC_ExitInitMode(hrtc); + } + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + if (status == HAL_OK) + { + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return status; +} + +/** + * @brief Disable the RTC reference clock detection. + * @param hrtc RTC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_DeactivateRefClock(RTC_HandleTypeDef *hrtc) +{ + HAL_StatusTypeDef status; + + /* Process Locked */ + __HAL_LOCK(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Enter Initialization mode */ + status = RTC_EnterInitMode(hrtc); + if (status == HAL_OK) + { + /* Disable clockref detection */ + CLEAR_BIT(RTC->CR, RTC_CR_REFCKON); + + /* Exit Initialization mode */ + status = RTC_ExitInitMode(hrtc); + } + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + if (status == HAL_OK) + { + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return status; +} +#endif /* RTC_CR_REFCKON */ + +/** + * @brief Enable the Bypass Shadow feature. + * @note When the Bypass Shadow is enabled the calendar value are taken + * directly from the Calendar counter. + * @param hrtc RTC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_EnableBypassShadow(RTC_HandleTypeDef *hrtc) +{ + /* Process Locked */ + __HAL_LOCK(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Set the BYPSHAD bit */ + SET_BIT(RTC->CR, RTC_CR_BYPSHAD); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Disable the Bypass Shadow feature. + * @note When the Bypass Shadow is enabled the calendar value are taken + * directly from the Calendar counter. + * @param hrtc RTC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_DisableBypassShadow(RTC_HandleTypeDef *hrtc) +{ + /* Process Locked */ + __HAL_LOCK(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Reset the BYPSHAD bit */ + CLEAR_BIT(RTC->CR, RTC_CR_BYPSHAD); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Increment Monotonic counter. + * @param hrtc RTC handle + * @param Instance Monotonic counter Instance + * This parameter can be one of the following values : + * @arg RTC_MONOTONIC_COUNTER_1 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_MonotonicCounterIncrement(const RTC_HandleTypeDef *hrtc, uint32_t Instance) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + UNUSED(Instance); + + /* This register is read-only only and is incremented by one when a write access is done to this + register. This register cannot roll-over and is frozen when reaching the maximum value. */ + CLEAR_REG(TAMP->COUNT1R); + + return HAL_OK; +} + +/** + * @brief Monotonic counter. + * @param hrtc RTC handle + * @param Instance Monotonic counter Instance + * This parameter can be one of the following values : + * @arg RTC_MONOTONIC_COUNTER_1 + * @param pValue Pointer to the counter monotonic counter value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_MonotonicCounterGet(const RTC_HandleTypeDef *hrtc, uint32_t Instance, uint32_t *pValue) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + UNUSED(Instance); + + /* This register is read-only only and is incremented by one when a write access is done to this + register. This register cannot roll-over and is frozen when reaching the maximum value. */ + *pValue = READ_REG(TAMP->COUNT1R); + + return HAL_OK; +} + +/** + * @brief Set SSR Underflow detection with Interrupt. + * @note The application must ensure that the EXTI RTC interrupt line is enabled. + * @param hrtc RTC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_SetSSRU_IT(RTC_HandleTypeDef *hrtc) +{ + /* Process Locked */ + __HAL_LOCK(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Enable IT SSRU */ + __HAL_RTC_SSRU_ENABLE_IT(hrtc, RTC_IT_SSRU); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Deactivate SSR Underflow. + * @param hrtc RTC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_DeactivateSSRU(RTC_HandleTypeDef *hrtc) +{ + /* Process Locked */ + __HAL_LOCK(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* In case of interrupt mode is used, the interrupt source must disabled */ + __HAL_RTC_SSRU_DISABLE_IT(hrtc, RTC_IT_SSRU); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Handle SSR underflow interrupt request. + * @param hrtc RTC handle + * @retval None + */ +void HAL_RTCEx_SSRUIRQHandler(RTC_HandleTypeDef *hrtc) +{ + /* Get the pending status of the SSR Underflow Interrupt */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + if (READ_BIT(RTC->SMISR, RTC_SMISR_SSRUMF) != 0U) +#else + if (READ_BIT(RTC->MISR, RTC_MISR_SSRUMF) != 0U) +#endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + { + /* Immediately clear SSR underflow flag */ + WRITE_REG(RTC->SCR, RTC_SCR_CSSRUF); + + /* SSRU callback */ +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + /* Call SSRUEvent registered Callback */ + hrtc->SSRUEventCallback(hrtc); +#else + HAL_RTCEx_SSRUEventCallback(hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + + } + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; +} + +/** + * @brief SSR underflow callback. + * @param hrtc RTC handle + * @retval None + */ +__weak void HAL_RTCEx_SSRUEventCallback(RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RTCEx_SSRUEventCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @addtogroup RTCEx_Exported_Functions_Group4 + * @brief Extended features functions + * +@verbatim + =============================================================================== + ##### Extended features functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) RTC Alarm B callback + (+) RTC Poll for Alarm B request + +@endverbatim + * @{ + */ + +/** + * @brief Alarm B callback. + * @param hrtc RTC handle + * @retval None + */ +__weak void HAL_RTCEx_AlarmBEventCallback(RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RTCEx_AlarmBEventCallback could be implemented in the user file + */ +} + +/** + * @brief Handle Alarm B Polling request. + * @param hrtc RTC handle + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_PollForAlarmBEvent(const RTC_HandleTypeDef *hrtc, uint32_t Timeout) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + uint32_t tickstart = HAL_GetTick(); + + while (READ_BIT(RTC->SR, RTC_SR_ALRBF) == 0U) + { + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + /* New check to avoid false timeout detection in case of preemption */ + if (READ_BIT(RTC->SR, RTC_SR_ALRBF) == 0U) + { + return HAL_TIMEOUT; + } + else + { + break; + } + } + } + } + + /* Clear the Alarm Flag */ + WRITE_REG(RTC->SCR, RTC_SCR_CALRBF); + + return HAL_OK; +} + +/** + * @} + */ + +/** @addtogroup RTCEx_Exported_Functions_Group5 + * @brief Extended RTC Tamper functions + * +@verbatim + ============================================================================== + ##### Tamper functions ##### + ============================================================================== + [..] + (+) Before calling any tamper or internal tamper function, you have to call first + HAL_RTC_Init() function. + (+) In that one you can select to output tamper event on RTC pin. + [..] + (+) Enable the Tamper and configure the Tamper filter count, trigger Edge + or Level according to the Tamper filter (if equal to 0 Edge else Level) + value, sampling frequency, NoErase, MaskFlag, precharge or discharge and + Pull-UP, timestamp using the HAL_RTCEx_SetTamper() function. + You can configure Tamper with interrupt mode using HAL_RTCEx_SetTamper_IT() function. + (+) The default configuration of the Tamper erases the backup registers. To avoid + erase, enable the NoErase field on the TAMP_TAMPCR register. + [..] + (+) Enable Internal Tamper and configure it with interrupt, timestamp using + the HAL_RTCEx_SetInternalTamper() function. + +@endverbatim + * @{ + */ + + +/** + * @brief Set Tamper + * @param hrtc RTC handle + * @param sTamper Pointer to Tamper Structure. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_SetTamper(const RTC_HandleTypeDef *hrtc, const RTC_TamperTypeDef *sTamper) +{ + uint32_t tmpreg; + + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* Check the parameters */ + assert_param(IS_RTC_TAMPER(sTamper->Tamper)); + assert_param(IS_RTC_TAMPER_TRIGGER(sTamper->Trigger)); + assert_param(IS_RTC_TAMPER_ERASE_MODE(sTamper->NoErase)); + assert_param(IS_RTC_TAMPER_MASKFLAG_STATE(sTamper->MaskFlag)); + assert_param(IS_RTC_TAMPER_TIMESTAMPONTAMPER_DETECTION(sTamper->TimeStampOnTamperDetection)); +#if (RTC_TAMP_NB > 2U) + /* Mask flag only supported by TAMPER 1, 2 and 3 */ + assert_param(!((sTamper->MaskFlag != RTC_TAMPERMASK_FLAG_DISABLE) && (sTamper->Tamper > RTC_TAMPER_3))); +#else + assert_param(!((sTamper->MaskFlag != RTC_TAMPERMASK_FLAG_DISABLE) && (sTamper->Tamper > RTC_TAMPER_2))); +#endif /* (RTC_TAMP_NB > 2U) */ + assert_param(IS_RTC_TAMPER_FILTER(sTamper->Filter)); + assert_param(IS_RTC_TAMPER_SAMPLING_FREQ(sTamper->SamplingFrequency)); + assert_param(IS_RTC_TAMPER_PRECHARGE_DURATION(sTamper->PrechargeDuration)); + assert_param(IS_RTC_TAMPER_PULLUP_STATE(sTamper->TamperPullUp)); + /* Trigger and Filter have exclusive configurations */ + assert_param(((sTamper->Filter != RTC_TAMPERFILTER_DISABLE) && + ((sTamper->Trigger == RTC_TAMPERTRIGGER_LOWLEVEL) || + (sTamper->Trigger == RTC_TAMPERTRIGGER_HIGHLEVEL))) || + ((sTamper->Filter == RTC_TAMPERFILTER_DISABLE) && + ((sTamper->Trigger == RTC_TAMPERTRIGGER_RISINGEDGE) || + (sTamper->Trigger == RTC_TAMPERTRIGGER_FALLINGEDGE)))); + + /* Configuration register 2 */ + tmpreg = READ_REG(TAMP->CR2); + tmpreg &= ~((sTamper->Tamper << TAMP_CR2_TAMP1TRG_Pos) | (sTamper->Tamper << TAMP_CR2_TAMP1MSK_Pos) | + (sTamper->Tamper << TAMP_CR2_TAMP1NOERASE_Pos)); + + if ((sTamper->Trigger == RTC_TAMPERTRIGGER_HIGHLEVEL) || (sTamper->Trigger == RTC_TAMPERTRIGGER_FALLINGEDGE)) + { + tmpreg |= (sTamper->Tamper << TAMP_CR2_TAMP1TRG_Pos); + } + + if (sTamper->MaskFlag != RTC_TAMPERMASK_FLAG_DISABLE) + { + tmpreg |= (sTamper->Tamper << TAMP_CR2_TAMP1MSK_Pos); + } + + if (sTamper->NoErase != RTC_TAMPER_ERASE_BACKUP_ENABLE) + { + tmpreg |= (sTamper->Tamper << TAMP_CR2_TAMP1NOERASE_Pos); + } + WRITE_REG(TAMP->CR2, tmpreg); + + /* Filter control register */ + WRITE_REG(TAMP->FLTCR, sTamper->Filter | sTamper->SamplingFrequency | sTamper->PrechargeDuration | + sTamper->TamperPullUp); + + /* Timestamp on tamper */ + if (READ_BIT(RTC->CR, RTC_CR_TAMPTS) != sTamper->TimeStampOnTamperDetection) + { + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + MODIFY_REG(RTC->CR, RTC_CR_TAMPTS, sTamper->TimeStampOnTamperDetection); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + } + + /* Control register 1 */ + SET_BIT(TAMP->CR1, sTamper->Tamper); + + return HAL_OK; +} + + +/** + * @brief Set Tamper in IT mode + * @note The application must ensure that the EXTI TAMP interrupt line is enabled. + * @param hrtc RTC handle + * @param sTamper Pointer to Tamper Structure. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_SetTamper_IT(const RTC_HandleTypeDef *hrtc, const RTC_TamperTypeDef *sTamper) +{ + uint32_t tmpreg; + + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* Check the parameters */ + assert_param(IS_RTC_TAMPER(sTamper->Tamper)); + assert_param(IS_RTC_TAMPER_TRIGGER(sTamper->Trigger)); + assert_param(IS_RTC_TAMPER_ERASE_MODE(sTamper->NoErase)); + assert_param(IS_RTC_TAMPER_TIMESTAMPONTAMPER_DETECTION(sTamper->TimeStampOnTamperDetection)); + /* The interrupt must not be enabled when TAMPxMSK is set. */ + assert_param(sTamper->MaskFlag == RTC_TAMPERMASK_FLAG_DISABLE); + assert_param(IS_RTC_TAMPER_FILTER(sTamper->Filter)); + assert_param(IS_RTC_TAMPER_SAMPLING_FREQ(sTamper->SamplingFrequency)); + assert_param(IS_RTC_TAMPER_PRECHARGE_DURATION(sTamper->PrechargeDuration)); + assert_param(IS_RTC_TAMPER_PULLUP_STATE(sTamper->TamperPullUp)); + /* Trigger and Filter have exclusive configurations */ + assert_param(((sTamper->Filter != RTC_TAMPERFILTER_DISABLE) && + ((sTamper->Trigger == RTC_TAMPERTRIGGER_LOWLEVEL) || + (sTamper->Trigger == RTC_TAMPERTRIGGER_HIGHLEVEL))) || + ((sTamper->Filter == RTC_TAMPERFILTER_DISABLE) && + ((sTamper->Trigger == RTC_TAMPERTRIGGER_RISINGEDGE) || + (sTamper->Trigger == RTC_TAMPERTRIGGER_FALLINGEDGE)))); + + /* Configuration register 2 */ + tmpreg = READ_REG(TAMP->CR2); + tmpreg &= ~((sTamper->Tamper << TAMP_CR2_TAMP1TRG_Pos) | (sTamper->Tamper << TAMP_CR2_TAMP1MSK_Pos) | + (sTamper->Tamper << TAMP_CR2_TAMP1NOERASE_Pos)); + + if ((sTamper->Trigger == RTC_TAMPERTRIGGER_HIGHLEVEL) || (sTamper->Trigger == RTC_TAMPERTRIGGER_FALLINGEDGE)) + { + tmpreg |= (sTamper->Tamper << TAMP_CR2_TAMP1TRG_Pos); + } + + if (sTamper->NoErase != RTC_TAMPER_ERASE_BACKUP_ENABLE) + { + tmpreg |= (sTamper->Tamper << TAMP_CR2_TAMP1NOERASE_Pos); + } + WRITE_REG(TAMP->CR2, tmpreg); + + /* Filter control register */ + WRITE_REG(TAMP->FLTCR, sTamper->Filter | sTamper->SamplingFrequency | sTamper->PrechargeDuration | + sTamper->TamperPullUp); + + /* Timestamp on tamper */ + if (READ_BIT(RTC->CR, RTC_CR_TAMPTS) != sTamper->TimeStampOnTamperDetection) + { + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + MODIFY_REG(RTC->CR, RTC_CR_TAMPTS, sTamper->TimeStampOnTamperDetection); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + } + + /* Interrupt enable register */ + SET_BIT(TAMP->IER, sTamper->Tamper); + + /* Control register 1 */ + SET_BIT(TAMP->CR1, sTamper->Tamper); + + return HAL_OK; +} + +/** + * @brief Deactivate Tamper. + * @param hrtc RTC handle + * @param Tamper Selected tamper pin. + * This parameter can be a combination of the following values: + * @arg RTC_TAMPER_1 + * @arg RTC_TAMPER_2 + * @arg RTC_TAMPER_3 + * @arg RTC_TAMPER_4 + * @arg RTC_TAMPER_5 + * @arg RTC_TAMPER_6 + * @arg RTC_TAMPER_7 + * @arg RTC_TAMPER_8 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_DeactivateTamper(const RTC_HandleTypeDef *hrtc, uint32_t Tamper) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + assert_param(IS_RTC_TAMPER(Tamper)); + + /* Disable the selected Tamper pin */ + CLEAR_BIT(TAMP->CR1, Tamper); + + /* Clear tamper interrupt and event flags (WO register) */ + WRITE_REG(TAMP->SCR, Tamper); + + /* Clear tamper mask/noerase/trigger configuration */ + CLEAR_BIT(TAMP->CR2, (Tamper << TAMP_CR2_TAMP1TRG_Pos) | (Tamper << TAMP_CR2_TAMP1MSK_Pos) | \ + (Tamper << TAMP_CR2_TAMP1NOERASE_Pos)); + + /* Clear tamper interrupt mode configuration */ + CLEAR_BIT(TAMP->IER, Tamper); + + return HAL_OK; +} + +/** + * @brief Set all active Tampers at the same time. + * @note For interrupt mode, the application must ensure that the EXTI TAMP interrupt line is enabled. + * @param hrtc RTC handle + * @param sAllTamper Pointer to active Tamper Structure. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_SetActiveTampers(RTC_HandleTypeDef *hrtc, const RTC_ActiveTampersTypeDef *sAllTamper) +{ + uint32_t tmp_ier; + uint32_t tmp_cr1; + uint32_t tmp_cr2; + uint32_t tmp_atcr1; + uint32_t tmp_atcr2; + uint32_t tmp_cr; + uint32_t i; + uint32_t tickstart; + +#ifdef USE_FULL_ASSERT + for (i = 0; i < RTC_TAMP_NB; i++) + { + assert_param(IS_RTC_TAMPER_ERASE_MODE(sAllTamper->TampInput[i].NoErase)); + assert_param(IS_RTC_TAMPER_MASKFLAG_STATE(sAllTamper->TampInput[i].MaskFlag)); + /* Mask flag only supported by TAMPER 1, 2 and 3 */ + assert_param(!((sAllTamper->TampInput[i].MaskFlag == RTC_TAMPERMASK_FLAG_ENABLE) && + (i >= RTC_TAMPER_MASKABLE_NB))); + } + assert_param(IS_RTC_TAMPER_TIMESTAMPONTAMPER_DETECTION(sAllTamper->TimeStampOnTamperDetection)); + assert_param(IS_RTC_ATAMPER_FILTER(sAllTamper->ActiveFilter)); + assert_param(IS_RTC_ATAMPER_OUTPUT_CHANGE_PERIOD(sAllTamper->ActiveOutputChangePeriod)); + assert_param(IS_RTC_ATAMPER_ASYNCPRES_RTCCLK(sAllTamper->ActiveAsyncPrescaler)); +#endif /* USE_FULL_ASSERT */ + + /* Active Tampers must not be already enabled */ + if (READ_BIT(TAMP->ATOR, TAMP_ATOR_INITS) != 0U) + { + /* Disable all actives tampers with HAL_RTCEx_DeactivateActiveTampers. + No need to check return value because it returns always HAL_OK */ + (void) HAL_RTCEx_DeactivateActiveTampers(hrtc); + } + + /* Set TimeStamp on tamper detection */ + tmp_cr = READ_REG(RTC->CR); + if ((tmp_cr & RTC_CR_TAMPTS) != (sAllTamper->TimeStampOnTamperDetection)) + { + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + MODIFY_REG(RTC->CR, RTC_CR_TAMPTS, sAllTamper->TimeStampOnTamperDetection); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + } + + tmp_cr1 = READ_REG(TAMP->CR1); + tmp_cr2 = READ_REG(TAMP->CR2); + tmp_atcr2 = 0U; + tmp_ier = READ_REG(TAMP->IER); + + /* Set common parameters */ + tmp_atcr1 = (sAllTamper->ActiveFilter | (sAllTamper->ActiveOutputChangePeriod << TAMP_ATCR1_ATPER_Pos) | + sAllTamper->ActiveAsyncPrescaler); + + /* Set specific parameters for each active tamper inputs if enable */ + for (i = 0; i < RTC_TAMP_NB; i++) + { + if (sAllTamper->TampInput[i].Enable != RTC_ATAMP_DISABLE) + { + tmp_cr1 |= (TAMP_CR1_TAMP1E << i); + tmp_atcr1 |= (TAMP_ATCR1_TAMP1AM << i); + + if (sAllTamper->TampInput[i].Interrupt != RTC_ATAMP_INTERRUPT_DISABLE) + { + /* Interrupt enable register */ + tmp_ier |= (TAMP_IER_TAMP1IE << i); + } + + if (sAllTamper->TampInput[i].MaskFlag != RTC_TAMPERMASK_FLAG_DISABLE) + { + tmp_cr2 |= (TAMP_CR2_TAMP1MSK << i); + } + + if (sAllTamper->TampInput[i].NoErase != RTC_TAMPER_ERASE_BACKUP_ENABLE) + { + tmp_cr2 |= (TAMP_CR2_TAMP1NOERASE << i); + } + + /* Configure ATOSELx[] in case of output sharing */ + tmp_atcr2 |= sAllTamper->TampInput[i].Output << ((3U * i) + TAMP_ATCR2_ATOSEL1_Pos); + + if (i != sAllTamper->TampInput[i].Output) + { + tmp_atcr1 |= TAMP_ATCR1_ATOSHARE; + } + } + } + + WRITE_REG(TAMP->IER, tmp_ier); + WRITE_REG(TAMP->ATCR1, tmp_atcr1); + WRITE_REG(TAMP->ATCR2, tmp_atcr2); + WRITE_REG(TAMP->CR2, tmp_cr2); + WRITE_REG(TAMP->CR1, tmp_cr1); + + /* Write seed */ + for (i = 0; i < RTC_ATAMP_SEED_NB_UINT32; i++) + { + WRITE_REG(TAMP->ATSEEDR, sAllTamper->Seed[i]); + } + + /* Wait till RTC SEEDF flag is cleared and if Time out is reached exit */ + tickstart = HAL_GetTick(); + while (READ_BIT(TAMP->ATOR, TAMP_ATOR_SEEDF) != 0U) + { + if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE) + { + /* New check to avoid false timeout detection in case of preemption */ + if (READ_BIT(TAMP->ATOR, TAMP_ATOR_SEEDF) != 0U) + { + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_TIMEOUT; + + return HAL_TIMEOUT; + } + else + { + break; + } + } + } + + return HAL_OK; +} + +/** + * @brief Write a new seed. Active tamper must be enabled. + * @param hrtc RTC handle + * @param pSeed Pointer to active tamper seed values. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_SetActiveSeed(RTC_HandleTypeDef *hrtc, const uint32_t *pSeed) +{ + uint32_t i; + uint32_t tickstart; + + /* Active Tampers must be enabled */ + if (READ_BIT(TAMP->ATOR, TAMP_ATOR_INITS) == 0U) + { + return HAL_ERROR; + } + + for (i = 0; i < RTC_ATAMP_SEED_NB_UINT32; i++) + { + WRITE_REG(TAMP->ATSEEDR, pSeed[i]); + } + + /* Wait till RTC SEEDF flag is cleared and if Time out is reached exit */ + tickstart = HAL_GetTick(); + while (READ_BIT(TAMP->ATOR, TAMP_ATOR_SEEDF) != 0U) + { + if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE) + { + /* New check to avoid false timeout detection in case of preemption */ + if (READ_BIT(TAMP->ATOR, TAMP_ATOR_SEEDF) != 0U) + { + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_TIMEOUT; + + return HAL_TIMEOUT; + } + else + { + break; + } + } + } + + return HAL_OK; +} + +#if defined(TAMP_SECCFGR_BHKLOCK) +/** + * @brief Lock the Boot hardware Key + * @param hrtc RTC handle + * @note The backup registers from TAMP_BKP0R to TAMP_BKP7R cannot be accessed neither in + * read nor in write (they are read as 0 and write ignore). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_LockBootHardwareKey(const RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + WRITE_REG(TAMP->SECCFGR, TAMP_SECCFGR_BHKLOCK); + + return HAL_OK; +} +#endif /* TAMP_SECCFGR_BHKLOCK */ + +/** + * @brief Deactivate all Active Tampers at the same time. + * @param hrtc RTC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_DeactivateActiveTampers(const RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* Get Active tampers */ + uint32_t atamp_mask = READ_BIT(TAMP->ATCR1, TAMP_ALL); + + /* Disable all actives tampers but not passives tampers */ + CLEAR_BIT(TAMP->CR1, atamp_mask); + + /* Clear tamper interrupt and event flags (WO register) of all actives tampers but not passives tampers */ + WRITE_REG(TAMP->SCR, atamp_mask); + + /* Disable no erase and mask */ +#if (RTC_TAMPER_MASKABLE_NB == 2) + CLEAR_BIT(TAMP->CR2, (atamp_mask | ((atamp_mask & (TAMP_ATCR1_TAMP1AM | TAMP_ATCR1_TAMP2AM)) << + TAMP_CR2_TAMP1MSK_Pos))); +#else + CLEAR_BIT(TAMP->CR2, (atamp_mask | ((atamp_mask & (TAMP_ATCR1_TAMP1AM | TAMP_ATCR1_TAMP2AM | TAMP_ATCR1_TAMP3AM)) << + TAMP_CR2_TAMP1MSK_Pos))); +#endif /* RTC_TAMPER_MASKABLE_NB */ + + /* Clear all active tampers interrupt mode configuration but not passives tampers */ + CLEAR_BIT(TAMP->IER, atamp_mask); + + /* Set reset value for active tamper control register 1 */ + WRITE_REG(TAMP->ATCR1, TAMP_ATCR1_ATCKSEL); + + /* Set reset value for active tamper control register 2 */ + CLEAR_REG(TAMP->ATCR2); + + return HAL_OK; +} + + +/** + * @brief Tamper event polling. + * @param hrtc RTC handle + * @param Tamper Selected tamper pin. + * This parameter can be a combination of the following values: + * @arg RTC_TAMPER_1 + * @arg RTC_TAMPER_2 + * @arg RTC_TAMPER_3 + * @arg RTC_TAMPER_4 + * @arg RTC_TAMPER_5 + * @arg RTC_TAMPER_6 + * @arg RTC_TAMPER_7 + * @arg RTC_TAMPER_8 + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_PollForTamperEvent(const RTC_HandleTypeDef *hrtc, uint32_t Tamper, uint32_t Timeout) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + assert_param(IS_RTC_TAMPER(Tamper)); + + uint32_t tickstart = HAL_GetTick(); + + /* Get the status of the Interrupt */ + while (READ_BIT(TAMP->SR, Tamper) != Tamper) + { + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + /* New check to avoid false timeout detection in case of preemption */ + if (READ_BIT(TAMP->SR, Tamper) != Tamper) + { + return HAL_TIMEOUT; + } + else + { + break; + } + } + } + } + + /* Clear the Tamper Flag */ + WRITE_REG(TAMP->SCR, Tamper); + + return HAL_OK; +} + + +/** + * @brief Set Internal Tamper + * @param hrtc RTC handle + * @param sIntTamper Pointer to Internal Tamper Structure. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_SetInternalTamper(const RTC_HandleTypeDef *hrtc, + const RTC_InternalTamperTypeDef *sIntTamper) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* Check the parameters */ + assert_param(IS_RTC_INTERNAL_TAMPER(sIntTamper->IntTamper)); + assert_param(IS_RTC_TAMPER_TIMESTAMPONTAMPER_DETECTION(sIntTamper->TimeStampOnTamperDetection)); + assert_param(IS_RTC_TAMPER_ERASE_MODE(sIntTamper->NoErase)); + + /* Timestamp enable on internal tamper */ + if (READ_BIT(RTC->CR, RTC_CR_TAMPTS) != sIntTamper->TimeStampOnTamperDetection) + { + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + MODIFY_REG(RTC->CR, RTC_CR_TAMPTS, sIntTamper->TimeStampOnTamperDetection); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + } + + /* No Erase Backup register enable for Internal Tamper */ + if (sIntTamper->NoErase != RTC_TAMPER_ERASE_BACKUP_ENABLE) + { + SET_BIT(TAMP->CR3, (sIntTamper->IntTamper >> (TAMP_CR1_ITAMP1E_Pos - TAMP_CR3_ITAMP1NOER_Pos))); + } + else + { + CLEAR_BIT(TAMP->CR3, (sIntTamper->IntTamper >> (TAMP_CR1_ITAMP1E_Pos - TAMP_CR3_ITAMP1NOER_Pos))); + } + + /* Enable Internal Tamper */ + SET_BIT(TAMP->CR1, sIntTamper->IntTamper); + + return HAL_OK; +} + + +/** + * @brief Set Internal Tamper in interrupt mode + * @note The application must ensure that the EXTI TAMP interrupt line is enabled. + * @param hrtc RTC handle + * @param sIntTamper Pointer to Internal Tamper Structure. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_SetInternalTamper_IT(const RTC_HandleTypeDef *hrtc, + const RTC_InternalTamperTypeDef *sIntTamper) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* Check the parameters */ + assert_param(IS_RTC_INTERNAL_TAMPER(sIntTamper->IntTamper)); + assert_param(IS_RTC_TAMPER_TIMESTAMPONTAMPER_DETECTION(sIntTamper->TimeStampOnTamperDetection)); + assert_param(IS_RTC_TAMPER_ERASE_MODE(sIntTamper->NoErase)); + + /* Timestamp enable on internal tamper */ + if (READ_BIT(RTC->CR, RTC_CR_TAMPTS) != sIntTamper->TimeStampOnTamperDetection) + { + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + MODIFY_REG(RTC->CR, RTC_CR_TAMPTS, sIntTamper->TimeStampOnTamperDetection); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + } + + /* Interrupt enable register */ + SET_BIT(TAMP->IER, sIntTamper->IntTamper); + + /* No Erase Backup register enable for Internal Tamper */ + if (sIntTamper->NoErase != RTC_TAMPER_ERASE_BACKUP_ENABLE) + { + SET_BIT(TAMP->CR3, (sIntTamper->IntTamper >> (TAMP_CR1_ITAMP1E_Pos - TAMP_CR3_ITAMP1NOER_Pos))); + } + else + { + CLEAR_BIT(TAMP->CR3, (sIntTamper->IntTamper >> (TAMP_CR1_ITAMP1E_Pos - TAMP_CR3_ITAMP1NOER_Pos))); + } + + /* Enable Internal Tamper */ + SET_BIT(TAMP->CR1, sIntTamper->IntTamper); + + return HAL_OK; +} + +/** + * @brief Deactivate Internal Tamper. + * @param hrtc RTC handle + * @param IntTamper Selected internal tamper event. + * This parameter can be any combination of existing internal tampers. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_DeactivateInternalTamper(const RTC_HandleTypeDef *hrtc, uint32_t IntTamper) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + assert_param(IS_RTC_INTERNAL_TAMPER(IntTamper)); + + /* Disable the selected Tamper pin */ + CLEAR_BIT(TAMP->CR1, IntTamper); + + /* Clear internal tamper interrupt mode configuration */ + CLEAR_BIT(TAMP->IER, IntTamper); + + /* Clear internal tamper interrupt */ + WRITE_REG(TAMP->SCR, IntTamper); + + return HAL_OK; +} + +/** + * @brief Internal Tamper event polling. + * @param hrtc RTC handle + * @param IntTamper selected tamper. + * This parameter can be any combination of existing internal tampers. + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_PollForInternalTamperEvent(const RTC_HandleTypeDef *hrtc, uint32_t IntTamper, + uint32_t Timeout) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + assert_param(IS_RTC_INTERNAL_TAMPER(IntTamper)); + + uint32_t tickstart = HAL_GetTick(); + + /* Get the status of the Interrupt */ + while (READ_BIT(TAMP->SR, IntTamper) != IntTamper) + { + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + /* New check to avoid false timeout detection in case of preemption */ + if (READ_BIT(TAMP->SR, IntTamper) != IntTamper) + { + return HAL_TIMEOUT; + } + else + { + break; + } + } + } + } + + /* Clear the Tamper Flag */ + WRITE_REG(TAMP->SCR, IntTamper); + + return HAL_OK; +} + +/** + * @brief Handle Tamper interrupt request. + * @param hrtc RTC handle + * @retval None + */ +void HAL_RTCEx_TamperIRQHandler(RTC_HandleTypeDef *hrtc) +{ + /* Get the pending status of the Tampers Interrupt */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + uint32_t tmp = READ_REG(TAMP->SMISR); +#else + uint32_t tmp = READ_REG(TAMP->MISR); +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + /* Check Tamper1 status */ + if ((tmp & RTC_TAMPER_1) == RTC_TAMPER_1) + { +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + /* Call Tamper 1 Event registered secure Callback */ + hrtc->Tamper1EventCallback(hrtc); +#else + /* Tamper1 secure callback */ + HAL_RTCEx_Tamper1EventCallback(hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + } + + /* Check Tamper2 status */ + if ((tmp & RTC_TAMPER_2) == RTC_TAMPER_2) + { +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + /* Call Tamper 2 Event registered secure Callback */ + hrtc->Tamper2EventCallback(hrtc); +#else + /* Tamper2 secure callback */ + HAL_RTCEx_Tamper2EventCallback(hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + } + +#if (RTC_TAMP_NB > 2U) + /* Check Tamper3 status */ + if ((tmp & RTC_TAMPER_3) == RTC_TAMPER_3) + { +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + /* Call Tamper 3 Event registered secure Callback */ + hrtc->Tamper3EventCallback(hrtc); +#else + /* Tamper3 secure callback */ + HAL_RTCEx_Tamper3EventCallback(hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + } + + /* Check Tamper4 status */ + if ((tmp & RTC_TAMPER_4) == RTC_TAMPER_4) + { +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + /* Call Tamper 4 Event registered secure Callback */ + hrtc->Tamper4EventCallback(hrtc); +#else + /* Tamper4 secure callback */ + HAL_RTCEx_Tamper4EventCallback(hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + } + + /* Check Tamper5 status */ + if ((tmp & RTC_TAMPER_5) == RTC_TAMPER_5) + { +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + /* Call Tamper 5 Event registered secure Callback */ + hrtc->Tamper5EventCallback(hrtc); +#else + /* Tamper5 secure callback */ + HAL_RTCEx_Tamper5EventCallback(hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + } + + /* Check Tamper6 status */ + if ((tmp & RTC_TAMPER_6) == RTC_TAMPER_6) + { +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + /* Call Tamper 6 Event registered secure Callback */ + hrtc->Tamper6EventCallback(hrtc); +#else + /* Tamper6 secure callback */ + HAL_RTCEx_Tamper6EventCallback(hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + } + + /* Check Tamper7 status */ + if ((tmp & RTC_TAMPER_7) == RTC_TAMPER_7) + { +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + /* Call Tamper 7 Event registered secure Callback */ + hrtc->Tamper7EventCallback(hrtc); +#else + /* Tamper7 secure callback */ + HAL_RTCEx_Tamper7EventCallback(hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + } + + /* Check Tamper8 status */ + if ((tmp & RTC_TAMPER_8) == RTC_TAMPER_8) + { +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + /* Call Tamper 8 Event registered secure Callback */ + hrtc->Tamper8EventCallback(hrtc); +#else + /* Tamper8 secure callback */ + HAL_RTCEx_Tamper8EventCallback(hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + } +#endif /* (RTC_TAMP_NB > 2U) */ + + /* Check Internal Tamper1 status */ + if ((tmp & RTC_INT_TAMPER_1) == RTC_INT_TAMPER_1) + { +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + /* Call Internal Tamper 1 Event registered secure Callback */ + hrtc->InternalTamper1EventCallback(hrtc); +#else + /* Internal Tamper1 secure callback */ + HAL_RTCEx_InternalTamper1EventCallback(hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + } + + /* Check Internal Tamper2 status */ + if ((tmp & RTC_INT_TAMPER_2) == RTC_INT_TAMPER_2) + { +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + /* Call Internal Tamper 2 Event registered secure Callback */ + hrtc->InternalTamper2EventCallback(hrtc); +#else + /* Internal Tamper2 secure callback */ + HAL_RTCEx_InternalTamper2EventCallback(hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + } + + /* Check Internal Tamper3 status */ + if ((tmp & RTC_INT_TAMPER_3) == RTC_INT_TAMPER_3) + { +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + /* Call Internal Tamper 3 Event registered secure Callback */ + hrtc->InternalTamper3EventCallback(hrtc); +#else + /* Internal Tamper3 secure callback */ + HAL_RTCEx_InternalTamper3EventCallback(hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + } + + /* Check Internal Tamper4 status */ + if ((tmp & RTC_INT_TAMPER_4) == RTC_INT_TAMPER_4) + { +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + /* Call Internal Tamper 4 Event registered secure Callback */ + hrtc->InternalTamper4EventCallback(hrtc); +#else + /* Internal Tamper4 secure callback */ + HAL_RTCEx_InternalTamper4EventCallback(hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + } + + /* Check Internal Tamper5 status */ + if ((tmp & RTC_INT_TAMPER_5) == RTC_INT_TAMPER_5) + { +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + /* Call Internal Tamper 5 Event registered secure Callback */ + hrtc->InternalTamper5EventCallback(hrtc); +#else + /* Internal Tamper5 secure callback */ + HAL_RTCEx_InternalTamper5EventCallback(hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + } + + /* Check Internal Tamper6 status */ + if ((tmp & RTC_INT_TAMPER_6) == RTC_INT_TAMPER_6) + { +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + /* Call Internal Tamper 6 Event registered secure Callback */ + hrtc->InternalTamper6EventCallback(hrtc); +#else + /* Internal Tamper6 secure callback */ + HAL_RTCEx_InternalTamper6EventCallback(hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + } + + /* Check Internal Tamper7 status */ + if ((tmp & RTC_INT_TAMPER_7) == RTC_INT_TAMPER_7) + { +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + /* Call Internal Tamper 7 Event registered secure Callback */ + hrtc->InternalTamper7EventCallback(hrtc); +#else + /* Internal Tamper7 secure callback */ + HAL_RTCEx_InternalTamper7EventCallback(hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + } + + /* Check Internal Tamper8 status */ + if ((tmp & RTC_INT_TAMPER_8) == RTC_INT_TAMPER_8) + { +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + /* Call Internal Tamper 8 Event registered secure Callback */ + hrtc->InternalTamper8EventCallback(hrtc); +#else + /* Internal Tamper8 secure callback */ + HAL_RTCEx_InternalTamper8EventCallback(hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + } + + /* Check Internal Tamper9 status */ + if ((tmp & RTC_INT_TAMPER_9) == RTC_INT_TAMPER_9) + { +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + /* Call Internal Tamper 9 Event registered secure Callback */ + hrtc->InternalTamper9EventCallback(hrtc); +#else + /* Internal Tamper9 secure callback */ + HAL_RTCEx_InternalTamper9EventCallback(hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + } + + /* Check Internal Tamper11 status */ + if ((tmp & RTC_INT_TAMPER_11) == RTC_INT_TAMPER_11) + { +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + /* Call Internal Tamper 11 Event registered secure Callback */ + hrtc->InternalTamper11EventCallback(hrtc); +#else + /* Internal Tamper11 secure callback */ + HAL_RTCEx_InternalTamper11EventCallback(hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + } + + /* Check Internal Tamper12 status */ + if ((tmp & RTC_INT_TAMPER_12) == RTC_INT_TAMPER_12) + { +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + /* Call Internal Tamper 12 Event registered secure Callback */ + hrtc->InternalTamper12EventCallback(hrtc); +#else + /* Internal Tamper12 secure callback */ + HAL_RTCEx_InternalTamper12EventCallback(hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + } + + /* Check Internal Tamper13 status */ + if ((tmp & RTC_INT_TAMPER_13) == RTC_INT_TAMPER_13) + { +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + /* Call Internal Tamper 13 Event registered secure Callback */ + hrtc->InternalTamper13EventCallback(hrtc); +#else + /* Internal Tamper13 secure callback */ + HAL_RTCEx_InternalTamper13EventCallback(hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + } + + /* Check Internal Tamper15 status */ + if ((tmp & RTC_INT_TAMPER_15) == RTC_INT_TAMPER_15) + { +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) + /* Call Internal Tamper 15 Event registered secure Callback */ + hrtc->InternalTamper15EventCallback(hrtc); +#else + /* Internal Tamper15 secure callback */ + HAL_RTCEx_InternalTamper15EventCallback(hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + } + + /* Clear flags after treatment to allow the potential tamper feature */ + WRITE_REG(TAMP->SCR, tmp); +} + +/** + * @brief Tamper 1 callback. + * @param hrtc RTC handle + * @retval None + */ +__weak void HAL_RTCEx_Tamper1EventCallback(RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RTCEx_Tamper1EventCallback could be implemented in the user file + */ +} + +/** + * @brief Tamper 2 callback. + * @param hrtc RTC handle + * @retval None + */ +__weak void HAL_RTCEx_Tamper2EventCallback(RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RTCEx_Tamper2EventCallback could be implemented in the user file + */ +} + +/** + * @brief Tamper 3 callback. + * @param hrtc RTC handle + * @retval None + */ +__weak void HAL_RTCEx_Tamper3EventCallback(RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RTCEx_Tamper3EventCallback could be implemented in the user file + */ +} + +/** + * @brief Tamper 4 callback. + * @param hrtc RTC handle + * @retval None + */ +__weak void HAL_RTCEx_Tamper4EventCallback(RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RTCEx_Tamper4EventCallback could be implemented in the user file + */ +} + +/** + * @brief Tamper 5 callback. + * @param hrtc RTC handle + * @retval None + */ +__weak void HAL_RTCEx_Tamper5EventCallback(RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RTCEx_Tamper5EventCallback could be implemented in the user file + */ +} + +/** + * @brief Tamper 6 callback. + * @param hrtc RTC handle + * @retval None + */ +__weak void HAL_RTCEx_Tamper6EventCallback(RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RTCEx_Tamper6EventCallback could be implemented in the user file + */ +} + +/** + * @brief Tamper 7 callback. + * @param hrtc RTC handle + * @retval None + */ +__weak void HAL_RTCEx_Tamper7EventCallback(RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RTCEx_Tamper7EventCallback could be implemented in the user file + */ +} + +/** + * @brief Tamper 8 callback. + * @param hrtc RTC handle + * @retval None + */ +__weak void HAL_RTCEx_Tamper8EventCallback(RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RTCEx_Tamper8EventCallback could be implemented in the user file + */ +} + +/** + * @brief Internal Tamper 1 callback. + * @param hrtc RTC handle + * @retval None + */ +__weak void HAL_RTCEx_InternalTamper1EventCallback(RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RTCEx_InternalTamper1EventCallback could be implemented in the user file + */ +} + +/** + * @brief Internal Tamper 2 callback. + * @param hrtc RTC handle + * @retval None + */ +__weak void HAL_RTCEx_InternalTamper2EventCallback(RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RTCEx_InternalTamper2EventCallback could be implemented in the user file + */ +} + +/** + * @brief Internal Tamper 3 callback. + * @param hrtc RTC handle + * @retval None + */ +__weak void HAL_RTCEx_InternalTamper3EventCallback(RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RTCEx_InternalTamper3EventCallback could be implemented in the user file + */ +} + +/** + * @brief Internal Tamper 4 callback. + * @param hrtc RTC handle + * @retval None + */ +__weak void HAL_RTCEx_InternalTamper4EventCallback(RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RTCEx_InternalTamper4EventCallback could be implemented in the user file + */ +} + +/** + * @brief Internal Tamper 5 callback. + * @param hrtc RTC handle + * @retval None + */ +__weak void HAL_RTCEx_InternalTamper5EventCallback(RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RTCEx_InternalTamper5EventCallback could be implemented in the user file + */ +} + +/** + * @brief Internal Tamper 6 callback. + * @param hrtc RTC handle + * @retval None + */ +__weak void HAL_RTCEx_InternalTamper6EventCallback(RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RTCEx_InternalTamper6EventCallback could be implemented in the user file + */ +} + +/** + * @brief Internal Tamper 7 callback. + * @param hrtc RTC handle + * @retval None + */ +__weak void HAL_RTCEx_InternalTamper7EventCallback(RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RTCEx_InternalTamper7EventCallback could be implemented in the user file + */ +} + +/** + * @brief Internal Tamper 8 callback. + * @param hrtc RTC handle + * @retval None + */ +__weak void HAL_RTCEx_InternalTamper8EventCallback(RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RTCEx_InternalTamper8EventCallback could be implemented in the user file + */ +} + +/** + * @brief Internal Tamper 9 callback. + * @param hrtc RTC handle + * @retval None + */ +__weak void HAL_RTCEx_InternalTamper9EventCallback(RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RTCEx_InternalTamper9EventCallback could be implemented in the user file + */ +} + +/** + * @brief Internal Tamper 11 callback. + * @param hrtc RTC handle + * @retval None + */ +__weak void HAL_RTCEx_InternalTamper11EventCallback(RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RTCEx_InternalTamper11EventCallback could be implemented in the user file + */ +} + +/** + * @brief Internal Tamper 12 callback. + * @param hrtc RTC handle + * @retval None + */ +__weak void HAL_RTCEx_InternalTamper12EventCallback(RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RTCEx_InternalTamper12EventCallback could be implemented in the user file + */ +} + +/** + * @brief Internal Tamper 13 callback. + * @param hrtc RTC handle + * @retval None + */ +__weak void HAL_RTCEx_InternalTamper13EventCallback(RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RTCEx_InternalTamper13EventCallback could be implemented in the user file + */ +} + +/** + * @brief Internal Tamper 15 callback. + * @param hrtc RTC handle + * @retval None + */ +__weak void HAL_RTCEx_InternalTamper15EventCallback(RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_RTCEx_InternalTamper15EventCallback could be implemented in the user file + */ +} +/** + * @} + */ + + +/** @addtogroup RTCEx_Exported_Functions_Group6 + * @brief Extended RTC Backup register functions + * +@verbatim + =============================================================================== + ##### Extended RTC Backup register functions ##### + =============================================================================== + [..] + (+) Before calling any tamper or internal tamper function, you have to call first + HAL_RTC_Init() function. + (+) In that one you can select to output tamper event on RTC pin. + [..] + This subsection provides functions allowing to + (+) Write a data in a specified RTC Backup data register + (+) Read a data in a specified RTC Backup data register +@endverbatim + * @{ + */ + + +/** + * @brief Write a data in a specified RTC Backup data register. + * @param hrtc RTC handle + * @param BackupRegister RTC Backup data Register number. + * This parameter can be RTC_BKP_DRx where x can be from 0 to RTC_BACKUP_NB + * @param Data Data to be written in the specified Backup data register. + * @retval None + */ +void HAL_RTCEx_BKUPWrite(const RTC_HandleTypeDef *hrtc, uint32_t BackupRegister, uint32_t Data) +{ + uint32_t tmp; + + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* Check the parameters */ + assert_param(IS_RTC_BKP(BackupRegister)); + + /* Determine address of the specified Backup register */ + tmp = (uint32_t)(&(TAMP->BKP0R)); + tmp += (BackupRegister * 4U); + + /* Write data in the specified register Backup register */ + *(__IO uint32_t *)tmp = (uint32_t)Data; +} + + +/** + * @brief Reads data from the specified RTC Backup data Register. + * @param hrtc RTC handle + * @param BackupRegister RTC Backup data Register number. + * This parameter can be RTC_BKP_DRx where x can be from 0 to RTC_BACKUP_NB + * @retval Read value + */ +uint32_t HAL_RTCEx_BKUPRead(const RTC_HandleTypeDef *hrtc, uint32_t BackupRegister) +{ + uint32_t tmp; + + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* Check the parameters */ + assert_param(IS_RTC_BKP(BackupRegister)); + + /* Determine address of the specified Backup register */ + tmp = (uint32_t)(&(TAMP->BKP0R)); + tmp += (BackupRegister * 4U); + + /* Read the data from the specified register */ + return (*(__IO uint32_t *)tmp); +} + +/** + * @brief Reset the RTC Backup data Registers and the device secrets. + * @param hrtc RTC handle + * @retval None + */ +void HAL_RTCEx_BKUPErase(const RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + SET_BIT(TAMP->CR2, TAMP_CR2_BKERASE); +} + +/** + * @brief Block the access to the RTC Backup data Register and all the device secrets. + * @param hrtc RTC handle + * @retval None + */ +void HAL_RTCEx_BKUPBlock(const RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + WRITE_REG(TAMP->CR2, TAMP_CR2_BKBLOCK); +} + +/** + * @brief Disable the Block to the access to the RTC Backup data Register and the device secrets. + * @param hrtc RTC handle + * @retval None + */ +void HAL_RTCEx_BKUPUnblock(const RTC_HandleTypeDef *hrtc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + CLEAR_BIT(TAMP->CR2, TAMP_CR2_BKBLOCK); +} + +#ifdef TAMP_ERCFGR_ERCFG0 +/** + * @brief Enable and Disable the erase of the configurable Device Secrets + * @note This API must be called before enabling the Tamper. + * @param hrtc RTC handle + * @param DeviceSecretConf Specifies the configuration of the Device Secrets + * This parameter can be a combination of the following values: + * @arg TAMP_DEVICESECRETS_ERASE_NONE + * @arg TAMP_DEVICESECRETS_ERASE_BKPSRAM + * + * @retval None + */ +void HAL_RTCEx_ConfigEraseDeviceSecrets(const RTC_HandleTypeDef *hrtc, uint32_t DeviceSecretConf) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + MODIFY_REG(TAMP->ERCFGR, TAMP_ERCFGR_ERCFG0, DeviceSecretConf); +} +#endif /* TAMP_ERCFGR_ERCFG0 */ + +/** + * @} + */ + +#if defined(RTC_SECCFGR_SEC) +/** @addtogroup RTCEx_Exported_Functions_Group7 + * @brief Extended RTC security functions + * +@verbatim + =============================================================================== + ##### Extended RTC security functions ##### + =============================================================================== + [..] + (+) Before calling security function, you have to call first + HAL_RTC_Init() function. +@endverbatim + * @{ + */ + +/** + * @brief Get the security level of the RTC/TAMP/Backup registers. + * To set the secure level please call HAL_RTCEx_SecureModeSet. + * @param hrtc RTC handle + * @param secureState Secure state + * @retval HAL_StatusTypeDef + */ +HAL_StatusTypeDef HAL_RTCEx_SecureModeGet(const RTC_HandleTypeDef *hrtc, RTC_SecureStateTypeDef *secureState) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* Read registers */ + uint32_t rtc_seccfgr = READ_REG(RTC->SECCFGR); + uint32_t tamp_seccfgr = READ_REG(TAMP->SECCFGR); + + /* RTC */ + secureState->rtcSecureFull = READ_BIT(rtc_seccfgr, RTC_SECCFGR_SEC); + + /* Warning, rtcNonSecureFeatures is only relevant if secureState->rtcSecureFull == RTC_SECURE_FULL_NO */ + secureState->rtcNonSecureFeatures = ~(READ_BIT(rtc_seccfgr, RTC_NONSECURE_FEATURE_ALL)) & RTC_NONSECURE_FEATURE_ALL; + + /* TAMP */ + secureState->tampSecureFull = READ_BIT(tamp_seccfgr, TAMP_SECCFGR_TAMPSEC); + + /* Monotonic Counter */ + secureState->MonotonicCounterSecure = READ_BIT(tamp_seccfgr, TAMP_SECCFGR_CNT1SEC); + + /* Backup register start zones + Warning : Backup register start zones are shared with privilege configuration */ + secureState->backupRegisterStartZone2 = READ_BIT(tamp_seccfgr, TAMP_SECCFGR_BKPRWSEC) >> TAMP_SECCFGR_BKPRWSEC_Pos; + secureState->backupRegisterStartZone3 = READ_BIT(tamp_seccfgr, TAMP_SECCFGR_BKPWSEC) >> TAMP_SECCFGR_BKPWSEC_Pos; + + return HAL_OK; +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + * @brief Set the security level of the RTC/TAMP/Backup registers. + * To get the current security level call HAL_RTCEx_SecureModeGet. + * @param hrtc RTC handle + * @param secureState Secure state + * @retval HAL_StatusTypeDef + */ +HAL_StatusTypeDef HAL_RTCEx_SecureModeSet(const RTC_HandleTypeDef *hrtc, const RTC_SecureStateTypeDef *secureState) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + assert_param(IS_RTC_SECURE_FULL(secureState->rtcSecureFull)); + assert_param(IS_RTC_NONSECURE_FEATURES(secureState->rtcNonSecureFeatures)); + assert_param(IS_TAMP_SECURE_FULL(secureState->tampSecureFull)); + assert_param(IS_RTC_BKP(secureState->backupRegisterStartZone2)); + assert_param(IS_RTC_BKP(secureState->backupRegisterStartZone3)); + assert_param(IS_TAMP_MONOTONIC_CNT_SECURE(secureState->MonotonicCounterSecure)); + + /* RTC, rtcNonSecureFeatures is only relevant if secureState->rtcSecureFull == RTC_SECURE_FULL_NO */ + WRITE_REG(RTC->SECCFGR, secureState->rtcSecureFull | (~(secureState->rtcNonSecureFeatures) & + RTC_NONSECURE_FEATURE_ALL)); + + /* Tamper + Backup register + Monotonic counter + Warning : Backup register start zone are Shared with privilege configuration */ + WRITE_REG(TAMP->SECCFGR, + secureState->tampSecureFull | secureState->MonotonicCounterSecure | + (TAMP_SECCFGR_BKPRWSEC & (secureState->backupRegisterStartZone2 << TAMP_SECCFGR_BKPRWSEC_Pos)) | + (TAMP_SECCFGR_BKPWSEC & (secureState->backupRegisterStartZone3 << TAMP_SECCFGR_BKPWSEC_Pos))); + + return HAL_OK; +} + + +#endif /* #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/** + * @} + */ +#endif /* RTC_SECCFGR_SEC */ + +#if defined(TAMP_PRIVCFGR_TAMPPRIV) +/** @addtogroup RTCEx_Exported_Functions_Group8 + * @brief Extended RTC privilege functions + * +@verbatim + =============================================================================== + ##### Extended RTC privilege functions ##### + =============================================================================== + [..] + (+) Before calling privilege function, you have to call first + HAL_RTC_Init() function. +@endverbatim + * @{ + */ + +/** + * @brief Set the privilege level of the RTC/TAMP/Backup registers. + * To get the current privilege level call HAL_RTCEx_PrivilegeModeGet. + * @param hrtc RTC handle + * @param privilegeState Privilege state + * @retval HAL_StatusTypeDef + */ +HAL_StatusTypeDef HAL_RTCEx_PrivilegeModeSet(const RTC_HandleTypeDef *hrtc, + const RTC_PrivilegeStateTypeDef *privilegeState) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + assert_param(IS_RTC_PRIVILEGE_FULL(privilegeState->rtcPrivilegeFull)); + assert_param(IS_RTC_PRIVILEGE_FEATURES(privilegeState->rtcPrivilegeFeatures)); + assert_param(IS_TAMP_PRIVILEGE_FULL(privilegeState->tampPrivilegeFull)); + assert_param(IS_TAMP_MONOTONIC_CNT_PRIVILEGE(privilegeState->MonotonicCounterPrivilege)); + assert_param(IS_RTC_PRIVILEGE_BKUP_ZONE(privilegeState->backupRegisterPrivZone)); + assert_param(IS_RTC_BKP(privilegeState->backupRegisterStartZone2)); + assert_param(IS_RTC_BKP(privilegeState->backupRegisterStartZone3)); + + /* RTC privilege configuration */ + WRITE_REG(RTC->PRIVCFGR, privilegeState->rtcPrivilegeFull | privilegeState->rtcPrivilegeFeatures); + + /* TAMP, Monotonic counter and Backup registers privilege configuration + Warning : privilegeState->backupRegisterPrivZone is only writable in secure mode or if trustzone is disabled. + In non secure mode, a notification is generated through a flag/interrupt in the TZIC + (TrustZone interrupt controller). The bits are not written. */ + WRITE_REG(TAMP->PRIVCFGR, privilegeState->tampPrivilegeFull | privilegeState->backupRegisterPrivZone | \ + privilegeState->MonotonicCounterPrivilege); + + /* Backup register start zone + Warning : This parameter is only writable in secure mode or if trustzone is disabled. + In non secure mode, a notification is generated through a flag/interrupt in the TZIC + (TrustZone interrupt controller). The bits are not written. + Warning : Backup register start zones are shared with secure configuration */ +#if defined(TAMP_SECCFGR_BKPWSEC) + MODIFY_REG(TAMP->SECCFGR, + (TAMP_SECCFGR_BKPRWSEC | TAMP_SECCFGR_BKPWSEC), + ((privilegeState->backupRegisterStartZone2 << TAMP_SECCFGR_BKPRWSEC_Pos) | \ + (privilegeState->backupRegisterStartZone3 << TAMP_SECCFGR_BKPWSEC_Pos))); +#endif /* TAMP_SECCFGR_BKPWSEC */ + + return HAL_OK; +} + +/** + * @brief Get the privilege level of the RTC/TAMP/Backup registers. + * To set the privilege level please call HAL_RTCEx_PrivilegeModeSet. + * @param hrtc RTC handle + * @param privilegeState Privilege state + * @retval HAL_StatusTypeDef + */ +HAL_StatusTypeDef HAL_RTCEx_PrivilegeModeGet(const RTC_HandleTypeDef *hrtc, RTC_PrivilegeStateTypeDef *privilegeState) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + /* Read registers */ + uint32_t rtc_privcfgr = READ_REG(RTC->PRIVCFGR); + uint32_t tamp_privcfgr = READ_REG(TAMP->PRIVCFGR); + uint32_t tamp_seccfgr = READ_REG(TAMP->SECCFGR); + + /* RTC privilege configuration */ + privilegeState->rtcPrivilegeFull = READ_BIT(rtc_privcfgr, RTC_PRIVCFGR_PRIV); + + /* Warning, rtcPrivilegeFeatures is only relevant if privilegeState->rtcPrivilegeFull == RTC_PRIVILEGE_FULL_NO */ + privilegeState->rtcPrivilegeFeatures = READ_BIT(rtc_privcfgr, RTC_PRIVILEGE_FEATURE_ALL); + + /* TAMP and Backup registers privilege configuration */ + privilegeState->tampPrivilegeFull = READ_BIT(tamp_privcfgr, TAMP_PRIVCFGR_TAMPPRIV); + + /* Monotonic registers privilege configuration */ + privilegeState->MonotonicCounterPrivilege = READ_BIT(tamp_privcfgr, TAMP_PRIVCFGR_CNT1PRIV); + + /* Backup registers Zones */ + privilegeState->backupRegisterPrivZone = READ_BIT(tamp_privcfgr, (TAMP_PRIVCFGR_BKPWPRIV | TAMP_PRIVCFGR_BKPRWPRIV)); + + /* Backup register start zones + Warning : Shared with secure configuration */ + privilegeState->backupRegisterStartZone2 = READ_BIT(tamp_seccfgr, TAMP_SECCFGR_BKPRWSEC) >> + TAMP_SECCFGR_BKPRWSEC_Pos; + + privilegeState->backupRegisterStartZone3 = READ_BIT(tamp_seccfgr, TAMP_SECCFGR_BKPWSEC) >> + TAMP_SECCFGR_BKPWSEC_Pos; + + return HAL_OK; +} + +/** + * @} + */ +#endif /* TAMP_PRIVCFGR_TAMPPRIV */ + +/** + * @} + */ + +#endif /* HAL_RTC_MODULE_ENABLED */ + +/** + * @} + */ + + +/** + * @} + */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sai.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sai.c new file mode 100644 index 0000000000..c0805263a4 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sai.c @@ -0,0 +1,2902 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_sai.c + * @author MCD Application Team + * @brief SAI HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Serial Audio Interface (SAI) peripheral: + * + Initialization/de-initialization functions + * + I/O operation functions + * + Peripheral Control functions + * + Peripheral State functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + + [..] + The SAI HAL driver can be used as follows: + + (#) Declare a SAI_HandleTypeDef handle structure (eg. SAI_HandleTypeDef hsai). + (#) Initialize the SAI low level resources by implementing the HAL_SAI_MspInit() API: + (##) Enable the SAI interface clock. + (##) SAI pins configuration: + (+++) Enable the clock for the SAI GPIOs. + (+++) Configure these SAI pins as alternate function pull-up. + (##) NVIC configuration if you need to use interrupt process (HAL_SAI_Transmit_IT() + and HAL_SAI_Receive_IT() APIs): + (+++) Configure the SAI interrupt priority. + (+++) Enable the NVIC SAI IRQ handle. + + (##) DMA Configuration if you need to use DMA process (HAL_SAI_Transmit_DMA() + and HAL_SAI_Receive_DMA() APIs): + (+++) Declare a DMA handle structure for the Tx/Rx stream. + (+++) Enable the DMAx interface clock. + (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. + (+++) Configure the DMA Tx/Rx Stream. + (+++) Associate the initialized DMA handle to the SAI DMA Tx/Rx handle. + (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the + DMA Tx/Rx Stream. + + (#) The initialization can be done by two ways + (##) Expert mode : Initialize the structures Init, FrameInit and SlotInit and call HAL_SAI_Init(). + (##) Simplified mode : Initialize the high part of Init Structure and call HAL_SAI_InitProtocol(). + + [..] + (@) The specific SAI interrupts (FIFO request and Overrun underrun interrupt) + will be managed using the macros __HAL_SAI_ENABLE_IT() and __HAL_SAI_DISABLE_IT() + inside the transmit and receive process. + [..] + (@) Make sure that either: + (+@) PLLSAI1CLK output is configured or + (+@) PLLSAI2CLK output is configured or + (+@) PLLSAI3CLK output is configured or + (+@) External clock source is configured after setting correctly + the define constant EXTERNAL_SAI1_CLOCK_VALUE or EXTERNAL_SAI2_CLOCK_VALUE + in the stm32h5xx_hal_conf.h file. + + [..] + (@) In master Tx mode: enabling the audio block immediately generates the bit clock + for the external slaves even if there is no data in the FIFO, However FS signal + generation is conditioned by the presence of data in the FIFO. + + [..] + (@) In master Rx mode: enabling the audio block immediately generates the bit clock + and FS signal for the external slaves. + + [..] + (@) It is mandatory to respect the following conditions in order to avoid bad SAI behavior: + (+@) First bit Offset <= (SLOT size - Data size) + (+@) Data size <= SLOT size + (+@) Number of SLOT x SLOT size = Frame length + (+@) The number of slots should be even when SAI_FS_CHANNEL_IDENTIFICATION is selected. + + [..] + (@) PDM interface can be activated through HAL_SAI_Init function. + Please note that PDM interface is only available for SAI1 sub-block A. + PDM microphone delays can be tuned with HAL_SAIEx_ConfigPdmMicDelay function. + + [..] + Three operation modes are available within this driver : + + *** Polling mode IO operation *** + ================================= + [..] + (+) Send an amount of data in blocking mode using HAL_SAI_Transmit() + (+) Receive an amount of data in blocking mode using HAL_SAI_Receive() + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Send an amount of data in non-blocking mode using HAL_SAI_Transmit_IT() + (+) At transmission end of transfer HAL_SAI_TxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_SAI_TxCpltCallback() + (+) Receive an amount of data in non-blocking mode using HAL_SAI_Receive_IT() + (+) At reception end of transfer HAL_SAI_RxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_SAI_RxCpltCallback() + (+) In case of flag error, HAL_SAI_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_SAI_ErrorCallback() + + *** DMA mode IO operation *** + ============================= + [..] + (+) Send an amount of data in non-blocking mode (DMA) using HAL_SAI_Transmit_DMA() + (+) At transmission end of transfer HAL_SAI_TxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_SAI_TxCpltCallback() + (+) Receive an amount of data in non-blocking mode (DMA) using HAL_SAI_Receive_DMA() + (+) At reception end of transfer HAL_SAI_RxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_SAI_RxCpltCallback() + (+) In case of flag error, HAL_SAI_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_SAI_ErrorCallback() + (+) Pause the DMA Transfer using HAL_SAI_DMAPause() + (+) Resume the DMA Transfer using HAL_SAI_DMAResume() + (+) Stop the DMA Transfer using HAL_SAI_DMAStop() + + *** SAI HAL driver additional function list *** + =============================================== + [..] + Below the list the others API available SAI HAL driver : + + (+) HAL_SAI_EnableTxMuteMode(): Enable the mute in tx mode + (+) HAL_SAI_DisableTxMuteMode(): Disable the mute in tx mode + (+) HAL_SAI_EnableRxMuteMode(): Enable the mute in Rx mode + (+) HAL_SAI_DisableRxMuteMode(): Disable the mute in Rx mode + (+) HAL_SAI_FlushRxFifo(): Flush the rx fifo. + (+) HAL_SAI_Abort(): Abort the current transfer + + *** SAI HAL driver macros list *** + ================================== + [..] + Below the list of most used macros in SAI HAL driver : + + (+) __HAL_SAI_ENABLE(): Enable the SAI peripheral + (+) __HAL_SAI_DISABLE(): Disable the SAI peripheral + (+) __HAL_SAI_ENABLE_IT(): Enable the specified SAI interrupts + (+) __HAL_SAI_DISABLE_IT(): Disable the specified SAI interrupts + (+) __HAL_SAI_GET_IT_SOURCE(): Check if the specified SAI interrupt source is + enabled or disabled + (+) __HAL_SAI_GET_FLAG(): Check whether the specified SAI flag is set or not + + *** Callback registration *** + ============================= + [..] + The compilation define USE_HAL_SAI_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + Use functions HAL_SAI_RegisterCallback() to register a user callback. + + [..] + Function HAL_SAI_RegisterCallback() allows to register following callbacks: + (+) RxCpltCallback : SAI receive complete. + (+) RxHalfCpltCallback : SAI receive half complete. + (+) TxCpltCallback : SAI transmit complete. + (+) TxHalfCpltCallback : SAI transmit half complete. + (+) ErrorCallback : SAI error. + (+) MspInitCallback : SAI MspInit. + (+) MspDeInitCallback : SAI MspDeInit. + [..] + This function takes as parameters the HAL peripheral handle, the callback ID + and a pointer to the user callback function. + + [..] + Use function HAL_SAI_UnRegisterCallback() to reset a callback to the default + weak (surcharged) function. + HAL_SAI_UnRegisterCallback() takes as parameters the HAL peripheral handle, + and the callback ID. + [..] + This function allows to reset following callbacks: + (+) RxCpltCallback : SAI receive complete. + (+) RxHalfCpltCallback : SAI receive half complete. + (+) TxCpltCallback : SAI transmit complete. + (+) TxHalfCpltCallback : SAI transmit half complete. + (+) ErrorCallback : SAI error. + (+) MspInitCallback : SAI MspInit. + (+) MspDeInitCallback : SAI MspDeInit. + + [..] + By default, after the HAL_SAI_Init and if the state is HAL_SAI_STATE_RESET + all callbacks are reset to the corresponding legacy weak (surcharged) functions: + examples HAL_SAI_RxCpltCallback(), HAL_SAI_ErrorCallback(). + Exception done for MspInit and MspDeInit callbacks that are respectively + reset to the legacy weak (surcharged) functions in the HAL_SAI_Init + and HAL_SAI_DeInit only when these callbacks are null (not registered beforehand). + If not, MspInit or MspDeInit are not null, the HAL_SAI_Init and HAL_SAI_DeInit + keep and use the user MspInit/MspDeInit callbacks (registered beforehand). + + [..] + Callbacks can be registered/unregistered in READY state only. + Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered + in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used + during the Init/DeInit. + In that case first register the MspInit/MspDeInit user callbacks + using HAL_SAI_RegisterCallback before calling HAL_SAI_DeInit + or HAL_SAI_Init function. + + [..] + When the compilation define USE_HAL_SAI_REGISTER_CALLBACKS is set to 0 or + not defined, the callback registering feature is not available + and weak (surcharged) callbacks are used. + + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +#if defined(SAI1) + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup SAI SAI + * @brief SAI HAL module driver + * @{ + */ + +#ifdef HAL_SAI_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/** @defgroup SAI_Private_Typedefs SAI Private Typedefs + * @{ + */ +typedef enum +{ + SAI_MODE_DMA, + SAI_MODE_IT +} SAI_ModeTypedef; +/** + * @} + */ + +/* Private define ------------------------------------------------------------*/ +/** @defgroup SAI_Private_Constants SAI Private Constants + * @{ + */ +#define SAI_DEFAULT_TIMEOUT 4U +#define SAI_LONG_TIMEOUT 1000U +#define SAI_SPDIF_FRAME_LENGTH 64U +#define SAI_AC97_FRAME_LENGTH 256U +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup SAI_Private_Functions SAI Private Functions + * @{ + */ +static void SAI_FillFifo(SAI_HandleTypeDef *hsai); +static uint32_t SAI_InterruptFlag(const SAI_HandleTypeDef *hsai, SAI_ModeTypedef mode); +static HAL_StatusTypeDef SAI_InitI2S(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot); +static HAL_StatusTypeDef SAI_InitPCM(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot); + +static HAL_StatusTypeDef SAI_Disable(SAI_HandleTypeDef *hsai); +static void SAI_Transmit_IT8Bit(SAI_HandleTypeDef *hsai); +static void SAI_Transmit_IT16Bit(SAI_HandleTypeDef *hsai); +static void SAI_Transmit_IT32Bit(SAI_HandleTypeDef *hsai); +static void SAI_Receive_IT8Bit(SAI_HandleTypeDef *hsai); +static void SAI_Receive_IT16Bit(SAI_HandleTypeDef *hsai); +static void SAI_Receive_IT32Bit(SAI_HandleTypeDef *hsai); + +static void SAI_DMATxCplt(DMA_HandleTypeDef *hdma); +static void SAI_DMATxHalfCplt(DMA_HandleTypeDef *hdma); +static void SAI_DMARxCplt(DMA_HandleTypeDef *hdma); +static void SAI_DMARxHalfCplt(DMA_HandleTypeDef *hdma); +static void SAI_DMAError(DMA_HandleTypeDef *hdma); +static void SAI_DMAAbort(DMA_HandleTypeDef *hdma); +/** + * @} + */ + +/* Exported functions ---------------------------------------------------------*/ +/** @defgroup SAI_Exported_Functions SAI Exported Functions + * @{ + */ + +/** @defgroup SAI_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + de-initialize the SAIx peripheral: + + (+) User must implement HAL_SAI_MspInit() function in which he configures + all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ). + + (+) Call the function HAL_SAI_Init() to configure the selected device with + the selected configuration: + (++) Mode (Master/slave TX/RX) + (++) Protocol + (++) Data Size + (++) MCLK Output + (++) Audio frequency + (++) FIFO Threshold + (++) Frame Config + (++) Slot Config + (++) PDM Config + + (+) Call the function HAL_SAI_DeInit() to restore the default configuration + of the selected SAI peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the structure FrameInit, SlotInit and the low part of + * Init according to the specified parameters and call the function + * HAL_SAI_Init to initialize the SAI block. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @param protocol one of the supported protocol @ref SAI_Protocol + * @param datasize one of the supported datasize @ref SAI_Protocol_DataSize + * the configuration information for SAI module. + * @param nbslot Number of slot. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_InitProtocol(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot) +{ + HAL_StatusTypeDef status; + + /* Check the parameters */ + assert_param(IS_SAI_SUPPORTED_PROTOCOL(protocol)); + assert_param(IS_SAI_PROTOCOL_DATASIZE(datasize)); + + switch (protocol) + { + case SAI_I2S_STANDARD : + case SAI_I2S_MSBJUSTIFIED : + case SAI_I2S_LSBJUSTIFIED : + status = SAI_InitI2S(hsai, protocol, datasize, nbslot); + break; + case SAI_PCM_LONG : + case SAI_PCM_SHORT : + status = SAI_InitPCM(hsai, protocol, datasize, nbslot); + break; + default : + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + status = HAL_SAI_Init(hsai); + } + + return status; +} + +/** + * @brief Initialize the SAI according to the specified parameters. + * in the SAI_InitTypeDef structure and initialize the associated handle. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_Init(SAI_HandleTypeDef *hsai) +{ + uint32_t tmpregisterGCR; + uint32_t ckstr_bits; + uint32_t syncen_bits; + + /* Check the SAI handle allocation */ + if (hsai == NULL) + { + return HAL_ERROR; + } + + /* check the instance */ + assert_param(IS_SAI_ALL_INSTANCE(hsai->Instance)); + + /* Check the SAI Block parameters */ + assert_param(IS_SAI_AUDIO_FREQUENCY(hsai->Init.AudioFrequency)); + assert_param(IS_SAI_BLOCK_PROTOCOL(hsai->Init.Protocol)); + assert_param(IS_SAI_BLOCK_MODE(hsai->Init.AudioMode)); + assert_param(IS_SAI_BLOCK_DATASIZE(hsai->Init.DataSize)); + assert_param(IS_SAI_BLOCK_FIRST_BIT(hsai->Init.FirstBit)); + assert_param(IS_SAI_BLOCK_CLOCK_STROBING(hsai->Init.ClockStrobing)); + assert_param(IS_SAI_BLOCK_SYNCHRO(hsai->Init.Synchro)); + assert_param(IS_SAI_BLOCK_MCK_OUTPUT(hsai->Init.MckOutput)); + assert_param(IS_SAI_BLOCK_OUTPUT_DRIVE(hsai->Init.OutputDrive)); + assert_param(IS_SAI_BLOCK_NODIVIDER(hsai->Init.NoDivider)); + assert_param(IS_SAI_BLOCK_FIFO_THRESHOLD(hsai->Init.FIFOThreshold)); + assert_param(IS_SAI_MONO_STEREO_MODE(hsai->Init.MonoStereoMode)); + assert_param(IS_SAI_BLOCK_COMPANDING_MODE(hsai->Init.CompandingMode)); + assert_param(IS_SAI_BLOCK_TRISTATE_MANAGEMENT(hsai->Init.TriState)); + assert_param(IS_SAI_BLOCK_SYNCEXT(hsai->Init.SynchroExt)); + assert_param(IS_SAI_BLOCK_MCK_OVERSAMPLING(hsai->Init.MckOverSampling)); + + /* Check the SAI Block Frame parameters */ + assert_param(IS_SAI_BLOCK_FRAME_LENGTH(hsai->FrameInit.FrameLength)); + assert_param(IS_SAI_BLOCK_ACTIVE_FRAME(hsai->FrameInit.ActiveFrameLength)); + assert_param(IS_SAI_BLOCK_FS_DEFINITION(hsai->FrameInit.FSDefinition)); + assert_param(IS_SAI_BLOCK_FS_POLARITY(hsai->FrameInit.FSPolarity)); + assert_param(IS_SAI_BLOCK_FS_OFFSET(hsai->FrameInit.FSOffset)); + + /* Check the SAI Block Slot parameters */ + assert_param(IS_SAI_BLOCK_FIRSTBIT_OFFSET(hsai->SlotInit.FirstBitOffset)); + assert_param(IS_SAI_BLOCK_SLOT_SIZE(hsai->SlotInit.SlotSize)); + assert_param(IS_SAI_BLOCK_SLOT_NUMBER(hsai->SlotInit.SlotNumber)); + assert_param(IS_SAI_SLOT_ACTIVE(hsai->SlotInit.SlotActive)); + + /* Check the SAI PDM parameters */ + assert_param(IS_FUNCTIONAL_STATE(hsai->Init.PdmInit.Activation)); + if (hsai->Init.PdmInit.Activation == ENABLE) + { + assert_param(IS_SAI_PDM_MIC_PAIRS_NUMBER(hsai->Init.PdmInit.MicPairsNbr)); + assert_param(IS_SAI_PDM_CLOCK_ENABLE(hsai->Init.PdmInit.ClockEnable)); + /* Check that SAI sub-block is SAI1 sub-block A, in master RX mode with free protocol */ + if ((hsai->Instance != SAI1_Block_A) || + (hsai->Init.AudioMode != SAI_MODEMASTER_RX) || + (hsai->Init.Protocol != SAI_FREE_PROTOCOL)) + { + return HAL_ERROR; + } + } + + if (hsai->State == HAL_SAI_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hsai->Lock = HAL_UNLOCKED; + +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) + /* Reset callback pointers to the weak predefined callbacks */ + hsai->RxCpltCallback = HAL_SAI_RxCpltCallback; + hsai->RxHalfCpltCallback = HAL_SAI_RxHalfCpltCallback; + hsai->TxCpltCallback = HAL_SAI_TxCpltCallback; + hsai->TxHalfCpltCallback = HAL_SAI_TxHalfCpltCallback; + hsai->ErrorCallback = HAL_SAI_ErrorCallback; + + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + if (hsai->MspInitCallback == NULL) + { + hsai->MspInitCallback = HAL_SAI_MspInit; + } + hsai->MspInitCallback(hsai); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + HAL_SAI_MspInit(hsai); +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ + } + + /* Disable the selected SAI peripheral */ + if (SAI_Disable(hsai) != HAL_OK) + { + return HAL_ERROR; + } + + hsai->State = HAL_SAI_STATE_BUSY; + + /* SAI Block Synchro Configuration -----------------------------------------*/ + /* This setting must be done with both audio block (A & B) disabled */ + switch (hsai->Init.SynchroExt) + { + case SAI_SYNCEXT_DISABLE : + tmpregisterGCR = 0; + break; + case SAI_SYNCEXT_OUTBLOCKA_ENABLE : + tmpregisterGCR = SAI_GCR_SYNCOUT_0; + break; + case SAI_SYNCEXT_OUTBLOCKB_ENABLE : + tmpregisterGCR = SAI_GCR_SYNCOUT_1; + break; + default : + tmpregisterGCR = 0; + break; + } + + switch (hsai->Init.Synchro) + { + case SAI_ASYNCHRONOUS : + syncen_bits = 0; + break; + case SAI_SYNCHRONOUS : + syncen_bits = SAI_xCR1_SYNCEN_0; + break; + case SAI_SYNCHRONOUS_EXT_SAI1 : + syncen_bits = SAI_xCR1_SYNCEN_1; + break; + case SAI_SYNCHRONOUS_EXT_SAI2 : + syncen_bits = SAI_xCR1_SYNCEN_1; + tmpregisterGCR |= SAI_GCR_SYNCIN_0; + break; + default : + syncen_bits = 0; + break; + } + + if ((hsai->Instance == SAI1_Block_A) || (hsai->Instance == SAI1_Block_B)) + { + SAI1->GCR = tmpregisterGCR; + } + else + { + SAI2->GCR = tmpregisterGCR; + } + + if (hsai->Init.AudioFrequency != SAI_AUDIO_FREQUENCY_MCKDIV) + { + uint32_t freq = 0; + uint32_t tmpval; + + /* In this case, the MCKDIV value is calculated to get AudioFrequency */ + if ((hsai->Instance == SAI1_Block_A) || (hsai->Instance == SAI1_Block_B)) + { + freq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SAI1); + } + if ((hsai->Instance == SAI2_Block_A) || (hsai->Instance == SAI2_Block_B)) + { + freq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SAI2); + } + + /* Configure Master Clock Divider using the following formula : + - If NODIV = 1 : + MCKDIV[5:0] = SAI_CK_x / (FS * (FRL + 1)) + - If NODIV = 0 : + MCKDIV[5:0] = SAI_CK_x / (FS * (OSR + 1) * 256) */ + if (hsai->Init.NoDivider == SAI_MASTERDIVIDER_DISABLE) + { + /* NODIV = 1 */ + uint32_t tmpframelength; + + if (hsai->Init.Protocol == SAI_SPDIF_PROTOCOL) + { + /* For SPDIF protocol, frame length is set by hardware to 64 */ + tmpframelength = SAI_SPDIF_FRAME_LENGTH; + } + else if (hsai->Init.Protocol == SAI_AC97_PROTOCOL) + { + /* For AC97 protocol, frame length is set by hardware to 256 */ + tmpframelength = SAI_AC97_FRAME_LENGTH; + } + else + { + /* For free protocol, frame length is set by user */ + tmpframelength = hsai->FrameInit.FrameLength; + } + + /* (freq x 10) to keep Significant digits */ + tmpval = (freq * 10U) / (hsai->Init.AudioFrequency * tmpframelength); + } + else + { + /* NODIV = 0 */ + uint32_t tmposr; + tmposr = (hsai->Init.MckOverSampling == SAI_MCK_OVERSAMPLING_ENABLE) ? 2U : 1U; + /* (freq x 10) to keep Significant digits */ + tmpval = (freq * 10U) / (hsai->Init.AudioFrequency * tmposr * 256U); + } + hsai->Init.Mckdiv = tmpval / 10U; + + /* Round result to the nearest integer */ + if ((tmpval % 10U) > 8U) + { + hsai->Init.Mckdiv += 1U; + } + + /* For SPDIF protocol, SAI shall provide a bit clock twice faster the symbol-rate */ + if (hsai->Init.Protocol == SAI_SPDIF_PROTOCOL) + { + hsai->Init.Mckdiv = hsai->Init.Mckdiv >> 1; + } + } + + /* Check the SAI Block master clock divider parameter */ + assert_param(IS_SAI_BLOCK_MASTER_DIVIDER(hsai->Init.Mckdiv)); + + /* Compute CKSTR bits of SAI CR1 according ClockStrobing and AudioMode */ + if ((hsai->Init.AudioMode == SAI_MODEMASTER_TX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX)) + { + /* Transmit */ + ckstr_bits = (hsai->Init.ClockStrobing == SAI_CLOCKSTROBING_RISINGEDGE) ? 0U : SAI_xCR1_CKSTR; + } + else + { + /* Receive */ + ckstr_bits = (hsai->Init.ClockStrobing == SAI_CLOCKSTROBING_RISINGEDGE) ? SAI_xCR1_CKSTR : 0U; + } + + /* SAI Block Configuration -------------------------------------------------*/ + /* SAI CR1 Configuration */ + hsai->Instance->CR1 &= ~(SAI_xCR1_MODE | SAI_xCR1_PRTCFG | SAI_xCR1_DS | \ + SAI_xCR1_LSBFIRST | SAI_xCR1_CKSTR | SAI_xCR1_SYNCEN | \ + SAI_xCR1_MONO | SAI_xCR1_OUTDRIV | SAI_xCR1_DMAEN | \ + SAI_xCR1_NODIV | SAI_xCR1_MCKDIV | SAI_xCR1_OSR | \ + SAI_xCR1_MCKEN); + + hsai->Instance->CR1 |= (hsai->Init.AudioMode | hsai->Init.Protocol | \ + hsai->Init.DataSize | hsai->Init.FirstBit | \ + ckstr_bits | syncen_bits | \ + hsai->Init.MonoStereoMode | hsai->Init.OutputDrive | \ + hsai->Init.NoDivider | (hsai->Init.Mckdiv << 20) | \ + hsai->Init.MckOverSampling | hsai->Init.MckOutput); + + /* SAI CR2 Configuration */ + hsai->Instance->CR2 &= ~(SAI_xCR2_FTH | SAI_xCR2_FFLUSH | SAI_xCR2_COMP | SAI_xCR2_CPL); + hsai->Instance->CR2 |= (hsai->Init.FIFOThreshold | hsai->Init.CompandingMode | hsai->Init.TriState); + + /* SAI Frame Configuration -----------------------------------------*/ + hsai->Instance->FRCR &= (~(SAI_xFRCR_FRL | SAI_xFRCR_FSALL | SAI_xFRCR_FSDEF | \ + SAI_xFRCR_FSPOL | SAI_xFRCR_FSOFF)); + hsai->Instance->FRCR |= ((hsai->FrameInit.FrameLength - 1U) | + hsai->FrameInit.FSOffset | + hsai->FrameInit.FSDefinition | + hsai->FrameInit.FSPolarity | + ((hsai->FrameInit.ActiveFrameLength - 1U) << 8)); + + /* SAI Block_x SLOT Configuration ------------------------------------------*/ + /* This register has no meaning in AC 97 and SPDIF audio protocol */ + hsai->Instance->SLOTR &= (~(SAI_xSLOTR_FBOFF | SAI_xSLOTR_SLOTSZ | \ + SAI_xSLOTR_NBSLOT | SAI_xSLOTR_SLOTEN)); + + hsai->Instance->SLOTR |= hsai->SlotInit.FirstBitOffset | hsai->SlotInit.SlotSize | \ + (hsai->SlotInit.SlotActive << 16) | ((hsai->SlotInit.SlotNumber - 1U) << 8); + + /* SAI PDM Configuration ---------------------------------------------------*/ + if (hsai->Instance == SAI1_Block_A) + { + /* Disable PDM interface */ + SAI1->PDMCR &= ~(SAI_PDMCR_PDMEN); + if (hsai->Init.PdmInit.Activation == ENABLE) + { + /* Configure and enable PDM interface */ + SAI1->PDMCR = (hsai->Init.PdmInit.ClockEnable | + ((hsai->Init.PdmInit.MicPairsNbr - 1U) << SAI_PDMCR_MICNBR_Pos)); + SAI1->PDMCR |= SAI_PDMCR_PDMEN; + } + } + + /* Initialize the error code */ + hsai->ErrorCode = HAL_SAI_ERROR_NONE; + + /* Initialize the SAI state */ + hsai->State = HAL_SAI_STATE_READY; + + /* Release Lock */ + __HAL_UNLOCK(hsai); + + return HAL_OK; +} + +/** + * @brief DeInitialize the SAI peripheral. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_DeInit(SAI_HandleTypeDef *hsai) +{ + /* Check the SAI handle allocation */ + if (hsai == NULL) + { + return HAL_ERROR; + } + + hsai->State = HAL_SAI_STATE_BUSY; + + /* Disabled All interrupt and clear all the flag */ + hsai->Instance->IMR = 0; + hsai->Instance->CLRFR = 0xFFFFFFFFU; + + /* Disable the SAI */ + if (SAI_Disable(hsai) != HAL_OK) + { + /* Reset SAI state to ready */ + hsai->State = HAL_SAI_STATE_READY; + + /* Release Lock */ + __HAL_UNLOCK(hsai); + + return HAL_ERROR; + } + + /* Flush the fifo */ + SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH); + + /* Disable SAI PDM interface */ + if (hsai->Instance == SAI1_Block_A) + { + /* Reset PDM delays */ + SAI1->PDMDLY = 0U; + + /* Disable PDM interface */ + SAI1->PDMCR &= ~(SAI_PDMCR_PDMEN); + } + + /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */ +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) + if (hsai->MspDeInitCallback == NULL) + { + hsai->MspDeInitCallback = HAL_SAI_MspDeInit; + } + hsai->MspDeInitCallback(hsai); +#else + HAL_SAI_MspDeInit(hsai); +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ + + /* Initialize the error code */ + hsai->ErrorCode = HAL_SAI_ERROR_NONE; + + /* Initialize the SAI state */ + hsai->State = HAL_SAI_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hsai); + + return HAL_OK; +} + +/** + * @brief Initialize the SAI MSP. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None + */ +__weak void HAL_SAI_MspInit(SAI_HandleTypeDef *hsai) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsai); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SAI_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitialize the SAI MSP. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None + */ +__weak void HAL_SAI_MspDeInit(SAI_HandleTypeDef *hsai) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsai); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SAI_MspDeInit could be implemented in the user file + */ +} + +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) +/** + * @brief Register a user SAI callback + * to be used instead of the weak predefined callback. + * @param hsai SAI handle. + * @param CallbackID ID of the callback to be registered. + * This parameter can be one of the following values: + * @arg @ref HAL_SAI_RX_COMPLETE_CB_ID receive complete callback ID. + * @arg @ref HAL_SAI_RX_HALFCOMPLETE_CB_ID receive half complete callback ID. + * @arg @ref HAL_SAI_TX_COMPLETE_CB_ID transmit complete callback ID. + * @arg @ref HAL_SAI_TX_HALFCOMPLETE_CB_ID transmit half complete callback ID. + * @arg @ref HAL_SAI_ERROR_CB_ID error callback ID. + * @arg @ref HAL_SAI_MSPINIT_CB_ID MSP init callback ID. + * @arg @ref HAL_SAI_MSPDEINIT_CB_ID MSP de-init callback ID. + * @param pCallback pointer to the callback function. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_SAI_RegisterCallback(SAI_HandleTypeDef *hsai, + HAL_SAI_CallbackIDTypeDef CallbackID, + pSAI_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* update the error code */ + hsai->ErrorCode |= HAL_SAI_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + } + else + { + if (HAL_SAI_STATE_READY == hsai->State) + { + switch (CallbackID) + { + case HAL_SAI_RX_COMPLETE_CB_ID : + hsai->RxCpltCallback = pCallback; + break; + case HAL_SAI_RX_HALFCOMPLETE_CB_ID : + hsai->RxHalfCpltCallback = pCallback; + break; + case HAL_SAI_TX_COMPLETE_CB_ID : + hsai->TxCpltCallback = pCallback; + break; + case HAL_SAI_TX_HALFCOMPLETE_CB_ID : + hsai->TxHalfCpltCallback = pCallback; + break; + case HAL_SAI_ERROR_CB_ID : + hsai->ErrorCallback = pCallback; + break; + case HAL_SAI_MSPINIT_CB_ID : + hsai->MspInitCallback = pCallback; + break; + case HAL_SAI_MSPDEINIT_CB_ID : + hsai->MspDeInitCallback = pCallback; + break; + default : + /* update the error code */ + hsai->ErrorCode |= HAL_SAI_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_SAI_STATE_RESET == hsai->State) + { + switch (CallbackID) + { + case HAL_SAI_MSPINIT_CB_ID : + hsai->MspInitCallback = pCallback; + break; + case HAL_SAI_MSPDEINIT_CB_ID : + hsai->MspDeInitCallback = pCallback; + break; + default : + /* update the error code */ + hsai->ErrorCode |= HAL_SAI_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* update the error code */ + hsai->ErrorCode |= HAL_SAI_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + } + } + return status; +} + +/** + * @brief Unregister a user SAI callback. + * SAI callback is redirected to the weak predefined callback. + * @param hsai SAI handle. + * @param CallbackID ID of the callback to be unregistered. + * This parameter can be one of the following values: + * @arg @ref HAL_SAI_RX_COMPLETE_CB_ID receive complete callback ID. + * @arg @ref HAL_SAI_RX_HALFCOMPLETE_CB_ID receive half complete callback ID. + * @arg @ref HAL_SAI_TX_COMPLETE_CB_ID transmit complete callback ID. + * @arg @ref HAL_SAI_TX_HALFCOMPLETE_CB_ID transmit half complete callback ID. + * @arg @ref HAL_SAI_ERROR_CB_ID error callback ID. + * @arg @ref HAL_SAI_MSPINIT_CB_ID MSP init callback ID. + * @arg @ref HAL_SAI_MSPDEINIT_CB_ID MSP de-init callback ID. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_SAI_UnRegisterCallback(SAI_HandleTypeDef *hsai, + HAL_SAI_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (HAL_SAI_STATE_READY == hsai->State) + { + switch (CallbackID) + { + case HAL_SAI_RX_COMPLETE_CB_ID : + hsai->RxCpltCallback = HAL_SAI_RxCpltCallback; + break; + case HAL_SAI_RX_HALFCOMPLETE_CB_ID : + hsai->RxHalfCpltCallback = HAL_SAI_RxHalfCpltCallback; + break; + case HAL_SAI_TX_COMPLETE_CB_ID : + hsai->TxCpltCallback = HAL_SAI_TxCpltCallback; + break; + case HAL_SAI_TX_HALFCOMPLETE_CB_ID : + hsai->TxHalfCpltCallback = HAL_SAI_TxHalfCpltCallback; + break; + case HAL_SAI_ERROR_CB_ID : + hsai->ErrorCallback = HAL_SAI_ErrorCallback; + break; + case HAL_SAI_MSPINIT_CB_ID : + hsai->MspInitCallback = HAL_SAI_MspInit; + break; + case HAL_SAI_MSPDEINIT_CB_ID : + hsai->MspDeInitCallback = HAL_SAI_MspDeInit; + break; + default : + /* update the error code */ + hsai->ErrorCode |= HAL_SAI_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_SAI_STATE_RESET == hsai->State) + { + switch (CallbackID) + { + case HAL_SAI_MSPINIT_CB_ID : + hsai->MspInitCallback = HAL_SAI_MspInit; + break; + case HAL_SAI_MSPDEINIT_CB_ID : + hsai->MspDeInitCallback = HAL_SAI_MspDeInit; + break; + default : + /* update the error code */ + hsai->ErrorCode |= HAL_SAI_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* update the error code */ + hsai->ErrorCode |= HAL_SAI_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + } + return status; +} +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup SAI_Exported_Functions_Group2 IO operation functions + * @brief Data transfers functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to manage the SAI data + transfers. + + (+) There are two modes of transfer: + (++) Blocking mode : The communication is performed in the polling mode. + The status of all data processing is returned by the same function + after finishing transfer. + (++) No-Blocking mode : The communication is performed using Interrupts + or DMA. These functions return the status of the transfer startup. + The end of the data processing will be indicated through the + dedicated SAI IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + + (+) Blocking mode functions are : + (++) HAL_SAI_Transmit() + (++) HAL_SAI_Receive() + + (+) Non Blocking mode functions with Interrupt are : + (++) HAL_SAI_Transmit_IT() + (++) HAL_SAI_Receive_IT() + + (+) Non Blocking mode functions with DMA are : + (++) HAL_SAI_Transmit_DMA() + (++) HAL_SAI_Receive_DMA() + + (+) A set of Transfer Complete Callbacks are provided in non Blocking mode: + (++) HAL_SAI_TxCpltCallback() + (++) HAL_SAI_RxCpltCallback() + (++) HAL_SAI_ErrorCallback() + +@endverbatim + * @{ + */ + +/** + * @brief Transmit an amount of data in blocking mode. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_Transmit(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart = HAL_GetTick(); + uint32_t temp; + + if ((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + if (hsai->State == HAL_SAI_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsai); + + hsai->XferSize = Size; + hsai->XferCount = Size; + hsai->pBuffPtr = pData; + hsai->State = HAL_SAI_STATE_BUSY_TX; + hsai->ErrorCode = HAL_SAI_ERROR_NONE; + + /* Check if the SAI is already enabled */ + if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == 0U) + { + /* fill the fifo with data before to enabled the SAI */ + SAI_FillFifo(hsai); + /* Enable SAI peripheral */ + __HAL_SAI_ENABLE(hsai); + } + + while (hsai->XferCount > 0U) + { + /* Write data if the FIFO is not full */ + if ((hsai->Instance->SR & SAI_xSR_FLVL) != SAI_FIFOSTATUS_FULL) + { + if ((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING)) + { + hsai->Instance->DR = *hsai->pBuffPtr; + hsai->pBuffPtr++; + } + else if (hsai->Init.DataSize <= SAI_DATASIZE_16) + { + temp = (uint32_t)(*hsai->pBuffPtr); + hsai->pBuffPtr++; + temp |= ((uint32_t)(*hsai->pBuffPtr) << 8); + hsai->pBuffPtr++; + hsai->Instance->DR = temp; + } + else + { + temp = (uint32_t)(*hsai->pBuffPtr); + hsai->pBuffPtr++; + temp |= ((uint32_t)(*hsai->pBuffPtr) << 8); + hsai->pBuffPtr++; + temp |= ((uint32_t)(*hsai->pBuffPtr) << 16); + hsai->pBuffPtr++; + temp |= ((uint32_t)(*hsai->pBuffPtr) << 24); + hsai->pBuffPtr++; + hsai->Instance->DR = temp; + } + hsai->XferCount--; + } + else + { + /* Check for the Timeout */ + if ((((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) && (Timeout != HAL_MAX_DELAY)) + { + /* Update error code */ + hsai->ErrorCode |= HAL_SAI_ERROR_TIMEOUT; + + /* Clear all the flags */ + hsai->Instance->CLRFR = 0xFFFFFFFFU; + + /* Disable SAI peripheral */ + /* No need to check return value because state update, unlock and error return will be performed later */ + (void) SAI_Disable(hsai); + + /* Flush the fifo */ + SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH); + + /* Change the SAI state */ + hsai->State = HAL_SAI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsai); + + return HAL_ERROR; + } + } + } + + hsai->State = HAL_SAI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsai); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in blocking mode. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @param pData Pointer to data buffer + * @param Size Amount of data to be received + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_Receive(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart = HAL_GetTick(); + uint32_t temp; + + if ((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + if (hsai->State == HAL_SAI_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsai); + + hsai->pBuffPtr = pData; + hsai->XferSize = Size; + hsai->XferCount = Size; + hsai->State = HAL_SAI_STATE_BUSY_RX; + hsai->ErrorCode = HAL_SAI_ERROR_NONE; + + /* Check if the SAI is already enabled */ + if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == 0U) + { + /* Enable SAI peripheral */ + __HAL_SAI_ENABLE(hsai); + } + + /* Receive data */ + while (hsai->XferCount > 0U) + { + if ((hsai->Instance->SR & SAI_xSR_FLVL) != SAI_FIFOSTATUS_EMPTY) + { + if ((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING)) + { + *hsai->pBuffPtr = (uint8_t)hsai->Instance->DR; + hsai->pBuffPtr++; + } + else if (hsai->Init.DataSize <= SAI_DATASIZE_16) + { + temp = hsai->Instance->DR; + *hsai->pBuffPtr = (uint8_t)temp; + hsai->pBuffPtr++; + *hsai->pBuffPtr = (uint8_t)(temp >> 8); + hsai->pBuffPtr++; + } + else + { + temp = hsai->Instance->DR; + *hsai->pBuffPtr = (uint8_t)temp; + hsai->pBuffPtr++; + *hsai->pBuffPtr = (uint8_t)(temp >> 8); + hsai->pBuffPtr++; + *hsai->pBuffPtr = (uint8_t)(temp >> 16); + hsai->pBuffPtr++; + *hsai->pBuffPtr = (uint8_t)(temp >> 24); + hsai->pBuffPtr++; + } + hsai->XferCount--; + } + else + { + /* Check for the Timeout */ + if ((((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) && (Timeout != HAL_MAX_DELAY)) + { + /* Update error code */ + hsai->ErrorCode |= HAL_SAI_ERROR_TIMEOUT; + + /* Clear all the flags */ + hsai->Instance->CLRFR = 0xFFFFFFFFU; + + /* Disable SAI peripheral */ + /* No need to check return value because state update, unlock and error return will be performed later */ + (void) SAI_Disable(hsai); + + /* Flush the fifo */ + SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH); + + /* Change the SAI state */ + hsai->State = HAL_SAI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsai); + + return HAL_ERROR; + } + } + } + + hsai->State = HAL_SAI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsai); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit an amount of data in non-blocking mode with Interrupt. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_Transmit_IT(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size) +{ + if ((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + if (hsai->State == HAL_SAI_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsai); + + hsai->pBuffPtr = pData; + hsai->XferSize = Size; + hsai->XferCount = Size; + hsai->ErrorCode = HAL_SAI_ERROR_NONE; + hsai->State = HAL_SAI_STATE_BUSY_TX; + + if ((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING)) + { + hsai->InterruptServiceRoutine = SAI_Transmit_IT8Bit; + } + else if (hsai->Init.DataSize <= SAI_DATASIZE_16) + { + hsai->InterruptServiceRoutine = SAI_Transmit_IT16Bit; + } + else + { + hsai->InterruptServiceRoutine = SAI_Transmit_IT32Bit; + } + + /* Fill the fifo before starting the communication */ + SAI_FillFifo(hsai); + + /* Enable FRQ and OVRUDR interrupts */ + __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT)); + + /* Check if the SAI is already enabled */ + if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == 0U) + { + /* Enable SAI peripheral */ + __HAL_SAI_ENABLE(hsai); + } + /* Process Unlocked */ + __HAL_UNLOCK(hsai); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in non-blocking mode with Interrupt. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @param pData Pointer to data buffer + * @param Size Amount of data to be received + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_Receive_IT(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size) +{ + if ((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + if (hsai->State == HAL_SAI_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsai); + + hsai->pBuffPtr = pData; + hsai->XferSize = Size; + hsai->XferCount = Size; + hsai->ErrorCode = HAL_SAI_ERROR_NONE; + hsai->State = HAL_SAI_STATE_BUSY_RX; + + if ((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING)) + { + hsai->InterruptServiceRoutine = SAI_Receive_IT8Bit; + } + else if (hsai->Init.DataSize <= SAI_DATASIZE_16) + { + hsai->InterruptServiceRoutine = SAI_Receive_IT16Bit; + } + else + { + hsai->InterruptServiceRoutine = SAI_Receive_IT32Bit; + } + + /* Enable TXE and OVRUDR interrupts */ + __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT)); + + /* Check if the SAI is already enabled */ + if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == 0U) + { + /* Enable SAI peripheral */ + __HAL_SAI_ENABLE(hsai); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hsai); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Pause the audio stream playing from the Media. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_DMAPause(SAI_HandleTypeDef *hsai) +{ + /* Process Locked */ + __HAL_LOCK(hsai); + + /* Pause the audio file playing by disabling the SAI DMA requests */ + hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN; + + /* Process Unlocked */ + __HAL_UNLOCK(hsai); + + return HAL_OK; +} + +/** + * @brief Resume the audio stream playing from the Media. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_DMAResume(SAI_HandleTypeDef *hsai) +{ + /* Process Locked */ + __HAL_LOCK(hsai); + + /* Enable the SAI DMA requests */ + hsai->Instance->CR1 |= SAI_xCR1_DMAEN; + + /* If the SAI peripheral is still not enabled, enable it */ + if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == 0U) + { + /* Enable SAI peripheral */ + __HAL_SAI_ENABLE(hsai); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hsai); + + return HAL_OK; +} + +/** + * @brief Stop the audio stream playing from the Media. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_DMAStop(SAI_HandleTypeDef *hsai) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process Locked */ + __HAL_LOCK(hsai); + + /* Disable SAI peripheral */ + if (SAI_Disable(hsai) != HAL_OK) + { + status = HAL_ERROR; + } + + /* Disable the SAI DMA request */ + hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN; + + /* Abort the SAI Tx DMA Stream */ + if ((hsai->State == HAL_SAI_STATE_BUSY_TX) && (hsai->hdmatx != NULL)) + { + if (HAL_DMA_Abort(hsai->hdmatx) != HAL_OK) + { + /* If the DMA Tx errorCode is different from DMA No Transfer then return Error */ + if (hsai->hdmatx->ErrorCode != HAL_DMA_ERROR_NO_XFER) + { + status = HAL_ERROR; + hsai->ErrorCode |= HAL_SAI_ERROR_DMA; + } + } + } + + /* Abort the SAI Rx DMA Stream */ + if ((hsai->State == HAL_SAI_STATE_BUSY_RX) && (hsai->hdmarx != NULL)) + { + if (HAL_DMA_Abort(hsai->hdmarx) != HAL_OK) + { + /* If the DMA Rx errorCode is different from DMA No Transfer then return Error */ + if (hsai->hdmarx->ErrorCode != HAL_DMA_ERROR_NO_XFER) + { + status = HAL_ERROR; + hsai->ErrorCode |= HAL_SAI_ERROR_DMA; + } + } + } + + /* Flush the fifo */ + SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH); + + /* Set hsai state to ready */ + hsai->State = HAL_SAI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsai); + + return status; +} + +/** + * @brief Abort the current transfer and disable the SAI. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_Abort(SAI_HandleTypeDef *hsai) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process Locked */ + __HAL_LOCK(hsai); + + /* Disable SAI peripheral */ + if (SAI_Disable(hsai) != HAL_OK) + { + status = HAL_ERROR; + } + + /* Check SAI DMA is enabled or not */ + if ((hsai->Instance->CR1 & SAI_xCR1_DMAEN) == SAI_xCR1_DMAEN) + { + /* Disable the SAI DMA request */ + hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN; + + /* Abort the SAI Tx DMA Stream */ + if ((hsai->State == HAL_SAI_STATE_BUSY_TX) && (hsai->hdmatx != NULL)) + { + if (HAL_DMA_Abort(hsai->hdmatx) != HAL_OK) + { + /* If the DMA Tx errorCode is different from DMA No Transfer then return Error */ + if (hsai->hdmatx->ErrorCode != HAL_DMA_ERROR_NO_XFER) + { + status = HAL_ERROR; + hsai->ErrorCode |= HAL_SAI_ERROR_DMA; + } + } + } + + /* Abort the SAI Rx DMA Stream */ + if ((hsai->State == HAL_SAI_STATE_BUSY_RX) && (hsai->hdmarx != NULL)) + { + if (HAL_DMA_Abort(hsai->hdmarx) != HAL_OK) + { + /* If the DMA Rx errorCode is different from DMA No Transfer then return Error */ + if (hsai->hdmarx->ErrorCode != HAL_DMA_ERROR_NO_XFER) + { + status = HAL_ERROR; + hsai->ErrorCode |= HAL_SAI_ERROR_DMA; + } + } + } + } + + /* Disabled All interrupt and clear all the flag */ + hsai->Instance->IMR = 0; + hsai->Instance->CLRFR = 0xFFFFFFFFU; + + /* Flush the fifo */ + SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH); + + /* Set hsai state to ready */ + hsai->State = HAL_SAI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsai); + + return status; +} + +/** + * @brief Transmit an amount of data in non-blocking mode with DMA. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_Transmit_DMA(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size) +{ + HAL_StatusTypeDef status; + uint32_t tickstart = HAL_GetTick(); + + if ((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + if (hsai->State == HAL_SAI_STATE_READY) + { + uint32_t dmaSrcSize; + + /* Process Locked */ + __HAL_LOCK(hsai); + + hsai->pBuffPtr = pData; + hsai->XferSize = Size; + hsai->XferCount = Size; + hsai->ErrorCode = HAL_SAI_ERROR_NONE; + hsai->State = HAL_SAI_STATE_BUSY_TX; + + /* Set the SAI Tx DMA Half transfer complete callback */ + hsai->hdmatx->XferHalfCpltCallback = SAI_DMATxHalfCplt; + + /* Set the SAI TxDMA transfer complete callback */ + hsai->hdmatx->XferCpltCallback = SAI_DMATxCplt; + + /* Set the DMA error callback */ + hsai->hdmatx->XferErrorCallback = SAI_DMAError; + + /* Set the DMA Tx abort callback */ + hsai->hdmatx->XferAbortCallback = NULL; + + /* For transmission, the DMA source is data buffer. + We have to compute DMA size of a source block transfer in bytes according SAI data size. */ + if ((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING)) + { + dmaSrcSize = (uint32_t) Size; + } + else if (hsai->Init.DataSize <= SAI_DATASIZE_16) + { + dmaSrcSize = 2U * (uint32_t) Size; + } + else + { + dmaSrcSize = 4U * (uint32_t) Size; + } + + /* Enable the Tx DMA Stream */ + if ((hsai->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hsai->hdmatx->LinkedListQueue != NULL) + { + /* Set DMA data size */ + hsai->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = dmaSrcSize; + + /* Set DMA source address */ + hsai->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)hsai->pBuffPtr; + + /* Set DMA destination address */ + hsai->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)&hsai->Instance->DR; + + status = HAL_DMAEx_List_Start_IT(hsai->hdmatx); + } + else + { + __HAL_UNLOCK(hsai); + return HAL_ERROR; + } + } + else + { + status = HAL_DMA_Start_IT(hsai->hdmatx, (uint32_t)hsai->pBuffPtr, (uint32_t)&hsai->Instance->DR, dmaSrcSize); + } + + if (status != HAL_OK) + { + __HAL_UNLOCK(hsai); + return HAL_ERROR; + } + + /* Enable the interrupts for error handling */ + __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA)); + + /* Enable SAI Tx DMA Request */ + hsai->Instance->CR1 |= SAI_xCR1_DMAEN; + + /* Wait until FIFO is not empty */ + while ((hsai->Instance->SR & SAI_xSR_FLVL) == SAI_FIFOSTATUS_EMPTY) + { + /* Check for the Timeout */ + if ((HAL_GetTick() - tickstart) > SAI_LONG_TIMEOUT) + { + /* Update error code */ + hsai->ErrorCode |= HAL_SAI_ERROR_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hsai); + + return HAL_TIMEOUT; + } + } + + /* Check if the SAI is already enabled */ + if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == 0U) + { + /* Enable SAI peripheral */ + __HAL_SAI_ENABLE(hsai); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hsai); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in non-blocking mode with DMA. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @param pData Pointer to data buffer + * @param Size Amount of data to be received + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_Receive_DMA(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size) +{ + HAL_StatusTypeDef status; + + if ((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + if (hsai->State == HAL_SAI_STATE_READY) + { + uint32_t dmaSrcSize; + + /* Process Locked */ + __HAL_LOCK(hsai); + + hsai->pBuffPtr = pData; + hsai->XferSize = Size; + hsai->XferCount = Size; + hsai->ErrorCode = HAL_SAI_ERROR_NONE; + hsai->State = HAL_SAI_STATE_BUSY_RX; + + /* Set the SAI Rx DMA Half transfer complete callback */ + hsai->hdmarx->XferHalfCpltCallback = SAI_DMARxHalfCplt; + + /* Set the SAI Rx DMA transfer complete callback */ + hsai->hdmarx->XferCpltCallback = SAI_DMARxCplt; + + /* Set the DMA error callback */ + hsai->hdmarx->XferErrorCallback = SAI_DMAError; + + /* Set the DMA Rx abort callback */ + hsai->hdmarx->XferAbortCallback = NULL; + + /* For reception, the DMA source is SAI DR register. + We have to compute DMA size of a source block transfer in bytes according SAI data size. */ + if ((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING)) + { + dmaSrcSize = (uint32_t) Size; + } + else if (hsai->Init.DataSize <= SAI_DATASIZE_16) + { + dmaSrcSize = 2U * (uint32_t) Size; + } + else + { + dmaSrcSize = 4U * (uint32_t) Size; + } + + /* Enable the Rx DMA Stream */ + if ((hsai->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hsai->hdmarx->LinkedListQueue != NULL) + { + /* Set DMA data size */ + hsai->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = dmaSrcSize; + + /* Set DMA source address */ + hsai->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)&hsai->Instance->DR; + + /* Set DMA destination address */ + hsai->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)hsai->pBuffPtr; + + status = HAL_DMAEx_List_Start_IT(hsai->hdmarx); + } + else + { + __HAL_UNLOCK(hsai); + return HAL_ERROR; + } + } + else + { + status = HAL_DMA_Start_IT(hsai->hdmarx, (uint32_t)&hsai->Instance->DR, (uint32_t)hsai->pBuffPtr, dmaSrcSize); + } + + if (status != HAL_OK) + { + __HAL_UNLOCK(hsai); + return HAL_ERROR; + } + + /* Enable the interrupts for error handling */ + __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA)); + + /* Enable SAI Rx DMA Request */ + hsai->Instance->CR1 |= SAI_xCR1_DMAEN; + + /* Check if the SAI is already enabled */ + if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == 0U) + { + /* Enable SAI peripheral */ + __HAL_SAI_ENABLE(hsai); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hsai); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Enable the Tx mute mode. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @param val value sent during the mute @ref SAI_Block_Mute_Value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_EnableTxMuteMode(SAI_HandleTypeDef *hsai, uint16_t val) +{ + assert_param(IS_SAI_BLOCK_MUTE_VALUE(val)); + + if (hsai->State != HAL_SAI_STATE_RESET) + { + CLEAR_BIT(hsai->Instance->CR2, SAI_xCR2_MUTEVAL | SAI_xCR2_MUTE); + SET_BIT(hsai->Instance->CR2, SAI_xCR2_MUTE | (uint32_t)val); + return HAL_OK; + } + return HAL_ERROR; +} + +/** + * @brief Disable the Tx mute mode. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_DisableTxMuteMode(SAI_HandleTypeDef *hsai) +{ + if (hsai->State != HAL_SAI_STATE_RESET) + { + CLEAR_BIT(hsai->Instance->CR2, SAI_xCR2_MUTEVAL | SAI_xCR2_MUTE); + return HAL_OK; + } + return HAL_ERROR; +} + +/** + * @brief Enable the Rx mute detection. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @param callback function called when the mute is detected. + * @param counter number a data before mute detection max 63. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_EnableRxMuteMode(SAI_HandleTypeDef *hsai, SAIcallback callback, uint16_t counter) +{ + assert_param(IS_SAI_BLOCK_MUTE_COUNTER(counter)); + + if (hsai->State != HAL_SAI_STATE_RESET) + { + /* set the mute counter */ + CLEAR_BIT(hsai->Instance->CR2, SAI_xCR2_MUTECNT); + SET_BIT(hsai->Instance->CR2, (uint32_t)((uint32_t)counter << SAI_xCR2_MUTECNT_Pos)); + hsai->mutecallback = callback; + /* enable the IT interrupt */ + __HAL_SAI_ENABLE_IT(hsai, SAI_IT_MUTEDET); + return HAL_OK; + } + return HAL_ERROR; +} + +/** + * @brief Disable the Rx mute detection. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_DisableRxMuteMode(SAI_HandleTypeDef *hsai) +{ + if (hsai->State != HAL_SAI_STATE_RESET) + { + /* set the mutecallback to NULL */ + hsai->mutecallback = NULL; + /* enable the IT interrupt */ + __HAL_SAI_DISABLE_IT(hsai, SAI_IT_MUTEDET); + return HAL_OK; + } + return HAL_ERROR; +} + +/** + * @brief Handle SAI interrupt request. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None + */ +void HAL_SAI_IRQHandler(SAI_HandleTypeDef *hsai) +{ + if (hsai->State != HAL_SAI_STATE_RESET) + { + uint32_t itflags = hsai->Instance->SR; + uint32_t itsources = hsai->Instance->IMR; + uint32_t cr1config = hsai->Instance->CR1; + uint32_t tmperror; + + /* SAI Fifo request interrupt occurred -----------------------------------*/ + if (((itflags & SAI_xSR_FREQ) == SAI_xSR_FREQ) && ((itsources & SAI_IT_FREQ) == SAI_IT_FREQ)) + { + hsai->InterruptServiceRoutine(hsai); + } + /* SAI Overrun error interrupt occurred ----------------------------------*/ + else if (((itflags & SAI_FLAG_OVRUDR) == SAI_FLAG_OVRUDR) && ((itsources & SAI_IT_OVRUDR) == SAI_IT_OVRUDR)) + { + /* Clear the SAI Overrun flag */ + __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_OVRUDR); + /* Get the SAI error code */ + tmperror = ((hsai->State == HAL_SAI_STATE_BUSY_RX) ? HAL_SAI_ERROR_OVR : HAL_SAI_ERROR_UDR); + /* Change the SAI error code */ + hsai->ErrorCode |= tmperror; + /* the transfer is not stopped, we will forward the information to the user and we let + the user decide what needs to be done */ +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) + hsai->ErrorCallback(hsai); +#else + HAL_SAI_ErrorCallback(hsai); +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ + } + /* SAI mutedet interrupt occurred ----------------------------------*/ + else if (((itflags & SAI_FLAG_MUTEDET) == SAI_FLAG_MUTEDET) && ((itsources & SAI_IT_MUTEDET) == SAI_IT_MUTEDET)) + { + /* Clear the SAI mutedet flag */ + __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_MUTEDET); + /* call the call back function */ + if (hsai->mutecallback != NULL) + { + /* inform the user that an RX mute event has been detected */ + hsai->mutecallback(); + } + } + /* SAI AFSDET interrupt occurred ----------------------------------*/ + else if (((itflags & SAI_FLAG_AFSDET) == SAI_FLAG_AFSDET) && ((itsources & SAI_IT_AFSDET) == SAI_IT_AFSDET)) + { + /* Clear the SAI AFSDET flag */ + __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_AFSDET); + + /* Change the SAI error code */ + hsai->ErrorCode |= HAL_SAI_ERROR_AFSDET; + + /* Check SAI DMA is enabled or not */ + if ((cr1config & SAI_xCR1_DMAEN) == SAI_xCR1_DMAEN) + { + /* Abort the SAI DMA Streams */ + if (hsai->hdmatx != NULL) + { + /* Set the DMA Tx abort callback */ + hsai->hdmatx->XferAbortCallback = SAI_DMAAbort; + + /* Abort DMA in IT mode */ + if (HAL_DMA_Abort_IT(hsai->hdmatx) != HAL_OK) + { + /* Update SAI error code */ + hsai->ErrorCode |= HAL_SAI_ERROR_DMA; + + /* Call SAI error callback */ +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) + hsai->ErrorCallback(hsai); +#else + HAL_SAI_ErrorCallback(hsai); +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ + } + } + if (hsai->hdmarx != NULL) + { + /* Set the DMA Rx abort callback */ + hsai->hdmarx->XferAbortCallback = SAI_DMAAbort; + + /* Abort DMA in IT mode */ + if (HAL_DMA_Abort_IT(hsai->hdmarx) != HAL_OK) + { + /* Update SAI error code */ + hsai->ErrorCode |= HAL_SAI_ERROR_DMA; + + /* Call SAI error callback */ +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) + hsai->ErrorCallback(hsai); +#else + HAL_SAI_ErrorCallback(hsai); +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ + } + } + } + else + { + /* Abort SAI */ + /* No need to check return value because HAL_SAI_ErrorCallback will be called later */ + (void) HAL_SAI_Abort(hsai); + + /* Set error callback */ +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) + hsai->ErrorCallback(hsai); +#else + HAL_SAI_ErrorCallback(hsai); +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ + } + } + /* SAI LFSDET interrupt occurred ----------------------------------*/ + else if (((itflags & SAI_FLAG_LFSDET) == SAI_FLAG_LFSDET) && ((itsources & SAI_IT_LFSDET) == SAI_IT_LFSDET)) + { + /* Clear the SAI LFSDET flag */ + __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_LFSDET); + + /* Change the SAI error code */ + hsai->ErrorCode |= HAL_SAI_ERROR_LFSDET; + + /* Check SAI DMA is enabled or not */ + if ((cr1config & SAI_xCR1_DMAEN) == SAI_xCR1_DMAEN) + { + /* Abort the SAI DMA Streams */ + if (hsai->hdmatx != NULL) + { + /* Set the DMA Tx abort callback */ + hsai->hdmatx->XferAbortCallback = SAI_DMAAbort; + + /* Abort DMA in IT mode */ + if (HAL_DMA_Abort_IT(hsai->hdmatx) != HAL_OK) + { + /* Update SAI error code */ + hsai->ErrorCode |= HAL_SAI_ERROR_DMA; + + /* Call SAI error callback */ +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) + hsai->ErrorCallback(hsai); +#else + HAL_SAI_ErrorCallback(hsai); +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ + } + } + if (hsai->hdmarx != NULL) + { + /* Set the DMA Rx abort callback */ + hsai->hdmarx->XferAbortCallback = SAI_DMAAbort; + + /* Abort DMA in IT mode */ + if (HAL_DMA_Abort_IT(hsai->hdmarx) != HAL_OK) + { + /* Update SAI error code */ + hsai->ErrorCode |= HAL_SAI_ERROR_DMA; + + /* Call SAI error callback */ +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) + hsai->ErrorCallback(hsai); +#else + HAL_SAI_ErrorCallback(hsai); +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ + } + } + } + else + { + /* Abort SAI */ + /* No need to check return value because HAL_SAI_ErrorCallback will be called later */ + (void) HAL_SAI_Abort(hsai); + + /* Set error callback */ +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) + hsai->ErrorCallback(hsai); +#else + HAL_SAI_ErrorCallback(hsai); +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ + } + } + /* SAI WCKCFG interrupt occurred ----------------------------------*/ + else if (((itflags & SAI_FLAG_WCKCFG) == SAI_FLAG_WCKCFG) && ((itsources & SAI_IT_WCKCFG) == SAI_IT_WCKCFG)) + { + /* Clear the SAI WCKCFG flag */ + __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_WCKCFG); + + /* Change the SAI error code */ + hsai->ErrorCode |= HAL_SAI_ERROR_WCKCFG; + + /* Check SAI DMA is enabled or not */ + if ((cr1config & SAI_xCR1_DMAEN) == SAI_xCR1_DMAEN) + { + /* Abort the SAI DMA Streams */ + if (hsai->hdmatx != NULL) + { + /* Set the DMA Tx abort callback */ + hsai->hdmatx->XferAbortCallback = SAI_DMAAbort; + + /* Abort DMA in IT mode */ + if (HAL_DMA_Abort_IT(hsai->hdmatx) != HAL_OK) + { + /* Update SAI error code */ + hsai->ErrorCode |= HAL_SAI_ERROR_DMA; + + /* Call SAI error callback */ +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) + hsai->ErrorCallback(hsai); +#else + HAL_SAI_ErrorCallback(hsai); +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ + } + } + if (hsai->hdmarx != NULL) + { + /* Set the DMA Rx abort callback */ + hsai->hdmarx->XferAbortCallback = SAI_DMAAbort; + + /* Abort DMA in IT mode */ + if (HAL_DMA_Abort_IT(hsai->hdmarx) != HAL_OK) + { + /* Update SAI error code */ + hsai->ErrorCode |= HAL_SAI_ERROR_DMA; + + /* Call SAI error callback */ +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) + hsai->ErrorCallback(hsai); +#else + HAL_SAI_ErrorCallback(hsai); +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ + } + } + } + else + { + /* If WCKCFG occurs, SAI audio block is automatically disabled */ + /* Disable all interrupts and clear all flags */ + hsai->Instance->IMR = 0U; + hsai->Instance->CLRFR = 0xFFFFFFFFU; + /* Set the SAI state to ready to be able to start again the process */ + hsai->State = HAL_SAI_STATE_READY; + + /* Initialize XferCount */ + hsai->XferCount = 0U; + + /* SAI error callback */ +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) + hsai->ErrorCallback(hsai); +#else + HAL_SAI_ErrorCallback(hsai); +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ + } + } + /* SAI CNRDY interrupt occurred ----------------------------------*/ + else if (((itflags & SAI_FLAG_CNRDY) == SAI_FLAG_CNRDY) && ((itsources & SAI_IT_CNRDY) == SAI_IT_CNRDY)) + { + /* Clear the SAI CNRDY flag */ + __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_CNRDY); + /* Change the SAI error code */ + hsai->ErrorCode |= HAL_SAI_ERROR_CNREADY; + /* the transfer is not stopped, we will forward the information to the user and we let + the user decide what needs to be done */ +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) + hsai->ErrorCallback(hsai); +#else + HAL_SAI_ErrorCallback(hsai); +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ + } + else + { + /* Nothing to do */ + } + } +} + +/** + * @brief Tx Transfer completed callback. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None + */ +__weak void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsai); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SAI_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Tx Transfer Half completed callback. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None + */ +__weak void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsai); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SAI_TxHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Transfer completed callback. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None + */ +__weak void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsai); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SAI_RxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Transfer half completed callback. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None + */ +__weak void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsai); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SAI_RxHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief SAI error callback. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None + */ +__weak void HAL_SAI_ErrorCallback(SAI_HandleTypeDef *hsai) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsai); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SAI_ErrorCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup SAI_Exported_Functions_Group3 Peripheral State functions + * @brief Peripheral State functions + * +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the SAI handle state. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval HAL state + */ +HAL_SAI_StateTypeDef HAL_SAI_GetState(const SAI_HandleTypeDef *hsai) +{ + return hsai->State; +} + +/** + * @brief Return the SAI error code. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for the specified SAI Block. + * @retval SAI Error Code + */ +uint32_t HAL_SAI_GetError(const SAI_HandleTypeDef *hsai) +{ + return hsai->ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup SAI_Private_Functions + * @brief Private functions + * @{ + */ + +/** + * @brief Initialize the SAI I2S protocol according to the specified parameters + * in the SAI_InitTypeDef and create the associated handle. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @param protocol one of the supported protocol. + * @param datasize one of the supported datasize @ref SAI_Protocol_DataSize. + * @param nbslot number of slot minimum value is 2 and max is 16. + * the value must be a multiple of 2. + * @retval HAL status + */ +static HAL_StatusTypeDef SAI_InitI2S(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot) +{ + HAL_StatusTypeDef status = HAL_OK; + + hsai->Init.Protocol = SAI_FREE_PROTOCOL; + hsai->Init.FirstBit = SAI_FIRSTBIT_MSB; + /* Compute ClockStrobing according AudioMode */ + if ((hsai->Init.AudioMode == SAI_MODEMASTER_TX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX)) + { + /* Transmit */ + hsai->Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE; + } + else + { + /* Receive */ + hsai->Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE; + } + hsai->FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION; + hsai->SlotInit.SlotActive = SAI_SLOTACTIVE_ALL; + hsai->SlotInit.FirstBitOffset = 0; + hsai->SlotInit.SlotNumber = nbslot; + + /* in IS2 the number of slot must be even */ + if ((nbslot & 0x1U) != 0U) + { + return HAL_ERROR; + } + + if (protocol == SAI_I2S_STANDARD) + { + hsai->FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW; + hsai->FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT; + } + else + { + /* SAI_I2S_MSBJUSTIFIED or SAI_I2S_LSBJUSTIFIED */ + hsai->FrameInit.FSPolarity = SAI_FS_ACTIVE_HIGH; + hsai->FrameInit.FSOffset = SAI_FS_FIRSTBIT; + } + + /* Frame definition */ + switch (datasize) + { + case SAI_PROTOCOL_DATASIZE_16BIT: + hsai->Init.DataSize = SAI_DATASIZE_16; + hsai->FrameInit.FrameLength = 32U * (nbslot / 2U); + hsai->FrameInit.ActiveFrameLength = 16U * (nbslot / 2U); + hsai->SlotInit.SlotSize = SAI_SLOTSIZE_16B; + break; + case SAI_PROTOCOL_DATASIZE_16BITEXTENDED : + hsai->Init.DataSize = SAI_DATASIZE_16; + hsai->FrameInit.FrameLength = 64U * (nbslot / 2U); + hsai->FrameInit.ActiveFrameLength = 32U * (nbslot / 2U); + hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B; + break; + case SAI_PROTOCOL_DATASIZE_24BIT: + hsai->Init.DataSize = SAI_DATASIZE_24; + hsai->FrameInit.FrameLength = 64U * (nbslot / 2U); + hsai->FrameInit.ActiveFrameLength = 32U * (nbslot / 2U); + hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B; + break; + case SAI_PROTOCOL_DATASIZE_32BIT: + hsai->Init.DataSize = SAI_DATASIZE_32; + hsai->FrameInit.FrameLength = 64U * (nbslot / 2U); + hsai->FrameInit.ActiveFrameLength = 32U * (nbslot / 2U); + hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B; + break; + default : + status = HAL_ERROR; + break; + } + if (protocol == SAI_I2S_LSBJUSTIFIED) + { + if (datasize == SAI_PROTOCOL_DATASIZE_16BITEXTENDED) + { + hsai->SlotInit.FirstBitOffset = 16; + } + if (datasize == SAI_PROTOCOL_DATASIZE_24BIT) + { + hsai->SlotInit.FirstBitOffset = 8; + } + } + return status; +} + +/** + * @brief Initialize the SAI PCM protocol according to the specified parameters + * in the SAI_InitTypeDef and create the associated handle. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @param protocol one of the supported protocol + * @param datasize one of the supported datasize @ref SAI_Protocol_DataSize + * @param nbslot number of slot minimum value is 1 and the max is 16. + * @retval HAL status + */ +static HAL_StatusTypeDef SAI_InitPCM(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot) +{ + HAL_StatusTypeDef status = HAL_OK; + + hsai->Init.Protocol = SAI_FREE_PROTOCOL; + hsai->Init.FirstBit = SAI_FIRSTBIT_MSB; + /* Compute ClockStrobing according AudioMode */ + if ((hsai->Init.AudioMode == SAI_MODEMASTER_TX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX)) + { + /* Transmit */ + hsai->Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE; + } + else + { + /* Receive */ + hsai->Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE; + } + hsai->FrameInit.FSDefinition = SAI_FS_STARTFRAME; + hsai->FrameInit.FSPolarity = SAI_FS_ACTIVE_HIGH; + hsai->FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT; + hsai->SlotInit.FirstBitOffset = 0; + hsai->SlotInit.SlotNumber = nbslot; + hsai->SlotInit.SlotActive = SAI_SLOTACTIVE_ALL; + + if (protocol == SAI_PCM_SHORT) + { + hsai->FrameInit.ActiveFrameLength = 1; + } + else + { + /* SAI_PCM_LONG */ + hsai->FrameInit.ActiveFrameLength = 13; + } + + switch (datasize) + { + case SAI_PROTOCOL_DATASIZE_16BIT: + hsai->Init.DataSize = SAI_DATASIZE_16; + hsai->FrameInit.FrameLength = 16U * nbslot; + hsai->SlotInit.SlotSize = SAI_SLOTSIZE_16B; + break; + case SAI_PROTOCOL_DATASIZE_16BITEXTENDED : + hsai->Init.DataSize = SAI_DATASIZE_16; + hsai->FrameInit.FrameLength = 32U * nbslot; + hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B; + break; + case SAI_PROTOCOL_DATASIZE_24BIT : + hsai->Init.DataSize = SAI_DATASIZE_24; + hsai->FrameInit.FrameLength = 32U * nbslot; + hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B; + break; + case SAI_PROTOCOL_DATASIZE_32BIT: + hsai->Init.DataSize = SAI_DATASIZE_32; + hsai->FrameInit.FrameLength = 32U * nbslot; + hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B; + break; + default : + status = HAL_ERROR; + break; + } + + return status; +} + +/** + * @brief Fill the fifo. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None + */ +static void SAI_FillFifo(SAI_HandleTypeDef *hsai) +{ + uint32_t temp; + + /* fill the fifo with data before to enabled the SAI */ + while (((hsai->Instance->SR & SAI_xSR_FLVL) != SAI_FIFOSTATUS_FULL) && (hsai->XferCount > 0U)) + { + if ((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING)) + { + hsai->Instance->DR = *hsai->pBuffPtr; + hsai->pBuffPtr++; + } + else if (hsai->Init.DataSize <= SAI_DATASIZE_16) + { + temp = (uint32_t)(*hsai->pBuffPtr); + hsai->pBuffPtr++; + temp |= ((uint32_t)(*hsai->pBuffPtr) << 8); + hsai->pBuffPtr++; + hsai->Instance->DR = temp; + } + else + { + temp = (uint32_t)(*hsai->pBuffPtr); + hsai->pBuffPtr++; + temp |= ((uint32_t)(*hsai->pBuffPtr) << 8); + hsai->pBuffPtr++; + temp |= ((uint32_t)(*hsai->pBuffPtr) << 16); + hsai->pBuffPtr++; + temp |= ((uint32_t)(*hsai->pBuffPtr) << 24); + hsai->pBuffPtr++; + hsai->Instance->DR = temp; + } + hsai->XferCount--; + } +} + +/** + * @brief Return the interrupt flag to set according the SAI setup. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @param mode SAI_MODE_DMA or SAI_MODE_IT + * @retval the list of the IT flag to enable + */ +static uint32_t SAI_InterruptFlag(const SAI_HandleTypeDef *hsai, SAI_ModeTypedef mode) +{ + uint32_t tmpIT = SAI_IT_OVRUDR; + + if (mode == SAI_MODE_IT) + { + tmpIT |= SAI_IT_FREQ; + } + + if ((hsai->Init.Protocol == SAI_AC97_PROTOCOL) && + ((hsai->Init.AudioMode == SAI_MODESLAVE_RX) || (hsai->Init.AudioMode == SAI_MODEMASTER_RX))) + { + tmpIT |= SAI_IT_CNRDY; + } + + if ((hsai->Init.AudioMode == SAI_MODESLAVE_RX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX)) + { + tmpIT |= SAI_IT_AFSDET | SAI_IT_LFSDET; + } + else + { + /* hsai has been configured in master mode */ + tmpIT |= SAI_IT_WCKCFG; + } + return tmpIT; +} + +/** + * @brief Disable the SAI and wait for the disabling. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None + */ +static HAL_StatusTypeDef SAI_Disable(SAI_HandleTypeDef *hsai) +{ + uint32_t count = SAI_DEFAULT_TIMEOUT * (SystemCoreClock / 7U / 1000U); + HAL_StatusTypeDef status = HAL_OK; + + /* Disable the SAI instance */ + __HAL_SAI_DISABLE(hsai); + + do + { + /* Check for the Timeout */ + if (count == 0U) + { + /* Update error code */ + hsai->ErrorCode |= HAL_SAI_ERROR_TIMEOUT; + status = HAL_TIMEOUT; + break; + } + count--; + } while ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) != 0U); + + return status; +} + +/** + * @brief Tx Handler for Transmit in Interrupt mode 8-Bit transfer. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None + */ +static void SAI_Transmit_IT8Bit(SAI_HandleTypeDef *hsai) +{ + if (hsai->XferCount == 0U) + { + /* Handle the end of the transmission */ + /* Disable FREQ and OVRUDR interrupts */ + __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT)); + hsai->State = HAL_SAI_STATE_READY; +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) + hsai->TxCpltCallback(hsai); +#else + HAL_SAI_TxCpltCallback(hsai); +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ + } + else + { + /* Write data on DR register */ + hsai->Instance->DR = *hsai->pBuffPtr; + hsai->pBuffPtr++; + hsai->XferCount--; + } +} + +/** + * @brief Tx Handler for Transmit in Interrupt mode for 16-Bit transfer. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None + */ +static void SAI_Transmit_IT16Bit(SAI_HandleTypeDef *hsai) +{ + if (hsai->XferCount == 0U) + { + /* Handle the end of the transmission */ + /* Disable FREQ and OVRUDR interrupts */ + __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT)); + hsai->State = HAL_SAI_STATE_READY; +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) + hsai->TxCpltCallback(hsai); +#else + HAL_SAI_TxCpltCallback(hsai); +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ + } + else + { + /* Write data on DR register */ + uint32_t temp; + temp = (uint32_t)(*hsai->pBuffPtr); + hsai->pBuffPtr++; + temp |= ((uint32_t)(*hsai->pBuffPtr) << 8); + hsai->pBuffPtr++; + hsai->Instance->DR = temp; + hsai->XferCount--; + } +} + +/** + * @brief Tx Handler for Transmit in Interrupt mode for 32-Bit transfer. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None + */ +static void SAI_Transmit_IT32Bit(SAI_HandleTypeDef *hsai) +{ + if (hsai->XferCount == 0U) + { + /* Handle the end of the transmission */ + /* Disable FREQ and OVRUDR interrupts */ + __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT)); + hsai->State = HAL_SAI_STATE_READY; +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) + hsai->TxCpltCallback(hsai); +#else + HAL_SAI_TxCpltCallback(hsai); +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ + } + else + { + /* Write data on DR register */ + uint32_t temp; + temp = (uint32_t)(*hsai->pBuffPtr); + hsai->pBuffPtr++; + temp |= ((uint32_t)(*hsai->pBuffPtr) << 8); + hsai->pBuffPtr++; + temp |= ((uint32_t)(*hsai->pBuffPtr) << 16); + hsai->pBuffPtr++; + temp |= ((uint32_t)(*hsai->pBuffPtr) << 24); + hsai->pBuffPtr++; + hsai->Instance->DR = temp; + hsai->XferCount--; + } +} + +/** + * @brief Rx Handler for Receive in Interrupt mode 8-Bit transfer. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None + */ +static void SAI_Receive_IT8Bit(SAI_HandleTypeDef *hsai) +{ + /* Receive data */ + *hsai->pBuffPtr = (uint8_t)hsai->Instance->DR; + hsai->pBuffPtr++; + hsai->XferCount--; + + /* Check end of the transfer */ + if (hsai->XferCount == 0U) + { + /* Disable TXE and OVRUDR interrupts */ + __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT)); + + /* Clear the SAI Overrun flag */ + __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_OVRUDR); + + hsai->State = HAL_SAI_STATE_READY; +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) + hsai->RxCpltCallback(hsai); +#else + HAL_SAI_RxCpltCallback(hsai); +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ + } +} + +/** + * @brief Rx Handler for Receive in Interrupt mode for 16-Bit transfer. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None + */ +static void SAI_Receive_IT16Bit(SAI_HandleTypeDef *hsai) +{ + uint32_t temp; + + /* Receive data */ + temp = hsai->Instance->DR; + *hsai->pBuffPtr = (uint8_t)temp; + hsai->pBuffPtr++; + *hsai->pBuffPtr = (uint8_t)(temp >> 8); + hsai->pBuffPtr++; + hsai->XferCount--; + + /* Check end of the transfer */ + if (hsai->XferCount == 0U) + { + /* Disable TXE and OVRUDR interrupts */ + __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT)); + + /* Clear the SAI Overrun flag */ + __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_OVRUDR); + + hsai->State = HAL_SAI_STATE_READY; +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) + hsai->RxCpltCallback(hsai); +#else + HAL_SAI_RxCpltCallback(hsai); +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ + } +} + +/** + * @brief Rx Handler for Receive in Interrupt mode for 32-Bit transfer. + * @param hsai pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None + */ +static void SAI_Receive_IT32Bit(SAI_HandleTypeDef *hsai) +{ + uint32_t temp; + + /* Receive data */ + temp = hsai->Instance->DR; + *hsai->pBuffPtr = (uint8_t)temp; + hsai->pBuffPtr++; + *hsai->pBuffPtr = (uint8_t)(temp >> 8); + hsai->pBuffPtr++; + *hsai->pBuffPtr = (uint8_t)(temp >> 16); + hsai->pBuffPtr++; + *hsai->pBuffPtr = (uint8_t)(temp >> 24); + hsai->pBuffPtr++; + hsai->XferCount--; + + /* Check end of the transfer */ + if (hsai->XferCount == 0U) + { + /* Disable TXE and OVRUDR interrupts */ + __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT)); + + /* Clear the SAI Overrun flag */ + __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_OVRUDR); + + hsai->State = HAL_SAI_STATE_READY; +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) + hsai->RxCpltCallback(hsai); +#else + HAL_SAI_RxCpltCallback(hsai); +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ + } +} + +/** + * @brief DMA SAI transmit process complete callback. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SAI_DMATxCplt(DMA_HandleTypeDef *hdma) +{ + SAI_HandleTypeDef *hsai = (SAI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Check if DMA in circular mode */ + if (hdma->Mode != DMA_LINKEDLIST_CIRCULAR) + { + hsai->XferCount = 0; + + /* Disable SAI Tx DMA Request */ + hsai->Instance->CR1 &= (uint32_t)(~SAI_xCR1_DMAEN); + + /* Stop the interrupts error handling */ + __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA)); + + hsai->State = HAL_SAI_STATE_READY; + } + +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) + hsai->TxCpltCallback(hsai); +#else + HAL_SAI_TxCpltCallback(hsai); +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA SAI transmit process half complete callback. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SAI_DMATxHalfCplt(DMA_HandleTypeDef *hdma) +{ + SAI_HandleTypeDef *hsai = (SAI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) + hsai->TxHalfCpltCallback(hsai); +#else + HAL_SAI_TxHalfCpltCallback(hsai); +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA SAI receive process complete callback. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SAI_DMARxCplt(DMA_HandleTypeDef *hdma) +{ + SAI_HandleTypeDef *hsai = (SAI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Check if DMA in circular mode*/ + if (hdma->Mode != DMA_LINKEDLIST_CIRCULAR) + { + /* Disable Rx DMA Request */ + hsai->Instance->CR1 &= (uint32_t)(~SAI_xCR1_DMAEN); + hsai->XferCount = 0; + + /* Stop the interrupts error handling */ + __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA)); + + hsai->State = HAL_SAI_STATE_READY; + } + +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) + hsai->RxCpltCallback(hsai); +#else + HAL_SAI_RxCpltCallback(hsai); +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA SAI receive process half complete callback + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SAI_DMARxHalfCplt(DMA_HandleTypeDef *hdma) +{ + SAI_HandleTypeDef *hsai = (SAI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) + hsai->RxHalfCpltCallback(hsai); +#else + HAL_SAI_RxHalfCpltCallback(hsai); +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA SAI communication error callback. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SAI_DMAError(DMA_HandleTypeDef *hdma) +{ + SAI_HandleTypeDef *hsai = (SAI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Set SAI error code */ + hsai->ErrorCode |= HAL_SAI_ERROR_DMA; + + /* Disable the SAI DMA request */ + hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN; + + /* Disable SAI peripheral */ + /* No need to check return value because state will be updated and HAL_SAI_ErrorCallback will be called later */ + (void) SAI_Disable(hsai); + + /* Set the SAI state ready to be able to start again the process */ + hsai->State = HAL_SAI_STATE_READY; + + /* Initialize XferCount */ + hsai->XferCount = 0U; + + /* SAI error Callback */ +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) + hsai->ErrorCallback(hsai); +#else + HAL_SAI_ErrorCallback(hsai); +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA SAI Abort callback. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SAI_DMAAbort(DMA_HandleTypeDef *hdma) +{ + SAI_HandleTypeDef *hsai = (SAI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Disable DMA request */ + hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN; + + /* Disable all interrupts and clear all flags */ + hsai->Instance->IMR = 0U; + hsai->Instance->CLRFR = 0xFFFFFFFFU; + + if (hsai->ErrorCode != HAL_SAI_ERROR_WCKCFG) + { + /* Disable SAI peripheral */ + /* No need to check return value because state will be updated and HAL_SAI_ErrorCallback will be called later */ + (void) SAI_Disable(hsai); + + /* Flush the fifo */ + SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH); + } + /* Set the SAI state to ready to be able to start again the process */ + hsai->State = HAL_SAI_STATE_READY; + + /* Initialize XferCount */ + hsai->XferCount = 0U; + + /* SAI error Callback */ +#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1) + hsai->ErrorCallback(hsai); +#else + HAL_SAI_ErrorCallback(hsai); +#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */ +} + +/** + * @} + */ + +#endif /* HAL_SAI_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +#endif /* SAI1 */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sai_ex.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sai_ex.c new file mode 100644 index 0000000000..580d57158f --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sai_ex.c @@ -0,0 +1,133 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_sai_ex.c + * @author MCD Application Team + * @brief SAI Extended HAL module driver. + * This file provides firmware functions to manage the following + * functionality of the SAI Peripheral Controller: + * + Modify PDM microphone delays. + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +#if defined(SAI1) + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ +#ifdef HAL_SAI_MODULE_ENABLED + +/** @defgroup SAIEx SAIEx + * @brief SAI Extended HAL module driver + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup SAIEx_Private_Defines SAIEx Extended Private Defines + * @{ + */ +#define SAI_PDM_DELAY_MASK 0x77U +#define SAI_PDM_DELAY_OFFSET 8U +#define SAI_PDM_RIGHT_DELAY_OFFSET 4U +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @defgroup SAIEx_Exported_Functions SAIEx Extended Exported Functions + * @{ + */ + +/** @defgroup SAIEx_Exported_Functions_Group1 Peripheral Control functions + * @brief SAIEx control functions + * +@verbatim + =============================================================================== + ##### Extended features functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Modify PDM microphone delays + +@endverbatim + * @{ + */ + +/** + * @brief Configure PDM microphone delays. + * @param hsai SAI handle. + * @param pdmMicDelay Microphone delays configuration. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAIEx_ConfigPdmMicDelay(const SAI_HandleTypeDef *hsai, + const SAIEx_PdmMicDelayParamTypeDef *pdmMicDelay) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t offset; + + /* Check that SAI sub-block is SAI1 sub-block A */ + if (hsai->Instance != SAI1_Block_A) + { + status = HAL_ERROR; + } + else + { + /* Check microphone delay parameters */ + assert_param(IS_SAI_PDM_MIC_PAIRS_NUMBER(pdmMicDelay->MicPair)); + assert_param(IS_SAI_PDM_MIC_DELAY(pdmMicDelay->LeftDelay)); + assert_param(IS_SAI_PDM_MIC_DELAY(pdmMicDelay->RightDelay)); + + /* Compute offset on PDMDLY register according mic pair number */ + offset = SAI_PDM_DELAY_OFFSET * (pdmMicDelay->MicPair - 1U); + + /* Check SAI state and offset */ + if ((hsai->State != HAL_SAI_STATE_RESET) && (offset <= 24U)) + { + /* Reset current delays for specified microphone */ + SAI1->PDMDLY &= ~(SAI_PDM_DELAY_MASK << offset); + + /* Apply new microphone delays */ + SAI1->PDMDLY |= (((pdmMicDelay->RightDelay << SAI_PDM_RIGHT_DELAY_OFFSET) | pdmMicDelay->LeftDelay) << offset); + } + else + { + status = HAL_ERROR; + } + } + return status; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_SAI_MODULE_ENABLED */ +/** + * @} + */ + +#endif /* SAI1 */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sd.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sd.c new file mode 100644 index 0000000000..1ba5e096d9 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sd.c @@ -0,0 +1,4098 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_sd.c + * @author MCD Application Team + * @brief SD card HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Secure Digital (SD) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + This driver implements a high level communication layer for read and write from/to + this memory. The needed STM32 hardware resources (SDMMC and GPIO) are performed by + the user in HAL_SD_MspInit() function (MSP layer). + Basically, the MSP layer configuration should be the same as we provide in the + examples. + You can easily tailor this configuration according to hardware resources. + + [..] + This driver is a generic layered driver for SDMMC memories which uses the HAL + SDMMC driver functions to interface with SD and uSD cards devices. + It is used as follows: + + (#)Initialize the SDMMC low level resources by implementing the HAL_SD_MspInit() API: + (##) Enable the SDMMC interface clock using __HAL_RCC_SDMMC_CLK_ENABLE(); + (##) SDMMC pins configuration for SD card + (+++) Enable the clock for the SDMMC GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE(); + (+++) Configure these SDMMC pins as alternate function pull-up using HAL_GPIO_Init() + and according to your pin assignment; + (##) NVIC configuration if you need to use interrupt process (HAL_SD_ReadBlocks_IT() + and HAL_SD_WriteBlocks_IT() APIs). + (+++) Configure the SDMMC interrupt priorities using function HAL_NVIC_SetPriority(); + (+++) Enable the NVIC SDMMC IRQs using function HAL_NVIC_EnableIRQ() + (+++) SDMMC interrupts are managed using the macros __HAL_SD_ENABLE_IT() + and __HAL_SD_DISABLE_IT() inside the communication process. + (+++) SDMMC interrupts pending bits are managed using the macros __HAL_SD_GET_IT() + and __HAL_SD_CLEAR_IT() + (##) No general propose DMA Configuration is needed, an Internal DMA for SDMMC Peripheral are used. + + (#) At this stage, you can perform SD read/write/erase operations after SD card initialization + + + *** SD Card Initialization and configuration *** + ================================================ + [..] + To initialize the SD Card, use the HAL_SD_Init() function. It Initializes + SDMMC Peripheral(STM32 side) and the SD Card, and put it into StandBy State (Ready for data transfer). + This function provide the following operations: + + (#) Apply the SD Card initialization process at 400KHz and check the SD Card + type (Standard Capacity or High Capacity). You can change or adapt this + frequency by adjusting the "ClockDiv" field. + The SD Card frequency (SDMMC_CK) is computed as follows: + + SDMMC_CK = SDMMCCLK / (2 * ClockDiv) + + In initialization mode and according to the SD Card standard, + make sure that the SDMMC_CK frequency doesn't exceed 400KHz. + + This phase of initialization is done through SDMMC_Init() and + SDMMC_PowerState_ON() SDMMC low level APIs. + + (#) Initialize the SD card. The API used is HAL_SD_InitCard(). + This phase allows the card initialization and identification + and check the SD Card type (Standard Capacity or High Capacity) + The initialization flow is compatible with SD standard. + + This API (HAL_SD_InitCard()) could be used also to reinitialize the card in case + of plug-off plug-in. + + (#) Configure the SD Card Data transfer frequency. You can change or adapt this + frequency by adjusting the "ClockDiv" field. + In transfer mode and according to the SD Card standard, make sure that the + SDMMC_CK frequency doesn't exceed 25MHz and 100MHz in High-speed mode switch. + + (#) Select the corresponding SD Card according to the address read with the step 2. + + (#) Configure the SD Card in wide bus mode: 4-bits data. + + *** SD Card Read operation *** + ============================== + [..] + (+) You can read from SD card in polling mode by using function HAL_SD_ReadBlocks(). + This function support only 512-bytes block length (the block size should be + chosen as 512 bytes). + You can choose either one block read operation or multiple block read operation + by adjusting the "NumberOfBlocks" parameter. + After this, you have to ensure that the transfer is done correctly. The check is done + through HAL_SD_GetCardState() function for SD card state. + + (+) You can read from SD card in DMA mode by using function HAL_SD_ReadBlocks_DMA(). + This function support only 512-bytes block length (the block size should be + chosen as 512 bytes). + You can choose either one block read operation or multiple block read operation + by adjusting the "NumberOfBlocks" parameter. + After this, you have to ensure that the transfer is done correctly. The check is done + through HAL_SD_GetCardState() function for SD card state. + You could also check the DMA transfer process through the SD Rx interrupt event. + + (+) You can read from SD card in Interrupt mode by using function HAL_SD_ReadBlocks_IT(). + This function support only 512-bytes block length (the block size should be + chosen as 512 bytes). + You can choose either one block read operation or multiple block read operation + by adjusting the "NumberOfBlocks" parameter. + After this, you have to ensure that the transfer is done correctly. The check is done + through HAL_SD_GetCardState() function for SD card state. + You could also check the IT transfer process through the SD Rx interrupt event. + + *** SD Card Write operation *** + =============================== + [..] + (+) You can write to SD card in polling mode by using function HAL_SD_WriteBlocks(). + This function support only 512-bytes block length (the block size should be + chosen as 512 bytes). + You can choose either one block read operation or multiple block read operation + by adjusting the "NumberOfBlocks" parameter. + After this, you have to ensure that the transfer is done correctly. The check is done + through HAL_SD_GetCardState() function for SD card state. + + (+) You can write to SD card in DMA mode by using function HAL_SD_WriteBlocks_DMA(). + This function support only 512-bytes block length (the block size should be + chosen as 512 bytes). + You can choose either one block read operation or multiple block read operation + by adjusting the "NumberOfBlocks" parameter. + After this, you have to ensure that the transfer is done correctly. The check is done + through HAL_SD_GetCardState() function for SD card state. + You could also check the DMA transfer process through the SD Tx interrupt event. + + (+) You can write to SD card in Interrupt mode by using function HAL_SD_WriteBlocks_IT(). + This function support only 512-bytes block length (the block size should be + chosen as 512 bytes). + You can choose either one block read operation or multiple block read operation + by adjusting the "NumberOfBlocks" parameter. + After this, you have to ensure that the transfer is done correctly. The check is done + through HAL_SD_GetCardState() function for SD card state. + You could also check the IT transfer process through the SD Tx interrupt event. + + *** SD card status *** + ====================== + [..] + (+) The SD Status contains status bits that are related to the SD Memory + Card proprietary features. To get SD card status use the HAL_SD_GetCardStatus(). + + *** SD card information *** + =========================== + [..] + (+) To get SD card information, you can use the function HAL_SD_GetCardInfo(). + It returns useful information about the SD card such as block size, card type, + block number ... + + *** SD card CSD register *** + ============================ + (+) The HAL_SD_GetCardCSD() API allows to get the parameters of the CSD register. + Some of the CSD parameters are useful for card initialization and identification. + + *** SD card CID register *** + ============================ + (+) The HAL_SD_GetCardCID() API allows to get the parameters of the CID register. + Some of the CSD parameters are useful for card initialization and identification. + + *** SD HAL driver macros list *** + ================================== + [..] + Below the list of most used macros in SD HAL driver. + + (+) __HAL_SD_ENABLE_IT: Enable the SD device interrupt + (+) __HAL_SD_DISABLE_IT: Disable the SD device interrupt + (+) __HAL_SD_GET_FLAG:Check whether the specified SD flag is set or not + (+) __HAL_SD_CLEAR_FLAG: Clear the SD's pending flags + + (@) You can refer to the SD HAL driver header file for more useful macros + + *** Callback registration *** + ============================================= + [..] + The compilation define USE_HAL_SD_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + + Use Functions HAL_SD_RegisterCallback() to register a user callback, + it allows to register following callbacks: + (+) TxCpltCallback : callback when a transmission transfer is completed. + (+) RxCpltCallback : callback when a reception transfer is completed. + (+) ErrorCallback : callback when error occurs. + (+) AbortCpltCallback : callback when abort is completed. + (+) Read_DMADblBuf0CpltCallback : callback when the DMA reception of first buffer is completed. + (+) Read_DMADblBuf1CpltCallback : callback when the DMA reception of second buffer is completed. + (+) Write_DMADblBuf0CpltCallback : callback when the DMA transmission of first buffer is completed. + (+) Write_DMADblBuf1CpltCallback : callback when the DMA transmission of second buffer is completed. + (+) MspInitCallback : SD MspInit. + (+) MspDeInitCallback : SD MspDeInit. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + For specific callbacks TransceiverCallback use dedicated register callbacks: + respectively HAL_SD_RegisterTransceiverCallback(). + + Use function HAL_SD_UnRegisterCallback() to reset a callback to the default + weak (overridden) function. It allows to reset following callbacks: + (+) TxCpltCallback : callback when a transmission transfer is completed. + (+) RxCpltCallback : callback when a reception transfer is completed. + (+) ErrorCallback : callback when error occurs. + (+) AbortCpltCallback : callback when abort is completed. + (+) Read_DMALnkLstBufCpltCallback : callback when the DMA reception of linked list node buffer is completed. + (+) Write_DMALnkLstBufCpltCallback : callback when the DMA transmission of linked list node buffer is completed. + (+) MspInitCallback : SD MspInit. + (+) MspDeInitCallback : SD MspDeInit. + This function) takes as parameters the HAL peripheral handle and the Callback ID. + For specific callbacks TransceiverCallback use dedicated unregister callbacks: + respectively HAL_SD_UnRegisterTransceiverCallback(). + + By default, after the HAL_SD_Init and if the state is HAL_SD_STATE_RESET + all callbacks are reset to the corresponding legacy weak (overridden) functions. + Exception done for MspInit and MspDeInit callbacks that are respectively + reset to the legacy weak (overridden) functions in the HAL_SD_Init + and HAL_SD_DeInit only when these callbacks are null (not registered beforehand). + If not, MspInit or MspDeInit are not null, the HAL_SD_Init and HAL_SD_DeInit + keep and use the user MspInit/MspDeInit callbacks (registered beforehand) + + Callbacks can be registered/unregistered in READY state only. + Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered + in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used + during the Init/DeInit. + In that case first register the MspInit/MspDeInit user callbacks + using HAL_SD_RegisterCallback before calling HAL_SD_DeInit + or HAL_SD_Init function. + + When The compilation define USE_HAL_SD_REGISTER_CALLBACKS is set to 0 or + not defined, the callback registering feature is not available + and weak (overridden) callbacks are used. + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup SD + * @{ + */ + +#if defined (SDMMC1) || defined (SDMMC2) +#ifdef HAL_SD_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup SD_Private_Defines + * @{ + */ +/* Frequencies used in the driver for clock divider calculation */ +#define SD_INIT_FREQ 400000U /* Initialization phase : 400 kHz max */ +#define SD_NORMAL_SPEED_FREQ 25000000U /* Normal speed phase : 25 MHz max */ +#define SD_HIGH_SPEED_FREQ 50000000U /* High speed phase : 50 MHz max */ +/* Private macro -------------------------------------------------------------*/ +#if defined (DLYB_SDMMC1) && defined (DLYB_SDMMC2) +#define SD_GET_DLYB_INSTANCE(SDMMC_INSTANCE) (((SDMMC_INSTANCE) == SDMMC1)? \ + DLYB_SDMMC1 : DLYB_SDMMC2 ) +#elif defined (DLYB_SDMMC1) +#define SD_GET_DLYB_INSTANCE(SDMMC_INSTANCE) ( DLYB_SDMMC1 ) +#endif /* (DLYB_SDMMC1) && defined (DLYB_SDMMC2) */ + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/** @defgroup SD_Private_Functions SD Private Functions + * @{ + */ +static uint32_t SD_InitCard(SD_HandleTypeDef *hsd); +static uint32_t SD_PowerON(SD_HandleTypeDef *hsd); +static uint32_t SD_SendSDStatus(SD_HandleTypeDef *hsd, uint32_t *pSDstatus); +static uint32_t SD_SendStatus(SD_HandleTypeDef *hsd, uint32_t *pCardStatus); +static uint32_t SD_WideBus_Enable(SD_HandleTypeDef *hsd); +static uint32_t SD_WideBus_Disable(SD_HandleTypeDef *hsd); +static uint32_t SD_FindSCR(SD_HandleTypeDef *hsd, uint32_t *pSCR); +static void SD_PowerOFF(SD_HandleTypeDef *hsd); +static void SD_Write_IT(SD_HandleTypeDef *hsd); +static void SD_Read_IT(SD_HandleTypeDef *hsd); +static uint32_t SD_SwitchSpeed(SD_HandleTypeDef *hsd, uint32_t SwitchSpeedMode); +#if (USE_SD_TRANSCEIVER != 0U) +static uint32_t SD_UltraHighSpeed(SD_HandleTypeDef *hsd, uint32_t UltraHighSpeedMode); +static uint32_t SD_DDR_Mode(SD_HandleTypeDef *hsd); +#endif /* USE_SD_TRANSCEIVER */ +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup SD_Exported_Functions + * @{ + */ + +/** @addtogroup SD_Exported_Functions_Group1 + * @brief Initialization and de-initialization functions + * +@verbatim + ============================================================================== + ##### Initialization and de-initialization functions ##### + ============================================================================== + [..] + This section provides functions allowing to initialize/de-initialize the SD + card device to be ready for use. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the SD according to the specified parameters in the + SD_HandleTypeDef and create the associated handle. + * @param hsd: Pointer to the SD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SD_Init(SD_HandleTypeDef *hsd) +{ + HAL_SD_CardStatusTypeDef CardStatus; + uint32_t speedgrade; + uint32_t unitsize; + uint32_t tickstart; + + /* Check the SD handle allocation */ + if (hsd == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_SDMMC_ALL_INSTANCE(hsd->Instance)); + assert_param(IS_SDMMC_CLOCK_EDGE(hsd->Init.ClockEdge)); + assert_param(IS_SDMMC_CLOCK_POWER_SAVE(hsd->Init.ClockPowerSave)); + assert_param(IS_SDMMC_BUS_WIDE(hsd->Init.BusWide)); + assert_param(IS_SDMMC_HARDWARE_FLOW_CONTROL(hsd->Init.HardwareFlowControl)); + assert_param(IS_SDMMC_CLKDIV(hsd->Init.ClockDiv)); + + if (hsd->State == HAL_SD_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hsd->Lock = HAL_UNLOCKED; + +#if (USE_SD_TRANSCEIVER != 0U) + /* Force SDMMC_TRANSCEIVER_PRESENT for Legacy usage */ + if (hsd->Init.TranceiverPresent == SDMMC_TRANSCEIVER_UNKNOWN) + { + hsd->Init.TranceiverPresent = SDMMC_TRANSCEIVER_PRESENT; + } +#endif /*USE_SD_TRANSCEIVER */ +#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U) + /* Reset Callback pointers in HAL_SD_STATE_RESET only */ + hsd->TxCpltCallback = HAL_SD_TxCpltCallback; + hsd->RxCpltCallback = HAL_SD_RxCpltCallback; + hsd->ErrorCallback = HAL_SD_ErrorCallback; + hsd->AbortCpltCallback = HAL_SD_AbortCallback; + hsd->Read_DMALnkLstBufCpltCallback = HAL_SDEx_Read_DMALnkLstBufCpltCallback; + hsd->Write_DMALnkLstBufCpltCallback = HAL_SDEx_Write_DMALnkLstBufCpltCallback; +#if (USE_SD_TRANSCEIVER != 0U) + if (hsd->Init.TranceiverPresent == SDMMC_TRANSCEIVER_PRESENT) + { + hsd->DriveTransceiver_1_8V_Callback = HAL_SD_DriveTransceiver_1_8V_Callback; + } +#endif /* USE_SD_TRANSCEIVER */ + + if (hsd->MspInitCallback == NULL) + { + hsd->MspInitCallback = HAL_SD_MspInit; + } + + /* Init the low level hardware */ + hsd->MspInitCallback(hsd); +#else + /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ + HAL_SD_MspInit(hsd); +#endif /* USE_HAL_SD_REGISTER_CALLBACKS */ + } + + hsd->State = HAL_SD_STATE_PROGRAMMING; + + /* Initialize the Card parameters */ + if (HAL_SD_InitCard(hsd) != HAL_OK) + { + return HAL_ERROR; + } + + if (HAL_SD_GetCardStatus(hsd, &CardStatus) != HAL_OK) + { + return HAL_ERROR; + } + /* Get Initial Card Speed from Card Status*/ + speedgrade = CardStatus.UhsSpeedGrade; + unitsize = CardStatus.UhsAllocationUnitSize; + if ((hsd->SdCard.CardType == CARD_SDHC_SDXC) && ((speedgrade != 0U) || (unitsize != 0U))) + { + hsd->SdCard.CardSpeed = CARD_ULTRA_HIGH_SPEED; + } + else + { + if (hsd->SdCard.CardType == CARD_SDHC_SDXC) + { + hsd->SdCard.CardSpeed = CARD_HIGH_SPEED; + } + else + { + hsd->SdCard.CardSpeed = CARD_NORMAL_SPEED; + } + + } + /* Configure the bus wide */ + if (HAL_SD_ConfigWideBusOperation(hsd, hsd->Init.BusWide) != HAL_OK) + { + return HAL_ERROR; + } + + /* Verify that SD card is ready to use after Initialization */ + tickstart = HAL_GetTick(); + while ((HAL_SD_GetCardState(hsd) != HAL_SD_CARD_TRANSFER)) + { + if ((HAL_GetTick() - tickstart) >= SDMMC_SWDATATIMEOUT) + { + hsd->ErrorCode = HAL_SD_ERROR_TIMEOUT; + hsd->State = HAL_SD_STATE_READY; + return HAL_TIMEOUT; + } + } + + /* Initialize the error code */ + hsd->ErrorCode = HAL_SD_ERROR_NONE; + + /* Initialize the SD operation */ + hsd->Context = SD_CONTEXT_NONE; + + /* Initialize the SD state */ + hsd->State = HAL_SD_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Initializes the SD Card. + * @param hsd: Pointer to SD handle + * @note This function initializes the SD card. It could be used when a card + re-initialization is needed. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SD_InitCard(SD_HandleTypeDef *hsd) +{ + uint32_t errorstate; + SD_InitTypeDef Init; + uint32_t sdmmc_clk = 0U; + + /* Default SDMMC peripheral configuration for SD card initialization */ + Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING; + Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE; + Init.BusWide = SDMMC_BUS_WIDE_1B; + Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE; + + /* Init Clock should be less or equal to 400Khz*/ + if (hsd->Instance == SDMMC1) + { + sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC1); + } +#if defined(SDMMC2) + if (hsd->Instance == SDMMC2) + { + sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC2); + } +#endif /* SDMMC2 */ + if (sdmmc_clk == 0U) + { + hsd->State = HAL_SD_STATE_READY; + hsd->ErrorCode = SDMMC_ERROR_INVALID_PARAMETER; + return HAL_ERROR; + } + Init.ClockDiv = sdmmc_clk / (2U * SD_INIT_FREQ); + +#if (USE_SD_TRANSCEIVER != 0U) + Init.TranceiverPresent = hsd->Init.TranceiverPresent; + + if (hsd->Init.TranceiverPresent == SDMMC_TRANSCEIVER_PRESENT) + { + /* Set Transceiver polarity */ + hsd->Instance->POWER |= SDMMC_POWER_DIRPOL; + } +#elif defined (USE_SD_DIRPOL) + /* Set Transceiver polarity */ + hsd->Instance->POWER |= SDMMC_POWER_DIRPOL; +#endif /* USE_SD_TRANSCEIVER */ + + /* Initialize SDMMC peripheral interface with default configuration */ + (void)SDMMC_Init(hsd->Instance, Init); + + /* Set Power State to ON */ + (void)SDMMC_PowerState_ON(hsd->Instance); + + /* wait 74 Cycles: required power up waiting time before starting + the SD initialization sequence */ + if (Init.ClockDiv != 0U) + { + sdmmc_clk = sdmmc_clk / (2U * Init.ClockDiv); + } + + if (sdmmc_clk != 0U) + { + HAL_Delay(1U + (74U * 1000U / (sdmmc_clk))); + } + + /* Identify card operating voltage */ + errorstate = SD_PowerON(hsd); + if (errorstate != HAL_SD_ERROR_NONE) + { + hsd->State = HAL_SD_STATE_READY; + hsd->ErrorCode |= errorstate; + return HAL_ERROR; + } + + /* Card initialization */ + errorstate = SD_InitCard(hsd); + if (errorstate != HAL_SD_ERROR_NONE) + { + hsd->State = HAL_SD_STATE_READY; + hsd->ErrorCode |= errorstate; + return HAL_ERROR; + } + + /* Set Block Size for Card */ + errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE); + if (errorstate != HAL_SD_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + hsd->ErrorCode |= errorstate; + hsd->State = HAL_SD_STATE_READY; + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief De-Initializes the SD card. + * @param hsd: Pointer to SD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SD_DeInit(SD_HandleTypeDef *hsd) +{ + /* Check the SD handle allocation */ + if (hsd == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_SDMMC_ALL_INSTANCE(hsd->Instance)); + + hsd->State = HAL_SD_STATE_BUSY; + +#if (USE_SD_TRANSCEIVER != 0U) + /* Deactivate the 1.8V Mode */ + if (hsd->Init.TranceiverPresent == SDMMC_TRANSCEIVER_PRESENT) + { +#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U) + if (hsd->DriveTransceiver_1_8V_Callback == NULL) + { + hsd->DriveTransceiver_1_8V_Callback = HAL_SD_DriveTransceiver_1_8V_Callback; + } + hsd->DriveTransceiver_1_8V_Callback(RESET); +#else + HAL_SD_DriveTransceiver_1_8V_Callback(RESET); +#endif /* USE_HAL_SD_REGISTER_CALLBACKS */ + } +#endif /* USE_SD_TRANSCEIVER */ + + /* Set SD power state to off */ + SD_PowerOFF(hsd); + +#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U) + if (hsd->MspDeInitCallback == NULL) + { + hsd->MspDeInitCallback = HAL_SD_MspDeInit; + } + + /* DeInit the low level hardware */ + hsd->MspDeInitCallback(hsd); +#else + /* De-Initialize the MSP layer */ + HAL_SD_MspDeInit(hsd); +#endif /* USE_HAL_SD_REGISTER_CALLBACKS */ + + hsd->ErrorCode = HAL_SD_ERROR_NONE; + hsd->State = HAL_SD_STATE_RESET; + + return HAL_OK; +} + + +/** + * @brief Initializes the SD MSP. + * @param hsd: Pointer to SD handle + * @retval None + */ +__weak void HAL_SD_MspInit(SD_HandleTypeDef *hsd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SD_MspInit could be implemented in the user file + */ +} + +/** + * @brief De-Initialize SD MSP. + * @param hsd: Pointer to SD handle + * @retval None + */ +__weak void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SD_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @addtogroup SD_Exported_Functions_Group2 + * @brief Data transfer functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to manage the data + transfer from/to SD card. + +@endverbatim + * @{ + */ + +/** + * @brief Reads block(s) from a specified address in a card. The Data transfer + * is managed by polling mode. + * @note This API should be followed by a check on the card state through + * HAL_SD_GetCardState(). + * @param hsd: Pointer to SD handle + * @param pData: pointer to the buffer that will contain the received data + * @param BlockAdd: Block Address from where data is to be read + * @param NumberOfBlocks: Number of SD blocks to read + * @param Timeout: Specify timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, + uint32_t Timeout) +{ + SDMMC_DataInitTypeDef config; + uint32_t errorstate; + uint32_t tickstart = HAL_GetTick(); + uint32_t count; + uint32_t data; + uint32_t dataremaining; + uint32_t add = BlockAdd; + uint8_t *tempbuff = pData; + + if (NULL == pData) + { + hsd->ErrorCode |= HAL_SD_ERROR_PARAM; + return HAL_ERROR; + } + + if (hsd->State == HAL_SD_STATE_READY) + { + hsd->ErrorCode = HAL_SD_ERROR_NONE; + + if ((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) + { + hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE; + return HAL_ERROR; + } + + hsd->State = HAL_SD_STATE_BUSY; + + /* Initialize data control register */ + hsd->Instance->DCTRL = 0U; + + if (hsd->SdCard.CardType != CARD_SDHC_SDXC) + { + add *= BLOCKSIZE; + } + + /* Configure the SD DPSM (Data Path State Machine) */ + config.DataTimeOut = SDMMC_DATATIMEOUT; + config.DataLength = NumberOfBlocks * BLOCKSIZE; + config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; + config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + config.DPSM = SDMMC_DPSM_DISABLE; + (void)SDMMC_ConfigData(hsd->Instance, &config); + __SDMMC_CMDTRANS_ENABLE(hsd->Instance); + + /* Read block(s) in polling mode */ + if (NumberOfBlocks > 1U) + { + hsd->Context = SD_CONTEXT_READ_MULTIPLE_BLOCK; + + /* Read Multi Block command */ + errorstate = SDMMC_CmdReadMultiBlock(hsd->Instance, add); + } + else + { + hsd->Context = SD_CONTEXT_READ_SINGLE_BLOCK; + + /* Read Single Block command */ + errorstate = SDMMC_CmdReadSingleBlock(hsd->Instance, add); + } + if (errorstate != HAL_SD_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + hsd->ErrorCode |= errorstate; + hsd->State = HAL_SD_STATE_READY; + hsd->Context = SD_CONTEXT_NONE; + return HAL_ERROR; + } + + /* Poll on SDMMC flags */ + dataremaining = config.DataLength; + while (!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND)) + { + if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= SDMMC_FIFO_SIZE)) + { + /* Read data from SDMMC Rx FIFO */ + for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++) + { + data = SDMMC_ReadFIFO(hsd->Instance); + *tempbuff = (uint8_t)(data & 0xFFU); + tempbuff++; + *tempbuff = (uint8_t)((data >> 8U) & 0xFFU); + tempbuff++; + *tempbuff = (uint8_t)((data >> 16U) & 0xFFU); + tempbuff++; + *tempbuff = (uint8_t)((data >> 24U) & 0xFFU); + tempbuff++; + } + dataremaining -= SDMMC_FIFO_SIZE; + } + + if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U)) + { + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + hsd->ErrorCode |= HAL_SD_ERROR_TIMEOUT; + hsd->State = HAL_SD_STATE_READY; + hsd->Context = SD_CONTEXT_NONE; + return HAL_TIMEOUT; + } + } + __SDMMC_CMDTRANS_DISABLE(hsd->Instance); + + /* Send stop transmission command in case of multiblock read */ + if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U)) + { + if (hsd->SdCard.CardType != CARD_SECURED) + { + /* Send stop transmission command */ + errorstate = SDMMC_CmdStopTransfer(hsd->Instance); + if (errorstate != HAL_SD_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + hsd->ErrorCode |= errorstate; + hsd->State = HAL_SD_STATE_READY; + hsd->Context = SD_CONTEXT_NONE; + return HAL_ERROR; + } + } + } + + /* Get error state */ + if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT)) + { + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + hsd->ErrorCode |= HAL_SD_ERROR_DATA_TIMEOUT; + hsd->State = HAL_SD_STATE_READY; + hsd->Context = SD_CONTEXT_NONE; + return HAL_ERROR; + } + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL)) + { + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + hsd->ErrorCode |= HAL_SD_ERROR_DATA_CRC_FAIL; + hsd->State = HAL_SD_STATE_READY; + hsd->Context = SD_CONTEXT_NONE; + return HAL_ERROR; + } + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR)) + { + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + hsd->ErrorCode |= HAL_SD_ERROR_RX_OVERRUN; + hsd->State = HAL_SD_STATE_READY; + hsd->Context = SD_CONTEXT_NONE; + return HAL_ERROR; + } + else + { + /* Nothing to do */ + } + + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); + + hsd->State = HAL_SD_STATE_READY; + + return HAL_OK; + } + else + { + hsd->ErrorCode |= HAL_SD_ERROR_BUSY; + return HAL_ERROR; + } +} + +/** + * @brief Allows to write block(s) to a specified address in a card. The Data + * transfer is managed by polling mode. + * @note This API should be followed by a check on the card state through + * HAL_SD_GetCardState(). + * @param hsd: Pointer to SD handle + * @param pData: pointer to the buffer that will contain the data to transmit + * @param BlockAdd: Block Address where data will be written + * @param NumberOfBlocks: Number of SD blocks to write + * @param Timeout: Specify timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, const uint8_t *pData, uint32_t BlockAdd, + uint32_t NumberOfBlocks, uint32_t Timeout) +{ + SDMMC_DataInitTypeDef config; + uint32_t errorstate; + uint32_t tickstart = HAL_GetTick(); + uint32_t count; + uint32_t data; + uint32_t dataremaining; + uint32_t add = BlockAdd; + const uint8_t *tempbuff = pData; + + if (NULL == pData) + { + hsd->ErrorCode |= HAL_SD_ERROR_PARAM; + return HAL_ERROR; + } + + if (hsd->State == HAL_SD_STATE_READY) + { + hsd->ErrorCode = HAL_SD_ERROR_NONE; + + if ((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) + { + hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE; + return HAL_ERROR; + } + + hsd->State = HAL_SD_STATE_BUSY; + + /* Initialize data control register */ + hsd->Instance->DCTRL = 0U; + + if (hsd->SdCard.CardType != CARD_SDHC_SDXC) + { + add *= BLOCKSIZE; + } + + /* Configure the SD DPSM (Data Path State Machine) */ + config.DataTimeOut = SDMMC_DATATIMEOUT; + config.DataLength = NumberOfBlocks * BLOCKSIZE; + config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; + config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD; + config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + config.DPSM = SDMMC_DPSM_DISABLE; + (void)SDMMC_ConfigData(hsd->Instance, &config); + __SDMMC_CMDTRANS_ENABLE(hsd->Instance); + + /* Write Blocks in Polling mode */ + if (NumberOfBlocks > 1U) + { + hsd->Context = SD_CONTEXT_WRITE_MULTIPLE_BLOCK; + + /* Write Multi Block command */ + errorstate = SDMMC_CmdWriteMultiBlock(hsd->Instance, add); + } + else + { + hsd->Context = SD_CONTEXT_WRITE_SINGLE_BLOCK; + + /* Write Single Block command */ + errorstate = SDMMC_CmdWriteSingleBlock(hsd->Instance, add); + } + if (errorstate != HAL_SD_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + hsd->ErrorCode |= errorstate; + hsd->State = HAL_SD_STATE_READY; + hsd->Context = SD_CONTEXT_NONE; + return HAL_ERROR; + } + + /* Write block(s) in polling mode */ + dataremaining = config.DataLength; + while (!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | + SDMMC_FLAG_DATAEND)) + { + if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= SDMMC_FIFO_SIZE)) + { + /* Write data to SDMMC Tx FIFO */ + for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++) + { + data = (uint32_t)(*tempbuff); + tempbuff++; + data |= ((uint32_t)(*tempbuff) << 8U); + tempbuff++; + data |= ((uint32_t)(*tempbuff) << 16U); + tempbuff++; + data |= ((uint32_t)(*tempbuff) << 24U); + tempbuff++; + (void)SDMMC_WriteFIFO(hsd->Instance, &data); + } + dataremaining -= SDMMC_FIFO_SIZE; + } + + if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U)) + { + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + hsd->ErrorCode |= errorstate; + hsd->State = HAL_SD_STATE_READY; + hsd->Context = SD_CONTEXT_NONE; + return HAL_TIMEOUT; + } + } + __SDMMC_CMDTRANS_DISABLE(hsd->Instance); + + /* Send stop transmission command in case of multiblock write */ + if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U)) + { + if (hsd->SdCard.CardType != CARD_SECURED) + { + /* Send stop transmission command */ + errorstate = SDMMC_CmdStopTransfer(hsd->Instance); + if (errorstate != HAL_SD_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + hsd->ErrorCode |= errorstate; + hsd->State = HAL_SD_STATE_READY; + hsd->Context = SD_CONTEXT_NONE; + return HAL_ERROR; + } + } + } + + /* Get error state */ + if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT)) + { + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + hsd->ErrorCode |= HAL_SD_ERROR_DATA_TIMEOUT; + hsd->State = HAL_SD_STATE_READY; + hsd->Context = SD_CONTEXT_NONE; + return HAL_ERROR; + } + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL)) + { + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + hsd->ErrorCode |= HAL_SD_ERROR_DATA_CRC_FAIL; + hsd->State = HAL_SD_STATE_READY; + hsd->Context = SD_CONTEXT_NONE; + return HAL_ERROR; + } + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_TXUNDERR)) + { + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + hsd->ErrorCode |= HAL_SD_ERROR_TX_UNDERRUN; + hsd->State = HAL_SD_STATE_READY; + hsd->Context = SD_CONTEXT_NONE; + return HAL_ERROR; + } + else + { + /* Nothing to do */ + } + + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); + + hsd->State = HAL_SD_STATE_READY; + + return HAL_OK; + } + else + { + hsd->ErrorCode |= HAL_SD_ERROR_BUSY; + return HAL_ERROR; + } +} + +/** + * @brief Reads block(s) from a specified address in a card. The Data transfer + * is managed in interrupt mode. + * @note This API should be followed by a check on the card state through + * HAL_SD_GetCardState(). + * @note You could also check the IT transfer process through the SD Rx + * interrupt event. + * @param hsd: Pointer to SD handle + * @param pData: Pointer to the buffer that will contain the received data + * @param BlockAdd: Block Address from where data is to be read + * @param NumberOfBlocks: Number of blocks to read. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SD_ReadBlocks_IT(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, + uint32_t NumberOfBlocks) +{ + SDMMC_DataInitTypeDef config; + uint32_t errorstate; + uint32_t add = BlockAdd; + + if (NULL == pData) + { + hsd->ErrorCode |= HAL_SD_ERROR_PARAM; + return HAL_ERROR; + } + + if (hsd->State == HAL_SD_STATE_READY) + { + hsd->ErrorCode = HAL_SD_ERROR_NONE; + + if ((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) + { + hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE; + return HAL_ERROR; + } + + hsd->State = HAL_SD_STATE_BUSY; + + /* Initialize data control register */ + hsd->Instance->DCTRL = 0U; + + hsd->pRxBuffPtr = pData; + hsd->RxXferSize = BLOCKSIZE * NumberOfBlocks; + + if (hsd->SdCard.CardType != CARD_SDHC_SDXC) + { + add *= BLOCKSIZE; + } + + /* Configure the SD DPSM (Data Path State Machine) */ + config.DataTimeOut = SDMMC_DATATIMEOUT; + config.DataLength = BLOCKSIZE * NumberOfBlocks; + config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; + config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + config.DPSM = SDMMC_DPSM_DISABLE; + (void)SDMMC_ConfigData(hsd->Instance, &config); + __SDMMC_CMDTRANS_ENABLE(hsd->Instance); + + /* Read Blocks in IT mode */ + if (NumberOfBlocks > 1U) + { + hsd->Context = (SD_CONTEXT_READ_MULTIPLE_BLOCK | SD_CONTEXT_IT); + + /* Read Multi Block command */ + errorstate = SDMMC_CmdReadMultiBlock(hsd->Instance, add); + } + else + { + hsd->Context = (SD_CONTEXT_READ_SINGLE_BLOCK | SD_CONTEXT_IT); + + /* Read Single Block command */ + errorstate = SDMMC_CmdReadSingleBlock(hsd->Instance, add); + } + if (errorstate != HAL_SD_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + hsd->ErrorCode |= errorstate; + hsd->State = HAL_SD_STATE_READY; + hsd->Context = SD_CONTEXT_NONE; + return HAL_ERROR; + } + + __HAL_SD_ENABLE_IT(hsd, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND | + SDMMC_FLAG_RXFIFOHF)); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Writes block(s) to a specified address in a card. The Data transfer + * is managed in interrupt mode. + * @note This API should be followed by a check on the card state through + * HAL_SD_GetCardState(). + * @note You could also check the IT transfer process through the SD Tx + * interrupt event. + * @param hsd: Pointer to SD handle + * @param pData: Pointer to the buffer that will contain the data to transmit + * @param BlockAdd: Block Address where data will be written + * @param NumberOfBlocks: Number of blocks to write + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SD_WriteBlocks_IT(SD_HandleTypeDef *hsd, const uint8_t *pData, uint32_t BlockAdd, + uint32_t NumberOfBlocks) +{ + SDMMC_DataInitTypeDef config; + uint32_t errorstate; + uint32_t add = BlockAdd; + + if (NULL == pData) + { + hsd->ErrorCode |= HAL_SD_ERROR_PARAM; + return HAL_ERROR; + } + + if (hsd->State == HAL_SD_STATE_READY) + { + hsd->ErrorCode = HAL_SD_ERROR_NONE; + + if ((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) + { + hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE; + return HAL_ERROR; + } + + hsd->State = HAL_SD_STATE_BUSY; + + /* Initialize data control register */ + hsd->Instance->DCTRL = 0U; + + hsd->pTxBuffPtr = pData; + hsd->TxXferSize = BLOCKSIZE * NumberOfBlocks; + + if (hsd->SdCard.CardType != CARD_SDHC_SDXC) + { + add *= BLOCKSIZE; + } + + /* Configure the SD DPSM (Data Path State Machine) */ + config.DataTimeOut = SDMMC_DATATIMEOUT; + config.DataLength = BLOCKSIZE * NumberOfBlocks; + config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; + config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD; + config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + config.DPSM = SDMMC_DPSM_DISABLE; + (void)SDMMC_ConfigData(hsd->Instance, &config); + + __SDMMC_CMDTRANS_ENABLE(hsd->Instance); + + /* Write Blocks in Polling mode */ + if (NumberOfBlocks > 1U) + { + hsd->Context = (SD_CONTEXT_WRITE_MULTIPLE_BLOCK | SD_CONTEXT_IT); + + /* Write Multi Block command */ + errorstate = SDMMC_CmdWriteMultiBlock(hsd->Instance, add); + } + else + { + hsd->Context = (SD_CONTEXT_WRITE_SINGLE_BLOCK | SD_CONTEXT_IT); + + /* Write Single Block command */ + errorstate = SDMMC_CmdWriteSingleBlock(hsd->Instance, add); + } + if (errorstate != HAL_SD_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + hsd->ErrorCode |= errorstate; + hsd->State = HAL_SD_STATE_READY; + hsd->Context = SD_CONTEXT_NONE; + return HAL_ERROR; + } + + /* Enable transfer interrupts */ + __HAL_SD_ENABLE_IT(hsd, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND | + SDMMC_FLAG_TXFIFOHE)); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Reads block(s) from a specified address in a card. The Data transfer + * is managed by DMA mode. + * @note This API should be followed by a check on the card state through + * HAL_SD_GetCardState(). + * @note You could also check the DMA transfer process through the SD Rx + * interrupt event. + * @param hsd: Pointer SD handle + * @param pData: Pointer to the buffer that will contain the received data + * @param BlockAdd: Block Address from where data is to be read + * @param NumberOfBlocks: Number of blocks to read. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, + uint32_t NumberOfBlocks) +{ + SDMMC_DataInitTypeDef config; + uint32_t errorstate; + uint32_t add = BlockAdd; + + if (NULL == pData) + { + hsd->ErrorCode |= HAL_SD_ERROR_PARAM; + return HAL_ERROR; + } + + if (hsd->State == HAL_SD_STATE_READY) + { + hsd->ErrorCode = HAL_SD_ERROR_NONE; + + if ((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) + { + hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE; + return HAL_ERROR; + } + + hsd->State = HAL_SD_STATE_BUSY; + + /* Initialize data control register */ + hsd->Instance->DCTRL = 0U; + + hsd->pRxBuffPtr = pData; + hsd->RxXferSize = BLOCKSIZE * NumberOfBlocks; + + if (hsd->SdCard.CardType != CARD_SDHC_SDXC) + { + add *= BLOCKSIZE; + } + + /* Configure the SD DPSM (Data Path State Machine) */ + config.DataTimeOut = SDMMC_DATATIMEOUT; + config.DataLength = BLOCKSIZE * NumberOfBlocks; + config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; + config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + config.DPSM = SDMMC_DPSM_DISABLE; + (void)SDMMC_ConfigData(hsd->Instance, &config); + + __SDMMC_CMDTRANS_ENABLE(hsd->Instance); + hsd->Instance->IDMABASER = (uint32_t) pData ; + hsd->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_SINGLE_BUFF; + + /* Read Blocks in DMA mode */ + if (NumberOfBlocks > 1U) + { + hsd->Context = (SD_CONTEXT_READ_MULTIPLE_BLOCK | SD_CONTEXT_DMA); + + /* Read Multi Block command */ + errorstate = SDMMC_CmdReadMultiBlock(hsd->Instance, add); + } + else + { + hsd->Context = (SD_CONTEXT_READ_SINGLE_BLOCK | SD_CONTEXT_DMA); + + /* Read Single Block command */ + errorstate = SDMMC_CmdReadSingleBlock(hsd->Instance, add); + } + if (errorstate != HAL_SD_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + hsd->ErrorCode |= errorstate; + hsd->State = HAL_SD_STATE_READY; + hsd->Context = SD_CONTEXT_NONE; + return HAL_ERROR; + } + + /* Enable transfer interrupts */ + __HAL_SD_ENABLE_IT(hsd, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND)); + + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Writes block(s) to a specified address in a card. The Data transfer + * is managed by DMA mode. + * @note This API should be followed by a check on the card state through + * HAL_SD_GetCardState(). + * @note You could also check the DMA transfer process through the SD Tx + * interrupt event. + * @param hsd: Pointer to SD handle + * @param pData: Pointer to the buffer that will contain the data to transmit + * @param BlockAdd: Block Address where data will be written + * @param NumberOfBlocks: Number of blocks to write + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, const uint8_t *pData, uint32_t BlockAdd, + uint32_t NumberOfBlocks) +{ + SDMMC_DataInitTypeDef config; + uint32_t errorstate; + uint32_t add = BlockAdd; + + if (NULL == pData) + { + hsd->ErrorCode |= HAL_SD_ERROR_PARAM; + return HAL_ERROR; + } + + if (hsd->State == HAL_SD_STATE_READY) + { + hsd->ErrorCode = HAL_SD_ERROR_NONE; + + if ((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) + { + hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE; + return HAL_ERROR; + } + + hsd->State = HAL_SD_STATE_BUSY; + + /* Initialize data control register */ + hsd->Instance->DCTRL = 0U; + + hsd->pTxBuffPtr = pData; + hsd->TxXferSize = BLOCKSIZE * NumberOfBlocks; + + if (hsd->SdCard.CardType != CARD_SDHC_SDXC) + { + add *= BLOCKSIZE; + } + + /* Configure the SD DPSM (Data Path State Machine) */ + config.DataTimeOut = SDMMC_DATATIMEOUT; + config.DataLength = BLOCKSIZE * NumberOfBlocks; + config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; + config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD; + config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + config.DPSM = SDMMC_DPSM_DISABLE; + (void)SDMMC_ConfigData(hsd->Instance, &config); + + + __SDMMC_CMDTRANS_ENABLE(hsd->Instance); + + hsd->Instance->IDMABASER = (uint32_t) pData ; + hsd->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_SINGLE_BUFF; + + /* Write Blocks in Polling mode */ + if (NumberOfBlocks > 1U) + { + hsd->Context = (SD_CONTEXT_WRITE_MULTIPLE_BLOCK | SD_CONTEXT_DMA); + + /* Write Multi Block command */ + errorstate = SDMMC_CmdWriteMultiBlock(hsd->Instance, add); + } + else + { + hsd->Context = (SD_CONTEXT_WRITE_SINGLE_BLOCK | SD_CONTEXT_DMA); + + /* Write Single Block command */ + errorstate = SDMMC_CmdWriteSingleBlock(hsd->Instance, add); + } + if (errorstate != HAL_SD_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + hsd->ErrorCode |= errorstate; + hsd->State = HAL_SD_STATE_READY; + hsd->Context = SD_CONTEXT_NONE; + return HAL_ERROR; + } + + /* Enable transfer interrupts */ + __HAL_SD_ENABLE_IT(hsd, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND)); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Erases the specified memory area of the given SD card. + * @note This API should be followed by a check on the card state through + * HAL_SD_GetCardState(). + * @param hsd: Pointer to SD handle + * @param BlockStartAdd: Start Block address + * @param BlockEndAdd: End Block address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SD_Erase(SD_HandleTypeDef *hsd, uint32_t BlockStartAdd, uint32_t BlockEndAdd) +{ + uint32_t errorstate; + uint32_t start_add = BlockStartAdd; + uint32_t end_add = BlockEndAdd; + + if (hsd->State == HAL_SD_STATE_READY) + { + hsd->ErrorCode = HAL_SD_ERROR_NONE; + + if (end_add < start_add) + { + hsd->ErrorCode |= HAL_SD_ERROR_PARAM; + return HAL_ERROR; + } + + if (end_add > (hsd->SdCard.LogBlockNbr)) + { + hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE; + return HAL_ERROR; + } + + hsd->State = HAL_SD_STATE_BUSY; + + /* Check if the card command class supports erase command */ + if (((hsd->SdCard.Class) & SDMMC_CCCC_ERASE) == 0U) + { + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + hsd->ErrorCode |= HAL_SD_ERROR_REQUEST_NOT_APPLICABLE; + hsd->State = HAL_SD_STATE_READY; + return HAL_ERROR; + } + + if ((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED) + { + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + hsd->ErrorCode |= HAL_SD_ERROR_LOCK_UNLOCK_FAILED; + hsd->State = HAL_SD_STATE_READY; + return HAL_ERROR; + } + + /* Get start and end block for high capacity cards */ + if (hsd->SdCard.CardType != CARD_SDHC_SDXC) + { + start_add *= BLOCKSIZE; + end_add *= BLOCKSIZE; + } + + /* According to sd-card spec 1.0 ERASE_GROUP_START (CMD32) and erase_group_end(CMD33) */ + if (hsd->SdCard.CardType != CARD_SECURED) + { + /* Send CMD32 SD_ERASE_GRP_START with argument as addr */ + errorstate = SDMMC_CmdSDEraseStartAdd(hsd->Instance, start_add); + if (errorstate != HAL_SD_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + hsd->ErrorCode |= errorstate; + hsd->State = HAL_SD_STATE_READY; + return HAL_ERROR; + } + + /* Send CMD33 SD_ERASE_GRP_END with argument as addr */ + errorstate = SDMMC_CmdSDEraseEndAdd(hsd->Instance, end_add); + if (errorstate != HAL_SD_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + hsd->ErrorCode |= errorstate; + hsd->State = HAL_SD_STATE_READY; + return HAL_ERROR; + } + } + + /* Send CMD38 ERASE */ + errorstate = SDMMC_CmdErase(hsd->Instance, 0UL); + if (errorstate != HAL_SD_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + hsd->ErrorCode |= errorstate; + hsd->State = HAL_SD_STATE_READY; + return HAL_ERROR; + } + + hsd->State = HAL_SD_STATE_READY; + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief This function handles SD card interrupt request. + * @param hsd: Pointer to SD handle + * @retval None + */ +void HAL_SD_IRQHandler(SD_HandleTypeDef *hsd) +{ + uint32_t errorstate; + uint32_t context = hsd->Context; + + /* Check for SDMMC interrupt flags */ + if ((__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF) != RESET) && ((context & SD_CONTEXT_IT) != 0U)) + { + SD_Read_IT(hsd); + } + + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DATAEND) != RESET) + { + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DATAEND); + + __HAL_SD_DISABLE_IT(hsd, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | \ + SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR | SDMMC_IT_TXFIFOHE | \ + SDMMC_IT_RXFIFOHF); + + __HAL_SD_DISABLE_IT(hsd, SDMMC_IT_IDMABTC); + __SDMMC_CMDTRANS_DISABLE(hsd->Instance); + + if ((context & SD_CONTEXT_IT) != 0U) + { + if (((context & SD_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & SD_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)) + { + errorstate = SDMMC_CmdStopTransfer(hsd->Instance); + if (errorstate != HAL_SD_ERROR_NONE) + { + hsd->ErrorCode |= errorstate; +#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U) + hsd->ErrorCallback(hsd); +#else + HAL_SD_ErrorCallback(hsd); +#endif /* USE_HAL_SD_REGISTER_CALLBACKS */ + } + } + + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); + + hsd->State = HAL_SD_STATE_READY; + hsd->Context = SD_CONTEXT_NONE; + if (((context & SD_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & SD_CONTEXT_READ_MULTIPLE_BLOCK) != 0U)) + { +#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U) + hsd->RxCpltCallback(hsd); +#else + HAL_SD_RxCpltCallback(hsd); +#endif /* USE_HAL_SD_REGISTER_CALLBACKS */ + } + else + { +#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U) + hsd->TxCpltCallback(hsd); +#else + HAL_SD_TxCpltCallback(hsd); +#endif /* USE_HAL_SD_REGISTER_CALLBACKS */ + } + } + else if ((context & SD_CONTEXT_DMA) != 0U) + { + hsd->Instance->DLEN = 0; + hsd->Instance->DCTRL = 0; + hsd->Instance->IDMACTRL = SDMMC_DISABLE_IDMA; + + /* Stop Transfer for Write Multi blocks or Read Multi blocks */ + if (((context & SD_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & SD_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)) + { + errorstate = SDMMC_CmdStopTransfer(hsd->Instance); + if (errorstate != HAL_SD_ERROR_NONE) + { + hsd->ErrorCode |= errorstate; +#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U) + hsd->ErrorCallback(hsd); +#else + HAL_SD_ErrorCallback(hsd); +#endif /* USE_HAL_SD_REGISTER_CALLBACKS */ + } + } + + hsd->State = HAL_SD_STATE_READY; + hsd->Context = SD_CONTEXT_NONE; + if (((context & SD_CONTEXT_WRITE_SINGLE_BLOCK) != 0U) || ((context & SD_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)) + { +#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U) + hsd->TxCpltCallback(hsd); +#else + HAL_SD_TxCpltCallback(hsd); +#endif /* USE_HAL_SD_REGISTER_CALLBACKS */ + } + if (((context & SD_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & SD_CONTEXT_READ_MULTIPLE_BLOCK) != 0U)) + { +#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U) + hsd->RxCpltCallback(hsd); +#else + HAL_SD_RxCpltCallback(hsd); +#endif /* USE_HAL_SD_REGISTER_CALLBACKS */ + } + } + else + { + /* Nothing to do */ + } + } + + else if ((__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_TXFIFOHE) != RESET) && ((context & SD_CONTEXT_IT) != 0U)) + { + SD_Write_IT(hsd); + } + + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_RXOVERR | + SDMMC_FLAG_TXUNDERR) != RESET) + { + /* Set Error code */ + if (__HAL_SD_GET_FLAG(hsd, SDMMC_IT_DCRCFAIL) != RESET) + { + hsd->ErrorCode |= HAL_SD_ERROR_DATA_CRC_FAIL; + } + if (__HAL_SD_GET_FLAG(hsd, SDMMC_IT_DTIMEOUT) != RESET) + { + hsd->ErrorCode |= HAL_SD_ERROR_DATA_TIMEOUT; + } + if (__HAL_SD_GET_FLAG(hsd, SDMMC_IT_RXOVERR) != RESET) + { + hsd->ErrorCode |= HAL_SD_ERROR_RX_OVERRUN; + } + if (__HAL_SD_GET_FLAG(hsd, SDMMC_IT_TXUNDERR) != RESET) + { + hsd->ErrorCode |= HAL_SD_ERROR_TX_UNDERRUN; + } + + /* Clear All flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); + + /* Disable all interrupts */ + __HAL_SD_DISABLE_IT(hsd, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | \ + SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR); + + __SDMMC_CMDTRANS_DISABLE(hsd->Instance); + hsd->Instance->DCTRL |= SDMMC_DCTRL_FIFORST; + hsd->Instance->CMD |= SDMMC_CMD_CMDSTOP; + hsd->ErrorCode |= SDMMC_CmdStopTransfer(hsd->Instance); + hsd->Instance->CMD &= ~(SDMMC_CMD_CMDSTOP); + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DABORT); + + if ((context & SD_CONTEXT_IT) != 0U) + { + /* Set the SD state to ready to be able to start again the process */ + hsd->State = HAL_SD_STATE_READY; + hsd->Context = SD_CONTEXT_NONE; +#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U) + hsd->ErrorCallback(hsd); +#else + HAL_SD_ErrorCallback(hsd); +#endif /* USE_HAL_SD_REGISTER_CALLBACKS */ + } + else if ((context & SD_CONTEXT_DMA) != 0U) + { + if (hsd->ErrorCode != HAL_SD_ERROR_NONE) + { + /* Disable Internal DMA */ + __HAL_SD_DISABLE_IT(hsd, SDMMC_IT_IDMABTC); + hsd->Instance->IDMACTRL = SDMMC_DISABLE_IDMA; + + /* Set the SD state to ready to be able to start again the process */ + hsd->State = HAL_SD_STATE_READY; +#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U) + hsd->ErrorCallback(hsd); +#else + HAL_SD_ErrorCallback(hsd); +#endif /* USE_HAL_SD_REGISTER_CALLBACKS */ + } + } + else + { + /* Nothing to do */ + } + } + + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_IDMABTC) != RESET) + { + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_IDMABTC); + + if ((context & SD_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U) + { +#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U) + hsd->Write_DMALnkLstBufCpltCallback(hsd); +#else + HAL_SDEx_Write_DMALnkLstBufCpltCallback(hsd); +#endif /* USE_HAL_SD_REGISTER_CALLBACKS */ + } + else /* SD_CONTEXT_READ_MULTIPLE_BLOCK */ + { +#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U) + hsd->Read_DMALnkLstBufCpltCallback(hsd); +#else + HAL_SDEx_Read_DMALnkLstBufCpltCallback(hsd); +#endif /* USE_HAL_SD_REGISTER_CALLBACKS */ + } + } + else + { + /* Nothing to do */ + } +} + +/** + * @brief return the SD state + * @param hsd: Pointer to sd handle + * @retval HAL state + */ +HAL_SD_StateTypeDef HAL_SD_GetState(const SD_HandleTypeDef *hsd) +{ + return hsd->State; +} + +/** + * @brief Return the SD error code + * @param hsd : Pointer to a SD_HandleTypeDef structure that contains + * the configuration information. + * @retval SD Error Code + */ +uint32_t HAL_SD_GetError(const SD_HandleTypeDef *hsd) +{ + return hsd->ErrorCode; +} + +/** + * @brief Tx Transfer completed callbacks + * @param hsd: Pointer to SD handle + * @retval None + */ +__weak void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SD_TxCpltCallback can be implemented in the user file + */ +} + +/** + * @brief Rx Transfer completed callbacks + * @param hsd: Pointer SD handle + * @retval None + */ +__weak void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SD_RxCpltCallback can be implemented in the user file + */ +} + +/** + * @brief SD error callbacks + * @param hsd: Pointer SD handle + * @retval None + */ +__weak void HAL_SD_ErrorCallback(SD_HandleTypeDef *hsd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SD_ErrorCallback can be implemented in the user file + */ +} + +/** + * @brief SD Abort callbacks + * @param hsd: Pointer SD handle + * @retval None + */ +__weak void HAL_SD_AbortCallback(SD_HandleTypeDef *hsd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SD_AbortCallback can be implemented in the user file + */ +} + +#if (USE_SD_TRANSCEIVER != 0U) +/** + * @brief Enable/Disable the SD Transceiver 1.8V Mode Callback. + * @param status: Voltage Switch State + * @retval None + */ +__weak void HAL_SD_DriveTransceiver_1_8V_Callback(FlagStatus status) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(status); + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SD_EnableTransceiver could be implemented in the user file + */ +} +#endif /* USE_SD_TRANSCEIVER */ + +#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U) +/** + * @brief Register a User SD Callback + * To be used instead of the weak (overridden) predefined callback + * @note The HAL_SD_RegisterCallback() may be called before HAL_SD_Init() in + * HAL_SD_STATE_RESET to register callbacks for HAL_SD_MSP_INIT_CB_ID + * and HAL_SD_MSP_DEINIT_CB_ID. + * @param hsd : SD handle + * @param CallbackID : ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_SD_TX_CPLT_CB_ID SD Tx Complete Callback ID + * @arg @ref HAL_SD_RX_CPLT_CB_ID SD Rx Complete Callback ID + * @arg @ref HAL_SD_ERROR_CB_ID SD Error Callback ID + * @arg @ref HAL_SD_ABORT_CB_ID SD Abort Callback ID + * @arg @ref HAL_SD_READ_DMA_LNKLST_BUF_CPLT_CB_ID SD DMA Rx Linked List Node buffer Callback ID + * @arg @ref HAL_SD_WRITE_DMA_LNKLST_BUF_CPLT_CB_ID SD DMA Tx Linked List Node buffer Callback ID + * @arg @ref HAL_SD_MSP_INIT_CB_ID SD MspInit Callback ID + * @arg @ref HAL_SD_MSP_DEINIT_CB_ID SD MspDeInit Callback ID + * @param pCallback : pointer to the Callback function + * @retval status + */ +HAL_StatusTypeDef HAL_SD_RegisterCallback(SD_HandleTypeDef *hsd, HAL_SD_CallbackIDTypeDef CallbackID, + pSD_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + + if (hsd->State == HAL_SD_STATE_READY) + { + switch (CallbackID) + { + case HAL_SD_TX_CPLT_CB_ID : + hsd->TxCpltCallback = pCallback; + break; + case HAL_SD_RX_CPLT_CB_ID : + hsd->RxCpltCallback = pCallback; + break; + case HAL_SD_ERROR_CB_ID : + hsd->ErrorCallback = pCallback; + break; + case HAL_SD_ABORT_CB_ID : + hsd->AbortCpltCallback = pCallback; + break; + case HAL_SD_READ_DMA_LNKLST_BUF_CPLT_CB_ID : + hsd->Read_DMALnkLstBufCpltCallback = pCallback; + break; + case HAL_SD_WRITE_DMA_LNKLST_BUF_CPLT_CB_ID : + hsd->Write_DMALnkLstBufCpltCallback = pCallback; + break; + case HAL_SD_MSP_INIT_CB_ID : + hsd->MspInitCallback = pCallback; + break; + case HAL_SD_MSP_DEINIT_CB_ID : + hsd->MspDeInitCallback = pCallback; + break; + default : + /* Update the error code */ + hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else if (hsd->State == HAL_SD_STATE_RESET) + { + switch (CallbackID) + { + case HAL_SD_MSP_INIT_CB_ID : + hsd->MspInitCallback = pCallback; + break; + case HAL_SD_MSP_DEINIT_CB_ID : + hsd->MspDeInitCallback = pCallback; + break; + default : + /* Update the error code */ + hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister a User SD Callback + * SD Callback is redirected to the weak (overridden) predefined callback + * @note The HAL_SD_UnRegisterCallback() may be called before HAL_SD_Init() in + * HAL_SD_STATE_RESET to register callbacks for HAL_SD_MSP_INIT_CB_ID + * and HAL_SD_MSP_DEINIT_CB_ID. + * @param hsd : SD handle + * @param CallbackID : ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_SD_TX_CPLT_CB_ID SD Tx Complete Callback ID + * @arg @ref HAL_SD_RX_CPLT_CB_ID SD Rx Complete Callback ID + * @arg @ref HAL_SD_ERROR_CB_ID SD Error Callback ID + * @arg @ref HAL_SD_ABORT_CB_ID SD Abort Callback ID + * @arg @ref HAL_SD_READ_DMA_LNKLST_BUF_CPLT_CB_ID SD DMA Rx Linked List Node buffer Callback ID + * @arg @ref HAL_SD_WRITE_DMA_LNKLST_BUF_CPLT_CB_ID SD DMA Tx Linked List Node buffer Callback ID + * @arg @ref HAL_SD_MSP_INIT_CB_ID SD MspInit Callback ID + * @arg @ref HAL_SD_MSP_DEINIT_CB_ID SD MspDeInit Callback ID + * @retval status + */ +HAL_StatusTypeDef HAL_SD_UnRegisterCallback(SD_HandleTypeDef *hsd, HAL_SD_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (hsd->State == HAL_SD_STATE_READY) + { + switch (CallbackID) + { + case HAL_SD_TX_CPLT_CB_ID : + hsd->TxCpltCallback = HAL_SD_TxCpltCallback; + break; + case HAL_SD_RX_CPLT_CB_ID : + hsd->RxCpltCallback = HAL_SD_RxCpltCallback; + break; + case HAL_SD_ERROR_CB_ID : + hsd->ErrorCallback = HAL_SD_ErrorCallback; + break; + case HAL_SD_ABORT_CB_ID : + hsd->AbortCpltCallback = HAL_SD_AbortCallback; + break; + case HAL_SD_READ_DMA_LNKLST_BUF_CPLT_CB_ID : + hsd->Read_DMALnkLstBufCpltCallback = HAL_SDEx_Read_DMALnkLstBufCpltCallback; + break; + case HAL_SD_WRITE_DMA_LNKLST_BUF_CPLT_CB_ID : + hsd->Write_DMALnkLstBufCpltCallback = HAL_SDEx_Write_DMALnkLstBufCpltCallback; + break; + case HAL_SD_MSP_INIT_CB_ID : + hsd->MspInitCallback = HAL_SD_MspInit; + break; + case HAL_SD_MSP_DEINIT_CB_ID : + hsd->MspDeInitCallback = HAL_SD_MspDeInit; + break; + default : + /* Update the error code */ + hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else if (hsd->State == HAL_SD_STATE_RESET) + { + switch (CallbackID) + { + case HAL_SD_MSP_INIT_CB_ID : + hsd->MspInitCallback = HAL_SD_MspInit; + break; + case HAL_SD_MSP_DEINIT_CB_ID : + hsd->MspDeInitCallback = HAL_SD_MspDeInit; + break; + default : + /* Update the error code */ + hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + } + + return status; +} + +#if (USE_SD_TRANSCEIVER != 0U) +/** + * @brief Register a User SD Transceiver Callback + * To be used instead of the weak (overridden) predefined callback + * @param hsd : SD handle + * @param pCallback : pointer to the Callback function + * @retval status + */ +HAL_StatusTypeDef HAL_SD_RegisterTransceiverCallback(SD_HandleTypeDef *hsd, pSD_TransceiverCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hsd); + + if (hsd->State == HAL_SD_STATE_READY) + { + hsd->DriveTransceiver_1_8V_Callback = pCallback; + } + else + { + /* Update the error code */ + hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hsd); + return status; +} + +/** + * @brief Unregister a User SD Transceiver Callback + * SD Callback is redirected to the weak (overridden) predefined callback + * @param hsd : SD handle + * @retval status + */ +HAL_StatusTypeDef HAL_SD_UnRegisterTransceiverCallback(SD_HandleTypeDef *hsd) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hsd); + + if (hsd->State == HAL_SD_STATE_READY) + { + hsd->DriveTransceiver_1_8V_Callback = HAL_SD_DriveTransceiver_1_8V_Callback; + } + else + { + /* Update the error code */ + hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hsd); + return status; +} +#endif /* USE_SD_TRANSCEIVER */ +#endif /* USE_HAL_SD_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @addtogroup SD_Exported_Functions_Group3 + * @brief management functions + * +@verbatim + ============================================================================== + ##### Peripheral Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control the SD card + operations and get the related information + +@endverbatim + * @{ + */ + +/** + * @brief Returns information the information of the card which are stored on + * the CID register. + * @param hsd: Pointer to SD handle + * @param pCID: Pointer to a HAL_SD_CardCIDTypeDef structure that + * contains all CID register parameters + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SD_GetCardCID(SD_HandleTypeDef *hsd, HAL_SD_CardCIDTypeDef *pCID) +{ + pCID->ManufacturerID = (uint8_t)((hsd->CID[0] & 0xFF000000U) >> 24U); + + pCID->OEM_AppliID = (uint16_t)((hsd->CID[0] & 0x00FFFF00U) >> 8U); + + pCID->ProdName1 = (((hsd->CID[0] & 0x000000FFU) << 24U) | ((hsd->CID[1] & 0xFFFFFF00U) >> 8U)); + + pCID->ProdName2 = (uint8_t)(hsd->CID[1] & 0x000000FFU); + + pCID->ProdRev = (uint8_t)((hsd->CID[2] & 0xFF000000U) >> 24U); + + pCID->ProdSN = (((hsd->CID[2] & 0x00FFFFFFU) << 8U) | ((hsd->CID[3] & 0xFF000000U) >> 24U)); + + pCID->Reserved1 = (uint8_t)((hsd->CID[3] & 0x00F00000U) >> 20U); + + pCID->ManufactDate = (uint16_t)((hsd->CID[3] & 0x000FFF00U) >> 8U); + + pCID->CID_CRC = (uint8_t)((hsd->CID[3] & 0x000000FEU) >> 1U); + + pCID->Reserved2 = 1U; + + return HAL_OK; +} + +/** + * @brief Returns information the information of the card which are stored on + * the CSD register. + * @param hsd: Pointer to SD handle + * @param pCSD: Pointer to a HAL_SD_CardCSDTypeDef structure that + * contains all CSD register parameters + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SD_GetCardCSD(SD_HandleTypeDef *hsd, HAL_SD_CardCSDTypeDef *pCSD) +{ + pCSD->CSDStruct = (uint8_t)((hsd->CSD[0] & 0xC0000000U) >> 30U); + + pCSD->SysSpecVersion = (uint8_t)((hsd->CSD[0] & 0x3C000000U) >> 26U); + + pCSD->Reserved1 = (uint8_t)((hsd->CSD[0] & 0x03000000U) >> 24U); + + pCSD->TAAC = (uint8_t)((hsd->CSD[0] & 0x00FF0000U) >> 16U); + + pCSD->NSAC = (uint8_t)((hsd->CSD[0] & 0x0000FF00U) >> 8U); + + pCSD->MaxBusClkFrec = (uint8_t)(hsd->CSD[0] & 0x000000FFU); + + pCSD->CardComdClasses = (uint16_t)((hsd->CSD[1] & 0xFFF00000U) >> 20U); + + pCSD->RdBlockLen = (uint8_t)((hsd->CSD[1] & 0x000F0000U) >> 16U); + + pCSD->PartBlockRead = (uint8_t)((hsd->CSD[1] & 0x00008000U) >> 15U); + + pCSD->WrBlockMisalign = (uint8_t)((hsd->CSD[1] & 0x00004000U) >> 14U); + + pCSD->RdBlockMisalign = (uint8_t)((hsd->CSD[1] & 0x00002000U) >> 13U); + + pCSD->DSRImpl = (uint8_t)((hsd->CSD[1] & 0x00001000U) >> 12U); + + pCSD->Reserved2 = 0U; /*!< Reserved */ + + if (hsd->SdCard.CardType == CARD_SDSC) + { + pCSD->DeviceSize = (((hsd->CSD[1] & 0x000003FFU) << 2U) | ((hsd->CSD[2] & 0xC0000000U) >> 30U)); + + pCSD->MaxRdCurrentVDDMin = (uint8_t)((hsd->CSD[2] & 0x38000000U) >> 27U); + + pCSD->MaxRdCurrentVDDMax = (uint8_t)((hsd->CSD[2] & 0x07000000U) >> 24U); + + pCSD->MaxWrCurrentVDDMin = (uint8_t)((hsd->CSD[2] & 0x00E00000U) >> 21U); + + pCSD->MaxWrCurrentVDDMax = (uint8_t)((hsd->CSD[2] & 0x001C0000U) >> 18U); + + pCSD->DeviceSizeMul = (uint8_t)((hsd->CSD[2] & 0x00038000U) >> 15U); + + hsd->SdCard.BlockNbr = (pCSD->DeviceSize + 1U) ; + hsd->SdCard.BlockNbr *= (1UL << ((pCSD->DeviceSizeMul & 0x07U) + 2U)); + hsd->SdCard.BlockSize = (1UL << (pCSD->RdBlockLen & 0x0FU)); + + hsd->SdCard.LogBlockNbr = (hsd->SdCard.BlockNbr) * ((hsd->SdCard.BlockSize) / BLOCKSIZE); + hsd->SdCard.LogBlockSize = BLOCKSIZE; + } + else if (hsd->SdCard.CardType == CARD_SDHC_SDXC) + { + /* Byte 7 */ + pCSD->DeviceSize = (((hsd->CSD[1] & 0x0000003FU) << 16U) | ((hsd->CSD[2] & 0xFFFF0000U) >> 16U)); + + hsd->SdCard.BlockNbr = ((pCSD->DeviceSize + 1U) * 1024U); + hsd->SdCard.LogBlockNbr = hsd->SdCard.BlockNbr; + hsd->SdCard.BlockSize = BLOCKSIZE; + hsd->SdCard.LogBlockSize = hsd->SdCard.BlockSize; + } + else + { + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + hsd->State = HAL_SD_STATE_READY; + return HAL_ERROR; + } + + pCSD->EraseGrSize = (uint8_t)((hsd->CSD[2] & 0x00004000U) >> 14U); + + pCSD->EraseGrMul = (uint8_t)((hsd->CSD[2] & 0x00003F80U) >> 7U); + + pCSD->WrProtectGrSize = (uint8_t)(hsd->CSD[2] & 0x0000007FU); + + pCSD->WrProtectGrEnable = (uint8_t)((hsd->CSD[3] & 0x80000000U) >> 31U); + + pCSD->ManDeflECC = (uint8_t)((hsd->CSD[3] & 0x60000000U) >> 29U); + + pCSD->WrSpeedFact = (uint8_t)((hsd->CSD[3] & 0x1C000000U) >> 26U); + + pCSD->MaxWrBlockLen = (uint8_t)((hsd->CSD[3] & 0x03C00000U) >> 22U); + + pCSD->WriteBlockPaPartial = (uint8_t)((hsd->CSD[3] & 0x00200000U) >> 21U); + + pCSD->Reserved3 = 0; + + pCSD->ContentProtectAppli = (uint8_t)((hsd->CSD[3] & 0x00010000U) >> 16U); + + pCSD->FileFormatGroup = (uint8_t)((hsd->CSD[3] & 0x00008000U) >> 15U); + + pCSD->CopyFlag = (uint8_t)((hsd->CSD[3] & 0x00004000U) >> 14U); + + pCSD->PermWrProtect = (uint8_t)((hsd->CSD[3] & 0x00002000U) >> 13U); + + pCSD->TempWrProtect = (uint8_t)((hsd->CSD[3] & 0x00001000U) >> 12U); + + pCSD->FileFormat = (uint8_t)((hsd->CSD[3] & 0x00000C00U) >> 10U); + + pCSD->ECC = (uint8_t)((hsd->CSD[3] & 0x00000300U) >> 8U); + + pCSD->CSD_CRC = (uint8_t)((hsd->CSD[3] & 0x000000FEU) >> 1U); + + pCSD->Reserved4 = 1; + + return HAL_OK; +} + +/** + * @brief Gets the SD status info.( shall be called if there is no SD transaction ongoing ) + * @param hsd: Pointer to SD handle + * @param pStatus: Pointer to the HAL_SD_CardStatusTypeDef structure that + * will contain the SD card status information + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SD_GetCardStatus(SD_HandleTypeDef *hsd, HAL_SD_CardStatusTypeDef *pStatus) +{ + uint32_t sd_status[16]; + uint32_t errorstate; + HAL_StatusTypeDef status = HAL_OK; + + if (hsd->State == HAL_SD_STATE_BUSY) + { + return HAL_ERROR; + } + + errorstate = SD_SendSDStatus(hsd, sd_status); + if (errorstate != HAL_SD_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + hsd->ErrorCode |= errorstate; + hsd->State = HAL_SD_STATE_READY; + status = HAL_ERROR; + } + else + { + pStatus->DataBusWidth = (uint8_t)((sd_status[0] & 0xC0U) >> 6U); + + pStatus->SecuredMode = (uint8_t)((sd_status[0] & 0x20U) >> 5U); + + pStatus->CardType = (uint16_t)(((sd_status[0] & 0x00FF0000U) >> 8U) | ((sd_status[0] & 0xFF000000U) >> 24U)); + + pStatus->ProtectedAreaSize = (((sd_status[1] & 0xFFU) << 24U) | ((sd_status[1] & 0xFF00U) << 8U) | + ((sd_status[1] & 0xFF0000U) >> 8U) | ((sd_status[1] & 0xFF000000U) >> 24U)); + + pStatus->SpeedClass = (uint8_t)(sd_status[2] & 0xFFU); + + pStatus->PerformanceMove = (uint8_t)((sd_status[2] & 0xFF00U) >> 8U); + + pStatus->AllocationUnitSize = (uint8_t)((sd_status[2] & 0xF00000U) >> 20U); + + pStatus->EraseSize = (uint16_t)(((sd_status[2] & 0xFF000000U) >> 16U) | (sd_status[3] & 0xFFU)); + + pStatus->EraseTimeout = (uint8_t)((sd_status[3] & 0xFC00U) >> 10U); + + pStatus->EraseOffset = (uint8_t)((sd_status[3] & 0x0300U) >> 8U); + + pStatus->UhsSpeedGrade = (uint8_t)((sd_status[3] & 0x00F0U) >> 4U); + pStatus->UhsAllocationUnitSize = (uint8_t)(sd_status[3] & 0x000FU) ; + pStatus->VideoSpeedClass = (uint8_t)((sd_status[4] & 0xFF000000U) >> 24U); + } + + /* Set Block Size for Card */ + errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE); + if (errorstate != HAL_SD_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + hsd->ErrorCode = errorstate; + hsd->State = HAL_SD_STATE_READY; + status = HAL_ERROR; + } + + + return status; +} + +/** + * @brief Gets the SD card info. + * @param hsd: Pointer to SD handle + * @param pCardInfo: Pointer to the HAL_SD_CardInfoTypeDef structure that + * will contain the SD card status information + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SD_GetCardInfo(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypeDef *pCardInfo) +{ + pCardInfo->CardType = (uint32_t)(hsd->SdCard.CardType); + pCardInfo->CardVersion = (uint32_t)(hsd->SdCard.CardVersion); + pCardInfo->Class = (uint32_t)(hsd->SdCard.Class); + pCardInfo->RelCardAdd = (uint32_t)(hsd->SdCard.RelCardAdd); + pCardInfo->BlockNbr = (uint32_t)(hsd->SdCard.BlockNbr); + pCardInfo->BlockSize = (uint32_t)(hsd->SdCard.BlockSize); + pCardInfo->LogBlockNbr = (uint32_t)(hsd->SdCard.LogBlockNbr); + pCardInfo->LogBlockSize = (uint32_t)(hsd->SdCard.LogBlockSize); + + return HAL_OK; +} + +/** + * @brief Enables wide bus operation for the requested card if supported by + * card. + * @param hsd: Pointer to SD handle + * @param WideMode: Specifies the SD card wide bus mode + * This parameter can be one of the following values: + * @arg SDMMC_BUS_WIDE_8B: 8-bit data transfer + * @arg SDMMC_BUS_WIDE_4B: 4-bit data transfer + * @arg SDMMC_BUS_WIDE_1B: 1-bit data transfer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SD_ConfigWideBusOperation(SD_HandleTypeDef *hsd, uint32_t WideMode) +{ + SDMMC_InitTypeDef Init; + uint32_t errorstate; + uint32_t sdmmc_clk; + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_SDMMC_BUS_WIDE(WideMode)); + + /* Change State */ + hsd->State = HAL_SD_STATE_BUSY; + + if (hsd->SdCard.CardType != CARD_SECURED) + { + if (WideMode == SDMMC_BUS_WIDE_8B) + { + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + } + else if (WideMode == SDMMC_BUS_WIDE_4B) + { + errorstate = SD_WideBus_Enable(hsd); + + hsd->ErrorCode |= errorstate; + } + else if (WideMode == SDMMC_BUS_WIDE_1B) + { + errorstate = SD_WideBus_Disable(hsd); + + hsd->ErrorCode |= errorstate; + } + else + { + /* WideMode is not a valid argument*/ + hsd->ErrorCode |= HAL_SD_ERROR_PARAM; + } + } + else + { + /* SD Card does not support this feature */ + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + } + + if (hsd->ErrorCode != HAL_SD_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + status = HAL_ERROR; + } + else + { + if (hsd->Instance == SDMMC1) + { + sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC1); + } +#if defined(SDMMC2) + else + { + sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC2); + } +#endif /* SDMMC2 */ + if (sdmmc_clk != 0U) + { + /* Configure the SDMMC peripheral */ + Init.ClockEdge = hsd->Init.ClockEdge; + Init.ClockPowerSave = hsd->Init.ClockPowerSave; + Init.BusWide = WideMode; + Init.HardwareFlowControl = hsd->Init.HardwareFlowControl; + + /* Check if user Clock div < Normal speed 25Mhz, no change in Clockdiv */ + if (hsd->Init.ClockDiv >= (sdmmc_clk / (2U * SD_NORMAL_SPEED_FREQ))) + { + Init.ClockDiv = hsd->Init.ClockDiv; + } + else if (hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) + { + /* UltraHigh speed SD card,user Clock div */ + Init.ClockDiv = hsd->Init.ClockDiv; + } + else if (hsd->SdCard.CardSpeed == CARD_HIGH_SPEED) + { + /* High speed SD card, Max Frequency = 50Mhz */ + if (hsd->Init.ClockDiv == 0U) + { + if (sdmmc_clk > SD_HIGH_SPEED_FREQ) + { + Init.ClockDiv = sdmmc_clk / (2U * SD_HIGH_SPEED_FREQ); + } + else + { + Init.ClockDiv = hsd->Init.ClockDiv; + } + } + else + { + if ((sdmmc_clk / (2U * hsd->Init.ClockDiv)) > SD_HIGH_SPEED_FREQ) + { + Init.ClockDiv = sdmmc_clk / (2U * SD_HIGH_SPEED_FREQ); + } + else + { + Init.ClockDiv = hsd->Init.ClockDiv; + } + } + } + else + { + /* No High speed SD card, Max Frequency = 25Mhz */ + if (hsd->Init.ClockDiv == 0U) + { + if (sdmmc_clk > SD_NORMAL_SPEED_FREQ) + { + Init.ClockDiv = sdmmc_clk / (2U * SD_NORMAL_SPEED_FREQ); + } + else + { + Init.ClockDiv = hsd->Init.ClockDiv; + } + } + else + { + if ((sdmmc_clk / (2U * hsd->Init.ClockDiv)) > SD_NORMAL_SPEED_FREQ) + { + Init.ClockDiv = sdmmc_clk / (2U * SD_NORMAL_SPEED_FREQ); + } + else + { + Init.ClockDiv = hsd->Init.ClockDiv; + } + } + } + +#if (USE_SD_TRANSCEIVER != 0U) + Init.TranceiverPresent = hsd->Init.TranceiverPresent; +#endif /* USE_SD_TRANSCEIVER */ + + (void)SDMMC_Init(hsd->Instance, Init); + } + else + { + hsd->ErrorCode |= SDMMC_ERROR_INVALID_PARAMETER; + status = HAL_ERROR; + } + } + + /* Set Block Size for Card */ + errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE); + if (errorstate != HAL_SD_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + hsd->ErrorCode |= errorstate; + status = HAL_ERROR; + } + + /* Change State */ + hsd->State = HAL_SD_STATE_READY; + + return status; +} + +/** + * @brief Configure the speed bus mode + * @param hsd: Pointer to the SD handle + * @param SpeedMode: Specifies the SD card speed bus mode + * This parameter can be one of the following values: + * @arg SDMMC_SPEED_MODE_AUTO: Max speed mode supported by the card + * @arg SDMMC_SPEED_MODE_DEFAULT: Default Speed/SDR12 mode + * @arg SDMMC_SPEED_MODE_HIGH: High Speed/SDR25 mode + * @arg SDMMC_SPEED_MODE_ULTRA: Ultra high speed mode + * @retval HAL status + */ + +HAL_StatusTypeDef HAL_SD_ConfigSpeedBusOperation(SD_HandleTypeDef *hsd, uint32_t SpeedMode) +{ + uint32_t tickstart; + uint32_t errorstate; + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_SDMMC_SPEED_MODE(SpeedMode)); + /* Change State */ + hsd->State = HAL_SD_STATE_BUSY; + +#if (USE_SD_TRANSCEIVER != 0U) + if (hsd->Init.TranceiverPresent == SDMMC_TRANSCEIVER_PRESENT) + { + switch (SpeedMode) + { + case SDMMC_SPEED_MODE_AUTO: + { + if ((hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) || + (hsd->SdCard.CardType == CARD_SDHC_SDXC)) + { + hsd->Instance->CLKCR |= SDMMC_CLKCR_BUSSPEED; + /* Enable Ultra High Speed */ + if (SD_UltraHighSpeed(hsd, SDMMC_SDR104_SWITCH_PATTERN) != HAL_SD_ERROR_NONE) + { + if (SD_SwitchSpeed(hsd, SDMMC_SDR25_SWITCH_PATTERN) != HAL_SD_ERROR_NONE) + { + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + status = HAL_ERROR; + } + } + } + else if (hsd->SdCard.CardSpeed == CARD_HIGH_SPEED) + { + /* Enable High Speed */ + if (SD_SwitchSpeed(hsd, SDMMC_SDR25_SWITCH_PATTERN) != HAL_SD_ERROR_NONE) + { + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + status = HAL_ERROR; + } + } + else + { + /*Nothing to do, Use defaultSpeed */ + } + break; + } + case SDMMC_SPEED_MODE_ULTRA_SDR104: + { + if ((hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) || + (hsd->SdCard.CardType == CARD_SDHC_SDXC)) + { + /* Enable UltraHigh Speed */ + if (SD_UltraHighSpeed(hsd, SDMMC_SDR104_SWITCH_PATTERN) != HAL_SD_ERROR_NONE) + { + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + status = HAL_ERROR; + } + hsd->Instance->CLKCR |= SDMMC_CLKCR_BUSSPEED; + } + else + { + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + status = HAL_ERROR; + } + break; + } + case SDMMC_SPEED_MODE_ULTRA_SDR50: + { + if ((hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) || + (hsd->SdCard.CardType == CARD_SDHC_SDXC)) + { + /* Enable UltraHigh Speed */ + if (SD_UltraHighSpeed(hsd, SDMMC_SDR50_SWITCH_PATTERN) != HAL_SD_ERROR_NONE) + { + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + status = HAL_ERROR; + } + hsd->Instance->CLKCR |= SDMMC_CLKCR_BUSSPEED; + } + else + { + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + status = HAL_ERROR; + } + break; + } + case SDMMC_SPEED_MODE_DDR: + { + if ((hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) || + (hsd->SdCard.CardType == CARD_SDHC_SDXC)) + { + /* Enable DDR Mode*/ + if (SD_DDR_Mode(hsd) != HAL_SD_ERROR_NONE) + { + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + status = HAL_ERROR; + } + hsd->Instance->CLKCR |= SDMMC_CLKCR_BUSSPEED | SDMMC_CLKCR_DDR; + } + else + { + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + status = HAL_ERROR; + } + break; + } + case SDMMC_SPEED_MODE_HIGH: + { + if ((hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) || + (hsd->SdCard.CardSpeed == CARD_HIGH_SPEED) || + (hsd->SdCard.CardType == CARD_SDHC_SDXC)) + { + /* Enable High Speed */ + if (SD_SwitchSpeed(hsd, SDMMC_SDR25_SWITCH_PATTERN) != HAL_SD_ERROR_NONE) + { + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + status = HAL_ERROR; + } + } + else + { + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + status = HAL_ERROR; + } + break; + } + case SDMMC_SPEED_MODE_DEFAULT: + { + /* Switch to default Speed */ + if (SD_SwitchSpeed(hsd, SDMMC_SDR12_SWITCH_PATTERN) != HAL_SD_ERROR_NONE) + { + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + status = HAL_ERROR; + } + + break; + } + default: + hsd->ErrorCode |= HAL_SD_ERROR_PARAM; + status = HAL_ERROR; + break; + } + } + else + { + switch (SpeedMode) + { + case SDMMC_SPEED_MODE_AUTO: + { + if ((hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) || + (hsd->SdCard.CardSpeed == CARD_HIGH_SPEED) || + (hsd->SdCard.CardType == CARD_SDHC_SDXC)) + { + /* Enable High Speed */ + if (SD_SwitchSpeed(hsd, SDMMC_SDR25_SWITCH_PATTERN) != HAL_SD_ERROR_NONE) + { + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + status = HAL_ERROR; + } + } + else + { + /*Nothing to do, Use defaultSpeed */ + } + break; + } + case SDMMC_SPEED_MODE_HIGH: + { + if ((hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) || + (hsd->SdCard.CardSpeed == CARD_HIGH_SPEED) || + (hsd->SdCard.CardType == CARD_SDHC_SDXC)) + { + /* Enable High Speed */ + if (SD_SwitchSpeed(hsd, SDMMC_SDR25_SWITCH_PATTERN) != HAL_SD_ERROR_NONE) + { + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + status = HAL_ERROR; + } + } + else + { + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + status = HAL_ERROR; + } + break; + } + case SDMMC_SPEED_MODE_DEFAULT: + { + /* Switch to default Speed */ + if (SD_SwitchSpeed(hsd, SDMMC_SDR12_SWITCH_PATTERN) != HAL_SD_ERROR_NONE) + { + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + status = HAL_ERROR; + } + + break; + } + case SDMMC_SPEED_MODE_ULTRA: /*not valid without transceiver*/ + default: + hsd->ErrorCode |= HAL_SD_ERROR_PARAM; + status = HAL_ERROR; + break; + } + } +#else + switch (SpeedMode) + { + case SDMMC_SPEED_MODE_AUTO: + { + if ((hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) || + (hsd->SdCard.CardSpeed == CARD_HIGH_SPEED) || + (hsd->SdCard.CardType == CARD_SDHC_SDXC)) + { + /* Enable High Speed */ + if (SD_SwitchSpeed(hsd, SDMMC_SDR25_SWITCH_PATTERN) != HAL_SD_ERROR_NONE) + { + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + status = HAL_ERROR; + } + } + else + { + /*Nothing to do, Use defaultSpeed */ + } + break; + } + case SDMMC_SPEED_MODE_HIGH: + { + if ((hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) || + (hsd->SdCard.CardSpeed == CARD_HIGH_SPEED) || + (hsd->SdCard.CardType == CARD_SDHC_SDXC)) + { + /* Enable High Speed */ + if (SD_SwitchSpeed(hsd, SDMMC_SDR25_SWITCH_PATTERN) != HAL_SD_ERROR_NONE) + { + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + status = HAL_ERROR; + } + } + else + { + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + status = HAL_ERROR; + } + break; + } + case SDMMC_SPEED_MODE_DEFAULT: + { + /* Switch to default Speed */ + if (SD_SwitchSpeed(hsd, SDMMC_SDR12_SWITCH_PATTERN) != HAL_SD_ERROR_NONE) + { + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + status = HAL_ERROR; + } + + break; + } + case SDMMC_SPEED_MODE_ULTRA: /*not valid without transceiver*/ + default: + hsd->ErrorCode |= HAL_SD_ERROR_PARAM; + status = HAL_ERROR; + break; + } +#endif /* USE_SD_TRANSCEIVER */ + + /* Verify that SD card is ready to use after Speed mode switch*/ + tickstart = HAL_GetTick(); + while ((HAL_SD_GetCardState(hsd) != HAL_SD_CARD_TRANSFER)) + { + if ((HAL_GetTick() - tickstart) >= SDMMC_SWDATATIMEOUT) + { + hsd->ErrorCode = HAL_SD_ERROR_TIMEOUT; + hsd->State = HAL_SD_STATE_READY; + return HAL_TIMEOUT; + } + } + + /* Set Block Size for Card */ + errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE); + if (errorstate != HAL_SD_ERROR_NONE) + { + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + hsd->ErrorCode |= errorstate; + status = HAL_ERROR; + } + + /* Change State */ + hsd->State = HAL_SD_STATE_READY; + return status; +} + +/** + * @brief Gets the current sd card data state. + * @param hsd: pointer to SD handle + * @retval Card state + */ +HAL_SD_CardStateTypeDef HAL_SD_GetCardState(SD_HandleTypeDef *hsd) +{ + uint32_t cardstate; + uint32_t errorstate; + uint32_t resp1 = 0; + + errorstate = SD_SendStatus(hsd, &resp1); + if (errorstate != HAL_SD_ERROR_NONE) + { + hsd->ErrorCode |= errorstate; + } + + cardstate = ((resp1 >> 9U) & 0x0FU); + + return (HAL_SD_CardStateTypeDef)cardstate; +} + +/** + * @brief Abort the current transfer and disable the SD. + * @param hsd: pointer to a SD_HandleTypeDef structure that contains + * the configuration information for SD module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SD_Abort(SD_HandleTypeDef *hsd) +{ + uint32_t error_code; + uint32_t tickstart; + + if (hsd->State == HAL_SD_STATE_BUSY) + { + /* DIsable All interrupts */ + __HAL_SD_DISABLE_IT(hsd, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | \ + SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR); + __SDMMC_CMDTRANS_DISABLE(hsd->Instance); + + /*we will send the CMD12 in all cases in order to stop the data transfers*/ + /*In case the data transfer just finished , the external memory will not respond + and will return HAL_SD_ERROR_CMD_RSP_TIMEOUT*/ + /*In case the data transfer aborted , the external memory will respond and will return HAL_SD_ERROR_NONE*/ + /*Other scenario will return HAL_ERROR*/ + + hsd->ErrorCode = SDMMC_CmdStopTransfer(hsd->Instance); + error_code = hsd->ErrorCode; + if ((error_code != HAL_SD_ERROR_NONE) && (error_code != HAL_SD_ERROR_CMD_RSP_TIMEOUT)) + { + return HAL_ERROR; + } + + tickstart = HAL_GetTick(); + if ((hsd->Instance->DCTRL & SDMMC_DCTRL_DTDIR) == SDMMC_TRANSFER_DIR_TO_CARD) + { + if (hsd->ErrorCode == HAL_SD_ERROR_NONE) + { + while (!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DABORT | SDMMC_FLAG_BUSYD0END)) + { + if ((HAL_GetTick() - tickstart) >= SDMMC_SWDATATIMEOUT) + { + hsd->ErrorCode = HAL_SD_ERROR_TIMEOUT; + hsd->State = HAL_SD_STATE_READY; + return HAL_TIMEOUT; + } + } + } + + if (hsd->ErrorCode == HAL_SD_ERROR_CMD_RSP_TIMEOUT) + { + while (!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DATAEND)) + { + if ((HAL_GetTick() - tickstart) >= SDMMC_SWDATATIMEOUT) + { + hsd->ErrorCode = HAL_SD_ERROR_TIMEOUT; + hsd->State = HAL_SD_STATE_READY; + return HAL_TIMEOUT; + } + } + } + } + else if ((hsd->Instance->DCTRL & SDMMC_DCTRL_DTDIR) == SDMMC_TRANSFER_DIR_TO_SDMMC) + { + while (!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DABORT | SDMMC_FLAG_DATAEND)) + { + if ((HAL_GetTick() - tickstart) >= SDMMC_SWDATATIMEOUT) + { + hsd->ErrorCode = HAL_SD_ERROR_TIMEOUT; + hsd->State = HAL_SD_STATE_READY; + return HAL_TIMEOUT; + } + } + } + else + { + /* Nothing to do*/ + } + + /*The reason of all these while conditions previously is that we need to wait the SDMMC and clear + the appropriate flags that will be set depending of the abort/non abort of the memory */ + /*Not waiting the SDMMC flags will cause the next SDMMC_DISABLE_IDMA to not get cleared + and will result in next SDMMC read/write operation to fail */ + + /*SDMMC ready for clear data flags*/ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_BUSYD0END); + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); + /* If IDMA Context, disable Internal DMA */ + hsd->Instance->IDMACTRL = SDMMC_DISABLE_IDMA; + + hsd->State = HAL_SD_STATE_READY; + + /* Initialize the SD operation */ + hsd->Context = SD_CONTEXT_NONE; + } + return HAL_OK; +} + + +/** + * @brief Abort the current transfer and disable the SD (IT mode). + * @param hsd: pointer to a SD_HandleTypeDef structure that contains + * the configuration information for SD module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SD_Abort_IT(SD_HandleTypeDef *hsd) +{ + HAL_SD_CardStateTypeDef CardState; + + /* Disable All interrupts */ + __HAL_SD_DISABLE_IT(hsd, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | \ + SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR); + + /* If IDMA Context, disable Internal DMA */ + hsd->Instance->IDMACTRL = SDMMC_DISABLE_IDMA; + + /* Clear All flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); + + CardState = HAL_SD_GetCardState(hsd); + hsd->State = HAL_SD_STATE_READY; + + if ((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING)) + { + hsd->ErrorCode = SDMMC_CmdStopTransfer(hsd->Instance); + } + + if (hsd->ErrorCode != HAL_SD_ERROR_NONE) + { + return HAL_ERROR; + } + else + { +#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U) + hsd->AbortCpltCallback(hsd); +#else + HAL_SD_AbortCallback(hsd); +#endif /* USE_HAL_SD_REGISTER_CALLBACKS */ + } + + return HAL_OK; +} + +/** + * @} + */ + +/** + * @} + */ + +/* Private function ----------------------------------------------------------*/ +/** @addtogroup SD_Private_Functions + * @{ + */ + + +/** + * @brief Initializes the sd card. + * @param hsd: Pointer to SD handle + * @retval SD Card error state + */ +static uint32_t SD_InitCard(SD_HandleTypeDef *hsd) +{ + HAL_SD_CardCSDTypeDef CSD; + uint32_t errorstate; + uint16_t sd_rca = 0U; + uint32_t tickstart = HAL_GetTick(); + + /* Check the power State */ + if (SDMMC_GetPowerState(hsd->Instance) == 0U) + { + /* Power off */ + return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE; + } + + if (hsd->SdCard.CardType != CARD_SECURED) + { + /* Send CMD2 ALL_SEND_CID */ + errorstate = SDMMC_CmdSendCID(hsd->Instance); + if (errorstate != HAL_SD_ERROR_NONE) + { + return errorstate; + } + else + { + /* Get Card identification number data */ + hsd->CID[0U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1); + hsd->CID[1U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP2); + hsd->CID[2U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP3); + hsd->CID[3U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP4); + } + } + + if (hsd->SdCard.CardType != CARD_SECURED) + { + /* Send CMD3 SET_REL_ADDR with argument 0 */ + /* SD Card publishes its RCA. */ + while (sd_rca == 0U) + { + errorstate = SDMMC_CmdSetRelAdd(hsd->Instance, &sd_rca); + if (errorstate != HAL_SD_ERROR_NONE) + { + return errorstate; + } + if ((HAL_GetTick() - tickstart) >= SDMMC_CMDTIMEOUT) + { + return HAL_SD_ERROR_TIMEOUT; + } + } + } + if (hsd->SdCard.CardType != CARD_SECURED) + { + /* Get the SD card RCA */ + hsd->SdCard.RelCardAdd = sd_rca; + + /* Send CMD9 SEND_CSD with argument as card's RCA */ + errorstate = SDMMC_CmdSendCSD(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U)); + if (errorstate != HAL_SD_ERROR_NONE) + { + return errorstate; + } + else + { + /* Get Card Specific Data */ + hsd->CSD[0U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1); + hsd->CSD[1U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP2); + hsd->CSD[2U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP3); + hsd->CSD[3U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP4); + } + } + + /* Get the Card Class */ + hsd->SdCard.Class = (SDMMC_GetResponse(hsd->Instance, SDMMC_RESP2) >> 20U); + + /* Get CSD parameters */ + if (HAL_SD_GetCardCSD(hsd, &CSD) != HAL_OK) + { + return HAL_SD_ERROR_UNSUPPORTED_FEATURE; + } + + /* Select the Card */ + errorstate = SDMMC_CmdSelDesel(hsd->Instance, (uint32_t)(((uint32_t)hsd->SdCard.RelCardAdd) << 16U)); + if (errorstate != HAL_SD_ERROR_NONE) + { + return errorstate; + } + + /* All cards are initialized */ + return HAL_SD_ERROR_NONE; +} + +/** + * @brief Enquires cards about their operating voltage and configures clock + * controls and stores SD information that will be needed in future + * in the SD handle. + * @param hsd: Pointer to SD handle + * @retval error state + */ +static uint32_t SD_PowerON(SD_HandleTypeDef *hsd) +{ + __IO uint32_t count = 0U; + uint32_t response = 0U; + uint32_t validvoltage = 0U; + uint32_t errorstate; +#if (USE_SD_TRANSCEIVER != 0U) + uint32_t tickstart = HAL_GetTick(); +#endif /* USE_SD_TRANSCEIVER */ + + /* CMD0: GO_IDLE_STATE */ + errorstate = SDMMC_CmdGoIdleState(hsd->Instance); + if (errorstate != HAL_SD_ERROR_NONE) + { + return errorstate; + } + + /* CMD8: SEND_IF_COND: Command available only on V2.0 cards */ + errorstate = SDMMC_CmdOperCond(hsd->Instance); + if (errorstate == SDMMC_ERROR_TIMEOUT) /* No response to CMD8 */ + { + hsd->SdCard.CardVersion = CARD_V1_X; + /* CMD0: GO_IDLE_STATE */ + errorstate = SDMMC_CmdGoIdleState(hsd->Instance); + if (errorstate != HAL_SD_ERROR_NONE) + { + return errorstate; + } + + } + else + { + hsd->SdCard.CardVersion = CARD_V2_X; + } + + if (hsd->SdCard.CardVersion == CARD_V2_X) + { + /* SEND CMD55 APP_CMD with RCA as 0 */ + errorstate = SDMMC_CmdAppCommand(hsd->Instance, 0); + if (errorstate != HAL_SD_ERROR_NONE) + { + return HAL_SD_ERROR_UNSUPPORTED_FEATURE; + } + } + /* SD CARD */ + /* Send ACMD41 SD_APP_OP_COND with Argument 0x80100000 */ + while ((count < SDMMC_MAX_VOLT_TRIAL) && (validvoltage == 0U)) + { + /* SEND CMD55 APP_CMD with RCA as 0 */ + errorstate = SDMMC_CmdAppCommand(hsd->Instance, 0); + if (errorstate != HAL_SD_ERROR_NONE) + { + return errorstate; + } + + /* Send CMD41 */ + errorstate = SDMMC_CmdAppOperCommand(hsd->Instance, SDMMC_VOLTAGE_WINDOW_SD | SDMMC_HIGH_CAPACITY | + SD_SWITCH_1_8V_CAPACITY); + if (errorstate != HAL_SD_ERROR_NONE) + { + return HAL_SD_ERROR_UNSUPPORTED_FEATURE; + } + + /* Get command response */ + response = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1); + + /* Get operating voltage*/ + validvoltage = (((response >> 31U) == 1U) ? 1U : 0U); + + count++; + } + + if (count >= SDMMC_MAX_VOLT_TRIAL) + { + return HAL_SD_ERROR_INVALID_VOLTRANGE; + } + + /* Set default card type */ + hsd->SdCard.CardType = CARD_SDSC; + + if ((response & SDMMC_HIGH_CAPACITY) == SDMMC_HIGH_CAPACITY) + { + hsd->SdCard.CardType = CARD_SDHC_SDXC; +#if (USE_SD_TRANSCEIVER != 0U) + if (hsd->Init.TranceiverPresent == SDMMC_TRANSCEIVER_PRESENT) + { + if ((response & SD_SWITCH_1_8V_CAPACITY) == SD_SWITCH_1_8V_CAPACITY) + { + hsd->SdCard.CardSpeed = CARD_ULTRA_HIGH_SPEED; + + /* Start switching procedue */ + hsd->Instance->POWER |= SDMMC_POWER_VSWITCHEN; + + /* Send CMD11 to switch 1.8V mode */ + errorstate = SDMMC_CmdVoltageSwitch(hsd->Instance); + if (errorstate != HAL_SD_ERROR_NONE) + { + return errorstate; + } + + /* Check to CKSTOP */ + while ((hsd->Instance->STA & SDMMC_FLAG_CKSTOP) != SDMMC_FLAG_CKSTOP) + { + if ((HAL_GetTick() - tickstart) >= SDMMC_SWDATATIMEOUT) + { + return HAL_SD_ERROR_TIMEOUT; + } + } + + /* Clear CKSTOP Flag */ + hsd->Instance->ICR = SDMMC_FLAG_CKSTOP; + + /* Check to BusyD0 */ + if ((hsd->Instance->STA & SDMMC_FLAG_BUSYD0) != SDMMC_FLAG_BUSYD0) + { + /* Error when activate Voltage Switch in SDMMC Peripheral */ + return SDMMC_ERROR_UNSUPPORTED_FEATURE; + } + else + { + /* Enable Transceiver Switch PIN */ +#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U) + hsd->DriveTransceiver_1_8V_Callback(SET); +#else + HAL_SD_DriveTransceiver_1_8V_Callback(SET); +#endif /* USE_HAL_SD_REGISTER_CALLBACKS */ + + /* Switch ready */ + hsd->Instance->POWER |= SDMMC_POWER_VSWITCH; + + /* Check VSWEND Flag */ + while ((hsd->Instance->STA & SDMMC_FLAG_VSWEND) != SDMMC_FLAG_VSWEND) + { + if ((HAL_GetTick() - tickstart) >= SDMMC_SWDATATIMEOUT) + { + return HAL_SD_ERROR_TIMEOUT; + } + } + + /* Clear VSWEND Flag */ + hsd->Instance->ICR = SDMMC_FLAG_VSWEND; + + /* Check BusyD0 status */ + if ((hsd->Instance->STA & SDMMC_FLAG_BUSYD0) == SDMMC_FLAG_BUSYD0) + { + /* Error when enabling 1.8V mode */ + return HAL_SD_ERROR_INVALID_VOLTRANGE; + } + /* Switch to 1.8V OK */ + + /* Disable VSWITCH FLAG from SDMMC Peripheral */ + hsd->Instance->POWER = 0x13U; + + /* Clean Status flags */ + hsd->Instance->ICR = 0xFFFFFFFFU; + } + } + } +#endif /* USE_SD_TRANSCEIVER */ + } + + return HAL_SD_ERROR_NONE; +} + +/** + * @brief Turns the SDMMC output signals off. + * @param hsd: Pointer to SD handle + * @retval None + */ +static void SD_PowerOFF(SD_HandleTypeDef *hsd) +{ + /* Set Power State to OFF */ + (void)SDMMC_PowerState_OFF(hsd->Instance); +} + +/** + * @brief Send Status info command. + * @param hsd: pointer to SD handle + * @param pSDstatus: Pointer to the buffer that will contain the SD card status + * SD Status register) + * @retval error state + */ +static uint32_t SD_SendSDStatus(SD_HandleTypeDef *hsd, uint32_t *pSDstatus) +{ + SDMMC_DataInitTypeDef config; + uint32_t errorstate; + uint32_t tickstart = HAL_GetTick(); + uint32_t count; + uint32_t *pData = pSDstatus; + + /* Check SD response */ + if ((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED) + { + return HAL_SD_ERROR_LOCK_UNLOCK_FAILED; + } + + /* Set block size for card if it is not equal to current block size for card */ + errorstate = SDMMC_CmdBlockLength(hsd->Instance, 64U); + if (errorstate != HAL_SD_ERROR_NONE) + { + hsd->ErrorCode |= HAL_SD_ERROR_NONE; + return errorstate; + } + + /* Send CMD55 */ + errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U)); + if (errorstate != HAL_SD_ERROR_NONE) + { + hsd->ErrorCode |= HAL_SD_ERROR_NONE; + return errorstate; + } + + /* Configure the SD DPSM (Data Path State Machine) */ + config.DataTimeOut = SDMMC_DATATIMEOUT; + config.DataLength = 64U; + config.DataBlockSize = SDMMC_DATABLOCK_SIZE_64B; + config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + config.DPSM = SDMMC_DPSM_ENABLE; + (void)SDMMC_ConfigData(hsd->Instance, &config); + + /* Send ACMD13 (SD_APP_STAUS) with argument as card's RCA */ + errorstate = SDMMC_CmdStatusRegister(hsd->Instance); + if (errorstate != HAL_SD_ERROR_NONE) + { + hsd->ErrorCode |= HAL_SD_ERROR_NONE; + return errorstate; + } + + /* Get status data */ + while (!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND)) + { + if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF)) + { + for (count = 0U; count < 8U; count++) + { + *pData = SDMMC_ReadFIFO(hsd->Instance); + pData++; + } + } + + if ((HAL_GetTick() - tickstart) >= SDMMC_SWDATATIMEOUT) + { + return HAL_SD_ERROR_TIMEOUT; + } + } + + if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT)) + { + return HAL_SD_ERROR_DATA_TIMEOUT; + } + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL)) + { + return HAL_SD_ERROR_DATA_CRC_FAIL; + } + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR)) + { + return HAL_SD_ERROR_RX_OVERRUN; + } + else + { + /* Nothing to do */ + } + + while ((__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DPSMACT))) + { + *pData = SDMMC_ReadFIFO(hsd->Instance); + pData++; + + if ((HAL_GetTick() - tickstart) >= SDMMC_SWDATATIMEOUT) + { + return HAL_SD_ERROR_TIMEOUT; + } + } + + /* Clear all the static status flags*/ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); + + return HAL_SD_ERROR_NONE; +} + +/** + * @brief Returns the current card's status. + * @param hsd: Pointer to SD handle + * @param pCardStatus: pointer to the buffer that will contain the SD card + * status (Card Status register) + * @retval error state + */ +static uint32_t SD_SendStatus(SD_HandleTypeDef *hsd, uint32_t *pCardStatus) +{ + uint32_t errorstate; + + if (pCardStatus == NULL) + { + return HAL_SD_ERROR_PARAM; + } + + /* Send Status command */ + errorstate = SDMMC_CmdSendStatus(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U)); + if (errorstate != HAL_SD_ERROR_NONE) + { + return errorstate; + } + + /* Get SD card status */ + *pCardStatus = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1); + + return HAL_SD_ERROR_NONE; +} + +/** + * @brief Enables the SDMMC wide bus mode. + * @param hsd: pointer to SD handle + * @retval error state + */ +static uint32_t SD_WideBus_Enable(SD_HandleTypeDef *hsd) +{ + uint32_t scr[2U] = {0UL, 0UL}; + uint32_t errorstate; + + if ((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED) + { + return HAL_SD_ERROR_LOCK_UNLOCK_FAILED; + } + + /* Get SCR Register */ + errorstate = SD_FindSCR(hsd, scr); + if (errorstate != HAL_SD_ERROR_NONE) + { + return errorstate; + } + + /* If requested card supports wide bus operation */ + if ((scr[1U] & SDMMC_WIDE_BUS_SUPPORT) != SDMMC_ALLZERO) + { + /* Send CMD55 APP_CMD with argument as card's RCA.*/ + errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U)); + if (errorstate != HAL_SD_ERROR_NONE) + { + return errorstate; + } + + /* Send ACMD6 APP_CMD with argument as 2 for wide bus mode */ + errorstate = SDMMC_CmdBusWidth(hsd->Instance, 2U); + if (errorstate != HAL_SD_ERROR_NONE) + { + return errorstate; + } + + return HAL_SD_ERROR_NONE; + } + else + { + return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE; + } +} + +/** + * @brief Disables the SDMMC wide bus mode. + * @param hsd: Pointer to SD handle + * @retval error state + */ +static uint32_t SD_WideBus_Disable(SD_HandleTypeDef *hsd) +{ + uint32_t scr[2U] = {0UL, 0UL}; + uint32_t errorstate; + + if ((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED) + { + return HAL_SD_ERROR_LOCK_UNLOCK_FAILED; + } + + /* Get SCR Register */ + errorstate = SD_FindSCR(hsd, scr); + if (errorstate != HAL_SD_ERROR_NONE) + { + return errorstate; + } + + /* If requested card supports 1 bit mode operation */ + if ((scr[1U] & SDMMC_SINGLE_BUS_SUPPORT) != SDMMC_ALLZERO) + { + /* Send CMD55 APP_CMD with argument as card's RCA */ + errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U)); + if (errorstate != HAL_SD_ERROR_NONE) + { + return errorstate; + } + + /* Send ACMD6 APP_CMD with argument as 0 for single bus mode */ + errorstate = SDMMC_CmdBusWidth(hsd->Instance, 0U); + if (errorstate != HAL_SD_ERROR_NONE) + { + return errorstate; + } + + return HAL_SD_ERROR_NONE; + } + else + { + return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE; + } +} + + +/** + * @brief Finds the SD card SCR register value. + * @param hsd: Pointer to SD handle + * @param pSCR: pointer to the buffer that will contain the SCR value + * @retval error state + */ +static uint32_t SD_FindSCR(SD_HandleTypeDef *hsd, uint32_t *pSCR) +{ + SDMMC_DataInitTypeDef config; + uint32_t errorstate; + uint32_t tickstart = HAL_GetTick(); + uint32_t index = 0U; + uint32_t tempscr[2U] = {0UL, 0UL}; + uint32_t *scr = pSCR; + + /* Set Block Size To 8 Bytes */ + errorstate = SDMMC_CmdBlockLength(hsd->Instance, 8U); + if (errorstate != HAL_SD_ERROR_NONE) + { + return errorstate; + } + + /* Send CMD55 APP_CMD with argument as card's RCA */ + errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)((hsd->SdCard.RelCardAdd) << 16U)); + if (errorstate != HAL_SD_ERROR_NONE) + { + return errorstate; + } + + config.DataTimeOut = SDMMC_DATATIMEOUT; + config.DataLength = 8U; + config.DataBlockSize = SDMMC_DATABLOCK_SIZE_8B; + config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + config.DPSM = SDMMC_DPSM_ENABLE; + (void)SDMMC_ConfigData(hsd->Instance, &config); + + /* Send ACMD51 SD_APP_SEND_SCR with argument as 0 */ + errorstate = SDMMC_CmdSendSCR(hsd->Instance); + if (errorstate != HAL_SD_ERROR_NONE) + { + return errorstate; + } + + while (!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND | + SDMMC_FLAG_DATAEND)) + { + if ((!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOE)) && (index == 0U)) + { + tempscr[0] = SDMMC_ReadFIFO(hsd->Instance); + tempscr[1] = SDMMC_ReadFIFO(hsd->Instance); + index++; + } + + + if ((HAL_GetTick() - tickstart) >= SDMMC_SWDATATIMEOUT) + { + return HAL_SD_ERROR_TIMEOUT; + } + } + + if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT)) + { + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DTIMEOUT); + + return HAL_SD_ERROR_DATA_TIMEOUT; + } + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL)) + { + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DCRCFAIL); + + return HAL_SD_ERROR_DATA_CRC_FAIL; + } + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR)) + { + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR); + + return HAL_SD_ERROR_RX_OVERRUN; + } + else + { + /* No error flag set */ + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); + + *scr = (((tempscr[1] & SDMMC_0TO7BITS) << 24U) | ((tempscr[1] & SDMMC_8TO15BITS) << 8U) | \ + ((tempscr[1] & SDMMC_16TO23BITS) >> 8U) | ((tempscr[1] & SDMMC_24TO31BITS) >> 24U)); + scr++; + *scr = (((tempscr[0] & SDMMC_0TO7BITS) << 24U) | ((tempscr[0] & SDMMC_8TO15BITS) << 8U) | \ + ((tempscr[0] & SDMMC_16TO23BITS) >> 8U) | ((tempscr[0] & SDMMC_24TO31BITS) >> 24U)); + + } + + return HAL_SD_ERROR_NONE; +} + +/** + * @brief Wrap up reading in non-blocking mode. + * @param hsd: pointer to a SD_HandleTypeDef structure that contains + * the configuration information. + * @retval None + */ +static void SD_Read_IT(SD_HandleTypeDef *hsd) +{ + uint32_t count; + uint32_t data; + uint8_t *tmp; + + tmp = hsd->pRxBuffPtr; + + if (hsd->RxXferSize >= SDMMC_FIFO_SIZE) + { + /* Read data from SDMMC Rx FIFO */ + for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++) + { + data = SDMMC_ReadFIFO(hsd->Instance); + *tmp = (uint8_t)(data & 0xFFU); + tmp++; + *tmp = (uint8_t)((data >> 8U) & 0xFFU); + tmp++; + *tmp = (uint8_t)((data >> 16U) & 0xFFU); + tmp++; + *tmp = (uint8_t)((data >> 24U) & 0xFFU); + tmp++; + } + + hsd->pRxBuffPtr = tmp; + hsd->RxXferSize -= SDMMC_FIFO_SIZE; + } +} + +/** + * @brief Wrap up writing in non-blocking mode. + * @param hsd: pointer to a SD_HandleTypeDef structure that contains + * the configuration information. + * @retval None + */ +static void SD_Write_IT(SD_HandleTypeDef *hsd) +{ + uint32_t count; + uint32_t data; + const uint8_t *tmp; + + tmp = hsd->pTxBuffPtr; + + if (hsd->TxXferSize >= SDMMC_FIFO_SIZE) + { + /* Write data to SDMMC Tx FIFO */ + for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++) + { + data = (uint32_t)(*tmp); + tmp++; + data |= ((uint32_t)(*tmp) << 8U); + tmp++; + data |= ((uint32_t)(*tmp) << 16U); + tmp++; + data |= ((uint32_t)(*tmp) << 24U); + tmp++; + (void)SDMMC_WriteFIFO(hsd->Instance, &data); + } + + hsd->pTxBuffPtr = tmp; + hsd->TxXferSize -= SDMMC_FIFO_SIZE; + } +} + +/** + * @brief Switches the SD card to High Speed mode. + * This API must be used after "Transfer State" + * @note This operation should be followed by the configuration + * of PLL to have SDMMCCK clock between 25 and 50 MHz + * @param hsd: SD handle + * @param SwitchSpeedMode: SD speed mode( SDMMC_SDR12_SWITCH_PATTERN, SDMMC_SDR25_SWITCH_PATTERN) + * @retval SD Card error state + */ +uint32_t SD_SwitchSpeed(SD_HandleTypeDef *hsd, uint32_t SwitchSpeedMode) +{ + uint32_t errorstate = HAL_SD_ERROR_NONE; + SDMMC_DataInitTypeDef sdmmc_datainitstructure; + uint32_t SD_hs[16] = {0}; + uint32_t count; + uint32_t loop = 0 ; + uint32_t Timeout = HAL_GetTick(); + + if (hsd->SdCard.CardSpeed == CARD_NORMAL_SPEED) + { + /* Standard Speed Card <= 12.5Mhz */ + return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE; + } + + if (hsd->SdCard.CardSpeed >= CARD_HIGH_SPEED) + { + /* Initialize the Data control register */ + hsd->Instance->DCTRL = 0; + errorstate = SDMMC_CmdBlockLength(hsd->Instance, 64U); + + if (errorstate != HAL_SD_ERROR_NONE) + { + return errorstate; + } + + /* Configure the SD DPSM (Data Path State Machine) */ + sdmmc_datainitstructure.DataTimeOut = SDMMC_DATATIMEOUT; + sdmmc_datainitstructure.DataLength = 64U; + sdmmc_datainitstructure.DataBlockSize = SDMMC_DATABLOCK_SIZE_64B ; + sdmmc_datainitstructure.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + sdmmc_datainitstructure.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + sdmmc_datainitstructure.DPSM = SDMMC_DPSM_ENABLE; + + (void)SDMMC_ConfigData(hsd->Instance, &sdmmc_datainitstructure); + + + errorstate = SDMMC_CmdSwitch(hsd->Instance, SwitchSpeedMode); + if (errorstate != HAL_SD_ERROR_NONE) + { + return errorstate; + } + + while (!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND | + SDMMC_FLAG_DATAEND)) + { + if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF)) + { + for (count = 0U; count < 8U; count++) + { + SD_hs[(8U * loop) + count] = SDMMC_ReadFIFO(hsd->Instance); + } + loop ++; + } + + if ((HAL_GetTick() - Timeout) >= SDMMC_SWDATATIMEOUT) + { + hsd->ErrorCode = HAL_SD_ERROR_TIMEOUT; + hsd->State = HAL_SD_STATE_READY; + return HAL_SD_ERROR_TIMEOUT; + } + } + + if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT)) + { + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DTIMEOUT); + + return errorstate; + } + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL)) + { + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DCRCFAIL); + + errorstate = SDMMC_ERROR_DATA_CRC_FAIL; + + return errorstate; + } + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR)) + { + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR); + + errorstate = SDMMC_ERROR_RX_OVERRUN; + + return errorstate; + } + else + { + /* No error flag set */ + } + + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); + + /* Test if the switch mode HS is ok */ + if ((((uint8_t *)SD_hs)[13] & 2U) != 2U) + { + errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE; + } + + } + + return errorstate; +} + +#if (USE_SD_TRANSCEIVER != 0U) +/** + * @brief Switches the SD card to Ultra High Speed mode. + * This API must be used after "Transfer State" + * @note This operation should be followed by the configuration + * of PLL to have SDMMCCK clock between 50 and 120 MHz + * @param hsd: SD handle + * @param UltraHighSpeedMode: SD speed mode( SDMMC_SDR50_SWITCH_PATTERN, SDMMC_SDR104_SWITCH_PATTERN) + * @retval SD Card error state + */ +static uint32_t SD_UltraHighSpeed(SD_HandleTypeDef *hsd, uint32_t UltraHighSpeedMode) +{ + uint32_t errorstate = HAL_SD_ERROR_NONE; + SDMMC_DataInitTypeDef sdmmc_datainitstructure; + uint32_t SD_hs[16] = {0}; + uint32_t count; + uint32_t loop = 0 ; + uint32_t Timeout = HAL_GetTick(); + + if (hsd->SdCard.CardSpeed == CARD_NORMAL_SPEED) + { + /* Standard Speed Card <= 12.5Mhz */ + return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE; + } + + if (hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) + { + /* Initialize the Data control register */ + hsd->Instance->DCTRL = 0; + errorstate = SDMMC_CmdBlockLength(hsd->Instance, 64U); + + if (errorstate != HAL_SD_ERROR_NONE) + { + return errorstate; + } + + /* Configure the SD DPSM (Data Path State Machine) */ + sdmmc_datainitstructure.DataTimeOut = SDMMC_DATATIMEOUT; + sdmmc_datainitstructure.DataLength = 64U; + sdmmc_datainitstructure.DataBlockSize = SDMMC_DATABLOCK_SIZE_64B ; + sdmmc_datainitstructure.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + sdmmc_datainitstructure.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + sdmmc_datainitstructure.DPSM = SDMMC_DPSM_ENABLE; + + if (SDMMC_ConfigData(hsd->Instance, &sdmmc_datainitstructure) != HAL_OK) + { + return (HAL_SD_ERROR_GENERAL_UNKNOWN_ERR); + } + + errorstate = SDMMC_CmdSwitch(hsd->Instance, UltraHighSpeedMode); + if (errorstate != HAL_SD_ERROR_NONE) + { + return errorstate; + } + + while (!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND | + SDMMC_FLAG_DATAEND)) + { + if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF)) + { + for (count = 0U; count < 8U; count++) + { + SD_hs[(8U * loop) + count] = SDMMC_ReadFIFO(hsd->Instance); + } + loop ++; + } + + if ((HAL_GetTick() - Timeout) >= SDMMC_SWDATATIMEOUT) + { + hsd->ErrorCode = HAL_SD_ERROR_TIMEOUT; + hsd->State = HAL_SD_STATE_READY; + return HAL_SD_ERROR_TIMEOUT; + } + } + + if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT)) + { + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DTIMEOUT); + + return errorstate; + } + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL)) + { + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DCRCFAIL); + + errorstate = SDMMC_ERROR_DATA_CRC_FAIL; + + return errorstate; + } + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR)) + { + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR); + + errorstate = SDMMC_ERROR_RX_OVERRUN; + + return errorstate; + } + else + { + /* No error flag set */ + } + + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); + + /* Test if the switch mode HS is ok */ + if ((((uint8_t *)SD_hs)[13] & 2U) != 2U) + { + errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE; + } + else + { +#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U) + hsd->DriveTransceiver_1_8V_Callback(SET); +#else + HAL_SD_DriveTransceiver_1_8V_Callback(SET); +#endif /* USE_HAL_SD_REGISTER_CALLBACKS */ +#if defined (DLYB_SDMMC1) || defined (DLYB_SDMMC2) + /* Enable DelayBlock Peripheral */ + /* SDMMC_FB_CLK tuned feedback clock selected as receive clock, for SDR104 */ + MODIFY_REG(hsd->Instance->CLKCR, SDMMC_CLKCR_SELCLKRX, SDMMC_CLKCR_SELCLKRX_1); + LL_DLYB_Enable(SD_GET_DLYB_INSTANCE(hsd->Instance)); +#endif /* (DLYB_SDMMC1) || (DLYB_SDMMC2) */ + } + } + + return errorstate; +} + +/** + * @brief Switches the SD card to Double Data Rate (DDR) mode. + * This API must be used after "Transfer State" + * @note This operation should be followed by the configuration + * of PLL to have SDMMCCK clock less than 50MHz + * @param hsd: SD handle + * @retval SD Card error state + */ +static uint32_t SD_DDR_Mode(SD_HandleTypeDef *hsd) +{ + uint32_t errorstate = HAL_SD_ERROR_NONE; + SDMMC_DataInitTypeDef sdmmc_datainitstructure; + uint32_t SD_hs[16] = {0}; + uint32_t count; + uint32_t loop = 0 ; + uint32_t Timeout = HAL_GetTick(); + + if (hsd->SdCard.CardSpeed == CARD_NORMAL_SPEED) + { + /* Standard Speed Card <= 12.5Mhz */ + return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE; + } + + if (hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) + { + /* Initialize the Data control register */ + hsd->Instance->DCTRL = 0; + errorstate = SDMMC_CmdBlockLength(hsd->Instance, 64U); + + if (errorstate != HAL_SD_ERROR_NONE) + { + return errorstate; + } + + /* Configure the SD DPSM (Data Path State Machine) */ + sdmmc_datainitstructure.DataTimeOut = SDMMC_DATATIMEOUT; + sdmmc_datainitstructure.DataLength = 64U; + sdmmc_datainitstructure.DataBlockSize = SDMMC_DATABLOCK_SIZE_64B ; + sdmmc_datainitstructure.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + sdmmc_datainitstructure.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + sdmmc_datainitstructure.DPSM = SDMMC_DPSM_ENABLE; + + if (SDMMC_ConfigData(hsd->Instance, &sdmmc_datainitstructure) != HAL_OK) + { + return (HAL_SD_ERROR_GENERAL_UNKNOWN_ERR); + } + + errorstate = SDMMC_CmdSwitch(hsd->Instance, SDMMC_DDR50_SWITCH_PATTERN); + if (errorstate != HAL_SD_ERROR_NONE) + { + return errorstate; + } + + while (!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND | + SDMMC_FLAG_DATAEND)) + { + if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF)) + { + for (count = 0U; count < 8U; count++) + { + SD_hs[(8U * loop) + count] = SDMMC_ReadFIFO(hsd->Instance); + } + loop ++; + } + + if ((HAL_GetTick() - Timeout) >= SDMMC_SWDATATIMEOUT) + { + hsd->ErrorCode = HAL_SD_ERROR_TIMEOUT; + hsd->State = HAL_SD_STATE_READY; + return HAL_SD_ERROR_TIMEOUT; + } + } + + if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT)) + { + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DTIMEOUT); + + return errorstate; + } + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL)) + { + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DCRCFAIL); + + errorstate = SDMMC_ERROR_DATA_CRC_FAIL; + + return errorstate; + } + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR)) + { + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR); + + errorstate = SDMMC_ERROR_RX_OVERRUN; + + return errorstate; + } + else + { + /* No error flag set */ + } + + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); + + /* Test if the switch mode is ok */ + if ((((uint8_t *)SD_hs)[13] & 2U) != 2U) + { + errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE; + } + else + { +#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U) + hsd->DriveTransceiver_1_8V_Callback(SET); +#else + HAL_SD_DriveTransceiver_1_8V_Callback(SET); +#endif /* USE_HAL_SD_REGISTER_CALLBACKS */ +#if defined (DLYB_SDMMC1) || defined (DLYB_SDMMC2) + /* Enable DelayBlock Peripheral */ + /* SDMMC_CKin feedback clock selected as receive clock, for DDR50 */ + MODIFY_REG(hsd->Instance->CLKCR, SDMMC_CLKCR_SELCLKRX, SDMMC_CLKCR_SELCLKRX_0); + LL_DLYB_Enable(SD_GET_DLYB_INSTANCE(hsd->Instance)); +#endif /* (DLYB_SDMMC1) || (DLYB_SDMMC2) */ + } + } + + return errorstate; +} + +#endif /* USE_SD_TRANSCEIVER */ + +/** + * @brief Read DMA Linked list node Transfer completed callbacks + * @param hsd: SD handle + * @retval None + */ +__weak void HAL_SDEx_Read_DMALnkLstBufCpltCallback(SD_HandleTypeDef *hsd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SDEx_Read_DMALnkLstBufCpltCallback can be implemented in the user file + */ +} +/** + * @brief Read DMA Linked list node Transfer completed callbacks + * @param hsd: SD handle + * @retval None + */ +__weak void HAL_SDEx_Write_DMALnkLstBufCpltCallback(SD_HandleTypeDef *hsd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SDEx_Write_DMALnkLstBufCpltCallback can be implemented in the user file + */ +} + +/** + * @} + */ + +#endif /* HAL_SD_MODULE_ENABLED */ +#endif /* SDMMC1 || SDMMC2 */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sd_ex.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sd_ex.c new file mode 100644 index 0000000000..7689a0b70c --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sd_ex.c @@ -0,0 +1,393 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_sd_ex.c + * @author MCD Application Team + * @brief SD card Extended HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Secure Digital (SD) peripheral: + * + Extended features functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The SD Extension HAL driver can be used as follows: + (+) Configure Buffer0 and Buffer1 start address and Buffer size using HAL_SDEx_ConfigDMAMultiBuffer() function. + (+) Start Read and Write for multibuffer mode using HAL_SDEx_ReadBlocksDMAMultiBuffer() + and HAL_SDEx_WriteBlocksDMAMultiBuffer() functions. + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup SDEx SDEx + * @brief SD Extended HAL module driver + * @{ + */ + +#if defined (SDMMC1) || defined (SDMMC2) +#ifdef HAL_SD_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup SDEx_Exported_Functions + * @{ + */ + + +/** @addtogroup SDEx_Exported_Functions_Group1 + * @brief Linked List management functions + * +@verbatim + =============================================================================== + ##### Linked List management functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the needed functions. + +@endverbatim + * @{ + */ + +/** + * @brief Build Linked List node. + * @param pNode: Pointer to new node to add. + * @param pNodeConf: Pointer to configuration parameters for new node to add. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDEx_DMALinkedList_BuildNode(SD_DMALinkNodeTypeDef *pNode, SD_DMALinkNodeConfTypeDef *pNodeConf) +{ + + (void)SDMMC_DMALinkedList_BuildNode(pNode, pNodeConf); + + return (HAL_OK); + +} + +/** + * @brief Insert new Linked List node. + * @param pLinkedList: Pointer to the linkedlist that contains transfer nodes + * @param pPrevNode: Pointer to previous node. + * @param pNewNode: Pointer to new node to insert. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDEx_DMALinkedList_InsertNode(SD_DMALinkedListTypeDef *pLinkedList, + SD_DMALinkNodeTypeDef *pPrevNode, SD_DMALinkNodeTypeDef *pNewNode) +{ + + (void)SDMMC_DMALinkedList_InsertNode(pLinkedList, pPrevNode, pNewNode); + + return (HAL_OK); + +} +/** + * @brief Remove Linked List node. + * @param pLinkedList: Pointer to the linkedlist that contains transfer nodes + * @param pNode: Pointer to node to remove. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDEx_DMALinkedList_RemoveNode(SD_DMALinkedListTypeDef *pLinkedList, SD_DMALinkNodeTypeDef *pNode) +{ + + if (SDMMC_DMALinkedList_RemoveNode(pLinkedList, pNode) != SDMMC_ERROR_NONE) + { + return HAL_ERROR; + } + else + { + return HAL_OK; + } +} + +/** + * @brief Lock Linked List node. + * @param pNode: Pointer to node to remove. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDEx_DMALinkedList_LockNode(SD_DMALinkNodeTypeDef *pNode) +{ + + if (SDMMC_DMALinkedList_LockNode(pNode) != SDMMC_ERROR_NONE) + { + return HAL_ERROR; + } + else + { + return HAL_OK; + } +} + +/** + * @brief Unlock Linked List node. + * @param pNode: Pointer to node to remove. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDEx_DMALinkedList_UnlockNode(SD_DMALinkNodeTypeDef *pNode) +{ + + if (SDMMC_DMALinkedList_UnlockNode(pNode) != SDMMC_ERROR_NONE) + { + return HAL_ERROR; + } + else + { + return HAL_OK; + } +} + +/** + * @brief Enable Circular mode for DMA Linked List. + * @param pLinkedList: Pointer to the linkedlist that contains transfer nodes + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDEx_DMALinkedList_EnableCircularMode(SD_DMALinkedListTypeDef *pLinkedList) +{ + + (void)SDMMC_DMALinkedList_EnableCircularMode(pLinkedList); + + return HAL_OK; + +} +/** + * @brief Disable Circular mode for DMA Linked List. + * @param pLinkedList: Pointer to the linkedlist that contains transfer nodes + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDEx_DMALinkedList_DisableCircularMode(SD_DMALinkedListTypeDef *pLinkedList) +{ + + (void)SDMMC_DMALinkedList_DisableCircularMode(pLinkedList); + + return HAL_OK; + +} + + +/** + * @brief Reads block(s) from a specified address in a card. The received Data will be stored in linked list buffers. + * linked list should be prepared before call this function . + * @param hsd: SD handle + * @param pLinkedList: pointer to first linked list node + * @param BlockAdd: Block Address from where data is to be read + * @param NumberOfBlocks: Total number of blocks to read + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDEx_DMALinkedList_ReadBlocks(SD_HandleTypeDef *hsd, SDMMC_DMALinkedListTypeDef *pLinkedList, + uint32_t BlockAdd, uint32_t NumberOfBlocks) +{ + SDMMC_DataInitTypeDef config; + uint32_t errorstate; + uint32_t DmaBase0_reg; + uint32_t DmaBase1_reg; + uint32_t add = BlockAdd; + + if (hsd->State == HAL_SD_STATE_READY) + { + if ((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) + { + hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE; + return HAL_ERROR; + } + + hsd->Instance->IDMABASER = (uint32_t) pLinkedList->pHeadNode->IDMABASER; + hsd->Instance->IDMABSIZE = (uint32_t) pLinkedList->pHeadNode->IDMABSIZE; + + hsd->Instance->IDMABAR = (uint32_t) pLinkedList->pHeadNode; + hsd->Instance->IDMALAR = (uint32_t) SDMMC_IDMALAR_ABR | SDMMC_IDMALAR_ULS | SDMMC_IDMALAR_ULA | + sizeof(SDMMC_DMALinkNodeTypeDef) ; /* Initial configuration */ + + DmaBase0_reg = hsd->Instance->IDMABASER; + DmaBase1_reg = hsd->Instance->IDMABAR; + + if ((hsd->Instance->IDMABSIZE == 0U) || (DmaBase0_reg == 0U) || (DmaBase1_reg == 0U)) + { + hsd->ErrorCode = HAL_SD_ERROR_ADDR_OUT_OF_RANGE; + return HAL_ERROR; + } + + /* Initialize data control register */ + hsd->Instance->DCTRL = 0; + /* Clear old Flags*/ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); + + hsd->ErrorCode = HAL_SD_ERROR_NONE; + hsd->State = HAL_SD_STATE_BUSY; + + if (hsd->SdCard.CardType != CARD_SDHC_SDXC) + { + add *= 512U; + } + + /* Configure the SD DPSM (Data Path State Machine) */ + config.DataTimeOut = SDMMC_DATATIMEOUT; + config.DataLength = BLOCKSIZE * NumberOfBlocks; + config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; + config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + config.DPSM = SDMMC_DPSM_DISABLE; + (void)SDMMC_ConfigData(hsd->Instance, &config); + + hsd->Instance->DCTRL |= SDMMC_DCTRL_FIFORST; + + __SDMMC_CMDTRANS_ENABLE(hsd->Instance); + + hsd->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_DOUBLE_BUFF0; + + /* Read Blocks in DMA mode */ + hsd->Context = (SD_CONTEXT_READ_MULTIPLE_BLOCK | SD_CONTEXT_DMA); + + /* Read Multi Block command */ + errorstate = SDMMC_CmdReadMultiBlock(hsd->Instance, add); + if (errorstate != HAL_SD_ERROR_NONE) + { + hsd->State = HAL_SD_STATE_READY; + hsd->ErrorCode |= errorstate; + return HAL_ERROR; + } + + __HAL_SD_ENABLE_IT(hsd, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND | + SDMMC_IT_IDMABTC)); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } + +} + +/** + * @brief Write block(s) to a specified address in a card. The transferred Data are stored linked list nodes buffers . + * linked list should be prepared before call this function . + * @param hsd: SD handle + * @param pLinkedList: pointer to first linked list node + * @param BlockAdd: Block Address from where data is to be read + * @param NumberOfBlocks: Total number of blocks to read + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDEx_DMALinkedList_WriteBlocks(SD_HandleTypeDef *hsd, SDMMC_DMALinkedListTypeDef *pLinkedList, + uint32_t BlockAdd, uint32_t NumberOfBlocks) + +{ + SDMMC_DataInitTypeDef config; + uint32_t errorstate; + uint32_t DmaBase0_reg; + uint32_t DmaBase1_reg; + uint32_t add = BlockAdd; + + if (hsd->State == HAL_SD_STATE_READY) + { + if ((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) + { + hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE; + return HAL_ERROR; + } + + hsd->Instance->IDMABASER = (uint32_t) pLinkedList->pHeadNode->IDMABASER; + hsd->Instance->IDMABSIZE = (uint32_t) pLinkedList->pHeadNode->IDMABSIZE; + + hsd->Instance->IDMABAR = (uint32_t) pLinkedList->pHeadNode; + hsd->Instance->IDMALAR = (uint32_t) SDMMC_IDMALAR_ABR | SDMMC_IDMALAR_ULS | SDMMC_IDMALAR_ULA | + sizeof(SDMMC_DMALinkNodeTypeDef) ; /* Initial configuration */ + + DmaBase0_reg = hsd->Instance->IDMABASER; + DmaBase1_reg = hsd->Instance->IDMABAR; + + if ((hsd->Instance->IDMABSIZE == 0U) || (DmaBase0_reg == 0U) || (DmaBase1_reg == 0U)) + { + hsd->ErrorCode = HAL_SD_ERROR_ADDR_OUT_OF_RANGE; + return HAL_ERROR; + } + + /* Initialize data control register */ + hsd->Instance->DCTRL = 0; + + hsd->ErrorCode = HAL_SD_ERROR_NONE; + + hsd->State = HAL_SD_STATE_BUSY; + + if (hsd->SdCard.CardType != CARD_SDHC_SDXC) + { + add *= 512U; + } + + /* Configure the SD DPSM (Data Path State Machine) */ + config.DataTimeOut = SDMMC_DATATIMEOUT; + config.DataLength = BLOCKSIZE * NumberOfBlocks; + config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; + config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD; + config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + config.DPSM = SDMMC_DPSM_DISABLE; + (void)SDMMC_ConfigData(hsd->Instance, &config); + + __SDMMC_CMDTRANS_ENABLE(hsd->Instance); + + hsd->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_DOUBLE_BUFF0; + + /* Write Blocks in DMA mode */ + hsd->Context = (SD_CONTEXT_WRITE_MULTIPLE_BLOCK | SD_CONTEXT_DMA); + + /* Write Multi Block command */ + errorstate = SDMMC_CmdWriteMultiBlock(hsd->Instance, add); + if (errorstate != HAL_SD_ERROR_NONE) + { + hsd->State = HAL_SD_STATE_READY; + hsd->ErrorCode |= errorstate; + return HAL_ERROR; + } + + __HAL_SD_ENABLE_IT(hsd, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND | + SDMMC_IT_IDMABTC)); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_SD_MODULE_ENABLED */ +#endif /* SDMMC1 || SDMMC2 */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sdram.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sdram.c new file mode 100644 index 0000000000..16e05f8df7 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sdram.c @@ -0,0 +1,1431 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_sdram.c + * @author MCD Application Team + * @brief SDRAM HAL module driver. + * This file provides a generic firmware to drive SDRAM memories mounted + * as external device. + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2022 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 ##### + ============================================================================== + [..] + This driver is a generic layered driver which contains a set of APIs used to + control SDRAM memories. It uses the FMC layer functions to interface + with SDRAM devices. + The following sequence should be followed to configure the FMC to interface + with SDRAM memories: + + (#) Declare a SDRAM_HandleTypeDef handle structure, for example: + SDRAM_HandleTypeDef hsdram + + (++) Fill the SDRAM_HandleTypeDef handle "Init" field with the allowed + values of the structure member. + + (++) Fill the SDRAM_HandleTypeDef handle "Instance" field with a predefined + base register instance for NOR or SDRAM device + + (#) Declare a FMC_SDRAM_TimingTypeDef structure; for example: + FMC_SDRAM_TimingTypeDef Timing; + and fill its fields with the allowed values of the structure member. + + (#) Initialize the SDRAM Controller by calling the function HAL_SDRAM_Init(). This function + performs the following sequence: + + (##) MSP hardware layer configuration using the function HAL_SDRAM_MspInit() + (##) Control register configuration using the FMC SDRAM interface function + FMC_SDRAM_Init() + (##) Timing register configuration using the FMC SDRAM interface function + FMC_SDRAM_Timing_Init() + (##) Program the SDRAM external device by applying its initialization sequence + according to the device plugged in your hardware. This step is mandatory + for accessing the SDRAM device. + + (#) At this stage you can perform read/write accesses from/to the memory connected + to the SDRAM Bank. You can perform either polling or DMA transfer using the + following APIs: + (++) HAL_SDRAM_Read()/HAL_SDRAM_Write() for polling read/write access + (++) HAL_SDRAM_Read_DMA()/HAL_SDRAM_Write_DMA() for DMA read/write transfer + + (#) You can also control the SDRAM device by calling the control APIs HAL_SDRAM_WriteOperation_Enable()/ + HAL_SDRAM_WriteOperation_Disable() to respectively enable/disable the SDRAM write operation or + the function HAL_SDRAM_SendCommand() to send a specified command to the SDRAM + device. The command to be sent must be configured with the FMC_SDRAM_CommandTypeDef + structure. + + (#) You can continuously monitor the SDRAM device HAL state by calling the function + HAL_SDRAM_GetState() + + *** Callback registration *** + ============================================= + [..] + The compilation define USE_HAL_SDRAM_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + + Use Functions HAL_SDRAM_RegisterCallback() to register a user callback, + it allows to register following callbacks: + (+) MspInitCallback : SDRAM MspInit. + (+) MspDeInitCallback : SDRAM MspDeInit. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + + Use function HAL_SDRAM_UnRegisterCallback() to reset a callback to the default + weak (overridden) function. It allows to reset following callbacks: + (+) MspInitCallback : SDRAM MspInit. + (+) MspDeInitCallback : SDRAM MspDeInit. + This function) takes as parameters the HAL peripheral handle and the Callback ID. + + By default, after the HAL_SDRAM_Init and if the state is HAL_SDRAM_STATE_RESET + all callbacks are reset to the corresponding legacy weak (overridden) functions. + Exception done for MspInit and MspDeInit callbacks that are respectively + reset to the legacy weak (overridden) functions in the HAL_SDRAM_Init + and HAL_SDRAM_DeInit only when these callbacks are null (not registered beforehand). + If not, MspInit or MspDeInit are not null, the HAL_SDRAM_Init and HAL_SDRAM_DeInit + keep and use the user MspInit/MspDeInit callbacks (registered beforehand) + + Callbacks can be registered/unregistered in READY state only. + Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered + in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used + during the Init/DeInit. + In that case first register the MspInit/MspDeInit user callbacks + using HAL_SDRAM_RegisterCallback before calling HAL_SDRAM_DeInit + or HAL_SDRAM_Init function. + + When The compilation define USE_HAL_SDRAM_REGISTER_CALLBACKS is set to 0 or + not defined, the callback registering feature is not available + and weak (overridden) callbacks are used. + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +#if defined(FMC_Bank5_6_R) + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + +/** @defgroup SDRAM SDRAM + * @brief SDRAM driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup SDRAM_Private_Functions SDRAM Private Functions + * @{ + */ +static void SDRAM_DMACplt(DMA_HandleTypeDef *hdma); +static void SDRAM_DMACpltProt(DMA_HandleTypeDef *hdma); +static void SDRAM_DMAError(DMA_HandleTypeDef *hdma); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup SDRAM_Exported_Functions SDRAM Exported Functions + * @{ + */ + +/** @defgroup SDRAM_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * + @verbatim + ============================================================================== + ##### SDRAM Initialization and de_initialization functions ##### + ============================================================================== + [..] + This section provides functions allowing to initialize/de-initialize + the SDRAM memory + +@endverbatim + * @{ + */ + +/** + * @brief Performs the SDRAM device initialization sequence. + * @param hsdram pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @param Timing Pointer to SDRAM control timing structure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_Init(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_TimingTypeDef *Timing) +{ + /* Check the SDRAM handle parameter */ + if (hsdram == NULL) + { + return HAL_ERROR; + } + + if (hsdram->State == HAL_SDRAM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hsdram->Lock = HAL_UNLOCKED; +#if (USE_HAL_SDRAM_REGISTER_CALLBACKS == 1) + if (hsdram->MspInitCallback == NULL) + { + hsdram->MspInitCallback = HAL_SDRAM_MspInit; + } + hsdram->RefreshErrorCallback = HAL_SDRAM_RefreshErrorCallback; + hsdram->DmaXferCpltCallback = HAL_SDRAM_DMA_XferCpltCallback; + hsdram->DmaXferErrorCallback = HAL_SDRAM_DMA_XferErrorCallback; + + /* Init the low level hardware */ + hsdram->MspInitCallback(hsdram); +#else + /* Initialize the low level hardware (MSP) */ + HAL_SDRAM_MspInit(hsdram); +#endif /* USE_HAL_SDRAM_REGISTER_CALLBACKS */ + } + + /* Initialize the SDRAM controller state */ + hsdram->State = HAL_SDRAM_STATE_BUSY; + + /* Initialize SDRAM control Interface */ + (void)FMC_SDRAM_Init(hsdram->Instance, &(hsdram->Init)); + + /* Initialize SDRAM timing Interface */ + (void)FMC_SDRAM_Timing_Init(hsdram->Instance, Timing, hsdram->Init.SDBank); + + /* Enable FMC Peripheral */ + __FMC_ENABLE(); + /* Update the SDRAM controller state */ + hsdram->State = HAL_SDRAM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Perform the SDRAM device initialization sequence. + * @param hsdram pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_DeInit(SDRAM_HandleTypeDef *hsdram) +{ +#if (USE_HAL_SDRAM_REGISTER_CALLBACKS == 1) + if (hsdram->MspDeInitCallback == NULL) + { + hsdram->MspDeInitCallback = HAL_SDRAM_MspDeInit; + } + + /* DeInit the low level hardware */ + hsdram->MspDeInitCallback(hsdram); +#else + /* Initialize the low level hardware (MSP) */ + HAL_SDRAM_MspDeInit(hsdram); +#endif /* USE_HAL_SDRAM_REGISTER_CALLBACKS */ + + /* Configure the SDRAM registers with their reset values */ + (void)FMC_SDRAM_DeInit(hsdram->Instance, hsdram->Init.SDBank); + + /* Reset the SDRAM controller state */ + hsdram->State = HAL_SDRAM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hsdram); + + return HAL_OK; +} + +/** + * @brief SDRAM MSP Init. + * @param hsdram pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @retval None + */ +__weak void HAL_SDRAM_MspInit(SDRAM_HandleTypeDef *hsdram) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsdram); + + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_SDRAM_MspInit could be implemented in the user file + */ +} + +/** + * @brief SDRAM MSP DeInit. + * @param hsdram pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @retval None + */ +__weak void HAL_SDRAM_MspDeInit(SDRAM_HandleTypeDef *hsdram) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsdram); + + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_SDRAM_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief This function handles SDRAM refresh error interrupt request. + * @param hsdram pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @retval HAL status + */ +void HAL_SDRAM_IRQHandler(SDRAM_HandleTypeDef *hsdram) +{ + /* Check SDRAM interrupt Rising edge flag */ + if (__FMC_SDRAM_GET_FLAG(hsdram->Instance, FMC_SDRAM_FLAG_REFRESH_IT)) + { + /* SDRAM refresh error interrupt callback */ +#if (USE_HAL_SDRAM_REGISTER_CALLBACKS == 1) + hsdram->RefreshErrorCallback(hsdram); +#else + HAL_SDRAM_RefreshErrorCallback(hsdram); +#endif /* USE_HAL_SDRAM_REGISTER_CALLBACKS */ + + /* Clear SDRAM refresh error interrupt pending bit */ + __FMC_SDRAM_CLEAR_FLAG(hsdram->Instance, FMC_SDRAM_FLAG_REFRESH_ERROR); + } +} + +/** + * @brief SDRAM Refresh error callback. + * @param hsdram pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @retval None + */ +__weak void HAL_SDRAM_RefreshErrorCallback(SDRAM_HandleTypeDef *hsdram) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsdram); + + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_SDRAM_RefreshErrorCallback could be implemented in the user file + */ +} + +/** + * @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 + */ +__weak void HAL_SDRAM_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdma); + + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_SDRAM_DMA_XferCpltCallback could be implemented in the user file + */ +} + +/** + * @brief DMA transfer complete error callback. + * @param hdma DMA handle + * @retval None + */ +__weak void HAL_SDRAM_DMA_XferErrorCallback(DMA_HandleTypeDef *hdma) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdma); + + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_SDRAM_DMA_XferErrorCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup SDRAM_Exported_Functions_Group2 Input and Output functions + * @brief Input Output and memory control functions + * + @verbatim + ============================================================================== + ##### SDRAM Input and Output functions ##### + ============================================================================== + [..] + This section provides functions allowing to use and control the SDRAM memory + +@endverbatim + * @{ + */ + +/** + * @brief Reads 8-bit data buffer from the SDRAM memory. + * @param hsdram pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @param pAddress Pointer to read start address + * @param pDstBuffer Pointer to destination buffer + * @param BufferSize Size of the buffer to read from memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_Read_8b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint8_t *pDstBuffer, + uint32_t BufferSize) +{ + uint32_t size; + __IO uint8_t *pSdramAddress = (uint8_t *)pAddress; + uint8_t *pdestbuff = pDstBuffer; + HAL_SDRAM_StateTypeDef state = hsdram->State; + + /* Check the SDRAM controller state */ + if (state == HAL_SDRAM_STATE_BUSY) + { + return HAL_BUSY; + } + else if ((state == HAL_SDRAM_STATE_READY) || (state == HAL_SDRAM_STATE_WRITE_PROTECTED)) + { + /* Process Locked */ + __HAL_LOCK(hsdram); + + /* Update the SDRAM controller state */ + hsdram->State = HAL_SDRAM_STATE_BUSY; + + /* Read data from source */ + for (size = BufferSize; size != 0U; size--) + { + *pdestbuff = *(__IO uint8_t *)pSdramAddress; + pdestbuff++; + pSdramAddress++; + } + + /* Update the SDRAM controller state */ + hsdram->State = state; + + /* Process Unlocked */ + __HAL_UNLOCK(hsdram); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Writes 8-bit data buffer to SDRAM memory. + * @param hsdram pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @param pAddress Pointer to write start address + * @param pSrcBuffer Pointer to source buffer to write + * @param BufferSize Size of the buffer to write to memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_Write_8b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint8_t *pSrcBuffer, + uint32_t BufferSize) +{ + uint32_t size; + __IO uint8_t *pSdramAddress = (uint8_t *)pAddress; + uint8_t *psrcbuff = pSrcBuffer; + + /* Check the SDRAM controller state */ + if (hsdram->State == HAL_SDRAM_STATE_BUSY) + { + return HAL_BUSY; + } + else if (hsdram->State == HAL_SDRAM_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsdram); + + /* Update the SDRAM controller state */ + hsdram->State = HAL_SDRAM_STATE_BUSY; + + /* Write data to memory */ + for (size = BufferSize; size != 0U; size--) + { + *(__IO uint8_t *)pSdramAddress = *psrcbuff; + psrcbuff++; + pSdramAddress++; + } + + /* Update the SDRAM controller state */ + hsdram->State = HAL_SDRAM_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsdram); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Reads 16-bit data buffer from the SDRAM memory. + * @param hsdram pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @param pAddress Pointer to read start address + * @param pDstBuffer Pointer to destination buffer + * @param BufferSize Size of the buffer to read from memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_Read_16b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint16_t *pDstBuffer, + uint32_t BufferSize) +{ + uint32_t size; + __IO uint32_t *pSdramAddress = pAddress; + uint16_t *pdestbuff = pDstBuffer; + HAL_SDRAM_StateTypeDef state = hsdram->State; + + /* Check the SDRAM controller state */ + if (state == HAL_SDRAM_STATE_BUSY) + { + return HAL_BUSY; + } + else if ((state == HAL_SDRAM_STATE_READY) || (state == HAL_SDRAM_STATE_WRITE_PROTECTED)) + { + /* Process Locked */ + __HAL_LOCK(hsdram); + + /* Update the SDRAM controller state */ + hsdram->State = HAL_SDRAM_STATE_BUSY; + + /* Read data from memory */ + for (size = BufferSize; size >= 2U ; size -= 2U) + { + *pdestbuff = (uint16_t)((*pSdramAddress) & 0x0000FFFFU); + pdestbuff++; + *pdestbuff = (uint16_t)(((*pSdramAddress) & 0xFFFF0000U) >> 16U); + pdestbuff++; + pSdramAddress++; + } + + /* Read last 16-bits if size is not 32-bits multiple */ + if ((BufferSize % 2U) != 0U) + { + *pdestbuff = (uint16_t)((*pSdramAddress) & 0x0000FFFFU); + } + + /* Update the SDRAM controller state */ + hsdram->State = state; + + /* Process Unlocked */ + __HAL_UNLOCK(hsdram); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Writes 16-bit data buffer to SDRAM memory. + * @param hsdram pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @param pAddress Pointer to write start address + * @param pSrcBuffer Pointer to source buffer to write + * @param BufferSize Size of the buffer to write to memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_Write_16b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint16_t *pSrcBuffer, + uint32_t BufferSize) +{ + uint32_t size; + __IO uint32_t *psdramaddress = pAddress; + uint16_t *psrcbuff = pSrcBuffer; + + /* Check the SDRAM controller state */ + if (hsdram->State == HAL_SDRAM_STATE_BUSY) + { + return HAL_BUSY; + } + else if (hsdram->State == HAL_SDRAM_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsdram); + + /* Update the SDRAM controller state */ + hsdram->State = HAL_SDRAM_STATE_BUSY; + + /* Write data to memory */ + for (size = BufferSize; size >= 2U ; size -= 2U) + { + *psdramaddress = (uint32_t)(*psrcbuff); + psrcbuff++; + *psdramaddress |= ((uint32_t)(*psrcbuff) << 16U); + psrcbuff++; + psdramaddress++; + } + + /* Write last 16-bits if size is not 32-bits multiple */ + if ((BufferSize % 2U) != 0U) + { + *psdramaddress = ((uint32_t)(*psrcbuff) & 0x0000FFFFU) | ((*psdramaddress) & 0xFFFF0000U); + } + + /* Update the SDRAM controller state */ + hsdram->State = HAL_SDRAM_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsdram); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Reads 32-bit data buffer from the SDRAM memory. + * @param hsdram pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @param pAddress Pointer to read start address + * @param pDstBuffer Pointer to destination buffer + * @param BufferSize Size of the buffer to read from memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_Read_32b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint32_t *pDstBuffer, + uint32_t BufferSize) +{ + uint32_t size; + __IO uint32_t *pSdramAddress = (uint32_t *)pAddress; + uint32_t *pdestbuff = pDstBuffer; + HAL_SDRAM_StateTypeDef state = hsdram->State; + + /* Check the SDRAM controller state */ + if (state == HAL_SDRAM_STATE_BUSY) + { + return HAL_BUSY; + } + else if ((state == HAL_SDRAM_STATE_READY) || (state == HAL_SDRAM_STATE_WRITE_PROTECTED)) + { + /* Process Locked */ + __HAL_LOCK(hsdram); + + /* Update the SDRAM controller state */ + hsdram->State = HAL_SDRAM_STATE_BUSY; + + /* Read data from source */ + for (size = BufferSize; size != 0U; size--) + { + *pdestbuff = *(__IO uint32_t *)pSdramAddress; + pdestbuff++; + pSdramAddress++; + } + + /* Update the SDRAM controller state */ + hsdram->State = state; + + /* Process Unlocked */ + __HAL_UNLOCK(hsdram); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Writes 32-bit data buffer to SDRAM memory. + * @param hsdram pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @param pAddress Pointer to write start address + * @param pSrcBuffer Pointer to source buffer to write + * @param BufferSize Size of the buffer to write to memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_Write_32b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint32_t *pSrcBuffer, + uint32_t BufferSize) +{ + uint32_t size; + __IO uint32_t *pSdramAddress = pAddress; + uint32_t *psrcbuff = pSrcBuffer; + + /* Check the SDRAM controller state */ + if (hsdram->State == HAL_SDRAM_STATE_BUSY) + { + return HAL_BUSY; + } + else if (hsdram->State == HAL_SDRAM_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsdram); + + /* Update the SDRAM controller state */ + hsdram->State = HAL_SDRAM_STATE_BUSY; + + /* Write data to memory */ + for (size = BufferSize; size != 0U; size--) + { + *pSdramAddress = *psrcbuff; + psrcbuff++; + pSdramAddress++; + } + + /* Update the SDRAM controller state */ + hsdram->State = HAL_SDRAM_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsdram); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Reads a Words data from the SDRAM memory using DMA transfer. + * @param hsdram pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @param pAddress Pointer to read start address + * @param pDstBuffer Pointer to destination buffer + * @param BufferSize Size of the buffer to read from memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_Read_DMA(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint32_t *pDstBuffer, + uint32_t BufferSize) +{ + HAL_StatusTypeDef status; + HAL_SDRAM_StateTypeDef state = hsdram->State; + uint32_t size; + uint32_t data_width; + + /* Check the SDRAM controller state */ + if (state == HAL_SDRAM_STATE_BUSY) + { + status = HAL_BUSY; + } + else if ((state == HAL_SDRAM_STATE_READY) || (state == HAL_SDRAM_STATE_WRITE_PROTECTED)) + { + /* Process Locked */ + __HAL_LOCK(hsdram); + + /* Update the SDRAM controller state */ + hsdram->State = HAL_SDRAM_STATE_BUSY; + + /* Configure DMA user callbacks */ + if (state == HAL_SDRAM_STATE_READY) + { + hsdram->hdma->XferCpltCallback = SDRAM_DMACplt; + } + else + { + hsdram->hdma->XferCpltCallback = SDRAM_DMACpltProt; + } + hsdram->hdma->XferErrorCallback = SDRAM_DMAError; + + if ((hsdram->hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hsdram->hdma->LinkedListQueue != 0U) && (hsdram->hdma->LinkedListQueue->Head != 0U)) + { + /* Check destination data width and set the size to be transferred */ + data_width = hsdram->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] & DMA_CTR1_DDW_LOG2; + + if (data_width == DMA_DEST_DATAWIDTH_WORD) + { + size = (BufferSize * 4U); + } + else if (data_width == DMA_DEST_DATAWIDTH_HALFWORD) + { + size = (BufferSize * 2U); + } + else + { + size = (BufferSize); + } + /* Set Source , destination , buffer size */ + /* Set DMA data size */ + hsdram->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = size; + /* Set DMA source address */ + hsdram->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)pAddress; + /* Set DMA destination address */ + hsdram->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)pDstBuffer; + + /* Enable the DMA Stream */ + status = HAL_DMAEx_List_Start_IT(hsdram->hdma); + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hsdram); + + status = HAL_ERROR; + } + } + else + { + /* Check destination data width and set the size to be transferred */ + data_width = hsdram->hdma->Init.DestDataWidth; + + if (data_width == DMA_DEST_DATAWIDTH_WORD) + { + size = (BufferSize * 4U); + } + else if (data_width == DMA_DEST_DATAWIDTH_HALFWORD) + { + size = (BufferSize * 2U); + } + else + { + size = (BufferSize); + } + + /* Enable the DMA Stream */ + status = HAL_DMA_Start_IT(hsdram->hdma, (uint32_t)pAddress, (uint32_t)pDstBuffer, size); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hsdram); + } + else + { + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Writes a Words data buffer to SDRAM memory using DMA transfer. + * @param hsdram pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @param pAddress Pointer to write start address + * @param pSrcBuffer Pointer to source buffer to write + * @param BufferSize Size of the buffer to write to memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_Write_DMA(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint32_t *pSrcBuffer, + uint32_t BufferSize) +{ + HAL_StatusTypeDef status; + uint32_t size; + uint32_t data_width; + + /* Check the SDRAM controller state */ + if (hsdram->State == HAL_SDRAM_STATE_BUSY) + { + status = HAL_BUSY; + } + else if (hsdram->State == HAL_SDRAM_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsdram); + + /* Update the SDRAM controller state */ + hsdram->State = HAL_SDRAM_STATE_BUSY; + + /* Configure DMA user callbacks */ + hsdram->hdma->XferCpltCallback = SDRAM_DMACplt; + hsdram->hdma->XferErrorCallback = SDRAM_DMAError; + + if ((hsdram->hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hsdram->hdma->LinkedListQueue != 0U) && (hsdram->hdma->LinkedListQueue->Head != 0U)) + { + /* Check destination data width and set the size to be transferred */ + data_width = hsdram->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] & DMA_CTR1_DDW_LOG2; + + if (data_width == DMA_DEST_DATAWIDTH_WORD) + { + size = (BufferSize * 4U); + } + else if (data_width == DMA_DEST_DATAWIDTH_HALFWORD) + { + size = (BufferSize * 2U); + } + else + { + size = (BufferSize); + } + /* Set Source , destination , buffer size */ + /* Set DMA data size */ + hsdram->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = size; + /* Set DMA source address */ + hsdram->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)pSrcBuffer; + /* Set DMA destination address */ + hsdram->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)pAddress; + + /* Enable the DMA Stream */ + status = HAL_DMAEx_List_Start_IT(hsdram->hdma); + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hsdram); + + status = HAL_ERROR; + } + } + else + { + /* Check destination data width and set the size to be transferred */ + data_width = hsdram->hdma->Init.DestDataWidth; + + if (data_width == DMA_DEST_DATAWIDTH_WORD) + { + size = (BufferSize * 4U); + } + else if (data_width == DMA_DEST_DATAWIDTH_HALFWORD) + { + size = (BufferSize * 2U); + } + else + { + size = (BufferSize); + } + + /* Enable the DMA Stream */ + status = HAL_DMA_Start_IT(hsdram->hdma, (uint32_t)pSrcBuffer, (uint32_t)pAddress, size); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hsdram); + } + else + { + status = HAL_ERROR; + } + + return status; +} + +#if (USE_HAL_SDRAM_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User SDRAM Callback + * To be used to override the weak predefined callback + * @param hsdram : SDRAM handle + * @param CallbackId : ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_SDRAM_MSP_INIT_CB_ID SDRAM MspInit callback ID + * @arg @ref HAL_SDRAM_MSP_DEINIT_CB_ID SDRAM MspDeInit callback ID + * @arg @ref HAL_SDRAM_REFRESH_ERR_CB_ID SDRAM Refresh Error callback ID + * @param pCallback : pointer to the Callback function + * @retval status + */ +HAL_StatusTypeDef HAL_SDRAM_RegisterCallback(SDRAM_HandleTypeDef *hsdram, HAL_SDRAM_CallbackIDTypeDef CallbackId, + pSDRAM_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + HAL_SDRAM_StateTypeDef state; + + if (pCallback == NULL) + { + return HAL_ERROR; + } + + state = hsdram->State; + if ((state == HAL_SDRAM_STATE_READY) || (state == HAL_SDRAM_STATE_WRITE_PROTECTED)) + { + switch (CallbackId) + { + case HAL_SDRAM_MSP_INIT_CB_ID : + hsdram->MspInitCallback = pCallback; + break; + case HAL_SDRAM_MSP_DEINIT_CB_ID : + hsdram->MspDeInitCallback = pCallback; + break; + case HAL_SDRAM_REFRESH_ERR_CB_ID : + hsdram->RefreshErrorCallback = pCallback; + break; + default : + /* update return status */ + status = HAL_ERROR; + break; + } + } + else if (hsdram->State == HAL_SDRAM_STATE_RESET) + { + switch (CallbackId) + { + case HAL_SDRAM_MSP_INIT_CB_ID : + hsdram->MspInitCallback = pCallback; + break; + case HAL_SDRAM_MSP_DEINIT_CB_ID : + hsdram->MspDeInitCallback = pCallback; + break; + default : + /* update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* update return status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister a User SDRAM Callback + * SDRAM Callback is redirected to the weak predefined callback + * @param hsdram : SDRAM handle + * @param CallbackId : ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_SDRAM_MSP_INIT_CB_ID SDRAM MspInit callback ID + * @arg @ref HAL_SDRAM_MSP_DEINIT_CB_ID SDRAM MspDeInit callback ID + * @arg @ref HAL_SDRAM_REFRESH_ERR_CB_ID SDRAM Refresh Error callback ID + * @arg @ref HAL_SDRAM_DMA_XFER_CPLT_CB_ID SDRAM DMA Xfer Complete callback ID + * @arg @ref HAL_SDRAM_DMA_XFER_ERR_CB_ID SDRAM DMA Xfer Error callback ID + * @retval status + */ +HAL_StatusTypeDef HAL_SDRAM_UnRegisterCallback(SDRAM_HandleTypeDef *hsdram, HAL_SDRAM_CallbackIDTypeDef CallbackId) +{ + HAL_StatusTypeDef status = HAL_OK; + HAL_SDRAM_StateTypeDef state; + + state = hsdram->State; + if ((state == HAL_SDRAM_STATE_READY) || (state == HAL_SDRAM_STATE_WRITE_PROTECTED)) + { + switch (CallbackId) + { + case HAL_SDRAM_MSP_INIT_CB_ID : + hsdram->MspInitCallback = HAL_SDRAM_MspInit; + break; + case HAL_SDRAM_MSP_DEINIT_CB_ID : + hsdram->MspDeInitCallback = HAL_SDRAM_MspDeInit; + break; + case HAL_SDRAM_REFRESH_ERR_CB_ID : + hsdram->RefreshErrorCallback = HAL_SDRAM_RefreshErrorCallback; + break; + case HAL_SDRAM_DMA_XFER_CPLT_CB_ID : + hsdram->DmaXferCpltCallback = HAL_SDRAM_DMA_XferCpltCallback; + break; + case HAL_SDRAM_DMA_XFER_ERR_CB_ID : + hsdram->DmaXferErrorCallback = HAL_SDRAM_DMA_XferErrorCallback; + break; + default : + /* update return status */ + status = HAL_ERROR; + break; + } + } + else if (hsdram->State == HAL_SDRAM_STATE_RESET) + { + switch (CallbackId) + { + case HAL_SDRAM_MSP_INIT_CB_ID : + hsdram->MspInitCallback = HAL_SDRAM_MspInit; + break; + case HAL_SDRAM_MSP_DEINIT_CB_ID : + hsdram->MspDeInitCallback = HAL_SDRAM_MspDeInit; + break; + default : + /* update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* update return status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Register a User SDRAM Callback for DMA transfers + * To be used to override the weak predefined callback + * @param hsdram : SDRAM handle + * @param CallbackId : ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_SDRAM_DMA_XFER_CPLT_CB_ID SDRAM DMA Xfer Complete callback ID + * @arg @ref HAL_SDRAM_DMA_XFER_ERR_CB_ID SDRAM DMA Xfer Error callback ID + * @param pCallback : pointer to the Callback function + * @retval status + */ +HAL_StatusTypeDef HAL_SDRAM_RegisterDmaCallback(SDRAM_HandleTypeDef *hsdram, HAL_SDRAM_CallbackIDTypeDef CallbackId, + pSDRAM_DmaCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + HAL_SDRAM_StateTypeDef state; + + if (pCallback == NULL) + { + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hsdram); + + state = hsdram->State; + if ((state == HAL_SDRAM_STATE_READY) || (state == HAL_SDRAM_STATE_WRITE_PROTECTED)) + { + switch (CallbackId) + { + case HAL_SDRAM_DMA_XFER_CPLT_CB_ID : + hsdram->DmaXferCpltCallback = pCallback; + break; + case HAL_SDRAM_DMA_XFER_ERR_CB_ID : + hsdram->DmaXferErrorCallback = pCallback; + break; + default : + /* update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* update return status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hsdram); + return status; +} +#endif /* USE_HAL_SDRAM_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup SDRAM_Exported_Functions_Group3 Control functions + * @brief management functions + * +@verbatim + ============================================================================== + ##### SDRAM Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control dynamically + the SDRAM interface. + +@endverbatim + * @{ + */ + +/** + * @brief Enables dynamically SDRAM write protection. + * @param hsdram pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_WriteProtection_Enable(SDRAM_HandleTypeDef *hsdram) +{ + /* Check the SDRAM controller state */ + if (hsdram->State == HAL_SDRAM_STATE_BUSY) + { + return HAL_BUSY; + } + else if (hsdram->State == HAL_SDRAM_STATE_READY) + { + /* Update the SDRAM state */ + hsdram->State = HAL_SDRAM_STATE_BUSY; + + /* Enable write protection */ + (void)FMC_SDRAM_WriteProtection_Enable(hsdram->Instance, hsdram->Init.SDBank); + + /* Update the SDRAM state */ + hsdram->State = HAL_SDRAM_STATE_WRITE_PROTECTED; + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Disables dynamically SDRAM write protection. + * @param hsdram pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_WriteProtection_Disable(SDRAM_HandleTypeDef *hsdram) +{ + HAL_SDRAM_StateTypeDef state = hsdram->State; + + /* Check the SDRAM controller state */ + if (state == HAL_SDRAM_STATE_BUSY) + { + return HAL_BUSY; + } + else if (state == HAL_SDRAM_STATE_WRITE_PROTECTED) + { + /* Update the SDRAM state */ + hsdram->State = HAL_SDRAM_STATE_BUSY; + + /* Disable write protection */ + (void)FMC_SDRAM_WriteProtection_Disable(hsdram->Instance, hsdram->Init.SDBank); + + /* Update the SDRAM state */ + hsdram->State = HAL_SDRAM_STATE_READY; + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Sends Command to the SDRAM bank. + * @param hsdram pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @param Command SDRAM command structure + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_SendCommand(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command, + uint32_t Timeout) +{ + HAL_SDRAM_StateTypeDef state = hsdram->State; + + /* Check the SDRAM controller state */ + if (state == HAL_SDRAM_STATE_BUSY) + { + return HAL_BUSY; + } + else if ((state == HAL_SDRAM_STATE_READY) || (state == HAL_SDRAM_STATE_PRECHARGED)) + { + /* Update the SDRAM state */ + hsdram->State = HAL_SDRAM_STATE_BUSY; + + /* Send SDRAM command */ + (void)FMC_SDRAM_SendCommand(hsdram->Instance, Command, Timeout); + + /* Update the SDRAM controller state state */ + if (Command->CommandMode == FMC_SDRAM_CMD_PALL) + { + hsdram->State = HAL_SDRAM_STATE_PRECHARGED; + } + else + { + hsdram->State = HAL_SDRAM_STATE_READY; + } + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Programs the SDRAM Memory Refresh rate. + * @param hsdram pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @param RefreshRate The SDRAM refresh rate value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_ProgramRefreshRate(SDRAM_HandleTypeDef *hsdram, uint32_t RefreshRate) +{ + /* Check the SDRAM controller state */ + if (hsdram->State == HAL_SDRAM_STATE_BUSY) + { + return HAL_BUSY; + } + else if (hsdram->State == HAL_SDRAM_STATE_READY) + { + /* Update the SDRAM state */ + hsdram->State = HAL_SDRAM_STATE_BUSY; + + /* Program the refresh rate */ + (void)FMC_SDRAM_ProgramRefreshRate(hsdram->Instance, RefreshRate); + + /* Update the SDRAM state */ + hsdram->State = HAL_SDRAM_STATE_READY; + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Sets the Number of consecutive SDRAM Memory auto Refresh commands. + * @param hsdram pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @param AutoRefreshNumber The SDRAM auto Refresh number + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_SetAutoRefreshNumber(SDRAM_HandleTypeDef *hsdram, uint32_t AutoRefreshNumber) +{ + /* Check the SDRAM controller state */ + if (hsdram->State == HAL_SDRAM_STATE_BUSY) + { + return HAL_BUSY; + } + else if (hsdram->State == HAL_SDRAM_STATE_READY) + { + /* Update the SDRAM state */ + hsdram->State = HAL_SDRAM_STATE_BUSY; + + /* Set the Auto-Refresh number */ + (void)FMC_SDRAM_SetAutoRefreshNumber(hsdram->Instance, AutoRefreshNumber); + + /* Update the SDRAM state */ + hsdram->State = HAL_SDRAM_STATE_READY; + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Returns the SDRAM memory current mode. + * @param hsdram pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @retval The SDRAM memory mode. + */ +uint32_t HAL_SDRAM_GetModeStatus(SDRAM_HandleTypeDef *hsdram) +{ + /* Return the SDRAM memory current mode */ + return (FMC_SDRAM_GetModeStatus(hsdram->Instance, hsdram->Init.SDBank)); +} + +/** + * @} + */ + +/** @defgroup SDRAM_Exported_Functions_Group4 State functions + * @brief Peripheral State functions + * +@verbatim + ============================================================================== + ##### SDRAM State functions ##### + ============================================================================== + [..] + This subsection permits to get in run-time the status of the SDRAM controller + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Returns the SDRAM state. + * @param hsdram pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @retval HAL state + */ +HAL_SDRAM_StateTypeDef HAL_SDRAM_GetState(SDRAM_HandleTypeDef *hsdram) +{ + return hsdram->State; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup SDRAM_Private_Functions SDRAM Private Functions + * @{ + */ +/** + * @brief DMA SDRAM process complete callback. + * @param hdma : DMA handle + * @retval None + */ +static void SDRAM_DMACplt(DMA_HandleTypeDef *hdma) +{ + SDRAM_HandleTypeDef *hsdram = (SDRAM_HandleTypeDef *)(hdma->Parent); + + /* Disable the DMA channel */ + __HAL_DMA_DISABLE(hdma); + + /* Update the SDRAM controller state */ + hsdram->State = HAL_SDRAM_STATE_READY; + +#if (USE_HAL_SDRAM_REGISTER_CALLBACKS == 1) + hsdram->DmaXferCpltCallback(hdma); +#else + HAL_SDRAM_DMA_XferCpltCallback(hdma); +#endif /* USE_HAL_SDRAM_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA SRAM process complete callback. + * @param hdma : DMA handle + * @retval None + */ +static void SDRAM_DMACpltProt(DMA_HandleTypeDef *hdma) +{ + SDRAM_HandleTypeDef *hsdram = (SDRAM_HandleTypeDef *)(hdma->Parent); + + /* Disable the DMA channel */ + __HAL_DMA_DISABLE(hdma); + + /* Update the SDRAM controller state */ + hsdram->State = HAL_SDRAM_STATE_WRITE_PROTECTED; + +#if (USE_HAL_SDRAM_REGISTER_CALLBACKS == 1) + hsdram->DmaXferCpltCallback(hdma); +#else + HAL_SDRAM_DMA_XferCpltCallback(hdma); +#endif /* USE_HAL_SDRAM_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA SDRAM error callback. + * @param hdma : DMA handle + * @retval None + */ +static void SDRAM_DMAError(DMA_HandleTypeDef *hdma) +{ + SDRAM_HandleTypeDef *hsdram = (SDRAM_HandleTypeDef *)(hdma->Parent); + + /* Disable the DMA channel */ + __HAL_DMA_DISABLE(hdma); + + /* Update the SDRAM controller state */ + hsdram->State = HAL_SDRAM_STATE_ERROR; + +#if (USE_HAL_SDRAM_REGISTER_CALLBACKS == 1) + hsdram->DmaXferErrorCallback(hdma); +#else + HAL_SDRAM_DMA_XferErrorCallback(hdma); +#endif /* USE_HAL_SDRAM_REGISTER_CALLBACKS */ +} + +/** + * @} + */ +/** + * @} + */ + +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +/** + * @} + */ + +#endif /* FMC_Bank5_6_R */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_smartcard.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_smartcard.c new file mode 100644 index 0000000000..57d1d00fc2 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_smartcard.c @@ -0,0 +1,3283 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_smartcard.c + * @author MCD Application Team + * @brief SMARTCARD HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the SMARTCARD peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State and Error functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The SMARTCARD HAL driver can be used as follows: + + (#) Declare a SMARTCARD_HandleTypeDef handle structure (eg. SMARTCARD_HandleTypeDef hsmartcard). + (#) Associate a USART to the SMARTCARD handle hsmartcard. + (#) Initialize the SMARTCARD low level resources by implementing the HAL_SMARTCARD_MspInit() API: + (++) Enable the USARTx interface clock. + (++) USART pins configuration: + (+++) Enable the clock for the USART GPIOs. + (+++) Configure the USART pins (TX as alternate function pull-up, RX as alternate function Input). + (++) NVIC configuration if you need to use interrupt process (HAL_SMARTCARD_Transmit_IT() + and HAL_SMARTCARD_Receive_IT() APIs): + (+++) Configure the USARTx interrupt priority. + (+++) Enable the NVIC USART IRQ handle. + (++) DMA Configuration if you need to use DMA process (HAL_SMARTCARD_Transmit_DMA() + and HAL_SMARTCARD_Receive_DMA() APIs): + (+++) Declare a DMA handle structure for the Tx/Rx channel. + (+++) Enable the DMAx interface clock. + (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. + (+++) Configure the DMA Tx/Rx channel. + (+++) Associate the initialized DMA handle to the SMARTCARD DMA Tx/Rx handle. + (+++) Configure the priority and enable the NVIC for the transfer complete + interrupt on the DMA Tx/Rx channel. + + (#) Program the Baud Rate, Parity, Mode(Receiver/Transmitter), clock enabling/disabling and accordingly, + the clock parameters (parity, phase, last bit), prescaler value, guard time and NACK on transmission + error enabling or disabling in the hsmartcard handle Init structure. + + (#) If required, program SMARTCARD advanced features (TX/RX pins swap, TimeOut, auto-retry counter,...) + in the hsmartcard handle AdvancedInit structure. + + (#) Initialize the SMARTCARD registers by calling the HAL_SMARTCARD_Init() API: + (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc) + by calling the customized HAL_SMARTCARD_MspInit() API. + [..] + (@) The specific SMARTCARD interrupts (Transmission complete interrupt, + RXNE interrupt and Error Interrupts) will be managed using the macros + __HAL_SMARTCARD_ENABLE_IT() and __HAL_SMARTCARD_DISABLE_IT() inside the transmit and receive process. + + [..] + [..] Three operation modes are available within this driver : + + *** Polling mode IO operation *** + ================================= + [..] + (+) Send an amount of data in blocking mode using HAL_SMARTCARD_Transmit() + (+) Receive an amount of data in blocking mode using HAL_SMARTCARD_Receive() + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Send an amount of data in non-blocking mode using HAL_SMARTCARD_Transmit_IT() + (+) At transmission end of transfer HAL_SMARTCARD_TxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_SMARTCARD_TxCpltCallback() + (+) Receive an amount of data in non-blocking mode using HAL_SMARTCARD_Receive_IT() + (+) At reception end of transfer HAL_SMARTCARD_RxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_SMARTCARD_RxCpltCallback() + (+) In case of transfer Error, HAL_SMARTCARD_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_SMARTCARD_ErrorCallback() + + *** DMA mode IO operation *** + ============================== + [..] + (+) Send an amount of data in non-blocking mode (DMA) using HAL_SMARTCARD_Transmit_DMA() + (+) At transmission end of transfer HAL_SMARTCARD_TxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_SMARTCARD_TxCpltCallback() + (+) Receive an amount of data in non-blocking mode (DMA) using HAL_SMARTCARD_Receive_DMA() + (+) At reception end of transfer HAL_SMARTCARD_RxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_SMARTCARD_RxCpltCallback() + (+) In case of transfer Error, HAL_SMARTCARD_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_SMARTCARD_ErrorCallback() + + *** SMARTCARD HAL driver macros list *** + ======================================== + [..] + Below the list of most used macros in SMARTCARD HAL driver. + + (+) __HAL_SMARTCARD_GET_FLAG : Check whether or not the specified SMARTCARD flag is set + (+) __HAL_SMARTCARD_CLEAR_FLAG : Clear the specified SMARTCARD pending flag + (+) __HAL_SMARTCARD_ENABLE_IT: Enable the specified SMARTCARD interrupt + (+) __HAL_SMARTCARD_DISABLE_IT: Disable the specified SMARTCARD interrupt + (+) __HAL_SMARTCARD_GET_IT_SOURCE: Check whether or not the specified SMARTCARD interrupt is enabled + + [..] + (@) You can refer to the SMARTCARD HAL driver header file for more useful macros + + ##### Callback registration ##### + ================================== + + [..] + The compilation define USE_HAL_SMARTCARD_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + + [..] + Use Function HAL_SMARTCARD_RegisterCallback() to register a user callback. + Function HAL_SMARTCARD_RegisterCallback() allows to register following callbacks: + (+) TxCpltCallback : Tx Complete Callback. + (+) RxCpltCallback : Rx Complete Callback. + (+) ErrorCallback : Error Callback. + (+) AbortCpltCallback : Abort Complete Callback. + (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback. + (+) AbortReceiveCpltCallback : Abort Receive Complete Callback. + (+) RxFifoFullCallback : Rx Fifo Full Callback. + (+) TxFifoEmptyCallback : Tx Fifo Empty Callback. + (+) MspInitCallback : SMARTCARD MspInit. + (+) MspDeInitCallback : SMARTCARD MspDeInit. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + + [..] + Use function HAL_SMARTCARD_UnRegisterCallback() to reset a callback to the default + weak function. + HAL_SMARTCARD_UnRegisterCallback() takes as parameters the HAL peripheral handle, + and the Callback ID. + This function allows to reset following callbacks: + (+) TxCpltCallback : Tx Complete Callback. + (+) RxCpltCallback : Rx Complete Callback. + (+) ErrorCallback : Error Callback. + (+) AbortCpltCallback : Abort Complete Callback. + (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback. + (+) AbortReceiveCpltCallback : Abort Receive Complete Callback. + (+) RxFifoFullCallback : Rx Fifo Full Callback. + (+) TxFifoEmptyCallback : Tx Fifo Empty Callback. + (+) MspInitCallback : SMARTCARD MspInit. + (+) MspDeInitCallback : SMARTCARD MspDeInit. + + [..] + By default, after the HAL_SMARTCARD_Init() and when the state is HAL_SMARTCARD_STATE_RESET + all callbacks are set to the corresponding weak functions: + examples HAL_SMARTCARD_TxCpltCallback(), HAL_SMARTCARD_RxCpltCallback(). + Exception done for MspInit and MspDeInit functions that are respectively + reset to the legacy weak functions in the HAL_SMARTCARD_Init() + and HAL_SMARTCARD_DeInit() only when these callbacks are null (not registered beforehand). + If not, MspInit or MspDeInit are not null, the HAL_SMARTCARD_Init() and HAL_SMARTCARD_DeInit() + keep and use the user MspInit/MspDeInit callbacks (registered beforehand). + + [..] + Callbacks can be registered/unregistered in HAL_SMARTCARD_STATE_READY state only. + Exception done MspInit/MspDeInit that can be registered/unregistered + in HAL_SMARTCARD_STATE_READY or HAL_SMARTCARD_STATE_RESET state, thus registered (user) + MspInit/DeInit callbacks can be used during the Init/DeInit. + In that case first register the MspInit/MspDeInit user callbacks + using HAL_SMARTCARD_RegisterCallback() before calling HAL_SMARTCARD_DeInit() + or HAL_SMARTCARD_Init() function. + + [..] + When The compilation define USE_HAL_SMARTCARD_REGISTER_CALLBACKS is set to 0 or + not defined, the callback registration feature is not available + and weak callbacks are used. + + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup SMARTCARD SMARTCARD + * @brief HAL SMARTCARD module driver + * @{ + */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup SMARTCARD_Private_Constants SMARTCARD Private Constants + * @{ + */ +#define SMARTCARD_TEACK_REACK_TIMEOUT 1000U /*!< SMARTCARD TX or RX enable acknowledge time-out value */ + +#define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | \ + USART_CR1_RE | USART_CR1_OVER8| \ + USART_CR1_FIFOEN)) /*!< USART CR1 fields of parameters set by SMARTCARD_SetConfig API */ + +#define USART_CR2_CLK_FIELDS ((uint32_t)(USART_CR2_CLKEN | USART_CR2_CPOL | \ + USART_CR2_CPHA | USART_CR2_LBCL)) /*!< SMARTCARD clock-related USART CR2 fields of parameters */ + +#define USART_CR2_FIELDS ((uint32_t)(USART_CR2_RTOEN | USART_CR2_CLK_FIELDS | \ + USART_CR2_STOP)) /*!< USART CR2 fields of parameters set by SMARTCARD_SetConfig API */ + +#define USART_CR3_FIELDS ((uint32_t)(USART_CR3_ONEBIT | USART_CR3_NACK | USART_CR3_SCARCNT | \ + USART_CR3_TXFTCFG | USART_CR3_RXFTCFG )) /*!< USART CR3 fields of parameters set by SMARTCARD_SetConfig API */ + +#define USART_BRR_MIN 0x10U /*!< USART BRR minimum authorized value */ + +#define USART_BRR_MAX 0x0000FFFFU /*!< USART BRR maximum authorized value */ +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup SMARTCARD_Private_Functions + * @{ + */ +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) +void SMARTCARD_InitCallbacksToDefault(SMARTCARD_HandleTypeDef *hsmartcard); +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACKS */ +static HAL_StatusTypeDef SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef *hsmartcard); +static void SMARTCARD_AdvFeatureConfig(SMARTCARD_HandleTypeDef *hsmartcard); +static HAL_StatusTypeDef SMARTCARD_CheckIdleState(SMARTCARD_HandleTypeDef *hsmartcard); +static HAL_StatusTypeDef SMARTCARD_WaitOnFlagUntilTimeout(SMARTCARD_HandleTypeDef *hsmartcard, uint32_t Flag, + FlagStatus Status, uint32_t Tickstart, uint32_t Timeout); +static void SMARTCARD_EndTxTransfer(SMARTCARD_HandleTypeDef *hsmartcard); +static void SMARTCARD_EndRxTransfer(SMARTCARD_HandleTypeDef *hsmartcard); +#if defined(HAL_DMA_MODULE_ENABLED) +static void SMARTCARD_DMATransmitCplt(DMA_HandleTypeDef *hdma); +static void SMARTCARD_DMAReceiveCplt(DMA_HandleTypeDef *hdma); +static void SMARTCARD_DMAError(DMA_HandleTypeDef *hdma); +static void SMARTCARD_DMAAbortOnError(DMA_HandleTypeDef *hdma); +static void SMARTCARD_DMATxAbortCallback(DMA_HandleTypeDef *hdma); +static void SMARTCARD_DMARxAbortCallback(DMA_HandleTypeDef *hdma); +static void SMARTCARD_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma); +static void SMARTCARD_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma); +#endif /* HAL_DMA_MODULE_ENABLED */ +static void SMARTCARD_TxISR(SMARTCARD_HandleTypeDef *hsmartcard); +static void SMARTCARD_TxISR_FIFOEN(SMARTCARD_HandleTypeDef *hsmartcard); +static void SMARTCARD_EndTransmit_IT(SMARTCARD_HandleTypeDef *hsmartcard); +static void SMARTCARD_RxISR(SMARTCARD_HandleTypeDef *hsmartcard); +static void SMARTCARD_RxISR_FIFOEN(SMARTCARD_HandleTypeDef *hsmartcard); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup SMARTCARD_Exported_Functions SMARTCARD Exported Functions + * @{ + */ + +/** @defgroup SMARTCARD_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + ============================================================================== + ##### Initialization and Configuration functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to initialize the USARTx + associated to the SmartCard. + (+) These parameters can be configured: + (++) Baud Rate + (++) Parity: parity should be enabled, frame Length is fixed to 8 bits plus parity + (++) Receiver/transmitter modes + (++) Synchronous mode (and if enabled, phase, polarity and last bit parameters) + (++) Prescaler value + (++) Guard bit time + (++) NACK enabling or disabling on transmission error + + (+) The following advanced features can be configured as well: + (++) TX and/or RX pin level inversion + (++) data logical level inversion + (++) RX and TX pins swap + (++) RX overrun detection disabling + (++) DMA disabling on RX error + (++) MSB first on communication line + (++) Time out enabling (and if activated, timeout value) + (++) Block length + (++) Auto-retry counter + [..] + The HAL_SMARTCARD_Init() API follows the USART synchronous configuration procedures + (details for the procedures are available in reference manual). + +@endverbatim + + The USART frame format is given in the following table: + + Table 1. USART frame format. + +---------------------------------------------------------------+ + | M1M0 bits | PCE bit | USART frame | + |-----------------------|---------------------------------------| + | 01 | 1 | | SB | 8 bit data | PB | STB | | + +---------------------------------------------------------------+ + + + * @{ + */ + +/** + * @brief Initialize the SMARTCARD mode according to the specified + * parameters in the SMARTCARD_HandleTypeDef and initialize the associated handle. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARD_Init(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Check the SMARTCARD handle allocation */ + if (hsmartcard == NULL) + { + return HAL_ERROR; + } + + /* Check the USART associated to the SMARTCARD handle */ + assert_param(IS_SMARTCARD_INSTANCE(hsmartcard->Instance)); + + if (hsmartcard->gState == HAL_SMARTCARD_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hsmartcard->Lock = HAL_UNLOCKED; + +#if USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1 + SMARTCARD_InitCallbacksToDefault(hsmartcard); + + if (hsmartcard->MspInitCallback == NULL) + { + hsmartcard->MspInitCallback = HAL_SMARTCARD_MspInit; + } + + /* Init the low level hardware */ + hsmartcard->MspInitCallback(hsmartcard); +#else + /* Init the low level hardware : GPIO, CLOCK */ + HAL_SMARTCARD_MspInit(hsmartcard); +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACKS */ + } + + hsmartcard->gState = HAL_SMARTCARD_STATE_BUSY; + + /* Disable the Peripheral to set smartcard mode */ + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_UE); + + /* In SmartCard mode, the following bits must be kept cleared: + - LINEN in the USART_CR2 register, + - HDSEL and IREN bits in the USART_CR3 register.*/ + CLEAR_BIT(hsmartcard->Instance->CR2, USART_CR2_LINEN); + CLEAR_BIT(hsmartcard->Instance->CR3, (USART_CR3_HDSEL | USART_CR3_IREN)); + + /* set the USART in SMARTCARD mode */ + SET_BIT(hsmartcard->Instance->CR3, USART_CR3_SCEN); + + /* Set the SMARTCARD Communication parameters */ + if (SMARTCARD_SetConfig(hsmartcard) == HAL_ERROR) + { + return HAL_ERROR; + } + + /* Set the SMARTCARD transmission completion indication */ + SMARTCARD_TRANSMISSION_COMPLETION_SETTING(hsmartcard); + + if (hsmartcard->AdvancedInit.AdvFeatureInit != SMARTCARD_ADVFEATURE_NO_INIT) + { + SMARTCARD_AdvFeatureConfig(hsmartcard); + } + + /* Enable the Peripheral */ + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_UE); + + /* TEACK and/or REACK to check before moving hsmartcard->gState and hsmartcard->RxState to Ready */ + return (SMARTCARD_CheckIdleState(hsmartcard)); +} + +/** + * @brief DeInitialize the SMARTCARD peripheral. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARD_DeInit(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Check the SMARTCARD handle allocation */ + if (hsmartcard == NULL) + { + return HAL_ERROR; + } + + /* Check the USART/UART associated to the SMARTCARD handle */ + assert_param(IS_SMARTCARD_INSTANCE(hsmartcard->Instance)); + + hsmartcard->gState = HAL_SMARTCARD_STATE_BUSY; + + /* Disable the Peripheral */ + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_UE); + + WRITE_REG(hsmartcard->Instance->CR1, 0x0U); + WRITE_REG(hsmartcard->Instance->CR2, 0x0U); + WRITE_REG(hsmartcard->Instance->CR3, 0x0U); + WRITE_REG(hsmartcard->Instance->RTOR, 0x0U); + WRITE_REG(hsmartcard->Instance->GTPR, 0x0U); + + /* DeInit the low level hardware */ +#if USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1 + if (hsmartcard->MspDeInitCallback == NULL) + { + hsmartcard->MspDeInitCallback = HAL_SMARTCARD_MspDeInit; + } + /* DeInit the low level hardware */ + hsmartcard->MspDeInitCallback(hsmartcard); +#else + HAL_SMARTCARD_MspDeInit(hsmartcard); +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACKS */ + + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + hsmartcard->gState = HAL_SMARTCARD_STATE_RESET; + hsmartcard->RxState = HAL_SMARTCARD_STATE_RESET; + + /* Process Unlock */ + __HAL_UNLOCK(hsmartcard); + + return HAL_OK; +} + +/** + * @brief Initialize the SMARTCARD MSP. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval None + */ +__weak void HAL_SMARTCARD_MspInit(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsmartcard); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMARTCARD_MspInit can be implemented in the user file + */ +} + +/** + * @brief DeInitialize the SMARTCARD MSP. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval None + */ +__weak void HAL_SMARTCARD_MspDeInit(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsmartcard); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMARTCARD_MspDeInit can be implemented in the user file + */ +} + +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User SMARTCARD Callback + * To be used to override the weak predefined callback + * @note The HAL_SMARTCARD_RegisterCallback() may be called before HAL_SMARTCARD_Init() + * in HAL_SMARTCARD_STATE_RESET to register callbacks for HAL_SMARTCARD_MSPINIT_CB_ID + * and HAL_SMARTCARD_MSPDEINIT_CB_ID + * @param hsmartcard smartcard handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_SMARTCARD_TX_COMPLETE_CB_ID Tx Complete Callback ID + * @arg @ref HAL_SMARTCARD_RX_COMPLETE_CB_ID Rx Complete Callback ID + * @arg @ref HAL_SMARTCARD_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_SMARTCARD_ABORT_COMPLETE_CB_ID Abort Complete Callback ID + * @arg @ref HAL_SMARTCARD_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID + * @arg @ref HAL_SMARTCARD_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID + * @arg @ref HAL_SMARTCARD_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID + * @arg @ref HAL_SMARTCARD_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID + * @arg @ref HAL_SMARTCARD_MSPINIT_CB_ID MspInit Callback ID + * @arg @ref HAL_SMARTCARD_MSPDEINIT_CB_ID MspDeInit Callback ID + * @param pCallback pointer to the Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARD_RegisterCallback(SMARTCARD_HandleTypeDef *hsmartcard, + HAL_SMARTCARD_CallbackIDTypeDef CallbackID, + pSMARTCARD_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hsmartcard->ErrorCode |= HAL_SMARTCARD_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + if (hsmartcard->gState == HAL_SMARTCARD_STATE_READY) + { + switch (CallbackID) + { + + case HAL_SMARTCARD_TX_COMPLETE_CB_ID : + hsmartcard->TxCpltCallback = pCallback; + break; + + case HAL_SMARTCARD_RX_COMPLETE_CB_ID : + hsmartcard->RxCpltCallback = pCallback; + break; + + case HAL_SMARTCARD_ERROR_CB_ID : + hsmartcard->ErrorCallback = pCallback; + break; + + case HAL_SMARTCARD_ABORT_COMPLETE_CB_ID : + hsmartcard->AbortCpltCallback = pCallback; + break; + + case HAL_SMARTCARD_ABORT_TRANSMIT_COMPLETE_CB_ID : + hsmartcard->AbortTransmitCpltCallback = pCallback; + break; + + case HAL_SMARTCARD_ABORT_RECEIVE_COMPLETE_CB_ID : + hsmartcard->AbortReceiveCpltCallback = pCallback; + break; + + case HAL_SMARTCARD_RX_FIFO_FULL_CB_ID : + hsmartcard->RxFifoFullCallback = pCallback; + break; + + case HAL_SMARTCARD_TX_FIFO_EMPTY_CB_ID : + hsmartcard->TxFifoEmptyCallback = pCallback; + break; + + case HAL_SMARTCARD_MSPINIT_CB_ID : + hsmartcard->MspInitCallback = pCallback; + break; + + case HAL_SMARTCARD_MSPDEINIT_CB_ID : + hsmartcard->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hsmartcard->ErrorCode |= HAL_SMARTCARD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (hsmartcard->gState == HAL_SMARTCARD_STATE_RESET) + { + switch (CallbackID) + { + case HAL_SMARTCARD_MSPINIT_CB_ID : + hsmartcard->MspInitCallback = pCallback; + break; + + case HAL_SMARTCARD_MSPDEINIT_CB_ID : + hsmartcard->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hsmartcard->ErrorCode |= HAL_SMARTCARD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hsmartcard->ErrorCode |= HAL_SMARTCARD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister an SMARTCARD callback + * SMARTCARD callback is redirected to the weak predefined callback + * @note The HAL_SMARTCARD_UnRegisterCallback() may be called before HAL_SMARTCARD_Init() + * in HAL_SMARTCARD_STATE_RESET to un-register callbacks for HAL_SMARTCARD_MSPINIT_CB_ID + * and HAL_SMARTCARD_MSPDEINIT_CB_ID + * @param hsmartcard smartcard handle + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_SMARTCARD_TX_COMPLETE_CB_ID Tx Complete Callback ID + * @arg @ref HAL_SMARTCARD_RX_COMPLETE_CB_ID Rx Complete Callback ID + * @arg @ref HAL_SMARTCARD_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_SMARTCARD_ABORT_COMPLETE_CB_ID Abort Complete Callback ID + * @arg @ref HAL_SMARTCARD_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID + * @arg @ref HAL_SMARTCARD_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID + * @arg @ref HAL_SMARTCARD_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID + * @arg @ref HAL_SMARTCARD_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID + * @arg @ref HAL_SMARTCARD_MSPINIT_CB_ID MspInit Callback ID + * @arg @ref HAL_SMARTCARD_MSPDEINIT_CB_ID MspDeInit Callback ID + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARD_UnRegisterCallback(SMARTCARD_HandleTypeDef *hsmartcard, + HAL_SMARTCARD_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (HAL_SMARTCARD_STATE_READY == hsmartcard->gState) + { + switch (CallbackID) + { + case HAL_SMARTCARD_TX_COMPLETE_CB_ID : + hsmartcard->TxCpltCallback = HAL_SMARTCARD_TxCpltCallback; /* Legacy weak TxCpltCallback */ + break; + + case HAL_SMARTCARD_RX_COMPLETE_CB_ID : + hsmartcard->RxCpltCallback = HAL_SMARTCARD_RxCpltCallback; /* Legacy weak RxCpltCallback */ + break; + + case HAL_SMARTCARD_ERROR_CB_ID : + hsmartcard->ErrorCallback = HAL_SMARTCARD_ErrorCallback; /* Legacy weak ErrorCallback */ + break; + + case HAL_SMARTCARD_ABORT_COMPLETE_CB_ID : + hsmartcard->AbortCpltCallback = HAL_SMARTCARD_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ + break; + + case HAL_SMARTCARD_ABORT_TRANSMIT_COMPLETE_CB_ID : + hsmartcard->AbortTransmitCpltCallback = HAL_SMARTCARD_AbortTransmitCpltCallback; /* Legacy weak + AbortTransmitCpltCallback*/ + break; + + case HAL_SMARTCARD_ABORT_RECEIVE_COMPLETE_CB_ID : + hsmartcard->AbortReceiveCpltCallback = HAL_SMARTCARD_AbortReceiveCpltCallback; /* Legacy weak + AbortReceiveCpltCallback */ + break; + + case HAL_SMARTCARD_RX_FIFO_FULL_CB_ID : + hsmartcard->RxFifoFullCallback = HAL_SMARTCARDEx_RxFifoFullCallback; /* Legacy weak RxFifoFullCallback */ + break; + + case HAL_SMARTCARD_TX_FIFO_EMPTY_CB_ID : + hsmartcard->TxFifoEmptyCallback = HAL_SMARTCARDEx_TxFifoEmptyCallback; /* Legacy weak TxFifoEmptyCallback */ + break; + + case HAL_SMARTCARD_MSPINIT_CB_ID : + hsmartcard->MspInitCallback = HAL_SMARTCARD_MspInit; /* Legacy weak MspInitCallback */ + break; + + case HAL_SMARTCARD_MSPDEINIT_CB_ID : + hsmartcard->MspDeInitCallback = HAL_SMARTCARD_MspDeInit; /* Legacy weak MspDeInitCallback */ + break; + + default : + /* Update the error code */ + hsmartcard->ErrorCode |= HAL_SMARTCARD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_SMARTCARD_STATE_RESET == hsmartcard->gState) + { + switch (CallbackID) + { + case HAL_SMARTCARD_MSPINIT_CB_ID : + hsmartcard->MspInitCallback = HAL_SMARTCARD_MspInit; + break; + + case HAL_SMARTCARD_MSPDEINIT_CB_ID : + hsmartcard->MspDeInitCallback = HAL_SMARTCARD_MspDeInit; + break; + + default : + /* Update the error code */ + hsmartcard->ErrorCode |= HAL_SMARTCARD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hsmartcard->ErrorCode |= HAL_SMARTCARD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup SMARTCARD_Exported_Functions_Group2 IO operation functions + * @brief SMARTCARD Transmit and Receive functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to manage the SMARTCARD data transfers. + + [..] + Smartcard is a single wire half duplex communication protocol. + The Smartcard interface is designed to support asynchronous protocol Smartcards as + defined in the ISO 7816-3 standard. The USART should be configured as: + (+) 8 bits plus parity: where M=1 and PCE=1 in the USART_CR1 register + (+) 1.5 stop bits when transmitting and receiving: where STOP=11 in the USART_CR2 register. + + [..] + (#) There are two modes of transfer: + (##) Blocking mode: The communication is performed in polling mode. + The HAL status of all data processing is returned by the same function + after finishing transfer. + (##) Non-Blocking mode: The communication is performed using Interrupts + or DMA, the relevant API's return the HAL status. + The end of the data processing will be indicated through the + dedicated SMARTCARD IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + (##) The HAL_SMARTCARD_TxCpltCallback(), HAL_SMARTCARD_RxCpltCallback() user callbacks + will be executed respectively at the end of the Transmit or Receive process + The HAL_SMARTCARD_ErrorCallback() user callback will be executed when a communication + error is detected. + + (#) Blocking mode APIs are : + (##) HAL_SMARTCARD_Transmit() + (##) HAL_SMARTCARD_Receive() + + (#) Non Blocking mode APIs with Interrupt are : + (##) HAL_SMARTCARD_Transmit_IT() + (##) HAL_SMARTCARD_Receive_IT() + (##) HAL_SMARTCARD_IRQHandler() + + (#) Non Blocking mode functions with DMA are : + (##) HAL_SMARTCARD_Transmit_DMA() + (##) HAL_SMARTCARD_Receive_DMA() + + (#) A set of Transfer Complete Callbacks are provided in non Blocking mode: + (##) HAL_SMARTCARD_TxCpltCallback() + (##) HAL_SMARTCARD_RxCpltCallback() + (##) HAL_SMARTCARD_ErrorCallback() + + [..] + (#) Non-Blocking mode transfers could be aborted using Abort API's : + (##) HAL_SMARTCARD_Abort() + (##) HAL_SMARTCARD_AbortTransmit() + (##) HAL_SMARTCARD_AbortReceive() + (##) HAL_SMARTCARD_Abort_IT() + (##) HAL_SMARTCARD_AbortTransmit_IT() + (##) HAL_SMARTCARD_AbortReceive_IT() + + (#) For Abort services based on interrupts (HAL_SMARTCARD_Abortxxx_IT), + a set of Abort Complete Callbacks are provided: + (##) HAL_SMARTCARD_AbortCpltCallback() + (##) HAL_SMARTCARD_AbortTransmitCpltCallback() + (##) HAL_SMARTCARD_AbortReceiveCpltCallback() + + (#) In Non-Blocking mode transfers, possible errors are split into 2 categories. + Errors are handled as follows : + (##) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is + to be evaluated by user : this concerns Frame Error, + Parity Error or Noise Error in Interrupt mode reception . + Received character is then retrieved and stored in Rx buffer, + Error code is set to allow user to identify error type, + and HAL_SMARTCARD_ErrorCallback() user callback is executed. Transfer is kept ongoing on SMARTCARD side. + If user wants to abort it, Abort services should be called by user. + (##) Error is considered as Blocking : Transfer could not be completed properly and is aborted. + This concerns Frame Error in Interrupt mode transmission, Overrun Error in Interrupt + mode reception and all errors in DMA mode. + Error code is set to allow user to identify error type, + and HAL_SMARTCARD_ErrorCallback() user callback is executed. + +@endverbatim + * @{ + */ + +/** + * @brief Send an amount of data in blocking mode. + * @note When FIFO mode is enabled, writing a data in the TDR register adds one + * data to the TXFIFO. Write operations to the TDR register are performed + * when TXFNF flag is set. From hardware perspective, TXFNF flag and + * TXE are mapped on the same bit-field. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @param pData pointer to data buffer. + * @param Size amount of data to be sent. + * @param Timeout Timeout duration. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARD_Transmit(SMARTCARD_HandleTypeDef *hsmartcard, const uint8_t *pData, uint16_t Size, + uint32_t Timeout) +{ + uint32_t tickstart; + const uint8_t *ptmpdata = pData; + + /* Check that a Tx process is not already ongoing */ + if (hsmartcard->gState == HAL_SMARTCARD_STATE_READY) + { + if ((ptmpdata == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hsmartcard); + + hsmartcard->gState = HAL_SMARTCARD_STATE_BUSY_TX; + + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + + /* Disable the Peripheral first to update mode for TX master */ + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_UE); + + /* In case of TX only mode, if NACK is enabled, the USART must be able to monitor + the bidirectional line to detect a NACK signal in case of parity error. + Therefore, the receiver block must be enabled as well (RE bit must be set). */ + if ((hsmartcard->Init.Mode == SMARTCARD_MODE_TX) + && (hsmartcard->Init.NACKEnable == SMARTCARD_NACK_ENABLE)) + { + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_RE); + } + /* Enable Tx */ + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_TE); + + /* Enable the Peripheral */ + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_UE); + + /* Perform a TX/RX FIFO Flush */ + __HAL_SMARTCARD_FLUSH_DRREGISTER(hsmartcard); + + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + hsmartcard->TxXferSize = Size; + hsmartcard->TxXferCount = Size; + + while (hsmartcard->TxXferCount > 0U) + { + hsmartcard->TxXferCount--; + if (SMARTCARD_WaitOnFlagUntilTimeout(hsmartcard, SMARTCARD_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + hsmartcard->Instance->TDR = (uint8_t)(*ptmpdata & 0xFFU); + ptmpdata++; + } + if (SMARTCARD_WaitOnFlagUntilTimeout(hsmartcard, SMARTCARD_TRANSMISSION_COMPLETION_FLAG(hsmartcard), RESET, + tickstart, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Disable the Peripheral first to update mode */ + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_UE); + if ((hsmartcard->Init.Mode == SMARTCARD_MODE_TX) + && (hsmartcard->Init.NACKEnable == SMARTCARD_NACK_ENABLE)) + { + /* In case of TX only mode, if NACK is enabled, receiver block has been enabled + for Transmit phase. Disable this receiver block. */ + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_RE); + } + if ((hsmartcard->Init.Mode == SMARTCARD_MODE_TX_RX) + || (hsmartcard->Init.NACKEnable == SMARTCARD_NACK_ENABLE)) + { + /* Perform a TX FIFO Flush at end of Tx phase, as all sent bytes are appearing in Rx Data register */ + __HAL_SMARTCARD_FLUSH_DRREGISTER(hsmartcard); + } + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_UE); + + /* At end of Tx process, restore hsmartcard->gState to Ready */ + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmartcard); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in blocking mode. + * @note When FIFO mode is enabled, the RXFNE flag is set as long as the RXFIFO + * is not empty. Read operations from the RDR register are performed when + * RXFNE flag is set. From hardware perspective, RXFNE flag and + * RXNE are mapped on the same bit-field. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @param pData pointer to data buffer. + * @param Size amount of data to be received. + * @param Timeout Timeout duration. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARD_Receive(SMARTCARD_HandleTypeDef *hsmartcard, uint8_t *pData, uint16_t Size, + uint32_t Timeout) +{ + uint32_t tickstart; + uint8_t *ptmpdata = pData; + + /* Check that a Rx process is not already ongoing */ + if (hsmartcard->RxState == HAL_SMARTCARD_STATE_READY) + { + if ((ptmpdata == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hsmartcard); + + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + hsmartcard->RxState = HAL_SMARTCARD_STATE_BUSY_RX; + + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + + hsmartcard->RxXferSize = Size; + hsmartcard->RxXferCount = Size; + + /* Check the remain data to be received */ + while (hsmartcard->RxXferCount > 0U) + { + hsmartcard->RxXferCount--; + + if (SMARTCARD_WaitOnFlagUntilTimeout(hsmartcard, SMARTCARD_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + *ptmpdata = (uint8_t)(hsmartcard->Instance->RDR & (uint8_t)0x00FF); + ptmpdata++; + } + + /* At end of Rx process, restore hsmartcard->RxState to Ready */ + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmartcard); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Send an amount of data in interrupt mode. + * @note When FIFO mode is disabled, USART interrupt is generated whenever + * USART_TDR register is empty, i.e one interrupt per data to transmit. + * @note When FIFO mode is enabled, USART interrupt is generated whenever + * TXFIFO threshold reached. In that case the interrupt rate depends on + * TXFIFO threshold configuration. + * @note This function sets the hsmartcard->TxIsr function pointer according to + * the FIFO mode (data transmission processing depends on FIFO mode). + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @param pData pointer to data buffer. + * @param Size amount of data to be sent. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsmartcard, const uint8_t *pData, uint16_t Size) +{ + /* Check that a Tx process is not already ongoing */ + if (hsmartcard->gState == HAL_SMARTCARD_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hsmartcard); + + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + hsmartcard->gState = HAL_SMARTCARD_STATE_BUSY_TX; + + hsmartcard->pTxBuffPtr = pData; + hsmartcard->TxXferSize = Size; + hsmartcard->TxXferCount = Size; + hsmartcard->TxISR = NULL; + + /* Disable the Peripheral first to update mode for TX master */ + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_UE); + + /* In case of TX only mode, if NACK is enabled, the USART must be able to monitor + the bidirectional line to detect a NACK signal in case of parity error. + Therefore, the receiver block must be enabled as well (RE bit must be set). */ + if ((hsmartcard->Init.Mode == SMARTCARD_MODE_TX) + && (hsmartcard->Init.NACKEnable == SMARTCARD_NACK_ENABLE)) + { + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_RE); + } + /* Enable Tx */ + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_TE); + + /* Enable the Peripheral */ + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_UE); + + /* Perform a TX/RX FIFO Flush */ + __HAL_SMARTCARD_FLUSH_DRREGISTER(hsmartcard); + + /* Configure Tx interrupt processing */ + if (hsmartcard->FifoMode == SMARTCARD_FIFOMODE_ENABLE) + { + /* Set the Tx ISR function pointer */ + hsmartcard->TxISR = SMARTCARD_TxISR_FIFOEN; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmartcard); + + /* Enable the SMARTCARD Error Interrupt: (Frame error) */ + SET_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + + /* Enable the TX FIFO threshold interrupt */ + SET_BIT(hsmartcard->Instance->CR3, USART_CR3_TXFTIE); + } + else + { + /* Set the Tx ISR function pointer */ + hsmartcard->TxISR = SMARTCARD_TxISR; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmartcard); + + /* Enable the SMARTCARD Error Interrupt: (Frame error) */ + SET_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + + /* Enable the SMARTCARD Transmit Data Register Empty Interrupt */ + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_TXEIE_TXFNFIE); + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in interrupt mode. + * @note When FIFO mode is disabled, USART interrupt is generated whenever + * USART_RDR register can be read, i.e one interrupt per data to receive. + * @note When FIFO mode is enabled, USART interrupt is generated whenever + * RXFIFO threshold reached. In that case the interrupt rate depends on + * RXFIFO threshold configuration. + * @note This function sets the hsmartcard->RxIsr function pointer according to + * the FIFO mode (data reception processing depends on FIFO mode). + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @param pData pointer to data buffer. + * @param Size amount of data to be received. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsmartcard, uint8_t *pData, uint16_t Size) +{ + /* Check that a Rx process is not already ongoing */ + if (hsmartcard->RxState == HAL_SMARTCARD_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hsmartcard); + + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + hsmartcard->RxState = HAL_SMARTCARD_STATE_BUSY_RX; + + hsmartcard->pRxBuffPtr = pData; + hsmartcard->RxXferSize = Size; + hsmartcard->RxXferCount = Size; + + /* Configure Rx interrupt processing */ + if ((hsmartcard->FifoMode == SMARTCARD_FIFOMODE_ENABLE) && (Size >= hsmartcard->NbRxDataToProcess)) + { + /* Set the Rx ISR function pointer */ + hsmartcard->RxISR = SMARTCARD_RxISR_FIFOEN; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmartcard); + + /* Enable the SMARTCART Parity Error interrupt and RX FIFO Threshold interrupt */ + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_PEIE); + SET_BIT(hsmartcard->Instance->CR3, USART_CR3_RXFTIE); + } + else + { + /* Set the Rx ISR function pointer */ + hsmartcard->RxISR = SMARTCARD_RxISR; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmartcard); + + /* Enable the SMARTCARD Parity Error and Data Register not empty Interrupts */ + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE); + } + + /* Enable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */ + SET_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief Send an amount of data in DMA mode. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @param pData pointer to data buffer. + * @param Size amount of data to be sent. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARD_Transmit_DMA(SMARTCARD_HandleTypeDef *hsmartcard, const uint8_t *pData, uint16_t Size) +{ + HAL_StatusTypeDef status; + + /* Check that a Tx process is not already ongoing */ + if (hsmartcard->gState == HAL_SMARTCARD_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hsmartcard); + + hsmartcard->gState = HAL_SMARTCARD_STATE_BUSY_TX; + + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + hsmartcard->pTxBuffPtr = pData; + hsmartcard->TxXferSize = Size; + hsmartcard->TxXferCount = Size; + + /* Disable the Peripheral first to update mode for TX master */ + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_UE); + + /* In case of TX only mode, if NACK is enabled, the USART must be able to monitor + the bidirectional line to detect a NACK signal in case of parity error. + Therefore, the receiver block must be enabled as well (RE bit must be set). */ + if ((hsmartcard->Init.Mode == SMARTCARD_MODE_TX) + && (hsmartcard->Init.NACKEnable == SMARTCARD_NACK_ENABLE)) + { + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_RE); + } + /* Enable Tx */ + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_TE); + + /* Enable the Peripheral */ + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_UE); + + /* Perform a TX/RX FIFO Flush */ + __HAL_SMARTCARD_FLUSH_DRREGISTER(hsmartcard); + + /* Set the SMARTCARD DMA transfer complete callback */ + hsmartcard->hdmatx->XferCpltCallback = SMARTCARD_DMATransmitCplt; + + /* Set the SMARTCARD error callback */ + hsmartcard->hdmatx->XferErrorCallback = SMARTCARD_DMAError; + + /* Set the DMA abort callback */ + hsmartcard->hdmatx->XferAbortCallback = NULL; + + /* Check linked list mode */ + if ((hsmartcard->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hsmartcard->hdmatx->LinkedListQueue != NULL) && (hsmartcard->hdmatx->LinkedListQueue->Head != NULL)) + { + /* Set DMA data size */ + hsmartcard->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = Size; + + /* Set DMA source address */ + hsmartcard->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = + (uint32_t)hsmartcard->pTxBuffPtr; + + /* Set DMA destination address */ + hsmartcard->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = + (uint32_t)&hsmartcard->Instance->TDR; + + /* Enable the SMARTCARD transmit DMA channel */ + status = HAL_DMAEx_List_Start_IT(hsmartcard->hdmatx); + } + else + { + /* Update status */ + status = HAL_ERROR; + } + } + else + { + /* Enable the SMARTCARD transmit DMA channel */ + status = HAL_DMA_Start_IT(hsmartcard->hdmatx, (uint32_t)hsmartcard->pTxBuffPtr, + (uint32_t)&hsmartcard->Instance->TDR, Size); + } + + if (status == HAL_OK) + { + /* Clear the TC flag in the ICR register */ + CLEAR_BIT(hsmartcard->Instance->ICR, USART_ICR_TCCF); + + /* Process Unlocked */ + __HAL_UNLOCK(hsmartcard); + + /* Enable the UART Error Interrupt: (Frame error) */ + SET_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + + /* Enable the DMA transfer for transmit request by setting the DMAT bit + in the SMARTCARD associated USART CR3 register */ + SET_BIT(hsmartcard->Instance->CR3, USART_CR3_DMAT); + + return HAL_OK; + } + else + { + /* Set error code to DMA */ + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmartcard); + + /* Restore hsmartcard->State to ready */ + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + + return HAL_ERROR; + } + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in DMA mode. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @param pData pointer to data buffer. + * @param Size amount of data to be received. + * @note The SMARTCARD-associated USART parity is enabled (PCE = 1), + * the received data contain the parity bit (MSB position). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARD_Receive_DMA(SMARTCARD_HandleTypeDef *hsmartcard, uint8_t *pData, uint16_t Size) +{ + HAL_StatusTypeDef status; + + /* Check that a Rx process is not already ongoing */ + if (hsmartcard->RxState == HAL_SMARTCARD_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hsmartcard); + + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + hsmartcard->RxState = HAL_SMARTCARD_STATE_BUSY_RX; + + hsmartcard->pRxBuffPtr = pData; + hsmartcard->RxXferSize = Size; + + /* Set the SMARTCARD DMA transfer complete callback */ + hsmartcard->hdmarx->XferCpltCallback = SMARTCARD_DMAReceiveCplt; + + /* Set the SMARTCARD DMA error callback */ + hsmartcard->hdmarx->XferErrorCallback = SMARTCARD_DMAError; + + /* Set the DMA abort callback */ + hsmartcard->hdmarx->XferAbortCallback = NULL; + + /* Check linked list mode */ + if ((hsmartcard->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hsmartcard->hdmarx->LinkedListQueue != NULL) && (hsmartcard->hdmarx->LinkedListQueue->Head != NULL)) + { + /* Set DMA data size */ + hsmartcard->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = Size; + + /* Set DMA source address */ + hsmartcard->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = + (uint32_t)&hsmartcard->Instance->RDR; + + /* Set DMA destination address */ + hsmartcard->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = + (uint32_t)hsmartcard->pRxBuffPtr; + + /* Enable the SMARTCARD receive DMA channel */ + status = HAL_DMAEx_List_Start_IT(hsmartcard->hdmarx); + } + else + { + /* Update status */ + status = HAL_ERROR; + } + } + else + { + /* Enable the DMA channel */ + status = HAL_DMA_Start_IT(hsmartcard->hdmarx, (uint32_t)&hsmartcard->Instance->RDR, + (uint32_t)hsmartcard->pRxBuffPtr, Size); + } + + if (status == HAL_OK) + { + /* Process Unlocked */ + __HAL_UNLOCK(hsmartcard); + + /* Enable the SMARTCARD Parity Error Interrupt */ + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_PEIE); + + /* Enable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */ + SET_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + + /* Enable the DMA transfer for the receiver request by setting the DMAR bit + in the SMARTCARD associated USART CR3 register */ + SET_BIT(hsmartcard->Instance->CR3, USART_CR3_DMAR); + + return HAL_OK; + } + else + { + /* Set error code to DMA */ + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmartcard); + + /* Restore hsmartcard->State to ready */ + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + + return HAL_ERROR; + } + } + else + { + return HAL_BUSY; + } +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Abort ongoing transfers (blocking mode). + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable SMARTCARD Interrupts (Tx and Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARD_Abort(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Disable RTOIE, EOBIE, TXEIE, TCIE, RXNE, PE, RXFT, TXFT and + ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hsmartcard->Instance->CR1, + (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE | USART_CR1_RTOIE | + USART_CR1_EOBIE)); + CLEAR_BIT(hsmartcard->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE)); + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Disable the SMARTCARD DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAT)) + { + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_DMAT); + + /* Abort the SMARTCARD DMA Tx channel : use blocking DMA Abort API (no callback) */ + if (hsmartcard->hdmatx != NULL) + { + /* Set the SMARTCARD DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + hsmartcard->hdmatx->XferAbortCallback = NULL; + + if (HAL_DMA_Abort(hsmartcard->hdmatx) != HAL_OK) + { + if (HAL_DMA_GetError(hsmartcard->hdmatx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + } + } + + /* Disable the SMARTCARD DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_DMAR); + + /* Abort the SMARTCARD DMA Rx channel : use blocking DMA Abort API (no callback) */ + if (hsmartcard->hdmarx != NULL) + { + /* Set the SMARTCARD DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + hsmartcard->hdmarx->XferAbortCallback = NULL; + + if (HAL_DMA_Abort(hsmartcard->hdmarx) != HAL_OK) + { + if (HAL_DMA_GetError(hsmartcard->hdmarx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + } + } +#endif /* HAL_DMA_MODULE_ENABLED */ + + /* Reset Tx and Rx transfer counters */ + hsmartcard->TxXferCount = 0U; + hsmartcard->RxXferCount = 0U; + + /* Clear the Error flags in the ICR register */ + __HAL_SMARTCARD_CLEAR_FLAG(hsmartcard, + SMARTCARD_CLEAR_OREF | SMARTCARD_CLEAR_NEF | SMARTCARD_CLEAR_PEF | SMARTCARD_CLEAR_FEF | + SMARTCARD_CLEAR_RTOF | SMARTCARD_CLEAR_EOBF); + + /* Restore hsmartcard->gState and hsmartcard->RxState to Ready */ + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + + /* Reset Handle ErrorCode to No Error */ + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + + return HAL_OK; +} + +/** + * @brief Abort ongoing Transmit transfer (blocking mode). + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable SMARTCARD Interrupts (Tx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARD_AbortTransmit(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Disable TCIE, TXEIE and TXFTIE interrupts */ + CLEAR_BIT(hsmartcard->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE)); + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_TXFTIE); + + /* Check if a receive process is ongoing or not. If not disable ERR IT */ + if (hsmartcard->RxState == HAL_SMARTCARD_STATE_READY) + { + /* Disable the SMARTCARD Error Interrupt: (Frame error) */ + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + } + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Disable the SMARTCARD DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAT)) + { + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_DMAT); + + /* Abort the SMARTCARD DMA Tx channel : use blocking DMA Abort API (no callback) */ + if (hsmartcard->hdmatx != NULL) + { + /* Set the SMARTCARD DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + hsmartcard->hdmatx->XferAbortCallback = NULL; + + if (HAL_DMA_Abort(hsmartcard->hdmatx) != HAL_OK) + { + if (HAL_DMA_GetError(hsmartcard->hdmatx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + } + } +#endif /* HAL_DMA_MODULE_ENABLED */ + + /* Reset Tx transfer counter */ + hsmartcard->TxXferCount = 0U; + + /* Clear the Error flags in the ICR register */ + __HAL_SMARTCARD_CLEAR_FLAG(hsmartcard, SMARTCARD_CLEAR_FEF); + + /* Restore hsmartcard->gState to Ready */ + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Abort ongoing Receive transfer (blocking mode). + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable SMARTCARD Interrupts (Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARD_AbortReceive(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Disable RTOIE, EOBIE, RXNE, PE, RXFT, TXFT and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hsmartcard->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_RTOIE | + USART_CR1_EOBIE)); + CLEAR_BIT(hsmartcard->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE)); + + /* Check if a Transmit process is ongoing or not. If not disable ERR IT */ + if (hsmartcard->gState == HAL_SMARTCARD_STATE_READY) + { + /* Disable the SMARTCARD Error Interrupt: (Frame error) */ + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + } + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Disable the SMARTCARD DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_DMAR); + + /* Abort the SMARTCARD DMA Rx channel : use blocking DMA Abort API (no callback) */ + if (hsmartcard->hdmarx != NULL) + { + /* Set the SMARTCARD DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + hsmartcard->hdmarx->XferAbortCallback = NULL; + + if (HAL_DMA_Abort(hsmartcard->hdmarx) != HAL_OK) + { + if (HAL_DMA_GetError(hsmartcard->hdmarx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + } + } +#endif /* HAL_DMA_MODULE_ENABLED */ + + /* Reset Rx transfer counter */ + hsmartcard->RxXferCount = 0U; + + /* Clear the Error flags in the ICR register */ + __HAL_SMARTCARD_CLEAR_FLAG(hsmartcard, + SMARTCARD_CLEAR_OREF | SMARTCARD_CLEAR_NEF | SMARTCARD_CLEAR_PEF | SMARTCARD_CLEAR_FEF | + SMARTCARD_CLEAR_RTOF | SMARTCARD_CLEAR_EOBF); + + /* Restore hsmartcard->RxState to Ready */ + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Abort ongoing transfers (Interrupt mode). + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable SMARTCARD Interrupts (Tx and Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARD_Abort_IT(SMARTCARD_HandleTypeDef *hsmartcard) +{ + uint32_t abortcplt = 1U; + + /* Disable RTOIE, EOBIE, TXEIE, TCIE, RXNE, PE, RXFT, TXFT and + ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hsmartcard->Instance->CR1, + (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE | USART_CR1_RTOIE | + USART_CR1_EOBIE)); + CLEAR_BIT(hsmartcard->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE)); + +#if defined(HAL_DMA_MODULE_ENABLED) + /* If DMA Tx and/or DMA Rx Handles are associated to SMARTCARD Handle, + DMA Abort complete callbacks should be initialised before any call + to DMA Abort functions */ + /* DMA Tx Handle is valid */ + if (hsmartcard->hdmatx != NULL) + { + /* Set DMA Abort Complete callback if SMARTCARD DMA Tx request if enabled. + Otherwise, set it to NULL */ + if (HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAT)) + { + hsmartcard->hdmatx->XferAbortCallback = SMARTCARD_DMATxAbortCallback; + } + else + { + hsmartcard->hdmatx->XferAbortCallback = NULL; + } + } + /* DMA Rx Handle is valid */ + if (hsmartcard->hdmarx != NULL) + { + /* Set DMA Abort Complete callback if SMARTCARD DMA Rx request if enabled. + Otherwise, set it to NULL */ + if (HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAR)) + { + hsmartcard->hdmarx->XferAbortCallback = SMARTCARD_DMARxAbortCallback; + } + else + { + hsmartcard->hdmarx->XferAbortCallback = NULL; + } + } + + /* Disable the SMARTCARD DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAT)) + { + /* Disable DMA Tx at UART level */ + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_DMAT); + + /* Abort the SMARTCARD DMA Tx channel : use non blocking DMA Abort API (callback) */ + if (hsmartcard->hdmatx != NULL) + { + /* SMARTCARD Tx DMA Abort callback has already been initialised : + will lead to call HAL_SMARTCARD_AbortCpltCallback() at end of DMA abort procedure */ + + /* Abort DMA TX */ + if (HAL_DMA_Abort_IT(hsmartcard->hdmatx) != HAL_OK) + { + hsmartcard->hdmatx->XferAbortCallback = NULL; + } + else + { + abortcplt = 0U; + } + } + } + + /* Disable the SMARTCARD DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_DMAR); + + /* Abort the SMARTCARD DMA Rx channel : use non blocking DMA Abort API (callback) */ + if (hsmartcard->hdmarx != NULL) + { + /* SMARTCARD Rx DMA Abort callback has already been initialised : + will lead to call HAL_SMARTCARD_AbortCpltCallback() at end of DMA abort procedure */ + + /* Abort DMA RX */ + if (HAL_DMA_Abort_IT(hsmartcard->hdmarx) != HAL_OK) + { + hsmartcard->hdmarx->XferAbortCallback = NULL; + abortcplt = 1U; + } + else + { + abortcplt = 0U; + } + } + } +#endif /* HAL_DMA_MODULE_ENABLED */ + + /* if no DMA abort complete callback execution is required => call user Abort Complete callback */ + if (abortcplt == 1U) + { + /* Reset Tx and Rx transfer counters */ + hsmartcard->TxXferCount = 0U; + hsmartcard->RxXferCount = 0U; + + /* Clear ISR function pointers */ + hsmartcard->RxISR = NULL; + hsmartcard->TxISR = NULL; + + /* Reset errorCode */ + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + + /* Clear the Error flags in the ICR register */ + __HAL_SMARTCARD_CLEAR_FLAG(hsmartcard, + SMARTCARD_CLEAR_OREF | SMARTCARD_CLEAR_NEF | SMARTCARD_CLEAR_PEF | + SMARTCARD_CLEAR_FEF | SMARTCARD_CLEAR_RTOF | SMARTCARD_CLEAR_EOBF); + + /* Restore hsmartcard->gState and hsmartcard->RxState to Ready */ + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) + /* Call registered Abort complete callback */ + hsmartcard->AbortCpltCallback(hsmartcard); +#else + /* Call legacy weak Abort complete callback */ + HAL_SMARTCARD_AbortCpltCallback(hsmartcard); +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */ + } + + return HAL_OK; +} + +/** + * @brief Abort ongoing Transmit transfer (Interrupt mode). + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable SMARTCARD Interrupts (Tx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARD_AbortTransmit_IT(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Disable TCIE, TXEIE and TXFTIE interrupts */ + CLEAR_BIT(hsmartcard->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE)); + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_TXFTIE); + + /* Check if a receive process is ongoing or not. If not disable ERR IT */ + if (hsmartcard->RxState == HAL_SMARTCARD_STATE_READY) + { + /* Disable the SMARTCARD Error Interrupt: (Frame error) */ + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + } + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Disable the SMARTCARD DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAT)) + { + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_DMAT); + + /* Abort the SMARTCARD DMA Tx channel : use non blocking DMA Abort API (callback) */ + if (hsmartcard->hdmatx != NULL) + { + /* Set the SMARTCARD DMA Abort callback : + will lead to call HAL_SMARTCARD_AbortCpltCallback() at end of DMA abort procedure */ + hsmartcard->hdmatx->XferAbortCallback = SMARTCARD_DMATxOnlyAbortCallback; + + /* Abort DMA TX */ + if (HAL_DMA_Abort_IT(hsmartcard->hdmatx) != HAL_OK) + { + /* Call Directly hsmartcard->hdmatx->XferAbortCallback function in case of error */ + hsmartcard->hdmatx->XferAbortCallback(hsmartcard->hdmatx); + } + } + else + { + /* Reset Tx transfer counter */ + hsmartcard->TxXferCount = 0U; + + /* Clear TxISR function pointers */ + hsmartcard->TxISR = NULL; + + /* Restore hsmartcard->gState to Ready */ + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) + /* Call registered Abort Transmit Complete Callback */ + hsmartcard->AbortTransmitCpltCallback(hsmartcard); +#else + /* Call legacy weak Abort Transmit Complete Callback */ + HAL_SMARTCARD_AbortTransmitCpltCallback(hsmartcard); +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */ + } + } + else +#endif /* HAL_DMA_MODULE_ENABLED */ + { + /* Reset Tx transfer counter */ + hsmartcard->TxXferCount = 0U; + + /* Clear TxISR function pointers */ + hsmartcard->TxISR = NULL; + + /* Clear the Error flags in the ICR register */ + __HAL_SMARTCARD_CLEAR_FLAG(hsmartcard, SMARTCARD_CLEAR_FEF); + + /* Restore hsmartcard->gState to Ready */ + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) + /* Call registered Abort Transmit Complete Callback */ + hsmartcard->AbortTransmitCpltCallback(hsmartcard); +#else + /* Call legacy weak Abort Transmit Complete Callback */ + HAL_SMARTCARD_AbortTransmitCpltCallback(hsmartcard); +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */ + } + + return HAL_OK; +} + +/** + * @brief Abort ongoing Receive transfer (Interrupt mode). + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable SMARTCARD Interrupts (Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARD_AbortReceive_IT(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Disable RTOIE, EOBIE, RXNE, PE, RXFT and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hsmartcard->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_RTOIE | + USART_CR1_EOBIE)); + CLEAR_BIT(hsmartcard->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE)); + + /* Check if a Transmit process is ongoing or not. If not disable ERR IT */ + if (hsmartcard->gState == HAL_SMARTCARD_STATE_READY) + { + /* Disable the SMARTCARD Error Interrupt: (Frame error) */ + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + } + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Disable the SMARTCARD DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_DMAR); + + /* Abort the SMARTCARD DMA Rx channel : use non blocking DMA Abort API (callback) */ + if (hsmartcard->hdmarx != NULL) + { + /* Set the SMARTCARD DMA Abort callback : + will lead to call HAL_SMARTCARD_AbortCpltCallback() at end of DMA abort procedure */ + hsmartcard->hdmarx->XferAbortCallback = SMARTCARD_DMARxOnlyAbortCallback; + + /* Abort DMA RX */ + if (HAL_DMA_Abort_IT(hsmartcard->hdmarx) != HAL_OK) + { + /* Call Directly hsmartcard->hdmarx->XferAbortCallback function in case of error */ + hsmartcard->hdmarx->XferAbortCallback(hsmartcard->hdmarx); + } + } + else + { + /* Reset Rx transfer counter */ + hsmartcard->RxXferCount = 0U; + + /* Clear RxISR function pointer */ + hsmartcard->RxISR = NULL; + + /* Clear the Error flags in the ICR register */ + __HAL_SMARTCARD_CLEAR_FLAG(hsmartcard, + SMARTCARD_CLEAR_OREF | SMARTCARD_CLEAR_NEF | SMARTCARD_CLEAR_PEF | + SMARTCARD_CLEAR_FEF | SMARTCARD_CLEAR_RTOF | SMARTCARD_CLEAR_EOBF); + + /* Restore hsmartcard->RxState to Ready */ + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) + /* Call registered Abort Receive Complete Callback */ + hsmartcard->AbortReceiveCpltCallback(hsmartcard); +#else + /* Call legacy weak Abort Receive Complete Callback */ + HAL_SMARTCARD_AbortReceiveCpltCallback(hsmartcard); +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */ + } + } + else +#endif /* HAL_DMA_MODULE_ENABLED */ + { + /* Reset Rx transfer counter */ + hsmartcard->RxXferCount = 0U; + + /* Clear RxISR function pointer */ + hsmartcard->RxISR = NULL; + + /* Clear the Error flags in the ICR register */ + __HAL_SMARTCARD_CLEAR_FLAG(hsmartcard, + SMARTCARD_CLEAR_OREF | SMARTCARD_CLEAR_NEF | SMARTCARD_CLEAR_PEF | + SMARTCARD_CLEAR_FEF | SMARTCARD_CLEAR_RTOF | SMARTCARD_CLEAR_EOBF); + + /* Restore hsmartcard->RxState to Ready */ + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) + /* Call registered Abort Receive Complete Callback */ + hsmartcard->AbortReceiveCpltCallback(hsmartcard); +#else + /* Call legacy weak Abort Receive Complete Callback */ + HAL_SMARTCARD_AbortReceiveCpltCallback(hsmartcard); +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */ + } + + return HAL_OK; +} + +/** + * @brief Handle SMARTCARD interrupt requests. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval None + */ +void HAL_SMARTCARD_IRQHandler(SMARTCARD_HandleTypeDef *hsmartcard) +{ + uint32_t isrflags = READ_REG(hsmartcard->Instance->ISR); + uint32_t cr1its = READ_REG(hsmartcard->Instance->CR1); + uint32_t cr3its = READ_REG(hsmartcard->Instance->CR3); + uint32_t errorflags; + uint32_t errorcode; + + /* If no error occurs */ + errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE | USART_ISR_RTOF)); + if (errorflags == 0U) + { + /* SMARTCARD in mode Receiver ---------------------------------------------------*/ + if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U) + && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) + || ((cr3its & USART_CR3_RXFTIE) != 0U))) + { + if (hsmartcard->RxISR != NULL) + { + hsmartcard->RxISR(hsmartcard); + } + return; + } + } + + /* If some errors occur */ + if ((errorflags != 0U) + && ((((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U) + || ((cr1its & (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)) != 0U)))) + { + /* SMARTCARD parity error interrupt occurred -------------------------------------*/ + if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U)) + { + __HAL_SMARTCARD_CLEAR_IT(hsmartcard, SMARTCARD_CLEAR_PEF); + + hsmartcard->ErrorCode |= HAL_SMARTCARD_ERROR_PE; + } + + /* SMARTCARD frame error interrupt occurred --------------------------------------*/ + if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) + { + __HAL_SMARTCARD_CLEAR_IT(hsmartcard, SMARTCARD_CLEAR_FEF); + + hsmartcard->ErrorCode |= HAL_SMARTCARD_ERROR_FE; + } + + /* SMARTCARD noise error interrupt occurred --------------------------------------*/ + if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) + { + __HAL_SMARTCARD_CLEAR_IT(hsmartcard, SMARTCARD_CLEAR_NEF); + + hsmartcard->ErrorCode |= HAL_SMARTCARD_ERROR_NE; + } + + /* SMARTCARD Over-Run interrupt occurred -----------------------------------------*/ + if (((isrflags & USART_ISR_ORE) != 0U) + && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) + || ((cr3its & USART_CR3_RXFTIE) != 0U) + || ((cr3its & USART_CR3_EIE) != 0U))) + { + __HAL_SMARTCARD_CLEAR_IT(hsmartcard, SMARTCARD_CLEAR_OREF); + + hsmartcard->ErrorCode |= HAL_SMARTCARD_ERROR_ORE; + } + + /* SMARTCARD receiver timeout interrupt occurred -----------------------------------------*/ + if (((isrflags & USART_ISR_RTOF) != 0U) && ((cr1its & USART_CR1_RTOIE) != 0U)) + { + __HAL_SMARTCARD_CLEAR_IT(hsmartcard, SMARTCARD_CLEAR_RTOF); + + hsmartcard->ErrorCode |= HAL_SMARTCARD_ERROR_RTO; + } + + /* Call SMARTCARD Error Call back function if need be --------------------------*/ + if (hsmartcard->ErrorCode != HAL_SMARTCARD_ERROR_NONE) + { + /* SMARTCARD in mode Receiver ---------------------------------------------------*/ + if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U) + && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) + || ((cr3its & USART_CR3_RXFTIE) != 0U))) + { + if (hsmartcard->RxISR != NULL) + { + hsmartcard->RxISR(hsmartcard); + } + } + + /* If Error is to be considered as blocking : + - Receiver Timeout error in Reception + - Overrun error in Reception + - any error occurs in DMA mode reception + */ + errorcode = hsmartcard->ErrorCode; + if ((HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAR)) + || ((errorcode & (HAL_SMARTCARD_ERROR_RTO | HAL_SMARTCARD_ERROR_ORE)) != 0U)) + { + /* Blocking error : transfer is aborted + Set the SMARTCARD state ready to be able to start again the process, + Disable Rx Interrupts, and disable Rx DMA request, if ongoing */ + SMARTCARD_EndRxTransfer(hsmartcard); + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Disable the SMARTCARD DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_DMAR); + + /* Abort the SMARTCARD DMA Rx channel */ + if (hsmartcard->hdmarx != NULL) + { + /* Set the SMARTCARD DMA Abort callback : + will lead to call HAL_SMARTCARD_ErrorCallback() at end of DMA abort procedure */ + hsmartcard->hdmarx->XferAbortCallback = SMARTCARD_DMAAbortOnError; + + /* Abort DMA RX */ + if (HAL_DMA_Abort_IT(hsmartcard->hdmarx) != HAL_OK) + { + /* Call Directly hsmartcard->hdmarx->XferAbortCallback function in case of error */ + hsmartcard->hdmarx->XferAbortCallback(hsmartcard->hdmarx); + } + } + else + { +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) + /* Call registered user error callback */ + hsmartcard->ErrorCallback(hsmartcard); +#else + /* Call legacy weak user error callback */ + HAL_SMARTCARD_ErrorCallback(hsmartcard); +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */ + } + } + else +#endif /* HAL_DMA_MODULE_ENABLED */ + { +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) + /* Call registered user error callback */ + hsmartcard->ErrorCallback(hsmartcard); +#else + /* Call legacy weak user error callback */ + HAL_SMARTCARD_ErrorCallback(hsmartcard); +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */ + } + } + /* other error type to be considered as blocking : + - Frame error in Transmission + */ + else if ((hsmartcard->gState == HAL_SMARTCARD_STATE_BUSY_TX) + && ((errorcode & HAL_SMARTCARD_ERROR_FE) != 0U)) + { + /* Blocking error : transfer is aborted + Set the SMARTCARD state ready to be able to start again the process, + Disable Tx Interrupts, and disable Tx DMA request, if ongoing */ + SMARTCARD_EndTxTransfer(hsmartcard); + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Disable the SMARTCARD DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAT)) + { + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_DMAT); + + /* Abort the SMARTCARD DMA Tx channel */ + if (hsmartcard->hdmatx != NULL) + { + /* Set the SMARTCARD DMA Abort callback : + will lead to call HAL_SMARTCARD_ErrorCallback() at end of DMA abort procedure */ + hsmartcard->hdmatx->XferAbortCallback = SMARTCARD_DMAAbortOnError; + + /* Abort DMA TX */ + if (HAL_DMA_Abort_IT(hsmartcard->hdmatx) != HAL_OK) + { + /* Call Directly hsmartcard->hdmatx->XferAbortCallback function in case of error */ + hsmartcard->hdmatx->XferAbortCallback(hsmartcard->hdmatx); + } + } + else + { +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) + /* Call registered user error callback */ + hsmartcard->ErrorCallback(hsmartcard); +#else + /* Call legacy weak user error callback */ + HAL_SMARTCARD_ErrorCallback(hsmartcard); +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */ + } + } + else +#endif /* HAL_DMA_MODULE_ENABLED */ + { +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) + /* Call registered user error callback */ + hsmartcard->ErrorCallback(hsmartcard); +#else + /* Call legacy weak user error callback */ + HAL_SMARTCARD_ErrorCallback(hsmartcard); +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */ + } + } + else + { + /* Non Blocking error : transfer could go on. + Error is notified to user through user error callback */ +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) + /* Call registered user error callback */ + hsmartcard->ErrorCallback(hsmartcard); +#else + /* Call legacy weak user error callback */ + HAL_SMARTCARD_ErrorCallback(hsmartcard); +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */ + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + } + } + return; + + } /* End if some error occurs */ + + /* SMARTCARD in mode Receiver, end of block interruption ------------------------*/ + if (((isrflags & USART_ISR_EOBF) != 0U) && ((cr1its & USART_CR1_EOBIE) != 0U)) + { + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + __HAL_UNLOCK(hsmartcard); +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) + /* Call registered Rx complete callback */ + hsmartcard->RxCpltCallback(hsmartcard); +#else + /* Call legacy weak Rx complete callback */ + HAL_SMARTCARD_RxCpltCallback(hsmartcard); +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */ + /* Clear EOBF interrupt after HAL_SMARTCARD_RxCpltCallback() call for the End of Block information + to be available during HAL_SMARTCARD_RxCpltCallback() processing */ + __HAL_SMARTCARD_CLEAR_IT(hsmartcard, SMARTCARD_CLEAR_EOBF); + return; + } + + /* SMARTCARD in mode Transmitter ------------------------------------------------*/ + if (((isrflags & USART_ISR_TXE_TXFNF) != 0U) + && (((cr1its & USART_CR1_TXEIE_TXFNFIE) != 0U) + || ((cr3its & USART_CR3_TXFTIE) != 0U))) + { + if (hsmartcard->TxISR != NULL) + { + hsmartcard->TxISR(hsmartcard); + } + return; + } + + /* SMARTCARD in mode Transmitter (transmission end) ------------------------*/ + if (__HAL_SMARTCARD_GET_IT(hsmartcard, hsmartcard->AdvancedInit.TxCompletionIndication) != RESET) + { + if (__HAL_SMARTCARD_GET_IT_SOURCE(hsmartcard, hsmartcard->AdvancedInit.TxCompletionIndication) != RESET) + { + SMARTCARD_EndTransmit_IT(hsmartcard); + return; + } + } + + /* SMARTCARD TX Fifo Empty occurred ----------------------------------------------*/ + if (((isrflags & USART_ISR_TXFE) != 0U) && ((cr1its & USART_CR1_TXFEIE) != 0U)) + { +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) + /* Call registered Tx Fifo Empty Callback */ + hsmartcard->TxFifoEmptyCallback(hsmartcard); +#else + /* Call legacy weak Tx Fifo Empty Callback */ + HAL_SMARTCARDEx_TxFifoEmptyCallback(hsmartcard); +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */ + return; + } + + /* SMARTCARD RX Fifo Full occurred ----------------------------------------------*/ + if (((isrflags & USART_ISR_RXFF) != 0U) && ((cr1its & USART_CR1_RXFFIE) != 0U)) + { +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) + /* Call registered Rx Fifo Full Callback */ + hsmartcard->RxFifoFullCallback(hsmartcard); +#else + /* Call legacy weak Rx Fifo Full Callback */ + HAL_SMARTCARDEx_RxFifoFullCallback(hsmartcard); +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */ + return; + } +} + +/** + * @brief Tx Transfer completed callback. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval None + */ +__weak void HAL_SMARTCARD_TxCpltCallback(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsmartcard); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMARTCARD_TxCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief Rx Transfer completed callback. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval None + */ +__weak void HAL_SMARTCARD_RxCpltCallback(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsmartcard); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMARTCARD_RxCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief SMARTCARD error callback. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval None + */ +__weak void HAL_SMARTCARD_ErrorCallback(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsmartcard); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMARTCARD_ErrorCallback can be implemented in the user file. + */ +} + +/** + * @brief SMARTCARD Abort Complete callback. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval None + */ +__weak void HAL_SMARTCARD_AbortCpltCallback(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsmartcard); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMARTCARD_AbortCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief SMARTCARD Abort Complete callback. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval None + */ +__weak void HAL_SMARTCARD_AbortTransmitCpltCallback(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsmartcard); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMARTCARD_AbortTransmitCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief SMARTCARD Abort Receive Complete callback. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval None + */ +__weak void HAL_SMARTCARD_AbortReceiveCpltCallback(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsmartcard); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMARTCARD_AbortReceiveCpltCallback can be implemented in the user file. + */ +} + +/** + * @} + */ + +/** @defgroup SMARTCARD_Exported_Functions_Group4 Peripheral State and Errors functions + * @brief SMARTCARD State and Errors functions + * +@verbatim + ============================================================================== + ##### Peripheral State and Errors functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to return the State of SmartCard + handle and also return Peripheral Errors occurred during communication process + (+) HAL_SMARTCARD_GetState() API can be helpful to check in run-time the state + of the SMARTCARD peripheral. + (+) HAL_SMARTCARD_GetError() checks in run-time errors that could occur during + communication. + +@endverbatim + * @{ + */ + +/** + * @brief Return the SMARTCARD handle state. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval SMARTCARD handle state + */ +HAL_SMARTCARD_StateTypeDef HAL_SMARTCARD_GetState(const SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Return SMARTCARD handle state */ + uint32_t temp1; + uint32_t temp2; + temp1 = (uint32_t)hsmartcard->gState; + temp2 = (uint32_t)hsmartcard->RxState; + + return (HAL_SMARTCARD_StateTypeDef)(temp1 | temp2); +} + +/** + * @brief Return the SMARTCARD handle error code. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval SMARTCARD handle Error Code + */ +uint32_t HAL_SMARTCARD_GetError(const SMARTCARD_HandleTypeDef *hsmartcard) +{ + return hsmartcard->ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup SMARTCARD_Private_Functions SMARTCARD Private Functions + * @{ + */ + +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) +/** + * @brief Initialize the callbacks to their default values. + * @param hsmartcard SMARTCARD handle. + * @retval none + */ +void SMARTCARD_InitCallbacksToDefault(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Init the SMARTCARD Callback settings */ + hsmartcard->TxCpltCallback = HAL_SMARTCARD_TxCpltCallback; /* Legacy weak TxCpltCallback */ + hsmartcard->RxCpltCallback = HAL_SMARTCARD_RxCpltCallback; /* Legacy weak RxCpltCallback */ + hsmartcard->ErrorCallback = HAL_SMARTCARD_ErrorCallback; /* Legacy weak ErrorCallback */ + hsmartcard->AbortCpltCallback = HAL_SMARTCARD_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ + hsmartcard->AbortTransmitCpltCallback = HAL_SMARTCARD_AbortTransmitCpltCallback; /* Legacy weak + AbortTransmitCpltCallback */ + hsmartcard->AbortReceiveCpltCallback = HAL_SMARTCARD_AbortReceiveCpltCallback; /* Legacy weak + AbortReceiveCpltCallback */ + hsmartcard->RxFifoFullCallback = HAL_SMARTCARDEx_RxFifoFullCallback; /* Legacy weak + RxFifoFullCallback */ + hsmartcard->TxFifoEmptyCallback = HAL_SMARTCARDEx_TxFifoEmptyCallback; /* Legacy weak + TxFifoEmptyCallback */ + +} +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACKS */ + +/** + * @brief Configure the SMARTCARD associated USART peripheral. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval HAL status + */ +static HAL_StatusTypeDef SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef *hsmartcard) +{ + uint32_t tmpreg; + SMARTCARD_ClockSourceTypeDef clocksource; + HAL_StatusTypeDef ret = HAL_OK; + static const uint16_t SMARTCARDPrescTable[12] = {1U, 2U, 4U, 6U, 8U, 10U, 12U, 16U, 32U, 64U, 128U, 256U}; + PLL2_ClocksTypeDef pll2_clocks; +#if defined(RCC_CR_PLL3ON) + PLL3_ClocksTypeDef pll3_clocks; +#endif /* RCC_CR_PLL3ON */ + uint32_t pclk; + + /* Check the parameters */ + assert_param(IS_SMARTCARD_INSTANCE(hsmartcard->Instance)); + assert_param(IS_SMARTCARD_BAUDRATE(hsmartcard->Init.BaudRate)); + assert_param(IS_SMARTCARD_WORD_LENGTH(hsmartcard->Init.WordLength)); + assert_param(IS_SMARTCARD_STOPBITS(hsmartcard->Init.StopBits)); + assert_param(IS_SMARTCARD_PARITY(hsmartcard->Init.Parity)); + assert_param(IS_SMARTCARD_MODE(hsmartcard->Init.Mode)); + assert_param(IS_SMARTCARD_POLARITY(hsmartcard->Init.CLKPolarity)); + assert_param(IS_SMARTCARD_PHASE(hsmartcard->Init.CLKPhase)); + assert_param(IS_SMARTCARD_LASTBIT(hsmartcard->Init.CLKLastBit)); + assert_param(IS_SMARTCARD_ONE_BIT_SAMPLE(hsmartcard->Init.OneBitSampling)); + assert_param(IS_SMARTCARD_NACK(hsmartcard->Init.NACKEnable)); + assert_param(IS_SMARTCARD_TIMEOUT(hsmartcard->Init.TimeOutEnable)); + assert_param(IS_SMARTCARD_AUTORETRY_COUNT(hsmartcard->Init.AutoRetryCount)); + assert_param(IS_SMARTCARD_CLOCKPRESCALER(hsmartcard->Init.ClockPrescaler)); + + /*-------------------------- USART CR1 Configuration -----------------------*/ + /* In SmartCard mode, M and PCE are forced to 1 (8 bits + parity). + * Oversampling is forced to 16 (OVER8 = 0). + * Configure the Parity and Mode: + * set PS bit according to hsmartcard->Init.Parity value + * set TE and RE bits according to hsmartcard->Init.Mode value */ + tmpreg = (((uint32_t)hsmartcard->Init.Parity) | ((uint32_t)hsmartcard->Init.Mode) | + ((uint32_t)hsmartcard->Init.WordLength)); + MODIFY_REG(hsmartcard->Instance->CR1, USART_CR1_FIELDS, tmpreg); + + /*-------------------------- USART CR2 Configuration -----------------------*/ + tmpreg = hsmartcard->Init.StopBits; + /* Synchronous mode is activated by default */ + tmpreg |= (uint32_t) USART_CR2_CLKEN | hsmartcard->Init.CLKPolarity; + tmpreg |= (uint32_t) hsmartcard->Init.CLKPhase | hsmartcard->Init.CLKLastBit; + tmpreg |= (uint32_t) hsmartcard->Init.TimeOutEnable; + MODIFY_REG(hsmartcard->Instance->CR2, USART_CR2_FIELDS, tmpreg); + + /*-------------------------- USART CR3 Configuration -----------------------*/ + /* Configure + * - one-bit sampling method versus three samples' majority rule + * according to hsmartcard->Init.OneBitSampling + * - NACK transmission in case of parity error according + * to hsmartcard->Init.NACKEnable + * - autoretry counter according to hsmartcard->Init.AutoRetryCount */ + + tmpreg = (uint32_t) hsmartcard->Init.OneBitSampling | hsmartcard->Init.NACKEnable; + tmpreg |= ((uint32_t)hsmartcard->Init.AutoRetryCount << USART_CR3_SCARCNT_Pos); + MODIFY_REG(hsmartcard->Instance->CR3, USART_CR3_FIELDS, tmpreg); + + /*--------------------- SMARTCARD clock PRESC Configuration ----------------*/ + /* Configure + * - SMARTCARD Clock Prescaler: set PRESCALER according to hsmartcard->Init.ClockPrescaler value */ + MODIFY_REG(hsmartcard->Instance->PRESC, USART_PRESC_PRESCALER, hsmartcard->Init.ClockPrescaler); + + /*-------------------------- USART GTPR Configuration ----------------------*/ + tmpreg = (hsmartcard->Init.Prescaler | ((uint32_t)hsmartcard->Init.GuardTime << USART_GTPR_GT_Pos)); + MODIFY_REG(hsmartcard->Instance->GTPR, (uint16_t)(USART_GTPR_GT | USART_GTPR_PSC), (uint16_t)tmpreg); + + /*-------------------------- USART RTOR Configuration ----------------------*/ + tmpreg = ((uint32_t)hsmartcard->Init.BlockLength << USART_RTOR_BLEN_Pos); + if (hsmartcard->Init.TimeOutEnable == SMARTCARD_TIMEOUT_ENABLE) + { + assert_param(IS_SMARTCARD_TIMEOUT_VALUE(hsmartcard->Init.TimeOutValue)); + tmpreg |= (uint32_t) hsmartcard->Init.TimeOutValue; + } + MODIFY_REG(hsmartcard->Instance->RTOR, (USART_RTOR_RTO | USART_RTOR_BLEN), tmpreg); + + /*-------------------------- USART BRR Configuration -----------------------*/ + SMARTCARD_GETCLOCKSOURCE(hsmartcard, clocksource); + tmpreg = 0U; + switch (clocksource) + { + case SMARTCARD_CLOCKSOURCE_PCLK1: + pclk = HAL_RCC_GetPCLK1Freq(); + tmpreg = (uint32_t)(((pclk / SMARTCARDPrescTable[hsmartcard->Init.ClockPrescaler]) + + (hsmartcard->Init.BaudRate / 2U)) / hsmartcard->Init.BaudRate); + break; + case SMARTCARD_CLOCKSOURCE_PCLK2: + pclk = HAL_RCC_GetPCLK2Freq(); + tmpreg = (uint32_t)(((pclk / SMARTCARDPrescTable[hsmartcard->Init.ClockPrescaler]) + + (hsmartcard->Init.BaudRate / 2U)) / hsmartcard->Init.BaudRate); + break; + case SMARTCARD_CLOCKSOURCE_PLL2Q: + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + tmpreg = (uint32_t)(((pll2_clocks.PLL2_Q_Frequency / SMARTCARDPrescTable[hsmartcard->Init.ClockPrescaler]) + + (hsmartcard->Init.BaudRate / 2U)) / hsmartcard->Init.BaudRate); + break; +#if defined(RCC_CR_PLL3ON) + case SMARTCARD_CLOCKSOURCE_PLL3Q: + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + tmpreg = (uint32_t)(((pll3_clocks.PLL3_Q_Frequency / SMARTCARDPrescTable[hsmartcard->Init.ClockPrescaler]) + + (hsmartcard->Init.BaudRate / 2U)) / hsmartcard->Init.BaudRate); + break; +#endif /* RCC_CR_PLL3ON */ + case SMARTCARD_CLOCKSOURCE_HSI: + tmpreg = (uint32_t)(((HSI_VALUE / SMARTCARDPrescTable[hsmartcard->Init.ClockPrescaler]) + + (hsmartcard->Init.BaudRate / 2U)) / hsmartcard->Init.BaudRate); + break; + case SMARTCARD_CLOCKSOURCE_CSI: + tmpreg = (uint32_t)(((CSI_VALUE / SMARTCARDPrescTable[hsmartcard->Init.ClockPrescaler]) + + (hsmartcard->Init.BaudRate / 2U)) / hsmartcard->Init.BaudRate); + break; + case SMARTCARD_CLOCKSOURCE_LSE: + tmpreg = (uint32_t)(((uint16_t)(LSE_VALUE / SMARTCARDPrescTable[hsmartcard->Init.ClockPrescaler]) + + (hsmartcard->Init.BaudRate / 2U)) / hsmartcard->Init.BaudRate); + break; + default: + ret = HAL_ERROR; + break; + } + + /* USARTDIV must be greater than or equal to 0d16 */ + if ((tmpreg >= USART_BRR_MIN) && (tmpreg <= USART_BRR_MAX)) + { + hsmartcard->Instance->BRR = (uint16_t)tmpreg; + } + else + { + ret = HAL_ERROR; + } + + /* Initialize the number of data to process during RX/TX ISR execution */ + hsmartcard->NbTxDataToProcess = 1U; + hsmartcard->NbRxDataToProcess = 1U; + + /* Clear ISR function pointers */ + hsmartcard->RxISR = NULL; + hsmartcard->TxISR = NULL; + + return ret; +} + + +/** + * @brief Configure the SMARTCARD associated USART peripheral advanced features. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval None + */ +static void SMARTCARD_AdvFeatureConfig(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Check whether the set of advanced features to configure is properly set */ + assert_param(IS_SMARTCARD_ADVFEATURE_INIT(hsmartcard->AdvancedInit.AdvFeatureInit)); + + /* if required, configure TX pin active level inversion */ + if (HAL_IS_BIT_SET(hsmartcard->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_TXINVERT_INIT)) + { + assert_param(IS_SMARTCARD_ADVFEATURE_TXINV(hsmartcard->AdvancedInit.TxPinLevelInvert)); + MODIFY_REG(hsmartcard->Instance->CR2, USART_CR2_TXINV, hsmartcard->AdvancedInit.TxPinLevelInvert); + } + + /* if required, configure RX pin active level inversion */ + if (HAL_IS_BIT_SET(hsmartcard->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_RXINVERT_INIT)) + { + assert_param(IS_SMARTCARD_ADVFEATURE_RXINV(hsmartcard->AdvancedInit.RxPinLevelInvert)); + MODIFY_REG(hsmartcard->Instance->CR2, USART_CR2_RXINV, hsmartcard->AdvancedInit.RxPinLevelInvert); + } + + /* if required, configure data inversion */ + if (HAL_IS_BIT_SET(hsmartcard->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_DATAINVERT_INIT)) + { + assert_param(IS_SMARTCARD_ADVFEATURE_DATAINV(hsmartcard->AdvancedInit.DataInvert)); + MODIFY_REG(hsmartcard->Instance->CR2, USART_CR2_DATAINV, hsmartcard->AdvancedInit.DataInvert); + } + + /* if required, configure RX/TX pins swap */ + if (HAL_IS_BIT_SET(hsmartcard->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_SWAP_INIT)) + { + assert_param(IS_SMARTCARD_ADVFEATURE_SWAP(hsmartcard->AdvancedInit.Swap)); + MODIFY_REG(hsmartcard->Instance->CR2, USART_CR2_SWAP, hsmartcard->AdvancedInit.Swap); + } + + /* if required, configure RX overrun detection disabling */ + if (HAL_IS_BIT_SET(hsmartcard->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_RXOVERRUNDISABLE_INIT)) + { + assert_param(IS_SMARTCARD_OVERRUN(hsmartcard->AdvancedInit.OverrunDisable)); + MODIFY_REG(hsmartcard->Instance->CR3, USART_CR3_OVRDIS, hsmartcard->AdvancedInit.OverrunDisable); + } + + /* if required, configure DMA disabling on reception error */ + if (HAL_IS_BIT_SET(hsmartcard->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_DMADISABLEONERROR_INIT)) + { + assert_param(IS_SMARTCARD_ADVFEATURE_DMAONRXERROR(hsmartcard->AdvancedInit.DMADisableonRxError)); + MODIFY_REG(hsmartcard->Instance->CR3, USART_CR3_DDRE, hsmartcard->AdvancedInit.DMADisableonRxError); + } + + /* if required, configure MSB first on communication line */ + if (HAL_IS_BIT_SET(hsmartcard->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_MSBFIRST_INIT)) + { + assert_param(IS_SMARTCARD_ADVFEATURE_MSBFIRST(hsmartcard->AdvancedInit.MSBFirst)); + MODIFY_REG(hsmartcard->Instance->CR2, USART_CR2_MSBFIRST, hsmartcard->AdvancedInit.MSBFirst); + } + +} + +/** + * @brief Check the SMARTCARD Idle State. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval HAL status + */ +static HAL_StatusTypeDef SMARTCARD_CheckIdleState(SMARTCARD_HandleTypeDef *hsmartcard) +{ + uint32_t tickstart; + + /* Initialize the SMARTCARD ErrorCode */ + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + + /* Check if the Transmitter is enabled */ + if ((hsmartcard->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE) + { + /* Wait until TEACK flag is set */ + if (SMARTCARD_WaitOnFlagUntilTimeout(hsmartcard, USART_ISR_TEACK, RESET, tickstart, + SMARTCARD_TEACK_REACK_TIMEOUT) != HAL_OK) + { + /* Timeout occurred */ + return HAL_TIMEOUT; + } + } + /* Check if the Receiver is enabled */ + if ((hsmartcard->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE) + { + /* Wait until REACK flag is set */ + if (SMARTCARD_WaitOnFlagUntilTimeout(hsmartcard, USART_ISR_REACK, RESET, tickstart, + SMARTCARD_TEACK_REACK_TIMEOUT) != HAL_OK) + { + /* Timeout occurred */ + return HAL_TIMEOUT; + } + } + + /* Initialize the SMARTCARD states */ + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmartcard); + + return HAL_OK; +} + +/** + * @brief Handle SMARTCARD Communication Timeout. It waits + * until a flag is no longer in the specified status. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @param Flag Specifies the SMARTCARD flag to check. + * @param Status The actual Flag status (SET or RESET). + * @param Tickstart Tick start value + * @param Timeout Timeout duration. + * @retval HAL status + */ +static HAL_StatusTypeDef SMARTCARD_WaitOnFlagUntilTimeout(SMARTCARD_HandleTypeDef *hsmartcard, uint32_t Flag, + FlagStatus Status, uint32_t Tickstart, uint32_t Timeout) +{ + /* Wait until flag is set */ + while ((__HAL_SMARTCARD_GET_FLAG(hsmartcard, Flag) ? SET : RESET) == Status) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + { + /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) + interrupts for the interrupt process */ + CLEAR_BIT(hsmartcard->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE)); + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmartcard); + return HAL_TIMEOUT; + } + } + } + return HAL_OK; +} + + +/** + * @brief End ongoing Tx transfer on SMARTCARD peripheral (following error detection or Transmit completion). + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval None + */ +static void SMARTCARD_EndTxTransfer(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Disable TXEIE, TCIE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hsmartcard->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE)); + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + + /* At end of Tx process, restore hsmartcard->gState to Ready */ + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; +} + + +/** + * @brief End ongoing Rx transfer on UART peripheral (following error detection or Reception completion). + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval None + */ +static void SMARTCARD_EndRxTransfer(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hsmartcard->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + + /* At end of Rx process, restore hsmartcard->RxState to Ready */ + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; +} + + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief DMA SMARTCARD transmit process complete callback. + * @param hdma Pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SMARTCARD_DMATransmitCplt(DMA_HandleTypeDef *hdma) +{ + SMARTCARD_HandleTypeDef *hsmartcard = (SMARTCARD_HandleTypeDef *)(hdma->Parent); + hsmartcard->TxXferCount = 0U; + + /* Disable the DMA transfer for transmit request by resetting the DMAT bit + in the SMARTCARD associated USART CR3 register */ + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_DMAT); + + /* Enable the SMARTCARD Transmit Complete Interrupt */ + __HAL_SMARTCARD_ENABLE_IT(hsmartcard, hsmartcard->AdvancedInit.TxCompletionIndication); +} + +/** + * @brief DMA SMARTCARD receive process complete callback. + * @param hdma Pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SMARTCARD_DMAReceiveCplt(DMA_HandleTypeDef *hdma) +{ + SMARTCARD_HandleTypeDef *hsmartcard = (SMARTCARD_HandleTypeDef *)(hdma->Parent); + hsmartcard->RxXferCount = 0U; + + /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_PEIE); + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + + /* Disable the DMA transfer for the receiver request by resetting the DMAR bit + in the SMARTCARD associated USART CR3 register */ + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_DMAR); + + /* At end of Rx process, restore hsmartcard->RxState to Ready */ + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) + /* Call registered Rx complete callback */ + hsmartcard->RxCpltCallback(hsmartcard); +#else + /* Call legacy weak Rx complete callback */ + HAL_SMARTCARD_RxCpltCallback(hsmartcard); +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */ +} + +/** + * @brief DMA SMARTCARD communication error callback. + * @param hdma Pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SMARTCARD_DMAError(DMA_HandleTypeDef *hdma) +{ + SMARTCARD_HandleTypeDef *hsmartcard = (SMARTCARD_HandleTypeDef *)(hdma->Parent); + + /* Stop SMARTCARD DMA Tx request if ongoing */ + if (hsmartcard->gState == HAL_SMARTCARD_STATE_BUSY_TX) + { + if (HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAT)) + { + hsmartcard->TxXferCount = 0U; + SMARTCARD_EndTxTransfer(hsmartcard); + } + } + + /* Stop SMARTCARD DMA Rx request if ongoing */ + if (hsmartcard->RxState == HAL_SMARTCARD_STATE_BUSY_RX) + { + if (HAL_IS_BIT_SET(hsmartcard->Instance->CR3, USART_CR3_DMAR)) + { + hsmartcard->RxXferCount = 0U; + SMARTCARD_EndRxTransfer(hsmartcard); + } + } + + hsmartcard->ErrorCode |= HAL_SMARTCARD_ERROR_DMA; +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) + /* Call registered user error callback */ + hsmartcard->ErrorCallback(hsmartcard); +#else + /* Call legacy weak user error callback */ + HAL_SMARTCARD_ErrorCallback(hsmartcard); +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */ +} + +/** + * @brief DMA SMARTCARD communication abort callback, when initiated by HAL services on Error + * (To be called at end of DMA Abort procedure following error occurrence). + * @param hdma DMA handle. + * @retval None + */ +static void SMARTCARD_DMAAbortOnError(DMA_HandleTypeDef *hdma) +{ + SMARTCARD_HandleTypeDef *hsmartcard = (SMARTCARD_HandleTypeDef *)(hdma->Parent); + hsmartcard->RxXferCount = 0U; + hsmartcard->TxXferCount = 0U; + +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) + /* Call registered user error callback */ + hsmartcard->ErrorCallback(hsmartcard); +#else + /* Call legacy weak user error callback */ + HAL_SMARTCARD_ErrorCallback(hsmartcard); +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */ +} + +/** + * @brief DMA SMARTCARD Tx communication abort callback, when initiated by user + * (To be called at end of DMA Tx Abort procedure following user abort request). + * @note When this callback is executed, User Abort complete call back is called only if no + * Abort still ongoing for Rx DMA Handle. + * @param hdma DMA handle. + * @retval None + */ +static void SMARTCARD_DMATxAbortCallback(DMA_HandleTypeDef *hdma) +{ + SMARTCARD_HandleTypeDef *hsmartcard = (SMARTCARD_HandleTypeDef *)(hdma->Parent); + + hsmartcard->hdmatx->XferAbortCallback = NULL; + + /* Check if an Abort process is still ongoing */ + if (hsmartcard->hdmarx != NULL) + { + if (hsmartcard->hdmarx->XferAbortCallback != NULL) + { + return; + } + } + + /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ + hsmartcard->TxXferCount = 0U; + hsmartcard->RxXferCount = 0U; + + /* Reset errorCode */ + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + + /* Clear the Error flags in the ICR register */ + __HAL_SMARTCARD_CLEAR_FLAG(hsmartcard, + SMARTCARD_CLEAR_OREF | SMARTCARD_CLEAR_NEF | SMARTCARD_CLEAR_PEF | SMARTCARD_CLEAR_FEF | + SMARTCARD_CLEAR_RTOF | SMARTCARD_CLEAR_EOBF); + + /* Restore hsmartcard->gState and hsmartcard->RxState to Ready */ + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) + /* Call registered Abort complete callback */ + hsmartcard->AbortCpltCallback(hsmartcard); +#else + /* Call legacy weak Abort complete callback */ + HAL_SMARTCARD_AbortCpltCallback(hsmartcard); +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */ +} + + +/** + * @brief DMA SMARTCARD Rx communication abort callback, when initiated by user + * (To be called at end of DMA Rx Abort procedure following user abort request). + * @note When this callback is executed, User Abort complete call back is called only if no + * Abort still ongoing for Tx DMA Handle. + * @param hdma DMA handle. + * @retval None + */ +static void SMARTCARD_DMARxAbortCallback(DMA_HandleTypeDef *hdma) +{ + SMARTCARD_HandleTypeDef *hsmartcard = (SMARTCARD_HandleTypeDef *)(hdma->Parent); + + hsmartcard->hdmarx->XferAbortCallback = NULL; + + /* Check if an Abort process is still ongoing */ + if (hsmartcard->hdmatx != NULL) + { + if (hsmartcard->hdmatx->XferAbortCallback != NULL) + { + return; + } + } + + /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ + hsmartcard->TxXferCount = 0U; + hsmartcard->RxXferCount = 0U; + + /* Reset errorCode */ + hsmartcard->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + + /* Clear the Error flags in the ICR register */ + __HAL_SMARTCARD_CLEAR_FLAG(hsmartcard, + SMARTCARD_CLEAR_OREF | SMARTCARD_CLEAR_NEF | SMARTCARD_CLEAR_PEF | SMARTCARD_CLEAR_FEF | + SMARTCARD_CLEAR_RTOF | SMARTCARD_CLEAR_EOBF); + + /* Restore hsmartcard->gState and hsmartcard->RxState to Ready */ + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) + /* Call registered Abort complete callback */ + hsmartcard->AbortCpltCallback(hsmartcard); +#else + /* Call legacy weak Abort complete callback */ + HAL_SMARTCARD_AbortCpltCallback(hsmartcard); +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */ +} + + +/** + * @brief DMA SMARTCARD Tx communication abort callback, when initiated by user by a call to + * HAL_SMARTCARD_AbortTransmit_IT API (Abort only Tx transfer) + * (This callback is executed at end of DMA Tx Abort procedure following user abort request, + * and leads to user Tx Abort Complete callback execution). + * @param hdma DMA handle. + * @retval None + */ +static void SMARTCARD_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma) +{ + SMARTCARD_HandleTypeDef *hsmartcard = (SMARTCARD_HandleTypeDef *)(hdma->Parent); + + hsmartcard->TxXferCount = 0U; + + /* Clear the Error flags in the ICR register */ + __HAL_SMARTCARD_CLEAR_FLAG(hsmartcard, SMARTCARD_CLEAR_FEF); + + /* Restore hsmartcard->gState to Ready */ + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) + /* Call registered Abort Transmit Complete Callback */ + hsmartcard->AbortTransmitCpltCallback(hsmartcard); +#else + /* Call legacy weak Abort Transmit Complete Callback */ + HAL_SMARTCARD_AbortTransmitCpltCallback(hsmartcard); +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */ +} + +/** + * @brief DMA SMARTCARD Rx communication abort callback, when initiated by user by a call to + * HAL_SMARTCARD_AbortReceive_IT API (Abort only Rx transfer) + * (This callback is executed at end of DMA Rx Abort procedure following user abort request, + * and leads to user Rx Abort Complete callback execution). + * @param hdma DMA handle. + * @retval None + */ +static void SMARTCARD_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma) +{ + SMARTCARD_HandleTypeDef *hsmartcard = (SMARTCARD_HandleTypeDef *)(hdma->Parent); + + hsmartcard->RxXferCount = 0U; + + /* Clear the Error flags in the ICR register */ + __HAL_SMARTCARD_CLEAR_FLAG(hsmartcard, + SMARTCARD_CLEAR_OREF | SMARTCARD_CLEAR_NEF | SMARTCARD_CLEAR_PEF | SMARTCARD_CLEAR_FEF | + SMARTCARD_CLEAR_RTOF | SMARTCARD_CLEAR_EOBF); + + /* Restore hsmartcard->RxState to Ready */ + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) + /* Call registered Abort Receive Complete Callback */ + hsmartcard->AbortReceiveCpltCallback(hsmartcard); +#else + /* Call legacy weak Abort Receive Complete Callback */ + HAL_SMARTCARD_AbortReceiveCpltCallback(hsmartcard); +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */ +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Send an amount of data in non-blocking mode. + * @note Function called under interruption only, once + * interruptions have been enabled by HAL_SMARTCARD_Transmit_IT() + * and when the FIFO mode is disabled. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval None + */ +static void SMARTCARD_TxISR(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Check that a Tx process is ongoing */ + if (hsmartcard->gState == HAL_SMARTCARD_STATE_BUSY_TX) + { + if (hsmartcard->TxXferCount == 0U) + { + /* Disable the SMARTCARD Transmit Data Register Empty Interrupt */ + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_TXEIE_TXFNFIE); + + /* Enable the SMARTCARD Transmit Complete Interrupt */ + __HAL_SMARTCARD_ENABLE_IT(hsmartcard, hsmartcard->AdvancedInit.TxCompletionIndication); + } + else + { + hsmartcard->Instance->TDR = (uint8_t)(*hsmartcard->pTxBuffPtr & 0xFFU); + hsmartcard->pTxBuffPtr++; + hsmartcard->TxXferCount--; + } + } +} + +/** + * @brief Send an amount of data in non-blocking mode. + * @note Function called under interruption only, once + * interruptions have been enabled by HAL_SMARTCARD_Transmit_IT() + * and when the FIFO mode is enabled. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval None + */ +static void SMARTCARD_TxISR_FIFOEN(SMARTCARD_HandleTypeDef *hsmartcard) +{ + uint16_t nb_tx_data; + + /* Check that a Tx process is ongoing */ + if (hsmartcard->gState == HAL_SMARTCARD_STATE_BUSY_TX) + { + for (nb_tx_data = hsmartcard->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--) + { + if (hsmartcard->TxXferCount == 0U) + { + /* Disable the SMARTCARD Transmit Data Register Empty Interrupt */ + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_TXEIE_TXFNFIE); + + /* Enable the SMARTCARD Transmit Complete Interrupt */ + __HAL_SMARTCARD_ENABLE_IT(hsmartcard, hsmartcard->AdvancedInit.TxCompletionIndication); + } + else if (READ_BIT(hsmartcard->Instance->ISR, USART_ISR_TXE_TXFNF) != 0U) + { + hsmartcard->Instance->TDR = (uint8_t)(*hsmartcard->pTxBuffPtr & 0xFFU); + hsmartcard->pTxBuffPtr++; + hsmartcard->TxXferCount--; + } + else + { + /* Nothing to do */ + } + } + } +} + +/** + * @brief Wrap up transmission in non-blocking mode. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval None + */ +static void SMARTCARD_EndTransmit_IT(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Disable the SMARTCARD Transmit Complete Interrupt */ + __HAL_SMARTCARD_DISABLE_IT(hsmartcard, hsmartcard->AdvancedInit.TxCompletionIndication); + + /* Check if a receive process is ongoing or not. If not disable ERR IT */ + if (hsmartcard->RxState == HAL_SMARTCARD_STATE_READY) + { + /* Disable the SMARTCARD Error Interrupt: (Frame error) */ + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + } + + /* Disable the Peripheral first to update mode */ + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_UE); + if ((hsmartcard->Init.Mode == SMARTCARD_MODE_TX) + && (hsmartcard->Init.NACKEnable == SMARTCARD_NACK_ENABLE)) + { + /* In case of TX only mode, if NACK is enabled, receiver block has been enabled + for Transmit phase. Disable this receiver block. */ + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_RE); + } + if ((hsmartcard->Init.Mode == SMARTCARD_MODE_TX_RX) + || (hsmartcard->Init.NACKEnable == SMARTCARD_NACK_ENABLE)) + { + /* Perform a TX FIFO Flush at end of Tx phase, as all sent bytes are appearing in Rx Data register */ + __HAL_SMARTCARD_FLUSH_DRREGISTER(hsmartcard); + } + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_UE); + + /* Tx process is ended, restore hsmartcard->gState to Ready */ + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + + /* Clear TxISR function pointer */ + hsmartcard->TxISR = NULL; + +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) + /* Call registered Tx complete callback */ + hsmartcard->TxCpltCallback(hsmartcard); +#else + /* Call legacy weak Tx complete callback */ + HAL_SMARTCARD_TxCpltCallback(hsmartcard); +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */ +} + +/** + * @brief Receive an amount of data in non-blocking mode. + * @note Function called under interruption only, once + * interruptions have been enabled by HAL_SMARTCARD_Receive_IT() + * and when the FIFO mode is disabled. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval None + */ +static void SMARTCARD_RxISR(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Check that a Rx process is ongoing */ + if (hsmartcard->RxState == HAL_SMARTCARD_STATE_BUSY_RX) + { + *hsmartcard->pRxBuffPtr = (uint8_t)(hsmartcard->Instance->RDR & (uint8_t)0xFF); + hsmartcard->pRxBuffPtr++; + + hsmartcard->RxXferCount--; + if (hsmartcard->RxXferCount == 0U) + { + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE); + + /* Check if a transmit process is ongoing or not. If not disable ERR IT */ + if (hsmartcard->gState == HAL_SMARTCARD_STATE_READY) + { + /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */ + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + } + + /* Disable the SMARTCARD Parity Error Interrupt */ + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_PEIE); + + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + + /* Clear RxISR function pointer */ + hsmartcard->RxISR = NULL; + +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) + /* Call registered Rx complete callback */ + hsmartcard->RxCpltCallback(hsmartcard); +#else + /* Call legacy weak Rx complete callback */ + HAL_SMARTCARD_RxCpltCallback(hsmartcard); +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */ + } + } + else + { + /* Clear RXNE interrupt flag */ + __HAL_SMARTCARD_SEND_REQ(hsmartcard, SMARTCARD_RXDATA_FLUSH_REQUEST); + } +} + +/** + * @brief Receive an amount of data in non-blocking mode. + * @note Function called under interruption only, once + * interruptions have been enabled by HAL_SMARTCARD_Receive_IT() + * and when the FIFO mode is enabled. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval None + */ +static void SMARTCARD_RxISR_FIFOEN(SMARTCARD_HandleTypeDef *hsmartcard) +{ + uint16_t nb_rx_data; + uint16_t rxdatacount; + + /* Check that a Rx process is ongoing */ + if (hsmartcard->RxState == HAL_SMARTCARD_STATE_BUSY_RX) + { + for (nb_rx_data = hsmartcard->NbRxDataToProcess ; nb_rx_data > 0U ; nb_rx_data--) + { + *hsmartcard->pRxBuffPtr = (uint8_t)(hsmartcard->Instance->RDR & (uint8_t)0xFF); + hsmartcard->pRxBuffPtr++; + + hsmartcard->RxXferCount--; + if (hsmartcard->RxXferCount == 0U) + { + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE); + + /* Check if a transmit process is ongoing or not. If not disable ERR IT */ + if (hsmartcard->gState == HAL_SMARTCARD_STATE_READY) + { + /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */ + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_EIE); + } + + /* Disable the SMARTCARD Parity Error Interrupt */ + CLEAR_BIT(hsmartcard->Instance->CR1, USART_CR1_PEIE); + + hsmartcard->RxState = HAL_SMARTCARD_STATE_READY; + + /* Clear RxISR function pointer */ + hsmartcard->RxISR = NULL; + +#if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1) + /* Call registered Rx complete callback */ + hsmartcard->RxCpltCallback(hsmartcard); +#else + /* Call legacy weak Rx complete callback */ + HAL_SMARTCARD_RxCpltCallback(hsmartcard); +#endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */ + } + } + + /* When remaining number of bytes to receive is less than the RX FIFO + threshold, next incoming frames are processed as if FIFO mode was + disabled (i.e. one interrupt per received frame). + */ + rxdatacount = hsmartcard->RxXferCount; + if (((rxdatacount != 0U)) && (rxdatacount < hsmartcard->NbRxDataToProcess)) + { + /* Disable the UART RXFT interrupt*/ + CLEAR_BIT(hsmartcard->Instance->CR3, USART_CR3_RXFTIE); + + /* Update the RxISR function pointer */ + hsmartcard->RxISR = SMARTCARD_RxISR; + + /* Enable the UART Data Register Not Empty interrupt */ + SET_BIT(hsmartcard->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE); + } + } + else + { + /* Clear RXNE interrupt flag */ + __HAL_SMARTCARD_SEND_REQ(hsmartcard, SMARTCARD_RXDATA_FLUSH_REQUEST); + } +} + +/** + * @} + */ + +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_smartcard_ex.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_smartcard_ex.c new file mode 100644 index 0000000000..b1bddd3e06 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_smartcard_ex.c @@ -0,0 +1,495 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_smartcard_ex.c + * @author MCD Application Team + * @brief SMARTCARD HAL module driver. + * This file provides extended firmware functions to manage the following + * functionalities of the SmartCard. + * + Initialization and de-initialization functions + * + Peripheral Control functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================= + ##### SMARTCARD peripheral extended features ##### + ============================================================================= + [..] + The Extended SMARTCARD HAL driver can be used as follows: + + (#) After having configured the SMARTCARD basic features with HAL_SMARTCARD_Init(), + then program SMARTCARD advanced features if required (TX/RX pins swap, TimeOut, + auto-retry counter,...) in the hsmartcard AdvancedInit structure. + + (#) FIFO mode enabling/disabling and RX/TX FIFO threshold programming. + + -@- When SMARTCARD operates in FIFO mode, FIFO mode must be enabled prior + starting RX/TX transfers. Also RX/TX FIFO thresholds must be + configured prior starting RX/TX transfers. + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup SMARTCARDEx SMARTCARDEx + * @brief SMARTCARD Extended HAL module driver + * @{ + */ +#ifdef HAL_SMARTCARD_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup SMARTCARDEx_Private_Constants SMARTCARD Extended Private Constants + * @{ + */ +/* UART RX FIFO depth */ +#define RX_FIFO_DEPTH 8U + +/* UART TX FIFO depth */ +#define TX_FIFO_DEPTH 8U +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +static void SMARTCARDEx_SetNbDataToProcess(SMARTCARD_HandleTypeDef *hsmartcard); + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup SMARTCARDEx_Exported_Functions SMARTCARD Extended Exported Functions + * @{ + */ + +/** @defgroup SMARTCARDEx_Exported_Functions_Group1 Extended Peripheral Control functions + * @brief Extended control functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to initialize the SMARTCARD. + (+) HAL_SMARTCARDEx_BlockLength_Config() API allows to configure the Block Length on the fly + (+) HAL_SMARTCARDEx_TimeOut_Config() API allows to configure the receiver timeout value on the fly + (+) HAL_SMARTCARDEx_EnableReceiverTimeOut() API enables the receiver timeout feature + (+) HAL_SMARTCARDEx_DisableReceiverTimeOut() API disables the receiver timeout feature + +@endverbatim + * @{ + */ + +/** @brief Update on the fly the SMARTCARD block length in RTOR register. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @param BlockLength SMARTCARD block length (8-bit long at most) + * @retval None + */ +void HAL_SMARTCARDEx_BlockLength_Config(SMARTCARD_HandleTypeDef *hsmartcard, uint8_t BlockLength) +{ + MODIFY_REG(hsmartcard->Instance->RTOR, USART_RTOR_BLEN, ((uint32_t)BlockLength << USART_RTOR_BLEN_Pos)); +} + +/** @brief Update on the fly the receiver timeout value in RTOR register. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @param TimeOutValue receiver timeout value in number of baud blocks. The timeout + * value must be less or equal to 0x0FFFFFFFF. + * @retval None + */ +void HAL_SMARTCARDEx_TimeOut_Config(SMARTCARD_HandleTypeDef *hsmartcard, uint32_t TimeOutValue) +{ + assert_param(IS_SMARTCARD_TIMEOUT_VALUE(hsmartcard->Init.TimeOutValue)); + MODIFY_REG(hsmartcard->Instance->RTOR, USART_RTOR_RTO, TimeOutValue); +} + +/** @brief Enable the SMARTCARD receiver timeout feature. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARDEx_EnableReceiverTimeOut(SMARTCARD_HandleTypeDef *hsmartcard) +{ + if (hsmartcard->gState == HAL_SMARTCARD_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsmartcard); + + hsmartcard->gState = HAL_SMARTCARD_STATE_BUSY; + + /* Set the USART RTOEN bit */ + SET_BIT(hsmartcard->Instance->CR2, USART_CR2_RTOEN); + + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmartcard); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** @brief Disable the SMARTCARD receiver timeout feature. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARDEx_DisableReceiverTimeOut(SMARTCARD_HandleTypeDef *hsmartcard) +{ + if (hsmartcard->gState == HAL_SMARTCARD_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsmartcard); + + hsmartcard->gState = HAL_SMARTCARD_STATE_BUSY; + + /* Clear the USART RTOEN bit */ + CLEAR_BIT(hsmartcard->Instance->CR2, USART_CR2_RTOEN); + + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmartcard); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @} + */ + +/** @defgroup SMARTCARDEx_Exported_Functions_Group2 Extended Peripheral IO operation functions + * @brief SMARTCARD Transmit and Receive functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of FIFO mode related callback functions. + + (#) TX/RX Fifos Callbacks: + (++) HAL_SMARTCARDEx_RxFifoFullCallback() + (++) HAL_SMARTCARDEx_TxFifoEmptyCallback() + +@endverbatim + * @{ + */ + +/** + * @brief SMARTCARD RX Fifo full callback. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval None + */ +__weak void HAL_SMARTCARDEx_RxFifoFullCallback(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsmartcard); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMARTCARDEx_RxFifoFullCallback can be implemented in the user file. + */ +} + +/** + * @brief SMARTCARD TX Fifo empty callback. + * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval None + */ +__weak void HAL_SMARTCARDEx_TxFifoEmptyCallback(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsmartcard); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMARTCARDEx_TxFifoEmptyCallback can be implemented in the user file. + */ +} + +/** + * @} + */ + +/** @defgroup SMARTCARDEx_Exported_Functions_Group3 Extended Peripheral FIFO Control functions + * @brief SMARTCARD control functions + * +@verbatim + =============================================================================== + ##### Peripheral FIFO Control functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the SMARTCARD + FIFO feature. + (+) HAL_SMARTCARDEx_EnableFifoMode() API enables the FIFO mode + (+) HAL_SMARTCARDEx_DisableFifoMode() API disables the FIFO mode + (+) HAL_SMARTCARDEx_SetTxFifoThreshold() API sets the TX FIFO threshold + (+) HAL_SMARTCARDEx_SetRxFifoThreshold() API sets the RX FIFO threshold +@endverbatim + * @{ + */ + +/** + * @brief Enable the FIFO mode. + * @param hsmartcard SMARTCARD handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARDEx_EnableFifoMode(SMARTCARD_HandleTypeDef *hsmartcard) +{ + uint32_t tmpcr1; + + /* Check parameters */ + assert_param(IS_UART_FIFO_INSTANCE(hsmartcard->Instance)); + + /* Process Locked */ + __HAL_LOCK(hsmartcard); + + hsmartcard->gState = HAL_SMARTCARD_STATE_BUSY; + + /* Save actual SMARTCARD configuration */ + tmpcr1 = READ_REG(hsmartcard->Instance->CR1); + + /* Disable SMARTCARD */ + __HAL_SMARTCARD_DISABLE(hsmartcard); + + /* Enable FIFO mode */ + SET_BIT(tmpcr1, USART_CR1_FIFOEN); + hsmartcard->FifoMode = SMARTCARD_FIFOMODE_ENABLE; + + /* Restore SMARTCARD configuration */ + WRITE_REG(hsmartcard->Instance->CR1, tmpcr1); + + /* Determine the number of data to process during RX/TX ISR execution */ + SMARTCARDEx_SetNbDataToProcess(hsmartcard); + + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmartcard); + + return HAL_OK; +} + +/** + * @brief Disable the FIFO mode. + * @param hsmartcard SMARTCARD handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARDEx_DisableFifoMode(SMARTCARD_HandleTypeDef *hsmartcard) +{ + uint32_t tmpcr1; + + /* Check parameters */ + assert_param(IS_UART_FIFO_INSTANCE(hsmartcard->Instance)); + + /* Process Locked */ + __HAL_LOCK(hsmartcard); + + hsmartcard->gState = HAL_SMARTCARD_STATE_BUSY; + + /* Save actual SMARTCARD configuration */ + tmpcr1 = READ_REG(hsmartcard->Instance->CR1); + + /* Disable SMARTCARD */ + __HAL_SMARTCARD_DISABLE(hsmartcard); + + /* Enable FIFO mode */ + CLEAR_BIT(tmpcr1, USART_CR1_FIFOEN); + hsmartcard->FifoMode = SMARTCARD_FIFOMODE_DISABLE; + + /* Restore SMARTCARD configuration */ + WRITE_REG(hsmartcard->Instance->CR1, tmpcr1); + + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmartcard); + + return HAL_OK; +} + +/** + * @brief Set the TXFIFO threshold. + * @param hsmartcard SMARTCARD handle. + * @param Threshold TX FIFO threshold value + * This parameter can be one of the following values: + * @arg @ref SMARTCARD_TXFIFO_THRESHOLD_1_8 + * @arg @ref SMARTCARD_TXFIFO_THRESHOLD_1_4 + * @arg @ref SMARTCARD_TXFIFO_THRESHOLD_1_2 + * @arg @ref SMARTCARD_TXFIFO_THRESHOLD_3_4 + * @arg @ref SMARTCARD_TXFIFO_THRESHOLD_7_8 + * @arg @ref SMARTCARD_TXFIFO_THRESHOLD_8_8 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARDEx_SetTxFifoThreshold(SMARTCARD_HandleTypeDef *hsmartcard, uint32_t Threshold) +{ + uint32_t tmpcr1; + + /* Check parameters */ + assert_param(IS_UART_FIFO_INSTANCE(hsmartcard->Instance)); + assert_param(IS_SMARTCARD_TXFIFO_THRESHOLD(Threshold)); + + /* Process Locked */ + __HAL_LOCK(hsmartcard); + + hsmartcard->gState = HAL_SMARTCARD_STATE_BUSY; + + /* Save actual SMARTCARD configuration */ + tmpcr1 = READ_REG(hsmartcard->Instance->CR1); + + /* Disable SMARTCARD */ + __HAL_SMARTCARD_DISABLE(hsmartcard); + + /* Update TX threshold configuration */ + MODIFY_REG(hsmartcard->Instance->CR3, USART_CR3_TXFTCFG, Threshold); + + /* Determine the number of data to process during RX/TX ISR execution */ + SMARTCARDEx_SetNbDataToProcess(hsmartcard); + + /* Restore SMARTCARD configuration */ + MODIFY_REG(hsmartcard->Instance->CR1, USART_CR1_UE, tmpcr1); + + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmartcard); + + return HAL_OK; +} + +/** + * @brief Set the RXFIFO threshold. + * @param hsmartcard SMARTCARD handle. + * @param Threshold RX FIFO threshold value + * This parameter can be one of the following values: + * @arg @ref SMARTCARD_RXFIFO_THRESHOLD_1_8 + * @arg @ref SMARTCARD_RXFIFO_THRESHOLD_1_4 + * @arg @ref SMARTCARD_RXFIFO_THRESHOLD_1_2 + * @arg @ref SMARTCARD_RXFIFO_THRESHOLD_3_4 + * @arg @ref SMARTCARD_RXFIFO_THRESHOLD_7_8 + * @arg @ref SMARTCARD_RXFIFO_THRESHOLD_8_8 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARDEx_SetRxFifoThreshold(SMARTCARD_HandleTypeDef *hsmartcard, uint32_t Threshold) +{ + uint32_t tmpcr1; + + /* Check parameters */ + assert_param(IS_UART_FIFO_INSTANCE(hsmartcard->Instance)); + assert_param(IS_SMARTCARD_RXFIFO_THRESHOLD(Threshold)); + + /* Process Locked */ + __HAL_LOCK(hsmartcard); + + hsmartcard->gState = HAL_SMARTCARD_STATE_BUSY; + + /* Save actual SMARTCARD configuration */ + tmpcr1 = READ_REG(hsmartcard->Instance->CR1); + + /* Disable SMARTCARD */ + __HAL_SMARTCARD_DISABLE(hsmartcard); + + /* Update RX threshold configuration */ + MODIFY_REG(hsmartcard->Instance->CR3, USART_CR3_RXFTCFG, Threshold); + + /* Determine the number of data to process during RX/TX ISR execution */ + SMARTCARDEx_SetNbDataToProcess(hsmartcard); + + /* Restore SMARTCARD configuration */ + MODIFY_REG(hsmartcard->Instance->CR1, USART_CR1_UE, tmpcr1); + + hsmartcard->gState = HAL_SMARTCARD_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmartcard); + + return HAL_OK; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup SMARTCARDEx_Private_Functions SMARTCARD Extended Private Functions + * @{ + */ + +/** + * @brief Calculate the number of data to process in RX/TX ISR. + * @note The RX FIFO depth and the TX FIFO depth is extracted from + * the USART configuration registers. + * @param hsmartcard SMARTCARD handle. + * @retval None + */ +static void SMARTCARDEx_SetNbDataToProcess(SMARTCARD_HandleTypeDef *hsmartcard) +{ + uint8_t rx_fifo_depth; + uint8_t tx_fifo_depth; + uint8_t rx_fifo_threshold; + uint8_t tx_fifo_threshold; + /* 2 0U/1U added for MISRAC2012-Rule-18.1_b and MISRAC2012-Rule-18.1_d */ + static const uint8_t numerator[] = {1U, 1U, 1U, 3U, 7U, 1U, 0U, 0U}; + static const uint8_t denominator[] = {8U, 4U, 2U, 4U, 8U, 1U, 1U, 1U}; + + if (hsmartcard->FifoMode == SMARTCARD_FIFOMODE_DISABLE) + { + hsmartcard->NbTxDataToProcess = 1U; + hsmartcard->NbRxDataToProcess = 1U; + } + else + { + rx_fifo_depth = RX_FIFO_DEPTH; + tx_fifo_depth = TX_FIFO_DEPTH; + rx_fifo_threshold = (uint8_t)(READ_BIT(hsmartcard->Instance->CR3, USART_CR3_RXFTCFG) >> USART_CR3_RXFTCFG_Pos); + tx_fifo_threshold = (uint8_t)(READ_BIT(hsmartcard->Instance->CR3, USART_CR3_TXFTCFG) >> USART_CR3_TXFTCFG_Pos); + hsmartcard->NbTxDataToProcess = ((uint16_t)tx_fifo_depth * numerator[tx_fifo_threshold]) / \ + (uint16_t)denominator[tx_fifo_threshold]; + hsmartcard->NbRxDataToProcess = ((uint16_t)rx_fifo_depth * numerator[rx_fifo_threshold]) / \ + (uint16_t)denominator[rx_fifo_threshold]; + } +} + +/** + * @} + */ + +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_smbus.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_smbus.c new file mode 100644 index 0000000000..22254296b3 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_smbus.c @@ -0,0 +1,2773 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_smbus.c + * @author MCD Application Team + * @brief SMBUS HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the System Management Bus (SMBus) peripheral, + * based on I2C principles of operation : + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral State and Errors functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The SMBUS HAL driver can be used as follows: + + (#) Declare a SMBUS_HandleTypeDef handle structure, for example: + SMBUS_HandleTypeDef hsmbus; + + (#)Initialize the SMBUS low level resources by implementing the HAL_SMBUS_MspInit() API: + (##) Enable the SMBUSx interface clock + (##) SMBUS pins configuration + (+++) Enable the clock for the SMBUS GPIOs + (+++) Configure SMBUS pins as alternate function open-drain + (##) NVIC configuration if you need to use interrupt process + (+++) Configure the SMBUSx interrupt priority + (+++) Enable the NVIC SMBUS IRQ Channel + + (#) Configure the Communication Clock Timing, Bus Timeout, Own Address1, Master Addressing mode, + Dual Addressing mode, Own Address2, Own Address2 Mask, General call, Nostretch mode, + Peripheral mode and Packet Error Check mode in the hsmbus Init structure. + + (#) Initialize the SMBUS registers by calling the HAL_SMBUS_Init() API: + (++) These API's configures also the low level Hardware GPIO, CLOCK, CORTEX...etc) + by calling the customized HAL_SMBUS_MspInit(&hsmbus) API. + + (#) To check if target device is ready for communication, use the function HAL_SMBUS_IsDeviceReady() + + (#) For SMBUS IO operations, only one mode of operations is available within this driver + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Transmit in master/host SMBUS mode an amount of data in non-blocking mode + using HAL_SMBUS_Master_Transmit_IT() + (++) At transmission end of transfer HAL_SMBUS_MasterTxCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_SMBUS_MasterTxCpltCallback() + (+) Receive in master/host SMBUS mode an amount of data in non-blocking mode + using HAL_SMBUS_Master_Receive_IT() + (++) At reception end of transfer HAL_SMBUS_MasterRxCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_SMBUS_MasterRxCpltCallback() + (+) Abort a master/host SMBUS process communication with Interrupt using HAL_SMBUS_Master_Abort_IT() + (++) The associated previous transfer callback is called at the end of abort process + (++) mean HAL_SMBUS_MasterTxCpltCallback() in case of previous state was master transmit + (++) mean HAL_SMBUS_MasterRxCpltCallback() in case of previous state was master receive + (+) Enable/disable the Address listen mode in slave/device or host/slave SMBUS mode + using HAL_SMBUS_EnableListen_IT() HAL_SMBUS_DisableListen_IT() + (++) When address slave/device SMBUS match, HAL_SMBUS_AddrCallback() is executed and users can + add their own code to check the Address Match Code and the transmission direction + request by master/host (Write/Read). + (++) At Listen mode end HAL_SMBUS_ListenCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_SMBUS_ListenCpltCallback() + (+) Transmit in slave/device SMBUS mode an amount of data in non-blocking mode + using HAL_SMBUS_Slave_Transmit_IT() + (++) At transmission end of transfer HAL_SMBUS_SlaveTxCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_SMBUS_SlaveTxCpltCallback() + (+) Receive in slave/device SMBUS mode an amount of data in non-blocking mode + using HAL_SMBUS_Slave_Receive_IT() + (++) At reception end of transfer HAL_SMBUS_SlaveRxCpltCallback() is executed and users can + add their own code by customization of function pointer HAL_SMBUS_SlaveRxCpltCallback() + (+) Enable/Disable the SMBUS alert mode using + HAL_SMBUS_EnableAlert_IT() or HAL_SMBUS_DisableAlert_IT() + (++) When SMBUS Alert is generated HAL_SMBUS_ErrorCallback() is executed and users can + add their own code by customization of function pointer HAL_SMBUS_ErrorCallback() + to check the Alert Error Code using function HAL_SMBUS_GetError() + (+) Get HAL state machine or error values using HAL_SMBUS_GetState() or HAL_SMBUS_GetError() + (+) In case of transfer Error, HAL_SMBUS_ErrorCallback() function is executed and users can + add their own code by customization of function pointer HAL_SMBUS_ErrorCallback() + to check the Error Code using function HAL_SMBUS_GetError() + + *** SMBUS HAL driver macros list *** + ================================== + [..] + Below the list of most used macros in SMBUS HAL driver. + + (+) __HAL_SMBUS_ENABLE: Enable the SMBUS peripheral + (+) __HAL_SMBUS_DISABLE: Disable the SMBUS peripheral + (+) __HAL_SMBUS_GET_FLAG: Check whether the specified SMBUS flag is set or not + (+) __HAL_SMBUS_CLEAR_FLAG: Clear the specified SMBUS pending flag + (+) __HAL_SMBUS_ENABLE_IT: Enable the specified SMBUS interrupt + (+) __HAL_SMBUS_DISABLE_IT: Disable the specified SMBUS interrupt + + *** Callback registration *** + ============================================= + [..] + The compilation flag USE_HAL_SMBUS_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + Use Functions HAL_SMBUS_RegisterCallback() or HAL_SMBUS_RegisterAddrCallback() + to register an interrupt callback. + [..] + Function HAL_SMBUS_RegisterCallback() allows to register following callbacks: + (+) MasterTxCpltCallback : callback for Master transmission end of transfer. + (+) MasterRxCpltCallback : callback for Master reception end of transfer. + (+) SlaveTxCpltCallback : callback for Slave transmission end of transfer. + (+) SlaveRxCpltCallback : callback for Slave reception end of transfer. + (+) ListenCpltCallback : callback for end of listen mode. + (+) ErrorCallback : callback for error detection. + (+) MspInitCallback : callback for Msp Init. + (+) MspDeInitCallback : callback for Msp DeInit. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + [..] + For specific callback AddrCallback use dedicated register callbacks : HAL_SMBUS_RegisterAddrCallback. + [..] + Use function HAL_SMBUS_UnRegisterCallback to reset a callback to the default + weak function. + HAL_SMBUS_UnRegisterCallback takes as parameters the HAL peripheral handle, + and the Callback ID. + This function allows to reset following callbacks: + (+) MasterTxCpltCallback : callback for Master transmission end of transfer. + (+) MasterRxCpltCallback : callback for Master reception end of transfer. + (+) SlaveTxCpltCallback : callback for Slave transmission end of transfer. + (+) SlaveRxCpltCallback : callback for Slave reception end of transfer. + (+) ListenCpltCallback : callback for end of listen mode. + (+) ErrorCallback : callback for error detection. + (+) MspInitCallback : callback for Msp Init. + (+) MspDeInitCallback : callback for Msp DeInit. + [..] + For callback AddrCallback use dedicated register callbacks : HAL_SMBUS_UnRegisterAddrCallback. + [..] + By default, after the HAL_SMBUS_Init() and when the state is HAL_I2C_STATE_RESET + all callbacks are set to the corresponding weak functions: + examples HAL_SMBUS_MasterTxCpltCallback(), HAL_SMBUS_MasterRxCpltCallback(). + Exception done for MspInit and MspDeInit functions that are + reset to the legacy weak functions in the HAL_SMBUS_Init()/ HAL_SMBUS_DeInit() only when + these callbacks are null (not registered beforehand). + If MspInit or MspDeInit are not null, the HAL_SMBUS_Init()/ HAL_SMBUS_DeInit() + keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state. + [..] + Callbacks can be registered/unregistered in HAL_I2C_STATE_READY state only. + Exception done MspInit/MspDeInit functions that can be registered/unregistered + in HAL_I2C_STATE_READY or HAL_I2C_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_SMBUS_RegisterCallback() before calling HAL_SMBUS_DeInit() + or HAL_SMBUS_Init() function. + [..] + When the compilation flag USE_HAL_SMBUS_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. + + [..] + (@) You can refer to the SMBUS HAL driver header file for more useful macros + + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup SMBUS SMBUS + * @brief SMBUS HAL module driver + * @{ + */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup SMBUS_Private_Define SMBUS Private Constants + * @{ + */ +#define TIMING_CLEAR_MASK (0xF0FFFFFFUL) /*!< SMBUS TIMING clear register Mask */ +#define HAL_TIMEOUT_ADDR (10000U) /*!< 10 s */ +#define HAL_TIMEOUT_BUSY (25U) /*!< 25 ms */ +#define HAL_TIMEOUT_DIR (25U) /*!< 25 ms */ +#define HAL_TIMEOUT_RXNE (25U) /*!< 25 ms */ +#define HAL_TIMEOUT_STOPF (25U) /*!< 25 ms */ +#define HAL_TIMEOUT_TC (25U) /*!< 25 ms */ +#define HAL_TIMEOUT_TCR (25U) /*!< 25 ms */ +#define HAL_TIMEOUT_TXIS (25U) /*!< 25 ms */ +#define MAX_NBYTE_SIZE 255U +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup SMBUS_Private_Functions SMBUS Private Functions + * @{ + */ +/* Private functions to handle flags during polling transfer */ +static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, + FlagStatus Status, uint32_t Timeout); + +/* Private functions for SMBUS transfer IRQ handler */ +static HAL_StatusTypeDef SMBUS_Master_ISR(SMBUS_HandleTypeDef *hsmbus, uint32_t StatusFlags); +static HAL_StatusTypeDef SMBUS_Slave_ISR(SMBUS_HandleTypeDef *hsmbus, uint32_t StatusFlags); +static void SMBUS_ITErrorHandler(SMBUS_HandleTypeDef *hsmbus); + +/* Private functions to centralize the enable/disable of Interrupts */ +static void SMBUS_Enable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint32_t InterruptRequest); +static void SMBUS_Disable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint32_t InterruptRequest); + +/* Private function to flush TXDR register */ +static void SMBUS_Flush_TXDR(SMBUS_HandleTypeDef *hsmbus); + +/* Private function to handle start, restart or stop a transfer */ +static void SMBUS_TransferConfig(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t Size, + uint32_t Mode, uint32_t Request); + +/* Private function to Convert Specific options */ +static void SMBUS_ConvertOtherXferOptions(SMBUS_HandleTypeDef *hsmbus); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup SMBUS_Exported_Functions SMBUS Exported Functions + * @{ + */ + +/** @defgroup SMBUS_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + deinitialize the SMBUSx peripheral: + + (+) User must Implement HAL_SMBUS_MspInit() function in which he configures + all related peripherals resources (CLOCK, GPIO, IT and NVIC ). + + (+) Call the function HAL_SMBUS_Init() to configure the selected device with + the selected configuration: + (++) Clock Timing + (++) Bus Timeout + (++) Analog Filer mode + (++) Own Address 1 + (++) Addressing mode (Master, Slave) + (++) Dual Addressing mode + (++) Own Address 2 + (++) Own Address 2 Mask + (++) General call mode + (++) Nostretch mode + (++) Packet Error Check mode + (++) Peripheral mode + + + (+) Call the function HAL_SMBUS_DeInit() to restore the default configuration + of the selected SMBUSx peripheral. + + (+) Enable/Disable Analog/Digital filters with HAL_SMBUS_ConfigAnalogFilter() and + HAL_SMBUS_ConfigDigitalFilter(). + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the SMBUS according to the specified parameters + * in the SMBUS_InitTypeDef and initialize the associated handle. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMBUS_Init(SMBUS_HandleTypeDef *hsmbus) +{ + /* Check the SMBUS handle allocation */ + if (hsmbus == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance)); + assert_param(IS_SMBUS_ANALOG_FILTER(hsmbus->Init.AnalogFilter)); + assert_param(IS_SMBUS_OWN_ADDRESS1(hsmbus->Init.OwnAddress1)); + assert_param(IS_SMBUS_ADDRESSING_MODE(hsmbus->Init.AddressingMode)); + assert_param(IS_SMBUS_DUAL_ADDRESS(hsmbus->Init.DualAddressMode)); + assert_param(IS_SMBUS_OWN_ADDRESS2(hsmbus->Init.OwnAddress2)); + assert_param(IS_SMBUS_OWN_ADDRESS2_MASK(hsmbus->Init.OwnAddress2Masks)); + assert_param(IS_SMBUS_GENERAL_CALL(hsmbus->Init.GeneralCallMode)); + assert_param(IS_SMBUS_NO_STRETCH(hsmbus->Init.NoStretchMode)); + assert_param(IS_SMBUS_PEC(hsmbus->Init.PacketErrorCheckMode)); + assert_param(IS_SMBUS_PERIPHERAL_MODE(hsmbus->Init.PeripheralMode)); + + if (hsmbus->State == HAL_SMBUS_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hsmbus->Lock = HAL_UNLOCKED; + +#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) + hsmbus->MasterTxCpltCallback = HAL_SMBUS_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */ + hsmbus->MasterRxCpltCallback = HAL_SMBUS_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */ + hsmbus->SlaveTxCpltCallback = HAL_SMBUS_SlaveTxCpltCallback; /* Legacy weak SlaveTxCpltCallback */ + hsmbus->SlaveRxCpltCallback = HAL_SMBUS_SlaveRxCpltCallback; /* Legacy weak SlaveRxCpltCallback */ + hsmbus->ListenCpltCallback = HAL_SMBUS_ListenCpltCallback; /* Legacy weak ListenCpltCallback */ + hsmbus->ErrorCallback = HAL_SMBUS_ErrorCallback; /* Legacy weak ErrorCallback */ + hsmbus->AddrCallback = HAL_SMBUS_AddrCallback; /* Legacy weak AddrCallback */ + + if (hsmbus->MspInitCallback == NULL) + { + hsmbus->MspInitCallback = HAL_SMBUS_MspInit; /* Legacy weak MspInit */ + } + + /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ + hsmbus->MspInitCallback(hsmbus); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + HAL_SMBUS_MspInit(hsmbus); +#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ + } + + hsmbus->State = HAL_SMBUS_STATE_BUSY; + + /* Disable the selected SMBUS peripheral */ + __HAL_SMBUS_DISABLE(hsmbus); + + /*---------------------------- SMBUSx TIMINGR Configuration ------------------------*/ + /* Configure SMBUSx: Frequency range */ + hsmbus->Instance->TIMINGR = hsmbus->Init.Timing & TIMING_CLEAR_MASK; + + /*---------------------------- SMBUSx TIMEOUTR Configuration ------------------------*/ + /* Configure SMBUSx: Bus Timeout */ + hsmbus->Instance->TIMEOUTR &= ~I2C_TIMEOUTR_TIMOUTEN; + hsmbus->Instance->TIMEOUTR &= ~I2C_TIMEOUTR_TEXTEN; + hsmbus->Instance->TIMEOUTR = hsmbus->Init.SMBusTimeout; + + /*---------------------------- SMBUSx OAR1 Configuration -----------------------*/ + /* Configure SMBUSx: Own Address1 and ack own address1 mode */ + hsmbus->Instance->OAR1 &= ~I2C_OAR1_OA1EN; + + if (hsmbus->Init.OwnAddress1 != 0UL) + { + if (hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_7BIT) + { + hsmbus->Instance->OAR1 = (I2C_OAR1_OA1EN | hsmbus->Init.OwnAddress1); + } + } + + /*---------------------------- SMBUSx CR2 Configuration ------------------------*/ + /* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process) */ + /* AUTOEND and NACK bit will be manage during Transfer process */ + hsmbus->Instance->CR2 |= (I2C_CR2_AUTOEND | I2C_CR2_NACK); + + /*---------------------------- SMBUSx OAR2 Configuration -----------------------*/ + /* Configure SMBUSx: Dual mode and Own Address2 */ + hsmbus->Instance->OAR2 = (hsmbus->Init.DualAddressMode | hsmbus->Init.OwnAddress2 | \ + (hsmbus->Init.OwnAddress2Masks << 8U)); + + /*---------------------------- SMBUSx CR1 Configuration ------------------------*/ + /* Configure SMBUSx: Generalcall and NoStretch mode */ + hsmbus->Instance->CR1 = (hsmbus->Init.GeneralCallMode | hsmbus->Init.NoStretchMode | \ + hsmbus->Init.PacketErrorCheckMode | hsmbus->Init.PeripheralMode | \ + hsmbus->Init.AnalogFilter); + + /* Enable Slave Byte Control only in case of Packet Error Check is enabled + and SMBUS Peripheral is set in Slave mode */ + if ((hsmbus->Init.PacketErrorCheckMode == SMBUS_PEC_ENABLE) && \ + ((hsmbus->Init.PeripheralMode == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE) || \ + (hsmbus->Init.PeripheralMode == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE_ARP))) + { + hsmbus->Instance->CR1 |= I2C_CR1_SBC; + } + + /* Enable the selected SMBUS peripheral */ + __HAL_SMBUS_ENABLE(hsmbus); + + hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE; + hsmbus->PreviousState = HAL_SMBUS_STATE_READY; + hsmbus->State = HAL_SMBUS_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitialize the SMBUS peripheral. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMBUS_DeInit(SMBUS_HandleTypeDef *hsmbus) +{ + /* Check the SMBUS handle allocation */ + if (hsmbus == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance)); + + hsmbus->State = HAL_SMBUS_STATE_BUSY; + + /* Disable the SMBUS Peripheral Clock */ + __HAL_SMBUS_DISABLE(hsmbus); + +#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) + if (hsmbus->MspDeInitCallback == NULL) + { + hsmbus->MspDeInitCallback = HAL_SMBUS_MspDeInit; /* Legacy weak MspDeInit */ + } + + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + hsmbus->MspDeInitCallback(hsmbus); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + HAL_SMBUS_MspDeInit(hsmbus); +#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ + + hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE; + hsmbus->PreviousState = HAL_SMBUS_STATE_RESET; + hsmbus->State = HAL_SMBUS_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hsmbus); + + return HAL_OK; +} + +/** + * @brief Initialize the SMBUS MSP. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @retval None + */ +__weak void HAL_SMBUS_MspInit(SMBUS_HandleTypeDef *hsmbus) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsmbus); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMBUS_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitialize the SMBUS MSP. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @retval None + */ +__weak void HAL_SMBUS_MspDeInit(SMBUS_HandleTypeDef *hsmbus) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsmbus); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMBUS_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief Configure Analog noise filter. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @param AnalogFilter This parameter can be one of the following values: + * @arg @ref SMBUS_ANALOGFILTER_ENABLE + * @arg @ref SMBUS_ANALOGFILTER_DISABLE + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMBUS_ConfigAnalogFilter(SMBUS_HandleTypeDef *hsmbus, uint32_t AnalogFilter) +{ + /* Check the parameters */ + assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance)); + assert_param(IS_SMBUS_ANALOG_FILTER(AnalogFilter)); + + if (hsmbus->State == HAL_SMBUS_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsmbus); + + hsmbus->State = HAL_SMBUS_STATE_BUSY; + + /* Disable the selected SMBUS peripheral */ + __HAL_SMBUS_DISABLE(hsmbus); + + /* Reset ANOFF bit */ + hsmbus->Instance->CR1 &= ~(I2C_CR1_ANFOFF); + + /* Set analog filter bit*/ + hsmbus->Instance->CR1 |= AnalogFilter; + + __HAL_SMBUS_ENABLE(hsmbus); + + hsmbus->State = HAL_SMBUS_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Configure Digital noise filter. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @param DigitalFilter Coefficient of digital noise filter between Min_Data=0x00 and Max_Data=0x0F. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMBUS_ConfigDigitalFilter(SMBUS_HandleTypeDef *hsmbus, uint32_t DigitalFilter) +{ + uint32_t tmpreg; + + /* Check the parameters */ + assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance)); + assert_param(IS_SMBUS_DIGITAL_FILTER(DigitalFilter)); + + if (hsmbus->State == HAL_SMBUS_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsmbus); + + hsmbus->State = HAL_SMBUS_STATE_BUSY; + + /* Disable the selected SMBUS peripheral */ + __HAL_SMBUS_DISABLE(hsmbus); + + /* Get the old register value */ + tmpreg = hsmbus->Instance->CR1; + + /* Reset I2C DNF bits [11:8] */ + tmpreg &= ~(I2C_CR1_DNF); + + /* Set I2Cx DNF coefficient */ + tmpreg |= DigitalFilter << I2C_CR1_DNF_Pos; + + /* Store the new register value */ + hsmbus->Instance->CR1 = tmpreg; + + __HAL_SMBUS_ENABLE(hsmbus); + + hsmbus->State = HAL_SMBUS_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User SMBUS Callback + * To be used instead of the weak predefined callback + * @note The HAL_SMBUS_RegisterCallback() may be called before HAL_SMBUS_Init() in + * HAL_SMBUS_STATE_RESET to register callbacks for HAL_SMBUS_MSPINIT_CB_ID and + * HAL_SMBUS_MSPDEINIT_CB_ID. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID + * @arg @ref HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID + * @arg @ref HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID + * @arg @ref HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID + * @arg @ref HAL_SMBUS_LISTEN_COMPLETE_CB_ID Listen Complete callback ID + * @arg @ref HAL_SMBUS_ERROR_CB_ID Error callback ID + * @arg @ref HAL_SMBUS_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_SMBUS_MSPDEINIT_CB_ID MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMBUS_RegisterCallback(SMBUS_HandleTypeDef *hsmbus, + HAL_SMBUS_CallbackIDTypeDef CallbackID, + pSMBUS_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + if (HAL_SMBUS_STATE_READY == hsmbus->State) + { + switch (CallbackID) + { + case HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID : + hsmbus->MasterTxCpltCallback = pCallback; + break; + + case HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID : + hsmbus->MasterRxCpltCallback = pCallback; + break; + + case HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID : + hsmbus->SlaveTxCpltCallback = pCallback; + break; + + case HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID : + hsmbus->SlaveRxCpltCallback = pCallback; + break; + + case HAL_SMBUS_LISTEN_COMPLETE_CB_ID : + hsmbus->ListenCpltCallback = pCallback; + break; + + case HAL_SMBUS_ERROR_CB_ID : + hsmbus->ErrorCallback = pCallback; + break; + + case HAL_SMBUS_MSPINIT_CB_ID : + hsmbus->MspInitCallback = pCallback; + break; + + case HAL_SMBUS_MSPDEINIT_CB_ID : + hsmbus->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_SMBUS_STATE_RESET == hsmbus->State) + { + switch (CallbackID) + { + case HAL_SMBUS_MSPINIT_CB_ID : + hsmbus->MspInitCallback = pCallback; + break; + + case HAL_SMBUS_MSPDEINIT_CB_ID : + hsmbus->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister an SMBUS Callback + * SMBUS callback is redirected to the weak predefined callback + * @note The HAL_SMBUS_UnRegisterCallback() may be called before HAL_SMBUS_Init() in + * HAL_SMBUS_STATE_RESET to un-register callbacks for HAL_SMBUS_MSPINIT_CB_ID and + * HAL_SMBUS_MSPDEINIT_CB_ID + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * This parameter can be one of the following values: + * @arg @ref HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID + * @arg @ref HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID + * @arg @ref HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID + * @arg @ref HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID + * @arg @ref HAL_SMBUS_LISTEN_COMPLETE_CB_ID Listen Complete callback ID + * @arg @ref HAL_SMBUS_ERROR_CB_ID Error callback ID + * @arg @ref HAL_SMBUS_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_SMBUS_MSPDEINIT_CB_ID MspDeInit callback ID + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMBUS_UnRegisterCallback(SMBUS_HandleTypeDef *hsmbus, + HAL_SMBUS_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (HAL_SMBUS_STATE_READY == hsmbus->State) + { + switch (CallbackID) + { + case HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID : + hsmbus->MasterTxCpltCallback = HAL_SMBUS_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */ + break; + + case HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID : + hsmbus->MasterRxCpltCallback = HAL_SMBUS_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */ + break; + + case HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID : + hsmbus->SlaveTxCpltCallback = HAL_SMBUS_SlaveTxCpltCallback; /* Legacy weak SlaveTxCpltCallback */ + break; + + case HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID : + hsmbus->SlaveRxCpltCallback = HAL_SMBUS_SlaveRxCpltCallback; /* Legacy weak SlaveRxCpltCallback */ + break; + + case HAL_SMBUS_LISTEN_COMPLETE_CB_ID : + hsmbus->ListenCpltCallback = HAL_SMBUS_ListenCpltCallback; /* Legacy weak ListenCpltCallback */ + break; + + case HAL_SMBUS_ERROR_CB_ID : + hsmbus->ErrorCallback = HAL_SMBUS_ErrorCallback; /* Legacy weak ErrorCallback */ + break; + + case HAL_SMBUS_MSPINIT_CB_ID : + hsmbus->MspInitCallback = HAL_SMBUS_MspInit; /* Legacy weak MspInit */ + break; + + case HAL_SMBUS_MSPDEINIT_CB_ID : + hsmbus->MspDeInitCallback = HAL_SMBUS_MspDeInit; /* Legacy weak MspDeInit */ + break; + + default : + /* Update the error code */ + hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_SMBUS_STATE_RESET == hsmbus->State) + { + switch (CallbackID) + { + case HAL_SMBUS_MSPINIT_CB_ID : + hsmbus->MspInitCallback = HAL_SMBUS_MspInit; /* Legacy weak MspInit */ + break; + + case HAL_SMBUS_MSPDEINIT_CB_ID : + hsmbus->MspDeInitCallback = HAL_SMBUS_MspDeInit; /* Legacy weak MspDeInit */ + break; + + default : + /* Update the error code */ + hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Register the Slave Address Match SMBUS Callback + * To be used instead of the weak HAL_SMBUS_AddrCallback() predefined callback + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @param pCallback pointer to the Address Match Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMBUS_RegisterAddrCallback(SMBUS_HandleTypeDef *hsmbus, + pSMBUS_AddrCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + if (HAL_SMBUS_STATE_READY == hsmbus->State) + { + hsmbus->AddrCallback = pCallback; + } + else + { + /* Update the error code */ + hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief UnRegister the Slave Address Match SMBUS Callback + * Info Ready SMBUS Callback is redirected to the weak HAL_SMBUS_AddrCallback() predefined callback + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMBUS_UnRegisterAddrCallback(SMBUS_HandleTypeDef *hsmbus) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (HAL_SMBUS_STATE_READY == hsmbus->State) + { + hsmbus->AddrCallback = HAL_SMBUS_AddrCallback; /* Legacy weak AddrCallback */ + } + else + { + /* Update the error code */ + hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup SMBUS_Exported_Functions_Group2 Input and Output operation functions + * @brief Data transfers functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the SMBUS data + transfers. + + (#) Blocking mode function to check if device is ready for usage is : + (++) HAL_SMBUS_IsDeviceReady() + + (#) There is only one mode of transfer: + (++) Non-Blocking mode : The communication is performed using Interrupts. + These functions return the status of the transfer startup. + The end of the data processing will be indicated through the + dedicated SMBUS IRQ when using Interrupt mode. + + (#) Non-Blocking mode functions with Interrupt are : + (++) HAL_SMBUS_Master_Transmit_IT() + (++) HAL_SMBUS_Master_Receive_IT() + (++) HAL_SMBUS_Slave_Transmit_IT() + (++) HAL_SMBUS_Slave_Receive_IT() + (++) HAL_SMBUS_EnableListen_IT() or alias HAL_SMBUS_EnableListen_IT() + (++) HAL_SMBUS_DisableListen_IT() + (++) HAL_SMBUS_EnableAlert_IT() + (++) HAL_SMBUS_DisableAlert_IT() + + (#) A set of Transfer Complete Callbacks are provided in non-Blocking mode: + (++) HAL_SMBUS_MasterTxCpltCallback() + (++) HAL_SMBUS_MasterRxCpltCallback() + (++) HAL_SMBUS_SlaveTxCpltCallback() + (++) HAL_SMBUS_SlaveRxCpltCallback() + (++) HAL_SMBUS_AddrCallback() + (++) HAL_SMBUS_ListenCpltCallback() + (++) HAL_SMBUS_ErrorCallback() + +@endverbatim + * @{ + */ + +/** + * @brief Transmit in master/host SMBUS mode an amount of data in non-blocking mode with Interrupt. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMBUS_Master_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, + uint8_t *pData, uint16_t Size, uint32_t XferOptions) +{ + uint32_t tmp; + + /* Check the parameters */ + assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if (hsmbus->State == HAL_SMBUS_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsmbus); + + hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_TX; + hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE; + /* Prepare transfer parameters */ + hsmbus->pBuffPtr = pData; + hsmbus->XferCount = Size; + hsmbus->XferOptions = XferOptions; + + /* In case of Quick command, remove autoend mode */ + /* Manage the stop generation by software */ + if (hsmbus->pBuffPtr == NULL) + { + hsmbus->XferOptions &= ~SMBUS_AUTOEND_MODE; + } + + if (Size > MAX_NBYTE_SIZE) + { + hsmbus->XferSize = MAX_NBYTE_SIZE; + } + else + { + hsmbus->XferSize = Size; + } + + /* Send Slave Address */ + /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */ + if ((hsmbus->XferSize < hsmbus->XferCount) && (hsmbus->XferSize == MAX_NBYTE_SIZE)) + { + SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize, + SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), + SMBUS_GENERATE_START_WRITE); + } + else + { + /* If transfer direction not change, do not generate Restart Condition */ + /* Mean Previous state is same as current state */ + + /* Store current volatile XferOptions, misra rule */ + tmp = hsmbus->XferOptions; + + if ((hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_TX) && \ + (IS_SMBUS_TRANSFER_OTHER_OPTIONS_REQUEST(tmp) == 0)) + { + SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions, + SMBUS_NO_STARTSTOP); + } + /* Else transfer direction change, so generate Restart with new transfer direction */ + else + { + /* Convert OTHER_xxx XferOptions if any */ + SMBUS_ConvertOtherXferOptions(hsmbus); + + /* Handle Transfer */ + SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize, + hsmbus->XferOptions, + SMBUS_GENERATE_START_WRITE); + } + + /* If PEC mode is enable, size to transmit manage by SW part should be Size-1 byte, corresponding to PEC byte */ + /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */ + if (SMBUS_GET_PEC_MODE(hsmbus) != 0UL) + { + if (hsmbus->XferSize > 0U) + { + hsmbus->XferSize--; + hsmbus->XferCount--; + } + else + { + return HAL_ERROR; + } + } + } + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + /* Note : The SMBUS interrupts must be enabled after unlocking current process + to avoid the risk of SMBUS interrupt handle execution before current + process unlock */ + SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in master/host SMBUS mode an amount of data in non-blocking mode with Interrupt. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMBUS_Master_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, + uint16_t Size, uint32_t XferOptions) +{ + uint32_t tmp; + + /* Check the parameters */ + assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if (hsmbus->State == HAL_SMBUS_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsmbus); + + hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_RX; + hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE; + + /* Prepare transfer parameters */ + hsmbus->pBuffPtr = pData; + hsmbus->XferCount = Size; + hsmbus->XferOptions = XferOptions; + + /* In case of Quick command, remove autoend mode */ + /* Manage the stop generation by software */ + if (hsmbus->pBuffPtr == NULL) + { + hsmbus->XferOptions &= ~SMBUS_AUTOEND_MODE; + } + + if (Size > MAX_NBYTE_SIZE) + { + hsmbus->XferSize = MAX_NBYTE_SIZE; + } + else + { + hsmbus->XferSize = Size; + } + + /* Send Slave Address */ + /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */ + if ((hsmbus->XferSize < hsmbus->XferCount) && (hsmbus->XferSize == MAX_NBYTE_SIZE)) + { + SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize, + SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), + SMBUS_GENERATE_START_READ); + } + else + { + /* If transfer direction not change, do not generate Restart Condition */ + /* Mean Previous state is same as current state */ + + /* Store current volatile XferOptions, Misra rule */ + tmp = hsmbus->XferOptions; + + if ((hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_RX) && \ + (IS_SMBUS_TRANSFER_OTHER_OPTIONS_REQUEST(tmp) == 0)) + { + SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions, + SMBUS_NO_STARTSTOP); + } + /* Else transfer direction change, so generate Restart with new transfer direction */ + else + { + /* Convert OTHER_xxx XferOptions if any */ + SMBUS_ConvertOtherXferOptions(hsmbus); + + /* Handle Transfer */ + SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize, + hsmbus->XferOptions, + SMBUS_GENERATE_START_READ); + } + } + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + /* Note : The SMBUS interrupts must be enabled after unlocking current process + to avoid the risk of SMBUS interrupt handle execution before current + process unlock */ + SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Abort a master/host SMBUS process communication with Interrupt. + * @note This abort can be called only if state is ready + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMBUS_Master_Abort_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress) +{ + if (hsmbus->State == HAL_SMBUS_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsmbus); + + /* Keep the same state as previous */ + /* to perform as well the call of the corresponding end of transfer callback */ + if (hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_TX) + { + hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_TX; + } + else if (hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_RX) + { + hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_RX; + } + else + { + /* Wrong usage of abort function */ + /* This function should be used only in case of abort monitored by master device */ + return HAL_ERROR; + } + hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE; + + /* Set NBYTES to 1 to generate a dummy read on SMBUS peripheral */ + /* Set AUTOEND mode, this will generate a NACK then STOP condition to abort the current transfer */ + SMBUS_TransferConfig(hsmbus, DevAddress, 1, SMBUS_AUTOEND_MODE, SMBUS_NO_STARTSTOP); + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + /* Note : The SMBUS interrupts must be enabled after unlocking current process + to avoid the risk of SMBUS interrupt handle execution before current + process unlock */ + if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX) + { + SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX); + } + else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX) + { + SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX); + } + else + { + /* Nothing to do */ + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit in slave/device SMBUS mode an amount of data in non-blocking mode with Interrupt. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMBUS_Slave_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, + uint32_t XferOptions) +{ + /* Check the parameters */ + assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN) + { + if ((pData == NULL) || (Size == 0UL)) + { + hsmbus->ErrorCode = HAL_SMBUS_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + + /* Disable Interrupts, to prevent preemption during treatment in case of multicall */ + SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR | SMBUS_IT_TX); + + /* Process Locked */ + __HAL_LOCK(hsmbus); + + hsmbus->State = (HAL_SMBUS_STATE_SLAVE_BUSY_TX | HAL_SMBUS_STATE_LISTEN); + hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE; + + /* Set SBC bit to manage Acknowledge at each bit */ + hsmbus->Instance->CR1 |= I2C_CR1_SBC; + + /* Enable Address Acknowledge */ + hsmbus->Instance->CR2 &= ~I2C_CR2_NACK; + + /* Prepare transfer parameters */ + hsmbus->pBuffPtr = pData; + hsmbus->XferCount = Size; + hsmbus->XferOptions = XferOptions; + + /* Convert OTHER_xxx XferOptions if any */ + SMBUS_ConvertOtherXferOptions(hsmbus); + + if (Size > MAX_NBYTE_SIZE) + { + hsmbus->XferSize = MAX_NBYTE_SIZE; + } + else + { + hsmbus->XferSize = Size; + } + + /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */ + if ((hsmbus->XferSize < hsmbus->XferCount) && (hsmbus->XferSize == MAX_NBYTE_SIZE)) + { + SMBUS_TransferConfig(hsmbus, 0, (uint8_t)hsmbus->XferSize, + SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), + SMBUS_NO_STARTSTOP); + } + else + { + /* Set NBYTE to transmit */ + SMBUS_TransferConfig(hsmbus, 0, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions, + SMBUS_NO_STARTSTOP); + + /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */ + /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */ + if (SMBUS_GET_PEC_MODE(hsmbus) != 0UL) + { + hsmbus->XferSize--; + hsmbus->XferCount--; + } + } + + /* Clear ADDR flag after prepare the transfer parameters */ + /* This action will generate an acknowledge to the HOST */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ADDR); + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + /* Note : The SMBUS interrupts must be enabled after unlocking current process + to avoid the risk of SMBUS interrupt handle execution before current + process unlock */ + /* REnable ADDR interrupt */ + SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX | SMBUS_IT_ADDR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in slave/device SMBUS mode an amount of data in non-blocking mode with Interrupt. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMBUS_Slave_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, + uint32_t XferOptions) +{ + /* Check the parameters */ + assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN) + { + if ((pData == NULL) || (Size == 0UL)) + { + hsmbus->ErrorCode = HAL_SMBUS_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + + /* Disable Interrupts, to prevent preemption during treatment in case of multicall */ + SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR | SMBUS_IT_RX); + + /* Process Locked */ + __HAL_LOCK(hsmbus); + + hsmbus->State = (HAL_SMBUS_STATE_SLAVE_BUSY_RX | HAL_SMBUS_STATE_LISTEN); + hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE; + + /* Set SBC bit to manage Acknowledge at each bit */ + hsmbus->Instance->CR1 |= I2C_CR1_SBC; + + /* Enable Address Acknowledge */ + hsmbus->Instance->CR2 &= ~I2C_CR2_NACK; + + /* Prepare transfer parameters */ + hsmbus->pBuffPtr = pData; + hsmbus->XferSize = Size; + hsmbus->XferCount = Size; + hsmbus->XferOptions = XferOptions; + + /* Convert OTHER_xxx XferOptions if any */ + SMBUS_ConvertOtherXferOptions(hsmbus); + + /* Set NBYTE to receive */ + /* If XferSize equal "1", or XferSize equal "2" with PEC requested (mean 1 data byte + 1 PEC byte */ + /* no need to set RELOAD bit mode, a ACK will be automatically generated in that case */ + /* else need to set RELOAD bit mode to generate an automatic ACK at each byte Received */ + /* This RELOAD bit will be reset for last BYTE to be receive in SMBUS_Slave_ISR */ + if (((SMBUS_GET_PEC_MODE(hsmbus) != 0UL) && (hsmbus->XferSize == 2U)) || (hsmbus->XferSize == 1U)) + { + SMBUS_TransferConfig(hsmbus, 0, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions, + SMBUS_NO_STARTSTOP); + } + else + { + SMBUS_TransferConfig(hsmbus, 0, 1, hsmbus->XferOptions | SMBUS_RELOAD_MODE, SMBUS_NO_STARTSTOP); + } + + /* Clear ADDR flag after prepare the transfer parameters */ + /* This action will generate an acknowledge to the HOST */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ADDR); + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + /* Note : The SMBUS interrupts must be enabled after unlocking current process + to avoid the risk of SMBUS interrupt handle execution before current + process unlock */ + /* REnable ADDR interrupt */ + SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_ADDR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Enable the Address listen mode with Interrupt. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMBUS_EnableListen_IT(SMBUS_HandleTypeDef *hsmbus) +{ + hsmbus->State = HAL_SMBUS_STATE_LISTEN; + + /* Enable the Address Match interrupt */ + SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_ADDR); + + return HAL_OK; +} + +/** + * @brief Disable the Address listen mode with Interrupt. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMBUS_DisableListen_IT(SMBUS_HandleTypeDef *hsmbus) +{ + /* Disable Address listen mode only if a transfer is not ongoing */ + if (hsmbus->State == HAL_SMBUS_STATE_LISTEN) + { + hsmbus->State = HAL_SMBUS_STATE_READY; + + /* Disable the Address Match interrupt */ + SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Enable the SMBUS alert mode with Interrupt. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUSx peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMBUS_EnableAlert_IT(SMBUS_HandleTypeDef *hsmbus) +{ + /* Enable SMBus alert */ + hsmbus->Instance->CR1 |= I2C_CR1_ALERTEN; + + /* Clear ALERT flag */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ALERT); + + /* Enable Alert Interrupt */ + SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_ALERT); + + return HAL_OK; +} +/** + * @brief Disable the SMBUS alert mode with Interrupt. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUSx peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMBUS_DisableAlert_IT(SMBUS_HandleTypeDef *hsmbus) +{ + /* Enable SMBus alert */ + hsmbus->Instance->CR1 &= ~I2C_CR1_ALERTEN; + + /* Disable Alert Interrupt */ + SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ALERT); + + return HAL_OK; +} + +/** + * @brief Check if target device is ready for communication. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param Trials Number of trials + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMBUS_IsDeviceReady(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint32_t Trials, + uint32_t Timeout) +{ + uint32_t tickstart; + + __IO uint32_t SMBUS_Trials = 0UL; + + FlagStatus tmp1; + FlagStatus tmp2; + + if (hsmbus->State == HAL_SMBUS_STATE_READY) + { + if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BUSY) != RESET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hsmbus); + + hsmbus->State = HAL_SMBUS_STATE_BUSY; + hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE; + + do + { + /* Generate Start */ + hsmbus->Instance->CR2 = SMBUS_GENERATE_START(hsmbus->Init.AddressingMode, DevAddress); + + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is set or a NACK flag is set*/ + tickstart = HAL_GetTick(); + + tmp1 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF); + tmp2 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF); + + while ((tmp1 == RESET) && (tmp2 == RESET)) + { + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL)) + { + /* Device is ready */ + hsmbus->State = HAL_SMBUS_STATE_READY; + + /* Update SMBUS error code */ + hsmbus->ErrorCode |= HAL_SMBUS_ERROR_HALTIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + return HAL_ERROR; + } + } + + tmp1 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF); + tmp2 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF); + } + + /* Check if the NACKF flag has not been set */ + if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) == RESET) + { + /* Wait until STOPF flag is reset */ + if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK) + { + return HAL_ERROR; + } + + /* Clear STOP Flag */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF); + + /* Device is ready */ + hsmbus->State = HAL_SMBUS_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + return HAL_OK; + } + else + { + /* Wait until STOPF flag is reset */ + if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK) + { + return HAL_ERROR; + } + + /* Clear NACK Flag */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF); + + /* Clear STOP Flag, auto generated with autoend*/ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF); + } + + /* Check if the maximum allowed number of trials has been reached */ + if (SMBUS_Trials == Trials) + { + /* Generate Stop */ + hsmbus->Instance->CR2 |= I2C_CR2_STOP; + + /* Wait until STOPF flag is reset */ + if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK) + { + return HAL_ERROR; + } + + /* Clear STOP Flag */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF); + } + + /* Increment Trials */ + SMBUS_Trials++; + } while (SMBUS_Trials < Trials); + + hsmbus->State = HAL_SMBUS_STATE_READY; + + /* Update SMBUS error code */ + hsmbus->ErrorCode |= HAL_SMBUS_ERROR_HALTIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + return HAL_ERROR; + } + else + { + return HAL_BUSY; + } +} +/** + * @} + */ + +/** @defgroup SMBUS_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @{ + */ + +/** + * @brief Handle SMBUS event interrupt request. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @retval None + */ +void HAL_SMBUS_EV_IRQHandler(SMBUS_HandleTypeDef *hsmbus) +{ + /* Use a local variable to store the current ISR flags */ + /* This action will avoid a wrong treatment due to ISR flags change during interrupt handler */ + uint32_t tmpisrvalue = READ_REG(hsmbus->Instance->ISR); + uint32_t tmpcr1value = READ_REG(hsmbus->Instance->CR1); + + /* SMBUS in mode Transmitter ---------------------------------------------------*/ + if ((SMBUS_CHECK_IT_SOURCE(tmpcr1value, (SMBUS_IT_TCI | SMBUS_IT_STOPI | + SMBUS_IT_NACKI | SMBUS_IT_TXI)) != RESET) && + ((SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TXIS) != RESET) || + (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TCR) != RESET) || + (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TC) != RESET) || + (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) || + (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET))) + { + /* Slave mode selected */ + if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX) + { + (void)SMBUS_Slave_ISR(hsmbus, tmpisrvalue); + } + /* Master mode selected */ + else if ((hsmbus->State & HAL_SMBUS_STATE_MASTER_BUSY_TX) == HAL_SMBUS_STATE_MASTER_BUSY_TX) + { + (void)SMBUS_Master_ISR(hsmbus, tmpisrvalue); + } + else + { + /* Nothing to do */ + } + } + + /* SMBUS in mode Receiver ----------------------------------------------------*/ + if ((SMBUS_CHECK_IT_SOURCE(tmpcr1value, (SMBUS_IT_TCI | SMBUS_IT_STOPI | + SMBUS_IT_NACKI | SMBUS_IT_RXI)) != RESET) && + ((SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_RXNE) != RESET) || + (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TCR) != RESET) || + (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TC) != RESET) || + (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) || + (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET))) + { + /* Slave mode selected */ + if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX) + { + (void)SMBUS_Slave_ISR(hsmbus, tmpisrvalue); + } + /* Master mode selected */ + else if ((hsmbus->State & HAL_SMBUS_STATE_MASTER_BUSY_RX) == HAL_SMBUS_STATE_MASTER_BUSY_RX) + { + (void)SMBUS_Master_ISR(hsmbus, tmpisrvalue); + } + else + { + /* Nothing to do */ + } + } + + /* SMBUS in mode Listener Only --------------------------------------------------*/ + if (((SMBUS_CHECK_IT_SOURCE(tmpcr1value, SMBUS_IT_ADDRI) != RESET) || + (SMBUS_CHECK_IT_SOURCE(tmpcr1value, SMBUS_IT_STOPI) != RESET) || + (SMBUS_CHECK_IT_SOURCE(tmpcr1value, SMBUS_IT_NACKI) != RESET)) && + ((SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_ADDR) != RESET) || + (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) || + (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET))) + { + if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN) + { + (void)SMBUS_Slave_ISR(hsmbus, tmpisrvalue); + } + } +} + +/** + * @brief Handle SMBUS error interrupt request. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @retval None + */ +void HAL_SMBUS_ER_IRQHandler(SMBUS_HandleTypeDef *hsmbus) +{ + SMBUS_ITErrorHandler(hsmbus); +} + +/** + * @brief Master Tx Transfer completed callback. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @retval None + */ +__weak void HAL_SMBUS_MasterTxCpltCallback(SMBUS_HandleTypeDef *hsmbus) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsmbus); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMBUS_MasterTxCpltCallback() could be implemented in the user file + */ +} + +/** + * @brief Master Rx Transfer completed callback. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @retval None + */ +__weak void HAL_SMBUS_MasterRxCpltCallback(SMBUS_HandleTypeDef *hsmbus) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsmbus); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMBUS_MasterRxCpltCallback() could be implemented in the user file + */ +} + +/** @brief Slave Tx Transfer completed callback. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @retval None + */ +__weak void HAL_SMBUS_SlaveTxCpltCallback(SMBUS_HandleTypeDef *hsmbus) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsmbus); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMBUS_SlaveTxCpltCallback() could be implemented in the user file + */ +} + +/** + * @brief Slave Rx Transfer completed callback. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @retval None + */ +__weak void HAL_SMBUS_SlaveRxCpltCallback(SMBUS_HandleTypeDef *hsmbus) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsmbus); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMBUS_SlaveRxCpltCallback() could be implemented in the user file + */ +} + +/** + * @brief Slave Address Match callback. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @param TransferDirection Master request Transfer Direction (Write/Read) + * @param AddrMatchCode Address Match Code + * @retval None + */ +__weak void HAL_SMBUS_AddrCallback(SMBUS_HandleTypeDef *hsmbus, uint8_t TransferDirection, + uint16_t AddrMatchCode) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsmbus); + UNUSED(TransferDirection); + UNUSED(AddrMatchCode); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMBUS_AddrCallback() could be implemented in the user file + */ +} + +/** + * @brief Listen Complete callback. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @retval None + */ +__weak void HAL_SMBUS_ListenCpltCallback(SMBUS_HandleTypeDef *hsmbus) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsmbus); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMBUS_ListenCpltCallback() could be implemented in the user file + */ +} + +/** + * @brief SMBUS error callback. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @retval None + */ +__weak void HAL_SMBUS_ErrorCallback(SMBUS_HandleTypeDef *hsmbus) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsmbus); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SMBUS_ErrorCallback() could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup SMBUS_Exported_Functions_Group3 Peripheral State and Errors functions + * @brief Peripheral State and Errors functions + * +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the SMBUS handle state. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @retval HAL state + */ +uint32_t HAL_SMBUS_GetState(const SMBUS_HandleTypeDef *hsmbus) +{ + /* Return SMBUS handle state */ + return hsmbus->State; +} + +/** + * @brief Return the SMBUS error code. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @retval SMBUS Error Code + */ +uint32_t HAL_SMBUS_GetError(const SMBUS_HandleTypeDef *hsmbus) +{ + return hsmbus->ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup SMBUS_Private_Functions SMBUS Private Functions + * @brief Data transfers Private functions + * @{ + */ + +/** + * @brief Interrupt Sub-Routine which handle the Interrupt Flags Master Mode. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @param StatusFlags Value of Interrupt Flags. + * @retval HAL status + */ +static HAL_StatusTypeDef SMBUS_Master_ISR(SMBUS_HandleTypeDef *hsmbus, uint32_t StatusFlags) +{ + uint16_t DevAddress; + + /* Process Locked */ + __HAL_LOCK(hsmbus); + + if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_AF) != RESET) + { + /* Clear NACK Flag */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF); + + /* Set corresponding Error Code */ + /* No need to generate STOP, it is automatically done */ + hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ACKF; + + /* Flush TX register */ + SMBUS_Flush_TXDR(hsmbus); + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + /* Call the Error callback to inform upper layer */ +#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) + hsmbus->ErrorCallback(hsmbus); +#else + HAL_SMBUS_ErrorCallback(hsmbus); +#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ + } + else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_STOPF) != RESET) + { + /* Check and treat errors if errors occurs during STOP process */ + SMBUS_ITErrorHandler(hsmbus); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ + if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX) + { + /* Disable Interrupt */ + SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX); + + /* Clear STOP Flag */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + SMBUS_RESET_CR2(hsmbus); + + /* Flush remaining data in Fifo register in case of error occurs before TXEmpty */ + /* Disable the selected SMBUS peripheral */ + __HAL_SMBUS_DISABLE(hsmbus); + + hsmbus->PreviousState = HAL_SMBUS_STATE_READY; + hsmbus->State = HAL_SMBUS_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + /* Re-enable the selected SMBUS peripheral */ + __HAL_SMBUS_ENABLE(hsmbus); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) + hsmbus->MasterTxCpltCallback(hsmbus); +#else + HAL_SMBUS_MasterTxCpltCallback(hsmbus); +#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ + } + else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX) + { + /* Store Last receive data if any */ + if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_RXNE) != RESET) + { + /* Read data from RXDR */ + *hsmbus->pBuffPtr = (uint8_t)(hsmbus->Instance->RXDR); + + /* Increment Buffer pointer */ + hsmbus->pBuffPtr++; + + if ((hsmbus->XferSize > 0U)) + { + hsmbus->XferSize--; + hsmbus->XferCount--; + } + } + + /* Disable Interrupt */ + SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX); + + /* Clear STOP Flag */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + SMBUS_RESET_CR2(hsmbus); + + hsmbus->PreviousState = HAL_SMBUS_STATE_READY; + hsmbus->State = HAL_SMBUS_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) + hsmbus->MasterRxCpltCallback(hsmbus); +#else + HAL_SMBUS_MasterRxCpltCallback(hsmbus); +#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ + } + else + { + /* Nothing to do */ + } + } + else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_RXNE) != RESET) + { + /* Read data from RXDR */ + *hsmbus->pBuffPtr = (uint8_t)(hsmbus->Instance->RXDR); + + /* Increment Buffer pointer */ + hsmbus->pBuffPtr++; + + /* Increment Size counter */ + hsmbus->XferSize--; + hsmbus->XferCount--; + } + else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_TXIS) != RESET) + { + /* Write data to TXDR */ + hsmbus->Instance->TXDR = *hsmbus->pBuffPtr; + + /* Increment Buffer pointer */ + hsmbus->pBuffPtr++; + + /* Increment Size counter */ + hsmbus->XferSize--; + hsmbus->XferCount--; + } + else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_TCR) != RESET) + { + if ((hsmbus->XferCount != 0U) && (hsmbus->XferSize == 0U)) + { + DevAddress = (uint16_t)(hsmbus->Instance->CR2 & I2C_CR2_SADD); + + if (hsmbus->XferCount > MAX_NBYTE_SIZE) + { + SMBUS_TransferConfig(hsmbus, DevAddress, MAX_NBYTE_SIZE, + (SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE)), + SMBUS_NO_STARTSTOP); + hsmbus->XferSize = MAX_NBYTE_SIZE; + } + else + { + hsmbus->XferSize = hsmbus->XferCount; + SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions, + SMBUS_NO_STARTSTOP); + /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */ + /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */ + if (SMBUS_GET_PEC_MODE(hsmbus) != 0UL) + { + hsmbus->XferSize--; + hsmbus->XferCount--; + } + } + } + else if ((hsmbus->XferCount == 0U) && (hsmbus->XferSize == 0U)) + { + /* Call TxCpltCallback() if no stop mode is set */ + if (SMBUS_GET_STOP_MODE(hsmbus) != SMBUS_AUTOEND_MODE) + { + /* Call the corresponding callback to inform upper layer of End of Transfer */ + if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX) + { + /* Disable Interrupt */ + SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX); + hsmbus->PreviousState = hsmbus->State; + hsmbus->State = HAL_SMBUS_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) + hsmbus->MasterTxCpltCallback(hsmbus); +#else + HAL_SMBUS_MasterTxCpltCallback(hsmbus); +#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ + } + else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX) + { + SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX); + hsmbus->PreviousState = hsmbus->State; + hsmbus->State = HAL_SMBUS_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) + hsmbus->MasterRxCpltCallback(hsmbus); +#else + HAL_SMBUS_MasterRxCpltCallback(hsmbus); +#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ + } + else + { + /* Nothing to do */ + } + } + } + else + { + /* Nothing to do */ + } + } + else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_TC) != RESET) + { + if (hsmbus->XferCount == 0U) + { + /* Specific use case for Quick command */ + if (hsmbus->pBuffPtr == NULL) + { + /* Generate a Stop command */ + hsmbus->Instance->CR2 |= I2C_CR2_STOP; + } + /* Call TxCpltCallback() if no stop mode is set */ + else if (SMBUS_GET_STOP_MODE(hsmbus) != SMBUS_AUTOEND_MODE) + { + /* No Generate Stop, to permit restart mode */ + /* The stop will be done at the end of transfer, when SMBUS_AUTOEND_MODE enable */ + + /* Call the corresponding callback to inform upper layer of End of Transfer */ + if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX) + { + /* Disable Interrupt */ + SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX); + hsmbus->PreviousState = hsmbus->State; + hsmbus->State = HAL_SMBUS_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) + hsmbus->MasterTxCpltCallback(hsmbus); +#else + HAL_SMBUS_MasterTxCpltCallback(hsmbus); +#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ + } + else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX) + { + SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX); + hsmbus->PreviousState = hsmbus->State; + hsmbus->State = HAL_SMBUS_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) + hsmbus->MasterRxCpltCallback(hsmbus); +#else + HAL_SMBUS_MasterRxCpltCallback(hsmbus); +#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ + } + else + { + /* Nothing to do */ + } + } + else + { + /* Nothing to do */ + } + } + } + else + { + /* Nothing to do */ + } + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + return HAL_OK; +} +/** + * @brief Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @param StatusFlags Value of Interrupt Flags. + * @retval HAL status + */ +static HAL_StatusTypeDef SMBUS_Slave_ISR(SMBUS_HandleTypeDef *hsmbus, uint32_t StatusFlags) +{ + uint8_t TransferDirection; + uint16_t SlaveAddrCode; + + /* Process Locked */ + __HAL_LOCK(hsmbus); + + if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_AF) != RESET) + { + /* Check that SMBUS transfer finished */ + /* if yes, normal usecase, a NACK is sent by the HOST when Transfer is finished */ + /* Mean XferCount == 0*/ + /* So clear Flag NACKF only */ + if (hsmbus->XferCount == 0U) + { + /* Clear NACK Flag */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF); + + /* Flush TX register */ + SMBUS_Flush_TXDR(hsmbus); + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + } + else + { + /* if no, error usecase, a Non-Acknowledge of last Data is generated by the HOST*/ + /* Clear NACK Flag */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF); + + /* Set HAL State to "Idle" State, mean to LISTEN state */ + /* So reset Slave Busy state */ + hsmbus->PreviousState = hsmbus->State; + hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_TX); + hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_RX); + + /* Disable RX/TX Interrupts, keep only ADDR Interrupt */ + SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_TX); + + /* Set ErrorCode corresponding to a Non-Acknowledge */ + hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ACKF; + + /* Flush TX register */ + SMBUS_Flush_TXDR(hsmbus); + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + /* Call the Error callback to inform upper layer */ +#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) + hsmbus->ErrorCallback(hsmbus); +#else + HAL_SMBUS_ErrorCallback(hsmbus); +#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ + } + } + else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_ADDR) != RESET) + { + TransferDirection = (uint8_t)(SMBUS_GET_DIR(hsmbus)); + SlaveAddrCode = (uint16_t)(SMBUS_GET_ADDR_MATCH(hsmbus)); + + /* Disable ADDR interrupt to prevent multiple ADDRInterrupt*/ + /* Other ADDRInterrupt will be treat in next Listen usecase */ + __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_ADDRI); + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + /* Call Slave Addr callback */ +#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) + hsmbus->AddrCallback(hsmbus, TransferDirection, SlaveAddrCode); +#else + HAL_SMBUS_AddrCallback(hsmbus, TransferDirection, SlaveAddrCode); +#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ + } + else if ((SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_RXNE) != RESET) || + (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_TCR) != RESET)) + { + if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX) + { + /* Read data from RXDR */ + *hsmbus->pBuffPtr = (uint8_t)(hsmbus->Instance->RXDR); + + /* Increment Buffer pointer */ + hsmbus->pBuffPtr++; + + hsmbus->XferSize--; + hsmbus->XferCount--; + + if (hsmbus->XferCount == 1U) + { + /* Receive last Byte, can be PEC byte in case of PEC BYTE enabled */ + /* or only the last Byte of Transfer */ + /* So reset the RELOAD bit mode */ + hsmbus->XferOptions &= ~SMBUS_RELOAD_MODE; + SMBUS_TransferConfig(hsmbus, 0, 1, hsmbus->XferOptions, SMBUS_NO_STARTSTOP); + } + else if (hsmbus->XferCount == 0U) + { + /* Last Byte is received, disable Interrupt */ + SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX); + + /* Remove HAL_SMBUS_STATE_SLAVE_BUSY_RX, keep only HAL_SMBUS_STATE_LISTEN */ + hsmbus->PreviousState = hsmbus->State; + hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_RX); + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) + hsmbus->SlaveRxCpltCallback(hsmbus); +#else + HAL_SMBUS_SlaveRxCpltCallback(hsmbus); +#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ + } + else + { + /* Set Reload for next Bytes */ + SMBUS_TransferConfig(hsmbus, 0, 1, + SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), + SMBUS_NO_STARTSTOP); + + /* Ack last Byte Read */ + hsmbus->Instance->CR2 &= ~I2C_CR2_NACK; + } + } + else if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX) + { + if ((hsmbus->XferCount != 0U) && (hsmbus->XferSize == 0U)) + { + if (hsmbus->XferCount > MAX_NBYTE_SIZE) + { + SMBUS_TransferConfig(hsmbus, 0, MAX_NBYTE_SIZE, + (SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE)), + SMBUS_NO_STARTSTOP); + hsmbus->XferSize = MAX_NBYTE_SIZE; + } + else + { + hsmbus->XferSize = hsmbus->XferCount; + SMBUS_TransferConfig(hsmbus, 0, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions, + SMBUS_NO_STARTSTOP); + /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */ + /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */ + if (SMBUS_GET_PEC_MODE(hsmbus) != 0UL) + { + hsmbus->XferSize--; + hsmbus->XferCount--; + } + } + } + } + else + { + /* Nothing to do */ + } + } + else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_TXIS) != RESET) + { + /* Write data to TXDR only if XferCount not reach "0" */ + /* A TXIS flag can be set, during STOP treatment */ + /* Check if all Data have already been sent */ + /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */ + if (hsmbus->XferCount > 0U) + { + /* Write data to TXDR */ + hsmbus->Instance->TXDR = *hsmbus->pBuffPtr; + + /* Increment Buffer pointer */ + hsmbus->pBuffPtr++; + + hsmbus->XferCount--; + hsmbus->XferSize--; + } + + if (hsmbus->XferCount == 0U) + { + /* Last Byte is Transmitted */ + /* Remove HAL_SMBUS_STATE_SLAVE_BUSY_TX, keep only HAL_SMBUS_STATE_LISTEN */ + SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX); + hsmbus->PreviousState = hsmbus->State; + hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_TX); + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) + hsmbus->SlaveTxCpltCallback(hsmbus); +#else + HAL_SMBUS_SlaveTxCpltCallback(hsmbus); +#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ + } + } + else + { + /* Nothing to do */ + } + + /* Check if STOPF is set */ + if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_STOPF) != RESET) + { + if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN) + { + /* Store Last receive data if any */ + if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET) + { + /* Read data from RXDR */ + *hsmbus->pBuffPtr = (uint8_t)(hsmbus->Instance->RXDR); + + /* Increment Buffer pointer */ + hsmbus->pBuffPtr++; + + if ((hsmbus->XferSize > 0U)) + { + hsmbus->XferSize--; + hsmbus->XferCount--; + } + } + + /* Disable RX and TX Interrupts */ + SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_TX); + + /* Disable ADDR Interrupt */ + SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR); + + /* Disable Address Acknowledge */ + hsmbus->Instance->CR2 |= I2C_CR2_NACK; + + /* Clear Configuration Register 2 */ + SMBUS_RESET_CR2(hsmbus); + + /* Clear STOP Flag */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF); + + /* Clear ADDR flag */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ADDR); + + hsmbus->XferOptions = 0; + hsmbus->PreviousState = hsmbus->State; + hsmbus->State = HAL_SMBUS_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ +#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) + hsmbus->ListenCpltCallback(hsmbus); +#else + HAL_SMBUS_ListenCpltCallback(hsmbus); +#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ + } + } + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + return HAL_OK; +} +/** + * @brief Manage the enabling of Interrupts. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @param InterruptRequest Value of @ref SMBUS_Interrupt_configuration_definition. + * @retval HAL status + */ +static void SMBUS_Enable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint32_t InterruptRequest) +{ + uint32_t tmpisr = 0UL; + + if ((InterruptRequest & SMBUS_IT_ALERT) == SMBUS_IT_ALERT) + { + /* Enable ERR interrupt */ + tmpisr |= SMBUS_IT_ERRI; + } + + if ((InterruptRequest & SMBUS_IT_ADDR) == SMBUS_IT_ADDR) + { + /* Enable ADDR, STOP interrupt */ + tmpisr |= SMBUS_IT_ADDRI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_ERRI; + } + + if ((InterruptRequest & SMBUS_IT_TX) == SMBUS_IT_TX) + { + /* Enable ERR, TC, STOP, NACK, RXI interrupt */ + tmpisr |= SMBUS_IT_ERRI | SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_TXI; + } + + if ((InterruptRequest & SMBUS_IT_RX) == SMBUS_IT_RX) + { + /* Enable ERR, TC, STOP, NACK, TXI interrupt */ + tmpisr |= SMBUS_IT_ERRI | SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_RXI; + } + + /* Enable interrupts only at the end */ + /* to avoid the risk of SMBUS interrupt handle execution before */ + /* all interrupts requested done */ + __HAL_SMBUS_ENABLE_IT(hsmbus, tmpisr); +} +/** + * @brief Manage the disabling of Interrupts. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @param InterruptRequest Value of @ref SMBUS_Interrupt_configuration_definition. + * @retval HAL status + */ +static void SMBUS_Disable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint32_t InterruptRequest) +{ + uint32_t tmpisr = 0UL; + uint32_t tmpstate = hsmbus->State; + + if ((tmpstate == HAL_SMBUS_STATE_READY) && ((InterruptRequest & SMBUS_IT_ALERT) == SMBUS_IT_ALERT)) + { + /* Disable ERR interrupt */ + tmpisr |= SMBUS_IT_ERRI; + } + + if ((InterruptRequest & SMBUS_IT_TX) == SMBUS_IT_TX) + { + /* Disable TC, STOP, NACK and TXI interrupt */ + tmpisr |= SMBUS_IT_TCI | SMBUS_IT_TXI; + + if ((SMBUS_GET_ALERT_ENABLED(hsmbus) == 0UL) + && ((tmpstate & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN)) + { + /* Disable ERR interrupt */ + tmpisr |= SMBUS_IT_ERRI; + } + + if ((tmpstate & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN) + { + /* Disable STOP and NACK interrupt */ + tmpisr |= SMBUS_IT_STOPI | SMBUS_IT_NACKI; + } + } + + if ((InterruptRequest & SMBUS_IT_RX) == SMBUS_IT_RX) + { + /* Disable TC, STOP, NACK and RXI interrupt */ + tmpisr |= SMBUS_IT_TCI | SMBUS_IT_RXI; + + if ((SMBUS_GET_ALERT_ENABLED(hsmbus) == 0UL) + && ((tmpstate & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN)) + { + /* Disable ERR interrupt */ + tmpisr |= SMBUS_IT_ERRI; + } + + if ((tmpstate & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN) + { + /* Disable STOP and NACK interrupt */ + tmpisr |= SMBUS_IT_STOPI | SMBUS_IT_NACKI; + } + } + + if ((InterruptRequest & SMBUS_IT_ADDR) == SMBUS_IT_ADDR) + { + /* Disable ADDR, STOP and NACK interrupt */ + tmpisr |= SMBUS_IT_ADDRI | SMBUS_IT_STOPI | SMBUS_IT_NACKI; + + if (SMBUS_GET_ALERT_ENABLED(hsmbus) == 0UL) + { + /* Disable ERR interrupt */ + tmpisr |= SMBUS_IT_ERRI; + } + } + + /* Disable interrupts only at the end */ + /* to avoid a breaking situation like at "t" time */ + /* all disable interrupts request are not done */ + __HAL_SMBUS_DISABLE_IT(hsmbus, tmpisr); +} + +/** + * @brief SMBUS interrupts error handler. + * @param hsmbus SMBUS handle. + * @retval None + */ +static void SMBUS_ITErrorHandler(SMBUS_HandleTypeDef *hsmbus) +{ + uint32_t itflags = READ_REG(hsmbus->Instance->ISR); + uint32_t itsources = READ_REG(hsmbus->Instance->CR1); + uint32_t tmpstate; + uint32_t tmperror; + + /* SMBUS Bus error interrupt occurred ------------------------------------*/ + if (((itflags & SMBUS_FLAG_BERR) == SMBUS_FLAG_BERR) && \ + ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI)) + { + hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BERR; + + /* Clear BERR flag */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_BERR); + } + + /* SMBUS Over-Run/Under-Run interrupt occurred ----------------------------------------*/ + if (((itflags & SMBUS_FLAG_OVR) == SMBUS_FLAG_OVR) && \ + ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI)) + { + hsmbus->ErrorCode |= HAL_SMBUS_ERROR_OVR; + + /* Clear OVR flag */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_OVR); + } + + /* SMBUS Arbitration Loss error interrupt occurred ------------------------------------*/ + if (((itflags & SMBUS_FLAG_ARLO) == SMBUS_FLAG_ARLO) && \ + ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI)) + { + hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ARLO; + + /* Clear ARLO flag */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ARLO); + } + + /* SMBUS Timeout error interrupt occurred ---------------------------------------------*/ + if (((itflags & SMBUS_FLAG_TIMEOUT) == SMBUS_FLAG_TIMEOUT) && \ + ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI)) + { + hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BUSTIMEOUT; + + /* Clear TIMEOUT flag */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_TIMEOUT); + } + + /* SMBUS Alert error interrupt occurred -----------------------------------------------*/ + if (((itflags & SMBUS_FLAG_ALERT) == SMBUS_FLAG_ALERT) && \ + ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI)) + { + hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ALERT; + + /* Clear ALERT flag */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ALERT); + } + + /* SMBUS Packet Error Check error interrupt occurred ----------------------------------*/ + if (((itflags & SMBUS_FLAG_PECERR) == SMBUS_FLAG_PECERR) && \ + ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI)) + { + hsmbus->ErrorCode |= HAL_SMBUS_ERROR_PECERR; + + /* Clear PEC error flag */ + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_PECERR); + } + + /* Flush TX register */ + SMBUS_Flush_TXDR(hsmbus); + + /* Store current volatile hsmbus->ErrorCode, misra rule */ + tmperror = hsmbus->ErrorCode; + + /* Call the Error Callback in case of Error detected */ + if ((tmperror != HAL_SMBUS_ERROR_NONE) && (tmperror != HAL_SMBUS_ERROR_ACKF)) + { + /* Do not Reset the HAL state in case of ALERT error */ + if ((tmperror & HAL_SMBUS_ERROR_ALERT) != HAL_SMBUS_ERROR_ALERT) + { + /* Store current volatile hsmbus->State, misra rule */ + tmpstate = hsmbus->State; + + if (((tmpstate & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX) + || ((tmpstate & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX)) + { + /* Reset only HAL_SMBUS_STATE_SLAVE_BUSY_XX */ + /* keep HAL_SMBUS_STATE_LISTEN if set */ + hsmbus->PreviousState = HAL_SMBUS_STATE_READY; + hsmbus->State = HAL_SMBUS_STATE_LISTEN; + } + } + + /* Call the Error callback to inform upper layer */ +#if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) + hsmbus->ErrorCallback(hsmbus); +#else + HAL_SMBUS_ErrorCallback(hsmbus); +#endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ + } +} + +/** + * @brief Handle SMBUS Communication Timeout. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUS. + * @param Flag Specifies the SMBUS flag to check. + * @param Status The new Flag status (SET or RESET). + * @param Timeout Timeout duration + * @retval HAL status + */ +static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, + FlagStatus Status, uint32_t Timeout) +{ + uint32_t tickstart = HAL_GetTick(); + + /* Wait until flag is set */ + while ((FlagStatus)(__HAL_SMBUS_GET_FLAG(hsmbus, Flag)) == Status) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL)) + { + hsmbus->PreviousState = hsmbus->State; + hsmbus->State = HAL_SMBUS_STATE_READY; + + /* Update SMBUS error code */ + hsmbus->ErrorCode |= HAL_SMBUS_ERROR_HALTIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + return HAL_ERROR; + } + } + } + + return HAL_OK; +} + +/** + * @brief SMBUS Tx data register flush process. + * @param hsmbus SMBUS handle. + * @retval None + */ +static void SMBUS_Flush_TXDR(SMBUS_HandleTypeDef *hsmbus) +{ + /* If a pending TXIS flag is set */ + /* Write a dummy data in TXDR to clear it */ + if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TXIS) != RESET) + { + hsmbus->Instance->TXDR = 0x00U; + } + + /* Flush TX register if not empty */ + if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TXE) == RESET) + { + __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_TXE); + } +} + +/** + * @brief Handle SMBUSx communication when starting transfer or during transfer (TC or TCR flag are set). + * @param hsmbus SMBUS handle. + * @param DevAddress specifies the slave address to be programmed. + * @param Size specifies the number of bytes to be programmed. + * This parameter must be a value between 0 and 255. + * @param Mode New state of the SMBUS START condition generation. + * This parameter can be one or a combination of the following values: + * @arg @ref SMBUS_RELOAD_MODE Enable Reload mode. + * @arg @ref SMBUS_AUTOEND_MODE Enable Automatic end mode. + * @arg @ref SMBUS_SOFTEND_MODE Enable Software end mode and Reload mode. + * @arg @ref SMBUS_SENDPEC_MODE Enable Packet Error Calculation mode. + * @param Request New state of the SMBUS START condition generation. + * This parameter can be one of the following values: + * @arg @ref SMBUS_NO_STARTSTOP Don't Generate stop and start condition. + * @arg @ref SMBUS_GENERATE_STOP Generate stop condition (Size should be set to 0). + * @arg @ref SMBUS_GENERATE_START_READ Generate Restart for read request. + * @arg @ref SMBUS_GENERATE_START_WRITE Generate Restart for write request. + * @retval None + */ +static void SMBUS_TransferConfig(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t Size, + uint32_t Mode, uint32_t Request) +{ + /* Check the parameters */ + assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance)); + assert_param(IS_SMBUS_TRANSFER_MODE(Mode)); + assert_param(IS_SMBUS_TRANSFER_REQUEST(Request)); + + /* update CR2 register */ + MODIFY_REG(hsmbus->Instance->CR2, + ((I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | \ + (I2C_CR2_RD_WRN & (uint32_t)(Request >> (31UL - I2C_CR2_RD_WRN_Pos))) | \ + I2C_CR2_START | I2C_CR2_STOP | I2C_CR2_PECBYTE)), \ + (uint32_t)(((uint32_t)DevAddress & I2C_CR2_SADD) | \ + (((uint32_t)Size << I2C_CR2_NBYTES_Pos) & I2C_CR2_NBYTES) | \ + (uint32_t)Mode | (uint32_t)Request)); +} + +/** + * @brief Convert SMBUSx OTHER_xxx XferOptions to functional XferOptions. + * @param hsmbus SMBUS handle. + * @retval None + */ +static void SMBUS_ConvertOtherXferOptions(SMBUS_HandleTypeDef *hsmbus) +{ + /* if user set XferOptions to SMBUS_OTHER_FRAME_NO_PEC */ + /* it request implicitly to generate a restart condition */ + /* set XferOptions to SMBUS_FIRST_FRAME */ + if (hsmbus->XferOptions == SMBUS_OTHER_FRAME_NO_PEC) + { + hsmbus->XferOptions = SMBUS_FIRST_FRAME; + } + /* else if user set XferOptions to SMBUS_OTHER_FRAME_WITH_PEC */ + /* it request implicitly to generate a restart condition */ + /* set XferOptions to SMBUS_FIRST_FRAME | SMBUS_SENDPEC_MODE */ + else if (hsmbus->XferOptions == SMBUS_OTHER_FRAME_WITH_PEC) + { + hsmbus->XferOptions = SMBUS_FIRST_FRAME | SMBUS_SENDPEC_MODE; + } + /* else if user set XferOptions to SMBUS_OTHER_AND_LAST_FRAME_NO_PEC */ + /* it request implicitly to generate a restart condition */ + /* then generate a stop condition at the end of transfer */ + /* set XferOptions to SMBUS_FIRST_AND_LAST_FRAME_NO_PEC */ + else if (hsmbus->XferOptions == SMBUS_OTHER_AND_LAST_FRAME_NO_PEC) + { + hsmbus->XferOptions = SMBUS_FIRST_AND_LAST_FRAME_NO_PEC; + } + /* else if user set XferOptions to SMBUS_OTHER_AND_LAST_FRAME_WITH_PEC */ + /* it request implicitly to generate a restart condition */ + /* then generate a stop condition at the end of transfer */ + /* set XferOptions to SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC */ + else if (hsmbus->XferOptions == SMBUS_OTHER_AND_LAST_FRAME_WITH_PEC) + { + hsmbus->XferOptions = SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC; + } + else + { + /* Nothing to do */ + } +} +/** + * @} + */ + +#endif /* HAL_SMBUS_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_smbus_ex.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_smbus_ex.c new file mode 100644 index 0000000000..8d80b1fdae --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_smbus_ex.c @@ -0,0 +1,243 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_smbus_ex.c + * @author MCD Application Team + * @brief SMBUS Extended HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of SMBUS Extended peripheral: + * + Extended features functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### SMBUS peripheral Extended features ##### + ============================================================================== + + [..] Comparing to other previous devices, the SMBUS interface for STM32H5xx + devices contains the following additional features + + (+) Disable or enable wakeup from Stop mode(s) + + ##### How to use this driver ##### + ============================================================================== + (#) Configure the enable or disable of SMBUS Wake Up Mode using the functions : + (++) HAL_SMBUSEx_EnableWakeUp() + (++) HAL_SMBUSEx_DisableWakeUp() + (#) Configure the enable or disable of fast mode plus driving capability using the functions : + (++) HAL_SMBUSEx_ConfigFastModePlus() + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup SMBUSEx SMBUSEx + * @brief SMBUS Extended HAL module driver + * @{ + */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup SMBUSEx_Exported_Functions SMBUS Extended Exported Functions + * @{ + */ + +/** @defgroup SMBUSEx_Exported_Functions_Group2 WakeUp Mode Functions + * @brief WakeUp Mode Functions + * +@verbatim + =============================================================================== + ##### WakeUp Mode Functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure Wake Up Feature + +@endverbatim + * @{ + */ + +/** + * @brief Enable SMBUS wakeup from Stop mode(s). + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUSx peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMBUSEx_EnableWakeUp(SMBUS_HandleTypeDef *hsmbus) +{ + /* Check the parameters */ + assert_param(IS_I2C_WAKEUP_FROMSTOP_INSTANCE(hsmbus->Instance)); + + if (hsmbus->State == HAL_SMBUS_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsmbus); + + hsmbus->State = HAL_SMBUS_STATE_BUSY; + + /* Disable the selected SMBUS peripheral */ + __HAL_SMBUS_DISABLE(hsmbus); + + /* Enable wakeup from stop mode */ + hsmbus->Instance->CR1 |= I2C_CR1_WUPEN; + + __HAL_SMBUS_ENABLE(hsmbus); + + hsmbus->State = HAL_SMBUS_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Disable SMBUS wakeup from Stop mode(s). + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUSx peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMBUSEx_DisableWakeUp(SMBUS_HandleTypeDef *hsmbus) +{ + /* Check the parameters */ + assert_param(IS_I2C_WAKEUP_FROMSTOP_INSTANCE(hsmbus->Instance)); + + if (hsmbus->State == HAL_SMBUS_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsmbus); + + hsmbus->State = HAL_SMBUS_STATE_BUSY; + + /* Disable the selected SMBUS peripheral */ + __HAL_SMBUS_DISABLE(hsmbus); + + /* Disable wakeup from stop mode */ + hsmbus->Instance->CR1 &= ~(I2C_CR1_WUPEN); + + __HAL_SMBUS_ENABLE(hsmbus); + + hsmbus->State = HAL_SMBUS_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} +/** + * @} + */ + +/** @defgroup SMBUSEx_Exported_Functions_Group3 Fast Mode Plus Functions + * @brief Fast Mode Plus Functions + * +@verbatim + =============================================================================== + ##### Fast Mode Plus Functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure Fast Mode Plus + +@endverbatim + * @{ + */ + +/** + * @brief Configure SMBUS Fast Mode Plus. + * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains + * the configuration information for the specified SMBUSx peripheral. + * @param FastModePlus New state of the Fast Mode Plus. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMBUSEx_ConfigFastModePlus(SMBUS_HandleTypeDef *hsmbus, uint32_t FastModePlus) +{ + /* Check the parameters */ + assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance)); + assert_param(IS_SMBUS_FASTMODEPLUS(FastModePlus)); + + if (hsmbus->State == HAL_SMBUS_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsmbus); + + hsmbus->State = HAL_SMBUS_STATE_BUSY; + + /* Disable the selected SMBUS peripheral */ + __HAL_SMBUS_DISABLE(hsmbus); + + if (FastModePlus == SMBUS_FASTMODEPLUS_ENABLE) + { + /* Set SMBUSx FMP bit */ + hsmbus->Instance->CR1 |= (I2C_CR1_FMP); + } + else + { + /* Reset SMBUSx FMP bit */ + hsmbus->Instance->CR1 &= ~(I2C_CR1_FMP); + } + + __HAL_SMBUS_ENABLE(hsmbus); + + hsmbus->State = HAL_SMBUS_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsmbus); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_SMBUS_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_spi.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_spi.c new file mode 100644 index 0000000000..4f55e257cb --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_spi.c @@ -0,0 +1,3810 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_spi.c + * @author MCD Application Team + * @brief SPI HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Serial Peripheral Interface (SPI) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The SPI HAL driver can be used as follows: + + (#) Declare a SPI_HandleTypeDef handle structure, for example: + SPI_HandleTypeDef hspi; + + (#)Initialize the SPI low level resources by implementing the HAL_SPI_MspInit() API: + (##) Enable the SPIx interface clock + (##) SPI pins configuration + (+++) Enable the clock for the SPI GPIOs + (+++) Configure these SPI pins as alternate function push-pull + (##) NVIC configuration if you need to use interrupt process or DMA process + (+++) Configure the SPIx interrupt priority + (+++) Enable the NVIC SPI IRQ handle + (##) DMA Configuration if you need to use DMA process + (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive Stream/Channel + (+++) Enable the DMAx clock + (+++) Configure the DMA handle parameters + (+++) Configure the DMA Tx or Rx Stream/Channel + (+++) Associate the initialized hdma_tx handle to the hspi DMA Tx or Rx handle + (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx + or Rx Stream/Channel + + (#) Program the Mode, BidirectionalMode , Data size, Baudrate Prescaler, NSS + management, Clock polarity and phase, FirstBit and CRC configuration in the hspi Init structure. + + (#) Initialize the SPI registers by calling the HAL_SPI_Init() API: + (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc) + by calling the customized HAL_SPI_MspInit() API. + [..] + Callback registration: + + (#) The compilation flag USE_HAL_SPI_REGISTER_CALLBACKS when set to 1UL + allows the user to configure dynamically the driver callbacks. + Use Functions HAL_SPI_RegisterCallback() to register an interrupt callback. + + Function HAL_SPI_RegisterCallback() allows to register following callbacks: + (+) TxCpltCallback : SPI Tx Completed callback + (+) RxCpltCallback : SPI Rx Completed callback + (+) TxRxCpltCallback : SPI TxRx Completed callback + (+) TxHalfCpltCallback : SPI Tx Half Completed callback + (+) RxHalfCpltCallback : SPI Rx Half Completed callback + (+) TxRxHalfCpltCallback : SPI TxRx Half Completed callback + (+) ErrorCallback : SPI Error callback + (+) AbortCpltCallback : SPI Abort callback + (+) SuspendCallback : SPI Suspend callback + (+) MspInitCallback : SPI Msp Init callback + (+) MspDeInitCallback : SPI 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_SPI_UnRegisterCallback to reset a callback to the default + weak function. + HAL_SPI_UnRegisterCallback takes as parameters the HAL peripheral handle, + and the Callback ID. + This function allows to reset following callbacks: + (+) TxCpltCallback : SPI Tx Completed callback + (+) RxCpltCallback : SPI Rx Completed callback + (+) TxRxCpltCallback : SPI TxRx Completed callback + (+) TxHalfCpltCallback : SPI Tx Half Completed callback + (+) RxHalfCpltCallback : SPI Rx Half Completed callback + (+) TxRxHalfCpltCallback : SPI TxRx Half Completed callback + (+) ErrorCallback : SPI Error callback + (+) AbortCpltCallback : SPI Abort callback + (+) SuspendCallback : SPI Suspend callback + (+) MspInitCallback : SPI Msp Init callback + (+) MspDeInitCallback : SPI Msp DeInit callback + + By default, after the HAL_SPI_Init() and when the state is HAL_SPI_STATE_RESET + all callbacks are set to the corresponding weak functions: + examples HAL_SPI_MasterTxCpltCallback(), HAL_SPI_MasterRxCpltCallback(). + Exception done for MspInit and MspDeInit functions that are + reset to the legacy weak functions in the HAL_SPI_Init()/ HAL_SPI_DeInit() only when + these callbacks are null (not registered beforehand). + If MspInit or MspDeInit are not null, the HAL_SPI_Init()/ HAL_SPI_DeInit() + keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state. + + Callbacks can be registered/unregistered in HAL_SPI_STATE_READY state only. + Exception done MspInit/MspDeInit functions that can be registered/unregistered + in HAL_SPI_STATE_READY or HAL_SPI_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_SPI_RegisterCallback() before calling HAL_SPI_DeInit() + or HAL_SPI_Init() function. + + When The compilation define USE_HAL_PPP_REGISTER_CALLBACKS is set to 0 or + not defined, the callback registering feature is not available + and weak (surcharged) callbacks are used. + + SuspendCallback restriction: + SuspendCallback is called only when MasterReceiverAutoSusp is enabled and + EOT interrupt is activated. SuspendCallback is used in relation with functions + HAL_SPI_Transmit_IT, HAL_SPI_Receive_IT and HAL_SPI_TransmitReceive_IT. + + [..] + Circular mode restriction: + (+) The DMA circular mode cannot be used when the SPI is configured in these modes: + (++) Master 2Lines RxOnly + (++) Master 1Line Rx + (+) The CRC feature is not managed when the DMA circular mode is enabled + (+) The functions HAL_SPI_DMAPause()/ HAL_SPI_DMAResume() are not supported. Return always + HAL_ERROR with ErrorCode set to HAL_SPI_ERROR_NOT_SUPPORTED. + Those functions are maintained for backward compatibility reasons. + + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup SPI SPI + * @brief SPI HAL module driver + * @{ + */ +#ifdef HAL_SPI_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ +/** @defgroup SPI_Private_Constants SPI Private Constants + * @{ + */ +#define SPI_DEFAULT_TIMEOUT 100UL +#define MAX_FIFO_LENGTH 16UL +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup SPI_Private_Functions SPI Private Functions + * @{ + */ +#if defined(HAL_DMA_MODULE_ENABLED) +static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma); +static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma); +static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma); +static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma); +static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma); +static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma); +static void SPI_DMAError(DMA_HandleTypeDef *hdma); +static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma); +static void SPI_DMATxAbortCallback(DMA_HandleTypeDef *hdma); +static void SPI_DMARxAbortCallback(DMA_HandleTypeDef *hdma); +#endif /* HAL_DMA_MODULE_ENABLED */ +static HAL_StatusTypeDef SPI_WaitOnFlagUntilTimeout(const SPI_HandleTypeDef *hspi, uint32_t Flag, + FlagStatus FlagStatus, uint32_t Timeout, uint32_t Tickstart); +static void SPI_TxISR_8BIT(SPI_HandleTypeDef *hspi); +static void SPI_TxISR_16BIT(SPI_HandleTypeDef *hspi); +static void SPI_TxISR_32BIT(SPI_HandleTypeDef *hspi); +static void SPI_RxISR_8BIT(SPI_HandleTypeDef *hspi); +static void SPI_RxISR_16BIT(SPI_HandleTypeDef *hspi); +static void SPI_RxISR_32BIT(SPI_HandleTypeDef *hspi); +static void SPI_AbortTransfer(SPI_HandleTypeDef *hspi); +static void SPI_CloseTransfer(SPI_HandleTypeDef *hspi); +static uint32_t SPI_GetPacketSize(const SPI_HandleTypeDef *hspi); + + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup SPI_Exported_Functions SPI Exported Functions + * @{ + */ + +/** @defgroup SPI_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + de-initialize the SPIx peripheral: + + (+) User must implement HAL_SPI_MspInit() function in which he configures + all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ). + + (+) Call the function HAL_SPI_Init() to configure the selected device with + the selected configuration: + (++) Mode + (++) Direction + (++) Data Size + (++) Clock Polarity and Phase + (++) NSS Management + (++) BaudRate Prescaler + (++) FirstBit + (++) TIMode + (++) CRC Calculation + (++) CRC Polynomial if CRC enabled + (++) CRC Length, used only with Data8 and Data16 + (++) FIFO reception threshold + (++) FIFO transmission threshold + + (+) Call the function HAL_SPI_DeInit() to restore the default configuration + of the selected SPIx peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the SPI according to the specified parameters + * in the SPI_InitTypeDef and initialize the associated handle. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi) +{ + uint32_t crc_length; + uint32_t packet_length; + + /* Check the SPI handle allocation */ + if (hspi == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance)); + assert_param(IS_SPI_MODE(hspi->Init.Mode)); + assert_param(IS_SPI_DIRECTION(hspi->Init.Direction)); + if (IS_SPI_LIMITED_INSTANCE(hspi->Instance)) + { + assert_param(IS_SPI_LIMITED_DATASIZE(hspi->Init.DataSize)); + assert_param(IS_SPI_LIMITED_FIFOTHRESHOLD(hspi->Init.FifoThreshold)); + } + else + { + assert_param(IS_SPI_DATASIZE(hspi->Init.DataSize)); + assert_param(IS_SPI_FIFOTHRESHOLD(hspi->Init.FifoThreshold)); + } + assert_param(IS_SPI_NSS(hspi->Init.NSS)); + assert_param(IS_SPI_NSSP(hspi->Init.NSSPMode)); + assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler)); + assert_param(IS_SPI_FIRST_BIT(hspi->Init.FirstBit)); + assert_param(IS_SPI_TIMODE(hspi->Init.TIMode)); + if (hspi->Init.TIMode == SPI_TIMODE_DISABLE) + { + assert_param(IS_SPI_CPOL(hspi->Init.CLKPolarity)); + assert_param(IS_SPI_CPHA(hspi->Init.CLKPhase)); + } +#if (USE_SPI_CRC != 0UL) + assert_param(IS_SPI_CRC_CALCULATION(hspi->Init.CRCCalculation)); + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + if (IS_SPI_LIMITED_INSTANCE(hspi->Instance)) + { + assert_param(IS_SPI_LIMITED_CRC_LENGTH(hspi->Init.CRCLength)); + } + else + { + assert_param(IS_SPI_CRC_LENGTH(hspi->Init.CRCLength)); + } + assert_param(IS_SPI_CRC_POLYNOMIAL(hspi->Init.CRCPolynomial)); + assert_param(IS_SPI_CRC_INITIALIZATION_PATTERN(hspi->Init.TxCRCInitializationPattern)); + assert_param(IS_SPI_CRC_INITIALIZATION_PATTERN(hspi->Init.RxCRCInitializationPattern)); + } +#else + hspi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; +#endif /* USE_SPI_CRC */ + + assert_param(IS_SPI_RDY_MASTER_MANAGEMENT(hspi->Init.ReadyMasterManagement)); + assert_param(IS_SPI_RDY_POLARITY(hspi->Init.ReadyPolarity)); + assert_param(IS_SPI_MASTER_RX_AUTOSUSP(hspi->Init.MasterReceiverAutoSusp)); + + /* Verify that the SPI instance supports Data Size higher than 16bits */ + if ((IS_SPI_LIMITED_INSTANCE(hspi->Instance)) && (hspi->Init.DataSize > SPI_DATASIZE_16BIT)) + { + return HAL_ERROR; + } + + /* Verify that the SPI instance supports requested data packing */ + packet_length = SPI_GetPacketSize(hspi); + if (((IS_SPI_LIMITED_INSTANCE(hspi->Instance)) && (packet_length > SPI_LOWEND_FIFO_SIZE)) || + ((IS_SPI_FULL_INSTANCE(hspi->Instance)) && (packet_length > SPI_HIGHEND_FIFO_SIZE))) + { + return HAL_ERROR; + } +#if (USE_SPI_CRC != 0UL) + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + /* Verify that the SPI instance supports CRC Length higher than 16bits */ + if ((IS_SPI_LIMITED_INSTANCE(hspi->Instance)) && (hspi->Init.CRCLength > SPI_CRC_LENGTH_16BIT)) + { + return HAL_ERROR; + } + + /* Align the CRC Length on the data size */ + if (hspi->Init.CRCLength == SPI_CRC_LENGTH_DATASIZE) + { + crc_length = (hspi->Init.DataSize >> SPI_CFG1_DSIZE_Pos) << SPI_CFG1_CRCSIZE_Pos; + } + else + { + crc_length = hspi->Init.CRCLength; + } + + /* Verify that the CRC Length is higher than DataSize */ + if ((hspi->Init.DataSize >> SPI_CFG1_DSIZE_Pos) > (crc_length >> SPI_CFG1_CRCSIZE_Pos)) + { + return HAL_ERROR; + } + } + else + { + crc_length = hspi->Init.DataSize << SPI_CFG1_CRCSIZE_Pos; + } +#endif /* USE_SPI_CRC */ + + if (hspi->State == HAL_SPI_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hspi->Lock = HAL_UNLOCKED; + +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) + /* Init the SPI Callback settings */ + hspi->TxCpltCallback = HAL_SPI_TxCpltCallback; /* Legacy weak TxCpltCallback */ + hspi->RxCpltCallback = HAL_SPI_RxCpltCallback; /* Legacy weak RxCpltCallback */ + hspi->TxRxCpltCallback = HAL_SPI_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */ + hspi->TxHalfCpltCallback = HAL_SPI_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */ + hspi->RxHalfCpltCallback = HAL_SPI_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */ + hspi->TxRxHalfCpltCallback = HAL_SPI_TxRxHalfCpltCallback; /* Legacy weak TxRxHalfCpltCallback */ + hspi->ErrorCallback = HAL_SPI_ErrorCallback; /* Legacy weak ErrorCallback */ + hspi->AbortCpltCallback = HAL_SPI_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ + hspi->SuspendCallback = HAL_SPI_SuspendCallback; /* Legacy weak SuspendCallback */ + + if (hspi->MspInitCallback == NULL) + { + hspi->MspInitCallback = HAL_SPI_MspInit; /* Legacy weak MspInit */ + } + + /* Init the low level hardware : GPIO, CLOCK, NVIC... */ + hspi->MspInitCallback(hspi); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC... */ + HAL_SPI_MspInit(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + } + + hspi->State = HAL_SPI_STATE_BUSY; + + /* Disable the selected SPI peripheral */ + __HAL_SPI_DISABLE(hspi); + +#if (USE_SPI_CRC == 0) + /* Keep the default value of CRCSIZE in case of CRC is not used */ + crc_length = hspi->Instance->CFG1 & SPI_CFG1_CRCSIZE; +#endif /* USE_SPI_CRC */ + + /*----------------------- SPIx CR1 & CR2 Configuration ---------------------*/ + /* Configure : SPI Mode, Communication Mode, Clock polarity and phase, NSS management, + Communication speed, First bit, CRC calculation state, CRC Length */ + + /* SPIx NSS Software Management Configuration */ + if ((hspi->Init.NSS == SPI_NSS_SOFT) && (((hspi->Init.Mode == SPI_MODE_MASTER) && \ + (hspi->Init.NSSPolarity == SPI_NSS_POLARITY_LOW)) || \ + ((hspi->Init.Mode == SPI_MODE_SLAVE) && \ + (hspi->Init.NSSPolarity == SPI_NSS_POLARITY_HIGH)))) + { + SET_BIT(hspi->Instance->CR1, SPI_CR1_SSI); + } + + /* SPIx Master Rx Auto Suspend Configuration */ + if (((hspi->Init.Mode & SPI_MODE_MASTER) == SPI_MODE_MASTER) && (hspi->Init.DataSize >= SPI_DATASIZE_8BIT)) + { + MODIFY_REG(hspi->Instance->CR1, SPI_CR1_MASRX, hspi->Init.MasterReceiverAutoSusp); + } + else + { + CLEAR_BIT(hspi->Instance->CR1, SPI_CR1_MASRX); + } + + /* SPIx CFG1 Configuration */ + WRITE_REG(hspi->Instance->CFG1, (hspi->Init.BaudRatePrescaler | hspi->Init.CRCCalculation | crc_length | + hspi->Init.FifoThreshold | hspi->Init.DataSize)); + + /* SPIx CFG2 Configuration */ + WRITE_REG(hspi->Instance->CFG2, (hspi->Init.NSSPMode | hspi->Init.TIMode | + hspi->Init.NSSPolarity | hspi->Init.NSS | + hspi->Init.CLKPolarity | hspi->Init.CLKPhase | + hspi->Init.FirstBit | hspi->Init.Mode | + hspi->Init.MasterInterDataIdleness | hspi->Init.Direction | + hspi->Init.MasterSSIdleness | hspi->Init.IOSwap | + hspi->Init.ReadyMasterManagement | hspi->Init.ReadyPolarity)); + +#if (USE_SPI_CRC != 0UL) + /*---------------------------- SPIx CRCPOLY Configuration ------------------*/ + /* Configure : CRC Polynomial */ + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + /* Initialize TXCRC Pattern Initial Value */ + if (hspi->Init.TxCRCInitializationPattern == SPI_CRC_INITIALIZATION_ALL_ONE_PATTERN) + { + SET_BIT(hspi->Instance->CR1, SPI_CR1_TCRCINI); + } + else + { + CLEAR_BIT(hspi->Instance->CR1, SPI_CR1_TCRCINI); + } + + /* Initialize RXCRC Pattern Initial Value */ + if (hspi->Init.RxCRCInitializationPattern == SPI_CRC_INITIALIZATION_ALL_ONE_PATTERN) + { + SET_BIT(hspi->Instance->CR1, SPI_CR1_RCRCINI); + } + else + { + CLEAR_BIT(hspi->Instance->CR1, SPI_CR1_RCRCINI); + } + + /* Enable 33/17 bits CRC computation */ + if (((IS_SPI_LIMITED_INSTANCE(hspi->Instance)) && (crc_length == SPI_CRC_LENGTH_16BIT)) || + ((IS_SPI_FULL_INSTANCE(hspi->Instance)) && (crc_length == SPI_CRC_LENGTH_32BIT))) + { + SET_BIT(hspi->Instance->CR1, SPI_CR1_CRC33_17); + } + else + { + CLEAR_BIT(hspi->Instance->CR1, SPI_CR1_CRC33_17); + } + + /* Write CRC polynomial in SPI Register */ + WRITE_REG(hspi->Instance->CRCPOLY, hspi->Init.CRCPolynomial); + } +#endif /* USE_SPI_CRC */ + + /* Insure that Underrun configuration is managed only by Salve */ + if (hspi->Init.Mode == SPI_MODE_SLAVE) + { +#if (USE_SPI_CRC != 0UL) + MODIFY_REG(hspi->Instance->CFG1, SPI_CFG1_UDRCFG, SPI_CFG1_UDRCFG); +#endif /* USE_SPI_CRC */ + } + +#if defined(SPI_I2SCFGR_I2SMOD) + /* Activate the SPI mode (Make sure that I2SMOD bit in I2SCFGR register is reset) */ + CLEAR_BIT(hspi->Instance->I2SCFGR, SPI_I2SCFGR_I2SMOD); +#endif /* SPI_I2SCFGR_I2SMOD */ + + /* Insure that AFCNTR is managed only by Master */ + if ((hspi->Init.Mode & SPI_MODE_MASTER) == SPI_MODE_MASTER) + { + /* Alternate function GPIOs control */ + MODIFY_REG(hspi->Instance->CFG2, SPI_CFG2_AFCNTR, (hspi->Init.MasterKeepIOState)); + } + + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->State = HAL_SPI_STATE_READY; + + return HAL_OK; +} + +/** + * @brief De-Initialize the SPI peripheral. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_DeInit(SPI_HandleTypeDef *hspi) +{ + /* Check the SPI handle allocation */ + if (hspi == NULL) + { + return HAL_ERROR; + } + + /* Check SPI Instance parameter */ + assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance)); + + hspi->State = HAL_SPI_STATE_BUSY; + + /* Disable the SPI Peripheral Clock */ + __HAL_SPI_DISABLE(hspi); + +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) + if (hspi->MspDeInitCallback == NULL) + { + hspi->MspDeInitCallback = HAL_SPI_MspDeInit; /* Legacy weak MspDeInit */ + } + + /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */ + hspi->MspDeInitCallback(hspi); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */ + HAL_SPI_MspDeInit(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->State = HAL_SPI_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hspi); + + return HAL_OK; +} + +/** + * @brief Initialize the SPI MSP. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +__weak void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hspi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SPI_MspInit should be implemented in the user file + */ +} + +/** + * @brief De-Initialize the SPI MSP. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +__weak void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hspi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SPI_MspDeInit should be implemented in the user file + */ +} + +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) +/** + * @brief Register a User SPI Callback + * To be used instead of the weak predefined callback + * @param hspi Pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for the specified SPI. + * @param CallbackID ID of the callback to be registered + * @param pCallback pointer to the Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_RegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID, + pSPI_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hspi->ErrorCode |= HAL_SPI_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + /* Lock the process */ + __HAL_LOCK(hspi); + + if (HAL_SPI_STATE_READY == hspi->State) + { + switch (CallbackID) + { + case HAL_SPI_TX_COMPLETE_CB_ID : + hspi->TxCpltCallback = pCallback; + break; + + case HAL_SPI_RX_COMPLETE_CB_ID : + hspi->RxCpltCallback = pCallback; + break; + + case HAL_SPI_TX_RX_COMPLETE_CB_ID : + hspi->TxRxCpltCallback = pCallback; + break; + + case HAL_SPI_TX_HALF_COMPLETE_CB_ID : + hspi->TxHalfCpltCallback = pCallback; + break; + + case HAL_SPI_RX_HALF_COMPLETE_CB_ID : + hspi->RxHalfCpltCallback = pCallback; + break; + + case HAL_SPI_TX_RX_HALF_COMPLETE_CB_ID : + hspi->TxRxHalfCpltCallback = pCallback; + break; + + case HAL_SPI_ERROR_CB_ID : + hspi->ErrorCallback = pCallback; + break; + + case HAL_SPI_ABORT_CB_ID : + hspi->AbortCpltCallback = pCallback; + break; + + case HAL_SPI_SUSPEND_CB_ID : + hspi->SuspendCallback = pCallback; + break; + + case HAL_SPI_MSPINIT_CB_ID : + hspi->MspInitCallback = pCallback; + break; + + case HAL_SPI_MSPDEINIT_CB_ID : + hspi->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_SPI_STATE_RESET == hspi->State) + { + switch (CallbackID) + { + case HAL_SPI_MSPINIT_CB_ID : + hspi->MspInitCallback = pCallback; + break; + + case HAL_SPI_MSPDEINIT_CB_ID : + hspi->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hspi); + return status; +} + +/** + * @brief Unregister an SPI Callback + * SPI callback is redirected to the weak predefined callback + * @param hspi Pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for the specified SPI. + * @param CallbackID ID of the callback to be unregistered + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_UnRegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Lock the process */ + __HAL_LOCK(hspi); + + if (HAL_SPI_STATE_READY == hspi->State) + { + switch (CallbackID) + { + case HAL_SPI_TX_COMPLETE_CB_ID : + hspi->TxCpltCallback = HAL_SPI_TxCpltCallback; /* Legacy weak TxCpltCallback */ + break; + + case HAL_SPI_RX_COMPLETE_CB_ID : + hspi->RxCpltCallback = HAL_SPI_RxCpltCallback; /* Legacy weak RxCpltCallback */ + break; + + case HAL_SPI_TX_RX_COMPLETE_CB_ID : + hspi->TxRxCpltCallback = HAL_SPI_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */ + break; + + case HAL_SPI_TX_HALF_COMPLETE_CB_ID : + hspi->TxHalfCpltCallback = HAL_SPI_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */ + break; + + case HAL_SPI_RX_HALF_COMPLETE_CB_ID : + hspi->RxHalfCpltCallback = HAL_SPI_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */ + break; + + case HAL_SPI_TX_RX_HALF_COMPLETE_CB_ID : + hspi->TxRxHalfCpltCallback = HAL_SPI_TxRxHalfCpltCallback; /* Legacy weak TxRxHalfCpltCallback */ + break; + + case HAL_SPI_ERROR_CB_ID : + hspi->ErrorCallback = HAL_SPI_ErrorCallback; /* Legacy weak ErrorCallback */ + break; + + case HAL_SPI_ABORT_CB_ID : + hspi->AbortCpltCallback = HAL_SPI_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ + break; + + case HAL_SPI_SUSPEND_CB_ID : + hspi->SuspendCallback = HAL_SPI_SuspendCallback; /* Legacy weak SuspendCallback */ + break; + + case HAL_SPI_MSPINIT_CB_ID : + hspi->MspInitCallback = HAL_SPI_MspInit; /* Legacy weak MspInit */ + break; + + case HAL_SPI_MSPDEINIT_CB_ID : + hspi->MspDeInitCallback = HAL_SPI_MspDeInit; /* Legacy weak MspDeInit */ + break; + + default : + /* Update the error code */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_SPI_STATE_RESET == hspi->State) + { + switch (CallbackID) + { + case HAL_SPI_MSPINIT_CB_ID : + hspi->MspInitCallback = HAL_SPI_MspInit; /* Legacy weak MspInit */ + break; + + case HAL_SPI_MSPDEINIT_CB_ID : + hspi->MspDeInitCallback = HAL_SPI_MspDeInit; /* Legacy weak MspDeInit */ + break; + + default : + /* Update the error code */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hspi); + return status; +} +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @defgroup SPI_Exported_Functions_Group2 IO operation functions + * @brief Data transfers functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the SPI + data transfers. + + [..] The SPI supports master and slave mode : + + (#) There are two modes of transfer: + (##) Blocking mode: The communication is performed in polling mode. + The HAL status of all data processing is returned by the same function + after finishing transfer. + (##) No-Blocking mode: The communication is performed using Interrupts + or DMA, These APIs return the HAL status. + The end of the data processing will be indicated through the + dedicated SPI IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + The HAL_SPI_TxCpltCallback(), HAL_SPI_RxCpltCallback() and HAL_SPI_TxRxCpltCallback() user callbacks + will be executed respectively at the end of the transmit or Receive process + The HAL_SPI_ErrorCallback()user callback will be executed when a communication error is detected + + (#) APIs provided for these 2 transfer modes (Blocking mode or Non blocking mode using either Interrupt or DMA) + exist for 1Line (simplex) and 2Lines (full duplex) modes. + +@endverbatim + * @{ + */ + +/** + * @brief Transmit an amount of data in blocking mode. + * @param hspi : pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param pData : pointer to data buffer + * @param Size : amount of data to be sent + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ +#if defined (__GNUC__) + __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->TXDR)); +#endif /* __GNUC__ */ + + uint32_t tickstart; + HAL_StatusTypeDef errorcode = HAL_OK; + + /* Check Direction parameter */ + assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_TXONLY(hspi->Init.Direction)); + + /* Lock the process */ + __HAL_LOCK(hspi); + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + if (hspi->State != HAL_SPI_STATE_READY) + { + errorcode = HAL_BUSY; + __HAL_UNLOCK(hspi); + return errorcode; + } + + if ((pData == NULL) || (Size == 0UL)) + { + errorcode = HAL_ERROR; + __HAL_UNLOCK(hspi); + return errorcode; + } + + /* Set the transaction information */ + hspi->State = HAL_SPI_STATE_BUSY_TX; + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->pTxBuffPtr = (const uint8_t *)pData; + hspi->TxXferSize = Size; + hspi->TxXferCount = Size; + + /*Init field not used in handle to zero */ + hspi->pRxBuffPtr = NULL; + hspi->RxXferSize = (uint16_t) 0UL; + hspi->RxXferCount = (uint16_t) 0UL; + hspi->TxISR = NULL; + hspi->RxISR = NULL; + + /* Configure communication direction : 1Line */ + if (hspi->Init.Direction == SPI_DIRECTION_1LINE) + { + SPI_1LINE_TX(hspi); + } + else + { + SPI_2LINES_TX(hspi); + } + + /* Set the number of data at current transfer */ + MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size); + + /* Enable SPI peripheral */ + __HAL_SPI_ENABLE(hspi); + + if (hspi->Init.Mode == SPI_MODE_MASTER) + { + /* Master transfer start */ + SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART); + } + + /* Transmit data in 32 Bit mode */ + if ((hspi->Init.DataSize > SPI_DATASIZE_16BIT) && (IS_SPI_FULL_INSTANCE(hspi->Instance))) + { + /* Transmit data in 32 Bit mode */ + while (hspi->TxXferCount > 0UL) + { + /* Wait until TXP flag is set to send data */ + if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP)) + { + *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr); + hspi->pTxBuffPtr += sizeof(uint32_t); + hspi->TxXferCount--; + } + else + { + /* Timeout management */ + if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U)) + { + /* Call standard close procedure with error check */ + SPI_CloseTransfer(hspi); + + /* Unlock the process */ + __HAL_UNLOCK(hspi); + + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT); + hspi->State = HAL_SPI_STATE_READY; + return HAL_TIMEOUT; + } + } + } + } + /* Transmit data in 16 Bit mode */ + else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + { + /* Transmit data in 16 Bit mode */ + while (hspi->TxXferCount > 0UL) + { + /* Wait until TXP flag is set to send data */ + if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP)) + { + if ((hspi->TxXferCount > 1UL) && (hspi->Init.FifoThreshold > SPI_FIFO_THRESHOLD_01DATA)) + { + *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr); + hspi->pTxBuffPtr += sizeof(uint32_t); + hspi->TxXferCount -= (uint16_t)2UL; + } + else + { +#if defined (__GNUC__) + *ptxdr_16bits = *((const uint16_t *)hspi->pTxBuffPtr); +#else + *((__IO uint16_t *)&hspi->Instance->TXDR) = *((const uint16_t *)hspi->pTxBuffPtr); +#endif /* __GNUC__ */ + hspi->pTxBuffPtr += sizeof(uint16_t); + hspi->TxXferCount--; + } + } + else + { + /* Timeout management */ + if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U)) + { + /* Call standard close procedure with error check */ + SPI_CloseTransfer(hspi); + + /* Unlock the process */ + __HAL_UNLOCK(hspi); + + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT); + hspi->State = HAL_SPI_STATE_READY; + return HAL_TIMEOUT; + } + } + } + } + /* Transmit data in 8 Bit mode */ + else + { + while (hspi->TxXferCount > 0UL) + { + /* Wait until TXP flag is set to send data */ + if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP)) + { + if ((hspi->TxXferCount > 3UL) && (hspi->Init.FifoThreshold > SPI_FIFO_THRESHOLD_03DATA)) + { + *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr); + hspi->pTxBuffPtr += sizeof(uint32_t); + hspi->TxXferCount -= (uint16_t)4UL; + } + else if ((hspi->TxXferCount > 1UL) && (hspi->Init.FifoThreshold > SPI_FIFO_THRESHOLD_01DATA)) + { +#if defined (__GNUC__) + *ptxdr_16bits = *((const uint16_t *)hspi->pTxBuffPtr); +#else + *((__IO uint16_t *)&hspi->Instance->TXDR) = *((const uint16_t *)hspi->pTxBuffPtr); +#endif /* __GNUC__ */ + hspi->pTxBuffPtr += sizeof(uint16_t); + hspi->TxXferCount -= (uint16_t)2UL; + } + else + { + *((__IO uint8_t *)&hspi->Instance->TXDR) = *((const uint8_t *)hspi->pTxBuffPtr); + hspi->pTxBuffPtr += sizeof(uint8_t); + hspi->TxXferCount--; + } + } + else + { + /* Timeout management */ + if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U)) + { + /* Call standard close procedure with error check */ + SPI_CloseTransfer(hspi); + + /* Unlock the process */ + __HAL_UNLOCK(hspi); + + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT); + hspi->State = HAL_SPI_STATE_READY; + return HAL_TIMEOUT; + } + } + } + } + + /* Wait for Tx (and CRC) data to be sent */ + if (SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_EOT, RESET, Timeout, tickstart) != HAL_OK) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); + } + + /* Call standard close procedure with error check */ + SPI_CloseTransfer(hspi); + + /* Unlock the process */ + __HAL_UNLOCK(hspi); + + hspi->State = HAL_SPI_STATE_READY; + + if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) + { + return HAL_ERROR; + } + return errorcode; +} + +/** + * @brief Receive an amount of data in blocking mode. + * @param hspi : pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param pData : pointer to data buffer + * @param Size : amount of data to be received + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart; + HAL_StatusTypeDef errorcode = HAL_OK; +#if defined (__GNUC__) + __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->RXDR)); +#endif /* __GNUC__ */ + + /* Check Direction parameter */ + assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_RXONLY(hspi->Init.Direction)); + + /* Lock the process */ + __HAL_LOCK(hspi); + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + if (hspi->State != HAL_SPI_STATE_READY) + { + errorcode = HAL_BUSY; + __HAL_UNLOCK(hspi); + return errorcode; + } + + if ((pData == NULL) || (Size == 0UL)) + { + errorcode = HAL_ERROR; + __HAL_UNLOCK(hspi); + return errorcode; + } + + /* Set the transaction information */ + hspi->State = HAL_SPI_STATE_BUSY_RX; + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->pRxBuffPtr = (uint8_t *)pData; + hspi->RxXferSize = Size; + hspi->RxXferCount = Size; + + /*Init field not used in handle to zero */ + hspi->pTxBuffPtr = NULL; + hspi->TxXferSize = (uint16_t) 0UL; + hspi->TxXferCount = (uint16_t) 0UL; + hspi->RxISR = NULL; + hspi->TxISR = NULL; + + /* Configure communication direction: 1Line */ + if (hspi->Init.Direction == SPI_DIRECTION_1LINE) + { + SPI_1LINE_RX(hspi); + } + else + { + SPI_2LINES_RX(hspi); + } + + /* Set the number of data at current transfer */ + MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size); + + /* Enable SPI peripheral */ + __HAL_SPI_ENABLE(hspi); + + if (hspi->Init.Mode == SPI_MODE_MASTER) + { + /* Master transfer start */ + SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART); + } + + /* Receive data in 32 Bit mode */ + if ((hspi->Init.DataSize > SPI_DATASIZE_16BIT) && (IS_SPI_FULL_INSTANCE(hspi->Instance))) + { + /* Transfer loop */ + while (hspi->RxXferCount > 0UL) + { + /* Check the RXWNE/EOT flag */ + if ((hspi->Instance->SR & (SPI_FLAG_RXWNE | SPI_FLAG_EOT)) != 0UL) + { + *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR); + hspi->pRxBuffPtr += sizeof(uint32_t); + hspi->RxXferCount--; + } + else + { + /* Timeout management */ + if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U)) + { + /* Call standard close procedure with error check */ + SPI_CloseTransfer(hspi); + + /* Unlock the process */ + __HAL_UNLOCK(hspi); + + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT); + hspi->State = HAL_SPI_STATE_READY; + return HAL_TIMEOUT; + } + } + } + } + /* Receive data in 16 Bit mode */ + else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + { + /* Transfer loop */ + while (hspi->RxXferCount > 0UL) + { + /* Check the RXP flag */ + if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP)) + { +#if defined (__GNUC__) + *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits; +#else + *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR); +#endif /* __GNUC__ */ + hspi->pRxBuffPtr += sizeof(uint16_t); + hspi->RxXferCount--; + } + else + { + /* Timeout management */ + if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U)) + { + /* Call standard close procedure with error check */ + SPI_CloseTransfer(hspi); + + /* Unlock the process */ + __HAL_UNLOCK(hspi); + + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT); + hspi->State = HAL_SPI_STATE_READY; + return HAL_TIMEOUT; + } + } + } + } + /* Receive data in 8 Bit mode */ + else + { + /* Transfer loop */ + while (hspi->RxXferCount > 0UL) + { + /* Check the RXP flag */ + if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP)) + { + *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR); + hspi->pRxBuffPtr += sizeof(uint8_t); + hspi->RxXferCount--; + } + else + { + /* Timeout management */ + if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U)) + { + /* Call standard close procedure with error check */ + SPI_CloseTransfer(hspi); + + /* Unlock the process */ + __HAL_UNLOCK(hspi); + + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT); + hspi->State = HAL_SPI_STATE_READY; + return HAL_TIMEOUT; + } + } + } + } + +#if (USE_SPI_CRC != 0UL) + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + /* Wait for crc data to be received */ + if (SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_EOT, RESET, Timeout, tickstart) != HAL_OK) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); + } + } +#endif /* USE_SPI_CRC */ + + /* Call standard close procedure with error check */ + SPI_CloseTransfer(hspi); + + /* Unlock the process */ + __HAL_UNLOCK(hspi); + + hspi->State = HAL_SPI_STATE_READY; + + if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) + { + return HAL_ERROR; + } + return errorcode; +} + +/** + * @brief Transmit and Receive an amount of data in blocking mode. + * @param hspi : pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param pTxData: pointer to transmission data buffer + * @param pRxData: pointer to reception data buffer + * @param Size : amount of data to be sent and received + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData, + uint16_t Size, uint32_t Timeout) +{ + HAL_StatusTypeDef errorcode = HAL_OK; +#if defined (__GNUC__) + __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->TXDR)); + __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->RXDR)); +#endif /* __GNUC__ */ + + uint32_t tickstart; + uint16_t initial_TxXferCount; + uint16_t initial_RxXferCount; + + /* Check Direction parameter */ + assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction)); + + /* Lock the process */ + __HAL_LOCK(hspi); + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + initial_TxXferCount = Size; + initial_RxXferCount = Size; + + if (hspi->State != HAL_SPI_STATE_READY) + { + errorcode = HAL_BUSY; + __HAL_UNLOCK(hspi); + return errorcode; + } + + if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0UL)) + { + errorcode = HAL_ERROR; + __HAL_UNLOCK(hspi); + return errorcode; + } + + /* Set the transaction information */ + hspi->State = HAL_SPI_STATE_BUSY_TX_RX; + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->pRxBuffPtr = (uint8_t *)pRxData; + hspi->RxXferCount = Size; + hspi->RxXferSize = Size; + hspi->pTxBuffPtr = (const uint8_t *)pTxData; + hspi->TxXferCount = Size; + hspi->TxXferSize = Size; + + /*Init field not used in handle to zero */ + hspi->RxISR = NULL; + hspi->TxISR = NULL; + + /* Set Full-Duplex mode */ + SPI_2LINES(hspi); + + /* Set the number of data at current transfer */ + MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size); + + __HAL_SPI_ENABLE(hspi); + + if (hspi->Init.Mode == SPI_MODE_MASTER) + { + /* Master transfer start */ + SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART); + } + + /* Transmit and Receive data in 32 Bit mode */ + if ((hspi->Init.DataSize > SPI_DATASIZE_16BIT) && (IS_SPI_FULL_INSTANCE(hspi->Instance))) + { + while ((initial_TxXferCount > 0UL) || (initial_RxXferCount > 0UL)) + { + /* Check TXP flag */ + if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP)) && (initial_TxXferCount > 0UL)) + { + *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr); + hspi->pTxBuffPtr += sizeof(uint32_t); + hspi->TxXferCount --; + initial_TxXferCount = hspi->TxXferCount; + } + + /* Check RXWNE/EOT flag */ + if (((hspi->Instance->SR & (SPI_FLAG_RXWNE | SPI_FLAG_EOT)) != 0UL) && (initial_RxXferCount > 0UL)) + { + *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR); + hspi->pRxBuffPtr += sizeof(uint32_t); + hspi->RxXferCount --; + initial_RxXferCount = hspi->RxXferCount; + } + + /* Timeout management */ + if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U)) + { + /* Call standard close procedure with error check */ + SPI_CloseTransfer(hspi); + + /* Unlock the process */ + __HAL_UNLOCK(hspi); + + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT); + hspi->State = HAL_SPI_STATE_READY; + return HAL_TIMEOUT; + } + } + } + /* Transmit and Receive data in 16 Bit mode */ + else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + { + while ((initial_TxXferCount > 0UL) || (initial_RxXferCount > 0UL)) + { + /* Check the TXP flag */ + if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP) && (initial_TxXferCount > 0UL)) + { +#if defined (__GNUC__) + *ptxdr_16bits = *((const uint16_t *)hspi->pTxBuffPtr); +#else + *((__IO uint16_t *)&hspi->Instance->TXDR) = *((const uint16_t *)hspi->pTxBuffPtr); +#endif /* __GNUC__ */ + hspi->pTxBuffPtr += sizeof(uint16_t); + hspi->TxXferCount--; + initial_TxXferCount = hspi->TxXferCount; + } + + /* Check the RXP flag */ + if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP)) && (initial_RxXferCount > 0UL)) + { +#if defined (__GNUC__) + *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits; +#else + *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR); +#endif /* __GNUC__ */ + hspi->pRxBuffPtr += sizeof(uint16_t); + hspi->RxXferCount--; + initial_RxXferCount = hspi->RxXferCount; + } + + /* Timeout management */ + if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U)) + { + /* Call standard close procedure with error check */ + SPI_CloseTransfer(hspi); + + /* Unlock the process */ + __HAL_UNLOCK(hspi); + + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT); + hspi->State = HAL_SPI_STATE_READY; + return HAL_TIMEOUT; + } + } + } + /* Transmit and Receive data in 8 Bit mode */ + else + { + while ((initial_TxXferCount > 0UL) || (initial_RxXferCount > 0UL)) + { + /* Check the TXP flag */ + if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP)) && (initial_TxXferCount > 0UL)) + { + *((__IO uint8_t *)&hspi->Instance->TXDR) = *((const uint8_t *)hspi->pTxBuffPtr); + hspi->pTxBuffPtr += sizeof(uint8_t); + hspi->TxXferCount--; + initial_TxXferCount = hspi->TxXferCount; + } + + /* Check the RXP flag */ + if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP)) && (initial_RxXferCount > 0UL)) + { + *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR); + hspi->pRxBuffPtr += sizeof(uint8_t); + hspi->RxXferCount--; + initial_RxXferCount = hspi->RxXferCount; + } + + /* Timeout management */ + if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U)) + { + /* Call standard close procedure with error check */ + SPI_CloseTransfer(hspi); + + /* Unlock the process */ + __HAL_UNLOCK(hspi); + + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT); + hspi->State = HAL_SPI_STATE_READY; + return HAL_TIMEOUT; + } + } + } + + /* Wait for Tx/Rx (and CRC) data to be sent/received */ + if (SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_EOT, RESET, Timeout, tickstart) != HAL_OK) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); + } + + /* Call standard close procedure with error check */ + SPI_CloseTransfer(hspi); + + /* Unlock the process */ + __HAL_UNLOCK(hspi); + + hspi->State = HAL_SPI_STATE_READY; + + if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) + { + return HAL_ERROR; + } + return errorcode; +} + +/** + * @brief Transmit an amount of data in non-blocking mode with Interrupt. + * @param hspi : pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param pData: pointer to data buffer + * @param Size : amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size) +{ + HAL_StatusTypeDef errorcode = HAL_OK; + + /* Check Direction parameter */ + assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_TXONLY(hspi->Init.Direction)); + + /* Lock the process */ + __HAL_LOCK(hspi); + + if ((pData == NULL) || (Size == 0UL)) + { + errorcode = HAL_ERROR; + __HAL_UNLOCK(hspi); + return errorcode; + } + + if (hspi->State != HAL_SPI_STATE_READY) + { + errorcode = HAL_BUSY; + __HAL_UNLOCK(hspi); + return errorcode; + } + + /* Set the transaction information */ + hspi->State = HAL_SPI_STATE_BUSY_TX; + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->pTxBuffPtr = (const uint8_t *)pData; + hspi->TxXferSize = Size; + hspi->TxXferCount = Size; + + /* Init field not used in handle to zero */ + hspi->pRxBuffPtr = NULL; + hspi->RxXferSize = (uint16_t) 0UL; + hspi->RxXferCount = (uint16_t) 0UL; + hspi->RxISR = NULL; + + /* Set the function for IT treatment */ + if ((hspi->Init.DataSize > SPI_DATASIZE_16BIT) && (IS_SPI_FULL_INSTANCE(hspi->Instance))) + { + hspi->TxISR = SPI_TxISR_32BIT; + } + else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + { + hspi->TxISR = SPI_TxISR_16BIT; + } + else + { + hspi->TxISR = SPI_TxISR_8BIT; + } + + /* Configure communication direction : 1Line */ + if (hspi->Init.Direction == SPI_DIRECTION_1LINE) + { + SPI_1LINE_TX(hspi); + } + else + { + SPI_2LINES_TX(hspi); + } + + /* Set the number of data at current transfer */ + MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size); + + /* Enable SPI peripheral */ + __HAL_SPI_ENABLE(hspi); + + /* Enable EOT, TXP, FRE, MODF and UDR interrupts */ + __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_TXP | SPI_IT_UDR | SPI_IT_FRE | SPI_IT_MODF)); + + if (hspi->Init.Mode == SPI_MODE_MASTER) + { + /* Master transfer start */ + SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART); + } + + __HAL_UNLOCK(hspi); + return errorcode; +} + +/** + * @brief Receive an amount of data in non-blocking mode with Interrupt. + * @param hspi : pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param pData: pointer to data buffer + * @param Size : amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size) +{ + HAL_StatusTypeDef errorcode = HAL_OK; + + /* Check Direction parameter */ + assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_RXONLY(hspi->Init.Direction)); + + /* Lock the process */ + __HAL_LOCK(hspi); + + if (hspi->State != HAL_SPI_STATE_READY) + { + errorcode = HAL_BUSY; + __HAL_UNLOCK(hspi); + return errorcode; + } + + if ((pData == NULL) || (Size == 0UL)) + { + errorcode = HAL_ERROR; + __HAL_UNLOCK(hspi); + return errorcode; + } + + /* Set the transaction information */ + hspi->State = HAL_SPI_STATE_BUSY_RX; + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->pRxBuffPtr = (uint8_t *)pData; + hspi->RxXferSize = Size; + hspi->RxXferCount = Size; + + /* Init field not used in handle to zero */ + hspi->pTxBuffPtr = NULL; + hspi->TxXferSize = (uint16_t) 0UL; + hspi->TxXferCount = (uint16_t) 0UL; + hspi->TxISR = NULL; + + /* Set the function for IT treatment */ + if ((hspi->Init.DataSize > SPI_DATASIZE_16BIT) && (IS_SPI_FULL_INSTANCE(hspi->Instance))) + { + hspi->RxISR = SPI_RxISR_32BIT; + } + else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + { + hspi->RxISR = SPI_RxISR_16BIT; + } + else + { + hspi->RxISR = SPI_RxISR_8BIT; + } + + /* Configure communication direction : 1Line */ + if (hspi->Init.Direction == SPI_DIRECTION_1LINE) + { + SPI_1LINE_RX(hspi); + } + else + { + SPI_2LINES_RX(hspi); + } + + /* Note : The SPI must be enabled after unlocking current process + to avoid the risk of SPI interrupt handle execution before current + process unlock */ + + /* Set the number of data at current transfer */ + MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size); + + /* Enable SPI peripheral */ + __HAL_SPI_ENABLE(hspi); + + /* Enable EOT, RXP, OVR, FRE and MODF interrupts */ + __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_RXP | SPI_IT_OVR | SPI_IT_FRE | SPI_IT_MODF)); + + if (hspi->Init.Mode == SPI_MODE_MASTER) + { + /* Master transfer start */ + SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART); + } + + /* Unlock the process */ + __HAL_UNLOCK(hspi); + return errorcode; +} + +/** + * @brief Transmit and Receive an amount of data in non-blocking mode with Interrupt. + * @param hspi : pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param pTxData: pointer to transmission data buffer + * @param pRxData: pointer to reception data buffer + * @param Size : amount of data to be sent and received + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData, + uint16_t Size) +{ + HAL_StatusTypeDef errorcode = HAL_OK; + uint32_t tmp_TxXferCount; + +#if defined (__GNUC__) + __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->TXDR)); +#endif /* __GNUC__ */ + + /* Check Direction parameter */ + assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction)); + + /* Lock the process */ + __HAL_LOCK(hspi); + + if (hspi->State != HAL_SPI_STATE_READY) + { + errorcode = HAL_BUSY; + __HAL_UNLOCK(hspi); + return errorcode; + } + + if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0UL)) + { + errorcode = HAL_ERROR; + __HAL_UNLOCK(hspi); + return errorcode; + } + + /* Set the transaction information */ + hspi->State = HAL_SPI_STATE_BUSY_TX_RX; + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->pTxBuffPtr = (const uint8_t *)pTxData; + hspi->TxXferSize = Size; + hspi->TxXferCount = Size; + hspi->pRxBuffPtr = (uint8_t *)pRxData; + hspi->RxXferSize = Size; + hspi->RxXferCount = Size; + tmp_TxXferCount = hspi->TxXferCount; + + /* Set the function for IT treatment */ + if ((hspi->Init.DataSize > SPI_DATASIZE_16BIT) && (IS_SPI_FULL_INSTANCE(hspi->Instance))) + { + hspi->TxISR = SPI_TxISR_32BIT; + hspi->RxISR = SPI_RxISR_32BIT; + } + else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + { + hspi->RxISR = SPI_RxISR_16BIT; + hspi->TxISR = SPI_TxISR_16BIT; + } + else + { + hspi->RxISR = SPI_RxISR_8BIT; + hspi->TxISR = SPI_TxISR_8BIT; + } + + /* Set Full-Duplex mode */ + SPI_2LINES(hspi); + + /* Set the number of data at current transfer */ + MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size); + + /* Enable SPI peripheral */ + __HAL_SPI_ENABLE(hspi); + + /* Fill in the TxFIFO */ + while ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP)) && (tmp_TxXferCount != 0UL)) + { + /* Transmit data in 32 Bit mode */ + if (hspi->Init.DataSize > SPI_DATASIZE_16BIT) + { + *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr); + hspi->pTxBuffPtr += sizeof(uint32_t); + hspi->TxXferCount--; + tmp_TxXferCount = hspi->TxXferCount; + } + /* Transmit data in 16 Bit mode */ + else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + { +#if defined (__GNUC__) + *ptxdr_16bits = *((const uint16_t *)hspi->pTxBuffPtr); +#else + *((__IO uint16_t *)&hspi->Instance->TXDR) = *((const uint16_t *)hspi->pTxBuffPtr); +#endif /* __GNUC__ */ + hspi->pTxBuffPtr += sizeof(uint16_t); + hspi->TxXferCount--; + tmp_TxXferCount = hspi->TxXferCount; + } + /* Transmit data in 8 Bit mode */ + else + { + *((__IO uint8_t *)&hspi->Instance->TXDR) = *((const uint8_t *)hspi->pTxBuffPtr); + hspi->pTxBuffPtr += sizeof(uint8_t); + hspi->TxXferCount--; + tmp_TxXferCount = hspi->TxXferCount; + } + } + + /* Enable EOT, DXP, UDR, OVR, FRE and MODF interrupts */ + __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_DXP | SPI_IT_UDR | SPI_IT_OVR | SPI_IT_FRE | SPI_IT_MODF)); + + if (hspi->Init.Mode == SPI_MODE_MASTER) + { + /* Start Master transfer */ + SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART); + } + + /* Unlock the process */ + __HAL_UNLOCK(hspi); + return errorcode; +} + + + + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief Transmit an amount of data in non-blocking mode with DMA. + * @param hspi : pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param pData: pointer to data buffer + * @param Size : amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size) +{ + HAL_StatusTypeDef errorcode; + + /* Check Direction parameter */ + assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_TXONLY(hspi->Init.Direction)); + + /* Lock the process */ + __HAL_LOCK(hspi); + + if (hspi->State != HAL_SPI_STATE_READY) + { + errorcode = HAL_BUSY; + __HAL_UNLOCK(hspi); + return errorcode; + } + + if ((pData == NULL) || (Size == 0UL)) + { + errorcode = HAL_ERROR; + __HAL_UNLOCK(hspi); + return errorcode; + } + + /* Set the transaction information */ + hspi->State = HAL_SPI_STATE_BUSY_TX; + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->pTxBuffPtr = (const uint8_t *)pData; + hspi->TxXferSize = Size; + hspi->TxXferCount = Size; + + /* Init field not used in handle to zero */ + hspi->pRxBuffPtr = NULL; + hspi->TxISR = NULL; + hspi->RxISR = NULL; + hspi->RxXferSize = (uint16_t)0UL; + hspi->RxXferCount = (uint16_t)0UL; + + /* Configure communication direction : 1Line */ + if (hspi->Init.Direction == SPI_DIRECTION_1LINE) + { + SPI_1LINE_TX(hspi); + } + else + { + SPI_2LINES_TX(hspi); + } + + /* Packing mode management is enabled by the DMA settings */ + if (((hspi->Init.DataSize > SPI_DATASIZE_16BIT) && (hspi->hdmatx->Init.SrcDataWidth != DMA_SRC_DATAWIDTH_WORD) && \ + (IS_SPI_FULL_INSTANCE(hspi->Instance))) || \ + ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) && (hspi->hdmatx->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_BYTE))) + { + /* Restriction the DMA data received is not allowed in this mode */ + errorcode = HAL_ERROR; + __HAL_UNLOCK(hspi); + return errorcode; + } + + /* Adjust XferCount according to DMA alignment / Data size */ + if (hspi->Init.DataSize <= SPI_DATASIZE_8BIT) + { + if (hspi->hdmatx->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_HALFWORD) + { + hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 1UL) >> 1UL; + } + if (hspi->hdmatx->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_WORD) + { + hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 3UL) >> 2UL; + } + } + else if (hspi->Init.DataSize <= SPI_DATASIZE_16BIT) + { + if (hspi->hdmatx->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_WORD) + { + hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 1UL) >> 1UL; + } + } + else + { + /* Adjustment done */ + } + + /* Set the SPI TxDMA Half transfer complete callback */ + hspi->hdmatx->XferHalfCpltCallback = SPI_DMAHalfTransmitCplt; + + /* Set the SPI TxDMA transfer complete callback */ + hspi->hdmatx->XferCpltCallback = SPI_DMATransmitCplt; + + /* Set the DMA error callback */ + hspi->hdmatx->XferErrorCallback = SPI_DMAError; + + /* Set the DMA AbortCpltCallback */ + hspi->hdmatx->XferAbortCallback = NULL; + + /* Clear TXDMAEN bit*/ + CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN); + + if (hspi->Init.DataSize <= SPI_DATASIZE_8BIT) + { + hspi->TxXferCount = Size; + } + else if (hspi->Init.DataSize <= SPI_DATASIZE_16BIT) + { + hspi->TxXferCount = Size * 2U; + } + else + { + hspi->TxXferCount = Size * 4U; + } + + /* Enable the Tx DMA Stream/Channel */ + if ((hspi->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hspi->hdmatx->LinkedListQueue != NULL) + { + /* Set DMA data size */ + hspi->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hspi->TxXferCount; + + /* Set DMA source address */ + hspi->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)hspi->pTxBuffPtr; + + /* Set DMA destination address */ + hspi->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)&hspi->Instance->TXDR; + + errorcode = HAL_DMAEx_List_Start_IT(hspi->hdmatx); + } + else + { + /* Update SPI error code */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); + + /* Unlock the process */ + __HAL_UNLOCK(hspi); + + hspi->State = HAL_SPI_STATE_READY; + errorcode = HAL_ERROR; + return errorcode; + } + } + else + { + errorcode = HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->TXDR, + hspi->TxXferCount); + } + + /* Check status */ + if (errorcode != HAL_OK) + { + /* Update SPI error code */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); + + /* Unlock the process */ + __HAL_UNLOCK(hspi); + + hspi->State = HAL_SPI_STATE_READY; + errorcode = HAL_ERROR; + return errorcode; + } + + /* Set the number of data at current transfer */ + if (hspi->hdmatx->Mode == DMA_LINKEDLIST_CIRCULAR) + { + MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, 0UL); + } + else + { + MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size); + } + + /* Enable Tx DMA Request */ + SET_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN); + + /* Enable the SPI Error Interrupt Bit */ + __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_UDR | SPI_IT_FRE | SPI_IT_MODF)); + + /* Enable SPI peripheral */ + __HAL_SPI_ENABLE(hspi); + + if (hspi->Init.Mode == SPI_MODE_MASTER) + { + /* Master transfer start */ + SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART); + } + + /* Unlock the process */ + __HAL_UNLOCK(hspi); + return errorcode; +} + +/** + * @brief Receive an amount of data in non-blocking mode with DMA. + * @param hspi : pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param pData: pointer to data buffer + * @param Size : amount of data to be sent + * @note When the CRC feature is enabled the pData Length must be Size + 1. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size) +{ + HAL_StatusTypeDef errorcode; + + /* Check Direction parameter */ + assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_RXONLY(hspi->Init.Direction)); + + /* Lock the process */ + __HAL_LOCK(hspi); + + if (hspi->State != HAL_SPI_STATE_READY) + { + errorcode = HAL_BUSY; + __HAL_UNLOCK(hspi); + return errorcode; + } + + if ((pData == NULL) || (Size == 0UL)) + { + errorcode = HAL_ERROR; + __HAL_UNLOCK(hspi); + return errorcode; + } + + /* Set the transaction information */ + hspi->State = HAL_SPI_STATE_BUSY_RX; + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->pRxBuffPtr = (uint8_t *)pData; + hspi->RxXferSize = Size; + hspi->RxXferCount = Size; + + /*Init field not used in handle to zero */ + hspi->RxISR = NULL; + hspi->TxISR = NULL; + hspi->TxXferSize = (uint16_t) 0UL; + hspi->TxXferCount = (uint16_t) 0UL; + + /* Configure communication direction : 1Line */ + if (hspi->Init.Direction == SPI_DIRECTION_1LINE) + { + SPI_1LINE_RX(hspi); + } + else + { + SPI_2LINES_RX(hspi); + } + + /* Packing mode management is enabled by the DMA settings */ + if (((hspi->Init.DataSize > SPI_DATASIZE_16BIT) && (hspi->hdmarx->Init.DestDataWidth != DMA_DEST_DATAWIDTH_WORD) && \ + (IS_SPI_FULL_INSTANCE(hspi->Instance))) || \ + ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) && (hspi->hdmarx->Init.DestDataWidth == DMA_DEST_DATAWIDTH_BYTE))) + { + /* Restriction the DMA data received is not allowed in this mode */ + errorcode = HAL_ERROR; + __HAL_UNLOCK(hspi); + return errorcode; + } + + /* Clear RXDMAEN bit */ + CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_RXDMAEN); + + /* Adjust XferCount according to DMA alignment / Data size */ + if (hspi->Init.DataSize <= SPI_DATASIZE_8BIT) + { + if (hspi->hdmarx->Init.DestDataWidth == DMA_DEST_DATAWIDTH_HALFWORD) + { + hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 1UL) >> 1UL; + } + if (hspi->hdmarx->Init.DestDataWidth == DMA_DEST_DATAWIDTH_WORD) + { + hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 3UL) >> 2UL; + } + } + else if (hspi->Init.DataSize <= SPI_DATASIZE_16BIT) + { + if (hspi->hdmarx->Init.DestDataWidth == DMA_DEST_DATAWIDTH_WORD) + { + hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 1UL) >> 1UL; + } + } + else + { + /* Adjustment done */ + } + + /* Set the SPI RxDMA Half transfer complete callback */ + hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt; + + /* Set the SPI Rx DMA transfer complete callback */ + hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt; + + /* Set the DMA error callback */ + hspi->hdmarx->XferErrorCallback = SPI_DMAError; + + /* Set the DMA AbortCpltCallback */ + hspi->hdmarx->XferAbortCallback = NULL; + + if (hspi->Init.DataSize <= SPI_DATASIZE_8BIT) + { + hspi->RxXferCount = Size; + } + else if (hspi->Init.DataSize <= SPI_DATASIZE_16BIT) + { + hspi->RxXferCount = Size * 2U; + } + else + { + hspi->RxXferCount = Size * 4U; + } + + /* Enable the Rx DMA Stream/Channel */ + if ((hspi->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hspi->hdmarx->LinkedListQueue != NULL) + { + /* Set DMA data size */ + hspi->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hspi->RxXferCount; + + /* Set DMA source address */ + hspi->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)&hspi->Instance->RXDR; + + /* Set DMA destination address */ + hspi->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)hspi->pRxBuffPtr; + + errorcode = HAL_DMAEx_List_Start_IT(hspi->hdmarx); + } + else + { + /* Update SPI error code */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); + + /* Unlock the process */ + __HAL_UNLOCK(hspi); + + hspi->State = HAL_SPI_STATE_READY; + errorcode = HAL_ERROR; + return errorcode; + } + } + else + { + errorcode = HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->RXDR, (uint32_t)hspi->pRxBuffPtr, + hspi->RxXferCount); + } + + /* Check status */ + if (errorcode != HAL_OK) + { + /* Update SPI error code */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); + + /* Unlock the process */ + __HAL_UNLOCK(hspi); + + hspi->State = HAL_SPI_STATE_READY; + errorcode = HAL_ERROR; + return errorcode; + } + + /* Set the number of data at current transfer */ + if (hspi->hdmarx->Mode == DMA_LINKEDLIST_CIRCULAR) + { + MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, 0UL); + } + else + { + MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size); + } + + /* Enable Rx DMA Request */ + SET_BIT(hspi->Instance->CFG1, SPI_CFG1_RXDMAEN); + + /* Enable the SPI Error Interrupt Bit */ + __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_OVR | SPI_IT_FRE | SPI_IT_MODF)); + + /* Enable SPI peripheral */ + __HAL_SPI_ENABLE(hspi); + + if (hspi->Init.Mode == SPI_MODE_MASTER) + { + /* Master transfer start */ + SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART); + } + + /* Unlock the process */ + __HAL_UNLOCK(hspi); + return errorcode; +} + +/** + * @brief Transmit and Receive an amount of data in non-blocking mode with DMA. + * @param hspi : pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param pTxData: pointer to transmission data buffer + * @param pRxData: pointer to reception data buffer + * @param Size : amount of data to be sent + * @note When the CRC feature is enabled the pRxData Length must be Size + 1 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData, + uint16_t Size) +{ + HAL_StatusTypeDef errorcode; + + /* Check Direction parameter */ + assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction)); + + /* Lock the process */ + __HAL_LOCK(hspi); + + if (hspi->State != HAL_SPI_STATE_READY) + { + errorcode = HAL_BUSY; + __HAL_UNLOCK(hspi); + return errorcode; + } + + if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0UL)) + { + errorcode = HAL_ERROR; + __HAL_UNLOCK(hspi); + return errorcode; + } + + /* Set the transaction information */ + hspi->State = HAL_SPI_STATE_BUSY_TX_RX; + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->pTxBuffPtr = (const uint8_t *)pTxData; + hspi->TxXferSize = Size; + hspi->TxXferCount = Size; + hspi->pRxBuffPtr = (uint8_t *)pRxData; + hspi->RxXferSize = Size; + hspi->RxXferCount = Size; + + /* Init field not used in handle to zero */ + hspi->RxISR = NULL; + hspi->TxISR = NULL; + + /* Set Full-Duplex mode */ + SPI_2LINES(hspi); + + /* Reset the Tx/Rx DMA bits */ + CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN); + + /* Packing mode management is enabled by the DMA settings */ + if (((hspi->Init.DataSize > SPI_DATASIZE_16BIT) && (hspi->hdmarx->Init.DestDataWidth != DMA_DEST_DATAWIDTH_WORD) && \ + (IS_SPI_FULL_INSTANCE(hspi->Instance))) || \ + ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) && (hspi->hdmarx->Init.DestDataWidth == DMA_DEST_DATAWIDTH_BYTE))) + { + /* Restriction the DMA data received is not allowed in this mode */ + errorcode = HAL_ERROR; + /* Unlock the process */ + __HAL_UNLOCK(hspi); + return errorcode; + } + + /* Adjust XferCount according to DMA alignment / Data size */ + if (hspi->Init.DataSize <= SPI_DATASIZE_8BIT) + { + if (hspi->hdmatx->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_HALFWORD) + { + hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 1UL) >> 1UL; + } + if (hspi->hdmatx->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_WORD) + { + hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 3UL) >> 2UL; + } + if (hspi->hdmarx->Init.DestDataWidth == DMA_DEST_DATAWIDTH_HALFWORD) + { + hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 1UL) >> 1UL; + } + if (hspi->hdmarx->Init.DestDataWidth == DMA_DEST_DATAWIDTH_WORD) + { + hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 3UL) >> 2UL; + } + } + else if (hspi->Init.DataSize <= SPI_DATASIZE_16BIT) + { + if (hspi->hdmatx->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_WORD) + { + hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 1UL) >> 1UL; + } + if (hspi->hdmarx->Init.DestDataWidth == DMA_DEST_DATAWIDTH_WORD) + { + hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 1UL) >> 1UL; + } + } + else + { + /* Adjustment done */ + } + + /* Set the SPI Tx/Rx DMA Half transfer complete callback */ + hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfTransmitReceiveCplt; + hspi->hdmarx->XferCpltCallback = SPI_DMATransmitReceiveCplt; + + /* Set the DMA error callback */ + hspi->hdmarx->XferErrorCallback = SPI_DMAError; + + /* Set the DMA AbortCallback */ + hspi->hdmarx->XferAbortCallback = NULL; + + if (hspi->Init.DataSize <= SPI_DATASIZE_8BIT) + { + hspi->RxXferCount = Size; + } + else if (hspi->Init.DataSize <= SPI_DATASIZE_16BIT) + { + hspi->RxXferCount = Size * 2U; + } + else + { + hspi->RxXferCount = Size * 4U; + } + /* Enable the Rx DMA Stream/Channel */ + if ((hspi->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hspi->hdmarx->LinkedListQueue != NULL) + { + /* Set DMA data size */ + hspi->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hspi->RxXferCount; + + /* Set DMA source address */ + hspi->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)&hspi->Instance->RXDR; + + /* Set DMA destination address */ + hspi->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)hspi->pRxBuffPtr; + + errorcode = HAL_DMAEx_List_Start_IT(hspi->hdmarx); + } + else + { + /* Update SPI error code */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); + + /* Unlock the process */ + __HAL_UNLOCK(hspi); + + hspi->State = HAL_SPI_STATE_READY; + errorcode = HAL_ERROR; + return errorcode; + } + } + else + { + errorcode = HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->RXDR, (uint32_t)hspi->pRxBuffPtr, + hspi->RxXferCount); + } + + /* Check status */ + if (errorcode != HAL_OK) + { + /* Update SPI error code */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); + + /* Unlock the process */ + __HAL_UNLOCK(hspi); + + hspi->State = HAL_SPI_STATE_READY; + errorcode = HAL_ERROR; + return errorcode; + } + + /* Enable Rx DMA Request */ + SET_BIT(hspi->Instance->CFG1, SPI_CFG1_RXDMAEN); + + /* Set the SPI Tx DMA transfer complete callback as NULL because the communication closing + is performed in DMA reception complete callback */ + hspi->hdmatx->XferHalfCpltCallback = NULL; + hspi->hdmatx->XferCpltCallback = NULL; + hspi->hdmatx->XferAbortCallback = NULL; + + /* Set the DMA error callback */ + hspi->hdmatx->XferErrorCallback = SPI_DMAError; + + if (hspi->Init.DataSize <= SPI_DATASIZE_8BIT) + { + hspi->TxXferCount = Size; + } + else if (hspi->Init.DataSize <= SPI_DATASIZE_16BIT) + { + hspi->TxXferCount = Size * 2U; + } + else + { + hspi->TxXferCount = Size * 4U; + } + + /* Enable the Tx DMA Stream/Channel */ + if ((hspi->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hspi->hdmatx->LinkedListQueue != NULL) + { + /* Set DMA data size */ + hspi->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hspi->TxXferCount; + + /* Set DMA source address */ + hspi->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)hspi->pTxBuffPtr; + + /* Set DMA destination address */ + hspi->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)&hspi->Instance->TXDR; + + errorcode = HAL_DMAEx_List_Start_IT(hspi->hdmatx); + } + else + { + /* Update SPI error code */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); + + /* Unlock the process */ + __HAL_UNLOCK(hspi); + + hspi->State = HAL_SPI_STATE_READY; + errorcode = HAL_ERROR; + return errorcode; + } + } + else + { + errorcode = HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->TXDR, + hspi->TxXferCount); + } + + /* Check status */ + if (errorcode != HAL_OK) + { + /* Update SPI error code */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); + + /* Unlock the process */ + __HAL_UNLOCK(hspi); + + hspi->State = HAL_SPI_STATE_READY; + errorcode = HAL_ERROR; + return errorcode; + } + + if ((hspi->hdmarx->Mode == DMA_LINKEDLIST_CIRCULAR) && (hspi->hdmatx->Mode == DMA_LINKEDLIST_CIRCULAR)) + { + MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, 0UL); + } + else + { + MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size); + } + + /* Enable Tx DMA Request */ + SET_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN); + + /* Enable the SPI Error Interrupt Bit */ + __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_OVR | SPI_IT_UDR | SPI_IT_FRE | SPI_IT_MODF)); + + /* Enable SPI peripheral */ + __HAL_SPI_ENABLE(hspi); + + if (hspi->Init.Mode == SPI_MODE_MASTER) + { + /* Master transfer start */ + SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART); + } + + /* Unlock the process */ + __HAL_UNLOCK(hspi); + return errorcode; +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Abort ongoing transfer (blocking mode). + * @param hspi SPI handle. + * @note This procedure could be used for aborting any ongoing transfer (Tx and Rx), + * started in Interrupt or DMA mode. + * @note This procedure performs following operations : + * + Disable SPI Interrupts (depending of transfer direction) + * + Disable the DMA transfer in the peripheral register (if enabled) + * + Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) + * + Set handle State to READY. + * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_Abort(SPI_HandleTypeDef *hspi) +{ + HAL_StatusTypeDef errorcode; + + __IO uint32_t count; + + /* Lock the process */ + __HAL_LOCK(hspi); + + /* Set hspi->state to aborting to avoid any interaction */ + hspi->State = HAL_SPI_STATE_ABORT; + + /* Initialized local variable */ + errorcode = HAL_OK; + count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24UL / 1000UL); + + /* If master communication on going, make sure current frame is done before closing the connection */ + if (HAL_IS_BIT_SET(hspi->Instance->CR1, SPI_CR1_CSTART)) + { + /* Disable EOT interrupt */ + __HAL_SPI_DISABLE_IT(hspi, SPI_IT_EOT); + do + { + count--; + if (count == 0UL) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); + break; + } + } while (HAL_IS_BIT_SET(hspi->Instance->IER, SPI_IT_EOT)); + + /* Request a Suspend transfer */ + SET_BIT(hspi->Instance->CR1, SPI_CR1_CSUSP); + do + { + count--; + if (count == 0UL) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); + break; + } + } while (HAL_IS_BIT_SET(hspi->Instance->CR1, SPI_CR1_CSTART)); + + /* Clear SUSP flag */ + __HAL_SPI_CLEAR_SUSPFLAG(hspi); + do + { + count--; + if (count == 0UL) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); + break; + } + } while (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_SUSP)); + } + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Disable the SPI DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN)) + { + if (hspi->hdmatx != NULL) + { + /* Abort the SPI DMA Tx Stream/Channel : use blocking DMA Abort API (no callback) */ + hspi->hdmatx->XferAbortCallback = NULL; + + /* Abort DMA Tx Handle linked to SPI Peripheral */ + if (HAL_DMA_Abort(hspi->hdmatx) != HAL_OK) + { + if (HAL_DMA_GetError(hspi->hdmatx) == HAL_DMA_ERROR_TIMEOUT) + { + hspi->ErrorCode = HAL_SPI_ERROR_ABORT; + } + } + } + } + + /* Disable the SPI DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(hspi->Instance->CFG1, SPI_CFG1_RXDMAEN)) + { + if (hspi->hdmarx != NULL) + { + /* Abort the SPI DMA Rx Stream/Channel : use blocking DMA Abort API (no callback) */ + hspi->hdmarx->XferAbortCallback = NULL; + + /* Abort DMA Rx Handle linked to SPI Peripheral */ + if (HAL_DMA_Abort(hspi->hdmarx) != HAL_OK) + { + if (HAL_DMA_GetError(hspi->hdmarx) == HAL_DMA_ERROR_TIMEOUT) + { + hspi->ErrorCode = HAL_SPI_ERROR_ABORT; + } + } + } + } +#endif /* HAL_DMA_MODULE_ENABLED */ + + /* Proceed with abort procedure */ + SPI_AbortTransfer(hspi); + + /* Check error during Abort procedure */ + if (HAL_IS_BIT_SET(hspi->ErrorCode, HAL_SPI_ERROR_ABORT)) + { + /* return HAL_Error in case of error during Abort procedure */ + errorcode = HAL_ERROR; + } + else + { + /* Reset errorCode */ + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + } + + /* Unlock the process */ + __HAL_UNLOCK(hspi); + + /* Restore hspi->state to ready */ + hspi->State = HAL_SPI_STATE_READY; + + return errorcode; +} + +/** + * @brief Abort ongoing transfer (Interrupt mode). + * @param hspi SPI handle. + * @note This procedure could be used for aborting any ongoing transfer (Tx and Rx), + * started in Interrupt or DMA mode. + * @note This procedure performs following operations : + * + Disable SPI Interrupts (depending of transfer direction) + * + Disable the DMA transfer in the peripheral register (if enabled) + * + Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) + * + Set handle State to READY + * + At abort completion, call user abort complete callback. + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_Abort_IT(SPI_HandleTypeDef *hspi) +{ + HAL_StatusTypeDef errorcode; + __IO uint32_t count; +#if defined(HAL_DMA_MODULE_ENABLED) + uint32_t dma_tx_abort_done = 1UL; + uint32_t dma_rx_abort_done = 1UL; +#endif /* HAL_DMA_MODULE_ENABLED */ + + /* Set hspi->state to aborting to avoid any interaction */ + hspi->State = HAL_SPI_STATE_ABORT; + + /* Initialized local variable */ + errorcode = HAL_OK; + count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24UL / 1000UL); + + /* If master communication on going, make sure current frame is done before closing the connection */ + if (HAL_IS_BIT_SET(hspi->Instance->CR1, SPI_CR1_CSTART)) + { + /* Disable EOT interrupt */ + __HAL_SPI_DISABLE_IT(hspi, SPI_IT_EOT); + do + { + count--; + if (count == 0UL) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); + break; + } + } while (HAL_IS_BIT_SET(hspi->Instance->IER, SPI_IT_EOT)); + + /* Request a Suspend transfer */ + SET_BIT(hspi->Instance->CR1, SPI_CR1_CSUSP); + do + { + count--; + if (count == 0UL) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); + break; + } + } while (HAL_IS_BIT_SET(hspi->Instance->CR1, SPI_CR1_CSTART)); + + /* Clear SUSP flag */ + __HAL_SPI_CLEAR_SUSPFLAG(hspi); + do + { + count--; + if (count == 0UL) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); + break; + } + } while (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_SUSP)); + } + +#if defined(HAL_DMA_MODULE_ENABLED) + /* If DMA Tx and/or DMA Rx Handles are associated to SPI Handle, DMA Abort complete callbacks should be initialized + before any call to DMA Abort functions */ + + if (hspi->hdmatx != NULL) + { + if (HAL_IS_BIT_SET(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN)) + { + /* Set DMA Abort Complete callback if SPI DMA Tx request if enabled */ + hspi->hdmatx->XferAbortCallback = SPI_DMATxAbortCallback; + + dma_tx_abort_done = 0UL; + + /* Abort DMA Tx Handle linked to SPI Peripheral */ + if (HAL_DMA_Abort_IT(hspi->hdmatx) != HAL_OK) + { + if (HAL_DMA_GetError(hspi->hdmatx) == HAL_DMA_ERROR_NO_XFER) + { + dma_tx_abort_done = 1UL; + hspi->hdmatx->XferAbortCallback = NULL; + } + } + } + else + { + hspi->hdmatx->XferAbortCallback = NULL; + } + } + + if (hspi->hdmarx != NULL) + { + if (HAL_IS_BIT_SET(hspi->Instance->CFG1, SPI_CFG1_RXDMAEN)) + { + /* Set DMA Abort Complete callback if SPI DMA Rx request if enabled */ + hspi->hdmarx->XferAbortCallback = SPI_DMARxAbortCallback; + + dma_rx_abort_done = 0UL; + + /* Abort DMA Rx Handle linked to SPI Peripheral */ + if (HAL_DMA_Abort_IT(hspi->hdmarx) != HAL_OK) + { + if (HAL_DMA_GetError(hspi->hdmarx) == HAL_DMA_ERROR_NO_XFER) + { + dma_rx_abort_done = 1UL; + hspi->hdmarx->XferAbortCallback = NULL; + } + } + } + else + { + hspi->hdmarx->XferAbortCallback = NULL; + } + } + + /* If no running DMA transfer, finish cleanup and call callbacks */ + if ((dma_tx_abort_done == 1UL) && (dma_rx_abort_done == 1UL)) + { +#endif /* HAL_DMA_MODULE_ENABLED */ + /* Proceed with abort procedure */ + SPI_AbortTransfer(hspi); + + /* Check error during Abort procedure */ + if (HAL_IS_BIT_SET(hspi->ErrorCode, HAL_SPI_ERROR_ABORT)) + { + /* return HAL_Error in case of error during Abort procedure */ + errorcode = HAL_ERROR; + } + else + { + /* Reset errorCode */ + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + } + + /* Restore hspi->state to ready */ + hspi->State = HAL_SPI_STATE_READY; + + /* Call user Abort complete callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) + hspi->AbortCpltCallback(hspi); +#else + HAL_SPI_AbortCpltCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ +#if defined(HAL_DMA_MODULE_ENABLED) + } +#endif /* HAL_DMA_MODULE_ENABLED */ + + return errorcode; +} + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief Pause the DMA Transfer. + * This API is not supported, it is maintained for backward compatibility. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for the specified SPI module. + * @retval HAL_ERROR + */ +HAL_StatusTypeDef HAL_SPI_DMAPause(SPI_HandleTypeDef *hspi) +{ + /* Set error code to not supported */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_NOT_SUPPORTED); + + return HAL_ERROR; +} + +/** + * @brief Resume the DMA Transfer. + * This API is not supported, it is maintained for backward compatibility. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for the specified SPI module. + * @retval HAL_ERROR + */ +HAL_StatusTypeDef HAL_SPI_DMAResume(SPI_HandleTypeDef *hspi) +{ + /* Set error code to not supported */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_NOT_SUPPORTED); + + return HAL_ERROR; +} + +/** + * @brief Stop the DMA Transfer. + * This API is not supported, it is maintained for backward compatibility. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for the specified SPI module. + * @retval HAL_ERROR + */ +HAL_StatusTypeDef HAL_SPI_DMAStop(SPI_HandleTypeDef *hspi) +{ + /* Set error code to not supported */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_NOT_SUPPORTED); + + return HAL_ERROR; +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Handle SPI interrupt request. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for the specified SPI module. + * @retval None + */ +void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi) +{ + uint32_t itsource = hspi->Instance->IER; + uint32_t itflag = hspi->Instance->SR; + uint32_t trigger = itsource & itflag; + uint32_t cfg1 = hspi->Instance->CFG1; + uint32_t handled = 0UL; + + HAL_SPI_StateTypeDef State = hspi->State; +#if defined (__GNUC__) + __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->RXDR)); +#endif /* __GNUC__ */ + + /* SPI in SUSPEND mode ----------------------------------------------------*/ + if (HAL_IS_BIT_SET(itflag, SPI_FLAG_SUSP) && HAL_IS_BIT_SET(itsource, SPI_FLAG_EOT)) + { + /* Clear the Suspend flag */ + __HAL_SPI_CLEAR_SUSPFLAG(hspi); + + /* Suspend on going, Call the Suspend callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) + hspi->SuspendCallback(hspi); +#else + HAL_SPI_SuspendCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + return; + } + + /* SPI in mode Transmitter and Receiver ------------------------------------*/ + if (HAL_IS_BIT_CLR(trigger, SPI_FLAG_OVR) && HAL_IS_BIT_CLR(trigger, SPI_FLAG_UDR) && \ + HAL_IS_BIT_SET(trigger, SPI_FLAG_DXP)) + { + hspi->TxISR(hspi); + hspi->RxISR(hspi); + handled = 1UL; + } + + /* SPI in mode Receiver ----------------------------------------------------*/ + if (HAL_IS_BIT_CLR(trigger, SPI_FLAG_OVR) && HAL_IS_BIT_SET(trigger, SPI_FLAG_RXP) && \ + HAL_IS_BIT_CLR(trigger, SPI_FLAG_DXP)) + { + hspi->RxISR(hspi); + handled = 1UL; + } + + /* SPI in mode Transmitter -------------------------------------------------*/ + if (HAL_IS_BIT_CLR(trigger, SPI_FLAG_UDR) && HAL_IS_BIT_SET(trigger, SPI_FLAG_TXP) && \ + HAL_IS_BIT_CLR(trigger, SPI_FLAG_DXP)) + { + hspi->TxISR(hspi); + handled = 1UL; + } + + + if (handled != 0UL) + { + return; + } + + /* SPI End Of Transfer: DMA or IT based transfer */ + if (HAL_IS_BIT_SET(trigger, SPI_FLAG_EOT)) + { + /* Clear EOT/TXTF/SUSP flag */ + __HAL_SPI_CLEAR_EOTFLAG(hspi); + __HAL_SPI_CLEAR_TXTFFLAG(hspi); + __HAL_SPI_CLEAR_SUSPFLAG(hspi); + + /* Disable EOT interrupt */ + __HAL_SPI_DISABLE_IT(hspi, SPI_IT_EOT); + + /* For the IT based receive extra polling maybe required for last packet */ + if (HAL_IS_BIT_CLR(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN)) + { + /* Pooling remaining data */ + while (hspi->RxXferCount != 0UL) + { + /* Receive data in 32 Bit mode */ + if (hspi->Init.DataSize > SPI_DATASIZE_16BIT) + { + *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR); + hspi->pRxBuffPtr += sizeof(uint32_t); + } + /* Receive data in 16 Bit mode */ + else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + { +#if defined (__GNUC__) + *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits; +#else + *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR); +#endif /* __GNUC__ */ + hspi->pRxBuffPtr += sizeof(uint16_t); + } + /* Receive data in 8 Bit mode */ + else + { + *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR); + hspi->pRxBuffPtr += sizeof(uint8_t); + } + + hspi->RxXferCount--; + } + } + + /* Call SPI Standard close procedure */ + SPI_CloseTransfer(hspi); + + hspi->State = HAL_SPI_STATE_READY; + if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) + { +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) + hspi->ErrorCallback(hspi); +#else + HAL_SPI_ErrorCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + return; + } + +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) + /* Call appropriate user callback */ + if (State == HAL_SPI_STATE_BUSY_TX_RX) + { + hspi->TxRxCpltCallback(hspi); + } + else if (State == HAL_SPI_STATE_BUSY_RX) + { + hspi->RxCpltCallback(hspi); + } + else if (State == HAL_SPI_STATE_BUSY_TX) + { + hspi->TxCpltCallback(hspi); + } +#else + /* Call appropriate user callback */ + if (State == HAL_SPI_STATE_BUSY_TX_RX) + { + HAL_SPI_TxRxCpltCallback(hspi); + } + else if (State == HAL_SPI_STATE_BUSY_RX) + { + HAL_SPI_RxCpltCallback(hspi); + } + else if (State == HAL_SPI_STATE_BUSY_TX) + { + HAL_SPI_TxCpltCallback(hspi); + } +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + else + { + /* End of the appropriate call */ + } + + return; + } + + /* SPI in Error Treatment --------------------------------------------------*/ + if ((trigger & (SPI_FLAG_MODF | SPI_FLAG_OVR | SPI_FLAG_FRE | SPI_FLAG_UDR)) != 0UL) + { + /* SPI Overrun error interrupt occurred ----------------------------------*/ + if ((trigger & SPI_FLAG_OVR) != 0UL) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_OVR); + __HAL_SPI_CLEAR_OVRFLAG(hspi); + } + + /* SPI Mode Fault error interrupt occurred -------------------------------*/ + if ((trigger & SPI_FLAG_MODF) != 0UL) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_MODF); + __HAL_SPI_CLEAR_MODFFLAG(hspi); + } + + /* SPI Frame error interrupt occurred ------------------------------------*/ + if ((trigger & SPI_FLAG_FRE) != 0UL) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FRE); + __HAL_SPI_CLEAR_FREFLAG(hspi); + } + + /* SPI Underrun error interrupt occurred ------------------------------------*/ + if ((trigger & SPI_FLAG_UDR) != 0UL) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_UDR); + __HAL_SPI_CLEAR_UDRFLAG(hspi); + } + + if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) + { + /* Disable SPI peripheral */ + __HAL_SPI_DISABLE(hspi); + + /* Disable all interrupts */ + __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_RXP | SPI_IT_TXP | SPI_IT_MODF | + SPI_IT_OVR | SPI_IT_FRE | SPI_IT_UDR)); + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Disable the SPI DMA requests if enabled */ + if (HAL_IS_BIT_SET(cfg1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN)) + { + /* Disable the SPI DMA requests */ + CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN); + + /* Abort the SPI DMA Rx channel */ + if (hspi->hdmarx != NULL) + { + /* Set the SPI DMA Abort callback : + will lead to call HAL_SPI_ErrorCallback() at end of DMA abort procedure */ + hspi->hdmarx->XferAbortCallback = SPI_DMAAbortOnError; + if (HAL_OK != HAL_DMA_Abort_IT(hspi->hdmarx)) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); + } + } + /* Abort the SPI DMA Tx channel */ + if (hspi->hdmatx != NULL) + { + /* Set the SPI DMA Abort callback : + will lead to call HAL_SPI_ErrorCallback() at end of DMA abort procedure */ + hspi->hdmatx->XferAbortCallback = SPI_DMAAbortOnError; + if (HAL_OK != HAL_DMA_Abort_IT(hspi->hdmatx)) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); + } + } + } + else + { +#endif /* HAL_DMA_MODULE_ENABLED */ + /* Restore hspi->State to Ready */ + hspi->State = HAL_SPI_STATE_READY; + + /* Call user error callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) + hspi->ErrorCallback(hspi); +#else + HAL_SPI_ErrorCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ +#if defined(HAL_DMA_MODULE_ENABLED) + } +#endif /* HAL_DMA_MODULE_ENABLED */ + } + return; + } +} + +/** + * @brief Tx Transfer completed callback. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +__weak void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */ +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hspi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SPI_TxCpltCallback should be implemented in the user file + */ +} + +/** + * @brief Rx Transfer completed callback. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +__weak void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */ +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hspi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SPI_RxCpltCallback should be implemented in the user file + */ +} + +/** + * @brief Tx and Rx Transfer completed callback. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +__weak void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */ +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hspi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SPI_TxRxCpltCallback should be implemented in the user file + */ +} + +/** + * @brief Tx Half Transfer completed callback. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +__weak void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */ +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hspi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SPI_TxHalfCpltCallback should be implemented in the user file + */ +} + +/** + * @brief Rx Half Transfer completed callback. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +__weak void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */ +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hspi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SPI_RxHalfCpltCallback() should be implemented in the user file + */ +} + +/** + * @brief Tx and Rx Half Transfer callback. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +__weak void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */ +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hspi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SPI_TxRxHalfCpltCallback() should be implemented in the user file + */ +} + +/** + * @brief SPI error callback. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +__weak void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */ +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hspi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SPI_ErrorCallback should be implemented in the user file + */ + /* NOTE : The ErrorCode parameter in the hspi handle is updated by the SPI processes + and user can use HAL_SPI_GetError() API to check the latest error occurred + */ +} + +/** + * @brief SPI Abort Complete callback. + * @param hspi SPI handle. + * @retval None + */ +__weak void HAL_SPI_AbortCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */ +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hspi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SPI_AbortCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief SPI Suspend callback. + * @param hspi SPI handle. + * @retval None + */ +__weak void HAL_SPI_SuspendCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */ +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hspi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SPI_SuspendCallback can be implemented in the user file. + */ +} + +/** + * @} + */ + +/** @defgroup SPI_Exported_Functions_Group3 Peripheral State and Errors functions + * @brief SPI control functions + * +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the SPI. + (+) HAL_SPI_GetState() API can be helpful to check in run-time the state of the SPI peripheral + (+) HAL_SPI_GetError() check in run-time Errors occurring during communication +@endverbatim + * @{ + */ + +/** + * @brief Return the SPI handle state. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval SPI state + */ +HAL_SPI_StateTypeDef HAL_SPI_GetState(const SPI_HandleTypeDef *hspi) +{ + /* Return SPI handle state */ + return hspi->State; +} + +/** + * @brief Return the SPI error code. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval SPI error code in bitmap format + */ +uint32_t HAL_SPI_GetError(const SPI_HandleTypeDef *hspi) +{ + /* Return SPI ErrorCode */ + return hspi->ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup SPI_Private_Functions + * @brief Private functions + * @{ + */ + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief DMA SPI transmit process complete callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma) +{ + SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + if (hspi->State != HAL_SPI_STATE_ABORT) + { + if (hspi->hdmatx->Mode == DMA_LINKEDLIST_CIRCULAR) + { +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) + hspi->TxCpltCallback(hspi); +#else + HAL_SPI_TxCpltCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + } + else + { + /* Enable EOT interrupt */ + __HAL_SPI_ENABLE_IT(hspi, SPI_IT_EOT); + } + } +} + +/** + * @brief DMA SPI receive process complete callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma) +{ + SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + if (hspi->State != HAL_SPI_STATE_ABORT) + { + if (hspi->hdmarx->Mode == DMA_LINKEDLIST_CIRCULAR) + { +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) + hspi->RxCpltCallback(hspi); +#else + HAL_SPI_RxCpltCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + } + else + { + /* Enable EOT interrupt */ + __HAL_SPI_ENABLE_IT(hspi, SPI_IT_EOT); + } + } +} + +/** + * @brief DMA SPI transmit receive process complete callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma) +{ + SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + if (hspi->State != HAL_SPI_STATE_ABORT) + { + if ((hspi->hdmarx->Mode == DMA_LINKEDLIST_CIRCULAR) && + (hspi->hdmatx->Mode == DMA_LINKEDLIST_CIRCULAR)) + { +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) + hspi->TxRxCpltCallback(hspi); +#else + HAL_SPI_TxRxCpltCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + } + else + { + /* Enable EOT interrupt */ + __HAL_SPI_ENABLE_IT(hspi, SPI_IT_EOT); + } + } +} + +/** + * @brief DMA SPI half transmit process complete callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma) /* Derogation MISRAC2012-Rule-8.13 */ +{ + SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-8.13 */ + +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) + hspi->TxHalfCpltCallback(hspi); +#else + HAL_SPI_TxHalfCpltCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA SPI half receive process complete callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma) /* Derogation MISRAC2012-Rule-8.13 */ +{ + SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-8.13 */ + +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) + hspi->RxHalfCpltCallback(hspi); +#else + HAL_SPI_RxHalfCpltCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA SPI half transmit receive process complete callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma) /* Derogation MISRAC2012-Rule-8.13 */ +{ + SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-8.13 */ + +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) + hspi->TxRxHalfCpltCallback(hspi); +#else + HAL_SPI_TxRxHalfCpltCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA SPI communication error callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SPI_DMAError(DMA_HandleTypeDef *hdma) +{ + SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* if DMA error is FIFO error ignore it */ + if (HAL_DMA_GetError(hdma) != HAL_DMA_ERROR_NONE) + { + /* Call SPI standard close procedure */ + SPI_CloseTransfer(hspi); + + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); + hspi->State = HAL_SPI_STATE_READY; +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) + hspi->ErrorCallback(hspi); +#else + HAL_SPI_ErrorCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + } +} + +/** + * @brief DMA SPI communication abort callback, when initiated by HAL services on Error + * (To be called at end of DMA Abort procedure following error occurrence). + * @param hdma DMA handle. + * @retval None + */ +static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma) +{ + SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + hspi->RxXferCount = (uint16_t) 0UL; + hspi->TxXferCount = (uint16_t) 0UL; + + /* Restore hspi->State to Ready */ + hspi->State = HAL_SPI_STATE_READY; + +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) + hspi->ErrorCallback(hspi); +#else + HAL_SPI_ErrorCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA SPI Tx communication abort callback, when initiated by user + * (To be called at end of DMA Tx Abort procedure following user abort request). + * @note When this callback is executed, User Abort complete call back is called only if no + * Abort still ongoing for Rx DMA Handle. + * @param hdma DMA handle. + * @retval None + */ +static void SPI_DMATxAbortCallback(DMA_HandleTypeDef *hdma) +{ + SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + hspi->hdmatx->XferAbortCallback = NULL; + + /* Check if an Abort process is still ongoing */ + if (hspi->hdmarx != NULL) + { + if (hspi->hdmarx->XferAbortCallback != NULL) + { + return; + } + } + + /* Call the Abort procedure */ + SPI_AbortTransfer(hspi); + + /* Restore hspi->State to Ready */ + hspi->State = HAL_SPI_STATE_READY; + + /* Call user Abort complete callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) + hspi->AbortCpltCallback(hspi); +#else + HAL_SPI_AbortCpltCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA SPI Rx communication abort callback, when initiated by user + * (To be called at end of DMA Rx Abort procedure following user abort request). + * @note When this callback is executed, User Abort complete call back is called only if no + * Abort still ongoing for Tx DMA Handle. + * @param hdma DMA handle. + * @retval None + */ +static void SPI_DMARxAbortCallback(DMA_HandleTypeDef *hdma) +{ + SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + hspi->hdmarx->XferAbortCallback = NULL; + + /* Check if an Abort process is still ongoing */ + if (hspi->hdmatx != NULL) + { + if (hspi->hdmatx->XferAbortCallback != NULL) + { + return; + } + } + + /* Call the Abort procedure */ + SPI_AbortTransfer(hspi); + + /* Restore hspi->State to Ready */ + hspi->State = HAL_SPI_STATE_READY; + + /* Call user Abort complete callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) + hspi->AbortCpltCallback(hspi); +#else + HAL_SPI_AbortCpltCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Manage the receive 8-bit in Interrupt context. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +static void SPI_RxISR_8BIT(SPI_HandleTypeDef *hspi) +{ + /* Receive data in 8 Bit mode */ + *((uint8_t *)hspi->pRxBuffPtr) = (*(__IO uint8_t *)&hspi->Instance->RXDR); + hspi->pRxBuffPtr += sizeof(uint8_t); + hspi->RxXferCount--; + + /* Disable IT if no more data excepted */ + if (hspi->RxXferCount == 0UL) + { + /* Disable RXP interrupts */ + __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXP); + } +} + + +/** + * @brief Manage the 16-bit receive in Interrupt context. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +static void SPI_RxISR_16BIT(SPI_HandleTypeDef *hspi) +{ + /* Receive data in 16 Bit mode */ +#if defined (__GNUC__) + __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->RXDR)); + + *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits; +#else + *((uint16_t *)hspi->pRxBuffPtr) = (*(__IO uint16_t *)&hspi->Instance->RXDR); +#endif /* __GNUC__ */ + hspi->pRxBuffPtr += sizeof(uint16_t); + hspi->RxXferCount--; + + /* Disable IT if no more data excepted */ + if (hspi->RxXferCount == 0UL) + { + /* Disable RXP interrupts */ + __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXP); + } +} + + +/** + * @brief Manage the 32-bit receive in Interrupt context. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +static void SPI_RxISR_32BIT(SPI_HandleTypeDef *hspi) +{ + /* Receive data in 32 Bit mode */ + *((uint32_t *)hspi->pRxBuffPtr) = (*(__IO uint32_t *)&hspi->Instance->RXDR); + hspi->pRxBuffPtr += sizeof(uint32_t); + hspi->RxXferCount--; + + /* Disable IT if no more data excepted */ + if (hspi->RxXferCount == 0UL) + { + /* Disable RXP interrupts */ + __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXP); + } +} + + +/** + * @brief Handle the data 8-bit transmit in Interrupt mode. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +static void SPI_TxISR_8BIT(SPI_HandleTypeDef *hspi) +{ + /* Transmit data in 8 Bit mode */ + *(__IO uint8_t *)&hspi->Instance->TXDR = *((const uint8_t *)hspi->pTxBuffPtr); + hspi->pTxBuffPtr += sizeof(uint8_t); + hspi->TxXferCount--; + + /* Disable IT if no more data excepted */ + if (hspi->TxXferCount == 0UL) + { + /* Disable TXP interrupts */ + __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXP); + } +} + +/** + * @brief Handle the data 16-bit transmit in Interrupt mode. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +static void SPI_TxISR_16BIT(SPI_HandleTypeDef *hspi) +{ + /* Transmit data in 16 Bit mode */ +#if defined (__GNUC__) + __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->TXDR)); + + *ptxdr_16bits = *((const uint16_t *)hspi->pTxBuffPtr); +#else + *((__IO uint16_t *)&hspi->Instance->TXDR) = *((const uint16_t *)hspi->pTxBuffPtr); +#endif /* __GNUC__ */ + hspi->pTxBuffPtr += sizeof(uint16_t); + hspi->TxXferCount--; + + /* Disable IT if no more data excepted */ + if (hspi->TxXferCount == 0UL) + { + /* Disable TXP interrupts */ + __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXP); + } +} + +/** + * @brief Handle the data 32-bit transmit in Interrupt mode. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +static void SPI_TxISR_32BIT(SPI_HandleTypeDef *hspi) +{ + /* Transmit data in 32 Bit mode */ + *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr); + hspi->pTxBuffPtr += sizeof(uint32_t); + hspi->TxXferCount--; + + /* Disable IT if no more data excepted */ + if (hspi->TxXferCount == 0UL) + { + /* Disable TXP interrupts */ + __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXP); + } +} + +/** + * @brief Abort Transfer and clear flags. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +static void SPI_AbortTransfer(SPI_HandleTypeDef *hspi) +{ + /* Disable SPI peripheral */ + __HAL_SPI_DISABLE(hspi); + + /* Disable ITs */ + __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_TXP | SPI_IT_RXP | SPI_IT_DXP | SPI_IT_UDR | SPI_IT_OVR | \ + SPI_IT_FRE | SPI_IT_MODF)); + + /* Clear the Status flags in the SR register */ + __HAL_SPI_CLEAR_EOTFLAG(hspi); + __HAL_SPI_CLEAR_TXTFFLAG(hspi); + + /* Disable Tx DMA Request */ + CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN); + + /* Clear the Error flags in the SR register */ + __HAL_SPI_CLEAR_OVRFLAG(hspi); + __HAL_SPI_CLEAR_UDRFLAG(hspi); + __HAL_SPI_CLEAR_FREFLAG(hspi); + __HAL_SPI_CLEAR_MODFFLAG(hspi); + __HAL_SPI_CLEAR_SUSPFLAG(hspi); + +#if (USE_SPI_CRC != 0U) + __HAL_SPI_CLEAR_CRCERRFLAG(hspi); +#endif /* USE_SPI_CRC */ + + hspi->TxXferCount = (uint16_t)0UL; + hspi->RxXferCount = (uint16_t)0UL; +} + + +/** + * @brief Close Transfer and clear flags. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval HAL_ERROR: if any error detected + * HAL_OK: if nothing detected + */ +static void SPI_CloseTransfer(SPI_HandleTypeDef *hspi) +{ + uint32_t itflag = hspi->Instance->SR; + + __HAL_SPI_CLEAR_EOTFLAG(hspi); + __HAL_SPI_CLEAR_TXTFFLAG(hspi); + + /* Disable SPI peripheral */ + __HAL_SPI_DISABLE(hspi); + + /* Disable ITs */ + __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_TXP | SPI_IT_RXP | SPI_IT_DXP | SPI_IT_UDR | SPI_IT_OVR | \ + SPI_IT_FRE | SPI_IT_MODF)); + + /* Disable Tx DMA Request */ + CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN); + + /* Report UnderRun error for non RX Only communication */ + if (hspi->State != HAL_SPI_STATE_BUSY_RX) + { + if ((itflag & SPI_FLAG_UDR) != 0UL) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_UDR); + __HAL_SPI_CLEAR_UDRFLAG(hspi); + } + } + + /* Report OverRun error for non TX Only communication */ + if (hspi->State != HAL_SPI_STATE_BUSY_TX) + { + if ((itflag & SPI_FLAG_OVR) != 0UL) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_OVR); + __HAL_SPI_CLEAR_OVRFLAG(hspi); + } + +#if (USE_SPI_CRC != 0UL) + /* Check if CRC error occurred */ + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + if ((itflag & SPI_FLAG_CRCERR) != 0UL) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); + __HAL_SPI_CLEAR_CRCERRFLAG(hspi); + } + } +#endif /* USE_SPI_CRC */ + } + + /* SPI Mode Fault error interrupt occurred -------------------------------*/ + if ((itflag & SPI_FLAG_MODF) != 0UL) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_MODF); + __HAL_SPI_CLEAR_MODFFLAG(hspi); + } + + /* SPI Frame error interrupt occurred ------------------------------------*/ + if ((itflag & SPI_FLAG_FRE) != 0UL) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FRE); + __HAL_SPI_CLEAR_FREFLAG(hspi); + } + + hspi->TxXferCount = (uint16_t)0UL; + hspi->RxXferCount = (uint16_t)0UL; +} + +/** + * @brief Handle SPI Communication Timeout. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param Flag: SPI flag to check + * @param Status: flag state to check + * @param Timeout: Timeout duration + * @param Tickstart: Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef SPI_WaitOnFlagUntilTimeout(const SPI_HandleTypeDef *hspi, uint32_t Flag, FlagStatus Status, + uint32_t Timeout, uint32_t Tickstart) +{ + /* Wait until flag is set */ + while ((__HAL_SPI_GET_FLAG(hspi, Flag) ? SET : RESET) == Status) + { + /* Check for the Timeout */ + if ((((HAL_GetTick() - Tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U)) + { + return HAL_TIMEOUT; + } + } + return HAL_OK; +} + +/** + * @brief Compute configured packet size from fifo perspective. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval Packet size occupied in the fifo + */ +static uint32_t SPI_GetPacketSize(const SPI_HandleTypeDef *hspi) +{ + uint32_t fifo_threashold = (hspi->Init.FifoThreshold >> SPI_CFG1_FTHLV_Pos) + 1UL; + uint32_t data_size = (hspi->Init.DataSize >> SPI_CFG1_DSIZE_Pos) + 1UL; + + /* Convert data size to Byte */ + data_size = (data_size + 7UL) / 8UL; + + return data_size * fifo_threashold; +} + +/** + * @} + */ + +#endif /* HAL_SPI_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_spi_ex.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_spi_ex.c new file mode 100644 index 0000000000..6df6b9b5e9 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_spi_ex.c @@ -0,0 +1,228 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_spi_ex.c + * @author MCD Application Team + * @brief Extended SPI HAL module driver. + * This file provides firmware functions to manage the following + * SPI peripheral extended functionalities : + * + IO operation functions + * + Peripheral Control functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup SPIEx SPIEx + * @brief SPI Extended HAL module driver + * @{ + */ +#ifdef HAL_SPI_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup SPIEx_Exported_Functions SPIEx Exported Functions + * @{ + */ + +/** @defgroup SPIEx_Exported_Functions_Group1 IO operation functions + * @brief Data transfers functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of extended functions to manage the SPI + data transfers. + + (#) SPIEx function: + (++) HAL_SPIEx_FlushRxFifo() + (++) HAL_SPIEx_FlushRxFifo() + (++) HAL_SPIEx_EnableLockConfiguration() + (++) HAL_SPIEx_ConfigureUnderrun() + +@endverbatim + * @{ + */ + +/** + * @brief Flush the RX fifo. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for the specified SPI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPIEx_FlushRxFifo(const SPI_HandleTypeDef *hspi) +{ + uint8_t count = 0; + uint32_t itflag = hspi->Instance->SR; + __IO uint32_t tmpreg; + + while (((hspi->Instance->SR & SPI_FLAG_FRLVL) != SPI_RX_FIFO_0PACKET) || ((itflag & SPI_FLAG_RXWNE) != 0UL)) + { + count += (uint8_t)4UL; + tmpreg = hspi->Instance->RXDR; + UNUSED(tmpreg); /* To avoid GCC warning */ + + if (IS_SPI_FULL_INSTANCE(hspi->Instance)) + { + if (count > SPI_HIGHEND_FIFO_SIZE) + { + return HAL_TIMEOUT; + } + } + else + { + if (count > SPI_LOWEND_FIFO_SIZE) + { + return HAL_TIMEOUT; + } + } + } + return HAL_OK; +} + + +/** + * @brief Enable the Lock for the AF configuration of associated IOs + * and write protect the Content of Configuration register 2 + * when SPI is enabled + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +HAL_StatusTypeDef HAL_SPIEx_EnableLockConfiguration(SPI_HandleTypeDef *hspi) +{ + HAL_StatusTypeDef errorcode = HAL_OK; + + /* Process Locked */ + __HAL_LOCK(hspi); + + if (hspi->State != HAL_SPI_STATE_READY) + { + errorcode = HAL_BUSY; + hspi->State = HAL_SPI_STATE_READY; + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + return errorcode; + } + + /* Check if the SPI is disabled to edit IOLOCK bit */ + if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) + { + SET_BIT(hspi->Instance->CR1, SPI_CR1_IOLOCK); + } + else + { + /* Disable SPI peripheral */ + __HAL_SPI_DISABLE(hspi); + + SET_BIT(hspi->Instance->CR1, SPI_CR1_IOLOCK); + + /* Enable SPI peripheral */ + __HAL_SPI_ENABLE(hspi); + } + + hspi->State = HAL_SPI_STATE_READY; + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + return errorcode; +} + +/** + * @brief Configure the UNDERRUN condition and behavior of slave transmitter. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param UnderrunDetection : Detection of underrun condition at slave transmitter + * This parameter is not supported in this SPI version. + * It is kept in order to not break the compatibility. + * @param UnderrunBehaviour : Behavior of slave transmitter at underrun condition + * This parameter can be a value of @ref SPI_Underrun_Behaviour. + * @retval None + */ +HAL_StatusTypeDef HAL_SPIEx_ConfigureUnderrun(SPI_HandleTypeDef *hspi, uint32_t UnderrunDetection, + uint32_t UnderrunBehaviour) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(UnderrunDetection); + + HAL_StatusTypeDef errorcode = HAL_OK; + + /* Process Locked */ + __HAL_LOCK(hspi); + + /* Check State and Insure that Underrun configuration is managed only by Salve */ + if ((hspi->State != HAL_SPI_STATE_READY) || (hspi->Init.Mode != SPI_MODE_SLAVE)) + { + errorcode = HAL_BUSY; + hspi->State = HAL_SPI_STATE_READY; + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + return errorcode; + } + + /* Check the parameters */ + assert_param(IS_SPI_UNDERRUN_BEHAVIOUR(UnderrunBehaviour)); + + /* Check if the SPI is disabled to edit CFG1 register */ + if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) + { + /* Configure Underrun fields */ + MODIFY_REG(hspi->Instance->CFG1, SPI_CFG1_UDRCFG, UnderrunBehaviour); + } + else + { + /* Disable SPI peripheral */ + __HAL_SPI_DISABLE(hspi); + + /* Configure Underrun fields */ + MODIFY_REG(hspi->Instance->CFG1, SPI_CFG1_UDRCFG, UnderrunBehaviour); + + /* Enable SPI peripheral */ + __HAL_SPI_ENABLE(hspi); + } + + + hspi->State = HAL_SPI_STATE_READY; + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + return errorcode; +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_SPI_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sram.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sram.c new file mode 100644 index 0000000000..0769a12e44 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_sram.c @@ -0,0 +1,1238 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_sram.c + * @author MCD Application Team + * @brief SRAM HAL module driver. + * This file provides a generic firmware to drive SRAM memories + * mounted as external device. + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2022 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 ##### + ============================================================================== + [..] + This driver is a generic layered driver which contains a set of APIs used to + control SRAM memories. It uses the FMC layer functions to interface + with SRAM devices. + The following sequence should be followed to configure the FMC to interface + with SRAM/PSRAM memories: + + (#) Declare a SRAM_HandleTypeDef handle structure, for example: + SRAM_HandleTypeDef hsram; and: + + (++) Fill the SRAM_HandleTypeDef handle "Init" field with the allowed + values of the structure member. + + (++) Fill the SRAM_HandleTypeDef handle "Instance" field with a predefined + base register instance for NOR or SRAM device + + (++) Fill the SRAM_HandleTypeDef handle "Extended" field with a predefined + base register instance for NOR or SRAM extended mode + + (#) Declare two FMC_NORSRAM_TimingTypeDef structures, for both normal and extended + mode timings; for example: + FMC_NORSRAM_TimingTypeDef Timing and FMC_NORSRAM_TimingTypeDef ExTiming; + and fill its fields with the allowed values of the structure member. + + (#) Initialize the SRAM Controller by calling the function HAL_SRAM_Init(). This function + performs the following sequence: + + (##) MSP hardware layer configuration using the function HAL_SRAM_MspInit() + (##) Control register configuration using the FMC NORSRAM interface function + FMC_NORSRAM_Init() + (##) Timing register configuration using the FMC NORSRAM interface function + FMC_NORSRAM_Timing_Init() + (##) Extended mode Timing register configuration using the FMC NORSRAM interface function + FMC_NORSRAM_Extended_Timing_Init() + (##) Enable the SRAM device using the macro __FMC_NORSRAM_ENABLE() + + (#) At this stage you can perform read/write accesses from/to the memory connected + to the NOR/SRAM Bank. You can perform either polling or DMA transfer using the + following APIs: + (++) HAL_SRAM_Read()/HAL_SRAM_Write() for polling read/write access + (++) HAL_SRAM_Read_DMA()/HAL_SRAM_Write_DMA() for DMA read/write transfer + + (#) You can also control the SRAM device by calling the control APIs HAL_SRAM_WriteOperation_Enable()/ + HAL_SRAM_WriteOperation_Disable() to respectively enable/disable the SRAM write operation + + (#) You can continuously monitor the SRAM device HAL state by calling the function + HAL_SRAM_GetState() + + *** Callback registration *** + ============================================= + [..] + The compilation define USE_HAL_SRAM_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + + Use Functions HAL_SRAM_RegisterCallback() to register a user callback, + it allows to register following callbacks: + (+) MspInitCallback : SRAM MspInit. + (+) MspDeInitCallback : SRAM MspDeInit. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + + Use function HAL_SRAM_UnRegisterCallback() to reset a callback to the default + weak (overridden) function. It allows to reset following callbacks: + (+) MspInitCallback : SRAM MspInit. + (+) MspDeInitCallback : SRAM MspDeInit. + This function) takes as parameters the HAL peripheral handle and the Callback ID. + + By default, after the HAL_SRAM_Init and if the state is HAL_SRAM_STATE_RESET + all callbacks are reset to the corresponding legacy weak (overridden) functions. + Exception done for MspInit and MspDeInit callbacks that are respectively + reset to the legacy weak (overridden) functions in the HAL_SRAM_Init + and HAL_SRAM_DeInit only when these callbacks are null (not registered beforehand). + If not, MspInit or MspDeInit are not null, the HAL_SRAM_Init and HAL_SRAM_DeInit + keep and use the user MspInit/MspDeInit callbacks (registered beforehand) + + Callbacks can be registered/unregistered in READY state only. + Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered + in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used + during the Init/DeInit. + In that case first register the MspInit/MspDeInit user callbacks + using HAL_SRAM_RegisterCallback before calling HAL_SRAM_DeInit + or HAL_SRAM_Init function. + + When The compilation define USE_HAL_SRAM_REGISTER_CALLBACKS is set to 0 or + not defined, the callback registering feature is not available + and weak (overridden) callbacks are used. + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +#if defined(FMC_BANK1) + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +#ifdef HAL_SRAM_MODULE_ENABLED + +/** @defgroup SRAM SRAM + * @brief SRAM driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup SRAM_Private_Functions SRAM Private Functions + * @{ + */ +static void SRAM_DMACplt(DMA_HandleTypeDef *hdma); +static void SRAM_DMACpltProt(DMA_HandleTypeDef *hdma); +static void SRAM_DMAError(DMA_HandleTypeDef *hdma); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup SRAM_Exported_Functions SRAM Exported Functions + * @{ + */ + +/** @defgroup SRAM_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions. + * + @verbatim + ============================================================================== + ##### SRAM Initialization and de_initialization functions ##### + ============================================================================== + [..] This section provides functions allowing to initialize/de-initialize + the SRAM memory + +@endverbatim + * @{ + */ + +/** + * @brief Performs the SRAM device initialization sequence + * @param hsram pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @param Timing Pointer to SRAM control timing structure + * @param ExtTiming Pointer to SRAM extended mode timing structure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SRAM_Init(SRAM_HandleTypeDef *hsram, FMC_NORSRAM_TimingTypeDef *Timing, + FMC_NORSRAM_TimingTypeDef *ExtTiming) +{ + /* Check the SRAM handle parameter */ + if (hsram == NULL) + { + return HAL_ERROR; + } + + if (hsram->State == HAL_SRAM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hsram->Lock = HAL_UNLOCKED; + +#if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1) + if (hsram->MspInitCallback == NULL) + { + hsram->MspInitCallback = HAL_SRAM_MspInit; + } + hsram->DmaXferCpltCallback = HAL_SRAM_DMA_XferCpltCallback; + hsram->DmaXferErrorCallback = HAL_SRAM_DMA_XferErrorCallback; + + /* Init the low level hardware */ + hsram->MspInitCallback(hsram); +#else + /* Initialize the low level hardware (MSP) */ + HAL_SRAM_MspInit(hsram); +#endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */ + } + + /* Initialize SRAM control Interface */ + (void)FMC_NORSRAM_Init(hsram->Instance, &(hsram->Init)); + + /* Initialize SRAM timing Interface */ + (void)FMC_NORSRAM_Timing_Init(hsram->Instance, Timing, hsram->Init.NSBank); + + /* Initialize SRAM extended mode timing Interface */ + (void)FMC_NORSRAM_Extended_Timing_Init(hsram->Extended, ExtTiming, hsram->Init.NSBank, + hsram->Init.ExtendedMode); + + /* Enable the NORSRAM device */ + __FMC_NORSRAM_ENABLE(hsram->Instance, hsram->Init.NSBank); + + /* Enable FMC Peripheral */ + __FMC_ENABLE(); + + /* Initialize the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Performs the SRAM device De-initialization sequence. + * @param hsram pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SRAM_DeInit(SRAM_HandleTypeDef *hsram) +{ +#if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1) + if (hsram->MspDeInitCallback == NULL) + { + hsram->MspDeInitCallback = HAL_SRAM_MspDeInit; + } + + /* DeInit the low level hardware */ + hsram->MspDeInitCallback(hsram); +#else + /* De-Initialize the low level hardware (MSP) */ + HAL_SRAM_MspDeInit(hsram); +#endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */ + + /* Configure the SRAM registers with their reset values */ + (void)FMC_NORSRAM_DeInit(hsram->Instance, hsram->Extended, hsram->Init.NSBank); + + /* Reset the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hsram); + + return HAL_OK; +} + +/** + * @brief SRAM MSP Init. + * @param hsram pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @retval None + */ +__weak void HAL_SRAM_MspInit(SRAM_HandleTypeDef *hsram) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsram); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SRAM_MspInit could be implemented in the user file + */ +} + +/** + * @brief SRAM MSP DeInit. + * @param hsram pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @retval None + */ +__weak void HAL_SRAM_MspDeInit(SRAM_HandleTypeDef *hsram) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hsram); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SRAM_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief DMA transfer complete callback. + * @param hdma pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @retval None + */ +__weak void HAL_SRAM_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdma); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SRAM_DMA_XferCpltCallback could be implemented in the user file + */ +} + +/** + * @brief DMA transfer complete error callback. + * @param hdma pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @retval None + */ +__weak void HAL_SRAM_DMA_XferErrorCallback(DMA_HandleTypeDef *hdma) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hdma); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SRAM_DMA_XferErrorCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup SRAM_Exported_Functions_Group2 Input Output and memory control functions + * @brief Input Output and memory control functions + * + @verbatim + ============================================================================== + ##### SRAM Input and Output functions ##### + ============================================================================== + [..] + This section provides functions allowing to use and control the SRAM memory + +@endverbatim + * @{ + */ + +/** + * @brief Reads 8-bit buffer from SRAM memory. + * @param hsram pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @param pAddress Pointer to read start address + * @param pDstBuffer Pointer to destination buffer + * @param BufferSize Size of the buffer to read from memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SRAM_Read_8b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint8_t *pDstBuffer, + uint32_t BufferSize) +{ + uint32_t size; + __IO uint8_t *psramaddress = (uint8_t *)pAddress; + uint8_t *pdestbuff = pDstBuffer; + HAL_SRAM_StateTypeDef state = hsram->State; + + /* Check the SRAM controller state */ + if ((state == HAL_SRAM_STATE_READY) || (state == HAL_SRAM_STATE_PROTECTED)) + { + /* Process Locked */ + __HAL_LOCK(hsram); + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_BUSY; + + /* Read data from memory */ + for (size = BufferSize; size != 0U; size--) + { + *pdestbuff = *psramaddress; + pdestbuff++; + psramaddress++; + } + + /* Update the SRAM controller state */ + hsram->State = state; + + /* Process unlocked */ + __HAL_UNLOCK(hsram); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Writes 8-bit buffer to SRAM memory. + * @param hsram pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @param pAddress Pointer to write start address + * @param pSrcBuffer Pointer to source buffer to write + * @param BufferSize Size of the buffer to write to memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SRAM_Write_8b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint8_t *pSrcBuffer, + uint32_t BufferSize) +{ + uint32_t size; + __IO uint8_t *psramaddress = (uint8_t *)pAddress; + uint8_t *psrcbuff = pSrcBuffer; + + /* Check the SRAM controller state */ + if (hsram->State == HAL_SRAM_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsram); + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_BUSY; + + /* Write data to memory */ + for (size = BufferSize; size != 0U; size--) + { + *psramaddress = *psrcbuff; + psrcbuff++; + psramaddress++; + } + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hsram); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Reads 16-bit buffer from SRAM memory. + * @param hsram pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @param pAddress Pointer to read start address + * @param pDstBuffer Pointer to destination buffer + * @param BufferSize Size of the buffer to read from memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SRAM_Read_16b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint16_t *pDstBuffer, + uint32_t BufferSize) +{ + uint32_t size; + __IO uint32_t *psramaddress = pAddress; + uint16_t *pdestbuff = pDstBuffer; + uint8_t limit; + HAL_SRAM_StateTypeDef state = hsram->State; + + /* Check the SRAM controller state */ + if ((state == HAL_SRAM_STATE_READY) || (state == HAL_SRAM_STATE_PROTECTED)) + { + /* Process Locked */ + __HAL_LOCK(hsram); + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_BUSY; + + /* Check if the size is a 32-bits multiple */ + limit = (((BufferSize % 2U) != 0U) ? 1U : 0U); + + /* Read data from memory */ + for (size = BufferSize; size != limit; size -= 2U) + { + *pdestbuff = (uint16_t)((*psramaddress) & 0x0000FFFFU); + pdestbuff++; + *pdestbuff = (uint16_t)(((*psramaddress) & 0xFFFF0000U) >> 16U); + pdestbuff++; + psramaddress++; + } + + /* Read last 16-bits if size is not 32-bits multiple */ + if (limit != 0U) + { + *pdestbuff = (uint16_t)((*psramaddress) & 0x0000FFFFU); + } + + /* Update the SRAM controller state */ + hsram->State = state; + + /* Process unlocked */ + __HAL_UNLOCK(hsram); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Writes 16-bit buffer to SRAM memory. + * @param hsram pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @param pAddress Pointer to write start address + * @param pSrcBuffer Pointer to source buffer to write + * @param BufferSize Size of the buffer to write to memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SRAM_Write_16b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint16_t *pSrcBuffer, + uint32_t BufferSize) +{ + uint32_t size; + __IO uint32_t *psramaddress = pAddress; + uint16_t *psrcbuff = pSrcBuffer; + uint8_t limit; + + /* Check the SRAM controller state */ + if (hsram->State == HAL_SRAM_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsram); + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_BUSY; + + /* Check if the size is a 32-bits multiple */ + limit = (((BufferSize % 2U) != 0U) ? 1U : 0U); + + /* Write data to memory */ + for (size = BufferSize; size != limit; size -= 2U) + { + *psramaddress = (uint32_t)(*psrcbuff); + psrcbuff++; + *psramaddress |= ((uint32_t)(*psrcbuff) << 16U); + psrcbuff++; + psramaddress++; + } + + /* Write last 16-bits if size is not 32-bits multiple */ + if (limit != 0U) + { + *psramaddress = ((uint32_t)(*psrcbuff) & 0x0000FFFFU) | ((*psramaddress) & 0xFFFF0000U); + } + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hsram); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Reads 32-bit buffer from SRAM memory. + * @param hsram pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @param pAddress Pointer to read start address + * @param pDstBuffer Pointer to destination buffer + * @param BufferSize Size of the buffer to read from memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SRAM_Read_32b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pDstBuffer, + uint32_t BufferSize) +{ + uint32_t size; + __IO uint32_t *psramaddress = pAddress; + uint32_t *pdestbuff = pDstBuffer; + HAL_SRAM_StateTypeDef state = hsram->State; + + /* Check the SRAM controller state */ + if ((state == HAL_SRAM_STATE_READY) || (state == HAL_SRAM_STATE_PROTECTED)) + { + /* Process Locked */ + __HAL_LOCK(hsram); + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_BUSY; + + /* Read data from memory */ + for (size = BufferSize; size != 0U; size--) + { + *pdestbuff = *psramaddress; + pdestbuff++; + psramaddress++; + } + + /* Update the SRAM controller state */ + hsram->State = state; + + /* Process unlocked */ + __HAL_UNLOCK(hsram); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Writes 32-bit buffer to SRAM memory. + * @param hsram pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @param pAddress Pointer to write start address + * @param pSrcBuffer Pointer to source buffer to write + * @param BufferSize Size of the buffer to write to memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SRAM_Write_32b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pSrcBuffer, + uint32_t BufferSize) +{ + uint32_t size; + __IO uint32_t *psramaddress = pAddress; + uint32_t *psrcbuff = pSrcBuffer; + + /* Check the SRAM controller state */ + if (hsram->State == HAL_SRAM_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsram); + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_BUSY; + + /* Write data to memory */ + for (size = BufferSize; size != 0U; size--) + { + *psramaddress = *psrcbuff; + psrcbuff++; + psramaddress++; + } + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hsram); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Reads a Words data from the SRAM memory using DMA transfer. + * @param hsram pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @param pAddress Pointer to read start address + * @param pDstBuffer Pointer to destination buffer + * @param BufferSize Size of the buffer to read from memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SRAM_Read_DMA(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pDstBuffer, + uint32_t BufferSize) +{ + HAL_StatusTypeDef status; + HAL_SRAM_StateTypeDef state = hsram->State; + uint32_t size; + uint32_t data_width; + + /* Check the SRAM controller state */ + if ((state == HAL_SRAM_STATE_READY) || (state == HAL_SRAM_STATE_PROTECTED)) + { + /* Process Locked */ + __HAL_LOCK(hsram); + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_BUSY; + + /* Configure DMA user callbacks */ + if (state == HAL_SRAM_STATE_READY) + { + hsram->hdma->XferCpltCallback = SRAM_DMACplt; + } + else + { + hsram->hdma->XferCpltCallback = SRAM_DMACpltProt; + } + hsram->hdma->XferErrorCallback = SRAM_DMAError; + + if ((hsram->hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hsram->hdma->LinkedListQueue != 0U) && (hsram->hdma->LinkedListQueue->Head != 0U)) + { + /* Check destination data width and set the size to be transferred */ + data_width = hsram->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] & DMA_CTR1_DDW_LOG2; + + if (data_width == DMA_DEST_DATAWIDTH_WORD) + { + size = (BufferSize * 4U); + } + else if (data_width == DMA_DEST_DATAWIDTH_HALFWORD) + { + size = (BufferSize * 2U); + } + else + { + size = (BufferSize); + } + /* Set Source , destination , buffer size */ + /* Set DMA data size */ + hsram->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = size; + /* Set DMA source address */ + hsram->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)pAddress; + /* Set DMA destination address */ + hsram->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)pDstBuffer; + + /* Enable the DMA Stream */ + status = HAL_DMAEx_List_Start_IT(hsram->hdma); + } + else + { + /* Change SRAM state */ + hsram->State = HAL_SRAM_STATE_READY; + + __HAL_UNLOCK(hsram); + + status = HAL_ERROR; + } + } + else + { + /* Check destination data width and set the size to be transferred */ + data_width = hsram->hdma->Init.DestDataWidth; + + if (data_width == DMA_DEST_DATAWIDTH_WORD) + { + size = (BufferSize * 4U); + } + else if (data_width == DMA_DEST_DATAWIDTH_HALFWORD) + { + size = (BufferSize * 2U); + } + else + { + size = (BufferSize); + } + + /* Enable the DMA Stream */ + status = HAL_DMA_Start_IT(hsram->hdma, (uint32_t)pAddress, (uint32_t)pDstBuffer, size); + } + + /* Process unlocked */ + __HAL_UNLOCK(hsram); + } + else + { + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Writes a Words data buffer to SRAM memory using DMA transfer. + * @param hsram pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @param pAddress Pointer to write start address + * @param pSrcBuffer Pointer to source buffer to write + * @param BufferSize Size of the buffer to write to memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SRAM_Write_DMA(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pSrcBuffer, + uint32_t BufferSize) +{ + HAL_StatusTypeDef status; + uint32_t size; + uint32_t data_width; + + /* Check the SRAM controller state */ + if (hsram->State == HAL_SRAM_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsram); + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_BUSY; + + /* Configure DMA user callbacks */ + hsram->hdma->XferCpltCallback = SRAM_DMACplt; + hsram->hdma->XferErrorCallback = SRAM_DMAError; + + if ((hsram->hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hsram->hdma->LinkedListQueue != 0U) && (hsram->hdma->LinkedListQueue->Head != 0U)) + { + /* Check destination data width and set the size to be transferred */ + data_width = hsram->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] & DMA_CTR1_DDW_LOG2; + + if (data_width == DMA_DEST_DATAWIDTH_WORD) + { + size = (BufferSize * 4U); + } + else if (data_width == DMA_DEST_DATAWIDTH_HALFWORD) + { + size = (BufferSize * 2U); + } + else + { + size = (BufferSize); + } + /* Set Source , destination , buffer size */ + /* Set DMA data size */ + hsram->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = size; + /* Set DMA source address */ + hsram->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)pSrcBuffer; + /* Set DMA destination address */ + hsram->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)pAddress; + /* Enable the DMA Stream */ + status = HAL_DMAEx_List_Start_IT(hsram->hdma); + } + else + { + /* Change SRAM state */ + hsram->State = HAL_SRAM_STATE_READY; + + __HAL_UNLOCK(hsram); + + status = HAL_ERROR; + } + } + else + { + /* Check destination data width and set the size to be transferred */ + data_width = hsram->hdma->Init.DestDataWidth; + + if (data_width == DMA_DEST_DATAWIDTH_WORD) + { + size = (BufferSize * 4U); + } + else if (data_width == DMA_DEST_DATAWIDTH_HALFWORD) + { + size = (BufferSize * 2U); + } + else + { + size = (BufferSize); + } + + /* Enable the DMA Stream */ + status = HAL_DMA_Start_IT(hsram->hdma, (uint32_t)pSrcBuffer, (uint32_t)pAddress, size); + } + + /* Process unlocked */ + __HAL_UNLOCK(hsram); + } + else + { + status = HAL_ERROR; + } + + return status; +} + +#if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User SRAM Callback + * To be used to override the weak predefined callback + * @param hsram : SRAM handle + * @param CallbackId : ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_SRAM_MSP_INIT_CB_ID SRAM MspInit callback ID + * @arg @ref HAL_SRAM_MSP_DEINIT_CB_ID SRAM MspDeInit callback ID + * @param pCallback : pointer to the Callback function + * @retval status + */ +HAL_StatusTypeDef HAL_SRAM_RegisterCallback(SRAM_HandleTypeDef *hsram, HAL_SRAM_CallbackIDTypeDef CallbackId, + pSRAM_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + HAL_SRAM_StateTypeDef state; + + if (pCallback == NULL) + { + return HAL_ERROR; + } + + state = hsram->State; + if ((state == HAL_SRAM_STATE_READY) || (state == HAL_SRAM_STATE_RESET) || (state == HAL_SRAM_STATE_PROTECTED)) + { + switch (CallbackId) + { + case HAL_SRAM_MSP_INIT_CB_ID : + hsram->MspInitCallback = pCallback; + break; + case HAL_SRAM_MSP_DEINIT_CB_ID : + hsram->MspDeInitCallback = pCallback; + break; + default : + /* update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* update return status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister a User SRAM Callback + * SRAM Callback is redirected to the weak predefined callback + * @param hsram : SRAM handle + * @param CallbackId : ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_SRAM_MSP_INIT_CB_ID SRAM MspInit callback ID + * @arg @ref HAL_SRAM_MSP_DEINIT_CB_ID SRAM MspDeInit callback ID + * @arg @ref HAL_SRAM_DMA_XFER_CPLT_CB_ID SRAM DMA Xfer Complete callback ID + * @arg @ref HAL_SRAM_DMA_XFER_ERR_CB_ID SRAM DMA Xfer Error callback ID + * @retval status + */ +HAL_StatusTypeDef HAL_SRAM_UnRegisterCallback(SRAM_HandleTypeDef *hsram, HAL_SRAM_CallbackIDTypeDef CallbackId) +{ + HAL_StatusTypeDef status = HAL_OK; + HAL_SRAM_StateTypeDef state; + + state = hsram->State; + if ((state == HAL_SRAM_STATE_READY) || (state == HAL_SRAM_STATE_PROTECTED)) + { + switch (CallbackId) + { + case HAL_SRAM_MSP_INIT_CB_ID : + hsram->MspInitCallback = HAL_SRAM_MspInit; + break; + case HAL_SRAM_MSP_DEINIT_CB_ID : + hsram->MspDeInitCallback = HAL_SRAM_MspDeInit; + break; + case HAL_SRAM_DMA_XFER_CPLT_CB_ID : + hsram->DmaXferCpltCallback = HAL_SRAM_DMA_XferCpltCallback; + break; + case HAL_SRAM_DMA_XFER_ERR_CB_ID : + hsram->DmaXferErrorCallback = HAL_SRAM_DMA_XferErrorCallback; + break; + default : + /* update return status */ + status = HAL_ERROR; + break; + } + } + else if (state == HAL_SRAM_STATE_RESET) + { + switch (CallbackId) + { + case HAL_SRAM_MSP_INIT_CB_ID : + hsram->MspInitCallback = HAL_SRAM_MspInit; + break; + case HAL_SRAM_MSP_DEINIT_CB_ID : + hsram->MspDeInitCallback = HAL_SRAM_MspDeInit; + break; + default : + /* update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* update return status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Register a User SRAM Callback for DMA transfers + * To be used to override the weak predefined callback + * @param hsram : SRAM handle + * @param CallbackId : ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_SRAM_DMA_XFER_CPLT_CB_ID SRAM DMA Xfer Complete callback ID + * @arg @ref HAL_SRAM_DMA_XFER_ERR_CB_ID SRAM DMA Xfer Error callback ID + * @param pCallback : pointer to the Callback function + * @retval status + */ +HAL_StatusTypeDef HAL_SRAM_RegisterDmaCallback(SRAM_HandleTypeDef *hsram, HAL_SRAM_CallbackIDTypeDef CallbackId, + pSRAM_DmaCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + HAL_SRAM_StateTypeDef state; + + if (pCallback == NULL) + { + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hsram); + + state = hsram->State; + if ((state == HAL_SRAM_STATE_READY) || (state == HAL_SRAM_STATE_PROTECTED)) + { + switch (CallbackId) + { + case HAL_SRAM_DMA_XFER_CPLT_CB_ID : + hsram->DmaXferCpltCallback = pCallback; + break; + case HAL_SRAM_DMA_XFER_ERR_CB_ID : + hsram->DmaXferErrorCallback = pCallback; + break; + default : + /* update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* update return status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hsram); + return status; +} +#endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup SRAM_Exported_Functions_Group3 Control functions + * @brief Control functions + * +@verbatim + ============================================================================== + ##### SRAM Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control dynamically + the SRAM interface. + +@endverbatim + * @{ + */ + +/** + * @brief Enables dynamically SRAM write operation. + * @param hsram pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SRAM_WriteOperation_Enable(SRAM_HandleTypeDef *hsram) +{ + /* Check the SRAM controller state */ + if (hsram->State == HAL_SRAM_STATE_PROTECTED) + { + /* Process Locked */ + __HAL_LOCK(hsram); + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_BUSY; + + /* Enable write operation */ + (void)FMC_NORSRAM_WriteOperation_Enable(hsram->Instance, hsram->Init.NSBank); + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hsram); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Disables dynamically SRAM write operation. + * @param hsram pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SRAM_WriteOperation_Disable(SRAM_HandleTypeDef *hsram) +{ + /* Check the SRAM controller state */ + if (hsram->State == HAL_SRAM_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsram); + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_BUSY; + + /* Disable write operation */ + (void)FMC_NORSRAM_WriteOperation_Disable(hsram->Instance, hsram->Init.NSBank); + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_PROTECTED; + + /* Process unlocked */ + __HAL_UNLOCK(hsram); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup SRAM_Exported_Functions_Group4 Peripheral State functions + * @brief Peripheral State functions + * +@verbatim + ============================================================================== + ##### SRAM State functions ##### + ============================================================================== + [..] + This subsection permits to get in run-time the status of the SRAM controller + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Returns the SRAM controller state + * @param hsram pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @retval HAL state + */ +HAL_SRAM_StateTypeDef HAL_SRAM_GetState(const SRAM_HandleTypeDef *hsram) +{ + return hsram->State; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup SRAM_Private_Functions SRAM Private Functions + * @{ + */ + +/** + * @brief DMA SRAM process complete callback. + * @param hdma : DMA handle + * @retval None + */ +static void SRAM_DMACplt(DMA_HandleTypeDef *hdma) +{ + SRAM_HandleTypeDef *hsram = (SRAM_HandleTypeDef *)(hdma->Parent); + + /* Disable the DMA channel */ + __HAL_DMA_DISABLE(hdma); + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_READY; + +#if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1) + hsram->DmaXferCpltCallback(hdma); +#else + HAL_SRAM_DMA_XferCpltCallback(hdma); +#endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA SRAM process complete callback. + * @param hdma : DMA handle + * @retval None + */ +static void SRAM_DMACpltProt(DMA_HandleTypeDef *hdma) +{ + SRAM_HandleTypeDef *hsram = (SRAM_HandleTypeDef *)(hdma->Parent); + + /* Disable the DMA channel */ + __HAL_DMA_DISABLE(hdma); + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_PROTECTED; + +#if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1) + hsram->DmaXferCpltCallback(hdma); +#else + HAL_SRAM_DMA_XferCpltCallback(hdma); +#endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA SRAM error callback. + * @param hdma : DMA handle + * @retval None + */ +static void SRAM_DMAError(DMA_HandleTypeDef *hdma) +{ + SRAM_HandleTypeDef *hsram = (SRAM_HandleTypeDef *)(hdma->Parent); + + /* Disable the DMA channel */ + __HAL_DMA_DISABLE(hdma); + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_ERROR; + +#if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1) + hsram->DmaXferErrorCallback(hdma); +#else + HAL_SRAM_DMA_XferErrorCallback(hdma); +#endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */ +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_SRAM_MODULE_ENABLED */ + +/** + * @} + */ + +#endif /* FMC_BANK1 */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_tim.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_tim.c new file mode 100644 index 0000000000..cdae141f78 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_tim.c @@ -0,0 +1,8305 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_tim.c + * @author MCD Application Team + * @brief TIM HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Timer (TIM) peripheral: + * + TIM Time Base Initialization + * + TIM Time Base Start + * + TIM Time Base Start Interruption + * + TIM Time Base Start DMA + * + TIM Output Compare/PWM Initialization + * + TIM Output Compare/PWM Channel Configuration + * + TIM Output Compare/PWM Start + * + TIM Output Compare/PWM Start Interruption + * + TIM Output Compare/PWM Start DMA + * + TIM Input Capture Initialization + * + TIM Input Capture Channel Configuration + * + TIM Input Capture Start + * + TIM Input Capture Start Interruption + * + TIM Input Capture Start DMA + * + TIM One Pulse Initialization + * + TIM One Pulse Channel Configuration + * + TIM One Pulse Start + * + TIM Encoder Interface Initialization + * + TIM Encoder Interface Start + * + TIM Encoder Interface Start Interruption + * + TIM Encoder Interface Start DMA + * + Commutation Event configuration with Interruption and DMA + * + TIM OCRef clear configuration + * + TIM External Clock configuration + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### TIMER Generic features ##### + ============================================================================== + [..] The Timer features include: + (#) 16-bit up, down, up/down auto-reload counter. + (#) 16-bit programmable prescaler allowing dividing (also on the fly) the + counter clock frequency either by any factor between 1 and 65536. + (#) Up to 4 independent channels for: + (++) Input Capture + (++) Output Compare + (++) PWM generation (Edge and Center-aligned Mode) + (++) One-pulse mode output + (#) Synchronization circuit to control the timer with external signals and to interconnect + several timers together. + (#) Supports incremental encoder for positioning purposes + + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Initialize the TIM low level resources by implementing the following functions + depending on the selected feature: + (++) Time Base : HAL_TIM_Base_MspInit() + (++) Input Capture : HAL_TIM_IC_MspInit() + (++) Output Compare : HAL_TIM_OC_MspInit() + (++) PWM generation : HAL_TIM_PWM_MspInit() + (++) One-pulse mode output : HAL_TIM_OnePulse_MspInit() + (++) Encoder mode output : HAL_TIM_Encoder_MspInit() + + (#) Initialize the TIM low level resources : + (##) Enable the TIM interface clock using __HAL_RCC_TIMx_CLK_ENABLE(); + (##) TIM pins configuration + (+++) Enable the clock for the TIM GPIOs using the following function: + __HAL_RCC_GPIOx_CLK_ENABLE(); + (+++) Configure these TIM pins in Alternate function mode using HAL_GPIO_Init(); + + (#) The external Clock can be configured, if needed (the default clock is the + internal clock from the APBx), using the following function: + HAL_TIM_ConfigClockSource, the clock configuration should be done before + any start function. + + (#) Configure the TIM in the desired functioning mode using one of the + Initialization function of this driver: + (++) HAL_TIM_Base_Init: to use the Timer to generate a simple time base + (++) HAL_TIM_OC_Init, HAL_TIM_OC_ConfigChannel and optionally HAL_TIMEx_OC_ConfigPulseOnCompare: + to use the Timer to generate an Output Compare signal. + (++) HAL_TIM_PWM_Init and HAL_TIM_PWM_ConfigChannel: to use the Timer to generate a + PWM signal. + (++) HAL_TIM_IC_Init and HAL_TIM_IC_ConfigChannel: to use the Timer to measure an + external signal. + (++) HAL_TIM_OnePulse_Init and HAL_TIM_OnePulse_ConfigChannel: to use the Timer + in One Pulse Mode. + (++) HAL_TIM_Encoder_Init: to use the Timer Encoder Interface. + + (#) Activate the TIM peripheral using one of the start functions depending from the feature used: + (++) Time Base : HAL_TIM_Base_Start(), HAL_TIM_Base_Start_DMA(), HAL_TIM_Base_Start_IT() + (++) Input Capture : HAL_TIM_IC_Start(), HAL_TIM_IC_Start_DMA(), HAL_TIM_IC_Start_IT() + (++) Output Compare : HAL_TIM_OC_Start(), HAL_TIM_OC_Start_DMA(), HAL_TIM_OC_Start_IT() + (++) PWM generation : HAL_TIM_PWM_Start(), HAL_TIM_PWM_Start_DMA(), HAL_TIM_PWM_Start_IT() + (++) One-pulse mode output : HAL_TIM_OnePulse_Start(), HAL_TIM_OnePulse_Start_IT() + (++) Encoder mode output : HAL_TIM_Encoder_Start(), HAL_TIM_Encoder_Start_DMA(), HAL_TIM_Encoder_Start_IT(). + + (#) The DMA Burst is managed with the two following functions: + HAL_TIM_DMABurst_WriteStart() + HAL_TIM_DMABurst_ReadStart() + + *** Callback registration *** + ============================================= + + [..] + The compilation define USE_HAL_TIM_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + + [..] + Use Function HAL_TIM_RegisterCallback() to register a callback. + HAL_TIM_RegisterCallback() takes as parameters the HAL peripheral handle, + the Callback ID and a pointer to the user callback function. + + [..] + Use function HAL_TIM_UnRegisterCallback() to reset a callback to the default + weak function. + HAL_TIM_UnRegisterCallback takes as parameters the HAL peripheral handle, + and the Callback ID. + + [..] + These functions allow to register/unregister following callbacks: + (+) Base_MspInitCallback : TIM Base Msp Init Callback. + (+) Base_MspDeInitCallback : TIM Base Msp DeInit Callback. + (+) IC_MspInitCallback : TIM IC Msp Init Callback. + (+) IC_MspDeInitCallback : TIM IC Msp DeInit Callback. + (+) OC_MspInitCallback : TIM OC Msp Init Callback. + (+) OC_MspDeInitCallback : TIM OC Msp DeInit Callback. + (+) PWM_MspInitCallback : TIM PWM Msp Init Callback. + (+) PWM_MspDeInitCallback : TIM PWM Msp DeInit Callback. + (+) OnePulse_MspInitCallback : TIM One Pulse Msp Init Callback. + (+) OnePulse_MspDeInitCallback : TIM One Pulse Msp DeInit Callback. + (+) Encoder_MspInitCallback : TIM Encoder Msp Init Callback. + (+) Encoder_MspDeInitCallback : TIM Encoder Msp DeInit Callback. + (+) HallSensor_MspInitCallback : TIM Hall Sensor Msp Init Callback. + (+) HallSensor_MspDeInitCallback : TIM Hall Sensor Msp DeInit Callback. + (+) PeriodElapsedCallback : TIM Period Elapsed Callback. + (+) PeriodElapsedHalfCpltCallback : TIM Period Elapsed half complete Callback. + (+) TriggerCallback : TIM Trigger Callback. + (+) TriggerHalfCpltCallback : TIM Trigger half complete Callback. + (+) IC_CaptureCallback : TIM Input Capture Callback. + (+) IC_CaptureHalfCpltCallback : TIM Input Capture half complete Callback. + (+) OC_DelayElapsedCallback : TIM Output Compare Delay Elapsed Callback. + (+) PWM_PulseFinishedCallback : TIM PWM Pulse Finished Callback. + (+) PWM_PulseFinishedHalfCpltCallback : TIM PWM Pulse Finished half complete Callback. + (+) ErrorCallback : TIM Error Callback. + (+) CommutationCallback : TIM Commutation Callback. + (+) CommutationHalfCpltCallback : TIM Commutation half complete Callback. + (+) BreakCallback : TIM Break Callback. + (+) Break2Callback : TIM Break2 Callback. + (+) EncoderIndexCallback : TIM Encoder Index Callback. + (+) DirectionChangeCallback : TIM Direction Change Callback + (+) IndexErrorCallback : TIM Index Error Callback. + (+) TransitionErrorCallback : TIM Transition Error Callback + + [..] +By default, after the Init and when the state is HAL_TIM_STATE_RESET +all interrupt callbacks are set to the corresponding weak functions: + examples HAL_TIM_TriggerCallback(), HAL_TIM_ErrorCallback(). + + [..] + Exception done for MspInit and MspDeInit functions that are reset to the legacy weak + functionalities in the Init / DeInit only when these callbacks are null + (not registered beforehand). If not, MspInit or MspDeInit are not null, the Init / DeInit + keep and use the user MspInit / MspDeInit callbacks(registered beforehand) + + [..] + Callbacks can be registered / unregistered in HAL_TIM_STATE_READY state only. + Exception done MspInit / MspDeInit that can be registered / unregistered + in HAL_TIM_STATE_READY or HAL_TIM_STATE_RESET state, + thus registered(user) MspInit / DeInit callbacks can be used during the Init / DeInit. + In that case first register the MspInit/MspDeInit user callbacks + using HAL_TIM_RegisterCallback() before calling DeInit or Init function. + + [..] + When The compilation define USE_HAL_TIM_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 "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup TIM TIM + * @brief TIM HAL module driver + * @{ + */ + +#ifdef HAL_TIM_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup TIM_Private_Constants + * @{ + */ +#define TIMx_AF2_OCRSEL TIM1_AF2_OCRSEL + +/** + * @} + */ +/* Private macros ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup TIM_Private_Functions + * @{ + */ +static void TIM_OC1_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config); +static void TIM_OC3_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config); +static void TIM_OC4_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config); +static void TIM_OC5_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config); +static void TIM_OC6_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config); +static void TIM_TI1_ConfigInputStage(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICFilter); +static void TIM_TI2_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter); +static void TIM_TI2_ConfigInputStage(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICFilter); +static void TIM_TI3_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter); +static void TIM_TI4_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter); +static void TIM_ITRx_SetConfig(TIM_TypeDef *TIMx, uint32_t InputTriggerSource); +static void TIM_DMAPeriodElapsedCplt(DMA_HandleTypeDef *hdma); +static void TIM_DMAPeriodElapsedHalfCplt(DMA_HandleTypeDef *hdma); +static void TIM_DMADelayPulseCplt(DMA_HandleTypeDef *hdma); +static void TIM_DMATriggerCplt(DMA_HandleTypeDef *hdma); +static void TIM_DMATriggerHalfCplt(DMA_HandleTypeDef *hdma); +static HAL_StatusTypeDef TIM_SlaveTimer_SetConfig(TIM_HandleTypeDef *htim, + const TIM_SlaveConfigTypeDef *sSlaveConfig); +/** + * @} + */ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup TIM_Exported_Functions TIM Exported Functions + * @{ + */ + +/** @defgroup TIM_Exported_Functions_Group1 TIM Time Base functions + * @brief Time Base functions + * +@verbatim + ============================================================================== + ##### Time Base functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the TIM base. + (+) De-initialize the TIM base. + (+) Start the Time Base. + (+) Stop the Time Base. + (+) Start the Time Base and enable interrupt. + (+) Stop the Time Base and disable interrupt. + (+) Start the Time Base and enable DMA transfer. + (+) Stop the Time Base and disable DMA transfer. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the TIM Time base Unit according to the specified + * parameters in the TIM_HandleTypeDef and initialize the associated handle. + * @note Switching from Center Aligned counter mode to Edge counter mode (or reverse) + * requires a timer reset to avoid unexpected direction + * due to DIR bit readonly in center aligned mode. + * Ex: call @ref HAL_TIM_Base_DeInit() before HAL_TIM_Base_Init() + * @param htim TIM Base handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_Init(TIM_HandleTypeDef *htim) +{ + /* Check the TIM handle allocation */ + if (htim == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode)); + assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); + assert_param(IS_TIM_PERIOD(htim, htim->Init.Period)); + assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload)); + + if (htim->State == HAL_TIM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + htim->Lock = HAL_UNLOCKED; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + /* Reset interrupt callbacks to legacy weak callbacks */ + TIM_ResetCallback(htim); + + if (htim->Base_MspInitCallback == NULL) + { + htim->Base_MspInitCallback = HAL_TIM_Base_MspInit; + } + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + htim->Base_MspInitCallback(htim); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + HAL_TIM_Base_MspInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Set the Time Base configuration */ + TIM_Base_SetConfig(htim->Instance, &htim->Init); + + /* Initialize the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_READY; + + /* Initialize the TIM channels state */ + TIM_CHANNEL_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_READY); + + /* Initialize the TIM state*/ + htim->State = HAL_TIM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the TIM Base peripheral + * @param htim TIM Base handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_DeInit(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the TIM Peripheral Clock */ + __HAL_TIM_DISABLE(htim); + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + if (htim->Base_MspDeInitCallback == NULL) + { + htim->Base_MspDeInitCallback = HAL_TIM_Base_MspDeInit; + } + /* DeInit the low level hardware */ + htim->Base_MspDeInitCallback(htim); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + HAL_TIM_Base_MspDeInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + /* Change the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_RESET; + + /* Change the TIM channels state */ + TIM_CHANNEL_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_RESET); + TIM_CHANNEL_N_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_RESET); + + /* Change TIM state */ + htim->State = HAL_TIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM Base MSP. + * @param htim TIM Base handle + * @retval None + */ +__weak void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_Base_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes TIM Base MSP. + * @param htim TIM Base handle + * @retval None + */ +__weak void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_Base_MspDeInit could be implemented in the user file + */ +} + + +/** + * @brief Starts the TIM Base generation. + * @param htim TIM Base handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_Start(TIM_HandleTypeDef *htim) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + /* Check the TIM state */ + if (htim->State != HAL_TIM_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Base generation. + * @param htim TIM Base handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_Stop(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Base generation in interrupt mode. + * @param htim TIM Base handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + /* Check the TIM state */ + if (htim->State != HAL_TIM_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Enable the TIM Update interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_UPDATE); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Base generation in interrupt mode. + * @param htim TIM Base handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_Stop_IT(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + /* Disable the TIM Update interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_UPDATE); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Base generation in DMA mode. + * @param htim TIM Base handle + * @param pData The source Buffer address. + * @param Length The length of data to be transferred from memory to peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_Start_DMA(TIM_HandleTypeDef *htim, const uint32_t *pData, uint16_t Length) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_DMA_INSTANCE(htim->Instance)); + + /* Set the TIM state */ + if (htim->State == HAL_TIM_STATE_BUSY) + { + return HAL_BUSY; + } + else if (htim->State == HAL_TIM_STATE_READY) + { + if ((pData == NULL) || (Length == 0U)) + { + return HAL_ERROR; + } + else + { + htim->State = HAL_TIM_STATE_BUSY; + } + } + else + { + return HAL_ERROR; + } + + /* Set the DMA Period elapsed callbacks */ + htim->hdma[TIM_DMA_ID_UPDATE]->XferCpltCallback = TIM_DMAPeriodElapsedCplt; + htim->hdma[TIM_DMA_ID_UPDATE]->XferHalfCpltCallback = TIM_DMAPeriodElapsedHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_UPDATE]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_UPDATE], (uint32_t)pData, (uint32_t)&htim->Instance->ARR, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + + /* Enable the TIM Update DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_UPDATE); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Base generation in DMA mode. + * @param htim TIM Base handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_Stop_DMA(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_DMA_INSTANCE(htim->Instance)); + + /* Disable the TIM Update DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_UPDATE); + + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_UPDATE]); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group2 TIM Output Compare functions + * @brief TIM Output Compare functions + * +@verbatim + ============================================================================== + ##### TIM Output Compare functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the TIM Output Compare. + (+) De-initialize the TIM Output Compare. + (+) Start the TIM Output Compare. + (+) Stop the TIM Output Compare. + (+) Start the TIM Output Compare and enable interrupt. + (+) Stop the TIM Output Compare and disable interrupt. + (+) Start the TIM Output Compare and enable DMA transfer. + (+) Stop the TIM Output Compare and disable DMA transfer. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the TIM Output Compare according to the specified + * parameters in the TIM_HandleTypeDef and initializes the associated handle. + * @note Switching from Center Aligned counter mode to Edge counter mode (or reverse) + * requires a timer reset to avoid unexpected direction + * due to DIR bit readonly in center aligned mode. + * Ex: call @ref HAL_TIM_OC_DeInit() before HAL_TIM_OC_Init() + * @param htim TIM Output Compare handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_Init(TIM_HandleTypeDef *htim) +{ + /* Check the TIM handle allocation */ + if (htim == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode)); + assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); + assert_param(IS_TIM_PERIOD(htim, htim->Init.Period)); + assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload)); + + if (htim->State == HAL_TIM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + htim->Lock = HAL_UNLOCKED; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + /* Reset interrupt callbacks to legacy weak callbacks */ + TIM_ResetCallback(htim); + + if (htim->OC_MspInitCallback == NULL) + { + htim->OC_MspInitCallback = HAL_TIM_OC_MspInit; + } + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + htim->OC_MspInitCallback(htim); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_OC_MspInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Init the base time for the Output Compare */ + TIM_Base_SetConfig(htim->Instance, &htim->Init); + + /* Initialize the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_READY; + + /* Initialize the TIM channels state */ + TIM_CHANNEL_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_READY); + + /* Initialize the TIM state*/ + htim->State = HAL_TIM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the TIM peripheral + * @param htim TIM Output Compare handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_DeInit(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the TIM Peripheral Clock */ + __HAL_TIM_DISABLE(htim); + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + if (htim->OC_MspDeInitCallback == NULL) + { + htim->OC_MspDeInitCallback = HAL_TIM_OC_MspDeInit; + } + /* DeInit the low level hardware */ + htim->OC_MspDeInitCallback(htim); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_OC_MspDeInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + /* Change the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_RESET; + + /* Change the TIM channels state */ + TIM_CHANNEL_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_RESET); + TIM_CHANNEL_N_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_RESET); + + /* Change TIM state */ + htim->State = HAL_TIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM Output Compare MSP. + * @param htim TIM Output Compare handle + * @retval None + */ +__weak void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_OC_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes TIM Output Compare MSP. + * @param htim TIM Output Compare handle + * @retval None + */ +__weak void HAL_TIM_OC_MspDeInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_OC_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief Starts the TIM Output Compare signal generation. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @arg TIM_CHANNEL_5: TIM Channel 5 selected + * @arg TIM_CHANNEL_6: TIM Channel 6 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_Start(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + /* Check the TIM channel state */ + if (TIM_CHANNEL_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + + /* Enable the Output compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Output Compare signal generation. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @arg TIM_CHANNEL_5: TIM Channel 5 selected + * @arg TIM_CHANNEL_6: TIM Channel 6 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + /* Disable the Output compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Output Compare signal generation in interrupt mode. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_CHANNEL(htim->Instance, Channel)); + + /* Check the TIM channel state */ + if (TIM_CHANNEL_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Enable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Enable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Enable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Enable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Enable the Output compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + } + + /* Return function status */ + return status; +} + +/** + * @brief Stops the TIM Output Compare signal generation in interrupt mode. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_CHANNEL(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Disable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Disable the Output compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + } + + /* Return function status */ + return status; +} + +/** + * @brief Starts the TIM Output Compare signal generation in DMA mode. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param pData The source Buffer address. + * @param Length The length of data to be transferred from memory to TIM peripheral + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData, + uint16_t Length) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_CHANNEL(htim->Instance, Channel)); + + /* Set the TIM channel state */ + if (TIM_CHANNEL_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_BUSY) + { + return HAL_BUSY; + } + else if (TIM_CHANNEL_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_READY) + { + if ((pData == NULL) || (Length == 0U)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + else + { + return HAL_ERROR; + } + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + + /* Enable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + + /* Enable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 3 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC4]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)pData, (uint32_t)&htim->Instance->CCR4, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 4 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC4); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Enable the Output compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + } + + /* Return function status */ + return status; +} + +/** + * @brief Stops the TIM Output Compare signal generation in DMA mode. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_CHANNEL(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]); + break; + } + + case TIM_CHANNEL_4: + { + /* Disable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC4); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC4]); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Disable the Output compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + } + + /* Return function status */ + return status; +} + +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group3 TIM PWM functions + * @brief TIM PWM functions + * +@verbatim + ============================================================================== + ##### TIM PWM functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the TIM PWM. + (+) De-initialize the TIM PWM. + (+) Start the TIM PWM. + (+) Stop the TIM PWM. + (+) Start the TIM PWM and enable interrupt. + (+) Stop the TIM PWM and disable interrupt. + (+) Start the TIM PWM and enable DMA transfer. + (+) Stop the TIM PWM and disable DMA transfer. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the TIM PWM Time Base according to the specified + * parameters in the TIM_HandleTypeDef and initializes the associated handle. + * @note Switching from Center Aligned counter mode to Edge counter mode (or reverse) + * requires a timer reset to avoid unexpected direction + * due to DIR bit readonly in center aligned mode. + * Ex: call @ref HAL_TIM_PWM_DeInit() before HAL_TIM_PWM_Init() + * @param htim TIM PWM handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_Init(TIM_HandleTypeDef *htim) +{ + /* Check the TIM handle allocation */ + if (htim == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode)); + assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); + assert_param(IS_TIM_PERIOD(htim, htim->Init.Period)); + assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload)); + + if (htim->State == HAL_TIM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + htim->Lock = HAL_UNLOCKED; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + /* Reset interrupt callbacks to legacy weak callbacks */ + TIM_ResetCallback(htim); + + if (htim->PWM_MspInitCallback == NULL) + { + htim->PWM_MspInitCallback = HAL_TIM_PWM_MspInit; + } + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + htim->PWM_MspInitCallback(htim); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_PWM_MspInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Init the base time for the PWM */ + TIM_Base_SetConfig(htim->Instance, &htim->Init); + + /* Initialize the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_READY; + + /* Initialize the TIM channels state */ + TIM_CHANNEL_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_READY); + + /* Initialize the TIM state*/ + htim->State = HAL_TIM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the TIM peripheral + * @param htim TIM PWM handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_DeInit(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the TIM Peripheral Clock */ + __HAL_TIM_DISABLE(htim); + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + if (htim->PWM_MspDeInitCallback == NULL) + { + htim->PWM_MspDeInitCallback = HAL_TIM_PWM_MspDeInit; + } + /* DeInit the low level hardware */ + htim->PWM_MspDeInitCallback(htim); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_PWM_MspDeInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + /* Change the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_RESET; + + /* Change the TIM channels state */ + TIM_CHANNEL_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_RESET); + TIM_CHANNEL_N_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_RESET); + + /* Change TIM state */ + htim->State = HAL_TIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM PWM MSP. + * @param htim TIM PWM handle + * @retval None + */ +__weak void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_PWM_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes TIM PWM MSP. + * @param htim TIM PWM handle + * @retval None + */ +__weak void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_PWM_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief Starts the PWM signal generation. + * @param htim TIM handle + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @arg TIM_CHANNEL_5: TIM Channel 5 selected + * @arg TIM_CHANNEL_6: TIM Channel 6 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + /* Check the TIM channel state */ + if (TIM_CHANNEL_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + + /* Enable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the PWM signal generation. + * @param htim TIM PWM handle + * @param Channel TIM Channels to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @arg TIM_CHANNEL_5: TIM Channel 5 selected + * @arg TIM_CHANNEL_6: TIM Channel 6 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + /* Disable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the PWM signal generation in interrupt mode. + * @param htim TIM PWM handle + * @param Channel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_CHANNEL(htim->Instance, Channel)); + + /* Check the TIM channel state */ + if (TIM_CHANNEL_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Enable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Enable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Enable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Enable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Enable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + } + + /* Return function status */ + return status; +} + +/** + * @brief Stops the PWM signal generation in interrupt mode. + * @param htim TIM PWM handle + * @param Channel TIM Channels to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_CHANNEL(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Disable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Disable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + } + + /* Return function status */ + return status; +} + +/** + * @brief Starts the TIM PWM signal generation in DMA mode. + * @param htim TIM PWM handle + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param pData The source Buffer address. + * @param Length The length of data to be transferred from memory to TIM peripheral + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData, + uint16_t Length) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_CHANNEL(htim->Instance, Channel)); + + /* Set the TIM channel state */ + if (TIM_CHANNEL_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_BUSY) + { + return HAL_BUSY; + } + else if (TIM_CHANNEL_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_READY) + { + if ((pData == NULL) || (Length == 0U)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + else + { + return HAL_ERROR; + } + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + + /* Enable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Output Capture/Compare 3 request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC4]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)pData, (uint32_t)&htim->Instance->CCR4, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 4 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC4); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Enable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + } + + /* Return function status */ + return status; +} + +/** + * @brief Stops the TIM PWM signal generation in DMA mode. + * @param htim TIM PWM handle + * @param Channel TIM Channels to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_CHANNEL(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]); + break; + } + + case TIM_CHANNEL_4: + { + /* Disable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC4); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC4]); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Disable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + } + + /* Return function status */ + return status; +} + +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group4 TIM Input Capture functions + * @brief TIM Input Capture functions + * +@verbatim + ============================================================================== + ##### TIM Input Capture functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the TIM Input Capture. + (+) De-initialize the TIM Input Capture. + (+) Start the TIM Input Capture. + (+) Stop the TIM Input Capture. + (+) Start the TIM Input Capture and enable interrupt. + (+) Stop the TIM Input Capture and disable interrupt. + (+) Start the TIM Input Capture and enable DMA transfer. + (+) Stop the TIM Input Capture and disable DMA transfer. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the TIM Input Capture Time base according to the specified + * parameters in the TIM_HandleTypeDef and initializes the associated handle. + * @note Switching from Center Aligned counter mode to Edge counter mode (or reverse) + * requires a timer reset to avoid unexpected direction + * due to DIR bit readonly in center aligned mode. + * Ex: call @ref HAL_TIM_IC_DeInit() before HAL_TIM_IC_Init() + * @param htim TIM Input Capture handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_Init(TIM_HandleTypeDef *htim) +{ + /* Check the TIM handle allocation */ + if (htim == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode)); + assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); + assert_param(IS_TIM_PERIOD(htim, htim->Init.Period)); + assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload)); + + if (htim->State == HAL_TIM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + htim->Lock = HAL_UNLOCKED; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + /* Reset interrupt callbacks to legacy weak callbacks */ + TIM_ResetCallback(htim); + + if (htim->IC_MspInitCallback == NULL) + { + htim->IC_MspInitCallback = HAL_TIM_IC_MspInit; + } + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + htim->IC_MspInitCallback(htim); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_IC_MspInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Init the base time for the input capture */ + TIM_Base_SetConfig(htim->Instance, &htim->Init); + + /* Initialize the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_READY; + + /* Initialize the TIM channels state */ + TIM_CHANNEL_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_READY); + + /* Initialize the TIM state*/ + htim->State = HAL_TIM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the TIM peripheral + * @param htim TIM Input Capture handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_DeInit(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the TIM Peripheral Clock */ + __HAL_TIM_DISABLE(htim); + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + if (htim->IC_MspDeInitCallback == NULL) + { + htim->IC_MspDeInitCallback = HAL_TIM_IC_MspDeInit; + } + /* DeInit the low level hardware */ + htim->IC_MspDeInitCallback(htim); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_IC_MspDeInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + /* Change the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_RESET; + + /* Change the TIM channels state */ + TIM_CHANNEL_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_RESET); + TIM_CHANNEL_N_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_RESET); + + /* Change TIM state */ + htim->State = HAL_TIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM Input Capture MSP. + * @param htim TIM Input Capture handle + * @retval None + */ +__weak void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_IC_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes TIM Input Capture MSP. + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIM_IC_MspDeInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_IC_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief Starts the TIM Input Capture measurement. + * @param htim TIM Input Capture handle + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_Start(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + uint32_t tmpsmcr; + HAL_TIM_ChannelStateTypeDef channel_state = TIM_CHANNEL_STATE_GET(htim, Channel); + HAL_TIM_ChannelStateTypeDef complementary_channel_state = TIM_CHANNEL_N_STATE_GET(htim, Channel); + + /* Check the parameters */ + assert_param(IS_TIM_CCX_CHANNEL(htim->Instance, Channel)); + + /* Check the TIM channel state */ + if ((channel_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_state != HAL_TIM_CHANNEL_STATE_READY)) + { + return HAL_ERROR; + } + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + + /* Enable the Input Capture channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Input Capture measurement. + * @param htim TIM Input Capture handle + * @param Channel TIM Channels to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_CHANNEL(htim->Instance, Channel)); + + /* Disable the Input Capture channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Input Capture measurement in interrupt mode. + * @param htim TIM Input Capture handle + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpsmcr; + + HAL_TIM_ChannelStateTypeDef channel_state = TIM_CHANNEL_STATE_GET(htim, Channel); + HAL_TIM_ChannelStateTypeDef complementary_channel_state = TIM_CHANNEL_N_STATE_GET(htim, Channel); + + /* Check the parameters */ + assert_param(IS_TIM_CCX_CHANNEL(htim->Instance, Channel)); + + /* Check the TIM channel state */ + if ((channel_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_state != HAL_TIM_CHANNEL_STATE_READY)) + { + return HAL_ERROR; + } + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Enable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Enable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Enable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Enable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Enable the Input Capture channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + } + + /* Return function status */ + return status; +} + +/** + * @brief Stops the TIM Input Capture measurement in interrupt mode. + * @param htim TIM Input Capture handle + * @param Channel TIM Channels to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_CHANNEL(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Disable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Disable the Input Capture channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + } + + /* Return function status */ + return status; +} + +/** + * @brief Starts the TIM Input Capture measurement in DMA mode. + * @param htim TIM Input Capture handle + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param pData The destination Buffer address. + * @param Length The length of data to be transferred from TIM peripheral to memory. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpsmcr; + + HAL_TIM_ChannelStateTypeDef channel_state = TIM_CHANNEL_STATE_GET(htim, Channel); + HAL_TIM_ChannelStateTypeDef complementary_channel_state = TIM_CHANNEL_N_STATE_GET(htim, Channel); + + /* Check the parameters */ + assert_param(IS_TIM_CCX_CHANNEL(htim->Instance, Channel)); + assert_param(IS_TIM_DMA_CC_INSTANCE(htim->Instance)); + + /* Set the TIM channel state */ + if ((channel_state == HAL_TIM_CHANNEL_STATE_BUSY) + || (complementary_channel_state == HAL_TIM_CHANNEL_STATE_BUSY)) + { + return HAL_BUSY; + } + else if ((channel_state == HAL_TIM_CHANNEL_STATE_READY) + && (complementary_channel_state == HAL_TIM_CHANNEL_STATE_READY)) + { + if ((pData == NULL) || (Length == 0U)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + else + { + return HAL_ERROR; + } + + /* Enable the Input Capture channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t)pData, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)&htim->Instance->CCR2, (uint32_t)pData, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)&htim->Instance->CCR3, (uint32_t)pData, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 3 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC4]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)&htim->Instance->CCR4, (uint32_t)pData, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 4 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC4); + break; + } + + default: + status = HAL_ERROR; + break; + } + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return status; +} + +/** + * @brief Stops the TIM Input Capture measurement in DMA mode. + * @param htim TIM Input Capture handle + * @param Channel TIM Channels to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_CHANNEL(htim->Instance, Channel)); + assert_param(IS_TIM_DMA_CC_INSTANCE(htim->Instance)); + + /* Disable the Input Capture channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]); + break; + } + + case TIM_CHANNEL_4: + { + /* Disable the TIM Capture/Compare 4 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC4); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC4]); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + } + + /* Return function status */ + return status; +} +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group5 TIM One Pulse functions + * @brief TIM One Pulse functions + * +@verbatim + ============================================================================== + ##### TIM One Pulse functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the TIM One Pulse. + (+) De-initialize the TIM One Pulse. + (+) Start the TIM One Pulse. + (+) Stop the TIM One Pulse. + (+) Start the TIM One Pulse and enable interrupt. + (+) Stop the TIM One Pulse and disable interrupt. + (+) Start the TIM One Pulse and enable DMA transfer. + (+) Stop the TIM One Pulse and disable DMA transfer. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the TIM One Pulse Time Base according to the specified + * parameters in the TIM_HandleTypeDef and initializes the associated handle. + * @note Switching from Center Aligned counter mode to Edge counter mode (or reverse) + * requires a timer reset to avoid unexpected direction + * due to DIR bit readonly in center aligned mode. + * Ex: call @ref HAL_TIM_OnePulse_DeInit() before HAL_TIM_OnePulse_Init() + * @note When the timer instance is initialized in One Pulse mode, timer + * channels 1 and channel 2 are reserved and cannot be used for other + * purpose. + * @param htim TIM One Pulse handle + * @param OnePulseMode Select the One pulse mode. + * This parameter can be one of the following values: + * @arg TIM_OPMODE_SINGLE: Only one pulse will be generated. + * @arg TIM_OPMODE_REPETITIVE: Repetitive pulses will be generated. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OnePulse_Init(TIM_HandleTypeDef *htim, uint32_t OnePulseMode) +{ + /* Check the TIM handle allocation */ + if (htim == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode)); + assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); + assert_param(IS_TIM_OPM_MODE(OnePulseMode)); + assert_param(IS_TIM_PERIOD(htim, htim->Init.Period)); + assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload)); + + if (htim->State == HAL_TIM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + htim->Lock = HAL_UNLOCKED; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + /* Reset interrupt callbacks to legacy weak callbacks */ + TIM_ResetCallback(htim); + + if (htim->OnePulse_MspInitCallback == NULL) + { + htim->OnePulse_MspInitCallback = HAL_TIM_OnePulse_MspInit; + } + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + htim->OnePulse_MspInitCallback(htim); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_OnePulse_MspInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Configure the Time base in the One Pulse Mode */ + TIM_Base_SetConfig(htim->Instance, &htim->Init); + + /* Reset the OPM Bit */ + htim->Instance->CR1 &= ~TIM_CR1_OPM; + + /* Configure the OPM Mode */ + htim->Instance->CR1 |= OnePulseMode; + + /* Initialize the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_READY; + + /* Initialize the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + + /* Initialize the TIM state*/ + htim->State = HAL_TIM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the TIM One Pulse + * @param htim TIM One Pulse handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OnePulse_DeInit(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the TIM Peripheral Clock */ + __HAL_TIM_DISABLE(htim); + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + if (htim->OnePulse_MspDeInitCallback == NULL) + { + htim->OnePulse_MspDeInitCallback = HAL_TIM_OnePulse_MspDeInit; + } + /* DeInit the low level hardware */ + htim->OnePulse_MspDeInitCallback(htim); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + HAL_TIM_OnePulse_MspDeInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + /* Change the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_RESET; + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_RESET); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_RESET); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_RESET); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_RESET); + + /* Change TIM state */ + htim->State = HAL_TIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM One Pulse MSP. + * @param htim TIM One Pulse handle + * @retval None + */ +__weak void HAL_TIM_OnePulse_MspInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_OnePulse_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes TIM One Pulse MSP. + * @param htim TIM One Pulse handle + * @retval None + */ +__weak void HAL_TIM_OnePulse_MspDeInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_OnePulse_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief Starts the TIM One Pulse signal generation. + * @note Though OutputChannel parameter is deprecated and ignored by the function + * it has been kept to avoid HAL_TIM API compatibility break. + * @note The pulse output channel is determined when calling + * @ref HAL_TIM_OnePulse_ConfigChannel(). + * @param htim TIM One Pulse handle + * @param OutputChannel See note above + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OnePulse_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2); + HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2); + + /* Prevent unused argument(s) compilation warning */ + UNUSED(OutputChannel); + + /* Check the TIM channels state */ + if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) + { + return HAL_ERROR; + } + + /* Set the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + + /* Enable the Capture compare and the Input Capture channels + (in the OPM Mode the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) + if TIM_CHANNEL_1 is used as output, the TIM_CHANNEL_2 will be used as input and + if TIM_CHANNEL_1 is used as input, the TIM_CHANNEL_2 will be used as output + whatever the combination, the TIM_CHANNEL_1 and TIM_CHANNEL_2 should be enabled together + + No need to enable the counter, it's enabled automatically by hardware + (the counter starts in response to a stimulus and generate a pulse */ + + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM One Pulse signal generation. + * @note Though OutputChannel parameter is deprecated and ignored by the function + * it has been kept to avoid HAL_TIM API compatibility break. + * @note The pulse output channel is determined when calling + * @ref HAL_TIM_OnePulse_ConfigChannel(). + * @param htim TIM One Pulse handle + * @param OutputChannel See note above + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OnePulse_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(OutputChannel); + + /* Disable the Capture compare and the Input Capture channels + (in the OPM Mode the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) + if TIM_CHANNEL_1 is used as output, the TIM_CHANNEL_2 will be used as input and + if TIM_CHANNEL_1 is used as input, the TIM_CHANNEL_2 will be used as output + whatever the combination, the TIM_CHANNEL_1 and TIM_CHANNEL_2 should be disabled together */ + + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM One Pulse signal generation in interrupt mode. + * @note Though OutputChannel parameter is deprecated and ignored by the function + * it has been kept to avoid HAL_TIM API compatibility break. + * @note The pulse output channel is determined when calling + * @ref HAL_TIM_OnePulse_ConfigChannel(). + * @param htim TIM One Pulse handle + * @param OutputChannel See note above + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OnePulse_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2); + HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2); + + /* Prevent unused argument(s) compilation warning */ + UNUSED(OutputChannel); + + /* Check the TIM channels state */ + if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) + { + return HAL_ERROR; + } + + /* Set the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + + /* Enable the Capture compare and the Input Capture channels + (in the OPM Mode the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) + if TIM_CHANNEL_1 is used as output, the TIM_CHANNEL_2 will be used as input and + if TIM_CHANNEL_1 is used as input, the TIM_CHANNEL_2 will be used as output + whatever the combination, the TIM_CHANNEL_1 and TIM_CHANNEL_2 should be enabled together + + No need to enable the counter, it's enabled automatically by hardware + (the counter starts in response to a stimulus and generate a pulse */ + + /* Enable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + + /* Enable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM One Pulse signal generation in interrupt mode. + * @note Though OutputChannel parameter is deprecated and ignored by the function + * it has been kept to avoid HAL_TIM API compatibility break. + * @note The pulse output channel is determined when calling + * @ref HAL_TIM_OnePulse_ConfigChannel(). + * @param htim TIM One Pulse handle + * @param OutputChannel See note above + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OnePulse_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(OutputChannel); + + /* Disable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + + /* Disable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + + /* Disable the Capture compare and the Input Capture channels + (in the OPM Mode the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) + if TIM_CHANNEL_1 is used as output, the TIM_CHANNEL_2 will be used as input and + if TIM_CHANNEL_1 is used as input, the TIM_CHANNEL_2 will be used as output + whatever the combination, the TIM_CHANNEL_1 and TIM_CHANNEL_2 should be disabled together */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group6 TIM Encoder functions + * @brief TIM Encoder functions + * +@verbatim + ============================================================================== + ##### TIM Encoder functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the TIM Encoder. + (+) De-initialize the TIM Encoder. + (+) Start the TIM Encoder. + (+) Stop the TIM Encoder. + (+) Start the TIM Encoder and enable interrupt. + (+) Stop the TIM Encoder and disable interrupt. + (+) Start the TIM Encoder and enable DMA transfer. + (+) Stop the TIM Encoder and disable DMA transfer. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the TIM Encoder Interface and initialize the associated handle. + * @note Switching from Center Aligned counter mode to Edge counter mode (or reverse) + * requires a timer reset to avoid unexpected direction + * due to DIR bit readonly in center aligned mode. + * Ex: call @ref HAL_TIM_Encoder_DeInit() before HAL_TIM_Encoder_Init() + * @note Encoder mode and External clock mode 2 are not compatible and must not be selected together + * Ex: A call for @ref HAL_TIM_Encoder_Init will erase the settings of @ref HAL_TIM_ConfigClockSource + * using TIM_CLOCKSOURCE_ETRMODE2 and vice versa + * @note When the timer instance is initialized in Encoder mode, timer + * channels 1 and channel 2 are reserved and cannot be used for other + * purpose. + * @param htim TIM Encoder Interface handle + * @param sConfig TIM Encoder Interface configuration structure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_Init(TIM_HandleTypeDef *htim, const TIM_Encoder_InitTypeDef *sConfig) +{ + uint32_t tmpsmcr; + uint32_t tmpccmr1; + uint32_t tmpccer; + + /* Check the TIM handle allocation */ + if (htim == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(htim->Instance)); + assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode)); + assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); + assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload)); + assert_param(IS_TIM_ENCODER_MODE(sConfig->EncoderMode)); + assert_param(IS_TIM_IC_SELECTION(sConfig->IC1Selection)); + assert_param(IS_TIM_IC_SELECTION(sConfig->IC2Selection)); + assert_param(IS_TIM_ENCODERINPUT_POLARITY(sConfig->IC1Polarity)); + assert_param(IS_TIM_ENCODERINPUT_POLARITY(sConfig->IC2Polarity)); + assert_param(IS_TIM_IC_PRESCALER(sConfig->IC1Prescaler)); + assert_param(IS_TIM_IC_PRESCALER(sConfig->IC2Prescaler)); + assert_param(IS_TIM_IC_FILTER(sConfig->IC1Filter)); + assert_param(IS_TIM_IC_FILTER(sConfig->IC2Filter)); + assert_param(IS_TIM_PERIOD(htim, htim->Init.Period)); + + if (htim->State == HAL_TIM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + htim->Lock = HAL_UNLOCKED; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + /* Reset interrupt callbacks to legacy weak callbacks */ + TIM_ResetCallback(htim); + + if (htim->Encoder_MspInitCallback == NULL) + { + htim->Encoder_MspInitCallback = HAL_TIM_Encoder_MspInit; + } + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + htim->Encoder_MspInitCallback(htim); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_Encoder_MspInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Reset the SMS and ECE bits */ + htim->Instance->SMCR &= ~(TIM_SMCR_SMS | TIM_SMCR_ECE); + + /* Configure the Time base in the Encoder Mode */ + TIM_Base_SetConfig(htim->Instance, &htim->Init); + + /* Get the TIMx SMCR register value */ + tmpsmcr = htim->Instance->SMCR; + + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = htim->Instance->CCMR1; + + /* Get the TIMx CCER register value */ + tmpccer = htim->Instance->CCER; + + /* Set the encoder Mode */ + tmpsmcr |= sConfig->EncoderMode; + + /* Select the Capture Compare 1 and the Capture Compare 2 as input */ + tmpccmr1 &= ~(TIM_CCMR1_CC1S | TIM_CCMR1_CC2S); + tmpccmr1 |= (sConfig->IC1Selection | (sConfig->IC2Selection << 8U)); + + /* Set the Capture Compare 1 and the Capture Compare 2 prescalers and filters */ + tmpccmr1 &= ~(TIM_CCMR1_IC1PSC | TIM_CCMR1_IC2PSC); + tmpccmr1 &= ~(TIM_CCMR1_IC1F | TIM_CCMR1_IC2F); + tmpccmr1 |= sConfig->IC1Prescaler | (sConfig->IC2Prescaler << 8U); + tmpccmr1 |= (sConfig->IC1Filter << 4U) | (sConfig->IC2Filter << 12U); + + /* Set the TI1 and the TI2 Polarities */ + tmpccer &= ~(TIM_CCER_CC1P | TIM_CCER_CC2P); + tmpccer &= ~(TIM_CCER_CC1NP | TIM_CCER_CC2NP); + tmpccer |= sConfig->IC1Polarity | (sConfig->IC2Polarity << 4U); + + /* Write to TIMx SMCR */ + htim->Instance->SMCR = tmpsmcr; + + /* Write to TIMx CCMR1 */ + htim->Instance->CCMR1 = tmpccmr1; + + /* Write to TIMx CCER */ + htim->Instance->CCER = tmpccer; + + /* Initialize the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_READY; + + /* Set the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + + /* Initialize the TIM state*/ + htim->State = HAL_TIM_STATE_READY; + + return HAL_OK; +} + + +/** + * @brief DeInitializes the TIM Encoder interface + * @param htim TIM Encoder Interface handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_DeInit(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the TIM Peripheral Clock */ + __HAL_TIM_DISABLE(htim); + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + if (htim->Encoder_MspDeInitCallback == NULL) + { + htim->Encoder_MspDeInitCallback = HAL_TIM_Encoder_MspDeInit; + } + /* DeInit the low level hardware */ + htim->Encoder_MspDeInitCallback(htim); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + HAL_TIM_Encoder_MspDeInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + /* Change the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_RESET; + + /* Set the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_RESET); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_RESET); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_RESET); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_RESET); + + /* Change TIM state */ + htim->State = HAL_TIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM Encoder Interface MSP. + * @param htim TIM Encoder Interface handle + * @retval None + */ +__weak void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_Encoder_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes TIM Encoder Interface MSP. + * @param htim TIM Encoder Interface handle + * @retval None + */ +__weak void HAL_TIM_Encoder_MspDeInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_Encoder_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief Starts the TIM Encoder Interface. + * @param htim TIM Encoder Interface handle + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_Start(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2); + HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2); + + /* Check the parameters */ + assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(htim->Instance)); + + /* Set the TIM channel(s) state */ + if (Channel == TIM_CHANNEL_1) + { + if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + else if (Channel == TIM_CHANNEL_2) + { + if ((channel_2_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + else + { + if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + + /* Enable the encoder interface channels */ + switch (Channel) + { + case TIM_CHANNEL_1: + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + break; + } + + case TIM_CHANNEL_2: + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + break; + } + + default : + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + break; + } + } + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Encoder Interface. + * @param htim TIM Encoder Interface handle + * @param Channel TIM Channels to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(htim->Instance)); + + /* Disable the Input Capture channels 1 and 2 + (in the EncoderInterface the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) */ + switch (Channel) + { + case TIM_CHANNEL_1: + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + break; + } + + case TIM_CHANNEL_2: + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + break; + } + + default : + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + break; + } + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channel(s) state */ + if ((Channel == TIM_CHANNEL_1) || (Channel == TIM_CHANNEL_2)) + { + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + } + else + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Encoder Interface in interrupt mode. + * @param htim TIM Encoder Interface handle + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2); + HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2); + + /* Check the parameters */ + assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(htim->Instance)); + + /* Set the TIM channel(s) state */ + if (Channel == TIM_CHANNEL_1) + { + if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + else if (Channel == TIM_CHANNEL_2) + { + if ((channel_2_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + else + { + if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + + /* Enable the encoder interface channels */ + /* Enable the capture compare Interrupts 1 and/or 2 */ + switch (Channel) + { + case TIM_CHANNEL_1: + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + break; + } + + default : + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + break; + } + } + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Encoder Interface in interrupt mode. + * @param htim TIM Encoder Interface handle + * @param Channel TIM Channels to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(htim->Instance)); + + /* Disable the Input Capture channels 1 and 2 + (in the EncoderInterface the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) */ + if (Channel == TIM_CHANNEL_1) + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + + /* Disable the capture compare Interrupts 1 */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + } + else if (Channel == TIM_CHANNEL_2) + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + + /* Disable the capture compare Interrupts 2 */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + } + else + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + + /* Disable the capture compare Interrupts 1 and 2 */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channel(s) state */ + if ((Channel == TIM_CHANNEL_1) || (Channel == TIM_CHANNEL_2)) + { + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + } + else + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Encoder Interface in DMA mode. + * @param htim TIM Encoder Interface handle + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected + * @param pData1 The destination Buffer address for IC1. + * @param pData2 The destination Buffer address for IC2. + * @param Length The length of data to be transferred from TIM peripheral to memory. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData1, + uint32_t *pData2, uint16_t Length) +{ + HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2); + HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2); + + /* Check the parameters */ + assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(htim->Instance)); + + /* Set the TIM channel(s) state */ + if (Channel == TIM_CHANNEL_1) + { + if ((channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY) + || (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY)) + { + return HAL_BUSY; + } + else if ((channel_1_state == HAL_TIM_CHANNEL_STATE_READY) + && (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_READY)) + { + if ((pData1 == NULL) || (Length == 0U)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + else + { + return HAL_ERROR; + } + } + else if (Channel == TIM_CHANNEL_2) + { + if ((channel_2_state == HAL_TIM_CHANNEL_STATE_BUSY) + || (complementary_channel_2_state == HAL_TIM_CHANNEL_STATE_BUSY)) + { + return HAL_BUSY; + } + else if ((channel_2_state == HAL_TIM_CHANNEL_STATE_READY) + && (complementary_channel_2_state == HAL_TIM_CHANNEL_STATE_READY)) + { + if ((pData2 == NULL) || (Length == 0U)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + else + { + return HAL_ERROR; + } + } + else + { + if ((channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY) + || (channel_2_state == HAL_TIM_CHANNEL_STATE_BUSY) + || (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY) + || (complementary_channel_2_state == HAL_TIM_CHANNEL_STATE_BUSY)) + { + return HAL_BUSY; + } + else if ((channel_1_state == HAL_TIM_CHANNEL_STATE_READY) + && (channel_2_state == HAL_TIM_CHANNEL_STATE_READY) + && (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_READY) + && (complementary_channel_2_state == HAL_TIM_CHANNEL_STATE_READY)) + { + if ((((pData1 == NULL) || (pData2 == NULL))) || (Length == 0U)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + else + { + return HAL_ERROR; + } + } + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t)pData1, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Input Capture DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + + /* Enable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + break; + } + + case TIM_CHANNEL_2: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError; + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)&htim->Instance->CCR2, (uint32_t)pData2, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Input Capture DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); + + /* Enable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + break; + } + + default: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t)pData1, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)&htim->Instance->CCR2, (uint32_t)pData2, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + + /* Enable the TIM Input Capture DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + /* Enable the TIM Input Capture DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); + + /* Enable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + break; + } + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Encoder Interface in DMA mode. + * @param htim TIM Encoder Interface handle + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(htim->Instance)); + + /* Disable the Input Capture channels 1 and 2 + (in the EncoderInterface the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) */ + if (Channel == TIM_CHANNEL_1) + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + + /* Disable the capture compare DMA Request 1 */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + } + else if (Channel == TIM_CHANNEL_2) + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + + /* Disable the capture compare DMA Request 2 */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); + } + else + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + + /* Disable the capture compare DMA Request 1 and 2 */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channel(s) state */ + if ((Channel == TIM_CHANNEL_1) || (Channel == TIM_CHANNEL_2)) + { + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + } + else + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ +/** @defgroup TIM_Exported_Functions_Group7 TIM IRQ handler management + * @brief TIM IRQ handler management + * +@verbatim + ============================================================================== + ##### IRQ handler management ##### + ============================================================================== + [..] + This section provides Timer IRQ handler function. + +@endverbatim + * @{ + */ +/** + * @brief This function handles TIM interrupts requests. + * @param htim TIM handle + * @retval None + */ +void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim) +{ + uint32_t itsource = htim->Instance->DIER; + uint32_t itflag = htim->Instance->SR; + + /* Capture compare 1 event */ + if ((itflag & (TIM_FLAG_CC1)) == (TIM_FLAG_CC1)) + { + if ((itsource & (TIM_IT_CC1)) == (TIM_IT_CC1)) + { + { + __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1); + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1; + + /* Input capture event */ + if ((htim->Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00U) + { +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->IC_CaptureCallback(htim); +#else + HAL_TIM_IC_CaptureCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + /* Output compare event */ + else + { +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->OC_DelayElapsedCallback(htim); + htim->PWM_PulseFinishedCallback(htim); +#else + HAL_TIM_OC_DelayElapsedCallback(htim); + HAL_TIM_PWM_PulseFinishedCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; + } + } + } + /* Capture compare 2 event */ + if ((itflag & (TIM_FLAG_CC2)) == (TIM_FLAG_CC2)) + { + if ((itsource & (TIM_IT_CC2)) == (TIM_IT_CC2)) + { + __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2); + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2; + /* Input capture event */ + if ((htim->Instance->CCMR1 & TIM_CCMR1_CC2S) != 0x00U) + { +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->IC_CaptureCallback(htim); +#else + HAL_TIM_IC_CaptureCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + /* Output compare event */ + else + { +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->OC_DelayElapsedCallback(htim); + htim->PWM_PulseFinishedCallback(htim); +#else + HAL_TIM_OC_DelayElapsedCallback(htim); + HAL_TIM_PWM_PulseFinishedCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; + } + } + /* Capture compare 3 event */ + if ((itflag & (TIM_FLAG_CC3)) == (TIM_FLAG_CC3)) + { + if ((itsource & (TIM_IT_CC3)) == (TIM_IT_CC3)) + { + __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC3); + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3; + /* Input capture event */ + if ((htim->Instance->CCMR2 & TIM_CCMR2_CC3S) != 0x00U) + { +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->IC_CaptureCallback(htim); +#else + HAL_TIM_IC_CaptureCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + /* Output compare event */ + else + { +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->OC_DelayElapsedCallback(htim); + htim->PWM_PulseFinishedCallback(htim); +#else + HAL_TIM_OC_DelayElapsedCallback(htim); + HAL_TIM_PWM_PulseFinishedCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; + } + } + /* Capture compare 4 event */ + if ((itflag & (TIM_FLAG_CC4)) == (TIM_FLAG_CC4)) + { + if ((itsource & (TIM_IT_CC4)) == (TIM_IT_CC4)) + { + __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC4); + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4; + /* Input capture event */ + if ((htim->Instance->CCMR2 & TIM_CCMR2_CC4S) != 0x00U) + { +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->IC_CaptureCallback(htim); +#else + HAL_TIM_IC_CaptureCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + /* Output compare event */ + else + { +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->OC_DelayElapsedCallback(htim); + htim->PWM_PulseFinishedCallback(htim); +#else + HAL_TIM_OC_DelayElapsedCallback(htim); + HAL_TIM_PWM_PulseFinishedCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; + } + } + /* TIM Update event */ + if ((itflag & (TIM_FLAG_UPDATE)) == (TIM_FLAG_UPDATE)) + { + if ((itsource & (TIM_IT_UPDATE)) == (TIM_IT_UPDATE)) + { + __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE); +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->PeriodElapsedCallback(htim); +#else + HAL_TIM_PeriodElapsedCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + } + /* TIM Break input event */ + if ((itflag & (TIM_FLAG_BREAK)) == (TIM_FLAG_BREAK)) + { + if ((itsource & (TIM_IT_BREAK)) == (TIM_IT_BREAK)) + { + __HAL_TIM_CLEAR_IT(htim, TIM_IT_BREAK); +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->BreakCallback(htim); +#else + HAL_TIMEx_BreakCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + } + /* TIM Break2 input event */ + if ((itflag & (TIM_FLAG_BREAK2)) == (TIM_FLAG_BREAK2)) + { + if ((itsource & (TIM_IT_BREAK)) == (TIM_IT_BREAK)) + { + __HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_BREAK2); +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->Break2Callback(htim); +#else + HAL_TIMEx_Break2Callback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + } + /* TIM Trigger detection event */ + if ((itflag & (TIM_FLAG_TRIGGER)) == (TIM_FLAG_TRIGGER)) + { + if ((itsource & (TIM_IT_TRIGGER)) == (TIM_IT_TRIGGER)) + { + __HAL_TIM_CLEAR_IT(htim, TIM_IT_TRIGGER); +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->TriggerCallback(htim); +#else + HAL_TIM_TriggerCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + } + /* TIM commutation event */ + if ((itflag & (TIM_FLAG_COM)) == (TIM_FLAG_COM)) + { + if ((itsource & (TIM_IT_COM)) == (TIM_IT_COM)) + { + __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_COM); +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->CommutationCallback(htim); +#else + HAL_TIMEx_CommutCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + } + /* TIM Encoder index event */ + if ((itflag & (TIM_FLAG_IDX)) == (TIM_FLAG_IDX)) + { + if ((itsource & (TIM_IT_IDX)) == (TIM_IT_IDX)) + { + __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_IDX); +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->EncoderIndexCallback(htim); +#else + HAL_TIMEx_EncoderIndexCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + } + /* TIM Direction change event */ + if ((itflag & (TIM_FLAG_DIR)) == (TIM_FLAG_DIR)) + { + if ((itsource & (TIM_IT_DIR)) == (TIM_IT_DIR)) + { + __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_DIR); +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->DirectionChangeCallback(htim); +#else + HAL_TIMEx_DirectionChangeCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + } + /* TIM Index error event */ + if ((itflag & (TIM_FLAG_IERR)) == (TIM_FLAG_IERR)) + { + if ((itsource & (TIM_IT_IERR)) == (TIM_IT_IERR)) + { + __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_IERR); +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->IndexErrorCallback(htim); +#else + HAL_TIMEx_IndexErrorCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + } + /* TIM Transition error event */ + if ((itflag & (TIM_FLAG_TERR)) == (TIM_FLAG_TERR)) + { + if ((itsource & (TIM_IT_TERR)) == (TIM_IT_TERR)) + { + __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_TERR); +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->TransitionErrorCallback(htim); +#else + HAL_TIMEx_TransitionErrorCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + } +} + +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group8 TIM Peripheral Control functions + * @brief TIM Peripheral Control functions + * +@verbatim + ============================================================================== + ##### Peripheral Control functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Configure The Input Output channels for OC, PWM, IC or One Pulse mode. + (+) Configure External Clock source. + (+) Configure Complementary channels, break features and dead time. + (+) Configure Master and the Slave synchronization. + (+) Configure the DMA Burst Mode. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the TIM Output Compare Channels according to the specified + * parameters in the TIM_OC_InitTypeDef. + * @param htim TIM Output Compare handle + * @param sConfig TIM Output Compare configuration structure + * @param Channel TIM Channels to configure + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @arg TIM_CHANNEL_5: TIM Channel 5 selected + * @arg TIM_CHANNEL_6: TIM Channel 6 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_ConfigChannel(TIM_HandleTypeDef *htim, + const TIM_OC_InitTypeDef *sConfig, + uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_CHANNELS(Channel)); + assert_param(IS_TIM_OC_CHANNEL_MODE(sConfig->OCMode, Channel)); + assert_param(IS_TIM_OC_POLARITY(sConfig->OCPolarity)); + + /* Process Locked */ + __HAL_LOCK(htim); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + + /* Configure the TIM Channel 1 in Output Compare */ + TIM_OC1_SetConfig(htim->Instance, sConfig); + break; + } + + case TIM_CHANNEL_2: + { + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + /* Configure the TIM Channel 2 in Output Compare */ + TIM_OC2_SetConfig(htim->Instance, sConfig); + break; + } + + case TIM_CHANNEL_3: + { + /* Check the parameters */ + assert_param(IS_TIM_CC3_INSTANCE(htim->Instance)); + + /* Configure the TIM Channel 3 in Output Compare */ + TIM_OC3_SetConfig(htim->Instance, sConfig); + break; + } + + case TIM_CHANNEL_4: + { + /* Check the parameters */ + assert_param(IS_TIM_CC4_INSTANCE(htim->Instance)); + + /* Configure the TIM Channel 4 in Output Compare */ + TIM_OC4_SetConfig(htim->Instance, sConfig); + break; + } + + case TIM_CHANNEL_5: + { + /* Check the parameters */ + assert_param(IS_TIM_CC5_INSTANCE(htim->Instance)); + + /* Configure the TIM Channel 5 in Output Compare */ + TIM_OC5_SetConfig(htim->Instance, sConfig); + break; + } + + case TIM_CHANNEL_6: + { + /* Check the parameters */ + assert_param(IS_TIM_CC6_INSTANCE(htim->Instance)); + + /* Configure the TIM Channel 6 in Output Compare */ + TIM_OC6_SetConfig(htim->Instance, sConfig); + break; + } + + default: + status = HAL_ERROR; + break; + } + + __HAL_UNLOCK(htim); + + return status; +} + +/** + * @brief Initializes the TIM Input Capture Channels according to the specified + * parameters in the TIM_IC_InitTypeDef. + * @param htim TIM IC handle + * @param sConfig TIM Input Capture configuration structure + * @param Channel TIM Channel to configure + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_ConfigChannel(TIM_HandleTypeDef *htim, const TIM_IC_InitTypeDef *sConfig, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + assert_param(IS_TIM_IC_POLARITY(sConfig->ICPolarity)); + assert_param(IS_TIM_IC_SELECTION(sConfig->ICSelection)); + assert_param(IS_TIM_IC_PRESCALER(sConfig->ICPrescaler)); + assert_param(IS_TIM_IC_FILTER(sConfig->ICFilter)); + + /* Process Locked */ + __HAL_LOCK(htim); + + if (Channel == TIM_CHANNEL_1) + { + /* TI1 Configuration */ + TIM_TI1_SetConfig(htim->Instance, + sConfig->ICPolarity, + sConfig->ICSelection, + sConfig->ICFilter); + + /* Reset the IC1PSC Bits */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC; + + /* Set the IC1PSC value */ + htim->Instance->CCMR1 |= sConfig->ICPrescaler; + } + else if (Channel == TIM_CHANNEL_2) + { + /* TI2 Configuration */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + TIM_TI2_SetConfig(htim->Instance, + sConfig->ICPolarity, + sConfig->ICSelection, + sConfig->ICFilter); + + /* Reset the IC2PSC Bits */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_IC2PSC; + + /* Set the IC2PSC value */ + htim->Instance->CCMR1 |= (sConfig->ICPrescaler << 8U); + } + else if (Channel == TIM_CHANNEL_3) + { + /* TI3 Configuration */ + assert_param(IS_TIM_CC3_INSTANCE(htim->Instance)); + + TIM_TI3_SetConfig(htim->Instance, + sConfig->ICPolarity, + sConfig->ICSelection, + sConfig->ICFilter); + + /* Reset the IC3PSC Bits */ + htim->Instance->CCMR2 &= ~TIM_CCMR2_IC3PSC; + + /* Set the IC3PSC value */ + htim->Instance->CCMR2 |= sConfig->ICPrescaler; + } + else if (Channel == TIM_CHANNEL_4) + { + /* TI4 Configuration */ + assert_param(IS_TIM_CC4_INSTANCE(htim->Instance)); + + TIM_TI4_SetConfig(htim->Instance, + sConfig->ICPolarity, + sConfig->ICSelection, + sConfig->ICFilter); + + /* Reset the IC4PSC Bits */ + htim->Instance->CCMR2 &= ~TIM_CCMR2_IC4PSC; + + /* Set the IC4PSC value */ + htim->Instance->CCMR2 |= (sConfig->ICPrescaler << 8U); + } + else + { + status = HAL_ERROR; + } + + __HAL_UNLOCK(htim); + + return status; +} + +/** + * @brief Initializes the TIM PWM channels according to the specified + * parameters in the TIM_OC_InitTypeDef. + * @param htim TIM PWM handle + * @param sConfig TIM PWM configuration structure + * @param Channel TIM Channels to be configured + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @arg TIM_CHANNEL_5: TIM Channel 5 selected + * @arg TIM_CHANNEL_6: TIM Channel 6 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_ConfigChannel(TIM_HandleTypeDef *htim, + const TIM_OC_InitTypeDef *sConfig, + uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_CHANNELS(Channel)); + assert_param(IS_TIM_PWM_MODE(sConfig->OCMode)); + assert_param(IS_TIM_OC_POLARITY(sConfig->OCPolarity)); + assert_param(IS_TIM_FAST_STATE(sConfig->OCFastMode)); + + /* Process Locked */ + __HAL_LOCK(htim); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + + /* Configure the Channel 1 in PWM mode */ + TIM_OC1_SetConfig(htim->Instance, sConfig); + + /* Set the Preload enable bit for channel1 */ + htim->Instance->CCMR1 |= TIM_CCMR1_OC1PE; + + /* Configure the Output Fast mode */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_OC1FE; + htim->Instance->CCMR1 |= sConfig->OCFastMode; + break; + } + + case TIM_CHANNEL_2: + { + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + /* Configure the Channel 2 in PWM mode */ + TIM_OC2_SetConfig(htim->Instance, sConfig); + + /* Set the Preload enable bit for channel2 */ + htim->Instance->CCMR1 |= TIM_CCMR1_OC2PE; + + /* Configure the Output Fast mode */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_OC2FE; + htim->Instance->CCMR1 |= sConfig->OCFastMode << 8U; + break; + } + + case TIM_CHANNEL_3: + { + /* Check the parameters */ + assert_param(IS_TIM_CC3_INSTANCE(htim->Instance)); + + /* Configure the Channel 3 in PWM mode */ + TIM_OC3_SetConfig(htim->Instance, sConfig); + + /* Set the Preload enable bit for channel3 */ + htim->Instance->CCMR2 |= TIM_CCMR2_OC3PE; + + /* Configure the Output Fast mode */ + htim->Instance->CCMR2 &= ~TIM_CCMR2_OC3FE; + htim->Instance->CCMR2 |= sConfig->OCFastMode; + break; + } + + case TIM_CHANNEL_4: + { + /* Check the parameters */ + assert_param(IS_TIM_CC4_INSTANCE(htim->Instance)); + + /* Configure the Channel 4 in PWM mode */ + TIM_OC4_SetConfig(htim->Instance, sConfig); + + /* Set the Preload enable bit for channel4 */ + htim->Instance->CCMR2 |= TIM_CCMR2_OC4PE; + + /* Configure the Output Fast mode */ + htim->Instance->CCMR2 &= ~TIM_CCMR2_OC4FE; + htim->Instance->CCMR2 |= sConfig->OCFastMode << 8U; + break; + } + + case TIM_CHANNEL_5: + { + /* Check the parameters */ + assert_param(IS_TIM_CC5_INSTANCE(htim->Instance)); + + /* Configure the Channel 5 in PWM mode */ + TIM_OC5_SetConfig(htim->Instance, sConfig); + + /* Set the Preload enable bit for channel5*/ + htim->Instance->CCMR3 |= TIM_CCMR3_OC5PE; + + /* Configure the Output Fast mode */ + htim->Instance->CCMR3 &= ~TIM_CCMR3_OC5FE; + htim->Instance->CCMR3 |= sConfig->OCFastMode; + break; + } + + case TIM_CHANNEL_6: + { + /* Check the parameters */ + assert_param(IS_TIM_CC6_INSTANCE(htim->Instance)); + + /* Configure the Channel 6 in PWM mode */ + TIM_OC6_SetConfig(htim->Instance, sConfig); + + /* Set the Preload enable bit for channel6 */ + htim->Instance->CCMR3 |= TIM_CCMR3_OC6PE; + + /* Configure the Output Fast mode */ + htim->Instance->CCMR3 &= ~TIM_CCMR3_OC6FE; + htim->Instance->CCMR3 |= sConfig->OCFastMode << 8U; + break; + } + + default: + status = HAL_ERROR; + break; + } + + __HAL_UNLOCK(htim); + + return status; +} + +/** + * @brief Initializes the TIM One Pulse Channels according to the specified + * parameters in the TIM_OnePulse_InitTypeDef. + * @param htim TIM One Pulse handle + * @param sConfig TIM One Pulse configuration structure + * @param OutputChannel TIM output channel to configure + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @param InputChannel TIM input Channel to configure + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @note To output a waveform with a minimum delay user can enable the fast + * mode by calling the @ref __HAL_TIM_ENABLE_OCxFAST macro. Then CCx + * output is forced in response to the edge detection on TIx input, + * without taking in account the comparison. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OnePulse_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OnePulse_InitTypeDef *sConfig, + uint32_t OutputChannel, uint32_t InputChannel) +{ + HAL_StatusTypeDef status = HAL_OK; + TIM_OC_InitTypeDef temp1; + + /* Check the parameters */ + assert_param(IS_TIM_OPM_CHANNELS(OutputChannel)); + assert_param(IS_TIM_OPM_CHANNELS(InputChannel)); + + if (OutputChannel != InputChannel) + { + /* Process Locked */ + __HAL_LOCK(htim); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Extract the Output compare configuration from sConfig structure */ + temp1.OCMode = sConfig->OCMode; + temp1.Pulse = sConfig->Pulse; + temp1.OCPolarity = sConfig->OCPolarity; + temp1.OCNPolarity = sConfig->OCNPolarity; + temp1.OCIdleState = sConfig->OCIdleState; + temp1.OCNIdleState = sConfig->OCNIdleState; + + switch (OutputChannel) + { + case TIM_CHANNEL_1: + { + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + + TIM_OC1_SetConfig(htim->Instance, &temp1); + break; + } + + case TIM_CHANNEL_2: + { + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + TIM_OC2_SetConfig(htim->Instance, &temp1); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + switch (InputChannel) + { + case TIM_CHANNEL_1: + { + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + + TIM_TI1_SetConfig(htim->Instance, sConfig->ICPolarity, + sConfig->ICSelection, sConfig->ICFilter); + + /* Reset the IC1PSC Bits */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC; + + /* Select the Trigger source */ + htim->Instance->SMCR &= ~TIM_SMCR_TS; + htim->Instance->SMCR |= TIM_TS_TI1FP1; + + /* Select the Slave Mode */ + htim->Instance->SMCR &= ~TIM_SMCR_SMS; + htim->Instance->SMCR |= TIM_SLAVEMODE_TRIGGER; + break; + } + + case TIM_CHANNEL_2: + { + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + TIM_TI2_SetConfig(htim->Instance, sConfig->ICPolarity, + sConfig->ICSelection, sConfig->ICFilter); + + /* Reset the IC2PSC Bits */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_IC2PSC; + + /* Select the Trigger source */ + htim->Instance->SMCR &= ~TIM_SMCR_TS; + htim->Instance->SMCR |= TIM_TS_TI2FP2; + + /* Select the Slave Mode */ + htim->Instance->SMCR &= ~TIM_SMCR_SMS; + htim->Instance->SMCR |= TIM_SLAVEMODE_TRIGGER; + break; + } + + default: + status = HAL_ERROR; + break; + } + } + + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return status; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Configure the DMA Burst to transfer Data from the memory to the TIM peripheral + * @param htim TIM handle + * @param BurstBaseAddress TIM Base address from where the DMA will start the Data write + * This parameter can be one of the following values: + * @arg TIM_DMABASE_CR1 + * @arg TIM_DMABASE_CR2 + * @arg TIM_DMABASE_SMCR + * @arg TIM_DMABASE_DIER + * @arg TIM_DMABASE_SR + * @arg TIM_DMABASE_EGR + * @arg TIM_DMABASE_CCMR1 + * @arg TIM_DMABASE_CCMR2 + * @arg TIM_DMABASE_CCER + * @arg TIM_DMABASE_CNT + * @arg TIM_DMABASE_PSC + * @arg TIM_DMABASE_ARR + * @arg TIM_DMABASE_RCR + * @arg TIM_DMABASE_CCR1 + * @arg TIM_DMABASE_CCR2 + * @arg TIM_DMABASE_CCR3 + * @arg TIM_DMABASE_CCR4 + * @arg TIM_DMABASE_BDTR + * @arg TIM_DMABASE_CCMR3 + * @arg TIM_DMABASE_CCR5 + * @arg TIM_DMABASE_CCR6 + * @arg TIM_DMABASE_DTR2 + * @arg TIM_DMABASE_ECR + * @arg TIM_DMABASE_TISEL + * @arg TIM_DMABASE_AF1 + * @arg TIM_DMABASE_AF2 + * @param BurstRequestSrc TIM DMA Request sources + * This parameter can be one of the following values: + * @arg TIM_DMA_UPDATE: TIM update Interrupt source + * @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source + * @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source + * @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source + * @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source + * @arg TIM_DMA_COM: TIM Commutation DMA source + * @arg TIM_DMA_TRIGGER: TIM Trigger DMA source + * @param BurstBuffer The Buffer address. + * @param BurstLength DMA Burst length. This parameter can be one value + * between: TIM_DMABURSTLENGTH_1TRANSFER and TIM_DMABURSTLENGTH_26TRANSFER. + * @note This function should be used only when BurstLength is equal to DMA data transfer length. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_DMABurst_WriteStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, + uint32_t BurstRequestSrc, const uint32_t *BurstBuffer, uint32_t BurstLength) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t BlockDataLength = 0; + uint32_t data_width; + const DMA_HandleTypeDef *hdma = NULL; + + assert_param(IS_TIM_DMA_SOURCE(BurstRequestSrc)); + + switch (BurstRequestSrc) + { + case TIM_DMA_UPDATE: + { + hdma = htim->hdma[TIM_DMA_ID_UPDATE]; + break; + } + case TIM_DMA_CC1: + { + hdma = htim->hdma[TIM_DMA_ID_CC1]; + break; + } + case TIM_DMA_CC2: + { + hdma = htim->hdma[TIM_DMA_ID_CC2]; + break; + } + case TIM_DMA_CC3: + { + hdma = htim->hdma[TIM_DMA_ID_CC3]; + break; + } + case TIM_DMA_CC4: + { + hdma = htim->hdma[TIM_DMA_ID_CC4]; + break; + } + case TIM_DMA_COM: + { + hdma = htim->hdma[TIM_DMA_ID_COMMUTATION]; + break; + } + case TIM_DMA_TRIGGER: + { + hdma = htim->hdma[TIM_DMA_ID_TRIGGER]; + break; + } + default: + status = HAL_ERROR; + break; + } + + if (hdma != NULL) + { + + if (((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) && (hdma->LinkedListQueue != 0U) + && (hdma->LinkedListQueue->Head != 0U)) + { + data_width = hdma->LinkedListQueue->Head->LinkRegisters[0] & DMA_CTR1_SDW_LOG2; + } + else + { + data_width = hdma->Init.SrcDataWidth; + } + + switch (data_width) + { + case DMA_SRC_DATAWIDTH_BYTE: + { + BlockDataLength = (BurstLength >> TIM_DCR_DBL_Pos) + 1UL; + break; + } + case DMA_SRC_DATAWIDTH_HALFWORD: + { + BlockDataLength = ((BurstLength >> TIM_DCR_DBL_Pos) + 1UL) * 2UL; + break; + } + case DMA_SRC_DATAWIDTH_WORD: + { + BlockDataLength = ((BurstLength >> TIM_DCR_DBL_Pos) + 1UL) * 4UL; + break; + } + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + status = HAL_TIM_DMABurst_MultiWriteStart(htim, BurstBaseAddress, BurstRequestSrc, BurstBuffer, BurstLength, + BlockDataLength); + } + } + + + return status; +} + +/** + * @brief Configure the DMA Burst to transfer multiple Data from the memory to the TIM peripheral + * @param htim TIM handle + * @param BurstBaseAddress TIM Base address from where the DMA will start the Data write + * This parameter can be one of the following values: + * @arg TIM_DMABASE_CR1 + * @arg TIM_DMABASE_CR2 + * @arg TIM_DMABASE_SMCR + * @arg TIM_DMABASE_DIER + * @arg TIM_DMABASE_SR + * @arg TIM_DMABASE_EGR + * @arg TIM_DMABASE_CCMR1 + * @arg TIM_DMABASE_CCMR2 + * @arg TIM_DMABASE_CCER + * @arg TIM_DMABASE_CNT + * @arg TIM_DMABASE_PSC + * @arg TIM_DMABASE_ARR + * @arg TIM_DMABASE_RCR + * @arg TIM_DMABASE_CCR1 + * @arg TIM_DMABASE_CCR2 + * @arg TIM_DMABASE_CCR3 + * @arg TIM_DMABASE_CCR4 + * @arg TIM_DMABASE_BDTR + * @arg TIM_DMABASE_CCMR3 + * @arg TIM_DMABASE_CCR5 + * @arg TIM_DMABASE_CCR6 + * @arg TIM_DMABASE_DTR2 + * @arg TIM_DMABASE_ECR + * @arg TIM_DMABASE_TISEL + * @arg TIM_DMABASE_AF1 + * @arg TIM_DMABASE_AF2 + * @param BurstRequestSrc TIM DMA Request sources + * This parameter can be one of the following values: + * @arg TIM_DMA_UPDATE: TIM update Interrupt source + * @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source + * @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source + * @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source + * @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source + * @arg TIM_DMA_COM: TIM Commutation DMA source + * @arg TIM_DMA_TRIGGER: TIM Trigger DMA source + * @param BurstBuffer The Buffer address. + * @param BurstLength DMA Burst length. This parameter can be one value + * between: TIM_DMABURSTLENGTH_1TRANSFER and TIM_DMABURSTLENGTH_26TRANSFER. + * @param DataLength Data length. This parameter can be one value + * between 1 and 0xFFFF. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_DMABurst_MultiWriteStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, + uint32_t BurstRequestSrc, const uint32_t *BurstBuffer, + uint32_t BurstLength, uint32_t DataLength) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpDBSS = 0; + + /* Check the parameters */ + assert_param(IS_TIM_DMABURST_INSTANCE(htim->Instance)); + assert_param(IS_TIM_DMA_BASE(BurstBaseAddress)); + assert_param(IS_TIM_DMA_SOURCE(BurstRequestSrc)); + assert_param(IS_TIM_DMA_LENGTH(BurstLength)); + assert_param(IS_TIM_DMA_DATA_LENGTH(DataLength)); + + if (htim->DMABurstState == HAL_DMA_BURST_STATE_BUSY) + { + return HAL_BUSY; + } + else if (htim->DMABurstState == HAL_DMA_BURST_STATE_READY) + { + if ((BurstBuffer == NULL) && (BurstLength > 0U)) + { + return HAL_ERROR; + } + else + { + htim->DMABurstState = HAL_DMA_BURST_STATE_BUSY; + } + } + else + { + /* nothing to do */ + } + + switch (BurstRequestSrc) + { + case TIM_DMA_UPDATE: + { + /* Set the DMA Period elapsed callbacks */ + htim->hdma[TIM_DMA_ID_UPDATE]->XferCpltCallback = TIM_DMAPeriodElapsedCplt; + htim->hdma[TIM_DMA_ID_UPDATE]->XferHalfCpltCallback = TIM_DMAPeriodElapsedHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_UPDATE]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_UPDATE], (uint32_t)BurstBuffer, + (uint32_t)&htim->Instance->DMAR, DataLength) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Configure the DMA Burst Source Selection */ + tmpDBSS = TIM_DCR_DBSS_0; + break; + } + case TIM_DMA_CC1: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)BurstBuffer, + (uint32_t)&htim->Instance->DMAR, DataLength) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Configure the DMA Burst Source Selection */ + tmpDBSS = TIM_DCR_DBSS_1; + break; + } + case TIM_DMA_CC2: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)BurstBuffer, + (uint32_t)&htim->Instance->DMAR, DataLength) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Configure the DMA Burst Source Selection */ + tmpDBSS = (TIM_DCR_DBSS_1 | TIM_DCR_DBSS_0); + break; + } + case TIM_DMA_CC3: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)BurstBuffer, + (uint32_t)&htim->Instance->DMAR, DataLength) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Configure the DMA Burst Source Selection */ + tmpDBSS = TIM_DCR_DBSS_2; + break; + } + case TIM_DMA_CC4: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC4]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)BurstBuffer, + (uint32_t)&htim->Instance->DMAR, DataLength) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Configure the DMA Burst Source Selection */ + tmpDBSS = (TIM_DCR_DBSS_2 | TIM_DCR_DBSS_0); + break; + } + case TIM_DMA_COM: + { + /* Set the DMA commutation callbacks */ + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferCpltCallback = TIMEx_DMACommutationCplt; + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferHalfCpltCallback = TIMEx_DMACommutationHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_COMMUTATION], (uint32_t)BurstBuffer, + (uint32_t)&htim->Instance->DMAR, DataLength) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Configure the DMA Burst Source Selection */ + tmpDBSS = (TIM_DCR_DBSS_2 | TIM_DCR_DBSS_1); + break; + } + case TIM_DMA_TRIGGER: + { + /* Set the DMA trigger callbacks */ + htim->hdma[TIM_DMA_ID_TRIGGER]->XferCpltCallback = TIM_DMATriggerCplt; + htim->hdma[TIM_DMA_ID_TRIGGER]->XferHalfCpltCallback = TIM_DMATriggerHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_TRIGGER]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_TRIGGER], (uint32_t)BurstBuffer, + (uint32_t)&htim->Instance->DMAR, DataLength) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Configure the DMA Burst Source Selection */ + tmpDBSS = (TIM_DCR_DBSS_2 | TIM_DCR_DBSS_1 | TIM_DCR_DBSS_0); + break; + } + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Configure the DMA Burst Mode */ + htim->Instance->DCR = (BurstBaseAddress | BurstLength | tmpDBSS); + /* Enable the TIM DMA Request */ + __HAL_TIM_ENABLE_DMA(htim, BurstRequestSrc); + } + + /* Return function status */ + return status; +} + +/** + * @brief Stops the TIM DMA Burst mode + * @param htim TIM handle + * @param BurstRequestSrc TIM DMA Request sources to disable + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_DMABurst_WriteStop(TIM_HandleTypeDef *htim, uint32_t BurstRequestSrc) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_DMA_SOURCE(BurstRequestSrc)); + + /* Abort the DMA transfer (at least disable the DMA channel) */ + switch (BurstRequestSrc) + { + case TIM_DMA_UPDATE: + { + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_UPDATE]); + break; + } + case TIM_DMA_CC1: + { + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + break; + } + case TIM_DMA_CC2: + { + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); + break; + } + case TIM_DMA_CC3: + { + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]); + break; + } + case TIM_DMA_CC4: + { + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC4]); + break; + } + case TIM_DMA_COM: + { + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_COMMUTATION]); + break; + } + case TIM_DMA_TRIGGER: + { + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_TRIGGER]); + break; + } + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Disable the TIM Update DMA request */ + __HAL_TIM_DISABLE_DMA(htim, BurstRequestSrc); + + /* Change the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_READY; + } + + /* Return function status */ + return status; +} + +/** + * @brief Configure the DMA Burst to transfer Data from the TIM peripheral to the memory + * @param htim TIM handle + * @param BurstBaseAddress TIM Base address from where the DMA will start the Data read + * This parameter can be one of the following values: + * @arg TIM_DMABASE_CR1 + * @arg TIM_DMABASE_CR2 + * @arg TIM_DMABASE_SMCR + * @arg TIM_DMABASE_DIER + * @arg TIM_DMABASE_SR + * @arg TIM_DMABASE_EGR + * @arg TIM_DMABASE_CCMR1 + * @arg TIM_DMABASE_CCMR2 + * @arg TIM_DMABASE_CCER + * @arg TIM_DMABASE_CNT + * @arg TIM_DMABASE_PSC + * @arg TIM_DMABASE_ARR + * @arg TIM_DMABASE_RCR + * @arg TIM_DMABASE_CCR1 + * @arg TIM_DMABASE_CCR2 + * @arg TIM_DMABASE_CCR3 + * @arg TIM_DMABASE_CCR4 + * @arg TIM_DMABASE_BDTR + * @arg TIM_DMABASE_CCMR3 + * @arg TIM_DMABASE_CCR5 + * @arg TIM_DMABASE_CCR6 + * @arg TIM_DMABASE_DTR2 + * @arg TIM_DMABASE_ECR + * @arg TIM_DMABASE_TISEL + * @arg TIM_DMABASE_AF1 + * @arg TIM_DMABASE_AF2 + * @param BurstRequestSrc TIM DMA Request sources + * This parameter can be one of the following values: + * @arg TIM_DMA_UPDATE: TIM update Interrupt source + * @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source + * @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source + * @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source + * @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source + * @arg TIM_DMA_COM: TIM Commutation DMA source + * @arg TIM_DMA_TRIGGER: TIM Trigger DMA source + * @param BurstBuffer The Buffer address. + * @param BurstLength DMA Burst length. This parameter can be one value + * between: TIM_DMABURSTLENGTH_1TRANSFER and TIM_DMABURSTLENGTH_26TRANSFER. + * @note This function should be used only when BurstLength is equal to DMA data transfer length. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, + uint32_t BurstRequestSrc, uint32_t *BurstBuffer, uint32_t BurstLength) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t BlockDataLength = 0; + uint32_t data_width; + const DMA_HandleTypeDef *hdma = NULL; + + assert_param(IS_TIM_DMA_SOURCE(BurstRequestSrc)); + + switch (BurstRequestSrc) + { + case TIM_DMA_UPDATE: + { + hdma = htim->hdma[TIM_DMA_ID_UPDATE]; + break; + } + case TIM_DMA_CC1: + { + hdma = htim->hdma[TIM_DMA_ID_CC1]; + break; + } + case TIM_DMA_CC2: + { + hdma = htim->hdma[TIM_DMA_ID_CC2]; + break; + } + case TIM_DMA_CC3: + { + hdma = htim->hdma[TIM_DMA_ID_CC3]; + break; + } + case TIM_DMA_CC4: + { + hdma = htim->hdma[TIM_DMA_ID_CC4]; + break; + } + case TIM_DMA_COM: + { + hdma = htim->hdma[TIM_DMA_ID_COMMUTATION]; + break; + } + case TIM_DMA_TRIGGER: + { + hdma = htim->hdma[TIM_DMA_ID_TRIGGER]; + break; + } + default: + status = HAL_ERROR; + break; + } + + if (hdma != NULL) + { + + if (((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) && (hdma->LinkedListQueue != 0U) + && (hdma->LinkedListQueue->Head != 0U)) + { + data_width = hdma->LinkedListQueue->Head->LinkRegisters[0] & DMA_CTR1_SDW_LOG2; + } + else + { + data_width = hdma->Init.SrcDataWidth; + } + + switch (data_width) + + { + case DMA_SRC_DATAWIDTH_BYTE: + { + BlockDataLength = ((BurstLength) >> TIM_DCR_DBL_Pos) + 1UL; + break; + } + case DMA_SRC_DATAWIDTH_HALFWORD: + { + BlockDataLength = ((BurstLength >> TIM_DCR_DBL_Pos) + 1UL) * 2UL; + break; + } + case DMA_SRC_DATAWIDTH_WORD: + { + BlockDataLength = ((BurstLength >> TIM_DCR_DBL_Pos) + 1UL) * 4UL; + break; + } + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + status = HAL_TIM_DMABurst_MultiReadStart(htim, BurstBaseAddress, BurstRequestSrc, BurstBuffer, BurstLength, + BlockDataLength); + } + } + + return status; +} + +/** + * @brief Configure the DMA Burst to transfer Data from the TIM peripheral to the memory + * @param htim TIM handle + * @param BurstBaseAddress TIM Base address from where the DMA will start the Data read + * This parameter can be one of the following values: + * @arg TIM_DMABASE_CR1 + * @arg TIM_DMABASE_CR2 + * @arg TIM_DMABASE_SMCR + * @arg TIM_DMABASE_DIER + * @arg TIM_DMABASE_SR + * @arg TIM_DMABASE_EGR + * @arg TIM_DMABASE_CCMR1 + * @arg TIM_DMABASE_CCMR2 + * @arg TIM_DMABASE_CCER + * @arg TIM_DMABASE_CNT + * @arg TIM_DMABASE_PSC + * @arg TIM_DMABASE_ARR + * @arg TIM_DMABASE_RCR + * @arg TIM_DMABASE_CCR1 + * @arg TIM_DMABASE_CCR2 + * @arg TIM_DMABASE_CCR3 + * @arg TIM_DMABASE_CCR4 + * @arg TIM_DMABASE_BDTR + * @arg TIM_DMABASE_CCMR3 + * @arg TIM_DMABASE_CCR5 + * @arg TIM_DMABASE_CCR6 + * @arg TIM_DMABASE_DTR2 + * @arg TIM_DMABASE_ECR + * @arg TIM_DMABASE_TISEL + * @arg TIM_DMABASE_AF1 + * @arg TIM_DMABASE_AF2 + * @param BurstRequestSrc TIM DMA Request sources + * This parameter can be one of the following values: + * @arg TIM_DMA_UPDATE: TIM update Interrupt source + * @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source + * @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source + * @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source + * @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source + * @arg TIM_DMA_COM: TIM Commutation DMA source + * @arg TIM_DMA_TRIGGER: TIM Trigger DMA source + * @param BurstBuffer The Buffer address. + * @param BurstLength DMA Burst length. This parameter can be one value + * between: TIM_DMABURSTLENGTH_1TRANSFER and TIM_DMABURSTLENGTH_26TRANSFER. + * @param DataLength Data length. This parameter can be one value + * between 1 and 0xFFFF. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_DMABurst_MultiReadStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, + uint32_t BurstRequestSrc, uint32_t *BurstBuffer, + uint32_t BurstLength, uint32_t DataLength) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpDBSS = 0; + + /* Check the parameters */ + assert_param(IS_TIM_DMABURST_INSTANCE(htim->Instance)); + assert_param(IS_TIM_DMA_BASE(BurstBaseAddress)); + assert_param(IS_TIM_DMA_SOURCE(BurstRequestSrc)); + assert_param(IS_TIM_DMA_LENGTH(BurstLength)); + assert_param(IS_TIM_DMA_DATA_LENGTH(DataLength)); + + if (htim->DMABurstState == HAL_DMA_BURST_STATE_BUSY) + { + return HAL_BUSY; + } + else if (htim->DMABurstState == HAL_DMA_BURST_STATE_READY) + { + if ((BurstBuffer == NULL) && (BurstLength > 0U)) + { + return HAL_ERROR; + } + else + { + htim->DMABurstState = HAL_DMA_BURST_STATE_BUSY; + } + } + else + { + /* nothing to do */ + } + switch (BurstRequestSrc) + { + case TIM_DMA_UPDATE: + { + /* Set the DMA Period elapsed callbacks */ + htim->hdma[TIM_DMA_ID_UPDATE]->XferCpltCallback = TIM_DMAPeriodElapsedCplt; + htim->hdma[TIM_DMA_ID_UPDATE]->XferHalfCpltCallback = TIM_DMAPeriodElapsedHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_UPDATE]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_UPDATE], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, + DataLength) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Configure the DMA Burst Source Selection */ + tmpDBSS = TIM_DCR_DBSS_0; + break; + } + case TIM_DMA_CC1: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, + DataLength) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Configure the DMA Burst Source Selection */ + tmpDBSS = TIM_DCR_DBSS_1; + break; + } + case TIM_DMA_CC2: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, + DataLength) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Configure the DMA Burst Source Selection */ + tmpDBSS = (TIM_DCR_DBSS_1 | TIM_DCR_DBSS_0); + break; + } + case TIM_DMA_CC3: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, + DataLength) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Configure the DMA Burst Source Selection */ + tmpDBSS = TIM_DCR_DBSS_2; + break; + } + case TIM_DMA_CC4: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC4]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, + DataLength) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Configure the DMA Burst Source Selection */ + tmpDBSS = (TIM_DCR_DBSS_2 | TIM_DCR_DBSS_0); + break; + } + case TIM_DMA_COM: + { + /* Set the DMA commutation callbacks */ + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferCpltCallback = TIMEx_DMACommutationCplt; + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferHalfCpltCallback = TIMEx_DMACommutationHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_COMMUTATION], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, + DataLength) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Configure the DMA Burst Source Selection */ + tmpDBSS = (TIM_DCR_DBSS_2 | TIM_DCR_DBSS_1); + break; + } + case TIM_DMA_TRIGGER: + { + /* Set the DMA trigger callbacks */ + htim->hdma[TIM_DMA_ID_TRIGGER]->XferCpltCallback = TIM_DMATriggerCplt; + htim->hdma[TIM_DMA_ID_TRIGGER]->XferHalfCpltCallback = TIM_DMATriggerHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_TRIGGER]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_TRIGGER], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, + DataLength) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Configure the DMA Burst Source Selection */ + tmpDBSS = (TIM_DCR_DBSS_2 | TIM_DCR_DBSS_1 | TIM_DCR_DBSS_0); + break; + } + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Configure the DMA Burst Mode */ + htim->Instance->DCR = (BurstBaseAddress | BurstLength | tmpDBSS); + + /* Enable the TIM DMA Request */ + __HAL_TIM_ENABLE_DMA(htim, BurstRequestSrc); + } + + /* Return function status */ + return status; +} + +/** + * @brief Stop the DMA burst reading + * @param htim TIM handle + * @param BurstRequestSrc TIM DMA Request sources to disable. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStop(TIM_HandleTypeDef *htim, uint32_t BurstRequestSrc) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_DMA_SOURCE(BurstRequestSrc)); + + /* Abort the DMA transfer (at least disable the DMA channel) */ + switch (BurstRequestSrc) + { + case TIM_DMA_UPDATE: + { + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_UPDATE]); + break; + } + case TIM_DMA_CC1: + { + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + break; + } + case TIM_DMA_CC2: + { + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); + break; + } + case TIM_DMA_CC3: + { + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]); + break; + } + case TIM_DMA_CC4: + { + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC4]); + break; + } + case TIM_DMA_COM: + { + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_COMMUTATION]); + break; + } + case TIM_DMA_TRIGGER: + { + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_TRIGGER]); + break; + } + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Disable the TIM Update DMA request */ + __HAL_TIM_DISABLE_DMA(htim, BurstRequestSrc); + + /* Change the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_READY; + } + + /* Return function status */ + return status; +} + +/** + * @brief Generate a software event + * @param htim TIM handle + * @param EventSource specifies the event source. + * This parameter can be one of the following values: + * @arg TIM_EVENTSOURCE_UPDATE: Timer update Event source + * @arg TIM_EVENTSOURCE_CC1: Timer Capture Compare 1 Event source + * @arg TIM_EVENTSOURCE_CC2: Timer Capture Compare 2 Event source + * @arg TIM_EVENTSOURCE_CC3: Timer Capture Compare 3 Event source + * @arg TIM_EVENTSOURCE_CC4: Timer Capture Compare 4 Event source + * @arg TIM_EVENTSOURCE_COM: Timer COM event source + * @arg TIM_EVENTSOURCE_TRIGGER: Timer Trigger Event source + * @arg TIM_EVENTSOURCE_BREAK: Timer Break event source + * @arg TIM_EVENTSOURCE_BREAK2: Timer Break2 event source + * @note Basic timers can only generate an update event. + * @note TIM_EVENTSOURCE_COM is relevant only with advanced timer instances. + * @note TIM_EVENTSOURCE_BREAK and TIM_EVENTSOURCE_BREAK2 are relevant + * only for timer instances supporting break input(s). + * @retval HAL status + */ + +HAL_StatusTypeDef HAL_TIM_GenerateEvent(TIM_HandleTypeDef *htim, uint32_t EventSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + assert_param(IS_TIM_EVENT_SOURCE(EventSource)); + + /* Process Locked */ + __HAL_LOCK(htim); + + /* Change the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Set the event sources */ + htim->Instance->EGR = EventSource; + + /* Change the TIM state */ + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Configures the OCRef clear feature + * @param htim TIM handle + * @param sClearInputConfig pointer to a TIM_ClearInputConfigTypeDef structure that + * contains the OCREF clear feature and parameters for the TIM peripheral. + * @param Channel specifies the TIM Channel + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 + * @arg TIM_CHANNEL_2: TIM Channel 2 + * @arg TIM_CHANNEL_3: TIM Channel 3 + * @arg TIM_CHANNEL_4: TIM Channel 4 + * @arg TIM_CHANNEL_5: TIM Channel 5 + * @arg TIM_CHANNEL_6: TIM Channel 6 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_ConfigOCrefClear(TIM_HandleTypeDef *htim, + const TIM_ClearInputConfigTypeDef *sClearInputConfig, + uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_OCXREF_CLEAR_INSTANCE(htim->Instance)); + assert_param(IS_TIM_CLEARINPUT_SOURCE(sClearInputConfig->ClearInputSource)); + + /* Process Locked */ + __HAL_LOCK(htim); + + htim->State = HAL_TIM_STATE_BUSY; + + switch (sClearInputConfig->ClearInputSource) + { + case TIM_CLEARINPUTSOURCE_NONE: + { + /* Clear the OCREF clear selection bit and the the ETR Bits */ + CLEAR_BIT(htim->Instance->SMCR, (TIM_SMCR_OCCS | TIM_SMCR_ETF | TIM_SMCR_ETPS | TIM_SMCR_ECE | TIM_SMCR_ETP)); + break; + } + case TIM_CLEARINPUTSOURCE_OCREFCLR: + { + /* Clear the OCREF clear selection bit */ + CLEAR_BIT(htim->Instance->SMCR, TIM_SMCR_OCCS); + break; + } + + case TIM_CLEARINPUTSOURCE_ETR: + { + /* Check the parameters */ + assert_param(IS_TIM_CLEARINPUT_POLARITY(sClearInputConfig->ClearInputPolarity)); + assert_param(IS_TIM_CLEARINPUT_PRESCALER(sClearInputConfig->ClearInputPrescaler)); + assert_param(IS_TIM_CLEARINPUT_FILTER(sClearInputConfig->ClearInputFilter)); + + /* When OCRef clear feature is used with ETR source, ETR prescaler must be off */ + if (sClearInputConfig->ClearInputPrescaler != TIM_CLEARINPUTPRESCALER_DIV1) + { + htim->State = HAL_TIM_STATE_READY; + __HAL_UNLOCK(htim); + return HAL_ERROR; + } + + TIM_ETR_SetConfig(htim->Instance, + sClearInputConfig->ClearInputPrescaler, + sClearInputConfig->ClearInputPolarity, + sClearInputConfig->ClearInputFilter); + + /* Set the OCREF clear selection bit */ + SET_BIT(htim->Instance->SMCR, TIM_SMCR_OCCS); + + /* Clear TIMx_AF2_OCRSEL (reset value) */ + CLEAR_BIT(htim->Instance->AF2, TIMx_AF2_OCRSEL); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + switch (Channel) + { + case TIM_CHANNEL_1: + { + if (sClearInputConfig->ClearInputState != (uint32_t)DISABLE) + { + /* Enable the OCREF clear feature for Channel 1 */ + SET_BIT(htim->Instance->CCMR1, TIM_CCMR1_OC1CE); + } + else + { + /* Disable the OCREF clear feature for Channel 1 */ + CLEAR_BIT(htim->Instance->CCMR1, TIM_CCMR1_OC1CE); + } + break; + } + case TIM_CHANNEL_2: + { + if (sClearInputConfig->ClearInputState != (uint32_t)DISABLE) + { + /* Enable the OCREF clear feature for Channel 2 */ + SET_BIT(htim->Instance->CCMR1, TIM_CCMR1_OC2CE); + } + else + { + /* Disable the OCREF clear feature for Channel 2 */ + CLEAR_BIT(htim->Instance->CCMR1, TIM_CCMR1_OC2CE); + } + break; + } + case TIM_CHANNEL_3: + { + if (sClearInputConfig->ClearInputState != (uint32_t)DISABLE) + { + /* Enable the OCREF clear feature for Channel 3 */ + SET_BIT(htim->Instance->CCMR2, TIM_CCMR2_OC3CE); + } + else + { + /* Disable the OCREF clear feature for Channel 3 */ + CLEAR_BIT(htim->Instance->CCMR2, TIM_CCMR2_OC3CE); + } + break; + } + case TIM_CHANNEL_4: + { + if (sClearInputConfig->ClearInputState != (uint32_t)DISABLE) + { + /* Enable the OCREF clear feature for Channel 4 */ + SET_BIT(htim->Instance->CCMR2, TIM_CCMR2_OC4CE); + } + else + { + /* Disable the OCREF clear feature for Channel 4 */ + CLEAR_BIT(htim->Instance->CCMR2, TIM_CCMR2_OC4CE); + } + break; + } + case TIM_CHANNEL_5: + { + if (sClearInputConfig->ClearInputState != (uint32_t)DISABLE) + { + /* Enable the OCREF clear feature for Channel 5 */ + SET_BIT(htim->Instance->CCMR3, TIM_CCMR3_OC5CE); + } + else + { + /* Disable the OCREF clear feature for Channel 5 */ + CLEAR_BIT(htim->Instance->CCMR3, TIM_CCMR3_OC5CE); + } + break; + } + case TIM_CHANNEL_6: + { + if (sClearInputConfig->ClearInputState != (uint32_t)DISABLE) + { + /* Enable the OCREF clear feature for Channel 6 */ + SET_BIT(htim->Instance->CCMR3, TIM_CCMR3_OC6CE); + } + else + { + /* Disable the OCREF clear feature for Channel 6 */ + CLEAR_BIT(htim->Instance->CCMR3, TIM_CCMR3_OC6CE); + } + break; + } + default: + break; + } + } + + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return status; +} + +/** + * @brief Configures the clock source to be used + * @param htim TIM handle + * @param sClockSourceConfig pointer to a TIM_ClockConfigTypeDef structure that + * contains the clock source information for the TIM peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_ConfigClockSource(TIM_HandleTypeDef *htim, const TIM_ClockConfigTypeDef *sClockSourceConfig) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpsmcr; + + /* Process Locked */ + __HAL_LOCK(htim); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Check the parameters */ + assert_param(IS_TIM_CLOCKSOURCE(sClockSourceConfig->ClockSource)); + + /* Reset the SMS, TS, ECE, ETPS and ETRF bits */ + tmpsmcr = htim->Instance->SMCR; + tmpsmcr &= ~(TIM_SMCR_SMS | TIM_SMCR_TS); + tmpsmcr &= ~(TIM_SMCR_ETF | TIM_SMCR_ETPS | TIM_SMCR_ECE | TIM_SMCR_ETP); + htim->Instance->SMCR = tmpsmcr; + + switch (sClockSourceConfig->ClockSource) + { + case TIM_CLOCKSOURCE_INTERNAL: + { + assert_param(IS_TIM_INSTANCE(htim->Instance)); + break; + } + + case TIM_CLOCKSOURCE_ETRMODE1: + { + /* Check whether or not the timer instance supports external trigger input mode 1 (ETRF)*/ + assert_param(IS_TIM_CLOCKSOURCE_ETRMODE1_INSTANCE(htim->Instance)); + + /* Check ETR input conditioning related parameters */ + assert_param(IS_TIM_CLOCKPRESCALER(sClockSourceConfig->ClockPrescaler)); + assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity)); + assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter)); + + /* Configure the ETR Clock source */ + TIM_ETR_SetConfig(htim->Instance, + sClockSourceConfig->ClockPrescaler, + sClockSourceConfig->ClockPolarity, + sClockSourceConfig->ClockFilter); + + /* Select the External clock mode1 and the ETRF trigger */ + tmpsmcr = htim->Instance->SMCR; + tmpsmcr |= (TIM_SLAVEMODE_EXTERNAL1 | TIM_CLOCKSOURCE_ETRMODE1); + /* Write to TIMx SMCR */ + htim->Instance->SMCR = tmpsmcr; + break; + } + + case TIM_CLOCKSOURCE_ETRMODE2: + { + /* Check whether or not the timer instance supports external trigger input mode 2 (ETRF)*/ + assert_param(IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(htim->Instance)); + + /* Check ETR input conditioning related parameters */ + assert_param(IS_TIM_CLOCKPRESCALER(sClockSourceConfig->ClockPrescaler)); + assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity)); + assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter)); + + /* Configure the ETR Clock source */ + TIM_ETR_SetConfig(htim->Instance, + sClockSourceConfig->ClockPrescaler, + sClockSourceConfig->ClockPolarity, + sClockSourceConfig->ClockFilter); + /* Enable the External clock mode2 */ + htim->Instance->SMCR |= TIM_SMCR_ECE; + break; + } + + case TIM_CLOCKSOURCE_TI1: + { + /* Check whether or not the timer instance supports external clock mode 1 */ + assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance)); + + /* Check TI1 input conditioning related parameters */ + assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity)); + assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter)); + + TIM_TI1_ConfigInputStage(htim->Instance, + sClockSourceConfig->ClockPolarity, + sClockSourceConfig->ClockFilter); + TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI1); + break; + } + + case TIM_CLOCKSOURCE_TI2: + { + /* Check whether or not the timer instance supports external clock mode 1 (ETRF)*/ + assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance)); + + /* Check TI2 input conditioning related parameters */ + assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity)); + assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter)); + + TIM_TI2_ConfigInputStage(htim->Instance, + sClockSourceConfig->ClockPolarity, + sClockSourceConfig->ClockFilter); + TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI2); + break; + } + + case TIM_CLOCKSOURCE_TI1ED: + { + /* Check whether or not the timer instance supports external clock mode 1 */ + assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance)); + + /* Check TI1 input conditioning related parameters */ + assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity)); + assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter)); + + TIM_TI1_ConfigInputStage(htim->Instance, + sClockSourceConfig->ClockPolarity, + sClockSourceConfig->ClockFilter); + TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI1ED); + break; + } + + case TIM_CLOCKSOURCE_ITR0: + case TIM_CLOCKSOURCE_ITR1: + case TIM_CLOCKSOURCE_ITR2: + case TIM_CLOCKSOURCE_ITR3: + case TIM_CLOCKSOURCE_ITR4: + case TIM_CLOCKSOURCE_ITR5: + case TIM_CLOCKSOURCE_ITR6: + case TIM_CLOCKSOURCE_ITR7: + case TIM_CLOCKSOURCE_ITR8: + case TIM_CLOCKSOURCE_ITR9: + case TIM_CLOCKSOURCE_ITR10: + case TIM_CLOCKSOURCE_ITR11: + case TIM_CLOCKSOURCE_ITR12: + { + /* Check whether or not the timer instance supports internal trigger input */ + assert_param(IS_TIM_CLOCKSOURCE_INSTANCE((htim->Instance), sClockSourceConfig->ClockSource)); + + TIM_ITRx_SetConfig(htim->Instance, sClockSourceConfig->ClockSource); + break; + } + + default: + status = HAL_ERROR; + break; + } + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return status; +} + +/** + * @brief Selects the signal connected to the TI1 input: direct from CH1_input + * or a XOR combination between CH1_input, CH2_input & CH3_input + * @param htim TIM handle. + * @param TI1_Selection Indicate whether or not channel 1 is connected to the + * output of a XOR gate. + * This parameter can be one of the following values: + * @arg TIM_TI1SELECTION_CH1: The TIMx_CH1 pin is connected to TI1 input + * @arg TIM_TI1SELECTION_XORCOMBINATION: The TIMx_CH1, CH2 and CH3 + * pins are connected to the TI1 input (XOR combination) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_ConfigTI1Input(TIM_HandleTypeDef *htim, uint32_t TI1_Selection) +{ + uint32_t tmpcr2; + + /* Check the parameters */ + assert_param(IS_TIM_XOR_INSTANCE(htim->Instance)); + assert_param(IS_TIM_TI1SELECTION(TI1_Selection)); + + /* Get the TIMx CR2 register value */ + tmpcr2 = htim->Instance->CR2; + + /* Reset the TI1 selection */ + tmpcr2 &= ~TIM_CR2_TI1S; + + /* Set the TI1 selection */ + tmpcr2 |= TI1_Selection; + + /* Write to TIMxCR2 */ + htim->Instance->CR2 = tmpcr2; + + return HAL_OK; +} + +/** + * @brief Configures the TIM in Slave mode + * @param htim TIM handle. + * @param sSlaveConfig pointer to a TIM_SlaveConfigTypeDef structure that + * contains the selected trigger (internal trigger input, filtered + * timer input or external trigger input) and the Slave mode + * (Disable, Reset, Gated, Trigger, External clock mode 1, Reset + Trigger, Gated + Reset). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchro(TIM_HandleTypeDef *htim, const TIM_SlaveConfigTypeDef *sSlaveConfig) +{ + /* Check the parameters */ + assert_param(IS_TIM_SLAVE_INSTANCE(htim->Instance)); + assert_param(IS_TIM_SLAVE_MODE(sSlaveConfig->SlaveMode)); + assert_param(IS_TIM_TRIGGER_INSTANCE(htim->Instance, sSlaveConfig->InputTrigger)); + + __HAL_LOCK(htim); + + htim->State = HAL_TIM_STATE_BUSY; + + if (TIM_SlaveTimer_SetConfig(htim, sSlaveConfig) != HAL_OK) + { + htim->State = HAL_TIM_STATE_READY; + __HAL_UNLOCK(htim); + return HAL_ERROR; + } + + /* Disable Trigger Interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_TRIGGER); + + /* Disable Trigger DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_TRIGGER); + + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Configures the TIM in Slave mode in interrupt mode + * @param htim TIM handle. + * @param sSlaveConfig pointer to a TIM_SlaveConfigTypeDef structure that + * contains the selected trigger (internal trigger input, filtered + * timer input or external trigger input) and the Slave mode + * (Disable, Reset, Gated, Trigger, External clock mode 1, Reset + Trigger, Gated + Reset). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchro_IT(TIM_HandleTypeDef *htim, + const TIM_SlaveConfigTypeDef *sSlaveConfig) +{ + /* Check the parameters */ + assert_param(IS_TIM_SLAVE_INSTANCE(htim->Instance)); + assert_param(IS_TIM_SLAVE_MODE(sSlaveConfig->SlaveMode)); + assert_param(IS_TIM_TRIGGER_INSTANCE(htim->Instance, sSlaveConfig->InputTrigger)); + + __HAL_LOCK(htim); + + htim->State = HAL_TIM_STATE_BUSY; + + if (TIM_SlaveTimer_SetConfig(htim, sSlaveConfig) != HAL_OK) + { + htim->State = HAL_TIM_STATE_READY; + __HAL_UNLOCK(htim); + return HAL_ERROR; + } + + /* Enable Trigger Interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_TRIGGER); + + /* Disable Trigger DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_TRIGGER); + + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Read the captured value from Capture Compare unit + * @param htim TIM handle. + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval Captured value + */ +uint32_t HAL_TIM_ReadCapturedValue(const TIM_HandleTypeDef *htim, uint32_t Channel) +{ + uint32_t tmpreg = 0U; + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + + /* Return the capture 1 value */ + tmpreg = htim->Instance->CCR1; + + break; + } + case TIM_CHANNEL_2: + { + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + /* Return the capture 2 value */ + tmpreg = htim->Instance->CCR2; + + break; + } + + case TIM_CHANNEL_3: + { + /* Check the parameters */ + assert_param(IS_TIM_CC3_INSTANCE(htim->Instance)); + + /* Return the capture 3 value */ + tmpreg = htim->Instance->CCR3; + + break; + } + + case TIM_CHANNEL_4: + { + /* Check the parameters */ + assert_param(IS_TIM_CC4_INSTANCE(htim->Instance)); + + /* Return the capture 4 value */ + tmpreg = htim->Instance->CCR4; + + break; + } + + default: + break; + } + + return tmpreg; +} + +/** + * @brief Start the DMA data transfer. + * @param hdma DMA handle + * @param src : The source memory Buffer address. + * @param dst : The destination memory Buffer address. + * @param length : The size of a source block transfer in byte. + * @retval HAL status + */ +HAL_StatusTypeDef TIM_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t src, uint32_t dst, + uint32_t length) +{ + HAL_StatusTypeDef status ; + + /* Enable the DMA channel */ + if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((hdma->LinkedListQueue != 0U) && (hdma->LinkedListQueue->Head != 0U)) + { + /* Enable the DMA channel */ + hdma->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = length; + hdma->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = src; + hdma->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = dst; + + status = HAL_DMAEx_List_Start_IT(hdma); + } + else + { + status = HAL_ERROR; + } + } + else + { + status = HAL_DMA_Start_IT(hdma, src, dst, length); + } + + return status; +} + +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group9 TIM Callbacks functions + * @brief TIM Callbacks functions + * +@verbatim + ============================================================================== + ##### TIM Callbacks functions ##### + ============================================================================== + [..] + This section provides TIM callback functions: + (+) TIM Period elapsed callback + (+) TIM Output Compare callback + (+) TIM Input capture callback + (+) TIM Trigger callback + (+) TIM Error callback + (+) TIM Index callback + (+) TIM Direction change callback + (+) TIM Index error callback + (+) TIM Transition error callback + +@endverbatim + * @{ + */ + +/** + * @brief Period elapsed callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_PeriodElapsedCallback could be implemented in the user file + */ +} + +/** + * @brief Period elapsed half complete callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIM_PeriodElapsedHalfCpltCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_PeriodElapsedHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Output Compare callback in non-blocking mode + * @param htim TIM OC handle + * @retval None + */ +__weak void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_OC_DelayElapsedCallback could be implemented in the user file + */ +} + +/** + * @brief Input Capture callback in non-blocking mode + * @param htim TIM IC handle + * @retval None + */ +__weak void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_IC_CaptureCallback could be implemented in the user file + */ +} + +/** + * @brief Input Capture half complete callback in non-blocking mode + * @param htim TIM IC handle + * @retval None + */ +__weak void HAL_TIM_IC_CaptureHalfCpltCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_IC_CaptureHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief PWM Pulse finished callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_PWM_PulseFinishedCallback could be implemented in the user file + */ +} + +/** + * @brief PWM Pulse finished half complete callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIM_PWM_PulseFinishedHalfCpltCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_PWM_PulseFinishedHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Hall Trigger detection callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIM_TriggerCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_TriggerCallback could be implemented in the user file + */ +} + +/** + * @brief Hall Trigger detection half complete callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIM_TriggerHalfCpltCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_TriggerHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Timer error callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIM_ErrorCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_ErrorCallback could be implemented in the user file + */ +} + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User TIM callback to be used instead of the weak predefined callback + * @param htim tim handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_TIM_BASE_MSPINIT_CB_ID Base MspInit Callback ID + * @arg @ref HAL_TIM_BASE_MSPDEINIT_CB_ID Base MspDeInit Callback ID + * @arg @ref HAL_TIM_IC_MSPINIT_CB_ID IC MspInit Callback ID + * @arg @ref HAL_TIM_IC_MSPDEINIT_CB_ID IC MspDeInit Callback ID + * @arg @ref HAL_TIM_OC_MSPINIT_CB_ID OC MspInit Callback ID + * @arg @ref HAL_TIM_OC_MSPDEINIT_CB_ID OC MspDeInit Callback ID + * @arg @ref HAL_TIM_PWM_MSPINIT_CB_ID PWM MspInit Callback ID + * @arg @ref HAL_TIM_PWM_MSPDEINIT_CB_ID PWM MspDeInit Callback ID + * @arg @ref HAL_TIM_ONE_PULSE_MSPINIT_CB_ID One Pulse MspInit Callback ID + * @arg @ref HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID One Pulse MspDeInit Callback ID + * @arg @ref HAL_TIM_ENCODER_MSPINIT_CB_ID Encoder MspInit Callback ID + * @arg @ref HAL_TIM_ENCODER_MSPDEINIT_CB_ID Encoder MspDeInit Callback ID + * @arg @ref HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID Hall Sensor MspInit Callback ID + * @arg @ref HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID Hall Sensor MspDeInit Callback ID + * @arg @ref HAL_TIM_PERIOD_ELAPSED_CB_ID Period Elapsed Callback ID + * @arg @ref HAL_TIM_PERIOD_ELAPSED_HALF_CB_ID Period Elapsed half complete Callback ID + * @arg @ref HAL_TIM_TRIGGER_CB_ID Trigger Callback ID + * @arg @ref HAL_TIM_TRIGGER_HALF_CB_ID Trigger half complete Callback ID + * @arg @ref HAL_TIM_IC_CAPTURE_CB_ID Input Capture Callback ID + * @arg @ref HAL_TIM_IC_CAPTURE_HALF_CB_ID Input Capture half complete Callback ID + * @arg @ref HAL_TIM_OC_DELAY_ELAPSED_CB_ID Output Compare Delay Elapsed Callback ID + * @arg @ref HAL_TIM_PWM_PULSE_FINISHED_CB_ID PWM Pulse Finished Callback ID + * @arg @ref HAL_TIM_PWM_PULSE_FINISHED_HALF_CB_ID PWM Pulse Finished half complete Callback ID + * @arg @ref HAL_TIM_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_TIM_COMMUTATION_CB_ID Commutation Callback ID + * @arg @ref HAL_TIM_COMMUTATION_HALF_CB_ID Commutation half complete Callback ID + * @arg @ref HAL_TIM_BREAK_CB_ID Break Callback ID + * @arg @ref HAL_TIM_BREAK2_CB_ID Break2 Callback ID + * @arg @ref HAL_TIM_ENCODER_INDEX_CB_ID Encoder Index Callback ID + * @arg @ref HAL_TIM_DIRECTION_CHANGE_CB_ID Direction Change Callback ID + * @arg @ref HAL_TIM_INDEX_ERROR_CB_ID Index Error Callback ID + * @arg @ref HAL_TIM_TRANSITION_ERROR_CB_ID Transition Error Callback ID + * @param pCallback pointer to the callback function + * @retval status + */ +HAL_StatusTypeDef HAL_TIM_RegisterCallback(TIM_HandleTypeDef *htim, HAL_TIM_CallbackIDTypeDef CallbackID, + pTIM_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + return HAL_ERROR; + } + + if (htim->State == HAL_TIM_STATE_READY) + { + switch (CallbackID) + { + case HAL_TIM_BASE_MSPINIT_CB_ID : + htim->Base_MspInitCallback = pCallback; + break; + + case HAL_TIM_BASE_MSPDEINIT_CB_ID : + htim->Base_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_IC_MSPINIT_CB_ID : + htim->IC_MspInitCallback = pCallback; + break; + + case HAL_TIM_IC_MSPDEINIT_CB_ID : + htim->IC_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_OC_MSPINIT_CB_ID : + htim->OC_MspInitCallback = pCallback; + break; + + case HAL_TIM_OC_MSPDEINIT_CB_ID : + htim->OC_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_PWM_MSPINIT_CB_ID : + htim->PWM_MspInitCallback = pCallback; + break; + + case HAL_TIM_PWM_MSPDEINIT_CB_ID : + htim->PWM_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_ONE_PULSE_MSPINIT_CB_ID : + htim->OnePulse_MspInitCallback = pCallback; + break; + + case HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID : + htim->OnePulse_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_ENCODER_MSPINIT_CB_ID : + htim->Encoder_MspInitCallback = pCallback; + break; + + case HAL_TIM_ENCODER_MSPDEINIT_CB_ID : + htim->Encoder_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID : + htim->HallSensor_MspInitCallback = pCallback; + break; + + case HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID : + htim->HallSensor_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_PERIOD_ELAPSED_CB_ID : + htim->PeriodElapsedCallback = pCallback; + break; + + case HAL_TIM_PERIOD_ELAPSED_HALF_CB_ID : + htim->PeriodElapsedHalfCpltCallback = pCallback; + break; + + case HAL_TIM_TRIGGER_CB_ID : + htim->TriggerCallback = pCallback; + break; + + case HAL_TIM_TRIGGER_HALF_CB_ID : + htim->TriggerHalfCpltCallback = pCallback; + break; + + case HAL_TIM_IC_CAPTURE_CB_ID : + htim->IC_CaptureCallback = pCallback; + break; + + case HAL_TIM_IC_CAPTURE_HALF_CB_ID : + htim->IC_CaptureHalfCpltCallback = pCallback; + break; + + case HAL_TIM_OC_DELAY_ELAPSED_CB_ID : + htim->OC_DelayElapsedCallback = pCallback; + break; + + case HAL_TIM_PWM_PULSE_FINISHED_CB_ID : + htim->PWM_PulseFinishedCallback = pCallback; + break; + + case HAL_TIM_PWM_PULSE_FINISHED_HALF_CB_ID : + htim->PWM_PulseFinishedHalfCpltCallback = pCallback; + break; + + case HAL_TIM_ERROR_CB_ID : + htim->ErrorCallback = pCallback; + break; + + case HAL_TIM_COMMUTATION_CB_ID : + htim->CommutationCallback = pCallback; + break; + + case HAL_TIM_COMMUTATION_HALF_CB_ID : + htim->CommutationHalfCpltCallback = pCallback; + break; + + case HAL_TIM_BREAK_CB_ID : + htim->BreakCallback = pCallback; + break; + + case HAL_TIM_BREAK2_CB_ID : + htim->Break2Callback = pCallback; + break; + + case HAL_TIM_ENCODER_INDEX_CB_ID : + htim->EncoderIndexCallback = pCallback; + break; + + case HAL_TIM_DIRECTION_CHANGE_CB_ID : + htim->DirectionChangeCallback = pCallback; + break; + + case HAL_TIM_INDEX_ERROR_CB_ID : + htim->IndexErrorCallback = pCallback; + break; + + case HAL_TIM_TRANSITION_ERROR_CB_ID : + htim->TransitionErrorCallback = pCallback; + break; + + default : + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (htim->State == HAL_TIM_STATE_RESET) + { + switch (CallbackID) + { + case HAL_TIM_BASE_MSPINIT_CB_ID : + htim->Base_MspInitCallback = pCallback; + break; + + case HAL_TIM_BASE_MSPDEINIT_CB_ID : + htim->Base_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_IC_MSPINIT_CB_ID : + htim->IC_MspInitCallback = pCallback; + break; + + case HAL_TIM_IC_MSPDEINIT_CB_ID : + htim->IC_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_OC_MSPINIT_CB_ID : + htim->OC_MspInitCallback = pCallback; + break; + + case HAL_TIM_OC_MSPDEINIT_CB_ID : + htim->OC_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_PWM_MSPINIT_CB_ID : + htim->PWM_MspInitCallback = pCallback; + break; + + case HAL_TIM_PWM_MSPDEINIT_CB_ID : + htim->PWM_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_ONE_PULSE_MSPINIT_CB_ID : + htim->OnePulse_MspInitCallback = pCallback; + break; + + case HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID : + htim->OnePulse_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_ENCODER_MSPINIT_CB_ID : + htim->Encoder_MspInitCallback = pCallback; + break; + + case HAL_TIM_ENCODER_MSPDEINIT_CB_ID : + htim->Encoder_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID : + htim->HallSensor_MspInitCallback = pCallback; + break; + + case HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID : + htim->HallSensor_MspDeInitCallback = pCallback; + break; + + default : + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister a TIM callback + * TIM callback is redirected to the weak predefined callback + * @param htim tim handle + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_TIM_BASE_MSPINIT_CB_ID Base MspInit Callback ID + * @arg @ref HAL_TIM_BASE_MSPDEINIT_CB_ID Base MspDeInit Callback ID + * @arg @ref HAL_TIM_IC_MSPINIT_CB_ID IC MspInit Callback ID + * @arg @ref HAL_TIM_IC_MSPDEINIT_CB_ID IC MspDeInit Callback ID + * @arg @ref HAL_TIM_OC_MSPINIT_CB_ID OC MspInit Callback ID + * @arg @ref HAL_TIM_OC_MSPDEINIT_CB_ID OC MspDeInit Callback ID + * @arg @ref HAL_TIM_PWM_MSPINIT_CB_ID PWM MspInit Callback ID + * @arg @ref HAL_TIM_PWM_MSPDEINIT_CB_ID PWM MspDeInit Callback ID + * @arg @ref HAL_TIM_ONE_PULSE_MSPINIT_CB_ID One Pulse MspInit Callback ID + * @arg @ref HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID One Pulse MspDeInit Callback ID + * @arg @ref HAL_TIM_ENCODER_MSPINIT_CB_ID Encoder MspInit Callback ID + * @arg @ref HAL_TIM_ENCODER_MSPDEINIT_CB_ID Encoder MspDeInit Callback ID + * @arg @ref HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID Hall Sensor MspInit Callback ID + * @arg @ref HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID Hall Sensor MspDeInit Callback ID + * @arg @ref HAL_TIM_PERIOD_ELAPSED_CB_ID Period Elapsed Callback ID + * @arg @ref HAL_TIM_PERIOD_ELAPSED_HALF_CB_ID Period Elapsed half complete Callback ID + * @arg @ref HAL_TIM_TRIGGER_CB_ID Trigger Callback ID + * @arg @ref HAL_TIM_TRIGGER_HALF_CB_ID Trigger half complete Callback ID + * @arg @ref HAL_TIM_IC_CAPTURE_CB_ID Input Capture Callback ID + * @arg @ref HAL_TIM_IC_CAPTURE_HALF_CB_ID Input Capture half complete Callback ID + * @arg @ref HAL_TIM_OC_DELAY_ELAPSED_CB_ID Output Compare Delay Elapsed Callback ID + * @arg @ref HAL_TIM_PWM_PULSE_FINISHED_CB_ID PWM Pulse Finished Callback ID + * @arg @ref HAL_TIM_PWM_PULSE_FINISHED_HALF_CB_ID PWM Pulse Finished half complete Callback ID + * @arg @ref HAL_TIM_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_TIM_COMMUTATION_CB_ID Commutation Callback ID + * @arg @ref HAL_TIM_COMMUTATION_HALF_CB_ID Commutation half complete Callback ID + * @arg @ref HAL_TIM_BREAK_CB_ID Break Callback ID + * @arg @ref HAL_TIM_BREAK2_CB_ID Break2 Callback ID + * @arg @ref HAL_TIM_ENCODER_INDEX_CB_ID Encoder Index Callback ID + * @arg @ref HAL_TIM_DIRECTION_CHANGE_CB_ID Direction Change Callback ID + * @arg @ref HAL_TIM_INDEX_ERROR_CB_ID Index Error Callback ID + * @arg @ref HAL_TIM_TRANSITION_ERROR_CB_ID Transition Error Callback ID + * @retval status + */ +HAL_StatusTypeDef HAL_TIM_UnRegisterCallback(TIM_HandleTypeDef *htim, HAL_TIM_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (htim->State == HAL_TIM_STATE_READY) + { + switch (CallbackID) + { + case HAL_TIM_BASE_MSPINIT_CB_ID : + /* Legacy weak Base MspInit Callback */ + htim->Base_MspInitCallback = HAL_TIM_Base_MspInit; + break; + + case HAL_TIM_BASE_MSPDEINIT_CB_ID : + /* Legacy weak Base Msp DeInit Callback */ + htim->Base_MspDeInitCallback = HAL_TIM_Base_MspDeInit; + break; + + case HAL_TIM_IC_MSPINIT_CB_ID : + /* Legacy weak IC Msp Init Callback */ + htim->IC_MspInitCallback = HAL_TIM_IC_MspInit; + break; + + case HAL_TIM_IC_MSPDEINIT_CB_ID : + /* Legacy weak IC Msp DeInit Callback */ + htim->IC_MspDeInitCallback = HAL_TIM_IC_MspDeInit; + break; + + case HAL_TIM_OC_MSPINIT_CB_ID : + /* Legacy weak OC Msp Init Callback */ + htim->OC_MspInitCallback = HAL_TIM_OC_MspInit; + break; + + case HAL_TIM_OC_MSPDEINIT_CB_ID : + /* Legacy weak OC Msp DeInit Callback */ + htim->OC_MspDeInitCallback = HAL_TIM_OC_MspDeInit; + break; + + case HAL_TIM_PWM_MSPINIT_CB_ID : + /* Legacy weak PWM Msp Init Callback */ + htim->PWM_MspInitCallback = HAL_TIM_PWM_MspInit; + break; + + case HAL_TIM_PWM_MSPDEINIT_CB_ID : + /* Legacy weak PWM Msp DeInit Callback */ + htim->PWM_MspDeInitCallback = HAL_TIM_PWM_MspDeInit; + break; + + case HAL_TIM_ONE_PULSE_MSPINIT_CB_ID : + /* Legacy weak One Pulse Msp Init Callback */ + htim->OnePulse_MspInitCallback = HAL_TIM_OnePulse_MspInit; + break; + + case HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID : + /* Legacy weak One Pulse Msp DeInit Callback */ + htim->OnePulse_MspDeInitCallback = HAL_TIM_OnePulse_MspDeInit; + break; + + case HAL_TIM_ENCODER_MSPINIT_CB_ID : + /* Legacy weak Encoder Msp Init Callback */ + htim->Encoder_MspInitCallback = HAL_TIM_Encoder_MspInit; + break; + + case HAL_TIM_ENCODER_MSPDEINIT_CB_ID : + /* Legacy weak Encoder Msp DeInit Callback */ + htim->Encoder_MspDeInitCallback = HAL_TIM_Encoder_MspDeInit; + break; + + case HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID : + /* Legacy weak Hall Sensor Msp Init Callback */ + htim->HallSensor_MspInitCallback = HAL_TIMEx_HallSensor_MspInit; + break; + + case HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID : + /* Legacy weak Hall Sensor Msp DeInit Callback */ + htim->HallSensor_MspDeInitCallback = HAL_TIMEx_HallSensor_MspDeInit; + break; + + case HAL_TIM_PERIOD_ELAPSED_CB_ID : + /* Legacy weak Period Elapsed Callback */ + htim->PeriodElapsedCallback = HAL_TIM_PeriodElapsedCallback; + break; + + case HAL_TIM_PERIOD_ELAPSED_HALF_CB_ID : + /* Legacy weak Period Elapsed half complete Callback */ + htim->PeriodElapsedHalfCpltCallback = HAL_TIM_PeriodElapsedHalfCpltCallback; + break; + + case HAL_TIM_TRIGGER_CB_ID : + /* Legacy weak Trigger Callback */ + htim->TriggerCallback = HAL_TIM_TriggerCallback; + break; + + case HAL_TIM_TRIGGER_HALF_CB_ID : + /* Legacy weak Trigger half complete Callback */ + htim->TriggerHalfCpltCallback = HAL_TIM_TriggerHalfCpltCallback; + break; + + case HAL_TIM_IC_CAPTURE_CB_ID : + /* Legacy weak IC Capture Callback */ + htim->IC_CaptureCallback = HAL_TIM_IC_CaptureCallback; + break; + + case HAL_TIM_IC_CAPTURE_HALF_CB_ID : + /* Legacy weak IC Capture half complete Callback */ + htim->IC_CaptureHalfCpltCallback = HAL_TIM_IC_CaptureHalfCpltCallback; + break; + + case HAL_TIM_OC_DELAY_ELAPSED_CB_ID : + /* Legacy weak OC Delay Elapsed Callback */ + htim->OC_DelayElapsedCallback = HAL_TIM_OC_DelayElapsedCallback; + break; + + case HAL_TIM_PWM_PULSE_FINISHED_CB_ID : + /* Legacy weak PWM Pulse Finished Callback */ + htim->PWM_PulseFinishedCallback = HAL_TIM_PWM_PulseFinishedCallback; + break; + + case HAL_TIM_PWM_PULSE_FINISHED_HALF_CB_ID : + /* Legacy weak PWM Pulse Finished half complete Callback */ + htim->PWM_PulseFinishedHalfCpltCallback = HAL_TIM_PWM_PulseFinishedHalfCpltCallback; + break; + + case HAL_TIM_ERROR_CB_ID : + /* Legacy weak Error Callback */ + htim->ErrorCallback = HAL_TIM_ErrorCallback; + break; + + case HAL_TIM_COMMUTATION_CB_ID : + /* Legacy weak Commutation Callback */ + htim->CommutationCallback = HAL_TIMEx_CommutCallback; + break; + + case HAL_TIM_COMMUTATION_HALF_CB_ID : + /* Legacy weak Commutation half complete Callback */ + htim->CommutationHalfCpltCallback = HAL_TIMEx_CommutHalfCpltCallback; + break; + + case HAL_TIM_BREAK_CB_ID : + /* Legacy weak Break Callback */ + htim->BreakCallback = HAL_TIMEx_BreakCallback; + break; + + case HAL_TIM_BREAK2_CB_ID : + /* Legacy weak Break2 Callback */ + htim->Break2Callback = HAL_TIMEx_Break2Callback; + break; + + case HAL_TIM_ENCODER_INDEX_CB_ID : + /* Legacy weak Encoder Index Callback */ + htim->EncoderIndexCallback = HAL_TIMEx_EncoderIndexCallback; + break; + + case HAL_TIM_DIRECTION_CHANGE_CB_ID : + /* Legacy weak Direction Change Callback */ + htim->DirectionChangeCallback = HAL_TIMEx_DirectionChangeCallback; + break; + + case HAL_TIM_INDEX_ERROR_CB_ID : + /* Legacy weak Index Error Callback */ + htim->IndexErrorCallback = HAL_TIMEx_IndexErrorCallback; + break; + + case HAL_TIM_TRANSITION_ERROR_CB_ID : + /* Legacy weak Transition Error Callback */ + htim->TransitionErrorCallback = HAL_TIMEx_TransitionErrorCallback; + break; + + default : + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (htim->State == HAL_TIM_STATE_RESET) + { + switch (CallbackID) + { + case HAL_TIM_BASE_MSPINIT_CB_ID : + /* Legacy weak Base MspInit Callback */ + htim->Base_MspInitCallback = HAL_TIM_Base_MspInit; + break; + + case HAL_TIM_BASE_MSPDEINIT_CB_ID : + /* Legacy weak Base Msp DeInit Callback */ + htim->Base_MspDeInitCallback = HAL_TIM_Base_MspDeInit; + break; + + case HAL_TIM_IC_MSPINIT_CB_ID : + /* Legacy weak IC Msp Init Callback */ + htim->IC_MspInitCallback = HAL_TIM_IC_MspInit; + break; + + case HAL_TIM_IC_MSPDEINIT_CB_ID : + /* Legacy weak IC Msp DeInit Callback */ + htim->IC_MspDeInitCallback = HAL_TIM_IC_MspDeInit; + break; + + case HAL_TIM_OC_MSPINIT_CB_ID : + /* Legacy weak OC Msp Init Callback */ + htim->OC_MspInitCallback = HAL_TIM_OC_MspInit; + break; + + case HAL_TIM_OC_MSPDEINIT_CB_ID : + /* Legacy weak OC Msp DeInit Callback */ + htim->OC_MspDeInitCallback = HAL_TIM_OC_MspDeInit; + break; + + case HAL_TIM_PWM_MSPINIT_CB_ID : + /* Legacy weak PWM Msp Init Callback */ + htim->PWM_MspInitCallback = HAL_TIM_PWM_MspInit; + break; + + case HAL_TIM_PWM_MSPDEINIT_CB_ID : + /* Legacy weak PWM Msp DeInit Callback */ + htim->PWM_MspDeInitCallback = HAL_TIM_PWM_MspDeInit; + break; + + case HAL_TIM_ONE_PULSE_MSPINIT_CB_ID : + /* Legacy weak One Pulse Msp Init Callback */ + htim->OnePulse_MspInitCallback = HAL_TIM_OnePulse_MspInit; + break; + + case HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID : + /* Legacy weak One Pulse Msp DeInit Callback */ + htim->OnePulse_MspDeInitCallback = HAL_TIM_OnePulse_MspDeInit; + break; + + case HAL_TIM_ENCODER_MSPINIT_CB_ID : + /* Legacy weak Encoder Msp Init Callback */ + htim->Encoder_MspInitCallback = HAL_TIM_Encoder_MspInit; + break; + + case HAL_TIM_ENCODER_MSPDEINIT_CB_ID : + /* Legacy weak Encoder Msp DeInit Callback */ + htim->Encoder_MspDeInitCallback = HAL_TIM_Encoder_MspDeInit; + break; + + case HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID : + /* Legacy weak Hall Sensor Msp Init Callback */ + htim->HallSensor_MspInitCallback = HAL_TIMEx_HallSensor_MspInit; + break; + + case HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID : + /* Legacy weak Hall Sensor Msp DeInit Callback */ + htim->HallSensor_MspDeInitCallback = HAL_TIMEx_HallSensor_MspDeInit; + break; + + default : + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group10 TIM Peripheral State functions + * @brief TIM Peripheral State functions + * +@verbatim + ============================================================================== + ##### Peripheral State functions ##### + ============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the TIM Base handle state. + * @param htim TIM Base handle + * @retval HAL state + */ +HAL_TIM_StateTypeDef HAL_TIM_Base_GetState(const TIM_HandleTypeDef *htim) +{ + return htim->State; +} + +/** + * @brief Return the TIM OC handle state. + * @param htim TIM Output Compare handle + * @retval HAL state + */ +HAL_TIM_StateTypeDef HAL_TIM_OC_GetState(const TIM_HandleTypeDef *htim) +{ + return htim->State; +} + +/** + * @brief Return the TIM PWM handle state. + * @param htim TIM handle + * @retval HAL state + */ +HAL_TIM_StateTypeDef HAL_TIM_PWM_GetState(const TIM_HandleTypeDef *htim) +{ + return htim->State; +} + +/** + * @brief Return the TIM Input Capture handle state. + * @param htim TIM IC handle + * @retval HAL state + */ +HAL_TIM_StateTypeDef HAL_TIM_IC_GetState(const TIM_HandleTypeDef *htim) +{ + return htim->State; +} + +/** + * @brief Return the TIM One Pulse Mode handle state. + * @param htim TIM OPM handle + * @retval HAL state + */ +HAL_TIM_StateTypeDef HAL_TIM_OnePulse_GetState(const TIM_HandleTypeDef *htim) +{ + return htim->State; +} + +/** + * @brief Return the TIM Encoder Mode handle state. + * @param htim TIM Encoder Interface handle + * @retval HAL state + */ +HAL_TIM_StateTypeDef HAL_TIM_Encoder_GetState(const TIM_HandleTypeDef *htim) +{ + return htim->State; +} + +/** + * @brief Return the TIM Encoder Mode handle state. + * @param htim TIM handle + * @retval Active channel + */ +HAL_TIM_ActiveChannel HAL_TIM_GetActiveChannel(const TIM_HandleTypeDef *htim) +{ + return htim->Channel; +} + +/** + * @brief Return actual state of the TIM channel. + * @param htim TIM handle + * @param Channel TIM Channel + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 + * @arg TIM_CHANNEL_2: TIM Channel 2 + * @arg TIM_CHANNEL_3: TIM Channel 3 + * @arg TIM_CHANNEL_4: TIM Channel 4 + * @arg TIM_CHANNEL_5: TIM Channel 5 + * @arg TIM_CHANNEL_6: TIM Channel 6 + * @retval TIM Channel state + */ +HAL_TIM_ChannelStateTypeDef HAL_TIM_GetChannelState(const TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_TIM_ChannelStateTypeDef channel_state; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + channel_state = TIM_CHANNEL_STATE_GET(htim, Channel); + + return channel_state; +} + +/** + * @brief Return actual state of a DMA burst operation. + * @param htim TIM handle + * @retval DMA burst state + */ +HAL_TIM_DMABurstStateTypeDef HAL_TIM_DMABurstState(const TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_DMABURST_INSTANCE(htim->Instance)); + + return htim->DMABurstState; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup TIM_Private_Functions TIM Private Functions + * @{ + */ + +/** + * @brief TIM DMA error callback + * @param hdma pointer to DMA handle. + * @retval None + */ +void TIM_DMAError(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + if (hdma == htim->hdma[TIM_DMA_ID_CC1]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1; + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC2]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2; + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC3]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3; + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_3, HAL_TIM_CHANNEL_STATE_READY); + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC4]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4; + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_4, HAL_TIM_CHANNEL_STATE_READY); + } + else + { + htim->State = HAL_TIM_STATE_READY; + } + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->ErrorCallback(htim); +#else + HAL_TIM_ErrorCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; +} + +/** + * @brief TIM DMA Delay Pulse complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +static void TIM_DMADelayPulseCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + if (hdma == htim->hdma[TIM_DMA_ID_CC1]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1; + + if (hdma->Init.Mode == DMA_NORMAL) + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + } + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC2]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2; + + if (hdma->Init.Mode == DMA_NORMAL) + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + } + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC3]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3; + + if (hdma->Init.Mode == DMA_NORMAL) + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_3, HAL_TIM_CHANNEL_STATE_READY); + } + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC4]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4; + + if (hdma->Init.Mode == DMA_NORMAL) + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_4, HAL_TIM_CHANNEL_STATE_READY); + } + } + else + { + /* nothing to do */ + } + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->PWM_PulseFinishedCallback(htim); +#else + HAL_TIM_PWM_PulseFinishedCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; +} + +/** + * @brief TIM DMA Delay Pulse half complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +void TIM_DMADelayPulseHalfCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + if (hdma == htim->hdma[TIM_DMA_ID_CC1]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1; + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC2]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2; + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC3]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3; + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC4]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4; + } + else + { + /* nothing to do */ + } + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->PWM_PulseFinishedHalfCpltCallback(htim); +#else + HAL_TIM_PWM_PulseFinishedHalfCpltCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; +} + +/** + * @brief TIM DMA Capture complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +void TIM_DMACaptureCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + if (hdma == htim->hdma[TIM_DMA_ID_CC1]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1; + + if (hdma->Init.Mode == DMA_NORMAL) + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + } + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC2]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2; + + if (hdma->Init.Mode == DMA_NORMAL) + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + } + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC3]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3; + + if (hdma->Init.Mode == DMA_NORMAL) + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_3, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_3, HAL_TIM_CHANNEL_STATE_READY); + } + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC4]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4; + + if (hdma->Init.Mode == DMA_NORMAL) + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_4, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_4, HAL_TIM_CHANNEL_STATE_READY); + } + } + else + { + /* nothing to do */ + } + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->IC_CaptureCallback(htim); +#else + HAL_TIM_IC_CaptureCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; +} + +/** + * @brief TIM DMA Capture half complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +void TIM_DMACaptureHalfCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + if (hdma == htim->hdma[TIM_DMA_ID_CC1]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1; + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC2]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2; + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC3]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3; + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC4]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4; + } + else + { + /* nothing to do */ + } + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->IC_CaptureHalfCpltCallback(htim); +#else + HAL_TIM_IC_CaptureHalfCpltCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; +} + +/** + * @brief TIM DMA Period Elapse complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +static void TIM_DMAPeriodElapsedCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + if (htim->hdma[TIM_DMA_ID_UPDATE]->Init.Mode == DMA_NORMAL) + { + htim->State = HAL_TIM_STATE_READY; + } + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->PeriodElapsedCallback(htim); +#else + HAL_TIM_PeriodElapsedCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ +} + +/** + * @brief TIM DMA Period Elapse half complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +static void TIM_DMAPeriodElapsedHalfCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->PeriodElapsedHalfCpltCallback(htim); +#else + HAL_TIM_PeriodElapsedHalfCpltCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ +} + +/** + * @brief TIM DMA Trigger callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +static void TIM_DMATriggerCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + if (htim->hdma[TIM_DMA_ID_TRIGGER]->Init.Mode == DMA_NORMAL) + { + htim->State = HAL_TIM_STATE_READY; + } + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->TriggerCallback(htim); +#else + HAL_TIM_TriggerCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ +} + +/** + * @brief TIM DMA Trigger half complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +static void TIM_DMATriggerHalfCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->TriggerHalfCpltCallback(htim); +#else + HAL_TIM_TriggerHalfCpltCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ +} + +/** + * @brief Time Base configuration + * @param TIMx TIM peripheral + * @param Structure TIM Base configuration structure + * @retval None + */ +void TIM_Base_SetConfig(TIM_TypeDef *TIMx, const TIM_Base_InitTypeDef *Structure) +{ + uint32_t tmpcr1; + tmpcr1 = TIMx->CR1; + + /* Set TIM Time Base Unit parameters ---------------------------------------*/ + if (IS_TIM_COUNTER_MODE_SELECT_INSTANCE(TIMx)) + { + /* Select the Counter Mode */ + tmpcr1 &= ~(TIM_CR1_DIR | TIM_CR1_CMS); + tmpcr1 |= Structure->CounterMode; + } + + if (IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx)) + { + /* Set the clock division */ + tmpcr1 &= ~TIM_CR1_CKD; + tmpcr1 |= (uint32_t)Structure->ClockDivision; + } + + /* Set the auto-reload preload */ + MODIFY_REG(tmpcr1, TIM_CR1_ARPE, Structure->AutoReloadPreload); + + TIMx->CR1 = tmpcr1; + + /* Set the Autoreload value */ + TIMx->ARR = (uint32_t)Structure->Period ; + + /* Set the Prescaler value */ + TIMx->PSC = Structure->Prescaler; + + if (IS_TIM_REPETITION_COUNTER_INSTANCE(TIMx)) + { + /* Set the Repetition Counter value */ + TIMx->RCR = Structure->RepetitionCounter; + } + + /* Generate an update event to reload the Prescaler + and the repetition counter (only for advanced timer) value immediately */ + TIMx->EGR = TIM_EGR_UG; +} + +/** + * @brief Timer Output Compare 1 configuration + * @param TIMx to select the TIM peripheral + * @param OC_Config The output configuration structure + * @retval None + */ +static void TIM_OC1_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config) +{ + uint32_t tmpccmrx; + uint32_t tmpccer; + uint32_t tmpcr2; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* Disable the Channel 1: Reset the CC1E Bit */ + TIMx->CCER &= ~TIM_CCER_CC1E; + + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR1 register value */ + tmpccmrx = TIMx->CCMR1; + + /* Reset the Output Compare Mode Bits */ + tmpccmrx &= ~TIM_CCMR1_OC1M; + tmpccmrx &= ~TIM_CCMR1_CC1S; + /* Select the Output Compare Mode */ + tmpccmrx |= OC_Config->OCMode; + + /* Reset the Output Polarity level */ + tmpccer &= ~TIM_CCER_CC1P; + /* Set the Output Compare Polarity */ + tmpccer |= OC_Config->OCPolarity; + + if (IS_TIM_CCXN_INSTANCE(TIMx, TIM_CHANNEL_1)) + { + /* Check parameters */ + assert_param(IS_TIM_OCN_POLARITY(OC_Config->OCNPolarity)); + + /* Reset the Output N Polarity level */ + tmpccer &= ~TIM_CCER_CC1NP; + /* Set the Output N Polarity */ + tmpccer |= OC_Config->OCNPolarity; + /* Reset the Output N State */ + tmpccer &= ~TIM_CCER_CC1NE; + } + + if (IS_TIM_BREAK_INSTANCE(TIMx)) + { + /* Check parameters */ + assert_param(IS_TIM_OCNIDLE_STATE(OC_Config->OCNIdleState)); + assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState)); + + /* Reset the Output Compare and Output Compare N IDLE State */ + tmpcr2 &= ~TIM_CR2_OIS1; + tmpcr2 &= ~TIM_CR2_OIS1N; + /* Set the Output Idle state */ + tmpcr2 |= OC_Config->OCIdleState; + /* Set the Output N Idle state */ + tmpcr2 |= OC_Config->OCNIdleState; + } + + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR1 = OC_Config->Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Timer Output Compare 2 configuration + * @param TIMx to select the TIM peripheral + * @param OC_Config The output configuration structure + * @retval None + */ +void TIM_OC2_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config) +{ + uint32_t tmpccmrx; + uint32_t tmpccer; + uint32_t tmpcr2; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* Disable the Channel 2: Reset the CC2E Bit */ + TIMx->CCER &= ~TIM_CCER_CC2E; + + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR1 register value */ + tmpccmrx = TIMx->CCMR1; + + /* Reset the Output Compare mode and Capture/Compare selection Bits */ + tmpccmrx &= ~TIM_CCMR1_OC2M; + tmpccmrx &= ~TIM_CCMR1_CC2S; + + /* Select the Output Compare Mode */ + tmpccmrx |= (OC_Config->OCMode << 8U); + + /* Reset the Output Polarity level */ + tmpccer &= ~TIM_CCER_CC2P; + /* Set the Output Compare Polarity */ + tmpccer |= (OC_Config->OCPolarity << 4U); + + if (IS_TIM_CCXN_INSTANCE(TIMx, TIM_CHANNEL_2)) + { + assert_param(IS_TIM_OCN_POLARITY(OC_Config->OCNPolarity)); + + /* Reset the Output N Polarity level */ + tmpccer &= ~TIM_CCER_CC2NP; + /* Set the Output N Polarity */ + tmpccer |= (OC_Config->OCNPolarity << 4U); + /* Reset the Output N State */ + tmpccer &= ~TIM_CCER_CC2NE; + + } + + if (IS_TIM_BREAK_INSTANCE(TIMx)) + { + /* Check parameters */ + assert_param(IS_TIM_OCNIDLE_STATE(OC_Config->OCNIdleState)); + assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState)); + + /* Reset the Output Compare and Output Compare N IDLE State */ + tmpcr2 &= ~TIM_CR2_OIS2; + tmpcr2 &= ~TIM_CR2_OIS2N; + /* Set the Output Idle state */ + tmpcr2 |= (OC_Config->OCIdleState << 2U); + /* Set the Output N Idle state */ + tmpcr2 |= (OC_Config->OCNIdleState << 2U); + } + + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR2 = OC_Config->Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Timer Output Compare 3 configuration + * @param TIMx to select the TIM peripheral + * @param OC_Config The output configuration structure + * @retval None + */ +static void TIM_OC3_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config) +{ + uint32_t tmpccmrx; + uint32_t tmpccer; + uint32_t tmpcr2; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* Disable the Channel 3: Reset the CC2E Bit */ + TIMx->CCER &= ~TIM_CCER_CC3E; + + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR2 register value */ + tmpccmrx = TIMx->CCMR2; + + /* Reset the Output Compare mode and Capture/Compare selection Bits */ + tmpccmrx &= ~TIM_CCMR2_OC3M; + tmpccmrx &= ~TIM_CCMR2_CC3S; + /* Select the Output Compare Mode */ + tmpccmrx |= OC_Config->OCMode; + + /* Reset the Output Polarity level */ + tmpccer &= ~TIM_CCER_CC3P; + /* Set the Output Compare Polarity */ + tmpccer |= (OC_Config->OCPolarity << 8U); + + if (IS_TIM_CCXN_INSTANCE(TIMx, TIM_CHANNEL_3)) + { + assert_param(IS_TIM_OCN_POLARITY(OC_Config->OCNPolarity)); + + /* Reset the Output N Polarity level */ + tmpccer &= ~TIM_CCER_CC3NP; + /* Set the Output N Polarity */ + tmpccer |= (OC_Config->OCNPolarity << 8U); + /* Reset the Output N State */ + tmpccer &= ~TIM_CCER_CC3NE; + } + + if (IS_TIM_BREAK_INSTANCE(TIMx)) + { + /* Check parameters */ + assert_param(IS_TIM_OCNIDLE_STATE(OC_Config->OCNIdleState)); + assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState)); + + /* Reset the Output Compare and Output Compare N IDLE State */ + tmpcr2 &= ~TIM_CR2_OIS3; + tmpcr2 &= ~TIM_CR2_OIS3N; + /* Set the Output Idle state */ + tmpcr2 |= (OC_Config->OCIdleState << 4U); + /* Set the Output N Idle state */ + tmpcr2 |= (OC_Config->OCNIdleState << 4U); + } + + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR2 */ + TIMx->CCMR2 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR3 = OC_Config->Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Timer Output Compare 4 configuration + * @param TIMx to select the TIM peripheral + * @param OC_Config The output configuration structure + * @retval None + */ +static void TIM_OC4_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config) +{ + uint32_t tmpccmrx; + uint32_t tmpccer; + uint32_t tmpcr2; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* Disable the Channel 4: Reset the CC4E Bit */ + TIMx->CCER &= ~TIM_CCER_CC4E; + + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR2 register value */ + tmpccmrx = TIMx->CCMR2; + + /* Reset the Output Compare mode and Capture/Compare selection Bits */ + tmpccmrx &= ~TIM_CCMR2_OC4M; + tmpccmrx &= ~TIM_CCMR2_CC4S; + + /* Select the Output Compare Mode */ + tmpccmrx |= (OC_Config->OCMode << 8U); + + /* Reset the Output Polarity level */ + tmpccer &= ~TIM_CCER_CC4P; + /* Set the Output Compare Polarity */ + tmpccer |= (OC_Config->OCPolarity << 12U); + + if (IS_TIM_CCXN_INSTANCE(TIMx, TIM_CHANNEL_4)) + { + assert_param(IS_TIM_OCN_POLARITY(OC_Config->OCNPolarity)); + + /* Reset the Output N Polarity level */ + tmpccer &= ~TIM_CCER_CC4NP; + /* Set the Output N Polarity */ + tmpccer |= (OC_Config->OCNPolarity << 12U); + /* Reset the Output N State */ + tmpccer &= ~TIM_CCER_CC4NE; + } + + if (IS_TIM_BREAK_INSTANCE(TIMx)) + { + /* Check parameters */ + assert_param(IS_TIM_OCNIDLE_STATE(OC_Config->OCNIdleState)); + assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState)); + + /* Reset the Output Compare IDLE State */ + tmpcr2 &= ~TIM_CR2_OIS4; + /* Reset the Output Compare N IDLE State */ + tmpcr2 &= ~TIM_CR2_OIS4N; + + /* Set the Output Idle state */ + tmpcr2 |= (OC_Config->OCIdleState << 6U); + /* Set the Output N Idle state */ + tmpcr2 |= (OC_Config->OCNIdleState << 6U); + } + + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR2 */ + TIMx->CCMR2 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR4 = OC_Config->Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Timer Output Compare 5 configuration + * @param TIMx to select the TIM peripheral + * @param OC_Config The output configuration structure + * @retval None + */ +static void TIM_OC5_SetConfig(TIM_TypeDef *TIMx, + const TIM_OC_InitTypeDef *OC_Config) +{ + uint32_t tmpccmrx; + uint32_t tmpccer; + uint32_t tmpcr2; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* Disable the output: Reset the CCxE Bit */ + TIMx->CCER &= ~TIM_CCER_CC5E; + + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + /* Get the TIMx CCMR1 register value */ + tmpccmrx = TIMx->CCMR3; + + /* Reset the Output Compare Mode Bits */ + tmpccmrx &= ~(TIM_CCMR3_OC5M); + /* Select the Output Compare Mode */ + tmpccmrx |= OC_Config->OCMode; + + /* Reset the Output Polarity level */ + tmpccer &= ~TIM_CCER_CC5P; + /* Set the Output Compare Polarity */ + tmpccer |= (OC_Config->OCPolarity << 16U); + + if (IS_TIM_BREAK_INSTANCE(TIMx)) + { + /* Reset the Output Compare IDLE State */ + tmpcr2 &= ~TIM_CR2_OIS5; + /* Set the Output Idle state */ + tmpcr2 |= (OC_Config->OCIdleState << 8U); + } + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR3 */ + TIMx->CCMR3 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR5 = OC_Config->Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Timer Output Compare 6 configuration + * @param TIMx to select the TIM peripheral + * @param OC_Config The output configuration structure + * @retval None + */ +static void TIM_OC6_SetConfig(TIM_TypeDef *TIMx, + const TIM_OC_InitTypeDef *OC_Config) +{ + uint32_t tmpccmrx; + uint32_t tmpccer; + uint32_t tmpcr2; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* Disable the output: Reset the CCxE Bit */ + TIMx->CCER &= ~TIM_CCER_CC6E; + + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + /* Get the TIMx CCMR1 register value */ + tmpccmrx = TIMx->CCMR3; + + /* Reset the Output Compare Mode Bits */ + tmpccmrx &= ~(TIM_CCMR3_OC6M); + /* Select the Output Compare Mode */ + tmpccmrx |= (OC_Config->OCMode << 8U); + + /* Reset the Output Polarity level */ + tmpccer &= (uint32_t)~TIM_CCER_CC6P; + /* Set the Output Compare Polarity */ + tmpccer |= (OC_Config->OCPolarity << 20U); + + if (IS_TIM_BREAK_INSTANCE(TIMx)) + { + /* Reset the Output Compare IDLE State */ + tmpcr2 &= ~TIM_CR2_OIS6; + /* Set the Output Idle state */ + tmpcr2 |= (OC_Config->OCIdleState << 10U); + } + + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR3 */ + TIMx->CCMR3 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR6 = OC_Config->Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Slave Timer configuration function + * @param htim TIM handle + * @param sSlaveConfig Slave timer configuration + * @retval None + */ +static HAL_StatusTypeDef TIM_SlaveTimer_SetConfig(TIM_HandleTypeDef *htim, + const TIM_SlaveConfigTypeDef *sSlaveConfig) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpsmcr; + uint32_t tmpccmr1; + uint32_t tmpccer; + + /* Get the TIMx SMCR register value */ + tmpsmcr = htim->Instance->SMCR; + + /* Reset the Trigger Selection Bits */ + tmpsmcr &= ~TIM_SMCR_TS; + /* Set the Input Trigger source */ + tmpsmcr |= sSlaveConfig->InputTrigger; + + /* Reset the slave mode Bits */ + tmpsmcr &= ~TIM_SMCR_SMS; + /* Set the slave mode */ + tmpsmcr |= sSlaveConfig->SlaveMode; + + /* Write to TIMx SMCR */ + htim->Instance->SMCR = tmpsmcr; + + /* Configure the trigger prescaler, filter, and polarity */ + switch (sSlaveConfig->InputTrigger) + { + case TIM_TS_ETRF: + { + /* Check the parameters */ + assert_param(IS_TIM_CLOCKSOURCE_ETRMODE1_INSTANCE(htim->Instance)); + assert_param(IS_TIM_TRIGGERPRESCALER(sSlaveConfig->TriggerPrescaler)); + assert_param(IS_TIM_TRIGGERPOLARITY(sSlaveConfig->TriggerPolarity)); + assert_param(IS_TIM_TRIGGERFILTER(sSlaveConfig->TriggerFilter)); + /* Configure the ETR Trigger source */ + TIM_ETR_SetConfig(htim->Instance, + sSlaveConfig->TriggerPrescaler, + sSlaveConfig->TriggerPolarity, + sSlaveConfig->TriggerFilter); + break; + } + + case TIM_TS_TI1F_ED: + { + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + assert_param(IS_TIM_TRIGGERFILTER(sSlaveConfig->TriggerFilter)); + + if ((sSlaveConfig->SlaveMode == TIM_SLAVEMODE_GATED) || \ + (sSlaveConfig->SlaveMode == TIM_SLAVEMODE_COMBINED_GATEDRESET)) + { + return HAL_ERROR; + } + + /* Disable the Channel 1: Reset the CC1E Bit */ + tmpccer = htim->Instance->CCER; + htim->Instance->CCER &= ~TIM_CCER_CC1E; + tmpccmr1 = htim->Instance->CCMR1; + + /* Set the filter */ + tmpccmr1 &= ~TIM_CCMR1_IC1F; + tmpccmr1 |= ((sSlaveConfig->TriggerFilter) << 4U); + + /* Write to TIMx CCMR1 and CCER registers */ + htim->Instance->CCMR1 = tmpccmr1; + htim->Instance->CCER = tmpccer; + break; + } + + case TIM_TS_TI1FP1: + { + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + assert_param(IS_TIM_TRIGGERPOLARITY(sSlaveConfig->TriggerPolarity)); + assert_param(IS_TIM_TRIGGERFILTER(sSlaveConfig->TriggerFilter)); + + /* Configure TI1 Filter and Polarity */ + TIM_TI1_ConfigInputStage(htim->Instance, + sSlaveConfig->TriggerPolarity, + sSlaveConfig->TriggerFilter); + break; + } + + case TIM_TS_TI2FP2: + { + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + assert_param(IS_TIM_TRIGGERPOLARITY(sSlaveConfig->TriggerPolarity)); + assert_param(IS_TIM_TRIGGERFILTER(sSlaveConfig->TriggerFilter)); + + /* Configure TI2 Filter and Polarity */ + TIM_TI2_ConfigInputStage(htim->Instance, + sSlaveConfig->TriggerPolarity, + sSlaveConfig->TriggerFilter); + break; + } + + case TIM_TS_ITR0: + case TIM_TS_ITR1: + case TIM_TS_ITR2: + case TIM_TS_ITR3: + case TIM_TS_ITR4: + case TIM_TS_ITR5: + case TIM_TS_ITR6: + case TIM_TS_ITR7: + case TIM_TS_ITR8: + case TIM_TS_ITR9: + case TIM_TS_ITR10: + case TIM_TS_ITR11: + case TIM_TS_ITR12: + { + /* Check the parameter */ + assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_INSTANCE((htim->Instance), sSlaveConfig->InputTrigger)); + break; + } + + default: + status = HAL_ERROR; + break; + } + + return status; +} + +/** + * @brief Configure the TI1 as Input. + * @param TIMx to select the TIM peripheral. + * @param TIM_ICPolarity The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPOLARITY_RISING + * @arg TIM_ICPOLARITY_FALLING + * @arg TIM_ICPOLARITY_BOTHEDGE + * @param TIM_ICSelection specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSELECTION_DIRECTTI: TIM Input 1 is selected to be connected to IC1. + * @arg TIM_ICSELECTION_INDIRECTTI: TIM Input 1 is selected to be connected to IC2. + * @arg TIM_ICSELECTION_TRC: TIM Input 1 is selected to be connected to TRC. + * @param TIM_ICFilter Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + * @note TIM_ICFilter and TIM_ICPolarity are not used in INDIRECT mode as TI2FP1 + * (on channel2 path) is used as the input signal. Therefore CCMR1 must be + * protected against un-initialized filter and polarity values. + */ +void TIM_TI1_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter) +{ + uint32_t tmpccmr1; + uint32_t tmpccer; + + /* Disable the Channel 1: Reset the CC1E Bit */ + tmpccer = TIMx->CCER; + TIMx->CCER &= ~TIM_CCER_CC1E; + tmpccmr1 = TIMx->CCMR1; + + /* Select the Input */ + if (IS_TIM_CC2_INSTANCE(TIMx) != RESET) + { + tmpccmr1 &= ~TIM_CCMR1_CC1S; + tmpccmr1 |= TIM_ICSelection; + } + else + { + tmpccmr1 |= TIM_CCMR1_CC1S_0; + } + + /* Set the filter */ + tmpccmr1 &= ~TIM_CCMR1_IC1F; + tmpccmr1 |= ((TIM_ICFilter << 4U) & TIM_CCMR1_IC1F); + + /* Select the Polarity and set the CC1E Bit */ + tmpccer &= ~(TIM_CCER_CC1P | TIM_CCER_CC1NP); + tmpccer |= (TIM_ICPolarity & (TIM_CCER_CC1P | TIM_CCER_CC1NP)); + + /* Write to TIMx CCMR1 and CCER registers */ + TIMx->CCMR1 = tmpccmr1; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the Polarity and Filter for TI1. + * @param TIMx to select the TIM peripheral. + * @param TIM_ICPolarity The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPOLARITY_RISING + * @arg TIM_ICPOLARITY_FALLING + * @arg TIM_ICPOLARITY_BOTHEDGE + * @param TIM_ICFilter Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + */ +static void TIM_TI1_ConfigInputStage(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICFilter) +{ + uint32_t tmpccmr1; + uint32_t tmpccer; + + /* Disable the Channel 1: Reset the CC1E Bit */ + tmpccer = TIMx->CCER; + TIMx->CCER &= ~TIM_CCER_CC1E; + tmpccmr1 = TIMx->CCMR1; + + /* Set the filter */ + tmpccmr1 &= ~TIM_CCMR1_IC1F; + tmpccmr1 |= (TIM_ICFilter << 4U); + + /* Select the Polarity and set the CC1E Bit */ + tmpccer &= ~(TIM_CCER_CC1P | TIM_CCER_CC1NP); + tmpccer |= TIM_ICPolarity; + + /* Write to TIMx CCMR1 and CCER registers */ + TIMx->CCMR1 = tmpccmr1; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the TI2 as Input. + * @param TIMx to select the TIM peripheral + * @param TIM_ICPolarity The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPOLARITY_RISING + * @arg TIM_ICPOLARITY_FALLING + * @arg TIM_ICPOLARITY_BOTHEDGE + * @param TIM_ICSelection specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSELECTION_DIRECTTI: TIM Input 2 is selected to be connected to IC2. + * @arg TIM_ICSELECTION_INDIRECTTI: TIM Input 2 is selected to be connected to IC1. + * @arg TIM_ICSELECTION_TRC: TIM Input 2 is selected to be connected to TRC. + * @param TIM_ICFilter Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + * @note TIM_ICFilter and TIM_ICPolarity are not used in INDIRECT mode as TI1FP2 + * (on channel1 path) is used as the input signal. Therefore CCMR1 must be + * protected against un-initialized filter and polarity values. + */ +static void TIM_TI2_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter) +{ + uint32_t tmpccmr1; + uint32_t tmpccer; + + /* Disable the Channel 2: Reset the CC2E Bit */ + tmpccer = TIMx->CCER; + TIMx->CCER &= ~TIM_CCER_CC2E; + tmpccmr1 = TIMx->CCMR1; + + /* Select the Input */ + tmpccmr1 &= ~TIM_CCMR1_CC2S; + tmpccmr1 |= (TIM_ICSelection << 8U); + + /* Set the filter */ + tmpccmr1 &= ~TIM_CCMR1_IC2F; + tmpccmr1 |= ((TIM_ICFilter << 12U) & TIM_CCMR1_IC2F); + + /* Select the Polarity and set the CC2E Bit */ + tmpccer &= ~(TIM_CCER_CC2P | TIM_CCER_CC2NP); + tmpccer |= ((TIM_ICPolarity << 4U) & (TIM_CCER_CC2P | TIM_CCER_CC2NP)); + + /* Write to TIMx CCMR1 and CCER registers */ + TIMx->CCMR1 = tmpccmr1 ; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the Polarity and Filter for TI2. + * @param TIMx to select the TIM peripheral. + * @param TIM_ICPolarity The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPOLARITY_RISING + * @arg TIM_ICPOLARITY_FALLING + * @arg TIM_ICPOLARITY_BOTHEDGE + * @param TIM_ICFilter Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + */ +static void TIM_TI2_ConfigInputStage(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICFilter) +{ + uint32_t tmpccmr1; + uint32_t tmpccer; + + /* Disable the Channel 2: Reset the CC2E Bit */ + tmpccer = TIMx->CCER; + TIMx->CCER &= ~TIM_CCER_CC2E; + tmpccmr1 = TIMx->CCMR1; + + /* Set the filter */ + tmpccmr1 &= ~TIM_CCMR1_IC2F; + tmpccmr1 |= (TIM_ICFilter << 12U); + + /* Select the Polarity and set the CC2E Bit */ + tmpccer &= ~(TIM_CCER_CC2P | TIM_CCER_CC2NP); + tmpccer |= (TIM_ICPolarity << 4U); + + /* Write to TIMx CCMR1 and CCER registers */ + TIMx->CCMR1 = tmpccmr1 ; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the TI3 as Input. + * @param TIMx to select the TIM peripheral + * @param TIM_ICPolarity The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPOLARITY_RISING + * @arg TIM_ICPOLARITY_FALLING + * @arg TIM_ICPOLARITY_BOTHEDGE + * @param TIM_ICSelection specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSELECTION_DIRECTTI: TIM Input 3 is selected to be connected to IC3. + * @arg TIM_ICSELECTION_INDIRECTTI: TIM Input 3 is selected to be connected to IC4. + * @arg TIM_ICSELECTION_TRC: TIM Input 3 is selected to be connected to TRC. + * @param TIM_ICFilter Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + * @note TIM_ICFilter and TIM_ICPolarity are not used in INDIRECT mode as TI3FP4 + * (on channel1 path) is used as the input signal. Therefore CCMR2 must be + * protected against un-initialized filter and polarity values. + */ +static void TIM_TI3_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter) +{ + uint32_t tmpccmr2; + uint32_t tmpccer; + + /* Disable the Channel 3: Reset the CC3E Bit */ + tmpccer = TIMx->CCER; + TIMx->CCER &= ~TIM_CCER_CC3E; + tmpccmr2 = TIMx->CCMR2; + + /* Select the Input */ + tmpccmr2 &= ~TIM_CCMR2_CC3S; + tmpccmr2 |= TIM_ICSelection; + + /* Set the filter */ + tmpccmr2 &= ~TIM_CCMR2_IC3F; + tmpccmr2 |= ((TIM_ICFilter << 4U) & TIM_CCMR2_IC3F); + + /* Select the Polarity and set the CC3E Bit */ + tmpccer &= ~(TIM_CCER_CC3P | TIM_CCER_CC3NP); + tmpccer |= ((TIM_ICPolarity << 8U) & (TIM_CCER_CC3P | TIM_CCER_CC3NP)); + + /* Write to TIMx CCMR2 and CCER registers */ + TIMx->CCMR2 = tmpccmr2; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the TI4 as Input. + * @param TIMx to select the TIM peripheral + * @param TIM_ICPolarity The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPOLARITY_RISING + * @arg TIM_ICPOLARITY_FALLING + * @arg TIM_ICPOLARITY_BOTHEDGE + * @param TIM_ICSelection specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSELECTION_DIRECTTI: TIM Input 4 is selected to be connected to IC4. + * @arg TIM_ICSELECTION_INDIRECTTI: TIM Input 4 is selected to be connected to IC3. + * @arg TIM_ICSELECTION_TRC: TIM Input 4 is selected to be connected to TRC. + * @param TIM_ICFilter Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @note TIM_ICFilter and TIM_ICPolarity are not used in INDIRECT mode as TI4FP3 + * (on channel1 path) is used as the input signal. Therefore CCMR2 must be + * protected against un-initialized filter and polarity values. + * @retval None + */ +static void TIM_TI4_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter) +{ + uint32_t tmpccmr2; + uint32_t tmpccer; + + /* Disable the Channel 4: Reset the CC4E Bit */ + tmpccer = TIMx->CCER; + TIMx->CCER &= ~TIM_CCER_CC4E; + tmpccmr2 = TIMx->CCMR2; + + /* Select the Input */ + tmpccmr2 &= ~TIM_CCMR2_CC4S; + tmpccmr2 |= (TIM_ICSelection << 8U); + + /* Set the filter */ + tmpccmr2 &= ~TIM_CCMR2_IC4F; + tmpccmr2 |= ((TIM_ICFilter << 12U) & TIM_CCMR2_IC4F); + + /* Select the Polarity and set the CC4E Bit */ + tmpccer &= ~(TIM_CCER_CC4P | TIM_CCER_CC4NP); + tmpccer |= ((TIM_ICPolarity << 12U) & (TIM_CCER_CC4P | TIM_CCER_CC4NP)); + + /* Write to TIMx CCMR2 and CCER registers */ + TIMx->CCMR2 = tmpccmr2; + TIMx->CCER = tmpccer ; +} + +/** + * @brief Selects the Input Trigger source + * @param TIMx to select the TIM peripheral + * @param InputTriggerSource The Input Trigger source. + * This parameter can be one of the following values: + * @arg TIM_TS_ITR0: Internal Trigger 0 + * @arg TIM_TS_ITR1: Internal Trigger 1 + * @arg TIM_TS_ITR2: Internal Trigger 2 + * @arg TIM_TS_ITR3: Internal Trigger 3 + * @arg TIM_TS_ITR4: Internal Trigger 4 + * @arg TIM_TS_ITR5: Internal Trigger 5 + * @arg TIM_TS_ITR6: Internal Trigger 6 + * @arg TIM_TS_ITR7: Internal Trigger 7 + * @arg TIM_TS_ITR8: Internal Trigger 8 + * @arg TIM_TS_ITR9: Internal Trigger 9 + * @arg TIM_TS_ITR10: Internal Trigger 10 + * @arg TIM_TS_ITR11: Internal Trigger 11 + * @arg TIM_TS_ITR12: Internal Trigger 12 + * @arg TIM_TS_TI1F_ED: TI1 Edge Detector + * @arg TIM_TS_TI1FP1: Filtered Timer Input 1 + * @arg TIM_TS_TI2FP2: Filtered Timer Input 2 + * @arg TIM_TS_ETRF: External Trigger input + * @retval None + */ +static void TIM_ITRx_SetConfig(TIM_TypeDef *TIMx, uint32_t InputTriggerSource) +{ + uint32_t tmpsmcr; + + /* Get the TIMx SMCR register value */ + tmpsmcr = TIMx->SMCR; + /* Reset the TS Bits */ + tmpsmcr &= ~TIM_SMCR_TS; + /* Set the Input Trigger source and the slave mode*/ + tmpsmcr |= (InputTriggerSource | TIM_SLAVEMODE_EXTERNAL1); + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; +} +/** + * @brief Configures the TIMx External Trigger (ETR). + * @param TIMx to select the TIM peripheral + * @param TIM_ExtTRGPrescaler The external Trigger Prescaler. + * This parameter can be one of the following values: + * @arg TIM_ETRPRESCALER_DIV1: ETRP Prescaler OFF. + * @arg TIM_ETRPRESCALER_DIV2: ETRP frequency divided by 2. + * @arg TIM_ETRPRESCALER_DIV4: ETRP frequency divided by 4. + * @arg TIM_ETRPRESCALER_DIV8: ETRP frequency divided by 8. + * @param TIM_ExtTRGPolarity The external Trigger Polarity. + * This parameter can be one of the following values: + * @arg TIM_ETRPOLARITY_INVERTED: active low or falling edge active. + * @arg TIM_ETRPOLARITY_NONINVERTED: active high or rising edge active. + * @param ExtTRGFilter External Trigger Filter. + * This parameter must be a value between 0x00 and 0x0F + * @retval None + */ +void TIM_ETR_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ExtTRGPrescaler, + uint32_t TIM_ExtTRGPolarity, uint32_t ExtTRGFilter) +{ + uint32_t tmpsmcr; + + tmpsmcr = TIMx->SMCR; + + /* Reset the ETR Bits */ + tmpsmcr &= ~(TIM_SMCR_ETF | TIM_SMCR_ETPS | TIM_SMCR_ECE | TIM_SMCR_ETP); + + /* Set the Prescaler, the Filter value and the Polarity */ + tmpsmcr |= (uint32_t)(TIM_ExtTRGPrescaler | (TIM_ExtTRGPolarity | (ExtTRGFilter << 8U))); + + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; +} + +/** + * @brief Enables or disables the TIM Capture Compare Channel x. + * @param TIMx to select the TIM peripheral + * @param Channel specifies the TIM Channel + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 + * @arg TIM_CHANNEL_2: TIM Channel 2 + * @arg TIM_CHANNEL_3: TIM Channel 3 + * @arg TIM_CHANNEL_4: TIM Channel 4 + * @arg TIM_CHANNEL_5: TIM Channel 5 selected + * @arg TIM_CHANNEL_6: TIM Channel 6 selected + * @param ChannelState specifies the TIM Channel CCxE bit new state. + * This parameter can be: TIM_CCx_ENABLE or TIM_CCx_DISABLE. + * @retval None + */ +void TIM_CCxChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelState) +{ + uint32_t tmp; + + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(TIMx)); + assert_param(IS_TIM_CHANNELS(Channel)); + + tmp = TIM_CCER_CC1E << (Channel & 0x1FU); /* 0x1FU = 31 bits max shift */ + + /* Reset the CCxE Bit */ + TIMx->CCER &= ~tmp; + + /* Set or reset the CCxE Bit */ + TIMx->CCER |= (uint32_t)(ChannelState << (Channel & 0x1FU)); /* 0x1FU = 31 bits max shift */ +} + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) +/** + * @brief Reset interrupt callbacks to the legacy weak callbacks. + * @param htim pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval None + */ +void TIM_ResetCallback(TIM_HandleTypeDef *htim) +{ + /* Reset the TIM callback to the legacy weak callbacks */ + htim->PeriodElapsedCallback = HAL_TIM_PeriodElapsedCallback; + htim->PeriodElapsedHalfCpltCallback = HAL_TIM_PeriodElapsedHalfCpltCallback; + htim->TriggerCallback = HAL_TIM_TriggerCallback; + htim->TriggerHalfCpltCallback = HAL_TIM_TriggerHalfCpltCallback; + htim->IC_CaptureCallback = HAL_TIM_IC_CaptureCallback; + htim->IC_CaptureHalfCpltCallback = HAL_TIM_IC_CaptureHalfCpltCallback; + htim->OC_DelayElapsedCallback = HAL_TIM_OC_DelayElapsedCallback; + htim->PWM_PulseFinishedCallback = HAL_TIM_PWM_PulseFinishedCallback; + htim->PWM_PulseFinishedHalfCpltCallback = HAL_TIM_PWM_PulseFinishedHalfCpltCallback; + htim->ErrorCallback = HAL_TIM_ErrorCallback; + htim->CommutationCallback = HAL_TIMEx_CommutCallback; + htim->CommutationHalfCpltCallback = HAL_TIMEx_CommutHalfCpltCallback; + htim->BreakCallback = HAL_TIMEx_BreakCallback; + htim->Break2Callback = HAL_TIMEx_Break2Callback; + htim->EncoderIndexCallback = HAL_TIMEx_EncoderIndexCallback; + htim->DirectionChangeCallback = HAL_TIMEx_DirectionChangeCallback; + htim->IndexErrorCallback = HAL_TIMEx_IndexErrorCallback; + htim->TransitionErrorCallback = HAL_TIMEx_TransitionErrorCallback; +} +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + +/** + * @} + */ + +#endif /* HAL_TIM_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_tim_ex.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_tim_ex.c new file mode 100644 index 0000000000..8693b9ef21 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_tim_ex.c @@ -0,0 +1,3446 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_tim_ex.c + * @author MCD Application Team + * @brief TIM HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Timer Extended peripheral: + * + Time Hall Sensor Interface Initialization + * + Time Hall Sensor Interface Start + * + Time Complementary signal break and dead time configuration + * + Time Master and Slave synchronization configuration + * + Time Output Compare/PWM Channel Configuration (for channels 5 and 6) + * + Time OCRef clear configuration + * + Timer remapping capabilities configuration + * + Timer encoder index configuration + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### TIMER Extended features ##### + ============================================================================== + [..] + The Timer Extended features include: + (#) Complementary outputs with programmable dead-time for : + (++) Output Compare + (++) PWM generation (Edge and Center-aligned Mode) + (++) One-pulse mode output + (#) Synchronization circuit to control the timer with external signals and to + interconnect several timers together. + (#) Break input to put the timer output signals in reset state or in a known state. + (#) Supports incremental (quadrature) encoder and hall-sensor circuitry for + positioning purposes + (#) In case of Pulse on compare, configure pulse length and delay + (#) Encoder index configuration + + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Initialize the TIM low level resources by implementing the following functions + depending on the selected feature: + (++) Hall Sensor output : HAL_TIMEx_HallSensor_MspInit() + + (#) Initialize the TIM low level resources : + (##) Enable the TIM interface clock using __HAL_RCC_TIMx_CLK_ENABLE(); + (##) TIM pins configuration + (+++) Enable the clock for the TIM GPIOs using the following function: + __HAL_RCC_GPIOx_CLK_ENABLE(); + (+++) Configure these TIM pins in Alternate function mode using HAL_GPIO_Init(); + + (#) The external Clock can be configured, if needed (the default clock is the + internal clock from the APBx), using the following function: + HAL_TIM_ConfigClockSource, the clock configuration should be done before + any start function. + + (#) Configure the TIM in the desired functioning mode using one of the + initialization function of this driver: + (++) HAL_TIMEx_HallSensor_Init() and HAL_TIMEx_ConfigCommutEvent(): to use the + Timer Hall Sensor Interface and the commutation event with the corresponding + Interrupt and DMA request if needed (Note that One Timer is used to interface + with the Hall sensor Interface and another Timer should be used to use + the commutation event). + (#) In case of Pulse On Compare: + (++) HAL_TIMEx_OC_ConfigPulseOnCompare(): to configure pulse width and prescaler + + + (#) Activate the TIM peripheral using one of the start functions: + (++) Complementary Output Compare : HAL_TIMEx_OCN_Start(), HAL_TIMEx_OCN_Start_DMA(), + HAL_TIMEx_OCN_Start_IT() + (++) Complementary PWM generation : HAL_TIMEx_PWMN_Start(), HAL_TIMEx_PWMN_Start_DMA(), + HAL_TIMEx_PWMN_Start_IT() + (++) Complementary One-pulse mode output : HAL_TIMEx_OnePulseN_Start(), HAL_TIMEx_OnePulseN_Start_IT() + (++) Hall Sensor output : HAL_TIMEx_HallSensor_Start(), HAL_TIMEx_HallSensor_Start_DMA(), + HAL_TIMEx_HallSensor_Start_IT(). + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup TIMEx TIMEx + * @brief TIM Extended HAL module driver + * @{ + */ + +#ifdef HAL_TIM_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup TIMEx_Private_Constants TIM Extended Private Constants + * @{ + */ +/* Timeout for break input rearm */ +#define TIM_BREAKINPUT_REARM_TIMEOUT 5UL /* 5 milliseconds */ +/** + * @} + */ +/* End of private constants --------------------------------------------------*/ + +/* Private macros ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +static void TIM_DMADelayPulseNCplt(DMA_HandleTypeDef *hdma); +static void TIM_DMAErrorCCxN(DMA_HandleTypeDef *hdma); +static void TIM_CCxNChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelNState); + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup TIMEx_Exported_Functions TIM Extended Exported Functions + * @{ + */ + +/** @defgroup TIMEx_Exported_Functions_Group1 Extended Timer Hall Sensor functions + * @brief Timer Hall Sensor functions + * +@verbatim + ============================================================================== + ##### Timer Hall Sensor functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure TIM HAL Sensor. + (+) De-initialize TIM HAL Sensor. + (+) Start the Hall Sensor Interface. + (+) Stop the Hall Sensor Interface. + (+) Start the Hall Sensor Interface and enable interrupts. + (+) Stop the Hall Sensor Interface and disable interrupts. + (+) Start the Hall Sensor Interface and enable DMA transfers. + (+) Stop the Hall Sensor Interface and disable DMA transfers. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the TIM Hall Sensor Interface and initialize the associated handle. + * @note When the timer instance is initialized in Hall Sensor Interface mode, + * timer channels 1 and channel 2 are reserved and cannot be used for + * other purpose. + * @param htim TIM Hall Sensor Interface handle + * @param sConfig TIM Hall Sensor configuration structure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Init(TIM_HandleTypeDef *htim, const TIM_HallSensor_InitTypeDef *sConfig) +{ + TIM_OC_InitTypeDef OC_Config; + + /* Check the TIM handle allocation */ + if (htim == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance)); + assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode)); + assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); + assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload)); + assert_param(IS_TIM_IC_POLARITY(sConfig->IC1Polarity)); + assert_param(IS_TIM_PERIOD(htim, htim->Init.Period)); + assert_param(IS_TIM_IC_PRESCALER(sConfig->IC1Prescaler)); + assert_param(IS_TIM_IC_FILTER(sConfig->IC1Filter)); + + if (htim->State == HAL_TIM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + htim->Lock = HAL_UNLOCKED; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + /* Reset interrupt callbacks to legacy week callbacks */ + TIM_ResetCallback(htim); + + if (htim->HallSensor_MspInitCallback == NULL) + { + htim->HallSensor_MspInitCallback = HAL_TIMEx_HallSensor_MspInit; + } + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + htim->HallSensor_MspInitCallback(htim); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + HAL_TIMEx_HallSensor_MspInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Configure the Time base in the Encoder Mode */ + TIM_Base_SetConfig(htim->Instance, &htim->Init); + + /* Configure the Channel 1 as Input Channel to interface with the three Outputs of the Hall sensor */ + TIM_TI1_SetConfig(htim->Instance, sConfig->IC1Polarity, TIM_ICSELECTION_TRC, sConfig->IC1Filter); + + /* Reset the IC1PSC Bits */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC; + /* Set the IC1PSC value */ + htim->Instance->CCMR1 |= sConfig->IC1Prescaler; + + /* Enable the Hall sensor interface (XOR function of the three inputs) */ + htim->Instance->CR2 |= TIM_CR2_TI1S; + + /* Select the TIM_TS_TI1F_ED signal as Input trigger for the TIM */ + htim->Instance->SMCR &= ~TIM_SMCR_TS; + htim->Instance->SMCR |= TIM_TS_TI1F_ED; + + /* Use the TIM_TS_TI1F_ED signal to reset the TIM counter each edge detection */ + htim->Instance->SMCR &= ~TIM_SMCR_SMS; + htim->Instance->SMCR |= TIM_SLAVEMODE_RESET; + + /* Program channel 2 in PWM 2 mode with the desired Commutation_Delay*/ + OC_Config.OCFastMode = TIM_OCFAST_DISABLE; + OC_Config.OCIdleState = TIM_OCIDLESTATE_RESET; + OC_Config.OCMode = TIM_OCMODE_PWM2; + OC_Config.OCNIdleState = TIM_OCNIDLESTATE_RESET; + OC_Config.OCNPolarity = TIM_OCNPOLARITY_HIGH; + OC_Config.OCPolarity = TIM_OCPOLARITY_HIGH; + OC_Config.Pulse = sConfig->Commutation_Delay; + + TIM_OC2_SetConfig(htim->Instance, &OC_Config); + + /* Select OC2REF as trigger output on TRGO: write the MMS bits in the TIMx_CR2 + register to 101 */ + htim->Instance->CR2 &= ~TIM_CR2_MMS; + htim->Instance->CR2 |= TIM_TRGO_OC2REF; + + /* Initialize the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_READY; + + /* Initialize the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + + /* Initialize the TIM state*/ + htim->State = HAL_TIM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the TIM Hall Sensor interface + * @param htim TIM Hall Sensor Interface handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_DeInit(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the TIM Peripheral Clock */ + __HAL_TIM_DISABLE(htim); + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + if (htim->HallSensor_MspDeInitCallback == NULL) + { + htim->HallSensor_MspDeInitCallback = HAL_TIMEx_HallSensor_MspDeInit; + } + /* DeInit the low level hardware */ + htim->HallSensor_MspDeInitCallback(htim); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + HAL_TIMEx_HallSensor_MspDeInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + /* Change the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_RESET; + + /* Change the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_RESET); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_RESET); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_RESET); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_RESET); + + /* Change TIM state */ + htim->State = HAL_TIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM Hall Sensor MSP. + * @param htim TIM Hall Sensor Interface handle + * @retval None + */ +__weak void HAL_TIMEx_HallSensor_MspInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIMEx_HallSensor_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes TIM Hall Sensor MSP. + * @param htim TIM Hall Sensor Interface handle + * @retval None + */ +__weak void HAL_TIMEx_HallSensor_MspDeInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIMEx_HallSensor_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief Starts the TIM Hall Sensor Interface. + * @param htim TIM Hall Sensor Interface handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start(TIM_HandleTypeDef *htim) +{ + uint32_t tmpsmcr; + HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2); + HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2); + + /* Check the parameters */ + assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance)); + + /* Check the TIM channels state */ + if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) + { + return HAL_ERROR; + } + + /* Set the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + + /* Enable the Input Capture channel 1 + (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1, + TIM_CHANNEL_2 and TIM_CHANNEL_3) */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Hall sensor Interface. + * @param htim TIM Hall Sensor Interface handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance)); + + /* Disable the Input Capture channels 1, 2 and 3 + (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1, + TIM_CHANNEL_2 and TIM_CHANNEL_3) */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Hall Sensor Interface in interrupt mode. + * @param htim TIM Hall Sensor Interface handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_IT(TIM_HandleTypeDef *htim) +{ + uint32_t tmpsmcr; + HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2); + HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2); + + /* Check the parameters */ + assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance)); + + /* Check the TIM channels state */ + if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) + { + return HAL_ERROR; + } + + /* Set the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + + /* Enable the capture compare Interrupts 1 event */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + + /* Enable the Input Capture channel 1 + (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1, + TIM_CHANNEL_2 and TIM_CHANNEL_3) */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Hall Sensor Interface in interrupt mode. + * @param htim TIM Hall Sensor Interface handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_IT(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance)); + + /* Disable the Input Capture channel 1 + (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1, + TIM_CHANNEL_2 and TIM_CHANNEL_3) */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + + /* Disable the capture compare Interrupts event */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Hall Sensor Interface in DMA mode. + * @param htim TIM Hall Sensor Interface handle + * @param pData The destination Buffer address. + * @param Length The length of data to be transferred from TIM peripheral to memory. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length) +{ + uint32_t tmpsmcr; + HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1); + + /* Check the parameters */ + assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance)); + + /* Set the TIM channel state */ + if ((channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY) + || (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY)) + { + return HAL_BUSY; + } + else if ((channel_1_state == HAL_TIM_CHANNEL_STATE_READY) + && (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_READY)) + { + if ((pData == NULL) || (Length == 0U)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + else + { + return HAL_ERROR; + } + + /* Enable the Input Capture channel 1 + (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1, + TIM_CHANNEL_2 and TIM_CHANNEL_3) */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + + /* Set the DMA Input Capture 1 Callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel for Capture 1*/ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t)pData, Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the capture compare 1 Interrupt */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Hall Sensor Interface in DMA mode. + * @param htim TIM Hall Sensor Interface handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_DMA(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance)); + + /* Disable the Input Capture channel 1 + (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1, + TIM_CHANNEL_2 and TIM_CHANNEL_3) */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + + + /* Disable the capture compare Interrupts 1 event */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup TIMEx_Exported_Functions_Group2 Extended Timer Complementary Output Compare functions + * @brief Timer Complementary Output Compare functions + * +@verbatim + ============================================================================== + ##### Timer Complementary Output Compare functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Start the Complementary Output Compare/PWM. + (+) Stop the Complementary Output Compare/PWM. + (+) Start the Complementary Output Compare/PWM and enable interrupts. + (+) Stop the Complementary Output Compare/PWM and disable interrupts. + (+) Start the Complementary Output Compare/PWM and enable DMA transfers. + (+) Stop the Complementary Output Compare/PWM and disable DMA transfers. + +@endverbatim + * @{ + */ + +/** + * @brief Starts the TIM Output Compare signal generation on the complementary + * output. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Start(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + /* Check the TIM complementary channel state */ + if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the TIM complementary channel state */ + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + + /* Enable the Capture compare channel N */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Output Compare signal generation on the complementary + * output. + * @param htim TIM handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + /* Disable the Capture compare channel N */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM complementary channel state */ + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Output Compare signal generation in interrupt mode + * on the complementary output. + * @param htim TIM OC handle + * @param Channel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + /* Check the TIM complementary channel state */ + if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the TIM complementary channel state */ + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Enable the TIM Output Compare interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Enable the TIM Output Compare interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Enable the TIM Output Compare interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3); + break; + } + + + case TIM_CHANNEL_4: + { + /* Enable the TIM Output Compare interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Enable the TIM Break interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_BREAK); + + /* Enable the Capture compare channel N */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + } + + /* Return function status */ + return status; +} + +/** + * @brief Stops the TIM Output Compare signal generation in interrupt mode + * on the complementary output. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpccer; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Output Compare interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Output Compare interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Output Compare interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Disable the TIM Output Compare interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Disable the Capture compare channel N */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); + + /* Disable the TIM Break interrupt (only if no more channel is active) */ + tmpccer = htim->Instance->CCER; + if ((tmpccer & (TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE | TIM_CCER_CC4NE)) == (uint32_t)RESET) + { + __HAL_TIM_DISABLE_IT(htim, TIM_IT_BREAK); + } + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM complementary channel state */ + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + } + + /* Return function status */ + return status; +} + +/** + * @brief Starts the TIM Output Compare signal generation in DMA mode + * on the complementary output. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param pData The source Buffer address. + * @param Length The length of data to be transferred from memory to TIM peripheral + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData, + uint16_t Length) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + /* Set the TIM complementary channel state */ + if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_BUSY) + { + return HAL_BUSY; + } + else if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_READY) + { + if ((pData == NULL) || (Length == 0U)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + else + { + return HAL_ERROR; + } + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseNCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAErrorCCxN ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Output Compare DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseNCplt; + htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAErrorCCxN ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Output Compare DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseNCplt; + htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAErrorCCxN ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Output Compare DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMADelayPulseNCplt; + htim->hdma[TIM_DMA_ID_CC4]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAErrorCCxN ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)pData, (uint32_t)&htim->Instance->CCR4, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Output Compare DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC4); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Enable the Capture compare channel N */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + } + + /* Return function status */ + return status; +} + +/** + * @brief Stops the TIM Output Compare signal generation in DMA mode + * on the complementary output. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Output Compare DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Output Compare DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Output Compare DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]); + break; + } + + case TIM_CHANNEL_4: + { + /* Disable the TIM Output Compare interrupt */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC4); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC4]); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Disable the Capture compare channel N */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM complementary channel state */ + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + } + + /* Return function status */ + return status; +} + +/** + * @} + */ + +/** @defgroup TIMEx_Exported_Functions_Group3 Extended Timer Complementary PWM functions + * @brief Timer Complementary PWM functions + * +@verbatim + ============================================================================== + ##### Timer Complementary PWM functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Start the Complementary PWM. + (+) Stop the Complementary PWM. + (+) Start the Complementary PWM and enable interrupts. + (+) Stop the Complementary PWM and disable interrupts. + (+) Start the Complementary PWM and enable DMA transfers. + (+) Stop the Complementary PWM and disable DMA transfers. + (+) Start the Complementary Input Capture measurement. + (+) Stop the Complementary Input Capture. + (+) Start the Complementary Input Capture and enable interrupts. + (+) Stop the Complementary Input Capture and disable interrupts. + (+) Start the Complementary Input Capture and enable DMA transfers. + (+) Stop the Complementary Input Capture and disable DMA transfers. + (+) Start the Complementary One Pulse generation. + (+) Stop the Complementary One Pulse. + (+) Start the Complementary One Pulse and enable interrupts. + (+) Stop the Complementary One Pulse and disable interrupts. + +@endverbatim + * @{ + */ + +/** + * @brief Starts the PWM signal generation on the complementary output. + * @param htim TIM handle + * @param Channel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + /* Check the TIM complementary channel state */ + if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the TIM complementary channel state */ + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + + /* Enable the complementary PWM output */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the PWM signal generation on the complementary output. + * @param htim TIM handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + /* Disable the complementary PWM output */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM complementary channel state */ + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the PWM signal generation in interrupt mode on the + * complementary output. + * @param htim TIM handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + /* Check the TIM complementary channel state */ + if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the TIM complementary channel state */ + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Enable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Enable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Enable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Enable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Enable the TIM Break interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_BREAK); + + /* Enable the complementary PWM output */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + } + + /* Return function status */ + return status; +} + +/** + * @brief Stops the PWM signal generation in interrupt mode on the + * complementary output. + * @param htim TIM handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpccer; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Disable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Disable the complementary PWM output */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); + + /* Disable the TIM Break interrupt (only if no more channel is active) */ + tmpccer = htim->Instance->CCER; + if ((tmpccer & (TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE | TIM_CCER_CC4NE)) == (uint32_t)RESET) + { + __HAL_TIM_DISABLE_IT(htim, TIM_IT_BREAK); + } + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM complementary channel state */ + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + } + + /* Return function status */ + return status; +} + +/** + * @brief Starts the TIM PWM signal generation in DMA mode on the + * complementary output + * @param htim TIM handle + * @param Channel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param pData The source Buffer address. + * @param Length The length of data to be transferred from memory to TIM peripheral + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData, + uint16_t Length) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + /* Set the TIM complementary channel state */ + if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_BUSY) + { + return HAL_BUSY; + } + else if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_READY) + { + if ((pData == NULL) || (Length == 0U)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + else + { + return HAL_ERROR; + } + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseNCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAErrorCCxN ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseNCplt; + htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAErrorCCxN ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseNCplt; + htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAErrorCCxN ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 3 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMADelayPulseNCplt; + htim->hdma[TIM_DMA_ID_CC4]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAErrorCCxN ; + + /* Enable the DMA channel */ + if (TIM_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)pData, (uint32_t)&htim->Instance->CCR4, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 4 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC4); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Enable the complementary PWM output */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + } + + /* Return function status */ + return status; +} + +/** + * @brief Stops the TIM PWM signal generation in DMA mode on the complementary + * output + * @param htim TIM handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]); + break; + } + + case TIM_CHANNEL_4: + { + /* Disable the TIM Capture/Compare 4 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC4); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC4]); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Disable the complementary PWM output */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM complementary channel state */ + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + } + + /* Return function status */ + return status; +} + +/** + * @} + */ + +/** @defgroup TIMEx_Exported_Functions_Group4 Extended Timer Complementary One Pulse functions + * @brief Timer Complementary One Pulse functions + * +@verbatim + ============================================================================== + ##### Timer Complementary One Pulse functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Start the Complementary One Pulse generation. + (+) Stop the Complementary One Pulse. + (+) Start the Complementary One Pulse and enable interrupts. + (+) Stop the Complementary One Pulse and disable interrupts. + +@endverbatim + * @{ + */ + +/** + * @brief Starts the TIM One Pulse signal generation on the complementary + * output. + * @note OutputChannel must match the pulse output channel chosen when calling + * @ref HAL_TIM_OnePulse_ConfigChannel(). + * @param htim TIM One Pulse handle + * @param OutputChannel pulse output channel to enable + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1; + HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2); + HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2); + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel)); + + /* Check the TIM channels state */ + if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) + { + return HAL_ERROR; + } + + /* Set the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + + /* Enable the complementary One Pulse output channel and the Input Capture channel */ + TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_ENABLE); + TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM One Pulse signal generation on the complementary + * output. + * @note OutputChannel must match the pulse output channel chosen when calling + * @ref HAL_TIM_OnePulse_ConfigChannel(). + * @param htim TIM One Pulse handle + * @param OutputChannel pulse output channel to disable + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel)); + + /* Disable the complementary One Pulse output channel and the Input Capture channel */ + TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_DISABLE); + TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_DISABLE); + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM One Pulse signal generation in interrupt mode on the + * complementary channel. + * @note OutputChannel must match the pulse output channel chosen when calling + * @ref HAL_TIM_OnePulse_ConfigChannel(). + * @param htim TIM One Pulse handle + * @param OutputChannel pulse output channel to enable + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1; + HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2); + HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2); + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel)); + + /* Check the TIM channels state */ + if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) + { + return HAL_ERROR; + } + + /* Set the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + + /* Enable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + + /* Enable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + + /* Enable the complementary One Pulse output channel and the Input Capture channel */ + TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_ENABLE); + TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM One Pulse signal generation in interrupt mode on the + * complementary channel. + * @note OutputChannel must match the pulse output channel chosen when calling + * @ref HAL_TIM_OnePulse_ConfigChannel(). + * @param htim TIM One Pulse handle + * @param OutputChannel pulse output channel to disable + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel)); + + /* Disable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + + /* Disable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + + /* Disable the complementary One Pulse output channel and the Input Capture channel */ + TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_DISABLE); + TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_DISABLE); + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup TIMEx_Exported_Functions_Group5 Extended Peripheral Control functions + * @brief Peripheral Control functions + * +@verbatim + ============================================================================== + ##### Peripheral Control functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Configure the commutation event in case of use of the Hall sensor interface. + (+) Configure Output channels for OC and PWM mode. + + (+) Configure Complementary channels, break features and dead time. + (+) Configure Master synchronization. + (+) Configure timer remapping capabilities. + (+) Select timer input source. + (+) Enable or disable channel grouping. + (+) Configure Pulse on compare. + (+) Configure Encoder index. + +@endverbatim + * @{ + */ + +/** + * @brief Configure the TIM commutation event sequence. + * @note This function is mandatory to use the commutation event in order to + * update the configuration at each commutation detection on the TRGI input of the Timer, + * the typical use of this feature is with the use of another Timer(interface Timer) + * configured in Hall sensor interface, this interface Timer will generate the + * commutation at its TRGO output (connected to Timer used in this function) each time + * the TI1 of the Interface Timer detect a commutation at its input TI1. + * @param htim TIM handle + * @param InputTrigger the Internal trigger corresponding to the Timer Interfacing with the Hall sensor + * This parameter can be one of the following values: + * @arg TIM_TS_ITR0: Internal trigger 0 selected + * @arg TIM_TS_ITR1: Internal trigger 1 selected + * @arg TIM_TS_ITR2: Internal trigger 2 selected + * @arg TIM_TS_ITR3: Internal trigger 3 selected + * @arg TIM_TS_ITR4: Internal trigger 4 selected + * @arg TIM_TS_ITR5: Internal trigger 5 selected + * @arg TIM_TS_ITR6: Internal trigger 6 selected + * @arg TIM_TS_ITR7: Internal trigger 7 selected + * @arg TIM_TS_ITR8: Internal trigger 8 selected + * @arg TIM_TS_ITR9: Internal trigger 9 selected + * @arg TIM_TS_ITR10: Internal trigger 10 selected + * @arg TIM_TS_ITR11: Internal trigger 11 selected + * @arg TIM_TS_ITR12: Internal trigger 12 selected + * @arg TIM_TS_NONE: No trigger is needed + * @param CommutationSource the Commutation Event source + * This parameter can be one of the following values: + * @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer + * @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent(TIM_HandleTypeDef *htim, uint32_t InputTrigger, + uint32_t CommutationSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance)); + assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_INSTANCE(htim->Instance, InputTrigger)); + + __HAL_LOCK(htim); + + if (CommutationSource == TIM_COMMUTATION_TRGI) + { + /* Select the Input trigger */ + htim->Instance->SMCR &= ~TIM_SMCR_TS; + htim->Instance->SMCR |= InputTrigger; + } + + /* Select the Capture Compare preload feature */ + htim->Instance->CR2 |= TIM_CR2_CCPC; + /* Select the Commutation event source */ + htim->Instance->CR2 &= ~TIM_CR2_CCUS; + htim->Instance->CR2 |= CommutationSource; + + /* Disable Commutation Interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_COM); + + /* Disable Commutation DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_COM); + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Configure the TIM commutation event sequence with interrupt. + * @note This function is mandatory to use the commutation event in order to + * update the configuration at each commutation detection on the TRGI input of the Timer, + * the typical use of this feature is with the use of another Timer(interface Timer) + * configured in Hall sensor interface, this interface Timer will generate the + * commutation at its TRGO output (connected to Timer used in this function) each time + * the TI1 of the Interface Timer detect a commutation at its input TI1. + * @param htim TIM handle + * @param InputTrigger the Internal trigger corresponding to the Timer Interfacing with the Hall sensor + * This parameter can be one of the following values: + * @arg TIM_TS_ITR0: Internal trigger 0 selected + * @arg TIM_TS_ITR1: Internal trigger 1 selected + * @arg TIM_TS_ITR2: Internal trigger 2 selected + * @arg TIM_TS_ITR3: Internal trigger 3 selected + * @arg TIM_TS_ITR4: Internal trigger 4 selected + * @arg TIM_TS_ITR5: Internal trigger 5 selected + * @arg TIM_TS_ITR6: Internal trigger 6 selected + * @arg TIM_TS_ITR7: Internal trigger 7 selected + * @arg TIM_TS_ITR8: Internal trigger 8 selected + * @arg TIM_TS_ITR9: Internal trigger 9 selected + * @arg TIM_TS_ITR10: Internal trigger 10 selected + * @arg TIM_TS_ITR11: Internal trigger 11 selected + * @arg TIM_TS_ITR12: Internal trigger 12 selected + * @arg TIM_TS_NONE: No trigger is needed + * @param CommutationSource the Commutation Event source + * This parameter can be one of the following values: + * @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer + * @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_IT(TIM_HandleTypeDef *htim, uint32_t InputTrigger, + uint32_t CommutationSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance)); + assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_INSTANCE(htim->Instance, InputTrigger)); + + __HAL_LOCK(htim); + + if (CommutationSource == TIM_COMMUTATION_TRGI) + { + /* Select the Input trigger */ + htim->Instance->SMCR &= ~TIM_SMCR_TS; + htim->Instance->SMCR |= InputTrigger; + } + + /* Select the Capture Compare preload feature */ + htim->Instance->CR2 |= TIM_CR2_CCPC; + /* Select the Commutation event source */ + htim->Instance->CR2 &= ~TIM_CR2_CCUS; + htim->Instance->CR2 |= CommutationSource; + + /* Disable Commutation DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_COM); + + /* Enable the Commutation Interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_COM); + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Configure the TIM commutation event sequence with DMA. + * @note This function is mandatory to use the commutation event in order to + * update the configuration at each commutation detection on the TRGI input of the Timer, + * the typical use of this feature is with the use of another Timer(interface Timer) + * configured in Hall sensor interface, this interface Timer will generate the + * commutation at its TRGO output (connected to Timer used in this function) each time + * the TI1 of the Interface Timer detect a commutation at its input TI1. + * @note The user should configure the DMA in his own software, in This function only the COMDE bit is set + * @param htim TIM handle + * @param InputTrigger the Internal trigger corresponding to the Timer Interfacing with the Hall sensor + * This parameter can be one of the following values: + * @arg TIM_TS_ITR0: Internal trigger 0 selected + * @arg TIM_TS_ITR1: Internal trigger 1 selected + * @arg TIM_TS_ITR2: Internal trigger 2 selected + * @arg TIM_TS_ITR3: Internal trigger 3 selected + * @arg TIM_TS_ITR4: Internal trigger 4 selected + * @arg TIM_TS_ITR5: Internal trigger 5 selected + * @arg TIM_TS_ITR6: Internal trigger 6 selected + * @arg TIM_TS_ITR7: Internal trigger 7 selected + * @arg TIM_TS_ITR8: Internal trigger 8 selected + * @arg TIM_TS_ITR9: Internal trigger 9 selected + * @arg TIM_TS_ITR10: Internal trigger 10 selected + * @arg TIM_TS_ITR11: Internal trigger 11 selected + * @arg TIM_TS_ITR12: Internal trigger 12 selected + * @arg TIM_TS_NONE: No trigger is needed + * @param CommutationSource the Commutation Event source + * This parameter can be one of the following values: + * @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer + * @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_DMA(TIM_HandleTypeDef *htim, uint32_t InputTrigger, + uint32_t CommutationSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance)); + assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_INSTANCE(htim->Instance, InputTrigger)); + + __HAL_LOCK(htim); + + if (CommutationSource == TIM_COMMUTATION_TRGI) + { + /* Select the Input trigger */ + htim->Instance->SMCR &= ~TIM_SMCR_TS; + htim->Instance->SMCR |= InputTrigger; + } + + /* Select the Capture Compare preload feature */ + htim->Instance->CR2 |= TIM_CR2_CCPC; + /* Select the Commutation event source */ + htim->Instance->CR2 &= ~TIM_CR2_CCUS; + htim->Instance->CR2 |= CommutationSource; + + /* Enable the Commutation DMA Request */ + /* Set the DMA Commutation Callback */ + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferCpltCallback = TIMEx_DMACommutationCplt; + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferHalfCpltCallback = TIMEx_DMACommutationHalfCplt; + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferErrorCallback = TIM_DMAError; + + /* Disable Commutation Interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_COM); + + /* Enable the Commutation DMA Request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_COM); + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Configures the TIM in master mode. + * @param htim TIM handle. + * @param sMasterConfig pointer to a TIM_MasterConfigTypeDef structure that + * contains the selected trigger output (TRGO) and the Master/Slave + * mode. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_MasterConfigSynchronization(TIM_HandleTypeDef *htim, + const TIM_MasterConfigTypeDef *sMasterConfig) +{ + uint32_t tmpcr2; + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_MASTER_INSTANCE(htim->Instance)); + assert_param(IS_TIM_TRGO_SOURCE(sMasterConfig->MasterOutputTrigger)); + assert_param(IS_TIM_MSM_STATE(sMasterConfig->MasterSlaveMode)); + + /* Check input state */ + __HAL_LOCK(htim); + + /* Change the handler state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Get the TIMx CR2 register value */ + tmpcr2 = htim->Instance->CR2; + + /* Get the TIMx SMCR register value */ + tmpsmcr = htim->Instance->SMCR; + + /* If the timer supports ADC synchronization through TRGO2, set the master mode selection 2 */ + if (IS_TIM_TRGO2_INSTANCE(htim->Instance)) + { + /* Check the parameters */ + assert_param(IS_TIM_TRGO2_SOURCE(sMasterConfig->MasterOutputTrigger2)); + + /* Clear the MMS2 bits */ + tmpcr2 &= ~TIM_CR2_MMS2; + /* Select the TRGO2 source*/ + tmpcr2 |= sMasterConfig->MasterOutputTrigger2; + } + + /* Reset the MMS Bits */ + tmpcr2 &= ~TIM_CR2_MMS; + /* Select the TRGO source */ + tmpcr2 |= sMasterConfig->MasterOutputTrigger; + + /* Update TIMx CR2 */ + htim->Instance->CR2 = tmpcr2; + + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + /* Reset the MSM Bit */ + tmpsmcr &= ~TIM_SMCR_MSM; + /* Set master mode */ + tmpsmcr |= sMasterConfig->MasterSlaveMode; + + /* Update TIMx SMCR */ + htim->Instance->SMCR = tmpsmcr; + } + + /* Change the htim state */ + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Configures the Break feature, dead time, Lock level, OSSI/OSSR State + * and the AOE(automatic output enable). + * @param htim TIM handle + * @param sBreakDeadTimeConfig pointer to a TIM_ConfigBreakDeadConfigTypeDef structure that + * contains the BDTR Register configuration information for the TIM peripheral. + * @note Interrupts can be generated when an active level is detected on the + * break input, the break 2 input or the system break input. Break + * interrupt can be enabled by calling the @ref __HAL_TIM_ENABLE_IT macro. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef *htim, + const TIM_BreakDeadTimeConfigTypeDef *sBreakDeadTimeConfig) +{ + /* Keep this variable initialized to 0 as it is used to configure BDTR register */ + uint32_t tmpbdtr = 0U; + + /* Check the parameters */ + assert_param(IS_TIM_BREAK_INSTANCE(htim->Instance)); + assert_param(IS_TIM_OSSR_STATE(sBreakDeadTimeConfig->OffStateRunMode)); + assert_param(IS_TIM_OSSI_STATE(sBreakDeadTimeConfig->OffStateIDLEMode)); + assert_param(IS_TIM_LOCK_LEVEL(sBreakDeadTimeConfig->LockLevel)); + assert_param(IS_TIM_DEADTIME(sBreakDeadTimeConfig->DeadTime)); + assert_param(IS_TIM_BREAK_STATE(sBreakDeadTimeConfig->BreakState)); + assert_param(IS_TIM_BREAK_POLARITY(sBreakDeadTimeConfig->BreakPolarity)); + assert_param(IS_TIM_BREAK_FILTER(sBreakDeadTimeConfig->BreakFilter)); + assert_param(IS_TIM_AUTOMATIC_OUTPUT_STATE(sBreakDeadTimeConfig->AutomaticOutput)); + + /* Check input state */ + __HAL_LOCK(htim); + + /* Set the Lock level, the Break enable Bit and the Polarity, the OSSR State, + the OSSI State, the dead time value and the Automatic Output Enable Bit */ + + /* Set the BDTR bits */ + MODIFY_REG(tmpbdtr, TIM_BDTR_DTG, sBreakDeadTimeConfig->DeadTime); + MODIFY_REG(tmpbdtr, TIM_BDTR_LOCK, sBreakDeadTimeConfig->LockLevel); + MODIFY_REG(tmpbdtr, TIM_BDTR_OSSI, sBreakDeadTimeConfig->OffStateIDLEMode); + MODIFY_REG(tmpbdtr, TIM_BDTR_OSSR, sBreakDeadTimeConfig->OffStateRunMode); + MODIFY_REG(tmpbdtr, TIM_BDTR_BKE, sBreakDeadTimeConfig->BreakState); + MODIFY_REG(tmpbdtr, TIM_BDTR_BKP, sBreakDeadTimeConfig->BreakPolarity); + MODIFY_REG(tmpbdtr, TIM_BDTR_AOE, sBreakDeadTimeConfig->AutomaticOutput); + MODIFY_REG(tmpbdtr, TIM_BDTR_BKF, (sBreakDeadTimeConfig->BreakFilter << TIM_BDTR_BKF_Pos)); + + if (IS_TIM_ADVANCED_INSTANCE(htim->Instance)) + { + /* Check the parameters */ + assert_param(IS_TIM_BREAK_AFMODE(sBreakDeadTimeConfig->BreakAFMode)); + + /* Set BREAK AF mode */ + MODIFY_REG(tmpbdtr, TIM_BDTR_BKBID, sBreakDeadTimeConfig->BreakAFMode); + } + + if (IS_TIM_BKIN2_INSTANCE(htim->Instance)) + { + /* Check the parameters */ + assert_param(IS_TIM_BREAK2_STATE(sBreakDeadTimeConfig->Break2State)); + assert_param(IS_TIM_BREAK2_POLARITY(sBreakDeadTimeConfig->Break2Polarity)); + assert_param(IS_TIM_BREAK_FILTER(sBreakDeadTimeConfig->Break2Filter)); + + /* Set the BREAK2 input related BDTR bits */ + MODIFY_REG(tmpbdtr, TIM_BDTR_BK2F, (sBreakDeadTimeConfig->Break2Filter << TIM_BDTR_BK2F_Pos)); + MODIFY_REG(tmpbdtr, TIM_BDTR_BK2E, sBreakDeadTimeConfig->Break2State); + MODIFY_REG(tmpbdtr, TIM_BDTR_BK2P, sBreakDeadTimeConfig->Break2Polarity); + + if (IS_TIM_ADVANCED_INSTANCE(htim->Instance)) + { + /* Check the parameters */ + assert_param(IS_TIM_BREAK2_AFMODE(sBreakDeadTimeConfig->Break2AFMode)); + + /* Set BREAK2 AF mode */ + MODIFY_REG(tmpbdtr, TIM_BDTR_BK2BID, sBreakDeadTimeConfig->Break2AFMode); + } + } + + /* Set TIMx_BDTR */ + htim->Instance->BDTR = tmpbdtr; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Configures the break input source. + * @param htim TIM handle. + * @param BreakInput Break input to configure + * This parameter can be one of the following values: + * @arg TIM_BREAKINPUT_BRK: Timer break input + * @arg TIM_BREAKINPUT_BRK2: Timer break 2 input + * @param sBreakInputConfig Break input source configuration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_ConfigBreakInput(TIM_HandleTypeDef *htim, + uint32_t BreakInput, + const TIMEx_BreakInputConfigTypeDef *sBreakInputConfig) + +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmporx; + uint32_t bkin_enable_mask; + uint32_t bkin_polarity_mask; + uint32_t bkin_enable_bitpos; + uint32_t bkin_polarity_bitpos; + + /* Check the parameters */ + assert_param(IS_TIM_BREAK_INSTANCE(htim->Instance)); + assert_param(IS_TIM_BREAKINPUT(BreakInput)); + assert_param(IS_TIM_BREAKINPUTSOURCE(sBreakInputConfig->Source)); + assert_param(IS_TIM_BREAKINPUTSOURCE_STATE(sBreakInputConfig->Enable)); + assert_param(IS_TIM_BREAKINPUTSOURCE_POLARITY(sBreakInputConfig->Polarity)); + + /* Check input state */ + __HAL_LOCK(htim); + + switch (sBreakInputConfig->Source) + { + case TIM_BREAKINPUTSOURCE_BKIN: + { + bkin_enable_mask = TIM1_AF1_BKINE; + bkin_enable_bitpos = TIM1_AF1_BKINE_Pos; + bkin_polarity_mask = TIM1_AF1_BKINP; + bkin_polarity_bitpos = TIM1_AF1_BKINP_Pos; + break; + } +#if defined(COMP1) + case TIM_BREAKINPUTSOURCE_COMP1: + { + bkin_enable_mask = TIM1_AF1_BKCMP1E; + bkin_enable_bitpos = TIM1_AF1_BKCMP1E_Pos; + bkin_polarity_mask = TIM1_AF1_BKCMP1P; + bkin_polarity_bitpos = TIM1_AF1_BKCMP1P_Pos; + break; + } +#endif /* COMP1 */ + + default: + { + bkin_enable_mask = 0U; + bkin_polarity_mask = 0U; + bkin_enable_bitpos = 0U; + bkin_polarity_bitpos = 0U; + break; + } + } + + switch (BreakInput) + { + case TIM_BREAKINPUT_BRK: + { + /* Get the TIMx_AF1 register value */ + tmporx = htim->Instance->AF1; + + /* Enable the break input */ + tmporx &= ~bkin_enable_mask; + tmporx |= (sBreakInputConfig->Enable << bkin_enable_bitpos) & bkin_enable_mask; + + /* Set the break input polarity */ + tmporx &= ~bkin_polarity_mask; + tmporx |= (sBreakInputConfig->Polarity << bkin_polarity_bitpos) & bkin_polarity_mask; + + /* Set TIMx_AF1 */ + htim->Instance->AF1 = tmporx; + break; + } + case TIM_BREAKINPUT_BRK2: + { + /* Get the TIMx_AF2 register value */ + tmporx = htim->Instance->AF2; + + /* Enable the break input */ + tmporx &= ~bkin_enable_mask; + tmporx |= (sBreakInputConfig->Enable << bkin_enable_bitpos) & bkin_enable_mask; + + /* Set the break input polarity */ + tmporx &= ~bkin_polarity_mask; + tmporx |= (sBreakInputConfig->Polarity << bkin_polarity_bitpos) & bkin_polarity_mask; + + /* Set TIMx_AF2 */ + htim->Instance->AF2 = tmporx; + break; + } + default: + status = HAL_ERROR; + break; + } + + __HAL_UNLOCK(htim); + + return status; +} + +/** + * @brief Configures the TIMx Remapping input capabilities. + * @param htim TIM handle. + * @param Remap specifies the TIM remapping source. + * For TIM1, the parameter can take one of the following values: + * @arg TIM_TIM1_ETR_GPIO TIM1 ETR is connected to GPIO + * @arg TIM_TIM1_ETR_COMP1 TIM1 ETR is connected to COMP1 output (*) + * @arg TIM_TIM1_ETR_ADC1_AWD1 TIM1 ETR is connected to ADC1 AWD1 + * @arg TIM_TIM1_ETR_ADC1_AWD2 TIM1 ETR is connected to ADC1 AWD2 + * @arg TIM_TIM1_ETR_ADC1_AWD3 TIM1 ETR is connected to ADC1 AWD3 + * + * For TIM2, the parameter can take one of the following values: + * @arg TIM_TIM2_ETR_GPIO TIM2 ETR is connected to GPIO + * @arg TIM_TIM2_ETR_COMP1 TIM2 ETR is connected to COMP1 output (*) + * @arg TIM_TIM2_ETR_LSE TIM2 ETR is connected to LSE + * @arg TIM_TIM2_ETR_SAI1_FSA TIM2 ETR is connected to SAI1 FSA (*) + * @arg TIM_TIM2_ETR_SAI1_FSB TIM2 ETR is connected to SAI1 FSB (*) + * @arg TIM_TIM2_ETR_TIM3_ETR TIM2 ETR is connected to TIM3 ETR pin + * @arg TIM_TIM2_ETR_TIM4_ETR TIM2 ETR is connected to TIM4 ETR pin (*) + * @arg TIM_TIM2_ETR_TIM5_ETR TIM2 ETR is connected to TIM5 ETR pin (*) + * @arg TIM_TIM2_ETR_ETH_PPS TIM2 ETR is connected to ETH PPS (*) + * + * For TIM3, the parameter can take one of the following values: + * @arg TIM_TIM3_ETR_GPIO TIM3 ETR is connected to GPIO + * @arg TIM_TIM3_ETR_COMP1 TIM3 ETR is connected to COMP1 output (*) + * @arg TIM_TIM3_ETR_TIM2_ETR TIM3 ETR is connected to TIM2 ETR pin + * @arg TIM_TIM3_ETR_TIM4_ETR TIM3 ETR is connected to TIM4 ETR pin (*) + * @arg TIM_TIM3_ETR_TIM5_ETR TIM3 ETR is connected to TIM5 ETR pin (*) + * @arg TIM_TIM3_ETR_ETH_PPS TIM3 ETR is connected to ETH PPS (*) + * + * For TIM4, the parameter can take one of the following values: (**) + * @arg TIM_TIM4_ETR_GPIO TIM4 ETR is connected to GPIO + * @arg TIM_TIM4_ETR_TIM2_ETR TIM4 ETR is connected to TIM2 ETR pin + * @arg TIM_TIM4_ETR_TIM3_ETR TIM4 ETR is connected to TIM3 ETR pin + * @arg TIM_TIM4_ETR_TIM5_ETR TIM4 ETR is connected to TIM5 ETR pin + * + * For TIM5, the parameter can take one of the following values: (**) + * @arg TIM_TIM5_ETR_GPIO TIM5 ETR is connected to GPIO + * @arg TIM_TIM2_ETR_SAI2_FSA TIM2 ETR is connected to SAI2 FSA + * @arg TIM_TIM2_ETR_SAI2_FSB TIM2 ETR is connected to SAI2 FSB + * @arg TIM_TIM5_ETR_TIM2_ETR TIM5 ETR is connected to TIM2 ETR pin + * @arg TIM_TIM5_ETR_TIM3_ETR TIM5 ETR is connected to TIM3 ETR pin + * @arg TIM_TIM5_ETR_TIM4_ETR TIM5 ETR is connected to TIM4 ETR pin + * + * For TIM8, the parameter can take one of the following values: (**) + * @arg TIM_TIM8_ETR_GPIO TIM8 ETR is connected to GPIO + * @arg TIM_TIM8_ETR_ADC2_AWD1 TIM8 ETR is connected to ADC2 AWD1 + * @arg TIM_TIM8_ETR_ADC2_AWD2 TIM8 ETR is connected to ADC2 AWD2 + * @arg TIM_TIM8_ETR_ADC2_AWD3 TIM8 ETR is connected to ADC2 AWD3 + * + * (*) Value not defined in all devices. + * (**) Timer instance not available on all devices. \n + * + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_RemapConfig(TIM_HandleTypeDef *htim, uint32_t Remap) +{ + /* Check parameters */ + assert_param(IS_TIM_REMAP_INSTANCE(htim->Instance)); + assert_param(IS_TIM_REMAP(Remap)); + + __HAL_LOCK(htim); + + MODIFY_REG(htim->Instance->AF1, TIM1_AF1_ETRSEL_Msk, Remap); + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Select the timer input source + * @param htim TIM handle. + * @param Channel specifies the TIM Channel + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TI1 input channel + * @arg TIM_CHANNEL_2: TI2 input channel + * @arg TIM_CHANNEL_4: TI4 input channel + * @param TISelection parameter of the TIM_TISelectionStruct structure is detailed as follows: + * For TIM1, the parameter is one of the following values: + * @arg TIM_TIM1_TI1_GPIO: TIM1 TI1 is connected to GPIO + * @arg TIM_TIM1_TI1_COMP1: TIM1 TI1 is connected to COMP1 output (*) + * @arg TIM_TIM1_TI2_GPIO: TIM1 TI2 is connected to GPIO + * @arg TIM_TIM1_TI3_GPIO: TIM1 TI3 is connected to GPIO + * @arg TIM_TIM1_TI4_GPIO: TIM1 TI4 is connected to GPIO + * + * For TIM2, the parameter is one of the following values: + * @arg TIM_TIM2_TI1_GPIO: TIM2 TI1 is connected to GPIO + * @arg TIM_TIM2_TI1_LSI: TIM2 TI1 is connected to LSI (*) + * @arg TIM_TIM2_TI1_LSE: TIM2 TI1 is connected to LSE (*) + * @arg TIM_TIM2_TI1_ETH_PPS TIM2 TI1 is connected to ETH PPS (*) + * @arg TIM_TIM2_TI1_RTC_WKUP: TIM2 TI2 is connected to RTC_WKUP (*) + * @arg TIM_TIM2_TI1_TIM3_TI1: TIM2 TI2 is connected to TIM3_TI1 (*) + * @arg TIM_TIM2_TI2_GPIO: TIM2 TI2 is connected to GPIO + * @arg TIM_TIM2_TI2_HSI_1024: TIM2 TI2 is connected to HSI/1024 (*) + * @arg TIM_TIM2_TI2_CSI_128: TIM2 TI2 is connected to CSI/128 (*) + * @arg TIM_TIM2_TI2_MCO2: TIM2 TI2 is connected to MCO1 (*) + * @arg TIM_TIM2_TI2_MCO1: TIM2 TI2 is connected to MCO1 (*) + * @arg TIM_TIM2_TI3_GPIO: TIM2 TI3 is connected to GPIO + * @arg TIM_TIM2_TI4_GPIO: TIM2 TI4 is connected to GPIO + * @arg TIM_TIM2_TI4_COMP1: TIM2 TI4 is connected to COMP1 output (*) + * + * For TIM3, the parameter is one of the following values: + * @arg TIM_TIM3_TI1_GPIO: TIM3 TI1 is connected to GPIO + * @arg TIM_TIM3_TI1_COMP1: TIM3 TI1 is connected to COMP1 output (*) + * @arg TIM_TIM3_TI1_MCO1: TIM3 TI2 is connected to MCO1 (*) + * @arg TIM_TIM3_TI1_TIM2_TI1: TIM3 TI2 is connected to TIM2 TI1 (*) + * @arg TIM_TIM3_TI1_HSE_1MHZ: TIM3 TI2 is connected to HSE_1MHZ (*) + * @arg TIM_TIM3_TI1_ETH_PPS TIM3 TI1 is connected to ETH PPS (*) + * @arg TIM_TIM3_TI2_GPIO: TIM3 TI2 is connected to GPIO + * @arg TIM_TIM3_TI2_CSI_128: TIM3 TI2 is connected to CSI_128 (*) + * @arg TIM_TIM3_TI2_MCO2: TIM3 TI2 is connected to MCO2 (*) + * @arg TIM_TIM3_TI2_HSI_1024: TIM3 TI2 is connected to HSI_1024 (*) + * @arg TIM_TIM3_TI3_GPIO: TIM3 TI2 is connected to GPIO + * @arg TIM_TIM3_TI4_GPIO: TIM3 TI2 is connected to GPIO + * + * For TIM4, the parameter is one of the following values: (**) + * @arg TIM_TIM4_TI1_GPIO: TIM4 TI1 is connected to GPIO + * @arg TIM_TIM4_TI2_GPIO: TIM4 TI2 is connected to GPIO + * @arg TIM_TIM4_TI3_GPIO: TIM4 TI3 is connected to GPIO + * @arg TIM_TIM4_TI4_GPIO: TIM4 TI4 is connected to GPIO + * + * For TIM5, the parameter is one of the following values: (**) + * @arg TIM_TIM5_TI1_GPIO: TIM5 TI1 is connected to GPIO + * @arg TIM_TIM5_TI2_GPIO: TIM5 TI2 is connected to GPIO + * @arg TIM_TIM5_TI3_GPIO: TIM5 TI3 is connected to GPIO + * @arg TIM_TIM5_TI4_GPIO: TIM5 TI4 is connected to GPIO + * + * For TIM8, the parameter is one of the following values: (**) + * @arg TIM_TIM8_TI1_GPIO: TIM8 TI1 is connected to GPIO + * @arg TIM_TIM8_TI2_GPIO: TIM8 TI2 is connected to GPIO + * @arg TIM_TIM8_TI3_GPIO: TIM8 TI3 is connected to GPIO + * @arg TIM_TIM8_TI4_GPIO: TIM8 TI4 is connected to GPIO + * + * For TIM12, the parameter is one of the following values: (**) + * @arg TIM_TIM12_TI1_GPIO: TIM12 TI1 is connected to GPIO + * @arg TIM_TIM12_TI1_HSI_1024: TIM12 TI1 is connected to HSI/1024 + * @arg TIM_TIM12_TI1_CSI_128: TIM12 TI1 is connected to CSI/128 + * + * For TIM13, the parameter is one of the following values: (**) + * @arg TIM_TIM12_TI1_GPIO: TIM13 TI1 is connected to GPIO + * + * For TIM14, the parameter is one of the following values: (**) + * @arg TIM_TIM14_TI1_GPIO: TIM14 TI1 is connected to GPIO + * + * For TIM15, the parameter can have the following values: (**) + * @arg TIM_TIM15_TI1_GPIO: TIM15 TI1 is connected to GPIO + * @arg TIM_TIM15_TI1_TIM2: TIM15 TI1 is connected to TIM2 + * @arg TIM_TIM15_TI1_TIM3: TIM15 TI1 is connected to TIM3 + * @arg TIM_TIM15_TI1_TIM4: TIM15 TI1 is connected to TIM4 + * @arg TIM_TIM15_TI1_LSE: TIM15 TI1 is connected to LSE + * @arg TIM_TIM15_TI1_CSI_128: TIM15 TI1 is connected to CSI/128 + * @arg TIM_TIM15_TI1_MCO: TIM15 TI1 is connected to MCO + * @arg TIM_TIM15_TI2_GPIO: TIM15 TI1 is connected to GPIO + * @arg TIM_TIM15_TI2_TIM2: TIM15 TI1 is connected to TIM2 + * @arg TIM_TIM15_TI2_TIM3: TIM15 TI1 is connected to TIM3 + * @arg TIM_TIM15_TI2_TIM4: TIM15 TI1 is connected to TIM4 + * + * For TIM16, the parameter is one of the following values: (**) + * @arg TIM_TIM16_TI1_GPIO: TIM16 TI1 is connected to GPIO + * @arg TIM_TIM16_TI1_LSI: TIM16 TI1 is connected to LSI + * @arg TIM_TIM16_TI1_LSE: TIM16 TI1 is connected to LSE + * @arg TIM_TIM16_TI1_RTC_WKUP: TIM16 TI1 is connected to RTCWKUP + * + * For TIM17, the parameter can have the following values: (**) + * @arg TIM_TIM17_TI1_GPIO: TIM17 TI1 is connected to GPIO + * @arg TIM_TIM17_TI1_HSE_1MHZ: TIM17 TI1 is connected to HSE_1MHZ + * @arg TIM_TIM17_TI1_MCO: TIM17 TI1 is connected to MCO + * + * (*) Value not defined in all devices. \n + * (**) Timer instance not available on all devices. \n + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_TISelection(TIM_HandleTypeDef *htim, uint32_t TISelection, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check parameters */ + assert_param(IS_TIM_TISEL_INSTANCE(htim->Instance)); + assert_param(IS_TIM_TISEL(TISelection)); + + __HAL_LOCK(htim); + + switch (Channel) + { + case TIM_CHANNEL_1: + MODIFY_REG(htim->Instance->TISEL, TIM_TISEL_TI1SEL, TISelection); + break; + case TIM_CHANNEL_2: + MODIFY_REG(htim->Instance->TISEL, TIM_TISEL_TI2SEL, TISelection); + break; + case TIM_CHANNEL_4: + MODIFY_REG(htim->Instance->TISEL, TIM_TISEL_TI4SEL, TISelection); + break; + default: + status = HAL_ERROR; + break; + } + + __HAL_UNLOCK(htim); + + return status; +} + +/** + * @brief Group channel 5 and channel 1, 2 or 3 + * @param htim TIM handle. + * @param Channels specifies the reference signal(s) the OC5REF is combined with. + * This parameter can be any combination of the following values: + * TIM_GROUPCH5_NONE: No effect of OC5REF on OC1REFC, OC2REFC and OC3REFC + * TIM_GROUPCH5_OC1REFC: OC1REFC is the logical AND of OC1REFC and OC5REF + * TIM_GROUPCH5_OC2REFC: OC2REFC is the logical AND of OC2REFC and OC5REF + * TIM_GROUPCH5_OC3REFC: OC3REFC is the logical AND of OC3REFC and OC5REF + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_GroupChannel5(TIM_HandleTypeDef *htim, uint32_t Channels) +{ + /* Check parameters */ + assert_param(IS_TIM_COMBINED3PHASEPWM_INSTANCE(htim->Instance)); + assert_param(IS_TIM_GROUPCH5(Channels)); + + /* Process Locked */ + __HAL_LOCK(htim); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Clear GC5Cx bit fields */ + htim->Instance->CCR5 &= ~(TIM_CCR5_GC5C3 | TIM_CCR5_GC5C2 | TIM_CCR5_GC5C1); + + /* Set GC5Cx bit fields */ + htim->Instance->CCR5 |= Channels; + + /* Change the htim state */ + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Disarm the designated break input (when it operates in bidirectional mode). + * @param htim TIM handle. + * @param BreakInput Break input to disarm + * This parameter can be one of the following values: + * @arg TIM_BREAKINPUT_BRK: Timer break input + * @arg TIM_BREAKINPUT_BRK2: Timer break 2 input + * @note The break input can be disarmed only when it is configured in + * bidirectional mode and when when MOE is reset. + * @note Purpose is to be able to have the input voltage back to high-state, + * whatever the time constant on the output . + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_DisarmBreakInput(TIM_HandleTypeDef *htim, uint32_t BreakInput) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpbdtr; + + /* Check the parameters */ + assert_param(IS_TIM_ADVANCED_INSTANCE(htim->Instance)); + assert_param(IS_TIM_BREAKINPUT(BreakInput)); + + switch (BreakInput) + { + case TIM_BREAKINPUT_BRK: + { + /* Check initial conditions */ + tmpbdtr = READ_REG(htim->Instance->BDTR); + if ((READ_BIT(tmpbdtr, TIM_BDTR_BKBID) == TIM_BDTR_BKBID) && + (READ_BIT(tmpbdtr, TIM_BDTR_MOE) == 0U)) + { + /* Break input BRK is disarmed */ + SET_BIT(htim->Instance->BDTR, TIM_BDTR_BKDSRM); + } + break; + } + + case TIM_BREAKINPUT_BRK2: + { + /* Check initial conditions */ + tmpbdtr = READ_REG(htim->Instance->BDTR); + if ((READ_BIT(tmpbdtr, TIM_BDTR_BK2BID) == TIM_BDTR_BK2BID) && + (READ_BIT(tmpbdtr, TIM_BDTR_MOE) == 0U)) + { + /* Break input BRK is disarmed */ + SET_BIT(htim->Instance->BDTR, TIM_BDTR_BK2DSRM); + } + break; + } + default: + status = HAL_ERROR; + break; + } + + return status; +} + +/** + * @brief Arm the designated break input (when it operates in bidirectional mode). + * @param htim TIM handle. + * @param BreakInput Break input to arm + * This parameter can be one of the following values: + * @arg TIM_BREAKINPUT_BRK: Timer break input + * @arg TIM_BREAKINPUT_BRK2: Timer break 2 input + * @note Arming is possible at anytime, even if fault is present. + * @note Break input is automatically armed as soon as MOE bit is set. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_ReArmBreakInput(const TIM_HandleTypeDef *htim, uint32_t BreakInput) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tickstart; + + /* Check the parameters */ + assert_param(IS_TIM_ADVANCED_INSTANCE(htim->Instance)); + assert_param(IS_TIM_BREAKINPUT(BreakInput)); + + switch (BreakInput) + { + case TIM_BREAKINPUT_BRK: + { + /* Check initial conditions */ + if (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BKBID) == TIM_BDTR_BKBID) + { + /* Break input BRK is re-armed automatically by hardware. Poll to check whether fault condition disappeared */ + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + while (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BKDSRM) != 0UL) + { + if ((HAL_GetTick() - tickstart) > TIM_BREAKINPUT_REARM_TIMEOUT) + { + /* New check to avoid false timeout detection in case of preemption */ + if (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BKDSRM) != 0UL) + { + return HAL_TIMEOUT; + } + } + } + } + break; + } + + case TIM_BREAKINPUT_BRK2: + { + /* Check initial conditions */ + if (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BK2BID) == TIM_BDTR_BK2BID) + { + /* Break input BRK2 is re-armed automatically by hardware. Poll to check whether fault condition disappeared */ + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + while (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BK2DSRM) != 0UL) + { + if ((HAL_GetTick() - tickstart) > TIM_BREAKINPUT_REARM_TIMEOUT) + { + /* New check to avoid false timeout detection in case of preemption */ + if (READ_BIT(htim->Instance->BDTR, TIM_BDTR_BK2DSRM) != 0UL) + { + return HAL_TIMEOUT; + } + } + } + } + break; + } + default: + status = HAL_ERROR; + break; + } + + return status; +} + +/** + * @brief Enable dithering + * @param htim TIM handle + * @note Main usage is PWM mode + * @note This function must be called when timer is stopped or disabled (CEN =0) + * @note If dithering is activated, pay attention to ARR, CCRx, CNT interpretation: + * - CNT: only CNT[11:0] holds the non-dithered part for 16b timers (or CNT[26:0] for 32b timers) + * - ARR: ARR[15:4] holds the non-dithered part, and ARR[3:0] the dither part for 16b timers + * - CCRx: CCRx[15:4] holds the non-dithered part, and CCRx[3:0] the dither part for 16b timers + * - ARR and CCRx values are limited to 0xFFEF in dithering mode for 16b timers + * (corresponds to 4094 for the integer part and 15 for the dithered part). + * @note Macros @ref __HAL_TIM_CALC_PERIOD_DITHER() __HAL_TIM_CALC_DELAY_DITHER() __HAL_TIM_CALC_PULSE_DITHER() + * can be used to calculate period (ARR) and delay (CCRx) value. + * @note Enabling dithering, modifies automatically values of registers ARR/CCRx to keep the same integer part. + * @note Enabling dithering, modifies automatically values of registers ARR/CCRx to keep the same integer part. + * So it may be necessary to read ARR value or CCRx value with macros @ref __HAL_TIM_GET_AUTORELOAD() + * __HAL_TIM_GET_COMPARE() and if necessary update Init structure field htim->Init.Period . + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_DitheringEnable(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + SET_BIT(htim->Instance->CR1, TIM_CR1_DITHEN); + return HAL_OK; +} + +/** + * @brief Disable dithering + * @param htim TIM handle + * @note This function must be called when timer is stopped or disabled (CEN =0) + * @note If dithering is activated, pay attention to ARR, CCRx, CNT interpretation: + * - CNT: only CNT[11:0] holds the non-dithered part for 16b timers (or CNT[26:0] for 32b timers) + * - ARR: ARR[15:4] holds the non-dithered part, and ARR[3:0] the dither part for 16b timers + * - CCRx: CCRx[15:4] holds the non-dithered part, and CCRx[3:0] the dither part for 16b timers + * - ARR and CCRx values are limited to 0xFFEF in dithering mode + * (corresponds to 4094 for the integer part and 15 for the dithered part). + * @note Disabling dithering, modifies automatically values of registers ARR/CCRx to keep the same integer part. + * So it may be necessary to read ARR value or CCRx value with macros @ref __HAL_TIM_GET_AUTORELOAD() + * __HAL_TIM_GET_COMPARE() and if necessary update Init structure field htim->Init.Period . + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_DitheringDisable(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + CLEAR_BIT(htim->Instance->CR1, TIM_CR1_DITHEN); + return HAL_OK; +} + +/** + * @brief Initializes the pulse on compare pulse width and pulse prescaler + * @param htim TIM Output Compare handle + * @param PulseWidthPrescaler Pulse width prescaler + * This parameter can be a number between Min_Data = 0x0 and Max_Data = 0x7 + * @param PulseWidth Pulse width + * This parameter can be a number between Min_Data = 0x00 and Max_Data = 0xFF + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OC_ConfigPulseOnCompare(TIM_HandleTypeDef *htim, + uint32_t PulseWidthPrescaler, + uint32_t PulseWidth) +{ + uint32_t tmpecr; + + /* Check the parameters */ + assert_param(IS_TIM_PULSEONCOMPARE_INSTANCE(htim->Instance)); + assert_param(IS_TIM_PULSEONCOMPARE_WIDTH(PulseWidth)); + assert_param(IS_TIM_PULSEONCOMPARE_WIDTHPRESCALER(PulseWidthPrescaler)); + + /* Process Locked */ + __HAL_LOCK(htim); + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Get the TIMx ECR register value */ + tmpecr = htim->Instance->ECR; + /* Reset the Pulse width prescaler and the Pulse width */ + tmpecr &= ~(TIM_ECR_PWPRSC | TIM_ECR_PW); + /* Set the Pulse width prescaler and Pulse width*/ + tmpecr |= PulseWidthPrescaler << TIM_ECR_PWPRSC_Pos; + tmpecr |= PulseWidth << TIM_ECR_PW_Pos; + /* Write to TIMx ECR */ + htim->Instance->ECR = tmpecr; + + /* Change the TIM state */ + htim->State = HAL_TIM_STATE_READY; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Configure preload source of Slave Mode Selection bitfield (SMS in SMCR register) + * @param htim TIM handle + * @param Source Source of slave mode selection preload + * This parameter can be one of the following values: + * @arg TIM_SMS_PRELOAD_SOURCE_UPDATE: Timer update event is used as source of Slave Mode Selection preload + * @arg TIM_SMS_PRELOAD_SOURCE_INDEX: Timer index event is used as source of Slave Mode Selection preload + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_ConfigSlaveModePreload(TIM_HandleTypeDef *htim, uint32_t Source) +{ + /* Check the parameters */ + assert_param(IS_TIM_SLAVE_INSTANCE(htim->Instance)); + assert_param(IS_TIM_SLAVE_PRELOAD_SOURCE(Source)); + + MODIFY_REG(htim->Instance->SMCR, TIM_SMCR_SMSPS, Source); + return HAL_OK; +} + +/** + * @brief Enable preload of Slave Mode Selection bitfield (SMS in SMCR register) + * @param htim TIM handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_EnableSlaveModePreload(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_SLAVE_INSTANCE(htim->Instance)); + + SET_BIT(htim->Instance->SMCR, TIM_SMCR_SMSPE); + return HAL_OK; +} + +/** + * @brief Disable preload of Slave Mode Selection bitfield (SMS in SMCR register) + * @param htim TIM handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_DisableSlaveModePreload(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_SLAVE_INSTANCE(htim->Instance)); + + CLEAR_BIT(htim->Instance->SMCR, TIM_SMCR_SMSPE); + return HAL_OK; +} + +/** + * @brief Enable deadtime preload + * @param htim TIM handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_EnableDeadTimePreload(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_BREAK_INSTANCE(htim->Instance)); + + SET_BIT(htim->Instance->DTR2, TIM_DTR2_DTPE); + return HAL_OK; +} + +/** + * @brief Disable deadtime preload + * @param htim TIM handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_DisableDeadTimePreload(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_BREAK_INSTANCE(htim->Instance)); + + CLEAR_BIT(htim->Instance->DTR2, TIM_DTR2_DTPE); + return HAL_OK; +} + +/** + * @brief Configure deadtime + * @param htim TIM handle + * @param Deadtime Deadtime value + * @note This parameter can be a number between Min_Data = 0x00 and Max_Data = 0xFF + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_ConfigDeadTime(TIM_HandleTypeDef *htim, uint32_t Deadtime) +{ + /* Check the parameters */ + assert_param(IS_TIM_BREAK_INSTANCE(htim->Instance)); + assert_param(IS_TIM_DEADTIME(Deadtime)); + + MODIFY_REG(htim->Instance->BDTR, TIM_BDTR_DTG, Deadtime); + return HAL_OK; +} + +/** + * @brief Configure asymmetrical deadtime + * @param htim TIM handle + * @param FallingDeadtime Falling edge deadtime value + * @note This parameter can be a number between Min_Data = 0x00 and Max_Data = 0xFF + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_ConfigAsymmetricalDeadTime(TIM_HandleTypeDef *htim, uint32_t FallingDeadtime) +{ + /* Check the parameters */ + assert_param(IS_TIM_BREAK_INSTANCE(htim->Instance)); + assert_param(IS_TIM_DEADTIME(FallingDeadtime)); + + MODIFY_REG(htim->Instance->DTR2, TIM_DTR2_DTGF, FallingDeadtime); + return HAL_OK; +} + +/** + * @brief Enable asymmetrical deadtime + * @param htim TIM handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_EnableAsymmetricalDeadTime(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_BREAK_INSTANCE(htim->Instance)); + + SET_BIT(htim->Instance->DTR2, TIM_DTR2_DTAE); + return HAL_OK; +} + +/** + * @brief Disable asymmetrical deadtime + * @param htim TIM handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_DisableAsymmetricalDeadTime(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_BREAK_INSTANCE(htim->Instance)); + + CLEAR_BIT(htim->Instance->DTR2, TIM_DTR2_DTAE); + return HAL_OK; +} + +/** + * @brief Configures the encoder index. + * @note warning in case of encoder mode clock plus direction + * @ref TIM_ENCODERMODE_CLOCKPLUSDIRECTION_X1 or @ref TIM_ENCODERMODE_CLOCKPLUSDIRECTION_X2 + * Direction must be set to @ref TIM_ENCODERINDEX_DIRECTION_UP_DOWN + * @param htim TIM handle. + * @param sEncoderIndexConfig Encoder index configuration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_ConfigEncoderIndex(TIM_HandleTypeDef *htim, + TIMEx_EncoderIndexConfigTypeDef *sEncoderIndexConfig) +{ + /* Check the parameters */ + assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(htim->Instance)); + assert_param(IS_TIM_ENCODERINDEX_POLARITY(sEncoderIndexConfig->Polarity)); + assert_param(IS_TIM_ENCODERINDEX_PRESCALER(sEncoderIndexConfig->Prescaler)); + assert_param(IS_TIM_ENCODERINDEX_FILTER(sEncoderIndexConfig->Filter)); + assert_param(IS_TIM_ENCODERINDEX_BLANKING(sEncoderIndexConfig->Blanking)); + assert_param(IS_FUNCTIONAL_STATE(sEncoderIndexConfig->FirstIndexEnable)); + assert_param(IS_TIM_ENCODERINDEX_POSITION(sEncoderIndexConfig->Position)); + assert_param(IS_TIM_ENCODERINDEX_DIRECTION(sEncoderIndexConfig->Direction)); + + /* Process Locked */ + __HAL_LOCK(htim); + + /* Configures the TIMx External Trigger (ETR) which is used as Index input */ + TIM_ETR_SetConfig(htim->Instance, + sEncoderIndexConfig->Prescaler, + sEncoderIndexConfig->Polarity, + sEncoderIndexConfig->Filter); + + /* Configures the encoder index */ + MODIFY_REG(htim->Instance->ECR, + TIM_ECR_IDIR_Msk | TIM_ECR_IBLK_Msk | TIM_ECR_FIDX_Msk | TIM_ECR_IPOS_Msk, + (sEncoderIndexConfig->Direction | + (sEncoderIndexConfig->Blanking) | + ((sEncoderIndexConfig->FirstIndexEnable == ENABLE) ? (0x1U << TIM_ECR_FIDX_Pos) : 0U) | + sEncoderIndexConfig->Position | + TIM_ECR_IE)); + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Enable encoder index + * @param htim TIM handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_EnableEncoderIndex(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(htim->Instance)); + + SET_BIT(htim->Instance->ECR, TIM_ECR_IE); + return HAL_OK; +} + +/** + * @brief Disable encoder index + * @param htim TIM handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_DisableEncoderIndex(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(htim->Instance)); + + CLEAR_BIT(htim->Instance->ECR, TIM_ECR_IE); + return HAL_OK; +} + +/** + * @brief Enable encoder first index + * @param htim TIM handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_EnableEncoderFirstIndex(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(htim->Instance)); + + SET_BIT(htim->Instance->ECR, TIM_ECR_FIDX); + return HAL_OK; +} + +/** + * @brief Disable encoder first index + * @param htim TIM handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_DisableEncoderFirstIndex(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(htim->Instance)); + + CLEAR_BIT(htim->Instance->ECR, TIM_ECR_FIDX); + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup TIMEx_Exported_Functions_Group6 Extended Callbacks functions + * @brief Extended Callbacks functions + * +@verbatim + ============================================================================== + ##### Extended Callbacks functions ##### + ============================================================================== + [..] + This section provides Extended TIM callback functions: + (+) Timer Commutation callback + (+) Timer Break callback + +@endverbatim + * @{ + */ + +/** + * @brief Hall commutation changed callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIMEx_CommutCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIMEx_CommutCallback could be implemented in the user file + */ +} +/** + * @brief Hall commutation changed half complete callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIMEx_CommutHalfCpltCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIMEx_CommutHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Hall Break detection callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIMEx_BreakCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIMEx_BreakCallback could be implemented in the user file + */ +} + +/** + * @brief Hall Break2 detection callback in non blocking mode + * @param htim: TIM handle + * @retval None + */ +__weak void HAL_TIMEx_Break2Callback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_TIMEx_Break2Callback could be implemented in the user file + */ +} + +/** + * @brief Encoder index callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIMEx_EncoderIndexCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIMEx_EncoderIndexCallback could be implemented in the user file + */ +} + +/** + * @brief Direction change callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIMEx_DirectionChangeCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIMEx_DirectionChangeCallback could be implemented in the user file + */ +} + +/** + * @brief Index error callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIMEx_IndexErrorCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIMEx_IndexErrorCallback could be implemented in the user file + */ +} + +/** + * @brief Transition error callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIMEx_TransitionErrorCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIMEx_TransitionErrorCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup TIMEx_Exported_Functions_Group7 Extended Peripheral State functions + * @brief Extended Peripheral State functions + * +@verbatim + ============================================================================== + ##### Extended Peripheral State functions ##### + ============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the TIM Hall Sensor interface handle state. + * @param htim TIM Hall Sensor handle + * @retval HAL state + */ +HAL_TIM_StateTypeDef HAL_TIMEx_HallSensor_GetState(const TIM_HandleTypeDef *htim) +{ + return htim->State; +} + +/** + * @brief Return actual state of the TIM complementary channel. + * @param htim TIM handle + * @param ChannelN TIM Complementary channel + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 + * @arg TIM_CHANNEL_2: TIM Channel 2 + * @arg TIM_CHANNEL_3: TIM Channel 3 + * @arg TIM_CHANNEL_4: TIM Channel 4 + * @retval TIM Complementary channel state + */ +HAL_TIM_ChannelStateTypeDef HAL_TIMEx_GetChannelNState(const TIM_HandleTypeDef *htim, uint32_t ChannelN) +{ + HAL_TIM_ChannelStateTypeDef channel_state; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, ChannelN)); + + channel_state = TIM_CHANNEL_N_STATE_GET(htim, ChannelN); + + return channel_state; +} +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup TIMEx_Private_Functions TIM Extended Private Functions + * @{ + */ + +/** + * @brief TIM DMA Commutation callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +void TIMEx_DMACommutationCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Change the htim state */ + htim->State = HAL_TIM_STATE_READY; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->CommutationCallback(htim); +#else + HAL_TIMEx_CommutCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ +} + +/** + * @brief TIM DMA Commutation half complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +void TIMEx_DMACommutationHalfCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Change the htim state */ + htim->State = HAL_TIM_STATE_READY; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->CommutationHalfCpltCallback(htim); +#else + HAL_TIMEx_CommutHalfCpltCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ +} + + +/** + * @brief TIM DMA Delay Pulse complete callback (complementary channel). + * @param hdma pointer to DMA handle. + * @retval None + */ +static void TIM_DMADelayPulseNCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + if (hdma == htim->hdma[TIM_DMA_ID_CC1]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1; + + if (hdma->Init.Mode == DMA_NORMAL) + { + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + } + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC2]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2; + + if (hdma->Init.Mode == DMA_NORMAL) + { + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + } + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC3]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3; + + if (hdma->Init.Mode == DMA_NORMAL) + { + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_3, HAL_TIM_CHANNEL_STATE_READY); + } + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC4]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4; + + if (hdma->Init.Mode == DMA_NORMAL) + { + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_4, HAL_TIM_CHANNEL_STATE_READY); + } + } + else + { + /* nothing to do */ + } + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->PWM_PulseFinishedCallback(htim); +#else + HAL_TIM_PWM_PulseFinishedCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; +} + +/** + * @brief TIM DMA error callback (complementary channel) + * @param hdma pointer to DMA handle. + * @retval None + */ +static void TIM_DMAErrorCCxN(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + if (hdma == htim->hdma[TIM_DMA_ID_CC1]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1; + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC2]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2; + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC3]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3; + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_3, HAL_TIM_CHANNEL_STATE_READY); + } + else + { + /* nothing to do */ + } + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->ErrorCallback(htim); +#else + HAL_TIM_ErrorCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; +} + +/** + * @brief Enables or disables the TIM Capture Compare Channel xN. + * @param TIMx to select the TIM peripheral + * @param Channel specifies the TIM Channel + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 + * @arg TIM_CHANNEL_2: TIM Channel 2 + * @arg TIM_CHANNEL_3: TIM Channel 3 + * @arg TIM_CHANNEL_4: TIM Channel 4 + * @param ChannelNState specifies the TIM Channel CCxNE bit new state. + * This parameter can be: TIM_CCxN_ENABLE or TIM_CCxN_Disable. + * @retval None + */ +static void TIM_CCxNChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelNState) +{ + uint32_t tmp; + + tmp = TIM_CCER_CC1NE << (Channel & 0x1FU); /* 0x1FU = 31 bits max shift */ + + /* Reset the CCxNE Bit */ + TIMx->CCER &= ~tmp; + + /* Set or reset the CCxNE Bit */ + TIMx->CCER |= (uint32_t)(ChannelNState << (Channel & 0x1FU)); /* 0x1FU = 31 bits max shift */ +} +/** + * @} + */ + +#endif /* HAL_TIM_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_timebase_rtc_alarm_template.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_timebase_rtc_alarm_template.c new file mode 100644 index 0000000000..c43f53995e --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_timebase_rtc_alarm_template.c @@ -0,0 +1,284 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_timebase_rtc_alarm_template.c + * @author MCD Application Team + * @brief HAL time base based on the hardware RTC_ALARM Template. + * + * This file overrides the native HAL time base functions (defined as weak) + * to use the RTC ALARM for time base generation: + * + Initializes the RTC peripheral to increment the seconds registers each 1ms + * + The alarm is configured to assert an interrupt when the RTC reaches 1ms + * + HAL_IncTick is called at each Alarm event + * + HSE (default), LSE or LSI can be selected as RTC clock source + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + This file must be copied to the application folder and modified as follows: + (#) Rename it to 'stm32h5xx_hal_timebase_rtc_alarm.c' + (#) Add this file and the RTC HAL drivers to your project and uncomment + HAL_RTC_MODULE_ENABLED define in stm32h5xx_hal_conf.h + + [..] + (@) HAL RTC alarm and HAL RTC wakeup drivers can not be used with low power modes: + The wake up capability of the RTC may be intrusive in case of prior low power mode + configuration requiring different wake up sources. + Application/Example behavior is no more guaranteed + (@) The stm32h5xx_hal_timebase_tim use is recommended for the Applications/Examples + requiring low power modes + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup HAL_TimeBase_RTC_Alarm_Template HAL TimeBase RTC Alarm Template + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/* Uncomment the line below to select the appropriate RTC Clock source for your application: + + RTC_CLOCK_SOURCE_HSE: can be selected for applications requiring timing precision. + + RTC_CLOCK_SOURCE_LSE: can be selected for applications with low constraint on timing + precision. + + RTC_CLOCK_SOURCE_LSI: can be selected for applications with low constraint on timing + precision. + */ +/* #define RTC_CLOCK_SOURCE_HSE */ +/* #define RTC_CLOCK_SOURCE_LSE */ +#define RTC_CLOCK_SOURCE_LSI + +/* The time base should be 1ms + Time base = ((RTC_ASYNCH_PREDIV + 1) * (RTC_SYNCH_PREDIV + 1)) / RTC_CLOCK + HSE as RTC clock + Time base = ((99 + 1) * (9 + 1)) / 1MHz + = 1ms + LSE as RTC clock + Time base = ((32 + 1) * (0 + 1)) / 32.768KHz + = ~1ms + LSI as RTC clock + Time base = ((31 + 1) * (0 + 1)) / 32KHz + = 1ms +*/ +#if defined (RTC_CLOCK_SOURCE_HSE) +#define RTC_ASYNCH_PREDIV 99U +#define RTC_SYNCH_PREDIV 9U +#elif defined (RTC_CLOCK_SOURCE_LSE) +#define RTC_ASYNCH_PREDIV 0U +#define RTC_SYNCH_PREDIV 32U +#elif defined (RTC_CLOCK_SOURCE_LSI) +#define RTC_ASYNCH_PREDIV 0U +#define RTC_SYNCH_PREDIV 31U +#else +#error Please select the RTC Clock source +#endif /* RTC_CLOCK_SOURCE_LSE */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +static RTC_HandleTypeDef hRTC_Handle; + +/* Private function prototypes -----------------------------------------------*/ +void RTC_IRQHandler(void); +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1U) +void TimeBase_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief This function configures the RTC_ALARMA as a time base source. + * The time source is configured to have 1ms time base with a dedicated + * Tick interrupt priority. + * @note This function is called automatically at the beginning of program after + * reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig(). + * @param TickPriority Tick interrupt priority. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) +{ + HAL_StatusTypeDef status; + + RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; + + /* Disable bkup domain protection */ + HAL_PWR_EnableBkUpAccess(); + + /* Force and Release the Backup domain reset */ + __HAL_RCC_BACKUPRESET_FORCE(); + __HAL_RCC_BACKUPRESET_RELEASE(); + + /* Enable RTC Clock */ + __HAL_RCC_RTC_ENABLE(); + __HAL_RCC_RTC_CLK_ENABLE(); + +#if defined (RTC_CLOCK_SOURCE_LSE) + /* Configure LSE as RTC clock source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + RCC_OscInitStruct.LSEState = RCC_LSE_ON; + PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; +#elif defined (RTC_CLOCK_SOURCE_LSI) + /* Configure LSI as RTC clock source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + RCC_OscInitStruct.LSIState = RCC_LSI_ON; + PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI; +#elif defined (RTC_CLOCK_SOURCE_HSE) + /* Configure HSE as RTC clock source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_HSE_DIV32; +#else +#error Please select the RTC Clock source +#endif /* RTC_CLOCK_SOURCE_LSE */ + + status = HAL_RCC_OscConfig(&RCC_OscInitStruct); + + if (status == HAL_OK) + { + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC; + status = HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + } + + if (status == HAL_OK) + { + hRTC_Handle.Instance = RTC; + hRTC_Handle.Init.HourFormat = RTC_HOURFORMAT_24; + hRTC_Handle.Init.AsynchPrediv = RTC_ASYNCH_PREDIV; + hRTC_Handle.Init.SynchPrediv = RTC_SYNCH_PREDIV; + hRTC_Handle.Init.OutPut = RTC_OUTPUT_DISABLE; + hRTC_Handle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; + hRTC_Handle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; + hRTC_Handle.Init.BinMode = RTC_BINARY_NONE; + + status = HAL_RTC_Init(&hRTC_Handle); + +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1U) + HAL_RTC_RegisterCallback(&hRTC_Handle, HAL_RTC_ALARM_A_EVENT_CB_ID, TimeBase_RTC_AlarmAEventCallback); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + } + + if (status == HAL_OK) + { + /* RTC variables */ + RTC_AlarmTypeDef RTC_AlarmStructure; + + /* RTC Alarm Generation */ + RTC_AlarmStructure.Alarm = RTC_ALARM_A; + RTC_AlarmStructure.AlarmDateWeekDay = RTC_WEEKDAY_MONDAY; + RTC_AlarmStructure.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE; + /* Mask all and keep only subsecond, to have one match in each time base 1ms(uwTickFreq) */ + RTC_AlarmStructure.AlarmMask = RTC_ALARMMASK_ALL; + RTC_AlarmStructure.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_NONE; + RTC_AlarmStructure.AlarmTime.TimeFormat = RTC_HOURFORMAT_24; + RTC_AlarmStructure.AlarmTime.Hours = 0; + RTC_AlarmStructure.AlarmTime.Minutes = 0; + RTC_AlarmStructure.AlarmTime.Seconds = 0; + RTC_AlarmStructure.AlarmTime.SubSeconds = 0; + + /* Set the specified RTC Alarm with Interrupt */ + status = HAL_RTC_SetAlarm_IT(&hRTC_Handle, &RTC_AlarmStructure, RTC_FORMAT_BCD); + } + + if (TickPriority < (1UL << __NVIC_PRIO_BITS)) + { + /* Enable the RTC global Interrupt */ + HAL_NVIC_SetPriority(RTC_IRQn, TickPriority, 0); + uwTickPrio = TickPriority; + } + else + { + status = HAL_ERROR; + } + + HAL_NVIC_EnableIRQ(RTC_IRQn); + + return status; +} + +/** + * @brief Suspend Tick increment. + * @note Disable the tick increment by disabling RTC ALARM interrupt. + * @retval None + */ +void HAL_SuspendTick(void) +{ + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(&hRTC_Handle); + /* Disable RTC ALARM update Interrupt */ + __HAL_RTC_ALARM_DISABLE_IT(&hRTC_Handle, RTC_IT_ALRA); + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(&hRTC_Handle); +} + +/** + * @brief Resume Tick increment. + * @note Enable the tick increment by Enabling RTC ALARM interrupt. + * @retval None + */ +void HAL_ResumeTick(void) +{ + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(&hRTC_Handle); + /* Enable RTC ALARM Update interrupt */ + __HAL_RTC_ALARM_ENABLE_IT(&hRTC_Handle, RTC_IT_ALRA); + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(&hRTC_Handle); +} + +/** + * @brief ALARM A Event Callback in non blocking mode + * @note This function is called when RTC_ALARM interrupt took place, inside + * RTC_ALARM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment + * a global variable "uwTick" used as application time base. + * @param hrtc RTC handle + * @retval None + */ +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1U) +void TimeBase_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) +#else +void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + HAL_IncTick(); +} + +/** + * @brief This function handles RTC ALARM interrupt request. + * @retval None + */ +void RTC_IRQHandler(void) +{ + HAL_RTC_AlarmIRQHandler(&hRTC_Handle); +} + +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_timebase_rtc_wakeup_template.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_timebase_rtc_wakeup_template.c new file mode 100644 index 0000000000..29ee942239 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_timebase_rtc_wakeup_template.c @@ -0,0 +1,268 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_timebase_rtc_wakeup_template.c + * @author MCD Application Team + * @brief HAL time base based on the hardware RTC_WAKEUP Template. + * + * This file overrides the native HAL time base functions (defined as weak) + * to use the RTC WAKEUP for the time base generation: + * + Initializes the RTC peripheral and configures the wakeup timer to be + * incremented each 1ms + * + The wakeup feature is configured to assert an interrupt each 1ms + * + HAL_IncTick is called inside the HAL_RTCEx_WakeUpTimerEventCallback + * + HSE (default), LSE or LSI can be selected as RTC clock source + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + This file must be copied to the application folder and modified as follows: + (#) Rename it to 'stm32h5xx_hal_timebase_rtc_wakeup.c' + (#) Add this file and the RTC HAL drivers to your project and uncomment + HAL_RTC_MODULE_ENABLED define in stm32h5xx_hal_conf.h + + [..] + (@) HAL RTC alarm and HAL RTC wakeup drivers can not be used with low power modes: + The wake up capability of the RTC may be intrusive in case of prior low power mode + configuration requiring different wake up sources. + Application/Example behavior is no more guaranteed + (@) The stm32h5xx_hal_timebase_tim use is recommended for the Applications/Examples + requiring low power modes + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup HAL_TimeBase_RTC_Alarm_Template HAL TimeBase RTC Alarm Template + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/* Uncomment the line below to select the appropriate RTC Clock source for your application: + + RTC_CLOCK_SOURCE_HSE: can be selected for applications requiring timing precision. + + RTC_CLOCK_SOURCE_LSE: can be selected for applications with low constraint on timing + precision. + + RTC_CLOCK_SOURCE_LSI: can be selected for applications with low constraint on timing + precision. + */ +/* #define RTC_CLOCK_SOURCE_HSE */ +/* #define RTC_CLOCK_SOURCE_LSE */ +#define RTC_CLOCK_SOURCE_LSI + +/* The time base should be 1ms + Time base = ((RTC_ASYNCH_PREDIV + 1) * (RTC_SYNCH_PREDIV + 1)) / RTC_CLOCK + HSE as RTC clock + Time base = ((99 + 1) * (9 + 1)) / 1MHz + = 1ms + LSE as RTC clock + Time base = ((32 + 1) * (0 + 1)) / 32.768KHz + = ~1ms + LSI as RTC clock + Time base = ((31 + 1) * (0 + 1)) / 32KHz + = 1ms +*/ +#if defined (RTC_CLOCK_SOURCE_HSE) +#define RTC_ASYNCH_PREDIV 99U +#define RTC_SYNCH_PREDIV 9U +#elif defined (RTC_CLOCK_SOURCE_LSE) +#define RTC_ASYNCH_PREDIV 0U +#define RTC_SYNCH_PREDIV 32U +#elif defined (RTC_CLOCK_SOURCE_LSI) +#define RTC_ASYNCH_PREDIV 0U +#define RTC_SYNCH_PREDIV 31U +#else +#error Please select the RTC Clock source +#endif /* RTC_CLOCK_SOURCE_LSE */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +static RTC_HandleTypeDef hRTC_Handle; + +/* Private function prototypes -----------------------------------------------*/ +void RTC_IRQHandler(void); +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1U) +void TimeBase_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief This function configures the RTC_ALARMA as a time base source. + * The time source is configured to have 1ms time base with a dedicated + * Tick interrupt priority. + * @note This function is called automatically at the beginning of program after + * reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig(). + * @param TickPriority Tick interrupt priority. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) +{ + HAL_StatusTypeDef status; + + RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; + + /* Disable bkup domain protection */ + HAL_PWR_EnableBkUpAccess(); + + /* Force and Release the Backup domain reset */ + __HAL_RCC_BACKUPRESET_FORCE(); + __HAL_RCC_BACKUPRESET_RELEASE(); + + /* Enable RTC Clock */ + __HAL_RCC_RTC_ENABLE(); + __HAL_RCC_RTC_CLK_ENABLE(); + +#if defined (RTC_CLOCK_SOURCE_LSE) + /* Configure LSE as RTC clock source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + RCC_OscInitStruct.LSEState = RCC_LSE_ON; + PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; +#elif defined (RTC_CLOCK_SOURCE_LSI) + /* Configure LSI as RTC clock source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + RCC_OscInitStruct.LSIState = RCC_LSI_ON; + PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI; +#elif defined (RTC_CLOCK_SOURCE_HSE) + /* Configure HSE as RTC clock source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_HSE_DIV32; +#else +#error Please select the RTC Clock source +#endif /* RTC_CLOCK_SOURCE_LSE */ + + status = HAL_RCC_OscConfig(&RCC_OscInitStruct); + + if (status == HAL_OK) + { + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC; + status = HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + } + + if (status == HAL_OK) + { + hRTC_Handle.Instance = RTC; + hRTC_Handle.Init.HourFormat = RTC_HOURFORMAT_24; + hRTC_Handle.Init.AsynchPrediv = RTC_ASYNCH_PREDIV; + hRTC_Handle.Init.SynchPrediv = RTC_SYNCH_PREDIV; + hRTC_Handle.Init.OutPut = RTC_OUTPUT_DISABLE; + hRTC_Handle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; + hRTC_Handle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; + hRTC_Handle.Init.BinMode = RTC_BINARY_NONE; + + status = HAL_RTC_Init(&hRTC_Handle); + +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1U) + HAL_RTC_RegisterCallback(&hRTC_Handle, HAL_RTC_WAKEUPTIMER_EVENT_CB_ID, TimeBase_RTCEx_WakeUpTimerEventCallback); +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ + } + + if (status == HAL_OK) + { + status = HAL_RTCEx_SetWakeUpTimer_IT(&hRTC_Handle, 0, RTC_WAKEUPCLOCK_CK_SPRE_16BITS, 0); + } + + if (TickPriority < (1UL << __NVIC_PRIO_BITS)) + { + /* Enable the RTC global Interrupt */ + HAL_NVIC_SetPriority(RTC_IRQn, TickPriority, 0U); + uwTickPrio = TickPriority; + } + else + { + status = HAL_ERROR; + } + + HAL_NVIC_EnableIRQ(RTC_IRQn); + + return status; +} + +/** + * @brief Suspend Tick increment. + * @note Disable the tick increment by disabling RTC_WKUP interrupt. + * @retval None + */ +void HAL_SuspendTick(void) +{ + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(&hRTC_Handle); + /* Disable WAKE UP TIMER Interrupt */ + __HAL_RTC_WAKEUPTIMER_DISABLE_IT(&hRTC_Handle, RTC_IT_WUT); + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(&hRTC_Handle); +} + +/** + * @brief Resume Tick increment. + * @note Enable the tick increment by Enabling RTC_WKUP interrupt. + * @retval None + */ +void HAL_ResumeTick(void) +{ + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(&hRTC_Handle); + /* Enable WAKE UP TIMER interrupt */ + __HAL_RTC_WAKEUPTIMER_ENABLE_IT(&hRTC_Handle, RTC_IT_WUT); + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(&hRTC_Handle); +} + +/** + * @brief Wake Up Timer Event Callback in non blocking mode + * @note This function is called when RTC_WKUP interrupt took place, inside + * RTC_WKUP_IRQHandler(). It makes a direct call to HAL_IncTick() to increment + * a global variable "uwTick" used as application time base. + * @param hrtc RTC handle + * @retval None + */ +#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1U) +void TimeBase_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc) +#else +void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc) +#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hrtc); + + HAL_IncTick(); +} + +/** + * @brief This function handles WAKE UP TIMER interrupt request. + * @retval None + */ +void RTC_IRQHandler(void) +{ + HAL_RTCEx_WakeUpTimerIRQHandler(&hRTC_Handle); +} + +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_timebase_tim_template.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_timebase_tim_template.c new file mode 100644 index 0000000000..a5ca9c5047 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_timebase_tim_template.c @@ -0,0 +1,203 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_timebase_tim_template.c + * @author MCD Application Team + * @brief HAL time base based on the hardware TIM. + * + * This file overrides the native HAL time base functions (defined as weak) + * the TIM time base: + * + Initializes the TIM peripheral to generate a Period elapsed Event each 1ms + * + HAL_IncTick is called inside HAL_TIM_PeriodElapsedCallback ie each 1ms + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + This file must be copied to the application folder and modified as follows: + (#) Rename it to 'stm32h5xx_hal_timebase_tim.c' + (#) Add this file and the TIM HAL drivers to your project and uncomment + HAL_TIM_MODULE_ENABLED define in stm32h5xx_hal_conf.h + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @addtogroup HAL_TimeBase + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +static TIM_HandleTypeDef TimHandle; + +/* Private function prototypes -----------------------------------------------*/ +void TIM6_IRQHandler(void); +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1U) +void TimeBase_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief This function configures the TIM6 as a time base source. + * The time source is configured to have 1ms time base with a dedicated + * Tick interrupt priority. + * @note This function is called automatically at the beginning of program after + * reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig(). + * @param TickPriority Tick interrupt priority. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) +{ + RCC_ClkInitTypeDef clkconfig; + uint32_t uwTimclock; + uint32_t uwAPB1Prescaler; + uint32_t uwPrescalerValue; + uint32_t pFLatency; + HAL_StatusTypeDef status; + + /* Enable TIM6 clock */ + __HAL_RCC_TIM6_CLK_ENABLE(); + + /* Get clock configuration */ + HAL_RCC_GetClockConfig(&clkconfig, &pFLatency); + + /* Get APB1 prescaler */ + uwAPB1Prescaler = clkconfig.APB1CLKDivider; + + /* Compute TIM6 clock */ + if (uwAPB1Prescaler == RCC_HCLK_DIV1) + { + uwTimclock = HAL_RCC_GetPCLK1Freq(); + } + else + { + uwTimclock = 2UL * HAL_RCC_GetPCLK1Freq(); + } + + /* Compute the prescaler value to have TIM6 counter clock equal to 100KHz */ + uwPrescalerValue = (uint32_t)((uwTimclock / 100000U) - 1U); + + /* Initialize TIM6 */ + TimHandle.Instance = TIM6; + + /* Initialize TIMx peripheral as follow: + + Period = [(TIM6CLK/1000) - 1]. to have a (1/1000) s time base. + + Prescaler = (uwTimclock/100000 - 1) to have a 100KHz counter clock. + + ClockDivision = 0 + + Counter direction = Up + */ + TimHandle.Init.Period = (100000U / 1000U) - 1U; + TimHandle.Init.Prescaler = uwPrescalerValue; + TimHandle.Init.ClockDivision = 0; + TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; + status = HAL_TIM_Base_Init(&TimHandle); + if (status == HAL_OK) + { + /* Start the TIM time Base generation in interrupt mode */ + status = HAL_TIM_Base_Start_IT(&TimHandle); + if (status == HAL_OK) + { + if (TickPriority < (1UL << __NVIC_PRIO_BITS)) + { + /* Enable the TIM6 global Interrupt */ + HAL_NVIC_SetPriority(TIM6_IRQn, TickPriority, 0); + uwTickPrio = TickPriority; + } + else + { + status = HAL_ERROR; + } + } + } +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1U) + HAL_TIM_RegisterCallback(&TimHandle, HAL_TIM_PERIOD_ELAPSED_CB_ID, TimeBase_TIM_PeriodElapsedCallback); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + HAL_NVIC_EnableIRQ(TIM6_IRQn); + + /* Return function status */ + return status; +} + +/** + * @brief Suspend Tick increment. + * @note Disable the tick increment by disabling TIM6 update interrupt. + * @param None + * @retval None + */ +void HAL_SuspendTick(void) +{ + /* Disable TIM6 update Interrupt */ + __HAL_TIM_DISABLE_IT(&TimHandle, TIM_IT_UPDATE); +} + +/** + * @brief Resume Tick increment. + * @note Enable the tick increment by Enabling TIM6 update interrupt. + * @param None + * @retval None + */ +void HAL_ResumeTick(void) +{ + /* Enable TIM6 Update interrupt */ + __HAL_TIM_ENABLE_IT(&TimHandle, TIM_IT_UPDATE); +} + +/** + * @brief Period elapsed callback in non blocking mode + * @note This function is called when TIM6 interrupt took place, inside + * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment + * a global variable "uwTick" used as application time base. + * @param htim TIM handle + * @retval None + */ +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1U) +void TimeBase_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) +#else +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + HAL_IncTick(); +} + +/** + * @brief This function handles TIM interrupt request. + * @param None + * @retval None + */ +void TIM6_IRQHandler(void) +{ + HAL_TIM_IRQHandler(&TimHandle); +} + +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_uart.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_uart.c new file mode 100644 index 0000000000..e88ada5e64 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_uart.c @@ -0,0 +1,4764 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_uart.c + * @author MCD Application Team + * @brief UART HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (UART). + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + =============================================================================== + ##### How to use this driver ##### + =============================================================================== + [..] + The UART HAL driver can be used as follows: + + (#) Declare a UART_HandleTypeDef handle structure (eg. UART_HandleTypeDef huart). + (#) Initialize the UART low level resources by implementing the HAL_UART_MspInit() API: + (++) Enable the USARTx interface clock. + (++) UART pins configuration: + (+++) Enable the clock for the UART GPIOs. + (+++) Configure these UART pins as alternate function pull-up. + (++) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT() + and HAL_UART_Receive_IT() APIs): + (+++) Configure the USARTx interrupt priority. + (+++) Enable the NVIC USART IRQ handle. + (++) UART interrupts handling: + -@@- The specific UART interrupts (Transmission complete interrupt, + RXNE interrupt, RX/TX FIFOs related interrupts and Error Interrupts) + are managed using the macros __HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT() + inside the transmit and receive processes. + (++) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA() + and HAL_UART_Receive_DMA() APIs): + (+++) Declare a DMA handle structure for the Tx/Rx channel. + (+++) Enable the DMAx interface clock. + (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. + (+++) Configure the DMA Tx/Rx channel. + (+++) Associate the initialized DMA handle to the UART DMA Tx/Rx handle. + (+++) Configure the priority and enable the NVIC for the transfer complete + interrupt on the DMA Tx/Rx channel. + + (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Prescaler value , Hardware + flow control and Mode (Receiver/Transmitter) in the huart handle Init structure. + + (#) If required, program UART advanced features (TX/RX pins swap, auto Baud rate detection,...) + in the huart handle AdvancedInit structure. + + (#) For the UART asynchronous mode, initialize the UART registers by calling + the HAL_UART_Init() API. + + (#) For the UART Half duplex mode, initialize the UART registers by calling + the HAL_HalfDuplex_Init() API. + + (#) For the UART LIN (Local Interconnection Network) mode, initialize the UART registers + by calling the HAL_LIN_Init() API. + + (#) For the UART Multiprocessor mode, initialize the UART registers + by calling the HAL_MultiProcessor_Init() API. + + (#) For the UART RS485 Driver Enabled mode, initialize the UART registers + by calling the HAL_RS485Ex_Init() API. + + [..] + (@) These API's (HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init(), HAL_MultiProcessor_Init(), + also configure the low level Hardware GPIO, CLOCK, CORTEX...etc) by + calling the customized HAL_UART_MspInit() API. + + ##### Callback registration ##### + ================================== + + [..] + The compilation define USE_HAL_UART_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + + [..] + Use Function HAL_UART_RegisterCallback() to register a user callback. + Function HAL_UART_RegisterCallback() allows to register following callbacks: + (+) TxHalfCpltCallback : Tx Half Complete Callback. + (+) TxCpltCallback : Tx Complete Callback. + (+) RxHalfCpltCallback : Rx Half Complete Callback. + (+) RxCpltCallback : Rx Complete Callback. + (+) ErrorCallback : Error Callback. + (+) AbortCpltCallback : Abort Complete Callback. + (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback. + (+) AbortReceiveCpltCallback : Abort Receive Complete Callback. + (+) WakeupCallback : Wakeup Callback. + (+) RxFifoFullCallback : Rx Fifo Full Callback. + (+) TxFifoEmptyCallback : Tx Fifo Empty Callback. + (+) MspInitCallback : UART MspInit. + (+) MspDeInitCallback : UART MspDeInit. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + + [..] + Use function HAL_UART_UnRegisterCallback() to reset a callback to the default + weak function. + HAL_UART_UnRegisterCallback() takes as parameters the HAL peripheral handle, + and the Callback ID. + This function allows to reset following callbacks: + (+) TxHalfCpltCallback : Tx Half Complete Callback. + (+) TxCpltCallback : Tx Complete Callback. + (+) RxHalfCpltCallback : Rx Half Complete Callback. + (+) RxCpltCallback : Rx Complete Callback. + (+) ErrorCallback : Error Callback. + (+) AbortCpltCallback : Abort Complete Callback. + (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback. + (+) AbortReceiveCpltCallback : Abort Receive Complete Callback. + (+) WakeupCallback : Wakeup Callback. + (+) RxFifoFullCallback : Rx Fifo Full Callback. + (+) TxFifoEmptyCallback : Tx Fifo Empty Callback. + (+) MspInitCallback : UART MspInit. + (+) MspDeInitCallback : UART MspDeInit. + + [..] + For specific callback RxEventCallback, use dedicated registration/reset functions: + respectively HAL_UART_RegisterRxEventCallback() , HAL_UART_UnRegisterRxEventCallback(). + + [..] + By default, after the HAL_UART_Init() and when the state is HAL_UART_STATE_RESET + all callbacks are set to the corresponding weak functions: + examples HAL_UART_TxCpltCallback(), HAL_UART_RxHalfCpltCallback(). + Exception done for MspInit and MspDeInit functions that are respectively + reset to the legacy weak functions in the HAL_UART_Init() + and HAL_UART_DeInit() only when these callbacks are null (not registered beforehand). + If not, MspInit or MspDeInit are not null, the HAL_UART_Init() and HAL_UART_DeInit() + keep and use the user MspInit/MspDeInit callbacks (registered beforehand). + + [..] + Callbacks can be registered/unregistered in HAL_UART_STATE_READY state only. + Exception done MspInit/MspDeInit that can be registered/unregistered + in HAL_UART_STATE_READY or HAL_UART_STATE_RESET state, thus registered (user) + MspInit/DeInit callbacks can be used during the Init/DeInit. + In that case first register the MspInit/MspDeInit user callbacks + using HAL_UART_RegisterCallback() before calling HAL_UART_DeInit() + or HAL_UART_Init() function. + + [..] + When The compilation define USE_HAL_UART_REGISTER_CALLBACKS is set to 0 or + not defined, the callback registration feature is not available + and weak callbacks are used. + + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup UART UART + * @brief HAL UART module driver + * @{ + */ + +#ifdef HAL_UART_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup UART_Private_Constants UART Private Constants + * @{ + */ +#define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | \ + USART_CR1_OVER8 | USART_CR1_FIFOEN)) /*!< UART or USART CR1 fields of parameters set by UART_SetConfig API */ + +#define USART_CR3_FIELDS ((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_ONEBIT | USART_CR3_TXFTCFG | \ + USART_CR3_RXFTCFG)) /*!< UART or USART CR3 fields of parameters set by UART_SetConfig API */ + +#define LPUART_BRR_MIN 0x00000300U /* LPUART BRR minimum authorized value */ +#define LPUART_BRR_MAX 0x000FFFFFU /* LPUART BRR maximum authorized value */ + +#define UART_BRR_MIN 0x10U /* UART BRR minimum authorized value */ +#define UART_BRR_MAX 0x0000FFFFU /* UART BRR maximum authorized value */ +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup UART_Private_Functions + * @{ + */ +static void UART_EndRxTransfer(UART_HandleTypeDef *huart); +#if defined(HAL_DMA_MODULE_ENABLED) +static void UART_EndTxTransfer(UART_HandleTypeDef *huart); +static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma); +static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma); +static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma); +static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma); +static void UART_DMAError(DMA_HandleTypeDef *hdma); +static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma); +static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma); +static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma); +static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma); +static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma); +#endif /* HAL_DMA_MODULE_ENABLED */ +static void UART_TxISR_8BIT(UART_HandleTypeDef *huart); +static void UART_TxISR_16BIT(UART_HandleTypeDef *huart); +static void UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart); +static void UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart); +static void UART_EndTransmit_IT(UART_HandleTypeDef *huart); +static void UART_RxISR_8BIT(UART_HandleTypeDef *huart); +static void UART_RxISR_16BIT(UART_HandleTypeDef *huart); +static void UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart); +static void UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart); +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @addtogroup UART_Private_variables + * @{ + */ +const uint16_t UARTPrescTable[12] = {1U, 2U, 4U, 6U, 8U, 10U, 12U, 16U, 32U, 64U, 128U, 256U}; +/** + * @} + */ + +/* Exported Constants --------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup UART_Exported_Functions UART Exported Functions + * @{ + */ + +/** @defgroup UART_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim +=============================================================================== + ##### Initialization and Configuration functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to initialize the USARTx or the UARTy + in asynchronous mode. + (+) For the asynchronous mode the parameters below can be configured: + (++) Baud Rate + (++) Word Length + (++) Stop Bit + (++) Parity: If the parity is enabled, then the MSB bit of the data written + in the data register is transmitted but is changed by the parity bit. + (++) Hardware flow control + (++) Receiver/transmitter modes + (++) Over Sampling Method + (++) One-Bit Sampling Method + (+) For the asynchronous mode, the following advanced features can be configured as well: + (++) TX and/or RX pin level inversion + (++) data logical level inversion + (++) RX and TX pins swap + (++) RX overrun detection disabling + (++) DMA disabling on RX error + (++) MSB first on communication line + (++) auto Baud rate detection + [..] + The HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init()and HAL_MultiProcessor_Init()API + follow respectively the UART asynchronous, UART Half duplex, UART LIN mode + and UART multiprocessor mode configuration procedures (details for the procedures + are available in reference manual). + +@endverbatim + + Depending on the frame length defined by the M1 and M0 bits (7-bit, + 8-bit or 9-bit), the possible UART formats are listed in the + following table. + + Table 1. UART frame format. + +-----------------------------------------------------------------------+ + | M1 bit | M0 bit | PCE bit | UART frame | + |---------|---------|-----------|---------------------------------------| + | 0 | 0 | 0 | | SB | 8 bit data | STB | | + |---------|---------|-----------|---------------------------------------| + | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | | + |---------|---------|-----------|---------------------------------------| + | 0 | 1 | 0 | | SB | 9 bit data | STB | | + |---------|---------|-----------|---------------------------------------| + | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | | + |---------|---------|-----------|---------------------------------------| + | 1 | 0 | 0 | | SB | 7 bit data | STB | | + |---------|---------|-----------|---------------------------------------| + | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | | + +-----------------------------------------------------------------------+ + + * @{ + */ + +/** + * @brief Initialize the UART mode according to the specified + * parameters in the UART_InitTypeDef and initialize the associated handle. + * @param huart UART handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart) +{ + /* Check the UART handle allocation */ + if (huart == NULL) + { + return HAL_ERROR; + } + + if (huart->Init.HwFlowCtl != UART_HWCONTROL_NONE) + { + /* Check the parameters */ + assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance)); + } + else + { + /* Check the parameters */ + assert_param((IS_UART_INSTANCE(huart->Instance)) || (IS_LPUART_INSTANCE(huart->Instance))); + } + + if (huart->gState == HAL_UART_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + huart->Lock = HAL_UNLOCKED; + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + UART_InitCallbacksToDefault(huart); + + if (huart->MspInitCallback == NULL) + { + huart->MspInitCallback = HAL_UART_MspInit; + } + + /* Init the low level hardware */ + huart->MspInitCallback(huart); +#else + /* Init the low level hardware : GPIO, CLOCK */ + HAL_UART_MspInit(huart); +#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ + } + + huart->gState = HAL_UART_STATE_BUSY; + + __HAL_UART_DISABLE(huart); + + /* Perform advanced settings configuration */ + /* For some items, configuration requires to be done prior TE and RE bits are set */ + if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) + { + UART_AdvFeatureConfig(huart); + } + + /* Set the UART Communication parameters */ + if (UART_SetConfig(huart) == HAL_ERROR) + { + return HAL_ERROR; + } + + /* In asynchronous mode, the following bits must be kept cleared: + - LINEN and CLKEN bits in the USART_CR2 register, + - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/ + CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); + CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN)); + + __HAL_UART_ENABLE(huart); + + /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */ + return (UART_CheckIdleState(huart)); +} + +/** + * @brief Initialize the half-duplex mode according to the specified + * parameters in the UART_InitTypeDef and creates the associated handle. + * @param huart UART handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart) +{ + /* Check the UART handle allocation */ + if (huart == NULL) + { + return HAL_ERROR; + } + + /* Check UART instance */ + assert_param(IS_UART_HALFDUPLEX_INSTANCE(huart->Instance)); + + if (huart->gState == HAL_UART_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + huart->Lock = HAL_UNLOCKED; + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + UART_InitCallbacksToDefault(huart); + + if (huart->MspInitCallback == NULL) + { + huart->MspInitCallback = HAL_UART_MspInit; + } + + /* Init the low level hardware */ + huart->MspInitCallback(huart); +#else + /* Init the low level hardware : GPIO, CLOCK */ + HAL_UART_MspInit(huart); +#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ + } + + huart->gState = HAL_UART_STATE_BUSY; + + __HAL_UART_DISABLE(huart); + + /* Perform advanced settings configuration */ + /* For some items, configuration requires to be done prior TE and RE bits are set */ + if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) + { + UART_AdvFeatureConfig(huart); + } + + /* Set the UART Communication parameters */ + if (UART_SetConfig(huart) == HAL_ERROR) + { + return HAL_ERROR; + } + + /* In half-duplex mode, the following bits must be kept cleared: + - LINEN and CLKEN bits in the USART_CR2 register, + - SCEN and IREN bits in the USART_CR3 register.*/ + CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); + CLEAR_BIT(huart->Instance->CR3, (USART_CR3_IREN | USART_CR3_SCEN)); + + /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */ + SET_BIT(huart->Instance->CR3, USART_CR3_HDSEL); + + __HAL_UART_ENABLE(huart); + + /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */ + return (UART_CheckIdleState(huart)); +} + + +/** + * @brief Initialize the LIN mode according to the specified + * parameters in the UART_InitTypeDef and creates the associated handle. + * @param huart UART handle. + * @param BreakDetectLength Specifies the LIN break detection length. + * This parameter can be one of the following values: + * @arg @ref UART_LINBREAKDETECTLENGTH_10B 10-bit break detection + * @arg @ref UART_LINBREAKDETECTLENGTH_11B 11-bit break detection + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength) +{ + /* Check the UART handle allocation */ + if (huart == NULL) + { + return HAL_ERROR; + } + + /* Check the LIN UART instance */ + assert_param(IS_UART_LIN_INSTANCE(huart->Instance)); + /* Check the Break detection length parameter */ + assert_param(IS_UART_LIN_BREAK_DETECT_LENGTH(BreakDetectLength)); + + /* LIN mode limited to 16-bit oversampling only */ + if (huart->Init.OverSampling == UART_OVERSAMPLING_8) + { + return HAL_ERROR; + } + /* LIN mode limited to 8-bit data length */ + if (huart->Init.WordLength != UART_WORDLENGTH_8B) + { + return HAL_ERROR; + } + + if (huart->gState == HAL_UART_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + huart->Lock = HAL_UNLOCKED; + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + UART_InitCallbacksToDefault(huart); + + if (huart->MspInitCallback == NULL) + { + huart->MspInitCallback = HAL_UART_MspInit; + } + + /* Init the low level hardware */ + huart->MspInitCallback(huart); +#else + /* Init the low level hardware : GPIO, CLOCK */ + HAL_UART_MspInit(huart); +#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ + } + + huart->gState = HAL_UART_STATE_BUSY; + + __HAL_UART_DISABLE(huart); + + /* Perform advanced settings configuration */ + /* For some items, configuration requires to be done prior TE and RE bits are set */ + if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) + { + UART_AdvFeatureConfig(huart); + } + + /* Set the UART Communication parameters */ + if (UART_SetConfig(huart) == HAL_ERROR) + { + return HAL_ERROR; + } + + /* In LIN mode, the following bits must be kept cleared: + - LINEN and CLKEN bits in the USART_CR2 register, + - SCEN and IREN bits in the USART_CR3 register.*/ + CLEAR_BIT(huart->Instance->CR2, USART_CR2_CLKEN); + CLEAR_BIT(huart->Instance->CR3, (USART_CR3_HDSEL | USART_CR3_IREN | USART_CR3_SCEN)); + + /* Enable the LIN mode by setting the LINEN bit in the CR2 register */ + SET_BIT(huart->Instance->CR2, USART_CR2_LINEN); + + /* Set the USART LIN Break detection length. */ + MODIFY_REG(huart->Instance->CR2, USART_CR2_LBDL, BreakDetectLength); + + __HAL_UART_ENABLE(huart); + + /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */ + return (UART_CheckIdleState(huart)); +} + + +/** + * @brief Initialize the multiprocessor mode according to the specified + * parameters in the UART_InitTypeDef and initialize the associated handle. + * @param huart UART handle. + * @param Address UART node address (4-, 6-, 7- or 8-bit long). + * @param WakeUpMethod Specifies the UART wakeup method. + * This parameter can be one of the following values: + * @arg @ref UART_WAKEUPMETHOD_IDLELINE WakeUp by an idle line detection + * @arg @ref UART_WAKEUPMETHOD_ADDRESSMARK WakeUp by an address mark + * @note If the user resorts to idle line detection wake up, the Address parameter + * is useless and ignored by the initialization function. + * @note If the user resorts to address mark wake up, the address length detection + * is configured by default to 4 bits only. For the UART to be able to + * manage 6-, 7- or 8-bit long addresses detection, the API + * HAL_MultiProcessorEx_AddressLength_Set() must be called after + * HAL_MultiProcessor_Init(). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod) +{ + /* Check the UART handle allocation */ + if (huart == NULL) + { + return HAL_ERROR; + } + + /* Check the wake up method parameter */ + assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod)); + + if (huart->gState == HAL_UART_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + huart->Lock = HAL_UNLOCKED; + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + UART_InitCallbacksToDefault(huart); + + if (huart->MspInitCallback == NULL) + { + huart->MspInitCallback = HAL_UART_MspInit; + } + + /* Init the low level hardware */ + huart->MspInitCallback(huart); +#else + /* Init the low level hardware : GPIO, CLOCK */ + HAL_UART_MspInit(huart); +#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ + } + + huart->gState = HAL_UART_STATE_BUSY; + + __HAL_UART_DISABLE(huart); + + /* Perform advanced settings configuration */ + /* For some items, configuration requires to be done prior TE and RE bits are set */ + if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) + { + UART_AdvFeatureConfig(huart); + } + + /* Set the UART Communication parameters */ + if (UART_SetConfig(huart) == HAL_ERROR) + { + return HAL_ERROR; + } + + /* In multiprocessor mode, the following bits must be kept cleared: + - LINEN and CLKEN bits in the USART_CR2 register, + - SCEN, HDSEL and IREN bits in the USART_CR3 register. */ + CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); + CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN)); + + if (WakeUpMethod == UART_WAKEUPMETHOD_ADDRESSMARK) + { + /* If address mark wake up method is chosen, set the USART address node */ + MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)Address << UART_CR2_ADDRESS_LSB_POS)); + } + + /* Set the wake up method by setting the WAKE bit in the CR1 register */ + MODIFY_REG(huart->Instance->CR1, USART_CR1_WAKE, WakeUpMethod); + + __HAL_UART_ENABLE(huart); + + /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */ + return (UART_CheckIdleState(huart)); +} + + +/** + * @brief DeInitialize the UART peripheral. + * @param huart UART handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart) +{ + /* Check the UART handle allocation */ + if (huart == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param((IS_UART_INSTANCE(huart->Instance)) || (IS_LPUART_INSTANCE(huart->Instance))); + + huart->gState = HAL_UART_STATE_BUSY; + + __HAL_UART_DISABLE(huart); + + huart->Instance->CR1 = 0x0U; + huart->Instance->CR2 = 0x0U; + huart->Instance->CR3 = 0x0U; + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + if (huart->MspDeInitCallback == NULL) + { + huart->MspDeInitCallback = HAL_UART_MspDeInit; + } + /* DeInit the low level hardware */ + huart->MspDeInitCallback(huart); +#else + /* DeInit the low level hardware */ + HAL_UART_MspDeInit(huart); +#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ + + huart->ErrorCode = HAL_UART_ERROR_NONE; + huart->gState = HAL_UART_STATE_RESET; + huart->RxState = HAL_UART_STATE_RESET; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + huart->RxEventType = HAL_UART_RXEVENT_TC; + + __HAL_UNLOCK(huart); + + return HAL_OK; +} + +/** + * @brief Initialize the UART MSP. + * @param huart UART handle. + * @retval None + */ +__weak void HAL_UART_MspInit(UART_HandleTypeDef *huart) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(huart); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_UART_MspInit can be implemented in the user file + */ +} + +/** + * @brief DeInitialize the UART MSP. + * @param huart UART handle. + * @retval None + */ +__weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(huart); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_UART_MspDeInit can be implemented in the user file + */ +} + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User UART Callback + * To be used to override the weak predefined callback + * @note The HAL_UART_RegisterCallback() may be called before HAL_UART_Init(), HAL_HalfDuplex_Init(), + * HAL_LIN_Init(), HAL_MultiProcessor_Init() or HAL_RS485Ex_Init() in HAL_UART_STATE_RESET to register + * callbacks for HAL_UART_MSPINIT_CB_ID and HAL_UART_MSPDEINIT_CB_ID + * @param huart uart handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID + * @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID + * @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID + * @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID + * @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID + * @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID + * @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID + * @arg @ref HAL_UART_WAKEUP_CB_ID Wakeup Callback ID + * @arg @ref HAL_UART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID + * @arg @ref HAL_UART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID + * @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID + * @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID + * @param pCallback pointer to the Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_RegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID, + pUART_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + if (huart->gState == HAL_UART_STATE_READY) + { + switch (CallbackID) + { + case HAL_UART_TX_HALFCOMPLETE_CB_ID : + huart->TxHalfCpltCallback = pCallback; + break; + + case HAL_UART_TX_COMPLETE_CB_ID : + huart->TxCpltCallback = pCallback; + break; + + case HAL_UART_RX_HALFCOMPLETE_CB_ID : + huart->RxHalfCpltCallback = pCallback; + break; + + case HAL_UART_RX_COMPLETE_CB_ID : + huart->RxCpltCallback = pCallback; + break; + + case HAL_UART_ERROR_CB_ID : + huart->ErrorCallback = pCallback; + break; + + case HAL_UART_ABORT_COMPLETE_CB_ID : + huart->AbortCpltCallback = pCallback; + break; + + case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID : + huart->AbortTransmitCpltCallback = pCallback; + break; + + case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID : + huart->AbortReceiveCpltCallback = pCallback; + break; + + case HAL_UART_WAKEUP_CB_ID : + huart->WakeupCallback = pCallback; + break; + + case HAL_UART_RX_FIFO_FULL_CB_ID : + huart->RxFifoFullCallback = pCallback; + break; + + case HAL_UART_TX_FIFO_EMPTY_CB_ID : + huart->TxFifoEmptyCallback = pCallback; + break; + + case HAL_UART_MSPINIT_CB_ID : + huart->MspInitCallback = pCallback; + break; + + case HAL_UART_MSPDEINIT_CB_ID : + huart->MspDeInitCallback = pCallback; + break; + + default : + huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; + + status = HAL_ERROR; + break; + } + } + else if (huart->gState == HAL_UART_STATE_RESET) + { + switch (CallbackID) + { + case HAL_UART_MSPINIT_CB_ID : + huart->MspInitCallback = pCallback; + break; + + case HAL_UART_MSPDEINIT_CB_ID : + huart->MspDeInitCallback = pCallback; + break; + + default : + huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; + + status = HAL_ERROR; + break; + } + } + else + { + huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; + + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister an UART Callback + * UART callaback is redirected to the weak predefined callback + * @note The HAL_UART_UnRegisterCallback() may be called before HAL_UART_Init(), HAL_HalfDuplex_Init(), + * HAL_LIN_Init(), HAL_MultiProcessor_Init() or HAL_RS485Ex_Init() in HAL_UART_STATE_RESET to un-register + * callbacks for HAL_UART_MSPINIT_CB_ID and HAL_UART_MSPDEINIT_CB_ID + * @param huart uart handle + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID + * @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID + * @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID + * @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID + * @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID + * @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID + * @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID + * @arg @ref HAL_UART_WAKEUP_CB_ID Wakeup Callback ID + * @arg @ref HAL_UART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID + * @arg @ref HAL_UART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID + * @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID + * @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_UnRegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (HAL_UART_STATE_READY == huart->gState) + { + switch (CallbackID) + { + case HAL_UART_TX_HALFCOMPLETE_CB_ID : + huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */ + break; + + case HAL_UART_TX_COMPLETE_CB_ID : + huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */ + break; + + case HAL_UART_RX_HALFCOMPLETE_CB_ID : + huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */ + break; + + case HAL_UART_RX_COMPLETE_CB_ID : + huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */ + break; + + case HAL_UART_ERROR_CB_ID : + huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */ + break; + + case HAL_UART_ABORT_COMPLETE_CB_ID : + huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ + break; + + case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID : + huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak + AbortTransmitCpltCallback */ + break; + + case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID : + huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak + AbortReceiveCpltCallback */ + break; + + case HAL_UART_WAKEUP_CB_ID : + huart->WakeupCallback = HAL_UARTEx_WakeupCallback; /* Legacy weak WakeupCallback */ + break; + + case HAL_UART_RX_FIFO_FULL_CB_ID : + huart->RxFifoFullCallback = HAL_UARTEx_RxFifoFullCallback; /* Legacy weak RxFifoFullCallback */ + break; + + case HAL_UART_TX_FIFO_EMPTY_CB_ID : + huart->TxFifoEmptyCallback = HAL_UARTEx_TxFifoEmptyCallback; /* Legacy weak TxFifoEmptyCallback */ + break; + + case HAL_UART_MSPINIT_CB_ID : + huart->MspInitCallback = HAL_UART_MspInit; /* Legacy weak MspInitCallback */ + break; + + case HAL_UART_MSPDEINIT_CB_ID : + huart->MspDeInitCallback = HAL_UART_MspDeInit; /* Legacy weak MspDeInitCallback */ + break; + + default : + huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; + + status = HAL_ERROR; + break; + } + } + else if (HAL_UART_STATE_RESET == huart->gState) + { + switch (CallbackID) + { + case HAL_UART_MSPINIT_CB_ID : + huart->MspInitCallback = HAL_UART_MspInit; + break; + + case HAL_UART_MSPDEINIT_CB_ID : + huart->MspDeInitCallback = HAL_UART_MspDeInit; + break; + + default : + huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; + + status = HAL_ERROR; + break; + } + } + else + { + huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; + + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Register a User UART Rx Event Callback + * To be used instead of the weak predefined callback + * @param huart Uart handle + * @param pCallback Pointer to the Rx Event Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_RegisterRxEventCallback(UART_HandleTypeDef *huart, pUART_RxEventCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(huart); + + if (huart->gState == HAL_UART_STATE_READY) + { + huart->RxEventCallback = pCallback; + } + else + { + huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; + + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(huart); + + return status; +} + +/** + * @brief UnRegister the UART Rx Event Callback + * UART Rx Event Callback is redirected to the weak HAL_UARTEx_RxEventCallback() predefined callback + * @param huart Uart handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_UnRegisterRxEventCallback(UART_HandleTypeDef *huart) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(huart); + + if (huart->gState == HAL_UART_STATE_READY) + { + huart->RxEventCallback = HAL_UARTEx_RxEventCallback; /* Legacy weak UART Rx Event Callback */ + } + else + { + huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK; + + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(huart); + return status; +} + +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup UART_Exported_Functions_Group2 IO operation functions + * @brief UART Transmit/Receive functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + This subsection provides a set of functions allowing to manage the UART asynchronous + and Half duplex data transfers. + + (#) There are two mode of transfer: + (+) Blocking mode: The communication is performed in polling mode. + The HAL status of all data processing is returned by the same function + after finishing transfer. + (+) Non-Blocking mode: The communication is performed using Interrupts + or DMA, These API's return the HAL status. + The end of the data processing will be indicated through the + dedicated UART IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks + will be executed respectively at the end of the transmit or Receive process + The HAL_UART_ErrorCallback()user callback will be executed when a communication error is detected + + (#) Blocking mode API's are : + (+) HAL_UART_Transmit() + (+) HAL_UART_Receive() + + (#) Non-Blocking mode API's with Interrupt are : + (+) HAL_UART_Transmit_IT() + (+) HAL_UART_Receive_IT() + (+) HAL_UART_IRQHandler() + + (#) Non-Blocking mode API's with DMA are : + (+) HAL_UART_Transmit_DMA() + (+) HAL_UART_Receive_DMA() + (+) HAL_UART_DMAPause() + (+) HAL_UART_DMAResume() + (+) HAL_UART_DMAStop() + + (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode: + (+) HAL_UART_TxHalfCpltCallback() + (+) HAL_UART_TxCpltCallback() + (+) HAL_UART_RxHalfCpltCallback() + (+) HAL_UART_RxCpltCallback() + (+) HAL_UART_ErrorCallback() + + (#) Non-Blocking mode transfers could be aborted using Abort API's : + (+) HAL_UART_Abort() + (+) HAL_UART_AbortTransmit() + (+) HAL_UART_AbortReceive() + (+) HAL_UART_Abort_IT() + (+) HAL_UART_AbortTransmit_IT() + (+) HAL_UART_AbortReceive_IT() + + (#) For Abort services based on interrupts (HAL_UART_Abortxxx_IT), a set of Abort Complete Callbacks are provided: + (+) HAL_UART_AbortCpltCallback() + (+) HAL_UART_AbortTransmitCpltCallback() + (+) HAL_UART_AbortReceiveCpltCallback() + + (#) A Rx Event Reception Callback (Rx event notification) is available for Non_Blocking modes of enhanced + reception services: + (+) HAL_UARTEx_RxEventCallback() + + (#) In Non-Blocking mode transfers, possible errors are split into 2 categories. + Errors are handled as follows : + (+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is + to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error + in Interrupt mode reception . + Received character is then retrieved and stored in Rx buffer, Error code is set to allow user + to identify error type, and HAL_UART_ErrorCallback() user callback is executed. + Transfer is kept ongoing on UART side. + If user wants to abort it, Abort services should be called by user. + (+) Error is considered as Blocking : Transfer could not be completed properly and is aborted. + This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode. + Error code is set to allow user to identify error type, and HAL_UART_ErrorCallback() + user callback is executed. + + -@- In the Half duplex communication, it is forbidden to run the transmit + and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX can't be useful. + +@endverbatim + * @{ + */ + +/** + * @brief Send an amount of data in blocking mode. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * the sent data is handled as a set of u16. In this case, Size must indicate the number + * of u16 provided through pData. + * @note When FIFO mode is enabled, writing a data in the TDR register adds one + * data to the TXFIFO. Write operations to the TDR register are performed + * when TXFNF flag is set. From hardware perspective, TXFNF flag and + * TXE are mapped on the same bit-field. + * @param huart UART handle. + * @param pData Pointer to data buffer (u8 or u16 data elements). + * @param Size Amount of data elements (u8 or u16) to be sent. + * @param Timeout Timeout duration. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + const uint8_t *pdata8bits; + const uint16_t *pdata16bits; + uint32_t tickstart; + + /* Check that a Tx process is not already ongoing */ + if (huart->gState == HAL_UART_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Disable the UART DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) + { + CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); + } + + huart->ErrorCode = HAL_UART_ERROR_NONE; + huart->gState = HAL_UART_STATE_BUSY_TX; + + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + + huart->TxXferSize = Size; + huart->TxXferCount = Size; + + /* In case of 9bits/No Parity transfer, pData needs to be handled as a uint16_t pointer */ + if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) + { + pdata8bits = NULL; + pdata16bits = (const uint16_t *) pData; + } + else + { + pdata8bits = pData; + pdata16bits = NULL; + } + + while (huart->TxXferCount > 0U) + { + if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK) + { + + huart->gState = HAL_UART_STATE_READY; + + return HAL_TIMEOUT; + } + if (pdata8bits == NULL) + { + huart->Instance->TDR = (uint16_t)(*pdata16bits & 0x01FFU); + pdata16bits++; + } + else + { + huart->Instance->TDR = (uint8_t)(*pdata8bits & 0xFFU); + pdata8bits++; + } + huart->TxXferCount--; + } + + if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK) + { + huart->gState = HAL_UART_STATE_READY; + + return HAL_TIMEOUT; + } + + /* At end of Tx process, restore huart->gState to Ready */ + huart->gState = HAL_UART_STATE_READY; + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in blocking mode. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * the received data is handled as a set of u16. In this case, Size must indicate the number + * of u16 available through pData. + * @note When FIFO mode is enabled, the RXFNE flag is set as long as the RXFIFO + * is not empty. Read operations from the RDR register are performed when + * RXFNE flag is set. From hardware perspective, RXFNE flag and + * RXNE are mapped on the same bit-field. + * @param huart UART handle. + * @param pData Pointer to data buffer (u8 or u16 data elements). + * @param Size Amount of data elements (u8 or u16) to be received. + * @param Timeout Timeout duration. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint8_t *pdata8bits; + uint16_t *pdata16bits; + uint16_t uhMask; + uint32_t tickstart; + + /* Check that a Rx process is not already ongoing */ + if (huart->RxState == HAL_UART_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Disable the UART DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); + } + + huart->ErrorCode = HAL_UART_ERROR_NONE; + huart->RxState = HAL_UART_STATE_BUSY_RX; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + + huart->RxXferSize = Size; + huart->RxXferCount = Size; + + /* Computation of UART mask to apply to RDR register */ + UART_MASK_COMPUTATION(huart); + uhMask = huart->Mask; + + /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */ + if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) + { + pdata8bits = NULL; + pdata16bits = (uint16_t *) pData; + } + else + { + pdata8bits = pData; + pdata16bits = NULL; + } + + /* as long as data have to be received */ + while (huart->RxXferCount > 0U) + { + if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK) + { + huart->RxState = HAL_UART_STATE_READY; + + return HAL_TIMEOUT; + } + if (pdata8bits == NULL) + { + *pdata16bits = (uint16_t)(huart->Instance->RDR & uhMask); + pdata16bits++; + } + else + { + *pdata8bits = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask); + pdata8bits++; + } + huart->RxXferCount--; + } + + /* At end of Rx process, restore huart->RxState to Ready */ + huart->RxState = HAL_UART_STATE_READY; + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Send an amount of data in interrupt mode. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * the sent data is handled as a set of u16. In this case, Size must indicate the number + * of u16 provided through pData. + * @param huart UART handle. + * @param pData Pointer to data buffer (u8 or u16 data elements). + * @param Size Amount of data elements (u8 or u16) to be sent. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size) +{ + /* Check that a Tx process is not already ongoing */ + if (huart->gState == HAL_UART_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Disable the UART DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) + { + CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); + } + + huart->pTxBuffPtr = pData; + huart->TxXferSize = Size; + huart->TxXferCount = Size; + huart->TxISR = NULL; + + huart->ErrorCode = HAL_UART_ERROR_NONE; + huart->gState = HAL_UART_STATE_BUSY_TX; + + /* Configure Tx interrupt processing */ + if (huart->FifoMode == UART_FIFOMODE_ENABLE) + { + /* Set the Tx ISR function pointer according to the data word length */ + if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) + { + huart->TxISR = UART_TxISR_16BIT_FIFOEN; + } + else + { + huart->TxISR = UART_TxISR_8BIT_FIFOEN; + } + + /* Enable the TX FIFO threshold interrupt */ + ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_TXFTIE); + } + else + { + /* Set the Tx ISR function pointer according to the data word length */ + if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) + { + huart->TxISR = UART_TxISR_16BIT; + } + else + { + huart->TxISR = UART_TxISR_8BIT; + } + + /* Enable the Transmit Data Register Empty interrupt */ + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE); + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in interrupt mode. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * the received data is handled as a set of u16. In this case, Size must indicate the number + * of u16 available through pData. + * @param huart UART handle. + * @param pData Pointer to data buffer (u8 or u16 data elements). + * @param Size Amount of data elements (u8 or u16) to be received. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) +{ + /* Check that a Rx process is not already ongoing */ + if (huart->RxState == HAL_UART_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Set Reception type to Standard reception */ + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + + /* Disable the UART DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); + } + + if (!(IS_LPUART_INSTANCE(huart->Instance))) + { + /* Check that USART RTOEN bit is set */ + if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U) + { + /* Enable the UART Receiver Timeout Interrupt */ + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RTOIE); + } + } + + return (UART_Start_Receive_IT(huart, pData, Size)); + } + else + { + return HAL_BUSY; + } +} + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief Send an amount of data in DMA mode. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * the sent data is handled as a set of u16. In this case, Size must indicate the number + * of u16 provided through pData. + * @param huart UART handle. + * @param pData Pointer to data buffer (u8 or u16 data elements). + * @param Size Amount of data elements (u8 or u16) to be sent. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size) +{ + HAL_StatusTypeDef status; + uint16_t nbByte = Size; + + /* Check that a Tx process is not already ongoing */ + if (huart->gState == HAL_UART_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + huart->pTxBuffPtr = pData; + huart->TxXferSize = Size; + huart->TxXferCount = Size; + + huart->ErrorCode = HAL_UART_ERROR_NONE; + huart->gState = HAL_UART_STATE_BUSY_TX; + + if (huart->hdmatx != NULL) + { + /* Set the UART DMA transfer complete callback */ + huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt; + + /* Set the UART DMA Half transfer complete callback */ + huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt; + + /* Set the DMA error callback */ + huart->hdmatx->XferErrorCallback = UART_DMAError; + + /* Set the DMA abort callback */ + huart->hdmatx->XferAbortCallback = NULL; + + /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter + should be aligned on a u16 frontier, so nbByte should be equal to Size * 2 */ + if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) + { + nbByte = Size * 2U; + } + + /* Check linked list mode */ + if ((huart->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((huart->hdmatx->LinkedListQueue != NULL) && (huart->hdmatx->LinkedListQueue->Head != NULL)) + { + /* Set DMA data size */ + huart->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = nbByte; + + /* Set DMA source address */ + huart->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)huart->pTxBuffPtr; + + /* Set DMA destination address */ + huart->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = + (uint32_t)&huart->Instance->TDR; + + /* Enable the UART transmit DMA channel */ + status = HAL_DMAEx_List_Start_IT(huart->hdmatx); + } + else + { + /* Update status */ + status = HAL_ERROR; + } + } + else + { + /* Enable the UART transmit DMA channel */ + status = HAL_DMA_Start_IT(huart->hdmatx, (uint32_t)huart->pTxBuffPtr, (uint32_t)&huart->Instance->TDR, nbByte); + } + + if (status != HAL_OK) + { + /* Set error code to DMA */ + huart->ErrorCode = HAL_UART_ERROR_DMA; + + /* Restore huart->gState to ready */ + huart->gState = HAL_UART_STATE_READY; + + return HAL_ERROR; + } + } + /* Clear the TC flag in the ICR register */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_TCF); + + /* Enable the DMA transfer for transmit request by setting the DMAT bit + in the UART CR3 register */ + ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in DMA mode. + * @note When the UART parity is enabled (PCE = 1), the received data contain + * the parity bit (MSB position). + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * the received data is handled as a set of u16. In this case, Size must indicate the number + * of u16 available through pData. + * @param huart UART handle. + * @param pData Pointer to data buffer (u8 or u16 data elements). + * @param Size Amount of data elements (u8 or u16) to be received. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) +{ + /* Check that a Rx process is not already ongoing */ + if (huart->RxState == HAL_UART_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Set Reception type to Standard reception */ + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + + if (!(IS_LPUART_INSTANCE(huart->Instance))) + { + /* Check that USART RTOEN bit is set */ + if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U) + { + /* Enable the UART Receiver Timeout Interrupt */ + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RTOIE); + } + } + + return (UART_Start_Receive_DMA(huart, pData, Size)); + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Pause the DMA Transfer. + * @param huart UART handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart) +{ + const HAL_UART_StateTypeDef gstate = huart->gState; + const HAL_UART_StateTypeDef rxstate = huart->RxState; + + if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) && + (gstate == HAL_UART_STATE_BUSY_TX)) + { + /* Suspend the UART DMA Tx channel : use blocking DMA Suspend API (no callback) */ + if (huart->hdmatx != NULL) + { + /* Set the UART DMA Suspend callback to Null. + No call back execution at end of DMA Suspend procedure */ + huart->hdmatx->XferSuspendCallback = NULL; + + if (HAL_DMAEx_Suspend(huart->hdmatx) != HAL_OK) + { + if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + huart->ErrorCode = HAL_UART_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + } + } + if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) && + (rxstate == HAL_UART_STATE_BUSY_RX)) + { + /* Suspend the UART DMA Rx channel : use blocking DMA Suspend API (no callback) */ + if (huart->hdmarx != NULL) + { + /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); + + /* Set the UART DMA Suspend callback to Null. + No call back execution at end of DMA Suspend procedure */ + huart->hdmarx->XferSuspendCallback = NULL; + + if (HAL_DMAEx_Suspend(huart->hdmarx) != HAL_OK) + { + if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + huart->ErrorCode = HAL_UART_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + } + } + + return HAL_OK; +} + +/** + * @brief Resume the DMA Transfer. + * @param huart UART handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart) +{ + if (huart->gState == HAL_UART_STATE_BUSY_TX) + { + /* Resume the UART DMA Tx channel */ + if (huart->hdmatx != NULL) + { + if (HAL_DMAEx_Resume(huart->hdmatx) != HAL_OK) + { + /* Set error code to DMA */ + huart->ErrorCode = HAL_UART_ERROR_DMA; + + return HAL_ERROR; + } + } + } + if (huart->RxState == HAL_UART_STATE_BUSY_RX) + { + /* Clear the Overrun flag before resuming the Rx transfer */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF); + + /* Re-enable PE and ERR (Frame error, noise error, overrun error) interrupts */ + if (huart->Init.Parity != UART_PARITY_NONE) + { + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE); + } + ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE); + + /* Resume the UART DMA Rx channel */ + if (huart->hdmarx != NULL) + { + if (HAL_DMAEx_Resume(huart->hdmarx) != HAL_OK) + { + /* Set error code to DMA */ + huart->ErrorCode = HAL_UART_ERROR_DMA; + + return HAL_ERROR; + } + } + } + + return HAL_OK; +} + +/** + * @brief Stop the DMA Transfer. + * @param huart UART handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart) +{ + /* The Lock is not implemented on this API to allow the user application + to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback() / + HAL_UART_TxHalfCpltCallback / HAL_UART_RxHalfCpltCallback: + indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete + interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of + the stream and the corresponding call back is executed. */ + + const HAL_UART_StateTypeDef gstate = huart->gState; + const HAL_UART_StateTypeDef rxstate = huart->RxState; + + /* Stop UART DMA Tx request if ongoing */ + if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) && + (gstate == HAL_UART_STATE_BUSY_TX)) + { + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT); + + /* Abort the UART DMA Tx channel */ + if (huart->hdmatx != NULL) + { + if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK) + { + if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + huart->ErrorCode = HAL_UART_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + } + + UART_EndTxTransfer(huart); + } + + /* Stop UART DMA Rx request if ongoing */ + if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) && + (rxstate == HAL_UART_STATE_BUSY_RX)) + { + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); + + /* Abort the UART DMA Rx channel */ + if (huart->hdmarx != NULL) + { + if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK) + { + if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + huart->ErrorCode = HAL_UART_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + } + + UART_EndRxTransfer(huart); + } + + return HAL_OK; +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Abort ongoing transfers (blocking mode). + * @param huart UART handle. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable UART Interrupts (Tx and Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart) +{ + /* Disable TXE, TC, RXNE, PE, RXFT, TXFT and ERR (Frame error, noise error, overrun error) interrupts */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | + USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE)); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE); + + /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */ + if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + { + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE)); + } + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Abort the UART DMA Tx channel if enabled */ + if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) + { + /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */ + if (huart->hdmatx != NULL) + { + /* Set the UART DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + huart->hdmatx->XferAbortCallback = NULL; + + if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK) + { + if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + huart->ErrorCode = HAL_UART_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + } + } + + /* Abort the UART DMA Rx channel if enabled */ + if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) + { + /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */ + if (huart->hdmarx != NULL) + { + /* Set the UART DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + huart->hdmarx->XferAbortCallback = NULL; + + if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK) + { + if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + huart->ErrorCode = HAL_UART_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + } + } +#endif /* HAL_DMA_MODULE_ENABLED */ + + /* Reset Tx and Rx transfer counters */ + huart->TxXferCount = 0U; + huart->RxXferCount = 0U; + + /* Clear the Error flags in the ICR register */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); + + /* Flush the whole TX FIFO (if needed) */ + if (huart->FifoMode == UART_FIFOMODE_ENABLE) + { + __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST); + } + + /* Discard the received data */ + __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); + + /* Restore huart->gState and huart->RxState to Ready */ + huart->gState = HAL_UART_STATE_READY; + huart->RxState = HAL_UART_STATE_READY; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + + huart->ErrorCode = HAL_UART_ERROR_NONE; + + return HAL_OK; +} + +/** + * @brief Abort ongoing Transmit transfer (blocking mode). + * @param huart UART handle. + * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable UART Interrupts (Tx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart) +{ + /* Disable TCIE, TXEIE and TXFTIE interrupts */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TCIE | USART_CR1_TXEIE_TXFNFIE)); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE); + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Abort the UART DMA Tx channel if enabled */ + if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) + { + /* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */ + if (huart->hdmatx != NULL) + { + /* Set the UART DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + huart->hdmatx->XferAbortCallback = NULL; + + if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK) + { + if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + huart->ErrorCode = HAL_UART_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + } + } +#endif /* HAL_DMA_MODULE_ENABLED */ + + /* Reset Tx transfer counter */ + huart->TxXferCount = 0U; + + /* Flush the whole TX FIFO (if needed) */ + if (huart->FifoMode == UART_FIFOMODE_ENABLE) + { + __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST); + } + + /* Restore huart->gState to Ready */ + huart->gState = HAL_UART_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Abort ongoing Receive transfer (blocking mode). + * @param huart UART handle. + * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable UART Interrupts (Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart) +{ + /* Disable PEIE, EIE, RXNEIE and RXFTIE interrupts */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE)); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE | USART_CR3_RXFTIE); + + /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */ + if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + { + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE)); + } + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Abort the UART DMA Rx channel if enabled */ + if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) + { + /* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */ + if (huart->hdmarx != NULL) + { + /* Set the UART DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + huart->hdmarx->XferAbortCallback = NULL; + + if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK) + { + if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + huart->ErrorCode = HAL_UART_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + } + } +#endif /* HAL_DMA_MODULE_ENABLED */ + + /* Reset Rx transfer counter */ + huart->RxXferCount = 0U; + + /* Clear the Error flags in the ICR register */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); + + /* Discard the received data */ + __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); + + /* Restore huart->RxState to Ready */ + huart->RxState = HAL_UART_STATE_READY; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + + return HAL_OK; +} + +/** + * @brief Abort ongoing transfers (Interrupt mode). + * @param huart UART handle. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable UART Interrupts (Tx and Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart) +{ + uint32_t abortcplt = 1U; + + /* Disable interrupts */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_TCIE | USART_CR1_RXNEIE_RXFNEIE | + USART_CR1_TXEIE_TXFNFIE)); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE)); + + /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */ + if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + { + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE)); + } + +#if defined(HAL_DMA_MODULE_ENABLED) + /* If DMA Tx and/or DMA Rx Handles are associated to UART Handle, DMA Abort complete callbacks should be initialised + before any call to DMA Abort functions */ + /* DMA Tx Handle is valid */ + if (huart->hdmatx != NULL) + { + /* Set DMA Abort Complete callback if UART DMA Tx request if enabled. + Otherwise, set it to NULL */ + if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) + { + huart->hdmatx->XferAbortCallback = UART_DMATxAbortCallback; + } + else + { + huart->hdmatx->XferAbortCallback = NULL; + } + } + /* DMA Rx Handle is valid */ + if (huart->hdmarx != NULL) + { + /* Set DMA Abort Complete callback if UART DMA Rx request if enabled. + Otherwise, set it to NULL */ + if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) + { + huart->hdmarx->XferAbortCallback = UART_DMARxAbortCallback; + } + else + { + huart->hdmarx->XferAbortCallback = NULL; + } + } + + /* Abort the UART DMA Tx channel if enabled */ + if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) + { + /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */ + if (huart->hdmatx != NULL) + { + /* UART Tx DMA Abort callback has already been initialised : + will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */ + + /* Abort DMA TX */ + if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK) + { + huart->hdmatx->XferAbortCallback = NULL; + } + else + { + abortcplt = 0U; + } + } + } + + /* Abort the UART DMA Rx channel if enabled */ + if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) + { + /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */ + if (huart->hdmarx != NULL) + { + /* UART Rx DMA Abort callback has already been initialised : + will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */ + + /* Abort DMA RX */ + if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK) + { + huart->hdmarx->XferAbortCallback = NULL; + abortcplt = 1U; + } + else + { + abortcplt = 0U; + } + } + } +#endif /* HAL_DMA_MODULE_ENABLED */ + + /* if no DMA abort complete callback execution is required => call user Abort Complete callback */ + if (abortcplt == 1U) + { + /* Reset Tx and Rx transfer counters */ + huart->TxXferCount = 0U; + huart->RxXferCount = 0U; + + /* Clear ISR function pointers */ + huart->RxISR = NULL; + huart->TxISR = NULL; + + /* Reset errorCode */ + huart->ErrorCode = HAL_UART_ERROR_NONE; + + /* Clear the Error flags in the ICR register */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); + + /* Flush the whole TX FIFO (if needed) */ + if (huart->FifoMode == UART_FIFOMODE_ENABLE) + { + __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST); + } + + /* Discard the received data */ + __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); + + /* Restore huart->gState and huart->RxState to Ready */ + huart->gState = HAL_UART_STATE_READY; + huart->RxState = HAL_UART_STATE_READY; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + + /* As no DMA to be aborted, call directly user Abort complete callback */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /* Call registered Abort complete callback */ + huart->AbortCpltCallback(huart); +#else + /* Call legacy weak Abort complete callback */ + HAL_UART_AbortCpltCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + } + + return HAL_OK; +} + +/** + * @brief Abort ongoing Transmit transfer (Interrupt mode). + * @param huart UART handle. + * @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable UART Interrupts (Tx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart) +{ + /* Disable interrupts */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TCIE | USART_CR1_TXEIE_TXFNFIE)); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE); + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Abort the UART DMA Tx channel if enabled */ + if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) + { + /* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */ + if (huart->hdmatx != NULL) + { + /* Set the UART DMA Abort callback : + will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */ + huart->hdmatx->XferAbortCallback = UART_DMATxOnlyAbortCallback; + + /* Abort DMA TX */ + if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK) + { + /* Call Directly huart->hdmatx->XferAbortCallback function in case of error */ + huart->hdmatx->XferAbortCallback(huart->hdmatx); + } + } + else + { + /* Reset Tx transfer counter */ + huart->TxXferCount = 0U; + + /* Clear TxISR function pointers */ + huart->TxISR = NULL; + + /* Restore huart->gState to Ready */ + huart->gState = HAL_UART_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /* Call registered Abort Transmit Complete Callback */ + huart->AbortTransmitCpltCallback(huart); +#else + /* Call legacy weak Abort Transmit Complete Callback */ + HAL_UART_AbortTransmitCpltCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + } + } + else +#endif /* HAL_DMA_MODULE_ENABLED */ + { + /* Reset Tx transfer counter */ + huart->TxXferCount = 0U; + + /* Clear TxISR function pointers */ + huart->TxISR = NULL; + + /* Flush the whole TX FIFO (if needed) */ + if (huart->FifoMode == UART_FIFOMODE_ENABLE) + { + __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST); + } + + /* Restore huart->gState to Ready */ + huart->gState = HAL_UART_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /* Call registered Abort Transmit Complete Callback */ + huart->AbortTransmitCpltCallback(huart); +#else + /* Call legacy weak Abort Transmit Complete Callback */ + HAL_UART_AbortTransmitCpltCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + } + + return HAL_OK; +} + +/** + * @brief Abort ongoing Receive transfer (Interrupt mode). + * @param huart UART handle. + * @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable UART Interrupts (Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart) +{ + /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE)); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE)); + + /* If Reception till IDLE event was ongoing, disable IDLEIE interrupt */ + if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + { + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_IDLEIE)); + } + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Abort the UART DMA Rx channel if enabled */ + if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) + { + /* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */ + if (huart->hdmarx != NULL) + { + /* Set the UART DMA Abort callback : + will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */ + huart->hdmarx->XferAbortCallback = UART_DMARxOnlyAbortCallback; + + /* Abort DMA RX */ + if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK) + { + /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */ + huart->hdmarx->XferAbortCallback(huart->hdmarx); + } + } + else + { + /* Reset Rx transfer counter */ + huart->RxXferCount = 0U; + + /* Clear RxISR function pointer */ + huart->pRxBuffPtr = NULL; + + /* Clear the Error flags in the ICR register */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); + + /* Discard the received data */ + __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); + + /* Restore huart->RxState to Ready */ + huart->RxState = HAL_UART_STATE_READY; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + + /* As no DMA to be aborted, call directly user Abort complete callback */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /* Call registered Abort Receive Complete Callback */ + huart->AbortReceiveCpltCallback(huart); +#else + /* Call legacy weak Abort Receive Complete Callback */ + HAL_UART_AbortReceiveCpltCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + } + } + else +#endif /* HAL_DMA_MODULE_ENABLED */ + { + /* Reset Rx transfer counter */ + huart->RxXferCount = 0U; + + /* Clear RxISR function pointer */ + huart->pRxBuffPtr = NULL; + + /* Clear the Error flags in the ICR register */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); + + /* Restore huart->RxState to Ready */ + huart->RxState = HAL_UART_STATE_READY; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + + /* As no DMA to be aborted, call directly user Abort complete callback */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /* Call registered Abort Receive Complete Callback */ + huart->AbortReceiveCpltCallback(huart); +#else + /* Call legacy weak Abort Receive Complete Callback */ + HAL_UART_AbortReceiveCpltCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + } + + return HAL_OK; +} + +/** + * @brief Handle UART interrupt request. + * @param huart UART handle. + * @retval None + */ +void HAL_UART_IRQHandler(UART_HandleTypeDef *huart) +{ + uint32_t isrflags = READ_REG(huart->Instance->ISR); + uint32_t cr1its = READ_REG(huart->Instance->CR1); + uint32_t cr3its = READ_REG(huart->Instance->CR3); + + uint32_t errorflags; + uint32_t errorcode; + + /* If no error occurs */ + errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE | USART_ISR_RTOF)); + if (errorflags == 0U) + { + /* UART in mode Receiver ---------------------------------------------------*/ + if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U) + && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) + || ((cr3its & USART_CR3_RXFTIE) != 0U))) + { + if (huart->RxISR != NULL) + { + huart->RxISR(huart); + } + return; + } + } + + /* If some errors occur */ + if ((errorflags != 0U) + && ((((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U) + || ((cr1its & (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_RTOIE)) != 0U)))) + { + /* UART parity error interrupt occurred -------------------------------------*/ + if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U)) + { + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF); + + huart->ErrorCode |= HAL_UART_ERROR_PE; + } + + /* UART frame error interrupt occurred --------------------------------------*/ + if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) + { + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF); + + huart->ErrorCode |= HAL_UART_ERROR_FE; + } + + /* UART noise error interrupt occurred --------------------------------------*/ + if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) + { + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF); + + huart->ErrorCode |= HAL_UART_ERROR_NE; + } + + /* UART Over-Run interrupt occurred -----------------------------------------*/ + if (((isrflags & USART_ISR_ORE) != 0U) + && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) || + ((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U))) + { + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF); + + huart->ErrorCode |= HAL_UART_ERROR_ORE; + } + + /* UART Receiver Timeout interrupt occurred ---------------------------------*/ + if (((isrflags & USART_ISR_RTOF) != 0U) && ((cr1its & USART_CR1_RTOIE) != 0U)) + { + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_RTOF); + + huart->ErrorCode |= HAL_UART_ERROR_RTO; + } + + /* Call UART Error Call back function if need be ----------------------------*/ + if (huart->ErrorCode != HAL_UART_ERROR_NONE) + { + /* UART in mode Receiver --------------------------------------------------*/ + if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U) + && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) + || ((cr3its & USART_CR3_RXFTIE) != 0U))) + { + if (huart->RxISR != NULL) + { + huart->RxISR(huart); + } + } + + /* If Error is to be considered as blocking : + - Receiver Timeout error in Reception + - Overrun error in Reception + - any error occurs in DMA mode reception + */ + errorcode = huart->ErrorCode; + if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) || + ((errorcode & (HAL_UART_ERROR_RTO | HAL_UART_ERROR_ORE)) != 0U)) + { + /* Blocking error : transfer is aborted + Set the UART state ready to be able to start again the process, + Disable Rx Interrupts, and disable Rx DMA request, if ongoing */ + UART_EndRxTransfer(huart); + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Abort the UART DMA Rx channel if enabled */ + if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) + { + /* Abort the UART DMA Rx channel */ + if (huart->hdmarx != NULL) + { + /* Set the UART DMA Abort callback : + will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */ + huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError; + + /* Abort DMA RX */ + if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK) + { + /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */ + huart->hdmarx->XferAbortCallback(huart->hdmarx); + } + } + else + { + /* Call user error callback */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered error callback*/ + huart->ErrorCallback(huart); +#else + /*Call legacy weak error callback*/ + HAL_UART_ErrorCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + + } + } + else +#endif /* HAL_DMA_MODULE_ENABLED */ + { + /* Call user error callback */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered error callback*/ + huart->ErrorCallback(huart); +#else + /*Call legacy weak error callback*/ + HAL_UART_ErrorCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + } + } + else + { + /* Non Blocking error : transfer could go on. + Error is notified to user through user error callback */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered error callback*/ + huart->ErrorCallback(huart); +#else + /*Call legacy weak error callback*/ + HAL_UART_ErrorCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + huart->ErrorCode = HAL_UART_ERROR_NONE; + } + } + return; + + } /* End if some error occurs */ + + /* Check current reception Mode : + If Reception till IDLE event has been selected : */ + if ((huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + && ((isrflags & USART_ISR_IDLE) != 0U) + && ((cr1its & USART_ISR_IDLE) != 0U)) + { + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Check if DMA mode is enabled in UART */ + if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) + { + /* DMA mode enabled */ + /* Check received length : If all expected data are received, do nothing, + (DMA cplt callback will be called). + Otherwise, if at least one data has already been received, IDLE event is to be notified to user */ + uint16_t nb_remaining_rx_data = (uint16_t) __HAL_DMA_GET_COUNTER(huart->hdmarx); + if ((nb_remaining_rx_data > 0U) + && (nb_remaining_rx_data < huart->RxXferSize)) + { + /* Reception is not complete */ + huart->RxXferCount = nb_remaining_rx_data; + + /* In Normal mode, end DMA xfer and HAL UART Rx process*/ + if (huart->hdmarx->Mode != DMA_LINKEDLIST_CIRCULAR) + { + /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); + + /* At end of Rx process, restore huart->RxState to Ready */ + huart->RxState = HAL_UART_STATE_READY; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); + + /* Last bytes received, so no need as the abort is immediate */ + (void)HAL_DMA_Abort(huart->hdmarx); + } + + /* Initialize type of RxEvent that correspond to RxEvent callback execution; + In this case, Rx Event type is Idle Event */ + huart->RxEventType = HAL_UART_RXEVENT_IDLE; + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered Rx Event callback*/ + huart->RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount)); +#else + /*Call legacy weak Rx Event callback*/ + HAL_UARTEx_RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount)); +#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ + } + return; + } + else + { +#endif /* HAL_DMA_MODULE_ENABLED */ + /* DMA mode not enabled */ + /* Check received length : If all expected data are received, do nothing. + Otherwise, if at least one data has already been received, IDLE event is to be notified to user */ + uint16_t nb_rx_data = huart->RxXferSize - huart->RxXferCount; + if ((huart->RxXferCount > 0U) + && (nb_rx_data > 0U)) + { + /* Disable the UART Parity Error Interrupt and RXNE interrupts */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); + + /* Disable the UART Error Interrupt:(Frame error, noise error, overrun error) and RX FIFO Threshold interrupt */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE)); + + /* Rx process is completed, restore huart->RxState to Ready */ + huart->RxState = HAL_UART_STATE_READY; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + + /* Clear RxISR function pointer */ + huart->RxISR = NULL; + + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); + + /* Initialize type of RxEvent that correspond to RxEvent callback execution; + In this case, Rx Event type is Idle Event */ + huart->RxEventType = HAL_UART_RXEVENT_IDLE; + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered Rx complete callback*/ + huart->RxEventCallback(huart, nb_rx_data); +#else + /*Call legacy weak Rx Event callback*/ + HAL_UARTEx_RxEventCallback(huart, nb_rx_data); +#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ + } + return; +#if defined(HAL_DMA_MODULE_ENABLED) + } +#endif /* HAL_DMA_MODULE_ENABLED */ + } + + /* UART wakeup from Stop mode interrupt occurred ---------------------------*/ + if (((isrflags & USART_ISR_WUF) != 0U) && ((cr3its & USART_CR3_WUFIE) != 0U)) + { + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_WUF); + + /* UART Rx state is not reset as a reception process might be ongoing. + If UART handle state fields need to be reset to READY, this could be done in Wakeup callback */ + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /* Call registered Wakeup Callback */ + huart->WakeupCallback(huart); +#else + /* Call legacy weak Wakeup Callback */ + HAL_UARTEx_WakeupCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + return; + } + + /* UART in mode Transmitter ------------------------------------------------*/ + if (((isrflags & USART_ISR_TXE_TXFNF) != 0U) + && (((cr1its & USART_CR1_TXEIE_TXFNFIE) != 0U) + || ((cr3its & USART_CR3_TXFTIE) != 0U))) + { + if (huart->TxISR != NULL) + { + huart->TxISR(huart); + } + return; + } + + /* UART in mode Transmitter (transmission end) -----------------------------*/ + if (((isrflags & USART_ISR_TC) != 0U) && ((cr1its & USART_CR1_TCIE) != 0U)) + { + UART_EndTransmit_IT(huart); + return; + } + + /* UART TX Fifo Empty occurred ----------------------------------------------*/ + if (((isrflags & USART_ISR_TXFE) != 0U) && ((cr1its & USART_CR1_TXFEIE) != 0U)) + { +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /* Call registered Tx Fifo Empty Callback */ + huart->TxFifoEmptyCallback(huart); +#else + /* Call legacy weak Tx Fifo Empty Callback */ + HAL_UARTEx_TxFifoEmptyCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + return; + } + + /* UART RX Fifo Full occurred ----------------------------------------------*/ + if (((isrflags & USART_ISR_RXFF) != 0U) && ((cr1its & USART_CR1_RXFFIE) != 0U)) + { +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /* Call registered Rx Fifo Full Callback */ + huart->RxFifoFullCallback(huart); +#else + /* Call legacy weak Rx Fifo Full Callback */ + HAL_UARTEx_RxFifoFullCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + return; + } +} + +/** + * @brief Tx Transfer completed callback. + * @param huart UART handle. + * @retval None + */ +__weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(huart); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_UART_TxCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief Tx Half Transfer completed callback. + * @param huart UART handle. + * @retval None + */ +__weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(huart); + + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_UART_TxHalfCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief Rx Transfer completed callback. + * @param huart UART handle. + * @retval None + */ +__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(huart); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_UART_RxCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief Rx Half Transfer completed callback. + * @param huart UART handle. + * @retval None + */ +__weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(huart); + + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_UART_RxHalfCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief UART error callback. + * @param huart UART handle. + * @retval None + */ +__weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(huart); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_UART_ErrorCallback can be implemented in the user file. + */ +} + +/** + * @brief UART Abort Complete callback. + * @param huart UART handle. + * @retval None + */ +__weak void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(huart); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_UART_AbortCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief UART Abort Complete callback. + * @param huart UART handle. + * @retval None + */ +__weak void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(huart); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_UART_AbortTransmitCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief UART Abort Receive Complete callback. + * @param huart UART handle. + * @retval None + */ +__weak void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(huart); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_UART_AbortReceiveCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief Reception Event Callback (Rx event notification called after use of advanced reception service). + * @param huart UART handle + * @param Size Number of data available in application reception buffer (indicates a position in + * reception buffer until which, data are available) + * @retval None + */ +__weak void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(huart); + UNUSED(Size); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_UARTEx_RxEventCallback can be implemented in the user file. + */ +} + +/** + * @} + */ + +/** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions + * @brief UART control functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the UART. + (+) HAL_UART_ReceiverTimeout_Config() API allows to configure the receiver timeout value on the fly + (+) HAL_UART_EnableReceiverTimeout() API enables the receiver timeout feature + (+) HAL_UART_DisableReceiverTimeout() API disables the receiver timeout feature + (+) HAL_MultiProcessor_EnableMuteMode() API enables mute mode + (+) HAL_MultiProcessor_DisableMuteMode() API disables mute mode + (+) HAL_MultiProcessor_EnterMuteMode() API enters mute mode + (+) UART_SetConfig() API configures the UART peripheral + (+) UART_AdvFeatureConfig() API optionally configures the UART advanced features + (+) UART_CheckIdleState() API ensures that TEACK and/or REACK are set after initialization + (+) HAL_HalfDuplex_EnableTransmitter() API disables receiver and enables transmitter + (+) HAL_HalfDuplex_EnableReceiver() API disables transmitter and enables receiver + (+) HAL_LIN_SendBreak() API transmits the break characters +@endverbatim + * @{ + */ + +/** + * @brief Update on the fly the receiver timeout value in RTOR register. + * @param huart Pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @param TimeoutValue receiver timeout value in number of baud blocks. The timeout + * value must be less or equal to 0x0FFFFFFFF. + * @retval None + */ +void HAL_UART_ReceiverTimeout_Config(UART_HandleTypeDef *huart, uint32_t TimeoutValue) +{ + if (!(IS_LPUART_INSTANCE(huart->Instance))) + { + assert_param(IS_UART_RECEIVER_TIMEOUT_VALUE(TimeoutValue)); + MODIFY_REG(huart->Instance->RTOR, USART_RTOR_RTO, TimeoutValue); + } +} + +/** + * @brief Enable the UART receiver timeout feature. + * @param huart Pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_EnableReceiverTimeout(UART_HandleTypeDef *huart) +{ + if (!(IS_LPUART_INSTANCE(huart->Instance))) + { + if (huart->gState == HAL_UART_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(huart); + + huart->gState = HAL_UART_STATE_BUSY; + + /* Set the USART RTOEN bit */ + SET_BIT(huart->Instance->CR2, USART_CR2_RTOEN); + + huart->gState = HAL_UART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Disable the UART receiver timeout feature. + * @param huart Pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_DisableReceiverTimeout(UART_HandleTypeDef *huart) +{ + if (!(IS_LPUART_INSTANCE(huart->Instance))) + { + if (huart->gState == HAL_UART_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(huart); + + huart->gState = HAL_UART_STATE_BUSY; + + /* Clear the USART RTOEN bit */ + CLEAR_BIT(huart->Instance->CR2, USART_CR2_RTOEN); + + huart->gState = HAL_UART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Enable UART in mute mode (does not mean UART enters mute mode; + * to enter mute mode, HAL_MultiProcessor_EnterMuteMode() API must be called). + * @param huart UART handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MultiProcessor_EnableMuteMode(UART_HandleTypeDef *huart) +{ + __HAL_LOCK(huart); + + huart->gState = HAL_UART_STATE_BUSY; + + /* Enable USART mute mode by setting the MME bit in the CR1 register */ + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_MME); + + huart->gState = HAL_UART_STATE_READY; + + return (UART_CheckIdleState(huart)); +} + +/** + * @brief Disable UART mute mode (does not mean the UART actually exits mute mode + * as it may not have been in mute mode at this very moment). + * @param huart UART handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MultiProcessor_DisableMuteMode(UART_HandleTypeDef *huart) +{ + __HAL_LOCK(huart); + + huart->gState = HAL_UART_STATE_BUSY; + + /* Disable USART mute mode by clearing the MME bit in the CR1 register */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_MME); + + huart->gState = HAL_UART_STATE_READY; + + return (UART_CheckIdleState(huart)); +} + +/** + * @brief Enter UART mute mode (means UART actually enters mute mode). + * @note To exit from mute mode, HAL_MultiProcessor_DisableMuteMode() API must be called. + * @param huart UART handle. + * @retval None + */ +void HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart) +{ + __HAL_UART_SEND_REQ(huart, UART_MUTE_MODE_REQUEST); +} + +/** + * @brief Enable the UART transmitter and disable the UART receiver. + * @param huart UART handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart) +{ + __HAL_LOCK(huart); + huart->gState = HAL_UART_STATE_BUSY; + + /* Clear TE and RE bits */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE)); + + /* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */ + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TE); + + huart->gState = HAL_UART_STATE_READY; + + __HAL_UNLOCK(huart); + + return HAL_OK; +} + +/** + * @brief Enable the UART receiver and disable the UART transmitter. + * @param huart UART handle. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart) +{ + __HAL_LOCK(huart); + huart->gState = HAL_UART_STATE_BUSY; + + /* Clear TE and RE bits */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE)); + + /* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */ + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RE); + + huart->gState = HAL_UART_STATE_READY; + + __HAL_UNLOCK(huart); + + return HAL_OK; +} + + +/** + * @brief Transmit break characters. + * @param huart UART handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart) +{ + /* Check the parameters */ + assert_param(IS_UART_LIN_INSTANCE(huart->Instance)); + + __HAL_LOCK(huart); + + huart->gState = HAL_UART_STATE_BUSY; + + /* Send break characters */ + __HAL_UART_SEND_REQ(huart, UART_SENDBREAK_REQUEST); + + huart->gState = HAL_UART_STATE_READY; + + __HAL_UNLOCK(huart); + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup UART_Exported_Functions_Group4 Peripheral State and Error functions + * @brief UART Peripheral State functions + * +@verbatim + ============================================================================== + ##### Peripheral State and Error functions ##### + ============================================================================== + [..] + This subsection provides functions allowing to : + (+) Return the UART handle state. + (+) Return the UART handle error code + +@endverbatim + * @{ + */ + +/** + * @brief Return the UART handle state. + * @param huart Pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART. + * @retval HAL state + */ +HAL_UART_StateTypeDef HAL_UART_GetState(const UART_HandleTypeDef *huart) +{ + uint32_t temp1; + uint32_t temp2; + temp1 = huart->gState; + temp2 = huart->RxState; + + return (HAL_UART_StateTypeDef)(temp1 | temp2); +} + +/** + * @brief Return the UART handle error code. + * @param huart Pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART. + * @retval UART Error Code + */ +uint32_t HAL_UART_GetError(const UART_HandleTypeDef *huart) +{ + return huart->ErrorCode; +} +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup UART_Private_Functions UART Private Functions + * @{ + */ + +/** + * @brief Initialize the callbacks to their default values. + * @param huart UART handle. + * @retval none + */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) +void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart) +{ + /* Init the UART Callback settings */ + huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */ + huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */ + huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */ + huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */ + huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */ + huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ + huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */ + huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */ + huart->WakeupCallback = HAL_UARTEx_WakeupCallback; /* Legacy weak WakeupCallback */ + huart->RxFifoFullCallback = HAL_UARTEx_RxFifoFullCallback; /* Legacy weak RxFifoFullCallback */ + huart->TxFifoEmptyCallback = HAL_UARTEx_TxFifoEmptyCallback; /* Legacy weak TxFifoEmptyCallback */ + huart->RxEventCallback = HAL_UARTEx_RxEventCallback; /* Legacy weak RxEventCallback */ + +} +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + +/** + * @brief Configure the UART peripheral. + * @param huart UART handle. + * @retval HAL status + */ +HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart) +{ + uint32_t tmpreg; + uint16_t brrtemp; + uint32_t clocksource; + uint32_t usartdiv; + HAL_StatusTypeDef ret = HAL_OK; + uint32_t lpuart_ker_ck_pres; + uint32_t pclk; + + /* Check the parameters */ + assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate)); + assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength)); + if (UART_INSTANCE_LOWPOWER(huart)) + { + assert_param(IS_LPUART_STOPBITS(huart->Init.StopBits)); + } + else + { + assert_param(IS_UART_STOPBITS(huart->Init.StopBits)); + assert_param(IS_UART_ONE_BIT_SAMPLE(huart->Init.OneBitSampling)); + } + + assert_param(IS_UART_PARITY(huart->Init.Parity)); + assert_param(IS_UART_MODE(huart->Init.Mode)); + assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl)); + assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling)); + assert_param(IS_UART_PRESCALER(huart->Init.ClockPrescaler)); + + /*-------------------------- USART CR1 Configuration -----------------------*/ + /* Clear M, PCE, PS, TE, RE and OVER8 bits and configure + * the UART Word Length, Parity, Mode and oversampling: + * set the M bits according to huart->Init.WordLength value + * set PCE and PS bits according to huart->Init.Parity value + * set TE and RE bits according to huart->Init.Mode value + * set OVER8 bit according to huart->Init.OverSampling value */ + tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling ; + MODIFY_REG(huart->Instance->CR1, USART_CR1_FIELDS, tmpreg); + + /*-------------------------- USART CR2 Configuration -----------------------*/ + /* Configure the UART Stop Bits: Set STOP[13:12] bits according + * to huart->Init.StopBits value */ + MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits); + + /*-------------------------- USART CR3 Configuration -----------------------*/ + /* Configure + * - UART HardWare Flow Control: set CTSE and RTSE bits according + * to huart->Init.HwFlowCtl value + * - one-bit sampling method versus three samples' majority rule according + * to huart->Init.OneBitSampling (not applicable to LPUART) */ + tmpreg = (uint32_t)huart->Init.HwFlowCtl; + + if (!(UART_INSTANCE_LOWPOWER(huart))) + { + tmpreg |= huart->Init.OneBitSampling; + } + MODIFY_REG(huart->Instance->CR3, USART_CR3_FIELDS, tmpreg); + + /*-------------------------- USART PRESC Configuration -----------------------*/ + /* Configure + * - UART Clock Prescaler : set PRESCALER according to huart->Init.ClockPrescaler value */ + MODIFY_REG(huart->Instance->PRESC, USART_PRESC_PRESCALER, huart->Init.ClockPrescaler); + + /*-------------------------- USART BRR Configuration -----------------------*/ + UART_GETCLOCKSOURCE(huart, clocksource); + + /* Check LPUART instance */ + if (UART_INSTANCE_LOWPOWER(huart)) + { + /* Retrieve frequency clock */ + pclk = HAL_RCCEx_GetPeriphCLKFreq(clocksource); + + /* If proper clock source reported */ + if (pclk != 0U) + { + /* Compute clock after Prescaler */ + lpuart_ker_ck_pres = (pclk / UARTPrescTable[huart->Init.ClockPrescaler]); + + /* Ensure that Frequency clock is in the range [3 * baudrate, 4096 * baudrate] */ + if ((lpuart_ker_ck_pres < (3U * huart->Init.BaudRate)) || + (lpuart_ker_ck_pres > (4096U * huart->Init.BaudRate))) + { + ret = HAL_ERROR; + } + else + { + /* Check computed UsartDiv value is in allocated range + (it is forbidden to write values lower than 0x300 in the LPUART_BRR register) */ + usartdiv = (uint32_t)(UART_DIV_LPUART(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler)); + if ((usartdiv >= LPUART_BRR_MIN) && (usartdiv <= LPUART_BRR_MAX)) + { + huart->Instance->BRR = usartdiv; + } + else + { + ret = HAL_ERROR; + } + } /* if ( (lpuart_ker_ck_pres < (3 * huart->Init.BaudRate) ) || + (lpuart_ker_ck_pres > (4096 * huart->Init.BaudRate) )) */ + } /* if (pclk != 0) */ + } + /* Check UART Over Sampling to set Baud Rate Register */ + else if (huart->Init.OverSampling == UART_OVERSAMPLING_8) + { + pclk = HAL_RCCEx_GetPeriphCLKFreq(clocksource); + + /* USARTDIV must be greater than or equal to 0d16 */ + if (pclk != 0U) + { + usartdiv = (uint32_t)(UART_DIV_SAMPLING8(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler)); + if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX)) + { + brrtemp = (uint16_t)(usartdiv & 0xFFF0U); + brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U); + huart->Instance->BRR = brrtemp; + } + else + { + ret = HAL_ERROR; + } + } + } + else + { + pclk = HAL_RCCEx_GetPeriphCLKFreq(clocksource); + + if (pclk != 0U) + { + /* USARTDIV must be greater than or equal to 0d16 */ + usartdiv = (uint32_t)(UART_DIV_SAMPLING16(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler)); + if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX)) + { + huart->Instance->BRR = (uint16_t)usartdiv; + } + else + { + ret = HAL_ERROR; + } + } + } + + /* Initialize the number of data to process during RX/TX ISR execution */ + huart->NbTxDataToProcess = 1; + huart->NbRxDataToProcess = 1; + + /* Clear ISR function pointers */ + huart->RxISR = NULL; + huart->TxISR = NULL; + + return ret; +} + +/** + * @brief Configure the UART peripheral advanced features. + * @param huart UART handle. + * @retval None + */ +void UART_AdvFeatureConfig(UART_HandleTypeDef *huart) +{ + /* Check whether the set of advanced features to configure is properly set */ + assert_param(IS_UART_ADVFEATURE_INIT(huart->AdvancedInit.AdvFeatureInit)); + + /* if required, configure RX/TX pins swap */ + if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_SWAP_INIT)) + { + assert_param(IS_UART_ADVFEATURE_SWAP(huart->AdvancedInit.Swap)); + MODIFY_REG(huart->Instance->CR2, USART_CR2_SWAP, huart->AdvancedInit.Swap); + } + + /* if required, configure TX pin active level inversion */ + if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_TXINVERT_INIT)) + { + assert_param(IS_UART_ADVFEATURE_TXINV(huart->AdvancedInit.TxPinLevelInvert)); + MODIFY_REG(huart->Instance->CR2, USART_CR2_TXINV, huart->AdvancedInit.TxPinLevelInvert); + } + + /* if required, configure RX pin active level inversion */ + if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXINVERT_INIT)) + { + assert_param(IS_UART_ADVFEATURE_RXINV(huart->AdvancedInit.RxPinLevelInvert)); + MODIFY_REG(huart->Instance->CR2, USART_CR2_RXINV, huart->AdvancedInit.RxPinLevelInvert); + } + + /* if required, configure data inversion */ + if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DATAINVERT_INIT)) + { + assert_param(IS_UART_ADVFEATURE_DATAINV(huart->AdvancedInit.DataInvert)); + MODIFY_REG(huart->Instance->CR2, USART_CR2_DATAINV, huart->AdvancedInit.DataInvert); + } + + /* if required, configure RX overrun detection disabling */ + if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_RXOVERRUNDISABLE_INIT)) + { + assert_param(IS_UART_OVERRUN(huart->AdvancedInit.OverrunDisable)); + MODIFY_REG(huart->Instance->CR3, USART_CR3_OVRDIS, huart->AdvancedInit.OverrunDisable); + } + +#if defined(HAL_DMA_MODULE_ENABLED) + /* if required, configure DMA disabling on reception error */ + if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_DMADISABLEONERROR_INIT)) + { + assert_param(IS_UART_ADVFEATURE_DMAONRXERROR(huart->AdvancedInit.DMADisableonRxError)); + MODIFY_REG(huart->Instance->CR3, USART_CR3_DDRE, huart->AdvancedInit.DMADisableonRxError); + } +#endif /* HAL_DMA_MODULE_ENABLED */ + + /* if required, configure auto Baud rate detection scheme */ + if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_AUTOBAUDRATE_INIT)) + { + assert_param(IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(huart->Instance)); + assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATE(huart->AdvancedInit.AutoBaudRateEnable)); + MODIFY_REG(huart->Instance->CR2, USART_CR2_ABREN, huart->AdvancedInit.AutoBaudRateEnable); + /* set auto Baudrate detection parameters if detection is enabled */ + if (huart->AdvancedInit.AutoBaudRateEnable == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE) + { + assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(huart->AdvancedInit.AutoBaudRateMode)); + MODIFY_REG(huart->Instance->CR2, USART_CR2_ABRMODE, huart->AdvancedInit.AutoBaudRateMode); + } + } + + /* if required, configure MSB first on communication line */ + if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_MSBFIRST_INIT)) + { + assert_param(IS_UART_ADVFEATURE_MSBFIRST(huart->AdvancedInit.MSBFirst)); + MODIFY_REG(huart->Instance->CR2, USART_CR2_MSBFIRST, huart->AdvancedInit.MSBFirst); + } +} + +/** + * @brief Check the UART Idle State. + * @param huart UART handle. + * @retval HAL status + */ +HAL_StatusTypeDef UART_CheckIdleState(UART_HandleTypeDef *huart) +{ + uint32_t tickstart; + + /* Initialize the UART ErrorCode */ + huart->ErrorCode = HAL_UART_ERROR_NONE; + + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + + /* Check if the Transmitter is enabled */ + if ((huart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE) + { + /* Wait until TEACK flag is set */ + if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_TEACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK) + { + /* Disable TXE interrupt for the interrupt process */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE)); + + huart->gState = HAL_UART_STATE_READY; + + __HAL_UNLOCK(huart); + + /* Timeout occurred */ + return HAL_TIMEOUT; + } + } + + /* Check if the Receiver is enabled */ + if ((huart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE) + { + /* Wait until REACK flag is set */ + if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK) + { + /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) + interrupts for the interrupt process */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); + + huart->RxState = HAL_UART_STATE_READY; + + __HAL_UNLOCK(huart); + + /* Timeout occurred */ + return HAL_TIMEOUT; + } + } + + /* Initialize the UART State */ + huart->gState = HAL_UART_STATE_READY; + huart->RxState = HAL_UART_STATE_READY; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + huart->RxEventType = HAL_UART_RXEVENT_TC; + + __HAL_UNLOCK(huart); + + return HAL_OK; +} + +/** + * @brief This function handles UART Communication Timeout. It waits + * until a flag is no longer in the specified status. + * @param huart UART handle. + * @param Flag Specifies the UART flag to check + * @param Status The actual Flag status (SET or RESET) + * @param Tickstart Tick start value + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, + uint32_t Tickstart, uint32_t Timeout) +{ + /* Wait until flag is set */ + while ((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + { + + return HAL_TIMEOUT; + } + + if (READ_BIT(huart->Instance->CR1, USART_CR1_RE) != 0U) + { + if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) == SET) + { + /* Clear Overrun Error flag*/ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF); + + /* Blocking error : transfer is aborted + Set the UART state ready to be able to start again the process, + Disable Rx Interrupts if ongoing */ + UART_EndRxTransfer(huart); + + huart->ErrorCode = HAL_UART_ERROR_ORE; + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return HAL_ERROR; + } + if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RTOF) == SET) + { + /* Clear Receiver Timeout flag*/ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_RTOF); + + /* Blocking error : transfer is aborted + Set the UART state ready to be able to start again the process, + Disable Rx Interrupts if ongoing */ + UART_EndRxTransfer(huart); + + huart->ErrorCode = HAL_UART_ERROR_RTO; + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return HAL_TIMEOUT; + } + } + } + } + return HAL_OK; +} + +/** + * @brief Start Receive operation in interrupt mode. + * @note This function could be called by all HAL UART API providing reception in Interrupt mode. + * @note When calling this function, parameters validity is considered as already checked, + * i.e. Rx State, buffer address, ... + * UART Handle is assumed as Locked. + * @param huart UART handle. + * @param pData Pointer to data buffer (u8 or u16 data elements). + * @param Size Amount of data elements (u8 or u16) to be received. + * @retval HAL status + */ +HAL_StatusTypeDef UART_Start_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) +{ + huart->pRxBuffPtr = pData; + huart->RxXferSize = Size; + huart->RxXferCount = Size; + huart->RxISR = NULL; + + /* Computation of UART mask to apply to RDR register */ + UART_MASK_COMPUTATION(huart); + + huart->ErrorCode = HAL_UART_ERROR_NONE; + huart->RxState = HAL_UART_STATE_BUSY_RX; + + /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ + ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE); + + /* Configure Rx interrupt processing */ + if ((huart->FifoMode == UART_FIFOMODE_ENABLE) && (Size >= huart->NbRxDataToProcess)) + { + /* Set the Rx ISR function pointer according to the data word length */ + if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) + { + huart->RxISR = UART_RxISR_16BIT_FIFOEN; + } + else + { + huart->RxISR = UART_RxISR_8BIT_FIFOEN; + } + + /* Enable the UART Parity Error interrupt and RX FIFO Threshold interrupt */ + if (huart->Init.Parity != UART_PARITY_NONE) + { + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE); + } + ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_RXFTIE); + } + else + { + /* Set the Rx ISR function pointer according to the data word length */ + if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) + { + huart->RxISR = UART_RxISR_16BIT; + } + else + { + huart->RxISR = UART_RxISR_8BIT; + } + + /* Enable the UART Parity Error interrupt and Data Register Not Empty interrupt */ + if (huart->Init.Parity != UART_PARITY_NONE) + { + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE); + } + else + { + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE); + } + } + return HAL_OK; +} + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief Start Receive operation in DMA mode. + * @note This function could be called by all HAL UART API providing reception in DMA mode. + * @note When calling this function, parameters validity is considered as already checked, + * i.e. Rx State, buffer address, ... + * UART Handle is assumed as Locked. + * @param huart UART handle. + * @param pData Pointer to data buffer (u8 or u16 data elements). + * @param Size Amount of data elements (u8 or u16) to be received. + * @retval HAL status + */ +HAL_StatusTypeDef UART_Start_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) +{ + HAL_StatusTypeDef status; + uint16_t nbByte = Size; + + huart->pRxBuffPtr = pData; + huart->RxXferSize = Size; + + huart->ErrorCode = HAL_UART_ERROR_NONE; + huart->RxState = HAL_UART_STATE_BUSY_RX; + + if (huart->hdmarx != NULL) + { + /* Set the UART DMA transfer complete callback */ + huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt; + + /* Set the UART DMA Half transfer complete callback */ + huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt; + + /* Set the DMA error callback */ + huart->hdmarx->XferErrorCallback = UART_DMAError; + + /* Set the DMA abort callback */ + huart->hdmarx->XferAbortCallback = NULL; + + /* In case of 9bits/No Parity transfer, pData buffer provided as input parameter + should be aligned on a u16 frontier, so nbByte should be equal to Size * 2 */ + if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) + { + nbByte = Size * 2U; + } + + /* Check linked list mode */ + if ((huart->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((huart->hdmarx->LinkedListQueue != NULL) && (huart->hdmarx->LinkedListQueue->Head != NULL)) + { + /* Set DMA data size */ + huart->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = nbByte; + + /* Set DMA source address */ + huart->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = + (uint32_t)&huart->Instance->RDR; + + /* Set DMA destination address */ + huart->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)huart->pRxBuffPtr; + + /* Enable the UART receive DMA channel */ + status = HAL_DMAEx_List_Start_IT(huart->hdmarx); + } + else + { + /* Update status */ + status = HAL_ERROR; + } + } + else + { + /* Enable the UART receive DMA channel */ + status = HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->RDR, (uint32_t)huart->pRxBuffPtr, nbByte); + } + + if (status != HAL_OK) + { + /* Set error code to DMA */ + huart->ErrorCode = HAL_UART_ERROR_DMA; + + /* Restore huart->RxState to ready */ + huart->RxState = HAL_UART_STATE_READY; + + return HAL_ERROR; + } + } + + /* Enable the UART Parity Error Interrupt */ + if (huart->Init.Parity != UART_PARITY_NONE) + { + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_PEIE); + } + + /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ + ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_EIE); + + /* Enable the DMA transfer for the receiver request by setting the DMAR bit + in the UART CR3 register */ + ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAR); + + return HAL_OK; +} + + +/** + * @brief End ongoing Tx transfer on UART peripheral (following error detection or Transmit completion). + * @param huart UART handle. + * @retval None + */ +static void UART_EndTxTransfer(UART_HandleTypeDef *huart) +{ + /* Disable TXEIE, TCIE, TXFT interrupts */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE)); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_TXFTIE)); + + /* At end of Tx process, restore huart->gState to Ready */ + huart->gState = HAL_UART_STATE_READY; +} +#endif /* HAL_DMA_MODULE_ENABLED */ + + +/** + * @brief End ongoing Rx transfer on UART peripheral (following error detection or Reception completion). + * @param huart UART handle. + * @retval None + */ +static void UART_EndRxTransfer(UART_HandleTypeDef *huart) +{ + /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE)); + + /* In case of reception waiting for IDLE event, disable also the IDLE IE interrupt source */ + if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + { + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); + } + + /* At end of Rx process, restore huart->RxState to Ready */ + huart->RxState = HAL_UART_STATE_READY; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + + /* Reset RxIsr function pointer */ + huart->RxISR = NULL; +} + + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief DMA UART transmit process complete callback. + * @param hdma DMA handle. + * @retval None + */ +static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); + + /* Check if DMA in circular mode */ + if (hdma->Mode != DMA_LINKEDLIST_CIRCULAR) + { + huart->TxXferCount = 0U; + + /* Enable the UART Transmit Complete Interrupt */ + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); + } + /* DMA Circular mode */ + else + { +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered Tx complete callback*/ + huart->TxCpltCallback(huart); +#else + /*Call legacy weak Tx complete callback*/ + HAL_UART_TxCpltCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + } +} + +/** + * @brief DMA UART transmit process half complete callback. + * @param hdma DMA handle. + * @retval None + */ +static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered Tx Half complete callback*/ + huart->TxHalfCpltCallback(huart); +#else + /*Call legacy weak Tx Half complete callback*/ + HAL_UART_TxHalfCpltCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA UART receive process complete callback. + * @param hdma DMA handle. + * @retval None + */ +static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); + + /* Check if DMA in circular mode */ + if (hdma->Mode != DMA_LINKEDLIST_CIRCULAR) + { + huart->RxXferCount = 0U; + + /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); + + /* At end of Rx process, restore huart->RxState to Ready */ + huart->RxState = HAL_UART_STATE_READY; + + /* If Reception till IDLE event has been selected, Disable IDLE Interrupt */ + if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + { + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); + } + } + + /* Initialize type of RxEvent that correspond to RxEvent callback execution; + In this case, Rx Event type is Transfer Complete */ + huart->RxEventType = HAL_UART_RXEVENT_TC; + + /* Check current reception Mode : + If Reception till IDLE event has been selected : use Rx Event callback */ + if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + { +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered Rx Event callback*/ + huart->RxEventCallback(huart, huart->RxXferSize); +#else + /*Call legacy weak Rx Event callback*/ + HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + } + else + { + /* In other cases : use Rx Complete callback */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered Rx complete callback*/ + huart->RxCpltCallback(huart); +#else + /*Call legacy weak Rx complete callback*/ + HAL_UART_RxCpltCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + } +} + +/** + * @brief DMA UART receive process half complete callback. + * @param hdma DMA handle. + * @retval None + */ +static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); + + /* Initialize type of RxEvent that correspond to RxEvent callback execution; + In this case, Rx Event type is Half Transfer */ + huart->RxEventType = HAL_UART_RXEVENT_HT; + + /* Check current reception Mode : + If Reception till IDLE event has been selected : use Rx Event callback */ + if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + { +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered Rx Event callback*/ + huart->RxEventCallback(huart, huart->RxXferSize / 2U); +#else + /*Call legacy weak Rx Event callback*/ + HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize / 2U); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + } + else + { + /* In other cases : use Rx Half Complete callback */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered Rx Half complete callback*/ + huart->RxHalfCpltCallback(huart); +#else + /*Call legacy weak Rx Half complete callback*/ + HAL_UART_RxHalfCpltCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + } +} + +/** + * @brief DMA UART communication error callback. + * @param hdma DMA handle. + * @retval None + */ +static void UART_DMAError(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); + + const HAL_UART_StateTypeDef gstate = huart->gState; + const HAL_UART_StateTypeDef rxstate = huart->RxState; + + /* Stop UART DMA Tx request if ongoing */ + if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT)) && + (gstate == HAL_UART_STATE_BUSY_TX)) + { + huart->TxXferCount = 0U; + UART_EndTxTransfer(huart); + } + + /* Stop UART DMA Rx request if ongoing */ + if ((HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) && + (rxstate == HAL_UART_STATE_BUSY_RX)) + { + huart->RxXferCount = 0U; + UART_EndRxTransfer(huart); + } + + huart->ErrorCode |= HAL_UART_ERROR_DMA; + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered error callback*/ + huart->ErrorCallback(huart); +#else + /*Call legacy weak error callback*/ + HAL_UART_ErrorCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA UART communication abort callback, when initiated by HAL services on Error + * (To be called at end of DMA Abort procedure following error occurrence). + * @param hdma DMA handle. + * @retval None + */ +static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); + huart->RxXferCount = 0U; + huart->TxXferCount = 0U; + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered error callback*/ + huart->ErrorCallback(huart); +#else + /*Call legacy weak error callback*/ + HAL_UART_ErrorCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA UART Tx communication abort callback, when initiated by user + * (To be called at end of DMA Tx Abort procedure following user abort request). + * @note When this callback is executed, User Abort complete call back is called only if no + * Abort still ongoing for Rx DMA Handle. + * @param hdma DMA handle. + * @retval None + */ +static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); + + huart->hdmatx->XferAbortCallback = NULL; + + /* Check if an Abort process is still ongoing */ + if (huart->hdmarx != NULL) + { + if (huart->hdmarx->XferAbortCallback != NULL) + { + return; + } + } + + /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ + huart->TxXferCount = 0U; + huart->RxXferCount = 0U; + + /* Reset errorCode */ + huart->ErrorCode = HAL_UART_ERROR_NONE; + + /* Clear the Error flags in the ICR register */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); + + /* Flush the whole TX FIFO (if needed) */ + if (huart->FifoMode == UART_FIFOMODE_ENABLE) + { + __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST); + } + + /* Restore huart->gState and huart->RxState to Ready */ + huart->gState = HAL_UART_STATE_READY; + huart->RxState = HAL_UART_STATE_READY; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + + /* Call user Abort complete callback */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /* Call registered Abort complete callback */ + huart->AbortCpltCallback(huart); +#else + /* Call legacy weak Abort complete callback */ + HAL_UART_AbortCpltCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ +} + + +/** + * @brief DMA UART Rx communication abort callback, when initiated by user + * (To be called at end of DMA Rx Abort procedure following user abort request). + * @note When this callback is executed, User Abort complete call back is called only if no + * Abort still ongoing for Tx DMA Handle. + * @param hdma DMA handle. + * @retval None + */ +static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); + + huart->hdmarx->XferAbortCallback = NULL; + + /* Check if an Abort process is still ongoing */ + if (huart->hdmatx != NULL) + { + if (huart->hdmatx->XferAbortCallback != NULL) + { + return; + } + } + + /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ + huart->TxXferCount = 0U; + huart->RxXferCount = 0U; + + /* Reset errorCode */ + huart->ErrorCode = HAL_UART_ERROR_NONE; + + /* Clear the Error flags in the ICR register */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); + + /* Discard the received data */ + __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); + + /* Restore huart->gState and huart->RxState to Ready */ + huart->gState = HAL_UART_STATE_READY; + huart->RxState = HAL_UART_STATE_READY; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + + /* Call user Abort complete callback */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /* Call registered Abort complete callback */ + huart->AbortCpltCallback(huart); +#else + /* Call legacy weak Abort complete callback */ + HAL_UART_AbortCpltCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ +} + + +/** + * @brief DMA UART Tx communication abort callback, when initiated by user by a call to + * HAL_UART_AbortTransmit_IT API (Abort only Tx transfer) + * (This callback is executed at end of DMA Tx Abort procedure following user abort request, + * and leads to user Tx Abort Complete callback execution). + * @param hdma DMA handle. + * @retval None + */ +static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent); + + huart->TxXferCount = 0U; + + /* Flush the whole TX FIFO (if needed) */ + if (huart->FifoMode == UART_FIFOMODE_ENABLE) + { + __HAL_UART_SEND_REQ(huart, UART_TXDATA_FLUSH_REQUEST); + } + + /* Restore huart->gState to Ready */ + huart->gState = HAL_UART_STATE_READY; + + /* Call user Abort complete callback */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /* Call registered Abort Transmit Complete Callback */ + huart->AbortTransmitCpltCallback(huart); +#else + /* Call legacy weak Abort Transmit Complete Callback */ + HAL_UART_AbortTransmitCpltCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA UART Rx communication abort callback, when initiated by user by a call to + * HAL_UART_AbortReceive_IT API (Abort only Rx transfer) + * (This callback is executed at end of DMA Rx Abort procedure following user abort request, + * and leads to user Rx Abort Complete callback execution). + * @param hdma DMA handle. + * @retval None + */ +static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + huart->RxXferCount = 0U; + + /* Clear the Error flags in the ICR register */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF); + + /* Discard the received data */ + __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); + + /* Restore huart->RxState to Ready */ + huart->RxState = HAL_UART_STATE_READY; + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + + /* Call user Abort complete callback */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /* Call registered Abort Receive Complete Callback */ + huart->AbortReceiveCpltCallback(huart); +#else + /* Call legacy weak Abort Receive Complete Callback */ + HAL_UART_AbortReceiveCpltCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief TX interrupt handler for 7 or 8 bits data word length . + * @note Function is called under interruption only, once + * interruptions have been enabled by HAL_UART_Transmit_IT(). + * @param huart UART handle. + * @retval None + */ +static void UART_TxISR_8BIT(UART_HandleTypeDef *huart) +{ + /* Check that a Tx process is ongoing */ + if (huart->gState == HAL_UART_STATE_BUSY_TX) + { + if (huart->TxXferCount == 0U) + { + /* Disable the UART Transmit Data Register Empty Interrupt */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE); + + /* Enable the UART Transmit Complete Interrupt */ + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); + } + else + { + huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr & (uint8_t)0xFF); + huart->pTxBuffPtr++; + huart->TxXferCount--; + } + } +} + +/** + * @brief TX interrupt handler for 9 bits data word length. + * @note Function is called under interruption only, once + * interruptions have been enabled by HAL_UART_Transmit_IT(). + * @param huart UART handle. + * @retval None + */ +static void UART_TxISR_16BIT(UART_HandleTypeDef *huart) +{ + const uint16_t *tmp; + + /* Check that a Tx process is ongoing */ + if (huart->gState == HAL_UART_STATE_BUSY_TX) + { + if (huart->TxXferCount == 0U) + { + /* Disable the UART Transmit Data Register Empty Interrupt */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE); + + /* Enable the UART Transmit Complete Interrupt */ + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); + } + else + { + tmp = (const uint16_t *) huart->pTxBuffPtr; + huart->Instance->TDR = (((uint32_t)(*tmp)) & 0x01FFUL); + huart->pTxBuffPtr += 2U; + huart->TxXferCount--; + } + } +} + +/** + * @brief TX interrupt handler for 7 or 8 bits data word length and FIFO mode is enabled. + * @note Function is called under interruption only, once + * interruptions have been enabled by HAL_UART_Transmit_IT(). + * @param huart UART handle. + * @retval None + */ +static void UART_TxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart) +{ + uint16_t nb_tx_data; + + /* Check that a Tx process is ongoing */ + if (huart->gState == HAL_UART_STATE_BUSY_TX) + { + for (nb_tx_data = huart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--) + { + if (huart->TxXferCount == 0U) + { + /* Disable the TX FIFO threshold interrupt */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE); + + /* Enable the UART Transmit Complete Interrupt */ + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); + + break; /* force exit loop */ + } + else if (READ_BIT(huart->Instance->ISR, USART_ISR_TXE_TXFNF) != 0U) + { + huart->Instance->TDR = (uint8_t)(*huart->pTxBuffPtr & (uint8_t)0xFF); + huart->pTxBuffPtr++; + huart->TxXferCount--; + } + else + { + /* Nothing to do */ + } + } + } +} + +/** + * @brief TX interrupt handler for 9 bits data word length and FIFO mode is enabled. + * @note Function is called under interruption only, once + * interruptions have been enabled by HAL_UART_Transmit_IT(). + * @param huart UART handle. + * @retval None + */ +static void UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart) +{ + const uint16_t *tmp; + uint16_t nb_tx_data; + + /* Check that a Tx process is ongoing */ + if (huart->gState == HAL_UART_STATE_BUSY_TX) + { + for (nb_tx_data = huart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--) + { + if (huart->TxXferCount == 0U) + { + /* Disable the TX FIFO threshold interrupt */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_TXFTIE); + + /* Enable the UART Transmit Complete Interrupt */ + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE); + + break; /* force exit loop */ + } + else if (READ_BIT(huart->Instance->ISR, USART_ISR_TXE_TXFNF) != 0U) + { + tmp = (const uint16_t *) huart->pTxBuffPtr; + huart->Instance->TDR = (((uint32_t)(*tmp)) & 0x01FFUL); + huart->pTxBuffPtr += 2U; + huart->TxXferCount--; + } + else + { + /* Nothing to do */ + } + } + } +} + +/** + * @brief Wrap up transmission in non-blocking mode. + * @param huart pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval None + */ +static void UART_EndTransmit_IT(UART_HandleTypeDef *huart) +{ + /* Disable the UART Transmit Complete Interrupt */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_TCIE); + + /* Tx process is ended, restore huart->gState to Ready */ + huart->gState = HAL_UART_STATE_READY; + + /* Cleat TxISR function pointer */ + huart->TxISR = NULL; + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered Tx complete callback*/ + huart->TxCpltCallback(huart); +#else + /*Call legacy weak Tx complete callback*/ + HAL_UART_TxCpltCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ +} + +/** + * @brief RX interrupt handler for 7 or 8 bits data word length . + * @param huart UART handle. + * @retval None + */ +static void UART_RxISR_8BIT(UART_HandleTypeDef *huart) +{ + uint16_t uhMask = huart->Mask; + uint16_t uhdata; + + /* Check that a Rx process is ongoing */ + if (huart->RxState == HAL_UART_STATE_BUSY_RX) + { + uhdata = (uint16_t) READ_REG(huart->Instance->RDR); + *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask); + huart->pRxBuffPtr++; + huart->RxXferCount--; + + if (huart->RxXferCount == 0U) + { + /* Disable the UART Parity Error Interrupt and RXNE interrupts */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); + + /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); + + /* Rx process is completed, restore huart->RxState to Ready */ + huart->RxState = HAL_UART_STATE_READY; + + /* Clear RxISR function pointer */ + huart->RxISR = NULL; + + /* Initialize type of RxEvent to Transfer Complete */ + huart->RxEventType = HAL_UART_RXEVENT_TC; + + if (!(IS_LPUART_INSTANCE(huart->Instance))) + { + /* Check that USART RTOEN bit is set */ + if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U) + { + /* Enable the UART Receiver Timeout Interrupt */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RTOIE); + } + } + + /* Check current reception Mode : + If Reception till IDLE event has been selected : */ + if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + { + /* Set reception type to Standard */ + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + + /* Disable IDLE interrupt */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); + + if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET) + { + /* Clear IDLE Flag */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); + } + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered Rx Event callback*/ + huart->RxEventCallback(huart, huart->RxXferSize); +#else + /*Call legacy weak Rx Event callback*/ + HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize); +#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ + } + else + { + /* Standard reception API called */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered Rx complete callback*/ + huart->RxCpltCallback(huart); +#else + /*Call legacy weak Rx complete callback*/ + HAL_UART_RxCpltCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + } + } + } + else + { + /* Clear RXNE interrupt flag */ + __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); + } +} + +/** + * @brief RX interrupt handler for 9 bits data word length . + * @note Function is called under interruption only, once + * interruptions have been enabled by HAL_UART_Receive_IT() + * @param huart UART handle. + * @retval None + */ +static void UART_RxISR_16BIT(UART_HandleTypeDef *huart) +{ + uint16_t *tmp; + uint16_t uhMask = huart->Mask; + uint16_t uhdata; + + /* Check that a Rx process is ongoing */ + if (huart->RxState == HAL_UART_STATE_BUSY_RX) + { + uhdata = (uint16_t) READ_REG(huart->Instance->RDR); + tmp = (uint16_t *) huart->pRxBuffPtr ; + *tmp = (uint16_t)(uhdata & uhMask); + huart->pRxBuffPtr += 2U; + huart->RxXferCount--; + + if (huart->RxXferCount == 0U) + { + /* Disable the UART Parity Error Interrupt and RXNE interrupt*/ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); + + /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); + + /* Rx process is completed, restore huart->RxState to Ready */ + huart->RxState = HAL_UART_STATE_READY; + + /* Clear RxISR function pointer */ + huart->RxISR = NULL; + + /* Initialize type of RxEvent to Transfer Complete */ + huart->RxEventType = HAL_UART_RXEVENT_TC; + + if (!(IS_LPUART_INSTANCE(huart->Instance))) + { + /* Check that USART RTOEN bit is set */ + if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U) + { + /* Enable the UART Receiver Timeout Interrupt */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RTOIE); + } + } + + /* Check current reception Mode : + If Reception till IDLE event has been selected : */ + if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + { + /* Set reception type to Standard */ + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + + /* Disable IDLE interrupt */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); + + if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET) + { + /* Clear IDLE Flag */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); + } + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered Rx Event callback*/ + huart->RxEventCallback(huart, huart->RxXferSize); +#else + /*Call legacy weak Rx Event callback*/ + HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize); +#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ + } + else + { + /* Standard reception API called */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered Rx complete callback*/ + huart->RxCpltCallback(huart); +#else + /*Call legacy weak Rx complete callback*/ + HAL_UART_RxCpltCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + } + } + } + else + { + /* Clear RXNE interrupt flag */ + __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); + } +} + +/** + * @brief RX interrupt handler for 7 or 8 bits data word length and FIFO mode is enabled. + * @note Function is called under interruption only, once + * interruptions have been enabled by HAL_UART_Receive_IT() + * @param huart UART handle. + * @retval None + */ +static void UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart) +{ + uint16_t uhMask = huart->Mask; + uint16_t uhdata; + uint16_t nb_rx_data; + uint16_t rxdatacount; + uint32_t isrflags = READ_REG(huart->Instance->ISR); + uint32_t cr1its = READ_REG(huart->Instance->CR1); + uint32_t cr3its = READ_REG(huart->Instance->CR3); + + /* Check that a Rx process is ongoing */ + if (huart->RxState == HAL_UART_STATE_BUSY_RX) + { + nb_rx_data = huart->NbRxDataToProcess; + while ((nb_rx_data > 0U) && ((isrflags & USART_ISR_RXNE_RXFNE) != 0U)) + { + uhdata = (uint16_t) READ_REG(huart->Instance->RDR); + *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask); + huart->pRxBuffPtr++; + huart->RxXferCount--; + isrflags = READ_REG(huart->Instance->ISR); + + /* If some non blocking errors occurred */ + if ((isrflags & (USART_ISR_PE | USART_ISR_FE | USART_ISR_NE)) != 0U) + { + /* UART parity error interrupt occurred -------------------------------------*/ + if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U)) + { + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF); + + huart->ErrorCode |= HAL_UART_ERROR_PE; + } + + /* UART frame error interrupt occurred --------------------------------------*/ + if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) + { + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF); + + huart->ErrorCode |= HAL_UART_ERROR_FE; + } + + /* UART noise error interrupt occurred --------------------------------------*/ + if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) + { + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF); + + huart->ErrorCode |= HAL_UART_ERROR_NE; + } + + /* Call UART Error Call back function if need be ----------------------------*/ + if (huart->ErrorCode != HAL_UART_ERROR_NONE) + { + /* Non Blocking error : transfer could go on. + Error is notified to user through user error callback */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered error callback*/ + huart->ErrorCallback(huart); +#else + /*Call legacy weak error callback*/ + HAL_UART_ErrorCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + huart->ErrorCode = HAL_UART_ERROR_NONE; + } + } + + if (huart->RxXferCount == 0U) + { + /* Disable the UART Parity Error Interrupt and RXFT interrupt*/ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); + + /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) + and RX FIFO Threshold interrupt */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE)); + + /* Rx process is completed, restore huart->RxState to Ready */ + huart->RxState = HAL_UART_STATE_READY; + + /* Clear RxISR function pointer */ + huart->RxISR = NULL; + + /* Initialize type of RxEvent to Transfer Complete */ + huart->RxEventType = HAL_UART_RXEVENT_TC; + + if (!(IS_LPUART_INSTANCE(huart->Instance))) + { + /* Check that USART RTOEN bit is set */ + if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U) + { + /* Enable the UART Receiver Timeout Interrupt */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RTOIE); + } + } + + /* Check current reception Mode : + If Reception till IDLE event has been selected : */ + if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + { + /* Set reception type to Standard */ + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + + /* Disable IDLE interrupt */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); + + if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET) + { + /* Clear IDLE Flag */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); + } + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered Rx Event callback*/ + huart->RxEventCallback(huart, huart->RxXferSize); +#else + /*Call legacy weak Rx Event callback*/ + HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize); +#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ + } + else + { + /* Standard reception API called */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered Rx complete callback*/ + huart->RxCpltCallback(huart); +#else + /*Call legacy weak Rx complete callback*/ + HAL_UART_RxCpltCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + } + } + } + + /* When remaining number of bytes to receive is less than the RX FIFO + threshold, next incoming frames are processed as if FIFO mode was + disabled (i.e. one interrupt per received frame). + */ + rxdatacount = huart->RxXferCount; + if ((rxdatacount != 0U) && (rxdatacount < huart->NbRxDataToProcess)) + { + /* Disable the UART RXFT interrupt*/ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_RXFTIE); + + /* Update the RxISR function pointer */ + huart->RxISR = UART_RxISR_8BIT; + + /* Enable the UART Data Register Not Empty interrupt */ + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE); + } + } + else + { + /* Clear RXNE interrupt flag */ + __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); + } +} + +/** + * @brief RX interrupt handler for 9 bits data word length and FIFO mode is enabled. + * @note Function is called under interruption only, once + * interruptions have been enabled by HAL_UART_Receive_IT() + * @param huart UART handle. + * @retval None + */ +static void UART_RxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart) +{ + uint16_t *tmp; + uint16_t uhMask = huart->Mask; + uint16_t uhdata; + uint16_t nb_rx_data; + uint16_t rxdatacount; + uint32_t isrflags = READ_REG(huart->Instance->ISR); + uint32_t cr1its = READ_REG(huart->Instance->CR1); + uint32_t cr3its = READ_REG(huart->Instance->CR3); + + /* Check that a Rx process is ongoing */ + if (huart->RxState == HAL_UART_STATE_BUSY_RX) + { + nb_rx_data = huart->NbRxDataToProcess; + while ((nb_rx_data > 0U) && ((isrflags & USART_ISR_RXNE_RXFNE) != 0U)) + { + uhdata = (uint16_t) READ_REG(huart->Instance->RDR); + tmp = (uint16_t *) huart->pRxBuffPtr ; + *tmp = (uint16_t)(uhdata & uhMask); + huart->pRxBuffPtr += 2U; + huart->RxXferCount--; + isrflags = READ_REG(huart->Instance->ISR); + + /* If some non blocking errors occurred */ + if ((isrflags & (USART_ISR_PE | USART_ISR_FE | USART_ISR_NE)) != 0U) + { + /* UART parity error interrupt occurred -------------------------------------*/ + if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U)) + { + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF); + + huart->ErrorCode |= HAL_UART_ERROR_PE; + } + + /* UART frame error interrupt occurred --------------------------------------*/ + if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) + { + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF); + + huart->ErrorCode |= HAL_UART_ERROR_FE; + } + + /* UART noise error interrupt occurred --------------------------------------*/ + if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) + { + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF); + + huart->ErrorCode |= HAL_UART_ERROR_NE; + } + + /* Call UART Error Call back function if need be ----------------------------*/ + if (huart->ErrorCode != HAL_UART_ERROR_NONE) + { + /* Non Blocking error : transfer could go on. + Error is notified to user through user error callback */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered error callback*/ + huart->ErrorCallback(huart); +#else + /*Call legacy weak error callback*/ + HAL_UART_ErrorCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + huart->ErrorCode = HAL_UART_ERROR_NONE; + } + } + + if (huart->RxXferCount == 0U) + { + /* Disable the UART Parity Error Interrupt and RXFT interrupt*/ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE); + + /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) + and RX FIFO Threshold interrupt */ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE)); + + /* Rx process is completed, restore huart->RxState to Ready */ + huart->RxState = HAL_UART_STATE_READY; + + /* Clear RxISR function pointer */ + huart->RxISR = NULL; + + /* Initialize type of RxEvent to Transfer Complete */ + huart->RxEventType = HAL_UART_RXEVENT_TC; + + if (!(IS_LPUART_INSTANCE(huart->Instance))) + { + /* Check that USART RTOEN bit is set */ + if (READ_BIT(huart->Instance->CR2, USART_CR2_RTOEN) != 0U) + { + /* Enable the UART Receiver Timeout Interrupt */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_RTOIE); + } + } + + /* Check current reception Mode : + If Reception till IDLE event has been selected : */ + if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + { + /* Set reception type to Standard */ + huart->ReceptionType = HAL_UART_RECEPTION_STANDARD; + + /* Disable IDLE interrupt */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); + + if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == SET) + { + /* Clear IDLE Flag */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); + } + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered Rx Event callback*/ + huart->RxEventCallback(huart, huart->RxXferSize); +#else + /*Call legacy weak Rx Event callback*/ + HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize); +#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ + } + else + { + /* Standard reception API called */ +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + /*Call registered Rx complete callback*/ + huart->RxCpltCallback(huart); +#else + /*Call legacy weak Rx complete callback*/ + HAL_UART_RxCpltCallback(huart); +#endif /* USE_HAL_UART_REGISTER_CALLBACKS */ + } + } + } + + /* When remaining number of bytes to receive is less than the RX FIFO + threshold, next incoming frames are processed as if FIFO mode was + disabled (i.e. one interrupt per received frame). + */ + rxdatacount = huart->RxXferCount; + if ((rxdatacount != 0U) && (rxdatacount < huart->NbRxDataToProcess)) + { + /* Disable the UART RXFT interrupt*/ + ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_RXFTIE); + + /* Update the RxISR function pointer */ + huart->RxISR = UART_RxISR_16BIT; + + /* Enable the UART Data Register Not Empty interrupt */ + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE); + } + } + else + { + /* Clear RXNE interrupt flag */ + __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); + } +} + +/** + * @} + */ + +#endif /* HAL_UART_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_uart_ex.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_uart_ex.c new file mode 100644 index 0000000000..291bb00ef1 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_uart_ex.c @@ -0,0 +1,1044 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_uart_ex.c + * @author MCD Application Team + * @brief Extended UART HAL module driver. + * This file provides firmware functions to manage the following extended + * functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (UART). + * + Initialization and de-initialization functions + * + Peripheral Control functions + * + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### UART peripheral extended features ##### + ============================================================================== + + (#) Declare a UART_HandleTypeDef handle structure. + + (#) For the UART RS485 Driver Enable mode, initialize the UART registers + by calling the HAL_RS485Ex_Init() API. + + (#) FIFO mode enabling/disabling and RX/TX FIFO threshold programming. + + -@- When UART operates in FIFO mode, FIFO mode must be enabled prior + starting RX/TX transfers. Also RX/TX FIFO thresholds must be + configured prior starting RX/TX transfers. + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup UARTEx UARTEx + * @brief UART Extended HAL module driver + * @{ + */ + +#ifdef HAL_UART_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup UARTEX_Private_Constants UARTEx Private Constants + * @{ + */ +/* UART RX FIFO depth */ +#define RX_FIFO_DEPTH 8U + +/* UART TX FIFO depth */ +#define TX_FIFO_DEPTH 8U +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup UARTEx_Private_Functions UARTEx Private Functions + * @{ + */ +static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection); +static void UARTEx_SetNbDataToProcess(UART_HandleTypeDef *huart); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup UARTEx_Exported_Functions UARTEx Exported Functions + * @{ + */ + +/** @defgroup UARTEx_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Extended Initialization and Configuration Functions + * +@verbatim +=============================================================================== + ##### Initialization and Configuration functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to initialize the USARTx or the UARTy + in asynchronous mode. + (+) For the asynchronous mode the parameters below can be configured: + (++) Baud Rate + (++) Word Length + (++) Stop Bit + (++) Parity: If the parity is enabled, then the MSB bit of the data written + in the data register is transmitted but is changed by the parity bit. + (++) Hardware flow control + (++) Receiver/transmitter modes + (++) Over Sampling Method + (++) One-Bit Sampling Method + (+) For the asynchronous mode, the following advanced features can be configured as well: + (++) TX and/or RX pin level inversion + (++) data logical level inversion + (++) RX and TX pins swap + (++) RX overrun detection disabling + (++) DMA disabling on RX error + (++) MSB first on communication line + (++) auto Baud rate detection + [..] + The HAL_RS485Ex_Init() API follows the UART RS485 mode configuration + procedures (details for the procedures are available in reference manual). + +@endverbatim + + Depending on the frame length defined by the M1 and M0 bits (7-bit, + 8-bit or 9-bit), the possible UART formats are listed in the + following table. + + Table 1. UART frame format. + +-----------------------------------------------------------------------+ + | M1 bit | M0 bit | PCE bit | UART frame | + |---------|---------|-----------|---------------------------------------| + | 0 | 0 | 0 | | SB | 8 bit data | STB | | + |---------|---------|-----------|---------------------------------------| + | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | | + |---------|---------|-----------|---------------------------------------| + | 0 | 1 | 0 | | SB | 9 bit data | STB | | + |---------|---------|-----------|---------------------------------------| + | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | | + |---------|---------|-----------|---------------------------------------| + | 1 | 0 | 0 | | SB | 7 bit data | STB | | + |---------|---------|-----------|---------------------------------------| + | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | | + +-----------------------------------------------------------------------+ + + * @{ + */ + +/** + * @brief Initialize the RS485 Driver enable feature according to the specified + * parameters in the UART_InitTypeDef and creates the associated handle. + * @param huart UART handle. + * @param Polarity Select the driver enable polarity. + * This parameter can be one of the following values: + * @arg @ref UART_DE_POLARITY_HIGH DE signal is active high + * @arg @ref UART_DE_POLARITY_LOW DE signal is active low + * @param AssertionTime Driver Enable assertion time: + * 5-bit value defining the time between the activation of the DE (Driver Enable) + * signal and the beginning of the start bit. It is expressed in sample time + * units (1/8 or 1/16 bit time, depending on the oversampling rate) + * @param DeassertionTime Driver Enable deassertion time: + * 5-bit value defining the time between the end of the last stop bit, in a + * transmitted message, and the de-activation of the DE (Driver Enable) signal. + * It is expressed in sample time units (1/8 or 1/16 bit time, depending on the + * oversampling rate). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RS485Ex_Init(UART_HandleTypeDef *huart, uint32_t Polarity, uint32_t AssertionTime, + uint32_t DeassertionTime) +{ + uint32_t temp; + + /* Check the UART handle allocation */ + if (huart == NULL) + { + return HAL_ERROR; + } + /* Check the Driver Enable UART instance */ + assert_param(IS_UART_DRIVER_ENABLE_INSTANCE(huart->Instance)); + + /* Check the Driver Enable polarity */ + assert_param(IS_UART_DE_POLARITY(Polarity)); + + /* Check the Driver Enable assertion time */ + assert_param(IS_UART_ASSERTIONTIME(AssertionTime)); + + /* Check the Driver Enable deassertion time */ + assert_param(IS_UART_DEASSERTIONTIME(DeassertionTime)); + + if (huart->gState == HAL_UART_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + huart->Lock = HAL_UNLOCKED; + +#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) + UART_InitCallbacksToDefault(huart); + + if (huart->MspInitCallback == NULL) + { + huart->MspInitCallback = HAL_UART_MspInit; + } + + /* Init the low level hardware */ + huart->MspInitCallback(huart); +#else + /* Init the low level hardware : GPIO, CLOCK, CORTEX */ + HAL_UART_MspInit(huart); +#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */ + } + + huart->gState = HAL_UART_STATE_BUSY; + + /* Disable the Peripheral */ + __HAL_UART_DISABLE(huart); + + /* Perform advanced settings configuration */ + /* For some items, configuration requires to be done prior TE and RE bits are set */ + if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT) + { + UART_AdvFeatureConfig(huart); + } + + /* Set the UART Communication parameters */ + if (UART_SetConfig(huart) == HAL_ERROR) + { + return HAL_ERROR; + } + + /* Enable the Driver Enable mode by setting the DEM bit in the CR3 register */ + SET_BIT(huart->Instance->CR3, USART_CR3_DEM); + + /* Set the Driver Enable polarity */ + MODIFY_REG(huart->Instance->CR3, USART_CR3_DEP, Polarity); + + /* Set the Driver Enable assertion and deassertion times */ + temp = (AssertionTime << UART_CR1_DEAT_ADDRESS_LSB_POS); + temp |= (DeassertionTime << UART_CR1_DEDT_ADDRESS_LSB_POS); + MODIFY_REG(huart->Instance->CR1, (USART_CR1_DEDT | USART_CR1_DEAT), temp); + + /* Enable the Peripheral */ + __HAL_UART_ENABLE(huart); + + /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */ + return (UART_CheckIdleState(huart)); +} + +/** + * @} + */ + +/** @defgroup UARTEx_Exported_Functions_Group2 IO operation functions + * @brief Extended functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + This subsection provides a set of Wakeup and FIFO mode related callback functions. + + (#) Wakeup from Stop mode Callback: + (+) HAL_UARTEx_WakeupCallback() + + (#) TX/RX Fifos Callbacks: + (+) HAL_UARTEx_RxFifoFullCallback() + (+) HAL_UARTEx_TxFifoEmptyCallback() + +@endverbatim + * @{ + */ + +/** + * @brief UART wakeup from Stop mode callback. + * @param huart UART handle. + * @retval None + */ +__weak void HAL_UARTEx_WakeupCallback(UART_HandleTypeDef *huart) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(huart); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_UARTEx_WakeupCallback can be implemented in the user file. + */ +} + +/** + * @brief UART RX Fifo full callback. + * @param huart UART handle. + * @retval None + */ +__weak void HAL_UARTEx_RxFifoFullCallback(UART_HandleTypeDef *huart) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(huart); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_UARTEx_RxFifoFullCallback can be implemented in the user file. + */ +} + +/** + * @brief UART TX Fifo empty callback. + * @param huart UART handle. + * @retval None + */ +__weak void HAL_UARTEx_TxFifoEmptyCallback(UART_HandleTypeDef *huart) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(huart); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_UARTEx_TxFifoEmptyCallback can be implemented in the user file. + */ +} + +/** + * @} + */ + +/** @defgroup UARTEx_Exported_Functions_Group3 Peripheral Control functions + * @brief Extended Peripheral Control functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] This section provides the following functions: + (+) HAL_MultiProcessorEx_AddressLength_Set() API optionally sets the UART node address + detection length to more than 4 bits for multiprocessor address mark wake up. + (+) HAL_UARTEx_StopModeWakeUpSourceConfig() API defines the wake-up from stop mode + trigger: address match, Start Bit detection or RXNE bit status. + (+) HAL_UARTEx_EnableStopMode() API enables the UART to wake up the MCU from stop mode + (+) HAL_UARTEx_DisableStopMode() API disables the above functionality + (+) HAL_UARTEx_EnableFifoMode() API enables the FIFO mode + (+) HAL_UARTEx_DisableFifoMode() API disables the FIFO mode + (+) HAL_UARTEx_SetTxFifoThreshold() API sets the TX FIFO threshold + (+) HAL_UARTEx_SetRxFifoThreshold() API sets the RX FIFO threshold + + [..] This subsection also provides a set of additional functions providing enhanced reception + services to user. (For example, these functions allow application to handle use cases + where number of data to be received is unknown). + + (#) Compared to standard reception services which only consider number of received + data elements as reception completion criteria, these functions also consider additional events + as triggers for updating reception status to caller : + (+) Detection of inactivity period (RX line has not been active for a given period). + (++) RX inactivity detected by IDLE event, i.e. RX line has been in idle state (normally high state) + for 1 frame time, after last received byte. + (++) RX inactivity detected by RTO, i.e. line has been in idle state + for a programmable time, after last received byte. + (+) Detection that a specific character has been received. + + (#) There are two mode of transfer: + (+) Blocking mode: The reception is performed in polling mode, until either expected number of data is received, + or till IDLE event occurs. Reception is handled only during function execution. + When function exits, no data reception could occur. HAL status and number of actually received data elements, + are returned by function after finishing transfer. + (+) Non-Blocking mode: The reception is performed using Interrupts or DMA. + These API's return the HAL status. + The end of the data processing will be indicated through the + dedicated UART IRQ when using Interrupt mode or the DMA IRQ when using DMA mode. + The HAL_UARTEx_RxEventCallback() user callback will be executed during Receive process + The HAL_UART_ErrorCallback()user callback will be executed when a reception error is detected. + + (#) Blocking mode API: + (+) HAL_UARTEx_ReceiveToIdle() + + (#) Non-Blocking mode API with Interrupt: + (+) HAL_UARTEx_ReceiveToIdle_IT() + + (#) Non-Blocking mode API with DMA: + (+) HAL_UARTEx_ReceiveToIdle_DMA() + +@endverbatim + * @{ + */ + +/** + * @brief By default in multiprocessor mode, when the wake up method is set + * to address mark, the UART handles only 4-bit long addresses detection; + * this API allows to enable longer addresses detection (6-, 7- or 8-bit + * long). + * @note Addresses detection lengths are: 6-bit address detection in 7-bit data mode, + * 7-bit address detection in 8-bit data mode, 8-bit address detection in 9-bit data mode. + * @param huart UART handle. + * @param AddressLength This parameter can be one of the following values: + * @arg @ref UART_ADDRESS_DETECT_4B 4-bit long address + * @arg @ref UART_ADDRESS_DETECT_7B 6-, 7- or 8-bit long address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MultiProcessorEx_AddressLength_Set(UART_HandleTypeDef *huart, uint32_t AddressLength) +{ + /* Check the UART handle allocation */ + if (huart == NULL) + { + return HAL_ERROR; + } + + /* Check the address length parameter */ + assert_param(IS_UART_ADDRESSLENGTH_DETECT(AddressLength)); + + huart->gState = HAL_UART_STATE_BUSY; + + /* Disable the Peripheral */ + __HAL_UART_DISABLE(huart); + + /* Set the address length */ + MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, AddressLength); + + /* Enable the Peripheral */ + __HAL_UART_ENABLE(huart); + + /* TEACK and/or REACK to check before moving huart->gState to Ready */ + return (UART_CheckIdleState(huart)); +} + +/** + * @brief Set Wakeup from Stop mode interrupt flag selection. + * @note It is the application responsibility to enable the interrupt used as + * usart_wkup interrupt source before entering low-power mode. + * @param huart UART handle. + * @param WakeUpSelection Address match, Start Bit detection or RXNE/RXFNE bit status. + * This parameter can be one of the following values: + * @arg @ref UART_WAKEUP_ON_ADDRESS + * @arg @ref UART_WAKEUP_ON_STARTBIT + * @arg @ref UART_WAKEUP_ON_READDATA_NONEMPTY + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UARTEx_StopModeWakeUpSourceConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tickstart; + + /* check the wake-up from stop mode UART instance */ + assert_param(IS_UART_WAKEUP_FROMSTOP_INSTANCE(huart->Instance)); + /* check the wake-up selection parameter */ + assert_param(IS_UART_WAKEUP_SELECTION(WakeUpSelection.WakeUpEvent)); + + /* Process Locked */ + __HAL_LOCK(huart); + + huart->gState = HAL_UART_STATE_BUSY; + + /* Disable the Peripheral */ + __HAL_UART_DISABLE(huart); + + /* Set the wake-up selection scheme */ + MODIFY_REG(huart->Instance->CR3, USART_CR3_WUS, WakeUpSelection.WakeUpEvent); + + if (WakeUpSelection.WakeUpEvent == UART_WAKEUP_ON_ADDRESS) + { + UARTEx_Wakeup_AddressConfig(huart, WakeUpSelection); + } + + /* Enable the Peripheral */ + __HAL_UART_ENABLE(huart); + + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + + /* Wait until REACK flag is set */ + if (UART_WaitOnFlagUntilTimeout(huart, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK) + { + status = HAL_TIMEOUT; + } + else + { + /* Initialize the UART State */ + huart->gState = HAL_UART_STATE_READY; + } + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return status; +} + +/** + * @brief Enable UART Stop Mode. + * @note The UART is able to wake up the MCU from Stop 1 mode as long as UART clock is HSI or LSE. + * @param huart UART handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UARTEx_EnableStopMode(UART_HandleTypeDef *huart) +{ + /* Process Locked */ + __HAL_LOCK(huart); + + /* Set UESM bit */ + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_UESM); + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return HAL_OK; +} + +/** + * @brief Disable UART Stop Mode. + * @param huart UART handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UARTEx_DisableStopMode(UART_HandleTypeDef *huart) +{ + /* Process Locked */ + __HAL_LOCK(huart); + + /* Clear UESM bit */ + ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_UESM); + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return HAL_OK; +} + +/** + * @brief Enable the FIFO mode. + * @param huart UART handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UARTEx_EnableFifoMode(UART_HandleTypeDef *huart) +{ + uint32_t tmpcr1; + + /* Check parameters */ + assert_param(IS_UART_FIFO_INSTANCE(huart->Instance)); + + /* Process Locked */ + __HAL_LOCK(huart); + + huart->gState = HAL_UART_STATE_BUSY; + + /* Save actual UART configuration */ + tmpcr1 = READ_REG(huart->Instance->CR1); + + /* Disable UART */ + __HAL_UART_DISABLE(huart); + + /* Enable FIFO mode */ + SET_BIT(tmpcr1, USART_CR1_FIFOEN); + huart->FifoMode = UART_FIFOMODE_ENABLE; + + /* Restore UART configuration */ + WRITE_REG(huart->Instance->CR1, tmpcr1); + + /* Determine the number of data to process during RX/TX ISR execution */ + UARTEx_SetNbDataToProcess(huart); + + huart->gState = HAL_UART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return HAL_OK; +} + +/** + * @brief Disable the FIFO mode. + * @param huart UART handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UARTEx_DisableFifoMode(UART_HandleTypeDef *huart) +{ + uint32_t tmpcr1; + + /* Check parameters */ + assert_param(IS_UART_FIFO_INSTANCE(huart->Instance)); + + /* Process Locked */ + __HAL_LOCK(huart); + + huart->gState = HAL_UART_STATE_BUSY; + + /* Save actual UART configuration */ + tmpcr1 = READ_REG(huart->Instance->CR1); + + /* Disable UART */ + __HAL_UART_DISABLE(huart); + + /* Enable FIFO mode */ + CLEAR_BIT(tmpcr1, USART_CR1_FIFOEN); + huart->FifoMode = UART_FIFOMODE_DISABLE; + + /* Restore UART configuration */ + WRITE_REG(huart->Instance->CR1, tmpcr1); + + huart->gState = HAL_UART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return HAL_OK; +} + +/** + * @brief Set the TXFIFO threshold. + * @param huart UART handle. + * @param Threshold TX FIFO threshold value + * This parameter can be one of the following values: + * @arg @ref UART_TXFIFO_THRESHOLD_1_8 + * @arg @ref UART_TXFIFO_THRESHOLD_1_4 + * @arg @ref UART_TXFIFO_THRESHOLD_1_2 + * @arg @ref UART_TXFIFO_THRESHOLD_3_4 + * @arg @ref UART_TXFIFO_THRESHOLD_7_8 + * @arg @ref UART_TXFIFO_THRESHOLD_8_8 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UARTEx_SetTxFifoThreshold(UART_HandleTypeDef *huart, uint32_t Threshold) +{ + uint32_t tmpcr1; + + /* Check parameters */ + assert_param(IS_UART_FIFO_INSTANCE(huart->Instance)); + assert_param(IS_UART_TXFIFO_THRESHOLD(Threshold)); + + /* Process Locked */ + __HAL_LOCK(huart); + + huart->gState = HAL_UART_STATE_BUSY; + + /* Save actual UART configuration */ + tmpcr1 = READ_REG(huart->Instance->CR1); + + /* Disable UART */ + __HAL_UART_DISABLE(huart); + + /* Update TX threshold configuration */ + MODIFY_REG(huart->Instance->CR3, USART_CR3_TXFTCFG, Threshold); + + /* Determine the number of data to process during RX/TX ISR execution */ + UARTEx_SetNbDataToProcess(huart); + + /* Restore UART configuration */ + WRITE_REG(huart->Instance->CR1, tmpcr1); + + huart->gState = HAL_UART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return HAL_OK; +} + +/** + * @brief Set the RXFIFO threshold. + * @param huart UART handle. + * @param Threshold RX FIFO threshold value + * This parameter can be one of the following values: + * @arg @ref UART_RXFIFO_THRESHOLD_1_8 + * @arg @ref UART_RXFIFO_THRESHOLD_1_4 + * @arg @ref UART_RXFIFO_THRESHOLD_1_2 + * @arg @ref UART_RXFIFO_THRESHOLD_3_4 + * @arg @ref UART_RXFIFO_THRESHOLD_7_8 + * @arg @ref UART_RXFIFO_THRESHOLD_8_8 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UARTEx_SetRxFifoThreshold(UART_HandleTypeDef *huart, uint32_t Threshold) +{ + uint32_t tmpcr1; + + /* Check the parameters */ + assert_param(IS_UART_FIFO_INSTANCE(huart->Instance)); + assert_param(IS_UART_RXFIFO_THRESHOLD(Threshold)); + + /* Process Locked */ + __HAL_LOCK(huart); + + huart->gState = HAL_UART_STATE_BUSY; + + /* Save actual UART configuration */ + tmpcr1 = READ_REG(huart->Instance->CR1); + + /* Disable UART */ + __HAL_UART_DISABLE(huart); + + /* Update RX threshold configuration */ + MODIFY_REG(huart->Instance->CR3, USART_CR3_RXFTCFG, Threshold); + + /* Determine the number of data to process during RX/TX ISR execution */ + UARTEx_SetNbDataToProcess(huart); + + /* Restore UART configuration */ + WRITE_REG(huart->Instance->CR1, tmpcr1); + + huart->gState = HAL_UART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return HAL_OK; +} + +/** + * @brief Receive an amount of data in blocking mode till either the expected number of data + * is received or an IDLE event occurs. + * @note HAL_OK is returned if reception is completed (expected number of data has been received) + * or if reception is stopped after IDLE event (less than the expected number of data has been received) + * In this case, RxLen output parameter indicates number of data available in reception buffer. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * the received data is handled as a set of uint16_t. In this case, Size must indicate the number + * of uint16_t available through pData. + * @note When FIFO mode is enabled, the RXFNE flag is set as long as the RXFIFO + * is not empty. Read operations from the RDR register are performed when + * RXFNE flag is set. From hardware perspective, RXFNE flag and + * RXNE are mapped on the same bit-field. + * @param huart UART handle. + * @param pData Pointer to data buffer (uint8_t or uint16_t data elements). + * @param Size Amount of data elements (uint8_t or uint16_t) to be received. + * @param RxLen Number of data elements finally received + * (could be lower than Size, in case reception ends on IDLE event) + * @param Timeout Timeout duration expressed in ms (covers the whole reception sequence). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen, + uint32_t Timeout) +{ + uint8_t *pdata8bits; + uint16_t *pdata16bits; + uint16_t uhMask; + uint32_t tickstart; + + /* Check that a Rx process is not already ongoing */ + if (huart->RxState == HAL_UART_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + huart->ErrorCode = HAL_UART_ERROR_NONE; + huart->RxState = HAL_UART_STATE_BUSY_RX; + huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE; + huart->RxEventType = HAL_UART_RXEVENT_TC; + + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + + huart->RxXferSize = Size; + huart->RxXferCount = Size; + + /* Computation of UART mask to apply to RDR register */ + UART_MASK_COMPUTATION(huart); + uhMask = huart->Mask; + + /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */ + if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) + { + pdata8bits = NULL; + pdata16bits = (uint16_t *) pData; + } + else + { + pdata8bits = pData; + pdata16bits = NULL; + } + + /* Initialize output number of received elements */ + *RxLen = 0U; + + /* as long as data have to be received */ + while (huart->RxXferCount > 0U) + { + /* Check if IDLE flag is set */ + if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE)) + { + /* Clear IDLE flag in ISR */ + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); + + /* If Set, but no data ever received, clear flag without exiting loop */ + /* If Set, and data has already been received, this means Idle Event is valid : End reception */ + if (*RxLen > 0U) + { + huart->RxEventType = HAL_UART_RXEVENT_IDLE; + huart->RxState = HAL_UART_STATE_READY; + + return HAL_OK; + } + } + + /* Check if RXNE flag is set */ + if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE)) + { + if (pdata8bits == NULL) + { + *pdata16bits = (uint16_t)(huart->Instance->RDR & uhMask); + pdata16bits++; + } + else + { + *pdata8bits = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask); + pdata8bits++; + } + /* Increment number of received elements */ + *RxLen += 1U; + huart->RxXferCount--; + } + + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + huart->RxState = HAL_UART_STATE_READY; + + return HAL_TIMEOUT; + } + } + } + + /* Set number of received elements in output parameter : RxLen */ + *RxLen = huart->RxXferSize - huart->RxXferCount; + /* At end of Rx process, restore huart->RxState to Ready */ + huart->RxState = HAL_UART_STATE_READY; + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in interrupt mode till either the expected number of data + * is received or an IDLE event occurs. + * @note Reception is initiated by this function call. Further progress of reception is achieved thanks + * to UART interrupts raised by RXNE and IDLE events. Callback is called at end of reception indicating + * number of received data elements. + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * the received data is handled as a set of uint16_t. In this case, Size must indicate the number + * of uint16_t available through pData. + * @param huart UART handle. + * @param pData Pointer to data buffer (uint8_t or uint16_t data elements). + * @param Size Amount of data elements (uint8_t or uint16_t) to be received. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check that a Rx process is not already ongoing */ + if (huart->RxState == HAL_UART_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Set Reception type to reception till IDLE Event*/ + huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE; + huart->RxEventType = HAL_UART_RXEVENT_TC; + + (void)UART_Start_Receive_IT(huart, pData, Size); + + if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + { + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); + } + else + { + /* In case of errors already pending when reception is started, + Interrupts may have already been raised and lead to reception abortion. + (Overrun error for instance). + In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */ + status = HAL_ERROR; + } + + return status; + } + else + { + return HAL_BUSY; + } +} + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief Receive an amount of data in DMA mode till either the expected number + * of data is received or an IDLE event occurs. + * @note Reception is initiated by this function call. Further progress of reception is achieved thanks + * to DMA services, transferring automatically received data elements in user reception buffer and + * calling registered callbacks at half/end of reception. UART IDLE events are also used to consider + * reception phase as ended. In all cases, callback execution will indicate number of received data elements. + * @note When the UART parity is enabled (PCE = 1), the received data contain + * the parity bit (MSB position). + * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * the received data is handled as a set of uint16_t. In this case, Size must indicate the number + * of uint16_t available through pData. + * @param huart UART handle. + * @param pData Pointer to data buffer (uint8_t or uint16_t data elements). + * @param Size Amount of data elements (uint8_t or uint16_t) to be received. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) +{ + HAL_StatusTypeDef status; + + /* Check that a Rx process is not already ongoing */ + if (huart->RxState == HAL_UART_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Set Reception type to reception till IDLE Event*/ + huart->ReceptionType = HAL_UART_RECEPTION_TOIDLE; + huart->RxEventType = HAL_UART_RXEVENT_TC; + + status = UART_Start_Receive_DMA(huart, pData, Size); + + /* Check Rx process has been successfully started */ + if (status == HAL_OK) + { + if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE) + { + __HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_IDLEF); + ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE); + } + else + { + /* In case of errors already pending when reception is started, + Interrupts may have already been raised and lead to reception abortion. + (Overrun error for instance). + In such case Reception Type has been reset to HAL_UART_RECEPTION_STANDARD. */ + status = HAL_ERROR; + } + } + + return status; + } + else + { + return HAL_BUSY; + } +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Provide Rx Event type that has lead to RxEvent callback execution. + * @note When HAL_UARTEx_ReceiveToIdle_IT() or HAL_UARTEx_ReceiveToIdle_DMA() API are called, progress + * of reception process is provided to application through calls of Rx Event callback (either default one + * HAL_UARTEx_RxEventCallback() or user registered one). As several types of events could occur (IDLE event, + * Half Transfer, or Transfer Complete), this function allows to retrieve the Rx Event type that has lead + * to Rx Event callback execution. + * @note This function is expected to be called within the user implementation of Rx Event Callback, + * in order to provide the accurate value : + * In Interrupt Mode : + * - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received) + * - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed (nb of + * received data is lower than expected one) + * In DMA Mode : + * - HAL_UART_RXEVENT_TC : when Reception has been completed (expected nb of data has been received) + * - HAL_UART_RXEVENT_HT : when half of expected nb of data has been received + * - HAL_UART_RXEVENT_IDLE : when Idle event occurred prior reception has been completed (nb of + * received data is lower than expected one). + * In DMA mode, RxEvent callback could be called several times; + * When DMA is configured in Normal Mode, HT event does not stop Reception process; + * When DMA is configured in Circular Mode, HT, TC or IDLE events don't stop Reception process; + * @param huart UART handle. + * @retval Rx Event Type (return vale will be a value of @ref UART_RxEvent_Type_Values) + */ +HAL_UART_RxEventTypeTypeDef HAL_UARTEx_GetRxEventType(const UART_HandleTypeDef *huart) +{ + /* Return Rx Event type value, as stored in UART handle */ + return (huart->RxEventType); +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup UARTEx_Private_Functions + * @{ + */ + +/** + * @brief Initialize the UART wake-up from stop mode parameters when triggered by address detection. + * @param huart UART handle. + * @param WakeUpSelection UART wake up from stop mode parameters. + * @retval None + */ +static void UARTEx_Wakeup_AddressConfig(UART_HandleTypeDef *huart, UART_WakeUpTypeDef WakeUpSelection) +{ + assert_param(IS_UART_ADDRESSLENGTH_DETECT(WakeUpSelection.AddressLength)); + + /* Set the USART address length */ + MODIFY_REG(huart->Instance->CR2, USART_CR2_ADDM7, WakeUpSelection.AddressLength); + + /* Set the USART address node */ + MODIFY_REG(huart->Instance->CR2, USART_CR2_ADD, ((uint32_t)WakeUpSelection.Address << UART_CR2_ADDRESS_LSB_POS)); +} + +/** + * @brief Calculate the number of data to process in RX/TX ISR. + * @note The RX FIFO depth and the TX FIFO depth is extracted from + * the UART configuration registers. + * @param huart UART handle. + * @retval None + */ +static void UARTEx_SetNbDataToProcess(UART_HandleTypeDef *huart) +{ + uint8_t rx_fifo_depth; + uint8_t tx_fifo_depth; + uint8_t rx_fifo_threshold; + uint8_t tx_fifo_threshold; + static const uint8_t numerator[] = {1U, 1U, 1U, 3U, 7U, 1U, 0U, 0U}; + static const uint8_t denominator[] = {8U, 4U, 2U, 4U, 8U, 1U, 1U, 1U}; + + if (huart->FifoMode == UART_FIFOMODE_DISABLE) + { + huart->NbTxDataToProcess = 1U; + huart->NbRxDataToProcess = 1U; + } + else + { + rx_fifo_depth = RX_FIFO_DEPTH; + tx_fifo_depth = TX_FIFO_DEPTH; + rx_fifo_threshold = (uint8_t)(READ_BIT(huart->Instance->CR3, USART_CR3_RXFTCFG) >> USART_CR3_RXFTCFG_Pos); + tx_fifo_threshold = (uint8_t)(READ_BIT(huart->Instance->CR3, USART_CR3_TXFTCFG) >> USART_CR3_TXFTCFG_Pos); + huart->NbTxDataToProcess = ((uint16_t)tx_fifo_depth * numerator[tx_fifo_threshold]) / + (uint16_t)denominator[tx_fifo_threshold]; + huart->NbRxDataToProcess = ((uint16_t)rx_fifo_depth * numerator[rx_fifo_threshold]) / + (uint16_t)denominator[rx_fifo_threshold]; + } +} +/** + * @} + */ + +#endif /* HAL_UART_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_usart.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_usart.c new file mode 100644 index 0000000000..f07ce802df --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_usart.c @@ -0,0 +1,3981 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_usart.c + * @author MCD Application Team + * @brief USART HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Universal Synchronous/Asynchronous Receiver Transmitter + * Peripheral (USART). + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State and Error functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + =============================================================================== + ##### How to use this driver ##### + =============================================================================== + [..] + The USART HAL driver can be used as follows: + + (#) Declare a USART_HandleTypeDef handle structure (eg. USART_HandleTypeDef husart). + (#) Initialize the USART low level resources by implementing the HAL_USART_MspInit() API: + (++) Enable the USARTx interface clock. + (++) USART pins configuration: + (+++) Enable the clock for the USART GPIOs. + (+++) Configure these USART pins as alternate function pull-up. + (++) NVIC configuration if you need to use interrupt process (HAL_USART_Transmit_IT(), + HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs): + (+++) Configure the USARTx interrupt priority. + (+++) Enable the NVIC USART IRQ handle. + (++) USART interrupts handling: + -@@- The specific USART interrupts (Transmission complete interrupt, + RXNE interrupt and Error Interrupts) will be managed using the macros + __HAL_USART_ENABLE_IT() and __HAL_USART_DISABLE_IT() inside the transmit and receive process. + (++) DMA Configuration if you need to use DMA process (HAL_USART_Transmit_DMA() + HAL_USART_Receive_DMA() and HAL_USART_TransmitReceive_DMA() APIs): + (+++) Declare a DMA handle structure for the Tx/Rx channel. + (+++) Enable the DMAx interface clock. + (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. + (+++) Configure the DMA Tx/Rx channel. + (+++) Associate the initialized DMA handle to the USART DMA Tx/Rx handle. + (+++) Configure the priority and enable the NVIC for the transfer + complete interrupt on the DMA Tx/Rx channel. + + (#) Program the Baud Rate, Word Length, Stop Bit, Parity, and Mode + (Receiver/Transmitter) in the husart handle Init structure. + + (#) Initialize the USART registers by calling the HAL_USART_Init() API: + (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc) + by calling the customized HAL_USART_MspInit(&husart) API. + + [..] + (@) To configure and enable/disable the USART to wake up the MCU from stop mode, resort to UART API's + HAL_UARTEx_StopModeWakeUpSourceConfig(), HAL_UARTEx_EnableStopMode() and + HAL_UARTEx_DisableStopMode() in casting the USART handle to UART type UART_HandleTypeDef. + + ##### Callback registration ##### + ================================== + + [..] + The compilation define USE_HAL_USART_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + + [..] + Use Function HAL_USART_RegisterCallback() to register a user callback. + Function HAL_USART_RegisterCallback() allows to register following callbacks: + (+) TxHalfCpltCallback : Tx Half Complete Callback. + (+) TxCpltCallback : Tx Complete Callback. + (+) RxHalfCpltCallback : Rx Half Complete Callback. + (+) RxCpltCallback : Rx Complete Callback. + (+) TxRxCpltCallback : Tx Rx Complete Callback. + (+) ErrorCallback : Error Callback. + (+) AbortCpltCallback : Abort Complete Callback. + (+) RxFifoFullCallback : Rx Fifo Full Callback. + (+) TxFifoEmptyCallback : Tx Fifo Empty Callback. + (+) MspInitCallback : USART MspInit. + (+) MspDeInitCallback : USART MspDeInit. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + + [..] + Use function HAL_USART_UnRegisterCallback() to reset a callback to the default + weak function. + HAL_USART_UnRegisterCallback() takes as parameters the HAL peripheral handle, + and the Callback ID. + This function allows to reset following callbacks: + (+) TxHalfCpltCallback : Tx Half Complete Callback. + (+) TxCpltCallback : Tx Complete Callback. + (+) RxHalfCpltCallback : Rx Half Complete Callback. + (+) RxCpltCallback : Rx Complete Callback. + (+) TxRxCpltCallback : Tx Rx Complete Callback. + (+) ErrorCallback : Error Callback. + (+) AbortCpltCallback : Abort Complete Callback. + (+) RxFifoFullCallback : Rx Fifo Full Callback. + (+) TxFifoEmptyCallback : Tx Fifo Empty Callback. + (+) MspInitCallback : USART MspInit. + (+) MspDeInitCallback : USART MspDeInit. + + [..] + By default, after the HAL_USART_Init() and when the state is HAL_USART_STATE_RESET + all callbacks are set to the corresponding weak functions: + examples HAL_USART_TxCpltCallback(), HAL_USART_RxHalfCpltCallback(). + Exception done for MspInit and MspDeInit functions that are respectively + reset to the legacy weak functions in the HAL_USART_Init() + and HAL_USART_DeInit() only when these callbacks are null (not registered beforehand). + If not, MspInit or MspDeInit are not null, the HAL_USART_Init() and HAL_USART_DeInit() + keep and use the user MspInit/MspDeInit callbacks (registered beforehand). + + [..] + Callbacks can be registered/unregistered in HAL_USART_STATE_READY state only. + Exception done MspInit/MspDeInit that can be registered/unregistered + in HAL_USART_STATE_READY or HAL_USART_STATE_RESET state, thus registered (user) + MspInit/DeInit callbacks can be used during the Init/DeInit. + In that case first register the MspInit/MspDeInit user callbacks + using HAL_USART_RegisterCallback() before calling HAL_USART_DeInit() + or HAL_USART_Init() function. + + [..] + When The compilation define USE_HAL_USART_REGISTER_CALLBACKS is set to 0 or + not defined, the callback registration feature is not available + and weak callbacks are used. + + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup USART USART + * @brief HAL USART Synchronous module driver + * @{ + */ + +#ifdef HAL_USART_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup USART_Private_Constants USART Private Constants + * @{ + */ +#define USART_DUMMY_DATA ((uint16_t) 0xFFFF) /*!< USART transmitted dummy data */ +#define USART_TEACK_REACK_TIMEOUT 1000U /*!< USART TX or RX enable acknowledge time-out value */ +#define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \ + USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8 | \ + USART_CR1_FIFOEN )) /*!< USART CR1 fields of parameters set by USART_SetConfig API */ + +#define USART_CR2_FIELDS ((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | \ + USART_CR2_LBCL | USART_CR2_STOP | USART_CR2_SLVEN | \ + USART_CR2_DIS_NSS)) /*!< USART CR2 fields of parameters set by USART_SetConfig API */ + +#define USART_CR3_FIELDS ((uint32_t)(USART_CR3_TXFTCFG | USART_CR3_RXFTCFG )) /*!< USART or USART CR3 fields of parameters set by USART_SetConfig API */ + +#define USART_BRR_MIN 0x10U /* USART BRR minimum authorized value */ +#define USART_BRR_MAX 0xFFFFU /* USART BRR maximum authorized value */ +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup USART_Private_Functions + * @{ + */ +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) +void USART_InitCallbacksToDefault(USART_HandleTypeDef *husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ +static void USART_EndTransfer(USART_HandleTypeDef *husart); +#if defined(HAL_DMA_MODULE_ENABLED) +static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma); +static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma); +static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma); +static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma); +static void USART_DMAError(DMA_HandleTypeDef *hdma); +static void USART_DMAAbortOnError(DMA_HandleTypeDef *hdma); +static void USART_DMATxAbortCallback(DMA_HandleTypeDef *hdma); +static void USART_DMARxAbortCallback(DMA_HandleTypeDef *hdma); +#endif /* HAL_DMA_MODULE_ENABLED */ +static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, + uint32_t Tickstart, uint32_t Timeout); +static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart); +static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart); +static void USART_TxISR_8BIT(USART_HandleTypeDef *husart); +static void USART_TxISR_16BIT(USART_HandleTypeDef *husart); +static void USART_TxISR_8BIT_FIFOEN(USART_HandleTypeDef *husart); +static void USART_TxISR_16BIT_FIFOEN(USART_HandleTypeDef *husart); +static void USART_EndTransmit_IT(USART_HandleTypeDef *husart); +static void USART_RxISR_8BIT(USART_HandleTypeDef *husart); +static void USART_RxISR_16BIT(USART_HandleTypeDef *husart); +static void USART_RxISR_8BIT_FIFOEN(USART_HandleTypeDef *husart); +static void USART_RxISR_16BIT_FIFOEN(USART_HandleTypeDef *husart); + + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup USART_Exported_Functions USART Exported Functions + * @{ + */ + +/** @defgroup USART_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and Configuration functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to initialize the USART + in asynchronous and in synchronous modes. + (+) For the asynchronous mode only these parameters can be configured: + (++) Baud Rate + (++) Word Length + (++) Stop Bit + (++) Parity: If the parity is enabled, then the MSB bit of the data written + in the data register is transmitted but is changed by the parity bit. + (++) USART polarity + (++) USART phase + (++) USART LastBit + (++) Receiver/transmitter modes + + [..] + The HAL_USART_Init() function follows the USART synchronous configuration + procedure (details for the procedure are available in reference manual). + +@endverbatim + + Depending on the frame length defined by the M1 and M0 bits (7-bit, + 8-bit or 9-bit), the possible USART formats are listed in the + following table. + + Table 1. USART frame format. + +-----------------------------------------------------------------------+ + | M1 bit | M0 bit | PCE bit | USART frame | + |---------|---------|-----------|---------------------------------------| + | 0 | 0 | 0 | | SB | 8 bit data | STB | | + |---------|---------|-----------|---------------------------------------| + | 0 | 0 | 1 | | SB | 7 bit data | PB | STB | | + |---------|---------|-----------|---------------------------------------| + | 0 | 1 | 0 | | SB | 9 bit data | STB | | + |---------|---------|-----------|---------------------------------------| + | 0 | 1 | 1 | | SB | 8 bit data | PB | STB | | + |---------|---------|-----------|---------------------------------------| + | 1 | 0 | 0 | | SB | 7 bit data | STB | | + |---------|---------|-----------|---------------------------------------| + | 1 | 0 | 1 | | SB | 6 bit data | PB | STB | | + +-----------------------------------------------------------------------+ + + * @{ + */ + +/** + * @brief Initialize the USART mode according to the specified + * parameters in the USART_InitTypeDef and initialize the associated handle. + * @param husart USART handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart) +{ + /* Check the USART handle allocation */ + if (husart == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_USART_INSTANCE(husart->Instance)); + + if (husart->State == HAL_USART_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + husart->Lock = HAL_UNLOCKED; + +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + USART_InitCallbacksToDefault(husart); + + if (husart->MspInitCallback == NULL) + { + husart->MspInitCallback = HAL_USART_MspInit; + } + + /* Init the low level hardware */ + husart->MspInitCallback(husart); +#else + /* Init the low level hardware : GPIO, CLOCK */ + HAL_USART_MspInit(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + } + + husart->State = HAL_USART_STATE_BUSY; + + /* Disable the Peripheral */ + __HAL_USART_DISABLE(husart); + + /* Set the Usart Communication parameters */ + if (USART_SetConfig(husart) == HAL_ERROR) + { + return HAL_ERROR; + } + + /* In Synchronous mode, the following bits must be kept cleared: + - LINEN bit in the USART_CR2 register + - HDSEL, SCEN and IREN bits in the USART_CR3 register. + */ + husart->Instance->CR2 &= ~USART_CR2_LINEN; + husart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN); + + /* Enable the Peripheral */ + __HAL_USART_ENABLE(husart); + + /* TEACK and/or REACK to check before moving husart->State to Ready */ + return (USART_CheckIdleState(husart)); +} + +/** + * @brief DeInitialize the USART peripheral. + * @param husart USART handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart) +{ + /* Check the USART handle allocation */ + if (husart == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_USART_INSTANCE(husart->Instance)); + + husart->State = HAL_USART_STATE_BUSY; + + husart->Instance->CR1 = 0x0U; + husart->Instance->CR2 = 0x0U; + husart->Instance->CR3 = 0x0U; + +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + if (husart->MspDeInitCallback == NULL) + { + husart->MspDeInitCallback = HAL_USART_MspDeInit; + } + /* DeInit the low level hardware */ + husart->MspDeInitCallback(husart); +#else + /* DeInit the low level hardware */ + HAL_USART_MspDeInit(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + + husart->ErrorCode = HAL_USART_ERROR_NONE; + husart->State = HAL_USART_STATE_RESET; + + /* Process Unlock */ + __HAL_UNLOCK(husart); + + return HAL_OK; +} + +/** + * @brief Initialize the USART MSP. + * @param husart USART handle. + * @retval None + */ +__weak void HAL_USART_MspInit(USART_HandleTypeDef *husart) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(husart); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_USART_MspInit can be implemented in the user file + */ +} + +/** + * @brief DeInitialize the USART MSP. + * @param husart USART handle. + * @retval None + */ +__weak void HAL_USART_MspDeInit(USART_HandleTypeDef *husart) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(husart); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_USART_MspDeInit can be implemented in the user file + */ +} + +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User USART Callback + * To be used to override the weak predefined callback + * @note The HAL_USART_RegisterCallback() may be called before HAL_USART_Init() in HAL_USART_STATE_RESET + * to register callbacks for HAL_USART_MSPINIT_CB_ID and HAL_USART_MSPDEINIT_CB_ID + * @param husart usart handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_USART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID + * @arg @ref HAL_USART_TX_COMPLETE_CB_ID Tx Complete Callback ID + * @arg @ref HAL_USART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID + * @arg @ref HAL_USART_RX_COMPLETE_CB_ID Rx Complete Callback ID + * @arg @ref HAL_USART_TX_RX_COMPLETE_CB_ID Rx Complete Callback ID + * @arg @ref HAL_USART_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_USART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID + * @arg @ref HAL_USART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID + * @arg @ref HAL_USART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID + * @arg @ref HAL_USART_MSPINIT_CB_ID MspInit Callback ID + * @arg @ref HAL_USART_MSPDEINIT_CB_ID MspDeInit Callback ID + * @param pCallback pointer to the Callback function + * @retval HAL status ++ */ +HAL_StatusTypeDef HAL_USART_RegisterCallback(USART_HandleTypeDef *husart, HAL_USART_CallbackIDTypeDef CallbackID, + pUSART_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + if (husart->State == HAL_USART_STATE_READY) + { + switch (CallbackID) + { + case HAL_USART_TX_HALFCOMPLETE_CB_ID : + husart->TxHalfCpltCallback = pCallback; + break; + + case HAL_USART_TX_COMPLETE_CB_ID : + husart->TxCpltCallback = pCallback; + break; + + case HAL_USART_RX_HALFCOMPLETE_CB_ID : + husart->RxHalfCpltCallback = pCallback; + break; + + case HAL_USART_RX_COMPLETE_CB_ID : + husart->RxCpltCallback = pCallback; + break; + + case HAL_USART_TX_RX_COMPLETE_CB_ID : + husart->TxRxCpltCallback = pCallback; + break; + + case HAL_USART_ERROR_CB_ID : + husart->ErrorCallback = pCallback; + break; + + case HAL_USART_ABORT_COMPLETE_CB_ID : + husart->AbortCpltCallback = pCallback; + break; + + case HAL_USART_RX_FIFO_FULL_CB_ID : + husart->RxFifoFullCallback = pCallback; + break; + + case HAL_USART_TX_FIFO_EMPTY_CB_ID : + husart->TxFifoEmptyCallback = pCallback; + break; + + case HAL_USART_MSPINIT_CB_ID : + husart->MspInitCallback = pCallback; + break; + + case HAL_USART_MSPDEINIT_CB_ID : + husart->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (husart->State == HAL_USART_STATE_RESET) + { + switch (CallbackID) + { + case HAL_USART_MSPINIT_CB_ID : + husart->MspInitCallback = pCallback; + break; + + case HAL_USART_MSPDEINIT_CB_ID : + husart->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister an USART Callback + * USART callaback is redirected to the weak predefined callback + * @note The HAL_USART_UnRegisterCallback() may be called before HAL_USART_Init() in HAL_USART_STATE_RESET + * to un-register callbacks for HAL_USART_MSPINIT_CB_ID and HAL_USART_MSPDEINIT_CB_ID + * @param husart usart handle + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_USART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID + * @arg @ref HAL_USART_TX_COMPLETE_CB_ID Tx Complete Callback ID + * @arg @ref HAL_USART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID + * @arg @ref HAL_USART_RX_COMPLETE_CB_ID Rx Complete Callback ID + * @arg @ref HAL_USART_TX_RX_COMPLETE_CB_ID Rx Complete Callback ID + * @arg @ref HAL_USART_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_USART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID + * @arg @ref HAL_USART_RX_FIFO_FULL_CB_ID Rx Fifo Full Callback ID + * @arg @ref HAL_USART_TX_FIFO_EMPTY_CB_ID Tx Fifo Empty Callback ID + * @arg @ref HAL_USART_MSPINIT_CB_ID MspInit Callback ID + * @arg @ref HAL_USART_MSPDEINIT_CB_ID MspDeInit Callback ID + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_UnRegisterCallback(USART_HandleTypeDef *husart, HAL_USART_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (HAL_USART_STATE_READY == husart->State) + { + switch (CallbackID) + { + case HAL_USART_TX_HALFCOMPLETE_CB_ID : + husart->TxHalfCpltCallback = HAL_USART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */ + break; + + case HAL_USART_TX_COMPLETE_CB_ID : + husart->TxCpltCallback = HAL_USART_TxCpltCallback; /* Legacy weak TxCpltCallback */ + break; + + case HAL_USART_RX_HALFCOMPLETE_CB_ID : + husart->RxHalfCpltCallback = HAL_USART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */ + break; + + case HAL_USART_RX_COMPLETE_CB_ID : + husart->RxCpltCallback = HAL_USART_RxCpltCallback; /* Legacy weak RxCpltCallback */ + break; + + case HAL_USART_TX_RX_COMPLETE_CB_ID : + husart->TxRxCpltCallback = HAL_USART_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */ + break; + + case HAL_USART_ERROR_CB_ID : + husart->ErrorCallback = HAL_USART_ErrorCallback; /* Legacy weak ErrorCallback */ + break; + + case HAL_USART_ABORT_COMPLETE_CB_ID : + husart->AbortCpltCallback = HAL_USART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ + break; + + case HAL_USART_RX_FIFO_FULL_CB_ID : + husart->RxFifoFullCallback = HAL_USARTEx_RxFifoFullCallback; /* Legacy weak RxFifoFullCallback */ + break; + + case HAL_USART_TX_FIFO_EMPTY_CB_ID : + husart->TxFifoEmptyCallback = HAL_USARTEx_TxFifoEmptyCallback; /* Legacy weak TxFifoEmptyCallback */ + break; + + case HAL_USART_MSPINIT_CB_ID : + husart->MspInitCallback = HAL_USART_MspInit; /* Legacy weak MspInitCallback */ + break; + + case HAL_USART_MSPDEINIT_CB_ID : + husart->MspDeInitCallback = HAL_USART_MspDeInit; /* Legacy weak MspDeInitCallback */ + break; + + default : + /* Update the error code */ + husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_USART_STATE_RESET == husart->State) + { + switch (CallbackID) + { + case HAL_USART_MSPINIT_CB_ID : + husart->MspInitCallback = HAL_USART_MspInit; + break; + + case HAL_USART_MSPDEINIT_CB_ID : + husart->MspDeInitCallback = HAL_USART_MspDeInit; + break; + + default : + /* Update the error code */ + husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + + +/** + * @} + */ + +/** @defgroup USART_Exported_Functions_Group2 IO operation functions + * @brief USART Transmit and Receive functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to manage the USART synchronous + data transfers. + + [..] The USART supports master mode only: it cannot receive or send data related to an input + clock (SCLK is always an output). + + [..] + + (#) There are two modes of transfer: + (++) Blocking mode: The communication is performed in polling mode. + The HAL status of all data processing is returned by the same function + after finishing transfer. + (++) No-Blocking mode: The communication is performed using Interrupts + or DMA, These API's return the HAL status. + The end of the data processing will be indicated through the + dedicated USART IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + The HAL_USART_TxCpltCallback(), HAL_USART_RxCpltCallback() and HAL_USART_TxRxCpltCallback() user callbacks + will be executed respectively at the end of the transmit or Receive process + The HAL_USART_ErrorCallback()user callback will be executed when a communication error is detected + + (#) Blocking mode API's are : + (++) HAL_USART_Transmit() in simplex mode + (++) HAL_USART_Receive() in full duplex receive only + (++) HAL_USART_TransmitReceive() in full duplex mode + + (#) Non-Blocking mode API's with Interrupt are : + (++) HAL_USART_Transmit_IT() in simplex mode + (++) HAL_USART_Receive_IT() in full duplex receive only + (++) HAL_USART_TransmitReceive_IT() in full duplex mode + (++) HAL_USART_IRQHandler() + + (#) No-Blocking mode API's with DMA are : + (++) HAL_USART_Transmit_DMA() in simplex mode + (++) HAL_USART_Receive_DMA() in full duplex receive only + (++) HAL_USART_TransmitReceive_DMA() in full duplex mode + (++) HAL_USART_DMAPause() + (++) HAL_USART_DMAResume() + (++) HAL_USART_DMAStop() + + (#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode: + (++) HAL_USART_TxCpltCallback() + (++) HAL_USART_RxCpltCallback() + (++) HAL_USART_TxHalfCpltCallback() + (++) HAL_USART_RxHalfCpltCallback() + (++) HAL_USART_ErrorCallback() + (++) HAL_USART_TxRxCpltCallback() + + (#) Non-Blocking mode transfers could be aborted using Abort API's : + (++) HAL_USART_Abort() + (++) HAL_USART_Abort_IT() + + (#) For Abort services based on interrupts (HAL_USART_Abort_IT), a Abort Complete Callbacks is provided: + (++) HAL_USART_AbortCpltCallback() + + (#) In Non-Blocking mode transfers, possible errors are split into 2 categories. + Errors are handled as follows : + (++) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is + to be evaluated by user : this concerns Frame Error, + Parity Error or Noise Error in Interrupt mode reception . + Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify + error type, and HAL_USART_ErrorCallback() user callback is executed. + Transfer is kept ongoing on USART side. + If user wants to abort it, Abort services should be called by user. + (++) Error is considered as Blocking : Transfer could not be completed properly and is aborted. + This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode. + Error code is set to allow user to identify error type, + and HAL_USART_ErrorCallback() user callback is executed. + +@endverbatim + * @{ + */ + +/** + * @brief Simplex send an amount of data in blocking mode. + * @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * the sent data is handled as a set of u16. In this case, Size must indicate the number + * of u16 provided through pTxData. + * @param husart USART handle. + * @param pTxData Pointer to data buffer (u8 or u16 data elements). + * @param Size Amount of data elements (u8 or u16) to be sent. + * @param Timeout Timeout duration. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint16_t Size, + uint32_t Timeout) +{ + const uint8_t *ptxdata8bits; + const uint16_t *ptxdata16bits; + uint32_t tickstart; + + if (husart->State == HAL_USART_STATE_READY) + { + if ((pTxData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(husart); + + /* Disable the USART DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT)) + { + CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT); + } + + husart->ErrorCode = HAL_USART_ERROR_NONE; + husart->State = HAL_USART_STATE_BUSY_TX; + + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + + husart->TxXferSize = Size; + husart->TxXferCount = Size; + + /* In case of 9bits/No Parity transfer, pTxData needs to be handled as a uint16_t pointer */ + if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) + { + ptxdata8bits = NULL; + ptxdata16bits = (const uint16_t *) pTxData; + } + else + { + ptxdata8bits = pTxData; + ptxdata16bits = NULL; + } + + /* Check the remaining data to be sent */ + while (husart->TxXferCount > 0U) + { + if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + if (ptxdata8bits == NULL) + { + husart->Instance->TDR = (uint16_t)(*ptxdata16bits & 0x01FFU); + ptxdata16bits++; + } + else + { + husart->Instance->TDR = (uint8_t)(*ptxdata8bits & 0xFFU); + ptxdata8bits++; + } + + husart->TxXferCount--; + } + + if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Clear Transmission Complete Flag */ + __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF); + + /* Clear overrun flag and discard the received data */ + __HAL_USART_CLEAR_OREFLAG(husart); + __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST); + __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST); + + /* At end of Tx process, restore husart->State to Ready */ + husart->State = HAL_USART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in blocking mode. + * @note To receive synchronous data, dummy data are simultaneously transmitted. + * @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * the received data is handled as a set of u16. In this case, Size must indicate the number + * of u16 available through pRxData. + * @param husart USART handle. + * @param pRxData Pointer to data buffer (u8 or u16 data elements). + * @param Size Amount of data elements (u8 or u16) to be received. + * @param Timeout Timeout duration. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout) +{ + uint8_t *prxdata8bits; + uint16_t *prxdata16bits; + uint16_t uhMask; + uint32_t tickstart; + + if (husart->State == HAL_USART_STATE_READY) + { + if ((pRxData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(husart); + + /* Disable the USART DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR); + } + + husart->ErrorCode = HAL_USART_ERROR_NONE; + husart->State = HAL_USART_STATE_BUSY_RX; + + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + + husart->RxXferSize = Size; + husart->RxXferCount = Size; + + /* Computation of USART mask to apply to RDR register */ + USART_MASK_COMPUTATION(husart); + uhMask = husart->Mask; + + /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */ + if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) + { + prxdata8bits = NULL; + prxdata16bits = (uint16_t *) pRxData; + } + else + { + prxdata8bits = pRxData; + prxdata16bits = NULL; + } + + /* as long as data have to be received */ + while (husart->RxXferCount > 0U) + { + if (husart->SlaveMode == USART_SLAVEMODE_DISABLE) + { + /* Wait until TXE flag is set to send dummy byte in order to generate the + * clock for the slave to send data. + * Whatever the frame length (7, 8 or 9-bit long), the same dummy value + * can be written for all the cases. */ + if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x0FF); + } + + /* Wait for RXNE Flag */ + if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + if (prxdata8bits == NULL) + { + *prxdata16bits = (uint16_t)(husart->Instance->RDR & uhMask); + prxdata16bits++; + } + else + { + *prxdata8bits = (uint8_t)(husart->Instance->RDR & (uint8_t)(uhMask & 0xFFU)); + prxdata8bits++; + } + + husart->RxXferCount--; + + } + + /* Clear SPI slave underrun flag and discard transmit data */ + if (husart->SlaveMode == USART_SLAVEMODE_ENABLE) + { + __HAL_USART_CLEAR_UDRFLAG(husart); + __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST); + } + + /* At end of Rx process, restore husart->State to Ready */ + husart->State = HAL_USART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Full-Duplex Send and Receive an amount of data in blocking mode. + * @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * the sent data and the received data are handled as sets of u16. In this case, Size must indicate the number + * of u16 available through pTxData and through pRxData. + * @param husart USART handle. + * @param pTxData pointer to TX data buffer (u8 or u16 data elements). + * @param pRxData pointer to RX data buffer (u8 or u16 data elements). + * @param Size amount of data elements (u8 or u16) to be sent (same amount to be received). + * @param Timeout Timeout duration. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint8_t *pRxData, + uint16_t Size, uint32_t Timeout) +{ + uint8_t *prxdata8bits; + uint16_t *prxdata16bits; + const uint8_t *ptxdata8bits; + const uint16_t *ptxdata16bits; + uint16_t uhMask; + uint16_t rxdatacount; + uint32_t tickstart; + + if (husart->State == HAL_USART_STATE_READY) + { + if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(husart); + + /* Disable the USART DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT)) + { + CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT); + } + + /* Disable the USART DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR); + } + + husart->ErrorCode = HAL_USART_ERROR_NONE; + husart->State = HAL_USART_STATE_BUSY_RX; + + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + + husart->RxXferSize = Size; + husart->TxXferSize = Size; + husart->TxXferCount = Size; + husart->RxXferCount = Size; + + /* Computation of USART mask to apply to RDR register */ + USART_MASK_COMPUTATION(husart); + uhMask = husart->Mask; + + /* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */ + if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) + { + prxdata8bits = NULL; + ptxdata8bits = NULL; + ptxdata16bits = (const uint16_t *) pTxData; + prxdata16bits = (uint16_t *) pRxData; + } + else + { + prxdata8bits = pRxData; + ptxdata8bits = pTxData; + ptxdata16bits = NULL; + prxdata16bits = NULL; + } + + if ((husart->TxXferCount == 0x01U) || (husart->SlaveMode == USART_SLAVEMODE_ENABLE)) + { + /* Wait until TXE flag is set to send data */ + if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + if (ptxdata8bits == NULL) + { + husart->Instance->TDR = (uint16_t)(*ptxdata16bits & uhMask); + ptxdata16bits++; + } + else + { + husart->Instance->TDR = (uint8_t)(*ptxdata8bits & (uint8_t)(uhMask & 0xFFU)); + ptxdata8bits++; + } + + husart->TxXferCount--; + } + + /* Check the remain data to be sent */ + /* rxdatacount is a temporary variable for MISRAC2012-Rule-13.5 */ + rxdatacount = husart->RxXferCount; + while ((husart->TxXferCount > 0U) || (rxdatacount > 0U)) + { + if (husart->TxXferCount > 0U) + { + /* Wait until TXE flag is set to send data */ + if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + if (ptxdata8bits == NULL) + { + husart->Instance->TDR = (uint16_t)(*ptxdata16bits & uhMask); + ptxdata16bits++; + } + else + { + husart->Instance->TDR = (uint8_t)(*ptxdata8bits & (uint8_t)(uhMask & 0xFFU)); + ptxdata8bits++; + } + + husart->TxXferCount--; + } + + if (husart->RxXferCount > 0U) + { + /* Wait for RXNE Flag */ + if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + if (prxdata8bits == NULL) + { + *prxdata16bits = (uint16_t)(husart->Instance->RDR & uhMask); + prxdata16bits++; + } + else + { + *prxdata8bits = (uint8_t)(husart->Instance->RDR & (uint8_t)(uhMask & 0xFFU)); + prxdata8bits++; + } + + husart->RxXferCount--; + } + rxdatacount = husart->RxXferCount; + } + + /* At end of TxRx process, restore husart->State to Ready */ + husart->State = HAL_USART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Send an amount of data in interrupt mode. + * @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * the sent data is handled as a set of u16. In this case, Size must indicate the number + * of u16 provided through pTxData. + * @param husart USART handle. + * @param pTxData pointer to data buffer (u8 or u16 data elements). + * @param Size amount of data elements (u8 or u16) to be sent. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint16_t Size) +{ + if (husart->State == HAL_USART_STATE_READY) + { + if ((pTxData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(husart); + + /* Disable the USART DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT)) + { + CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT); + } + + husart->pTxBuffPtr = pTxData; + husart->TxXferSize = Size; + husart->TxXferCount = Size; + husart->TxISR = NULL; + + husart->ErrorCode = HAL_USART_ERROR_NONE; + husart->State = HAL_USART_STATE_BUSY_TX; + + /* The USART Error Interrupts: (Frame error, noise error, overrun error) + are not managed by the USART Transmit Process to avoid the overrun interrupt + when the usart mode is configured for transmit and receive "USART_MODE_TX_RX" + to benefit for the frame error and noise interrupts the usart mode should be + configured only for transmit "USART_MODE_TX" */ + + /* Configure Tx interrupt processing */ + if (husart->FifoMode == USART_FIFOMODE_ENABLE) + { + /* Set the Tx ISR function pointer according to the data word length */ + if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) + { + husart->TxISR = USART_TxISR_16BIT_FIFOEN; + } + else + { + husart->TxISR = USART_TxISR_8BIT_FIFOEN; + } + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + /* Enable the TX FIFO threshold interrupt */ + __HAL_USART_ENABLE_IT(husart, USART_IT_TXFT); + } + else + { + /* Set the Tx ISR function pointer according to the data word length */ + if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) + { + husart->TxISR = USART_TxISR_16BIT; + } + else + { + husart->TxISR = USART_TxISR_8BIT; + } + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + /* Enable the USART Transmit Data Register Empty Interrupt */ + __HAL_USART_ENABLE_IT(husart, USART_IT_TXE); + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in interrupt mode. + * @note To receive synchronous data, dummy data are simultaneously transmitted. + * @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * the received data is handled as a set of u16. In this case, Size must indicate the number + * of u16 available through pRxData. + * @param husart USART handle. + * @param pRxData pointer to data buffer (u8 or u16 data elements). + * @param Size amount of data elements (u8 or u16) to be received. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size) +{ + uint16_t nb_dummy_data; + + if (husart->State == HAL_USART_STATE_READY) + { + if ((pRxData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(husart); + + /* Disable the USART DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR); + } + + husart->pRxBuffPtr = pRxData; + husart->RxXferSize = Size; + husart->RxXferCount = Size; + husart->RxISR = NULL; + + USART_MASK_COMPUTATION(husart); + + husart->ErrorCode = HAL_USART_ERROR_NONE; + husart->State = HAL_USART_STATE_BUSY_RX; + + /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */ + SET_BIT(husart->Instance->CR3, USART_CR3_EIE); + + /* Configure Rx interrupt processing */ + if ((husart->FifoMode == USART_FIFOMODE_ENABLE) && (Size >= husart->NbRxDataToProcess)) + { + /* Set the Rx ISR function pointer according to the data word length */ + if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) + { + husart->RxISR = USART_RxISR_16BIT_FIFOEN; + } + else + { + husart->RxISR = USART_RxISR_8BIT_FIFOEN; + } + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + /* Enable the USART Parity Error interrupt and RX FIFO Threshold interrupt */ + if (husart->Init.Parity != USART_PARITY_NONE) + { + SET_BIT(husart->Instance->CR1, USART_CR1_PEIE); + } + SET_BIT(husart->Instance->CR3, USART_CR3_RXFTIE); + } + else + { + /* Set the Rx ISR function pointer according to the data word length */ + if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) + { + husart->RxISR = USART_RxISR_16BIT; + } + else + { + husart->RxISR = USART_RxISR_8BIT; + } + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + /* Enable the USART Parity Error and Data Register not empty Interrupts */ + if (husart->Init.Parity != USART_PARITY_NONE) + { + SET_BIT(husart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE); + } + else + { + SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE); + } + } + + if (husart->SlaveMode == USART_SLAVEMODE_DISABLE) + { + /* Send dummy data in order to generate the clock for the Slave to send the next data. + When FIFO mode is disabled only one data must be transferred. + When FIFO mode is enabled data must be transmitted until the RX FIFO reaches its threshold. + */ + if ((husart->FifoMode == USART_FIFOMODE_ENABLE) && (Size >= husart->NbRxDataToProcess)) + { + for (nb_dummy_data = husart->NbRxDataToProcess ; nb_dummy_data > 0U ; nb_dummy_data--) + { + husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF); + } + } + else + { + husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF); + } + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Full-Duplex Send and Receive an amount of data in interrupt mode. + * @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * the sent data and the received data are handled as sets of u16. In this case, Size must indicate the number + * of u16 available through pTxData and through pRxData. + * @param husart USART handle. + * @param pTxData pointer to TX data buffer (u8 or u16 data elements). + * @param pRxData pointer to RX data buffer (u8 or u16 data elements). + * @param Size amount of data elements (u8 or u16) to be sent (same amount to be received). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint8_t *pRxData, + uint16_t Size) +{ + + if (husart->State == HAL_USART_STATE_READY) + { + if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(husart); + + /* Disable the USART DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT)) + { + CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT); + } + + /* Disable the USART DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR); + } + + husart->pRxBuffPtr = pRxData; + husart->RxXferSize = Size; + husart->RxXferCount = Size; + husart->pTxBuffPtr = pTxData; + husart->TxXferSize = Size; + husart->TxXferCount = Size; + + /* Computation of USART mask to apply to RDR register */ + USART_MASK_COMPUTATION(husart); + + husart->ErrorCode = HAL_USART_ERROR_NONE; + husart->State = HAL_USART_STATE_BUSY_TX_RX; + + /* Configure TxRx interrupt processing */ + if ((husart->FifoMode == USART_FIFOMODE_ENABLE) && (Size >= husart->NbRxDataToProcess)) + { + /* Set the Rx ISR function pointer according to the data word length */ + if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) + { + husart->TxISR = USART_TxISR_16BIT_FIFOEN; + husart->RxISR = USART_RxISR_16BIT_FIFOEN; + } + else + { + husart->TxISR = USART_TxISR_8BIT_FIFOEN; + husart->RxISR = USART_RxISR_8BIT_FIFOEN; + } + + /* Process Locked */ + __HAL_UNLOCK(husart); + + /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */ + SET_BIT(husart->Instance->CR3, USART_CR3_EIE); + + if (husart->Init.Parity != USART_PARITY_NONE) + { + /* Enable the USART Parity Error interrupt */ + SET_BIT(husart->Instance->CR1, USART_CR1_PEIE); + } + + /* Enable the TX and RX FIFO Threshold interrupts */ + SET_BIT(husart->Instance->CR3, (USART_CR3_TXFTIE | USART_CR3_RXFTIE)); + } + else + { + if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) + { + husart->TxISR = USART_TxISR_16BIT; + husart->RxISR = USART_RxISR_16BIT; + } + else + { + husart->TxISR = USART_TxISR_8BIT; + husart->RxISR = USART_RxISR_8BIT; + } + + /* Process Locked */ + __HAL_UNLOCK(husart); + + /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */ + SET_BIT(husart->Instance->CR3, USART_CR3_EIE); + + /* Enable the USART Parity Error and USART Data Register not empty Interrupts */ + if (husart->Init.Parity != USART_PARITY_NONE) + { + SET_BIT(husart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE); + } + else + { + SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE); + } + + /* Enable the USART Transmit Data Register Empty Interrupt */ + SET_BIT(husart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE); + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief Send an amount of data in DMA mode. + * @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * the sent data is handled as a set of u16. In this case, Size must indicate the number + * of u16 provided through pTxData. + * @param husart USART handle. + * @param pTxData pointer to data buffer (u8 or u16 data elements). + * @param Size amount of data elements (u8 or u16) to be sent. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint16_t Size) +{ + HAL_StatusTypeDef status = HAL_OK; + const uint32_t *tmp; + uint16_t nbByte = Size; + + if (husart->State == HAL_USART_STATE_READY) + { + if ((pTxData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(husart); + + husart->pTxBuffPtr = pTxData; + husart->TxXferSize = Size; + husart->TxXferCount = Size; + + husart->ErrorCode = HAL_USART_ERROR_NONE; + husart->State = HAL_USART_STATE_BUSY_TX; + + if (husart->hdmatx != NULL) + { + /* Set the USART DMA transfer complete callback */ + husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt; + + /* Set the USART DMA Half transfer complete callback */ + husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt; + + /* Set the DMA error callback */ + husart->hdmatx->XferErrorCallback = USART_DMAError; + + /* In case of 9bits/No Parity transfer, pTxData buffer provided as input parameter + should be aligned on a u16 frontier, so nbByte should be equal to Size multiplied by 2 */ + if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) + { + nbByte = Size * 2U; + } + + tmp = (const uint32_t *)&pTxData; + + /* Check linked list mode */ + if ((husart->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((husart->hdmatx->LinkedListQueue != NULL) && (husart->hdmatx->LinkedListQueue->Head != NULL)) + { + /* Set DMA data size */ + husart->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = nbByte; + + /* Set DMA source address */ + husart->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = *(const uint32_t *)tmp; + + /* Set DMA destination address */ + husart->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = + (uint32_t)&husart->Instance->TDR; + + /* Enable the USART transmit DMA channel */ + status = HAL_DMAEx_List_Start_IT(husart->hdmatx); + } + else + { + /* Update status */ + status = HAL_ERROR; + } + } + else + { + /* Enable the USART transmit DMA channel */ + status = HAL_DMA_Start_IT(husart->hdmatx, *(const uint32_t *)tmp, (uint32_t)&husart->Instance->TDR, nbByte); + } + } + + if (status == HAL_OK) + { + /* Clear the TC flag in the ICR register */ + __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF); + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + /* Enable the DMA transfer for transmit request by setting the DMAT bit + in the USART CR3 register */ + SET_BIT(husart->Instance->CR3, USART_CR3_DMAT); + + return HAL_OK; + } + else + { + /* Set error code to DMA */ + husart->ErrorCode = HAL_USART_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + /* Restore husart->State to ready */ + husart->State = HAL_USART_STATE_READY; + + return HAL_ERROR; + } + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in DMA mode. + * @note When the USART parity is enabled (PCE = 1), the received data contain + * the parity bit (MSB position). + * @note The USART DMA transmit channel must be configured in order to generate the clock for the slave. + * @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * the received data is handled as a set of u16. In this case, Size must indicate the number + * of u16 available through pRxData. + * @param husart USART handle. + * @param pRxData pointer to data buffer (u8 or u16 data elements). + * @param Size amount of data elements (u8 or u16) to be received. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t *tmp = (uint32_t *)&pRxData; + uint16_t nbByte = Size; + + /* Check that a Rx process is not already ongoing */ + if (husart->State == HAL_USART_STATE_READY) + { + if ((pRxData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(husart); + + husart->pRxBuffPtr = pRxData; + husart->RxXferSize = Size; + husart->pTxBuffPtr = pRxData; + husart->TxXferSize = Size; + + husart->ErrorCode = HAL_USART_ERROR_NONE; + husart->State = HAL_USART_STATE_BUSY_RX; + + if (husart->hdmarx != NULL) + { + /* Set the USART DMA Rx transfer complete callback */ + husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt; + + /* Set the USART DMA Half transfer complete callback */ + husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt; + + /* Set the USART DMA Rx transfer error callback */ + husart->hdmarx->XferErrorCallback = USART_DMAError; + + /* In case of 9bits/No Parity transfer, pTxData buffer provided as input parameter + should be aligned on a u16 frontier, so nbByte should be equal to Size multiplied by 2 */ + if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) + { + nbByte = Size * 2U; + } + + /* Check linked list mode */ + if ((husart->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((husart->hdmarx->LinkedListQueue != NULL) && (husart->hdmarx->LinkedListQueue->Head != NULL)) + { + /* Set DMA data size */ + husart->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = nbByte; + + /* Set DMA source address */ + husart->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = + (uint32_t)&husart->Instance->RDR; + + /* Set DMA destination address */ + husart->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = *(uint32_t *)tmp; + + /* Enable the USART receive DMA channel */ + status = HAL_DMAEx_List_Start_IT(husart->hdmarx); + } + else + { + /* Update status */ + status = HAL_ERROR; + } + } + else + { + /* Enable the USART receive DMA channel */ + status = HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(uint32_t *)tmp, nbByte); + } + } + + if ((status == HAL_OK) && + (husart->SlaveMode == USART_SLAVEMODE_DISABLE)) + { + /* Enable the USART transmit DMA channel: the transmit channel is used in order + to generate in the non-blocking mode the clock to the slave device, + this mode isn't a simplex receive mode but a full-duplex receive mode */ + + /* Set the USART DMA Tx Complete and Error callback to Null */ + if (husart->hdmatx != NULL) + { + husart->hdmatx->XferErrorCallback = NULL; + husart->hdmatx->XferHalfCpltCallback = NULL; + husart->hdmatx->XferCpltCallback = NULL; + + /* Check linked list mode */ + if ((husart->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((husart->hdmatx->LinkedListQueue != NULL) && (husart->hdmatx->LinkedListQueue->Head != NULL)) + { + /* Set DMA data size */ + husart->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = nbByte; + + /* Set DMA source address */ + husart->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = *(uint32_t *)tmp; + + /* Set DMA destination address */ + husart->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = + (uint32_t)&husart->Instance->TDR; + + /* Enable the USART transmit DMA channel */ + status = HAL_DMAEx_List_Start_IT(husart->hdmatx); + } + else + { + /* Update status */ + status = HAL_ERROR; + } + } + else + { + status = HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t *)tmp, (uint32_t)&husart->Instance->TDR, nbByte); + } + } + } + + if (status == HAL_OK) + { + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + if (husart->Init.Parity != USART_PARITY_NONE) + { + /* Enable the USART Parity Error Interrupt */ + SET_BIT(husart->Instance->CR1, USART_CR1_PEIE); + } + + /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */ + SET_BIT(husart->Instance->CR3, USART_CR3_EIE); + + /* Enable the DMA transfer for the receiver request by setting the DMAR bit + in the USART CR3 register */ + SET_BIT(husart->Instance->CR3, USART_CR3_DMAR); + + /* Enable the DMA transfer for transmit request by setting the DMAT bit + in the USART CR3 register */ + SET_BIT(husart->Instance->CR3, USART_CR3_DMAT); + + return HAL_OK; + } + else + { + if ((husart->hdmarx != NULL) && ((husart->hdmarx->Mode & DMA_LINKEDLIST) != DMA_LINKEDLIST)) + { + status = HAL_DMA_Abort(husart->hdmarx); + } + + /* No need to check on error code */ + UNUSED(status); + + /* Set error code to DMA */ + husart->ErrorCode = HAL_USART_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + /* Restore husart->State to ready */ + husart->State = HAL_USART_STATE_READY; + + return HAL_ERROR; + } + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Full-Duplex Transmit Receive an amount of data in non-blocking mode. + * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit. + * @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01), + * the sent data and the received data are handled as sets of u16. In this case, Size must indicate the number + * of u16 available through pTxData and through pRxData. + * @param husart USART handle. + * @param pTxData pointer to TX data buffer (u8 or u16 data elements). + * @param pRxData pointer to RX data buffer (u8 or u16 data elements). + * @param Size amount of data elements (u8 or u16) to be received/sent. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, const uint8_t *pTxData, uint8_t *pRxData, + uint16_t Size) +{ + HAL_StatusTypeDef status; + const uint32_t *tmp; + uint16_t nbByte = Size; + + if (husart->State == HAL_USART_STATE_READY) + { + if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(husart); + + husart->pRxBuffPtr = pRxData; + husart->RxXferSize = Size; + husart->pTxBuffPtr = pTxData; + husart->TxXferSize = Size; + + husart->ErrorCode = HAL_USART_ERROR_NONE; + husart->State = HAL_USART_STATE_BUSY_TX_RX; + + if ((husart->hdmarx != NULL) && (husart->hdmatx != NULL)) + { + /* Set the USART DMA Rx transfer complete callback */ + husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt; + + /* Set the USART DMA Half transfer complete callback */ + husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt; + + /* Set the USART DMA Tx transfer complete callback */ + husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt; + + /* Set the USART DMA Half transfer complete callback */ + husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt; + + /* Set the USART DMA Tx transfer error callback */ + husart->hdmatx->XferErrorCallback = USART_DMAError; + + /* Set the USART DMA Rx transfer error callback */ + husart->hdmarx->XferErrorCallback = USART_DMAError; + + /* In case of 9bits/No Parity transfer, pTxData buffer provided as input parameter + should be aligned on a u16 frontier, so nbByte should be equal to Size multiplied by 2 */ + if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE)) + { + nbByte = Size * 2U; + } + + /* Check linked list mode */ + tmp = (uint32_t *)&pRxData; + if ((husart->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((husart->hdmarx->LinkedListQueue != NULL) && (husart->hdmarx->LinkedListQueue->Head != NULL)) + { + /* Set DMA data size */ + husart->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = nbByte; + + /* Set DMA source address */ + husart->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = + (uint32_t)&husart->Instance->RDR; + + /* Set DMA destination address */ + husart->hdmarx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = *(const uint32_t *)tmp; + + /* Enable the USART receive DMA channel */ + status = HAL_DMAEx_List_Start_IT(husart->hdmarx); + } + else + { + /* Update status */ + status = HAL_ERROR; + } + } + else + { + /* Enable the USART receive DMA channel */ + status = HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(const uint32_t *)tmp, nbByte); + } + + /* Enable the USART transmit DMA channel */ + if (status == HAL_OK) + { + tmp = (const uint32_t *)&pTxData; + + /* Check linked list mode */ + if ((husart->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if ((husart->hdmatx->LinkedListQueue != NULL) && (husart->hdmatx->LinkedListQueue->Head != NULL)) + { + /* Set DMA data size */ + husart->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = nbByte; + + /* Set DMA source address */ + husart->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = *(const uint32_t *)tmp; + + /* Set DMA destination address */ + husart->hdmatx->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = + (uint32_t)&husart->Instance->TDR; + + /* Enable the USART transmit DMA channel */ + status = HAL_DMAEx_List_Start_IT(husart->hdmatx); + } + else + { + /* Update status */ + status = HAL_ERROR; + } + } + else + { + status = HAL_DMA_Start_IT(husart->hdmatx, *(const uint32_t *)tmp, (uint32_t)&husart->Instance->TDR, nbByte); + } + } + } + else + { + status = HAL_ERROR; + } + + if (status == HAL_OK) + { + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + if (husart->Init.Parity != USART_PARITY_NONE) + { + /* Enable the USART Parity Error Interrupt */ + SET_BIT(husart->Instance->CR1, USART_CR1_PEIE); + } + + /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */ + SET_BIT(husart->Instance->CR3, USART_CR3_EIE); + + /* Clear the TC flag in the ICR register */ + __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_TCF); + + /* Enable the DMA transfer for the receiver request by setting the DMAR bit + in the USART CR3 register */ + SET_BIT(husart->Instance->CR3, USART_CR3_DMAR); + + /* Enable the DMA transfer for transmit request by setting the DMAT bit + in the USART CR3 register */ + SET_BIT(husart->Instance->CR3, USART_CR3_DMAT); + + return HAL_OK; + } + else + { + if ((husart->hdmarx != NULL) && ((husart->hdmarx->Mode & DMA_LINKEDLIST) != DMA_LINKEDLIST)) + { + status = HAL_DMA_Abort(husart->hdmarx); + } + + /* No need to check on error code */ + UNUSED(status); + + /* Set error code to DMA */ + husart->ErrorCode = HAL_USART_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + /* Restore husart->State to ready */ + husart->State = HAL_USART_STATE_READY; + + return HAL_ERROR; + } + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Pause the DMA Transfer. + * @param husart USART handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart) +{ + const HAL_USART_StateTypeDef state = husart->State; + + /* Process Locked */ + __HAL_LOCK(husart); + + if ((HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT)) && + (state == HAL_USART_STATE_BUSY_TX)) + { + /* Suspend the USART DMA Tx channel : use blocking DMA Suspend API (no callback) */ + if (husart->hdmatx != NULL) + { + /* Set the USART DMA Suspend callback to Null. + No call back execution at end of DMA Suspend procedure */ + husart->hdmatx->XferSuspendCallback = NULL; + + if (HAL_DMAEx_Suspend(husart->hdmatx) != HAL_OK) + { + if (HAL_DMA_GetError(husart->hdmatx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + husart->ErrorCode = HAL_USART_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + } + } + else if ((state == HAL_USART_STATE_BUSY_RX) || + (state == HAL_USART_STATE_BUSY_TX_RX)) + { + /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE); + CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE); + + /* Set the USART DMA Suspend callback to Null. + No call back execution at end of DMA Suspend procedure */ + husart->hdmarx->XferSuspendCallback = NULL; + + if (HAL_DMAEx_Suspend(husart->hdmarx) != HAL_OK) + { + if (HAL_DMA_GetError(husart->hdmarx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + husart->ErrorCode = HAL_USART_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + + if (state == HAL_USART_STATE_BUSY_TX_RX) + { + /* Set the USART DMA Suspend callback to Null. + No call back execution at end of DMA Suspend procedure */ + husart->hdmatx->XferSuspendCallback = NULL; + + if (HAL_DMAEx_Suspend(husart->hdmatx) != HAL_OK) + { + if (HAL_DMA_GetError(husart->hdmatx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + husart->ErrorCode = HAL_USART_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + } + } + else + { + /* Nothing to do */ + } + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + return HAL_OK; +} + +/** + * @brief Resume the DMA Transfer. + * @param husart USART handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart) +{ + const HAL_USART_StateTypeDef state = husart->State; + + /* Process Locked */ + __HAL_LOCK(husart); + + if (state == HAL_USART_STATE_BUSY_TX) + { + /* Resume the USART DMA Tx channel */ + if (husart->hdmatx != NULL) + { + if (HAL_DMAEx_Resume(husart->hdmatx) != HAL_OK) + { + /* Set error code to DMA */ + husart->ErrorCode = HAL_USART_ERROR_DMA; + + return HAL_ERROR; + } + } + } + else if ((state == HAL_USART_STATE_BUSY_RX) || + (state == HAL_USART_STATE_BUSY_TX_RX)) + { + /* Clear the Overrun flag before resuming the Rx transfer*/ + __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF); + + /* Re-enable PE and ERR (Frame error, noise error, overrun error) interrupts */ + if (husart->Init.Parity != USART_PARITY_NONE) + { + SET_BIT(husart->Instance->CR1, USART_CR1_PEIE); + } + SET_BIT(husart->Instance->CR3, USART_CR3_EIE); + + /* Resume the USART DMA Rx channel */ + if (husart->hdmarx != NULL) + { + if (HAL_DMAEx_Resume(husart->hdmarx) != HAL_OK) + { + /* Set error code to DMA */ + husart->ErrorCode = HAL_USART_ERROR_DMA; + + return HAL_ERROR; + } + } + + if (state == HAL_USART_STATE_BUSY_TX_RX) + { + /* Resume the USART DMA Tx channel */ + if (husart->hdmatx != NULL) + { + if (HAL_DMAEx_Resume(husart->hdmatx) != HAL_OK) + { + /* Set error code to DMA */ + husart->ErrorCode = HAL_USART_ERROR_DMA; + + return HAL_ERROR; + } + } + } + } + else + { + /* Nothing to do */ + } + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + return HAL_OK; +} + +/** + * @brief Stop the DMA Transfer. + * @param husart USART handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart) +{ + /* The Lock is not implemented on this API to allow the user application + to call the HAL USART API under callbacks HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback() / + HAL_USART_TxHalfCpltCallback / HAL_USART_RxHalfCpltCallback: + indeed, when HAL_DMA_Abort() API is called, the DMA TX/RX Transfer or Half Transfer complete + interrupt is generated if the DMA transfer interruption occurs at the middle or at the end of + the stream and the corresponding call back is executed. */ + + /* Disable the USART Tx/Rx DMA requests */ + CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT); + CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR); + + /* Abort the USART DMA tx channel */ + if (husart->hdmatx != NULL) + { + if (HAL_DMA_Abort(husart->hdmatx) != HAL_OK) + { + if (HAL_DMA_GetError(husart->hdmatx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + husart->ErrorCode = HAL_USART_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + } + /* Abort the USART DMA rx channel */ + if (husart->hdmarx != NULL) + { + if (HAL_DMA_Abort(husart->hdmarx) != HAL_OK) + { + if (HAL_DMA_GetError(husart->hdmarx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + husart->ErrorCode = HAL_USART_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + } + + USART_EndTransfer(husart); + husart->State = HAL_USART_STATE_READY; + + return HAL_OK; +} +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Abort ongoing transfers (blocking mode). + * @param husart USART handle. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable USART Interrupts (Tx and Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_Abort(USART_HandleTypeDef *husart) +{ + /* Disable TXEIE, TCIE, RXNE, RXFT, TXFT, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE | + USART_CR1_TCIE)); + CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE)); + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Abort the USART DMA Tx channel if enabled */ + if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT)) + { + /* Abort the USART DMA Tx channel : use blocking DMA Abort API (no callback) */ + if (husart->hdmatx != NULL) + { + /* Set the USART DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + husart->hdmatx->XferAbortCallback = NULL; + + if (HAL_DMA_Abort(husart->hdmatx) != HAL_OK) + { + if (HAL_DMA_GetError(husart->hdmatx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + husart->ErrorCode = HAL_USART_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + } + } + + /* Abort the USART DMA Rx channel if enabled */ + if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR)) + { + /* Abort the USART DMA Rx channel : use blocking DMA Abort API (no callback) */ + if (husart->hdmarx != NULL) + { + /* Set the USART DMA Abort callback to Null. + No call back execution at end of DMA abort procedure */ + husart->hdmarx->XferAbortCallback = NULL; + + if (HAL_DMA_Abort(husart->hdmarx) != HAL_OK) + { + if (HAL_DMA_GetError(husart->hdmarx) == HAL_DMA_ERROR_TIMEOUT) + { + /* Set error code to DMA */ + husart->ErrorCode = HAL_USART_ERROR_DMA; + + return HAL_TIMEOUT; + } + } + } + } +#endif /* HAL_DMA_MODULE_ENABLED */ + + /* Reset Tx and Rx transfer counters */ + husart->TxXferCount = 0U; + husart->RxXferCount = 0U; + + /* Clear the Error flags in the ICR register */ + __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF); + + /* Flush the whole TX FIFO (if needed) */ + if (husart->FifoMode == USART_FIFOMODE_ENABLE) + { + __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST); + } + + /* Discard the received data */ + __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST); + + /* Restore husart->State to Ready */ + husart->State = HAL_USART_STATE_READY; + + /* Reset Handle ErrorCode to No Error */ + husart->ErrorCode = HAL_USART_ERROR_NONE; + + return HAL_OK; +} + +/** + * @brief Abort ongoing transfers (Interrupt mode). + * @param husart USART handle. + * @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable USART Interrupts (Tx and Rx) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be + * considered as completed only when user abort complete callback is executed (not when exiting function). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_Abort_IT(USART_HandleTypeDef *husart) +{ + uint32_t abortcplt = 1U; + + /* Disable TXEIE, TCIE, RXNE, RXFT, TXFT, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE | + USART_CR1_TCIE)); + CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE)); + +#if defined(HAL_DMA_MODULE_ENABLED) + /* If DMA Tx and/or DMA Rx Handles are associated to USART Handle, DMA Abort complete callbacks should be initialised + before any call to DMA Abort functions */ + /* DMA Tx Handle is valid */ + if (husart->hdmatx != NULL) + { + /* Set DMA Abort Complete callback if USART DMA Tx request if enabled. + Otherwise, set it to NULL */ + if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT)) + { + husart->hdmatx->XferAbortCallback = USART_DMATxAbortCallback; + } + else + { + husart->hdmatx->XferAbortCallback = NULL; + } + } + /* DMA Rx Handle is valid */ + if (husart->hdmarx != NULL) + { + /* Set DMA Abort Complete callback if USART DMA Rx request if enabled. + Otherwise, set it to NULL */ + if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR)) + { + husart->hdmarx->XferAbortCallback = USART_DMARxAbortCallback; + } + else + { + husart->hdmarx->XferAbortCallback = NULL; + } + } + + /* Abort the USART DMA Tx channel if enabled */ + if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT)) + { + /* Abort the USART DMA Tx channel : use non blocking DMA Abort API (callback) */ + if (husart->hdmatx != NULL) + { + /* USART Tx DMA Abort callback has already been initialised : + will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */ + + /* Abort DMA TX */ + if (HAL_DMA_Abort_IT(husart->hdmatx) != HAL_OK) + { + husart->hdmatx->XferAbortCallback = NULL; + } + else + { + abortcplt = 0U; + } + } + } + + /* Abort the USART DMA Rx channel if enabled */ + if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR)) + { + /* Abort the USART DMA Rx channel : use non blocking DMA Abort API (callback) */ + if (husart->hdmarx != NULL) + { + /* USART Rx DMA Abort callback has already been initialised : + will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */ + + /* Abort DMA RX */ + if (HAL_DMA_Abort_IT(husart->hdmarx) != HAL_OK) + { + husart->hdmarx->XferAbortCallback = NULL; + abortcplt = 1U; + } + else + { + abortcplt = 0U; + } + } + } +#endif /* HAL_DMA_MODULE_ENABLED */ + + /* if no DMA abort complete callback execution is required => call user Abort Complete callback */ + if (abortcplt == 1U) + { + /* Reset Tx and Rx transfer counters */ + husart->TxXferCount = 0U; + husart->RxXferCount = 0U; + + /* Reset errorCode */ + husart->ErrorCode = HAL_USART_ERROR_NONE; + + /* Clear the Error flags in the ICR register */ + __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF); + + /* Flush the whole TX FIFO (if needed) */ + if (husart->FifoMode == USART_FIFOMODE_ENABLE) + { + __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST); + } + + /* Discard the received data */ + __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST); + + /* Restore husart->State to Ready */ + husart->State = HAL_USART_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + /* Call registered Abort Complete Callback */ + husart->AbortCpltCallback(husart); +#else + /* Call legacy weak Abort Complete Callback */ + HAL_USART_AbortCpltCallback(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + } + + return HAL_OK; +} + +/** + * @brief Handle USART interrupt request. + * @param husart USART handle. + * @retval None + */ +void HAL_USART_IRQHandler(USART_HandleTypeDef *husart) +{ + uint32_t isrflags = READ_REG(husart->Instance->ISR); + uint32_t cr1its = READ_REG(husart->Instance->CR1); + uint32_t cr3its = READ_REG(husart->Instance->CR3); + + uint32_t errorflags; + uint32_t errorcode; + + /* If no error occurs */ + errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE | USART_ISR_RTOF | + USART_ISR_UDR)); + if (errorflags == 0U) + { + /* USART in mode Receiver ---------------------------------------------------*/ + if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U) + && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) + || ((cr3its & USART_CR3_RXFTIE) != 0U))) + { + if (husart->RxISR != NULL) + { + husart->RxISR(husart); + } + return; + } + } + + /* If some errors occur */ + if ((errorflags != 0U) + && (((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U) + || ((cr1its & (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)) != 0U))) + { + /* USART parity error interrupt occurred -------------------------------------*/ + if (((isrflags & USART_ISR_PE) != 0U) && ((cr1its & USART_CR1_PEIE) != 0U)) + { + __HAL_USART_CLEAR_IT(husart, USART_CLEAR_PEF); + + husart->ErrorCode |= HAL_USART_ERROR_PE; + } + + /* USART frame error interrupt occurred --------------------------------------*/ + if (((isrflags & USART_ISR_FE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) + { + __HAL_USART_CLEAR_IT(husart, USART_CLEAR_FEF); + + husart->ErrorCode |= HAL_USART_ERROR_FE; + } + + /* USART noise error interrupt occurred --------------------------------------*/ + if (((isrflags & USART_ISR_NE) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) + { + __HAL_USART_CLEAR_IT(husart, USART_CLEAR_NEF); + + husart->ErrorCode |= HAL_USART_ERROR_NE; + } + + /* USART Over-Run interrupt occurred -----------------------------------------*/ + if (((isrflags & USART_ISR_ORE) != 0U) + && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) || + ((cr3its & (USART_CR3_RXFTIE | USART_CR3_EIE)) != 0U))) + { + __HAL_USART_CLEAR_IT(husart, USART_CLEAR_OREF); + + husart->ErrorCode |= HAL_USART_ERROR_ORE; + } + + /* USART Receiver Timeout interrupt occurred ---------------------------------*/ + if (((isrflags & USART_ISR_RTOF) != 0U) && ((cr1its & USART_CR1_RTOIE) != 0U)) + { + __HAL_USART_CLEAR_IT(husart, USART_CLEAR_RTOF); + + husart->ErrorCode |= HAL_USART_ERROR_RTO; + } + + /* USART SPI slave underrun error interrupt occurred -------------------------*/ + if (((isrflags & USART_ISR_UDR) != 0U) && ((cr3its & USART_CR3_EIE) != 0U)) + { + /* Ignore SPI slave underrun errors when reception is going on */ + if (husart->State == HAL_USART_STATE_BUSY_RX) + { + __HAL_USART_CLEAR_UDRFLAG(husart); + return; + } + else + { + __HAL_USART_CLEAR_UDRFLAG(husart); + husart->ErrorCode |= HAL_USART_ERROR_UDR; + } + } + + /* Call USART Error Call back function if need be --------------------------*/ + if (husart->ErrorCode != HAL_USART_ERROR_NONE) + { + /* USART in mode Receiver ---------------------------------------------------*/ + if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U) + && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) + || ((cr3its & USART_CR3_RXFTIE) != 0U))) + { + if (husart->RxISR != NULL) + { + husart->RxISR(husart); + } + } + + /* If Overrun error occurs, or if any error occurs in DMA mode reception, + consider error as blocking */ + errorcode = husart->ErrorCode & HAL_USART_ERROR_ORE; + if ((HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR)) || + (errorcode != 0U)) + { + /* Blocking error : transfer is aborted + Set the USART state ready to be able to start again the process, + Disable Interrupts, and disable DMA requests, if ongoing */ + USART_EndTransfer(husart); + +#if defined(HAL_DMA_MODULE_ENABLED) + /* Abort the USART DMA Rx channel if enabled */ + if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR)) + { + /* Abort the USART DMA Tx channel */ + if (husart->hdmatx != NULL) + { + /* Set the USART Tx DMA Abort callback to NULL : no callback + executed at end of DMA abort procedure */ + husart->hdmatx->XferAbortCallback = NULL; + + /* Abort DMA TX */ + (void)HAL_DMA_Abort_IT(husart->hdmatx); + } + + /* Abort the USART DMA Rx channel */ + if (husart->hdmarx != NULL) + { + /* Set the USART Rx DMA Abort callback : + will lead to call HAL_USART_ErrorCallback() at end of DMA abort procedure */ + husart->hdmarx->XferAbortCallback = USART_DMAAbortOnError; + + /* Abort DMA RX */ + if (HAL_DMA_Abort_IT(husart->hdmarx) != HAL_OK) + { + /* Call Directly husart->hdmarx->XferAbortCallback function in case of error */ + husart->hdmarx->XferAbortCallback(husart->hdmarx); + } + } + else + { + /* Call user error callback */ +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + /* Call registered Error Callback */ + husart->ErrorCallback(husart); +#else + /* Call legacy weak Error Callback */ + HAL_USART_ErrorCallback(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + } + } + else +#endif /* HAL_DMA_MODULE_ENABLED */ + { + /* Call user error callback */ +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + /* Call registered Error Callback */ + husart->ErrorCallback(husart); +#else + /* Call legacy weak Error Callback */ + HAL_USART_ErrorCallback(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + } + } + else + { + /* Non Blocking error : transfer could go on. + Error is notified to user through user error callback */ +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + /* Call registered Error Callback */ + husart->ErrorCallback(husart); +#else + /* Call legacy weak Error Callback */ + HAL_USART_ErrorCallback(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + husart->ErrorCode = HAL_USART_ERROR_NONE; + } + } + return; + + } /* End if some error occurs */ + + + /* USART in mode Transmitter ------------------------------------------------*/ + if (((isrflags & USART_ISR_TXE_TXFNF) != 0U) + && (((cr1its & USART_CR1_TXEIE_TXFNFIE) != 0U) + || ((cr3its & USART_CR3_TXFTIE) != 0U))) + { + if (husart->TxISR != NULL) + { + husart->TxISR(husart); + } + return; + } + + /* USART in mode Transmitter (transmission end) -----------------------------*/ + if (((isrflags & USART_ISR_TC) != 0U) && ((cr1its & USART_CR1_TCIE) != 0U)) + { + USART_EndTransmit_IT(husart); + return; + } + + /* USART TX Fifo Empty occurred ----------------------------------------------*/ + if (((isrflags & USART_ISR_TXFE) != 0U) && ((cr1its & USART_CR1_TXFEIE) != 0U)) + { +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + /* Call registered Tx Fifo Empty Callback */ + husart->TxFifoEmptyCallback(husart); +#else + /* Call legacy weak Tx Fifo Empty Callback */ + HAL_USARTEx_TxFifoEmptyCallback(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + return; + } + + /* USART RX Fifo Full occurred ----------------------------------------------*/ + if (((isrflags & USART_ISR_RXFF) != 0U) && ((cr1its & USART_CR1_RXFFIE) != 0U)) + { +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + /* Call registered Rx Fifo Full Callback */ + husart->RxFifoFullCallback(husart); +#else + /* Call legacy weak Rx Fifo Full Callback */ + HAL_USARTEx_RxFifoFullCallback(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + return; + } +} + +/** + * @brief Tx Transfer completed callback. + * @param husart USART handle. + * @retval None + */ +__weak void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(husart); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_USART_TxCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief Tx Half Transfer completed callback. + * @param husart USART handle. + * @retval None + */ +__weak void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(husart); + + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_USART_TxHalfCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief Rx Transfer completed callback. + * @param husart USART handle. + * @retval None + */ +__weak void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(husart); + + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_USART_RxCpltCallback can be implemented in the user file. + */ +} + +/** + * @brief Rx Half Transfer completed callback. + * @param husart USART handle. + * @retval None + */ +__weak void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(husart); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_USART_RxHalfCpltCallback can be implemented in the user file + */ +} + +/** + * @brief Tx/Rx Transfers completed callback for the non-blocking process. + * @param husart USART handle. + * @retval None + */ +__weak void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(husart); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_USART_TxRxCpltCallback can be implemented in the user file + */ +} + +/** + * @brief USART error callback. + * @param husart USART handle. + * @retval None + */ +__weak void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(husart); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_USART_ErrorCallback can be implemented in the user file. + */ +} + +/** + * @brief USART Abort Complete callback. + * @param husart USART handle. + * @retval None + */ +__weak void HAL_USART_AbortCpltCallback(USART_HandleTypeDef *husart) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(husart); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_USART_AbortCpltCallback can be implemented in the user file. + */ +} + +/** + * @} + */ + +/** @defgroup USART_Exported_Functions_Group4 Peripheral State and Error functions + * @brief USART Peripheral State and Error functions + * +@verbatim + ============================================================================== + ##### Peripheral State and Error functions ##### + ============================================================================== + [..] + This subsection provides functions allowing to : + (+) Return the USART handle state + (+) Return the USART handle error code + +@endverbatim + * @{ + */ + + +/** + * @brief Return the USART handle state. + * @param husart pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART. + * @retval USART handle state + */ +HAL_USART_StateTypeDef HAL_USART_GetState(const USART_HandleTypeDef *husart) +{ + return husart->State; +} + +/** + * @brief Return the USART error code. + * @param husart pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART. + * @retval USART handle Error Code + */ +uint32_t HAL_USART_GetError(const USART_HandleTypeDef *husart) +{ + return husart->ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup USART_Private_Functions USART Private Functions + * @{ + */ + +/** + * @brief Initialize the callbacks to their default values. + * @param husart USART handle. + * @retval none + */ +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) +void USART_InitCallbacksToDefault(USART_HandleTypeDef *husart) +{ + /* Init the USART Callback settings */ + husart->TxHalfCpltCallback = HAL_USART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */ + husart->TxCpltCallback = HAL_USART_TxCpltCallback; /* Legacy weak TxCpltCallback */ + husart->RxHalfCpltCallback = HAL_USART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */ + husart->RxCpltCallback = HAL_USART_RxCpltCallback; /* Legacy weak RxCpltCallback */ + husart->TxRxCpltCallback = HAL_USART_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */ + husart->ErrorCallback = HAL_USART_ErrorCallback; /* Legacy weak ErrorCallback */ + husart->AbortCpltCallback = HAL_USART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ + husart->RxFifoFullCallback = HAL_USARTEx_RxFifoFullCallback; /* Legacy weak RxFifoFullCallback */ + husart->TxFifoEmptyCallback = HAL_USARTEx_TxFifoEmptyCallback; /* Legacy weak TxFifoEmptyCallback */ +} +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + +/** + * @brief End ongoing transfer on USART peripheral (following error detection or Transfer completion). + * @param husart USART handle. + * @retval None + */ +static void USART_EndTransfer(USART_HandleTypeDef *husart) +{ + /* Disable TXEIE, TCIE, RXNE, RXFT, TXFT, PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE | + USART_CR1_TCIE)); + CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE | USART_CR3_TXFTIE)); + + /* At end of process, restore husart->State to Ready */ + husart->State = HAL_USART_STATE_READY; +} + +#if defined(HAL_DMA_MODULE_ENABLED) +/** + * @brief DMA USART transmit process complete callback. + * @param hdma DMA handle. + * @retval None + */ +static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma) +{ + USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent); + + /* Check if DMA in circular mode */ + if (hdma->Mode != DMA_LINKEDLIST_CIRCULAR) + { + husart->TxXferCount = 0U; + + if (husart->State == HAL_USART_STATE_BUSY_TX) + { + /* Enable the USART Transmit Complete Interrupt */ + __HAL_USART_ENABLE_IT(husart, USART_IT_TC); + } + } + /* DMA Circular mode */ + else + { + if (husart->State == HAL_USART_STATE_BUSY_TX) + { +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + /* Call registered Tx Complete Callback */ + husart->TxCpltCallback(husart); +#else + /* Call legacy weak Tx Complete Callback */ + HAL_USART_TxCpltCallback(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + } + } +} + +/** + * @brief DMA USART transmit process half complete callback. + * @param hdma DMA handle. + * @retval None + */ +static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma) +{ + USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent); + +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + /* Call registered Tx Half Complete Callback */ + husart->TxHalfCpltCallback(husart); +#else + /* Call legacy weak Tx Half Complete Callback */ + HAL_USART_TxHalfCpltCallback(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA USART receive process complete callback. + * @param hdma DMA handle. + * @retval None + */ +static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma) +{ + USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent); + + /* Check if DMA in circular mode*/ + if (hdma->Mode != DMA_LINKEDLIST_CIRCULAR) + { + husart->RxXferCount = 0U; + + /* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ + CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE); + CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE); + + if (husart->State == HAL_USART_STATE_BUSY_RX) + { +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + /* Call registered Rx Complete Callback */ + husart->RxCpltCallback(husart); +#else + /* Call legacy weak Rx Complete Callback */ + HAL_USART_RxCpltCallback(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + } + /* The USART state is HAL_USART_STATE_BUSY_TX_RX */ + else + { +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + /* Call registered Tx Rx Complete Callback */ + husart->TxRxCpltCallback(husart); +#else + /* Call legacy weak Tx Rx Complete Callback */ + HAL_USART_TxRxCpltCallback(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + } + husart->State = HAL_USART_STATE_READY; + } + /* DMA circular mode */ + else + { + if (husart->State == HAL_USART_STATE_BUSY_RX) + { +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + /* Call registered Rx Complete Callback */ + husart->RxCpltCallback(husart); +#else + /* Call legacy weak Rx Complete Callback */ + HAL_USART_RxCpltCallback(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + } + /* The USART state is HAL_USART_STATE_BUSY_TX_RX */ + else + { +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + /* Call registered Tx Rx Complete Callback */ + husart->TxRxCpltCallback(husart); +#else + /* Call legacy weak Tx Rx Complete Callback */ + HAL_USART_TxRxCpltCallback(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + } + } +} + +/** + * @brief DMA USART receive process half complete callback. + * @param hdma DMA handle. + * @retval None + */ +static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma) +{ + USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent); + +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + /* Call registered Rx Half Complete Callback */ + husart->RxHalfCpltCallback(husart); +#else + /* Call legacy weak Rx Half Complete Callback */ + HAL_USART_RxHalfCpltCallback(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA USART communication error callback. + * @param hdma DMA handle. + * @retval None + */ +static void USART_DMAError(DMA_HandleTypeDef *hdma) +{ + USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent); + + husart->RxXferCount = 0U; + husart->TxXferCount = 0U; + USART_EndTransfer(husart); + + husart->ErrorCode |= HAL_USART_ERROR_DMA; + husart->State = HAL_USART_STATE_READY; + +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + /* Call registered Error Callback */ + husart->ErrorCallback(husart); +#else + /* Call legacy weak Error Callback */ + HAL_USART_ErrorCallback(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA USART communication abort callback, when initiated by HAL services on Error + * (To be called at end of DMA Abort procedure following error occurrence). + * @param hdma DMA handle. + * @retval None + */ +static void USART_DMAAbortOnError(DMA_HandleTypeDef *hdma) +{ + USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent); + husart->RxXferCount = 0U; + husart->TxXferCount = 0U; + +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + /* Call registered Error Callback */ + husart->ErrorCallback(husart); +#else + /* Call legacy weak Error Callback */ + HAL_USART_ErrorCallback(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA USART Tx communication abort callback, when initiated by user + * (To be called at end of DMA Tx Abort procedure following user abort request). + * @note When this callback is executed, User Abort complete call back is called only if no + * Abort still ongoing for Rx DMA Handle. + * @param hdma DMA handle. + * @retval None + */ +static void USART_DMATxAbortCallback(DMA_HandleTypeDef *hdma) +{ + USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent); + + husart->hdmatx->XferAbortCallback = NULL; + + /* Check if an Abort process is still ongoing */ + if (husart->hdmarx != NULL) + { + if (husart->hdmarx->XferAbortCallback != NULL) + { + return; + } + } + + /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ + husart->TxXferCount = 0U; + husart->RxXferCount = 0U; + + /* Reset errorCode */ + husart->ErrorCode = HAL_USART_ERROR_NONE; + + /* Clear the Error flags in the ICR register */ + __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF); + + /* Restore husart->State to Ready */ + husart->State = HAL_USART_STATE_READY; + + /* Call user Abort complete callback */ +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + /* Call registered Abort Complete Callback */ + husart->AbortCpltCallback(husart); +#else + /* Call legacy weak Abort Complete Callback */ + HAL_USART_AbortCpltCallback(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + +} + + +/** + * @brief DMA USART Rx communication abort callback, when initiated by user + * (To be called at end of DMA Rx Abort procedure following user abort request). + * @note When this callback is executed, User Abort complete call back is called only if no + * Abort still ongoing for Tx DMA Handle. + * @param hdma DMA handle. + * @retval None + */ +static void USART_DMARxAbortCallback(DMA_HandleTypeDef *hdma) +{ + USART_HandleTypeDef *husart = (USART_HandleTypeDef *)(hdma->Parent); + + husart->hdmarx->XferAbortCallback = NULL; + + /* Check if an Abort process is still ongoing */ + if (husart->hdmatx != NULL) + { + if (husart->hdmatx->XferAbortCallback != NULL) + { + return; + } + } + + /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */ + husart->TxXferCount = 0U; + husart->RxXferCount = 0U; + + /* Reset errorCode */ + husart->ErrorCode = HAL_USART_ERROR_NONE; + + /* Clear the Error flags in the ICR register */ + __HAL_USART_CLEAR_FLAG(husart, USART_CLEAR_OREF | USART_CLEAR_NEF | USART_CLEAR_PEF | USART_CLEAR_FEF); + + /* Restore husart->State to Ready */ + husart->State = HAL_USART_STATE_READY; + + /* Call user Abort complete callback */ +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + /* Call registered Abort Complete Callback */ + husart->AbortCpltCallback(husart); +#else + /* Call legacy weak Abort Complete Callback */ + HAL_USART_AbortCpltCallback(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ +} + +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @brief Handle USART Communication Timeout. It waits + * until a flag is no longer in the specified status. + * @param husart USART handle. + * @param Flag Specifies the USART flag to check. + * @param Status the actual Flag status (SET or RESET). + * @param Tickstart Tick start value + * @param Timeout timeout duration. + * @retval HAL status + */ +static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, + uint32_t Tickstart, uint32_t Timeout) +{ + /* Wait until flag is set */ + while ((__HAL_USART_GET_FLAG(husart, Flag) ? SET : RESET) == Status) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + { + husart->State = HAL_USART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + return HAL_TIMEOUT; + } + } + } + return HAL_OK; +} + +/** + * @brief Configure the USART peripheral. + * @param husart USART handle. + * @retval HAL status + */ +static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart) +{ + uint32_t tmpreg; + USART_ClockSourceTypeDef clocksource; + HAL_StatusTypeDef ret = HAL_OK; + uint16_t brrtemp; + uint32_t usartdiv = 0x00000000; + PLL2_ClocksTypeDef pll2_clocks; +#if defined(RCC_CR_PLL3ON) + PLL3_ClocksTypeDef pll3_clocks; +#endif /* RCC_CR_PLL3ON */ + uint32_t pclk; + + /* Check the parameters */ + assert_param(IS_USART_POLARITY(husart->Init.CLKPolarity)); + assert_param(IS_USART_PHASE(husart->Init.CLKPhase)); + assert_param(IS_USART_LASTBIT(husart->Init.CLKLastBit)); + assert_param(IS_USART_BAUDRATE(husart->Init.BaudRate)); + assert_param(IS_USART_WORD_LENGTH(husart->Init.WordLength)); + assert_param(IS_USART_STOPBITS(husart->Init.StopBits)); + assert_param(IS_USART_PARITY(husart->Init.Parity)); + assert_param(IS_USART_MODE(husart->Init.Mode)); + assert_param(IS_USART_PRESCALER(husart->Init.ClockPrescaler)); + + /*-------------------------- USART CR1 Configuration -----------------------*/ + /* Clear M, PCE, PS, TE and RE bits and configure + * the USART Word Length, Parity and Mode: + * set the M bits according to husart->Init.WordLength value + * set PCE and PS bits according to husart->Init.Parity value + * set TE and RE bits according to husart->Init.Mode value + * force OVER8 to 1 to allow to reach the maximum speed (Fclock/8) */ + tmpreg = (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode | USART_CR1_OVER8; + MODIFY_REG(husart->Instance->CR1, USART_CR1_FIELDS, tmpreg); + + /*---------------------------- USART CR2 Configuration ---------------------*/ + /* Clear and configure the USART Clock, CPOL, CPHA, LBCL STOP and SLVEN bits: + * set CPOL bit according to husart->Init.CLKPolarity value + * set CPHA bit according to husart->Init.CLKPhase value + * set LBCL bit according to husart->Init.CLKLastBit value (used in SPI master mode only) + * set STOP[13:12] bits according to husart->Init.StopBits value */ + tmpreg = (uint32_t)(USART_CLOCK_ENABLE); + tmpreg |= (uint32_t)husart->Init.CLKLastBit; + tmpreg |= ((uint32_t)husart->Init.CLKPolarity | (uint32_t)husart->Init.CLKPhase); + tmpreg |= (uint32_t)husart->Init.StopBits; + MODIFY_REG(husart->Instance->CR2, USART_CR2_FIELDS, tmpreg); + + /*-------------------------- USART PRESC Configuration -----------------------*/ + /* Configure + * - USART Clock Prescaler : set PRESCALER according to husart->Init.ClockPrescaler value */ + MODIFY_REG(husart->Instance->PRESC, USART_PRESC_PRESCALER, husart->Init.ClockPrescaler); + + /*-------------------------- USART BRR Configuration -----------------------*/ + /* BRR is filled-up according to OVER8 bit setting which is forced to 1 */ + USART_GETCLOCKSOURCE(husart, clocksource); + + switch (clocksource) + { + case USART_CLOCKSOURCE_PCLK1: + pclk = HAL_RCC_GetPCLK1Freq(); + usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate, husart->Init.ClockPrescaler)); + break; + case USART_CLOCKSOURCE_PCLK2: + pclk = HAL_RCC_GetPCLK2Freq(); + usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate, husart->Init.ClockPrescaler)); + break; + case USART_CLOCKSOURCE_PLL2Q: + HAL_RCCEx_GetPLL2ClockFreq(&pll2_clocks); + usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pll2_clocks.PLL2_Q_Frequency, husart->Init.BaudRate, + husart->Init.ClockPrescaler)); + break; +#if defined(RCC_CR_PLL3ON) + case USART_CLOCKSOURCE_PLL3Q: + HAL_RCCEx_GetPLL3ClockFreq(&pll3_clocks); + usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pll3_clocks.PLL3_Q_Frequency, husart->Init.BaudRate, + husart->Init.ClockPrescaler)); + break; +#endif /* RCC_CR_PLL3ON */ + case USART_CLOCKSOURCE_HSI: + usartdiv = (uint32_t)(USART_DIV_SAMPLING8(HSI_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler)); + break; + case USART_CLOCKSOURCE_CSI: + usartdiv = (uint32_t)(USART_DIV_SAMPLING8(CSI_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler)); + break; + case USART_CLOCKSOURCE_LSE: + usartdiv = (uint32_t)(USART_DIV_SAMPLING8(LSE_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler)); + break; + default: + ret = HAL_ERROR; + break; + } + + /* USARTDIV must be greater than or equal to 0d16 and smaller than or equal to ffff */ + if ((usartdiv >= USART_BRR_MIN) && (usartdiv <= USART_BRR_MAX)) + { + brrtemp = (uint16_t)(usartdiv & 0xFFF0U); + brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U); + husart->Instance->BRR = brrtemp; + } + else + { + ret = HAL_ERROR; + } + + /* Initialize the number of data to process during RX/TX ISR execution */ + husart->NbTxDataToProcess = 1U; + husart->NbRxDataToProcess = 1U; + + /* Clear ISR function pointers */ + husart->RxISR = NULL; + husart->TxISR = NULL; + + return ret; +} + +/** + * @brief Check the USART Idle State. + * @param husart USART handle. + * @retval HAL status + */ +static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart) +{ + uint32_t tickstart; + + /* Initialize the USART ErrorCode */ + husart->ErrorCode = HAL_USART_ERROR_NONE; + + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + + /* Check if the Transmitter is enabled */ + if ((husart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE) + { + /* Wait until TEACK flag is set */ + if (USART_WaitOnFlagUntilTimeout(husart, USART_ISR_TEACK, RESET, tickstart, USART_TEACK_REACK_TIMEOUT) != HAL_OK) + { + /* Timeout occurred */ + return HAL_TIMEOUT; + } + } + /* Check if the Receiver is enabled */ + if ((husart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE) + { + /* Wait until REACK flag is set */ + if (USART_WaitOnFlagUntilTimeout(husart, USART_ISR_REACK, RESET, tickstart, USART_TEACK_REACK_TIMEOUT) != HAL_OK) + { + /* Timeout occurred */ + return HAL_TIMEOUT; + } + } + + /* Initialize the USART state*/ + husart->State = HAL_USART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + return HAL_OK; +} + +/** + * @brief Simplex send an amount of data in non-blocking mode. + * @note Function called under interruption only, once + * interruptions have been enabled by HAL_USART_Transmit_IT(). + * @note The USART errors are not managed to avoid the overrun error. + * @note ISR function executed when FIFO mode is disabled and when the + * data word length is less than 9 bits long. + * @param husart USART handle. + * @retval None + */ +static void USART_TxISR_8BIT(USART_HandleTypeDef *husart) +{ + const HAL_USART_StateTypeDef state = husart->State; + + /* Check that a Tx process is ongoing */ + if ((state == HAL_USART_STATE_BUSY_TX) || + (state == HAL_USART_STATE_BUSY_TX_RX)) + { + if (husart->TxXferCount == 0U) + { + /* Disable the USART Transmit data register empty interrupt */ + __HAL_USART_DISABLE_IT(husart, USART_IT_TXE); + + /* Enable the USART Transmit Complete Interrupt */ + __HAL_USART_ENABLE_IT(husart, USART_IT_TC); + } + else + { + husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr & (uint8_t)0xFF); + husart->pTxBuffPtr++; + husart->TxXferCount--; + } + } +} + +/** + * @brief Simplex send an amount of data in non-blocking mode. + * @note Function called under interruption only, once + * interruptions have been enabled by HAL_USART_Transmit_IT(). + * @note The USART errors are not managed to avoid the overrun error. + * @note ISR function executed when FIFO mode is disabled and when the + * data word length is 9 bits long. + * @param husart USART handle. + * @retval None + */ +static void USART_TxISR_16BIT(USART_HandleTypeDef *husart) +{ + const HAL_USART_StateTypeDef state = husart->State; + const uint16_t *tmp; + + if ((state == HAL_USART_STATE_BUSY_TX) || + (state == HAL_USART_STATE_BUSY_TX_RX)) + { + if (husart->TxXferCount == 0U) + { + /* Disable the USART Transmit data register empty interrupt */ + __HAL_USART_DISABLE_IT(husart, USART_IT_TXE); + + /* Enable the USART Transmit Complete Interrupt */ + __HAL_USART_ENABLE_IT(husart, USART_IT_TC); + } + else + { + tmp = (const uint16_t *) husart->pTxBuffPtr; + husart->Instance->TDR = (uint16_t)(*tmp & 0x01FFU); + husart->pTxBuffPtr += 2U; + husart->TxXferCount--; + } + } +} + +/** + * @brief Simplex send an amount of data in non-blocking mode. + * @note Function called under interruption only, once + * interruptions have been enabled by HAL_USART_Transmit_IT(). + * @note The USART errors are not managed to avoid the overrun error. + * @note ISR function executed when FIFO mode is enabled and when the + * data word length is less than 9 bits long. + * @param husart USART handle. + * @retval None + */ +static void USART_TxISR_8BIT_FIFOEN(USART_HandleTypeDef *husart) +{ + const HAL_USART_StateTypeDef state = husart->State; + uint16_t nb_tx_data; + + /* Check that a Tx process is ongoing */ + if ((state == HAL_USART_STATE_BUSY_TX) || + (state == HAL_USART_STATE_BUSY_TX_RX)) + { + for (nb_tx_data = husart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--) + { + if (husart->TxXferCount == 0U) + { + /* Disable the TX FIFO threshold interrupt */ + __HAL_USART_DISABLE_IT(husart, USART_IT_TXFT); + + /* Enable the USART Transmit Complete Interrupt */ + __HAL_USART_ENABLE_IT(husart, USART_IT_TC); + + break; /* force exit loop */ + } + else if (__HAL_USART_GET_FLAG(husart, USART_FLAG_TXFNF) == SET) + { + husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr & (uint8_t)0xFF); + husart->pTxBuffPtr++; + husart->TxXferCount--; + } + else + { + /* Nothing to do */ + } + } + } +} + +/** + * @brief Simplex send an amount of data in non-blocking mode. + * @note Function called under interruption only, once + * interruptions have been enabled by HAL_USART_Transmit_IT(). + * @note The USART errors are not managed to avoid the overrun error. + * @note ISR function executed when FIFO mode is enabled and when the + * data word length is 9 bits long. + * @param husart USART handle. + * @retval None + */ +static void USART_TxISR_16BIT_FIFOEN(USART_HandleTypeDef *husart) +{ + const HAL_USART_StateTypeDef state = husart->State; + const uint16_t *tmp; + uint16_t nb_tx_data; + + /* Check that a Tx process is ongoing */ + if ((state == HAL_USART_STATE_BUSY_TX) || + (state == HAL_USART_STATE_BUSY_TX_RX)) + { + for (nb_tx_data = husart->NbTxDataToProcess ; nb_tx_data > 0U ; nb_tx_data--) + { + if (husart->TxXferCount == 0U) + { + /* Disable the TX FIFO threshold interrupt */ + __HAL_USART_DISABLE_IT(husart, USART_IT_TXFT); + + /* Enable the USART Transmit Complete Interrupt */ + __HAL_USART_ENABLE_IT(husart, USART_IT_TC); + + break; /* force exit loop */ + } + else if (__HAL_USART_GET_FLAG(husart, USART_FLAG_TXFNF) == SET) + { + tmp = (const uint16_t *) husart->pTxBuffPtr; + husart->Instance->TDR = (uint16_t)(*tmp & 0x01FFU); + husart->pTxBuffPtr += 2U; + husart->TxXferCount--; + } + else + { + /* Nothing to do */ + } + } + } +} + +/** + * @brief Wraps up transmission in non-blocking mode. + * @param husart Pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @retval None + */ +static void USART_EndTransmit_IT(USART_HandleTypeDef *husart) +{ + /* Disable the USART Transmit Complete Interrupt */ + __HAL_USART_DISABLE_IT(husart, USART_IT_TC); + + /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */ + __HAL_USART_DISABLE_IT(husart, USART_IT_ERR); + + /* Clear TxISR function pointer */ + husart->TxISR = NULL; + + if (husart->State == HAL_USART_STATE_BUSY_TX) + { + /* Clear overrun flag and discard the received data */ + __HAL_USART_CLEAR_OREFLAG(husart); + __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST); + + /* Tx process is completed, restore husart->State to Ready */ + husart->State = HAL_USART_STATE_READY; + +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + /* Call registered Tx Complete Callback */ + husart->TxCpltCallback(husart); +#else + /* Call legacy weak Tx Complete Callback */ + HAL_USART_TxCpltCallback(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + } + else if (husart->RxXferCount == 0U) + { + /* TxRx process is completed, restore husart->State to Ready */ + husart->State = HAL_USART_STATE_READY; + +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + /* Call registered Tx Rx Complete Callback */ + husart->TxRxCpltCallback(husart); +#else + /* Call legacy weak Tx Rx Complete Callback */ + HAL_USART_TxRxCpltCallback(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + } + else + { + /* Nothing to do */ + } +} + + +/** + * @brief Simplex receive an amount of data in non-blocking mode. + * @note Function called under interruption only, once + * interruptions have been enabled by HAL_USART_Receive_IT(). + * @note ISR function executed when FIFO mode is disabled and when the + * data word length is less than 9 bits long. + * @param husart USART handle + * @retval None + */ +static void USART_RxISR_8BIT(USART_HandleTypeDef *husart) +{ + const HAL_USART_StateTypeDef state = husart->State; + uint16_t txdatacount; + uint16_t uhMask = husart->Mask; + uint32_t txftie; + + if ((state == HAL_USART_STATE_BUSY_RX) || + (state == HAL_USART_STATE_BUSY_TX_RX)) + { + *husart->pRxBuffPtr = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask); + husart->pRxBuffPtr++; + husart->RxXferCount--; + + if (husart->RxXferCount == 0U) + { + /* Disable the USART Parity Error Interrupt and RXNE interrupt*/ + CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); + + /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */ + CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE); + + /* Clear RxISR function pointer */ + husart->RxISR = NULL; + + /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */ + txftie = READ_BIT(husart->Instance->CR3, USART_CR3_TXFTIE); + txdatacount = husart->TxXferCount; + + if (state == HAL_USART_STATE_BUSY_RX) + { + /* Clear SPI slave underrun flag and discard transmit data */ + if (husart->SlaveMode == USART_SLAVEMODE_ENABLE) + { + __HAL_USART_CLEAR_UDRFLAG(husart); + __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST); + } + + /* Rx process is completed, restore husart->State to Ready */ + husart->State = HAL_USART_STATE_READY; + +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + /* Call registered Rx Complete Callback */ + husart->RxCpltCallback(husart); +#else + /* Call legacy weak Rx Complete Callback */ + HAL_USART_RxCpltCallback(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + } + else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) && + (txftie != USART_CR3_TXFTIE) && + (txdatacount == 0U)) + { + /* TxRx process is completed, restore husart->State to Ready */ + husart->State = HAL_USART_STATE_READY; + +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + /* Call registered Tx Rx Complete Callback */ + husart->TxRxCpltCallback(husart); +#else + /* Call legacy weak Tx Rx Complete Callback */ + HAL_USART_TxRxCpltCallback(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + } + else + { + /* Nothing to do */ + } + } + else if ((state == HAL_USART_STATE_BUSY_RX) && + (husart->SlaveMode == USART_SLAVEMODE_DISABLE)) + { + /* Send dummy byte in order to generate the clock for the Slave to Send the next data */ + husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF); + } + else + { + /* Nothing to do */ + } + } +} + +/** + * @brief Simplex receive an amount of data in non-blocking mode. + * @note Function called under interruption only, once + * interruptions have been enabled by HAL_USART_Receive_IT(). + * @note ISR function executed when FIFO mode is disabled and when the + * data word length is 9 bits long. + * @param husart USART handle + * @retval None + */ +static void USART_RxISR_16BIT(USART_HandleTypeDef *husart) +{ + const HAL_USART_StateTypeDef state = husart->State; + uint16_t txdatacount; + uint16_t *tmp; + uint16_t uhMask = husart->Mask; + uint32_t txftie; + + if ((state == HAL_USART_STATE_BUSY_RX) || + (state == HAL_USART_STATE_BUSY_TX_RX)) + { + tmp = (uint16_t *) husart->pRxBuffPtr; + *tmp = (uint16_t)(husart->Instance->RDR & uhMask); + husart->pRxBuffPtr += 2U; + husart->RxXferCount--; + + if (husart->RxXferCount == 0U) + { + /* Disable the USART Parity Error Interrupt and RXNE interrupt*/ + CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); + + /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */ + CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE); + + /* Clear RxISR function pointer */ + husart->RxISR = NULL; + + /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */ + txftie = READ_BIT(husart->Instance->CR3, USART_CR3_TXFTIE); + txdatacount = husart->TxXferCount; + + if (state == HAL_USART_STATE_BUSY_RX) + { + /* Clear SPI slave underrun flag and discard transmit data */ + if (husart->SlaveMode == USART_SLAVEMODE_ENABLE) + { + __HAL_USART_CLEAR_UDRFLAG(husart); + __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST); + } + + /* Rx process is completed, restore husart->State to Ready */ + husart->State = HAL_USART_STATE_READY; + +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + /* Call registered Rx Complete Callback */ + husart->RxCpltCallback(husart); +#else + /* Call legacy weak Rx Complete Callback */ + HAL_USART_RxCpltCallback(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + } + else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) && + (txftie != USART_CR3_TXFTIE) && + (txdatacount == 0U)) + { + /* TxRx process is completed, restore husart->State to Ready */ + husart->State = HAL_USART_STATE_READY; + +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + /* Call registered Tx Rx Complete Callback */ + husart->TxRxCpltCallback(husart); +#else + /* Call legacy weak Tx Rx Complete Callback */ + HAL_USART_TxRxCpltCallback(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + } + else + { + /* Nothing to do */ + } + } + else if ((state == HAL_USART_STATE_BUSY_RX) && + (husart->SlaveMode == USART_SLAVEMODE_DISABLE)) + { + /* Send dummy byte in order to generate the clock for the Slave to Send the next data */ + husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF); + } + else + { + /* Nothing to do */ + } + } +} + +/** + * @brief Simplex receive an amount of data in non-blocking mode. + * @note Function called under interruption only, once + * interruptions have been enabled by HAL_USART_Receive_IT(). + * @note ISR function executed when FIFO mode is enabled and when the + * data word length is less than 9 bits long. + * @param husart USART handle + * @retval None + */ +static void USART_RxISR_8BIT_FIFOEN(USART_HandleTypeDef *husart) +{ + HAL_USART_StateTypeDef state = husart->State; + uint16_t txdatacount; + uint16_t rxdatacount; + uint16_t uhMask = husart->Mask; + uint16_t nb_rx_data; + uint32_t txftie; + + /* Check that a Rx process is ongoing */ + if ((state == HAL_USART_STATE_BUSY_RX) || + (state == HAL_USART_STATE_BUSY_TX_RX)) + { + for (nb_rx_data = husart->NbRxDataToProcess ; nb_rx_data > 0U ; nb_rx_data--) + { + if (__HAL_USART_GET_FLAG(husart, USART_FLAG_RXFNE) == SET) + { + *husart->pRxBuffPtr = (uint8_t)(husart->Instance->RDR & (uint8_t)(uhMask & 0xFFU)); + husart->pRxBuffPtr++; + husart->RxXferCount--; + + if (husart->RxXferCount == 0U) + { + /* Disable the USART Parity Error Interrupt */ + CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE); + + /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) + and RX FIFO Threshold interrupt */ + CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE)); + + /* Clear RxISR function pointer */ + husart->RxISR = NULL; + + /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */ + txftie = READ_BIT(husart->Instance->CR3, USART_CR3_TXFTIE); + txdatacount = husart->TxXferCount; + + if (state == HAL_USART_STATE_BUSY_RX) + { + /* Clear SPI slave underrun flag and discard transmit data */ + if (husart->SlaveMode == USART_SLAVEMODE_ENABLE) + { + __HAL_USART_CLEAR_UDRFLAG(husart); + __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST); + } + + /* Rx process is completed, restore husart->State to Ready */ + husart->State = HAL_USART_STATE_READY; + state = HAL_USART_STATE_READY; + +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + /* Call registered Rx Complete Callback */ + husart->RxCpltCallback(husart); +#else + /* Call legacy weak Rx Complete Callback */ + HAL_USART_RxCpltCallback(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + } + else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) && + (txftie != USART_CR3_TXFTIE) && + (txdatacount == 0U)) + { + /* TxRx process is completed, restore husart->State to Ready */ + husart->State = HAL_USART_STATE_READY; + state = HAL_USART_STATE_READY; + +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + /* Call registered Tx Rx Complete Callback */ + husart->TxRxCpltCallback(husart); +#else + /* Call legacy weak Tx Rx Complete Callback */ + HAL_USART_TxRxCpltCallback(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + } + else + { + /* Nothing to do */ + } + } + else if ((state == HAL_USART_STATE_BUSY_RX) && + (husart->SlaveMode == USART_SLAVEMODE_DISABLE)) + { + /* Send dummy byte in order to generate the clock for the Slave to Send the next data */ + husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF); + } + else + { + /* Nothing to do */ + } + } + } + + /* When remaining number of bytes to receive is less than the RX FIFO + threshold, next incoming frames are processed as if FIFO mode was + disabled (i.e. one interrupt per received frame). + */ + rxdatacount = husart->RxXferCount; + if (((rxdatacount != 0U)) && (rxdatacount < husart->NbRxDataToProcess)) + { + /* Disable the USART RXFT interrupt*/ + CLEAR_BIT(husart->Instance->CR3, USART_CR3_RXFTIE); + + /* Update the RxISR function pointer */ + husart->RxISR = USART_RxISR_8BIT; + + /* Enable the USART Data Register Not Empty interrupt */ + SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE); + + if ((husart->TxXferCount == 0U) && + (state == HAL_USART_STATE_BUSY_TX_RX) && + (husart->SlaveMode == USART_SLAVEMODE_DISABLE)) + { + /* Send dummy byte in order to generate the clock for the Slave to Send the next data */ + husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF); + } + } + } + else + { + /* Clear RXNE interrupt flag */ + __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST); + } +} + +/** + * @brief Simplex receive an amount of data in non-blocking mode. + * @note Function called under interruption only, once + * interruptions have been enabled by HAL_USART_Receive_IT(). + * @note ISR function executed when FIFO mode is enabled and when the + * data word length is 9 bits long. + * @param husart USART handle + * @retval None + */ +static void USART_RxISR_16BIT_FIFOEN(USART_HandleTypeDef *husart) +{ + HAL_USART_StateTypeDef state = husart->State; + uint16_t txdatacount; + uint16_t rxdatacount; + uint16_t *tmp; + uint16_t uhMask = husart->Mask; + uint16_t nb_rx_data; + uint32_t txftie; + + /* Check that a Tx process is ongoing */ + if ((state == HAL_USART_STATE_BUSY_RX) || + (state == HAL_USART_STATE_BUSY_TX_RX)) + { + for (nb_rx_data = husart->NbRxDataToProcess ; nb_rx_data > 0U ; nb_rx_data--) + { + if (__HAL_USART_GET_FLAG(husart, USART_FLAG_RXFNE) == SET) + { + tmp = (uint16_t *) husart->pRxBuffPtr; + *tmp = (uint16_t)(husart->Instance->RDR & uhMask); + husart->pRxBuffPtr += 2U; + husart->RxXferCount--; + + if (husart->RxXferCount == 0U) + { + /* Disable the USART Parity Error Interrupt */ + CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE); + + /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) + and RX FIFO Threshold interrupt */ + CLEAR_BIT(husart->Instance->CR3, (USART_CR3_EIE | USART_CR3_RXFTIE)); + + /* Clear RxISR function pointer */ + husart->RxISR = NULL; + + /* txftie and txdatacount are temporary variables for MISRAC2012-Rule-13.5 */ + txftie = READ_BIT(husart->Instance->CR3, USART_CR3_TXFTIE); + txdatacount = husart->TxXferCount; + + if (state == HAL_USART_STATE_BUSY_RX) + { + /* Clear SPI slave underrun flag and discard transmit data */ + if (husart->SlaveMode == USART_SLAVEMODE_ENABLE) + { + __HAL_USART_CLEAR_UDRFLAG(husart); + __HAL_USART_SEND_REQ(husart, USART_TXDATA_FLUSH_REQUEST); + } + + /* Rx process is completed, restore husart->State to Ready */ + husart->State = HAL_USART_STATE_READY; + state = HAL_USART_STATE_READY; + +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + /* Call registered Rx Complete Callback */ + husart->RxCpltCallback(husart); +#else + /* Call legacy weak Rx Complete Callback */ + HAL_USART_RxCpltCallback(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + } + else if ((READ_BIT(husart->Instance->CR1, USART_CR1_TCIE) != USART_CR1_TCIE) && + (txftie != USART_CR3_TXFTIE) && + (txdatacount == 0U)) + { + /* TxRx process is completed, restore husart->State to Ready */ + husart->State = HAL_USART_STATE_READY; + state = HAL_USART_STATE_READY; + +#if (USE_HAL_USART_REGISTER_CALLBACKS == 1) + /* Call registered Tx Rx Complete Callback */ + husart->TxRxCpltCallback(husart); +#else + /* Call legacy weak Tx Rx Complete Callback */ + HAL_USART_TxRxCpltCallback(husart); +#endif /* USE_HAL_USART_REGISTER_CALLBACKS */ + } + else + { + /* Nothing to do */ + } + } + else if ((state == HAL_USART_STATE_BUSY_RX) && + (husart->SlaveMode == USART_SLAVEMODE_DISABLE)) + { + /* Send dummy byte in order to generate the clock for the Slave to Send the next data */ + husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF); + } + else + { + /* Nothing to do */ + } + } + } + + /* When remaining number of bytes to receive is less than the RX FIFO + threshold, next incoming frames are processed as if FIFO mode was + disabled (i.e. one interrupt per received frame). + */ + rxdatacount = husart->RxXferCount; + if (((rxdatacount != 0U)) && (rxdatacount < husart->NbRxDataToProcess)) + { + /* Disable the USART RXFT interrupt*/ + CLEAR_BIT(husart->Instance->CR3, USART_CR3_RXFTIE); + + /* Update the RxISR function pointer */ + husart->RxISR = USART_RxISR_16BIT; + + /* Enable the USART Data Register Not Empty interrupt */ + SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE_RXFNEIE); + + if ((husart->TxXferCount == 0U) && + (state == HAL_USART_STATE_BUSY_TX_RX) && + (husart->SlaveMode == USART_SLAVEMODE_DISABLE)) + { + /* Send dummy byte in order to generate the clock for the Slave to Send the next data */ + husart->Instance->TDR = (USART_DUMMY_DATA & (uint16_t)0x00FF); + } + } + } + else + { + /* Clear RXNE interrupt flag */ + __HAL_USART_SEND_REQ(husart, USART_RXDATA_FLUSH_REQUEST); + } +} + +/** + * @} + */ + +#endif /* HAL_USART_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_usart_ex.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_usart_ex.c new file mode 100644 index 0000000000..3c4d45c5ac --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_usart_ex.c @@ -0,0 +1,541 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_usart_ex.c + * @author MCD Application Team + * @brief Extended USART HAL module driver. + * This file provides firmware functions to manage the following extended + * functionalities of the Universal Synchronous Receiver Transmitter Peripheral (USART). + * + Peripheral Control functions + * + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### USART peripheral extended features ##### + ============================================================================== + + (#) FIFO mode enabling/disabling and RX/TX FIFO threshold programming. + + -@- When USART operates in FIFO mode, FIFO mode must be enabled prior + starting RX/TX transfers. Also RX/TX FIFO thresholds must be + configured prior starting RX/TX transfers. + + (#) Slave mode enabling/disabling and NSS pin configuration. + + -@- When USART operates in Slave mode, Slave mode must be enabled prior + starting RX/TX transfers. + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup USARTEx USARTEx + * @brief USART Extended HAL module driver + * @{ + */ + +#ifdef HAL_USART_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/** @defgroup USARTEx_Private_Constants USARTEx Private Constants + * @{ + */ +/* USART RX FIFO depth */ +#define RX_FIFO_DEPTH 8U + +/* USART TX FIFO depth */ +#define TX_FIFO_DEPTH 8U +/** + * @} + */ + +/* Private define ------------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup USARTEx_Private_Functions USARTEx Private Functions + * @{ + */ +static void USARTEx_SetNbDataToProcess(USART_HandleTypeDef *husart); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup USARTEx_Exported_Functions USARTEx Exported Functions + * @{ + */ + +/** @defgroup USARTEx_Exported_Functions_Group1 IO operation functions + * @brief Extended USART Transmit/Receive functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + This subsection provides a set of FIFO mode related callback functions. + + (#) TX/RX Fifos Callbacks: + (+) HAL_USARTEx_RxFifoFullCallback() + (+) HAL_USARTEx_TxFifoEmptyCallback() + +@endverbatim + * @{ + */ + +/** + * @brief USART RX Fifo full callback. + * @param husart USART handle. + * @retval None + */ +__weak void HAL_USARTEx_RxFifoFullCallback(USART_HandleTypeDef *husart) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(husart); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_USARTEx_RxFifoFullCallback can be implemented in the user file. + */ +} + +/** + * @brief USART TX Fifo empty callback. + * @param husart USART handle. + * @retval None + */ +__weak void HAL_USARTEx_TxFifoEmptyCallback(USART_HandleTypeDef *husart) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(husart); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_USARTEx_TxFifoEmptyCallback can be implemented in the user file. + */ +} + +/** + * @} + */ + +/** @defgroup USARTEx_Exported_Functions_Group2 Peripheral Control functions + * @brief Extended Peripheral Control functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] This section provides the following functions: + (+) HAL_USARTEx_EnableSPISlaveMode() API enables the SPI slave mode + (+) HAL_USARTEx_DisableSPISlaveMode() API disables the SPI slave mode + (+) HAL_USARTEx_ConfigNSS API configures the Slave Select input pin (NSS) + (+) HAL_USARTEx_EnableFifoMode() API enables the FIFO mode + (+) HAL_USARTEx_DisableFifoMode() API disables the FIFO mode + (+) HAL_USARTEx_SetTxFifoThreshold() API sets the TX FIFO threshold + (+) HAL_USARTEx_SetRxFifoThreshold() API sets the RX FIFO threshold + + +@endverbatim + * @{ + */ + +/** + * @brief Enable the SPI slave mode. + * @note When the USART operates in SPI slave mode, it handles data flow using + * the serial interface clock derived from the external SCLK signal + * provided by the external master SPI device. + * @note In SPI slave mode, the USART must be enabled before starting the master + * communications (or between frames while the clock is stable). Otherwise, + * if the USART slave is enabled while the master is in the middle of a + * frame, it will become desynchronized with the master. + * @note The data register of the slave needs to be ready before the first edge + * of the communication clock or before the end of the ongoing communication, + * otherwise the SPI slave will transmit zeros. + * @param husart USART handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USARTEx_EnableSlaveMode(USART_HandleTypeDef *husart) +{ + uint32_t tmpcr1; + + /* Check parameters */ + assert_param(IS_UART_SPI_SLAVE_INSTANCE(husart->Instance)); + + /* Process Locked */ + __HAL_LOCK(husart); + + husart->State = HAL_USART_STATE_BUSY; + + /* Save actual USART configuration */ + tmpcr1 = READ_REG(husart->Instance->CR1); + + /* Disable USART */ + __HAL_USART_DISABLE(husart); + + /* In SPI slave mode mode, the following bits must be kept cleared: + - LINEN and CLKEN bit in the USART_CR2 register + - HDSEL, SCEN and IREN bits in the USART_CR3 register.*/ + CLEAR_BIT(husart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); + CLEAR_BIT(husart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN)); + + /* Enable SPI slave mode */ + SET_BIT(husart->Instance->CR2, USART_CR2_SLVEN); + + /* Restore USART configuration */ + WRITE_REG(husart->Instance->CR1, tmpcr1); + + husart->SlaveMode = USART_SLAVEMODE_ENABLE; + + husart->State = HAL_USART_STATE_READY; + + /* Enable USART */ + __HAL_USART_ENABLE(husart); + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + return HAL_OK; +} + +/** + * @brief Disable the SPI slave mode. + * @param husart USART handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USARTEx_DisableSlaveMode(USART_HandleTypeDef *husart) +{ + uint32_t tmpcr1; + + /* Check parameters */ + assert_param(IS_UART_SPI_SLAVE_INSTANCE(husart->Instance)); + + /* Process Locked */ + __HAL_LOCK(husart); + + husart->State = HAL_USART_STATE_BUSY; + + /* Save actual USART configuration */ + tmpcr1 = READ_REG(husart->Instance->CR1); + + /* Disable USART */ + __HAL_USART_DISABLE(husart); + + /* Disable SPI slave mode */ + CLEAR_BIT(husart->Instance->CR2, USART_CR2_SLVEN); + + /* Restore USART configuration */ + WRITE_REG(husart->Instance->CR1, tmpcr1); + + husart->SlaveMode = USART_SLAVEMODE_DISABLE; + + husart->State = HAL_USART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + return HAL_OK; +} + +/** + * @brief Configure the Slave Select input pin (NSS). + * @note Software NSS management: SPI slave will always be selected and NSS + * input pin will be ignored. + * @note Hardware NSS management: the SPI slave selection depends on NSS + * input pin. The slave is selected when NSS is low and deselected when + * NSS is high. + * @param husart USART handle. + * @param NSSConfig NSS configuration. + * This parameter can be one of the following values: + * @arg @ref USART_NSS_HARD + * @arg @ref USART_NSS_SOFT + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USARTEx_ConfigNSS(USART_HandleTypeDef *husart, uint32_t NSSConfig) +{ + uint32_t tmpcr1; + + /* Check parameters */ + assert_param(IS_UART_SPI_SLAVE_INSTANCE(husart->Instance)); + assert_param(IS_USART_NSS(NSSConfig)); + + /* Process Locked */ + __HAL_LOCK(husart); + + husart->State = HAL_USART_STATE_BUSY; + + /* Save actual USART configuration */ + tmpcr1 = READ_REG(husart->Instance->CR1); + + /* Disable USART */ + __HAL_USART_DISABLE(husart); + + /* Program DIS_NSS bit in the USART_CR2 register */ + MODIFY_REG(husart->Instance->CR2, USART_CR2_DIS_NSS, NSSConfig); + + /* Restore USART configuration */ + WRITE_REG(husart->Instance->CR1, tmpcr1); + + husart->State = HAL_USART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + return HAL_OK; +} + +/** + * @brief Enable the FIFO mode. + * @param husart USART handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USARTEx_EnableFifoMode(USART_HandleTypeDef *husart) +{ + uint32_t tmpcr1; + + /* Check parameters */ + assert_param(IS_UART_FIFO_INSTANCE(husart->Instance)); + + /* Process Locked */ + __HAL_LOCK(husart); + + husart->State = HAL_USART_STATE_BUSY; + + /* Save actual USART configuration */ + tmpcr1 = READ_REG(husart->Instance->CR1); + + /* Disable USART */ + __HAL_USART_DISABLE(husart); + + /* Enable FIFO mode */ + SET_BIT(tmpcr1, USART_CR1_FIFOEN); + husart->FifoMode = USART_FIFOMODE_ENABLE; + + /* Restore USART configuration */ + WRITE_REG(husart->Instance->CR1, tmpcr1); + + /* Determine the number of data to process during RX/TX ISR execution */ + USARTEx_SetNbDataToProcess(husart); + + husart->State = HAL_USART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + return HAL_OK; +} + +/** + * @brief Disable the FIFO mode. + * @param husart USART handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USARTEx_DisableFifoMode(USART_HandleTypeDef *husart) +{ + uint32_t tmpcr1; + + /* Check parameters */ + assert_param(IS_UART_FIFO_INSTANCE(husart->Instance)); + + /* Process Locked */ + __HAL_LOCK(husart); + + husart->State = HAL_USART_STATE_BUSY; + + /* Save actual USART configuration */ + tmpcr1 = READ_REG(husart->Instance->CR1); + + /* Disable USART */ + __HAL_USART_DISABLE(husart); + + /* Enable FIFO mode */ + CLEAR_BIT(tmpcr1, USART_CR1_FIFOEN); + husart->FifoMode = USART_FIFOMODE_DISABLE; + + /* Restore USART configuration */ + WRITE_REG(husart->Instance->CR1, tmpcr1); + + husart->State = HAL_USART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + return HAL_OK; +} + +/** + * @brief Set the TXFIFO threshold. + * @param husart USART handle. + * @param Threshold TX FIFO threshold value + * This parameter can be one of the following values: + * @arg @ref USART_TXFIFO_THRESHOLD_1_8 + * @arg @ref USART_TXFIFO_THRESHOLD_1_4 + * @arg @ref USART_TXFIFO_THRESHOLD_1_2 + * @arg @ref USART_TXFIFO_THRESHOLD_3_4 + * @arg @ref USART_TXFIFO_THRESHOLD_7_8 + * @arg @ref USART_TXFIFO_THRESHOLD_8_8 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USARTEx_SetTxFifoThreshold(USART_HandleTypeDef *husart, uint32_t Threshold) +{ + uint32_t tmpcr1; + + /* Check parameters */ + assert_param(IS_UART_FIFO_INSTANCE(husart->Instance)); + assert_param(IS_USART_TXFIFO_THRESHOLD(Threshold)); + + /* Process Locked */ + __HAL_LOCK(husart); + + husart->State = HAL_USART_STATE_BUSY; + + /* Save actual USART configuration */ + tmpcr1 = READ_REG(husart->Instance->CR1); + + /* Disable USART */ + __HAL_USART_DISABLE(husart); + + /* Update TX threshold configuration */ + MODIFY_REG(husart->Instance->CR3, USART_CR3_TXFTCFG, Threshold); + + /* Determine the number of data to process during RX/TX ISR execution */ + USARTEx_SetNbDataToProcess(husart); + + /* Restore USART configuration */ + WRITE_REG(husart->Instance->CR1, tmpcr1); + + husart->State = HAL_USART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + return HAL_OK; +} + +/** + * @brief Set the RXFIFO threshold. + * @param husart USART handle. + * @param Threshold RX FIFO threshold value + * This parameter can be one of the following values: + * @arg @ref USART_RXFIFO_THRESHOLD_1_8 + * @arg @ref USART_RXFIFO_THRESHOLD_1_4 + * @arg @ref USART_RXFIFO_THRESHOLD_1_2 + * @arg @ref USART_RXFIFO_THRESHOLD_3_4 + * @arg @ref USART_RXFIFO_THRESHOLD_7_8 + * @arg @ref USART_RXFIFO_THRESHOLD_8_8 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USARTEx_SetRxFifoThreshold(USART_HandleTypeDef *husart, uint32_t Threshold) +{ + uint32_t tmpcr1; + + /* Check the parameters */ + assert_param(IS_UART_FIFO_INSTANCE(husart->Instance)); + assert_param(IS_USART_RXFIFO_THRESHOLD(Threshold)); + + /* Process Locked */ + __HAL_LOCK(husart); + + husart->State = HAL_USART_STATE_BUSY; + + /* Save actual USART configuration */ + tmpcr1 = READ_REG(husart->Instance->CR1); + + /* Disable USART */ + __HAL_USART_DISABLE(husart); + + /* Update RX threshold configuration */ + MODIFY_REG(husart->Instance->CR3, USART_CR3_RXFTCFG, Threshold); + + /* Determine the number of data to process during RX/TX ISR execution */ + USARTEx_SetNbDataToProcess(husart); + + /* Restore USART configuration */ + WRITE_REG(husart->Instance->CR1, tmpcr1); + + husart->State = HAL_USART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + return HAL_OK; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup USARTEx_Private_Functions + * @{ + */ + +/** + * @brief Calculate the number of data to process in RX/TX ISR. + * @note The RX FIFO depth and the TX FIFO depth is extracted from + * the USART configuration registers. + * @param husart USART handle. + * @retval None + */ +static void USARTEx_SetNbDataToProcess(USART_HandleTypeDef *husart) +{ + uint8_t rx_fifo_depth; + uint8_t tx_fifo_depth; + uint8_t rx_fifo_threshold; + uint8_t tx_fifo_threshold; + /* 2 0U/1U added for MISRAC2012-Rule-18.1_b and MISRAC2012-Rule-18.1_d */ + static const uint8_t numerator[] = {1U, 1U, 1U, 3U, 7U, 1U, 0U, 0U}; + static const uint8_t denominator[] = {8U, 4U, 2U, 4U, 8U, 1U, 1U, 1U}; + + if (husart->FifoMode == USART_FIFOMODE_DISABLE) + { + husart->NbTxDataToProcess = 1U; + husart->NbRxDataToProcess = 1U; + } + else + { + rx_fifo_depth = RX_FIFO_DEPTH; + tx_fifo_depth = TX_FIFO_DEPTH; + rx_fifo_threshold = (uint8_t)((READ_BIT(husart->Instance->CR3, + USART_CR3_RXFTCFG) >> USART_CR3_RXFTCFG_Pos) & 0xFFU); + tx_fifo_threshold = (uint8_t)((READ_BIT(husart->Instance->CR3, + USART_CR3_TXFTCFG) >> USART_CR3_TXFTCFG_Pos) & 0xFFU); + husart->NbTxDataToProcess = ((uint16_t)tx_fifo_depth * numerator[tx_fifo_threshold]) / + (uint16_t)denominator[tx_fifo_threshold]; + husart->NbRxDataToProcess = ((uint16_t)rx_fifo_depth * numerator[rx_fifo_threshold]) / + (uint16_t)denominator[rx_fifo_threshold]; + } +} +/** + * @} + */ + +#endif /* HAL_USART_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_wwdg.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_wwdg.c new file mode 100644 index 0000000000..12feddb968 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_wwdg.c @@ -0,0 +1,419 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_wwdg.c + * @author MCD Application Team + * @brief WWDG HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Window Watchdog (WWDG) peripheral: + * + Initialization and Configuration functions + * + IO operation functions + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### WWDG Specific features ##### + ============================================================================== + [..] + Once enabled the WWDG generates a system reset on expiry of a programmed + time period, unless the program refreshes the counter (T[6;0] downcounter) + before reaching 0x3F value (i.e. a reset is generated when the counter + value rolls down from 0x40 to 0x3F). + + (+) An MCU reset is also generated if the counter value is refreshed + before the counter has reached the refresh window value. This + implies that the counter must be refreshed in a limited window. + (+) Once enabled the WWDG cannot be disabled except by a system reset. + (+) If required by application, an Early Wakeup Interrupt can be triggered + in order to be warned before WWDG expiration. The Early Wakeup Interrupt + (EWI) can be used if specific safety operations or data logging must + be performed before the actual reset is generated. When the downcounter + reaches 0x40, interrupt occurs. This mechanism requires WWDG interrupt + line to be enabled in NVIC. Once enabled, EWI interrupt cannot be + disabled except by a system reset. + (+) WWDGRST flag in RCC CSR register can be used to inform when a WWDG + reset occurs. + (+) The WWDG counter input clock is derived from the APB clock divided + by a programmable prescaler. + (+) WWDG clock (Hz) = PCLK1 / (4096 * Prescaler) + (+) WWDG timeout (mS) = 1000 * (T[5;0] + 1) / WWDG clock (Hz) + where T[5;0] are the lowest 6 bits of Counter. + (+) WWDG Counter refresh is allowed between the following limits : + (++) min time (mS) = 1000 * (Counter - Window) / WWDG clock + (++) max time (mS) = 1000 * (Counter - 0x40) / WWDG clock + (+) Typical values: + (++) Counter min (T[5;0] = 0x00) at 56MHz (PCLK1) with zero prescaler: + max timeout before reset: approximately 73.14us + (++) Counter max (T[5;0] = 0x3F) at 56MHz (PCLK1) with prescaler + dividing by 128: + max timeout before reset: approximately 599.18ms + + ##### How to use this driver ##### + ============================================================================== + + *** Common driver usage *** + =========================== + + [..] + (+) Enable WWDG APB1 clock using __HAL_RCC_WWDG_CLK_ENABLE(). + (+) Configure the WWDG prescaler, refresh window value, counter value and early + interrupt status using HAL_WWDG_Init() function. This will automatically + enable WWDG and start its downcounter. Time reference can be taken from + function exit. Care must be taken to provide a counter value + greater than 0x40 to prevent generation of immediate reset. + (+) If the Early Wakeup Interrupt (EWI) feature is enabled, an interrupt is + generated when the counter reaches 0x40. When HAL_WWDG_IRQHandler is + triggered by the interrupt service routine, flag will be automatically + cleared and HAL_WWDG_WakeupCallback user callback will be executed. User + can add his own code by customization of callback HAL_WWDG_WakeupCallback. + (+) Then the application program must refresh the WWDG counter at regular + intervals during normal operation to prevent an MCU reset, using + HAL_WWDG_Refresh() function. This operation must occur only when + the counter is lower than the refresh window value already programmed. + + *** Callback registration *** + ============================= + + [..] + The compilation define USE_HAL_WWDG_REGISTER_CALLBACKS when set to 1 allows + the user to configure dynamically the driver callbacks. Use Functions + HAL_WWDG_RegisterCallback() to register a user callback. + + (+) Function HAL_WWDG_RegisterCallback() allows to register following + callbacks: + (++) EwiCallback : callback for Early WakeUp Interrupt. + (++) MspInitCallback : WWDG MspInit. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + + (+) Use function HAL_WWDG_UnRegisterCallback() to reset a callback to + the default weak (surcharged) function. HAL_WWDG_UnRegisterCallback() + takes as parameters the HAL peripheral handle and the Callback ID. + This function allows to reset following callbacks: + (++) EwiCallback : callback for Early WakeUp Interrupt. + (++) MspInitCallback : WWDG MspInit. + + [..] + When calling HAL_WWDG_Init function, callbacks are reset to the + corresponding legacy weak (surcharged) functions: + HAL_WWDG_EarlyWakeupCallback() and HAL_WWDG_MspInit() only if they have + not been registered before. + + [..] + When compilation define USE_HAL_WWDG_REGISTER_CALLBACKS is set to 0 or + not defined, the callback registering feature is not available + and weak (surcharged) callbacks are used. + + *** WWDG HAL driver macros list *** + =================================== + [..] + Below the list of available macros in WWDG HAL driver. + (+) __HAL_WWDG_ENABLE: Enable the WWDG peripheral + (+) __HAL_WWDG_GET_FLAG: Get the selected WWDG's flag status + (+) __HAL_WWDG_CLEAR_FLAG: Clear the WWDG's pending flags + (+) __HAL_WWDG_ENABLE_IT: Enable the WWDG early wakeup interrupt + + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +#ifdef HAL_WWDG_MODULE_ENABLED +/** @defgroup WWDG WWDG + * @brief WWDG HAL module driver. + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup WWDG_Exported_Functions WWDG Exported Functions + * @{ + */ + +/** @defgroup WWDG_Exported_Functions_Group1 Initialization and Configuration functions + * @brief Initialization and Configuration functions. + * +@verbatim + ============================================================================== + ##### Initialization and Configuration functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and start the WWDG according to the specified parameters + in the WWDG_InitTypeDef of associated handle. + (+) Initialize the WWDG MSP. + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the WWDG according to the specified. + * parameters in the WWDG_InitTypeDef of associated handle. + * @param hwwdg pointer to a WWDG_HandleTypeDef structure that contains + * the configuration information for the specified WWDG module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_WWDG_Init(WWDG_HandleTypeDef *hwwdg) +{ + /* Check the WWDG handle allocation */ + if (hwwdg == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_WWDG_ALL_INSTANCE(hwwdg->Instance)); + assert_param(IS_WWDG_PRESCALER(hwwdg->Init.Prescaler)); + assert_param(IS_WWDG_WINDOW(hwwdg->Init.Window)); + assert_param(IS_WWDG_COUNTER(hwwdg->Init.Counter)); + assert_param(IS_WWDG_EWI_MODE(hwwdg->Init.EWIMode)); + +#if (USE_HAL_WWDG_REGISTER_CALLBACKS == 1) + /* Reset Callback pointers */ + if (hwwdg->EwiCallback == NULL) + { + hwwdg->EwiCallback = HAL_WWDG_EarlyWakeupCallback; + } + + if (hwwdg->MspInitCallback == NULL) + { + hwwdg->MspInitCallback = HAL_WWDG_MspInit; + } + + /* Init the low level hardware */ + hwwdg->MspInitCallback(hwwdg); +#else + /* Init the low level hardware */ + HAL_WWDG_MspInit(hwwdg); +#endif /* USE_HAL_WWDG_REGISTER_CALLBACKS */ + + /* Set WWDG Counter */ + WRITE_REG(hwwdg->Instance->CR, (WWDG_CR_WDGA | hwwdg->Init.Counter)); + + /* Set WWDG Prescaler and Window */ + WRITE_REG(hwwdg->Instance->CFR, (hwwdg->Init.EWIMode | hwwdg->Init.Prescaler | hwwdg->Init.Window)); + + /* Return function status */ + return HAL_OK; +} + + +/** + * @brief Initialize the WWDG MSP. + * @param hwwdg pointer to a WWDG_HandleTypeDef structure that contains + * the configuration information for the specified WWDG module. + * @note When rewriting this function in user file, mechanism may be added + * to avoid multiple initialize when HAL_WWDG_Init function is called + * again to change parameters. + * @retval None + */ +__weak void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hwwdg); + + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_WWDG_MspInit could be implemented in the user file + */ +} + + +#if (USE_HAL_WWDG_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User WWDG Callback + * To be used instead of the weak (surcharged) predefined callback + * @param hwwdg WWDG handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_WWDG_EWI_CB_ID Early WakeUp Interrupt Callback ID + * @arg @ref HAL_WWDG_MSPINIT_CB_ID MspInit callback ID + * @param pCallback pointer to the Callback function + * @retval status + */ +HAL_StatusTypeDef HAL_WWDG_RegisterCallback(WWDG_HandleTypeDef *hwwdg, HAL_WWDG_CallbackIDTypeDef CallbackID, + pWWDG_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + status = HAL_ERROR; + } + else + { + switch (CallbackID) + { + case HAL_WWDG_EWI_CB_ID: + hwwdg->EwiCallback = pCallback; + break; + + case HAL_WWDG_MSPINIT_CB_ID: + hwwdg->MspInitCallback = pCallback; + break; + + default: + status = HAL_ERROR; + break; + } + } + + return status; +} + + +/** + * @brief Unregister a WWDG Callback + * WWDG Callback is redirected to the weak (surcharged) predefined callback + * @param hwwdg WWDG handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_WWDG_EWI_CB_ID Early WakeUp Interrupt Callback ID + * @arg @ref HAL_WWDG_MSPINIT_CB_ID MspInit callback ID + * @retval status + */ +HAL_StatusTypeDef HAL_WWDG_UnRegisterCallback(WWDG_HandleTypeDef *hwwdg, HAL_WWDG_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + switch (CallbackID) + { + case HAL_WWDG_EWI_CB_ID: + hwwdg->EwiCallback = HAL_WWDG_EarlyWakeupCallback; + break; + + case HAL_WWDG_MSPINIT_CB_ID: + hwwdg->MspInitCallback = HAL_WWDG_MspInit; + break; + + default: + status = HAL_ERROR; + break; + } + + return status; +} +#endif /* USE_HAL_WWDG_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup WWDG_Exported_Functions_Group2 IO operation functions + * @brief IO operation functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Refresh the WWDG. + (+) Handle WWDG interrupt request and associated function callback. + +@endverbatim + * @{ + */ + +/** + * @brief Refresh the WWDG. + * @param hwwdg pointer to a WWDG_HandleTypeDef structure that contains + * the configuration information for the specified WWDG module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_WWDG_Refresh(WWDG_HandleTypeDef *hwwdg) +{ + /* Write to WWDG CR the WWDG Counter value to refresh with */ + WRITE_REG(hwwdg->Instance->CR, (hwwdg->Init.Counter)); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Handle WWDG interrupt request. + * @note The Early Wakeup Interrupt (EWI) can be used if specific safety operations + * or data logging must be performed before the actual reset is generated. + * The EWI interrupt is enabled by calling HAL_WWDG_Init function with + * EWIMode set to WWDG_EWI_ENABLE. + * When the downcounter reaches the value 0x40, and EWI interrupt is + * generated and the corresponding Interrupt Service Routine (ISR) can + * be used to trigger specific actions (such as communications or data + * logging), before resetting the device. + * @param hwwdg pointer to a WWDG_HandleTypeDef structure that contains + * the configuration information for the specified WWDG module. + * @retval None + */ +void HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg) +{ + /* Check if Early Wakeup Interrupt is enable */ + if (__HAL_WWDG_GET_IT_SOURCE(hwwdg, WWDG_IT_EWI) != RESET) + { + /* Check if WWDG Early Wakeup Interrupt occurred */ + if (__HAL_WWDG_GET_FLAG(hwwdg, WWDG_FLAG_EWIF) != RESET) + { + /* Clear the WWDG Early Wakeup flag */ + __HAL_WWDG_CLEAR_FLAG(hwwdg, WWDG_FLAG_EWIF); + +#if (USE_HAL_WWDG_REGISTER_CALLBACKS == 1) + /* Early Wakeup registered callback */ + hwwdg->EwiCallback(hwwdg); +#else + /* Early Wakeup callback */ + HAL_WWDG_EarlyWakeupCallback(hwwdg); +#endif /* USE_HAL_WWDG_REGISTER_CALLBACKS */ + } + } +} + + +/** + * @brief WWDG Early Wakeup callback. + * @param hwwdg pointer to a WWDG_HandleTypeDef structure that contains + * the configuration information for the specified WWDG module. + * @retval None + */ +__weak void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hwwdg); + + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_WWDG_EarlyWakeupCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_WWDG_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_xspi.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_xspi.c new file mode 100644 index 0000000000..69412887c4 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_hal_xspi.c @@ -0,0 +1,3193 @@ +/** + ****************************************************************************** + * @file stm32h5xx_hal_xspi.c + * @author MCD Application Team + * @brief XSPI HAL module driver. + This file provides firmware functions to manage the following + functionalities of the OctoSPI interface (XSPI). + + Initialization and de-initialization functions + + Hyperbus configuration + + Indirect functional mode management + + Memory-mapped functional mode management + + Auto-polling functional mode management + + Interrupts and flags management + + DMA channel configuration for indirect functional mode + + Errors management and abort functionality + + Delay block configuration + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + =============================================================================== + ##### How to use this driver ##### + =============================================================================== + [..] + *** Initialization *** + ====================== + [..] + As prerequisite, fill in the HAL_XSPI_MspInit() : + (+) Enable OctoSPI clocks interface with __HAL_RCC_XSPI_CLK_ENABLE(). + (+) Reset OctoSPI Peripheral with __HAL_RCC_XSPI_FORCE_RESET() and __HAL_RCC_XSPI_RELEASE_RESET(). + (+) Enable the clocks for the OctoSPI GPIOS with __HAL_RCC_GPIOx_CLK_ENABLE(). + (+) Configure these OctoSPI pins in alternate mode using HAL_GPIO_Init(). + (+) If interrupt or DMA mode is used, enable and configure OctoSPI global + interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ(). + (+) If DMA mode is used, enable the clocks for the OctoSPI DMA channel + with __HAL_RCC_DMAx_CLK_ENABLE(), configure DMA with HAL_DMA_Init(), + link it with OctoSPI handle using __HAL_LINKDMA(), enable and configure + DMA channel global interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ(). + [..] + Configure the fifo threshold, the memory mode, the memory type, the + device size, the CS high time, the free running clock, the clock mode, + the wrap size, the clock prescaler, the sample shifting, the hold delay + and the CS boundary using the HAL_XSPI_Init() function. + [..] + When using Hyperbus, configure the RW recovery time, the access time, + the write latency and the latency mode using the HAL_XSPI_HyperbusCfg() + function. + + *** Indirect functional mode *** + ================================ + [..] + In regular mode, configure the command sequence using the HAL_XSPI_Command() + or HAL_XSPI_Command_IT() functions : + (+) Instruction phase : the mode used and if present the size, the instruction + opcode and the DTR mode. + (+) Address phase : the mode used and if present the size, the address + value and the DTR mode. + (+) Alternate-bytes phase : the mode used and if present the size, the + alternate bytes values and the DTR mode. + (+) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase). + (+) Data phase : the mode used and if present the number of bytes and the DTR mode. + (+) Data strobe (DQS) mode : the activation (or not) of this mode + (+) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode. + (+) IO selection : to access external memory. + (+) Operation type : always common configuration. + [..] + In Hyperbus mode, configure the command sequence using the HAL_XSPI_HyperbusCmd() + function : + (+) Address space : indicate if the access will be done in register or memory + (+) Address size + (+) Number of data + (+) Data strobe (DQS) mode : the activation (or not) of this mode + [..] + If no data is required for the command (only for regular mode, not for + Hyperbus mode), it is sent directly to the memory : + (+) In polling mode, the output of the function is done when the transfer is complete. + (+) In interrupt mode, HAL_XSPI_CmdCpltCallback() will be called when the transfer is complete. + [..] + For the indirect write mode, use HAL_XSPI_Transmit(), HAL_XSPI_Transmit_DMA() or + HAL_XSPI_Transmit_IT() after the command configuration : + (+) In polling mode, the output of the function is done when the transfer is complete. + (+) In interrupt mode, HAL_XSPI_FifoThresholdCallback() will be called when the fifo threshold + is reached and HAL_XSPI_TxCpltCallback() will be called when the transfer is complete. + (+) In DMA mode, HAL_XSPI_TxHalfCpltCallback() will be called at the half transfer and + HAL_XSPI_TxCpltCallback() will be called when the transfer is complete. + [..] + For the indirect read mode, use HAL_XSPI_Receive(), HAL_XSPI_Receive_DMA() or + HAL_XSPI_Receive_IT() after the command configuration : + (+) In polling mode, the output of the function is done when the transfer is complete. + (+) In interrupt mode, HAL_XSPI_FifoThresholdCallback() will be called when the fifo threshold + is reached and HAL_XSPI_RxCpltCallback() will be called when the transfer is complete. + (+) In DMA mode, HAL_XSPI_RxHalfCpltCallback() will be called at the half transfer and + HAL_XSPI_RxCpltCallback() will be called when the transfer is complete. + + *** Auto-polling functional mode *** + ==================================== + [..] + Configure the command sequence by the same way than the indirect mode + [..] + Configure the auto-polling functional mode using the HAL_XSPI_AutoPolling() + or HAL_XSPI_AutoPolling_IT() functions : + (+) The size of the status bytes, the match value, the mask used, the match mode (OR/AND), + the polling interval and the automatic stop activation. + [..] + After the configuration : + (+) In polling mode, the output of the function is done when the status match is reached. The + automatic stop is activated to avoid an infinite loop. + (+) In interrupt mode, HAL_XSPI_StatusMatchCallback() will be called each time the status match is reached. + + *** Memory-mapped functional mode *** + ===================================== + [..] + Configure the command sequence by the same way than the indirect mode except + for the operation type in regular mode : + (+) Operation type equals to read configuration : the command configuration + applies to read access in memory-mapped mode + (+) Operation type equals to write configuration : the command configuration + applies to write access in memory-mapped mode + (+) Both read and write configuration should be performed before activating + memory-mapped mode + [..] + Configure the memory-mapped functional mode using the HAL_XSPI_MemoryMapped() + functions : + (+) The timeout activation and the timeout period. + [..] + After the configuration, the OctoSPI will be used as soon as an access on the AHB is done on + the address range. HAL_XSPI_TimeOutCallback() will be called when the timeout expires. + + *** Errors management and abort functionality *** + ================================================= + [..] + HAL_XSPI_GetError() function gives the error raised during the last operation. + [..] + HAL_XSPI_Abort() and HAL_XSPI_AbortIT() functions aborts any on-going operation and + flushes the fifo : + (+) In polling mode, the output of the function is done when the transfer + complete bit is set and the busy bit cleared. + (+) In interrupt mode, HAL_XSPI_AbortCpltCallback() will be called when + the transfer complete bit is set. + + *** Control functions *** + ========================= + [..] + HAL_XSPI_GetState() function gives the current state of the HAL XSPI driver. + [..] + HAL_XSPI_SetTimeout() function configures the timeout value used in the driver. + [..] + HAL_XSPI_SetFifoThreshold() function configures the threshold on the Fifo of the OctoSPI Peripheral. + [..] + HAL_XSPI_SetMemoryType() function configures the type of the external memory. + [..] + HAL_XSPI_SetDeviceSize() function configures the size of the external memory. + [..] + HAL_XSPI_SetClockPrescaler() function configures the clock prescaler of the OctoSPI Peripheral. + [..] + HAL_XSPI_GetFifoThreshold() function gives the current of the Fifo's threshold + + *** Delay Block functions *** + ========================================== + [..] + The delay block (DLYB) is used to generate an output clock that is dephased from the input clock. + (+) The delay line length can be Configure to one period of the Input clock with HAL_XSPI_DLYB_GetClockPeriod(). + (+) The phase of the output clock can be programmed directly with HAL_XSPI_DLYB_SetConfig(). + (+) The phase of the output clock can be got with HAL_XSPI_DLYB_GetConfig(). + [..] + + *** Callback registration *** + ============================================= + [..] + The compilation define USE_HAL_XSPI_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + + [..] + Use function HAL_XSPI_RegisterCallback() to register a user callback, + it allows to register following callbacks: + (+) ErrorCallback : callback when error occurs. + (+) AbortCpltCallback : callback when abort is completed. + (+) FifoThresholdCallback : callback when the fifo threshold is reached. + (+) CmdCpltCallback : callback when a command without data is completed. + (+) RxCpltCallback : callback when a reception transfer is completed. + (+) TxCpltCallback : callback when a transmission transfer is completed. + (+) RxHalfCpltCallback : callback when half of the reception transfer is completed. + (+) TxHalfCpltCallback : callback when half of the transmission transfer is completed. + (+) StatusMatchCallback : callback when a status match occurs. + (+) TimeOutCallback : callback when the timeout perioed expires. + (+) MspInitCallback : XSPI MspInit. + (+) MspDeInitCallback : XSPI MspDeInit. + [..] + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + + [..] + Use function HAL_XSPI_UnRegisterCallback() to reset a callback to the default + weak (overridden) function. It allows to reset following callbacks: + (+) ErrorCallback : callback when error occurs. + (+) AbortCpltCallback : callback when abort is completed. + (+) FifoThresholdCallback : callback when the fifo threshold is reached. + (+) CmdCpltCallback : callback when a command without data is completed. + (+) RxCpltCallback : callback when a reception transfer is completed. + (+) TxCpltCallback : callback when a transmission transfer is completed. + (+) RxHalfCpltCallback : callback when half of the reception transfer is completed. + (+) TxHalfCpltCallback : callback when half of the transmission transfer is completed. + (+) StatusMatchCallback : callback when a status match occurs. + (+) TimeOutCallback : callback when the timeout perioed expires. + (+) MspInitCallback : XSPI MspInit. + (+) MspDeInitCallback : XSPI MspDeInit. + [..] + This function) takes as parameters the HAL peripheral handle and the Callback ID. + + [..] + By default, after the HAL_XSPI_Init() and if the state is HAL_XSPI_STATE_RESET + all callbacks are reset to the corresponding legacy weak (overridden) functions. + Exception done for MspInit and MspDeInit callbacks that are respectively + reset to the legacy weak (overridden) functions in the HAL_XSPI_Init() + and HAL_XSPI_DeInit() only when these callbacks are null (not registered beforehand). + If not, MspInit or MspDeInit are not null, the HAL_XSPI_Init() and HAL_XSPI_DeInit() + keep and use the user MspInit/MspDeInit callbacks (registered beforehand) + + [..] + Callbacks can be registered/unregistered in READY state only. + Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered + in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used + during the Init/DeInit. + In that case first register the MspInit/MspDeInit user callbacks + using HAL_XSPI_RegisterCallback() before calling HAL_XSPI_DeInit() + or HAL_XSPI_Init() function. + + [..] + When The compilation define USE_HAL_XSPI_REGISTER_CALLBACKS is set to 0 or + not defined, the callback registering feature is not available + and weak (overridden) callbacks are used. + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +#if defined(HSPI) || defined(HSPI1) || defined(HSPI2)|| defined(OCTOSPI) || defined(OCTOSPI1)|| defined(OCTOSPI2) + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup XSPI XSPI + * @brief XSPI HAL module driver + * @{ + */ + +#ifdef HAL_XSPI_MODULE_ENABLED + +/** + @cond 0 + */ +/* Private typedef -----------------------------------------------------------*/ + +/* Private define ------------------------------------------------------------*/ +#define XSPI_FUNCTIONAL_MODE_INDIRECT_WRITE ((uint32_t)0x00000000) /*!< Indirect write mode */ +#define XSPI_FUNCTIONAL_MODE_INDIRECT_READ ((uint32_t)XSPI_CR_FMODE_0) /*!< Indirect read mode */ +#define XSPI_FUNCTIONAL_MODE_AUTO_POLLING ((uint32_t)XSPI_CR_FMODE_1) /*!< Automatic polling mode */ +#define XSPI_FUNCTIONAL_MODE_MEMORY_MAPPED ((uint32_t)XSPI_CR_FMODE) /*!< Memory-mapped mode */ + +#define XSPI_CFG_STATE_MASK 0x00000004U +#define XSPI_BUSY_STATE_MASK 0x00000008U + +/* Private macro -------------------------------------------------------------*/ +#define IS_XSPI_FUNCTIONAL_MODE(MODE) (((MODE) == XSPI_FUNCTIONAL_MODE_INDIRECT_WRITE) || \ + ((MODE) == XSPI_FUNCTIONAL_MODE_INDIRECT_READ) || \ + ((MODE) == XSPI_FUNCTIONAL_MODE_AUTO_POLLING) || \ + ((MODE) == XSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)) + +/* Private variables ---------------------------------------------------------*/ + +/* Private function prototypes -----------------------------------------------*/ +static void XSPI_DMACplt(DMA_HandleTypeDef *hdma); +static void XSPI_DMAHalfCplt(DMA_HandleTypeDef *hdma); +static void XSPI_DMAError(DMA_HandleTypeDef *hdma); +static void XSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma); +static HAL_StatusTypeDef XSPI_WaitFlagStateUntilTimeout(XSPI_HandleTypeDef *hxspi, uint32_t Flag, FlagStatus State, + uint32_t Tickstart, uint32_t Timeout); +static HAL_StatusTypeDef XSPI_ConfigCmd(XSPI_HandleTypeDef *hxspi, XSPI_RegularCmdTypeDef *const pCmd); +/** + @endcond + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup XSPI_Exported_Functions XSPI Exported Functions + * @{ + */ + +/** @defgroup XSPI_Exported_Functions_Group1 Initialization/de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim +=============================================================================== + ##### Initialization and Configuration functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to : + (+) Initialize the XSPI. + (+) De-initialize the XSPI. + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the XSPI mode according to the specified parameters + * in the XSPI_InitTypeDef and initialize the associated handle. + * @param hxspi : XSPI handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_XSPI_Init(XSPI_HandleTypeDef *hxspi) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tickstart = HAL_GetTick(); + + /* Check the XSPI handle allocation */ + if (hxspi == NULL) + { + status = HAL_ERROR; + /* No error code can be set set as the handler is null */ + } + else + { + /* Check the parameters of the initialization structure */ + assert_param(IS_XSPI_MEMORY_MODE(hxspi->Init.MemoryMode)); + assert_param(IS_XSPI_MEMORY_TYPE(hxspi->Init.MemoryType)); + assert_param(IS_XSPI_MEMORY_SIZE(hxspi->Init.MemorySize)); + assert_param(IS_XSPI_CS_HIGH_TIME_CYCLE(hxspi->Init.ChipSelectHighTimeCycle)); + assert_param(IS_XSPI_FREE_RUN_CLK(hxspi->Init.FreeRunningClock)); + assert_param(IS_XSPI_CLOCK_MODE(hxspi->Init.ClockMode)); + assert_param(IS_XSPI_WRAP_SIZE(hxspi->Init.WrapSize)); + assert_param(IS_XSPI_CLK_PRESCALER(hxspi->Init.ClockPrescaler)); + assert_param(IS_XSPI_SAMPLE_SHIFTING(hxspi->Init.SampleShifting)); + assert_param(IS_XSPI_DHQC(hxspi->Init.DelayHoldQuarterCycle)); + assert_param(IS_XSPI_CS_BOUND(hxspi->Init.ChipSelectBoundary)); + assert_param(IS_XSPI_FIFO_THRESHOLD_BYTE(hxspi->Init.FifoThresholdByte)); + if (IS_OSPI_ALL_INSTANCE(hxspi->Instance)) + { + assert_param(IS_XSPI_DLYB_BYPASS(hxspi->Init.DelayBlockBypass)); + } + /* Initialize error code */ + hxspi->ErrorCode = HAL_XSPI_ERROR_NONE; + + /* Check if the state is the reset state */ + if (hxspi->State == HAL_XSPI_STATE_RESET) + { +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) + /* Reset Callback pointers in HAL_XSPI_STATE_RESET only */ + hxspi->ErrorCallback = HAL_XSPI_ErrorCallback; + hxspi->AbortCpltCallback = HAL_XSPI_AbortCpltCallback; + hxspi->FifoThresholdCallback = HAL_XSPI_FifoThresholdCallback; + hxspi->CmdCpltCallback = HAL_XSPI_CmdCpltCallback; + hxspi->RxCpltCallback = HAL_XSPI_RxCpltCallback; + hxspi->TxCpltCallback = HAL_XSPI_TxCpltCallback; + hxspi->RxHalfCpltCallback = HAL_XSPI_RxHalfCpltCallback; + hxspi->TxHalfCpltCallback = HAL_XSPI_TxHalfCpltCallback; + hxspi->StatusMatchCallback = HAL_XSPI_StatusMatchCallback; + hxspi->TimeOutCallback = HAL_XSPI_TimeOutCallback; + + if (hxspi->MspInitCallback == NULL) + { + hxspi->MspInitCallback = HAL_XSPI_MspInit; + } + + /* Init the low level hardware */ + hxspi->MspInitCallback(hxspi); +#else + /* Initialization of the low level hardware */ + HAL_XSPI_MspInit(hxspi); +#endif /* defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */ + + /* Configure the default timeout for the XSPI memory access */ + (void)HAL_XSPI_SetTimeout(hxspi, HAL_XSPI_TIMEOUT_DEFAULT_VALUE); + + /* Configure memory type, device size, chip select high time, free running clock, clock mode */ + MODIFY_REG(hxspi->Instance->DCR1, + (XSPI_DCR1_MTYP | XSPI_DCR1_DEVSIZE | XSPI_DCR1_CSHT | XSPI_DCR1_FRCK | XSPI_DCR1_CKMODE), + (hxspi->Init.MemoryType | ((hxspi->Init.MemorySize) << XSPI_DCR1_DEVSIZE_Pos) | + ((hxspi->Init.ChipSelectHighTimeCycle - 1U) << XSPI_DCR1_CSHT_Pos) | hxspi->Init.ClockMode)); + + /* Configure delay block bypass */ + if (IS_OSPI_ALL_INSTANCE(hxspi->Instance)) + { + MODIFY_REG(hxspi->Instance->DCR1, OCTOSPI_DCR1_DLYBYP, hxspi->Init.DelayBlockBypass); + } + + /* Configure wrap size */ + MODIFY_REG(hxspi->Instance->DCR2, XSPI_DCR2_WRAPSIZE, hxspi->Init.WrapSize); + + /* Configure chip select boundary */ + MODIFY_REG(hxspi->Instance->DCR3, XSPI_DCR3_CSBOUND, (hxspi->Init.ChipSelectBoundary << XSPI_DCR3_CSBOUND_Pos)); + + /* Configure refresh */ + hxspi->Instance->DCR4 = hxspi->Init.Refresh; + + /* Configure FIFO threshold */ + MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FTHRES, ((hxspi->Init.FifoThresholdByte - 1U) << XSPI_CR_FTHRES_Pos)); + + /* Wait till busy flag is reset */ + status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, hxspi->Timeout); + + if (status == HAL_OK) + { + /* Configure clock prescaler */ + MODIFY_REG(hxspi->Instance->DCR2, XSPI_DCR2_PRESCALER, + ((hxspi->Init.ClockPrescaler) << XSPI_DCR2_PRESCALER_Pos)); + + /* Configure Dual Memory mode */ + MODIFY_REG(hxspi->Instance->CR, XSPI_CR_DMM, hxspi->Init.MemoryMode); + + /* Configure sample shifting and delay hold quarter cycle */ + MODIFY_REG(hxspi->Instance->TCR, (XSPI_TCR_SSHIFT | XSPI_TCR_DHQC), + (hxspi->Init.SampleShifting | hxspi->Init.DelayHoldQuarterCycle)); + + /* Enable XSPI */ + HAL_XSPI_ENABLE(hxspi); + + /* Enable free running clock if needed : must be done after XSPI enable */ + if (hxspi->Init.FreeRunningClock == HAL_XSPI_FREERUNCLK_ENABLE) + { + SET_BIT(hxspi->Instance->DCR1, XSPI_DCR1_FRCK); + } + + /* Initialize the XSPI state */ + if (hxspi->Init.MemoryType == HAL_XSPI_MEMTYPE_HYPERBUS) + { + hxspi->State = HAL_XSPI_STATE_HYPERBUS_INIT; + } + else + { + hxspi->State = HAL_XSPI_STATE_READY; + } + } + } + } + return status; +} + +/** + * @brief Initialize the XSPI MSP. + * @param hxspi : XSPI handle + * @retval None + */ +__weak void HAL_XSPI_MspInit(XSPI_HandleTypeDef *hxspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hxspi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_XSPI_MspInit can be implemented in the user file + */ +} + +/** + * @brief De-Initialize the XSPI peripheral. + * @param hxspi : XSPI handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_XSPI_DeInit(XSPI_HandleTypeDef *hxspi) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the XSPI handle allocation */ + if (hxspi == NULL) + { + status = HAL_ERROR; + /* No error code can be set as the handler is null */ + } + else + { + /* Disable XSPI */ + HAL_XSPI_DISABLE(hxspi); + + /* Disable free running clock if needed : must be done after XSPI disable */ + CLEAR_BIT(hxspi->Instance->DCR1, XSPI_DCR1_FRCK); + +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) + if (hxspi->MspDeInitCallback == NULL) + { + hxspi->MspDeInitCallback = HAL_XSPI_MspDeInit; + } + + /* De-initialize the low level hardware */ + hxspi->MspDeInitCallback(hxspi); +#else + /* De-initialize the low-level hardware */ + HAL_XSPI_MspDeInit(hxspi); +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */ + + /* Reset the driver state */ + hxspi->State = HAL_XSPI_STATE_RESET; + } + + return status; +} + +/** + * @brief DeInitialize the XSPI MSP. + * @param hxspi : XSPI handle + * @retval None + */ +__weak void HAL_XSPI_MspDeInit(XSPI_HandleTypeDef *hxspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hxspi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_XSPI_MspDeInit can be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup XSPI_Exported_Functions_Group2 Input and Output operation functions + * @brief XSPI Transmit/Receive functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to : + (+) Handle the interrupts. + (+) Handle the command sequence (regular and Hyperbus). + (+) Handle the Hyperbus configuration. + (+) Transmit data in blocking, interrupt or DMA mode. + (+) Receive data in blocking, interrupt or DMA mode. + (+) Manage the auto-polling functional mode. + (+) Manage the memory-mapped functional mode. + +@endverbatim + * @{ + */ + +/** + * @brief Handle XSPI interrupt request. + * @param hxspi : XSPI handle + * @retval None + */ +void HAL_XSPI_IRQHandler(XSPI_HandleTypeDef *hxspi) +{ + __IO uint32_t *data_reg = &hxspi->Instance->DR; + uint32_t flag = hxspi->Instance->SR; + uint32_t itsource = hxspi->Instance->CR; + uint32_t currentstate = hxspi->State; + + /* XSPI fifo threshold interrupt occurred -------------------------------*/ + if (((flag & HAL_XSPI_FLAG_FT) != 0U) && ((itsource & HAL_XSPI_IT_FT) != 0U)) + { + if (currentstate == HAL_XSPI_STATE_BUSY_TX) + { + /* Write a data in the fifo */ + *((__IO uint8_t *)data_reg) = *hxspi->pBuffPtr; + hxspi->pBuffPtr++; + hxspi->XferCount--; + } + else if (currentstate == HAL_XSPI_STATE_BUSY_RX) + { + /* Read a data from the fifo */ + *hxspi->pBuffPtr = *((__IO uint8_t *)data_reg); + hxspi->pBuffPtr++; + hxspi->XferCount--; + } + else + { + /* Nothing to do */ + } + + if (hxspi->XferCount == 0U) + { + /* All data have been received or transmitted for the transfer */ + /* Disable fifo threshold interrupt */ + HAL_XSPI_DISABLE_IT(hxspi, HAL_XSPI_IT_FT); + } + + /* Fifo threshold callback */ +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) + hxspi->FifoThresholdCallback(hxspi); +#else + HAL_XSPI_FifoThresholdCallback(hxspi); +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */ + } + /* XSPI transfer complete interrupt occurred ----------------------------*/ + else if (((flag & HAL_XSPI_FLAG_TC) != 0U) && ((itsource & HAL_XSPI_IT_TC) != 0U)) + { + if (currentstate == HAL_XSPI_STATE_BUSY_RX) + { + if ((hxspi->XferCount > 0U) && ((flag & XSPI_SR_FLEVEL) != 0U)) + { + /* Read the last data received in the fifo */ + *hxspi->pBuffPtr = *((__IO uint8_t *)data_reg); + hxspi->pBuffPtr++; + hxspi->XferCount--; + } + else if (hxspi->XferCount == 0U) + { + /* Clear flag */ + hxspi->Instance->FCR = HAL_XSPI_FLAG_TC; + + /* Disable the interrupts */ + HAL_XSPI_DISABLE_IT(hxspi, HAL_XSPI_IT_TC | HAL_XSPI_IT_FT | HAL_XSPI_IT_TE); + + hxspi->State = HAL_XSPI_STATE_READY; + + /* RX complete callback */ +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) + hxspi->RxCpltCallback(hxspi); +#else + HAL_XSPI_RxCpltCallback(hxspi); +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */ + } + else + { + /* Nothing to do */ + } + } + else + { + /* Clear flag */ + hxspi->Instance->FCR = HAL_XSPI_FLAG_TC; + + /* Disable the interrupts */ + HAL_XSPI_DISABLE_IT(hxspi, HAL_XSPI_IT_TC | HAL_XSPI_IT_FT | HAL_XSPI_IT_TE); + + hxspi->State = HAL_XSPI_STATE_READY; + + if (currentstate == HAL_XSPI_STATE_BUSY_TX) + { + /* TX complete callback */ +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) + hxspi->TxCpltCallback(hxspi); +#else + HAL_XSPI_TxCpltCallback(hxspi); +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */ + } + else if (currentstate == HAL_XSPI_STATE_BUSY_CMD) + { + /* Command complete callback */ +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) + hxspi->CmdCpltCallback(hxspi); +#else + HAL_XSPI_CmdCpltCallback(hxspi); +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */ + } + else if (currentstate == HAL_XSPI_STATE_ABORT) + { + if (hxspi->ErrorCode == HAL_XSPI_ERROR_NONE) + { + /* Abort called by the user */ + /* Abort complete callback */ +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) + hxspi->AbortCpltCallback(hxspi); +#else + HAL_XSPI_AbortCpltCallback(hxspi); +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */ + } + else + { + /* Abort due to an error (eg : DMA error) */ + /* Error callback */ +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) + hxspi->ErrorCallback(hxspi); +#else + HAL_XSPI_ErrorCallback(hxspi); +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */ + } + } + else + { + /* Nothing to do */ + } + } + } + /* XSPI status match interrupt occurred ---------------------------------*/ + else if (((flag & HAL_XSPI_FLAG_SM) != 0U) && ((itsource & HAL_XSPI_IT_SM) != 0U)) + { + /* Clear flag */ + hxspi->Instance->FCR = HAL_XSPI_FLAG_SM; + + /* Check if automatic poll mode stop is activated */ + if ((hxspi->Instance->CR & XSPI_CR_APMS) != 0U) + { + /* Disable the interrupts */ + HAL_XSPI_DISABLE_IT(hxspi, HAL_XSPI_IT_SM | HAL_XSPI_IT_TE); + + hxspi->State = HAL_XSPI_STATE_READY; + } + + /* Status match callback */ +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) + hxspi->StatusMatchCallback(hxspi); +#else + HAL_XSPI_StatusMatchCallback(hxspi); +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */ + } + /* XSPI transfer error interrupt occurred -------------------------------*/ + else if (((flag & HAL_XSPI_FLAG_TE) != 0U) && ((itsource & HAL_XSPI_IT_TE) != 0U)) + { + /* Clear flag */ + hxspi->Instance->FCR = HAL_XSPI_FLAG_TE; + + /* Disable all interrupts */ + HAL_XSPI_DISABLE_IT(hxspi, (HAL_XSPI_IT_TO | HAL_XSPI_IT_SM | HAL_XSPI_IT_FT | HAL_XSPI_IT_TC | HAL_XSPI_IT_TE)); + + /* Set error code */ + hxspi->ErrorCode = HAL_XSPI_ERROR_TRANSFER; + + /* Check if the DMA is enabled */ + if ((hxspi->Instance->CR & XSPI_CR_DMAEN) != 0U) + { + /* Disable the DMA transfer on the XSPI side */ + CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_DMAEN); + + /* Disable the DMA transmit on the DMA side */ + hxspi->hdmatx->XferAbortCallback = XSPI_DMAAbortCplt; + if (HAL_DMA_Abort_IT(hxspi->hdmatx) != HAL_OK) + { + hxspi->State = HAL_XSPI_STATE_READY; + + /* Error callback */ +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) + hxspi->ErrorCallback(hxspi); +#else + HAL_XSPI_ErrorCallback(hxspi); +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */ + } + + /* Disable the DMA receive on the DMA side */ + hxspi->hdmarx->XferAbortCallback = XSPI_DMAAbortCplt; + if (HAL_DMA_Abort_IT(hxspi->hdmarx) != HAL_OK) + { + hxspi->State = HAL_XSPI_STATE_READY; + + /* Error callback */ +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) + hxspi->ErrorCallback(hxspi); +#else + HAL_XSPI_ErrorCallback(hxspi); +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */ + } + } + else + { + hxspi->State = HAL_XSPI_STATE_READY; + + /* Error callback */ +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) + hxspi->ErrorCallback(hxspi); +#else + HAL_XSPI_ErrorCallback(hxspi); +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */ + } + } + /* XSPI timeout interrupt occurred --------------------------------------*/ + else if (((flag & HAL_XSPI_FLAG_TO) != 0U) && ((itsource & HAL_XSPI_IT_TO) != 0U)) + { + /* Clear flag */ + hxspi->Instance->FCR = HAL_XSPI_FLAG_TO; + + /* Timeout callback */ +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) + hxspi->TimeOutCallback(hxspi); +#else + HAL_XSPI_TimeOutCallback(hxspi); +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */ + } + else + { + /* Nothing to do */ + } +} + +/** + * @brief Set the command configuration. + * @param hxspi : XSPI handle + * @param pCmd : structure that contains the command configuration information + * @param Timeout : Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_XSPI_Command(XSPI_HandleTypeDef *hxspi, XSPI_RegularCmdTypeDef *const pCmd, uint32_t Timeout) +{ + HAL_StatusTypeDef status; + uint32_t state; + uint32_t tickstart = HAL_GetTick(); + + /* Check the parameters of the command structure */ + assert_param(IS_XSPI_OPERATION_TYPE(pCmd->OperationType)); + if (hxspi->Init.MemoryMode == HAL_XSPI_SINGLE_MEM) + { + assert_param(IS_XSPI_IO_SELECT(pCmd->IOSelect)); + } + + assert_param(IS_XSPI_INSTRUCTION_MODE(pCmd->InstructionMode)); + if (pCmd->InstructionMode != HAL_XSPI_INSTRUCTION_NONE) + { + assert_param(IS_XSPI_INSTRUCTION_WIDTH(pCmd->InstructionWidth)); + assert_param(IS_XSPI_INSTRUCTION_DTR_MODE(pCmd->InstructionDTRMode)); + } + + assert_param(IS_XSPI_ADDRESS_MODE(pCmd->AddressMode)); + if (pCmd->AddressMode != HAL_XSPI_ADDRESS_NONE) + { + assert_param(IS_XSPI_ADDRESS_WIDTH(pCmd->AddressWidth)); + assert_param(IS_XSPI_ADDRESS_DTR_MODE(pCmd->AddressDTRMode)); + } + + assert_param(IS_XSPI_ALT_BYTES_MODE(pCmd->AlternateBytesMode)); + if (pCmd->AlternateBytesMode != HAL_XSPI_ALT_BYTES_NONE) + { + assert_param(IS_XSPI_ALT_BYTES_WIDTH(pCmd->AlternateBytesWidth)); + assert_param(IS_XSPI_ALT_BYTES_DTR_MODE(pCmd->AlternateBytesDTRMode)); + } + + assert_param(IS_XSPI_DATA_MODE(pCmd->DataMode)); + + if (pCmd->DataMode != HAL_XSPI_DATA_NONE) + { + if (pCmd->OperationType == HAL_XSPI_OPTYPE_COMMON_CFG) + { + assert_param(IS_XSPI_DATA_LENGTH(pCmd->DataLength)); + } + assert_param(IS_XSPI_DATA_DTR_MODE(pCmd->DataDTRMode)); + assert_param(IS_XSPI_DUMMY_CYCLES(pCmd->DummyCycles)); + } + + assert_param(IS_XSPI_DQS_MODE(pCmd->DQSMode)); + assert_param(IS_XSPI_SIOO_MODE(pCmd->SIOOMode)); + + /* Check the state of the driver */ + state = hxspi->State; + if (((state == HAL_XSPI_STATE_READY) && (hxspi->Init.MemoryType != HAL_XSPI_MEMTYPE_HYPERBUS)) || + ((state == HAL_XSPI_STATE_READ_CMD_CFG) && ((pCmd->OperationType == HAL_XSPI_OPTYPE_WRITE_CFG) || + (pCmd->OperationType == HAL_XSPI_OPTYPE_WRAP_CFG))) || + ((state == HAL_XSPI_STATE_WRITE_CMD_CFG) && + ((pCmd->OperationType == HAL_XSPI_OPTYPE_READ_CFG) || + (pCmd->OperationType == HAL_XSPI_OPTYPE_WRAP_CFG)))) + { + /* Wait till busy flag is reset */ + status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, Timeout); + + if (status == HAL_OK) + { + /* Initialize error code */ + hxspi->ErrorCode = HAL_XSPI_ERROR_NONE; + + /* Configure the registers */ + status = XSPI_ConfigCmd(hxspi, pCmd); + + if (status == HAL_OK) + { + if (pCmd->DataMode == HAL_XSPI_DATA_NONE) + { + /* When there is no data phase, the transfer start as soon as the configuration is done + so wait until TC flag is set to go back in idle state */ + status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_TC, SET, tickstart, Timeout); + + HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TC); + } + else + { + /* Update the state */ + if (pCmd->OperationType == HAL_XSPI_OPTYPE_COMMON_CFG) + { + hxspi->State = HAL_XSPI_STATE_CMD_CFG; + } + else if (pCmd->OperationType == HAL_XSPI_OPTYPE_READ_CFG) + { + if (hxspi->State == HAL_XSPI_STATE_WRITE_CMD_CFG) + { + hxspi->State = HAL_XSPI_STATE_CMD_CFG; + } + else + { + hxspi->State = HAL_XSPI_STATE_READ_CMD_CFG; + } + } + else if (pCmd->OperationType == HAL_XSPI_OPTYPE_WRITE_CFG) + { + if (hxspi->State == HAL_XSPI_STATE_READ_CMD_CFG) + { + hxspi->State = HAL_XSPI_STATE_CMD_CFG; + } + else + { + hxspi->State = HAL_XSPI_STATE_WRITE_CMD_CFG; + } + } + else + { + /* Wrap configuration, no state change */ + } + } + } + } + else + { + status = HAL_BUSY; + } + } + else + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE; + } + + return status; +} + +/** + * @brief Set the command configuration in interrupt mode. + * @param hxspi : XSPI handle + * @param pCmd : structure that contains the command configuration information + * @note This function is used only in Indirect Read or Write Modes + * @retval HAL status + */ +HAL_StatusTypeDef HAL_XSPI_Command_IT(XSPI_HandleTypeDef *hxspi, XSPI_RegularCmdTypeDef *const pCmd) +{ + HAL_StatusTypeDef status; + uint32_t tickstart = HAL_GetTick(); + + /* Check the parameters of the command structure */ + assert_param(IS_XSPI_OPERATION_TYPE(pCmd->OperationType)); + + if (hxspi->Init.MemoryMode == HAL_XSPI_SINGLE_MEM) + { + assert_param(IS_XSPI_IO_SELECT(pCmd->IOSelect)); + } + + assert_param(IS_XSPI_INSTRUCTION_MODE(pCmd->InstructionMode)); + if (pCmd->InstructionMode != HAL_XSPI_INSTRUCTION_NONE) + { + assert_param(IS_XSPI_INSTRUCTION_WIDTH(pCmd->InstructionWidth)); + assert_param(IS_XSPI_INSTRUCTION_DTR_MODE(pCmd->InstructionDTRMode)); + } + + assert_param(IS_XSPI_ADDRESS_MODE(pCmd->AddressMode)); + if (pCmd->AddressMode != HAL_XSPI_ADDRESS_NONE) + { + assert_param(IS_XSPI_ADDRESS_WIDTH(pCmd->AddressWidth)); + assert_param(IS_XSPI_ADDRESS_DTR_MODE(pCmd->AddressDTRMode)); + } + + assert_param(IS_XSPI_ALT_BYTES_MODE(pCmd->AlternateBytesMode)); + if (pCmd->AlternateBytesMode != HAL_XSPI_ALT_BYTES_NONE) + { + assert_param(IS_XSPI_ALT_BYTES_WIDTH(pCmd->AlternateBytesWidth)); + assert_param(IS_XSPI_ALT_BYTES_DTR_MODE(pCmd->AlternateBytesDTRMode)); + } + + assert_param(IS_XSPI_DATA_MODE(pCmd->DataMode)); + + if (pCmd->DataMode != HAL_XSPI_DATA_NONE) + { + assert_param(IS_XSPI_DATA_LENGTH(pCmd->DataLength)); + assert_param(IS_XSPI_DATA_DTR_MODE(pCmd->DataDTRMode)); + assert_param(IS_XSPI_DUMMY_CYCLES(pCmd->DummyCycles)); + } + + assert_param(IS_XSPI_DQS_MODE(pCmd->DQSMode)); + assert_param(IS_XSPI_SIOO_MODE(pCmd->SIOOMode)); + + /* Check the state of the driver */ + if ((hxspi->State == HAL_XSPI_STATE_READY) && (pCmd->OperationType == HAL_XSPI_OPTYPE_COMMON_CFG) && + (pCmd->DataMode == HAL_XSPI_DATA_NONE) && (hxspi->Init.MemoryType != HAL_XSPI_MEMTYPE_HYPERBUS)) + { + /* Wait till busy flag is reset */ + status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, hxspi->Timeout); + + if (status == HAL_OK) + { + /* Initialize error code */ + hxspi->ErrorCode = HAL_XSPI_ERROR_NONE; + + /* Clear flags related to interrupt */ + HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TE | HAL_XSPI_FLAG_TC); + + /* Configure the registers */ + status = XSPI_ConfigCmd(hxspi, pCmd); + + if (status == HAL_OK) + { + /* Update the state */ + hxspi->State = HAL_XSPI_STATE_BUSY_CMD; + + /* Enable the transfer complete and transfer error interrupts */ + HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TC | HAL_XSPI_IT_TE); + } + } + } + else + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE; + } + + return status; +} + +/** + * @brief Configure the Hyperbus parameters. + * @param hxspi : XSPI handle + * @param pCfg : Pointer to Structure containing the Hyperbus configuration + * @param Timeout : Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_XSPI_HyperbusCfg(XSPI_HandleTypeDef *hxspi, XSPI_HyperbusCfgTypeDef *const pCfg, + uint32_t Timeout) +{ + HAL_StatusTypeDef status; + uint32_t state; + uint32_t tickstart = HAL_GetTick(); + + /* Check the parameters of the hyperbus configuration structure */ + assert_param(IS_XSPI_RW_RECOVERY_TIME_CYCLE(pCfg->RWRecoveryTimeCycle)); + assert_param(IS_XSPI_ACCESS_TIME_CYCLE(pCfg->AccessTimeCycle)); + assert_param(IS_XSPI_WRITE_ZERO_LATENCY(pCfg->WriteZeroLatency)); + assert_param(IS_XSPI_LATENCY_MODE(pCfg->LatencyMode)); + + /* Check the state of the driver */ + state = hxspi->State; + if ((state == HAL_XSPI_STATE_HYPERBUS_INIT) || (state == HAL_XSPI_STATE_READY)) + { + /* Wait till busy flag is reset */ + status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, Timeout); + + if (status == HAL_OK) + { + /* Configure Hyperbus configuration Latency register */ + WRITE_REG(hxspi->Instance->HLCR, ((pCfg->RWRecoveryTimeCycle << XSPI_HLCR_TRWR_Pos) | + (pCfg->AccessTimeCycle << XSPI_HLCR_TACC_Pos) | + pCfg->WriteZeroLatency | pCfg->LatencyMode)); + + /* Update the state */ + hxspi->State = HAL_XSPI_STATE_READY; + } + else + { + status = HAL_BUSY; + } + } + else + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE; + } + + return status; +} + +/** + * @brief Set the Hyperbus command configuration. + * @param hxspi : XSPI handle + * @param pCmd : Structure containing the Hyperbus command + * @param Timeout : Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_XSPI_HyperbusCmd(XSPI_HandleTypeDef *hxspi, XSPI_HyperbusCmdTypeDef *const pCmd, + uint32_t Timeout) +{ + HAL_StatusTypeDef status; + uint32_t tickstart = HAL_GetTick(); + + /* Check the parameters of the hyperbus command structure */ + assert_param(IS_XSPI_ADDRESS_SPACE(pCmd->AddressSpace)); + assert_param(IS_XSPI_ADDRESS_WIDTH(pCmd->AddressWidth)); + assert_param(IS_XSPI_DATA_LENGTH(pCmd->DataLength)); + assert_param(IS_XSPI_DQS_MODE(pCmd->DQSMode)); + + /* Check the state of the driver */ + if ((hxspi->State == HAL_XSPI_STATE_READY) && (hxspi->Init.MemoryType == HAL_XSPI_MEMTYPE_HYPERBUS)) + { + /* Wait till busy flag is reset */ + status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, Timeout); + + if (status == HAL_OK) + { + /* Re-initialize the value of the functional mode */ + MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FMODE, 0U); + + /* Configure the address space in the DCR1 register */ + MODIFY_REG(hxspi->Instance->DCR1, XSPI_DCR1_MTYP_0, pCmd->AddressSpace); + + /* Configure the CCR and WCCR registers with the address size and the following configuration : + - DQS signal enabled (used as RWDS) + - DTR mode enabled on address and data */ + /* - address and data on 8 lines */ + WRITE_REG(hxspi->Instance->CCR, (pCmd->DQSMode | XSPI_CCR_DDTR | XSPI_CCR_DMODE_2 | + pCmd->AddressWidth | XSPI_CCR_ADDTR | XSPI_CCR_ADMODE_2)); + WRITE_REG(hxspi->Instance->WCCR, (pCmd->DQSMode | XSPI_WCCR_DDTR | XSPI_WCCR_DMODE_2 | + pCmd->AddressWidth | XSPI_WCCR_ADDTR | XSPI_WCCR_ADMODE_2)); + + /* Configure the DLR register with the number of data */ + WRITE_REG(hxspi->Instance->DLR, (pCmd->DataLength - 1U)); + + /* Configure the AR register with the address value */ + WRITE_REG(hxspi->Instance->AR, pCmd->Address); + + /* Update the state */ + hxspi->State = HAL_XSPI_STATE_CMD_CFG; + } + else + { + status = HAL_BUSY; + } + } + else + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE; + } + + return status; +} + +/** + * @brief Transmit an amount of data in blocking mode. + * @param hxspi : XSPI handle + * @param pData : pointer to data buffer + * @param Timeout : Timeout duration + * @note This function is used only in Indirect Write Mode + * @retval HAL status + */ +HAL_StatusTypeDef HAL_XSPI_Transmit(XSPI_HandleTypeDef *hxspi, uint8_t *const pData, uint32_t Timeout) +{ + HAL_StatusTypeDef status; + uint32_t tickstart = HAL_GetTick(); + __IO uint32_t *data_reg = &hxspi->Instance->DR; + + /* Check the data pointer allocation */ + if (pData == NULL) + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM; + } + else + { + /* Check the state */ + if (hxspi->State == HAL_XSPI_STATE_CMD_CFG) + { + /* Configure counters and size */ + hxspi->XferCount = READ_REG(hxspi->Instance->DLR) + 1U; + hxspi->XferSize = hxspi->XferCount; + hxspi->pBuffPtr = pData; + + /* Configure CR register with functional mode as indirect write */ + MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FMODE, XSPI_FUNCTIONAL_MODE_INDIRECT_WRITE); + + do + { + /* Wait till fifo threshold flag is set to send data */ + status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_FT, SET, tickstart, Timeout); + + if (status != HAL_OK) + { + break; + } + + *((__IO uint8_t *)data_reg) = *hxspi->pBuffPtr; + hxspi->pBuffPtr++; + hxspi->XferCount--; + } while (hxspi->XferCount > 0U); + + if (status == HAL_OK) + { + /* Wait till transfer complete flag is set to go back in idle state */ + status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_TC, SET, tickstart, Timeout); + + if (status == HAL_OK) + { + /* Clear transfer complete flag */ + HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TC); + + hxspi->State = HAL_XSPI_STATE_READY; + } + } + } + else + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE; + } + } + + return status; +} + +/** + * @brief Receive an amount of data in blocking mode. + * @param hxspi : XSPI handle + * @param pData : pointer to data buffer + * @param Timeout : Timeout duration + * @note This function is used only in Indirect Read Mode + * @retval HAL status + */ +HAL_StatusTypeDef HAL_XSPI_Receive(XSPI_HandleTypeDef *hxspi, uint8_t *const pData, uint32_t Timeout) +{ + HAL_StatusTypeDef status; + uint32_t tickstart = HAL_GetTick(); + __IO uint32_t *data_reg = &hxspi->Instance->DR; + uint32_t addr_reg = hxspi->Instance->AR; + uint32_t ir_reg = hxspi->Instance->IR; + + /* Check the data pointer allocation */ + if (pData == NULL) + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM; + } + else + { + /* Check the state */ + if (hxspi->State == HAL_XSPI_STATE_CMD_CFG) + { + /* Configure counters and size */ + hxspi->XferCount = READ_REG(hxspi->Instance->DLR) + 1U; + hxspi->XferSize = hxspi->XferCount; + hxspi->pBuffPtr = pData; + + /* Configure CR register with functional mode as indirect read */ + MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FMODE, XSPI_FUNCTIONAL_MODE_INDIRECT_READ); + + /* Trig the transfer by re-writing address or instruction register */ + if (hxspi->Init.MemoryType == HAL_XSPI_MEMTYPE_HYPERBUS) + { + WRITE_REG(hxspi->Instance->AR, addr_reg); + } + else + { + if (READ_BIT(hxspi->Instance->CCR, XSPI_CCR_ADMODE) != HAL_XSPI_ADDRESS_NONE) + { + WRITE_REG(hxspi->Instance->AR, addr_reg); + } + else + { + WRITE_REG(hxspi->Instance->IR, ir_reg); + } + } + + do + { + /* Wait till fifo threshold or transfer complete flags are set to read received data */ + status = XSPI_WaitFlagStateUntilTimeout(hxspi, (HAL_XSPI_FLAG_FT | HAL_XSPI_FLAG_TC), SET, tickstart, Timeout); + + if (status != HAL_OK) + { + break; + } + + *hxspi->pBuffPtr = *((__IO uint8_t *)data_reg); + hxspi->pBuffPtr++; + hxspi->XferCount--; + } while (hxspi->XferCount > 0U); + + if (status == HAL_OK) + { + /* Wait till transfer complete flag is set to go back in idle state */ + status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_TC, SET, tickstart, Timeout); + + if (status == HAL_OK) + { + /* Clear transfer complete flag */ + HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TC); + + hxspi->State = HAL_XSPI_STATE_READY; + } + } + } + else + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE; + } + } + + return status; +} + +/** + * @brief Send an amount of data in non-blocking mode with interrupt. + * @param hxspi : XSPI handle + * @param pData : pointer to data buffer + * @note This function is used only in Indirect Write Mode + * @retval HAL status + */ +HAL_StatusTypeDef HAL_XSPI_Transmit_IT(XSPI_HandleTypeDef *hxspi, uint8_t *const pData) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the data pointer allocation */ + if (pData == NULL) + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM; + } + else + { + /* Check the state */ + if (hxspi->State == HAL_XSPI_STATE_CMD_CFG) + { + /* Configure counters and size */ + hxspi->XferCount = READ_REG(hxspi->Instance->DLR) + 1U; + hxspi->XferSize = hxspi->XferCount; + hxspi->pBuffPtr = pData; + + /* Configure CR register with functional mode as indirect write */ + MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FMODE, XSPI_FUNCTIONAL_MODE_INDIRECT_WRITE); + + /* Clear flags related to interrupt */ + HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TE | HAL_XSPI_FLAG_TC); + + /* Update the state */ + hxspi->State = HAL_XSPI_STATE_BUSY_TX; + + /* Enable the transfer complete, fifo threshold and transfer error interrupts */ + HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TC | HAL_XSPI_IT_FT | HAL_XSPI_IT_TE); + } + else + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE; + } + } + + return status; +} + +/** + * @brief Receive an amount of data in non-blocking mode with interrupt. + * @param hxspi : XSPI handle + * @param pData : pointer to data buffer + * @note This function is used only in Indirect Read Mode + * @retval HAL status + */ +HAL_StatusTypeDef HAL_XSPI_Receive_IT(XSPI_HandleTypeDef *hxspi, uint8_t *const pData) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t addr_reg = hxspi->Instance->AR; + uint32_t ir_reg = hxspi->Instance->IR; + + /* Check the data pointer allocation */ + if (pData == NULL) + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM; + } + else + { + /* Check the state */ + if (hxspi->State == HAL_XSPI_STATE_CMD_CFG) + { + /* Configure counters and size */ + hxspi->XferCount = READ_REG(hxspi->Instance->DLR) + 1U; + hxspi->XferSize = hxspi->XferCount; + hxspi->pBuffPtr = pData; + + /* Configure CR register with functional mode as indirect read */ + MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FMODE, XSPI_FUNCTIONAL_MODE_INDIRECT_READ); + + /* Clear flags related to interrupt */ + HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TE | HAL_XSPI_FLAG_TC); + + /* Update the state */ + hxspi->State = HAL_XSPI_STATE_BUSY_RX; + + /* Enable the transfer complete, fifo threshold and transfer error interrupts */ + HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TC | HAL_XSPI_IT_FT | HAL_XSPI_IT_TE); + + /* Trig the transfer by re-writing address or instruction register */ + if (hxspi->Init.MemoryType == HAL_XSPI_MEMTYPE_HYPERBUS) + { + WRITE_REG(hxspi->Instance->AR, addr_reg); + } + else + { + if (READ_BIT(hxspi->Instance->CCR, XSPI_CCR_ADMODE) != HAL_XSPI_ADDRESS_NONE) + { + WRITE_REG(hxspi->Instance->AR, addr_reg); + } + else + { + WRITE_REG(hxspi->Instance->IR, ir_reg); + } + } + } + else + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE; + } + } + + return status; +} + +/** + * @brief Send an amount of data in non-blocking mode with DMA. + * @param hxspi : XSPI handle + * @param pData : pointer to data buffer + * @note This function is used only in Indirect Write Mode + * @note If DMA peripheral access is configured as halfword, the number + * of data and the fifo threshold should be aligned on halfword + * @note If DMA peripheral access is configured as word, the number + * of data and the fifo threshold should be aligned on word + * @retval HAL status + */ +HAL_StatusTypeDef HAL_XSPI_Transmit_DMA(XSPI_HandleTypeDef *hxspi, uint8_t *const pData) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t data_size = hxspi->Instance->DLR + 1U; + DMA_QListTypeDef *p_queue = {NULL}; + uint32_t data_width = DMA_DEST_DATAWIDTH_BYTE; + + /* Check the data pointer allocation */ + if (pData == NULL) + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM; + } + else + { + /* Check the state */ + if (hxspi->State == HAL_XSPI_STATE_CMD_CFG) + { + if ((hxspi->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + p_queue = hxspi->hdmatx->LinkedListQueue; + if ((p_queue != NULL) && (p_queue->Head != NULL)) + { + data_width = p_queue->Head->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] & DMA_CTR1_DDW_LOG2; + } + else + { + /* Set Error Code function status */ + hxspi->ErrorCode = HAL_XSPI_ERROR_DMA; + + /* Return function status */ + status = HAL_ERROR; + } + } + else + { + data_width = hxspi->hdmatx->Init.DestDataWidth; + } + /* Configure counters and size */ + if (data_width == DMA_DEST_DATAWIDTH_BYTE) + { + hxspi->XferCount = data_size; + } + else if (data_width == DMA_DEST_DATAWIDTH_HALFWORD) + { + if (((data_size % 2U) != 0U) || ((hxspi->Init.FifoThresholdByte % 2U) != 0U)) + { + /* The number of data or the fifo threshold is not aligned on halfword + => no transfer possible with DMA peripheral access configured as halfword */ + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + else + { + hxspi->XferCount = data_size; + } + } + else if (data_width == DMA_DEST_DATAWIDTH_WORD) + { + if (((data_size % 4U) != 0U) || ((hxspi->Init.FifoThresholdByte % 4U) != 0U)) + { + /* The number of data or the fifo threshold is not aligned on word + => no transfer possible with DMA peripheral access configured as word */ + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + else + { + hxspi->XferCount = data_size; + } + } + else + { + /* Nothing to do */ + } + + if (status == HAL_OK) + { + hxspi->XferSize = hxspi->XferCount; + hxspi->pBuffPtr = pData; + + /* Configure CR register with functional mode as indirect write */ + MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FMODE, XSPI_FUNCTIONAL_MODE_INDIRECT_WRITE); + + /* Clear flags related to interrupt */ + HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TE | HAL_XSPI_FLAG_TC); + + /* Update the state */ + hxspi->State = HAL_XSPI_STATE_BUSY_TX; + + /* Set the DMA transfer complete callback */ + hxspi->hdmatx->XferCpltCallback = XSPI_DMACplt; + + /* Set the DMA Half transfer complete callback */ + hxspi->hdmatx->XferHalfCpltCallback = XSPI_DMAHalfCplt; + + /* Set the DMA error callback */ + hxspi->hdmatx->XferErrorCallback = XSPI_DMAError; + + /* Clear the DMA abort callback */ + hxspi->hdmatx->XferAbortCallback = NULL; + + /* Enable the transmit DMA Channel */ + if ((hxspi->hdmatx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hxspi->hdmatx->LinkedListQueue != NULL) + { + /* Enable the DMA channel */ + MODIFY_REG(p_queue->Head->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET], \ + (DMA_CTR1_SINC | DMA_CTR1_DINC), (DMA_SINC_INCREMENTED | DMA_DINC_FIXED)); + MODIFY_REG(p_queue->Head->LinkRegisters[NODE_CTR2_DEFAULT_OFFSET], \ + DMA_CTR2_DREQ, DMA_MEMORY_TO_PERIPH); + /* Set DMA data size*/ + p_queue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hxspi->XferSize; + /* Set DMA source address */ + p_queue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)pData; + /* Set DMA destination address */ + p_queue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)&hxspi->Instance->DR; + + status = HAL_DMAEx_List_Start_IT(hxspi->hdmatx); + } + else + { + /* Set Error Code */ + hxspi->ErrorCode = HAL_XSPI_ERROR_DMA; + + hxspi->State = HAL_XSPI_STATE_READY; + + /* Return function status */ + status = HAL_ERROR; + } + } + else + { + if ((hxspi->hdmatx->Init.Direction == DMA_MEMORY_TO_PERIPH) && + (hxspi->hdmatx->Init.SrcInc == DMA_SINC_INCREMENTED) && (hxspi->hdmatx->Init.DestInc == DMA_DINC_FIXED)) + { + status = HAL_DMA_Start_IT(hxspi->hdmatx, (uint32_t)pData, (uint32_t)&hxspi->Instance->DR, hxspi->XferSize); + } + else + { + /* no transmit possible with DMA peripheral, invalid configuration */ + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + } + if (status == HAL_OK) + { + /* Enable the transfer error interrupt */ + HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TE); + + /* Enable the DMA transfer by setting the DMAEN bit */ + SET_BIT(hxspi->Instance->CR, XSPI_CR_DMAEN); + } + else + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_DMA; + hxspi->State = HAL_XSPI_STATE_READY; + } + } + } + else + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE; + } + } + + return status; +} + +/** + * @brief Receive an amount of data in non-blocking mode with DMA. + * @param hxspi : XSPI handle + * @param pData : pointer to data buffer. + * @note This function is used only in Indirect Read Mode + * @note If DMA peripheral access is configured as halfword, the number + * of data and the fifo threshold should be aligned on halfword + * @note If DMA peripheral access is configured as word, the number + * of data and the fifo threshold should be aligned on word + * @retval HAL status + */ +HAL_StatusTypeDef HAL_XSPI_Receive_DMA(XSPI_HandleTypeDef *hxspi, uint8_t *const pData) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t data_size = hxspi->Instance->DLR + 1U; + uint32_t addr_reg = hxspi->Instance->AR; + uint32_t ir_reg = hxspi->Instance->IR; + DMA_QListTypeDef *p_queue = {NULL}; + uint32_t data_width = DMA_DEST_DATAWIDTH_BYTE; + + /* Check the data pointer allocation */ + if (pData == NULL) + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM; + } + else + { + /* Check the state */ + if (hxspi->State == HAL_XSPI_STATE_CMD_CFG) + { + if ((hxspi->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + p_queue = hxspi->hdmarx->LinkedListQueue; + if ((p_queue != NULL) && (p_queue->Head != NULL)) + { + data_width = p_queue->Head->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] & DMA_CTR1_DDW_LOG2; + } + else + { + /* Set Error Code */ + hxspi->ErrorCode = HAL_XSPI_ERROR_DMA; + + /* Return function status */ + status = HAL_ERROR; + } + } + else + { + data_width = hxspi->hdmarx->Init.DestDataWidth; + } + + /* Configure counters and size */ + if (data_width == DMA_DEST_DATAWIDTH_BYTE) + { + hxspi->XferCount = data_size; + } + else if (data_width == DMA_DEST_DATAWIDTH_HALFWORD) + { + if (((data_size % 2U) != 0U) || ((hxspi->Init.FifoThresholdByte % 2U) != 0U)) + { + /* The number of data or the fifo threshold is not aligned on halfword + => no transfer possible with DMA peripheral access configured as halfword */ + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + else + { + hxspi->XferCount = data_size; + } + } + else if (data_width == DMA_DEST_DATAWIDTH_WORD) + { + if (((data_size % 4U) != 0U) || ((hxspi->Init.FifoThresholdByte % 4U) != 0U)) + { + /* The number of data or the fifo threshold is not aligned on word + => no transfer possible with DMA peripheral access configured as word */ + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + else + { + hxspi->XferCount = data_size; + } + } + else + { + /* Nothing to do */ + } + + if (status == HAL_OK) + { + hxspi->XferSize = hxspi->XferCount; + hxspi->pBuffPtr = pData; + + /* Configure CR register with functional mode as indirect read */ + MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FMODE, XSPI_FUNCTIONAL_MODE_INDIRECT_READ); + + /* Clear flags related to interrupt */ + HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TE | HAL_XSPI_FLAG_TC); + + /* Update the state */ + hxspi->State = HAL_XSPI_STATE_BUSY_RX; + + /* Set the DMA transfer complete callback */ + hxspi->hdmarx->XferCpltCallback = XSPI_DMACplt; + + /* Set the DMA Half transfer complete callback */ + hxspi->hdmarx->XferHalfCpltCallback = XSPI_DMAHalfCplt; + + /* Set the DMA error callback */ + hxspi->hdmarx->XferErrorCallback = XSPI_DMAError; + + /* Clear the DMA abort callback */ + hxspi->hdmarx->XferAbortCallback = NULL; + + /* Enable the receive DMA Channel */ + if ((hxspi->hdmarx->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST) + { + if (hxspi->hdmarx->LinkedListQueue != NULL) + { + /* Enable the DMA channel */ + MODIFY_REG(p_queue->Head->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET], \ + (DMA_CTR1_SINC | DMA_CTR1_DINC), (DMA_SINC_FIXED | DMA_DINC_INCREMENTED)); + MODIFY_REG(p_queue->Head->LinkRegisters[NODE_CTR2_DEFAULT_OFFSET], \ + DMA_CTR2_DREQ, DMA_PERIPH_TO_MEMORY); + /* Set DMA data size */ + p_queue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hxspi->XferSize; + /* Set DMA source address */ + p_queue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)&hxspi->Instance->DR; + /* Set DMA destination address */ + p_queue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)pData; + + status = HAL_DMAEx_List_Start_IT(hxspi->hdmarx); + } + else + { + /* Set Error Code */ + hxspi->ErrorCode = HAL_XSPI_ERROR_DMA; + + hxspi->State = HAL_XSPI_STATE_READY; + + /* Return function status */ + status = HAL_ERROR; + } + } + else + { + if ((hxspi->hdmarx->Init.Direction == DMA_PERIPH_TO_MEMORY) && (hxspi->hdmarx->Init.SrcInc == DMA_SINC_FIXED) + && (hxspi->hdmarx->Init.DestInc == DMA_DINC_INCREMENTED)) + { + status = HAL_DMA_Start_IT(hxspi->hdmarx, (uint32_t)&hxspi->Instance->DR, (uint32_t)pData, hxspi->XferSize); + } + else + { + /* no receive possible with DMA peripheral, invalid configuration */ + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM; + status = HAL_ERROR; + } + } + if (status == HAL_OK) + { + /* Enable the transfer error interrupt */ + HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TE); + + /* Trig the transfer by re-writing address or instruction register */ + if (hxspi->Init.MemoryType == HAL_XSPI_MEMTYPE_HYPERBUS) + { + WRITE_REG(hxspi->Instance->AR, addr_reg); + } + else + { + if (READ_BIT(hxspi->Instance->CCR, XSPI_CCR_ADMODE) != HAL_XSPI_ADDRESS_NONE) + { + WRITE_REG(hxspi->Instance->AR, addr_reg); + } + else + { + WRITE_REG(hxspi->Instance->IR, ir_reg); + } + } + + /* Enable the DMA transfer by setting the DMAEN bit */ + SET_BIT(hxspi->Instance->CR, XSPI_CR_DMAEN); + } + else + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_DMA; + hxspi->State = HAL_XSPI_STATE_READY; + } + } + } + else + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE; + } + } + + return status; +} + +/** + * @brief Configure the XSPI Automatic Polling Mode in blocking mode. + * @param hxspi : XSPI handle + * @param pCfg : Pointer to structure that contains the polling configuration information. + * @param Timeout : Timeout duration + * @note This function is used only in Automatic Polling Mode + * @retval HAL status + */ +HAL_StatusTypeDef HAL_XSPI_AutoPolling(XSPI_HandleTypeDef *hxspi, XSPI_AutoPollingTypeDef *const pCfg, + uint32_t Timeout) +{ + HAL_StatusTypeDef status; + uint32_t tickstart = HAL_GetTick(); + uint32_t addr_reg = hxspi->Instance->AR; + uint32_t ir_reg = hxspi->Instance->IR; +#ifdef USE_FULL_ASSERT + uint32_t dlr_reg = hxspi->Instance->DLR; +#endif /* USE_FULL_ASSERT */ + + /* Check the parameters of the autopolling configuration structure */ + assert_param(IS_XSPI_MATCH_MODE(pCfg->MatchMode)); + assert_param(IS_XSPI_AUTOMATIC_STOP(pCfg->AutomaticStop)); + assert_param(IS_XSPI_INTERVAL(pCfg->IntervalTime)); + assert_param(IS_XSPI_STATUS_BYTES_SIZE(dlr_reg + 1U)); + + /* Check the state */ + if ((hxspi->State == HAL_XSPI_STATE_CMD_CFG) && (pCfg->AutomaticStop == HAL_XSPI_AUTOMATIC_STOP_ENABLE)) + { + /* Wait till busy flag is reset */ + status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, Timeout); + + if (status == HAL_OK) + { + /* Configure registers */ + WRITE_REG(hxspi->Instance->PSMAR, pCfg->MatchValue); + WRITE_REG(hxspi->Instance->PSMKR, pCfg->MatchMask); + WRITE_REG(hxspi->Instance->PIR, pCfg->IntervalTime); + MODIFY_REG(hxspi->Instance->CR, (XSPI_CR_PMM | XSPI_CR_APMS | XSPI_CR_FMODE), + (pCfg->MatchMode | pCfg->AutomaticStop | XSPI_FUNCTIONAL_MODE_AUTO_POLLING)); + + /* Trig the transfer by re-writing address or instruction register */ + if (hxspi->Init.MemoryType == HAL_XSPI_MEMTYPE_HYPERBUS) + { + WRITE_REG(hxspi->Instance->AR, addr_reg); + } + else + { + if (READ_BIT(hxspi->Instance->CCR, XSPI_CCR_ADMODE) != HAL_XSPI_ADDRESS_NONE) + { + WRITE_REG(hxspi->Instance->AR, addr_reg); + } + else + { + WRITE_REG(hxspi->Instance->IR, ir_reg); + } + } + + /* Wait till status match flag is set to go back in idle state */ + status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_SM, SET, tickstart, Timeout); + + if (status == HAL_OK) + { + /* Clear status match flag */ + HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_SM); + + hxspi->State = HAL_XSPI_STATE_READY; + } + } + else + { + status = HAL_BUSY; + } + } + else + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE; + } + + return status; +} + +/** + * @brief Configure the XSPI Automatic Polling Mode in non-blocking mode. + * @param hxspi : XSPI handle + * @param pCfg : Pointer to structure that contains the polling configuration information. + * @note This function is used only in Automatic Polling Mode + * @retval HAL status + */ +HAL_StatusTypeDef HAL_XSPI_AutoPolling_IT(XSPI_HandleTypeDef *hxspi, XSPI_AutoPollingTypeDef *const pCfg) +{ + HAL_StatusTypeDef status; + uint32_t tickstart = HAL_GetTick(); + uint32_t addr_reg = hxspi->Instance->AR; + uint32_t ir_reg = hxspi->Instance->IR; +#ifdef USE_FULL_ASSERT + uint32_t dlr_reg = hxspi->Instance->DLR; +#endif /* USE_FULL_ASSERT */ + + /* Check the parameters of the autopolling configuration structure */ + assert_param(IS_XSPI_MATCH_MODE(pCfg->MatchMode)); + assert_param(IS_XSPI_AUTOMATIC_STOP(pCfg->AutomaticStop)); + assert_param(IS_XSPI_INTERVAL(pCfg->IntervalTime)); + assert_param(IS_XSPI_STATUS_BYTES_SIZE(dlr_reg + 1U)); + + /* Check the state */ + if (hxspi->State == HAL_XSPI_STATE_CMD_CFG) + { + /* Wait till busy flag is reset */ + status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, hxspi->Timeout); + + if (status == HAL_OK) + { + /* Configure registers */ + WRITE_REG(hxspi->Instance->PSMAR, pCfg->MatchValue); + WRITE_REG(hxspi->Instance->PSMKR, pCfg->MatchMask); + WRITE_REG(hxspi->Instance->PIR, pCfg->IntervalTime); + MODIFY_REG(hxspi->Instance->CR, (XSPI_CR_PMM | XSPI_CR_APMS | XSPI_CR_FMODE), + (pCfg->MatchMode | pCfg->AutomaticStop | XSPI_FUNCTIONAL_MODE_AUTO_POLLING)); + + /* Clear flags related to interrupt */ + HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TE | HAL_XSPI_FLAG_SM); + + hxspi->State = HAL_XSPI_STATE_BUSY_AUTO_POLLING; + + /* Enable the status match and transfer error interrupts */ + HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_SM | HAL_XSPI_IT_TE); + + /* Trig the transfer by re-writing address or instruction register */ + if (hxspi->Init.MemoryType == HAL_XSPI_MEMTYPE_HYPERBUS) + { + WRITE_REG(hxspi->Instance->AR, addr_reg); + } + else + { + if (READ_BIT(hxspi->Instance->CCR, XSPI_CCR_ADMODE) != HAL_XSPI_ADDRESS_NONE) + { + WRITE_REG(hxspi->Instance->AR, addr_reg); + } + else + { + WRITE_REG(hxspi->Instance->IR, ir_reg); + } + } + } + } + else + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE; + } + + return status; +} + +/** + * @brief Configure the Memory Mapped mode. + * @param hxspi : XSPI handle + * @param pCfg : Pointer to structure that contains the memory mapped configuration information. + * @note This function is used only in Memory mapped Mode + * @retval HAL status + */ +HAL_StatusTypeDef HAL_XSPI_MemoryMapped(XSPI_HandleTypeDef *hxspi, XSPI_MemoryMappedTypeDef *const pCfg) +{ + HAL_StatusTypeDef status; + uint32_t tickstart = HAL_GetTick(); + + /* Check the parameters of the memory-mapped configuration structure */ + assert_param(IS_XSPI_TIMEOUT_ACTIVATION(pCfg->TimeOutActivation)); + + /* Check the state */ + if (hxspi->State == HAL_XSPI_STATE_CMD_CFG) + { + /* Wait till busy flag is reset */ + status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, hxspi->Timeout); + + if (status == HAL_OK) + { + hxspi->State = HAL_XSPI_STATE_BUSY_MEM_MAPPED; + + if (pCfg->TimeOutActivation == HAL_XSPI_TIMEOUT_COUNTER_ENABLE) + { + assert_param(IS_XSPI_TIMEOUT_PERIOD(pCfg->TimeoutPeriodClock)); + + /* Configure register */ + WRITE_REG(hxspi->Instance->LPTR, pCfg->TimeoutPeriodClock); + + /* Clear flags related to interrupt */ + HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TO); + + /* Enable the timeout interrupt */ + HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TO); + } + + /* Configure CR register with functional mode as memory-mapped */ + MODIFY_REG(hxspi->Instance->CR, (XSPI_CR_TCEN | XSPI_CR_FMODE), + (pCfg->TimeOutActivation | XSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)); + } + } + else + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE; + } + + return status; +} + +/** + * @brief Transfer Error callback. + * @param hxspi : XSPI handle + * @retval None + */ +__weak void HAL_XSPI_ErrorCallback(XSPI_HandleTypeDef *hxspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hxspi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_XSPI_ErrorCallback could be implemented in the user file + */ +} + +/** + * @brief Abort completed callback. + * @param hxspi : XSPI handle + * @retval None + */ +__weak void HAL_XSPI_AbortCpltCallback(XSPI_HandleTypeDef *hxspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hxspi); + + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_XSPI_AbortCpltCallback could be implemented in the user file + */ +} + +/** + * @brief FIFO Threshold callback. + * @param hxspi : XSPI handle + * @retval None + */ +__weak void HAL_XSPI_FifoThresholdCallback(XSPI_HandleTypeDef *hxspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hxspi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_XSPI_FIFOThresholdCallback could be implemented in the user file + */ +} + +/** + * @brief Command completed callback. + * @param hxspi : XSPI handle + * @retval None + */ +__weak void HAL_XSPI_CmdCpltCallback(XSPI_HandleTypeDef *hxspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hxspi); + + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_XSPI_CmdCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Transfer completed callback. + * @param hxspi : XSPI handle + * @retval None + */ +__weak void HAL_XSPI_RxCpltCallback(XSPI_HandleTypeDef *hxspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hxspi); + + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_XSPI_RxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Tx Transfer completed callback. + * @param hxspi : XSPI handle + * @retval None + */ +__weak void HAL_XSPI_TxCpltCallback(XSPI_HandleTypeDef *hxspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hxspi); + + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_XSPI_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Half Transfer completed callback. + * @param hxspi : XSPI handle + * @retval None + */ +__weak void HAL_XSPI_RxHalfCpltCallback(XSPI_HandleTypeDef *hxspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hxspi); + + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_XSPI_RxHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Tx Half Transfer completed callback. + * @param hxspi : XSPI handle + * @retval None + */ +__weak void HAL_XSPI_TxHalfCpltCallback(XSPI_HandleTypeDef *hxspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hxspi); + + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_XSPI_TxHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Status Match callback. + * @param hxspi : XSPI handle + * @retval None + */ +__weak void HAL_XSPI_StatusMatchCallback(XSPI_HandleTypeDef *hxspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hxspi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_XSPI_StatusMatchCallback could be implemented in the user file + */ +} + +/** + * @brief Timeout callback. + * @param hxspi : XSPI handle + * @retval None + */ +__weak void HAL_XSPI_TimeOutCallback(XSPI_HandleTypeDef *hxspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hxspi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_XSPI_TimeOutCallback could be implemented in the user file + */ +} + +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) +/** + * @brief Register a User XSPI Callback + * To be used to override the weak predefined callback + * @param hxspi : XSPI handle + * @param CallbackID : ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_XSPI_ERROR_CB_ID XSPI Error Callback ID + * @arg @ref HAL_XSPI_ABORT_CB_ID XSPI Abort Callback ID + * @arg @ref HAL_XSPI_FIFO_THRESHOLD_CB_ID XSPI FIFO Threshold Callback ID + * @arg @ref HAL_XSPI_CMD_CPLT_CB_ID XSPI Command Complete Callback ID + * @arg @ref HAL_XSPI_RX_CPLT_CB_ID XSPI Rx Complete Callback ID + * @arg @ref HAL_XSPI_TX_CPLT_CB_ID XSPI Tx Complete Callback ID + * @arg @ref HAL_XSPI_RX_HALF_CPLT_CB_ID XSPI Rx Half Complete Callback ID + * @arg @ref HAL_XSPI_TX_HALF_CPLT_CB_ID XSPI Tx Half Complete Callback ID + * @arg @ref HAL_XSPI_STATUS_MATCH_CB_ID XSPI Status Match Callback ID + * @arg @ref HAL_XSPI_TIMEOUT_CB_ID XSPI Timeout Callback ID + * @arg @ref HAL_XSPI_MSP_INIT_CB_ID XSPI MspInit callback ID + * @arg @ref HAL_XSPI_MSP_DEINIT_CB_ID XSPI MspDeInit callback ID + * @param pCallback : pointer to the Callback function + * @retval status + */ +HAL_StatusTypeDef HAL_XSPI_RegisterCallback(XSPI_HandleTypeDef *hxspi, HAL_XSPI_CallbackIDTypeDef CallbackID, + pXSPI_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + + if (hxspi->State == HAL_XSPI_STATE_READY) + { + switch (CallbackID) + { + case HAL_XSPI_ERROR_CB_ID : + hxspi->ErrorCallback = pCallback; + break; + case HAL_XSPI_ABORT_CB_ID : + hxspi->AbortCpltCallback = pCallback; + break; + case HAL_XSPI_FIFO_THRESHOLD_CB_ID : + hxspi->FifoThresholdCallback = pCallback; + break; + case HAL_XSPI_CMD_CPLT_CB_ID : + hxspi->CmdCpltCallback = pCallback; + break; + case HAL_XSPI_RX_CPLT_CB_ID : + hxspi->RxCpltCallback = pCallback; + break; + case HAL_XSPI_TX_CPLT_CB_ID : + hxspi->TxCpltCallback = pCallback; + break; + case HAL_XSPI_RX_HALF_CPLT_CB_ID : + hxspi->RxHalfCpltCallback = pCallback; + break; + case HAL_XSPI_TX_HALF_CPLT_CB_ID : + hxspi->TxHalfCpltCallback = pCallback; + break; + case HAL_XSPI_STATUS_MATCH_CB_ID : + hxspi->StatusMatchCallback = pCallback; + break; + case HAL_XSPI_TIMEOUT_CB_ID : + hxspi->TimeOutCallback = pCallback; + break; + case HAL_XSPI_MSP_INIT_CB_ID : + hxspi->MspInitCallback = pCallback; + break; + case HAL_XSPI_MSP_DEINIT_CB_ID : + hxspi->MspDeInitCallback = pCallback; + break; + default : + /* Update the error code */ + hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else if (hxspi->State == HAL_XSPI_STATE_RESET) + { + switch (CallbackID) + { + case HAL_XSPI_MSP_INIT_CB_ID : + hxspi->MspInitCallback = pCallback; + break; + case HAL_XSPI_MSP_DEINIT_CB_ID : + hxspi->MspDeInitCallback = pCallback; + break; + default : + /* Update the error code */ + hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister a User XSPI Callback + * XSPI Callback is redirected to the weak predefined callback + * @param hxspi : XSPI handle + * @param CallbackID : ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_XSPI_ERROR_CB_ID XSPI Error Callback ID + * @arg @ref HAL_XSPI_ABORT_CB_ID XSPI Abort Callback ID + * @arg @ref HAL_XSPI_FIFO_THRESHOLD_CB_ID XSPI FIFO Threshold Callback ID + * @arg @ref HAL_XSPI_CMD_CPLT_CB_ID XSPI Command Complete Callback ID + * @arg @ref HAL_XSPI_RX_CPLT_CB_ID XSPI Rx Complete Callback ID + * @arg @ref HAL_XSPI_TX_CPLT_CB_ID XSPI Tx Complete Callback ID + * @arg @ref HAL_XSPI_RX_HALF_CPLT_CB_ID XSPI Rx Half Complete Callback ID + * @arg @ref HAL_XSPI_TX_HALF_CPLT_CB_ID XSPI Tx Half Complete Callback ID + * @arg @ref HAL_XSPI_STATUS_MATCH_CB_ID XSPI Status Match Callback ID + * @arg @ref HAL_XSPI_TIMEOUT_CB_ID XSPI Timeout Callback ID + * @arg @ref HAL_XSPI_MSP_INIT_CB_ID XSPI MspInit callback ID + * @arg @ref HAL_XSPI_MSP_DEINIT_CB_ID XSPI MspDeInit callback ID + * @retval status + */ +HAL_StatusTypeDef HAL_XSPI_UnRegisterCallback(XSPI_HandleTypeDef *hxspi, HAL_XSPI_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (hxspi->State == HAL_XSPI_STATE_READY) + { + switch (CallbackID) + { + case HAL_XSPI_ERROR_CB_ID : + hxspi->ErrorCallback = HAL_XSPI_ErrorCallback; + break; + case HAL_XSPI_ABORT_CB_ID : + hxspi->AbortCpltCallback = HAL_XSPI_AbortCpltCallback; + break; + case HAL_XSPI_FIFO_THRESHOLD_CB_ID : + hxspi->FifoThresholdCallback = HAL_XSPI_FifoThresholdCallback; + break; + case HAL_XSPI_CMD_CPLT_CB_ID : + hxspi->CmdCpltCallback = HAL_XSPI_CmdCpltCallback; + break; + case HAL_XSPI_RX_CPLT_CB_ID : + hxspi->RxCpltCallback = HAL_XSPI_RxCpltCallback; + break; + case HAL_XSPI_TX_CPLT_CB_ID : + hxspi->TxCpltCallback = HAL_XSPI_TxCpltCallback; + break; + case HAL_XSPI_RX_HALF_CPLT_CB_ID : + hxspi->RxHalfCpltCallback = HAL_XSPI_RxHalfCpltCallback; + break; + case HAL_XSPI_TX_HALF_CPLT_CB_ID : + hxspi->TxHalfCpltCallback = HAL_XSPI_TxHalfCpltCallback; + break; + case HAL_XSPI_STATUS_MATCH_CB_ID : + hxspi->StatusMatchCallback = HAL_XSPI_StatusMatchCallback; + break; + case HAL_XSPI_TIMEOUT_CB_ID : + hxspi->TimeOutCallback = HAL_XSPI_TimeOutCallback; + break; + case HAL_XSPI_MSP_INIT_CB_ID : + hxspi->MspInitCallback = HAL_XSPI_MspInit; + break; + case HAL_XSPI_MSP_DEINIT_CB_ID : + hxspi->MspDeInitCallback = HAL_XSPI_MspDeInit; + break; + default : + /* Update the error code */ + hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else if (hxspi->State == HAL_XSPI_STATE_RESET) + { + switch (CallbackID) + { + case HAL_XSPI_MSP_INIT_CB_ID : + hxspi->MspInitCallback = HAL_XSPI_MspInit; + break; + case HAL_XSPI_MSP_DEINIT_CB_ID : + hxspi->MspDeInitCallback = HAL_XSPI_MspDeInit; + break; + default : + /* Update the error code */ + hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_CALLBACK; + /* update return status */ + status = HAL_ERROR; + } + + return status; +} +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */ + +/** + * @} + */ + +/** @defgroup XSPI_Exported_Functions_Group3 Peripheral Control and State functions + * @brief XSPI control and State functions + * +@verbatim + =============================================================================== + ##### Peripheral Control and State functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to : + (+) Check in run-time the state of the driver. + (+) Check the error code set during last operation. + (+) Abort any operation. + (+) Manage the Fifo threshold. + (+) Configure the timeout duration used in the driver. + +@endverbatim + * @{ + */ + +/** + * @brief Abort the current transmission. + * @param hxspi : XSPI handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_XSPI_Abort(XSPI_HandleTypeDef *hxspi) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t state; + uint32_t tickstart = HAL_GetTick(); + + /* Check if the state is in one of the busy or configured states */ + state = hxspi->State; + if (((state & XSPI_BUSY_STATE_MASK) != 0U) || ((state & XSPI_CFG_STATE_MASK) != 0U)) + { + /* Check if the DMA is enabled */ + if ((hxspi->Instance->CR & XSPI_CR_DMAEN) != 0U) + { + /* Disable the DMA transfer on the XSPI side */ + CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_DMAEN); + + /* Disable the DMA transmit on the DMA side */ + status = HAL_DMA_Abort(hxspi->hdmatx); + if (status != HAL_OK) + { + hxspi->ErrorCode = HAL_XSPI_ERROR_DMA; + } + + /* Disable the DMA receive on the DMA side */ + status = HAL_DMA_Abort(hxspi->hdmarx); + if (status != HAL_OK) + { + hxspi->ErrorCode = HAL_XSPI_ERROR_DMA; + } + } + + if (HAL_XSPI_GET_FLAG(hxspi, HAL_XSPI_FLAG_BUSY) != RESET) + { + /* Perform an abort of the XSPI */ + SET_BIT(hxspi->Instance->CR, XSPI_CR_ABORT); + + /* Wait until the transfer complete flag is set to go back in idle state */ + status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_TC, SET, tickstart, hxspi->Timeout); + + if (status == HAL_OK) + { + /* Clear transfer complete flag */ + HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TC); + + /* Wait until the busy flag is reset to go back in idle state */ + status = XSPI_WaitFlagStateUntilTimeout(hxspi, HAL_XSPI_FLAG_BUSY, RESET, tickstart, hxspi->Timeout); + + if (status == HAL_OK) + { + hxspi->State = HAL_XSPI_STATE_READY; + } + } + } + else + { + hxspi->State = HAL_XSPI_STATE_READY; + } + } + else + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE; + } + + return status; +} + +/** + * @brief Abort the current transmission (non-blocking function) + * @param hxspi : XSPI handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_XSPI_Abort_IT(XSPI_HandleTypeDef *hxspi) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t state; + + /* Check if the state is in one of the busy or configured states */ + state = hxspi->State; + if (((state & XSPI_BUSY_STATE_MASK) != 0U) || ((state & XSPI_CFG_STATE_MASK) != 0U)) + { + /* Disable all interrupts */ + HAL_XSPI_DISABLE_IT(hxspi, (HAL_XSPI_IT_TO | HAL_XSPI_IT_SM | HAL_XSPI_IT_FT | HAL_XSPI_IT_TC | HAL_XSPI_IT_TE)); + + hxspi->State = HAL_XSPI_STATE_ABORT; + + /* Check if the DMA is enabled */ + if ((hxspi->Instance->CR & XSPI_CR_DMAEN) != 0U) + { + /* Disable the DMA transfer on the XSPI side */ + CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_DMAEN); + + /* Disable the DMA transmit on the DMA side */ + hxspi->hdmatx->XferAbortCallback = XSPI_DMAAbortCplt; + if (HAL_DMA_Abort_IT(hxspi->hdmatx) != HAL_OK) + { + hxspi->State = HAL_XSPI_STATE_READY; + + /* Abort callback */ +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) + hxspi->AbortCpltCallback(hxspi); +#else + HAL_XSPI_AbortCpltCallback(hxspi); +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */ + } + + /* Disable the DMA receive on the DMA side */ + hxspi->hdmarx->XferAbortCallback = XSPI_DMAAbortCplt; + if (HAL_DMA_Abort_IT(hxspi->hdmarx) != HAL_OK) + { + hxspi->State = HAL_XSPI_STATE_READY; + + /* Abort callback */ +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) + hxspi->AbortCpltCallback(hxspi); +#else + HAL_XSPI_AbortCpltCallback(hxspi); +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */ + } + } + else + { + if (HAL_XSPI_GET_FLAG(hxspi, HAL_XSPI_FLAG_BUSY) != RESET) + { + /* Clear transfer complete flag */ + HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TC); + + /* Enable the transfer complete interrupts */ + HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TC); + + /* Perform an abort of the XSPI */ + SET_BIT(hxspi->Instance->CR, XSPI_CR_ABORT); + } + else + { + hxspi->State = HAL_XSPI_STATE_READY; + + /* Abort callback */ +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) + hxspi->AbortCpltCallback(hxspi); +#else + HAL_XSPI_AbortCpltCallback(hxspi); +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */ + } + } + } + else + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE; + } + + return status; +} + +/** @brief Set XSPI Fifo threshold. + * @param hxspi : XSPI handle. + * @param Threshold : Threshold of the Fifo. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_XSPI_SetFifoThreshold(XSPI_HandleTypeDef *hxspi, uint32_t Threshold) +{ + HAL_StatusTypeDef status = HAL_OK; + + assert_param(IS_XSPI_FIFO_THRESHOLD_BYTE(Threshold)); + + /* Check the state */ + if ((hxspi->State & XSPI_BUSY_STATE_MASK) == 0U) + { + /* Synchronize initialization structure with the new fifo threshold value */ + hxspi->Init.FifoThresholdByte = Threshold; + + /* Configure new fifo threshold */ + MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FTHRES, ((hxspi->Init.FifoThresholdByte - 1U) << XSPI_CR_FTHRES_Pos)); + + } + else + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE; + } + + return status; +} + +/** @brief Get XSPI Fifo threshold. + * @param hxspi : XSPI handle. + * @retval Fifo threshold + */ +uint32_t HAL_XSPI_GetFifoThreshold(const XSPI_HandleTypeDef *hxspi) +{ + return ((READ_BIT(hxspi->Instance->CR, XSPI_CR_FTHRES) >> XSPI_CR_FTHRES_Pos) + 1U); +} + +/** @brief Set XSPI Memory Type. + * @param hxspi : XSPI handle. + * @param Type : Memory Type. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_XSPI_SetMemoryType(XSPI_HandleTypeDef *hxspi, uint32_t Type) +{ + HAL_StatusTypeDef status = HAL_OK; + + assert_param(IS_XSPI_MEMORY_TYPE(Type)); + + /* Check the state */ + if ((hxspi->State & XSPI_BUSY_STATE_MASK) == 0U) + { + /* Synchronize initialization structure with the new memory type value */ + hxspi->Init.MemoryType = Type; + + /* Configure new memory type */ + MODIFY_REG(hxspi->Instance->DCR1, XSPI_DCR1_MTYP, hxspi->Init.MemoryType); + } + else + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE; + } + + return status; +} + +/** @brief Set XSPI Device Size. + * @param hxspi : XSPI handle. + * @param Size : Device Size. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_XSPI_SetDeviceSize(XSPI_HandleTypeDef *hxspi, uint32_t Size) +{ + HAL_StatusTypeDef status = HAL_OK; + + assert_param(IS_XSPI_MEMORY_SIZE(Size)); + + /* Check the state */ + if ((hxspi->State & XSPI_BUSY_STATE_MASK) == 0U) + { + /* Synchronize initialization structure with the new device size value */ + hxspi->Init.MemorySize = Size; + + /* Configure new device size */ + MODIFY_REG(hxspi->Instance->DCR1, XSPI_DCR1_DEVSIZE, + (hxspi->Init.MemorySize << XSPI_DCR1_DEVSIZE_Pos)); + } + else + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE; + } + + return status; +} + +/** @brief Set XSPI Clock prescaler. + * @param hxspi : XSPI handle. + * @param Prescaler : Clock prescaler. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_XSPI_SetClockPrescaler(XSPI_HandleTypeDef *hxspi, uint32_t Prescaler) +{ + HAL_StatusTypeDef status = HAL_OK; + assert_param(IS_XSPI_CLK_PRESCALER(Prescaler)); + + /* Check the state */ + if ((hxspi->State & XSPI_BUSY_STATE_MASK) == 0U) + { + /* Synchronize initialization structure with the new clock prescaler value */ + hxspi->Init.ClockPrescaler = Prescaler; + + /* Configure clock prescaler */ + MODIFY_REG(hxspi->Instance->DCR2, XSPI_DCR2_PRESCALER, + ((hxspi->Init.ClockPrescaler) << XSPI_DCR2_PRESCALER_Pos)); + } + else + { + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_SEQUENCE; + } + + return status; +} + +/** @brief Set XSPI timeout. + * @param hxspi : XSPI handle. + * @param Timeout : Timeout for the memory access. + * @retval HAL state + */ +HAL_StatusTypeDef HAL_XSPI_SetTimeout(XSPI_HandleTypeDef *hxspi, uint32_t Timeout) +{ + hxspi->Timeout = Timeout; + return HAL_OK; +} + +/** + * @brief Return the XSPI error code. + * @param hxspi : XSPI handle + * @retval XSPI Error Code + */ +uint32_t HAL_XSPI_GetError(const XSPI_HandleTypeDef *hxspi) +{ + return hxspi->ErrorCode; +} + +/** + * @brief Return the XSPI handle state. + * @param hxspi : XSPI handle + * @retval HAL state + */ +uint32_t HAL_XSPI_GetState(const XSPI_HandleTypeDef *hxspi) +{ + /* Return XSPI handle state */ + return hxspi->State; +} + +/** + * @} + */ + +/** @defgroup XSPI_Exported_Functions_Group4 Delay Block function + * @brief Delay block function + * +@verbatim + =============================================================================== + ##### Delay Block function ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to : + (+) Configure the delay block. + +@endverbatim + * @{ + */ + +/** + * @brief Set the Delay Block configuration. + * @param hxspi : XSPI handle. + * @param pdlyb_cfg: Pointer to DLYB configuration structure. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_XSPI_DLYB_SetConfig(XSPI_HandleTypeDef *hxspi, HAL_XSPI_DLYB_CfgTypeDef *const pdlyb_cfg) +{ + HAL_StatusTypeDef status = HAL_ERROR; + + /* Enable XSPI Free Running Clock (mandatory) */ + SET_BIT(hxspi->Instance->DCR1, XSPI_DCR1_FRCK); + + /* Update XSPI state */ + hxspi->State = HAL_XSPI_STATE_BUSY_CMD; + + if (hxspi->Instance == OCTOSPI1) + { + /* Enable the DelayBlock */ + LL_DLYB_Enable(DLYB_OCTOSPI1); + + /* Set the Delay Block configuration */ + LL_DLYB_SetDelay(DLYB_OCTOSPI1, pdlyb_cfg); + status = HAL_OK; + } + else + { + hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_PARAM; + } + + /* Abort the current XSPI operation if exist */ + (void)HAL_XSPI_Abort(hxspi); + + /* Disable Free Running Clock */ + CLEAR_BIT(hxspi->Instance->DCR1, XSPI_DCR1_FRCK); + + return status; +} + +/** + * @brief Get the Delay Block configuration. + * @param hxspi : XSPI handle. + * @param pdlyb_cfg: Pointer to DLYB configuration structure. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_XSPI_DLYB_GetConfig(XSPI_HandleTypeDef *hxspi, HAL_XSPI_DLYB_CfgTypeDef *const pdlyb_cfg) +{ + HAL_StatusTypeDef status = HAL_ERROR; + + if (hxspi->Instance == OCTOSPI1) + { + LL_DLYB_GetDelay(DLYB_OCTOSPI1, pdlyb_cfg); + status = HAL_OK; + } + else + { + hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_PARAM; + } + + return status; +} + +/** + * @brief Get the Delay line length value. + * @param hxspi : XSPI handle. + * @param pdlyb_cfg: Pointer to DLYB configuration structure. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_XSPI_DLYB_GetClockPeriod(XSPI_HandleTypeDef *hxspi, HAL_XSPI_DLYB_CfgTypeDef *const pdlyb_cfg) +{ + HAL_StatusTypeDef status = HAL_ERROR; + + /* Enable XSPI Free Running Clock (mandatory) */ + SET_BIT(hxspi->Instance->DCR1, XSPI_DCR1_FRCK); + + /* Update XSPI state */ + hxspi->State = HAL_XSPI_STATE_BUSY_CMD; + + if (hxspi->Instance == OCTOSPI1) + { + /* Enable the DelayBlock */ + LL_DLYB_Enable(DLYB_OCTOSPI1); + + /* try to detect Period */ + if (LL_DLYB_GetClockPeriod(DLYB_OCTOSPI1, pdlyb_cfg) == (uint32_t)SUCCESS) + { + status = HAL_OK; + } + + /* Disable the DelayBlock */ + LL_DLYB_Disable(DLYB_OCTOSPI1); + } + else + { + hxspi->ErrorCode |= HAL_XSPI_ERROR_INVALID_PARAM; + } + + /* Abort the current XSPI operation if exist */ + (void)HAL_XSPI_Abort(hxspi); + + /* Disable Free Running Clock */ + CLEAR_BIT(hxspi->Instance->DCR1, XSPI_DCR1_FRCK); + + return status; +} + +/** + @cond 0 + */ +/** + * @brief DMA XSPI process complete callback. + * @param hdma : DMA handle + * @retval None + */ +static void XSPI_DMACplt(DMA_HandleTypeDef *hdma) +{ + XSPI_HandleTypeDef *hxspi = (XSPI_HandleTypeDef *)(hdma->Parent); + hxspi->XferCount = 0; + + /* Disable the DMA transfer on the XSPI side */ + CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_DMAEN); + + /* Disable the DMA channel */ + __HAL_DMA_DISABLE(hdma); + + /* Enable the XSPI transfer complete Interrupt */ + HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TC); +} + +/** + * @brief DMA XSPI process half complete callback. + * @param hdma : DMA handle + * @retval None + */ +static void XSPI_DMAHalfCplt(DMA_HandleTypeDef *hdma) +{ + XSPI_HandleTypeDef *hxspi = (XSPI_HandleTypeDef *)(hdma->Parent); + hxspi->XferCount = (hxspi->XferCount >> 1); + + if (hxspi->State == HAL_XSPI_STATE_BUSY_RX) + { +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) + hxspi->RxHalfCpltCallback(hxspi); +#else + HAL_XSPI_RxHalfCpltCallback(hxspi); +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */ + } + else + { +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) + hxspi->TxHalfCpltCallback(hxspi); +#else + HAL_XSPI_TxHalfCpltCallback(hxspi); +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */ + } +} + +/** + * @brief DMA XSPI communication error callback. + * @param hdma : DMA handle + * @retval None + */ +static void XSPI_DMAError(DMA_HandleTypeDef *hdma) +{ + XSPI_HandleTypeDef *hxspi = (XSPI_HandleTypeDef *)(hdma->Parent); + hxspi->XferCount = 0; + hxspi->ErrorCode = HAL_XSPI_ERROR_DMA; + + /* Disable the DMA transfer on the XSPI side */ + CLEAR_BIT(hxspi->Instance->CR, XSPI_CR_DMAEN); + + /* Abort the XSPI */ + if (HAL_XSPI_Abort_IT(hxspi) != HAL_OK) + { + /* Disable the interrupts */ + HAL_XSPI_DISABLE_IT(hxspi, HAL_XSPI_IT_TC | HAL_XSPI_IT_FT | HAL_XSPI_IT_TE); + + hxspi->State = HAL_XSPI_STATE_READY; + + /* Error callback */ +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) + hxspi->ErrorCallback(hxspi); +#else + HAL_XSPI_ErrorCallback(hxspi); +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */ + } +} + +/** + * @brief DMA XSPI abort complete callback. + * @param hdma : DMA handle + * @retval None + */ +static void XSPI_DMAAbortCplt(DMA_HandleTypeDef *hdma) +{ + XSPI_HandleTypeDef *hxspi = (XSPI_HandleTypeDef *)(hdma->Parent); + hxspi->XferCount = 0; + + /* Check the state */ + if (hxspi->State == HAL_XSPI_STATE_ABORT) + { + /* DMA abort called by XSPI abort */ + if (HAL_XSPI_GET_FLAG(hxspi, HAL_XSPI_FLAG_BUSY) != RESET) + { + /* Clear transfer complete flag */ + HAL_XSPI_CLEAR_FLAG(hxspi, HAL_XSPI_FLAG_TC); + + /* Enable the transfer complete interrupts */ + HAL_XSPI_ENABLE_IT(hxspi, HAL_XSPI_IT_TC); + + /* Perform an abort of the XSPI */ + SET_BIT(hxspi->Instance->CR, XSPI_CR_ABORT); + } + else + { + hxspi->State = HAL_XSPI_STATE_READY; + + /* Abort callback */ +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) + hxspi->AbortCpltCallback(hxspi); +#else + HAL_XSPI_AbortCpltCallback(hxspi); +#endif /* (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */ + } + } + else + { + /* DMA abort called due to a transfer error interrupt */ + hxspi->State = HAL_XSPI_STATE_READY; + + /* Error callback */ +#if defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) + hxspi->ErrorCallback(hxspi); +#else + HAL_XSPI_ErrorCallback(hxspi); +#endif /* defined (USE_HAL_XSPI_REGISTER_CALLBACKS) && (USE_HAL_XSPI_REGISTER_CALLBACKS == 1U) */ + } +} + +/** + * @brief Wait for a flag state until timeout. + * @param hxspi : XSPI handle + * @param Flag : Flag checked + * @param State : Value of the flag expected + * @param Timeout : Duration of the timeout + * @param Tickstart : Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef XSPI_WaitFlagStateUntilTimeout(XSPI_HandleTypeDef *hxspi, uint32_t Flag, + FlagStatus State, uint32_t Tickstart, uint32_t Timeout) +{ + /* Wait until flag is in expected state */ + while ((HAL_XSPI_GET_FLAG(hxspi, Flag)) != State) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + { + hxspi->State = HAL_XSPI_STATE_ERROR; + hxspi->ErrorCode |= HAL_XSPI_ERROR_TIMEOUT; + + return HAL_TIMEOUT; + } + } + } + return HAL_OK; +} + +/** + * @brief Configure the registers for the regular command mode. + * @param hxspi : XSPI handle + * @param pCmd : structure that contains the command configuration information + * @retval HAL status + */ +static HAL_StatusTypeDef XSPI_ConfigCmd(XSPI_HandleTypeDef *hxspi, XSPI_RegularCmdTypeDef *pCmd) +{ + HAL_StatusTypeDef status = HAL_OK; + __IO uint32_t *ccr_reg; + __IO uint32_t *tcr_reg; + __IO uint32_t *ir_reg; + __IO uint32_t *abr_reg; + + /* Re-initialize the value of the functional mode */ + MODIFY_REG(hxspi->Instance->CR, XSPI_CR_FMODE, 0U); + + if (hxspi->Init.MemoryMode == HAL_XSPI_SINGLE_MEM) + { + assert_param(IS_XSPI_IO_SELECT(pCmd->IOSelect)); + MODIFY_REG(hxspi->Instance->CR, XSPI_CR_MSEL, pCmd->IOSelect); + } + + if (pCmd->OperationType == HAL_XSPI_OPTYPE_WRITE_CFG) + { + ccr_reg = &(hxspi->Instance->WCCR); + tcr_reg = &(hxspi->Instance->WTCR); + ir_reg = &(hxspi->Instance->WIR); + abr_reg = &(hxspi->Instance->WABR); + } + else if (pCmd->OperationType == HAL_XSPI_OPTYPE_WRAP_CFG) + { + ccr_reg = &(hxspi->Instance->WPCCR); + tcr_reg = &(hxspi->Instance->WPTCR); + ir_reg = &(hxspi->Instance->WPIR); + abr_reg = &(hxspi->Instance->WPABR); + } + else + { + ccr_reg = &(hxspi->Instance->CCR); + tcr_reg = &(hxspi->Instance->TCR); + ir_reg = &(hxspi->Instance->IR); + abr_reg = &(hxspi->Instance->ABR); + } + + /* Configure the CCR register with DQS and SIOO modes */ + *ccr_reg = (pCmd->DQSMode | pCmd->SIOOMode); + + if (pCmd->AlternateBytesMode != HAL_XSPI_ALT_BYTES_NONE) + { + /* Configure the ABR register with alternate bytes value */ + *abr_reg = pCmd->AlternateBytes; + + /* Configure the CCR register with alternate bytes communication parameters */ + MODIFY_REG((*ccr_reg), (XSPI_CCR_ABMODE | XSPI_CCR_ABDTR | XSPI_CCR_ABSIZE), + (pCmd->AlternateBytesMode | pCmd->AlternateBytesDTRMode | pCmd->AlternateBytesWidth)); + } + + /* Configure the TCR register with the number of dummy cycles */ + MODIFY_REG((*tcr_reg), XSPI_TCR_DCYC, pCmd->DummyCycles); + + if (pCmd->DataMode != HAL_XSPI_DATA_NONE) + { + if (pCmd->OperationType == HAL_XSPI_OPTYPE_COMMON_CFG) + { + /* Configure the DLR register with the number of data */ + hxspi->Instance->DLR = (pCmd->DataLength - 1U); + } + } + + if (pCmd->InstructionMode != HAL_XSPI_INSTRUCTION_NONE) + { + if (pCmd->AddressMode != HAL_XSPI_ADDRESS_NONE) + { + if (pCmd->DataMode != HAL_XSPI_DATA_NONE) + { + /* ---- Command with instruction, address and data ---- */ + + /* Configure the CCR register with all communication parameters */ + MODIFY_REG((*ccr_reg), (XSPI_CCR_IMODE | XSPI_CCR_IDTR | XSPI_CCR_ISIZE | + XSPI_CCR_ADMODE | XSPI_CCR_ADDTR | XSPI_CCR_ADSIZE | + XSPI_CCR_DMODE | XSPI_CCR_DDTR), + (pCmd->InstructionMode | pCmd->InstructionDTRMode | pCmd->InstructionWidth | + pCmd->AddressMode | pCmd->AddressDTRMode | pCmd->AddressWidth | + pCmd->DataMode | pCmd->DataDTRMode)); + } + else + { + /* ---- Command with instruction and address ---- */ + + /* Configure the CCR register with all communication parameters */ + MODIFY_REG((*ccr_reg), (XSPI_CCR_IMODE | XSPI_CCR_IDTR | XSPI_CCR_ISIZE | + XSPI_CCR_ADMODE | XSPI_CCR_ADDTR | XSPI_CCR_ADSIZE), + (pCmd->InstructionMode | pCmd->InstructionDTRMode | pCmd->InstructionWidth | + pCmd->AddressMode | pCmd->AddressDTRMode | pCmd->AddressWidth)); + + /* The DHQC bit is linked with DDTR bit which should be activated */ + if ((hxspi->Init.DelayHoldQuarterCycle == HAL_XSPI_DHQC_ENABLE) && + (pCmd->InstructionDTRMode == HAL_XSPI_INSTRUCTION_DTR_ENABLE)) + { + MODIFY_REG((*ccr_reg), XSPI_CCR_DDTR, HAL_XSPI_DATA_DTR_ENABLE); + } + } + /* Configure the IR register with the instruction value */ + *ir_reg = pCmd->Instruction; + + /* Configure the AR register with the address value */ + hxspi->Instance->AR = pCmd->Address; + } + else + { + if (pCmd->DataMode != HAL_XSPI_DATA_NONE) + { + /* ---- Command with instruction and data ---- */ + + /* Configure the CCR register with all communication parameters */ + MODIFY_REG((*ccr_reg), (XSPI_CCR_IMODE | XSPI_CCR_IDTR | XSPI_CCR_ISIZE | + XSPI_CCR_DMODE | XSPI_CCR_DDTR), + (pCmd->InstructionMode | pCmd->InstructionDTRMode | pCmd->InstructionWidth | + pCmd->DataMode | pCmd->DataDTRMode)); + } + else + { + /* ---- Command with only instruction ---- */ + + /* Configure the CCR register with all communication parameters */ + MODIFY_REG((*ccr_reg), (XSPI_CCR_IMODE | XSPI_CCR_IDTR | XSPI_CCR_ISIZE), + (pCmd->InstructionMode | pCmd->InstructionDTRMode | pCmd->InstructionWidth)); + + /* The DHQC bit is linked with DDTR bit which should be activated */ + if ((hxspi->Init.DelayHoldQuarterCycle == HAL_XSPI_DHQC_ENABLE) && + (pCmd->InstructionDTRMode == HAL_XSPI_INSTRUCTION_DTR_ENABLE)) + { + MODIFY_REG((*ccr_reg), XSPI_CCR_DDTR, HAL_XSPI_DATA_DTR_ENABLE); + } + } + + /* Configure the IR register with the instruction value */ + *ir_reg = pCmd->Instruction; + + } + } + else + { + if (pCmd->AddressMode != HAL_XSPI_ADDRESS_NONE) + { + if (pCmd->DataMode != HAL_XSPI_DATA_NONE) + { + /* ---- Command with address and data ---- */ + + /* Configure the CCR register with all communication parameters */ + MODIFY_REG((*ccr_reg), (XSPI_CCR_ADMODE | XSPI_CCR_ADDTR | XSPI_CCR_ADSIZE | + XSPI_CCR_DMODE | XSPI_CCR_DDTR), + (pCmd->AddressMode | pCmd->AddressDTRMode | pCmd->AddressWidth | + pCmd->DataMode | pCmd->DataDTRMode)); + } + else + { + /* ---- Command with only address ---- */ + + /* Configure the CCR register with all communication parameters */ + MODIFY_REG((*ccr_reg), (XSPI_CCR_ADMODE | XSPI_CCR_ADDTR | XSPI_CCR_ADSIZE), + (pCmd->AddressMode | pCmd->AddressDTRMode | pCmd->AddressWidth)); + } + + /* Configure the AR register with the instruction value */ + hxspi->Instance->AR = pCmd->Address; + } + else + { + /* ---- Invalid command configuration (no instruction, no address) ---- */ + status = HAL_ERROR; + hxspi->ErrorCode = HAL_XSPI_ERROR_INVALID_PARAM; + } + } + + return status; +} + +/** + @endcond + */ + +/** + * @} + */ + +#endif /* HAL_XSPI_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HSPI || HSPI1 || HSPI2 || OCTOSPI || OCTOSPI1 || OCTOSPI2 */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_adc.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_adc.c new file mode 100644 index 0000000000..7c79b7e950 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_adc.c @@ -0,0 +1,1119 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_adc.c + * @author MCD Application Team + * @brief ADC LL module driver + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +#if defined(USE_FULL_LL_DRIVER) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_adc.h" +#include "stm32h5xx_ll_bus.h" + +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (ADC1) || defined (ADC2) + +/** @addtogroup ADC_LL ADC + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @addtogroup ADC_LL_Private_Constants + * @{ + */ + +/* Definitions of ADC hardware constraints delays */ +/* Note: Only ADC peripheral 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. */ +/* Refer to @ref ADC_LL_EC_HW_DELAYS for description of ADC timeout */ +/* values definition. */ +/* Note: ADC timeout values are defined here in CPU cycles to be independent */ +/* of device clock setting. */ +/* In user application, ADC timeout values should be defined with */ +/* temporal values, in function of device clock settings. */ +/* Highest ratio CPU clock frequency vs ADC clock frequency: */ +/* - ADC clock from synchronous clock with AHB prescaler 512, */ +/* ADC prescaler 4. */ +/* Ratio max = 512 *4 = 2048 */ +/* - ADC clock from asynchronous clock (PLLP) with prescaler 256. */ +/* Highest CPU clock PLL (PLLR). */ +/* Ratio max = PLLRmax /PPLPmin * 256 = (VCO/2) / (VCO/31) * 256 */ +/* = 3968 */ +/* Unit: CPU cycles. */ +#define ADC_CLOCK_RATIO_VS_CPU_HIGHEST (3968UL) +#define ADC_TIMEOUT_DISABLE_CPU_CYCLES (ADC_CLOCK_RATIO_VS_CPU_HIGHEST * 1UL) +#define ADC_TIMEOUT_STOP_CONVERSION_CPU_CYCLES (ADC_CLOCK_RATIO_VS_CPU_HIGHEST * 1UL) + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ + +/** @addtogroup ADC_LL_Private_Macros + * @{ + */ + +/* Check of parameters for configuration of ADC hierarchical scope: */ +/* common to several ADC instances. */ +#define IS_LL_ADC_COMMON_CLOCK(__CLOCK__) \ + (((__CLOCK__) == LL_ADC_CLOCK_SYNC_PCLK_DIV1) \ + || ((__CLOCK__) == LL_ADC_CLOCK_SYNC_PCLK_DIV2) \ + || ((__CLOCK__) == LL_ADC_CLOCK_SYNC_PCLK_DIV4) \ + || ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV1) \ + || ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV2) \ + || ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV4) \ + || ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV6) \ + || ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV8) \ + || ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV10) \ + || ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV12) \ + || ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV16) \ + || ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV32) \ + || ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV64) \ + || ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV128) \ + || ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_DIV256) \ + ) + +/* Check of parameters for configuration of ADC hierarchical scope: */ +/* ADC instance. */ +#define IS_LL_ADC_RESOLUTION(__RESOLUTION__) \ + (((__RESOLUTION__) == LL_ADC_RESOLUTION_12B) \ + || ((__RESOLUTION__) == LL_ADC_RESOLUTION_10B) \ + || ((__RESOLUTION__) == LL_ADC_RESOLUTION_8B) \ + || ((__RESOLUTION__) == LL_ADC_RESOLUTION_6B) \ + ) + +#define IS_LL_ADC_DATA_ALIGN(__DATA_ALIGN__) \ + (((__DATA_ALIGN__) == LL_ADC_DATA_ALIGN_RIGHT) \ + || ((__DATA_ALIGN__) == LL_ADC_DATA_ALIGN_LEFT) \ + ) + +#define IS_LL_ADC_LOW_POWER(__LOW_POWER__) \ + (((__LOW_POWER__) == LL_ADC_LP_MODE_NONE) \ + || ((__LOW_POWER__) == LL_ADC_LP_AUTOWAIT) \ + ) + +/* Check of parameters for configuration of ADC hierarchical scope: */ +/* ADC group regular */ +#if defined(TIM8) +/* Devices STM32H563/H573xx */ +#define IS_LL_ADC_REG_TRIG_SOURCE(__REG_TRIG_SOURCE__) \ + ( ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_SOFTWARE) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH1) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH2) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH3) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM2_CH2) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM3_TRGO) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM4_CH4) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_EXTI_LINE11) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM8_TRGO) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM8_TRGO2) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_TRGO) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_TRGO2) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM2_TRGO) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM4_TRGO) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM6_TRGO) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM15_TRGO) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM3_CH4) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_EXTI_LINE15) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_LPTIM1_CH1) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_LPTIM2_CH1) \ + ) +#else +/* Devices STM32H503xx */ +#define IS_LL_ADC_REG_TRIG_SOURCE(__REG_TRIG_SOURCE__) \ + ( ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_SOFTWARE) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH1) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH2) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH3) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM2_CH2) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM3_TRGO) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_EXTI_LINE11) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_TRGO) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_TRGO2) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM2_TRGO) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM6_TRGO) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM3_CH4) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_EXTI_LINE15) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM7_TRGO) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_LPTIM1_CH1) \ + || ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_LPTIM2_CH1) \ + ) +#endif /* Devices STM32H563/H573xx or STM32H503xx */ + +#define IS_LL_ADC_REG_CONTINUOUS_MODE(__REG_CONTINUOUS_MODE__) \ + (((__REG_CONTINUOUS_MODE__) == LL_ADC_REG_CONV_SINGLE) \ + || ((__REG_CONTINUOUS_MODE__) == LL_ADC_REG_CONV_CONTINUOUS) \ + ) + +#define IS_LL_ADC_REG_DMA_TRANSFER(__REG_DMA_TRANSFER__) \ + (((__REG_DMA_TRANSFER__) == LL_ADC_REG_DMA_TRANSFER_NONE) \ + || ((__REG_DMA_TRANSFER__) == LL_ADC_REG_DMA_TRANSFER_LIMITED) \ + || ((__REG_DMA_TRANSFER__) == LL_ADC_REG_DMA_TRANSFER_UNLIMITED) \ + ) + +#define IS_LL_ADC_REG_OVR_DATA_BEHAVIOR(__REG_OVR_DATA_BEHAVIOR__) \ + (((__REG_OVR_DATA_BEHAVIOR__) == LL_ADC_REG_OVR_DATA_PRESERVED) \ + || ((__REG_OVR_DATA_BEHAVIOR__) == LL_ADC_REG_OVR_DATA_OVERWRITTEN) \ + ) + +#define IS_LL_ADC_REG_SEQ_SCAN_LENGTH(__REG_SEQ_SCAN_LENGTH__) \ + (((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_DISABLE) \ + || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_2RANKS) \ + || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_3RANKS) \ + || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_4RANKS) \ + || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_5RANKS) \ + || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_6RANKS) \ + || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_7RANKS) \ + || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_8RANKS) \ + || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_9RANKS) \ + || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_10RANKS) \ + || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_11RANKS) \ + || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_12RANKS) \ + || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_13RANKS) \ + || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_14RANKS) \ + || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_15RANKS) \ + || ((__REG_SEQ_SCAN_LENGTH__) == LL_ADC_REG_SEQ_SCAN_ENABLE_16RANKS) \ + ) + +#define IS_LL_ADC_REG_SEQ_SCAN_DISCONT_MODE(__REG_SEQ_DISCONT_MODE__) \ + (((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_DISABLE) \ + || ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_1RANK) \ + || ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_2RANKS) \ + || ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_3RANKS) \ + || ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_4RANKS) \ + || ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_5RANKS) \ + || ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_6RANKS) \ + || ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_7RANKS) \ + || ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_8RANKS) \ + ) + +/* Check of parameters for configuration of ADC hierarchical scope: */ +/* ADC group injected */ +#if defined(TIM8) +/* Devices STM32H563/H573xx */ +#define IS_LL_ADC_INJ_TRIG_SOURCE(__INJ_TRIG_SOURCE__) \ + ( ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_SOFTWARE) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM1_TRGO) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM1_CH4) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM2_TRGO) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM2_CH1) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM3_CH4) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM4_TRGO) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_EXTI_LINE15) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM8_CH4) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM1_TRGO2) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM8_TRGO) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM8_TRGO2) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM3_CH3) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM3_TRGO) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM3_CH1) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM6_TRGO) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM15_TRGO) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_LPTIM1_CH1) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_LPTIM2_CH1) \ + ) +#else +/* Devices STM32H503xx */ +#define IS_LL_ADC_INJ_TRIG_SOURCE(__INJ_TRIG_SOURCE__) \ + ( ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_SOFTWARE) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM1_TRGO) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM1_CH4) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM2_TRGO) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM2_CH1) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM3_CH4) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_EXTI_LINE15) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM1_TRGO2) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM3_CH3) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM3_TRGO) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM3_CH1) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM6_TRGO) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_TIM7_TRGO) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_LPTIM1_CH1) \ + || ((__INJ_TRIG_SOURCE__) == LL_ADC_INJ_TRIG_EXT_LPTIM2_CH1) \ + ) +#endif /* Devices STM32H563/H573xx or STM32H503xx */ + +#define IS_LL_ADC_INJ_TRIG_EXT_EDGE(__INJ_TRIG_EXT_EDGE__) \ + (((__INJ_TRIG_EXT_EDGE__) == LL_ADC_INJ_TRIG_EXT_RISING) \ + || ((__INJ_TRIG_EXT_EDGE__) == LL_ADC_INJ_TRIG_EXT_FALLING) \ + || ((__INJ_TRIG_EXT_EDGE__) == LL_ADC_INJ_TRIG_EXT_RISINGFALLING) \ + ) + +#define IS_LL_ADC_INJ_TRIG_AUTO(__INJ_TRIG_AUTO__) \ + (((__INJ_TRIG_AUTO__) == LL_ADC_INJ_TRIG_INDEPENDENT) \ + || ((__INJ_TRIG_AUTO__) == LL_ADC_INJ_TRIG_FROM_GRP_REGULAR) \ + ) + +#define IS_LL_ADC_INJ_SEQ_SCAN_LENGTH(__INJ_SEQ_SCAN_LENGTH__) \ + (((__INJ_SEQ_SCAN_LENGTH__) == LL_ADC_INJ_SEQ_SCAN_DISABLE) \ + || ((__INJ_SEQ_SCAN_LENGTH__) == LL_ADC_INJ_SEQ_SCAN_ENABLE_2RANKS) \ + || ((__INJ_SEQ_SCAN_LENGTH__) == LL_ADC_INJ_SEQ_SCAN_ENABLE_3RANKS) \ + || ((__INJ_SEQ_SCAN_LENGTH__) == LL_ADC_INJ_SEQ_SCAN_ENABLE_4RANKS) \ + ) + +#define IS_LL_ADC_INJ_SEQ_SCAN_DISCONT_MODE(__INJ_SEQ_DISCONT_MODE__) \ + (((__INJ_SEQ_DISCONT_MODE__) == LL_ADC_INJ_SEQ_DISCONT_DISABLE) \ + || ((__INJ_SEQ_DISCONT_MODE__) == LL_ADC_INJ_SEQ_DISCONT_1RANK) \ + ) + +#if defined(ADC_MULTIMODE_SUPPORT) +/* Check of parameters for configuration of ADC hierarchical scope: */ +/* multimode. */ +#define IS_LL_ADC_MULTI_MODE(__MULTI_MODE__) \ + (((__MULTI_MODE__) == LL_ADC_MULTI_INDEPENDENT) \ + || ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_SIMULT) \ + || ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_INTERL) \ + || ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_INJ_SIMULT) \ + || ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_INJ_ALTERN) \ + || ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_SIM_INJ_SIM) \ + || ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_SIM_INJ_ALT) \ + || ((__MULTI_MODE__) == LL_ADC_MULTI_DUAL_REG_INT_INJ_SIM) \ + ) + +#define IS_LL_ADC_MULTI_DMA_TRANSFER(__MULTI_DMA_TRANSFER__) \ + (((__MULTI_DMA_TRANSFER__) == LL_ADC_MULTI_REG_DMA_EACH_ADC) \ + || ((__MULTI_DMA_TRANSFER__) == LL_ADC_MULTI_REG_DMA_LIMIT_RES12_10B) \ + || ((__MULTI_DMA_TRANSFER__) == LL_ADC_MULTI_REG_DMA_LIMIT_RES8_6B) \ + || ((__MULTI_DMA_TRANSFER__) == LL_ADC_MULTI_REG_DMA_UNLMT_RES12_10B) \ + || ((__MULTI_DMA_TRANSFER__) == LL_ADC_MULTI_REG_DMA_UNLMT_RES8_6B) \ + ) + +#define IS_LL_ADC_MULTI_TWOSMP_DELAY(__MULTI_TWOSMP_DELAY__) \ + (((__MULTI_TWOSMP_DELAY__) == LL_ADC_MULTI_TWOSMP_DELAY_1CYCLE) \ + || ((__MULTI_TWOSMP_DELAY__) == LL_ADC_MULTI_TWOSMP_DELAY_2CYCLES) \ + || ((__MULTI_TWOSMP_DELAY__) == LL_ADC_MULTI_TWOSMP_DELAY_3CYCLES) \ + || ((__MULTI_TWOSMP_DELAY__) == LL_ADC_MULTI_TWOSMP_DELAY_4CYCLES) \ + || ((__MULTI_TWOSMP_DELAY__) == LL_ADC_MULTI_TWOSMP_DELAY_5CYCLES) \ + || ((__MULTI_TWOSMP_DELAY__) == LL_ADC_MULTI_TWOSMP_DELAY_6CYCLES) \ + || ((__MULTI_TWOSMP_DELAY__) == LL_ADC_MULTI_TWOSMP_DELAY_7CYCLES) \ + || ((__MULTI_TWOSMP_DELAY__) == LL_ADC_MULTI_TWOSMP_DELAY_8CYCLES) \ + || ((__MULTI_TWOSMP_DELAY__) == LL_ADC_MULTI_TWOSMP_DELAY_9CYCLES) \ + || ((__MULTI_TWOSMP_DELAY__) == LL_ADC_MULTI_TWOSMP_DELAY_10CYCLES) \ + || ((__MULTI_TWOSMP_DELAY__) == LL_ADC_MULTI_TWOSMP_DELAY_11CYCLES) \ + || ((__MULTI_TWOSMP_DELAY__) == LL_ADC_MULTI_TWOSMP_DELAY_12CYCLES) \ + ) + +#define IS_LL_ADC_MULTI_MASTER_SLAVE(__MULTI_MASTER_SLAVE__) \ + (((__MULTI_MASTER_SLAVE__) == LL_ADC_MULTI_MASTER) \ + || ((__MULTI_MASTER_SLAVE__) == LL_ADC_MULTI_SLAVE) \ + || ((__MULTI_MASTER_SLAVE__) == LL_ADC_MULTI_MASTER_SLAVE) \ + ) + +#endif /* ADC_MULTIMODE_SUPPORT */ +/** + * @} + */ + + +/* Private function prototypes -----------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup ADC_LL_Exported_Functions + * @{ + */ + +/** @addtogroup ADC_LL_EF_Init + * @{ + */ + +/** + * @brief De-initialize registers of all ADC instances belonging to + * the same ADC common instance to their default reset values. + * @note This function is performing a hard reset, using high level + * clock source RCC ADC reset. + * Caution: On this STM32 series, if several ADC instances are available + * on the selected device, RCC ADC reset will reset + * all ADC instances belonging to the common ADC instance. + * To de-initialize only 1 ADC instance, use + * function @ref LL_ADC_DeInit(). + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @retval An ErrorStatus enumeration value: + * - SUCCESS: ADC common registers are de-initialized + * - ERROR: not applicable + */ +ErrorStatus LL_ADC_CommonDeInit(const ADC_Common_TypeDef *ADCxy_COMMON) +{ + /* Check the parameters */ + assert_param(IS_ADC_COMMON_INSTANCE(ADCxy_COMMON)); + + /* Prevent unused argument compilation warning */ + (void)(ADCxy_COMMON); + + /* Force reset of ADC clock (core clock) */ + LL_AHB2_GRP1_ForceReset(LL_AHB2_GRP1_PERIPH_ADC); + + /* Release reset of ADC clock (core clock) */ + LL_AHB2_GRP1_ReleaseReset(LL_AHB2_GRP1_PERIPH_ADC); + + return SUCCESS; +} + +/** + * @brief Initialize some features of ADC common parameters + * (all ADC instances belonging to the same ADC common instance) + * and multimode (for devices with several ADC instances available). + * @note The setting of ADC common parameters is conditioned to + * ADC instances state: + * All ADC instances belonging to the same ADC common instance + * must be disabled. + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @param pADC_CommonInitStruct Pointer to a @ref LL_ADC_CommonInitTypeDef structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: ADC common registers are initialized + * - ERROR: ADC common registers are not initialized + */ +ErrorStatus LL_ADC_CommonInit(ADC_Common_TypeDef *ADCxy_COMMON, const LL_ADC_CommonInitTypeDef *pADC_CommonInitStruct) +{ + ErrorStatus status = SUCCESS; + + /* Check the parameters */ + assert_param(IS_ADC_COMMON_INSTANCE(ADCxy_COMMON)); + assert_param(IS_LL_ADC_COMMON_CLOCK(pADC_CommonInitStruct->CommonClock)); + +#if defined(ADC_MULTIMODE_SUPPORT) + assert_param(IS_LL_ADC_MULTI_MODE(pADC_CommonInitStruct->Multimode)); + if (pADC_CommonInitStruct->Multimode != LL_ADC_MULTI_INDEPENDENT) + { + assert_param(IS_LL_ADC_MULTI_DMA_TRANSFER(pADC_CommonInitStruct->MultiDMATransfer)); + assert_param(IS_LL_ADC_MULTI_TWOSMP_DELAY(pADC_CommonInitStruct->MultiTwoSamplingDelay)); + } +#endif /* ADC_MULTIMODE_SUPPORT */ + + /* Note: Hardware constraint (refer to description of functions */ + /* "LL_ADC_SetCommonXXX()" and "LL_ADC_SetMultiXXX()"): */ + /* On this STM32 series, setting of these features is conditioned to */ + /* ADC state: */ + /* All ADC instances of the ADC common group must be disabled. */ + if (__LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(ADCxy_COMMON) == 0UL) + { + /* Configuration of ADC hierarchical scope: */ + /* - common to several ADC */ + /* (all ADC instances belonging to the same ADC common instance) */ + /* - Set ADC clock (conversion clock) */ + /* - multimode (if several ADC instances available on the */ + /* selected device) */ + /* - Set ADC multimode configuration */ + /* - Set ADC multimode DMA transfer */ + /* - Set ADC multimode: delay between 2 sampling phases */ +#if defined(ADC_MULTIMODE_SUPPORT) + if (pADC_CommonInitStruct->Multimode != LL_ADC_MULTI_INDEPENDENT) + { + MODIFY_REG(ADCxy_COMMON->CCR, + ADC_CCR_CKMODE + | ADC_CCR_PRESC + | ADC_CCR_DUAL + | ADC_CCR_MDMA + | ADC_CCR_DELAY + , + pADC_CommonInitStruct->CommonClock + | pADC_CommonInitStruct->Multimode + | pADC_CommonInitStruct->MultiDMATransfer + | pADC_CommonInitStruct->MultiTwoSamplingDelay + ); + } + else + { + MODIFY_REG(ADCxy_COMMON->CCR, + ADC_CCR_CKMODE + | ADC_CCR_PRESC + | ADC_CCR_DUAL + | ADC_CCR_MDMA + | ADC_CCR_DELAY + , + pADC_CommonInitStruct->CommonClock + | LL_ADC_MULTI_INDEPENDENT + ); + } +#else + LL_ADC_SetCommonClock(ADCxy_COMMON, pADC_CommonInitStruct->CommonClock); +#endif /* ADC_MULTIMODE_SUPPORT */ + } + else + { + /* Initialization error: One or several ADC instances belonging to */ + /* the same ADC common instance are not disabled. */ + status = ERROR; + } + + return status; +} + +/** + * @brief Set each @ref LL_ADC_CommonInitTypeDef field to default value. + * @param pADC_CommonInitStruct Pointer to a @ref LL_ADC_CommonInitTypeDef structure + * whose fields will be set to default values. + * @retval None + */ +void LL_ADC_CommonStructInit(LL_ADC_CommonInitTypeDef *pADC_CommonInitStruct) +{ + /* Set pADC_CommonInitStruct fields to default values */ + /* Set fields of ADC common */ + /* (all ADC instances belonging to the same ADC common instance) */ + pADC_CommonInitStruct->CommonClock = LL_ADC_CLOCK_SYNC_PCLK_DIV2; + +#if defined(ADC_MULTIMODE_SUPPORT) + /* Set fields of ADC multimode */ + pADC_CommonInitStruct->Multimode = LL_ADC_MULTI_INDEPENDENT; + pADC_CommonInitStruct->MultiDMATransfer = LL_ADC_MULTI_REG_DMA_EACH_ADC; + pADC_CommonInitStruct->MultiTwoSamplingDelay = LL_ADC_MULTI_TWOSMP_DELAY_1CYCLE; +#endif /* ADC_MULTIMODE_SUPPORT */ +} + +/** + * @brief De-initialize registers of the selected ADC instance + * to their default reset values. + * @note To reset all ADC instances quickly (perform a hard reset), + * use function @ref LL_ADC_CommonDeInit(). + * @note If this functions returns error status, it means that ADC instance + * is in an unknown state. + * In this case, perform a hard reset using high level + * clock source RCC ADC reset. + * Caution: On this STM32 series, if several ADC instances are available + * on the selected device, RCC ADC reset will reset + * all ADC instances belonging to the common ADC instance. + * Refer to function @ref LL_ADC_CommonDeInit(). + * @param ADCx ADC instance + * @retval An ErrorStatus enumeration value: + * - SUCCESS: ADC registers are de-initialized + * - ERROR: ADC registers are not de-initialized + */ +ErrorStatus LL_ADC_DeInit(ADC_TypeDef *ADCx) +{ + ErrorStatus status = SUCCESS; + + __IO uint32_t timeout_cpu_cycles = 0UL; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(ADCx)); + + /* Disable ADC instance if not already disabled. */ + if (LL_ADC_IsEnabled(ADCx) == 1UL) + { + /* Set ADC group regular trigger source to SW start to ensure to not */ + /* have an external trigger event occurring during the conversion stop */ + /* ADC disable process. */ + LL_ADC_REG_SetTriggerSource(ADCx, LL_ADC_REG_TRIG_SOFTWARE); + + /* Stop potential ADC conversion on going on ADC group regular. */ + if (LL_ADC_REG_IsConversionOngoing(ADCx) != 0UL) + { + if (LL_ADC_REG_IsStopConversionOngoing(ADCx) == 0UL) + { + LL_ADC_REG_StopConversion(ADCx); + } + } + + /* Set ADC group injected trigger source to SW start to ensure to not */ + /* have an external trigger event occurring during the conversion stop */ + /* ADC disable process. */ + LL_ADC_INJ_SetTriggerSource(ADCx, LL_ADC_INJ_TRIG_SOFTWARE); + + /* Stop potential ADC conversion on going on ADC group injected. */ + if (LL_ADC_INJ_IsConversionOngoing(ADCx) != 0UL) + { + if (LL_ADC_INJ_IsStopConversionOngoing(ADCx) == 0UL) + { + LL_ADC_INJ_StopConversion(ADCx); + } + } + + /* Wait for ADC conversions are effectively stopped */ + timeout_cpu_cycles = ADC_TIMEOUT_STOP_CONVERSION_CPU_CYCLES; + while ((LL_ADC_REG_IsStopConversionOngoing(ADCx) + | LL_ADC_INJ_IsStopConversionOngoing(ADCx)) == 1UL) + { + timeout_cpu_cycles--; + if (timeout_cpu_cycles == 0UL) + { + /* Time-out error */ + status = ERROR; + break; + } + } + + /* Flush group injected contexts queue (register JSQR): */ + /* Note: Bit JQM must be set to empty the contexts queue (otherwise */ + /* contexts queue is maintained with the last active context). */ + LL_ADC_INJ_SetQueueMode(ADCx, LL_ADC_INJ_QUEUE_2CONTEXTS_END_EMPTY); + + /* Disable the ADC instance */ + LL_ADC_Disable(ADCx); + + /* Wait for ADC instance is effectively disabled */ + timeout_cpu_cycles = ADC_TIMEOUT_DISABLE_CPU_CYCLES; + while (LL_ADC_IsDisableOngoing(ADCx) == 1UL) + { + timeout_cpu_cycles--; + if (timeout_cpu_cycles == 0UL) + { + /* Time-out error */ + status = ERROR; + break; + } + } + } + + /* Check whether ADC state is compliant with expected state */ + if (READ_BIT(ADCx->CR, + (ADC_CR_JADSTP | ADC_CR_ADSTP | ADC_CR_JADSTART | ADC_CR_ADSTART + | ADC_CR_ADDIS | ADC_CR_ADEN) + ) + == 0UL) + { + /* ========== Reset ADC registers ========== */ + /* Reset register IER */ + CLEAR_BIT(ADCx->IER, + (LL_ADC_IT_ADRDY + | LL_ADC_IT_EOC + | LL_ADC_IT_EOS + | LL_ADC_IT_OVR + | LL_ADC_IT_EOSMP + | LL_ADC_IT_JEOC + | LL_ADC_IT_JEOS + | LL_ADC_IT_JQOVF + | LL_ADC_IT_AWD1 + | LL_ADC_IT_AWD2 + | LL_ADC_IT_AWD3 + ) + ); + + /* Reset register ISR */ + SET_BIT(ADCx->ISR, + (LL_ADC_FLAG_ADRDY + | LL_ADC_FLAG_EOC + | LL_ADC_FLAG_EOS + | LL_ADC_FLAG_OVR + | LL_ADC_FLAG_EOSMP + | LL_ADC_FLAG_JEOC + | LL_ADC_FLAG_JEOS + | LL_ADC_FLAG_JQOVF + | LL_ADC_FLAG_AWD1 + | LL_ADC_FLAG_AWD2 + | LL_ADC_FLAG_AWD3 + ) + ); + + /* Reset register CR */ + /* - Bits ADC_CR_JADSTP, ADC_CR_ADSTP, ADC_CR_JADSTART, ADC_CR_ADSTART, */ + /* ADC_CR_ADCAL, ADC_CR_ADDIS, ADC_CR_ADEN are in */ + /* access mode "read-set": no direct reset applicable. */ + /* - Reset Calibration mode to default setting (single ended). */ + /* - Disable ADC internal voltage regulator. */ + /* - Enable ADC deep power down. */ + /* Note: ADC internal voltage regulator disable and ADC deep power */ + /* down enable are conditioned to ADC state disabled: */ + /* already done above. */ + CLEAR_BIT(ADCx->CR, ADC_CR_ADVREGEN | ADC_CR_ADCALDIF); + SET_BIT(ADCx->CR, ADC_CR_DEEPPWD); + + /* Reset register CFGR */ + MODIFY_REG(ADCx->CFGR, + (ADC_CFGR_AWD1CH | ADC_CFGR_JAUTO | ADC_CFGR_JAWD1EN + | ADC_CFGR_AWD1EN | ADC_CFGR_AWD1SGL | ADC_CFGR_JQM + | ADC_CFGR_JDISCEN | ADC_CFGR_DISCNUM | ADC_CFGR_DISCEN + | ADC_CFGR_AUTDLY | ADC_CFGR_CONT | ADC_CFGR_OVRMOD + | ADC_CFGR_EXTEN | ADC_CFGR_EXTSEL | ADC_CFGR_ALIGN + | ADC_CFGR_RES | ADC_CFGR_DMACFG | ADC_CFGR_DMAEN), + ADC_CFGR_JQDIS + ); + + /* Reset register CFGR2 */ + CLEAR_BIT(ADCx->CFGR2, + (ADC_CFGR2_ROVSM | ADC_CFGR2_TROVS | ADC_CFGR2_OVSS + | ADC_CFGR2_SWTRIG | ADC_CFGR2_BULB | ADC_CFGR2_SMPTRIG + | ADC_CFGR2_OVSR | ADC_CFGR2_JOVSE | ADC_CFGR2_ROVSE) + ); + + /* Reset register SMPR1 */ + CLEAR_BIT(ADCx->SMPR1, + (ADC_SMPR1_SMP9 | ADC_SMPR1_SMP8 | ADC_SMPR1_SMP7 + | ADC_SMPR1_SMP6 | ADC_SMPR1_SMP5 | ADC_SMPR1_SMP4 + | ADC_SMPR1_SMP3 | ADC_SMPR1_SMP2 | ADC_SMPR1_SMP1) + ); + + /* Reset register SMPR2 */ + CLEAR_BIT(ADCx->SMPR2, + (ADC_SMPR2_SMP18 | ADC_SMPR2_SMP17 | ADC_SMPR2_SMP16 + | ADC_SMPR2_SMP15 | ADC_SMPR2_SMP14 | ADC_SMPR2_SMP13 + | ADC_SMPR2_SMP12 | ADC_SMPR2_SMP11 | ADC_SMPR2_SMP10) + ); + + /* Reset register TR1 */ + MODIFY_REG(ADCx->TR1, ADC_TR1_AWDFILT | ADC_TR1_HT1 | ADC_TR1_LT1, ADC_TR1_HT1); + + /* Reset register TR2 */ + MODIFY_REG(ADCx->TR2, ADC_TR2_HT2 | ADC_TR2_LT2, ADC_TR2_HT2); + + /* Reset register TR3 */ + MODIFY_REG(ADCx->TR3, ADC_TR3_HT3 | ADC_TR3_LT3, ADC_TR3_HT3); + + /* Reset register SQR1 */ + CLEAR_BIT(ADCx->SQR1, + (ADC_SQR1_SQ4 | ADC_SQR1_SQ3 | ADC_SQR1_SQ2 + | ADC_SQR1_SQ1 | ADC_SQR1_L) + ); + + /* Reset register SQR2 */ + CLEAR_BIT(ADCx->SQR2, + (ADC_SQR2_SQ9 | ADC_SQR2_SQ8 | ADC_SQR2_SQ7 + | ADC_SQR2_SQ6 | ADC_SQR2_SQ5) + ); + + /* Reset register SQR3 */ + CLEAR_BIT(ADCx->SQR3, + (ADC_SQR3_SQ14 | ADC_SQR3_SQ13 | ADC_SQR3_SQ12 + | ADC_SQR3_SQ11 | ADC_SQR3_SQ10) + ); + + /* Reset register SQR4 */ + CLEAR_BIT(ADCx->SQR4, ADC_SQR4_SQ16 | ADC_SQR4_SQ15); + + /* Reset register JSQR */ + CLEAR_BIT(ADCx->JSQR, + (ADC_JSQR_JL + | ADC_JSQR_JEXTSEL | ADC_JSQR_JEXTEN + | ADC_JSQR_JSQ4 | ADC_JSQR_JSQ3 + | ADC_JSQR_JSQ2 | ADC_JSQR_JSQ1) + ); + + /* Reset register DR */ + /* Note: bits in access mode read only, no direct reset applicable */ + + /* Reset register OFR1 */ + CLEAR_BIT(ADCx->OFR1, + ADC_OFR1_OFFSET1_EN | ADC_OFR1_OFFSET1_CH | ADC_OFR1_OFFSET1 | ADC_OFR1_SATEN | ADC_OFR1_OFFSETPOS); + /* Reset register OFR2 */ + CLEAR_BIT(ADCx->OFR2, + ADC_OFR2_OFFSET2_EN | ADC_OFR2_OFFSET2_CH | ADC_OFR2_OFFSET2 | ADC_OFR2_SATEN | ADC_OFR2_OFFSETPOS); + /* Reset register OFR3 */ + CLEAR_BIT(ADCx->OFR3, + ADC_OFR3_OFFSET3_EN | ADC_OFR3_OFFSET3_CH | ADC_OFR3_OFFSET3 | ADC_OFR3_SATEN | ADC_OFR3_OFFSETPOS); + /* Reset register OFR4 */ + CLEAR_BIT(ADCx->OFR4, + ADC_OFR4_OFFSET4_EN | ADC_OFR4_OFFSET4_CH | ADC_OFR4_OFFSET4 | ADC_OFR4_SATEN | ADC_OFR4_OFFSETPOS); + + /* Reset registers JDR1, JDR2, JDR3, JDR4 */ + /* Note: bits in access mode read only, no direct reset applicable */ + + /* Reset register AWD2CR */ + CLEAR_BIT(ADCx->AWD2CR, ADC_AWD2CR_AWD2CH); + + /* Reset register AWD3CR */ + CLEAR_BIT(ADCx->AWD3CR, ADC_AWD3CR_AWD3CH); + + /* Reset register DIFSEL */ + CLEAR_BIT(ADCx->DIFSEL, ADC_DIFSEL_DIFSEL); + + /* Reset register CALFACT */ + CLEAR_BIT(ADCx->CALFACT, ADC_CALFACT_CALFACT_D | ADC_CALFACT_CALFACT_S); + } + else + { + /* ADC instance is in an unknown state */ + /* Need to performing a hard reset of ADC instance, using high level */ + /* clock source RCC ADC reset. */ + /* Caution: On this STM32 series, if several ADC instances are available */ + /* on the selected device, RCC ADC reset will reset */ + /* all ADC instances belonging to the common ADC instance. */ + /* Caution: On this STM32 series, if several ADC instances are available */ + /* on the selected device, RCC ADC reset will reset */ + /* all ADC instances belonging to the common ADC instance. */ + status = ERROR; + } + + return status; +} + +/** + * @brief Initialize 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 series). + * 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 series. 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. + * @note After using this function, some other features must be configured + * using LL unitary functions. + * The minimum configuration remaining to be done is: + * - Set ADC group regular or group injected sequencer: + * map channel on the selected sequencer rank. + * Refer to function @ref LL_ADC_REG_SetSequencerRanks(). + * - Set ADC channel sampling time + * Refer to function LL_ADC_SetChannelSamplingTime(); + * @param ADCx ADC instance + * @param pADC_InitStruct Pointer to a @ref LL_ADC_REG_InitTypeDef structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: ADC registers are initialized + * - ERROR: ADC registers are not initialized + */ +ErrorStatus LL_ADC_Init(ADC_TypeDef *ADCx, const LL_ADC_InitTypeDef *pADC_InitStruct) +{ + ErrorStatus status = SUCCESS; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(ADCx)); + + assert_param(IS_LL_ADC_RESOLUTION(pADC_InitStruct->Resolution)); + assert_param(IS_LL_ADC_DATA_ALIGN(pADC_InitStruct->DataAlignment)); + assert_param(IS_LL_ADC_LOW_POWER(pADC_InitStruct->LowPowerMode)); + + /* Note: Hardware constraint (refer to description of this function): */ + /* ADC instance must be disabled. */ + if (LL_ADC_IsEnabled(ADCx) == 0UL) + { + /* Configuration of ADC hierarchical scope: */ + /* - ADC instance */ + /* - Set ADC data resolution */ + /* - Set ADC conversion data alignment */ + /* - Set ADC low power mode */ + MODIFY_REG(ADCx->CFGR, + ADC_CFGR_RES + | ADC_CFGR_ALIGN + | ADC_CFGR_AUTDLY + , + pADC_InitStruct->Resolution + | pADC_InitStruct->DataAlignment + | pADC_InitStruct->LowPowerMode + ); + + } + else + { + /* Initialization error: ADC instance is not disabled. */ + status = ERROR; + } + + return status; +} + +/** + * @brief Set each @ref LL_ADC_InitTypeDef field to default value. + * @param pADC_InitStruct Pointer to a @ref LL_ADC_InitTypeDef structure + * whose fields will be set to default values. + * @retval None + */ +void LL_ADC_StructInit(LL_ADC_InitTypeDef *pADC_InitStruct) +{ + /* Set pADC_InitStruct fields to default values */ + /* Set fields of ADC instance */ + pADC_InitStruct->Resolution = LL_ADC_RESOLUTION_12B; + pADC_InitStruct->DataAlignment = LL_ADC_DATA_ALIGN_RIGHT; + pADC_InitStruct->LowPowerMode = LL_ADC_LP_MODE_NONE; + +} + +/** + * @brief Initialize 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_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 series. 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. + * @note After using this function, other features must be configured + * using LL unitary functions. + * The minimum configuration remaining to be done is: + * - Set ADC group regular or group injected sequencer: + * map channel on the selected sequencer rank. + * Refer to function @ref LL_ADC_REG_SetSequencerRanks(). + * - Set ADC channel sampling time + * Refer to function LL_ADC_SetChannelSamplingTime(); + * @param ADCx ADC instance + * @param pADC_RegInitStruct Pointer to a @ref LL_ADC_REG_InitTypeDef structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: ADC registers are initialized + * - ERROR: ADC registers are not initialized + */ +ErrorStatus LL_ADC_REG_Init(ADC_TypeDef *ADCx, const LL_ADC_REG_InitTypeDef *pADC_RegInitStruct) +{ + ErrorStatus status = SUCCESS; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(ADCx)); + assert_param(IS_LL_ADC_REG_TRIG_SOURCE(pADC_RegInitStruct->TriggerSource)); + assert_param(IS_LL_ADC_REG_SEQ_SCAN_LENGTH(pADC_RegInitStruct->SequencerLength)); + if (pADC_RegInitStruct->SequencerLength != LL_ADC_REG_SEQ_SCAN_DISABLE) + { + assert_param(IS_LL_ADC_REG_SEQ_SCAN_DISCONT_MODE(pADC_RegInitStruct->SequencerDiscont)); + + /* ADC group regular continuous mode and discontinuous mode */ + /* can not be enabled simultenaeously */ + assert_param((pADC_RegInitStruct->ContinuousMode == LL_ADC_REG_CONV_SINGLE) + || (pADC_RegInitStruct->SequencerDiscont == LL_ADC_REG_SEQ_DISCONT_DISABLE)); + } + assert_param(IS_LL_ADC_REG_CONTINUOUS_MODE(pADC_RegInitStruct->ContinuousMode)); + assert_param(IS_LL_ADC_REG_DMA_TRANSFER(pADC_RegInitStruct->DMATransfer)); + assert_param(IS_LL_ADC_REG_OVR_DATA_BEHAVIOR(pADC_RegInitStruct->Overrun)); + + /* Note: Hardware constraint (refer to description of this function): */ + /* ADC instance must be disabled. */ + if (LL_ADC_IsEnabled(ADCx) == 0UL) + { + /* Configuration of ADC hierarchical scope: */ + /* - ADC group regular */ + /* - Set ADC group regular trigger source */ + /* - Set ADC group regular sequencer length */ + /* - Set ADC group regular sequencer discontinuous mode */ + /* - Set ADC group regular continuous mode */ + /* - Set ADC group regular conversion data transfer: no transfer or */ + /* transfer by DMA, and DMA requests mode */ + /* - Set ADC group regular overrun behavior */ + /* Note: On this STM32 series, ADC trigger edge is set to value 0x0 by */ + /* setting of trigger source to SW start. */ + if (pADC_RegInitStruct->SequencerLength != LL_ADC_REG_SEQ_SCAN_DISABLE) + { + MODIFY_REG(ADCx->CFGR, + ADC_CFGR_EXTSEL + | ADC_CFGR_EXTEN + | ADC_CFGR_DISCEN + | ADC_CFGR_DISCNUM + | ADC_CFGR_CONT + | ADC_CFGR_DMAEN + | ADC_CFGR_DMACFG + | ADC_CFGR_OVRMOD + , + pADC_RegInitStruct->TriggerSource + | pADC_RegInitStruct->SequencerDiscont + | pADC_RegInitStruct->ContinuousMode + | pADC_RegInitStruct->DMATransfer + | pADC_RegInitStruct->Overrun + ); + } + else + { + MODIFY_REG(ADCx->CFGR, + ADC_CFGR_EXTSEL + | ADC_CFGR_EXTEN + | ADC_CFGR_DISCEN + | ADC_CFGR_DISCNUM + | ADC_CFGR_CONT + | ADC_CFGR_DMAEN + | ADC_CFGR_DMACFG + | ADC_CFGR_OVRMOD + , + pADC_RegInitStruct->TriggerSource + | LL_ADC_REG_SEQ_DISCONT_DISABLE + | pADC_RegInitStruct->ContinuousMode + | pADC_RegInitStruct->DMATransfer + | pADC_RegInitStruct->Overrun + ); + } + + /* Set ADC group regular sequencer length and scan direction */ + LL_ADC_REG_SetSequencerLength(ADCx, pADC_RegInitStruct->SequencerLength); + } + else + { + /* Initialization error: ADC instance is not disabled. */ + status = ERROR; + } + return status; +} + +/** + * @brief Set each @ref LL_ADC_REG_InitTypeDef field to default value. + * @param pADC_RegInitStruct Pointer to a @ref LL_ADC_REG_InitTypeDef structure + * whose fields will be set to default values. + * @retval None + */ +void LL_ADC_REG_StructInit(LL_ADC_REG_InitTypeDef *pADC_RegInitStruct) +{ + /* Set pADC_RegInitStruct fields to default values */ + /* Set fields of ADC group regular */ + /* Note: On this STM32 series, ADC trigger edge is set to value 0x0 by */ + /* setting of trigger source to SW start. */ + pADC_RegInitStruct->TriggerSource = LL_ADC_REG_TRIG_SOFTWARE; + pADC_RegInitStruct->SequencerLength = LL_ADC_REG_SEQ_SCAN_DISABLE; + pADC_RegInitStruct->SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE; + pADC_RegInitStruct->ContinuousMode = LL_ADC_REG_CONV_SINGLE; + pADC_RegInitStruct->DMATransfer = LL_ADC_REG_DMA_TRANSFER_NONE; + pADC_RegInitStruct->Overrun = LL_ADC_REG_OVR_DATA_OVERWRITTEN; +} + +/** + * @brief Initialize 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_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 series. 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. + * @note After using this function, other features must be configured + * using LL unitary functions. + * The minimum configuration remaining to be done is: + * - Set ADC group injected sequencer: + * map channel on the selected sequencer rank. + * Refer to function @ref LL_ADC_INJ_SetSequencerRanks(). + * - Set ADC channel sampling time + * Refer to function LL_ADC_SetChannelSamplingTime(); + * @note Caution if feature ADC group injected contexts queue is enabled + * (refer to with function @ref LL_ADC_INJ_SetQueueMode() ): + * using successively several times this function will appear as + * having no effect. + * To set several features of ADC group injected, use + * function @ref LL_ADC_INJ_ConfigQueueContext(). + * @param ADCx ADC instance + * @param pADC_InjInitStruct Pointer to a @ref LL_ADC_INJ_InitTypeDef structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: ADC registers are initialized + * - ERROR: ADC registers are not initialized + */ +ErrorStatus LL_ADC_INJ_Init(ADC_TypeDef *ADCx, const LL_ADC_INJ_InitTypeDef *pADC_InjInitStruct) +{ + ErrorStatus status = SUCCESS; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(ADCx)); + assert_param(IS_LL_ADC_INJ_TRIG_SOURCE(pADC_InjInitStruct->TriggerSource)); + assert_param(IS_LL_ADC_INJ_SEQ_SCAN_LENGTH(pADC_InjInitStruct->SequencerLength)); + if (pADC_InjInitStruct->SequencerLength != LL_ADC_INJ_SEQ_SCAN_DISABLE) + { + assert_param(IS_LL_ADC_INJ_SEQ_SCAN_DISCONT_MODE(pADC_InjInitStruct->SequencerDiscont)); + } + assert_param(IS_LL_ADC_INJ_TRIG_AUTO(pADC_InjInitStruct->TrigAuto)); + + /* Note: Hardware constraint (refer to description of this function): */ + /* ADC instance must be disabled. */ + if (LL_ADC_IsEnabled(ADCx) == 0UL) + { + /* Configuration of ADC hierarchical scope: */ + /* - ADC group injected */ + /* - Set ADC group injected trigger source */ + /* - Set ADC group injected sequencer length */ + /* - Set ADC group injected sequencer discontinuous mode */ + /* - Set ADC group injected conversion trigger: independent or */ + /* from ADC group regular */ + /* Note: On this STM32 series, ADC trigger edge is set to value 0x0 by */ + /* setting of trigger source to SW start. */ + if (pADC_InjInitStruct->SequencerLength != LL_ADC_REG_SEQ_SCAN_DISABLE) + { + MODIFY_REG(ADCx->CFGR, + ADC_CFGR_JDISCEN + | ADC_CFGR_JAUTO + , + pADC_InjInitStruct->SequencerDiscont + | pADC_InjInitStruct->TrigAuto + ); + } + else + { + MODIFY_REG(ADCx->CFGR, + ADC_CFGR_JDISCEN + | ADC_CFGR_JAUTO + , + LL_ADC_REG_SEQ_DISCONT_DISABLE + | pADC_InjInitStruct->TrigAuto + ); + } + + MODIFY_REG(ADCx->JSQR, + ADC_JSQR_JEXTSEL + | ADC_JSQR_JEXTEN + | ADC_JSQR_JL + , + pADC_InjInitStruct->TriggerSource + | pADC_InjInitStruct->SequencerLength + ); + } + else + { + /* Initialization error: ADC instance is not disabled. */ + status = ERROR; + } + return status; +} + +/** + * @brief Set each @ref LL_ADC_INJ_InitTypeDef field to default value. + * @param pADC_InjInitStruct Pointer to a @ref LL_ADC_INJ_InitTypeDef structure + * whose fields will be set to default values. + * @retval None + */ +void LL_ADC_INJ_StructInit(LL_ADC_INJ_InitTypeDef *pADC_InjInitStruct) +{ + /* Set pADC_InjInitStruct fields to default values */ + /* Set fields of ADC group injected */ + pADC_InjInitStruct->TriggerSource = LL_ADC_INJ_TRIG_SOFTWARE; + pADC_InjInitStruct->SequencerLength = LL_ADC_INJ_SEQ_SCAN_DISABLE; + pADC_InjInitStruct->SequencerDiscont = LL_ADC_INJ_SEQ_DISCONT_DISABLE; + pADC_InjInitStruct->TrigAuto = LL_ADC_INJ_TRIG_INDEPENDENT; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* ADC1 || ADC2 */ + +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_comp.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_comp.c new file mode 100644 index 0000000000..33f55f42fc --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_comp.c @@ -0,0 +1,260 @@ +/** + ********************************************************************************************************************** + * @file stm32h5xx_ll_comp.c + * @author MCD Application Team + * @brief COMP LL module driver + ********************************************************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ********************************************************************************************************************** + */ +#if defined(USE_FULL_LL_DRIVER) + +/* Includes ----------------------------------------------------------------------------------------------------------*/ +#include "stm32h5xx_ll_comp.h" + +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (COMP1) + +/** @addtogroup COMP_LL COMP + * @{ + */ + +/* Private types -----------------------------------------------------------------------------------------------------*/ +/* Private variables -------------------------------------------------------------------------------------------------*/ +/* Private constants -------------------------------------------------------------------------------------------------*/ +/* Private macros ----------------------------------------------------------------------------------------------------*/ + +/** @addtogroup COMP_LL_Private_Macros + * @{ + */ + +/* Check of parameters for configuration of COMP hierarchical scope: */ +/* COMP instance. */ + +#define IS_LL_COMP_POWER_MODE(__POWER_MODE__) \ + (((__POWER_MODE__) == LL_COMP_POWERMODE_HIGHSPEED) \ + || ((__POWER_MODE__) == LL_COMP_POWERMODE_MEDIUMSPEED) \ + || ((__POWER_MODE__) == LL_COMP_POWERMODE_ULTRALOWPOWER) \ + ) + +/* Note: On this STM32 series, comparator input plus parameters are */ +/* the same on all COMP instances. */ +/* However, comparator instance kept as macro parameter for */ +/* compatibility with other STM32 families. */ +#define IS_LL_COMP_INPUT_PLUS(__COMP_INSTANCE__, __INPUT_PLUS__) \ + (((__INPUT_PLUS__) == LL_COMP_INPUT_PLUS_IO1) \ + || ((__INPUT_PLUS__) == LL_COMP_INPUT_PLUS_IO2) \ + || ((__INPUT_PLUS__) == LL_COMP_INPUT_PLUS_IO3) \ + || ((__INPUT_PLUS__) == LL_COMP_INPUT_PLUS_DAC1_CH1)) + + +/* Note: On this STM32 series, comparator input minus parameters are */ +/* the same on all COMP instances. */ +/* However, comparator instance kept as macro parameter for */ +/* compatibility with other STM32 families. */ +#define IS_LL_COMP_INPUT_MINUS(__COMP_INSTANCE__, __INPUT_MINUS__) \ + (((__INPUT_MINUS__) == LL_COMP_INPUT_MINUS_1_4VREFINT) \ + || ((__INPUT_MINUS__) == LL_COMP_INPUT_MINUS_1_2VREFINT) \ + || ((__INPUT_MINUS__) == LL_COMP_INPUT_MINUS_3_4VREFINT) \ + || ((__INPUT_MINUS__) == LL_COMP_INPUT_MINUS_VREFINT) \ + || ((__INPUT_MINUS__) == LL_COMP_INPUT_MINUS_DAC1_CH1) \ + || ((__INPUT_MINUS__) == LL_COMP_INPUT_MINUS_IO1) \ + || ((__INPUT_MINUS__) == LL_COMP_INPUT_MINUS_IO2) \ + || ((__INPUT_MINUS__) == LL_COMP_INPUT_MINUS_IO3) \ + || ((__INPUT_MINUS__) == LL_COMP_INPUT_MINUS_TEMPSENSOR) \ + || ((__INPUT_MINUS__) == LL_COMP_INPUT_MINUS_VBAT)) + + +#define IS_LL_COMP_INPUT_HYSTERESIS(__INPUT_HYSTERESIS__) \ + (((__INPUT_HYSTERESIS__) == LL_COMP_HYSTERESIS_NONE) \ + || ((__INPUT_HYSTERESIS__) == LL_COMP_HYSTERESIS_LOW) \ + || ((__INPUT_HYSTERESIS__) == LL_COMP_HYSTERESIS_MEDIUM) \ + || ((__INPUT_HYSTERESIS__) == LL_COMP_HYSTERESIS_HIGH) \ + ) + +#define IS_LL_COMP_OUTPUT_POLARITY(__POLARITY__) \ + (((__POLARITY__) == LL_COMP_OUTPUTPOL_NONINVERTED) \ + || ((__POLARITY__) == LL_COMP_OUTPUTPOL_INVERTED) \ + ) + +#define IS_LL_COMP_OUTPUT_BLANKING_SOURCE(__COMP_INSTANCE__, __OUTPUT_BLANKING_SOURCE__) \ + (((__OUTPUT_BLANKING_SOURCE__) == LL_COMP_BLANKINGSRC_NONE) \ + || ((__OUTPUT_BLANKING_SOURCE__) == LL_COMP_BLANKINGSRC_TIM1_OC5) \ + || ((__OUTPUT_BLANKING_SOURCE__) == LL_COMP_BLANKINGSRC_TIM2_OC3) \ + || ((__OUTPUT_BLANKING_SOURCE__) == LL_COMP_BLANKINGSRC_TIM3_OC3) \ + || ((__OUTPUT_BLANKING_SOURCE__) == LL_COMP_BLANKINGSRC_TIM3_OC4) \ + || ((__OUTPUT_BLANKING_SOURCE__) == LL_COMP_BLANKINGSRC_LPTIM1_OC2) \ + || ((__OUTPUT_BLANKING_SOURCE__) == LL_COMP_BLANKINGSRC_LPTIM2_OC2) \ + ) + +/** + * @} + */ + + +/* Private function prototypes ---------------------------------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------------------------------------------------*/ +/** @addtogroup COMP_LL_Exported_Functions + * @{ + */ + +/** @addtogroup COMP_LL_EF_Init + * @{ + */ + +/** + * @brief De-initialize registers of the selected COMP instance + * to their default reset values. + * @note If comparator is locked, de-initialization by software is + * not possible. + * The only way to unlock the comparator is a device hardware reset. + * @param COMPx COMP instance + * @retval An ErrorStatus enumeration value: + * - SUCCESS: COMP registers are de-initialized + * - ERROR: COMP registers are not de-initialized + */ +ErrorStatus LL_COMP_DeInit(COMP_TypeDef *COMPx) +{ + ErrorStatus status = SUCCESS; + + /* Check the parameters */ + assert_param(IS_COMP_ALL_INSTANCE(COMPx)); + + /* Note: Hardware constraint (refer to description of this function): */ + /* COMP instance must not be locked. */ + if (LL_COMP_IsLocked(COMPx) == 0UL) + { + LL_COMP_WriteReg(COMPx, CFGR1, 0x00000000UL); + LL_COMP_WriteReg(COMPx, CFGR2, 0x00000000UL); + } + else + { + /* Comparator instance is locked: de-initialization by software is */ + /* not possible. */ + /* The only way to unlock the comparator is a device hardware reset. */ + status = ERROR; + } + + return status; +} + +/** + * @brief Initialize some features of COMP instance. + * @note This function configures features of the selected COMP instance. + * Some features are also available at scope COMP common instance + * (common to several COMP instances). + * Refer to functions having argument "COMPxy_COMMON" as parameter. + * @param COMPx COMP instance + * @param COMP_InitStruct Pointer to a @ref LL_COMP_InitTypeDef structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: COMP registers are initialized + * - ERROR: COMP registers are not initialized + */ +ErrorStatus LL_COMP_Init(COMP_TypeDef *COMPx, const LL_COMP_InitTypeDef *COMP_InitStruct) +{ + ErrorStatus status = SUCCESS; + + /* Check the parameters */ + assert_param(IS_COMP_ALL_INSTANCE(COMPx)); + assert_param(IS_LL_COMP_POWER_MODE(COMP_InitStruct->PowerMode)); + assert_param(IS_LL_COMP_INPUT_PLUS(COMPx, COMP_InitStruct->InputPlus)); + assert_param(IS_LL_COMP_INPUT_MINUS(COMPx, COMP_InitStruct->InputMinus)); + assert_param(IS_LL_COMP_INPUT_HYSTERESIS(COMP_InitStruct->InputHysteresis)); + assert_param(IS_LL_COMP_OUTPUT_POLARITY(COMP_InitStruct->OutputPolarity)); + assert_param(IS_LL_COMP_OUTPUT_BLANKING_SOURCE(COMPx, COMP_InitStruct->OutputBlankingSource)); + + /* Note: Hardware constraint (refer to description of this function) */ + /* COMP instance must not be locked. */ + if (LL_COMP_IsLocked(COMPx) == 0UL) + { + /* Configuration of comparator instance : */ + /* - PowerMode */ + /* - InputPlus */ + /* - InputMinus */ + /* - InputHysteresis */ + /* - OutputPolarity */ + /* - OutputBlankingSource */ + MODIFY_REG(COMPx->CFGR1, + COMP_CFGR1_PWRMODE + | COMP_CFGR1_INPSEL1 + | COMP_CFGR1_INPSEL2 + | COMP_CFGR1_SCALEN + | COMP_CFGR1_BRGEN + | COMP_CFGR1_INMSEL + | COMP_CFGR1_HYST + | COMP_CFGR1_POLARITY + | COMP_CFGR1_BLANKING + , + COMP_InitStruct->PowerMode + | COMP_InitStruct->InputPlus + | COMP_InitStruct->InputMinus + | COMP_InitStruct->InputHysteresis + | COMP_InitStruct->OutputPolarity + | COMP_InitStruct->OutputBlankingSource + ); + + MODIFY_REG(COMPx->CFGR2, COMP_CFGR2_INPSEL0, + ((COMP_InitStruct->InputPlus == LL_COMP_INPUT_PLUS_IO2) ? COMP_CFGR2_INPSEL0 : 0U)); + } + else + { + /* Initialization error: COMP instance is locked */ + status = ERROR; + } + + return status; +} + +/** + * @brief Set each @ref LL_COMP_InitTypeDef field to default value. + * @param COMP_InitStruct Pointer to a @ref LL_COMP_InitTypeDef structure + * whose fields will be set to default values. + * @retval None + */ +void LL_COMP_StructInit(LL_COMP_InitTypeDef *COMP_InitStruct) +{ + /* Set COMP_InitStruct fields to default values */ + COMP_InitStruct->PowerMode = LL_COMP_POWERMODE_ULTRALOWPOWER; + COMP_InitStruct->InputPlus = LL_COMP_INPUT_PLUS_IO1; + COMP_InitStruct->InputMinus = LL_COMP_INPUT_MINUS_VREFINT; + COMP_InitStruct->InputHysteresis = LL_COMP_HYSTERESIS_NONE; + COMP_InitStruct->OutputPolarity = LL_COMP_OUTPUTPOL_NONINVERTED; + COMP_InitStruct->OutputBlankingSource = LL_COMP_BLANKINGSRC_NONE; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* COMP1 */ + +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_cordic.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_cordic.c new file mode 100644 index 0000000000..c02b4ebbd2 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_cordic.c @@ -0,0 +1,102 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_cordic.c + * @author MCD Application Team + * @brief CORDIC LL module driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +#if defined(USE_FULL_LL_DRIVER) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_cordic.h" +#include "stm32h5xx_ll_bus.h" +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined(CORDIC) + +/** @addtogroup CORDIC_LL + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup CORDIC_LL_Exported_Functions + * @{ + */ + +/** @addtogroup CORDIC_LL_EF_Init + * @{ + */ + +/** + * @brief De-Initialize CORDIC peripheral registers to their default reset values. + * @param CORDICx CORDIC Instance + * @retval An ErrorStatus enumeration value: + * - SUCCESS: CORDIC registers are de-initialized + * - ERROR: CORDIC registers are not de-initialized + */ +ErrorStatus LL_CORDIC_DeInit(const CORDIC_TypeDef *CORDICx) +{ + ErrorStatus status = SUCCESS; + + /* Check the parameters */ + assert_param(IS_CORDIC_ALL_INSTANCE(CORDICx)); + + if (CORDICx == CORDIC) + { + /* Force CORDIC reset */ + LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_CORDIC); + + /* Release CORDIC reset */ + LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_CORDIC); + } + else + { + status = ERROR; + } + + return (status); +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined(CORDIC) */ + +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_crc.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_crc.c new file mode 100644 index 0000000000..e7019ddf98 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_crc.c @@ -0,0 +1,103 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_crc.c + * @author MCD Application Team + * @brief CRC LL module driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +#if defined(USE_FULL_LL_DRIVER) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_crc.h" +#include "stm32h5xx_ll_bus.h" + +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (CRC) + +/** @addtogroup CRC_LL + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup CRC_LL_Exported_Functions + * @{ + */ + +/** @addtogroup CRC_LL_EF_Init + * @{ + */ + +/** + * @brief De-initialize CRC registers (Registers restored to their default values). + * @param CRCx CRC Instance + * @retval An ErrorStatus enumeration value: + * - SUCCESS: CRC registers are de-initialized + * - ERROR: CRC registers are not de-initialized + */ +ErrorStatus LL_CRC_DeInit(const CRC_TypeDef *CRCx) +{ + ErrorStatus status = SUCCESS; + + /* Check the parameters */ + assert_param(IS_CRC_ALL_INSTANCE(CRCx)); + + if (CRCx == CRC) + { + /* Force CRC reset */ + LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_CRC); + + /* Release CRC reset */ + LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_CRC); + } + else + { + status = ERROR; + } + + return (status); +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined (CRC) */ + +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_crs.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_crs.c new file mode 100644 index 0000000000..aebb79d09d --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_crs.c @@ -0,0 +1,84 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_crs.h + * @author MCD Application Team + * @brief CRS LL module driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +#if defined(USE_FULL_LL_DRIVER) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_crs.h" +#include "stm32h5xx_ll_bus.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined(CRS) + +/** @defgroup CRS_LL CRS + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup CRS_LL_Exported_Functions + * @{ + */ + +/** @addtogroup CRS_LL_EF_Init + * @{ + */ + +/** + * @brief De-Initializes CRS peripheral registers to their default reset values. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: CRS registers are de-initialized + * - ERROR: not applicable + */ +ErrorStatus LL_CRS_DeInit(void) +{ + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_CRS); + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_CRS); + + return SUCCESS; +} + + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined(CRS) */ + +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_dac.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_dac.c new file mode 100644 index 0000000000..4583232d48 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_dac.c @@ -0,0 +1,312 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_dac.c + * @author MCD Application Team + * @brief DAC LL module driver + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +#if defined(USE_FULL_LL_DRIVER) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_dac.h" +#include "stm32h5xx_ll_bus.h" + +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined(DAC1) + +/** @addtogroup DAC_LL DAC + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ + +/** @addtogroup DAC_LL_Private_Macros + * @{ + */ +#define IS_LL_DAC_CHANNEL(__DAC_CHANNEL__) \ + (((__DAC_CHANNEL__) == LL_DAC_CHANNEL_1) \ + || ((__DAC_CHANNEL__) == LL_DAC_CHANNEL_2) \ + ) + +#if defined(TIM8) +/* Devices STM32H563/H573xx */ +#define IS_LL_DAC_TRIGGER_SOURCE(__TRIGGER_SOURCE__) \ + ( ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM1_TRGO) \ + || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM2_TRGO) \ + || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM4_TRGO) \ + || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM5_TRGO) \ + || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM6_TRGO) \ + || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM7_TRGO) \ + || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM8_TRGO) \ + || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM15_TRGO) \ + || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_LPTIM1_CH1) \ + || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_LPTIM2_CH1) \ + || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_EXTI_LINE9) \ + || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_SOFTWARE) \ + ) +#else +/* Devices STM32H503xx */ +#define IS_LL_DAC_TRIGGER_SOURCE(__TRIGGER_SOURCE__) \ + ( ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM1_TRGO) \ + || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM2_TRGO) \ + || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM3_TRGO) \ + || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM6_TRGO) \ + || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_TIM7_TRGO) \ + || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_LPTIM1_CH1) \ + || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_LPTIM2_CH1) \ + || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_EXT_EXTI_LINE9) \ + || ((__TRIGGER_SOURCE__) == LL_DAC_TRIG_SOFTWARE) \ + ) +#endif /* Devices STM32H563/H573xx or STM32H503xx */ + +#define IS_LL_DAC_WAVE_AUTO_GENER_MODE(__WAVE_AUTO_GENERATION_MODE__) \ + (((__WAVE_AUTO_GENERATION_MODE__) == LL_DAC_WAVE_AUTO_GENERATION_NONE) \ + || ((__WAVE_AUTO_GENERATION_MODE__) == LL_DAC_WAVE_AUTO_GENERATION_NOISE) \ + || ((__WAVE_AUTO_GENERATION_MODE__) == LL_DAC_WAVE_AUTO_GENERATION_TRIANGLE) \ + ) + +#define IS_LL_DAC_WAVE_AUTO_GENER_CONFIG(__WAVE_AUTO_GENERATION_MODE__, __WAVE_AUTO_GENERATION_CONFIG__) \ + ( (((__WAVE_AUTO_GENERATION_MODE__) == LL_DAC_WAVE_AUTO_GENERATION_NOISE) \ + && (((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BIT0) \ + || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS1_0) \ + || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS2_0) \ + || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS3_0) \ + || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS4_0) \ + || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS5_0) \ + || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS6_0) \ + || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS7_0) \ + || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS8_0) \ + || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS9_0) \ + || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS10_0) \ + || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_NOISE_LFSR_UNMASK_BITS11_0)) \ + ) \ + ||(((__WAVE_AUTO_GENERATION_MODE__) == LL_DAC_WAVE_AUTO_GENERATION_TRIANGLE) \ + && (((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_1) \ + || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_3) \ + || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_7) \ + || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_15) \ + || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_31) \ + || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_63) \ + || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_127) \ + || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_255) \ + || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_511) \ + || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_1023) \ + || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_2047) \ + || ((__WAVE_AUTO_GENERATION_CONFIG__) == LL_DAC_TRIANGLE_AMPLITUDE_4095)) \ + ) \ + ) + +#define IS_LL_DAC_OUTPUT_BUFFER(__OUTPUT_BUFFER__) \ + (((__OUTPUT_BUFFER__) == LL_DAC_OUTPUT_BUFFER_ENABLE) \ + || ((__OUTPUT_BUFFER__) == LL_DAC_OUTPUT_BUFFER_DISABLE) \ + ) + +#define IS_LL_DAC_OUTPUT_CONNECTION(__OUTPUT_CONNECTION__) \ + (((__OUTPUT_CONNECTION__) == LL_DAC_OUTPUT_CONNECT_GPIO) \ + || ((__OUTPUT_CONNECTION__) == LL_DAC_OUTPUT_CONNECT_INTERNAL) \ + ) + +#define IS_LL_DAC_OUTPUT_MODE(__OUTPUT_MODE__) \ + (((__OUTPUT_MODE__) == LL_DAC_OUTPUT_MODE_NORMAL) \ + || ((__OUTPUT_MODE__) == LL_DAC_OUTPUT_MODE_SAMPLE_AND_HOLD) \ + ) + +/** + * @} + */ + + +/* Private function prototypes -----------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup DAC_LL_Exported_Functions + * @{ + */ + +/** @addtogroup DAC_LL_EF_Init + * @{ + */ + +/** + * @brief De-initialize registers of the selected DAC instance + * to their default reset values. + * @param DACx DAC instance + * @retval An ErrorStatus enumeration value: + * - SUCCESS: DAC registers are de-initialized + * - ERROR: not applicable + */ +ErrorStatus LL_DAC_DeInit(const DAC_TypeDef *DACx) +{ + /* Check the parameters */ + assert_param(IS_DAC_ALL_INSTANCE(DACx)); + +#ifdef DAC1 + /* Force reset of DAC clock */ + LL_AHB2_GRP1_ForceReset(LL_AHB2_GRP1_PERIPH_DAC1); + + /* Release reset of DAC clock */ + LL_AHB2_GRP1_ReleaseReset(LL_AHB2_GRP1_PERIPH_DAC1); +#endif /* DAC1 */ + + return SUCCESS; +} + +/** + * @brief Initialize some features of DAC channel. + * @note @ref LL_DAC_Init() aims to ease basic configuration of a DAC channel. + * Leaving it ready to be enabled and output: + * a level by calling one of + * @ref LL_DAC_ConvertData12RightAligned + * @ref LL_DAC_ConvertData12LeftAligned + * @ref LL_DAC_ConvertData8RightAligned + * or one of the supported autogenerated wave. + * @note This function allows configuration of: + * - Output mode + * - Trigger + * - Wave generation + * @note The setting of these parameters by function @ref LL_DAC_Init() + * is conditioned to DAC state: + * DAC channel must be disabled. + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 + * @param DAC_InitStruct Pointer to a @ref LL_DAC_InitTypeDef structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: DAC registers are initialized + * - ERROR: DAC registers are not initialized + */ +ErrorStatus LL_DAC_Init(DAC_TypeDef *DACx, uint32_t DAC_Channel, const LL_DAC_InitTypeDef *DAC_InitStruct) +{ + ErrorStatus status = SUCCESS; + + /* Check the parameters */ + assert_param(IS_DAC_ALL_INSTANCE(DACx)); + assert_param(IS_LL_DAC_CHANNEL(DAC_Channel)); + assert_param(IS_LL_DAC_TRIGGER_SOURCE(DAC_InitStruct->TriggerSource)); + assert_param(IS_LL_DAC_OUTPUT_BUFFER(DAC_InitStruct->OutputBuffer)); + assert_param(IS_LL_DAC_OUTPUT_CONNECTION(DAC_InitStruct->OutputConnection)); + assert_param(IS_LL_DAC_OUTPUT_MODE(DAC_InitStruct->OutputMode)); + assert_param(IS_LL_DAC_WAVE_AUTO_GENER_MODE(DAC_InitStruct->WaveAutoGeneration)); + if (DAC_InitStruct->WaveAutoGeneration != LL_DAC_WAVE_AUTO_GENERATION_NONE) + { + assert_param(IS_LL_DAC_WAVE_AUTO_GENER_CONFIG(DAC_InitStruct->WaveAutoGeneration, + DAC_InitStruct->WaveAutoGenerationConfig)); + } + + /* Note: Hardware constraint (refer to description of this function) */ + /* DAC instance must be disabled. */ + if (LL_DAC_IsEnabled(DACx, DAC_Channel) == 0UL) + { + /* Configuration of DAC channel: */ + /* - TriggerSource */ + /* - WaveAutoGeneration */ + /* - OutputBuffer */ + /* - OutputConnection */ + /* - OutputMode */ + if (DAC_InitStruct->WaveAutoGeneration != LL_DAC_WAVE_AUTO_GENERATION_NONE) + { + MODIFY_REG(DACx->CR, + (DAC_CR_TSEL1 + | DAC_CR_WAVE1 + | DAC_CR_MAMP1 + ) << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK) + , + (DAC_InitStruct->TriggerSource + | DAC_InitStruct->WaveAutoGeneration + | DAC_InitStruct->WaveAutoGenerationConfig + ) << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK) + ); + } + else + { + MODIFY_REG(DACx->CR, + (DAC_CR_TSEL1 + | DAC_CR_WAVE1 + ) << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK) + , + (DAC_InitStruct->TriggerSource + | LL_DAC_WAVE_AUTO_GENERATION_NONE + ) << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK) + ); + } + MODIFY_REG(DACx->MCR, + (DAC_MCR_MODE1_1 + | DAC_MCR_MODE1_0 + | DAC_MCR_MODE1_2 + ) << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK) + , + (DAC_InitStruct->OutputBuffer + | DAC_InitStruct->OutputConnection + | DAC_InitStruct->OutputMode + ) << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK) + ); + } + else + { + /* Initialization error: DAC instance is not disabled. */ + status = ERROR; + } + return status; +} + +/** + * @brief Set each @ref LL_DAC_InitTypeDef field to default value. + * @param DAC_InitStruct pointer to a @ref LL_DAC_InitTypeDef structure + * whose fields will be set to default values. + * @retval None + */ +void LL_DAC_StructInit(LL_DAC_InitTypeDef *DAC_InitStruct) +{ + /* Set DAC_InitStruct fields to default values */ + DAC_InitStruct->TriggerSource = LL_DAC_TRIG_SOFTWARE; + DAC_InitStruct->WaveAutoGeneration = LL_DAC_WAVE_AUTO_GENERATION_NONE; + /* Note: Parameter discarded if wave auto generation is disabled, */ + /* set anyway to its default value. */ + DAC_InitStruct->WaveAutoGenerationConfig = LL_DAC_NOISE_LFSR_UNMASK_BIT0; + DAC_InitStruct->OutputBuffer = LL_DAC_OUTPUT_BUFFER_ENABLE; + DAC_InitStruct->OutputConnection = LL_DAC_OUTPUT_CONNECT_GPIO; + DAC_InitStruct->OutputMode = LL_DAC_OUTPUT_MODE_NORMAL; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* DAC1 */ + +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_dlyb.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_dlyb.c new file mode 100644 index 0000000000..cfb8510a35 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_dlyb.c @@ -0,0 +1,243 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_dlyb.c + * @author MCD Application Team + * @brief DelayBlock Low Layer HAL module driver. + * + * This file provides firmware functions to manage the following + * functionalities of the DelayBlock peripheral: + * + input clock frequency + * + up to 12 oversampling phases + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### DelayBlock peripheral features ##### + ============================================================================== + [..] The DelayBlock is used to generate an Output clock which is de-phased from the Input + clock. The phase of the Output clock is programmed by FW. The Output clock is then used + to clock the receive data in i.e. a SDMMC, OSPI or QSPI interface. + The delay is Voltage and Temperature dependent, which may require FW to do re-tuning + and recenter the Output clock phase to the receive data. + + [..] The DelayBlock features include the following: + (+) Input clock frequency. + (+) Up to 12 oversampling phases. + + ##### How to use this driver ##### + ============================================================================== + [..] + This driver is a considered as a driver of service for external devices drivers + that interfaces with the DELAY peripheral. + The LL_DLYB_SetDelay() function, configure the Delay value configured on SEL and UNIT. + The LL_DLYB_GetDelay() function, return the Delay value configured on SEL and UNIT. + The LL_DLYB_GetClockPeriod()function, get the clock period. + + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +/** @defgroup DLYB_LL DLYB + * @brief DLYB LL module driver. + * @{ + */ + +#if defined(HAL_SD_MODULE_ENABLED) || defined(HAL_OSPI_MODULE_ENABLED) || defined(HAL_XSPI_MODULE_ENABLED) +#if defined (DLYB_SDMMC1) || defined (DLYB_SDMMC2) || defined (DLYB_OCTOSPI1) || defined (DLYB_OCTOSPI2) + +/** + @cond 0 + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define DLYB_TIMEOUT 0xFFU +#define DLYB_LNG_10_0_MASK 0x07FF0000U +#define DLYB_LNG_11_10_MASK 0x0C000000U +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ + +/** + @endcond + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup DLYB_LL_Exported_Functions + * @brief Configuration and control functions + * +@verbatim + =============================================================================== + ##### Control functions ##### + =============================================================================== + [..] This section provides functions allowing to + (+) Control the DLYB. +@endverbatim + * @{ + */ + +/** @addtogroup DLYB_Control_Functions DLYB Control functions + * @{ + */ + +/** + * @brief Set the Delay value configured on SEL and UNIT. + * @param DLYBx: Pointer to DLYB instance. + * @param pdlyb_cfg: Pointer to DLYB configuration structure. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: the Delay value is set. + * - ERROR: the Delay value is not set. + */ +void LL_DLYB_SetDelay(DLYB_TypeDef *DLYBx, LL_DLYB_CfgTypeDef *pdlyb_cfg) +{ + /* Check the DelayBlock instance */ + assert_param(IS_DLYB_ALL_INSTANCE(DLYBx)); + + /* Enable the length sampling */ + SET_BIT(DLYBx->CR, DLYB_CR_SEN); + + /* Update the UNIT and SEL field */ + DLYBx->CFGR = (pdlyb_cfg->PhaseSel) | ((pdlyb_cfg->Units) << DLYB_CFGR_UNIT_Pos); + + /* Disable the length sampling */ + CLEAR_BIT(DLYBx->CR, DLYB_CR_SEN); +} + +/** + * @brief Get the Delay value configured on SEL and UNIT. + * @param DLYBx: Pointer to DLYB instance. + * @param pdlyb_cfg: Pointer to DLYB configuration structure. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: the Delay value is received. + * - ERROR: the Delay value is not received. + */ +void LL_DLYB_GetDelay(DLYB_TypeDef *DLYBx, LL_DLYB_CfgTypeDef *pdlyb_cfg) +{ + /* Check the DelayBlock instance */ + assert_param(IS_DLYB_ALL_INSTANCE(DLYBx)); + + /* Fill the DelayBlock configuration structure with SEL and UNIT value */ + pdlyb_cfg->Units = ((DLYBx->CFGR & DLYB_CFGR_UNIT) >> DLYB_CFGR_UNIT_Pos); + pdlyb_cfg->PhaseSel = (DLYBx->CFGR & DLYB_CFGR_SEL); +} + +/** + * @brief Get the clock period. + * @param DLYBx: Pointer to DLYB instance. + * @param pdlyb_cfg: Pointer to DLYB configuration structure. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: there is a valid period detected and stored in pdlyb_cfg. + * - ERROR: there is no valid period detected. + */ +uint32_t LL_DLYB_GetClockPeriod(DLYB_TypeDef *DLYBx, LL_DLYB_CfgTypeDef *pdlyb_cfg) +{ + uint32_t i = 0U; + uint32_t nb ; + uint32_t lng ; + uint32_t tickstart; + + /* Check the DelayBlock instance */ + assert_param(IS_DLYB_ALL_INSTANCE(DLYBx)); + + /* Enable the length sampling */ + SET_BIT(DLYBx->CR, DLYB_CR_SEN); + + /* Delay line length detection */ + while (i < DLYB_MAX_UNIT) + { + /* Set the Delay of the UNIT(s)*/ + DLYBx->CFGR = DLYB_MAX_SELECT | (i << DLYB_CFGR_UNIT_Pos); + + /* Waiting for a LNG valid value */ + tickstart = HAL_GetTick(); + while ((DLYBx->CFGR & DLYB_CFGR_LNGF) == 0U) + { + if ((HAL_GetTick() - tickstart) >= DLYB_TIMEOUT) + { + /* New check to avoid false timeout detection in case of preemption */ + if ((DLYBx->CFGR & DLYB_CFGR_LNGF) == 0U) + { + return (uint32_t) HAL_TIMEOUT; + } + } + } + + if ((DLYBx->CFGR & DLYB_LNG_10_0_MASK) != 0U) + { + if ((DLYBx->CFGR & (DLYB_CFGR_LNG_11 | DLYB_CFGR_LNG_10)) != DLYB_LNG_11_10_MASK) + { + /* Delay line length is configured to one input clock period*/ + break; + } + } + i++; + } + + if (DLYB_MAX_UNIT != i) + { + /* Determine how many unit delays (nb) span one input clock period */ + lng = (DLYBx->CFGR & DLYB_CFGR_LNG) >> 16U; + nb = 10U; + while ((nb > 0U) && ((lng >> nb) == 0U)) + { + nb--; + } + if (nb != 0U) + { + pdlyb_cfg->PhaseSel = nb ; + pdlyb_cfg->Units = i ; + + /* Disable the length sampling */ + DLYBx->CR = DLYB_CR_SEN; + + return (uint32_t)SUCCESS; + } + } + + /* Disable the length sampling */ + DLYBx->CR = DLYB_CR_SEN; + + return (uint32_t)ERROR; + +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* DLYB_SDMMC1 || DLYB_SDMMC2 || DLYB_OCTOSPI1 || DLYB_OCTOSPI2 */ +#endif /* HAL_SD_MODULE_ENABLED || HAL_OSPI_MODULE_ENABLED || HAL_XSPI_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_dma.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_dma.c new file mode 100644 index 0000000000..4ba1702f56 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_dma.c @@ -0,0 +1,1130 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_dma.c + * @author MCD Application Team + * @brief DMA LL module driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### LL DMA driver acronyms ##### + ============================================================================== + [..] Acronyms table : + ========================================= + || Acronym || || + ========================================= + || SRC || Source || + || DEST || Destination || + || ADDR || Address || + || ADDRS || Addresses || + || INC || Increment / Incremented || + || DEC || Decrement / Decremented || + || BLK || Block || + || RPT || Repeat / Repeated || + || TRIG || Trigger || + ========================================= + @endverbatim + ****************************************************************************** + */ + +#if defined (USE_FULL_LL_DRIVER) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_dma.h" +#include "stm32h5xx_ll_bus.h" +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (GPDMA1) + +/** @addtogroup DMA_LL + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ + +/** @addtogroup DMA_LL_Private_Macros + * @{ + */ +#define IS_LL_DMA_ALL_CHANNEL_INSTANCE(INSTANCE, Channel) ((((INSTANCE) == GPDMA1) && \ + (((Channel) == LL_DMA_CHANNEL_0) || \ + ((Channel) == LL_DMA_CHANNEL_1) || \ + ((Channel) == LL_DMA_CHANNEL_2) || \ + ((Channel) == LL_DMA_CHANNEL_3) || \ + ((Channel) == LL_DMA_CHANNEL_4) || \ + ((Channel) == LL_DMA_CHANNEL_5) || \ + ((Channel) == LL_DMA_CHANNEL_6) || \ + ((Channel) == LL_DMA_CHANNEL_7) || \ + ((Channel) == LL_DMA_CHANNEL_ALL))) || \ + (((INSTANCE) == GPDMA2) && \ + (((Channel) == LL_DMA_CHANNEL_0) || \ + ((Channel) == LL_DMA_CHANNEL_1) || \ + ((Channel) == LL_DMA_CHANNEL_2) || \ + ((Channel) == LL_DMA_CHANNEL_3) || \ + ((Channel) == LL_DMA_CHANNEL_4) || \ + ((Channel) == LL_DMA_CHANNEL_5) || \ + ((Channel) == LL_DMA_CHANNEL_6) || \ + ((Channel) == LL_DMA_CHANNEL_7) || \ + ((Channel) == LL_DMA_CHANNEL_ALL)))) + +#define IS_LL_GPDMA_CHANNEL_INSTANCE(INSTANCE, Channel) ((((INSTANCE) == GPDMA1) && \ + (((Channel) == LL_DMA_CHANNEL_0) || \ + ((Channel) == LL_DMA_CHANNEL_1) || \ + ((Channel) == LL_DMA_CHANNEL_2) || \ + ((Channel) == LL_DMA_CHANNEL_3) || \ + ((Channel) == LL_DMA_CHANNEL_4) || \ + ((Channel) == LL_DMA_CHANNEL_5) || \ + ((Channel) == LL_DMA_CHANNEL_6) || \ + ((Channel) == LL_DMA_CHANNEL_7))) || \ + (((INSTANCE) == GPDMA2) && \ + (((Channel) == LL_DMA_CHANNEL_0) || \ + ((Channel) == LL_DMA_CHANNEL_1) || \ + ((Channel) == LL_DMA_CHANNEL_2) || \ + ((Channel) == LL_DMA_CHANNEL_3) || \ + ((Channel) == LL_DMA_CHANNEL_4) || \ + ((Channel) == LL_DMA_CHANNEL_5) || \ + ((Channel) == LL_DMA_CHANNEL_6) || \ + ((Channel) == LL_DMA_CHANNEL_7)))) + +#define IS_LL_DMA_2D_CHANNEL_INSTANCE(INSTANCE, Channel) ((((INSTANCE) == GPDMA1) && \ + (((Channel) == LL_DMA_CHANNEL_6) || \ + ((Channel) == LL_DMA_CHANNEL_7))) || \ + (((INSTANCE) == GPDMA2) && \ + (((Channel) == LL_DMA_CHANNEL_6) || \ + ((Channel) == LL_DMA_CHANNEL_7)))) + +#define IS_LL_DMA_MODE(__VALUE__) (((__VALUE__) == LL_DMA_NORMAL) || \ + ((__VALUE__) == LL_DMA_PFCTRL)) + +#define IS_LL_DMA_DIRECTION(__VALUE__) (((__VALUE__) == LL_DMA_DIRECTION_MEMORY_TO_MEMORY) || \ + ((__VALUE__) == LL_DMA_DIRECTION_PERIPH_TO_MEMORY) || \ + ((__VALUE__) == LL_DMA_DIRECTION_MEMORY_TO_PERIPH)) + +#define IS_LL_DMA_DATA_ALIGNMENT(__VALUE__) (((__VALUE__) == LL_DMA_DATA_ALIGN_ZEROPADD) || \ + ((__VALUE__) == LL_DMA_DATA_ALIGN_SIGNEXTPADD) || \ + ((__VALUE__) == LL_DMA_DATA_PACK_UNPACK)) + +#define IS_LL_DMA_BURST_LENGTH(__VALUE__) (((__VALUE__) > 0U) && ((__VALUE__) <= 64U)) + +#define IS_LL_DMA_SRC_DATA_WIDTH(__VALUE__) (((__VALUE__) == LL_DMA_SRC_DATAWIDTH_BYTE) || \ + ((__VALUE__) == LL_DMA_SRC_DATAWIDTH_HALFWORD) || \ + ((__VALUE__) == LL_DMA_SRC_DATAWIDTH_WORD)) + +#define IS_LL_DMA_DEST_DATA_WIDTH(__VALUE__) (((__VALUE__) == LL_DMA_DEST_DATAWIDTH_BYTE) || \ + ((__VALUE__) == LL_DMA_DEST_DATAWIDTH_HALFWORD) || \ + ((__VALUE__) == LL_DMA_DEST_DATAWIDTH_WORD)) + +#define IS_LL_DMA_SRC_INCREMENT_MODE(__VALUE__) (((__VALUE__) == LL_DMA_SRC_FIXED) || \ + ((__VALUE__) == LL_DMA_SRC_INCREMENT)) + +#define IS_LL_DMA_DEST_INCREMENT_MODE(__VALUE__) (((__VALUE__) == LL_DMA_DEST_FIXED) || \ + ((__VALUE__) == LL_DMA_DEST_INCREMENT)) + +#define IS_LL_DMA_PRIORITY(__VALUE__) (((__VALUE__) == LL_DMA_LOW_PRIORITY_LOW_WEIGHT) || \ + ((__VALUE__) == LL_DMA_LOW_PRIORITY_MID_WEIGHT) || \ + ((__VALUE__) == LL_DMA_LOW_PRIORITY_HIGH_WEIGHT) || \ + ((__VALUE__) == LL_DMA_HIGH_PRIORITY)) + +#define IS_LL_DMA_BLK_DATALENGTH(__VALUE__) ((__VALUE__) <= 0xFFFFU) + +#define IS_LL_DMA_BLK_REPEATCOUNT(__VALUE__) ((__VALUE__) <= 0x0EFFU) + +#define IS_LL_DMA_TRIGGER_MODE(__VALUE__) (((__VALUE__) == LL_DMA_TRIGM_BLK_TRANSFER) || \ + ((__VALUE__) == LL_DMA_TRIGM_RPT_BLK_TRANSFER) || \ + ((__VALUE__) == LL_DMA_TRIGM_LLI_LINK_TRANSFER) || \ + ((__VALUE__) == LL_DMA_TRIGM_SINGLBURST_TRANSFER )) + +#define IS_LL_DMA_TRIGGER_POLARITY(__VALUE__) (((__VALUE__) == LL_DMA_TRIG_POLARITY_MASKED) || \ + ((__VALUE__) == LL_DMA_TRIG_POLARITY_RISING) || \ + ((__VALUE__) == LL_DMA_TRIG_POLARITY_FALLING)) + +#define IS_LL_DMA_BLKHW_REQUEST(__VALUE__) (((__VALUE__) == LL_DMA_HWREQUEST_SINGLEBURST) || \ + ((__VALUE__) == LL_DMA_HWREQUEST_BLK)) + +#if defined (I3C2) +#define IS_LL_DMA_TRIGGER_SELECTION(__VALUE__) ((__VALUE__) <= LL_GPDMA1_TRIGGER_EVENTOUT) +#else +#define IS_LL_DMA_TRIGGER_SELECTION(__VALUE__) ((__VALUE__) <= LL_GPDMA1_TRIGGER_LPTIM6_CH2) +#endif /* I3C2 */ + +#if defined (I3C2) +#define IS_LL_DMA_REQUEST_SELECTION(__VALUE__) ((__VALUE__) <= LL_GPDMA1_REQUEST_I3C2_RS) +#else +#define IS_LL_DMA_REQUEST_SELECTION(__VALUE__) ((__VALUE__) <= LL_GPDMA1_REQUEST_LPTIM6_UE) +#endif /* I3C2 */ + +#define IS_LL_DMA_TRANSFER_EVENT_MODE(__VALUE__) (((__VALUE__) == LL_DMA_TCEM_BLK_TRANSFER) || \ + ((__VALUE__) == LL_DMA_TCEM_RPT_BLK_TRANSFER) || \ + ((__VALUE__) == LL_DMA_TCEM_EACH_LLITEM_TRANSFER) || \ + ((__VALUE__) == LL_DMA_TCEM_LAST_LLITEM_TRANSFER)) + +#define IS_LL_DMA_DEST_HALFWORD_EXCHANGE(__VALUE__) (((__VALUE__) == LL_DMA_DEST_HALFWORD_PRESERVE) || \ + ((__VALUE__) == LL_DMA_DEST_HALFWORD_EXCHANGE)) + +#define IS_LL_DMA_DEST_BYTE_EXCHANGE(__VALUE__) (((__VALUE__) == LL_DMA_DEST_BYTE_PRESERVE) || \ + ((__VALUE__) == LL_DMA_DEST_BYTE_EXCHANGE)) + +#define IS_LL_DMA_SRC_BYTE_EXCHANGE(__VALUE__) (((__VALUE__) == LL_DMA_SRC_BYTE_PRESERVE) || \ + ((__VALUE__) == LL_DMA_SRC_BYTE_EXCHANGE)) + +#define IS_LL_DMA_LINK_ALLOCATED_PORT(__VALUE__) (((__VALUE__) == LL_DMA_LINK_ALLOCATED_PORT0) || \ + ((__VALUE__) == LL_DMA_LINK_ALLOCATED_PORT1)) + +#define IS_LL_DMA_SRC_ALLOCATED_PORT(__VALUE__) (((__VALUE__) == LL_DMA_SRC_ALLOCATED_PORT0) || \ + ((__VALUE__) == LL_DMA_SRC_ALLOCATED_PORT1)) + +#define IS_LL_DMA_DEST_ALLOCATED_PORT(__VALUE__) (((__VALUE__) == LL_DMA_DEST_ALLOCATED_PORT0) || \ + ((__VALUE__) == LL_DMA_DEST_ALLOCATED_PORT1)) + +#define IS_LL_DMA_LINK_STEP_MODE(__VALUE__) (((__VALUE__) == LL_DMA_LSM_FULL_EXECUTION) || \ + ((__VALUE__) == LL_DMA_LSM_1LINK_EXECUTION)) + +#define IS_LL_DMA_BURST_SRC_ADDR_UPDATE(__VALUE__) (((__VALUE__) == LL_DMA_BURST_SRC_ADDR_INCREMENT) || \ + ((__VALUE__) == LL_DMA_BURST_SRC_ADDR_DECREMENT)) + +#define IS_LL_DMA_BURST_DEST_ADDR_UPDATE(__VALUE__) (((__VALUE__) == LL_DMA_BURST_DEST_ADDR_INCREMENT) || \ + ((__VALUE__) == LL_DMA_BURST_DEST_ADDR_DECREMENT)) + +#define IS_LL_DMA_BURST_ADDR_UPDATE_VALUE(__VALUE__) ((__VALUE__) <= 0x1FFFU) + +#define IS_LL_DMA_BLKRPT_SRC_ADDR_UPDATE(__VALUE__) (((__VALUE__) == LL_DMA_BLKRPT_SRC_ADDR_INCREMENT) || \ + ((__VALUE__) == LL_DMA_BLKRPT_SRC_ADDR_DECREMENT)) + +#define IS_LL_DMA_BLKRPT_DEST_ADDR_UPDATE(__VALUE__) (((__VALUE__) == LL_DMA_BLKRPT_DEST_ADDR_INCREMENT) || \ + ((__VALUE__) == LL_DMA_BLKRPT_DEST_ADDR_DECREMENT)) + +#define IS_LL_DMA_BLKRPT_ADDR_UPDATE_VALUE(__VALUE__) ((__VALUE__) <= 0xFFFFU) + +#define IS_LL_DMA_LINK_BASEADDR(__VALUE__) (((__VALUE__) & 0xFFFFU) == 0U) + +#define IS_LL_DMA_LINK_ADDR_OFFSET(__VALUE__) (((__VALUE__) & 0x03U) == 0U) + +#define IS_LL_DMA_LINK_UPDATE_REGISTERS(__VALUE__) ((((__VALUE__) & 0x01FE0000U) == 0U) && ((__VALUE__) != 0U)) + +#define IS_LL_DMA_LINK_NODETYPE(__VALUE__) (((__VALUE__) == LL_DMA_GPDMA_2D_NODE) || \ + ((__VALUE__) == LL_DMA_GPDMA_LINEAR_NODE)) + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define IS_LL_DMA_CHANNEL_SRC_SEC(__VALUE__) (((__VALUE__) == LL_DMA_CHANNEL_SRC_NSEC) || \ + ((__VALUE__) == LL_DMA_CHANNEL_SRC_SEC)) + +#define IS_LL_DMA_CHANNEL_DEST_SEC(__VALUE__) (((__VALUE__) == LL_DMA_CHANNEL_DEST_NSEC) || \ + ((__VALUE__) == LL_DMA_CHANNEL_DEST_SEC)) +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup DMA_LL_Exported_Functions + * @{ + */ + +/** @addtogroup DMA_LL_EF_Init + * @{ + */ + +/** + * @brief De-initialize the DMA registers to their default reset values. + * @note This API is used for all available DMA channels. + * @note To convert DMAx_Channely Instance to DMAx Instance and Channely, use + * helper macros : + * @arg @ref LL_DMA_GET_INSTANCE + * @arg @ref LL_DMA_GET_CHANNEL + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval An ErrorStatus enumeration value: + * - SUCCESS : DMA registers are de-initialized. + * - ERROR : DMA registers are not de-initialized. + */ +uint32_t LL_DMA_DeInit(DMA_TypeDef *DMAx, uint32_t Channel) +{ + DMA_Channel_TypeDef *tmp; + ErrorStatus status = SUCCESS; + + /* Check the DMA Instance DMAx and Channel parameters */ + assert_param(IS_LL_DMA_ALL_CHANNEL_INSTANCE(DMAx, Channel)); + + if (Channel == LL_DMA_CHANNEL_ALL) + { + if (DMAx == GPDMA1) + { + /* Force reset of DMA clock */ + LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_GPDMA1); + + /* Release reset of DMA clock */ + LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_GPDMA1); + } + else + { + /* Force reset of DMA clock */ + LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_GPDMA2); + + /* Release reset of DMA clock */ + LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_GPDMA2); + } + } + else + { + /* Get the DMA Channel Instance */ + tmp = (DMA_Channel_TypeDef *)(LL_DMA_GET_CHANNEL_INSTANCE(DMAx, Channel)); + + /* Suspend DMA channel */ + LL_DMA_SuspendChannel(DMAx, Channel); + + /* Disable the selected Channel */ + LL_DMA_ResetChannel(DMAx, Channel); + + /* Reset DMAx_Channely control register */ + LL_DMA_WriteReg(tmp, CLBAR, 0U); + + /* Reset DMAx_Channely control register */ + LL_DMA_WriteReg(tmp, CCR, 0U); + + /* Reset DMAx_Channely Configuration register */ + LL_DMA_WriteReg(tmp, CTR1, 0U); + + /* Reset DMAx_Channely transfer register 2 */ + LL_DMA_WriteReg(tmp, CTR2, 0U); + + /* Reset DMAx_Channely block number of data register */ + LL_DMA_WriteReg(tmp, CBR1, 0U); + + /* Reset DMAx_Channely source address register */ + LL_DMA_WriteReg(tmp, CSAR, 0U); + + /* Reset DMAx_Channely destination address register */ + LL_DMA_WriteReg(tmp, CDAR, 0U); + + /* Check DMA channel */ + if (IS_LL_DMA_2D_CHANNEL_INSTANCE(DMAx, Channel) != 0U) + { + /* Reset DMAx_Channely transfer register 3 */ + LL_DMA_WriteReg(tmp, CTR3, 0U); + + /* Reset DMAx_Channely Block register 2 */ + LL_DMA_WriteReg(tmp, CBR2, 0U); + } + + /* Reset DMAx_Channely Linked list address register */ + LL_DMA_WriteReg(tmp, CLLR, 0U); + + /* Reset DMAx_Channely pending flags */ + LL_DMA_WriteReg(tmp, CFCR, 0x00003F00U); + + /* Reset DMAx_Channely attribute */ + LL_DMA_DisableChannelPrivilege(DMAx, Channel); + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + LL_DMA_DisableChannelSecure(DMAx, Channel); +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + } + + return (uint32_t)status; +} + +/** + * @brief Initialize the DMA registers according to the specified parameters + * in DMA_InitStruct. + * @note This API is used for all available DMA channels. + * @note A software request transfer can be done once programming the direction + * field in memory to memory value. + * @note To convert DMAx_Channely Instance to DMAx Instance and Channely, use + * helper macros : + * @arg @ref LL_DMA_GET_INSTANCE + * @arg @ref LL_DMA_GET_CHANNEL + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param DMA_InitStruct pointer to a @ref LL_DMA_InitTypeDef structure. + * @retval An ErrorStatus enumeration value: + * - SUCCESS : DMA registers are initialized. + * - ERROR : Not applicable. + */ +uint32_t LL_DMA_Init(DMA_TypeDef *DMAx, uint32_t Channel, LL_DMA_InitTypeDef *DMA_InitStruct) +{ + /* Check the DMA Instance DMAx and Channel parameters*/ + assert_param(IS_LL_DMA_ALL_CHANNEL_INSTANCE(DMAx, Channel)); + + /* Check the DMA parameters from DMA_InitStruct */ + assert_param(IS_LL_DMA_DIRECTION(DMA_InitStruct->Direction)); + + /* Check direction */ + if (DMA_InitStruct->Direction != LL_DMA_DIRECTION_MEMORY_TO_MEMORY) + { + assert_param(IS_LL_DMA_REQUEST_SELECTION(DMA_InitStruct->Request)); + } + + assert_param(IS_LL_DMA_DATA_ALIGNMENT(DMA_InitStruct->DataAlignment)); + assert_param(IS_LL_DMA_SRC_DATA_WIDTH(DMA_InitStruct->SrcDataWidth)); + assert_param(IS_LL_DMA_DEST_DATA_WIDTH(DMA_InitStruct->DestDataWidth)); + assert_param(IS_LL_DMA_SRC_INCREMENT_MODE(DMA_InitStruct->SrcIncMode)); + assert_param(IS_LL_DMA_DEST_INCREMENT_MODE(DMA_InitStruct->DestIncMode)); + assert_param(IS_LL_DMA_PRIORITY(DMA_InitStruct->Priority)); + assert_param(IS_LL_DMA_BLK_DATALENGTH(DMA_InitStruct->BlkDataLength)); + assert_param(IS_LL_DMA_TRIGGER_POLARITY(DMA_InitStruct->TriggerPolarity)); + assert_param(IS_LL_DMA_BLKHW_REQUEST(DMA_InitStruct->BlkHWRequest)); + assert_param(IS_LL_DMA_TRANSFER_EVENT_MODE(DMA_InitStruct->TransferEventMode)); + assert_param(IS_LL_DMA_LINK_STEP_MODE(DMA_InitStruct->LinkStepMode)); + assert_param(IS_LL_DMA_LINK_BASEADDR(DMA_InitStruct->LinkedListBaseAddr)); + assert_param(IS_LL_DMA_LINK_ADDR_OFFSET(DMA_InitStruct->LinkedListAddrOffset)); + assert_param(IS_LL_DMA_MODE(DMA_InitStruct->Mode)); + + /* Check DMA instance */ + if (IS_LL_GPDMA_CHANNEL_INSTANCE(DMAx, Channel) != 0U) + { + assert_param(IS_LL_DMA_BURST_LENGTH(DMA_InitStruct->SrcBurstLength)); + assert_param(IS_LL_DMA_BURST_LENGTH(DMA_InitStruct->DestBurstLength)); + assert_param(IS_LL_DMA_DEST_HALFWORD_EXCHANGE(DMA_InitStruct->DestHWordExchange)); + assert_param(IS_LL_DMA_DEST_BYTE_EXCHANGE(DMA_InitStruct->DestByteExchange)); + assert_param(IS_LL_DMA_SRC_BYTE_EXCHANGE(DMA_InitStruct->SrcByteExchange)); + assert_param(IS_LL_DMA_LINK_ALLOCATED_PORT(DMA_InitStruct->LinkAllocatedPort)); + assert_param(IS_LL_DMA_SRC_ALLOCATED_PORT(DMA_InitStruct->SrcAllocatedPort)); + assert_param(IS_LL_DMA_DEST_ALLOCATED_PORT(DMA_InitStruct->DestAllocatedPort)); + } + + /* Check trigger polarity */ + if (DMA_InitStruct->TriggerPolarity != LL_DMA_TRIG_POLARITY_MASKED) + { + assert_param(IS_LL_DMA_TRIGGER_MODE(DMA_InitStruct->TriggerMode)); + assert_param(IS_LL_DMA_TRIGGER_SELECTION(DMA_InitStruct->TriggerSelection)); + } + + /* Check DMA channel */ + if (IS_LL_DMA_2D_CHANNEL_INSTANCE(DMAx, Channel) != 0U) + { + assert_param(IS_LL_DMA_BLK_REPEATCOUNT(DMA_InitStruct->BlkRptCount)); + assert_param(IS_LL_DMA_BURST_SRC_ADDR_UPDATE(DMA_InitStruct->SrcAddrUpdateMode)); + assert_param(IS_LL_DMA_BURST_DEST_ADDR_UPDATE(DMA_InitStruct->DestAddrUpdateMode)); + assert_param(IS_LL_DMA_BURST_ADDR_UPDATE_VALUE(DMA_InitStruct->SrcAddrOffset)); + assert_param(IS_LL_DMA_BURST_ADDR_UPDATE_VALUE(DMA_InitStruct->DestAddrOffset)); + assert_param(IS_LL_DMA_BLKRPT_SRC_ADDR_UPDATE(DMA_InitStruct->BlkRptSrcAddrUpdateMode)); + assert_param(IS_LL_DMA_BLKRPT_DEST_ADDR_UPDATE(DMA_InitStruct->BlkRptDestAddrUpdateMode)); + assert_param(IS_LL_DMA_BLKRPT_ADDR_UPDATE_VALUE(DMA_InitStruct->BlkRptSrcAddrOffset)); + assert_param(IS_LL_DMA_BLKRPT_ADDR_UPDATE_VALUE(DMA_InitStruct->BlkRptDestAddrOffset)); + } + + /*-------------------------- DMAx CLBAR Configuration ------------------------ + * Configure the Transfer linked list address with parameter : + * - LinkedListBaseAdd: DMA_CLBAR_LBA[31:16] bits + */ + LL_DMA_SetLinkedListBaseAddr(DMAx, Channel, DMA_InitStruct->LinkedListBaseAddr); + + /*-------------------------- DMAx CCR Configuration -------------------------- + * Configure the control parameter : + * - LinkAllocatedPort: DMA_CCR_LAP bit + * - LinkStepMode: DMA_CCR_LSM bit + * - Priority: DMA_CCR_PRIO [23:22] bits + */ + LL_DMA_ConfigControl(DMAx, Channel, DMA_InitStruct->Priority | \ + DMA_InitStruct->LinkAllocatedPort | \ + DMA_InitStruct->LinkStepMode); + + /*-------------------------- DMAx CTR1 Configuration ------------------------- + * Configure the Data transfer parameter : + * - DestAllocatedPort: DMA_CTR1_DAP bit + * - DestHWordExchange: DMA_CTR1_DHX bit + * - DestByteExchange: DMA_CTR1_DBX bit + * - DestIncMode: DMA_CTR1_DINC bit + * - DestDataWidth: DMA_CTR1_DDW_LOG2 [17:16] bits + * - SrcAllocatedPort: DMA_CTR1_SAP bit + * - SrcByteExchange: DMA_CTR1_SBX bit + * - DataAlignment: DMA_CTR1_PAM [12:11] bits + * - SrcIncMode: DMA_CTR1_SINC bit + * - SrcDataWidth: DMA_CTR1_SDW_LOG2 [1:0] bits + * - SrcBurstLength: DMA_CTR1_SBL_1 [9:4] bits + * - DestBurstLength: DMA_CTR1_DBL_1 [25:20] bits + */ + LL_DMA_ConfigTransfer(DMAx, Channel, DMA_InitStruct->DestAllocatedPort | \ + DMA_InitStruct->DestHWordExchange | \ + DMA_InitStruct->DestByteExchange | \ + DMA_InitStruct->DestIncMode | \ + DMA_InitStruct->DestDataWidth | \ + DMA_InitStruct->SrcAllocatedPort | \ + DMA_InitStruct->SrcByteExchange | \ + DMA_InitStruct->DataAlignment | \ + DMA_InitStruct->SrcIncMode | \ + DMA_InitStruct->SrcDataWidth); + /* Check DMA instance */ + if (IS_LL_GPDMA_CHANNEL_INSTANCE(DMAx, Channel) != 0U) + { + LL_DMA_ConfigBurstLength(DMAx, Channel, DMA_InitStruct->SrcBurstLength, + DMA_InitStruct->DestBurstLength); + } + + /*-------------------------- DMAx CTR2 Configuration ------------------------- + * Configure the channel transfer parameter : + * - TransferEventMode: DMA_CTR2_TCEM [31:30] bits + * - TriggerPolarity: DMA_CTR2_TRIGPOL [25:24] bits + * - TriggerMode: DMA_CTR2_TRIGM [15:14] bits + * - BlkHWRequest: DMA_CTR2_BREQ bit + * - Mode: DMA_CTR2_PFREQ bit + * - Direction: DMA_CTR2_DREQ bit + * - Direction: DMA_CTR2_SWREQ bit + * - TriggerSelection: DMA_CTR2_TRIGSEL [21:16] bits + * - Request: DMA_CTR2_REQSEL [6:0] bits + */ + LL_DMA_ConfigChannelTransfer(DMAx, Channel, DMA_InitStruct->TransferEventMode | \ + DMA_InitStruct->TriggerPolarity | \ + DMA_InitStruct->BlkHWRequest | \ + DMA_InitStruct->Mode | \ + DMA_InitStruct->Direction); + + /* Check direction */ + if (DMA_InitStruct->Direction != LL_DMA_DIRECTION_MEMORY_TO_MEMORY) + { + LL_DMA_SetPeriphRequest(DMAx, Channel, DMA_InitStruct->Request); + } + + /* Check trigger polarity */ + if (DMA_InitStruct->TriggerPolarity != LL_DMA_TRIG_POLARITY_MASKED) + { + LL_DMA_SetHWTrigger(DMAx, Channel, DMA_InitStruct->TriggerSelection); + LL_DMA_SetTriggerMode(DMAx, Channel, DMA_InitStruct->TriggerMode); + } + + /*-------------------------- DMAx CBR1 Configuration ------------------------- + * Configure the Transfer Block counters and update mode with parameter : + * - BlkDataLength: DMA_CBR1_BNDT[15:0] bits + * - BlkRptCount: DMA_CBR1_BRC[26:16] bits + * BlkRptCount field is supported only by 2D addressing channels. + * - BlkRptSrcAddrUpdateMode: DMA_CBR1_BRSDEC bit + * BlkRptSrcAddrUpdateMode field is supported only by 2D addressing channels. + * - BlkRptDestAddrUpdateMode: DMA_CBR1_BRDDEC bit + * BlkRptDestAddrUpdateMode field is supported only by 2D addressing channels. + * - SrcAddrUpdateMode: DMA_CBR1_SDEC bit + * SrcAddrUpdateMode field is supported only by 2D addressing channels. + * - DestAddrUpdateMode: DMA_CBR1_DDEC bit + * DestAddrUpdateMode field is supported only by 2D addressing channels. + */ + LL_DMA_SetBlkDataLength(DMAx, Channel, DMA_InitStruct->BlkDataLength); + + /* Check DMA channel */ + if (IS_LL_DMA_2D_CHANNEL_INSTANCE(DMAx, Channel) != 0U) + { + LL_DMA_SetBlkRptCount(DMAx, Channel, DMA_InitStruct->BlkRptCount); + LL_DMA_ConfigBlkRptAddrUpdate(DMAx, Channel, DMA_InitStruct->BlkRptSrcAddrUpdateMode | \ + DMA_InitStruct->BlkRptDestAddrUpdateMode | \ + DMA_InitStruct->SrcAddrUpdateMode | \ + DMA_InitStruct->DestAddrUpdateMode); + } + + /*-------------------------- DMAx CSAR and CDAR Configuration ---------------- + * Configure the Transfer source address with parameter : + * - SrcAddress: DMA_CSAR_SA[31:0] bits + * - DestAddress: DMA_CDAR_DA[31:0] bits + */ + LL_DMA_ConfigAddresses(DMAx, Channel, DMA_InitStruct->SrcAddress, DMA_InitStruct->DestAddress); + + /* Check DMA channel */ + if (IS_LL_DMA_2D_CHANNEL_INSTANCE(DMAx, Channel) != 0U) + { + /*------------------------ DMAx CTR3 Configuration ------------------------- + * Configure the Transfer Block counters and update mode with parameter : + * - SrcAddrOffset: DMA_CTR3_SAO[28:16] bits + * SrcAddrOffset field is supported only by 2D addressing channels. + * - DestAddrOffset: DMA_CTR3_DAO[12:0] bits + * DestAddrOffset field is supported only by 2D addressing channels. + */ + LL_DMA_ConfigAddrUpdateValue(DMAx, Channel, DMA_InitStruct->SrcAddrOffset, DMA_InitStruct->DestAddrOffset); + + /*------------------------ DMAx CBR2 Configuration ----------------------- + * Configure the Transfer Block counters and update mode with parameter : + * - BlkRptSrcAddrOffset: DMA_CBR2_BRSAO[15:0] bits + * BlkRptSrcAddrOffset field is supported only by 2D addressing channels. + * - BlkRptDestAddrOffset: DMA_CBR2_BRDAO[31:16] bits + * BlkRptDestAddrOffset field is supported only by 2D addressing channels. + */ + LL_DMA_ConfigBlkRptAddrUpdateValue(DMAx, Channel, DMA_InitStruct->BlkRptSrcAddrOffset, + DMA_InitStruct->BlkRptDestAddrOffset); + } + + /*-------------------------- DMAx CLLR Configuration ------------------------- + * Configure the Transfer linked list address with parameter : + * - DestAddrOffset: DMA_CLLR_LA[15:2] bits + */ + LL_DMA_SetLinkedListAddrOffset(DMAx, Channel, DMA_InitStruct->LinkedListAddrOffset); + + return (uint32_t)SUCCESS; +} + +/** + * @brief Set each @ref LL_DMA_InitTypeDef field to default value. + * @param DMA_InitStruct Pointer to a @ref LL_DMA_InitTypeDef structure. + * @retval None. + */ +void LL_DMA_StructInit(LL_DMA_InitTypeDef *DMA_InitStruct) +{ + /* Set DMA_InitStruct fields to default values */ + DMA_InitStruct->SrcAddress = 0x00000000U; + DMA_InitStruct->DestAddress = 0x00000000U; + DMA_InitStruct->Direction = LL_DMA_DIRECTION_MEMORY_TO_MEMORY; + DMA_InitStruct->BlkHWRequest = LL_DMA_HWREQUEST_SINGLEBURST; + DMA_InitStruct->DataAlignment = LL_DMA_DATA_ALIGN_ZEROPADD; + DMA_InitStruct->SrcBurstLength = 1U; + DMA_InitStruct->DestBurstLength = 1U; + DMA_InitStruct->SrcDataWidth = LL_DMA_SRC_DATAWIDTH_BYTE; + DMA_InitStruct->DestDataWidth = LL_DMA_DEST_DATAWIDTH_BYTE; + DMA_InitStruct->SrcIncMode = LL_DMA_SRC_FIXED; + DMA_InitStruct->DestIncMode = LL_DMA_DEST_FIXED; + DMA_InitStruct->Priority = LL_DMA_LOW_PRIORITY_LOW_WEIGHT; + DMA_InitStruct->BlkDataLength = 0x00000000U; + DMA_InitStruct->Mode = LL_DMA_NORMAL; + DMA_InitStruct->BlkRptCount = 0x00000000U; + DMA_InitStruct->TriggerMode = LL_DMA_TRIGM_BLK_TRANSFER; + DMA_InitStruct->TriggerPolarity = LL_DMA_TRIG_POLARITY_MASKED; + DMA_InitStruct->TriggerSelection = 0x00000000U; + DMA_InitStruct->Request = 0x00000000U; + DMA_InitStruct->TransferEventMode = LL_DMA_TCEM_BLK_TRANSFER; + DMA_InitStruct->DestHWordExchange = LL_DMA_DEST_HALFWORD_PRESERVE; + DMA_InitStruct->DestByteExchange = LL_DMA_DEST_BYTE_PRESERVE; + DMA_InitStruct->SrcByteExchange = LL_DMA_SRC_BYTE_PRESERVE; + DMA_InitStruct->SrcAllocatedPort = LL_DMA_SRC_ALLOCATED_PORT0; + DMA_InitStruct->DestAllocatedPort = LL_DMA_DEST_ALLOCATED_PORT0; + DMA_InitStruct->LinkAllocatedPort = LL_DMA_LINK_ALLOCATED_PORT0; + DMA_InitStruct->LinkStepMode = LL_DMA_LSM_FULL_EXECUTION; + DMA_InitStruct->SrcAddrUpdateMode = LL_DMA_BURST_SRC_ADDR_INCREMENT; + DMA_InitStruct->DestAddrUpdateMode = LL_DMA_BURST_DEST_ADDR_INCREMENT; + DMA_InitStruct->SrcAddrOffset = 0x00000000U; + DMA_InitStruct->DestAddrOffset = 0x00000000U; + DMA_InitStruct->BlkRptSrcAddrUpdateMode = LL_DMA_BLKRPT_SRC_ADDR_INCREMENT; + DMA_InitStruct->BlkRptDestAddrUpdateMode = LL_DMA_BLKRPT_DEST_ADDR_INCREMENT; + DMA_InitStruct->BlkRptSrcAddrOffset = 0x00000000U; + DMA_InitStruct->BlkRptDestAddrOffset = 0x00000000U; + DMA_InitStruct->LinkedListBaseAddr = 0x00000000U; + DMA_InitStruct->LinkedListAddrOffset = 0x00000000U; +} + +/** + * @brief Set each @ref LL_DMA_InitLinkedListTypeDef field to default value. + * @param DMA_InitLinkedListStruct Pointer to + * a @ref LL_DMA_InitLinkedListTypeDef structure. + * @retval None. + */ +void LL_DMA_ListStructInit(LL_DMA_InitLinkedListTypeDef *DMA_InitLinkedListStruct) +{ + /* Set LL_DMA_InitLinkedListTypeDef fields to default values */ + DMA_InitLinkedListStruct->Priority = LL_DMA_LOW_PRIORITY_LOW_WEIGHT; + DMA_InitLinkedListStruct->LinkStepMode = LL_DMA_LSM_FULL_EXECUTION; + DMA_InitLinkedListStruct->TransferEventMode = LL_DMA_TCEM_LAST_LLITEM_TRANSFER; + DMA_InitLinkedListStruct->LinkAllocatedPort = LL_DMA_LINK_ALLOCATED_PORT0; +} + +/** + * @brief De-initialize the DMA linked list. + * @note This API is used for all available DMA channels. + * @note To convert DMAx_Channely Instance to DMAx Instance and Channely, use + * helper macros : + * @arg @ref LL_DMA_GET_INSTANCE + * @arg @ref LL_DMA_GET_CHANNEL + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval An ErrorStatus enumeration value: + * - SUCCESS : DMA registers are de-initialized. + * - ERROR : DMA registers are not de-initialized. + */ +uint32_t LL_DMA_List_DeInit(DMA_TypeDef *DMAx, uint32_t Channel) +{ + return LL_DMA_DeInit(DMAx, Channel); +} + +/** + * @brief Initialize the DMA linked list according to the specified parameters + * in LL_DMA_InitLinkedListTypeDef. + * @note This API is used for all available DMA channels. + * @note To convert DMAx_Channely Instance to DMAx Instance and Channely, use + * helper macros : + * @arg @ref LL_DMA_GET_INSTANCE + * @arg @ref LL_DMA_GET_CHANNEL + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_0 + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param DMA_InitLinkedListStruct pointer to + * a @ref LL_DMA_InitLinkedListTypeDef structure. + * @retval An ErrorStatus enumeration value: + * - SUCCESS : DMA registers are initialized. + * - ERROR : Not applicable. + */ +uint32_t LL_DMA_List_Init(DMA_TypeDef *DMAx, uint32_t Channel, LL_DMA_InitLinkedListTypeDef *DMA_InitLinkedListStruct) +{ + /* Check the DMA Instance DMAx and Channel parameters*/ + assert_param(IS_LL_DMA_ALL_CHANNEL_INSTANCE(DMAx, Channel)); + + /* Check the DMA parameters from DMA_InitLinkedListStruct */ + assert_param(IS_LL_DMA_PRIORITY(DMA_InitLinkedListStruct->Priority)); + assert_param(IS_LL_DMA_LINK_STEP_MODE(DMA_InitLinkedListStruct->LinkStepMode)); + assert_param(IS_LL_DMA_TRANSFER_EVENT_MODE(DMA_InitLinkedListStruct->TransferEventMode)); + /* Check DMA instance */ + if (IS_LL_GPDMA_CHANNEL_INSTANCE(DMAx, Channel) != 0U) + { + assert_param(IS_LL_DMA_LINK_ALLOCATED_PORT(DMA_InitLinkedListStruct->LinkAllocatedPort)); + } + + /*-------------------------- DMAx CCR Configuration -------------------------- + * Configure the control parameter : + * - LinkAllocatedPort: DMA_CCR_LAP bit + * LinkAllocatedPort field is supported only by GPDMA channels. + * - LinkStepMode: DMA_CCR_LSM bit + * - Priority: DMA_CCR_PRIO [23:22] bits + */ + LL_DMA_ConfigControl(DMAx, Channel, DMA_InitLinkedListStruct->Priority | \ + DMA_InitLinkedListStruct->LinkAllocatedPort | \ + DMA_InitLinkedListStruct->LinkStepMode); + + /*-------------------------- DMAx CTR2 Configuration ------------------------- + * Configure the channel transfer parameter : + * - TransferEventMode: DMA_CTR2_TCEM [31:30] bits + */ + LL_DMA_SetTransferEventMode(DMAx, Channel, DMA_InitLinkedListStruct->TransferEventMode); + + return (uint32_t)SUCCESS; +} + +/** + * @brief Set each @ref LL_DMA_InitNodeTypeDef field to default value. + * @param DMA_InitNodeStruct Pointer to a @ref LL_DMA_InitNodeTypeDef + * structure. + * @retval None. + */ +void LL_DMA_NodeStructInit(LL_DMA_InitNodeTypeDef *DMA_InitNodeStruct) +{ + /* Set DMA_InitNodeStruct fields to default values */ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + DMA_InitNodeStruct->DestSecure = LL_DMA_CHANNEL_DEST_NSEC; +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + DMA_InitNodeStruct->DestAllocatedPort = LL_DMA_DEST_ALLOCATED_PORT0; + DMA_InitNodeStruct->DestHWordExchange = LL_DMA_DEST_HALFWORD_PRESERVE; + DMA_InitNodeStruct->DestByteExchange = LL_DMA_DEST_BYTE_PRESERVE; + DMA_InitNodeStruct->DestBurstLength = 1U; + DMA_InitNodeStruct->DestIncMode = LL_DMA_DEST_FIXED; + DMA_InitNodeStruct->DestDataWidth = LL_DMA_DEST_DATAWIDTH_BYTE; +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + DMA_InitNodeStruct->SrcSecure = LL_DMA_CHANNEL_SRC_NSEC; +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + DMA_InitNodeStruct->SrcAllocatedPort = LL_DMA_SRC_ALLOCATED_PORT0; + DMA_InitNodeStruct->SrcByteExchange = LL_DMA_SRC_BYTE_PRESERVE; + DMA_InitNodeStruct->DataAlignment = LL_DMA_DATA_ALIGN_ZEROPADD; + DMA_InitNodeStruct->SrcBurstLength = 1U; + DMA_InitNodeStruct->SrcIncMode = LL_DMA_SRC_FIXED; + DMA_InitNodeStruct->SrcDataWidth = LL_DMA_SRC_DATAWIDTH_BYTE; + DMA_InitNodeStruct->TransferEventMode = LL_DMA_TCEM_BLK_TRANSFER; + DMA_InitNodeStruct->TriggerPolarity = LL_DMA_TRIG_POLARITY_MASKED; + DMA_InitNodeStruct->TriggerSelection = 0x00000000U; + DMA_InitNodeStruct->TriggerMode = LL_DMA_TRIGM_BLK_TRANSFER; + DMA_InitNodeStruct->BlkHWRequest = LL_DMA_HWREQUEST_SINGLEBURST; + DMA_InitNodeStruct->Direction = LL_DMA_DIRECTION_MEMORY_TO_MEMORY; + DMA_InitNodeStruct->Request = 0x00000000U; + DMA_InitNodeStruct->BlkRptDestAddrUpdateMode = LL_DMA_BLKRPT_DEST_ADDR_INCREMENT; + DMA_InitNodeStruct->BlkRptSrcAddrUpdateMode = LL_DMA_BLKRPT_SRC_ADDR_INCREMENT; + DMA_InitNodeStruct->DestAddrUpdateMode = LL_DMA_BURST_DEST_ADDR_INCREMENT; + DMA_InitNodeStruct->SrcAddrUpdateMode = LL_DMA_BURST_SRC_ADDR_INCREMENT; + DMA_InitNodeStruct->BlkRptCount = 0x00000000U; + DMA_InitNodeStruct->BlkDataLength = 0x00000000U; + DMA_InitNodeStruct->SrcAddress = 0x00000000U; + DMA_InitNodeStruct->DestAddress = 0x00000000U; + DMA_InitNodeStruct->DestAddrOffset = 0x00000000U; + DMA_InitNodeStruct->SrcAddrOffset = 0x00000000U; + DMA_InitNodeStruct->BlkRptDestAddrOffset = 0x00000000U; + DMA_InitNodeStruct->BlkRptSrcAddrOffset = 0x00000000U; + DMA_InitNodeStruct->UpdateRegisters = (LL_DMA_UPDATE_CTR1 | LL_DMA_UPDATE_CTR2 | \ + LL_DMA_UPDATE_CBR1 | LL_DMA_UPDATE_CSAR | \ + LL_DMA_UPDATE_CDAR | LL_DMA_UPDATE_CTR3 | \ + LL_DMA_UPDATE_CBR2 | LL_DMA_UPDATE_CLLR); + DMA_InitNodeStruct->NodeType = LL_DMA_GPDMA_LINEAR_NODE; +} + +/** + * @brief Initializes DMA linked list node according to the specified + * parameters in the DMA_InitNodeStruct. + * @param DMA_InitNodeStruct Pointer to a LL_DMA_InitNodeTypeDef structure + * that contains linked list node + * registers configurations. + * @param pNode Pointer to linked list node to fill according to + * LL_DMA_LinkNodeTypeDef parameters. + * @retval None + */ +uint32_t LL_DMA_CreateLinkNode(LL_DMA_InitNodeTypeDef *DMA_InitNodeStruct, LL_DMA_LinkNodeTypeDef *pNode) +{ + uint32_t reg_counter = 0U; + + /* Check the DMA Node type */ + assert_param(IS_LL_DMA_LINK_NODETYPE(DMA_InitNodeStruct->NodeType)); + + /* Check the DMA parameters from DMA_InitNodeStruct */ + assert_param(IS_LL_DMA_DIRECTION(DMA_InitNodeStruct->Direction)); + + /* Check direction */ + if (DMA_InitNodeStruct->Direction != LL_DMA_DIRECTION_MEMORY_TO_MEMORY) + { + assert_param(IS_LL_DMA_REQUEST_SELECTION(DMA_InitNodeStruct->Request)); + } + + assert_param(IS_LL_DMA_DATA_ALIGNMENT(DMA_InitNodeStruct->DataAlignment)); + assert_param(IS_LL_DMA_SRC_DATA_WIDTH(DMA_InitNodeStruct->SrcDataWidth)); + assert_param(IS_LL_DMA_DEST_DATA_WIDTH(DMA_InitNodeStruct->DestDataWidth)); + assert_param(IS_LL_DMA_SRC_INCREMENT_MODE(DMA_InitNodeStruct->SrcIncMode)); + assert_param(IS_LL_DMA_DEST_INCREMENT_MODE(DMA_InitNodeStruct->DestIncMode)); + assert_param(IS_LL_DMA_BLK_DATALENGTH(DMA_InitNodeStruct->BlkDataLength)); + assert_param(IS_LL_DMA_TRIGGER_POLARITY(DMA_InitNodeStruct->TriggerPolarity)); + assert_param(IS_LL_DMA_BLKHW_REQUEST(DMA_InitNodeStruct->BlkHWRequest)); + assert_param(IS_LL_DMA_TRANSFER_EVENT_MODE(DMA_InitNodeStruct->TransferEventMode)); + assert_param(IS_LL_DMA_LINK_UPDATE_REGISTERS(DMA_InitNodeStruct->UpdateRegisters)); + assert_param(IS_LL_DMA_MODE(DMA_InitNodeStruct->Mode)); + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + assert_param(IS_LL_DMA_CHANNEL_SRC_SEC(DMA_InitNodeStruct->SrcSecure)); + assert_param(IS_LL_DMA_CHANNEL_DEST_SEC(DMA_InitNodeStruct->DestSecure)); +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + /* Check trigger polarity */ + if (DMA_InitNodeStruct->TriggerPolarity != LL_DMA_TRIG_POLARITY_MASKED) + { + assert_param(IS_LL_DMA_TRIGGER_MODE(DMA_InitNodeStruct->TriggerMode)); + assert_param(IS_LL_DMA_TRIGGER_SELECTION(DMA_InitNodeStruct->TriggerSelection)); + } + + /* Check node type */ + if (DMA_InitNodeStruct->NodeType == LL_DMA_GPDMA_LINEAR_NODE) + { + assert_param(IS_LL_DMA_BURST_LENGTH(DMA_InitNodeStruct->SrcBurstLength)); + assert_param(IS_LL_DMA_BURST_LENGTH(DMA_InitNodeStruct->DestBurstLength)); + assert_param(IS_LL_DMA_DEST_HALFWORD_EXCHANGE(DMA_InitNodeStruct->DestHWordExchange)); + assert_param(IS_LL_DMA_DEST_BYTE_EXCHANGE(DMA_InitNodeStruct->DestByteExchange)); + assert_param(IS_LL_DMA_SRC_BYTE_EXCHANGE(DMA_InitNodeStruct->SrcByteExchange)); + assert_param(IS_LL_DMA_SRC_ALLOCATED_PORT(DMA_InitNodeStruct->SrcAllocatedPort)); + assert_param(IS_LL_DMA_DEST_ALLOCATED_PORT(DMA_InitNodeStruct->DestAllocatedPort)); + } + + /* Check DMA channel */ + if (DMA_InitNodeStruct->NodeType == LL_DMA_GPDMA_2D_NODE) + { + assert_param(IS_LL_DMA_BLK_REPEATCOUNT(DMA_InitNodeStruct->BlkRptCount)); + assert_param(IS_LL_DMA_BURST_SRC_ADDR_UPDATE(DMA_InitNodeStruct->SrcAddrUpdateMode)); + assert_param(IS_LL_DMA_BURST_DEST_ADDR_UPDATE(DMA_InitNodeStruct->DestAddrUpdateMode)); + assert_param(IS_LL_DMA_BURST_ADDR_UPDATE_VALUE(DMA_InitNodeStruct->SrcAddrOffset)); + assert_param(IS_LL_DMA_BURST_ADDR_UPDATE_VALUE(DMA_InitNodeStruct->DestAddrOffset)); + assert_param(IS_LL_DMA_BLKRPT_SRC_ADDR_UPDATE(DMA_InitNodeStruct->BlkRptSrcAddrUpdateMode)); + assert_param(IS_LL_DMA_BLKRPT_DEST_ADDR_UPDATE(DMA_InitNodeStruct->BlkRptDestAddrUpdateMode)); + assert_param(IS_LL_DMA_BLKRPT_ADDR_UPDATE_VALUE(DMA_InitNodeStruct->BlkRptSrcAddrOffset)); + assert_param(IS_LL_DMA_BLKRPT_ADDR_UPDATE_VALUE(DMA_InitNodeStruct->BlkRptDestAddrOffset)); + } + + /* Check if CTR1 register update is enabled */ + if ((DMA_InitNodeStruct->UpdateRegisters & LL_DMA_UPDATE_CTR1) == LL_DMA_UPDATE_CTR1) + { + /*-------------------------- DMAx CTR1 Configuration ----------------------- + * Configure the Data transfer parameter : + * - DestAllocatedPort: DMA_CTR1_DAP bit + * - DestHWordExchange: DMA_CTR1_DHX bit + * - DestByteExchange: DMA_CTR1_DBX bit + * - DestIncMode: DMA_CTR1_DINC bit + * - DestDataWidth: DMA_CTR1_DDW_LOG2 [17:16] bits + * - SrcAllocatedPort: DMA_CTR1_SAP bit + * - SrcByteExchange: DMA_CTR1_SBX bit + * - DataAlignment: DMA_CTR1_PAM [12:11] bits + * - SrcIncMode: DMA_CTR1_SINC bit + * - SrcDataWidth: DMA_CTR1_SDW_LOG2 [1:0] bits + * - SrcBurstLength: DMA_CTR1_SBL_1 [9:4] bits + * - DestBurstLength: DMA_CTR1_DBL_1 [25:20] bits + */ + + pNode->LinkRegisters[reg_counter] = (DMA_InitNodeStruct->DestIncMode | \ + DMA_InitNodeStruct->DestDataWidth | \ + DMA_InitNodeStruct->DataAlignment | \ + DMA_InitNodeStruct->SrcIncMode | \ + DMA_InitNodeStruct->SrcDataWidth); + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + pNode->LinkRegisters[reg_counter] |= (DMA_InitNodeStruct->DestSecure | \ + DMA_InitNodeStruct->SrcSecure); +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + /* Update CTR1 register fields */ + pNode->LinkRegisters[reg_counter] |= (DMA_InitNodeStruct->DestAllocatedPort | \ + DMA_InitNodeStruct->DestHWordExchange | \ + DMA_InitNodeStruct->DestByteExchange | \ + ((DMA_InitNodeStruct->DestBurstLength - 1U) << DMA_CTR1_DBL_1_Pos) | \ + DMA_InitNodeStruct->SrcAllocatedPort | \ + DMA_InitNodeStruct->SrcByteExchange | \ + ((DMA_InitNodeStruct->SrcBurstLength - 1U) << DMA_CTR1_SBL_1_Pos)); + + /* Increment counter for the next register */ + reg_counter++; + } + + + /* Check if CTR2 register update is enabled */ + if ((DMA_InitNodeStruct->UpdateRegisters & LL_DMA_UPDATE_CTR2) == LL_DMA_UPDATE_CTR2) + { + /*-------------------------- DMAx CTR2 Configuration ----------------------- + * Configure the channel transfer parameter : + * - TransferEventMode: DMA_CTR2_TCEM [31:30] bits + * - TriggerPolarity: DMA_CTR2_TRIGPOL [25:24] bits + * - TriggerMode: DMA_CTR2_TRIGM [15:14] bits + * - Mode: DMA_CTR2_PFREQ bit + * - BlkHWRequest: DMA_CTR2_BREQ bit + * - Direction: DMA_CTR2_DREQ bit + * - Direction: DMA_CTR2_SWREQ bit + * - TriggerSelection: DMA_CTR2_TRIGSEL [21:16] bits + * - Request: DMA_CTR2_REQSEL [6:0] bits + */ + pNode->LinkRegisters[reg_counter] = (DMA_InitNodeStruct->TransferEventMode | \ + DMA_InitNodeStruct->TriggerPolarity | \ + DMA_InitNodeStruct->BlkHWRequest | \ + DMA_InitNodeStruct->Mode | \ + DMA_InitNodeStruct->Direction); + + /* Check direction */ + if (DMA_InitNodeStruct->Direction != LL_DMA_DIRECTION_MEMORY_TO_MEMORY) + { + pNode->LinkRegisters[reg_counter] |= DMA_InitNodeStruct->Request & DMA_CTR2_REQSEL; + } + + /* Check trigger polarity */ + if (DMA_InitNodeStruct->TriggerPolarity != LL_DMA_TRIG_POLARITY_MASKED) + { + pNode->LinkRegisters[reg_counter] |= (((DMA_InitNodeStruct->TriggerSelection << DMA_CTR2_TRIGSEL_Pos) & \ + DMA_CTR2_TRIGSEL) | DMA_InitNodeStruct->TriggerMode); + } + + + /* Increment counter for the next register */ + reg_counter++; + } + + /* Check if CBR1 register update is enabled */ + if ((DMA_InitNodeStruct->UpdateRegisters & LL_DMA_UPDATE_CBR1) == LL_DMA_UPDATE_CBR1) + { + /*-------------------------- DMAx CBR1 Configuration ----------------------- + * Configure the Transfer Block counters and update mode with parameter : + * - BlkDataLength: DMA_CBR1_BNDT[15:0] bits + * - BlkRptCount: DMA_CBR1_BRC[26:16] bits + * BlkRptCount field is supported only by 2D addressing channels. + * - BlkRptSrcAddrUpdateMode: DMA_CBR1_BRSDEC bit + * BlkRptSrcAddrUpdateMode field is supported only by 2D addressing channels. + * - BlkRptDestAddrUpdateMode: DMA_CBR1_BRDDEC bit + * BlkRptDestAddrUpdateMode field is supported only by 2D addressing channels. + * - SrcAddrUpdateMode: DMA_CBR1_SDEC bit + * SrcAddrUpdateMode field is supported only by 2D addressing channels. + * - DestAddrUpdateMode: DMA_CBR1_DDEC bit + * DestAddrUpdateMode field is supported only by 2D addressing channels. + */ + pNode->LinkRegisters[reg_counter] = DMA_InitNodeStruct->BlkDataLength; + + /* Update CBR1 register fields for 2D addressing channels */ + if (DMA_InitNodeStruct->NodeType == LL_DMA_GPDMA_2D_NODE) + { + pNode->LinkRegisters[reg_counter] |= (DMA_InitNodeStruct->BlkRptDestAddrUpdateMode | \ + DMA_InitNodeStruct->BlkRptSrcAddrUpdateMode | \ + DMA_InitNodeStruct->DestAddrUpdateMode | \ + DMA_InitNodeStruct->SrcAddrUpdateMode | \ + ((DMA_InitNodeStruct->BlkRptCount << DMA_CBR1_BRC_Pos) & DMA_CBR1_BRC)); + } + + /* Increment counter for the next register */ + reg_counter++; + } + + /* Check if CSAR register update is enabled */ + if ((DMA_InitNodeStruct->UpdateRegisters & LL_DMA_UPDATE_CSAR) == LL_DMA_UPDATE_CSAR) + { + /*-------------------------- DMAx CSAR Configuration ----------------------- + * Configure the Transfer Block counters and update mode with parameter : + * - SrcAddress: DMA_CSAR_SA[31:0] bits + */ + pNode->LinkRegisters[reg_counter] = DMA_InitNodeStruct->SrcAddress; + + /* Increment counter for the next register */ + reg_counter++; + } + + + /* Check if CDAR register update is enabled */ + if ((DMA_InitNodeStruct->UpdateRegisters & LL_DMA_UPDATE_CDAR) == LL_DMA_UPDATE_CDAR) + { + /*-------------------------- DMAx CDAR Configuration ----------------------- + * Configure the Transfer Block counters and update mode with parameter : + * - DestAddress: DMA_CDAR_DA[31:0] bits + */ + pNode->LinkRegisters[reg_counter] = DMA_InitNodeStruct->DestAddress; + + /* Increment counter for the next register */ + reg_counter++; + } + + + /* Update CTR3 register fields for 2D addressing channels */ + if (DMA_InitNodeStruct->NodeType == LL_DMA_GPDMA_2D_NODE) + { + /* Check if CTR3 register update is enabled */ + if ((DMA_InitNodeStruct->UpdateRegisters & LL_DMA_UPDATE_CTR3) == LL_DMA_UPDATE_CTR3) + { + /*-------------------------- DMAx CTR3 Configuration --------------------- + * Configure the Block counters and update mode with parameter : + * - DestAddressOffset: DMA_CTR3_DAO[12:0] bits + * DestAddressOffset field is supported only by 2D addressing channels. + * - SrcAddressOffset: DMA_CTR3_SAO[12:0] bits + * SrcAddressOffset field is supported only by 2D addressing channels. + */ + pNode->LinkRegisters[reg_counter] = (DMA_InitNodeStruct->SrcAddrOffset | \ + ((DMA_InitNodeStruct->DestAddrOffset << DMA_CTR3_DAO_Pos) & DMA_CTR3_DAO)); + + /* Increment counter for the next register */ + reg_counter++; + } + } + + + /* Update CBR2 register fields for 2D addressing channels */ + if (DMA_InitNodeStruct->NodeType == LL_DMA_GPDMA_2D_NODE) + { + /* Check if CBR2 register update is enabled */ + if ((DMA_InitNodeStruct->UpdateRegisters & LL_DMA_UPDATE_CBR2) == LL_DMA_UPDATE_CBR2) + { + /*-------------------------- DMAx CBR2 Configuration --------------------- + * Configure the Block counters and update mode with parameter : + * - BlkRptDestAddrOffset: DMA_CBR2_BRDAO[31:16] bits + * BlkRptDestAddrOffset field is supported only by 2D addressing channels. + * - BlkRptSrcAddrOffset: DMA_CBR2_BRSAO[15:0] bits + * BlkRptSrcAddrOffset field is supported only by 2D addressing channels. + */ + pNode->LinkRegisters[reg_counter] = (DMA_InitNodeStruct->BlkRptSrcAddrOffset | \ + ((DMA_InitNodeStruct->BlkRptDestAddrOffset << DMA_CBR2_BRDAO_Pos) & \ + DMA_CBR2_BRDAO)); + + /* Increment counter for the next register */ + reg_counter++; + } + } + + /* Check if CLLR register update is enabled */ + if ((DMA_InitNodeStruct->UpdateRegisters & LL_DMA_UPDATE_CLLR) == LL_DMA_UPDATE_CLLR) + { + /*-------------------------- DMAx CLLR Configuration ----------------------- + * Configure the Transfer Block counters and update mode with parameter : + * - UpdateRegisters DMA_CLLR_UT1 bit + * - UpdateRegisters DMA_CLLR_UT2 bit + * - UpdateRegisters DMA_CLLR_UB1 bit + * - UpdateRegisters DMA_CLLR_USA bit + * - UpdateRegisters DMA_CLLR_UDA bit + * - UpdateRegisters DMA_CLLR_UT3 bit + * DMA_CLLR_UT3 bit is discarded for linear addressing channels. + * - UpdateRegisters DMA_CLLR_UB2 bit + * DMA_CLLR_UB2 bit is discarded for linear addressing channels. + * - UpdateRegisters DMA_CLLR_ULL bit + */ + pNode->LinkRegisters[reg_counter] = ((DMA_InitNodeStruct->UpdateRegisters & (DMA_CLLR_UT1 | DMA_CLLR_UT2 | \ + DMA_CLLR_UB1 | DMA_CLLR_USA | \ + DMA_CLLR_UDA | DMA_CLLR_ULL))); + + /* Update CLLR register fields for 2D addressing channels */ + if (DMA_InitNodeStruct->NodeType == LL_DMA_GPDMA_2D_NODE) + { + pNode->LinkRegisters[reg_counter] |= (DMA_InitNodeStruct->UpdateRegisters & (DMA_CLLR_UT3 | DMA_CLLR_UB2)); + } + } + + return (uint32_t)SUCCESS; +} + +/** + * @brief Connect Linked list Nodes. + * @param pPrevLinkNode Pointer to previous linked list node to be connected to new Linked list node. + * @param PrevNodeCLLRIdx Offset of Previous Node CLLR register. + * This parameter can be a value of @ref DMA_LL_EC_CLLR_OFFSET. + * @param pNewLinkNode Pointer to new Linked list. + * @param NewNodeCLLRIdx Offset of New Node CLLR register. + * This parameter can be a value of @ref DMA_LL_EC_CLLR_OFFSET. + * @retval None + */ +void LL_DMA_ConnectLinkNode(LL_DMA_LinkNodeTypeDef *pPrevLinkNode, uint32_t PrevNodeCLLRIdx, + LL_DMA_LinkNodeTypeDef *pNewLinkNode, uint32_t NewNodeCLLRIdx) +{ + pPrevLinkNode->LinkRegisters[PrevNodeCLLRIdx] = (((uint32_t)pNewLinkNode & DMA_CLLR_LA) | \ + (pNewLinkNode->LinkRegisters[NewNodeCLLRIdx] & (DMA_CLLR_UT1 | \ + DMA_CLLR_UT2 | DMA_CLLR_UB1 | DMA_CLLR_USA | DMA_CLLR_UDA | \ + DMA_CLLR_UT3 | DMA_CLLR_UB2 | DMA_CLLR_ULL))); +} + +/** + * @brief Disconnect the next linked list node. + * @param pLinkNode Pointer to linked list node to be disconnected from the next one. + * @param LinkNodeCLLRIdx Offset of Link Node CLLR register. + * @retval None. + */ +void LL_DMA_DisconnectNextLinkNode(LL_DMA_LinkNodeTypeDef *pLinkNode, uint32_t LinkNodeCLLRIdx) +{ + pLinkNode->LinkRegisters[LinkNodeCLLRIdx] = 0; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined (GPDMA1) */ + +/** + * @} + */ + +#endif /* defined (USE_FULL_LL_DRIVER) */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_exti.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_exti.c new file mode 100644 index 0000000000..b099732d44 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_exti.c @@ -0,0 +1,296 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_exti.c + * @author MCD Application Team + * @brief EXTI LL module driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +#if defined(USE_FULL_LL_DRIVER) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_exti.h" +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (EXTI) + +/** @defgroup EXTI_LL EXTI + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup EXTI_LL_Private_Macros + * @{ + */ + +#define IS_LL_EXTI_LINE_0_31(__VALUE__) (((__VALUE__) & ~LL_EXTI_LINE_ALL_0_31) == 0x00000000U) +#define IS_LL_EXTI_LINE_32_63(__VALUE__) (((__VALUE__) & ~LL_EXTI_LINE_ALL_32_63) == 0x00000000U) + +#define IS_LL_EXTI_MODE(__VALUE__) (((__VALUE__) == LL_EXTI_MODE_IT) \ + || ((__VALUE__) == LL_EXTI_MODE_EVENT) \ + || ((__VALUE__) == LL_EXTI_MODE_IT_EVENT)) + + +#define IS_LL_EXTI_TRIGGER(__VALUE__) (((__VALUE__) == LL_EXTI_TRIGGER_NONE) \ + || ((__VALUE__) == LL_EXTI_TRIGGER_RISING) \ + || ((__VALUE__) == LL_EXTI_TRIGGER_FALLING) \ + || ((__VALUE__) == LL_EXTI_TRIGGER_RISING_FALLING)) + +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup EXTI_LL_Exported_Functions + * @{ + */ + +/** @addtogroup EXTI_LL_EF_Init + * @{ + */ + +/** + * @brief De-initialize the EXTI registers to their default reset values. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: EXTI registers are de-initialized + * - ERROR: not applicable + */ +ErrorStatus LL_EXTI_DeInit(void) +{ + /* Interrupt mask register set to default reset values */ + LL_EXTI_WriteReg(IMR1, 0xFFFE0000U); +#if (defined(STM32H573xx) || defined(STM32H563xx) || defined(STM32H562xx)) + LL_EXTI_WriteReg(IMR2, 0x03DBBFFFU); +#else + LL_EXTI_WriteReg(IMR2, 0x001BFFFFU); +#endif /* defined(STM32H573xx) || defined(STM32H563xx) || defined(STM32H562xx) */ + + /* Event mask register set to default reset values */ + LL_EXTI_WriteReg(EMR1, 0x00000000U); + LL_EXTI_WriteReg(EMR2, 0x00000000U); + + /* Rising Trigger selection register set to default reset values */ + LL_EXTI_WriteReg(RTSR1, 0x00000000U); + LL_EXTI_WriteReg(RTSR2, 0x00000000U); + + /* Falling Trigger selection register set to default reset values */ + LL_EXTI_WriteReg(FTSR1, 0x00000000U); + LL_EXTI_WriteReg(FTSR2, 0x00000000U); + + /* Software interrupt event register set to default reset values */ + LL_EXTI_WriteReg(SWIER1, 0x00000000U); + LL_EXTI_WriteReg(SWIER2, 0x00000000U); + + /* Pending register set to default reset values */ + LL_EXTI_WriteReg(RPR1, 0xFFFFFFFFU); + LL_EXTI_WriteReg(FPR1, 0xFFFFFFFFU); + LL_EXTI_WriteReg(RPR2, 0xFFFFFFFFU); + LL_EXTI_WriteReg(FPR2, 0xFFFFFFFFU); + + /* Privilege register set to default reset values */ + LL_EXTI_WriteReg(PRIVCFGR1, 0x00000000U); + LL_EXTI_WriteReg(PRIVCFGR2, 0x00000000U); +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + /* Secure register set to default reset values */ + LL_EXTI_WriteReg(SECCFGR1, 0x00000000U); + LL_EXTI_WriteReg(SECCFGR2, 0x00000000U); +#endif /* __ARM_FEATURE_CMSE */ + return SUCCESS; +} + +/** + * @brief Initialize the EXTI registers according to the specified parameters in EXTI_InitStruct. + * @param EXTI_InitStruct pointer to a @ref LL_EXTI_InitTypeDef structure. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: EXTI registers are initialized + * - ERROR: not applicable + */ +ErrorStatus LL_EXTI_Init(LL_EXTI_InitTypeDef *EXTI_InitStruct) +{ + ErrorStatus status = SUCCESS; + /* Check the parameters */ + assert_param(IS_LL_EXTI_LINE_0_31(EXTI_InitStruct->Line_0_31)); + assert_param(IS_LL_EXTI_LINE_32_63(EXTI_InitStruct->Line_32_63)); + assert_param(IS_FUNCTIONAL_STATE(EXTI_InitStruct->LineCommand)); + assert_param(IS_LL_EXTI_MODE(EXTI_InitStruct->Mode)); + + /* ENABLE LineCommand */ + if (EXTI_InitStruct->LineCommand != DISABLE) + { + assert_param(IS_LL_EXTI_TRIGGER(EXTI_InitStruct->Trigger)); + + /* Configure EXTI Lines in range from 0 to 31 */ + if (EXTI_InitStruct->Line_0_31 != LL_EXTI_LINE_NONE) + { + switch (EXTI_InitStruct->Mode) + { + case LL_EXTI_MODE_IT: + /* First Disable Event on provided Lines */ + LL_EXTI_DisableEvent_0_31(EXTI_InitStruct->Line_0_31); + /* Then Enable IT on provided Lines */ + LL_EXTI_EnableIT_0_31(EXTI_InitStruct->Line_0_31); + break; + case LL_EXTI_MODE_EVENT: + /* First Disable IT on provided Lines */ + LL_EXTI_DisableIT_0_31(EXTI_InitStruct->Line_0_31); + /* Then Enable Event on provided Lines */ + LL_EXTI_EnableEvent_0_31(EXTI_InitStruct->Line_0_31); + break; + case LL_EXTI_MODE_IT_EVENT: + /* Directly Enable IT & Event on provided Lines */ + LL_EXTI_EnableIT_0_31(EXTI_InitStruct->Line_0_31); + LL_EXTI_EnableEvent_0_31(EXTI_InitStruct->Line_0_31); + break; + default: + status = ERROR; + break; + } + if (EXTI_InitStruct->Trigger != LL_EXTI_TRIGGER_NONE) + { + switch (EXTI_InitStruct->Trigger) + { + case LL_EXTI_TRIGGER_RISING: + /* First Disable Falling Trigger on provided Lines */ + LL_EXTI_DisableFallingTrig_0_31(EXTI_InitStruct->Line_0_31); + /* Then Enable Rising Trigger on provided Lines */ + LL_EXTI_EnableRisingTrig_0_31(EXTI_InitStruct->Line_0_31); + break; + case LL_EXTI_TRIGGER_FALLING: + /* First Disable Rising Trigger on provided Lines */ + LL_EXTI_DisableRisingTrig_0_31(EXTI_InitStruct->Line_0_31); + /* Then Enable Falling Trigger on provided Lines */ + LL_EXTI_EnableFallingTrig_0_31(EXTI_InitStruct->Line_0_31); + break; + case LL_EXTI_TRIGGER_RISING_FALLING: + LL_EXTI_EnableRisingTrig_0_31(EXTI_InitStruct->Line_0_31); + LL_EXTI_EnableFallingTrig_0_31(EXTI_InitStruct->Line_0_31); + break; + default: + status = ERROR; + break; + } + } + } + + /* Configure EXTI Lines in range from 32 to 63 */ + if (EXTI_InitStruct->Line_32_63 != LL_EXTI_LINE_NONE) + { + switch (EXTI_InitStruct->Mode) + { + case LL_EXTI_MODE_IT: + /* First Disable Event on provided Lines */ + LL_EXTI_DisableEvent_32_63(EXTI_InitStruct->Line_32_63); + /* Then Enable IT on provided Lines */ + LL_EXTI_EnableIT_32_63(EXTI_InitStruct->Line_32_63); + break; + case LL_EXTI_MODE_EVENT: + /* First Disable IT on provided Lines */ + LL_EXTI_DisableIT_32_63(EXTI_InitStruct->Line_32_63); + /* Then Enable Event on provided Lines */ + LL_EXTI_EnableEvent_32_63(EXTI_InitStruct->Line_32_63); + break; + case LL_EXTI_MODE_IT_EVENT: + /* Directly Enable IT & Event on provided Lines */ + LL_EXTI_EnableIT_32_63(EXTI_InitStruct->Line_32_63); + LL_EXTI_EnableEvent_32_63(EXTI_InitStruct->Line_32_63); + break; + default: + status = ERROR; + break; + } + if (EXTI_InitStruct->Trigger != LL_EXTI_TRIGGER_NONE) + { + switch (EXTI_InitStruct->Trigger) + { + case LL_EXTI_TRIGGER_RISING: + /* First Disable Falling Trigger on provided Lines */ + LL_EXTI_DisableFallingTrig_32_63(EXTI_InitStruct->Line_32_63); + /* Then Enable Rising Trigger on provided Lines */ + LL_EXTI_EnableRisingTrig_32_63(EXTI_InitStruct->Line_32_63); + break; + case LL_EXTI_TRIGGER_FALLING: + /* First Disable Rising Trigger on provided Lines */ + LL_EXTI_DisableRisingTrig_32_63(EXTI_InitStruct->Line_32_63); + /* Then Enable Falling Trigger on provided Lines */ + LL_EXTI_EnableFallingTrig_32_63(EXTI_InitStruct->Line_32_63); + break; + case LL_EXTI_TRIGGER_RISING_FALLING: + LL_EXTI_EnableRisingTrig_32_63(EXTI_InitStruct->Line_32_63); + LL_EXTI_EnableFallingTrig_32_63(EXTI_InitStruct->Line_32_63); + break; + default: + status = ERROR; + break; + } + } + } + } + /* DISABLE LineCommand */ + else + { + /* De-configure EXTI Lines in range from 0 to 31 */ + LL_EXTI_DisableIT_0_31(EXTI_InitStruct->Line_0_31); + LL_EXTI_DisableEvent_0_31(EXTI_InitStruct->Line_0_31); + + /* De-configure EXTI Lines in range from 32 to 63 */ + LL_EXTI_DisableIT_32_63(EXTI_InitStruct->Line_32_63); + LL_EXTI_DisableEvent_32_63(EXTI_InitStruct->Line_32_63); + } + return status; +} + +/** + * @brief Set each @ref LL_EXTI_InitTypeDef field to default value. + * @param EXTI_InitStruct Pointer to a @ref LL_EXTI_InitTypeDef structure. + * @retval None + */ +void LL_EXTI_StructInit(LL_EXTI_InitTypeDef *EXTI_InitStruct) +{ + EXTI_InitStruct->Line_0_31 = LL_EXTI_LINE_NONE; + EXTI_InitStruct->Line_32_63 = LL_EXTI_LINE_NONE; + EXTI_InitStruct->LineCommand = DISABLE; + EXTI_InitStruct->Mode = LL_EXTI_MODE_IT; + EXTI_InitStruct->Trigger = LL_EXTI_TRIGGER_FALLING; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined (EXTI) */ + +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_fmac.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_fmac.c new file mode 100644 index 0000000000..4451b98497 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_fmac.c @@ -0,0 +1,136 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_fmac.c + * @author MCD Application Team + * @brief Header for stm32h5xx_ll_fmac.c module + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +#if defined(USE_FULL_LL_DRIVER) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_fmac.h" +#include "stm32h5xx_ll_bus.h" +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined(FMAC) + +/** @addtogroup FMAC_LL + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Global variables ----------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Functions Definition ------------------------------------------------------*/ +/** @addtogroup FMAC_LL_Exported_Functions + * @{ + */ + +/** @addtogroup FMAC_LL_EF_Init + * @{ + */ + +/** + * @brief Initialize FMAC peripheral registers to their default reset values. + * @param FMACx FMAC Instance + * @retval ErrorStatus enumeration value: + * - SUCCESS: FMAC registers are initialized + * - ERROR: FMAC registers are not initialized + */ +ErrorStatus LL_FMAC_Init(FMAC_TypeDef *FMACx) +{ + ErrorStatus status = SUCCESS; + + /* Check the parameters */ + assert_param(IS_FMAC_ALL_INSTANCE(FMACx)); + + if (FMACx == FMAC) + { + /* Perform the reset */ + LL_FMAC_EnableReset(FMACx); + + /* Wait until flag is reset */ + while (LL_FMAC_IsEnabledReset(FMACx) != 0UL) + { + } + } + else + { + status = ERROR; + } + + return (status); +} + +/** + * @brief De-Initialize FMAC peripheral registers to their default reset values. + * @param FMACx FMAC Instance + * @retval An ErrorStatus enumeration value: + * - SUCCESS: FMAC registers are de-initialized + * - ERROR: FMAC registers are not de-initialized + */ +ErrorStatus LL_FMAC_DeInit(const FMAC_TypeDef *FMACx) +{ + ErrorStatus status = SUCCESS; + + /* Check the parameters */ + assert_param(IS_FMAC_ALL_INSTANCE(FMACx)); + + if (FMACx == FMAC) + { + /* Force FMAC reset */ + LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_FMAC); + + /* Release FMAC reset */ + LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_FMAC); + } + else + { + status = ERROR; + } + + return (status); +} + + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined(FMAC) */ + +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_fmc.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_fmc.c new file mode 100644 index 0000000000..0105b3cce9 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_fmc.c @@ -0,0 +1,1162 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_fmc.c + * @author MCD Application Team + * @brief FMC Low Layer HAL module driver. + * + * This file provides firmware functions to manage the following + * functionalities of the Flexible Memory Controller (FMC) peripheral memories: + * + Initialization/de-initialization functions + * + Peripheral Control functions + * + Peripheral State functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2022 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 + ============================================================================== + ##### FMC peripheral features ##### + ============================================================================== + [..] The Flexible memory controller (FMC) includes following memory controllers: + (+) The NOR/PSRAM memory controller + (+) The NAND memory controller + (+) The Synchronous DRAM (SDRAM) controller + + [..] The FMC functional block makes the interface with synchronous and asynchronous static + memories and SDRAM memories. Its main purposes are: + (+) to translate AHB transactions into the appropriate external device protocol + (+) to meet the access time requirements of the external memory devices + + [..] All external memories share the addresses, data and control signals with the controller. + Each external device is accessed by means of a unique Chip Select. The FMC performs + only one access at a time to an external device. + The main features of the FMC controller are the following: + (+) Interface with static-memory mapped devices including: + (++) Static random access memory (SRAM) + (++) Read-only memory (ROM) + (++) NOR Flash memory/OneNAND Flash memory + (++) PSRAM (4 memory banks) + (++) Two banks of NAND Flash memory with ECC hardware to check up to 8 Kbytes of + data + (+) Interface with synchronous DRAM (SDRAM) memories + (+) Independent Chip Select control for each memory bank + (+) Independent configuration for each memory bank + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ +#if defined(HAL_NOR_MODULE_ENABLED) || defined(HAL_NAND_MODULE_ENABLED) || defined(HAL_SDRAM_MODULE_ENABLED)\ + || defined(HAL_SRAM_MODULE_ENABLED) + +/** @defgroup FMC_LL FMC Low Layer + * @brief FMC driver modules + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/** @defgroup FMC_LL_Private_Constants FMC Low Layer Private Constants + * @{ + */ + +/* ----------------------- FMC registers bit mask --------------------------- */ + +#if defined(FMC_BANK1) +/* --- BCR Register ---*/ +/* BCR register clear mask */ + +/* --- BTR Register ---*/ +/* BTR register clear mask */ +#define BTR_CLEAR_MASK ((uint32_t)(FMC_BTRx_ADDSET | FMC_BTRx_ADDHLD |\ + FMC_BTRx_DATAST | FMC_BTRx_BUSTURN |\ + FMC_BTRx_CLKDIV | FMC_BTRx_DATLAT |\ + FMC_BTRx_ACCMOD | FMC_BTRx_DATAHLD)) + +/* --- BWTR Register ---*/ +/* BWTR register clear mask */ +#define BWTR_CLEAR_MASK ((uint32_t)(FMC_BWTRx_ADDSET | FMC_BWTRx_ADDHLD |\ + FMC_BWTRx_DATAST | FMC_BWTRx_BUSTURN |\ + FMC_BWTRx_ACCMOD | FMC_BWTRx_DATAHLD)) +#endif /* FMC_BANK1 */ +#if defined(FMC_BANK3) + +/* --- PCR Register ---*/ +/* PCR register clear mask */ +#define PCR_CLEAR_MASK ((uint32_t)(FMC_PCR_PWAITEN | FMC_PCR_PBKEN | \ + FMC_PCR_PTYP | FMC_PCR_PWID | \ + FMC_PCR_ECCEN | FMC_PCR_TCLR | \ + FMC_PCR_TAR | FMC_PCR_ECCPS)) +/* --- PMEM Register ---*/ +/* PMEM register clear mask */ +#define PMEM_CLEAR_MASK ((uint32_t)(FMC_PMEM_MEMSET | FMC_PMEM_MEMWAIT |\ + FMC_PMEM_MEMHOLD | FMC_PMEM_MEMHIZ)) + +/* --- PATT Register ---*/ +/* PATT register clear mask */ +#define PATT_CLEAR_MASK ((uint32_t)(FMC_PATT_ATTSET | FMC_PATT_ATTWAIT |\ + FMC_PATT_ATTHOLD | FMC_PATT_ATTHIZ)) + +#endif /* FMC_BANK3 */ +#if defined(FMC_Bank5_6_R) + +/* --- SDCR Register ---*/ +/* SDCR register clear mask */ +#define SDCR_CLEAR_MASK ((uint32_t)(FMC_SDCRx_NC | FMC_SDCRx_NR | \ + FMC_SDCRx_MWID | FMC_SDCRx_NB | \ + FMC_SDCRx_CAS | FMC_SDCRx_WP | \ + FMC_SDCRx_SDCLK | FMC_SDCRx_RBURST | \ + FMC_SDCRx_RPIPE)) + +/* --- SDTR Register ---*/ +/* SDTR register clear mask */ +#define SDTR_CLEAR_MASK ((uint32_t)(FMC_SDTRx_TMRD | FMC_SDTRx_TXSR | \ + FMC_SDTRx_TRAS | FMC_SDTRx_TRC | \ + FMC_SDTRx_TWR | FMC_SDTRx_TRP | \ + FMC_SDTRx_TRCD)) +#endif /* FMC_Bank5_6_R */ + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup FMC_LL_Exported_Functions FMC Low Layer Exported Functions + * @{ + */ + +#if defined(FMC_BANK1) + +/** @defgroup FMC_LL_Exported_Functions_NORSRAM FMC Low Layer NOR SRAM Exported Functions + * @brief NORSRAM Controller functions + * + @verbatim + ============================================================================== + ##### How to use NORSRAM device driver ##### + ============================================================================== + + [..] + This driver contains a set of APIs to interface with the FMC NORSRAM banks in order + to run the NORSRAM external devices. + + (+) FMC NORSRAM bank reset using the function FMC_NORSRAM_DeInit() + (+) FMC NORSRAM bank control configuration using the function FMC_NORSRAM_Init() + (+) FMC NORSRAM bank timing configuration using the function FMC_NORSRAM_Timing_Init() + (+) FMC NORSRAM bank extended timing configuration using the function + FMC_NORSRAM_Extended_Timing_Init() + (+) FMC NORSRAM bank enable/disable write operation using the functions + FMC_NORSRAM_WriteOperation_Enable()/FMC_NORSRAM_WriteOperation_Disable() + +@endverbatim + * @{ + */ + +/** @defgroup FMC_LL_NORSRAM_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 FMC NORSRAM interface + (+) De-initialize the FMC NORSRAM interface + (+) Configure the FMC clock and associated GPIOs + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the FMC_NORSRAM device according to the specified + * control parameters in the FMC_NORSRAM_InitTypeDef + * @param Device Pointer to NORSRAM device instance + * @param Init Pointer to NORSRAM Initialization structure + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NORSRAM_Init(FMC_NORSRAM_TypeDef *Device, + FMC_NORSRAM_InitTypeDef *Init) +{ + uint32_t flashaccess; + uint32_t btcr_reg; + uint32_t mask; + + /* Check the parameters */ + assert_param(IS_FMC_NORSRAM_DEVICE(Device)); + assert_param(IS_FMC_NORSRAM_BANK(Init->NSBank)); + assert_param(IS_FMC_MUX(Init->DataAddressMux)); + assert_param(IS_FMC_MEMORY(Init->MemoryType)); + assert_param(IS_FMC_NORSRAM_MEMORY_WIDTH(Init->MemoryDataWidth)); + assert_param(IS_FMC_BURSTMODE(Init->BurstAccessMode)); + assert_param(IS_FMC_WAIT_POLARITY(Init->WaitSignalPolarity)); + assert_param(IS_FMC_WAIT_SIGNAL_ACTIVE(Init->WaitSignalActive)); + assert_param(IS_FMC_WRITE_OPERATION(Init->WriteOperation)); + assert_param(IS_FMC_WAITE_SIGNAL(Init->WaitSignal)); + assert_param(IS_FMC_EXTENDED_MODE(Init->ExtendedMode)); + assert_param(IS_FMC_ASYNWAIT(Init->AsynchronousWait)); + assert_param(IS_FMC_WRITE_BURST(Init->WriteBurst)); + assert_param(IS_FMC_CONTINOUS_CLOCK(Init->ContinuousClock)); + assert_param(IS_FMC_WRITE_FIFO(Init->WriteFifo)); + assert_param(IS_FMC_PAGESIZE(Init->PageSize)); + assert_param(IS_FMC_NBL_SETUPTIME(Init->NBLSetupTime)); + assert_param(IS_FUNCTIONAL_STATE(Init->MaxChipSelectPulse)); + + /* Disable NORSRAM Device */ + __FMC_NORSRAM_DISABLE(Device, Init->NSBank); + + /* Set NORSRAM device control parameters */ + if (Init->MemoryType == FMC_MEMORY_TYPE_NOR) + { + flashaccess = FMC_NORSRAM_FLASH_ACCESS_ENABLE; + } + else + { + flashaccess = FMC_NORSRAM_FLASH_ACCESS_DISABLE; + } + + btcr_reg = (flashaccess | \ + Init->DataAddressMux | \ + Init->MemoryType | \ + Init->MemoryDataWidth | \ + Init->BurstAccessMode | \ + Init->WaitSignalPolarity | \ + Init->WaitSignalActive | \ + Init->WriteOperation | \ + Init->WaitSignal | \ + Init->ExtendedMode | \ + Init->AsynchronousWait | \ + Init->WriteBurst); + + btcr_reg |= Init->ContinuousClock; + btcr_reg |= Init->WriteFifo; + btcr_reg |= Init->NBLSetupTime; + btcr_reg |= Init->PageSize; + + mask = (FMC_BCRx_MBKEN | + FMC_BCRx_MUXEN | + FMC_BCRx_MTYP | + FMC_BCRx_MWID | + FMC_BCRx_FACCEN | + FMC_BCRx_BURSTEN | + FMC_BCRx_WAITPOL | + FMC_BCRx_WAITCFG | + FMC_BCRx_WREN | + FMC_BCRx_WAITEN | + FMC_BCRx_EXTMOD | + FMC_BCRx_ASYNCWAIT | + FMC_BCRx_CBURSTRW); + + mask |= FMC_BCR1_CCLKEN; + mask |= FMC_BCR1_WFDIS; + mask |= FMC_BCRx_NBLSET; + mask |= FMC_BCRx_CPSIZE; + + MODIFY_REG(Device->BTCR[Init->NSBank], mask, btcr_reg); + + /* Configure synchronous mode when Continuous clock is enabled for bank2..4 */ + if ((Init->ContinuousClock == FMC_CONTINUOUS_CLOCK_SYNC_ASYNC) && (Init->NSBank != FMC_NORSRAM_BANK1)) + { + MODIFY_REG(Device->BTCR[FMC_NORSRAM_BANK1], FMC_BCR1_CCLKEN, Init->ContinuousClock); + } + + if (Init->NSBank != FMC_NORSRAM_BANK1) + { + /* Configure Write FIFO mode when Write Fifo is enabled for bank2..4 */ + SET_BIT(Device->BTCR[FMC_NORSRAM_BANK1], (uint32_t)(Init->WriteFifo)); + } + + /* Check PSRAM chip select counter state */ + if (Init->MaxChipSelectPulse == ENABLE) + { + /* Check the parameters */ + assert_param(IS_FMC_MAX_CHIP_SELECT_PULSE_TIME(Init->MaxChipSelectPulseTime)); + + /* Configure PSRAM chip select counter value */ + MODIFY_REG(Device->PCSCNTR, FMC_PCSCNTR_CSCOUNT, (uint32_t)(Init->MaxChipSelectPulseTime)); + + /* Enable PSRAM chip select counter for the bank */ + switch (Init->NSBank) + { + case FMC_NORSRAM_BANK1 : + SET_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB1EN); + break; + + case FMC_NORSRAM_BANK2 : + SET_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB2EN); + break; + + case FMC_NORSRAM_BANK3 : + SET_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB3EN); + break; + + default : + SET_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB4EN); + break; + } + } + + return HAL_OK; +} + +/** + * @brief DeInitialize the FMC_NORSRAM peripheral + * @param Device Pointer to NORSRAM device instance + * @param ExDevice Pointer to NORSRAM extended mode device instance + * @param Bank NORSRAM bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NORSRAM_DeInit(FMC_NORSRAM_TypeDef *Device, + FMC_NORSRAM_EXTENDED_TypeDef *ExDevice, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NORSRAM_DEVICE(Device)); + assert_param(IS_FMC_NORSRAM_EXTENDED_DEVICE(ExDevice)); + assert_param(IS_FMC_NORSRAM_BANK(Bank)); + + /* Disable the FMC_NORSRAM device */ + __FMC_NORSRAM_DISABLE(Device, Bank); + + /* De-initialize the FMC_NORSRAM device */ + /* FMC_NORSRAM_BANK1 */ + if (Bank == FMC_NORSRAM_BANK1) + { + Device->BTCR[Bank] = 0x000030DBU; + } + /* FMC_NORSRAM_BANK2, FMC_NORSRAM_BANK3 or FMC_NORSRAM_BANK4 */ + else + { + Device->BTCR[Bank] = 0x000030D2U; + } + + Device->BTCR[Bank + 1U] = 0x0FFFFFFFU; + ExDevice->BWTR[Bank] = 0x0FFFFFFFU; + + /* De-initialize PSRAM chip select counter */ + switch (Bank) + { + case FMC_NORSRAM_BANK1 : + CLEAR_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB1EN); + break; + + case FMC_NORSRAM_BANK2 : + CLEAR_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB2EN); + break; + + case FMC_NORSRAM_BANK3 : + CLEAR_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB3EN); + break; + + default : + CLEAR_BIT(Device->PCSCNTR, FMC_PCSCNTR_CNTB4EN); + break; + } + + return HAL_OK; +} + +/** + * @brief Initialize the FMC_NORSRAM Timing according to the specified + * parameters in the FMC_NORSRAM_TimingTypeDef + * @param Device Pointer to NORSRAM device instance + * @param Timing Pointer to NORSRAM Timing structure + * @param Bank NORSRAM bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NORSRAM_Timing_Init(FMC_NORSRAM_TypeDef *Device, + FMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank) +{ + uint32_t tmpr; + + /* Check the parameters */ + assert_param(IS_FMC_NORSRAM_DEVICE(Device)); + assert_param(IS_FMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime)); + assert_param(IS_FMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime)); + assert_param(IS_FMC_DATAHOLD_DURATION(Timing->DataHoldTime)); + assert_param(IS_FMC_DATASETUP_TIME(Timing->DataSetupTime)); + assert_param(IS_FMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration)); + assert_param(IS_FMC_CLK_DIV(Timing->CLKDivision)); + assert_param(IS_FMC_DATA_LATENCY(Timing->DataLatency)); + assert_param(IS_FMC_ACCESS_MODE(Timing->AccessMode)); + assert_param(IS_FMC_NORSRAM_BANK(Bank)); + + /* Set FMC_NORSRAM device timing parameters */ + MODIFY_REG(Device->BTCR[Bank + 1U], BTR_CLEAR_MASK, (Timing->AddressSetupTime | + ((Timing->AddressHoldTime) << FMC_BTRx_ADDHLD_Pos) | + ((Timing->DataSetupTime) << FMC_BTRx_DATAST_Pos) | + ((Timing->DataHoldTime) << FMC_BTRx_DATAHLD_Pos) | + ((Timing->BusTurnAroundDuration) << FMC_BTRx_BUSTURN_Pos) | + (((Timing->CLKDivision) - 1U) << FMC_BTRx_CLKDIV_Pos) | + (((Timing->DataLatency) - 2U) << FMC_BTRx_DATLAT_Pos) | + (Timing->AccessMode))); + + /* Configure Clock division value (in NORSRAM bank 1) when continuous clock is enabled */ + if (HAL_IS_BIT_SET(Device->BTCR[FMC_NORSRAM_BANK1], FMC_BCR1_CCLKEN)) + { + tmpr = (uint32_t)(Device->BTCR[FMC_NORSRAM_BANK1 + 1U] & ~((0x0FU) << FMC_BTRx_CLKDIV_Pos)); + tmpr |= (uint32_t)(((Timing->CLKDivision) - 1U) << FMC_BTRx_CLKDIV_Pos); + MODIFY_REG(Device->BTCR[FMC_NORSRAM_BANK1 + 1U], FMC_BTRx_CLKDIV, tmpr); + } + + return HAL_OK; +} + +/** + * @brief Initialize the FMC_NORSRAM Extended mode Timing according to the specified + * parameters in the FMC_NORSRAM_TimingTypeDef + * @param Device Pointer to NORSRAM device instance + * @param Timing Pointer to NORSRAM Timing structure + * @param Bank NORSRAM bank number + * @param ExtendedMode FMC Extended Mode + * This parameter can be one of the following values: + * @arg FMC_EXTENDED_MODE_DISABLE + * @arg FMC_EXTENDED_MODE_ENABLE + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NORSRAM_Extended_Timing_Init(FMC_NORSRAM_EXTENDED_TypeDef *Device, + FMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank, + uint32_t ExtendedMode) +{ + /* Check the parameters */ + assert_param(IS_FMC_EXTENDED_MODE(ExtendedMode)); + + /* Set NORSRAM device timing register for write configuration, if extended mode is used */ + if (ExtendedMode == FMC_EXTENDED_MODE_ENABLE) + { + /* Check the parameters */ + assert_param(IS_FMC_NORSRAM_EXTENDED_DEVICE(Device)); + assert_param(IS_FMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime)); + assert_param(IS_FMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime)); + assert_param(IS_FMC_DATASETUP_TIME(Timing->DataSetupTime)); + assert_param(IS_FMC_DATAHOLD_DURATION(Timing->DataHoldTime)); + assert_param(IS_FMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration)); + assert_param(IS_FMC_ACCESS_MODE(Timing->AccessMode)); + assert_param(IS_FMC_NORSRAM_BANK(Bank)); + + /* Set NORSRAM device timing register for write configuration, if extended mode is used */ + MODIFY_REG(Device->BWTR[Bank], BWTR_CLEAR_MASK, (Timing->AddressSetupTime | + ((Timing->AddressHoldTime) << FMC_BWTRx_ADDHLD_Pos) | + ((Timing->DataSetupTime) << FMC_BWTRx_DATAST_Pos) | + ((Timing->DataHoldTime) << FMC_BWTRx_DATAHLD_Pos) | + Timing->AccessMode | + ((Timing->BusTurnAroundDuration) << FMC_BWTRx_BUSTURN_Pos))); + } + else + { + Device->BWTR[Bank] = 0x0FFFFFFFU; + } + + return HAL_OK; +} +/** + * @} + */ + +/** @addtogroup FMC_LL_NORSRAM_Private_Functions_Group2 + * @brief management functions + * +@verbatim + ============================================================================== + ##### FMC_NORSRAM Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control dynamically + the FMC NORSRAM interface. + +@endverbatim + * @{ + */ + +/** + * @brief Enables dynamically FMC_NORSRAM write operation. + * @param Device Pointer to NORSRAM device instance + * @param Bank NORSRAM bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NORSRAM_WriteOperation_Enable(FMC_NORSRAM_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NORSRAM_DEVICE(Device)); + assert_param(IS_FMC_NORSRAM_BANK(Bank)); + + /* Enable write operation */ + SET_BIT(Device->BTCR[Bank], FMC_WRITE_OPERATION_ENABLE); + + return HAL_OK; +} + +/** + * @brief Disables dynamically FMC_NORSRAM write operation. + * @param Device Pointer to NORSRAM device instance + * @param Bank NORSRAM bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NORSRAM_WriteOperation_Disable(FMC_NORSRAM_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NORSRAM_DEVICE(Device)); + assert_param(IS_FMC_NORSRAM_BANK(Bank)); + + /* Disable write operation */ + CLEAR_BIT(Device->BTCR[Bank], FMC_WRITE_OPERATION_ENABLE); + + return HAL_OK; +} + +/** + * @} + */ + +/** + * @} + */ +#endif /* FMC_BANK1 */ + +#if defined(FMC_BANK3) + +/** @defgroup FMC_LL_Exported_Functions_NAND FMC Low Layer NAND Exported Functions + * @brief NAND Controller functions + * + @verbatim + ============================================================================== + ##### How to use NAND device driver ##### + ============================================================================== + [..] + This driver contains a set of APIs to interface with the FMC NAND banks in order + to run the NAND external devices. + + (+) FMC NAND bank reset using the function FMC_NAND_DeInit() + (+) FMC NAND bank control configuration using the function FMC_NAND_Init() + (+) FMC NAND bank common space timing configuration using the function + FMC_NAND_CommonSpace_Timing_Init() + (+) FMC NAND bank attribute space timing configuration using the function + FMC_NAND_AttributeSpace_Timing_Init() + (+) FMC NAND bank enable/disable ECC correction feature using the functions + FMC_NAND_ECC_Enable()/FMC_NAND_ECC_Disable() + (+) FMC NAND bank get ECC correction code using the function FMC_NAND_GetECC() + +@endverbatim + * @{ + */ + +/** @defgroup FMC_LL_NAND_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 FMC NAND interface + (+) De-initialize the FMC NAND interface + (+) Configure the FMC clock and associated GPIOs + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the FMC_NAND device according to the specified + * control parameters in the FMC_NAND_HandleTypeDef + * @param Device Pointer to NAND device instance + * @param Init Pointer to NAND Initialization structure + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NAND_Init(FMC_NAND_TypeDef *Device, FMC_NAND_InitTypeDef *Init) +{ + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_NAND_BANK(Init->NandBank)); + assert_param(IS_FMC_WAIT_FEATURE(Init->Waitfeature)); + assert_param(IS_FMC_NAND_MEMORY_WIDTH(Init->MemoryDataWidth)); + assert_param(IS_FMC_ECC_STATE(Init->EccComputation)); + assert_param(IS_FMC_ECCPAGE_SIZE(Init->ECCPageSize)); + assert_param(IS_FMC_TCLR_TIME(Init->TCLRSetupTime)); + assert_param(IS_FMC_TAR_TIME(Init->TARSetupTime)); + + /* NAND bank 3 registers configuration */ + MODIFY_REG(Device->PCR, PCR_CLEAR_MASK, (Init->Waitfeature | + FMC_PCR_MEMORY_TYPE_NAND | + Init->MemoryDataWidth | + Init->EccComputation | + Init->ECCPageSize | + ((Init->TCLRSetupTime) << FMC_PCR_TCLR_Pos) | + ((Init->TARSetupTime) << FMC_PCR_TAR_Pos))); + + return HAL_OK; +} + +/** + * @brief Initializes the FMC_NAND Common space Timing according to the specified + * parameters in the FMC_NAND_PCC_TimingTypeDef + * @param Device Pointer to NAND device instance + * @param Timing Pointer to NAND timing structure + * @param Bank NAND bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NAND_CommonSpace_Timing_Init(FMC_NAND_TypeDef *Device, + FMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime)); + assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime)); + assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime)); + assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + /* Prevent unused argument(s) compilation warning if no assert_param check */ + UNUSED(Bank); + + /* NAND bank 3 registers configuration */ + MODIFY_REG(Device->PMEM, PMEM_CLEAR_MASK, (Timing->SetupTime | + ((Timing->WaitSetupTime) << FMC_PMEM_MEMWAIT_Pos) | + ((Timing->HoldSetupTime) << FMC_PMEM_MEMHOLD_Pos) | + ((Timing->HiZSetupTime) << FMC_PMEM_MEMHIZ_Pos))); + + return HAL_OK; +} + +/** + * @brief Initializes the FMC_NAND Attribute space Timing according to the specified + * parameters in the FMC_NAND_PCC_TimingTypeDef + * @param Device Pointer to NAND device instance + * @param Timing Pointer to NAND timing structure + * @param Bank NAND bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NAND_AttributeSpace_Timing_Init(FMC_NAND_TypeDef *Device, + FMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime)); + assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime)); + assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime)); + assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + /* Prevent unused argument(s) compilation warning if no assert_param check */ + UNUSED(Bank); + + /* NAND bank 3 registers configuration */ + MODIFY_REG(Device->PATT, PATT_CLEAR_MASK, (Timing->SetupTime | + ((Timing->WaitSetupTime) << FMC_PATT_ATTWAIT_Pos) | + ((Timing->HoldSetupTime) << FMC_PATT_ATTHOLD_Pos) | + ((Timing->HiZSetupTime) << FMC_PATT_ATTHIZ_Pos))); + + return HAL_OK; +} + +/** + * @brief DeInitializes the FMC_NAND device + * @param Device Pointer to NAND device instance + * @param Bank NAND bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NAND_DeInit(FMC_NAND_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + /* Disable the NAND Bank */ + __FMC_NAND_DISABLE(Device, Bank); + + /* De-initialize the NAND Bank */ + /* Prevent unused argument(s) compilation warning if no assert_param check */ + UNUSED(Bank); + + /* Set the FMC_NAND_BANK3 registers to their reset values */ + WRITE_REG(Device->PCR, 0x00000018U); + WRITE_REG(Device->SR, 0x00000040U); + WRITE_REG(Device->PMEM, 0xFCFCFCFCU); + WRITE_REG(Device->PATT, 0xFCFCFCFCU); + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup HAL_FMC_NAND_Group2 Peripheral Control functions + * @brief management functions + * +@verbatim + ============================================================================== + ##### FMC_NAND Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control dynamically + the FMC NAND interface. + +@endverbatim + * @{ + */ + + +/** + * @brief Enables dynamically FMC_NAND ECC feature. + * @param Device Pointer to NAND device instance + * @param Bank NAND bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NAND_ECC_Enable(FMC_NAND_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + /* Enable ECC feature */ + /* Prevent unused argument(s) compilation warning if no assert_param check */ + UNUSED(Bank); + + SET_BIT(Device->PCR, FMC_PCR_ECCEN); + + return HAL_OK; +} + + +/** + * @brief Disables dynamically FMC_NAND ECC feature. + * @param Device Pointer to NAND device instance + * @param Bank NAND bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NAND_ECC_Disable(FMC_NAND_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + /* Disable ECC feature */ + /* Prevent unused argument(s) compilation warning if no assert_param check */ + UNUSED(Bank); + + CLEAR_BIT(Device->PCR, FMC_PCR_ECCEN); + + return HAL_OK; +} + +/** + * @brief Disables dynamically FMC_NAND ECC feature. + * @param Device Pointer to NAND device instance + * @param ECCval Pointer to ECC value + * @param Bank NAND bank number + * @param Timeout Timeout wait value + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NAND_GetECC(FMC_NAND_TypeDef *Device, uint32_t *ECCval, uint32_t Bank, + uint32_t Timeout) +{ + uint32_t tickstart; + + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait until FIFO is empty */ + while (__FMC_NAND_GET_FLAG(Device, Bank, FMC_FLAG_FEMPT) == RESET) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + return HAL_TIMEOUT; + } + } + } + + /* Prevent unused argument(s) compilation warning if no assert_param check */ + UNUSED(Bank); + + /* Get the ECCR register value */ + *ECCval = (uint32_t)Device->ECCR; + + return HAL_OK; +} + +/** + * @} + */ +#endif /* FMC_BANK3 */ + + +#if defined(FMC_Bank5_6_R) + +/** @defgroup FMC_LL_SDRAM + * @brief SDRAM Controller functions + * + @verbatim + ============================================================================== + ##### How to use SDRAM device driver ##### + ============================================================================== + [..] + This driver contains a set of APIs to interface with the FMC SDRAM banks in order + to run the SDRAM external devices. + + (+) FMC SDRAM bank reset using the function FMC_SDRAM_DeInit() + (+) FMC SDRAM bank control configuration using the function FMC_SDRAM_Init() + (+) FMC SDRAM bank timing configuration using the function FMC_SDRAM_Timing_Init() + (+) FMC SDRAM bank enable/disable write operation using the functions + FMC_SDRAM_WriteOperation_Enable()/FMC_SDRAM_WriteOperation_Disable() + (+) FMC SDRAM bank send command using the function FMC_SDRAM_SendCommand() + +@endverbatim + * @{ + */ + +/** @addtogroup FMC_LL_SDRAM_Private_Functions_Group1 + * @brief Initialization and Configuration functions + * +@verbatim + ============================================================================== + ##### Initialization and de_initialization functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the FMC SDRAM interface + (+) De-initialize the FMC SDRAM interface + (+) Configure the FMC clock and associated GPIOs + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the FMC_SDRAM device according to the specified + * control parameters in the FMC_SDRAM_InitTypeDef + * @param Device Pointer to SDRAM device instance + * @param Init Pointer to SDRAM Initialization structure + * @retval HAL status + */ +HAL_StatusTypeDef FMC_SDRAM_Init(FMC_SDRAM_TypeDef *Device, FMC_SDRAM_InitTypeDef *Init) +{ + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_SDRAM_BANK(Init->SDBank)); + assert_param(IS_FMC_COLUMNBITS_NUMBER(Init->ColumnBitsNumber)); + assert_param(IS_FMC_ROWBITS_NUMBER(Init->RowBitsNumber)); + assert_param(IS_FMC_SDMEMORY_WIDTH(Init->MemoryDataWidth)); + assert_param(IS_FMC_INTERNALBANK_NUMBER(Init->InternalBankNumber)); + assert_param(IS_FMC_CAS_LATENCY(Init->CASLatency)); + assert_param(IS_FMC_WRITE_PROTECTION(Init->WriteProtection)); + assert_param(IS_FMC_SDCLOCK_PERIOD(Init->SDClockPeriod)); + assert_param(IS_FMC_READ_BURST(Init->ReadBurst)); + assert_param(IS_FMC_READPIPE_DELAY(Init->ReadPipeDelay)); + + /* Set SDRAM bank configuration parameters */ + if (Init->SDBank == FMC_SDRAM_BANK1) + { + MODIFY_REG(Device->SDCR[FMC_SDRAM_BANK1], + SDCR_CLEAR_MASK, + (Init->ColumnBitsNumber | + Init->RowBitsNumber | + Init->MemoryDataWidth | + Init->InternalBankNumber | + Init->CASLatency | + Init->WriteProtection | + Init->SDClockPeriod | + Init->ReadBurst | + Init->ReadPipeDelay)); + } + else /* FMC_Bank2_SDRAM */ + { + MODIFY_REG(Device->SDCR[FMC_SDRAM_BANK1], + FMC_SDCRx_SDCLK | + FMC_SDCRx_RBURST | + FMC_SDCRx_RPIPE, + (Init->SDClockPeriod | + Init->ReadBurst | + Init->ReadPipeDelay)); + + MODIFY_REG(Device->SDCR[FMC_SDRAM_BANK2], + SDCR_CLEAR_MASK, + (Init->ColumnBitsNumber | + Init->RowBitsNumber | + Init->MemoryDataWidth | + Init->InternalBankNumber | + Init->CASLatency | + Init->WriteProtection)); + } + + return HAL_OK; +} + + +/** + * @brief Initializes the FMC_SDRAM device timing according to the specified + * parameters in the FMC_SDRAM_TimingTypeDef + * @param Device Pointer to SDRAM device instance + * @param Timing Pointer to SDRAM Timing structure + * @param Bank SDRAM bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_SDRAM_Timing_Init(FMC_SDRAM_TypeDef *Device, + FMC_SDRAM_TimingTypeDef *Timing, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_LOADTOACTIVE_DELAY(Timing->LoadToActiveDelay)); + assert_param(IS_FMC_EXITSELFREFRESH_DELAY(Timing->ExitSelfRefreshDelay)); + assert_param(IS_FMC_SELFREFRESH_TIME(Timing->SelfRefreshTime)); + assert_param(IS_FMC_ROWCYCLE_DELAY(Timing->RowCycleDelay)); + assert_param(IS_FMC_WRITE_RECOVERY_TIME(Timing->WriteRecoveryTime)); + assert_param(IS_FMC_RP_DELAY(Timing->RPDelay)); + assert_param(IS_FMC_RCD_DELAY(Timing->RCDDelay)); + assert_param(IS_FMC_SDRAM_BANK(Bank)); + + /* Set SDRAM device timing parameters */ + if (Bank == FMC_SDRAM_BANK1) + { + MODIFY_REG(Device->SDTR[FMC_SDRAM_BANK1], + SDTR_CLEAR_MASK, + (((Timing->LoadToActiveDelay) - 1U) | + (((Timing->ExitSelfRefreshDelay) - 1U) << FMC_SDTRx_TXSR_Pos) | + (((Timing->SelfRefreshTime) - 1U) << FMC_SDTRx_TRAS_Pos) | + (((Timing->RowCycleDelay) - 1U) << FMC_SDTRx_TRC_Pos) | + (((Timing->WriteRecoveryTime) - 1U) << FMC_SDTRx_TWR_Pos) | + (((Timing->RPDelay) - 1U) << FMC_SDTRx_TRP_Pos) | + (((Timing->RCDDelay) - 1U) << FMC_SDTRx_TRCD_Pos))); + } + else /* FMC_Bank2_SDRAM */ + { + MODIFY_REG(Device->SDTR[FMC_SDRAM_BANK1], + FMC_SDTRx_TRC | + FMC_SDTRx_TRP, + (((Timing->RowCycleDelay) - 1U) << FMC_SDTRx_TRC_Pos) | + (((Timing->RPDelay) - 1U) << FMC_SDTRx_TRP_Pos)); + + MODIFY_REG(Device->SDTR[FMC_SDRAM_BANK2], + SDTR_CLEAR_MASK, + (((Timing->LoadToActiveDelay) - 1U) | + (((Timing->ExitSelfRefreshDelay) - 1U) << FMC_SDTRx_TXSR_Pos) | + (((Timing->SelfRefreshTime) - 1U) << FMC_SDTRx_TRAS_Pos) | + (((Timing->WriteRecoveryTime) - 1U) << FMC_SDTRx_TWR_Pos) | + (((Timing->RCDDelay) - 1U) << FMC_SDTRx_TRCD_Pos))); + } + + return HAL_OK; +} + +/** + * @brief DeInitializes the FMC_SDRAM peripheral + * @param Device Pointer to SDRAM device instance + * @retval HAL status + */ +HAL_StatusTypeDef FMC_SDRAM_DeInit(FMC_SDRAM_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_SDRAM_BANK(Bank)); + + /* De-initialize the SDRAM device */ + Device->SDCR[Bank] = 0x000002D0U; + Device->SDTR[Bank] = 0x0FFFFFFFU; + Device->SDCMR = 0x00000000U; + Device->SDRTR = 0x00000000U; + Device->SDSR = 0x00000000U; + + return HAL_OK; +} + +/** + * @} + */ + +/** @addtogroup FMC_LL_SDRAMPrivate_Functions_Group2 + * @brief management functions + * +@verbatim + ============================================================================== + ##### FMC_SDRAM Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control dynamically + the FMC SDRAM interface. + +@endverbatim + * @{ + */ + +/** + * @brief Enables dynamically FMC_SDRAM write protection. + * @param Device Pointer to SDRAM device instance + * @param Bank SDRAM bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_SDRAM_WriteProtection_Enable(FMC_SDRAM_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_SDRAM_BANK(Bank)); + + /* Enable write protection */ + SET_BIT(Device->SDCR[Bank], FMC_SDRAM_WRITE_PROTECTION_ENABLE); + + return HAL_OK; +} + +/** + * @brief Disables dynamically FMC_SDRAM write protection. + * @param hsdram FMC_SDRAM handle + * @retval HAL status + */ +HAL_StatusTypeDef FMC_SDRAM_WriteProtection_Disable(FMC_SDRAM_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_SDRAM_BANK(Bank)); + + /* Disable write protection */ + CLEAR_BIT(Device->SDCR[Bank], FMC_SDRAM_WRITE_PROTECTION_ENABLE); + + return HAL_OK; +} + +/** + * @brief Send Command to the FMC SDRAM bank + * @param Device Pointer to SDRAM device instance + * @param Command Pointer to SDRAM command structure + * @param Timing Pointer to SDRAM Timing structure + * @param Timeout Timeout wait value + * @retval HAL state + */ +HAL_StatusTypeDef FMC_SDRAM_SendCommand(FMC_SDRAM_TypeDef *Device, + FMC_SDRAM_CommandTypeDef *Command, uint32_t Timeout) +{ + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_COMMAND_MODE(Command->CommandMode)); + assert_param(IS_FMC_COMMAND_TARGET(Command->CommandTarget)); + assert_param(IS_FMC_AUTOREFRESH_NUMBER(Command->AutoRefreshNumber)); + assert_param(IS_FMC_MODE_REGISTER(Command->ModeRegisterDefinition)); + + /* Set command register */ + MODIFY_REG(Device->SDCMR, (FMC_SDCMR_MODE | FMC_SDCMR_CTB2 | FMC_SDCMR_CTB1 | FMC_SDCMR_NRFS | FMC_SDCMR_MRD), + ((Command->CommandMode) | (Command->CommandTarget) | + (((Command->AutoRefreshNumber) - 1U) << FMC_SDCMR_NRFS_Pos) | + ((Command->ModeRegisterDefinition) << FMC_SDCMR_MRD_Pos))); + /* Prevent unused argument(s) compilation warning */ + UNUSED(Timeout); + return HAL_OK; +} + +/** + * @brief Program the SDRAM Memory Refresh rate. + * @param Device Pointer to SDRAM device instance + * @param RefreshRate The SDRAM refresh rate value. + * @retval HAL state + */ +HAL_StatusTypeDef FMC_SDRAM_ProgramRefreshRate(FMC_SDRAM_TypeDef *Device, uint32_t RefreshRate) +{ + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_REFRESH_RATE(RefreshRate)); + + /* Set the refresh rate in command register */ + MODIFY_REG(Device->SDRTR, FMC_SDRTR_COUNT, (RefreshRate << FMC_SDRTR_COUNT_Pos)); + + return HAL_OK; +} + +/** + * @brief Set the Number of consecutive SDRAM Memory auto Refresh commands. + * @param Device Pointer to SDRAM device instance + * @param AutoRefreshNumber Specifies the auto Refresh number. + * @retval None + */ +HAL_StatusTypeDef FMC_SDRAM_SetAutoRefreshNumber(FMC_SDRAM_TypeDef *Device, + uint32_t AutoRefreshNumber) +{ + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_AUTOREFRESH_NUMBER(AutoRefreshNumber)); + + /* Set the Auto-refresh number in command register */ + MODIFY_REG(Device->SDCMR, FMC_SDCMR_NRFS, ((AutoRefreshNumber - 1U) << FMC_SDCMR_NRFS_Pos)); + + return HAL_OK; +} + +/** + * @brief Returns the indicated FMC SDRAM bank mode status. + * @param Device Pointer to SDRAM device instance + * @param Bank Defines the FMC SDRAM bank. This parameter can be + * FMC_Bank1_SDRAM or FMC_Bank2_SDRAM. + * @retval The FMC SDRAM bank mode status, could be on of the following values: + * FMC_SDRAM_NORMAL_MODE, FMC_SDRAM_SELF_REFRESH_MODE or + * FMC_SDRAM_POWER_DOWN_MODE. + */ +uint32_t FMC_SDRAM_GetModeStatus(const FMC_SDRAM_TypeDef *Device, uint32_t Bank) +{ + uint32_t tmpreg; + + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_SDRAM_BANK(Bank)); + + /* Get the corresponding bank mode */ + if (Bank == FMC_SDRAM_BANK1) + { + tmpreg = (uint32_t)(Device->SDSR & FMC_SDSR_MODES1); + } + else + { + tmpreg = ((uint32_t)(Device->SDSR & FMC_SDSR_MODES2) >> 2U); + } + + /* Return the mode status */ + return tmpreg; +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* FMC_Bank5_6_R */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_NOR_MODULE_ENABLED */ +/** + * @} + */ +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_gpio.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_gpio.c new file mode 100644 index 0000000000..340ed846b4 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_gpio.c @@ -0,0 +1,288 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_gpio.c + * @author MCD Application Team + * @brief GPIO LL module driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +#if defined(USE_FULL_LL_DRIVER) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_gpio.h" +#include "stm32h5xx_ll_bus.h" +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (GPIOA) || defined (GPIOB) || defined (GPIOC) || defined (GPIOD) || defined (GPIOE) || defined (GPIOF) || \ + defined (GPIOG) || defined (GPIOH) || defined (GPIOI) + +/** @addtogroup GPIO_LL + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup GPIO_LL_Private_Macros + * @{ + */ +#define IS_LL_GPIO_PIN(__VALUE__) (((0x00000000U) < (__VALUE__)) && ((__VALUE__) <= (LL_GPIO_PIN_ALL))) + +#define IS_LL_GPIO_MODE(__VALUE__) (((__VALUE__) == LL_GPIO_MODE_INPUT) ||\ + ((__VALUE__) == LL_GPIO_MODE_OUTPUT) ||\ + ((__VALUE__) == LL_GPIO_MODE_ALTERNATE) ||\ + ((__VALUE__) == LL_GPIO_MODE_ANALOG)) + +#define IS_LL_GPIO_OUTPUT_TYPE(__VALUE__) (((__VALUE__) == LL_GPIO_OUTPUT_PUSHPULL) ||\ + ((__VALUE__) == LL_GPIO_OUTPUT_OPENDRAIN)) + +#define IS_LL_GPIO_SPEED(__VALUE__) (((__VALUE__) == LL_GPIO_SPEED_FREQ_LOW) ||\ + ((__VALUE__) == LL_GPIO_SPEED_FREQ_MEDIUM) ||\ + ((__VALUE__) == LL_GPIO_SPEED_FREQ_HIGH) ||\ + ((__VALUE__) == LL_GPIO_SPEED_FREQ_VERY_HIGH)) + +#define IS_LL_GPIO_PULL(__VALUE__) (((__VALUE__) == LL_GPIO_PULL_NO) ||\ + ((__VALUE__) == LL_GPIO_PULL_UP) ||\ + ((__VALUE__) == LL_GPIO_PULL_DOWN)) + +#define IS_LL_GPIO_ALTERNATE(__VALUE__) (((__VALUE__) == LL_GPIO_AF_0 ) ||\ + ((__VALUE__) == LL_GPIO_AF_1 ) ||\ + ((__VALUE__) == LL_GPIO_AF_2 ) ||\ + ((__VALUE__) == LL_GPIO_AF_3 ) ||\ + ((__VALUE__) == LL_GPIO_AF_4 ) ||\ + ((__VALUE__) == LL_GPIO_AF_5 ) ||\ + ((__VALUE__) == LL_GPIO_AF_6 ) ||\ + ((__VALUE__) == LL_GPIO_AF_7 ) ||\ + ((__VALUE__) == LL_GPIO_AF_8 ) ||\ + ((__VALUE__) == LL_GPIO_AF_9 ) ||\ + ((__VALUE__) == LL_GPIO_AF_10 ) ||\ + ((__VALUE__) == LL_GPIO_AF_11 ) ||\ + ((__VALUE__) == LL_GPIO_AF_12 ) ||\ + ((__VALUE__) == LL_GPIO_AF_13 ) ||\ + ((__VALUE__) == LL_GPIO_AF_14 ) ||\ + ((__VALUE__) == LL_GPIO_AF_15 )) +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup GPIO_LL_Exported_Functions + * @{ + */ + +/** @addtogroup GPIO_LL_EF_Init + * @{ + */ + +/** + * @brief De-initialize GPIO registers (Registers restored to their default values). + * @param GPIOx GPIO Port + * @retval An ErrorStatus enumeration value: + * - SUCCESS: GPIO registers are de-initialized + * - ERROR: Wrong GPIO Port + */ +ErrorStatus LL_GPIO_DeInit(const GPIO_TypeDef *GPIOx) +{ + ErrorStatus status = SUCCESS; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_INSTANCE(GPIOx)); + + /* Force and Release reset on clock of GPIOx Port */ + if (GPIOx == GPIOA) + { + LL_AHB2_GRP1_ForceReset(LL_AHB2_GRP1_PERIPH_GPIOA); + LL_AHB2_GRP1_ReleaseReset(LL_AHB2_GRP1_PERIPH_GPIOA); + } + else if (GPIOx == GPIOB) + { + LL_AHB2_GRP1_ForceReset(LL_AHB2_GRP1_PERIPH_GPIOB); + LL_AHB2_GRP1_ReleaseReset(LL_AHB2_GRP1_PERIPH_GPIOB); + } + else if (GPIOx == GPIOC) + { + LL_AHB2_GRP1_ForceReset(LL_AHB2_GRP1_PERIPH_GPIOC); + LL_AHB2_GRP1_ReleaseReset(LL_AHB2_GRP1_PERIPH_GPIOC); + } +#if defined(GPIOD) + else if (GPIOx == GPIOD) + { + LL_AHB2_GRP1_ForceReset(LL_AHB2_GRP1_PERIPH_GPIOD); + LL_AHB2_GRP1_ReleaseReset(LL_AHB2_GRP1_PERIPH_GPIOD); + } +#endif /* GPIOD */ +#if defined(GPIOE) + else if (GPIOx == GPIOE) + { + LL_AHB2_GRP1_ForceReset(LL_AHB2_GRP1_PERIPH_GPIOE); + LL_AHB2_GRP1_ReleaseReset(LL_AHB2_GRP1_PERIPH_GPIOE); + } +#endif /* GPIOE */ +#if defined(GPIOF) + else if (GPIOx == GPIOF) + { + LL_AHB2_GRP1_ForceReset(LL_AHB2_GRP1_PERIPH_GPIOF); + LL_AHB2_GRP1_ReleaseReset(LL_AHB2_GRP1_PERIPH_GPIOF); + } +#endif /* GPIOF */ +#if defined(GPIOG) + else if (GPIOx == GPIOG) + { + LL_AHB2_GRP1_ForceReset(LL_AHB2_GRP1_PERIPH_GPIOG); + LL_AHB2_GRP1_ReleaseReset(LL_AHB2_GRP1_PERIPH_GPIOG); + } +#endif /* GPIOG */ +#if defined(GPIOH) + else if (GPIOx == GPIOH) + { + LL_AHB2_GRP1_ForceReset(LL_AHB2_GRP1_PERIPH_GPIOH); + LL_AHB2_GRP1_ReleaseReset(LL_AHB2_GRP1_PERIPH_GPIOH); + } +#endif /* GPIOH */ +#if defined(GPIOI) + else if (GPIOx == GPIOI) + { + LL_AHB2_GRP1_ForceReset(LL_AHB2_GRP1_PERIPH_GPIOI); + LL_AHB2_GRP1_ReleaseReset(LL_AHB2_GRP1_PERIPH_GPIOI); + } +#endif /* GPIOI */ + else + { + status = ERROR; + } + + return (status); +} + +/** + * @brief Initialize GPIO registers according to the specified parameters in GPIO_InitStruct. + * @param GPIOx GPIO Port + * @param GPIO_InitStruct: pointer to a @ref LL_GPIO_InitTypeDef structure + * that contains the configuration information for the specified GPIO peripheral. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: GPIO registers are initialized according to GPIO_InitStruct content + * - ERROR: Not applicable + */ +ErrorStatus LL_GPIO_Init(GPIO_TypeDef *GPIOx, LL_GPIO_InitTypeDef *GPIO_InitStruct) +{ + uint32_t pinpos; + uint32_t currentpin; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_INSTANCE(GPIOx)); + assert_param(IS_LL_GPIO_PIN(GPIO_InitStruct->Pin)); + assert_param(IS_LL_GPIO_MODE(GPIO_InitStruct->Mode)); + assert_param(IS_LL_GPIO_PULL(GPIO_InitStruct->Pull)); + + /* ------------------------- Configure the port pins ---------------- */ + /* Initialize pinpos on first pin set */ + pinpos = POSITION_VAL(GPIO_InitStruct->Pin); + + /* Configure the port pins */ + while (((GPIO_InitStruct->Pin) >> pinpos) != 0U) + { + /* Get current io position */ + currentpin = (GPIO_InitStruct->Pin) & (1UL << pinpos); + + if (currentpin != 0U) + { + if ((GPIO_InitStruct->Mode == LL_GPIO_MODE_OUTPUT) || (GPIO_InitStruct->Mode == LL_GPIO_MODE_ALTERNATE)) + { + /* Check Speed mode parameters */ + assert_param(IS_LL_GPIO_SPEED(GPIO_InitStruct->Speed)); + + /* Speed mode configuration */ + LL_GPIO_SetPinSpeed(GPIOx, currentpin, GPIO_InitStruct->Speed); + + /* Check Output mode parameters */ + assert_param(IS_LL_GPIO_OUTPUT_TYPE(GPIO_InitStruct->OutputType)); + + /* Output mode configuration*/ + LL_GPIO_SetPinOutputType(GPIOx, GPIO_InitStruct->Pin, GPIO_InitStruct->OutputType); + } + + /* Pull-up Pull down resistor configuration*/ + LL_GPIO_SetPinPull(GPIOx, currentpin, GPIO_InitStruct->Pull); + + if (GPIO_InitStruct->Mode == LL_GPIO_MODE_ALTERNATE) + { + /* Check Alternate parameter */ + assert_param(IS_LL_GPIO_ALTERNATE(GPIO_InitStruct->Alternate)); + + /* Speed mode configuration */ + if (POSITION_VAL(currentpin) < 8U) + { + LL_GPIO_SetAFPin_0_7(GPIOx, currentpin, GPIO_InitStruct->Alternate); + } + else + { + LL_GPIO_SetAFPin_8_15(GPIOx, currentpin, GPIO_InitStruct->Alternate); + } + } + /* Pin Mode configuration */ + LL_GPIO_SetPinMode(GPIOx, currentpin, GPIO_InitStruct->Mode); + } + pinpos++; + } + + return (SUCCESS); +} + +/** + * @brief Set each @ref LL_GPIO_InitTypeDef field to default value. + * @param GPIO_InitStruct: pointer to a @ref LL_GPIO_InitTypeDef structure + * whose fields will be set to default values. + * @retval None + */ + +void LL_GPIO_StructInit(LL_GPIO_InitTypeDef *GPIO_InitStruct) +{ + /* Reset GPIO init structure parameters values */ + GPIO_InitStruct->Pin = LL_GPIO_PIN_ALL; + GPIO_InitStruct->Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct->Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct->OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct->Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct->Alternate = LL_GPIO_AF_0; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined (GPIOA) || defined (GPIOB) || defined (GPIOC) || defined (GPIOD) || defined (GPIOE) || \ + defined (GPIOF) || defined (GPIOG) || defined (GPIOH) || defined (GPIOI) */ + +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_i2c.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_i2c.c new file mode 100644 index 0000000000..c12d3c37a5 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_i2c.c @@ -0,0 +1,244 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_i2c.c + * @author MCD Application Team + * @brief I2C LL module driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +#if defined(USE_FULL_LL_DRIVER) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_i2c.h" +#include "stm32h5xx_ll_bus.h" +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (I2C1) || defined (I2C2) || defined (I2C3) || defined (I2C4) + +/** @defgroup I2C_LL I2C + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup I2C_LL_Private_Macros + * @{ + */ + +#define IS_LL_I2C_PERIPHERAL_MODE(__VALUE__) (((__VALUE__) == LL_I2C_MODE_I2C) || \ + ((__VALUE__) == LL_I2C_MODE_SMBUS_HOST) || \ + ((__VALUE__) == LL_I2C_MODE_SMBUS_DEVICE) || \ + ((__VALUE__) == LL_I2C_MODE_SMBUS_DEVICE_ARP)) + +#define IS_LL_I2C_ANALOG_FILTER(__VALUE__) (((__VALUE__) == LL_I2C_ANALOGFILTER_ENABLE) || \ + ((__VALUE__) == LL_I2C_ANALOGFILTER_DISABLE)) + +#define IS_LL_I2C_DIGITAL_FILTER(__VALUE__) ((__VALUE__) <= 0x0000000FU) + +#define IS_LL_I2C_OWN_ADDRESS1(__VALUE__) ((__VALUE__) <= 0x000003FFU) + +#define IS_LL_I2C_TYPE_ACKNOWLEDGE(__VALUE__) (((__VALUE__) == LL_I2C_ACK) || \ + ((__VALUE__) == LL_I2C_NACK)) + +#define IS_LL_I2C_OWN_ADDRSIZE(__VALUE__) (((__VALUE__) == LL_I2C_OWNADDRESS1_7BIT) || \ + ((__VALUE__) == LL_I2C_OWNADDRESS1_10BIT)) +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup I2C_LL_Exported_Functions + * @{ + */ + +/** @addtogroup I2C_LL_EF_Init + * @{ + */ + +/** + * @brief De-initialize the I2C registers to their default reset values. + * @param I2Cx I2C Instance. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: I2C registers are de-initialized + * - ERROR: I2C registers are not de-initialized + */ +ErrorStatus LL_I2C_DeInit(const I2C_TypeDef *I2Cx) +{ + ErrorStatus status = SUCCESS; + + /* Check the I2C Instance I2Cx */ + assert_param(IS_I2C_ALL_INSTANCE(I2Cx)); + + if (I2Cx == I2C1) + { + /* Force reset of I2C clock */ + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1); + + /* Release reset of I2C clock */ + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C1); + } + else if (I2Cx == I2C2) + { + /* Force reset of I2C clock */ + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C2); + + /* Release reset of I2C clock */ + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C2); + + } +#if defined(I2C3) + else if (I2Cx == I2C3) + { + /* Force reset of I2C clock */ + LL_APB3_GRP1_ForceReset(LL_APB3_GRP1_PERIPH_I2C3); + + /* Release reset of I2C clock */ + LL_APB3_GRP1_ReleaseReset(LL_APB3_GRP1_PERIPH_I2C3); + } +#endif /* I2C3 */ +#if defined(I2C4) + else if (I2Cx == I2C4) + { + /* Force reset of I2C clock */ + LL_APB3_GRP1_ForceReset(LL_APB3_GRP1_PERIPH_I2C4); + + /* Release reset of I2C clock */ + LL_APB3_GRP1_ReleaseReset(LL_APB3_GRP1_PERIPH_I2C4); + } +#endif /* I2C4 */ + else + { + status = ERROR; + } + + return status; +} + +/** + * @brief Initialize the I2C registers according to the specified parameters in I2C_InitStruct. + * @param I2Cx I2C Instance. + * @param I2C_InitStruct pointer to a @ref LL_I2C_InitTypeDef structure. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: I2C registers are initialized + * - ERROR: Not applicable + */ +ErrorStatus LL_I2C_Init(I2C_TypeDef *I2Cx, const LL_I2C_InitTypeDef *I2C_InitStruct) +{ + /* Check the I2C Instance I2Cx */ + assert_param(IS_I2C_ALL_INSTANCE(I2Cx)); + + /* Check the I2C parameters from I2C_InitStruct */ + assert_param(IS_LL_I2C_PERIPHERAL_MODE(I2C_InitStruct->PeripheralMode)); + assert_param(IS_LL_I2C_ANALOG_FILTER(I2C_InitStruct->AnalogFilter)); + assert_param(IS_LL_I2C_DIGITAL_FILTER(I2C_InitStruct->DigitalFilter)); + assert_param(IS_LL_I2C_OWN_ADDRESS1(I2C_InitStruct->OwnAddress1)); + assert_param(IS_LL_I2C_TYPE_ACKNOWLEDGE(I2C_InitStruct->TypeAcknowledge)); + assert_param(IS_LL_I2C_OWN_ADDRSIZE(I2C_InitStruct->OwnAddrSize)); + + /* Disable the selected I2Cx Peripheral */ + LL_I2C_Disable(I2Cx); + + /*---------------------------- I2Cx CR1 Configuration ------------------------ + * Configure the analog and digital noise filters with parameters : + * - AnalogFilter: I2C_CR1_ANFOFF bit + * - DigitalFilter: I2C_CR1_DNF[3:0] bits + */ + LL_I2C_ConfigFilters(I2Cx, I2C_InitStruct->AnalogFilter, I2C_InitStruct->DigitalFilter); + + /*---------------------------- I2Cx TIMINGR Configuration -------------------- + * Configure the SDA setup, hold time and the SCL high, low period with parameter : + * - Timing: I2C_TIMINGR_PRESC[3:0], I2C_TIMINGR_SCLDEL[3:0], I2C_TIMINGR_SDADEL[3:0], + * I2C_TIMINGR_SCLH[7:0] and I2C_TIMINGR_SCLL[7:0] bits + */ + LL_I2C_SetTiming(I2Cx, I2C_InitStruct->Timing); + + /* Enable the selected I2Cx Peripheral */ + LL_I2C_Enable(I2Cx); + + /*---------------------------- I2Cx OAR1 Configuration ----------------------- + * Disable, Configure and Enable I2Cx device own address 1 with parameters : + * - OwnAddress1: I2C_OAR1_OA1[9:0] bits + * - OwnAddrSize: I2C_OAR1_OA1MODE bit + */ + LL_I2C_DisableOwnAddress1(I2Cx); + LL_I2C_SetOwnAddress1(I2Cx, I2C_InitStruct->OwnAddress1, I2C_InitStruct->OwnAddrSize); + + /* OwnAdress1 == 0 is reserved for General Call address */ + if (I2C_InitStruct->OwnAddress1 != 0U) + { + LL_I2C_EnableOwnAddress1(I2Cx); + } + + /*---------------------------- I2Cx MODE Configuration ----------------------- + * Configure I2Cx peripheral mode with parameter : + * - PeripheralMode: I2C_CR1_SMBDEN and I2C_CR1_SMBHEN bits + */ + LL_I2C_SetMode(I2Cx, I2C_InitStruct->PeripheralMode); + + /*---------------------------- I2Cx CR2 Configuration ------------------------ + * Configure the ACKnowledge or Non ACKnowledge condition + * after the address receive match code or next received byte with parameter : + * - TypeAcknowledge: I2C_CR2_NACK bit + */ + LL_I2C_AcknowledgeNextData(I2Cx, I2C_InitStruct->TypeAcknowledge); + + return SUCCESS; +} + +/** + * @brief Set each @ref LL_I2C_InitTypeDef field to default value. + * @param I2C_InitStruct Pointer to a @ref LL_I2C_InitTypeDef structure. + * @retval None + */ +void LL_I2C_StructInit(LL_I2C_InitTypeDef *I2C_InitStruct) +{ + /* Set I2C_InitStruct fields to default values */ + I2C_InitStruct->PeripheralMode = LL_I2C_MODE_I2C; + I2C_InitStruct->Timing = 0U; + I2C_InitStruct->AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE; + I2C_InitStruct->DigitalFilter = 0U; + I2C_InitStruct->OwnAddress1 = 0U; + I2C_InitStruct->TypeAcknowledge = LL_I2C_NACK; + I2C_InitStruct->OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* I2C1 || I2C2 || I2C3 || I2C4 */ + +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_i3c.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_i3c.c new file mode 100644 index 0000000000..cabc24279f --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_i3c.c @@ -0,0 +1,212 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_i3c.c + * @author MCD Application Team + * @brief I3C LL module driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +#if defined(USE_FULL_LL_DRIVER) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_i3c.h" +#include "stm32h5xx_ll_bus.h" +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (I3C1) + +/** @defgroup I3C_LL I3C + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup I3C_LL_Private_Macros + * @{ + */ +#define IS_LL_I3C_SDAHOLDTIME_VALUE(VALUE) (((VALUE) == LL_I3C_SDA_HOLD_TIME_0_5) || \ + ((VALUE) == LL_I3C_SDA_HOLD_TIME_1_5)) + +#define IS_LL_I3C_WAITTIME_VALUE(VALUE) (((VALUE) == LL_I3C_OWN_ACTIVITY_STATE_0) || \ + ((VALUE) == LL_I3C_OWN_ACTIVITY_STATE_1) || \ + ((VALUE) == LL_I3C_OWN_ACTIVITY_STATE_2) || \ + ((VALUE) == LL_I3C_OWN_ACTIVITY_STATE_3)) +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup I3C_LL_Exported_Functions + * @{ + */ + +/** @addtogroup I3C_LL_EF_Init + * @{ + */ + +/** + * @brief De-initialize the I3C registers to their default reset values. + * @param I3Cx I3C Instance. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: I3C registers are de-initialized + * - ERROR: I3C registers are not de-initialized + */ +ErrorStatus LL_I3C_DeInit(const I3C_TypeDef *I3Cx) +{ + ErrorStatus status = SUCCESS; + + /* Check the I3C Instance I3Cx */ + assert_param(IS_I3C_ALL_INSTANCE(I3Cx)); + + if (I3Cx == I3C1) + { + /* Force reset of I3C clock */ + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I3C1); + + /* Release reset of I3C clock */ + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I3C1); + } +#if defined(I3C2) + else if (I3Cx == I3C2) + { + /* Force reset of I3C clock */ + LL_APB3_GRP1_ForceReset(LL_APB3_GRP1_PERIPH_I3C2); + + /* Release reset of I3C clock */ + LL_APB3_GRP1_ReleaseReset(LL_APB3_GRP1_PERIPH_I3C2); + + } +#endif /* I3C2 */ + else + { + status = ERROR; + } + + return status; +} + +/** + * @brief Initialize the I3C registers according to the specified parameters in I3C_InitStruct. + * @param I3Cx I3C Instance. + * @param I3C_InitStruct pointer to a @ref LL_I3C_InitTypeDef structure. + * @param Mode I3C peripheral mode. + * This parameter can be a value of @ref I3C_LL_EC_MODE. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: I3C registers are initialized + * - ERROR: Not applicable + */ +ErrorStatus LL_I3C_Init(I3C_TypeDef *I3Cx, LL_I3C_InitTypeDef *I3C_InitStruct, uint32_t Mode) +{ + uint32_t waveform_value; + uint32_t timing_value; + + /* Check the I3C Instance I3Cx */ + assert_param(IS_I3C_ALL_INSTANCE(I3Cx)); + + /* Disable the selected I3C peripheral */ + LL_I3C_Disable(I3Cx); + + /* Check on the I3C mode: initialization depends on the mode */ + if (Mode == LL_I3C_MODE_CONTROLLER) + { + /* Check the parameters */ + assert_param(IS_LL_I3C_SDAHOLDTIME_VALUE(I3C_InitStruct->CtrlBusCharacteristic.SDAHoldTime)); + assert_param(IS_LL_I3C_WAITTIME_VALUE(I3C_InitStruct->CtrlBusCharacteristic.WaitTime)); + + /* Set Controller mode */ + LL_I3C_SetMode(I3Cx, LL_I3C_MODE_CONTROLLER); + + /*------------------ SCL signal waveform configuration : I3C timing register 0 (I3C_TIMINGR0) ------------------- */ + /* Set the controller SCL waveform */ + waveform_value = + ((uint32_t)(I3C_InitStruct->CtrlBusCharacteristic.SCLPPLowDuration) | + ((uint32_t)I3C_InitStruct->CtrlBusCharacteristic.SCLI3CHighDuration << I3C_TIMINGR0_SCLH_I3C_Pos) | + ((uint32_t)I3C_InitStruct->CtrlBusCharacteristic.SCLODLowDuration << I3C_TIMINGR0_SCLL_OD_Pos) | + ((uint32_t)I3C_InitStruct->CtrlBusCharacteristic.SCLI2CHighDuration << I3C_TIMINGR0_SCLH_I2C_Pos)); + + LL_I3C_ConfigClockWaveForm(I3Cx, waveform_value); + + /*------------------- Timing configuration : I3C timing register 1 (I3C_TIMINGR1) ------------------------------- */ + /* Set SDA hold time, activity state, bus free duration and bus available duration */ + timing_value = ((uint32_t)(I3C_InitStruct->CtrlBusCharacteristic.SDAHoldTime) | + (uint32_t)(I3C_InitStruct->CtrlBusCharacteristic.WaitTime) | + ((uint32_t)I3C_InitStruct->CtrlBusCharacteristic.BusFreeDuration << I3C_TIMINGR1_FREE_Pos) | + (uint32_t)(I3C_InitStruct->CtrlBusCharacteristic.BusIdleDuration)); + + LL_I3C_SetCtrlBusCharacteristic(I3Cx, timing_value); + } + else + { + /* Set target mode */ + LL_I3C_SetMode(I3Cx, LL_I3C_MODE_TARGET); + + /*------------------- Timing configuration : I3C timing register 1 (I3C_TIMINGR1) ------------------------------- */ + /* Set the number of kernel clocks cycles for the bus available condition time */ + LL_I3C_SetTgtBusCharacteristic(I3Cx, I3C_InitStruct->TgtBusCharacteristic.BusAvailableDuration); + } + + /* Enable the selected I3C peripheral */ + LL_I3C_Enable(I3Cx); + + return SUCCESS; +} + +/** + * @brief Set each @ref LL_I3C_InitTypeDef field to default value. + * @param I3C_InitStruct Pointer to a @ref LL_I3C_InitTypeDef structure. + * @retval None + */ +void LL_I3C_StructInit(LL_I3C_InitTypeDef *I3C_InitStruct) +{ + /* Set I3C_InitStruct fields to default values */ + I3C_InitStruct->CtrlBusCharacteristic.SDAHoldTime = LL_I3C_SDA_HOLD_TIME_0_5; + I3C_InitStruct->CtrlBusCharacteristic.WaitTime = LL_I3C_OWN_ACTIVITY_STATE_0; + I3C_InitStruct->CtrlBusCharacteristic.SCLPPLowDuration = 0U; + I3C_InitStruct->CtrlBusCharacteristic.SCLI3CHighDuration = 0U; + I3C_InitStruct->CtrlBusCharacteristic.SCLODLowDuration = 0U; + I3C_InitStruct->CtrlBusCharacteristic.SCLI2CHighDuration = 0U; + I3C_InitStruct->CtrlBusCharacteristic.BusFreeDuration = 0U; + I3C_InitStruct->CtrlBusCharacteristic.BusIdleDuration = 0U; + I3C_InitStruct->TgtBusCharacteristic.BusAvailableDuration = 0U; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* I3C1 */ + +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_icache.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_icache.c new file mode 100644 index 0000000000..3c38ba78df --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_icache.c @@ -0,0 +1,143 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_icache.c + * @author MCD Application Team + * @brief ICACHE LL module driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +#if defined(USE_FULL_LL_DRIVER) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_icache.h" +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined(ICACHE) + +/** @defgroup ICACHE_LL ICACHE + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup ICACHE_LL_Private_Macros ICACHE Private Macros + * @{ + */ +#if defined(ICACHE_CRRx_REN) + +#define IS_LL_ICACHE_REGION(__VALUE__) (((__VALUE__) == LL_ICACHE_REGION_0) || \ + ((__VALUE__) == LL_ICACHE_REGION_1) || \ + ((__VALUE__) == LL_ICACHE_REGION_2) || \ + ((__VALUE__) == LL_ICACHE_REGION_3)) + +#define IS_LL_ICACHE_REGION_SIZE(__VALUE__) (((__VALUE__) == LL_ICACHE_REGIONSIZE_2MB) || \ + ((__VALUE__) == LL_ICACHE_REGIONSIZE_4MB) || \ + ((__VALUE__) == LL_ICACHE_REGIONSIZE_8MB) || \ + ((__VALUE__) == LL_ICACHE_REGIONSIZE_16MB) || \ + ((__VALUE__) == LL_ICACHE_REGIONSIZE_32MB) || \ + ((__VALUE__) == LL_ICACHE_REGIONSIZE_64MB) || \ + ((__VALUE__) == LL_ICACHE_REGIONSIZE_128MB)) + +#define IS_LL_ICACHE_MASTER_PORT(__VALUE__) (((__VALUE__) == LL_ICACHE_MASTER1_PORT) || \ + ((__VALUE__) == LL_ICACHE_MASTER2_PORT)) + +#define IS_LL_ICACHE_OUTPUT_BURST(__VALUE__) (((__VALUE__) == LL_ICACHE_OUTPUT_BURST_WRAP) || \ + ((__VALUE__) == LL_ICACHE_OUTPUT_BURST_INCR)) + +#endif /* ICACHE_CRRx_REN */ +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup ICACHE_LL_Exported_Functions + * @{ + */ + +#if defined(ICACHE_CRRx_REN) +/** @addtogroup ICACHE_LL_EF_REGION_Init + * @{ + */ + +/** + * @brief Configure and enable the memory remapped region. + * @note The Instruction Cache and corresponding region must be disabled. + * @param Region This parameter can be one of the following values: + * @arg @ref LL_ICACHE_REGION_0 + * @arg @ref LL_ICACHE_REGION_1 + * @arg @ref LL_ICACHE_REGION_2 + * @arg @ref LL_ICACHE_REGION_3 + * @param pICACHE_RegionStruct pointer to a @ref LL_ICACHE_RegionTypeDef structure. + * @retval None + */ +void LL_ICACHE_ConfigRegion(uint32_t Region, const LL_ICACHE_RegionTypeDef *const pICACHE_RegionStruct) +{ + __IO uint32_t *p_reg; + uint32_t value; + + /* Check the parameters */ + assert_param(IS_LL_ICACHE_REGION(Region)); + assert_param(IS_LL_ICACHE_REGION_SIZE(pICACHE_RegionStruct->Size)); + assert_param(IS_LL_ICACHE_MASTER_PORT(pICACHE_RegionStruct->TrafficRoute)); + assert_param(IS_LL_ICACHE_OUTPUT_BURST(pICACHE_RegionStruct->OutputBurstType)); + + /* Get region control register address */ + p_reg = &(ICACHE->CRR0) + (1U * Region); + + /* Region 2MB: BaseAddress size 8 bits, RemapAddress size 11 bits */ + /* Region 4MB: BaseAddress size 7 bits, RemapAddress size 10 bits */ + /* Region 8MB: BaseAddress size 6 bits, RemapAddress size 9 bits */ + /* Region 16MB: BaseAddress size 5 bits, RemapAddress size 8 bits */ + /* Region 32MB: BaseAddress size 4 bits, RemapAddress size 7 bits */ + /* Region 64MB: BaseAddress size 3 bits, RemapAddress size 6 bits */ + /* Region 128MB: BaseAddress size 2 bits, RemapAddress size 5 bits */ + value = ((pICACHE_RegionStruct->BaseAddress & 0x1FFFFFFFU) >> 21U) & \ + (0xFFU & ~(pICACHE_RegionStruct->Size - 1U)); + value |= ((pICACHE_RegionStruct->RemapAddress >> 5U) & \ + ((uint32_t)(0x7FFU & ~(pICACHE_RegionStruct->Size - 1U)) << ICACHE_CRRx_REMAPADDR_Pos)); + value |= (pICACHE_RegionStruct->Size << ICACHE_CRRx_RSIZE_Pos) | pICACHE_RegionStruct->TrafficRoute | \ + pICACHE_RegionStruct->OutputBurstType; + *p_reg = (value | ICACHE_CRRx_REN); /* Configure and enable region */ +} + +/** + * @} + */ +#endif /* ICACHE_CRRx_REN */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* ICACHE */ + +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_lptim.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_lptim.c new file mode 100644 index 0000000000..b58fd17b2b --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_lptim.c @@ -0,0 +1,219 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_lptim.c + * @author MCD Application Team + * @brief LPTIM LL module driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +#if defined(USE_FULL_LL_DRIVER) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_lptim.h" +#include "stm32h5xx_ll_bus.h" +#include "stm32h5xx_ll_rcc.h" + + +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (LPTIM1) || defined (LPTIM2) || defined (LPTIM3) || defined (LPTIM4) || defined (LPTIM5) || defined (LPTIM6) + +/** @addtogroup LPTIM_LL + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup LPTIM_LL_Private_Macros + * @{ + */ +#define IS_LL_LPTIM_CLOCK_SOURCE(__VALUE__) (((__VALUE__) == LL_LPTIM_CLK_SOURCE_INTERNAL) \ + || ((__VALUE__) == LL_LPTIM_CLK_SOURCE_EXTERNAL)) + +#define IS_LL_LPTIM_CLOCK_PRESCALER(__VALUE__) (((__VALUE__) == LL_LPTIM_PRESCALER_DIV1) \ + || ((__VALUE__) == LL_LPTIM_PRESCALER_DIV2) \ + || ((__VALUE__) == LL_LPTIM_PRESCALER_DIV4) \ + || ((__VALUE__) == LL_LPTIM_PRESCALER_DIV8) \ + || ((__VALUE__) == LL_LPTIM_PRESCALER_DIV16) \ + || ((__VALUE__) == LL_LPTIM_PRESCALER_DIV32) \ + || ((__VALUE__) == LL_LPTIM_PRESCALER_DIV64) \ + || ((__VALUE__) == LL_LPTIM_PRESCALER_DIV128)) + +#define IS_LL_LPTIM_WAVEFORM(__VALUE__) (((__VALUE__) == LL_LPTIM_OUTPUT_WAVEFORM_PWM) \ + || ((__VALUE__) == LL_LPTIM_OUTPUT_WAVEFORM_SETONCE)) + +/** + * @} + */ + + +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/** @defgroup LPTIM_Private_Functions LPTIM Private Functions + * @{ + */ +/** + * @} + */ +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup LPTIM_LL_Exported_Functions + * @{ + */ + +/** @addtogroup LPTIM_LL_EF_Init + * @{ + */ + +/** + * @brief Set LPTIMx registers to their reset values. + * @param LPTIMx LP Timer instance + * @retval An ErrorStatus enumeration value: + * - SUCCESS: LPTIMx registers are de-initialized + * - ERROR: invalid LPTIMx instance + */ +ErrorStatus LL_LPTIM_DeInit(const LPTIM_TypeDef *LPTIMx) +{ + ErrorStatus result = SUCCESS; + + /* Check the parameters */ + assert_param(IS_LPTIM_INSTANCE(LPTIMx)); + + if (LPTIMx == LPTIM1) + { + LL_APB3_GRP1_ForceReset(LL_APB3_GRP1_PERIPH_LPTIM1); + LL_APB3_GRP1_ReleaseReset(LL_APB3_GRP1_PERIPH_LPTIM1); + } + else if (LPTIMx == LPTIM2) + { + LL_APB1_GRP2_ForceReset(LL_APB1_GRP2_PERIPH_LPTIM2); + LL_APB1_GRP2_ReleaseReset(LL_APB1_GRP2_PERIPH_LPTIM2); + } +#if defined(LPTIM3) + else if (LPTIMx == LPTIM3) + { + LL_APB3_GRP1_ForceReset(LL_APB3_GRP1_PERIPH_LPTIM3); + LL_APB3_GRP1_ReleaseReset(LL_APB3_GRP1_PERIPH_LPTIM3); + } +#endif /* LPTIM3 */ +#if defined(LPTIM4) + else if (LPTIMx == LPTIM4) + { + LL_APB3_GRP1_ForceReset(LL_APB3_GRP1_PERIPH_LPTIM4); + LL_APB3_GRP1_ReleaseReset(LL_APB3_GRP1_PERIPH_LPTIM4); + } +#endif /* LPTIM4 */ +#if defined(LPTIM5) + else if (LPTIMx == LPTIM5) + { + LL_APB3_GRP1_ForceReset(LL_APB3_GRP1_PERIPH_LPTIM5); + LL_APB3_GRP1_ReleaseReset(LL_APB3_GRP1_PERIPH_LPTIM5); + } +#endif /* LPTIM5 */ +#if defined(LPTIM6) + else if (LPTIMx == LPTIM6) + { + LL_APB3_GRP1_ForceReset(LL_APB3_GRP1_PERIPH_LPTIM6); + LL_APB3_GRP1_ReleaseReset(LL_APB3_GRP1_PERIPH_LPTIM6); + } +#endif /* LPTIM6 */ + else + { + result = ERROR; + } + + return result; +} + +/** + * @brief Set each fields of the LPTIM_InitStruct structure to its default + * value. + * @param LPTIM_InitStruct pointer to a @ref LL_LPTIM_InitTypeDef structure + * @retval None + */ +void LL_LPTIM_StructInit(LL_LPTIM_InitTypeDef *LPTIM_InitStruct) +{ + /* Set the default configuration */ + LPTIM_InitStruct->ClockSource = LL_LPTIM_CLK_SOURCE_INTERNAL; + LPTIM_InitStruct->Prescaler = LL_LPTIM_PRESCALER_DIV1; + LPTIM_InitStruct->Waveform = LL_LPTIM_OUTPUT_WAVEFORM_PWM; +} + +/** + * @brief Configure the LPTIMx peripheral according to the specified parameters. + * @note LL_LPTIM_Init can only be called when the LPTIM instance is disabled. + * @note LPTIMx can be disabled using unitary function @ref LL_LPTIM_Disable(). + * @param LPTIMx LP Timer Instance + * @param LPTIM_InitStruct pointer to a @ref LL_LPTIM_InitTypeDef structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: LPTIMx instance has been initialized + * - ERROR: LPTIMx instance hasn't been initialized + */ +ErrorStatus LL_LPTIM_Init(LPTIM_TypeDef *LPTIMx, const LL_LPTIM_InitTypeDef *LPTIM_InitStruct) +{ + ErrorStatus result = SUCCESS; + /* Check the parameters */ + assert_param(IS_LPTIM_INSTANCE(LPTIMx)); + assert_param(IS_LL_LPTIM_CLOCK_SOURCE(LPTIM_InitStruct->ClockSource)); + assert_param(IS_LL_LPTIM_CLOCK_PRESCALER(LPTIM_InitStruct->Prescaler)); + assert_param(IS_LL_LPTIM_WAVEFORM(LPTIM_InitStruct->Waveform)); + + /* The LPTIMx_CFGR register must only be modified when the LPTIM is disabled + (ENABLE bit is reset to 0). + */ + if (LL_LPTIM_IsEnabled(LPTIMx) == 1UL) + { + result = ERROR; + } + else + { + /* Set CKSEL bitfield according to ClockSource value */ + /* Set PRESC bitfield according to Prescaler value */ + /* Set WAVE bitfield according to Waveform value */ + MODIFY_REG(LPTIMx->CFGR, + (LPTIM_CFGR_CKSEL | LPTIM_CFGR_PRESC | LPTIM_CFGR_WAVE), + LPTIM_InitStruct->ClockSource | \ + LPTIM_InitStruct->Prescaler | \ + LPTIM_InitStruct->Waveform); + } + + return result; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* LPTIM1 || LPTIM2 || LPTIM3 || LPTIM4 || LPTIM5 || LPTIM6 */ + +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_lpuart.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_lpuart.c new file mode 100644 index 0000000000..0bb8a1cf7e --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_lpuart.c @@ -0,0 +1,285 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_lpuart.c + * @author MCD Application Team + * @brief LPUART LL module driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +#if defined(USE_FULL_LL_DRIVER) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_lpuart.h" +#include "stm32h5xx_ll_rcc.h" +#include "stm32h5xx_ll_bus.h" +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (LPUART1) + +/** @addtogroup LPUART_LL + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @addtogroup LPUART_LL_Private_Constants + * @{ + */ + +/* Definition of default baudrate value used for LPUART initialisation */ +#define LPUART_DEFAULT_BAUDRATE (9600U) + +/** + * @} + */ + + +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup LPUART_LL_Private_Macros + * @{ + */ + +/* Check of parameters for configuration of LPUART registers */ + +#define IS_LL_LPUART_PRESCALER(__VALUE__) (((__VALUE__) == LL_LPUART_PRESCALER_DIV1) \ + || ((__VALUE__) == LL_LPUART_PRESCALER_DIV2) \ + || ((__VALUE__) == LL_LPUART_PRESCALER_DIV4) \ + || ((__VALUE__) == LL_LPUART_PRESCALER_DIV6) \ + || ((__VALUE__) == LL_LPUART_PRESCALER_DIV8) \ + || ((__VALUE__) == LL_LPUART_PRESCALER_DIV10) \ + || ((__VALUE__) == LL_LPUART_PRESCALER_DIV12) \ + || ((__VALUE__) == LL_LPUART_PRESCALER_DIV16) \ + || ((__VALUE__) == LL_LPUART_PRESCALER_DIV32) \ + || ((__VALUE__) == LL_LPUART_PRESCALER_DIV64) \ + || ((__VALUE__) == LL_LPUART_PRESCALER_DIV128) \ + || ((__VALUE__) == LL_LPUART_PRESCALER_DIV256)) + +/* __BAUDRATE__ Depending on constraints applicable for LPUART BRR register */ +/* value : */ +/* - fck must be in the range [3 x baudrate, 4096 x baudrate] */ +/* - LPUART_BRR register value should be >= 0x300 */ +/* - LPUART_BRR register value should be <= 0xFFFFF (20 bits) */ +/* Baudrate specified by the user should belong to [8, 33000000].*/ +#define IS_LL_LPUART_BAUDRATE(__BAUDRATE__) (((__BAUDRATE__) <= 33000000U) && ((__BAUDRATE__) >= 8U)) + +/* __VALUE__ BRR content must be greater than or equal to 0x300. */ +#define IS_LL_LPUART_BRR_MIN(__VALUE__) ((__VALUE__) >= 0x300U) + +/* __VALUE__ BRR content must be lower than or equal to 0xFFFFF. */ +#define IS_LL_LPUART_BRR_MAX(__VALUE__) ((__VALUE__) <= 0x000FFFFFU) + +#define IS_LL_LPUART_DIRECTION(__VALUE__) (((__VALUE__) == LL_LPUART_DIRECTION_NONE) \ + || ((__VALUE__) == LL_LPUART_DIRECTION_RX) \ + || ((__VALUE__) == LL_LPUART_DIRECTION_TX) \ + || ((__VALUE__) == LL_LPUART_DIRECTION_TX_RX)) + +#define IS_LL_LPUART_PARITY(__VALUE__) (((__VALUE__) == LL_LPUART_PARITY_NONE) \ + || ((__VALUE__) == LL_LPUART_PARITY_EVEN) \ + || ((__VALUE__) == LL_LPUART_PARITY_ODD)) + +#define IS_LL_LPUART_DATAWIDTH(__VALUE__) (((__VALUE__) == LL_LPUART_DATAWIDTH_7B) \ + || ((__VALUE__) == LL_LPUART_DATAWIDTH_8B) \ + || ((__VALUE__) == LL_LPUART_DATAWIDTH_9B)) + +#define IS_LL_LPUART_STOPBITS(__VALUE__) (((__VALUE__) == LL_LPUART_STOPBITS_1) \ + || ((__VALUE__) == LL_LPUART_STOPBITS_2)) + +#define IS_LL_LPUART_HWCONTROL(__VALUE__) (((__VALUE__) == LL_LPUART_HWCONTROL_NONE) \ + || ((__VALUE__) == LL_LPUART_HWCONTROL_RTS) \ + || ((__VALUE__) == LL_LPUART_HWCONTROL_CTS) \ + || ((__VALUE__) == LL_LPUART_HWCONTROL_RTS_CTS)) + +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup LPUART_LL_Exported_Functions + * @{ + */ + +/** @addtogroup LPUART_LL_EF_Init + * @{ + */ + +/** + * @brief De-initialize LPUART registers (Registers restored to their default values). + * @param LPUARTx LPUART Instance + * @retval An ErrorStatus enumeration value: + * - SUCCESS: LPUART registers are de-initialized + * - ERROR: not applicable + */ +ErrorStatus LL_LPUART_DeInit(const USART_TypeDef *LPUARTx) +{ + ErrorStatus status = SUCCESS; + + /* Check the parameters */ + assert_param(IS_LPUART_INSTANCE(LPUARTx)); + + if (LPUARTx == LPUART1) + { + /* Force reset of LPUART peripheral */ + LL_APB3_GRP1_ForceReset(LL_APB3_GRP1_PERIPH_LPUART1); + + /* Release reset of LPUART peripheral */ + LL_APB3_GRP1_ReleaseReset(LL_APB3_GRP1_PERIPH_LPUART1); + } + else + { + status = ERROR; + } + + return (status); +} + +/** + * @brief Initialize LPUART registers according to the specified + * parameters in LPUART_InitStruct. + * @note As some bits in LPUART configuration registers can only be written when + * the LPUART is disabled (USART_CR1_UE bit =0), + * LPUART Peripheral should be in disabled state prior calling this function. + * Otherwise, ERROR result will be returned. + * @note Baud rate value stored in LPUART_InitStruct BaudRate field, should be valid (different from 0). + * @param LPUARTx LPUART Instance + * @param LPUART_InitStruct pointer to a @ref LL_LPUART_InitTypeDef structure + * that contains the configuration information for the specified LPUART peripheral. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: LPUART registers are initialized according to LPUART_InitStruct content + * - ERROR: Problem occurred during LPUART Registers initialization + */ +ErrorStatus LL_LPUART_Init(USART_TypeDef *LPUARTx, const LL_LPUART_InitTypeDef *LPUART_InitStruct) +{ + ErrorStatus status = ERROR; + uint32_t periphclk; + + /* Check the parameters */ + assert_param(IS_LPUART_INSTANCE(LPUARTx)); + assert_param(IS_LL_LPUART_PRESCALER(LPUART_InitStruct->PrescalerValue)); + assert_param(IS_LL_LPUART_BAUDRATE(LPUART_InitStruct->BaudRate)); + assert_param(IS_LL_LPUART_DATAWIDTH(LPUART_InitStruct->DataWidth)); + assert_param(IS_LL_LPUART_STOPBITS(LPUART_InitStruct->StopBits)); + assert_param(IS_LL_LPUART_PARITY(LPUART_InitStruct->Parity)); + assert_param(IS_LL_LPUART_DIRECTION(LPUART_InitStruct->TransferDirection)); + assert_param(IS_LL_LPUART_HWCONTROL(LPUART_InitStruct->HardwareFlowControl)); + + /* LPUART needs to be in disabled state, in order to be able to configure some bits in + CRx registers. Otherwise (LPUART not in Disabled state) => return ERROR */ + if (LL_LPUART_IsEnabled(LPUARTx) == 0U) + { + /*---------------------------- LPUART CR1 Configuration ----------------------- + * Configure LPUARTx CR1 (LPUART Word Length, Parity and Transfer Direction bits) with parameters: + * - DataWidth: USART_CR1_M bits according to LPUART_InitStruct->DataWidth value + * - Parity: USART_CR1_PCE, USART_CR1_PS bits according to LPUART_InitStruct->Parity value + * - TransferDirection: USART_CR1_TE, USART_CR1_RE bits according to LPUART_InitStruct->TransferDirection value + */ + MODIFY_REG(LPUARTx->CR1, + (USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE), + (LPUART_InitStruct->DataWidth | LPUART_InitStruct->Parity | LPUART_InitStruct->TransferDirection)); + + /*---------------------------- LPUART CR2 Configuration ----------------------- + * Configure LPUARTx CR2 (Stop bits) with parameters: + * - Stop Bits: USART_CR2_STOP bits according to LPUART_InitStruct->StopBits value. + */ + LL_LPUART_SetStopBitsLength(LPUARTx, LPUART_InitStruct->StopBits); + + /*---------------------------- LPUART CR3 Configuration ----------------------- + * Configure LPUARTx CR3 (Hardware Flow Control) with parameters: + * - HardwareFlowControl: USART_CR3_RTSE, USART_CR3_CTSE bits according + * to LPUART_InitStruct->HardwareFlowControl value. + */ + LL_LPUART_SetHWFlowCtrl(LPUARTx, LPUART_InitStruct->HardwareFlowControl); + + /*---------------------------- LPUART BRR Configuration ----------------------- + * Retrieve Clock frequency used for LPUART Peripheral + */ + periphclk = LL_RCC_GetLPUARTClockFreq(LL_RCC_LPUART1_CLKSOURCE); + + /* Configure the LPUART Baud Rate : + - prescaler value is required + - valid baud rate value (different from 0) is required + - Peripheral clock as returned by RCC service, should be valid (different from 0). + */ + if ((periphclk != LL_RCC_PERIPH_FREQUENCY_NO) + && (LPUART_InitStruct->BaudRate != 0U)) + { + status = SUCCESS; + LL_LPUART_SetBaudRate(LPUARTx, + periphclk, + LPUART_InitStruct->PrescalerValue, + LPUART_InitStruct->BaudRate); + + /* Check BRR is greater than or equal to 0x300 */ + assert_param(IS_LL_LPUART_BRR_MIN(LPUARTx->BRR)); + + /* Check BRR is lower than or equal to 0xFFFFF */ + assert_param(IS_LL_LPUART_BRR_MAX(LPUARTx->BRR)); + } + + /*---------------------------- LPUART PRESC Configuration ----------------------- + * Configure LPUARTx PRESC (Prescaler) with parameters: + * - PrescalerValue: LPUART_PRESC_PRESCALER bits according to LPUART_InitStruct->PrescalerValue value. + */ + LL_LPUART_SetPrescaler(LPUARTx, LPUART_InitStruct->PrescalerValue); + } + + return (status); +} + +/** + * @brief Set each @ref LL_LPUART_InitTypeDef field to default value. + * @param LPUART_InitStruct pointer to a @ref LL_LPUART_InitTypeDef structure + * whose fields will be set to default values. + * @retval None + */ + +void LL_LPUART_StructInit(LL_LPUART_InitTypeDef *LPUART_InitStruct) +{ + /* Set LPUART_InitStruct fields to default values */ + LPUART_InitStruct->PrescalerValue = LL_LPUART_PRESCALER_DIV1; + LPUART_InitStruct->BaudRate = LPUART_DEFAULT_BAUDRATE; + LPUART_InitStruct->DataWidth = LL_LPUART_DATAWIDTH_8B; + LPUART_InitStruct->StopBits = LL_LPUART_STOPBITS_1; + LPUART_InitStruct->Parity = LL_LPUART_PARITY_NONE ; + LPUART_InitStruct->TransferDirection = LL_LPUART_DIRECTION_TX_RX; + LPUART_InitStruct->HardwareFlowControl = LL_LPUART_HWCONTROL_NONE; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* LPUART1 */ + +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_opamp.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_opamp.c new file mode 100644 index 0000000000..c69fb9239b --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_opamp.c @@ -0,0 +1,218 @@ +/** + ********************************************************************************************************************** + * @file stm32h5xx_ll_opamp.c + * @author MCD Application Team + * @brief OPAMP LL module driver + ********************************************************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ********************************************************************************************************************** + */ +#if defined(USE_FULL_LL_DRIVER) + +/* Includes ----------------------------------------------------------------------------------------------------------*/ +#include "stm32h5xx_ll_opamp.h" + +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (OPAMP1) +/** @addtogroup OPAMP_LL OPAMP + * @{ + */ + +/* Private types -----------------------------------------------------------------------------------------------------*/ +/* Private variables -------------------------------------------------------------------------------------------------*/ +/* Private constants -------------------------------------------------------------------------------------------------*/ +/* Private macros ----------------------------------------------------------------------------------------------------*/ +/** @addtogroup OPAMP_LL_Private_Macros + * @{ + */ + +/* Check of parameters for configuration of OPAMP hierarchical scope: */ +/* OPAMP instance. */ + +#define IS_LL_OPAMP_POWER_MODE(__POWER_MODE__) \ + (((__POWER_MODE__) == LL_OPAMP_POWERMODE_NORMAL) \ + || ((__POWER_MODE__) == LL_OPAMP_POWERMODE_HIGHSPEED)) + +#define IS_LL_OPAMP_FUNCTIONAL_MODE(__FUNCTIONAL_MODE__) \ + (((__FUNCTIONAL_MODE__) == LL_OPAMP_MODE_STANDALONE) \ + || ((__FUNCTIONAL_MODE__) == LL_OPAMP_MODE_FOLLOWER) \ + || ((__FUNCTIONAL_MODE__) == LL_OPAMP_MODE_PGA) \ + || ((__FUNCTIONAL_MODE__) == LL_OPAMP_MODE_PGA_IO0) \ + || ((__FUNCTIONAL_MODE__) == LL_OPAMP_MODE_PGA_IO0_BIAS) \ + || ((__FUNCTIONAL_MODE__) == LL_OPAMP_MODE_PGA_IO0_IO1_BIAS) \ + ) + +#define IS_LL_OPAMP_INPUT_NONINVERTING(__INPUT_NONINVERTING__) \ + (((__INPUT_NONINVERTING__) == LL_OPAMP_INPUT_NONINVERT_IO0) \ + || ((__INPUT_NONINVERTING__) == LL_OPAMP_INPUT_NONINVERT_IO1) \ + || ((__INPUT_NONINVERTING__) == LL_OPAMP_INPUT_NONINVERT_DAC) \ + ) + + + +#define IS_LL_OPAMP_INPUT_INVERTING(__INPUT_INVERTING__) \ + (((__INPUT_INVERTING__) == LL_OPAMP_INPUT_INVERT_IO0) \ + || ((__INPUT_INVERTING__) == LL_OPAMP_INPUT_INVERT_IO1) \ + || ((__INPUT_INVERTING__) == LL_OPAMP_INPUT_INVERT_CONNECT_NO) \ + ) + +/** + * @} + */ + +/* Private function prototypes ---------------------------------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------------------------------------------------*/ +/** @addtogroup OPAMP_LL_Exported_Functions + * @{ + */ + +/** @addtogroup OPAMP_LL_EF_Init + * @{ + */ + +/** + * @brief De-initialize registers of the selected OPAMP instance + * to their default reset values. + * @note If comparator is locked, de-initialization by software is + * not possible. + * The only way to unlock the comparator is a device hardware reset. + * @param OPAMPx OPAMP instance + * @retval An ErrorStatus enumeration value: + * - SUCCESS: OPAMP registers are de-initialized + * - ERROR: OPAMP registers are not de-initialized + */ +ErrorStatus LL_OPAMP_DeInit(OPAMP_TypeDef *OPAMPx) +{ + ErrorStatus status = SUCCESS; + + /* Check the parameters */ + assert_param(IS_OPAMP_ALL_INSTANCE(OPAMPx)); + + LL_OPAMP_WriteReg(OPAMPx, CSR, 0x00000000U); + + return status; +} + +/** + * @brief Initialize some features of OPAMP instance. + * @note This function reset bit of calibration mode to ensure + * to be in functional mode, in order to have OPAMP parameters + * (inputs selection, ...) set with the corresponding OPAMP mode + * to be effective. + * @param OPAMPx OPAMP instance + * @param OPAMP_InitStruct Pointer to a @ref LL_OPAMP_InitTypeDef structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: OPAMP registers are initialized + * - ERROR: OPAMP registers are not initialized + */ +ErrorStatus LL_OPAMP_Init(OPAMP_TypeDef *OPAMPx, const LL_OPAMP_InitTypeDef *OPAMP_InitStruct) +{ + ErrorStatus status = SUCCESS; + + /* Check the parameters */ + assert_param(IS_OPAMP_ALL_INSTANCE(OPAMPx)); + assert_param(IS_LL_OPAMP_POWER_MODE(OPAMP_InitStruct->PowerMode)); + assert_param(IS_LL_OPAMP_FUNCTIONAL_MODE(OPAMP_InitStruct->FunctionalMode)); + assert_param(IS_LL_OPAMP_INPUT_NONINVERTING(OPAMP_InitStruct->InputNonInverting)); + + /* Note: OPAMP inverting input can be used with OPAMP in mode standalone */ + /* or PGA with external capacitors for filtering circuit. */ + /* Otherwise (OPAMP in mode follower), OPAMP inverting input is */ + /* not used (not connected to GPIO pin). */ + if (OPAMP_InitStruct->FunctionalMode != LL_OPAMP_MODE_FOLLOWER) + { + assert_param(IS_LL_OPAMP_INPUT_INVERTING(OPAMP_InitStruct->InputInverting)); + } + + /* Configuration of OPAMP instance : */ + /* - PowerMode */ + /* - Functional mode */ + /* - Input non-inverting */ + /* - Input inverting */ + /* Note: Bit OPAMP_CSR_CALON reset to ensure to be in functional mode. */ + if (OPAMP_InitStruct->FunctionalMode != LL_OPAMP_MODE_FOLLOWER) + { + MODIFY_REG(OPAMPx->CSR, + OPAMP_CSR_OPAHSM + | OPAMP_CSR_CALON + | OPAMP_CSR_VMSEL + | OPAMP_CSR_VPSEL + | OPAMP_CSR_PGGAIN_2 | OPAMP_CSR_PGGAIN_1 + , + (OPAMP_InitStruct->PowerMode & OPAMP_POWERMODE_CSR_BIT_MASK) + | OPAMP_InitStruct->FunctionalMode + | OPAMP_InitStruct->InputNonInverting + | OPAMP_InitStruct->InputInverting + ); + } + else + { + MODIFY_REG(OPAMPx->CSR, + OPAMP_CSR_OPAHSM + | OPAMP_CSR_CALON + | OPAMP_CSR_VMSEL + | OPAMP_CSR_VPSEL + | OPAMP_CSR_PGGAIN_2 | OPAMP_CSR_PGGAIN_1 + , + (OPAMP_InitStruct->PowerMode & OPAMP_POWERMODE_CSR_BIT_MASK) + | LL_OPAMP_MODE_FOLLOWER + | OPAMP_InitStruct->InputNonInverting + ); + } + + return status; +} + +/** + * @brief Set each @ref LL_OPAMP_InitTypeDef field to default value. + * @param OPAMP_InitStruct pointer to a @ref LL_OPAMP_InitTypeDef structure + * whose fields will be set to default values. + * @retval None + */ +void LL_OPAMP_StructInit(LL_OPAMP_InitTypeDef *OPAMP_InitStruct) +{ + /* Set OPAMP_InitStruct fields to default values */ + OPAMP_InitStruct->PowerMode = LL_OPAMP_POWERMODE_NORMAL; + OPAMP_InitStruct->FunctionalMode = LL_OPAMP_MODE_FOLLOWER; + OPAMP_InitStruct->InputNonInverting = LL_OPAMP_INPUT_NONINVERT_IO0; + /* Note: Parameter discarded if OPAMP in functional mode follower, */ + /* set anyway to its default value. */ + OPAMP_InitStruct->InputInverting = LL_OPAMP_INPUT_INVERT_CONNECT_NO; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* OPAMP1 */ + +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_pka.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_pka.c new file mode 100644 index 0000000000..b0c9fed2f4 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_pka.c @@ -0,0 +1,163 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_pka.c + * @author MCD Application Team + * @brief PKA LL module driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +#if defined(USE_FULL_LL_DRIVER) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_pka.h" +#include "stm32h5xx_ll_bus.h" + +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined(PKA) + +/** @addtogroup PKA_LL + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup PKA_LL_Private_Macros PKA Private Constants + * @{ + */ +#define IS_LL_PKA_MODE(__VALUE__) (((__VALUE__)== LL_PKA_MODE_MODULAR_EXP) ||\ + ((__VALUE__) == LL_PKA_MODE_MONTGOMERY_PARAM) ||\ + ((__VALUE__) == LL_PKA_MODE_MODULAR_EXP_FAST) ||\ + ((__VALUE__) == LL_PKA_MODE_MODULAR_EXP_PROTECT) ||\ + ((__VALUE__) == LL_PKA_MODE_ECC_MUL) ||\ + ((__VALUE__) == LL_PKA_MODE_ECC_COMPLETE_ADD) ||\ + ((__VALUE__) == LL_PKA_MODE_ECDSA_SIGNATURE) ||\ + ((__VALUE__) == LL_PKA_MODE_ECDSA_VERIFICATION) ||\ + ((__VALUE__) == LL_PKA_MODE_POINT_CHECK) ||\ + ((__VALUE__) == LL_PKA_MODE_RSA_CRT_EXP) ||\ + ((__VALUE__) == LL_PKA_MODE_MODULAR_INV) ||\ + ((__VALUE__) == LL_PKA_MODE_ARITHMETIC_ADD) ||\ + ((__VALUE__) == LL_PKA_MODE_ARITHMETIC_SUB) ||\ + ((__VALUE__) == LL_PKA_MODE_ARITHMETIC_MUL) ||\ + ((__VALUE__) == LL_PKA_MODE_COMPARISON) ||\ + ((__VALUE__) == LL_PKA_MODE_MODULAR_REDUC) ||\ + ((__VALUE__) == LL_PKA_MODE_MODULAR_ADD) ||\ + ((__VALUE__) == LL_PKA_MODE_MODULAR_SUB) ||\ + ((__VALUE__) == LL_PKA_MODE_MONTGOMERY_MUL) ||\ + ((__VALUE__) == LL_PKA_MODE_DOUBLE_BASE_LADDER) ||\ + ((__VALUE__) == LL_PKA_MODE_ECC_PROJECTIVE_AFF)) +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup PKA_LL_Exported_Functions + * @{ + */ + +/** @addtogroup PKA_LL_EF_Init + * @{ + */ + +/** + * @brief De-initialize PKA registers (Registers restored to their default values). + * @param PKAx PKA Instance. + * @retval ErrorStatus + * - SUCCESS: PKA registers are de-initialized + * - ERROR: PKA registers are not de-initialized + */ +ErrorStatus LL_PKA_DeInit(const PKA_TypeDef *PKAx) +{ + ErrorStatus status = SUCCESS; + + /* Check the parameters */ + assert_param(IS_PKA_ALL_INSTANCE(PKAx)); + + if (PKAx == PKA) + { + /* Force PKA reset */ + LL_AHB2_GRP1_ForceReset(LL_AHB2_GRP1_PERIPH_PKA); + + /* Release PKA reset */ + LL_AHB2_GRP1_ReleaseReset(LL_AHB2_GRP1_PERIPH_PKA); + } + else + { + status = ERROR; + } + + return (status); +} + +/** + * @brief Initialize PKA registers according to the specified parameters in PKA_InitStruct. + * @param PKAx PKA Instance. + * @param PKA_InitStruct pointer to a @ref LL_PKA_InitTypeDef structure + * that contains the configuration information for the specified PKA peripheral. + * @retval ErrorStatus + * - SUCCESS: PKA registers are initialized according to PKA_InitStruct content + * - ERROR: Not applicable + */ +ErrorStatus LL_PKA_Init(PKA_TypeDef *PKAx, LL_PKA_InitTypeDef *PKA_InitStruct) +{ + assert_param(IS_PKA_ALL_INSTANCE(PKAx)); + assert_param(IS_LL_PKA_MODE(PKA_InitStruct->Mode)); + + LL_PKA_Config(PKAx, PKA_InitStruct->Mode); + + return (SUCCESS); +} + +/** + * @brief Set each @ref LL_PKA_InitTypeDef field to default value. + * @param PKA_InitStruct pointer to a @ref LL_PKA_InitTypeDef structure + * whose fields will be set to default values. + * @retval None + */ + +void LL_PKA_StructInit(LL_PKA_InitTypeDef *PKA_InitStruct) +{ + /* Reset PKA init structure parameters values */ + PKA_InitStruct->Mode = LL_PKA_MODE_MODULAR_EXP; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined (PKA) */ + +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_pwr.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_pwr.c new file mode 100644 index 0000000000..5926631b0f --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_pwr.c @@ -0,0 +1,82 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_pwr.c + * @author MCD Application Team + * @brief PWR LL module driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +#if defined (USE_FULL_LL_DRIVER) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_pwr.h" + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (PWR) + +/** @defgroup PWR_LL PWR + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup PWR_LL_Exported_Functions + * @{ + */ + +/** @addtogroup PWR_LL_EF_Init + * @{ + */ + +/** + * @brief De-initialize the PWR registers to their default reset values. + * @retval An ErrorStatus enumeration value: + * - SUCCESS : PWR registers are de-initialized. + * - ERROR : not applicable. + */ +ErrorStatus LL_PWR_DeInit(void) +{ + /* Clear PWR low power flags */ + LL_PWR_ClearFlag_STOP(); + + /* Clear PWR wake up flags */ + LL_PWR_ClearFlag_WU(); + + return SUCCESS; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* defined(PWR) */ +/** + * @} + */ + +#endif /* defined (USE_FULL_LL_DRIVER) */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_rcc.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_rcc.c new file mode 100644 index 0000000000..a35546d158 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_rcc.c @@ -0,0 +1,3313 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_rcc.c + * @author MCD Application Team + * @brief RCC LL module driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +#if defined(USE_FULL_LL_DRIVER) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_rcc.h" +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined(RCC) + +/** @addtogroup RCC_LL + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup RCC_LL_Private_Macros + * @{ + */ +#if defined(USART6) +#define IS_LL_RCC_USART_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_USART1_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_USART2_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_USART3_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_USART6_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_USART10_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_USART11_CLKSOURCE)) +#else +#define IS_LL_RCC_USART_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_USART1_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_USART2_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_USART3_CLKSOURCE)) +#endif /* USART6 */ + +#if defined(UART4) +#define IS_LL_RCC_UART_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_UART4_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_UART5_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_UART7_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_UART8_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_UART9_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_UART12_CLKSOURCE)) +#endif /* UART4 */ + +#define IS_LL_RCC_LPUART_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_LPUART1_CLKSOURCE)) + +#if defined(I2C3) +#define IS_LL_RCC_I2C_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_I2C1_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_I2C2_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_I2C3_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_I2C4_CLKSOURCE)) +#else +#define IS_LL_RCC_I2C_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_I2C1_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_I2C2_CLKSOURCE)) +#endif /* I2C3*/ + +#if defined(I3C2) +#define IS_LL_RCC_I3C_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_I3C1_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_I3C2_CLKSOURCE)) +#else +#define IS_LL_RCC_I3C_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_I3C1_CLKSOURCE)) +#endif /* I3C2 */ + +#if defined(SPI4) +#define IS_LL_RCC_SPI_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_SPI1_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_SPI2_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_SPI3_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_SPI4_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_SPI5_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_SPI6_CLKSOURCE)) +#else +#define IS_LL_RCC_SPI_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_SPI1_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_SPI2_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_SPI3_CLKSOURCE)) +#endif /* SPI4 */ + +#if defined(LPTIM3) +#define IS_LL_RCC_LPTIM_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_LPTIM1_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_LPTIM2_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_LPTIM3_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_LPTIM4_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_LPTIM5_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_LPTIM6_CLKSOURCE)) +#else +#define IS_LL_RCC_LPTIM_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_LPTIM1_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_LPTIM2_CLKSOURCE)) +#endif /* LPTIM3 */ + +#if defined(SAI1) +#define IS_LL_RCC_SAI_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_SAI1_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_SAI2_CLKSOURCE)) +#endif /* SAI1 */ + +#if defined (SDMMC2) +#define IS_LL_RCC_SDMMC_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_SDMMC1_CLKSOURCE) \ + || ((__VALUE__) == LL_RCC_SDMMC2_CLKSOURCE)) +#elif defined (SDMMC1) +#define IS_LL_RCC_SDMMC_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_SDMMC1_CLKSOURCE)) +#endif /* SDMMC2*/ + +#define IS_LL_RCC_RNG_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_RNG_CLKSOURCE)) + +#define IS_LL_RCC_USB_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_USB_CLKSOURCE)) + +#define IS_LL_RCC_ADCDAC_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_ADCDAC_CLKSOURCE)) + +#define IS_LL_RCC_DAC_LP_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_DAC_LP_CLKSOURCE)) + +#define IS_LL_RCC_OCTOSPI_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_OCTOSPI_CLKSOURCE)) + +#define IS_LL_RCC_FDCAN_CLKSOURCE(__VALUE__) ((__VALUE__) == LL_RCC_FDCAN_CLKSOURCE) + +#if defined(CEC) +#define IS_LL_RCC_CEC_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_CEC_CLKSOURCE)) +#endif /* CEC */ + +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup RCC_LL_Private_Functions RCC Private functions + * @{ + */ +uint32_t RCC_GetSystemClockFreq(void); +uint32_t RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency); +uint32_t RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency); +uint32_t RCC_GetPCLK2ClockFreq(uint32_t HCLK_Frequency); +uint32_t RCC_GetPCLK3ClockFreq(uint32_t HCLK_Frequency); +uint32_t RCC_PLL1_GetFreqSystem(void); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup RCC_LL_Exported_Functions + * @{ + */ + +/** @addtogroup RCC_LL_EF_Init + * @{ + */ + +/** + * @brief Reset the RCC clock configuration to the default reset state. + * @note The default reset state of the clock configuration is given below: + * - HSI ON and used as system clock source + * - HSE, CSI, PLL1, PLL2 and PLL3 OFF + * - AHB, APB1, APB2 and APB3 prescaler set to 1. + * - CSS OFF + * - All interrupts disabled + * @note This function doesn't modify the configuration of the + * - Peripheral clocks + * - LSI, LSE and RTC clocks + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RCC registers are de-initialized + * - ERROR: not applicable + */ +ErrorStatus LL_RCC_DeInit(void) +{ + + /* Set HSION bit */ + LL_RCC_HSI_Enable(); + + /* Wait for HSI READY bit */ + while (LL_RCC_HSI_IsReady() == 0U) + { + } + + /* Set HSIDIV Default value */ + CLEAR_BIT(RCC->CR, RCC_CR_HSIDIV); + + /* Set HSITRIM bits to the reset value*/ + LL_RCC_HSI_SetCalibTrimming(0x40U); + + /* Reset CFGR register */ + LL_RCC_WriteReg(CFGR1, 0x00000000U); + LL_RCC_WriteReg(CFGR2, 0x00000000U); + + /* Wait till clock switch is ready */ + while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI) + { + } + +#if defined(RCC_CR_PLL3ON) + /* Reset HSECSSON, HSEON, HSIKERON, CSION, CSIKERON, HSI48ON, PLL1ON, PLL2ON and PLL3ON bits */ + CLEAR_BIT(RCC->CR, RCC_CR_CSION | RCC_CR_CSIKERON | RCC_CR_HSECSSON | RCC_CR_HSIKERON | RCC_CR_HSI48ON | + RCC_CR_HSEON | RCC_CR_PLL1ON | RCC_CR_PLL2ON | RCC_CR_PLL3ON); +#else + /* Reset HSECSSON, HSEON, HSIKERON, CSION, CSIKERON, HSI48ON, PLL1ON, PLL2ON and PLL3ON bits */ + CLEAR_BIT(RCC->CR, RCC_CR_CSION | RCC_CR_CSIKERON | RCC_CR_HSECSSON | RCC_CR_HSIKERON | RCC_CR_HSI48ON | + RCC_CR_HSEON | RCC_CR_PLL1ON | RCC_CR_PLL2ON); +#endif /* PLL3 */ + + /* Wait for PLL1 READY bit to be reset */ + while (LL_RCC_PLL1_IsReady() != 0U) + {} + + /* Wait for PLL2 READY bit to be reset */ + while (LL_RCC_PLL2_IsReady() != 0U) + {} + +#if defined(RCC_CR_PLL3ON) + /* Wait for PLL3 READY bit to be reset */ + while (LL_RCC_PLL3_IsReady() != 0U) + {} +#endif /* PLL3 */ + + /* Reset PLL1CFGR register */ + CLEAR_REG(RCC->PLL1CFGR); + + /* Reset PLL1DIVR register */ + LL_RCC_WriteReg(PLL1DIVR, 0x01010280U); + + /* Reset PLL1FRACR register */ + CLEAR_REG(RCC->PLL1FRACR); + + /* Reset PLL2CFGR register */ + CLEAR_REG(RCC->PLL2CFGR); + + /* Reset PLL2DIVR register */ + LL_RCC_WriteReg(PLL2DIVR, 0x01010280U); + + /* Reset PLL2FRACR register */ + CLEAR_REG(RCC->PLL2FRACR); + +#if defined(RCC_CR_PLL3ON) + /* Reset PLL3CFGR register */ + CLEAR_REG(RCC->PLL3CFGR); + + /* Reset PLL3DIVR register */ + LL_RCC_WriteReg(PLL3DIVR, 0x01010280U); + + /* Reset PLL3FRACR register */ + CLEAR_REG(RCC->PLL3FRACR); +#endif /* PLL3 */ + + /* Reset HSEBYP bit */ + CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP); + + /* Reset HSEEXT bit */ + CLEAR_BIT(RCC->CR, RCC_CR_HSEEXT); + +#if defined(RCC_CR_PLL3ON) + /* Disable all interrupts */ + CLEAR_BIT(RCC->CIER, RCC_CIER_LSIRDYIE | RCC_CIER_LSERDYIE | RCC_CIER_HSIRDYIE | RCC_CIER_HSERDYIE + | RCC_CIER_CSIRDYIE | RCC_CIER_HSI48RDYIE | RCC_CIER_PLL1RDYIE | RCC_CIER_PLL2RDYIE + | RCC_CIER_PLL3RDYIE); + + /* Clear all interrupt flags */ + SET_BIT(RCC->CICR, RCC_CICR_LSIRDYC | RCC_CICR_LSERDYC | RCC_CICR_HSIRDYC | RCC_CICR_HSERDYC + | RCC_CICR_CSIRDYC | RCC_CICR_HSI48RDYC | RCC_CICR_PLL1RDYC | RCC_CICR_PLL2RDYC + | RCC_CICR_PLL3RDYC | RCC_CICR_HSECSSC); +#else + /* Disable all interrupts */ + CLEAR_BIT(RCC->CIER, RCC_CIER_LSIRDYIE | RCC_CIER_LSERDYIE | RCC_CIER_HSIRDYIE | RCC_CIER_HSERDYIE + | RCC_CIER_CSIRDYIE | RCC_CIER_HSI48RDYIE | RCC_CIER_PLL1RDYIE | RCC_CIER_PLL2RDYIE); + + /* Clear all interrupt flags */ + SET_BIT(RCC->CICR, RCC_CICR_LSIRDYC | RCC_CICR_LSERDYC | RCC_CICR_HSIRDYC | RCC_CICR_HSERDYC + | RCC_CICR_CSIRDYC | RCC_CICR_HSI48RDYC | RCC_CICR_PLL1RDYC | RCC_CICR_PLL2RDYC + | RCC_CICR_HSECSSC); +#endif /* PLL3 */ + + + /* Clear all reset flags */ + LL_RCC_ClearResetFlags(); + + /* Update the SystemCoreClock global variable */ + SystemCoreClock = HSI_VALUE; + + return SUCCESS; +} + +/** + * @} + */ + +/** @addtogroup RCC_LL_EF_Get_Freq + * @brief Return the frequencies of different on chip clocks; System, AHB, APB1 and APB2 buses clocks + * and different peripheral clocks available on the device. + * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*) + * @note If SYSCLK source is CSI, function returns values based on CSI_VALUE(**) + * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(***) + * @note If SYSCLK source is PLL1, function returns values based on HSE_VALUE(***) + * or HSI_VALUE(**) or CSI_VALUE(*) multiplied/divided by the main PLL factors. + * @note (*) HSI_VALUE is a constant defined in this file (default value + * 64 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * @note (**) CSI_VALUE is a constant defined in this file (default value + * 4 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * @note (***) HSE_VALUE is a constant defined in this file (default value + * 32 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * @note The result of this function could be incorrect when using fractional + * value for HSE crystal. + * @note This function can be used by the user application to compute the + * baud-rate for the communication peripherals or configure other parameters. + * @{ + */ + +/** + * @brief Return the frequencies of different on chip clocks; System, AHB, APB1, APB2 and APB3 buses clocks + * @note Each time SYSCLK, HCLK, PCLK1, PCLK2 and PCLK3 clock changes, this function + * must be called to update structure fields. Otherwise, any + * configuration based on this function will be incorrect. + * @param pRCC_Clocks pointer to a @ref LL_RCC_ClocksTypeDef structure which will hold the clocks frequencies + * @retval None + */ +void LL_RCC_GetSystemClocksFreq(LL_RCC_ClocksTypeDef *pRCC_Clocks) +{ + /* Get SYSCLK frequency */ + pRCC_Clocks->SYSCLK_Frequency = RCC_GetSystemClockFreq(); + + /* HCLK clock frequency */ + pRCC_Clocks->HCLK_Frequency = RCC_GetHCLKClockFreq(pRCC_Clocks->SYSCLK_Frequency); + + /* PCLK1 clock frequency */ + pRCC_Clocks->PCLK1_Frequency = RCC_GetPCLK1ClockFreq(pRCC_Clocks->HCLK_Frequency); + + /* PCLK2 clock frequency */ + pRCC_Clocks->PCLK2_Frequency = RCC_GetPCLK2ClockFreq(pRCC_Clocks->HCLK_Frequency); + + /* PCLK3 clock frequency */ + pRCC_Clocks->PCLK3_Frequency = RCC_GetPCLK3ClockFreq(pRCC_Clocks->HCLK_Frequency); +} + +/** + * @brief Return PLL1 clocks frequencies + * @note LL_RCC_PERIPH_FREQUENCY_NO returned for non activated output or oscillator not ready + * @retval None + */ +void LL_RCC_GetPLL1ClockFreq(LL_PLL_ClocksTypeDef *pPLL_Clocks) +{ + uint32_t pllinputfreq = LL_RCC_PERIPH_FREQUENCY_NO; + uint32_t pllsource; + uint32_t pllm; + uint32_t plln; + uint32_t fracn = 0U; + + /* PLL_VCO = (HSE_VALUE, CSI_VALUE or HSI_VALUE/HSIDIV) / PLLM * (PLLN + FRACN) + SYSCLK = PLL_VCO / PLLP + */ + pllsource = LL_RCC_PLL1_GetSource(); + + switch (pllsource) + { + case LL_RCC_PLL1SOURCE_HSI: + if (LL_RCC_HSI_IsReady() != 0U) + { + pllinputfreq = HSI_VALUE >> (LL_RCC_HSI_GetDivider() >> RCC_CR_HSIDIV_Pos); + } + break; + + case LL_RCC_PLL1SOURCE_CSI: + if (LL_RCC_CSI_IsReady() != 0U) + { + pllinputfreq = CSI_VALUE; + } + break; + + case LL_RCC_PLL1SOURCE_HSE: + if (LL_RCC_HSE_IsReady() != 0U) + { + pllinputfreq = HSE_VALUE; + } + break; + + case LL_RCC_PLL1SOURCE_NONE: + default: + /* PLL clock disabled */ + break; + } + + pPLL_Clocks->PLL_P_Frequency = 0U; + pPLL_Clocks->PLL_Q_Frequency = 0U; + pPLL_Clocks->PLL_R_Frequency = 0U; + + pllm = LL_RCC_PLL1_GetM(); + plln = LL_RCC_PLL1_GetN(); + if (LL_RCC_PLL1FRACN_IsEnabled() != 0U) + { + fracn = LL_RCC_PLL1_GetFRACN(); + } + + if (pllm != 0U) + { + if (LL_RCC_PLL1P_IsEnabled() != 0U) + { + pPLL_Clocks->PLL_P_Frequency = LL_RCC_CalcPLLClockFreq(pllinputfreq, pllm, plln, fracn, LL_RCC_PLL1_GetP()); + } + + if (LL_RCC_PLL1Q_IsEnabled() != 0U) + { + pPLL_Clocks->PLL_Q_Frequency = LL_RCC_CalcPLLClockFreq(pllinputfreq, pllm, plln, fracn, LL_RCC_PLL1_GetQ()); + } + + if (LL_RCC_PLL1R_IsEnabled() != 0U) + { + pPLL_Clocks->PLL_R_Frequency = LL_RCC_CalcPLLClockFreq(pllinputfreq, pllm, plln, fracn, LL_RCC_PLL1_GetR()); + } + } +} + +/** + * @brief Return PLL2 clocks frequencies + * @note LL_RCC_PERIPH_FREQUENCY_NO returned for non activated output or oscillator not ready + * @retval None + */ +void LL_RCC_GetPLL2ClockFreq(LL_PLL_ClocksTypeDef *pPLL_Clocks) +{ + uint32_t pllinputfreq = LL_RCC_PERIPH_FREQUENCY_NO; + uint32_t pllsource; + uint32_t pllm; + uint32_t plln; + uint32_t fracn = 0U; + + /* PLL_VCO = (HSE_VALUE, CSI_VALUE or HSI_VALUE/HSIDIV) / PLLM * (PLLN + FRACN) + SYSCLK = PLL_VCO / PLLP + */ + pllsource = LL_RCC_PLL2_GetSource(); + + switch (pllsource) + { + case LL_RCC_PLL2SOURCE_HSI: + if (LL_RCC_HSI_IsReady() != 0U) + { + pllinputfreq = HSI_VALUE >> (LL_RCC_HSI_GetDivider() >> RCC_CR_HSIDIV_Pos); + } + break; + + case LL_RCC_PLL2SOURCE_CSI: + if (LL_RCC_CSI_IsReady() != 0U) + { + pllinputfreq = CSI_VALUE; + } + break; + + case LL_RCC_PLL2SOURCE_HSE: + if (LL_RCC_HSE_IsReady() != 0U) + { + pllinputfreq = HSE_VALUE; + } + break; + + case LL_RCC_PLL2SOURCE_NONE: + default: + /* PLL clock disabled */ + break; + } + + pPLL_Clocks->PLL_P_Frequency = 0U; + pPLL_Clocks->PLL_Q_Frequency = 0U; + pPLL_Clocks->PLL_R_Frequency = 0U; + + pllm = LL_RCC_PLL2_GetM(); + plln = LL_RCC_PLL2_GetN(); + if (LL_RCC_PLL2FRACN_IsEnabled() != 0U) + { + fracn = LL_RCC_PLL2_GetFRACN(); + } + + if (pllm != 0U) + { + if (LL_RCC_PLL2P_IsEnabled() != 0U) + { + pPLL_Clocks->PLL_P_Frequency = LL_RCC_CalcPLLClockFreq(pllinputfreq, pllm, plln, fracn, LL_RCC_PLL2_GetP()); + } + + if (LL_RCC_PLL2Q_IsEnabled() != 0U) + { + pPLL_Clocks->PLL_Q_Frequency = LL_RCC_CalcPLLClockFreq(pllinputfreq, pllm, plln, fracn, LL_RCC_PLL2_GetQ()); + } + + if (LL_RCC_PLL2R_IsEnabled() != 0U) + { + pPLL_Clocks->PLL_R_Frequency = LL_RCC_CalcPLLClockFreq(pllinputfreq, pllm, plln, fracn, LL_RCC_PLL2_GetR()); + } + } +} + +#if defined(RCC_CR_PLL3ON) +/** + * @brief Return PLL3 clocks frequencies + * @note LL_RCC_PERIPH_FREQUENCY_NO returned for non activated output or oscillator not ready + * @retval None + */ +void LL_RCC_GetPLL3ClockFreq(LL_PLL_ClocksTypeDef *pPLL_Clocks) +{ + uint32_t pllinputfreq = LL_RCC_PERIPH_FREQUENCY_NO; + uint32_t pllsource; + uint32_t pllm; + uint32_t plln; + uint32_t fracn = 0U; + + /* PLL_VCO = (HSE_VALUE, CSI_VALUE or HSI_VALUE/HSIDIV) / PLLM * (PLLN + FRACN) + SYSCLK = PLL_VCO / PLLP + */ + pllsource = LL_RCC_PLL3_GetSource(); + + switch (pllsource) + { + case LL_RCC_PLL3SOURCE_HSI: + if (LL_RCC_HSI_IsReady() != 0U) + { + pllinputfreq = HSI_VALUE >> (LL_RCC_HSI_GetDivider() >> RCC_CR_HSIDIV_Pos); + } + break; + + case LL_RCC_PLL3SOURCE_CSI: + if (LL_RCC_CSI_IsReady() != 0U) + { + pllinputfreq = CSI_VALUE; + } + break; + + case LL_RCC_PLL3SOURCE_HSE: + if (LL_RCC_HSE_IsReady() != 0U) + { + pllinputfreq = HSE_VALUE; + } + break; + + case LL_RCC_PLL3SOURCE_NONE: + default: + /* PLL clock disabled */ + break; + } + + pPLL_Clocks->PLL_P_Frequency = 0U; + pPLL_Clocks->PLL_Q_Frequency = 0U; + pPLL_Clocks->PLL_R_Frequency = 0U; + + pllm = LL_RCC_PLL3_GetM(); + plln = LL_RCC_PLL3_GetN(); + if (LL_RCC_PLL3FRACN_IsEnabled() != 0U) + { + fracn = LL_RCC_PLL3_GetFRACN(); + } + + if ((pllm != 0U) && (pllinputfreq != 0U)) + { + if (LL_RCC_PLL3P_IsEnabled() != 0U) + { + pPLL_Clocks->PLL_P_Frequency = LL_RCC_CalcPLLClockFreq(pllinputfreq, pllm, plln, fracn, LL_RCC_PLL3_GetP()); + } + + if (LL_RCC_PLL3Q_IsEnabled() != 0U) + { + pPLL_Clocks->PLL_Q_Frequency = LL_RCC_CalcPLLClockFreq(pllinputfreq, pllm, plln, fracn, LL_RCC_PLL3_GetQ()); + } + + if (LL_RCC_PLL3R_IsEnabled() != 0U) + { + pPLL_Clocks->PLL_R_Frequency = LL_RCC_CalcPLLClockFreq(pllinputfreq, pllm, plln, fracn, LL_RCC_PLL3_GetR()); + } + } +} +#endif /* PLL3 */ + +/** + * @brief Helper function to calculate the PLL1 frequency output + * @note ex: @ref LL_RCC_CalcPLLClockFreq (HSE_VALUE, @ref LL_RCC_PLL1_GetM (), + * @ref LL_RCC_PLL1_GetN (), @ref LL_RCC_PLL1_GetFRACN (), @ref LL_RCC_PLL1_GetP ()); + * @param PLLInputFreq PLL Input frequency (based on HSE/(HSI/HSIDIV)/CSI) + * @param M Between 1 and 63 + * @param N Between 4 and 512 + * @param FRACN Between 0 and 0x1FFF + * @param PQR VCO output divider (P, Q or R) + * Between 1 and 128, except for PLL1P Odd value not allowed + * @retval PLL1 output clock frequency (in Hz) + */ +uint32_t LL_RCC_CalcPLLClockFreq(uint32_t PLLInputFreq, uint32_t M, uint32_t N, uint32_t FRACN, uint32_t PQR) +{ + float_t freq; + + freq = ((float_t)PLLInputFreq / (float_t)M) * ((float_t)N + ((float_t)FRACN / (float_t)0x2000)); + + freq = freq / (float_t)PQR; + + return (uint32_t)freq; +} + + +/** + * @brief Return USARTx clock frequency + * @param USARTxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_USART1_CLKSOURCE + * @arg @ref LL_RCC_USART2_CLKSOURCE + * @arg @ref LL_RCC_USART3_CLKSOURCE + * @arg @ref LL_RCC_USART6_CLKSOURCE (*) + * @arg @ref LL_RCC_USART10_CLKSOURCE (*) + * @arg @ref LL_RCC_USART11_CLKSOURCE (*) + * + * (*) : For stm32h56xxx and stm32h57xxx family lines only. + * @retval USART clock frequency (in Hz) + * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator or PLL is not ready + */ +uint32_t LL_RCC_GetUSARTClockFreq(uint32_t USARTxSource) +{ + uint32_t usart_frequency = LL_RCC_PERIPH_FREQUENCY_NO; + LL_PLL_ClocksTypeDef PLL_Clocks; + + /* Check parameter */ + assert_param(IS_LL_RCC_USART_CLKSOURCE(USARTxSource)); + + if (USARTxSource == LL_RCC_USART1_CLKSOURCE) + { + /* USART1CLK clock frequency */ + switch (LL_RCC_GetUSARTClockSource(USARTxSource)) + { + case LL_RCC_USART1_CLKSOURCE_PCLK2: /* USART1 Clock is PCLK2 */ + usart_frequency = RCC_GetPCLK2ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); + break; + + case LL_RCC_USART1_CLKSOURCE_PLL2Q: /* USART1 Clock is PLL2 Q */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + usart_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + +#if defined(LL_RCC_USART1_CLKSOURCE_PLL3Q) + case LL_RCC_USART1_CLKSOURCE_PLL3Q: /* USART1 Clock is PLL3 Q */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + usart_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; +#endif /* LL_RCC_USART1_CLKSOURCE_PLL3 */ + + case LL_RCC_USART1_CLKSOURCE_HSI: /* USART1 Clock is HSI Osc. */ + if (LL_RCC_HSI_IsReady() == 1U) + { + usart_frequency = HSI_VALUE; + } + break; + + case LL_RCC_USART1_CLKSOURCE_CSI: /* USART1 Clock is CSI Osc. */ + if (LL_RCC_CSI_IsReady() == 1U) + { + usart_frequency = CSI_VALUE; + } + break; + + case LL_RCC_USART1_CLKSOURCE_LSE: /* USART1 Clock is LSE Osc. */ + if (LL_RCC_LSE_IsReady() == 1U) + { + usart_frequency = LSE_VALUE; + } + break; + + default: + /* unreachable code */ + break; + } + } + else if (USARTxSource == LL_RCC_USART2_CLKSOURCE) + { + /* USART2CLK clock frequency */ + switch (LL_RCC_GetUSARTClockSource(USARTxSource)) + { + case LL_RCC_USART2_CLKSOURCE_PCLK1: /* USART2 Clock is PCLK1 */ + usart_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); + break; + + case LL_RCC_USART2_CLKSOURCE_PLL2Q: /* USART2 Clock is PLL2 Q */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + usart_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + +#if defined(LL_RCC_USART2_CLKSOURCE_PLL3Q) + case LL_RCC_USART2_CLKSOURCE_PLL3Q: /* USART2 Clock is PLL3 Q */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + usart_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; +#endif /* LL_RCC_USART2_CLKSOURCE_PLL3 */ + + case LL_RCC_USART2_CLKSOURCE_HSI: /* USART2 Clock is HSI Osc. */ + if (LL_RCC_HSI_IsReady() == 1U) + { + usart_frequency = HSI_VALUE; + } + break; + + case LL_RCC_USART2_CLKSOURCE_CSI: /* USART2 Clock is CSI Osc. */ + if (LL_RCC_CSI_IsReady() == 1U) + { + usart_frequency = CSI_VALUE; + } + break; + + case LL_RCC_USART2_CLKSOURCE_LSE: /* USART2 Clock is LSE Osc. */ + if (LL_RCC_LSE_IsReady() == 1U) + { + usart_frequency = LSE_VALUE; + } + break; + + default: + /* unreachable code */ + break; + } + } + else if (USARTxSource == LL_RCC_USART3_CLKSOURCE) + { + /* USART3CLK clock frequency */ + switch (LL_RCC_GetUSARTClockSource(USARTxSource)) + { + case LL_RCC_USART3_CLKSOURCE_PCLK1: /* USART3 Clock is PCLK1 */ + usart_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); + break; + + case LL_RCC_USART3_CLKSOURCE_PLL2Q: /* USART3 Clock is PLL2 Q */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + usart_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + +#if defined(LL_RCC_USART3_CLKSOURCE_PLL3Q) + case LL_RCC_USART3_CLKSOURCE_PLL3Q: /* USART3 Clock is PLL3 Q */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + usart_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; +#endif /* LL_RCC_USART3_CLKSOURCE_PLL3 */ + + case LL_RCC_USART3_CLKSOURCE_HSI: /* USART3 Clock is HSI Osc. */ + if (LL_RCC_HSI_IsReady() == 1U) + { + usart_frequency = HSI_VALUE; + } + break; + + case LL_RCC_USART3_CLKSOURCE_CSI: /* USART3 Clock is CSI Osc. */ + if (LL_RCC_CSI_IsReady() == 1U) + { + usart_frequency = CSI_VALUE; + } + break; + + case LL_RCC_USART3_CLKSOURCE_LSE: /* USART3 Clock is LSE Osc. */ + if (LL_RCC_LSE_IsReady() == 1U) + { + usart_frequency = LSE_VALUE; + } + break; + + default: + /* unreachable code */ + break; + } + } + +#if defined(USART6) + else if (USARTxSource == LL_RCC_USART6_CLKSOURCE) + { + /* USART6CLK clock frequency */ + switch (LL_RCC_GetUSARTClockSource(USARTxSource)) + { + case LL_RCC_USART6_CLKSOURCE_PCLK1: /* USART6 Clock is PCLK1 */ + usart_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); + break; + + case LL_RCC_USART6_CLKSOURCE_PLL2Q: /* USART6 Clock is PLL2 Q */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + usart_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_USART6_CLKSOURCE_PLL3Q: /* USART6 Clock is PLL3 Q */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + usart_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_USART6_CLKSOURCE_HSI: /* USART6 Clock is HSI Osc. */ + if (LL_RCC_HSI_IsReady() == 1U) + { + usart_frequency = HSI_VALUE; + } + break; + + case LL_RCC_USART6_CLKSOURCE_CSI: /* USART6 Clock is CSI Osc. */ + if (LL_RCC_CSI_IsReady() == 1U) + { + usart_frequency = CSI_VALUE; + } + break; + + case LL_RCC_USART6_CLKSOURCE_LSE: /* USART6 Clock is LSE Osc. */ + if (LL_RCC_LSE_IsReady() == 1U) + { + usart_frequency = LSE_VALUE; + } + break; + + default: + /* unreachable code */ + break; + } + } +#endif /* USART6 */ + +#if defined(USART10) + else if (USARTxSource == LL_RCC_USART10_CLKSOURCE) + { + /* USART10CLK clock frequency */ + switch (LL_RCC_GetUSARTClockSource(USARTxSource)) + { + case LL_RCC_USART10_CLKSOURCE_PCLK1: /* USART10 Clock is PCLK1 */ + usart_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); + break; + + case LL_RCC_USART10_CLKSOURCE_PLL2Q: /* USART10 Clock is PLL2 Q */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + usart_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_USART10_CLKSOURCE_PLL3Q: /* USART10 Clock is PLL3 Q */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + usart_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_USART10_CLKSOURCE_HSI: /* USART10 Clock is HSI Osc. */ + if (LL_RCC_HSI_IsReady() == 1U) + { + usart_frequency = HSI_VALUE; + } + break; + + case LL_RCC_USART10_CLKSOURCE_CSI: /* USART10 Clock is CSI Osc. */ + if (LL_RCC_CSI_IsReady() == 1U) + { + usart_frequency = CSI_VALUE; + } + break; + + case LL_RCC_USART10_CLKSOURCE_LSE: /* USART10 Clock is LSE Osc. */ + if (LL_RCC_LSE_IsReady() == 1U) + { + usart_frequency = LSE_VALUE; + } + break; + + default: + /* unreachable code */ + break; + } + } +#endif /* USART10 */ + +#if defined(USART11) + else if (USARTxSource == LL_RCC_USART11_CLKSOURCE) + { + /* USART11CLK clock frequency */ + switch (LL_RCC_GetUSARTClockSource(USARTxSource)) + { + case LL_RCC_USART11_CLKSOURCE_PCLK1: /* USART11 Clock is PCLK1 */ + usart_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); + break; + + case LL_RCC_USART11_CLKSOURCE_PLL2Q: /* USART11 Clock is PLL2 Q */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + usart_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_USART11_CLKSOURCE_PLL3Q: /* USART11 Clock is PLL3 Q */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + usart_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_USART11_CLKSOURCE_HSI: /* USART11 Clock is HSI Osc. */ + if (LL_RCC_HSI_IsReady() == 1U) + { + usart_frequency = HSI_VALUE; + } + break; + + case LL_RCC_USART11_CLKSOURCE_CSI: /* USART11 Clock is CSI Osc. */ + if (LL_RCC_CSI_IsReady() == 1U) + { + usart_frequency = CSI_VALUE; + } + break; + + case LL_RCC_USART11_CLKSOURCE_LSE: /* USART11 Clock is LSE Osc. */ + if (LL_RCC_LSE_IsReady() == 1U) + { + usart_frequency = LSE_VALUE; + } + break; + + default: + /* unreachable code */ + break; + } + } +#endif /* USART11 */ + else + { + /* nothing to do */ + } + + return usart_frequency; +} + +#if defined(UART4) +/** + * @brief Return UARTx clock frequency + * @param UARTxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_UART4_CLKSOURCE + * @arg @ref LL_RCC_UART5_CLKSOURCE + * @arg @ref LL_RCC_UART7_CLKSOURCE + * @arg @ref LL_RCC_UART8_CLKSOURCE + * @arg @ref LL_RCC_UART9_CLKSOURCE + * @arg @ref LL_RCC_UART12_CLKSOURCE + * @retval UART clock frequency (in Hz) + * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator or PLL is not ready + */ +uint32_t LL_RCC_GetUARTClockFreq(uint32_t UARTxSource) +{ + uint32_t uart_frequency = LL_RCC_PERIPH_FREQUENCY_NO; + LL_PLL_ClocksTypeDef PLL_Clocks; + + /* Check parameter */ + assert_param(IS_LL_RCC_UART_CLKSOURCE(UARTxSource)); + + if (UARTxSource == LL_RCC_UART4_CLKSOURCE) + { + /* UART4CLK clock frequency */ + switch (LL_RCC_GetUARTClockSource(UARTxSource)) + { + case LL_RCC_UART4_CLKSOURCE_PCLK1: /* UART4 Clock is PCLK1 */ + uart_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); + break; + + case LL_RCC_UART4_CLKSOURCE_PLL2Q: /* UART4 Clock is PLL2 Q */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + uart_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_UART4_CLKSOURCE_PLL3Q: /* UART4 Clock is PLL3 Q */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + uart_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_UART4_CLKSOURCE_HSI: /* UART4 Clock is HSI Osc. */ + if (LL_RCC_HSI_IsReady() == 1U) + { + uart_frequency = HSI_VALUE; + } + break; + + case LL_RCC_UART4_CLKSOURCE_CSI: /* UART4 Clock is CSI Osc. */ + if (LL_RCC_CSI_IsReady() == 1U) + { + uart_frequency = CSI_VALUE; + } + break; + + case LL_RCC_UART4_CLKSOURCE_LSE: /* UART4 Clock is LSE Osc. */ + if (LL_RCC_LSE_IsReady() == 1U) + { + uart_frequency = LSE_VALUE; + } + break; + + default: + /* unreachable code */ + break; + } + } + else if (UARTxSource == LL_RCC_UART5_CLKSOURCE) + { + /* UART5CLK clock frequency */ + switch (LL_RCC_GetUARTClockSource(UARTxSource)) + { + case LL_RCC_UART5_CLKSOURCE_PCLK1: /* UART5 Clock is PCLK1 */ + uart_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); + break; + + case LL_RCC_UART5_CLKSOURCE_PLL2Q: /* UART5 Clock is PLL2 Q */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + uart_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_UART5_CLKSOURCE_PLL3Q: /* UART5 Clock is PLL3 Q */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + uart_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_UART5_CLKSOURCE_HSI: /* UART5 Clock is HSI Osc. */ + if (LL_RCC_HSI_IsReady() == 1U) + { + uart_frequency = HSI_VALUE; + } + break; + + case LL_RCC_UART5_CLKSOURCE_CSI: /* UART5 Clock is CSI Osc. */ + if (LL_RCC_CSI_IsReady() == 1U) + { + uart_frequency = CSI_VALUE; + } + break; + + case LL_RCC_UART5_CLKSOURCE_LSE: /* UART5 Clock is LSE Osc. */ + if (LL_RCC_LSE_IsReady() == 1U) + { + uart_frequency = LSE_VALUE; + } + break; + + default: + /* unreachable code */ + break; + } + } + else if (UARTxSource == LL_RCC_UART7_CLKSOURCE) + { + /* UART7CLK clock frequency */ + switch (LL_RCC_GetUARTClockSource(UARTxSource)) + { + case LL_RCC_UART7_CLKSOURCE_PCLK1: /* UART7 Clock is PCLK1 */ + uart_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); + break; + + case LL_RCC_UART7_CLKSOURCE_PLL2Q: /* UART7 Clock is PLL2 Q */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + uart_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_UART7_CLKSOURCE_PLL3Q: /* UART7 Clock is PLL3 Q */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + uart_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_UART7_CLKSOURCE_HSI: /* UART7 Clock is HSI Osc. */ + if (LL_RCC_HSI_IsReady() == 1U) + { + uart_frequency = HSI_VALUE; + } + break; + + case LL_RCC_UART7_CLKSOURCE_CSI: /* UART7 Clock is CSI Osc. */ + if (LL_RCC_CSI_IsReady() == 1U) + { + uart_frequency = CSI_VALUE; + } + break; + + case LL_RCC_UART7_CLKSOURCE_LSE: /* UART7 Clock is LSE Osc. */ + if (LL_RCC_LSE_IsReady() == 1U) + { + uart_frequency = LSE_VALUE; + } + break; + + default: + /* unreachable code */ + break; + } + } + else if (UARTxSource == LL_RCC_UART8_CLKSOURCE) + { + /* UART8CLK clock frequency */ + switch (LL_RCC_GetUARTClockSource(UARTxSource)) + { + case LL_RCC_UART8_CLKSOURCE_PCLK1: /* UART8 Clock is PCLK1 */ + uart_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); + break; + + case LL_RCC_UART8_CLKSOURCE_PLL2Q: /* UART8 Clock is PLL2 Q */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + uart_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_UART8_CLKSOURCE_PLL3Q: /* UART8 Clock is PLL3 Q */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + uart_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_UART8_CLKSOURCE_HSI: /* UART8 Clock is HSI Osc. */ + if (LL_RCC_HSI_IsReady() == 1U) + { + uart_frequency = HSI_VALUE; + } + break; + + case LL_RCC_UART8_CLKSOURCE_CSI: /* UART8 Clock is CSI Osc. */ + if (LL_RCC_CSI_IsReady() == 1U) + { + uart_frequency = CSI_VALUE; + } + break; + + case LL_RCC_UART8_CLKSOURCE_LSE: /* UART8 Clock is LSE Osc. */ + if (LL_RCC_LSE_IsReady() == 1U) + { + uart_frequency = LSE_VALUE; + } + break; + + default: + /* unreachable code */ + break; + } + } + else if (UARTxSource == LL_RCC_UART9_CLKSOURCE) + { + /* UART9CLK clock frequency */ + switch (LL_RCC_GetUARTClockSource(UARTxSource)) + { + case LL_RCC_UART9_CLKSOURCE_PCLK1: /* UART9 Clock is PCLK1 */ + uart_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); + break; + + case LL_RCC_UART9_CLKSOURCE_PLL2Q: /* UART9 Clock is PLL2 Q */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + uart_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_UART9_CLKSOURCE_PLL3Q: /* UART9 Clock is PLL3 Q */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + uart_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_UART9_CLKSOURCE_HSI: /* UART9 Clock is HSI Osc. */ + if (LL_RCC_HSI_IsReady() == 1U) + { + uart_frequency = HSI_VALUE; + } + break; + + case LL_RCC_UART9_CLKSOURCE_CSI: /* UART9 Clock is CSI Osc. */ + if (LL_RCC_CSI_IsReady() == 1U) + { + uart_frequency = CSI_VALUE; + } + break; + + case LL_RCC_UART9_CLKSOURCE_LSE: /* UART9 Clock is LSE Osc. */ + if (LL_RCC_LSE_IsReady() == 1U) + { + uart_frequency = LSE_VALUE; + } + break; + + default: + /* unreachable code */ + break; + } + } + else if (UARTxSource == LL_RCC_UART12_CLKSOURCE) + { + /* UART12CLK clock frequency */ + switch (LL_RCC_GetUARTClockSource(UARTxSource)) + { + case LL_RCC_UART12_CLKSOURCE_PCLK1: /* UART12 Clock is PCLK1 */ + uart_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); + break; + + case LL_RCC_UART12_CLKSOURCE_PLL2Q: /* UART12 Clock is PLL2 Q */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + uart_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_UART12_CLKSOURCE_PLL3Q: /* UART12 Clock is PLL3 Q */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + uart_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_UART12_CLKSOURCE_HSI: /* UART12 Clock is HSI Osc. */ + if (LL_RCC_HSI_IsReady() == 1U) + { + uart_frequency = HSI_VALUE; + } + break; + + case LL_RCC_UART12_CLKSOURCE_CSI: /* UART12 Clock is CSI Osc. */ + if (LL_RCC_CSI_IsReady() == 1U) + { + uart_frequency = CSI_VALUE; + } + break; + + case LL_RCC_UART12_CLKSOURCE_LSE: /* UART12 Clock is LSE Osc. */ + if (LL_RCC_LSE_IsReady() == 1U) + { + uart_frequency = LSE_VALUE; + } + break; + + default: + /* unreachable code */ + break; + } + } + else + { + /* nothing to do */ + } + + return uart_frequency; +} +#endif /* UART4 */ + +/** + * @brief Return SPIx clock frequency + * @param SPIxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_SPI1_CLKSOURCE + * @arg @ref LL_RCC_SPI2_CLKSOURCE + * @arg @ref LL_RCC_SPI3_CLKSOURCE + * @arg @ref LL_RCC_SPI4_CLKSOURCE (*) + * @arg @ref LL_RCC_SPI5_CLKSOURCE (*) + * @arg @ref LL_RCC_SPI6_CLKSOURCE (*) + * + * (*) : For stm32h56xxx and stm32h57xxx family lines only. + * @retval SPI clock frequency (in Hz) + * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator or PLL is not ready + */ +uint32_t LL_RCC_GetSPIClockFreq(uint32_t SPIxSource) +{ + uint32_t spi_frequency = LL_RCC_PERIPH_FREQUENCY_NO; + LL_PLL_ClocksTypeDef PLL_Clocks; + + /* Check parameter */ + assert_param(IS_LL_RCC_SPI_CLKSOURCE(SPIxSource)); + + if (SPIxSource == LL_RCC_SPI1_CLKSOURCE) + { + /* SPI1 CLK clock frequency */ + switch (LL_RCC_GetSPIClockSource(SPIxSource)) + { + case LL_RCC_SPI1_CLKSOURCE_PLL1Q: /* SPI1 Clock is PLL1 Q */ + if (LL_RCC_PLL1_IsReady() != 0U) + { + if (LL_RCC_PLL1Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL1ClockFreq(&PLL_Clocks); + spi_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_SPI1_CLKSOURCE_PLL2P: /* SPI1 Clock is PLL2 P */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2P_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + spi_frequency = PLL_Clocks.PLL_P_Frequency; + } + } + break; + +#if defined(LL_RCC_SPI1_CLKSOURCE_PLL3P) + case LL_RCC_SPI1_CLKSOURCE_PLL3P: /* SPI1 Clock is PLL3 P */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3P_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + spi_frequency = PLL_Clocks.PLL_P_Frequency; + } + } + break; +#endif /* PLL3 */ + + case LL_RCC_SPI1_CLKSOURCE_PIN: /* SPI1 Clock is External Clock */ + spi_frequency = EXTERNAL_CLOCK_VALUE; + break; + + case LL_RCC_SPI1_CLKSOURCE_CLKP: /* SPI1 Clock is CLKP */ + spi_frequency = LL_RCC_GetCLKPClockFreq(LL_RCC_GetCLKPClockSource(LL_RCC_CLKP_CLKSOURCE)); + break; + + default: + /* unreachable code */ + break; + } + } + else if (SPIxSource == LL_RCC_SPI2_CLKSOURCE) + { + /* SPI2 CLK clock frequency */ + switch (LL_RCC_GetSPIClockSource(SPIxSource)) + { + case LL_RCC_SPI2_CLKSOURCE_PLL1Q: /* SPI2 Clock is PLL1 Q */ + if (LL_RCC_PLL1_IsReady() != 0U) + { + if (LL_RCC_PLL1Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL1ClockFreq(&PLL_Clocks); + spi_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_SPI2_CLKSOURCE_PLL2P: /* SPI2 Clock is PLL2 P */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2P_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + spi_frequency = PLL_Clocks.PLL_P_Frequency; + } + } + break; + +#if defined(LL_RCC_SPI2_CLKSOURCE_PLL3P) + case LL_RCC_SPI2_CLKSOURCE_PLL3P: /* SPI2 Clock is PLL3 P */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3P_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + spi_frequency = PLL_Clocks.PLL_P_Frequency; + } + } + break; +#endif /* PLL3 */ + + case LL_RCC_SPI2_CLKSOURCE_PIN: /* SPI2 Clock is External Clock */ + spi_frequency = EXTERNAL_CLOCK_VALUE; + break; + + case LL_RCC_SPI2_CLKSOURCE_CLKP: /* SPI2 Clock is CLKP */ + spi_frequency = LL_RCC_GetCLKPClockFreq(LL_RCC_GetCLKPClockSource(LL_RCC_CLKP_CLKSOURCE)); + break; + + default: + /* unreachable code */ + break; + } + } + else if (SPIxSource == LL_RCC_SPI3_CLKSOURCE) + { + /* SPI3 CLK clock frequency */ + switch (LL_RCC_GetSPIClockSource(SPIxSource)) + { + case LL_RCC_SPI3_CLKSOURCE_PLL1Q: /* SPI3 Clock is PLL1 Q */ + if (LL_RCC_PLL1_IsReady() != 0U) + { + if (LL_RCC_PLL1Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL1ClockFreq(&PLL_Clocks); + spi_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_SPI3_CLKSOURCE_PLL2P: /* SPI3 Clock is PLL2 P*/ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2P_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + spi_frequency = PLL_Clocks.PLL_P_Frequency; + } + } + break; + +#if defined(LL_RCC_SPI3_CLKSOURCE_PLL3P) + case LL_RCC_SPI3_CLKSOURCE_PLL3P: /* SPI3 Clock is PLL3 P*/ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3P_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + spi_frequency = PLL_Clocks.PLL_P_Frequency; + } + } + break; +#endif /* PLL3 */ + case LL_RCC_SPI3_CLKSOURCE_PIN: /* SPI3 Clock is External Clock */ + spi_frequency = EXTERNAL_CLOCK_VALUE; + break; + + case LL_RCC_SPI3_CLKSOURCE_CLKP: /* SPI3 Clock is CLKP */ + spi_frequency = LL_RCC_GetCLKPClockFreq(LL_RCC_GetCLKPClockSource(LL_RCC_CLKP_CLKSOURCE)); + break; + + default: + /* unreachable code */ + break; + } + } +#if defined(SPI4) + else if (SPIxSource == LL_RCC_SPI4_CLKSOURCE) + { + /* SPI4 CLK clock frequency */ + switch (LL_RCC_GetSPIClockSource(SPIxSource)) + { + case LL_RCC_SPI4_CLKSOURCE_PCLK2: /* SPI4 Clock is PCLK2 */ + spi_frequency = RCC_GetPCLK2ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); + break; + + case LL_RCC_SPI4_CLKSOURCE_PLL2Q: /* SPI4 Clock is PLL2 Q*/ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + spi_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_SPI4_CLKSOURCE_PLL3Q: /* SPI4 Clock is PLL3 Q*/ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + spi_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_SPI4_CLKSOURCE_HSI: /* SPI4 Clock is HSI Osc. */ + if (LL_RCC_HSI_IsReady() == 1U) + { + spi_frequency = HSI_VALUE; + } + break; + + case LL_RCC_SPI4_CLKSOURCE_CSI: /* SPI4 Clock is CSI Osc. */ + if (LL_RCC_CSI_IsReady() == 1U) + { + spi_frequency = CSI_VALUE; + } + break; + + case LL_RCC_SPI4_CLKSOURCE_HSE: /* SPI4 Clock is HSE Osc. */ + if (LL_RCC_HSE_IsReady() == 1U) + { + spi_frequency = HSE_VALUE; + } + break; + + default: + /* unreachable code */ + break; + } + } +#endif /* SPI4 */ +#if defined(SPI5) + else if (SPIxSource == LL_RCC_SPI5_CLKSOURCE) + { + /* SPI5 CLK clock frequency */ + switch (LL_RCC_GetSPIClockSource(SPIxSource)) + { + case LL_RCC_SPI5_CLKSOURCE_PCLK3: /* SPI5 Clock is PCLK3 */ + spi_frequency = RCC_GetPCLK3ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); + break; + + case LL_RCC_SPI5_CLKSOURCE_PLL2Q: /* SPI5 Clock is PLL2 Q*/ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + spi_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_SPI5_CLKSOURCE_PLL3Q: /* SPI5 Clock is PLL3 Q*/ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + spi_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_SPI5_CLKSOURCE_HSI: /* SPI5 Clock is HSI Osc. */ + if (LL_RCC_HSI_IsReady() == 1U) + { + spi_frequency = HSI_VALUE; + } + break; + + case LL_RCC_SPI5_CLKSOURCE_CSI: /* SPI5 Clock is CSI Osc. */ + if (LL_RCC_CSI_IsReady() == 1U) + { + spi_frequency = CSI_VALUE; + } + break; + + case LL_RCC_SPI5_CLKSOURCE_HSE: /* SPI5 Clock is HSE Osc. */ + if (LL_RCC_HSE_IsReady() == 1U) + { + spi_frequency = HSE_VALUE; + } + break; + + default: + /* unreachable code */ + break; + } + } +#endif /* SPI5 */ +#if defined(SPI6) + else if (SPIxSource == LL_RCC_SPI6_CLKSOURCE) + { + /* SPI6 CLK clock frequency */ + switch (LL_RCC_GetSPIClockSource(SPIxSource)) + { + case LL_RCC_SPI6_CLKSOURCE_PCLK2: /* SPI6 Clock is PCLK2 */ + spi_frequency = RCC_GetPCLK2ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); + break; + + case LL_RCC_SPI6_CLKSOURCE_PLL2Q: /* SPI6 Clock is PLL2 Q*/ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + spi_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_SPI6_CLKSOURCE_PLL3Q: /* SPI6 Clock is PLL3 Q*/ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + spi_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_SPI6_CLKSOURCE_HSI: /* SPI6 Clock is HSI Osc. */ + if (LL_RCC_HSI_IsReady() == 1U) + { + spi_frequency = HSI_VALUE; + } + break; + + case LL_RCC_SPI6_CLKSOURCE_CSI: /* SPI6 Clock is CSI Osc. */ + if (LL_RCC_CSI_IsReady() == 1U) + { + spi_frequency = CSI_VALUE; + } + break; + + case LL_RCC_SPI6_CLKSOURCE_HSE: /* SPI6 Clock is HSE Osc. */ + if (LL_RCC_HSE_IsReady() == 1U) + { + spi_frequency = HSE_VALUE; + } + break; + + default: + /* unreachable code */ + break; + } + } +#endif /* SPI6 */ + + else + { + /* nothing to do */ + } + + return spi_frequency; +} + +/** + * @brief Return I2Cx clock frequency + * @param I2CxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_I2C1_CLKSOURCE + * @arg @ref LL_RCC_I2C2_CLKSOURCE + * @arg @ref LL_RCC_I2C3_CLKSOURCE (*) + * @arg @ref LL_RCC_I2C4_CLKSOURCE (*) + * + * (*) : For stm32h56xxx and stm32h57xxx family lines only. + * @retval I2C clock frequency (in Hz) + * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator or PLL is not ready + */ +uint32_t LL_RCC_GetI2CClockFreq(uint32_t I2CxSource) +{ + uint32_t i2c_frequency = LL_RCC_PERIPH_FREQUENCY_NO; + LL_PLL_ClocksTypeDef PLL_Clocks; + + /* Check parameter */ + assert_param(IS_LL_RCC_I2C_CLKSOURCE(I2CxSource)); + + if (I2CxSource == LL_RCC_I2C1_CLKSOURCE) + { + /* I2C1 CLK clock frequency */ + switch (LL_RCC_GetI2CClockSource(I2CxSource)) + { + case LL_RCC_I2C1_CLKSOURCE_PCLK1: /* I2C1 Clock is PCLK1 */ + i2c_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); + break; + +#if defined(LL_RCC_I2C1_CLKSOURCE_PLL3R) + case LL_RCC_I2C1_CLKSOURCE_PLL3R: /* I2C1 Clock is PLL3 R */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3R_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + i2c_frequency = PLL_Clocks.PLL_R_Frequency; + } + } + break; +#else + case LL_RCC_I2C1_CLKSOURCE_PLL2R: /* I2C1 Clock is PLL2 R */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2R_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + i2c_frequency = PLL_Clocks.PLL_R_Frequency; + } + } + break; +#endif /* PLL3 */ + + case LL_RCC_I2C1_CLKSOURCE_HSI: /* I2C1 Clock is HSI Osc. */ + if (LL_RCC_HSI_IsReady() == 1U) + { + i2c_frequency = HSI_VALUE; + } + break; + + case LL_RCC_I2C1_CLKSOURCE_CSI: /* I2C1 Clock is CSI Osc. */ + if (LL_RCC_CSI_IsReady() == 1U) + { + i2c_frequency = CSI_VALUE; + } + break; + + default: + /* unreachable code */ + break; + } + } + else if (I2CxSource == LL_RCC_I2C2_CLKSOURCE) + { + /* I2C2 CLK clock frequency */ + switch (LL_RCC_GetI2CClockSource(I2CxSource)) + { + case LL_RCC_I2C2_CLKSOURCE_PCLK1: /* I2C2 Clock is PCLK1 */ + i2c_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); + break; + +#if defined(LL_RCC_I2C2_CLKSOURCE_PLL3R) + case LL_RCC_I2C2_CLKSOURCE_PLL3R: /* I2C2 Clock is PLL3 R */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3R_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + i2c_frequency = PLL_Clocks.PLL_R_Frequency; + } + } + break; +#else + case LL_RCC_I2C2_CLKSOURCE_PLL2R: /* I2C2 Clock is PLL2 R */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2R_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + i2c_frequency = PLL_Clocks.PLL_R_Frequency; + } + } + break; +#endif /* PLL3 */ + + case LL_RCC_I2C2_CLKSOURCE_HSI: /* I2C2 Clock is HSI Osc. */ + if (LL_RCC_HSI_IsReady() == 1U) + { + i2c_frequency = HSI_VALUE; + } + break; + + case LL_RCC_I2C2_CLKSOURCE_CSI: /* I2C2 Clock is CSI Osc. */ + if (LL_RCC_CSI_IsReady() == 1U) + { + i2c_frequency = CSI_VALUE; + } + break; + + default: + /* unreachable code */ + break; + } + } +#if defined(I2C3) + else if (I2CxSource == LL_RCC_I2C3_CLKSOURCE) + { + /* I2C3 CLK clock frequency */ + switch (LL_RCC_GetI2CClockSource(I2CxSource)) + + { + case LL_RCC_I2C3_CLKSOURCE_PCLK3: /* I2C3 Clock is PCLK3 */ + i2c_frequency = RCC_GetPCLK3ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); + break; + + case LL_RCC_I2C3_CLKSOURCE_PLL3R: /* I2C3 Clock is PLL3 R */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3R_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + i2c_frequency = PLL_Clocks.PLL_R_Frequency; + } + } + break; + + case LL_RCC_I2C3_CLKSOURCE_HSI: /* I2C3 Clock is HSI Osc. */ + if (LL_RCC_HSI_IsReady() == 1U) + { + i2c_frequency = HSI_VALUE; + } + break; + + case LL_RCC_I2C3_CLKSOURCE_CSI: /* I2C3 Clock is CSI Osc. */ + if (LL_RCC_CSI_IsReady() == 1U) + { + i2c_frequency = CSI_VALUE; + } + break; + + default: + /* unreachable code */ + break; + } + } +#endif /* I2C3 */ +#if defined(I2C4) + else if (I2CxSource == LL_RCC_I2C4_CLKSOURCE) + { + /* I2C4 CLK clock frequency */ + switch (LL_RCC_GetI2CClockSource(I2CxSource)) + { + case LL_RCC_I2C4_CLKSOURCE_PCLK3: /* I2C4 Clock is PCLK3 */ + i2c_frequency = RCC_GetPCLK3ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); + break; + + case LL_RCC_I2C4_CLKSOURCE_PLL3R: /* I2C4 Clock is PLL3 R */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3R_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + i2c_frequency = PLL_Clocks.PLL_R_Frequency; + } + } + break; + + case LL_RCC_I2C4_CLKSOURCE_HSI: /* I2C4 Clock is HSI Osc. */ + if (LL_RCC_HSI_IsReady() == 1U) + { + i2c_frequency = HSI_VALUE; + } + break; + + case LL_RCC_I2C4_CLKSOURCE_CSI: /* I2C4 Clock is CSI Osc. */ + if (LL_RCC_CSI_IsReady() == 1U) + { + i2c_frequency = CSI_VALUE; + } + break; + + default: + /* unreachable code */ + break; + } + } +#endif /* I2C4 */ + else + { + /* nothing to do */ + } + + return i2c_frequency; +} + +/** + * @brief Return I3Cx clock frequency + * @param I3CxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_I3C1_CLKSOURCE + * @arg @ref LL_RCC_I3C2_CLKSOURCE (*) + * + * (*) : For stm32h503xx family line only. + * @retval I3C clock frequency (in Hz) + * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator or PLL is not ready or no clock is selected + */ +uint32_t LL_RCC_GetI3CClockFreq(uint32_t I3CxSource) +{ + uint32_t I3C_frequency = LL_RCC_PERIPH_FREQUENCY_NO; + LL_PLL_ClocksTypeDef PLL_Clocks; + + /* Check parameter */ + assert_param(IS_LL_RCC_I3C_CLKSOURCE(I3CxSource)); + + + if (I3CxSource == LL_RCC_I3C1_CLKSOURCE) + { + /* I3C1 CLK clock frequency */ + switch (LL_RCC_GetI3CClockSource(I3CxSource)) + { + case LL_RCC_I3C1_CLKSOURCE_PCLK1: /* I3C1 Clock is PCLK1 */ + I3C_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); + break; + +#if defined(LL_RCC_I3C1_CLKSOURCE_PLL3R) + case LL_RCC_I3C1_CLKSOURCE_PLL3R: /* I3C1 Clock is PLL3 R */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3R_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + I3C_frequency = PLL_Clocks.PLL_R_Frequency; + } + } + break; +#else + case LL_RCC_I3C1_CLKSOURCE_PLL2R: /* I3C1 Clock is PLL2 R */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2R_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + I3C_frequency = PLL_Clocks.PLL_R_Frequency; + } + } + break; +#endif /* LL_RCC_I3C1_CLKSOURCE_PLL3R */ + + case LL_RCC_I3C1_CLKSOURCE_HSI: /* I3C1 Clock is HSI Osc. */ + if (LL_RCC_HSI_IsReady() == 1U) + { + I3C_frequency = HSI_VALUE; + } + break; + + case LL_RCC_I3C1_CLKSOURCE_NONE: /* No Clock used for I3C1 */ + break; + + default: + /* unreachable code */ + break; + } + + } + +#if defined (I3C2) + else if (I3CxSource == LL_RCC_I3C2_CLKSOURCE) + { + /* I3C2 CLK clock frequency */ + switch (LL_RCC_GetI3CClockSource(I3CxSource)) + { + case LL_RCC_I3C2_CLKSOURCE_PCLK3: /* I3C2 Clock is PCLK3 */ + I3C_frequency = RCC_GetPCLK3ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); + break; + + case LL_RCC_I3C2_CLKSOURCE_PLL2R: /* I3C2 Clock is PLL2 R */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2R_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + I3C_frequency = PLL_Clocks.PLL_R_Frequency; + } + } + break; + + case LL_RCC_I3C2_CLKSOURCE_HSI: /* I3C2 Clock is HSI Osc. */ + if (LL_RCC_HSI_IsReady() == 1U) + { + I3C_frequency = HSI_VALUE; + } + break; + + case LL_RCC_I3C2_CLKSOURCE_NONE: /* No Clock used for I3C2 */ + break; + + default: + /* unreachable code */ + break; + } + } +#endif /* I3C2 */ + else + { + /* nothing to do */ + } + + return I3C_frequency; +} + +/** + * @brief Return LPUARTx clock frequency + * @param LPUARTxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_LPUART1_CLKSOURCE + * @retval LPUART clock frequency (in Hz) + * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator or PLL is not ready + */ +uint32_t LL_RCC_GetLPUARTClockFreq(uint32_t LPUARTxSource) +{ + uint32_t lpuart_frequency = LL_RCC_PERIPH_FREQUENCY_NO; + LL_PLL_ClocksTypeDef PLL_Clocks; + + /* Check parameter */ + assert_param(IS_LL_RCC_LPUART_CLKSOURCE(LPUARTxSource)); + + /* LPUART1CLK clock frequency */ + switch (LL_RCC_GetLPUARTClockSource(LPUARTxSource)) + { + case LL_RCC_LPUART1_CLKSOURCE_PCLK3: /* LPUART1 Clock is is PCLK3 */ + lpuart_frequency = RCC_GetPCLK3ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); + break; + + case LL_RCC_LPUART1_CLKSOURCE_PLL2Q: /* LPUART1 Clock is PLL2 Q */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + lpuart_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + +#if defined(LL_RCC_LPUART1_CLKSOURCE_PLL3Q) + case LL_RCC_LPUART1_CLKSOURCE_PLL3Q: /* LPUART1 Clock is PLL3 Q */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + lpuart_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; +#endif /* PLL3 */ + + case LL_RCC_LPUART1_CLKSOURCE_HSI: /* LPUART1 Clock is HSI Osc. */ + if (LL_RCC_HSI_IsReady() == 1U) + { + lpuart_frequency = HSI_VALUE; + } + break; + + case LL_RCC_LPUART1_CLKSOURCE_CSI: /* LPUART1 Clock is CSI Osc. */ + if (LL_RCC_CSI_IsReady() == 1U) + { + lpuart_frequency = CSI_VALUE; + } + break; + + case LL_RCC_LPUART1_CLKSOURCE_LSE: /* LPUART1 Clock is LSE Osc. */ + if (LL_RCC_LSE_IsReady() == 1U) + { + lpuart_frequency = LSE_VALUE; + } + break; + + default: + /* unreachable code */ + break; + } + + return lpuart_frequency; +} + +/** + * @brief Return LPTIMx clock frequency + * @param LPTIMxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_LPTIM1_CLKSOURCE + * @arg @ref LL_RCC_LPTIM2_CLKSOURCE + * @arg @ref LL_RCC_LPTIM3_CLKSOURCE (*) + * @arg @ref LL_RCC_LPTIM4_CLKSOURCE (*) + * @arg @ref LL_RCC_LPTIM5_CLKSOURCE (*) + * @arg @ref LL_RCC_LPTIM6_CLKSOURCE (*) + * + * (*) : For stm32h56xxx and stm32h57xxx family lines only. + * @retval LPTIM clock frequency (in Hz) + * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator or PLL is not ready + */ +uint32_t LL_RCC_GetLPTIMClockFreq(uint32_t LPTIMxSource) +{ + uint32_t lptim_frequency = LL_RCC_PERIPH_FREQUENCY_NO; + LL_PLL_ClocksTypeDef PLL_Clocks; + + /* Check parameter */ + assert_param(IS_LL_RCC_LPTIM_CLKSOURCE(LPTIMxSource)); + + if (LPTIMxSource == LL_RCC_LPTIM1_CLKSOURCE) + { + /* LPTIM1CLK clock frequency */ + switch (LL_RCC_GetLPTIMClockSource(LPTIMxSource)) + { + case LL_RCC_LPTIM1_CLKSOURCE_PCLK3: /* LPTIM1 Clock is is PCLK3 */ + lptim_frequency = RCC_GetPCLK3ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); + break; + + case LL_RCC_LPTIM1_CLKSOURCE_PLL2P: /* LPTIM1 Clock is PLL2 P */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2P_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + lptim_frequency = PLL_Clocks.PLL_P_Frequency; + } + } + break; + +#if defined(LL_RCC_LPTIM1_CLKSOURCE_PLL3R) + case LL_RCC_LPTIM1_CLKSOURCE_PLL3R: /* LPTIM1 Clock is PLL3 R */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3R_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + lptim_frequency = PLL_Clocks.PLL_R_Frequency; + } + } + break; +#endif /* PLL3 */ + + case LL_RCC_LPTIM1_CLKSOURCE_LSE: /* LPTIM1 Clock is LSE Osc. */ + if (LL_RCC_LSE_IsReady() == 1U) + { + lptim_frequency = LSE_VALUE; + } + break; + + case LL_RCC_LPTIM1_CLKSOURCE_LSI: /* LPTIM1 Clock is LSI Osc. */ + if (LL_RCC_LSI_IsReady() == 1U) + { + lptim_frequency = LSI_VALUE; + } + break; + + case LL_RCC_LPTIM1_CLKSOURCE_CLKP: /* LPTIM1 Clock is CLKP */ + lptim_frequency = LL_RCC_GetCLKPClockFreq(LL_RCC_GetCLKPClockSource(LL_RCC_CLKP_CLKSOURCE)); + break; + + default: + /* unreachable code */ + break; + } + } + else if (LPTIMxSource == LL_RCC_LPTIM2_CLKSOURCE) + { + /* LPTIM2CLK clock frequency */ + switch (LL_RCC_GetLPTIMClockSource(LPTIMxSource)) + { + case LL_RCC_LPTIM2_CLKSOURCE_PCLK1: /* LPTIM2 Clock is is PCLK1 */ + lptim_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); + break; + + case LL_RCC_LPTIM2_CLKSOURCE_PLL2P: /* LPTIM2 Clock is PLL2 P */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2P_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + lptim_frequency = PLL_Clocks.PLL_P_Frequency; + } + } + break; + +#if defined(LL_RCC_LPTIM2_CLKSOURCE_PLL3R) + case LL_RCC_LPTIM2_CLKSOURCE_PLL3R: /* LPTIM2 Clock is PLL3 R */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3R_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + lptim_frequency = PLL_Clocks.PLL_R_Frequency; + } + } + break; +#endif /* PLL3 */ + + case LL_RCC_LPTIM2_CLKSOURCE_LSE: /* LPTIM2 Clock is LSE Osc. */ + if (LL_RCC_LSE_IsReady() == 1U) + { + lptim_frequency = LSE_VALUE; + } + break; + + case LL_RCC_LPTIM2_CLKSOURCE_LSI: /* LPTIM2 Clock is LSI Osc. */ + if (LL_RCC_LSI_IsReady() == 1U) + { + lptim_frequency = LSI_VALUE; + } + break; + + case LL_RCC_LPTIM2_CLKSOURCE_CLKP: /* LPTIM2 Clock is CLKP */ + lptim_frequency = LL_RCC_GetCLKPClockFreq(LL_RCC_GetCLKPClockSource(LL_RCC_CLKP_CLKSOURCE)); + break; + + default: + /* unreachable code */ + break; + } + } +#if defined(LPTIM3) + else if (LPTIMxSource == LL_RCC_LPTIM3_CLKSOURCE) + { + /* LPTIM3CLK clock frequency */ + switch (LL_RCC_GetLPTIMClockSource(LPTIMxSource)) + { + case LL_RCC_LPTIM3_CLKSOURCE_PCLK3: /* LPTIM3 Clock is is PCLK3 */ + lptim_frequency = RCC_GetPCLK3ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); + break; + + case LL_RCC_LPTIM3_CLKSOURCE_PLL2P: /* LPTIM3 Clock is PLL2 P */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2P_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + lptim_frequency = PLL_Clocks.PLL_P_Frequency; + } + } + break; + + case LL_RCC_LPTIM3_CLKSOURCE_PLL3R: /* LPTIM3 Clock is PLL3 R */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3R_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + lptim_frequency = PLL_Clocks.PLL_R_Frequency; + } + } + break; + + case LL_RCC_LPTIM3_CLKSOURCE_LSE: /* LPTIM3 Clock is LSE Osc. */ + if (LL_RCC_LSE_IsReady() == 1U) + { + lptim_frequency = LSE_VALUE; + } + break; + + case LL_RCC_LPTIM3_CLKSOURCE_LSI: /* LPTIM3 Clock is LSI Osc. */ + if (LL_RCC_LSI_IsReady() == 1U) + { + lptim_frequency = LSI_VALUE; + } + break; + + case LL_RCC_LPTIM3_CLKSOURCE_CLKP: /* LPTIM3 Clock is CLKP */ + lptim_frequency = LL_RCC_GetCLKPClockFreq(LL_RCC_GetCLKPClockSource(LL_RCC_CLKP_CLKSOURCE)); + break; + + default: + /* unreachable code */ + break; + } + } +#endif /* LPTIM3 */ +#if defined(LPTIM4) + else if (LPTIMxSource == LL_RCC_LPTIM4_CLKSOURCE) + { + /* LPTIM4CLK clock frequency */ + switch (LL_RCC_GetLPTIMClockSource(LPTIMxSource)) + { + case LL_RCC_LPTIM4_CLKSOURCE_PCLK3: /* LPTIM4 Clock is is PCLK3 */ + lptim_frequency = RCC_GetPCLK3ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); + break; + + case LL_RCC_LPTIM4_CLKSOURCE_PLL2P: /* LPTIM4 Clock is PLL2 P */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2P_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + lptim_frequency = PLL_Clocks.PLL_P_Frequency; + } + } + break; + + case LL_RCC_LPTIM4_CLKSOURCE_PLL3R: /* LPTIM4 Clock is PLL3 R */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3R_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + lptim_frequency = PLL_Clocks.PLL_R_Frequency; + } + } + break; + + case LL_RCC_LPTIM4_CLKSOURCE_LSE: /* LPTIM4 Clock is LSE Osc. */ + if (LL_RCC_LSE_IsReady() == 1U) + { + lptim_frequency = LSE_VALUE; + } + break; + + case LL_RCC_LPTIM4_CLKSOURCE_LSI: /* LPTIM4 Clock is LSI Osc. */ + if (LL_RCC_LSI_IsReady() == 1U) + { + lptim_frequency = LSI_VALUE; + } + break; + + case LL_RCC_LPTIM4_CLKSOURCE_CLKP: /* LPTIM4 Clock is CLKP */ + lptim_frequency = LL_RCC_GetCLKPClockFreq(LL_RCC_GetCLKPClockSource(LL_RCC_CLKP_CLKSOURCE)); + break; + + default: + /* unreachable code */ + break; + } + } +#endif /* LPTIM4 */ +#if defined(LPTIM5) + else if (LPTIMxSource == LL_RCC_LPTIM5_CLKSOURCE) + { + /* LPTIM5CLK clock frequency */ + switch (LL_RCC_GetLPTIMClockSource(LPTIMxSource)) + { + case LL_RCC_LPTIM5_CLKSOURCE_PCLK3: /* LPTIM5 Clock is is PCLK3 */ + lptim_frequency = RCC_GetPCLK3ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); + break; + + case LL_RCC_LPTIM5_CLKSOURCE_PLL2P: /* LPTIM5 Clock is PLL2 P */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2P_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + lptim_frequency = PLL_Clocks.PLL_P_Frequency; + } + } + break; + + case LL_RCC_LPTIM5_CLKSOURCE_PLL3R: /* LPTIM5 Clock is PLL3 R */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3R_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + lptim_frequency = PLL_Clocks.PLL_R_Frequency; + } + } + break; + + case LL_RCC_LPTIM5_CLKSOURCE_LSE: /* LPTIM5 Clock is LSE Osc. */ + if (LL_RCC_LSE_IsReady() == 1U) + { + lptim_frequency = LSE_VALUE; + } + break; + + case LL_RCC_LPTIM5_CLKSOURCE_LSI: /* LPTIM5 Clock is LSI Osc. */ + if (LL_RCC_LSI_IsReady() == 1U) + { + lptim_frequency = LSI_VALUE; + } + break; + + case LL_RCC_LPTIM5_CLKSOURCE_CLKP: /* LPTIM5 Clock is CLKP */ + lptim_frequency = LL_RCC_GetCLKPClockFreq(LL_RCC_GetCLKPClockSource(LL_RCC_CLKP_CLKSOURCE)); + break; + + default: + /* unreachable code */ + break; + } + } +#endif /* LPTIM5 */ +#if defined(LPTIM6) + else if (LPTIMxSource == LL_RCC_LPTIM6_CLKSOURCE) + { + /* LPTIM6CLK clock frequency */ + switch (LL_RCC_GetLPTIMClockSource(LPTIMxSource)) + { + case LL_RCC_LPTIM6_CLKSOURCE_PCLK3: /* LPTIM6 Clock is is PCLK3 */ + lptim_frequency = RCC_GetPCLK3ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); + break; + + case LL_RCC_LPTIM6_CLKSOURCE_PLL2P: /* LPTIM6 Clock is PLL2 P */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2P_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + lptim_frequency = PLL_Clocks.PLL_P_Frequency; + } + } + break; + + case LL_RCC_LPTIM6_CLKSOURCE_PLL3R: /* LPTIM6 Clock is PLL3 R */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3R_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + lptim_frequency = PLL_Clocks.PLL_R_Frequency; + } + } + break; + + case LL_RCC_LPTIM6_CLKSOURCE_LSE: /* LPTIM6 Clock is LSE Osc. */ + if (LL_RCC_LSE_IsReady() == 1U) + { + lptim_frequency = LSE_VALUE; + } + break; + + case LL_RCC_LPTIM6_CLKSOURCE_LSI: /* LPTIM6 Clock is LSI Osc. */ + if (LL_RCC_LSI_IsReady() == 1U) + { + lptim_frequency = LSI_VALUE; + } + break; + + case LL_RCC_LPTIM6_CLKSOURCE_CLKP: /* LPTIM6 Clock is CLKP */ + lptim_frequency = LL_RCC_GetCLKPClockFreq(LL_RCC_GetCLKPClockSource(LL_RCC_CLKP_CLKSOURCE)); + break; + + default: + /* unreachable code */ + break; + } + } +#endif /* LPTIM6 */ + else + { + /* nothing to do */ + } + + return lptim_frequency; +} + +#if defined(SAI1) +/** + * @brief Return SAIx clock frequency + * @param SAIxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_SAI1_CLKSOURCE + * @arg @ref LL_RCC_SAI2_CLKSOURCE + * @retval SAI clock frequency (in Hz) + * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that PLL is not ready + */ +uint32_t LL_RCC_GetSAIClockFreq(uint32_t SAIxSource) +{ + uint32_t sai_frequency = LL_RCC_PERIPH_FREQUENCY_NO; + LL_PLL_ClocksTypeDef PLL_Clocks; + + /* Check parameter */ + assert_param(IS_LL_RCC_SAI_CLKSOURCE(SAIxSource)); + + if (SAIxSource == LL_RCC_SAI1_CLKSOURCE) + { + /* SAI1CLK clock frequency */ + switch (LL_RCC_GetSAIClockSource(SAIxSource)) + { + case LL_RCC_SAI1_CLKSOURCE_PLL1Q: /* PLL1 Q clock used as SAI1 clock source */ + if (LL_RCC_PLL1_IsReady() != 0U) + { + if (LL_RCC_PLL1Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL1ClockFreq(&PLL_Clocks); + sai_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_SAI1_CLKSOURCE_PLL2P: /* PLL2 P clock used as SAI1 clock source */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2P_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + sai_frequency = PLL_Clocks.PLL_P_Frequency; + } + } + break; + + case LL_RCC_SAI1_CLKSOURCE_PLL3P: /* PLL3 P clock used as SAI1 clock source */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3P_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + sai_frequency = PLL_Clocks.PLL_P_Frequency; + } + } + break; + + case LL_RCC_SAI1_CLKSOURCE_PIN: /* External input clock used as SAI1 clock source */ + sai_frequency = EXTERNAL_CLOCK_VALUE; + break; + + case LL_RCC_SAI1_CLKSOURCE_CLKP: /* CLKP used as SAI1 clock source */ + sai_frequency = LL_RCC_GetCLKPClockFreq(LL_RCC_GetCLKPClockSource(LL_RCC_CLKP_CLKSOURCE)); + break; + + default: + /* unreachable code */ + break; + } + } + else if (SAIxSource == LL_RCC_SAI2_CLKSOURCE) + { + /* SAI2CLK clock frequency */ + switch (LL_RCC_GetSAIClockSource(SAIxSource)) + { + case LL_RCC_SAI2_CLKSOURCE_PLL1Q: /* PLL1 Q clock used as SAI2 clock source */ + if (LL_RCC_PLL1_IsReady() != 0U) + { + if (LL_RCC_PLL1Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL1ClockFreq(&PLL_Clocks); + sai_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_SAI2_CLKSOURCE_PLL2P: /* PLL2 P clock used as SAI2 clock source */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2P_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + sai_frequency = PLL_Clocks.PLL_P_Frequency; + } + } + break; + + case LL_RCC_SAI2_CLKSOURCE_PLL3P: /* PLL3 P clock used as SAI2 clock source */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3P_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + sai_frequency = PLL_Clocks.PLL_P_Frequency; + } + } + break; + + case LL_RCC_SAI2_CLKSOURCE_PIN: /* External input clock used as SAI2 clock source */ + sai_frequency = EXTERNAL_CLOCK_VALUE; + break; + + case LL_RCC_SAI2_CLKSOURCE_CLKP: /* SAI2 Clock is CLKP */ + sai_frequency = LL_RCC_GetCLKPClockFreq(LL_RCC_GetCLKPClockSource(LL_RCC_CLKP_CLKSOURCE)); + break; + + default: + /* unreachable code */ + break; + } + } + else + { + /* nothing to do */ + } + + return sai_frequency; +} +#endif /* SAI1 */ + +#if defined(SDMMC1) +/** + * @brief Return SDMMCx clock frequency + * @param SDMMCxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_SDMMC1_CLKSOURCE + * @arg @ref LL_RCC_SDMMC2_CLKSOURCE (*) + * @retval SDMMC clock frequency (in Hz) + * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator or PLL is not ready + * + * (*) : Available on some STM32H5 lines only. + */ +uint32_t LL_RCC_GetSDMMCClockFreq(uint32_t SDMMCxSource) +{ + uint32_t sdmmc_frequency = LL_RCC_PERIPH_FREQUENCY_NO; + LL_PLL_ClocksTypeDef PLL_Clocks; + + /* Check parameter */ + assert_param(IS_LL_RCC_SDMMC_CLKSOURCE(SDMMCxSource)); + + if (SDMMCxSource == LL_RCC_SDMMC1_CLKSOURCE) + { + /* SDMMC1CLK clock frequency */ + switch (LL_RCC_GetSDMMCClockSource(SDMMCxSource)) + { + case LL_RCC_SDMMC1_CLKSOURCE_PLL1Q: /* PLL1 Q clock used as SDMMC1 clock source */ + if (LL_RCC_PLL1_IsReady() != 0U) + { + if (LL_RCC_PLL1Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL1ClockFreq(&PLL_Clocks); + sdmmc_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_SDMMC1_CLKSOURCE_PLL2R: /* PLL2 R clock used as SDMMC1 clock source */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2R_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + sdmmc_frequency = PLL_Clocks.PLL_R_Frequency; + } + } + break; + + default: + /* unreachable code */ + break; + } + } + +#if defined(SDMMC2) + else if (SDMMCxSource == LL_RCC_SDMMC2_CLKSOURCE) + { + /* SDMMC2CLK clock frequency */ + switch (LL_RCC_GetSDMMCClockSource(SDMMCxSource)) + { + case LL_RCC_SDMMC2_CLKSOURCE_PLL1Q: /* PLL1 Q clock used as SDMMC2 clock source */ + if (LL_RCC_PLL1_IsReady() != 0U) + { + if (LL_RCC_PLL1Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL1ClockFreq(&PLL_Clocks); + sdmmc_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_SDMMC2_CLKSOURCE_PLL2R: /* PLL2 R clock used as SDMMC2 clock source */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2R_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + sdmmc_frequency = PLL_Clocks.PLL_R_Frequency; + } + } + break; + + default: + /* unreachable code */ + break; + } + } +#endif /* SDMMC2 */ + + else + { + /* nothing to do */ + } + + return sdmmc_frequency; +} +#endif /* SDMMC1 */ + +/** + * @brief Return RNGx clock frequency + * @param RNGxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_RNG_CLKSOURCE + * @retval RNG clock frequency (in Hz) + * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator or PLL is not ready + */ +uint32_t LL_RCC_GetRNGClockFreq(uint32_t RNGxSource) +{ + uint32_t rng_frequency = LL_RCC_PERIPH_FREQUENCY_NO; + LL_PLL_ClocksTypeDef PLL_Clocks; + + /* Check parameter */ + assert_param(IS_LL_RCC_RNG_CLKSOURCE(RNGxSource)); + + /* RNGCLK clock frequency */ + switch (LL_RCC_GetRNGClockSource(RNGxSource)) + { + case LL_RCC_RNG_CLKSOURCE_HSI48: /* HSI48 clock used as RNG clock source */ + if (LL_RCC_HSI48_IsReady() == 1U) + { + rng_frequency = HSI48_VALUE; + } + break; + + case LL_RCC_RNG_CLKSOURCE_PLL1Q: /* PLL1 Q clock used as RNG clock source */ + if (LL_RCC_PLL1_IsReady() != 0U) + { + if (LL_RCC_PLL1Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL1ClockFreq(&PLL_Clocks); + rng_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_RNG_CLKSOURCE_LSE: /* LSE clock used as RNG clock source */ + if (LL_RCC_LSE_IsReady() == 1U) + { + rng_frequency = LSE_VALUE; + } + break; + + case LL_RCC_RNG_CLKSOURCE_LSI: /* LSI clock used as RNG clock source */ + if (LL_RCC_LSI_IsReady() == 1U) + { + rng_frequency = LSI_VALUE; + } + break; + + default: + /* unreachable code */ + break; + + } + + return rng_frequency; +} + +/** + * @brief Return USBx clock frequency + * @param USBxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_USB_CLKSOURCE + * @retval USB clock frequency (in Hz) + * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator or PLL is not ready or no clock is selected + */ +uint32_t LL_RCC_GetUSBClockFreq(uint32_t USBxSource) +{ + uint32_t usb_frequency = LL_RCC_PERIPH_FREQUENCY_NO; + LL_PLL_ClocksTypeDef PLL_Clocks; + + /* Check parameter */ + assert_param(IS_LL_RCC_USB_CLKSOURCE(USBxSource)); + + /* USBCLK clock frequency */ + switch (LL_RCC_GetUSBClockSource(USBxSource)) + { + + case LL_RCC_USB_CLKSOURCE_NONE: /* NO clock used as USB clock source */ + break; + + case LL_RCC_USB_CLKSOURCE_PLL1Q: /* PLL1 Q clock used as USB clock source */ + if (LL_RCC_PLL1_IsReady() != 0U) + { + if (LL_RCC_PLL1Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL1ClockFreq(&PLL_Clocks); + usb_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + +#if defined(LL_RCC_USB_CLKSOURCE_PLL3Q) + case LL_RCC_USB_CLKSOURCE_PLL3Q: /* PLL3 Q clock used as USB clock source */ + if (LL_RCC_PLL3_IsReady() != 0U) + { + if (LL_RCC_PLL3Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); + usb_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; +#endif /* LL_RCC_USB_CLKSOURCE_PLL3 */ + + case LL_RCC_USB_CLKSOURCE_HSI48: /* HSI48 clock used as USB clock source */ + if (LL_RCC_HSI48_IsReady() == 1U) + { + usb_frequency = HSI48_VALUE; + } + break; + + default: + /* unreachable code */ + break; + } + + return usb_frequency; +} + +/** + * @brief Return ADCxDAC clock frequency + * @param ADCDACxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_ADCDAC_CLKSOURCE + * @retval ADCDAC clock frequency (in Hz) + * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator or PLL is not ready + */ +uint32_t LL_RCC_GetADCDACClockFreq(uint32_t ADCDACxSource) +{ + uint32_t adcdac_frequency = LL_RCC_PERIPH_FREQUENCY_NO; + LL_PLL_ClocksTypeDef PLL_Clocks; + + /* Check parameter */ + assert_param(IS_LL_RCC_ADCDAC_CLKSOURCE(ADCDACxSource)); + + /* ADCCLK clock frequency */ + switch (LL_RCC_GetADCDACClockSource(ADCDACxSource)) + { + case LL_RCC_ADCDAC_CLKSOURCE_HCLK: /* ADCDAC Clock is AHB clock */ + adcdac_frequency = RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()); + break; + + case LL_RCC_ADCDAC_CLKSOURCE_SYSCLK: /* ADCDAC Clock is SYSCLK clock */ + adcdac_frequency = RCC_GetSystemClockFreq(); + break; + + case LL_RCC_ADCDAC_CLKSOURCE_PLL2R: /* ADCDAC Clock is PLL2 R */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2R_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + adcdac_frequency = PLL_Clocks.PLL_R_Frequency; + } + } + break; + + case LL_RCC_ADCDAC_CLKSOURCE_HSE: /* ADCDAC Clock is HSE Osc. */ + if (LL_RCC_HSE_IsReady() == 1U) + { + adcdac_frequency = HSE_VALUE; + } + break; + + case LL_RCC_ADCDAC_CLKSOURCE_HSI: /* ADCDAC Clock is HSI Osc. */ + if (LL_RCC_HSI_IsReady() == 1U) + { + adcdac_frequency = HSI_VALUE; + } + break; + + case LL_RCC_ADCDAC_CLKSOURCE_CSI: /* ADCDAC Clock is CSI Osc. */ + if (LL_RCC_CSI_IsReady() == 1U) + { + adcdac_frequency = CSI_VALUE; + } + break; + + default: + /* unreachable code */ + break; + } + + return adcdac_frequency; +} + +/** + * @brief Return DAC low-power clock frequency + * @param DACLPxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_DAC_LP_CLKSOURCE + * @retval DAC low-power clock frequency (in Hz) + * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that LSI or LSE oscillator is not ready + */ +uint32_t LL_RCC_GetDACLPClockFreq(uint32_t DACLPxSource) +{ + uint32_t daclp_frequency = LL_RCC_PERIPH_FREQUENCY_NO; + + /* Check parameter */ + assert_param(IS_LL_RCC_DAC_LP_CLKSOURCE(DACLPxSource)); + + /* DAC clock frequency */ + switch (LL_RCC_GetDACLPClockSource(DACLPxSource)) + { + case LL_RCC_DAC_LP_CLKSOURCE_LSE: /* DAC low-power Clock is LSE Osc. */ + if (LL_RCC_LSE_IsReady() == 1U) + { + daclp_frequency = LSE_VALUE; + } + break; + + case LL_RCC_DAC_LP_CLKSOURCE_LSI: /* DAC low-power Clock is LSI Osc. */ + if (LL_RCC_LSI_IsReady() == 1U) + { + daclp_frequency = LSI_VALUE; + } + break; + + default: + /* unreachable code */ + break; + } + + return daclp_frequency; +} + +#if defined( OCTOSPI1) +/** + * @brief Return OCTOSPI clock frequency + * @param OCTOSPIxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_OCTOSPI_CLKSOURCE + * @retval OCTOSPI clock frequency (in Hz) + * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator or PLL is not ready + */ +uint32_t LL_RCC_GetOCTOSPIClockFreq(uint32_t OCTOSPIxSource) +{ + uint32_t octospi_frequency = LL_RCC_PERIPH_FREQUENCY_NO; + LL_PLL_ClocksTypeDef PLL_Clocks; + + /* Check parameter */ + assert_param(IS_LL_RCC_OCTOSPI_CLKSOURCE(OCTOSPIxSource)); + + /* OCTOSPI clock frequency */ + switch (LL_RCC_GetOCTOSPIClockSource(OCTOSPIxSource)) + { + case LL_RCC_OSPI_CLKSOURCE_HCLK: /* OCTOSPI clock is SYSCLK */ + octospi_frequency = RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()); + break; + + case LL_RCC_OSPI_CLKSOURCE_PLL1Q: /* OSPI Clock is PLL1 Q */ + if (LL_RCC_PLL1_IsReady() != 0U) + { + if (LL_RCC_PLL1Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL1ClockFreq(&PLL_Clocks); + octospi_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_OSPI_CLKSOURCE_PLL2R: /* OSPI Clock is PLL2 R */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2R_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + octospi_frequency = PLL_Clocks.PLL_R_Frequency; + } + } + break; + + case LL_RCC_OSPI_CLKSOURCE_CLKP: /* OSPI Clock is CLKP */ + octospi_frequency = LL_RCC_GetCLKPClockFreq(LL_RCC_GetCLKPClockSource(LL_RCC_CLKP_CLKSOURCE)); + break; + + default: + /* unreachable code */ + break; + } + + return octospi_frequency; +} +#endif /* OCTOSPI1 */ + +/** + * @brief Return FDCAN kernel clock frequency + * @param FDCANxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_FDCAN_CLKSOURCE + * @retval FDCAN kernel clock frequency (in Hz) + * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator or PLL is not ready or no clock is selected + * + */ +uint32_t LL_RCC_GetFDCANClockFreq(uint32_t FDCANxSource) +{ + uint32_t fdcan_frequency = LL_RCC_PERIPH_FREQUENCY_NO; + LL_PLL_ClocksTypeDef PLL_Clocks; + + /* Check parameter */ + assert_param(IS_LL_RCC_FDCAN_CLKSOURCE(FDCANxSource)); + + /* FDCANCLK clock frequency */ + switch (LL_RCC_GetFDCANClockSource(FDCANxSource)) + { + case LL_RCC_FDCAN_CLKSOURCE_HSE: /* HSE clock used as FDCAN clock source */ + if (LL_RCC_HSE_IsReady() == 1U) + { + fdcan_frequency = HSE_VALUE; + } + break; + + case LL_RCC_FDCAN_CLKSOURCE_PLL1Q: /* PLL1 Q clock used as FDCAN clock source */ + if (LL_RCC_PLL1_IsReady() != 0U) + { + if (LL_RCC_PLL1Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL1ClockFreq(&PLL_Clocks); + fdcan_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_FDCAN_CLKSOURCE_PLL2Q: /* PLL2 Q clock used as FDCAN clock source */ + if (LL_RCC_PLL2_IsReady() != 0U) + { + if (LL_RCC_PLL2Q_IsEnabled() != 0U) + { + LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); + fdcan_frequency = PLL_Clocks.PLL_Q_Frequency; + } + } + break; + + case LL_RCC_FDCAN_CLKSOURCE_NONE: /* No clock used as FDCAN clock source */ + break; + + default: + /* unreachable code */ + break; + } + + return fdcan_frequency; +} + +#if defined(CEC) +/** + * @brief Return CEC clock frequency + * @param CECxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_CEC_CLKSOURCE + * @retval CEC clock frequency (in Hz) + * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready or no clock is selected + */ +uint32_t LL_RCC_GetCECClockFreq(uint32_t CECxSource) +{ + uint32_t cec_frequency = LL_RCC_PERIPH_FREQUENCY_NO; + + switch (LL_RCC_GetCECClockSource(CECxSource)) + { + case LL_RCC_CEC_CLKSOURCE_LSE: /* CEC Clock is LSE */ + if (LL_RCC_LSE_IsReady() != 0U) + { + cec_frequency = LSE_VALUE; + } + break; + + case LL_RCC_CEC_CLKSOURCE_LSI: /* CEC Clock is LSI */ + if (LL_RCC_LSI_IsReady() != 0U) + { + cec_frequency = LSI_VALUE; + } + break; + + case LL_RCC_CEC_CLKSOURCE_CSI_DIV122: /* CEC Clock is CSI divided by 122 */ + if (LL_RCC_CSI_IsReady() != 0U) + { + cec_frequency = CSI_VALUE / 122U; + } + break; + + case LL_RCC_CEC_CLKSOURCE_NONE: /* No Clock selected for CEC */ + break; + + default: + /* Kernel clock disabled */ + break; + } + + return cec_frequency; +} +#endif /* CEC */ + +/** + * @brief Return CLKP clock frequency + * @param CLKPxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_CLKP_CLKSOURCE + * @retval CLKP clock frequency (in Hz) + * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready or no clock is selected + */ +uint32_t LL_RCC_GetCLKPClockFreq(uint32_t CLKPxSource) +{ + uint32_t clkp_frequency = LL_RCC_PERIPH_FREQUENCY_NO; + + switch (LL_RCC_GetCLKPClockSource(CLKPxSource)) + { + case LL_RCC_CLKP_CLKSOURCE_HSI: /* HSI used as CLKP clock source */ + if (LL_RCC_HSI_IsReady() != 0U) + { + clkp_frequency = HSI_VALUE >> (LL_RCC_HSI_GetDivider() >> RCC_CR_HSIDIV_Pos); + } + break; + + case LL_RCC_CLKP_CLKSOURCE_CSI: /* CSI used as CLKP clock source */ + if (LL_RCC_CSI_IsReady() != 0U) + { + clkp_frequency = CSI_VALUE; + } + break; + + case LL_RCC_CLKP_CLKSOURCE_HSE: /* HSE used as CLKP clock source */ + if (LL_RCC_HSE_IsReady() != 0U) + { + clkp_frequency = HSE_VALUE; + } + break; + + case LL_RCC_CLKP_CLKSOURCE_NONE: /* NO clock used as CLKP clock source */ + break; + + default: + /* CLKP clock disabled */ + break; + } + + return clkp_frequency; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup RCC_LL_Private_Functions + * @{ + */ + +/** + * @brief Return SYSTEM clock frequency + * @retval SYSTEM clock frequency (in Hz) + */ +uint32_t RCC_GetSystemClockFreq(void) +{ + uint32_t frequency; + + /* Get SYSCLK source -------------------------------------------------------*/ + switch (LL_RCC_GetSysClkSource()) + { + case LL_RCC_SYS_CLKSOURCE_STATUS_HSI: /* HSI used as system clock source */ + frequency = HSI_VALUE; + break; + + case LL_RCC_SYS_CLKSOURCE_STATUS_CSI: /* CSI used as system clock source */ + frequency = CSI_VALUE; + break; + + case LL_RCC_SYS_CLKSOURCE_STATUS_HSE: /* HSE used as system clock source */ + frequency = HSE_VALUE; + break; + + case LL_RCC_SYS_CLKSOURCE_STATUS_PLL1: /* PLL1 used as system clock source */ + frequency = RCC_PLL1_GetFreqSystem(); + break; + + default: + frequency = HSI_VALUE; + break; + } + + return frequency; +} + +/** + * @brief Return HCLK clock frequency + * @param SYSCLK_Frequency SYSCLK clock frequency + * @retval HCLK clock frequency (in Hz) + */ +uint32_t RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency) +{ + /* HCLK clock frequency */ + return __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, LL_RCC_GetAHBPrescaler()); +} + +/** + * @brief Return PCLK1 clock frequency + * @param HCLK_Frequency HCLK clock frequency + * @retval PCLK1 clock frequency (in Hz) + */ +uint32_t RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency) +{ + /* PCLK1 clock frequency */ + return __LL_RCC_CALC_PCLK1_FREQ(HCLK_Frequency, LL_RCC_GetAPB1Prescaler()); +} + +/** + * @brief Return PCLK2 clock frequency + * @param HCLK_Frequency HCLK clock frequency + * @retval PCLK2 clock frequency (in Hz) + */ +uint32_t RCC_GetPCLK2ClockFreq(uint32_t HCLK_Frequency) +{ + /* PCLK2 clock frequency */ + return __LL_RCC_CALC_PCLK2_FREQ(HCLK_Frequency, LL_RCC_GetAPB2Prescaler()); +} + + +/** + * @brief Return PCLK3 clock frequency + * @param HCLK_Frequency HCLK clock frequency + * @retval PCLK3 clock frequency (in Hz) + */ +uint32_t RCC_GetPCLK3ClockFreq(uint32_t HCLK_Frequency) +{ + /* PCLK3 clock frequency */ + return __LL_RCC_CALC_PCLK3_FREQ(HCLK_Frequency, LL_RCC_GetAPB3Prescaler()); +} + +/** + * @brief Return PLL1 clock frequency used for system clock + * @retval PLL1 clock frequency (in Hz) + */ +uint32_t RCC_PLL1_GetFreqSystem(void) +{ + uint32_t pllinputfreq; + uint32_t pllsource; + + /* PLL_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN + SYSCLK = PLL_VCO / PLLP + */ + pllsource = LL_RCC_PLL1_GetSource(); + + switch (pllsource) + { + case LL_RCC_PLL1SOURCE_HSI: /* HSI used as PLL1 clock source */ + pllinputfreq = HSI_VALUE; + break; + + case LL_RCC_PLL1SOURCE_CSI: /* CSI used as PLL1 clock source */ + pllinputfreq = CSI_VALUE; + break; + + case LL_RCC_PLL1SOURCE_HSE: /* HSE used as PLL1 clock source */ + pllinputfreq = HSE_VALUE; + break; + + default: + pllinputfreq = 0; + break; + } + return __LL_RCC_CALC_PLL1CLK_P_FREQ(pllinputfreq, LL_RCC_PLL1_GetM(), + LL_RCC_PLL1_GetN(), LL_RCC_PLL1_GetP()); +} + + + + + + + + +/** + * @} + */ + + + +/** + * @} + */ + +#endif /* defined(RCC) */ + +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_rng.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_rng.c new file mode 100644 index 0000000000..256a487012 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_rng.c @@ -0,0 +1,158 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_rng.c + * @author MCD Application Team + * @brief RNG LL module driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +#if defined(USE_FULL_LL_DRIVER) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_rng.h" +#include "stm32h5xx_ll_bus.h" + +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (RNG) + +/** @addtogroup RNG_LL + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup RNG_LL_Private_Macros RNG Private Macros + * @{ + */ +#define IS_LL_RNG_CED(__MODE__) (((__MODE__) == LL_RNG_CED_ENABLE) || \ + ((__MODE__) == LL_RNG_CED_DISABLE)) + +#define IS_LL_RNG_CLOCK_DIVIDER(__CLOCK_DIV__) ((__CLOCK_DIV__) <=0x0Fu) + + +#define IS_LL_RNG_NIST_COMPLIANCE(__NIST_COMPLIANCE__) (((__NIST_COMPLIANCE__) == LL_RNG_NIST_COMPLIANT) || \ + ((__NIST_COMPLIANCE__) == LL_RNG_NOTNIST_COMPLIANT)) + +#define IS_LL_RNG_CONFIG1 (__CONFIG1__) ((__CONFIG1__) <= 0x3FUL) + +#define IS_LL_RNG_CONFIG2 (__CONFIG2__) ((__CONFIG2__) <= 0x07UL) + +#define IS_LL_RNG_CONFIG3 (__CONFIG3__) ((__CONFIG3__) <= 0xFUL) +/** + * @} + */ +/* Private function prototypes -----------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup RNG_LL_Exported_Functions + * @{ + */ + +/** @addtogroup RNG_LL_EF_Init + * @{ + */ + +/** + * @brief De-initialize RNG registers (Registers restored to their default values). + * @param RNGx RNG Instance + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RNG registers are de-initialized + * - ERROR: not applicable + */ +ErrorStatus LL_RNG_DeInit(const RNG_TypeDef *RNGx) +{ + ErrorStatus status = SUCCESS; + + /* Check the parameters */ + assert_param(IS_RNG_ALL_INSTANCE(RNGx)); + if (RNGx == RNG) + { + /* Enable RNG reset state */ + LL_AHB2_GRP1_ForceReset(LL_AHB2_GRP1_PERIPH_RNG); + + /* Release RNG from reset state */ + LL_AHB2_GRP1_ReleaseReset(LL_AHB2_GRP1_PERIPH_RNG); + } + else + { + status = ERROR; + } + + return status; +} + +/** + * @brief Initialize RNG registers according to the specified parameters in RNG_InitStruct. + * @param RNGx RNG Instance + * @param RNG_InitStruct pointer to a LL_RNG_InitTypeDef structure + * that contains the configuration information for the specified RNG peripheral. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RNG registers are initialized according to RNG_InitStruct content + * - ERROR: not applicable + */ +ErrorStatus LL_RNG_Init(RNG_TypeDef *RNGx, LL_RNG_InitTypeDef *RNG_InitStruct) +{ + /* Check the parameters */ + assert_param(IS_RNG_ALL_INSTANCE(RNGx)); + assert_param(IS_LL_RNG_CED(RNG_InitStruct->ClockErrorDetection)); + + /* Clock Error Detection Configuration when CONDRT bit is set to 1 */ + MODIFY_REG(RNGx->CR, RNG_CR_CED | RNG_CR_CONDRST, RNG_InitStruct->ClockErrorDetection | RNG_CR_CONDRST); + /* Writing bits CONDRST=0*/ + CLEAR_BIT(RNGx->CR, RNG_CR_CONDRST); + + return (SUCCESS); +} + +/** + * @brief Set each @ref LL_RNG_InitTypeDef field to default value. + * @param RNG_InitStruct pointer to a @ref LL_RNG_InitTypeDef structure + * whose fields will be set to default values. + * @retval None + */ +void LL_RNG_StructInit(LL_RNG_InitTypeDef *RNG_InitStruct) +{ + /* Set RNG_InitStruct fields to default values */ + RNG_InitStruct->ClockErrorDetection = LL_RNG_CED_ENABLE; + +} +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* RNG */ + +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_rtc.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_rtc.c new file mode 100644 index 0000000000..531388ff5a --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_rtc.c @@ -0,0 +1,855 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_rtc.c + * @author MCD Application Team + * @brief RTC LL module driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +#if defined(USE_FULL_LL_DRIVER) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_rtc.h" +#include "stm32h5xx_ll_cortex.h" +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined(RTC) + +/** @addtogroup RTC_LL + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @addtogroup RTC_LL_Private_Constants + * @{ + */ +/* Default values used for prescaler */ +#define RTC_ASYNCH_PRESC_DEFAULT ((uint32_t) 0x0000007FU) +#define RTC_SYNCH_PRESC_DEFAULT ((uint32_t) 0x000000FFU) + +/* Values used for timeout */ +#define RTC_INITMODE_TIMEOUT ((uint32_t) 1000U) /* 1s when tick set to 1ms */ +#define RTC_SYNCHRO_TIMEOUT ((uint32_t) 1000U) /* 1s when tick set to 1ms */ +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup RTC_LL_Private_Macros + * @{ + */ + +#define IS_LL_RTC_HOURFORMAT(__VALUE__) (((__VALUE__) == LL_RTC_HOURFORMAT_24HOUR) \ + || ((__VALUE__) == LL_RTC_HOURFORMAT_AMPM)) + +#define IS_LL_RTC_ASYNCH_PREDIV(__VALUE__) ((__VALUE__) <= 0x7FU) + +#define IS_LL_RTC_SYNCH_PREDIV(__VALUE__) ((__VALUE__) <= 0x7FFFU) + +#define IS_LL_RTC_FORMAT(__VALUE__) (((__VALUE__) == LL_RTC_FORMAT_BIN) \ + || ((__VALUE__) == LL_RTC_FORMAT_BCD)) + +#define IS_LL_RTC_TIME_FORMAT(__VALUE__) (((__VALUE__) == LL_RTC_TIME_FORMAT_AM_OR_24) \ + || ((__VALUE__) == LL_RTC_TIME_FORMAT_PM)) + +#define IS_LL_RTC_HOUR12(__HOUR__) (((__HOUR__) > 0U) && ((__HOUR__) <= 12U)) +#define IS_LL_RTC_HOUR24(__HOUR__) ((__HOUR__) <= 23U) +#define IS_LL_RTC_MINUTES(__MINUTES__) ((__MINUTES__) <= 59U) +#define IS_LL_RTC_SECONDS(__SECONDS__) ((__SECONDS__) <= 59U) + +#define IS_LL_RTC_WEEKDAY(__VALUE__) (((__VALUE__) == LL_RTC_WEEKDAY_MONDAY) \ + || ((__VALUE__) == LL_RTC_WEEKDAY_TUESDAY) \ + || ((__VALUE__) == LL_RTC_WEEKDAY_WEDNESDAY) \ + || ((__VALUE__) == LL_RTC_WEEKDAY_THURSDAY) \ + || ((__VALUE__) == LL_RTC_WEEKDAY_FRIDAY) \ + || ((__VALUE__) == LL_RTC_WEEKDAY_SATURDAY) \ + || ((__VALUE__) == LL_RTC_WEEKDAY_SUNDAY)) + +#define IS_LL_RTC_DAY(__DAY__) (((__DAY__) >= (uint32_t)1U) && ((__DAY__) <= (uint32_t)31U)) + +#define IS_LL_RTC_MONTH(__MONTH__) (((__MONTH__) >= 1U) && ((__MONTH__) <= 12U)) + +#define IS_LL_RTC_YEAR(__YEAR__) ((__YEAR__) <= 99U) + +#define IS_LL_RTC_ALMA_MASK(__VALUE__) (((__VALUE__) == LL_RTC_ALMA_MASK_NONE) \ + || ((__VALUE__) == LL_RTC_ALMA_MASK_DATEWEEKDAY) \ + || ((__VALUE__) == LL_RTC_ALMA_MASK_HOURS) \ + || ((__VALUE__) == LL_RTC_ALMA_MASK_MINUTES) \ + || ((__VALUE__) == LL_RTC_ALMA_MASK_SECONDS) \ + || ((__VALUE__) == LL_RTC_ALMA_MASK_ALL)) + +#define IS_LL_RTC_ALMB_MASK(__VALUE__) (((__VALUE__) == LL_RTC_ALMB_MASK_NONE) \ + || ((__VALUE__) == LL_RTC_ALMB_MASK_DATEWEEKDAY) \ + || ((__VALUE__) == LL_RTC_ALMB_MASK_HOURS) \ + || ((__VALUE__) == LL_RTC_ALMB_MASK_MINUTES) \ + || ((__VALUE__) == LL_RTC_ALMB_MASK_SECONDS) \ + || ((__VALUE__) == LL_RTC_ALMB_MASK_ALL)) + + +#define IS_LL_RTC_ALMA_DATE_WEEKDAY_SEL(__SEL__) (((__SEL__) == LL_RTC_ALMA_DATEWEEKDAYSEL_DATE) || \ + ((__SEL__) == LL_RTC_ALMA_DATEWEEKDAYSEL_WEEKDAY)) + +#define IS_LL_RTC_ALMB_DATE_WEEKDAY_SEL(__SEL__) (((__SEL__) == LL_RTC_ALMB_DATEWEEKDAYSEL_DATE) || \ + ((__SEL__) == LL_RTC_ALMB_DATEWEEKDAYSEL_WEEKDAY)) + + +/** + * @} + */ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup RTC_LL_Exported_Functions + * @{ + */ + +/** @addtogroup RTC_LL_EF_Init + * @{ + */ + +/** + * @brief De-Initializes the RTC registers to their default reset values. + * @note This function does not reset the RTC Clock source and RTC Backup Data + * registers. + * @param RTCx RTC Instance + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC registers are de-initialized + * - ERROR: RTC registers are not de-initialized + */ +ErrorStatus LL_RTC_DeInit(RTC_TypeDef *RTCx) +{ + ErrorStatus status = ERROR; + + /* Check the parameter */ + assert_param(IS_RTC_ALL_INSTANCE(RTCx)); + + /* Disable the write protection for RTC registers */ + LL_RTC_DisableWriteProtection(RTCx); + + /* Set Initialization mode */ + if (LL_RTC_EnterInitMode(RTCx) != ERROR) + { + WRITE_REG(RTCx->TR, 0U); + WRITE_REG(RTCx->DR, (RTC_DR_WDU_0 | RTC_DR_MU_0 | RTC_DR_DU_0)); + WRITE_REG(RTCx->CR, 0U); + WRITE_REG(RTCx->WUTR, RTC_WUTR_WUT); + WRITE_REG(RTCx->PRER, (RTC_PRER_PREDIV_A | RTC_SYNCH_PRESC_DEFAULT)); + WRITE_REG(RTCx->ALRMAR, 0U); + WRITE_REG(RTCx->ALRMBR, 0U); + WRITE_REG(RTCx->SHIFTR, 0U); + WRITE_REG(RTCx->CALR, 0U); + WRITE_REG(RTCx->ALRMASSR, 0U); + WRITE_REG(RTCx->ALRMBSSR, 0U); + WRITE_REG(RTCx->PRIVCFGR, 0U); +#if defined (RTC_SECCFGR_SEC) + WRITE_REG(RTCx->SECCFGR, 0U); +#endif /* RTC_SECCFGR_SEC */ + + /* Clear some bits of RTC_ICSR and exit Initialization mode */ + CLEAR_BIT(RTCx->ICSR, RTC_ICSR_BCDU_Msk | RTC_ICSR_BIN_Msk | RTC_ICSR_INIT); + + /* Wait till the RTC RSF flag is set */ + status = LL_RTC_WaitForSynchro(RTCx); + } + + /* Enable the write protection for RTC registers */ + LL_RTC_EnableWriteProtection(RTCx); + + /* DeInitialization of the TAMP registers */ + WRITE_REG(TAMP->CR1, 0U); + WRITE_REG(TAMP->CR2, 0U); + WRITE_REG(TAMP->CR3, 0U); +#if defined (TAMP_SECCFGR_TAMPSEC) + WRITE_REG(TAMP->SECCFGR, 0U); +#endif /* TAMP_SECCFGR_TAMPSEC */ + WRITE_REG(TAMP->PRIVCFGR, 0U); + WRITE_REG(TAMP->FLTCR, 0U); + WRITE_REG(TAMP->ATCR1, 0x00070000U); + WRITE_REG(TAMP->ATCR2, 0U); + WRITE_REG(TAMP->IER, 0U); + WRITE_REG(TAMP->SCR, 0xFFFFFFFFU); + + return status; +} + +/** + * @brief Initializes the RTC registers according to the specified parameters + * in RTC_InitStruct. + * @param RTCx RTC Instance + * @param RTC_InitStruct pointer to a @ref LL_RTC_InitTypeDef structure that contains + * the configuration information for the RTC peripheral. + * @note The RTC Prescaler register is write protected and can be written in + * initialization mode only. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC registers are initialized + * - ERROR: RTC registers are not initialized + */ +ErrorStatus LL_RTC_Init(RTC_TypeDef *RTCx, LL_RTC_InitTypeDef *RTC_InitStruct) +{ + ErrorStatus status = ERROR; + + /* Check the parameters */ + assert_param(IS_RTC_ALL_INSTANCE(RTCx)); + assert_param(IS_LL_RTC_HOURFORMAT(RTC_InitStruct->HourFormat)); + assert_param(IS_LL_RTC_ASYNCH_PREDIV(RTC_InitStruct->AsynchPrescaler)); + assert_param(IS_LL_RTC_SYNCH_PREDIV(RTC_InitStruct->SynchPrescaler)); + + /* Disable the write protection for RTC registers */ + LL_RTC_DisableWriteProtection(RTCx); + + /* Set Initialization mode */ + if (LL_RTC_EnterInitMode(RTCx) != ERROR) + { + /* Set Hour Format */ + LL_RTC_SetHourFormat(RTCx, RTC_InitStruct->HourFormat); + + /* Configure Synchronous and Asynchronous prescaler factor */ + LL_RTC_SetSynchPrescaler(RTCx, RTC_InitStruct->SynchPrescaler); + LL_RTC_SetAsynchPrescaler(RTCx, RTC_InitStruct->AsynchPrescaler); + + /* Exit Initialization mode */ + LL_RTC_DisableInitMode(RTCx); + + status = SUCCESS; + } + /* Enable the write protection for RTC registers */ + LL_RTC_EnableWriteProtection(RTCx); + + return status; +} + +/** + * @brief Set each @ref LL_RTC_InitTypeDef field to default value. + * @param RTC_InitStruct pointer to a @ref LL_RTC_InitTypeDef structure which will be initialized. + * @retval None + */ +void LL_RTC_StructInit(LL_RTC_InitTypeDef *RTC_InitStruct) +{ + /* Set RTC_InitStruct fields to default values */ + RTC_InitStruct->HourFormat = LL_RTC_HOURFORMAT_24HOUR; + RTC_InitStruct->AsynchPrescaler = RTC_ASYNCH_PRESC_DEFAULT; + RTC_InitStruct->SynchPrescaler = RTC_SYNCH_PRESC_DEFAULT; +} + +/** + * @brief Set the RTC current time. + * @param RTCx RTC Instance + * @param RTC_Format This parameter can be one of the following values: + * @arg @ref LL_RTC_FORMAT_BIN + * @arg @ref LL_RTC_FORMAT_BCD + * @param RTC_TimeStruct pointer to a RTC_TimeTypeDef structure that contains + * the time configuration information for the RTC. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC Time register is configured + * - ERROR: RTC Time register is not configured + */ +ErrorStatus LL_RTC_TIME_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_TimeTypeDef *RTC_TimeStruct) +{ + ErrorStatus status = ERROR; + + /* Check the parameters */ + assert_param(IS_RTC_ALL_INSTANCE(RTCx)); + assert_param(IS_LL_RTC_FORMAT(RTC_Format)); + + if (RTC_Format == LL_RTC_FORMAT_BIN) + { + if (LL_RTC_GetHourFormat(RTCx) != LL_RTC_HOURFORMAT_24HOUR) + { + assert_param(IS_LL_RTC_HOUR12(RTC_TimeStruct->Hours)); + assert_param(IS_LL_RTC_TIME_FORMAT(RTC_TimeStruct->TimeFormat)); + } + else + { + RTC_TimeStruct->TimeFormat = 0x00U; + assert_param(IS_LL_RTC_HOUR24(RTC_TimeStruct->Hours)); + } + assert_param(IS_LL_RTC_MINUTES(RTC_TimeStruct->Minutes)); + assert_param(IS_LL_RTC_SECONDS(RTC_TimeStruct->Seconds)); + } + else + { + if (LL_RTC_GetHourFormat(RTCx) != LL_RTC_HOURFORMAT_24HOUR) + { + assert_param(IS_LL_RTC_HOUR12(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Hours))); + assert_param(IS_LL_RTC_TIME_FORMAT(RTC_TimeStruct->TimeFormat)); + } + else + { + RTC_TimeStruct->TimeFormat = 0U; + assert_param(IS_LL_RTC_HOUR24(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Hours))); + } + assert_param(IS_LL_RTC_MINUTES(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Minutes))); + assert_param(IS_LL_RTC_SECONDS(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Seconds))); + } + + /* Disable the write protection for RTC registers */ + LL_RTC_DisableWriteProtection(RTCx); + + /* Set Initialization mode */ + if (LL_RTC_EnterInitMode(RTCx) != ERROR) + { + /* Check the input parameters format */ + if (RTC_Format != LL_RTC_FORMAT_BIN) + { + LL_RTC_TIME_Config(RTCx, RTC_TimeStruct->TimeFormat, RTC_TimeStruct->Hours, + RTC_TimeStruct->Minutes, RTC_TimeStruct->Seconds); + } + else + { + LL_RTC_TIME_Config(RTCx, RTC_TimeStruct->TimeFormat, __LL_RTC_CONVERT_BIN2BCD(RTC_TimeStruct->Hours), + __LL_RTC_CONVERT_BIN2BCD(RTC_TimeStruct->Minutes), + __LL_RTC_CONVERT_BIN2BCD(RTC_TimeStruct->Seconds)); + } + + /* Exit Initialization mode */ + LL_RTC_DisableInitMode(RTCx); + + /* If RTC_CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */ + if (LL_RTC_IsShadowRegBypassEnabled(RTCx) == 0U) + { + status = LL_RTC_WaitForSynchro(RTCx); + } + else + { + status = SUCCESS; + } + } + /* Enable the write protection for RTC registers */ + LL_RTC_EnableWriteProtection(RTCx); + + return status; +} + +/** + * @brief Set each @ref LL_RTC_TimeTypeDef field to default value (Time = 00h:00min:00sec). + * @param RTC_TimeStruct pointer to a @ref LL_RTC_TimeTypeDef structure which will be initialized. + * @retval None + */ +void LL_RTC_TIME_StructInit(LL_RTC_TimeTypeDef *RTC_TimeStruct) +{ + /* Time = 00h:00min:00sec */ + RTC_TimeStruct->TimeFormat = LL_RTC_TIME_FORMAT_AM_OR_24; + RTC_TimeStruct->Hours = 0U; + RTC_TimeStruct->Minutes = 0U; + RTC_TimeStruct->Seconds = 0U; +} + +/** + * @brief Set the RTC current date. + * @param RTCx RTC Instance + * @param RTC_Format This parameter can be one of the following values: + * @arg @ref LL_RTC_FORMAT_BIN + * @arg @ref LL_RTC_FORMAT_BCD + * @param RTC_DateStruct: pointer to a RTC_DateTypeDef structure that contains + * the date configuration information for the RTC. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC Day register is configured + * - ERROR: RTC Day register is not configured + */ +ErrorStatus LL_RTC_DATE_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_DateTypeDef *RTC_DateStruct) +{ + ErrorStatus status = ERROR; + + /* Check the parameters */ + assert_param(IS_RTC_ALL_INSTANCE(RTCx)); + assert_param(IS_LL_RTC_FORMAT(RTC_Format)); + + if ((RTC_Format == LL_RTC_FORMAT_BIN) && ((RTC_DateStruct->Month & 0x10U) == 0x10U)) + { + RTC_DateStruct->Month = (uint8_t)((uint32_t) RTC_DateStruct->Month & (uint32_t)~(0x10U)) + 0x0AU; + } + if (RTC_Format == LL_RTC_FORMAT_BIN) + { + assert_param(IS_LL_RTC_YEAR(RTC_DateStruct->Year)); + assert_param(IS_LL_RTC_MONTH(RTC_DateStruct->Month)); + assert_param(IS_LL_RTC_DAY(RTC_DateStruct->Day)); + } + else + { + assert_param(IS_LL_RTC_YEAR(__LL_RTC_CONVERT_BCD2BIN(RTC_DateStruct->Year))); + assert_param(IS_LL_RTC_MONTH(__LL_RTC_CONVERT_BCD2BIN(RTC_DateStruct->Month))); + assert_param(IS_LL_RTC_DAY(__LL_RTC_CONVERT_BCD2BIN(RTC_DateStruct->Day))); + } + assert_param(IS_LL_RTC_WEEKDAY(RTC_DateStruct->WeekDay)); + + /* Disable the write protection for RTC registers */ + LL_RTC_DisableWriteProtection(RTCx); + + /* Set Initialization mode */ + if (LL_RTC_EnterInitMode(RTCx) != ERROR) + { + /* Check the input parameters format */ + if (RTC_Format != LL_RTC_FORMAT_BIN) + { + LL_RTC_DATE_Config(RTCx, RTC_DateStruct->WeekDay, RTC_DateStruct->Day, RTC_DateStruct->Month, + RTC_DateStruct->Year); + } + else + { + LL_RTC_DATE_Config(RTCx, RTC_DateStruct->WeekDay, __LL_RTC_CONVERT_BIN2BCD(RTC_DateStruct->Day), + __LL_RTC_CONVERT_BIN2BCD(RTC_DateStruct->Month), + __LL_RTC_CONVERT_BIN2BCD(RTC_DateStruct->Year)); + } + + /* Exit Initialization mode */ + LL_RTC_DisableInitMode(RTCx); + + /* If RTC_CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */ + if (LL_RTC_IsShadowRegBypassEnabled(RTCx) == 0U) + { + status = LL_RTC_WaitForSynchro(RTCx); + } + else + { + status = SUCCESS; + } + } + /* Enable the write protection for RTC registers */ + LL_RTC_EnableWriteProtection(RTCx); + + return status; +} + +/** + * @brief Set each @ref LL_RTC_DateTypeDef field to default value (date = Monday, January 01 xx00) + * @param RTC_DateStruct pointer to a @ref LL_RTC_DateTypeDef structure which will be initialized. + * @retval None + */ +void LL_RTC_DATE_StructInit(LL_RTC_DateTypeDef *RTC_DateStruct) +{ + /* Monday, January 01 xx00 */ + RTC_DateStruct->WeekDay = LL_RTC_WEEKDAY_MONDAY; + RTC_DateStruct->Day = 1U; + RTC_DateStruct->Month = LL_RTC_MONTH_JANUARY; + RTC_DateStruct->Year = 0U; +} + +/** + * @brief Set the RTC Alarm A. + * @note The Alarm register can only be written when the corresponding Alarm + * is disabled (Use @ref LL_RTC_ALMA_Disable function). + * @param RTCx RTC Instance + * @param RTC_Format This parameter can be one of the following values: + * @arg @ref LL_RTC_FORMAT_BIN + * @arg @ref LL_RTC_FORMAT_BCD + * @param RTC_AlarmStruct pointer to a @ref LL_RTC_AlarmTypeDef structure that + * contains the alarm configuration parameters. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: ALARMA registers are configured + * - ERROR: ALARMA registers are not configured + */ +ErrorStatus LL_RTC_ALMA_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_AlarmTypeDef *RTC_AlarmStruct) +{ + /* Check the parameters */ + assert_param(IS_RTC_ALL_INSTANCE(RTCx)); + assert_param(IS_LL_RTC_FORMAT(RTC_Format)); + assert_param(IS_LL_RTC_ALMA_MASK(RTC_AlarmStruct->AlarmMask)); + assert_param(IS_LL_RTC_ALMA_DATE_WEEKDAY_SEL(RTC_AlarmStruct->AlarmDateWeekDaySel)); + + if (RTC_Format == LL_RTC_FORMAT_BIN) + { + if (LL_RTC_GetHourFormat(RTCx) != LL_RTC_HOURFORMAT_24HOUR) + { + assert_param(IS_LL_RTC_HOUR12(RTC_AlarmStruct->AlarmTime.Hours)); + assert_param(IS_LL_RTC_TIME_FORMAT(RTC_AlarmStruct->AlarmTime.TimeFormat)); + } + else + { + RTC_AlarmStruct->AlarmTime.TimeFormat = 0x00U; + assert_param(IS_LL_RTC_HOUR24(RTC_AlarmStruct->AlarmTime.Hours)); + } + assert_param(IS_LL_RTC_MINUTES(RTC_AlarmStruct->AlarmTime.Minutes)); + assert_param(IS_LL_RTC_SECONDS(RTC_AlarmStruct->AlarmTime.Seconds)); + + if (RTC_AlarmStruct->AlarmDateWeekDaySel == LL_RTC_ALMA_DATEWEEKDAYSEL_DATE) + { + assert_param(IS_LL_RTC_DAY(RTC_AlarmStruct->AlarmDateWeekDay)); + } + else + { + assert_param(IS_LL_RTC_WEEKDAY(RTC_AlarmStruct->AlarmDateWeekDay)); + } + } + else + { + if (LL_RTC_GetHourFormat(RTCx) != LL_RTC_HOURFORMAT_24HOUR) + { + assert_param(IS_LL_RTC_HOUR12(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Hours))); + assert_param(IS_LL_RTC_TIME_FORMAT(RTC_AlarmStruct->AlarmTime.TimeFormat)); + } + else + { + RTC_AlarmStruct->AlarmTime.TimeFormat = 0x00U; + assert_param(IS_LL_RTC_HOUR24(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Hours))); + } + + assert_param(IS_LL_RTC_MINUTES(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Minutes))); + assert_param(IS_LL_RTC_SECONDS(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Seconds))); + + if (RTC_AlarmStruct->AlarmDateWeekDaySel == LL_RTC_ALMA_DATEWEEKDAYSEL_DATE) + { + assert_param(IS_LL_RTC_DAY(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmDateWeekDay))); + } + else + { + assert_param(IS_LL_RTC_WEEKDAY(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmDateWeekDay))); + } + } + + /* Disable the write protection for RTC registers */ + LL_RTC_DisableWriteProtection(RTCx); + + /* Select weekday selection */ + if (RTC_AlarmStruct->AlarmDateWeekDaySel == LL_RTC_ALMA_DATEWEEKDAYSEL_DATE) + { + /* Set the date for ALARM */ + LL_RTC_ALMA_DisableWeekday(RTCx); + if (RTC_Format != LL_RTC_FORMAT_BIN) + { + LL_RTC_ALMA_SetDay(RTCx, RTC_AlarmStruct->AlarmDateWeekDay); + } + else + { + LL_RTC_ALMA_SetDay(RTCx, __LL_RTC_CONVERT_BIN2BCD(RTC_AlarmStruct->AlarmDateWeekDay)); + } + } + else + { + /* Set the week day for ALARM */ + LL_RTC_ALMA_EnableWeekday(RTCx); + LL_RTC_ALMA_SetWeekDay(RTCx, RTC_AlarmStruct->AlarmDateWeekDay); + } + + /* Configure the Alarm register */ + if (RTC_Format != LL_RTC_FORMAT_BIN) + { + LL_RTC_ALMA_ConfigTime(RTCx, RTC_AlarmStruct->AlarmTime.TimeFormat, RTC_AlarmStruct->AlarmTime.Hours, + RTC_AlarmStruct->AlarmTime.Minutes, RTC_AlarmStruct->AlarmTime.Seconds); + } + else + { + LL_RTC_ALMA_ConfigTime(RTCx, RTC_AlarmStruct->AlarmTime.TimeFormat, + __LL_RTC_CONVERT_BIN2BCD(RTC_AlarmStruct->AlarmTime.Hours), + __LL_RTC_CONVERT_BIN2BCD(RTC_AlarmStruct->AlarmTime.Minutes), + __LL_RTC_CONVERT_BIN2BCD(RTC_AlarmStruct->AlarmTime.Seconds)); + } + /* Set ALARM mask */ + LL_RTC_ALMA_SetMask(RTCx, RTC_AlarmStruct->AlarmMask); + + /* Enable the write protection for RTC registers */ + LL_RTC_EnableWriteProtection(RTCx); + + return SUCCESS; +} + +/** + * @brief Set the RTC Alarm B. + * @note The Alarm register can only be written when the corresponding Alarm + * is disabled (@ref LL_RTC_ALMB_Disable function). + * @param RTCx RTC Instance + * @param RTC_Format This parameter can be one of the following values: + * @arg @ref LL_RTC_FORMAT_BIN + * @arg @ref LL_RTC_FORMAT_BCD + * @param RTC_AlarmStruct pointer to a @ref LL_RTC_AlarmTypeDef structure that + * contains the alarm configuration parameters. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: ALARMB registers are configured + * - ERROR: ALARMB registers are not configured + */ +ErrorStatus LL_RTC_ALMB_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_AlarmTypeDef *RTC_AlarmStruct) +{ + /* Check the parameters */ + assert_param(IS_RTC_ALL_INSTANCE(RTCx)); + assert_param(IS_LL_RTC_FORMAT(RTC_Format)); + assert_param(IS_LL_RTC_ALMB_MASK(RTC_AlarmStruct->AlarmMask)); + assert_param(IS_LL_RTC_ALMB_DATE_WEEKDAY_SEL(RTC_AlarmStruct->AlarmDateWeekDaySel)); + + if (RTC_Format == LL_RTC_FORMAT_BIN) + { + if (LL_RTC_GetHourFormat(RTCx) != LL_RTC_HOURFORMAT_24HOUR) + { + assert_param(IS_LL_RTC_HOUR12(RTC_AlarmStruct->AlarmTime.Hours)); + assert_param(IS_LL_RTC_TIME_FORMAT(RTC_AlarmStruct->AlarmTime.TimeFormat)); + } + else + { + RTC_AlarmStruct->AlarmTime.TimeFormat = 0x00U; + assert_param(IS_LL_RTC_HOUR24(RTC_AlarmStruct->AlarmTime.Hours)); + } + assert_param(IS_LL_RTC_MINUTES(RTC_AlarmStruct->AlarmTime.Minutes)); + assert_param(IS_LL_RTC_SECONDS(RTC_AlarmStruct->AlarmTime.Seconds)); + + if (RTC_AlarmStruct->AlarmDateWeekDaySel == LL_RTC_ALMB_DATEWEEKDAYSEL_DATE) + { + assert_param(IS_LL_RTC_DAY(RTC_AlarmStruct->AlarmDateWeekDay)); + } + else + { + assert_param(IS_LL_RTC_WEEKDAY(RTC_AlarmStruct->AlarmDateWeekDay)); + } + } + else + { + if (LL_RTC_GetHourFormat(RTCx) != LL_RTC_HOURFORMAT_24HOUR) + { + assert_param(IS_LL_RTC_HOUR12(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Hours))); + assert_param(IS_LL_RTC_TIME_FORMAT(RTC_AlarmStruct->AlarmTime.TimeFormat)); + } + else + { + RTC_AlarmStruct->AlarmTime.TimeFormat = 0x00U; + assert_param(IS_LL_RTC_HOUR24(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Hours))); + } + + assert_param(IS_LL_RTC_MINUTES(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Minutes))); + assert_param(IS_LL_RTC_SECONDS(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Seconds))); + + if (RTC_AlarmStruct->AlarmDateWeekDaySel == LL_RTC_ALMB_DATEWEEKDAYSEL_DATE) + { + assert_param(IS_LL_RTC_DAY(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmDateWeekDay))); + } + else + { + assert_param(IS_LL_RTC_WEEKDAY(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmDateWeekDay))); + } + } + + /* Disable the write protection for RTC registers */ + LL_RTC_DisableWriteProtection(RTCx); + + /* Select weekday selection */ + if (RTC_AlarmStruct->AlarmDateWeekDaySel == LL_RTC_ALMB_DATEWEEKDAYSEL_DATE) + { + /* Set the date for ALARM */ + LL_RTC_ALMB_DisableWeekday(RTCx); + if (RTC_Format != LL_RTC_FORMAT_BIN) + { + LL_RTC_ALMB_SetDay(RTCx, RTC_AlarmStruct->AlarmDateWeekDay); + } + else + { + LL_RTC_ALMB_SetDay(RTCx, __LL_RTC_CONVERT_BIN2BCD(RTC_AlarmStruct->AlarmDateWeekDay)); + } + } + else + { + /* Set the week day for ALARM */ + LL_RTC_ALMB_EnableWeekday(RTCx); + LL_RTC_ALMB_SetWeekDay(RTCx, RTC_AlarmStruct->AlarmDateWeekDay); + } + + /* Configure the Alarm register */ + if (RTC_Format != LL_RTC_FORMAT_BIN) + { + LL_RTC_ALMB_ConfigTime(RTCx, RTC_AlarmStruct->AlarmTime.TimeFormat, RTC_AlarmStruct->AlarmTime.Hours, + RTC_AlarmStruct->AlarmTime.Minutes, RTC_AlarmStruct->AlarmTime.Seconds); + } + else + { + LL_RTC_ALMB_ConfigTime(RTCx, RTC_AlarmStruct->AlarmTime.TimeFormat, + __LL_RTC_CONVERT_BIN2BCD(RTC_AlarmStruct->AlarmTime.Hours), + __LL_RTC_CONVERT_BIN2BCD(RTC_AlarmStruct->AlarmTime.Minutes), + __LL_RTC_CONVERT_BIN2BCD(RTC_AlarmStruct->AlarmTime.Seconds)); + } + /* Set ALARM mask */ + LL_RTC_ALMB_SetMask(RTCx, RTC_AlarmStruct->AlarmMask); + + /* Enable the write protection for RTC registers */ + LL_RTC_EnableWriteProtection(RTCx); + + return SUCCESS; +} + +/** + * @brief Set each @ref LL_RTC_AlarmTypeDef of ALARMA field to default value (Time = 00h:00mn:00sec / + * Day = 1st day of the month/Mask = all fields are masked). + * @param RTC_AlarmStruct pointer to a @ref LL_RTC_AlarmTypeDef structure which will be initialized. + * @retval None + */ +void LL_RTC_ALMA_StructInit(LL_RTC_AlarmTypeDef *RTC_AlarmStruct) +{ + /* Alarm Time Settings : Time = 00h:00mn:00sec */ + RTC_AlarmStruct->AlarmTime.TimeFormat = LL_RTC_ALMA_TIME_FORMAT_AM; + RTC_AlarmStruct->AlarmTime.Hours = 0U; + RTC_AlarmStruct->AlarmTime.Minutes = 0U; + RTC_AlarmStruct->AlarmTime.Seconds = 0U; + + /* Alarm Day Settings : Day = 1st day of the month */ + RTC_AlarmStruct->AlarmDateWeekDaySel = LL_RTC_ALMA_DATEWEEKDAYSEL_DATE; + RTC_AlarmStruct->AlarmDateWeekDay = 1U; + + /* Alarm Masks Settings : Mask = all fields are not masked */ + RTC_AlarmStruct->AlarmMask = LL_RTC_ALMA_MASK_NONE; +} + +/** + * @brief Set each @ref LL_RTC_AlarmTypeDef of ALARMA field to default value (Time = 00h:00mn:00sec / + * Day = 1st day of the month/Mask = all fields are masked). + * @param RTC_AlarmStruct pointer to a @ref LL_RTC_AlarmTypeDef structure which will be initialized. + * @retval None + */ +void LL_RTC_ALMB_StructInit(LL_RTC_AlarmTypeDef *RTC_AlarmStruct) +{ + /* Alarm Time Settings : Time = 00h:00mn:00sec */ + RTC_AlarmStruct->AlarmTime.TimeFormat = LL_RTC_ALMB_TIME_FORMAT_AM; + RTC_AlarmStruct->AlarmTime.Hours = 0U; + RTC_AlarmStruct->AlarmTime.Minutes = 0U; + RTC_AlarmStruct->AlarmTime.Seconds = 0U; + + /* Alarm Day Settings : Day = 1st day of the month */ + RTC_AlarmStruct->AlarmDateWeekDaySel = LL_RTC_ALMB_DATEWEEKDAYSEL_DATE; + RTC_AlarmStruct->AlarmDateWeekDay = 1U; + + /* Alarm Masks Settings : Mask = all fields are not masked */ + RTC_AlarmStruct->AlarmMask = LL_RTC_ALMB_MASK_NONE; +} + +/** + * @brief Enters the RTC Initialization mode. + * @note The RTC Initialization mode is write protected, use the + * @ref LL_RTC_DisableWriteProtection before calling this function. + * @param RTCx RTC Instance + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC is in Init mode + * - ERROR: RTC is not in Init mode + */ +ErrorStatus LL_RTC_EnterInitMode(RTC_TypeDef *RTCx) +{ + __IO uint32_t timeout = RTC_INITMODE_TIMEOUT; + ErrorStatus status = SUCCESS; + uint32_t tmp; + + /* Check the parameter */ + assert_param(IS_RTC_ALL_INSTANCE(RTCx)); + + /* Check if the Initialization mode is set */ + if (LL_RTC_IsActiveFlag_INIT(RTCx) == 0U) + { + /* Set the Initialization mode */ + LL_RTC_EnableInitMode(RTCx); + + /* Wait till RTC is in INIT state and if Time out is reached exit */ + tmp = LL_RTC_IsActiveFlag_INIT(RTCx); + while ((timeout != 0U) && (tmp != 1U)) + { + if (LL_SYSTICK_IsActiveCounterFlag() == 1U) + { + timeout --; + } + tmp = LL_RTC_IsActiveFlag_INIT(RTCx); + if (timeout == 0U) + { + status = ERROR; + } + } + } + return status; +} + +/** + * @brief Exit the RTC Initialization mode. + * @note When the initialization sequence is complete, the calendar restarts + * counting after 4 RTCCLK cycles. + * @note The RTC Initialization mode is write protected, use the + * @ref LL_RTC_DisableWriteProtection before calling this function. + * @param RTCx RTC Instance + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC exited from in Init mode + * - ERROR: Not applicable + */ +ErrorStatus LL_RTC_ExitInitMode(RTC_TypeDef *RTCx) +{ + /* Check the parameter */ + assert_param(IS_RTC_ALL_INSTANCE(RTCx)); + + /* Disable initialization mode */ + LL_RTC_DisableInitMode(RTCx); + + return SUCCESS; +} + +/** + * @brief Waits until the RTC Time and Day registers (RTC_TR and RTC_DR) are + * synchronized with RTC APB clock. + * @note The RTC Resynchronization mode is write protected, use the + * @ref LL_RTC_DisableWriteProtection before calling this function. + * @note To read the calendar through the shadow registers after Calendar + * initialization, calendar update or after wakeup from low power modes + * the software must first clear the RSF flag. + * The software must then wait until it is set again before reading + * the calendar, which means that the calendar registers have been + * correctly copied into the RTC_TR and RTC_DR shadow registers. + * @param RTCx RTC Instance + * @retval An ErrorStatus enumeration value: + * - SUCCESS: RTC registers are synchronised + * - ERROR: RTC registers are not synchronised + */ +ErrorStatus LL_RTC_WaitForSynchro(RTC_TypeDef *RTCx) +{ + __IO uint32_t timeout = RTC_SYNCHRO_TIMEOUT; + uint32_t tmp; + ErrorStatus status = SUCCESS; + + /* Check the parameter */ + assert_param(IS_RTC_ALL_INSTANCE(RTCx)); + + /* Clear RSF flag */ + LL_RTC_ClearFlag_RS(RTCx); + + /* Wait the registers to be synchronised */ + tmp = LL_RTC_IsActiveFlag_RS(RTCx); + while ((timeout != 0U) && (tmp != 1U)) + { + if (LL_SYSTICK_IsActiveCounterFlag() == 1U) + { + timeout--; + } + tmp = LL_RTC_IsActiveFlag_RS(RTCx); + } + + if (timeout == 0U) + { + status = ERROR; + } + + return status; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined(RTC) */ + +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_sdmmc.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_sdmmc.c new file mode 100644 index 0000000000..5ecc55c77b --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_sdmmc.c @@ -0,0 +1,1883 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_sdmmc.c + * @author MCD Application Team + * @brief SDMMC Low Layer HAL module driver. + * + * This file provides firmware functions to manage the following + * functionalities of the SDMMC peripheral: + * + Initialization/de-initialization functions + * + I/O operation functions + * + Peripheral Control functions + * + Peripheral State functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### SDMMC peripheral features ##### + ============================================================================== + [..] The SD/SDMMC MMC card host interface (SDMMC) provides an interface between the AHB + peripheral bus and MultiMedia cards (MMCs), SD memory cards, SDMMC cards and CE-ATA + devices. + + [..] The SDMMC features include the following: + (+) Full compliance with MultiMediaCard System Specification Version 4.51. Card support + for three different databus modes: 1-bit (default), 4-bit and 8-bit. + (+) Full compatibility with previous versions of MultiMediaCards (backward compatibility). + (+) Full compliance with SD memory card specifications version 4.1. + (SDR104 SDMMC_CK speed limited to maximum allowed IO speed, SPI mode and + UHS-II mode not supported). + (+) Full compliance with SDIO card specification version 4.0. Card support + for two different databus modes: 1-bit (default) and 4-bit. + (SDR104 SDMMC_CK speed limited to maximum allowed IO speed, SPI mode and + UHS-II mode not supported). + (+) Data transfer up to 208 Mbyte/s for the 8 bit mode. (depending maximum allowed IO speed). + (+) Data and command output enable signals to control external bidirectional drivers + + ##### How to use this driver ##### + ============================================================================== + [..] + This driver is a considered as a driver of service for external devices drivers + that interfaces with the SDMMC peripheral. + According to the device used (SD card/ MMC card / SDMMC card ...), a set of APIs + is used in the device's driver to perform SDMMC operations and functionalities. + + This driver is almost transparent for the final user, it is only used to implement other + functionalities of the external device. + + [..] + (+) The SDMMC clock is coming from output of PLL1_Q or PLL2_R. + Before start working with SDMMC peripheral make sure that the PLL is well configured. + The SDMMC peripheral uses two clock signals: + (++) PLL1_Q bus clock (default after reset) + (++) PLL2_R bus clock + + (+) Enable/Disable peripheral clock using RCC peripheral macros related to SDMMC + peripheral. + + (+) Enable the Power ON State using the SDMMC_PowerState_ON(SDMMCx) + function and disable it using the function SDMMC_PowerState_OFF(SDMMCx). + + (+) Enable/Disable the peripheral interrupts using the macros __SDMMC_ENABLE_IT(hSDMMC, IT) + and __SDMMC_DISABLE_IT(hSDMMC, IT) if you need to use interrupt mode. + + (+) When using the DMA mode + (++) Configure the IDMA mode (Single buffer or double) + (++) Configure the buffer address + (++) Configure Data Path State Machine + + (+) To control the CPSM (Command Path State Machine) and send + commands to the card use the SDMMC_SendCommand(SDMMCx), + SDMMC_GetCommandResponse() and SDMMC_GetResponse() functions. First, user has + to fill the command structure (pointer to SDMMC_CmdInitTypeDef) according + to the selected command to be sent. + The parameters that should be filled are: + (++) Command Argument + (++) Command Index + (++) Command Response type + (++) Command Wait + (++) CPSM Status (Enable or Disable). + + -@@- To check if the command is well received, read the SDMMC_CMDRESP + register using the SDMMC_GetCommandResponse(). + The SDMMC responses registers (SDMMC_RESP1 to SDMMC_RESP2), use the + SDMMC_GetResponse() function. + + (+) To control the DPSM (Data Path State Machine) and send/receive + data to/from the card use the SDMMC_DataConfig(), SDMMC_GetDataCounter(), + SDMMC_ReadFIFO(), SDMMC_WriteFIFO() and SDMMC_GetFIFOCount() functions. + + *** Read Operations *** + ======================= + [..] + (#) First, user has to fill the data structure (pointer to + SDMMC_DataInitTypeDef) according to the selected data type to be received. + The parameters that should be filled are: + (++) Data TimeOut + (++) Data Length + (++) Data Block size + (++) Data Transfer direction: should be from card (To SDMMC) + (++) Data Transfer mode + (++) DPSM Status (Enable or Disable) + + (#) Configure the SDMMC resources to receive the data from the card + according to selected transfer mode (Refer to Step 8, 9 and 10). + + (#) Send the selected Read command (refer to step 11). + + (#) Use the SDMMC flags/interrupts to check the transfer status. + + *** Write Operations *** + ======================== + [..] + (#) First, user has to fill the data structure (pointer to + SDMMC_DataInitTypeDef) according to the selected data type to be received. + The parameters that should be filled are: + (++) Data TimeOut + (++) Data Length + (++) Data Block size + (++) Data Transfer direction: should be to card (To CARD) + (++) Data Transfer mode + (++) DPSM Status (Enable or Disable) + + (#) Configure the SDMMC resources to send the data to the card according to + selected transfer mode. + + (#) Send the selected Write command. + + (#) Use the SDMMC flags/interrupts to check the transfer status. + + *** Command management operations *** + ===================================== + [..] + (#) The commands used for Read/Write/Erase operations are managed in + separate functions. + Each function allows to send the needed command with the related argument, + then check the response. + By the same approach, you could implement a command and check the response. + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_HAL_Driver + * @{ + */ + +/** @defgroup SDMMC_LL SDMMC Low Layer + * @brief Low layer module for SD + * @{ + */ + +#if defined (SDMMC1) || defined (SDMMC2) +#if defined (HAL_SD_MODULE_ENABLED) || defined (HAL_MMC_MODULE_ENABLED) + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +static uint32_t SDMMC_GetCmdError(SDMMC_TypeDef *SDMMCx); + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup SDMMC_LL_Exported_Functions SDMMC Low Layer Exported Functions + * @{ + */ + +/** @defgroup HAL_SDMMC_LL_Group1 Initialization de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization/de-initialization functions ##### + =============================================================================== + [..] This section provides functions allowing to: + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the SDMMC according to the specified + * parameters in the SDMMC_InitTypeDef and create the associated handle. + * @param SDMMCx: Pointer to SDMMC register base + * @param Init: SDMMC initialization structure + * @retval HAL status + */ +HAL_StatusTypeDef SDMMC_Init(SDMMC_TypeDef *SDMMCx, SDMMC_InitTypeDef Init) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_SDMMC_ALL_INSTANCE(SDMMCx)); + assert_param(IS_SDMMC_CLOCK_EDGE(Init.ClockEdge)); + assert_param(IS_SDMMC_CLOCK_POWER_SAVE(Init.ClockPowerSave)); + assert_param(IS_SDMMC_BUS_WIDE(Init.BusWide)); + assert_param(IS_SDMMC_HARDWARE_FLOW_CONTROL(Init.HardwareFlowControl)); + assert_param(IS_SDMMC_CLKDIV(Init.ClockDiv)); + + /* Set SDMMC configuration parameters */ + tmpreg |= (Init.ClockEdge | \ + Init.ClockPowerSave | \ + Init.BusWide | \ + Init.HardwareFlowControl | \ + Init.ClockDiv + ); + + /* Write to SDMMC CLKCR */ + MODIFY_REG(SDMMCx->CLKCR, CLKCR_CLEAR_MASK, tmpreg); + + return HAL_OK; +} + + +/** + * @} + */ + +/** @defgroup HAL_SDMMC_LL_Group2 IO operation functions + * @brief Data transfers functions + * +@verbatim + =============================================================================== + ##### I/O operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the SDMMC data + transfers. + +@endverbatim + * @{ + */ + +/** + * @brief Read data (word) from Rx FIFO in blocking mode (polling) + * @param SDMMCx: Pointer to SDMMC register base + * @retval HAL status + */ +uint32_t SDMMC_ReadFIFO(const SDMMC_TypeDef *SDMMCx) +{ + /* Read data from Rx FIFO */ + return (SDMMCx->FIFO); +} + +/** + * @brief Write data (word) to Tx FIFO in blocking mode (polling) + * @param SDMMCx: Pointer to SDMMC register base + * @param pWriteData: pointer to data to write + * @retval HAL status + */ +HAL_StatusTypeDef SDMMC_WriteFIFO(SDMMC_TypeDef *SDMMCx, uint32_t *pWriteData) +{ + /* Write data to FIFO */ + SDMMCx->FIFO = *pWriteData; + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup HAL_SDMMC_LL_Group3 Peripheral Control functions + * @brief management functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the SDMMC data + transfers. + +@endverbatim + * @{ + */ + +/** + * @brief Set SDMMC Power state to ON. + * @param SDMMCx: Pointer to SDMMC register base + * @retval HAL status + */ +HAL_StatusTypeDef SDMMC_PowerState_ON(SDMMC_TypeDef *SDMMCx) +{ + /* Set power state to ON */ + SDMMCx->POWER |= SDMMC_POWER_PWRCTRL; + + return HAL_OK; +} + +/** + * @brief Set SDMMC Power state to Power-Cycle. + * @param SDMMCx: Pointer to SDMMC register base + * @retval HAL status + */ +HAL_StatusTypeDef SDMMC_PowerState_Cycle(SDMMC_TypeDef *SDMMCx) +{ + /* Set power state to Power Cycle*/ + SDMMCx->POWER |= SDMMC_POWER_PWRCTRL_1; + + return HAL_OK; +} + +/** + * @brief Set SDMMC Power state to OFF. + * @param SDMMCx: Pointer to SDMMC register base + * @retval HAL status + */ +HAL_StatusTypeDef SDMMC_PowerState_OFF(SDMMC_TypeDef *SDMMCx) +{ + /* Set power state to OFF */ + SDMMCx->POWER &= ~(SDMMC_POWER_PWRCTRL); + + return HAL_OK; +} + +/** + * @brief Get SDMMC Power state. + * @param SDMMCx: Pointer to SDMMC register base + * @retval Power status of the controller. The returned value can be one of the + * following values: + * - 0x00: Power OFF + * - 0x02: Power UP + * - 0x03: Power ON + */ +uint32_t SDMMC_GetPowerState(const SDMMC_TypeDef *SDMMCx) +{ + return (SDMMCx->POWER & SDMMC_POWER_PWRCTRL); +} + +/** + * @brief Configure the SDMMC command path according to the specified parameters in + * SDMMC_CmdInitTypeDef structure and send the command + * @param SDMMCx: Pointer to SDMMC register base + * @param Command: pointer to a SDMMC_CmdInitTypeDef structure that contains + * the configuration information for the SDMMC command + * @retval HAL status + */ +HAL_StatusTypeDef SDMMC_SendCommand(SDMMC_TypeDef *SDMMCx, SDMMC_CmdInitTypeDef *Command) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_SDMMC_CMD_INDEX(Command->CmdIndex)); + assert_param(IS_SDMMC_RESPONSE(Command->Response)); + assert_param(IS_SDMMC_WAIT(Command->WaitForInterrupt)); + assert_param(IS_SDMMC_CPSM(Command->CPSM)); + + /* Set the SDMMC Argument value */ + SDMMCx->ARG = Command->Argument; + + /* Set SDMMC command parameters */ + tmpreg |= (uint32_t)(Command->CmdIndex | \ + Command->Response | \ + Command->WaitForInterrupt | \ + Command->CPSM); + + /* Write to SDMMC CMD register */ + MODIFY_REG(SDMMCx->CMD, CMD_CLEAR_MASK, tmpreg); + + return HAL_OK; +} + +/** + * @brief Return the command index of last command for which response received + * @param SDMMCx: Pointer to SDMMC register base + * @retval Command index of the last command response received + */ +uint8_t SDMMC_GetCommandResponse(const SDMMC_TypeDef *SDMMCx) +{ + return (uint8_t)(SDMMCx->RESPCMD); +} + + +/** + * @brief Return the response received from the card for the last command + * @param SDMMCx: Pointer to SDMMC register base + * @param Response: Specifies the SDMMC response register. + * This parameter can be one of the following values: + * @arg SDMMC_RESP1: Response Register 1 + * @arg SDMMC_RESP2: Response Register 2 + * @arg SDMMC_RESP3: Response Register 3 + * @arg SDMMC_RESP4: Response Register 4 + * @retval The Corresponding response register value + */ +uint32_t SDMMC_GetResponse(const SDMMC_TypeDef *SDMMCx, uint32_t Response) +{ + uint32_t tmp; + + /* Check the parameters */ + assert_param(IS_SDMMC_RESP(Response)); + + /* Get the response */ + tmp = (uint32_t)(&(SDMMCx->RESP1)) + Response; + + return (*(__IO uint32_t *) tmp); +} + +/** + * @brief Configure the SDMMC data path according to the specified + * parameters in the SDMMC_DataInitTypeDef. + * @param SDMMCx: Pointer to SDMMC register base + * @param Data : pointer to a SDMMC_DataInitTypeDef structure + * that contains the configuration information for the SDMMC data. + * @retval HAL status + */ +HAL_StatusTypeDef SDMMC_ConfigData(SDMMC_TypeDef *SDMMCx, SDMMC_DataInitTypeDef *Data) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_SDMMC_DATA_LENGTH(Data->DataLength)); + assert_param(IS_SDMMC_BLOCK_SIZE(Data->DataBlockSize)); + assert_param(IS_SDMMC_TRANSFER_DIR(Data->TransferDir)); + assert_param(IS_SDMMC_TRANSFER_MODE(Data->TransferMode)); + assert_param(IS_SDMMC_DPSM(Data->DPSM)); + + /* Set the SDMMC Data TimeOut value */ + SDMMCx->DTIMER = Data->DataTimeOut; + + /* Set the SDMMC DataLength value */ + SDMMCx->DLEN = Data->DataLength; + + /* Set the SDMMC data configuration parameters */ + tmpreg |= (uint32_t)(Data->DataBlockSize | \ + Data->TransferDir | \ + Data->TransferMode | \ + Data->DPSM); + + /* Write to SDMMC DCTRL */ + MODIFY_REG(SDMMCx->DCTRL, DCTRL_CLEAR_MASK, tmpreg); + + return HAL_OK; + +} + +/** + * @brief Returns number of remaining data bytes to be transferred. + * @param SDMMCx: Pointer to SDMMC register base + * @retval Number of remaining data bytes to be transferred + */ +uint32_t SDMMC_GetDataCounter(const SDMMC_TypeDef *SDMMCx) +{ + return (SDMMCx->DCOUNT); +} + +/** + * @brief Get the FIFO data + * @param SDMMCx: Pointer to SDMMC register base + * @retval Data received + */ +uint32_t SDMMC_GetFIFOCount(const SDMMC_TypeDef *SDMMCx) +{ + return (SDMMCx->FIFO); +} + +/** + * @brief Sets one of the two options of inserting read wait interval. + * @param SDMMCx: Pointer to SDMMC register base + * @param SDMMC_ReadWaitMode: SDMMC Read Wait operation mode. + * This parameter can be: + * @arg SDMMC_READ_WAIT_MODE_CLK: Read Wait control by stopping SDMMCCLK + * @arg SDMMC_READ_WAIT_MODE_DATA2: Read Wait control using SDMMC_DATA2 + * @retval None + */ +HAL_StatusTypeDef SDMMC_SetSDMMCReadWaitMode(SDMMC_TypeDef *SDMMCx, uint32_t SDMMC_ReadWaitMode) +{ + /* Check the parameters */ + assert_param(IS_SDMMC_READWAIT_MODE(SDMMC_ReadWaitMode)); + + /* Set SDMMC read wait mode */ + MODIFY_REG(SDMMCx->DCTRL, SDMMC_DCTRL_RWMOD, SDMMC_ReadWaitMode); + + return HAL_OK; +} + +/** + * @} + */ + + +/** @defgroup HAL_SDMMC_LL_Group4 Command management functions + * @brief Data transfers functions + * +@verbatim + =============================================================================== + ##### Commands management functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the needed commands. + +@endverbatim + * @{ + */ + +/** + * @brief Send the Data Block Length command and check the response + * @param SDMMCx: Pointer to SDMMC register base + * @retval HAL status + */ +uint32_t SDMMC_CmdBlockLength(SDMMC_TypeDef *SDMMCx, uint32_t BlockSize) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + /* Set Block Size for Card */ + sdmmc_cmdinit.Argument = (uint32_t)BlockSize; + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SET_BLOCKLEN; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SET_BLOCKLEN, SDMMC_CMDTIMEOUT); + + return errorstate; +} + +/** + * @brief Send the Read Single Block command and check the response + * @param SDMMCx: Pointer to SDMMC register base + * @retval HAL status + */ +uint32_t SDMMC_CmdReadSingleBlock(SDMMC_TypeDef *SDMMCx, uint32_t ReadAdd) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + /* Set Block Size for Card */ + sdmmc_cmdinit.Argument = (uint32_t)ReadAdd; + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_READ_SINGLE_BLOCK; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_READ_SINGLE_BLOCK, SDMMC_CMDTIMEOUT); + + return errorstate; +} + +/** + * @brief Send the Read Multi Block command and check the response + * @param SDMMCx: Pointer to SDMMC register base + * @retval HAL status + */ +uint32_t SDMMC_CmdReadMultiBlock(SDMMC_TypeDef *SDMMCx, uint32_t ReadAdd) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + /* Set Block Size for Card */ + sdmmc_cmdinit.Argument = (uint32_t)ReadAdd; + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_READ_MULT_BLOCK; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_READ_MULT_BLOCK, SDMMC_CMDTIMEOUT); + + return errorstate; +} + +/** + * @brief Send the Write Single Block command and check the response + * @param SDMMCx: Pointer to SDMMC register base + * @retval HAL status + */ +uint32_t SDMMC_CmdWriteSingleBlock(SDMMC_TypeDef *SDMMCx, uint32_t WriteAdd) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + /* Set Block Size for Card */ + sdmmc_cmdinit.Argument = (uint32_t)WriteAdd; + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_WRITE_SINGLE_BLOCK; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_WRITE_SINGLE_BLOCK, SDMMC_CMDTIMEOUT); + + return errorstate; +} + +/** + * @brief Send the Write Multi Block command and check the response + * @param SDMMCx: Pointer to SDMMC register base + * @retval HAL status + */ +uint32_t SDMMC_CmdWriteMultiBlock(SDMMC_TypeDef *SDMMCx, uint32_t WriteAdd) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + /* Set Block Size for Card */ + sdmmc_cmdinit.Argument = (uint32_t)WriteAdd; + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_WRITE_MULT_BLOCK; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_WRITE_MULT_BLOCK, SDMMC_CMDTIMEOUT); + + return errorstate; +} + +/** + * @brief Send the Start Address Erase command for SD and check the response + * @param SDMMCx: Pointer to SDMMC register base + * @retval HAL status + */ +uint32_t SDMMC_CmdSDEraseStartAdd(SDMMC_TypeDef *SDMMCx, uint32_t StartAdd) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + /* Set Block Size for Card */ + sdmmc_cmdinit.Argument = (uint32_t)StartAdd; + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_ERASE_GRP_START; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SD_ERASE_GRP_START, SDMMC_CMDTIMEOUT); + + return errorstate; +} + +/** + * @brief Send the End Address Erase command for SD and check the response + * @param SDMMCx: Pointer to SDMMC register base + * @retval HAL status + */ +uint32_t SDMMC_CmdSDEraseEndAdd(SDMMC_TypeDef *SDMMCx, uint32_t EndAdd) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + /* Set Block Size for Card */ + sdmmc_cmdinit.Argument = (uint32_t)EndAdd; + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_ERASE_GRP_END; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SD_ERASE_GRP_END, SDMMC_CMDTIMEOUT); + + return errorstate; +} + +/** + * @brief Send the Start Address Erase command and check the response + * @param SDMMCx: Pointer to SDMMC register base + * @retval HAL status + */ +uint32_t SDMMC_CmdEraseStartAdd(SDMMC_TypeDef *SDMMCx, uint32_t StartAdd) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + /* Set Block Size for Card */ + sdmmc_cmdinit.Argument = (uint32_t)StartAdd; + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ERASE_GRP_START; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_ERASE_GRP_START, SDMMC_CMDTIMEOUT); + + return errorstate; +} + +/** + * @brief Send the End Address Erase command and check the response + * @param SDMMCx: Pointer to SDMMC register base + * @retval HAL status + */ +uint32_t SDMMC_CmdEraseEndAdd(SDMMC_TypeDef *SDMMCx, uint32_t EndAdd) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + /* Set Block Size for Card */ + sdmmc_cmdinit.Argument = (uint32_t)EndAdd; + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ERASE_GRP_END; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_ERASE_GRP_END, SDMMC_CMDTIMEOUT); + + return errorstate; +} + +/** + * @brief Send the Erase command and check the response + * @param SDMMCx Pointer to SDMMC register base + * @param EraseType Type of erase to be performed + * @retval HAL status + */ +uint32_t SDMMC_CmdErase(SDMMC_TypeDef *SDMMCx, uint32_t EraseType) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + /* Set Block Size for Card */ + sdmmc_cmdinit.Argument = EraseType; + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ERASE; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_ERASE, SDMMC_MAXERASETIMEOUT); + + return errorstate; +} + +/** + * @brief Send the Stop Transfer command and check the response. + * @param SDMMCx: Pointer to SDMMC register base + * @retval HAL status + */ +uint32_t SDMMC_CmdStopTransfer(SDMMC_TypeDef *SDMMCx) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + /* Send CMD12 STOP_TRANSMISSION */ + sdmmc_cmdinit.Argument = 0U; + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_STOP_TRANSMISSION; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + + __SDMMC_CMDSTOP_ENABLE(SDMMCx); + __SDMMC_CMDTRANS_DISABLE(SDMMCx); + + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_STOP_TRANSMISSION, SDMMC_STOPTRANSFERTIMEOUT); + + __SDMMC_CMDSTOP_DISABLE(SDMMCx); + + /* Ignore Address Out Of Range Error, Not relevant at end of memory */ + if (errorstate == SDMMC_ERROR_ADDR_OUT_OF_RANGE) + { + errorstate = SDMMC_ERROR_NONE; + } + + return errorstate; +} + +/** + * @brief Send the Select Deselect command and check the response. + * @param SDMMCx: Pointer to SDMMC register base + * @param addr: Address of the card to be selected + * @retval HAL status + */ +uint32_t SDMMC_CmdSelDesel(SDMMC_TypeDef *SDMMCx, uint32_t Addr) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + /* Send CMD7 SDMMC_SEL_DESEL_CARD */ + sdmmc_cmdinit.Argument = (uint32_t)Addr; + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEL_DESEL_CARD; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SEL_DESEL_CARD, SDMMC_CMDTIMEOUT); + + return errorstate; +} + +/** + * @brief Send the Go Idle State command and check the response. + * @param SDMMCx: Pointer to SDMMC register base + * @retval HAL status + */ +uint32_t SDMMC_CmdGoIdleState(SDMMC_TypeDef *SDMMCx) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + sdmmc_cmdinit.Argument = 0U; + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_GO_IDLE_STATE; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_NO; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + errorstate = SDMMC_GetCmdError(SDMMCx); + + return errorstate; +} + +/** + * @brief Send the Operating Condition command and check the response. + * @param SDMMCx: Pointer to SDMMC register base + * @retval HAL status + */ +uint32_t SDMMC_CmdOperCond(SDMMC_TypeDef *SDMMCx) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + /* Send CMD8 to verify SD card interface operating condition */ + /* Argument: - [31:12]: Reserved (shall be set to '0') + - [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V) + - [7:0]: Check Pattern (recommended 0xAA) */ + /* CMD Response: R7 */ + sdmmc_cmdinit.Argument = SDMMC_CHECK_PATTERN; + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_HS_SEND_EXT_CSD; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + errorstate = SDMMC_GetCmdResp7(SDMMCx); + + return errorstate; +} + +/** + * @brief Send the Application command to verify that that the next command + * is an application specific com-mand rather than a standard command + * and check the response. + * @param SDMMCx: Pointer to SDMMC register base + * @param Argument: Command Argument + * @retval HAL status + */ +uint32_t SDMMC_CmdAppCommand(SDMMC_TypeDef *SDMMCx, uint32_t Argument) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + sdmmc_cmdinit.Argument = (uint32_t)Argument; + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_APP_CMD; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + /* If there is a HAL_ERROR, it is a MMC card, else + it is a SD card: SD card 2.0 (voltage range mismatch) + or SD card 1.x */ + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_APP_CMD, SDMMC_CMDTIMEOUT); + + return errorstate; +} + +/** + * @brief Send the command asking the accessed card to send its operating + * condition register (OCR) + * @param SDMMCx: Pointer to SDMMC register base + * @param Argument: Command Argument + * @retval HAL status + */ +uint32_t SDMMC_CmdAppOperCommand(SDMMC_TypeDef *SDMMCx, uint32_t Argument) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + sdmmc_cmdinit.Argument = Argument; + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_OP_COND; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + errorstate = SDMMC_GetCmdResp3(SDMMCx); + + return errorstate; +} + +/** + * @brief Send the Bus Width command and check the response. + * @param SDMMCx: Pointer to SDMMC register base + * @param BusWidth: BusWidth + * @retval HAL status + */ +uint32_t SDMMC_CmdBusWidth(SDMMC_TypeDef *SDMMCx, uint32_t BusWidth) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + sdmmc_cmdinit.Argument = (uint32_t)BusWidth; + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_APP_SD_SET_BUSWIDTH; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_APP_SD_SET_BUSWIDTH, SDMMC_CMDTIMEOUT); + + return errorstate; +} + +/** + * @brief Send the Send SCR command and check the response. + * @param SDMMCx: Pointer to SDMMC register base + * @retval HAL status + */ +uint32_t SDMMC_CmdSendSCR(SDMMC_TypeDef *SDMMCx) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + /* Send CMD51 SD_APP_SEND_SCR */ + sdmmc_cmdinit.Argument = 0U; + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_SEND_SCR; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SD_APP_SEND_SCR, SDMMC_CMDTIMEOUT); + + return errorstate; +} + +/** + * @brief Send the Send CID command and check the response. + * @param SDMMCx: Pointer to SDMMC register base + * @retval HAL status + */ +uint32_t SDMMC_CmdSendCID(SDMMC_TypeDef *SDMMCx) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + /* Send CMD2 ALL_SEND_CID */ + sdmmc_cmdinit.Argument = 0U; + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ALL_SEND_CID; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_LONG; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + errorstate = SDMMC_GetCmdResp2(SDMMCx); + + return errorstate; +} + +/** + * @brief Send the Send CSD command and check the response. + * @param SDMMCx: Pointer to SDMMC register base + * @param Argument: Command Argument + * @retval HAL status + */ +uint32_t SDMMC_CmdSendCSD(SDMMC_TypeDef *SDMMCx, uint32_t Argument) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + /* Send CMD9 SEND_CSD */ + sdmmc_cmdinit.Argument = Argument; + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEND_CSD; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_LONG; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + errorstate = SDMMC_GetCmdResp2(SDMMCx); + + return errorstate; +} + +/** + * @brief Send the Send CSD command and check the response. + * @param SDMMCx: Pointer to SDMMC register base + * @param pRCA: Card RCA + * @retval HAL status + */ +uint32_t SDMMC_CmdSetRelAdd(SDMMC_TypeDef *SDMMCx, uint16_t *pRCA) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + /* Send CMD3 SD_CMD_SET_REL_ADDR */ + sdmmc_cmdinit.Argument = 0U; + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SET_REL_ADDR; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + errorstate = SDMMC_GetCmdResp6(SDMMCx, SDMMC_CMD_SET_REL_ADDR, pRCA); + + return errorstate; +} + +/** + * @brief Send the Set Relative Address command to MMC card (not SD card). + * @param SDMMCx Pointer to SDMMC register base + * @param RCA Card RCA + * @retval HAL status + */ +uint32_t SDMMC_CmdSetRelAddMmc(SDMMC_TypeDef *SDMMCx, uint16_t RCA) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + /* Send CMD3 SD_CMD_SET_REL_ADDR */ + sdmmc_cmdinit.Argument = ((uint32_t)RCA << 16U); + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SET_REL_ADDR; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SET_REL_ADDR, SDMMC_CMDTIMEOUT); + + return errorstate; +} + +/** + * @brief Send the Sleep command to MMC card (not SD card). + * @param SDMMCx Pointer to SDMMC register base + * @param Argument Argument of the command (RCA and Sleep/Awake) + * @retval HAL status + */ +uint32_t SDMMC_CmdSleepMmc(SDMMC_TypeDef *SDMMCx, uint32_t Argument) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + /* Send CMD5 SDMMC_CMD_MMC_SLEEP_AWAKE */ + sdmmc_cmdinit.Argument = Argument; + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_MMC_SLEEP_AWAKE; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_MMC_SLEEP_AWAKE, SDMMC_CMDTIMEOUT); + + return errorstate; +} + +/** + * @brief Send the Status command and check the response. + * @param SDMMCx: Pointer to SDMMC register base + * @param Argument: Command Argument + * @retval HAL status + */ +uint32_t SDMMC_CmdSendStatus(SDMMC_TypeDef *SDMMCx, uint32_t Argument) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + sdmmc_cmdinit.Argument = Argument; + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEND_STATUS; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SEND_STATUS, SDMMC_CMDTIMEOUT); + + return errorstate; +} + +/** + * @brief Send the Status register command and check the response. + * @param SDMMCx: Pointer to SDMMC register base + * @retval HAL status + */ +uint32_t SDMMC_CmdStatusRegister(SDMMC_TypeDef *SDMMCx) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + sdmmc_cmdinit.Argument = 0U; + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_STATUS; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SD_APP_STATUS, SDMMC_CMDTIMEOUT); + + return errorstate; +} + +/** + * @brief Sends host capacity support information and activates the card's + * initialization process. Send SDMMC_CMD_SEND_OP_COND command + * @param SDMMCx: Pointer to SDMMC register base + * @parame Argument: Argument used for the command + * @retval HAL status + */ +uint32_t SDMMC_CmdOpCondition(SDMMC_TypeDef *SDMMCx, uint32_t Argument) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + sdmmc_cmdinit.Argument = Argument; + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEND_OP_COND; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + errorstate = SDMMC_GetCmdResp3(SDMMCx); + + return errorstate; +} + +/** + * @brief Checks switchable function and switch card function. SDMMC_CMD_HS_SWITCH command + * @param SDMMCx: Pointer to SDMMC register base + * @parame Argument: Argument used for the command + * @retval HAL status + */ +uint32_t SDMMC_CmdSwitch(SDMMC_TypeDef *SDMMCx, uint32_t Argument) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + /* Send CMD6 to activate SDR50 Mode and Power Limit 1.44W */ + /* CMD Response: R1 */ + sdmmc_cmdinit.Argument = Argument; /* SDMMC_SDR25_SWITCH_PATTERN*/ + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_HS_SWITCH; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_HS_SWITCH, SDMMC_CMDTIMEOUT); + + return errorstate; +} + +/** + * @brief Send the command asking the accessed card to send its operating + * condition register (OCR) + * @param None + * @retval HAL status + */ +uint32_t SDMMC_CmdVoltageSwitch(SDMMC_TypeDef *SDMMCx) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + sdmmc_cmdinit.Argument = 0x00000000; + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_VOLTAGE_SWITCH; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_VOLTAGE_SWITCH, SDMMC_CMDTIMEOUT); + + return errorstate; +} + +/** + * @brief Send the Send EXT_CSD command and check the response. + * @param SDMMCx: Pointer to SDMMC register base + * @param Argument: Command Argument + * @retval HAL status + */ +uint32_t SDMMC_CmdSendEXTCSD(SDMMC_TypeDef *SDMMCx, uint32_t Argument) +{ + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + /* Send CMD9 SEND_CSD */ + sdmmc_cmdinit.Argument = Argument; + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_HS_SEND_EXT_CSD; + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + + /* Check for error conditions */ + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_HS_SEND_EXT_CSD, SDMMC_CMDTIMEOUT); + + return errorstate; +} + +/** + * @} + */ + + +/** @defgroup HAL_SDMMC_LL_Group5 Responses management functions + * @brief Responses functions + * +@verbatim + =============================================================================== + ##### Responses management functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the needed responses. + +@endverbatim + * @{ + */ +/** + * @brief Checks for error conditions for R1 response. + * @param hsd: SD handle + * @param SD_CMD: The sent command index + * @retval SD Card error state + */ +uint32_t SDMMC_GetCmdResp1(SDMMC_TypeDef *SDMMCx, uint8_t SD_CMD, uint32_t Timeout) +{ + uint32_t response_r1; + uint32_t sta_reg; + + /* 8 is the number of required instructions cycles for the below loop statement. + The Timeout is expressed in ms */ + uint32_t count = Timeout * (SystemCoreClock / 8U / 1000U); + + do + { + if (count-- == 0U) + { + return SDMMC_ERROR_TIMEOUT; + } + sta_reg = SDMMCx->STA; + } while (((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT | + SDMMC_FLAG_BUSYD0END)) == 0U) || ((sta_reg & SDMMC_FLAG_CMDACT) != 0U)); + + if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT)) + { + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT); + + return SDMMC_ERROR_CMD_RSP_TIMEOUT; + } + else if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL)) + { + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL); + + return SDMMC_ERROR_CMD_CRC_FAIL; + } + else + { + /* Nothing to do */ + } + + /* Clear all the static flags */ + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS); + + /* Check response received is of desired command */ + if (SDMMC_GetCommandResponse(SDMMCx) != SD_CMD) + { + return SDMMC_ERROR_CMD_CRC_FAIL; + } + + /* We have received response, retrieve it for analysis */ + response_r1 = SDMMC_GetResponse(SDMMCx, SDMMC_RESP1); + + if ((response_r1 & SDMMC_OCR_ERRORBITS) == SDMMC_ALLZERO) + { + return SDMMC_ERROR_NONE; + } + else if ((response_r1 & SDMMC_OCR_ADDR_OUT_OF_RANGE) == SDMMC_OCR_ADDR_OUT_OF_RANGE) + { + return SDMMC_ERROR_ADDR_OUT_OF_RANGE; + } + else if ((response_r1 & SDMMC_OCR_ADDR_MISALIGNED) == SDMMC_OCR_ADDR_MISALIGNED) + { + return SDMMC_ERROR_ADDR_MISALIGNED; + } + else if ((response_r1 & SDMMC_OCR_BLOCK_LEN_ERR) == SDMMC_OCR_BLOCK_LEN_ERR) + { + return SDMMC_ERROR_BLOCK_LEN_ERR; + } + else if ((response_r1 & SDMMC_OCR_ERASE_SEQ_ERR) == SDMMC_OCR_ERASE_SEQ_ERR) + { + return SDMMC_ERROR_ERASE_SEQ_ERR; + } + else if ((response_r1 & SDMMC_OCR_BAD_ERASE_PARAM) == SDMMC_OCR_BAD_ERASE_PARAM) + { + return SDMMC_ERROR_BAD_ERASE_PARAM; + } + else if ((response_r1 & SDMMC_OCR_WRITE_PROT_VIOLATION) == SDMMC_OCR_WRITE_PROT_VIOLATION) + { + return SDMMC_ERROR_WRITE_PROT_VIOLATION; + } + else if ((response_r1 & SDMMC_OCR_LOCK_UNLOCK_FAILED) == SDMMC_OCR_LOCK_UNLOCK_FAILED) + { + return SDMMC_ERROR_LOCK_UNLOCK_FAILED; + } + else if ((response_r1 & SDMMC_OCR_COM_CRC_FAILED) == SDMMC_OCR_COM_CRC_FAILED) + { + return SDMMC_ERROR_COM_CRC_FAILED; + } + else if ((response_r1 & SDMMC_OCR_ILLEGAL_CMD) == SDMMC_OCR_ILLEGAL_CMD) + { + return SDMMC_ERROR_ILLEGAL_CMD; + } + else if ((response_r1 & SDMMC_OCR_CARD_ECC_FAILED) == SDMMC_OCR_CARD_ECC_FAILED) + { + return SDMMC_ERROR_CARD_ECC_FAILED; + } + else if ((response_r1 & SDMMC_OCR_CC_ERROR) == SDMMC_OCR_CC_ERROR) + { + return SDMMC_ERROR_CC_ERR; + } + else if ((response_r1 & SDMMC_OCR_STREAM_READ_UNDERRUN) == SDMMC_OCR_STREAM_READ_UNDERRUN) + { + return SDMMC_ERROR_STREAM_READ_UNDERRUN; + } + else if ((response_r1 & SDMMC_OCR_STREAM_WRITE_OVERRUN) == SDMMC_OCR_STREAM_WRITE_OVERRUN) + { + return SDMMC_ERROR_STREAM_WRITE_OVERRUN; + } + else if ((response_r1 & SDMMC_OCR_CID_CSD_OVERWRITE) == SDMMC_OCR_CID_CSD_OVERWRITE) + { + return SDMMC_ERROR_CID_CSD_OVERWRITE; + } + else if ((response_r1 & SDMMC_OCR_WP_ERASE_SKIP) == SDMMC_OCR_WP_ERASE_SKIP) + { + return SDMMC_ERROR_WP_ERASE_SKIP; + } + else if ((response_r1 & SDMMC_OCR_CARD_ECC_DISABLED) == SDMMC_OCR_CARD_ECC_DISABLED) + { + return SDMMC_ERROR_CARD_ECC_DISABLED; + } + else if ((response_r1 & SDMMC_OCR_ERASE_RESET) == SDMMC_OCR_ERASE_RESET) + { + return SDMMC_ERROR_ERASE_RESET; + } + else if ((response_r1 & SDMMC_OCR_AKE_SEQ_ERROR) == SDMMC_OCR_AKE_SEQ_ERROR) + { + return SDMMC_ERROR_AKE_SEQ_ERR; + } + else + { + return SDMMC_ERROR_GENERAL_UNKNOWN_ERR; + } +} + +/** + * @brief Checks for error conditions for R2 (CID or CSD) response. + * @param hsd: SD handle + * @retval SD Card error state + */ +uint32_t SDMMC_GetCmdResp2(SDMMC_TypeDef *SDMMCx) +{ + uint32_t sta_reg; + /* 8 is the number of required instructions cycles for the below loop statement. + The SDMMC_CMDTIMEOUT is expressed in ms */ + uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U / 1000U); + + do + { + if (count-- == 0U) + { + return SDMMC_ERROR_TIMEOUT; + } + sta_reg = SDMMCx->STA; + } while (((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT)) == 0U) || + ((sta_reg & SDMMC_FLAG_CMDACT) != 0U)); + + if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT)) + { + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT); + + return SDMMC_ERROR_CMD_RSP_TIMEOUT; + } + else if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL)) + { + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL); + + return SDMMC_ERROR_CMD_CRC_FAIL; + } + else + { + /* No error flag set */ + /* Clear all the static flags */ + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS); + } + + return SDMMC_ERROR_NONE; +} + +/** + * @brief Checks for error conditions for R3 (OCR) response. + * @param hsd: SD handle + * @retval SD Card error state + */ +uint32_t SDMMC_GetCmdResp3(SDMMC_TypeDef *SDMMCx) +{ + uint32_t sta_reg; + /* 8 is the number of required instructions cycles for the below loop statement. + The SDMMC_CMDTIMEOUT is expressed in ms */ + uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U / 1000U); + + do + { + if (count-- == 0U) + { + return SDMMC_ERROR_TIMEOUT; + } + sta_reg = SDMMCx->STA; + } while (((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT)) == 0U) || + ((sta_reg & SDMMC_FLAG_CMDACT) != 0U)); + + if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT)) + { + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT); + + return SDMMC_ERROR_CMD_RSP_TIMEOUT; + } + else + { + /* Clear all the static flags */ + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS); + } + + return SDMMC_ERROR_NONE; +} + +/** + * @brief Checks for error conditions for R6 (RCA) response. + * @param hsd: SD handle + * @param SD_CMD: The sent command index + * @param pRCA: Pointer to the variable that will contain the SD card relative + * address RCA + * @retval SD Card error state + */ +uint32_t SDMMC_GetCmdResp6(SDMMC_TypeDef *SDMMCx, uint8_t SD_CMD, uint16_t *pRCA) +{ + uint32_t response_r1; + uint32_t sta_reg; + + /* 8 is the number of required instructions cycles for the below loop statement. + The SDMMC_CMDTIMEOUT is expressed in ms */ + uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U / 1000U); + + do + { + if (count-- == 0U) + { + return SDMMC_ERROR_TIMEOUT; + } + sta_reg = SDMMCx->STA; + } while (((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT)) == 0U) || + ((sta_reg & SDMMC_FLAG_CMDACT) != 0U)); + + if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT)) + { + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT); + + return SDMMC_ERROR_CMD_RSP_TIMEOUT; + } + else if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL)) + { + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL); + + return SDMMC_ERROR_CMD_CRC_FAIL; + } + else + { + /* Nothing to do */ + } + + /* Check response received is of desired command */ + if (SDMMC_GetCommandResponse(SDMMCx) != SD_CMD) + { + return SDMMC_ERROR_CMD_CRC_FAIL; + } + + /* Clear all the static flags */ + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS); + + /* We have received response, retrieve it. */ + response_r1 = SDMMC_GetResponse(SDMMCx, SDMMC_RESP1); + + if ((response_r1 & (SDMMC_R6_GENERAL_UNKNOWN_ERROR | SDMMC_R6_ILLEGAL_CMD | + SDMMC_R6_COM_CRC_FAILED)) == SDMMC_ALLZERO) + { + *pRCA = (uint16_t)(response_r1 >> 16); + + return SDMMC_ERROR_NONE; + } + else if ((response_r1 & SDMMC_R6_ILLEGAL_CMD) == SDMMC_R6_ILLEGAL_CMD) + { + return SDMMC_ERROR_ILLEGAL_CMD; + } + else if ((response_r1 & SDMMC_R6_COM_CRC_FAILED) == SDMMC_R6_COM_CRC_FAILED) + { + return SDMMC_ERROR_COM_CRC_FAILED; + } + else + { + return SDMMC_ERROR_GENERAL_UNKNOWN_ERR; + } +} + +/** + * @brief Checks for error conditions for R7 response. + * @param hsd: SD handle + * @retval SD Card error state + */ +uint32_t SDMMC_GetCmdResp7(SDMMC_TypeDef *SDMMCx) +{ + uint32_t sta_reg; + /* 8 is the number of required instructions cycles for the below loop statement. + The SDMMC_CMDTIMEOUT is expressed in ms */ + uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U / 1000U); + + do + { + if (count-- == 0U) + { + return SDMMC_ERROR_TIMEOUT; + } + sta_reg = SDMMCx->STA; + } while (((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT)) == 0U) || + ((sta_reg & SDMMC_FLAG_CMDACT) != 0U)); + + if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT)) + { + /* Card is not SD V2.0 compliant */ + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT); + + return SDMMC_ERROR_CMD_RSP_TIMEOUT; + } + + else if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL)) + { + /* Card is not SD V2.0 compliant */ + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL); + + return SDMMC_ERROR_CMD_CRC_FAIL; + } + else + { + /* Nothing to do */ + } + + if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CMDREND)) + { + /* Card is SD V2.0 compliant */ + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CMDREND); + } + + return SDMMC_ERROR_NONE; + +} + +/** + * @} + */ + + +/** @defgroup HAL_SDMMC_LL_Group6 Linked List functions + * @brief Linked List management functions + * +@verbatim + =============================================================================== + ##### Linked List management functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the needed functions. + +@endverbatim + * @{ + */ + +/** + * @brief Build new Linked List node. + * @param pNode: Pointer to new node to add. + * @param pNodeConf: Pointer to configuration parameters for new node to add. + * @retval Error status + */ +uint32_t SDMMC_DMALinkedList_BuildNode(SDMMC_DMALinkNodeTypeDef *pNode, SDMMC_DMALinkNodeConfTypeDef *pNodeConf) +{ + + if ((pNode == NULL) || (pNodeConf == NULL)) + { + return SDMMC_ERROR_INVALID_PARAMETER; + } + /* Configure the Link Node registers*/ + pNode->IDMABASER = pNodeConf->BufferAddress; + pNode->IDMABSIZE = pNodeConf->BufferSize; + pNode->IDMALAR = SDMMC_IDMALAR_ULS | SDMMC_IDMALAR_ABR; + + return SDMMC_ERROR_NONE; +} + +/** + * @brief Insert new Linked List node. + * @param pLinkedList: Pointer to the linkedlist that contains transfer nodes + * @param pPrevNode: Pointer to previous node . + * @param pNewNode: Pointer to new node to add. + * @retval Error status + */ +uint32_t SDMMC_DMALinkedList_InsertNode(SDMMC_DMALinkedListTypeDef *pLinkedList, SDMMC_DMALinkNodeTypeDef *pPrevNode, + SDMMC_DMALinkNodeTypeDef *pNode) +{ + uint32_t link_list_offset; + uint32_t node_address = (uint32_t) pNode; + + /* First Node */ + if (pLinkedList->NodesCounter == 0U) + { + + pLinkedList->pHeadNode = pNode; + pLinkedList->pTailNode = pNode; + pLinkedList->NodesCounter = 1U; + + } + else if (pPrevNode == pLinkedList->pTailNode) + { + if (pNode <= pLinkedList->pHeadNode) + { + /* Node Address should greater than Head Node Address*/ + return SDMMC_ERROR_INVALID_PARAMETER; + } + + /*Last Node, no next node */ + MODIFY_REG(pPrevNode->IDMALAR, SDMMC_IDMALAR_ULA, 0U); + + /*link Prev node with new one */ + MODIFY_REG(pPrevNode->IDMALAR, SDMMC_IDMALAR_ULA, SDMMC_IDMALAR_ULA); + MODIFY_REG(pPrevNode->IDMALAR, SDMMC_IDMALAR_IDMALA, (node_address - (uint32_t)pLinkedList->pHeadNode)); + + pLinkedList->NodesCounter ++; + pLinkedList->pTailNode = pNode; + + } + else + { + + if (pNode <= pLinkedList->pHeadNode) + { + /* Node Address should greater than Head Node Address*/ + return SDMMC_ERROR_INVALID_PARAMETER; + } + + /*link New node with Next one */ + link_list_offset = pNode->IDMALAR; + MODIFY_REG(pPrevNode->IDMALAR, SDMMC_IDMALAR_IDMALA, link_list_offset); + + /*link Prev node with new one */ + MODIFY_REG(pPrevNode->IDMALAR, SDMMC_IDMALAR_ULA, SDMMC_IDMALAR_ULA); + MODIFY_REG(pPrevNode->IDMALAR, SDMMC_IDMALAR_IDMALA, (node_address - (uint32_t)pLinkedList->pHeadNode)); + + pLinkedList->NodesCounter ++; + + } + return SDMMC_ERROR_NONE; +} + +/** + * @brief Remove node from the Linked List. + * @param pLinkedList: Pointer to the linkedlist that contains transfer nodes + * @param pNode: Pointer to new node to add. + * @retval Error status + */ +uint32_t SDMMC_DMALinkedList_RemoveNode(SDMMC_DMALinkedListTypeDef *pLinkedList, SDMMC_DMALinkNodeTypeDef *pNode) +{ + uint32_t count = 0U; + uint32_t linked_list_offset; + SDMMC_DMALinkNodeTypeDef *prev_node = NULL; + SDMMC_DMALinkNodeTypeDef *curr_node ; + + /* First Node */ + if (pLinkedList->NodesCounter == 0U) + { + + return SDMMC_ERROR_INVALID_PARAMETER; + } + else + { + curr_node = pLinkedList->pHeadNode; + while ((curr_node != pNode) && (count <= pLinkedList->NodesCounter)) + { + prev_node = curr_node; + curr_node = (SDMMC_DMALinkNodeTypeDef *)((prev_node->IDMALAR & SDMMC_IDMALAR_IDMALA) + + (uint32_t)pLinkedList->pHeadNode); + count++; + } + + if ((count == 0U) || (count > pLinkedList->NodesCounter)) + { + /* Node not found in the linked list */ + return SDMMC_ERROR_INVALID_PARAMETER; + } + + pLinkedList->NodesCounter--; + + if (pLinkedList->NodesCounter == 0U) + { + pLinkedList->pHeadNode = 0U; + pLinkedList->pTailNode = 0U; + } + else + { + /*link prev node with next one */ + linked_list_offset = curr_node->IDMALAR; + MODIFY_REG(prev_node->IDMALAR, SDMMC_IDMALAR_IDMALA, linked_list_offset); + /* Configure the new Link Node registers*/ + pNode->IDMALAR |= linked_list_offset; + + pLinkedList->pTailNode = prev_node; + } + } + return SDMMC_ERROR_NONE; +} + +/** + * @brief Lock Linked List Node + * @param pNode: Pointer to node to lock. + * @retval Error status + + */ +uint32_t SDMMC_DMALinkedList_LockNode(SDMMC_DMALinkNodeTypeDef *pNode) +{ + + if (pNode == NULL) + { + return SDMMC_ERROR_INVALID_PARAMETER; + } + + MODIFY_REG(pNode->IDMALAR, SDMMC_IDMALAR_ABR, 0U); + + return SDMMC_ERROR_NONE; +} + +/** + * @brief Unlock Linked List Node + * @param pNode: Pointer to node to unlock. + * @retval Error status + + */ +uint32_t SDMMC_DMALinkedList_UnlockNode(SDMMC_DMALinkNodeTypeDef *pNode) +{ + + if (pNode == NULL) + { + return SDMMC_ERROR_INVALID_PARAMETER; + } + + MODIFY_REG(pNode->IDMALAR, SDMMC_IDMALAR_ABR, SDMMC_IDMALAR_ABR); + + return SDMMC_ERROR_NONE; +} + +/** + * @brief Enable Linked List circular mode + * @param pLinkedList: Pointer to the linkedlist that contains transfer nodes + * @retval Error status + + */ +uint32_t SDMMC_DMALinkedList_EnableCircularMode(SDMMC_DMALinkedListTypeDef *pLinkedList) +{ + + if (pLinkedList == NULL) + { + return SDMMC_ERROR_INVALID_PARAMETER; + } + + MODIFY_REG(pLinkedList->pTailNode->IDMALAR, SDMMC_IDMALAR_ULA | SDMMC_IDMALAR_IDMALA, SDMMC_IDMALAR_ULA); + + return SDMMC_ERROR_NONE; +} + +/** + * @brief Disable DMA Linked List Circular mode + * @param pLinkedList: Pointer to the linkedlist that contains transfer nodes + * @retval Error status + */ +uint32_t SDMMC_DMALinkedList_DisableCircularMode(SDMMC_DMALinkedListTypeDef *pLinkedList) +{ + + if (pLinkedList == NULL) + { + return SDMMC_ERROR_INVALID_PARAMETER; + } + + MODIFY_REG(pLinkedList->pTailNode->IDMALAR, SDMMC_IDMALAR_ULA, 0U); + + return SDMMC_ERROR_NONE; +} + +/** + * @} + */ + + +/* Private function ----------------------------------------------------------*/ +/** @addtogroup SD_Private_Functions + * @{ + */ + +/** + * @brief Checks for error conditions for CMD0. + * @param hsd: SD handle + * @retval SD Card error state + */ +static uint32_t SDMMC_GetCmdError(SDMMC_TypeDef *SDMMCx) +{ + /* 8 is the number of required instructions cycles for the below loop statement. + The SDMMC_CMDTIMEOUT is expressed in ms */ + uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U / 1000U); + + do + { + if (count-- == 0U) + { + return SDMMC_ERROR_TIMEOUT; + } + + } while (!__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CMDSENT)); + + /* Clear all the static flags */ + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS); + + return SDMMC_ERROR_NONE; +} + +/** + * @} + */ + +#endif /* HAL_SD_MODULE_ENABLED || HAL_MMC_MODULE_ENABLED */ +#endif /* SDMMC1 || SDMMC2 */ +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_spi.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_spi.c new file mode 100644 index 0000000000..c70a438adf --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_spi.c @@ -0,0 +1,751 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_spi.c + * @author MCD Application Team + * @brief SPI LL module driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +#if defined(USE_FULL_LL_DRIVER) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_spi.h" +#include "stm32h5xx_ll_bus.h" +#include "stm32h5xx_ll_rcc.h" +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined(SPI1) || defined(SPI2) || defined(SPI3) || defined(SPI4) || defined(SPI5) || defined(SPI6) + +/** @addtogroup SPI_LL + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup SPI_LL_Private_Macros + * @{ + */ + +#define IS_LL_SPI_MODE(__VALUE__) (((__VALUE__) == LL_SPI_MODE_MASTER) || \ + ((__VALUE__) == LL_SPI_MODE_SLAVE)) + +#define IS_LL_SPI_SS_IDLENESS(__VALUE__) (((__VALUE__) == LL_SPI_SS_IDLENESS_00CYCLE) || \ + ((__VALUE__) == LL_SPI_SS_IDLENESS_01CYCLE) || \ + ((__VALUE__) == LL_SPI_SS_IDLENESS_02CYCLE) || \ + ((__VALUE__) == LL_SPI_SS_IDLENESS_03CYCLE) || \ + ((__VALUE__) == LL_SPI_SS_IDLENESS_04CYCLE) || \ + ((__VALUE__) == LL_SPI_SS_IDLENESS_05CYCLE) || \ + ((__VALUE__) == LL_SPI_SS_IDLENESS_06CYCLE) || \ + ((__VALUE__) == LL_SPI_SS_IDLENESS_07CYCLE) || \ + ((__VALUE__) == LL_SPI_SS_IDLENESS_08CYCLE) || \ + ((__VALUE__) == LL_SPI_SS_IDLENESS_09CYCLE) || \ + ((__VALUE__) == LL_SPI_SS_IDLENESS_10CYCLE) || \ + ((__VALUE__) == LL_SPI_SS_IDLENESS_11CYCLE) || \ + ((__VALUE__) == LL_SPI_SS_IDLENESS_12CYCLE) || \ + ((__VALUE__) == LL_SPI_SS_IDLENESS_13CYCLE) || \ + ((__VALUE__) == LL_SPI_SS_IDLENESS_14CYCLE) || \ + ((__VALUE__) == LL_SPI_SS_IDLENESS_15CYCLE)) + +#define IS_LL_SPI_ID_IDLENESS(__VALUE__) (((__VALUE__) == LL_SPI_ID_IDLENESS_00CYCLE) || \ + ((__VALUE__) == LL_SPI_ID_IDLENESS_01CYCLE) || \ + ((__VALUE__) == LL_SPI_ID_IDLENESS_02CYCLE) || \ + ((__VALUE__) == LL_SPI_ID_IDLENESS_03CYCLE) || \ + ((__VALUE__) == LL_SPI_ID_IDLENESS_04CYCLE) || \ + ((__VALUE__) == LL_SPI_ID_IDLENESS_05CYCLE) || \ + ((__VALUE__) == LL_SPI_ID_IDLENESS_06CYCLE) || \ + ((__VALUE__) == LL_SPI_ID_IDLENESS_07CYCLE) || \ + ((__VALUE__) == LL_SPI_ID_IDLENESS_08CYCLE) || \ + ((__VALUE__) == LL_SPI_ID_IDLENESS_09CYCLE) || \ + ((__VALUE__) == LL_SPI_ID_IDLENESS_10CYCLE) || \ + ((__VALUE__) == LL_SPI_ID_IDLENESS_11CYCLE) || \ + ((__VALUE__) == LL_SPI_ID_IDLENESS_12CYCLE) || \ + ((__VALUE__) == LL_SPI_ID_IDLENESS_13CYCLE) || \ + ((__VALUE__) == LL_SPI_ID_IDLENESS_14CYCLE) || \ + ((__VALUE__) == LL_SPI_ID_IDLENESS_15CYCLE)) + +#define IS_LL_SPI_TXCRCINIT_PATTERN(__VALUE__) (((__VALUE__) == LL_SPI_TXCRCINIT_ALL_ZERO_PATTERN) || \ + ((__VALUE__) == LL_SPI_TXCRCINIT_ALL_ONES_PATTERN)) + +#define IS_LL_SPI_RXCRCINIT_PATTERN(__VALUE__) (((__VALUE__) == LL_SPI_RXCRCINIT_ALL_ZERO_PATTERN) || \ + ((__VALUE__) == LL_SPI_RXCRCINIT_ALL_ONES_PATTERN)) + +#define IS_LL_SPI_UDR_CONFIG_REGISTER(__VALUE__) (((__VALUE__) == LL_SPI_UDR_CONFIG_REGISTER_PATTERN) || \ + ((__VALUE__) == LL_SPI_UDR_CONFIG_LAST_RECEIVED) || \ + ((__VALUE__) == LL_SPI_UDR_CONFIG_LAST_TRANSMITTED)) + +#define IS_LL_SPI_UDR_DETECT_BEGIN_DATA(__VALUE__) (((__VALUE__) == LL_SPI_UDR_DETECT_BEGIN_DATA_FRAME) || \ + ((__VALUE__) == LL_SPI_UDR_DETECT_END_DATA_FRAME) || \ + ((__VALUE__) == LL_SPI_UDR_DETECT_BEGIN_ACTIVE_NSS)) + +#define IS_LL_SPI_PROTOCOL(__VALUE__) (((__VALUE__) == LL_SPI_PROTOCOL_MOTOROLA) || \ + ((__VALUE__) == LL_SPI_PROTOCOL_TI)) + +#define IS_LL_SPI_PHASE(__VALUE__) (((__VALUE__) == LL_SPI_PHASE_1EDGE) || \ + ((__VALUE__) == LL_SPI_PHASE_2EDGE)) + +#define IS_LL_SPI_POLARITY(__VALUE__) (((__VALUE__) == LL_SPI_POLARITY_LOW) || \ + ((__VALUE__) == LL_SPI_POLARITY_HIGH)) + +#define IS_LL_SPI_BAUDRATEPRESCALER(__VALUE__) (((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_BYPASS) || \ + ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV2) || \ + ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV4) || \ + ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV8) || \ + ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV16) || \ + ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV32) || \ + ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV64) || \ + ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV128) || \ + ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV256)) + +#define IS_LL_SPI_BITORDER(__VALUE__) (((__VALUE__) == LL_SPI_LSB_FIRST) || \ + ((__VALUE__) == LL_SPI_MSB_FIRST)) + +#define IS_LL_SPI_TRANSFER_DIRECTION(__VALUE__) (((__VALUE__) == LL_SPI_FULL_DUPLEX) || \ + ((__VALUE__) == LL_SPI_SIMPLEX_TX) || \ + ((__VALUE__) == LL_SPI_SIMPLEX_RX) || \ + ((__VALUE__) == LL_SPI_HALF_DUPLEX_RX) || \ + ((__VALUE__) == LL_SPI_HALF_DUPLEX_TX)) + +#define IS_LL_SPI_DATAWIDTH(__VALUE__) (((__VALUE__) == LL_SPI_DATAWIDTH_4BIT) || \ + ((__VALUE__) == LL_SPI_DATAWIDTH_5BIT) || \ + ((__VALUE__) == LL_SPI_DATAWIDTH_6BIT) || \ + ((__VALUE__) == LL_SPI_DATAWIDTH_7BIT) || \ + ((__VALUE__) == LL_SPI_DATAWIDTH_8BIT) || \ + ((__VALUE__) == LL_SPI_DATAWIDTH_9BIT) || \ + ((__VALUE__) == LL_SPI_DATAWIDTH_10BIT) || \ + ((__VALUE__) == LL_SPI_DATAWIDTH_11BIT) || \ + ((__VALUE__) == LL_SPI_DATAWIDTH_12BIT) || \ + ((__VALUE__) == LL_SPI_DATAWIDTH_13BIT) || \ + ((__VALUE__) == LL_SPI_DATAWIDTH_14BIT) || \ + ((__VALUE__) == LL_SPI_DATAWIDTH_15BIT) || \ + ((__VALUE__) == LL_SPI_DATAWIDTH_16BIT) || \ + ((__VALUE__) == LL_SPI_DATAWIDTH_17BIT) || \ + ((__VALUE__) == LL_SPI_DATAWIDTH_18BIT) || \ + ((__VALUE__) == LL_SPI_DATAWIDTH_19BIT) || \ + ((__VALUE__) == LL_SPI_DATAWIDTH_20BIT) || \ + ((__VALUE__) == LL_SPI_DATAWIDTH_21BIT) || \ + ((__VALUE__) == LL_SPI_DATAWIDTH_22BIT) || \ + ((__VALUE__) == LL_SPI_DATAWIDTH_23BIT) || \ + ((__VALUE__) == LL_SPI_DATAWIDTH_24BIT) || \ + ((__VALUE__) == LL_SPI_DATAWIDTH_25BIT) || \ + ((__VALUE__) == LL_SPI_DATAWIDTH_26BIT) || \ + ((__VALUE__) == LL_SPI_DATAWIDTH_27BIT) || \ + ((__VALUE__) == LL_SPI_DATAWIDTH_28BIT) || \ + ((__VALUE__) == LL_SPI_DATAWIDTH_29BIT) || \ + ((__VALUE__) == LL_SPI_DATAWIDTH_30BIT) || \ + ((__VALUE__) == LL_SPI_DATAWIDTH_31BIT) || \ + ((__VALUE__) == LL_SPI_DATAWIDTH_32BIT)) + +#define IS_LL_SPI_FIFO_TH(__VALUE__) (((__VALUE__) == LL_SPI_FIFO_TH_01DATA) || \ + ((__VALUE__) == LL_SPI_FIFO_TH_02DATA) || \ + ((__VALUE__) == LL_SPI_FIFO_TH_03DATA) || \ + ((__VALUE__) == LL_SPI_FIFO_TH_04DATA) || \ + ((__VALUE__) == LL_SPI_FIFO_TH_05DATA) || \ + ((__VALUE__) == LL_SPI_FIFO_TH_06DATA) || \ + ((__VALUE__) == LL_SPI_FIFO_TH_07DATA) || \ + ((__VALUE__) == LL_SPI_FIFO_TH_08DATA) || \ + ((__VALUE__) == LL_SPI_FIFO_TH_09DATA) || \ + ((__VALUE__) == LL_SPI_FIFO_TH_10DATA) || \ + ((__VALUE__) == LL_SPI_FIFO_TH_11DATA) || \ + ((__VALUE__) == LL_SPI_FIFO_TH_12DATA) || \ + ((__VALUE__) == LL_SPI_FIFO_TH_13DATA) || \ + ((__VALUE__) == LL_SPI_FIFO_TH_14DATA) || \ + ((__VALUE__) == LL_SPI_FIFO_TH_15DATA) || \ + ((__VALUE__) == LL_SPI_FIFO_TH_16DATA)) + +#define IS_LL_SPI_CRC(__VALUE__) (((__VALUE__) == LL_SPI_CRC_4BIT) || \ + ((__VALUE__) == LL_SPI_CRC_5BIT) || \ + ((__VALUE__) == LL_SPI_CRC_6BIT) || \ + ((__VALUE__) == LL_SPI_CRC_7BIT) || \ + ((__VALUE__) == LL_SPI_CRC_8BIT) || \ + ((__VALUE__) == LL_SPI_CRC_9BIT) || \ + ((__VALUE__) == LL_SPI_CRC_10BIT) || \ + ((__VALUE__) == LL_SPI_CRC_11BIT) || \ + ((__VALUE__) == LL_SPI_CRC_12BIT) || \ + ((__VALUE__) == LL_SPI_CRC_13BIT) || \ + ((__VALUE__) == LL_SPI_CRC_14BIT) || \ + ((__VALUE__) == LL_SPI_CRC_15BIT) || \ + ((__VALUE__) == LL_SPI_CRC_16BIT) || \ + ((__VALUE__) == LL_SPI_CRC_17BIT) || \ + ((__VALUE__) == LL_SPI_CRC_18BIT) || \ + ((__VALUE__) == LL_SPI_CRC_19BIT) || \ + ((__VALUE__) == LL_SPI_CRC_20BIT) || \ + ((__VALUE__) == LL_SPI_CRC_21BIT) || \ + ((__VALUE__) == LL_SPI_CRC_22BIT) || \ + ((__VALUE__) == LL_SPI_CRC_23BIT) || \ + ((__VALUE__) == LL_SPI_CRC_24BIT) || \ + ((__VALUE__) == LL_SPI_CRC_25BIT) || \ + ((__VALUE__) == LL_SPI_CRC_26BIT) || \ + ((__VALUE__) == LL_SPI_CRC_27BIT) || \ + ((__VALUE__) == LL_SPI_CRC_28BIT) || \ + ((__VALUE__) == LL_SPI_CRC_29BIT) || \ + ((__VALUE__) == LL_SPI_CRC_30BIT) || \ + ((__VALUE__) == LL_SPI_CRC_31BIT) || \ + ((__VALUE__) == LL_SPI_CRC_32BIT)) + +#define IS_LL_SPI_NSS(__VALUE__) (((__VALUE__) == LL_SPI_NSS_SOFT) || \ + ((__VALUE__) == LL_SPI_NSS_HARD_INPUT) || \ + ((__VALUE__) == LL_SPI_NSS_HARD_OUTPUT)) + +#define IS_LL_SPI_RX_FIFO(__VALUE__) (((__VALUE__) == LL_SPI_RX_FIFO_0PACKET) || \ + ((__VALUE__) == LL_SPI_RX_FIFO_1PACKET) || \ + ((__VALUE__) == LL_SPI_RX_FIFO_2PACKET) || \ + ((__VALUE__) == LL_SPI_RX_FIFO_3PACKET)) + +#define IS_LL_SPI_CRCCALCULATION(__VALUE__) (((__VALUE__) == LL_SPI_CRCCALCULATION_ENABLE) || \ + ((__VALUE__) == LL_SPI_CRCCALCULATION_DISABLE)) + +#define IS_LL_SPI_CRC_POLYNOMIAL(__VALUE__) ((__VALUE__) >= 0x1UL) + +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup SPI_LL_Exported_Functions + * @{ + */ + +/** @addtogroup SPI_LL_EF_Init + * @{ + */ + +/** + * @brief De-initialize the SPI registers to their default reset values. + * @param SPIx SPI Instance + * @retval An ErrorStatus enumeration value: + * - SUCCESS: SPI registers are de-initialized + * - ERROR: SPI registers are not de-initialized + */ +ErrorStatus LL_SPI_DeInit(const SPI_TypeDef *SPIx) +{ + ErrorStatus status = ERROR; + + /* Check the parameters */ + assert_param(IS_SPI_ALL_INSTANCE(SPIx)); + +#if defined(SPI1) + if (SPIx == SPI1) + { + /* Force reset of SPI clock */ + LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); + + /* Release reset of SPI clock */ + LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1); + + /* Update the return status */ + status = SUCCESS; + } +#endif /* SPI1 */ +#if defined(SPI2) + if (SPIx == SPI2) + { + /* Force reset of SPI clock */ + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); + + /* Release reset of SPI clock */ + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2); + + /* Update the return status */ + status = SUCCESS; + } +#endif /* SPI2 */ +#if defined(SPI3) + if (SPIx == SPI3) + { + /* Force reset of SPI clock */ + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI3); + + /* Release reset of SPI clock */ + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI3); + + /* Update the return status */ + status = SUCCESS; + } +#endif /* SPI3 */ +#if defined(SPI4) + if (SPIx == SPI4) + { + /* Force reset of SPI clock */ + LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI4); + + /* Release reset of SPI clock */ + LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI4); + + /* Update the return status */ + status = SUCCESS; + } +#endif /* SPI4 */ +#if defined(SPI5) + if (SPIx == SPI5) + { + /* Force reset of SPI clock */ + LL_APB3_GRP1_ForceReset(LL_APB3_GRP1_PERIPH_SPI5); + + /* Release reset of SPI clock */ + LL_APB3_GRP1_ReleaseReset(LL_APB3_GRP1_PERIPH_SPI5); + + /* Update the return status */ + status = SUCCESS; + } +#endif /* SPI5 */ +#if defined(SPI6) + if (SPIx == SPI6) + { + /* Force reset of SPI clock */ + LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI6); + + /* Release reset of SPI clock */ + LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI6); + + /* Update the return status */ + status = SUCCESS; + } +#endif /* SPI6 */ + + return status; +} + +/** + * @brief Initialize the SPI registers according to the specified parameters in SPI_InitStruct. + * @note As some bits in SPI configuration registers can only be written when the SPI is disabled + * (SPI_CR1_SPE bit =0), SPI IP should be in disabled state prior calling this function. + * Otherwise, ERROR result will be returned. + * @param SPIx SPI Instance + * @param SPI_InitStruct pointer to a @ref LL_SPI_InitTypeDef structure + * @retval An ErrorStatus enumeration value. (Return always SUCCESS) + */ +ErrorStatus LL_SPI_Init(SPI_TypeDef *SPIx, LL_SPI_InitTypeDef *SPI_InitStruct) +{ + ErrorStatus status = ERROR; + uint32_t tmp_nss; + uint32_t tmp_mode; + uint32_t tmp_nss_polarity; + + /* Check the SPI Instance SPIx*/ + assert_param(IS_SPI_ALL_INSTANCE(SPIx)); + + /* Check the SPI parameters from SPI_InitStruct*/ + assert_param(IS_LL_SPI_TRANSFER_DIRECTION(SPI_InitStruct->TransferDirection)); + assert_param(IS_LL_SPI_MODE(SPI_InitStruct->Mode)); + assert_param(IS_LL_SPI_DATAWIDTH(SPI_InitStruct->DataWidth)); + assert_param(IS_LL_SPI_POLARITY(SPI_InitStruct->ClockPolarity)); + assert_param(IS_LL_SPI_PHASE(SPI_InitStruct->ClockPhase)); + assert_param(IS_LL_SPI_NSS(SPI_InitStruct->NSS)); + assert_param(IS_LL_SPI_BAUDRATEPRESCALER(SPI_InitStruct->BaudRate)); + assert_param(IS_LL_SPI_BITORDER(SPI_InitStruct->BitOrder)); + assert_param(IS_LL_SPI_CRCCALCULATION(SPI_InitStruct->CRCCalculation)); + + /* Check the SPI instance is not enabled */ + if (LL_SPI_IsEnabled(SPIx) == 0x00000000UL) + { + /*---------------------------- SPIx CFG1 Configuration ------------------------ + * Configure SPIx CFG1 with parameters: + * - Master Baud Rate : SPI_CFG1_MBR[2:0] bits & SPI_CFG1_BPASS bit + * - CRC Computation Enable : SPI_CFG1_CRCEN bit + * - Length of data frame : SPI_CFG1_DSIZE[4:0] bits + */ + MODIFY_REG(SPIx->CFG1, SPI_CFG1_BPASS | SPI_CFG1_MBR | SPI_CFG1_CRCEN | SPI_CFG1_DSIZE, + SPI_InitStruct->BaudRate | SPI_InitStruct->CRCCalculation | SPI_InitStruct->DataWidth); + + tmp_nss = SPI_InitStruct->NSS; + tmp_mode = SPI_InitStruct->Mode; + tmp_nss_polarity = LL_SPI_GetNSSPolarity(SPIx); + + /* Checks to setup Internal SS signal level and avoid a MODF Error */ + if ((tmp_nss == LL_SPI_NSS_SOFT) && (((tmp_nss_polarity == LL_SPI_NSS_POLARITY_LOW) && \ + (tmp_mode == LL_SPI_MODE_MASTER)) || \ + ((tmp_nss_polarity == LL_SPI_NSS_POLARITY_HIGH) && \ + (tmp_mode == LL_SPI_MODE_SLAVE)))) + { + LL_SPI_SetInternalSSLevel(SPIx, LL_SPI_SS_LEVEL_HIGH); + } + + /*---------------------------- SPIx CFG2 Configuration ------------------------ + * Configure SPIx CFG2 with parameters: + * - NSS management : SPI_CFG2_SSM, SPI_CFG2_SSOE bits + * - ClockPolarity : SPI_CFG2_CPOL bit + * - ClockPhase : SPI_CFG2_CPHA bit + * - BitOrder : SPI_CFG2_LSBFRST bit + * - Master/Slave Mode : SPI_CFG2_MASTER bit + * - SPI Mode : SPI_CFG2_COMM[1:0] bits + */ + MODIFY_REG(SPIx->CFG2, SPI_CFG2_SSM | SPI_CFG2_SSOE | + SPI_CFG2_CPOL | SPI_CFG2_CPHA | + SPI_CFG2_LSBFRST | SPI_CFG2_MASTER | SPI_CFG2_COMM, + SPI_InitStruct->NSS | SPI_InitStruct->ClockPolarity | + SPI_InitStruct->ClockPhase | SPI_InitStruct->BitOrder | + SPI_InitStruct->Mode | (SPI_InitStruct->TransferDirection & SPI_CFG2_COMM)); + + /*---------------------------- SPIx CR1 Configuration ------------------------ + * Configure SPIx CR1 with parameter: + * - Half Duplex Direction : SPI_CR1_HDDIR bit + */ + MODIFY_REG(SPIx->CR1, SPI_CR1_HDDIR, SPI_InitStruct->TransferDirection & SPI_CR1_HDDIR); + + /*---------------------------- SPIx CRCPOLY Configuration ---------------------- + * Configure SPIx CRCPOLY with parameter: + * - CRCPoly : CRCPOLY[31:0] bits + */ + if (SPI_InitStruct->CRCCalculation == LL_SPI_CRCCALCULATION_ENABLE) + { + assert_param(IS_LL_SPI_CRC_POLYNOMIAL(SPI_InitStruct->CRCPoly)); + LL_SPI_SetCRCPolynomial(SPIx, SPI_InitStruct->CRCPoly); + } + + /* Activate the SPI mode (Reset I2SMOD bit in I2SCFGR register) */ + CLEAR_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SMOD); + + status = SUCCESS; + } + + return status; +} + +/** + * @brief Set each @ref LL_SPI_InitTypeDef field to default value. + * @param SPI_InitStruct pointer to a @ref LL_SPI_InitTypeDef structure + * whose fields will be set to default values. + * @retval None + */ +void LL_SPI_StructInit(LL_SPI_InitTypeDef *SPI_InitStruct) +{ + /* Set SPI_InitStruct fields to default values */ + SPI_InitStruct->TransferDirection = LL_SPI_FULL_DUPLEX; + SPI_InitStruct->Mode = LL_SPI_MODE_SLAVE; + SPI_InitStruct->DataWidth = LL_SPI_DATAWIDTH_8BIT; + SPI_InitStruct->ClockPolarity = LL_SPI_POLARITY_LOW; + SPI_InitStruct->ClockPhase = LL_SPI_PHASE_1EDGE; + SPI_InitStruct->NSS = LL_SPI_NSS_HARD_INPUT; + SPI_InitStruct->BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV2; + SPI_InitStruct->BitOrder = LL_SPI_MSB_FIRST; + SPI_InitStruct->CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE; + SPI_InitStruct->CRCPoly = 7UL; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +/** @addtogroup I2S_LL + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup I2S_LL_Private_Constants I2S Private Constants + * @{ + */ +/* I2S registers Masks */ +#define I2S_I2SCFGR_CLEAR_MASK (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN | \ + SPI_I2SCFGR_DATFMT | SPI_I2SCFGR_CKPOL | \ + SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_MCKOE | \ + SPI_I2SCFGR_I2SCFG | SPI_I2SCFGR_I2SMOD ) + +/** + * @} + */ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup I2S_LL_Private_Macros I2S Private Macros + * @{ + */ + +#define IS_LL_I2S_DATAFORMAT(__VALUE__) (((__VALUE__) == LL_I2S_DATAFORMAT_16B) || \ + ((__VALUE__) == LL_I2S_DATAFORMAT_16B_EXTENDED) || \ + ((__VALUE__) == LL_I2S_DATAFORMAT_24B) || \ + ((__VALUE__) == LL_I2S_DATAFORMAT_24B_LEFT_ALIGNED) || \ + ((__VALUE__) == LL_I2S_DATAFORMAT_32B)) + +#define IS_LL_I2S_CHANNEL_LENGTH_TYPE (__VALUE__) (((__VALUE__) == LL_I2S_SLAVE_VARIABLE_CH_LENGTH) || \ + ((__VALUE__) == LL_I2S_SLAVE_FIXED_CH_LENGTH)) + +#define IS_LL_I2S_CKPOL(__VALUE__) (((__VALUE__) == LL_I2S_POLARITY_LOW) || \ + ((__VALUE__) == LL_I2S_POLARITY_HIGH)) + +#define IS_LL_I2S_STANDARD(__VALUE__) (((__VALUE__) == LL_I2S_STANDARD_PHILIPS) || \ + ((__VALUE__) == LL_I2S_STANDARD_MSB) || \ + ((__VALUE__) == LL_I2S_STANDARD_LSB) || \ + ((__VALUE__) == LL_I2S_STANDARD_PCM_SHORT) || \ + ((__VALUE__) == LL_I2S_STANDARD_PCM_LONG)) + +#define IS_LL_I2S_MODE(__VALUE__) (((__VALUE__) == LL_I2S_MODE_SLAVE_TX) || \ + ((__VALUE__) == LL_I2S_MODE_SLAVE_RX) || \ + ((__VALUE__) == LL_I2S_MODE_SLAVE_FULL_DUPLEX) || \ + ((__VALUE__) == LL_I2S_MODE_MASTER_TX) || \ + ((__VALUE__) == LL_I2S_MODE_MASTER_RX) || \ + ((__VALUE__) == LL_I2S_MODE_MASTER_FULL_DUPLEX)) + +#define IS_LL_I2S_MCLK_OUTPUT(__VALUE__) (((__VALUE__) == LL_I2S_MCLK_OUTPUT_ENABLE) || \ + ((__VALUE__) == LL_I2S_MCLK_OUTPUT_DISABLE)) + +#define IS_LL_I2S_AUDIO_FREQ(__VALUE__) ((((__VALUE__) >= LL_I2S_AUDIOFREQ_8K) && \ + ((__VALUE__) <= LL_I2S_AUDIOFREQ_192K)) || \ + ((__VALUE__) == LL_I2S_AUDIOFREQ_DEFAULT)) + +#define IS_LL_I2S_PRESCALER_LINEAR(__VALUE__) ((__VALUE__) <= 0xFFUL) + +#define IS_LL_I2S_PRESCALER_PARITY(__VALUE__) (((__VALUE__) == LL_I2S_PRESCALER_PARITY_EVEN) || \ + ((__VALUE__) == LL_I2S_PRESCALER_PARITY_ODD)) + +#define IS_LL_I2S_FIFO_TH (__VALUE__) (((__VALUE__) == LL_I2S_LL_I2S_FIFO_TH_01DATA) || \ + ((__VALUE__) == LL_I2S_LL_I2S_FIFO_TH_02DATA) || \ + ((__VALUE__) == LL_I2S_LL_I2S_FIFO_TH_03DATA) || \ + ((__VALUE__) == LL_I2S_LL_I2S_FIFO_TH_04DATA) || \ + ((__VALUE__) == LL_I2S_LL_I2S_FIFO_TH_05DATA) || \ + ((__VALUE__) == LL_I2S_LL_I2S_FIFO_TH_06DATA) || \ + ((__VALUE__) == LL_I2S_LL_I2S_FIFO_TH_07DATA) || \ + ((__VALUE__) == LL_I2S_LL_I2S_FIFO_TH_08DATA)) + +#define IS_LL_I2S_BIT_ORDER(__VALUE__) (((__VALUE__) == LL_I2S_LSB_FIRST) || \ + ((__VALUE__) == LL_I2S_MSB_FIRST)) +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup I2S_LL_Exported_Functions + * @{ + */ + +/** @addtogroup I2S_LL_EF_Init + * @{ + */ + +/** + * @brief De-initialize the SPI/I2S registers to their default reset values. + * @param SPIx SPI Instance + * @retval An ErrorStatus enumeration value: + * - SUCCESS: SPI registers are de-initialized + * - ERROR: SPI registers are not de-initialized + */ +ErrorStatus LL_I2S_DeInit(const SPI_TypeDef *SPIx) +{ + return LL_SPI_DeInit(SPIx); +} + +/** + * @brief Initializes the SPI/I2S registers according to the specified parameters in I2S_InitStruct. + * @note As some bits in I2S configuration registers can only be written when the SPI is disabled + * (SPI_CR1_SPE bit =0), SPI IP should be in disabled state prior calling this function. + * Otherwise, ERROR result will be returned. + * @note I2S (SPI) source clock must be ready before calling this function. Otherwise will results + * in wrong programming. + * @param SPIx SPI Instance + * @param I2S_InitStruct pointer to a @ref LL_I2S_InitTypeDef structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: SPI registers are Initialized + * - ERROR: SPI registers are not Initialized + */ +ErrorStatus LL_I2S_Init(SPI_TypeDef *SPIx, LL_I2S_InitTypeDef *I2S_InitStruct) +{ + uint32_t i2sdiv = 0UL; + uint32_t i2sodd = 0UL; + uint32_t packetlength = 1UL; + uint32_t ispcm = 0UL; + uint32_t tmp; + uint32_t sourceclock; + + ErrorStatus status = ERROR; + + /* Check the I2S parameters */ + assert_param(IS_I2S_ALL_INSTANCE(SPIx)); + assert_param(IS_LL_I2S_MODE(I2S_InitStruct->Mode)); + assert_param(IS_LL_I2S_STANDARD(I2S_InitStruct->Standard)); + assert_param(IS_LL_I2S_DATAFORMAT(I2S_InitStruct->DataFormat)); + assert_param(IS_LL_I2S_MCLK_OUTPUT(I2S_InitStruct->MCLKOutput)); + assert_param(IS_LL_I2S_AUDIO_FREQ(I2S_InitStruct->AudioFreq)); + assert_param(IS_LL_I2S_CKPOL(I2S_InitStruct->ClockPolarity)); + + /* Check that SPE bit is set to 0 in order to be sure that SPI/I2S block is disabled. + * In this case, it is useless to check if the I2SMOD bit is set to 0 because + * this bit I2SMOD only serves to select the desired mode. + */ + if (LL_SPI_IsEnabled(SPIx) == 0x00000000UL) + { + /*---------------------------- SPIx I2SCFGR Configuration -------------------- + * Configure SPIx I2SCFGR with parameters: + * - Mode : SPI_I2SCFGR_I2SCFG[2:0] bits + * - Standard : SPI_I2SCFGR_I2SSTD[1:0] and SPI_I2SCFGR_PCMSYNC bits + * - DataFormat : SPI_I2SCFGR_CHLEN, SPI_I2SCFGR_DATFMT and SPI_I2SCFGR_DATLEN[1:0] bits + * - ClockPolarity : SPI_I2SCFGR_CKPOL bit + * - MCLKOutput : SPI_I2SPR_MCKOE bit + * - I2S mode : SPI_I2SCFGR_I2SMOD bit + */ + + /* Write to SPIx I2SCFGR */ + MODIFY_REG(SPIx->I2SCFGR, + I2S_I2SCFGR_CLEAR_MASK, + I2S_InitStruct->Mode | I2S_InitStruct->Standard | + I2S_InitStruct->DataFormat | I2S_InitStruct->ClockPolarity | + I2S_InitStruct->MCLKOutput | SPI_I2SCFGR_I2SMOD); + + /*---------------------------- SPIx I2SCFGR Configuration ---------------------- + * Configure SPIx I2SCFGR with parameters: + * - AudioFreq : SPI_I2SCFGR_I2SDIV[7:0] and SPI_I2SCFGR_ODD bits + */ + + /* If the requested audio frequency is not the default, compute the prescaler (i2sodd, i2sdiv) + * else, default values are used: i2sodd = 0U, i2sdiv = 0U. + */ + if (I2S_InitStruct->AudioFreq != LL_I2S_AUDIOFREQ_DEFAULT) + { + /* Check the frame length (For the Prescaler computing) + * Default value: LL_I2S_DATAFORMAT_16B (packetlength = 1U). + */ + if (I2S_InitStruct->DataFormat != LL_I2S_DATAFORMAT_16B) + { + /* Packet length is 32 bits */ + packetlength = 2UL; + } + + /* Check if PCM standard is used */ + if ((I2S_InitStruct->Standard == LL_I2S_STANDARD_PCM_SHORT) || + (I2S_InitStruct->Standard == LL_I2S_STANDARD_PCM_LONG)) + { + ispcm = 1UL; + } + + /* Get the I2S (SPI) source clock value */ + if (SPIx == SPI1) + { + sourceclock = LL_RCC_GetSPIClockFreq(LL_RCC_SPI1_CLKSOURCE); + } + else if (SPIx == SPI2) + { + sourceclock = LL_RCC_GetSPIClockFreq(LL_RCC_SPI2_CLKSOURCE); + } + else /* SPI3 */ + { + sourceclock = LL_RCC_GetSPIClockFreq(LL_RCC_SPI3_CLKSOURCE); + } + + /* Compute the Real divider depending on the MCLK output state with a fixed point */ + if (I2S_InitStruct->MCLKOutput == LL_I2S_MCLK_OUTPUT_ENABLE) + { + /* MCLK output is enabled */ + tmp = (((sourceclock / (256UL >> ispcm)) * 16UL) / I2S_InitStruct->AudioFreq) + 8UL; + } + else + { + /* MCLK output is disabled */ + tmp = (((sourceclock / ((32UL >> ispcm) * packetlength)) * 16UL) / I2S_InitStruct->AudioFreq) + 8UL; + } + + /* Remove the fixed point */ + tmp = tmp / 16UL; + + /* Check the parity of the divider */ + i2sodd = tmp & 0x1UL; + + /* Compute the i2sdiv prescaler */ + i2sdiv = tmp / 2UL; + } + + /* Test if the obtain values are forbidden or out of range */ + if (((i2sodd == 1UL) && (i2sdiv == 1UL)) || (i2sdiv > 0xFFUL)) + { + /* Set the default values */ + i2sdiv = 0UL; + i2sodd = 0UL; + } + + /* Write to SPIx I2SCFGR register the computed value */ + MODIFY_REG(SPIx->I2SCFGR, + SPI_I2SCFGR_ODD | SPI_I2SCFGR_I2SDIV, + (i2sodd << SPI_I2SCFGR_ODD_Pos) | (i2sdiv << SPI_I2SCFGR_I2SDIV_Pos)); + + status = SUCCESS; + } + + return status; +} + +/** + * @brief Set each @ref LL_I2S_InitTypeDef field to default value. + * @param I2S_InitStruct pointer to a @ref LL_I2S_InitTypeDef structure + * whose fields will be set to default values. + * @retval None + */ +void LL_I2S_StructInit(LL_I2S_InitTypeDef *I2S_InitStruct) +{ + /*--------------- Reset I2S init structure parameters values -----------------*/ + I2S_InitStruct->Mode = LL_I2S_MODE_SLAVE_TX; + I2S_InitStruct->Standard = LL_I2S_STANDARD_PHILIPS; + I2S_InitStruct->DataFormat = LL_I2S_DATAFORMAT_16B; + I2S_InitStruct->MCLKOutput = LL_I2S_MCLK_OUTPUT_DISABLE; + I2S_InitStruct->AudioFreq = LL_I2S_AUDIOFREQ_DEFAULT; + I2S_InitStruct->ClockPolarity = LL_I2S_POLARITY_LOW; +} + +/** + * @brief Set linear and parity prescaler. + * @note To calculate value of PrescalerLinear(I2SDIV[7:0] bits) and PrescalerParity(ODD bit)\n + * Check Audio frequency table and formulas inside Reference Manual (SPI/I2S). + * @param SPIx SPI Instance + * @param PrescalerLinear Value between Min_Data=0x00 and Max_Data=0xFF + * @note PrescalerLinear '1' is not authorized with parity LL_I2S_PRESCALER_PARITY_ODD + * @param PrescalerParity This parameter can be one of the following values: + * @arg @ref LL_I2S_PRESCALER_PARITY_EVEN + * @arg @ref LL_I2S_PRESCALER_PARITY_ODD + * @retval None + */ +void LL_I2S_ConfigPrescaler(SPI_TypeDef *SPIx, uint32_t PrescalerLinear, uint32_t PrescalerParity) +{ + /* Check the I2S parameters */ + assert_param(IS_I2S_ALL_INSTANCE(SPIx)); + assert_param(IS_LL_I2S_PRESCALER_LINEAR(PrescalerLinear)); + assert_param(IS_LL_I2S_PRESCALER_PARITY(PrescalerParity)); + + /* Write to SPIx I2SPR */ + MODIFY_REG(SPIx->I2SCFGR, SPI_I2SCFGR_I2SDIV | SPI_I2SCFGR_ODD, (PrescalerLinear << SPI_I2SCFGR_I2SDIV_Pos) | + (PrescalerParity << SPI_I2SCFGR_ODD_Pos)); +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined(SPI1) || defined(SPI2) || defined(SPI3) || defined(SPI4) || defined(SPI5) || defined(SPI6) */ + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_tim.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_tim.c new file mode 100644 index 0000000000..a5a38863d4 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_tim.c @@ -0,0 +1,1419 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_tim.c + * @author MCD Application Team + * @brief TIM LL module driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +#if defined(USE_FULL_LL_DRIVER) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_tim.h" +#include "stm32h5xx_ll_bus.h" + +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined (TIM1) \ + || defined (TIM2) \ + || defined (TIM3) \ + || defined (TIM4) \ + || defined (TIM5) \ + || defined (TIM6) \ + || defined (TIM7) \ + || defined (TIM8) \ + || defined (TIM12) \ + || defined (TIM13) \ + || defined (TIM14) \ + || defined (TIM15) \ + || defined (TIM16) \ + || defined (TIM17) + +/** @addtogroup TIM_LL + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup TIM_LL_Private_Macros + * @{ + */ +#define IS_LL_TIM_COUNTERMODE(__VALUE__) (((__VALUE__) == LL_TIM_COUNTERMODE_UP) \ + || ((__VALUE__) == LL_TIM_COUNTERMODE_DOWN) \ + || ((__VALUE__) == LL_TIM_COUNTERMODE_CENTER_UP) \ + || ((__VALUE__) == LL_TIM_COUNTERMODE_CENTER_DOWN) \ + || ((__VALUE__) == LL_TIM_COUNTERMODE_CENTER_UP_DOWN)) + +#define IS_LL_TIM_CLOCKDIVISION(__VALUE__) (((__VALUE__) == LL_TIM_CLOCKDIVISION_DIV1) \ + || ((__VALUE__) == LL_TIM_CLOCKDIVISION_DIV2) \ + || ((__VALUE__) == LL_TIM_CLOCKDIVISION_DIV4)) + +#define IS_LL_TIM_OCMODE(__VALUE__) (((__VALUE__) == LL_TIM_OCMODE_FROZEN) \ + || ((__VALUE__) == LL_TIM_OCMODE_ACTIVE) \ + || ((__VALUE__) == LL_TIM_OCMODE_INACTIVE) \ + || ((__VALUE__) == LL_TIM_OCMODE_TOGGLE) \ + || ((__VALUE__) == LL_TIM_OCMODE_FORCED_INACTIVE) \ + || ((__VALUE__) == LL_TIM_OCMODE_FORCED_ACTIVE) \ + || ((__VALUE__) == LL_TIM_OCMODE_PWM1) \ + || ((__VALUE__) == LL_TIM_OCMODE_PWM2) \ + || ((__VALUE__) == LL_TIM_OCMODE_RETRIG_OPM1) \ + || ((__VALUE__) == LL_TIM_OCMODE_RETRIG_OPM2) \ + || ((__VALUE__) == LL_TIM_OCMODE_COMBINED_PWM1) \ + || ((__VALUE__) == LL_TIM_OCMODE_COMBINED_PWM2) \ + || ((__VALUE__) == LL_TIM_OCMODE_ASSYMETRIC_PWM1) \ + || ((__VALUE__) == LL_TIM_OCMODE_ASSYMETRIC_PWM2) \ + || ((__VALUE__) == LL_TIM_OCMODE_PULSE_ON_COMPARE) \ + || ((__VALUE__) == LL_TIM_OCMODE_DIRECTION_OUTPUT)) + +#define IS_LL_TIM_OCSTATE(__VALUE__) (((__VALUE__) == LL_TIM_OCSTATE_DISABLE) \ + || ((__VALUE__) == LL_TIM_OCSTATE_ENABLE)) + +#define IS_LL_TIM_OCPOLARITY(__VALUE__) (((__VALUE__) == LL_TIM_OCPOLARITY_HIGH) \ + || ((__VALUE__) == LL_TIM_OCPOLARITY_LOW)) + +#define IS_LL_TIM_OCIDLESTATE(__VALUE__) (((__VALUE__) == LL_TIM_OCIDLESTATE_LOW) \ + || ((__VALUE__) == LL_TIM_OCIDLESTATE_HIGH)) + +#define IS_LL_TIM_ACTIVEINPUT(__VALUE__) (((__VALUE__) == LL_TIM_ACTIVEINPUT_DIRECTTI) \ + || ((__VALUE__) == LL_TIM_ACTIVEINPUT_INDIRECTTI) \ + || ((__VALUE__) == LL_TIM_ACTIVEINPUT_TRC)) + +#define IS_LL_TIM_ICPSC(__VALUE__) (((__VALUE__) == LL_TIM_ICPSC_DIV1) \ + || ((__VALUE__) == LL_TIM_ICPSC_DIV2) \ + || ((__VALUE__) == LL_TIM_ICPSC_DIV4) \ + || ((__VALUE__) == LL_TIM_ICPSC_DIV8)) + +#define IS_LL_TIM_IC_FILTER(__VALUE__) (((__VALUE__) == LL_TIM_IC_FILTER_FDIV1) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV1_N2) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV1_N4) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV1_N8) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV2_N6) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV2_N8) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV4_N6) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV4_N8) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV8_N6) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV8_N8) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV16_N5) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV16_N6) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV16_N8) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV32_N5) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV32_N6) \ + || ((__VALUE__) == LL_TIM_IC_FILTER_FDIV32_N8)) + +#define IS_LL_TIM_IC_POLARITY(__VALUE__) (((__VALUE__) == LL_TIM_IC_POLARITY_RISING) \ + || ((__VALUE__) == LL_TIM_IC_POLARITY_FALLING) \ + || ((__VALUE__) == LL_TIM_IC_POLARITY_BOTHEDGE)) + +#define IS_LL_TIM_ENCODERMODE(__VALUE__) (((__VALUE__) == LL_TIM_ENCODERMODE_X2_TI1) \ + || ((__VALUE__) == LL_TIM_ENCODERMODE_X2_TI2) \ + || ((__VALUE__) == LL_TIM_ENCODERMODE_X4_TI12) \ + || ((__VALUE__) == LL_TIM_ENCODERMODE_CLOCKPLUSDIRECTION_X2) \ + || ((__VALUE__) == LL_TIM_ENCODERMODE_CLOCKPLUSDIRECTION_X1) \ + || ((__VALUE__) == LL_TIM_ENCODERMODE_DIRECTIONALCLOCK_X2) \ + || ((__VALUE__) == LL_TIM_ENCODERMODE_DIRECTIONALCLOCK_X1_TI12) \ + || ((__VALUE__) == LL_TIM_ENCODERMODE_X1_TI1) \ + || ((__VALUE__) == LL_TIM_ENCODERMODE_X1_TI2)) + +#define IS_LL_TIM_IC_POLARITY_ENCODER(__VALUE__) (((__VALUE__) == LL_TIM_IC_POLARITY_RISING) \ + || ((__VALUE__) == LL_TIM_IC_POLARITY_FALLING)) + +#define IS_LL_TIM_OSSR_STATE(__VALUE__) (((__VALUE__) == LL_TIM_OSSR_DISABLE) \ + || ((__VALUE__) == LL_TIM_OSSR_ENABLE)) + +#define IS_LL_TIM_OSSI_STATE(__VALUE__) (((__VALUE__) == LL_TIM_OSSI_DISABLE) \ + || ((__VALUE__) == LL_TIM_OSSI_ENABLE)) + +#define IS_LL_TIM_LOCK_LEVEL(__VALUE__) (((__VALUE__) == LL_TIM_LOCKLEVEL_OFF) \ + || ((__VALUE__) == LL_TIM_LOCKLEVEL_1) \ + || ((__VALUE__) == LL_TIM_LOCKLEVEL_2) \ + || ((__VALUE__) == LL_TIM_LOCKLEVEL_3)) + +#define IS_LL_TIM_BREAK_STATE(__VALUE__) (((__VALUE__) == LL_TIM_BREAK_DISABLE) \ + || ((__VALUE__) == LL_TIM_BREAK_ENABLE)) + +#define IS_LL_TIM_BREAK_POLARITY(__VALUE__) (((__VALUE__) == LL_TIM_BREAK_POLARITY_LOW) \ + || ((__VALUE__) == LL_TIM_BREAK_POLARITY_HIGH)) + +#define IS_LL_TIM_BREAK_FILTER(__VALUE__) (((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV1) \ + || ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV1_N2) \ + || ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV1_N4) \ + || ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV1_N8) \ + || ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV2_N6) \ + || ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV2_N8) \ + || ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV4_N6) \ + || ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV4_N8) \ + || ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV8_N6) \ + || ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV8_N8) \ + || ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV16_N5) \ + || ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV16_N6) \ + || ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV16_N8) \ + || ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV32_N5) \ + || ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV32_N6) \ + || ((__VALUE__) == LL_TIM_BREAK_FILTER_FDIV32_N8)) + +#define IS_LL_TIM_BREAK_AFMODE(__VALUE__) (((__VALUE__) == LL_TIM_BREAK_AFMODE_INPUT) \ + || ((__VALUE__) == LL_TIM_BREAK_AFMODE_BIDIRECTIONAL)) + +#define IS_LL_TIM_BREAK2_STATE(__VALUE__) (((__VALUE__) == LL_TIM_BREAK2_DISABLE) \ + || ((__VALUE__) == LL_TIM_BREAK2_ENABLE)) + +#define IS_LL_TIM_BREAK2_POLARITY(__VALUE__) (((__VALUE__) == LL_TIM_BREAK2_POLARITY_LOW) \ + || ((__VALUE__) == LL_TIM_BREAK2_POLARITY_HIGH)) + +#define IS_LL_TIM_BREAK2_FILTER(__VALUE__) (((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV1) \ + || ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV1_N2) \ + || ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV1_N4) \ + || ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV1_N8) \ + || ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV2_N6) \ + || ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV2_N8) \ + || ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV4_N6) \ + || ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV4_N8) \ + || ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV8_N6) \ + || ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV8_N8) \ + || ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV16_N5) \ + || ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV16_N6) \ + || ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV16_N8) \ + || ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV32_N5) \ + || ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV32_N6) \ + || ((__VALUE__) == LL_TIM_BREAK2_FILTER_FDIV32_N8)) + +#define IS_LL_TIM_BREAK2_AFMODE(__VALUE__) (((__VALUE__) == LL_TIM_BREAK2_AFMODE_INPUT) \ + || ((__VALUE__) == LL_TIM_BREAK2_AFMODE_BIDIRECTIONAL)) + +#define IS_LL_TIM_AUTOMATIC_OUTPUT_STATE(__VALUE__) (((__VALUE__) == LL_TIM_AUTOMATICOUTPUT_DISABLE) \ + || ((__VALUE__) == LL_TIM_AUTOMATICOUTPUT_ENABLE)) +/** + * @} + */ + + +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup TIM_LL_Private_Functions TIM Private Functions + * @{ + */ +static ErrorStatus OC1Config(TIM_TypeDef *TIMx, const LL_TIM_OC_InitTypeDef *TIM_OCInitStruct); +static ErrorStatus OC2Config(TIM_TypeDef *TIMx, const LL_TIM_OC_InitTypeDef *TIM_OCInitStruct); +static ErrorStatus OC3Config(TIM_TypeDef *TIMx, const LL_TIM_OC_InitTypeDef *TIM_OCInitStruct); +static ErrorStatus OC4Config(TIM_TypeDef *TIMx, const LL_TIM_OC_InitTypeDef *TIM_OCInitStruct); +static ErrorStatus OC5Config(TIM_TypeDef *TIMx, const LL_TIM_OC_InitTypeDef *TIM_OCInitStruct); +static ErrorStatus OC6Config(TIM_TypeDef *TIMx, const LL_TIM_OC_InitTypeDef *TIM_OCInitStruct); +static ErrorStatus IC1Config(TIM_TypeDef *TIMx, const LL_TIM_IC_InitTypeDef *TIM_ICInitStruct); +static ErrorStatus IC2Config(TIM_TypeDef *TIMx, const LL_TIM_IC_InitTypeDef *TIM_ICInitStruct); +static ErrorStatus IC3Config(TIM_TypeDef *TIMx, const LL_TIM_IC_InitTypeDef *TIM_ICInitStruct); +static ErrorStatus IC4Config(TIM_TypeDef *TIMx, const LL_TIM_IC_InitTypeDef *TIM_ICInitStruct); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup TIM_LL_Exported_Functions + * @{ + */ + +/** @addtogroup TIM_LL_EF_Init + * @{ + */ + +/** + * @brief Set TIMx registers to their reset values. + * @param TIMx Timer instance + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: invalid TIMx instance + */ +ErrorStatus LL_TIM_DeInit(const TIM_TypeDef *TIMx) +{ + ErrorStatus result = SUCCESS; + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(TIMx)); + + if (TIMx == TIM1) + { + LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM1); + LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM1); + } + else if (TIMx == TIM2) + { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM2); + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM2); + } + else if (TIMx == TIM3) + { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM3); + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM3); + } +#if defined (TIM4) + else if (TIMx == TIM4) + { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM4); + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM4); + } +#endif /* TIM4 */ +#if defined (TIM5) + else if (TIMx == TIM5) + { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM5); + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM5); + } +#endif /* TIM5 */ + else if (TIMx == TIM6) + { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM6); + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM6); + } + else if (TIMx == TIM7) + { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM7); + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM7); + } +#if defined (TIM8) + else if (TIMx == TIM8) + { + LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM8); + LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM8); + } +#endif /* TIM8 */ +#if defined (TIM12) + else if (TIMx == TIM12) + { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM12); + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM12); + } +#endif /* TIM12 */ +#if defined (TIM13) + else if (TIMx == TIM13) + { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM13); + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM13); + } +#endif /* TIM13 */ +#if defined (TIM14) + else if (TIMx == TIM14) + { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM14); + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM14); + } +#endif /* TIM14 */ +#if defined (TIM15) + else if (TIMx == TIM15) + { + LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM15); + LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM15); + } +#endif /* TIM15 */ +#if defined (TIM16) + else if (TIMx == TIM16) + { + LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM16); + LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM16); + } +#endif /* TIM16 */ +#if defined (TIM17) + else if (TIMx == TIM17) + { + LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM17); + LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM17); + } +#endif /* TIM17 */ + else + { + result = ERROR; + } + + return result; +} + +/** + * @brief Set the fields of the time base unit configuration data structure + * to their default values. + * @param TIM_InitStruct pointer to a @ref LL_TIM_InitTypeDef structure (time base unit configuration data structure) + * @retval None + */ +void LL_TIM_StructInit(LL_TIM_InitTypeDef *TIM_InitStruct) +{ + /* Set the default configuration */ + TIM_InitStruct->Prescaler = (uint16_t)0x0000; + TIM_InitStruct->CounterMode = LL_TIM_COUNTERMODE_UP; + TIM_InitStruct->Autoreload = 0xFFFFFFFFU; + TIM_InitStruct->ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; + TIM_InitStruct->RepetitionCounter = 0x00000000U; +} + +/** + * @brief Configure the TIMx time base unit. + * @param TIMx Timer Instance + * @param TIM_InitStruct pointer to a @ref LL_TIM_InitTypeDef structure + * (TIMx time base unit configuration data structure) + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +ErrorStatus LL_TIM_Init(TIM_TypeDef *TIMx, const LL_TIM_InitTypeDef *TIM_InitStruct) +{ + uint32_t tmpcr1; + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_COUNTERMODE(TIM_InitStruct->CounterMode)); + assert_param(IS_LL_TIM_CLOCKDIVISION(TIM_InitStruct->ClockDivision)); + + tmpcr1 = LL_TIM_ReadReg(TIMx, CR1); + + if (IS_TIM_COUNTER_MODE_SELECT_INSTANCE(TIMx)) + { + /* Select the Counter Mode */ + MODIFY_REG(tmpcr1, (TIM_CR1_DIR | TIM_CR1_CMS), TIM_InitStruct->CounterMode); + } + + if (IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx)) + { + /* Set the clock division */ + MODIFY_REG(tmpcr1, TIM_CR1_CKD, TIM_InitStruct->ClockDivision); + } + + /* Write to TIMx CR1 */ + LL_TIM_WriteReg(TIMx, CR1, tmpcr1); + + /* Set the Autoreload value */ + LL_TIM_SetAutoReload(TIMx, TIM_InitStruct->Autoreload); + + /* Set the Prescaler value */ + LL_TIM_SetPrescaler(TIMx, TIM_InitStruct->Prescaler); + + if (IS_TIM_REPETITION_COUNTER_INSTANCE(TIMx)) + { + /* Set the Repetition Counter value */ + LL_TIM_SetRepetitionCounter(TIMx, TIM_InitStruct->RepetitionCounter); + } + + /* Generate an update event to reload the Prescaler + and the repetition counter value (if applicable) immediately */ + LL_TIM_GenerateEvent_UPDATE(TIMx); + + return SUCCESS; +} + +/** + * @brief Set the fields of the TIMx output channel configuration data + * structure to their default values. + * @param TIM_OC_InitStruct pointer to a @ref LL_TIM_OC_InitTypeDef structure + * (the output channel configuration data structure) + * @retval None + */ +void LL_TIM_OC_StructInit(LL_TIM_OC_InitTypeDef *TIM_OC_InitStruct) +{ + /* Set the default configuration */ + TIM_OC_InitStruct->OCMode = LL_TIM_OCMODE_FROZEN; + TIM_OC_InitStruct->OCState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct->OCNState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct->CompareValue = 0x00000000U; + TIM_OC_InitStruct->OCPolarity = LL_TIM_OCPOLARITY_HIGH; + TIM_OC_InitStruct->OCNPolarity = LL_TIM_OCPOLARITY_HIGH; + TIM_OC_InitStruct->OCIdleState = LL_TIM_OCIDLESTATE_LOW; + TIM_OC_InitStruct->OCNIdleState = LL_TIM_OCIDLESTATE_LOW; +} + +/** + * @brief Configure the TIMx output channel. + * @param TIMx Timer Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @arg @ref LL_TIM_CHANNEL_CH5 + * @arg @ref LL_TIM_CHANNEL_CH6 + * @param TIM_OC_InitStruct pointer to a @ref LL_TIM_OC_InitTypeDef structure (TIMx output channel configuration + * data structure) + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx output channel is initialized + * - ERROR: TIMx output channel is not initialized + */ +ErrorStatus LL_TIM_OC_Init(TIM_TypeDef *TIMx, uint32_t Channel, const LL_TIM_OC_InitTypeDef *TIM_OC_InitStruct) +{ + ErrorStatus result = ERROR; + + switch (Channel) + { + case LL_TIM_CHANNEL_CH1: + result = OC1Config(TIMx, TIM_OC_InitStruct); + break; + case LL_TIM_CHANNEL_CH2: + result = OC2Config(TIMx, TIM_OC_InitStruct); + break; + case LL_TIM_CHANNEL_CH3: + result = OC3Config(TIMx, TIM_OC_InitStruct); + break; + case LL_TIM_CHANNEL_CH4: + result = OC4Config(TIMx, TIM_OC_InitStruct); + break; + case LL_TIM_CHANNEL_CH5: + result = OC5Config(TIMx, TIM_OC_InitStruct); + break; + case LL_TIM_CHANNEL_CH6: + result = OC6Config(TIMx, TIM_OC_InitStruct); + break; + default: + break; + } + + return result; +} + +/** + * @brief Set the fields of the TIMx input channel configuration data + * structure to their default values. + * @param TIM_ICInitStruct pointer to a @ref LL_TIM_IC_InitTypeDef structure (the input channel configuration + * data structure) + * @retval None + */ +void LL_TIM_IC_StructInit(LL_TIM_IC_InitTypeDef *TIM_ICInitStruct) +{ + /* Set the default configuration */ + TIM_ICInitStruct->ICPolarity = LL_TIM_IC_POLARITY_RISING; + TIM_ICInitStruct->ICActiveInput = LL_TIM_ACTIVEINPUT_DIRECTTI; + TIM_ICInitStruct->ICPrescaler = LL_TIM_ICPSC_DIV1; + TIM_ICInitStruct->ICFilter = LL_TIM_IC_FILTER_FDIV1; +} + +/** + * @brief Configure the TIMx input channel. + * @param TIMx Timer Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param TIM_IC_InitStruct pointer to a @ref LL_TIM_IC_InitTypeDef structure (TIMx input channel configuration data + * structure) + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx output channel is initialized + * - ERROR: TIMx output channel is not initialized + */ +ErrorStatus LL_TIM_IC_Init(TIM_TypeDef *TIMx, uint32_t Channel, const LL_TIM_IC_InitTypeDef *TIM_IC_InitStruct) +{ + ErrorStatus result = ERROR; + + switch (Channel) + { + case LL_TIM_CHANNEL_CH1: + result = IC1Config(TIMx, TIM_IC_InitStruct); + break; + case LL_TIM_CHANNEL_CH2: + result = IC2Config(TIMx, TIM_IC_InitStruct); + break; + case LL_TIM_CHANNEL_CH3: + result = IC3Config(TIMx, TIM_IC_InitStruct); + break; + case LL_TIM_CHANNEL_CH4: + result = IC4Config(TIMx, TIM_IC_InitStruct); + break; + default: + break; + } + + return result; +} + +/** + * @brief Fills each TIM_EncoderInitStruct field with its default value + * @param TIM_EncoderInitStruct pointer to a @ref LL_TIM_ENCODER_InitTypeDef structure (encoder interface + * configuration data structure) + * @retval None + */ +void LL_TIM_ENCODER_StructInit(LL_TIM_ENCODER_InitTypeDef *TIM_EncoderInitStruct) +{ + /* Set the default configuration */ + TIM_EncoderInitStruct->EncoderMode = LL_TIM_ENCODERMODE_X2_TI1; + TIM_EncoderInitStruct->IC1Polarity = LL_TIM_IC_POLARITY_RISING; + TIM_EncoderInitStruct->IC1ActiveInput = LL_TIM_ACTIVEINPUT_DIRECTTI; + TIM_EncoderInitStruct->IC1Prescaler = LL_TIM_ICPSC_DIV1; + TIM_EncoderInitStruct->IC1Filter = LL_TIM_IC_FILTER_FDIV1; + TIM_EncoderInitStruct->IC2Polarity = LL_TIM_IC_POLARITY_RISING; + TIM_EncoderInitStruct->IC2ActiveInput = LL_TIM_ACTIVEINPUT_DIRECTTI; + TIM_EncoderInitStruct->IC2Prescaler = LL_TIM_ICPSC_DIV1; + TIM_EncoderInitStruct->IC2Filter = LL_TIM_IC_FILTER_FDIV1; +} + +/** + * @brief Configure the encoder interface of the timer instance. + * @param TIMx Timer Instance + * @param TIM_EncoderInitStruct pointer to a @ref LL_TIM_ENCODER_InitTypeDef structure (TIMx encoder interface + * configuration data structure) + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +ErrorStatus LL_TIM_ENCODER_Init(TIM_TypeDef *TIMx, const LL_TIM_ENCODER_InitTypeDef *TIM_EncoderInitStruct) +{ + uint32_t tmpccmr1; + uint32_t tmpccer; + + /* Check the parameters */ + assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_ENCODERMODE(TIM_EncoderInitStruct->EncoderMode)); + assert_param(IS_LL_TIM_IC_POLARITY_ENCODER(TIM_EncoderInitStruct->IC1Polarity)); + assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_EncoderInitStruct->IC1ActiveInput)); + assert_param(IS_LL_TIM_ICPSC(TIM_EncoderInitStruct->IC1Prescaler)); + assert_param(IS_LL_TIM_IC_FILTER(TIM_EncoderInitStruct->IC1Filter)); + assert_param(IS_LL_TIM_IC_POLARITY_ENCODER(TIM_EncoderInitStruct->IC2Polarity)); + assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_EncoderInitStruct->IC2ActiveInput)); + assert_param(IS_LL_TIM_ICPSC(TIM_EncoderInitStruct->IC2Prescaler)); + assert_param(IS_LL_TIM_IC_FILTER(TIM_EncoderInitStruct->IC2Filter)); + + /* Disable the CC1 and CC2: Reset the CC1E and CC2E Bits */ + TIMx->CCER &= (uint32_t)~(TIM_CCER_CC1E | TIM_CCER_CC2E); + + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1); + + /* Get the TIMx CCER register value */ + tmpccer = LL_TIM_ReadReg(TIMx, CCER); + + /* Configure TI1 */ + tmpccmr1 &= (uint32_t)~(TIM_CCMR1_CC1S | TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC); + tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC1ActiveInput >> 16U); + tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC1Filter >> 16U); + tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC1Prescaler >> 16U); + + /* Configure TI2 */ + tmpccmr1 &= (uint32_t)~(TIM_CCMR1_CC2S | TIM_CCMR1_IC2F | TIM_CCMR1_IC2PSC); + tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC2ActiveInput >> 8U); + tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC2Filter >> 8U); + tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC2Prescaler >> 8U); + + /* Set TI1 and TI2 polarity and enable TI1 and TI2 */ + tmpccer &= (uint32_t)~(TIM_CCER_CC1P | TIM_CCER_CC1NP | TIM_CCER_CC2P | TIM_CCER_CC2NP); + tmpccer |= (uint32_t)(TIM_EncoderInitStruct->IC1Polarity); + tmpccer |= (uint32_t)(TIM_EncoderInitStruct->IC2Polarity << 4U); + tmpccer |= (uint32_t)(TIM_CCER_CC1E | TIM_CCER_CC2E); + + /* Set encoder mode */ + LL_TIM_SetEncoderMode(TIMx, TIM_EncoderInitStruct->EncoderMode); + + /* Write to TIMx CCMR1 */ + LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1); + + /* Write to TIMx CCER */ + LL_TIM_WriteReg(TIMx, CCER, tmpccer); + + return SUCCESS; +} + +/** + * @brief Set the fields of the TIMx Hall sensor interface configuration data + * structure to their default values. + * @param TIM_HallSensorInitStruct pointer to a @ref LL_TIM_HALLSENSOR_InitTypeDef structure (HALL sensor interface + * configuration data structure) + * @retval None + */ +void LL_TIM_HALLSENSOR_StructInit(LL_TIM_HALLSENSOR_InitTypeDef *TIM_HallSensorInitStruct) +{ + /* Set the default configuration */ + TIM_HallSensorInitStruct->IC1Polarity = LL_TIM_IC_POLARITY_RISING; + TIM_HallSensorInitStruct->IC1Prescaler = LL_TIM_ICPSC_DIV1; + TIM_HallSensorInitStruct->IC1Filter = LL_TIM_IC_FILTER_FDIV1; + TIM_HallSensorInitStruct->CommutationDelay = 0U; +} + +/** + * @brief Configure the Hall sensor interface of the timer instance. + * @note TIMx CH1, CH2 and CH3 inputs connected through a XOR + * to the TI1 input channel + * @note TIMx slave mode controller is configured in reset mode. + Selected internal trigger is TI1F_ED. + * @note Channel 1 is configured as input, IC1 is mapped on TRC. + * @note Captured value stored in TIMx_CCR1 correspond to the time elapsed + * between 2 changes on the inputs. It gives information about motor speed. + * @note Channel 2 is configured in output PWM 2 mode. + * @note Compare value stored in TIMx_CCR2 corresponds to the commutation delay. + * @note OC2REF is selected as trigger output on TRGO. + * @note LL_TIM_IC_POLARITY_BOTHEDGE must not be used for TI1 when it is used + * when TIMx operates in Hall sensor interface mode. + * @param TIMx Timer Instance + * @param TIM_HallSensorInitStruct pointer to a @ref LL_TIM_HALLSENSOR_InitTypeDef structure (TIMx HALL sensor + * interface configuration data structure) + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +ErrorStatus LL_TIM_HALLSENSOR_Init(TIM_TypeDef *TIMx, const LL_TIM_HALLSENSOR_InitTypeDef *TIM_HallSensorInitStruct) +{ + uint32_t tmpcr2; + uint32_t tmpccmr1; + uint32_t tmpccer; + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_IC_POLARITY_ENCODER(TIM_HallSensorInitStruct->IC1Polarity)); + assert_param(IS_LL_TIM_ICPSC(TIM_HallSensorInitStruct->IC1Prescaler)); + assert_param(IS_LL_TIM_IC_FILTER(TIM_HallSensorInitStruct->IC1Filter)); + + /* Disable the CC1 and CC2: Reset the CC1E and CC2E Bits */ + TIMx->CCER &= (uint32_t)~(TIM_CCER_CC1E | TIM_CCER_CC2E); + + /* Get the TIMx CR2 register value */ + tmpcr2 = LL_TIM_ReadReg(TIMx, CR2); + + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1); + + /* Get the TIMx CCER register value */ + tmpccer = LL_TIM_ReadReg(TIMx, CCER); + + /* Get the TIMx SMCR register value */ + tmpsmcr = LL_TIM_ReadReg(TIMx, SMCR); + + /* Connect TIMx_CH1, CH2 and CH3 pins to the TI1 input */ + tmpcr2 |= TIM_CR2_TI1S; + + /* OC2REF signal is used as trigger output (TRGO) */ + tmpcr2 |= LL_TIM_TRGO_OC2REF; + + /* Configure the slave mode controller */ + tmpsmcr &= (uint32_t)~(TIM_SMCR_TS | TIM_SMCR_SMS); + tmpsmcr |= LL_TIM_TS_TI1F_ED; + tmpsmcr |= LL_TIM_SLAVEMODE_RESET; + + /* Configure input channel 1 */ + tmpccmr1 &= (uint32_t)~(TIM_CCMR1_CC1S | TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC); + tmpccmr1 |= (uint32_t)(LL_TIM_ACTIVEINPUT_TRC >> 16U); + tmpccmr1 |= (uint32_t)(TIM_HallSensorInitStruct->IC1Filter >> 16U); + tmpccmr1 |= (uint32_t)(TIM_HallSensorInitStruct->IC1Prescaler >> 16U); + + /* Configure input channel 2 */ + tmpccmr1 &= (uint32_t)~(TIM_CCMR1_OC2M | TIM_CCMR1_OC2FE | TIM_CCMR1_OC2PE | TIM_CCMR1_OC2CE); + tmpccmr1 |= (uint32_t)(LL_TIM_OCMODE_PWM2 << 8U); + + /* Set Channel 1 polarity and enable Channel 1 and Channel2 */ + tmpccer &= (uint32_t)~(TIM_CCER_CC1P | TIM_CCER_CC1NP | TIM_CCER_CC2P | TIM_CCER_CC2NP); + tmpccer |= (uint32_t)(TIM_HallSensorInitStruct->IC1Polarity); + tmpccer |= (uint32_t)(TIM_CCER_CC1E | TIM_CCER_CC2E); + + /* Write to TIMx CR2 */ + LL_TIM_WriteReg(TIMx, CR2, tmpcr2); + + /* Write to TIMx SMCR */ + LL_TIM_WriteReg(TIMx, SMCR, tmpsmcr); + + /* Write to TIMx CCMR1 */ + LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1); + + /* Write to TIMx CCER */ + LL_TIM_WriteReg(TIMx, CCER, tmpccer); + + /* Write to TIMx CCR2 */ + LL_TIM_OC_SetCompareCH2(TIMx, TIM_HallSensorInitStruct->CommutationDelay); + + return SUCCESS; +} + +/** + * @brief Set the fields of the Break and Dead Time configuration data structure + * to their default values. + * @param TIM_BDTRInitStruct pointer to a @ref LL_TIM_BDTR_InitTypeDef structure (Break and Dead Time configuration + * data structure) + * @retval None + */ +void LL_TIM_BDTR_StructInit(LL_TIM_BDTR_InitTypeDef *TIM_BDTRInitStruct) +{ + /* Set the default configuration */ + TIM_BDTRInitStruct->OSSRState = LL_TIM_OSSR_DISABLE; + TIM_BDTRInitStruct->OSSIState = LL_TIM_OSSI_DISABLE; + TIM_BDTRInitStruct->LockLevel = LL_TIM_LOCKLEVEL_OFF; + TIM_BDTRInitStruct->DeadTime = (uint8_t)0x00; + TIM_BDTRInitStruct->BreakState = LL_TIM_BREAK_DISABLE; + TIM_BDTRInitStruct->BreakPolarity = LL_TIM_BREAK_POLARITY_LOW; + TIM_BDTRInitStruct->BreakFilter = LL_TIM_BREAK_FILTER_FDIV1; + TIM_BDTRInitStruct->BreakAFMode = LL_TIM_BREAK_AFMODE_INPUT; + TIM_BDTRInitStruct->Break2State = LL_TIM_BREAK2_DISABLE; + TIM_BDTRInitStruct->Break2Polarity = LL_TIM_BREAK2_POLARITY_LOW; + TIM_BDTRInitStruct->Break2Filter = LL_TIM_BREAK2_FILTER_FDIV1; + TIM_BDTRInitStruct->Break2AFMode = LL_TIM_BREAK2_AFMODE_INPUT; + TIM_BDTRInitStruct->AutomaticOutput = LL_TIM_AUTOMATICOUTPUT_DISABLE; +} + +/** + * @brief Configure the Break and Dead Time feature of the timer instance. + * @note As the bits BK2P, BK2E, BK2F[3:0], BKF[3:0], AOE, BKP, BKE, OSSI, OSSR + * and DTG[7:0] can be write-locked depending on the LOCK configuration, it + * can be necessary to configure all of them during the first write access to + * the TIMx_BDTR register. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @note Macro IS_TIM_BKIN2_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a second break input. + * @param TIMx Timer Instance + * @param TIM_BDTRInitStruct pointer to a @ref LL_TIM_BDTR_InitTypeDef structure (Break and Dead Time configuration + * data structure) + * @retval An ErrorStatus enumeration value: + * - SUCCESS: Break and Dead Time is initialized + * - ERROR: not applicable + */ +ErrorStatus LL_TIM_BDTR_Init(TIM_TypeDef *TIMx, const LL_TIM_BDTR_InitTypeDef *TIM_BDTRInitStruct) +{ + uint32_t tmpbdtr = 0; + + /* Check the parameters */ + assert_param(IS_TIM_BREAK_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_OSSR_STATE(TIM_BDTRInitStruct->OSSRState)); + assert_param(IS_LL_TIM_OSSI_STATE(TIM_BDTRInitStruct->OSSIState)); + assert_param(IS_LL_TIM_LOCK_LEVEL(TIM_BDTRInitStruct->LockLevel)); + assert_param(IS_LL_TIM_BREAK_STATE(TIM_BDTRInitStruct->BreakState)); + assert_param(IS_LL_TIM_BREAK_POLARITY(TIM_BDTRInitStruct->BreakPolarity)); + assert_param(IS_LL_TIM_AUTOMATIC_OUTPUT_STATE(TIM_BDTRInitStruct->AutomaticOutput)); + + /* Set the Lock level, the Break enable Bit and the Polarity, the OSSR State, + the OSSI State, the dead time value and the Automatic Output Enable Bit */ + + /* Set the BDTR bits */ + MODIFY_REG(tmpbdtr, TIM_BDTR_DTG, TIM_BDTRInitStruct->DeadTime); + MODIFY_REG(tmpbdtr, TIM_BDTR_LOCK, TIM_BDTRInitStruct->LockLevel); + MODIFY_REG(tmpbdtr, TIM_BDTR_OSSI, TIM_BDTRInitStruct->OSSIState); + MODIFY_REG(tmpbdtr, TIM_BDTR_OSSR, TIM_BDTRInitStruct->OSSRState); + MODIFY_REG(tmpbdtr, TIM_BDTR_BKE, TIM_BDTRInitStruct->BreakState); + MODIFY_REG(tmpbdtr, TIM_BDTR_BKP, TIM_BDTRInitStruct->BreakPolarity); + MODIFY_REG(tmpbdtr, TIM_BDTR_AOE, TIM_BDTRInitStruct->AutomaticOutput); + assert_param(IS_LL_TIM_BREAK_FILTER(TIM_BDTRInitStruct->BreakFilter)); + assert_param(IS_LL_TIM_BREAK_AFMODE(TIM_BDTRInitStruct->BreakAFMode)); + MODIFY_REG(tmpbdtr, TIM_BDTR_BKF, TIM_BDTRInitStruct->BreakFilter); + MODIFY_REG(tmpbdtr, TIM_BDTR_BKBID, TIM_BDTRInitStruct->BreakAFMode); + + if (IS_TIM_BKIN2_INSTANCE(TIMx)) + { + assert_param(IS_LL_TIM_BREAK2_STATE(TIM_BDTRInitStruct->Break2State)); + assert_param(IS_LL_TIM_BREAK2_POLARITY(TIM_BDTRInitStruct->Break2Polarity)); + assert_param(IS_LL_TIM_BREAK2_FILTER(TIM_BDTRInitStruct->Break2Filter)); + assert_param(IS_LL_TIM_BREAK2_AFMODE(TIM_BDTRInitStruct->Break2AFMode)); + + /* Set the BREAK2 input related BDTR bit-fields */ + MODIFY_REG(tmpbdtr, TIM_BDTR_BK2F, (TIM_BDTRInitStruct->Break2Filter)); + MODIFY_REG(tmpbdtr, TIM_BDTR_BK2E, TIM_BDTRInitStruct->Break2State); + MODIFY_REG(tmpbdtr, TIM_BDTR_BK2P, TIM_BDTRInitStruct->Break2Polarity); + MODIFY_REG(tmpbdtr, TIM_BDTR_BK2BID, TIM_BDTRInitStruct->Break2AFMode); + } + + /* Set TIMx_BDTR */ + LL_TIM_WriteReg(TIMx, BDTR, tmpbdtr); + + return SUCCESS; +} +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup TIM_LL_Private_Functions TIM Private Functions + * @brief Private functions + * @{ + */ +/** + * @brief Configure the TIMx output channel 1. + * @param TIMx Timer Instance + * @param TIM_OCInitStruct pointer to the the TIMx output channel 1 configuration data structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +static ErrorStatus OC1Config(TIM_TypeDef *TIMx, const LL_TIM_OC_InitTypeDef *TIM_OCInitStruct) +{ + uint32_t tmpccmr1; + uint32_t tmpccer; + uint32_t tmpcr2; + + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode)); + assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState)); + assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity)); + assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCNState)); + assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCNPolarity)); + + /* Disable the Channel 1: Reset the CC1E Bit */ + CLEAR_BIT(TIMx->CCER, TIM_CCER_CC1E); + + /* Get the TIMx CCER register value */ + tmpccer = LL_TIM_ReadReg(TIMx, CCER); + + /* Get the TIMx CR2 register value */ + tmpcr2 = LL_TIM_ReadReg(TIMx, CR2); + + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1); + + /* Reset Capture/Compare selection Bits */ + CLEAR_BIT(tmpccmr1, TIM_CCMR1_CC1S); + + /* Set the Output Compare Mode */ + MODIFY_REG(tmpccmr1, TIM_CCMR1_OC1M, TIM_OCInitStruct->OCMode); + + /* Set the Output Compare Polarity */ + MODIFY_REG(tmpccer, TIM_CCER_CC1P, TIM_OCInitStruct->OCPolarity); + + /* Set the Output State */ + MODIFY_REG(tmpccer, TIM_CCER_CC1E, TIM_OCInitStruct->OCState); + + if (IS_TIM_BREAK_INSTANCE(TIMx)) + { + assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCNIdleState)); + assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCIdleState)); + + /* Set the complementary output Polarity */ + MODIFY_REG(tmpccer, TIM_CCER_CC1NP, TIM_OCInitStruct->OCNPolarity << 2U); + + /* Set the complementary output State */ + MODIFY_REG(tmpccer, TIM_CCER_CC1NE, TIM_OCInitStruct->OCNState << 2U); + + /* Set the Output Idle state */ + MODIFY_REG(tmpcr2, TIM_CR2_OIS1, TIM_OCInitStruct->OCIdleState); + + /* Set the complementary output Idle state */ + MODIFY_REG(tmpcr2, TIM_CR2_OIS1N, TIM_OCInitStruct->OCNIdleState << 1U); + } + + /* Write to TIMx CR2 */ + LL_TIM_WriteReg(TIMx, CR2, tmpcr2); + + /* Write to TIMx CCMR1 */ + LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1); + + /* Set the Capture Compare Register value */ + LL_TIM_OC_SetCompareCH1(TIMx, TIM_OCInitStruct->CompareValue); + + /* Write to TIMx CCER */ + LL_TIM_WriteReg(TIMx, CCER, tmpccer); + + return SUCCESS; +} + +/** + * @brief Configure the TIMx output channel 2. + * @param TIMx Timer Instance + * @param TIM_OCInitStruct pointer to the the TIMx output channel 2 configuration data structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +static ErrorStatus OC2Config(TIM_TypeDef *TIMx, const LL_TIM_OC_InitTypeDef *TIM_OCInitStruct) +{ + uint32_t tmpccmr1; + uint32_t tmpccer; + uint32_t tmpcr2; + + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode)); + assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState)); + assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity)); + assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCNState)); + assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCNPolarity)); + + /* Disable the Channel 2: Reset the CC2E Bit */ + CLEAR_BIT(TIMx->CCER, TIM_CCER_CC2E); + + /* Get the TIMx CCER register value */ + tmpccer = LL_TIM_ReadReg(TIMx, CCER); + + /* Get the TIMx CR2 register value */ + tmpcr2 = LL_TIM_ReadReg(TIMx, CR2); + + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1); + + /* Reset Capture/Compare selection Bits */ + CLEAR_BIT(tmpccmr1, TIM_CCMR1_CC2S); + + /* Select the Output Compare Mode */ + MODIFY_REG(tmpccmr1, TIM_CCMR1_OC2M, TIM_OCInitStruct->OCMode << 8U); + + /* Set the Output Compare Polarity */ + MODIFY_REG(tmpccer, TIM_CCER_CC2P, TIM_OCInitStruct->OCPolarity << 4U); + + /* Set the Output State */ + MODIFY_REG(tmpccer, TIM_CCER_CC2E, TIM_OCInitStruct->OCState << 4U); + + if (IS_TIM_BREAK_INSTANCE(TIMx)) + { + assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCNIdleState)); + assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCIdleState)); + + /* Set the complementary output Polarity */ + MODIFY_REG(tmpccer, TIM_CCER_CC2NP, TIM_OCInitStruct->OCNPolarity << 6U); + + /* Set the complementary output State */ + MODIFY_REG(tmpccer, TIM_CCER_CC2NE, TIM_OCInitStruct->OCNState << 6U); + + /* Set the Output Idle state */ + MODIFY_REG(tmpcr2, TIM_CR2_OIS2, TIM_OCInitStruct->OCIdleState << 2U); + + /* Set the complementary output Idle state */ + MODIFY_REG(tmpcr2, TIM_CR2_OIS2N, TIM_OCInitStruct->OCNIdleState << 3U); + } + + /* Write to TIMx CR2 */ + LL_TIM_WriteReg(TIMx, CR2, tmpcr2); + + /* Write to TIMx CCMR1 */ + LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1); + + /* Set the Capture Compare Register value */ + LL_TIM_OC_SetCompareCH2(TIMx, TIM_OCInitStruct->CompareValue); + + /* Write to TIMx CCER */ + LL_TIM_WriteReg(TIMx, CCER, tmpccer); + + return SUCCESS; +} + +/** + * @brief Configure the TIMx output channel 3. + * @param TIMx Timer Instance + * @param TIM_OCInitStruct pointer to the the TIMx output channel 3 configuration data structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +static ErrorStatus OC3Config(TIM_TypeDef *TIMx, const LL_TIM_OC_InitTypeDef *TIM_OCInitStruct) +{ + uint32_t tmpccmr2; + uint32_t tmpccer; + uint32_t tmpcr2; + + /* Check the parameters */ + assert_param(IS_TIM_CC3_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode)); + assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState)); + assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity)); + assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCNState)); + assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCNPolarity)); + + /* Disable the Channel 3: Reset the CC3E Bit */ + CLEAR_BIT(TIMx->CCER, TIM_CCER_CC3E); + + /* Get the TIMx CCER register value */ + tmpccer = LL_TIM_ReadReg(TIMx, CCER); + + /* Get the TIMx CR2 register value */ + tmpcr2 = LL_TIM_ReadReg(TIMx, CR2); + + /* Get the TIMx CCMR2 register value */ + tmpccmr2 = LL_TIM_ReadReg(TIMx, CCMR2); + + /* Reset Capture/Compare selection Bits */ + CLEAR_BIT(tmpccmr2, TIM_CCMR2_CC3S); + + /* Select the Output Compare Mode */ + MODIFY_REG(tmpccmr2, TIM_CCMR2_OC3M, TIM_OCInitStruct->OCMode); + + /* Set the Output Compare Polarity */ + MODIFY_REG(tmpccer, TIM_CCER_CC3P, TIM_OCInitStruct->OCPolarity << 8U); + + /* Set the Output State */ + MODIFY_REG(tmpccer, TIM_CCER_CC3E, TIM_OCInitStruct->OCState << 8U); + + if (IS_TIM_BREAK_INSTANCE(TIMx)) + { + assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCNIdleState)); + assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCIdleState)); + + /* Set the complementary output Polarity */ + MODIFY_REG(tmpccer, TIM_CCER_CC3NP, TIM_OCInitStruct->OCNPolarity << 10U); + + /* Set the complementary output State */ + MODIFY_REG(tmpccer, TIM_CCER_CC3NE, TIM_OCInitStruct->OCNState << 10U); + + /* Set the Output Idle state */ + MODIFY_REG(tmpcr2, TIM_CR2_OIS3, TIM_OCInitStruct->OCIdleState << 4U); + + /* Set the complementary output Idle state */ + MODIFY_REG(tmpcr2, TIM_CR2_OIS3N, TIM_OCInitStruct->OCNIdleState << 5U); + } + + /* Write to TIMx CR2 */ + LL_TIM_WriteReg(TIMx, CR2, tmpcr2); + + /* Write to TIMx CCMR2 */ + LL_TIM_WriteReg(TIMx, CCMR2, tmpccmr2); + + /* Set the Capture Compare Register value */ + LL_TIM_OC_SetCompareCH3(TIMx, TIM_OCInitStruct->CompareValue); + + /* Write to TIMx CCER */ + LL_TIM_WriteReg(TIMx, CCER, tmpccer); + + return SUCCESS; +} + +/** + * @brief Configure the TIMx output channel 4. + * @param TIMx Timer Instance + * @param TIM_OCInitStruct pointer to the the TIMx output channel 4 configuration data structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +static ErrorStatus OC4Config(TIM_TypeDef *TIMx, const LL_TIM_OC_InitTypeDef *TIM_OCInitStruct) +{ + uint32_t tmpccmr2; + uint32_t tmpccer; + uint32_t tmpcr2; + + /* Check the parameters */ + assert_param(IS_TIM_CC4_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode)); + assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState)); + assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity)); + assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCNPolarity)); + assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCNState)); + + /* Disable the Channel 4: Reset the CC4E Bit */ + CLEAR_BIT(TIMx->CCER, TIM_CCER_CC4E); + + /* Get the TIMx CCER register value */ + tmpccer = LL_TIM_ReadReg(TIMx, CCER); + + /* Get the TIMx CR2 register value */ + tmpcr2 = LL_TIM_ReadReg(TIMx, CR2); + + /* Get the TIMx CCMR2 register value */ + tmpccmr2 = LL_TIM_ReadReg(TIMx, CCMR2); + + /* Reset Capture/Compare selection Bits */ + CLEAR_BIT(tmpccmr2, TIM_CCMR2_CC4S); + + /* Select the Output Compare Mode */ + MODIFY_REG(tmpccmr2, TIM_CCMR2_OC4M, TIM_OCInitStruct->OCMode << 8U); + + /* Set the Output Compare Polarity */ + MODIFY_REG(tmpccer, TIM_CCER_CC4P, TIM_OCInitStruct->OCPolarity << 12U); + + /* Set the Output State */ + MODIFY_REG(tmpccer, TIM_CCER_CC4E, TIM_OCInitStruct->OCState << 12U); + + if (IS_TIM_BREAK_INSTANCE(TIMx)) + { + assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCNIdleState)); + assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCIdleState)); + + /* Set the complementary output Polarity */ + MODIFY_REG(tmpccer, TIM_CCER_CC4NP, TIM_OCInitStruct->OCNPolarity << 14U); + + /* Set the complementary output State */ + MODIFY_REG(tmpccer, TIM_CCER_CC4NE, TIM_OCInitStruct->OCNState << 14U); + + /* Set the Output Idle state */ + MODIFY_REG(tmpcr2, TIM_CR2_OIS4, TIM_OCInitStruct->OCIdleState << 6U); + + /* Set the complementary output Idle state */ + MODIFY_REG(tmpcr2, TIM_CR2_OIS4N, TIM_OCInitStruct->OCNIdleState << 7U); + } + + /* Write to TIMx CR2 */ + LL_TIM_WriteReg(TIMx, CR2, tmpcr2); + + /* Write to TIMx CCMR2 */ + LL_TIM_WriteReg(TIMx, CCMR2, tmpccmr2); + + /* Set the Capture Compare Register value */ + LL_TIM_OC_SetCompareCH4(TIMx, TIM_OCInitStruct->CompareValue); + + /* Write to TIMx CCER */ + LL_TIM_WriteReg(TIMx, CCER, tmpccer); + + return SUCCESS; +} + +/** + * @brief Configure the TIMx output channel 5. + * @param TIMx Timer Instance + * @param TIM_OCInitStruct pointer to the the TIMx output channel 5 configuration data structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +static ErrorStatus OC5Config(TIM_TypeDef *TIMx, const LL_TIM_OC_InitTypeDef *TIM_OCInitStruct) +{ + uint32_t tmpccmr3; + uint32_t tmpccer; + + /* Check the parameters */ + assert_param(IS_TIM_CC5_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode)); + assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState)); + assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity)); + assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCNPolarity)); + assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCNState)); + + /* Disable the Channel 5: Reset the CC5E Bit */ + CLEAR_BIT(TIMx->CCER, TIM_CCER_CC5E); + + /* Get the TIMx CCER register value */ + tmpccer = LL_TIM_ReadReg(TIMx, CCER); + + /* Get the TIMx CCMR3 register value */ + tmpccmr3 = LL_TIM_ReadReg(TIMx, CCMR3); + + /* Select the Output Compare Mode */ + MODIFY_REG(tmpccmr3, TIM_CCMR3_OC5M, TIM_OCInitStruct->OCMode); + + /* Set the Output Compare Polarity */ + MODIFY_REG(tmpccer, TIM_CCER_CC5P, TIM_OCInitStruct->OCPolarity << 16U); + + /* Set the Output State */ + MODIFY_REG(tmpccer, TIM_CCER_CC5E, TIM_OCInitStruct->OCState << 16U); + + if (IS_TIM_BREAK_INSTANCE(TIMx)) + { + assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCNIdleState)); + assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCIdleState)); + + /* Set the Output Idle state */ + MODIFY_REG(TIMx->CR2, TIM_CR2_OIS5, TIM_OCInitStruct->OCIdleState << 8U); + + } + + /* Write to TIMx CCMR3 */ + LL_TIM_WriteReg(TIMx, CCMR3, tmpccmr3); + + /* Set the Capture Compare Register value */ + LL_TIM_OC_SetCompareCH5(TIMx, TIM_OCInitStruct->CompareValue); + + /* Write to TIMx CCER */ + LL_TIM_WriteReg(TIMx, CCER, tmpccer); + + return SUCCESS; +} + +/** + * @brief Configure the TIMx output channel 6. + * @param TIMx Timer Instance + * @param TIM_OCInitStruct pointer to the the TIMx output channel 6 configuration data structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +static ErrorStatus OC6Config(TIM_TypeDef *TIMx, const LL_TIM_OC_InitTypeDef *TIM_OCInitStruct) +{ + uint32_t tmpccmr3; + uint32_t tmpccer; + + /* Check the parameters */ + assert_param(IS_TIM_CC6_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode)); + assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState)); + assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity)); + assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCNPolarity)); + assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCNState)); + + /* Disable the Channel 5: Reset the CC6E Bit */ + CLEAR_BIT(TIMx->CCER, TIM_CCER_CC6E); + + /* Get the TIMx CCER register value */ + tmpccer = LL_TIM_ReadReg(TIMx, CCER); + + /* Get the TIMx CCMR3 register value */ + tmpccmr3 = LL_TIM_ReadReg(TIMx, CCMR3); + + /* Select the Output Compare Mode */ + MODIFY_REG(tmpccmr3, TIM_CCMR3_OC6M, TIM_OCInitStruct->OCMode << 8U); + + /* Set the Output Compare Polarity */ + MODIFY_REG(tmpccer, TIM_CCER_CC6P, TIM_OCInitStruct->OCPolarity << 20U); + + /* Set the Output State */ + MODIFY_REG(tmpccer, TIM_CCER_CC6E, TIM_OCInitStruct->OCState << 20U); + + if (IS_TIM_BREAK_INSTANCE(TIMx)) + { + assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCNIdleState)); + assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCIdleState)); + + /* Set the Output Idle state */ + MODIFY_REG(TIMx->CR2, TIM_CR2_OIS6, TIM_OCInitStruct->OCIdleState << 10U); + } + + /* Write to TIMx CCMR3 */ + LL_TIM_WriteReg(TIMx, CCMR3, tmpccmr3); + + /* Set the Capture Compare Register value */ + LL_TIM_OC_SetCompareCH6(TIMx, TIM_OCInitStruct->CompareValue); + + /* Write to TIMx CCER */ + LL_TIM_WriteReg(TIMx, CCER, tmpccer); + + return SUCCESS; +} + +/** + * @brief Configure the TIMx input channel 1. + * @param TIMx Timer Instance + * @param TIM_ICInitStruct pointer to the the TIMx input channel 1 configuration data structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +static ErrorStatus IC1Config(TIM_TypeDef *TIMx, const LL_TIM_IC_InitTypeDef *TIM_ICInitStruct) +{ + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_IC_POLARITY(TIM_ICInitStruct->ICPolarity)); + assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput)); + assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler)); + assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter)); + + /* Disable the Channel 1: Reset the CC1E Bit */ + TIMx->CCER &= (uint32_t)~TIM_CCER_CC1E; + + /* Select the Input and set the filter and the prescaler value */ + MODIFY_REG(TIMx->CCMR1, + (TIM_CCMR1_CC1S | TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC), + (TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | TIM_ICInitStruct->ICPrescaler) >> 16U); + + /* Select the Polarity and set the CC1E Bit */ + MODIFY_REG(TIMx->CCER, + (TIM_CCER_CC1P | TIM_CCER_CC1NP), + (TIM_ICInitStruct->ICPolarity | TIM_CCER_CC1E)); + + return SUCCESS; +} + +/** + * @brief Configure the TIMx input channel 2. + * @param TIMx Timer Instance + * @param TIM_ICInitStruct pointer to the the TIMx input channel 2 configuration data structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +static ErrorStatus IC2Config(TIM_TypeDef *TIMx, const LL_TIM_IC_InitTypeDef *TIM_ICInitStruct) +{ + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_IC_POLARITY(TIM_ICInitStruct->ICPolarity)); + assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput)); + assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler)); + assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter)); + + /* Disable the Channel 2: Reset the CC2E Bit */ + TIMx->CCER &= (uint32_t)~TIM_CCER_CC2E; + + /* Select the Input and set the filter and the prescaler value */ + MODIFY_REG(TIMx->CCMR1, + (TIM_CCMR1_CC2S | TIM_CCMR1_IC2F | TIM_CCMR1_IC2PSC), + (TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | TIM_ICInitStruct->ICPrescaler) >> 8U); + + /* Select the Polarity and set the CC2E Bit */ + MODIFY_REG(TIMx->CCER, + (TIM_CCER_CC2P | TIM_CCER_CC2NP), + ((TIM_ICInitStruct->ICPolarity << 4U) | TIM_CCER_CC2E)); + + return SUCCESS; +} + +/** + * @brief Configure the TIMx input channel 3. + * @param TIMx Timer Instance + * @param TIM_ICInitStruct pointer to the the TIMx input channel 3 configuration data structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +static ErrorStatus IC3Config(TIM_TypeDef *TIMx, const LL_TIM_IC_InitTypeDef *TIM_ICInitStruct) +{ + /* Check the parameters */ + assert_param(IS_TIM_CC3_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_IC_POLARITY(TIM_ICInitStruct->ICPolarity)); + assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput)); + assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler)); + assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter)); + + /* Disable the Channel 3: Reset the CC3E Bit */ + TIMx->CCER &= (uint32_t)~TIM_CCER_CC3E; + + /* Select the Input and set the filter and the prescaler value */ + MODIFY_REG(TIMx->CCMR2, + (TIM_CCMR2_CC3S | TIM_CCMR2_IC3F | TIM_CCMR2_IC3PSC), + (TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | TIM_ICInitStruct->ICPrescaler) >> 16U); + + /* Select the Polarity and set the CC3E Bit */ + MODIFY_REG(TIMx->CCER, + (TIM_CCER_CC3P | TIM_CCER_CC3NP), + ((TIM_ICInitStruct->ICPolarity << 8U) | TIM_CCER_CC3E)); + + return SUCCESS; +} + +/** + * @brief Configure the TIMx input channel 4. + * @param TIMx Timer Instance + * @param TIM_ICInitStruct pointer to the the TIMx input channel 4 configuration data structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +static ErrorStatus IC4Config(TIM_TypeDef *TIMx, const LL_TIM_IC_InitTypeDef *TIM_ICInitStruct) +{ + /* Check the parameters */ + assert_param(IS_TIM_CC4_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_IC_POLARITY(TIM_ICInitStruct->ICPolarity)); + assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput)); + assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler)); + assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter)); + + /* Disable the Channel 4: Reset the CC4E Bit */ + TIMx->CCER &= (uint32_t)~TIM_CCER_CC4E; + + /* Select the Input and set the filter and the prescaler value */ + MODIFY_REG(TIMx->CCMR2, + (TIM_CCMR2_CC4S | TIM_CCMR2_IC4F | TIM_CCMR2_IC4PSC), + (TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | TIM_ICInitStruct->ICPrescaler) >> 8U); + + /* Select the Polarity and set the CC2E Bit */ + MODIFY_REG(TIMx->CCER, + (TIM_CCER_CC4P | TIM_CCER_CC4NP), + ((TIM_ICInitStruct->ICPolarity << 12U) | TIM_CCER_CC4E)); + + return SUCCESS; +} + + +/** + * @} + */ + +/** + * @} + */ + +#endif /* TIM1 || TIM2 || TIM3 || TIM4 || TIM5 || TIM6 || TIM7 || TIM8 || TIM12 || TIM13 || TIM14 || TIM15 || TIM16 || TIM17 */ + +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_ucpd.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_ucpd.c new file mode 100644 index 0000000000..77ea79eb6f --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_ucpd.c @@ -0,0 +1,169 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_ucpd.c + * @author MCD Application Team + * @brief UCPD LL module driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +#if defined(USE_FULL_LL_DRIVER) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_ucpd.h" +#include "stm32h5xx_ll_bus.h" +#include "stm32h5xx_ll_rcc.h" + +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ +#if defined (UCPD1) +/** @addtogroup UCPD_LL + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup UCPD_LL_Private_Constants UCPD Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup UCPD_LL_Private_Macros UCPD Private Macros + * @{ + */ + + +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup UCPD_LL_Exported_Functions + * @{ + */ + +/** @addtogroup UCPD_LL_EF_Init + * @{ + */ + +/** + * @brief De-initialize the UCPD registers to their default reset values. + * @param UCPDx ucpd Instance + * @retval An ErrorStatus enumeration value: + * - SUCCESS: ucpd registers are de-initialized + * - ERROR: ucpd registers are not de-initialized + */ +ErrorStatus LL_UCPD_DeInit(UCPD_TypeDef *UCPDx) +{ + ErrorStatus status = ERROR; + + /* Check the parameters */ + assert_param(IS_UCPD_ALL_INSTANCE(UCPDx)); + + LL_UCPD_Disable(UCPDx); + + if (UCPD1 == UCPDx) + { + /* Force reset of ucpd clock */ + LL_APB1_GRP2_ForceReset(LL_APB1_GRP2_PERIPH_UCPD1); + + /* Release reset of ucpd clock */ + LL_APB1_GRP2_ReleaseReset(LL_APB1_GRP2_PERIPH_UCPD1); + + /* Disable ucpd clock */ + LL_APB1_GRP2_DisableClock(LL_APB1_GRP2_PERIPH_UCPD1); + + status = SUCCESS; + } + + return status; +} + +/** + * @brief Initialize the ucpd registers according to the specified parameters in UCPD_InitStruct. + * @note As some bits in ucpd configuration registers can only be written when the ucpd is disabled + * (ucpd_CR1_SPE bit =0), UCPD peripheral should be in disabled state prior calling this function. + * Otherwise, ERROR result will be returned. + * @param UCPDx UCPD Instance + * @param UCPD_InitStruct pointer to a @ref LL_UCPD_InitTypeDef structure that contains + * the configuration information for the UCPD peripheral. + * @retval An ErrorStatus enumeration value. (Return always SUCCESS) + */ +ErrorStatus LL_UCPD_Init(UCPD_TypeDef *UCPDx, LL_UCPD_InitTypeDef *UCPD_InitStruct) +{ + /* Check the ucpd Instance UCPDx*/ + assert_param(IS_UCPD_ALL_INSTANCE(UCPDx)); + + if (UCPD1 == UCPDx) + { + LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_UCPD1); + } + + + LL_UCPD_Disable(UCPDx); + + /*---------------------------- UCPDx CFG1 Configuration ------------------------*/ + MODIFY_REG(UCPDx->CFG1, + UCPD_CFG1_PSC_UCPDCLK | UCPD_CFG1_TRANSWIN | UCPD_CFG1_IFRGAP | UCPD_CFG1_HBITCLKDIV, + UCPD_InitStruct->psc_ucpdclk | (UCPD_InitStruct->transwin << UCPD_CFG1_TRANSWIN_Pos) | + (UCPD_InitStruct->IfrGap << UCPD_CFG1_IFRGAP_Pos) | UCPD_InitStruct->HbitClockDiv); + + return SUCCESS; +} + +/** + * @brief Set each @ref LL_UCPD_InitTypeDef field to default value. + * @param UCPD_InitStruct pointer to a @ref LL_UCPD_InitTypeDef structure + * whose fields will be set to default values. + * @retval None + */ +void LL_UCPD_StructInit(LL_UCPD_InitTypeDef *UCPD_InitStruct) +{ + /* Set UCPD_InitStruct fields to default values */ + UCPD_InitStruct->psc_ucpdclk = LL_UCPD_PSC_DIV2; + UCPD_InitStruct->transwin = 0x7; /* Divide by 8 */ + UCPD_InitStruct->IfrGap = 0x10; /* Divide by 17 */ + UCPD_InitStruct->HbitClockDiv = 0x0D; /* Divide by 14 to produce HBITCLK */ +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* defined (UCPD1) */ +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_usart.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_usart.c new file mode 100644 index 0000000000..7ac11b1495 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_usart.c @@ -0,0 +1,548 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_usart.c + * @author MCD Application Team + * @brief USART LL module driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +#if defined(USE_FULL_LL_DRIVER) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_usart.h" +#include "stm32h5xx_ll_rcc.h" +#include "stm32h5xx_ll_bus.h" +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +#if defined(USART1) || defined(USART2) || defined(USART3) || defined(UART4) || defined(UART5) || defined(USART6) \ + || defined(UART7) || defined(UART8) || defined(UART9) || defined(USART10) || defined(USART11) || defined(UART12) + +/** @addtogroup USART_LL + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @addtogroup USART_LL_Private_Constants + * @{ + */ + +/* Definition of default baudrate value used for USART initialisation */ +#define USART_DEFAULT_BAUDRATE (9600U) + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup USART_LL_Private_Macros + * @{ + */ + +#define IS_LL_USART_PRESCALER(__VALUE__) (((__VALUE__) == LL_USART_PRESCALER_DIV1) \ + || ((__VALUE__) == LL_USART_PRESCALER_DIV2) \ + || ((__VALUE__) == LL_USART_PRESCALER_DIV4) \ + || ((__VALUE__) == LL_USART_PRESCALER_DIV6) \ + || ((__VALUE__) == LL_USART_PRESCALER_DIV8) \ + || ((__VALUE__) == LL_USART_PRESCALER_DIV10) \ + || ((__VALUE__) == LL_USART_PRESCALER_DIV12) \ + || ((__VALUE__) == LL_USART_PRESCALER_DIV16) \ + || ((__VALUE__) == LL_USART_PRESCALER_DIV32) \ + || ((__VALUE__) == LL_USART_PRESCALER_DIV64) \ + || ((__VALUE__) == LL_USART_PRESCALER_DIV128) \ + || ((__VALUE__) == LL_USART_PRESCALER_DIV256)) + +/* __BAUDRATE__ The maximum Baud Rate is derived from the maximum clock available + * divided by the smallest oversampling used on the USART (i.e. 8) */ +#define IS_LL_USART_BAUDRATE(__BAUDRATE__) ((__BAUDRATE__) <= 20000000U) + +/* __VALUE__ In case of oversampling by 16 and 8, BRR content must be greater than or equal to 16d. */ +#define IS_LL_USART_BRR_MIN(__VALUE__) ((__VALUE__) >= 16U) + +#define IS_LL_USART_DIRECTION(__VALUE__) (((__VALUE__) == LL_USART_DIRECTION_NONE) \ + || ((__VALUE__) == LL_USART_DIRECTION_RX) \ + || ((__VALUE__) == LL_USART_DIRECTION_TX) \ + || ((__VALUE__) == LL_USART_DIRECTION_TX_RX)) + +#define IS_LL_USART_PARITY(__VALUE__) (((__VALUE__) == LL_USART_PARITY_NONE) \ + || ((__VALUE__) == LL_USART_PARITY_EVEN) \ + || ((__VALUE__) == LL_USART_PARITY_ODD)) + +#define IS_LL_USART_DATAWIDTH(__VALUE__) (((__VALUE__) == LL_USART_DATAWIDTH_7B) \ + || ((__VALUE__) == LL_USART_DATAWIDTH_8B) \ + || ((__VALUE__) == LL_USART_DATAWIDTH_9B)) + +#define IS_LL_USART_OVERSAMPLING(__VALUE__) (((__VALUE__) == LL_USART_OVERSAMPLING_16) \ + || ((__VALUE__) == LL_USART_OVERSAMPLING_8)) + +#define IS_LL_USART_LASTBITCLKOUTPUT(__VALUE__) (((__VALUE__) == LL_USART_LASTCLKPULSE_NO_OUTPUT) \ + || ((__VALUE__) == LL_USART_LASTCLKPULSE_OUTPUT)) + +#define IS_LL_USART_CLOCKPHASE(__VALUE__) (((__VALUE__) == LL_USART_PHASE_1EDGE) \ + || ((__VALUE__) == LL_USART_PHASE_2EDGE)) + +#define IS_LL_USART_CLOCKPOLARITY(__VALUE__) (((__VALUE__) == LL_USART_POLARITY_LOW) \ + || ((__VALUE__) == LL_USART_POLARITY_HIGH)) + +#define IS_LL_USART_CLOCKOUTPUT(__VALUE__) (((__VALUE__) == LL_USART_CLOCK_DISABLE) \ + || ((__VALUE__) == LL_USART_CLOCK_ENABLE)) + +#define IS_LL_USART_STOPBITS(__VALUE__) (((__VALUE__) == LL_USART_STOPBITS_0_5) \ + || ((__VALUE__) == LL_USART_STOPBITS_1) \ + || ((__VALUE__) == LL_USART_STOPBITS_1_5) \ + || ((__VALUE__) == LL_USART_STOPBITS_2)) + +#define IS_LL_USART_HWCONTROL(__VALUE__) (((__VALUE__) == LL_USART_HWCONTROL_NONE) \ + || ((__VALUE__) == LL_USART_HWCONTROL_RTS) \ + || ((__VALUE__) == LL_USART_HWCONTROL_CTS) \ + || ((__VALUE__) == LL_USART_HWCONTROL_RTS_CTS)) + +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup USART_LL_Exported_Functions + * @{ + */ + +/** @addtogroup USART_LL_EF_Init + * @{ + */ + +/** + * @brief De-initialize USART registers (Registers restored to their default values). + * @param USARTx USART Instance + * @retval An ErrorStatus enumeration value: + * - SUCCESS: USART registers are de-initialized + * - ERROR: USART registers are not de-initialized + */ +ErrorStatus LL_USART_DeInit(const USART_TypeDef *USARTx) +{ + ErrorStatus status = SUCCESS; + + /* Check the parameters */ + assert_param(IS_UART_INSTANCE(USARTx)); + + if (USARTx == USART1) + { + /* Force reset of USART clock */ + LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_USART1); + + /* Release reset of USART clock */ + LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_USART1); + } + else if (USARTx == USART2) + { + /* Force reset of USART clock */ + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_USART2); + + /* Release reset of USART clock */ + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_USART2); + } + else if (USARTx == USART3) + { + /* Force reset of USART clock */ + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_USART3); + + /* Release reset of USART clock */ + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_USART3); + } +#if defined(UART4) + else if (USARTx == UART4) + { + /* Force reset of UART clock */ + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_UART4); + + /* Release reset of UART clock */ + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_UART4); + } +#endif /* UART4 */ +#if defined(UART5) + else if (USARTx == UART5) + { + /* Force reset of UART clock */ + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_UART5); + + /* Release reset of UART clock */ + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_UART5); + } +#endif /* UART5 */ +#if defined(USART6) + else if (USARTx == USART6) + { + /* Force reset of USART clock */ + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_USART6); + + /* Release reset of USART clock */ + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_USART6); + } +#endif /* USART6 */ +#if defined(UART7) + else if (USARTx == UART7) + { + /* Force reset of UART clock */ + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_UART7); + + /* Release reset of UART clock */ + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_UART7); + } +#endif /* UART7 */ +#if defined(UART8) + else if (USARTx == UART8) + { + /* Force reset of UART clock */ + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_UART8); + + /* Release reset of UART clock */ + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_UART8); + } +#endif /* UART8 */ +#if defined(UART9) + else if (USARTx == UART9) + { + /* Force reset of UART clock */ + LL_APB1_GRP2_ForceReset(LL_APB1_GRP2_PERIPH_UART9); + + /* Release reset of UART clock */ + LL_APB1_GRP2_ReleaseReset(LL_APB1_GRP2_PERIPH_UART9); + } +#endif /* UART9 */ +#if defined(USART10) + else if (USARTx == USART10) + { + /* Force reset of UART clock */ + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_USART10); + + /* Release reset of UART clock */ + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_USART10); + } +#endif /* USART10 */ +#if defined(USART11) + else if (USARTx == USART11) + { + /* Force reset of UART clock */ + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_USART11); + + /* Release reset of UART clock */ + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_USART11); + } +#endif /* USART11 */ +#if defined(UART12) + else if (USARTx == UART12) + { + /* Force reset of UART clock */ + LL_APB1_GRP2_ForceReset(LL_APB1_GRP2_PERIPH_UART12); + + /* Release reset of UART clock */ + LL_APB1_GRP2_ReleaseReset(LL_APB1_GRP2_PERIPH_UART12); + } +#endif /* UART12 */ + else + { + status = ERROR; + } + + return (status); +} + +/** + * @brief Initialize USART registers according to the specified + * parameters in USART_InitStruct. + * @note As some bits in USART configuration registers can only be written when + * the USART is disabled (USART_CR1_UE bit =0), USART Peripheral should be in disabled state prior calling + * this function. Otherwise, ERROR result will be returned. + * @note Baud rate value stored in USART_InitStruct BaudRate field, should be valid (different from 0). + * @param USARTx USART Instance + * @param USART_InitStruct pointer to a LL_USART_InitTypeDef structure + * that contains the configuration information for the specified USART peripheral. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: USART registers are initialized according to USART_InitStruct content + * - ERROR: Problem occurred during USART Registers initialization + */ +ErrorStatus LL_USART_Init(USART_TypeDef *USARTx, const LL_USART_InitTypeDef *USART_InitStruct) +{ + ErrorStatus status = ERROR; + uint32_t periphclk = LL_RCC_PERIPH_FREQUENCY_NO; + + /* Check the parameters */ + assert_param(IS_UART_INSTANCE(USARTx)); + assert_param(IS_LL_USART_PRESCALER(USART_InitStruct->PrescalerValue)); + assert_param(IS_LL_USART_BAUDRATE(USART_InitStruct->BaudRate)); + assert_param(IS_LL_USART_DATAWIDTH(USART_InitStruct->DataWidth)); + assert_param(IS_LL_USART_STOPBITS(USART_InitStruct->StopBits)); + assert_param(IS_LL_USART_PARITY(USART_InitStruct->Parity)); + assert_param(IS_LL_USART_DIRECTION(USART_InitStruct->TransferDirection)); + assert_param(IS_LL_USART_HWCONTROL(USART_InitStruct->HardwareFlowControl)); + assert_param(IS_LL_USART_OVERSAMPLING(USART_InitStruct->OverSampling)); + + /* USART needs to be in disabled state, in order to be able to configure some bits in + CRx registers */ + if (LL_USART_IsEnabled(USARTx) == 0U) + { + /*---------------------------- USART CR1 Configuration --------------------- + * Configure USARTx CR1 (USART Word Length, Parity, Mode and Oversampling bits) with parameters: + * - DataWidth: USART_CR1_M bits according to USART_InitStruct->DataWidth value + * - Parity: USART_CR1_PCE, USART_CR1_PS bits according to USART_InitStruct->Parity value + * - TransferDirection: USART_CR1_TE, USART_CR1_RE bits according to USART_InitStruct->TransferDirection value + * - Oversampling: USART_CR1_OVER8 bit according to USART_InitStruct->OverSampling value. + */ + MODIFY_REG(USARTx->CR1, + (USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | + USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8), + (USART_InitStruct->DataWidth | USART_InitStruct->Parity | + USART_InitStruct->TransferDirection | USART_InitStruct->OverSampling)); + + /*---------------------------- USART CR2 Configuration --------------------- + * Configure USARTx CR2 (Stop bits) with parameters: + * - Stop Bits: USART_CR2_STOP bits according to USART_InitStruct->StopBits value. + * - CLKEN, CPOL, CPHA and LBCL bits are to be configured using LL_USART_ClockInit(). + */ + LL_USART_SetStopBitsLength(USARTx, USART_InitStruct->StopBits); + + /*---------------------------- USART CR3 Configuration --------------------- + * Configure USARTx CR3 (Hardware Flow Control) with parameters: + * - HardwareFlowControl: USART_CR3_RTSE, USART_CR3_CTSE bits according to + * USART_InitStruct->HardwareFlowControl value. + */ + LL_USART_SetHWFlowCtrl(USARTx, USART_InitStruct->HardwareFlowControl); + + /*---------------------------- USART BRR Configuration --------------------- + * Retrieve Clock frequency used for USART Peripheral + */ + if (USARTx == USART1) + { + periphclk = LL_RCC_GetUSARTClockFreq(LL_RCC_USART1_CLKSOURCE); + } + else if (USARTx == USART2) + { + periphclk = LL_RCC_GetUSARTClockFreq(LL_RCC_USART2_CLKSOURCE); + } + else if (USARTx == USART3) + { + periphclk = LL_RCC_GetUSARTClockFreq(LL_RCC_USART3_CLKSOURCE); + } +#if defined(UART4) + else if (USARTx == UART4) + { + periphclk = LL_RCC_GetUARTClockFreq(LL_RCC_UART4_CLKSOURCE); + } +#endif /* UART4 */ +#if defined(UART5) + else if (USARTx == UART5) + { + periphclk = LL_RCC_GetUARTClockFreq(LL_RCC_UART5_CLKSOURCE); + } +#endif /* UART5 */ +#if defined(USART6) + else if (USARTx == USART6) + { + periphclk = LL_RCC_GetUSARTClockFreq(LL_RCC_USART6_CLKSOURCE); + } +#endif /* USART6 */ +#if defined(UART7) + else if (USARTx == UART7) + { + periphclk = LL_RCC_GetUARTClockFreq(LL_RCC_UART7_CLKSOURCE); + } +#endif /* UART7 */ +#if defined(UART8) + else if (USARTx == UART8) + { + periphclk = LL_RCC_GetUARTClockFreq(LL_RCC_UART8_CLKSOURCE); + } +#endif /* UART8 */ +#if defined(UART9) + else if (USARTx == UART9) + { + periphclk = LL_RCC_GetUSARTClockFreq(LL_RCC_UART9_CLKSOURCE); + } +#endif /* UART9 */ +#if defined(USART10) + else if (USARTx == USART10) + { + periphclk = LL_RCC_GetUSARTClockFreq(LL_RCC_USART10_CLKSOURCE); + } +#endif /* USART10 */ +#if defined(USART11) + else if (USARTx == USART11) + { + periphclk = LL_RCC_GetUSARTClockFreq(LL_RCC_USART11_CLKSOURCE); + } +#endif /* USART11 */ +#if defined(UART12) + else if (USARTx == UART12) + { + periphclk = LL_RCC_GetUARTClockFreq(LL_RCC_UART12_CLKSOURCE); + } +#endif /* UART12 */ + else + { + /* Nothing to do, as error code is already assigned to ERROR value */ + } + + /* Configure the USART Baud Rate : + - prescaler value is required + - valid baud rate value (different from 0) is required + - Peripheral clock as returned by RCC service, should be valid (different from 0). + */ + if ((periphclk != LL_RCC_PERIPH_FREQUENCY_NO) + && (USART_InitStruct->BaudRate != 0U)) + { + status = SUCCESS; + LL_USART_SetBaudRate(USARTx, + periphclk, + USART_InitStruct->PrescalerValue, + USART_InitStruct->OverSampling, + USART_InitStruct->BaudRate); + + /* Check BRR is greater than or equal to 16d */ + assert_param(IS_LL_USART_BRR_MIN(USARTx->BRR)); + } + + /*---------------------------- USART PRESC Configuration ----------------------- + * Configure USARTx PRESC (Prescaler) with parameters: + * - PrescalerValue: USART_PRESC_PRESCALER bits according to USART_InitStruct->PrescalerValue value. + */ + LL_USART_SetPrescaler(USARTx, USART_InitStruct->PrescalerValue); + } + /* Endif (=> USART not in Disabled state => return ERROR) */ + + return (status); +} + +/** + * @brief Set each @ref LL_USART_InitTypeDef field to default value. + * @param USART_InitStruct pointer to a @ref LL_USART_InitTypeDef structure + * whose fields will be set to default values. + * @retval None + */ + +void LL_USART_StructInit(LL_USART_InitTypeDef *USART_InitStruct) +{ + /* Set USART_InitStruct fields to default values */ + USART_InitStruct->PrescalerValue = LL_USART_PRESCALER_DIV1; + USART_InitStruct->BaudRate = USART_DEFAULT_BAUDRATE; + USART_InitStruct->DataWidth = LL_USART_DATAWIDTH_8B; + USART_InitStruct->StopBits = LL_USART_STOPBITS_1; + USART_InitStruct->Parity = LL_USART_PARITY_NONE ; + USART_InitStruct->TransferDirection = LL_USART_DIRECTION_TX_RX; + USART_InitStruct->HardwareFlowControl = LL_USART_HWCONTROL_NONE; + USART_InitStruct->OverSampling = LL_USART_OVERSAMPLING_16; +} + +/** + * @brief Initialize USART Clock related settings according to the + * specified parameters in the USART_ClockInitStruct. + * @note As some bits in USART configuration registers can only be written when + * the USART is disabled (USART_CR1_UE bit =0), USART Peripheral should be in disabled state prior calling + * this function. Otherwise, ERROR result will be returned. + * @param USARTx USART Instance + * @param USART_ClockInitStruct pointer to a @ref LL_USART_ClockInitTypeDef structure + * that contains the Clock configuration information for the specified USART peripheral. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: USART registers related to Clock settings are initialized according + * to USART_ClockInitStruct content + * - ERROR: Problem occurred during USART Registers initialization + */ +ErrorStatus LL_USART_ClockInit(USART_TypeDef *USARTx, const LL_USART_ClockInitTypeDef *USART_ClockInitStruct) +{ + ErrorStatus status = SUCCESS; + + /* Check USART Instance and Clock signal output parameters */ + assert_param(IS_UART_INSTANCE(USARTx)); + assert_param(IS_LL_USART_CLOCKOUTPUT(USART_ClockInitStruct->ClockOutput)); + + /* USART needs to be in disabled state, in order to be able to configure some bits in + CRx registers */ + if (LL_USART_IsEnabled(USARTx) == 0U) + { + /* Ensure USART instance is USART capable */ + assert_param(IS_USART_INSTANCE(USARTx)); + + /* Check clock related parameters */ + assert_param(IS_LL_USART_CLOCKPOLARITY(USART_ClockInitStruct->ClockPolarity)); + assert_param(IS_LL_USART_CLOCKPHASE(USART_ClockInitStruct->ClockPhase)); + assert_param(IS_LL_USART_LASTBITCLKOUTPUT(USART_ClockInitStruct->LastBitClockPulse)); + + /*---------------------------- USART CR2 Configuration ----------------------- + * Configure USARTx CR2 (Clock signal related bits) with parameters: + * - Clock Output: USART_CR2_CLKEN bit according to USART_ClockInitStruct->ClockOutput value + * - Clock Polarity: USART_CR2_CPOL bit according to USART_ClockInitStruct->ClockPolarity value + * - Clock Phase: USART_CR2_CPHA bit according to USART_ClockInitStruct->ClockPhase value + * - Last Bit Clock Pulse Output: USART_CR2_LBCL bit according to USART_ClockInitStruct->LastBitClockPulse value. + */ + MODIFY_REG(USARTx->CR2, + USART_CR2_CLKEN | USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_LBCL, + USART_ClockInitStruct->ClockOutput | USART_ClockInitStruct->ClockPolarity | + USART_ClockInitStruct->ClockPhase | USART_ClockInitStruct->LastBitClockPulse); + } + /* Else (USART not in Disabled state => return ERROR */ + else + { + status = ERROR; + } + + return (status); +} + +/** + * @brief Set each field of a @ref LL_USART_ClockInitTypeDef type structure to default value. + * @param USART_ClockInitStruct pointer to a @ref LL_USART_ClockInitTypeDef structure + * whose fields will be set to default values. + * @retval None + */ +void LL_USART_ClockStructInit(LL_USART_ClockInitTypeDef *USART_ClockInitStruct) +{ + /* Set LL_USART_ClockInitStruct fields with default values */ + USART_ClockInitStruct->ClockOutput = LL_USART_CLOCK_DISABLE; + USART_ClockInitStruct->ClockPolarity = LL_USART_POLARITY_LOW; /* Not relevant when ClockOutput = + LL_USART_CLOCK_DISABLE */ + USART_ClockInitStruct->ClockPhase = LL_USART_PHASE_1EDGE; /* Not relevant when ClockOutput = + LL_USART_CLOCK_DISABLE */ + USART_ClockInitStruct->LastBitClockPulse = LL_USART_LASTCLKPULSE_NO_OUTPUT; /* Not relevant when ClockOutput = + LL_USART_CLOCK_DISABLE */ +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* USART1 || USART2 || USART3 || UART4 || UART5 || USART6 + || UART7 || UART8 || UART9 || USART10 || USART11 || UART12 */ + +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ + + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_usb.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_usb.c new file mode 100644 index 0000000000..d17ce7e360 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_usb.c @@ -0,0 +1,1410 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_usb.c + * @author MCD Application Team + * @brief USB Low Layer HAL module driver. + * + * This file provides firmware functions to manage the following + * functionalities of the USB Peripheral Controller: + * + Initialization/de-initialization functions + * + I/O operation functions + * + Peripheral Control functions + * + Peripheral State functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Fill parameters of Init structure in USB_CfgTypeDef structure. + + (#) Call USB_CoreInit() API to initialize the USB Core peripheral. + + (#) The upper HAL HCD/PCD driver will call the right routines for its internal processes. + + @endverbatim + + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" + +/** @addtogroup STM32H5xx_LL_USB_DRIVER + * @{ + */ + +#if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) +#if defined (USB_DRD_FS) +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +static HAL_StatusTypeDef USB_CoreReset(USB_DRD_TypeDef *USBx); +#if (USE_USB_DOUBLE_BUFFER == 1U) +static HAL_StatusTypeDef USB_HC_BULK_DB_StartXfer(USB_DRD_TypeDef *USBx, + USB_DRD_HCTypeDef *hc, + uint32_t ch_reg, + uint32_t *len); + +static HAL_StatusTypeDef USB_HC_ISO_DB_StartXfer(USB_DRD_TypeDef *USBx, + USB_DRD_HCTypeDef *hc, + uint32_t len); +#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ + +/** + * @brief Reset the USB Core (needed after USB clock settings change) + * @param USBx Selected device + * @retval HAL status + */ +static HAL_StatusTypeDef USB_CoreReset(USB_DRD_TypeDef *USBx) +{ + /* Disable Host Mode */ + USBx->CNTR &= ~USB_CNTR_HOST; + + /* Force Reset IP */ + USBx->CNTR |= USB_CNTR_USBRST; + + return HAL_OK; +} + +/** + * @brief Initializes the USB Core + * @param USBx USB Instance + * @param cfg pointer to a USB_CfgTypeDef structure that contains + * the configuration information for the specified USBx peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef USB_CoreInit(USB_DRD_TypeDef *USBx, USB_DRD_CfgTypeDef cfg) +{ + HAL_StatusTypeDef ret; + UNUSED(cfg); + + if (USBx == NULL) + { + return HAL_ERROR; + } + + /* Reset after a PHY select */ + ret = USB_CoreReset(USBx); + + /* Clear pending interrupts */ + USBx->ISTR = 0U; + + return ret; +} + +/** + * @brief USB_EnableGlobalInt + * Enables the controller's Global Int in the AHB Config reg + * @param USBx Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_EnableGlobalInt(USB_DRD_TypeDef *USBx) +{ + uint32_t winterruptmask; + + /* Clear pending interrupts */ + USBx->ISTR = 0U; + + /* Set winterruptmask variable */ + winterruptmask = USB_CNTR_CTRM | USB_CNTR_WKUPM | + USB_CNTR_SUSPM | USB_CNTR_ERRM | + USB_CNTR_SOFM | USB_CNTR_ESOFM | + USB_CNTR_RESETM | USB_CNTR_L1REQM; + + /* Set interrupt mask */ + USBx->CNTR = winterruptmask; + + return HAL_OK; +} + +/** + * @brief USB_DisableGlobalInt + * Disable the controller's Global Int in the AHB Config reg + * @param USBx Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_DisableGlobalInt(USB_DRD_TypeDef *USBx) +{ + uint32_t winterruptmask; + + /* Set winterruptmask variable */ + winterruptmask = USB_CNTR_CTRM | USB_CNTR_WKUPM | + USB_CNTR_SUSPM | USB_CNTR_ERRM | + USB_CNTR_SOFM | USB_CNTR_ESOFM | + USB_CNTR_RESETM | USB_CNTR_L1REQM; + + /* Clear interrupt mask */ + USBx->CNTR &= ~winterruptmask; + + return HAL_OK; +} + +/** + * @brief USB_SetCurrentMode Set functional mode + * @param USBx Selected device + * @param mode current core mode + * This parameter can be one of the these values: + * @arg USB_DEVICE_MODE Peripheral mode + * @retval HAL status + */ +HAL_StatusTypeDef USB_SetCurrentMode(USB_DRD_TypeDef *USBx, USB_DRD_ModeTypeDef mode) +{ + if (mode == USB_DEVICE_MODE) + { + USBx->CNTR &= ~USB_CNTR_HOST; + } + else if (mode == USB_HOST_MODE) + { + USBx->CNTR |= USB_CNTR_HOST; + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief USB_DevInit Initializes the USB controller registers + * for device mode + * @param USBx Selected device + * @param cfg pointer to a USB_DRD_CfgTypeDef structure that contains + * the configuration information for the specified USBx peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef USB_DevInit(USB_DRD_TypeDef *USBx, USB_DRD_CfgTypeDef cfg) +{ + HAL_StatusTypeDef ret; + + /* Prevent unused argument(s) compilation warning */ + UNUSED(cfg); + + /* Force Reset */ + USBx->CNTR = USB_CNTR_USBRST; + + /* Release Reset */ + USBx->CNTR &= ~USB_CNTR_USBRST; + + /* Set the Device Mode */ + ret = USB_SetCurrentMode(USBx, USB_DEVICE_MODE); + + /* Clear pending interrupts */ + USBx->ISTR = 0U; + + return ret; +} + +#if defined (HAL_PCD_MODULE_ENABLED) +/** + * @brief Activate and configure an endpoint + * @param USBx Selected device + * @param ep pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_ActivateEndpoint(USB_DRD_TypeDef *USBx, USB_DRD_EPTypeDef *ep) +{ + HAL_StatusTypeDef ret = HAL_OK; + uint32_t wEpRegVal; + + wEpRegVal = PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_T_MASK; + + /* initialize Endpoint */ + switch (ep->type) + { + case EP_TYPE_CTRL: + wEpRegVal |= USB_EP_CONTROL; + break; + + case EP_TYPE_BULK: + wEpRegVal |= USB_EP_BULK; + break; + + case EP_TYPE_INTR: + wEpRegVal |= USB_EP_INTERRUPT; + break; + + case EP_TYPE_ISOC: + wEpRegVal |= USB_EP_ISOCHRONOUS; + break; + + default: + ret = HAL_ERROR; + break; + } + + PCD_SET_ENDPOINT(USBx, ep->num, (wEpRegVal | USB_EP_VTRX | USB_EP_VTTX)); + + PCD_SET_EP_ADDRESS(USBx, ep->num, ep->num); + + if (ep->doublebuffer == 0U) + { + if (ep->is_in != 0U) + { + /*Set the endpoint Transmit buffer address */ + PCD_SET_EP_TX_ADDRESS(USBx, ep->num, ep->pmaadress); + PCD_CLEAR_TX_DTOG(USBx, ep->num); + + if (ep->type != EP_TYPE_ISOC) + { + /* Configure NAK status for the Endpoint */ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK); + } + else + { + /* Configure TX Endpoint to disabled state */ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); + } + } + else + { + /* Set the endpoint Receive buffer address */ + PCD_SET_EP_RX_ADDRESS(USBx, ep->num, ep->pmaadress); + + /* Set the endpoint Receive buffer counter */ + PCD_SET_EP_RX_CNT(USBx, ep->num, ep->maxpacket); + PCD_CLEAR_RX_DTOG(USBx, ep->num); + + if (ep->num == 0U) + { + /* Configure VALID status for EP0 */ + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID); + } + else + { + /* Configure NAK status for OUT Endpoint */ + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_NAK); + } + } + } +#if (USE_USB_DOUBLE_BUFFER == 1U) + /* Double Buffer */ + else + { + if (ep->type == EP_TYPE_BULK) + { + /* Set bulk endpoint as double buffered */ + PCD_SET_BULK_EP_DBUF(USBx, ep->num); + } + else + { + /* Set the ISOC endpoint in double buffer mode */ + PCD_CLEAR_EP_KIND(USBx, ep->num); + } + + /* Set buffer address for double buffered mode */ + PCD_SET_EP_DBUF_ADDR(USBx, ep->num, ep->pmaaddr0, ep->pmaaddr1); + + if (ep->is_in == 0U) + { + /* Clear the data toggle bits for the endpoint IN/OUT */ + PCD_CLEAR_RX_DTOG(USBx, ep->num); + PCD_CLEAR_TX_DTOG(USBx, ep->num); + + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID); + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); + } + else + { + /* Clear the data toggle bits for the endpoint IN/OUT */ + PCD_CLEAR_RX_DTOG(USBx, ep->num); + PCD_CLEAR_TX_DTOG(USBx, ep->num); + + if (ep->type != EP_TYPE_ISOC) + { + /* Configure NAK status for the Endpoint */ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK); + } + else + { + /* Configure TX Endpoint to disabled state */ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); + } + + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS); + } + } +#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ + + return ret; +} + +/** + * @brief De-activate and de-initialize an endpoint + * @param USBx Selected device + * @param ep pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_DeactivateEndpoint(USB_DRD_TypeDef *USBx, USB_DRD_EPTypeDef *ep) +{ + if (ep->doublebuffer == 0U) + { + if (ep->is_in != 0U) + { + PCD_CLEAR_TX_DTOG(USBx, ep->num); + + /* Configure DISABLE status for the Endpoint */ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); + } + + else + { + PCD_CLEAR_RX_DTOG(USBx, ep->num); + + /* Configure DISABLE status for the Endpoint */ + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS); + } + } +#if (USE_USB_DOUBLE_BUFFER == 1U) + /* Double Buffer */ + else + { + if (ep->is_in == 0U) + { + /* Clear the data toggle bits for the endpoint IN/OUT*/ + PCD_CLEAR_RX_DTOG(USBx, ep->num); + PCD_CLEAR_TX_DTOG(USBx, ep->num); + + /* Reset value of the data toggle bits for the endpoint out*/ + PCD_TX_DTOG(USBx, ep->num); + + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS); + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); + } + else + { + /* Clear the data toggle bits for the endpoint IN/OUT*/ + PCD_CLEAR_RX_DTOG(USBx, ep->num); + PCD_CLEAR_TX_DTOG(USBx, ep->num); + PCD_RX_DTOG(USBx, ep->num); + + /* Configure DISABLE status for the Endpoint*/ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS); + } + } +#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ + + return HAL_OK; +} + +/** + * @brief USB_EPStartXfer setup and starts a transfer over an EP + * @param USBx Selected device + * @param ep pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_EPStartXfer(USB_DRD_TypeDef *USBx, USB_DRD_EPTypeDef *ep) +{ + uint32_t len; +#if (USE_USB_DOUBLE_BUFFER == 1U) + uint16_t pmabuffer; + uint16_t wEPVal; +#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ + + /* IN endpoint */ + if (ep->is_in == 1U) + { + /*Multi packet transfer*/ + if (ep->xfer_len > ep->maxpacket) + { + len = ep->maxpacket; + } + else + { + len = ep->xfer_len; + } + + /* configure and validate Tx endpoint */ + if (ep->doublebuffer == 0U) + { + USB_WritePMA(USBx, ep->xfer_buff, ep->pmaadress, (uint16_t)len); + PCD_SET_EP_TX_CNT(USBx, ep->num, len); + } +#if (USE_USB_DOUBLE_BUFFER == 1U) + else + { + /* double buffer bulk management */ + if (ep->type == EP_TYPE_BULK) + { + if (ep->xfer_len_db > ep->maxpacket) + { + /* enable double buffer */ + PCD_SET_BULK_EP_DBUF(USBx, ep->num); + + /* each Time to write in PMA xfer_len_db will */ + ep->xfer_len_db -= len; + + /* Fill the two first buffer in the Buffer0 & Buffer1 */ + if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U) + { + /* Set the Double buffer counter for pmabuffer1 */ + PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len); + pmabuffer = ep->pmaaddr1; + + /* Write the user buffer to USB PMA */ + USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len); + ep->xfer_buff += len; + + if (ep->xfer_len_db > ep->maxpacket) + { + ep->xfer_len_db -= len; + } + else + { + len = ep->xfer_len_db; + ep->xfer_len_db = 0U; + } + + /* Set the Double buffer counter for pmabuffer0 */ + PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len); + pmabuffer = ep->pmaaddr0; + + /* Write the user buffer to USB PMA */ + USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len); + } + else + { + /* Set the Double buffer counter for pmabuffer0 */ + PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len); + pmabuffer = ep->pmaaddr0; + + /* Write the user buffer to USB PMA */ + USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len); + ep->xfer_buff += len; + + if (ep->xfer_len_db > ep->maxpacket) + { + ep->xfer_len_db -= len; + } + else + { + len = ep->xfer_len_db; + ep->xfer_len_db = 0U; + } + + /* Set the Double buffer counter for pmabuffer1 */ + PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len); + pmabuffer = ep->pmaaddr1; + + /* Write the user buffer to USB PMA */ + USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len); + } + } + /* auto Switch to single buffer mode when transfer xfer_len_db; + + /* disable double buffer mode for Bulk endpoint */ + PCD_CLEAR_BULK_EP_DBUF(USBx, ep->num); + + /* Set Tx count with nbre of byte to be transmitted */ + PCD_SET_EP_TX_CNT(USBx, ep->num, len); + pmabuffer = ep->pmaaddr0; + + /* Write the user buffer to USB PMA */ + USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len); + } + } + else /* manage isochronous double buffer IN mode */ + { + /* each Time to write in PMA xfer_len_db will */ + ep->xfer_len_db -= len; + + /* Fill the data buffer */ + if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U) + { + /* Set the Double buffer counter for pmabuffer1 */ + PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len); + pmabuffer = ep->pmaaddr1; + + /* Write the user buffer to USB PMA */ + USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len); + } + else + { + /* Set the Double buffer counter for pmabuffer0 */ + PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len); + pmabuffer = ep->pmaaddr0; + + /* Write the user buffer to USB PMA */ + USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len); + } + } + } +#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ + + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID); + } + else /* OUT endpoint */ + { + if (ep->doublebuffer == 0U) + { + /* Multi packet transfer */ + if (ep->xfer_len > ep->maxpacket) + { + len = ep->maxpacket; + ep->xfer_len -= len; + } + else + { + len = ep->xfer_len; + ep->xfer_len = 0U; + } + /* configure and validate Rx endpoint */ + PCD_SET_EP_RX_CNT(USBx, ep->num, len); + } +#if (USE_USB_DOUBLE_BUFFER == 1U) + else + { + /* First Transfer Coming From HAL_PCD_EP_Receive & From ISR */ + /* Set the Double buffer counter */ + if (ep->type == EP_TYPE_BULK) + { + PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, ep->maxpacket); + + /* Coming from ISR */ + if (ep->xfer_count != 0U) + { + /* update last value to check if there is blocking state */ + wEPVal = (uint16_t)PCD_GET_ENDPOINT(USBx, ep->num); + + /*Blocking State */ + if ((((wEPVal & USB_EP_DTOG_RX) != 0U) && ((wEPVal & USB_EP_DTOG_TX) != 0U)) || + (((wEPVal & USB_EP_DTOG_RX) == 0U) && ((wEPVal & USB_EP_DTOG_TX) == 0U))) + { + PCD_FREE_USER_BUFFER(USBx, ep->num, 0U); + } + } + } + /* iso out double */ + else if (ep->type == EP_TYPE_ISOC) + { + /* Multi packet transfer */ + if (ep->xfer_len > ep->maxpacket) + { + len = ep->maxpacket; + ep->xfer_len -= len; + } + else + { + len = ep->xfer_len; + ep->xfer_len = 0U; + } + PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, len); + } + else + { + return HAL_ERROR; + } + } +#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ + + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID); + } + + return HAL_OK; +} + + +/** + * @brief USB_EPSetStall set a stall condition over an EP + * @param USBx Selected device + * @param ep pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_EPSetStall(USB_DRD_TypeDef *USBx, USB_DRD_EPTypeDef *ep) +{ + if (ep->is_in != 0U) + { + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_STALL); + } + else + { + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_STALL); + } + + return HAL_OK; +} + +/** + * @brief USB_EPClearStall Clear a stall condition over an EP + * @param USBx Selected device + * @param ep pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_EPClearStall(USB_DRD_TypeDef *USBx, USB_DRD_EPTypeDef *ep) +{ + if (ep->doublebuffer == 0U) + { + if (ep->is_in != 0U) + { + PCD_CLEAR_TX_DTOG(USBx, ep->num); + + if (ep->type != EP_TYPE_ISOC) + { + /* Configure NAK status for the Endpoint */ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK); + } + } + else + { + PCD_CLEAR_RX_DTOG(USBx, ep->num); + + /* Configure VALID status for the Endpoint */ + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID); + } + } + + return HAL_OK; +} + +/** + * @brief USB_EPStoptXfer Stop transfer on an EP + * @param USBx usb device instance + * @param ep pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_EPStopXfer(USB_DRD_TypeDef *USBx, USB_DRD_EPTypeDef *ep) +{ + /* IN endpoint */ + if (ep->is_in == 1U) + { + if (ep->doublebuffer == 0U) + { + if (ep->type != EP_TYPE_ISOC) + { + /* Configure NAK status for the Endpoint */ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK); + } + else + { + /* Configure TX Endpoint to disabled state */ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); + } + } + } + else /* OUT endpoint */ + { + if (ep->doublebuffer == 0U) + { + if (ep->type != EP_TYPE_ISOC) + { + /* Configure NAK status for the Endpoint */ + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_NAK); + } + else + { + /* Configure RX Endpoint to disabled state */ + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS); + } + } + } + + return HAL_OK; +} +#endif /* defined (HAL_PCD_MODULE_ENABLED) */ + +/** + * @brief USB_StopDevice Stop the usb device mode + * @param USBx Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_StopDevice(USB_DRD_TypeDef *USBx) +{ + /* disable all interrupts and force USB reset */ + USBx->CNTR = USB_CNTR_USBRST; + + /* clear interrupt status register */ + USBx->ISTR = 0U; + + /* switch-off device */ + USBx->CNTR = (USB_CNTR_USBRST | USB_CNTR_PDWN); + + return HAL_OK; +} + +/** + * @brief USB_SetDevAddress Stop the usb device mode + * @param USBx Selected device + * @param address new device address to be assigned + * This parameter can be a value from 0 to 255 + * @retval HAL status + */ +HAL_StatusTypeDef USB_SetDevAddress(USB_DRD_TypeDef *USBx, uint8_t address) +{ + if (address == 0U) + { + /* set device address and enable function */ + USBx->DADDR = USB_DADDR_EF; + } + + return HAL_OK; +} + +/** + * @brief USB_DevConnect Connect the USB device by enabling the pull-up/pull-down + * @param USBx Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_DevConnect(USB_DRD_TypeDef *USBx) +{ + /* Enabling DP Pull-UP bit to Connect internal PU resistor on USB DP line */ + USBx->BCDR |= USB_BCDR_DPPU; + + return HAL_OK; +} + +/** + * @brief USB_DevDisconnect Disconnect the USB device by disabling the pull-up/pull-down + * @param USBx Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_DevDisconnect(USB_DRD_TypeDef *USBx) +{ + /* Disable DP Pull-Up bit to disconnect the Internal PU resistor on USB DP line */ + USBx->BCDR &= ~(USB_BCDR_DPPU); + + return HAL_OK; +} + +/** + * @brief USB_ReadInterrupts return the global USB interrupt status + * @param USBx Selected device + * @retval USB Global Interrupt status + */ +uint32_t USB_ReadInterrupts(USB_DRD_TypeDef const *USBx) +{ + uint32_t tmpreg; + + tmpreg = USBx->ISTR; + return tmpreg; +} + +/** + * @brief USB_ActivateRemoteWakeup : active remote wakeup signalling + * @param USBx Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_DRD_TypeDef *USBx) +{ + USBx->CNTR |= USB_CNTR_L2RES; + + return HAL_OK; +} + +/** + * @brief USB_DeActivateRemoteWakeup de-active remote wakeup signalling + * @param USBx Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_DRD_TypeDef *USBx) +{ + USBx->CNTR &= ~USB_CNTR_L2RES; + + return HAL_OK; +} + +/** + * @brief Copy a buffer from user memory area to packet memory area (PMA) + * @param USBx USB peripheral instance register address. + * @param pbUsrBuf pointer to user memory area. + * @param wPMABufAddr address into PMA. + * @param wNBytes no. of bytes to be copied. + * @retval None + */ +void USB_WritePMA(USB_DRD_TypeDef const *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes) +{ + UNUSED(USBx); + uint32_t WrVal; + uint32_t count; + __IO uint32_t *pdwVal; + uint32_t NbWords = ((uint32_t)wNBytes + 3U) >> 2U; + /* Due to the PMA access 32bit only so the last non word data should be processed alone */ + uint16_t remaining_bytes = wNBytes % 4U; + uint8_t *pBuf = pbUsrBuf; + + /* Check if there is a remaining byte */ + if (remaining_bytes != 0U) + { + NbWords--; + } + + /* Get the PMA Buffer pointer */ + pdwVal = (__IO uint32_t *)(USB_DRD_PMAADDR + (uint32_t)wPMABufAddr); + + /* Write the Calculated Word into the PMA related Buffer */ + for (count = NbWords; count != 0U; count--) + { + *pdwVal = __UNALIGNED_UINT32_READ(pBuf); + pdwVal++; + /* Increment pBuf 4 Time as Word Increment */ + pBuf++; + pBuf++; + pBuf++; + pBuf++; + } + + /* When Number of data is not word aligned, write the remaining Byte */ + if (remaining_bytes != 0U) + { + WrVal = 0U; + + do + { + WrVal |= (uint32_t)(*(uint8_t *)pBuf) << (8U * count); + count++; + pBuf++; + remaining_bytes--; + } while (remaining_bytes != 0U); + + *pdwVal = WrVal; + } +} + +/** + * @brief Copy data from packet memory area (PMA) to user memory buffer + * @param USBx USB peripheral instance register address. + * @param pbUsrBuf pointer to user memory area. + * @param wPMABufAddr address into PMA. + * @param wNBytes no. of bytes to be copied. + * @retval None + */ +void USB_ReadPMA(USB_DRD_TypeDef const *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes) +{ + UNUSED(USBx); + uint32_t count; + uint32_t RdVal; + __IO uint32_t *pdwVal; + uint32_t NbWords = ((uint32_t)wNBytes + 3U) >> 2U; + /*Due to the PMA access 32bit only so the last non word data should be processed alone */ + uint16_t remaining_bytes = wNBytes % 4U; + uint8_t *pBuf = pbUsrBuf; + + /* Get the PMA Buffer pointer */ + pdwVal = (__IO uint32_t *)(USB_DRD_PMAADDR + (uint32_t)wPMABufAddr); + + /* if nbre of byte is not word aligned decrement the nbre of word*/ + if (remaining_bytes != 0U) + { + NbWords--; + } + + /*Read the Calculated Word From the PMA related Buffer*/ + for (count = NbWords; count != 0U; count--) + { + __UNALIGNED_UINT32_WRITE(pBuf, *pdwVal); + + pdwVal++; + pBuf++; + pBuf++; + pBuf++; + pBuf++; + } + + /*When Number of data is not word aligned, read the remaining byte*/ + if (remaining_bytes != 0U) + { + RdVal = *(__IO uint32_t *)pdwVal; + + do + { + *(uint8_t *)pBuf = (uint8_t)(RdVal >> (8U * (uint8_t)(count))); + count++; + pBuf++; + remaining_bytes--; + } while (remaining_bytes != 0U); + } +} + + +/*------------------------------------------------------------------------*/ +/* HOST API */ +/*------------------------------------------------------------------------*/ + +/** + * @brief USB_HostInit Initializes the USB DRD controller registers + * for Host mode + * @param USBx Selected device + * @param cfg pointer to a USB_DRD_CfgTypeDef structure that contains + * the configuration information for the specified USBx peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef USB_HostInit(USB_DRD_TypeDef *USBx, USB_DRD_CfgTypeDef cfg) +{ + UNUSED(cfg); + + /* Clear All Pending Interrupt */ + USBx->ISTR = 0U; + + /* Disable all interrupts */ + USBx->CNTR &= ~(USB_CNTR_CTRM | USB_CNTR_PMAOVRM | USB_CNTR_ERRM | + USB_CNTR_WKUPM | USB_CNTR_SUSPM | USB_CNTR_DCON | + USB_CNTR_SOFM | USB_CNTR_ESOFM | USB_CNTR_L1REQM); + + /* Clear All Pending Interrupt */ + USBx->ISTR = 0U; + + /* Enable Global interrupt */ + USBx->CNTR |= (USB_CNTR_CTRM | USB_CNTR_PMAOVRM | USB_CNTR_ERRM | + USB_CNTR_WKUPM | USB_CNTR_SUSPM | USB_CNTR_DCON | + USB_CNTR_SOFM | USB_CNTR_ESOFM | USB_CNTR_L1REQM); + + /* Remove Reset */ + USBx->CNTR &= ~USB_CNTR_USBRST; + + return HAL_OK; +} + + +/** + * @brief USB_DRD_ResetPort : Reset Host Port + * @param USBx Selected device + * @retval HAL status + * @note (1)The application must wait at least 10 ms + * before clearing the reset bit. + */ +HAL_StatusTypeDef USB_ResetPort(USB_DRD_TypeDef *USBx) +{ + /* Force USB Reset */ + USBx->CNTR |= USB_CNTR_USBRST; + HAL_Delay(100); + /* Release USB Reset */ + USBx->CNTR &= ~USB_CNTR_USBRST; + HAL_Delay(30); + + return HAL_OK; +} + +/** + * @brief Return Host Core speed + * @param USBx Selected device + * @retval speed Host speed + * This parameter can be one of these values + * @arg USB_DRD_SPEED_FS Full speed mode + * @arg USB_DRD_SPEED_LS Low speed mode + */ +uint32_t USB_GetHostSpeed(USB_DRD_TypeDef const *USBx) +{ + if ((USBx->ISTR & USB_ISTR_LS_DCONN) != 0U) + { + return USB_DRD_SPEED_LS; + } + else + { + return USB_DRD_SPEED_FS; + } +} + +/** + * @brief Return Host Current Frame number + * @param USBx Selected device + * @retval current frame number + */ +uint32_t USB_GetCurrentFrame(USB_DRD_TypeDef const *USBx) +{ + return USBx->FNR & 0x7FFU; +} + +/** + * @brief Set the channel Kind (Single/double buffer mode) + * @param USBx Selected device + * @param phy_ch_num Selected device + * @param db_state double state can be USB_DRD_XXX_DBUFF_ENBALE/USB_DRD_XXX_DBUFF_DISABLE + * @retval HAL status + */ +HAL_StatusTypeDef USB_HC_DoubleBuffer(USB_DRD_TypeDef *USBx, + uint8_t phy_ch_num, uint8_t db_state) +{ + uint32_t tmp; + + if ((db_state == USB_DRD_BULK_DBUFF_ENBALE) || (db_state == USB_DRD_ISOC_DBUFF_DISABLE)) + { + tmp = (USB_DRD_GET_CHEP(USBx, phy_ch_num) | USB_CH_KIND) & USB_CHEP_DB_MSK; + } + else + { + tmp = USB_DRD_GET_CHEP(USBx, phy_ch_num) & (~USB_CH_KIND) & USB_CHEP_DB_MSK; + } + + /* Set the device speed in case using HUB FS with device LS */ + USB_DRD_SET_CHEP(USBx, phy_ch_num, tmp); + + return HAL_OK; +} + +/** + * @brief Initialize a host channel + * @param USBx Selected device + * @param phy_ch_num Channel number + * This parameter can be a value from 1 to 15 + * @param epnum Endpoint number + * This parameter can be a value from 1 to 15 + * @param dev_address Current device address + * This parameter can be a value from 0 to 255 + * @param speed Current device speed + * This parameter can be one of these values: + * @arg USB_DRD_SPEED_FULL Full speed mode + * @arg USB_DRD_SPEED_LOW Low speed mode + * @param ep_type Endpoint Type + * This parameter can be one of these values: + * @arg EP_TYPE_CTRL Control type + * @arg EP_TYPE_ISOC Isochronous type + * @arg EP_TYPE_BULK Bulk type + * @arg EP_TYPE_INTR Interrupt type + * @param mps Max Packet Size + * This parameter can be a value from 0 to 32K + * @retval HAL state + */ +HAL_StatusTypeDef USB_HC_Init(USB_DRD_TypeDef *USBx, uint8_t phy_ch_num, + uint8_t epnum, uint8_t dev_address, uint8_t speed, + uint8_t ep_type, uint16_t mps) +{ + HAL_StatusTypeDef ret = HAL_OK; + uint32_t wChRegVal; + uint32_t HostCoreSpeed; + + UNUSED(mps); + + wChRegVal = USB_DRD_GET_CHEP(USBx, phy_ch_num) & USB_CH_T_MASK; + + /* initialize host Channel */ + switch (ep_type) + { + case EP_TYPE_CTRL: + wChRegVal |= USB_EP_CONTROL; + break; + + case EP_TYPE_BULK: + wChRegVal |= USB_EP_BULK; + break; + + case EP_TYPE_INTR: + wChRegVal |= USB_EP_INTERRUPT; + break; + + case EP_TYPE_ISOC: + wChRegVal |= USB_EP_ISOCHRONOUS; + break; + + default: + ret = HAL_ERROR; + break; + } + + wChRegVal &= ~USB_CHEP_DEVADDR; + wChRegVal |= (((uint32_t)dev_address << USB_CHEP_DEVADDR_Pos) | + ((uint32_t)epnum & 0x0FU)); + + /* Get Host core Speed */ + HostCoreSpeed = USB_GetHostSpeed(USBx); + + /* Set the device speed in case using HUB FS with device LS */ + if ((speed == USB_DRD_SPEED_LS) && (HostCoreSpeed == USB_DRD_SPEED_FS)) + { + wChRegVal |= USB_CHEP_LSEP; + } + + /* Set the dev_address & ep type */ + USB_DRD_SET_CHEP(USBx, phy_ch_num, (wChRegVal | USB_CH_VTRX | USB_CH_VTTX)); + + return ret; +} + +/** + * @brief Start a transfer over a host channel + * @param USBx Selected device + * @param hc pointer to host channel structure + * @retval HAL state + */ +HAL_StatusTypeDef USB_HC_StartXfer(USB_DRD_TypeDef *USBx, USB_DRD_HCTypeDef *hc) +{ + uint32_t len; + uint32_t phy_ch_num = (uint32_t)hc->phy_ch_num; +#if (USE_USB_DOUBLE_BUFFER == 1U) + uint32_t ch_reg = USB_DRD_GET_CHEP(USBx, phy_ch_num); +#endif /* USE_USB_DOUBLE_BUFFER */ + + if (hc->ch_dir == CH_IN_DIR) /* In Channel */ + { + /* Multi packet transfer */ + if (hc->xfer_len > hc->max_packet) + { + len = hc->max_packet; + } + else + { + len = hc->xfer_len; + } + + if (hc->doublebuffer == 0U) + { + /* Set RX buffer count */ + USB_DRD_SET_CHEP_RX_CNT(USBx, phy_ch_num, len); + } +#if (USE_USB_DOUBLE_BUFFER == 1U) + else if (hc->ep_type == EP_TYPE_BULK) + { + /* Double buffer activated */ + if ((hc->xfer_len > hc->max_packet)) + { + (void)USB_HC_DoubleBuffer(USBx, (uint8_t)phy_ch_num, USB_DRD_BULK_DBUFF_ENBALE); + + /*Set the Double buffer counter*/ + USB_DRD_SET_CHEP_DBUF0_CNT(USBx, phy_ch_num, 0U, len); + USB_DRD_SET_CHEP_DBUF1_CNT(USBx, phy_ch_num, 0U, len); + } + else /* switch to single buffer mode */ + { + (void)USB_HC_DoubleBuffer(USBx, (uint8_t)phy_ch_num, USB_DRD_BULK_DBUFF_DISABLE); + + /* Set RX buffer count */ + USB_DRD_SET_CHEP_RX_CNT(USBx, phy_ch_num, len); + } + } + else /* isochronous */ + { + /* Set the Double buffer counter */ + USB_DRD_SET_CHEP_DBUF0_CNT(USBx, phy_ch_num, 0U, len); + USB_DRD_SET_CHEP_DBUF1_CNT(USBx, phy_ch_num, 0U, len); + } +#endif /* USE_USB_DOUBLE_BUFFER */ + + /*Enable host channel */ + USB_DRD_SET_CHEP_RX_STATUS(USBx, phy_ch_num, USB_CHEP_RX_STRX); + } + else /* Out Channel */ + { + /* Multi packet transfer*/ + if (hc->xfer_len > hc->max_packet) + { + len = hc->max_packet; + } + else + { + len = hc->xfer_len; + } + + /* configure and validate Tx endpoint */ + if (hc->doublebuffer == 0U) + { + USB_WritePMA(USBx, hc->xfer_buff, hc->pmaadress, (uint16_t)len); + USB_DRD_SET_CHEP_TX_CNT(USBx, phy_ch_num, (uint16_t)len); + + /*SET PID SETUP */ + if ((hc->data_pid) == HC_PID_SETUP) + { + USB_DRD_CHEP_TX_SETUP(USBx, phy_ch_num); + } + } +#if (USE_USB_DOUBLE_BUFFER == 1U) + else if (hc->ep_type == EP_TYPE_BULK) + { + (void)USB_HC_BULK_DB_StartXfer(USBx, hc, ch_reg, &len); + } + else + { + (void)USB_HC_ISO_DB_StartXfer(USBx, hc, len); + } +#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ + + /* Enable host channel */ + USB_DRD_SET_CHEP_TX_STATUS(USBx, hc->phy_ch_num, USB_CH_TX_VALID); + } + + return HAL_OK; +} + +#if (USE_USB_DOUBLE_BUFFER == 1U) +/** + * @brief Start Transfer of Channel isochronous out double buffer + * @param USBx Selected device + * @param hc_num Host Channel number + * This parameter can be a value from 1 to 15 + * @param len Transfer Length + * @retval HAL state + */ +static HAL_StatusTypeDef USB_HC_ISO_DB_StartXfer(USB_DRD_TypeDef *USBx, + USB_DRD_HCTypeDef *hc, + uint32_t len) +{ + uint32_t phy_ch_num = (uint32_t)hc->phy_ch_num; + + /* check the DTOG_TX to determine in which buffer we should write */ + if ((USB_DRD_GET_CHEP(USBx, phy_ch_num) & USB_CH_DTOG_TX) != 0U) + { + USB_DRD_SET_CHEP_DBUF0_CNT(USBx, phy_ch_num, 1U, len); + USB_WritePMA(USBx, hc->xfer_buff, hc->pmaaddr0, (uint16_t)len); + } + else + { + /* DTOGTX=0 */ + /* Set the Double buffer counter for pmabuffer0 */ + USB_DRD_SET_CHEP_DBUF1_CNT(USBx, phy_ch_num, 1U, len); + USB_WritePMA(USBx, hc->xfer_buff, hc->pmaaddr1, (uint16_t)len); + } + + return HAL_OK; +} + +/** + * @brief Start Transfer of Channel bulk out double buffer + * @param USBx Selected device + * @param hc_num Host Channel number + * This parameter can be a value from 1 to 15 + * @param ch_reg snapshot of the CHEPR register + * @param len Transfer Length + * @retval HAL state + */ +static HAL_StatusTypeDef USB_HC_BULK_DB_StartXfer(USB_DRD_TypeDef *USBx, + USB_DRD_HCTypeDef *hc, + uint32_t ch_reg, + uint32_t *len) +{ + uint32_t phy_ch_num = (uint32_t)hc->phy_ch_num; + + /* -Double Buffer Mangement- */ + if (hc->xfer_len_db > hc->max_packet) + { + /* enable double buffer mode */ + (void)USB_HC_DoubleBuffer(USBx, (uint8_t)phy_ch_num, USB_DRD_BULK_DBUFF_ENBALE); + *len = hc->max_packet; + hc->xfer_len_db -= *len; + + /* Prepare two buffer before enabling host */ + if ((ch_reg & USB_CH_DTOG_TX) == 0U) + { + /* Write Buffer0 */ + USB_DRD_SET_CHEP_DBUF0_CNT(USBx, phy_ch_num, 1U, (uint16_t)*len); + USB_WritePMA(USBx, hc->xfer_buff, hc->pmaaddr0, (uint16_t)*len); + } + else + { + /* Write Buffer1 */ + USB_DRD_SET_CHEP_DBUF1_CNT(USBx, phy_ch_num, 1U, (uint16_t)*len); + USB_WritePMA(USBx, hc->xfer_buff, hc->pmaaddr1, (uint16_t)*len); + } + + hc->xfer_buff += *len; + + /* Multi packet transfer */ + if (hc->xfer_len_db > hc->max_packet) + { + hc->xfer_len_db -= *len; + } + else + { + *len = hc->xfer_len_db; + hc->xfer_len_db = 0U; + } + + if ((ch_reg & USB_CH_DTOG_TX) == 0U) + { + /* Write Buffer1 */ + USB_DRD_SET_CHEP_DBUF1_CNT(USBx, phy_ch_num, 1U, (uint16_t)*len); + USB_WritePMA(USBx, hc->xfer_buff, hc->pmaaddr1, (uint16_t)*len); + } + else + { + /* Write Buffer0 */ + USB_DRD_SET_CHEP_DBUF0_CNT(USBx, phy_ch_num, 1U, (uint16_t)*len); + USB_WritePMA(USBx, hc->xfer_buff, hc->pmaaddr0, (uint16_t)*len); + } + } + else + { + /* Disable bulk double buffer mode */ + (void)USB_HC_DoubleBuffer(USBx, (uint8_t)phy_ch_num, USB_DRD_BULK_DBUFF_DISABLE); + USB_WritePMA(USBx, hc->xfer_buff, hc->pmaaddr0, (uint16_t)*len); + USB_DRD_SET_CHEP_TX_CNT(USBx, phy_ch_num, (uint16_t)*len); + } + + return HAL_OK; +} +#endif /* (USE_USB_DOUBLE_BUFFER == 1U) */ + + +/** + * @brief Halt a host channel in + * @param USBx Selected device + * @param hc_num Host Channel number + * This parameter can be a value from 1 to 15 + * @retval HAL state + */ +HAL_StatusTypeDef USB_HC_IN_Halt(USB_DRD_TypeDef *USBx, uint8_t phy_ch) +{ + /* Set disable to Channel */ + USB_DRD_SET_CHEP_RX_STATUS(USBx, phy_ch, USB_CH_RX_DIS); + + return HAL_OK; +} + + +/** + * @brief Halt a host channel out + * @param USBx Selected device + * @param hc_num Host Channel number + * This parameter can be a value from 1 to 15 + * @retval HAL state + */ +HAL_StatusTypeDef USB_HC_OUT_Halt(USB_DRD_TypeDef *USBx, uint8_t phy_ch) +{ + /* Set disable to Channel */ + USB_DRD_SET_CHEP_TX_STATUS(USBx, phy_ch, USB_CH_TX_DIS); + + return HAL_OK; +} + +/** + * @brief Stop Host Core + * @param USBx Selected device + * @retval HAL state + */ +HAL_StatusTypeDef USB_StopHost(USB_DRD_TypeDef *USBx) +{ + USBx->ISTR &= ~(USB_ISTR_DIR | USB_ISTR_L1REQ | + USB_ISTR_ESOF | USB_ISTR_SOF | + USB_ISTR_RESET | USB_ISTR_DCON | + USB_ISTR_SUSP | USB_ISTR_WKUP | + USB_ISTR_ERR | USB_ISTR_PMAOVR | + USB_ISTR_CTR); + + /* Set PowerDown */ + USBx->CNTR |= USB_CNTR_PDWN; + + /* Force a Reset */ + USBx->CNTR |= USB_CNTR_USBRST; + + return HAL_OK; +} + +/** + * @} + */ + +/** + * @} + */ +#endif /* defined (USB_DRD_FS) */ +#endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */ + +/** + * @} + */ diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_utils.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_utils.c new file mode 100644 index 0000000000..d81eb0641a --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_ll_utils.c @@ -0,0 +1,933 @@ +/** + ****************************************************************************** + * @file stm32h5xx_ll_utils.c + * @author MCD Application Team + * @brief UTILS LL module driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_ll_utils.h" +#include "stm32h5xx_ll_rcc.h" +#include "stm32h5xx_ll_system.h" +#include "stm32h5xx_ll_pwr.h" +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +/** @addtogroup STM32H5xx_LL_Driver + * @{ + */ + +/** @addtogroup UTILS_LL + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @addtogroup UTILS_LL_Private_Constants + * @{ + */ +#define UTILS_MAX_FREQUENCY_SCALE0 250000000U /*!< Maximum frequency for system clock at power scale0, in Hz */ +#define UTILS_MAX_FREQUENCY_SCALE1 180000000U /*!< Maximum frequency for system clock at power scale1, in Hz */ +#define UTILS_MAX_FREQUENCY_SCALE2 130000000U /*!< Maximum frequency for system clock at power scale2, in Hz */ +#define UTILS_MAX_FREQUENCY_SCALE3 80000000U /*!< Maximum frequency for system clock at power scale3, in Hz */ + +/* Defines used for PLL range */ +#define UTILS_PLLVCO_INPUT_MIN1 1000000U /*!< Frequency min for the low range PLLVCO input, in Hz */ +#define UTILS_PLLVCO_INPUT_MAX1 2000000U /*!< Frequency max for the wide range PLLVCO input, in Hz */ +#define UTILS_PLLVCO_INPUT_MIN2 2000000U /*!< Frequency min for the low range PLLVCO input, in Hz */ +#define UTILS_PLLVCO_INPUT_MAX2 4000000U /*!< Frequency max for the wide range PLLVCO input, in Hz */ +#define UTILS_PLLVCO_INPUT_MIN3 4000000U /*!< Frequency min for the low range PLLVCO input, in Hz */ +#define UTILS_PLLVCO_INPUT_MAX3 8000000U /*!< Frequency max for the wide range PLLVCO input, in Hz */ +#define UTILS_PLLVCO_INPUT_MIN4 8000000U /*!< Frequency min for the low range PLLVCO input, in Hz */ +#define UTILS_PLLVCO_INPUT_MAX4 16000000U /*!< Frequency max for the wide range PLLVCO input, in Hz */ + +#define UTILS_PLLVCO_MEDIUM_OUTPUT_MIN 150000000U /*!< Frequency min for the medium range PLLVCO output, in Hz */ +#define UTILS_PLLVCO_WIDE_OUTPUT_MIN 192000000U /*!< Frequency min for the wide range PLLVCO output, in Hz */ +#define UTILS_PLLVCO_MEDIUM_OUTPUT_MAX 420000000U /*!< Frequency max for the medium range PLLVCO output, in Hz */ +#define UTILS_PLLVCO_WIDE_OUTPUT_MAX 836000000U /*!< Frequency max for the wide range PLLVCO output, in Hz */ +/* Defines used for HSE range */ +#define UTILS_HSE_FREQUENCY_MIN 4000000U /*!< Frequency min for HSE frequency, in Hz */ +#define UTILS_HSE_FREQUENCY_MAX 50000000U /*!< Frequency max for HSE frequency, in Hz */ + +/* Defines used for FLASH latency according to HCLK Frequency */ +#define UTILS_SCALE0_LATENCY0_FREQ 38000000U /*!< HCLK frequency to set FLASH latency 0 in power scale 0 */ +#define UTILS_SCALE0_LATENCY1_FREQ 76000000U /*!< HCLK frequency to set FLASH latency 1 in power scale 0 */ +#define UTILS_SCALE0_LATENCY2_FREQ 114000000U /*!< HCLK frequency to set FLASH latency 2 in power scale 0 */ +#define UTILS_SCALE0_LATENCY3_FREQ 152000000U /*!< HCLK frequency to set FLASH latency 3 in power scale 0 */ +#define UTILS_SCALE0_LATENCY4_FREQ 190000000U /*!< HCLK frequency to set FLASH latency 4 in power scale 0 */ +#define UTILS_SCALE0_LATENCY5_FREQ 250000000U /*!< HCLK frequency to set FLASH latency 5 in power scale 0 */ + +#define UTILS_SCALE1_LATENCY0_FREQ 32000000U /*!< HCLK frequency to set FLASH latency 0 in power scale 1 */ +#define UTILS_SCALE1_LATENCY1_FREQ 64000000U /*!< HCLK frequency to set FLASH latency 1 in power scale 1 */ +#define UTILS_SCALE1_LATENCY2_FREQ 96000000U /*!< HCLK frequency to set FLASH latency 2 in power scale 1 */ +#define UTILS_SCALE1_LATENCY3_FREQ 128000000U /*!< HCLK frequency to set FLASH latency 3 in power scale 1 */ +#define UTILS_SCALE1_LATENCY4_FREQ 160000000U /*!< HCLK frequency to set FLASH latency 4 in power scale 1 */ +#define UTILS_SCALE1_LATENCY5_FREQ 180000000U /*!< HCLK frequency to set FLASH latency 5 in power scale 1 */ + +#define UTILS_SCALE2_LATENCY0_FREQ 26000000U /*!< HCLK frequency to set FLASH latency 0 in power scale 2 */ +#define UTILS_SCALE2_LATENCY1_FREQ 50000000U /*!< HCLK frequency to set FLASH latency 1 in power scale 2 */ +#define UTILS_SCALE2_LATENCY2_FREQ 80000000U /*!< HCLK frequency to set FLASH latency 2 in power scale 2 */ +#define UTILS_SCALE2_LATENCY3_FREQ 106000000U /*!< HCLK frequency to set FLASH latency 3 in power scale 2 */ +#define UTILS_SCALE2_LATENCY4_FREQ 130000000U /*!< HCLK frequency to set FLASH latency 4 in power scale 2 */ + +#define UTILS_SCALE3_LATENCY0_FREQ 16000000U /*!< HCLK frequency to set FLASH latency 0 in power scale 3 */ +#define UTILS_SCALE3_LATENCY1_FREQ 32000000U /*!< HCLK frequency to set FLASH latency 1 in power scale 3 */ +#define UTILS_SCALE3_LATENCY2_FREQ 50000000U /*!< HCLK frequency to set FLASH latency 2 in power scale 3 */ +#define UTILS_SCALE3_LATENCY3_FREQ 65000000U /*!< HCLK frequency to set FLASH latency 3 in power scale 3 */ +#define UTILS_SCALE3_LATENCY4_FREQ 80000000U /*!< HCLK frequency to set FLASH latency 4 in power scale 3 */ +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup UTILS_LL_Private_Macros + * @{ + */ +#define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) (((__VALUE__) == LL_RCC_SYSCLK_DIV_1) \ + || ((__VALUE__) == LL_RCC_SYSCLK_DIV_2) \ + || ((__VALUE__) == LL_RCC_SYSCLK_DIV_4) \ + || ((__VALUE__) == LL_RCC_SYSCLK_DIV_8) \ + || ((__VALUE__) == LL_RCC_SYSCLK_DIV_16) \ + || ((__VALUE__) == LL_RCC_SYSCLK_DIV_64) \ + || ((__VALUE__) == LL_RCC_SYSCLK_DIV_128) \ + || ((__VALUE__) == LL_RCC_SYSCLK_DIV_256) \ + || ((__VALUE__) == LL_RCC_SYSCLK_DIV_512)) + +#define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \ + || ((__VALUE__) == LL_RCC_APB1_DIV_2) \ + || ((__VALUE__) == LL_RCC_APB1_DIV_4) \ + || ((__VALUE__) == LL_RCC_APB1_DIV_8) \ + || ((__VALUE__) == LL_RCC_APB1_DIV_16)) + +#define IS_LL_UTILS_APB2_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB2_DIV_1) \ + || ((__VALUE__) == LL_RCC_APB2_DIV_2) \ + || ((__VALUE__) == LL_RCC_APB2_DIV_4) \ + || ((__VALUE__) == LL_RCC_APB2_DIV_8) \ + || ((__VALUE__) == LL_RCC_APB2_DIV_16)) + +#define IS_LL_UTILS_APB3_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB3_DIV_1) \ + || ((__VALUE__) == LL_RCC_APB3_DIV_2) \ + || ((__VALUE__) == LL_RCC_APB3_DIV_4) \ + || ((__VALUE__) == LL_RCC_APB3_DIV_8) \ + || ((__VALUE__) == LL_RCC_APB3_DIV_16)) + +#define IS_LL_UTILS_PLLM_VALUE(__VALUE__) ((1U <= (__VALUE__)) && ((__VALUE__) <= 63U)) + +#define IS_LL_UTILS_PLLN_VALUE(__VALUE__) ((4U <= (__VALUE__)) && ((__VALUE__) <= 512U)) + +#define IS_LL_UTILS_PLLP_VALUE(__VALUE__) ((2U <= (__VALUE__)) && ((__VALUE__) <= 128U)) + +#define IS_LL_UTILS_FRACN_VALUE(__VALUE__) ((__VALUE__) <= 0x1FFFU) + +#define IS_LL_UTILS_PLLVCO_INPUT(__VALUE__, __RANGE__) ( \ + (((__RANGE__) == LL_RCC_PLLINPUTRANGE_1_2) && \ + (UTILS_PLLVCO_INPUT_MIN1 <= (__VALUE__)) && \ + ((__VALUE__) <= UTILS_PLLVCO_INPUT_MAX1)) || \ + (((__RANGE__) == LL_RCC_PLLINPUTRANGE_2_4) && \ + (UTILS_PLLVCO_INPUT_MIN2 <= (__VALUE__)) && \ + ((__VALUE__) <= UTILS_PLLVCO_INPUT_MAX2)) || \ + (((__RANGE__) == LL_RCC_PLLINPUTRANGE_4_8) && \ + (UTILS_PLLVCO_INPUT_MIN3 <= (__VALUE__)) && \ + ((__VALUE__) <= UTILS_PLLVCO_INPUT_MAX3)) || \ + (((__RANGE__) == LL_RCC_PLLINPUTRANGE_8_16) && \ + (UTILS_PLLVCO_INPUT_MIN4 <= (__VALUE__)) && \ + ((__VALUE__) <= UTILS_PLLVCO_INPUT_MAX4))) + +#define IS_LL_UTILS_PLLVCO_OUTPUT(__VALUE__, __RANGE__) ( \ + (((__RANGE__) == LL_RCC_PLLVCORANGE_MEDIUM) && \ + (UTILS_PLLVCO_MEDIUM_OUTPUT_MIN <= (__VALUE__)) && \ + ((__VALUE__) <= UTILS_PLLVCO_MEDIUM_OUTPUT_MAX)) || \ + (((__RANGE__) == LL_RCC_PLLVCORANGE_WIDE) && \ + (UTILS_PLLVCO_WIDE_OUTPUT_MIN <= (__VALUE__)) && \ + ((__VALUE__) <= UTILS_PLLVCO_WIDE_OUTPUT_MAX))) + +#define IS_LL_UTILS_CHECK_VCO_RANGES(__RANGEIN__, __RANGEOUT__) ( \ + (((__RANGEIN__) == LL_RCC_PLLINPUTRANGE_1_2) && \ + ((__RANGEOUT__) == LL_RCC_PLLVCORANGE_MEDIUM)) || \ + (((__RANGEIN__) != LL_RCC_PLLINPUTRANGE_1_2) && \ + ((__RANGEOUT__) == LL_RCC_PLLVCORANGE_WIDE))) + +#define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE0) ? \ + ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE0) : \ + (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1) ? \ + ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE1) : \ + (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE2) ? \ + ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE2) : \ + ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE3)) + +#define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON) \ + || ((__STATE__) == LL_UTILS_HSEBYPASS_DIGITAL_ON) \ + || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF)) + +#define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN) &&\ + ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX)) +/** + * @} + */ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup UTILS_LL_Private_Functions UTILS Private functions + * @{ + */ +static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, + const LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct); +static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, + LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct); +static ErrorStatus UTILS_PLL_IsBusy(void); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup UTILS_LL_Exported_Functions + * @{ + */ + +/** @addtogroup UTILS_LL_EF_DELAY + * @{ + */ + +/** + * @brief This function configures the Cortex-M SysTick source to have 1ms time base. + * @note When a RTOS is used, it is recommended to avoid changing the Systick + * configuration by calling this function, for a delay use rather osDelay RTOS service. + * @param HCLKFrequency HCLK frequency in Hz + * @note HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq + * @retval None + */ +void LL_Init1msTick(uint32_t HCLKFrequency) +{ + /* Use frequency provided in argument */ + LL_InitTick(HCLKFrequency, 1000U); +} + +/** + * @brief This function provides accurate delay (in milliseconds) based + * on SysTick counter flag + * @note When a RTOS is used, it is recommended to avoid using blocking delay + * and use rather osDelay service. + * @note To respect 1ms timebase, user should call @ref LL_Init1msTick function which + * will configure Systick to 1ms + * @param Delay specifies the delay time length, in milliseconds. + * @retval None + */ + +void LL_mDelay(uint32_t Delay) +{ + __IO uint32_t tmp = SysTick->CTRL; /* Clear the COUNTFLAG first */ + uint32_t tmpDelay = Delay; + + /* Add this code to indicate that local variable is not used */ + ((void)tmp); + + /* Add a period to guaranty minimum wait */ + if (tmpDelay < LL_MAX_DELAY) + { + tmpDelay++; + } + + while (tmpDelay != 0U) + { + if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U) + { + tmpDelay--; + } + } +} + +/** + * @} + */ + +/** @addtogroup UTILS_EF_SYSTEM + * @brief System Configuration functions + * + @verbatim + =============================================================================== + ##### System Configuration functions ##### + =============================================================================== + [..] + System, AHB and APB buses clocks configuration + + (+) The maximum frequency of the SYSCLK is 250 MHz and HCLK is 250 MHz. + (+) The maximum frequency of the PCLK1, PCLK2 and PCLK3 is 250 MHz. + @endverbatim + @internal + Depending on the device voltage range, the maximum frequency should be + adapted accordingly: + + (++) Table 1. HCLK clock frequency for STM32H5 devices + (++) +-----------------------------------------------------------------------------------------------+ + (++) | Latency | HCLK clock frequency (MHz) | + (++) | |-----------------------------------------------------------------------------| + (++) | | voltage range 0 | voltage range 1 | voltage range 2 | voltage range 3 | + (++) | | 1.26 - 1.35V | 1.15 - 1.26V | 1.05 - 1.15V | 0,95 - 1,05V | + (++) |-----------------|-------------------|------------------|------------------|-------------------| + (++) |0WS(1 CPU cycles)| 0 < HCLK <= 38 | 0 < HCLK <= 32 | 0 < HCLK <= 26 | 0 < HCLK <= 16 | + (++) |-----------------|-------------------|------------------|------------------|-------------------| + (++) |1WS(2 CPU cycles)| 38 < HCLK <= 76 | 32 < HCLK <= 64 | 26 < HCLK <= 50 | 16 < HCLK <= 32 | + (++) |-----------------|-------------------|------------------|------------------|-------------------| + (++) |2WS(3 CPU cycles)| 76 < HCLK <= 114 | 64 < HCLK <= 96 | 50 < HCLK <= 80 | 32 < HCLK <= 50 | + (++) |-----------------|-------------------|------------------|------------------|-------------------| + (++) |3WS(4 CPU cycles)| 114 < HCLK <= 152 | 96 < HCLK <= 128 | 80 < HCLK <= 106 | 50 < HCLK <= 65 | + (++) |-----------------|-------------------|------------------|------------------|-------------------| + (++) |4WS(5 CPU cycles)| 152 < HCLK <= 190| 128 < HCLK <= 160| 106 < HCLK <= 130| 65 < HCLK <= 80 | + (++) |-----------------|-------------------|------------------|------------------|-------------------| + (++) |5WS(6 CPU cycles)| 190 < HCLK <= 250| 160 < HCLK <= 180| NA | NA | + (++) +-----------------+-------------------+------------------+------------------+-------------------+ + + @endinternal + * @{ + */ + +/** + * @brief This function sets directly SystemCoreClock CMSIS variable. + * @note Variable can be calculated also through SystemCoreClockUpdate function. + * @param HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro) + * @retval None + */ +void LL_SetSystemCoreClock(uint32_t HCLKFrequency) +{ + /* HCLK clock frequency */ + SystemCoreClock = HCLKFrequency; +} + +/** + * @brief This function configures system clock at maximum frequency with CSI as clock source of the PLL1 + * @note The application needs to ensure that all PLLs is disabled. + * @note Function is based on the following formula: + * - PLL1 output frequency = (((CSI frequency / PLL1M) * PLL1N) / PLL1P) + * - PLL1M: ensure that the VCO input frequency ranges from 1 to 16 MHz (PLL1VCO_input = CSI frequency / PLL1M) + * - PLL1N: ensure that the VCO output frequency is between 192 and 836 MHz + * (PLL1VCO_output = PLL1VCO_input * PLL1N) + * - PLL1P: ensure that max frequency at 250 MHz is reached (PLL1VCO_output / PLL1P) + * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains + * the configuration information for the PLL. + * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains + * the configuration information for the BUS prescalers. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: Max frequency configuration done + * - ERROR: Max frequency configuration not done + */ +ErrorStatus LL_PLL_ConfigSystemClock_CSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, + LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct) +{ + ErrorStatus status; +#ifdef USE_FULL_ASSERT + uint32_t vcoinput_freq; + uint32_t vcooutput_freq; +#endif /* USE_FULL_ASSERT */ + uint32_t pllfreq; + + /* Check the parameters */ + assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM)); + assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN)); + assert_param(IS_LL_UTILS_PLLP_VALUE(UTILS_PLLInitStruct->PLLP)); + assert_param(IS_LL_UTILS_FRACN_VALUE(UTILS_PLLInitStruct->FRACN)); + + /* Check VCO Input frequency */ +#ifdef USE_FULL_ASSERT + vcoinput_freq = CSI_VALUE / UTILS_PLLInitStruct->PLLM; +#endif /* USE_FULL_ASSERT */ + assert_param(IS_LL_UTILS_PLLVCO_INPUT(vcoinput_freq, UTILS_PLLInitStruct->VCO_Input)); + + /* Check VCO Input ranges */ + assert_param(IS_LL_UTILS_CHECK_VCO_RANGES(UTILS_PLLInitStruct->VCO_Input, UTILS_PLLInitStruct->VCO_Output)); + + /* Check VCO Output frequency */ +#ifdef USE_FULL_ASSERT + vcooutput_freq = LL_RCC_CalcPLLClockFreq(CSI_VALUE, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN, + UTILS_PLLInitStruct->FRACN, 1U); + /* PLL1P Set to 1 to check the assert param (VCO_output)*/ +#endif /* USE_FULL_ASSERT */ + assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(vcooutput_freq, UTILS_PLLInitStruct->VCO_Output)); + + /* Check if the main PLL is enabled */ + if (UTILS_PLL_IsBusy() == SUCCESS) + { + /* Calculate the new PLL output frequency */ + pllfreq = UTILS_GetPLLOutputFrequency(CSI_VALUE, UTILS_PLLInitStruct); + + /* Enable CSI if not enabled */ + if (LL_RCC_CSI_IsReady() != 1U) + { + LL_RCC_CSI_Enable(); + while (LL_RCC_CSI_IsReady() != 1U) + { + /* Wait for CSI ready */ + } + } + + /* Configure PLL */ + LL_RCC_PLL1_ConfigDomain_SYS(LL_RCC_PLL1SOURCE_CSI, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN, + UTILS_PLLInitStruct->PLLP); + LL_RCC_PLL1FRACN_Disable(); + LL_RCC_PLL1_SetFRACN(UTILS_PLLInitStruct->FRACN); + LL_RCC_PLL1FRACN_Enable(); + LL_RCC_PLL1_SetVCOInputRange(UTILS_PLLInitStruct->VCO_Input); + LL_RCC_PLL1_SetVCOOutputRange(UTILS_PLLInitStruct->VCO_Output); + + /* Enable PLL and switch system clock to PLL */ + status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct); + } + else + { + /* Current PLL configuration cannot be modified */ + status = ERROR; + } + + return status; +} + + +/** + * @brief This function configures system clock at maximum frequency with HSI as clock source of the PLL1 + * @note The application need to ensure that all PLLs are disabled. + * @note Function is based on the following formula: + * - PLL1 output frequency = (((HSI frequency / PLL1M) * PLL1N) / PLL1P) + * - PLL1M: ensure that the VCO input frequency ranges from 1 to 16 MHz (PLL1VCO_input = HSI frequency / PLL1M) + * - PLL1N: ensure that the VCO output frequency is between 150 and 836 MHz + * (PLL1VCO_output = PLL1VCO_input * PLL1N) + * - PLL1P: ensure that max frequency at 250 MHz is reach (PLL1VCO_output / PLL1P) + * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains + * the configuration information for the PLL1. + * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains + * the configuration information for the BUS prescalers. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: Max frequency configuration done + * - ERROR: Max frequency configuration not done + * + * + */ +ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, + LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct) +{ + ErrorStatus status; +#ifdef USE_FULL_ASSERT + uint32_t vcoinput_freq; + uint32_t vcooutput_freq; +#endif /* USE_FULL_ASSERT */ + uint32_t pllfreq; + uint32_t hsi_clk; + + /* Check the parameters */ + assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM)); + assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN)); + assert_param(IS_LL_UTILS_PLLP_VALUE(UTILS_PLLInitStruct->PLLP)); + assert_param(IS_LL_UTILS_FRACN_VALUE(UTILS_PLLInitStruct->FRACN)); + + hsi_clk = (HSI_VALUE >> (LL_RCC_HSI_GetDivider() >> RCC_CR_HSIDIV_Pos)); + + /* Check VCO Input frequency */ +#ifdef USE_FULL_ASSERT + vcoinput_freq = hsi_clk / UTILS_PLLInitStruct->PLLM; +#endif /* USE_FULL_ASSERT */ + assert_param(IS_LL_UTILS_PLLVCO_INPUT(vcoinput_freq, UTILS_PLLInitStruct->VCO_Input)); + + /* Check VCO Input ranges */ + assert_param(IS_LL_UTILS_CHECK_VCO_RANGES(UTILS_PLLInitStruct->VCO_Input, UTILS_PLLInitStruct->VCO_Output)); + + /* Check VCO Output frequency */ +#ifdef USE_FULL_ASSERT + vcooutput_freq = LL_RCC_CalcPLLClockFreq(hsi_clk, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN, + UTILS_PLLInitStruct->FRACN, 1UL); + /* PLL1P Set to 1 to check the assert param (VCO_output)*/ +#endif /* USE_FULL_ASSERT */ + assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(vcooutput_freq, UTILS_PLLInitStruct->VCO_Output)); + + /* Check if the main PLL is enabled */ + if (UTILS_PLL_IsBusy() == SUCCESS) + { + /* Calculate the new PLL output frequency */ + pllfreq = UTILS_GetPLLOutputFrequency(hsi_clk, UTILS_PLLInitStruct); + + /* Enable HSI if not enabled */ + if (LL_RCC_HSI_IsReady() != 1U) + { + LL_RCC_HSI_Enable(); + while (LL_RCC_HSI_IsReady() != 1U) + { + /* Wait for HSI ready */ + } + } + + /* Configure PLL */ + LL_RCC_PLL1_ConfigDomain_SYS(LL_RCC_PLL1SOURCE_HSI, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN, + UTILS_PLLInitStruct->PLLP); + LL_RCC_PLL1FRACN_Disable(); + LL_RCC_PLL1_SetFRACN(UTILS_PLLInitStruct->FRACN); + LL_RCC_PLL1FRACN_Enable(); + LL_RCC_PLL1_SetVCOInputRange(UTILS_PLLInitStruct->VCO_Input); + LL_RCC_PLL1_SetVCOOutputRange(UTILS_PLLInitStruct->VCO_Output); + + /* Enable PLL and switch system clock to PLL */ + status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct); + } + else + { + /* Current PLL configuration cannot be modified */ + status = ERROR; + } + + return status; +} + +/** + * @brief This function configures system clock with HSE as clock source of the PLL1 + * @note The application needs to ensure that the PLL1 is disabled. + * @note Function is based on the following formula: + * - PLL1 output frequency = (((HSE frequency / PLL1M) * PLL1N) / PLL1P) + * - PLL1M: ensure that the VCO input frequency ranges from 1 to 16 MHz (PLL1VCO_input = HSE frequency / PLL1M) + * - PLL1N: ensure that the VCO output frequency is between 192 and 836 MHz + * (PLL1VCO_output = PLL1VCO_input * PLL1N) + * - PLL1P: ensure that max frequency at 250 MHz is reached (PLL1VCO_output / PLL1P) + * @param HSEFrequency Value between Min_Data = 4000000 and Max_Data = 50000000 + * @param HSEBypass This parameter can be one of the following values: + * @arg @ref LL_UTILS_HSEBYPASS_ON + * @arg @ref LL_UTILS_HSEBYPASS_OFF + * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains + * the configuration information for the PLL. + * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains + * the configuration information for the BUS prescalers. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: Max frequency configuration done + * - ERROR: Max frequency configuration not done + */ +ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass, + LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, + LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct) +{ + ErrorStatus status; +#ifdef USE_FULL_ASSERT + uint32_t vcoinput_freq; + uint32_t vcooutput_freq; +#endif /* USE_FULL_ASSERT */ + uint32_t pllfreq; + + /* Check the parameters */ + assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM)); + assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN)); + assert_param(IS_LL_UTILS_PLLP_VALUE(UTILS_PLLInitStruct->PLLP)); + assert_param(IS_LL_UTILS_FRACN_VALUE(UTILS_PLLInitStruct->FRACN)); + assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency)); + assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass)); + + /* Check VCO Input frequency */ +#ifdef USE_FULL_ASSERT + vcoinput_freq = HSEFrequency / UTILS_PLLInitStruct->PLLM; +#endif /* USE_FULL_ASSERT */ + assert_param(IS_LL_UTILS_PLLVCO_INPUT(vcoinput_freq, UTILS_PLLInitStruct->VCO_Input)); + + /* Check VCO Input/output ranges compatibility */ + assert_param(IS_LL_UTILS_CHECK_VCO_RANGES(UTILS_PLLInitStruct->VCO_Input, UTILS_PLLInitStruct->VCO_Output)); + + /* Check VCO output frequency */ +#ifdef USE_FULL_ASSERT + vcooutput_freq = LL_RCC_CalcPLLClockFreq(HSEFrequency, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN, + UTILS_PLLInitStruct->FRACN, 1U); + /* PLL1P Set to 1 to check the assert param (VCO_output)*/ +#endif /* USE_FULL_ASSERT */ + assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(vcooutput_freq, UTILS_PLLInitStruct->VCO_Output)); + + /* Check if the main PLL is enabled */ + if (UTILS_PLL_IsBusy() == SUCCESS) + { + /* Calculate the new PLL output frequency */ + pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct); + + /* Enable HSE if not enabled */ + if (LL_RCC_HSE_IsReady() != 1U) + { + /* Check if need to enable HSE bypass feature or not */ + if (HSEBypass == LL_UTILS_HSEBYPASS_ON) + { + LL_RCC_HSE_EnableBypass(); + LL_RCC_HSE_SetExternalClockType(LL_RCC_HSE_ANALOG_TYPE); + } + else if (HSEBypass == LL_UTILS_HSEBYPASS_DIGITAL_ON) + { + LL_RCC_HSE_EnableBypass(); + LL_RCC_HSE_SetExternalClockType(LL_RCC_HSE_DIGITAL_TYPE); + } + else + { + LL_RCC_HSE_DisableBypass(); + } + + /* Enable HSE */ + LL_RCC_HSE_Enable(); + while (LL_RCC_HSE_IsReady() != 1U) + { + /* Wait for HSE ready */ + } + } + + /* Configure PLL */ + LL_RCC_PLL1_ConfigDomain_SYS(LL_RCC_PLL1SOURCE_HSE, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN, + UTILS_PLLInitStruct->PLLP); + LL_RCC_PLL1FRACN_Disable(); + LL_RCC_PLL1_SetFRACN(UTILS_PLLInitStruct->FRACN); + LL_RCC_PLL1FRACN_Enable(); + LL_RCC_PLL1_SetVCOInputRange(UTILS_PLLInitStruct->VCO_Input); + LL_RCC_PLL1_SetVCOOutputRange(UTILS_PLLInitStruct->VCO_Output); + + /* Enable PLL and switch system clock to PLL */ + status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct); + } + else + { + /* Current PLL configuration cannot be modified */ + status = ERROR; + } + + return status; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @brief Update number of Flash wait states in line with new frequency and current + voltage range. + * @param HCLK_Frequency HCLK frequency + * @retval An ErrorStatus enumeration value: + * - SUCCESS: Latency has been modified + * - ERROR: Latency cannot be modified + */ +ErrorStatus LL_SetFlashLatency(uint32_t HCLK_Frequency) +{ + ErrorStatus status = SUCCESS; + uint32_t timeout; + uint32_t getlatency; + uint32_t latency = LL_FLASH_LATENCY_0; /* default value 0WS */ + + /* Frequency cannot be equal to 0 */ + if (HCLK_Frequency == 0U) + { + status = ERROR; + } + else + { + if (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE0) + { + if (HCLK_Frequency <= UTILS_SCALE0_LATENCY0_FREQ) + { + /* 0 < HCLK <= 38 => 0WS (1 CPU cycles) : Do nothing, keep latency to default LL_FLASH_LATENCY_0 */ + } + else if ((HCLK_Frequency <= UTILS_SCALE0_LATENCY1_FREQ)) + { + /* 38 < HCLK <=76 => 1WS (2 CPU cycles) */ + latency = LL_FLASH_LATENCY_1; + } + else if (HCLK_Frequency <= UTILS_SCALE0_LATENCY2_FREQ) + { + /* 76 < HCLK <= 114 => 2WS (3 CPU cycles) */ + latency = LL_FLASH_LATENCY_2; + } + else if (HCLK_Frequency <= UTILS_SCALE0_LATENCY3_FREQ) + { + /* 114 < HCLK <= 152 => 3WS (4 CPU cycles) */ + latency = LL_FLASH_LATENCY_3; + } + else if (HCLK_Frequency <= UTILS_SCALE0_LATENCY4_FREQ) + { + /* 152 < HCLK <= 190 => 4WS (5 CPU cycles) */ + latency = LL_FLASH_LATENCY_4; + } + else if (HCLK_Frequency <= UTILS_SCALE0_LATENCY5_FREQ) + { + /* 190 < HCLK <= 250 => 5WS (6 CPU cycles) */ + latency = LL_FLASH_LATENCY_5; + } + else + { + status = ERROR; + } + } + else if (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1) + { + if (HCLK_Frequency <= UTILS_SCALE1_LATENCY0_FREQ) + { + /* 0 < HCLK <= 32 => 0WS (1 CPU cycles) : Do nothing, keep latency to default LL_FLASH_LATENCY_0 */ + } + else if (HCLK_Frequency <= UTILS_SCALE1_LATENCY1_FREQ) + { + /* 32 < HCLK <=64 => 1WS (2 CPU cycles) */ + latency = LL_FLASH_LATENCY_1; + } + else if (HCLK_Frequency <= UTILS_SCALE1_LATENCY2_FREQ) + { + /* 64 < HCLK <= 96 => 2WS (3 CPU cycles) */ + latency = LL_FLASH_LATENCY_2; + } + else if (HCLK_Frequency <= UTILS_SCALE1_LATENCY3_FREQ) + { + /* 96 < HCLK <= 128 => 3WS (4 CPU cycles) */ + latency = LL_FLASH_LATENCY_3; + } + else if (HCLK_Frequency <= UTILS_SCALE1_LATENCY4_FREQ) + { + /* 128 < HCLK <= 160 => 4WS (5 CPU cycles) */ + latency = LL_FLASH_LATENCY_4; + } + else if (HCLK_Frequency <= UTILS_SCALE1_LATENCY5_FREQ) + { + /* 160 < HCLK <= 150 => 5WS (6 CPU cycles) */ + latency = LL_FLASH_LATENCY_5; + } + else + { + status = ERROR; + } + } + else if (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE2) + { + if (HCLK_Frequency <= UTILS_SCALE2_LATENCY0_FREQ) + { + /* 0 < HCLK <= 26 => 0WS (1 CPU cycles) : Do nothing, keep latency to default LL_FLASH_LATENCY_0 */ + } + else if (HCLK_Frequency <= UTILS_SCALE2_LATENCY1_FREQ) + { + /* 26 < HCLK <= 50 => 1WS (2 CPU cycles) */ + latency = LL_FLASH_LATENCY_1; + } + else if (HCLK_Frequency <= UTILS_SCALE2_LATENCY2_FREQ) + { + /* 50 < HCLK <= 80 => 2WS (3 CPU cycles) */ + latency = LL_FLASH_LATENCY_2; + } + else if (HCLK_Frequency <= UTILS_SCALE2_LATENCY3_FREQ) + { + /* 80 < HCLK <= 106 => 3WS (4 CPU cycles) */ + latency = LL_FLASH_LATENCY_3; + } + else if (HCLK_Frequency <= UTILS_SCALE2_LATENCY4_FREQ) + { + /* 106 < HCLK <= 130 => 4WS (5 CPU cycles) */ + latency = LL_FLASH_LATENCY_4; + } + else + { + status = ERROR; + } + } + else /* Voltage Scale 3 */ + { + if (HCLK_Frequency <= UTILS_SCALE3_LATENCY0_FREQ) + { + /* 0 < HCLK <= 16 => 0WS (1 CPU cycles) : Do nothing, keep latency to default LL_FLASH_LATENCY_0 */ + } + else if (HCLK_Frequency <= UTILS_SCALE3_LATENCY1_FREQ) + { + /* 16 < HCLK <= 32 => 1WS (2 CPU cycles) */ + latency = LL_FLASH_LATENCY_1; + } + else if (HCLK_Frequency <= UTILS_SCALE3_LATENCY2_FREQ) + { + /* 32 < HCLK <= 50 => 2WS (3 CPU cycles) */ + latency = LL_FLASH_LATENCY_2; + } + else if (HCLK_Frequency <= UTILS_SCALE3_LATENCY3_FREQ) + { + /* 50 < HCLK <= 65 => 3WS (4 CPU cycles) */ + latency = LL_FLASH_LATENCY_3; + } + else if (HCLK_Frequency <= UTILS_SCALE3_LATENCY4_FREQ) + { + /* 65 < HCLK <= 80 => 4WS (5 CPU cycles) */ + latency = LL_FLASH_LATENCY_4; + } + else + { + status = ERROR; + } + } + } + + if (status == SUCCESS) + { + LL_FLASH_SetLatency(latency); + + /* Check that the new number of wait states is taken into account to access the Flash + memory by reading the FLASH_ACR register */ + timeout = 2; + do + { + /* Wait for Flash latency to be updated */ + getlatency = LL_FLASH_GetLatency(); + timeout--; + } while ((getlatency != latency) && (timeout > 0U)); + + if (getlatency != latency) + { + status = ERROR; + } + } + return status; +} + +/** @addtogroup UTILS_LL_Private_Functions + * @{ + */ +/** + * @brief Function to Get PLL1 Output frequency + * @param PLL_InputFrequency PLL1 input frequency (in Hz) + * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains + * the configuration information for the PLL. + * @retval PLL output frequency (in Hz) + */ +static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, + const LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct) +{ + uint32_t pllfreq; + + /* Check the parameters */ + assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM)); + assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN)); + assert_param(IS_LL_UTILS_PLLP_VALUE(UTILS_PLLInitStruct->PLLP)); + assert_param(IS_LL_UTILS_FRACN_VALUE(UTILS_PLLInitStruct->FRACN)); + + /* Check different PLL parameters according to RM */ + /* - PLLM: ensure that the VCO input frequency is in the correct range. */ + pllfreq = PLL_InputFrequency / (UTILS_PLLInitStruct->PLLM); + assert_param(IS_LL_UTILS_PLLVCO_INPUT(pllfreq, UTILS_PLLInitStruct->VCO_Input)); + + /* - PLLN: ensure that the VCO output frequency is in the correct range. */ + pllfreq = pllfreq * (UTILS_PLLInitStruct->PLLN); + assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(pllfreq, UTILS_PLLInitStruct->VCO_Output)); + + /* - PLLP: ensure that PLL1P output frequency does not exceed the corresponding maximum voltage scale frequency. */ + pllfreq = pllfreq / (UTILS_PLLInitStruct->PLLP); + assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq)); + + return pllfreq; +} + +/** + * @brief Function to check that main PLL can be modified + * @retval An ErrorStatus enumeration value: + * - SUCCESS: Main PLL modification can be done + * - ERROR: Main PLL is busy + */ +static ErrorStatus UTILS_PLL_IsBusy(void) +{ + ErrorStatus status = SUCCESS; + + /* Check if PLL1 is busy*/ + if (LL_RCC_PLL1_IsReady() != 0U) + { + /* PLL configuration cannot be modified */ + status = ERROR; + } + + return status; +} + +/** + * @brief Function to enable PLL1 and switch system clock to PLL1 + * @param SYSCLK_Frequency SYSCLK frequency + * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains + * the configuration information for the BUS prescalers. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: No problem to switch system to PLL1 + * - ERROR: Problem to switch system to PLL1 + */ +static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, + LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct) +{ + ErrorStatus status = SUCCESS; + uint32_t hclk_frequency; + + assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->SYSCLKDivider)); + assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider)); + assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider)); + assert_param(IS_LL_UTILS_APB3_DIV(UTILS_ClkInitStruct->APB3CLKDivider)); + + /* Calculate HCLK frequency */ + hclk_frequency = __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->SYSCLKDivider); + + /* Increasing the number of wait states because of higher CPU frequency */ + if (SystemCoreClock < hclk_frequency) + { + /* Set FLASH latency to highest latency */ + status = LL_SetFlashLatency(hclk_frequency); + } + + /* Update system clock configuration */ + if (status == SUCCESS) + { + /* Enable PLL1 */ + LL_RCC_PLL1_Enable(); + LL_RCC_PLL1P_Enable(); + while (LL_RCC_PLL1_IsReady() != 1U) + { + /* Wait for PLL ready */ + } + + /* Set All APBxPrescaler to the Highest Divider */ + LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_16); + LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_16); + LL_RCC_SetAPB3Prescaler(LL_RCC_APB3_DIV_16); + + /* Set AHB prescaler*/ + LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->SYSCLKDivider); + + /* Sysclk activation on the main PLL */ + LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL1); + while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL1) + { + /* Wait for system clock switch to PLL */ + } + + /* Set APB1, APB2 & APB3 prescaler*/ + LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider); + LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider); + LL_RCC_SetAPB3Prescaler(UTILS_ClkInitStruct->APB3CLKDivider); + } + + /* Decreasing the number of wait states because of lower CPU frequency */ + if (SystemCoreClock > hclk_frequency) + { + /* Set FLASH latency to lowest latency */ + status = LL_SetFlashLatency(hclk_frequency); + } + + /* Update SystemCoreClock variable */ + if (status == SUCCESS) + { + LL_SetSystemCoreClock(hclk_frequency); + } + + return status; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + diff --git a/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_util_i3c.c b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_util_i3c.c new file mode 100644 index 0000000000..d4396b76d5 --- /dev/null +++ b/bsp/stm32/libraries/STM32H5xx_HAL/STM32H5xx_HAL_Driver/Src/stm32h5xx_util_i3c.c @@ -0,0 +1,409 @@ +/** + ********************************************************************************************************************** + * @file stm32h5xx_util_i3c.c + * @author MCD Application Team + * @brief This utility help to calculate the different I3C Timing. + ********************************************************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ********************************************************************************************************************** + */ + +/* Includes ----------------------------------------------------------------------------------------------------------*/ +#include "stm32h5xx_util_i3c.h" + +/** @addtogroup STM32H5xx_UTIL_Driver + * @{ + */ + +/** @addtogroup I3C + * @{ + */ + +/* Private typedef ---------------------------------------------------------------------------------------------------*/ +/* Private define ----------------------------------------------------------------------------------------------------*/ +/** @defgroup I3C_UTIL_Private_Define I3C Utility Private Define + * @{ + */ +#define SEC210PSEC (uint64_t)100000000000 /*!< 10ps, to take two decimal float of ns calculation */ +#define TI3CH_MIN 3200U /*!< Open drain & push pull SCL high min, 32ns */ +#define TI3CH_OD_MAX 4100U /*!< Open drain SCL high max, 41 ns */ +#define TI3CL_OD_MIN 20000U /*!< Open drain SCL low min, 200 ns */ +#define TFMPL_OD_MIN 50000U /*!< Fast Mode Plus Open drain SCL low min, 500 ns */ +#define TFML_OD_MIN 130000U /*!< Fast Mode Open drain SCL low min, 1300 ns */ +#define TFM_MIN 250000U /*!< Fast Mode, period min for ti3cclk, 2.5us */ +#define TSM_MIN 1000000U /*!< Standard Mode, period min for ti3cclk, 10us */ +#define TI3C_CAS_MIN 3840U /*!< Time SCL after START min, 38.4 ns */ +#define TCAPA 35000U /*!< Capacitor effect Value measure on Nucleo around 350ns */ +/** + * @} + */ + +/* Private macro -----------------------------------------------------------------------------------------------------*/ +/** @defgroup I3C_UTIL_Private_Macro I3C Utility Private Macro + * @{ + */ +#define DIV_ROUND_CLOSEST(x, d) (((x) + ((d) / 2U)) / (d)) +/** + * @} + */ + +/* Private function prototypes ---------------------------------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------------------------------------------------*/ +/** @defgroup I3C_UTIL_Exported_Functions I3C Utility Exported Functions + * @{ + */ + +/** @defgroup I3C_UTIL_EF_Computation Computation + * @{ + */ +/** + * @brief Calculate the I3C Controller timing according current I3C clock source and required I3C bus clock. + * @param pInputTiming : [IN] Pointer to an I3C_CtrlTimingTypeDef structure that contains + * the required parameter for I3C timing computation. + * @param pOutputConfig : [OUT] Pointer to an LL_I3C_CtrlBusConfTypeDef structure that contains + * the configuration information for the specified I3C. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: Timing calculation successfully + * - ERROR: Parameters or timing calculation error + */ +ErrorStatus I3C_CtrlTimingComputation(const I3C_CtrlTimingTypeDef *pInputTiming, + LL_I3C_CtrlBusConfTypeDef *pOutputConfig) +{ + ErrorStatus status = SUCCESS; + + /* MIPI Standard constants */ + /* I3C: Open drain & push pull SCL high min, tDIG_H & tDIG_H_MIXED: 32 ns */ + uint32_t ti3ch_min = TI3CH_MIN; + + /* I3C: Open drain SCL high max, t_HIGH: 41 ns */ + uint32_t ti3ch_od_max = TI3CH_OD_MAX; + + /* I3C: Open drain SCL high max, tHIGH: 41 ns (Ti3ch_od_max= 410) + I3C (pure bus): Open drain SCL low min, tLOW_OD: 200 ns */ + uint32_t ti3cl_od_min = TI3CL_OD_MIN; + + /* I3C (mixed bus): Open drain SCL low min, + tLOW: 500 ns (FM+ I2C on the bus) + tLOW: 1300 ns (FM I2C on the bus) */ + uint32_t tfmpl_od_min = TFMPL_OD_MIN; + uint32_t tfml_od_min = TFML_OD_MIN; + + /* I2C: min ti3cclk + fSCL: 1 MHz (FM+) + fSCL: 100 kHz (SM) */ + uint32_t tfm_min = TFM_MIN; + uint32_t tsm_min = TSM_MIN; + + /* I3C: time SCL after START min, Tcas: 38,4 ns */ + uint32_t ti3c_cas_min = TI3C_CAS_MIN; + + /* Period Clock source */ + uint32_t ti3cclk = 0U; + + /* I3C: Push pull period */ + uint32_t ti3c_pp_min = 0U; + + /* I2C: Open drain period */ + uint32_t ti2c_od_min = 0U; + + /* Time for SDA rise to 70% VDD from GND, capacitor effect */ + /* Value measure on Nucleo around 350ns */ + uint32_t tcapa = TCAPA; + + /* Compute variable */ + uint32_t sclhi3c; + uint32_t scllpp; + uint32_t scllod; + uint32_t sclhi2c; + uint32_t oneus; + uint32_t free; + uint32_t sdahold; + + /* Verify Parameters */ + if (((pInputTiming->clockSrcFreq == 0U) || (pInputTiming->i3cPPFreq == 0U)) && + (pInputTiming->busType == I3C_PURE_I3C_BUS)) + { + status = ERROR; + } + + if (((pInputTiming->clockSrcFreq == 0U) || (pInputTiming->i3cPPFreq == 0U) || (pInputTiming->i2cODFreq == 0U)) && + (pInputTiming->busType == I3C_MIXED_BUS)) + { + status = ERROR; + } + + if (status == SUCCESS) + { + /* Period Clock source */ + ti3cclk = (uint32_t)((SEC210PSEC + ((uint64_t)pInputTiming->clockSrcFreq / (uint64_t)2)) / + (uint64_t)pInputTiming->clockSrcFreq); + + if ((pInputTiming->dutyCycle > 50U) || (ti3cclk == 0U)) + { + status = ERROR; + } + } + + if ((status == SUCCESS) && (ti3cclk != 0U)) + { + /* I3C: Push pull period */ + ti3c_pp_min = (uint32_t)((SEC210PSEC + ((uint64_t)pInputTiming->i3cPPFreq / (uint64_t)2)) / + (uint64_t)pInputTiming->i3cPPFreq); + + /* I2C: Open drain period */ + ti2c_od_min = (uint32_t)((SEC210PSEC + ((uint64_t)pInputTiming->i2cODFreq / (uint64_t)2)) / + (uint64_t)pInputTiming->i2cODFreq); + + if ((pInputTiming->busType != I3C_PURE_I3C_BUS) && (ti2c_od_min > tsm_min)) + { + status = ERROR; + } + } + + /* SCL Computation */ + if ((status == SUCCESS) && (ti3cclk != 0U)) + { + /* I3C SCL high level (push-pull & open drain) */ + if (pInputTiming->busType == I3C_PURE_I3C_BUS) + { + sclhi3c = DIV_ROUND_CLOSEST(DIV_ROUND_CLOSEST(ti3c_pp_min * pInputTiming->dutyCycle, ti3cclk), 100U) - 1U; + + /* Check if sclhi3c < ti3ch_min, in that case calculate sclhi3c based on ti3ch_min */ + if (((sclhi3c + 1U) * ti3cclk) < ti3ch_min) + { + sclhi3c = DIV_ROUND_CLOSEST(ti3ch_min, ti3cclk) - 1U; + + /* Check if sclhi3c < ti3ch_min */ + if (((sclhi3c + 1U) * ti3cclk) < ti3ch_min) + { + sclhi3c += 1U; + } + + scllpp = DIV_ROUND_CLOSEST(ti3c_pp_min, ti3cclk) - (sclhi3c + 1U) - 1U; + } + else + { + sclhi3c = DIV_ROUND_CLOSEST(DIV_ROUND_CLOSEST(ti3c_pp_min * pInputTiming->dutyCycle, ti3cclk), 100U) - 1U; + + /* Check if sclhi3c < ti3ch_min */ + if (((sclhi3c + 1U) * ti3cclk) < ti3ch_min) + { + sclhi3c += 1U; + } + + scllpp = DIV_ROUND_CLOSEST((ti3c_pp_min - ((sclhi3c + 1U) * ti3cclk) + (ti3cclk / 2U)), ti3cclk) - 1U; + } + + } + else + { + /* Warning: (sclhi3c + 1) * ti3cclk > Ti3ch_od_max expected */ + sclhi3c = DIV_ROUND_CLOSEST(ti3ch_od_max, ti3cclk) - 1U; + + if (((sclhi3c + 1U) * ti3cclk) < ti3ch_min) + { + sclhi3c += 1U; + } + else if (((sclhi3c + 1U) * ti3cclk) > ti3ch_od_max) + { + sclhi3c = (ti3ch_od_max / ti3cclk); + } + else + { + /* Do nothing, keep sclhi3c as previously calculated */ + } + + /* I3C SCL low level (push-pull) */ + /* tscllpp = (scllpp + 1) x ti3cclk */ + scllpp = DIV_ROUND_CLOSEST((ti3c_pp_min - ((sclhi3c + 1U) * ti3cclk)), ti3cclk) - 1U; + } + + /* Check if scllpp is superior at (ti3c_pp_min + 1/2 clock source cycle) */ + /* Goal is to choice the scllpp approach lowest, to have a value frequency highest approach as possible */ + uint32_t ideal_scllpp = (ti3c_pp_min - ((sclhi3c + 1U) * ti3cclk)); + if (((scllpp + 1U) * ti3cclk) >= (ideal_scllpp + (ti3cclk / 2U) + 1U)) + { + scllpp -= 1U; + } + + /* Check if scllpp + sclhi3c is inferior at (ti3c_pp_min + 1/2 clock source cycle) */ + /* Goal is to increase the scllpp, to have a value frequency not out of the clock request */ + if (((scllpp + sclhi3c + 1U + 1U) * ti3cclk) < (ideal_scllpp + (ti3cclk / 2U) + 1U)) + { + scllpp += 1U; + } + + /* I3C SCL low level (pure I3C bus) */ + if (pInputTiming->busType == I3C_PURE_I3C_BUS) + { + if (ti3c_pp_min < ti3cl_od_min) + { + scllod = DIV_ROUND_CLOSEST(ti3cl_od_min, ti3cclk) - 1U; + + if (((scllod + 1U) * ti3cclk) < ti3cl_od_min) + { + scllod += 1U; + } + } + else + { + scllod = scllpp; + } + + /* Verify that SCL Open drain Low duration is superior as SDA rise time 70% */ + if (((scllod + 1U) * ti3cclk) < tcapa) + { + scllod = DIV_ROUND_CLOSEST(tcapa, ti3cclk) + 1U; + } + + sclhi2c = 0U; /* I2C SCL not used in pure I3C bus */ + } + /* SCL low level on mixed bus (open-drain) */ + /* I2C SCL high level (mixed bus with I2C) */ + else + { + scllod = DIV_ROUND_CLOSEST(DIV_ROUND_CLOSEST(ti2c_od_min * (100U - pInputTiming->dutyCycle), + ti3cclk), 100U) - 1U; + + /* Mix Bus Fast Mode plus */ + if (ti2c_od_min < tfm_min) + { + if (((scllod + 1U) * ti3cclk) < tfmpl_od_min) + { + scllod = DIV_ROUND_CLOSEST(tfmpl_od_min, ti3cclk) - 1U; + } + } + /* Mix Bus Fast Mode */ + else + { + if (((scllod + 1U) * ti3cclk) < tfml_od_min) + { + scllod = DIV_ROUND_CLOSEST(tfml_od_min, ti3cclk) - 1U; + } + } + + sclhi2c = DIV_ROUND_CLOSEST((ti2c_od_min - ((scllod + 1U) * ti3cclk)), ti3cclk) - 1U; + } + + /* Clock After Start computation */ + + /* I3C pure bus: (Tcas + tcapa)/2 */ + if (pInputTiming->busType == I3C_PURE_I3C_BUS) + { + free = DIV_ROUND_CLOSEST((ti3c_cas_min + tcapa), (2U * ti3cclk)) + 1U; + } + /* I3C, I2C mixed: (scllod + tcapa)/2 */ + else + { + free = DIV_ROUND_CLOSEST((((scllod + 1U) * ti3cclk) + tcapa), (2U * ti3cclk)); + } + + /* One cycle hold time addition */ + /* By default 1/2 cycle: must be > 3 ns */ + if (ti3cclk > 600U) + { + sdahold = 0U; + } + else + { + sdahold = 1U; + } + + /* 1 microsecond reference */ + oneus = DIV_ROUND_CLOSEST(100000U, ti3cclk) - 2U; + + if ((scllpp > 0xFFU) || (sclhi3c > 0xFFU) || (scllod > 0xFFU) || (sclhi2c > 0xFFU) || + (free > 0xFFU) || (oneus > 0xFFU)) + { + /* Case of value is over 8bits, issue may be due to clocksource have a rate too high for bus clock request */ + /* Update the return status */ + status = ERROR; + } + else + { + /* SCL configuration */ + pOutputConfig->SCLPPLowDuration = (uint8_t)scllpp; + pOutputConfig->SCLI3CHighDuration = (uint8_t)sclhi3c; + pOutputConfig->SCLODLowDuration = (uint8_t)scllod; + pOutputConfig->SCLI2CHighDuration = (uint8_t)sclhi2c; + + /* Free, Idle and SDA hold time configuration */ + pOutputConfig->BusFreeDuration = (uint8_t)free; + pOutputConfig->BusIdleDuration = (uint8_t)oneus; + pOutputConfig->SDAHoldTime = (uint32_t)(sdahold << I3C_TIMINGR1_SDA_HD_Pos); + } + } + + return status; +} + +/** + * @brief Calculate the I3C Controller timing according current I3C clock source and required I3C bus clock. + * @param pInputTiming : [IN] Pointer to an I3C_TgtTimingTypeDef structure that contains + * the required parameter for I3C timing computation. + * @param pOutputConfig : [OUT] Pointer to an LL_I3C_TgtBusConfTypeDef structure that contains + * the configuration information for the specified I3C. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: Timing calculation successfully + * - ERROR: Parameters or timing calculation error + */ +ErrorStatus I3C_TgtTimingComputation(const I3C_TgtTimingTypeDef *pInputTiming, + LL_I3C_TgtBusConfTypeDef *pOutputConfig) +{ + ErrorStatus status = SUCCESS; + uint32_t oneus; + uint32_t ti3cclk = 0U; + + /* Verify Parameters */ + if (pInputTiming->clockSrcFreq == 0U) + { + status = ERROR; + } + + if (status == SUCCESS) + { + /* Period Clock source */ + ti3cclk = (uint32_t)((SEC210PSEC + ((uint64_t)pInputTiming->clockSrcFreq / (uint64_t)2)) / + (uint64_t)pInputTiming->clockSrcFreq); + + /* Verify Parameters */ + if (ti3cclk == 0U) + { + status = ERROR; + } + } + + if ((status == SUCCESS) && (ti3cclk != 0U)) + { + /* 1 microsecond reference */ + oneus = DIV_ROUND_CLOSEST(100000U, ti3cclk) - 2U; + + /* Bus available time configuration */ + pOutputConfig->BusAvailableDuration = (uint8_t)oneus; + } + + return status; +} +/** + * @} + */ +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** + * @} + */ + +/** + * @} + */ diff --git a/bsp/stm32/stm32h563-st-nucleo/.config b/bsp/stm32/stm32h563-st-nucleo/.config new file mode 100644 index 0000000000..1f39f3173c --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/.config @@ -0,0 +1,713 @@ +# +# Automatically generated file; DO NOT EDIT. +# RT-Thread Configuration +# + +# +# RT-Thread Kernel +# +CONFIG_RT_NAME_MAX=8 +# CONFIG_RT_USING_ARCH_DATA_TYPE is not set +# CONFIG_RT_USING_SMART is not set +# CONFIG_RT_USING_AMP is not set +# CONFIG_RT_USING_SMP is not set +CONFIG_RT_ALIGN_SIZE=8 +# CONFIG_RT_THREAD_PRIORITY_8 is not set +CONFIG_RT_THREAD_PRIORITY_32=y +# CONFIG_RT_THREAD_PRIORITY_256 is not set +CONFIG_RT_THREAD_PRIORITY_MAX=32 +CONFIG_RT_TICK_PER_SECOND=1000 +CONFIG_RT_USING_OVERFLOW_CHECK=y +CONFIG_RT_USING_HOOK=y +CONFIG_RT_HOOK_USING_FUNC_PTR=y +CONFIG_RT_USING_IDLE_HOOK=y +CONFIG_RT_IDLE_HOOK_LIST_SIZE=4 +CONFIG_IDLE_THREAD_STACK_SIZE=256 +CONFIG_RT_USING_TIMER_SOFT=y +CONFIG_RT_TIMER_THREAD_PRIO=4 +CONFIG_RT_TIMER_THREAD_STACK_SIZE=512 + +# +# kservice optimization +# +# CONFIG_RT_KSERVICE_USING_STDLIB is not set +# CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set +# CONFIG_RT_USING_TINY_FFS is not set +# CONFIG_RT_KPRINTF_USING_LONGLONG is not set +CONFIG_RT_USING_DEBUG=y +CONFIG_RT_DEBUGING_COLOR=y +CONFIG_RT_DEBUGING_CONTEXT=y +CONFIG_RT_DEBUGING_INIT=y + +# +# Inter-Thread communication +# +CONFIG_RT_USING_SEMAPHORE=y +CONFIG_RT_USING_MUTEX=y +CONFIG_RT_USING_EVENT=y +CONFIG_RT_USING_MAILBOX=y +CONFIG_RT_USING_MESSAGEQUEUE=y +# CONFIG_RT_USING_MESSAGEQUEUE_PRIORITY is not set +# CONFIG_RT_USING_SIGNALS is not set + +# +# Memory Management +# +CONFIG_RT_USING_MEMPOOL=y +CONFIG_RT_USING_SMALL_MEM=y +# CONFIG_RT_USING_SLAB is not set +# CONFIG_RT_USING_MEMHEAP is not set +CONFIG_RT_USING_SMALL_MEM_AS_HEAP=y +# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set +# CONFIG_RT_USING_SLAB_AS_HEAP is not set +# CONFIG_RT_USING_USERHEAP is not set +# CONFIG_RT_USING_NOHEAP is not set +# CONFIG_RT_USING_MEMTRACE is not set +# CONFIG_RT_USING_HEAP_ISR is not set +CONFIG_RT_USING_HEAP=y + +# +# Kernel Device Object +# +CONFIG_RT_USING_DEVICE=y +# CONFIG_RT_USING_DEVICE_OPS is not set +# CONFIG_RT_USING_DM is not set +# CONFIG_RT_USING_INTERRUPT_INFO is not set +CONFIG_RT_USING_CONSOLE=y +CONFIG_RT_CONSOLEBUF_SIZE=256 +CONFIG_RT_CONSOLE_DEVICE_NAME="uart3" +CONFIG_RT_VER_NUM=0x50001 +# CONFIG_RT_USING_STDC_ATOMIC is not set +# CONFIG_RT_USING_CACHE is not set +CONFIG_RT_USING_HW_ATOMIC=y +# CONFIG_ARCH_ARM_BOOTWITH_FLUSH_CACHE is not set +# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set +CONFIG_RT_USING_CPU_FFS=y +CONFIG_ARCH_ARM=y +CONFIG_ARCH_ARM_CORTEX_M=y +CONFIG_ARCH_ARM_CORTEX_M33=y + +# +# RT-Thread Components +# +CONFIG_RT_USING_COMPONENTS_INIT=y +CONFIG_RT_USING_USER_MAIN=y +CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048 +CONFIG_RT_MAIN_THREAD_PRIORITY=10 +# CONFIG_RT_USING_LEGACY is not set +CONFIG_RT_USING_MSH=y +CONFIG_RT_USING_FINSH=y +CONFIG_FINSH_USING_MSH=y +CONFIG_FINSH_THREAD_NAME="tshell" +CONFIG_FINSH_THREAD_PRIORITY=20 +CONFIG_FINSH_THREAD_STACK_SIZE=4096 +CONFIG_FINSH_USING_HISTORY=y +CONFIG_FINSH_HISTORY_LINES=5 +CONFIG_FINSH_USING_SYMTAB=y +CONFIG_FINSH_CMD_SIZE=80 +CONFIG_MSH_USING_BUILT_IN_COMMANDS=y +CONFIG_FINSH_USING_DESCRIPTION=y +# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set +# CONFIG_FINSH_USING_AUTH is not set +CONFIG_FINSH_ARG_MAX=10 + +# +# DFS: device virtual file system +# +# CONFIG_RT_USING_DFS is not set +# CONFIG_RT_USING_FAL is not set + +# +# Device Drivers +# +CONFIG_RT_USING_DEVICE_IPC=y +CONFIG_RT_UNAMED_PIPE_NUMBER=64 +CONFIG_RT_USING_SYSTEM_WORKQUEUE=y +CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=2048 +CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23 +CONFIG_RT_USING_SERIAL=y +CONFIG_RT_USING_SERIAL_V1=y +# CONFIG_RT_USING_SERIAL_V2 is not set +# CONFIG_RT_SERIAL_USING_DMA is not set +CONFIG_RT_SERIAL_RB_BUFSZ=64 +# CONFIG_RT_USING_CAN is not set +# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_USING_CPUTIME is not set +CONFIG_RT_USING_I2C=y +# CONFIG_RT_I2C_DEBUG is not set +CONFIG_RT_USING_I2C_BITOPS=y +# CONFIG_RT_I2C_BITOPS_DEBUG is not set +# CONFIG_RT_USING_PHY is not set +CONFIG_RT_USING_PIN=y +CONFIG_RT_USING_ADC=y +# CONFIG_RT_USING_DAC is not set +# CONFIG_RT_USING_NULL is not set +# CONFIG_RT_USING_ZERO is not set +# CONFIG_RT_USING_RANDOM is not set +CONFIG_RT_USING_PWM=y +# CONFIG_RT_USING_MTD_NOR is not set +# CONFIG_RT_USING_MTD_NAND is not set +# CONFIG_RT_USING_PM is not set +# CONFIG_RT_USING_FDT is not set +# CONFIG_RT_USING_RTC is not set +# CONFIG_RT_USING_SDIO is not set +CONFIG_RT_USING_SPI=y +# CONFIG_RT_USING_SPI_BITOPS is not set +# CONFIG_RT_USING_QSPI is not set +# CONFIG_RT_USING_SPI_MSD is not set +# CONFIG_RT_USING_SFUD is not set +# CONFIG_RT_USING_ENC28J60 is not set +# CONFIG_RT_USING_SPI_WIFI is not set +# CONFIG_RT_USING_WDT is not set +# CONFIG_RT_USING_AUDIO is not set +# CONFIG_RT_USING_SENSOR is not set +# CONFIG_RT_USING_TOUCH is not set +# CONFIG_RT_USING_LCD is not set +# CONFIG_RT_USING_HWCRYPTO is not set +# CONFIG_RT_USING_PULSE_ENCODER is not set +# CONFIG_RT_USING_INPUT_CAPTURE is not set +# CONFIG_RT_USING_DEV_BUS is not set +# CONFIG_RT_USING_WIFI is not set +# CONFIG_RT_USING_VIRTIO is not set + +# +# Using USB +# +# CONFIG_RT_USING_USB is not set +# CONFIG_RT_USING_USB_HOST is not set +# CONFIG_RT_USING_USB_DEVICE is not set + +# +# C/C++ and POSIX layer +# + +# +# ISO-ANSI C layer +# + +# +# Timezone and Daylight Saving Time +# +# CONFIG_RT_LIBC_USING_FULL_TZ_DST is not set +CONFIG_RT_LIBC_USING_LIGHT_TZ_DST=y +CONFIG_RT_LIBC_TZ_DEFAULT_HOUR=8 +CONFIG_RT_LIBC_TZ_DEFAULT_MIN=0 +CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0 + +# +# POSIX (Portable Operating System Interface) layer +# +# CONFIG_RT_USING_POSIX_FS is not set +# CONFIG_RT_USING_POSIX_DELAY is not set +# CONFIG_RT_USING_POSIX_CLOCK is not set +# CONFIG_RT_USING_POSIX_TIMER is not set +# CONFIG_RT_USING_PTHREADS is not set +# CONFIG_RT_USING_MODULE is not set + +# +# Interprocess Communication (IPC) +# +# CONFIG_RT_USING_POSIX_PIPE is not set +# CONFIG_RT_USING_POSIX_MESSAGE_QUEUE is not set +# CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE is not set + +# +# Socket is in the 'Network' category +# +# CONFIG_RT_USING_CPLUSPLUS is not set + +# +# Network +# +# CONFIG_RT_USING_SAL is not set +# CONFIG_RT_USING_NETDEV is not set +# CONFIG_RT_USING_LWIP is not set +# CONFIG_RT_USING_AT is not set + +# +# Utilities +# +# CONFIG_RT_USING_RYM is not set +# CONFIG_RT_USING_ULOG is not set +# CONFIG_RT_USING_UTEST is not set +# CONFIG_RT_USING_VAR_EXPORT is not set +# CONFIG_RT_USING_RESOURCE_ID is not set +# CONFIG_RT_USING_ADT is not set +# CONFIG_RT_USING_RT_LINK is not set +# CONFIG_RT_USING_VBUS is not set +# CONFIG_RT_USING_KTIME is not set + +# +# RT-Thread Utestcases +# +# CONFIG_RT_USING_UTESTCASES is not set + +# +# RT-Thread online packages +# + +# +# IoT - internet of things +# +# CONFIG_PKG_USING_LWIP is not set +# CONFIG_PKG_USING_LORAWAN_DRIVER is not set +# CONFIG_PKG_USING_PAHOMQTT is not set +# CONFIG_PKG_USING_UMQTT is not set +# CONFIG_PKG_USING_WEBCLIENT is not set +# CONFIG_PKG_USING_WEBNET is not set +# CONFIG_PKG_USING_MONGOOSE is not set +# CONFIG_PKG_USING_MYMQTT is not set +# CONFIG_PKG_USING_KAWAII_MQTT is not set +# CONFIG_PKG_USING_BC28_MQTT is not set +# CONFIG_PKG_USING_WEBTERMINAL is not set +# CONFIG_PKG_USING_LIBMODBUS is not set +# CONFIG_PKG_USING_FREEMODBUS is not set +# CONFIG_PKG_USING_NANOPB is not set + +# +# Wi-Fi +# + +# +# Marvell WiFi +# +# CONFIG_PKG_USING_WLANMARVELL is not set + +# +# Wiced WiFi +# +# CONFIG_PKG_USING_WLAN_WICED is not set +# CONFIG_PKG_USING_RW007 is not set +# CONFIG_PKG_USING_COAP is not set +# CONFIG_PKG_USING_NOPOLL is not set +# CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_CMUX is not set +# CONFIG_PKG_USING_PPP_DEVICE is not set +# CONFIG_PKG_USING_AT_DEVICE is not set +# CONFIG_PKG_USING_ATSRV_SOCKET is not set +# CONFIG_PKG_USING_WIZNET is not set +# CONFIG_PKG_USING_ZB_COORDINATOR is not set + +# +# IoT Cloud +# +# CONFIG_PKG_USING_ONENET is not set +# CONFIG_PKG_USING_GAGENT_CLOUD is not set +# CONFIG_PKG_USING_ALI_IOTKIT is not set +# CONFIG_PKG_USING_AZURE is not set +# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set +# CONFIG_PKG_USING_JIOT-C-SDK is not set +# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set +# CONFIG_PKG_USING_JOYLINK is not set +# CONFIG_PKG_USING_EZ_IOT_OS is not set +# CONFIG_PKG_USING_IOTSHARP_SDK is not set +# CONFIG_PKG_USING_NIMBLE is not set +# CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER is not set +# CONFIG_PKG_USING_OTA_DOWNLOADER is not set +# CONFIG_PKG_USING_IPMSG is not set +# CONFIG_PKG_USING_LSSDP is not set +# CONFIG_PKG_USING_AIRKISS_OPEN is not set +# CONFIG_PKG_USING_LIBRWS is not set +# CONFIG_PKG_USING_TCPSERVER is not set +# CONFIG_PKG_USING_PROTOBUF_C is not set +# CONFIG_PKG_USING_DLT645 is not set +# CONFIG_PKG_USING_QXWZ is not set +# CONFIG_PKG_USING_SMTP_CLIENT is not set +# CONFIG_PKG_USING_ABUP_FOTA is not set +# CONFIG_PKG_USING_LIBCURL2RTT is not set +# CONFIG_PKG_USING_CAPNP is not set +# CONFIG_PKG_USING_AGILE_TELNET is not set +# CONFIG_PKG_USING_NMEALIB is not set +# CONFIG_PKG_USING_PDULIB is not set +# CONFIG_PKG_USING_BTSTACK is not set +# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set +# CONFIG_PKG_USING_WAYZ_IOTKIT is not set +# CONFIG_PKG_USING_MAVLINK is not set +# CONFIG_PKG_USING_BSAL is not set +# CONFIG_PKG_USING_AGILE_MODBUS is not set +# CONFIG_PKG_USING_AGILE_FTP is not set +# CONFIG_PKG_USING_EMBEDDEDPROTO is not set +# CONFIG_PKG_USING_RT_LINK_HW is not set +# CONFIG_PKG_USING_LORA_PKT_FWD is not set +# CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set +# CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set +# CONFIG_PKG_USING_HM is not set +# CONFIG_PKG_USING_SMALL_MODBUS is not set +# CONFIG_PKG_USING_NET_SERVER is not set +# CONFIG_PKG_USING_ZFTP is not set + +# +# security packages +# +# CONFIG_PKG_USING_MBEDTLS is not set +# CONFIG_PKG_USING_LIBSODIUM is not set +# CONFIG_PKG_USING_LIBHYDROGEN is not set +# CONFIG_PKG_USING_TINYCRYPT is not set +# CONFIG_PKG_USING_TFM is not set +# CONFIG_PKG_USING_YD_CRYPTO is not set + +# +# language packages +# + +# +# JSON: JavaScript Object Notation, a lightweight data-interchange format +# +# CONFIG_PKG_USING_CJSON is not set +# CONFIG_PKG_USING_LJSON is not set +# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set +# CONFIG_PKG_USING_RAPIDJSON is not set +# CONFIG_PKG_USING_JSMN is not set +# CONFIG_PKG_USING_AGILE_JSMN is not set +# CONFIG_PKG_USING_PARSON is not set + +# +# XML: Extensible Markup Language +# +# CONFIG_PKG_USING_SIMPLE_XML is not set +# CONFIG_PKG_USING_EZXML is not set +# CONFIG_PKG_USING_LUATOS_SOC is not set +# CONFIG_PKG_USING_LUA is not set +# CONFIG_PKG_USING_JERRYSCRIPT is not set +# CONFIG_PKG_USING_MICROPYTHON is not set +# CONFIG_PKG_USING_PIKASCRIPT is not set +# CONFIG_PKG_USING_RTT_RUST is not set + +# +# multimedia packages +# + +# +# LVGL: powerful and easy-to-use embedded GUI library +# +# CONFIG_PKG_USING_LVGL is not set +# CONFIG_PKG_USING_LITTLEVGL2RTT is not set +# CONFIG_PKG_USING_LV_MUSIC_DEMO is not set +# CONFIG_PKG_USING_GUI_GUIDER_DEMO is not set + +# +# u8g2: a monochrome graphic library +# +# CONFIG_PKG_USING_U8G2_OFFICIAL is not set +# CONFIG_PKG_USING_U8G2 is not set +# CONFIG_PKG_USING_OPENMV is not set +# CONFIG_PKG_USING_MUPDF is not set +# CONFIG_PKG_USING_STEMWIN is not set +# CONFIG_PKG_USING_WAVPLAYER is not set +# CONFIG_PKG_USING_TJPGD is not set +# CONFIG_PKG_USING_PDFGEN is not set +# CONFIG_PKG_USING_HELIX is not set +# CONFIG_PKG_USING_AZUREGUIX is not set +# CONFIG_PKG_USING_TOUCHGFX2RTT is not set +# CONFIG_PKG_USING_NUEMWIN is not set +# CONFIG_PKG_USING_MP3PLAYER is not set +# CONFIG_PKG_USING_TINYJPEG is not set +# CONFIG_PKG_USING_UGUI is not set + +# +# PainterEngine: A cross-platform graphics application framework written in C language +# +# CONFIG_PKG_USING_PAINTERENGINE is not set +# CONFIG_PKG_USING_PAINTERENGINE_AUX is not set +# CONFIG_PKG_USING_MCURSES is not set +# CONFIG_PKG_USING_TERMBOX is not set +# CONFIG_PKG_USING_VT100 is not set +# CONFIG_PKG_USING_QRCODE is not set +# CONFIG_PKG_USING_GUIENGINE is not set + +# +# tools packages +# +# CONFIG_PKG_USING_CMBACKTRACE is not set +# CONFIG_PKG_USING_EASYFLASH is not set +# CONFIG_PKG_USING_EASYLOGGER is not set +# CONFIG_PKG_USING_SYSTEMVIEW is not set +# CONFIG_PKG_USING_SEGGER_RTT is not set +# CONFIG_PKG_USING_RDB is not set +# CONFIG_PKG_USING_ULOG_EASYFLASH is not set +# CONFIG_PKG_USING_ULOG_FILE is not set +# CONFIG_PKG_USING_LOGMGR is not set +# CONFIG_PKG_USING_ADBD is not set +# CONFIG_PKG_USING_COREMARK is not set +# CONFIG_PKG_USING_DHRYSTONE is not set +# CONFIG_PKG_USING_MEMORYPERF is not set +# CONFIG_PKG_USING_NR_MICRO_SHELL is not set +# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set +# CONFIG_PKG_USING_LUNAR_CALENDAR is not set +# CONFIG_PKG_USING_BS8116A is not set +# CONFIG_PKG_USING_GPS_RMC is not set +# CONFIG_PKG_USING_URLENCODE is not set +# CONFIG_PKG_USING_UMCN is not set +# CONFIG_PKG_USING_LWRB2RTT is not set +# CONFIG_PKG_USING_CPU_USAGE is not set +# CONFIG_PKG_USING_GBK2UTF8 is not set +# CONFIG_PKG_USING_VCONSOLE is not set +# CONFIG_PKG_USING_KDB is not set +# CONFIG_PKG_USING_WAMR is not set +# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set +# CONFIG_PKG_USING_LWLOG is not set +# CONFIG_PKG_USING_ANV_TRACE is not set +# CONFIG_PKG_USING_ANV_MEMLEAK is not set +# CONFIG_PKG_USING_ANV_TESTSUIT is not set +# CONFIG_PKG_USING_ANV_BENCH is not set +# CONFIG_PKG_USING_DEVMEM is not set +# CONFIG_PKG_USING_REGEX is not set +# CONFIG_PKG_USING_MEM_SANDBOX is not set +# CONFIG_PKG_USING_SOLAR_TERMS is not set +# CONFIG_PKG_USING_GAN_ZHI is not set +# CONFIG_PKG_USING_FDT is not set +# CONFIG_PKG_USING_CBOX is not set +# CONFIG_PKG_USING_SNOWFLAKE is not set +# CONFIG_PKG_USING_HASH_MATCH is not set +# CONFIG_PKG_USING_FIRE_PID_CURVE is not set +# CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set + +# +# system packages +# + +# +# enhanced kernel services +# +# CONFIG_PKG_USING_RT_MEMCPY_CM is not set +# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set +# CONFIG_PKG_USING_RT_VSNPRINTF_FULL is not set + +# +# acceleration: Assembly language or algorithmic acceleration packages +# +# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set +# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set +# CONFIG_PKG_USING_QFPLIB_M3 is not set + +# +# CMSIS: ARM Cortex-M Microcontroller Software Interface Standard +# +# CONFIG_PKG_USING_CMSIS_5 is not set +# CONFIG_PKG_USING_CMSIS_RTOS1 is not set +# CONFIG_PKG_USING_CMSIS_RTOS2 is not set + +# +# Micrium: Micrium software products porting for RT-Thread +# +# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set +# CONFIG_PKG_USING_UCOSII_WRAPPER is not set +# CONFIG_PKG_USING_UC_CRC is not set +# CONFIG_PKG_USING_UC_CLK is not set +# CONFIG_PKG_USING_UC_COMMON is not set +# CONFIG_PKG_USING_UC_MODBUS is not set +# CONFIG_PKG_USING_RTDUINO is not set +# CONFIG_PKG_USING_CAIRO is not set +# CONFIG_PKG_USING_PIXMAN is not set +# CONFIG_PKG_USING_PARTITION is not set +# CONFIG_PKG_USING_PERF_COUNTER is not set +# CONFIG_PKG_USING_FLASHDB is not set +# CONFIG_PKG_USING_SQLITE is not set +# CONFIG_PKG_USING_RTI is not set +# CONFIG_PKG_USING_DFS_YAFFS is not set +# CONFIG_PKG_USING_LITTLEFS is not set +# CONFIG_PKG_USING_DFS_JFFS2 is not set +# CONFIG_PKG_USING_DFS_UFFS is not set +# CONFIG_PKG_USING_LWEXT4 is not set +# CONFIG_PKG_USING_THREAD_POOL is not set +# CONFIG_PKG_USING_ROBOTS is not set +# CONFIG_PKG_USING_EV is not set +# CONFIG_PKG_USING_SYSWATCH is not set +# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set +# CONFIG_PKG_USING_PLCCORE is not set +# CONFIG_PKG_USING_RAMDISK is not set +# CONFIG_PKG_USING_MININI is not set +# CONFIG_PKG_USING_QBOOT is not set +# CONFIG_PKG_USING_PPOOL is not set +# CONFIG_PKG_USING_OPENAMP is not set +# CONFIG_PKG_USING_LPM is not set +# CONFIG_PKG_USING_TLSF is not set +# CONFIG_PKG_USING_EVENT_RECORDER is not set +# CONFIG_PKG_USING_ARM_2D is not set +# CONFIG_PKG_USING_MCUBOOT is not set +# CONFIG_PKG_USING_TINYUSB is not set +# CONFIG_PKG_USING_CHERRYUSB is not set +# CONFIG_PKG_USING_KMULTI_RTIMER is not set +# CONFIG_PKG_USING_TFDB is not set +# CONFIG_PKG_USING_QPC is not set + +# +# peripheral libraries and drivers +# +# CONFIG_PKG_USING_SENSORS_DRIVERS is not set +# CONFIG_PKG_USING_REALTEK_AMEBA is not set +# CONFIG_PKG_USING_SHT2X is not set +# CONFIG_PKG_USING_SHT3X is not set +# CONFIG_PKG_USING_ADT74XX is not set +# CONFIG_PKG_USING_AS7341 is not set +# CONFIG_PKG_USING_STM32_SDIO is not set +# CONFIG_PKG_USING_RTT_ESP_IDF is not set +# CONFIG_PKG_USING_ICM20608 is not set +# CONFIG_PKG_USING_BUTTON is not set +# CONFIG_PKG_USING_PCF8574 is not set +# CONFIG_PKG_USING_SX12XX is not set +# CONFIG_PKG_USING_SIGNAL_LED is not set +# CONFIG_PKG_USING_LEDBLINK is not set +# CONFIG_PKG_USING_LITTLED is not set +# CONFIG_PKG_USING_LKDGUI is not set +# CONFIG_PKG_USING_NRF5X_SDK is not set +# CONFIG_PKG_USING_NRFX is not set +# CONFIG_PKG_USING_WM_LIBRARIES is not set +# CONFIG_PKG_USING_KENDRYTE_SDK is not set +# CONFIG_PKG_USING_INFRARED is not set +# CONFIG_PKG_USING_MULTI_INFRARED is not set +# CONFIG_PKG_USING_AGILE_BUTTON is not set +# CONFIG_PKG_USING_AGILE_LED is not set +# CONFIG_PKG_USING_AT24CXX is not set +# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set +# CONFIG_PKG_USING_AD7746 is not set +# CONFIG_PKG_USING_PCA9685 is not set +# CONFIG_PKG_USING_I2C_TOOLS is not set +# CONFIG_PKG_USING_NRF24L01 is not set +# CONFIG_PKG_USING_TOUCH_DRIVERS is not set +# CONFIG_PKG_USING_MAX17048 is not set +# CONFIG_PKG_USING_RPLIDAR is not set +# CONFIG_PKG_USING_AS608 is not set +# CONFIG_PKG_USING_RC522 is not set +# CONFIG_PKG_USING_WS2812B is not set +# CONFIG_PKG_USING_EMBARC_BSP is not set +# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set +# CONFIG_PKG_USING_MULTI_RTIMER is not set +# CONFIG_PKG_USING_MAX7219 is not set +# CONFIG_PKG_USING_BEEP is not set +# CONFIG_PKG_USING_EASYBLINK is not set +# CONFIG_PKG_USING_PMS_SERIES is not set +# CONFIG_PKG_USING_CAN_YMODEM is not set +# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set +# CONFIG_PKG_USING_QLED is not set +# CONFIG_PKG_USING_PAJ7620 is not set +# CONFIG_PKG_USING_AGILE_CONSOLE is not set +# CONFIG_PKG_USING_LD3320 is not set +# CONFIG_PKG_USING_WK2124 is not set +# CONFIG_PKG_USING_LY68L6400 is not set +# CONFIG_PKG_USING_DM9051 is not set +# CONFIG_PKG_USING_SSD1306 is not set +# CONFIG_PKG_USING_QKEY is not set +# CONFIG_PKG_USING_RS485 is not set +# CONFIG_PKG_USING_RS232 is not set +# CONFIG_PKG_USING_NES is not set +# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set +# CONFIG_PKG_USING_VDEVICE is not set +# CONFIG_PKG_USING_SGM706 is not set +# CONFIG_PKG_USING_STM32WB55_SDK is not set +# CONFIG_PKG_USING_RDA58XX is not set +# CONFIG_PKG_USING_LIBNFC is not set +# CONFIG_PKG_USING_MFOC is not set +# CONFIG_PKG_USING_TMC51XX is not set +# CONFIG_PKG_USING_TCA9534 is not set +# CONFIG_PKG_USING_KOBUKI is not set +# CONFIG_PKG_USING_ROSSERIAL is not set +# CONFIG_PKG_USING_MICRO_ROS is not set +# CONFIG_PKG_USING_MCP23008 is not set +# CONFIG_PKG_USING_BLUETRUM_SDK is not set +# CONFIG_PKG_USING_MISAKA_AT24CXX is not set +# CONFIG_PKG_USING_MISAKA_RGB_BLING is not set +# CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set +# CONFIG_PKG_USING_BL_MCU_SDK is not set +# CONFIG_PKG_USING_SOFT_SERIAL is not set +# CONFIG_PKG_USING_MB85RS16 is not set +# CONFIG_PKG_USING_CW2015 is not set +# CONFIG_PKG_USING_RFM300 is not set +# CONFIG_PKG_USING_IO_INPUT_FILTER is not set + +# +# AI packages +# +# CONFIG_PKG_USING_LIBANN is not set +# CONFIG_PKG_USING_NNOM is not set +# CONFIG_PKG_USING_ONNX_BACKEND is not set +# CONFIG_PKG_USING_ONNX_PARSER is not set +# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set +# CONFIG_PKG_USING_ELAPACK is not set +# CONFIG_PKG_USING_ULAPACK is not set +# CONFIG_PKG_USING_QUEST is not set +# CONFIG_PKG_USING_NAXOS is not set + +# +# miscellaneous packages +# + +# +# project laboratory +# + +# +# samples: kernel and components samples +# +# CONFIG_PKG_USING_KERNEL_SAMPLES is not set +# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set +# CONFIG_PKG_USING_NETWORK_SAMPLES is not set +# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set + +# +# entertainment: terminal games and other interesting software packages +# +# CONFIG_PKG_USING_CMATRIX is not set +# CONFIG_PKG_USING_SL is not set +# CONFIG_PKG_USING_CAL is not set +# CONFIG_PKG_USING_ACLOCK is not set +# CONFIG_PKG_USING_THREES is not set +# CONFIG_PKG_USING_2048 is not set +# CONFIG_PKG_USING_SNAKE is not set +# CONFIG_PKG_USING_TETRIS is not set +# CONFIG_PKG_USING_DONUT is not set +# CONFIG_PKG_USING_COWSAY is not set +# CONFIG_PKG_USING_LIBCSV is not set +# CONFIG_PKG_USING_OPTPARSE is not set +# CONFIG_PKG_USING_FASTLZ is not set +# CONFIG_PKG_USING_MINILZO is not set +# CONFIG_PKG_USING_QUICKLZ is not set +# CONFIG_PKG_USING_LZMA is not set +# CONFIG_PKG_USING_MULTIBUTTON is not set +# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set +# CONFIG_PKG_USING_CANFESTIVAL is not set +# CONFIG_PKG_USING_ZLIB is not set +# CONFIG_PKG_USING_MINIZIP is not set +# CONFIG_PKG_USING_HEATSHRINK is not set +# CONFIG_PKG_USING_DSTR is not set +# CONFIG_PKG_USING_TINYFRAME is not set +# CONFIG_PKG_USING_KENDRYTE_DEMO is not set +# CONFIG_PKG_USING_DIGITALCTRL is not set +# CONFIG_PKG_USING_UPACKER is not set +# CONFIG_PKG_USING_UPARAM is not set +# CONFIG_PKG_USING_HELLO is not set +# CONFIG_PKG_USING_VI is not set +# CONFIG_PKG_USING_KI is not set +# CONFIG_PKG_USING_ARMv7M_DWT is not set +# CONFIG_PKG_USING_UKAL is not set +# CONFIG_PKG_USING_CRCLIB is not set +# CONFIG_PKG_USING_LWGPS is not set +# CONFIG_PKG_USING_STATE_MACHINE is not set +# CONFIG_PKG_USING_DESIGN_PATTERN is not set +# CONFIG_PKG_USING_CONTROLLER is not set +# CONFIG_PKG_USING_PHASE_LOCKED_LOOP is not set +# CONFIG_PKG_USING_MFBD is not set +# CONFIG_PKG_USING_SLCAN2RTT is not set +# CONFIG_PKG_USING_SOEM is not set +CONFIG_SOC_FAMILY_STM32=y +CONFIG_SOC_SERIES_STM32H5=y + +# +# Hardware Drivers Config +# +CONFIG_SOC_STM32H563ZI=y + +# +# On-chip Peripheral Drivers +# +CONFIG_BSP_USING_GPIO=y +CONFIG_BSP_USING_UART=y +# CONFIG_BSP_USING_UART1 is not set +# CONFIG_BSP_USING_UART2 is not set +CONFIG_BSP_USING_UART3=y +# CONFIG_BSP_USING_LPUART1 is not set +# CONFIG_BSP_USING_UDID is not set + +# +# Board extended module Drivers +# diff --git a/bsp/stm32/stm32h563-st-nucleo/.gitignore b/bsp/stm32/stm32h563-st-nucleo/.gitignore new file mode 100644 index 0000000000..7221bde019 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/.gitignore @@ -0,0 +1,42 @@ +*.pyc +*.map +*.dblite +*.elf +*.bin +*.hex +*.axf +*.exe +*.pdb +*.idb +*.ilk +*.old +build +Debug +documentation/html +packages/ +*~ +*.o +*.obj +*.out +*.bak +*.dep +*.lib +*.i +*.d +.DS_Stor* +.config 3 +.config 4 +.config 5 +Midea-X1 +*.uimg +GPATH +GRTAGS +GTAGS +.vscode +JLinkLog.txt +JLinkSettings.ini +DebugConfig/ +RTE/ +settings/ +*.uvguix* +cconfig.h diff --git a/bsp/stm32/stm32h563-st-nucleo/EventRecorderStub.scvd b/bsp/stm32/stm32h563-st-nucleo/EventRecorderStub.scvd new file mode 100644 index 0000000000..2956b29683 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/EventRecorderStub.scvd @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/bsp/stm32/stm32h563-st-nucleo/Kconfig b/bsp/stm32/stm32h563-st-nucleo/Kconfig new file mode 100644 index 0000000000..79b160b856 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/Kconfig @@ -0,0 +1,21 @@ +mainmenu "RT-Thread Configuration" + +config BSP_DIR + string + option env="BSP_ROOT" + default "." + +config RTT_DIR + string + option env="RTT_ROOT" + default "../../.." + +config PKGS_DIR + string + option env="PKGS_ROOT" + default "packages" + +source "$RTT_DIR/Kconfig" +source "$PKGS_DIR/Kconfig" +source "../libraries/Kconfig" +source "board/Kconfig" diff --git a/bsp/stm32/stm32h563-st-nucleo/README.md b/bsp/stm32/stm32h563-st-nucleo/README.md new file mode 100644 index 0000000000..d026d71b2a --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/README.md @@ -0,0 +1,135 @@ +# **NUCLEO-H563ZI** 开发板 BSP 说明 + +## 简介 + +本文档为 yuanzihao为 NUCLEO-STM32H563ZIT6 开发板提供的 BSP (板级支持包) 说明。 + +主要内容如下: + +- 开发板资源介绍 +- BSP 快速上手 +- 注意事项及参考资料 + +通过阅读快速上手章节开发者可以快速地上手该 BSP,将 RT-Thread 运行在开发板上。 + +## 开发板介绍 + +NUCLEO-STM32H563ZIT6是 ST 推出的一款基于 ARM Cortex-M33 内核的开发板,最高主频为 250Mhz,2 MB Flash,640 KB RAM,该开发板具有丰富的板载资源,可以充分发挥 STM32H563ZIT6的芯片性能。 + +开发板外观如下图所示(板载TYPE-C接口的STLINK-V3哦): + +![board](figures/board.png) + +该开发板常用 **板载资源** 如下: + +- MCU:STM32H563ZI,高性能,Arm Cortex-M33带有TrustZone,MCU带有2 MB Flash,640 KB RAM,250 MHz CPU,375 DMIPS (Dhrystone 2.1) +- 通用特性 + - 采用LQFP144封装的STM32 微控制器 + - 3个用户LED + - 2个用户按钮和复位按钮 + - 32.768 kHz晶体振荡器 + - 板连接器:SWDST Zio扩展连接器,包括ARDUINO® Uno V3ST morpho扩展连接器 + - 灵活的供电选项:ST-LINK、USB VBUS或外部电源 + - 具有USB重新枚举功能的板上ST-LINK调试器/编程器:大容量存储器、虚拟COM端口和调试端口 + - 提供了全面的免费软件库和例程,可从STM32Cube MCU软件包获得 + - 支持多种集成开发环境(IDE),包括IAR™、Keil®、和STM32CubeIDE + +开发板更多详细信息请参考 ST [STM32H563ZI]([STM32H563ZI - 高性能,Arm Cortex-M33带有TrustZone,MCU带有2 MB Flash,640 KB RAM,250 MHz CPU - 意法半导体STMicroelectronics](https://www.st.com/zh/microcontrollers-microprocessors/stm32h563zi.html))。 + +硬件框图如下: + +![hardware_block_diagram](figures/hardware_block_diagram.png) + +## 外设支持 + +本 BSP 目前对外设的支持情况如下: + +| **板载外设** | **支持情况** | **备注** | +| :------------------------------- | :----------: | :------- | +| USB 转 串口(板载**STLINK-V3EC**) | 支持 | | +| **片上外设** | **支持情况** | **备注** | +| GPIO | 支持 | | +| UART | 支持 | UART3 | + + +## 使用说明 + +使用说明分为如下两个章节: + +- 快速上手 + + 本章节是为刚接触 RT-Thread 的新手准备的使用说明,遵循简单的步骤即可将 RT-Thread 操作系统运行在该开发板上,看到实验效果 。 + +- 进阶使用 + + 本章节是为需要在 RT-Thread 操作系统上使用更多开发板资源的开发者准备的。通过使用 ENV 工具对 BSP 进行配置,可以开启更多板载资源,实现更多高级功能。 + + +### 快速上手 + +本 BSP 为开发者提供 MDK5 和 IAR 工程,并且支持 GCC 开发环境。下面以 MDK5 开发环境为例,介绍如何将系统运行起来。 + +#### 硬件连接 + +使用Type-C数据线连接开发板到 PC。 + +#### 编译下载 + +双击 project.uvprojx 文件,打开 MDK5 工程,编译并下载程序到开发板。 + +> 工程默认配置使用 ST_LINK 仿真器下载程序,在通过 ST_LINK 连接开发板的基础上,点击下载按钮即可下载程序到开发板 + +#### 运行结果 + +下载程序成功之后,系统会自动运行,LED1闪烁。 + +连接开发板对应串口到 PC , 在终端工具里打开相应的串口(115200-8-1-N),复位设备后,可以看到 RT-Thread 的输出信息: + +```bash + \ | / +- RT - Thread Operating System + / | \ 5.0.1 build Aug 27 2023 20:47:55 + 2006 - 2022 Copyright by RT-Thread team +do components initialization. +initialize rti_board_end:0 done +initialize rt_work_sys_workqueue_init:0 done +initialize finsh_system_init:0 done +msh > +``` + +### 进阶使用 + +此 BSP 默认只开启了 GPIO 和 UART1 的功能,如果需使用更多高级功能,需要利用 ENV 工具对BSP 进行配置,步骤如下: + +1. 在 bsp 下打开 env 工具。 + +2. 输入`menuconfig`命令配置工程,配置好之后保存退出。 + +3. 输入`pkgs --update`命令更新软件包。 + +4. 输入`scons --target=mdk4/mdk5/iar` 命令重新生成工程。 + +本章节更多详细的介绍请参考 [STM32 系列 BSP 外设驱动使用教程](../docs/STM32系列BSP外设驱动使用教程.md)。 + +## 注意事项 + +- 调试串口为 UART3 ,映射说明(详情看STM32Cubemx中的配置): + + ```c + PD8 ------> USART3_TX(T_VCP_TX) + PD9 ------> USART3_RX(T_VCP_RX) + ``` + +* MDK版本最好使用比较新的版本的,本次搭建是在MDK5.36版本下进行的。 + +## 参考资料: + +1. [STM32H563-NUCLEO原理图下载](https://www.st.com/resource/en/schematic_pack/mb1404-h563zi-c01-schematic.pdf) +2. [STM32H563官方介绍页](https://www.st.com/en/microcontrollers-microprocessors/stm32h563zi.html) +3. [STM32H563-NUCLEO开发板手册](https://www.st.com/resource/en/user_manual/um3115-stm32h5-nucleo144-board-mb1404-stmicroelectronics.pdf) + +## 联系人信息 + +维护人: + +- [yuanzihao](https://github.com/zihao-yuan/), 邮箱:[y@yzh.email](mailto:y@yzh.email) diff --git a/bsp/stm32/stm32h563-st-nucleo/SConscript b/bsp/stm32/stm32h563-st-nucleo/SConscript new file mode 100644 index 0000000000..20f7689c53 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/SConscript @@ -0,0 +1,15 @@ +# for module compiling +import os +Import('RTT_ROOT') +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/bsp/stm32/stm32h563-st-nucleo/SConstruct b/bsp/stm32/stm32h563-st-nucleo/SConstruct new file mode 100644 index 0000000000..a96d69cbe1 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/SConstruct @@ -0,0 +1,59 @@ +import os +import sys +import rtconfig + +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') +else: + RTT_ROOT = os.path.normpath(os.getcwd() + '/../../..') + +sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] +try: + from building import * +except: + print('Cannot found RT-Thread root directory, please check RTT_ROOT') + print(RTT_ROOT) + exit(-1) + +TARGET = 'rt-thread.' + rtconfig.TARGET_EXT + +DefaultEnvironment(tools=[]) +env = Environment(tools = ['mingw'], + AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, + CC = rtconfig.CC, CFLAGS = rtconfig.CFLAGS, + AR = rtconfig.AR, ARFLAGS = '-rc', + CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS, + LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) +env.PrependENVPath('PATH', rtconfig.EXEC_PATH) + +if rtconfig.PLATFORM in ['iccarm']: + env.Replace(CCCOM = ['$CC $CFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -o $TARGET $SOURCES']) + env.Replace(ARFLAGS = ['']) + env.Replace(LINKCOM = env["LINKCOM"] + ' --map rt-thread.map') + +Export('RTT_ROOT') +Export('rtconfig') + +SDK_ROOT = os.path.abspath('./') + +if os.path.exists(SDK_ROOT + '/libraries'): + libraries_path_prefix = SDK_ROOT + '/libraries' +else: + libraries_path_prefix = os.path.dirname(SDK_ROOT) + '/libraries' + +SDK_LIB = libraries_path_prefix +Export('SDK_LIB') + +# prepare building environment +objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False) + +stm32_library = 'STM32H5xx_HAL' +rtconfig.BSP_LIBRARY_TYPE = stm32_library + +# include libraries +objs.extend(SConscript(os.path.join(libraries_path_prefix, stm32_library, 'SConscript'), variant_dir='build/libraries/'+stm32_library, duplicate=0)) +# include drivers +objs.extend(SConscript(os.path.join(libraries_path_prefix, 'HAL_Drivers', 'SConscript'),variant_dir='build/libraries/'+'HAL_Drivers', duplicate=0)) + +# make a building +DoBuilding(TARGET, objs) diff --git a/bsp/stm32/stm32h563-st-nucleo/applications/SConscript b/bsp/stm32/stm32h563-st-nucleo/applications/SConscript new file mode 100644 index 0000000000..e1c7fa5996 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/applications/SConscript @@ -0,0 +1,18 @@ +from building import * +import os + +cwd = GetCurrentDir() +CPPPATH = [cwd] +src = Glob('*.c') + +if GetDepend(['PKG_USING_RTDUINO']) and not GetDepend(['RTDUINO_NO_SETUP_LOOP']): + src += ['arduino_main.cpp'] + +group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) + +list = os.listdir(cwd) +for item in list: + if os.path.isfile(os.path.join(cwd, item, 'SConscript')): + group = group + SConscript(os.path.join(item, 'SConscript')) + +Return('group') diff --git a/bsp/stm32/stm32h563-st-nucleo/applications/arduino_main.cpp b/bsp/stm32/stm32h563-st-nucleo/applications/arduino_main.cpp new file mode 100644 index 0000000000..5b49a16169 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/applications/arduino_main.cpp @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-04-13 songw4232 first version + */ + +#include + +void setup(void) +{ + /* put your setup code here, to run once: */ + Serial.begin(); +} + +void loop(void) +{ + /* put your main code here, to run repeatedly: */ + Serial.println("Hello Arduino!"); + delay(800); +} diff --git a/bsp/stm32/stm32h563-st-nucleo/applications/arduino_pinout/README.md b/bsp/stm32/stm32h563-st-nucleo/applications/arduino_pinout/README.md new file mode 100644 index 0000000000..d9ce48cf0c --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/applications/arduino_pinout/README.md @@ -0,0 +1,51 @@ +# STM32U575-NUCLEO开发板的Arduino生态兼容说明 + +## 1 RTduino - RT-Thread的Arduino生态兼容层 + +STM32U575-NUCLEO开发板已经完整适配了[RTduino软件包](https://github.com/RTduino/RTduino),即RT-Thread的Arduino生态兼容层。用户可以按照Arduino的编程习惯来操作该BSP,并且可以使用大量Arduino社区丰富的库,是对RT-Thread生态的极大增强。更多信息,请参见[RTduino软件包说明文档](https://github.com/RTduino/RTduino)。 + +### 1.1 如何开启针对本BSP的Arduino生态兼容层 + +Env 工具下敲入 menuconfig 命令,或者 RT-Thread Studio IDE 下选择 RT-Thread Settings: + +```Kconfig +Hardware Drivers Config ---> + Onboard Peripheral Drivers ---> + [*] Compatible with Arduino Ecosystem (RTduino) +``` + +## 2 Arduino引脚排布 + +该BSP遵照Arduino UNO板的引脚排列方式,并扩展增加了STM32U575-NUCLEO自身的板载资源功能引脚。详见 `pins_arduino.c` + +更多引脚布局相关信息参见 [pins_arduino.c](pins_arduino.c) 和 [pins_arduino.h](pins_arduino.h)。 + +| Arduino引脚编号 | STM32引脚编号 | 5V容忍 | 备注 | +| --------------------- | --------- | ------- | -------------------------------------------- | +| 0 (D0) | PG8 | 是 | Serial-Rx,被RT-Thread的UART设备框架uart1接管 | +| 1 (D1) | PG7 | 是 | Serial-Tx,被RT-Thread的UART设备框架uart1接管 | +| 2 (D2) | PF15 | 是 | 普通IO | +| 3 (D3) | PE13 | 是 | PWM1-CH2,默认被RT-Thread的PWM设备框架pwm1接管 | +| 4 (D4) | PF14 | 是 | 普通IO | +| 5 (D5) | PE11 | 是 | PWM1-CH3,默认被RT-Thread的PWM设备框架pwm1接管 | +| 6 (D6) | PE9 | 是 | PWM1-CH1,默认被RT-Thread的PWM设备框架pwm1接管 | +| 7 (D7) | PF13 | 是 | 普通IO | +| 8 (D8) | PF12 | 是 | 普通IO | +| 9 (D9) | PD15 | 是 | PWM4-CH4,默认被RT-Thread的PWM设备框架pwm4接管 | +| 10 (D10) | PD14 | 是 | SPI1 片选 CS | +| 11 (D11) | PA7 | 是 | SPI1-MOSI,默认被RT-Thread的SPI设备框架spi1总线接管 | +| 12 (D12) | PA6 | 是 | SPI1-MISO,默认被RT-Thread的SPI设备框架spi1总线接管 | +| 13 (D13) | PA5 | 是 | SPI1-SCK,默认被RT-Thread的SPI设备框架spi1总线接管 | +| 14 (D14) | PB9 | 是 | I2C1-SDA,默认被RT-Thread的I2C设备框架i2c1总线接管 | +| 15 (D15) | PB8 | 是 | I2C1-SCL,默认被RT-Thread的I2C设备框架i2c1总线接管 | +| A0 | PA3 | 是(但不建议) | ADC1-CH8,默认被RT-Thread的ADC设备框架adc1接管 | +| A1 | PA2 | 是(但不建议) | ADC1-CH7,默认被RT-Thread的ADC设备框架adc1接管 | +| A2 | PC3 | 是(但不建议) | ADC1-CH4,默认被RT-Thread的ADC设备框架adc1接管 | +| A3 | PB0 | 是(但不建议) | ADC1-CH15,默认被RT-Thread的ADC设备框架adc1接管| +| A4 | PC1 | 是(但不建议) | ADC1-CH2,默认被RT-Thread的ADC设备框架adc1接管 | +| A5 | PC0 | 是(但不建议) | ADC1-CH1,默认被RT-Thread的ADC设备框架adc1接管 | + + +> 注意: +> +> 1. 暂无 diff --git a/bsp/stm32/stm32h563-st-nucleo/applications/arduino_pinout/SConscript b/bsp/stm32/stm32h563-st-nucleo/applications/arduino_pinout/SConscript new file mode 100644 index 0000000000..2539929027 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/applications/arduino_pinout/SConscript @@ -0,0 +1,9 @@ +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +inc = [cwd] + +group = DefineGroup('RTduino', src, depend = ['PKG_USING_RTDUINO'], CPPPATH = inc) + +Return('group') diff --git a/bsp/stm32/stm32h563-st-nucleo/applications/arduino_pinout/pins_arduino.c b/bsp/stm32/stm32h563-st-nucleo/applications/arduino_pinout/pins_arduino.c new file mode 100644 index 0000000000..cdb3cc9abb --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/applications/arduino_pinout/pins_arduino.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-04-13 songw4232 first version + */ + +#include +#include +#include "pins_arduino.h" + +/* + * {Arduino Pin, RT-Thread Pin [, Device Name, Channel]} + * [] means optional + * Digital pins must NOT give the device name and channel. + * Analog pins MUST give the device name and channel(ADC, PWM or DAC). + * Arduino Pin must keep in sequence. + */ +const pin_map_t pin_map_table[]= +{ + {D0, GET_PIN(G,8), "uart1"}, /* Serial-RX */ + {D1, GET_PIN(G,7), "uart1"}, /* Serial-TX */ + {D2, GET_PIN(F,15)}, + {D3, GET_PIN(E,13), "pwm1", 3}, /* PWM */ + {D4, GET_PIN(F,14)}, + {D5, GET_PIN(E,11), "pwm1", 2}, /* PWM */ + {D6, GET_PIN(E,9), "pwm1", 1}, /* PWM */ + {D7, GET_PIN(F,13)}, + {D8, GET_PIN(F,12)}, + {D9, GET_PIN(D,15), "pwm4", 4}, /* PWM */ + {D10, GET_PIN(D,14)}, + {D11, GET_PIN(A,7), "spi1"}, /* SPI-MOSI */ + {D12, GET_PIN(A,6), "spi1"}, /* SPI-MISO */ + {D13, GET_PIN(A,5), "spi1"}, /* SPI-SCK */ + {D14, GET_PIN(B,9), "i2c1"}, /* I2C-SDA (Wire) */ + {D15, GET_PIN(B,8), "i2c1"}, /* I2C-SCL (Wire) */ + {A0, GET_PIN(A,3), "adc1", 8}, /* ADC, On-Chip: internal reference voltage, ADC_CHANNEL_VREFINT */ + {A1, GET_PIN(A,2), "adc1", 7}, /* ADC, On-Chip: internal reference voltage, ADC_CHANNEL_VREFINT */ + {A2, GET_PIN(C,3), "adc1", 4}, /* ADC, On-Chip: internal reference voltage, ADC_CHANNEL_VREFINT */ + {A3, GET_PIN(B,0), "adc1", 15}, /* ADC, On-Chip: internal reference voltage, ADC_CHANNEL_VREFINT */ + {A4, GET_PIN(C,1), "adc1", 2}, /* ADC, On-Chip: internal reference voltage, ADC_CHANNEL_VREFINT */ + {A5, GET_PIN(C,0), "adc1", 1}, /* ADC, On-Chip: internal reference voltage, ADC_CHANNEL_VREFINT */ +}; diff --git a/bsp/stm32/stm32h563-st-nucleo/applications/arduino_pinout/pins_arduino.h b/bsp/stm32/stm32h563-st-nucleo/applications/arduino_pinout/pins_arduino.h new file mode 100644 index 0000000000..3b91474eb8 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/applications/arduino_pinout/pins_arduino.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-04-13 songw4232 first version + */ + +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +/* pins alias. Must keep in sequence */ +#define D0 (0) +#define D1 (1) +#define D2 (2) +#define D3 (3) +#define D4 (4) +#define D5 (5) +#define D6 (6) +#define D7 (7) +#define D8 (8) +#define D9 (9) +#define D10 (10) +#define D11 (11) +#define D12 (12) +#define D13 (13) +#define D14 (14) +#define D15 (15) +#define A0 (16) +#define A1 (17) +#define A2 (18) +#define A3 (19) +#define A4 (20) +#define A5 (21) + +#define F_CPU 160000000L /* CPU:160MHz */ + +/* i2c1 : PB9-SDA PB8-SCL */ +#define RTDUINO_DEFAULT_IIC_BUS_NAME "i2c1" + +/* spi1 : PA5-SCK PA6-MISO PA7-MOSI */ +#define RTDUINO_DEFAULT_SPI_BUS_NAME "spi1" + +#endif /* Pins_Arduino_h */ diff --git a/bsp/stm32/stm32h563-st-nucleo/applications/main.c b/bsp/stm32/stm32h563-st-nucleo/applications/main.c new file mode 100644 index 0000000000..645a086afc --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/applications/main.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-11-06 SummerGift first version + */ + +#include +#include +#include + +/* defined the LED1 pin: PB0 */ +#define LED1_PIN GET_PIN(B, 0) + +int main(void) +{ + int count = 1; + /* set LED0 pin mode to output */ + rt_pin_mode(LED1_PIN, PIN_MODE_OUTPUT); + + while (count++) + { + rt_pin_write(LED1_PIN, PIN_HIGH); + rt_thread_mdelay(500); + rt_pin_write(LED1_PIN, PIN_LOW); + rt_thread_mdelay(500); + } + + return RT_EOK; +} diff --git a/bsp/stm32/stm32h563-st-nucleo/board/.ignore_format.yml b/bsp/stm32/stm32h563-st-nucleo/board/.ignore_format.yml new file mode 100644 index 0000000000..4e3e46a59e --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/board/.ignore_format.yml @@ -0,0 +1,7 @@ +# files format check exclude path, please follow the instructions below to modify; +# If you need to exclude an entire folder, add the folder path in dir_path; +# If you need to exclude a file, add the path to the file in file_path. + +dir_path: +- CubeMX_Config +- linker_scripts diff --git a/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/.mxproject b/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/.mxproject new file mode 100644 index 0000000000..5f19705715 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/.mxproject @@ -0,0 +1,26 @@ +[PreviousGenFiles] +AdvancedFolderStructure=true +HeaderFileListSize=4 +HeaderFiles#0=..\Core\Inc\stm32h5xx_it.h +HeaderFiles#1=..\Core\Inc\stm32_assert.h +HeaderFiles#2=..\Core\Inc\stm32h5xx_hal_conf.h +HeaderFiles#3=..\Core\Inc\main.h +HeaderFolderListSize=1 +HeaderPath#0=..\Core\Inc +HeaderFiles=; +SourceFileListSize=3 +SourceFiles#0=..\Core\Src\stm32h5xx_it.c +SourceFiles#1=..\Core\Src\stm32h5xx_hal_msp.c +SourceFiles#2=..\Core\Src\main.c +SourceFolderListSize=1 +SourcePath#0=..\Core\Src +SourceFiles=; + +[PreviousLibFiles] +LibFiles=Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_adc.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_adc_ex.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_ll_adc.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_dma.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_dma_ex.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_rcc.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_rcc_ex.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_ll_bus.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_ll_rcc.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_ll_crs.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_ll_system.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_ll_utils.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_flash.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_flash_ex.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_gpio.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_gpio_ex.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_ll_gpio.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_ll_dma.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_ll_dmamux.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_pwr.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_pwr_ex.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_ll_pwr.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_cortex.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_ll_cortex.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_def.h;Drivers\STM32H5xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_exti.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_ll_exti.h;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_ll_utils.c;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_ll_exti.c;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_eth.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_eth_ex.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_icache.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_uart.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_uart_ex.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_ll_ucpd.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_pcd.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_pcd_ex.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_ll_usb.h;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_adc.c;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_adc_ex.c;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_dma.c;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_dma_ex.c;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_rcc.c;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_rcc_ex.c;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_flash.c;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_flash_ex.c;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_gpio.c;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_pwr.c;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_pwr_ex.c;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_cortex.c;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal.c;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_exti.c;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_ll_rcc.c;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_eth.c;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_eth_ex.c;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_icache.c;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_uart.c;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_uart_ex.c;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_ll_ucpd.c;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_ll_gpio.c;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_ll_exti.c;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_ll_dma.c;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_pcd.c;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_pcd_ex.c;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_ll_usb.c;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_adc.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_adc_ex.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_ll_adc.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_dma.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_dma_ex.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_rcc.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_rcc_ex.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_ll_bus.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_ll_rcc.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_ll_crs.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_ll_system.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_ll_utils.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_flash.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_flash_ex.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_gpio.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_gpio_ex.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_ll_gpio.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_ll_dma.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_ll_dmamux.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_pwr.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_pwr_ex.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_ll_pwr.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_cortex.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_ll_cortex.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_def.h;Drivers\STM32H5xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_exti.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_ll_exti.h;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_ll_utils.c;Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_ll_exti.c;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_eth.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_eth_ex.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_icache.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_uart.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_uart_ex.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_ll_ucpd.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_pcd.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_hal_pcd_ex.h;Drivers\STM32H5xx_HAL_Driver\Inc\stm32h5xx_ll_usb.h;Drivers\CMSIS\Device\ST\STM32H5xx\Include\stm32h563xx.h;Drivers\CMSIS\Device\ST\STM32H5xx\Include\stm32h5xx.h;Drivers\CMSIS\Device\ST\STM32H5xx\Include\system_stm32h5xx.h;Drivers\CMSIS\Device\ST\STM32H5xx\Source\Templates\system_stm32h5xx.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=..\Core\Src\main.c;..\Core\Src\stm32h5xx_it.c;..\Core\Src\stm32h5xx_hal_msp.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_ll_utils.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_ll_exti.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_adc.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_adc_ex.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_dma.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_dma_ex.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_rcc.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_rcc_ex.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_flash.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_flash_ex.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_gpio.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_pwr.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_pwr_ex.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_cortex.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_exti.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_ll_rcc.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_eth.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_eth_ex.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_icache.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_uart.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_uart_ex.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_ll_ucpd.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_ll_gpio.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_ll_dma.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_pcd.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_pcd_ex.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_ll_usb.c;..\Drivers\CMSIS\Device\ST\STM32H5xx\Source\Templates\system_stm32h5xx.c;..\Core\Src\system_stm32h5xx.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_ll_utils.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_ll_exti.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_adc.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_adc_ex.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_dma.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_dma_ex.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_rcc.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_rcc_ex.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_flash.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_flash_ex.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_gpio.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_pwr.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_pwr_ex.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_cortex.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_exti.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_ll_rcc.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_eth.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_eth_ex.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_icache.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_uart.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_uart_ex.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_ll_ucpd.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_ll_gpio.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_ll_dma.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_pcd.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_hal_pcd_ex.c;..\Drivers\STM32H5xx_HAL_Driver\Src\stm32h5xx_ll_usb.c;..\Drivers\CMSIS\Device\ST\STM32H5xx\Source\Templates\system_stm32h5xx.c;..\Core\Src\system_stm32h5xx.c;;; +HeaderPath=..\Drivers\STM32H5xx_HAL_Driver\Inc;..\Drivers\STM32H5xx_HAL_Driver\Inc\Legacy;..\Drivers\CMSIS\Device\ST\STM32H5xx\Include;..\Drivers\CMSIS\Include;..\Core\Inc; +CDefines=USE_FULL_LL_DRIVER;USE_HAL_DRIVER;STM32H563xx;USE_FULL_LL_DRIVER;USE_HAL_DRIVER;USE_HAL_DRIVER; + diff --git a/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/CubeMX_Config.ioc b/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/CubeMX_Config.ioc new file mode 100644 index 0000000000..f57e4a0345 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/CubeMX_Config.ioc @@ -0,0 +1,429 @@ +#MicroXplorer Configuration settings - do not modify +ADC1.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_18 +ADC1.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,OffsetNumber-0\#ChannelRegularConversion,MonitoredBy-0\#ChannelRegularConversion,NbrOfConversionFlag,master +ADC1.MonitoredBy-0\#ChannelRegularConversion=__NULL +ADC1.NbrOfConversionFlag=1 +ADC1.OffsetNumber-0\#ChannelRegularConversion=ADC_OFFSET_NONE +ADC1.Rank-0\#ChannelRegularConversion=1 +ADC1.SamplingTime-0\#ChannelRegularConversion=ADC_SAMPLETIME_2CYCLES_5 +ADC1.master=1 +CAD.formats= +CAD.pinconfig= +CAD.provider= +CORTEX_M33_NS.userName=CORTEX_M33 +ETH.IPParameters=MediaInterface +ETH.MediaInterface=HAL_ETH_RMII_MODE +File.Version=6 +GPIO.groupedBy=Group By Peripherals +KeepUserPlacement=false +Mcu.CPN=STM32H563ZIT6 +Mcu.ContextProject=TrustZoneDisabled +Mcu.Family=STM32H5 +Mcu.IP0=ADC1 +Mcu.IP1=CORTEX_M33_NS +Mcu.IP10=UCPD1 +Mcu.IP11=USART3 +Mcu.IP12=USB +Mcu.IP2=DEBUG +Mcu.IP3=ETH +Mcu.IP4=ICACHE +Mcu.IP5=LPUART1 +Mcu.IP6=NVIC +Mcu.IP7=PWR +Mcu.IP8=RCC +Mcu.IP9=SYS +Mcu.IPNb=13 +Mcu.Name=STM32H563ZITx +Mcu.Package=LQFP144 +Mcu.Pin0=PE2 +Mcu.Pin1=PE3 +Mcu.Pin10=PC1 +Mcu.Pin11=PA1 +Mcu.Pin12=PA2 +Mcu.Pin13=PA4 +Mcu.Pin14=PA7 +Mcu.Pin15=PC4 +Mcu.Pin16=PC5 +Mcu.Pin17=PB0 +Mcu.Pin18=PB13 +Mcu.Pin19=PB14 +Mcu.Pin2=PE4 +Mcu.Pin20=PB15 +Mcu.Pin21=PD8 +Mcu.Pin22=PD9 +Mcu.Pin23=PG4 +Mcu.Pin24=PG7 +Mcu.Pin25=PC9 +Mcu.Pin26=PA9 +Mcu.Pin27=PA11 +Mcu.Pin28=PA12 +Mcu.Pin29=PA13(JTMS/SWDIO) +Mcu.Pin3=PE5 +Mcu.Pin30=PA14(JTCK/SWCLK) +Mcu.Pin31=PA15(JTDI) +Mcu.Pin32=PG11 +Mcu.Pin33=PG13 +Mcu.Pin34=PB3(JTDO/TRACESWO) +Mcu.Pin35=PB6 +Mcu.Pin36=PB7 +Mcu.Pin37=VP_ICACHE_VS_ICACHE +Mcu.Pin38=VP_PWR_VS_SECSignals +Mcu.Pin39=VP_SYS_VS_Systick +Mcu.Pin4=PE6 +Mcu.Pin5=PC13 +Mcu.Pin6=PC14-OSC32_IN(OSC32_IN) +Mcu.Pin7=PC15-OSC32_OUT(OSC32_OUT) +Mcu.Pin8=PF4 +Mcu.Pin9=PH0-OSC_IN(PH0) +Mcu.PinsNb=40 +Mcu.ThirdPartyNb=0 +Mcu.UserConstants= +Mcu.UserName=STM32H563ZITx +MxCube.Version=6.9.1 +MxDb.Version=DB.6.0.91 +NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.ForceEnableDMAVector=true +NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 +NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false +NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +PA1.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Label,GPIO_Mode +PA1.GPIO_Label=RMII_REF_CLK +PA1.GPIO_Mode=GPIO_MODE_AF_PP +PA1.GPIO_PuPd=GPIO_NOPULL +PA1.GPIO_Speed=GPIO_SPEED_FREQ_LOW +PA1.Locked=true +PA1.Mode=RMII +PA1.Signal=ETH_REF_CLK +PA11.GPIOParameters=GPIO_Label +PA11.GPIO_Label=USB_FS_N +PA11.Locked=true +PA11.Mode=Device +PA11.Signal=USB_DM +PA12.GPIOParameters=GPIO_Label +PA12.GPIO_Label=USB_FS_P +PA12.Locked=true +PA12.Mode=Device +PA12.Signal=USB_DP +PA13(JTMS/SWDIO).GPIOParameters=GPIO_Label +PA13(JTMS/SWDIO).GPIO_Label=SWDIO +PA13(JTMS/SWDIO).Locked=true +PA13(JTMS/SWDIO).Mode=Trace_Synchro_4bits_JTAG +PA13(JTMS/SWDIO).Signal=DEBUG_JTMS-SWDIO +PA14(JTCK/SWCLK).GPIOParameters=GPIO_Label +PA14(JTCK/SWCLK).GPIO_Label=SWCLK +PA14(JTCK/SWCLK).Locked=true +PA14(JTCK/SWCLK).Mode=Trace_Synchro_4bits_JTAG +PA14(JTCK/SWCLK).Signal=DEBUG_JTCK-SWCLK +PA15(JTDI).GPIOParameters=GPIO_Label +PA15(JTDI).GPIO_Label=T_JTDI +PA15(JTDI).Locked=true +PA15(JTDI).Mode=Trace_Synchro_4bits_JTAG +PA15(JTDI).Signal=DEBUG_JTDI +PA2.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Label,GPIO_Mode +PA2.GPIO_Label=RMII_MDIO +PA2.GPIO_Mode=GPIO_MODE_AF_PP +PA2.GPIO_PuPd=GPIO_NOPULL +PA2.GPIO_Speed=GPIO_SPEED_FREQ_LOW +PA2.Locked=true +PA2.Mode=RMII +PA2.Signal=ETH_MDIO +PA4.GPIOParameters=GPIO_Label +PA4.GPIO_Label=VBUS_SENSE +PA4.Locked=true +PA4.Signal=ADCx_INP18 +PA7.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Label,GPIO_Mode +PA7.GPIO_Label=RMII_CRS_DV +PA7.GPIO_Mode=GPIO_MODE_AF_PP +PA7.GPIO_PuPd=GPIO_NOPULL +PA7.GPIO_Speed=GPIO_SPEED_FREQ_LOW +PA7.Locked=true +PA7.Mode=RMII +PA7.Signal=ETH_CRS_DV +PA9.GPIOParameters=GPIO_Label +PA9.GPIO_Label=UCPD_DBn +PA9.Locked=true +PA9.Mode=EnableDeadBattery +PA9.Signal=UCPD1_DB1 +PB0.GPIOParameters=GPIO_Label +PB0.GPIO_Label=LED1_GREEN +PB0.Locked=true +PB0.Signal=GPIO_Output +PB13.GPIOParameters=GPIO_Label +PB13.GPIO_Label=UCPD_CC1 +PB13.Locked=true +PB13.Mode=Source_AllSignals +PB13.Signal=UCPD1_CC1 +PB14.GPIOParameters=GPIO_Label +PB14.GPIO_Label=UCPD_CC2 +PB14.Locked=true +PB14.Mode=Source_AllSignals +PB14.Signal=UCPD1_CC2 +PB15.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Label,GPIO_Mode +PB15.GPIO_Label=RMII_TXD1 +PB15.GPIO_Mode=GPIO_MODE_AF_PP +PB15.GPIO_PuPd=GPIO_NOPULL +PB15.GPIO_Speed=GPIO_SPEED_FREQ_LOW +PB15.Locked=true +PB15.Mode=RMII +PB15.Signal=ETH_TXD1 +PB3(JTDO/TRACESWO).GPIOParameters=GPIO_Label +PB3(JTDO/TRACESWO).GPIO_Label=SWO +PB3(JTDO/TRACESWO).Locked=true +PB3(JTDO/TRACESWO).Mode=Trace_Synchro_4bits_JTAG +PB3(JTDO/TRACESWO).Signal=DEBUG_JTDO-SWO +PB6.GPIOParameters=GPIO_Label +PB6.GPIO_Label=ARD_D1_TX +PB6.Locked=true +PB6.Mode=Asynchronous +PB6.Signal=LPUART1_TX +PB7.GPIOParameters=GPIO_Label +PB7.GPIO_Label=ARD_D0_RX +PB7.Locked=true +PB7.Mode=Asynchronous +PB7.Signal=LPUART1_RX +PC1.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Label,GPIO_Mode +PC1.GPIO_Label=RMII_MDC +PC1.GPIO_Mode=GPIO_MODE_AF_PP +PC1.GPIO_PuPd=GPIO_NOPULL +PC1.GPIO_Speed=GPIO_SPEED_FREQ_LOW +PC1.Locked=true +PC1.Mode=RMII +PC1.Signal=ETH_MDC +PC13.GPIOParameters=GPIO_Label +PC13.GPIO_Label=USER_BUTTON +PC13.Locked=true +PC13.Signal=GPXTI13 +PC14-OSC32_IN(OSC32_IN).Locked=true +PC14-OSC32_IN(OSC32_IN).Mode=LSE-External-Oscillator +PC14-OSC32_IN(OSC32_IN).Signal=RCC_OSC32_IN +PC15-OSC32_OUT(OSC32_OUT).Locked=true +PC15-OSC32_OUT(OSC32_OUT).Mode=LSE-External-Oscillator +PC15-OSC32_OUT(OSC32_OUT).Signal=RCC_OSC32_OUT +PC4.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Label,GPIO_Mode +PC4.GPIO_Label=RMII_RXD0 +PC4.GPIO_Mode=GPIO_MODE_AF_PP +PC4.GPIO_PuPd=GPIO_NOPULL +PC4.GPIO_Speed=GPIO_SPEED_FREQ_LOW +PC4.Locked=true +PC4.Mode=RMII +PC4.Signal=ETH_RXD0 +PC5.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Label,GPIO_Mode +PC5.GPIO_Label=RMII_RXD1 +PC5.GPIO_Mode=GPIO_MODE_AF_PP +PC5.GPIO_PuPd=GPIO_NOPULL +PC5.GPIO_Speed=GPIO_SPEED_FREQ_LOW +PC5.Locked=true +PC5.Mode=RMII +PC5.Signal=ETH_RXD1 +PC9.Mode=EnableDeadBattery +PC9.Signal=UCPD1_DB2 +PD8.GPIOParameters=GPIO_Label +PD8.GPIO_Label=T_VCP_TX +PD8.Locked=true +PD8.Mode=Asynchronous +PD8.Signal=USART3_TX +PD9.GPIOParameters=GPIO_Label +PD9.GPIO_Label=T_VCP_RX +PD9.Locked=true +PD9.Mode=Asynchronous +PD9.Signal=USART3_RX +PE2.GPIOParameters=GPIO_Label +PE2.GPIO_Label=TRACE_CK +PE2.Locked=true +PE2.Mode=Trace_Synchro_4bits_JTAG +PE2.Signal=DEBUG_TRACECLK +PE3.GPIOParameters=GPIO_Label +PE3.GPIO_Label=TRACE_D0 +PE3.Locked=true +PE3.Mode=Trace_Synchro_4bits_JTAG +PE3.Signal=DEBUG_TRACED0 +PE4.GPIOParameters=GPIO_Label +PE4.GPIO_Label=TRACE_D1 +PE4.Locked=true +PE4.Mode=Trace_Synchro_4bits_JTAG +PE4.Signal=DEBUG_TRACED1 +PE5.GPIOParameters=GPIO_Label +PE5.GPIO_Label=TRACE_D2 +PE5.Locked=true +PE5.Mode=Trace_Synchro_4bits_JTAG +PE5.Signal=DEBUG_TRACED2 +PE6.GPIOParameters=GPIO_Label +PE6.GPIO_Label=TRACE_D3 +PE6.Locked=true +PE6.Mode=Trace_Synchro_4bits_JTAG +PE6.Signal=DEBUG_TRACED3 +PF4.GPIOParameters=GPIO_Label +PF4.GPIO_Label=LED2_YELLOW +PF4.Locked=true +PF4.Signal=GPIO_Output +PG11.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Label,GPIO_Mode +PG11.GPIO_Label=RMII_TXT_EN +PG11.GPIO_Mode=GPIO_MODE_AF_PP +PG11.GPIO_PuPd=GPIO_NOPULL +PG11.GPIO_Speed=GPIO_SPEED_FREQ_LOW +PG11.Locked=true +PG11.Mode=RMII +PG11.Signal=ETH_TX_EN +PG13.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Label,GPIO_Mode +PG13.GPIO_Label=RMI_TXD0 +PG13.GPIO_Mode=GPIO_MODE_AF_PP +PG13.GPIO_PuPd=GPIO_NOPULL +PG13.GPIO_Speed=GPIO_SPEED_FREQ_LOW +PG13.Locked=true +PG13.Mode=RMII +PG13.Signal=ETH_TXD0 +PG4.GPIOParameters=GPIO_Label +PG4.GPIO_Label=LED3_RED +PG4.Locked=true +PG4.Signal=GPIO_Output +PG7.GPIOParameters=GPIO_Label +PG7.GPIO_Label=UCPD_FLT +PG7.Locked=true +PG7.Signal=GPXTI7 +PH0-OSC_IN(PH0).Locked=true +PH0-OSC_IN(PH0).Mode=HSE-DIG-External-Clock-Source +PH0-OSC_IN(PH0).Signal=RCC_OSC_IN +PinOutPanel.RotationAngle=0 +ProjectManager.AskForMigrate=true +ProjectManager.BackupPrevious=false +ProjectManager.CompilerOptimize=6 +ProjectManager.ComputerToolchain=false +ProjectManager.CoupleFile=false +ProjectManager.CustomerFirmwarePackage= +ProjectManager.DefaultFWLocation=true +ProjectManager.DeletePrevious=true +ProjectManager.DeviceId=STM32H563ZITx +ProjectManager.FirmwarePackage=STM32Cube FW_H5 V1.1.1 +ProjectManager.FreePins=false +ProjectManager.HalAssertFull=false +ProjectManager.HeapSize=0x200 +ProjectManager.KeepUserCode=true +ProjectManager.LastFirmware=true +ProjectManager.LibraryCopy=0 +ProjectManager.MainLocation=Core/Src +ProjectManager.NoMain=false +ProjectManager.PreviousToolchain= +ProjectManager.ProjectBuild=false +ProjectManager.ProjectFileName=CubeMX_Config.ioc +ProjectManager.ProjectName=CubeMX_Config +ProjectManager.ProjectStructure= +ProjectManager.RegisterCallBack= +ProjectManager.StackSize=0x400 +ProjectManager.TargetToolchain=MDK-ARM V5.32 +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_ADC1_Init-ADC1-false-HAL-true,4-MX_ETH_Init-ETH-false-HAL-true,5-MX_ICACHE_Init-ICACHE-false-HAL-true,6-MX_LPUART1_UART_Init-LPUART1-false-HAL-true,7-MX_USART3_UART_Init-USART3-false-HAL-true,8-MX_UCPD1_Init-UCPD1-false-LL-true,9-MX_USB_PCD_Init-USB-false-HAL-true,0-MX_CORTEX_M33_NS_Init-CORTEX_M33_NS-false-HAL-true,0-MX_PWR_Init-PWR-false-HAL-true +RCC.ADCFreq_Value=250000000 +RCC.AHBFreq_Value=250000000 +RCC.APB1Freq_Value=250000000 +RCC.APB1TimFreq_Value=250000000 +RCC.APB2Freq_Value=250000000 +RCC.APB2TimFreq_Value=250000000 +RCC.APB3Freq_Value=250000000 +RCC.CECFreq_Value=32000 +RCC.CKPERFreq_Value=64000000 +RCC.CRSFreq_Value=48000000 +RCC.CSI_VALUE=4000000 +RCC.CortexFreq_Value=250000000 +RCC.DACFreq_Value=32768 +RCC.EPOD_VALUE=8000000 +RCC.ETHFreq_Value=250000000 +RCC.FCLKCortexFreq_Value=250000000 +RCC.FDCANFreq_Value=8000000 +RCC.FamilyName=M +RCC.HCLKFreq_Value=250000000 +RCC.HSE_VALUE=8000000 +RCC.HSI48_VALUE=48000000 +RCC.HSIDiv=RCC_HSI_DIV1 +RCC.HSI_VALUE=64000000 +RCC.I2C1Freq_Value=250000000 +RCC.I2C2Freq_Value=250000000 +RCC.I2C3Freq_Value=250000000 +RCC.I2C4Freq_Value=250000000 +RCC.I3C1Freq_Value=250000000 +RCC.IPParameters=ADCFreq_Value,AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,APB3Freq_Value,CECFreq_Value,CKPERFreq_Value,CRSFreq_Value,CSI_VALUE,CortexFreq_Value,DACFreq_Value,EPOD_VALUE,ETHFreq_Value,FCLKCortexFreq_Value,FDCANFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI48_VALUE,HSIDiv,HSI_VALUE,I2C1Freq_Value,I2C2Freq_Value,I2C3Freq_Value,I2C4Freq_Value,I3C1Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM3Freq_Value,LPTIM4Freq_Value,LPTIM5Freq_Value,LPTIM6Freq_Value,LPUART1Freq_Value,LSCOPinFreq_Value,LSIRC_VALUE,MCO1PinFreq_Value,MCO2PinFreq_Value,OCTOSPIMFreq_Value,PLL2PoutputFreq_Value,PLL2QoutputFreq_Value,PLL2RoutputFreq_Value,PLL3PoutputFreq_Value,PLL3QoutputFreq_Value,PLL3RoutputFreq_Value,PLLM,PLLN,PLLPoutputFreq_Value,PLLQoutputFreq_Value,PLLSourceVirtual,PWRFreq_Value,RNGFreq_Value,SAI1Freq_Value,SAI2Freq_Value,SDMMC1Freq_Value,SDMMC2Freq_Value,SPI1Freq_Value,SPI2Freq_Value,SPI3Freq_Value,SPI4Freq_Value,SPI5Freq_Value,SPI6Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,UART12Freq_Value,UART4Freq_Value,UART5Freq_Value,UART7Freq_Value,UART8Freq_Value,UART9Freq_Value,UCPD1outputFreq_Value,USART10Freq_Value,USART11Freq_Value,USART1Freq_Value,USART2Freq_Value,USART3Freq_Value,USART6Freq_Value,USBFreq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VCOPLL2OutputFreq_Value,VCOPLL3OutputFreq_Value +RCC.LPTIM1Freq_Value=250000000 +RCC.LPTIM2Freq_Value=250000000 +RCC.LPTIM3Freq_Value=250000000 +RCC.LPTIM4Freq_Value=250000000 +RCC.LPTIM5Freq_Value=250000000 +RCC.LPTIM6Freq_Value=250000000 +RCC.LPUART1Freq_Value=250000000 +RCC.LSCOPinFreq_Value=32000 +RCC.LSIRC_VALUE=32000 +RCC.MCO1PinFreq_Value=64000000 +RCC.MCO2PinFreq_Value=250000000 +RCC.OCTOSPIMFreq_Value=250000000 +RCC.PLL2PoutputFreq_Value=258000000 +RCC.PLL2QoutputFreq_Value=258000000 +RCC.PLL2RoutputFreq_Value=258000000 +RCC.PLL3PoutputFreq_Value=258000000 +RCC.PLL3QoutputFreq_Value=258000000 +RCC.PLL3RoutputFreq_Value=258000000 +RCC.PLLM=4 +RCC.PLLN=250 +RCC.PLLPoutputFreq_Value=250000000 +RCC.PLLQoutputFreq_Value=250000000 +RCC.PLLSourceVirtual=RCC_PLL1_SOURCE_HSE +RCC.PWRFreq_Value=250000000 +RCC.RNGFreq_Value=48000000 +RCC.SAI1Freq_Value=258000000 +RCC.SAI2Freq_Value=258000000 +RCC.SDMMC1Freq_Value=250000000 +RCC.SDMMC2Freq_Value=250000000 +RCC.SPI1Freq_Value=250000000 +RCC.SPI2Freq_Value=250000000 +RCC.SPI3Freq_Value=250000000 +RCC.SPI4Freq_Value=250000000 +RCC.SPI5Freq_Value=250000000 +RCC.SPI6Freq_Value=250000000 +RCC.SYSCLKFreq_VALUE=250000000 +RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK +RCC.UART12Freq_Value=250000000 +RCC.UART4Freq_Value=250000000 +RCC.UART5Freq_Value=250000000 +RCC.UART7Freq_Value=250000000 +RCC.UART8Freq_Value=250000000 +RCC.UART9Freq_Value=250000000 +RCC.UCPD1outputFreq_Value=16000000 +RCC.USART10Freq_Value=250000000 +RCC.USART11Freq_Value=250000000 +RCC.USART1Freq_Value=250000000 +RCC.USART2Freq_Value=250000000 +RCC.USART3Freq_Value=250000000 +RCC.USART6Freq_Value=250000000 +RCC.USBFreq_Value=48000000 +RCC.VCOInput2Freq_Value=4000000 +RCC.VCOInput3Freq_Value=4000000 +RCC.VCOInputFreq_Value=2000000 +RCC.VCOOutputFreq_Value=500000000 +RCC.VCOPLL2OutputFreq_Value=516000000 +RCC.VCOPLL3OutputFreq_Value=516000000 +SH.ADCx_INP18.0=ADC1_INP18,IN18-Single-Ended +SH.ADCx_INP18.ConfNb=1 +SH.GPXTI13.0=GPIO_EXTI13 +SH.GPXTI13.ConfNb=1 +SH.GPXTI7.0=GPIO_EXTI7 +SH.GPXTI7.ConfNb=1 +USART3.IPParameters=VirtualMode,RxPinLevelInvertParam,OverSampling +USART3.OverSampling=UART_OVERSAMPLING_8 +USART3.RxPinLevelInvertParam=ADVFEATURE_RXINV_ENABLE +USART3.VirtualMode=VM_ASYNC +USB.IPParameters=VirtualMode +USB.VirtualMode=Device_Only +VP_ICACHE_VS_ICACHE.Mode=DefaultMode +VP_ICACHE_VS_ICACHE.Signal=ICACHE_VS_ICACHE +VP_PWR_VS_SECSignals.Mode=Security/Privilege +VP_PWR_VS_SECSignals.Signal=PWR_VS_SECSignals +VP_SYS_VS_Systick.Mode=SysTick +VP_SYS_VS_Systick.Signal=SYS_VS_Systick +board=NUCLEO-H563ZI +boardIOC=true diff --git a/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Inc/main.h b/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Inc/main.h new file mode 100644 index 0000000000..f02c0533d1 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Inc/main.h @@ -0,0 +1,146 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.h + * @brief : Header for main.c file. + * This file contains the common defines of the application. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MAIN_H +#define __MAIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" +#include "stm32h5xx_ll_ucpd.h" +#include "stm32h5xx_ll_bus.h" +#include "stm32h5xx_ll_cortex.h" +#include "stm32h5xx_ll_rcc.h" +#include "stm32h5xx_ll_system.h" +#include "stm32h5xx_ll_utils.h" +#include "stm32h5xx_ll_pwr.h" +#include "stm32h5xx_ll_gpio.h" +#include "stm32h5xx_ll_dma.h" + +#include "stm32h5xx_ll_exti.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +/* USER CODE BEGIN ET */ + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* Exported macro ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +/* Exported functions prototypes ---------------------------------------------*/ +void Error_Handler(void); + +/* USER CODE BEGIN EFP */ + +/* USER CODE END EFP */ + +/* Private defines -----------------------------------------------------------*/ +#define TRACE_CK_Pin GPIO_PIN_2 +#define TRACE_CK_GPIO_Port GPIOE +#define TRACE_D0_Pin GPIO_PIN_3 +#define TRACE_D0_GPIO_Port GPIOE +#define TRACE_D1_Pin GPIO_PIN_4 +#define TRACE_D1_GPIO_Port GPIOE +#define TRACE_D2_Pin GPIO_PIN_5 +#define TRACE_D2_GPIO_Port GPIOE +#define TRACE_D3_Pin GPIO_PIN_6 +#define TRACE_D3_GPIO_Port GPIOE +#define USER_BUTTON_Pin GPIO_PIN_13 +#define USER_BUTTON_GPIO_Port GPIOC +#define LED2_YELLOW_Pin GPIO_PIN_4 +#define LED2_YELLOW_GPIO_Port GPIOF +#define RMII_MDC_Pin GPIO_PIN_1 +#define RMII_MDC_GPIO_Port GPIOC +#define RMII_REF_CLK_Pin GPIO_PIN_1 +#define RMII_REF_CLK_GPIO_Port GPIOA +#define RMII_MDIO_Pin GPIO_PIN_2 +#define RMII_MDIO_GPIO_Port GPIOA +#define VBUS_SENSE_Pin GPIO_PIN_4 +#define VBUS_SENSE_GPIO_Port GPIOA +#define RMII_CRS_DV_Pin GPIO_PIN_7 +#define RMII_CRS_DV_GPIO_Port GPIOA +#define RMII_RXD0_Pin GPIO_PIN_4 +#define RMII_RXD0_GPIO_Port GPIOC +#define RMII_RXD1_Pin GPIO_PIN_5 +#define RMII_RXD1_GPIO_Port GPIOC +#define LED1_GREEN_Pin GPIO_PIN_0 +#define LED1_GREEN_GPIO_Port GPIOB +#define UCPD_CC1_Pin GPIO_PIN_13 +#define UCPD_CC1_GPIO_Port GPIOB +#define UCPD_CC2_Pin GPIO_PIN_14 +#define UCPD_CC2_GPIO_Port GPIOB +#define RMII_TXD1_Pin GPIO_PIN_15 +#define RMII_TXD1_GPIO_Port GPIOB +#define T_VCP_TX_Pin GPIO_PIN_8 +#define T_VCP_TX_GPIO_Port GPIOD +#define T_VCP_RX_Pin GPIO_PIN_9 +#define T_VCP_RX_GPIO_Port GPIOD +#define LED3_RED_Pin GPIO_PIN_4 +#define LED3_RED_GPIO_Port GPIOG +#define UCPD_FLT_Pin GPIO_PIN_7 +#define UCPD_FLT_GPIO_Port GPIOG +#define UCPD_DBn_Pin GPIO_PIN_9 +#define UCPD_DBn_GPIO_Port GPIOA +#define USB_FS_N_Pin GPIO_PIN_11 +#define USB_FS_N_GPIO_Port GPIOA +#define USB_FS_P_Pin GPIO_PIN_12 +#define USB_FS_P_GPIO_Port GPIOA +#define SWDIO_Pin GPIO_PIN_13 +#define SWDIO_GPIO_Port GPIOA +#define SWCLK_Pin GPIO_PIN_14 +#define SWCLK_GPIO_Port GPIOA +#define T_JTDI_Pin GPIO_PIN_15 +#define T_JTDI_GPIO_Port GPIOA +#define RMII_TXT_EN_Pin GPIO_PIN_11 +#define RMII_TXT_EN_GPIO_Port GPIOG +#define RMI_TXD0_Pin GPIO_PIN_13 +#define RMI_TXD0_GPIO_Port GPIOG +#define SWO_Pin GPIO_PIN_3 +#define SWO_GPIO_Port GPIOB +#define ARD_D1_TX_Pin GPIO_PIN_6 +#define ARD_D1_TX_GPIO_Port GPIOB +#define ARD_D0_RX_Pin GPIO_PIN_7 +#define ARD_D0_RX_GPIO_Port GPIOB + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MAIN_H */ diff --git a/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Inc/stm32_assert.h b/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Inc/stm32_assert.h new file mode 100644 index 0000000000..ce166a2203 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Inc/stm32_assert.h @@ -0,0 +1,53 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32_assert.h + * @brief STM32 assert file. + ****************************************************************************** + * @attention + * + * Copyright (c) 2018 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 __STM32_ASSERT_H +#define __STM32_ASSERT_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Includes ------------------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_ASSERT_H */ + diff --git a/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Inc/stm32h5xx_hal_conf.h b/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Inc/stm32h5xx_hal_conf.h new file mode 100644 index 0000000000..9049361114 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Inc/stm32h5xx_hal_conf.h @@ -0,0 +1,504 @@ +/* USER CODE BEGIN Header */ +/** + ********************************************************************************************************************** + + * @file stm32h5xx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration file. + ********************************************************************************************************************** + + * @attention + * + * Copyright (c) 2022 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 STM32H5xx_HAL_CONF_H +#define STM32H5xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ----------------------------------------------------------------------------------------------------*/ +/* Exported constants ------------------------------------------------------------------------------------------------*/ + +/* ########################################### Module Selection ##################################################### */ + +/** + * @brief This is the list of modules to be used in the HAL driver + */ + +#define HAL_MODULE_ENABLED + +#define HAL_ADC_MODULE_ENABLED +/*#define HAL_CEC_MODULE_ENABLED */ +/*#define HAL_COMP_MODULE_ENABLED */ +/*#define HAL_CORDIC_MODULE_ENABLED */ +/*#define HAL_CRC_MODULE_ENABLED */ +/*#define HAL_CRYP_MODULE_ENABLED */ +/*#define HAL_DAC_MODULE_ENABLED */ +/*#define HAL_DCACHE_MODULE_ENABLED */ +/*#define HAL_DCMI_MODULE_ENABLED */ +/*#define HAL_DTS_MODULE_ENABLED */ +#define HAL_ETH_MODULE_ENABLED +/*#define HAL_FDCAN_MODULE_ENABLED */ +/*#define HAL_FMAC_MODULE_ENABLED */ +/*#define HAL_GTZC_MODULE_ENABLED */ +/*#define HAL_HASH_MODULE_ENABLED */ +/*#define HAL_HCD_MODULE_ENABLED */ +/*#define HAL_IRDA_MODULE_ENABLED */ +/*#define HAL_IWDG_MODULE_ENABLED */ +/*#define HAL_I2C_MODULE_ENABLED */ +/*#define HAL_I3C_MODULE_ENABLED */ +/*#define HAL_I2S_MODULE_ENABLED */ +/*#define HAL_LPTIM_MODULE_ENABLED */ +/*#define HAL_NAND_MODULE_ENABLED */ +/*#define HAL_NOR_MODULE_ENABLED */ +/*#define HAL_OPAMP_MODULE_ENABLED */ +/*#define HAL_XSPI_MODULE_ENABLED */ +/*#define HAL_OTFDEC_MODULE_ENABLED */ +/*#define HAL_PKA_MODULE_ENABLED */ +/*#define HAL_RNG_MODULE_ENABLED */ +/*#define HAL_RTC_MODULE_ENABLED */ +/*#define HAL_SAI_MODULE_ENABLED */ +/*#define HAL_SD_MODULE_ENABLED */ +/*#define HAL_SDRAM_MODULE_ENABLED */ +/*#define HAL_MMC_MODULE_ENABLED */ +/*#define HAL_SMARTCARD_MODULE_ENABLED */ +/*#define HAL_SMBUS_MODULE_ENABLED */ +/*#define HAL_SPI_MODULE_ENABLED */ +/*#define HAL_SRAM_MODULE_ENABLED */ +/*#define HAL_TIM_MODULE_ENABLED */ +/*#define HAL_RAMCFG_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/*#define HAL_USART_MODULE_ENABLED */ +/*#define HAL_WWDG_MODULE_ENABLED */ +/*#define HAL_PSSI_MODULE_ENABLED */ +#define HAL_ICACHE_MODULE_ENABLED +#define HAL_PCD_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED + +/* ####################################### Oscillator Values adaptation ##############################################*/ + +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal Core Speed oscillator (CSI) default value. + * This value is the default CSI range value after Reset. + */ +#if !defined (CSI_VALUE) + #define CSI_VALUE 4000000UL /*!< Value of the Internal oscillator in Hz*/ +#endif /* CSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE 64000000UL /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI48) value for USB FS, SDMMC and RNG. + * This internal oscillator is mainly dedicated to provide a high precision clock to + * the USB peripheral by means of a special Clock Recovery System (CRS) circuitry. + * When the CRS is not used, the HSI48 RC oscillator runs on it default frequency + * which is subject to manufacturing process variations. + */ +#if !defined (HSI48_VALUE) + #define HSI48_VALUE 48000000UL /*!< Value of the Internal High Speed oscillator for USB FS/SDMMC/RNG in Hz. + The real value my vary depending on manufacturing process variations.*/ +#endif /* HSI48_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE 32000UL /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature.*/ + +#if !defined (LSI_STARTUP_TIME) + #define LSI_STARTUP_TIME 130UL /*!< Time out for LSI start up, in ms */ +#endif /* LSI_STARTUP_TIME */ + +/** + * @brief External Low Speed oscillator (LSE) value. + * This value is used by the UART, RTC HAL module to compute the system frequency + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE 32768UL /*!< Value of the External oscillator in Hz*/ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT 5000UL /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for SPI/SAI peripheral + * This value is used by the SPI/SAI HAL module to compute the SPI/SAI clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + + */ +#if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE 12288000UL /*!< Value of the External clock in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ############################################ System Configuration ################################################ */ + +/** + * @brief This is the HAL system configuration section + */ + +#define VDD_VALUE 3300UL /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY (15UL) /*!< tick interrupt priority (lowest by default) */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 0U /*!< Enable prefetch */ + +/* ############################################ Assert Selection #################################################### */ + +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ + +/* #define USE_FULL_ASSERT 1U */ + +/* ############################################ Register callback feature configuration ############################# */ + +/** + * @brief Set below the peripheral configuration to "1U" to add the support + * of HAL callback registration/unregistration feature for the HAL + * driver(s). This allows user application to provide specific callback + * functions thanks to HAL_PPP_RegisterCallback() rather than overwriting + * the default weak callback functions (see each stm32h5xx_hal_ppp.h file + * for possible callback identifiers defined in HAL_PPP_CallbackIDTypeDef + * for each PPP peripheral). + */ +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_COMP_REGISTER_CALLBACKS 0U /* COMP register callback disabled */ +#define USE_HAL_CORDIC_REGISTER_CALLBACKS 0U /* CORDIC register callback disabled */ +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ +#define USE_HAL_DTS_REGISTER_CALLBACKS 0U /* DTS register callback disabled */ +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ +#define USE_HAL_FDCAN_REGISTER_CALLBACKS 0U /* FDCAN register callback disabled */ +#define USE_HAL_FMAC_REGISTER_CALLBACKS 0U /* FMAC register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_I3C_REGISTER_CALLBACKS 0U /* I3C register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_IWDG_REGISTER_CALLBACKS 0U /* IWDG register callback disabled */ +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ + +#define USE_HAL_OPAMP_REGISTER_CALLBACKS 0U /* OTFDEC register callback disabled */ +#define USE_HAL_OTFDEC_REGISTER_CALLBACKS 0U /* OPAMP register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_PKA_REGISTER_CALLBACKS 0U /* PKA register callback disabled */ +#define USE_HAL_RAMCFG_REGISTER_CALLBACKS 0U /* RAMCFG register callback disabled */ +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ +#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ +#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ +#define USE_HAL_XSPI_REGISTER_CALLBACKS 0U /* XSPI register callback disabled */ + +/* ############################################ SPI peripheral configuration ######################################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver + * Activated: CRC code is present inside driver + * Deactivated: CRC code cleaned from driver + */ +#define USE_SPI_CRC 0U + +/* Includes ----------------------------------------------------------------------------------------------------------*/ + +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32h5xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32h5xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_ICACHE_MODULE_ENABLED + #include "stm32h5xx_hal_icache.h" +#endif /* HAL_ICACHE_MODULE_ENABLED */ + +#ifdef HAL_DCACHE_MODULE_ENABLED + #include "stm32h5xx_hal_dcache.h" +#endif /* HAL_DCACHE_MODULE_ENABLED */ + +#ifdef HAL_GTZC_MODULE_ENABLED + #include "stm32h5xx_hal_gtzc.h" +#endif /* HAL_GTZC_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32h5xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_DTS_MODULE_ENABLED + #include "stm32h5xx_hal_dts.h" +#endif /* HAL_DTS_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32h5xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_PKA_MODULE_ENABLED + #include "stm32h5xx_hal_pka.h" +#endif /* HAL_PKA_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32h5xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32h5xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32h5xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32h5xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32h5xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32h5xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32h5xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + #include "stm32h5xx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_MMC_MODULE_ENABLED + #include "stm32h5xx_hal_mmc.h" +#endif /* HAL_MMC_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32h5xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32h5xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32h5xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32h5xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_I3C_MODULE_ENABLED + #include "stm32h5xx_hal_i3c.h" +#endif /* HAL_I3C_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32h5xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED +#include "stm32h5xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32h5xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_XSPI_MODULE_ENABLED + #include "stm32h5xx_hal_xspi.h" +#endif /* HAL_XSPI_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32h5xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32h5xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32h5xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32h5xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32h5xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32h5xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32h5xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32h5xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32h5xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32h5xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32h5xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32h5xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32h5xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32h5xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED + #include "stm32h5xx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CORDIC_MODULE_ENABLED + #include "stm32h5xx_hal_cordic.h" +#endif /* HAL_CORDIC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32h5xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32h5xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "stm32h5xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_FDCAN_MODULE_ENABLED + #include "stm32h5xx_hal_fdcan.h" +#endif /* HAL_FDCAN_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32h5xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_FMAC_MODULE_ENABLED + #include "stm32h5xx_hal_fmac.h" +#endif /* HAL_FMAC_MODULE_ENABLED */ + +#ifdef HAL_OPAMP_MODULE_ENABLED + #include "stm32h5xx_hal_opamp.h" +#endif /* HAL_OPAMP_MODULE_ENABLED */ + +#ifdef HAL_OTFDEC_MODULE_ENABLED + #include "stm32h5xx_hal_otfdec.h" +#endif /* HAL_OTFDEC_MODULE_ENABLED */ + +#ifdef HAL_PSSI_MODULE_ENABLED + #include "stm32h5xx_hal_pssi.h" +#endif /* HAL_PSSI_MODULE_ENABLED */ + +#ifdef HAL_RAMCFG_MODULE_ENABLED + #include "stm32h5xx_hal_ramcfg.h" +#endif /* HAL_RAMCFG_MODULE_ENABLED */ + +/* Exported macro ----------------------------------------------------------------------------------------------------*/ + +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ----------------------------------------------------------------------------------------------- */ + + void assert_failed(uint8_t *file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_CONF_H */ + diff --git a/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Inc/stm32h5xx_it.h b/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Inc/stm32h5xx_it.h new file mode 100644 index 0000000000..43b86c7ee7 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Inc/stm32h5xx_it.h @@ -0,0 +1,66 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32h5xx_it.h + * @brief This file contains the headers of the interrupt handlers. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32H5xx_IT_H +#define __STM32H5xx_IT_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +/* USER CODE BEGIN ET */ + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* Exported macro ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +/* Exported functions prototypes ---------------------------------------------*/ +void NMI_Handler(void); +void HardFault_Handler(void); +void MemManage_Handler(void); +void BusFault_Handler(void); +void UsageFault_Handler(void); +void SVC_Handler(void); +void DebugMon_Handler(void); +void PendSV_Handler(void); +void SysTick_Handler(void); +/* USER CODE BEGIN EFP */ + +/* USER CODE END EFP */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32H5xx_IT_H */ diff --git a/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Src/main.c b/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Src/main.c new file mode 100644 index 0000000000..cd29ecbc44 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Src/main.c @@ -0,0 +1,593 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.c + * @brief : Main program body + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "string.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN PTD */ + +/* USER CODE END PTD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ + +ETH_TxPacketConfig TxConfig; +ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */ +ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */ + +ADC_HandleTypeDef hadc1; + +ETH_HandleTypeDef heth; + +UART_HandleTypeDef hlpuart1; +UART_HandleTypeDef huart3; + +PCD_HandleTypeDef hpcd_USB_DRD_FS; + +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +void SystemClock_Config(void); +static void MX_GPIO_Init(void); +static void MX_ADC1_Init(void); +static void MX_ETH_Init(void); +static void MX_ICACHE_Init(void); +static void MX_LPUART1_UART_Init(void); +static void MX_USART3_UART_Init(void); +static void MX_UCPD1_Init(void); +static void MX_USB_PCD_Init(void); +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/** + * @brief The application entry point. + * @retval int + */ +int main(void) +{ + /* USER CODE BEGIN 1 */ + + /* USER CODE END 1 */ + + /* MCU Configuration--------------------------------------------------------*/ + + /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ + HAL_Init(); + + /* USER CODE BEGIN Init */ + + /* USER CODE END Init */ + + /* Configure the system clock */ + SystemClock_Config(); + + /* USER CODE BEGIN SysInit */ + + /* USER CODE END SysInit */ + + /* Initialize all configured peripherals */ + MX_GPIO_Init(); + MX_ADC1_Init(); + MX_ETH_Init(); + MX_ICACHE_Init(); + MX_LPUART1_UART_Init(); + MX_USART3_UART_Init(); + MX_UCPD1_Init(); + MX_USB_PCD_Init(); + /* USER CODE BEGIN 2 */ + + /* USER CODE END 2 */ + + /* Infinite loop */ + /* USER CODE BEGIN WHILE */ + while (1) + { + /* USER CODE END WHILE */ + + /* USER CODE BEGIN 3 */ + } + /* USER CODE END 3 */ +} + +/** + * @brief System Clock Configuration + * @retval None + */ +void SystemClock_Config(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + + /** Configure the main internal regulator output voltage + */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0); + + while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {} + + /** Initializes the RCC Oscillators according to the specified parameters + * in the RCC_OscInitTypeDef structure. + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSI + |RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS_DIGITAL; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1; + RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLL1_SOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = 4; + RCC_OscInitStruct.PLL.PLLN = 250; + RCC_OscInitStruct.PLL.PLLP = 2; + RCC_OscInitStruct.PLL.PLLQ = 2; + RCC_OscInitStruct.PLL.PLLR = 2; + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1_VCIRANGE_1; + RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1_VCORANGE_WIDE; + RCC_OscInitStruct.PLL.PLLFRACN = 0; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + Error_Handler(); + } + + /** Initializes the CPU, AHB and APB buses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK + |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2 + |RCC_CLOCKTYPE_PCLK3; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) + { + Error_Handler(); + } +} + +/** + * @brief ADC1 Initialization Function + * @param None + * @retval None + */ +static 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 */ + + /** Common config + */ + hadc1.Instance = ADC1; + hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2; + hadc1.Init.Resolution = ADC_RESOLUTION_12B; + hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; + hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; + hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV; + hadc1.Init.LowPowerAutoWait = DISABLE; + hadc1.Init.ContinuousConvMode = DISABLE; + hadc1.Init.NbrOfConversion = 1; + hadc1.Init.DiscontinuousConvMode = DISABLE; + hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; + hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; + hadc1.Init.DMAContinuousRequests = DISABLE; + hadc1.Init.SamplingMode = ADC_SAMPLING_MODE_NORMAL; + hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED; + hadc1.Init.OversamplingMode = DISABLE; + if (HAL_ADC_Init(&hadc1) != HAL_OK) + { + Error_Handler(); + } + + /** Configure Regular Channel + */ + sConfig.Channel = ADC_CHANNEL_18; + sConfig.Rank = ADC_REGULAR_RANK_1; + sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5; + sConfig.SingleDiff = ADC_SINGLE_ENDED; + sConfig.OffsetNumber = ADC_OFFSET_NONE; + sConfig.Offset = 0; + if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN ADC1_Init 2 */ + + /* USER CODE END ADC1_Init 2 */ + +} + +/** + * @brief ETH Initialization Function + * @param None + * @retval None + */ +static void MX_ETH_Init(void) +{ + + /* USER CODE BEGIN ETH_Init 0 */ + + /* USER CODE END ETH_Init 0 */ + + static uint8_t MACAddr[6]; + + /* USER CODE BEGIN ETH_Init 1 */ + + /* USER CODE END ETH_Init 1 */ + heth.Instance = ETH; + MACAddr[0] = 0x00; + MACAddr[1] = 0x80; + MACAddr[2] = 0xE1; + MACAddr[3] = 0x00; + MACAddr[4] = 0x00; + MACAddr[5] = 0x00; + heth.Init.MACAddr = &MACAddr[0]; + heth.Init.MediaInterface = HAL_ETH_RMII_MODE; + heth.Init.TxDesc = DMATxDscrTab; + heth.Init.RxDesc = DMARxDscrTab; + heth.Init.RxBuffLen = 1524; + + /* USER CODE BEGIN MACADDRESS */ + + /* USER CODE END MACADDRESS */ + + if (HAL_ETH_Init(&heth) != HAL_OK) + { + Error_Handler(); + } + + memset(&TxConfig, 0 , sizeof(ETH_TxPacketConfig)); + TxConfig.Attributes = ETH_TX_PACKETS_FEATURES_CSUM | ETH_TX_PACKETS_FEATURES_CRCPAD; + TxConfig.ChecksumCtrl = ETH_CHECKSUM_IPHDR_PAYLOAD_INSERT_PHDR_CALC; + TxConfig.CRCPadCtrl = ETH_CRC_PAD_INSERT; + /* USER CODE BEGIN ETH_Init 2 */ + + /* USER CODE END ETH_Init 2 */ + +} + +/** + * @brief ICACHE Initialization Function + * @param None + * @retval None + */ +static void MX_ICACHE_Init(void) +{ + + /* USER CODE BEGIN ICACHE_Init 0 */ + + /* USER CODE END ICACHE_Init 0 */ + + /* USER CODE BEGIN ICACHE_Init 1 */ + + /* USER CODE END ICACHE_Init 1 */ + + /** Enable instruction cache (default 2-ways set associative cache) + */ + if (HAL_ICACHE_Enable() != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN ICACHE_Init 2 */ + + /* USER CODE END ICACHE_Init 2 */ + +} + +/** + * @brief LPUART1 Initialization Function + * @param None + * @retval None + */ +static void MX_LPUART1_UART_Init(void) +{ + + /* USER CODE BEGIN LPUART1_Init 0 */ + + /* USER CODE END LPUART1_Init 0 */ + + /* USER CODE BEGIN LPUART1_Init 1 */ + + /* USER CODE END LPUART1_Init 1 */ + hlpuart1.Instance = LPUART1; + hlpuart1.Init.BaudRate = 209700; + hlpuart1.Init.WordLength = UART_WORDLENGTH_8B; + hlpuart1.Init.StopBits = UART_STOPBITS_1; + hlpuart1.Init.Parity = UART_PARITY_NONE; + hlpuart1.Init.Mode = UART_MODE_TX_RX; + hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; + hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; + hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; + hlpuart1.FifoMode = UART_FIFOMODE_DISABLE; + if (HAL_UART_Init(&hlpuart1) != HAL_OK) + { + Error_Handler(); + } + if (HAL_UARTEx_SetTxFifoThreshold(&hlpuart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK) + { + Error_Handler(); + } + if (HAL_UARTEx_SetRxFifoThreshold(&hlpuart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK) + { + Error_Handler(); + } + if (HAL_UARTEx_DisableFifoMode(&hlpuart1) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN LPUART1_Init 2 */ + + /* USER CODE END LPUART1_Init 2 */ + +} + +/** + * @brief USART3 Initialization Function + * @param None + * @retval None + */ +static void MX_USART3_UART_Init(void) +{ + + /* USER CODE BEGIN USART3_Init 0 */ + + /* USER CODE END USART3_Init 0 */ + + /* USER CODE BEGIN USART3_Init 1 */ + + /* USER CODE END USART3_Init 1 */ + huart3.Instance = USART3; + huart3.Init.BaudRate = 115200; + huart3.Init.WordLength = UART_WORDLENGTH_8B; + huart3.Init.StopBits = UART_STOPBITS_1; + huart3.Init.Parity = UART_PARITY_NONE; + huart3.Init.Mode = UART_MODE_TX_RX; + huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE; + huart3.Init.OverSampling = UART_OVERSAMPLING_8; + huart3.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; + huart3.Init.ClockPrescaler = UART_PRESCALER_DIV1; + huart3.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_RXINVERT_INIT; + huart3.AdvancedInit.RxPinLevelInvert = UART_ADVFEATURE_RXINV_ENABLE; + if (HAL_UART_Init(&huart3) != HAL_OK) + { + Error_Handler(); + } + if (HAL_UARTEx_SetTxFifoThreshold(&huart3, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK) + { + Error_Handler(); + } + if (HAL_UARTEx_SetRxFifoThreshold(&huart3, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK) + { + Error_Handler(); + } + if (HAL_UARTEx_DisableFifoMode(&huart3) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN USART3_Init 2 */ + + /* USER CODE END USART3_Init 2 */ + +} + +/** + * @brief UCPD1 Initialization Function + * @param None + * @retval None + */ +static void MX_UCPD1_Init(void) +{ + + /* USER CODE BEGIN UCPD1_Init 0 */ + + /* USER CODE END UCPD1_Init 0 */ + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /* Peripheral clock enable */ + LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_UCPD1); + + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB); + /**UCPD1 GPIO Configuration + PB13 ------> UCPD1_CC1 + PB14 ------> UCPD1_CC2 + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_13|LL_GPIO_PIN_14; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* USER CODE BEGIN UCPD1_Init 1 */ + + /* USER CODE END UCPD1_Init 1 */ + /* USER CODE BEGIN UCPD1_Init 2 */ + + /* USER CODE END UCPD1_Init 2 */ + +} + +/** + * @brief USB Initialization Function + * @param None + * @retval None + */ +static void MX_USB_PCD_Init(void) +{ + + /* USER CODE BEGIN USB_Init 0 */ + + /* USER CODE END USB_Init 0 */ + + /* USER CODE BEGIN USB_Init 1 */ + + /* USER CODE END USB_Init 1 */ + hpcd_USB_DRD_FS.Instance = USB_DRD_FS; + hpcd_USB_DRD_FS.Init.dev_endpoints = 8; + hpcd_USB_DRD_FS.Init.speed = USBD_FS_SPEED; + hpcd_USB_DRD_FS.Init.phy_itface = PCD_PHY_EMBEDDED; + hpcd_USB_DRD_FS.Init.Sof_enable = DISABLE; + hpcd_USB_DRD_FS.Init.low_power_enable = DISABLE; + hpcd_USB_DRD_FS.Init.lpm_enable = DISABLE; + hpcd_USB_DRD_FS.Init.battery_charging_enable = DISABLE; + hpcd_USB_DRD_FS.Init.vbus_sensing_enable = DISABLE; + hpcd_USB_DRD_FS.Init.bulk_doublebuffer_enable = DISABLE; + hpcd_USB_DRD_FS.Init.iso_singlebuffer_enable = DISABLE; + if (HAL_PCD_Init(&hpcd_USB_DRD_FS) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN USB_Init 2 */ + + /* USER CODE END USB_Init 2 */ + +} + +/** + * @brief GPIO Initialization Function + * @param None + * @retval None + */ +static void MX_GPIO_Init(void) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; +/* USER CODE BEGIN MX_GPIO_Init_1 */ +/* USER CODE END MX_GPIO_Init_1 */ + + /* GPIO Ports Clock Enable */ + __HAL_RCC_GPIOE_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOF_CLK_ENABLE(); + __HAL_RCC_GPIOH_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOG_CLK_ENABLE(); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(LED2_YELLOW_GPIO_Port, LED2_YELLOW_Pin, GPIO_PIN_RESET); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(LED1_GREEN_GPIO_Port, LED1_GREEN_Pin, GPIO_PIN_RESET); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(LED3_RED_GPIO_Port, LED3_RED_Pin, GPIO_PIN_RESET); + + /*Configure GPIO pin : USER_BUTTON_Pin */ + GPIO_InitStruct.Pin = USER_BUTTON_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(USER_BUTTON_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pin : LED2_YELLOW_Pin */ + GPIO_InitStruct.Pin = LED2_YELLOW_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(LED2_YELLOW_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pin : LED1_GREEN_Pin */ + GPIO_InitStruct.Pin = LED1_GREEN_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(LED1_GREEN_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pin : LED3_RED_Pin */ + GPIO_InitStruct.Pin = LED3_RED_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(LED3_RED_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pin : UCPD_FLT_Pin */ + GPIO_InitStruct.Pin = UCPD_FLT_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(UCPD_FLT_GPIO_Port, &GPIO_InitStruct); + +/* USER CODE BEGIN MX_GPIO_Init_2 */ +/* USER CODE END MX_GPIO_Init_2 */ +} + +/* USER CODE BEGIN 4 */ + +/* USER CODE END 4 */ + +/** + * @brief This function is executed in case of error occurrence. + * @retval None + */ +void Error_Handler(void) +{ + /* USER CODE BEGIN Error_Handler_Debug */ + /* User can add his own implementation to report the HAL error return state */ + __disable_irq(); + while (1) + { + } + /* USER CODE END Error_Handler_Debug */ +} + +#ifdef USE_FULL_ASSERT +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t *file, uint32_t line) +{ + /* USER CODE BEGIN 6 */ + /* User can add his own implementation to report the file name and line number, + ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + /* USER CODE END 6 */ +} +#endif /* USE_FULL_ASSERT */ diff --git a/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Src/stm32h5xx_hal_msp.c b/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Src/stm32h5xx_hal_msp.c new file mode 100644 index 0000000000..7b68e44b61 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Src/stm32h5xx_hal_msp.c @@ -0,0 +1,467 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32h5xx_hal_msp.c + * @brief This file provides code for the MSP Initialization + * and de-Initialization codes. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ +#include +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN Define */ + +/* USER CODE END Define */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN Macro */ + +/* USER CODE END Macro */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* External functions --------------------------------------------------------*/ +/* USER CODE BEGIN ExternalFunctions */ + +/* USER CODE END ExternalFunctions */ + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ +/** + * Initializes the Global MSP. + */ +void HAL_MspInit(void) +{ + /* USER CODE BEGIN MspInit 0 */ + + /* USER CODE END MspInit 0 */ + + /* System interrupt init*/ + + /* USER CODE BEGIN MspInit 1 */ + + /* USER CODE END MspInit 1 */ +} + +/** +* @brief ADC MSP Initialization +* This function configures the hardware resources used in this example +* @param hadc: ADC handle pointer +* @retval None +*/ +void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + if(hadc->Instance==ADC1) + { + /* USER CODE BEGIN ADC1_MspInit 0 */ + + /* USER CODE END ADC1_MspInit 0 */ + + /** Initializes the peripherals clock + */ + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_ADCDAC; + PeriphClkInitStruct.AdcDacClockSelection = RCC_ADCDACCLKSOURCE_HCLK; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) + { + Error_Handler(); + } + + /* Peripheral clock enable */ + __HAL_RCC_ADC_CLK_ENABLE(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**ADC1 GPIO Configuration + PA4 ------> ADC1_INP18 + */ + GPIO_InitStruct.Pin = VBUS_SENSE_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(VBUS_SENSE_GPIO_Port, &GPIO_InitStruct); + + /* USER CODE BEGIN ADC1_MspInit 1 */ + + /* USER CODE END ADC1_MspInit 1 */ + } + +} + +/** +* @brief ADC MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hadc: ADC handle pointer +* @retval None +*/ +void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc) +{ + if(hadc->Instance==ADC1) + { + /* USER CODE BEGIN ADC1_MspDeInit 0 */ + + /* USER CODE END ADC1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_ADC_CLK_DISABLE(); + + /**ADC1 GPIO Configuration + PA4 ------> ADC1_INP18 + */ + HAL_GPIO_DeInit(VBUS_SENSE_GPIO_Port, VBUS_SENSE_Pin); + + /* USER CODE BEGIN ADC1_MspDeInit 1 */ + + /* USER CODE END ADC1_MspDeInit 1 */ + } + +} + +/** +* @brief ETH MSP Initialization +* This function configures the hardware resources used in this example +* @param heth: ETH handle pointer +* @retval None +*/ +void HAL_ETH_MspInit(ETH_HandleTypeDef* heth) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(heth->Instance==ETH) + { + /* USER CODE BEGIN ETH_MspInit 0 */ + + /* USER CODE END ETH_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_ETH_CLK_ENABLE(); + __HAL_RCC_ETHTX_CLK_ENABLE(); + __HAL_RCC_ETHRX_CLK_ENABLE(); + + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOG_CLK_ENABLE(); + /**ETH GPIO Configuration + PC1 ------> ETH_MDC + PA1 ------> ETH_REF_CLK + PA2 ------> ETH_MDIO + PA7 ------> ETH_CRS_DV + PC4 ------> ETH_RXD0 + PC5 ------> ETH_RXD1 + PB15 ------> ETH_TXD1 + PG11 ------> ETH_TX_EN + PG13 ------> ETH_TXD0 + */ + GPIO_InitStruct.Pin = RMII_MDC_Pin|RMII_RXD0_Pin|RMII_RXD1_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF11_ETH; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = RMII_REF_CLK_Pin|RMII_MDIO_Pin|RMII_CRS_DV_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF11_ETH; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = RMII_TXD1_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF11_ETH; + HAL_GPIO_Init(RMII_TXD1_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = RMII_TXT_EN_Pin|RMI_TXD0_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF11_ETH; + HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); + + /* USER CODE BEGIN ETH_MspInit 1 */ + + /* USER CODE END ETH_MspInit 1 */ + } + +} + +/** +* @brief ETH MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param heth: ETH handle pointer +* @retval None +*/ +void HAL_ETH_MspDeInit(ETH_HandleTypeDef* heth) +{ + if(heth->Instance==ETH) + { + /* USER CODE BEGIN ETH_MspDeInit 0 */ + + /* USER CODE END ETH_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_ETH_CLK_DISABLE(); + __HAL_RCC_ETHTX_CLK_DISABLE(); + __HAL_RCC_ETHRX_CLK_DISABLE(); + + /**ETH GPIO Configuration + PC1 ------> ETH_MDC + PA1 ------> ETH_REF_CLK + PA2 ------> ETH_MDIO + PA7 ------> ETH_CRS_DV + PC4 ------> ETH_RXD0 + PC5 ------> ETH_RXD1 + PB15 ------> ETH_TXD1 + PG11 ------> ETH_TX_EN + PG13 ------> ETH_TXD0 + */ + HAL_GPIO_DeInit(GPIOC, RMII_MDC_Pin|RMII_RXD0_Pin|RMII_RXD1_Pin); + + HAL_GPIO_DeInit(GPIOA, RMII_REF_CLK_Pin|RMII_MDIO_Pin|RMII_CRS_DV_Pin); + + HAL_GPIO_DeInit(RMII_TXD1_GPIO_Port, RMII_TXD1_Pin); + + HAL_GPIO_DeInit(GPIOG, RMII_TXT_EN_Pin|RMI_TXD0_Pin); + + /* USER CODE BEGIN ETH_MspDeInit 1 */ + + /* USER CODE END ETH_MspDeInit 1 */ + } + +} + +/** +* @brief UART MSP Initialization +* This function configures the hardware resources used in this example +* @param huart: UART handle pointer +* @retval None +*/ +void HAL_UART_MspInit(UART_HandleTypeDef* huart) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + if(huart->Instance==LPUART1) + { + /* USER CODE BEGIN LPUART1_MspInit 0 */ + + /* USER CODE END LPUART1_MspInit 0 */ + + /** Initializes the peripherals clock + */ + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPUART1; + PeriphClkInitStruct.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK3; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) + { + Error_Handler(); + } + + /* Peripheral clock enable */ + __HAL_RCC_LPUART1_CLK_ENABLE(); + + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**LPUART1 GPIO Configuration + PB6 ------> LPUART1_TX + PB7 ------> LPUART1_RX + */ + GPIO_InitStruct.Pin = ARD_D1_TX_Pin|ARD_D0_RX_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF8_LPUART1; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* USER CODE BEGIN LPUART1_MspInit 1 */ + + /* USER CODE END LPUART1_MspInit 1 */ + } + else if(huart->Instance==USART3) + { + /* USER CODE BEGIN USART3_MspInit 0 */ + + /* USER CODE END USART3_MspInit 0 */ + + /** Initializes the peripherals clock + */ + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART3; + PeriphClkInitStruct.Usart3ClockSelection = RCC_USART3CLKSOURCE_PCLK1; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) + { + Error_Handler(); + } + + /* Peripheral clock enable */ + __HAL_RCC_USART3_CLK_ENABLE(); + + __HAL_RCC_GPIOD_CLK_ENABLE(); + /**USART3 GPIO Configuration + PD8 ------> USART3_TX + PD9 ------> USART3_RX + */ + GPIO_InitStruct.Pin = T_VCP_TX_Pin|T_VCP_RX_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF7_USART3; + HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); + + /* USER CODE BEGIN USART3_MspInit 1 */ + + /* USER CODE END USART3_MspInit 1 */ + } + +} + +/** +* @brief UART MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param huart: UART handle pointer +* @retval None +*/ +void HAL_UART_MspDeInit(UART_HandleTypeDef* huart) +{ + if(huart->Instance==LPUART1) + { + /* USER CODE BEGIN LPUART1_MspDeInit 0 */ + + /* USER CODE END LPUART1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_LPUART1_CLK_DISABLE(); + + /**LPUART1 GPIO Configuration + PB6 ------> LPUART1_TX + PB7 ------> LPUART1_RX + */ + HAL_GPIO_DeInit(GPIOB, ARD_D1_TX_Pin|ARD_D0_RX_Pin); + + /* USER CODE BEGIN LPUART1_MspDeInit 1 */ + + /* USER CODE END LPUART1_MspDeInit 1 */ + } + else if(huart->Instance==USART3) + { + /* USER CODE BEGIN USART3_MspDeInit 0 */ + + /* USER CODE END USART3_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_USART3_CLK_DISABLE(); + + /**USART3 GPIO Configuration + PD8 ------> USART3_TX + PD9 ------> USART3_RX + */ + HAL_GPIO_DeInit(GPIOD, T_VCP_TX_Pin|T_VCP_RX_Pin); + + /* USER CODE BEGIN USART3_MspDeInit 1 */ + + /* USER CODE END USART3_MspDeInit 1 */ + } + +} + +/** +* @brief PCD MSP Initialization +* This function configures the hardware resources used in this example +* @param hpcd: PCD handle pointer +* @retval None +*/ +void HAL_PCD_MspInit(PCD_HandleTypeDef* hpcd) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + if(hpcd->Instance==USB_DRD_FS) + { + /* USER CODE BEGIN USB_DRD_FS_MspInit 0 */ + + /* USER CODE END USB_DRD_FS_MspInit 0 */ + + /** Initializes the peripherals clock + */ + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; + PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) + { + Error_Handler(); + } + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**USB GPIO Configuration + PA11 ------> USB_DM + PA12 ------> USB_DP + */ + GPIO_InitStruct.Pin = USB_FS_N_Pin|USB_FS_P_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF10_USB; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Peripheral clock enable */ + __HAL_RCC_USB_CLK_ENABLE(); + /* USER CODE BEGIN USB_DRD_FS_MspInit 1 */ + + /* USER CODE END USB_DRD_FS_MspInit 1 */ + } + +} + +/** +* @brief PCD MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hpcd: PCD handle pointer +* @retval None +*/ +void HAL_PCD_MspDeInit(PCD_HandleTypeDef* hpcd) +{ + if(hpcd->Instance==USB_DRD_FS) + { + /* USER CODE BEGIN USB_DRD_FS_MspDeInit 0 */ + + /* USER CODE END USB_DRD_FS_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_USB_CLK_DISABLE(); + + /**USB GPIO Configuration + PA11 ------> USB_DM + PA12 ------> USB_DP + */ + HAL_GPIO_DeInit(GPIOA, USB_FS_N_Pin|USB_FS_P_Pin); + + /* USER CODE BEGIN USB_DRD_FS_MspDeInit 1 */ + + /* USER CODE END USB_DRD_FS_MspDeInit 1 */ + } + +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Src/stm32h5xx_it.c b/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Src/stm32h5xx_it.c new file mode 100644 index 0000000000..9ff21449c3 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Src/stm32h5xx_it.c @@ -0,0 +1,203 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32h5xx_it.c + * @brief Interrupt Service Routines. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "stm32h5xx_it.h" +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* External variables --------------------------------------------------------*/ + +/* USER CODE BEGIN EV */ + +/* USER CODE END EV */ + +/******************************************************************************/ +/* Cortex Processor Interruption and Exception Handlers */ +/******************************************************************************/ +/** + * @brief This function handles Non maskable interrupt. + */ +void NMI_Handler(void) +{ + /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ + + /* USER CODE END NonMaskableInt_IRQn 0 */ + /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ + while (1) + { + } + /* USER CODE END NonMaskableInt_IRQn 1 */ +} + +/** + * @brief This function handles Hard fault interrupt. + */ +void HardFault_Handler(void) +{ + /* USER CODE BEGIN HardFault_IRQn 0 */ + + /* USER CODE END HardFault_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_HardFault_IRQn 0 */ + /* USER CODE END W1_HardFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Memory management fault. + */ +void MemManage_Handler(void) +{ + /* USER CODE BEGIN MemoryManagement_IRQn 0 */ + + /* USER CODE END MemoryManagement_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */ + /* USER CODE END W1_MemoryManagement_IRQn 0 */ + } +} + +/** + * @brief This function handles Prefetch fault, memory access fault. + */ +void BusFault_Handler(void) +{ + /* USER CODE BEGIN BusFault_IRQn 0 */ + + /* USER CODE END BusFault_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_BusFault_IRQn 0 */ + /* USER CODE END W1_BusFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Undefined instruction or illegal state. + */ +void UsageFault_Handler(void) +{ + /* USER CODE BEGIN UsageFault_IRQn 0 */ + + /* USER CODE END UsageFault_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_UsageFault_IRQn 0 */ + /* USER CODE END W1_UsageFault_IRQn 0 */ + } +} + +/** + * @brief This function handles System service call via SWI instruction. + */ +void SVC_Handler(void) +{ + /* USER CODE BEGIN SVCall_IRQn 0 */ + + /* USER CODE END SVCall_IRQn 0 */ + /* USER CODE BEGIN SVCall_IRQn 1 */ + + /* USER CODE END SVCall_IRQn 1 */ +} + +/** + * @brief This function handles Debug monitor. + */ +void DebugMon_Handler(void) +{ + /* USER CODE BEGIN DebugMonitor_IRQn 0 */ + + /* USER CODE END DebugMonitor_IRQn 0 */ + /* USER CODE BEGIN DebugMonitor_IRQn 1 */ + + /* USER CODE END DebugMonitor_IRQn 1 */ +} + +/** + * @brief This function handles Pendable request for system service. + */ +void PendSV_Handler(void) +{ + /* USER CODE BEGIN PendSV_IRQn 0 */ + + /* USER CODE END PendSV_IRQn 0 */ + /* USER CODE BEGIN PendSV_IRQn 1 */ + + /* USER CODE END PendSV_IRQn 1 */ +} + +/** + * @brief This function handles System tick timer. + */ +void SysTick_Handler(void) +{ + /* USER CODE BEGIN SysTick_IRQn 0 */ + + /* USER CODE END SysTick_IRQn 0 */ + HAL_IncTick(); + /* USER CODE BEGIN SysTick_IRQn 1 */ + + /* USER CODE END SysTick_IRQn 1 */ +} + +/******************************************************************************/ +/* STM32H5xx Peripheral Interrupt Handlers */ +/* Add here the Interrupt Handlers for the used peripherals. */ +/* For the available peripheral interrupt handler names, */ +/* please refer to the startup file (startup_stm32h5xx.s). */ +/******************************************************************************/ + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Src/system_stm32h5xx.c b/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Src/system_stm32h5xx.c new file mode 100644 index 0000000000..0c74ae7da0 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/board/CubeMX_Config/Src/system_stm32h5xx.c @@ -0,0 +1,401 @@ +/** + ****************************************************************************** + * @file system_stm32h5xx.c + * @author MCD Application Team + * @brief CMSIS Cortex-M33 Device Peripheral Access Layer System Source File + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + * This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32h5xx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used + * by the user application to setup the SysTick + * timer or configure other parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * After each device reset the HSI (64 MHz) is used as system clock source. + * Then SystemInit() function is called, in "startup_stm32h5xx.s" file, to + * configure the system clock before to branch to main program. + * + * This file configures the system clock as follows: + *============================================================================= + *----------------------------------------------------------------------------- + * System Clock source | HSI + *----------------------------------------------------------------------------- + * SYSCLK(Hz) | 64000000 + *----------------------------------------------------------------------------- + * HCLK(Hz) | 64000000 + *----------------------------------------------------------------------------- + * AHB Prescaler | 1 + *----------------------------------------------------------------------------- + * APB1 Prescaler | 1 + *----------------------------------------------------------------------------- + * APB2 Prescaler | 1 + *----------------------------------------------------------------------------- + * APB3 Prescaler | 1 + *----------------------------------------------------------------------------- + * HSI Division factor | 1 + *----------------------------------------------------------------------------- + * PLL1_SRC | No clock + *----------------------------------------------------------------------------- + * PLL1_M | Prescaler disabled + *----------------------------------------------------------------------------- + * PLL1_N | 129 + *----------------------------------------------------------------------------- + * PLL1_P | 2 + *----------------------------------------------------------------------------- + * PLL1_Q | 2 + *----------------------------------------------------------------------------- + * PLL1_R | 2 + *----------------------------------------------------------------------------- + * PLL1_FRACN | 0 + *----------------------------------------------------------------------------- + * PLL2_SRC | No clock + *----------------------------------------------------------------------------- + * PLL2_M | Prescaler disabled + *----------------------------------------------------------------------------- + * PLL2_N | 129 + *----------------------------------------------------------------------------- + * PLL2_P | 2 + *----------------------------------------------------------------------------- + * PLL2_Q | 2 + *----------------------------------------------------------------------------- + * PLL2_R | 2 + *----------------------------------------------------------------------------- + * PLL2_FRACN | 0 + *----------------------------------------------------------------------------- + * PLL3_SRC | No clock + *----------------------------------------------------------------------------- + * PLL3_M | Prescaler disabled + *----------------------------------------------------------------------------- + * PLL3_N | 129 + *----------------------------------------------------------------------------- + * PLL3_P | 2 + *----------------------------------------------------------------------------- + * PLL3_Q | 2 + *----------------------------------------------------------------------------- + * PLL3_R | 2 + *----------------------------------------------------------------------------- + * PLL3_FRACN | 0 + *----------------------------------------------------------------------------- + *============================================================================= + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup STM32H5xx_system + * @{ + */ + +/** @addtogroup STM32H5xx_System_Private_Includes + * @{ + */ + +#include "stm32h5xx.h" + +/** + * @} + */ + +/** @addtogroup STM32H5xx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32H5xx_System_Private_Defines + * @{ + */ + +#if !defined (HSE_VALUE) + #define HSE_VALUE (25000000UL) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (CSI_VALUE) + #define CSI_VALUE (4000000UL) /*!< Value of the Internal oscillator in Hz*/ +#endif /* CSI_VALUE */ + +#if !defined (HSI_VALUE) + #define HSI_VALUE (64000000UL) /*!< Value of the Internal oscillator in Hz */ +#endif /* HSI_VALUE */ + +/************************* Miscellaneous Configuration ************************/ +/*!< Uncomment the following line if you need to relocate your vector Table in + Internal SRAM. */ +/* #define VECT_TAB_SRAM */ +#define VECT_TAB_OFFSET 0x00U /*!< Vector Table base offset field. + This value must be a multiple of 0x200. */ +/******************************************************************************/ + +/** + * @} + */ + +/** @addtogroup STM32H5xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32H5xx_System_Private_Variables + * @{ + */ + /* The SystemCoreClock variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetHCLKFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency + Note: If you use this function to configure the system clock; then there + is no need to call the 2 first functions listed above, since SystemCoreClock + variable is updated automatically. + */ + uint32_t SystemCoreClock = 64000000U; + + const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U}; + const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U}; +/** + * @} + */ + +/** @addtogroup STM32H5xx_System_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32H5xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system. + * @param None + * @retval None + */ + +void SystemInit(void) +{ + uint32_t reg_opsr; + + /* FPU settings ------------------------------------------------------------*/ + #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + SCB->CPACR |= ((3UL << 20U)|(3UL << 22U)); /* set CP10 and CP11 Full Access */ + #endif + + /* Reset the RCC clock configuration to the default reset state ------------*/ + /* Set HSION bit */ + RCC->CR = RCC_CR_HSION; + + /* Reset CFGR register */ + RCC->CFGR1 = 0U; + RCC->CFGR2 = 0U; + + /* Reset HSEON, HSECSSON, HSEBYP, HSEEXT, HSIDIV, HSIKERON, CSION, CSIKERON, HSI48 and PLLxON bits */ +#if defined(RCC_CR_PLL3ON) + RCC->CR &= ~(RCC_CR_HSEON | RCC_CR_HSECSSON | RCC_CR_HSEBYP | RCC_CR_HSEEXT | RCC_CR_HSIDIV | RCC_CR_HSIKERON | \ + RCC_CR_CSION | RCC_CR_CSIKERON |RCC_CR_HSI48ON | RCC_CR_PLL1ON | RCC_CR_PLL2ON | RCC_CR_PLL3ON); +#else + RCC->CR &= ~(RCC_CR_HSEON | RCC_CR_HSECSSON | RCC_CR_HSEBYP | RCC_CR_HSEEXT | RCC_CR_HSIDIV | RCC_CR_HSIKERON | \ + RCC_CR_CSION | RCC_CR_CSIKERON |RCC_CR_HSI48ON | RCC_CR_PLL1ON | RCC_CR_PLL2ON); +#endif + + /* Reset PLLxCFGR register */ + RCC->PLL1CFGR = 0U; + RCC->PLL2CFGR = 0U; +#if defined(RCC_CR_PLL3ON) + RCC->PLL3CFGR = 0U; +#endif /* RCC_CR_PLL3ON */ + + /* Reset PLL1DIVR register */ + RCC->PLL1DIVR = 0x01010280U; + /* Reset PLL1FRACR register */ + RCC->PLL1FRACR = 0x00000000U; + /* Reset PLL2DIVR register */ + RCC->PLL2DIVR = 0x01010280U; + /* Reset PLL2FRACR register */ + RCC->PLL2FRACR = 0x00000000U; +#if defined(RCC_CR_PLL3ON) + /* Reset PLL3DIVR register */ + RCC->PLL3DIVR = 0x01010280U; + /* Reset PLL3FRACR register */ + RCC->PLL3FRACR = 0x00000000U; +#endif /* RCC_CR_PLL3ON */ + + /* Reset HSEBYP bit */ + RCC->CR &= ~(RCC_CR_HSEBYP); + + /* Disable all interrupts */ + RCC->CIER = 0U; + + /* Configure the Vector Table location add offset address ------------------*/ + #ifdef VECT_TAB_SRAM + SCB->VTOR = SRAM1_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ + #else + SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ + #endif /* VECT_TAB_SRAM */ + + /* Check OPSR register to verify if there is an ongoing swap or option bytes update interrupted by a reset */ + reg_opsr = FLASH->OPSR & FLASH_OPSR_CODE_OP; + if ((reg_opsr == FLASH_OPSR_CODE_OP) || (reg_opsr == (FLASH_OPSR_CODE_OP_2 | FLASH_OPSR_CODE_OP_1))) + { + /* Check FLASH Option Control Register access */ + if ((FLASH->OPTCR & FLASH_OPTCR_OPTLOCK) != 0U) + { + /* Authorizes the Option Byte registers programming */ + FLASH->OPTKEYR = 0x08192A3BU; + FLASH->OPTKEYR = 0x4C5D6E7FU; + } + /* Launch the option bytes change operation */ + FLASH->OPTCR |= FLASH_OPTCR_OPTSTART; + + /* Lock the FLASH Option Control Register access */ + FLASH->OPTCR |= FLASH_OPTCR_OPTLOCK; + } +} + +/** + * @brief Update SystemCoreClock variable according to Clock Register Values. + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any configuration + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is CSI, SystemCoreClock will contain the CSI_VALUE(*) + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***) + * or HSI_VALUE(**) or CSI_VALUE(*) multiplied/divided by the PLL factors. + * + * (*) CSI_VALUE is a constant defined in stm32h5xx_hal.h file (default value + * 4 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (**) HSI_VALUE is a constant defined in stm32h5xx_hal.h file (default value + * 64 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (***) HSE_VALUE is a constant defined in stm32h5xx_hal.h file (default value + * 25 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @param None + * @retval None + */ +void SystemCoreClockUpdate(void) +{ + uint32_t pllp, pllsource, pllm, pllfracen, hsivalue, tmp; + float_t fracn1, pllvco; + + /* Get SYSCLK source -------------------------------------------------------*/ + switch (RCC->CFGR1 & RCC_CFGR1_SWS) + { + case 0x00UL: /* HSI used as system clock source */ + SystemCoreClock = (uint32_t) (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3)); + break; + + case 0x08UL: /* CSI used as system clock source */ + SystemCoreClock = CSI_VALUE; + break; + + case 0x10UL: /* HSE used as system clock source */ + SystemCoreClock = HSE_VALUE; + break; + + case 0x18UL: /* PLL1 used as system clock source */ + /* PLL_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN + SYSCLK = PLL_VCO / PLLR + */ + pllsource = (RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1SRC); + pllm = ((RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1M)>> RCC_PLL1CFGR_PLL1M_Pos); + pllfracen = ((RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1FRACEN)>>RCC_PLL1CFGR_PLL1FRACEN_Pos); + fracn1 = (float_t)(uint32_t)(pllfracen* ((RCC->PLL1FRACR & RCC_PLL1FRACR_PLL1FRACN)>> RCC_PLL1FRACR_PLL1FRACN_Pos)); + + switch (pllsource) + { + case 0x01UL: /* HSI used as PLL clock source */ + hsivalue = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3)) ; + pllvco = ((float_t)hsivalue / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \ + (fracn1/(float_t)0x2000) +(float_t)1 ); + break; + + case 0x02UL: /* CSI used as PLL clock source */ + pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \ + (fracn1/(float_t)0x2000) +(float_t)1 ); + break; + + case 0x03UL: /* HSE used as PLL clock source */ + pllvco = ((float_t)HSE_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \ + (fracn1/(float_t)0x2000) +(float_t)1 ); + break; + + default: /* No clock sent to PLL*/ + pllvco = (float_t) 0U; + break; + } + + pllp = (((RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1P) >>RCC_PLL1DIVR_PLL1P_Pos) + 1U ) ; + SystemCoreClock = (uint32_t)(float_t)(pllvco/(float_t)pllp); + + break; + + default: + SystemCoreClock = HSI_VALUE; + break; + } + /* Compute HCLK clock frequency --------------------------------------------*/ + /* Get HCLK prescaler */ + tmp = AHBPrescTable[((RCC->CFGR2 & RCC_CFGR2_HPRE) >> RCC_CFGR2_HPRE_Pos)]; + /* HCLK clock frequency */ + SystemCoreClock >>= tmp; +} + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + diff --git a/bsp/stm32/stm32h563-st-nucleo/board/Kconfig b/bsp/stm32/stm32h563-st-nucleo/board/Kconfig new file mode 100644 index 0000000000..a071b60d3e --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/board/Kconfig @@ -0,0 +1,67 @@ +menu "Hardware Drivers Config" + +config SOC_STM32H563ZI + bool + select SOC_SERIES_STM32H5 + select RT_USING_COMPONENTS_INIT + select RT_USING_USER_MAIN + default y + +menu "On-chip Peripheral Drivers" + + config BSP_USING_GPIO + bool "Enable GPIO" + select RT_USING_PIN + default y + + menuconfig BSP_USING_UART + bool "Enable UART" + default y + select RT_USING_SERIAL + if BSP_USING_UART + config BSP_USING_UART1 + bool "Enable UART1" + default y + + config BSP_UART1_RX_USING_DMA + bool "Enable UART1 RX DMA" + depends on BSP_USING_UART1 && RT_SERIAL_USING_DMA + default n + + config BSP_USING_UART2 + bool "Enable UART2" + default y + + config BSP_UART2_RX_USING_DMA + bool "Enable UART2 RX DMA" + depends on BSP_USING_UART2 && RT_SERIAL_USING_DMA + default n + + config BSP_USING_UART3 + bool "Enable UART3" + default y + + config BSP_UART3_RX_USING_DMA + bool "Enable UART3 RX DMA" + depends on BSP_USING_UART3 && RT_SERIAL_USING_DMA + default n + + config BSP_USING_LPUART1 + bool "Enable LPUART1" + default y + + config BSP_LPUART1_RX_USING_DMA + bool "Enable LPUART1 RX DMA" + depends on BSP_USING_LPUART1 && RT_SERIAL_USING_DMA + default n + endif + + source "../libraries/HAL_Drivers/Kconfig" + +endmenu + +menu "Board extended module Drivers" + +endmenu + +endmenu diff --git a/bsp/stm32/stm32h563-st-nucleo/board/SConscript b/bsp/stm32/stm32h563-st-nucleo/board/SConscript new file mode 100644 index 0000000000..b1772de703 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/board/SConscript @@ -0,0 +1,38 @@ +import os +import rtconfig +from building import * + +Import('SDK_LIB') + +cwd = GetCurrentDir() + +# add general drivers +src = Split(''' +board.c +CubeMX_Config/Src/stm32h5xx_hal_msp.c +''') + +if GetDepend(['BSP_USING_KEY']): + src += Glob('ports/drv_key.c') + +if GetDepend(['BSP_USING_SPI_FLASH']): + src += Glob('ports/drv_spi_flash.c') + +path = [cwd] +path += [cwd + '/CubeMX_Config/Inc'] + +startup_path_prefix = SDK_LIB + +if rtconfig.PLATFORM in ['gcc']: + src += [startup_path_prefix + '/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/gcc/startup_stm32h563xx.s'] +elif rtconfig.PLATFORM in ['armcc', 'armclang']: + src += [startup_path_prefix + '/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/arm/startup_stm32h563xx.s'] +elif rtconfig.PLATFORM in ['iccarm']: + src += [startup_path_prefix + '/STM32H5xx_HAL/CMSIS/Device/ST/STM32H5xx/Source/Templates/iar/startup_stm32h563xx.s'] + +# You can select chips from the list above +CPPDEFINES = ['STM32H563xx'] +group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES) + +Return('group') + diff --git a/bsp/stm32/stm32h563-st-nucleo/board/board.c b/bsp/stm32/stm32h563-st-nucleo/board/board.c new file mode 100644 index 0000000000..dd1d2dc99e --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/board/board.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-11-06 SummerGift first version + */ + +#include "board.h" + +/** + * @brief System Clock Configuration + * @retval None + */ +void SystemClock_Config(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + + /** Configure the main internal regulator output voltage + */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0); + + while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {} + + /** Initializes the RCC Oscillators according to the specified parameters + * in the RCC_OscInitTypeDef structure. + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSI + |RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS_DIGITAL; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1; + RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLL1_SOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = 4; + RCC_OscInitStruct.PLL.PLLN = 250; + RCC_OscInitStruct.PLL.PLLP = 2; + RCC_OscInitStruct.PLL.PLLQ = 2; + RCC_OscInitStruct.PLL.PLLR = 2; + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1_VCIRANGE_1; + RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1_VCORANGE_WIDE; + RCC_OscInitStruct.PLL.PLLFRACN = 0; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + Error_Handler(); + } + + /** Initializes the CPU, AHB and APB buses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK + |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2 + |RCC_CLOCKTYPE_PCLK3; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) + { + Error_Handler(); + } +} diff --git a/bsp/stm32/stm32h563-st-nucleo/board/board.h b/bsp/stm32/stm32h563-st-nucleo/board/board.h new file mode 100644 index 0000000000..55131f5584 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/board/board.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-11-5 SummerGift first version + * 2019-04-24 yangjie Use the end of ZI as HEAP_BEGIN + */ + +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#include +#include +#include "drv_common.h" +#include "drv_gpio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define STM32_FLASH_START_ADRESS ((uint32_t)0x08000000) +#define STM32_FLASH_SIZE (2048 * 1024) +#define STM32_FLASH_END_ADDRESS ((uint32_t)(STM32_FLASH_START_ADRESS + STM32_FLASH_SIZE)) + +#define STM32_SRAM1_SIZE (640) +#define STM32_SRAM1_START (0x20000000) +#define STM32_SRAM1_END (STM32_SRAM1_START + STM32_SRAM1_SIZE * 1024) + +#if defined(__ARMCC_VERSION) +extern int Image$$RW_IRAM1$$ZI$$Limit; +#define HEAP_BEGIN ((void *)&Image$$RW_IRAM1$$ZI$$Limit) +#elif __ICCARM__ +#pragma section="CSTACK" +#define HEAP_BEGIN (__segment_end("CSTACK")) +#else +extern int __bss_end; +#define HEAP_BEGIN ((void *)&__bss_end) +#endif + +#define HEAP_END STM32_SRAM1_END + +void SystemClock_Config(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/bsp/stm32/stm32h563-st-nucleo/board/linker_scripts/link.icf b/bsp/stm32/stm32h563-st-nucleo/board/linker_scripts/link.icf new file mode 100644 index 0000000000..dd72230153 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/board/linker_scripts/link.icf @@ -0,0 +1,29 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x08000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x081FFFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x2009FFFF; + +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x0400; +define symbol __ICFEDIT_size_heap__ = 0x000; +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, last block CSTACK}; diff --git a/bsp/stm32/stm32h563-st-nucleo/board/linker_scripts/link.lds b/bsp/stm32/stm32h563-st-nucleo/board/linker_scripts/link.lds new file mode 100644 index 0000000000..9618ecdbd5 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/board/linker_scripts/link.lds @@ -0,0 +1,156 @@ +/* + * linker script for STM32L4XX with GNU ld + */ + +/* Program Entry, set to mark it as "used" and avoid gc */ +MEMORY +{ + ROM (rx) : ORIGIN = 0x08000000, LENGTH = 2048k /* 2048KB flash */ + RAM (rw) : ORIGIN = 0x20000000, LENGTH = 640k /* 640KB sram */ +} +ENTRY(Reset_Handler) +_system_stack_size = 0x400; + +SECTIONS +{ + .text : + { + . = ALIGN(4); + _stext = .; + KEEP(*(.isr_vector)) /* Startup code */ + + . = ALIGN(4); + *(.text) /* remaining code */ + *(.text.*) /* remaining code */ + *(.rodata) /* read-only data (constants) */ + *(.rodata*) + *(.glue_7) + *(.glue_7t) + *(.gnu.linkonce.t*) + + /* section information for finsh shell */ + . = ALIGN(4); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + + . = ALIGN(4); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + + /* section information for initial. */ + . = ALIGN(4); + __rt_init_start = .; + KEEP(*(SORT(.rti_fn*))) + __rt_init_end = .; + + . = ALIGN(4); + + PROVIDE(__ctors_start__ = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + PROVIDE(__ctors_end__ = .); + + . = ALIGN(4); + + _etext = .; + } > ROM = 0 + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + + /* This is used by the startup in order to initialize the .data secion */ + _sidata = .; + } > ROM + __exidx_end = .; + + /* .data section which is used for initialized data */ + + .data : AT (_sidata) + { + . = ALIGN(4); + /* This is used by the startup in order to initialize the .data secion */ + _sdata = . ; + + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + + PROVIDE(__dtors_start__ = .); + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + PROVIDE(__dtors_end__ = .); + + . = ALIGN(4); + /* This is used by the startup in order to initialize the .data secion */ + _edata = . ; + } > RAM + + .stack : + { + . = ALIGN(4); + _sstack = .; + . = . + _system_stack_size; + . = ALIGN(4); + _estack = .; + } > RAM + + __bss_start = .; + .bss : + { + . = ALIGN(4); + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; + + *(.bss) + *(.bss.*) + *(COMMON) + + . = ALIGN(4); + /* This is used by the startup in order to initialize the .bss secion */ + _ebss = . ; + + *(.bss.init) + } > RAM + __bss_end = .; + + _end = .; + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + * Symbols in the DWARF debugging sections are relative to the beginning + * of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } +} diff --git a/bsp/stm32/stm32h563-st-nucleo/board/linker_scripts/link.sct b/bsp/stm32/stm32h563-st-nucleo/board/linker_scripts/link.sct new file mode 100644 index 0000000000..d883eeda50 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/board/linker_scripts/link.sct @@ -0,0 +1,15 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; ************************************************************* + +LR_IROM1 0x08000000 0x00200000 { ; load region size_region + ER_IROM1 0x08000000 0x00200000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + RW_IRAM1 0x20000000 0x000A0000 { ; RW data + .ANY (+RW +ZI) + } +} diff --git a/bsp/stm32/stm32h563-st-nucleo/board/ports/drv_key.c b/bsp/stm32/stm32h563-st-nucleo/board/ports/drv_key.c new file mode 100644 index 0000000000..dcb1404a4b --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/board/ports/drv_key.c @@ -0,0 +1,276 @@ +/** + * @File: flexible_button_demo.c + * @Author: MurphyZhao + * @Date: 2018-09-29 + * + * Copyright (c) 2018-2019 MurphyZhao + * https://github.com/murphyzhao + * All rights reserved. + * License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Change logs: + * Date Author Notes + * 2018-09-29 MurphyZhao First add + * 2019-08-02 MurphyZhao 迁移代码到 murphyzhao 仓库 +*/ + +#include +#include "flexible_button.h" +#include +#include +#include + +/*The button PIN_KEY0,PIN_KEY1,PIN_KEY2 are an expansion button,which users can add according to their needs*/ +#define PIN_KEY0 GET_PIN(D,10) +#define PIN_KEY1 GET_PIN(D,9) +#define PIN_KEY2 GET_PIN(D,8) +#define PIN_WK_UP GET_PIN(C,13) + +typedef enum +{ + USER_BUTTON_0 = 0, + USER_BUTTON_1, + USER_BUTTON_2, + USER_BUTTON_3, + USER_BUTTON_MAX +} user_button_t; + +static flex_button_t user_button[USER_BUTTON_MAX]; + +static void btn_0_cb(flex_button_t *btn) +{ + rt_kprintf("btn_0_cb\n"); + switch (btn->event) + { + case FLEX_BTN_PRESS_DOWN: + rt_kprintf("btn_0_cb [FLEX_BTN_PRESS_DOWN]\n"); + break; + case FLEX_BTN_PRESS_CLICK: + rt_kprintf("btn_0_cb [FLEX_BTN_PRESS_CLICK]\n"); + break; + case FLEX_BTN_PRESS_DOUBLE_CLICK: + rt_kprintf("btn_0_cb [FLEX_BTN_PRESS_DOUBLE_CLICK]\n"); + break; + case FLEX_BTN_PRESS_SHORT_START: + rt_kprintf("btn_0_cb [FLEX_BTN_PRESS_SHORT_START]\n"); + break; + case FLEX_BTN_PRESS_SHORT_UP: + rt_kprintf("btn_0_cb [FLEX_BTN_PRESS_SHORT_UP]\n"); + break; + case FLEX_BTN_PRESS_LONG_START: + rt_kprintf("btn_0_cb [FLEX_BTN_PRESS_LONG_START]\n"); + break; + case FLEX_BTN_PRESS_LONG_UP: + rt_kprintf("btn_0_cb [FLEX_BTN_PRESS_LONG_UP]\n"); + break; + case FLEX_BTN_PRESS_LONG_HOLD: + rt_kprintf("btn_0_cb [FLEX_BTN_PRESS_LONG_HOLD]\n"); + break; + case FLEX_BTN_PRESS_LONG_HOLD_UP: + rt_kprintf("btn_0_cb [FLEX_BTN_PRESS_LONG_HOLD_UP]\n"); + break; + } +} + +static void btn_1_cb(flex_button_t *btn) +{ + rt_kprintf("btn_1_cb\n"); + switch (btn->event) + { + case FLEX_BTN_PRESS_DOWN: + rt_kprintf("btn_1_cb [FLEX_BTN_PRESS_DOWN]\n"); + break; + case FLEX_BTN_PRESS_CLICK: + rt_kprintf("btn_1_cb [FLEX_BTN_PRESS_CLICK]\n"); + break; + case FLEX_BTN_PRESS_DOUBLE_CLICK: + rt_kprintf("btn_1_cb [FLEX_BTN_PRESS_DOUBLE_CLICK]\n"); + break; + case FLEX_BTN_PRESS_SHORT_START: + rt_kprintf("btn_1_cb [FLEX_BTN_PRESS_SHORT_START]\n"); + break; + case FLEX_BTN_PRESS_SHORT_UP: + rt_kprintf("btn_1_cb [FLEX_BTN_PRESS_SHORT_UP]\n"); + break; + case FLEX_BTN_PRESS_LONG_START: + rt_kprintf("btn_1_cb [FLEX_BTN_PRESS_LONG_START]\n"); + break; + case FLEX_BTN_PRESS_LONG_UP: + rt_kprintf("btn_1_cb [FLEX_BTN_PRESS_LONG_UP]\n"); + break; + case FLEX_BTN_PRESS_LONG_HOLD: + rt_kprintf("btn_1_cb [FLEX_BTN_PRESS_LONG_HOLD]\n"); + break; + case FLEX_BTN_PRESS_LONG_HOLD_UP: + rt_kprintf("btn_1_cb [FLEX_BTN_PRESS_LONG_HOLD_UP]\n"); + break; + } +} + +static void btn_2_cb(flex_button_t *btn) +{ + rt_kprintf("btn_2_cb\n"); + switch (btn->event) + { + case FLEX_BTN_PRESS_DOWN: + rt_kprintf("btn_2_cb [FLEX_BTN_PRESS_DOWN]\n"); + break; + case FLEX_BTN_PRESS_CLICK: + rt_kprintf("btn_2_cb [FLEX_BTN_PRESS_CLICK]\n"); + break; + case FLEX_BTN_PRESS_DOUBLE_CLICK: + rt_kprintf("btn_2_cb [FLEX_BTN_PRESS_DOUBLE_CLICK]\n"); + break; + case FLEX_BTN_PRESS_SHORT_START: + rt_kprintf("btn_2_cb [FLEX_BTN_PRESS_SHORT_START]\n"); + break; + case FLEX_BTN_PRESS_SHORT_UP: + rt_kprintf("btn_2_cb [FLEX_BTN_PRESS_SHORT_UP]\n"); + break; + case FLEX_BTN_PRESS_LONG_START: + rt_kprintf("btn_2_cb [FLEX_BTN_PRESS_LONG_START]\n"); + break; + case FLEX_BTN_PRESS_LONG_UP: + rt_kprintf("btn_2_cb [FLEX_BTN_PRESS_LONG_UP]\n"); + break; + case FLEX_BTN_PRESS_LONG_HOLD: + rt_kprintf("btn_2_cb [FLEX_BTN_PRESS_LONG_HOLD]\n"); + break; + case FLEX_BTN_PRESS_LONG_HOLD_UP: + rt_kprintf("btn_2_cb [FLEX_BTN_PRESS_LONG_HOLD_UP]\n"); + break; + } +} + + +static void btn_3_cb(flex_button_t *btn) +{ + rt_kprintf("btn_3_cb\n"); + switch (btn->event) + { + case FLEX_BTN_PRESS_DOWN: + rt_kprintf("btn_3_cb [FLEX_BTN_PRESS_DOWN]\n"); + break; + case FLEX_BTN_PRESS_CLICK: + rt_kprintf("btn_3_cb [FLEX_BTN_PRESS_CLICK]\n"); + break; + case FLEX_BTN_PRESS_DOUBLE_CLICK: + rt_kprintf("btn_3_cb [FLEX_BTN_PRESS_DOUBLE_CLICK]\n"); + break; + case FLEX_BTN_PRESS_SHORT_START: + rt_kprintf("btn_3_cb [FLEX_BTN_PRESS_SHORT_START]\n"); + break; + case FLEX_BTN_PRESS_SHORT_UP: + rt_kprintf("btn_3_cb [FLEX_BTN_PRESS_SHORT_UP]\n"); + break; + case FLEX_BTN_PRESS_LONG_START: + rt_kprintf("btn_3_cb [FLEX_BTN_PRESS_LONG_START]\n"); + break; + case FLEX_BTN_PRESS_LONG_UP: + rt_kprintf("btn_3_cb [FLEX_BTN_PRESS_LONG_UP]\n"); + break; + case FLEX_BTN_PRESS_LONG_HOLD: + rt_kprintf("btn_3_cb [FLEX_BTN_PRESS_LONG_HOLD]\n"); + break; + case FLEX_BTN_PRESS_LONG_HOLD_UP: + rt_kprintf("btn_3_cb [FLEX_BTN_PRESS_LONG_HOLD_UP]\n"); + break; + } +} + + + +static uint8_t button_key0_read(void) +{ + return rt_pin_read(PIN_KEY0); +} + +static uint8_t button_key1_read(void) +{ + return rt_pin_read(PIN_KEY1); +} + +static uint8_t button_key2_read(void) +{ + return rt_pin_read(PIN_KEY2); +} + +static uint8_t button_keywkup_read(void) +{ + return rt_pin_read(PIN_WK_UP); +} + +static void button_scan(void *arg) +{ + while(1) + { + flex_button_scan(); + rt_thread_mdelay(20); + } +} + +static void user_button_init(void) +{ + int i; + + rt_memset(&user_button[0], 0x0, sizeof(user_button)); + + user_button[USER_BUTTON_0].usr_button_read = button_key0_read; + user_button[USER_BUTTON_1].usr_button_read = button_key1_read; + user_button[USER_BUTTON_2].usr_button_read = button_key2_read; + + user_button[USER_BUTTON_3].usr_button_read = button_keywkup_read; + user_button[USER_BUTTON_3].cb = (flex_button_response_callback)btn_3_cb; + + rt_pin_mode(PIN_KEY0, PIN_MODE_INPUT); /* set KEY pin mode to input */ + rt_pin_mode(PIN_KEY1, PIN_MODE_INPUT); /* set KEY pin mode to input */ + rt_pin_mode(PIN_KEY2, PIN_MODE_INPUT); /* set KEY pin mode to input */ + rt_pin_mode(PIN_WK_UP, PIN_MODE_INPUT); /* set KEY pin mode to input */ + + for (i = 0; i < USER_BUTTON_MAX; i ++) + { + user_button[i].pressed_logic_level = 0; + user_button[i].click_start_tick = 20; + user_button[i].short_press_start_tick = 100; + user_button[i].long_press_start_tick = 200; + user_button[i].long_hold_start_tick = 300; + + if (i == USER_BUTTON_3) + { + user_button[USER_BUTTON_3].pressed_logic_level = 1; + } + + flex_button_register(&user_button[i]); + } +} + +int flex_button_main(void) +{ + rt_thread_t tid = RT_NULL; + + user_button_init(); + + /* Create background ticks thread */ + tid = rt_thread_create("flex_btn", button_scan, RT_NULL, 1024, 10, 10); + if(tid != RT_NULL) + { + rt_thread_startup(tid); + } + + return 0; +} +#ifdef FINSH_USING_MSH +INIT_APP_EXPORT(flex_button_main); +#endif diff --git a/bsp/stm32/stm32h563-st-nucleo/board/ports/drv_spi_flash.c b/bsp/stm32/stm32h563-st-nucleo/board/ports/drv_spi_flash.c new file mode 100644 index 0000000000..d2566f7d82 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/board/ports/drv_spi_flash.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-11-27 zylx first version + */ + +#include +#include +#include +#include +#include +#include + +#ifdef BSP_USING_SPI_FLASH + +#include "spi_flash.h" +#include "spi_flash_sfud.h" + +static int rt_hw_spi_flash_init(void) +{ + + rt_hw_spi_device_attach("spi1", "spi10", 24); // CS:PB8 + + if (RT_NULL == rt_sfud_flash_probe("W25Q128", "spi10")) + { + return -RT_ERROR; + }; + + return RT_EOK; +} +INIT_COMPONENT_EXPORT(rt_hw_spi_flash_init); + +#if defined(RT_USING_DFS_ELMFAT) && !defined(BSP_USING_SDCARD) +#include + +#define BLK_DEV_NAME "W25Q128" + +int mnt_init(void) +{ + rt_thread_delay(RT_TICK_PER_SECOND); + + if (dfs_mount(BLK_DEV_NAME, "/", "elm", 0, 0) == 0) + { + rt_kprintf("file system initialization done!\n"); + } + else + { + if(dfs_mkfs("elm", BLK_DEV_NAME) == 0) + { + if (dfs_mount(BLK_DEV_NAME, "/", "elm", 0, 0) == 0) + { + rt_kprintf("file system initialization done!\n"); + } + else + { + rt_kprintf("file system initialization failed!\n"); + } + } + } + + return 0; +} +INIT_ENV_EXPORT(mnt_init); + +#endif /* defined(RT_USING_DFS_ELMFAT) && !defined(BSP_USING_SDCARD) */ +#endif /* BSP_USING_SPI_FLASH */ diff --git a/bsp/stm32/stm32h563-st-nucleo/context_rvds.lst b/bsp/stm32/stm32h563-st-nucleo/context_rvds.lst new file mode 100644 index 0000000000..9a85aa2ef1 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/context_rvds.lst @@ -0,0 +1,779 @@ + + + +ARM Macro Assembler Page 1 + + + 1 00000000 ;/* + 2 00000000 ;* Copyright (c) 2006-2018, RT-Thread Development Team + 3 00000000 ;* + 4 00000000 ;* SPDX-License-Identifier: Apache-2.0 + 5 00000000 ;* + 6 00000000 ; * Change Logs: + 7 00000000 ; * Date Author Notes + 8 00000000 ; * 2009-01-17 Bernard first version. + 9 00000000 ; * 2012-01-01 aozima support context switch l + oad/store FPU register. + 10 00000000 ; * 2013-06-18 aozima add restore MSP feature. + + 11 00000000 ; * 2013-06-23 aozima support lazy stack optim + ized. + 12 00000000 ; * 2018-07-24 aozima enhancement hard fault e + xception handler. + 13 00000000 ; */ + 14 00000000 + 15 00000000 ;/** + 16 00000000 ; * @addtogroup cortex-m33 + 17 00000000 ; */ + 18 00000000 ;/*@{*/ + 19 00000000 + 20 00000000 E000ED08 + SCB_VTOR + EQU 0xE000ED08 ; Vector Table Offs + et Register + 21 00000000 E000ED04 + NVIC_INT_CTRL + EQU 0xE000ED04 ; interrupt control + state register + 22 00000000 E000ED20 + NVIC_SYSPRI2 + EQU 0xE000ED20 ; system priority r + egister (2) + 23 00000000 FFFF0000 + NVIC_PENDSV_PRI + EQU 0xFFFF0000 ; PendSV and SysTic + k priority value (l + owest) + 24 00000000 10000000 + NVIC_PENDSVSET + EQU 0x10000000 ; value to trigger + PendSV exception + 25 00000000 + 26 00000000 AREA |.text|, CODE, READONLY, ALIGN= +2 + 27 00000000 THUMB + 28 00000000 REQUIRE8 + 29 00000000 PRESERVE8 + 30 00000000 + 31 00000000 IMPORT rt_thread_switch_interrupt_flag + 32 00000000 IMPORT rt_interrupt_from_thread + 33 00000000 IMPORT rt_interrupt_to_thread + 34 00000000 IMPORT rt_trustzone_current_context + 35 00000000 IMPORT rt_trustzone_context_load + 36 00000000 IMPORT rt_trustzone_context_store + 37 00000000 + 38 00000000 ;/* + + + +ARM Macro Assembler Page 2 + + + 39 00000000 ; * rt_base_t rt_hw_interrupt_disable(); + 40 00000000 ; */ + 41 00000000 rt_hw_interrupt_disable + PROC + 42 00000000 EXPORT rt_hw_interrupt_disable + 43 00000000 F3EF 8010 MRS r0, PRIMASK + 44 00000004 B672 CPSID I + 45 00000006 4770 BX LR + 46 00000008 ENDP + 47 00000008 + 48 00000008 ;/* + 49 00000008 ; * void rt_hw_interrupt_enable(rt_base_t level); + 50 00000008 ; */ + 51 00000008 rt_hw_interrupt_enable + PROC + 52 00000008 EXPORT rt_hw_interrupt_enable + 53 00000008 F380 8810 MSR PRIMASK, r0 + 54 0000000C 4770 BX LR + 55 0000000E ENDP + 56 0000000E + 57 0000000E ;/* + 58 0000000E ; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 + to); + 59 0000000E ; * r0 --> from + 60 0000000E ; * r1 --> to + 61 0000000E ; */ + 62 0000000E rt_hw_context_switch_interrupt + 63 0000000E EXPORT rt_hw_context_switch_interrupt + 64 0000000E rt_hw_context_switch + PROC + 65 0000000E EXPORT rt_hw_context_switch + 66 0000000E + 67 0000000E ; set rt_thread_switch_interrupt_flag to 1 + 68 0000000E 4A5D LDR r2, =rt_thread_switch_interrupt +_flag + 69 00000010 6813 LDR r3, [r2] + 70 00000012 2B01 CMP r3, #1 + 71 00000014 D004 BEQ _reswitch + 72 00000016 F04F 0301 MOV r3, #1 + 73 0000001A 6013 STR r3, [r2] + 74 0000001C + 75 0000001C 4A5A LDR r2, =rt_interrupt_from_thread ; + set rt_interrupt_f + rom_thread + 76 0000001E 6010 STR r0, [r2] + 77 00000020 + 78 00000020 _reswitch + 79 00000020 4A5A LDR r2, =rt_interrupt_to_thread ; s + et rt_interrupt_to_ + thread + 80 00000022 6011 STR r1, [r2] + 81 00000024 + 82 00000024 485A LDR r0, =NVIC_INT_CTRL ; trigger th + e PendSV exception + (causes context swi + tch) + 83 00000026 F04F 5180 LDR r1, =NVIC_PENDSVSET + 84 0000002A 6001 STR r1, [r0] + 85 0000002C 4770 BX LR + + + +ARM Macro Assembler Page 3 + + + 86 0000002E ENDP + 87 0000002E + 88 0000002E ; r0 --> switch from thread stack + 89 0000002E ; r1 --> switch to thread stack + 90 0000002E ; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from + ] stack + 91 0000002E PendSV_Handler + PROC + 92 0000002E EXPORT PendSV_Handler + 93 0000002E + 94 0000002E ; disable interrupt to protect context switch + 95 0000002E F3EF 8210 MRS r2, PRIMASK ; R2 = PRIMASK + 96 00000032 B672 CPSID I ; disable all inter + rupt + 97 00000034 + 98 00000034 ; get rt_thread_switch_interrupt_flag + 99 00000034 4853 LDR r0, =rt_thread_switch_interrupt +_flag + ; r0 = &rt_thread_s + witch_interrupt_fla + g + 100 00000036 6801 LDR r1, [r0] ; r1 = *r1 + 101 00000038 2900 CMP r1, #0x00 ; compare r1 == 0x0 + 0 + 102 0000003A D102 BNE schedule + 103 0000003C F382 8810 MSR PRIMASK, r2 ; if r1 == 0x00, do + msr PRIMASK, r2 + 104 00000040 4770 BX lr ; if r1 == 0x00, do + bx lr + 105 00000042 + 106 00000042 schedule + 107 00000042 B404 PUSH {r2} ; store interrupt s + tate + 108 00000044 + 109 00000044 ; clear rt_thread_switch_interrupt_flag to 0 + 110 00000044 F04F 0100 MOV r1, #0x00 ; r1 = 0x00 + 111 00000048 6001 STR r1, [r0] ; *r0 = r1 + 112 0000004A + 113 0000004A ; skip register save at the first time + 114 0000004A 484F LDR r0, =rt_interrupt_from_thread ; + r0 = &rt_interrupt + _from_thread + 115 0000004C 6801 LDR r1, [r0] ; r1 = *r0 + 116 0000004E B359 CBZ r1, switch_to_thread ; if r1 == + 0, goto switch_to_ + thread + 117 00000050 + 118 00000050 ; Whether TrustZone thread stack exists + 119 00000050 4950 LDR r1, =rt_trustzone_current_cont +ext + ; r1 = &rt_secure_c + urrent_context + 120 00000052 6809 LDR r1, [r1] ; r1 = *r1 + 121 00000054 B1A1 CBZ r1, contex_ns_store ; if r1 == + 0, goto contex_ns_s + tore + 122 00000056 + 123 00000056 ;call TrustZone fun, Save TrustZone stack + 124 00000056 B503 STMFD sp!, {r0-r1, lr} + + + +ARM Macro Assembler Page 4 + + + ; push register + 125 00000058 4608 MOV r0, r1 ; r0 = rt_secure_cu + rrent_context + 126 0000005A F7FF FFFE BL rt_trustzone_context_store ; ca + ll TrustZone store + fun + 127 0000005E E8BD 4003 LDMFD sp!, {r0-r1, lr} ; pop register + + 128 00000062 + 129 00000062 ; check break from TrustZone + 130 00000062 4672 MOV r2, lr ; r2 = lr + 131 00000064 F012 0F40 TST r2, #0x40 ; if EXC_RETURN[6] + is 1, TrustZone sta + ck was used + 132 00000068 D00A BEQ contex_ns_store ; if r2 & 0x40 + == 0, goto contex_n + s_store + 133 0000006A + 134 0000006A ; push PSPLIM CONTROL PSP LR current_context to stack + 135 0000006A F3EF 830B MRS r3, psplim ; r3 = psplim + 136 0000006E F3EF 8414 MRS r4, control ; r4 = control + 137 00000072 F3EF 8509 MRS r5, psp ; r5 = psp + 138 00000076 E925 001E STMFD r5!, {r1-r4} ; push to thread s + tack + 139 0000007A + 140 0000007A ; update from thread stack pointer + 141 0000007A 6800 LDR r0, [r0] ; r0 = rt_thread_sw + itch_interrupt_flag + + 142 0000007C 6005 STR r5, [r0] ; *r0 = r5 + 143 0000007E E013 b switch_to_thread ; goto switch_ + to_thread + 144 00000080 + 145 00000080 contex_ns_store + 146 00000080 + 147 00000080 F3EF 8109 MRS r1, psp ; get from thread s + tack pointer + 148 00000084 + 149 00000084 IF {FPU} != "SoftVFP" + 150 00000084 F01E 0F10 TST lr, #0x10 ; if(!EXC_RETURN[4] + ) + 151 00000088 BF08 ED21 + 8B10 VSTMFDEQ r1!, {d8 - d15} ; push FPU regi + ster s16~s31 + 152 0000008E ENDIF + 153 0000008E + 154 0000008E E921 0FF0 STMFD r1!, {r4 - r11} ; push r4 - r11 + register + 155 00000092 + 156 00000092 4A40 LDR r2, =rt_trustzone_current_cont +ext + ; r2 = &rt_secure_c + urrent_context + 157 00000094 6812 LDR r2, [r2] ; r2 = *r2 + 158 00000096 4673 MOV r3, lr ; r3 = lr + 159 00000098 F3EF 840B MRS r4, psplim ; r4 = psplim + 160 0000009C F3EF 8514 MRS r5, control ; r5 = control + 161 000000A0 E921 003C STMFD r1!, {r2-r5} ; push to thread s + tack + + + +ARM Macro Assembler Page 5 + + + 162 000000A4 + 163 000000A4 6800 LDR r0, [r0] + 164 000000A6 6001 STR r1, [r0] ; update from threa + d stack pointer + 165 000000A8 + 166 000000A8 switch_to_thread + 167 000000A8 4938 LDR r1, =rt_interrupt_to_thread + 168 000000AA 6809 LDR r1, [r1] + 169 000000AC 6809 LDR r1, [r1] ; load thread stack + pointer + 170 000000AE + 171 000000AE ; update current TrustZone context + 172 000000AE C93C LDMFD r1!, {r2-r5} ; pop thread stack + + 173 000000B0 F384 880B MSR psplim, r4 ; psplim = r4 + 174 000000B4 F385 8814 MSR control, r5 ; control = r5 + 175 000000B8 469E MOV lr, r3 ; lr = r3 + 176 000000BA 4E36 LDR r6, =rt_trustzone_current_cont +ext + ; r6 = &rt_secure_c + urrent_context + 177 000000BC 6032 STR r2, [r6] ; *r6 = r2 + 178 000000BE 4610 MOV r0, r2 ; r0 = r2 + 179 000000C0 + 180 000000C0 ; Whether TrustZone thread stack exists + 181 000000C0 B140 CBZ r0, contex_ns_load ; if r0 == 0 + , goto contex_ns_lo + ad + 182 000000C2 B40A PUSH {r1, r3} ; push lr, thread_s + tack + 183 000000C4 F7FF FFFE BL rt_trustzone_context_load ; cal + l TrustZone load fu + n + 184 000000C8 BC0A POP {r1, r3} ; pop lr, thread_st + ack + 185 000000CA 469E MOV lr, r3 ; lr = r1 + 186 000000CC F013 0F40 TST r3, #0x40 ; if EXC_RETURN[6] + is 1, TrustZone sta + ck was used + 187 000000D0 D000 BEQ contex_ns_load ; if r1 & 0x40 = + = 0, goto contex_ns + _load + 188 000000D2 E006 B pendsv_exit + 189 000000D4 + 190 000000D4 contex_ns_load + 191 000000D4 E8B1 0FF0 LDMFD r1!, {r4 - r11} ; pop r4 - r11 + register + 192 000000D8 + 193 000000D8 IF {FPU} != "SoftVFP" + 194 000000D8 F01E 0F10 TST lr, #0x10 ; if(!EXC_RETURN[4] + ) + 195 000000DC BF08 ECB1 + 8B10 VLDMFDEQ r1!, {d8 - d15} ; pop FPU regis + ter s16~s31 + 196 000000E2 ENDIF + 197 000000E2 + 198 000000E2 pendsv_exit + 199 000000E2 F381 8809 MSR psp, r1 ; update stack poin + ter + + + +ARM Macro Assembler Page 6 + + + 200 000000E6 ; restore interrupt + 201 000000E6 BC04 POP {r2} + 202 000000E8 F382 8810 MSR PRIMASK, r2 + 203 000000EC + 204 000000EC 4770 BX lr + 205 000000EE ENDP + 206 000000EE + 207 000000EE ;/* + 208 000000EE ; * void rt_hw_context_switch_to(rt_uint32 to); + 209 000000EE ; * r0 --> to + 210 000000EE ; * this fucntion is used to perform the first thread sw + itch + 211 000000EE ; */ + 212 000000EE rt_hw_context_switch_to + PROC + 213 000000EE EXPORT rt_hw_context_switch_to + 214 000000EE ; set to thread + 215 000000EE 4927 LDR r1, =rt_interrupt_to_thread + 216 000000F0 6008 STR r0, [r1] + 217 000000F2 + 218 000000F2 IF {FPU} != "SoftVFP" + 219 000000F2 ; CLEAR CONTROL.FPCA + 220 000000F2 F3EF 8214 MRS r2, CONTROL ; read + 221 000000F6 F022 0204 BIC r2, #0x04 ; modify + 222 000000FA F382 8814 MSR CONTROL, r2 ; write-back + 223 000000FE ENDIF + 224 000000FE + 225 000000FE ; set from thread to 0 + 226 000000FE 4922 LDR r1, =rt_interrupt_from_thread + 227 00000100 F04F 0000 MOV r0, #0x0 + 228 00000104 6008 STR r0, [r1] + 229 00000106 + 230 00000106 ; set interrupt flag to 1 + 231 00000106 491F LDR r1, =rt_thread_switch_interrupt +_flag + 232 00000108 F04F 0001 MOV r0, #1 + 233 0000010C 6008 STR r0, [r1] + 234 0000010E + 235 0000010E ; set the PendSV and SysTick exception priority + 236 0000010E 4822 LDR r0, =NVIC_SYSPRI2 + 237 00000110 4922 LDR r1, =NVIC_PENDSV_PRI + 238 00000112 F8D0 2000 LDR.W r2, [r0,#0x00] ; read + 239 00000116 EA41 0102 ORR r1,r1,r2 ; modify + 240 0000011A 6001 STR r1, [r0] ; write-back + 241 0000011C + 242 0000011C ; trigger the PendSV exception (causes context switch) + 243 0000011C 481C LDR r0, =NVIC_INT_CTRL + 244 0000011E F04F 5180 LDR r1, =NVIC_PENDSVSET + 245 00000122 6001 STR r1, [r0] + 246 00000124 + 247 00000124 ; restore MSP + 248 00000124 481E LDR r0, =SCB_VTOR + 249 00000126 6800 LDR r0, [r0] + 250 00000128 6800 LDR r0, [r0] + 251 0000012A F380 8808 MSR msp, r0 + 252 0000012E + 253 0000012E ; enable interrupts at processor level + 254 0000012E B661 CPSIE F + 255 00000130 B662 CPSIE I + + + +ARM Macro Assembler Page 7 + + + 256 00000132 + 257 00000132 ; ensure PendSV exception taken place before subsequent + operation + 258 00000132 F3BF 8F4F DSB + 259 00000136 F3BF 8F6F ISB + 260 0000013A + 261 0000013A ; never reach here! + 262 0000013A ENDP + 263 0000013A + 264 0000013A ; compatible with old version + 265 0000013A rt_hw_interrupt_thread_switch + PROC + 266 0000013A EXPORT rt_hw_interrupt_thread_switch + 267 0000013A 4770 BX lr + 268 0000013C ENDP + 269 0000013C + 270 0000013C IMPORT rt_hw_hard_fault_exception + 271 0000013C EXPORT HardFault_Handler + 272 0000013C HardFault_Handler + PROC + 273 0000013C + 274 0000013C ; get current context + 275 0000013C F3EF 8008 MRS r0, msp ;get fault context + from handler + 276 00000140 F01E 0F04 TST lr, #0x04 ;if(!EXC_RETURN[2]) + + 277 00000144 D001 BEQ get_sp_done + 278 00000146 F3EF 8009 MRS r0, psp ;get fault context + from thread + 279 0000014A get_sp_done + 280 0000014A + 281 0000014A E920 0FF0 STMFD r0!, {r4 - r11} ; push r4 - r11 + register + 282 0000014E + 283 0000014E 4A11 LDR r2, =rt_trustzone_current_cont +ext + ; r2 = &rt_secure_c + urrent_context + 284 00000150 6812 LDR r2, [r2] ; r2 = *r2 + 285 00000152 4673 MOV r3, lr ; r3 = lr + 286 00000154 F3EF 840B MRS r4, psplim ; r4 = psplim + 287 00000158 F3EF 8514 MRS r5, control ; r5 = control + 288 0000015C E920 003C STMFD r0!, {r2-r5} ; push to thread s + tack + 289 00000160 + 290 00000160 F840 ED04 STMFD r0!, {lr} ; push exec_return + register + 291 00000164 + 292 00000164 F01E 0F04 TST lr, #0x04 ; if(!EXC_RETURN[2] + ) + 293 00000168 D002 BEQ update_msp + 294 0000016A F380 8809 MSR psp, r0 ; update stack poin + ter to PSP + 295 0000016E E001 B update_done + 296 00000170 update_msp + 297 00000170 F380 8808 MSR msp, r0 ; update stack poin + ter to MSP + 298 00000174 update_done + 299 00000174 + + + +ARM Macro Assembler Page 8 + + + 300 00000174 B500 PUSH {lr} + 301 00000176 F7FF FFFE BL rt_hw_hard_fault_exception + 302 0000017A F85D EB04 POP {lr} + 303 0000017E + 304 0000017E F04E 0E04 ORR lr, lr, #0x04 + 305 00000182 4770 BX lr + 306 00000184 ENDP + 307 00000184 + 308 00000184 ALIGN 4 + 309 00000184 + 310 00000184 END + 00000000 + 00000000 + 00000000 + E000ED04 + 00000000 + E000ED20 + FFFF0000 + E000ED08 +Command Line: --debug --xref --diag_suppress=9931 --cpu=Cortex-M33 --fpu=FPv5-S +P --depend=.\build\keil\obj\context_rvds.d -o.\build\keil\obj\context_rvds.o -I +D:\1_tool_prog\2_MDK\pack\Keil\STM32H5xx_DFP\1.1.0\Drivers\CMSIS\Device\ST\STM3 +2H5xx\Include --predefine="__UVISION_VERSION SETA 536" --predefine="STM32H563xx + SETA 1" --list=context_rvds.lst ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + + + +ARM Macro Assembler Page 1 Alphabetic symbol ordering +Relocatable symbols + +.text 00000000 + +Symbol: .text + Definitions + At line 26 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + None +Comment: .text unused +HardFault_Handler 0000013C + +Symbol: HardFault_Handler + Definitions + At line 272 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + At line 271 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S +Comment: HardFault_Handler used once +PendSV_Handler 0000002E + +Symbol: PendSV_Handler + Definitions + At line 91 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + At line 92 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S +Comment: PendSV_Handler used once +_reswitch 00000020 + +Symbol: _reswitch + Definitions + At line 78 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + At line 71 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S +Comment: _reswitch used once +contex_ns_load 000000D4 + +Symbol: contex_ns_load + Definitions + At line 190 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + At line 181 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + At line 187 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + +contex_ns_store 00000080 + +Symbol: contex_ns_store + Definitions + At line 145 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + At line 121 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + At line 132 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + +get_sp_done 0000014A + +Symbol: get_sp_done + Definitions + At line 279 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + At line 277 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S +Comment: get_sp_done used once +pendsv_exit 000000E2 + + + +ARM Macro Assembler Page 2 Alphabetic symbol ordering +Relocatable symbols + + +Symbol: pendsv_exit + Definitions + At line 198 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + At line 188 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S +Comment: pendsv_exit used once +rt_hw_context_switch 0000000E + +Symbol: rt_hw_context_switch + Definitions + At line 64 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + At line 65 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S +Comment: rt_hw_context_switch used once +rt_hw_context_switch_interrupt 0000000E + +Symbol: rt_hw_context_switch_interrupt + Definitions + At line 62 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + At line 63 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S +Comment: rt_hw_context_switch_interrupt used once +rt_hw_context_switch_to 000000EE + +Symbol: rt_hw_context_switch_to + Definitions + At line 212 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + At line 213 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S +Comment: rt_hw_context_switch_to used once +rt_hw_interrupt_disable 00000000 + +Symbol: rt_hw_interrupt_disable + Definitions + At line 41 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + At line 42 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S +Comment: rt_hw_interrupt_disable used once +rt_hw_interrupt_enable 00000008 + +Symbol: rt_hw_interrupt_enable + Definitions + At line 51 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + At line 52 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S +Comment: rt_hw_interrupt_enable used once +rt_hw_interrupt_thread_switch 0000013A + +Symbol: rt_hw_interrupt_thread_switch + Definitions + At line 265 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + At line 266 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S +Comment: rt_hw_interrupt_thread_switch used once +schedule 00000042 + +Symbol: schedule + Definitions + + + +ARM Macro Assembler Page 3 Alphabetic symbol ordering +Relocatable symbols + + At line 106 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + At line 102 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S +Comment: schedule used once +switch_to_thread 000000A8 + +Symbol: switch_to_thread + Definitions + At line 166 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + At line 116 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + At line 143 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + +update_done 00000174 + +Symbol: update_done + Definitions + At line 298 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + At line 295 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S +Comment: update_done used once +update_msp 00000170 + +Symbol: update_msp + Definitions + At line 296 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + At line 293 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S +Comment: update_msp used once +18 symbols + + + +ARM Macro Assembler Page 1 Alphabetic symbol ordering +Absolute symbols + +NVIC_INT_CTRL E000ED04 + +Symbol: NVIC_INT_CTRL + Definitions + At line 21 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + At line 82 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + At line 243 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + +NVIC_PENDSVSET 10000000 + +Symbol: NVIC_PENDSVSET + Definitions + At line 24 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + At line 83 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + At line 244 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + +NVIC_PENDSV_PRI FFFF0000 + +Symbol: NVIC_PENDSV_PRI + Definitions + At line 23 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + At line 237 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S +Comment: NVIC_PENDSV_PRI used once +NVIC_SYSPRI2 E000ED20 + +Symbol: NVIC_SYSPRI2 + Definitions + At line 22 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + At line 236 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S +Comment: NVIC_SYSPRI2 used once +SCB_VTOR E000ED08 + +Symbol: SCB_VTOR + Definitions + At line 20 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + At line 248 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S +Comment: SCB_VTOR used once +5 symbols + + + +ARM Macro Assembler Page 1 Alphabetic symbol ordering +External symbols + +rt_hw_hard_fault_exception 00000000 + +Symbol: rt_hw_hard_fault_exception + Definitions + At line 270 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + At line 301 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S +Comment: rt_hw_hard_fault_exception used once +rt_interrupt_from_thread 00000000 + +Symbol: rt_interrupt_from_thread + Definitions + At line 32 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + At line 75 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + At line 114 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + At line 226 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + +rt_interrupt_to_thread 00000000 + +Symbol: rt_interrupt_to_thread + Definitions + At line 33 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + At line 79 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + At line 167 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + At line 215 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + +rt_thread_switch_interrupt_flag 00000000 + +Symbol: rt_thread_switch_interrupt_flag + Definitions + At line 31 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + At line 68 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + At line 99 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + At line 231 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + +rt_trustzone_context_load 00000000 + +Symbol: rt_trustzone_context_load + Definitions + At line 35 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + At line 183 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S +Comment: rt_trustzone_context_load used once +rt_trustzone_context_store 00000000 + +Symbol: rt_trustzone_context_store + Definitions + At line 36 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + Uses + At line 126 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S +Comment: rt_trustzone_context_store used once +rt_trustzone_current_context 00000000 + +Symbol: rt_trustzone_current_context + Definitions + At line 34 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + + + +ARM Macro Assembler Page 2 Alphabetic symbol ordering +External symbols + + Uses + At line 119 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + At line 156 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + At line 176 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + At line 283 in file ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + +7 symbols +365 symbols in table diff --git a/bsp/stm32/stm32h563-st-nucleo/figures/board.png b/bsp/stm32/stm32h563-st-nucleo/figures/board.png new file mode 100644 index 0000000000000000000000000000000000000000..835b93ed5f308c61f33dbc932ab2dc1911d03781 GIT binary patch literal 2363086 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

dzh}~u2I@kFx&Zc37 zImqS+XHSwiUoe!XzDnM?DnhS&WKrsAN5;ihXY(1sb)^8y)~l6pz~UDxkNFX{`sO7V zU0`|sdd#MX<6J0bUncxo{rI|d7)ihDsr%ZSWlT^A_d1kT!_@paNRjZQ-@(*o{gQHf zh<`Lq2m`<-Et`5l{N+8{vFIPs@QvcE@_bsO*x#7MGbD>Xw;sDI^ZK@%t4aO*;zhhVzIF8uYQ5w}JulKg?t?cRdkk#*cM^}XFX8(Rb# zYYw{CZ0yy{cb#YZ_)j9l(Nf$VSwN*^M?{$`%9?>R+1UP(d#wa7`T+{;Z~p9~!+hq( z6e^;wj8W3N54_m3Rr+CLC!yWzk!C0c@uHD`v%0sZ7dr38X(QCi>qXsG8RdyF(@HzQ z=sQ?EJiv08s0)p$(rA2n59CeFA>Atx9sl-TZ7?tx>|ZxOb*+|}yNN4Mb+ynrE?kNa zk>bK!VpTy1${CDpP>sC_>ZXgV3snfS3Abl8!)qfPMNKW(EKkd2<}M}F%ZoXlv+csB z@H8%nRdO3NhYXyBL8|GNxzx}urE``=TzLFn1hi0V3s7}cOuDX7pq*hMt^%8gN6bvu ztQXw@O=IvRe9G|D8ppS0rdn3)idP1UCEJ$s^pC%c{l1>MxQhR>5q%s7z$25@J6e~5 z`ercvK)h=sd_TQ@n91gNb(TkyTp^69l6Zay(}B7gl$bG4vNy9SoXSPXmI;_XWd6Rs z!_HwBrZ;?k;9gU6Af1H-SYsfb{bE@T)kHZb+%0ZtbZE!*; zluqG}$Eswt=AgmW##+o#lk?5mrn4Dtd6{XL37bo3sX3Jvlkxs`A7nyi0t+-u2H0); z)iE&tveHZmo)pd0v=}u%%OEm?R!lIj;pgE8tU8E()96vZ2eyQT0*UPEz`tnX6y7|lXXI0r+=Oe?#} z@zKj$P+;$<+<21SH=%cWdr2=^mg<7BfM%(T1nqLu4bI*?r{~<^6&%_~{Xfe+c)E|G)}2o}dxLLz;eKOUuj1Yo^k= zmQ(OsSaq)#{`pRqtJEU~l^bZ)%N5De+CR@(C3D zN|#474&K+)-gTK~!^u>qq>TX3noNmUNVeNjb;|TC*!;J+#&eCab?V8fK9|b4WZ%_` z_e6a}aB{!DQa+6aDa-Zk&&6x+oqgQ-ys_|s=>b=|BbU24Ilyvz(>vl!Z^$67o<7m@ zIPf(!bJ?`rJqWnSh+O90EbD-Y{(y0Z&NFTdM*e6m?fu712g~^aTS5^>Gicm#;RC*~ z@|Gk%(+YmkX)rb$n zI=R!oNbxcR#$HpRdi$#{^j(6(#4NvUTr+_qh`_ zZT{SlJySLo1*wq}9$8+SC&jjR$rgg7GM|niUiJtpY+^m}6?onufg?DaUqVBIM1}we z%rQON7_^d%ZA?ek633kfn8pt4&OB+UiYs-)D}%nL@NrFPP2H$Q4%AD1$5&8Ww9YXMsWL^ z!uz-9n4R8tU7LAn#}=gl8Co^2Bs{D~;nePD^XBpLmZ61xpoaD@A}^>uj=4s8XxZ|5 zdSMxa2SnJ5Y;GU_l3bg)GP!&fDJIw{lTqwe2Le-gw8n{O&1EZCrGKOY@T{!5+-@vK_P~Eb8V0RJ>3$AxjPiZXmE1@}l2nr&$#UB^RW=T3fC6)bzMS13Kg{5_{zs@|Fw{=SCJ}l;cV3Gpn`{ymS znk(h1#AFQQ6){iE)24=LJPhhJ0dkaFmM(uiDV4yC*VsbE8)vFRCj4hnL=-?^-l-xv z8^xEQtmuD$cXWo0Qw4!rfip$`4DN_P1=6J+B}*3X*?Tbeo0cRPeh3Z5x-olWZMnQ? zDf|RkH|8*dq_$F?X}dQt_BSSiE*C9pndbVc<1EswxauQnflXNDo)D=cJ*&}Anrkcr zWJ^7Op%z#+%E$(7!5FL-t0BfrXHv4a9)1i*gz==4Lbb2i0QMIE!#QIrRIZJCe^`LW zRk~lV3rE*FN(#usvumVhDD_6bF9F!MDeDhaY(_-f8E}lbZZtLJRhi4~VER|ND`%j{X)h9GEI)@glkg%8($mXf$)QGGv~Ux8dPDhiKwtW3P>Pa$PLrhQ3TGi zR-eR+5fBEmw&eW-(i<>xo?TBinim%=^B7lFNjnxFR)fxjXIF<;3sj!8u2#Qw#A8RH zapR~~o;#vU3I6JNDd3c=#Xk{``1Q3VL!=yn{}v<=EHxKS5Ufzet*{{MoRvPmOm!HT zxxIKzm?aS!E6^Ib9KH9=Uc*B-TTpI8I~ZqQvIJeviBdh@>iiKuFDuL;QAf9xChfRp*qB|YC$)Hr_v8Ft}5 zh4{Nl@rt(>CS8^k@X4ct1!mx*r*+&5-?}3ansXolMY-!%fhRRs!hhESK*?rmeH|A_ zytD}3%j~AL-nZE8Aqso~eeaolW8y__QQL(!&Gh!6;K97S)o}NP^<1=V`h5{{>*wx0 zxpj}|J<#lGj?U*~sl2u9%|!fDPjQ_b5JeIE zm}G!SbZ@XbwTGK`89a@FlC(pNzC*S5P5GqTHht!%pJkmOU6IQp#L1-Ixn)RHE`Hpw zL!3!C?7ocEF^3-%%D@+9Q2@$*7KKE2E_3pN(ijlCw@#wPHD7+ML{rr37vzztP>%vB zUo&LCq3s8=g8#I>5z^|I1~We#ANYi z8}GBrHwtP5D~qQ>{8+`vk9;5Td5IynNtUJWmr8L_Y6Q}< zYz#-}Y^V|(q;(-cw2lKn0!M{CkPKzTF}SPLqE}p8VljIZzD$KBf@w0<&NTx8uFl>J z#hK{BjyH-}TRs8$VJ;M_Y#vdOgF2EqxVE`(#*0dAWj6}V4Q;sOC|^COFUyQ`}i0Mt5D1W4p5$P=b_*L8N;eF^5yb7g!wF zA>Ia3skBj7cMQn}^A4Qj>pwdTRUvQJV{n{46pK~<3%;(_%G{gg+s8_hHJu@zohY9C zlQn3P>)fuw&XK6Ft-$LnC{T)8bX}o^+NE#^{hMRx8oN)GcmS-Fb>?J&`y&h{z9}qt z-dh?97bACzyG;_y0^SBqiKr{4p}O+YoxvjS^?8SPYGeCFp6d}rleUjIA3+~!V9KpK zZs+6kW_M#c_sHhvOXc6hzAcba&S&sH_R7nGFvZPm5K+L$rP zac2jMA!9yEWr)00a%ffXt6tM~;(Gl1o%Ge=6)SRtU6%&x?B54X$mlKNVKsmY}i&>m7TPUyG0@KFx!@p+*?+|YB5neWW1 zcrcAQ^MI-U`?!JdjZRQNaKNtfjf2ASL*g)N1L*i>^Rb zMzdoC)&QxQKJWbGuvUltd!+#bax0Y868@oW&cMTTX1QVLI@i`2>V}R4*BwA$`&LszGAq8=yzZFXbjjS>$4ZlNtaM)tKNslV@5Y4S zei)fbq0Q3Rsg{Z~CB-|XMCD#YHjP|zw29=}As{N^=?oYa;qeW`Rm&(T*r4@O#m*Kur(oRW zt`Pe9;mXw7JXJLOd=yb)&4aTt9*cl>he#{Am)7tbAXD2@4{{U~A`e__L{O76bAJe?zNtlKn9Oz2}+|D&>B86wJuYbCIg zV7n*UvXuC{>-w@&K?EC zTtz5bnFpgzr65!IzabUIj+m2}0Gp4?!&@n2FLV8)#`oy@T5j;l`xl{P!OT--W{o^r zum2{y#a^hDh8*z5D;sRFkSBND!~VB+qblceRupeLU(^~zIP``!jw}MQzFcXSOg0>t z=g~UN2rpWYrlgF@ur*s#b)Tq`?Ik88=Mo6$64rp1^Zr-W?p^_i>DDM<4YiL`7?O4V z9=+qc>k3i;L4kXqWydq+`C~N)AeRE}A<)uw_i4Wo^*X)sK~eLv;WrbI1YX*hzkbBn z-754FifMm(N*4nZIFvGqV!UeI_;M!rBEsd2;(z6~6-h7uU_+>N5GSC%=VJH8&#?J? zLtS~?%B=BsiRKCvW0Pg3NZqse!aGW>PvQ01wR#|SKS3tA9=~7A&5XBQrq*u~wpiA1 zq|#O&(_ju5*rFsp$JIr)q-I$UY;&#*{ec(k#kW%X53*S!dp#u+eJZ-u7)V&4|J5uD zyA4+_86H~eoonP`Yttt1jBwHT65=-{jr!Ujadoo{_Xmjrn$Blqzo9kE9ylJ<+0Nd7 zc^{PP0Y^4@J;NKm$E2GNC3(BM&s)+IVDyl>ptiM_Krm-G=xfQ2#5JE@_>zK?25Poa zIXlZ+Y;*}$*5zB1NWGKMwNRJN;^?4j=r z4E81-u**Qy33L7*=U^$qLhSRBi0$A1p1+wI=WraWx6V%HLcun9T5hfYH4)%{%SK&_ zFoQ})m$>87S}|e!Lpj>|lFiq7NCa@#WzX~cLGkMFuKR`G)*{((()!wt=;-m6@L4%o zcQffC)JC9v9cT{B{g{jMgs39BE{hI{uUfg(c4`c~pEtx0#q%0c#|l16bCgkd+#Wm_ zYAWw<+tdt_K#wen2hCWm>lo;Z0RfEJ`eBj6Lqd8vvPM?+bU;<`3`O`8k3-j8B)ZJ_ zED+V%I)j)6MYHRaXS1Ye9uvI28P;3(%XweK6x0nk)RiRw5EZTgeeW+EySEp8;RVPU z@)BaCQiccAnW=kx{bx0_+g9&05}V!IwT6$QHka*}ZbbhsY?^)@eNWsS*Ae)a^_Y4> z8Y@?aUYD&QW>@nAv273n{yOUCBX#Mqz3U4hZUa{5wM7aN8UKosgO|68o=2v%?RQ8# zAL$GQfeYR;tpX50e|&Y>9JJ}{@bd?;s*L?59N#;d_lK|VbN@~N`YGQiukY@Y_rMyc ztkG)p@opjwY86J!``k0A3&-~aoxaW`ZT1+^nNtIL;l~TsgPDHPjtLsJ&(}5e@ZcUVAh@;|CLq||gP$rPd_aP2s9Q3V2Iw!i z+e+AANr6aOHQ|_wzDaM9rks@KKN5{MlRP{~Y~2(nLj^z83i@&< z#|nq}0@u1&k5_J+5#2q@T{sO~vNdVLv)|otWX=L-DZRg2n2EieJ*nC>CV(wkx0bMz z5Een|v6vKB>EJGqOv);--syi6*k*>6xW2p+dO=jBsC9SlJ0xXOepIcXbRK^8q9Fd( zHjL2mm$9#e9+4Z82|(aBDtJ!%A`3fGOBF z(4dbvq7TF;d9cmbGs9Z27}~Db;T$VikCgke=YEu=q z3|9tHq@Z(3kU_zIeDYy;NCt2mB`Xy^O4qOlrlz%@nPI}9YdSIcKu&$1;z_b(j`PhyK{OqN}EUubGbh|H$% zyA}sq^h>ko1MmJ;84sd75R}DL?MFwqv)Ic$W;0b1kOg` z@-k~xAMg~oR^PIIIj4~}Zx3i=Z|^*+*gpfwSj*P<%%b@a2;wgC&ZE+(u+&{tcd-rk zb_X5=2Buu3!GBjqJd5D^y%x4{$;do|eM;?kI~5Lb{~pYB&9qo;qxkQzb#MU+fdo zrbJGB9lZw|rlZyJnZwbbn4HrP?;lq_s3I?Crb6q800Q~!-F-tlZoXVF82LtLdY%}{ z4P!)x{A1;X&(wE`oBi&}kiY?ExD$Y{WPRPe!LMgc6f-RnhctOJzb%L3nV-VY_{ zskq+Hv^%4D-OnvA9rhuGCV!lJJ32IT|MZy=e!@_4602$oEirNO4?un&2JyM>fiS*b z=LJLBhUi2oeuD%JLclJd2(3VbZv`_nwp- zG7D4?E4&YmcpM@2KqnySpC{CFUmHf(Xl284S0ZR~)XHWc&2b|j_iyrz;?;OA*?2#;DI8F4yK!!n?2Ivf zEPn^jJH6aJe<1JNeyup#D?tbHV0*D9l|+Hne9~?H^LBRz#|4v}Fri@1)_^jFhZLTO z;mp~;>2cRrhI3wBDD%;C$l%y>g9I5!aEws!y?4sy^B}1=FMifoOUU)&WTaF}&&b&G zPdlix`vl*<4P9A?eZv3?otj-DT-Vh#WKErkkve3uqF)N#zFh~MzJjbQn_ULlK_VsAd6WOLChJzGBh+~E~l$d0*aNvO!FPO8vI7=;aH>)a3HDe z?97Iej%`D1=JoDwN@aqBbo5}PqoWYsDz)MX(35Ddeu}$b%#Xrk6chIQPS>X2q&$$* zpVe)s3JBA!2+{3y_f>#Z+i@iI>JIEh3Wfi{l_<|B>-MReC5*`~PPwQ$2US{0lI|HM zV-6uQ)dr;Fnc4EQTq+r;wD%USX~`NK{Yt7vp+F+knju!Z9H$yJ_ss4DxJ5<)0O=Q! z{oOwKb@%%UR3On17#X?l$fpxdKBy6wc`&s@|1AZ9Dm|FX_VeYy=DU|)KcU|jK`xKV zZZNaGMTnQ*6Fc4a*M|G`9G-^N#I6Jm!#mQZcj8IUJ7Kz@XG+r0LhT|Dd|&^&?`f9% z3N7NTo7*@111&1wgVxMJ^-ecPN?LzP7#C}fvHI`c)TgAc;lS5hGsWW*v$pr^o#O+- zZ~dS2Jt`Q5cGR_RF^P=Y@}>9G^t3oOKi;k@_lMc*?pDv#yYJOXVl$cL02b%5t!_}j z*OUIIbH|TuO3m#3wvczy(S6_o_KUkNvyF&9>2VH=b(YhtPi_2&2>E#b^{yoE!>ap; zeMh=Y_gL{9`LeJebJ;47N}hPN#g`d~ThSdbT!eTE3G*8Sd^|?w6~Yz;V{rqr)qA{Wmr?#vpxR z0EY26URKV@RuhWd`)sfHrF93wV1obtY`fB&nmDGE}-VOQ?}z(D+k&^>m5Pj`PHe88mz zMw`%0A=gGRs456Au)lVwuc$bk!=~8&N8SB~{+)w*RMOfm+CKSFh8OO%QnuurheJN6 z>2Aw1_?%6Y$yDF8Di7_TDhje6nt)l~a z0%4C|UAF5sgfaXdhnYv|k}mTI=#k^!Nt}OFSk^UIZ`G~UYQG5puMInI)V}w)aSwUF z6OZoSe;-xqV+TJ&@nYgJJul<2;s+50li zH-uI#@5Xx}i_7l|1&6`u{xCu`e1oBk5X`U?rQY=JWEE#$ED{@FO8bqc&Bkt zLk;__Z`v=?UUtI-21zj)Yg=2nlAGOU&)M+EIPhpyDwf>O&l$BI0^Ph3BQ=q z81(jEF8MSD*5zZG;k45|%Z5mxnHql7QG(#hfZ*PH&&_+?Dlle8V_d_;I4TP=v_}k8 z=utcxo?;o8_thBg>l|lKq;ZWmbl-z*@azGOiD}&O9VV`1-Pl~~Z!xLYo1HJ0k6wi@ zMTHszo;=_88n-939xE%GSdpi zcUZ=ajFFAgb8?PSOSV#tY=dm|KDm<6RKOLnNAuCl5V@U>;cDDpC-itls14u1HBIyl zZ|*|G0`o@^zuq|?YI5J;DqWTmT5ffuIg!qH!RrX+Jz5N9}C;SS#?PJQdWAWf$ zj@&+2@G^r)h3~Mwn8aaAPIPf)5u>Bmj>gxbQJ zIFx?ks+f$wP4`cg1Ub^`c*}6)%zJgKU2yE%r^fWr|q(!z$`Q80TLA|t(qeseAco_^TyeN zO*_JoJ_p;(S-du=)EKC2@>|Tph~p_yW3C3W&pzT|dju`QjQX z^T*HU)a~vZtTP^Qf7ye@6ZDPzX}bGq*C7X?$kh;Tx(zkplO9`k9>QSM?~V>vEC;LP)N6W- z?%%BACh)!m;Y^*FMqhoHWpXCKWsUw>`uP3ttBQ9zI!&c}ttIfCa znv*R?58$nocy0PaNsm;*c|$M7q_awkau+%zL%5d0B(qu0JijS=uy&x6v7J)R&+6}2YZ&Tk=Rn7fNOwkmX z4Us<^aiKO|!u_#3@HULW!oa{lxw6Kh`M&DuhDA0sbRb^pnX6;!D0~q>ddX7wLLbJ0 z%qDpb9>G*khl_k?s3bjN`H69leh%{=?zqo<=YLgqByKKsSRk|_s9J*zEZlHSq-0LG zZ7Cp@tQ6I;QWzK-1~`&6h8m9Y?!3Z&3@UtZRa8`Tv_B5{Z1az6X#oSZ2ybtVZzWMd+TSrlm0t|F}~_u9o2{mE_a*C!y1-|8_pc`;F~C^P_wY!;@a%*8 zo-UyVpR`AT$wxeew#j7sb-IPO56~1qgREE$Z!$EGpD&QZptytrX2PM4>;2I3eIeQ# zellL0Y8IzmUG@*%IJrdd6T!CU^AafBC{8n_F&}%y$kEoAcp1iQI{TR0?Socb9Yci~ z*r#PUnr20X=kxYMw%?%VI)!mW8@J6bn19Q+ryZC5lzP$y>_G|~G zc-eQqE;+Olg;@w7>3r@9h*mYp~vs^?fiiLdYMoz2i<#VJ62U)X96-r#2Xz0+Y*g!Krd)a!K)mnu}NHT;qTFRmT;*#V4WEG;c@ z;ljg|%N2T_2iB$(B$A3%+2)`raqi&c~({}_!MVU20yJ_~q+?VCDS$DE-=q)|Hz#OkB2*n1;051=xID7Rf;3+7; zBZ;N_d7pwv1Y-Sou6Y{v2_V6bu6{QkTGdK9Q)Z{^CF~T5ONTVpg1YPQYkF0CRMYAf z6^=_Ihk56(W}s43i#97&-C~P|8Oznd1>YJ)mdiVDXuYg2V^tTrfy+NzH*oEC0= zpwavTRC8=Izi_R+zP!3N1T6w9h3Vqb4R>(-sh ztJ^ly8;{c(j?VA*N;?Q3By86r(BbymuVd4uXL#THKTje#N-Wk}gJzXd{OzUZYXx_s z2Y(~gNC?=x`DL#B%%{=XZ1D3Gk%0Tq>jhsld{HMvJk%>B1o3#UtNSnyh@l}>f8L?B z91CsHq#H`8wOI`3=}F=Ui}vELwubJv+HlPuUp=J0*q7rrU(@acO>52WWD>`5TpqAk zoP#Xh7@|@|YE0s)taa=2#t7mF4VkVrDb;g1JUo0*7}%j8+2%uhRsX#TfsSNGYvS3e zv&&*d$ii23Gq0jVwr!|I=}ekra@0l4^dWuh^EKU-u35A;RnJWjD5Tk#I6yu*Opmb1 z1fpyi9p#wSQU1Dlg7-X8A%jg&TF?;%g7{R5?KfWpFZ>dYIhSL9UvnKLvU+@ng1gh{Tuq~pPNzwwMj0GjT`EbU*#(*9L+#e1>ciK*6Qgb)l34ZB(amq#B6a6rVMV-A8( zF?QPpT=n7gP;x*yCK;`i;N=Z#c>d~TuunteT+k_C$lL=#3rNEmtDz8s?Fr`YxQM;C zpTyYp$B_7L4~2Wrfbqv+?I17Tcmc2f+cI|lc)ZLn)A^sJ*9i)J)Z z7HZctopx{>Rio>s-Qms=(F&J(R1vU0ovKkmr8E=lkWdKW&`cUgBZPyLS)|M&L>9}^ zbh=+sDx_3cmZHTnzn@{4?(R9Xc32jR5fT=2IX`2Y570x;8(5#sGhy2{Q|TNbH+Q8O zQA3LsHYZ1V=IWo5CKm-S2?1ki3gcNU%c8}SIJsiOo>fn0o*y3i-NtwRJu7uNXHrT^ zr4o}Wi&sO$*j~|UTebgNMYEMEP!aW({^s`)%R)*)Fldgor>BRJkrA?4$21bI&TP72 zkm13rJxl}b!C*s^67H~ET9+UaG5-ddNF>7FcE5@*C|s>g5O1lmFl(vP4$ZiKzigQ) z=7Uli(SI;PSES>Jc@;C1n5@xY>NS)uLJ_e5zbROSKuRBz%4u+7^>+8tTud93(^`%c zFnaCVVdN>W2MAsDC{q@c1KqS<<74Ba9#dG4Y-H2V&)|d;+L?9|<`hP3mh^^k1kB|; zXdOJ_{aHg)3g%u6NFN~~m`bPFpH9)K({$j#_z;ZmrV~v-D<)Dytmut0t6;SyfHdDo zj`E0zKsF7Vw!uE2-~k!uGynA8T>Xa`rcgxHHaacXj(CHEev2s+N}+AjomZj z?)%<=55Ipt(ARq?4Yim9DJWo)+l8=clTn&vl#Z|uvKff<;S2Qg#qZw&A`X{SSik;& zS@SgnVlCMHt0+rXCJ_jrl#vKj_c*iviaH(K!F%Gu8f&Jmmdm^KaM_h$yb*J&g?r+` z?;~n;MpZ9rEJAcc{a$a#G0#}hHQg%+hKENv@4R<&&xVI+4M&--V>9`hr0Ir*yKw#B z`~S|PPd>ti4bQP_TLuj@SpwxaBodKK3G{!Axzt%`$=q=TzXXbxE@jBept=eQ%3o@lt4Z%4Q;#JkM zRGTO%Ez;@HnmAI3|HZ-8U7u-3flKYE@q4v8V&7PuK3LYgfUEIyi3I|&gPk?1#e0(! zwM1K=atI$CCAY7G&ph-zpT71jgm%8ftcv5Y1mhycW#4=lmb}h=zG34lS0& z>}ZBNzkV^7+_4AzF<=1v4itw;b@y}Y?_c1ypU!~H^3ioA?zrN;uyYt83rrCqot897 zwTLBiBTQd?&MeDfV4%PD`D3wzX_t#pFlT5yU$d^zb8jl;ijl>lB0C}8*mGRvw9aT< zYZ|Llm@4P>$ORYfbVktTUL&nF(@v2VOQP#tstz%6Zp`bbzxNEyEtN79Fx!sS1}?`8 ztmc;6e#Eq+aIy|lx?t#}B}F!yWine}XDQ37&J$?T5r)S0bNBat#)-!-XWOe=ICEtW zsjT9g*IdJf>eER@z?vWG< zuM+AxnkD0paX<)u_=E59hr1-rg>jYy3xqqCA;cW2P^O>??Ag1IcxMmYeLeKVVtnjF z@1x?P5b=0#&4@s`&NmVun}WVMMg?4V({CZT4myB+Lm*=uf93tm-Fgu`{AoA`!PME z{7m4-SBJX#T!b}OHider?mnFr0^u_rLw)ufV^8nFD`Nzujn`4Eusxi1+De8q!}ydu z;xkf3ftRg1iv7b$*Od?~+d3pQ`Oy2RUUZH0YoODnR}^p@MJAU<$_`W^dzkMPKmp^_ zryC~PUhSbGVbAW}yyG43;L%4PC5xh?BZ8C`jx&xBe%hsF42p$t#pKexhN3nYnQ#N) zvRTE*_T^-j9(Ryw{FR)nL4m>@7KN;0X~z<>*(^aR85tR&qobo?U#b2& zgT`MH$cU^Pv>cozf$-P#IYwvT)b>QjQS1?tr2!v|Y=wxq2Hw$O#_sqSonL+smY+=T z`yYm7t|M4hbN$DT;wxvJ!<_cBXE;ZvWy9F3u*_jj9aA$x^6EZjMD_@U?EE4sWq_h8 zGUgPC3c;#XtJt5(v9CDg+9aoG7lN`LrClgSlG~8|>)EC)=!ub28d9UMWDv$*;ty9} zz>3xIt*_q0PdSkrulqA!c;bAzDbb|T%r53)_6AUu`q%Q_IO92|hRPeWnKZLn)7RaN zucS>QR;trsqw#7*K?~Yd*x1aEJG2)9G!;h)=oGnhnl35XmD~*?3&BCY{q%l5{4f8+ zcmM7sh_B>bI|Gp30g*WW^3X0$IlrAHPL5dIW?wEvhh@_emZ+j~b=;4U=`js(E(+KX0gWx(FpX(k=$hSm%9I9#bVDsQp4vFJ$`1BXn@yO=ak+FV+C^G2FvQ#Lx=qz1C-T2P= zK{qrVwI)Pqgp>%Ouq~U(2G_p-xwtp)-e=N9Y!iu8gC1rvT3WsRZi8eur(_b`o+oF0C~|ci5BF+T=4>-F)H~uR_q~ zgI`|5Z37vC(NpkT_AA&G;lF?XSDe%>jAU{=x1)juHI z1hB{oO(N91Ap`I{Qd9ZO;Lw?i#yC!JK81`b(k93 z#;gipS<7*pG%%0&+2)y)<;@v{OG5|8jvmUHN|ay14A({1bbX~%KQ0R;`h?9mRk z9cRwb?Ao@I*;Oa7ZTx^iMmk~~P-V&rmRd0?${_=wG-!v*~K?P(UC+)DAO;pvC9op3O^5U^9ZRJ@_=&ZM2OR^}i;0 zkiD=xX7bV=eVjAz{w;G){ED5!!+3?JS-_5+J8CGeZQHff_xf73`7qa~NeWPA7+5vK zsSf2W%c^tT6^CtB>g%EU_o+z|98*infF!NbwPE4Hq2fXYmKRe$YS(GcP?M{Jiuq;L zSEWx3ZGMnvpM8KUKK*4{195P2q_uJt{EBIj7b*_m{p1$(wDi;yuVT@%4B_WA1}_ZdB} zPjD%k4L;zD7ufT;^4~;k_>2h&E6b<~q;l$> zi9?^mL!ls5YGl6VzNZ_eFa}l8HN6oWY_?E!ZCY4(3Favz^)#5n|Sp= zhAopBy1G3$2g;0Y&r)ofWI5n>b~ARv`{6@Br!OFo@i2J{eCiCM@$CrFgH%!8e@-iw zH%~K7Ow8sPZ1?l)U;ms?sGD#x&mei4XJ-&07^cLMke>tj5=}bKQa`-P93c-tnYK`g zpZ@SBmM`z)iYxxfaLj=g>0?eQ(8@?m3Ys-^@IqoMbV!~bdWPWo6=Z<98{dlOsz+J5 z<`lv^i-fg9Xmu3C9KFsLF}uRzHm7(N}}XqmEdn3dZ>t}%2JCHUC$v;5}A zd5G9N@zhDI^g&@X&62}h#KJtFvCN)xN_OtlFsrn372U?3w<*P;R|Ac|CSP>!+_=Nz!q}fH7 zayjGH)kya`62-<3m>iL+!@$VMUf%i6cQQ0I#Pa3KX%&K>{_>aHb=Msf3T9B$0!(Q| ztB_1-MKBn_TPo2M5hj<xPg~mdd~fR=m;8Wp4a`*eqroZ ztLsfr2&T|%*|LS}uDgyee&GwOJ?=Pc+h#(;$jC^;^jMgH7n-Cw-@>IxHA%BRSFdHY zVX-0>72iDaSJCr9%F5L(STaqf;BoVSiZpA7*?o1+DXxm(xax#n3@439&v6~nIu z{wR#oPfROb9U6s>wV+Fo5ol4Sg$&@DTr5I+s{XkwF?u>&_eUjaO{;C&klD$ZF&{VU zQBV%vvUUg73QsJ?3#w@LHWVMSPGZ!y_|>i?oYKlHiU}!*31M_FNZPd`9uUkT`J0Z? zeNZ6xq3evrs7^->u0m_gfy5}ScCa%OndE30 zDJ6dCV=}E67#L_^fmCZ3qrpozFl!cTTJp7e(Q$Po!Zm0z^=POe?BzNR&F z@6>1-trY|P{TxV+HVho=gR*s<#?)~fLUP`a$#E22@i@6$j%d`ZeZH`QSyF7+@C)MW z-o^4WKfw#hQ7lW+<~YpOpc@bAw6P46(%g&z_p|A08mxOV^UA@J#${kunP#MlBpAAu zs=0)DYhq`~tm_r8-HDh|^LY(b%S@#dUd+^>O6#dk+-KavQYptRU|p`eFd;ZvYi!%t zPJ$*RWzC7ITDS>mV5|^s@X}#YJDY(DqQMv1vMi?3IV?A;zzFuOgQojJNH+;r9o9jt zibzz?alI%{YfTu*qzjGLbDHa^HH|*vx?v(+{kiotplZkd#x_6IK>Lxhp7M2Y*S~OM z-6Ji|OefeKi<1w`(N{K`T@NG7Im^jg4rOV&?65Rc5iFN`Zh`RmjxYhxfRAQ`37XU% zC~NQuC~Bqy}07 zhO-0ElOVACF*g3^dx={m#))yt>S=y-=Xd$=@^cx&BGM~Zs#AD~a_3E#aLKiQfF6s- z=2Dz<`Olzq3PjxLLeK&$W{SC?>* zjc4aDlX8%(fRIp3DjTg5M(jtm;ZY5u#wID4bNm#=I3;TpX`P{yee~)ce9D*syPXKH4p=O^cMl{wKvj6B zy@fyB_Y=Yb3bRdkH2A$f@|6mGYu50}E6-5Mr1ATtaa++atD#8)uWf4f+(es@-h)+B(*r`5lI{pThGS1$__0y3?5Z$vLny!E?gK?vB!3 zv|xNItQcfgOEP+xP8k4tK=}cOfG#pEB`r#l>vk8Sj??+g9e;%mi#MGS<}JPvvN=B* z%~PTbG7l&Qv?8O5fQ`qB@gjm&B*%+1oq8Wiz)1HRp8d-N-_7g<*6@ziQ9iR8+LIZk z9Y4j`97zhiC9QbPD&dI^^7!48T=D5m>6T;2pv5zrHgW0auB179oJ#?QY}lry zXzokf9YlHE43TOxVq+Tl_Nav_>IUsfebKOR52+W;d+XNVnVRX1(c5`l*S#6%br25I z*?oBRn+S>srCNTBaqpXV?t%HBV^PPOFVJes8vSloDcU5QuzW3F|CevDdi4p6m9qTy z@%vf3b~!tq8bb6KA$wP(!`P3zdq>E!-1AW&Pl>m`;~o6&-g{ZSdL`w8=C^Z z=i}2S91s3yK?+7ij-^O4(!#41Gnm?KS~)e^bCVQIx$z23Iu24pHqBlIXZNn+bvFXD zGqaO?ILcnp4El8#hkeliA}~(34&!9tye~WeeJ6uRaB{DY&z-!KUp=}Do*E_hzU7?Q zZS(VOUZa5#Td)WIo{>xe#dd7b4cd@G-@zsAHc3{ zJJ>Uldcqhib{t_0%g-x2PJL zMN=w}mTfF2r_yQcSnRO&yz?iX8l5DO7;-PT<^F7oyjH|w zc1?(1offyrdBKr5sL*!pUtQ{yZQF$0rm58qGgCLco=WFvk40+}zmSmRQ8mP-adT&IbahjH@KzcKDd$E^Vk=Uo4&X-uk*ks2_Tun}#h zV(Ju5`ECi)FPVv#=sS39T5`|5UT{tHp~kH4`KUrpu2Y_|p^@|duf7@*)ks|T+{%W9 z!F8}*LDLPe}Ua3jBSc!L$Myet}J84$P7}HLIumDF0(!hk4 z^!Bf2LP8;9nwN=Gkr`sNtZHTR=x$IwgwZtv0kZ&`HN&J`tHaX%s>hH@rQ!As#wu8A zen0jkegUOf50y%VuC87V9N3Q^FKbt>WarME{QQP*anVKZC0`cYdCxuU-=F2*zWE)- z4ipIc+nFjjghi04ke^Da#FmK(Y`>pLCb;K^--O@_BODxefGmHx{pW=IFzfM4Q_w|%q6xp>PnLFK z#UjZK{}=xLZSe9|SYd%9xM{}{`eYxD0MeQr@iknp%G~jbz3^-XMw+4Y zC$>dm+(3$7Tz?W5^cQH!M98MSB!s4^dyrLE-VcBEGqdJ6KG5Gnd3czASoaprIqzal zJSM<5ueuz6AjZc&`&sU~_g0qm#0dHPSYb&>Sd_zpvX(^M&A&-Tu+xfFgM$RRyE*Z! z)42Y+8+h~CZ|B6b&f?#$`3C=f?X@IF(=UhptnbZ2(Bcj-4E54NIpe&z zWfOzzSCGvXAgf94PIL0n>nJQY`DSe$J&cU(Llp`PEMM-5h*R!>Ge`(cytkW?kr9en zMWIk)#foKa_LFHkN^bIeR%?RVk6#Fyf`W;xK~t(s1}SBOb#ZEBAHkrpGp;&+_4M?a zqSv;_QD8nl#-*s$h3~aV<3QQdzl15Br&OAvJ!TQ^2(WM87-9t1-k4gm5|olwf3Sfq zQl;h2>qRxfpG9Lbq^2E*kZsXw+f1d?WHJt~4-NAcx;duk1xGL$>|ItHy?2%K{UFK(NU*n%`b&u(s2m8gXW5W zyyJj?_L$9XCjov9$Dhpw|M{ZXUrUyYu4Vb?#hXd@UTF4`jy1gb{0E_shEj*2M0NJS z%XcyIvk$_~zi`_6vuHbRKa=~)v|kBCM&N}VAmFXXTl}35a*jh+Y=BqO&}qTY@KEj9 zn9skX&XA=(ZoudmXVBzbq@vS~vEM~5D?*S;CFpjuz+TrKHR=|BejYl*us;D23-+fN z&YWRTr&rSu>40ap8G*czu*acgrRLe6d>L;h!?crTD3zu=HoyU;v2g=1w>?P<=ix0! z(OS@qB%Lnf6-Hlaa>?w5Amk&{@^MWo%zCu$q|^A_ukK?;Yo^i;EmojrVzVq3V}BxP zTzK6f$}fNU3qJeV&)~Rg(V=uIOKh75{`4mX`UkMA0R8>_u6wLQEEY2WfZH@GcYXWU zf4!QoT=~Ts0^RKHyIw757G{`Il}FSxDhSw>974)=R;)gOk&LQQFO(Y$CWNT@O3y6P z2uwOTVzDR_sSJ)&Bp&Z2l}cb)_CW&HhCrOv^~wr%tO?J$nx zFwj4MlQYzTs>gq&!INJ%K#k4r+k}KzN zg5J7rdFGHszdiz`?0*wFW<=>o$;W^41Y`vpP1Y>Kq=8w`SqRn_#=6!=9CWzXf%=m-m=V>pjI0atKK!*YzF$JECnR`(JFFt2@ z@sV{fvHR?Tzz|EgLiW7Tn_769s%O12WVGEluCX_anO1Q3eW@7pJ&@f%`-Xn^U zl`Nqgk7)>llB+&-7T0~?TZBShauXirntUV=93bTN5ef(@{t|7{M@NUnjn{mIx4!cN zhBrTlH?q_`v!Ng%AWDejM3VpW^>49r%NFjv?RMt;&_b5{mWQDGXejJu&4rh+_4j{< zZb4~uf>pi!Y)=ePn8;I})szu5H#MNunK!RH4dv|R{pWp=5B&3&=(J*# zN+rrg&5~vP95`@*Qqduo&qI8GbRx+q!D(K*|6lp_4G%&|G9(1h2cnrtVd443 zBwrtha_86H%6&!6a}09XZI7~b%Nd0K{f~^@d=VWxpJxdfcR*m#tcQq-vJuN`7a{Bp z^QS-km9Kv3>umkieFXd6%#@NM_5Jtq;EoKJ{UE`6K6gLKyDlP|OtLcI(wxQ}L^O_4 zql~47Xciq*u*ixmYhnX@V+Y*v_#fauzDxg4?%|?{WbgPS_dSq+jtlw7zdXeDAH9`` zlV;Vbes)M$cjf)Y26f3GDM#TGt@OogPU`LFEyo?lMB#62+PZ^3-2X#9dD-Rs=DvG4 zY1vYml%G^7L0hmLtv!?rd8|kftxL>_5ZSEegP*#RS2yhDt*4(usxZ#}bc(l!!+h#f z|5VFFkW%8*6(7}slXfZ7t+q`(KEPBujg}I}MZ7~oyrE*HA`WHqtpPt?S3g0);j~lE z1tw920^vnm6@_4t`~~eghBg|KME!nRJC;!qnh7;Vv%ih@U?)4D-$nnGU*hRUAEu-Q z!C;VRPY-Rbqo7iXcziifa)*`z+m10lHbx{8VFp;Wb}hRS3H*L)p^UZsqEd;9A6kST ztsSO?!0)0Ne!t&njNJ9dag6nGQ_wUHxm=E}c#NsE~>lxF&MuPzjMGmuR-BjnJX&NCa+=EF`A7@rEBya$H}oQ*3E%Lg1EHI9-|fP zAA%Jwk~=;QDnZNk0O$7$9?EVtd*7sTHD6h1E5WHzidXzIEye95b&S_Xlf3%5Gr8lT zJzV`*(G0wTaN%3}`N1boWhygFi)G_z;ZmAX*mevdAf0w*RCjB`3F7M=t;UcZkPAbU+ z-cp73SQi}w{d9Ln*}ij_RWV7hyO(0o!=AK5FlMoDG{eK!f0&9ok5#dD@;XP08+hEL zOoQb(i8|VsZpaMNuCc;m&v(5IvmLc56biK37Beo@uH39c@4$Es1o6Z0#|N=bqb)lS^~%-~Ao04<%`}!w202^;D{F{`-G$;|({E zNG3?7MzQTEAtAA1^G;YHA(6JthTr~{r=EI>o36WoL?TIx6oy1h1S(Iv$+a|plL_?k*S+JjTf3PD8~ zM>8wjg_A3ylp@xB6g$!MicU&H!>o=U&!oG+j22Uz{BQ4ISE7vLbm7&CiqJL7*pRSD zXL3}c0a}Zix}y23hfR!+GE|d4XU|rE%Gi1zRYOF ztSUpW5BBflAKw|`77|QMROoE#X1p>IPK57V7bjWCjW6JCV=HYff*4euXnl#p@LV;=JUamSMlGGA@;3q z<(NzXvW5%a9nJE|vs$?9p%{$x(EH^FnYi`>v>t`h6s(Am(V968Q6brG4S?fAi4v;_ z@cmmKhD+D;nNua#f25OHl_JbC_I~26EWhv$5bOBS&tK-6&m70kw@q;Q|9Q~_RrU!; zkMQQ$Nq91l7J`4c`b(734izC$s?3x&C_&GXrG&&BJ_-an+7P167%5niITuU>KUQBS z`_tp3QX@5&yaS2d{N$Ef*tBUAb54TJMRz=P{^K6D* z+rg|-b@uj0vVlLe^Osj^lm>}GOqWK(z@$6e@-*l{^`fD$!i^=E7mQb5<$|WDA(!1t zBoZMvR-zdXv0x_?sT`ij91$HM7K@QerP;62EU|5zY?ee~cTIy+EqW%iSt5}LNDP~J(S>lP}UV~(0)1du)_ToXtbM5q0b11at zjGugs@9-^#l!s5OKGh6@6yzoBd47*81hUAxR^=Xdoo|c9YFb3$8Y{(O-9)2?hSU|1 zJa)}TXp$|glS>GaW>`T{tRSL~V~Ol$E&#{f^sZWS?Ko*X7TEn!nz5L1945qaJl$bJ zO5@E8bJc}Qx$4{~uL+oQM(OPhQk+ z*Rm|P{xa8~$(D8bTBcUqq7-Z1_BN(68I&^S6+SC~ls1X9Vp{f)*Meiu?8nJvh_CKv zw&>8-9VMe-W@nP6XbvQX$ZJ?)53qVwFWYwRBw`6XYA0>dVluT8$0-_Ckx!7*2OmUh&H3lOllEA5tvG8a zrs^7%=bnE7Cud-;`q0B>N1)xJt>U_m33pOo@l^w{MC}%vPk(LP43_ovVMpx-9Z53+ z?Yh5s>pE(&;JQiIT|^&oBRiN5R&#GdH#C(8C&7zFH?D=9cSRhG#55x)OF^cXF$l-_ z5I_3rnS6YG3qmiUkjqgKD-k|{E^Ep)$0kwx%=O3ZUjz|K`U*_va&(555GXGt=nGRU zmfe(BALW39uclG)P;v`-KYl7=jy5f!3|UpCgr+$x5MquQ6a}qVSRrO9d068$ppKDG&=nLjArlupJ7T5I$OcB}P>mtQZwxQDGh> z^XmC~V#eh{hlHU0`bXUWK?@vADCSd1(6Iciz5MgpC-ILrJP7(|&bj(o=59U(hIg_x z5ur6MuwAnUD{QeMzLp0b*~rQ3*E2Lc)S%@$)XQTDx^x8e7(@hNV6a{AVjlWe4l=&u z8S=$EVXwe$5{zcYs0hKY@4b&NeeMb(GSB~a*-d=$->)K(9OA%%*O~JcnV3l6K_dz? zgi6rf-plBCl3WSwkfh*faC#;LrG;M%oVmR-w#@caFAcXu%{ae&d$3H+3pYx2_`@bm2UBu{MK z19mSw`5H@oAyN?^$P&aVTz~Qj{L2qs=jcnf!qL5;#tmxdS3G(Cu`F@QB&`5jbQp*O zn@~#Nu`KqGhI9&+U5Mwh?Qlkv3x2kZW54_$KltQZ&3mB837fq;HU>t{MU)p0RB^&?74}ZUb?ZZhT+M*2){oN^k`2Dx= z)gL~=2hTo>kPtkx^{fmIgz(cB=|m~TQG-Xj)MABg_mFpoJ1x>jKI0JY zjdLKGK-e~)`OL>_`A!wLFc}&eW^mOiv~BT+`+iM8YsQpQb1!@&PDhLD(>$n}j?Z41)6ZbT zj~}TOmxWS^yk!{^f?yEaw%NXYJExz1HmOvK8A|NmzrPmLsI_*R5b*mA)ZG*eBHVqV zR4TcRiyv=6o2jzj&vXgArFqNYsZs$-rh%A9rD;9!MAwm%x?s9GQMeWkGYHMU~n7l3#iaM+uO@VZH_30h_ z*CWsIuFqagth*O7qqGZ6N=u^Aa7`Oq)j3w#HZygW&t7++R&^(xb?Hdc=^|b6-kSSq zDwW{Vmwt@(>(_JD<)7romtV>U-uqsfv_i@`Dq54(ev;c0{53mHYex^?zW%=$Kd_HX z(&Uo`GC8_zi%-1g{har~_X6;acfXsv@4lN-+F{L_0S4CeW62=DzW0|LfASd&B@$Rx znD&^B*2)e0cIfTxuH7%nl~|-wX=1V1VO>?L)Wjw!*tTuhjq1>JS~g>(Nu^RXGpvvh zjHS~oi^Uio9>%LRUGexqtfhq-7_BwK!%4KJE_TGM1@U;irU$Pcrx3zLU4(15ZSFIT zrddPLZ4`YzUqdv3ugNXCn`EShT$o}zO`D8Rp~TDrSD$*iP$DtP659w~DwavAZV`eX z-Fh27;bSbBJZO1qpnOPaps9SBP1`mjr3rV+yD*n!Np>ZY*me}9GzSt1zVV%F(Hb^y z{u|a2(%n<36qA`0$z-P1MOO1ZOdf*IP3blZ?ya|e2c=-|&YcTjtHocNUVNHla+IN= zVJs_*l+tv_E?uqqusDvxd*1zS&OYlb(iwA;)dzOX)KSYSb?N9g-0&^5hSAYcHy0vc z{#_Y|vWkEZh7QoAMeSx@5%1^jU*1I~lUZaVJJ_?GLkOn4`tTdx8x`Fz=JP#+#-|j~ z{$69RI1XB;NhaqIP8$EJRXCIgi8ZrkZoqzvQR?PEZr_$Ipone zx{MSS`!?^vvI2GCrPXGuY&HWjuI?yi?x$peR$J2D9c5C%apgf~k{OCZlh+R889^A$ z(r5sGF2w;XntV1>PLaHxKkgarU`NBCHCju?w8NxQlx2{LkUWI9>t5v2rb0p>q#%brEPYSwEJ6kWK{#xhxT$m+DI{$|6J6ca za1AFk9LO1OcC7`SGD99^3?tn8*6V6NyfOe*03tSi5oQkXYKNebv?6eXgLV$e@sNACs{d zGa`WBwJA@HrkS3rkaLQpGiHL_T%!RT`rcPcF{?a=*0#jLr_v;oS!inFl^xH}*49RD zVw@=t=-CRtJN!0LS+BGPE~|aweIcouRL* zmzQ4JL6hv@OJDmo?LyEbcjJx6P$~_S2nH>}em@fvljQSxLLooC0xTU|$`h|83AD#~ zVQUhIfPiiR*9mFpU(Og`JgXB`bh!4X8{m~bb6*85{{N4yYS4jy6A+v6j->k&i$+7#o##}w?}$MGM16GWcmWT9zhfF{{TC^^j2KR$`m zzBbA2Ke?T?m%R`AW?_6gVKfJn0vV$NhZdcpDFc@W6X)@r?>`C*z_ES2<|t0F+6mc$9%-?=1XF3p9l{xxI=dr6 zOK^r#wv1(UQP5_v5exmOv5`JBgiG zjxE`eERC!gS@X!&`^SuAIY8<8y`P`{iId1$XP&vA`@XL4Wn$;^y!Ofy8GSm1X=dpY zF^)NQBZo5?qR}XAo&jIeH2kW{*nuR9fd2k|{`9Bc)1kF9?^qnYX_LFLu`EJSl~zl# zC#Xew0JZyRaKFW+oGvoBNRnYF4!mn3Wb8#Y+b1qXwKVek##VSK~zAr z9Wqm+Ko48CoPt@*dY^-e5H)X2R%lV&=d&z}IWM24LsOAbYix#ADj0kSp_0j(jpv@v z7O|Tq2kla!&+;}Njs&v`e;t9NP5@K5>nFIOgxJuf!l4wb9Rex%`7i#P8{c?p<30LS zuygKfnM)Pz@Q@BD1yYMtt5bmcc7fo zA7Nl~g7uq^rIf2OZ~BO;aTF8!v@l=$_IFqxi+K`c!F;($z_zHUDvzUcYNrb$DU@fJ zeQXbFu9hSuOqw=DAxNz6Y76K?HVlwLuvdy;t9Cuf@`epN-+Rpzr< zMv~)f-@c3YUVRORl4JDu50OeG2?BTB^&LL?(T}qBgcJDC)t7U^*=O_ouI+S`UMLL! z03ZNKL_t&!#aY+c$$bwz#Malmif4Xw4`ybXGcP@dJTNN+W;V<5$8Tcw#*Mt^#_Kub zj5GN7$3Hmzoy4c)XMOta|{M*&JaJz{VzM+qOyCNm``z3{lJei~6G2tw$Ps^%f}^9i8+#8j+Vx*VJ``9Xob=ENZ=hKue{P zY*;_ULeb_>GEF=lBM1P=KsLYZ-aU@4yQZ}lYgJXehDW^%mCF@rk+5mg(G-hCH!;46 z1hyn-nCZvI#~Wt)`K6f;J{WR7 zC`3+xX_i^E%h;kuSO`KdvyW747#vLS{A7+psRiQkPL3PwMCOY8;G5s%iN8J!IJ9em z-rhbE!y8$*`4k2=Z$*s-U_3{`27ePNq(uq@l1?ezWbs0kIjK-VLop0M$FWTo%q%`V z{-PL3fBkiv?swTA2|%&PX?s(b!`Puo0--R8L=Pi-cd};9dbS^!;LpGR9mgMk z0!vDbAPR4P&lYAUljQR=luC27hC66+O0@cev?2&W65E zg`$slizMH$dsr(KEEPWXhNJl48`h%PHZ3wsN*!Viu(@vLuzt5{hcH89Gy`R72j|BFl}SWV`H!srnHVi)I7E zo=C*lzk44Y@lJxkf@zXUC0QNsZ%k+Y_csan+^(fi8eRObNB+xup2ueY?87D>QDn`8oPd9^`N)Lx&b6ZuByC-~g)O z(!Lflmw*DvkfY^=y$ik4-2%W_ zlA<&wEDPRuwj^qlq{J|~NLz=fTFd0eMO#wxh-aed8dhK9DmcV@dl}jOCw}_9&+&~r zf5?A*{UMIsuz|;R{gLMnJja^elbD#8rh?;6I~|uurfC`-T9it|@c2SSg1c#{VP>*! zXst&t?deZ=1XLQ6l~x2825U8&F15g)|NT;?rAdnvm?Y^?b;fPU;rJ zjR=ukj#DF$^FS+s*arIgR?{tQ%9G<5hI=^P)r?n7+ebUb$1Zpe?C8>#i0z*V-$ z6|%|i-*G3`UH2inZNu|byVSa;9(|NH0e|@Qom_b78_DHtVy`%!kPsBHIp@-g062Sm z12YAagMZ$SB~7ZTiX}~Q(xhY^U}R($+qP}v_)W*ND5ZB@bI%bKl^burolk!LX0E^f zlg#7~HYx=971u=Mj*%{`3`?C@L<#D+#+E~ z1+{6DS4aQW3$SL5bGL3#l6IquB&B@8V@kUa7Ulp|Kf>|?*UkVn9(V z99_kSOWcZJ6C3R0fhQ00`O8jZXjOo7k26RxNe8WHY8wew;V{o#w{KzHF zHW2Oy&wFNFc?Nly2X&#@<(dx{j zFiIf%B!{1Pkb@&@aP(d-dE+OjrlE?vRs_ALSgHd|RTC724iR7;$RMz7L8maN89J@f ze#vG-unv{8;|zT3abCG$0}uS^l2geiOpo5|VwO9;iuEdNvL+SA} zmUQT8S16SnKw>HFKntqg&b;H$8PZ7SGlVpqa=An~uh1E8CplXnXFW^Dnn4y2j31n$ ztGk;Y{pdSfa>?s?-RoY@Pk-=Ze2!Zjt?la}ot`AO7-Vh#2KJ}-k{cN%cD5V-3uUD2 z#PPcI`vLtA`{2PjKxeZNXP4?{Q`cYl()!JuA5Sn8nkKKW=N&(u1<+EGxiE%1+7Hk_+HCQwLAZl#L_1S6biP<9r zJULDhlObU+pWRC+axRM-j)&*|hR`kc2=Ln~aoeCsijLR;rgJv2!PCj9a45ZtnCzuo z)cD-z|CPTz@Dz{!c7&en(ZtvH@L+nJ)rkm|LY7Qsim?MV=BE$Q;av~rZ0U84UD;RA zYjRYu2u3wzR&qFVn3LkeJhAO@PCDaE+EusfY?^k%2UeE}fox3m>&?18!=3(5PEOJh zcfF6cbQ@E;!1E4>|D&M0l|IE90qJhH^oWW>h6S^3Onzx1<+86rHl_wa1PhMElA_S6 zs{~D0)z!`Pbe2`!QCgS*eHB%!K!5)Rj@vlK&YdH~;|6|Bc(QM|FyAvaMxSAz1wtG= zv=5`NkJ;H-R>$M6+%Xz;NnJpjqIk!uYo@P=+6%Dlbze!d>}o!nB^r&Ao`8~LHDui@ z18^1fMt>r~;`sAOxj?xvPDh7JK})6f)7GUjQ^+*c9uny|u53_Qmfjh0{Rp|V zT=AS0U`@QgfqM>n@|t>ZaWs@6DQr*__DdVE*|Mph)2n$DN+4qp=|l>hbH4Q)6m%%K zuk+z+U&&F&cW`*e^Bw@jM0oz!ye;V(+Q9C;&$4ItD5|c~rV4hB?k0#ERB0AWeleco z6ho!An5L3UVo6CzRng)bIGB}e9LzGfaey{sfVq%h$~IY41#zKL(po5u1gW0Cj>Bew z)c6i^CM0bigF}P-{GNMw?{$|m4eU&hvGI}%`OD~b&OZAb=0Y{{5tUv-oO9NzkX5@u zRjt=r^=n?)OmhvFXvx+DHp!_jnqu&jKq+h znq$#khD*Km(#v_|H}~>XMq;2dZx`tm{qzz+PD)<$npd%J*C?>ONhtwKs?M~8F0u&S z^&6kQbt`kJG=|a7=y)2%=)^4A4d{klwpUPWU&=Rpq~gW4%LsMl0ARV{?FO43@?>Cb zUcO4Zs(X#qzh5Jorb)L4h6*=4K+>zTvvlja+r03kU){P+-Zas@{XxCXU98J0oAwBD z#YV*o({p#x?k1yGck#IeLQUq|mH8WWkAM^|0I9A8T(oWC@lH~y9EQyiT&4 zl_K#A)f*SNNaMO;tAbqd+0-`*es#HvUN`uZ{(-!YV8fhdFl%PL&b5msl}Ln?q*6uV z@dV&v5#7)^x6m(p1;5+%QX9$5tk?{A_(Ii%K2=cN4Ga>2yE&?LV0K@#Uv<-dm+#*kwj;>BNTC*d!NK{`XG6FtA+?#kz4AgR zr~)&|H1T*RdD}+y4r-k-4yo&1FM}39i=BfhW(f+LS89TR_+~Pug_H&XwMInL@JUJ8 zl=ws#Ma<)q4tZI@ls<%LBcy8-vv~}ohpG*;whvX!P)Y6trkFw!Fd$+UnOAid%p@Tx zh^q-^>@<#Apd>XSBWrljV@ddM@WhWB%&-NiWF2xQnjG|j>IBZ%3r4QS#;?pCvL6W|rAuM;xkFq`E^A3TXMJ4IHN z95Wc<<}W|Zy?1|-PmH*=PSBPDly=i3OO)14}ENDp8burn0}B&*m-Wbk+f z$_itq$+%FU-F3dMpQ;WOsLj3%>gRfBDL#oU=ZT za_ujX69eFsVRa4mD7^WjPjl^mZREV&3vhoC`tE|GUI!0rUe3!H?E5p1j;!LSA%kvR zvLlscShbl@2UuN>l2Dhx8DX;5#3u|6${hVjrb)6kZa_K9yW_pw7!8p#Gb{kdn`1m; zBsfiVuyZy~b2@K-(=R#k)HwHj;6#Gv7)wIM-x=Z2`(_}c;^-2)JVvh^LQIY_ll&`E zO3rxA#aw>HmHhC|uX53O=QEw!M`zq%$qb;X?sr$P^Y~=crArPdm<0>1x5QQFzYg1u z^6<8ugr!Lk2*nKw0)oUiD60&pS^TQxFJnbou{l)_5!4MT!lptTD+14zO$<|G7>AIY zz^89)1lS%~P>Tkc$}0w%*6gwejaU+rFf|H7=MWNPpPQW_1Vsw8XS7fV8r818ROaF)Cx#V`zXDLL-s zlbOz?k&YySLaeKP!s&`V=h7K~WSJtYS%mia>ZN??DtQvVo4o zFhUdxKEg^j9cqc0$!Ay{A7(r|&7zPif|^sQEQaB3INJ<^2nL$ycTMe6+zfi>aI6any68|;ioBivi0Tf+NP`t zuq1T3^t>s+XS(vabrFkikL$euww*3Ux3Hb-Ppt998{W)(vCLvRO<2_2j$c=tl6UNc zfyHc+QdV*>K183Lr6Vg@BUBEE6#w=3Htx9O4E)J)qKT70jnE$Hq@8-RFU0E35W-B+ zt*hL7-_N=H@;A_*h*7Z1gd{9lH5Rq~WV5XdMh4l`AEmQ1f^D0W%O-Dm`$ZHcbEv?3 zFT02@U;hP8yZSPI_GFstKKnSVj)Sz>_T>v$FKiZto250C&C+J{Q%xm7RcY1TT65O4 zX)|>ELXgg8X-BeM?4^UX^xBdggE6wXG)F(Vo7A&qV*M7QliJs6IPn^9P_ZI9&lV)gEFz2`~C5j5-TE28fN+y>5e;v2(dr8i*DUuk*YU^P(2El*Nte(#;AKr zglT($Gm?sFV;G$*nC`SC;&t>FyiArL0%_WWRrLjlyf53|7c0|3|B;T7EhS5yXT<2# zi43~q?V{=89*w~mMbjjtsthFtDcdHkYJeaS@AZX_=*$F~UQfW~=F1w39$6wt2q_~} zrNpE;IaJajeJeW1E!EJ=OoXa0u~}%wCBD>fU($vrt*YZAy`Aa;&}vFT@`ZDVg%vtx zS0eCIK9e1k8lY zJZ)}S5m?eeh&F_9f1a4wPhVFr0aYP8T_B*9v8;J&B1pUDQciNyN%UwZK3T#7Dzv#g zJE1f_yZZZ^HM7K2oq#Qwv2#>C4P{JMiH4w4(fGxe-bJ6BWXHB&5m38ORDvth+f9tsce0wry zeV@_khq&rv-(qUKN(9;H+SZSU`eLK1DtXhS3!C_+O`LkvJ2|%RE^dC?CFEoYM|0>j zQ|#J5L2usx)6;wDlB?+MieqNdNGC^&Y@tI~eEXJ9@U9!agp@@LBTlXnKq~*Sj&1`8 zu`+Wi;WyWV&ySKTtrFPF+cZeA7(kbkZ0dJtw=+Z|$Mf!A z&+^?zMoE44Jp8F5%$m?G2@B9P9kW!xEbXH`tTA@zFdcf>n}R3^1)kaU42hlu#;R`0 z`8@f29!GJQ7#*clD&aT|EsGMh%bjfG^BLMisIh5j?dfBBZf@BK>NqIjFplHkI1VLG z8dfbkSeE;E<-EngyyeMoY7L6m;loqx*tU&aDUVPz?72D0vg~etuyKLO4vEAnccs%K z^?4X2AwW*L$Zj(ZNS^)a7W#AJ%ydTh*7qOa_8%Y3hwpxtUwv^4a(V)Kbq?Hi1`$2P z*p7!d^`j2o_{<(|x%*=BuUJJ(;(YWQcY-ML(U0_T^(#)GC3h+tIzyz>X`~c%#QVK< z-t>HFFC{%%&!U~fwv)W|>;yOd$99Nr;J@#m<1?>%1)J03n8Kzocsg&t@^{eH&(qU8 zS?WB6oHVGJCLx5Ykrz=)QfDbpL8>0GJF`g*` zEmX)h!Az7!!v@-U{9C`~!~b#|-}}*B3=9k~Q`pbOjmOa6KLlnKgK;zj#gxgK!A)%6 z@f3f&?@zq;_J3#Z_#~@P8N{T60H3`1-}vJX{>F~|&yg~FDSK<@vix;f23wyR)SFHf zAz##U*dnV)S;ag8jP87n z=VnLf>t01>HbXq#&%8(1s?#{k?u02WShTAQ z4Y}+1ZMWSHwBgXsCFfs(X-XCf(v_DrJ};-S25XvF;YHD-QLmFPQPq0!r+QwCGVQ8L z#gUB!asjMN5#KB7oa`c5)@$cXLIR(>I?@XtXoOjK~DHN(a_~2t?v*kwUrES|>^r}}P zv8kU*OSKFKpPZp@Fb3l}S3jYtkTKaac92b*BUB_vug0`(n=W0YEZmJtyQ4y9&yPOB@Y6UsfpAd*f!(22xnc!vxEz2F7o6%wgTw}pYk+*G=xm1px{uuFCoU!rbiizxt z`Qz#nnS?i8DK(^F?m(k?2odlLwJ|bV5+D#9HM9ZSw%Kyh8T{nOcQnR~aHJ$kdPW?1 zgm1uG#DqXJ(WuPEs9Ip#Mfc?UKbTqnZ${lM-k3~PRidE?H-F*NeEIV?%JFNfKTBtv)!V29z0H^gB)qX@ zix5O(5t5TRA|lS3NC=_$c=XQq^8B{HP_mN@^sZt5p@X!F2!1_|gJ9N7Qnf6~=3%1x zB3sWqfhQh+3`6sA_vhZqHDAA-Y+~|2o?hmVsVrar z`WJZT`)?qSmXuK&W7MUl^RP|0`qN`J1$fJAze-p4{k-kfr;tA|gHLp@^VxmGv?)$G z>wG|AmDo&r;vf?flW0PrYG=_@h5Y_U>0G^)o3Foy&))ts4(5t1n38pIgZX0lAC{jS zdCt~1E03fPaGDmAo|@#NIK2WZyIK#oTFx5$lzdrQVudyiKzy2sd=KC{Dj&| z{PZ{f5C8d}|KUwbvyd|xN$tlpQ|K7{*-X)&*hFAbQZiGhgPZv4sLFS5{UfZ=T_d$n z+@M0$?Oe~5OdNlWuwO+{!bmH_oN1Bh>tS+g2FuEG<|!wTvnQ^}Tf(sEs;lX?FWo&K+MbT(klnq*!wJ7NTO5R4Lx+qcgcEZ4t zP%y$_gi<3vmuE>)XxG~5=m?W7l~AR_tXZHZmOxPi>GTYuB|tz?upAp_(ZXR7%d(iw zX2EoGPy#Z9Ps7U~GTeS!VT?`zYRr$oV$I3t!w*VC5A7u@dtHpP9AZx{#3j`n9KVTs zKUU$9=_HV%(y0?pPja>@c!)BW=^56_Hga-;L!)K&o_U(!1unopYQGJig-1i zErB+yszWxLVYCMGzXnWDG1v;mA#001BWNkljx9O`SUliV4L(A7F8P*)xs<)+N3|O^cSMJR{wcx>k_n%Viu-Dve-;Y!nJGnouYdEXKx1(KL-@GTD%utl2QczFi{>4fQiNmZVb%9^AF7vH8-p_C~GI6YavX zEbkmqT#^^Ek)U3od6ObnpvRX)%}u8-6c9oX>C&+dO;aJjTxyzlT%{x}%mW!u&MKHm zro4jBH6kyVCgnma0aar>Q()+*bqEnhwgQ7H1Nmm-^nCTzwtrB z#Wds!#Du|gRUt!&CD8@s!JEw08;>OkVLeXRQ(3G&`9m1zpThP}oyISIe?K4nzExja5!3$@xJ;cy3~QXU^Qdc$FA3QW(H+zD1#p-^(r{5~GI(|sSUevO62 zGDf(MY-x&Cf0S}L%c8XL3z(c7W6kj=xQ&a5aEpxIe&|xM1o%S%1U_02bgL?98*FJ) z7J_cwoq!2@Sys4cOJ-7ORt;?+m6~B)yoZl$`Vd@vCI_zF%J^-!aq0=T(yprb)ewoq zAbtUAOm!z(2*RB){Hoxbb1vafYJ#91U}R(j!-(To;f_1+G9DOgc4>+omz=I zZA?_^OMm1=X=sg2fvEj2%DiPBoBKQ!)~-F4_|EyjA3^Q#UYmc*a9atK?0aSgapYgh)w1Gho6*hydZv zup9d*Eqv04ZCglL#gYz&(azI5_tMwZ#kwu0QtKT+1O%E8m_?JBiTz9-*v(UWM_4^@ zELFRNPq?3XD+*HjC<}K+R2J@J4^&FhWO95IT_0kgGemzVzysgBh{D)5G*KX^ce8JL zicM#}nRS~_qa+mqs*02r3JQPy({I@R+#l$fo+UB7ma4r(Xdu9sKJh+oy!9*0nl9Ku zdd&b^+7yK(B%!QAEh6~d7w+XP=RJubS20Bj%dQZhm6OjrpW{wGi;{#)(dLv5r{Pys zMn`w@$M4?45C%);42sAzpP6OHv)|_3*IY+gxIQ!4NPca&%UCdN;_*1o>`rp%k$>Ye z|FVTW2M$xUOU&#@aoN?ww4dUHDV*be4>-r|IaVM{tKx6eEP!m-1Hjgp+J=+ zkEZ*1vYPuUxF%k5oC}Vbq#Miv!52}BGB7am7$>_CMHtMrBbYp_tPPvuzMea zs>QI{UC$R1q*!NrDB>d8=@;sew#23H{)u=fNGxV!i9x8to0fK>yL0u2&3ZUakqtNUz{fHT5pKX?*-Lgnh= z5O@D!l1s140TVE=nNM82#P!##COVnsY1u{J;2_EVL-2SC&0bA4tq_o1sH!`0oHVm^ z3y8#3rkgKx(&u(Xn!E?YxCf;}HF!dl0 z-E}4H#c>K)D8?{CN|x*@oobexlO!yTLP|-WVQ|Y$xAOGUkMs0XQ(SWCrF6s%HgDd* z@ClpQzI_|R!@~%nvc_^lbydy1m@O2Rwcs7LP0yA~@I_Tp(+Aji^2sDN#rT&`y&b2T zWLl~Ws5*JmMhZ!v>Uyaj8V@pRE^@}E1f~wZA6w*0U;7I<8Ho1s!w;OnS+PzQiZoEb zEk}q9ntc{4B_YdHL?Hq$*|X{Q3bx%q^R^i-X)q|ICm~+O=Ppn6o39CqS0+d*!mSSq z1rysYux>!7-H6hzwc|M3dGg_HoOj+C9COSuJo3mR1QG1pwvE%aY#|;Wpd=-ooe{Fx zX*x9bxw^Z$$lErBLZJ~rxYW2FJ1jWR=Dj-0J6D<|DJ{+m8+sK$*Q3lh`)P6f6tkH| z=v*OVq7S>6)w%*?!8AGNO>bgsY|PE8QWR`!igV99muH`Ng5k9TRFGsc)3kV>vy`AT zuC-3%-&{Sv+ITN3JT!`e1I%Y_H<-}dgf(v%19lV@1+p^`jZ)G38UFIq@Jt#`ywZi4 zSXthE#Rc4S|2{NTrA6&#KAS}s3!J(kMhl*H&$0<38`&gPRV8godUfHFqWVrGD|)?6 zrGp<8EvzwT=9!zDqtzdzLvLr!%wt(5exJf(3rssuD_L$+N0!N1iwq78acF#;kgo+z z3t?Fj-5(-bn#2ev$dzW$!*R?~3WOw)=y%~jDzxe$Skvo98VH+pn>SJ@r^!i(c}js+ zJq}qKN)p)wdvQr%DjU`hGM|&EYK<|o4C~JXX|U?}_3S+GH1B%HM?Bi7WNK=PV~;(S zJ$v@>>Q}#--~8q`^!4?zZ{H!hyQ3s$5Axm*-oQndzJ>e$@({PJiV}-zeEg=HdFz|s z%#VNaLwehL&@@3lpXZiaKE+$#aJid2FH|mk^+n!^WMJ4?kW&y%fKcf>VI6zNM+r%l z(>5K?)c7Pq==61VGM6sDpeA2AP*A=14yG+pg=m_N3i7tQZn(ZV*R);_l5GYRy_B@H zMY>bZ`K*g2t^==xP$_x#ha=Tb!6V3;b@hciO*6d)NMwb7JK%5f6&OYY2vL$LW|B!x z-ntdjOf^!X>zxWIWyA39vf;f^t%owJhrcZefltRB$u%YKR*>k1OBQHH@PG3b^fY&> z_XW72PbI=iJFP4+#T=r&!lX4$n+T)!_OXBeI5klr8VwLsBVOU}fT&Ot3O-qJi*p<- ztBn8-VW7f1C<_QtLlHrOm{c%c%A4+OTJH5KXcqREk9x5jhama9HrBDsD>3{)tIK`Y@|EpU$SuXY!nB z;}aSwGea=c&c>66dG(v##iu`Z1)*q=HcB`^K-Mn~3k|bm$UCWx&Ja^MHv!s+g!t3X z9%k#hHfq`3RILEE?Z*>5c@L8E92mz-0Dv#$6U8&7{FU%Ta>xZ&d; zBbKz+;Ga37eVFAl*9L`iYP7mQ={HI&mVm{OlRN`0mR|Luzu_47QC=4g5pr=hBNvQtIJg zzZ&uJ`cH3%zAiUQ#qQ!W_sw%p>HzoNbOF)aF3hYA?WcfRqpH?u6$LV=RFyu)_wMBZ zZ;d+VoC}bq%^!dLYhL?WSEdn1rKn3ZqmwJI|9{!OM}c()6sA2{O#o!oqc+$q+0AH1 zg>ZWqEvzv7b-mWq4O+`@LjYY5} zK(Qu`J8QwT3%b0QT+M zN2%nvNaBznpoB5a3^MN!Tny4)awwv>--B&KK~gC?SO`xFmU0u~dR2IC1oFdh+*WXQ z^Oet?#HnZZ@VChvcinIv|9s9tE_`r~!_#q)2Dd&s!mYdJsa>~)lSX%wmkGvY7OWIG zc{EZF;kON{NM=o&776p&EJ18&&bkq`7Z5WRlkKz{A&Nj%9U`9|=kxFHIs`i6D51AbFM&S8(viG6B>oxnaQ*V`J{z z&9_LdRKgE*glY%`rScS=VV!Jg20h$Hwlss3HZ4-8Y};6N8M?f>=YlOuvo=5a?Ke@S0HK1avu(#? ztd2+c!9CxjHQYtHTw-ZS^4GuKi=wpizyrTQQQDExBG@8WXxbS3;hz5j;Q1MN-aRt; z_Se1yv|y$)wE9CReub+pe;4I%R(a?9uOgi`iAB71PDpe;;C@$@gyA9H_qA`+f7ch8 zIB) zfA_W|+ygW(-5sNwM(SW$)3k~jeK_nKo#yth{VR_=`VfD(|0%W}cQ$!@mI^tq15@$V zkv3O`AtjdOP_=yca9AvWi9=1a(4mD0sTxA5Ae{oMWQ3ZiUtbk!O06Ng0`QSrA*niY zlA-*asfthfaE_RTD01aetQAJ+We%Z0KrA3N2cLAPQKafPjm7ijrYA4HRe_*WK`235 zfC?3S-q_#qrY-YC5Tb@AYQ!~IyJ zHeCue0aMvIUj3F2($;wt&!@^9ESHHyG*^~TL__IKqIqBorGcKWR{i!^@dy{` z8U2lJMbgZ&s19@0$8Y0s;Sl`;Ct((*2{6KceePp?_MRtLvg=w=*XL!MHsM4khpS~i zf8%fX^wl|J^7TxMUobCwSiAZttWX~{G$a~TT_>u?=}#mui#bd)%g-O!%|CzP``rF- zSFv}`URL+6BYj{Sv(Fa^0`rI_4Y|u&Us6@V0wyPOY+w(TJR8eMQGBk#QuGk5r(eQM z?j*v={bU$m&8E`{qOxIYoTakKNOA-8=d++1u;q~MX?Bc9VtGM_3-{KXQ zy&Drr&944K=jV$dvFkZ1ulvcvur9^bm-O(ZH=M>@_x_FRzdpnMziwez|1DGRKb5Tk z0ZtO^8dCN$tM*bug{ce$=MaxRzZ*@{_~D&*5YXB=cyQK(atPWaB!x;T5~E`N7P8bluFE*GYlqrm`Tr}2^T=}*;{X=UDE)C zd2d2umCGoKg5y|}%N7EG<2WcG&6Tex3K1nt(VM3Dm#XgBU0Z^sD%nzr#YO3Mjsd4s zBBCfPcxPMy1x0a-GJ9^01>BBuL~%FziUOrl=>=!A;#Zh63;6Y}I@2AniAEwE&iY{D z2{?8LtT<#wc;@%-z@LNT-ufBnehW{IRrt_WgPv>{-@pA2Pu+SclUw~PGQ_?#9Cgn$ z9N5Un?s?Y5U78tEKy(;K&yXR&f=r>RA^bu^7dnf!NkFPEev$MFVkC43ox}D4W>t$; zb(j_zXMTKya}p7beNzuTp`)m(HtF;jPHqfSL^))4F(`C~Wq@(q%&;rA4svdP3?U>H z0@SjSw7I}>XIu{()mkh=xGG zH?BR7JMQ=ifB5Vrw8vDgzJDM4pU!$MOx=C#`*r{}A2_dv*PL?+7vJ+Z5aJCVyNkj- zZ+SufMl(HXNeF^Rz)hCKvL8V<9}7(y_C?_~7}civx_F86x6){0Du^a8r0W;VFlX9y z^mbucvxEk8irEYm9G-dpSw0ny)8F4uGMS`XH#nS`X3Lf>1hZKNVll?YM!n`}3BRJT zX2S-up69^bfGjuC+_j|E*qA72O~<*?^rz$bz91|VY}=;Y=*Dpz_iF_&Lqa8+&C+HV zNNF`;Zxsd;gY4L|hry%#sA>&WbBT`8sLD(xLo}*$$|4#&Lh%cVj=LV&j)Svgu}F;}1>S!7t9i#e-bPeai5R-ud@ya$b@q)-^4!Q? zzW%kZ@aWE2*O#O~t~AHdLqm*?jS~unsV>ce)M*t0DQDbfiYlN8cYNdPTsjn>778(M zo21e%Cf78R_`RqGDP;rCJ2gIuuIqf_)1PGDu2H%o5hf>1_x)>bU};zg7FncPE}`pT z<~%v>qO|aVyY4E`r6?SnOE=C3zYlyhcYjs`{JtfGzlF-;B0+zU%AzZWuK5DI_XF3G zw+npiWAA6dv}r|>NsqhhT_Foy2}mWm=ce~@*$r2bnank4Uxv}ijL0@gI$vD=Rbe@> zT!`h(3qr7c$CD%?In)L+nI;Aao73(B}?CtH6v@JXk=SX>?C&X zHciu(1h#=vXbWw(r9j(-vJ`kYmX>Q5x(k%Dz;Z)jId;oYmM!$hu?JhOLMim5cble7 z(#A<+*SBPAWNBpSD|@~=et*nJcG9%4zvuZmkDes5tQn7HzVrEf-WR8xX04EBtTfYD zxyC3zJJ2)FkV-NzFo5IOyyqQPFfox^A+UdL!_uh>aygsXqD@E5qoXY;Nr#FYW9k$F zNT=6&)@8&Q8rsAXS*AuZtV)}Nk?mg13mEiZ!q!`?N++3^7{N-XJ#M3DCDi&NUa1Hv zMba0`#ry+3J2J}9&>#gV|39}Xo`XoIlFa0*I8Kg8d==f@Av)a!mX1vG{eOHDvDzGg znWMa7^)_ao86%a7Q&uiv!YmPJdzVY8prFtyooJdtB)$M>)G8WfrJ+?It_chkz$L+= zn4qb3vIqzfZj05I$x$yHSh;`;D*T*gC7=R;ixA0Us9IIO^9ZyM6-R;AMO8G>{F4yB z_;Ny2MGparTCGM6;RlV{NLizz!ps#bq}T4Gr+*tqGBu`cIP1I%5x$+GVR{hnt_!zw z_x%s^mTRtO-}Qg(yP*Zzn`*g`fj^}i>L-&av0Cq;o-L8on#|8Ufl__`7%a%v-LGaW zQzEC}6=$Bu5`q~eF!7RKyR0;I>5$&Cg^#}d0^a@Rb9iR&Eo@A8a_`Y+a8WD~pe`j% z<)JrSmdSyv!;3ce^3flCp7(t5QXc%(A$03h4jg@gcf9jEO!>mZE^B}_gWJhuZ8F&s zx^7}wCR+zLGkkEClP-EM`|tQBVda7zW9z9VkNxte>^T2YoRZUCz`O~Fq&u19Ti^Z; zm%UPFF;}GO3=oP}*#7E4g8HQ_vX>$AFF9#&kZjg#rk~B*)TN|5y#*nl(;VQB@hwQ% zB%l^}@x~4O{(o-d{43v0CM#(qWB*TAY=?gz4g*LF<|g=uH=K_;c$g2Ja}qm~L%i~1 zWw>KC??_E^?aOySJOsjXHkq&`PCvZy{Fid%w~y1eeiKe{8Zd~&<1C>e1k?m9qR{nT zrbkEl;|=ejLqV=o^(WF0*L9F3pJt%wj73NX!(=qYLdBs=M1UHF`FU2YT17TD%joD7 z2_pe$l&b|a*QKFpn0}T+CmOY&OGPOfjhfed1O**+)h?@ofgolgMLeEha$?2x7BN^n zhJNa{!|poVa{G0adX-=>NY!tS(!yX-2-l<}rc>~n2n7{M zsHW&KG)SdAOVgZZf4YGTQ8|M9oA;ny@(?$FL-LigcQ89S24mZJ(f5|HuQEtRpqT_d z`Fb|K?N>wwwsJu9kyLTd)>qY8^bz``2qAnYM@M>k0^Lf3^uozJ^z*rEQJ$l8_s3W$ zRR|*~I2s9k3-)N9pe~t2QqfId0|}+GVCON-2x+0i#1U#ky(~H)vsnVRAOmPtfDT;} zkQ&i*wjo_;Buo$$Pjnnld*=fJ=A8X z$8D~@=>f=X;BY3uS-m>9-o6)v$>X1R1+ks*u5UlcoqHwh2=VF5I!Lmgqn~;y8?OBw z6w_3zs*PwIuTK>IU{S4{xUQgXE%|O>O4V3g5pGyk6_oPyCFqf3G%Cw>#Q0);=umDu z1hJ*T=ulqrd6y8Bbpu&Zm_{5SLJSP7Bh@`lZmQBQ-djz=Suc4B2lnqLolav}7Bh$U zvo4)R2#ttgFfcH{uYY|z9cU<3!2p!sxObu*Bb*nSV8M0UIxpcTU@!ORu5S`lVdH>x zjLrSj$OOHo3^C_8gdN!qg>G^Cv-vEQN`+Kv1D(1-D%H)_p&`Ec-G3*Q>Z4MT9NvG( zGg;8Q{c5u~S4_0M3@=WoQ2{S(Hg1~Kr9!o`C000v_9agz%A%($vzk;gll;?_XA%{P ztaR953bNTS>yyc2g!pv@HT`s^96@n%)@!I+lsTo4%HfpFgJiQ=fz(UK#e$6F^K|%y zbI?Dib*a!zokd5o=txY<)1=Nh-qe3+aEQ4{n=qD#4vviwW+Qdk`cSGA=F6DDFeSH4 zM<7Tns8OiQqS3)*xlRD+=@p!^c`FzH#fwPjI!$44@1dtT{K&mLair)sm@Z2+QH=_Q zFmUUN4}Itwgb=*%-S49*ZBm21%x!6 zTK;$VI9FNEZ51ARa4)w$`2b6}y#DpCVf~gNWL5Fl{$by2K>GR-9bNafvC^ehDbW_b z+kP&Ju6x-j8~O)WY&Mvj%%9N2qcs+nQgX>97jXF{7m#x#jz9Pf9#@x!0(yiwC+82+ zA~;T-va(q-G(=r4>rh%KNQYYHNh+n7n8@?P8*k*p|M(H#xx$0lr1UuOH-6;{2qD-w zuz|76IP20LfAhB6ZsVehF5;9uXa0YtetDCQh7k0}BBax6Sz?K~xg5QQ;M%XghlZF( z#THoRQmMGylmMOJF6=;YCRn?@ZEfLmMVWd{mh#w>>OqA+E&PeP+0jHuc zQyRJvqEoH%PbMEz@&9&JD|G6Gsa>Hqr%*eNTkHDEfkt4(+S^Lx^{8YTA>mQpmVla6 zXu?}4HKj0)x%Dsk2+eck{KwGG!pFQnl>E$$TY8UP001BWNkl(+jnEeA}HnJ3SUqpmd}ZbKRRm&9ox>(tEcG#et-LK z*mF*hX?vKIv4LFiX||t!E}$`%vAO&;m$F!@Vml6DGwtQrj7+jB-RlJ%>N+3z+fOij z-%Y&u^q2F*y+5X}ZyUph529JyF-^~5Oeu*}f`-*kn4|Q$PxADGJ6Py@ie~PmB=k=7 zfi1|95w>jEj#4^q-m?_;60U7Rz?_p|(K?y!C$Hh5Uwwjw$_#P=Dtj*cFnrUXMuQpoNjs9OZ}ekdw1Y-a4dckH@N5YSPpvCwcaq9G#DG;%)6 z(7JUL3I!S(tTGK>*A^v_0183%zA!LJpp;9O(1;`q#)gLpt%?$l_CU74s#Q_u=jUno zXo}g>Ll~Ht)u@%rba!{t5!5h(0zDd~OA{=(o;bM^C=?24nnuYj6VfzRX;Hd_cV#CM z-fI?=YKPo)0$RjG^NS~~Taa+Oh({qa@3Q%n?cnI3NnE9fR7#Lbz{Y+^Wne~8muWhr zL9HZs<6kxS$wRy8{_xj0^y9a|HxI&-Ls%bq5Y`Srx}OVbF2DKWgG5D@m@1N>m-D2} z?d~K=c`-ezlP)YAdxD5(eFQ>~Z3os0YN4iA869^{)zc9U9_*moJcUkE;)o1+Wg^TN zHCH*OdKT>>dm z_@jK+0$F3{W;l|)kDtDA58dCo3Epxx(PWzXzENUHJeqYyYrA6|Bf@UeCPZ62zg+x! zS~c%cLrRB5WnfF`Q5=0yd|jMav3MdQ8>IrCPR4a9izbN`4pj?Eq3Z@m?HM+$9bzUk z&KcWJp<1X=sZ`jvZy!o2Hf-3y#KZ&zDaq$@?FMG}&><|V52ai}uIo?Ai}dxSXjGcs z8slq6TTM!bpB1!xbMx|D8vfeff!Ek9www?v3d7Lp(lm74phF3YPLb8gWZQ^m&OgqU zWg#@LzL}ewqac%91dOB2+EV0%)K#bSISN>)mma*2Mk z&ZuT1;TW&W?(hXOia)j z45O-5mg-GDbKqP*zo9S_eXlq1=+E89Xup))tttk(n;&@9}Am-nnPnHfwd0 zARZ05B|Gpk19cL@L`j7$Z4$c0f*pW@1M4iJ!o+bTO<<{BCkSZ4CNYAP8+F`9gGRH- zB6Z$-!OOVzi(e+WxgVi?O-9L~q2Mz8EohMn2%X`5hxx*%zQhlI^B|386SrQW5e%?8 z($D+f|9-+4yzAYs_wBRskXq&G@oIU8MVX|_vMA!wJY#-1`=84yYADs#nh7B=VqwLMq6~_Eo>%DN3|^~)r#VL-9+DCjQKBMBM1_d~X+w}oEn*m1`ovo5a-J|5BJmOd<;m`y_Z5+QwwhFG8>7TW*UL=#OkX&(1zJ@46FYW@wxZ9l@a7CrAhqW&Yyl3&~} zKb9y1WqZDKg~RTl1#X zx4q*mroOm?N3W{GcnJbtIyvznvN&ky#E^t46{Pf9ql8$XUR_bVAboM+FT%P5sJ@^%f=OtSI@7~BABU?B1S_ zFexF(`BTuma;OSLMOV0HnlO`eD@8+`PDg4T9Wu{=ZZK^>O4VDxJHd@2IW*J_+}+8a19Q-r<* zS=VO1QYJ`Cv}m`lLrtib&m5q)-D_GL+J;y@M}!dV1#ZobUT-q{fm^uA?xoY5VIiOA z{4=|_<;^=ihv$@PC?Glmjs?20cFu?M*Ou;hl*k>lc(JDXrR?x1<;tBoTXfLDQ4$=i(+uy zGPAR@IJ2|J`3keM1;&O)0gYm|%-r-83vPkQ+$?TgQLQ*=n#Rb;2nUV~dsMNyqFO9c zuP?Qy&YAfF#oR2p$w?+BC)=X?4i{==kn?3GCnu3kncU*Xpbh! zQvJ zaZR1x-Xy)fG5V4*PU;PjjYP=S`n-M5DW28^ag{-r;5Y%&=@1QJ`@HJ3zZNN)jzdvc z{`uuFZ8bTp6urvi%-9fp!XgD!GLm^Em~tkV&pg3aYcpZCV%r*r>=H|ONzg|Q?qjKB z(}_R`gQ=Wkvg9yVQcUOJ@yD}tC_y=2!p`SeD%A+YyaHgsmQ+-n*{a2te)16POqoZS5+<>f1$u?RH*aH;*h6Y^f$<-0^zh2{_-h!(uVj9gMygdh?ZI8Kqlz70rOBW#(>N^daQXY_FN=ux(B-;R{Zn{W?p zrGLX#|Gfp3@iBy`u*fQst5ewa1W^&EQpur|MzL6=p?UNz*LA(XNg!x=zkdr&QLb0R zEVz|6il>wx+KJ9nM-S1nDMiBxP?M61J4VTG>RMrTQ6b2VkF#ZSKSvH8q&IF5a}|?E zpJCG}r&E-kW2I9Zqgb3FmWtC@!Gs8}5Hahz&VnkU>*k8%%5g=Vw|(1|ben0PebTCH z@P~7zM=Mk|=sFWs!9U&p1Yf!%!B_sH&RcJImXF-Hz_)IAid$|x!q0E1^39v3xb>zZ zlzz3ytFHS4i^-5jiO>glR)L02NIICNPE+6yYZVw0gd!;f5fz|FoyqB0f`I^GYEo6OUtG<4l!QRy^7CT>;HQBy=BI+YqoStDkeG=;zrI>QGKbMARB zXZ+}XIvY*qRRyghgmRnISm3WNdlv(k5bpzf7>xa#zrCM@e4bn^#JCXD^j^Z41Qaxc zq^yLmc~mqVn@*Kvi6liKND7^T%rLL}S|Q;Hx|gsa5TJ<{W^5}L!}KWWi_IplddU_V z#c{sz^WP%Uy%e$~3Z(#URi{FV5;{exm>6ATY&4Iq$NBCLzmH=d;!T&nlBIf+NWHb zQRo!?+_bpzLP9<3?;5&pQuBrDi=_-FZ5SZ$P7*Sj+maP44=| z4@e5nlHb#f2p?6^+l;A(kA8S-jr7+d4}}S~BMP2-Zm%?rXvs`kD9W7Ukc!1{oZ_+6 zuRoVUb?m=I+vohoAAXOC$qAxD5bsShHR{>vby*hU2nIHu%yiCS8k^DSY1XY<2MES8 zHUlUM6O(|;YAf9qw<)FC@KY=A$9-8W<4@Q5OQy3chrU(9}I~jU(wK=<6v$EVv$WQ?lnh#4nZfa!6zV z%Stnq$xs)HgsxLp%FpS+Z(;?BNC@dSTV>^^x5&`8K}L#C zQ%)|s;Rtws-v8=R5`>5qer3~!cL9Enz67gQ@zQ1~Be?Kt& zf_W+p@m%p=8Cddp#dln_$maJ+81Lhw7k-_O9Qpv|$r{t68P2?NBcF*^xbD-B!i)BR zlOa%xBb*v%ZqfM9v!>}x85CrN?(QCPa~0~91=g?ct3Elw_oHg zI(YP+f@0CBdQd zAA0~R+DkMVC7YY4H?@k%*=ejbn~=kkl-&yTS(iN*rhPHJL=#OO5-odT9W)Da83sSG z-$Ou!?lmc52>N;%`uvk#fTJ+s^dY!+E$m3b(Ht-O=w5Jak21A!$Xii1q*?u;$2?6; z%OOT8kJ6!}kE~c=?DvGh0{VqRM1d40bHXGl6pmvfgicg=ngZ|o*W2_O)3+z}GQmtz zF_Yijb2lIP$Tj@UTQ21dZ@Gd+$Dz~oRBY$GbQ{0D^N&p1MW#mcJbm;4xBTFTBocx* zzxmC4{_`JZcD6vZ>Qb*)_~s9O&VnsDX~O`w+;R)I-0~xK?>>ob+fL=yTYpcrILG?+ ztBJ?Ex$);er+)NdI#Vv6`RFUS=7v8)D$Q1B16}*}@$gk!*!t?*VfEDn-v37yfAmt^ z$stZn>oh_U%)kFN4ISfdb^r2!eP1KyF6%&Kg{pv*f|Qk_tX#THo!oeaf|LvmZD3+z9Lw_J z8`9}Cx~}u^Ll4o=1hLd==2d{sn92UT9>y@d1ea7?kjoW`3Iny`8kLm_!f&j4;whh6 zvuq*T>Q~xn_HA@UvSafgW7#ZWwL&PZLw95q;F+exRfaPMn#?&4&lommm=PY65-O6D zHN`;`RBV!#B9G#Auik}L%KBMm8BDffnlXw}dX7*^5ioUhJp|pJz}vPn9(ouE5Q-RR zZj+Mh^5uVgKX1I^3Nn);NLeFkC8_!7VnYZTA=(Bu^=b{N6iv}`M1!1TV_8W`j?JP| zrBE2BBfb{5u|zBorP?fWXy1LDx@$eCr{VO|IQqfM(MPKUOcP4O>><LGo6Nyo$5V zu~{;U9E#|eksE-!6IWNzpKOVy@dO_1$MVpg$Jj~SapSNv?p}`@f ztRYN+oww0-y2xoPj)QI6 z$JifdG8sQ}1G-JC4affJ10!gNCN7GGa1oluWI^(Wd-h{?M_E!DLI|qGV!OyN41tDA zrDfyD62eC~TGT5cS~K7zbs42vtb0YE(Ilj6f3k@>=6E01n1o*-XJTa&<9#mS=Xqrd z_CArJv3p!I;-0WUc|QN^=eDrn_IoshhQLLsFv{o6uhiHG;ng8hNguTn9`szPVyI|4 z=cJ%PK$U5VMNG4g;xo_s?sR=*rNT%LV#=&nh$}^>>1F*)+a=QJUKa8tGBbxTgopI3 zJVHxt>pnqQIdqx*l%>PkwJ~NM)H(T#5R>C&3b{N(FHI5Dn-m-mJt<^tx-E+(yyD-s zGo;hrdo9={bQz#Oo}gZQgyESH;%i@o9tojp_zCe6UAIsQ<}wZu3lhe5GUG>C6E73h zHZy$meqOIfurXP5yfo`oLZ>Jt^G=?i9%(lYWod(mQ7q08(Pj|BKsS9g*1d$cbbw{Zhrk@6U;z7rW`SdNvqQ(lL-fA(!{%^jPZ~gp1v@?3imPRS-gVca} z_5dHdcs)J++j-}Ww{mjd7)7}aM4B@OBK+sSe1WgO>k@hr@W{TsoPOpx+Z# z`4x>uF``DOY{za^2%MbR{vpZA)Sa=FZw!IODv|C6lIG}iU@ zGnSjAtF>mubzBwTy@uk0G6OUC(_7#v8;rOY%v6bkCcU|%8~5jrBc3&=O2LzNd3v8Y z!<&MtI6Rt#c+*2@Qd{835$}Chr(wF}xr=Frmu_$5A)e!!YcA$BR*>CE?~I;`rJ+AU zms6#`e=|}-A)6)Pr*;?GnO(lF&@XBo$HDRGqMJ5t;)*LSqc@p^q-Xwe&pr41p@I^} zvDvbDh^O{G%&uLhvSGsjmtS%rZ++vXG=$EVKl4RydEg$Dl5F3;1v{TXDapwvujk4) zyn(Y{em0-`)aL;B+-E+)r$75?{zECgcGbmvjTqq=T%$Q~RFYBaSz`&zh|A$$UCrkA z-NMD&rkPQF6h$9M$%fu07nntUGjkUkUoyyt-u`MPOW76d0@^mk4P9>+0b!J<8}J>w zx=b&;d17LcnTbPO_xB%QVZO}o?|uMTk*x1a^T@~{3|)W0BBF%^Ecxz~t*hc#JUYC6@}weIePRc30)^Mlc5tx_nC~09;7J*LKC>E z!kVECWHK2vA=*^N=eP&DF0Fv#pzb*mxvq;Y43t|TD&owyEWVY(Na>Vv64Q*6p8+Fo z0ABMItSLrD4k3i_MfE1LnG9uh8jn5t0A0c$r0cj&jf8HJ%jJj)K@EjLoOoQPlyj&^ ziSD~>y8eRK(xK$U7t+Ya%80UC}?(AP0h zl#nt>=%#0I(`-_$IyCBa{_?ET`OtMACqFv8JREaM%sCDL)1*rX;-QFNSqOr$7zrU5 z$&C1}vL4E`=#&TvK}bNcWV2}RC2pM#1TY2+GV>#(Ogz1qQml3|gh_KmDLVUiGdBs{ zy-+2?oSk7Ef<*6j{(av(xBmQB{Qkoik)%n7YEo3*HVe|m$;`rP3o4RKCPO-HLNG{o z_Zojxfuh z8uypuEnpwycbDy8(6m{!hl%PY4JFX^blbhlwrvWs%FdxdA`yX$*R0=p$K#x_{S=;h z>Im!BujiB(ok}j3^R&zUtfJG6m?KKz`S;i2WXREASoXQj-V`v3s<=6sWDHmNAlx#(2u1d97 z!7wyZ-9dtS6D0#}yWl^^rgiCgnt>N?TAFQM@$=fhiszm(9mgfouN2L%{FxIuHJo@m zODqWpt8n}Mgjiz9J@#iiY60pjPyaB?6%IMV_wa7HWqPb!(@Y|zVqoJCPdsJG-H`80|VTRcU|DCrpwEK0Wd)G2oYEcyx3$~4}o9Mbl-fsYg z(iTtr{?`cMLCGOK!l9$nyz(tWEI4_hy3V3>&~=bf&}sIP=(YLRf4-Oh_?I)Nj5H{_ zhba|Z7M%=Iq^K(h3!RF;jh=x)f{_Sg*(^#`+1TI9$ie$b7y@0?kL%Hm>Lt8y`MO*$q8l`fXjs5-DBZrvHLOj(&F*nQn ze8Dpv$J@a| zz>ph}QZcVriK|U?nlTEp>YqnpI#dGFjL@NKI1Z%K+fb_Jqai&cbkY9&2N6s&!WkzQ z2!&Ey`<`pK_153BYW-@Wt4(^$IQt)cnwOn>4(FZsDh37ynRD!8rqW)yJYiOx)9W*O*GQ$AOqUh#Tv8jKLe=84h6MAS0pdue6S>tFGv zsWYFkS(Ub!8kwZaijm3W$z(GK0bjoUa};Oi7&-U|pZ)Ad`Nz-Rz+(pv5I5tLayc-? z^A;Jc`)PQE!%$QR3QCbcBPc>FDn-LDre}*qx`ZH;u_?PAO5jwAfQxDBOxqcXGUp*7 zm5PTx2o2>bDwQ$=0|WeS_z*e?I$A-&D!`Ijo1Ok2G7cRSYoy5+an|SX#-od9o z^Tl>RrY=Ae5w9$fl3Heg4qYdqBtjIah*MasMabHd2oYdb7_322kUCpG{GSkq!(TW9 zsQCI0MNn1Qym^p+{6bZV9kRq}?3hG$3-iR*1$^Zb07U*3Hi!;d_Iu7?Py z05LO0-p-?&I$c(pXtEa}AUB$)LrFT!0MTSGJ9g~?sd#MPBW-l7COj0nlF7313sfvm&s9dUVZgL zOy=Tn>HETlL`{doshpMlcZI z-@bl5=be8pW23{Ersw9`A=L_&kM7f;nlw?k3Kpd#uA9u*9%VX!B55U2O44nb9J%#I zHeUQrBE|rVO#B+Y|26p1&!AX?C-T0Vpb0zxbC0oa&l=X8 z93rSZ%H^V?hzgw!f6zZLkY*?(2#F9Ez2*Ww@b33<^ymbyd;O(e_R07dOTe0;4fG78 zx$CYw*}Hc?*I)ky4jw#=Wu<+Ulu226&2!_=1`1x-;<(MMP|wfe3LWFMES~QNUPu5d zSZ(#P=y&&~X|_B5hHml9zWb;ai=2JtE)G2UN2-;1sznV~^%7C1(rsFdFiIwqQY`N| zq_`(+P#Quzj^_3JM6X6$$jLF5j1BSUQEtNO#NRs+Rj|#k0EL<~S`&2T!()E_1BOOWkGB2g!zj=7Qw0d=2F^^5aAu5G^v2kGcmgFXg1SjV zN=gX2tbQ_?S%h%eym<}7k351>vuG?)mlc#7z@>U@hSmP^#wNU_A|5OUPNySGoMMH}T2We4h8dZ51KC zi}mIvZvWLcdDYwB&fMV|4q1<;*P5*AIujFFx~vGNY#!u}-~0i{6HqQ?)j+BMyI*#p zzfflB>rZ;YRsMO|Q45?<=qFIV<@rkLh_|*REsM*4IL)1R9E52}^H&#<6cdaqgLmC} zgxl{;@sr1X$0z^xR6emQO=jOd5}OB!nI^Bia4Yvdw4dQaHs_tUhdb_jn8yx`aQa`o zigY?g%CtC~wOJGr(-bU<7*%J6ay|=&19OLv@|DavRnNW?hsXCl!M>3vF`^pj=xR#L zBRWE8!KQDLQK4LRJtV^|JRQvZ{5<8dMxo-cZEy>V zle2WJN>DRga<<(Lwrom?TQb==up1#lbgC+gP6jM5m@z3NRpDT6-$EFH;|vo9VguWK z=SPRUt&ucigiX1kXfr8FSV9mP7$=~{=|W>wI)on4+cX#rftb|TZ0%%17O4ke$6sE~ zrc+))R5*0Tr_hpT@S;;Zs>xH2KhBOVJLynRR*ui*caTz17Sg9q>TONO#F3}?*^htB zTi$X7y}bhj^boJT;I+JD*J+H7PEl5hgnysWb)DhiL+HBT>UX@8>;CEUXhN`l{d#m= zC!MyiEDOUBBy_<~?!A+ff3&ep*J%iyUAuO-8~z1HvaMeLaS&^fnHnM@X<7z{dwV(k z>VJp3qcs0`8Ksd~(iZ&aktwde<|){e=7I0Ml$RtWqxrybV)vCaD3F;<+lgmYy4TB@ zu##9-k{w$&@%Y{c*thQyW+x};5}Hr7RtyXbFr_Nb%TQ<)5@A5;I^kl`!^VYYxxJ*j zgr(~ZErre!E^$K;qor#RMB+Nn9GN021gTVt?D#lq`ufP_a)4rDVuG}2$KM<*wknX!?w$WSVUZs?>^DHePxqK=N^MYF8kZl{<%76UuC%oIE0KFpfI?VdS?P)wCd5I4b$5K70XsQ@(u zL0q1+hgp>#AZ)ofA%R^h5>=9-wbtK)$ziE`_u-U@5Q3tUrAsK@d*zk9@xlw3oy<^| z0goCroxwD>Q5p8mjlz7Ho4@xJGKYuJ^^ixmRMJb7*L8Z+{bdk6N5+3RU=Ou>_nJkH0i|2*IM=FLn}XKvCP;83*bkR_CY|Ji># z=Zvg_y`$hh4C~J3Gaq}9$YC z=uI*)dKf7Kq|-VzS)=5X+Re@Sm+#?iZ@ZZ9eeZV+X)sdv)8;DAZkjwCfPoBkv`cX_2meWB(KL!;LGRS!$p?`QqQ?k?^q#vu>>R^S?dATqZ$84k_mcJK1u9$WF3Bt6U_ls!NPV>|w zg8y^#f3V}!7h&h-h{t&TNyv%T%*;G`EmP_4;Yc%@aF>mp@=csz|^ME!%lM6I&0d~o7j zXd26bO`_?S;~E_*j8Xx{$Ey@7Wej79RCfq7m7pOspIY?i>P4Pkk8+~#{dr&7pGZY{ zZsXE=9KRn8UmzcTf&FbYOX24fOrCvYz(;&KYJoN-p&D47C^~c&Ly9cFvpHV^wtu)E4H+`1XsW=*t%N0CqLF;U9E9^s; zj-w%EoYC@F4^&6B65cQSd*rcA)$*l$65J7NxgcAllqf<=QDr9 z$!lvk&Nv}`kl+0AaW1*?qtw;1$gK5q-hP+JW^3GZ%lCQ5dw+qsHHNEVbjPFYz3mrl ziMfQN?Z4jB$aqs?h#?v5ZSte9ew3tesTQB5l&g^J+ra*3r`Y}S*RWWUC!kq*RIr^p zPvT$>YG$0G?4TwUwaOUJK5{!lrp}<{`r(icLEXCs5_*%9dLuZK`?%%1A4e0dPub$( zr>1!Q74KvwU-GjWR-6gyg(+Zd_}Aw%2XzmYzy82s?!03Zi~;CYRFq9c#sQtnc6UPG zL!b;k`L$>H`XhC=45Ud+=2>zC1uNtq;{dnbdOKZ~#aPCnE(1(VWEmaJBZQ*I)XCd6 zbB+gRM|AkzSKrE=zy2gGmW~7bP6OQ2KkCZ zC}NxtN%6La@9d>9IX%Yu!9ffWBoy^%p5>}Te@}|Z$w@?1qr1C@E}=0qGwx68bTlET zh8&idpdb%pli{dvn6d;%beBRpM5k%;6yrRhM$mPWhOpQxGwgFRRFsYyC^OAbGRmeX zZRVB3yt0{Mgko|A*A5US1(+U!kq>asA0Fkmzr2ThzDmgoVG|;vTU_$Si}~qyKg%Ef z=N5VfhB)QSSFvqqh`N+GPL8!}hlnOa{-oE!G)=lJt9?I`vWjizna|jiN)E2;^7q$W zNvB!iclZ2&XAa-b1#j3*Vtt4uax9UftZG=6#S>3F!FAVtoOfS!6~Rb^fByRQbfrv+ z#W|#O2>K%RPSfNo|MC^4X6O0akA9RV9(jcR{$9TSt*;YHc`iC-1x7lJBLm>1K`FM1 zPDII}zrUZ;&%Ft9uLGmPq^wfj*#m<~`Wg3VcG@2P;?iGpdwu}ZG~12I@yL6J@&x%SSCXzYvU9h@|6OaY=(4Snu&=Cvg7vi-cy$y`j(jsN+~p9 z95YZ`$a#&=%*;4S1(+>L$_k3bA`7ZQJRax3fdeFbn_gKdV(5bH+qZM*=_e4HC&usY z?)Ji(mBLl7Kg3(s<}_9~e6^hJ%IesHzag5(AV8p@35di^aygrB)1vAqI?Xs8D!|Ol zG*&8wotyFKGr1gHmdVJ-NV|r3YGQ_<9&cZJt9;(Rt{dcXxweK!DbE$HW5pW0Y*qaH zwL;PHGVJbo=wANkXaCJ5mt4aCx%p-W2m5_`n~uGLpSJ*Hq+(XWh*M*iH9(&uSv8R- zm9Mc`8EjIDH4aemCgj#&uQ#dpkC%o*N{4JVLx-;wE-M8G4|&$Yrq}oqfX)D1dg*I? z{evQ+>pqRYMtA=pBIFGo3R3zAk!p*t!NqYDL7@}WO;-00(ru=39B-JI$>ixD*h+44 zg!jGgZ$NJz_$v0;c?{PgOd@#Y)nxOgvhd+EBPYw@zHCDt&2T}hkX~PRKiCE!;#|m^-tr&=R98d3hevQZR z#jN+dX_}OkWVPi9ot5&$%>^m3^9~>T;x`HEDK_soll7`0e;dNKMn~VQ1ZEqgl zR(Yp?e{Pzt}6u2Y5? z+D@0DE7P5J3Ur}t4Lc!ZA*X+qW=sAZ1-Nb?0ktpnsf&}U&N#(lhKY$Rvv!ey8$cLgBJoz=)UO*&%JGM? zqg--1huMi3rrAbU_nb!p^ViPalRW+Z`Gq`wqw>FPQiA$_`~CjDzq7c3@fw#3TD$%Y z@~@@XR~paZ0-;8DI`y~)OM{z3YrAof2epZmZDfa!5|U8@T65ykc0PaIKhWJ1BR{ka z+s+de&~6D1?cK%lB=p2we)`pGS!ou036_slFr$rPxlY8HwKG^&2S&nWWF*UQHp?F$ ze~@>4@`v=VIE6VmkCe0g;m0>o+4legs}pFQA*gMpRGyHsiRgp0i6MS<`+MkdMzNGj zDW`COyYfOPpSp){ ze(Ft}5YPLsRg|0^WX&n(V)gVf;ct7~a{0x5S&PUv3(c}b)#1aT07%IR^R=ku_F37n_Fg9JJWAPKf0asd&wckZOO0q$ z5)MQfgfDPuvs&qBwTMPUqY;@YJIs{b7kEda(Kg!J+9;YN^#o20MayRZRAIaq#&pzQPE38rzwvFsb&HM@`{8i6SfzM z+D<7*CP8bPnjN5K8-PW#)sGNqv=)SvB$TbvholclBvWRYuvn2u@W}Um#xK6`HC7}N zlny>ct196R4ROsSXHeY#ICuX1KRE5I)2T+%#3K=|yz+9Slnf6aWGd_3PxAS^KSc93 zn5{mDWkxG3%bNxc4Gp2nULk$fS!dDL*Tb4MYx&ETzp$jQ$A5o%l$%3`#v14UaCQ`g zVC~wqw6`yzqqnEwJ4hzGXl?BPpJKG`tg{+{h_iN)Fp4>46V%ExC~Ff$j(IUkq^F;E z-uM6%S3qtHlmESeSj^$^!Vphq3%v6D^;92z1BiRzlucaxovnmI;sp{X-5}|SMcF1E zK%Z!!z7P)+m{uL`c$D{v^X0+zS6IU{s$utbO z9u!5>e4Na2-dG$0>D}w=ew5}$!y*W}uGd5uf?Up%o9!Ol1BeD~X#f7h^!N2J?IToo z?%2T_uDF^fo_Lm1)^B90=t~LXNyf+X%-Th&N|DRuFim+3&R;3z;lPFXs|3|!o4|#w zSlmjXHKbDAgrsEe-o0FO*{gW;(MNsxEPkGb23;nkY|>Kr1!{sJY$k+aKAmJrTI7I& zvdN*KyBAPQ7s_4^RW3tND?0o7n9<(zKBW|U_wMsREM^=W?=cs~#~~Qt(sNJp2Y%i* zrK~*9(UShvRI3IR1WG}R3VEWE}nH#Ev$vq>CjEpd+%Iw`cL?)9VpU=?S z+e>e6FUdrbGfv&WcklQH{U@yCoO3oYGI9{hvS_wsLyP?49u>8SOyUO@;bqJlR4{}= zv_9>`rCgl$3vPpED{)MINzj)wY3*Vc75T9uhUlO@-by4s&%7w&GUHEIjAJ^&7i&a< zeu2OEcm3mky}0|o`OA3GhUNI5@AzLeaqJ|o{Tna<7iwR0>qtrrlbC)&eEqUGIGlzrXKKq*9%9 zrKhPM$F4m~{y1_t`*O~;tG_i)?iUQ5V+jF>7ADMsj!X?E{^jyJsR z;}m^)h7gi`ei|vIFA3C47xGw^WImMOfvpeo>i68sDd(iI^I=Xop_@*T;j?eKko$l6 z9X1T~5sB1D#X_{8_}n{Q!^8i58%wNNqQJ<3L52@cpxprHUib>iLN+weUcn+8H@A5K zqoY|ayy|Lp>{Wh2u$vCq$))F?#|Ped0bl#*bsQZz$kNUTYkLwzwBl#q`~pAz`p4)o zZPr?4Z#pKUYV0^LZO1_V>s$7lt79b?=N{7?jHjic3M;eCJcI$KG~? zSl*yJ86s4+$sY`2Y|AqGsmoyeS;%V+YRx`t9F?fD=U2a`N!B>+w39GRxa1$sXWnqR z_10Ti(%;XNf)44KQlld2pA8;{G^9!-u?Zu*L}~#X9_G@QU&yP@IFHq<`>52)oUw5; zhG9^c@d`D=h&Di6t-f^2Xgc;f^UU{?OioUcj7D+iG#wq?XxE{&HO1!h&u^qw+jfzj zl`AP0r|9eJBN8zwxh_^~%1fvBw=>88_L`#^X393z8J8v@m?@VTnV7&Z47BS~nV-ke zWlrc>#lXOT-_*jCUI=C?3UDL@EJ4XHvO_9QHx8#t4OsNCh9#_^1dQcNR5J!`DoI&r zT9t{E79|u1$*@-+q~Pnb+qKD{fUPQz(;H)(J;L*aQNDc7fAW*<5ApQqK7zeTcH30~ zJ$=0LEjMz?MOOi^d)qcfw>?Uegw{?k?_%lF-s3!r-lnwU%Y!!$jWr!(dGcYiK5Q36jV)g0)?_5fx5yEWbU3B#J zkjaeGwY-lxt*M1-O!|2Js1RIw&Ur+%Vov1=qX}vS)-afYJ^2wzB>CyXWr!EK{h>>V zLmG}s4*1vc;;#>QzAfby|2aP+rRr#0 z?cFQ$V>yz^B)MFU&705Q9dCX!Pd>SYa&f95=IZKN>NlR={Us{u#38rwn%8}rbuwbq z|GC0={+)TlAm|4`&Ms=~03vZodpw1df^>QrTDv&T6ce`1h7B9YWHS8Y8{R;(wD{8> zf5+j&hgs6y?H6-`!NJ`$NfXo0k!yG`eb9h*U82HlnCcr;GM{kz!Y0uB!?gC|ZCn@1 zMK265pU?T=7=g36b`vfUZPO)OEN#=IY&s$lR>%mgkr*i?C&UsYI@2r@!jl(in+}u@ zwy+2Tqx<$@Sr(C=ev-)~%h&XIrv11Dj;4?=uy*aqFjwPU?|wVe1shWcOd(LJOiR++ zip*#z6bfG6kiY$^c&}JPfpN<%xA3*w|BXbV7p(<{M@Q-F@25#h_U#=)2#c;{8n;xh z^;+4sZ35c6hzY35B(k~`TqxQ{u~mQ}DWSUt+UCEmZY42VVtike3MNu&q!M(>0p>-T z>3oUqzCQB#tk;cqr^#eS{Kh>zRHmpjwyh|X z%FOuzi9!fmptG}wQmN$ow-syFtZuyCRVgU}nO#G?_U%{F6o^utacL7aZKebi6*OH# zyXY#EDO4?**RST^KXnPO{@`*rw+4)ZlV@u0ewLJ~tQHm&N>otPl3w%p>5qS$_rK#E zfQuCDBb#)^IjF0Dt$7Q3zPA1cgjAR=0*0Wyv65e;+`|0dVpnUIXOESU# zAHV*Z5-5b0G|5^c-O?){>w4l|410um;dP%?Y5CIu?Hk@9CL}Xj(Tm6*(|6$Y1_)A19r3GU;^M)8zXrbgmI;y~mTSQ@ zCz-cfSluPrI^2z^+la~<%03FR;vXKKAgSt9DHb)#31f%^D^`tR2*Xc^uOF*3jSa)! zl3&#&QO(CF%j->m7vETaOf_FxrRyXzQEPn9%A)ol?0?t)$!Nd$= z_<==RrMkDpTk;2Vps}6{`=Eh<8(>OnlA=J605c94*w_TnTF|S@eD9`<=@ptEUi*Y^ z4wJaC8cir3H%F-mft^2$5HVVk9oX8XY*$&iG{~>M@@k@hDO(mbloc$(2x(AZo^X7U zG0q{XvyAAcsdObsyYg3;H;(RGZp&?3jhEh07*naRH3FAB|~WC3HL zJg2-SZDLgL+~F~9|MZ)%L=Q@BCr*rWS9Q=Xv;6V4EBLijA`G;eG3G^$Rx?c1N|QHC zVvfTPfBhUkc=TDOBAsOOSyp!@DChJ3n?(4A;TkTI3KkW-0M>f3v3R2*SX68&{{}3_ zNh_F_A%^7&vLZ)2U|0qv(ThVKQiCAQp}$~(ZE|FNh_@a3J*D3VdEF&pL{anmZ{I`9 zk|m^7vt0fUJ-7u)rxc8#30OtK8nQ|fp~ws?KtveT1u%<#AyFpYYBCY8P@V|z z;Nx3pYfBMq(##t$K6%7fz#EK?9YtCuQ&UrPbQnxdDhxy7x}K!bGz|jo5tdmYCUc{# z?_a{@uYMy>J-3}ydy2;&e3UQV@?jp|x|LdYJEd*g*tDjPo!hq3W(cMnmqHB$0gNVt zfa^)i^t^}J4Il^;!Ewv{pFMhzOr=IFbS%7c-_@{Jrr>NjH z%oTqVF}Ujq?!W81XzlRy7S9mA^_e{w?cG%HfE-iGqel(z-^U++aTj4U9cGgM8sEd< zV4l;`U3AC^3f37+$NFfOc@RaIFxV(AB&8H|dzjPrX&XkDVfWPd)m^`#C%%+(HlB`< z{p0{nNy7m}CYvGZn|SLJ>w1{lj8=p+G>HY6Osf>^-dEt{lTY%gQZVaivctm|M$MCp z#giNz0mo4!lhz{Am!~eMG^U(_Fdj~PMk^w5$@usH68)?gS7utR;jW!pvC(n}j3tJg4IP2>GJDI5-95y)J-@r*{ZDLX>Od)Y}fC`GF@Dw%8 z!eV%21g#BD-nfxUNqaS>^nfY(oujDX2idW`O8FmOK?zVuDoXpg9YuuD%;a;#dp2>- zx*m2se~|q#z$~KW*=P+mc`))gLgQL7lD6YX%3r#Pl9j{|us#t1A=tHV2qUS9=mG&d z?=_jDE;Aa43)nx1BTr#Y)Ce%g`DdI2%7a`7@$$pwh4f(}Ws(Wsn~25;;b-0G#*n-? zx{GEjK|o3hg%VnuRHcQ`ie~N5j38h+Q0nKOUUe$}`P)Y*3yaD1Nx-6lpt5>^3WCr4 z_G#|eIt$A3|T1B9crR+CI31QJ>3m)EfH|634FTeaB*}iX|4=Yks zWeCUdJcDs7<)gDTC0k)xDU`BlNk(wcOglxSkX&%a25$b?4SfFdpC_9w`E{N^2pf>t zwt<;$V@mBKj;2kdaT#Prul1ur3Iy_5{`ki&{L_2h#Ws5v5uK#j@(!pu|9$V(Dh|R} zAZdo?^g_|nB)!ar3Ey`Trb<~@jRGR-8|~WAwE0H0Or6fP2)oxH`S=%IP}^+WxRJZZ zM`*E996311(PEBND#g~VTe;+tOW3gCw8r69C=`gr0<7%qqma=aqrISrMl8Pi`LA%^ zMHg}A1sBoZ-@nL%^4E2qQd(4Wz9D_79|l#&CFp7<$rCkP!pRUv)j_nLXI7ZZs7Y_i zpi=%cyoI2KNv$b40bE}~rkt41YIm8@Rlp@G3?lKEPhuJWA9_T;923WWZuYp|a$eNX z{-IDOh|T->MQ`&G_HP{FV^|4wB8q2DU)XX4wF`dZqBuVB{)O9>vaJ`Pg~Kl}?^m>L zB-&RNZDT6+%T+|tdIqfn%!&}zD!#cA=C!6;_6iPfB4iP>HRfoIL{E~7ogO-c%RCN_ z<1()mA)rkdbjCZWiUhV&K#}dk19A&V?u?eaoH4&g~=>XH?CE7%aoC*=vX2Zzk zg&-=d&Ll^MMi|qYnduA{CIW0&=WyM--^i1X{E+TsjqYR|M+eZl8B?T5rX*#1kWy|x zk$5XbCrazmbGh=vH#1)HF6f}I>qIZ+|HG`U5mJ&u&_tDG>0TbY=jXijRaf$%H*O*> zrkNfeC2bh2IsGJ*nxR-!tU2v`&b#y#eB-u{Gv$DlTEWf(L;UHHXR&qO13_p-STB-> zG$xO_A+c%_B^<4|;kF-e)tRfm9mSR5KLQ|h~7b|v?0=Sx8#<3U6Y8Lqd2uX!<8SP=|Hg)XVZh`K$-J9ixQ>@)K}z(dYu>|O?tf(A zbZiRy?MjXD@o_G^^p#%9u~LkTc;J<=ZPU}co;w~q#79S5P8=NMgRkkKRW9Q zAA_S=`uaK<-jzm8&hYXpuCDusIZ?iXbAS65X5uS2WUc0wZFAf^I1GB2(>I*W=RVp^ zZ$dMxt6mO`mK;$gQELw~R+`)X@&n%Y`ZsZs2qTq3ayA^!L;M0-Wz^3OIbKer8;D*Z zK>9EZts$C7GCn@ci7VD3BN676XJ&WZ0Lesx!x`IGOB7k^BdP1nO8vi;hJ@BDI>Y{m zp&m3D)L!cQY*CR)rD&2~6O&4%*tUB+U%uswoVMX4PU!Dv>hJ;jx>H>7it{*hXu>m) zFYji)I05vs@th0E=WL{mGvhc&QzG#;4E4uo7zVShOS9|JWSY3b^0T~#j-bE4pL~9tuC8S~ziSs&Gr+ZPzl!Bu%NQR&Oe)n*Z@Y;zH3q<$7hJ%9 zeg95RrkS)FUcAAA=fYE74hc~u4pq&t}sQSQIzad0MiTEWx5%KIP?-%Mx-FSiH*^uyslV5kis zy1-F{BG9A-%GUn1SeI+p4{}ekWc$RY_Rb`kp%IFzjFb_gJ_1|=`Fw^|>-so4QlL=C zpp>VWNXi7c%m^L5Y2N#ecXR)f&w2)Jyio2rrBK@29vKK^GRd4$EM2vnXLgLzm2L-9 zAe17iZQ43RV5a%>gHb+xPX>w-;upi79ay($7|%o8Vn7e`z?Wac(OtVRrNFY1o~+lm z5-ctv>uCK;U-mNGvh6pSA!@oxP=iusqC$9iFsjtZXbSshneq|cpM2j9tU2X$Uj3H0 z(rhIOBM1o#*H#3DL6h`iGpbs1#u=yc-QPUIj(yW!Zqy0Ad?Q=s#!vqa4tIf>26G%X z*Lans*z&m>xO4F5^dQ*3Zx>P~8P^~Z5kxspXJ?47{OfI8fBh{S-Zw;VPd_802idb{ z4`-gbfur^V^jeZ>G^Qyj7j0(zX4)Hu8_brJW#tMHtVN*QAw)z!QRu^7Ou~Quy=@-7xTpMSSo% zRVLY==GkYrv2P0BjZOKn-ly8dHl^U?CajO@(QHM%s5r2K#SQ#i%2qM)|ebS zjH69Pi_^@>PMW02(c%3pNky4)yrMqffB!jWfrVZZaA>SbKr6KC;5eRU&uTa6B1$S1 zMeF7lxrsLuc+nfaOLfsrM+?LMdbhECF+}VbGFSLGS(j2CSH9jn1{QBugz*CW@bN#7 zDa~WNIo_%rzuD2u;Wi4+;Bh%6!DIfOw|cK&_)U!ep0RC+B)srAKlj73Jf!ErBNHeq zMpc{4sTx5MLJJ5GVqVwKVxCrEP!nFLB*J@50va4$L5K>8WE*9B7Du~Ogu%gL9&JT% zd@5T-fzTd_=xBZvr=*d+{p`jVx@n2YT^@sWP&9A{qMmTtIDmKKfv=@K?zTCg{Z?H7Bu5Q4MJMjc9~{N&>RU7B*yAj zT)`tpZ7w`#GkszY=bv>7wYbShZUiA~1Y{de4nD`0FK_1^U;7qY9zDpDk7v34-tV(# zw1n9i<8Wagt(`H71@jmLa0Ts6v=BJL^KeaOG+8D2&SOXU(6t}rhW~RLAA9d*SY0(x zQ$$^jFlyLtfC+mN+RP_!_-8(H-AA}|pqueSIo^EX zIUIJ5G|tAbQ6mlLZtpq`V_=#lV`E2HzT6{;jZ7RNYDO6tIFtSR_i^ca-oj(UPq1^x zLH_jApLqJ|2RZeR2ccDS2=zC4_<#Se#j+N0oL@>eirc!mcpm)xhWchh^X1#V&Xz|X z&-(SJP}PBk99c?%L}0{1eDv0PA-Cet9|jgJ@Ed+0D;~U@o5gUt_aqkml&?mvtE}s7OZ@A#i zZ{=v=AhFmwSQ>)yG*^9dJOBEL4V*Gs<+-okiz~_)u^Qv0DnEJXkXN)6OEkyYnJ+6; z+JJu!2%9M~m+j2?PJI|*UbXq5&ho_RX66MrJo+D_2btU95K zmef+#uYU=5eCOxh5LCc)E=RJfi$KwnmNohQh^pg_^y0uA2CjA*8|0vW@2WT6byb1m zw0_GDPi5nv+T5lhgO#%|DL@t@ka=5yzDI6?P+fyWWaRQ8(c}5 zWKQK9uYF}v^E59)6zgbO|K|^Cje$i~1gL0DtF)L>ijk4MOy|o;Ki8HdPx7k%Z$V>tHtr|y_Vpu7<8UxOHBj-UHru_Vqi!OQzwr%^tl+{K4S^T2j zYue_Nm#J1C>Q~S-;e~~layi1_ZKTnJgrQ(X8(e z7ambjd$64fim(^H$Z)pA(t%ZEfq%Pig4=iOgW(-;*+qQ)mk)9A*B;@TE6-)UDv?en znNv1lA(&9wm;OhXUgS{;%`MVL*3EOuZ&hxzBLRXFkpD!9ntQ+uu|OcJJQpzlqbnj=w~2?^4F{87c^* z6ztivho}&A^d^bKL(J9YcK4re?yP=x2Rr=ra*cDKip_e^nzhOzzbs=19g9hs1eX^L+&Mnpjj^jF;*6N zP8Lhj%J$5nfJmPzv}g=We=Y^;>!Pp+{N0+(b$PVT5Uw%b5}Io$oxzwb$IhYhJa6 z(rB5qh>;tbWK}YW%H|1EZWMv_n~m^w+gf?_u_ftV@_Cz?g5cYCe4TIK_IbX3eWoC5N63{sq}*7^7*|;?cKZ*iBRK`3~5cU z>TgYiAgl#Ngl_~r-dCp4Xy(g`$3As3Xa2(j@JxygHx5F&$jACS5km6)ySFnoXnKKy z>Q`)g&sEHhW;wy?C#dsGNr+)_>iS;K2`HO{af5w+}r=(4ApgM`5|#>RjzsufL2}KbGw|O>plI`!b9)I^7q*h&<7K%l z4Dn{PLJBVsSCwrqgi$G`{eZ|^E{9==MM>#_ze@F4JV>Y)sP+4A(D$1)nWFJEYfe6a z?c29|DAulJ*mjOYR~N&>!#wlo)BNG_tz<`sxc(FG<@b;Ng;P)5%tWrpjGkii<_kIF z{Fm|1*WZj%22E1>R7aCy(PmD;ycCGW{onPSr`~okh=*JDjPu_6w;3-iGU%%S%yZ+^x)W>dQ zNy&iX?>Q%XOxPWonN z3sv?AXos~XR22(_c_c(x2;O39{^R`@GInq$A>q-VVu_g7SS(z|l!RdT(L5AQNGWDR zMW$2MqES3bUSB|=pf(KNSb8`tp&}=US{nf`uo=~rSjzS zw9ukqwmi+~MiA7d=z%xEv4$CMHQG)eD->y{FU%?AdSV16)(ND5Y2 z!=&sHCNrA0^vM+T>6Az^t`uwJDVS>1zeXf2$t2hr|H%k6HYy%*%6nXW{XG=&1tK!! zqm`>flSy1)*0z1RmS$#AqmB?n{gCnN-u)gXT}509ippk2tA>Zl@wY}HA-v4N{yu8J zq^f#;Agy7{1hZamjlNpEQ#C!=u9w{cjtntj3wCDVyz74LHCMR+h|}PENBH2cNg5Z;ibtQ5_Qs@YJJ@U)U6BN>*j>GzuzL9>)d9pk8o5V0((e$GmhlvII=@?As8OsO}SX4UoB(JnzelEUvK57Km8#udHEF$a?7!D1FtxYCKJpH z+n*wN2W_$FkRwF1o+H}cMw8<(=FDIS&t%%u-bqzCw23H9qSz2+Nh1tI@#?TJVdfD= z6zzs^^*mb7Q4=+y!l22V#nl;t`o&!;Rrjw4HP(!pU--L!<#Wcu=giq-d?_zh7zA*A z8QCmB-3-EQtf~Y5!{3$Cz>}rds8At{(eT4~**j5c!obkpp2sk1xNe}4b>ALu^&teB zfD4usgbO885{p4OhU!u(5=uSpP_L59S=<7cf8A&rQB-uihN*SV^Jq!;G(QaAHYbc?K z3BkOCay=_Vc-ro=_HH^$`uiy;o9515f+EDT*#cetSMrJPUy1aKxSFn_s~V6Pkq{*b z*=(77p^CI3XkDc$Bg~5k^FmOrPsPQ;X1n4Sni}Y|)=<%!w$3z%vm+F=q*V$&`1v33 zLGGgBZ-VMlvAPVv(XcZMvvz^*WRgr~gmz1kOr{%+Z?;hKCvF;r+nA<$fpnsA6I{GW z@nl6_fmKnOGtfNpr8jf#P4~fLK)c14|NOj1OIo%O#& zn~t6V#Aue1f?Mynoi zvmem(08Rds_JV;G{A4&oZr5RG)!+pDNr40H5?TeLhYWD5>^)Kj?Sfeb$6cuVo#*LW zzKopXp;{k$@&Ug7rCa(Ws!{I1~;!UWSc^ z(a9sUwY5^3&=d{9%*+(gsLAA{gVou}v-|gxavfrZ!NkNN48tVvIP9OCqNAgO+~^VJ zIy;aK%(zpen8wocEaeEF{OD_W^*g@>%lj$Wnzr;Bj+SlC8tCK`FYo7zcl{2;#hf>I z*ej-lfE>`Z286|i6LQ>n-3ms1%2~K!4A)c^$tk@JP?{-U5~sDMx2K1Pe*b&Y=_GAZ zqRr|OiET$b#rJ;v zpWJyTeDtH&a_2qwb70p#X6-61$r#J}`grE4hxqXIH`69lB)U=z?cPmPNT!s-l2kWk zt!bfjYyAKKAOJ~3K~%y;>i~x9VPBi6HGbBRDVTQs&5-c2R^|<8c41c38XKc7zj4yq z+cuAnkMrd(evxagxrR$#eg!}O!FSoZbt@Y-Y+%*8HLM&Mpin6Bsw>|@(lA)M)C+cO zwj_oj$c~TG95-o`)}puveOzRMFFF1jkpZ*$B65W!(ba`*+q47uOrEZ_OA$hl!6pHq zB}mwbWH4_s_{2`$cm4^i?UguMF$>I=0IJ9M0v&mfpl^O&Wu<-fgl1wS>%$oY`GR80qgzNOEY`1I!>(PsNT++5&fA_}Lfd4O z_db=2$4WVKNe8tm+NrHc8le-@kI!Rd43NNS@}nO-m|G zs=t>#Pd-S^F0v$*VkAFKo0JVHUp#I#o{d~S&)g!v*~rK+mKA4cXo!^qt0|WST6sOe zlu{(5g;q8}ZP3!!!{#gRgq0V;gFoR5pShaz5)p)ehYMvs`ot(~ho3!CAiidTYd7_P z%KF0yfq_HoBKm%4R+Z^acG2J8Pm>U2GFi0t(&cBBW`c zWSS=F-PHA>i9nN2*&54d=E{A&7_WUjU2Z~DK|c*bp;{j!Hq0D&SKzr()4l9gNqO|i*7A0 z5J8I?xPfEHWPhyyv6*Q|x4gZG<4MTex((lHlpAgxPrRtNI$9j_zq4odohp>PJR2!# zm68!5aO+jHqlx4dOVXXx3X03uoQ>Xiexrz)so#KA)te+nLR9^AY<(pi)YXOrE+j&@ zz>KbXD@j};Rg-C;LLN(alE+pl2`7^t`y5DjrpXub%&9zaVKJw?XJUWB_M2TvGQE*a zt2g3kFV8PiC=t|IkB)*sh#tB`FHLyiS0SybNUsPF>IJEVW%;=(z`=tD>FDicGMn*$ z6jqXQ42DOuNC`3$B9k2@DlFPMJDDphX0zH~yV{ifsp1?}Mn<5ww;!d%F#(F<2BW;L ziw0XMno)H3C73A`P)ahY%FL+}ElKY%4r-WLv?iYyo&h@Dnc(oK*N_R}UGH@aYGQ*HcLS2~ zVi6AIV9B!jg$j0{K{4egT0h4TGv`j~vJV;dIz|GHVxK5U_$_`M(zU+_Yl zv$2z0$vYc&?%Kt}k32%nogol_*|`eYtXB{X4-a#iA5=J&&ongVo`f(0q+mSG(m0fK z05u7ro(^Id9CfE?5v|M$m#L{KT-T+wwUxFu6W4X9&bV}RbRb$gIC}Ib9UUELJ<~Y* znoL29t}*RTnWIt97ueC+K?R4PYcex4L&?yr?mL;m(NU6p%|IG>fbO0RJf9t9MoKb6 zhj{;WYuUVMo>zbQX((<0C+nTu9(J4yjZM$8nHSGNo*kqo`@UD0|7*kBd6VY9YI2+P`ic z*E4S8`$h%Ol1h1=1OIE3Q>3eF8M$1MSSpU|!k2ElgIsQmZ+`Q8wD%;r|Ne)#?Y3_) zqaB2h93CE~6KLzQ2pNzvQyeYk=!h?6+AVrmEZ;Ccf6Rc+!w}b-l3C#%BRL3}0;n-K z=rvR2q5=)gmc?^>2D$$FPm{~p+jq9GE+yNxJ<0Z`wy~tY zpRs(Np!O6zZRsRQd8RoR-qXgC11lN)O3x3}K)3`MGn=pZ(N!0waspi);A+&aA0ZN6!!ddA$ zK#cZ8o>1lLmc}}=bYz`Z_IYJ_|9FpN z&mlAk=j1V=rne3jY# zx6tk7N!I6y3BhPga^rQEaL4ygaMM=`{KM^c@Lym0Hdb6sM;O2YV;X|{}RC6yat zX6Al&?AXEWU-}|mv4R>jZeB8(UPt?4onB>~u0uBvZM(n*y}1$WzG12aoH$-2(U;?N zMKgBJVo&5vv6CI#wdZ*f4miPBxXHb=sWPc{UHXtTthTJr-JIdvs(ZD~VKShnb-2xn%7D zGdazeCNiCIi0Ve$qT8VLb>av*WelaED`TcVepNA;84EufM9ueE&!ykS(Q4NO=K0>!M zLNk-$y!U()lw*X8z7DAkt)w+09DT(*z5-ipIOhro=D6g2-+_vTOUK~rKY)!EOk4zg z3cp7hu*6rU5fOdh&x1%pk2J+{QbIXIY5fW{(Fbq+FozJ39OVOFe<=LD4x5WCoGgO% zm?^T7mPv@dzSg45M1BppziE8lz-M{bWI zy9QYBYxtDu>ar;Lra|fN@26ZY0+d( zhnaF2%d+UU1o?#pI_V;62^zH;-ByySWzn@^jHjo3tgbHZJ9rw-83#1^sUxJMpsFt01XL;F3jANgD8{O3-%;_wrv}TKKbB@>oi3E$)I(0ElTzhRqs-+Vp6u2*k!dRpG zT+8PWf_9McLe=o=9mgS=Od@51sMZvV#ZX4y`q1PV`Dtelw}cP|u~?Tm)(ojZJu*#A z`(frtnjCw~&26KS$po7!9jtu-%t(S=M;&(IXBSe76N zRC`!LV4k~ane3uYKv+qF(6%@@%jt5xaRan0e=S!02#ItW-}l>vs%a{c{NAnar8nHC zrIffukMp;04+mR8Xws9UUa6pb&FIEKDiwv+5o+38>l?C$_pbt!(;3A z>s98ojW4UleNNacS0hBVqQ|xgT-DCuimuHAQObm%0^D}n?fk`G{3)L2h3J|Ibe7UY zNaS)`x%=+#ar^)NN51jRFY?sn0aA8?r)Lx+BO}~>_rpl(&}rM$Jfo3_3rR`}0s@3+ zkhN2kN-niplMPlcem$f{Nl8q3ylxDB&Ye*`O6Gx5^lXhrKY4WRDr?qZqx*emF{ptM=^J}mBRjQubzP7Yh;WcH< zKUzqoZMV<}d)@VsrizD!wN6seV9Bc^M1&4$wXdK32M>Sl8(;fvE)Z3^+!^BDaW>>Ov64z)4V}wR_U+@wxBVVJJ#c`k z)*PIiWHjqgnUO5b&7rlXQkf@?6*dMs4A3>ESjn{H@u&8)A)6(cH1&0}-XNW@nJ(n% zk;Z|nOGtd>(q&7Ui4=eRy?bEi)qLcVGAW>l=7h+y5|h+Qlbnm@w=VDJraL3>vmX)- zYlb?CWh6}@S@88bd*aYpf>5|sQyP`eW7{@wc=f9|a3F@Y=cRn(2)zAU`(W;A@H`kD z0V#O!+7*VRLtZJm1e~6oWyr~)!i7?YRIXxij%4yeTsI(*NO0kW7qV~PKBP=CJ$(Yu z;Z#R4FDh6c8*h9i*WGX)SzCf9z!u;|KqSI7*ig`|pV9oa7Q5EeM{7-&(Ca7w>&fQkXBDML zhMx9X3+76VP%NeC0tTeQO2pc)^&O8r#y{4l`KjLk%jQL?UCaYBRo4`g$*`35n;^n; zmsTR#ndEnaPbrJK@J$0FIv`&)4k=CoW@f_$T7WtM(l(+)Z+@-$(F&v!elJ1Knfr?h zD9<>kC=3-zhvIRe&F@j5vujv?Ys%YN&^%=d%5><$Qc;j@3D9-h39VHqn4&){Kn0+S z=DGavm~Yz&hYp&@um$8NO@Z1vHc4UrR(YmS9dtm3BY5GMlX3c?@O>L!eROUuR^D2N z^hE>&3WRIc13R~7M;uP=P|6%r9YKo@nlaA0Hbr}&ab|#=DTsv-T+#Il{jjUgGmVI>y?(i}BnZ{AUR!gXYcX1r8jkNb?`6|w^SDV32fxc3uihEjAkfwz{IYKP zthJ(rps}t=(OS_Hb~*KWl?NYukPX=^g+c+xu|qnq$Hc@gzWkZndFOk6zbzp5JlAMd zyavwBj6un^jPv2o{}DDTj9P+K%x54hgAfFP(eCy1^biLs<#LFQz`0v@F?sSh$)sS( zuhE-K(wppInO=OqMy4x?B_OwH6Pxq~9@}>SyT6}EPY?QZ1gpzpL6^x|5$xb3BkBfx`g1RFTI}W>1jG`sJT1SjMZLvrqojxP$DBc#- zuLZ`oCg4H{lw}5atvw@-K*}U#RcSW|Wo2BzJkRLG`qLImm7+m{m7?F-h_4i-xeD+Bs={0;0(vu8!@T5UcY&WXYf!MRX0fFCUMYTcw8(p|pD+eX6%UI9wrx|=9;;!K zvM31GZoo1Qovot$Z~x(Q{Pib4MTfLOt9AmtX=DUidwlM5w=p!-PePg?#W^?6`1lyE z>v7dpSFO|NNNiiOH6QBJo9T8Yu3D`2$1M@Cu2O(_Ag(`Ikowm;f zS7!LLUmfK?b0L@g?I}2vGl$YDarb=>QGX}I3sdw+!II-ZKEJMPFdpk2Am~#aRjoOx3)HKc^h++{)Pqm4P{^|kY#SZLPD?5k*VNmNjSl8nPywlInzWs!M@o7f zho-04v3Z`>BxHM?T~UfIN1~J$UN@SA6g;ggnAgNExSZ)i zl?h=HxMr=04Gc3^Dqs&Mz;j{82rGpW{SszWi1-P?@;d!?Y*}cs7_CW3E4rjjN(o}h zBRihs4OiYu-{0Zi_U&V2;2=W>>{XF{&f)P>FI ze2HSQ!oht{kjssd&(Dw>9As%9#0lt6C(!{^i>HX=qm!fb4h~Wd{j^Wy^DKD{V#zGM zxj`()xCBVOdPbA7{_9o|R2M3Al5)`6<=CuIWVofef%{6LO>$~24yNF)o@MvQa|R4oA=Snt$ljn8}Z94K3+(WPg58_@~&`-q?KTD*nzpPKyn-C z&HVJyI%E@|6^~xx!4n4|oihzVrDS%<&~*ZD#-!S-u$d4N{D!&z(-G=JVF6iO02wul zw6B2EhB6@PkZhRgbds}*a%KJ(o+%V{eNFg}1u|<2AYYpA(*lZ<=6`9!T*DNJX>F2Z z%UM%wZkRE3r9TSRG4M+!C0JN6=V1gt!sN;b1#@*sH$a9q&Puj>7b-UB85orC* zi-w;ZhKnwS;$b+Y%=BC+t-yAe}Hnh+_xVn(T@TDtu4H8OVl{ zdXF#*3Znm=`g#kRh-{o=&A$#HLeA%F^bvaM`RqqKxAS zNmM^ZOkYY=tg=KYbb~SzEiD9y97?1RYKkZdTNr-syvVcc2o|+XO=?E9VhD%2N;0V{ z_!9~Kg=DQ*@GLL76~9Ap}-wk5tQ zvW&*IjhIx*y*Q4IowgA%fs|2f`{g)}!ztH&=78oIgQ4fPBW~HpKYNoxJ8z)14rOhd zOE12RE3dkYzxd0KaxhkbYJ*X1dXs4ui*rm&4D-!9?qJuhi>;HDu~M8N5z#%9#_eR|S;R4Nt9=QFHeDH%GV8@P~ zeC^xc=jee0h@{{}*IdfH=dz3zm% zAQw`Ibp{pYHMm-1&$y&VMsXa6$uEAL8*X|%g?yc+5R~mK>3SW6X;6Yx8b+T2hQS{( zdxI;@W+9Dn2(D@mmi~4BkNLwl{t9psk{-#Frf@_Nw{z5_Mtgab5~i831o)LTDj2Y` z0!NNaF`7$J^;DRDviABL(&3-J@HGGqyDnYArduZPyb?V!MioJ4s7vXQ0!wRF0YN~& zEjX<#NR9Ic@BdS}q8(%s7FsWwp`Z|mYKgwgDkr7G-_Mr#{U1CE_Y_P$P)R~|8Y-Gg zw&eKWP1lib%&;UXbcigLr>W}*N+~*IYtI)%6UO-w;2%HtRX%mwXIW8GM0JFuOt1(@ z>Cl_oO1}*F@@Kxlu_q63>jyqWmu-jU6^6>zD+E8AnWRG+3TCGrLwj``$Dyti8--xf zlk6ND=jK28G(_NvOu*mz3byXyFTZpg0{HyjZ09#7dZ4t-N+!mI!<$(A+6KDc^<8)} z%fW+7TsktxiZ@7YY=F+{!@Nar;{C_}l?U#*i`}~~A&x@K1t{gBgMcM8O{lW6#!|_zg3p?hvr(xgaD>VUt&`F%=dS z&>kC!GLSeAzpjZ$MLM&}>3ZGN;{c;T?qxhaX(6^|SQb?VWRaq`N-nvk;EJh`%F%*_ zm(g@$pu0pS!_A+r!I!5X>9O-Xhc{k(8G|~{@?;;k&rI^r+zc?t>)!Ww{PSo23)54x ztY~9D8y7nCpH2`20Z%=3j9t5SGw*qHJEL5B$tCRn@jY#AX*!)|aBwj6q?Y9Kc}|DW zX;j04@6qW=Mn)X8794$IF0@;t?b2|DbI@~St2`f%`pjnH=Rd$N(#Sm9-?l_pFQmyi z+i|7IT0q|O-J0uOLp&@%#X1q|zhgG~Z)oJ!ewY&;?i76gBR6vU-3O`Y3Ty^T)VO-r z1VYSl^SfTpkLU7y;Y)YYeSw3o6qX36cpg$-#c?socCArq$fRoA5S?Xk&ega@c zMCnLGX^KvoqBG4uKQy6~Qh2xB(RGoRRMyI`r73GB!Rk>ziZO1v0@5i=NMBF;Pxh+U(v*bn4x|g~r zGUSY~=q5?wnkX#MM??#>P8z|iTtx_tQWjle3pra-m^wmT2v!Ehc)V2QXuiPf_HP&!W+IeNu7hvicUAwyR|i?}xKVpez_4d&}~NDn1fakWbo0opi-^kL(B z3Wef?P^{q6BYkqDLKMvAr*e?(u@rr(%CJ|bLu(d=LqSR=MF#XB_>))Tbfo|QAOJ~3 zK~#M3s&m<$>!FHGQ`p2*p89N+Ow6W=OQr5|?Zp?cSkk0OvW!oM)Ko%&WUZljNn!w1 z*LW3=kr9*j>{Zn>n)&6>23>27leODuXX|H8Va`dJkf^##M`8n@Sac2d*-qO)iWSx3 zr<-8dAwNd9(}AknXzil|pWNUsq6tBdlyuq&;#liwg8!Bw$}e`mmYruiT|EZ>^@Hza zWMqVfR#^E0Lr#u?RE!jm7|inLfAptxJA)iPd3#DR3 zj%XvYu0vYmJzJK=inSW*Z32ddHu2<>k8$eMDW2SSnErubD&;bj@@bX`=+<3r3hw;; zJbis>76YHCHU;ne{JiL6BUHH z9wwyuOaJf7yydNL36g#&?jh^AO#m1T^+MF%EfK50lOA?mB!&YfDfa_Ax4(8K5aVMx_8(5wRVnP*~2N5!cmFBdRD@>tvi93mTO2NVV*! z+m^rLjL+P%EH1tD5-O)pQT3|Cgt6@%$Yl^Qo4OE`3x$w-pV*C3fw(2v5Q3dYxmQqDNkcQi>I=Ny!*~NNF|$%pgP^C7qEDmR47&6lM`ZlCl$2 zlt)xYu%B82Pb^>z0TEQl^Ls0r+$~ z4%NaGkw}D9RzqS!8Xh_V$_ze-&fjFhCbj0s>?9XC<4jhoeEbhz&3kWtj8A^=N%p>X zkbWr$N_9LhLh{0`%>U0>ip5jR%p3zO=6r>)RuPuP!Ka>L#rMO=37=bk@4Xy8e3;ul z_gOBw=yD$Y0K7m$zs@%p8XV>7Yc3(GH7~jNV*dB-U*O$uf4i|@)^JQpWFiLDDk<%< z!4|lMD%Z*!ccmc10rKcmjxEAXTzViQm0_QmVw>RzJ)+^6pu5_4aUbuJ|Z;Ls%`O9)~jw$4T4>`hYt8+`wNxd_7xYXrnE@v)vC zb!q-m-{SK%a{7$Lx3vJbCc{f|l_fXNizm)!@cK<`9v(*PI&lK3)e>nrz`K|8R0;(? z_12frkuc6yOI45bK!#%l7#`k8yfDd9qL0AdLL5yI%?2$g3RC>0!tM%w1>1EI*{Z&1wvxmP%a%|P{DcQIi_a;sTgt!bm|II z?jYO8`Y9bbNpz%!(4)i@tZKokwn&IonnDrau}p<-TcV^*O-q)=K&b7JXyvjGOoEGxxyA%&mRlPdr_`Fx_B9KOfhJ_*P%O?91klsdN7Fh?Q$V7phu);%C;J}6@6uRSlDGv! zLqk+5^OQqviV@W(iRyr+W%%gTARuE|1cA{NT0p6$>FTmfL8S?4pWu0lrht;`k{C;I z`?tQzuU)&B^IrO^ruiwAh{a;ue9JBD-Mg1~DgmB{lgaVf&wY-E?|X<(e)^+0juQs! zsrK=2eTHRKM}>O3lao`7kB{@cFMW+$e*gXKzUW1~>Q%2|W_FU(Gt&(B4Yl-W-l zXuEp$0IEf0Y9V?}>rBQ#e4U|vYyXM1wIYTe-x|cVnq_n9STu!cD7vuD&~J8y_iYN( zC^pZs+BXe}`CaEat%~`(Fa-Gw$22SadC)eGh-0DgS;C;fOY8Q~W?UMow&ypAibxS02S=!3lNKmR7@Y@MK{rqSAHfn$jT zCEW~>_Bp6;0Wl6j^N~FbAQze)lu1jULZLx=cq@LR#74azAzsY!!&7aIXkAD%ArD;- zTeabtDCioubVWy~1>;KGudhHF&OdVk$H-Jn?YFZJ;re`2yv<$2Tf|CgwSS0g> zDJpfBC1sN0dom8?LWxe>p=V%#Om5t83K2Z|_&%<598gCAn>Y?NcM;|%!;Fy#yzG3A zz2#-(luJWiL|M7$>Lg=A;Hn6|mnJO}%$-3~Z?q}?tmhz@}OKVP_Z2@;#wwSaBfxcH9UBHA6tI=CKj|yLV0Ac zSrHCTr(E`4aRI7wihJ)p#f>+<74lH26q%ZvCMlET=TCCZIh)wAc?&n+ax)t?Y~aQl zU(2CG$GGn0*D&cSzVd%R&s*Q{a*jRrW6s@}B`H=Z6wL4=>uP!vNfvdLrt(;k0y#Fu z-R=xzck|_MRQd8P%3avZi13qpy)y0W@mk)Vp76Q zg1jP*YzIK*^La=IK#_Os*-cMjie)L8^k&GC=dgE(-S##kHr=1&>1uJS0nmbF6v^nj1C{>`- zHayyysaZA(2XD4OUuuNJ2Y(29#L%%c2HsX7+}(!Lh2b&?j8;QBgcVu%y;##(Xt~Du zm+Q11LV!91Mc0UQrG~6D3AjZK=@D=ws2R}XP$?MBsUyMlz;Nq{C(1qqSQ=^P2mQ|P{ElfT!a(jgY0650_Q{A1hNdeASxKcJ zS%VWZRI5EWR7uDjrFw&)G{dTj5Kll|OL|3?73DE(r@%i6Xi}*d3we_VV`g)DO?%pM zRTrym1V}^$D=W*q<2T>I4L97t(AWfpLIDwzp^iniEtp%iOe^GaIm{918yH}|FiFO- zDS95Il8caOdNN~-j*ie7iBn%$#=~dV$ksLHshuHJD)9Dko5$YL&*5x}`==$`b%f2I z{yJQ_6`UL&-g^!&8@Z6Z1FHz{2!r-2i)aS42=yZ&(qpw4HEZY7qONoQ6HjnrY8D|H z4CDr=dL9WWND5fQrYn`A9yTE4q_KD=AQQ_lS1K_vv6E^wj|vB{5FsrSp{2D=x!&M` zL$kE}3VNh~`KRHct+0C=$P+-Fq^J;$t+HBDoX{@g!vp-;=N^S~9Qwryx}oT?B`Zpk z&*zcS=7yJF$M3x7gIx0~zrsEDe4otVAYjp#wK;L(1Y<*+cXh;b?8C%-*+EH_Z07X*Lyi~kCUju>xN?OmpvR@P*{Z5B!8{uiQh-hSJ>JGsW~e z41Q{c3jSrF>@`3o!BUJ%o7%yntc;A&6q^wY;Ml8p?lGbx8)!b2WLj&Mygc2`IMb>` zRQS|N9=*97mpcv}9dY*m>}Onk%{4fV&5B=XPkRc}(`a4hC2x8SO%YJ3Xr`y1#tmWH zsP-Ao_R&NjlY;#IQ*0cY;8>y14yjt}{9BWxU$j{ezr-fvg`yDp87M>iEHq*{6u>@f zviC3e^zpNv^FR8w{2Y#Et^cKTkV4QU6w6wnJVis=94OSWopGX`OP3HVx_O4iMyOWJ zq5;IkJ!)DoU8sY%8Af**LAdR}T)}8nDq)k-(oj@XsK>D3m}_8GAT`x7)A3b*F0tr zeweMvg9?T8l_vlvyvQ~9lV-|qNzju<=Mre6w@SD4BB97WX~TRT`fT&KzJ{Tkd9QPM zP_Ai`tgt!r)td8_6>3vj8k^z_Y`GY`Jp1lF&bzN1qfn?Dv`L!)&mL*6!4+kkgaV}z zGKS~n&4y)5IuNWVkCcSroWw=pPCZT>Nl$K^y62L$S8?4sS$l+2xC{)Z=n_q8r8zoO zgg)U=(-JS=V3Y7@3dyPsNl_-55Oj%Q64>N5)J229onb&K7L`Y*vz1kmpjjwz=Z9a( zCm&eh>kl8{z_IGuF%SwiCV0(AhEMFh86}I9m5maE2vKCoJw{aKkYg7TbswWLd5leI zn{Jt=IKB&|G+T$qsn1T*>ExK4oS|t6hDWwith&t2<=MJ*oTnxaBc%*I`^7rj=r!8M zs@9+&DoiaB7m_GzA$v340dj+8f@e7~iWEtYCa4G(Kk3uQAay*-ekG(ZrcI!ip9g$8 z+zi}r@L~<9Ki;bT6p>a|h%g0fQY7(#Skj`iX7mlS z^Yf^M1(L%_0$+3F$PwuF#|2mJ;lKlr z@Re_Um-8>Vf?BC+P!pxud->(;z5H@2b%Uaua;xNW8Kl;2=f-H57Ou7CM7}_uogxav zXmBJyLuTs*lqUElbq3F8&iWLE# zS7q0(U7Vh&(wj5G3){9SYoA@I1Ye!gkPg`b_7jk<6K6Z{1h&rMdV;6&bzXM)1WU?A zsRmk%5=X70&5LIpDmI0F26`sK^LBZ~CuMcv1vL`sEJ0AAZ+Mucs)taaJ7uUx5(rk% z?S@nc*&hB0At<>n!($^T1-5i}&8uF=%uIo-)yu$mANiy6%$zcTjm*1{pQW0~F+b~a z+dF@qdw%dFM>l)u*ImkcKC9uFhPfF&vMg)!Ga* zw8{JGv?YUGUCh;dGF@GaZQDh&>GSl#gQTUQSa&2OqG8tVL_#1lf}VB5mrf}dvu&0< zj}_IRUnZDyJ;uhySS-18N}FV6gx&F8?2foGTws~;@r*Ib*}8-OmiYny;}yS02Y#2o`=6g? z%dTDYCX*}!!<#oFgy7%<4{+^EUrlZ>%Y*x#z*h}63=Wba$)f8Lu{9H;4yC7m#$}hD zOHCW`f4yEu2*D9GLtsndsSK4;gkE9OH9O1ub1^nwu!Z^6M@i@`U16zO(~4$DGuK-4 zGc6dguOKz`I8)kY*L4?hc=iArGv~7-y<@FWG0?lQiCkGXiD^o~iint^$c|AJny9mi z)_I0A8CItjNaq^JiM?EV|I^&Lae#a0rb%5ngwi?`ODBnk{>n;ueE<7*aqYENGIQ&# zeEj2o$wLo4M2AeXSS+?V(~mv&5Eoo{A%F9+PmxUaV_8Y&=TEY^ua8rwj+0FG@R=Xp z&z<)^z_CKEMR*k!_%`RqB_E;j1hMWB&0=AY$rA`Mo*zmIgwzcUZqbf z5}5&xm0&ytk!pc?G@hri?HnMeX|GK?kTOL@6zIq+x}6-0sRT9cv8mc1sy%9UmR_$; zMcPQ!AU3d@mHH4C(=5eC>1>R$6oXD-MEF6yffth`WDKi1gB2SjXr$>##ORPtJEtb0 zH620|R9(u65mu|S_yfaizUhZ>D$g!^1F~Kxp*0QLHnytTSXFDGkurvqIh4`_0=gZO z;=AOz^bQP=ObxSKEwPLuqI2|1kLuV2a~=%2Rk~$@;@DQIz&|~b;gN4WO0V#E!&N)D zbSwjfSyJu{n{5X~g_0cO0pRNgmiYX`kAOP|P7drC?;CV@-Q{D*6m-Y~Ja+g;Y#F(V zB^AM<&WCr6@SzJbG!m;UqY2Ph2%7Z>wS1Kg`WOdYMS)S45ex|E&26QuHgnVe`e$|w zZsyHby_!mWh7W(@4xV^iLoyBNfLmX?i}O;7^r%Bw!8`upHg0(N)m*;!V(z>DZgy-Q zVX>&GhxFSHOVDg{=MCE-YTIoQeKY(Q5Bd5{t?5J3iG+lW1Wp#~xLQ&wx?m5optCIM z2!R$PNz;iP3i&k`Trk0+n_oBKK9j1W+mzrJwhk@-8`ck{6p3(puC=Di7Hv9?ITu|z zLT98}XwtIx^2=Ftt1NknA=@!wWCv%loHaeqa2OB?vYp#whCMan1bEsQxGV)G;4ugS z5I;QNaH^ahsNM5i_9uXbbcERBc`hl)*B*V*HriT=xV=Sf$H7_QkKuOTe0 zCdjySS!ivN=9@uq29lw*HnhR;J}r%xC05(Pm+Pr$>(BMIuUCl%0n3(Uyg*tMwP3Za zLs{FWBdmna)fB5|!~jG?SI3qf!=#lPs#_ClU2}6L)gGarbJOh5(1~DXCXa3BXbM3p zKLx6`9X=ms9G?`1ELx&IEXe*YixH%Fi3tKZtsjUxlR zW>1QRhGf>84bgK=T{YSU7(%qJMM0c;`>?e_dn3SLS3jp}1v)$8EUheKS!o`A_){HRu#EdIm;Fr5rkhz_v}+PoYqtqoV^iC{sMNK!gZ8N5<&T z3O42-mtk6s(w8wVl@EXSkGTArYq)UuGA_IIYX11sb9^^149kH!JpDtO3ZmL2mm5Im z*H{)Uy7k$;W2(cVRI9NHY~Q|{r=B{*si`AmGY(5i8LyqTOO*d<`qA@{athv4lp_}zyk$MkARGnbcrfDlf$-M&b#Ci9=Y#+8onl(Op-r-oC`0% zoXtCTGBr1cuM}M(i4dz4i!Qa$c;nC$|AIevf}Z3mTeof_5Q4JO0yqtWD!PC%FIq`#Cmiv*<3gn|hBpO=0N!aiBx`%v51ejDv<#r7GKp2WTqAa&gVb zCDshPdnqLW0;N@`Qwa-wKMy4Mz7}*bju_6M3RN7L!b^4YoqLZn`NU(ug^X<735g~r z56?0_KEa$eBBc&#T(?|V;+9)(;iDh@D1Y_`f5%}*&w~#>!1dR^f{tX8 zMIGQ*d3YhmiJkO)Y zaS#HI-}9h9gK~h)1DmKZ!)X=c&VQL@Wq6E(t|lVk91)>QH#kaz9U{W(w`NGA=*w(i ze<{LUp5WH+{gjmJ@|KJDaQ&WsR&A(@C+Hp?=KjYQx%Ytu#B702XEGq+^2;$1+*SF^Q^~*$ELpB5rzH`rmyynGY{Mj4NWq7B;JNN*>`FnWFKketvAJ%~+ z1U&|Asstcr_}F(I;A4L;x$H$YU-{#!*>S$j+>uGTopH({L5yjZyaw78B!wi3z|$q_ zLeZIv@tEt-?MPw=s-%UB)-KEJ=G8ZS8ipjZciqmb-uQob=k*_lbGAV;TwLchfAz_S z`OP<_xb)gr@t*(lSvaWp_^BW9lgTPKzwUY#rw-61TG>PKg6KQ|03ZNKL_t)FXo#FF z15p(=3{r-UmAV~}NEoIY7lI{EGv|4v#UO8g+wVi~IR;kWGzzDtL(P29p_U5K zSK*U?_*MoIR=apI>q4wuP;@-UI(Q~>{qwK&=N%1cO;fBQ!v<{8_2`hI-NbAYMM|Da zW?&a9i3|(ch*}c~kDduTOl?mvJdk0rT16%j%zG}ln(emDVK>4Ot8F*Gh;9|aMsE-V z0o|5B2ii=~fn-uLG_-;I@#AzPyV!gF`7Gg+OiBg@PEs#dki9(|KXHnSFTR*cWuDWg zPqU&lmt1lQ{plnA7td4eA}WsH|C9IT@oiOi z-v3*c&b4(U>&n)ZZ8@=>*a>kUAqyn|0u)ME%1)szltO7)3Y`fp9Xc&MbfH6`lukP> zOBpB>N+~duq%CD@fwBaege4^jS#6Wpv87m&tt(4c_B~pjKkl{Sgr&0#^lF8(m5jOTaZ^XN( zPs-I&IMg-=G}I_h6-d-5XQHEQXTnt$0yU{q5CJBfD9EbGOL@QbGdZOZIKuX_TkzJo zdXf=$h1V#Lo4@0vhL<&MpG7(uLOdD#SZ8Zfz=k8vFXMF6C&9;5km88%p)B1=&=kE` zEr9a4VtQ4z@fYs<6;pst$=W*&Rm#oP`hdrnQe-j~htBIpN=dY{g@J)}7)HB$pZc-Y zpyT=|1SAG1>oLCn!VbRo!0(~8gT5b~%FGK-=TjG-%_ncz0z(BJd-^H(ozB3I&Z4<} z4&+|~Eb5Aiu#}|S&%w8k>Cd|#L%9S#JWP}(&@>HODULYe!+iAEV|o0^CmBsAsFRX} zE2wX2X#o_4LV-ddOC%CucpyPjTMJ&H^Y~*=ar!xD;K73tY$TN%A?&HeWP&6`OF3(cyv=Av6~*|mQ6*T_`=Juv*_CR=Rv^iR>j>{pUtdvA4osx{scuC10||# zZUPRtm~?5&6$;qpGOfWz5_yxYTlzTu_>=j=AD*m62-N$1)w-^Ry;j|m*GtzOH@HH< zq&B28UR2cSF||&7`QzMI{L3(Jk9Hx53@MBnAWIKwSe4M1abtVt|{C*BQ{BXie zVP1Rf6%IV`Ad<;E{;-66o|2WPwKd9Uevr*;c2LUiCb9iBK7QrZ3}-D`V+P?^jGgf~ zorb|k+@i_Q@c}`X<7c(BaOw~4usYt^!1n+60!=X( zjqf32Wr@v+p~97Ysb5T?5=;Po0UjZMB20@w63+e9D#xB!?E;yHOaTt9KzAqHekXkA zcRUdvqC^vou@=TsS(NnS!^tJ7aoxW@{_&6V+H0@z&O6(9Q7<&Y;V?@U9>_~CzQEx}9K&UoU(U|H0j3+RQx4g^2l?J~<9(?V ze~k;+#NSzn|1DFRsjun%4)>b6+Z+u7s7{-&D3(+mQilI{Z+0yw~cR|yO=DJ3+`A2nFy#c2p1qK`SOllcxnw? z{t4LiJMMY(T2`$q@%=~E!)Tw=A<=9{D>B#*n&A3x_b|Nbb2PSevigBltQLJ-)3tyZ zx@1sAs3najRm3w#a@$?6!C*h%JmX{B|M(Ul2!nA53pT1fFl@p>^Vpc|Wg}a-`t(D& z?3cUX^&*7BkQ}EhN)$wqU%a%QU)=Qy_g!`npE|yq-QZ|;Y{#iMr!r2FB6P+riy#uA zcTqOl*%NBv_E*NZ`Ig5Zd;%o@1gGtBC~r?CAkYC}n}@HzkLII0`SzEOb{1l^n~Ai> zjLs9d`s$Y*T3U1m%sRxen|w9S$~6PDb;Y=RX(QoS7k90%<>{xlIY0ZPIm}ijJKpGV zY@4GJj++P1jq&PRI@jK_neU$2%mFctoyy{w{(dy8m9Q=u2hyhL?0JN-ERAxZ$PT}c zrSSx(##&JEjg+O2Z{Pm{h*>b)!}tIFP;UMHzd7&eogO}W^&;kX`T5CzY-h(hjeBo> zl%r4iXN>64q#Am`R;+oVmo>kCgBvb6i=(=Im{}7uqsU=Z0}rWAw=K7Wy;l!VcJ&oy zP2ks)R5ZZ^Lv$T?Aie7?Cl6)VwWQ8xz^*ulu#liREqxUjrg2UP`YpHHIhkK0s>$L` zrpEg>K&EOAYWCaH{@Q)CLCPu*-^u#Oq6^2MVcazNeQYu7`$zcN9Zx&LQkNozF2U>p zy&cRU=f3SQVAlqo`Nk*F%`84Mh5ud6mVI>rkzjyyE>AGHH+XmT>eU1SLCTsyD4XY> zf1a}DOiFB9BNA{zAroSlf#Ge`ivXIYv3=VnMo07bf&qkZMD(>9lw4cOvZi6@Yytso zFB3pY{C+15UMb}^-2@vpyw3EdCJLE7gu@M#?3@!g88ztd?`3+|QerVD@XmBWN{uVt z9ZscakUBZH>1Y@RV=1%h>S@N)RZ)CdXw(}qcE#U;aFji!iIYwx7*qN8JRkN>5gfsL zjlC~;nbcHG>Zm4wqEc10LXA@704eN!zHdS};_>o6nhk}Jf;s}A@@|)2V_ewPF1@B{ z}0DS_tEz~dpRIbn!n zcA27kJrjwnvsVWUCL#(*@r8?HTz>gslq{1JSlvNF+uvpQqH(!R41mM1+P?dDd@!hf;o& zF_oinG{HYzc{O>Z2t^EXN)hpgFbt=Ww5PKRtI$si5JOP1QWUIq8udfqr7;kz9oqUd z2`b}Y2dRU!T>5(#u!Wko6sbfXokly-k`yc$$m|_J_(E<0nU@kNAgTm86hfICqU*3} zEzIn8M73m`C&-u%GTI^F$QZ0#4fj6C7cV;quMo6b1C(Tpcg!>mu@Gi|8m|l?rNN&5 z0lxLE8+quy+gSC`Lo7PHn-^YKMYzH7sBdX#WS}QbHu)-Zr%9$8)7jCpouMI{OIG|7 z%a$EW(z5XAl8aV+j*&#-JrB^S>DPY?eM!8lcvt^PU^8{3{qCU1_sc<<_$xFn`{xn7 z7k@lgrBMjSE4)hC-Wy0%^FF)g( zq*h3VP2Bz&Q)mc+X_zFHd-w=RFj8SqrJSNn?&9pDjz>?uNxcDsalx-%G$0@2u&ZBY z{6|Oex=6!J1BA))1rG2vb)62Yhk%?QuG%^9&ALi#gqYlsf7FIIMC8yR?qt2nEOlC3yA_fb)x$dME z8hX|e6nXM;8DD;Q8_Yb3rcXc3z^j+S3_zU1%txQcyzV3xZrVgncLJKezP{*u1_#7A zK-!K*$4tVEA+G+&BHA<)Ei*xb971Rz7R)(^fK_lr_cP{0ej`8nheqbe2G(vJ=I*#; z_gizh==L?d(sdAbb((Hx-XLfxgy19CYwQGZXXwd>F6ktUK&!^siq(1 zmo7dZ0n9u9c3>9RgP_6=n2q|~4tLbOPj&%{M|N-Fke_^+gJcI=M2JU+9)^Y_zgTe* zN4NR8dfj&+d>|jW@JvqW8l*nEg}cA-X^t6s7BUC1W$SaK*y7xH(*y7hpk{F0jZeTF zoq30Lam@*fXe`7j_%ckO80hVxD;mYhhu!Y8*k?V*EDDdMJ3@;R*AwfL8iD|l^o(>Q_j9@rGZ8$?>+G4bKHeuxk&GbN;urW z?qnWMGDTy|AYnNI*3uLTl|uz{oX&Jz$Lu$$l@iNx3dC|Xq*v}0w+o1xU<(tlXrrAF zc|74kTGWy$j&pmLpm1HTYLsGJIc{gUWD-qttjS06PWB0a3c5ePU_6XC9bNkA^$ zDZ~Vh>sQXz76~C-`v(VTlmkwNk`#h6m3;tCKJU=?ig|@UEXn8dRg261!Hw+)vuWf#%rgX@FlBQod!-$$Sn7IdnH(z z4E514^;L1bO|u@W-cM@E)YNHE*yJszD=*xfmY~#`m=cKVYiWbbb3m)BYgBymmm5I9 z)r*Jt?v4LIQ7C@;QUEl?t(P9aKhBTvgHvjV-K6pB4PnkvfM!8PF_r}@rej&qtaNe$ zLMRGIH+*;y1A%wQ<$-yop63-P+f*vf=i~Ky`Ngk(!!LgI8$2E_^XD%@Z)&1B9A-}@ z!)PYM+i$F;QYkr9z+fY}oXvPS4^)`&dZ}+|!!wv6TTTD2tS;VB8Cup=$2!`^b z)YR1A_j?)7+f>vjnkE<-86g~wa?Lf@aO3sYJGR!Ai84VIE$TzMqfb(b2?TYnsld2p za`VkM^WB?n!sGEk1yZ(`B?lkCx{ZB!grH&<7&qh2Ih1cFt>E%|MtS_;_ODXE~cKQc;`Nic6$X;&Jtd=6Il-pb~coUsNzWKb9?IXHi@b}zv+ocGR!WK3; zWs#LSQ4}>{ed?T9GVEy zyStB2lVrhyC1f(gcmrWRe!&$Sv}iH9Zje_np^7M_Fb5Kd|C?rA{{tSi)opZAKrg0D zI{p$6`)k@h;{Wpd`{2j)Xog>1TmtJu45y2D+WcfrSkJTf4MVDxT4mCS4z>Zp;>qhi zf*?)~NiZ95QIr7#{n*(#kkkGM_(v2KAi3InazmU&;XB}8+l(Go4b)&K=0uetq{PZOtz(1ch2Pf@8LZ+WJx1Pk@&Iq}5 zf>0Os&3q-;xTBBxCv|e=@v|u;5*)SULtG*RXWsfcuRSNZ`=(Xgb@z$Y z)Lf+$UVjBI0;P03dKUviu*2--#h{W5>1Cn^7$jfb!4c{hx5 z`8ajD59}TY1W2YN3#?hZHN1xTC;PebD`#;1El;vL4~)X5Rc~am)99%;8s^!p=+_t3U2o zs0Jib3PvmsMB35*j(cvZ+u&q?pJ|#^cO$7g$?%SzY^nw5)QO8T5gxTHg2Hj(D_IsL zMb#o1rO@MB`T9AFv7G=)y*Aj6Nc z;^gHn{7R>qKNkoP5Mg$Wf@erH)}ldFF+c9COedD%g}o6TUzOBieywfnNv;K&`-~c)3aE zy2J!mui}OsswsP=5U%r;Gcj|hN`BYv5K2~o(R}`0j#T?M(Q5WFgHi9<(3&j#Yp49* z#D3o=gurtD-zx<{rBS9*1r=piZ-VWB1zRb60kKz{uJ*M)R?4{!6PiXHT2<`tdbZH0ja3<^Y<;xM@)%B{Bd~ z21un+G)P%ZdY=RnKoZB6A{+=-z}q{bLR_CoCzdVl~&NCSF9>r5gh3sXn()3c?)*UM~cxC0BOV zN=VZP27~Mw9i?1xzPce8WHg@#%52>D1`dXCW-%U54Yf5sCdy@~R4C*}feM}q)Ob8J zXd21>UZw?G$mRfYR4udJFu-2X%8Zyz-@hD2=eM8XYb$s1wOd~0$kXQV@;No6h$D0- zAbheh973QhXpu28!g0K`EZ5i~943`cku)QOnj6R^O>7%#@KDCl4SKy^N~IFt``-7s z>86`lzI-`XU3C?U7cZuzC5CC5j%~jSx_|rFZ@Kf%JNe@u|46A+0z8C7fUKRz>-Dj5 z<5r-Ciai0|T9hinL0u3vxc8MB9)G+9wnbNmO>G*m3Vd#98!Mk1h9RAKpL>LXKb%i) zpbt$!Kq-#U+p&6!*t&Grc7QRhNKh2<84AN_WoGLEq}3?dq+^?03+Q1-lQ(DnT!bbV z&Y09kJE#k_qU(k;m34Cq%L05>94Q6k%4tq19O~&wGBG+yc7!(odSGOsH6>|Td z(UhqF<8E00Ss?JYKE!+Q$@ib?i0bCPzvI|G0N}59c@zI11!!aL!PUTAXA+=N1S8#y zpco|zW)6nmaEspBsxweQKp9C^NrHaCkZ^>NmWmSzbpmmaI;Z{oPds(bfgGS4G%9%R z>I3=N(Phq9)Je$#W_7{qtLalqm;k0@LAD<~1htk$T}uqp+C_~tATtP}LS7maQ52L! zLTE0Q!iKCeKD3*$BBz@tec~-s58Wx$F|Xay1^173sR@Q zcfdL9^Kj8an+cq=DGH-IjPw!*bl_%h*gS){$D&HXIh{`gm3~G^N zu_y=$O$OK|qAAJ*kbHY9t$H)LoK1Ps=?8Ia(VVFl|K*IVzf?hZwUbt&JUc zm$PkxK}UB|%sF`-!C;WlTn?duhKAnUKw@;1krA*%#8TinlAF=r=H~5XJ4UC$SI;A!8fk?hMQ}I39wwS;=Vse=i)XN z-=jFG)dd5+36Nnh`^n3>kk=p}kiueSR`T`VuY+g|WCp!W5#JUk(9#A&{SeRzNU=B9 z0>!v#p(7c!(g@{4HzcO%aV}3&E2&hPceZS$RC1`3nk`7#ImT=oYh)D7<4jt{OC^fA z9AzNn^Kq49{jVPO}9GmuxTete9J%rZazau+2_kg&2SrD)RiD#fy76(~uI5(+7uX&@?( z5iw|MYa_d7gc>~H_0r%PZj1vBem}urkX?xc9*>u2pZz1xKKmRVkF&CBYJ8L^;>Aa) zSAWS0FESmMp0-_UKINzpw@Jt$hEs;#X{9&&Ka>7!&!+Dbw-*!JzH3}ZXF#RGdSds z!p8{vf3Em{_dcNbpY;&$E2Q85ef>Qemk;8q z|JMP%|J-BaP&*%g*oSU=iHC=IawrbZ6+mfx`olhu5?hWzzyu8RYu7k}V@(HAKo_%P zHZOeU7z8l?xOr?`Q=o69#+=7ZXx#t@cd}|}Jtv-h1kH&){0c~=AYk*$mp%OQ>1QC? z4VHvT3e0})IBgDBoF1cWO+c#;hElZMItZyW#Jq%339>KlZ~($GKR&Anp$g0fc15}L z(N`I`?z50B@|73XLmurvppMPsbE{cTp<{x*aShcY7sWM1aM%NFvfW11Nh zJHd)GAS%$(!f--kLMa-o0!=L;Fn7Qm9q10R--6bqVD)nEozL-&k6*|i1)Trj8ps5=`^ec` z`u&F>d?HUjy%nBMLwGUJ&b4>G#m!${z?_Hoz+;;sWAfDt7U7WsPr9FnuUW{s*ZCNJ zT&M2&H$WF)YM{;KOJ-iCy@qQWt2Kji3pvY4zcJePPPQga7u@I+5v#3Mi0s1WqOGvziq(&;j z>fK%Bzoj`5iy3_N8{gopv(CaWBE(`bOfy9)m2%V8%@5G62!g_~tgKa{TBuGa#e{Mw zOj zq2UMe?__8UG|(_T%s8M4LGR$8ll!F)n3D!1QZj5g9nFc!&Ogc( zs_(S{cGBHF`%Ts-_j4aI5J1!NRodUw24?MFF+s0$fx`r#S0@mY=2q%mQh)w#g|)ct0B9gzM0S_+a6;Bc!jO*lUM8zMt;K`8OwrWn#*tre+FVdNP;g zef2O?@6Uka&Q}%?2n0walT4tnET>p)GGcpkR;B>78l{m_`F*A|rRr7LdkwRuNw~cQ zHjG1FIg^8M1%~3RR)=t82yWO|0;O@#N%N>BMeUq<+_S9!f%%YsnGU_qH6V#o8}id& zInw~c@RL)*t+4{Gh9gCDdxV1)&j&Az)-;lP_BgsD5n!a8XM3UtsHM(Rrp5!K_FlI;!mf3*0u~w^7>d9E z7+5G1@P|nj<2-ZC3{G6Jk=J{@#E$t816GlOl;r6lt4r$fqYH^?W*JPxu`G+}vjCVt zXTN4)C&Tpj_ptHLJ*0;oK-r3;j{Y!@J^nOiW|SpIe;8el($UpTw7m-_Z*h_$?AT7D z1T_e(6ijRBB$Y0rOCN)&K61)r-n=>d`?exCe)~b78v^}&a@JcseEn%)4zhJ!n#Ncc zO>-io2L`B-HkN5RW(JWKl+ii`s8mJt%E{EOjyHuPers~a_sfrjEo-4wfY}d$cBl9v z1Hq%;P~Pjk)K)v1$^|Qvo8o&@ zs3vWb|5o7g-w9UAf9d0v{ru{If-6odIVF?kff*(bT=8k_bb<-fa$P9|yyfPUNDpWx z46kO#YjNs7^9ATz$LpV3$j_p0bK6U4HtmuQ_;|X8vsMm4bTh;Eok&0_$6+aaDhv)d z6AmoM6hXxSi=LhoWE%-cAMEOd*^A-1^$rhsmn6G04dJ6WG`xm&w|tEBwm3?MXRrJS z%P&~V?!1SJRm9`>@za+QpgOqggz4ndY3f2PPG$?;4i6q2@M2H$a80a&a;GFQ5DCUb zg$V?yRF=kA2qV(sT-SUNqOq#TcW)u!biQrVgI|Y|GSNjB>6GHgWz*q~hk(;K`<7J@ zUJ9A50DSZ10N>oO26hx-_8bVT<$^^^IprIt^XU3o{+wy!XD_dIKvgo%+VCKjbs#*j z4Z?Go8-9-KFa8M0zHMZz4n8_h=Le^i`SQy3AlqSA8W0>c%g@ihdI7J$vInLMK6z3j z-@dS&4cpeD8HeDNkTetgV0jCNCYO;@Ch2sRqSP5TJv6x@Z?B9IR5m%QA0cC8w|US* zSyo+hEz0?{@*rI%R6TKu}{3gl1JygtX3<#YXHNu$6BO-o=5-Aog z>SX7()hOjbk9AQ_nKbD!=ioaC(%s znFZZXt((m5fEXLwR_}Yh>|cztcP8yP7ft!RC&5r{HGI+i`;-EFY90xI6cSCFVmROe zh4Jbn&!wop2hFT*(zL*~v2hF#CSAEEu&J$vHwt$$=$T@$pzR})uLA5T`(2Iu+_h8O zq4qsHZ8tB*p@U6MQA(B~FY?t;NFf}zJ+Bn+3;k-*@G9KEW*p7K{`R>@1`ER=JP?l2 zAOy%BSTKvDzPJYF8jd}$y^AN7oJx6MfQRGo4|l%=vWrs>>BiXWEilD48FVJ?pIu>i zSchuF~kX1BWp7-tGDER%{+!B&d8LYM{>r~+4e%Dpy$Q`0Hn%{SK(4jTj`2GZ|n z+00B5g<^VF7jL}!0&CZ==ZIxXS-NyF$DMKt*L?M#2}N5ubjguy?(L<{w5WHj-*Z#U zArO#L0^Mj~B#|a2CE0kKIwOX!r4#*|zkt`n(Aov6pMSjPEWYFi%pyt}h$YYqjHG*+ z(E_816tx)GQm0>7{88J;|EdC&DTl+PFuE3pCtSkM=&h#_Zi$dd3=obS3@Ao1xcZfG z?tSo8U_NZWk2|ki!sm}!!q!a#)U+GaD@8-fVkDm6(hJVz6Q4W_a7LkeI7&1cWpiqX z0}nfjp`m`dy5`c{-p>4ai>nJ(N|3rvjdD=%q(Av&mWE|nd(%$T-v=`O-v%k~onBwN zpNRjx07?0OkoLy`EBn4+ZSwu3*6>fCKY^i)$wMo9fI}eA!;`ms1p2n2MMAWRnA880 zK7M<{hp8pQpbFDQ6A95nm$3loWxS=6y!3Oy=`%Rz_#l7wcd`AITJHG$b~X)35beym z;SqLx<_L%?7)o*M;bp%4sgr0=^;0&})aVTq#DSEBK`vyIRcXh)WU!Zi`^t32fv-K- z>-eZ!L)?A$`BeJW;*}ljQi6j+1)v8qQU1`EW_Eis40%B7=c7vwVP{{087(;AC{y5u z&vkOz(wW3W3SBAkN>HbN3|~tKOIffr0U}0|N}`!23k(l&YYV%qIDwX!KP@c_ zKn#N>T>6G{@A!!^;!iT9k_1!-UfD*SS-^boOI-Pbm$-k+5U`O|KRudMUy)0%d({DB zO*WYK@#?K#A!+t9-B4V)L_ymOzJ2)uXFpoM4l(CM8ie5W&o2U!_)q^1uMQMB7K6T6 zBXt7_t~#@ht1di>?d#qlt%7tenMpG`Ls`K=i(ue|OQ|)t63sT!Yn_5mK|pRKr&1IX zajrOLHoLQFhEp%2>oH13n0h^eN3ZZ&JkE5WL54}C6rqTYq1*JtH*(n0rK~#gT$&hT zqHiN1EX<5aF`&~rXEE#h`uWKJ`U8)A=M1jD;ADQ;x}LL6T7=gR+mpRix_o%E8cJz& zbckGHk=n+9DZJCZyM##V_=xCuBq6I2hXhhKB7liy4UTIL2 zliz0&@Jsd}-j|=h?_TiUfw)_@ZR62L@1w78fKg`9^Sl<{dbgft&outH*Vgy9kR(%~(PCA~lc;Xr`b z*Y}Z2Dpo%GBL8yb)lO!S0>aYmP&!57L5mKeH)}C#-aHsT9MeNl=JtQ;K~GZ(r3QVJMx#qqj_H z{uNNRLes=vI?P|tD@_F>6YfMpD!C7pZ|c`ho?8w`(A>0c_Q^!6v8QBtRL>}9nmgeZ z@s2)4t4^G7X{#@L=zw z-ziTP`5`bs=nsZ`&{qIkHsLs2nwu%!+5bwwtWAS z%>BY$jid{}U7w1?MTFj#HeIZ6n#EQf|JM zJ5fYlsZ^3&+C=yS@pzmGoO~dq6jmb6&O{tDV{!Q6rHon*9l5u+A0ryY zh{Wj64$x)9=pX3k^^F^y5XFGN%3CyKEjIV|A_J2Akjc3#E~J0c0B>yENDm#Z^{}KM zVx&^rVYmmGFN12rvDk`3Ua^N>OsTM}B29XTY|2DR-3j4TE`Y}g=_IT}z|q_Vh0U{1 zJjzv9te~l>sS4binwppZJjzDdis?;ZCV+Y&kbwYxJ?vVbJ8Q5Y>}rkK(b4LfB4nz8 zq?Xk{n_j^y1DIx#nR5?!*4Z@OX|CiIyjCQxVEUXg@2D^(p^#>huzx-$Ui}8-TRD1G z7nwqVpb(TylMrEaQ)Bv($1rTBP^w5yDROp(cq&CLiiTJ_;cx&=OeeAP9d5kw1|qG~ z*ptan$XMKe|NX>bG0KG^v!za*?wBmpG8t(iNLY%ZN)Xa5Y}G?sTa01hr|k>Rz|d^y zXmOkxWsKWatl_q>?yPSs1-1#%#jxuc-uUGg2#W;mLI)+#%{&V-YG3Ntq|bUSjzdTF zrT_*a5q1s?;ImTHv@PO!6VCd^Gmf7#0<6_M|HwC4CbN*Th!~v=S|;_DiLL}m@_g-E zU%@n!)RO1WgAd`M$9{tl2hiHuK`122CI$YmPFJLx-o6AgT4L1ceiwPCT;L>Ks+VHi zG${+`fXnTJH2$+7L;W{_ivODDd9R80`;EaTrz_?6eedG$1}y*GQTEIaH3zW(7L zQWp5?d1tZk)P35V6G07=$qp07VoziqnSnI*kvV+j zS3CLs$_<=-S|^X3*UrL1KgV@fxZ?Pu_}B~Yu$QB)&}OQU}~IVL^!ym!kFba zVt89ZjHinPm4(k5!mDbWu{$Q0FPn*--oRzwKas}I+y&uQ7JmG0%wJ#1cp`z{Qba|D zTQ69`ihK8P;@yAX^uta7Bu9QE0tz<_&U7X{D#gk3qa4suA(1etGuoL@!YPsx1B5~q zmc=5xvZKJT((njLDLp`~fVw%0`Awf6@+ru>A(W;$rSm2cSTv&8Q`9IUXw@aVEbwgG zN+f1;^X12JpE#TeA+ghMQXhlQK6)ZQS+|>+u?R=B9Y#YT&GtfyT|{YZ>*SZ~wzIPL zHLf^zImgXg!e}DPCUZT9e6$nOnojtOzk`&da>qwdg{{=7FuNlW+8)~sPp`wg`!Y5p z-lSHAd80UHrK84;*9MBbEV`M&$rQwlVALl1uJ&mN9!X^wY zopdk1j#(FfhM!-)h}K=kWbszrxGEd6~Pezl5FfNAOs)@kHlx+PPmPc-Wyl zaP7sUx2{DgL5(v1qHUoJM9JodumfQp_}wc!|CUL3hE72!{7Nt&B`A}qWsyXJ9)*C9 z!x-ZFPaOkhVZVF)Z@b~Uy4qO3ej8Fs48vd~o~m|7)s(_=ul8ZDW^Mv!N-m|-EE6t2 zzwAzUy;71eH8gz~Ez-ree!hdBy}S(!!F`vW&T;d+*xRzuIfp;?!52UOAmkOxkJOkE zlhj)E~0N^ZJ!6-OSonA>i+ zi;h?qo1_nH4Z;-?3C9#h*L4O429U9CmVM|58e;~pZRjTu5DX0s5sm8f^z7oyGtZ|+ z33jF8H0cJ{U3VSX?3GBrq_?jZUDs)H^$(Nj?Gx+^D3mIqtU`6~pKx8Mgj;ZV75fOy zt3|SasTR-syH-}UDek{3rS=ifPd#h*TKl@|L+lOA8=vyjk_XjLEur9_&< zk1pef>qqEcy^Zs({t~CPKu@9%+6+)nGXLNRZ~n_C7?&0se|YI7&OZBGe1R}K zhf-uL#gBh{FY^y*#VZAO+;Io#v=iVRi9}exemy5FT0}ORg_Pp*FJ4V7(8?FDxPtFJ z@n_d*S`kv9R1}&F9*c!|lXk}yj2J|_d9lz+$PcxChho{>5@j^ei_d~4J?0eeD1ySB zv<=1);vnMj6q!Pj`|kfax-P4(YtEh~tHu?BsW`fBpp->})Y%!2(;#(s8ZXHy$Azy> zcdq4l)}%h7SDpGm&>$gUDRg})9^G*6A7z0u`NpXS@$Jn84!Y!JIJ=WuS`1p{2&-t~ zhF>RLn)eW2J^cg*`?e8Ql3EnDt}|gm#w?Ii9%_`pDkx&H81v`PXCxkHER`asY*NF! zX>MrX*rSi2f7cL&%qT%2xc<89x$~Y|NhXJwW_41h>&_J1W#Qx$v`FXow1R-;AuJWm z5>5=j??m2VUk$rCUSS-KuLamKC+=jI2Kg9P0YXABqT=WZJR-(i)%kAf*Z$ph z!~oN+I1O{=@U6!-bN$LRh;A5M%?~bK##I-47)=bYJ#JB_+oV+-h>;UIDLq3r?sP92 zV>-1+cJyv09Ig-uR2a3A2w@Y7>ZFG(lu9wJvx}Uv$fYtEhCxusYEr7{21QK-I{28ePtYz5>&Y0{{A*gZQWG{|w1l-1CPKKD{JF${2@f zdC(<8LK0>^6A?h9@L@2g4ajb!G1dTKoyVSDNBP1}5J7@pqLko6vYSyBe=(DWVG-cbZ6#J*_cHh0ypWITbMcE^6cwzvdpih|o31|ne{=Wdfo)ZH-uK70 zj%*z{x^i^oST>du+lg&R0!bhVgeB}tN(-c{g+d2P=|UH}&<%J>nRaNQEmLUeLJMsv zr6DXWP$29iAuI_=91=URomh%3$GVDjW$Vb+k>%%)d+j7Zr+sJMd7gJ(|Km-|-E{8n z_xo;qJyJp#LAIt5?^PQdk9ASWUmkuC&RW65)j>+?8);lU$nHO-AUqF@cEDziE+JeW zqU6HIAb2wD@iXzxKAIy91VbU7SoJ9AnPj@^sbBFNn;-ueT5DR>1o(V>{rO!y{hLnM z-NVk~_p`LgWYkvt<)tkkYUx`24#)lVWjgP>oU!i5D9A8-Rgf97jq^YGUGN_Z{#wXt ze*NZ+1gkvF@dvTzvAWwl zmo`D=EJg+e=YRO~{NnfDV1J^WkeDFz4;lw6X;D!t@zex(;!6)h)#(gpOJFbobq$cs zK-MPd_d7JcDu4_d2HQF8vTKOb{(&O;fA%YpNVsMv4uxWxX=2;<6e@q9aAnHi;l1e0 zxYCrmNV!rrBd%*sooSNSF%p3`7JcJYP*KOyQboDy6MyCSn`ZKh4B-KZaE94PJkFA8%}Ugy|6{W8;WL zOL^{{4aDsneO4#euYCjRj)iQuTNo-vZJR1XGGJL$7zW$ByXf8?Lq-B0BKmYm9 zIjpXZ-JNk78|MPjp?|r@H(@6*O-C%;XW3L6#uQ~}%0-*cZlPt; zhu<%$NN33^h5!GdcB$w#AY%uu5v5b<--kX{97N$R3PGg|9z>ryfTm1dKU(K0cWZ%3 zn_(yR$IXOs&9{UQ;P)ehAe+rPE@xgR(2@5s2PP=hUibN4DqM%BG4d2$8|H&8iM_%J zeAJVc${+Cg9CHVNlQcCUBt;z41t}$70frGo2*EVNa0bjuxlIXf9*ah4MTPKAp+80O z{$uAwF>IB=%qB>#1<^n`1~cNF+}fJQ+giKST!(c>N45@-k1=gsXX4|%1Xn&Se&}P=Uw~$hjO4)=$2i(h? zzxDF;3(vDZtH@?GO4*Ddm{k+y_19m;tUHUA@N6D?`f1n3S)e;Qs1%ZQ>)xa&1U+wb zvd>O4uDopR=wwDX0{)bv(Gk7Q(bisgY&VM@90QSbSPCk|#n%lu8B5+Q(98NievwjP zVi<~1JHeQA2K1Iv&i+-KL?Si3JFtV=P%T>9bacir0)|7eO<5QLiOOlTHb`mhgd8L2 ziYM^-3{tj5IfBeUg4&QtcXu~OES$&TO|59H@kzlz!lEJKZp0kW!4;2?~=4 zc3$zF(~GQMyPfCX_QLP|d^NuxjtGFXoc(MlVb{N1OnJ{c2w_r0l9%wdZE;j4{Lquxo!6PWmD5SO-!k{P`@tTeFTXFn$oS%RDL@w^02Yc~nP-1Mk`Y;+BF#0EjmkI*!>DBpNm08zLoHp-sZE=d z49UfmeBm+ZZvfE%`A3=f?b&p<)X~{lpu(^ziX>n#T^VRyLQZ(8RJABZ*{fs3V!h0c zMrdj}j#pmpVp`aXW3?^_g+ip$Y4Z6bLjw>B1z5Ih8L3oe>cijN-Ay#wG&O~BeB+tY zTD+gmrT;0q*P(^H_-{a0#6S3({)e#6Hf$vv zy)KZI1}P15RDyTS3CeT>vlBT?BS~CJ3bKg+{S-Z#(n13v?E#%4X2;kf4eCNBk%4Y9 z2n^lKxZHsd5h_C=AjU8-A|*4GpmbX&14fh%DGA%%M5V#&i4@_c8ifA)Su9f`!heWz zz2ALi%sqznO4D!D5LE+?(L=SSTsN~WtO1*)DE12257cYTHH#19Ck-zXC&Uf+?BR3E zkH@da9nPyTsk?6w?36RnBr1jq001BWNkl(aU@Z9V zysv?=gwOnNGoJ|?2lhv4XR?vrz~Ha0B_W!Ccc4pP+~RfqpH+}dz)TZ%r5L+&DH(wS z*J^{5lvoUs6B=7IFx?I@DmAuY z4KV9mzVZF_?7yml+ZP|h^!s*!=yHNI?G8A69&Cv7l_f*m`P5!e26%(e+r#GHeF$>x zgagf(tG7dN9wfK%>q}Y?Ez{YR86cBMa_{x0a@o9nob;1TP`iSoe!7L>>t|94yft9* z^e$_~V`Lg1?Q=UH>W%-8P?$6=a@~8mtc~zWR8}GVg3>$$3?KdJEMt^# z`;Y$@H{Q4kL@khnV?xZ;VGQk|knAPc&_K>VK|p&rLY~05N*t6pKH+3WpbtV}^?StD z`U9w@^1uYuojMBPIKWIIBL}0prSIYNPol3Q+DRyP!qJ@Uk3ES5^CCX(ey0Ssmq2v~ zvo5G-cmD=Rr&;^ga*o)z5xS}&tEdmIIZ5Q&)h{epKlZKG01URk>ZIGqnNBRTX}KV-A~{^bo^vAl`U zOg}l%%TY@!DD%x^f5M`%uE^q{YNkh8SbF{4PGD$QL)xN3+l&BdAu)tx)XuQDwUwA{ zbIdV8W=8TPwr=4&S6<4p^UkBUCPaHK!+b4B31=!?6oLtDVIoLtn;{|Smj(elfyP0$ ziXVWwr$v@3?V}P2D1^`yWEEMV2!uUTu2X+cP%m7BCr7U9*cI|zggr~Oh{nwpyFvn(!M zaUL5tZY0NEMC&w4pNqoaC`b=E)j%{l4ny}r^O=zBa;=MF4jVu;f!__h%?e}zyf~=C zxX=`ZNl;t#%CNh%X*+hZ2 zxArji)P+2nYlHMosI37T)_nUDJkzAsiBTP5E%$P9)zwk2Bw~s&kelI#-g7gO|M^INc3&RK! zHvJ?L{j6U77xoRkNqu!Qe|mE*9UXDLeCv1V>gweOcl`=2VN{z0w4#y}Xagm{Yh>}~ zvYZwPQymJSg^ftXpk^Kq^gxF$5LKG-#9>62!SZ;VA(=+fN|Tkr0%Rb-e7XGqqEaRW ziA2BS%GDTkQj%?(Ix|8jB>8dyesuNyF#BX+6C6Fk`WwFpb~jP2*?vYZxO# zr3sc*AfuCHjWpFpIqk~krNpa0VTi3Ua=m{=ny6{aI{ zBuS%b&|?+w2t}2VMr#<-iZTRV)1(X-QZ_{mAt8y2c?4|m=@=!3#Yp2~o{7W5FYjS2 zZL`+aV2p7VHpfOL`1CnPalA^fzq5lfvy}onK;)UI3320JwsHTCYOrmpFqxap@>=r* z>(5(ErN}T-K+$Suqv|KHUi6*H-TN`je#&tYS}U|7(UV~P&pu22;opHHnz`YdeH?k&#n9&nE=lfm#L=^&kc~r7 z^H$%R+}=CH@0NdyC-1$O4_$pX)SkfLpZ0`=j;o927|r)>5sQFzHO9BUB@gVKvn~Ny^xg-?5dT+(f3=<_9SgcTf}Xs zvkUa46=W08Yda@KN@r>;4K}`f0vqGcQ5`zj^^`S`ayk`yf_g0(WCwK;_NfE~X%aO| zVmX5!-})<9zJ%k#7C*S=Bq|5u%u<4Brl$A#FVb+^2H4)f4{zz<2d@AdQovH~IzPmU za~5&a?Jw}qt^#-7)#lhDcRkC!SDeA8R-VkR&X?&jLX_0_Nc}zzd3fSmr}5#%V|1lD z5Hd`;4$~9&bK>$jycjV!<&HPtb%p2ZIZ(fV#ou@hWE%uuVEqrTMGv$yqH{!~i9~bv zvKFoi7@YBg=ULOI+02nhong8V{NeQu@V9aKNg@9AvP!O1A7|OMtDUB&?={F<-0|Jz z91}^BQda7j1zTlW-WV^ZT`o&!P;U$cu+R1bb&={RZJ`tx>8U!`mcKvy5wG?F<=9qIy zb-ciicap?n{gk3KN8ZK=aive2(r!<{xaaQ;>zEV48qETVExJmz`U8 zFgqGyS8w;!?EAQ7%g82rxZ&J|{57W7B^B47bq+y>7?&nvN|Q}ERFb_`35yn0d=-gi%#q!@V|%AHGX z^5_GNh?Dm2|EJHl*UbkhcLz#iu9mb^mrOA<#->E(lll}_gW@(jr8xO6rCMWaMOof6 zrD2)e_DK={DEULg_<0<(q{1}=@PEKPw*oH+2i++OLD4(uOy)Rz>3r7BU-{ts^(gtN zS3M*k`h88fI3&O^mrmpN2c2d`2&`lhGaN)~HAU+Zh^c{V=|Os~QrD9D;0OWno`Hc^ zdkL#<$NYsfwu0gMCb9z-6-I>lwq{h=j7d$_hEXC^7&Y`zz?K$u0)~aV=4%)!IL%p6 zIu^?#Q|1@8qba~gsa8z)PbY5m(>l9>)vNzRU*B$~9dul>*%8Y8mCTy8nE4Gs`q@TB zz{8E-_!;a?^WrP_k#mC~ckbNDp51%M>paH{o4_9K{K z12be2vhy&w6>9U4t70&dqu!8w|Ave4N!J!wL*=(WMSNg@QP))JU>k6)H6z-ls;Y{; z$w5vy`B-KIt7)Fy%yTcl!pvDSX_hGph3K= zpVQAcpRa%YCT_m@W~V{-2(;3SXoYke?NSZ4U7)gYF2f2+e$)lezr>S2SV^^!;;L)^ z0CN^P7J$h<`06tZufK(nR1cOtKp2Jeg-|&dSJMvFs7UEJ#|)<&$CjqXCWccMH{X0G z|Ne3cK7S`{?R1K=UW4P#>xOU^($50@kUkRpf-hY%$_2}(6A*sNwHK*MNGqGpt#9## zPhZO$ufD?mJ-f*RZ|~{k>~lT@cwf>((W77ZO-zG2WB4JALQYrI{Xp0dom|ee^ zJp*xu0~1WkWT-X-6@ffMxdIst6^5Wv2yELzh<<8R1HSqIkBAUgT=r*3H#n39Awe4; zhIz(c$}`~*x7_m>PyXlvjxxNYw8eBCqt{%>(iOjT+?xmj7DHIPCIoC$9Jl&0@NcDa z)h&d@ILd6IFSCPET?xW-z~x0a!pb6(*2w?$^Hrk^RA-!e!vKF4w9T;5%J*&vv$A=d zqfWb=Qk|f#F~Eeash2fmv}WtuxA54@oB3!YOLzh3drl)SB>`n4L>re^7o&~Tb=vxM=nMPm=>6z zMB1F?@$<$#XEPr0a6~=$Rgp4gkV~b25F4NP9Pg%VimHUega;us`|KP_7)0x*Q;|86 zg@(oU8=L95u$&Por`$qj1SA0oMaY}!q14(1cb(t205(} z9uNQa$QD?92GGvB8&4sf8X%zrMNz|$$`R2CM!$Co6`yaZBm zHZSx@PMzy*ib zSYs9VsL)Io8XD%q%iWwSr?I=EhUt+Y_`~4+D-7=8iC=$)F`Dpax=H%_Ns9>Ged~cV z|8~LgB%gYY#(5|3VkW`iK9fQshx8{|Hn$#v3esWv`U@;-jnJ3UOqY`VF27xP1*2%} zq>ULi8P!R`;VAvx9ZU=F!w`}iZ#a|Nzxx{=xN{3%zh^nQOpcy61kHg~N)sAGNOD?J zV)$IkSf<3mhZd*ezr9JBOyWKm#nG-+u@HhT-OC$l8U!0S(r6(N&*7^PAo4KVgyb9i z>9$KaEs`ZQ(8GwXWk#f#Ju1P3nFUqLsGZ{6B{Mk6wy^CCHPYabjhe&j=A*S{%a+aT z*#0g{k6q5(*|SNfH9OlkF{?JpY(xJ8x|0W(VAM`Ct2RQW3tDH@k?Oa3@#!@jcEkeO z+L}52+;h44+qZJjMVIsG6-RN678vybatavOiKSp1NywD!wF}IM)-$f5L>SZ>f&tZ! zKRSphIdEqqc^DFkuLroxEgm-S@2cQea$=-}_w3{JW|O39SH|G{X4 z5Rz%GE%T&x@PAA%b}7Wd3B)VSgU9b@j6Bki2$$MbDxgA2#wj>dEA2EjWkMi0pk@fgIJM_{#qsYuhk1(H(VUd#^M`0t97Jj25Z%hb z!ug^Q2p7?sL=v2YcrRKj!r?GQAxQ4pMb*riNWY)v=4Quz$xdRLkwaJ>llweLZx{F} z6!Zr+^Pouy10#@!{@pM;f)FP0RE8Q;GGSTlM^Ho(HVkrBf})5qYAX&iBs0YX`&5Am zTTM|iiylc)I57|&ZDSY_x;i$op!Ikd+zwtzqj?^yO6fCGTwC zLQBJJ#(+J&dsuSfSyUTYcK7cDyfjva=^51Qi^V7_gCV6^blft$UO{ZvE@n2=k+BBR zdCiwTdp%atqEbj^L?iTf?_tzd9M?9JhyM5&UtV+$dwosVnGDr65w@ffR2v5S?F1v* zse$TrhID)Yr8NOF!eAnSX_}0<4zh+3Ag!F|K@##15}LumA?p1>4E)5qx+v9}cV6GX zocV3Ew{K*_hF6*H4>CP+IMHY`M=V-IEEXp$U|46F5iszU`6voW>#RBS?ASrjOPa+)Yk7NXjJ@66w9Pvn^1Jx*xgR0#YMXr6$Q+F2H2W-@Qmrry z$p~VKQd_F^RNbhxW`Cle;k>4M(?+iP#C05V{0aQ{$9HqZ$3Km2rzw+ywzi`YVuFYe zQ$yr2AQFjEVi;(hBpePiZ@xff;f#|`!Y~Y^6r|!QKswhvn!IIEB?X0=M%Kp*oc;BO z9YiY_b#2lopl+VSETP*8Wv=}sCw=8LUb^c9c3GWN)rZJtQiy;-QPjU*Oz+s_IS0kg z*pv&&qD70Kw-dVK@Ky?{H1xgXrgNJ>t>fV1m9TpQ1u=(;NpZfEjuQt3(rLxUja$eg zFske5>+9q2BNnn{%Vy@Dd<9)yyTsK5Ygh^Nls#Fl^nha!BksJa; z_?RXHBdPsdx2z4n2CER_iZA>Yf{TD|t~s#=AtcLd$7xUR=Qi698xjy+!iO%phj(B7 z3ZC31B7yU$ZF>;TI~j;^>7oG7bnIZLHwXqX-33P0aWAQD0(+lBZ3`Q) zz1?|lzu{2U(yu!lbef_E8yWqi7cx7f@zMgvj$tD*?Kco6ny`QfsymrOr?U=wXJ4 zl5fx8*C{^#nK}IXuXd8z8iBk8a~#T)*G{l6G}m!H>D$PbyFWpLr$8)ML#dFA+fF`s zSORQ7PEG@lV1S|BUt(W`C76_gke0w~56 zOw%Pa8_ksWWMJtT5YC{0Ix|2)_d3^7wWP$TWx`A{t|H*w14DIeT6GB}R)H6CFH%Ps zGJZsjcADrxMRol`S^_5R%BHQxhg4t$CxEP@M>%Q{ycJ_uYkV4vfWc_N;d@u$gd)za zcPOykJ>3*VE$Oty+-NJh5M?BzIc-H1GIA!hwNduP`;oo|3esdqDZ<$JwMG~Q0~Q#@ zWI;CZcMLiH`%#qlzvn>{}Ldnf@nhoD`^pY zZ!qF}C+)hQ+S*z-Qp_fq>?b}r$Q^h8m{P4sBofS-H;*&UJ)fhGUyNb+NXI%bO@quk ziczx_j9NT3jf~qsCQgOnVShqVZAJ)DOG#sq7N(Ktj1i13AfZwOA^`$Ml#Jn^A*!d7 zI@2U4B#Fd6+M@NOVx7)f_P+a!K8Skj2I!%u(!TwEKYoAi@4I}7Lw_%K2ON%zuV$1y z(}m*_H7P(Y*V>_|sYxW|y|iC1LV#EJDU*6i=ni>`ZUZznHSs+_PprVp=s^w4!OmFk zwGBSxF>ZKYxr?++>QzR83io^YL5)qR)`w`hO0{?DHOCIprbxHBE1R_HRSLr}s0aq} zOUKGPk+2YAVv1hoq|Y-&aTW+%BYi4`oN6o&Zf4xFl1v~#dqG1m3Rwe*6D}O~WGSza zbV?I%JdV$@2^f;`ni?`_gtig!7?rY?oX)wL2u)FVD7s>C56=0EL?UDpasKxB9Z2b6 z$8!&`c<~ad!Ul_)Tj}cBK{@coD{IJRv%J{1m#SbD^Nu+Nt-Bb}wKU8;nb8b<=87{I z_ks|b8AdaP5k^YM{zQVa&iXL1*ba_ebT)@KHSy?Ek8$fAcW}>7f6p}2V1}-xqqCb+ zmn~!6gEulgk|mxgFluYYu$WMaQ5>t|Ay;#f5p%H_M;a5Pv|=2aF-y5rE*l}7LffNk z*8k>T83poh{tb`ck6#MTIp-W+e|-b*Zrem&XYoGuD2<05hR$o=7~Ds}KZDCIyAWSc zqH;Fhxc(aUr8Cr-1{pmLkHnkj|}HMjJ{v>5Mbk z($PUn#K)FDe~+SoZddQ;1aT$+O_h`sg-Hl6)hG!2TVxzLaj~LT^FI>9H#9%+u0OW zjA)2NBJ>VeR8Gd&9kkGR4i+>P4dH4XY$_uWKKjv>T(V+-H5N2n)<)idvF`O8+tf&V zC_qI|iV3qGkIIlujB}U~LfDf1+DnEk{aVr7)WW5ox`D2)jZ_k7A;!D`i&bH(TXozcO4Ht@-#Ce4QQ=-{uYKo3GX=Gf~A!zqYe zTgrE~w)30MpTvgl{g9jq;TZO+^9k57+Jy<30;h&%aWgjJx+s_2_8Jc-qx|xbxB1?s zRow9AD9kl!ZtG{;b*E6+)`R-^wN!s|BfPSX*M4yV#&tgCfAU2Lp2f5A7-yOSE0#e= znM&F{Fr9k;@1_5R)7NJyOw(};Vs8xOe4rVWaHt`{e(;7JBxrjIs+%1Md)+1{$G{tg zY=e^`j&``dq5#1r*p*=@>xVk&(73j5at6=&pfly`%{hs{$%N}MZ$MXvlZu}Af`7Jy zLiSGvcNw4yV3$CCGR$Zzs2;bN7S8kf2V5v#IR&=uW}!$Ewxqz{3cVS~=bZi0en@9r z>YAGwvuD5&diQN|__;~Py$iqLa%&{`-Pg`*P`1;&OTd5T$SSc!GgqVW5fDgQR$eVnt2Y$Ptf<)(Yl-4g~ zSKMajx*o1ud>Bu?Q|*W=vmNYaJ|Q9C)Md~xkH2q+;U+RO|qH!B+)WT zNaWo{v5k-2zlPOcIEoT0&%T#Bsb5&ncukNbCcAV4y!ElTU_C?J`Q!LD5e7JTw# z@|i4NA&9g@7$(g`riyY>yVR@9j$2RTU%$$I7oNxkt~GO0Qxi%lX2^cZZ`;geOBeFsvL?pV z0LjK0ZhCrvyE=NoO7PW_=Wx-y7K&;B+wP#oFo@eR>Y8e>Ec+0;t=5OSGHG2hRV3pU z&QePJuKweLnv+SSrF5$4(No9fKtV5@n!?Q=DN1JpwAN&^S^R##V@E3wMN5Pi%GCi{ zRymIQXmPUfa0g%hNqvdPPrYZ}eSe*woGKsc9Cj#`3)i`Af^zMhdavRXx|ly`|4R;P ze4NJ~j0l!h)Y(eKal_Jf)T#$FHFx!>pyp{;%GR;fz0%uR*+txuWHbI#LfkL3E6q5e^-Ht%rO0#0c`6!iU#fp>p z<_$Mue&TY@J>z`PaM@*-^2Ez)u&gu-ql*ZTV}b-Fmd$hwstk!2O}XJ%3m26$^Af*7~ z*rd}*n(7*sYz+Vs`Azg)B89|J@|DR@xsXV)JWg|i%?%&!Cb@O=S+(u5B3-O+A`Y@p`3ibv9 zXu>T%IJF+s1dl$nnsbg{MupMHbe&-!m0^qnfu|lvCm`L)hs8A0M7Xq}L?Xrlsaa9u zV?+kntpyD=$MNVp`}s}BJ{qM>^R{uS1O2Q#eGa*J3T4|Mf@oc!9D_b9L(_r_h+-AW5T0^|tpREyA@;=vk$$KM%wRO5Ni#xYO^AK5Js3fW)}yZd;2c%2*2LJeBq@` zM%kxqlAbgfqm^I$YCi;{tX|m6$`?{FtAy<$!m#vn^@Txrtq8GB*4u((L>v7+A4Rj4 zFg7#mC)laFdHCWG7e6|{L!Y~!4_|#4mwfmP6!5!M&+z>7FCf?amaFc17V?sLr`8Y( zdC;8$?78enW?u0CIDKKFW3a@J;d?x>HAhg?`(*#Wl3m)jBU`L%D6V2 z9`65ZC-?8jg1y~Af3}wJ!tcI>+4KYtYa3!?T*zDe>y>l((IqY1aO=Co(}G`aE9Z;_ z3;E2~Kf+_}Z<046^dwSz?Q8csPGQ-8S|dJ0q6Bc94wXkBU1zM#Tegr+r@8d1E7{(& ziRJ+7Koq|~8+Infcxa5q#iwx7m!Dz#iyL`s&9`~O+Dd6cvp41C##yRSpY>Q7TK%j_vGAC#kBc zW`80v!5lc~R z7>s+M-7Wzg<|og+&1D~-&7M?-fG5B-;LnK!G+oFad*eK?%w}(6JgY9)Eo0ch>nVZKl)u_15lW=u8 zMRDNR*ly@)ZEY>SpkzF&NhXto!?i>k!c*tuP^}Ax7|;x5wM)fZ6cd3U)i+$|eY1@)1(2*EnhP+JLtQxcvGJtiJ7V=1ar<(1Dl2 zK~1Nla~)I`0!@_^2w~7CB961F9$R;BN48GZC(7tXnkf&qo4vwC8 zE`8Pj0W2z|$$%0RHI!<{1y)LvAyr^{WClvXLfwg1LpqT_PSUPTlR;ZCf+iZRXUnEH ziAL)w(-UYQFC{N++QiwHe4J93=Jdqlt5E7#)@<0of~Gb)I=VRb+?C9m*Giw2AUbO8IJI!FMWoqK5;eYop%wdR{fT1uK5OK(s^v9 zFi0d47=~a^B7rtcN4w=#jAO!a94rE38hjiG1f4W-(Ao*$O!e<3TwP5tXwcUaClZN} zNDT09*A9*|mLjDe+jh8-mgO|f!`e9?i9|m__`!(M9*Yq*45AGtMdhH;T5B3=YS`1+ zgAk^xiP0Fiz--q5yj#jCKRcO>U0{X`W5sqt-$QWZB0NfG0_(P)(Y35(v| zUQ9ELQU!$YlT149W0zle8E?M1&DB~6#)RYi(N^0=AmF2Ga4+s!`%lxU{=e9;99p#N zL$<$6nv@8El!6IcGnVM&rmI`nPMWt~h{NG|w%)jid7_zorkk9{pu})49FMY@$ka04 zli<9?^ZCJ@f99=?S$=l%30%1RqjakTN4Hpb@v)cVdB8ULmz$r2I?2+u8qk7U!b`c1 zaen^PyR4YIlofLg-nIqzKl~(!T8duirh!}TxF7rtEHdnVJTg?0knCT})U zx+tFD@1iRIO!G2qQI2aT2oyJ;nfZgbV6xLLIDOdamoW8_7^n5W8f>4 zFs|weNX#cLORpFLT;)N7}1&l%P6Q61+590HH-lT4L%=~&z-~8 zLJFS_5DxelNo5E()-X~iV56B(iWyQ6X*_~_CPm7!Fe4F!kOV_Dq*EzM>pkooNU&e! zXj(Rhab+`-vY3!XN)64pb`p{`8XtK#JE8zgFeb+E=n|5oDf4BiGQt#W$*3(@+SJCb zZNvB@6WBsBX4{lYFCe&j@ie}e+zK-zn7{V%$dyf;7lN`J)Cb^&oZz(EH$d$vu$~9QiR?H&i=?+2hpiBAsFBzMvO4SPz!+W|5PM;dU~(>%Q4O<1d7mcgpQ z4nB9rbdH~EQok%fd~<h4e;#@tsSlGkxrg$Em9^ z>9Z`C7wo~dZNB!^FCt}tVJpSVnkYhpza~P`@Nmf$KZ3y{A(>}atb@9!B&bbZeR4DG zn@zm$SWdbAS^n~)Gby+G-Oty-jmiJrq}PKRB&{_`k4>Z@0Dmii^%?Hpl7q0%L5+hJ zZ1oV^7$b%OG}At~n{&T46VWtA9~SipEM=o8p%lRwib6(HfnY(yZ00mL$mTRd^6l^b z04WU~e*9_rESu@>VBv$-rOB@m?X1m{9B~jVYMxJje;3nd&SX4a!tHn51qkl@-Jhs7 zdD$4sVq} z(Bj$KFF=Gmobr*c@$8_@{R`*vu_j54G^h}goR$de|IlFOfRTa|eyAqbXzxGQtd;}& z^LfWs)>h<3 zLA6s(a|d!!ie4{8tq*(`2eelQBPig|zDjYz_{#AzP9E?~z4zo}4-9V(G)t3B5C_r2 z#$ETWF`T9hH^Cbmi{wd4PNk4;K8+JlQA?B2l<~YP7#{0knZ{= z$jS&mczQQ%&w%WP*#eSFNWJQZ;6i3M^z-GDr}K@c@(gY9a`{v1dEvsdrY?c7|V70u_c24fOQ%@W2BP@c84ebImnp5gY7d zcC;1SPEZn&#O)I54eg-9QXn)Kh5&4)*#qQki&7P4+z^yIAs*Ov);*TWwSl$>H?_F6 ziAJMIY4BCeVC&Yc95a7DLI}<}?>wRn%|vP=ELpsS?(P_oNQBufEtGY3(%1hic3Lsr zZ!oMUY3=a9FMq+c*M5pqPd^6)48{l8ofu-xnl&7`criyVp3As0c#*QENsR)DE&zZ?bP2s(n;A$AP!uMhNvkY6 z?>&_IH7TGglX9wPmQqp_f=hn7o%UBdp-xiYzkw!B0No7UW~jA6W?{RZNB;dyzPs{c zO`*%wRDZP`R3wZyu1Q4tJdSrq@f{7e}95X zA;}~aFTJ#maQJ^S_vYbkRd@dX%gd3iBU@LFt{lmU<-~Rp2a-S%2vEWfft0-zx}*hK zTA;KHGhOJ$l(s`l*O@ZYp|q6g!dfWMvXoLvpg@2Gl0XuOO>8HTv87m7iLPuN**dcQ z`{P{64$#8ydA`5-{w{yO^VnQj(z)k+KJU+av1w_sDH>dL9GOEiiB7#{$P%9ipb9=e_^K0mQ;SspEkLS;W*>NBBIz$o4 zaIT68RYg=r*e8-5UegQ#dZa3`U7h&xQaPv-U^X3A@m%VpSFTh&j7u`qRO(sokrUn zCj)3~J6fUsiGOeazLzVe5=;ugZf!G^7+{ebrpi)Sy2OOi)DS>xKa;LQmCjI2h&th; zE*vA-Gl8-k#$1M} z_0ix~u`u3Bs=uF-gb`JuAWDXIq6J0m5)cxaiNLq&@78}@rtvXk}lC~ zMF_ejw4;gIE#y7tom!7xFd+oBy2=E8A?b3fI1m$b=hBR6Xhc%2T}GTf=Gc(dEmZ3u z(lQQyqbLHI0q*(fMSS?Wd*S5>AMEWmnwQR{FyuhiXQ*nv@AAs^7aIqVfQH=x$QF3{ zCx3-`C&8}gp}5!3+ve0lTP-M;=bc`v!zYu^Nn~n0sn4Ix^|!pr&mY=qxY_|5?tB{L zQcxjIS~<@8E7wun@DergMeK`4*_j%k(T>5-9)PFo4ApPkPOV;#M23o8{wYe309p{SA>f5~Q01go$T*3)mvw3*aABZkl!Eho&EEdIaGH5N3 z(vJ`l$H`z>eny-s>MTv89p#%hzY2qgLq5wVe!7mi9b@cIT1=7TU#~fa(#j~e{m-94 zxA3)}{f_mYSxe4MzO5kr-<+nrlU4jd`#`3fbK0AEenFZsAsKL$(QHW#Letfor1p>^ zJFG0IG{=zToOqa=PLM%Rt6+|8lT0Qn0EtqXAU>Xa>2=P%=q!#{x`as3LLeB)6?pN* z7dZChvjIWiEeFY4#n|H_%cKb4x(;@v1ECZzzr2}c^IACXyo*?P?6IEYOVJ>vs8t30 z(#M1{-1A1akH>p^IQ=hm>~Ol7&<&MytX4{bJ4WDZC-K$DFr!#-|KkvVH?BX1`BF1k z>gDnKf57SYy~_6=-M~k_bv6aZaM^=WqH+HY>%dnzC(9go^mIU@PngO6X-H65l@}{hqRPcoy_6MqFf9ztMtE@u;{xvnUQl+ zESgD5u{cc!D>pf1@w>qRO(RmFstGfltH(zkb&zm=Ce3SF4^ymI6qiN)x~P%T7zhZ@ zirFOIYeJzAN*Vf&>$*g2t8&hdqnSih%9y&hQX;kR?o*yfmFqRr?7SY%vo|0?M8K7d zYROH%dIdUd7G8QNJ?(x@{o`()+`JL=US9k1hY&i+;;!R3;VTbP*qJu0XKC(ND7cjd z3!q5`$hcXCmFop^3Y@gdz;Kq8E93O+Npbw~NAtj=f8qmYzMsCnes5jW(%s#|hL;~> z=@F;$$o;#xY+V~g(TD5yA;eKkjLsz%YhzzxFG^{i-L#1f^Zg-g{|lYvbW3 zp5PnbxREEHyn{pM%;Sw6JuF_ekUhyQ#9|#}bh46L1A?^c67&FxIkqGzr*Pe@ndr^P z-)Zt#L{nO$g+${+shkO#^-BuCh?8dh`X~AMuWzmFO%qC!$z-rBiv^38c+F3N-`(*D zpS|jOUV831=C#DUHClyF1i1L)A7k#^cJ8?IP8KX##HiLBf7<(vCA$#3y!8!~((K&% zDs$}y0~RVxN*TQo%1{9<%kuOm3IzlOGxWc@@?4B*O>HgsLjmdt5pQdw^G9g?LG2@u?tK&&8 z^3#0buc0~4ZFdiI^@>jRTMk+)TAUUJ1dQh#dU{@D#5t7%szf@i&>E_=CY?6+v2XVE zqO~Rxu_+dfBZfg=ER>g)DvD62t7sGm63|ZMv4X z9+KsIiMNclXO5qz1#bEuar~JDG;WAsB1v)GhIV(<+ zY$dyOAA`3X!yWgvbCK1L(t8;fEm&Got&@z}Q)o9pt(J`2l2oRf;&-p*s$2H(%RfI2 z#VJE;3HePBTtGnaS*}|g=HG7q5*r8lv8)#Sh3!0h&zT%|_2b}M4C$-u%z>rb^UV77cnEes?jGLLpFuTca#qJfD01@G!O=p0OEgFB3-^jKKTv zdMVkT%rGf5wr%6O#{I(}2-888C20fD^VFZX{F9fmKQ}@yr*RM zG7%@?CMik5d`m*O$QVhYc8sC0pV9uUEDX0YFi-#~DM`(Uc4^dc0@|UL0OR;T8}a0G z8#eH<4}Jj089}&yMo1xqTcHRPGX-Xe7-OzWtEET?jT6lCW^RZ@u@JRN@N!>H-=uJQioMRt}dMFTp$pFfN*UoxNF-8qH_GBm82ODH}; zyWM7{uc-{<@m8dSQqKU3Vlnn76QsU;Hbdv_W8=ntUh50u6g9Ht0LL$F;IyMYfa@k1 zc0=T)kDUxrtpwj#GtT$U`!Lm7F^=>K5U1i)V#!JuUHW` znIqhFB+ov5I|KyReBmfQw`LXt?p{LHp@j6)q?E%oYmVgPt|;sN`5|^}u&Dl&5iU+A z#~&Ojhqn&?p1$t?#8rO1y1xTf>{BhA&|&e{o6f>7C4OxR@4Rj!AT$LLqo5Qv8i@;; zPV&Mf;Xp(x94pRSE)@Exh>Ri+u5mD`@m+m$n^dv?MvbI|bWDkU~=3F zfPg`}T>?ar>x#oxC4C;ej1wQ(tU?H%5#?k4p9y8$#QZ)Vd9Q&91On6{$mbyt zFw>2Ce2ieSQUak6sl7wgThdq%Ynapqp&!>pkBeVolspZdkYrK_CM%Z7nhA}`GVz)k zrLtZ>B&ZRBblQlfD-D+~P^lfl-kDZzB*&Q+L~Ec%=BeWt3PPi_LxYZa`7=->K`EOy z@utzJO36Z$(Mr042is>cRO;irrGB1#ybapYB!p&me~IRH2eJYJE75+>oI9xR4KwD#5hG<*P){$Mgh$q9@~aHJjhcji#wd^G3=a?D6M`q7e3D`@PaQsLm12K#h*d|P z$o==O6-oZ^TLV&}_v~DoI1xh(I4)!;K>t*HG`6=_z_Td#w&CsqmA+=qj3R zo1`+f-E-_9$1Yz^Nd_on2f6l|YZ!K2Iy*bLqh3yYvbsnk0u!ObML+P(jbg=bvm79 z!Gc3M`OIUf)-DlZpp#@U5gp@7RSYT0_3Hs|(k7)Bel9%o1y_^HDQW{#RErQbem^x{ zGZT-;>Dj)GaeUMSB9(hZM2Kd~rb(KK%gU9@Cdq(lm%{mJEWeDlInIO}ge=UlBzyWLeB*ilL!5rW=(q4Q0$NAnlflm$%Qh*s|p{2(-b1ot$t%CnLH2JXR{1 zpsLUm_gg#pfE&ku%n}OQN^IP`fv>GOhP(o$1!KZ!EV9`w9dj1}J{B%JjG;e2%l^De zW@w1ofZ^}?iW;Tz6pI#ZCf^$*jy zXf>0uAd~E&dD8$>_xuZlrx+aA%7n70vm^&}04khGGsZ1UmQV^ZnT$8Krh<5mYK`kE z+S}Xd>FF`4y>_s|x3nyi8b0bZea)85IGPd1!M1HKzWBp@;LLL==_-$MHvO6Fl4h1A zIp8L-q8;drVpLc0!$)7`c1M{sbfl*?-3ykVADp+4Gne?OO$8WtH`5kf&Eo@A%)9Fu zNc#B5(pvuK+$bw@TPQgJtXQ0vk`Di~@eO{cZ6+fYC#T;e=;rvsC5Ny((}yh$lCUvO z%K!i%07*naRJKnEge6G2W_nmgR!q2<sP%>FCVOU0Qqr9Zy6pgmzBOf`Q{Uy`9MWg22t}7KtCNl^z#hiEy zD;Q-Ylf!ijBoYbc#iEp?K|GsV+v)G`H}no^@p@k$E0-+iKq|v7*QFka$D;^fUM$M| zt|jbA7HALC?5mvh8^sr-~N0pJTeBCL?G#!YU$`;0jMP8fFJ&_ooQ3%dib24jB zKbvbV`y@(bS$FBD+4jb3EL(Uen>TOqsCE|BT9L^(GN7a>QF?-1pjw}S2O!gCP5AsZ^gI`|vILH<*Sm`H-OBF4Y zWQ_HykA+$sWcxc_d5)_Na?fIh>y*#S_85N;^y%qDbx{da^a(*7KHQ?BeugN2(l_03 zjL*=AOz(Xj04Pm>;<%XU*d=B(w^QCkq{t*w6-|diQ>PD}tl;tc$0_0~9xU9i)>W11 zM572Ge4wTFteJ~U=qjo)_bva;;vk#iBI6YoGRdfCAwH%|qhqZ2rzaq8HcOq)M>d=F z=z`|+D+4e_WG?_!X;x+$ABY(_8FdH>TC+gAyrh-M#|l|Y=_(`q>D^9OZXVU)I1#ZQ zildONB8WuFcHCSEbO`b;*<1m#8bXp_&?2P@OsE1{nCjouP&tICrAA8PR*--F`q!Cb zN2%6|{{8`)qA`RJ?C$PkcHHL3)yH|kt%_JIN@5_zu0+CXvJ`I4;m1GvA=O$_Drx-w zGJp)ZoI~5vF0bCQD{CVjkCI3vm=%kfrtbd$ZAJ)*lm=Wh0ypR2=3MGS5?M4&=*pEVX^NiY)rwWvc8milhoPYa zW5Bv~pFk;1EEcVN*ONjp>;dYwrx)Ls7+_W`%($KgzRR`kTY++8?Oo-)H(#ak*Sg9J zd^Pzk%5$SDuPxg)fNw0;Rtb=Gvkr%Kb>VXruk|Hph*(6!Haj-IXr?ND!9+n0o_T_e_a>mwJ${^K2i)Xj)l zwbs~njA7UDC{q$AnIPU8Cozz~wv7<2q%}ToYA{uTyoRi>xc&AA;E*-O@hV+y9JhQW zpn+@ef01V|Xyl%Y4AmYx=96JO=x6O${st_D zp&n?FtXB#K6}7sTpML&$Ci*jktr#h{3MDl476>gE*VAL$Vb^S!M;yC~fq?`f)`IlA z1hL2tw9!qL#`Z9e_2;>>7(n zq1ly4A!RMimgPAC>FFj!OgH-a9fh>|AXL4a*jwKC9LK2~z+1L%<(f;bVAb)*apaN5 z)6vnvpmO>8{lDX;AAEy_u^5Bep|v&2IpEfE7-ZSkH6e^E9aee z9`Sgb4_$mQ{rv-#=dO$r*GNIkALh}A{>YUdxs>mH?`Af<{30ukS;i~RJi{1p?U%kp zN5>+@g?SziC=+Tssf{OnDy1k%iQ_u#ODN7dY6a(>doITuvzFOyHoyM$Z@B-#NBQtY zm-27l{yO_8BBjL{AHIZFH^0dHjz5mW4_n4-ukWNO6r!j#PyP9Ej$N^YU;X}%ys&jE zmgVQL#q)Xp+Ozo6pB`cHF=w-Hc#y(@1Nedd{+;yqcQY?$5chEn2eiu^JIuz7o4EXv z3pwh9Q>X`)9(g3YcD>H}jV>o2<>xnd{R!T5fg(Z_&^pcet50OsU3ZYRW7G;kT)9~O zAnbOaDME{I$jz9hytgLhe^M5EtC2GS#{Lvt(Oon{2 zkHcd&C9R3Hx02RHgtXAPDn=2+TB8&*18A*C3~yy5V`y8=mTgc;;NSl3#~e_KL?T5H zO*CqIYucrumdY7oSuqYM<$*4OdP{Q2C7&XZ=%+>+SDe+WPpTBft5+ZE?f+IK?2tl% zlk5(jdVT<3r^FId6tyJh><5M!74tyDVid(fj&beKhL32hoj+t!od1=_p{QwX+sjWb zJB!I3o9Lj8Y_dR8M;G~I-#gH@Op#wr)!V+>a#1~rZ`!K-A6(Tl&O+C9P2=ICqD86E zqB5y7HpW#41twN&O|=k}kVvHz0ndC|%n;budBsz?LC`bSsTMvaMJ>Xk0M&TSOpW(m z$3(I6_Z;j1RwSP{Q;ee46tw|9iyqfsc|mqFwUX7IOWL@Ys<&EuBLvD-G)RdO zwO)~&qr1n@D7U9}a3JqetwDKjAfpvkIn!wEN_5jCE&BQrSk^QOF9Q-ctJpu(O{1sL z(dlV$@qkiTArpT1YIh&8n2i>K!7W>f#ag|lqEumKyqD|mX(W}Iw5DF?0Uugx#$49~!N{E zwkmG2Y{pzOoS45T%MJ}nF|iQu1qyNjD1NI@jdc3H*U4?k!!aOi~mP7p4* zaRQh8g5moe;GiyP;B`63* zGTFx*yQ4B*Y_@E)RuzOqNXY@^QX^|Cjhk)TSV0RXW16#S4Gpn4O1Vr5!MHaOvu&H% zK|cW@P)ZOEhsot~2qCBywY0allgkxQ%B3KTNG>1*u5$59n_(ID!iSPvd-gc9TO0Ay z%wjdd3tonJh>9YS#~I4;Pi)*Qmx8y^R?l+N#OX6nnG%+`R4 zK)%4GS1e)f-YsCoP-+S1u4$xRXBm}}gmMYQ!en%kY8S?Erx8Ud85f#CZ_P?6aT8U{ zl?5i#JgZS37lR za+pn^Mp{fL2gflf*fR^zccU`CyLMom2m#Ok>Gy2hxS8jk+kjG<{XZ@6| z?ovK+<&~A`+oTXQ%NVZfFz#xagHfLP^OJn!>-XLZQQgSD;mWX0jhPD-8+Yv-(qpb>BpjVmi?)W5w=Ey zy!y9?d3pOA{N*oCu<@B^$PDfwxx2_Q%Ma(Gv)3>)K=rx1xm z*q_&&cz7F+KKcl&SFa|MNqTmj8KexF!b_Mfy1RQPC!BCR`Fxhhyg8)PduWY>_|Zj2 z^3u=-G7^|C!58C4e|d$=*MvEce46(~SMa8jK%*J8x_IQVL1p4!66qyHj&+5Hh*B~lc@GuE@f91^Bl}I54 z)W2miULyrHQkrRu(7+U~o5Qxl-uYoB#ErIDbNixxp3(~D#JNKjxly`Ii5#`D7~R4p zZYLq{vU85jSUAY6{+%?7E}l)m`9FLJd@EtWvpj#}$EZ!^fKJBTKIX(**_z0`qwc3{ z$*X4|_IVGL8212+x_8+H#yz0PG&M7t2A{Dz6}mV>@IG@GTYO6sst?lr7&~4)!z!4A zrWt0M;+y8=3m-xhJ^NzMR@g(7t7qK1&ZE}OY&Ir^z~>W4Bt9`kUYQAtPfjt32@DkY z7#A~}CeJe26U$eZ^&?s{>7#PCm9L4s$(5NMY9^f?WL{ev*{pH>Dg$vdLCu-_ZyCwg z+N{Sq?}77-pU9x83bxbQQGm_+VCP0A#rZ~iS`}yU7hVKQ0KE`e0iuJdPp>!AlOw_q z3c;?&*`GSZ7>;<_n;=G?TrQMHy-8U$Rb~R=H#A(c4@<1jG~gwKg_BmufJDj|G9Van zJVOWXa~aDj)8Kmh?l_v}kd2dencWs6ZVMd8WjLpp6^r5KT(n=%AS@FY9J8?z?+NJr zNBXLnYim+W8S@0C7|pp<`%NxNqis`PQk4AQ^Gm9fC6l#g9hiYZ6_#bzlt8d!#||$0*vGl;j@yl^ zmIu1m31dQ`E8(bRN}_4z{hlUeB&{kyqShKqLr3RgUVPzM8olt~*_I7ne#+~8eb}~* zZMU#u#R?AO9A*>tYG`wxQI8%zsuk6Mloqb5aka({+e{Q(?z`=FZocuq*u3*;_AEbx z$9BBQBRjWK5|UN1Mh><8tm<08{IEs$)=h+MiwSArI*NKEf$$WO$n@S?TV1ABNLlgg zo)j>ab2)a!5?Fr-ciz8+A6yACUV~JNnVs~Jm1%ZsMOMVto4EoF(xOfm zsTYDODS6G!GH>1-3Ib|`aR-^z79+K77m@&zK0yF!l4JqLahVj*Btwkn3}s~BP?9mr zqNAgOI-uS=G^)$IPTtu$%CZcXTX|zy*ELv8JRYxnf&WO@>AG&^cgvcUveuJPmXqA^ z2FX;?Y|4I#n{$!gL)6#T$2k{%5K${|G7e3a#jD*r7|FQUVTQ6ZJ z1oo#O5)AUlU;oORy?rcQx|HoZc5vFMC*U{^8#ernS2k|p)HC1Df_MkLZjyQ{Y&^cb zq}ScalF6JIitw#duDW$LIB1#^@}ihO7799ncUcxYQLH^7b^eaw!pV9<4Fl!7+PBA+ylT2e}s zRtV4PG9Hh6sEMY-in7n$L}b+}PW;-lY<}9fl+j$v5l0-w;?;*Ur3&1!r3ZGpkPVS} zvOx1a|4r{7KFi{EO|qwl3FR_7-a*c*7;HO6HlZqOep1Y&hD;|UzZdFdC@WVUGky3gjTQ<=xk!nZj4KF6Lfm}wP2Bs-Us95ShOnP>Umt;h zpvfjrif>i$B8Z)kks2@>SGn z1vmYW>u0~>*ZvSa$9z#&eD?x= ze$_qv^m~dC-)UTUVi#-eC{rRxmEY#aTWk4`TOI@gEI6@)H^OmdyM?#uMczw;^1pR8 z+BSJar2U`Z2V`ck(UkA^G=gn01P*Vyr(%NyT5i{z&L@cSpBxeh{U2D3?M zISHI9()kzQy%61-9_%~o()Ag!xtv|33yDH?>21}WH+OwrM?h}m)R zwxV)EDRw0WsMa8*pK5IyV#~4-qPCLqULz$!NGwY*8_kiH#Y;4R%455Vdh$4l6iutT z_|p?F8A_k!XBdCBMI;5(p=K~@<&EC2J3MV>g=T%cMhCRC|{_Ky?|B`OdI9HhY%Vp^3TS+2}{{2 ztXgX(yvC<2s-JFrd`t?DdgOgxW$nO((g@4^+qicX357zq*({MrgtX((($YdYoyNAU zgBuF||(7P4fxmYm=|kh#m>`$h={i0NHVJxrLV@^DlqhCCM z#qF*14y2fwS%lIDO~UIA+OLgsS5cSD-`pB!%a-j-3V|KAX!IGtPI@(NKCg(j#fis_ zvst~@jK`v3TqlEV2fYSeQ7mdE3k8Ib3_D5UtwxtL?79qQTpEPtu&#E#bj`;(kSS1a zDL#7Y96oi?HH~Qj4GHE(m0((!v_IqwRmIB8YwD5W*;!- zIvmoz2#P<1dB-v5`a5{-yJukaLrm6F74|cxTlwME{k-(E|AaNi@$nN6VJz8CtuP|I z0*2-TK86MdS)%idYC*)d>1ef)#bpe2C(Oe4EDOuj5zDf%EQ|g5ylEzck3q*F6tai} z4aFoBGD4)Xxa^&&3Bo%p%;HNX4Qjc4dp}?M+Sj<_j@$n(tz{-Z^rrv(Pg-IvTzKI} z(Av-R(*^C!1c7h6iTwi&_UxdBX&pWDsUug~IjVR7iX?T~(s zhd;ZJvzFIDF2!SCJdCwJ+QaS7I$U@0VZ7Wk0r>z6j?lbuSqLt>h^mi12zi%Vp7=E3 zfecH6wLJFKb*%l|P4tF<3w&%Sg`o&bkBIYy)$_UZn-9Uf6`cRw=ONO?bte~D+!bZ% zlG%(EU`h^9Q}($p6gd8(!?r`wC>c8L`$e z?t*MJspcCL;3h#;u`JffCm!vANQ}c4=L!2Y^lxCoA2r&RIg&poeH;)W$os$!GUwBe zn2ARVy#Ce0u&gP%x|TAI#jKbhncPmqj#IBgSoT!K5oS`rpp#^d9b-%>MzvxB!T9p! zSU3C}UVk5Gmz%$P2i%Y`zgNyk~e>10Femfj_I-M6j%WL-? zhrhLzT)&I!CYcmAj$1{w<@acFZlz$EtS}T!m{gs9_hv;1K}$Hu{ME7R?=g}7e>-1g zR7)~i(gEyC4M27~SPu7Ie+V7zVIn!3LSi@9{b3XL4Mo`XlEd$IjBt8ake^-FO7DsV z#8Ugo`4{r-N4i1SF!&;0{QUKd>IAV|1kk*)aT5(f(hxHZNYcq5gd~+r($&?DUu!0m z>$w-EsJDWQ>JqJ%nF?2H5SGLef+nwVPCABSSvCWa(!x~^wq-HmI40~+DL%8Jlb7y) z0fw^_ue*r)Tnc+hlx_`={do*RotzpP!mkyN4m7atTaUoJ7#tVoy7LxO5FnzfnNS4^ zIhP4-Gf@!C)9!nw>NN>CAObVoyr!tr;_psVW}ame+UQGlC6KUK(QTCNPqinGH;sj^ zG!4~WQzN~mqk#afb`f&w9fF*TjC&Trz|j6`Jn&0Oi9*pR1j=&{s|f^*#w--V%?=Zt z*Frv@uZZhs>Q4^N855NAt%R5|*7h@^3&uSIq1k>f6i-+cW1$`Yeg(D4r66oNwL?lS zCZz-+U1CYBmYnOd+nJATpTQeK(<=RC*vXhQD^M7huLF*Q(j}U$Fq2}6aljG=SX|H= z=hj<)!|xyX15jk%>}FQ2Iud~2{`NN7W_O?i@bCYA6GDK>n})}A99-A&!Z2NC$77s* z>RPI5OpxapXPnNWd2PJ#=Lh-C-M?jiM;FJOcq0FN%|Fo~Ot@mR6|3Zey_FI3kDEOG z4ttEkl0g)O${Fb9%(MQn4<5_HWgYAu?&s(w3u#?2pWpxf4R-eQQz*jcuDpSjD^0UD zk~dmVpASZg)7p>i+qZN5S3XNagT<^_O`NdiBnF4lj1Ono^yY3l=g;S=E3f8=rAyGN zz?cgY0xT;?GU;&RcfZB9o_>@nAjA~59h;_R&j1?7XHYQ#3Ry)kGLK9q$AVZK#~Grd zBMt~=$J@|4PlE_hZ&}3S9TkZ}Vjw}iH#x4O7Oe|33c;u?@O)r3Y1BqD^4#Hr2==}@JZHP@g!s;9D3m+uqyIFiU0s007*naRG`a* zw75yw8=(E<De92b4>_W#KqEwASp{v5j??U4{>7#zRUm$BvQG zedP0sF;9ok(qdy-5iBc0ARyV(yO*xTi|Om_rAdbH`z1pe!)wpwatHD3-f2@VBSdBD zm6Vd!)>drW=6%PW@OLR+(;c@&`X!wmi?Kqo;=EKYcHXVgFeA5VF8|vdzTQntYO_HpE5Zvz#7bUBPC%%GbL==MA8mf)zScgJ<+|&>%+iIOeDjLJpKX1kTWsR2IonSbK5=Y5pH{tQGU9MMJdRri`nQ??gE zG0&>G140hX5$-LDp~1Fm#!qrFAv^x)xL(ii&O6JhDAwK36s5p;K)j{Ty=E z&v|71_nD*msd9Q~i$w`oHcDwGynr#K6m`;~4q;q7v^j_@%OWe%eD$72cwrt4Kfv%y z*CU^PnzeQ9eEci3IY-BN^T8y~MLMan7twXnC+UCw)3l#<6D(NGppDrs%f2~URD|?po!9t#D08Yc?Cc+)ulE&3GbLW%+G8{$(HLD_T|CqK zG^xVtJn@H@IqIlm7)B7xI>wHYf|4eQ;nKoH2|3EB}Sjr~k;Iu`UMxL6h>DF_mMF)lX|Y%YXmyL)>@aBQU3fyZTa`xoQFDUwi~p{dw$F%h?u<^6fj< zL)zi@U%#5U3aVOoe(|jj;q>>==t8UV(I<-UfG`^|{kt_GlVX}y@{gU{M8zJs&L?Q}`6?O; z#0+B&F~j_(SOjSV_VvPmq{7P~DNkM|-a#WborO{kxbxvdkf(Hze#K-%LD3U3*T^Z) z8EQHsrCL|fAdIE(q(`L*`F!5gwuF$zX1L)k8kKqhV_wl-_ZAvk-3(``vWr)BvB;bG zL1qO4WQH8VEjC)`fp-HrH6SbW^0K{dxn41!yW-8f0=Ehx7NtyqxxoO9XwqRn+jT38 za|3j?*RoGbuHKO1Z`~O#UfRkf?X@g$vt)WQMmsPEYQ2VORFyz@ZmU|OQ~{+6xH%V5 zYczfxvYkgCxPu3NbsJAU`#9CbJb9I6@18wed*#P*(rGsCNmBp}LG!+kX1}MY7;zk8 zEr!n4^iS@e!I)Vq~c~rO{h|(My%E#Y6YTJFsI=#E%fk zG8WD2q*%-&rNyL2NiRFrmFvW0GJ%wWczhlwowSO~;1J{KL7LG-k6gf-51vYD?+`(6 z->9Ps%kq1+!x||CTerSOEEcUu9rO%KZj*U)Fr`gOKMg{9>(fU%?a+`+Aw&RO(x`&t zy=SPgWTja%k~A|F8c7eCP{+1T8p1YOSD}<5=w+n|F>SulAOt?wWz2POyeW82D|TlJ zv|2u@b0r$3O&ywoa%hq^Ka_rrkV8n6g-nkR4VM3+p z=;$CCjo~7Umn*eWgMv`bX1{WGcyp7koqL%{jfLez#0<{oOqY~*yGDqUk&2Q^Ggp^5t)tP{BDoU(EyKVNgcPVw*4_9d zb8kJ4F}sV?uh|A@Vx1k-ssx`{73J!{o2-8^MU_*6o!el+NsvxrU-~#dy7?@!JKp4m zJI7#HbLxsw-jtoh3kN_8{@4;^0*yP6;qH%|#yuCV;;z0b);$-6haQD|8w@8IPHd;a zp2ANj{r&rS|NBp4pm!%X-E@;d5IqELU|@hTH_e19Fp_a_GMZCXpTw8H{CWQ8mRra; z4u>sY!br{`mCVr9)xlL)T}q)~kgBnqVxV^~M=pzT#L_MnbuFSXXrs|Q{q)m3{?NTV z_uR9f6*W>a>=uj|4b8%MoRs4jo_jAK&V%O%V4gC;gG%zzHqD)1ID&!_oU*)@Z>pUT ziZkb$2jTd0O`bs{4q7rtC;uPr-ZZ?e>RkK($<~tXEk|3nw+Gp=oY+q6kO?P{5W*1V zGD8^(f^>}|yf>2R+8-|KzPt8ejj#om(kUTZzibKk$46>^C6u|6(bR>I?#ok+sx zW7<`}geA9g#&v(D`=JZ*sSY%$NTD$R` zNP2ko@muJAv;6h zN4fXjdmRbXz5qm&?JpTeBOZrX%wqHA&7@-e4${=m8*jWqcmE*s7c3?iY^6{Wl%bPw zWE&|ZDbo!Kl!j$Z;L+U-hr{%A_c7SkPpU_eR!OIu>m?_ual1>zT#{SOh5 z-59zL%Sxf^B}8P3M#G>dY-8Np-+zyf-+qhXWRhoIc!pX2nXG>B*L?ZBi|F6Dn=$bk zD=!=8@-HlAV#72>%`OH4^(+RCX#(`Uf1yFmR){hzc0p)R4uFzK^4$%+29UbkPd^_&r=(F`SZ;XH`l3tR%w730;O>KDlkIl$;M zH;|4`P_yc%;5{0&CT@7KgBu=tmE1#TkYLPiXeg7!&=5t~5fygR#6A~FD^8j2%lnrS z6ZXCutoHKLyS_uqj5_AbX=WTZ#~yJ4U0uD*ZfM|@jUQ816R-;v6q+}{G$Gj8*+rl> zfbJJaY2on*EUTZZS6zxxp;1Jd_V!K0F$jgW6N^Rj->a08)|M7B^518B*i#BOS#p#L z`#uiG!*&BPDXA#!qqFmQ9)0Q#o_zEniuD$P!3KuICQq(@0e|HRteD+UomQz+j9@%z zB0M@OX+P^@%5=W7B+Cz9h^7f<1RBu&8e0ZTBJ7_zq?8NgknReU!Z0eFtU*0rtQJj0 zgimQM6(JCsKS>6fR%mj^TexP3~Iax|6=y1|H)M5OKQD3D%ukz}diBlhzP z*}8QnJ9g}(CmaSm9Cg&;1cPpp9eoUIb0|0z)_08`VC~A z4s>Sf94xQLwMkK9mSt}a3NlJjrTfT8MOcRaZYSfw8p1Tgf5&^G{)q-s96*Z-m0mTko1;05RfWpM0gw>uaI6O!=GWksZi0u+f7etu~U z*WA4kl4k%ZNWKZG0T5jOg_po{6ljtY=WgTF<)=_?b+OTB_i*Y>7fB7WBFdh44VXim z)RLvIMW=k#CB(bCDNwcOx=z1R#DvL^CQ-`Xpq_c*dFmPiC0y=AAoEWZ8edZsWSwMnF~CL50y;G;NG;tenZ0R~5XWZKll{J z=iUM>Mm#=&U)R_pB@rno6B>SHp@cn^D|L$KG0Vy?S~WER&Ue?$Agb&xNgmxT>I5S*d=SJ zuTS%F-wtA-6oyexnI@g?r(|48Csa_&kIyGj&tgh`&1BeF5durv3+R|-Q}t|Ff<~b* zh^jh@5cvE#Dm+yLft=XO2RplIYP^F1B{7_gpriidWPbIB2O#0XjfV{5gm!Glm4o~5 z{~pVa{~ReP7{{Vi2+Fh?hEyC+Ns@S6B2+!|7N1F^cO62EQb7<%;!>TcssKf8^XLS8 zQcKB9dwXrCdbh1dV}u!r?yZjU2r)%^@eB%k=l&ra~mB5TlHGJ*2$V6o?Qj zzxX5Gk4%u$bChWYC8kCZUi<;c$fDUSGEHjH*k+~})&eAyq()EUmr3XFsgu+!5=v36 zT9Go2KbXceEvi)|abhGjMOxGGSoYLUN)wl^4(en0CrXR`UN$b8d>4G`raKOF3XR!9 z&?7a9@j=pr8S|NTyP-BCUq`z+hdR#yk{XaOD zk#Gl^)mnh>h2X7?n|b=> zmkEV-uxZol$W+8ZC`(E;gJNF=QaV9?0voR_1Sz2?78+?&;X|XWLa;X#VpKCwvY)bf zioVWEh;H6PM@Nc1QIqo*`Iymm4j&14Us)U`a^xO9i)b*%b`(`+GcCN!OD(M|>n@{M zKZ3r#ZakuvZexI>cD%+$G5I`eWE@j;R^;$0JE=n|3BpThY=jX7K0woK%x^|{DH6$p zqWtYfq@-Ba*}i={MS$DMDJk;$QA*+Qc=CrUkH<7$s`_+Cy!rFN{Qy3>`JSA(K^}DpPJF;mWp;wu|z2j6&hhFN$F52Y*TejeGT_A z2wDU%K~(bOYsK97%LFtSAk$=pMbWPYpz=bHVM>}iNqLj7O~Z9ZC*5CO4AB>$GJwn1 zNKEySQ4)bhp$0hEUZrg5PeMtme6|@plumQnsb@20MfviLx6$3*K@o7l=PDSATio}; z`;1wVaxFkKYEtZ1j1eQ);G@{_2I;y%T4gx?_)oF)#M5~7)mNygsik>QE%TQz;rbhH zVMfCtPR3u30%f7lDNwHb>XQ}!+QPGc@vR(ilgiWR#-&8}>G?C7XZm!inh#~1N){aT z>HP1oydgAi6*6fTqr>4aGASwc>h`milz6?9ldv?A$S^exbNR}xH}l++&*JtOq=n$~ zXPwVocm3Ka2sN@ykWf(!Baq*F$0vPblgc1xe@@8Bdq=lnHqIe`+$rS!Gv@N{Yj3mU z=wlcThY1FQBnM1JCp|}wIXVMfLXweD)L@h-8qzD!q#&8pY|6xZ+w@xK zkP-@P*i>G^_OFuk+yQF7CU}!@0r3 z_!ONCwKOulQ4xFMTt4XQV|e{qj{n@Hlz-!C@a$l&zKplt8s%pjI{DSL&6G#hQ)3*@ z_L3&3%)!q0DZ*`o7li$+*$a*3^cANrwqlB$z|Gn>HiEy2uUuBnX$w!`{YSsRN1b6t zd6#-)HaiER96Dz{U7bC+E2pE>Fozs+2*3E@xB2d^zv98w@4`o6a_+;(iWoyf3QaTc zX?7>8P!o=xTiAY>DV{1#vlo`^6wP#=Y~)aRW*ANE3Ux6f5VXg~&L(YHii^*=nDyHp zp{CN!$GdhjYt}q^dt-d+bN`EqmKJ&h>^3`?u3GrX51!}vk56WF^WVskW?Eq>@w5Wh zI5*t>JXQ5}eoBL8;1+^VXb;7DjxmSCXIXGaQw!T_XX1(NA&VXKRwQbe?rlSc{j|3E z7?u{}Dh%ijMJAj#1q#FN2$c$*<%gZcw%2#y^?E2lF;0R#gE3As=2KSUV_Yfrm?4@Q zFJbG94DdIyrBFo)C1ut0?j6BbHJ|zOS1@L!C{QlC`r5hp;>&sE$%m-+``HuSOI+dF43G@R=?QmJqQJ7;jLHqzEJ$ogkB{V>s-l zO1IIF1p^A*edxMi zPKBE?Z5O*(L11DCmmZ_2zL7HNCLWJaXL{JGuK@YhKD4c-kyXkGf150(atM(|3h-)n zqPI=*N+X2Jfp4&1K{~m|XRy5)LI}pBq9E^U-`9v6vn*TTkWMr1@lZOcsrPssnT^UP z#urSHkxfnz5)Ke&XkcJU%DjgQKl5pV^)+;L_YthGaq=hv?C5B>P2P>In5Ic66yl|q zUb2f2$HZP+Tg#0%-pHF9-{SZ8KVf;oA~wdjhdq~h!6HS+z77V=0(H!E+wJGkeb5P$va^H_r;cmymxc{!I{@z#eR)qpr}Nn2#vxC=ld@a&aMx*^c*0p2 zl?G*+&aO~5fq-v6>wuj~ujQp>Q#1UOIX$S^clYAw=Mu)>D<3M@9E`s{a zFwJ_vF1n?lo=Q@^CSKtoCm|k=v-r5*aG{%AIU=xW%+BO_Tql{w*bnUSu$)v^N#jPBs4yqVLM&%?t2!;wzf+FEIAYa?gb8?L$h$GrZXFVSY$`bQHt4YOx+-#x$Kvdb>B54nXdGMOAMmy3Jvy_Yp>UgDNJ zZ$>G&_=?}qx2K(NV2zvHXIkN#Dkeggs#J+p5=DDKOc!+ZevA*mE1|!VXk1dLNk%MXVPKBjTuJnnk% zF|N3~om0O2dH!(qVGInx;Y+^+!wRxlvg8=eCUMb3PIPnJXMRpp_4Dz2-=(j6h-y_& zV`B|>-Sr)AyX{AGo1^Rwk8{-`w?q@#5-9P^i zLR)uGC^Uw{af)?Y&besmV($E}yE*#wm7H<(+03uWarRO37)iQtdq)^&l)Ab`zVPMS zNTxk}xb;4QEhQ|P^Fv#D=_(_Uh>-Q9G5aJFs*Jba*vVmsp2N#8JOSurg-%9-*Xtz~ z>tpe(`SkYmQ(acWa5&8D`HScY_1O{>)8eGlk6|^zFe?B6AOJ~3K~(+vZOjU`aPG0^ zFn2~7XSCIlQ#sN~QJD7N_cwCIXTQa?)I&>%|hiLca_Ef z!_ZM`0FTcNgC+>U(?7kEd3v19U2!hFePz;GAmNFR^N&5O4*cHg^52NWcMTLcAGg*pV1*9_yPl*dqWSj%>#y8he zS*hpu#_sMu3`1x0=FL=8RM6es?OeB_K-%f$B?5|sMI1#+7-$uZELD(2lBlWosu!PD$yT$1yC2xX!>1Q8J1|72)F^v-H`(n8@Cbs( z74u?ifEjW#yPb6OzvqdxC#RAj6{Xl~AJ~ja16MT72&sK?YH@I{O2SEhx133^$Kyez z)8KeLM$>ka5=R0y_26sEO~rnDvT*RK{)EXI{rUddS(oXz=Xo<~DN1AAjp2Ao3Z zgcD9+-MV%B=ArvI`sibb^bSyfXCJ;+k*BClH8CHEQ68Tnjg_$&3MZJ?o^75lIXfd-1+?FWJ5s-2i2U;hYD7Bz3gn? z#FI}v$?qP00GG={E;j*p{}f6qx$)L3Db(C3OHx{)p_Cw-QXn)+N(8#wWJF3z^fKOi z??YaHeJzl~<0-}GDdo4n`aR$K&Rq;AW9Yg;I2^$+?115LI6|>rGG+Ru_WKo015i zx}kyIox3TRIi1&^c*2HPlzCbA&g%eNcF`*K_J$dsH;>lVM#AARN?B-{fzTWRrvrtW z^uAb@#4yAGa>2O*g?VxC6P)p21KN3OCvQu)eQlxuSSXAPy72@c;T79^1EOEmOnlHG`k0S zKXJoNE_em%|Ait2hBcj(&}h~xXi}15y@X8_Eqtb{0@nqP;JxN=9QDH<=FKaipkph! zc$}^hAFiw3<-dOO3eRpyF%6A^a2&1XDD)dPp`Y^{{;Qs2_7C4BQZb+YNSx`K$+tVo zC_eo;=uELOlA>s62N})aks)wh^)zkQuI2deZ^F3#k5nvKL9rRa*Ve}AcfG?kH~tO! zYe}0fip&s7ne>Vj4?g%PZm)*RRY-Yx4cV-{ndNdhjyvvTZn*hows%K}MB=>k{2K1O z<2G_>3y-G^uUDtGyc&Qbk35o8Hp_>M2O?!pdc-uCB-Dsis`7CZiNC3VIBYz>Sf**%r3Dr;Gr*`#&je%UwbTwD8IPxV-`G9jsN%KyzoXGyuI9Y<*6u@ zniBk}@>=z*5L1%i_b;}`^C673;k}|13e*TuYcEpT!Azs(AZ~9dfxz^9)4-(?q+%gT zl&#sPZXV%q93hf5b0!x@d&3k5EQ)pz-sB;uSl2O(3Upl~ zICn0G%w5F5z#c~A2(xC*CasdpojaG)Rvg2zt@DUFp0A6}ITK3#xV>J=${?4^QBmpz zmE+76^SSl9D=9*wt|GvQ9A;?9YV@SW4Pdw(-?^iF^;{4>3Yryv?=j7&ARO-F$3MNDswzK&u^3x-?q+as zgx&qSiNzGZdH6^C@sT@_QV|ZDOf%dl6{ja0$LDl|;|NBiImHC2*&SknlQ-s7TQ~%r7KTQdW6@g;Trh@Iu@aB=Im730o zbdh!2ht#QP;C}?un2ZU?dhB&#Y>I~7<4jHpy&`XtSIRb+AIzd@uYu`L0Bx*T48Max z-xKX8)Yrx8C!SzLTC}##Cm3v^becpy$dRfoT)2?cFR!tY z!Ip(gCMi%*X&6-Lm3C_|7NZCcUa#gD;y(!_IPiQi`8OsDu*r#veMqciZ!Ct}YiCvL zjYX%Vf~zT$#ZP)(g%D)&Uf9XCnEXU#w@;%_V9St&!WVbhCVizd*H?q5BF*Y{CwX3k zsHxR0-bXeXD79Bj>jd|Anfm>0~nYQ&Q$Fq0m)GCI?^n z>UGRtu!u5EN4Pc0N_2!eJ^y&YyvT5?#vj=HdO>F=aWRxVKlI#tIP)gC%G}8$kGf`@SDm{Q@ z*|<+#4`7;-P$-t- z#He!F>7C8Zj7UXILy(3Uwba(u($mx9NPA9V^X5%_>-y^m_w@YBw1)$)@qfx|+>zr9 zhr3CeT~yUKar9#!@yvZ6*tr0zmAAHcv+$hXAzJ2f#B0MepC7WdaLF)7FKR?73vbI3 zf|oxBJM(d*1SWKEdBo!o7l1klAIJ}3Z zrr8V(gm7zKO8hlsg=UZQlX1#4%|Ti^L>(!eXISJrqm$ulrTM9eW2|*FuTwYU$=8T9 z$qMBxqLPfX7_`Ea2THi>CpYoxhdUXil$0oSNFyV(XgQww`RBQ0c{%QshYB~WyyQ@V zo%RGA7A`!L z1q%;l9B4jrE{m2ONmB0Q7x#aWSwS~a!l>zC)U+o9Wtzc`9o@F92t^SwPCUJhOIDu3 zv1c8|Wmlig{KF5Yde&09_w;l6>GL>Yc{P^Rg{}uF=1r2x_kdAkI!iKRBU8yG$Ru|% zI@HcM5j4$4AFo-nhSo!ua{bMB@YV;Nd~ww^9MZOkjc>j|v9AQvj8LEyyLWUr(uO!n zSsXUMmH)iyE1Z1RS^W07zw%$dyoc}Ic{{bWGl(SLp{hRRKoKfY$|Ru%DAVR3r6isw zcqyhC0dhtwX+7wK)4_;?r5B=vR7E2>qY0&41n149UiUFw7Z?bpIRqjf9yDputfl|A zuYW!#s5cM@Vp)Ll02+OL_Jp#dW0=bu3pw#fH~0lN-uFC%G*BU$5PgDM*6p;r$qVKq zgd!#_`~3<*setRQyN-c@0c1+D_O;jWRoaKu%IbQm>ZX$`^io|@PC5BzoOIB!9=>ZZ-(b3WEOjJ6sEISWJO38>cnauRF4-o<(3{2C*Pj7yJ_qw`yW_2H| z_Q2`_{`^!o^qMd$2)lN`QxiP!>)q_`7^2AX(sJ1^!JmePZCrfOGEVvST4+9w#j^y@ ze|I5|{I3}xLr{4X$N%c1{PTU_-lx=rQxMqAhkCC@u@DT0Elg86nI_)+GhcL&X5i#O zW9k90=zzm~LHZvZ6!#qti`aLaQ}^-8%1Q6_eW~25 z5gr(r685O36fOJyp4}``6y^i_M!@CT{D_P>8|fFMkYm zt#CpXi3v41Hfb|gi<{IfOrd5r%PFUr9h=?9yx2;t6uk44VEmo8aCV8#pz z3++#RB$>1|iooo7Z3Jop_IEX*@?pYu0VbSC44ZO$_4U_NUS2~kmqQ3IMrk>FN1{;Z zV&%#!oUA2{rlywsy)fA*9G~K20`gdW)3oyM%YIHpUV=C&4fA;*(zBD@yFX@VU?=hD z0DHQ&)7!p@-P^Yi?J^NkP^L5r!xnX-k`e`;n4)0FMZ9YV&3>Iyk*2?E3#Y6&oavQ* zJ7-ARO&-g#{f%Xs4XGKJ64w2%G&&Bvr>9Ck^U|+EA($0xrr4?Q$E`S{md()Cv=T;5 z%SjZs9~?VCQRGwF|6avC*%1~(qg<5W6N1jpPPT4(n^?@Qyk^f|KvuU+S*L#LR0@>B zG@}?sEm@BsJP_vSqnBbvEh-J2)lWRZAOH9}8tbO>(qEon!Hil8CKQ?d9`vbn67_Fu zsQ*vDW(vW8vZx6dlu9={BQE&cW=QHRUpCG~b8=k$8-p!c0R5^?kV7y-K~I=Besm;< zG!-)8PV#8C##mB-+|Df*wUMcx%N;*|7Pe_rU1<}-NJcq2*Uw*`zntyyIE}=4>9uZK zzq)G!Z~yu;yc3?_x*xv{174~w`7@~FA^99vHVp8ypI<|dO3@(&sv|;BNj|m|RnF$0 z&Lr^^+96vWkB6b52$qCBW;elLBcV_q?d|PAmc4uX@D%27Ww1M(N-+|NFltJs8396l zeJEuStg7Ulp6x&u!{eo^XQ!>*kH_r=Ln;I%?ClGKVL!}%p|ijTPu_JoZAOGqU~9OF z3Xw)fXG6Eim1iHy4;H2PNIROi9^=f$LDH|E&dZxep}U*omp7p519W%C=_E*F-vlqN zT*mqfX0luAd_)Jah@?UveDFmYhta zyN~zRKhE~;VIIEcx17E5JoJ(pk`r-GIQg^v zXZsdzz4cC_ae+cntoevr7X7A4v93{|(!9Q59ROeY@--xtm#m1=-xX(Dw3o;JbT>yW zKbL7nJtK0$CcOv?lpq*vVI0YzwSy{MXV=ybc=z44eDV5oC{c>D&pww}Dvm$c%x&NL z3cvirJs5@$t;EgE=bXe_Th?*?;8rd=?HopmPV$d4k&bxlWNoSmkTWC}V>nTDIRud$Yo!T4>*6`k2ukps} z)m(AOg}l0PGp#L6cnlv47A)YeTVCMwi&s#s)eIVhXk4yplGO@CvR;=Kc^i; zfFrJYm%ZOP419{tE*B&xIH$Rh-iV#lo)waDk>kCtSNQr(HzB2>eajA7=gi^88^6uw zZJpe3!#C+4GO6+ztXcC2!^uIW89J+0T}!F()8F4iV1}J8ZdBAbsnQC=u)B<=X*%y+ z%cnVOx(-q?W=bxIS*nS*SSy~KO{aL7`w38widJj4ZUg+x-d zz%r1Xj6L!hJXQ*JDVSyP`d62c@Ff|ioE^b4X}xzFY%@`+Za?zmBu06hoD)hYFo%Zd ziXAR3Kw-gy_ZZrys0KKcY+ebb({ z>V7{`N{&DNcrLy4QoeHa)%K09UdXA(dv{QgSz#-jNB8Un$Py^x=S>9bn;4OH-iD?LC%Z3)lC}@02*JDWZl<(UC!J1{PFv(kJ&?vh(F?-i2u)2k zWTZ;3Kfod z-LTKO?tQ-_4@}YogO*7Vg0Aj9d{us;(Y>V835L=x3S0${$qJ4cFI;WYAElG|z;z)k=tA|8MIT%XufBtK4 zD1r$37)3FrU=Ym?Z>ti#y6O;$HHemExa~*%Fhjtu5BSWHOZn~3FGN!zQt=ccTAGk5 zh5j(JRs{L(S*2Jq!5v4mz`I2t(lGEY4}Ej8!4)31YDG92J`BDluihK@T2ch=<-mmmyxta z7`CFMGZ`u>Di9Tdh!7-{1+zUu#n11gR+_$5^5;Fu(Y(yV{mXc zpqS=ykx&Vyi2}wlP+L(!LMbBB!YecqN>Ec%!TRSn^YVrds1Evgp=*dWu_%V9W!Z%n zP}h`Wr@0Al;Ana}Qhe~x_vx*j!(&2lG+xHd7s$1i@b!yNBh%5vhqSSX&18ka451U> z+C_ySsL~)F9zq3Y;!X|O@{&LRO@nbo-jsWAo$US-l`kIA$bC$(_^RjF^xk`%?sD6)ihY!u0z_P}v5FTKhmfCt^R*dK0euW>tHqM2=-({QikJUja3Y1O(784rIsMbDk z6bXTyJ!fn1(Nw-*5>qI61&U8hRmS2eM$Hs8LECsK9Zh*wXq<7z$^7ZQ@A1Zlc6RI- zV^*-0iq^w;^-s5R`z2pPX^@LdP*LxLES!1f(R}XwFEbIJASEPA+$*SDrE%tI7gHW+ zCgpg0+)B%v{juz8(kpDDoJ_j7`&W-q9%!bvwV0eW!KSx2bNS^rIJCG3LP&bTL(B-& zH~@e+#kw0!v%5eQ6+sHMI@YY&KwI-d)~xw0bC%Zg;r91A{P1PWtZ1aOuLE}l)Kr)A z^utfHdi6_=hS<%hIYdoOJ!>y}ol+-ouFj|+7z{FzNYK?4V(#KaRQc>puB$7=k|jrx zO4*)(uo6roTb<(fvJrt#Vb?aY}ohwa^AYAXy((_-O*BhfU2U7NR3XEfr| zeJBMnWuj|#aA(dkDc5!G*%0B$Cp%z9j@ynsfnrlqjE{usX2go~>^*PstY2{TNwc~0 zp-1UVF0-kENeSM79ct>$L3#_dfs0w9{d?=%{;AvtGgbnD3Ze|)w}xPFlYL$sI)*sl zmnOqNI?~7eUptp8uelSoQ8Dn1S(J%Eh;E0T5I42m0%Y+ZDNvH#%FR3L*YV1Rt@H^m zC!T&f-Q9hh_t}eCddx9Iq+~?eQ@7dkkKhk~xQE+r`#!gR^Sf;8>SFGqHoCeyD6J@= zuWyJVr_(v9ZMO~SP$q&zr0Mw5Bn84wcW%&q{O0?oQ2zw{;;E;h)&K_i{k6y7S1|3I zpMj?Hvs;_lW0j)%Hjoi5_7j=b7)Pft1ylu~H$|q#&2aY)vZ9vanid$CfJ);4Im}dP zk#yD=3zv#f?-x|2?PqGjlg6zS1@fQsUxlzqUz2iCl?LJQ=JP{5PN%m(Ic9s$zC-!c zaJs29!K~BF0mvj3!ee)n3zXf>*EHc2D}KlCYIksj5HvN_(-ZEcC)}GywN74VI2`6% z-})9m{?U(Ec<7;Q{OCPC^{G?o?d_$twUvABxrfiMTFGlKuBF)Tb!35J%7JR~4eXC| zE;vYmt)>L=$z%+_-%lzQBO{bE#o6cm-6ua1Qz8%c9R`bZCq(oBTIgixZ6v-Il7OnD zD<0;ylj}M4(GOuD3jPM@9O9Jd&zKpEaev=;`TmQQpj$Aoo+ocQm%?zjO=a>2h@~bd zoILDG@CitW1Jln1O4!#or@4Z@ZGvc-hje0uiOew5gop6(2su|NMqMpgp~#9fns75_ zIa5Vv4KHve_X*{uy1I;=JNHspn8PU5Nv9LG+)C5=Xh#PD2k))xK4-EpM4=N_Ii8o? z{quwH-}i;uKB%lv6e&Sgpb5(|2?Q$GI~a2$WOk8~$z=eTH?NVA$ONW2L{_C86tRJliV;Vqxv$xv z5eNimZ{Ny{Kn=yZ?htPe^q>jKG#}5s`nEkC92#Q8xqmWJF=)jJN5Twke*&eF6sRQ8 z8In@rLHAcv-!vOd)9^K&MKIVzeN8=RvIg8rgkXQMX_GOG`$4NA$jmG z6e&_lMj}I8v2rCF-*}yd8MXZR_YdLq+NQhIU>_;rAv>~{;bfA|tsjsTf`*nBA|r!r z-L!@J`f9AbNfs?$%*n?d%dOX6&kyeSPCl_U^LHd&O7U-Vw*ODRs)H?b5k^XjdAiP^ zg{?u=4T?1wh^HvV58fzzxQW&Oc_L>lDuzfmf7W$QvdYj!lw3Fjvjglx10~QWJbXnD z@(X<{^jcW=d#*4 z$I#GH$3$|34eK{iQ&Yu-C!fOQmtW43qmSXdRTnX^F-{<0;G%?!Pd|a)_MO~&@2wnj z%n8g~ay}<(X|7y#H^q1Sh*4#tb@g%goeyx*VF?Caf0wzl#);s;^w%`ngHrL)w#{7gpWh=6 zJiGcWpo#M?TTC|6&NQ0I3X3EXKe}y;mKH+S(S$~UvOB+G$|6%L1PQfoL(YnQ1R(oo zf?%+Q(~dub1xprk@4ernyStkr>~OD{wY7A1cCuk0gx|k|zQOgh9=_uL`7-&nn_7gl9aTir9goeDIf@lauoy-4xk8#dK7PuiVsIc6yOeSr)o%8&Duk(Ax7q3_C zB{Q@4+G~Bk-_MPdDiRffIpsH+hEhQA!p3K4Yg@#)g1jj5(AryBcI2h(auiv5(KRjM|6=*JRW6A)$mGBFUK5lGHagrJ5$Ou?&h-A^4%Z*h~`Ly_V#wPuHm7F z9%u1khY}2i8FbuA-iGj;RcyPN0?^*x#Vxn|g5@iZLhB5^LXNJcgRt#Y__T#(g{ea` za=Y4JsG_3&9&m@XD-o9O9!HCMi{9^%QcyhsqKEf^QYB<2s^lL>H z8+K@;dn&kmU}-&reQ%ADyxoSSjM7&ZeQE7tSvIcL94Hk%fB8DaAovG*sI{k=<4RJ} z0v+Yd&P{yy!OzhjEa0RAyqc=x`CC8AveW>1F~BZI(PY{9l)%l}ELs|;^RQ!h=9z!6 ze*H#jrR2PeF9RTvNE);t=VC=9pZnaG*po~$luojG^}CG*tF@Vdfwal}K-1RNhT}LD zQLj(Klr}v4TB#XzlSGBlcP0|gF|RGm*DeWi^$AC?@Y4@Kf1K6_9k}9R=vrm0>` zL{;j8Lcye%M5+W>;l(Xm z_|liY#LsWJg-frzlE41(KMBVo_zDG{fBt#??Uq}(_S$QaQWA+oux*>jNQ5!R<@7Vo z;D0asmh6^}mpC{`p=MctWkfto3LO|#?0d4H)>M_kfD%gHZt>PF&UZV z;#95stEPWRDG5X@=GYd}QH+C!HkoFkFI>Ql8Y2i?L0Sry=@Fhj?MS{dkm9KRb;x6b zT&?HwNbkdRpY|%`I{A2ef$v^(1k*u`t$ajQ5R_)iVz*KVVS9Ag@}$06xNWqepSt8| zj_WM&@iTvjE=@5#4HHw|AwLa2yzzfyS(>43>uItiQikwpNsW|Dxp;aGKTocIhTh&@ zuaK`LTNuYTRRh#;%P)S$DW{z6(VYgc?J%Qmo+c|g3sHHaLif$4_SN@yhTa!INI$hw zaQMnq9N5%IZEY=r64^q@)7{r_;K2uR@9)=O+fnK;!&aZx2rKAOrTq*$4xOE?eEBP1 z#7zxQQ&R)ec!K;|rlw0=_tk&p%=0cpNPuJs3_2mrnh%1!&+mDLx|XM z>Mfgb4X^a2%n%_9R@h<^K}snOY;EOzA2@^Sum29Gob+y-l;hRh;tdEfQqbqPTzK_0l|Mc8 z@)^NT!O4=(8@}NLhL2gMk%Yrx>Ma|~val?RU@$oA0u*)83vAT;JseB_zim=xI;;tI z6IeD<7SOt%CQLAssdGbQahW54*OPG6B37P!5IcLGCL&`T;R?nWAtX8&WdcTaam-=~ zx`v{LRKNun-g{~Xq2_67H$O+Wu-IiSBCpcaHQOBO?xZi4LyL8c}_PI zu0?;Uk8$m?u(gBqK%S6@GvO-gq+&_qBzN8MYYymaMQaz=b?N9>hSqTR-FLHoTLQn* z)JehU>pS_#1?O_9dsDcjNK_F1e1CQN@Gcv--VL_)>_~Of$27dY1?*r3J1NF7F ztpDp2S6=!auDj{?eD3ONXw-`2lfA^gY_mhBI8a!KxP{JUnY2u{gzb-;!b#d3=_*RX zC7m9i$?`nTh4D)dD)XG|kru8p^d+GclUmUzB@?ch{2msLa`8DO?tDsc-IxEy*56&l zj~6ZCgyT=*vnNc^bm$`btYEHcp-yUCH^m&=WIom50+I#IQFgZlN#-<} z%rNsJ5$1>xSv{AM(DbKXWYJLvpawMcmW`5{J-GN232eKKq7*1sQ<4@wp?T(oCs}#u zk-YTM^R%}Ip}&I#@prLB^)jOK)Ob|c!rXE4qJWc3vSGsp1_uX;#Ud`j`E>OFX- z2%CLIh&Q2ql^f+L<Cp@k>%m9xH2QY2U; z;*2M=q@=|})MlbD#X{MM)|y1Rz=UjN>`xc*)f?Av^9ynK<7=QLSS}-O92tC(seFWN zA8fz=11$W?uVAQ)`Byvzu@zA0g-5fr|K&krHlX96{)4rb{xjpcm!O_GuU*$A6mMg| z?F9lfHd{Qkeg{wg;(AWM@N!<$?L;CLrHrm{#AoX-%4n=+%G0`)9j)++_=$|7E+D9l zNK__6NeA{LV4ew%%x4s_m{qlA1XHdH7^l!}FTKQvF1~;%WwaA^tcB5B2A_tk=frl( zdr#z7KmR!wU3M9F{QT#{Vlna=qrZLcS!Z$IefM$x#TTYZc!VR5 zJO-tT?8%u%tGUI5;TZ~!tb{e2#;ky^+>BI;;X)57;*~!J%JWED7jNdE?MVGN7HGs%&qDTxf1&~8TU6-^QVO)TZ z9Vl&A*0N87(s?EUDgCszHnVbZJ6Bxs5kB?N^SSJzf8w=G8_-(Q^U79EKjRE;{r)HT z+SjfpFJpiot&5a|Lg)gJCyU^Kcq^Z}{KMRJ*H0PTx`R7@bvxtZntAgYSw26)S1&!D z^Dp}-cR&0%gU$ex2_9bI$N|y&%-GCec@3XGP6a5$4C@2*1(S9N&2?wbGB2#{8rFybD zSohb?H+oUvd1X{?DXw>KTu5A*cs}L5Y+>YAX&zuF0X8<&aT6 z6a_-e&U*O2F|t_jLSnPSwUVb?1EuM(dr;61-|Z98iY+q!MtpmP&!2p2eiX3zoaM^kOQ`} z6>!P=CH0m|w-rUHFr%q7vA9jzQRIOl7Rk{ZuMQ-Mb#^kWYUp0NlK#E{qS0nX6$FHF zLYZ*$M7&AX&b~gBa_H#jps%lorQO{e)ZWgPE!)Yud8Cv?qd~^U_mJxE=Y?mUVUBGv zno2PVmB!YxEb_|rC_QFf6bc2}+T+w6cM=UkvY@-0dCha#y?Yd&FMwq=GCn?zY-nI& zPm0sdIhQS)H*@~^7qM;Iwu&`i`M`NinFqEh97gCY+XoVafq2};Clnz=}ioWkOhAL6!eoWi}uBE5YN zaf%vYS}vhq3z}NHxi=*^|DwM^XfdeA_~C6IV8=iojk1d=9YF|5QMiL7;M{Z1rMGtnLqq+1^PAt~y6=7$rHuY!IBi6h)6>%&wrUk(!viW zzw`G;AK`buyNhD6%+IwLttucIrG=BuvVQ%GyuNcM2OqqU1?}ym`uhomBzNEaSFXG6 zJI0MkmIaAfnrxeCG_LDXtBqA^leBp3@rT*^`fI%Y`fHqb-uoFD$?(7fk0L~f?n92K zAjQqiQO3u|IdE|oKmPbloOt31L?RL91Va4ww|`>ui!buofBAgn;86KI)P{(~VyJ@_ zuw(O13VM{12+_P?Atk@jk&L=76K<9UJL=K%4E*2s`s?IJhiPnVO!ob%yJa9vYa8L_De-wbL&ofJ$ev)|T83q%$IkWZ&+vJ@e=z@BWLF((Vs4;n_a zV9*WGs1?1*ZNv^chVS0+M}wyp zw{B+AYYa`eVEL?(l*BZR(xToA74%i{_3ON1T5IhUuI%H$17$(AWOpJ(d%Tsjb{I=1 zIM9|9QS>B}ER_%-LPjZm^7#+($;}fizV&{PE5S(+ldvrd5ekHLA7PPU@FySQ>WBAm z_n+^Bk>wz2AQFcb4Qdq}okYg1S`BQ7s*-RkLOrMC}Q{OxZK($dnx#&zrH zT(X4hh>KD=28Rc^;)*MH;-SY_|KvJ+1vtRdOg2hMddOj1D^5H03~s;ub`Ry$jEsyB z3Wcf=6z$Q{rad%#=2lnJjVgb~D-OpB1?mYfK>^`uTtZSHL$Zn{IC~9M*Efkok|S3y z;=&8x&$a*ZWxjm%SJ9Tq>M)-v!*F^6LN*{7p`GJ@u?8{$XbZx<;o}GAc92&|vT6cGhoImPYYmficVSskz{aPo%Kb0bh*p(V{lcY(v1=ql z_aR5H_04ri9*u1l|qcUI;URbFuqBKfL!O606<+0RT zaW4AA)qLfK?=YnlsZ^Roq8Hna^W^%6IB?P709aO-30GCFu}>R>(R@~g>k7adWbLC1 zpKWrXba5YTnW0dMs_LJLqo>i%dOu5;M!-a{ihbx@A#$G`w>tsRV~(`a4Tw^6Apqa@x#Gl?eXrFF8Gi`N^e_a|rF{F=&yCFo6J z{T@xr=Lzb92*!)5BEa+c#VmU`DT5xmBW7KEjmZQk3H~pAiP;b<+H=~FXkBlt2Dd9N zx@!ydTJyY914^=eNVDqK!^GWT=E!j#P?`r<&*8}K4hHikYk(1pIX`^GxIqm83*tQT zXb-K)qPg)S{WOML{(RvQPU!aYplE|op0$squ^#L(eDx6^6z4aOW%nJLX8#aT63TJoencv#XL2aE}`WmJsV$5)=3Z$f{28S()8*i z2#IBNl1yf?tSD)%nA1GXcrioB)no>Wth?=Wy8hQXSPu!ay!rL^1SxBjQ>bd7xw5XeU%VJM5O?UT!{C4ZzY}~k+_V#w3 zfBqS^Z|dRFOE1N;EE4@g6g9MX+7hVYk9Xe5+O=zGZf+wQYNR$Kc;%H1o*Q8&zF-hs zw^E!qPSSHJlhg?T1lYE18=E(7VE%#*0)YUD*EW;Q=2^G#IU1$KpkrK^OwzKZ!Lk@l zrparCZQ1np_F;uBoL$2-Hir1dH@=N!#pvi*#7#H-lpAmS0bt(Kr{S2xSMj^sf5Z6r zI2$*3r}5JlUaGjV!i)^=;;d6XMoWv$$jCx&y6GnFy6Y|=WW=@7I5!!NvxQPF zVI&zKFI;SC5kf+y1_}_2PV-92UJDk-J0P&z&_K|H2{GYnx|c5H)SK5pCIa&n zSG|8euWfvWn0>fG+TH?H+26jlKlG$J(`Row@!os=Ks!1siJId%{IS_gO=i*GmBIOJnxlIbGTn-rufu~zRYp<~14}~l+6E3UE&VpVoGUYWmkw^q7CGmJ?<-Jdm zvWnMk_UDgZc_sh+na}W>JMSbGiy=e^UC8m3&wY-ceD5YsJLhzsd-(<0+uIpe3N z5CN3RaLzgB@T-5nomfi@$8n4`uh1O2crimmL$hdIK5u|xCe3Co)V&$^KHwRpcuh)4 z?EM^wy;u~YYQis=V_R(7){El|ap!G!aKqPc z;G+5T6`$g(*WJKz#~nv|dmBST4lOP1ygrnqKGFkL4DC(&r##(8R7xiGzEk>=s5Vj( zZ@cCaV)n1KhG1cw&dx5b{_;0D=!m1qxQdu9J=ywUhdh(Y43YK$>-Mdm-}wwyz@SS5Q5!_6m#q_(sSw5y6lQa z)%P)V@Oaf;IkN}NupY{5b#Jq)l7Lzv5PD{vmW_OBJ?FDYuQ}PL;~N!MfpoNYv0}vvoOPM1%mKLY!V7VnAx4Hq5JK?G z3;$s0!i98o9ZbD7pGmjqO^h|uz%lQ64|Tu`FZ_c8TaIAdbEcEh6ox(xZEc+ukMWwC zTINLK#B&N~#HCRRQmFwN8X9oN_fT6~M=Umv-Ma^wnwmt)h-c%QM~2MWT-eshB;Yt% zI<0A>Fc0nao<2r1id@mG>#bRrmN*o&razISqqB{i*3=6@PAh7qU`#AB2cFiRW~IPf zWuEIzb8(1oxk_OscUG->N&j>Ft|yn^b^vBM0z3db>`$F{a+9(v*-Cfuy2nJ~}p#*Le~ z`0~q1rji~+uetl~zapidk!+SRuR)mf=qRnNt?X7V8#eb)heYcliT>R@@YsEHb#<}w z=wq1{nnWVSqifePFp$Q!Z5+p`P#KldIIcs35Dcfsd3ED+q*6&%tXRRH|9me;u0DY? zK6nWu*)(I0stk6@2YPt|Uh@9)YfP?)&VYcVh%@XeY9;J;Q|7tOC5cH0r+e9hU{W;m z;Jv-jw2B{IbPy8*Jp}AHQ_6YMI^d0j@^99pz`i<_H##Wa?Dck=6(IzZo^V`w1$~1s z&*P}46PiI$ydtI=(a~?d&-*kq#w~^uX|RGwX``H8BDT%ufdJ=za~qPU{5Yq#3Wf>Mb;a!<+F7ej!AVN^V;H+M3^S4lhI_F zjCN@6Xl7ub7irmE7^6T+gXRhZFK&E}Z~!j9{BnN!(_hda1i4%WD`GLF6z%PCwr_Zn zdM{g~JYn6R@O4VfaQp+_7YZ@1b4(R9xCQDX z5x(`k?=d$NVs|D(EEXe|%aI-&q&5^HJ3P!;XP?dc-v55?f8+s{ELj3T&(7`44aF!4 z!OG)SanB$Az``X9KF50-lr{8 zp-F{VO~o6X-}P06Txq`*TVNlW_x=j!X<^pm?nFP&KK?ih+uFJ3p1*V9g&(9o>_=)% zJW>yt&0vGnKCb@2LByOIrrZ2vPJ4#t_0JJ%nZt1NT$&maEAYp-o*N(fdT z^Dd-}P)`maB)z?TOewS1x~`$P3MoCSU7P#wU&}?8UCf<#-pSDGgN#zZ3N*6%n4?&+ zVg>bRgesanP0VES?0soxkk+@)uGx1#DzkH7I?%v|4X^N#D?i1r{`fb-u^6vz-O8#% z7IWkoXH;nkRpqQ6RW`E#03ZNKL_t)jrb><~7imd$?(FB2mtDrKx8Kg6|NLi$G8u0C z!Ofg?k zRLW>drFp4pq)Tt2@u^0c4U()Y_Q-E_52O_I^z23mKa-f)i9IO=1S>Y!UZXOTl`#9E z5&LZTlW(AY;Lqi<8csZ`yKhu;3{nXaf zux8BzL?R)^3h<*_Z{dU!PT=XMpW`P#`AH=Ju?*W!0;imLj%R^fPCa%APH9H>?7^z7 zB{wz6?o?p*J)NStqZ^e<@?aj?>-rPf5Ya7W_(sS?WU{onKZ|-5~ z(r$Ws`tXSv;b~i28+%fYS6E6Wg+?p0k4-7fq%7Ms))0@kR;HHkFu3`O6VD`yF(=EswpL^?h?`B5D{6N1Br4P8?TG}I zWtsehbecis5|6jBC+W~2{A^G3v7~dcr>`-Gie-gy(k^3eo?7Xz1Zinqrn$M)TNW>F z+-TNq*rM5vdQ(-+@IZ=`_dcdDwwZ8^F+#B7B;-eHMT6E5i-OLeG%S)9O(^mr!#pcu zT)mpi^m?~S61Cg7^YJlgIu=NB$-7sfHuodjmQhgK_A!I_{~B?gp&6Uqw6qtM`K_9j z1|$gM965<+B;h@q)kQ~XRj``LSF3Fm+i$ivyRBSFn4ALXyNp2oof{HYX{ zR!j(!LY~Rz&3k);o3enm(Q8(2yZL55aKX8(U;kXC*mJdFL35n#14$-ET%-)`w?Nsu z3DgCHp17F|G88g{f{^f-88cZblV087D-<9gDuuktX=KRk|8p%#Nx{692z!*#6Qy!F zYGW}X;GGQ-T0E1EpWk*HU%%lSoN>mP)b;l>G&EEx#6J1SEBNWdhxGBQ=hyKAa$GnR%GIVsb0s|F2PCRbn zE|SS4@pzn;Xp|?OSj&m;JBbAg77%Ni&sYIMAwfjvIA&P~nZyoa($6k$N}U%1^z5+4 zeecVEeSay}kda6eyGC4o@S`6Q2sE}4ES=`nSJ!jP4_@b_li$tI&2!|hi1kXPE0!vpMhY)74R1(t_=7|uq1?e+L zNfllz_I)O2?6dtB_U>>QLgZd4?@oh*$a zNW8h3EqwztN)t9es;V?9x@yz5sxHK&&;)s_CWU>Pl(IIZ;@Q!3sQhoz7#;oKGEbO@~_W9fO+ z;WCDSI~$^YuDa?f0G@pKVLtkaPtdz#2c2DA=ye+i2*HJyUe3TkijIy}zH!6%x#Q>m zK`vKde#-*pE({Tmx3hV}vy5w4y!a66EI*@ZMPpF#jcT4%U=faxUOQ3ZS*g7Xnbh= zZZA@~M5G{!#h}*Yg`~+V01oMHMWs?qyGcSqGb$~>V$52~*KdA=l(1Pxjy&GoiwvQ9&zB@wnoGMU7uizua75N~5tDI@|d6!W9a3=9}? zyvl1@TRX^Rv!0$u($?BZI-RW?kd~B`JczvB3R3H#ty(FjJbhA`Hd@|K%8jtA94~EM z5RXUETH`nl3*x3hTHf8www@jaog_hB!Ecn}U%(Xc6S3jqKY@ z3C%=2%w{KR&{Yv6D{O}CWwb@7`PYYDgF=X9$F&kt34HN51CF9uO7ib;`+cJ!QuSnX ze}AX+HuuYSf~uHi+6)?MrJ+KUhjz6dUC*EqRVSX_i|X?hQ!%Y!RJ%yaCZ!-MBq1Sq zXxkWURB%i$(=S}a9nU;(gz>q17`}A{G1*2|2u}OuAWz>}#Jos^oDlT)_cIj;uqTt@tW!_rp@$ygsO3kpaoq+&9%XN2 zWQ66*m-D;d{+2UOJ(XYHc_)!bgej#7$IK9*=jE-$Vi6Ow;JFt9WO5l#nhwRNQWll<;K?qvB=FOiGf~k*k%STQif(46|vWYr*$>wt?;Jkz~17WYBYta#a#|# zEQ@fSH8HOl{-;Q@zVdTi~P=nR{u5hX74|Lryn=!E&fSrNb6~| z;~?cUg}wyS!s1m=Bw14CeoWvp=_b)yd2T}ikVafTm33$kd3;*)>VU(PG66k3J-v); zXtLUH-5SQVpvJN&2|wFafGMRBs*k)k6(lWDDo2#juiw@(*H!h{IIm*C5A5E6UsM1_<>Bq<` z7pt|IR|m2*Ha9bxP4kIQdFx%9G+ z@QEuw#`V`<&!dk%%Ddlv3=cp2INAH3;KZ}fr?|3rTF z`46!m8l{-(A;k#eTA~Epb$1^`d=Qe*5(Lt)!KS3MP|!S|*~UN4K8UZs;)9`f($78v zIR_%}{D{Nz^Oy01KfK26SD(b`-4=~m#keJ@?>LMVH*bfnA?{gw7iXRMNmMe=LGeXg zx7o)xF8n?mb~+4ZdHV4b@A~CtUb*vhCfo#AHo{A*FWVH40}UQOzX^+-$pJF9p_oXi zX^;{n%wg+P0%Mi8F)8eLoRVLl@`~YXmbuN%sC<@^fE@z^)FH4eQQ`g8NuItc%^o%r&D7qvhS;wK|QC!9`n}4kkNNst4S5h zPO>tg@|CSEm5UadERvuS_=V=+jwlRogO)`++ykdCUCO8nJ1qF@Lu+7u7wBGsx*e@0 zlfuvT{v_xK-&uJCzG8+^FOhg$TY!4o`{z5|D`EB^>y2J{v45Sw{+ws(_9xb_6kldI zmem@e%^DX~$8i&dZe8g@6p8d)e^25Ac&;uHlaR0}xxpiQh>=i-2Pf91S8TbX3FQjV!|urLmowO(koysOENSxNJ#`L zXqd`n0KwyrKTcCqg!cA@3=Qo>BchQ8x&|drw`>(@(AgAel^Hw?+vU zH3UqtI3bL-!Dm?rYm%aZxLAzqIz*+ypV#y|c_LAxGX+J4u}WPv<>iRfq6kXK9?zEE zOMI*hi#?n~|z^GDKVViVO z(-;gAl#uL6RU8EkvI}!;iwSqORG=)&DD9V4tM_VZYW6$u5&LSk8Q7TWPWs!DWnmiZ0>U-!fckX3dF~r;R!QXo!?C+vf zcWYWhUg%keMX8EsS9;6$nStWVe84wuB=nom1pZG@ws?m>e_v;hy&=Xoy5@~?gbBBZ zlx>WvBK4NxhWk~3pp281hU4kFd9&E8Y0zd0VhNiL?Xpt~d|FU+H4Q>}H(pR{#qswR zSs3qR43}}8q)rHeNK~>0TegrzGZ(?6PNKDgAAwDjF$8%OZEgz_BEy(AjzbcQX(V}} zDary_EXK9Qr?Q^^wxmCmWo~m6H=CZJ<4B1Hq-BxKX4#!cQ`aUyND3a^rLQlAkQUi& zo}f3i7*4y)6;YC@6dauAU?+Y=6FU+_^*IpZ9*_wQiUs^hrkny&$xvHZB#5EXnaQ*kAY4O_837Ld6l;eBT|euGp%+-bAIgr=%946!$$j< z4>HTLs6+76pZ<&+um2i5hX#$~m4{XcArPK0U28}>1H|La#wY*?ge6iMyG30zG%z6q ziNpZ4(oci;o=PQ%$D0{+j26am9Okvf0YSaDQM#_lG}+bL$CPDqN?bSV(Nq0w>FvR` zTPss9v$@vbdeHrzBjxs;@|FuC;-P_z> z-|lPgOoh6=hF%RqR5VyhYvTsyO(82eVctQm-^TYg`ZgnEueZV|l|af2oribB@ITnG zF2`e6y_eO;bi*wV@bn{FdGUhtIlKtIXqfIFu7S`Jy5%roG(;>IacL~(x%H~!`0;sZ zj{4?*vR$r%p#a?eD&JznOvqb0Nq(Wxv%jUHd)l2CprvKLx27y|xg52jkU=V4m-cp> zd|~F~=?(69^!sWN2uJxuHQfi$(!Vs&$vojrYC9*i_*EmhBkUkMte&0t@O#^z>( zgo0o4U|%l{woPLqK^*~BEIp8HHebos5kfHPD#Cj`cje)WPw9$AX9h5s&3T)A(*aW1 z+(Yj5^9vrEX?C+x8P;fKnQ90z``HjxTKBiZcA7++n$nIkt{sFh!^~Do%tlnERh~K` z9^9?bt_C7ZDVJLL=E<~^Z}9)C;ioC3yet4JBF{3MZh3;|vJhvcsZoGLNG(Jm@l z98sCtkLw6XC}KYUlqxWVWKu#7$D_8m)JiB~0^ZDI)f8KUNQ{-8%Y+aNS8ak?DMTDH zW#mkltOW#MO;f-?w3&+JDozO)X25(OZIO^8Gv7~2927=Fr70$hOj&}EXB+*sPkxnS zPF&4Nr=84LI!j|X%0xCrlO-8dnx=4+!E~DW(I_>Rq~5aFv}u6bAG(Lne&P}ugdnRG zjbV!^Z!!@<^4%|fl@DEUX(e#YwrwVqVq6*On`KF|XnbjnQkr^8BBjmBl_wHXiiK@$ zr1AVDaXx+-FdYabePJaBSVRpSx1Is0h zIH0;9lLlFYP{A}TDhbcJu+gRF{5_0znu)@stGMue$5XFepqAQ9E5BSb2JJ!q`J@&` zvsrw>DT*4fR>4RwkAL-Dyld$J^k(5~e}e1IJ{s|bmmy-aGr5~s_px-H_cV}&C2^=} zgOLP>MQx@AiuCC;Y<`8q4$tv}&wq+s`cYo`!qFUh>QnH%%Lr5r282hEF$u}#iIJ3o zItPMn-Q*G}0y06~4&rwgkS2f>8IS_k)o9loSOCg3l$1uxGSnz-#J6Kk5-BC;Uif}? zXLd4)z;Rt%HxF)}MrmkIGmXB*pp(U?!6A=uvQ+}Y0ugPDLd*or&^&5o5Uq-25^1n3 zTu(Hg+Sa$%06|cv^3+?l7nGHvL6~(psuWIEGs%FLl&l$cO)`B+U^F5^5mSTBI4yDX4twS&TVuCGdDuxif1L6I3{baRw{9V9f|ot7u|j zyP~hE^F;ZMK+^|I#$Mt>6gENjAofuUjSbcBaL_hKrQ5I?;?&n>$W z>>LQg;a$+_V~giAqrD)YFxO?O;<0`ES&WR-_Qx2^V)(@pJeq+44@mQx z?FBki*mPI4hm|Ok&Sc5UXM^_W^g>L@Fq0xj3CU`@DCr?WT|N(GTwd~m@PUQNg>86BQ#AQ8deL zYz0zz%({|;i4^OLRQhMip! zd+MOmyjT=$36hI(&%lX=kZ4_b+D=BJRJa@Xz6fC;#nZVW^Ny&mZ?*m2bq#`M#;f4E z33N~tmw_s1E&gg0z&e_HB^DDby%brcwNXZlL<9?>L7q4y!)RSLmD21mj*|u!h&nN5 zQT)9Wka@AFKr>Y|Nk_Ysl!A(-@uSd7Gj<^nfeyLrrpX1c1|h@}l9|>aqmD3~!F2=Q z3L$8h5vGD0rnMrMD;n2N=>{qj5?RMt9+83Szowh=_dkq@mATPU8mNp8Hu74Fboqoy zFUx^BGGm5CE>C0S#$0y&cXpg=iI#3qlh8F&;-G@=k@IqF*wD+on4+Xdf~ZU}Ud)jY zF2loFy1V-r&SZ@HYO!cGo`_Mv_|&Iv;-epZ4N-5i{l8w3Zkh5|9R_Ixaj4& zY1QBW03ZNKL_t(9VoE960@Wl_VRnq`E@p#jbsW;E1bg;ANnc;uj5jAu7)_@WF$8$6 zX(57?U1YOG+S~*}2p-Gi=O3d8r%@;>K6K4V{Ky-GKktH7+n_Vd z8*g|n>%E8h-u+Lob6`72htI$MI5ud7y|F|tTcN8f!RTm_;Y@}ON6?vY85|x4+Ch0B zdYDDfR8%+)#<5yK1{b03LF+gqVq~hq=sw$m1y7k`cX=nLT>NYvbi3e(Lm&>;E4}k5 z4h~+0hsQny^Qj9t`Gz}T%@&fDqStd7WOND9vsQ(vEpQVt*KD9#)7vd6c!E(?rPE!Y zS>;%#gE1T=&N?94ho!_qFs?Nnj-*MN@sst8z`^>>8~EbKKE^<1I3VJOgH692Y(Ro` zDQJ>mv|cb+bD#yk4%2AS8YvA{wpI86?*$@S&?G_Y2*n@`Upl}1`kWG?Mr@Cu)B@lW z6$>OBXqPcOuSyIXA;b0gP|}K-U|v;agasi80bvJh9YgCXVG(9Q2pre{-1&v;**~1)Yr~@q43G1&zRkSk z+*3HdH-gURc``Rlx;MdDBEmgCdL5g3Q_Oq2m_~3=CumJYXks`}3Jj`zHCf7rfT6ag z)vAQEXukKopK$KE=W^1<4NNKT8TJo?b21_guIrM`X4!Q7Dg5H+KYPY5OD%B{B1ocw zajTSOPE~m8jc?;CU;Yw8nf*uvn{qmBT%ex`+BGi(9f=fYoqY~(d)tjX_lz@`M^o}V z+NGpWBaAD}yeny!f{DR>Na=9vE&s~)Yky5foCv?4gQNhp&p$*%& zc=bxQ)*9Om8(D2j;KUuYU#88f1?%Ez(G*6}Gqhx{Yz2g6A#{UZ%8`5yZDy%~Yc8Oa zX0mMN;_&b=i9~|4FSr091eaWL3AtRZ-kp_F@`E4zfIEKk8+H}$BN8`-)<6IG&wSwv zUm%;!lFQ|o_I=udy|ASQco8+|-U2NeL_8j>7ZzHVgJUpj(WXtCc=XXnX{vEzff9ic z<`J82lW({;jT$C!~IF8{)39;mQwwO%Fc#7qUI8sv5KJ8AL zuq`MSJYq4!pX%sMaqv&WhGb$pJmQ3T?~V+_ZP1E875al)6J$opgF+Uh51o>4TzwG- zM>B9>53K3KDu!qZ1Y-`W93e;3f`jG3DxD*wvvh6V%)i}rh>!pK-4J)U6~V3dXk(j@ zd^YUgV^m1@$N9(0Z)V^pH!-6O99K$7Q*aN9TJeMz=fb!C4CsV4VR&*Mv~L98f;HpN z>4Hvk`OW`hluA#D(f{VN3FU@(j#TW?@~C+~FB(^Xr97ac*HQ&S5JNKJc|@c`o9j>! zF3-RAv+&sQP#%L*6KwzTEa+8m`kXn(0~#JVjk90*RmOjO9S8b%6BU9P;ZPMmEez76 zEh19!lid~{zF`-1YzKP)R0UWE>mxAnM>7QXceCnkKj*Q}y@<9UkIA&A%{w~gswK-! zTGLX8nN^rYbH*8`uy=1ixm=!AZi*>YJa(sAz>0K&$!wmUQS+8_U6&cpqb*2Q4D3_}u^@FdHLaJfCmOwkd~Yl)bR+Z&3Iz|( z%Q5RIgm9QsRhncNrM)F;2FLEE)Z~cGBGgFWF(+m!|J_}N3|gyd)dF$dAgMNAH+hWkTHIPIl&X?WrUqovkdDjFJ$vcy?xLh?rgaI1GsE=t^-?ZZ z*}r!$B^|;}r|9nLVq)ki66plvnGB^;o`K9Lx$G#UQwSj#_dMEzAXNmNJOS*_WZ1I# zIL3>4(&;pLJ%CFOkf2FdX?I|j98=2Uq*FKW@K6yq79$>u1w>QHc(G_EUo66Gv5Mzq zX$4w}lJT2g%nyILpXPX`T7@s2y4!TiCt{m zm?D!OV*Dp>0SCT*?=<{inzJwONhr0^mF2tE;258{U!CPqX1T?q64_3vK>SL@5=zq+Q(D8=$qzxFu*z(7C0>-vC6 zbDm1UNY2w<3*Q8Tva{1iTLL6p;gtace-?*+z=tw4s#bRW<3{64cTqFA~ zCHXHO=y;xon{avAOJB;it($29rqm+mr3I)cMZ|F_0#msxCv+Qbz(Bud_)}*xjNn@j zJV|D-2qehZnohsK>$aWE=^I)p3YZ$TSrLP4pB3ZDfqk?kPNS_lNXV<=qX}u7Hdm7n z2N5Vjc^LZjH`#R6wahzC9pz9<^0V0yR=G*E*7*JcwryhxjE7JzN82)Z^dpm%xnm64 znZ{(*hZ+1uB~Wzz7%ai(@uh()Oz0kk@s`K1?Sge?W1|%3(T`X3l^8W;Dvnc zmamddrx^G0NNHq&g%Bvu@J7aixOvasy*zOD{akayHKt(T$ohKU9&`l9gN}-fNG`hg z`F!cKUpxYZq?cXe4ZL-N&fHcL@Yj(QgrwBp(-BPtikCU7>P-?j&7yszv_5Qi&~RT8EC>{ z7e)rjoPNfnWch0mn4jszd)!jHi$XA~6-pU=aW-24lI-0(h7gjd=wVJlRK(E%w6CUU zluoCXoX@UZ4|CGSE@lDOjZp!{GGhoCIVI6L#O-_U=eZZ3j+;tx#{-jW*}Q`6XpvpJ?`3)-hnsYe z5eHRK0ipAJ9LJ2eSu`{K!@TK?HlBaRRcw0S&*70cy|2FqHl@LG*@A~sFsE!*=L(b@ ztBxVBRu&;KW4Rm@LY%Ta6>MOR;TI_{2qqmK{QB*j<2%s4F2Eb7;ozS{gK z>v}f_%QBm5!82Cu+VxEA9WmFO zGJNb)xc(rqeIn zmUPPXQL@7y`p^d{<%{(MytW=r=ZbX|wnnv`Blp2ou1hYT<%VmnVWQ|U?s-IopjAr7 zgDya`beIt$;Iv7!oxfH_g)m>4YnUy7J81wVl${3TqgS-`>%x-Jd-lrS) zn;Cq@0^{F!JdW@Cq}C(@n4o54WQ2}DVz~*6`8e#{`3R?+atdSK1P2Zrpv|%ncASF; z4Jzbar;4Q~@Duz^4F|beVg1{+TBa4&ZA|b3KsKH2FUB z)}r+Ayp+Z>B}i75%uftdwm4z@U$oX}->0*)lZlA}Jw2Uun0vEWl!|Q%j&DAwDzESB zBNmfXs|(D9!yFnJ;i7ZTH8m5*<>YRQKRucS6mR{dPkYjZ#44_e3m(%BP6XQI0xJR- z)P&Ofw7<%?b{*#XwgV$JtlAER5ef;Y<{+XKs|19-RpcnppUu-OT?ztz`M@Ns?Spj( z*>U5m7!t@O(BU}DY6UpF z{?%90>coiF>>IRRBCJu1*TZ@#^`chbX?%nYVOs`9GcI$=a1FFpON{s$2g2-M3H^%J z76~D^>7yUxA1}IyXma?-{P zv`C5Qmh9fWn^RBS%AP%YX>(Hu=@1oQNr!PS%l^y|+qP~sj_1R}OpfMp6K*iU(#U|* zkR2XEYXc8l*=@%ALQdicK`aGZp1+>GhYs=U!7^XD^#H$m&t2?(@Wni}Z!g!r;!>Wq zbt~oa6epap8KpGkvd{j9zRxE<_!B$%_2H!#-Zo&6U0U6b(0nO9{0f<@A zdeBf`IU16V+Vi!FrwJx313&ROcA{{^XZiKlTG&ww?fdw?j~=yHu*~aPu$cBsgc?3F z_6&2&viv%qrg0OgJtl%Ts`$GN&|HMZ^Z)X-tVQ9)+M?>Twn zag0ulp(YFTq&kSMY)9*M=BIX{O9n1ySy4)*5>vj1-5e*C?4YCc1o!OT3!AsIxyK^L zL0a8*_GBwm)7``vJvu2kBGK>yuc2DdoXL!m&E{F#f&dw7J-E)&@4X%sDEh5K{2O&|m;Zl=V)F zsfvU06d}h&NjdC;K9rc>)v#?fxMK9yzh(SeEMHb;>J^-qR2X&cTd1bH>|pn zhbD4d6=|WENaK9wr*L=bue?a#J@Sm(7$KAl6!I z)_3>uyWjne>#n;FJ*a^&E9`dKgup9$M1`bT=aw%}ilvoMu?*R_vG_GZgAZK;7qrPY z76ra8W7)P*#3F>_I801TFsC$!d;p6c+}#4G#)K!6%wRf$8o#pzWZr(jOFH0GTDP!IpxU7R)I@c$ssPdNJ`Y0f&eF zKQ20Hf#2VC9|^sVvQ~to%K-(HJrce?X7P7Qbt0u^*LVM!xBc>e_|dn=;HN#D@YCCP z_`IXk9);l?F&rXVQ_bxnmwofwWI*?Ro(^-8{Lk0XEDgz2*ROw_g7{2Z`H`3q8cjQ|yz*6sG#WF~fHiViqZ->^5BWM; zxl99EDU>pBm3d)2Ck|xy)zzAs2+`Nq#j4I0-u~um0L@(w=eXr7UqWj|Z?cX32gd;T zrz>C0x4-=@KK!XqbNKNGx$E}Z@w&UX{=M(xCqMo!$FDn?HSKYJbI0%4x38buzWGf) zar4b==uC3+$3De7-f<(ni5`CQ;2x%w#~EAJa_LK7!Rlm^F;DTaPk)Mi`}$dv-oTj3 zQBWQ`9~@#3!KL4NgrOhw!)a$Sr>aKYc7C2KUV1U@0p|X=6SuSPiG6I_)`jmt9+)qN zaAJM*k5=gFiqJZ=m!DpJ5_ex>arPU&0BoY;!W8pj7$2Lx+NRfW7|CWyI%yooWjZ$; zDCP+0>E_<-Fbk|lYY&Yw&?p56#apj?0iQTS^He@hD)lUE<>BY|Fsnlh2|=N^4^c6j zPgzK?9rCI`K`GiWot&54bdZ1Cp5U5OD}-ZDaB6BDoYD(-4Y9MhhgXHqsLTI0l8|d- z$Z^87;NWY`@ZNsYAyJwY%|5HwY$TJJBC=v7w(m3VYr;_*?fcC8W!l?U64pNXk_k3e ztPu4ey*j0t^d^ZUeOj?-i?#;}G@AK_q-D9}q*mydw@ijHU;n?x_gO&`!8$6@Y5crW zsYEzx(P~-vL4q|?GRFiK@l@2Dk7W@?5cSRbgk_<9CJ1!4`_s<3j*_m2 zMvJFt)~q&Q-pXV73kWNagZE2#V?$J|C?S863Q=r(0dK6I4y&1x1wz<7mMK%5vv4Dm zw69o6Q*hj!QHxHJSQbo94ze@44&u)R-^CIIimYQeJI0oD0&+zTiJCsY2|QbLO%*6u z`x}y!8lFwdUz4I~|ycmnJb z`RHwTP~7-(zVMs<@cUt)2S#@A-iy|vRH`n!4AADfMlQEuEGbncnd~%B-3gEO9+#Oi z$4vejVI;Fb5oNXk>ScIJ7A^S9){{a5^{PR^d|hU~EU;|bBohK=3uR_JufDh1!lpP; zAUEM5EF<+R5NN+lZ)Ycy$|N$qoonbnxSy5rI75#Q(77tfp+bQbc03Sx(Di%Y0yGOz z-zA#>8yjJXI?=r#JX$ct2w@r1OYQ4=hSKCilUNM=W{&8WHZ`mzsd${}a+!{f4obRA zlMn0G_uzR2(&$#|KJfY%@qv9i;ak%%KENAacm-3L`&kecEu;|$l=Ntq zeWX$mDBlfhUPjjyck@-`R*T$D_KgqwnQ9QIZ=!Z7fNbGw7Py1L?qWPw z3>=$HyGsTY`CLx$hBsdiz`lL`G-*vbonUx)v~B>`-Q9)fc^n!X!gCYcdh6H7X0uD= z1ep4dO7VYg_yp6rJWA!*cG`34>Pj%D z6v zJhp;@m0_*~b0)5*>`&I=>>2G7$0lZJLxT60CJKFPR#F(7V!?t477IYgx2XDyuL=3E zU>$=j=r2OIX3?gE61+a-LkJ%W1LJCKSj$>~g<9n&+HU@~2x$5`_*(?8E2By!7A$BE zf*Z>MtSI2q92{%p2-ubtgf`9o(=V`xEc2}ri>lQKD}k^N7AXppv9O8T<(`|!001BW zNklFZN@ZdSB+uwXB6pgf75oI*qe z@u)?qq_J3F&eBw@K?4`Fvt-wWnE(y}liof$Wp@LC)tF>0b?_EAj$}MYE^2C6rJ%Yd z0wU-$L1SysNW(D{q|s^}7>G^q_&y%~$O)XZbqfsr5#4(UJQN4!c-QmFyz24`dCi9h*tt{lg%9ok&k(5T zDR9?Sr}M1zI1`?t2~k%MYQe1gH@)M%{PyQRXZ!Z^C~3{cjVE$ASE>6rSXQHnn?9yI zvEjZLc-LHwDDMNp#}X!ysoj^Qq!yKn27AO=7#N+WL z=UB$44a-yud?UtT#n6M5x#WU3Ct;h<8;u5CZZ*idInppMF@#iBXj7W zyCTYfW||(VK`f9;#W*;c36w(($=vMk4nw&?I)K9P9IH2%x#>gyz|EiD$Da?_d}`AI z*Pd}4(T%G)tjZkNSLMbVcEZ*)6n@WpU;PoLhxVd`q}7QqrE)|AF(0Y-5fvU5Y1)+} zrTf|Q`IETrH)DL`TQjg$fimYarxc0qZt}StSx*yI)n((OmLoZ8Pup1$%;E*&IBC$D zayH9peQDnGx($5c%a20Gg|KQ6PB~z>Gk>)Cz>|Lhy8wjv`j@Vz+P@bm<7laoD5gA3 zH63Hd%aIb2{a^oQ*1zCq&~YMv`pj;K_dt0QUGbg#_WBEX;p;yOk103@Zhg&*$n`%- zDD4>D;W1$MOEM;kY!*FrHUj+z&Z+!NGWgMFJ(SMWL%XRmJ!_ zM}inW6TtMdP)A}(W<15XmoqV5(PMacl2PASx+x9~W^mm^z+FfzNl-*Uc2!E#-JK#ABsZQ1li5+$ZrngNJIaB; zF?;beLrb=%7Wk`RZhy|~`*E|doLFco-a)TF5U`c7eZcnnpkBGcV;CfeB6`yAHvZlz`xw|Vn%6pIPKXFM}R zB9UUvnoa}|OB%I_OeTZpc|7N|?T7#}ptVuydg!4YTy@n|w4kX>PSVxY1zPc|AAgTm z-1ttmI;-jEh_kA<3r9*$IN=0RsRR%0J;WoPO-$u^b~;A0Y=-+Eh1b3d_76eaWmHv} zswiR|t9g8I7_azW%#}5VhVnf0&_2$4-g)Hn7Hfq|I8xwe-~10=@QcIn&@}$=BfRs~ z$D{H^Muva~tDr5`{pyoUfA8I-M@QJ}C9!~rbZ8ZZgxArPg7FDM+E$WpGp$PX>c@n`{@ zMzF~;D78?jOjo-=>oTRODWVpnEF0f1QyLp(OEg6(Ge!|um+E3FlVRJME-GUKv`r0= z8%xo%vYT==#k>_%k1+YnFi+6&h4mh-RRkw4tY@a!%g8x_lJfMUto zITa)tHHg&WdLjR!j!Gkst~L&9P_kSu7ks~dTIkpk*jGb0d|pTdI>1>QPFqbXzIKey z1Re1_RmWJd{q86*nr_@%rp}3wPsqF zB)4i712rOPZHEhy%NqQ~pO6EN*)Mzlk>>|!9(&nwTE1^vx7U9JYjl)mrD$DpP8&NOJ0OmEi50u32
HA6BUBt;Vd122U@LD-PhMuU#D9dit_phU&PsCtlcd~ z+_O-%TweIVXWq$Wm%R$;!F3a4v-<#r)Xzb?f z(`+P1s}dZoQqb73Y5e;T1=^(>97~u;;NUvrRY(Yj19E~SE-ly$cu(LsE^!?K$9M!ES)7)nZKp`VY*kf1Z7c^ zdTElfylTQ?#=6uaU@33q?|-yB4fL$GIJ8SalU7VA#k_DS=@93=X(!EhzlGMWwUjAy z!P*XXKUH93e1WQMF+M&XEZi1a`!xAFFvOz%T(w+gURX3~pLt<|!fLrj%JR|LM+ghc zvM85J*mjhTjwHE56XeTfEK4vsImL<jV-)08tJ+^%UL5t>xS+-^U4OKcBhEC@Ui_ z@h=|$(s17`-21vSSbugKe%{6wY5w(_cW}$jK*1z=kcH2^m|dfT#7JVRTBSh|PHo`6 zA$a-CKj-qE1AO9RZzY!>LI?*LNpQt$KFR%uALq7je46vq;d;_uhubs+cILjM*tutt z%U<$EUi6Af`P|1|#pGz7bSlj4{ZX#C?!zW%^4(wu9^t>gdLx^=o5|%eb?x+7j6aCu z$hxmWlQ!<#WvN*mi_v-Qoyftk+fk}zKY+|GH{UE{z$Gjby!htWYk|`Y#!1_3(2M6@`~MmjXQttETd|g$$KpEN zcnx*^It-LDEUbPRT=4HS^-VB$^?G*i9b=UnV-}BDWL=N{nM6Mtxo&?M%v1+mexq8| zEMdm;Xmunro@N%CR_8E&u7Z>fws7$=(%E^PqbfBklnKzAf|$Fcy&&0knMD%O9_`X_ zN}8p^yfEa|>0A-lHG(TMo~lC@n(8vxi`eR?KM#rHcuXk`^sz>0q9VtwgCVZ@=zcgU z!otnl@r#4})1Fm)`{czLX;ztN3uCqCtb=T z!-SRLib%Ow@z=VhOl1XXlLdC%cVFEU(bqn@-QS>$=Qh<2WYaUlel?gyIff z!J`Fu)zw$?iBEijcIj~Wt6z;*EY`i`nzZ*c?&Q#@Pj)1d!^BYHnE$uPNd(6!;OE*| zDZ@;&gJyXmt+8H;4rE71*%DcxHD6&$DLheNL+>_&2KdZDu0JutTeddSp|f~Gknv2C z76aPwu-r7?+gIV5KOTY!#d(_|{OZ-u!W#M`;dD2L5*z9I{NwQb-E^HS+3}&XI5c=a zRhgzqo2vc~zWGgF_r^Dp%?{VSRc4B?*=V+4KczXtJyZ&ard(+jNnhpoNV&m^+?oo`c+-{H#`+9r1 zzkiZ+dV%$^1Z(lA_RldaCumEA=@)&RdF?$sYuyCDc;#9OqTBFWo+h4qW-+ADQE~KN zM_&+2uHF0*T=E*MvgS!uL)6q%cc1Ce>PRLAi$T*N$1H*t9C}hQ-gm=4^66Xt%XCzl zg&->Ipu-Wt3ovIZyVI1j73PJeT}Buj>_^HN?NZ`-MU>V-!ctj=OlcqhO@Bj-d?Z0{ zwn1`Kh%j1LX;L+HfG{Vqj$Ag&3P&1tCH>PB&Ut1D9Y) zlM2x;9j0}j!?_}@jzg1HL6t6q5QYGm&E{Cyog$YrQi>g}LoPQ;I-REMdG!JGw@Cd; z>D0+ajRVqfNyHL@{BmP*DIs3`uO=tY)H19E!}FL5NsXi$6_UKxWV3k?KDL06UjToK z%y^lJ$ti5#IP_LansS+X;0VxKwx~c5aN0q@s3`-j0Ya$km$4A_3YOM^HovcF^2>|^ z-qaLW7L$`xtX#R0si`R}%VMTxM7LrE5}#440KUgeLDQb<4Jzy!3Imk%dSfD5o@Zm{ zTJi^;!nS?3Za$8P6X&xZ|1fu6{CplOYQC~71NZF%@h2Yo#aq~%hl81En!4uks|We& zd(Yz3-A%my=AE#=gWo+c$4MKL%y=3d7+%e4&2%Nh+H@D6`{#2we`6~%#XJjMj<_Qb zB>3>VuQub~36srcX>((=29OoUacGwgQ_8C+zKSBx+OmQ_-tkRVq+9WdRg}syISS9& zn&6&aUCCpEMgF*Fkh8aK&v`3}=h>nGF&VQ_frrmMvk`E&Eu(@z2-0 z)&3FlF93-N3?R)n$37o?Vv}B)-t-IiE9uW4PX&z~cU5xNFTD{Gj@ zF)#DX=~YN+Of755GV_07jpnae9_z&)p_wIXT;jC=sVOK$v*Q@GN8N*+2G7eftGz%) z&|$%=(&M^}Yeh+!4RKB>q;!#i+M}&K#)PDbA|f4TktnZ9v-D|~3(N)8-@oV4C=VYM znzB|w2R&~1W{zM=Lwh8R&>H+4mtFo3h&^cM}bTX!LODdSP;Gzca$PQ%7J;PqzRi* zRiNybX|rrB$6SNT$O!RxoUk2Kb_29|Ye2*wJaCxx>(@}yn&LzOTMB0InV2Y;3bSva zb%|~|I>dnk2e9oB$z+^a6cJn2@3D{q+ZHrw!B}B}8GI(o1)6P(Y@tAxj8pPq zO=pjRM+frxwIpy(K}BfdIz$UL>2!i`ee3(UZkkIjxrFSf5uVwwVFRP1qszot;%SnO z#r3r5X_J%2*VmLNt3;g`Syf>~+jRH#a@pH|&aQ(Pzn@iGc<|$=5mI;2z2O|L{Ov5? z`RFvg6a`uWsp-?tJu`q^I+T=I1H>_nwimmkjuWGZM^Sln zI%%}>j7sX(Q~A~}_jBWyA20@%%7Y~I|K|%xRHm3^6F1zngP+|Mcu9GJCO1sfk&Js; zX0=hn+L6oB;x2F~mSFp}KY|GX;~rR=H+1z7NqJ_ouD|zDGd^21KofNbWProDhiG$s zrgMYLcoo(;>sXWC!eq9>ypW`18X=&FA}ZoE1vqLc7fdBMJBpMJmYb$onvP7TSRg9G zl(fZx>@X|4!_0WYM1@HprqnQPZiM~AnIKURM{NfBFJ!6LHjTw9_+r*yQ}24Z4SunU za%`RIzmG%n^glIavRWm-26?Do7o8=>BrryZNh(ugge>s=Nj!fF%L2<1CUCR_ZI+C+knZ%zIo zgV(hM9;R}tYF-%~g2OqFwHr6^iTAyYgZrPPx1)m9r`1wsQ;dpP5gV`}U-8Qn73Z56Dvb&#u+T2R}@d>aTewgW}B}gu-GR!Q3ihwzl zBcd~0w5=5(G!d<6mx4K!V>*|i*A25F9bt{6j!UhzX0_Igdj{Uu;kcwzF@(^RbdmMl zVaA3Z!}A8|a16F|==L$1_fElEt8Gy$oddRJlDIkx1p z7wTOQAuKF$^n0}*qR9^-f^m8DkH89k>dAy%Vyj^7`j+11MN z5svEd(8Ja>d(3A(^M1cyR~aUp@aANrlop@Is#LH49UY%iiU!Nljj^^Ss-hbsPL6Tc zAfGQWFC}%B-scyE9-;+~S{5q{K|yJ)ik>1X8igJdl~8z6PoHB5Vz?m^QTHc#{tLb? z^6RBWA*0fw0RhDlxTDNVff5$8r7|doyZ1gsSwLW|r-V%;o}gUnC#if8dcQ3piF9^i zb+!O5Sb7cBSzU}On`~wiaaBtT)<2I`2U>daxpU{E-28w4iBEs&YYYtLNT+R@A!pH=Lk%_7nr7kqh>Fz!S!!R+;B!>=- zl1QiVJjJ46;QNYMjL_cQV65md3luy>5U8-xHZ+oBh#IpTk4ewR^K@ACf>^@yJmyfi zVJK`61ej7%FC~#6U}9o|!pMk5{0#$P7_45sx@x~Jgh8O{Fin&8ut=&8GgKxfT>6Jb ztNN9CQ*xxJoybZP6BLWuaV(ikl0S5aNzV(vZl&H7%rZsP45&*AgkkXT!%yJ*b-1pB z>pE2pSA|wv7YJfVrpoi2d+vo?e)*ME(Q;R3Cu3v7)!~tosjn3 zD73Y|;}o=;)aFaraMMqCax@Gh>ga=FJ7-^Y7p09C(fZ!+^6&qA5JVQtaZX9=ys!q# zVvc3@M@q(7Yi0Q8XMX_edLcc;rc+1t8lPxq>nBEe+duvk&bbf{{)%hX7WwW+u4Xd- z9EKfb+R2B_U71sR*N1ux6|R?KH!07z`qkQ|1cC%$3PD*2c8$T`-uY|j*aU|LfF!6a z>p%KqK1COu*ZhzlKb;1A&OU7|=k&D^QHsfYo>Yhc#|SvBC(dk(&DPKSKPYB3b0O6Y ztGDp2Pu|BbtSoD<{W|~trKjMObK$xBx%F+=P%h<}wxWNcCS~b=O=mq7HYoL>UPVh6 zT=My`7u2u_A(`^aq@+f|E83Wzo=!$bN0&7!^+Mt}6B@d)wJqah-a$&iD_{8vrhMHQ zy7_zSlr}&F%p2@642}pKz z5?4uz!+9DKiguwWs{_pXN#?C38U#drm#FVDZ3RsE0WHFyQCdu(!q*w4L3vE(i_}@| zDC+32H!$ruK#~?=vxva=9j1Ngus1TN@++uc%k&2E0viDp1`bix>{NJuv6D7?CqhvE zG>yyAQ|)7IWZDfUoC}4Gi;$A$Y!=2xi4ibQfYI29V48Nb4XFYYl?l755pDu1s6Ou) zMs?a=q0B5+fs~+Hz#dK80cdPAwQEWMGm{>&Sr?E&pjb4Pn3?gAGg19`X25iX%N;sb zaoA^CDaKvJ(9kGt$t3RhH~|6OYgREC%<$CUAe$|zpY2c{NV3XqA}Bo08vAsHbI;M# zo1j_r5Eqj`j*io#Og%P%5=~lDB?OB?>c(G48ih`0k4lB_3t|?;khs2!ZEH$kZr?Dg zdNa%lXe3Oh4X2CCP908IAW70K37Q)l_^WsSHNUv~Za((G_i_21>N(bF;kX1U0*a5w3atd=`a41C{Apz~tCCbcVL3 z;l4laIz*Jh%393%>ID=#fA~kE=wiuLOgbg9*_JAQKcysXRu-j}SQK&Q@NpfV4m+!h zU*ARA7E#}&MF{46H>B%UkZD0wKmwl`<)VnPq%2}W=l0AA#iEE)kN-zKe<>v~B#X*t z+|3gMHf6eKvkWkoz*|e}jrZ&8CfTb4Ta{1e+x`cz^{2msZ`^nqS6n2)wV-1Qoi{xJ zX^pOM%H`m>^t|^s+6_!t;2+|GY@8ol*^COU<0Hoi5bo;gWinsj*}*(kB8$rJW4e$h z8m^HA-z6d>LYOonn8PE6qTY_vCKDXV&1;830!$N<$t1;Mk$Epb83txD$=J{#Vkq(l z57D=}9nbff4T_{&TbTnI2=F{;PHIg_vlJ|N0j6o;c}1Fp0f8c!H1Rx*x+vw-WC-R$ zJ(ejX$^cU&@jQ=+@-YmU4HQx-grRLS2!nrB5HO9R$F|vj;DFYSNJ*d+3*HhD!yuv* zv&9LTlWC;XS|iU>2(d&Y(AQx^DH^22o0y<5I*KV}h~60N-~SBdDa936UcwK4{zFzL zQxuC!M17A{=_F%APt($Fp_HIe2viuXt1l^+IRs7E%)0Z0?$QVWv!znCpi_$D7NM0r zYVicMNJJg`|CPV351mvj+4i63e?L4^->qJQQs%wm%%H-$Zke{eiQ9Doc);xdHiW$?*K>( zM*f@o?s^xeS%PUNM_?5>oFAgY?q$|3SG8~evu+v7`Jnec001BWNklL9tB@yBlDne7L;_(S)B=;e#=`5#E04#fff z>F-YC+LxbAU169hKaXv9h5Gj_3%(?+azv~?_?-cw%%?wgK5sgwiH`Sv7h1cy>c;;8 z&Id2g%iA5ke(TM&7W&C6#e}p-y8My#+y7pZQhEQf*(|fJiy!LHD|M-MnLXJc$EU;Y zs%A{hgmuM2Jb@{f>7bEX2uE+?^UQ?YvTLusnj3ETbH-g4*DYy*n3VYbd^M-!h4R~K z1u~Tayz*H)jXSz9S8BehNAdk~IQfW%lW2uhr*kA%$B0v6$j=e!j8haoOLmk7OHV_} zp=f8?IY5UU4HL;>4iVbA6`7;RjB<%)yGVBR(bm<;94=G-0fY!x6aht1q%4Ze%Oxyp z38eiKm`W%fl-4*Ex(>1tjvtC>8LHljxNet%oL_+R#BKmp?{}RjCr0H7K&Qa z5Cp0^32y*mbb&}hQsN1R(ZZNsje!6&O+%>1Snw1}!XVz-N<7&{+-hY;1+;apXTa6( z^|o%!J-&SaikWj+bY0eTts|)>h^S%47-c|M?0NV}Fp`|1l3}B#h$tW5pC_UuLfFKx zh$~5xZ8PpF%0kj$Wtj;%p-pxRbKx~mE11)cHv0W*&e}+6ladyVLh!!7`+NTEWiR8p zE3d?LeeS#Gm$c#fWqPEuwwiF7wRb`0{&lTUKN1sCw57oEpX?!1#kB2Il= zpRaVnI_lglpF=e>!~Bd_Etro+=xT=*4H(p$q6Rh5l(0F1W9$dP^Y)6`!h2DKHl{*T zq>hWSD1EHT&lim)454Xfm1ZYaqra-47Ajm@nravv=bAZM2VxwPj#Z0{2xF;=mMjYW z_(sj^o2${W%vE2rrfVIoIjJ-zwGCk9c!q!`VbCNRX%dak8$u`*gpHA&Og0%(clt%W z$m>I-PD+W0MxR&Utlaxoey&7+#Yt|U`scH586lui=;6hJ@6#*<^}fTLGk`&kSvSX$ z>(U}D7JNO4)|SOCmV#yhQQsjWMHNvHLNKX(8r>Z2LXyA){E+&q&2~zEf*ZW+Iz*Hp zCGDz#$wbNJ$nYQ(cY%}BO^UBzBBw)FAK#(#6^cHL4nrUqE`$`W@c}rr16&0Ma^Uz- z901>e315G2Zw?+C;J1(LTtWAmt6BS%bC%ENFzgn7^s9$>rcmH_k33Q}yCF0Hh@qHu zN11j;iTZwZa=d%@F6t$8b+==uCFxd+)}+MqrZCO0u^t~`Ra(*_1m~T03eLzO8pRTg z2F!a?#F%1ke1wRaVzD?*f`HlL1Q9hwL=~}6#PEpWQSVI=QTpFTu|%sSXc2;_uZVhz z#iCEt^N1_OQqiN{Q#2q#ElGedz)G4rpwiHy{n61O(rJriQX)-3dwUvyiScnv)5I3A z;7u?+F-n4f1T!oZCy4svWKG?mSxJ**m}U>qER(dir|IeF;QWo7dE|lZ{Moh(36vsh zwqjY5^Umv~yStuxDOeN%Gs?&Ji{X7!A!U?gQc@q6>>nQBP?$2VlnMt>vTDt}D4yS- zRQ9i0H05N-%83{iDQU6bmx)m%w|ft)*#x+J`u*+YZKW zdpqUa9;TgK=)&5GZQIp-zs0tBXx~m)y#ZElA*o<)XFu<{@+uhF2O`h;MxNq-ev~tD z8Qa}YgVn{jYmky%EckUSiYSdDT6KV36icBq<*}QTV<9WrqFXVed_3jS*plG>0S8() z@Y1U>qYLsh*;Z(jFpuFTaU2Cx zb+9_hJ1E%6}gB`dCg`&*Pfcyx?OCF^?`P>Q?9>>cdV^AXw%5 z^xAQD`$IHzbuytO{ce&6?iplNdl#?jSz=VSki;h?@_^!jeI!yonn#Jv>*Qr#`NbnK;9A^8W3!aG(`Dmp{K? zD>Et|rZ_87GRmURLg58vuqXwt>x9Uq#gy`yb_&=w)Ky&iq^vp)S(X)|p_&eM>sP+Q zU)}Idq|8z(m9cFbGb$;JI%Gp?L+{!RKqFC^LFH@UEQJmY8ItDjtmX4ZQJ?8 zfRQn6-+I8wheBt85(*Jr3ae{f5YF;^6NZ%`PvI2b;AFXrM1qw~%F&HMMReX!%}-fI zS0X_ji!2@WJeI}h4dHdA3-lR1aSNq!RV2a)YO*5gmbd?K0PR2$zfH~&5Dh6{hA=>B z-AU}IMyi4sR*qXKG9tbrUupbXeFAnQhXogRfNb&1(8_{dHB;|(_&N+sLGxb zgqF<9I-ZKbK?tr81OchG6eCLOR64pdEGVC;Fk5J*jOOFpzo$*jmSr=Y=7;N&oc#help#mQ1`PX19JS|8T~O6bX8o3yz4zIwlhn6I_1DCDcoaM;hMd4^=t#5b2%y{4Vg zxXW4F&f@-`-^-@6&!l8d(A}P9baaArI?3qB2r)x2?-i@AZt-N2x}t|^N+!l9hyjjQ zq|r!Wh7D*r2q*`EZW;`O85H%V!1sIt72t)1kLM|!duV71q)>uL0Dj=J;34gz_wYeZx!_{vLSqrb(5!;t@d-vo4j~M|$oPKFz2t0~+ik9V z?e(00!6g9f@Bb~vU=+6)t5VM@Y?VSttMuJblG0*zXD?F5aU2)hmWYtkUon6<9?gC( zJlDs&JddVp9_ttjz9J$($}9)>4YD@dK(C#Joxg)Cd!bavv@!@snzf5Qm^cikB3jnF+hYER-d9F^e)sd&GBY?x$#*fc z0b~9Emes|ATLL)*%GU0EVm@Ri$dICzctK5AOavi)Y@W_+2G`A_d>>m1rUE#pOHxor zDErXAwh!(b=Csv{2S5LMCQ3V)7=$3phD^Y&;ioA9tyV8F=2_$V?3aIvMn(LdgX3*UEX zwQP`r8Q;eW*Qb=?gvYlM32yz$x47euAMn)P?clp~cDCTFl`dt`%G7z*b+N48(DpIU zqJXTOA)>TD@>DgUa=vOQd~}ndyV<%IpjQzm6noYFt`N~MG)h#(^c8PtDJAp%0G^B@ z>@FV6)$y^<{Rl=3@C5KE-{dK{=sIqE{1m~sm&6p z4a+&v$BbGw52!dORMK=^w{o*rp~K4a)8X~kf0*Og3*|W0{(CGKxiZ> zv+vP+`SCqJVaIRorK!aV0~aO#ar^E3{Tr_3_Pg)KE%|KQnBgsNdj;S5#r?eV^|$b; z3tq>zOPiU`9j4B#=RbdS07mP8fcL+qiMm7)r%;*l`qdlNl=6uQ7*%eVtD}9&7nF}} zYv^3LIvg}2my1Eyb(ur4x--L}{z1O}g)j2S&wYxK!C~wc8>Q;lw{IVF1ax(0nHPu9tVd&jKMZVMGUSQCv*8^`|JMPmtqWtxS6P-q6uO- z{~;38)igyMo5p1Rtn=ibGt1fCHA}pTUw};dF)>HHyX5D#GGRs%)n`6O0%wJrxju|&k9GJrgBvJ~- zM3%emon$(IKfj^_Q$P$WME)JX`r}H3aI!6wpcFO;V_{CqYD=)GCBr8^^EI9uI#9LY zo%B7DmSol)!fdyB$$3}NarN0KC9td|K6~r?=`znIEs6|J7-W(~W{U<^axKHbvwY#> z|3tHhGCn-0n-Mr>3OYanIO3P-Xz$|SSb+x1;-QCrL#t)cv0(%CQd0Jd%=kW13ZzW3 z*O}*wpSq2m_x+alf8Ykb|NZ|Y)BSh6?82AQVcVRsc{3ncP>OmXc>K}dGVA(m+_Z^g zCR1G;Z-3AGD7g-<>(klQ#aKRHT_+Vfb;Y2iqR*HLt^2k0Da@9%cCI0zbpcalA1h&1 z@4wRpt=FrMOBTvL4G9ak|oy$dztio;>k3tde7A)a7$D zXS=X08zBUQaQehyupDLP61CW?%>DEvFF(Ny$9`rsUFBu3=ue zj5yt#W=SUVV`Q^^%qWH9_*xUC6b6dC8pD^qw)|I$IV3T=hh4cbFl}fL*wEv#f6oq# z?2Bk|U825X!4lM~=%1*rQ#JC0KW%N;(vqOLG0x|1{bz3Yi@)Gde?PswJ>+sZPU-4m z+;vX47M((YTW7Gt@?tG4I8`mA3Os}*XN2rgO@ypDiix9^tphdG5 zQ+~N-!-&^xD1Y3GuSHZUzRKdL7gObi)aR5vOtro~p*-SN6zVdq1?*VI6M51$mqMV6hQVt^M;d?R9++i#kU%z64arfE_vhJ~1^1@?`N z2EV-bUM{@w9DeuP$H=5pw6-QWeE2YCVrRDq92o2m`S?+!lpHv)7b}_M$j||{U3?yQ-~DfNbS$!H z%rG#Kqe&RVQwIAF+|PA4UQE4Q%Wv<07^M_<+;IoD-14avVol4ki2C56-2y|Uc33z= zVJ5&}+4XDXwI75uDZQMR^%~3Tp;}mr;~{>*%A#FWitNyl%3QhES5SvqT2xc`e=pF% zkHQdIp8|MCrkD?(V*_@`QKl}h6{+`SIx4x0peQlKeAzXK!7oD@2Uu=JlPkj0*Fo(G6HD{1ek_3_o z*CnESgk0i2SMbqqZU+?SU3xve;ov8t=4q70Ke|zwQ9jK=hRBmP#Yl%b#~1;q7C!uu z_b|LT$7PpX!rNc-4)*RHVEyS`%%~`5p8HyU^SuXn<7L~RJkR3~-A&8TlQgfrh*__W z^EbrFwl|UB6n^>eAg8rQ8Qb$~TDmT-BJP!jv7%>))FSujFt<_H<=&s&!xk&x!nN(J zN@s~BY!2mJ7A-rp!Bu!dGV9l|AUdFN9Y=~j>rUUs5AXUp8JQ%uWfO0?@g~-;-9Uqt z#I_Uk_V%)N%NE}D?srpfnzUIKLqkJsIsbe*Y@2jC&3Kr(Fg!fW#*OP4cik}CMrVsW zv-?R-+p>wL_w8fLmUEeL2FTi3>ZOnGE84PIGMNm8g05K{$EB+)OGH6Dq$w5(1(M;A zMF@eX6m?1w4Jj(75Y)%x%$9V*cQTXV***PL-Crh?p;Rj2I1WGm#eL*QN5ha%i)*jF zlFm-;7&$yV%uDxr| zVil@d@a{h_#B1Kzi$rPz3*WDzAQgwD6KPJ4*QCUb$BsD0@VG(wEJ%rEwJ_z^v0zDt zTm{K2D38D@l97rYF9zdfIB$tjCFtzBh^#8%ZQMwyRAwY!z_Q{bLUW)Q*Qf0J?3XT> z9=JZ=&Y8@)Wj?iI7p%_W_&L6}a~=B%14v9dRV%OPX(7Q71%IA7wj#u6O;e(qm29>J z*Y#@xV2_^z*BFM9E(%FLUqDJhA|Az13d~08d(WhaW}+g{v`mp^F|kBiDlWD=nHD8F zdNa(ridlCa%kB#II-hw3t=0r(zYeC-Iwuey15J3~je^Qj!XldOB@&I(D+P;cfG5Qg zkGf?NC*6NeKBWFbo0Q5>Ja&TLnHnoFyExC-Sb^z+LpGZU86Gx=^7-Q+Dl3OsV`F7z z-4ac;!&)G!r~ct0sGutPg)Fg9lS1yg zB^s>+_+`HQQP+0?InESYhU8rbI++B zfB9zRYZoR0dV70#-_19(XXg_fI(&%Iz;5d7I3IY&kDy}%Bp>FfA6<{k7ig1L@aUrp zT=JDQ@ZtTu`k$X<z#-E|V3fOt~0+?AE z(g!&5z5heP_Zb}P$L_h5q2C^1bzdLfy!9)5``iB?o;SyV;b9sD%v5z6Cp%Hvr@kUg zu1u3QZd^z6xtsXeFCQYCZK-Bg_@RT$auam?yn^3Hhf<4(=nGiVU`hURdp~h6%@IFO z4#5HX03XsmkqO13RA5F}wQDDzxb!qmwRM(CM%wJkm0@a>gT@9@Q+vs#1O+cf+%Pai zBXjBq4K!*CW7DKqoI+r%5LkPjM^|erg;1niZI}(0^u>AW z#Vl}#{#nwpmvMJDsh$=d`qfW)@ry6x;OHnf{p(Np{DxQZ{d*2@`no>iMnF29Bx$ws z<9qHWYG(NKH-5=8{=JwIesk}=TzctiQOaS#AD~gRQ>QG(l}|FHdI=#QX@Myi9iE}B zv2EGat)?+Bgb`AZ^m(83rU(K(FliEv1ZsvD3Ns}zgw9V`v!;W`_dKWRNGYS5EfNcx zRjom)AR{_oM7t3M#7u*+sVQAJ1|BKXqyhcdAP`0)2L}&h7zU=9Vrt5xDMUfK*SF$% zs*3b_UQo?&agR)4HZEtrR2q)*R6s1GC(fxL>=Txof(nvS)r5qNiy3armF7%@f_5Pc z8iYnfs1eo&!LrqIEv2j??pG)l!v;r@I(2TLW!e22J_l!ewvH6Y35a#)tdtn1>sWh^VMZ{C)L>zA>t1d&h! zSt;;*pKx#Us}zFDKB$z>lpLj@a|>JF_5`RGL2wt}d}}l5p4H5c&GPzh`5^mv=_mf1 zv0Gk+;g6BrnBm4BJ;wLHIu7gl0E>;vp@_|>Qy|{C#B?Et-EtvszwW=`vdiJWe#v>h zgN@*bDpN1_)9iQSNl~59YSWMqwH3>I?XuIOk7e1+x^76z6eN_OC_o6G#_-IIpin|1 zv!#q6A=-HGn|IQelngkJv+t?BoYid;6$U^4-oLVK>sAng1r$blE%RP45w)Ln-D_#G zqBIGchIl};Il`wt@M-?R`#7bNPlKiNk1BTF^)+G54dGs2#9|eBQkKo|z4I)ZL;Urt z`smLO5py7-9Aa32MFf`x*CB1&94t;iTL(`cP@KB?O!hzYGrswmuhZO|;uWvE2&G0@ z$ou5;qug-A4ZQgc*Rb`JZj@4Fv)$}_`e{D)!GGYr?|3tY5C}t%&35zo&wY;JBS-k~ z2R@+fiiL@twz=)LZ!kPE!e>7AN$%YJeN^Bf41>>n{tF}CxKDcSx=V!ru28x%{`q2R`=qmcqs$f?u9q-!}GE{wV;g;8J z?&qDeYG~Dp%udfOxVThfDx-JJd648M5y%TUg5al=5%h+1hvQyB=wj%r31#qsnh>X^-I z?3j(Ks{RuXslAKGX?99LX>e@$xC&xIqDyw`xXh|bV>~a0SVSU3l!!Y@XEsXU4Ab7( z$#lR<>enCsVX&$F@8axpAwbrUQQ(%GVr<*fD~ilv3RN;m6>#7lD}u z>BH!D2ph1)pj|%)^9Y9zI^6icogCQyUP@v@NB{sJ07*naRC2?^?8)tB?Zv$`{R>1q zNSP@hAeCxkcz6o4Ger~HvtB9f`l5@~MpTU(5^TBbDct~jo<}OBljl>(6bqh5DwU+!OfemJJonr|{7Ky$n~f%O zp#`>SHWEYNDG!Ch5GKMfne&cR*WJ;XE}B+mRNtSfz9zi1wToDw-N8Z>Wr5(hBsh(- z1jLlq>_ku~wZwvF5Yz;tR+>d&h|tniYi%k4su2YdV@bQ9O@;%PqDyH4rb}g}e3!Ud zrshZ_v#!h5jq9~db&JK3;T%dSI(oB=I1U|l3rhLeS(`*+4a393(jXPj751^!-blIsx2)Q@g|j|11g+g#yuL2WVKRWk&q`eP5D~JZ za8F8qs1LPu(z0+I2g|Z(R7$6BpX3G*Q3}Hd_}vo^^5xHb4ZEj@h4%grZ#5E>8;>2q9}4vE|q7g)i&KxWnb=_i^Y^g9W3GGtSw}bl{PcNur*@Zr6H> zb={}bXsh&4LWp{lQf%0;fn06~rF>djQ^zVFhz*2WM^WYU(_@F=jm+VOow zYjcX$wl?zlA^J9K28G())|c<52qu3gKt9ULA8dlyH$~>*U2~0oV(p z0$f{f=qf~+Jpp2=0+GYW6O7~&%=E58VQPa4VKIjyuM`=%N>iXl9KA%7vRd$>6c`U{ zaTiHg=W*8B7KCt_!)KOx>Q7R_ma5mUIOcn{2-I1Uc>)T`Cn6Ngmq^JXhrI#KzByK% z6@<lIL?VX*JO6BU{@%L<06!3igNj{$s6F8SNFEvCz+PXTi{c_cI%yq+H zrmDCvT162C1_oK3?PT07AViduv^2NS*T3uJhUx0+#P`cOL}zC|jY8l!1$uio^6h(` zfj~m5B2585pQoeiJRWrNJf#BGlH%iUdpW}W9~xv9yk|k?5#2Uw`(741+WE-8JkAH- zu#Gd*MIJdfi!zpAxBw5V4lyu~{Er?Y&judZeix@~6a4feucgiz=Fy$cAjA@jLXgdB zd(2!ecM{hF!lrE*k#d{@uItj()kQ8hhLnYB+GlM>$sdB6oCr;sLxoMDs4nC=6hgtj zedDiq)6HLmvtI`aZn$neofEq#(#hfWK2~|ZL7MF>jb=EvZyO00>IO=*t9G8d=O7hnkV>T}Pfb<7uam!@FQTq!2G%z>Gh5uj4cESj{kykw z*xf*R*x}5VpN4I_%(^bKZh>999;a{3Wt@Hb8Th_#x^KVz2Yljlw=h;HG48rd$ud)m z0kf`P*I0o%OCj@vm_o52C4sP56c#B7Grmt$q)*ytDs^lsU)8lEKSo_PgNkRcEX67- z&Q2$f%yd%UV<8J;BoZ(*R^a=$eubp8nd~n!?TlerA7L`@Fi@JOKGVlD!(%kdDBCW6 z6_;K4D($e8jdEJ&1=LAUI1H4=G&TdGoUy)v z0pH@uyYn<${8DDG+6dptf~N>dNoFmRy=sh8H=e`iA3eeo6F~6^SbHuE4Im}VxGoF6 zAfl2q*~`Pv6VY`SLs9ya<5%}9Kv|HX>ySk)jKjR>qZlg;OC<)Mcj<@KFCxXQ&t z5gn@|qFl1=HZ3hJOq6`~=Z2X>G2u)QLvg5o5Z5iS(A&u!cicsLdpEPL9v+z478ZPW z1@)sgoLJve=0Su{$dGiI7A-9{9ZCTfzL&3_^BACnpiT&+A(#;`ZGtbBShsE+zub2} z<)TODDeX**9wMSlUh?8C)S)fX2lwvBvXV5}cDT;wNhU2^cY3gbv&0 zHxE8YOM8+-qfzQj$hNkIRAhzg7HO~~W}`uQYKqm_EYI%Ui!cnNlq@VP(cYfscTYS* zGN}io>2xbolaov<#hPrEfq|SB0jHDf>YpatZZn6+f&I_&7jJ(Hx83$tIy=&|hA5dZ z1Pi{;;P4omH*dyuCpfVGDZpUsS!dBu2PwJ4!w){dl2~HHsi$E|$>fxWG$oTcUl+H5 z*2c^h{pv(}Ucllp95zt`0+_Eg)KI@4lV`z)n1Ff_t!jRnY>Ovd#p#`Wx)2NziFsAW zLRr(Mnrui#1+yYbU7`z1YC8NTk>!Gym-sCf_;umUNG=!jm4T`faMnvXbJIr5OalvL zi+TlR5htSNF@)kJi5&aC^BNjDd-OHpyTs?`A<@F90*lw;m-Qj%fLY2U5=;2LARlyi&p{ zp-3ukWup>1VRLda>QWt+l|U(NS*%dRd>@~HS+`6~h!r+*Ga=u;lEETnoM}h#bpIY! zXS#45mvY&svBj#2>7~>~!Yi7_78zK{Lei#+_Qm$1Qh5mKkiR?@+HdwX$09l^;$F)IQ-rJ%RBCq!Wc zww+*LU=Z8RRGqhK#rpqS;`xe0TO<@nzj5<8!N0$WxBl&~Ah7t{b*~~l)_{j(DziY7 zy9Tf*m)mG*X<>MH54YX+_w==&!n~(A{k7LKKQl(_hF;9Z6w`sC(KLa8c*?BOVHP~? zHlz_2RhQyIu2SKS}%EHHvXGm=BK@67(9D^Av&I~ysOwg)K z47GtHa`XiZ2#$XZ*7f!<<;)WsD`Pt);u7Tg^?c;s!;J5q02y#a`z(Kd*=mIH85=9` zyWALyLNd``z!qg1dNy(6KYpGs-TYouVSsVpWr75j)y_a3KELM>&m<&o-PFwWnJA5= z0mjKQI+mm(v!1$wb`%rQsNQhRG<$dV(`2loY*aErmK&7Cnvg|dnh2#++UG;pDMrz-5K58LOd!DU202sX0UF zCM|r72+QtgkpKd5wEc5XH4s2mbU8JIWg(F9IKtP{*Et0dUl9|6ef#=JCQVK`Wi3xX z{Ww4V!R=ge#TCqq9^#izJ%%(*3?Ud986j$>*s^&&?|BvSKpm}?#kdOx`~$q^nm%HMMTQ4m7S_Z4_gu!7&K{mDHS*Gt z2jDahBi=_xK{3Yxa^(y+e{4Uj4tVPB8#(h0zX2o>)lZi!QuJ+Fh0T%t{}8p#J1L@4 zu?V+?RUJNo&XS@A1z%YcgkKa23=R*|y{V6PUGX+P`|*zxS(9Y&;9=hK+BdU0D;RN# zyzH`Tm}8!22L@0|@!*d8S-0kPPT71u9UUF~>Q}#DW@d&T{NM-pzR!$8XBt$qHq;8f zdQ~UnYdYz?&<>7=&_R$>UNO|m>7i9Ld>ujv>I_K|!3>IW5U~G1j^<>NrHCM&G7h_4@ZR@)gbPnUol7shlvTZ5^!E0W&*!Q8 zIHaWHs+(>?DMfBLM|*oag_(f$r*GhzYp+E_qclj#5C8T1lqcr7^2*mT?YM00-oRO# zwvb6?cr^lL7^{BnM`{UK(T;LLN+8X{yU@;sJ3PV*((TZLbA;G9flYdkf9{%gX zO$Q$1Cgq055X;wu35@vqc*eL!6g(G9p>@DTAIPKggk(4{b~U982}TkE?P!GmJt)B!1O`dAu3d2QNV#(XslQc(UrJn zs(3D662p8+`TA>N9i!B%`G)sGLurq*PRykf|5=bc8L8?Idf4SoCeW0+kpX?KgvF0u z+``Y^aVm?&@slGe5mi@X52j97XvY9w`5_w8g6o!0YM$n7hH0mOQuA0=oQTr)?@}(Y z;Lp=wCGh<+ZCx4Wa*BExrCtdd<^NCHna9Uf*8BgRWS*1EIg>dvnaL!RWTsh4lhOrR zY74T+CW~MdQ8pED;a=>q8Q-aD^XUwyUBbTXOeJm>j-zn{wGM6G@I;9wR13*=kS1ut7m^H>K5;^wlW?qU^O0x(dQ$dO@O@@%qEh_*Ln8a zXRz$lA4B9QmR<)JS z^rK8!7HOjhR+;8-lw>l?lvVzR7f?7HCYj6u`W#wTRdwR=7=~fYb>j|1eg1Fcq#P;) zZy`>4B$4CP_D(){Oc#Ir)ieC$r+%*d&hR8>?^X}bnp)1*ps65?y{&FSoC$xM~fDKctMkZz#X1ke|*tU&r&r4fo&B0Zg1_cvansaiaX~lL-`8FKav6Ra``bEC^qwjOf z>UF&9wBxw!iqG)%uU|*nND|aN3?#F>|ALPKlKUTdf`Nen8Ujui|9wZFN0U(5Cz1pJ z!?IY^=tWokP^{pY#8wtlkFKj&avxQ?%}iq>SQ>WUzJKbolJej`_ZbF_s-Q_&=pDa+lfbebbqE#r?5KRj0~R7#sd zz5qx90hMV*knYbT6lVgHNoO2bh~nIcM@I5g2BDZqGcFVY0S!&l*|lpojllr@*t7&9 z0u&~fHNf#^EX7t^Wo6Ir0uRjchjz3P)v-uIWE=m(B}C0KsNT1g)KDtzj@fD z?IMk5uh)6h*aWi~E%O*-=Rh>GA4N@bjnxy_Ou19Wg%UE%17*(AL8iM>Q7IkJiUZvU z@zhg~6N}W-*3?8vTHJEmPdNGHV|e1>$54cgEp3)BX{CGD0R25XIrqco@y5=bY}vBK zq1~mD)F1m!a=D^Qn9`k0FI7OsV9D~MsZw*~vxeI#43oDcraFjj6{%L^OqVBF9h*QY zK24W(3~2V;!RT7Y4$nwQYgER>Vt#R16foX9B6B4|tplD1IjYi2^Z@+&| z<4jeAa6(pt?j&7W*4y8x{UMf}@E*Q?%iZ*(dhs$txesWl;|D+Z4)J(9H{EnInc^gk zjebr$?LEBfooi_d3Y4k}UVZfiUVU|j#>PfUr4k#SdXB?at)(H>&S)xk$fnl*=K2K( zXgT|yX69sR6ARX;*CkKdLNFu*$O;xkR007H!>_;Yta&N%cvSR|%9N!ttKPWq!VBjN z=~7BgIptIyee_ALxZ+xxW1Vvgt+~0Cty_0;%&{jjV_AgNc7%X+>&~RRdozuVG1}WZ z-RYdO_PjxjXnQ+Vs!F6WL~DCHGr)xxUBa|y23^%TeAOz3Gg+vB6)RRS?eS2hI#Yl} zOP0|)G(v0pa%hJYYmarhy#YNvgNonyP&+P<`c8Ux$=@bddY(d~IeA8Xn0o^@VXTfr_e+GJ;V#9t5 z8$l7$RNL!$|UV?yIpcS&tzYEnl^b6qxMgAi~ptn4T z8wX3934V zQ6wA=&G|J{;ROUGCQ(%{(r~*#5`<7$v3xnxhQj5ioyeoN-vlEWFjT74IOB#yvut{W z$;Rv&zHrW6uyzG|Za*0!0^~~eTF{$4ONF2g1(5!B&^5ZEHv4w= zahM9*5*s<^!|&mNtM7wlOWi4wGZ~uY%!4x>$!4<)P@?ip4xbi6gb9cJWV2cKrXMDo zbqHEcNZ5fl7*=6@b}&wJn{QS zId%P+WKubfIkBC(s29V?B19O&u!zUo8P28MmTyg7k};n zkZT~Ap&_u8)vQ%8Q>njO=~8iL9!k zqtQd&lJk>UQxerRCQBwL2a>+_-^*qLIA?(f)2`%8QN-NAIS>e76--BtmC4Z3(!$VC znn)xMkE2GBGG%XA9R=9UPG(8w1ogdzw80`w0IqXhyeZhCwm5Wq4m(&;q8AcQmx zX~W7T%gLDq+S*zv6bkr+pin4)=^WNVz94!q$k5ObleWYg6a+QL3o`+f^LeD5M=07{ zrqo=qAvq{NMII;*6K_7o$1V7(_nS=37c7TvciH;9Cd`;`hfB1+YX#}kPj319ddyn7x0{>T_t zpVf(Fr3mRNy~zME{q36v!ks8R|IE{T{L`Oyr)QGsLuOv>e=jJeQrz>`M;J8V%)5U> zn^MIN6lO9e9$?k`KgKB+tf!QNT&hS!*U9IS9JTmx5_kyve2fDlsS%p$8u`(!KO>dO zkxV7XW{X60@BYQe0TR-Zte8X4q6xeKl^R_~4+N;xbV@So1P3Ch78YPLBZRxQCik22 z`Mf?9q0-aS$L>TgLGL17dg(a;?)u{&3D-BF`~B#;&SQ@~hR^5YsSO)QCX-A6N3UMZ zlN&Yw3WjBoNF*HEp{}!i^EMPMNG?~VyStB|sxq9-QBzSdH$4r7LW~v5nC^RfX5&Uq zJ@r&9>5S2L?(C(qvWi@;NVz;oxm+aR)k$XxluFL}-`?Ggs_L}1$B;H;OQTExsYGf{ z?NCus!H8jz%H`Z_lQ8!@_#iV>Fq}vciN)B_(?cxQL7`xv0wr4>l($x;I#W}D6QnBM zY=PO5$^8mWH>%(t(0@6>+&Y>t$Vre=p#q85>w$s>Y~b`0+WA07gX?K@B}qU?2)xo! z!OTk-s|c#sg!M^Jc$S1874CG50mIdt6CcY@d`g_#@QNj88aFjl5;d z$>GOc4E1c|)aRagd_qtzTi}0ddA;|5b$?*SpWi*N&W3e6jrS!80eLG+jqaT@l2;#O zSQltk09AFeV#-1gbpNmUuXWy2NT^uu`>K?ZvMXC_6=8P*YEUUFs15rOLdUY4s0veN z=cM?D^f=46o2bbHyg3JYNDfwPER>4YNO{QN#6RjCu@6z;O?ze*d_OvJ5{CWoh2L-I zPxk|sMG=V*k+*-Hi37g<*?g1(108ie%y2e^uKTg1#kf(XHta{&{S>8Ril27nO+F#0 zQWX~iH%of)I{`7epJ@ws8si+so5PLdtum2th=F7ZRaKc59-6~po_+acPC52n%m6Dz ziqD)hK|sdY``~}_j^mCazG4}Bj2VKRF}`r=1F&ob6dYbU!vi1;biI{&-Os7fB9|=L z#+R-Qyps?5jV_ZW0$NIY~kqFm&#Mn4Z+_FoX_0O6R_26|J@qKn4n z%=CH7Aa7ady1L&2Iq-8A!twd&y6&cYX5E6tG33w6!sf=V2P~BT>Eqxa&iO2xY6Jt) zqHXzF_U1Nm_$r+V{FEe&NrSU4`~>60GE!RDMv_Vi4SJZTe*YUhnsZ?fOUdrU2yJx@ z)CUy|Y;4n{M)=Sag@PuXx<=w&riD&P){`iPIsH>V2IUkOo@8Td zmZf(*$kjJo#-(dl5J+`1UWDSSK9Jg6sNX+3O%V$SZ8K8P6!l|;I=JS7+aYi?hrP?g z3tv8oNhxVaP4kg+PbTu=p8QqJJOh>(}4aNBM zkADQ|dj9qDcD{beGMYleoZNLeXMS`O{PsbN&wYl|Pi!IO6=aHKd_tw#?{~UDg#wDA zkSmq&C_WU#oV;lk+dJpKP~_YM%pp_>JeuSCD5eb(=`>w#Ar_-d< zL)73k zoLL~*Kg`f@KW%MoZn0F)n3Uv7Tiv`9Sk&2uqRh*%On1UpDQze8alx5%VlH>Z`F(cE zQn_G~u@JAkuz1=3&-PrAQUi=JpBg-k6Z%-a@MbFazoy4sv;5pOuP9VYm{8_@Gz%xH z6}Bs8aJ%eP2XxrehCzFKj8eiPXPShX!tB_wgTXvHi&EY1zUX^0e0xX_>`f-j}`wpJ{>9ah6;QJZDRk08wn_otcb}(gS ziFP*9cKM6&dM|(c(h^QRwT(>CBrkO;)DR5(0^Siu2^HvSTq&xc;2nXNvwZ;(3F8wdqHHhBW z2BUkJv8SM_nYeF|hyJ#MJ(qr$yMFjpG%2VSU?g&cTbkK6kih5jL8(ME-p=m9-Z|rR zW!8bv;7X78pT^I7RD8n2w3y$8OevYN9H5QIglbJtgK(}>``~V^hSPx5v;Z@Tk95Xh zdqk#oN)=Q{ObE-}9PAGmL5vVuw+d14h_sx3*4t~!X} zeFj|}UA*ta2)ax%QZ7?ObpRK_G1*s2@0{#!f{=RXU=3TTzXj1Jz55& z(`+ug@BpVVJ9}+-IYL-eZ6n2V~Dj2L3rS{hNh2 z0%Wr}9)IF-R<2yh;q9GFiOD&Gwv>|?R*{JAN4Q~-xm1$ZcWmL9)kjks4pAv9+zCq2 z&1*5x-Bi)MRpfs_dB5DJg2K(&Y1eFfX>a>Z+Lj*&9WVy^h*5HokAE9hX22y<#dyAZY+9^ycFly#W zlu|SW8>j&kMMDTj=7p={uR)l!1j5zl&vuk+l^OP=Qrv#iwOoAR#YkY<#RT{Cq=-cuNm*ICx|Z|m z)*hza6xKI(Ca88d?o>yV8Z2V|M((+JA8c!ez-xTuYwzLC2X2QYYxwtHK24_F&VQX6 zA|e5E3q(|crc{zMmn8A(*#;TWeUir z3)lfkBobiKH0kf}M-h%m*C~R7Zc4Ra)HGcfgH2akC+W;E&CRXs*u0shwl);uOkhT> z0=AphE`$O;oWquxW>PxjtVvVO6Ib|hXrUJpO} z(}2^oji^LB(+OUVbv5$+t_bJZ2TZKJ? z#NN@tRi`b%Uo2v0B`vB!`AyBV3lBq*H7l0$?svbFo}RwBw$wkeJ(pw!$N*5JI66v= zgsQ4G6g>#`AfzR2D~~1=atK{UHc0?cL9V_;*U6cV!D)1~W$~#vd&59MB^zZEBkB|Hr zzwl8PZQ_exyoS1{mt-=_Bab|QM{{J-7hUur48!83mtJBZHOLX`)^Xl>A3;@Ba=9!+ znJf=IbT22KeliV#dP1QvLU_3K)>|1F8RnQX&OrC;tXZ*~Y<7^RHvWx}rt#kQp3d^+ zD@Z1jSeC`b7k?B*YoMhg&Z%deg|6#7^UU9vEK9~*%<^fcbpnzHAAEpEAAgLxXqbzS zI}TM<8R$vy#J%^T2!X2U*mBT8dD+h1Q<+IK4uzh5doy{J zD!_2|*lAV8hsTXMu-qZvV!Y_sxiV=Z#f$*IuH%t_VPFVBHIiy9DurMQm2pc_=}I$; zmcfj4GSa~LT}sE7BwSxx!Z6%>r=Swck#kC?f!$yUMvbB?;|ow0I?|F<%1KA^kH9c; zc%{U!$^=zE)i~yNW7n>fk7EHSrfJ+u0 z?4<;u3aW%V!4VFhVp7$CEPgi&O(L*`NZBmdB62r(*rFv0S4<)JcjjvqArcGM_M+2*?D&vMDg9?X3Sk@%fz~LR8 zy!UrKG|Ae(I?T`l3l+*=nHvH@w)<#+wOb>BKPmupej1XvSpncU6etY*HNTyO$ z3x|eNDJ?f~T`Z7nIpnjF%iOoDth+#+s(Q+D=v%X$%LBV|v)L@p-~Z2xl-ZGD^?qa~ z-0wl~)K9yievwNnsQ{(h)rVGtGRAKomeBtg*L>+c+_b)$ZI;T9Z+ih@y}(d*k|{Go zb(Pcg9?P3FG{h*|&OxdYs8uwE5<|4a+L5*-XXaTNY2(!mFH=bc<$_5$pT{4GAcVrc zz9Gs%6I(h&k9^)SeNLH@>7c^U(6DpxOcxj$$}r^~M5k=0YYY(56vo_%OPA8f?|%0b zMHaE~wHJBk;>Gv`y#L~lGFWytkJ02HpFI6&)~`Q>jZZ&?$0rB|8i_=jIZ9i?H-Gyz zG6H_{LLUTlUVr#(j_`Z<-HF$5`5iCt^E-OD{hlVgjec%jn{{-(=A!*Ba3>x2z>P*A zgnLuL+34qKJdQ@Gd$rxnJP-*FC$@6RbITGoS!Gt_HWTr$;>?Tx00GJS-VvrA zoo7UjMd*Czdtczh550owRe=m3sj+?JNZ|7Y9jvY`kqT5R+FbW=K93|pYgapyrs+ya zVL~bdg3a{z@4_1hvZs3&ZEbB-X@X)p!`ih+^4EtS#sVUdh%4nX85$nKG)-1DuVSFT zpT*0U(dNp>Hazznl|YRqkhaN~G!a5!9KpudUf|SIPi4%8iA)A>&;dV`^UnJ52@T6O zS=10CXF9a6O`Be#1_%a&EM2vX;o%JFkr5QdDa4eZ?;t#O^#L$}>Nk;XEevLKCLRva zOHpR#3T|g|PRv4w&$LbRsIOWVU zn9!rt8k^8{4?OtIv%u~M{pF^!tK}FP0h;GP_Vruo2!(pP86KdNnP3_fV_6!K7(&^H;x$Vn}}Vhd;5nMP>c^)41iPuXExV zr;yt68sEI}M*iiJPg0VSUwr@jtX{nWp$MLO@>$lNa4NA#Gyi(&MO=5?m8fbx*I$1< z>({Txwr#%pr7vOs+t=ydy`62_wsGaZeTNtR_9Q?5(e+&W)vxl|&;Bd#I{j=ex#W|4 z{mWnEJ?DIs3(h%*3of{TcOAWs53N6+PhNCBYmYvekA3Rn{O*T0vU15P#w2|B!=K}k z`|sep-~BF$^bkj^JDw&j!oOT{3E%tPci6LM4}X7R10Ou+T#~zX^V#43mRoN53HRN1 zAL(?O<4-z)D?jrEZn)tFdbaH3cX!;uyJAbpn-Z(h!?@W6!A=m4U44OPF3=+l%pL~OZ9CF70r@Niwt{3mC2x-lQ zo0rb;j{fHR)XQ&R$wZK``y{U;+i< z1fvU&V5$tdzmbu04%HuX>1C5d8@*)uvS|8pCiF7fyaIJHM2ud>jVvSTO7_YmAuO6u zDX0b$2xg3cQ{d<(6G+kqM0B0{Y?i&MAcN!xp^}q=y+W`IN42z18r0|zkWeY>nN%An zQp8}8l8n+Uz$*=^T~GJ~VorwV>>bWjWy)0u8HP1SG%O1-_jU9BYG++KBwOPU{%Seb zaIeOqT1WzAomyK!eGyEHI%_4_1@|c=)sUfTQu zOP0jgx~ok0=B>0X>Eex-UtwB-{{DVy6@^l%MAcLUmT6L}!O#;=;1i7mn_BVhc?BJt zp`jsgt5O+>5C{ed1XZ8~p$IxV>*?+u=8atiZoKJE&OYls#N&RZWfrZ`Lpe3+rgI7x zMeN))gyo#pYQtg14Qs!#*tCFYxxeXg_D1u+sQQ{KNDifcoIv7}g7xpRQN%C>33*p1 zTcfKOS&ROGEatERkvQM~@}ry`JD0;(dHBXxPvhqAU&AL)I){PeAiwy@50Q2YAx)!T zJG7>TV3090kHDrS)`Dr~@n{Mff}!Cd#<2-$K_-xMhWmodqc;Q@w{0Xg(GhG@EQs?Kbz&}-+Gb8>n{M&0R@9$zaQMs{y?ADY@p+8aXVY=&Jl&&!%wWY zNG!gDYO~rE0@(-whL|CZq^hxtjxk|!hLt7Lz8dAyr$K}v{Wy1AaTAlNA|XqHP$^H887daZ=CV#Ot0o|CQ)$}{ zX-b)y^HuC$3@cRHHXfgkeSLkbUcDNBBtUofE?Qbz7&QyDG`C?(6RFv#nns~epgz(} zCX=D1rJa1ibUV`~b%6k?wuH@_w=q1NLDK^4>E6YXB}*6{9%lK96^>+VWQ1s23)Lui z6oG9+M@I)QzPO1ME0&W^50gkFSh1pujwNl3Nt=>1DVruamo!!-6ns9=G=*^+#tY8p zqWLrwpL1Md2YrrNXR3?N@B&IT0cJ_&++vWe@`&?ZrVy;3rbB<%IGtEWf{O^g$E%(KEGf}fm>vPbBYghfb-xsb;H|A%->>1M3m zk6uy9$?sXusi&UFlTSWMJl;rpIKziO_&&C8-_EzLy_T=sa05nB^3=w^bJ_V90Hds3 z*+F|tCllB#TGYxdxBVKup^jYx!&F)lpHP{SZ%v(?ih6j>7-Uct5R8Id&zZmNhrKrI zL>;|y2(PfI7ZO`q^e~DqFiAcSXiZR1x%&2Ph=C&S&?1ZsJ;#OTpT*;UyNi|<1yIqn zAPp|kyMNyRYgevh)U?nv6-7~4eAr>^+c!*WR~M@fKb%e5chl9?MbF;7%oO&pI2L2c zqD9e8p8PU%nj6v^eaDr6|w%C>R;8xZ=~C zeDZOQpHOe_H?pjyg~JbD%DwkK#7SqI%(d5EOIvF*9!;Y@P|rvv&6+i9 zcDy~-P(1o&tit7j#|lm_uWT*eLc<1&9pCFN-WaMefQl*ou<*=(ZTpKKQ+n+ zIOp=;gSH5cI|aJ8aQSy1b+XAA0nzVVzyTc!66%{k4!CCKFa!iFwbc7&(OW&=BvS^}45FdlmwVU^oeZ8HYS}*b3O4a`sK3 zIiLXB0%^{h&K1ou*xMP1L>)qxV)D*49`5ub}sq$W{3o!-{5`c`MK}Lv$6Wd zXiz0S3ByuhS~z~D8r_4(s$eW@P^Ai5qaD1Q9ONCkPKD~AogF)cN|j|$!kK#cEP;?t zK8~5)Lxr`MxLedk^$h7`iV0K*N7-jsR3lJzFq2s()#%(A^rcOkQ8kryYu8e8&$3R) zt?uIIg*(`Alt3FcZe;bURfq7v9GnBVe?E)r*;)XV@kqB)l5UX@kH<(RlZ+-))Q0`U z<6$hzz%YskG2@!XCxJKNjMT*i%F&-UF5N>HEplPHEX@bE31F2pzhJ{zu z@$3uFBBjcVa5}XW(&6fvQxlkG2|W^|+7vW(E@5b>pQiRM#)gJS6bh(XBM(2mfl4z( zb(7QCRTP_n)NJNL1)gEe(b1dp(v={L!wBh^$F}$G?BS1yZVnLVhyEB3`e@mF#&LRpEl0?q{Rc!6zPko~Juc;D)c>!UTfJq{3J>No!*R z=|nGeb&Zs5NhBCV2*{L1XlQ6)@vLWGmEFt|1Q)fnplK>XwDR=R8;AxQ$mjF4w6u^;r&-jv zk~2;}i>p7io^So&kKAzm_Zch<@VTq5V9Jsh(qeaFCm*}$B7}e&Z~ig8y}iU1cd%v4 zR+^0YHet6|dUbLR$`8ST@8#fF2^$KJG9jzgD13vJO*HbP$^hYuP-8G!K9I*QPrsuf(aH= zrTdvIPcmU;@f8gw^st)(TtSDY9?OCvW$G~SN)!C6iM;y(P*y_EJ&bO+iNS0io@kg_ z)y7O#(ASqFWl4@~?{b3qOo`8@Q6)5TrcI5l;0ATfdoANU;LG}GfCOrw~4m4Hf&pxHZynw0VaUnp)|o@kR?l+NxQmpRnyqg zvlSbgIxXN9IFdrak#z-wLAGw~#^=-U`FyU5&8AXTP-(jaIcz7$(VfVdrc)?6Unen3 zCMG7f4Qky&*}$O*dvE`+_gfbW3%=QcW7dzg(BmRd-qN5y`a&+*qSe(Yj_#9j$naolXaHLDaxh$(!uOpdC zqN;+hcZOvvRxs^R(fxvCDoHr(=+Y~Npc;d{35!@!^5j>}q?FaTe!~d1*1#&Yns>J! zPIcHMQ#4S*QR1`xDkUtA zg?R0mEGL|>j&eTDefQrIIj{liZKY=x_J*L;~k zAixb@zn*QId-(Ii_p|;(AL6dN?jjb6aMMjUbN?d`vS-g8PCe^%Zu$NZ`8i8(;h? z>((93Gta+DOMN~6_L#o~LWCpn8Uq8TY-@6G-)A-eY{D>WWz5L=AcXILh7x3B7 zJj{t_9M19lLYnX zo0_cmr+&>FrmGRig$8P||JUw6%@^!dVVBVHhgA#&dk`#E1x+203wcp*$$Kv$%4HA#XP*uU<9qnYZIhw;EYQr&xfD_k!5h8~>#hwVe`6LhV{Ducu zbL=uE45umY_xmXpi%1Dm!b@Fa8~r`~NLk??yhEgo98qb(#)qNM>=YxK4zd9GENpxR zgewaTYIBlj6r9&Jr2`Uh?=uV!I)(l4AXSU~1SAAx5|lj-`E2zH9(w+MlJaa?bT9j| z7WMH})O(;b8DeB`D_)tTIUJ=*)fvkg6b5q~)7gkVsj)Aaq;vTyltd9Jvz*e|$Ygg9 zuVxii$2;ij?L)+4G_CDq0*h%&GJ!_AXd$9aNXsB^STu*DSe8XHnI)*|uIyLP*%{+K zXT6te|LrUD4fh3}q}jc0aBz@lG)^oQ;)t%rys>l70_ezF??sb}OLtKYE}}g`2+~G@ za5zj!!p@yNRH+`~@fc~taI-u@_=E>3Cz)WF7P$_5it(@0w)P~4z54FS}OPE0cmWO)9` zKk@zx&n1~kFlB*P)-&cN6$>G-3@1PkoG`GlY?cWju?7cGRh_&gXby)-8(AchDVJ<> zu&(%@)2Y7oMt10@&*rFXO(oHF=g=|G-A}DsKuQVKWsAz5GT*!8104T}2iR?9X;8g< z`YL$7TyAZ02j8!qs5>uw6 zR@0aO#-z=dEfI=>nRXc4vso%rreiX;r88}rHU9+yPGb44T>}Jz8Y3eK8X960-RFl*ma$6toM7DfGd#{04?RwX`5Fy8Lv-ki?G@4XYP zHO$U?&!LpaAXrSu%5YdA$?l+vC>sQ2B|)!b3Kg}nor)80f#xpgzLVZ3K1)yxG8&8W zrHjFOS0sC-aSS-p^;Y4B%6B1p82h%9PEMA+=OX)P=uFC)lW!mBu|`mD?AMMC77}V z?cq3SV~`1;P6(3!N1aO{oW}L4k3Z#jA7zD`KrcWu!5oD8Fi(E$NS2>iOHWS^i&UL} z*ntvS!Id|?z;Et;nd?7!EML87HOZYDsEV)V?@5g>-T2>7z%9rmymK`VeQ6~f>I9R? zGBRn=pn9mMf^iX|x3`-$E0*$?XEyNQgZE-u7Vkd(c)VVfZJS?X%+w3i@EjZxAD}oe`jY;4?+sU zVU=)L$LsZyef9ecc8`!uI*0R;tR@^@;-0%y0@7f2BFRfHypCxZtU7uHhj%QSgAtjj zEP+@(RjSHxR$=w3)2P;=m>XpMCr-im#3@|yr`Ngt=GUNArBa2_ToV7PRjj}MDPDb{ zj~{;Kot(Hj&WvGTSq2k0du3C&4gVGY1!lc-sn_QnvzclU3uO59r$0bc%~3RV5>TNR zFYmnKPG{o@)H_J!`Z$Oz&wu)K!t_y@?4?rG(V}sN42w3m5ZSo#b$a)_PA*r*FtS*d zB&doxP?iwFy&fF^RCjll@tJA*`Vt3Bky+4qpI^Jvo|(4zX*vWB6O(Eex49^w(j3z`e&u40Y;QzL z!IU*gmD)fekw8kx^5vZvhQZ4(zl^TyEMLCdnVPs`++wkel#J%aBLss%vZjfyXh>O_Bbf{jr|||gDs4!o(`cGT4GP1BVJdA1w=~Zk3=4$<&CSi! z3=L7^QoR%*DCF~Knu4??v6coVD7jjE$9z2-T-OqdF_aj=<8yp7BX*u=p5Kn|UGL_Z z$Dd~Mxfcm6^78SEE&~L~WR^&*gKgWod1b=}8Wx4n{q>AxlbFeUtT^pxl06U-O-!m8 zdba-;Yp&nH?p;YTeu2NZhq~xGdN=<++TJ`oj_OR?zqOo_x~kRHEp@llT3VK5Tk?t* z_QkA$FoZzDl0cTp#)NDi`Ax_=3t7mQgqbiOnMoiC5GI5rKoSNp5WuVk;~i|-mTWE7 z+ES~f?rL>a%XM1P_s1!<1%XL^*W~kc>9QsFrLC&YIq&;E&;5+^#BFDB#Z5owxi`IF zsJe1wU;a<@n+oA8iiL_Iza5{XEEFl~^=p`SCb_05z!#FE5M9C2yN=NF>GhP1?FW4Y zdnxDRw><&I3T6!#pOnl18R4TzH#s6k!L=#W)c|QylPRK2r(iC<4c3Rj-p$aPH__-g zSW>3~A0IvWY({pxMAHUAd;1#3^NMmOA`#?)LHvG=BsnzAORse$m1sp7*n+f3X!BI~ z4NgD(bY6V%MKo!%Zr#be`s%BUkB?J{AKP}xPCL^!N3l2|+_c1G^6#AfL%l?pKYB8Y9G{ohG1Zq%#>p zK^^I;HAA{k$hm0MhF7Gh>ocdpw6rOBhT`Uy22vvvjHT0F*30q7^erA0>AvHX9;BYttqwO_K`GjC)L%_;lgn zM0F~4fhh!fDvOn|FoQboL<(Iu8Ap_GNOj`~COw6E3nXXf5>Ik7SQz}p$)k?xD zCnyzUneN~Uc%!M6e|~nH&D*v6a=lUO$>B)Gi7JE>#jR7gC=ht z>SAmxg>5@L{>(Gp-lVkaBdOG%?P99EB}<*I^R-W$>|Og&@V6gZ*({-J#TeqtC0uKdSRwmfG^%b0afx2MS1I-kO)JAyb znOA{Vsjpv-#l-;WUU+5aD>iTbuPobgLHJ9!_-(WvAQa3U1!z_Ql`h*=~S`O>{B7x0;Upu1mkrG0r|fq zr{{lquWHRe7{n+<0J~gG7Hk2;xZtMec<2|KI4|DBMDGlN^%ru(1KW7uzq%p1k#fgi zFfoV-m(xptuYBzx6=E2LO((>7`OO4u?&2~I@%m?$P@1xccWfZ-B#@TGvQi`x3BGva zH`uU#Jr%&%Sc3L;m8J8edw#@ykNlAz+;<;D8)=NTFx-6rWR8y2%lSnz!%u&Zro1EEpUn+6HMX=V7m#;$;y49@x{lxHQ05Gi9h=~y_1AFIH^0rU zff1ISe;Jrdxx$EWW$S6&lRgZ>Ae${v<~SS!UVLslB!f&8w4w}82%R#aV_A}+!C@FN zJQ&9)*j{e1{(%R6dp@h>01Yvd1Br2XqX5wp;Al!sFAnbkMiKw(BFc0@ zxuYx{C0=tRX*onqlUS^VgL}J`|D=eQmPl{%E2Z>6P{(Ju-Q7cPQG+a&cK!DhMHTt6 zxCSp*BW45B)JZ#d1{Vm0YnT&|N@a@_u2NYjy8it_Fh@C6*3&esxr#5|e~2fx{2oGU z)lDpH+(0>dHt)c39J;!cL8r_ROpT^^|5cZ86f)4XAX(QY8f_&pWpk*{M$`P10COUwNK=+1UR%w;gvBYRHn6Yz zD8XQeQt1*h40>&s70XYir}GVxwoNcpN6K|cCo@0^wySjDc&1s`Rh`Lc*G5XHYe+Mg zOf!>dU`c2#FFv-73jUo$q6gC~Cnx;~u^{(yy#>I)G)*43=NOE(?n3?3Nl*)IXv{WF7iLgf~k=WKC&0eR|kx*(m9BZ%P z*2fO0bXh&Yy2w29_Bd5W6Vnn5!_WBmIEE2oES;pS zp@B);CfPsC+V<5EG~GO^zM;`B-XEOcpFa0~tavLmj%3CfBq1dywXa4x&p}!}hcQE7+i%VCSU9Lx zNLMXJuEcd+o_h3ALct(2uH?Z7e@)n5?LBh_u5|JH)kD}j(obD9NPmAHfoO<)CPyX% z!JvVZHl-e@q0A7Z)8p*koum?h^zNI5qUPltTd6?dkUKl~QsdV!j1a>^L$tQGV%uqK zJB?w?GiBQpY>6vNnA5c5p`vaHwyTOU*Hu4{$^kN%6GxW6k+CymGQ$XAQ>~{NcPE$=E6{b_o9an=dwZ!dLR5tVgbHdRDTJUZ zVzPhBbNnyUBoc`*c;o<+qbVE-tt*x)obDpDvg0^Z$CUKOtg9~mUodD=RbwKA&cwt7 z;cyr!C8MJgUU0O|SX$*HwY9CFZ*&wPOoXNmf|ivcmC9f{O2!xr1(}vMhM`Qv3$ny1 z%Thj>6>U8G_|vRiyH3sd0 zwXBV=;K0x%b#*ZgJ1NE_#5&I4qEG)6k`{^Ie~Ruzf;!!#BdqgUDn*kiI3^{3jY_4g z@OA>|VnbCAhyix~`=y-dI|zkk3`p1}S8~liJq@ca?f`dFf*B^RyI+F#L7;PDMXNR5b4S0O;e{r7zp8DOGpC^x=sL{bnhX) z@PQ8z-EazyuZDlS>v!me)7mg^I503{OmWXk4Aa!7;+&07)y$rc+PggV%hDuip3-mc^Sm zni#`LsSK2=aDYT&l2F)W`;H?#@z@KHo`B`15?H$6(@lnZdx*vAajXpfuqsjjp4Y*ZeIYD0BmD-8oF9mdDg*tsEcIYBz_!dwZWRHNDq z6%D7+XoP&)VFp8WSf$J1r1Cpd*EjRP?;hg^-~BEh|J#q#*Sp`-kLtxy{=x!VDxo$W z!?G+UdIzbFg=uYV;)WZ(!WrkC&-K?|Pe>2a)zyRU(~DgumBxI0Y$oMf0|5UgM*D>< zh*J61j>_{1#grek60~&0xu8D8*B*X?b5A~-X$x+@wTBlD&4L!;hNU*4Iv@M??jSF0 z`cljI*yn!;zDDv45sik(WYQFJ8a9F&f3=e7NU1i$j00$BLSr_aVNMv7+BTVtL#ew^ ztl4CfNeZ^BZZj!yGZ~~eaS_@)nM{T`;i`#?go%j^nr6`1*-a%HW0^Ennjk$sj$n@e ze6p8+-F6>;`>}Su_5Ni<&^emOof4T&+*)jH~7+5UxVdwcK-N8+FD%##1UTL z<1w#evOr%u2Hr+=oEij+^`OEdalDRe2I;kI{@2B;naQl@J3o0AHc#-KXS<=nhKzu8 z4}bXCWt_gc3VY0lopo4K=kf3DUKrlOW$hQRysio<;kk!@4h>hR4oygh|Jv)_6r()W z|1fuc=RTlcQbQvo<}nO|bjGGUWDtmIRH7t>(KYR4 z(rH$&UhPd{lGL|0QtGN;$xM2ja6>KGWE$z_sBdi~8V%ClKTb3nLb_@yVHgJGhQRMP ziU##*58|r|9t|)^r_%@z7wiie?_f?{?9*8sKf#k!8a&>~H}*MP_TBg5791inPTo=X<3bo*r5T_EAC{FZ zW;_&pI(Z?`>y#t_pOTa)#ApeP@mTRdUa9K{FE~^oiUk1`%gfyjiuK;PtU)eM^qnWq9(>C?mEiW-%o?S2E>H&ZAgdmx(>Dv&4Ob< zFvgEQ*1~wEiz-n^gQz8>kK&U$%ffMj&TcIJ+VZdC)GrWdH9p4126^MqKAwK@8BSci z9+0F`&Aj&7YXl+BOZEYRo zq{H$x8?bFPZ98Gb32fi?vX^}(ux*!kQ=Gw}L9f`?nJdp1Wr-_W+Y~j=vXBx2kqEK+ z7=05d1`hQwowAAtwSD{c5s5^Kv^CcS(~MwcGRz4LC+~pi0_Ds)8Ky0VX=yVj6kfT^ z5a@xe~euU6ixnc#DWsyuyu=b>txUM9T7$6>BQB*<1V)ezw zb4x!5OJ zJO{`yj97$x0o<`kUTCP52I#et< z>m~&qPQKtYhI$5Ay>uB(O?6n7L*6N{;nYq1_SX+`?zv~sRM*6HpZO&3J=5fSKm2F< zUf71;$Wa}xVJ>UqE7vJUO&M${afU{b0)jphzX%c$f@#a5wyl}wwl8qgjW_b;Gv31+ z&ppDnJAcSUpFSIr@1?i*=eQ;e4fPQfD#U()5uYtcpp0svlR}V}YBF3Z2i0q$G1}Ui zsB(_r=q{JGuVdBO>$v!DAA;aUzI(?(Zn^#xe(}n$KpK4N3-4#u`Z6jgXC*$e;d!!F z3cnB>O(du^O_s!BxTyrTE|3oBy6|ia0fZ3j>+U8NtHW`uV*a1X0`z(R4tu70{cR1J zce`md-ceYvSo#$VsvDwA7sO(9Boaf!<4yeL;l~Nrn4ZbI4_#N%uvBV{R0?#xoae0w z?_0l&dq3tde{KsO?;M98zKX9QLgi$^+jML%Y2D)dGtcAc7yd{`M+d2t!*j1ZM_XH* zGF|ZU_7~{hcSvnoUS(hQu+C|xZ3N(nKm3u6>o<^bGXSdC7}-zz@(q+p7r*c`nj6Dc zQi4_rw(F90VTK%_v3$9bcSNI&6l@#AP#u%Z@CX47@+B~tb3MlPJSB4l#;w{VHSPca zAOJ~3K~xFK%6!bu9>aAd)6(`Zk1EqZ)7H?{-A^6yMHy0-1jIG6Ov`i ze4Nm+f>=Li>^wTYIF4)*QY&MBvy!mdPuNF>NjU;i3cUv?#5|N7VY z=tn<6xhP+BKwVs<9PchIEILyD|EGezn;CDRaCzSsey0|>785>n4m{DzEeVTTzVQT% zcz0h=KoD;J(nY+vV=ubC5$PP_;8+%19sE(MLpg?r`w4|wz%MA|Bz27{dDM1Y#?l!w z9`D zYB&vOn6)9S@iYZoYHMo=$tjLx4A7c6*0h>QnWV}pq0x+S$V#E>J`#xpX>W>Ag}}-r z5dxa)qf}7Os_rQ&!lO)^9Rx192iORWOK|%Ngu>-aN}b$fT2Wuvz)7Eenuq@Ve6A4t z=@UUkUwT^sa!kr1!DBJnbYYURAlrZlgP6>kI&(waeEafpK5^#x{I0ve=AJxtQsdm% zJl9?FL9$kYZ9{pcrJ%w}v0ggloJpR#?sPJzRkG3PVd_K-}ZUB^E$KTqXe13 zSMW2RDPc+M0%o%7nAtnbDs0la$y6f61d@huoEa%0IYCoX69efX4@#je+6Z0GPodto zZOIIhNF;)7r*U0L$V+|?d6Tm$5iAF@96v~$m7*Q+}` z>X9h*{pp5#yhpQBS_h8c4bgu^kl9_bQO2%=_~C9yivPKumV1V<30^A;WL?Kn=J zb!(dF?d`^KBxSlzLtTK$$-Eaz2W8%7rq!(BOAn5y4LLH(&@Zn>P7X5flT;vi?b!}a zzp58r&7+Uyp*=?QBToS5L3#$7d%)=d)-opqQunc~`v|xLtT}HL@4upy7STY3)ES$c zWYlN##$*gFp;2iXe??`@J5RvJ#)f#aYd?kq6NA zavaAZXOGj^T1R!=c^vxbLpY8@nG4O$&0KuRh1~wLpP_j{)#Zjx@4*Ayc;gKihR(|` z@8(JWn)xBALP{E8Bb|5nYac`UkV5eZoTK-|jG^fQ@;L1A6tXW=t^l_NTBhqkTM56z!={fJ%g5E1y`Mve4zY6OQhIuNXpBVIv}qH6cUoI$p1 z-At2dvV6^%R9E|HTYm<&7Q!C4si|pYcD@9dr**|zMn^|UTPY84Bsh5RAd{0>V%~)A zqo4j5j;HY1<0RNMG*9PmGqkPP&Ic|zoBr;79O*kmxTcxu$pZ+HLH9*4gh2)Ko}@j) zbk<=uGfLa#>xr%YG#P&>uTf8I?_sv>-pv)CyOQC)EX}$^v!=<4a&kyUkQh3!G6n~o zMH6s|M5s{Auopb30iC^+$`dKm>&ZzSt@8lyU0us(Pw?^cfgYaQw+lyp8>9h|4(|TN zYux?)L3K7;KEU(0eHk$}M!gPo5^|2iQA=W)VP+jA{aOG(l?iq32!{in{8D*S)E*#< zh~kATtaqC#|0!%_(K@NgKLNm$FTP1D#RBq9RY+@Aw|n707N+R~=DjMZ93keBQgTi> z%tzk$0esTt{>%T1^G17lJ|wWEgD4MB9Sf66r3i;rcW2L@-I!+B>l93|YUxt^LNISR zM1x_v5rj1*jY>Nij97%_9UbVp&bGaKIn>w9stxNI9vNZOPIL0PA7t;|H~7Fc*Qg}p z&$)^FM0j(@A2Ezt>RVf=C(4oGH>nN@=F=q@ zMjZ`}EzEh6iII^c!Cv+%`h-9Ku)U63_F{m zbwwMMrW#Xj-~I|8y!-<=j>SmdAk(ho>Z?D*JrDevc+?)81iDNrb9fq9l_^mM>pTe}6wI*FcU~ zWRq#kT7%Jani=;PX00D<++_w0+XbQ%ARHPdhd51-(oLRf9Ka-LjUgpOA`!~;d2*wN zk@Ejjxsz>AG`?hmAm1D zQ@Q%KH<|nH`xqPR#5BXCJr4W~5;vuw3rk{Qq|_;OB;`m9@0u%O$HH|tsdglg!VJe4 z@}_SeTOZ^4lLbjJij*4NsRTYLS*oX)7ZOL;Nyr#NcW99|`Wfp<3&CV6g^miaI}tcW z-8-1O>&Qu$v{Xg25E06R%0Iz1AQ)jPImnzAqY~HiPaHptE1!ybrpgR((>bJ+L?R71 zPKI$_3Dej_gHeWuhtV`ORhqJsfWURt*IX#5R8bdtM?~^sLRiJ( z$;{h207OB%zFc#fOTo>7t${8;x2VA(C3U8OGO5UfX~!a5Q^#-adZg$(TeUQf&o@sx zU&0CPtvveZZqvxY zQli^DwXG9a!6z=QML1ogERB$CBjjwQ+>G(^R~u=>Bp_2{X#)E-SUJz#pZFU-b<0aY z5P`{*o}~qgt^39xxRL!`1y)?!3rjK(pXZfNpT?Q_{k*|$vhfv!QYMAJLZzZM@C8Ku zaYBv|f(lGb(?r)LAG*AQv}18X`kW%?Ef!g*~3`0;E6!>a2{`c4ZiCG((%s7?!`P8+a;lBIt z$1s86$)wTTa+ux!@N)rA3Ec?XO#I2>|2MsDC8UEO{ z7qpca!7%mpJ2{eG#`XJN;mJ!bC-3yoD^m~+^Tm(7hyVEPiy$pB;zVjJi(ykRF9bnH zVCyD%uc0{WO(dn1#i_``fw2Pd7WC_J>erth5T$e!{ZlMRz`Q1;7U#D=-N|ol2k3!d z2BZmg1(#lOm=B$EHAgx-k$Q@&t~v)XnI&vnq(eb==_#)9`LR+CBId)f2C*EAmNTxR z#k$$&@S3eJe`T`B&a%tOeTX60-qF&ji%6b$()vB-b&Hi zJ4P(l#JnYu0$zAw2j_kKVwi_z4RId0|3%I@_k2nN5yC=nY%-4!jT}S6N)*_&Zw~;c zoVJ!|V4j@FK;#(nRxQ>T_^N}vx$|M}{Fl#SPHtpqcNa5*L)dKr68Zo*f;kamw)<7S zeBssbqk}N|JU(ylos>#i=C=kZ({(0I6GT0P1b$IY#Bs=wphA}vvMI*b#^JSD_C`n=~6A;-5js^B6&b#sEgb1QOqDQbY-nKLjyIUKCA&Hg(Ae0* zl)lw=;FpLmc*JUh|!L}u~ZL?&_5{8FI=M!qDr(A)mAc} zuBWBtbfA`z;R&+I42EG442IA&L6uN45W_G?r){FqsM6UAAETqAEQ_}h4%f3{#ah;` zJ&}%%HIz#A;Mdf|*|6bE+S)p3ZeB`NI80+(2dAHNA(kaMvJ7-ZSnHu5G-~S=xy&q!y zj!PN-=hGOxaV6=0K9TvmKFIuYH*o(iZ{fY?oJ}e<$)Ub(N~I(g3sV&isLyGujiTijPm^R&y!3h$!9VolS!h{Mka>R_>EdLyMlaLqG=l0p&?8RNUE-d?I`cf zoX~MmjQWOfjq-~K!LFS=q}!JB*FwLxa{1vct!)H#B<)Ty#yZZJ=TFe}?mX4VOllNNcQHll*A zQ_xN3gvp%HIfkH2cM!rt*CA;oNIMoXvW}^?oQ6 z!tXaI*fxWQ4;LE=ukYPKYGj09FiP)m5=}EmCT%)eHelN&-t#O;CNns;qVV;Nj4+fO zDI$;4=?s~S4fsh7+sxV;(P$&K4VjEXY9vDiAzatMwj~o21#G(n(2!E20>6hYR?ov& zCW$kZ=9o7n5}IHznWWT(b57mF>Q$=)FDAhz+6HhgRyjyN?ay$>9_no zlrP17ikj5X@Xg=Kq-~V=&xySm3$Q?cS02{ zZ}+S$$if!$u z{Qcj5k*U!E>J0d=hwkR#d+(;Vr`J2cn>_Q(W+o<5Y~Q|vpkA(;B%VPtE5fjI5J<5x zFoB-eG0hl5)+8n7QnEx?604&w=EF7x>9H(R_y3gCcRtE{P7bJN+Yn?0lsghXCa)b# z!IC;SvK_Pucw-P=4{_FITS2a29nFLX6V(1y{3)Vn`gY#tH?u6q^I#s&vr^%|N-pdd zIwhvV=;ROuT~emQcz%p5Dav#U({zfjoAa7gmX)F^Y%ZF%|GE7;#oDzUT(oHuX~!ZE zFexjjeP9OZ;nM|kLZ?jEDbr2L43jK^DQ|x<1A4JQ?eFjB(n~L5?`yAf#kE)AI1Xti zk6s<(`?vm(q?O|I)6Z7u z0EX9?b6L4^9sl~TKVj2*-oyHJCz11l0B^kUt9&GR-QS&dq{s6P(?`~>_2}t&WNI-+7)&W_s4i8^Di3h*)MFw7d zl~(VbOIi+rK!8kY6oktL8D=J{(b!glo7#!vBxpY4Dn5DBA-HP>MxN*ESFY#Owi?3W z7&!?O*i@SHNZI2(FFu42^d0I!*9{!UqCOT=#KPHm!mX_gBr}YpEUx@RTHNwTu(`= z9z(>L6MAvlSQ+qf;YUt_nsJZ`G$%z(jgLxGdA4VS&NPx)#{%OZ*xShIkd%^y9wQ@S zNEu|Qt%K%(JxT=$KHP3`rT#j9{K*Hg9=?e2n@Lr^C@I>>Z3i)jWIO;r9H>Wf}H(3T*?{JZGNBxhZ61_2y$ z(m_Zal9SLN5jFD+4h)dVScJp%#lvwlUNpC!Ja+cq*4>KwJl}F8e?ve=im!p`35JfUBOE) zZ{y&ePARe)Q3G@i4Hh@4g_ousi-d%LC7AHKG=3fY!XzgxQYj0|DPgW0kOtPsI0qS_b^S8Z zUBkqxJIIk^A~#H|I;6VC+B~CueT1q*j8Bad_E)Qqt7$ah#zyj)H06H5;P^0pzdc4K{RKRGjv8Y zf!`HmvjvR08gfGk#w~|BX|R9)9=2?LmPa4DpQ*$k0aK^1Z;*!`{2h1P@jJeG{l`=o zrftJAlS@|5;STL5W1dA$!kl!l^f2R=#Zt$F`VMdlyly$fWdg^sXl-j_!m!rc5`zL&rk*BSiqc2upAr zhcU;YDr{1LDBgGP6cDBY1l4_2E*DZ}#iI4&7^NPFqSP%ZCZ!+GK~aa{(Y|5I{eq!n zk}|{Kx#yl|)28#VZJT&B%Fe9^@CE(6@p>nrP>9z@_E74U;0qbpc8+Sp&#*mFlme#H zHiqG<+!e!M)-EBPNirui`d;5dZEdZWZl5F&jndUWT$E*1EHblalagtfBN)`MZI^7) zX3|y@ylTTw#1eg<9!VG zEmNCHG-ibRmcYqUR~=3jEzI@uvNWX7-_n&8LfuEv zy_Za8lmIrunqVrW=zE#W1dh{8Z*MPk&Gl^AvV}`8{UEdDI(etStm6>!I>N&USiS)! z23ZknrX=MM2t!(T$T%ibR)VGBIBCbiHU<82L1<_aOr6648(Nk^=8!7hEDf4~$OIg` zkGsG8X+Ctu9Q(%_IQ6@`V95qPeEaL%{`HN_2-qnt>V^JSn5Y~t-RC@9^Rb0zR2Nt& zm9D*{u8Gv-Bx8<6g`@sY2T~~u(-cffNz{`-Syqa2M{*3ESX~$=?;yfqj(M;RzYvV1 zlM_p`KoD|KY8yUcQR8AN*($#?#ThhCA=PlR2Rm_pCW#U>787PCA3jFT0YXi4?sf zBb;~MS?ufXC22V;^#a*z4WweO;>1M=ip`+u!69Yr+J_vQ#@M`ck9dW*`_QFC?RhZhYZ#{K7#9 zo#wEQbizVPlaQ{HNTdjdl`kOYd0BV{fI z2lvzOI27~RfgB@L`rO7o2?7`Mm!6%Q&_JWflDMO*iu&x826ptvh)5 zSHGrp#R`6M`yE{Kz6;5x(>(d)lSO}ICX>OkEHW8|)UB^y!jdH_{y-((2S_AFIc?)c z9)IQuYU69^I@HTa)$r?I{R{oQJ=FR_3}-Xc)I=!H=Md#OWxC+J^Vgy42211Wewv(| zV9w3}BkX(TtDJPkUMCMPWldO2>i$MTGOy3)c)RV^)v)l+TgNSR?e zHOj1$A!?db;4))PaPh?#6EsblA`#BobQUM9T|s@lNqv2cmip%6*VYZe2R?8yEiDaH zX)rw8&yk@n_U?F@uCDzg`nxH0ZKSlR5`NMdTT#Q(sw3*UE(Z=ApsZ|B`=A7HU6RRe z;!&N(2AzCnm}u&ThlAjzEfU{|0BYi}()x_v@tp8X;0v7^p;+VbhFU_AQhNKkXl!ai=4__YNos3DUI)X)btPtP zh-28SY;C2?5ZE~dED%CtczBp{!;cUep-_k_q2c!%1VcfR$ze3jk8Mk)rgF5lwo;`D zM*I4xt~L+?hK7c4U7IRRQ0nHW#3eB`#1<{VNHhtj1sHA%kPQSF92z5}>ufZ`m}Y=k zN3w4HI#MZ%GF``(pw)!Ym()|HLm`_bB!ps^rnElr?>%gK_$H6wY7;-sZ6S~j{I-o3&QJ6y;GrE z;+8N2MJ)7jIgvnU0-?KXrAOruMPpw*Vjid6eXWYQ^*~c z#7w(3b}r3iP8B7kZV8!;?MbOrj*H*#XWDhi<)%oa$BWNIQ#9&4<~sub03ZNKL_t&) zDK45Oa9xE*SLT0#ls2J|ft^cJ7c#uxoAf3$P$e{~G(n}80R*Z@H*0H=()Ii;E}`lW zjg3)4USmd0e-un)!5=fHsb}%+l(B^g%EITHmbpbzu!Z9Bt=DVjxC5^EuY!ke#am}8 zfJnfkuC9ehL?@p~QXLD>)zyWR7Shd;$)qWDZLCa^)ywKRhD|2#;JP-=&CMJh=s^fb z=hdOTBH&})x()R2H~`IRvwV55K#6IhJA*XqE>b$IYYi}vD52Mia4b+mYI2ZgUU-!Y zF1?O2Jq*HypujIBP4PxXhKA_7?W2tR`cr&zLlqNQgA-~3eD)J3L8h1Aj;646LA7IX zx?}xSHsew$J+!DQQj|nj6%$fA)HcP``d!EquBjnvhRI2XhMGFc9TUH3rcAG++zDb? zI#TMi$5vAxZl$%g4ks_Es|%=ZtEEC2k0u7a=l-3Glf_;0GQAvK_c1(?Qs3vIEmAjh zstp~#&5g<)ip>@&j6KX1Sutl`upkW8Q^=j{0HCq?yX2yQX8*h zXgJA7KJ{5nde6n|-1R29FHE>5MrY?yZomCbK6KUJGBPqjNRKlw1UX-r$DW=7TQzLi z`8-3LU-5c{VSaS)!z6T_GG7~cOW+U3)P9n&DChz$Tth)Ov4mjIk?e8`3<~vJRGKF7 zc-(7d>K+wR{6&hGw^P5~4*x)m0uG5CGw9tjL?_31rgoB+%GHRP zI&w10q^p6{7?mlarogg5w6ACBkDh|pc7y2Q`wxGZC1>rO9+k zqtaBwxT9nLm$x?!Z>zl1|39|%99!ooI+C^6vST^6vp73RAOR9mb||z!+1g?4M)#Gj z(_gpgGNpwwrOb5bbf8d{(iLb+p=_Z6N)ob^#7XQVwi9`gEK8P-taD_aN4Ebj&avXK zbb4K#`TI=>$d|aZJkNKz@6Vm&cTYV{>*58BnHGEZ?nO%JY|E!6`Oz)k=F0QW;>(}> z2t9*GdCP`1EQ+`A+duq)!pI1hUwko&qEJ&)!*71`Fb5AF#2?WqO3A{7OF3}hFyU~F zS_IAE7(aR7US2)87t=H;CzE{X#xvOd=dY6O`7P<*J$O|?V`BtU=21|nDocEx89F+e zh{beDr95S6vaqFzSS*5>*v~u$NcH|0uS|31##30bq@AJ6G0N&NHYVZr_2?~Ysg{x& zRcFFd;rU+3NqnIeqPos9eTI;cz|JJ81$>r-wsqj1D+|INrW4x{LSlscJi2u^kmm~* zu3=!HK;5-J;NqX}XK~|7s$~L4zt9BHFcbLV@W1zmt4 zz>lO(*i0b_sT%u_93U(NYC!PPv%hEg!lk5#hlxZ2ScVBmhKCPh+n|gdWdf6Ial|Qv zWezz5OciMsL2`q8QG-Dg#m6|{(SigkQWOQ-mP}3AmF}AADwwKfd_Xc`r?GN5nu0Bi z+K?HP#G`A`G{^9p%jGE+9q&t370k?($rgv0VVZ`92AbO2naSl)Rh1oEw^E}y1z=ef z96Y!aAp}Q`yvjZI9K|$EPCtDkC!f5O2_w&hG0JVXeV?&p0$o)ZIC7A)H*RFYFvwfw z3XZl~hzcD_x|biWbjz`tI7RK`tZC7efbp8G%HNVH%zccMjzz_kRz(Ul>zSzqswAl4 zu-ni&moLIu-V`67Ji^c$ja+n3)HHDyi}1`uB@Q| zmO-^Nm@y>vs&H8QIGdRogd4i&OejJ^B`Yn2>a4A5RKeS?x|Zv&zmCo8H&UbGW*xjy zu_KvAye5=TzTwt&)&M>m_BdpwUio)Vms~8;YC-gvhPqA(P)%>K20DnpC(0MnijcSjs=~aG&eUBjXHF{K*aH(tlqGJ zV}}kgX69Jd?r7;XtpQJ)D}Mvh={)K5ARa{_8jTW-Mk(b?gaY0`fLaua(xkt?pJ08E zwzf9B0gXaBk3Sk97>H7%2?Bu#FTVH^hX)2YfAgv2@)ofLP3+&lpOa2KmBGP57B61R zk*+SM@o1h;BpPK}%wSm-w(XeNrxp0?wk|ZE#*)QL$eKB(Op^&4;?bzPr7;;AN>j?^ zkUnjWoXcr^Ow)W_!@``9NM|Nx&)Krfg|H~p**JjX+2rLp2vaE~Im^K34l`1zBUIZq zLxV$1S!I^3>|o!%Q9vOOXk$X=@oO3b`84CBd9JwT1MJ@I7|9#r3lTyP^y*}?NkX9z z*Ijotr|MqXJI3f6j`5ABM)=ry>+lU6VcG~#qe>2o5GVc16EI}(g%8zp%ll4YYSS7v z8)YH@%`w=r52VF7WolHFJMMg$)hpY%cCAGwBdL$gIO+lCAUnRjmj65WcOleDNN$Zf zdoDYFH!KUwO48om!q%t%j4VrnUPu1*#ACmqqob1*E0%NHo%itcGcWM3-~KB8u%F$# zUtuhnBoGfHgv$0ENj9(FNES&@RjHm08Mfq`I;g8<6%v~%t39Bs2aniNpYpJ@ym|uwla) zWXq1^O$e1={pwMsJOWvE&YFGudid}sKS6I_4?@5ho6n(h$qKgZd5ItY_&<@-Vq8ir z(_%ragWldA9((L5$}U26;kq+Wy-p_2-FN?tLLtM27dG+Hk9Kl2l_b*9!ELwRN+OY< z7Ri10KFGeVE-t8QGB6O*>m_9m81ER&thxrVGlMBz4rms16!vmV>uFl*!^zV}!#kB&`DVjee@K156ms0Bsf%TkU4l z$k&|RZ;msEs!D#>YjQ5ER)~7g<8_pi3PM)lVK<-u(3yPiu09wIaK|$_KC-5RDWjKa zX;9l9XTZoq^D17Id9ESP$s5n)x;uyA6$P4Cfi8K(O7g^(DmpaDO0|lA+PIt!v+!qeRwpD zI$&mIrZQj}8yh1Kh_GtaDuyx!O-(Tj!@{;f^{UkAUerb}#;8+Y9y@lJ7axC$n{PUq zGB&2PS-f%`6GEj&i~nu3bvXs$zv$%Sq?`h@0PaCZD^k0m~YuBThE z7MObhizlrTr|S!`!a6&93w-9bKL86M-_0j(IF-X)UC_0fSNf|ta9M$sE9w|3sqpXs zXb~=7I7v_jkb0P|#2}4v4|N&I#Q(ASOI1~jOp;K@Pa%FD> z3RO$V6ti2D|M~yYCp_*-I6_brOc=c|*iEFl39nSp1A2v~U|E(EENK`thnqNQ!y3Zj zFh`TeICA6&+2MYyrY6>{TZJBouzT0bw0E=;YHA`oJX%2!u3Wi z>P!M59O+Swsxn=Xp}CFJxo1HCc6xFO1nQZu6sa1t@J2OSqDwe*Xq3(c?G@8=yg^~v znl(K4+z#d`8q=;R8Eo3x+QL-1FCV^u)8G3C4)0P~_uZHI&1K8U zi6vO=OL%?&9^ZYG`|sZaN`#wESx3F-0Ctcc7-m5%MvW>+8yQxtSj+t`SiEg^(tS{h(w@Tp;{aV|9j ziG`zYwk!i(=sf%Eb6j!xI~~d08(dzs$k!t*U-MZ4m{Dd>aAbDMtXxc)dEM`g4vbK) z*Vw$_44!)Gan`MK2!H-)6e%Sw(E#23BW~impu4||Xf)t@j{>eIL&3I-3=9mgWJw$8 zbeegJz_v{qgF!r+U}&g^NhIZBk*pBJ7q8*ap+jgw0R(|a6h9ItX2o{5e9ksy!nDzB z8%+yR=lZ8+i~f8*k10)ROhG=MCw<8AL`iAW($Z3C6tY7@)N4VEbe@j+ZA{`wS#!A@ zseB&W{oXiR5*u$oqfv1-C%IgXbUN)43!`W_#KCD--Zooo1m|o_oD3D5Z>&6#1U74` zpH%EO$3)KlO>wUXSvBW9E>*Ve)e>^T`SYTSF6Ds-9$?cMXK?V~5$1)%?A?2SmPPBy z8dc=;Wty5)rWMGK<~h{WO>b{6s;YALJ$G^I_x=r|-~>cwvsrGt?N&rK#aGT!dC%{+ z!f=F#x+b`yWfcL{%cy{p{+I@_5X@d~xbhOx11~Z!+{&lle+j<6K6q(2v~^%$0ZGzE zD|b8_gso}H4{hM4B?egp|Mt{22y}3Po?xC);;63E>&zSfVGVYjs)Bna*9p}LODs8? zhURdLP{_-!t}ZTr+c{kSz7OIPfxl@}ji*A_{us`8oZ*D|pCm;C@Bqls8(*?Vqe-UNfndts7!`T$Se0GZyPB`YxkmN0>4R>Ohc}CJ{nwpzPs!y_z;Q$BSn*gqt*O+%OGcLxP*Hif0l;0A5|;kQES;bS|S<jX8{R#HpaS7#~9+s_H z4~rj!yveGs9D&w2Jo5+;pxQpjtsnmgeSKTVN`>jLpiG{sOwid#|DQ^~oQ+_qR3Z`y zL!d-5kp!YHf$}wt%4~7@_dh`uQdUtbOr+GP2F5ck10_U~*nK3MCyb&7WjwzAlSr2Dz)#<#L6Ji|xd_Gun{Gn z!u_yTyQafg$&e30RXEOsYwE+54o=T)RB{Hzz;Y*#BR|Z4{OX%ru%VM`dxn*Z*KqR2 z#k}hs7jtOeKAw2uF}A+AjrYI*Ch~cU+i$;#f|U& zD2MX@!k54IV=lP%L!>sZhI8Yv;Vgblo*UH|!war19M?Eod|pqwMC9CKUX0N?r7 z575_FA{zEG4~?qEMxO2(=ieXw3+Jv~Lr8_UZCu05K-Q6PxN-|!k5T7u}JUYENw_j6M_XIeK~5X~C3QI1ot>RX(^&(U<66)Tpr zefxGsMn>@Y>bc;83n(C*Ku;ma=Pg27fLHhJdiHSNw^pyN<*ReF|e3=OimYuQ+TY9Kcb!M!kG{pT>WxOCA z#XwLEyE#2eIkfK}enrq2m`~48Khk#2%Xx~%;Y1%-z5f#&Iy}t$6&jkVlRP@iJ8!s* z^yo3_fX5!Yhx+;me#OVDJw1$#jo|YIQ54D6t=st5+ipYGEw(=W3fo?OiE3Gedd${-6t=zxu0CoCGYOHD|@?$gxbOP}v_H66rnVPe3tS!Veq^d3oif5om6L^brJ*HY`>(!bzHB=gwl zKrp~Xr%m$B8$Uu%PZvS8m1-GaICBib9t@%W4co{6&W}?AOG5rerp+0T_$;+-qkI@A%P%*s`#I-8hLgU^5V^Q>F7)}=Qz(ACvX z9gY^am^{Rkrjt1ESIU6~Y`aJS6Tc$dBFAYe(&nzM(=@# z`F{`njK@F!LoU1iJ9M_4Mo+E^6|;i;EMqdIs-)9t6vgqs%%9)P&`_SMuDTK-VAZO1 zc)cFNVcnHdsjkV*a5eq7z5wSiDY;$}U3Ul(s#kT4k#3s3Q(U;_RktBgRpDf&xF?EF zbx2>%0qk(LMFlGzt~A)Q&C-e66Ztn~UH;dyJo|gPyL;(LW|#z0M+Z6WBR8?6DMt6f zy^NW-(>DcG3$T0lZcab_TrwHSX=~19=k^HliD4Mt&z0{!m$)^uHL;m+SBSD~MH2QEm@A zO$zX>3#a*iA3B4heS4_OSd<$#(v^a@eda+R4*6zw9-IU_&*%PQkiXo%ni>Hf0h3ao z2$fU`?tlCM|M|mT@tdz+%tdcKnGvImH{QVGFO6{X*M0`kRbXn|A$Rf3uV2rV8|%?x zF>0ifXk5UeMhGU165()&WHO6omDs&!51mU^P^bG5v&FbLo~tw4Gfj)vOT8u?uCD7( zo77ho04I4JFXU`st5tA2Re34C?&SGTSb^tbSa5Tyd z`8=t7-UTM~v*D!m^!NAR^C=9ZhiG&qSTd;L7Yd4^F*rC#H41e|@;Q^TT}3cBp9yl5 zayjR-t%wTEOA!jWqD_|Ljli^9^Uq4NCc&i$4!XvDC-UE9*ln-SFEt2~dCHj1J#f$2g-96H!MEl9FxI$@EfO|5&Kj7!Js zr6>-O&=#^n{<7V)`dMhe^cyV8rVS~y{wE~rvfEX&}e_3OF$pTER) z@4taeCd0aQ>qsUu+;G#i98D?sqX~wN<}tl7F1qGMzWKfHv2w`@^0t#_Wmy)RHl2kj z9jWUqxhNx5=JlnRxb;2UboXKI|LqjKnxPcQ!e|q4j4xl&$k#8aCfV0VUE>la3I&o< zQnh3Sm@k6}Q)|JL)k?bSancWNBKqzJV01Gt{{FAPUI^s*%}?KjFT9)GmPIDK6p>6& zrT=3(Z82x6J&TMzu&0X&BpcSRcTw{evBnrT-0&{;?%lXnX&|%Hob!<9(@SY%=4D>&vLd=-Zdl#QkAV|?cWU0sKPKx1XUeFItWm| zUw7{k$=Gm)`=0GX#UvilS-Uh&b0`d0OxgyMHaz#}BWyn7Y@{WTw%hCoL5(K(^&cK* z*7W!k1aUBZXun?*w7ai|CZ4fgVs%C4?27 zP?Jt!G(#-{%gmr?peQqp+a_&G|U$gS^pMU0LrmQ%Lo<7Gn74y)O+=ibff~rp8s~4ac%SanZhNVgo zmGR5~*PXST8!kHsJvq*EnG}-<{`14R&0h$g+-e#pdbaWZhZlQ9nN7`D$=#*5KNEo z-Vc3{bI-lp#a`RkQnKol)m(GUHPq=2VJ|U|0Gu4buCD#~gj2)a_V^C&{`q$3D}%2V z0$C>@SqV59GxoF4whS6K0SYg7NnYObh|?@666}4DuYy1m$UH6E`gs3YE4XySa>g@d z*4^?acxf+a=RmUu!z!Wcf`ff~_~pZwGi5p7#Ri!nrp}N}OpuG8!o1K0Oze4@p5Ly* zCjS6u!292H#;oFEB$ZSgvn_~jfN z&V?z2hbb!nBtgtDNfU*haROu+N5LilR)z^VYYHwiW7ue_%HEzXT3Q;JlmQSkNP^0{H+siCk6k+dy9$KO;l!%ht zw~sx0_R-wj&ieJ6IC}IbyAQldW^j~zegqNKc;@LHTyx4MvUmRhJpyf;TKL0F&!B0I z)L~W;i$z4DCPtM(ZHVfA*arMvg1mnCA z!c7d#qU-+3B`IC*{qeW^&GJ^9$JNd;PlMC6OuH9gt&7nd&txjAV&}P4cjJ?!``=II zXtIrDDoLGRr6>)0ZAqYYA&XWtQlmx~9hG!+#ONEyv!H1q>(_7Mk!QCvEd(h9^_t-Q zSD#OPEY4@|xQ~3egCj+gwo5LLz>he959$S_C9W!c=FHl!RdQk`)N0o=2bE zPFqu$acLri&F4S<0sI}SFb1;djcXCv49QdHEv>(8s7QwZ}6pmzLvEeVX9@GS|q9(VO$T9vq}_Yp3~N> z!77zqs*FLkl++3*Hwi_65LDS!R8wSHQ5d%+b+%;6OK2h9DLxg1-zY{9QMTZlhBxdm@fqm;|h*4B)o2&^%9>ZzAdw0d&60UCqN zjG1}LLl)z;Kfv>?e`j$AHBE|(@446=CfVocLS2#xOUJ~XWXV`Kz;&SoPTjdHZRn+2Wi z6-=fvlEdS3WQ~o%AgNrAkfxE$jnLK>LDMvf#T*`=Z%)u7WX%ymK81982!wWmuW(ih zR?6ioWVBkGFd9WDcoe0QtuhO$sIGWcYNqsq)1SUCr;C1B6OdT=n)35@~P5vMk!eVZz}Me!quO zsf^_svu8E-LL9*(7E9Fmfpfc9*P7NL?d zEXsbJ#GhIj+$Y?>!*M~RUM4KPlj3A*vPl;`Vi4Y3wXy{-$E{xVM;=^swoA_{_PnWQ-uVkqOv zfTWx=gp?=vlvLGZSn4bi9ptQi?2pZ`x38HWedT#)LaXJ$%mY5|lP_`EM>g@kwKW92 zGo1h7qoB>_{^uX($y=|Xm_3N|Y1aAL?|az4-^at5K7Re~)x@xCY8=pmy^k6 zX!7cmN*2{#$ymW+o+6koWvIp};-|fWYRe!b9P%N6x2#g@50foB?{|Guyn^_5lOjFVrP#H5v zvCTZ*U_GVc2q;0&6|i$e>KizG_yB=G0O5M}e40jE=Q^^oil7B)qnmKJ12Y+*7K3m& z&9qRd@-N};Pk#*>BF=kK#A!ePM$(`(Loon7nd4ag!O=MjX#qaPA-kCZWPpLk2l(1c z-CX;Z<$Ub>cfl{`gIEB{ULxcf5f=bqyfVX#VPUv%q*0+VY5`#ltUf2XUhSYd15Vtj zMcF;8EGz52onbb*934XdLMN9RaB;pme!ws!&RW`0Sd@h6HmW)ijQ`R8F{?0{t1xhg zkbmF#=o8M6%HJ4r9-B9~31;;Uv?UJfM;@C1YlefEMI%aRg0qF8q;vni|c?K`Ch#5M&w{OpoyN^IaSrPLs1j zyxNnbp+RGGq)2h5NY=~|(t<2nyokP`A%=#AT;GdEy{6GS*iR%9<^%72FHb)646#@o z;StEPq*~SI=>4U0@Cw|?l0XU--6P0kGlau23?qYK7%YgzNgGa4Al&e-sQYJ2OA9~z zp(B4f(H|gRcZuq{7bz_aL!hd{HCS42;8ziUWAgUq|9#4`m==Ob%W^Y0ba!$q$w>>t zNL5zxiA19E!4)2z&wcKzyyg7&(A~Y8kwlXAmUfK1#m;^EC>eP&nF7<6WN%MD%QtSs z%$67$9%b6HSTx@$_^!P23cm8KZ&52W45LJ9bbx6gINCQreJsuq!@?*yU&QU(cQ7qr z_3BmV0iD6#1gkqc+-;w%gj~(S3shC5Rsc9b$G%DiGg*!t>SoLHPg5f$p^zUTV9lEK z97~lDLS;Pb`h?u|`)uPli69nhVOj{%16d}FBt9XS7mkD9&u1?BB}CUD^q1-T&U^6d zl1Zb?=dOG=t=BvVav>l7;ZHgAh08fsQaIzh9{|fhiGyZQXf!E_8mj!AY`gtAIMmB` zKXD$Pe_u0`BEzpo>!81h=N{e9hL5l2jO8ky{q!fe`JO-X)(>9Fhp#!Gr=R>WN3Gk* z${gRjX#vM}-NAFumWc+U+qML!5a$UQ3X>T4_;NJ zPN+<{pOp!~|C%xUiRtPNwae%8A*G~Tv>6&2qNBN)Xf(=@Z8KpzDelvXV8Slqk;mZ} zWiv;xK8SQT61HuV%B4{hg>-rZJ=(yrL;Y?rqLVKoZOIr#V!Hs^T~>2A{Lk;=A2 zL2=|=fgm7=N9Qv>Kgw|bAZyl~#KHc46a_lww~@-F$>;MNI&{dzqX*nHc$;ZOq1vuO zC=L#JL1#Pj6d&W#WUxO?Lqh|mIl}4<8%Xx|bMlI{*wUnR$r8G{b|Zujy`h0>X)|t{ z1cO03nwtTeTt0uoR-}S7p2b%yGgR9rdQ&E_sk4&nt;&_c-d)^C#D7#J- z=L{CA%7kH%wk#$p#38VRipM&F5IS|5U9LU9yr6snfY;Ga%`;y6Iq{Gw}?E8M2a8TTbHiwn8r# zHl9zF1y$K$qJ9t37{D7^f~i8yiZ<3;W$N^L48tH3f`*p)9N4pimUxU&l6d7mhUW|k zC|U-w#ug?EB@XoT^WYyJ{ zTXq>$rjN3a_|yP({wC^UE77)h^W4rX^A{=vT5PIBhEQxJgS`W^=sNko8TdQHgrT8_ zy=0T!)aWWw#`w`yUxd!nVg4xZTD^`$z~nDaCn0U}=tEoB5Wbl8ohm5%At=CZ=C%iS zaLv_iRAqZv*RqZ}vkPpC2r5A}z|lgKY5z)Yx#KbRcaav5HpRg>%KWK)Y&G&gT|CO|k%gbl)O=qh^MMdHaN6T(dI2Fi) zWtGtN5SCRUXJiS7Lr5u^7uHD|2DPf6oYhNF91pdu_L{UT^b&NNpPpj|bwFz*Lgeg? z)M&a(LX=EkQ)63|24w=9d74Hf96{AoSHcs%r$z`e!<2AP@6*DO462$+Ko1}km8O`}WX%i5E5Y37pMMfs zs>FRC{wMD2?59Rb^nglhi=SMo&lwJ@f=N`D*7@f6=xOmkdF0+4j#Z2JKiQB>x&!UM z*P~L|{<%49{f0q}2oi}z->6ZMZ-6g+V{gh_)1?qIAZ6txm=-hC$|_glAyiCe6MOj8wJIG|Kn36h%RYFz0Oj#v_(8y#mRF@4hqZ!t&UCFoq?N$~jQGx-D zDbr-!mc*k`9(m@^OyzqCi5X0DkepcyT8zw4KdMqiXJ-qkyh+*2qi9+Mxh$n5leYXn?vDtU~{e-keYBWhry`wFku%U10DCu+>P1A@*qvUcX1L;Bf`nsHOnyD!) z%Oa8JMOAeSBjX}G9jt8aoNbkqk`dQ)qPuMTWHN!O>O}Q0Im=?oDkJpc(t)8&hM=m_ z)6;`(Pm@YzD`8b{yb+-yyE`uX5_1j@5JJ8o^-IdvH!yD`BiOR#c~07}{&?UYkhTmr zFtSwXvJ;73EKAa+chKCiiqCxZOSH8$^YceO${pYR7yN!5J=#Fp$TQh1-0U8e^UgVk zzY58(e)e+?Cz3=X5yp}!Hf=neNtx&FyYHv>z%eer{Bl5W_63*Vk2G=TeGlOiuzcOw zs9wRURqMF_XFub?O$x1Ug={9j72WeOGy6o=ly^NikoQ@@iJ`*au!%tiI2ViY|dL6qHT$voCF^d znsiuGMYYU>F!=1(Kf_I{-i~PoQS$wGEETU*=-%@z3)-Tjb`GFv^-Ni{)M*-jeEcz@ zy2`VM4|3XRr*itqCzBf+V`w0Ys_LYS3?2*eLQ)+rGa(%vt)eKeYf@(AMYXduFafqH ziAJ5Y^^i|v|E^thG&j57u^@@GiBM)xgo3Ro)B@EmhPPxp_6ggz@dks$T!~h_rm-hA zf=Ba_Ef$GJodeIK`A~%I4Gn}ejc6cBBHd4C+Y)E?S8|EXV z!m&d~X=v&~V4b6`lStb}6B^SBl~j5~Q7~n(;t86- ze%*XwV$PJR7KQ0IJmrc&zAj`Ld>)k=wUvlJ zMk0~qV_*0H|Ms7^QYu-rhnk40F{*Sgy6Qz$1xCRc%vkRDw@%Ba*e`_0urA6ZX3WG>O;k8`x-6!~q z8ar;4*GEBSz!H3E!+O5dxt?rh2Swfc59bKX7)e5Un9)LsDNEwh{TxXZ+-bKX53cw4 zG12MSew0&JzlFzs_cE(aIgNWC>7x6uPjmI97xTRz{DhO*&LG_E(sz!6ZCz|GLbS4oz_~i2}T^;9(SFh)R2OmUA zlN#x0Ya@{emT93{d71?*3J6qvni@0B6<5BMTsB3xF~pP4|AmN)td}zD-05ZK&N*$( z8ftaD5*_fjZS?<$_iC0bCtp)r$V&4vOA4K}%*>KVRn?1SIR^Gvti{bS36sfWsig{` ztJJt#TU1F6FfSaYsk0MVb~ZU33j>S|Co2tTP}Rv<4vla&Pj0p`n$7yE)1C85Rh`d5 zjnL_nNn%Ut`R1KldGrT6AQ}VB0y)YPzx@*HT3|Ta%UH65m!B$O77ug92RE|bD~?kF zUnBXP7Be)5Ra#owIWmwU915YJkj*BTaeaOtJ-;5yZNeHG8|doVg9wKKoucLVu_lq! zN>OP_s^$MqQ!$DBUujI<=%4?7Y3zxS76{mPqz}o06JApfv!>@aWvz=h#E!l;0CHN) zRFH?WG_V>~rCtv^n}hQ4B7IqV3r3-UWqGMZC7Db)(^&*|ra&f}LG=m}iC(JZC=-T7 zZ|@Nn&5t_S3=(P-fuaPMRup!1^&yLS;tfHhtaGw96hR&nb84D#S;QL4kqrd!OG(Mq zottJ6pB7{iIA&In9FyoRjqD%Hu^`w&X{3*3i`Vkh)@P7zF%XSLNvHFbz(*%+ErMa> zsj8}BJdZCuw~u(dg?K#X zgnw0<2xrZyYIOlmg(0uE`l3x zyo#;c_f?AdSgett>fj+~L))B`*BC~@;*}S-^Naf)bR;aravW!QMm*|hj|UhVGY;>+Joji!=JCAj|j z>!@!Gvv1#Sf~v~Mu_R4RVLtPjFAxejk^t!zLsOPyQb4`xXs0bpBE>B6#%VNEcZ(H^ zH4=+8R=WSR;rM^jhSNOG9?(;kth_`us*@h?G@TBGMb}kwmc*3s+@3?w><3}s6V7|1 z#n!VwF-S}ZqPk?}k5@C0%2JcEc-xBg1gNxNH!e%BhsACyV{9+3`?EQRv^Fr?5@;H`I3AL?rJ|8IL z(l*nIOfdq2Ywjgb;!$@y2Lk+YNlIn}aEy4IG?3)Mou(!C(+G zmm|>F$o3sOShHpg0J;32+u*=FsX4zlXW}0SYM7?;Tq9#6=uyXbuh!S2Xb|1#NANnX{BVn_5M|oNYkd5KAH6d;;gd5ME!X2xZ1?09~Jv zw2xzZ5kR>DQt+!z@s$`zpzDqoucKoLX~UV6d#o_i2&Bxizqi{hNJ{Qwp~kW>q{Xxd zGj15@bGFA4Ny0MFL?=gumy0g@0|eqQnsoHx3u3T$6S3dj!SC+5oMt2;p)i<95?j*F zH|~C!!v__}8|eRX0skLwXC5C(UFZFGj$b8R)#>U^S9j7mXOheXGXukLsKX)R0U`)0 zF5)UE>Y}@-&&qnTx~{Ir;=0Sa;*G%LfwHW4Ac}G**Dx?MFf+^~Gm}j2?(~uF>U32n z^-DU>AHV8OW&rhh+-LirNiwf=b?W&2zTfZXI-DxgL4e2aNTGy7O{B%Wb#&c&DUjobJ0>zx_yyyrhy2$y)^v0t-w{WV+Ph(z#X~*IGi!S2&w_k*pgJ*{h zaLvUR@cP&P1(#fMAp)1_aqYSwZXQo>zHO85j{jjK!dc7+i!GTqU(!(U177X zCrUCo!IEoJFMUn0ufYU~Tm;c5p4UiJGmL~T$=Nx!Y~0A5_dUZs|Mp{utOL!4sWIq0 zmy2F=3t#-w>p5eGNpm+io`kkA?Pqr3jn`8Vf@SdQH>zHXEFdYOvpJTeAS7N1ES-pn;-!?6k|8@}N#aTH`wVLq{BR(s` zVMQCqR%?>$oFJxOIKer}{R0Pip@jOXZEl6-8sbu?3tCN+zx~jAIeOp-W;~2;7&J(a zC82Tg1sAe=_ij>!J#@#``YE9uej%;8-iWT#=xU5gmqMXHzK|zq1ey08ZAvAFuC6#% z*9M*$+)rvW%gHC7%%XHCr3FjY zQX;()bKWfD=}DHB>M(*43`6%9&B7|`io=#ITPR7F<>e*9VI3)5QmGWK>yq~$kWeV3 z@+yihg|ZE0yGG+085trFFnQ>q2N6Q>u6MnQn{WPiCXOEAwtMg4*j6K>SW%0b z%@CHQ3gthfHK|TLR*O1U+`vQ)Iazs*<@2DqNI)l*%lfF4;xX^rw;x>>Oi!!7x7CMZ ztr$f8spe`lX<^kvtzdPP9Sq@89}e?!NmjmE11vTCPdZ4?wI!;BnJJ_e~LM zc{f$V1JOvTkOkQZ!X<=D#0s!0JA-aUSt3AL6j{tY$-EuImXeSudGDJ}LAd)7nPDWo zL`4BFH$lOc#H|E#xg-tI1mAn;Qm3vC001BWNkl18}~=rPWE-Gv;;KErcUj}wpg072@*g0ee9gTBCgQ5jjR?NA|oU0rdSkeH^pBWkK?2vP+_=Ng=y<)rRSq-SR6=9NhomN6QSV@g`OB`!gqwelaa{ zf48Q(3_ra5dP3pQrRLM}=U4iEFX*If+2 z@bEB+jvlhPEZIyJD`w$3Dj3wV5{xDlowmUcEP0ZW=VFFU7NkUPY@{MO{C&d3ai)oi z4iJj5S0J z`B2m^HINt|pWwT<-9}$WFEfP#;c$$JOcuv=Xz;@5hM++=YTCIfW5JV>lQy-hCRP{3 z!xlP%M52d~-bmU`kr0izZn?In2Zf*_8mX6yRHP*3j?-*f_&U zyo99`Y`F4UV3^$esoVMTzrB_vF$Zx6oD4JLMI!XFWUFi+{5-R&yB}zbXBQRqKB3WU z>df0NJ>7jA98uKFX}gSRhHw$g+c_-DqU5L42ZfG{TSHXv_s;4ys2be-F>2L`4zK@H zugag0+xNVzAHxJ6Me|$PvpP}AI6c?%Q~76Gz0_>|LWI#|GT&H zXF}Ce;^yne}=G}kK={t6S3lBW}Fo{Hh!J+-sds0nN6FoHOI%l6f zz%PGtFVT3IiqKdT8sV@(z0{~j@z_gC6$S@KSdtEv-du1jq6Gbo3ZfdPE|sFv?AfTf{$X*bTqU%_&tzD+2@mcaqQz1= zoVlDT=1qU$Z|mu%#Z}W4D{7KYWvP^13`1v0D2Fq*EZcivToU_k9lWaEWHzYPqzHqF<3MaRUC`sv3sx8naWh8c1 z9bYs;dpH1OAY&84glrvaMI(*T0<)=MT(QhPcPsJD0n!KdqO}K@&e`QkSaLi(=@E~IvC}h1ua5dv zcV&w(sMny?M@~GaL?)BLaU7(Sv`5;gmoqi1;8G-lm{^SkJNe{zNg+)2E+9N?`rAKdDKlws|NH~mP807PLnluQ64JId5DCwf(`OaXV zNr^BFqJ}{v99E5l?;IvpdER^83sbvRTNJPUdi7eqdgCZp*8oR8k0nx_zUEz*pim)& z5vhzp76f!!A&MyB{gLq$qsbz=t_BDZU1!OKCSB6q-A=JsMl|Y-PmI%PS-7rxmd@%9 zaQz+6LT3P+ogDoBHH1cnm`VxSy8D^GElTql-vwegLpio?*g@T8w}IRQVhmyla9unK z=z1NvIbN}&jVX>2qJf6?weZ%TfS2ILw?x@-W{IbB9u*O0KD!sJoc%Y4B`N|*JrgG1RvbZpwlFYdpY1v|%) ziQTjmG*QGDvd6V)DUD}WC|*MqX-+z>_1DB*(2 zW^pr|k+6{VA(owS)%Y4KCO*mOBv#BKn^m9J3|s8kvmYs4dU|?DPA6+@fNUmPv%#ND zW^2PLdpb+AslJ{sxHN~A8`AEhSq$A|eXq)kis`*HXgV|HX#yHFc?waltg2%~BR=g$ z)EEs2Uxy4VHLB;aWpU*JI^I1?{a$Gi^ni&=9bNrBjJeZ*kAM7qesufS=Y@jsVj zk!F3_AK(v@OqCV7Iy21;*I$Cn4RZgt?<3~@ly0$}I2wO@=|%KzSj#KAwoyzA?*H)D zctUtMj>Pj*)YTrRsJWh$EIDxMwo}=;_bG0;;cvO@ve%NIm|(pQ$Sirwp-wuA$&nD` z?W|8p6V&@u+v+K-o_EFSsG}q#y3qeGsCxf%&B{UzeV2a}iK(ovVWm{*@NisMZQ~2W zdn*s@pB5M-Yg1{(?Oaqst3}D@|KXpw?|}#D=t$H$?tAXJhpVo-nvRZM9({B_5F?_8 z*uOu;l1b@pzbW!6BV4Ua?b2Wfgdr&B3upo&MjMWkr#vx1T}3Tb4Zt#WRDi~yM!hX5 zdLH#2elbxXpI5FELP#bjr&zy!4LvkEfn`oM-p$;%E2$lG9H=g+`$Y@@hjNgdmwrkw~=v z(Hmg3-lU462vJ22WNpf^vS_@xwdRYxOw+7A{HqI~c~>Dw$It#X%HZ4h)2HmP{cvTuwT`tFY8+zdG-+?sANzmLdn3CDlFhS8l zA=J(G3vXfb8C!VzmhC(>G@`_}p#)54z;k)FxX2|UO2AFhZ1(WWtmN|U0Owc}B3Qdp`6fjvcCJ&riS2_vQUmL>GmEMpJA(-@4;By!q107#@9w z{&*Lk{zM~xc~fU%;TV;!W58UY{a z$vJs8Z9AFK(NW^@INk9$Yu2n`|KY=2c;VUn=YKv(Yip1V8`iUC%^Do1KrvImaa<;+ zrU-Wfw51G!>&Q}z+G1wT)xs!!<%ga`y0 zS(J+$8ycZWZ=}(!Bc6!zliTm(>)*VCg9q+saPTk@U7@48E?AU{K21Z>MFRnWlsZeU z%d{NeKOWf$MlTnOGr=bVP1rNK71pYKXb!2O`W-{YUHF} zDFoU#GHnLpHFN7KfgB zhF~zll9MMKi7-AnL|0cAAx)z}mT(-025GS5c`SL5_XB<#j3B~MYg_~m%?Ogu=c$*{ zKens#U+u> zh3k)N-H)$P>uan80nQwlO7mX5pPtvKR0G{!`0f@j>K;%PWh)Aps5xY~t|V={R5YCy z%fzJrc(-1g(ZaJRYV{NHdQ|Bpks`JDj|Evwy=JMrbNWVtQf% zO@nB#4GfL;_HKH^hOe;^EE*aa4-yeUIIJ3?Sw}sPU0t2TVx7P!@puPPdN_{D`1m+y zp1BRzb&16~>FMntZQI~;#r1%iI#!VlfZ>s0Ua{kBvbiJxm%aA2=sHxEeJ7M+k=BG& z%PeU^)E+{$h`;c)sx}?fMMKKt7ZBH#*me=i5;X|!#3tp1L}DOnQ(A>+s0o0|1CTWb zmy&dqcvOJd-^b+e2tgs(u%VB%U1ZDV4dh*$5W+_{%-ZK|_K}{sY>w{kZWd_7GNURN z#y2I%yDkm7jxL~HNS4Gh^-^cv&XUd9v_w}t_?yiTxQjIF0YEBhnjWnQ->b9$DP1JG zKM8V~x0Oa^!Kb%WQLXAZ8BHnk1J}0wyqr*tqnpjj|$ItIz_Mt360pED&7G`H$-go^M zNo>3v?>pmUI!>o`O(XyLlYhk2`k9;9!_@ZEIR9lYV`O@|h6v_ewed9iu(VuUtRX6O zULDPvFW&YP+9lDb_nQvo#-q@vdJpv02v0uwB%9W*#V`!ku3d}tJW_=;PAN}gFj8x9 zDjLj5$>iiDkw`0!ldrjcrPBqh&KSx343S71<-EhJrm^4)-se0A3ZQ8Q$bRI7;)0+G{P777t;lrQAkdqP&mPiLcL~Z9opIyf;%%aLsxej zseB$fJ<{nkRr{p_q!E?_&$J(`P$>;O5Mj|}-++H+8aNxjR`uqFH=L@9M8R|V* zqpli;KnhX&z6ogbLsO~fBn<^`%QPC>jiH7_}jSm-aFa3^8wcPT72NT_jB=8Z|C>F-^s>}8+pfD z-p+N`y_1|zZ>b1D3>`*o(87E$)JZ6pW?l>^|9y9yv=|^R%k&C0Y0eb)ap#u?XchG| zq+C9jiGhp}krqXnV%{Dmm}qC&&Z)obzb1jF`TA$CrD+6~?KMO!k40T)JUamTpBMO; z%_fQH34}i(T-0^u%>di4`7X#_b&53|gbt3)(??xS`NwbYyU+X;M}~LNDl=&3xbaoP620z}Tn);W8PJ7Ux{~O@8~!_tD`_{Esk)#)kF1JUlhc zwo^AT&_93~(y23hl#WKzG4ufS0l~)hjpU?Y(B6k3wBzV8^|D$Ds(|B$fR64{r>i3S z)!KlC=LzwT-z%Gi>1!$a`10rfg%5u6{XDh*Fhq24GSqt|5)p%Q&N_$5becVT_NW@A zs>vWle^(n%rcxvfok|%-lSu+*2%8dj-gXz4U4Ai%L=RgxZs8aA-%l*oNzpDVvxYw^ zrayk*ynr~)v1xTvQf*QeP}H1?P@#~zuL-h!ZNUl^Og?Yexgxk%dq*;rWN2u}N7R+| z{F+FFxk4I82wJot6;IM+Xf$bBZO+C-;#5=Bf15fOJj)1JAK?nkVns$pHEY}3g zOUaTW>9j0H4jsaEdvRUUfBzyow!f7A{%+=rWwMzp&1QgXHp{$ivnJNf#DV7sM8Y^u zoziRpM%$l$1r7Up=;$4I4JH>&fT%t84y-;gNB! zeb?1YWwV4OB$IW7Or4zE$C8vp#a0a0K*u5P+Gv(VPD;X3U|}e9!StBKB}5NFp{yB8 zQc{u%v2W6$MJ%)AYLsMw7E3if$z+m6;ozm$n{@lB-hQ8-$`~ znP!3o+h!_Tq^(DxL`Fh6YDsj0{&b=VsCPjM9RW1DvetN3Eh5!t4N(z-yzc}SLn2)l zVXEIlhg>ejXWzMj8*kmqf8J^GpGTiy=X=lPsqrA!-}Q(RsTQ*Q?q4s!E|y6Mi@ZC| zut-4c5M(w1OEi{`g3vknCEIu`GsDMk`yI>X8Juk`GVu9dL!^h8kwFUh@aJygy~Rb6 z(k5*K*hndGl66RF(9<2}WgP*|I_nzVaoL+`LSk7_y1Tn;i{8LQA>!&k!XgR7~;EAwHiTYk)+cF-~Lx27xi8cO>4y~c?2Q`3%*w4 zzWeT@y}b=YiK15`VMNed+c-2bLNq;trUhxyG_*FbXJ(iIdfK{Z(Ue8;;}1USZz>uy zGZR!ajcCvSp%Dxkq|?eZY-UD|L$ zgUmW5G)-{ez$g_BgkjL&qaF$+_Sm!M00761P1Vp5^~z%y8jFs{q5QF$0YT1LK}`%p zotL?Mo@P{FrC|u)F)YZU;}H%kG`e0wqoLfv3?rz{v42h*3}XdpF$DR1iAE&lxPVvy zX{d%YC9EYTw zrC9`#9cQp}?_Msu@B&_a?n~LSlW&08s%U zH-jTBVrG^_B)eUSu7~L^I+WcaC9@BVC%_RbQ&vTnwT0&FIEnUdF8}Qu!~#%=@#ek- z(m9WkDbPilm}`#8uW8u?0$ansVlj-zXSo7 z&mCyv6E{5vnO+{=HN#(Qi{hC(*n00geCIc??Ftxu6gH)4>p2rM*}*42`vAP{O>pOL zSpLGBL0@F+x1VCazL8gcaW~FKHZh&cF>hBbcSS9{w+TVcHRxgt(6RcvK>HmSTY2TT zpW%1cokae?IA>TD#``vK`8E4s?Hedg-ATJ1QfgLXjOo}mve^JTbiwtn-@sRXx<>{4 ziVm_upji$gRX`IuAqq5^I?w~UOF(J_0?RxpdbsKL$9O~b5Es5?1H<_ddbfr+ zrrrV8_imyjCF{3rK?p&+t_t)9U8g7|5wSw24hm?JS*EeD?IKs-@F6tYrByc}Ux!J7 ziWUTx884)1i^r9zh$C6_JVpPahhkbISl7gXBVz=k5V4hR=jq)eeE7Oc_~C6|Clu3Z zqLYmqxAML3eTdKA^brP!CWxC>4MA(rb&BpPO~5LYqavCW)yAjqhpM_AT~Lv-RuBta zpd)yG9KuSd=?cZXOr05JN!m2Jb#z)$ChTD8G@KKe^cG+Hz$I(eiK!P5*( z&0xvNGb>970~!s3MaN+Qhjt@Oz0^q0OyC3~wIO;78m+AnzW3Ez_{nYGX3ZH*S?2u^|G#I%j%>vLOG=yd_>*NV(z*L5OzQEQE z+c|b@ii+@P#-rePw1*=Y;V_d^lj?Uh4b5qy-t*|zG%TU+30+qXp{*`Bx<|cqj?=U? z2-6>Cs^)6tIvo!hl>GYo#f`7T^VX>o=g!a9D8Cr>|Ak*A>DPR#OoWzPm)1mrJ8!>( zmz{q;rWsIH<5Y83s>c)LTxhX$ns8Z*a+V|(U>b>>&K{4bs0q6Zy0V&dZArZl#LXyq zH_4J)ChL~b^$>ZtjFgf@qMd9uM-ah+ge{vlbJbhkNg|P8e0&1kKaoKpNM*8Y-MWcP zChIpO3Q#}ioR@Id&wtKsx8KfLXP$}~4$~q8H{W~{{as!3tXo4Slg4o*Q&SldYvV|% zrio)i1qy{c-RIIN001BWNklrdW@ z<2Zh(RD`DZT8>N(Q3tHsvYE-<2b4`|=SIe5p5D0Pj@L`c{{08oy?am1(FmZuJ%SJ# z#Y~3f84iTnHeeT!On=%I&rc=v9?VUzEE{p$!#quDe` z4iB?^`%5@7ev}MZifH7r64UJPIpK>6CBvq{GO=x!fCwwQWl^9>hmtD^=@wG%r-V*a zsK(&naEcgF8gxNGnk)#nbQXZt5(c8sE5Y-RMf!Z>Ey;c6T#|WZurwpzDl}E5szI>nyo8os+hp7|k_A!Au4 z3w9R#Vm4PQ5N>Z{&U0u+Au3C#4P#DQK5k+!rN^vPh{(JUM2$!-om~~oc?P<=$T@iy zOL-!Z2q#7QnRQAmIS$dFK{Bs?9t=Xxch!=fha>aMD2)xLRye{JVib8PK3REp?Z}zrKz7)zi&dLVu0Z{WA&@t^G@7ARyQY2Xf^S> zVFao7U|x8%U>r9gs~$@TjTRAP-q)y9PHdB5w{9KJJh_K?+a@0FVnMn@MJHpKQTonI@2{{xik#HR zS(}L2N$#~1JU2Yg8+Y^}hb9U3n2hQ+6LJKmvT)K_)QM&F44cp>0NvuA2Yvyr&h=Nm zib`4KfJxWIbu}D2MYCBo4S11B<)7572m=0;KGNRKlOywR-)})P`Tm#R$9a8O4h%(T zv0_}a&Edc$0e<)+xaWbreDcaI{N$H=;p@MIledE`f)H4N1Rc>R2OfKzZ++%N@Pm7K z=X=(Y>4ph=j9+Ei79WKlTaN?HYIa)Q6OvYQ{>xtFQi;jLpa z&bWLF?L)oX_>qSpZ9w7YeBnzMlM-bh22+x_uz)c#O!Jnj&*m$?dl2Y_DGg#Jnh@v# zlQKFBEFn{K-Y9?SAT{s>FXGoZo0e&GxB#5WK?{un_{{^q}AZ@ z$DhEH9!rkoNB{e~l$-*G(+*`k5Q~UmtomJw2!Kz3+U7 zU;X$l&N}N%cK!BOeC^h+@$~*7EGtoKPSj9WIpKBn_pxjz3FsCx<3qHXQIg{+N^%i2 zSVSPb5>5$vfze~f@TA1^Ji5BNn4Fws9+)T39E+UuhD$h{DpO~6vt>s&pZd}rq}*pY z{S|K{nH;0pgbXfE4SI~FAl9$Z;JQ9?;G$*=dd)1LTAeP5(Uq$Gz#dCbdm8qk_Cr_lEbFH zE*2f9<^;FsYwvQ7L^C49+cW}U9mkQioD?Cz2phCV!oC@aq)1u@O;IFkxp;Kp5l++90VI6udAE|HT`OKMhLx zb2TdwUC~4>OSzRLlPUW9`&e>aZv5;&@yM%RwW4o^6D*b`-KNE~J5B+eY{pg}sNl0t zRvo8t$){+kDX^%eN(v#!W^**?k`^mOOYKBSf+9dRoAi0NiwHdc!1XtLh}mQk(+n}2 zOwrZfM@c$#5A?8a-##oWhGoSV9zKe$>+IXNkBct6P;vQPhq1Avcv5oV`R600WO{Uz ziY8dMZVhYJtig392M#>P(@*b4(+rlDBuh&Rw6?Y)rKBgmmULPrG7nD<(zUq{XG+p) zgc+Wiq^+&HHq|Ys9X!KfIGv}xt&3wLBlK=D={^^M5NBIzkr9F+5UT3cI*=wS+l0%vU9&Vvs=fUX;a!zMjFy&T=Wo9V$r>^*o8 z$8kCDyz^Lc9ZuT5mC1t#x%0ta69|N8Hcjrj>n=Pg(c7a`L>OnuV!Fi6Aik~kM6jWoReqs=FNQf``>3o zriio$XsN4X>(;Hr<6XS+l^0;!HknM8JMOrHzyJFi(JYg9yya@TyW6?p10UxbU;Q%e zu{JKh{9E0;KLvIIFCL4JC>Y0J9eB&I2^+?EgpUP2|yzri}5dCy15pr zdHd~maQ^w{^Oh^lClZNp>ZzwvC=`%Va`pumF`3QqkDtDg(V>YKvqR?B({O1-5k*xZt%d{N;NuX1%*eeQrOqdLyCscIqcQ z8ip3R`-+#dv*&)!Ju^xs6k=9NTJ}E1^38AH*89@jdbGe}Zkk&Y{ru%!ucKfm8BHzH z+HNs4F^g%M#4tIQ%R*7IT+oQoLEP-Y(H22d&w4nTz%)b5+cuVu1kT!aZF1(8UFNby z_8r*Ixo2)8YMJB=9ZiG$>;ppTj;%GbPqe&+FN$~MnaSt?uCpT(SXn3|fx^E}qB zUF$b84*5bFBP`gw`Lr6XV6(oC1|v){lVNyr3Mtk5L?Q+UeS{*FO7o^ST}krT6vQK> z(=${wK_INLcI_Gt?j1#FFYHk-y*h=SNX0*{_v)TktQv+v#i3>(;CUWi)mBl1CaKjL zhy_$r(Tw_8)q(3o%jSyj&Q<*^)$9|^Z=~jZ-AP42y;BDQ-!W_@b)Hpv8N=spS5xcj zy*e~QTS=|=uZ;oBDH5FzzH2KiFtOr(R4-R(991!=l!^{#nmPv$K11U2%hePu;}Q?Y z$YiGI?9|D-lN1UW&hEJgFI%o%-&eo-)$H1}mvXsGi)B(Sm-*~x|AF4#09S3lgdaTn zB)9Bt*)#dX#cN0MdQCeNK3j zPjA_u1EwVyE^oaw&fG|fI#U&L^-?F8a9O}Y%Iu%DkxQwlwji0#NuC&)1;YXZuIPhQ zs*I7)u(L^`E`0MX=kof~X4%%)N^xX@c3rUURU7$_5511pd|@9r7A?XgW80kd%2T;* z_cL5`%Okwunp2sdDAFx8Vo@No2!>wMAqxLGEgYvuROdqoi@9u$MmNdV-hMjuc9tLh zV1y@+)bZp$-wjhP7#-jp<=T(#U|WBKvf3$Rz%!`NWHGw~EYQfYc#h--E z)9IEDv&kZ0P%j0bvsTQ3GsgOYph15b&BB6A7Q$i3dpz~XgS59r7#$qs@V*iH`}=uj z=aV#}5sDZbIdFhx|K7}KlSI*|^CUO@^H z!NyY;$W6Q4bI%W$w{3p=+n*9Ue1OcX%31sNXFf<&gPZ^PlU)0kZ{!Ex{Wm`Hk$>Q% zb-j#@9%0GNV*17`b48bjcRq;gEcz~kI@8nBBy_w3C5FrK2<3PExf z!X}=hQJVE=YincAo;}oi8kz=?NQBABNsOSzybzR~5=+ZVG#EPV?Eyae#h!=JP@&-A5u!PEPoSC>j~5^h1$I8=xsWcSEC4$kQAa6bc39)~0E` z#j?N%hbb2d6!Lj08U*~kLD$2zh9jHJ;>bEoGr)p4u}P^Ka7Zd2pZnhvuCRJc(Pft6;!-L8NaxTfx(8LQKw`Sbp+SDVc4}{P=EC}boP~4cbonC2F z8vHl0EQ_Gf8BL~W>rp(ptFC$*wl~9(!C}TH#+ezP@Tb{s4W_C9CA)}ehA>T&xonP- zT~zK*A(IDxc^_}R_S#yBuUeDxIny#)c94F1XRt>E%Nj^VIBr?F9Q$olXp?Dm}$+PG<1cO1G(hSSX z%PdqX)B{?BMt65NYuB#flv7XQ;K75Obka%8CbOJ8a1wT*KwF}NdI?agX0J25EcR7Lwm_hF`7&f?g_CZpmJttB{3kHc3gk=)xi5 zLB4a#Ej+R3$=c#JFp%Jj|9B%eeBxvL=)PamWCkeZiVQyc6hHm1A9G;$Zk~PiDO!YN zWIDqYmtMr(cmIss^cb$Y$Xqr_EYwFZ7~x%SzMMiK!)YfC&^6FYP=v|51y0%6M_)&b zioe*puFHilKM&6<5Q~{Cxstie7=QPkcW`icoZY+k;g(e+*xMfEpFi_irVbtAZEwEV zzi;ah1HE()^z+od{TRAg*{B&qAJzGt{IK_{W^2c5LSrtM zMepe$Cp`iRXokySMW0zgU&f(n*46Nh+`|q!9d`qs&f+@((C22y^ zx>xXnybaHqTzlsc?t0_PLE5zHI=x@cfVK%pa?ZtTn6mdGOr3z#u_x+4kHL|n)CrZx zA*7^9xA^J)Sr7?u_R}e#N$A+prlJeHY#FI%S-|ws?>|qGyyUtxn>q{VJT-j`3>{1m zZkA&*%gI@tZnKB^sK?02F8(6X!(y?>h^}*1zr}r@JJnCCb|Gw0$}Q3aH0Y9V-nA1l zF0cFkQ>1Tx1>kYfcbdC9;6FMstbIoS+gCW}lAk8tDl=VOm&dHHGWWV6HQ`Wlv9NC^1ym#=1M z-w-c7>*ZKhBeuOr#Z~m93(wj>iz_&Jpplg8D%yF+0J7i`G&Ghy<%zwvwVgRnqu%p~ z1|vvM{vX=jJiM*5PXGQ$_H%5VBkM?(Y)f`z$4lZQP0}W9lhTAjN})gtQ=sfyhhbPc z1I)`XEEn6$GB8V-ffkqo!vMoF!wfA;_tMf%+CtJLX_lsO5<9kKTe5Uy>Bu@q_Ib4Y z{y4{q-34ae`MtTWUb*VXk}ON-`7ZbUx$#Sf4n?rcN^q=&rUfxF1=?^>Iu&~2oh;+f zsWmw3Xb@H*r&5XTAR}SPtn$zUx3P7@%jobXx0mnTO^XlAObTR;{^WYfJKp#@4n6TSEt-Z9us#uI*2wUmcmD@>-+M0??l_N{Etz#BLw)Nx`q*Ra zea#z)m=5a`aT;bC(G>zsAd6m2VOdnmE)IOh&fUz;oW+rD;oBmiC(=V@p~(1|r-4^< z+kN+tJ2VMO7(ILe3In9mX*y%AL;@;5{n2;W`9F_pBNt1KXR25Z)zM&*7()IQgD;3(;(9l@(|Esqs z{%0Vg>%s+`oD2MxJa=gK|G%^^UDxqTNx?L*ZIxKe4J^+d9`lAYJPT5>N^b(FluA_` zX+v%rbk%FhoYm4VSCV2F1|nh8-=F04^dY)+o%yNvniDIR?AaV)EV<5)=fA849u zLM;^L$z(G04G%Y;Y)^MLGc&U|jwDl@XZ!YTkhOW!wL3_LGx%g4+w!v@gWUhn9Dzs@ z%PF`&wBjP;RumRO(Oe%xVFpbWc=_J*ICK2BTygpNbo6fI?{B^pT?8=-?zFMHJIwCE z9Tbb}DHO64i$yXSH>fg|N^xTRICtHDH&?#m9jl|%3o;ow-{_M8RnWs(@h=lo|6vS0`B2<<%Lw~yU0IJm8 z-vi?;2?N`-2@oTx57UNCRi;s;PKT;v2)Ceg44ctJf)X%c*aXcgHCd%gjS<#WYIdGh zJK#=X1eoawmx(SQ8jaG`6()6NikI(uYqPnvZIgIB&Z%R^xO~sW1Ofr3G6sowoP~ul z>C7}+hKK1)B#3y87{J%Rego6f(_}Ik2I6tz>-+fDw{GHB|M^QEdF0n@-?WMLP>572 zgOrk~sX6KuH+v?Z&+``_`zYs)#ORCeV>WLPizYBj2IiR@U-`;c&~=@PZ4&T|`g3!0 zeBu+=lTJ?)6e`;{ZDY@7@@Vki(JTcM27q%w3SS?Y)Ad@x-@7Tll#^CVr zSvFa)ac`VUqEX6bi53HTW0H)tu%%8%tlx!a*akk`q82M~(+@sEi`M0B=fdcs6{MtH zS6RqpSVppbG)X<<9(=ZGus#uIB4@bd7e$ZkvDU*VS9Y6PaElP(D zO=D3y96o#)$8p%Xb0?1DaOlt>>;<^w1v@!jKF;iHmTeoivj5;i_#J2sYE;V>Gm65d zO`9kdvnYx}S9cc&4(w;cwoTL(=-0Zr<(Av%>2W1xfv_u+oXyTWqhMd#B(%wMvMv`b z>~1L9QJM|cGLC2RbZ;whn)DaTD$}88Yp~3#iCc~%(S-KA_~5nlF7LTWn%77-tHwd` zw8+ob@VFE*rP(AYiqe#Stu9=bylu-`Nt!}gI$&3zD6yqys1@!>*x%oeX__RHNv5Z# z>DGIx3&GECxeX&{Qo>@&(x}>PER&$OcRQzZXX#bppMUWKQfKB!jtp?yZMX5kzxpcz zfl!kUX__W}ndW7qyZG3(JNVmQjq$VFO8D+R0KKXk{Foa6Om2AZ#pq;M)B|*w63sT) z92*_gbnLx=`RQ@`62nYS8^rY(b!qaFtx;YuGzhdZVN4T{ z8d5^hY>?FZdDZSX9We*fl(efVQd425tje~-qjWg*K7TGQJmJPC~Z{#P9LGuy4W zpM&mX4;_j|I4n4Ob_^7#Sp|?W_xIlwmO zv#nY7TzV0U`7~<(C>0?onI%$Z^6=6t;TI<$yCNfZc-!0F#)A(&$i|Hu8K0eHYHW;# z6QtruT4aNyu2Z++dw>0LY+G{Y&+laHp;P#sGRruuQv)2h_ct7S@@JF)Gc`e%u49@e zwiF0e#iy#&Y!`34vNCCrYeyA+>EZ+==ez`~&$e?-3SKQJo>eTL^Dvk!+3x1x$#jPO zzcnDNvp;*1-iu#IS2#zxT&Anj&6+~fa2(0#=te4qEQ^jS@lzD&P&6bKi$KjP(gGN> zR@1jv^Kke}NEF9MhlsFc%K(;bGd4L%`s`Ucl%NZ0k&^6;JF(xobq9{)dZ$BOy`-{5 z78VM;?b>(n#8Z#bt|(37YZQf?Q=mh*V3nHYqf#s&wV?MLIOk7M+~HSMT9hjVie`>{ zzC_kEUAeyW(V{li7|Pe41wPvKz^d1F4cPfyOycj^eEr{SP@elS1dB$V&P1Gqu9Hqr zBc=zyC`r>ffOMny6;HN^$HFY)AF8C2D6UdG2K z0JnKrNaww-yOl-54fLB#XV7(lu7^mcGpMl;NKn-PS+hiY-r&Tk)7Z9T-@ccUO{Iv$ zqe$r^o0=xkn_%0vODK3K+eMF|o;7pCVqG4J*PvJ|0+L65`&+u#c?qtTg_+ILQkJ~_ zP&Kq6NR3Qr}SOtr$S7dG6xRr1?jFb+!oXNnz0J&U_i!R#E zwr$&+n#y)Pgl(I2CK4>9)5Ky4(&@}ORIh39@_qYIRX3xfC)rP{Xr*4M5R8T>nH3hs z7EpD8Z3|R2<}tM0b?!pCf)FL704*_uVU!4=5?6I5(;1YQ-~!zuZJHodHV?%)`{+3B zKwXW|BNaLmIp&NUA^M5MV=U$kGU=1ljV==U5XD%iSp*3o(9|#|PCUuxp;6cWA#I}3 zIDYA_G><&_B&zD_j_pd7kfN|@bQ8&Bl6F;R$u@cARabHJZfFyJUu>5M=Zvz|MoN9@s4-1j3k?K-zRt8`Ah!j@4v)FyY^6% zHmOvKczhQdw`TaoFaDE7!)P`smPb5WNE;*)33NS1&NLYs8s)D(^+_yCy3-AB0?>|w zZJ8WAc!(FhY#*2J*~`TEG!-G}>gu8=kszNhu?z&|xr@19t~Iu`sDhejxL?Vf=!?Z@ z3xz0T@*sVD{JS}Re9HuAQy^?kYcJ%w-<{^V-Z}p3hRaz>9j6VQnynMqdKGgvyyjis z2W5cke&WZMuh51~`{)qw`tIZ0^6!h#J?vsnZ_;?}J36`PeJ?;MO_Mh=wBqVXtExaq zn>No3XHQFBf9+plmP(9|r@U!LD~Ut`DQ!CAG3<)X*jS2)s$xrtP*s*~JP3nIYAy{@ z66GyVGXMY}07*naR15|QMS7@NE+Ixb5}`C$^h}S-I3C@`4Lj`gisv>(5EL5ALQpQ3 zaR_p1>@0zZMm)TZa9GE2VDr!@<1@3gdz%-R0H)EYg*kcl6kW+4FPUEBt_SX6$Bx|; z3I!ae(46{Zv-4V-y zU3y5;YLo6*mXe4b<4h_=Fxbi8eeG*pb=6haw#}XQ-_NK2_H+E#y=VE#U*8RM^ZCE~ z1mAe~W%O^inf~^_;j6c>P?SZT|_CT4)Ztf+d*+>ly80G zzrY%RNmoup_$dGK7gzB1Z2=0cDn~Ptb=V9hbY{#vIA`Fz0jT6rVo6k)N9L<&(f~Ql z)!Sc$CIptu(>I!AaAX%DtIV14$2pR(5PC*Ka<0h#?`>Ly09EJ|Y!k4#bkh*uzU?tk zRiqlDJ~6?fuCpWrKEpvD-NpxQzMEI?-Nh>tG3L?+HPt2q(^) z;>l@#^^e!{mQQ_^vh{MXVz6ZjPP?+66(ZA$bfoPWG7%SkU};Z z1ck<8KF@~!5T}kE=leH)h?22LM<4(~;*|0zp*YvP{tf)}7yrST6rNW^Cni*cG|3ol z(5O$ef-PC$_dCxc%@NNqazArQud1q-cOjn@X(5Ebrx&T1RVt#vq*(&XhAy3p-?5ME zLkIE82Eky2fsK9mq-1!@7Ru5`S67VvzrGL0a>!Z*I;3C$hc=)?xYy_wO;B;#Sd``F zXR}QxRIymdWth&+a`xI`kABiiW0XEXqkL1vk+9 zH@|s+b)Gj;2WnOpM+j6Y3HA-LI6F(FP@pc{tzW#m3#n;LXR~fbu19)2)XvJ#vd_mgtCu=o=cMBNii_PSZCuOkK1h zWtDX+Z0+G;Y+G`k7wl)`Og3%qM>-PIH2BsxZstXMFTt`b;*oC7PMoFPDN`2?(^IFI zKQo1b!t~TB7OVxbxLtUmm}A|#KE}pQvE#h+IP&OWBH;*F7IbP{|Htp-O)nmx_Jc#D zrpCGKx|dKF3QrtAP9z*b(-caU1zMPzC7Ez?h+Gjx2#ncT_V0g)FMa8+F-?<>ShQ&> zbCb$lsZUS;FsiD$VSk=vV&{(CEMyFPs-Qy%X7fg~i1K?E6d_>FH0X#8lanDN5L8w0 z^sx#SGPa51W-Dz1y44D%F^*3UQH>|rpDB@+K3eq-d;+4Ic9NYQr(M_#4Gr;Fr4>V! zNZUuhuo;Pl2#YAT?NAph4W!xZ-*dSfj^l9n@NvwN!I7uOx#pUyh^V@IJ4IO))FT-h z-prT3{53%GuRr}MS6}@y!r?Hpvva)ZO>bh>Fe#Z8LVAF3ILxtAr6he&iB zwrt+aWID}>@o|nGeVU$dFK>Cv>)E>D0+d*cmOy~{REFqi2*+_KnmHajTIAr9!0$Mq zXw3^(r{Yqv9HC%2t~NZEogviS%}6qdbQBh48K+>e)E&mQY!VTTOd(5D6SQdIropjL zD7e_#h=!)EL(^1_96Zj(jaxCZ1)|{yHP1g{SvK)-oJFa42w$gZre6t{Txq19=|Ngr z^))wO@|@hNRa0mY0u5IlP%IYKgk9EG`APiVeYJbYWyf*60?a)VR+^7x3!EYA-}r9r#HnntI2HVHwCsuCgAg#V~WmJOiS{CpIEkH^QlVy>1b6KvkS{Tn zP9sE^bwZ^h7UNiYoNzMAlehg9rda`FoEdcLw!u1G@}6rh;x*S?#FClEn8+i9!D1%C z-FMu@&SWduRNf`csOtafX!lD=9vg{ZV?5;26=%mm4s%Bat{93kHs(iF8z`e8KK|>o zeD4-N-@D}&oI9^Xql=<34N_3bnV@wMi?)$Xr3i``PnIlZCT5xV$saRUHCW#&IW4wx z@jDN|tl<@sZl=`ob7W(cymQKLnABvI#PBdnCY&`Y1VtAa+X0~xL`B+?px$6vw`r)Y z*mf%c6gpy2N=BNjnWo!A-?!@t3U(DC9NP7Mq*Q2?CK4ZuMu~O=m6%Subgx0uG@-kT z7H5*oOpc1uO;Bi?P80^TG%v9%A|E|MG>;N;n}gd^P)3li1| zw-}#1$_vlm%(p)DR!XT9Rw_g9Ra+=eon~Iq#;2y5} z_+OGeIl;`h$GCw+34{dh$3myGVb3f)-Wq+dJ;%vdb>>q5%YcFN000svDAQdd-JeI~w;tM?68D z)lG_AJI`Oqy;$=#yt8GcX%Upo3Q^HbKrPdk2)W;rOLO!4uH(i7x3MgG33YelNQrbT z=H@1O;`k(kgM$pNUr#ER<=Dx?WEwSmz(8E%C3`PHD4^?MjGWEG4n^td}<^!ZTy zewJ%BYE}V9Iz%E7{Eow-bQ_(Xo*o>>g)1qF8*kC739{K4Ivj;mZk%9HFt;$x+`=?I z;9b|ggubpYt(xHU={Y85XL$PQqplp**FvpPr>-dU_4N^tL`bY(PrG-0Zxn4#c}V%H ztTgK*_p@m}4@Ou%PdvnPXCnRI{qt;v$m+*f9UPfR#9cx#(yR4NF9IV(yQ;1U6kq** zS@tT*dTWEaP${O;Xu_tWSf$G4Emy)b$c-?n`CDWxjt#nKvF$^1B zk7Jsqn|&c$ftBz*7h{?=4T2tXT=np*DcO=05clQg^) zdpOd~g$|K;s4`83~t*H&J8)kd^XlD;qA z3Xd!9g<6x~O!3$c-a~X4(zea9Oo}T%a0J2$n9V?!#b@4gG1uif74oR);99OkP#hl~#KFD_{Mm z8_CZZeCaDU@W|r|6d&i;-~RwtZ0&&j81KHekAwTRaLETAz!o)SSJ#DDs)tu#V9)48g(T9C(dB-q+a{XU3 zJ2%CVgFoT#zjy}?zn?>!^7No(@pHU zcn@Fu+E>YB^0Wzo6e_AvnX(PeOC~*{uDiNzL!seu(H#dAd^k?i!r^9)SY^s(i%7&> zlgA@Hgu1)YG>z=MOY$n03n+?fn7s2hzv7ZhF7cAu1*cA(Wyg-4oH_1b;hHSR#>N;O z9p#~i9wMZ~nV&BZ47yvF)}V%_g;5k&cIG%xb1ar{HN)p}UEVF$0f?gAb@_B953`)MOghlqhHNTsG}FS&^NM4}%f z?^5^NbK@ZX{t?nPs8X}RWo+s~rA0s? zlcFc7!;5!AQRg)u{yx9??3>s(x(w3fZ;nU!m+#Mj7UNG|dmd+HH_~=JVU(&6j=`M7 zEG-g^4&tvy`NA(A<>9Y%aQ)G(EPg6Ru$1QF?-t!{(@PTs0)Zxl>0Dvz8FhuAA|PNY zBZRN=L1dUh#f4^YSvTD>y2I(|33NS5ET+;XB~rK< zT~$4bZQ9iID9f@+7(rjm%doL+Y@ySs%5#Ntp~$?IWnDzaM}!4S67JTRn3!POwrv2+ z&d$=^z0Ngiw-L8m#G7Xn*=g05Aj5gy@21Z8# zAK&=-k9gD7S91Gpw^GW@vU%e=+Pc>ET z#28H^IGV1qzJC)B{O-&2_3BJb8C-SE8#pmBPFV_`e)QHtDp9u5V^4Q=&z6hnf%E@k?f<%KNU`LoAlSGz}Vd^*JhB`HW1Ma{#5a zehJZRL`>5}Ri7E=s5Un%A%^Lomzr?~JG}^^3pC5M@aHB$?`3r3MwWA@$Y$pWM8b4; zyJ{87w&)2*sB=kXxwBYOBFhW3``irO-IrW~-+}%64`LTmsF7io zJOum75Neq+9U@3{-4IJSELsJkLc?(iED4RizA$gT?(O{T=WoR4a}|dJ>%+hTLMVj8 z4YZ=b`zQ2B7llHO4k74J1cv1TVT#2fVefq;L=auq38(=?MS8L*`MiOPYlU9oId385 z?{8%OzsbJ-XW!)3HToKF%*y*`ZIiOL(P=~CM_}ahZ0PT&GHtT4Kg5G`88#0jT%Y3V z+NwpBZm0w9o6EKhmdq+bs4P=-{R!SgMpXltrl&<$Ti0}bQdXPz(yH3(6_e6K^?AV& z9{IyB6@o$sG^A9hsycPyrkK_}O@CS1)CE*pZSqxv1zXZNJcQ#2G%dn{Rlu?ega|Wn z(x5Ek+_nEW1=&W~0mo734X*SI)n`%wcban%hJ@~0L0Rh@D^&-I`E2R8lDwa^0HzBZ`A`uO>P zkB%m8k$x%2M*ZTkqj?YKHE<9vU==1%vbjJL&8U(xSrq-~SHg@&=2v@^?4? zfZ)18@cD@a<8-$K31|@y^dG)o|LW_^qpn}%YLWdBv0(&n$pGWuKhm`JzBcCsEd^*P~ z-t^}#!KJg4_LdejAqWN)7Ut&o&Ue1SR3_Cl088)vD#W>@Rv{n+WNecb75q}C)mFJ; zQ!Be(*v|_N`T>>Xt_#_>wS}kh2RSHXOysLz=LvoIa0IV=rC(&NoiT1NuF289%Bl|8UJM|Gh^X5guYML?mB%k=~2lG2aofkJpShLl)Po$o?B;y6_uh6ZfBfcmda1|mg(xTl zLE&C>BdSWpHfa|E*6HL}q@uV5zjP#u;v#_6POZ76s96$CixBj}96J=(gjmWJF=n%# zmqHR!I%y|Jv1swCSG^9)f^62Jl$9jAdpL6NFph^eHnUkO1q;6;85$aL4f#P=_pAk7 zDolq^$Y$Maq#Zjpa_Qx}xcu^6Y}h)ABA~7a>Pn-D^j-0rtkAKfbUcrV(+pHx!Tv7F zax>dR2&GBtdM+QziX3ZEma(jI^D$PMqDAN2wx&aI?{9_DCB2`wP$(d!Lx%`9o1G=^ zxfP3rW>(6IG2d}q$;8TrWl=hwEJAAvK$dW@EQ^(8Sev528ho;74xb`wj9NvmY0z!k zCKhwC^lZdL)YTIbG#4mf1(x$4~ zooim< zN=8rQ>G;so_RCwwq_lrtZGAyb(=WiLbHT!=5t-(LtxRdvXyMP@OG#X@u;h}sYp zDndAbPDRAXs15RZgSyaJMx`hmqy$}$HVcpvg1S&q)mFmNq^h#(H?=M}N+vV<&m{Uw)j29~(ne`?&wHCwb|suH>sX-;9Vx>7qz9 z8elAIaoZg~VEO5L`PVG@*6~6hotFRyVCFSazhs}?1T3Gm1%auSC9DL3KisGOs zaL4>_J*qMUapy6o-3$V zwg7JMvHRNEUih(W8oF2La_7ij6#+sVU@4YhvDyXQ4S2y`t{l05`j+$2Dbk_1*Sf^u z5L-tsK+_^vR*^thuwYr9HOckPjSdcy%gr%$YK)+W5FhAc89%ZCAv(z(I?CzeM_H&f zXdit6Lp#>9ZtHr6c5Gzxj*aw;b}_PblzO+Ib)8C7gYIsPT`zkvTXybbWa}t>eLei} z>o?Nf;?6yLg9>wVS*n(gO3@;$Yb3ig{666B?{)Ud1q(y`cj-g(TNVm>k_L|IuSD%!nL0#xTf;J=psUT$+70-XZ(uAz| z(N{Ml?qJvUdWUl$g=NlpmZX%;2$VMOd+NeP7UyMxfHc??3-IY19^{{HnP)lCPdFZ+ zUGG|(qw>rPY#Y_)+HZA7x4L^fqN zOYgSL3X7&2=xC)4mH}N4;g^zD58vvS5`Wbu5>RPJk~=kqscVe(tfMueQ79Bx0)F`O zd+Cn|d`^*xnKbpFK<^%5He1B+bIA)csT4y)>rjNClr7NR-A&%I2t*<*S@Rs3&G6t8 zGl(Ee-~1D5!65NqCs$wnV(z>BUM4fstecrdcm;?Mf^ay3nYBp_4mLLqi9`awlyvJc zqR}WVDwOjjT3cHo>JpUl`8+LwRsw2>n(a;?a^l>I_55AukxJ#!brsE)Oc+zdqSfXL zU$breUM`1e=BQOFuF+CascIpDA^;CQ1l^mN{^46m#!beB&d6II0!8J^kDO(>R03;` z-4{6A_o>$qMB=;o1gM+1;Xm){&`Hp5VFA>5Nhbrv|A zIRdnBR1R{65jG?P$b5w;D#1N3a!qw*hgdL3Ay+^IG!#YQk{!Fqm8!&|F|wr!dMJRV z30gIs`NBLwzrb1p;8m(A6(C_q{t#&?DL+zSMtK-D1Y`3$Dvr|@)rcWW+%)@GD zZ(q8EifwYm=2!EhZ~l@tY_<+ZIehpYdh{@+0UgRNd@@Krn`L1AAhtbAuyq(A1RFMt z01k%_AEaixh1#rP5)^K(i;bJXv?L`s;B(}&U{Wha?G-{+U1{L=CYE@chjwV1?U%d) z+AkffvP0F9lyXJp&Yoq_k>?6{@BS18`uh4%gqx8v)Yr!`YmQ=So@6pfx-d^j36l5V z9esT(IZYPfaDIz*5~FTl~V%5-WG79FdZmGWHA|5=*hX7&r9 z2>g!pkkX!UUU)43XGle)H;{@&W5_BP#sslgjLA%z_K?ojs7nnzdGZ*4_U?CZ>V>heW)*i{D3GTWQQz0%V1FW(JOUo>{2$=zfyAP|<~oz$QO_5>?eXdf#W+ z{>6J>Y8d|cm#||PCXcc2)uVj0WD>aT{x)Xl&iO)w>3`wMMyIrdoFB-PgO`v29_mBrBZYylZ2ac zOOTEOnoc5~;P|maBodpjREcStJbv&fC2}~1!oh=S?tl1Km_?h*<2s$M+C@w)66PrX z{KMOM@Sb~k;)#<8A^4kr{5CFsv+{?ekFX#m4cn%D#ZO_T znV&CEvuujC&E)JX@$N1*Y}i0CS7fNKmzE6!%$qsDp+ST8mKJ2aMqMoM(yOoFPp*F% z_uhLK-TFozzT<8d%Fv+{=o{?d=vawb4K&SR{uJb`B9Tbg-6U&47P784%8@>*jz(Qk zc=X;Q)D`!9TF&~2DRBz*3?sf47RwII&Jq?~^pC8^CxdJWYy9MA`&j~dht{#^OpxsE zW+lLQ@7}$PjBMfI$A3$^qcAmlmMisebI4J!1wkR0BZscXyl_pGS}ew6=?u~qtk-w5 zK79x!*3TIkrYJ)shle?mPT|u>DC+^bj6Cfzld<%psA_^Lpb|z)^pY|m?B&F%2&6Qd zIN@br&M@d#cVX$0f;~ zMv39!B&KN-Q3U}h=#Gz)9GQU^zKrkQ{008`&0l2V=`+8tQF*>alz7gy(xQ=HqieLy zir0a=FOc+}r2Anww?bShxrd59Zg@rcesBQ<(45hGf;~;~B8##Ua zDf094^!Kb|S<$cr9Gsb;Lup6riD5Yo8iGhfVNv*iDv{10LJ3kA4Kx%AMH|bJ-ZU~o zK{&K0I|+41cyerlNKcYV!D4c9lDUNpiV|e~;2=^$Dw`#nwTMK*O`Uo!XW&y5KKikb z5)Oyy5H7yZG_weyd7Y<3Rkh}nRC=bdV$o#t=It1UD|uM0Vf@hh{sasNtF0^UHBX=I zU}Mk`i=l+Pe{*1}2>CpW4C-96ImEgUlu`!?B=^EV0cLZ2NYN3CVcISSe)8l5KA%E*VV;=MNoQv#>4gmCe1%2B_9zo7PaQtX zV%`LwpK{JZYtdY(3XmMxOkFgXOyz+*pkmt(6g&lM-4bsJe>uw5XPGC5pBnZfg_(x>PrC(G>i{`*v|g=zR00`?&p%4BxnBiFfT0Jp6C> z@S+#Lmea*K(rJSY{Rwi$3?ZOk`3MSy-o7qUxw8a&Tj{O1Ab=xBjxaD_6Ank3pZ%3Y z+M4tsg=TlgU!l3A*?iKrm!aUJn1TCl#>+2#A)|!-; zc8|E%6HmJ7AI=KVPhoaumi~Fy5G*Vo092M!VG>A|uJKo?OhOg1~q>}<9vhZ@IuwmuDuv$Dv&Mh&Ov8Jdw=G(eb)q~2MeNkh&1mY}ePA)MK=&A?gB_ZJPztrbQL! znjitfUP0`h%OhGTlvXlAmc0*~WUX1;%`0#rCgbB1Boc9Au^7i6f7splcpK_OPJf5+>AeO z;LB{mn~yY~=UR%>A8Jf^&XBp)4Ne4PDpR zfAA^#yVoHU!FRv$9kzJE&OPBUw~ie{(_qJr^YA;kA%0dF$AR#=9_p3^&3(@#`-hn` zN;tIA=E<`IYKU6QWbA<_7~C|>@NkloC&%dt_wt@A-$|*Irywj|@|w3|mJGHG4SCH* zjI3Eg3isUgOO?xay^$@01zvZ-I;N(^Xw`bCNd;SLW9K!WTb5*w{#xOdDr@fnw3bvTPnd z{uH<0eml9`0&jfdn~6pPn5IhEHpyl(7&a)TLByl<$(3r;aYK09yaKecO18Ybs@4-? zwY=-U?~hPbL0zgSLZF8{(pb^JaooX7*rP+u&St%gDM5Vw1}w`aeRh^bIZs!Agxs`? zxxf2?G}m4CN@})F_Dqp1v&_%B=}6XsAhLA>?apBWK7p{-;a9SBNOu@gRTMAe*9Eu; zAy71pnVDJEty_=Zkrawq!r=%338ym|D%5E4!F8Yf1Vh99bVNg(N#*&+Z+@GKr{Zt{ zO+gkci}MCI^2G7O?AWn`6DLj(4u|Pf!#s89II5~rGOM)fIsu8Rrb!MXOKEy-i6$jW zGEG#N4C!&y={yYqbyX#3R}n~x(-T~%H>jD%m`_XAt9v+QOt2#%DB3oiB0*++g1V~E zuljIw9lvd2dXn6raD!e|Ri~^D(=t6zOTxjlRW_?&)i&^&wS?7y!U@@Cf}#|# z78dAGb`Vm6ZaC2FENz}iR?{FH?m`HKC!V;6Kl-CrfRz072mea7S|u8dlF#R<*(RY- zsJTjAS&gn38&`AgKlGsw@y&03lO?mtO*h@hz4zV4$3FI9gwUzjz~N&MQL*if&Gl>E zFo+A`Zd8cT2&+V+@W40U!@5d^|QMPZ@QVAG~e^hV>&6*Jgu-8#hZa1XQNWk8T~7Ff)gEY)hXw!-LWlBrCI zg>;5Jdj|RCuTDavj;;&*4z%IW0NQoc)71(R@gzpR#L!TjL?TL~v5ck!Q4|Nus!(s# z(RI~32m;M1>+>4j>?%@98s221BcxKw2$T{o-(NO3TZLl9M^r*gBrxO?RP-j$H zM&ki`B#4Y;a;(JH?)VIh{5crYv{t}x+g!X-Or03#<}bdQ_YM`XY2)ra^)p&xX4$R3n8DFaoVep&1_svC z+uO@iPq{=6(+hoEVe~KmUX82r99$X2lS^4BNIHZ-3kLZ=oV|H`8}*(4|CFrH*q)I! zl080T$4BfWc0!yqp$X8GtL?V11$uFnQhLy9dvAAt?Y7%KXemqEExTK`UCMV^SdJ|% zP$&g@QEn)ZKnReO#EFksJ|s&cOCxJW_Ixbq_s5KnK-#kF$0LvUc-Xo|pU>z0e!pJN zS4DVJjEeM-qz#JVUFXFjhHc}zHVfF)N=dHh($UvPgAnBM9=Cqhwh02Sj7~5QtXZ>` z=H_O~gOY<|L$tK4!M5}CZP>sw`Hr!hL3NxU#axG{Fze3DmxXqv`6 zE)A=wEp>iZZK;r1P+V%I@|uFA7G*hSMo|PptWdy~d?`yIjjQj+QsJ}o^-`c?YildX znHgGJTPfvigmx?iY_*4FbuqM5pj3{TetC=iqO!^~dz=e>37ArplGe^R$&`uXl!(XM zu&e@(Wzp6aXDC@f*W*}L79pxc1n7E*jN|1A38A9K)#dwBl#Yim}-t z5Gn#F`jZvU)EUQdtmO_~A~C{zb&=80iDfPc2D;<%{jS5Hk>vI^v1G}F&J7PY>N zHj^pZ9J{4+#xTv&r1|9P->t{Dxl$DK!wyNCi3? z8@&U2Od~NfgXVfoo7n(NL9@P+&7xgoU1u)~ns-!d)S?uSOrlfU_hvr)sml;TFtBwa zeVaCV*>!r9zP>(ksRBX>>U5PUGf9KdhoKrIeZWjZBy!A)DTG(BFI^KMDgVsGM80k> zgOrjof;#CSWdQOfNCzohPwFYWWcgAq$D%D!gdm;CFE@aJ=6G}eID=%Tk&Q5&nQX^fFbk5RTq{YI2aSc{RE$x#yyQ!EzI6@`*N&7a;s zLVK(gDRY$EIsWO2ue0aVUxg~vR^igKKTe|_M2+dBayCP=E&&3}Q}rl!uFHdYk#raadq)ezREG%OhZRVv%MmxoVw|tIl7qZ{5)K z$f_(mYdK4?)`vXARPXzWYLG(()nFoTEl=zJM4_@O8B+$lAf{E65bu8lAy#yyExJnD zG7-XChz${0z9WlLa@w2U%&s?{NX~KS?(W7g47P7Sk$dm`C1;;?7Hw*kE&T&tW`g4| zGBQk8*E&Xqhw19>#&Ik^L&Kv@wZx*!vX5xAm7sJfq%+hYC`F%Nvhd6au*SUt_;bDXjeC%T%qq(`6)c8@lyL*U6b@F)!MF`^U%{Y$3^z<|U z-QDXL9)5){eBp}>Pb3IR$wxo%VQ#wlX1@H5f8ZmRobQD``S@Zqpu?cS@FZmw;h;+( z(gd0gj-Z}Ag~BMc^$~LB3v7E;ILr%oUBPKz z`4-`(Ub2e?-ubq7BBe!EmI(r5vk4$TtTDz#@4kQ!e&%mEZ&QdKxO-+D1@B9hZU3VQf{p2U4QdxT9aZWqqog6&)lBcy+yguiAxs0N~C6}DX zx#zx*3ogHmSbZlq-gpz={nodDDzmdiR#dNW-+g!U(8Eu1%k4iQnM%>y+eZJU9caG! z*ew?+`1XOingDm+c@yi_b#dY4moqbw`m-_z#i%E5N!nDE5)SEt#YR0&v>w*9>r7@8 zZhkh;x6f-rI9UP`W_3YLTQ3)X?>Y8ApWOtLj>!S z%n6$fasq4xly*M6xsJl<3q!Q&obhx5+IZ@}%d7 z2p%(7SxG>zT_y8E^Kue|7GvG!b`MXU&LC}%hSSs2L*npJ=EjDQQle>5wrtppP!v+R zG<_W#n8>8b+BRX26OE=t35UZ>PR{s;ZkLXZ4s6@zmC-|-cG}4tIy%PMwFA^4m%w``VQlA*nNGBod-^p}d1x>Z>!Qog#RlCOClmcl3F zZE@xc7E(Gy^d_8=N`JoxRd{)5f^}V<*DjMN@Siu_$0t61IYQWU7=n_OAl@`UMEAC# zvg1w2=2pqKmaaX^vX)KZp61!`8(PO6ju%!Pq`Zl?MNvA`s4A*YK6-M`K3a5RS+2Z* zT)uW!<3V2?khnB`TH1JDZ62+N;}q)BlQ%2?YP^etX%bTnn)~96r?RN(HqzD{G1bMg zlBg=g;}J&9Bz0%oikeLM3%zh+vz+k%>dpMGP8@E)=7U zBO{}fy6f8r3kcUx>77^EVqm|5?6DN2WdfleNM2)kH zM|#&{)mikC>D{H!hE)?2UuodI&gyFlTJgVVs|TfILG`>6QcAEbQ1S$W-b$uN+c766 zS+mB&$=4#7b0wWEEi52uZ|}jed{3hf%Bib?h8i$kZxh$FAk)PPb2HF3H9@jiB@|Ye zo|r^Xq$aF*8G4F0A+9gFNY}*zN^TJm4x=gxx!erkQl!KyBf}J{5K|gy4=em}HpSFz zh1y&mt6HT>01pqdz~PriQNm#kA3jP;OEW@L{RS2sIdX*lp7pfFS_w)>rBcfwh^A?> zBi_rrHI3fc$#W%xcYN=l_jWsS$b0TLxjgWdbBPsF*p8(8tG@sx4jB{lIFJBzuTd>r znBL1Tum2$L`r6MRFL?a#&n7G+rfHJFvm~r-3bA{%#M`dBle3!Z`O($qQaZ4YHUZVm zoB77wIj+C^CCKmR$W8C{UwiQyS?lZhs8LlG9EYHE=<4d@#oc@O#V>xrx4(TQMa%LK z%zhg)8r6XmMDHCxHLA0wc?Z+e z(^P~;G^$`2?R0f_VP>WgLR~dUQP{L?8wW>6XzT7KC?)sY{ZncJ(B0j=Opek7@Yg57 zlB7;LRQwTexv9z1yxI;yS)qYC_GTp;dIx!QG{kw|c>?myU_Z<7udm?1feEzuAhk}C znv&qxw|ox8XyhYb|4$}*PUW00{126DE=HsZIHH6~h$_(C6yna?zQ=`cU&r^az7^=E zASAOx1$sK$xbymd;ArwNp%R$ZA`@5?(o>YIG;+8=Pqr!J>f4{^t>w{p%oXY%0>Ur5<;SUb?meRutu z&UFLabI${wKD1OKrmEBeGb4xi)a93R?bE-cm^Hcm_FEVnJds_y&ftbyZzYi!C#ni& z{$fYTLRI6`Vv+MPmSrKBlLh|%?I-ZXU%vuE=cx%er?W~i8=$6bJ3mjs{$I|6(#{Ee zVHU_U-()adS|poF5xDAQaCBxDo5{*W2HV=8rwB&^Jic#?HQP4RM>{|JeGY7$le$l$ zmN@@><1M`7?9+Jsz%%@AVjuO|EFb;o=h^?~eSx3- z`bhw`pK>Dqc;%J+zw2+}{P(?&V#+I4yzbkI(GFiS6mUJyNcGP=H}n4gOQ<@ z@;N#?`#5l5jA+y=kb+8-lI@^rDq~|_dT}zB`;*1WlJraXQH4osGnUik zeF@jfL}rEB<+^g2?zNOGe?0lt>VjiwqLR;hzPo%rM>HBEpU)jPZ-wLJC5U4V7Vh#i zW$Bn=xyLU53(JvXU}lr3s!DHXCs$u_6#&!Iwl?`%@3!m<=CnM}~t)wSxdv^33^%QBR( zf87uPIo3 z;-65L_1udHx;lHA%4Si8AfT(viY%y-yd!Dv?`5G-!Zamq>L7LX^@wrA;%k%9Z&it{^UfZ_AeY- z7LN0`SKnq3A5fsGNM(@#VVc5{s^&ptW^J4EFTIePZn}vbJ9hBmvoFvVi*dpUCm@6% zJAIV)_HL#o^Q6;h7V@@#J3b&n1}K^qy(jfC=41ASsM52xmkm4DG7uA7fBlbW?b^Wl zO>g4P`}gvV&t1j7v1va0H=p1~Upt4>-}+Y0fA2Yz9h2{T^NW1o@=tNi)!*XId++7N z(F64LHS*cZK0_^OuDkwL8X|G;J`_y0-8;bVfBzhB@9U>Y2r^Edwf$Sc-2*};k(*`5 zKp(}TVA0Oe6o%*bzf3h4pshK^%Lv8__ptc(iiGmmT$EQA=daf`P@@`X zSpIr%v)Rp)s0mXCNLMaHL2|hnw)Agj&doF9uU`*7_$wC5B_K$M5M^8z%aAKW9bt;q zIjW_AU!cSA-VCWCG!=`S)OQM5f1M}mJ2^{5z*siGJ3e|HXj@=xuZPvPf#E^Ux#R&x{`DNf)+F5f zBy^kzG2t~P^HI?HVCn^65nP4hhyq8tVJg5_vcN!Bgl65qMMX*rJC$Y1)ZnP(x6_ic zBiSfTYWn|*58pk-EjJzp1Q)%jca?%l{-2r>mOsR(@l{e4!Sd&-s``_2Nqtj@+36(Y zt>xmlZV8jRRHz)IGZkXh#Drt`*xp52J*I;!<)W`kmb|!o59_vX_H@Qpz#CnwD%t5I z9Y!-E5@47A2s45+8Z3rQ#QKJ;4q_1xyi9}*~BbbwtV$r5Sgpo?s zOa9bUDhe1v!N5a=u3fv9vYjJq+pKMr=q(=kt3e3QJg;fQVo_XI($mw!qmTXpO%doV z3X8UeA_T7Vq*g{i3w>9l9g(lm|X$tjxruJFNw2l?9HeV$~} zL$)muG3pGRruGPRkr0(Ubgt{dbvukG#3o0b%g2-B+WdKg3G@06KEa)H9`7US70C5 z!+_DpGb5wq;!SKuXXk*4ojgF|_Ky&_-~nJgvx^RMnADf6LmTuB#UY@-@EAt{O#30MF%R5!RY7#e)M18XV1Prpz8*6rp2~xySVy0 z-{Ct~e~ayBol7JVK?u10_FMSUSN}iaaf3Qt<;;P%<2WWiyyoAz`+*0@WHQSOWx*;z zjly@n`>#wS68!bqe@&)fvUTT9PCMyL?zs0}46(xDj>V#6r!%bY>cg^<1Z98=F1UbL zTN6({`6ScRCi6aZ4k850B^ousJwN?9gM)*ddFDF+K`NCZrs|ByP7?A-@oY(F>s+ZQNi7de{CGc%E5|ABo7;pu}%hLe2hTc0M8C}EXhP71F0(e=Ez z`&VAr^P+M;_@k_sR~q2=d8Q9LuOg}o9Q=x-JaxYYW^ zh+UKrQ<%%=a7J?|isBa`3Rc=h@#SGHYt~T8=NKECqTm*(n}kqUp;+`e`O-zY5*tXT z)4s{vOFNFnVm$Wjvvjw1f(yl>*X^8|N;5klU;qOt(J7zw&zhP zr1NMouV@isDe0M2SvJQ`e3lw6LFsy#6#o8OQ3Q3qnZ6#dqzlr=nXcNc7Vr$9YQ0w& z+|c>lo7VHf@BRf<)o`U`*RC^o?6E)ahOIs9 z*m5HCdCSKEOX?;3(=|WjFja&O$OkP`9xx-QV~Xia^v$3)B*jF0;17efK@gyU#uwMNuf*Ho20; z;2Yn_%{SjngAmNgS#AT)Pv^ zUc>G^lbrj$v)Mj4$c1MPK#cv%dNfBD#u|5H#sgMn*;e2Z(ady}#s>pZp|G zJo7AxM8czKl^o7J@BQpMu#av1JGtk;U2IUdaQW%y@HwmG9pvl)TifCoMs+#6Vkx67 zZJB_eC>5K&bcj3#iB%fY;XNW|;P3*#8?$&y#4R!VGf{GiAG%`{C)hoXd%w5XJV zU^|qV#x57JZ3k6#>F*yz)2bxL#{66=?^@8hmjC6TrPzV^e100XoPkNo6f`pA&BqU`v`-$2J8@BPLP zc=3iW^1FMlM)RqLyKep?=9B{+Ri3}<6b_mYQ#*L)wgo;Q6QJonbvIANa;S;-5tS-o zX?c=Yts9zM7Ntc^*GXJ?AKY@=7-)Ik)ot@1U%!;}#Kh}f3y$wm(h&mYEr+CKanjCR zoV0TnR>4}9-qs38PfRe_*9IL0$eYYNrDYG{YbGiyra`g109TIbyu5bNX)u~7I}RhG zqkQN?7jZN>OTy1e5dua=hS{=Z3#OT&C*Dok%3xU*9Y#AjC(kp_Ji{~3JmVDwhT*fP zy*G0vlc6pe^~XSxSS&`QrI~y_&75n~B%%nRk+t*QhU-c{I89>O5=GHaayjZ_F-E2) zX=!Q2wr!q$_9?2>vZrnA+rhl+QqHAm(ln%NQ&Ga0wo6(l*kj%}&r0WM)M9>t5=GNg z^7#y9TVj)A$Br}D{nVp8`|MtHQKM?Kb+=O$0yATA=N-54`Okiqt1J_P07%K1eGx|Y{*JKt8`_&xW=bY%Bt%Y1 zJh7rdM^hZKB@!~kWuLqb)(`UW=s5p*?RzO+Q!t^EFphq(HRZ}J~^-Aj#U+hOh64u146 z-{)(8_eFm5)U)V%GlPSD{Pxj@nKLcVgztATBYHiQ7x?YHzv6`L+Zi35KnTH{nPu;R zAu<`q_XP>c5}KPkc>2*td2!DHo_gZ9oN%Ita_;JilQ?pO(Wwl&t`iCgirE77^)*z4 zi{nUcxZ!5DY}tq&H83+KMaiiMTjoigaZyV_4dQq{eVel+W?&ucrIn} zy^DL<|FF&<_5}Fx7oP@Y3%G~)!Wa74)GtXDQe@E4^)7na7D+kdI3+>%U>`>cFQCN@ zzW39Aq*2v*=&1);(`=9~I1Kdnd!0Go{3=2!Q;tbbXD9Q8(y<2;;ZdWiiWhzu%-PH< zOWueT^4EgmX?yk77D~B1K_uGTYC(R<(4XaYB96O@uUH$a1;(G`m_=XwQ@ ztGM3p_yoZIwQEVI(*&iLlTxdAg++I3Cs}_&;sqHh)FN2d*~^@3uVk1gf?O`==lHB- zp(uVf3Ccer?_Y`jHZSCZv3%_vn8zY($r?@Ur@rFYg5YG{{0dJ zIaV^ZG^ttbS6RXi+smolzI4o|uPr@3Z=F2Wn7;r7ZJUZB{QMhOPz1Pg`Srq;-oN7< z$}Q<_C_8t)0mre3Ml}pYaA?mTs9KUjdWzl_L2CRZy46OG9?i35$GJRx-{XXvLe%0C zjp_`&e2`M9L{LiF+S-`6@;J8Rdj=f;aChuRxfE!)Zf77&ptdGUYC zNBC2eu)kc?$mQqc&lNt)g`O|TLlrDpxoZ)W{A+W^;Gmb&RxC2>IJD|IPe1)MXP$W` zzx&Ar1fi8}n~YWzN^SH|si6R+7e06}_gOMpeUMlB&o9Cc}H5 zp{}OJn?l->CecVTH%o748^vsv`o%>W6b;ifIq$slDLaySsS;J;ExUG*&rk92Q-_Gh z!+=eVdX%gi#*`9UI_P?w1(IwXh{NPC&D+;u^lm1Vn&Fp^KE+HT!O16Y=iO(Y&yBa< zN<|3%>C4~Z?))D(HM)!Uo%K%E=pkq}z)iBzh>&xV#Qp1gsY~to#=KzRnx()`1RBue zUyD`g=knOfsz%a^alS?fKP$;O?&NLdy7)_hgo3i~V+_`ZKmkpNhp^i6^l`^bIjT~X3}Y5F^%c5 zF&2xSCr1cD&aw#lg-?ZXDx#C0KT`l@3vc_tASZ5is7xFspl{~cn=a+#_xv+2#cVPv z2*ah#9Hy_opS2_Xm=ErQzcM(nH%)`##aYZd(vyP`#X_P9K}q!r*O0VWv(!wr9Z1_W z>jqc;`Z=z+z6hGlM^BmJ#xH%4qoajo>e~`!apm=YeLfY(v1ri^=A`GzG5t{UWzd39 zaV(Sm-d-jjeFmmR`1I%A#R4uht59S+uxJMtVSoqi(YLmG23OoI?qayeQwg^KjX$GKdd z4JT~izWeT@T$WJrdc&F)qoOD%N()av{WL8dJrt!)V|$c$T=))NcwsLkvqX3II@;Ug zsA`nHb#FwE7{udEUgn8od5P{q<@x8H=JZqEN<7}oFMja=+qR!dy&C6WYJwgy%`Oq( z#s|h(_p50(os{Jt`UJBh3SYeQAgBXy_-1x(yNU$xfwx@^yWRtNlZ6Z3#Wx=RBa5LZ zamM)kdFOG{?l<$%duMt7{fD^X;vS5)3Ol~`GN>CteTo@z4%Nv7nfee1vnI7P)2FNK zXg|zV`}WZC#x2Y+j@WcIq5RW0vX<`dbzEepiAs~KDv+{3e*k{-@Cz)^&a+2%H5!MkW0 zFQAXd`0r>Ab&J87-Rp@=IW!`-v!F zaJ^|tE|;SztazGsTVhV7sfeXK5<$ygKOG&-IF2XVT-V%#lwMfm^jLZ4J1@7_l~ zHN*SPc{>k2_#m3rK}SamMX6!OY?_;!dE}9&Rve@L$CBKvLGdzaG$rgmm+moMmnC^x z&|V3b6hcAKlw>9j^WNWPqTfIGI?oM6*m_34@~AOIAIEa5QqNBv>CJmMzd^Nji-# zj#v^?H&`bnGggU!ZjhG_^^WCBe;1jSZRDIo#8j2CW0AI!7=}*T@5ZsIkaC!aJ^)UfMYT%% zh8WY+wYct4A`ulS1+8seOis+;RwZFYP?WROYYImaDLOjaC`$==IQzang9QX@bb;e6 zvh}pLaQNlD?0@bh4#=lzUH=ANJ~GZHKKKqo$wSokcj7n&RHvD$Eb+u|F2hz`5(oD1 z^9OfB!C_-_GpT%@PyFzDHXH49nB#o(Z!hINrO#3q>0)Y3=5D$uD0XqGU6!vX?VuLms9;^dLc$_f<$VN@diB%~mg zs8;+5$)NZ%PzLXC8+0^ktr2WprN*2C8-_GEV_OI4>zT)9u~=k!bQVQX2!+E8Pfk(? z7-5AuSD|OXn~Hq$>p#YIUBY2cj=NZt$gsdl?WGQdrm%u6COG}Wg7ke4KnucsW3KHF{oA6cpud z+M+QAHk^oUdyS>((Mc3V!Bo-&U5Tp22(_%?U~!ayZzQjmE0f4YwVl!Ie%`T8=Xb9- zJap9!=%v5nhTg4wq#xGEJkQ*GHt~3zp;VShDQH&>+){wej>B`B0**ySuA{*U02U=7 z!4{ynbO9!kpirroCNVWmM(S8hfK*|FP0O#-aMdJqY~&MXP4O?6eUz6+3sl57wRFD< zrX^qX8ZR|}q%VAcAA@Yrl+Twu`<*FH3*tII*?M5&*vE%8)NF|1eF>H zmSMg;1(Z3Z|8#8ICL$UMy5I;{R3Iv1D2hf<+8i7m^6yoZnwnb5Ajd=a`ozZhvSDTDHI|C1@Ai`mOsQ z2Po|@^a%4;6u9J5r@&AC9Wit^-`epDuUpx%1;(D_zyqIVc4!~c=ps6iV1v=cgk@2T z)N|*<_w(cLeT6T4;Q6s}z(C4H7TfCiBhc5b6QfGM z8V3x<6}aujN4V*m|IFA^|3-&p5zrx~wJ>qy01Mp~rS7d1)I|oG*YWc3U7U8>*)+-X zdBM_&i4+kbam(wt@Qr7aNJxG)ZgRh~pMDe`zyG&fe(t%PoS9})A0Q2MlVj*t_jBs! zzsme+8qfUZcQkfKXge6DDXOsZ@{4)WOd?gCNM{rCH4CgerHhyvqTJrjV~;&e-wAKv ziC_PkfBpXVxqbWy2!ohfpeRkEs*ZxnoKrvuk1kV@E@7ck^gF&mp^`6IykX-Oq?Dvm zNqQWGq9s{G=YliO;3D1Y9+#bQGAWyv<%t+VGUS-_#^ac#Nl;pR>TSCi9esiPgqPwv zBN7M!iKK&J#QDsZ-plCd1Z}Fy(V-!)lPev;C4mz>y;dX>V^QJMD!vs>!EVv~#HKI+@HUVJ$|7E6Khh+41&|VCs^Ey(83jg(z!9 z=9?T!j>&=qbx~y~nWPp$S8o?q$zkl!5Qfo2PiLHDDv1!PpNzaxh%6cJmkOCbXBMwT zMIv#egKp?tG2ORo;ZP$4 zlcavgK=dQNtd=z55vm8B}YpwD?LM9#8k zF#PG30NwWo1^wVm;TvtM<{=vN0oH3eM{JGa=JHlqmCH%On@2!Sj8d@ooy8DqBj9`7HNuik+B@YszEWE#C2V7 z`j8HgN?FSobs+?ejg6!-Q^+8ci!NPVZ6E|i$6;zJ!>+fS=Vko><4F@CyxgJPFTKS2 zP3t-F#FN?ci@?6>m$uYZ>te||Ihl8ICU%sJlVOtlQs$t0$#QXWat8ePYX9bh4< z(y!%_d565%%F)C$^U-D+ki?TFy~ZHpDVVoRIt)qLO0vJLo}q%pM%m0J-N2R>qoze; ze2}D*q^GZr!&Zi*HBMRINF6GQ#WH%fA_PLzfG>Gp%24?~4&h!iQK@~^`)}R_E1#$F zb$DL9;9RlnWt`XCrmr5> z4n4+NBaW(9vFk$|mL>>6%p=EBmH}L(53%u(--!v6jYbnfRjEjrGfh-gP@{$*XTqlK z@Na*B6HbEZ{k-|iw^GbXnnW9p6QCsQ*Swzilj&ngVBY1juxgFXve6I-g3|Rf75cysfQ92o=A0BpJOT(T%cK@TgQ_!YrItHUQaZjt-tq5v zz)#2YOz^kfa05U7@xL=?PSf11)1vFVbm(P1a><905^lZscGj)yCg(W3a_}X}z86GO z1<9jF$>%*UNh;&z9kjHxQ0M0_WQ#c#T^A#)Q=A%Nan_|V+=%JA1Y?33x5!4V*FPjE zw6?ZVEEfGuzlfp)aoq~VsVPFZ#2Xiwvxli6OpVq^A)Tk_I%t|l->I+HD3xrWiVn%j1I;yHMD{VGzT*sr2 z{)#v5+J=-8TiQH$|2=&0W0zAaB`ux3sM10yn51uc4?p_XdwA&i{XE@%Dnui^NwxWx zcfXC3`zz$L!))jba>g4yX-%sf$7+V48Yf}dH1#xb@te01Ixs`=t6%5(=o8#FEO0iS zNw+k)?fOsCR-YtcNlXV8X{Ta2)afc?QqpwFiG2OaZ}WzePi27~V%i?6qJxvyC_Hfe zm5BCc<{g1z6$my}SvznB#bJ{}2X+(LwvF0m-9H#k^3bntVEvhAF^5EE7dijj_we7> z?;-P>pD~_$nobmEv@rEjLA0O12DQowx`iBasA)6Ua?X1G;XkkC(#_jAcT+bnkH5%9 z6q3^BXOH}h3r>D31tgsaK6~*+Ty^DB+;rvt;0VF{-?I_J%`@}jJjtFJ9)IOFZvNC| zOlKDfIVSJE^gJdri#&4g_u2Z+i#X$5=Odg9xjmx{{o+Tw@x(Xr5)c*+mgNu>I!!{S z=p+aWZ?VrgUcgq1ZcwAHkc%$<(EAY~!Cclt7*$fhf}bMW>^Rf`bE1os&^b+nIGjvS z7q2HHC5kYJ={kv$1--rWmEsiDEG8D!rVxs7nXrcG6|kYrpnef5!tlD7{^6h^EE zxJMob=W%*QKUekWNohEPBK)k8Y`(|_%q@$q4dwFJJlukYF;iI!D?zrPWx#}C=#!z;Wv?Y%}xR0uJlt6O} z2Wh1~8fFn2RTJbgi%exp{QOssP)mSz4Q}|^k9p_C@1jPn$2Ch>ma|-hOl3`^gyz0p zA_&Z^Nl-dSydrzvm%d0x%3=*27%Zqz3F(+w zhc-1%1Cn_wNsSbg@%$OCwMfh`SWtKU?bQGPAOJ~3K~z_$IyLoTm6Y^Pf6SQ)>U5n3 z!!vLP9Z5X`O{g^M5oR38f;mD=s1z(oV?0h#btp=QiqNUUq_M4ynydj>w2NtSsS#AQ z3rCHUQR6i9h8QjsXf#WN)ez2%8qYfxI(~s>Ue*-EEze?IK&ZZX_sew)AiJ4%97C z3W*ejj700`VSZv1sN%XVsZySNQp3 zPt#`GJay0i@RR?(ntP9dsf~nC%#F}(wlMZu^WZc?MovvezCuz|` z1W~96n=UCyOtb-WDXWgY9n!CC5_~v6g8?!ixDSinXHvM zI1WL)wDW3x6K*z3Koq=*iW^;p`xdKYjQ<-1@$rC5())Y9G;wwQ3P5r;#ajP&=Ya-) z74pJ<1B8?+0)eJzD|?S}ENRhOtBVNV$C%E{vRG{7v!A(|>0*jH0?hlVM@vSAx`4ub z)%6ShAk{#HO0`N|Ab|9#Vts9G%(-D=&0DA_GfT6B=G$EUIQ%uPxat{xK5fHv5?IH?QMmlVoB7J;xAEQg@5DT? zk9pl-#woC|J;ER4oVRWXm={&Q8L(mrRq`cNM*=4G!ohVU4XW7O%JPw7Hs z>Cj*_Q_Pys#WD)gFyj9|ZEqgmMtSaiemn0_RMwN*Y(@*N}ZfEkx9-9uPpr2WfQC>VSvyA|y@`gFMwTyF z%Kl7-V6cY0d;1s|=ta{)Xd#UXTTrJdET6H6(SdGGSkS<5e;>O#x>>$x1ut~&p<0_t zB0WHDZ7unHhW1%=iN#{%azhR>GFIZ4IjyWbaxU?`8`z&QS$WnayuN-nJN9G{B1qo0 zP!x^U#_1e+>q%B*L=H_NDyzmQ@EDy<83@{0)f@yj^H(hrqKave> z)0Zt;nX%y=vX)FXt4l}#4MUvn6$ssnQvcSX}~ znApguRl}htp2%O%+>M>e5)26TCbrP1`>F7^^**#h z3Im5%>b>Pgq`Of_CAyIk3?o9?GRUhwgcOXJ76H8#45vXmL7sw;s=J7YbHC)IMU@Jp zZXi`i2u3Z(HL@U75I!oCo2XX>HaZePUA;=7;DqaCQ8D8Ck-85*I{h&d!)T^4>c@;F z@Q`Fc!XYhDI%A!n>J)qj+%%@3Qqg1(k0;P|9m8-C8!3y_HAUTf{F7mJ<>Dg*6-Z}D zDc|$r0OG2Yz{b^%iGS$|^0s^LIN@B1qPc>0!MNfSzlouvkWMo)qme4% zSd2S*kQ{|{nrZW9xu}VBEydGrT{?g)R98F049Wq>x|nw?QGJ@jNAB(IBbUojH8BJT z;o8&MplAmp8S>y@NZXc7)j|Y=5wD!x|9-CHjF5s zRFq&zGaNO8;dh?_YZhY(lL}oY;tw#Au<)va=4hDjf8#P9e&h+xKmBu@e*PDE_0^X! zruESBnM-(c!x(S;Q_3OpS!g!_Jtsfv9N4XBKG_I>oGoS0+#+5&98iqCNsB)TutUcXy!c29-qU@7jrC zbh(FfSr*Thq=jX{6g5JX?x(+}6CqTl;Dl3JR)KL*DsQ64h59LI(1ABot*YcKNkK@w z?$U5fO7dobG0P+)3@X$-)1xgIreJ>ossbf)sTe*}uuNF=_Us|6Mi>_=EiGY2iBaJ% zF^YvZSp+daz$`MuXk%PB^r33MPLw?RL=(eFNB)QOoettCuKegH}hJ9`Cp-}?yP`p$KnzU*XPefUNWo4<^E?)@MBzV=OC`0HPp zzi1&(K72nnefw*C?dMPNmp}Xu|9Eyamz=qXl2A#?Iu5Nlg4OHxflQK14k02sqwY4_ zG;KV#2O*#?802TS|BPYjm|k3W*Im56b_ZK`_H))XUnjrqRid>)etXw%7|LhxN?7&G z3oKoFq$4^9(uovz-F^#CJpVi^792)%Q!_JlKRp{Z@bZRLeDN#aCy~ffuSO`DCY1t0 z^V;c*cX5QK)2CSslA(riDrp6D3L=S=yJ%w?vHDiVg^iu;acP4pwosX>MnDRdSq509 zV^wRYKmeb#fbIBX16~PZXtd}Ny1TQ^!Lq&tMhW`lC*1BT`Ty!6ky1grTlbNPO}hfN z?a=$jEIFy}C}nzT6(AJbt+nzKb!|wsdXyC)xB?2&!~H zm9ElmqL=2SK}M(~6DD--=b^70&+35W{aB1$Jq=v)_=9lla(?mP>zvSD&*G+K^!3D; zyD*CO%==*HNtc~^ojyD+0Na8*_}Z3`(o2k47DZLZA5lpN*x1z#QU|S{o4*+4%=1oX z@!1c7oX^}JJ;u9tpG$S3hn%Iky+=LBY4O0&CCk-x{9_craq;hTEaD*N#BrYwr7VPT zW{Xd?C-(c*a$4ksAj>N~NSSpY=B9cq%VId0Vu}%PTvsefr4R>AKMp;lh~>VioA0{Y z*{}d(?iW^7C#BLsYElT{W6Ua&woEM76THH`u!s65EQ(cLfBlVePJ-9YQ#(zge@}*E z=T76&GnUiP;%EKpXXqUCF{Uo!PiwYv*z6hX*|U?#jA?A`*u?VXi#k_8>{8ovrLp-uZ=Sp&)IcAV(g#63fan zfBt-S@9yIG-4SCz%wxfi|H^khyO19osiPx#r+b)d zH>N-{P%;*?f;vO}A92L878bVoiCgb7E_L)|kwb)JAl^w#Em2|2M^VEx$QU{EO)RyU zyuXFMEPSwK52v(8sgH)SH?3n-ETUkjtm+(Qf6ow?oH&DlSc1xyD4V;BY)cNK6XUd{ za|w$GN;1j*js(+Z&*LwzgGYyRmyVO|?q)zpO5JfxAmjD&sc z&RR&d9iLy2DrOlY!d-va#=hO#IjKF$`KLzkB@)aMDyd?D-6G8I%rI|l+QnzX`?>na zM$ANlYE@uK7?LXg{mh3P*4)O~#~5gqg%CRZRu3Un#Vec!psFfWx=Mu*j7o{F>nNs0 zy^wgV9@3VDDFjmtom!D$#EjFUHXx)aG5U9pWN$B8wT4!$p$LUkK21}wmYFl=QOKm7oE4$C)U6CtgkZ*u z8Duh+;}WAdDfRh$j!G1gxis@o7_n`FL6v+yL_R-I9=0k`7zL&Xg<%|9-w6aJpU=BP zi6EbMXkV?3j&tB}KF7e|AX5~DVQ>Rym4Ex*6rr(m=T66=D4(ajy`7GZjWo}mO+KGv z#I;e?YeS3+!N9-(Z8K&t3SYPHM!NLe zk5j+EIV==`_8OfnH~fgl*ZzseEFIqGjtw@>0vLtu@_5lX7CJ(HBjLn;O zuyDD-)CM1Brk2(Q4{zA7l9X`Xe_X@s@4UoUF1m=4DLLi1A5yOcnR?+Rj3tW9)FY%) zDI`f641+|x2OolIhC$lR)vD5UJVG!oC05dM=ta8DP&`T8N|x!26NC2XzjUQJurZX< zqN&xPii}AI0hnUw^qEmARcO=;l*~Am+Qf@yfJ;`tiTc4rA#P-V=b zAl{;q!>AHIlrWgtI3C@=OPI%B?_gm3eo*4E+KcA}nbZJaXAW4pCziWD}~4Q#Wr4 z_q@KJYajRsgv#0a9)5Vi5|$bR_>xIR#Y{FzKbNfA#-8mOSfl*sNjWY#au!7ke90cF z)Cko=C*>L+R14KH6mW;MQJ~uGcft)ouGJ&tQYo%EzMgw-eFds(S=h1+ayh>E^$Xav zsS{(`3>sTnn4d9uYu)?&@rft#7cJCaEv+rH8J0G;-1)q(m+&M~jH}LGyb{MP@a(fsWx)-H@!Q}3nlD^&5jWoU3#O{g)Yf=;_r+ZtanptT z*Hgdd^S9l^gAYE)6h+~mZ@tCVty?+s!Y`0D3p9iSba!_$qiqqF=mt_s(uov82rl^A z_en-e*lHNn^iWL1X;M{^NefeIsOoamsEJ{1ceIVNhJY#1Q(dgzuz|+QF5{)uAM)Ym zAr6@nh-iV>MlJYMjt;T5yNARPQ zjCB)jQc1)u>_QPt1#H{BN2>l`m@WMKVP)cV()BkMHi&AK3QaI(IbT^(9IV8egr0cq zgE#UMNb%&Hs<5bIT(OdZR>zSp|HQaly(l59{jpsBxh5SV^HCt0xx4@ zP8`JuU?-%T%a#MG%Z4hGznAe(L023!T4LMIzk5-roTSWjmXj0ouLG2^oGLhd*)O4X zKErR%Akq06ON=I3nzmy;^mX)O?}Hg_Y>+C`r6i=57_(r+T}YL)tz1;!KPkhhNzdSy zCYF?xOi4g(LPJt(^@HXE&EyBCoQ@sa!u8)ihTDI-i_|ua@4v8<2bN7O>-@yWf^TJ+ z#wyBmHa?bN^}llxbltJb8CFH*(@`q`UxiTV@9*cNlZIcXUmMB^?+5TRNnT_+=zUM%In}cTbk;xp$Ysit~ z=Qm%=_pdmMKz0vX-e1ScFP_NZbLO$Pb0^+9fu;$FpgPpLZ=ZgSEW-?uR_} z>~q|9;|*joCevDc7=}^iusRm7xIWa5h;U+HQB@~3)-WO@5-Dff(;aglVACX|s-$o% zwf%mTEAL+gnK|6c5N9_X!eNG>H<_e1+QuWBMi@coXD_|R&7c1=BPOhPXbtoSL5YEF zu_n_AwSuSC{~7yux?C<$`}TNu=ySh@A2l(zsy`C zLI}zF1e|~KL!cQ9{COt6`Zi*+z{+R~Bc{c)a6O(vfMPwYy5e~t&W}%Qq{6QcK9gxF_!6&S&1{>_tb> zS{!1*3DfxEm!5}A0|@d6J#vX1DIEN7l@GztQb^pUobjF`f)__ZW^<2~RyuUMAlXjfE0K}st0 z2%;s-P!?YA8DWZ$tY~RN6jD@6K|Y?MRyUBkLCPoCn~;Rm02TEnekn=Cx~NxmrWp<* zYU?VN-^Vj=yifN#Z}FQOze8mf_E{ELRQy6xqYH+l#mEH3MhH$l;UqqH>F2rNg7Z;T z)pbjvoIo!p4!z<4np!D8)|jM|2QsEigcbhlsx{%%rw9dG=CEA@i$HAoGDo0aO?}YOo~6@$<-%tTrXMs+pg3Jmo2p=s0cX&ORk2OZpp(|Ly7A;Cdh z^Oyq}@;S!=%n{ey%$>Ukuasmmj+4t!K2JXHgjr6|uAITgb>R9~m}Aet0HIJV#k|F| zT9vW9WZt|*RA_<$ZGd9JCX>lCefo4hdT$eYZHS?Kp3crrLLrAT=7{FyB#MTD5ca21 zx+YsEPaaYxG&7Y_`QNxQ9Y9sQwg*KSXUj)jtoYM^@q_rSP;lyb$+Yn69=sHg61uV; zmYsJg1E#ZKUK(BQ*nRgTsgf4w&R6kYI-f&mC1fONOdMU>Wyh0Tis#9}EOp8xvP91pjL-Bao z)-@7oBAJY%>qa@KEHCG<jMjc;0VF5-Y}^U8xWNh&8bb7?u64^>sE#G+(62aBp`3tP=1M_l_dY;%&(ksDxl5AXLM z&73D6=gFrp;qz(=Z?uJ~+g8CxMK^D&z%%4|X6--u)Ac8?yj4N<*K@?z)_|~_K0pIM z-nN0AT}6I){-Fd_NjC0KgoSVhlNxl2x=K+>a+c%XHtsS8Cah~K;wCi_mCw(v;Do!+ zB-4|i1|T=YZ+>|*>pBJ*986PGbq34~JGZ>cgAYE)9e3P8Yhxp$#0ds9?*7F?#CB&{ z^VVyuSa}*}eCa|?I_*RvZFQ8g;B$LzYfBUX+nET z8XVf-VfW%CR3W+c+G|;}=1rC@SW2MA;Hs;y;iJw@Ui|CRj0+$6ST|avm3-KThK^$P z&|(-2>rJdN;e{thP)W12HNa`@5iEA&)lKSD9gkU}Qw=aj9K~br4RPb|UkCQF>7LJX z>jl4t$hTo_5rpLJZQVTlr@!;x_k58R>L3kBYMNT;vvyHhx{@oO9pIsRp5X02e1nBEHHGGKo|yH7sE*=2VN=4wf+Cj%3A*GJQaDs zvbeUc&I#KU4wCZ8zF;#fZIrx%jqM=8?f`>*09_uIHpm>goXym!3WK>Js;f0BYzIv? zs-vzUl7pCO)tc-6YCF!cnuey;lI-iFLK8rq?yfEewWpd2H%DuNayBw)%Tx7Vc(vL=#CS8Sry`ZY7Sx`+6-#)gE z+yC(%Y&(=^Zj1ASRSRg2WL?7&>mZHFgb~T;CoI}Ud9gYAFRqb^0cG-#TPPG=&%Xm# z(uAhFjHpN{nPM2ILS=6}fs`g~vs>uxE|A>OO=D{dJv}`bhJmiDq}^|N0+th#Qhf!E zou;!f0n^N47-1^)0LgfQNF+=$nZmLpkw`r`;ip3S$^|$l9RYo<&|SwCouPP~-L_;f z=Wxk0nY1ftwaJpE_RuBtW{M;;Q!yH*6WcwGZSTXD8HR>>*}p$VG#X{bj2WcUX=cor z!N!dpG&VNUKQM(kwLW59NlHC~v>v*YaYgX{j*sw^U~I@!cEnk+VmYBu5FrGaOoq)n zcQSkSEH^>g!-Ee#!rv}9A1N(#cX}?kc9^QFq6@*Oi!?c#CX2?FCd{mfX<1HUsVW#T zO?2H6VUMdiX0nI+`Vur4K#4IuLn+YD-c*WFH9|Jq&1g33>?3qRDwUu*Tn|YLf(BuA zAD^8WV6$3Jm1%P0%p(!qDXL^M0kNJgQ!MEO2=eO_mtv<<5SatpdMF6^?X%m6Zzw_#Xf|NC3WIR;6@O*(gXa(m z`>|3fm}P)yqhAfO;Nri+bRGHu!vHG@(f}EE1YdR!#s$xV7U80k{e1WQ!&q{`Q((`B z1qQ!v3-j%(e#Vpce20hgl9yiUgh3DF>pAYU$1(qY305q{o!7kzUq7E`&Y1@Fr@*&< z;S_9k({gSd-D}*rbD48bh9!p1`xl4#$(wP0Vl9IAW6b^5^Ca&&9w`Jv zq6onzVp1@I#fX_AELv!43gef-GCC1*4HS~eB$nkg^(+=veG3n58s@^4HT_ zgzrCk8;zF9Pg7Z{z!`om3)8Z&rIUjZP*u{VNv*Ckf5~AS+S=-h?o`)W*L`yEy*_~! zj(>`Sscjc26jAY6|H*>2w-jT{SZA3@8&hDIXsIlD)lU>cZYl8_@L- zGaDP3Id2xWog*5pbF7wah4|2ZjymcnhV4B2I`_EERViBvPj>p6uuh&BmYm+CxbVAu zP+;Vz<$_H7St*r&F+e(WiD4V)%d`Hj?cA^SbJjISFj`3B6Dna50cnvDIu-RkzH-kt zUf$dZyLuqq&%&i`eC>>tC~Rk%FuC-~vw5bwz!mqs0k3UlPHhAA=O4v?T{907F&e@F z_7@>qmp ze4KOsa5&E~OF3OxGDlQ?lUT=ctsUR$5y^FLY7+pnC&FMqMtS?0{#%^P=phRy3n zxMo#9k3RT1pF8bPn!;i7aR)US7vPuRm5%N~RaM8!MODdKCi!HF>5(u&U8g_UgTSCY z5@omCgwM$FVfPmP_~Z)|Rh7?J3aaX3yihyCL^raH$fe2@ue?9}k#*-@0*cvS_N^?>{ z59q91Ih(zS?aXO!XXVOc8H%SE7jX2_BN;`KFFMSTDqZExWRY{uxSmTcJ%=BkGz(o< zdAg^-_wIWYHU&WwJX%}gng)|U-}G5#>iY=Fe*CgX6hFIZ=f0iG^ZbTT$B1ef2w6M`;1E90=34nI7= zIhTFLK~!Wv_@QKZ817E7`}WT<^ThjL#>pIU?)~(=^tnk3vIAO`$*~NR`~L)5I_e_S z9~a?&{8Fo&G{_1eKvO|Z)ZfyiU|1w|!63GyZC6wM!LGX9QaAmXb9C&p$YcyA3)O_WJReJbne?p#!|@9%9E=%uxHR> zRDn?vNI8zz>*zsxdmZaIb0Bj7WeLt9Z-;sOnRUGI%6ht!8UC?;1LGkt&8;CylxUbb z)!{$}L*+>_7_21}tR>m&h-IaeeDJ|rY}wL*XT&~Z9DBCDWDk4eJ@oW+kxa(P zNt015dSYEzmWirTw%W|eq&vYno2d#_P$8UyD@Ymyc!bVQ5uqRiwZPdv9k!aV+e3rD zo{?A<29mJ#W#V_9!(*2o&W1}5=eeto=fs5->}3Q0j0~WO`PAwW!a`u0k|{bN9V3@U4z9lt4Y~?t%tER#*Aa+7x6o9{v6j zO5aTpd;DamksunFf5m-(fgyCr0GT)qLc(6taUl^+Aca#zGh3W9Mc(bs4H3wD@W(C2 z5(URATzi_~+voGGc~z9My?ov>dFt#s23DU;=5KAFZ2+42YsUyb`R`{TJ)dtzy!7=y z&Pxy92_~SL#QuIEUFXM$J#>yUxV*3MQA)suEv#r?$YZPT=jNs341Kc( z_4Q#=mUIRSAf!4OFJ1`)W)J2hfBR9K!_>F{!!Qs+FkeLY+n=}b;2m!`)Qly|V7lSF z;TnS*|Io{|uk1lzxR4JL34VCPqYg?IY=y(yVBZRE|LNPj+A&NeP6BMGzMen5x1X~v zy^n8Re-jTq_(v*SI%lO@WGYl=_!u!Ay^CpP*|MdB-`#x&ZEdp|F|&-AW|@~dW;yr$ z{Tj-r8CP(ETos3!l}@M2TbV-I5v|wO)ZmpK zI(Kx^*|~?QTFA{)^7E4q8*Qopg3vE{VRx3I>Sq8+g{os&koT9!Ntk=sb-esiH*D2lpaGb}rq@zj z`K#OUwY9N*&|=vIH}bRR_QT#9&<-fPrbj+NtB=wgX=21oGG;k8K?lRWXnlT;$gl!ytD@W-DH zQ{ceoaI_O@nK~Af3CJg*IYK3{rDF{Gg3#=vbpO%(=UH=k|MnXA=@=XrW#(yjus2>! zrS3;I`$5|W%|58{LruUr9H<$XnStrM!I}v*N5ixgR0VwWb@xySG&M!YNweJeC+OP; zp2F4D#Hj>yT_vQdCYqyA7bM2W1~oVBgw}kbaZ5Z(Yo1%y;<42_cvnflwu zFD9vphS7BuJrE!ojZ!FB6bh1LDgiheL&J!m>pF)tg*l|jkFIA}wsZ=SNIj-mps}@u zNTi;8(V|eW5I#X)D$X#_Z2@9BYkP{cw1f#aMETwg_rT&)Vd-8t(hphgN#Q zHcDnQhv==$RW0uP`(6k|xO{~l`=M)@`-}BFa?4XN(`Mwpb0~dxCdt)bf|;!_V6gt# zy-cmIr$17nkSf4)-5`8Ca77(QFNC*W=>ci-yB`fR{^}w+pIZs)c98JZ>tANZ?0KM; zKn#Lg?+$39_={L@BDNtvLu`a09pyt|o7a8?IRCer$@+J~2>@ zU^6b9nx|>iKs8OZvk8Tw_&t>bl&L6+2UV%S>@l5U~j=WR}Cbo+_!_z28z)84g@W_c!!aQkCGXsqO+Ulf4c(qJO;vG%a#t3Nry^% zAjDiAq(%Aoa!$HbPv`9OzrS`yT|JA}ufilvo;69ow2C%5q1qv!Q;FS)9ThkI{T*T2+f_+AW(SXg&l#W*lKE!0Sr$9|pl)0jX>adS} zi3DMP3zaAgWKHTLVM?Y+GMS=Q4`2y_lz9jC4mg7S(QJYJnGDj-xEw%1V`F2PPu`>j z*|M|1WpDlsMS)1?1;GI4TMYIx>8hvZ_ zGF3B~SKUZ1ZFBNjr?B?TH>s|kTE0=7uRVYe3SlkC_B}h%b)AX|ABQwWG0h|`hK^+> z2}Pq+8g4kC&&OCncOh1s*R{;USICk|CLLjmP7;4*}y_eFd`iI zPE`de0_k#zRb5971o+SXe>x(=OO7C&+DJhxX8Wan?h|qDezbw#-2NBNyzNWS&;;uX z)R+=16@qcjT)2q6or4Tzvy|??5YI6`fCXR0bMd`wSp99#Ob|`@ES=J-bMaiY3WCQu zX}L%HDc*84TM`8pUb7DxVAX#f&EaMzEz#Nh^1(jHck!(soJtnx?--)N@KF$gd{UxI z3q2sY_bX@e^{Y1XYR_A&$}~gY27Wa=LPhL2cDEPd+Na@In*cD->7{ZZaJUMClJ~dl z2is)L6R&dj9p{tiNTBOMVt@NO(Tg9040x{Jz>$|N2K7Vc?d_qGquDGnghh%&WHUJz zwHTcw9IJGV4Fam*y=0L)S9Jh_Th0h@(-m_lStbRsm}7pmnGZgg&)xTK<<}?HarDD) zL(L*CKI9{Qar>8PG~-RhAITn*)v$b zaU)H&jr8{RqSw`tPN$hQtAu5mi;`OgkA3 zQxpwfD8#@(nyH$?1mkL0=9sEgGi=*#){0=n)tm@TFl^iCwGM}&n9DGI`gHbZGGuL= zY-~T%rcDDJ;|)K~`wnZ>j7+i?)--LBU%f&)ou;m?n*ICtQ&(3R_w&qY3wdBmHCNs2Vbvq=ao$OdtOy$nsd=EEIh=$k63(JWckF$2U1fU2 zpjvV0Vrh4aH?jDc(4>@w!*1gpcM2bo=uYs;b)V(G{`>(quF67l1jM^+c>Ek@NjUcA?QGZ<=a#S5 zap8$ggk&@ML;?tsS4$L3lb}@HOrn3?6K@`%^n%& z5NT3WkLG)wW3Vp?s>RC4Ae9)D1QbM)QE55XUE zX-HaiL44B)_rK}|?HP6)bplnbE4k=%zo$Rl4{3`o4y9}74mL}{`mcP0mpfi%1dC?B z%Dw_rX(beV4Et@S`4>||7joWGj(%VO^3TJzAk+-H7TY!i;i%;Sp1k5P>bgxTREs)Q zU;v)_7Chfy1A`VLt52u9J3+PX(6noG70Yk)CMxHg_Z;oVwDZ<2f^;IoN})MRH%tUc z9@rk^iY`A(lCSdKeP5+y73tP}%>2a$cs0q(uk>=k(kj+xV{3>`Qp% z7M3Toyps=d+Bbvjkrr)?)f*P?*FV%_@J}VWc{tDsNuYA6o z?=-Qr@!Ad*ES=s@mAe#5WO7(TX>2dpV|f_&fKc#yJ&Y?bmM=IK!lI%)NP8BE zPC5~vq*b;^TaIP;K+MC}Pg=@XS4uZauns9Dt*tEp^rwqr#u3aRLeHviIN_9* zdC)RwBB*ilwNUvn?TV_ZL?RKU88g||weR0vJ6SB6MH8Vw30*j*S_D-rX`-sZ$iEK(3YB0xqKDM*Q52nsU8ykwpZLj~DS zyHrpIlN`G^z|Su|o?CzQd){8Z7ERL_w$s>d9?IN97ce+DNcW~qG&a_f&r57OSN>t7 z)9JF6u%c8`S64@4<1~7E2VIv3hxXyP=n>oK`>ZDCX*o;3?gM7P{?E~rm7`ET9BRl_Ho$J$FsAi zAFq`B`LT!SjPE0{?tO%4L25OCLa(doiAzDV)FBB8=75z3%b{`Iv*~TnY=^S-_G+lH zL0inxr@qB=H>_Y~#A2J3r_yzHvL*=}$E0M$ZPpL8F5T^&7oQR4 zhAUPuX07G7YZr6EoogI;u|cx4DGxOkd}Q+a>qDG;>_So{?q3tKbYP$qVNl4(XRbZQ!%vKPM|N1~;4zW(rf5DM*Wvw895k4PFv;retXWqHtKWec1`H}- z4Ki-|5kg=X27i9`S)u`*d^|}51Epu{EGzZOCym;{>M;HZZORB4@(X=4L=>hia*+Vd>F(p*X zu35>d`|QIyi8ESFGu6PC~CNKeX88U2_= z@#L^a#j#EM#75DldZ+-Z1AeAl|0c{@4t*Ply>dNi3o@}3-#qUG+GY=P@+E8G;nmDv z`z=2A-PNqxmgLdvXR&hjI3Y2M|NKc4Kfd=>?*C{X*U81eAoT6!v8#Vc-=<+sJv9ff zMIjSr^ILnk;G}x;awhvl596XpQPruy(Nd|ZKv;0b`JbmyD3UhKa&wH-N8Js&Gmtol ziH>ENjJu-xN`z}DBM9jRrfE_T0;WemsI2_mHatlUW-sTq)myo0>0-QU52@&}%>3Oh z=t{6}`#O~D4zhs~ne0YxxHQPor_JJ+E7pQo&f+gU#RCtW%!bHrc>fSiR|ly}07h#+|>$w`ZlYPgP@|K8eDx&u~Gz^H^!z|Xr~aZu-Q?wlxK5zr0dDX37JNhRY< zpFM@jqMt}&4yG_Uq-i#av{2P{y26shKm0X_#k8*oP@gE`Gfgn!bXhelKK*5w(F6?w znp=rRTd3&l#v=rll+@~itQ4dziLMJr+^eae2Jx#ZA=Sf(Dv)N9O_98lv@RPkS{8E4 zlONHaKLn(QAKiNqHTgK-{nJ0_P<5uX8T|Pl&vIC#9>0VU8Dzwa6Ba67HBTjixlQw! z(l#A_w9fgw!7VOVPB<<{nILb;AYYT)c=m!yGFA<{Rh3x1k8l3sX^`_lrYOWxRHzxI z(ngQyBozqoVWE|Cu6_unpTrhSywXCgpUI9LDg@^fQ*&g6;N`z>g$)I6{rN(AWSqKG zk=mloPgmA)!`db`>?m;6ky8oC8q(P;r`NQzrSWj4|9Cqu+~3YA7fXEEXx+Cf(9Oh%GX zK!7$u-PD{~I6O%M>9u9qUY_xyyL5r^F`IneW{S{gZ<|jhou+GVHzO6|z-zr_Zz;02 zjX#qqFW0=b#|iUAB5etIC;+uWU`t02Bc&7gJCRvsyB5v4T#j3By@ipiS-xL$u0!7e zy@ou<;KLaPL^&k!(@=}ahyMwS;7>C+5U%84bV6k6{`(k|wbb5^=}gP7{XckA={m_| z+|6}rqN{5MO--!~+vCJyv48vj*6KQMu3JaPhBZvT_{Si3Ii3fqN_KGYz@Xy5P&Qfe z*g~=~Hp~Nm>42IL>oO(;ZE&>~Ac#*4(6*$21VzwcYtD8&lVFS10BSSu-uiofcK+e~ z^rq{1{`u!vzwsRmL#MsHy$rX0(9wbZ#dA3G%(IBa5(EN%giy(5vrf|uhuPHe9xW~H zJo)64+;GDUG&Z)ND2_XhrYWuf$_Z(U4US>kb~)TlQ50(Grc#AMI-RGnvC(bFHnp`u z_Uze%BC64AgCw?YVQ6TG>S_hsb~uyyLV+bS7BLvx&q&%ls4=9|8A738InYhhRPuR~ z-~ax%#N$0QH8qh;Cd>Tk5z`67n%LwyY4px?JF}^YKmPaK%$?cH*RHsn4ILfabLX9$ za@jMv-FFnP(-#UUO z5n#xSbK9kd@_NrcIx@OL!^(8w>4|awNk?$y`vuN=sG5uav7N{NBLV@Nf!HQWZ(N9H z&UK)E)e+`rf>=_L(*;%{!Om+=;h(3~aKbnK$cw)V;`!54aO~;u{ubAWKqFu&9C>6F z+!2T7(^zuxMyT;Yg9UP*gUFZy`m!*s3G&bI<(4a%`L)k*-WT5C{XZB?eQ6D)`{(e& zeP6(nDiXJn{Cd+UxBdQkMNW0Mkf!VQbIDmyONw2;JA*?m ze;R6!1GR}*<{wn*KBiz%VH9~U{w8z8{7Jl2r{IoRP$@w5`(d{Qs>+v+pGQ@yhq#2I z9w96SDW$ehc;Gt>6%AssZXUbr7__gPK`xnPry65VeUvZWwh!bSXvi>#g<(Xw{jzy{ z<-3RTjbE+jsTVyc?lmiXK6dZ!BCo2%c5kObQ?aZh@4fjV75V+-g8z%QH;-?tJk$Qa zmh~K4=g2xzBrmdKJF$~Eo1w%IAZ&pGg|f7iQd%elTAjG6MG`Gzq7z~own!_}+Oeh+rS-|UeoI4XPhP+Akxm`V4!7SJ?59@{2k zn%H(0WyWScg*-m&VL5EDpXyjvy06FBlo(td-oPeh5s7g6Tpy-EDm--eg+wh$HeVv7 zs*J_*92GTq@xBUT`e_)%x$2suSsu@Geq<6dWmsW@w>mdDh|~qmjOp<7Kq=LV$k&#TCoTbxT7oZSxki`|Mpwd-6lvJG>;bkzLVZ2zv zvdV}=RQ#^IrBbK_R7aZY0WA0MFohAUOl@5G4yFU(c4sF#DvWb2s;uX|2Eg@l9 zcyvKuq7SXEnv~HAkyeB_K#+R6!!Ymi&7gLGFxYg>sd#-UdW~un7SV#FA(UbeAEbgH z`&rv{6lYp#ywM0@8D%`(&v;!UYNj+Ta{)hS!j;aH825S)7u`7lS`^JPm~9-O+U(+z z?=0i?i#-Ujn41kJypHc*$C71jjCFTXuIrTHV?k33J}D6*hZ&!wQdha}ug`Kzss;MH zFrK>zDI?_bB__fqH@!B%i>u;1|8zG4U%Q-Y*~Ko}xcc%}K(BWWd)g4eKr7i&GpTeB zl`Sp&^Ame`WK9C9m${v51HU|qzC<@!tKE_7Y|rs+RG+*#vi1(`6jn5IQ-Pt1T;W-_pW0*WBQs|38A}uW%8+pPc&c$e$)=G&n0b z++32Mkjg2iLp0^bOza*h4|`{(y&oSZZ5@`%%1`t!eY9Y5rYJh;bOysPTqsGJ|H&Jy z+~;H0<}JMb+G||@{kxsw*>;May5{D?g-QS&kDN^f)daj@c3UH0nlQ&EaCCt4gh>%E zUg?`Q!i)R?KAidZC03ZNKL_t)u3>yaH+ zNtG5gjbZ17S71eJgh?ZgPihRuYp6b^5@ll&4)(#)90B0*YmVj4E9X$v(nya4E$?IC z?c32We-;qz=*h4`Kbg2pOs_0cZ%RKf=B5W50fWcyUcps&tp)_oyttJ+Z@ZM;u>|#M ziJf=PE*Ziv)OBEi#l9K}iZJkR@sHN^JxBc#N;^*!da`$zfuFTR7%FCKL4fxrr?V3XHe2Hr=SUk>5f?hWr&hm#A|G% zu_eqiAEgby$u23Czms+5DFuvNx2PPRdWa}y3T8BKVaUxW}bffNgjXvQL-}6 zxFsp6;Q4O}9}0>x$pmh9e+GZP62EIybUY%`HeETB&EUYGJ7JZy&Yn#L(An8Z$C7sT zY~4+zP}sbCKSE5>)wR!^Qp|Qn;MpvRci$zfg=jyjgYJPYl3IvEb^)_sqHBJ}O_M{e z;e6Y+trW8+qfB{YB)(7x+lKT&5@R@r=GVxWCYdc;&@_#4QzBebyR(>Uj7ev6v~8OS z7xaN5m|astHk)Mvs8TeFWa;YKMK+rxo6Qmp)v|Wu1_}j}+S*!{bu1;B%&}$5t|Ky3 z@^%4X3QXH{iw;L0T`mN|CE_SEg0{eRXlha%k-;)$O7++yL>4Z+&%=qyJu-S@VlsyfkV9s4bVhDek#EUF?tS8J_uD4phw7vCltjiBp+Y5781TO0X& zo=7A@e}6wMO%@~1e3Nw>$9ZyZjOWA<#m&zm_H}c<{$;8Ib79{ms8M<1|1P1SWstE% z3B9p}vKY*1t3^#fbtb{PmxXxl^x0f=`C15dfIUPyu!25yHa;08Ye_6wA|xlN(IZq! zi}c?NOH-#GdkH9WfgLLr&*S}f(mcO5#ovGR1gd;#N{J!?VUfbb-*Pg4eQ%T%E0^NQ z^wU5!d%S%tS-BY+PJ!MyxxbuGk`krZ8md~p!m#C~N)>GV>s91+xbya>_+wv?%YXI? zlaHRlj-D=by@gs;@O~mjTisH8Q_nzJZu0q5;o?OTf@s=s{Cz>4N+G!Ul9Tw(veQu( zdJ$rhXJdJIxd(!RU*CTNnkCWoC?yp_z+gJf0#&C%D0m_|DI-m7V+*{|1C~J`6Jfj` z!Yy91mcftCTEdHuyaHN;{rNnz8^c_E)xAIm7#7S^VUIyEpQj)+LUlGhu{@7F{3?ig z2l!$GsWb?cnt)D?z7NC>5FOn1?Pnc=(}F0s-}O2_eEDiN;#Mj_iZwn3{{bZ%*LWG5#!)B zr!x1|e*tkKci+6lkzo^ISE`9y@9lKRUoyoN=bgfpD{JX}ZyR$OYyT%~;r~aEikvPG zgsX0G5Y^*u8@-yUnn@~yDt&zi7&lEf=FfKb3}t$a0-I6ywvCNv{K)$#*f#c5!K)~E z{eB|014U63L8)L)->wo0honiVVAJUL;|pn&OnW-}WXf|m;YyMVg#yKKa|))5QVtV1 z>GM;jdb40o)4o2MS0yyaWhGaA@sjB#&y@UoDgvZJe1x?j40cgKjjxBuH{ zf=q(j@A!LezvFv6uyF+Tbirch0gVhDUj4jNk8#u}qqYPK^jQ!Lg6!mto4-P9J_FNa z{*S*odnGJUZAj-K5@9G%N5hIgfTm(tMbZNU)aW`J*REy3QHvb>a6Hbo4I3D@EIa~Q zT3TqG*Gh8pW=3-+dN7Eps-#i|wM|V7_s7ZQa@=sk4LtC`zcF|2Tz2leXty{OTe_(*Y!IYDL>L@^%GiMH|l!0j;Lvkn{_ys;`$qIV9j%XMM_vaZxOa#pu7x1njmLMnwnZk870ss;fm8~3>@H4CXH7r zG&V)B*6(Dq6BM$VSGck0$kGkZC3#`x5{0b{7ZD0<(25V_OeW9ZAt2UPz-1QlEc| zhwfO&g10C5`6K(FSujgLF=5fzG=`EXQkRdj`NtQK6|l2d&o5t`g-46fRyV{MYKpVl z+Q_R0W+FyGM$z(peDP~0U1v8@3?C1PBC6F-pMC}<0qeeV8kK2{qnDqIWpz_B;_Q_X z-n-*O_`ZhaYo$|I7)|XQANDe2n~tp5Hybf@4L3 zOuB?cKelDi*wVs>#wHK~TNY4-(_z~1;U>Pg@8cH@GF2_K+~LsyEdqi z$R#NcY6v&?C!b1D%;mWF;tMbggG1>wRgor&(r^er?g3;}%BhH1z@`GtNt<=$L=wpa zlX#{GB??Tq*&Y*$gF2q_pG`@TLcx$r2!oMafkGjR-|u)W6u0om<+5&ayHg-J0guk@ zWOA4Z;n2KlfQ0+Eg-{q6NK&O}jN2wc(J+RG@%lBANs}r!G*Q!>NygNq5yde~YG{~d zk_l{V+jK%nT^PVrAXzdwjBS@qPk4Q<*QS^=nLWFO^gz-v-1{LFi!nSrJiXD)3WdmJ zlhd_=6Xb=Pog$~nhcg2qr@l8$(~(lx3SPgnHkG@%BPH{&;lIkgE*^IRQ~{t&x?Mtf zWSXSg*(+C_4y0cQ5E=w^RF|t?AFg9GpF!wV3|eV22?ez=zy$rwmO<)#P1q%aANRmR zfBy!U&0P7#NzOgSf?_>(Pmu$nA7%MT=-0jg+vt?sb^WS@-#eB;uT)LeDxKa zb=GM-_tbX42?ag#%+t8zj!iuC;)|?(?H!gaTh88eCnrY&T-Xxg!ZSNasf!ph6v{GQ z0(t_kRpiy*Ttj$y8_UEb12TgEKLuDn0?FiC?#Q0YZ%nEwIN~-_#+Yt zQxgueXZ7oFU=)HXd%}H4LR2OU4yr}YeQ+&k$3yRXoE{L2S^*xsbS0J-&RBUI$K7%O ztY&<5EyzRL+bz1G{w1L7zR?61cY$JM$!i1KvAlM z%3E8vk+%!e#mQ8$PzmH`cu}UOZ{^dN5*Jl$yAuv&8f!f2I@mq7O}a2bK=ETMkSo}D z{R&~fb8Z|S9wrp3ohDaJFf}a^*tYGY$@@VNCdg@L zpG`cT#xv#5WNL!q$WSY$LKBcZDqIFGlbT}KVgA`Sm-Ri|7CH__w)0EtD z%T1hn?uDcW2We|-o1UgjZPK%}5Spei7Sbr0l3dmaY|EG?il%YMv{|rVF7vec?Ay27 z^@@OJ|{bXlCbJPgj7C_&!TFh%~C7n()hGfz4$D;%yoOt@_{OOt12qE~*Z=T>! zk3Yhy=bq)#yYC~J5oE12FJE~k=YHu{ZeozHeYgrm!lC?5s%huB=hwsEpU>W3{fIkO z<#_O%tKpXw{3^AL?|kDl$Ygjmrh?fFgX=lIMTJnafdMJ&kW$X%23Djk!&ylMT$}?)OGfNPVBZdx0+s>W;GSxgGd5(o@oRq0sM9ImxQ~op zWHj8tDkIM;Z*S!XjmLA+NoVs^58QUuvrZAG>RcbI$TpmGQkl?`Ef} z@`tnMa(-KwGwy$$w|2~fTsKrpesPm3EeL%f!f;)Hlq= z$eGk>f>9jL*kC%vXO2FO!E~Bu|MV1(KmJ=Xx})z$e8M!v{Va?tQwNkX*No_N@5`sq zjuK4Qcs`~$q?bdQAD`wBU&erefdRsrL#7$($x>5Wi^rBkTvI%Dmf5psFMcVWF*V1Ss`X=8or>0N7gciO*U&%%x1BHSs_1|5UkOhP(IV1ej8*8CLy6r z`(GMEwS*S5ArwLPz(IO?2GC5wgd)&@+S*!z!61W!1CB1+EKnsBOnXY_eK^IwrY4A@ z1l^5OV44=itVuqbbID-h6LMCL^r}p0y*>8F8&sBMF%DQh0SyZwS4Khlm{0{~x7h#7C)=M^)kC^UoolN^$XJU%;|b%x|tI zKGermSAE4HKIvYhv`A+%%xi36?%W1Ia_Xtaa{B3~)6^8DyStlcG|E#?JjO47`7oO{ zeTeD}V^B?{Dk;Re7-5Kz+Dy6L#IPk95f-Pnw@{u*lZltew$8;TG8`SY=`HEBT9VOl zjy^TTkX27(AdHCh@cZvCrYhV@rfVaWQg_RG3yF@`Qkl?oibAL2Z?rTE(sHSM7E%Z- z3v4US$?YvL#|A~^%GG;#^{dB|$dvGhz5L|u-E4X%19Ok!yC)nXYrz>;u7h9`gd7mAojz;;vsl3QJCARr@HnEDzI-;H$f$ka`p99YKj-sH8I)=0>6frDF|| z(rq5Na`CC~XUnoE30T&&0L%}e0Rn)L&oFMqso*5Y8ej_uNk|%O+&IpKO%e7OX(}5V zsk1B&Wb)KYnAh0CPzF-6NM#@b$=#qvSh8}L^Sq=53^_8Y-7oUWBbP&|p8+e#=a<&e zqE9-X&7qwRqS|s0%jLR{LMG20mt9CHlVG7tKq`(%sg$erBx7Z$NWQjw7M~Rc|Mt~0 z2*?O~c8!yf7JKy+=d>*${na8@EU#rzU4VQd!JMdy$2y8JHZW3mJgawwF*gn{yS1LZ zO%gMr@wMeA(kM>EBl8rbEJFp7 z%D@@Cnt)h(m<1=*LLx&2g6^Jv79Z32za;sZ>76J;n?cwsmxq6_O8D5bcL(W#fg{3Z zr+mpa3dN%777DIlY2qV`R?&IMCd$Qh0a2PNRNT16S+nY}?ZOe0j;t#!vx+9ALW~Jl zGB!G0s3??*CgbBaqI||(jtfT1onmEFIjkz1E@Ecnyr2M5p>g&CYMUBeLar0yT99%& zTz%$5V=6p(;vS;qhDi4D&*lzlTR*E{&tp*VHnJbMk%=V zh6;DeJ1#By`(s2RflvK?zYzFTFJ&k+)JI{x1sKzoiNl48P$}0mf=xaqNs~u$bd;)! znJ7|_D#Cryrw9*1Wjge+N~jz#EZW+Z;?ozhCD!fu0&+MK9Crgur}Hf7=%6qG4-MUS@^u}6>xg0e$4MbcHe#$k{m}ZWenrb|@!bu$`l1vWb;mEG*)bp7TFk+f6 zRmdUjlw&iuW)9<~#1=U=Y}h~|(La3wT3cJ)Y?d6R>2w|))rJ!Udb*jJhm*T@RvZD(ly;XVeV^8bjmm z+izjl)}4Io>Te(=)ans>dxw}^(}G_}HpWM&7m`yOC;8lpMZ97xqUQb&IMxcXEINxv zo?Hbr9nim@l_$1Rrsw#~@^ZEXEx!BY2oF`40~PFkYCYu2xcv*uC?i6nUWOkz?Mv~v z0X{SN>5US;`c{F}Ph}kUS`dD*r;A@axdG$P*U{M11zwfA*Yv>tAiZDou)J+4r#vP`&u$i5-2z4u*swuwXceU7#}LI8>hi(ht=+hmzA91S7zk2jaZBrke-9`FXx~?kox{ zpz5j}U@DLs=3VU_cu|MGP6v%F>!CNz!$UpPgzNablUn(AsdMMek3#*)u)oOV>$f{z zm_2!@H$aO(O5=y$dy>iCII3hV z={$!}ncuRMq5u)E29dy{3dV~?%2gkV(6B6vp}|2G)Hk#0xfhsJLgY{=6AJm1;}fZ` z50dQd;;pyVBV`#j@aiA`!aWcCD?L3iCWJ~!sCc9`owYJ^fvcF#dzk8qIV1C_jlknr zH8^Bu8Pog-F-f^5s4|_G+9M{>LmG4EE~Trhi(*!y*VeLp`Ek7P{0naIqhOZir!MID z%{;bb?%W2VbLX;Q!v<%nqJ`XPj*TLm2}h;-xSYv?GA)zxNQvLC5!9T?Y_y@CDkVpx zp@w8KiD{aYT$!0imLYAMnwlECns6y+jwJQq!2vu4=d+Y4WbxxB$h)1kuohw>SjP7#YbDY-vGrAOF-erKToG zC=?f@k&kO?`7f|&kUM^`=7ol|CPVm2O}3D~4!A1+cXhmAjOS&Snn z=@tYnu;8{|Z|0SIJ1C?#Vi-`VO3DK5eD1V+!90+!zIr;pG9RekKTSX%Noa+$ZIG@2~|i?K@njrt4O)(91_w} zlCTW!yyFfhRM<^*@9F8nvRwZP8X>g|At0AC$>mIrJ*u6MDmd8L$?}ty)6~?&Z-4tZ zmtFQ{q?9bfBAFLV)cNo*NsDL!1S1lve03C5!G}Pj5ul<4#u6|VF;VkzjJgO5eRU-A zMOx|tWPNEWR0FRF~<+t@$?S+YY}Ofw?xTzOsP9o*4DI$`BTP791UkFd!{T zr4p4v9T)*4H%$pLC6poA(0|Cuq{*cS#4@C%q;cs|b|yAZT>Bjcb-4Zh4_NgV$;DUw zJCoaQqDth*QEnHak* zjXE{Qs8PnGp>W8^JNrja$5Sd16-^`*(TmRq-+OL5zkd1yXi%Aa;CzU^ z4PhVOy7^5|1^@U5m323rL3^Fb9MxhhlcrhWqP6hIo)kQ z(?S%aM0bmo8oincAxNhUJQC{bn;AvY+|-PeCWc|))ilag2j8|hIFG)*KBu#&sdVq_ zVU`vm9Ml-<>7mEA(G)+8jkRc+Mn0M25H=xALs1+fYBHH}C1ECs#NZJZs=K?JV~;)7 z9XUFB^JLb^UC^`;hq8{&YjALo&d!}oPL_ZP6eWbBz+f>+O+yWDzx@uytVzSk4buqB za#iKDjt;hW?qx+s2ct+-pUUt5@Dz&|&7&bw&w}<-`21(j;E4zCM+lV_D_8R3i!ZTj zXBW5q{dbu((nKQlRAP|a`Zo9f_&Sz6xC7R9vq_G!DcJ)JDkRslX5n$1xbmAQMu}_5 zak{pScannLKi>vRCc*5ceMOePyX~`V-qnS!JJ~5ydd0&U#lz;U5eciiOJEw@avYQ| z^l{I_-Oz9f`X$eD;LjHkNOU@8cG-x*C~v&C8{YU3M3g(fJD256i#Y#hPr*o%eXsS4TTBebQ#8`Iu}wN!5Y8+yxBbR>hCx-phhD141&p-bgXPvQ<14Ajg4qDjz{y@2{@VU>OO(+qzzBHx?oKx*wRMYHivARN?Tz<+SBhZC!eG+P2n>!F>^VjZ4;U8B*xd& z%x3@aPHJk}NTpJQLLuVWEPlVngqS2yqY}(%lxxmLlT0QV9v-HprDYm1EM26pHJnAS ztwm9wByBvlMAQ6CXadu8DOghu3O-krvg~&8jM-kIT{KH*6 z`v^n*;ooxtJcJMkRi#o0f`KsqanWqP{fqZmzpa|5Hx6_0@)iP8Wx%p%ynin=EP{gu zC!brx;~RH#_rL9ixdN_Oz%Ncaj+7B+PGguF0+iH7>aTqS#8FT!8T|R>)CbaxS`mr@ zf@+=#V+*pek$e#}EEHc9;nm4yO=d--9Eio}?CeI@Ra#pYGHyXGXQ8UW>CM{d7ii3` zp2MC4ds%YKLgp@PWY?~(w6(QSsRw!YjSsl_X2EkkAujsuelRTvra?v_Wr6PCj_EU; zCQLmX*D=P2mwt=A!&|5i9M7${yudmc1;cO-%0f5=0n!QY?OO-B1gR5N;rUxmBpitn zLC1_|h(sI@=%;LZRxd)zWmgk&tA;G&gF_)s+Q(tm7(=2OV_1tHhz1nBNb zbLr{jT)olHs~>EE;6m856;vJOM;yP#U>xjzzVzgFSa>w7TL;y`$?cFO2np`GVg;9+ zG)g{JWIUZlZ}gHC_2l{!l%iq0UYlS*2knqkogne4s!J(?)zL|3s+`;d;V|oZ6uy1e zdpvl@IplYB(JazDdh;=?TAKhlk6{;uen?8n)d-el;E{q+!@@6`u&g50VIAxNSkTJk zqaBdX@LXpZ7yWB5Fpoby@dm&A*0BsEGK?C6k}4RG2IXoU&;&UJpOhF@Hl*mpD zxtDzD1jf|kfeCi@braC58O`@WSnz6385ezT4^&^w=!^S#;>I~7^CsupS%|!^R%ojQA5{yNc5y$4{Q|q|@g9KPQr`-HFu|Hmfq8f~b z!=&_x$^ST1E)cvLwZ_=jzSnWI*3Wn4gGVq1NvoJo#t!a>MeP{?n&@ zS(Zh$s#C4%l-q~g+ROQy_4N%iCo15Pz4&AqHIa7q#WU`8P$^eo$wMDPFRb~|0_H@$ zgw-Yj-&zCpI?10cA}=kXLgnB8v=tPcFJG32Pz195WKc1Nb2LQikH*F3nHl|WQ6SWKu4B`s~ z0h>@LNGzsdng)}Tlh}5a@o^93!@oT60NG52tFHVSH{EapokK(DY7^mn#xY|x zEu)mkv+K&EcsepfPrR2!>Ll}AohTn$D>wr`3u`YL>PPcL=>53JTQdu_~q!wJpdmV?0N1hc)xrR z-fMTjfoisAbSLbv-eB^+b3jBW`^h>$u;yA1?QP}Mvzx?y=TmptPTq@~e6ypeldr7GJO48C-U7L>mXOnGd(3|DyW$xANm~CGEUjUVOXExu5Y%{vDBiX zC&2b-(yPD1whfD@ zK%pw46RD08y(&s15+)YQqpD7^mH|q-04qX4`WROwC=#!~kt9&zCeW7)1x4D}g#x2C zcochl0Nl91>x%ga@oarp}+t&9|-%>-#%u?N0OE#ONp`n@y1wtY1u>5o|MKYNs zQ!r_7uK^^rwYB7O5|1sJP$rqBg-8x3QD=qlNGM6Cc$rYd5vX4UhnRK9EP%AB60H1f4xg0`hY~8wr#_C!YESQ6)L40JG=&VM@P01`RG@V-#3OP98 zQQJni@_s9=MpIYEV*qp2P@ z48~QJbi(4RpP$W5t9*>6biVm$1>bzD8zLrb&V$hb2TT0*fyGP+_|e__;H2|F?1ar3 z%HCKHQU$q#_WDU~zUCa#LuF78OFp9<5~Xwhu@?uBk`5IE{QHp0+Y`#TF5cqyB<58W@u=T zZac){#YYo=?XS#ja5l-D9)>-yJ4WbK1ae!PLL((WjXEK`$uyV|TAJo@#*c0%>Q(6% zV3LAu{SaCN%@T|>4Aw)n0=a$|v>>N~D#-M9BEn}dmWOf6piK9X{~u_^s|+ZQG?7M< zPInWHMzDxtS&}LYz8?tl(ysN+;-gt0CSgxEBrTr0L4vl=mHhWZNC#;;Yw^?p#*Fap zV=*whU_lcM0U{0iHuLNww{lXW!QNO2Aym-8lYu&6kkNf$S?F?zd96o**a()!p1jV{ zdWLGRkBnN!FYa0onhD1>u|o3~G(Nd~x|QuD`g7ho2nb{wK%z+81@2NFb~r zBjGU`4H#2PphzH2QV2#xH6?W?C2JlPqMAeAA#7QMoFLrnBY;5+jXW(}bXzyfUka&* zxbx(*(4}B9y^w>^5>Nco629>tFT(uOIsgAYN$G*FQ!YL9Sew~NGhaEghU-?IN(ABD zJ%aIoOn$UzV=@+V!e{R37tjZ2=%co5Iu=CKU)K*>wN2i0e&fMd zbjg0&tfky{y~cMhF=+kS2cYWQ|8kOlTwX~vfOY_6145W6R56B1QCMgaD$p5|=}(dW z$WQtH@OvWSQ9WgIRRxJ%5jPotz2M_JB`M1AfJfgRs2*c3T7d}Ll69t zQvD)sd_D%-O8j(3hKsILsjzmU3BhP2N=7OxO3Ha0Q&}rh@PL`tf=I+czk@>$El7ia zH^8`}I(RP2LZDKvPR{hG92r&ru~JQK1*M3oM$zg594h%BDZn%+l!BCG2G#3x z;f!o0yApY@npoa6n_QxsfINz7VetA>H?sJ~{m>^lRt^OMn0bOM6;q$EW--pPFw;6 zyBnc8!hf|la6Br(M2RsKA}vt}zQy(}yO>yhBTu&gIxDT3P**ukyl{7>}&q341<(py29Lj_1~Yx`~z+Nj4GVg83=d zh#g2RN24ZL(JXjMrf3&lju!2BG9~;%cQwH!jyb-LWvLP?s)2l-k|mWis4E z!b(#uOvbAf@(5}II^X#}w=l1@2~P>ykLp16spz^+BodzPmQ0}z$8Zjblj$@SY6P!k zaC&o?SG9Hq?)xe8kLn?!Ld;J>W8G(-_>2{(N&@|2Qci57!<|oirgQf{`*o-7i zf(^+TJC|`&x*15gQJT@jL(Jpo;g` z!+-&8t#I&J?tSP&+S?1nyS7610AzzsR*HlF0VM%;oSiAb>(33sfCM`avJ6rNXsY{I&R|i*Yet5o?zB2!C4D}6otiAY~j2IPo?JO=U~nyu;@Hq zzC>Yux{EP1YUC0&CHe_AMwk_y#4lDbQ9M9hshQ0`yPC3l*1`5_7?P~M{}hguT}UYy zl78kyPa#hpJFVc6OK8r=FlCN-y2PyLLJHFOn+Df0BpyRjsjIZMG?LEb5yJ6{l&dPs zR>GIBZACPN(X0ptMVA z%a(R2T_`O}OWCq%>9wUTl$IW}(2H$L%TZdO_sLamC|3wqnu8=xVmq;7OO{8LM%Ik% z`AG8bj~R=E(q+Hj-S6-Foqz0kB(|j)&FAxezhBq=+;dMKtJN-AwS~O!`^UgBS$|Z5 zb5%%h$C9mt6*`Qtpmqm?#S?^^OkVaqjy5bVvfG_ zJG}D8kD<#9*`kjQRd=Z;mf;D^7g7^prj0b6F_=mlgu}XP|Ex)BT964_WsxxX@$)YL z6Hpk({Nt6#T#*;c<1E$71Z=oqT?=nJ{dii=zY7XQell3)%vdW^BEYfcD0WdLEhTxO z;+KMeEm3X3oT%_{Ym8O4!8!lX5BKhX{RV&9GDi0a9ke97xpQ;^RxAcN&KEDdltQY= zFeXi1B}RuIA`o7~5s5j@f6F?4{`(Z)el*3m&N$75>Lxq>kL9P#qbgO~rGC3cLblg1 zyP=YPDY0xDO;xc91)hBJafHzDS0$mKM&2^PUxOO>eF{-c;5ar-4L(9aL8RP}=W&%ZV$Xh0{_D(A020r@HPxFJjH^KfbAQpl(i4XyrV=-4pc8Ks@ zO8c-R_W#{O2>zcv8ofc}tNAc0qoYIUddwYe{LT8N)Jfxq9)UL$&e#Sxk}hME1+f~l zbbuxRo1VZV!>Wo^0c;7Dq%jqP% z`#P(RK9ZL=Jx3&>)6vnv-o5*%+CI*E=lghh=T?$EJ$2`y(LH-<&@`qki)KZmqo;?F zkulCZbvdW4O0xCQ-}20(+t~QQ_j3Q%{p>uLrHK%VqLIpGIbzLfdOJF}<(BUObL`J# zIIgdcD=&X9TOYfVlUDbUSa<^4#w*Xm?PoflMNy!$Z4oDIIL#9uNvf7Z&MFX% zwvo+_Q7G6bio%*B-o)a?i#=+OBqX4xVhheq*BAQcZV^IGUFKqLnb-rL$`yB!1^;_|33HL77SN>81<-a);4e)zWLr7 z|NQQEFpC@HSha08bzW65O~Xq_b;VsFA<#XZp^6)bwy{;=2Ybf&(nHg{V_l3jOtO;* z(>WFAQ>UO@`DdQpDF6d(lcg+j?GYy-cI{(q`^;kcdJ|lB>yscNV2zUN>g7M47=eAy zf~FJeZFPCM+tT>1-A7yUEO<5t5y5#MeUS$r?n02@w5tz5WPtbTd)c_AlRJMr$bCPs z_>ox7$5yv;SE|glpZhgfaZVmMmKQP^-u2B%h_v#NM1cNd`?>X3JBa+tui?CRzypr~ z5!e>t4^K?i0(7~oKBcJroyV(en^?`j1J5dEBI{_iA$L*7Y&xKY~@!2D`;*FFjLIA;agHr zl2AmDE<;<{M@@h;nMTGX#~#~@UqX63O)Rb>EAn-@$n#-Uekq8=VvHCjAytqwhv0@E za7dxwXqhC+46pLvVO+My0F!sQeQr+fiaNE)(ZiN4Tj=auK*e&1Mq8Mnbhrl8aXHPBdHU5{ z-6SonD2LbtE1ngy+vrs+o1#Z?h(@FI^z_it(ZP$)yg)jiC#)z;BN3K@-*W_WQ5uU# zBuX~xx|=oeHyMuJ=TkW>rGDnM!&1+)zY&2@bsCUVfJUQ2gF4E-ADqqJR1s^p!c5VJ z(rU4M{b^J)f@Hv?Ggjf=@4S~0LSWlPI%8o}A?u0GQc8q0>0NgMkL^zL_II3vU^~g^9HXW~H7IB(!xwIUq&^hz z2|-2r`1S37;?BVofB3}`W~vH4C5q~lC^E-}5B?ip`Q|qn&y8Zp#q=h^+;R2Wx!|i0 z!7C;kF297b6l{|LmWiFbWyJuKnIeV_v-(2D%rsHeBy8K1uQ-WSS3SkveLik}Xe(!5 z+KH1hsF)FU8H2=P4l^P`S1ietv}i;l7ISTu{n&3f(bV-AQreiNiD^PC<_dI6(k5iX z{m=Y{FTVdo#&>6!7=4kqpL!zCsx=CMJiZeb&@ErhW2lMw?`K`xXIUems*H~ABpJ*z zVwX8#^?KU6jwE24jPAIfQ2(iiISsw`=NJL}DbNgB7hBx*k#opy8KE_{jB&%lMv_c+ zV;dD_bwSQBS*#111+e)kIBO*ox06>Ry_K~W+ygA(JJ-I%k1vliRrYbv zkVIA_px`!#F;r5<2uH-aDVU=i(H*9kE3>lP2nQdfb73EvScQhd{ZIcH(75JZClVgs zLCRc+t;g|U@REoTHPb{%@u9O<^W)zS^QXt3;rvUF#J^(*sV1?!`&AO43ka$LA#`R@ zX~_8q*gh(mA}ix6+arPl(#8%-WO*MCnSPK3mMrcjkSP&hG)HdS}6SQ{h+RSnH?QRz+3J%y$PDVNK{ z^f(jwNurug(J4^%2E#_FL{o#0+3FnOvPDx3W@~daD^s)xh0J6MNtLFS5NfD}{MZCd z4T3-@R5x9!luEDWt^iIIG~uEouQwF%Q^Tp&=nN@LlpGgvUK?{$U$I%q!TVo4Adw$MR| zc*TcGP-cjQaSKgNxXunzf>4#$`_6YVV-_iw zZO%ID9EOH=BPA?YyqG54o$zmZZW9Nxd5R8on9y+~kw_a=JI~sV1)O!=$9V3icQGNS z=#B_pJ_w1ZMnH?u6p1jpXFu_HoUh*SL&nnwNbTK6Wn_?9V=wPGZ85!Py`8&nd5Dz@ z`w1(Gt0@7dEsIok%yY|8JS$>Qq-)>W*4D}5#S2-xb}fBr{L>wSuuCDk=>-sz5C`O1&OHD7pv6HR3tJxJ z=Rf!W2pf(R@Rw1py~f~LrvtP}Xj5U&pLyE}-(bV>cftBML*ZV|?~ic)iY46otA|~C z$~*SB?sSWE*s1WT@4UdLGzpFhg)*NxuZt#C^4DA6!kf*IRU^)NZ7dvvG zmbB?Usfj~&m;OSp1%cVj@ zqfxTnHFBNDG7J ziK;QCbApi2Ik~TunLrtZ02L9VRj7=sD$S^<0l`#Rl1%nfl4XL@CLjb+F-n6Pqvq`c z8EF#|0#y}+L>LiJ8LkAl>Xru>+dhe}TESnc5)CRCN{DKy#0@v?=bdj}M6Zb8(!ztZ$}{1W)G|4aZ0#aiE;B2ky{n&eCWEgvNLvwZgodBK001BWNkl6h6X64dFynX$tTyxcDDUR-DX5TIl;8%5K$R1W)x@e)ooS4IBOa5f~ z_|W?=LYF>5!sLfPyn*5IalUrL*E#EBm-GBzh7d*du!{9iF9(_X&Bu6P zu*x&T89L+w+9=R*`q8YdWEk7>1m)yPUdpBTF?tCRGK4t69mem9t}pJLDdnqO(Ym#WmgauNZzxsKrwMFdvYMv7`?3t7K>J{IBzxI zdSC}HO*){iB2-D!7ISDYA>Ik?dVyNNqN}@$ArpKt6%(6?+D&^G&?7i@!%C(k%n89G z-r8hz^+MMyO|8u|2uZ$Z(jo*t5o0bGpfM7I!B=oj4pI{aoyjEIY@L`MrjsJg6wti; zSq8GE!taUWXFO8cyrD}#Q3!eW&T$+{<CQcD2z)X@b3fycIg%#EK5xbH}O>RRs;Iz;C<3 zi(&D`jmjG}E;aGL;wmiue@9~Wj;84D?yCPS+lF_YdoEx3$~Q*Q(MkyORh_CnUTNzot`?V0y*4X%?vo zfe-<2VRS9`sZL)`*u8&0d-v?65!g90$QniP;NADI z;DS}m4efGWfk~8+uEpDZWkVjwlVG4p0#O&2F<0S6be~3Y&e-&9GdhXI&LE} z&m}CGCc3Jk>N-uj>uM&1ph?$hkkp%$235s0ZL+2-O4^$mrI9!_QDLDP#5B{qFDdx& zJs(GD4Krce7`Y5XLya6cFhCdx1_NHR15%z;_eqbh=x1Ll#f)jv9CO8zvq)^yy$9Xh z-55q1(=_WpKV#ZFksD>_4d-#u4Lf&G$M)ymKA&-2|sEQGy2;6WbSbR|_`(ops>{P~mkntd-f|8*Z6(aq6o zPvCet%H?-`gD|i{Q@KL@38#MZ(_kAEa%HmjUB>sWy^U$Pgx+N>{M)>n;u1iHKO$W#hM-`{XR4_#~;)EKk2N#3^cOUO$}O?9nF^HSh93__xh1|i7V zLm*V73@}5CvNQ>cK4yWuG*MzM$G9q8q{A^P)P!^$z=TfCZ(Et#>4nAq%27kTIh zcY-5Wnpi<$VjIn&5QY*Wtc1Ab7k^@W*BXBH-IJJ-HpyO<_gwO0c)HB;7C-wH1?edG zsuq^%Ugzs?`#GzVmvVgf9PQYM;WW=*zJbd5$72`<7^0!<;Q#@rw{C8l#AZIXC{ z92MJki#{V~VB0RGcV4s$lIB{3554~~YRZmHH`c+~|8jA?0Qr0FK$e>1CEKJ` z2*RlhOI292x(O*8=xFUBT^XfnmzgGssj8T^ft4BOc(sF-Z%(3#X_P=SxlD$QY;ca_KAHA#8v^2P!m)#gPh!#WbEO~0F&9_3`cwGo=t^WdypG0T*6l`J(8C( zc_k%~vP@5_O>uAw*_$t7R+VH^yE$OTIa&yY%``#?VnXGl7|i_fN-~)g3vwCeTEkp- zOoGqczlR$iZ{_NB%kXEOr$<<{$v6@FDYWjjjHn52yyspxW(~=O4UEeWRT&``GmuhX z+bU8G7yoGs4Auh>zsETTv4}YbsA7rEZbzJV56!6MF=!a!#FsG-;tCp z%e5svn5FNXM=>R5ap=S!U%<|tlYm0io5Yq%Qw;QM;Q7HlD3(Pu5+!HlX>V&oNJ+_= z<&mcj@TbRKqJP!dR8&D~B1Lr$p7*SbTUrt%dwN`ssyAsY7Tkto|HMJ^w#6qe`2>6R z?Q=H@({*>4-&lpm>8^PWTl2-3 zHedPPSNPEl-)8;0&mi76z~Y6=na$_eJ3LG@66cs@M-qvs{B>l6si`S4`BJ?B0qPA? zXDmiKohEAfDHmQ>OC%@gJ=}ij*|1}pwJVZ* z|GR=XpxHzGtxhtEMsIQP~kx$49>(JE{znKWPi%y~=-l_Ef9n14>%Y`o>e|f0(ywo<(K62hq>JHuhV{m4#!dcfc_??0KE zv4ebBP!Vf9!Oh?LoX+`?mK3E! zRF5I0>&{p5kfC|^7T3v4B4wFIRYypO>8(8b;vFzDi5hPwXO-MgRj&xHxz%*NNS~kD zOGgrnXe6Rh3i&*H_PiRP>Q1{P%^rdx6s?Y)luH)Dh=x!E%|eh@+}w~^9Hu?gpa}=Z zagdJ1v}3tu9bU`OG(Tl?=Cx?0y7*kv+{UQAJxZaFMTjUhMe&k|A=)0LV!5`P-ED1b z+cQFoXLIf*B0H>EyMo;#+Yf``XAarO-5eK%X<1?xNzH+(C21BKehoC$rD|D@B%7Te zlb@hjac6*SZEbXRc9PE*a2$!_g)<5SLkEYcluFD1YuB#y5Glvi2x>07uNY95CY71LyqTu4p0!M1H)QLd;eexai4Dr2~fwyx?3DXDqXFPBDPqv|ovSQp@~ z-+Yg&{`KETZ`)0?rZJi~UAt|^;_mNX!0Od4>`4t%wFQBg%8lRs5V1$La_hNsG%HYb z++3Uk`8-FiRJr$wYq4!;Di&$5CGoCa_To_z5R0{P?6GTTN$L!5-%1`StF=m1J#l0W_FKCb!tm+LVFuB(vv z8zHV{r)f)ckuAE$B+2>7s)S9cG@Y?H6Shqv*~;Y59(r|1stc*w0#lk~gvOj%rA2fQ zwH-n_NNLij>dY7wh!tGRY$>sUutzZ&%s@>Pv9Vc(N=>;gNL+$^<{8$l?xJev zn2vSxG7hu-ISx zu+r|np#UNV?028Rh{^|71vx@5vTrm+W8ZRGTj6c*UB|soR=N7~o49&I7aIrK=}f9j z$TCBzcK&$NA7IH@@Yf&m`G*M)yRwj zixLTT@80dY6QYo*9wZpl4znM26osZKhpDN2-RTKp7?6UN&prj_J~y41ZqOuc;jmkITc)dj zP<5nq(Sjxf!mgm=aWXy1kzr(r#li?7h;}6~%_0cFL?KPGBgXWkfnU0iT~AMs%k3}Z zu`CNsQ+R&sUMjZE@Xj=22Qvu8MQAEkp5}%*W~;E}<;^4)EFcnzvvto7!a^Y!)fls; zn9lkr$r=GI!80R|)4p^iQB5OnNurvdR4&ux1*KV*YZ%b%!G$w8ENWjsXDrT~<9P4K zrD8Qm>FPaH6dK>0Ex%m+4!!jHRpA^2M8O+0P_>Y^vLs&{K+qjWzYM7c( z>(m{8|6RlgznRWhSqfFD*AKKLg>_P5k@)ukho$M!;FdjaLp}=nvz6Dot2Qa$=OXe)374+P8!yiwk^eeLM6X z!@3)PN&3-gzJJ{%{Ocz^$>__^u`oP`svg6Swp6+N^P7Mi7j>stb;42}m#r+i>`t&F zpilDMx4n~pJEIpe8Ip+vr~m9l9(^zhTgu$=8A*5lYF6E}mF?Sx>r}|`ji-^!4YCiL zIB`zC>M?RV6;LwVcsb0NfSu%k9VDTef5)GEp2I0T#L=eYnHdNn2zdo{MY=kcnh@xE zl12mpOlGAZFC}1jMM;dPs@8*9OVUJ2)0^hI>9MYpn_Ky$4A;}XCOk;ql=#sJ37tk& zB29w^6;xt}xP=^^tSgb2_9zKeM~E0RW|<|6SF!itb68Uuf{8Btj$~GO)kw1O5WB~k zqEOD~nZY5cX+$DzOgj$#Y=Nrd!;ey@K{?VvS2Qm~Rl{*WZ*N1&d|lJgG(W9!M4i4= zQ-p_NC^$}@CKUXNK=F!mDP6I76G~k-GJihfH97HkC%LgnDy0(ft}ZH8iOG~}f83%* z*qzVG@f>A?qc}J7|T%Ve~e~ zl1Q1SR4UP{3A)-kF~;`OtO%qdiA39pb;e1Lj4-2V1T2dg9BjLQqA1Kb4qDxJ-=XFO zD8Js`)pVE#u2UbKHliX_AC4E?IcFw_s*sm4YC>Wb1wusV>F=VD8bo0QHBlxfZMtL( zzl@=)?)!-$DI^M%Dln}I^l*ULVh%MJWQHIRptbDMM_K{_rUOtd+vIHSQO z@5u4JPk)r*mmXwpuF4DwP@}<_pyKoMv#*{**LB~at#u^$qQdQlQp?P=pEp;VU>$7 zycdMZI6mHXMi*nl!zh6OUl>mEi!1&B>OzPVxZr(9^YxWMx_Tv24WoR^fhV`X*bdIU z^kf=~DqXs}heUKi>Az467)F{{EQT5kW7`>QThiN`z%bIh_tJmDwkL_If)iG(VS3Wt ze*#*Fpe|6+@Jj~;H_Kv9I37alkhd+8iN$Pv`6*5~bpx}&%mc$0%}8nn;a4TiYLF?z zpxL%?koa{KQwSP~Giy``#h@e&nqxY@+@0Zqjd#M*0K`v%@ktN?*OuP4S+cB;$3A}o z!-LOrgdSjjx|gG_xdW7i9;Myj!$%Bo-4zSjK`TdJ{7vXM77Eg99we~WJzrw6?V7W> z^b_m3>6csh`j69m{nt7y3xe7WqZ!znhK>Ok8{+a)8aPUnaZs7Ehsc))$l18R3j>s} zCngqd^=3&J8-+zG|FA5;O;?=F{=w&o_jR++9AqkO^200EF=#x<-mSosMZUX9fXup! zPQjyX9=MNR{&*vSa*>EC0L!IU6aQ~FBCqH6btu~6QjVcP`rPZMsl2#p6XT^4VI{=W z)D)qR!bCn#S9?1LCMIa~E6jL70L7|B88~L$(QJO+Vg|wD75x;mSx!Fg1fJNml>?b6 z+7sPqnj0J8IBs^={5})%?BVB!%ucD~4%z&HH+X*`l!g+jrt;{0n|Rae0Scx`#E~?I zW2mK)E6O*^#N+K`G8rkQz%SgSr(B9lnYjUGi{DWczMST9(#0*WQ&gD=%~>~qLBoXvP9l-Skc|> zO->!M*)bM(E+CuDQne&P3*lFyys-NqT1$nJCduv@WCn-j?R^x`_d*7i3C6W=`9GM(!FpY+qZ2anOul%+oaRu3=Ax*bAV0LWME)`hKi&b z5Ow5b^X6xW#giPfZZ)H$89HMDGPXrc2tsO%*0P}aK$#VJg?OsS-9P;Si$Wo^mKJXP z>_$Q%_knzT(<2=5%NyA8Ke&m99{Mv;Z<;x8 zC)W~-VHhTD{paKRZdq(M5cM?yRBW(EG zH$W@~R>2Db<=r=KM1QB3t8<$@{$>|#} z;^!C7@*htKF8|6lXj=%5&A%MiPY4y?MR&n|ApRcy_4=22b`W2!GD3`R{B9@P z?;eJT3YrSCkB%$u!urko`1TX8aOYhI+$T$!;eWb$d|%!U8ygM7et zZJ?WCD$}-2KvkJFO*iyVN-Ap7Lsa8)+Lv%5qX@W@wLZKEa9_o@SSvXRXDNNGU)&{tV@Q#N@I1Ypr@pnxW4n1155L%mf zT@G?E8b$Na7a`nmG`|BannpYxXWQT&S8L;;LS1d06bc2xLQu7=x|YZN>Qd;Yk#2;V zmm?!N+yQL%;^?SZ`#D2pZGfK zzVJ>C+;=B6(`LVH<2&E^5x%iO!a&)EcyBNL-`WKSbeP=ju1{(oM_=*>=59ZSb+_*1 zg{QVbM<48enu|{CB$V1rQbgESj_`{Q{{cFaz&J>qJHGe`7k=Xuo=p09@B4r4+U`n| z4eR^p0xEWz24Y0j7NuLVIe!%6%enlRerf`Oa*}}EK!e(ilri8X+PmLEN!qlwh8Y|jq(SW?Zwq<^%<4&Iw>-g~ zudd~mCk}GS;~Cgmaka&Y4M(Vat#6EfKKB&#$`F}!86jdcCv+FV`5$)q`rGfJR<>yr zf~uHv_fQ182lvv`(!wk-kA?OcUQBH=N{Vp2AxU(Y#NCm zgoS}*e+eJY%JOccj3X?Aj^t7rhn}QuLks9Z zcM2dQScy44di+_WvLp2Lv{6$82M=ahu%L&3`ls`_<&K+3YVOTivSbMjs){1PCnW>P z4h&csNc;O3IN2LZU#vB56esmXa@j zFQd*EEb9)NKcj6aPnJGRh8e}`v*2|+=#SoCQO6AzCQM+4KBX; zLQZ+}YG!dQ8RzY01+L&es>0pH9K2A5PMeLV^-?eue){NkYAj9{sKq54JHk4|JWif`sQyz9!2wI&$*a?Ar2#V@Zo8=Z`~A9J0H3;B#-~%=I%oG@OF{YeCz_smE=l(Ma>a zyNCD^i}_M~mlv!CE5s1Ly809rcUky;HVbX%&}BWyRU6Oaiw^}D+op2)&49Vxoi0tj z#OKdm&lk>Ggu*Uvdb9!&!Rbfr4` z$zzjLCDL5{pDNvEk?49ah0zySqJ~jTgP^{KtcYRT1_@QtWT#1>V+zO{25q{EZA)?z zDymA+Ht7^PK`Bs$#9)%LEoc?p=yn)~6ppSkDGh=GVhFHZ$;O18BdV%(PjeSA5}qxp zsN0;r8V2}kSY=HJ8U;wH(uj%@Gbsz{rc66=N~I|pL*3Mrx%y%}`x@$(q9|B-3!w=7 z(noL4QjCKIG!3MOmez!*!}daGE;_4e)GW)@bwsmsp2ibHfF?j|>rmQ^CXtdr`Onbb4zXU69p|`h@&lhMG(1@g?CywK|`kcKx_Hg97 z)f5T^8nijAu{;wK6STLtV_EKG$^lZ@0+EPaU&m&Ep@RpRvMk!#;%;LSg^enkbsRsg<5^Ow~(4}ZO%*5Cg7zoH>iS~ zmr5KlB7{YpG~icVx|}8jV?rKAgUs7DejzAJNez>zD#+V5LO|J@%FTKXr_;HN>jqXf zX-OvOIPwfqrb0HAqcA$ew5n1xZB8E;;6vXpa@0E=;%bhWKmf(m_}m9S%$<)u#vNB( z&n%0m#pdW!b$;`kpK<*0$I!O88>KkRR-wX+qrgILI&VEk^hP=Pn}2|aitkhVpil%$ zAas-GfAo*US}n$k&=pSb!EZeYM|VTPVC0i;L5%SR6(O1r}75b;qJa|bK;37vS!UnCW|@OxF)Q#d-pIkRZvj_*s{bk zgHN%~9O8t&qnWbusA?y+?J(!jkR4oP1*xFR5OcJmj_>2th25mK>>%e@v;jr6#DN3P zlFkp-wT!Q7FWvPb2-v1cNR{2lKK14vo_^-9ys#~cZAliyVdbiRj#>8>Lajk2i$xq=r6w}8 zsohkhjSpzi=O_EgLyEHk&_@yQqcWZ=)1>RJzCqgLCDepLqu$59RGBjd5~K&Z4jU}h z0&@h)OBgQ-8l{1y>IeaC(gxcERHR&hs~ofmO5H4@3uKf5SVYi}+LOC7Mx*dX34{R0*Xa=(!R)2tUYbBe_zZ-oAE1wn2Zg zm$T0}oAiM_1S1*;>_$u!rm7NAcF-C$6ckG25g{;34vL}>_L`JKX<+jx(0qe(sPmWK z7eM%-Qq55+DZJ$^@8EwHt7$Z$FO^~%NluppY)PA3#xPIO z8S6s`op3lz)h^RW0Y}#vG9?YgQC>={WVM8)sSG=08Z9}1&oHP71KU>V@9*dFVv#0n zPPA3Fm=#jG!|@y-Cp+p$j?3r}UfhT)g_uRsDq;l6Ho9nKD705M#H@XC7eo?3(MnZ!5Q+RlRxhWa?H9G+Sl92!3?Rv zvg^E*HEGL5cyap<20x`Ygew|x#ynb7;@1eJ(FX1t2FSYywwU8t(Y@U9`Wq|Uf8&gLf{VbP)< zR-6Ick<&{@+^2r-$P<3p>q_3}!p`jGbu~u?9gOJc^5Tf4o&M!uODJdby zydg25*w!gqRkBL5CEN1a zZM!#mgKl;@>>&^cA=}NK5XeHvWbU0za!GPYm@G34lYN;?CV>orB#?zH5CS9+2#^pO zx*O=d+jiSh+mf|dDz&O))sgM{$0^Bnvn83|{p+Xa>4(N`Ev2eD=l#C#cex5PS7uHE zBMp!_z=L1Dm^1noSbNJ=oc@M;AhQna2`D_q-Y34G#_k6nraiJ%<)%o<{nwvQ6of)fdkDDYUT7*5pKQaY(hGiulxdp`k^oZM;_&- zPh88J-mr?kT#ALU92}@XTH|N`{7z2TP~xIBn;CfDpFs{O7cqGkfBNzz^aaCIs-QWm zV0;G{7Qg1WQWl6Iz;7i&2t;HZ;g zaBz_M)EJS7&YY7aZtW(>0GcjnMimfqo)EbfCO78@Z}Cv0S2cF+L>#6Ma2u-k~P*wTDbKMTydi{9IsKVMB5&POf2T?EX`$_UjlN45a>d$yN3zA zmY(dL3-5TEylceN%{n-)X|-y0>h+*81h!q^SQbV{M~TPdIF3Uza4;F?jjwqPj$N0-ui~j_4bVE>bVMQ#)`t_$VG7{%4Z|P%VtPG9;0~1{NmKbjC z09XI7bGYS)(=c9!^pkw|F@8taf0Z66H8`2TXBhH z!SL{Awm*75u}l>y;mPg05Ly7oQP4zqAVtas?>s8-;tz%S^T@Mo>pq*qQ&U`Y(PfM$ zf6F`qAp!(D9OfKJEEb^xl%%NJ_tz#Z^M3_}Xn6-%z62jc){CD-gAf%5P|vapnPB*6 zl%q&YGN}fl?LIEQ`f@(;*e_spjPZkGd^{@ndCwEvaKl>(VlsJfjDLLPNqqK`&q2=_ zNNF)+HP9@eBC`~IUGQ8S3R!Ob;?+Pi^P*ZWx&lJyymL?FqF0_la}azEl*`~aInqwD zek{$vto33!IpTS1<{S#>9dAF|=uvP5!qe$2f4wGM;By=#I#pStt$Esjm*E0c{wn%c z!{6MsuK|aL!G78M&%Mw&r~*DhfdH>K`*g1QpC7MV@^^I^+<4O$Sv|Pc zW7^c)*vpQ^^G5O3OhL1h%g#;($U8|oBN6`BXYb?>BE+9RaREUr%8o;h7;{d9py}iK z-|pp`k0tp2D}wZG*}(a4`XPUJK|9xdcq6+<8`$)B--0vyn7QsEihHK%iUp|#RhZ@KbTC}c?g z=pX3A$DvdbT^EF8guyj^Tyn!b+@DGEwbyN6%TOO3rb!W($*e((`7*N~53qzHf^?<` zb~Bi|cRw!*^nA6=#57HExg2$SobCu6UF|F+lI+$8+4RvJaQFbD|9LUhWRBHCJv{k` zao+xs@57oX@Bh#n`O+%~F&yglxUE4SU-{}y#N#83CshI8VHPP#!E`)HG}_HCe|aw# zT_pMKZyzRY6$l7Hp`dR1HY3En_x_j<{QbvBO-y)Ui8_X%VHnCbSXl;3%4M6mxeAq1 zrM}TA*B+NPThgcrTjHj59hqitC=skpufF6f6ucm`qB^Y25=z30A>D*F&C;rGcTLA@*md zc-vK1^P8XF&F>!k1K;?@zq57gN!o z>^<}h-77oDl1Kr%;*eVot&t$LP&_=xokp+YRa?A-M+Hns z2YLn})no?8rx35(cu&EpvBP{&z ze^cGFhY}4;lVe6?lnrzUnx#%hN~29k1>B}4xbed$@uoMNfRjp*bfA?8vqCU4mLn30 z(2PUgdH$Gm={U8*4)RWvIRD>UDsK#lKn}No>;kjzLi(+*tCDl6ZjCwF#i(+Zl zH%4_%+~dxb2G|}Q%|#1{`ui!TE{&NQ6;w(ZrHf&NafPw~u4rI}!>G_mn^wcX78)~l z8rP$@%?ph=TT;bkGBu6f)<&yT^sCZz9<$S+-2-#B8t2k(glQETIXh2_t7vRBFjJ8( zt}Pd>g@Hy_al>msz{Xv@=lUapC8BZsqT2Fo2{k|jLi|&KamrTxd)9TGuYdKQx%iBedFI*2 z`QWv0qca|4baWplZtiA5&d_LtX%rf;K%<o(_c_Y#Ln0CbO4|FF%7O-C^P2E>=V~qJQ}z zIOR0R9AIAb;}W4$N}9X6xa!*v!BjIF&RxsvUL7EDFtG@Ts38|D=o}1#l zs3mr*nqbbMPPu(slvj5o}pgCp)j}Heh2UWK%^chsWpjZz(@VR zR^Me__`8xc>98P79^9UVaFl=kuun-qcs2hR@ft;cbG41-@`xj`)Sg3O1hvcE65eA-2bO4V6bIq z17P7eS#$wLYy)#n;$>-SrfE`@79G(DXtSX4JYx=@5CW@UQ9?^ZCxhDP9p9XUpIg)iE+4<0Q#uvrJ5k zuyyMuT1*qmYQS+EMn~h!ISn|%MhKlXn>Mol$3G?`1Oo%B$Ye4!={n(1FK@o$P26_d zU37GWme~S?LLu+QgZ1k-BBk^;Ue|LIQnajrHLGcKCHX?Z%Un>@4qGa|dB`vjn#M7= zL<<_Ow3!zR7)F5J-X3gwQJbQ4Do%ZqZR_db$dPds!soioIg)9|p-nfLaV(C>0>i_r z7@vBU)`&sgnZR-iw3r5t<6xR5O}gM%Mp4^bTz>k~pL75H58&7~A>Btdr8*)-2mTl@ zbLIc}G7wUSneKt<4D_ALp(7TE6^eRy#wK3(u?M;Cl_mb}BOl;cu1F*j!?G-I^e%8b zyU%76$G9f)sueE*p))7Oz^*7qo}2@+%CHcO$Q0XNzkye5Xo6glbhd%v{x0$q)aY2k zOe&7gF)+JYpeF)$mIuD|9_AAVX*T_YbwNq0FgFYbq{QbygGWO|IA9d`&>OZ<+OwTT z+0CrEfavPNCk2EcC?sw!iQ|_LYlmlZy!-48Y;1?|vF#XUjIbF|9D8d5bb}&U=7j;p zs<#tl+5hz`Nu>_ZCe{*i9185Gx@IFV0`?TM4zvi9h)_lmMByLaZ~~KKyJ)f;{CbSC zl(a-*Se8SDAdd6GQssHE2v$OJfUr5lbi9n?9AoRyN#var3zkFFi~(_uMW)DGMOH_K z$U87C;7HQq#K<<9oLz)vr^rTrR3eAG0#B3E0 zv^MEFExJyJP~Glhxzvkx-K1xiYnnPibjs4faU8{S*SuU1A#iQQeXlIhJ=D7RHCPbT z0%}_63FBv%h}wnF>LG_UH?BeAgfSROucFFS|O|tp8Ztt9JBQ-U>XcY@I83wLfVqSBZm&%!|&CsX- zh7pFaT01%kqX|JzZx6>@i5;?$(k2+{sME)6TV>143)Q{T0t*PKI^wl!s`kCrrzb)+ zQsaXDrKoqdmuBtEdqq@D<5c@2mvqX6P~f?7 z8SqhVhqVIE@th!QPFCu_`VxCyhXV)4*t>5(8&?hUz3+XGfq`!J@7Ea_89~(tWO6yA?m%}0GLr9o zcVTD z1X+NnP`V9$8`wqu@SktT&OM3GF{t|cNTlLKy4G^d9Y-iX*A06Q@{9jESv5Lz=#Y|J zImE9YN`Q#*ukSsZxzw09F&9f3f8O=%O?V*bfk+Qfc-MO)f@WR!?7IK@#|sAmis#+S z6%^HMIiv~{Jdm+Te5C!tyVC16r5l8fNPtxr}eFE|zRe&p8r;l6r$>(Mg^B6M<#J*4pMYWG&MBi&bhd$61FVY z+U|9;m01rJHO@)qz4uxUG8U<9qR~fUa+)^Nzz75gN5Qrw6>M_0JQ+@JMYmB)s zkfvLyEBc=Q2#*9BtaSHo-qN20rnKzUVR$(-gY0j z%`gxFr;I%?2u20E2YKX)$GPVqoEUNG5+(<7Iq2O4uB22glXs>F=v(ni2?BCvhI{`w z2P=m_WV!V#7oy84=8{#0%?k;)!?|xdjYp;=U--!mZv5JtspeAbw;-%L{M#c(A-V}d zHYaxlDHbKu(oq)dR=Li=c(I4$SVZ**!S*12j;SF>CR<NoG;`dh|HnV}BuRUlK-WMws|SV&>pC~z z{C!S5@kH*u_t(q`jm>LTGjT9Yb2wB75Vei0A|=geR8WObq_>w)C`>V}K#EG1Za`vF zbzSmHJhnlj$uKaa0xclO*-}wNgh4u;#xMk$CJ2W^=(=EXa*Cneo_ZH++Xb&c*LC*n z*h#FrnFEqsmxjtLgCLzIk0%VrW8_!`*LTt?%X01_L{hL7gz#N8*q)0z0ze`N`)g=siHav>C>Xu+U91YLe87s*S9v~_?MQ+3pe zB0@-7FS*gQTLyE)2@bhb{V-K_Sa2E$=n*oOx?!gyQOrn)mSmD%-Q-v#Mwc!KXLnIH zV>Bdl^v3$oksM9#raNMC3N5O0FA;6}0*yexP+-elq`ozx^f)!`M{RPl zv~H+XnP5`cqxfwQZD(U2h>4r!5sE(pfB;OH$Ijq=>F*oWv4J z*!+@zs|Z1}T-sIhT;}9bJNLyxcH3EJ@z|q}k;r6d(hV%jVPfJ5hKE-nrKBg)O@DtM zQ@Na?BMG?SU;c?-{p2S&Qc-$uzWo+l*QTeZhu6L3HAJIPB$ANj83{-m%m{NP=vEoT zB#&pZ^vW>!7s&f1;l56eJQQwyoj<8P{;xfjrtY>Vk0NikIlhv zW{`4 zH=8$~qkxWU(clyaGiWA8AhC;6 zHVk5ZV;UZv1G$qgfBal7UD#x~NdN#K07*naRMSH$HAaan1HpDaf5#z+o(5t!rw{t5 zCS={VeQ`=I6nGZ`U02hKiiZv=O8`Zqch2R1^LwZZmA!SS)^uD7WSTvPDI`mBZ>oR8 zluN!W?dvb2i!ImuF4eXyrBP{3E^THP$^0}M2RBkE6mVUa(eb04z3p^%J+XsOR{-g% z=XJMr)u~sdvh5|?FQ(AXYo4)->+)h5yjoLjnxabMzMf9}p%4cS9H6bOjqFSbH#Nf< zXPm*ogS*k1nw9}-P1BAyKl9GDH}yL1{bnt2M3(ox?F4@Cjvs(A%wyY+@ya0`WSp)p zKWE%D0ihThH!lE^el4Udtepzzr{hWoI0jP(Ar#~CFaCnbTQ9?xN)V_8DB4avo*kRUJOqT8k%~&#A!0Ok zxqRZ$F_6Q2_~Jpd;uup>XG)lC(QR6?Nwwy^WTPcQ$#L+Pp*a`?qY7TwbR-g41S*zg z5s60XG$70J?1`V-!>X&#=bt`50?&-G{hOE2qk}cpzzL#C+{$7*-87~O{Nvl!^PSxd zT=s7dGA?6KcmSm2Sh)cZ932@!Hx^jg-_M)_dB;N6b=GVe;-`1t&v$RT6M$1r+053h zTRCvx0IuuuyNL;QKJpYRSFT`QX!P{-vU24LcJ11WFa$H6pjNu-4wO<-wM*cI`3ND% z=T(fb$(q1t1Uw3g>TtFI^Twj3sdUw95e|2dPNxw9(&;p=JBjqV zoH88ZwHIEFDJ9cRSAIZ5@EnIv~ph-`>G)ryt}b zh$J7|*2#O%T7#2H(2Rp$>My^+#_|-UMuBc-%R!#mKF;u9J3W0Z=(WOsGgvK$uM5v>K?9rn{dTWLl%O?lIULIhm zKuiGJE^$njXqM`p)`S8fwr$huQPWyHol0|Er=kE&u9PRJ1(-KjHoeg_jjD8+7tp*! znBM}}fdG9SQGy*Igryy;4@|DuuYK*Sb#RtQ zBtIsdFPNu?4>xQ@W*^VNY@?LCXJwct#^ zREWM?Ch=QU%9aBiCd8*W^^OQn#dm@p<6Ot$eHWd@X=}>#ntsSe!Hm%Mi3eCU(9dB^ zh^_@B9iMy*ez6 zu#}uO+|P&K{XOoz;}&lH+^1eMH+NQeK$ir#jRUw#t&7LkiS+u zT3>qy!9)zs2QC;6Gn}EI8 zF~5}SQe_D>PGuvB=RL1}Pt{-B%WxCEmz-EF&G>jZ_FmD>p3_4Sd@PkWQ{GMcMVD!T;y8gjnM@xzUl zB^0pvCh>fSTWW%O5RKH=(d5_|ZEbDLX&RlKok%I!^~4kCZGq#OUdMm_7oL7K%H{Mg zp~L3(0`%D6=zR6JN4V&^&9oPH(4=o5|C9ykQSSNI_kd+n$_SzzF*1b_iUL|?Rk1uy ziK#dUJ;HnM+Q)xgegZ3X3*>&Ffv`VF)lz#;qwrCbf}mr99fegfZod6-ZvKW;8kK~BwY^2smB4z{0{j4GoPn;%6L*ZKoL@A7jQYcmon;mH-7m)`Tm`Ea_v=D(QEp7_F$GdT`)MZ$-uvd)Fuds;9((N1+;+#0$xh60>yK{ZTQ`1|%Pzc-cU^H7js9LPyzoNq zzyBfn`XUsI7LiChli4KA2t~2-7Mp-DY0(9Zh`LDiNR797*x@IKi;4!}N;TD)iu0TA z{YqJLPL%m&+G6XL7LdEuh<%5{ZUXFfw=0i&6L#+yWp|)AHh|2)a6ed*yMMk1q6UAI zI*cFSRhO;?cfSG|PpfM?M^T}7YZRVVUj)v3(x`5r<4a$%ibG1p|7b zYH`xD?0z&0p%9olOjvwjWP~eEU60R^%;6Bw#mjPxr^PyU#(jMJr&A>UIO1smo`(E$ z@Y-$6Ubl(aJ%6MTL1xXV3|{#|#eH|->Vg9&KE=ov-i)1^U~tW8y!obw_|1bUb$&Dl z+$SqNb;FLc0UUK9bBnPiy;Q&kAM5X^gpXq{dl zP`2Z!F|w|k_0GHNN*Y-NDaSu*o5rFyysJc>hNlCOs$YVar4s7spj^mfc6L%srwMj+ zP$;O~z_x8qRO;3X@cO1945Uy+`_d`M3-r=x!DUuxG|T0aoOx}bK6R~ul;t`WcZsu+ z%3IQeMs{)%>8i%YEG``#9iDTSjcu#${oGNTe4#)(UEt`^1hH_Z(!+S~VcUy=luO0% z<$}#ISJLi@=K22HncUQ8Yc_-Qspa~CrR9QeQOIDUr z)~TeXM^|zzhoYy2YSDG(oJD$)@MthgIreqh&k~J_D(+;xnX+_}qRbrBwUxT!BR6YHa132#3UGuFg7+yi)q#=Oo>E-!NEatxgr%yg8du} zY=qw@DANtD1uJww=c#-4K+ig`bsov&=!@;)+>=(&ENyjJI2MQqhj)ysOp8@(VSFdZ z80BY2*&Q8Xccu(>g4bVhGCjheTbRtsY#j)`bjN*Bz`k_40xF~In(IGBs%-FhJjJ`; zb~O!Fmg#tco1Z*_cJ`Zj))6#S4I~-}les0|ZSuv zvI7}QSvbcN33Q>;8WA294d$iuSKF_?SW*1qjaju%RXo~Pon|AeAQuQaKsLqt!4^L8 zhCyz;vz7n+ox#cHHS>m3RjJx?!(%XY0@zdh;m23d*JlxzCf)rFOd^RmCb?pRs%s{9 z@X52@L8UAyIB}{=0OG97QaO&MXksp-hApK%nx2E>OC4)P%4LA;c#t;F@wVpj1p!V4 zmC5ydy4K%zJ{I3+k@i*bCM%84ORHZp9aYW^p34}=O;MIiQ#>k|5PllxYU^JYrP2(8 zy@Tu<8zY&|d!Sl5gyn4u(Wqc**f71?>2VN)4=NO@eBv#Bg69seGQ9 z$!W@dgSNIX(Y{Ws>FGL9(X{7-m8IvY=JX|B;Qp;3Xe;LU-uqw4RX04v{rgPf<*oGV zF~0S?BWh1wZPM?TGzgtzQIpK%b~s_JGFcM3XP2Giwr{+hcfIab?z`RMr)$>m?*6LR zWHNBd4OE>5T1BA=9! z^~1x;2}qPN&5)uFt%%elO^`7-S`4uwwiY|tKwE4hJ9E!*rj%rPT+v^iIRHfIjctNS zAYEl`(9g&2x`z*a_&sDZ6HI2ab&9~2EnC^PZ3}<+?RMhv32fV9WaKcZe1X1>4xULr z!-|zF(Hu!)d=j6bvwiz^Rn8ihQuJ>a#0qtDG~CJ7|8W&x|L!;W-S3~IYj8Df!)pk( zg;}|7GY{-}f;WHoJ^c2k53*(bDjX+^<46yXsBlR^tq548T(qEjn~S9EI6N@8kuUNT z<0rTr#!;(`%&^K8%rL~sro{sx2Zq~u^@yK~b-}-%zkv^p#yMRUu=Qbf%M7b9X_q=B zV-wBYk{xmc=;vc+4|1}<$^}uKhir#cmvnL1%CJg0zyKQyI^(8b=ei7t3L8dTzVo_M znbjxwj}rt$T*&I2En)~+ATFNcaQ7yd@@y6j$>~v(%k(VYy)F>=O|x(&9A7W|weTzwQb&@ep&4 zM$>?gSFSscp1&Kw3 zV9>{m^ieFU07=oVlRcQC5rcW%kFE#Vy6qxv{PcCa{?c=pNv4#hLM#SO$t8SSAp|YD ziO+$ma0mv2-aje&$ed+u z#qc7ntVXqJ6#?+TO^Y}E0gX^d&}1x-ICPXuB2Tz2OnWFyx!^G8y7a88Noi5PP z(LtqPb1ZGMZg5k5Q?G$B*F6ddIyyR-oIF|wX9~0^GXcTkB&p__R{N|=L0kRrUNU_} za}nOpUQA41DwVuiPzNC>Nr$RcrtDFu>Rn+W2%rSiQc9A^6!AnHDJ5&yY$O)zQWQZ) z70`=8U$XADRs$imHK_sw5X<=PHBC(2HdR1anB=|A{hBpv07#`$GCzZ<4-5%kppr7rRA7XE}56gBrL6*=& z7yFZ=^omUw{S#Occ1g*F>s&r_>4|g~0e^w_zo(ap(JCdU%4QaL%3MRc@N;s+&%Wne(_ohjI9;KyGLVOaPd{pIgID~ ztqPY=RGA};?N`Nt2SmLto~I>{&}(|b#Sj>#mnC9BScj0w8QjD7zW#3rq1QDU%?Qkh zauDQip>QoJkYA4a)L5U?QRl<^s@??9SYV%?r7gCS=EOlh{+4sN@rfPKy@B_A_1nDn zM<3#yPbT2m5E$KXvdizXM=6ZP3CLl3^bBu0wU=f`XJ6ba_*MwIgpU!&=Ya!7dkhFX zO108g&7s*JxBeGr*xkhw%HGXlv`@sogsm99+x9^fXS{Mr#tZnNen}JOO`zQaMk+A0`k8 zpt+?w6YF>py-(9>^NM$P?`OR;*Y5R;?a~!Ac=C>%O zM^Lh;_Y`;K>U`&AX3Lg3ML-eicrZ*a)N!Q6{Eu_qH|NZw93Yp|4GlW70wquh$I!U7j zQsx;58%!VCLpT)1?9e%KBttU-9St;%R6b2xTbPjBNjMBnK7r6Gn6#1~v+=ccGK)qd zC7LyZc}*2u<-CnyC?T#t6lVUYO;-uJ(`g__Q-{H%oWW=G5kG3vy)wkCRH0bWzE0X~ z17~KMYNK-NNw^8ZfdF9e*!IT(mvs6ln^vz@H-zlKaU`}q#h9G%08s-Or@)~@;{-dV z_|@IN;Y z=5gr_x6y(ic`(PTE`AHytVNTqqw5hbaLAz%Nr&vli20ey#;G6)BAB$w1P9wVRE)E# z-{jZd9!4Vy1UW_-tvyY%Y=B&pQhNr75I|=kQ3a>SwU@5u+MtiTx6zcHZrX&P3CSFS z83`eME25ZWpYIY1#Zex-zMCn1fwG9wFC&Ot5&SNdTm%N8+1UX^nU(#_7E^?9nZN!r z<^?o~tmg^8Rrzoi%Rm;ox|y|f>}r)pDS6#lCT}`t0U-q6^}1lHQ>8)~|9$BVRIQRP zrnu&9>lMG%XVkS0YH{yYlDq0F7kT)=q+{U-(4|ACccWF%Y0+WUlK7=TgPEa%O{9Gb zSHJ0p5IUXnx-EYHwO0|BabOkC9&G0Fe|QjNlpo!9g!O~%kO$l(>7TxzC_C7h7-s7= zKS#P}kWT2B!MG|Y5C4*d-(AK|C&U&cR9{72wqfhg-`vJkm%pCx{p>D2_301uk&pa6 zH(dK6P8wcMF*C_euH8g>^fvDK>@7&C@xd?N$W1rhNLY`ue#;hyhSt^>+!kF&pyLx+ zYyqiM4$&=;N1#H0IpRPU^O{&plN(Yy*5W>V~Y8>%VZ8%~{_5jNo1WRdN0S_eTUM5m40orjKrgY%+VU>I?T$Cc%YdD2`5E_O; zMp4;3lNf}qiXWk?scgqO?+%%QsII2!={R(|T+qJ-pHpT)7l6ZfGD$2p1b|;=sfx%; zcIsbj;!@X0zDzM&)lKFchfWEOl%)K9v@i?y??7y2hzN(Xd+3QoNFGcu^4ZfFe%rqQ z-86i|hUbncVYh3;v+((+i^^`weFmiD?RO56>TjvYbG4>`Nv&(0Z=i|OS^s@|2tv{SZEfDV82OM*F{6u!ixeG1++ZP zi+Hj8lotad@;C=F;nB+@K+ZG5>Hw78d$YIJR#*&UoCR8z2t8aEI?X8a8dOUzv2Z80 zou@Ytz|}NntUTFLiJ)JZmiYXFdCg^NChqB0Ts5U$0w!j0X(^SKOjnNAFRJGpb2Tpy z%SCFEqFX}K0!*i7nD?8CiWX2)>=`RhS2Rqa1hcMkpj=p(qk>CG>PT6pg3^jKB0w5Q zX)#2Ed7)$bEjZZ+f6{o%ts34jV-g>cl`hjul*tL4tzH}r_O;kLD*lW#VIf+P0%ACceBTL64rMk1aa7%I>1z} zffL)|y%+Rx^ZiLazq6aqz10Fa0%vZ5eSWUH_bIM<_t~lu%oBt*oJQrKz|1C@Gh^(N zit_1~$(Pk&)fg4WiVme*t}Z}qUeffci|K_>mb_Ijn5QP5oOK)uR}T=nKtW)?6Dk&_Z+ON_&fXinMo=q zjCef3Owy{m4%K+h;MT|3Q&UqIhCwJaMRqcSCREU4yBlU+gVv4;7o5AEZEH_sI=+Vo zfA=Tea?@wH_PWp0+OrNTt?~l;J9^0%rU~|Rs315meY(GMfp6b_6OaD-`^37>L5mIW z^T(d!{)hLnX3a*99-U-fTcF+0=vlcEAq0k@dtb6vM}D?lVDsi-hKGmf>WVRw%Hh*> z=6pT^9uK>5i8IT*cQRT`lR2kKB+^bK62a#a=(-=rQ3>HA2g^tqrQ$3QiI@a|quFsL zrbqeLZ+(t|P%p=%a#l)Drdb&Zv*3+QcR#+DkAC(8{OFFmN#~~kop>TgK$x_P7$A9a z>{eEawd5TOzclEG4H1b5(upD)^eD5A&NLQPeTuwqib_$^>u9thh&ypsIQ>+xn3Q9L z`r4V44pz}2QWS)w^a4a-!J}og#gy}yD~f28X_7vYLXs_-$XpB|vP|$K&4kD~aH3vi z`}Uo5_V+Q9oTDwK&`;cw%*!HeP8Qb`WYEyNVoWEBm`EiSPe=lyT)&o%cimc~NysIR zLyP?1dN|YbM)Kt)3-#i8mAcNHCz@>XUbWeKO}T`t-6)|V3?A7v4f+tIck|O*-$(x7 zBQ%)(1cTjdi%D*HXCI&W{ch&ks|e9fv}1}7T(ug_f_!2%8`t{kFNp}5Vl2xmEc>KY~ z@Q1=gqrD`@$NAN-enx-)0Du1T)BNOD_i^~>QKpjKQMe3X8eYeuB>r-l*QsWEIpmA>&t=(^qQ#@9H3K57=%vziRYy-iI+MX?2x2Q% zkQ^UpURz*ta+02&9*z~H+H}21KqwTVDx^1=>0tEep%>^hdJblG$)mS+)ImyrM=!Iu z%J@U5NmSl-35UaA2(m}hXqrJdtT8=3O)T7rD_smj9fMu6>kez-aF}Fb6ngFF6;wgR z^&=p3EK6w;YB@adxW(EvYx(F$KVI)7kEfC}3qi#DowQ{svE=i_`HRJl5>zU?TWMMK zNleMhQ2{}Vsn^8_=s*AfAOJ~3K~!JjiCw$+`Okk$ry1gzXP)6te|Ut7fLm_4odz3stgXW9;0uhaWw34~^L>88W>4l6TSCwU#@t`4(_K4~Cjl zNoHHz$x)CcKI=NH3r+BcpPrA*S&Yeu>Ow}9r^)R^xcwfDf4^x9*Y=q-kL_VW2=eU% z>@5mj@sS@w+97vo?=ly?rCC1mFKT$JBGhs$VrD-9QOlT7Zd51BKl0Q+ok=7TV?3Fw z?>i+~pi;E(`%TK_Ui^MPO`aHk&U2$w04a-|YM{TbkE*VkW!>$AFi$%o*~Hpt4H2Z4I<&us@lp$PU-V=)oVA>Ik1LYu1Je%l6M?T zQ>Q_|7eDZ7e*IjINio63(_LJtsNk*yMd*VTFUd#4&uk*jWg7+=J2%H0t~j5`u>`|r z3^$9HOY;A>$6tQTirTbroQPhc8(w;kTO*}v$ML7MI#|F}>GSiNR{xd85|nT$x+Q4R zXlrXj)1a7|p|LE{H1)GmsZ^)Z2E8YjG?j%li|bLxo=;1zfu>fi2BPpliKj~mC~dPA z2#_t!5Y#jRegoH4&u`J7=+3ByRyId}|5~zHm78OlCe!g89kCb-Vu5_N%Kv5W&7&Ks z?!51hW!EzmSnquNoJmz_ngW5 z)H%(ug(a2cs(XLG-**eTX@X*o2S0WZ=l$E=sFX$5txto1rAs2z$`FlhYw(JSx~Qe? zgH4Tc&x9mo3y^aONsHp}Fn50WTCV!WQ?TEHC2L^wRz@<4i0^~ux;7ncO>Exv8lSvl zH%IlH$SogRK`FT%(I$9R0Z~az?qo)shMO_C^O94z>I)C?#NKY6`0id%l8;>Uc7zKx zLQq8D_%&5P{oz#m|Hu(sctHilp%s41>&eEkzY3XXCR!DkQcULD|3ya-~z_fCt(|J1LZIp#z&rs6u zBz@Rx7%VG6!M15lL~z|CdtLZ{@3?~xUjK0{OYr@#{*Z0={*0wvt;A8x<|ec-4TIB9 zJd3Mu{5YTco4+NUDH2d6mLw7k4UJ(X^oF$Vj0<_~iGNbe22*_rD1V!_vk!s-=~Fbk5|-)zaAFD~SQW~a)%_nVzr z*QE|YSOm!-AQIvJjjw`gfmPjvg^Np$3A-DmK)OTx#l?ql-nmE8(-vaS_HkbN$E#^6 zDW=A@Gn44%?q>(Jg)^{zbte!1`XPwc!KlTzeq}@RCfG3q*PO!MQ@da+gAkGz(l+gm z%Zhf%z`zbxwD;nT4ict7UrUTBV03hVrjAxt^{?Qujn7aATzv5b+<*T=)%7CL*3CrT zrA`RSs-j|5kj>FxG&1cJsyda5!<14U_#*ClpI!21`kl((q~71grj$k#roD>wxWY6A zQ%(WTr#NZhybgz4D7K&9fDER^JS{5VEp(wV-r(jn&6{*83(l{SUSBVKdVp!t7K=}cN*$5QI`g!ynjou_3X zg|#et9ngWH(3%~t6pZM^V z)YQ~6H#ZB^P{SNGz^SWN@!adr(bjefKYjWEEbOz1w!PAne9v_Gc?45%;Azu z57QJ+Ffx!q$|7N*5OJ-yu${VWH#DAS^tuM7mlr!b#G<$2^ikFZeyJc8jy>I(%5wu4bSN35+8qcF+1UBe@fJVLPutJbZi zU~AiIDMMsk-Q1hfqFzKOs=b`lhIVkxm0(8%)IR?5nsXQ%%Mefo1(hb3n+3BQ92?h1 z?=U5p5kTN1hj`!m4ScsJ$4hoUr1Ib>I{G3^4@=5unyxc8#>#ktXJ4~7$UiU zA9lVD%how9sg#Xj80_5n91$aoVHgC%Cb3wQfHE*+rsnt?2Kk8zvRMbEYB+G<0Eew! zO(K!Nb+rv}BGJ8IVsGtqK`X2u8WzFNIT6c1$kT0Dgl)wDh1?C#@%6RrG=DnqP9)5 zatR7>l*^P|!xRo-KbNCc#wpk~-9k}x6^@KE)#Z>Jh!YdgVWl9loX5A%^7Q600ut75 zSj#D)AeNn{jy$frk8&bJM^iuL;V}l2+vs0+CWQK{XLX|5h6;_V<|@bCZfC` zFs|-UdUq8XU)ZpSKWchZ2h0dnb$+VA=8Fnip&Oby^e~_-1oc*&-;L%$#GtvGf|4{O z*5J8u#!;+J#F-dQa}2`_r7h|$D2=5sM4Vt-gufqi`Kw#@fa!75U%rikfFC|R1)~j+ z-N;w};ZkzX|A?=D{|PwjRId8bi#&7rDn{K=u#TWKI)oebXlgo|1N(QerlSSdb;#u$ z%F@KZAnRoPte+@tJxg$1mov{igS=ftDVVg=)cI5OG28ZOion4G#9}e_j87sP%|#;Z zg_Mrz1t0T5N0x<6rEX*l0*<221jly+Q#ec`7NI2-vH83=zfmph0}J|%%Gc9=F;YcO z-f#|{ubnX7&_FG0u7m+)rPH2UTAKA_+*3qjt$;%@n?5$$N@&-<9L?JB~2=n!WiZ@%(5+y2kbRCO12HJ}(D$s-;o zDCUSaCFtmAVLUgA5Oa);4YOxxFEzgDil7cv_NbWyQB%Wl>kemRU?&InW$0_~Vat|n zyyJ>fiA3-V00Dbm;;A2>&Iw&J%y1ZWZYk&ORHn4Gw~)oO&?w&G*u(Tx#Vs zH>PUgVS`^h`3fI7wU-ZlZwL20v<;SYYx>mweF)JEXrqcheu}LYH7R{vO%yUk!ifZt zNQ8Vo&zjY%Q6OW<5R`=?uM`0xi717e+(xSvp;1Q3|9>#u4=CSBPiRNc z2+(Xnol4STX*F-GyBpiKQOadxV0+bpZ+L;mg+ua?@X0MLbQ3|+6`Etr9-}N01QF!1 zQ45?Mh4|BJTK-Uz{8j^|g(e#_cton7j{;9s5evgG@HjMh(Wnk(!iG^D)Rc|IT967Y zEEqD07>0gL&!bfEC>t96NEZs!`%x8nuTWk41C_y*v3OWz7{0y)qsjvC@Cb$t0+Sx~ zhC#_I=v)@hBU{K}8dAGGdQejaBNRq?9_d1X+S)KT-uM@|u8Zs1v{-TfI;=rT-7tV4 zqiPTs*uw+ddhI!U=Jw5y3xP;;#`;F~?;1deI6Z94xfl&v!G?`4E zoS~s-(qcGDJX?m;nlQ-sh<4fT&s5rJxk5{uM>s61 z#mKDVFk`^z!57H7E0`4HjO^G%D&?@>X(TKHc+Ng%XJ?t5oFoxzWh^&AEEZ*AB1NMa z1sr0HE1AgU+4%HUgxF6Yx`Ch!k}ixfJL{2gCJ8vTRZ+C(DaNun3O=F|F-%%pTaYry z%{Sk|WgqwewyniLG2iJ%2vN0etni8vnp<4Wq8}-RpD5qN z&mJmp^EZD79m87G*aD0gKn)M>9)NuZAl$6G?6AqF4s7L)Z+@PcJnY%Nn}&Fh*+_^) z*Lr4v<}Q~x+dzmQeNA1|N*EsAMUw(cDYhkDX5?PtT^6o&6dN-cR(3_OGA<26!w4%u zvy_Y_cM?uCG27I|z}Of~%iAdC)6~0hnxrCS+l-`>v{-_GvI)l%jD#Y@zw{J5nc=SQ zzlV->eVlgHBan-NnFFsGez}=1oxh$hpV5Imu$kI*>-q8Kai03&bF5GF^U*8MoqVFoO4W&kDl6zqxSLr&z{YFzj%}{zwaVCBPD9$mvHsD7qa~CvTPj9F!Lc;zNVko zHx-%9DfXofveus_dVnEYs1YsHVo<`t9vQ&0;%wUVbCUZM`YS!u5EBq9(=M1k#j9Q(_2{!NEax z@7hI2XCKWS&5Vqse4`JoeQPvLa=9Dj?^Oe9lA@H5UTq@3$W#RhNOF<&h#*s%J$-#Ylbr5MJf>Jda@vRN%Yp`5`nliI< zbF}pwMpIKardZ0Jdw$1>Ju7*2=QdWXIFY8NIjzUYHM2~%feU#B%~%Kl$0)&zqoZ8& zmmlHr9rr*K5INd2C5kFfDALb6qXix^OZ;+Qo)4U3kzzkYUA}t#Y25gQUxBpz)nVbf zw3z;NXk)TiWUlv^|L1dGqNlsZ4{wFAzmFU^aDY#J@h>>IZf?GaC=nE0o1%;_`aEY2DUxceQL?U!v=Zzc-l=IVu1Re?NX|X5$b$Zl zH30b2qk7E;J-$)9qK#FA5QHjszo88XI{Md8%#KsW^BV~74UI_N58*BwfM)=@*_ig% z>c+;HKN#}YgRnu_)0&d9p%EEl(eu4(_#;5RP*{MPdw8DjIA(a%dj3$p4}SLl^h&M$9+!4wbv-RE&KV+(TlbR9dDP7{-hT_OLNqxkP! zXTe$lQU>4D&pS}kMYeY95`rLdUoy{;i!{O;_2aMFbt{PafGH<1U!$NmjgWZ zOd8A$2H3tkO?&SQ8Se#V%}&}IHTST!wV(0v@#+Ks&;nH7g0v+TWnw~WY6^u(D&GDT zF=KmM6Uq-)DvLQHzRP>%F)2g1Awj96h(tmtWf5zOFzf09WzJTl(`j0}n%F-!#@kM5 zW8FI>wLNpJJ?;#CeD`m`P$1@X0&hngl%TmI&Xkb+uNzMxpU*Ruw(0C|BM=HPR201P z`kymwH#6OAf#=d0)s~jAc#w1ZoA|_rK4$a7^ocGeLm}?kHOvjacm%8!VCA^u#3nwx zypwExCjn)!WcfNi_AmSS(Wb2sm0%rY(}z!>R>0KIW)g`w4bq||6hw_3V1|BkSj?%K?mZKtqq-D;xWdm0|gfSKTT&y92QGrs|M zsTPH%(lC;TXcwn^?Lnr#avls1FKSXM)T|kwf>-w@Lcj_|k3UdI;p*8QCpI(L72(u- z_ptrpBH-}RlMCE_-RUF;cF{nB^SdIP{h6~7`BAdNHH;^^=nf6RD`S8nh2Wold>fy; z;M=@1`Z`$z&p*G7*plUJ-9JLxl1_fVc@Lpzl-5`cO=gTc@4TDd_9a|;>3jLfPyU%` zH0n>f(}aaZ09AEzvLcdMDPVasV~-4Cb?E#fl=qgdFab{?m|LVYh;vH z(V-dCnuwYFCJti8Vwk2D=dWJ9j@`R=vw!D7+WR``=s22L$6?4h$k6yW5yPORwH4(} z^1{Z=9JhWwYu2n`aBxHm>H+1|&=3x5?zqsJ6d@$DR*6~!wZb1c`-1d}^|hWJx<0+v zT7)Kt7iqrUSQs8Ev@BPV6zzP7#D8r+!^KBkVlqK8IfQN7G&e^{r_&4%kFjix*8a?? zA_RhjO+8^R6eijH>Z{BE1N(-VNac8X|0dpb-P;jC#jNY-%Cjd({A&-w@f)-oW;z3D z8$=DP+{5SIUdsw0Amzf~R`PA{CPf<&;GxGhf#~NES2GB{`hg?p`_SPuOSrK;0VzGO zt9z3Id0{@to1rN>4+D1Ye2FKYe3Xw|c_kmb_G{SP9x>f>)m3 z$Sc2lmCLTWoRikSgL)a^m~{y{;{AN|qo1VabjkV^Yj9ncefzd?|35v**Z%qz!XnP{ zzJ5X_c;dc)C6QP~RED_ps=IlPZV+jGeWV1RxzlFLZRdkhb4z1vN@mUF2qL8zC)`MNGyVh1s!$V%7l))pe~7&$mRcSi>6x zjRh9#o&kpEBN5ui-kmJ?*2F=g%`r`>FK9Q|P)NL?{qej4C4X7f)G}ic&9~lHCsoiL z!_W+XU|0`|48PH-Hw?-?J$F%@)@=h<&vi)V$XLohM?JW5zdX;GsT=dEAHvY(v5>Mj@?8{qi< zCSLu`%@}cTi^EI{0j{FOl3dY0$B94tUlde{xpb1KC7BX1VcYa2`Znj7-cm3}dFqZ!S?Lae)y-Fbwx4hPY=F1l z{S+^(e>Xgx0W;2pYbE#XO#(*)E^Cg@vgt!dF`7Aw!#;Bl?6#lym*P|X$*RoYh>ZIu~7ht|y~rKitArxptV^=?-%tx}U7T^%Pk^QT+v6o}IJb#U{`x7lKQIduE`Raq!@2RCP8i#V(N`vw zkJIqJ=V4-$M;U1_yUna{_9mK-o5RLQtm!fs$f< zkHxdEY{96VtD+_qRHY)OuY?NL0W-!N+7@`8>IFJ{u^vxTkbF0)fP#9{tcoBFQQDz-I+;}(mVknwId2AF znkE^iqERuKm^er*7DGytY&MH*46|(6GNREanb8!HmKH`v1~E;ORNpbxx0{>NOVA-RAGpiY7+*h)#F6MQu~-{{9s_{`kYJUcL-3 zII{o%AOJ~3K~$QHKYb?kwR!`bo}Hmk&?Qwo9OhTQ{ViV}+sP5@Pvl+apU>bkFVWEy z_wQw?ow6`tWC(uqFVK?vUzn}M0(eSA1Fs#WG9CzG0jZ(QTNQ-(o$EuDF zLfs(_+9|>Urke%9UO}ik#0Y7cm?JEqzAHq=EZ|6&6lu!V9FFu@e!)7Lms&I}k5D5$ zJS8~m$_qID%%fR$<@*_4nt)dgIAR6t9fI~X2=)<^A>2HE9@l^Gkx^7x3$w1xtkN!5 zl}2`FTD!)Tg$}M&O6NPx`e=8ZsG#Q+^OJdMs&=I_2`EKby38n>m}TL*dhlbq<{ubj z{VAd;>P5i_Sft>1Aibm zpDz>b>!Xi~Yhw*lUIEiIX^XYuI1bA5s)K4Rk=4(seXA+dx+DVIc|iL|Q#m!O-* zL=cv74%%tGX1Y0wLSPDuNg=2eim9YxR@kiWvPcbV!-#h?Yww_$BKfq9%>gWHC3V1L zGDDqkm_<@2EM|a|?UKeuNXcX}O#?0kDVesT^kUJX(gcNKDwAPW*-W{D`nY7$wuvbV z(@itQK9o|d>FQ(e@EEl|D=LU0plo7N;GoEB0@;6^m|ppAUscyHpZWzJK{rZdc^^*< zkMYj$Jq=}}s( zW@hlX@iSlG*T4QX&u-boaVwS*Z;n$Ru@-Ga0j2q-+EvEpo_ii-)61_g>p0ls6SVhr z`hD_2_Ki5yH-_0ofyUMtJDdSJOz7zhGBAL@p~n~;I7mxtD;dYp0@$p>ZnHqAG8o^L zMaCMjy)1>novdBEl8Fh2!&;05zSt(FSrNMmP#%fiUXp{mX>X5X7y)j(?Yj&Q57QBk z`(jVGTBM1p`tE-SfB6Mcwnk~9GKkgK#JQ)R&cuX6+%QQ^ zj1XxNeCOVK$*GdIqjX*F`SKDViDmVW6wA5lwk_~_o`bvh^5Q$-y&LAZ;p$%jEBV0N z_Hgq}r_=TI$3UFOwSWBzAHCp0zWihslm#C-oTrZRI5`sG?9V>PBYW3!)(zh$_nl8r z$P7>?Br)H{a?{IG5bcMh2Uxp2%I3{6NJZg<22KXpKFh(?+qm^TYxvd!V<_9@o@XZ^ z`zRxSfmM*9q=?E<@dd z&?Rk8tg6UJfW>(d71PPOLzd`6MfVjXChR+1RQ@TYh@kn?HNK5&*`F#0T$}#BTG-GJ zqs^T0{@-!i=TG3s^+BdeDbD)bLm;n!1Gn*|+plJ0y2MX^Jgx&OkF@BH_wu>l4$@of zWnbSYpI#TFsb@c#o|T++!vmCVyA-brF8=H@kgeg23)g7c#_hj=APknakxVY3jss*} zo2+Z_TE>8I2g{B*i{_I=x))E z6|)Y%dGJ9Bg)y$W_FC@0=RP_*I%x0fBYkiJwMu4B$q3t2>a-JC7d=aWR>P51WcuE;&F>m$l~$GpWv*s zPGj$Dd-(MA*RyWbVb~J~S-oKcjb;mzj>F28OS$%wH}L3h?&I}+TloAJzC!=1Q+Vu= zf8%}EpF^MoVWi$>b2eAJXE~RyIfMJ3ALPgPKM!6Gj*ZjT7h*ayhP0FH`@!k-fAr_D zC(cV>*r?5Bnv;;TIV>KBe4c_7>{qZX6oJ>qfHX=~G?(*P7nLSXQ-sA^6p!;7y5{C6 z+qP{(DVHPrS1^&!^V-WV^YY8j^DetYNEw7>h_Db8b1*)X=9SI6=xaP|HnyHv2tJkMM zkn#88I#`f#0w_TqZ4upUS&XVQQbITd zzUbQ%j0}%}(LprYLLCzXyfCVuGwo`;c~r%n^s1k5xr(f4YS*++84DMj>hLNUHt{@% zQbDs^8iYy4aR_9!&P1cBg{pOZ*-w$LzTRxjqE<`*<=Q!aFk&)0TlAgsbfaU|#wbz1 zqeQ&{wY9Y@S+Sg?XY%_;U*(94-$f_{yN1%VNs9=QbUK4&g_yQ&4icp=4iP&^9To-G zrq;4J;Ofl5GKx7@P)bN9TpNi=REF3;wv8p0#R1WT9`z|Axc)##F_m^{k`^eBf>O*V zmtM=FUMb4TCN3onN{~SDG-*-^K@ScMb`53v{dLwR=%%p|C@BfqE{($CfY10H-8Dto zlH^^NT3_=OP>QG&IKY(puWVF=qK>GaO6^i_HTi*1&=Be7m3`x!eElnMAPUVfLehu%b-Is{Ga{oH!%w^+KgpUKfQ zXWZ~HvaZWR_x*-sGL4jyT+SsLmE>|Zra4Ew6{VmQhG8=0I0VC5M7nf!2g$({hJadc zl1QPzNyNUa{cu;&}x~K{KVN5g7)_I>L&F1>#wt9 z$r3!zp}D!49XnpkM82HzWgP={`J45SoEl^4b#;Xqg0sWzWZ(i*Wwd5-^_(a zpT~1|J&2dyhp^UbhZ(0|8Drm>ziH~>#bY1nbSK7#`GVzSZ zB|rZAAMsaT{2bHe65F@$LQ0E(|D5t6W(h(F@=8xkB4}hyT9S#hLI?{>z>cq+#L8>F z4Q4YRzk3kAUxH`^avk8@$Iq`@O{^`#%Ikln!`4VZO7QWoyrgpxD8ufbbH?4*@$(zs z%Ndt_2ckz4yk?8$`4yeNXeLMvSZg1B&vzufrL>K-mn`ClZ@y2MUw8O4(#4ddtWD}DcH7c7wgxrC*x#EPH3ctfr)DD8YSkFuqy^36>+^T{A85^R`Bzi!v6F-=qg|D zGM{PWDi>*4)S_*6+oY%#?6oq^42ptlQ>PR{Kmm(c6v3ciI-jO3Ciul&w_}=utFF3+ zBUX1&^YvSacK6fTy^>@yP2Y+Y%!R)}u4wRsFMNeBfA;fy{Q4WY<-sTU(Z*fec5NSd zk$~tNOek)-2n6i2OcfVqfm}A-6V|a1vR_aRC(XwnwzqMhtQ8a!BP3a#B{hT0p6LYf771(45S?0c{c0HwY*PSu)9mT=J?0oKY}4Xg)fNxA`&hOV$$a?4T@Q z0uOs~62s8e>vMBZTQmPYWd%jYK?DK|+Vvpgb_&X117uUx>nh`9^a09X&89&y~r~ju8$Uc!e?eH z7>agANc*girQqtkoRo4AQdY0og0d+9O+p(r<%A-Kpc!a(0V)V#viiHvNJ-FD1VO(y zijef~0J76cz{OHd(wk^cHn`gP={$De>ECnP9shtE^iHyuaRQMjxaK+VEvt`Q` zmLz&8D8<&TTd=HVpHD9M#V>x!x#ylsdwZO%Tes5F(?e&oH;H7 zEi-{K4TdD|C)Z;bkv=06Hto&^Ur1~okl7BS3c{k^ZE9zx3X&GN)8-I^2j3(^3W4cP*YPwixnkeS-k%8 zFuluLIsg3g__t?n=cV8Op0~e!4FEUY^w-o@d6Nct&tqUfXDk z7ArxGo!8Ces&1W5nm1U{6vwtpYzCkQatAnWMJ-vSpr;+g3L3xrD!={8@tpI$2Vf!$ zl%S~zaz}#=mt1=m=QhWQZ67DJx)pNGkaL+#X6SEgz;(wc`x7p!l;`62pUS^J5ax{Q z9_HBd*TbrQ7){gi#Rs9M4bnT{fDPsWetXF&H23xLgONvh>=B1A8clq0gUNG$cLGE1 zDnzl!Zn>O`Z-0?(TZ$ltxZ=2u>f);Wn`fa&xAJ)1zXNX9O6ezg>&@^z@4KAFM1oAF zh!C<$8K?mIKn1^`HRS~p(12f<#pCfR&))X)BVzS#jDz5k_|GgxyIttUQ9(_w6Ip*6KHXn(~D(sH@VLbmqyVnj;o9 z5kB%Up37mFCWm))@Yu$eb^G8WD3t(4PZgL_^Vuk6p&N*@u~;ncDen!%(8A(iN;y8l zV$k5PBV|Kptr(v126tjD_lW*rQ}(I|=X-k^i2CeCA2&mm9=Y4njO!!YP-Zei>0?W|jOH~|l8O_L={meAMH zTh)$Ck9h_X2DJq5|V;aWR)TwPf&DSgn#eEq$KOwNGY_PIp~}f*Yyh?{Vybh4kGj) z3*n-GeBR~gQ_tjQ>(;S9Im8PapXbMS-%r|8G)nxf!nVd<8k-9);BOeLo|cU>#1k9~#hd*Ca#Y~hx5 z%ZbVaH5Wb(GR|wiIG$DR5e(4{uRjRFD7Z zWO9gj+^VASCTV)4OG)IgZG#%OnWPP6;V>tYxUS8%ZQGDnU&f^$`xpcJb`g>mM<{so z(cfd+dHVa8Gm_3TrL&{SDVlDoWM!v zz8fLt2uX{V|Ne(8Yl$*r!{;tJllR<|h2}LNYz{lcLkLA2iIFyFl|cq{`S^d2|DPX~ zL55ypB}91&7;lbsEe93n%Z;Uh_?d*&x2epM{jS3pWJR#`QoN&($&>fr4<-r zj*R2rI1Wu_jE>G0OjEmk9e4b3I%C04lrA|6JXqPcf`)?w7=~HBcudozv3D8SY|fvu z!j#ajn?+za4)q8UEm|B~TU)cpic?Ap>87ZYg1%-8JLghw2y7wfZckuE;_ON$IqImR z2n)!%SMd)-Tyse-2o_IJ%-uo(pxdf#5!st%e z3wTk&Eji9SvlAmfMDoUCNPKq`UN<=BZBIZ)GqjYr>*gNvB1xo2kiTaO&h_gt*R@eV z^78g^ZNb^wOmZyA5yc>$5ZFSJS2m4ql3OlVPGem(L@3wYrP zFuM8PM~~$AzDA~j_g}l7yB;3kTc7?Vmp^$EN5}*8VKC*U`O5DOvhC>-q|zLFSr;cJ zvSi(6=3RB(IQ|MBLajLThAI18=NVwu53GF0JI?eo3#8A%ofp&Bsl|&^5JdSM@j}wO(CCJrrnPA zmkhc?K{C5G6OTtw*!qG{?;&(Eq&%2LYhtF9&R0pLY@)Fk&%N{#Pe1)QZEc-QPEHaJ zH_{esW!<_X$>nl9wdolQ!=SmPh5ds%oVT^Lm25Uk$ny@Fyb4NwdPG1$ou3sIkH?v| zwS95LIK_2c=4^e>;HRutn)Z=&nwX4NEv;vKO4q)91FY)r(`m(N8_!CBn5QI{eG26a z+7`T5B$*L<7*i`O;(dM0#p87LuVHZKfaabnMIA1)rowe{g!2v;zvD#q3=c8YwT?EW z=t)GVcU{VEiCWoCL58&DFp_DjL@5*^DqGp}?2|n7jnnA5;%?x0&i>*a?)uJ3Z2?L* zhu{2jZawZyK6B?IkWF&k4X5(U@7>BLZu~ss*=fT4E7)DJ0(|6t4*S3*OwW}V9?me8 zPW##(s-IsDSLZpoH3VHnlhp=xk+Se8sZpIF0##b+vh^E$jhDo695PB#lg?;;S41)~ zF@Z1y%hs<4*Ci+=%hs&n3xD_by!Vb-Q zTC8TWu0u>#M9ZFb#Ai^g~}ww(iD(o-~~Z5+p4(D@p8UXGTQ z|IOZ+$2W4;_y29l&)9lK)=1XaYx&S-?cJ=C?1pRtxo<))ZW4~B94#qr(l&+C{s_<( z3gvDK6evfzN+CcXG$a9%a3qj}oSRMd$e#ADE!&dik)@F}BYPfM`u#B@+1}j%{hjUa zhhDFJt?if2(aiIFKi}`?=ta{+AZqf0=MC&E(a?1t!038{v8gFEtwhbK(A(R?Pae1* z8g(|Nhl#`!EISTDX(STs2nQi;&4XBTe9mf@E?7j-8}C7>UW5>68ca>)85roHR4UQa zvyPoRchW5-^RCN={`D-DEW*0r;6&E%&d*s$X|R9BLQP~zrBXb(>nY~5GfYp<1%?Cd zT=l{$x$VneXnj$cOon~?_W9sV1IO_@qZeLyHh0|dUG#7mFXS%>iS8(c$~@U@juSR- zrK?AhKQxKzH)*fdNQ!niYnWT#cpc2|hJSb%cGjThbdUvx*3Yr$@BWlB4bHgWMsg1D z(R*O#VgI|G+XeB{dBa~nOa6!3*!c%3PI%qzeCZv6FI_a{i|&8A5A;(ZZxK?RbRcL5 zgN*H>nFb+yg0}H-ZoNLn{u|!PFMhg*<-Iwcn%Tu2amke{L>vQFL~y|2}6;JWiLH@@X41qi+w=@?A(I)W(=g}=#PvqfXoa9kLz2&C zF-@P=l}--@=cun?5pI^K5a>b$*2Id22*mFAw(XsPhkp&l^nTyUGo%z-(#gQm*!6=5 zM>bOzg1oJm7m|T9w<5EGNbGCr0eq{catvzVTGXQ`?%j)&GH}QNh*K<<*tKh%RJV>M zqOH_XuSwMkZl%%`@pyuyu2T?#+kbRti;sA4a*X!*ZZ-`K`A!ju1Ph*rqsf->ggdJSkU>dHa+kE6JU*OHx{}I(7`Pqp1plo_NPdpywgw%S3 z5F9#m$p75S3RMS16=!l9fHTiLlbM1=SV4b(itWl}3B}~(6zt3K(T8v49pW(_lO6m+ zPng?2e?MSw^*J%RVjf2dHTM7D#~43+1a^L(ogX=w{^STrE}-qAzk-1`@VRg2dCxV= zeE1D9-u0;r{9-*g8Au2a6QH$`9y$TbvgkETgzJl9{b0BhstPG=t~oEs$WbVCDGjpO zESooPVPB!Zq5{*D*p{E3Y#0W47gDLsWb6Wlk)i`=Hw?mob<_3cG{Rduaaon6a=g5qUq^FjPD8p@y}!=DQh7;v zDCOY=pHtJcfWid}p0A5qP@WG~j)RdF@h3+<5Ly91{)DGNE}*c+NRyfjMD(tWlglE6Bq9XUR+i11hnXJF_|pX3HC*_r5Yz4k+PvX~vLJkV>VnEZ@ezX%Nt5n)D)Y z>>7v$da9jy0b=A7mTkXb8?k;tIz2*I3P!h`2}*II5M**WzW8t7BAd-YN)Qt|S<9kW za@e@>WZrcBjUXh;N>M13894c5uD|gwab2j3b{0!E<$RuVuDXyn-*iK3iCk3h{*Qi~ z4VzD)47~Wf^SJ4C1AOlCO}M!Nt}7TGHmO##{4!VNq~`$nzrFqc1Av5rNINVGuT_L5 zr9n;eT?eYg5|>?e6+ivy-JEvP8B94v7J){i&Qcvzy^gbLQE&)>a;P^NI5;#~-T33* zJUrUGHfRe0bs7zT25q#hee82=7b^-D|K6(=Ee#s9X(7t9MNWI=^AIRZvmbgx@Yo~_ zn9oW3TKW&sztnH|ch%D59t~{%^8prd)PzWY2(^A+15||Y3zdpe2-n3hl78xCk6>V^ zkG3*+;|03y9H!dAN6(D#(QD4&$(+GE|M3U>?8i1ZHU9XEd*H}Z?D@&>fhS>)#d1~S zz|NhFY}^>Qwv+-#33w@C%*=4s1s5`vogu7CcJ6!<*H!4c zK-Ufa?OWgWKVGm|9-5pb8BH)aG)$Ke2wi8snXv46#N$47WI-varDE%3Yo3C&$~>{& z&9pm#Eu`a5EOcGqIL*uj-pgn%S*!WMYD_)Y-IgBT>;Hq+Gsx$4~j@H*X^>4gUE{U*f_GFJ$+V zj}S8q=5qyxhGNXjSj6KAPCxl%zW0N>IJ_^*?YG~~nWvu0f^w)i(Azu6;qk+0T7}zg zyMr#%1QZ7*4pDDq8}z^ z9?yf?2!=*~Qj*V9NhV`(?Mq;9jQbDW&kea3aMraiWY4v*aQ6`^u@W5@pT-5({Qx|R z(b3D9&+bPlpNqcaTGV6@P9#FQy$aroywqJ*pys{k}(QY zX%{oJXDs?mk8xM07>Up^G=hgmwJMN(+bHeNt)XHazcZnJ^~J9U(%B`J<+~dRA()-a z(P_j`K$I0xXw%`XzGkW-SAiS1m9w*d|8DxyDHdFXW?Kvyk_F49-L*+egHm>u6eW_T zNx`yM4g`wJ3L-)h0@`egq%^76Ig&yU$`#m>PE(q+h^1hkrRXApZP$>d0Rfd{325(2 z(pA$rlARVY23aU6PkdspaAq8akF3Q!2`xL~Bd!tU}%{4Jp2hj=w#doef; z9$pJvEDEm$R_fwcPw1P@F-L=sd!Uk)Tv8(xCymfWSt$>e^K7MKqBNXh(jyU@Da&Z~2)ShGDRE z>lT(>AH;Xc2n$vY!;nbn1K_S?A9lG+dT5wTCWm2~{)Eg{3=IuYt(I|Jmqb(7;;O(Y zP6h&L-=w0fd>6fhl>SyHAeYS|rOCVty@o%fbS=e@;ZH)!=zx1v2A3Oq$!vvTXdkYtZYg`5OpQJ*j$h*QBW>%TcfN-2uX{V4j17(lV|%} zLK%y!M4-4d9btBI2G?z1+cvIS#Wa(xHK{vgvg|72S(lV*!;=nkv39Qe z^iMc=XcLrdhWZcjC+q8Yp2Pd!|6#7Z_F6in!9uyr!w)~s^z<|*q>?PVRT8GjtXg3o zAPp7@Rk~sZU;XB%(W6lg@7qs0y%ptFS$6$(;;!57;LSJONHF5zmT!HF4}bXYP%=(f zntWw@2N>sbqrI1duTCJPpqiPaM=8!tZK3F9ep{{oe|!@{N2~f9X;=jnv(xYmIfCm! z(*$8%=jy9p#=ZC6Lw(t!K?6%JXuxGhAzxf}T?V&&&!eyj(- z_#lP0P;mD;&GuxgNg4d0hr=AVTNJFlnx-*h&l5>>^YyQPgMa+c2Yt=7<3ex$aqZuh ze#1%0|1N6Ze-5xBe&z9K8ndjSeuaWR3Lyx&_+$P}r{k5Y^jldxOk8sdT5=0+b&|}E z`-z(=ZvD{NRQ|%`U&m(o+wUI$=MY)f1vLR;j;>^br=NM66HgswVKPgXX|R6%dOBhe zUOc*$BiTuAyXA+$8*_R1;rqGx;`4as!JpCJ-_M?>pJia6hkb|lP;)#Ii3FQQhgsL# zi#0um<5Z~TX3>CUr^sBzX<5)E;=Kqx!Mx)zFfc$!!GYXPAD*F)ej)d*ILnV|{%Ta|YQ$m3Q294j+HulW@vQxaOappz*IKQki=cZd-;# z58`H%;bE6q*Mf;E9BE_28SOl?FV5xfy@m5$zLke=I+Y~}pZ@tQls1CePEQOVjcZv5 zp%_TUSgsjd_JIdEXh<+(pxPl@@(Uv2fSaY6=d;Om`S2y3oPPRdKCokny@WU?*1=M_ z#_0ZecJ(EgnUur}724G_bFmSUoCdlmt{9de_suWVFN8hih#pzHhuOl=+D6TGo{20$`p^&id>n}8MZ0KYs+A)Br1C0@3k}l+NHil^h2T4-dhaXPt%A7jMoLLM5+hozQKp@Gdk~~rtJ2*LowA)hxq|N+ zBLpSaVhM$o8YLTvASDds_A#YuNFzl(nWQ6@qzn|RHI~t6^u?$FOXV6Vp{Pko&b8?< zN11R1C#WoCB z!YLG{k1#fUm=|AqDQ~;+2IBES-=N0Hlhk!wP3Qc}UdB*wFOK6-@jR}+`YN9I>5nKl zE_20gaLKFTwja}Z{Y%J~%k-!?Vd0UtbN>&fwEw?(J9>>@`d?L!iq+j76|8mszPRKC za%epP$~PI&!-9H5$BafP2WwAfK(kt{Pg%sb6lS%th_{ydb@X1)6w^29W18lh4|T4h zeXahP)@wXBtyonm^b91ZRG?CsRFD+iRZIr+L@jN8f<5V@EA2gde+u+m}ynu)Adyu*i ztf!yt+qX0CIP~w*V+%02+I?KSg^~V{Cewfq`Bo zCXNt~_fm9SBFbT?*9csJJj&J)gsm}EDh1SrINiG7dw1Q%&$n-#;Te?jeV z9%IYdeB@If*jKfrZuif$W8!=zJLSY;O_(;WQCJ~;O*K!=$zPy&9r%eUbzY5w0&h;h&v<9mjO zRXEH)etkdmjPfJL0?qeiM>`B&4;``D_j$1g4o}!LsQzWGjcrr(*fK7ZnKJ)v8HElS*ZpJ}@y1gJoAxQGzxj#guXp zN+DAwo>ClE7X3zwBUTnYl?plxeqfmt0wn~lOi@u5728HigP375YuE4$Q0X)^E6ad6 z!lLcsN1zh)=KT64BP?)pYC%t@+x0*Q}=FnDV?egNvpZe+iEcrLEamn)b!bjk1*@uU4G8 zR@}r^Ku71Q&mY!x|9e%Q50J##DUecYkG*2WRZJ<51w57=p9d}=a8dIZ9319>2OcG# z&vWLPXYxEevPWjf=kv7d32KhR##1&CQf-tHGSUbZPC}ddEF{^zAqBiO+qGO(P?G|FJ*Lel)wLnf1olw$LGHCWiGnnh3t6b3H0l}<8!^^rl08S z+MsOcmyjM}@um~V?jHx?+h{K-MLike1#kTqc*df7$M55zlS{_9=+&Qu^=E(^&-gpt+uEjb5b!&`4nZ`C#WNnKLN)QQvSeZGZ)ToOsoMi9k=NN1=Y)&2S zr0u=`4!;;<>3e^~_+%T8JoSApy8Ol1_({7aL}MQecM^=+rN)&F2}yT zV;IKctqJVK*I&c;epKYG@A@jQ|L_ek?ZSx$=k%7CxaTf*Rw`IiQ$!L8zWC`cut?Jg z!66#e0Y#Q#*BJ&X&SfPb{iujCow+0A5GIpMgC$o_x~0J{FkF^ zso&UM`PX;w6LS}q6kN^?6?%15|2OnAYmcs>yBatHpQK*sJ@ko-_X&5 z09_G{QmA;V)^_OhR$?=5Sm{6ef9^ZXybssChPx^T_@1^)egxA+Y~M=|KO12dp2 zrVHb|^PTUcyb?bX}Khwy>s<2?f*>x9U5{*d-eyZt(a6kHX9haUe91 zpc6%1Yp{F&5x($&>$!9^%-p{Fx%Jz3^QxQvo-6+7A7R7kg!6~dMS^0n1kCWtt6$B5 z{ZEm}WEdSC0SY|!$nE^>z1Ohq?2CEY>E>Gx8tnMN6ZC5dpn|3ea-|YmPdo+X`CZS; zdj`-njZ&$^`t|+9dJIg{7b4e|vm@YEK(_{A6V`s<%$dOXM2*f_&wLE5X!*-2U0WrV~X-x*UA9V$+86_{?i>hV^HIljSAXUd|0y4KSC> z5mzpYF64vM=Ye*3?4Qr&tbgr*_xvGfCBFE;L(FG~iA_F*5Q-zB&Pi^PO8N)`BQeh0 z{CsZMz6<6gun{&s3!)!p#u%B|hjDS5r{W%{IWFioNu?UCoRsFp8d_ss<#RcsL29<^ zx`9oq8zd0B!FS^Zltq`YjI4BzO*0U`i`FE?r;4o*LOWW8s|du~KL5M}!LqBEGZZ7X zONTHi3yJR9Y(!!KW#QmiSx!i$$=fy|;gXPoW#xBig)k|)F7csu7IsgvS#6~#1v^cb zZlyRi8)t!2sZ!#APzVX9Mm!eBqi8Zh+1ST8J#?cO6cADtHPHZ}Q56OSB^dNo1K4(% zbb1Kew&*krmV;wcQi1{CzNe;HaGnRc1qoPmDlBUWLS7pp$Wie{k8LZ|D?CcV*RVu1 zokbv$7-F&Hp=k*mN3pC66uxMFE#7QyAW@cCoe&R;UTbv0f~p|USauX)U9jvZ^uVQ0 zsfw=$P!1?(Wno-1fm!+8J&Jp^tb>mE*3!mZjFTIqBi7a3L z(x*7}!~vvqee-@j4p{z$>$tvNW~K*@%=3D?%y(~I&#r>TNn$TOvD0aL_q{N462$v? z7C~MqQe}UCVxkR%4Jr%qvwXL%XEV&HDk>JC?3Sq0&$399#3f-_EKA8uUmvPaMRzUQ z3`I`r^tm-c%rGEFkaiEQyW~%r<0tXd8IwYjf)6&4h(u`<-`k|2_9H zv~h%UPCuJm^$@d@yGTfb7$x5G_BR8HOm335z4Knn&j7i(d7_ahF-@Zb5BsPo zdUHZk55)DM*2I`&Xvx0$iic}gNk+nistT{(ASR&Tz}aV?O2H{|WZx`((LS_pI50m+ zqcRW9-SqdK%ba1b!_ryL99_1{k~CNn4I)YsQYGp^t+=K^del_DV+~D8tpR}|s0~-@ zn$_k&;Bm?)rJu5WU~drvK?Jd{m&fb^L$X3V4!^kTPGWep<51J}Kw~19 z*na?Lu$O_s4Q$x3nQAGI<7D}(SHFb!zwNaElqd3>d&U+Xx&LV*PLWVtr%ULBL>u!? z$f%wBMT!kdF^NrAc?-gpWOt7<@xIq{##`^j(o&Ef zrE%>ByxJMG#h~O?>8#mw#Ud07Ctz7RVOd(WpbP5a*buTK*(UwT2Xj(NEXxiS_th4| zzE!bd7<3@0xbB+Hgx`68?osdYHnl!wkaKMe!$wM|;gVB|B@AMsA2%h@l+6G(btLn) zpy*aPAtey@7}AY%Fw>xK%hk*mYE+a(ni4Ug5W-?vm}s`mdBzsT>@r0Z1E~mg0Y}_6 z&JeJyBw8}Ybit&mKnR6q+ngd{I(XlP5o^)cKv4u%fOT*H03ZNKL_t*Q!Njry!Lq2e zbRl?(HqS$$g3i@SkzLpPDT5!rsnM-wArSvXj;9$?iQi~L?@&i?-hRP9FEqlMFY<2F z1deiO3qwU(+v(_ zShcmzo3O60(%yJ1dq;Qox>*j+Q~x!zfOZJW0yN!Y(W`JEU*tgkFq&A~)eA=xRMDt3 zUGNlCH4ikM2oSDR{LM`BH^g?)pj|cy3*|eNDZ$v-I9s-y!V*v^6zCmFa`xG0BZS~3 z7u?9>kIyn-j&kRncM=L|7{)sE0hrnTUD^oK2-Ugbq8G7!_YO*>8V@}1C|6#2r4RTu z8?NkQ{~IqLAq{$z0_C#l-=;bAsK;%OxD?7ZmeROGoX)jx+3s7MGX`Qir;AroB}b=i zG4q)>vr8l~MSmD znwk!}$Q2R^okgY4!h$=0d_VAfP%aUrXm@RT1k|XpXlGe6QbeUhxqk3q1iu*+Qi{0B zGN5$gVwh=n8Ap~F8s5Uhc$prcgDh3C8l0$A1&&zb^!eM{e*pN1qZv5rIg8V(P(e_! zLB*|6bbZ5@F4LdHt6*A?y+%1mPgY zKnOud`c8#w*&b_i-FyI|j;S4*ra&FQGAlIfrPce7Iu>ZGeIBu5it|4RxSI`kKcLYL z>fGjZ-EP%RMo`1r0lmC=4THio`v@ruT^cYq4RL=b>@s`SYE=9VunH1`tG=DckxA+T z{_>mK0geCm!eRdIrgJ#Bd!DVoe>a@Am0eFxLa)VHCmY=I*|%YhKSr@?LPA1bQp=VD zVXmKq>8cvbu0p1g2+^PpbeX#rs*6>~a^i`bc;>MuNG0MFi+K_W z9mjE*-?x+AYtLZ7?8LP^PJQ0RJp7D>s?4KGQ|#S4Mq67OTeqG;SQmsmIGmrRw>QD` zRGuCj*f7YhT@#etBI%RPXKLpR&yMXSOdGXHFr({8bnBQ5w+>t)5r?1vdBK)#EW3)& ze)daz;tZapus|+jcPW_i76Pu<%%=ASpf88j6<0W9hfXC8_l-4@{(;-h0n82 zONitqSX6Q9LQqFgLm+|>xMkO-OA1bvaAhjOJwM&YKYzT$yKZloX&#QY0CZ4aQy^=&t?(`7Q?nGuY$zaDWOhwA?C6c8vz0dj zb)&IjN3QlF-FN|OEA3`)$hb?Y#<-+nu< zeB~=irThtKd)1{Y7UOL<-iT#cfeuU&GYra`ZNB#T&vPW3<(g}Lhq@5H;hH8Om4YKK zV6$YqXh&r}9NQJvsCNq-r$Q%?h$qlhlqJ9^I>fXny}gpUrV;Xdt9?y_je~>K0}Yrp zou}?O{=_Dcpi=SB^#ooi?`xh6)2HPf93v_OajB>)hqCK3oJup}u2eu#A?Q$`lwTmN zlhEawlqcsIkR^ngfpLwBrPG}nq9I(WO0FuT)=tNNi&1_wXHQ3aHwV5>kw9o z0|yRpXljZ|r9wE|XidaJfempvSmSCQB%=wWl>FhJ-N-{f{61g)(m&JYY5eHlzr{Ol zyoN7-{dV+lI~pE!O`~WRF@m+GbIqQzYX1oA-H)b*t+uJJR6JbI2$h9ncuf>oOHSmDJ9vg zAIqVXA}j^__U+;3w_V4Zzp)(#mcg4t1r7W)K*b-=C}OcB#jyqdJL)wl<_a(~36A1V zFS!b}{~ueX67}NGV%XE)kqS zLi*GnyKJLSgq7Q(gf+kLg!F~g2`O2ZPWv5w8&h3-}1K$Ey zN`GVMF_M(+0u|*44;BmK^coSAnxW{{0%saYL_tUi%C=vKJ2FMcG}vbq=t4s`QY^YI zM=}LEjWo7!@hnBJVX}muQP3yT%qvC1jT2&ygki9Rq^kTRYQvB$ST;%t<}Jysm%zm6 z^XM2kon7S!NdY4fn8=NDF8!2+#eOwLBi6^*j!7;`N7??j7x9CAWeyD|v3HNNUiQ!- z4DxoInjB%%P&@OvOsiwkEHFEc3KKF79|$I-(aJpO5Q6z^wq;3N2`-psxZ0xaww@y_ z#To!~bk|}9z_2FWy&mMC+`22n*K0aUN^zA)v4~`{-KMv8n6o#Z#tV}*vT~G3R}n|C zStw@hF_!zb@y0t2^4^#CBC1u)>^{<|B;n*Jc@g1HzBSD=3a&jX!H2h`Ay>x6rJ`U{ zUz$v2lCU(GO`1fjE_E?Uqb%u*#mK7~o|F_2w7V`sw3Cq1|6Dd}GzsCr4XOz&&;ZBR zlr(^NQ=y@bKT@980xiT*I+IAVqxWkqhQ)LI>H&fQC0I}@NS|*~Vpbeml=5h3;;4;G z&x! z2>e5Qt=>`Hxw4n>^*5RZnujI?A+3S(JeD=Z@=--@H7Hu4>FnnE{-Qb%44(>r>s7^ZV)ROXB8g zM5V>8yXSesJHF@VLdExh0c;$CJC`Be4?&(yf})whFg!t_&M^rGeGxZ^wD;lzz; z&bs(KoI-(gGD&0eX54D6Wn7VrB`M`HzJ4t^#K`9B85kPk<*$8}PvsKAj|`9z-+`^9 zsJJ$Zctl&3*4pc!t~G)+N@FfF%OzJ`z_OzP?UrJDCd26HR#F2ppdh+vd4GZzPsCZm zp-bqf-ULf|sCf=T)7BJrng&n&>@nDM4(NW7+F`qBLuvAb7=>62NdYfANytd~AY4dF z$ssxoDD5Ao3ztaRMI<9c)aiJIHhQ;3sAE&gxG3atyS*!oqu;9a|7Wxc{@Q!=0=lvW zrPFB^EX%jYSBj)zlARn!$_TxNWLZeU67ty@me5H^0|J_~pB54ins#e9fIWM6a$x6n zLYhWQ(^`#@CP?wKoGL`RyID{+TSvFiWg6tNS)LtxmS>;c&1olZ!*v`wg+Nv75U#O^ z$D#+}@Y>JVa!w4UDT}{ylH#o~NNHPc@W7)#qfa(?{F$dXVM9NszThRk!=7?j#0%{9 zqqJ4J&{0G*(4vre>LDV^WnL+S3_xPwepXpE$!OLkM^8?k>-=uUB7}Zpu>K#rPLx{P zRQpvxc-eLR&lc!#3G&w5Aot3$EKD=js;`=%zaUVy%YfNOZ*MPBw)>Og0Q6XMb8CT$ zVfZ|`YPCwQVL;x3-V}+xWRT8lF^42+tj9A-f`adZ|1<#R+mF%UMas zNH;h;K?jE!PDrIm^!XNv<+6>+x^$UIMn{KRAELSNEU_X=j@f0ZRhN0!<)xRuh`aB( zn?*d5y3YRn2heq$fq_Ak8ssat{RC6YQ*&$_$D&NE%*;|1V8r^c z3I(FVrD0cDMj{MJn>2iTJrqkqv0&}OFiaYzU=G2IJ&BZpuyk2=Ej%S~U7NaT;M#sS zr6waRSPCT~L;^ZgRR~Z%SJk(^G*E`g`gVtT*~j|fK4RGH9iL>cGUzp+pS^SpUBcMz zIC~|PCqlo>F0$h?0=m4&=A?2K~hRgV}@9An1kbsxT!X@091tVFYJ!s z;%ff9Ze1@^Q`5Mv+d}`%i^-oh+O5YlsRn^WKFC$^J5`}o8)tI_+gwbJ=9@ObiV%X| z`PkF2>2xSf^0T=ezA3(> z89{4e;t3VJw(#>>R3QGOK{pzn7G(*KxYCX(Si-^QZ~;TB`#KfjK@ha4i#BQjh!3xF z!jn?A%m4&I`@TGsQmkLU9@97pCmZF3=f9FR-a|a9(O@3C;?dn5!Y(!lx52>hFhy6< ziQvH}p5$VAj=xD;g0FsjJN(^e`O!m9!+p;{sR!a|nENh2|HK<8Rg0)d57%8jNJtf# zV;QE~K$s+|Wg2RRqFW^*Yji4TGlto9_YTk#{NTM;^4Gf8$y(sn0SP};~7F~ zgyG~cn_u!PSehS=)KQT>9pMi}9 zFcKg#eC)DA_}7!V85_v{^+~}$ZvRDq^7j?7^P6j$B?(K7TD?M@5R7F;l-0I?0V_kZ z2$M|q6ESsSu_z-W1qua8Fsg%YG9z7tU+I&o9r8$+9WTE`QQ8E8T6LP?x^r$^vr~}L z_&A1PlF#S7yfQy8?|7Be;3&r)9wrtKGiKQ|wit}2O4xRZni@&1Y2a8n`~lTqu5s0* zWmY42Fj%Q^dENRw3DiuNXfOrIJ^R_XdkaesS^>CAE^4oiU!#B5&Dzg+JU$^J` zXFladLBs@CdVEF`v?RJ-%lL>xYt#affiS%D?4_i3jZ&ivEHh1wu9L|~RLd!j zFBId!pFPBVk8GeZ9tT|F@i$Z@MXnKCp62SFOM@f!xND_H=z zQX|wDXGR$OWm_+rrmXEUwQgzhKEORO`GMNtFWvR4T%H` zTNmP#N=z0cb(pvrA3+iK=xBlx4pYpI-5eGR!K8HX=?SJh4r)L;goL1&8KF_{M3^R1 zmTLCZ>XJ-mI{_(~5`y4tMh_4WP$wmpWf5*&$pG-jfl02o1snz0rJd%|W!Dy1%kD z%%8l}AwVnxM}uRUxUMz3OdEnve)6N7e$wfzKk+0EJ@in% zd)v+Q_6}g`rgB*lVs4`1UBj-cF@=VvrRH^c5A5D+LSRZ+r9B-;X#!k(ZsGt`yyyF> z^rX4(9ULg>^Egr(8WXPScul!;mXZ}s1DgXn#Iw&)uQ}xbm?`QGf=Tmv!~r)5Xw?m8 zs=Co>Xqt=b=2Un44K|7z*GHY(Kt-!mKfBNMF@=li9gDI@mYz;VdmUh_XjzIm+Y63d zfX{WQ$T_DR6fBtoW3CSk*EB~erce36Tm@g*2+auvQj7%HuhIL*D_N2)@l>WnQMYJ``Z**8Q&tQ_7ibykXs1!e zSs2qvjqF6kVtoIPgKDt~Z|1ZkFJx>Wixe?}i72+y%eLpYvby_ZN+myk***cr;ef^1 zT}M-gz`SBFJpU4p{@_r~NCY5i^MO^DaN0$;!IC&g0}+eTpMQyqPCJ~5OrCnv{mEWv{h{)#7_d4l%#7FKjE=a_Y?8Oo|o;_f|r4lE+2qpAogsdyU6 zztt@jnjokd?CMjDgs5RKlFJc^EF^2^i5g+@!5lTNa*?a^MkVuQSChCH!a&+KnnraW z132TvWB7AkKt6+0vWNQS%~ zV5cAsq}%!awSQsJw@%~o9c{#%ck_VRr)nJj%)hC^1ZrGQ{4 zQ=&EzqJp2W9-~I~Gcu9{!UUrUQjWunh!bWQS(e}zDnQrJ!GMWeo~RI>E^q!MdJarz z-WobSoiV)`=~^a+@@)Rg3zWlxbI!e(AKkNwL_-6Uo~BL|T_$Tich~t&D+f`) zYTVaPx@R54z-6YkmT}9abNO0MIN>B3n&WhC-AhqwXwfK<$RaeY54&WexkY>)NO4^k zciM)^w4#p-ovc(DSpg|QD7yV$Lj|)nMU4kq-e_`CZMaJL2D7lgu1$HfDU6hFK7D&V zKv6q%?L47NjVIFA4V|s8yuhwqy+{ddZA}L-hE&}z$z-xbIuhl_I3e?pa`WtCf zW=A&@>SWRcg+fUkxi0y`$OMPQx+!G~kk5c2_}LRftXSKC1r+omD}_ltesG7CPK6j> z{`z%%_Ug|7E{W!5B7p$0Sd0(9@1MEys!#H@FMkfd5V*){Avnv^Q`CYC-Q6pB>s!yq zFfQI>4)gY5^`5U1r8cS+}m6y|q3{Ih&>kNDOlM9D}+2ELyaP zfT81#rI|wK`E9QfGfco`^XBL1=~>6nwwGw@Sxi$?1Foya==ppe5ajbNwk-)YhS|Am zJ7=7DC4b!TOYXk=N&0pvKHfy8K)q>JdC0S%a8^8TSr*fd!{JB1k5^uLiQ8`b0YAFq zZUCNn=1DF&|2zs-iAcc2k`|x)+||7J^wS)9Q!wD(hJjcBnwagp{T=8 z9`56|TVGOVVq-IR|6(6^Z@rh)ZI|%KmO-w(`Eh9Og0PS7t{me!eCC(0a`)|{K$xfE zA-;L*BmDCF7jnVcDEDn2=hCz9g65N9Wf#rP>o>HSH|RiQtc;rSBofu>Vl*0Jd?bk$ zGre zL+C4;K&<2XU;lbKPk-WHZu$Xv3cU zMCAZ5qG>1%g*LxRHV)$4=Uz7@ng8QyF-1LEb;Fz8^lH5*udoMF{Dy&>%T+h61+&gu z?(3&Cb*?%ye6CA2s1bMr4M3?1R7L=8PH^uYJRzy8ZjAGD0A?Rr(MApe9*T0Mq4HNM zym_*>VKgv4ZlP&{pfDJB!B>P}&_KE{Mbe|XiKZ7xTkAf5m_N`U(2_ zOWbqsliYOI1Ke}tC4Bh9my=BHW5b5ubJ0cb;fY5dhtvZ$W00 z+`X@cPv5o)T$8W;VvHZZvysJt9%{;d(A3#7001BWNklSY z&=u`Dq9YR_a0CUXA3fTs_D#J4?l5VYVMeog^2xvO?#ti9A_2){lEF-xlg~VjjZbYN z7K<|@bk0BXd`>v(Xf{6e7$7+Nym#@~#;ZAW`4QBioU$0RK*p4rjV&3s@+_#W@VA5C z-Ku8ksH2Wj8l=8HGJ|6j#>QB2@{t505pua4{k!&)&*cdybzwgtmwki zFTM!N&xOW>(zsd{IAzdGz+kF6p%VlJ)Ju;MWI&Vd@@Q`q_DHa|QP^+=3qq3bK2gJ` z?#lDI&pgcK8!kGiIGbZL`~#%?PfuIq>k3(2_tQ5rKrGgT4}l#BarRX|VBq3Sw4MHV-;;<~CynsY|T*$#&tdotsF8J4VRW81dZsPRFuSfrt$iScn|P!iXIOt|iw zYDM4trXg`S_2gsNv11SS@7~3t#)V7@0}IGI4njoGG#%GLRz=eg8dTg06k*J= z&|+;AodSUa*cS3{P6}tLniO#WfSJ8t2M6qZ^Pew-cthsF-{(~K_g!04%w3B?&-rW2 zvIq*nQAZxh_U*f>`C1BVD9Tq`Ya7Xdear|!TcVYGwihE1fb4faNe9}UeWpZd=IN{^x)4u%b5TY2Hn*FvLI1sL$J zU%r;tcD_b)BF5m}y^IP73Y~$00n+Iq9)IEqDxyLu?~qI;NvG2XEI@T}lREBWfzTMU z)8ultI*GkPBPI+6_V1^rriNV3!phmqP^OS7^8Ay}pw()OTNX<&n9(GD!vI%V=nW3; zC$4EM5E`{LezL{!D&l@&>x%?~4eZ>xkGh&#f`LHwm>L@!RmXjB4CzV^?Ow@458Y39 zcMq4Ge;x}o!J>Ez%a$!?M(FI_yH}m`a<1#TFdWCW^DGe1o=C7|%NA;+=B1nvxlODvd{@jO9^99pfhF)gwPpx;I@Ci z4;Ehr@ol_!buD*q@PodJrkl3Hi(6p%$*^Y&w_MuFCoa|4mMU@gcXF`eWXL}VaTi*S z;?ghvoU=c=o(He}J+xc~dmiKCA8+8)o+$gQO!eZOoi@$h*8tl~R*yzQY~Q|%SWI0| zyLN3S(Uu?-ijpp5nfAb?t}B~8={QJ_=2fc;OrdBRbq*A9s)G7AyUqB4#X96IV$lGU z3`&kheW}2LXb7y=K$Xk+l< zjSNzR$`tq9a~EIy;#ZJTa@SpV5e|o$5l}2R-a;r3B&~aD>ZxD^S45C<3Br{~4dsXg zbE0l3u&aypypG!Zy2v$N2Tl$I1n!$Q2a`xJ46pg(sN*xFx(~{-w)#@Ddv}0 zy;*7lu;$1^`OsBYbHODaL{F6Ag%_C!*j#+^#r*Df8)$ED#xNpeG8rzs=t4day~1M> z#vq*`Bq42;`1smxc6ROJj@NX4^6$^{zVi>GD{Bz93~CZFrkxQ2au`G!44ss-nL`qb z*^?PXPq?J55~Ra`kB{~=F))zCG}|Z%N!l5qHPOaIMt%MTF`EPxU>II$qwyvIq7ULB zuqEewZwG(A?s$UYDAr&305l#3P6jlG8Ar$2-@#Gu?O@ZBPjdP>XL8Y5Z{_Xpdk>SA zq~6r4*MsM2&igyN`ODK!^R>@^nLT^@Xm4MGx4XmG2*^&zSzzZW4Q236Pgl>MgTp}& zoc^iD?B2bb-CMWP(%DI-I8J-_Aw2*5ON@=>s|E|I`KR_)p=s4ZXWE;y^lJU6OEY!_6?}dBqg?lCS9-A9A+7%w~^3-!+U<6Q}<8nWI+^C+aKh_ z(=UL#_CaK|M-3O=vLfbzm4ASg|EbAJ?VJ26XN06y_mgrQ!foBGIRA@4I~a!nVL)=- zHMcNy)jHmP_K}n!A#!HB2+Wc*=r+J}b_EeZ$0-80?c3FHlyiY6jhT9i16X zHI0fz<=#~n3Ng6tIezx5-=G(L$kH^{@26RN%xVtlX=UfmK_!K#_v$dXpf~ zf(oeQoDy-NGb0>og-$>!t!T|b6s$QXFEQ_X^Xa%Ct8l#- z{wdGrI4E?=Wyus8M1)GG2M9j~FDzCop}kdE5$AV8-t;yvKpR$%7fO_h41*!?mkP>0 z&2~Joc9}5yr>z)YeuI zUKh4DAgB~wY)xZvYbUPjQY)nwmL(V)8&X|#O;RH@Y?&tYqH zH|b68<>;diW9QD-D9Q>#2pY|V2N1$^cD8ZnuYb<6Wy|oHVJ?3A+u5>Z3$9ycFr6kK z9U9FTwuDnpeGA(+Kg-~bmzl_9XzO0d7rt;SpZLUw(X=4b(~?L)xlr__QuOT_U`7af zGyOCqOpZVP1PTah^){rGq;aSd2^>eA&^1VMj_P4|v^7z19L5OHrH>$Gnnikonh}eE zScsWulp_YR%vc#FL@Q%f3P>`ko75qR35Tu1p;_cfJBFIF#9|Bp4KhPh8F0FQZH(P< zJaH#OIJAgcel-GCCrF3)=N)eR$+<+MdGZ5E{=6>^EisVyGI`%WQ6~kys~>}KClCJH zeu#8pu!;MBc?_+gA*=yO+H^57>9!=UjB(AbX`XZ(jusX}5+?Kn$N4w2PH$ty+E&VC z3tz^^WX$A$ZPSR9{>-ZAI(DR{IZRC8Zwj*^HNdxzT|nK=I_$Oe+`P-=#s{}@W+KEz zCokqiJw*p;c33{@Fsbtv4T+>q%oc}GQ&v{1gjdt}lUE>C4~(ks?bINB46v8?b)U;C z*(9B(b&zg7i`dE_zU%uTyoQOg1GFLaG!MMC4TQm|t6HJpBQG+vSTQ)_NXYLbNQRDO zU2GrLSUBWE*W=Yf#MWvE5+>2mL9abXt(d};#OG1S{jsz1#c=U&9GH#|Vz@u|rP z&?tv-LaWf6BDiT)SVm0j{DrEB9_mN7#8vVz-qgjFFiRnk0)zp!?G?@%NLx{JYzG?6 z1LxAN_rG?~+N;ear&qy;^gs$O7;&|)j-}y{cDVFnc;U`esxagQ5u<7Qk?jK*TD8cx*5WIp}7;b z$1pM_Cdo6h^+guovgzM$V8b`R$fPjv8wQ495YY{+w8WOZxNZ@jTtI^%FvBw(zovuX z;XQ;TY|~w6Y=?XjT6B=jI75G=HV~MzBSrIy6zu>lSRF1Cu1&XLkQ^JMp`i)aOXCJf zQ^X)M*h|^fFoF?WDXGur327i*8(}maK$VF^3`R!>h%_{yX*wJ7FMx9{gqxYPEOwe; z>z!baK}(()0ZvvT5d?*f69Dof5bgmIyr{nbG=ucxIM5_kD~#^OK;O%*kwaOvs*Oo2 zNu87gg~^y@QS0gB{+8Ic=Km1S%=~{Sg_-&DKyojjSh z)uhG-y`hP*(H!Am12=r+^W<{5su_TW20=ypDi>V{E}()J}|RXW@vC1u>gHSPq*qEBRng$`id)t*>YERm7W6 z)8-~_b2)RfVbSxyKmR(h~Q6>t#-sY=g2SQ{rX`0#-)artww3S1WE~t?{ zblo7R8FX~4L`sMD_AXX*t)^BNgu^EN{YjR0HY26VEop3QK}sKc2lo?+gc%*n(_$RtsK58jBUG=jX68cMj=?BsZC-ErGXh7Of&7e9NN=^ZRaqIAhunk zan&Mnd55kQE09vE{1jJU+mc+)X3?S+A`zAF+t}EG>)L?E`t|E+iN&g&_nw|*R5ZcD zwsuy9O>(yCMAthGt5&T-O3A8K>oCn2Ke*{fTzcUpWU^U)ckc!+c*i^V_P1{#xoZ~- z+dA3ZpQOKkFVnWoP-cX-l`Gk}@nO~ZYzR^;x)e(m#ge)-o0^(P7Yf+6Lrj{?2*LPB zmbNyNB2cfJR4jFpO?#=*GeXd4>f{`Yh^}+0EU~kxgS)qD^l$UAePjh0U2<%E4?TLG z^G`d1Ot!=dJ&o=NN+Lm4N}^3|)TLlTS_m^n00-$b;HU^Y9^cHn6~BI z!UPN_x#UCZx$)R#6e!cTeLIJ(>}LOiFM-UHIC_<$SOK&LU~3H0Te$M906+Nng$$*# z)Y5{K7Ht`WypW`Y!{f>A-1hI!gVxUWd`9W7>`|VQgAkqoM!5O<%lS}iE!Tbdr`+{I zBdiF)%R5wY7vBrSAU(oInhvM=*tMMXna9|^M-{SCAHo z`zzPH9ESKA@Z?i!m&k`9Y%8vI^H%P->`0D_Nd_DkD{Ny~0vzg<49tEF;dEn^bn>EE zH4vnv>DVQlaQfM7+P#I!*5^Q0yuB&LnB}7&1(8OberK4ofcjb=hU=%`<{22;#KMTl zxFw;Y1e2?!B%Mwxx}~mT2tT>3va6idO|s=O)1smZ@7V%ac-?)mMit8l50sheabx|^ z(hLkK)wnSm_nV&s7={am^M-t4fG992CAO$k)8}WgM2#ykq$DnKM8XE6P9MXrWTsJa z*{MhI^LHNw$DK_5;$|joRj3=YIY&~G2I6Sc3zuA@OGNjhNtXiP2p1b$iOg|X8jG_4 zKZQ)5(V=0wmUeOM@g0R_>_eo8*^@e zgYe!(5|pq{!U?O7qE<>SKKoDt(m}*R6fs?R?Mh8Y{NW{pc3d)LJH#y?C zV@W1^S=8A8f(HVD=IF0)#zLsPx)Grwf=qgi3s>5N!x2o;0!XIw zJ{rS1<#2`FeQ9>2OLNzarbE~d{mSxH6Gqjst2B+fzT>2+8|xR-&Em8J#BpG;V0llllulDoZj8a z*B&ZDUP4Q!S2QV6@RXF)Nm&ioosxf>L;sK4-z$cm4SZDH?;4@3`pcpdn>TzINp>S1wD0tSBpaufY=X z^eHp*bjj6Ou?Hk(|Ig)e1PsA{{QBouqq*wjZ*+8&8BN2smEqC!v=3?pAx*1-4%aQt z(aJbbk205HuV}CJ^MqM5wG}`k7z|d8BW91ub?4^Xt|!v3pEt45W?dEmd@48aV8A=& zt+9S5LnJ21$Ta`?)GofVVOli-_wR$2!_?PuFSK;RQ@`h_doHCT*3JXTCa(D8ufTXk zU2EZ@n&!s)`Ij><;G^H$4J{__Js~PD4bUCyV9c^`O_$wzjI-YH1(0j_=p*ky2y5Pi zQdDb|n*RqwODR=@yrx_}AemmEtg!!XpyIpg0odX2+wY&rdQ->e(Rd2dA*D-Na99un zSNf5T#iTW?psN8TZ=w>>!;Fj!vmj>D7>kp094seIJZ|#s@7>P26)T9x6U+$c&nGbq z!Hyj}Xl`!ine>bF^$l~#AuD*~k;iFhh|t#3LMlI|PW&++W5yV^og=m=!l<-~Mj}{a zlCtfivdG0S4D$KBM^$mz{_J*!#|K#2)x`LfMds($=9gbs>XlV89giR07^f0#f752Ky zWWcgA#N%N!t%h`Z6lTB>LZw2F7a7hDFf!thPN(VWYG?n>eOz$CyO53&Fqx*mnwOy* zBGj?en>sRMp+%!SHIU`_xBgUFbLLT9V{MqAp71`shF(d6gl zUC$GX9m%v~5<9Rfhv)G_r6y_Pq=%sYh8@kxz33+OAs;wU$qx0?FYQ`nhy4oURj zW(9TOHi#Q^P$6VVC>6ZoKFhi_ZG7eZi^**NBhz{hKC=}|Pthp_J{|ng03()E1x&1s zx1F+lsKDxaam)`QdMSdH>nVsgWau#G5C-LNg4f;Gd7=)577=M+$70 zQB}-e_%7amQVo^ovzW02wrMftq^XytN(i@o)HK;R&H&BP*6N%5c~^mZfB74BZ`-ci zzwE7wJ|e-fHHwZy!W8(zE){14-wgO%jgSWZV1?22I2|o*>`&Spvu+&#>y9~`&W=__ zhPy}?vP7aLPRSzY_$Ugg@P}qYZl4ECX1nfq>t?lJWl7MlC`mcbHnCiW*48!x|8zQQ zk3NieXB$%5Na?G-M@<=oUv-F_l4ngF(C6u#<}9nh_5|-PL17?-Am=zd_W1Ak$@jj) zLytX$<8;hR;gwa|mXtnbyzr|U2~NrJEX@_2Q20ePf9c@S{p`jU;=r-Ll(H&joDncc z{s0ladaR4%I82vRA*=^f&eIfBLC37qU6XFo)3X98AsB^hHcw_mU3bzdQF1I6Hzmk; zSx}1;38s)ln?eYoKtNxzmxe?WeIr>+vkfB=VxjJ*Z)A|8d!iJjMKP0BfvbfQBO^&d zp>B>j=?IQ$xr4XFd#KNr>4}C&Zhwg-F_U-41pV)*=i8h62_*a2Upj(fz(mXJVo_6o zwQ-kBc!-(kQ51=R@Z-y5xj5nD54^~Gjy{%vPA6DJ&X zJc~L_`UZCKw$qky#%U{v0eWgX$TYp*Ih7jOMu7q`%fjE`=Nd=CevNe2$N6u&g6WM9 zVF-<&s37q%DFl82k_yVe8;a8Q{yudSrKFN~35Uac`qEE${E9M&I?u_^o3Pnx0$1Zo zrnEN-JXHl?jVp11o%{P#$5~3GM|nx*b4+gEj;1N#kuBO}i#C44z_xAj*tjm(t|T`; zK%^mpCcr=-G!0!74D8K9xEu0m+-!lM>1R)7KwbQCld>+!4oGHVF?^;=NmL-OK{&yN z-V`4^sg)1?JPqzLF8lF|knV^4;jlOcFQ4D8?*qJ^XTrL zj!{#T$7xOJCo0t}6YT&7vFjP1fXldL(c032HL67QRSin(LUK6;Qe4-iwsuY^U*my` z8kD7by*me1W`**T^EkyduFK@?gaxYLMrazYR3=RI9wibK8$h}?lR!|@Jej3>%~>sA zxmbjnnkwD=;248h>QtSG64ASuqFxzFgmpNw2c#eLJcI)UJMr5`^A zD^|g)e^73NhSH6{Rfn6-YvH@UY=^wggQ)_?n-$1NY7i7-Hn%^Q0_{{-Vj}!=Ze(*t z73%)qGqL=?$50dpQ0M(`M7cg-OElVmeSkw9c{IyM0niYXM4mmCP(nl@@yRj^W_e}q zfx@3!UCh^L+! z1Rxj;vU>GlBoZ;UZQI6{9XnXx-poZ8y_0ZQ$F?P}?A*%2wuJJ`kC`m*T*Zsqwy>cQ3T1qU(Lf1`nU4^ Z9_zW1vvx z_zyh^M;rxvwh?d9Ne@YA>;cz=r2<~iVMB_KBu9AgQ|D4Dlo-zLBOa?DWiK_TMAC?( z#P&G^qqFXEQb5?DfR3(rq9+zWO9fEA?QY1VO$a7{lHcSddjf2WAW?6xa>0y&c%HTs z))I_H@zIJcp(wM|NQZIhP?S3LB|pK82C^A47I(d889`^1Nk*wJ&G5;y-$Cr$4KOC? zO{I9t$qV`OdqOPYXhdNrJEA?TxGV!hz5M>W>v2m-vYV%&Md!HVJGk-49EceAJR5*v zKX*L+BL8wy!#t(iU-9G!x53bB+McJ<#o;-p!pN=(>X_k}wg6jFCO8ttl1Kq1t-`8ilRYmy zP3t+QaMv&HX0lSDG7U3s5I1Fkua-RnL%H&6Me20`hAOyyQZngEEOZ9E4Jhb!vR{4t z51e%7DLA%dI+da9N_-xCm<{c$2!W>Q*m;Yf(D50PQeI6Qbwg0=QNv~gxReMX@M#WZ zPl9<=&uZGfbR&g*BMLMbI))IGZKt|fNht}3W7P%Oa3nrkbu`O))rrP1tFCAjjp|5# zHXkU%+~zVD{OWbthSS{&001BWNkl>!%|XeXN=)yLkWm-_Nw;umBhlIunHy z3oHxWOi+|Mmg5j^atI}#r^Yn#=_b?j%q66&bHs6%u=UwLqKQhCr(KpV6`|n+>VyI* zQWi1H2%1-XPsnkm^a!V)c9v>bR81&kb#EP)ioP}Nm0AZUTF*YP)-cedTP^Ztv7wd7Eb8c>FgA#EHB#wO+T#ncB5ee&#ePGyi}X|3e~r;jImC6rd?+*DH*Vl<9NwH1xDXV+Gq;L-*C2 z_~1DU_+0E526>V@zkDL+e)?es_5)6{LOhN-Z~cBKOG#kf`vw5t^fZ-uCLXf@Wj-w{ zXG=O-TWM@;WB`}qc#+oDR&3j*Y%4>hVzKC@*=v-GE(MR;XirOwd3h@H-MkK<$GLbQ z=Jk#!h6magXhF{$NIgnu0=wuE@<7UrrhZoMQPw8sy-JTpc4qgphD4OKBdF6& zu!>-hLQ4kguFEK9_tE4uQ`Xaff$*CoOM4mDbq3NF^o{VF8_wgX)0eOa*qs_+X`l

Q8}{Bo22|#g!KPIc;xSTJOAGl zU8VPd=1^xPiL^!u2TUr3GBvu%C^lWD>c}_gI??VXdQ*AWKLUnMAfPfSW`ssW4^xyj zJ9qA*v$Kn(ZEfsH_G8<5G8sX0bDT|^HqzDAj^pH6b@&?cRvK5@n5NF29j~x>@ltww zx6;tCkW{J{pAV9i3V{ZVTux#{Iw*{dQ6CN>$uX%FDGk~*HipUN^6cNg-vcSLBc=*_ zk~>+t@;tT=_Ht_yWArm4b@wr}1_JRZlg@?)0Q%w31gZ~1f3EqO^aSk%0R*&pheVxJp{5u0YLXN zBNE7RnB9IqXkl1nFo+WVjXD_u19ddDnyk3$0m#R>=Dd2AubpBuE=yy6=pW&!M@C4$ z?+Ui2Pywk!{hZSMK02t7^nBC*D%CTe1OtvN`=~D%lrn?-_QPvveD>c+yT|ahuRlre z9p^BeQdXrAJ*+xgVi@uzrjmyeJTi#D;gl1)dG32J@x=|hIOnWWSR(>F`bS`U5)M%v zth;W%i7$TZ7TP$G?T_yy(5Cb2-`vf&ZvA(TKJi`LbJs@JtzAy%@)@4m@t+)j{Hfe` z--C=<7Nz`Fbi<%f$kG^!k;!II5uO%NU2x6Y*Lxi~K_-)BB4aTloOzpI2SNyfLQo?e zMw9!n4aG-wZ0mq9&Y&mMpIz*yJ<;c6b&*&4mKp>#NY55nqar2KLR963Q>gQ9+LjbO z3Q3~5jhyWe)O2rSoZHMw!gFLnP(l69bRn2P;LY#wqpZAzfLcQ*leWkqiF#qI6-`lB z8N_U%IVA*Ba&B{(ntiVK ztw~S(T+hLwmTHnCkj!|SYOTkgp3xKt)PR87S#i+JLYH}eDFaoIq4+a%m_72A+G<@r?~!KzXsDT(bend^2cb3E6u|-SABq^ z-t$gAdF9n~b}eJsvSmymX+8T_5I#(~UEzS<2D|rxk%p7j@!ECE=ouKm?__yv%tcR) zV6>jhiPt{HlTU1B|4;v!*-WSf9V@wEpv3?B)Xl(ZknJEgaqAbZ;KW1|VH2jLqa5ur zBZ_(;5;U5U-Ht98)qFXi}Q4+~ce@&tX$3%ujBA zhVP%fk~2R3Pn1g*{Y_E2j(8jv$LNS1#taTMQhGdiy$bsN5vB6?=~?RD5TG1roH6HW z>E(M!$&{32tSvN|F)T~vWZZb$`}o{@e*(EU|F&ljKfLn>%KH{$?Hu6O-#LM|f9aPD zJYlIkF!^WTP;b?A5Ap%g<|#+C>J(yDuTrf-Yg9{SXmF4^O`|3lL}(h5c8=n>64|@1 zTLmhvrgVNYnuakCfE)}^>Z<{hc#{-GKbyT@1NpiYQqiIrSdV#L9Ict6>35gMkF)alJnP<$(FcSra zR3605Ngpe2dW8C(R{rVq6=a+Yli32dUb&u2zx67-B1j9JsA(e|hrw(V_5=1#t~|Dl ziEQ=&%kSB#8dVdH|97Bey4sMLGX(e>KxN)hx32>P=RB9@iqs6R$|*v&WQozpk3|FT z%v&swpowuhGz* za{DpK(qJ?)gNA5q^s*cvpUx^HG_pFe55-EbeAtV1Of5AI6M;S6|)15l0-s zo;`b6zI+X(d>T+xw$`qty!^_`G{zgT_VyzL^!4?#bZHlzon1Wt(o1ak!ynl8;tL3& z@!(?{`MFn^6s$7&yp3&3`uc{b)x(6tEi7y|`PHxP;|uqH4a+K2-5!4U!yn=}(Aw3- ztv|S#>#n_)`yY9Pt5+ULqiHf`WyobR!~vffLkN?ilOcg%T7oRYW1F^s*3Q4Z_gvbu z1+vyoR(ChRSsk#kj$i!ZN#66$rEuCRxcd+Ejf``2hoAks##x-`VZh3u>#~ZPT?8ee z6E?wL0)}?N;+`YXHhMOUt=DG`((w|CVNx_#td^p#?>j5y1qw(!KL0S-B2d8y% zM#n;Yz5BuZ8|=z>52QyJA2Aq}J{FlF0?rmTeD89O{=^2zuja;|J;SHp8A1MU_TD_c zt@6zK{#w#~Y~50HB{w20CyqlBNCF|0Eo@=m%ao;*PMNk$XP9=nOs54(Te>lA zc?Q~2T1qMHl(j6SP-qI2wS)i(SxDj}c49lW6kD=&Wa-F0w=6w>oMYLc?a)5+zBAAJ zd8>bv$hMZFbME`PuHTl?P%7-uJftJaUKoavTn_;6zjQHQzhg6uG;qXE2OTl>9Z!H} z^38v^lCppcEF3CBcXdYq`aO>o(z;rOJa;?luts~Qv=r5udMTdHyC3a-G> zS8-`w4jnFZ2wXoym8<&DxIg!}0(nmf%059|$#Ge!Lons@RjFTM)+QlDg_1PLD}mwC zPj%g3%CZRRl3EnD`<Z4tJw6ptS-g*F$;?`nEdL_JV*R==$JujQ`|h z>N49%Bk)E~;=)_@^5Px|3syN}5~-+BBkas1xbB)qAiM^26W9wQ2G@S=Cp`C~4>Dy5 zLhj~Vi(|F9C0S(cKi>iKS3%)b=LiMj&b4kQT^g1I)c_4cV7G!$)S)5z(^Zl3>|jqJ zDkz}ribls3Sm}e*5TzE4DJC8FG{0~ro+A8j1>vd3pTg@ezf4FA z^4lkW3*iW$7%@v!42OD21jwd2@yjN6ee7gTT)lwbbm#boPdx}r&W54iQHknQHm11m zsd4Um@h;3KKY>R^>G+PLJz5yvj~)`3ImHwTkkw-Ezq5e)|JO|%GW4j^D=5okuIyr@ z$K>Sr2+#fQO76SoZH`^}VYaI6gySKKn|tx8EWf(xV!nURetvb|t6bb+U|B^xCG`%M zHX9)-RJ`6pv?w#uju{$Qy{2<8mBOByqNTYRp=s>ey_|`D~FUW(G%^V>4mkyhcuhkhC$T;@j3s>^; z{o8mM3!WY3)*rsb!#7{Sd-MSBTkYdg^%jT@?%X)e#}m-f6651{Z2>LJFFK72v`^mhQsZ1*WO2-e3J2W8rxRnMv|;udlo}O zeL#RCjyTp8(Md8xX^uW(Eq#4`ELyaX?c3jGXx{;rFItMXP(v+wRyPYaZTvl*hqcpF zC}7zw1Vk9KFw7hgB%2*35|PAW2@W0{sCMCo$Wtne($VZ=a99=(#C!+ACj4ijiz zN@nZ;(LjX8#%5NmSk3V82;p#;x8L54Z5L3gz`7GoAX6xC?6L1b$}n}hq@^RlK{HKD zM;9JdL#)*?hd$|;Q;{-&ls+u0#F&+3UPlKL*(`abv2NW3tXp>hi9~{Lq1e2AGxhNV zR#9=^y+7gA=U-sou5IL9VXt2)KJ%H+W12p3=xN&&q1TkO1&O3z0~P`GRh(-42qdE9laQcgovupBMVPLt6RXolal+BI+Iw`qE}ropxPJYAA~eLiil4 zMfVetdiA|qRtcd?g2IPa3Rk2!P5mlS7CvW*o@Kx4=uBWb#dzktagK47+9d>j<-C4v zb&>bGpT$|^3$jwx!_2|1QV}LmOj$lx4DhQvz*U-c`6{ZyAYzSeaMh2)uQ5+jU(=>8+o)s%r(B0ilp-`Zu zV~LyTrJP}eQQ+~D<}o*2PjvNaM!N?X>G5#(-QAGYcwzHCj_WkooQree4KF!{6b*40 z+QvRrq)P~5!r;-@QeZcMou+c@IUv&1e0&6kOz!&Wv;5oTCo%`fr_)5z7wLyps> zSO!|ov764O9p|crx~tm*3L~(8FEk$y!%jYxH|(Ppjf#tMJ71~oX5(mR!gkRx5F$uK zZvYgdWG>HdKUZopQ0^bI89Um znvA*hTNyNSggZWeG1q+UJCI(()z|;VY3zh>+`e9Uh=(8i7{4DF;M5fhpm`q@jzquY zK}XX@0vgji{ke;oDmrLNt&47YEcI7i%KwwhuUSa$ABw#J8px<5xPzZM-N*L+90OK> zuRi)4icJM>zv>7UEbXKwUBiKGTe)Ceh09JlkAS5yW~FCPaWTvG{T+Vu(@2GbjLbYf zIyy=)7$gu3Qph_g@S4|4BoZN07-It4b=`sqdzwaO&vLe#X&h$1X1Pi?bIx^-J%hN^ z0cFhzZX6vQr7$&Pq3;Vi^s-ETj9RZoy&jpBljUe)rp5JTm$gHc`gQ0*_b8{FRJK1edHjpBrD@41GEmfA&!- z_g)COe*W%^Hh%Q9$#svt%|Cp$16>&W=IIT9$=_df3j4dwYS!DIl7IZ)a(h=XJ@!tJ zaYsZQcC^Syi>@6O`38f5fCX8LsFa+wWEHYha#lc1rzCX@;b>Uq7&_x=^AI@4G)*V4 z#wu2)c-_9z|AB2QhKGl!BY+AhQdtYtyNj=W@guBV7Uf|7 z%iRCSFS+sSU*v+Tzlt|-6q7(8A{iTVT)sLx7jg2*Cow!c=s=1ao?*wH4gBKkpXa?_ zJCBWCoi7QWB9fA(8QToH5spE0a+i zzIbVMdYc0xQgX0ANiJt013E%DKU=x-Xw00+(v}wH7&=lq$?B$QGCv;2G}9>M6l6tV zQLb_nEi5aIk_J~^eg^m4^Ap~9BaZ*7Hy!S9b{h_TqKbM`nl!Ox8{9LbNtDDX8<~J@T7PWahBdO`EP#D-uKqO$O2w{txuD+N( zy*Y&NF~2R!IX8R{8cwIVV~7K{E(Z~(=3^Tmt8@Cd|AXIr=@b~?4;qx&x8Hs3J!CRV z(L;Ug=*`e(tfgXh;7R3p@PY;Wpgqco*5?Q-*p}&GzEL3{8u-$OPh;eiBCD3pr!Tdg zHsff#W)GiPCiuVu=koK7&tnx9VXQock1nmFI50p(8ua#NC=1wYrm1O(;z<`tgcEp_ zKtyfyP??|@BVZYLlw^`LjYgb<14$-ySrr9NPvFZgMazRkS&BM64rYD;O`lU$PVJawSBvB6 z;(8JXRh+~JL|yGh4RylDB+y{Q=reOf^cYQ6k)o*JQ8m@<5~q2XCWi*75t1O_5gHNU zgu>QPq5*@l?!1;)`ccBFPVA;siJ;Vp7=kIQ7UgMl?b}e?@_H6GZ9#2#^Vt;)-`*!Uj zuLR4MwX-ji18)uEsz@NvKoA@3JT$y0U38Jt&<$qbgNO6TtzYNd za4U0+#T;%_&{~?|?&qPgor-Cq%LUwZ*G_o5AC8b<^+N$Hk!2DCLM{Au)0@!T24WWq z@K_QW4A^1fCrT}f33m-Pgk;#XXw)qV_g=xA^KYlzd>k~v;I~hp$zP$r*F#7zFeRPi z-^1Y?^{+320+R{Sp#nKqatMWBAA~@Fg2y{1)cNF>zdq9HFwrr>Q@1e4O(EPAkl<_mM9=n9|0UYRbS8* z0T&8*(3qnI5L6f&8>>2f?c3MQQOlRJZ{I$oCRiAX!|;BbeyZf4Y?)nLup&XzS3bbk z?tPvOdrA;!2NW%07jHg#1`To-c{9M?)Go5OpTNg%-p{=|vY^39y5g3bj>Oh2JZT4! zl+tniQVOIyyqLuLtD64*aEkp-F@3G8eVcaus&&^~j}<@&gAqpXwM%}rEyb5F-2!W_ z0Q+v(e*)({bQ8b*$xYPb3}7 zSbK!g!WgBzO+KH8ymKAYdNo>_=P~Z;y*#!e=e`Fm7^Lh9^bZ+)DVR1nnQjIrX#i}( z%AnC2hHMUm$<-fPfmcDJ=%bD@n3Bbd&!jK2iv^1tc=!t|h<27aaYY-&fl0n_W*0S= z-wom8x%ZWQ9J4aSS1&k>A3gmvY!P_n8a8Y{0EI9tR2pQd%ILu|NxwMyYp4v*ZU6j2d!0v|it$pC0w@Om$A{4mU_wh(06LH1Me zK}|8tgx|(f(il}10a0L&WmUb~YSL+J1r?osB&1qh)tm`-9ChLa#|rmMPvl9U96V@Iqh7vso@9re3`r6oFcR3c>;j|r<`&Mcm3#g zKKZH7@$dafK6Cx`%vEsrT|eM|eg9U@KKnGRg2mv_2!TMDxw=D<2`j}%K7A8Ix=t+C z&S5n*-1Uub@by=>a^a;P;pxIXG;R)a^EbZ1ZQuMRS6==v{NSE@*lVWQuQ$;|4?BTQ ze*sZU0$pH@aPMXFnG{LBaoO?IeC}>Ycd+VxcT;}q!%SJ-)QLEYIzxQ)r=t+gGOwdR zy=cV~m(-@WlgTZGY!_s6?6~t3?CzH-wZysa3k$jI${({Qum-P+QzA7pp%RDQPg*AP z+9mVaeWG^q3IG5g07*naRE%dJCL6G<0dQ?1G2w!Cr+_RflNKaX7MNJH=z@+Fbxf)O zLg3VT>~ud~DbaVe%&CVZWuKtGzn}9i zc`p^$OTA7CO3JO-fS`c;9=nePi53fsi@F-t(ah$%MEG(p~AcQ1>T}3ZybUz~~bm^l8A7vEY>JX;F92ugF z!qz1|0h8{qB8MWNM>)_lz+}#1Ti-^4Lh$Ma$3P??16=d*Yw=1+oe+3ki{D|>F}z5p z(=_TnzV)qd^U)7p#p^F`a&>@?e(B5$&d0J~5j)hnNID zdhI8fDwZhw1er{ZrbvK+y*qey#~$8)$q#93iBdCFp{{0%LOzA9c^s!TPk{;$k#VGy zOk^#ZnwlIMT}gA&*nj>@K5*wZ*}8p{`u-Hf6?I&5#~Yxnfx%sLtXxIE>fxW3m3f~Y zyLD)oC0rJu!m6Lqw+75nk)!o36Xy19!(Wq?cfkq#f9CsR1R)wCZAC<{) zgpx?9I{~-sV$-ib$Pp(#0sFfczbef{Y!93ClQ~LN@Tw%1HNuM6GRQi`^OOjX?H4R> zYDTFs##M@-sGzAiPBUOTdXy;v{Z@gX&=}74(AqkWywVsPDNyqJF{vO57D|*rwN$~9 z1&h~FGc}3FcCu0q4)k-@DXRb*f4GTXJo+5%^V=8;2&Pcj3S!}a^Iq&x8XIF23bt#t z-w5Fd9#voho3bYG27K%qOR)%>OHNutEzr==z>DjD$IjmEWQrB=3W`Pn8lzCK>60)I zgS=RSFSCgg^$t$B{!C|LU7FT~F2u4Fy_P^o@Tf4koXKsUYUXy|eCODdoZ+4_EsE}S zn0JdjubggB0OY$CLjTnqly@uE-ue9R{QbZ5_5ZBDSAT-0|0gJM6Q)T)3TlP3mQ0w| zjEH*JqTWSs^U4CD6GAX$70C){aP_>s}R1H({BAe zPkp0{#-1j83i^s$(L-HeB^mP-hzW^dd7RMQ;0mO@uZlU$(FB8bo>D$fFj!wjHuSl3 zK|#2|$<@n_74W%DKv1iv7D3Qf*sf!j&qXrOoK$;5 zqcUzo<@$J0C^#A~f*MlOs?AI|7-Z6Is76OqEMDA>w;)ItG-?9@GW&N^uY28kOhZXY zNhZNG@mWnEb%Yq9%m{I-gR)^WEVEE(fJGgA?*q%I?H*uLEJABZBMRiqBo+zsB1&Sd zP9(OU-d>%y^hOA+gpQM;uY^(!G$!{`>1>16EbKXwOE-@5)OR+^X$5HK@MX3HMO|1B@k`Q$F>IA59G;JDE0pFSBq~2jLs)0yYcFv`YXd@r*th=x z`@2V|4Yt#tN|8#XIHK!F#C+u$_r*ck#Clp@kZ2l3c z&`-? z>yq)bNy!Zs(sjcP_OY0fLvF4Z~!9|+#mIX+>%Gs>vMH9dQ$eK)8 zFp|qL2aWqaeJPh+`9sh;Sa-_?9{$oA_HEn@p-z6dbpr^=3ClalyVM`0n4IPQG<%~{s6%Wa z#jFc{5_JelA*B2Z#&7Q5EAcKC+uwCFIJnwsbng4bVv z1JBRk`QJWCx22p^5HVv5IejdqU4v?sn4yu)+V-cZRYEvA03ohk<{0Y8qErq2d-l-3eKTv%JC#%_gOpC=&}QAPbIpes%4De1b!V!oJ9?O@Vu@S+?Q@)Z((xR9 z#1S;CS;K^trcn=b@52xCiO+tLfy^`w&tl!W)9L7F<>l8m^4MdK@#EWnNNcQ~j-_iD zEGUWuCL(?qtP^6;McmSi{L5d(*Mxw(DTzO$c|u z;7fe{Ul)<^#~8|_Sbl5*-`c|P?}6xZ_*cC39ZM2wi2Ft64U@Rw1O^~ zx57)~z&5m;hQg>?wug}HOP7d+6hHpbVSMk0zh=O^jFN2Tq>xEIlc7!-j3kSAqtY1& z9PB4+j&kNnNAv0ih&MGexa9zit!-@C@^%&NsAMaYhxgGiuZ2{h!0IK-Ne>-B;Gvla zwV4c38k`Vl;@N$>;27nIsD_6SBF)R|Z|4hNeT3cJ+lfRpe*WuU0RlT`amAHyaoPnJ z@!-7=pzPTwsD;oR^Mmw=Nm*oF%8jJXhGElUep8&spI%S?i6@E88|St=e~LTxVBNaS zoOsSfoN>;1eBu+=apck#*!Lhr1oc)DpW{d({AbNnzo;;YV6GAr(`h)+2P7GM?$gw!yLo)&Qa<$Q zw_x`hMASlj)+kB{=0pV^%VY}aXtI=rWqBL~C-3kjg+IdBXr5qDBN_}+Ks&_2Yiz7g zwJ4r$JZ#%RD$1Hhtwt5auz@<9hQ+pL(2@H3dPj>gBilbjD>F^gsv;@w?+9(Sc5%iH zXTn8ZX1mVS*VmIiaF7W!{F+8c)2QeTjG71W*K2sCM5z)U6jSc;_PTnNqA1`|X{J=3 zq! zy^&f&C!^q-e{&k2`Qm<_{K@N%&AF!d$1|5OKF~|V&_UV%qi1Y7ZPKA9911@I3KL)m z_n6I`t3I#LDT@F~LC!RpvNVS$*J|KV&=`-A7D;@`60PlBOj!`dAS@(Wx`s(PBMb^E zcgkS{1&dlFa|}r`nL^h?7(%i?IY50pMp*h$N)c5hP&MRLiIP=f4o-G}X_*XWEley9 z_L($=!)S#9yLazrj?l1Cc+lu*nake3enKk9-9LMrf(kH65Evm40B=nVQR@F)LOajg&g3 znI@Us${X9Za_sr~p1z zyP@HdDJuoTNx-5`!dMEFFuAlX#Ix6~aO&T7@=S6EJl6=>9G|?no=h?KXTb34U0qvdHzBiOW7Hq| zoWJw=6f-#+Gydo^yySOHc78{bGyDDzH%0MBH$P7m`c^X(Lm}}?fq!^}qYqz#H&DSe z`><`r=+Gdaz2-wKiW`hkqRzEEcRpJQJ>(}S1Z{0?9JQzkU9S+J01E#0;xkAl9mKFv zmtXNObSRPd)Y!or~tv z(yHT8BOJB7gAK2~$}vk?S+%qUEtexA1(xO7vHApa6AAkJd#KZWeDH&p(5UMi-gO>% zTQQzCnLgY42YNA#I5O&IB9}o4g&s1nu@FMBY-uw=QQ)vuU6kFS(C)q=PQ3hbGMNl> zq9Ky06iA6jnPe=Jwzf8yn&i6c{+Rfd(7E)|OBqXLs>fu?Qhfi8yLkPj z=Xm__$C%#~XUo=IJoeNJytT8RZd38lqt9~9S3bk9u0NR*k2{`MUwwgt*)jh0lb_;* zQ_td-TW(=~XA3NP3M|{vgt(Mqj%tV3_wwWKoyX;?52Cs==)#~kwTnq4Cq#W9Ef{pd zJGHcg*ed?<<~?98hW+>Q)qgvcMr$V@{^py&V%FXKD-K+{1UXP-M1aCX$~azhnk9^O zck{QWwQ<_&_W|>;GdYR_n~-fS*cm}XdkDL<3q~x^meVBb@L3IbWtbO!zY#qgWP9Hr zC!cu*hpk+L?ItzPL9uJsE)Mn&k?QMXR5{d=NnsO?MFAgUwt~iliy#QFH3pPUvs}*c zr%v$O7oTNCTO-Nd0p8xciAe;*S&OO46a`s8i2#%6c>OvfB`8=HO#ls!ZfgP%J{@mK zF@Yiy75H0y^rg12c)@bkKmKb*hms_dLmakh4fXZ&_~#pMCLT|aRDS2Zss5@3{(LFP zs}Y9NIf92!U1twv#2?H}3Wdo8(;-_b(8!`? zYuM7gfzi=CvOai-7(Ecw$fri}xJ}D+e=+U0r2&)Lp&As&e%qyZY10Dz028iJ#LUlK zO&7C+8tp0-tgMMY*iUCSKV|nlP3yWmwv9g$A>jV*z(5bhqN1Upg?UStVi-|OGlxfk zM+i_hlQ@>;f(9HkAVjlh1#JRGBo{n>fVJ64>e2zG^hw4Pgw-gQUlJ#ATqiu<%QG+3 zaO*}d#~G*drHA@p1Q^@E$;X~fa-f^xUd5+ZwDB4H8L*u2$jEz!n1@AP!fvads4)IV z&u7ChoM2I95f1qw-~m-|k*Jy7*Ec<9tkd-wK~**lN4E3LuY83?JNkL#i#M?-K0?9V z%9J&qkZ$8qBLwsY#@)rU)`e1nvo3 zt`^2^js5#grV52>F;*7SJmW0G!(-TXf%m-UJ>(9ic=Z1JIWRKh3ThQbgDVpDfvy`Q zQ~iLzh#DxRXw-GQQsPk-!=^<#?UWmdL>od#bhiPSACDt^0>AVzWtAwDEPSR(znNj- z(nWN4@1rbyDANL6l4yyM&SZ$`k}`_swiwOC7#K(~;ZE;OGe@KDujZ>bLo?^TKAynq z_j4pLE-HjW6;M8ksUpFcpGY(c1O1rM5Jt3x$sCL(Ut>{h9`gyppi`OLI|BXhUC<%aLh7v1|&Di)4?Fg9JXNS(6qN`s;h1TlH! z`ip4&@Pn{B%rj4=(^|_y% z^?8IkR3qb2YNi2um+!B}9Ts_|L|G<50l$6bDK0+sR4%z>EwNaFOeVv}uKobG-1433 zwmF^bt`zL+9$?YZ1(;@zyYKie+uwW@%N@xdSgiWKuDIet=EtL?(>bKn+1lO1Yp=b`)mLB5-hotAQzwK(&a&54%3?`-f;ooH zn5CGq;EkO*PgSp|k+PQFROWZK@_3Gj7A`h^k4*kqC9^QWw&l1Lylr;)AG zC38h9FK*bxk;fg!m{r4zkG;TW-_#(`1;ZBOdJ9P_M?Re+q_208yzrVokf#&E(&KZYc(nDdy=qWlO^F5G)8&j6yN) z!zAmRH-r%)L48~>Zkg06n^;H^u%IFpAu32&0%bukz@EVoT1A+-b6Xg(2e3x-*ufyd zV9-TT1i@gCoZFO4Hy9esN}3ng_UKFwiajlow`T$y#kA$HgOX@M!&Z(<-gLx@rWE$H z^OrVzty9&e2Hxo$=KOz-CMX92C}lhDtOEmtf`H+&VXhU1!YB-v$bI829xnimU66g=34v5etmG!{{Mz4g_mW?;eMb*Jy`^c_4%ED|BFz*kT#Xlvv3ty@{O>KFzF z4!Vn}MgfIgD7Y61tX{pE-MimLsRDsOkgZ$aK*|6XU|JR)Wx9-PY^<$ubEGgNdJC$j>$(Was+roPXh|L>EVC#>Bh57a!q2Nuz#e@Y7$~ z0L(mxm?f4Lhip*gLjqi8MrqU3vGSi$7`$5}^G;gWpV~h??-0jL-(s!v>FMb~GbE#_ zK9b3PrizNqZ@*1A(N12KD7!Fu?IGxpb34$}!@iQjvR)z4(vFm2DxyM3O6ppqi`;?d z&sdQ?YIg2`s!k)P?SN;~DXc&9m`sNN23;B~D2kRvI4l_-8DahU-!Z?bshV_OACEhk zH9|+%jq35AV?;4?IXASj%rj3uQ5_1^HyPaj=p%%~4X(zo#CY1I*@!b`SrieNrlO_A zu_+G70OOf7L#9bOJw!u$7Xy2D($=+{OeRA_I`p)lYfLcZikNG(ATK@f9H*SHilC6# zriCh5Y*a|%PY0er*)P%1b{+#Gud`@D z6B{;d;L#@^z$?QfT03~+S5MQ{)y0CYRyXibBRTYIR(7;gqbwG-Bxr42$o%D9H0YAS zbP_a(h9T3aV0S+hvW(b6c&}WFzdnXiHcvnO6agt17|Bu*ju?NcsGMn}T@{o;q51%f znNFh;5TGO$2kyV0`K|M@mCfLYMOlkr7*QU1`umVQ92x-9PE)Q+ zf~G)Of^pP4EJxKLsPMb3f&Vuo&zHsjR~wW+eXH&hLR1kIHJh_PtDxMan~Vt`6Ii^s zYctFXKz0Zr9DQqZv>n0?P!RYmKT2stq(M|k=9oFg5KQDu{COg^6{SRZjr^xUA)`uZTXI1NTwa{?G=S{A1c@~E0wPKcE%G9om`Uf9;0 zy+^pFDbo$dv{t1K8ylOlnE5*=VARp4Oa^Scws3P+92(iQP<~+KAd3!LMsM#yJhn}| zK1e~}lpIBqR@Rbt9At90UN8~9oTMUkc~92)9fz}F#4G?q1i}~vP=e* z;FDJ!MpPakMhnNs3#hapuL6Yr2hZv0?Nrxwd_ocmRVd;Fr_&Gz1g4ptX;eIF<_}}B zIH_LYi0L2sHOp>4gOe8@#aqw+p8EJ=Lb`!pfU*Qa=uS$uVK|dN0VQEGsg&#Ku0Ytd zH;1|QqaWh64R3PPr5DrR-_HdXTmUGRE^Ot7$9_U4lg2c2)e9!?3hbp@;J3APa{l?3 zkQ**g)}WZp5($SHFASqMHZw77Q(}~@-NQ_vp^X(t=SPXuYk0jiOiWGD+1W{^P=JEN zGn^wdCb6-HhtV{R?$I&EZO0lfpBf+>t0x!?QYaMAG$%A|5*yogvP?8h5C{Yq85v=C zI7=;#*Y@R?UqNqg53!iRglXZG!gchrNTrgrM-38*IP2H1CmuIA*x%0wFT0HApMQn7 z_wJ#mXBTa4F`j+)X^uJO7!S@lGhkyV6PdV$X^NBV!Q>Xixn}}hWCVTq( zNhA_@l#|tP!HPEg64JfBM5H8yWQS=HBF9{n;~ST?ur23&mIXrNoW+u`e;^fvcK`q& z07*naR34+LUMg-7p%PSSIJuqx=Ps?|lC~q6lPfW1?ZPh%MpXb`B2UHC{%myQzq*-D zzQg)(`u~n@BaKhniY>y|HTDK%uJ?~s#4IVr&b%^dW(ie$*wK0qtqBa8DMy% zz@?X6#h(5Y4edH8$Mr|KVTi?|qjk&KHuwDSHjX^*!)1M>tP;&e z9HlIpjVPIn8fmNDIc( zCb4J>4i6$pzuCwUm?T0WID9#53A6NDuk!m_PiF$6GjAY_tw zTa20;e+47+fi&lKv~$1$%Py*y{b zx#o-}{^s~gn8exh3YJO0HBnJ2iDfz3DWOTmN75{7jg#uzMOPqz5Q2|<}yb$wTLBQLLBT4j{Wck_NX)z zz6T4AhhdXrzy2sN1lbxG8{+!Qj^p(9C}WmMonx8dG{q4~O@5S=J%BgRM%#jBG%dhT z?>wdcH#Uq1B~ zFpmSmpe%gVAkCtXl(Cq^!mlJA$MS@LkgQ%TXm7`*I!B23Lj-drOra?GLsW7aK1)$U zg6-YgS#)fi+twb*E&f$lLg7o9*rp?$7_-vUGQvTzoT%vI+m|1K=J(UzyOFYJr%n%% zGqbMC=6^q$GJUfwMF6l_fbd< z(6qQrZOBh5wT=JH-kXQFRo(gjFWElV*13wWY)iIf$97^ni4&3lN!XXNG)#cD(6SWT zDYOG^DGbxncDhYV7iLO3ZRs|2XlWUkZp^gMg|bsZ*+K##WVM~xPAtckY)Q7RqI+cD zBTK(OuIxAqOFNyJ&hPo&=gITLo0hA4&-r{l?`>Ylk5plDB7rH}NNLX*r%HO_%P}py zzel2gw_N%ze*er1rHv`bij`r0@{6BwY*!ci6A31E46vuSm#y91OwL;Nijv^Y!3c$k zM7EPorx9k5Nyot-3^Iv>X`1BIifKm^2m}}zkK^-|Q!EyMB1z}qb(?Y~yet93#DLk9 zULgz&!=$X-AfB6`koA_+L^O_J7;N9Z-MisyOWaA*^cojo02;@E`STaDdvG7F>$11E zhi6`RhSW%c&dx+jh zX>4qOVv&8lJ6N{-M6}lI?e1plwrz-t4-pDQsKgT{XSJqEN~-1{D=3>vE5tv2_HTJ! zKF#(G{ov%e=DHKPDv~B31brDzu*G7EK7x8aLH#yb=%ZS>jJ~{w&D(qVx9oSQ3)Fam zw`onro#I{V-paMtUQ3}uFc?p9)km*m*-2e|aPuPsD3EieXsR_BwOtl04szQ)KP8h% zQHI8s$@5IlIFCN|5F7vSC^fZyl39h;MZm||>)yuuuKOFd^$wK^p9rD$YLWv3#A0!( zfxW#unBVTv>SD1NK1-03iV0iO5NhR_-`+?4@k_`gbNIU=OvHNFolMfU;v~xbepEb; zn@pl*2Q|{dwOSbI-HQ=2n6x!@!Xhpt`BurK-9u1^UUwsUwO&CVmNI>`M&}U0-<+xC z6mvBx`VecxN`0_s_^&o1f9gUtg(j~x`-k_kdhuyg=`@u{a%qRU=6XV5i}@WbNa+>M zw(U`;gpiEcHd(D19@x){3r}auA08tZG|}2%$Z@#n^1nt@2&zkkP?Iy!S@n-lr>XXYJTR0>X_frLNpp967kFdA`#E+>%j+q!|B&vO*ERI zy!3jb{R5uZJ+Te)c{+t;UMho=%kc4!p3JwezZ;w&AOF|`{Q4X3p)w>$Cnbe=2AqCy zV;mbK`u!t#PzsS_|r|5WPCaP%014 z=b_%^wht`grnBbL7tfFdvbN1v-`v2pmz>Humpub2QVIxeLh4S2N7AfVw3t1EQO1*s zNCfIckXJTtW`1Xc!R_05``h0^G#aBu!d{(b>C#15)sl2N&Ef@%$xFecl#sTmwW=v* zdO2f>AKO+G?I@OIQ4_2oAO!W6LIoAfTh86+2@S8;SAc^AB?7Ti#Ab$8s*|sAHdwvM@A{ zWGu>*5Y$@{Diy?HQOuIQ>}WN1VUAN}LFmH}7V&365B`7Fw)_d`iMPh*#7yX@$0qRQ z=b*mgAktDe?D^`oMgR68R(7>>;mR()|1S^0l5^OzDdyFArU6c$_y2Sfc5H)%=Yk>m z@^7Ey@-JLXJr*V|=b`<`di9L)LNFKRkwM8dwcAOiWCW9UrGqD3k`A{BLw!;z8MrQCosPd}R-J9cu?H6Lc7W zPL>oHNk*}#B+L}k6ogG)Lb z2^GT#c~sz>j?pMBGH;k0@aIQU0IX_1FaKc&>mT_E9q<1tG}q0BWG9n}gN@4Ei(e^4 zxvVRF?vh8JdJ&s0u<{(}F{rXSag#|5Wq?&r-1f0drkJ!9p$@@3p-E~={9rFfC97Sk ztT2hh2>W6q6of$}(l+bjlnGgssTL~IX-1Xu8WJHeO~JG@X%&J6kv1I1nN6*Zr^jYd z%Q9DU%=~7y48&QpW+f974#WHQ(b617jgL_@f-G9Ggx=o0)Ys3aw%%miad6XF3IgUC zKE~2x7*-8UH72=P&{e8eFZ8)RB58d@V>W0e@i2Q)Ockk5|e z1Cq%Y!$Siom1bTj%%aXtlBrn9?lj4y%269>Jj79Kx>Vq2l_IBM+l|fml3s%IkNSJK z?W%Q@$1_B1n<{GrgF2KdGAS0)O*Qqhj$aH6vnLj$Xq4e)O4yW@RbUtaw(Z`7^m{H| zp}IPH;xH2P0rPQPmxh`EvGKjs1sX{VxjepOCzqUd4B3<*@2}vMSe$!b*baealG$;l zr+t*0LGn3=^)I}@$>*KLg2q-)@kv*+rGkmk3Y|@ zExTE;q>kMxfz{H*=z^dg-P1MV)^jRXYR!R&|=wZM#LQ9>WnY`%nDHu zV)p0%-ACDBp<**(gGwoq2!8R4pYiQ~_%IQ}#S(&Q3B7yw(kLZOb$$lpGnylb*4`Q= zrR3_Xufnnl=8}@y9cs*TiOu?8B%hbI+$=>mw$<9yP9numI&k z9OCdLL@5OPk3y76PKHV`FrfI+kAB3@zw;d?xBiZ4Tmqsi8D4wyCNM z(LFH0S8n|xKWz)KZ`)H;=q#ad4at!N^JI_<)?Pp=lOq{TVUwe1Ynr+m8M8enz!zS4 zny-K2{VZv&XE-rHUDHDLk7YTwtBc0QM)sz1OxiY6fQ=>;@~lp6+osBrR7pu(*%+Y^ zQwYKx9h7NBG8yB_D=*>fvrqHvXO&G>L08ujFdl(5jetVNa`;6AM{DW@JpAcpoPSRi znP@{)G}0a4gp?~Nldx{x5~en%>C~D@8DY#8tQ3k}cYTI0-m{JW7uNP3E1+EpMZ6FBkFZ0Qd9K%=t z;R$H607*fVbMl#W#J0uQ@YH&)zvgOAS#<_sD>SS1scxxeS__U_E9e`Fa_;hrapEy1 zY{ky8F|K{jb&LwZLqb5%B4dTfAj#N1rf8y=Gf}FCm5UcsroHp6RGLcdE3FYO`-F=l z6qQ1OrKvDol%tqJAWW0g2!z5GIY%+2ZK|3iyK~!!g~oWcW`N7gAjwpW1BnrY5JU(2 zSa;T0G)l>6bb#lCh1nJ1rC5xB2$8WYDs4@f%CWpP!lbP@$UxO|h82gVl~-~oC2ZEE z@Bg7H|3$R@;QmpGATMBAF%v(^;lYcCA48&zq@@^DF}jv$KKf6`5VMD=AwjngEKOE3 zX*H6zlhny_a;Ka@Qniv#M7inhXEA2SO0KeoXDH%&1Kzi;J&X9_W}e%zkKz9Pgj*U| zy0FZFo0%=7_FAXmz4ODVZtI!PJ|g35sa2<5~&n^WfKrdv=05RQ!7<2M@x%`sCTx{ zgY#nP|to%8Vf4^~qWXley^!R`PuJoljE;>lIObUmBPwWUXdpMCsUpD2V@@aKq%m4*urQgJ(A3m4 zuz&x40s#}Z6w-s%gnKLNW=oheFu47ce=jEb>ZFBL!g; zsi8cvkDW{8irZmJn#wP(V=VSEgjP_nJ4srCKB<``&NKl)2p+)BAFkTzVP zKqYy~11;>>Z*uabf6s&WeiMH_&i5bO%>zGt4050gqm0`IHMPwo?I#SV4lCGvU z+O&zq$}Z_byr8~*pG7vboJj%Ji#G+h*)_ zr@))$Yk?4YR_mev%e?2;UgLfRWCmAwpDAQTYbRXm9 ze9Er<0oT9hYHmNjg?GRA1MJlq@d~Iq$Ze#0XiGB^4FQ$F#J`HWqp2;c{-f>7RMWIXx^0SD@1%$2uqmrL#Z>lZkE2Kc)iT zso&$|)6U~}UvA>w@7}@Re(W<8lNq)p2gu=&)a{(pbt`LEb<-ra&@RqkJnhmEbl5L~ z_)h%eruV`*V-;o=e|JDt3UrWE3Ssv(@IbQdG~;7?o-7pOlt|7-?qBFe-&$(oVAP z8)te2lhXJsi=6h*!K@u;v1}#%Sqmqxn9Rg!5)sfzhLqsnE^I(tdywSiAOOc5dFxl~-H>q`|ZpMo~!v)kGLnQS#MA>Mg;8`*u@nE@Jjs%VXu&5*nDF`D$D6|goMkHW=e)^?8z3{4F>#G+@nv!Ng@%eL)M|9r8e_*p+ z4e_3{A}rE*9_sEUPo1*>vdYfloe2!(y7Vy|(Px9t7*HJVC4?J)` z>(;F!r*c$T606#xudkmo*RExJWFNiTx|uwGEy-jIC=v)5#3mBx0+^zRE_k$)p`jt# z+7_^MX%`zdY)48zv{UA$2sk^vzWr=rI()O zrOnUc!%w+c%d|5}u{ecgNp|c=a@sj(a3GoFmF{jXyzoNm+v^w_8Y-pT`zfEJzxYc% z4o47X3y0F^<{(E^{I@hJ<$%9*ilmg3`z5}dVt8njT|L{`x9KsOZdgjXZ!1<%FiDXb z(`0bVCU6Y)y}N-0OXhRu_rK5i7hg?xvY&Ekv19#jXk6S(#e!OLX@~k?fMBqeqBLRS zi##0;!JGbun{WOc$z+P5p`qD4AvvpsQ->K49DSX8Em5!5y5x|h5JJq-os{yB$q{Xn z*P5n{c%ThS@)`lV$A->EFH)zg)~9accY( z4EAni(%6gtR1-I?(0Y^_X)>;-5Y8S#tN@z0=9>3#!PVEWFPTD0=^@z31L(vaCMJeC z^@L7F`zG)QgJj(-1?eCr_AwsY&d^W;k8XX5vADsOEnBER{sb!Z2zp{qX>F?|F9Z{6 zf?&`jo*1U4+1o(RKI<%YZQMnL@Z1Cs7NhzITFG2}q<4bF5mWS;-1`Dn+pMK{8rVrafA=76MVCx_JK=OgmnhxM>I`4VZEi1*J>WW>~ni ziyJyV&UkEuFMjD3KydZdA3~`d(uy!+H~absu|5nf7XN3^l6ot|SkfEhS*0ALnM{(o zh1}c*Yj)uA-~8I9ju^P;S^DaX-MV+*h{GD3gYdAcHA?AOp-XF+WPaeIP^374`m1Iwzx zFbu}W$C;kinB`(N!0~YOC_9r!U!sZO9@(i>;Zmp#;FR)QT-T+xwvo}%Q4AyC(aMBL z-pz8r&2q}BlL!W(r85LiYzNWw-_KU~6YnAMnho*)+%biwsA1App5v^}m)_GH!w;Zh zN(d&D@`Q_aj3yc3mmj}`d7)}5t09z$zvcwu0FCSxd1|zxnKyHVAEvGnG-VWSDoG>~ zV)Mu#IEqLlgp?JfX=8$gOP8{7>x(osHPPAG=|RiUD1(E8oO|xMq|<5cxZ@5^ymTcm zy)=wznrz&-iD}1S^X3BnsQtwMkkm*zaG=9VV+?!?syb5$8o5yuV;98FWuc+W|yAwa)ajP`M56p z?!Nz^rX~!y2mvD_`v`}_97rS(hA45p9mcgrN|S&POq&uZO)k6aGCuU7Yx%_IZsMlv zZ{i)7T*84&hAXeUlv{4O8Nc)+GJ>G2U`zK_GGhsrE$d_o7>uXbpV)`b=RudI=`YdY zTpaDPapPt}p)N*75@-#!ohA~AP!NJi+iOlLg(yvmy~OY`?K!?oD+QKCWXTd#JVQYx zsjI7l>K3{OhG>+Eg3utFP<8Em^WQh{u?tVYsIK52-g*|{`XCgiD4T}ZxVN18d=TCJ zBKQCNKCZv!66_&({NacB(XF>5$TAvtDbC?c4#tQ0@->%p@6WzRg={3?hwCp{L%T5EhhC@TZA z9Gu)Zm1Usud77S{9#*Va#VZ@1MM}YhvMCGFw7tzwmQvE2L#@2$!nK^+(ZZ(tKS^OC#isq63D)L?B*9!KKIHK{OZ^L$}7Kk5T|}A!^7KYc2gwG zG6uT4nNTn`umu@vB@*#;Z&f9S!!bL_f=Dab+4n9e2z`il=Z`wSw#NtdniJ2dOKHWJ z?G?XaE5u-IKOzK<%JZJf)^O=bzvRmwIfetq0VYKmnc;ot`XR2k?mB*a{-=oN@+1bf zQzJvfbgq=Q(yf`ZWS|eqMU+ah60nP!jwi z!W1?t9%oVOayGnp7k7O7UG$7Rj~??gH8w_leTIzk5$oPYT7k$6uyxBO%*ZMlT9=TD z$NANdKEo3aKFkXb+=k->2sbSxXlBVfiktrGot$&kB|NifCyla5TPVVomtUcAMavO7 zs6%ssGzZ<)<~A$`o5Yz0MIQz6n?ie*tA|kwXZ9(5SW`1Kr(m9|(VEfY9IX&|YorS5 zC5&j^aqlkfzhXHBWm7Bs5KrSYF5#KD;0L$=6xu>C7zM3qZEfVc-`mV7ZJh*z7O{OJ zocyL!7#tiVkw_z@#59AXY(>zrXliQ0vMge;Bu_l?dp`fE&#|B>0%-OO#v$ECF{x;j zMN-&kZR6KrEX$(0KFF%otBJ>wy!nz#0YRgXNNF*V)F?+CobtPKkXZL1h4Fyvt@}!8 zr0E&iWF3e1UU4ON+;InIpM4I!y}cZJ{E3`&=9wj$xGw1)-sn1^51Xw1-)L6m4mA4v z2WV|=@tR&C{^<4M&tI$_>fSilQhkQ{bTsPlk(2U+_eBK)A&LZqB&Zb=N?{_X)e?G@ zHwiXN*0v%KL}9NF7A^&6kSCu_^5i2M_||VfM3+pHP36!P#aS&3E*Pajtt)(p(y%xX zm>?b>W!K9u^S8<9|tD9pY0uwQ(j(4S(yQaJQL%i6icFHpU;Ow zp6ThrY`N>hnIpP~SpoC358vVIi_d#*XVifrjE_%HZPYL}JdROrpmGyTPERq303Ylb z+Dl_iI{{H-bg++bbC|@&5oit_v0wOSKRX|Y;_DXj2SbSu`~IBBfjlw8!NN4CCZ0aUBDV72<`jm1fd zR;1J%NOqGDCS6O`a@SpVaou&-kxr*eg^^7p(!`1tOW3}BJ8ypTo7uW`Yf1cRmGUnH z_uqd%!^6WgH#c+F&wfUvrUugtGCDfSvi2@^WqSw(Y8e?HCgs#%=psTm%o73j5AA13 z*Fw@0F6F{QP#nh-z!$(nHp~D*6aj;DdV*t@G7>76sfsDiWbUxW8~UTu441^`xqLkq^_<=CS%iB z7vU%W{_p(qf#1^b(T_4-O7-?`U>CpSVU03oz79?w{TsUbf*{^ z8e)D&D?49)8Kn|5HHBs!j3ge7Vg@15TKz?DvXzGvhkt&7>g$Q|l}Zu_MJSVggf5cN z3a!DiG;5YG>C&$)4z?&ueqAL9zUHbE5!Wvc49*@B9T@` zbc}jS@cny!$elmOJ@3@DLz5fQj_U+qAYE52R6ojNqdAb_YO7ZFI-@-R;{UT?rI>`$w z4EZt8y!*OOa>}Kbu&kq<3S|?wldL)IICjTV2%!(TM#?zc$U(nKG5f}^(Ki|pc(kmJ zsgjdiVUB)l)=FDz5CeSrJ;!tFk9Y9w1Dg8Z_rkgpY4tmtA{75|&oFeGB|Lg7G@Sw? zMKaNT`k#A=zrW=sHf(+Ytu_DfrO)w^4}FL;&s@X94?lr+9TqHHKqBejYQ>#D_yNbS zT19vFR>GFW&7Zr46VE@Dv)ejY|LXx(y|as~)}(a0lzrt592T@KV#DUmSk-6Kg#-cV zOosmcC}yOylnHcbIP8pJgeXy)C(~a3jAeO-6ItNSoOGYMdv?vmX6h!|Qnv|KwHXtSCQqa-SKASZ*cknZ}xh;tQ=~1;l$`E;u z75$vz_K3lf)}^LFGOd!72~nc8Rj^+x4CTYGeN+pBAc}i#zKkg(^9)JeQRIZCk^~2m zc^p|_Pk25*ydw?HxqRf#Ej)ewF*xxY_&uTe%#}xXB&LLh4Jxmy1LpK7}!s>VNen9STEVEhkVr3cwbLUOfVyWKZO2u1afke zHKml(Qsz2DY0~Kl>gyW-*tK^H0kekf+k2_0sbTf%lNs5&mujPyjGJX)?Lq>E%lLSl zw)PgZ9!InU7#kb#-k>(An&aQDwaX-C2|^5zcN{8l7}@&*^9;!pby%2Gn%i^U=m$G~J0OL*;?YiuJWPqmj`M9p8zCO&ZT{|%hlVH%xZ&6C& zx;_j;<2W;E_Xh5sT{w=z&b}yMGBPsE?(g4)>!$HbLA2MiD1PsI-%D)YKKASxWXqN< z3=bz*zy4)%Y0p7oe>8~@f>0<#!KmRMKJzuk#`aQOUr#vP#6wU1o*!O$1tY1HXPaCt zaZ`4Q%j#Vm)j*XH6hjf>IXM5OA3^h5K%1b_-0_{q@pBprRTm&N% zr=qbM0<~=Ij`E#f+y^2AC~W0XVt(?YpHo$utZNMgCylH3qm)gocZducsT4v;l(NyT z!GyAz-%>%PC{hL(qMpq=da1J7D9>3`mS}7>rbS4YOxii7m8Lu-nY43M*VnUo^JYwG z($L~r6_1Q~BKLsbhwGM;%{dt5MGWI0|F|H$|Ht~G*tSh56e-aQ1?5r@izTrv`4_zq z%+L`IrGOnQ2*pvWg@cn$tzWxnEPI{juPO~5rnTqVRfDJLm{2w~2wE36(bFBps$RvT z&uw8^DU6JdlUJQWKqzXf{UlRS>Z}M-RuE7#6bGA?%bR(0M-TJrY*MKh^Ki%sgVRqv zmVf|TK*+L)#gnwQM&^jxJx!6v*%z-e@qPXC>N(_j#dd3JWOmq+OeVcpKLJ^#sT7`h zMU9k9DQIh{;DQTJp?lYh%PzAEI-XM!f6l zA&XCb@}qp^D>t*XXFFvYLLrOVNTj4?46%CoDsKGvhiPwb=eg%L@%69&lu>&OzqB}@ z`e1P@W62~_G~lx$B)^{WR<=y94yo_dO#Z~n@xp~DPv zRCQR>{{qzegS=oWsnq7VU{QG6^Vt6=#WmRL_8LW~+&!0j$c`e7o z*ZbW5CyyB_r_d0tuEVx%4{=iJu4niD9Q3$|2 zh^WlIR)cb>5r)BJI?eF#J`zJi7zRv{r?;nvn%Wjz7skh3T3Tu-%T7>*K~K+qYHI_S zhQP@>UNaLgm}iJtk^M|?X_hZM+2o(bR$7o9F)>uis<~At>_~$<1^YM;U%rQ1Z$b zrR3x)AxOnilp~qenu4&7Kyc^gGgM>HqM=zvcqN%5pY%~9Es9Dq96i7ffBa*tYKy(S z1I+Jep%THqSQLO*EY2~jS5sc%dyYFcleS`B$YOuLXT6vcUP5ysnZQmb>D#%7lTJLH zczTRnT2Y0=k_8s^!8SIme}>Uf=v=*;&D$rK4%9HSj8>Q)$FLG`90#pkz{PZ2uD$#` zw!Qc(3{lC-<4)z3T^V*yOfWH)CK8;_@bDPT&COhK#TAT<3^OkrL~Bjoj@_Jp_PLao z{N~R*^JJt95{c9?k;}25(R0)a2$LyX3b{OG{)&>Dfs59@($wFjMhZfq2!6kX5dP9) zp?GD-z-*?$isj4sw_pAeHUU_@;+v0T z_~s)oK7XKM;UzYdw0{=)=756 zrl~1Rnbr*T4KjtGO8UL?sx`8%8tu9?H8rty>n7^05a0docfE|8@^Vs6fnu=)drx~{ zu;1?|mGVNEHgE1`_3AZ*LJ_327)~ZpT2X^Vy=5K3ng2^~SSt0A=*mIv_*{K}epUYJ zAM5KMC>2Sz$|GgPtk_ftf%I2!(ivy6^^xDRX=@)^4ZG2W9%d(hK z8kNjY9`au2{EiNCk2^fIc^k)_EQuwOUUOonnJ2vaJgPh)e55f%|3E*@p-72_X_sr{g{M%;#{t)5I5o)fqurQ$e;)+NhOK{DH|y*5_X0&&RE4SAGnu9!bfA9g)fnztj(gkyN}aX29f>> zswzTEW;8*dH#R_{jIgwQInO_|fi;~cu(Pj^3R5#?drew8onWf8&MBqQ*x0sBbEt#K zlGWznXw{Ln+J6eIkk_Oozma0`aNWyXs#rn5UfoGcKE=1MS;Tc`*YVGfJ;#6c^&_kf z8WV%8U0KcBS1sd|RcDh1s1Lz#k^|bHr9Q|#_uh+XN_Gzp(%9CK!FSwo2X8v>JU;y4kF#XuN?JPGc;ttVdK8yLAB_1Zs0xH=Mu;$36(u0y z)U(gxmF{gkvVJ|s9(yYDLKc1feHdntcfaduLUo>_j;_$)pV2Oe*?_;YQmCn@5T);X zgUgPN4z79M2ar;bOxna^FSDq%m9y7H(AtMmIa*sAu}hz?)<>t49GzaG|K!j3fBNw5 zX|I@y#o~PY#*cBw9skONvP(H{M+>qQZ+LzDa~xBLJ@*WXu1gtEhuk0H$j;GG3a#gr z^ojzd@@TE76q4!^MQK{+5kjypmZBhBvRW{vHIC)-%0Qf^x(HHs^6YlOmwxaB)LVo} zmzrbmER-K+svt_5sdPF`Z0~M{`-hk$OJi*#4S@hoHcM=L0>dz9X=z|r|86>47ckEV z5FOo%MS%WjKMjEZHMO;97gAa8_YK2D2$M4H9<^yJlyu5fhosIQY5SGUW-$zd<*hAb zvqQMJWV4XXX$sjanTZ4|RxDuK&V5vR@$mfO>$kw0{tk>~M@MyM*QVlM%ys_1g>KGV zla&YxD(8K1)J8=J%BAPZQ?zaT!t!`y%7X(lud;zm0SHaeswUE(WO(}yrXr0rv_^1~ zs+2|!W2IDZGtx+Z{}59^jr21GghGv_sZ2E!D(6MtlsfrH#Pe;Ra5S<>@}r;qk}9C4 z#^ix#*RyDTGxhcLyz;^yxbya(P+{-l^Pm1}KKC~tos&`(@dGEcRHD{iSb~PpftsN4HG>+p1 zK01zrY1R-=ry)JYMHgL4INZdt;hLb4*bs?mbtSA-D(@N9O8u1<rZ_Dw~vEj;-fE^M+QEM zqfS2$eoy~V#bj1{=$K_mq?E)}4Dd8RAQ)F^s>4laon|O8%tSg(D*=K*i@X%fudX1K z(gcJgD+MV#i4d9vkq%yZX@JOrLHc*~QPAS*ni%CZDS+y1k;GQIlah{KwaKTcsf#nG?lsnSDLB*J&DTg3N- z1(_g~)oqw6gvxCv6-!W|yEtCjY#H5vWv%0eZ+@3pY@p<379*KV($h1<1@CwdqiLJp zJ@GtM2=Q5jNG8#`je4t^ zX?uieOg{19Pm$FMrE&;Sl zC={7Bh?p5{$WmrnGUg%khZf}Gbp{)MJbL-RePp%5k``qey7%s(+%M3!r{hstAK|#A z^=qNke|~D(LCwirBt^ewV>8>-9})!VT?fUIxlTbqSVKXTv|N@)Tdk7SrRK#XPn6oa z4k{7+VSAjv|H^tG3=DGVRp+6UUBWP2GBY%3n*@10mC@4+2^kWH0R^ws0**RONBsC$JIA}mXQ548?{ThDcPS$@ckeBl+S+P25!Ion@B0x zk0zbgG=`g~l?!-fYafoODF@a+{Cn1%u$VwsgagSWVd+Kw7Q2hpaFg-vaY_4Q%cIfSUDMnE(=L~CmcqJ)_2 z>m4FJ8Y7X(ko_YxMh9Jd4i;LGNMorX7G5g5lnf1}cxijztcFPlJgS?NOxr$?@YD-` zz?3J_zH9+XNtUnfpusYT4@Q|#Nyai6eAO;)JV_){jh#`{Hny;5QxB79mM&e%V-MU% zbLRrKj%>r-ynt}Y9KZ-wFqYXvt6Bh3F|8F+dbGviWRmq8USes}iAZVE-e&Q9TG7(k zNl#A?r<`>vlV~hUP-fexToFS=7#_&c*3d{pFi2L135VO57*upW@+^xME%^Vad-M1< z?mGYfX<47K^^u~Htg&Oov7Fdx;*=z9($a&LLQ6UN4*pls$rIDqNtoi8p{xKujZj&^nh25VX zk9owAJ(|(X=kuBO@j7VAxONB$QV@8I>$+Tx>sSg<%MDK-nK-W8|B=;7{TNUpaRSM< z2N&)WdvHaGGN-Y3B8X{rvkFC7mC2|QT8F8NG+m+_(@t~mhhDiK!}IaldWLWwhK5;8PkmViHm4KRXbJ$(LuBpbZCu0AWiT8O{k~i6p%8+=;$P? zQweN4OWh|}E9EfnR58uy33Zf@9w`0)14Lg_o_T3HohFs)XV1NNa%eKs>X!M{pO87@WL zMoO$_*SCL;lMg_*iCc3i&rM)Yj`>){BD1qoetXbG>k`4RAQE0pClT(v?>?S(;j`)Q z??wAc8Q=vdol!|nc?N`aAt?IFLqd4!TD6@j8+ZT!AOJ~3K~%D4XlU4fV0+gnrxd1{ zY+Va4=<#r*?NU-e`<*a>l%DU2m9Q{Pi<%OwN?24-NNM`!noBBA&2EY(MQoy!#&ISP zLL)?XtDRrW#~?nyL#9CMFi|v!ZkP@8(+@q1dggu(D##1TKsL)ZUqa>?XRl}f&#vNw z@A@I3SRZS`aV!CU{MC(o_u8-Ul(SE#rXcE6dD%Pd)l;PnWjEW2u2`{_+a(?xrpK;f&hp7&P*n0XYTyW8aRB(CkJKn-mpLz-| zf&!4$f~?j=2RHHDORwPBue^e)T*DvlAK`Vcdn>1%b{ci%ke;6KP3k1)zx0i)PMyZN z=e~fgTes6@S{$}LRVVMBdX==waVlm_1)~#L94e34%0jHznp}wH_Q=0Kk>L7hThqg0 z`NN|*_Pl?+06QWyp!~&7wz{ujrRec1u%0l3Nk)0=g_ITxcA13m#$H+AyX9(nrA0ss z+Dt(t5#nc`{t0W=Y~aB7G!OmmZYKZhPYiF~%nQ$Y7CmEC;wnp*umBSfgtW!tWSKro zaQDu=6m^L|{NazZ%P{vp^bp+}Hn4Mg4%ZB!b;kEVNccq%T9v{BnMrcWleYC1`z2g? zi+|!LBrD(3D>m(mQV1bdZ~St z^Sqay!|vT#%%~((4U-pwq84G|KA!fx^SJ)jt9kywi}=N7zQm0; z|C*fEtPzkSl9G__CZ{H`217iYnc=|rK`hbDcRv4p3Uhzrlb?SZ|8di;fTYb7I8K^?mehqw zUZ~?fWb1+zMw&;PN9ASP%6Z~#%ja7CsGC@^9V;n$^yckvV^Ls$3O1c)h6-RKDai%_ zE$P4}q&HI*7Go%OITI9cFdXRBUiUAZnV^DKgmdyX6*Tk8p%Z8i3vy+LO2KB)u`x|= z?$wk7Xl8{)P-Pet8EOhjGDTjDga6F+3RoduO|yYzMKR3~pj+>En%?i~qCvY1(k?^( zb0kQo8KPY_{4PraDH})`#5AKm-!V!}X`~Dhmu73t>oh}tNBP*vhY(G}LE%5!S8f$V zYaLp?txRaeimmBk)bcWV5`w*z^ZU`icO2Un6tLMhHui{sThL=#M1<)D?SAK}T^_Cb zeC+SqH0E7OB%9l@1W=lsBe{&HrCaM&b3R1;wcLv#O#eDAJE#j`|G3^Y@Wx38o~(Q~ zf{<3N@ljKXkQV-Z)pV(D^1|i_igmpfcl`YA{Pv%o#;eZV%1F8Z2n-}5C=nv&sfESD z)CBzc$3OPXv^_paz=dkjC2AN{i!Rk-k&x>Wa1GjwE+(BY+s=I%ZLtBq`;#B=t?zw- zFMRavbWoz?lz<4iTpQ_Jj%u+)2QKAY$+L)Xy#T%gSa3C^k|ta7ez)M3mhoD`emBRZ zSS(UE@I6}${`EW8v-_R{jNHA44qSp|o2sf3k95(PpT~7)Xcz_}6rrc9mkOis!@uS3 zyZ5kY1?fN|gy~TZR2v-_B%Ct6Qc^&YQQfqe7I`sFQQNf36a_TX5<=RcM{CA~Nl99S zv_oCYA?4CqSQnCthf5*~)P+R_lf2N(F^&*(^eW97#~`4gDg{DJ)1xK5s+*uP{Aa$P z%`RY}=+`z$zvEhxFo&Q*l8}~!wEaZDX8s!H`#6@XoHj57+7tCCYE44O)_e#ys|GdY znKw$m^4^3=G>KJBO?)qi6{J!_IF3!HX|m`zenm)7R7Gm33z{0SvkbQ}UzjTQ7BeyhV_48We6q9#1Uo^UwMqS3`KckXAy(0P3N z%U>ZJj(_o}DEW4-*ax9vmIzYybEO*2G-CdetY; zJ=>{I+c-5?*Bho*Y-16Z!fc+twSCluK~GPNQc07~=g8$soU~;xi3Ej0flZtGDJ##l)3F`a4)!xT zHinb}E0IK0JzZR-H0?5hiDb;4@E1mJmC{u~S8qRBx3vORg@;*fo|kRgM1-JSnwUbi zR{my?wNAjn+&CSqqoaR46#<=S7WEuTRS66ZvssjIoD!X8l(Dh>Oz3{T_WR#Z7LwO0 zK`5JH(NS#ZPx6&-T}>{NCElB0I$K65#n8}J?!4y#Do&M!tnF8JY%UYf)8FqAu@w}v zS;odPeE(Zl`-^&+LP51UR99T_9*SDi9ZirgmyyzH8E)0eWfpAjVY6e$88}XXno=YZ z7DcUy_cl8SnoiRsF_iKRurx)bTX4OIpJX=Ox21e?iS)~fn8&M5KAHOG&3TsU+YlRdh-P!@iW{ZTXw&_IDFdO7lnrz4ZON>9kFcDUmYBH^297hKIMZbLUR3c>NU=tI97bcu*=SE#gvu1z-Hy*Zg3p!Kc6U zbpU?))1PzQb=OfS6i`aHNd4Zr4AQa~8yn-(|NJR_f6J|C?Ny2|e(C>42+2==ay{>Q z%iAecy-Mle;1E+|qllzQT$+rHP4a{5Z{WzGLktWI@TqOvID5wq#`cf#xzB!Id+3ar z1cFekD(b2^CxiZH9sL}HSU!%$F`-sZekD~LB{?~|i@eqlSeEovPH6pmtvXJi zTl|+8KjINdZWEFteCc{AC6=^&qP^)qW6j5@3Mq~X?OOS}m4&6p8ly$62+`yTIv^x* zDG3TZDOf|aAWs3k)N%N8VQ6~!&&{G&StCMF6AkZ}J(2^Xqb&*IrPm`lA_lT6LVCW4 z07ggmv$or0&wYO+JAH`a)EJ?dhmdJBg>WLmGh#G=qED1}T`)Yw*MO@DxNgf|rS3z_ znozIKWv5{HiemZ9EctwnwLOCL;Tb})2&z;<2*E>#4&mf-^!2YM;Ck-$b;Iull|8|v z>FG4BG8C3^M<>o;zpBm{NCWp;LsK&iy4wQKpik9>i%cl43Y zw-M1HYJb{8FwzAWEY@m7jR>yRtP00ia5bTLm{=^v)YM_t4WG{6f9mU)ZkkL^;TZR` zda8p+qzl(|i5d~?;yiT&N+rd7X^vbj$J({)*|>2dhGB5{@L{H7G0M3aKK{WE0-9K? zyS0$ig&;FN-nzy$rI0d4VvU8AqNUuSHKbA-a2&W_zIeKM1k=Dd{BGZjr| z(wL?skw~yE+0Fg;k5a*dEybk=6V+N%mYy4R!EuQCRkw(g*p7{ZreRquXuxSE&r2lw zDj>9=qT!+!KOe_Y)KrzS52rA!e*XSrpCnT*1CkCYsVIdIUX{gh6rE<0H@@dXt@Z2pL4khMqPmoO06(tZC2TrE2J&&>K-l0{!2qXmd@vR zu%so^*T;YT#W9OG9s02i6$4Ljom_r?%N4bn$F*&*z*AFR{1Op@iq^!X#jIm5yMIsY zTsoFP?w15fcud3LCgP&3z1iscX3j3YAIhV6HA|QIk&@QOygqsf?$(?GT5H;?+UG`V zR^b=*TyKz096Z3X9HRB}BVUtKGZ^gxSC^4euxZmKZoBz9jvUy{mW}J#b6`Kc>o$6l z@dnJ#&k*T~u*z2hTQL^gmDg&KrUIC!{)KCR;rj0y)D4&U`58)Xoi%-HNey%Z2B(~I zD&?k9o@r92K~o*9X$)yZ45S%GJCIIKlkD|WCl~AjR;r(xU&J`9)3nPZ>xISq#3YvJ zX3=S*E+#OnInENBxq0VptQkI&F;yk2^F)!vMT7OiM#>~dM#tz)CU9&UDK(v@#h7g~ zXqn7Ant;*_$|Q>dCeyo!OGt_!dLl!wwUrrXl*MEMr6g@6X-KHpX}ZvaM3PgrhI9tg zO0s}Lr_(IZjbp7P%H#<_6OUB@T<-JJ*+f$?>qjH zyyFlvB}(Oa=}TYA{r8XY`Zry{t-t(t7F8QU2o{|nU;W}I`07_a#oVEED=4vsk{lix zp)1+ns-{ac1+8!$n}8P7MGSDMI1U?QA@}JA?P$svf3d%VG~OYQPrA~HmPa><`6}#sVc#| zR&)tTT|gO4!N+SXk#`{>QiNm`M=SbF6D>7$t#PwuqS8xdqd?WkB4v=?-d^Skf+@R< z5HU>CgFDtmkX2T~yQhVM$IB8Dt(`v;^Zn#?tkg0Y(*@gU1vaJ`A|g^GlfC|$YNM3b zxjJdfAY)^bM1=4qu)P}{mnKE6NTmkRTCr}c$7K^jGM)8E&kMHA`b~qRGif@2b-hXK ztkdEPnL`$V{m?E2QhK=QrU_<`Y0@4N%uG%Ym!=nxN$LB;cuD&X>kJ&np?k<8E+rF_ z6PTuj3<(zeZv0Y`sGo2k{6G1nmyKsHnee2RJE)@l#Je-*JwF2>fz*<^(x{-~)ZtAl zU~2(iFm!iiqi0jZ1S+^#3m?OG`a@Yj(4T^?Y0 zoGHDc_%Jv)NLRRnFMj>oTzcs%a2&^jcuI%}N&ToEC(F7)NAZ<88mz7IXU++&p{5lY z*@E;QOi$1-rDry1EJ5unf981TK>N_Xl?rIJpdf(T>XWqVHi%2mief46!LW|;smi$qQe|hPPbCbyt6bcf9W(NKf0?E^LTISa6pToJh!6`XH8+ zzM2_PC$MA(xzt%{c6Jtl{{GdJa|VWJ;A%MUyk}BDP*#e(QVb6d`G(>imn9f6aEmUk zYY>UVnV-*b=9y=4WNZRQ6&T*Sh26XNU|CTDcu?T5ItkbAM#?s{Y@nn?Rj%cTo+P6C z+5GHY4yiPYqDm){fMZaTK~@dA*khVbGw2mmkt{lC3Z}*CE&UWHGt5cJYVFXeZQ7N? zX`8liM71$ZkdEk9)|R1?2$CyL&@H-IbR6asY}&Mmic@9I4B}=BG#pK?x0j5t>5sZ3 zsiO*+6PUu{gvM-rxk~_#Hc|~XAumn5W2Y~%snBT0QxZugds~FErs~InZG+G)sK}z@ z&@O|1>oe5CJihr&Z@|?W%QD%q<7ND5=Uoh)dnQ+1^?AZlaQ^w{vTb-PBm4I=Iyy>v zdK@!mvUBHuVw&9m3=IvT-6FUytAxRVc4-Gn+NBeh)vNn?_~9|`+dGD!%0Rct?SJ?^ zU15VnB!XQm5{|?Phr_JWp3b&Cb%b!(VE*t3Jv}|#H#0@;NRC`CN5|9=+UhPHG)RQw z)a!8M$Po;~py1{Shr@)!al+v^9SHKdS=yzboXc^`Ew?av=pdW6olHo>+6_abcc-zs zO#&|L-hDsA!^7Nj$4(sIQ|1F7{UAU8`Stwa54Z9F?m!X0vKL>-_xZ|HccReGX9!J~A`Pvz~e?wOSnr__VDWbBFHZ zo$vl6Ke*-^rfi!JfB3`v{`YrsXmZkTOKU1ZvtXA!$z5q7MS`lZ=|uCQbGJ|`-AOqt z$!!Q>=mxS>A{?%e*KO32QD7F+Y2&oB2T6zmou)&@v=~*Il7KGdaPj$PGBGhtMQa?j zRK4l5EaIUM4jR|C*|w>d&bA5+D$>{OqRN7#<#^ z>SyJqX;Rb<9RjAa8EQVC#5655n!E45hxNmoaNRm%W0Q2Y;D=ta(IJy8I^OX>_)2U` z2?|oI2uv)ise+@PP{lT&PyBEH5-+7RmL+|7kz8TCn(+<$ni7-UrUzwkoHQXJIC&_F zZ9fRa=roh0)81NvV-r>mYo(8m)(}AX3o|5y^c}4QvyKAcsZ%XFX%-!ab;E-Qp>eeW zt*8OrW`nBMOiqr_X_^cT_A-?%5SIyZ%E6wF+5%P)Toou+s19LMosp=H&orjCw{dL2m9q+JRQ@Aph!)9DP3Qzn&4VhJxhBs{@3VwGJCMG>oO%wSj$L#+p9gn|MveN8$G!uxrZzL&% zz%)%}C)2bG&#Oe06}qbV{8zu=dG7cS(k5g>YY!eGrOC0>w3d(6r2tp_MPZ`<9WcC( z$JpmD4gXpi!uqJkE0+s==F4B_^{;;&larIaNDdqson-CM;0k%}qo40m0(x}mcd?>d z(Jb~=IMI8nAM*>=#L+#rPV}Buj&a=r8Y;TY^OI`wZ^9(_>oOT(bqaAYd86ZO4Fz7NPtz@H=bd>06KU`Mt}+Y)kqBWU zOwsU?mTD2&+XCEi$L+l9%J)$j8zr4iW13O_ezy@;ZS+||7VP~jnl7_uim%>ugrDDD zhPg774#B#Eyz8=ac=z@}jIlfD8GJSue*D+`wlvP4{_)kcX(%a&hU2h(%XZ#$&0fCw zom;r^6R+pwA%&DsiuQ6(CdqR@d>1_6K>!iZA2xaETb{zpw+vy8?ID;P=I6KW;f#Oy zDXclmD@q@k2hG+uI3;BN)OU)EB2#Dv>Sa5JJ$k zwui!Oj#{Hez=cMmLbV2>4U9k=V`C2^M2M&nVdKV=*tKgfu~-keT#iII%)BnKDja5X z??J-hFeh&qqNYkr9vWxcwr#9Rm`u&3aq^1M(L*GYYw-LRg0yQv%<3kS$r1{gY(M!_ z{^_%yq^2~#`t^Ts&grM~{Fh(C*jR=Q{k@!a+G(7+`7{n4dH`^l8XF@b8Z;UWpiXDI zL6;dv7mMWFA|dUvP{@)_PY^dPF249h0UE?{B;2t_{IMq3mXMTv!MnblHKa3;v1DGPxkAnhn#XeDX5bq-}Rezi&aFci(f ziBSUDAernX?PPg)M3c`iQZ6ehz7(^NOP#2Ri3zrC+QQAZ-NEqipclMJj|Z^m!xjTV zw6OiFEQ_4uk*K?p{iM_OQXr>19>#)gvtWagf{HMG9*Pf#5`sk^`l9p_3`6+A=6ojo zq_sBwy8^PNPl9QhNJ)#E)(oJelw`H0j-bcvg{b#{R2oV`v!UN4U#=1iHYkzDB18m5 zKr6xul(eWxfeiJwppW%(fvV$BQx2x(af$i|dkKY7-2VI937DXRCJhlp>nauhkrokx zTDjm!6c-#iPzaIYjyvw=z3+G@M`mYQWPhdf2|*W*zp#o&RjD6ug}>;FRup}>tZ7Q@ ztOs3emx48k1V8!3&p7pzZCoTTMr(!bIGCmfWo<z=Ma*XVUbTo}Z5plFxnlQ~bj} zT*-9SZbA6c=`=mwOl{r6F3VHTtDxDqbrYdbh*!VhA_}v!OiUc)!I3d6%Ocq;(N)Ef z(a9Ec%#&UA6wQ*!B*M0N_S0U9)$vzTm(oY= zRyLtPk%ZTcwX-&T35yDvg-6K#wo8w%1P#9+sF!tW9^ZF=WPtsb?5G?qU~VQ!6*L{k zN&cV6x~ET|`B{0w-*zc*Kblmw<7h6u^c9SZi~s`564aEYE1AG?>=WSB9P9b9k`q($ zuW834;8rK{Txk~);d26o^!Ua7rUa&1!D7cUcv&-u?hwJpJVx{0FIPW%q$Iu&0;;;z zsUVjp4otd5AmYDoEN_0aU|^F6#t4N3?d=WL4-awGRiEQ)|9U+G-C=TbB^vGU#<#zj z5B}fxbJaJ$ftq(&bY0dC53_&&ej<^`GKg1G5_!4FqjzkNui_;x0T-`Bf=dX<=N-n! zr|ItRC!d>V(_lZdvx>L9=l!f-zutq1i7<7;Wx>@gVSs|`A_76O)6*EfP}1`5V!MQd z-oT>cP?awA#8#gBmao9!7?d;^dFa^y2djMH9eX+a$~Zs!+jGg3%l!5s4M%#|J37X8 zD@XxISSBdVb?GXszkoY-XL!+Y2S-9lK7Z#CKJ(4rfw2Lk2{@qAOir16?h_My?(AM> z|MncZ1bpPdMTk8e#@j&KAO_$NP%1-rA8&lsfAZt6K8NR;CVAB3pHat{v$bI3m~$n# z1pioiuxefPpdh1T#AV3unxwtTnlOD=V#_Dp7g{ofx7=_e=bwMhifXM#DD*fPP40>i zl2S=CJ#BN&v(BO}1PiW4${1R>?A!Mc8#bK8q49@tfPMQ$DY%dfhXI3l-0(4lPz{G! zyLJ%0+MolMeC`P0aD(;hhq>#n5yFN`&+2|akjc-`Z>*(ID$yH{6ATMxXJ_f#xQVt{ zoPgFOa^B!wa9u+2IOlBIfp#^Se4cV%u}XxA$HQptsYV2}roFEZ!*IzS*4+MwyBHW) z!zshtkl`4~q{p{dmrQYRVw?+~|9p1t+(|My0Ho<37-DoZ4M;{Fp5~qJd@B(l$>;O@ z`!8?gbyr>qcm({25DaWwPe5x{8PGS_%a3ljh0gYNx=fSl`5d$JIaWvF;1(GlANP|; z4=+1CJ;!`HO|y&E?5ae4C9$QX@Aeh|03ZNKL_t)AM^ICFqEs1m9BQhKRpfyx1q52B zS+EUO=@Jzzgb>U*3au?VgkaH5({Gu?l)=8yNgT%^oa{vi6H|(oqpuJWX`0MB4u+Lr zWMYi0)+kkG(Q!B_HAvR>)X&ms8zD?~?b^$Z?Pu`7$cV2B;lUM^QY~e!4k5^?GId8$ zK_X4>ag$S7+NC74jEmJ{ddhPd<$2Du1z{Bl8ifLJA(+BbVC%qBRkO1;^XY6Wa4Q~% z?D#)9L0SIti1TSbS@A0KsZ^>pe^>YSv%d^qx@n4kyK9fHF$^fh)(!n!w87#f+t;#V z%O++gN2qC7HMoTZ0YA8Vfdknr`=^gkaXcQ&QwJu*V{{^oFS-OD!`?eUd-!X|7r?_0y7h7R$1l> zY1=1KP1X9?0osXvM#bO1?sum=zMm&9GFQlO^9?^Hn=O-b9JE%X`ctT~)9Rvl6?ffA zAXf>~6V|Z$nVFqsI-90Kvw&o=E}3kp4tjza9=W~Kln4#B?LoEfyZ2548pg&Zu`F+m zZwA+v74^A$01OUJMew{$%+2+168g6 zBIhTBR|C{SAVmYMJ;~RkNK*8RLzWMdZt~+iF8Xf$J6ao+CkIp z^UVZEfe|#95utT!je4Xh>xuGe>MOV{9CaLor36=j0gGr)X{*HvVcEY+uW-9yuz!d@ z?R$W)eBv|wVdw4ic6YJhy6iaPY%=*-9{AHk$Z(9g8Hae-q*N|3J9`8x;z6?NhC#q5 z!z}u#Nuc#U)ctd4a#dU);2(cz-A1nc&Na+y&DP;zip3cYkInk$8fMr1dx%5~YNe8& zTzNuIiw1PM287_2U*E!4q_-Z-Ok`M{>P0K%L!81mPJzKQp32bW*Ft^+7->HD#fx~> zP?3OM!xz8zUwrpBecbS?4Bt7k$a!aM^e$;wB4w0-c95o|=A=R3L9A!1L(0jkgW4w_tec zwdMdX`P?6wGzNI-d#`5k*2`c_J8Tc(SqM+M?~r@Q$4)!6OF^Ht z2CX&Wa15>C7q{Nx1%j64^EnJwr&5@voF5$4iAcD?& zZS!zg&>l9}J9PvdiL*NF5{gL*vx?r>YOKBZE zr3Sd+hMRoF9j^m5KAvUcR*Pbx%qgdw&O)}pq?%ys>8Eh>4L5nlT6UVAp<#+zbK9?e zMc3avk60|m!y~(?_<{j5PKijQAJ=tRaG?gg<_-UcvC#=~%HtCa46O01Cc4E5@eDtg z!Ul^UdJLL){w=eduWpn zwNiw8qh!Xa#6^f%dlI4A=t?GN7lMJU+r93Ol^~hy=ivS^x{{tmb3}M#<9O0!=iPg- zER$7MFSCwKpEN;Qq|+G|Rh590t+6!eIJEmob1F5+qT^xp>ssMBHVwd0ux`sBzr6DZ zuf6Fm{9)Y3z#cpsUT>RQC|MfH*@E` zSx_dPahL!Z0HcF1{Nf(IAZ*_M@-w*dqLXOTkkJmNFqxd3q%H)hRFYZ$9&4?i0D<+% ziGqZXJ}g$Yezq*D<*igvibHDBhgLcCm=<<6&4O*SI+a2xkMN#TO-P>f6AJJ9&1&!A zB!wqcUPt?cc-ivMs0-*cJxH&RUV*@IY$_-kj?bfU6v?E8ZF?q-9=FbukX>{X3gvg- zyfIQKI6lnR>xlIwEuSmnB|1teI;8o8$M0j`KmAt;R3H2IVnruqsbdKNU2Tzyr3}%5 zCp6(NK*OE!!(N(67cD%nnf9KJ7bFEj3Q3&y9_)il8c(k=``Tcz?bI(VcvYr^c z@QK6vj{e=7P^@IK*M~W2lF4LC&e(ArB0?T_4jd1jCj=<9T*BMy&aE7C`ndUbM0lJK zDTA1pl>Iml(;u9;t&YkQg9@(Xsw{uCX{d(0ZZ9Pb;V`Z)p1^0ilynJaW|DQiUF_Yn zheS9|spOI5N2jK!0JHaxU>F8r5h4=l!d$(Y$;nY7kw`1ycvNELw{M!=mc>UL*Mox@ z%*@OX>+L6o=AqG1273Fc0Qt-eiAbCUJi(=6u}GvV4nVc2srvpeZ8evTr)@;3Dgdce zKRMrgTS`fZX&NHPLt~4S_NF1G_{e82;Z?~7JrgA!mUr>BE6?M*_CC0CH^2S&U0nRk zFM&`HRtROVekjR=f~b^`2zfWM&mtg8RD{Wwe)s_72cWOPW*e!kceBdDWErIPF#^{SVtlqY%X z6bdbJtr?9{FPFLNmfM)g&ymmPIsg0%uo6i=bmhmm@>Dd^&KcV{GI5aif8YaL|AT8uPmJ@2-~FCXeDLlm$0EG-;xl>h@G9m@Iez?;@6x8aSu_P5(xKsKYC;m*66G5sck{uI z%tHJ<{77k@Zo-RFgIsvYdD!+ir*A!z)vlJ0i4=P#%k-E* z;&K|L92!nHj%Bf+)AVYSlxic(IAt+J2MJa&!U6&zOzJ`~t<%(nB&G#HrEyKkDknx= z5K;-}XBgKMUsW=W8$D!dq^h1HFOMKKKjVZ(YVN4Ih5*br3!qx*I%g!!#ER&7H*2+5|NI?>!Yb zDI~KR`phJ@T_7%#1T=)vgwX`i{v*v>>pWkmrZ1H@#|v5$w~|cRY2SF&`x}i1$p|Px zrwLhY(`Nd5_?Q@$BrhN-6yplwrb&n0Mnpi=w5X6EqjnMZjT~!wS>;!X7KyjblsIYI zQ;IPyYI`~3fSXR=`@oB(rLCz$+U(n8lfEuqQPdL?t93u!J2`h^Z(n#rf1QgKBX{akjLI`@ICJR|b zQG3caIi*M}leb-I4!PWW;=~IFj}<@*p^wJgj;hh%9rUUhYOM z#N$sM{<_^2-I8(-X;u`y01{GgK)6(hae63Fs4?11 zm$^ieu#(7fmHiwdr{F1ifGC39(jk(Fvc6D;M39D~SS*xTKr-!nnS?Yn97X8~ik&>t zX!KZ#V_kSKG3{G1G~w{jy!Xeue)!PNM~|zxTp|_+^rMqveH_{5fY#Kd^u1HO&PrW) zo!rG>bLTK!%lvHW{+iVx8eU;qh!#8wjAalnZ=Vj9AYYY7C0||~SPdzlgi;az+)I=x z`EV}}`qfm-ibRZ7XTmTH>J6x15H<{Qxl*f;Y#5&BONTaa4X}$vFbs;tdFrk~)QGU? zuH>Gyhr<}!_0?Pr3jV)K$qNKrg8&{sWf7OvU0pOeXI7*O?P_M{W{8BsEc)jiFd_sa z5sJl}-=Xn1{I2U#K@$vzeFIH_;}nScld`59%BIUYy@vnTnSmY?gys!rbRkAYcu+co z^akv)DhJItFe_$_pEtsZksVdFQc~yp0RyXtMX-}PLV1ReL{q@YJ z(>(CN16=y*SMlqcf6eC28`yrb*Jh-1m!}DZsZ*Qkot1&sHSidn$spJxm z^-wF7*n1?8VF*q+<6QRa-OIL(8_DF0Tz~yFwD~!@FhWevmxx5--1>)`i9{j{4-W#G zyYBi8n>U}#zJ2!sVeUNi5V!gG$kR_hon$h}DrqvGo*H{Emt=bUpY zlam?Do;dsWKgb2;GFoeTd!rnl9w*w<lG9V1pqc}+DNug zVEc~kTzl;g0NAzbK7R0nAFzG@QS~G37S!;|{J?|UH(r6K?0|!}FeFamu3a;9z4#m!ojlJw|LLSsDH3NSxbenc za&RI|rx{{AlV;9La?QuC;o=Kkz&X!9oBj4Ai`pO|H&c~SY7+-YB_*9mrl~Sxr7)Qz zWKWPYgP!@K8fD5B^rp6BI2kI~tV)KcsW}SfK32;Vt}PMDU{Mw5w=5h-QxPd3{iIZ^ z>jH!yU^PkarjY#eO*4?&$8Y}iSv;$^28BG0D_=s}rT+;i&VS}QCNEh>{~PXtDM_J_ z;Z5KEJ@gH8<+dCjc=vgXs{z1dSU`Iw%hkOu4~esQ%4@#~Q(<-%s#yJ-_}RaG3&Iw+ zfBz+%+dIb*r<-v3KEh%%-wH~Qr||w;5A&&iJ;0T}nB)I@`3ullkNad*3y$A?Y)W2h21z58Lsv4vczT=)f?97c`!hD3 z(qy%*NG6ly(l%p0Ja$Q%*W-RoOzdw-_(p{EDr!Qo=-5Prg;LPa7Hdq&%)|%-$tVS- zX~#q(C|f4QV4kP;N(zN(MwFzk5iVhMK&HbD- zm?WrNWTKx^Aw#1#NEZqEoIw^$IP8>(NyW)JO*NEak`SNzmwPFhLv){^#U0Cb}rmt^4YgvfO2**fM8xr>`jBb@uv@Q!(HPb6)#I};h+9? zD+6SxI1`MasYJK)`hTl%&;D5`O~BdbaMvYCx<v)~d3;L5{b~&74em` zyZ}EEiO|#2(@J0ff)RtT5D3GAU4cu!q+4c<%}$92y)urfciaKEhC$sBbh=(L(&VUk z&@cb_=R>!0^Ya*n;mZyeF^mY2kf-pfeLl+aE)4$X)C~w45f+O@VzJn=YuZ@J%TR6f z^!Ic9*Zv)laH>T|p-cruNe&TJ;5hqfmnKh1C79TAn61Nu-q$xmT>rT>T>s^L(36DH zK?qMnco=jWQ?U?bWx=csVTY$~y#OW(M65gq3VH6hb1i$L<8+vD$kZ4XZM72<>*aEKUXs#On-M|DRiFI~-}~M*?B2Z}DTPlc z?dHvIemie}`#b305G9ow;EiX#k@tQ0!>lp{-Q6aCdf)+Ku^2J4o0A5hqQi(>RL9JGzy&bx`ya}~# zT_4@u-Td*7|HX@6ehH(8_E8st9UC@#-IJKf=%G>2nmhmVx8(DA4jkCS;P&lY`oc^2 z(f?!a&BNO$&o%C!ZM|cAM%GA{yvUB1*iP*18-zdtgq>2LDYUFDrKJ=K6nc6%r8|eh zVJR&wP$-2$p*^gnkVDwZ8rB3t7KbEGVmr2MOSUCTBWp(Xyt4fLF|y;NVQFc<@6&bV zif!3iM(@1y+|P3_|Mw6rEsebL)@!`<%nN+$I~Q}qjW_Vqn{S?^;S5F%1_lzW-@Khs z6k1xAQJ|{4`R01QbLG{Pg(Jv}#8<3x%MHIm2~=_Ky^oSeSX_AFrCfgbcXHiiolzwH z-Hw(dUs@z{G?m_{!I+gM8}#E21{nw^NnxR)QUH^JT`2@YRT+{3Fc^|ydaNiuT_V7CasgBMAc`6r#~6FFo@tO-)S*0W)W|@XkB$aQf+|^0znM;3rr9 z(AgZv)4boBX7(bTC5L_RroOU~5yNmi+bv1C9>A9rv33ec-IvfYCC2Oo05adU7- zG7wHO5_LwV3Br{93yO`xT(L2lbK98MKwK`t(_IQEI%XiqAPLfjfwuD6%fT<9~1MkV>tI-rsBE{Ngj*vRb42G(`-lN28OM4>Irw7EeJUbdL`dWY#- zw~=`(4+d>M)Hide#|0g&jEH6QszC~*pe5RkFt%{%NvpW=!A>v@N-c;=Ngxo+QP{$$ zs*di_8IBn_J%|GeoFGvHX;}mUL3*POJ#5r+9KzZ=c2HZ}NLD)Z1yxl^1H1L*NSP+! zDn_b~EqZZAP$_i+=)_fv0mDKG=rk7Vw0E>40=naJ=EMk49}LnT>PFXf;#QRMoW8F- z5Fli1LDy&Dwj4TEMQs6NVvur=&OoS}sNTq&XgdXJfFJ&;mt&4Ph?V+oyduqpsFAZS z{^*;ot4PZte@e$zRRfgQc)0$Sm$^mgU_I|#Q>-!w`W^6Vz%*u2Az=f8vs?Q3<9Q4C z!&bp}fAW~qRg*DTBY3~Qk9F64h2gdy<}UK^jlaIm^UsVjL*317U#lk+%}~B*9zTC- zC%<}m5cS`$bwV1lah(l%Il;%Z)6 zvx@mv2h|M?DCgb}91a78K!iuV8+r8kFdg@v!8l!%G|Z#%!WUqd2Gt3NN@Rps_DDO! ze>s`aj;$03fmBtBgus*^4Im5uiO+BU&+tGKtNjc0&#nRb=yfLqWSMGWG2uWbrs(57 zo?f*-)vfqr)>c-GLoP%*`w3LBf{Y_BD9AWg#go(?TTqNM38^TpK-!X_93XJJ-DtTu ziGhIulC}-0p-DgxN~N4>N-nR&qm(-OlLOq8DPUz}a-KQmo!d4jObY1%itN4mk`cub z-MbVe_k1u_^glF|!sX66i`foUY(#OM&!f1}G>skcK~z=4l$m{uMka24q0^mC(jx$G z0Q$oCT_)SY?F@-pf`G1@B!tblm_=o95qQR7upPX$Ks!t~K~Ll+dgD0`rk7E>hzbBx z1FyxfG#Eppyt0%#ZhwTQAJ;*NgSO3yo)~z7ue^N*gd@R@&mc3oqr4JMP9`RYs}iaF&yUQP!?q%g&v<=D3gWv29xyrfKu`JDVLb(m)))=A);l2h&b5yQYzNJVb#Vp+E^y z?W>^JJx4z84YFAn8MlFPrk749)w>n19mD5y6B&pQ9?E0U zp+^vpOGY$>G?J?FGTfR*UuP#^Q=%yJMFtQ{ zhkNcOBQxyWx|I(;_<(imwvrX&{N&o3*b|Omr6gwv)xN##w2u#!Du3K-z>(xml4Bmh1J#5>? zFbpoZ5zy4{!09yyI$|YZ| z;ErQUXbWwjq+tcu{dEs_{dGH784xDlyL%J&{OEL!2znSX+G(n(WOpd)Y%u?(TP7np zbxAQ#?XKbrmp{Sw+s>eBuFee`duUzT185wvbOEo1GVsL9pi0VXYB(-1%6)s%%(?4r z;^&-%S5=ui*AWRPX`oLw^GsWY_ukkF-WI&`Dsz*e?XWA#Op|G`G$u`c$sbx@QuJrF`r-&{l1 z+DmyGjyf0QN;QCCSm=6yQ3TO&i~`j~nbk&hAb?Cp=?-^Oq6ZN&KtrH`p7vq%mc8lI zBT0kChDJxqbC@;&03ZNKL_t(n7K@S4)AI~IUwm7*h&v7mm{1BrjTS%;jeM{zp%6PCi+684f-*y;@uEM1x0dVv^bY@dR0%UxNlIEcdSx*g7Af|d zAZI^?5-ocG5V9|AP#oZx%TL`@7UJ*eF&__fM2=>*7nJO45iIt}W7+@Z6@JPAkr2*j zIbjbiW!^uwAST{R=D@#`&P`Ozltbq#EiIiaPUAy4mq+(rH?H!E3Y6USzd%#)YZ@a! zTU!tL>`j@Upn4VMz=_N4{`)=Ab_DYyfCpvo6b9R&ZJ}W2z{kX6WtkdGX-~dZk5W3R zbD3B#6ZcQ(V9Lq@$c#MTl*wf&ZrK2DCn>R}F(T6rI83N)6DmsrCix+g z3m4BrcJ<-)Ht=X73fq9{C5%~;lXX8&m%E{9oS}=W@J7;n|96}D<)$cj6WHnu@?16~ z{{^Zyq2lobNb9;YQ4wRgsf|PkZ3Y6W6rJ%?vSsX(m{| z{!Ln1TF^9=wQFAm#yRMq!|>X1PFZ;{{kvaBh!GYZ@fBX$9_FpLKBPqRk+#dpnv$wH z^^7DEoUrm(-hFMY!>65l2z7N$3>Z=7G&OPXiWSt>)?gS(3RD-m9suN|hxkMgq%(n< zuq)Ncmrz<6#7H^`(xW+BO(~rXcPwXJnM@{gj!X?X3tp8-I*M=!;%RHr{xxbv(E~wr zZ-4?RnZ0N(kw|n>&_40JMs7Ng73w7VZS)k=+tEg`5R?aN88O0)3h;PpDX1)-f`@SJrULEx#sh8WYP7O=!5> z3Qs=yB7=i}CR;Gh@9+3M#d-y0ZozH0y+dhfEo;}l%w2c=nu>~QN)*BWwzfL%9d?R8 z{Q1v}VAKECe#R6SOWBN#NwQ-Znrdfq-L;oft(4N!Gt3hY--=!_3z0IRW*KPE^FfSn zUtCQ_Y``y7=*=VO36e}2w5H-5($`DRwht);-ZM@7)zi7_cfaGz^DZV&*J&}JPpHg) z(4{L4p`uU!6w*K$A#bjE1RA@gE6^{j*c)DEW;FopRtf})=XiJi#-|2 znRBPQ`S=o^`txfb7BlOtSE1VFSQc7v;z}LGZ}7Pz?+5P^4xhaTA-cKtdrjPTBQAQKLkM3XSs z4SEagPC8VyUtLH?s11qZfHiaOT;fRsX+*j2zI%~U($Nv2FefNCEQ3I04Qv1Q9<8k( zP+M0^A(F~s9aD`l3beL5BX+~EIQH`=frQ)F4HNW^aM+@mWOd1ifQMgvoYEYy8GF;9 zT-TlAK?sB*uuRF>XP-_a5~DyBY;FtXLLDu3b%&^}Z6KS|u(+%M3U!b!5c zoSdE%?pIKK(nR8)>4+B|04RJ^;NM4e9HspK2@v_jLStW@M&XoWP^7Ay`FcNyS}=F8 z{h>2xNv0X--oc`v&iDi8l6T~t;H_m-8w6>Boo{pR&(33E<%shc&u@e-*c$$TggAn$ zABjL&fLHE0oOzZ-#$U`U_g%u*zIQ!K=UqU)?jap+r&!goA`R(F?E#zHrtb`S5R- zP#W5bRCV^3P8H_ptDi<6C#A)rMRO=zRKcFDV_@`vaA?|NQ_PB76G4v!>RwvcL;`ER zfP$O@(B4RUXCY4d`|rm|9mN^@PK2CAqe-L$!$<=5+oVz`%vTr z1;VlBojB&D0iCg&t?p37anl(v3@ppa0Tw2$E3-fE1fVE8Dwy zd~gp)6@;L=O68kP9!^-=h=&mMVmIh29hQe>ryRl^j|@@JU&{6hjmo&BsIrFg@^U&- zLj)?SsVSevz`y{uonp+bQ6d!lT1$>E3R2pnQYJMujTrrLT3Y7O*U^Sg(-@XEF1MRH zO~W+Z*f!Ku_=uWuD$1Qq9H;9cQ3O;r)=(Jgq(B)b)#9Z%9!Iky7-Bk7GYRdsNu&=Z zp{l$lOfUxtWTrESVA0QhK=S?9sH!R>*4IgOc{u}vywFpp)c7@*40kOnk#7d!MhH? zkX2x2pe#rG*wYQwDl5)f%InLk7_p!|ndU!_n@+u_n2Vn5gl$RCyg(X+?G(uGwKLce zY4p?H-cG<<#X!Pf{TuJHYSkBV;(CjvOJ}liV<(Lb(+T)1F_O+0L@oAU8fkQ0;PJTl z#a(NlHwM**ILGa*GhoAZ=rf=%16m_^gYfohFm(o_7JLE)-!VVYbLYGBy~M%@8Po?G zdHb33Iqb0eVde_vEw12XPY*83O@F$8BF{{8sba@MlvOtK%+?GH#8`f819(jISUc%T zoehs4&600E4b~DG|FjFGu>l_4M$xPw7=n^?5_&B-*v}2ejWH&-@$f0jdGoIIJag_` zvR0T_+Xy$WoX(Sv^${A>Fe@z{ytSTlfAO>fas@p2qlKJP+soVQhgtq;H=xpf%M4Po z3{@@3y*DTSYs`{Vs3O<&`}^YQqX5Lef?Aaoe_ym__scaAp9%o{|Nk~2Hs4=#o)r#t z^szTOKx!Oygo_ptW}rKQ)N3(>i4_Ua`o|M-1zl)X2YO2}-&*@c%uJSbX^p!g?XW?E z#BRR6xRi)xfGC6dVpcu1iR79wkWr2~x|w$$`Vm$n&46JcMSy%uQWp%;V}w8BJCy(M z{r|2I-;WB5oCUN;Wqw*@qR7+IzncHZmusS8^aIdjJ~T z1cl3)qPQomjFritdzk}1Zic0Uyqti@iAQjrFKIjVZn1Y?UH8;;q)2y+G@5ik^nnuK z%*&tV_1jKHb!FI|cJbcUVP1W%12iwokEqD)Nx})wq!cN2N8ch;1`SDXR}#vCY#lTx zv*5{ds`=vAp9k{uO0=p5e5xHsNmH>iINssD%5J$MLH-) zvf=V0SaR|ILiJIcb#I(4XE)O^847(Mu>Q#)e8jLw$|MzP9;sN;Id(ZSimB_}C3798 z!YOpFiJ&ontTZOY@e?P&1X@>B6*-Ai_8S}Kki9RUvnT9?KvoAT+1B2Hl#*aj|~=P%)?qn7jGhug?1g5*GgF#%>GPM~@kZ@lpa&GY9od(m97(g7N(0O3+6 ziza~j${?wXqXkGwiK^?2N=cFKy!Whd=ywIGKpF-CeJVa-$evEBs>|`J8li;6?1mP0heDJD0@OF0#5Zr+ z4&D=}(fhdm^x1T-e~SWDr&h%Hp9}n4zu{eksA9y(SdXp;xc~lJnA0?ee){@a`UeJRo;j1UGAGyISNGh( zSR~9qXgk+_?-V@qI=T5b_v5+fnmM&!o4lpX%C5L^{nbOHixN zCDhi*^rb;i61=s$orkR^meE8cwuM9eDzE+MSXN&8Is>l+;N3Rx))A1!kk(Kub?4%@ zsf`#b@B{x@<0D-*$b!H-#AGpLix%_t)?qNpKw5ZEIcI4N=RDGY^3x}fMjhwg`W{;@ zna*XWw!pP_!f`8T@OvPmGiX>0Nf4?^77HPwjMC@O1V5%|{GDbT0cAs`4`f zflt%n{}{;g{|dD%yPsvTbKM??L>QRQjFxG%Mm908VIGmR#!e$jrP@dZVSF+{)KEax zDasfO5n$PQ_d99W;t;6r=Je%9V#ktTb%C5ma!t2$Z4#1~*KDPF&1>{NbUq`YC?%C1 z!VyVVxP3AoY(hJ8po#Loic)u=&+4B6!lNGpi1xQ|o?vQZ#ng2By+NU$ZYuW4R@aWh zR^H#ew!KqJF~tE)OrfRan&12N)D$5=abu^tal1=%x)d1bk7L^@K*3k)LlFwNeb__h zWEP5P+L)LQ4Q>kEYh?euF9#NsDbp3(mN_t^;c{!(wmEs8OgxTI95a+*6iO5rRh%hO zJSV(&7i*IguzI!ip)^X%n z_rr{F(CXl=4L})8w|L|`$3w?P=W)zFBGyiVL6eLG%^x5u?8(ogNw^>uVO2oonQPAG z^H)Ag>p&Hsd%xSM=Y$R)wn6m_=^30mY7%E##Nl+t89`Up!n~IQ^=OF1# zo8HRt=4{49%7KM(B;z?y*Bgye90)KX zCFQy^O>vH)W4V+S4!Rz&qF_l1R6%bnLNMqj8jTXD^kC%ZUqu0ZlB(wxV$!>PVz&~) zIXOxKIwOWfN;>>|DXqyA>5_oXm=(=|N`bT_MS76UF*xg6H#>hrPDNp9Q$FUJXVB&n>JMX$1h5o~-uAD!`js(cmn z#p7)6>_qeV=;-L6rly8`>1-_3)20y`7{KU{Q(4h~v`z9AP=rDx(T@-cLMUjO#=t-i zMJUW}Y#|(vQw(^gO{2B7m8O~+67e`F3I#p|(+q)9imy~-D6)f+Y0V64f(Hn5S8+9! z$#zz$E>=qzG7a=-F$aewJ%Cp3MFINyddRn(=~KWTU{A!L(Bp!aUWMuwesx9#$a)h8H33rcOE~+uP;86*JFa&GC)#q;GpZ?g)+&sssvk;$(#V# zqUMr!VOJG+JAuc!_qx+@`^U*z5%Sa^qf(vZ5P!CgsF)n*=S#_G?t38whNvl~C$f&pVn45j z;OMVC$h>13*m%LA#A30@CW>JgSXLS-lSnD457rRxjxw#GkvIlPBaPdw@TYrzOR+Sm z3+mJ^UPfzcE0&eOvP`~u=BZeg$??Y@f@N8F8a?!PhZ$@SbKg!|2_U*(ZD3*#& z9b=&g7acd9L+1SlJ?$~BH7#Nt8Ny@E935s2I9* z&iUpWT)7~?&EH!LA(cZK44!=SG`{%N7offtL?3x-1Bfo#(cy>&cqgC0IrnqRw-$2V z$^d_P=rpuQh9ObOWw)&1v9;x3F5z2ejZ$VA#3F4J>5UBE`9*&6r#<}gz6>|rKg3Nh zj=;eypess`KA%u1giBh~=z&}w7!>F&q%4V;BBno3db|9L6O{uMqNASzCP?{llar}@ zcJT=?MEuJqLjP!&zwqNgl9XUWrEpR1(dmt(iAjYj6>6+*+Wme+QY8@-?3M=8qDk^= zfCWJoTeW=9+Y0q6xBh7}S1(@R2yF-RKn<|vp(S`@Q2T>dK&;>!cfG^&=akbM+d+X^ z#<PB-U;3z_&zdw%K?Z)kP=YW8Mnae2A z+}d8+p(30jcM3?!<|Z~1UkjmN+j8=22W*&=cHlDizFeA;qo#uyk2?-uQ?w`UobJW8 zog6=aF%vTOzVFetQxp^w5by__94$-cuCb6W^N>i2bd{K;0prZk6Ri8q#hiTWP6j)Z z(3Nl;yULrGc2JPlzPF6Rj*XP5#m+QE2~!_zAYVGVyhNy*nwm;hHThZn(3_ld+OfRj zF`1Su#zWUIIuqO|C+d&J!LKD0uuUvN`hcpx*B5(3v0S`CFcks=+FJUrD ze=b;ChN67qxCX9xdJ}Ama?dj#a{D*y|1Na*AJP3y;02klPA|iaWJ7(QF9p#14c3zY9(@rNk{jn7$Qo*?`JIS{CqeX z!>0?ZXr7apDl?!7`I4 zyh9P=XvG>yTQDZmZlk}Vj1f8jH;N+2mkPQ9rkTQrLRN9uLFmS>^YjNH z(3Ut_j%|;z?BEM|H?bCE6&GCgGAG}68e<|um`W<-R??p!rq6zg9ELH=B9)^U7N{y> z%GERN8t2qYZ-w$NI^9uk8SJQ`_TA?R-*_VBY`|lz0QC(hA0zZ1483v;2++4%p+Fcpr$WgS&pgXjmwb(De|{CSo0_PoX(VKHbJaPg@;|FzXKqa+ z#Tm(e-Fyw1?MVW9H|<6qPu;V6vcuQc*GE;A!LHrAsH>~OFf2^dq`t16!RR0_Jih^d zRT*i+L{&wOuWgeMUS3|iniJ>Oa^fs62d_AaST2*L#}fSXXFntw-AsLOHd3l2F)69? zGWbTCDq%5ZP$Unps#74NJoZ!wG#^V2exKVe zIEYB(T?)hrj2KCTmE`8LeSGEfB`iE|E%Y@(T>=7qOtT;r&Z8vIh?G$VtZo8<7AGr0 zh8=gZDZpeOVDTwjX|n&aGWNjKt^;@6_YIGnYGFH(xiJ;c92oS-$tKo_A@QmK3aktn z327n8*T;!T11X_cT9gE8*=bq01(YF)NrP_PMTMc!fX;TdgD#j8t-=tnNk&;H8u8#^ z!04eQ;3AbXm2j)ho}yMtP;IEUd8j?aWyjSbWrRFkC4!CavFT2#yuRMYVJiy>h|SbD z9L{JcMCK<|6sT1^@N5C+KRwJX&%eQ`hb#bd7HGRMZ(T+z)<(I%l5byeG{3v^6<*j9 zg$oWP(4K^Vpi@k!AwPO@vYRN?qJ>h+nFwU8421y~5vv_l9j8xbs8oZD7!o0L+``FO zN((E;L{a&q^!m}yKrQ>I$IQ;~0AH>PDV zO37rSRFfK`(j+UK-**C>(>ZFbhu&y}K)_EbYVA`ePMxYu{A?5hT?EKSFv6g-bVWVu zI@fdZ%$dYHcQP0X;dZ<6`Fw;zAxcY2$+K_& zoCw}=>%w+Y;$1m<`2+=QLbswQ3i(oF*p}p{oFH+e13>(mkBI5e%pFP@sHINkOEx!Q zDbO^G{(jWbQcwhn;>PdRh(to96@}4?3RZsce^@fNf<0|f284=RNL*6GR3&aH$Vw>0 zBqd=Km6E_XZ{Ij$(tQ^kcTrVUiN`wVw;ZR{?rRs26$^kU!%=4uomQ>b4PG_R?5O#EC`)lU@T zP836N%R*I)ov^f=24eNkyS%z?+pk6)2Gj*r>B>)X-9I^br0fq!_4M#;${kPqn95> zdvAiu%2M)eFinZi>!qi6fa%k#(KL_BoYby)zyq7 z64cez=QaR|r>qRCs}E0^PFhHGy^4ABmhs%`XBo3hy1KS=+x_8hZ08U6+(9IgoTP9q36}AVZ(mOPwp|ox8Z(-j@Or&`VulKfd;Vo-O}7mJYz8&qQf1`$-k&6R{!EQ06X zCtK#ERu38(M%BHYnta>F<=)HD7AQz*lU2qk#NmfZ3Hg(OQlM#jZ2%6o0)9PpGibNPvEij{CSMdQl zM_PkSGZbWPGY`oSCyGW~ZE3V%4Z9m)AheYuj4&J9d$`Qd;MT3c4*vSb6Y22}vPHMR z+zA5~Pu+JJM>cp!@)c_S>lH}M;--hT@!#K^jmL^HO2QFZf2N6wL{3ala>>W}(wXL| zs>(O-8i465pl&zzHS-CDGBjTGJSdF>|8p%LK6nBZu?)yE=*>g(*!=JM80=OYZO0MK z@O&8F=m16XU#DjI#yN-c!*y9!-@Sz!?(N|E(;X+gEC0L&6rGFaC%AakDJ*(m1H8YE z-`zS$^A8W@ie?Xa>pMV7Vwxl=0!SI7$fHv3)w$}YKV@*Rk73FevFu5JdwV1S<8 zyQ!Zwds1(wssdFi^lslqI6O|N<|Y&h5mW=@t1uAFuyNaZzH!RuIOLEMuq;VNH3^4f z=(aQRhq3rXRv@;S4p-GE;eI8ih zPw3b>)7oMw&`|-4@qmRCHk!YMUR7}EEiV(_zJ*IJJd&2?MwXoaAcz%^Xayv(?AjXEKjz9v9hA8sthx3-HCtDX6UBm)|>%!z*1ZZCpZpYZ9r~BV>pX5hd++(Hk{?=CJB5vTB#kg`0u&NJ%BVAe4m9R2_8(ms=3D>XiNk>#1>)0F zB;@`V_kE`WQ}rPS>dtrK(AUF69U6PC0N4`_69@$H>3yW5b;P@q)YXnMVq_SLHld3u z=F&x4=(vnLDnt{>sD;Z?DA8S13qc7{h6xi0KuUtk0=Li^l`tZqFB#?Rx)XT#r4YO2 z2Dtc4DlDi+rPJ_HHg_7I`@z$&HOgh?T!Jmrx%SQ%c z$EXgFfZjYzsZ&A(B5yL=IuQmHXcF`z8C7)(5EMtdks|o9(}Kl9B^!;9k&;o}Cap_C zhQuv`3`f084-6tL3$FyEfh}Wf%q&i_<^<)70k6--Vq#AMj$#B*n- zOkqZIQw%33OOlt#%lXG@4h@UFp{S!%GJS+#GIAm%9cIRaY0p&W*QtgI`^W%XF332K zSsPRKYqfExTod(fiPwiqnt%@>#xYGf>F%Xz3PNb)%RELkn_@Kb_j5un zscB@`PB8-X8~s%JT5!8daaT-Z`l5xr+!rMpOCn_+S@om#gsChfi@hPPVzS|%l8)W| z*p&Kw>JVY7PFzlj94S!6WVX?mC6Pi-PLNbpWh9y2=Wq9ato_?Ad!OUe)4M*+RJQ07 z_DL^WUAtrdKsw%K7iD5*kt!d=pM;>M6k%tlp=rlGq5{(+n zZfxYB`o?eyHqZ}{7UA{n@4YNPmcC80N9vX zIfJ%BY%oQ>uMo&X+Tal;V*&>I4apQJR5cl^)TC8 zOFWSvD@^K|r(w6*C_V*G&XFQ8t;{)b5(&Is@8oOEwu>dqN%AVw`pW3R*UKC+RbUl zA49(Ma_+e&uyW-WC@n3;w&BqS?gSu@Jn{=*My;27@4Oz%5?pf0C3w9m&#nFomtTG{ zg*hv?LJ69spaoSn?`XxX>*VPks+zr^NV3oG$tBY$=B!B zkdhI0T1o1JiQiSsSKi#ngWHq5a>?l&sq4f=fb(A6Lu>0OBn)1>^jMCrDPnUd#v!$H zz>GtAF~?MT7~T3B)ip(&v#f!K_6+lv=x%QG%)(djQPyD;%+{?^;?e70%hz(^3@kVgg%WYuUp8f=2HH5 z#R9&1eJhl8@w1EPQxJKP+fO>4p*L$;yIJGu*E%_P`C%X}sM5LX;!_~j#)fN_aP=)O z^YmK5cYpE@^KU`ss7nzGD|&?_x$12`tNE{rXo~x$=01Op6U~y~Pp7ABV0(Utb@dvH+`B zKgRUw)0xp!&+6w^Gkf+T3W3d=*0cPiRrssQc>n!385auMx9?`oktdNC3sbIpXxq65 zDf8%Q?`HFk4zeOnG#W(_k}?8x$RwSy7+x8rSalIa;BWSmC*Y{LL&$s26Y18yB%7nqh9^a?rzk|4&(N-tYo5s#-_{+gP+{Iw`A|Bnj-w zaSHWCJiM`oqk{8j6lp>jV6}r)2=Bu^PYv*u(~o4p*ovP3)AR;9qZ_HH^Zvo;{vp3l9GT<+%hOoo%4L$usBE! zqDhr-v}rP&*=2<(mKn5wiC@=A8ItWXOjhVL>NUhI$ciCsY>FiyEMjtyay3Y?m7!4R z6srM-b6xeAwD|cswLE<1i@*$i_Q)Q7b?R&oAjC8-ynQny>VR&3`1ymlx30hygJ;$c!}|Y+yElz*qdfQizqWOcqmiwVVp*2F#!C_>WFZMzXrQcNDGjBC zu(m);+ry!xa41__3WajmX<5$Uq)=LD%i6MU0SaXcNeD^E?l`d>uaafS(#W2XJ+~}B zFGg0J1;RP)`Tw8KGjHNp@@Ttt&-J^m-|`W-3}y!a)&LFM^-_diTsRd;9lyMP8$?Vd z&o(fHj;N|8lZ1e(lgdui_F7SkeP|~h6HHBDs#OfT9TclN$<{3dgg_I;gv?@evlmUX zP*q9VG*N^K_{f(kg6LjdhB(M)Kkj$xLDA=-KmRW}#+u9r2e|faqcV^Du^f-A@Yy04 zen-JLBP1#FaLK%VG%!-8QB^0ZbY`!6c}Vli6{#5^kg2_3ZETEL?DY`e*+$IcqS{}{ z5EebHt>Xd|?VOUF;60mdLUyWRi`Vz+LOxHYqU&*71tNFeq-Bvmk_A--w!_%qphZ!U zLcRsbY^bAscLley_q_Sm*kfC{{}-arXT_#}f87LU&1OVZ z$%r%=;Ut5J!z8Qi76*XQF_2-`<0>K>^|99mTpX}2_63dm0u{mDK==IYd88nhbM!^) zYdo!UJe@25%P-&mR>Sm*4#yZel37dPk=%>?a?fClDk7!Cn{~Od>0tH)f9=#$2)FNM za&?d`Th`-MJ*-_DI~JJw(r z2Ho9VS#F_1S64T+wY9V*wlJyD&#tBjn|5rXq(~udSY%pvFu|Konb%8KXD^2@nv2Wj zrC6xE`|jUyxx8#{-pYs&)J&bq;GjVyV$#{$jmU@A&Ta}6=9EYd<6!P4LVgAI0VJaN~_X<&j4oq998l88K~vQE6!@TR+~#KrD&?QmGV9r^bjZ zpv+s!;9x(H#_ZQ=`s5Reebw~!^>F<0N7GbWi^u7tFKa#PRW&SA($dm|&!-`T&1GLO z)lJoWH=XM?bJMjxsOYuF#7L039RP#|iAj)nnbS`{o3*W5k+PHlnF7V6w=+&~ViEb| zkx@pG2LUW&E?c3?s)6wZFLb1|y|~;wr+WDD)Gz%?^xa;z~D` z1P=-W)*xx6h*1>s69$-3nnOJZVN-H^!oX#Q7>K5*Y^)+R8e@A)2fI2#_&pkrJ^5Fp zgg}ig(2Yhz)W{&W&2;j!rUW0YZY6o{$+&$QN+`7=(yC4-SVuwxiOWHtm3qxCHo~S!KrJDK{!iH` z4kpUamw6EF0I$Z|t^H_o8u3Ou391&`ZvP>NUA6{#j^wakZ^~NEgz&13HfS+mL2x3( zI$1WSitjY9fl?<$LM26zBv4u(fOY-2>u1=nLg>(AA_b(QCSG*|uUvHk3s}jz^$i@q z{3H0@6q_0*eH6+TKtZM@GA&7DLB~69yiUWMnXLKS+vJmA=jJBd+V|+~w9P7_T|JC6 z7z`=~E|-h)@^U6gLk8mm`- z48XbPozDYLy~Mwq_YIuPp*!+-RijL>E#pEieQ7Q1=vsv{U(9we>8t#7~0 zEpPSm-1kqV2KE}7?86Sx+y)8tLk}3`)Npw=8p8Nl@8xp19-$ee=C1lprgQ)>) zS@-DK)QVZGc&(QkUYW%=AODQe>yO~EtqND(_7O~OfNfj2>ghH+Gbm9GT_1ug$gbTD zxR%|9_2SRSYXzTb;0Vm6_~JJi>Q=z$gT;*ms~v=19)N_&u1~_;>M!KhcOGNMUoNK7 zG-%PLGVhERpxXt;-#F=_qj>9swcr5^9jtl$^p-(3?{4Rwt7Z^x-AD!XRBDZM>rpb| zz>v2CM-~5f+iQ)OCa7W@SlPeZEwZ71P${CKyf`ggSPTulY#Txsj^CMIcv<51XJm(@aR2 zq;#DTAfwrg3N5gi@BVZ#f4HZO6)Q|utlSDUZrjyQ`XJK5Rp&3H+-Y*x*$a5-y^mp& zM#B{*CpRqM&F7v2zs5OdE}%?>cdq;zCtUV2_q?KUPe;t=w0|51`gr5Iiy7@)i!K^~ z5}e~K@iM}GfA&8Ts)iA8a@SwC@#wv;ap_Ob=jZ1hMP6$sQhtJ^Eg(-gNvlp0LLyZS z5a_zS<(2Z~f+PQ@1_wfXIUrN`Idn52z#&G-6Am)i9eOE*J?Q{Qm{@WmVR}$bp3MGj8q+j$jXEjKTtPeh1wdaovaiLm#UHaKPsWI}(bm?6-|r{j^^=$w z&+1j;45kcZCQZ^Z$g?}JOVIrO zM=dtf%WXPkgVSHHFVtVoz35cEWvmxsOn& zok`Wzw6t_Ey?z=IVe!s8Z_wD-Nc+|n>dZz~Z&*)E8h}E5eFINF_Y{dl9_{Vz)YjJK zy6cfh0>9r+A`!ta6hKmp10zo&QeWx9s(zL&JD<_fQC7YC zAFW&ivB+VeWifrrPtdJ$1h~pL$K^jOo$OKOrg%OFspszvY z%!Os71oWB;C7Mb~PoimdAx$2vS+gEB3lwW=YG~`}Vb-i!5!jkbe`tA$e8!41`;+`30n zas7upb>op79_wJ&t3M!Lrl8eiC@_d2b5K#T_ilDIH*?7)m+*tjFXNnZ&Sb~-?M$6LoA&k| z>MCj(0z4i+d)k`G2tlA`GV9i@LRD2PY1o-6(!ekVIccd)@j7DW4Ejts`5WJ0%FKDx zl};xmAR`QfLvZeS7lCS!R&`qR5YrYc;hN`m@!-9mz+ns7+T&;It_;c(Yv_Dr5tTbP zBC4kH`;R8Ts>y7e+0R!_nwYzg9cYpO!;BRYd->)_6}P*dRZqSMGQsHE-v!z^9Vf56 zl4Sn(7T|YxP!h}I=jS=NVSNI6LiClmx$?G0z|#nQe~0M~h)%QhM64wK>Xmeu4rX8X z1Vn1M=8tc1-x;TZyPm~2J*_kOZgA zAk-1I>8_<3#|PakIchqW2cq~9OmMpCQ3Wq;jd9bH&7k@?KIq`KOD3aXGQrnLo?GQF zohg3w;s;EY9%_Y(p$2i8EnI%m6z0^aSZ0VKp;91WSgM4bdHmv%$uxR2uDkao*r>wB zLcjyw5a%tg$3wf0=L-R^ib#TcGkBR;=h^ z#mb#*e&}SpY6+Rx7A9yK(sVJR3pC9Qq;QBRnwG%Ky6%ZX(D*(tN9RD$^50u)Z=fph{;h`_6t`2g6d@SvO-7 z7qTcfUxFy+9?4jO}a`Gh4Lor41bF@cDd< zm?ocY+{m}jT8d$$S+nsoG|f#k8fE6pMxK3kJ&P92BpQt}xw?Tpp>`$(%PB1_WluQD zNlT8UrDZ3zjk8FrE=Ek7``Oi}7vl@VaALZ7>1;+t(*R~Zd@)G9gzqwj|WXrNyQD0J8}_e!$47r zu&hA_q(QNOnkfru@|RIpF^NHGU|F_SA(2RsNQ?odIK#l4IY)8iF-r)CJLnIE=u1X1 zvX-gAKs7?B3?tA@lfxG-B#}yyR!iv&$B6c&C@-JHk@M!VVZ&Db}OV zm{CS=X9w<54>ePY=zJvb$eo9L#Nc8p6(?3YqH1TUb!tn^x8ydLp zzWV@(=z6Y$lBZb=OO1-GU@%{TLz<}W4wj!WgK?w@8GnfCo#QlE`@S*pD)39D&Yha3=E2eU;uErTv?BE1!>uO zlVYLlBdkg!_R_z`9Nb(k7cQ5z-}x=9EQQSFQW;ISkk$ahQX&TjIda|gz^n z{iKP&NW001BWNklq{0Hc(;kU8_TY;D+nx*q>`>j1|{>jZ5!) zn}?qd@$l0fL|?yvc1kJkY-Pj!Co|>NXV?`y3imvXuk~$VgYLs4V`wEBe}3gvx|;X! ziz_Z8Uz+R*hZsgs>?&pLJD+k+@*Aju5^xFL`EV7}r`r?K`uciqzWom7&zi?)J2vyn zU;cte9(kAxF1Uc#Uw<9Hzm%Gq$+Wk(6KZSYD~pe1{imCV^mTLi;d6L%~FmnpD@!VpGzGiGnGktc}5g zD_(<&8uI5k`Tn9x9)6`2`dn1~>|HkBa6B`GNtaZiq5+R5viCDIa;HhV_8lw53 z3+NJpswFprv6L5{Ig=69L9GhAA3vEnC$?~ZM>qGmL-dItAHN<0SCY!8PT|sL`So*A7M-Mkw+1oaBKpvAw8dN;zVHR8)L8fYH5^f* zgMe)dYxvvclHWbKoBz5kh$%ZrL|f2;K_a?2t_OQ?oxq_e2gCp1b$9%va{sK6FLM-) z6_7dl(%$QN{u1 zw`$z<%Qx+5l~?6mL$K(%w|V)um+=+NhtQn-=+ys!DJQe5yMNF@e zQ>3yQzWjZH_Qo}1TY7N^3aF^j=-zJHR!@7P%)01JSUQ8&(`HiYhCX795CVEo^fX1N z|4|VnRY;S4F zfsmoxdB$D0a?V=zYa9<=gko!ri>1Xt)(OnAtX#%QMzQs?Ru2v9ZlD6BnVo27>0IMl|AR7* z0x`Ou8OB~+&_19*>|MVyJ3tt}R>poFuZbF8cMXp-d>H!!siQMN|T{+&R$=13`A|K+qrY*@c84;u)DJppRWW>v)y>! z+Omad)20zOO?1;1V@sKr4JXV)Pnf*++S};*-nmeLZ&^ToZ!$`Jn z-AcggB@#(cGu2Bpks#l&ohGXMwJ1Vi?I&xImfY{cGq(688#ZjDwzk$5TCe?t$DVqM zA|bNxX&?DgqN*--@7~S4dGi>Q1|w#gVxOCVXp)rBcxTl{TBChL^aR48GNgCnRXyl> zAHw0lt2!BsC9!~sE3X92F zlr>MSq7tZEI0Hp1Ar_4xg+w?U^leV?Sknsb{m=WTuC68&4)Ol#H4Gzi8@M;x#0IsR zvd$z;mwlBVKK=n8%+{bU3Le3&GY9$l9p7e9ZpP!B%d+X!d=_-mYwCQpbSAG>Tg>Q4 z;8q7IKXWk|VNxP=KD_g*-1*u%cDDQQOoEfYRmpj$dkJq{OT9Li?VT~wYV|+0rLlh@ zHH>84&Ia_m8+c>Y0Dt_ug?Di=fm9E})bLR!95ppg)+1Y~Hkq&st-Y2+5htu7U2Aod5CT zSW(+@JrruEvGHiGz4ig#zxZ{c{l6w*x_M&NFes&*dgfH_Ik$p(BtJiIGBuYy0qrWY zZhez&x19{WQF!|!3`ZeCld3VswTEQcx)+XP$dL&)xD8!yV<6 zG=7t`6oh1o0Rbc$=rcn^k}mKxz$7=Ngdn_u72jFRrMLW!xfk3_XQx44XeZhnA9z)$ z3G&v)jo^n17tJ84x6oJ;WZoQu_1)VkWgg+3EsUrdvx1HM&050{A;M-JL%KqV8l1WM8ByMquR~P8N<}iP#M)TbkT=5 zS;~;pK~f65fw>HZlhl;JT(txo2A~sa4HK-Zr(dRUxC3~lq+Es}s6myRxGCvl8X-N2 z&nJjRI{*`p2x3a}06;K)Mbrg-Y}a?w9ktCfIHee(qwsnQJOgzr-s6;G8#(f*i5$JS z9*qQrGEKD_VEcw~rSC^ipAnabew3X1np( z$xIfMjF@Rw{{1aX)8w?%PRrJ6PNYod#Qf|7ocHa%kL<(Ww!u&uTRSpk$`m4zZX%Hg zU0vN&`~8$poJeP1FREhO?BrX@xVm94Zc!8kMadTb)|jAQ$tBAdD9@;O#9w0hs zQBvk*aIhC;Vi5%h%>FpuiC)rJdoxiKg`yl#5xLJM&+nzbKTaVEZA~qF|B~;K5n0li z-v`;8n<61_Gn$JN7`BUV>HlAmzpKU0nIUiz06Yc_G;~9u30Pgp*!xoKE(kO zxQsZE3Ojs|J@Y^?^G`m6IJlU8OgOKq4u(jY-Y-#eZC7+HFu}EbLTKY6-1*t zx}GE$3=k~$v3~s;YN~_T`wN0vkdBTHYHAwTxMn@2rKR|MJ_dB1At9-*u3^X8EeuMN zZF(P*f;Dt?buoADLb|%T>F(~Kwzif?q>GFgL}!o!kAhPXn1+GV>!sMEvUzJWi|5WD z9yjoMJ;dWCet#*wi3pY@nL2d}mZebR@*o5_Jst)Pg9#{vUAmOAppS{cAVWzVX-SqeHWH0SQH2Lx+UfIy z(&FvaYsi=hwrzNq%f5R7M=e=`o_v|NUwIR^&xunNXqtk*%FW7^D_C%J1E=BP+>0(` z-ACJKoTza4qD4q657niTFZ1Y)M=*>ymtTGv$DeuzM;tMql`B_r<&{^`mrOEZN{W3x z3QUtCVG<45ld(|hQwpUYx9THL1x1wLa==hBMZeTBofZk9qB%NSiwQrf=gPLBtV7{%ps5s$|iM&fhXQ>BP5&~a9SG(0c<{T%j1D3stpVFj!~(_TBIxqsEi!0sUd_YzUdMwsKMt5IyXbU& zaqE4!(U4N7yH)a=TOJ`JcH#GE9Dm};sG6Xxtcr??S|(^tMq*JKeGc}>5=QhP%Ct57 z^|o1Y6(qTSsZNaC_WmHd7Bod@m70iDgILRM#6cT$o8nZ+aMgNo&8;>Ag9!8NE zW>46KM=il0Xd&+=o!3w5W%JDq#A1`lPi|n6n1-5+vGBAqHaLn%C6g3WgOG0W!bz6+ zdbsv47f_DQ?r@xHQ%A~DI#j`u1+|P$oeC)jo#CBK(TnJ<8)ZvUrSJ7-ZoBXZetgm@ zs?`9a`dT{0H1uSO7hZggp@f|YRFJjo6hbg0Jly}gr}*WM|BYf_6|Jo;WE2-^bAUv` z#9iuQ<;s;bH#gh4F@8VteS`V)=d)tP3YIVb38rb%*4D<+^XK!x{r7Y3#TU@JeHYEm z?=g4AWQ@KZyfx)`RXcBINKfUmiLSfx4nF%ZNNZ~c$-Z`crKL!j$F9y!PCRib=PX~y zM6&}WZ8DUc2xv4Sm}E+Z!(oO37VrM*0*?RAvyf2um#6pGA&-a6!AR};5|ea6zI2g~ zNk%momf%!X9F7E+|Lc)FbIG3pmE{lZ;DY;qNV;_ZUzL-MsGNM;tKg}INE3g)_q#Zq zX>di^ohav&N4N9H8B_S{ah2>^_$}OZ4o0w8u_es%M?MC09%xvCQ=QCV=+L$s2TI;OcC+Nr->1o6qmsw(;oi`&csfY);kS**nkS zwbznKe6`1Pe5AW=%qEC&Uug;$-%h;9em7N{^{s{34c)&FK8_>Th{`Gxv~ zLy7GR#op(jvcK`gc5C5M+{;(PwjMOCfmmxhG>2eL6<43@#VJin(SS+BVo63! zflz}CBT+F)36r!mNw^av1Jn53#ymcGag@raO1e78bFK`h7(S$EqRb^2HGCMDv?^U} zwFICsQ+BgOOve9Fl&I_=BYRnlh9aZ2~<$Fo+#v#6gdB^(r z&zl3t#S6tVtR5Ypn9nKOZ^h-KxyDzG0wi7>Q1)H_-9m~g)Qq7*z zrVNdV=6yjQrfHH&m`n;*(bCe2l<6<^4RB-=>L-lR&7`q+-eOsJJf19lOQEZ)H7BGO z2+VB0%J}AH{zx8@G-N>JJ8)zJ7}F^O2^92ai}MkQQXq2Lk}&~&PG^!yQy>b+C}l{Q zVsOxYKK+CJcH=2!KqmVd^Bo7*kagSN&fah@%T7NN(=_k_rL{Hmt!)R7hLk4xGR?3U z&E?z_3bG6vW84&F-&)-kyB`Qd#Q|EC&)Y}#&AJ)?clLx$9%LWfcS5-T`uyJjD1{t6 z&1XL`y}fW%Rb!&&V^B);EM;iS+Hvd!nx>f@MZ=J8GC@=KzLDAc4(s;6n&w6b!FwxL za^lfnWmiW#6~S`b_E_r7n$^fV@4U;Dni_U&-^BV=ALqL7ufHBg2=M#;l$IXGh$*S8 z^bm>cwCO^|AOkYa1i!!|1GrojxsV=@W#vYUhfl3#M_V42r7(;_DxtG$%Qni&TugMi z7%;kVxV#KRBGlGSVFXB%hu>c@&e6+jQ-~O4B>Vj;R-jlY1ZpejaE&sO$is<3G#;l^ zNsz~e<^0nRYsatRcQNJg4C=j5aK@sFsop@E1R#fsy(yvM!>OAz;5N;&h2owZq32D8P zGF3xLjj&W1(sc@v>SVl76F13#S`d>UZ&1kLMRj^kub6o zR0vF(#9ME@%B7e7n3*#-F=D`pN1wpGYahT@I*E$PTJj~7`aS&k+RORRn{MQkqfcbS z)QKc?pqTcsiPu-cP&CZHo~CimpH?A66{ntY8UxWJRn>KbLotk=zq9PrNqiV?<*O?E z>r_9t8w$U9XD26|KAF?BDu%;bDX)T;e}6WofBOYKdafTlqtMsE%YnnVBKtYXY(YDu z+lB!`sN_qD6O%qn%7scE9$JM;IRalSiYk(fKDvm1|6~Gl92(xvFi91H}5|4J&qGmmY+WbD{b;gtHRO$@+`Qff#(f=efnKQIy*^;CRDYCq+U*} zWDjmx`i1oWLyJNG8DjhKnE-n`riD3eiTGSf#qhxjh;d!jLTTF0N)if%z+p;8gbrv7 zN}$#N8MOC=k|5wim}x$2O+m#X=#ElVRgETk00RzN$i;tL&G*kbl5-zl52Z7yDoudY zSkqDn6%J5?G+dd0U2CBs$g@`*!HEF}rWpmQF;q8uOq~k%C?!dQXsjGxos-{Ob^~~( zfolNX-U+};BqS1cJ`-I)V%+=gVv7V^{X`7Y*4Oxbtg?Eu?eqb#ia_~{bzPtG>B8$c zcFt7#!!gQ)B%dfrlbi+s@<0v0*Dh0R)?RQ zzr{OI$wP0w#Pho+!}fOYmb3o7J~Aeh$MOzI&HA!9_CP@LWz8NAOVpXK2$Xth4-X=g zd@^#B{QP_zP8W)jovch$a!z4oWp=EDTPY%G*^?2=ve3%Pa`bY;7$o14q~Zo;Wu@5( zjSH{0%(gYQ6!I;F=wLs-q9T&kAT?!G#N%;XMJ^Pfph=4Xis-NmUU>ISesS%UB=OK^ z#K7wUY0|G&lP~|yB-6)$79=LktY*;G{~YYPozn*$R71D_+OW@+5o4ws_BCNx%6$OE z*k_XwV{sAV0LcHsuJ^_J;okKrgi0Z{L4*BewSPYl?HdnN_S&JDrp^S-ho)&nqfxZ1 z_oM5g2zL$ubH8QLPbRd&CPvGbk#C*(q#7R*~N_7Ni>O3Kr$pH zhGAeK$@jR>6qS5cQ0(br$JXr(83xt0rA(>SavZ<{%V1ckU_^1zstDo+6!|BS@t2ZJ z=uGfv_DJ2bNFi~0pin8zGA1R1mPO^BK1wPkv3u(-+%Aj3?hU-Y_DMWm`+ae^rrX*V z;Uc35oE{G@)k8)BRdo^lY!}6%jNv|$PhNYE;!+3iJpU?hJ@pjV-EaffEx(FLERA%l z+Is6nr8;`cS8svg+$8B{1xaT4@3ffBM4LytQiI^xi> z)y{B8^f0W$x^?SF=-sS-a0S&<7LZXO;B^s|7KJECOJeQEGquOI3TY-R_LYEU=H8 zCX<9t%Cv(`hfR|~DM$*H;*tPn3Q9zbAzde5hH_n#L1~gwRVMf}tf)>#nrJ~cQQZdE zg+ek+6gNJ4B)GHFfng*CS!-))>I{p2&UP|9j@FnN_p_?1yv0I(@h{K9^pn7N5~&Kj zB@0Q1W7OBfviTN&*|i%sDg4`mz5IFE0y2Rr>X$tMp1I)Kf@ykiRt1=MTrJ(!5O^d= zi$DGBQR?qLkDF!;GMa{)-b?e~idA5!RJl~7`gQcyekRL_ToD}P{?Fco_C*|a!5ZFu z;&^Iz#>j{mWz{NAKL0S=*1tjnz5!dWxfMJo&b zQHq455Q9mRO6g4`i1jp6<@d0D{RdQ3s6c|JpZ*=o&OVWzo?RSs%xoqGopgS@lP8|| zEk`d|LRoc?w_kmq<7!Gde9jCWyyp(Czvpf&VY}n4egAKCoqGax(HLzzJM4*b(j=ny z;Z=1e1>CIbY-Q>kV3GxW4SfBW$GG6aDt>?dBtD77m{H|s-QDwB&kuOsH%n)bB&{Z$PtK3&SJH}BT^B)yi=QpWB>0Bn< zwAprR%uCqKCshSga?uh4M+&+Soco*QJbix`&#m|I+$+yQxer`xSozS8=wmk*Y}o*Z zeHHpT!0fQiRdy?!ebqZWcI&Aut5b=^bQIm>*pe#3onZ`zL1^*)ec#o zpamI}`XMK3|NYCnI5eH~e;}a$-vTYBX`+k)enn&*X0hwg?2$KWS);e!c_*iyaRxqL zkUt zfwO8Bmgc5E)IoiHJ({L6j751#kW6QoxGE^bhf{*nX$6io!vFvv07*naRM6QOrUgg_ zHA+Kk$cs*9Af}TNQBn>E!Ut7YOk*}%f)?`wB@|)XD!$XY6|^7~LZdX=fvG}MQ<%oa z83+NpI$9`SFoz}+zP{{kP#1CWcjj>2sYR3v$xnW84dvxE{P>2;35T~37IUc+Y4V~i zWCZL9B^gGr^q567lzPc1UK}nZmnd(G;EQq_i)C5F<8gvsFHWyFx0wXI9yaf6Mo|Pa zX3Svg)~!sLGL^QrHfBwoLi5h%+~(u=`!NiI5yKYN`~7})w6&2hEu^Ue5 zV{poGi}~#%zq3gSW}3cah(c6URiitqGeNU?{YEH-syYyYoaux&P(m!0BpTHj#)YQ2 zDMS*DhM8O)U`UTLV%nXn4x!>z?T$gdG?CJzK-CzOf)yN9?*jR z$jO9uw&IjfsY%<-q-rY9zaHm`->d^yf`Pvr&5h4>^PA_=AfvQC`c)iehzeBlOR8Ac zxsyp#>$v9EAMp5UFZ69D@zOcuX->2=o&c$G%_#wXwCqTRN#iv`^qMeZhJ&V99@8$| zWOrp}?PB!06KD^2BBjdnuf5GPfBZdn-S9&uSNo{0t7BJdm=_=UPkdkhHYY4zf=lT5 z3d=b2gt;6y-yp6oBi9w{jj7Ki&rx#gC-IQ|E>bN2VYk5lSs?mGOQd~W#FRg9P> z)zuAnRUZ*O%9=Ir^YFdDrA1ds`P>vcLR70k&iL6H-btAJ;l?AlIN)SUEQQ0|!L*WU zUfepsHy>+;PfR|!y^N~4Gjd^IV;8nD{_%)uk`a;uwHlWhC9Oh2_|T#q1chKrppNHX z>gJwjR)Nt@`|HN-?Fp+M>|no5->ml0dkLwrB;DL_0}eHBQ-sCSBy0)G@3=q;m@q-9>QfCBc!XORomq< z81&_+X(c6YFikpIcjBxHuwmm)^kf?080DzN3jmXN%A_VxO`$1B#F7-K8pUo053l$W zLO?*ZDK%Z}v4`v-oA!CtRllGomLw+01{#B}#79SG2b$)~0TnZQ-FM0;B_%Vs<&9n3 z{=g$VefPieO`k==G)V=0~Y8Q%R7F;85e$+^&6TP8I%Mk28a!MQ5Ri6m*D}?!-s#m z7FVbVr&LG?l{{?}BNU@bt0tM7AbvSRj{O0K$WFt?ejXmT-yAG}bbn(BA;kYL;AHG! z2c=252vX{{_|>XjZhANlo<0U1IhsHH`av#QeicFp91^*Y?VM?v_-F8{wqfw zc?8RrotL{!%TmHj(?m*p;~5r$!f~CeVQf3y5!0l)s-9s)?lEj0q@=pqF0i7}ur1)q zxk!xWf+vTQNi-=*CDW*ZX>8Rc%=-qx!yEYCyn05=9(L_cQQ%T3&T%m9pL4X9ESQ=Y z^r0XyOepmEkW$)TTCIU$DM^`ju~w}3sBZ{z_F3hOh*6}>W3MfoiD82xRZP&`4_zxXCkHx+W}vI`mQXrr=DFiADWZ8-A(koV@{ZIx%<|HrnTW9vxPku1rP z?8r`RCw7RllMu)PNmxQ5DU_uwL!pJXlxbclrKP2`w3G>@3oT`!6s9f9&;q5bY1spW zKte(ih@HiW?ZlRC$+l$c$kLI09@+l=ab(AV&~~Qny#394u1i;R>2kcB<$3P={%+$O z#j(lfJ}J5Jj~#Rb^H}QkFgsI7)|QXKAYOX7_OuW^$#!b!qDU(Ac>@eqX*~CEC%O{@~#;9s>Vit5pD#+7~)eG)zcUbGb~l4)G=dj z=FeY5XG}-e84%G3558=Ehlr{b%%NI&aK>e>erC1QLbEl215vjqe;A?l0uop z4z%k!2g6~)39D$*G!G7kASO-h!ZBfjsf9w?UbmA&4%{7viU@nu8WTZ){!)j6#1^Ux++?6dqErC3QVv>mV zaqz%l_BJ-s7>-lw(n!fPOO~8QI2=V)HHz$lTJI#5tvG}I2b%CXoH!f~+-{Y|#slna zX|{3#q$DjP6sRh8&1N;)2nu{bMulLqE*UbwG@wZHA*Df~A+Sj(Q&r4Z2B)SX4MBxk zLfU|SL&qQVQHaWj5d&aUO6<8s$fAyENGbkiuIPw3_GV`lRyMZ3)C7kjy!x9}xLRMw zm`yt!t5K&J8gCJ}CqkyS^T zT{9cM&(8%l6%6WD`tlG4fyzqW-S-~HA3p~n1iEgJ5l}a0278+KvgD*CY~Q_)iUkYk zhXT*rcEoOrKOE{*AApDQgB+$Tq^H=fO+$(7}hFzJsF^4Ns#6x(`kOAkD|InZaq1+?r20<%}S9b zDAH8=4IM-3lna64^RZ!9H$Q%)+oDg+v23neTH2Xf=VR?zC-K`4{s1O?{u@s+<-sc` z_q7qMTEL}ue84kLHo_^h7+AjyJ=}_{3UJ}|_kb+po0ZUf*SSoVVGf`&RjQ<iv(EUs|-A5%Q^+9sGYO3(UFd_E4j0-XIuAA5iJAUB?Q0$;nl zny9glqEH<*XWa`_@YywX?zsAN+8cM_)OGBd6*%nB97sdqqsEouzoY^9TleuXt&~N@ zu)d!YHHW4g5yK*m*vXEJ)4JqQqSp^|*vINrE0aNti(<#7;UFNbg0Y{C_pPByXk75y z_u0N_5d1-E>x#fzL?qtA_kPuBH7UoXY5vgyCL?KT(wKAeMxNT5<;yGjxa+**xqt2P zcrZAGBuF!V{F1^+>vn>a6lAP;gN)ZsIN3(pHw&8q!JrRak5Q^={QD1X<=Z#^1TqR0 zp+%rZSXx(y!yDj-H{Ha!C!9dP%;FVp_O(Xws2VP>i|%*?)8*xh*IrJdzlWh@lF~o` zj66{7AmO^t|0{z@Yrj@ii?<(ZiF4Oozu-IH`9`j0v8YSc)m7-a4niXw?&hoKP2>DC z*W(m66iY!!G`XL?`Z}I?Ba32`aALKSq5#C=Pa}kiN7eZI`?LOY9abv6g;GpxN{;Oa zB^YyD9h%T|kBPg7#nCzo#i26X)y1&1bidJPH<91i0sDIwh5jmO~urxUMJAk92nDC14aAW)P#I)5$SG;?Y8mK|{sN8H86 zY>10ca0Hx4GsXV>yIHWHj>|8;g72>XHZ4)f!~bz9d)nK%?6Rxa_|li~*%kWx`an_W zZh8ki(+Eu|L$%u(LXeN8A1ffuplTx}jlUbm>f?}+BN~;XMe6zgB)6^4>!l~0L>WWb z$^t-wLaaS&occ9pmX@D$j?2##(f~qHj%k6$gjCI;34YyUIhcjHDeZ_5e9+W{rnyj6 zmA*)Xfn4KIq-hMqVyLPeuv3H;FgF$;B#;QNgCZk=kYTU(w9zD$*0ijSdw`%Pg*Bzm?fSIt^oq=M%9uDZxyG;uz;uVvgBO z0Kx(3Lhxu%s(|U|iRWJ8mg`s1t(&-gc6xL%zELsZTsd=%)qlJ_K*yijV0s~&54^?Z zv0MxXfSbE+dxM|de;)IKhY>Egr!~&{&;BPUGr-ij;eEK_`3<~!_t`A>!fiJ{%Dagg za2Sy8vaBYjp8%b1=y{8B?^KpAnn`}v&WH>$VzhHO(o3*vph7%^(tf3FOSE=?gLE}0!>W^@OV5{gJDXfqR`RN!K6u(Xgkn^-R+?#*Q5X> z`V9t5lVQ`M|7H67!Q;T;5F~qg5Do_pw}VU~jWi|hKnYW(P9+!&QlM(Ix3_TGX{WGj z*EW2nMxGX+MAXos>#$}n{NWV_btfsA+w^@wi|VFnBy>T(a9~7XGV^f7TbU9V!|IoT z^x+gq?5Z8Fs`AjwFJoJ}ltL6+J7d-^!x)Z@sP0x1PfyQL(pn=^;jeS7h!Zk8=uMS-faW5*^=yEuYdjWZ}sV!BRA zU>4tcY%g)wEUvraI|S;haI2D(E5OQScfq1+?znIgUp-|ZyOM`VSi49fBbj&HJ_jen{IXz4RV3_kIz#80F009c1tGjWA^v??qy`Tr-eT zk_L-k@6h?;=KOQ3fal+L<_q&eeUmRO&BcVJ9WhM(kUR1IKf6p?rQ8lWotB6F}(KL;y0ri@lL~9dTZ7s9z+(KqwlJhHVTz~T_ zPP*+Wc(u@~8_-y|%FgeuKbO&PhFW0|k^lP|mBNqQd*(+_o)KY^Z~S#)dIiYZpkM+` zY*+|vxu3PGv5{;_;!+giDJ#=1I4MLrZN2a9?Zofb@P{VR+}cie?sszm-Q7__lS*(n zJnU~hL{(@ygGlmoO^L_j!6r>iQ(6wPrbU$;tK*zb1rQVntK^bWfO4d`4|g8sg0oNO z#TQ=S^ix)F(bb<}<G^Cz_K(bdTxShH4w2_oLDTzefQqWd6!(AgOnJja*YYngb*KE zP~|wZZJ{Iv)zwuL0`2YXKmV6{l!bU_Ucct_H&EyyVFoQgX_NVYZQAOda{D`H*SKNE2uxN zlRx}sIV`LILvZTt|4Bx`*DtDK!AU)Ee2UZ04B+}?6==XT8@RhTeSR&Y$t0bzI7vNA zRt+MAkNg}0HV})TX(|P(N@G(a*L~8%E02DSexsc}X|OjLA*-5XRRhCFQtZ>nWHP+F z?R_pd|9noIH;=Dh{YBEllIgP+j0@(i##fA^Dy~wuWh*EI6{V%5(dBLFdpr!M( zG5Y%0wd-A;dFC1Nr9m^A zvoKAC!%3cd8(dZMF|{7e1jwTJpSoK7Or>fC0y8 zb<{{nncjp`?8T)Ccx@Xv{M6|&&i1*$twBsj0=gby(5I1-I^{G`p(Zg5!CrC1eI*f( z;`LV06OLj^$(5I00XX=>lP{1j9qirP%#xLBh(u##GI{LZwTDlA>TF6&r;|0D;NaN>!}NrW>LVr5a4 z)K+oMv;ExuSRwcS@CCdV%%vodrrGEsW5i&(52TM9f4GNB?rYN(7!88fCcY`7VSdB}@NM0h{@ZvPax1?+971C_gevJGly z@#8PfB)e`3{h0_Z1Oda~`O6pb=1*2b?@s6x{Ay>GQqp)sE@oc!AfSO`H>vwRO}eRx zc3%~PvYkKv_zZr1%kj|G0O>h=``HeL5Nv;B7r4``E$iZ$^~*Tiw2MiGq&VC}+i$Pn z&Xp!mM(49(wud1aZJ|nY;S@fKG#{O@_G2O>6AS*aXort`{jGMxct)ADl3XnlK*vg!`ncVjH`<(mk5bpZDah_K~q2aTu^qchgb_Q)1?C3g~Y#dyE9l?NXF1!tePnyAr5x1kdi zc4mI^>nyzXB`&^WAE&PQDMPxKpztw;X^iR$uRiuBstEFacrzQ`c#?m6Ow{rYi2rmQ?t`SH9r1TqfB*k*3>|ad$YVr|TF##zOG~tl(cA-<9<%LL6h;h# zcvpl22lmj{*H0|xwB=HqmCJ4T2>OPCtDm$#4s$^|dTKOK5A?0u|g;n644Y6hl8rB$;3Ju$TRoR zviTME?AktF|BZ;z94-9MIST&e20~0gT1UjOo0<_J{s}ZFe_6xlR$U+=G_e$u3bE*Cnx>)adAX)UK~-%G=O}GQZX{zoBxlTW)cSdH9DI>dFr};- z&86b=xzNLLiV<|RXBZAj^xREU2;+X@!-hdt6}UtUR1<0h-&^aUEUpli21Owc@~qXA zf8#w6^Lc#NFo|#&%1(#g&20Srr^%NQn%6I;=9;&lIYU!ZE9WjMX3crWkwoG(1dpp4 z7hSOd%myC)+4&SpNtYoQ!XT(YpA1rn&Y&L4IlW0bQAr29bO|`wh|#%g8w={^VMs|L zlcf-Yslo&;!QM!gl3)c_Tz)yvJo_xg3VipmrwI8c(a>-RwPfreIy#Zw<8hCpBBqp- zmQLdE{{1XkzKlbM4j&P_0i~sWdU|?syWJc*bcoW@(ur(G^3!<~xE+wTnvv4dQWV9? z(n+T~7z7+bLCJw^o{|#kXV$ZH=~6UJV@6dSr<`&+`}c>bsHmkg79n5e(SJBb#aR_p zS6B1?ww1Bu*vVIAx?%o7lZcuhGSFGUH)n2aY9pwCLUqXLiF@s^j5Oy3wph$zkzykhl zTL%~lh+eAeR)fn1iFPY{=8Z#q`Lt8$iAT|VUhKfHy!zHwjytY~n||4G?h~-Evf*J7wg5PI`C?v?A-byLH8&^ zm^d7xH162S8RuU_IvS(I<%Q7^9)98p)_wl-y!7mARL@<=o;`bc?6IeK`pk=H&p=kH zG(}aOyYCGsUrg}4Nt{~mLX8{rh%!bpNiq*z$`!xc%i~*T@x%*JzOtf}V9*Z6(VO1b z&`C;5Q#eK^8XJ;i44r(h9UK)PC6gp%q=T#)q%D$UZtY|`lH_O#IoqT({Oq~IFmpak zNpsz)8U^t^IMo>xN*yyNid?MP_}O)9x$Z~raLp5MGJ4tqdUb0mk2KJqxfDluCsM6J z$~bK?H$IYlw%$(P=T6~<$K(9Cp$TVo8k86ioJVz6>_#%4Ds46$HZuObJ#pHCRDkq@9kI{eYW&`}Q$+Mh%A1iyH7UEC4YLsGy@w zf}@NB`Y`iD1thu~DC8uDNU*E1kzi1xONP1rbC>h%OD_-zTu(G=3F!?(5;nrF-Zrb1Jm9wi60f@cz47c=eAPc~hP^XAuh_0^Xt77oHa32yx6Eo2OxV2KqDIj63UXd+F#qX%J{cogVs*~IqEFEQ&& zSJ7vf6ax9eqNff^NrCw5ufvB4KVF7>hX4Q|07*naR7dNSj_nRM4krAwHY#?FC!Tzc zw%xB0y!00Edx2htbK3X`jmnYYzQpHaD2K3UK5bkqU+nXeFD1IJ=aTCMshpU1OgJSb zTAm3NHCM>{d?IHTJSMg>a*K#gA%c{VMODSPE+t=blrShy8%2$cB1D>W(=Mh-m1&jL zNW-97tt6pL2y)7yXhKns`mEd^v_wZ~3;qL0rwyFIh=0^ViW1gh?yI!^ZfU0RD-Os} zu?DeV!=Vo~zJ4VA(xT{;2=J&j`i%$)O+%gKBVRYhLw`QpP=O>v5R4+w+wckj(jep= z<$$r9>E7AUrGr{YGB`?8_%-M)CVy2uehJ~ma;j@}aI2tK@OV>(`KQ+NerpsVbi9E8 z7hSUfs3f>N#5wgPq+2s2R39TELcYmLAj5M(8Y5#TM$ zInrNkQSC%Km#nVhfivr9i$>Y9Web@^g6;#2w0Cw=T0Wh^Nlpr7iUBhX3J4U^xttmy z6r?oqc*;3+=nxC0PN7%`IyyQrO>gUj*LpU4`5{Z7w%O}&>*+IT= zA{0wsluoDdIxIo{v}w~hc<=zyloTrho1)O)-H*d*U4xAq-=e4YD^}ue+Q3!n=k`1A zM%ObG;-I|3$IH*Xz!@hlXZz-z)XkW|k8ZmgBW+MpR+($;YY5x9+V0i-f?inD=%>KHzsrTnJ4kf z-$lW_0NP@Ng%5fipr}AEPbS*=x9jbgF$14ZqyO(vXpM1-hjNLx;}jyp;L=4?S+~#y zT?!{%zY~t{XXy+(b<$01uVCYj53FY-?ckSRIhnk8m=&i?f?vM}(ua1@q<_jhpX>w`SMqKH(*RNjmYvNay& z!M8TR-ZDrxbJtljX>E;IHjj22hazpLs^I+d*K+4i?#AXA<@GIF*uHr)_dm0NpRZd2 z7~FQlH~9M1xA6OC?qb#wAGiJJi?p;Hq^@o{v3M`S1`B4*X7~PmIK<3xV1C$;^k)oU z5IvEgqN0pQWIsNpl2t2MenK5hufM=so0|Ca_dd%IS%iR|WSoQTUFdp@!%eLmfAeC5 zP?=mEK+`k^ldUuhfhK&s|8kGjJk05&Yu#!_w{)kj{Triz}p_6YMp(_;R+;uFY1%XFZF^m{`PTO=OfXxAkG=oWq8(wc#C2&Mj&x#*GGGj(0J zG!h)!d2D2Yo$-Hl+Fb}_5R8Z{q-TTMMi((MF2O)Nz+9ms?FOs~!HZkD>6RFmE}6;G zzh1++>vn-uXne5|_V{70VA~HaB@vG@dg>%T*OkX_es&mo_d&W6*v*6AJDE?0`e}LG;!Xg7hqse>~m4HYBg`a_98B~Mpg<| ze*S*TFeBjyzYY8`KEM8MKKc9WFq{QsRY5PXb@SW&OZ5r(sbODBnAw#JiO1vPwZqs@ zG878Y+S-~MOzN~7?No%Sv8y)X@g!2fd(9b0dr0577&Y@Q%f7#iGcS7-PIYlyl}TZ1 zjFUnESg;h*Q67k9S)HSQ{=ajK)h}6#oghR`!~0=rz|oqOqwZ5-F<6FloqY$IDAD{m zk^Cea4kxXxEjXP{JSEN?`r#OFGzwil%gIf3)9~JQdON!*bbBzR#OUwF?R3x`?Z)PG z;&duGfj#3cUL!(bkTm(J6xj*M^ri_#nB?d5Dpt#4t^6|=%wo@uEd)y}3-Dx5l+u~U zGkZ!c{b>Wc3LdwhwJ%CX2dJJ99*>hue;AqS!w#gn+Hl(Jbm>X*)zO@xltc>R`uiLnM{OlUebu}eu~9C@(5hnmwSNSwlrl%v*XG7nW9#V|4yBJipzx{;g^ zDkG4(fe>!;CD?3|ZY<{{1QdMeVvSLYj{fWjl?8?I6xITVB{(e16(LSVwVWOjl6(Y( zxEU~|Wp%22c*8jIz85HVtEBCg#hqaYi#ID_R5!?%5~omesF5|@%+K98DiS*yh<-q@ z;JNMW>2(7YcpbIGpWh1Z*^u7I=L2=z>RJuT03*A*Ku)71n59=0&}9HKDD8Tmlq_aQ zD`Osl-!u+`5ro86c3pWXnQ#+>Y8{0{5F~&Z*rmY`niY+bGdvj72jGwajy#y!Wi=>i zX<5g0?YFc!2!4CtHo}|2Y`AMB_uu^=^rDk!Zzo>6h|5d!2!-Y_0C*i92C)_m9D;l~ zN@wRG%F9bJO{>w3=B$P-J&Q?CPY3n&^+XOqtfPbJ)2GmN2y6;WojNrq^0Sbd{!}-U z%cnARYCQvH8bwKy?CqowlNBo$@$9RJq+67$u+?zc3R5iDKe2eFOS37-s3LGUO8DX9&+zD@Pw=nT+h~njdOt&2+5}II z_M@nF%Pb@}_*o!TM!hCqkF@|ZxN}Ac9eO)yt(sa9CnI(elQZa(ke_VeduPq#mMtH! zG2&&!c4YV=gyke<=?#tC`eYE0DvGo+dV2H-qrq8>04plr3i)tdvk6LrtnjySL3J_zUOI!;h9oXo%2Fhq#MrIXGpJ`+DVr(K{QO{l zzs2d7mbuA*>INkZv0i$qq(rlUVX$3P;xnv$LcvconE^)(WF6f6I#h;8$`(xRcm~6* z6lpQq)oN1GhD*jlGg(I^q~BwWQAdSTX%lH|hCv}gqN>H<{=X|mW}H7haWd@`AF?R^ zkj3O1|pzv04QjU0iSUP^hn=K#f|3)20UK zbg)|5$d_G=h?+lh?Ir(xwe+9+e}8?^SvcOfju|x^n>Uyd6I0NSSPOrY8f=-;fO5nV zJJ+lXjiW6ek~xn3EAy;<0F#{u58}{9b3ZeF?A{56s!k;nwaVZM@ijzn* z$+AU@h;(()(c8(wrHk3p*nnXqNTp1?B_%oOiGu2I5bkSX&{={D7;!onPN%IJM6oQ0 z$7oa&m=)3neXOz7RwfFmuLTp}ov1|fF|eFt`9qHyx!6R{Z%q6vwjlrRKj z(qVdg`>86QOdOL;UmrcX1QayQMoLOXq>4}lPMKy16}ODhrwT?ynu7S-g%6e3b5txCMYq$pRXJBjguUP-xTg51F&&4-j_xTQf_1&3kaBZ$!3(X=#a z=_VtB3}|r3Xr`XBqt>M{*T_P|IJ4*#T={YaBCM%|joyUqUxZYcTYM|r+~d3t3v zX2asx7IG8K2l6L|d?lue~&V!m1~ksr7@i*!)6|)GMbxg99iJ(?jyeDiXxEGL2dAPSgdo$C#yzDRx5GhM*%ZPD4`RnMhOin` z52Tzt^YjP&%($PsuUNvRbzb_7B>AewpdOgbhd`+xp4-iSG)zC@P1P(8WIj|;o5IrPO#R7 z9&X~sGf(EhUvGr+3JydwtkBXd2~9;wx*74>*!=Kb=+)skl}}x~lyJBeY2+cbG$I%5 zWI3&=6uMl5!(j$umLTnKbp=aD8dzGth~3}+Ebs2`=7ok<{I@Brwdtk_ZD7nYeyc8S@ZzEol}nw@`V*Aaq6O}G>5~es!B>4 zc!bKAE?Gszta^U_@*WPh?S?79;Z0BqU;otUteQ8OYVRoh@fMuIL>dk>O{1=^mb>r& zB_35}_?rKN5SD95T2*m+T@2|udGU7KdF?##&=*LjO-`D=fOuyw{!%~F%ckJ>`*Rw) zBbf{L{3OnR*@dVs;~U?(g3B*o$`>xbj0-P3gGDFIW7p0mmMmGqP2cea6lqF&wGz>IN!zl#O_7)~p)bg!sujcj7 zZh}9-%nvrQa#e`qs_h8TN3`9^@9ujO9A%K$%8L(QgJK5~yP>z5ySC+X-jYdpqLOl3 z7Gw)}Ra&$FxBO-U2+2*=y%65Q2_af|;sHNw5MCjJEE_;}XoN3-Z=mTX3uJ^mi`g z+^Zk3G@))4_PoUp?^y@H$!iyr5ot!01Pf0%0V$z17NfmAhTA;_u$tpS1U-7pqOKch z8XB7rLJ$fCn6+dHzkc-h80kC`LXe7Qxb3pjx%tjUZn*UWb}jbu)6YQk_t)V}3I;M+ zUN912wIqI!vO_ph-!a}X2nq)CW0zL#4ZgA=;b(H1`%&$c6Bu|+OdfO z2K7-!^$4FlWfCWxHj@R{HN&1Lw?6a-9$9xD$!Lu3_BbS9^5iNSI$F_`lJSRLAQ%x! zF5^bAJl;`qQxJ1p`=clh91h30n9l9C^elxaxZR~h`VZx@Q3R!>lj!N`Al%c#Ku3xN z_4Ozy96sF1&K)mO6AF<51SXOG6vN6Sij@iyltZVVmv)Bv^t>ukdIVueY*OM>1&56! zlWL}sXx@zCE~TrhAI$>n4+mLWtzZGd0@eiPt^B|au&pz8xxLTGx1)1BGGsphY)ld`%tqZbVjon29*0WkOqp;j9bEQuUgCy3jsUAmg50uk`x#* z^21FOP7u!Z8!;fpr)CAYc*#n#5@PWr9#!CS*-0j?qCk&FaE_z3f>_Mr`A-Q}(B2-# zDQp-l%hym_Tg$Zi5YcER*X)ex z?v9-8iSNz0j!S6tN84F5tBU8QWO;E%l((;3$!gKc{6LCmw1rAh22~*%q{jBwb^s36 z%&_Ic>?XKB$+1mPj3aESDlmja=~Yz~4+f)poGPEj1NWTF=g+wlqn2RHC; z1WFeG&1`@E)1)IWqtve8>Z=!V->+J^?%sZ`+uX{{E9Oz6XDE;!cJ9)7=*10|BVl4I zw|?eah=x(^F_x^V=j~1T+_L^nIzL;_Wz|6z1*P1H6*FmX zKR~`}8xIfrzjYKIvsw9{Eo4hIE1XtURfY_mSS*6i=i}XXxADdsudsdlI}F5=6uVr2 z;FjBNqp`6OpD#$h)G73O*|6a$R;~IeE0>&8DdxsQ8XIo zE7yOOna9oGJ2!rnWYW6tMuebh#vFQd9jCDDva1%I&YoS{FdWmEyttHi!byr;E+7GZ z$*jsC4X*&VKuEvGSn4Z64`=zrs;d~(b-<5Dtwsyk>EE`Cg-h#r{`t)owGrqy3<9b~ zk&Iy+-b1EsH(?Uoy6%@GdlIbt#Hqxw(W__i+cd5@HNaD^HL>%L?L3-@@zZt3VT(7Q zi}{p!M_GH#{cvCkcp~h2_G=h2hR6gFB4as4{V%sE{_}?dISnsk3F%|!Lt2f%Q3Eq+ zFl0(ZP8(8WnxsrfVP%@673ByPlO~t7*2}`#voQ>Vz?3rTs%vm6f;`Q~#g|;p&+mGW zbXuY+P&Iindt3KoGp*rgb^>xT;&hG=MlE|{%Z@l7X)$UPFfma~$fispWzO;RHpd>46lof1HA*&Oj0abDgu@gm3N}UH_j@Q-97t0VIeeIWnPn*F&SfAe%ncJ% zO)w-?Zn*tLnrUX^H!s76!Kj|aE*(_(Lah1iQ*3D4$D7w)%ru!tTC3!Zb_Y*C^ge(3 zK(~gNr&d6Xop&ypLs3&41;H;GGW_y^tyVCrse@Yw`2i~{D)|1=dS>~0K|c~vPc98c8#v5n9WCYt6#N`rw| zCN~AljEn8ZHsSvX1m)wJl%c->yH1>r7Jeu=Xej3?Zk<~>ZX;>AN?8}fopgdJKxyVz zSJz=P@-WX|$--+k62`|BUwM%5D_0P0O)~0Jxa#~9Sv|j=J05zIcYO2t-HH^;AMJo< zoljhP5~D@~ac_VtpF99K@cDJ-1i)z3QKg#^H9;XTD6Ph11cM<7pfPN~ppl1L+Nf9k z^y&s3>}NnrQy_wri3(h_)8Dj#Q2p6lv(m-AdorXD2r-&-dQ+gZhMtZDey7OM9u$hq zBj;@pC@@px%RJJ#aL#mEj!&OW)1rV$sZgvqNF);U^zbUhtralt`=r5OW}46Fc3Ew!NI}y zEEN^iOscF#noz7rvT2>3gu$eWAO)&mU#m4uwm9*zk6BNx#;8`0fzL}!YOJaCg8Kk; zDSYDEw|L-+Wy~T{0H8|YB{Ik4#`D_p8EV&R{rh#@X$boQ_pPo6D{5G9? zH|elj;kMl`fLRIU0Z2rxO;g>?tG~LGL-8oXQc#r1o?W+|NTdlTI*ZjWt*4`74nz4YEmm`oj{>2n*~>?n z%2S!XH;n<&pmFi>$@@MnZOud?%?Ke`yS5jtO%vScIJmCI)-`L$7Ynq`ijo`76Sbn` zhqII|i&TCO(daCagL^28P!K3CrshE^O~J>vBXwHp3&$ ztvqtiANbat=ks=%0i|XPR%Qf4{*7lTQVK#!Oc4Zy0KG4xDs*7j`QUe1#nmLQmCsDQ}W-gdl+2Q~IAOJ~3K~&f^(=KvJbHYscT{nZ)<5f87V6H|Dh^p@7 zzq3I(7=N@LCJFNmSA(zT4JwQRWk4D6F`fTP|- z=hZ)9^2-;H=}+Ta`BP#?wzK`FQyG^4^WplZps9-nTT>GcQ7aQXv1vCnh4|>H-PGd- z#cHSuH%{sZC1EHo2xFfdQkpS*l=3MHo3fA;g9I^95di)|(g^89@lxv3Wc5=gni=_TBi}Cz~x0k2agehb%&r zg6U6|(ZWs`8Nim^4Cac2gmI+<7JQ5MIrE8|iW z0(J`!Lww@Br-Hi%A$!m|Lw8S{wP}wS#*8AJPBJ!GCYj9e;-(Gs^em*T{(63XJrXS- zuLbqOMrlP+3rfOaL_?Dn2s>dKZ`Wl)gNGn1BtrI37H-h2>nbIwjG!!Sw1$N8Xp;_m zlt)oOqP>T)oJZbsnVU#ZRDxZe3(8DuE!(EXs|+y&wk>E45~nM!g~sJilh>NVx;tU0 z4`dSz?KVwHQvwQtr?zb3pU!>@jnl&SXfo?jC?ptfk&GcIr!~#NJ$&S%1YXWX2u-6f zuZ_mLXqJ)&JBA%Nv6aybdhRRO2TutF8*JFDiquJgPWQ6$mNPi)ieJDEhs*zE6|_u3 zWDDpf5S>5|46Wp+|8Y5~{G0k{lr*i5VJpyr+8*)w{fJ~ zz60jMw=Y`EKOMh>Lb4YnH5-M^q1a4p*udnUKFXCpev$vUx8Ils6kM}`Y){d7+#>$t zeJ6A7nXP!e{a8*9PAJ9jFVE+nKX)&8J+%Xxx?pGsMpDpXbHUuDeDRj^h>A3OdXvm| zmNTLRo}Hnkes<2GYJ+uYe~8R%oxt*cmcSP$VQ$+!@RkP#YJu6;M-vS`u5 z>OEPOHeS%AG)u_^XTK3EWDviHS3Spzn>KO!=_|P5n$K~;4L8xRG9=pLXgyA6ptZ_r z&4R8)tdsLN`^}f|*-w3z7hiahx=50Vg6780e1(_SK7uV_x6njlHrb-bM4|_4;W9dw zpFz~~Xj*bSbB=}~n%MmGR>D$n?9!u2rw54HJ|Z!jbpI;mW|q)GHzTnWwYdnN`1Fss z@s@wU$7TJdO|*3_XHpGd=nVVTOZ#_c`v3Q%Lj5WWv*#Pli^W99(Doaq>sACru^94A z^1Btah*!k=zNtfM^N=kRnAhA)celm&zV|(L?b=15kfl)=G$h>I%7;JvF)T~a)6+wt zP#_w$Xl-qyDac!!vLv>^5>;#B+CZD)8zvZ5K>f;DrcoNlM`{=^6j*V>sT_06F|1$T zOG{@b+xP5YET5;deHP_9K|b%ZptFaU`})lL1eCKzOJE7hWGM;3IGS1^s@k-ulq5X` zO>-gQnEFw9baZu5=u?#1MiAxTM&;G{IZG)Sbv;TzotO$Z92hX6N*cXStzHT`D5Z)> zX{M~HREAbN#-L}MI|Tc0RQ7I8UTw4TYG_`srb!W&nZDOy7HP4UU-k5mo#}s`N@)!a zz7Xs}!~Dabu#p^+TAiRVVN*~pxBUBMeDdQDLB~@5b8S8E?s8z4OK$d3Zg?omSxaVd z?hkfAQv%VlgRUi~lHQP`y&KrAp)kN%%g$shIRs)dSSW02wTBi3Kw{fn{^T{FKFNW%uhDz-^en`6QvscC<|Ma%uYzg6Y1h*p zO*)uJE0+m06Ur3Dww+*H8oE|g2x=A7YC)@Qj3ahym!#IrRZuI%46RnJR+NQiQX53J z!4^19g1pwa8PjCcVzbSKqVSLjlYfv?9@$iiIw_I1q#kfxuUd#zior(5Sd&U2$Y(O# zcH^0(fLMB%#?Vppiv)#YH>WSGqeCmS9iHLHr?m=-{TNC$LCoYv)yYX*H%&)8hLj>` zhQPMtRpDVOm8wpy4LxoDg{0P|Sy^X?*pzbV5e{=if%&0L^nU9CuDs(p9^5ztBTc3- z*C}8t?>aWjr{4Q|=C-@!a$VIXr8Z~+E5hx{=Llh_26ch?L_TQ9D%nn@o)~F2!{7#& zxUh)XibC28^ag_Qt{9V^PYXqQJ(qCTQg&xtE?d&hr@GE!cRa*ovdHXsm>LPYk{cLL zZXzTlo`5(b)G3=<0lWHF@^5cDm21vEmVUR0=k+sYce26}v}(avJjC;vO(blayz)?D zgpu(9{{5!Y_@cIPGevf}11zu)CoZ5h7H50<38JEjsJ#f!Euuw{NugpDhn5O60VPP{iko>sw++SqLijt5dw}q?l_!yjOU+yGSG_(EDJh2J1JS8$MGNu*Sk_OwP($@#3 zJ7=DK9*y1ItV*U)$s9dBaT@G}lyG_eiF>KX%0_K>G!D?c7OXRy&*5_Y#dp+10m^wpr~sM=WCJ&YiTkw~@~m zC=~L{nq}&j=H@oadyk;|{kL+sl;ksOI3`@+dmlKS58bwtr zjPuuCV%QMXCZ!=b;UFBNx|+Mqbo0&K0Z`-(8w4|)e7Mn1k;a55cHVM z76?V7)#j!g@K-BMP0=r)educIB%R$uBoZMvI6}-aR><1d)HMs5MH3CckZ)1z=Z$Tk z(ku{yc4@M3@_L+RDY2zP(o3^@TQC3gyF1Cd8Dh4>VIs^k6t?|zs)0!=m> zZ+a`+H>@R+NKnLP&>f(?vy=4?rvb@FmLE#7SfpPGI&FdP4vv@L#d#ffYmA19$SFK&u5 zr>C3w@fZ!oG?U6@cSf_D1Tj=~l3TwYn$d)wvXM8Ajs{sN3)tnlU)R@6wF zUN6N_0!CDk8e38p2~^UhOG@U-9Uui6?Gp30;^`JPdJYY?g>Or6H66lcmpc~+iR-3_ z0jD}fgq`zT1{tTub{O_7L#>sXh-0%oW$3L@*)hkUb%B8$DHa`e7#qIvb#l2JyIdD3CGmJ1XHF}JAAV$26Q;Fh z)Yk|rLe489r3?b0&1X1{!}ipG$z{_TJIF2xcXsocKfJ(3n(*7_F)JOVDRc;aMlrnJ zqbo5%zBo>Dq{IYZbR-U8XM_$rZd>V zca+k`j)l4V2meVTk>KzJJ=igu^4WqlYu0n!r*5R=L1SES_l7ZUx#1!B=*4_}_1kIH z4J6eDVxo(aR?OqH)m=QcMRWgyBRpD~WTAFhmC4aLgYG?rs{G$UQ~U!q)FzBIA3=Acu)I029rxjsc}B=#nlFxKQdl*_pJ}US#{_o_`68x zL_h<#n8uyli}v*@5S3TMF_S^Cm_i82m{K&`4vF>z+k3ZFLx1*%rU0Z;X%dNc+PV@9 z4DKS4NU(l=FVQLl_1BLl{+cF5Sf;=tfG#JhP0Ezl^MNcR%hQCj#-dm;riww~qqz3; zW7*Q@^425XOLMV?yc%F}*AdjFibOJ-xcrtkA%5@^mO9-`q;q`!>=QXU(akMSyu^B~ z`41<{rB}Y6NPjOUN=c30!8Yl^m2c+}t!N5QqLfWut3V%P1tCKodEFA6oJy9CAg^pT zrs_#P*$Pnupe)YpoF_zpwo83a%D}o(@H!Nr9t7#m%s0}71 z;8$&L$98wk=w_0O%Xt&EIh@%=n@vk870!>7@TP{KzI7tFs8+&YE} zdHf)0wymwrAT++FY~}Ix`0ON4jSsa}I}Jp^ih!_bZ3&~b!gW0wY@4z$lpRo(+-iBz;;-C^^Yju{0}q}r@GJc)3Bmin^nI9jHnb=vKe2#5m15FyhzMxWf(dEUmm3d`v*yH}b}~9e z(Mh1Z0URNzkq(2dDFn1;6SucS?Lv($8KOX~YGS_KNlNuoL{Z`d zI<;b}gbX%|gpF|5kQ5pz7cy(0mnKoexR=5b8X;_kwPr$%Q)5eZ;Zm<>6G9M`nxfdj zPB(?L7tw;mch`gczlZwuKamn$7I5UEh13bbsOv#+pR~8PGcb^3^@a_cvSSCQEnm** zE8fWO9{fEQUGxtOdM=LRR4w&W+jdbp@loutD_FrhR*N=xjsuVAxhs3pTP#IPzdt0&BVsd4@xS7f5S zz?FCX5t@#Km5+1v4X0AB+HeBGrFC4>n9~kE9AFbzg>pYTQK8Is;gk5+u zbVdKyC|{MK^WJW*(@~asZS0Z9rqvpwz@+apHk_^616x)kXeJ7b`92N4CK`=0JUmP! z5}^TT5Q0phKvR>^o*cJyDbGCp3=Nh=G#VwjYbSGC+Q{ckjWCW+C>jmI9W@OVZHn)c z3(%IbWuh%CYpPKS1vId_h{cf30v0cB-atpkJoD$@Q@Nkydv)T~|BFz!D z?(C-li}dgwx;y4k$QQ6Ii+rFJ6hc(p_spQaodNAa!2?S(mdg!YBK<(fNRfZv5-u4L(gEZ@E4SSH4|6PJtFqGv-S2CLU`%-O#- zG+}EK$fe+~=7pQyL@{u!D+iJdD#(1Gss6jIQ=!ldh}nQ2a$2LJ1yb5m6eVpYf_j>@ z@V?3KYDSX+&@63A!H>%-k3^!KP5m25rBgwZR6~ao$8|F^-cw2=PD&&?x&24CF)%Pd zoiy$>B>^F28Vjv8b>rqT-=EvpfzXt404cuO2Bm(QqgSnOa#Vy6)C#DbM)#@*O1gru zgiR2V(6ma2Iw^2nk7&S6Yz}NfqryhmHnqW|(+<1*;|E_yFJbQVip*s$6Dg0L?oOm` z;50eF>#sSBEDl4t41@P6USS3= zNKa2Y9gf3i=mDUI>ZiV7tKTDR(qj%djYMYu_ zvu!7HL>rCGaKh0`cy9A%gs>N1ett1+(&J^yLNw+|So>_4{UV>t)RplQpDefrTNPudI#n@z4L7Qx6~FfiGXoZX{75ncW@Y{NLue z?>j$Y&6nOyBw;fmp+S3C+BLzSd!ZXz9;rQc^X3+CUv?p+YAAIXJ{5yWmGr#^7eSQ7-nL4tCLmAZuAy%r9 z3886dk|+VCaExX&W4RRCuV=z)qFjJk5r=X?0V#TV=CQM{mUo;yA3a_~+mf{MXpG0W z?C^hwV~&7A!C2!qO9KKF%ysdRX2s-hE;iwnBdbY$bhQW)_W-&6O%$M%Ef9*93=ZBfw-p00VgAAn$%%0Vbn;)jLvlDNR8L~D< znsM`aNntJ2hJ&+MVXCMqSnT$e`2rdEsU-cn);6`C$*_zQ598TU*KL8v%R12d+0 zGxVJyAaDrEF)NX%c2jywR zj~!z4nzz!N?58>Ib4UL?-v5dFjlX>1F%Tns^{h+zm&?Ll>%%9i98LvN!!I1*TzW!W3 z_T&FD4nxg{gIGk~P4ndM@1fI{6qV5?2q^(Up`dx&S!eOwy61^E&7(HpkpAJ}hdJxq zbIB^r9VAAubl@cNR;JnF$E(udGs(4kpluA*wcLDWE z&~14?|1P*&4v5~oHi&rt&sQe4TL$|1(lu9c=N)&E3W}z&0Iit{uAO?XN~7|h|M^|s za>^+jD&u@;QHbXv1-|jSA-a~H#AOTHXh=WH#)Un6{4>9XrWP)I=Wz_>iqvYs&+qyn zx%2*!`~J8#ND$UUQ~}4f@m!B~>CAwz_xBqrfw*(q9X|Zw4>JaQ=iA@L%X!o)MNSwx zoNYVC!X0gl8Zg&HWupkQH>zS@GeC-{ZGLM3k3HJZcIpMxB_u;SMM?Ok$PhC(2(wno zeFiwMt@e@!YzPjv(G`Wa-)nQ~abU!x=^z)H*49CJ_u&IflIy1(kdmIFC{!lQCOB<; zuWQ~oQ`7(eAOJ~3K~yOtYY~n{+x2Kuat}FB4&rGFLl!f5pcf1`T1oPTsG|Pq9u^~#> zgr#ZdLuww)(&)s>!VDmU5TNIy1CejRER{?s7nj4)8qPTRPzIA3WDs~Ngdid$U;O%8 zsMWA`<9a$5^qBiVDLS2nOeoEwMR5>@c0<;qJszS#XHddnlZewK*RUuI?QS2$eV8X; zOBcN=3jn+i$ysYfJLKG%2-6LXuy227>k;FN#*l|qEVWoCZnZR`;@eC^s2lTj3&hj zXkb+7=swLfQwX#yYG6b`YZtr2al#H{WFuvDB&R9?EeY7ZgN62NIyyVK^ACGC>2-^_ z?j1+*`71hkX6HuN6I}R_ z+hF@)Jo3huIC4>^af0={V7Nhmic+O&m#f1@vClg7SEI~&|C{~vwJ%gbMjR(@_^W|q zPIJI(t~daQfU{QCQ(xLs8aV^*G;{)_*-T3ToucAAW7{$FoRB0EHhq1`z)rMg1|6)H zznw4n-Yz_QH!k%7m1s))GDY_?4NDNL7Q9VfYiv7=5Mil@0NA!TUV7Cj(fgLS$+`19(6LVRaPV@eM`2%#E0&){?IV{ct zJG!{$&doITMET&!UHopt1mC&yC77Flxm_S!&@sIzYzEv8Z)Dd<1@QY$}rhtu>z3%o36g$7ak^jwgj_h&*hV!IgPwupiT;!y4vx)0?ST3k>$&m^KxI3vR2ed$&Ni)&YL%zNPC>u zU-&*E?Tc8tILF!tH)8w|UFw-bt8EMh1_RfqK~J$gl_V0edAV;Z=b!&BK5_NcL3RtA z|L#l3WGbO@$1vstlnQkEQS{sko`mk+DRw-;dP9)MqSQ>4c;}|>Ty1k~IGmB=y z!w=lU8yN;(Hr*ZMhjdxi#rQB3Tkch|W?@y9c$$*~eu>)B7)bANgW^i3Eh$)cR!nlKe z=#ux~WimviWRL{UC5v44#qWWf3k#M)$_?^wg!!+ljBRAZHs`yriCfP(lyjH2Q>%+; ztq5Tg6(BGgV)gw~2K;?a+fhM)W*b)Idrd)B>(qLH;#si9#d94qY#dy9z zInbgQS45v$->i)>%Ys?6s%#sk3HTc@)USFXjNu2gGm9~NLcV#wobTfU;{~72&Q5&o zGpbF%bv)WksLf*Yrp=tRY>8nz=&Ad^Qb#GR$$2jGmUIV$XAQX=aj}tz+eC{7Hy&6J z3y7h4;7>^|`Q%G*{7xosKZ106J;x>#r!HBeyH z3M4swNhiD|3|mLowrQB9OS^;6Z>SSfu^<&4&HmQj`oF<7Iw58j2GiHOP(`F#5!pqB z2*kOfY9|Vnw0V;}KcRw9pJ1h}$8gXQl^`3V?3IDLO=Tk%8kAN%@x-&-dh_R4x$+^B zo?E@yD>u_?Nui$*P^Vv;P4V1(6EHepADiS0?%-5=wMO=c8obZFGsTs zBc+BN z9(;=H&+8!PDaHsq_FY5Ish>v2D^Ekx+NGT4X|03gS)&=K1H9n;hLlH_v>8tA;r5T8 z$#6QwVixlf5n64@C13hH_uTniR-F45zV)piQx0x|=H^+vxN#kyxaMY_Sod*2ur0Nl z=B8#Qtx3ANy4kgB1hA;&|14d)l)TmyM-(y~W1>8c)^Os zf+jnXWyOjWJo(gfJoC)cTz1(9(CG}=1<)S#DEij+(cyGqVY9$-$SRl7bT7tf&887a zvycoWH&CYpvxS3?BC69A2GZ0!adI?Kma_>dO^;BNoDf+rh4B!Zy61F7bMzN&llm3W z6XUpLnrXzo8(E3{P2Kk$0PKz8{B1U7bKORTARizRy}kW(IB|wkDWX!&SnRZ(`g~K& zd8~ZuLA>NR^*Y6_{`LIohEqA=^2b3eV(!Q8XX#<504?CJWAhE~WH7mkX4%614{hOH z5ANjd`~Ltn%Y(O-)X5N04I05NH;t6~fJjoUt~4tyXTSLk)Q%gGdnM2^ALwle=vs!( zHI;?Yrrc@ASnu;Y$E9NoJhWHUvj`!p^tkD$S$RJ+rLvqkF|OO2T4o=t5R=o2mVFVQ zgHPP1P=JR07FgndjZ9Jeb%kQxK?Ykj!Qa>Hrx~pa?t{wju3>rzvL+X-xie6i%J;7B zNqRqYoT=wx$m-g>Kcuua_(GNY8Zm{SODWizOw(%H5Kxnycmh>aCM*>}Uw=P`b$63Y z=FIh&F+r*=F`G=rCF7-;*PbAib`e5i+XfBUu%QIgi$5hCO8LVys>?+GqzZ3;MD1BEmUZUuJJc>Yn$j>o9gkWPCflbcNQ;d#tT zbWx8n|Hvwrn{WOiAO7%%Ir`|MsR>*O>w)k8_=lYK-nX-{zlPgB@@778`!>%1(05t= z)YWJW%fmi7dY~P)Y3TmgBcKn1!`HE_U6by0$x1s2eEds?FyimpuVF}H+3{4^X0*FW&trGpiSwgd-2qCa6YlcH*SwJWnMOdO*s8w?y@l9r(W#Ma| zNW>!RYlLMOGh@DKaK?RzMw0 z!1%s-J`}O=3qGTMfq0~ua+`&>Cky!kEp09IZr;W6R1pJf_%_mRKzVMg2_dN_7x!oXj_$L<)BT;K@QYRBtv)@17W=Qq#d%6m7$?i#>hnY)$eBkTab`&nF^g)90lK3qvES6hs8)s6O!1HmH!ELR|uMtrVqq7~YHFLV><7U%#F^&OZmOHUIi=p9Y}6-&g@xCW|GYtE-1GPoYtaxMpIBR!j=Xs5aO7Y1yCi*7U+|?b=>?Y==Ec6H3gbF4NB= zA3KRN-uX2+{uI{VvjI9ZJ3o5?xed=!>}sJNNi>w<<$)xF-#DMviyk+F2kEdmwUtK4 zrd~j^49!4_Uuoi~gW=9VGF3%8O4=kh*Hs4~u5nMYjcG!KZfe_h^;j4_u{q^adId=? zn6j5JmdWE%P}G_URhh`^YVlT@#y_srQ$`}MW-~b$jc|XkL;XSCzoh?CjfwfJCUuba zKPcsJ|L!yUPM~#lwmhA~JsC8OGYwa!EOlztOw=a)DvH4HUMS1-#&qg)DnYLzXf6$k zJ>6VGYgo|PZY)nR`B4Vtvx8xjq!pWVI*k)|sFg9c_x4k(H3I`l94AJ1cQ@O6lgvsu z45w06B(w4vdCwyxB-{FWvF#YOTG7>&;Du+OfLNsN+y4V9Zk{!$nBm zdeMh?dQC4+ui3zR-*X9Pz4=UzI_fAcy67Tid+Qlf5&q%i6@1|KN8z%|IOaRg13lDI z;v$jdPPZSPUk&rlha+tM@ZK&;$yFvZ?7wm7@;}$G?En5LAr5#w?v1LH0}AQh_rH*4 zm6@oz4n!EEz^qwq4EY6ozkt@d>h$U3Q>!5o5y9cGrZp*=F+>2dSd@iDqln-~j8j)B zc)bu2GwltoLlKDa0fT<{n(=%dyRA83@B~9-AIkWQ`q1EOA`!uu?=xN~poa5|1(dG_ zpg9_$PzX>OA2JkZwj%hxPqyH3=%OWT+PHzsFTXs<8M3RAhzjMmU5(?Txap?%aN~7P z@y8vDn0x6XChJQpLv6L-h6|Sv6+7tZZsL&FmD%#N=4+qd!q>jP8=M5xBn&DzqB-sZ z?=fqNDuTAi-J7HJ?q|U7GeNojT!C?@HR#2Ic=D zqli%5bd`O85O|(Pvy?cF!-P_lgFqO9WZTLHB_uOCF@z4L3wl~-EP@kML80Jn*MSd4AJ+)^B);#JqXj|EGue;0Hg*Pk#ABz@kouIPCZn`T5W9W!bXjeEmyb z+x{oWJ4eT$}P#n67n zf&0^%> zcZo|s_zv!PEDaGj?}$!1;+m}NAuZwvmEpu?aehiWElR`YHBb-;(ZDRHi+rFRDGM_> z+dnl(S2^5Dc|?UEYTMOyLI)d0-84#&475{OWv;bGCxPds_G$_Ofp&0zHhQk{@~Fpi)1sv3${gUIZ!K`0CLS5dpKYTddp@W->{7*S8bt9 z!&85JoIQt!x$3H`iO1teA-VUSdw71`IzI7JIYFO=d-_o)&-zvgTIPLt~iJH z%~{N&kKK(*NJ0vx+s?jLitE1X!hbLA{k5ixmk!b_zgAR52tlnbfDlB&;cAnn#1&yyYg#bMHtHe~_UuVg z>l>G`Fg`*|a(K@&PCxyPdm-YYI$Y4&Vj!93%{>n4s*}0(hkpia*yTa9g6zv&^R_ei z>}78x)8EU8O7h&5Cvjuq1-^0b^RT%I23=qr3hVgBRV%pa!e;PNT&JJni-lPR1@s+= z%r$WqBfH_aNp{?D4z+rm3FRSzJ<~Xanh@a$)t5*U-Kvh0oVtll7)c4 zj+GhoFUN66rBWzWq^qkPkX0TlRVY{Nb&HA_#efdnN0c&J71zxeor>p?N~KL|chG@P z7bjLUD*GGOy;3uBAXMd5)4-;4svTU;tAU6EI~3OE9)b7Y4624>u3in^T!{4Xr*FRBEFecLp}206kAD9tj$ZV7 zPD69dtxvxVz4EZ|di46x|yAD|=Nh2_|! zQZ9=YEkS5Sy_DF2(?wkngr}58yOflIY=FjT^c%0YpSG?9&BDg>o*^o1q-bK#fDw#_ zgk-ktp@bl$6cg1VMG~V6G>qHO6qAf*G+-lbQKeqhE8}LB#U>_9;i&-HKqbEeEmU3` z1gBB}*B)e3D@~i`RygZY&UEpczUb6V6S7T5P3rfVv`^JNMzbcWO->12Er6#s>c4D7 z+rPGCst6E4W=X4USC3Og-!Y-o0WB7V0N*V#-d#u9_2_mwff0tKlNxXPGVSl8mOw$%qhw zai5QYfDfH7L-;1}34zjO#W1`;AavBpSZ*3n$QS?JXj97bN85-R-j>sRGzQqX$iHpj zR<0Y~_VMwfoOVasGe%0?TMlc6;44x}N{-Sbz`)0-$QR9M3g1t`xMWbLK?}yj1XX(4 z-Zlka97>_ox{PHq@@+fYzFI>(=t} z+GmYniV#J2BCRw0^A|qLNh?qG1n%(cvl))Djm5nkvFYsU#ImfSCe?A$;24|Zg$oz* z>be(s__4=0zO4;6?ckZzwVWyuoLI2#yX)v8q_5=p8oi-1;)sT6KHPREXo zyz=ZH`S7`CQSHyMeajm(EjyP^C(gp=2FlY(?z!?bt`lEnaN%q&cxoGKE^a5M!+c=X zDO|i@f=GHNPyFe3l*f((op{%vLL64(^gpN3{huCokBfqyTJ6ig+vYy6A1|jbqC2kHmm~=3H8-Kp%8?f~i-h3h^Ja3+*_R@eg>T!NWCAH>t-OSo z)a>55fn%&CM0J*$w9A(-uIHM|KSFBT2%}w_u$Qgi#OCFU_H@zJ(?hE@!B=m&k=xT* zb}NTjLeghRMhP;P2J$+KuP05HDCk^GU13?4nM?{pH6Jf^j6)aC*U|rh$x79bPQ3dfp=B|M{8WCeJ@z!Mc8q*bn+-5*(b?I_%&=hL!X@lWICOS)QW=yuNtYSY=%5Go2rhu9ajh6r+H<@Uf5#p2P`yXFR>cNOK~q-Dd!WSTqfzL!5ZCrxFI znED>yF(u}2thV(3 z3$DVnHL>)2ION>(oA07X6w8@oQhFVWBYeEWRJDKp!VE0S0NcW!CXH>T_WBFgNx>*X zYv_1u7e3zvKmPH(T>J4)am~j+#`5L!k=}Z0S;jrDAspt<>z+kQ!GZ+~5JK{UAN+uy z{qE6XkmSr*l!I}n_#SHP2m!4Sz=57P@xC~py8csu#&vDl+uQl-&wtKbX>m|WmaSgF z_iq0ZZEbVdyTK+HjS*-F5C~0x5WMANd1gm~S*uzISvEgnnE$fsyc{=;ZA;dyS;Z@x zwsOkp4Rm#Nk(UBr)TV1-fX{#BHa>OBEl4TYwrv~F@7Y4D(@l$198Bz?#+t_ykd2Z6 z03ZNKL_t*R$vjKfTtPs%q&|5fzAWTI83xk3X~_l|(~|O-#h^+v+f^jw-{<@~G|~Q@ zft7b6^_s2+JG#~&_cwluLq+xF+L#-RmNd#}YGHV9hR)sr79CfI))Hs`euUpVzM*y| zFi0?1%UH%tScD(^VuGAkD^3EVAU>TT7z~on`0)!tpf-%#Kfovu6oPTBDbMAo2nMP3 z`zg=m7}A<_f4_IF_=}14nL@J~v**>;){@C&yr5}6xm>0QcFJ{*%wPsn$9=csAOC z>YaWLF3=1us9{UjMq2DSyrmQs*)kRiN#`<~w#8Kp>I?%tTdA_5>?g{w)6H=WekLLo z(dGb^uFGs`qY;ehZU!R)0wB^5iA2a|)816lVlbH|5ST!S0Lf(D+f%1cZT~(whm%cG zVVYn1@Ta|ROef-p=whg6aOl7H%fs&D* z_OdxZN?&m!E~So4j-j(yRs`2gQYiyo0GllGUB^9J-;pDIk|P|jfheG?D(^d^Rl@<n34{IBmS<#cA+JZih+g>dMGHQ{D zcMuhtA>g1)F{z zpHvG{i%8? z5$qQ(Z3v`&C%g*v6Ei0$Sj-y+Vq>lJ={#e7y-f}nCq3!6G? zfY&?gxvFD7T}p6Cqs?tAVU}wX*X|_fErO*n-oqazL_sU415Q99*GBhb2q z5qB%GHXq;LAmNqSkm;lEdnfRGXOheJ?PcpjiVdrl@qq<`uB3xS3qy1hP_AJorOXs8 zD4?80_j#}I4Nl=qf zN8!&X@85;_T!jKJr>DODA-GDsvr110is9qAX*F4CL0JTLVj7?*c^?AMuJ>!n`_;+_ z#=*G%1ij`}N*U@}*aB^Gl|VwvKIoeV{<(auqmLIalyte8tdLaVk{32X<&s4fBLxc1 zUxn#;()(UBnFHkWnq6BuIp>s9xZ(rnbK6~aA$&e_y}F9()&|D?ezxz}!~52p&+WJ0 z#fd9c@cs+0;LXjOS-xx;Xw8so#PWr3JEdF{U`fH8#qHF!M(A}q(OQ#CIt*)<>n^;4 zN;k`x%F`KlXlpx(K&*j>AA69iuegFYpNrGk*~xJW=knNNPqAd_Qf822q^E~B{^J*9 zh2mh`A)y@7ju8c)y5?;9l4)i{V~n^i$G6R8*|KHqNhIj(>|k$42d6Aq!n1#PnwxL@ zSGu}7iAEPOLurI?iED*c3aK>%Kqv`8?Po|z2EFgI64)nUmXIXkNrF*hP@$AD6-XmI z>v)H}v{6bE5t5*CJtt5}QU{r^2dIcE+N>xV&0E^&Bxk4~L09pXl_?3zRa6TTCsAcZ z4XsJ25-s78ucgtF!cdgj&gWoQKpIUzYXX#!^=h{nDo=Kbwy*3kz~m?sOKCIWIy74o z#sM%0WF$9V`x*ZD{m-&x*G!fzJDKI@tl^bspT$=_gU4X-7&_PR@E~Pn<&@)N90&$$$!CYr;~L7} zCa}8)CV<4iAdGp_)xu$z7^e(~9~_{(EWoJ?=i>SgFmLf1?%!KWzGER=^EJ-C_zYAc zO-4$DQUr9EyiB2$%M$!-LR0>;VLmpmhM&IQW+0vBRUPLz6{Ff#eCyr=_=Vz@PaaDm zv4{Fd8++10KJcqI+1i-|ZL=nt;_DY4!-F$823#uu{OB_u;Yk60-y+B-D7$wv4EjxA zUU+~ZVbd3_U{2SgxRIr}&246N8i+F-$uO=hs&|gi5X;f+1Zk2648-HzfZ({;Lbk?} zlvy(gk!Qq(kfj+@4s)d@D{Pdq(6X6fy^bYf1vA|=qtd~Sq)c;;wu&}?!-T=cnL znDd}6%AG%SIQz5^58iSnL8l9B$%j7w1_RsjCTp^8F7O(pW^wshaX4apQT8 zk#!6zhbnubSiel|x`}rT)`ch}xC?{`qZF)LzYY50xNbcGokvD3w5tgOBK+jhwXjF< z@}e1>xVV9S`z`i6L8776oN@g|*ig>SMO}R0tm8;Il9~lRLbq>+9U0i%0Zny05Z=iH zcm0vIfA~-4q;(OHR2KFc%^|kPe|ty$olq-|tdAJh-ORTww2rZ!2%r7zeK4zyk6zYJ zZNmg-wjW32$;~9gbGYD!`+4T!YpK(Ds@+b?tO+VD%M1-N#z}9;15bG=45ikRZ_8Vs zUMC-^CLcYFKEu=r8+qWW<7gBy4hYRLxM(fOSrAl`N*sngFkSTWFX^)8-)4aoM@XBV z3IxlHzR-I^M}Lf%((sv~%8qjW`ilQsiWdsU!tWjL9L6es#Lar3Pf{xbWTZHx!Bonj zKe|1#ep|{;K?~&*l6+CuH+d`5lAN~(`n+>7S7KgJ_zV-%Y&i=WKtC=$LeioHN(Kn} zAd|1-lppl6`}wDU1xG0q1t^W4HboUuP-9z+2|rqw5p9fOpL;IDo~YSPr;*Y&w)4p} zH9|1cs>5{$c;A{c_~oOIGJnoI4)*mGGl~jY%u3S^pxk@?gYiOmoN06_rC7aemDjk` z1Z03(Y4PI5*N8?N(YlNqKK?0|FI&d&@G!&KEMNZmmszuB4cj|AnAzOSh^v^{9HYCZ zgJsK>@y3P?SW;p|ZE7PSdU_HZa9n0YZDO%D5{U%0(n3m$v(CGaA;;n8zxf>lY1gZ7 zR54NjG);DtUMEhqWf#-Bm1D&D0SrT8M8SULP!+W~AS3~;DHk?qMLi0o9Bezr!R`cA zR*3yh4{0mJxPTB2F|m)4_z5JfK6c4IsvJMH(qfnDCLQ%5ZJ43zNP2YNQEiT^lokSv zGuz*JU|4W@oz$vmFUYZM+Qh|w7;0{56>n~i69;LG8D@rpka`vTuwco2ns2y@dw=-^ zTQE9i$3~_{;J8VK_TZZhX|}Fs)r_n*0fwcFNFyWj&1te68@d+UPsq!5$G*#~5W#mk$! z;PJiuY>(zYSDuO10x50Al%`(_?tY{TM3CFBu$iH={OF}BKJm4Op{WJ-c0lbso)z%y z#(pljw29v=i-C5z^WhDkPhvb(&2Cu@YNuJaGC}tAZevgVOZ@QS>-pun?Y#Va8H5kA zn*?mz0JE2Z?t`$+iu)ht{x4j{vbmC=(%6=bPYFWGCMDFnI^SkAL>SBZ5hCXq!wiC7 z9CBXy3XAoyHjYG=Wg(QJySp39k{-X#Jjn8F3`-Z|g0qg4(wnL%q-F8cQ_pe3$3H?x z$6iK-36UHvGCxh_BgpwPu-lw)G5A@R0-qcga_U&OX5QlXb723 z+AfE4Pl-^;01eX5P}eqo{<$-G;I}`5`t!N^(%&%h@=g5uzkkEv(`8)z>bIGA`Z`ch z_VGu6S)Bfl%NbYN>oA5n@iPz5^NUM(Rl(|;egln*fQ=jwiYhHw6rIUfs0J&bDbHug zqG@bzrd(?V(%mdw(8`7l8wl8KjM8oVgIXh`L<8eOVrj^A_0ZBB!0my6J;9ix7-bH6 zu0@yQV|6UVp6(>Em`P$a`lkR$6NGv5&7a|_tFEQ9vy0;vw&OUCmu&1Kk zgbHaAlBJZy<3nCLca|z4sIfv+3rVeKM>`%*FswDU2;qyA6&D8Ejxvg7h7~D>0SX~W zxZTF#ra8n=GRLsaFhP(fHtgk}?|KG~T?KUkZj04WBgXmMMxZaqiC_F96W_Un9vR@G z8`nZ^5nM1#q^^zRoq3*mCBxT${S4PGi_p~2%0OxWmPJ541(_Yt*a)c%?_F~iI-emC zPtXu;$H7=6CzN{#wQDL^d1o{#t;?torojLb-f|!VqXdb_3C0j8W%N1hb0ODAGE>Hw zv^f|VMg-bvy>>0U)dKZlg1R3+0wMDJ<>_j8tqFn-|LdN!xO#4gMRz^|>N3u_=`EZ) zn{ZuSGD-2Ksrv6nnfU88FH9R>L#5MALe6FNx7NaO3#k%Yxcl;}*`MrzbQfKBUy615 z-7x=b&bo6w=`Wr@nX`{QG$NDU^Mxf9o_pT7l+=U*o+a?nrbB=IaTqUfdU8N-H)kz7 zgIX=wn@)cMu-qnnrxM+g|$BX;NYkv5#bfw)5;co z=zXQPls!>G0q{*u&kN6AasX3@Ic()6lbb=UaJ8|~l^XK+h?D|{X#rwdAN}(s#iYG( z`RjX)f zZRVz%ZswzxT*&TiTlvQeE@l+XpB{MvofEw8gC8W5*Eo)YZJVa&ur|(&uIn;0)>ae` zTb4zYl*Hq4qR}X0O7m9SI0&jD^;uA1S&S;hpzBbrpx&~HOG!$bT(m*Y6hlahxT|Q1 zweyynpxg>DDqu!5V%7&?k;P(IX%->aFEj@<9H)cKRAC~`7O(Vl5D*p!ML;VmgjF;e zD)%V1VO>W49W)b;wjlaS&LNZEBM?F}&V*scOr!mp8NF3_~70%alPRpjmbdREr>XQ!6`q4{*gzU*p?*%HY*x@o|O8!QmQ-$;<&D2$>W$kp{9o z32H49=do99fu<;=viJiq;ld~W{kO1k4ajaDyY3oN!pGPDvY*{=l<~lCcJkfD$5I~& zfM@~s!AUW0iutG!f3&Eh9BrL6W+eajxNHFANx&6NHGxz#C%%WU$x^zpZUrHG}O(t^` zhKsZ-RV*;1v^?IbD$-60`jdjtx)K-`My$Jh`7*xrrLRxzX6ZwdC~Ysz{pOoL&-v#Y z3)px(fn`}7j33$p3Ho^dq7i;}*)k4n+eU*OU_3IHFZ}8ae!Q^{w9R+l7hqQ323B8w7Fws- zE4Nd*cr_P(VGG+*uYs_s4ZE!W${DylJ%ofO61FV{l_oEI3@S}D8UY%LVTq$F4<)TIw03^hjp zqn5D;?(9quj@eX5fs>3A(9qP{&OYVi#=9Pex^wvS>Kg94yb+=EKqY5fIF}PY^C%41 z{QM8UW_bBZ=FU#)BS@;w{*k6*9nbC=z~Mi&E4Qu}!G!Rt6yYtq<+ z&^TS&2q+5`Yh{Oa8L=|V(3%>;jK50`sJTAyyoE`J>lTfEzS_-+3d5m73nG%#~#N`l79OR0T_xk;}%Vaz53mKB*4tP8=xqf8wS9_924YpeK>!{xvf z_Q^4C|ErW{a$Yc!F{}X75E&Pfj&7BhsarrwDz!o@&9GF(@4PUr8B>Z;+w$l}iXkUY zbp*3k*N2aIWG0O-bg|$PCBS7&Y5F}NeN0^=r=4{cQV2AP;C(+uN=Z#5!bmzvRta|P z+Qpe?p2kTFmk3wXf>6j}-MY23wOv6p8pXD4?z{WH zX%0#T44P)=aV>M$xN##(moB2pvN(CwN?!QOIxnY1GU6JW_U_%g=;-L+yz|cE z#SJe}i6GwR5NV8&&1xLiDK=20w2Jzi8aqm_E(g0(%$1T^I>=5^26$r{y@e)KxmJY4H1Phnuad>{ZWLc} z3SExZ_?yD&)KjvH5Wd4cpP9m#sm~||KverA)Ym~U$GCt*Mv<1YXgvKw_VGL~^(to8 zFJSiU#psM?pnrg1FvoZ%$2cbUu!10C!h|wrbcO(eT+Z-RD*O{hN8&fO%H#M6*4C54 z1eIs}K@zD9k+7eNU@hDC_7lKQmRvDsC6Fm&%s)|dJ{uGMq6mKksL)e2yjA##r~1)C z(ciO!8$SOztj0Eu-E)xLC7`Dm5=@gh-Ml|K0~#Bk?=Mq8ilKga$YorZQSh+Vj46e%ENnaK0Tbm3;Tm}9h=|lFq9UD1zxa1BT=f1O6g5x zv_?vs0p;ggi^loV_9ytt*;O0(lIKiWahGw1WgpYP@u>yxwzi_W?fZ`^z-EqWhmUB{?! zNhl4e76>nfJ(anogMXb2Gz5%#GbFMv|gXj`}{&!#Q`85^4V_?L^%U?APipItwV zI?E}|n)^Pyn1}z;!@T9~*saan|IN#2k%~$^j?#XHoPHQ^i0#jF4DhGTZ<=EpUct8> zuOij)8o`B&`Tmk&s%@X4y9tXV=KAw#KOrP3+@owThcEUE*F`1D%Th4cu^(^hhPk$s z$}p^5Dx}fApn=Q)nQS@3Izo#MQ?~z4ob=Uec=d(fL(osyT7Xh;K*#yaRr6VV${4Fw zR*~DVfv}v%BiqIx*9XBqVA0!7LiGQ*Uxq$p(pk{i8TTVir|YN5j_~?Jw^JL?)THAa zR4#t0iP$0b#pA@HQMNqz1*)@I+;}%iNb0Q+{XLuc)xTaw*5{)pohH>CCuB#dwJm%~ zGk!>Ny7()BmZ1z3g2E;-O5W%&v?i=!f4q|h8zN$Y3Z>AlOAw2Y<+;_lilEk1NNH%f zo;zA_ni#lpT0wp^AX%XMO#k1a;fOfGbBM`li2pD^Zld^Ic@AaMsBeXJSfKG~c20 zG{c_Wp&X6&=tqGPpc0ZcLjr1m3KW$n>O}zDIP{kRGmi=&E4|}2>QQ>Cg=83oauq`O zd40zYUVL#q;{vX};vcDyVK1FJjn;~Wh6wxj_cP)u?z!h4diuZ4```b5cI?`*F7H+{Tzv#9}RUcJ9HlB(J=( zo-cjri$o$J1cLu{)AfA#!yo3)>z-v`AVr1rF`P^js;eg+kMrPzzvmzS@j@CSQJiGj zqX8OlV!+d+POhP$fsD=*Yi=eWDTdu0zqp;<+X~rO<~loeK{I|gYceoeBMc|ggaZK* zi6p^>W|A6W5-MqCIGM&5kmRKg3uw`bzMY#9B8F`X2DG56xtWY^1+w_E4zu(Q_ELsV zNrv1mVhb8b5M~cEiAr!)C;7CEB}`bRY4XTPCWoB(JFSsonlX}Bv==4;hlRt1rb*c} z+E}61E4aAk8TT^7-1I@nWW1tRQWkFEm{f{m+9J%AC-K7bFSBFsdIow9(A?b2=dQYn z#J)WUAqWP;o~9~8B@hUQOI%8)($S1A%Yc?GZ)|7jNhjer4mvl7x%1|swPsKmJ=Ijk zg1>~uT381?BX|E)$1!uCVAqx{JpbG)wAF{1{}1n>eQu1gkf2@-uzN5LO)Zq?^PUsq z)TMA-2r49G(a_%qVU5xXDPaVKA3;3c2zrm9VaX_OsRKrX*ff_rf4rLyUVI$2?Q3X2 zGx(EFv#z6uzA6 zKE`AceR1KP>dr8H@C8-C(V+@3;4t73$UF4yS9zc zYbj=^FekJ}sJ2G=uZtEUPR|+})I<^} z*SqOWBzfIxM!%j1J-~+l^JyAImK(492B*IC8Ls=;dOmi=vHWJk5Xcp9LXQ5goX?_UBA9-c-22NYHlI8`i z{O29tHIoN&TCK(KxL4l07?oPGSU$4Dfy$bg`#telH4zKGu5UOxE2 z58^m3Gh;10{;QvH-Df^eWyt2l<;!qgm)6#1K6U-IJpIQBGE_)SZ%>jFn-^1;wkS(xSvI$dbCw(rxQuN+$VcV|NJeJz zsfPx+_l3>S*A4xR-1EQdn?PL zOE{>+VSQJobiR*JNKU6VO>&M44F(M<2ZFXI-p-XI=6Z{pzY&!&qR)sJVBhQ4v8Q>0 zGx`?7_7M^uw>(56H3T_sfrV0A$jbq8?aR38+D9R1v!rFB#0hXZec+vf6n&IJUL183 zo<6xKz1D|yCs`T8(mtA;9@1`t;aD>%A*t1!WVL3(j*@d6TD@!9l~MY%OReanLii}x zaq^BvVb(vT;6S&rUmq9m>~kC$$QYnfUPu6{0kyP1cV@@e^J_y^!cJ*PV9q;@-k0J0KQ7Cz2&{(8%9VK3+G`Hz+7%zpQ9E)-3 zhZxXM$(1QXg%m8ddqk^cNU_?jjy=d~BwCOn5eDJ5s0 zeI9*%4mEy>ZP)R`pZ$_?0khhh*|{@8wJ>gv+wR?rsqJjpvW3l?UuXXO z`Go4~xZr{d*wd3lDMghfsSTK#W$hDB@ZcXG=A@-3@!H1MIAz6BT-RmEk`*jmxY+x= zipJ(<{_~FS;ZrHv7cFJ~V{vNb1aEHK!oS>oH{W|?H#h(AF{oPv85fRiGc<1HLZjeI z^L%{sqLt*jcGA<`LB)c_G=A+#NZDrnJzlW>W2Yf)MUzm3LLt8U++J>dbPMeB0|Rhc z1CO59$O#P*#(H*AjtR0g%~<6ny}$cvv1-aSn=eiS$24yPub4{9c0}NxIMxJ+3YZcZ{0^oHj4Gk2}Q)%2dEoaPu;q>@k%`3yszeN@bBU zK$C6bx^B_O-HZ@D%TuN*N=@e@Til2(&-v?cw6QS{tQa6NU03qg_AfO>!MtzsQ9dTk zAPxa3LQLyC9?I7&wS=vbU|9hwP@V`*)1QX_ea|Co+8%_k$2m{Mq0TblQaS~nXs71_ zjTT#|wwCk74H16wzEvLf^XjU5FfqsQerb} zu?2kUV;4~?1=T`RA8usMoEBbt={f2fV#t8mw4ZZM!@POu{k_3Sj9cPmPjB^hUc5jW4Q zXftWGjq!$d?tSPvBhgDK2wU88_M?Q_|i=;pSE4?t!ftM6D# z?^n*CMs+dbrV&Y`yb}sJN^mR zb&F#9@nSyDUt7HY?Lg*mPFtmWdxf;9mlmmxU4*0{)Yi&oS7Aq^RJz?HwIHuNid=Um zjdmNuMRO2EuPd-Dv#}3r7}t_Y0hR?>ai}#Y?{GbuKD8M4#7TwRqROIxM6f%XXF^(J zGz_USLSiNpb_k_46K*$QuZvy*jJb+I0-F^QN*`zZxC=Kpdy5z zT64%0ru3L;rKixYDyO|}$eY?!mclwOXjlOKLLX*=H<{)>ew0G5&MVpqCJ>Xy$=p|6 z0Qp)IzyQI@0x$uprLlG|ysrv0LJNW#d>CzuPnrG1=TWl2DN=ON&GzUCduA=$=dxwIW9e(35-^4uO52E)*3ifVRuLP|qZ47O{&^>P=RGi^L{d5H1$c3RK- zHZ-n)fvf?UuVq>B@}F4$>+^{KFK-*+)|;L;B4#lFTEd^3xRY18`-;=B5L9`3r2&r; znf`l>qjOW~@uMZzaOK+o-%6c7Ea}i(cZGy{LA8Jk0QVh5R{W7m|)mUcqT_A z-eXJJgd#Y}G$>yBC4UbG&4j}*P4jX8KA7DCnL6;>5cIS%`tXdR@dCvuSkT%Clmacv z$ZM#z9Plg9nygZYWCv@%at{CT#9MspPa9yb3vVW%sewD~?qFNI^5LpVWb-UNTSWhs^E1VfnI zm53c7KFga!ODg`SA zPO4>DR9TbMn_6j3*j~q(valbn=rTo&-*iblE5$LTa6PAs0w;6IRHYPDU98ecP^RAvs)lg^aPAv@Dx^18nM3P=A8?`>`3wq`(1Y zH4s^PD#^YMcD=NVlU6S0nGFZ{$*sSJ6W748Hm3^B%YEHk`|VwL z5X4qanit?TS3>F>R-e0$%;V=VMmJ&CbQ`N;6<+r|MnGEl#awnIlFVDYiXXo;WV%Dz zB{Db1rIBGSe)=jJ7P#!_dX|>fvysUxk`-51E8(?5PAh@QrnVw{jRAhn`bITxg z09tJJcXrVj4AQ@QJ13lWChPwE1QC&=JbVoE<}G65#*Li1CPYy9ingAH^F6_WmKev+ zX~P+C$YvGs_&#d<{$ls0Jnd3jTgMq^oJqBS1+h8Iool$yzxn;|uhy|j__Fzw`m>zUkykR+EnBt z!su0s>uOk28^}=Q^U%l1dk+3AHl7pxa|Qw$iwQ zWzFVk3SVI%z4d4m6X-cEbkX2oTtK~)^e7isx%3MV!Zv%Aupn6W4zxp)*(%jSdbFF# z<5d?5p_C>R3Xsv7ajgkiHbcn-NQs+HQ)OA~PiJY21d918X*XL0DWhm+MU8GlIWAR} z37{O-CYuU0<32$mkzm9F2IF4s5cCBQ0(N!pBOEq#k7_YNw>v;=rlGa9wYBlHU;ms- zF1ds)TRL#vwAs%?0eX6RkkX<&oka*i!c9WxGsLc`3N-1FZ*;Ip@U#ROoY`S!ou#_wLchO9jXwIiU{ zv**F9nYpuzYTKrd5U1a{k==a@`P2PxA}?RVr+>WL6n<}Q<-kv_qdqdhHQ)U+KY2xP z{lEN_XYan6k6d;S9Cto*-Z#p&PX<`GGs#)E#Ci5tPtkqeX)F-}zYw@y9Tob!EsxsM zUFf3bcHEm@mg?fBuc?Kpi7wGVjh8S>3O|=Cb6qQyr7Gm<8EP%qJ75?KTlc_B%QRmz zuD4L+ARLBF&TGaI=?`Qrc8;(7caKrf5tx zCIvpN&BS|9LVY9kc^g3sDx2q<7c}wB3+AyW`2n7P>P`N;ql5KYfQoYMy>D>OCr<#! zg-nuj|M^6|y0QjeJWhxf$}AuKZVTc-bI%mJ!OM3;c}&$mYgC^8U-q(WV}SQbhxQX zq4*cRx93yq{9#06zC-6NqGWn9{k}pfcVSaD7h#Tq9cO83_as%!yk3R0m~b6NrA-)3 zm5lQH-#^GFF2CGdjD7p~$|u_S!UaniPR^n+;6n?GpFQym*IoWz&iw70OeB+BbkFNB z>kR(2Wjmkv$_fUU!`hz*xbcr&oN>=yChiXN!gdElCr{scB5M}Rq(W|??Dhc|i1D3A zp5WHg-_HS&W;_zY>G2#XY>j>W7Sm}EF6_%gunn~4vX%_<8rtbfB&oKN^la{AUi)%( z0ViJcQ<%M!&#v4~2)lUg4%p2!sBO$lN=BsxTC-@M%gU&an}dF4oG_0ouRNFQuDOu` z?P8>Iz!3E?SpiNgp*L$ew|H96!(I)C(@B5`mP8WHQb7?|J}VFzf->EJ6wn z9!wC6MQLk`A%u^3Jjt;O7OqfjZJ=5O-aM_c)S^|MN-v?bY{NmcIM{Fbs`l z8MuWDDf9MJS!>b-t4b;CO)4#ng3#Wcz7-YFmth2hTHr0nWw%XF3fJ~oj28x-(N6MOFy1hTOAD7}B4snaZ@&sm24BM7(0sjYy8c9Jg@+wx z3tkLzGC(_S7XEbUD2xFFpgu$Ts$)nClSI0k5+osK2uIdMxVxL$X-zCkLWvb+UW1b( z>(Ar3ub#xWZassNWDU-47uraX78;iVhXKPFNXw$C$EMP&Z8d92ve?FB{ z>l7{|5p9Q)O|G3r@Rp_YcLl%@V0A-c3$NYtJq|J4OwwUG+)lo~BFPb12R}S>BBezR zUVZRg?dG;6eOx-v$&64h#bOF0V;Nn0gHOk_FG65=4Jv>3B6Ll*r`)~( z?Cjvp$G%LpYNJA?DAJ0px}J&tTIw%-7BV5bfRYCEw$T2_2~^1dgYh)!sys;~{R$d{ z#rU*=a+{>Io3xM=Nx`rJhe(pQBIGTL-7EZvej@BA&hV!f0HgNQ=t?VyHBfA9m+Xa<$yu-Ymf zc;L^3+qdBJ*~#;vP=GhzdylUz{tk2J9?8zOPD%}f;(ZKu46hq2X;E8S#dTL-%ZDF* zz#sqc2ZpR}Hg|TgWy@B|10gQH_+rLMJ6LjD^AuLDTE&A8-pki7znq+amtTH^wzf9n z@i;!8q|$IxAq3^)%6ag?2dValP-zRp>n0}zZ$JJB*WP#|ot`Eq?zvy&! z#cWd%rR?me_3KyT^9gbyPsT9DD0l{gRLFX^tysbI1=9$J<9IwCilb46U3*}vA5J@( zMl?|)MVErZ=wkJaa~Sva*K94IG{Q114tZ(<=)o{^C z)3~$!36@`c2_?~Dj;fskw1B9m&lyh1G7L;l%Z@!L1~^E)oC z|Mj`tUZ)u^-JHAVFury6q5O8m5I_9;9v)h^kz2(~kO@d_;q0rn=>R9c=*iu>}*>D!oZ<5wbQ1tJT6&y(UXudIKk7-&u{xC+s2$;?AK+t zvJWzQl(&U+eIprf1EVKkBmCmCWrJ9IS-GQfi1;Y!$?Q@<(ac_FFK8r9#{()Xt|T`Jh7Hn z9t%UY#(MCpSn>4?;|3Xlotlcd3lSIH1${p5ee!%J)_%lbvWB<9jo?`iiC+AEC;d7= z2HQlU*bTdq8Vdtq*oGJ5jao)j8m~||%qWLS!EPZL5(khm;e zusBr|YmMOrU136>;P21w;E(ssp{PnRjKNE5c0-~Ic5UaVrZWiy%9$c;FZ`N@29z{x zO@x$GdYvTA1Wwt^!c+bW`h0kfo=?llmzV$y#?yEWK~!my*gWN&$d6H&bius9izZjt z=m!g^s$odmA5ZCj+5Ygr&GC~_(EXjO4jex0MPNQAL;YOTsDJiRAtjE&b5^7wU6{CQ zowlcg6$bHSvOw7lp|!%Y6h5tOJyMT`3JtMt$Vh^oBwh^KyLU6C!B0mrO_8#w7jAgH z1tvAx6p01X;oYYwxoRfi&LqyJ+1&ZcPPX-K=lI52PC2=Wg@1aB<*!CTO@{geudRQZ z`F_ZSJ4q1lRIwMp_O%nNuuVGOZ*esy37EEm?svap$(wJ| z)YL#aou%6A=hj5>p$S zC=Ue28Y06mP|BjCvy%#GV1?tHdCDmqIb#MzS~Iz+i83Mi@ijl<7kAu&loBaDj3}G> z77PY>;DHCY_~MI+hNGNw+G*T>|NS_f&H|@Bi3aA+pHFXZFSWI`965UdJGO4+t>w#Y zN@Lv4VteSJKk?L4PxI1C|0p23DGr-Fnb%)`gCnLl(PKu~-Q9(h9+JrbyHQ+K5+B zu~i4auwdt8CI_Zd;_YUq8D%0>pj|c%H=gBZi^g%|RoAgY!{zI9e9+PkA_0>E%xfxV zpmU>*q)CI~0xdpQK&$?5ANFvsNNWZG(~Kjf8?CbiAi}{&Va*jwL8*~PYlRyaR2C(| zU|4Aa0WUpf8102Q$4_GznB_C5(3%O88*Mg~QC(n3bRmP1qD(0{R~H{`nnt&pm!QsnO2^4FAiws#Q7)odm2IE2o{pl|7CK&Ip zrUZ!|vr67O{Lk%IXI3+<(GPkfWSUvBVi$`SOrt~#1Pxs9(5v9704*re0ugA2niB4~ z?_Iw9@F`3YU4-2}ilo6y8&`q|awHH`Kx_&SA*B?;c@0!di!OZaM9l(IGvO3{D^lhpGk4Jl^)BaG!VkHA|G3S2lfOx@y}AW z_rKQp&n(>iP>z4{+E30iiM--f>M$weq0iyZbK}7WX+Ig0YqCP^5ar2eZG&VLDeusdBkH@#<2+Rth z)CiT`10+Ndmpr=)f^{5kY+*27VS8yKF?F2j;RqOYEKh5@6ZSyNQucHt5y1<1LlTlE z(Qv7)d$FKM0w{`ff{Ma~m<)V$%jrxCz!MgH=bC$=dOpj$I&fJPxB`CiRvP?`JksW7 z@qaxF6Q@ILHE;cPG5tbOin0NwM3y3*W?U#wk=8hsAJA;KT~u*s&6+pfp!AP_glIp- zj$w?3T57cB#;dPoPj3f<*=ZoW>`A34Aw~b56n}f*0eS~B6jQv{!vXm`t5z@P&wqW6Z+z<_`U*(Wnl)=!^vvJcx^*jY(_%2L zIAOseHgDcck%kICd}Z-Go_@ZaKmIPpA3Nsq=Xo_0ExLxq%X^@G82VRp&yAO|qzzta z+W}$<7d_g~tfOah^W)1vO#!`%xwUZOMaT2jVJpdkJ(9Do_q zwvlEmgTc0EEWy?={X1yb2WHWfd`1JYZx$jnaPJ22)!{G{u5<&+g4S#o}kVVoEca z>!&cJ(o{58fk+cqKHM@uAdqCp>fXy)FTAFsE@5M@Yo&(1xB1!czQCo^zRXa#lZ^Q~ zdvp+o(MYcur_|8sNDC`(KZWJ zfq7kB6=h{*)C7zIRSgE>ahAUP3YT1Q1zESmj7O;UH&9(sfl`Xu$1lK;ZY;~>r`KJ_ z*Dk*b=@zKC&BPc{nxO*9SRoC{gq4Yu&ZyaA&i#IX=Exkc(vzmKuy@+Ns z)VrYzzIL=gYl(0XRjGo}NrEEfBBeSC4zRtrg&j?y zghB{Sw%5dKNSr<=BLYTJcF?9@NWjCe&fpf3VxM3zleb;(Jc5!`iea517Tbal9?Co} zbS6cyN0ZBBNGCM&f{mHsNfqqHfh-!YtD2FNBABv1JRm* z9hz8D2tVDIl{5O-6G<|4nja3$gZ6OwuUB&U5(8u%bZOXG2D+UGet7{!T5;ZKEVhK=?r3sMT} zzJ(OYe&{n1)ixTN*B%DqVdgXhxbfU3ZdsP*gIB^VTQrR?8WKwjwpbP+DR67?DUHcL zu^}?G8p=b!PcY{ChdqxqJeVddLTw@=5krlDOGtEJYo>4FI(E~?HIr<6I&t>gLWn6sC zYg~TwyPWgK9b9tLyU?43mmlVl^A4lhohn$p#yH`&w-_*{vD1_+d}t?3oDCVpxF$CQ zdqGG}x^pe--L?E7Qo@su?Xow-gdj;5mI%-<4U(9U>4L;M4z0>EWVLd(-{P_VJkAaT ze5-`FTPtwuAT=_;nl=ZEZ(Ir!>zF5&l6d5NHoMcbhu2f9Ej$S5u~;1m<8~*gaA$b4 z8}Q8rA&FV=VQ(*ex*v8&sj6zGSd_7+Bh2QWC@*h(nYpJOj@B@2!MA_#JzniygSWVX zXi8IER)(jz3~%u`oSq3>eCdzTT2L$n6;*z|{q66wXU`yBmx~+@4ymgnpU+e7Dq{8O z)m(Yy74&q*G0h~s@g(2;=4Gs2vzlUQzee>{b?k{mIPKhX?e|MO&hKtKk#mmB+x*#o zY~qriJjvo4pM+O;z>3#->A`c^ts;iUZ zSh9|Q&^ZIWiHKZFD#r` z#yd|xM70nMY9Bpj1-m*N?ASVh)(%`&H@97S9zQ&8JoL1~&In2=?qAZ+(3+$z>O6lI z^eKoL5S+oP?;c6yp6Q(U#bQu`KRmb+cWncp7_zdA$PBr{da05D0>YpiP|+|{1KZYd z|JRP-!ebZl-jWv>=af{)YKpYMo=BGRKr?Rbp;;JwwB&UR0moDWOJAcwNQOI;(36Bi z+_XRZ9q#@5MAqJNI&519A6cAq(|hz7Zf@;}fG>bo80dJKL9KBVZ14}p3>a-z=-UE) z9b7tXJhcu7hL(6lkV>PDALhCAq1UzxoF`T>5 z3!6Iu$z|6b$ecTtWLX?i zUr&9gj&FYJa)j_OP8uYWX**Cj8nMF!gT671Odt?o;oJp;EfcL3l?Z5$@PY3rh&W(v z3wWBrmv;S976{s}O}Dbxu3TiLcHO^2oSvj42U_LJY9Fo2uNnmGh2cb}i zoCx9YHk0=^;_yx;ADn?RG@qinIk^1u$;uGpLN*&BE$SIxH=Xi;ByU;!**6~yy)QMK zWTR2G{OMYt-PY-RWWw4AY>Gpwmm4o>;+xGWhC4TKTy2IYe|Ih%p`aLTjJjU8 zQ$eQ&pnW4K2OPc#R0sK|ZlFV@K?^qCei1XibrbMiyq9-_XO-;?GDb|5{QAO^x%QW@ z@IiMYbN*vB1XJL$3qgD~B$^hIe#^mtlu*+Mi59ZbNvzW%Bn`eXcM=yZ*#pew#GgEc z_0Cs`Szb>6$z3qJ(OixoP5S9lzQD`s9uFMuq=~F&5Z~l8B_`t)jal_Z*u9IJv_Irg{3;hgg}4= zBF7KT{vi&p#rkBHozV?^`^i2DEEX-4IZ;-DXd8D+7WaGeW5m zphVe&>EVJVqF5SO8XVG~PB<75;0ibyFkN^FF(FV)TjvTMx%nLWqXw$=Lv-!ooO0gz zoPFsDJaE-TWa3G}mOS@9L5;PoA3zf!1 z1e&|EnVKw#8Dv9g%hWPl|B zCr3^F0$#0I_rQOWG53%YaVDrdkA7_;gBw@z+6NX-N8^0|xCu)b@Z)|VOdF%$t1tK@4iCgZm;)}f+0jsKwDdwNlgt5#FK=>VM+~y zAuG+EUK5o{QS5foYetA!no^%6VJZAxFP)v8jH?RaCByRNt7({W6hc5{RV@g?vSlkd z>9nr{L$JLYq{)`woWev^&9%?(#7*m4nb6o^XPX&rdO9P#yX-B#c>M8&NQp#Ye>5l&1|>Kd#>4AtcJo1dmNwl^ zjSk|}5}mPdSLc~GImmGh%_QmMKY#TGvug~#dd4iq$##l8PE0Mi>#?`lnsRaFsSPyM z3w9@ZDfQL!)_a}2`oR{ybnJWvVi8{6zQh*W6Qs=LLuFD(mtxw~5Hp&qSmX<^I}t&t z7={s~%;UjISO_7JGQ>UWT3ESuHLSO6^x2bQ&dGJ$aP}hNTU&6Z;qfOnurjfMT&l|+ zE^42RnrRC%k{Okno3A~Yo+SM6%D-{`dDFS*wDD9(O`=dU4x=g2b`b2o^DbJjKZYNId>k-iofFcXbgFrI`?P z^2Ot>#7hMr|-4#?ChmaEj%d+)X{zB|WNJuU{`EaIIHBk}jVt_6b z9*QxDYfU)X$;x}qq1$p$BhH{RZo7Wv!Zt0{DFdIgVG*Bd9OD$9evOlYK(piko>|dY zM=t)&&B~`=lM{JL3aO?a7sKi?VW~jxV`urveDMAA8^k9zHsS!MuaX1wD7k`Y{?m}5 zgXwmPG$?f8T6-fM)SA4r09y&gb?40D>N6)&E#~w4CqClpKed2I@Z>8W@YR#X6AybR zYw*+d)X(|CkKZF641h>*>QS?J<*g_PfsSXne8G5T{9!StJpK&RGFgUZOru>2SQmxK z5(wbdN&E=X+7AgI_?mGls1G%>!O|S5q9lK`5bwng!_=cO?tB%D=`eA=Eqc|0z~ZF^ z%Rpe0#fm3qa>7~7-15N7ApV2NXFmw9+y##;fu7g6|KS_hzM+kU=RF3ydzoHWK_Z+W ztUK6~8HVDiT(bBHzIgU7p1A%D3_pBf@m;*XT2WR8$xMcv%LVQ{WCY!PipDA5;Em<~ zL#5YC2@noP3CH@Wa0_Z{Ca^oYn}NZ8G8xBS_ZwvwdpkNh8Hicb`2A>YQ6cR^tUMse zXh;hK!+-&^gH4v^izn4`?5uIb{7%exlo`Tc$O^MdN*2fvy~?0H+{N@d$)gQblx97Y zAm~%8*wzMqV+zHF6QZsBvZ);B+yH}BUcS;5;E5lqoT(sW#VH2nV(K$)nkSrAJ?cHIH>q|V>G%a=+D_m z?Z1zV?nT4hU5+f0pe+s~1(phgpPS_HMpHM1M}@75Q& zWabIPlxB}sI7JimdZ1!5nL01ULQ`wmbfsh=)Hf$=0}>auIm9Hdn+dbVlM@N3$ngI9 zw`pwn0>Od^wp2>&Y)%t|3 zVzHGR)fiG@nh`c{*um7sCQ??GN~4YeQ{hE1BJ7aPq*5rAMX6z1pEUN!;Lv;bxqZ)a zpWDfqi@wC{S<`G(CTbE0gvbflv9%4QGz|?+JhS8}4xiFYeN`Ps<%B}esBIpR)ef}I z(B0j|j2X?8dc7Put%=pE_fL@SFEpiNXdZejoqou&FwKY^yq8r7r(h^)(cCnhS+i!* zXT_*6BtD-c+TTZy8K-H+6pBV%-2J<|S^eQ!CN)nc5C~E%os{{#yz$1nba!_%-e

N+&s&pjRm_zxoD7M4s@j1b6-XCf0BI5U`!m_CzC0 zXlkIda~Bry)RQkU5Vu&dv4fZ2dW+kHpj;0@288Y1bT3g8*F^->i z3@esx2ECmU!wGRgPS}NR+352vjDM<0`Mk9KNzF~Pw6rp_xrsi@qPeMwXCD76>smLV zwWdN!;#x3R2&62+K~5Sx`sxR4TBD#w(~^opMF>`Hf$=_`^JSQ}ppoDFZz9`s>h_Ao2ytvdz8FFKkU6CWG1n zp&2B@s@8T^i9CTzzew|x0K_sll}$OuXP`5J|9NpaE8pH|yLNee5blMBde*(s&AIQ~ z#-DG#lv3cMovq|{0WQmqeMl5g5)lJeH5+$)fDE09RGtcHqN2;0 zAq5N1I*ih+B5y@VnHw;X3}E0f0@P|vIDF-u$`LuKI;M(zzAu8fC z(2svj#CqVHMDTG3u+M5*_G(o2(z0Oxl;Y2et{hCaQnJtQ%@xG*qYcX^iE9s}e;xQe z!-as%6q<3s=&|S!1rJaiWR6Ht9c>|_9DM)GnLP4-lJ&iU^Z&e?uP$i9FckN`(Zl=8 zR}=ZoISeI}lzXReU#H-eKefUk27a%bvu=5joFVAD@f?Dk8yKmYit~l-(4{$gMj!cb z9MF^n49Zjzd|i}!6h&DWP>Nz{(4#dCPLl_(J)BGLea)tgxor0jtOyt(&;_0&CeB7u!^soBK9?W9zMe~Ox|FrSK3+_9@X{YHV=$hkZdwDEUAdUYUsyuRyMH0*0vDQb zE*CwiLB4+WJkC4qI8xax>A2>C3(w+xJ|z415=x6RWYYZ<6+6j{i~xQ7<&m2(ykI4h zlnFs)RTag>c4N6ay4w~akEoz7d9!hsON=``H5EKc6VaudQb)(ICJfR?ES};51zrD6H@np1JLGuD$0)?pwAVkZfA=RdTJZ)P3ulB!QmJEDe4q zMcFhX%EDoVacGTcYRU`)tqO&(7Pxhueyw=DJI>vYbwVaWW8WW`Iq$3N6fq#fKrBnT zU*oSSW7DQh_{FaTFWrfqWIR4Lry!#>&#btCK&6j& zUU-o}O+79{u%h=({2m{>T6a=aQ9)Yt^YRl*@cC*;#uWakIfkfUMELM%4{=M=p7O9! zPX#fVKk0QG8VE4Ec0A*hpj+v&sq4Rj+8%5Vuqg`r8ieda3DXBhLk>m_%k4A#(E8&! zB>U=C)INpW{~lGbhcik@oD|Z7#r`ziQP25eDaWW7!)QDOetGB%&v49f%{+MH6f(Pa zV;CWxS@Jd`YM9>McGUbb9{u|rT>qb6rKql!?rsxB9rJHk2fdoi!}Gc6j9QksL!ABe zW_~xlmajFzp4Go(w{TLLjk7y2i(_wi4fG7~tfRr7A=BALEe8EsQi8%ToD7p9;|(wr zO|eHwF1r6!wm%;x{K2KRP4mc+q^>E%OZVN!?N?pH zFW%_qrhA{|HX;d-@4it%VIwklAtrLxUMQR;@{VMhbC>0oq?sGs;Y`yyoHx<`y! zo_dO3+6?J&>79R`ZYqpw=X)MaO;a&001BWNkl_dGB&zt)kA6yzX;RZrOIB-&q+n-Tm~UQw39W6N z6iZ2{s*aw{D80SC#1M?vnmv(jzCLXpmt65}f?hwv)>^=Y4$fh~aMB+3Fi~cC@TwDe zG;{dH_mO|@LQZ~sC2zi*nDib#n3Us>MKiQ=GZ$MttG?_lViJnLVDGe+u$trUb zhT+CE^*)8>s2(?uzivF6G*B4;pJw_=waBg(YL7aar`JYdhe_+R>pA`S(G{Ni-#R>d{ruJQFHX+46KJHv+=^i|lB14YTG8(obf^%GW)`Dv4q>Z<65WPZNV=3stx=7k8;HcS z2q6)&j%0xj7*U!EY2dO<+))osA@K<(4xP0dd8HW=f+7S)ttK7q#)YlNE}1(~*{a1B4DlQ-(iwZ{kyF6nhJdgSdn3)12(vpyWQIkQn~VfnW#4>kw+&OiEj_S9MYsB;M3ibJZJhmOut>oo``O_rMxnyTDv zyypn~LeQyFtLS|EyG)8k8S+-KJDsIWXo|FjQWh0ewIq{C0-VUE ztVO2N#hm76uMe8`+>P0VhX#7`c0h)ciq z3*1@gH9IL28ed%qrJ^*NEtCfWgsCGdC0+&3g!-6l%)(0?Wm%LNZcHp{0wH#*kH}eR zywo#8*0V>M>)K*POw98()Hy;DtZE#gERep*P;aPSeFKL(m)Urn0t) zu(siKL;yDmS0qlO;bxb%aO!G?EQ?}8(3;Ew)u0tqC-~4k7K8L+(Mh^Lh2PV}h7ElT z;UXmrowP8itjy9_X#sK0p@@*$Ybu*cOj{zjaEJ$cXGR;rUoXX8pPJ`2a!-cE1@wMMfpn{Ej z=nOH*fKwK)0zDbFJ<0RGK8Z>3I59Du7SYWl%R`A_{~ckggRB&!5QJ){v;Cu9s9DIL zR&3(w`+r7F*2k?czQ|?w|DMtcA0av^?i+`^0E zEEM6CfXapRm?p^j#A9BrkTx>5cdq&@-89Sk%=?f>rk9b-*+cT2XEU zFwG9?WQZX&N_3SV4 z+B@&i6sqHkr=H2ORqN<6O(r!pFqF)aR+>yELm&{u3p2aN%Ds4Lx z4xz?k1`H`lbVsSJt7TeUBaw|;*w)f!Th|%}OP9Y*#IkdGI@;S=y=)ohoO1z#gM-|2 z&z;yBmm2d5Hvz4A;+Yp zWAD@U7AEL=@&;^Ff@4)DD{eZI1>gAxOq$K@k8bBLH=jf8yU#)|IIesK^g>7-0-0yH z=lYuQ=@}$Z5@pvRN8AAq(`_|6Av; zNF{w#!35?kL6^xs3c8+E?UEzsWHAtowVq) zocM*nrxh79OG9HFVXKRbswZTaWPlwC%7n(L6+SH}K~kzUreR@cxIl@p&sRl;xOSkW zK{Bo>lLkpEi<=;2(qO=Z%7DO20%3XBCTdAbDDGH8ZC!vJN>bi1iN0tXLKp|p-+cbZ za3L@6vl|tyu`Fwhzi&^U<$k|VN&(95M#qH$nC7U%hZ>tC4u49+w0~&br%y?X_M?5d z_H#DbSKBg*%8aHpe?FM=g-O~0(8LRO(vD<6p}5OvUF@(z-#{mmS* zVTcS_hSXMWz3wD#xTzQ_EpB?FgeQOT4JMy;H}oD)>Ed2HPau(n;5xp3!8gFNc=+^E z7XM`f&%K(#u`CLff}XA1c+mo!Rg;OPO-i+(P8$p*ZQ7YqqHu`WlPkl3ya>=|DWne5 zqcv7%E1^(;VLi%yw}ppFX}XC}UU)uxv_TG-j3TUH7#pP#|DU@v4{xhF^Z&=T&b4)9 z>&nrUBRR31*a>z*7Lq_n*-BcLvNjZktu1YVcId*7DP;O-~Nhh=Fz3(Hh;fW`npsyp%%$5jI2|xeF9sJFC z@8j!b_j1dP*O0TbG|!vMOE130SlEWrLZDp2> zF`i4JkQAj!0T@*duF@#0g{*%_qa22`V6i=yF_H9Ev=n%ZT@y$V(M|LVO|=;Cb2k#q z#9>SelnUXRl6|T`@7))2!wp}gA+m}-=AgAhg9!(;#IPC}$a&3`12SPc>cT*k_?A*DQ{rmSbbLLED&YX>uAriAElfgZ%`U!-TBA?Gw zBP4akEXrMwAz9i?M)Mj=OF&X1Ld*!&Q;DECI{*E% zsZ#jhM5=T76b?Q|L3@RmpmuSXiO1w4DkMXW2B}MfkB|^l>VUsBYAOmvq*C+?h?$-y zs1oQF0`g@LNw7O-5OdRf>+de(b6@@!Zu*-KGIPliM!LGV`_ZS^pY7)T=fp{GeQsjc z2cg&(fawT+aMK+uSXs-yuALO6CQBo8P3Y4m4_~y0&pz=S&piA-TH|3l(lJ``4p2u7 zP^|@d(_*e};h+Q3lvHI3P%mKH78Y|BIeRTuB*tehX=UA$KcnZJI6Ij}z4;l=Zo-%XManv z46a)d=Kp;(%+6#lG2PF&<6S$%dX$(2T_zvA@vr&y$|ab;?}eXdpmz(*9S0@BeUX#i z)ylIsFJ|1?&7d;q#$~x|V^}y;_}0{6yh6Ds{qEa{P%8v7Xfh;nD5a^Mzn7&i=d4QBb+)z?!e zOst)IdHLlxIQ{f9IA!^AMwQ~OyY3}Qx>*37!Fbi7!=4CVZ;n@$NC~{ zGZ>Hb@{RLmklgqTb&ZV>Zb3FQvp<((j+0`)wAijeqG%H1Xf1j7!Z;5;_!KLbox@Ho ziEF_rc9D^UMX0rxi*Kmm_dm|?*807C=9H#AH{a!O#5pSe#hrzsXoJ_%CeeZ6d4nl%yQlijoVt^_H zEk=myyZ~naj$6!?pSp*eKC+bN`T(`0`0*WQvwdBd#q$~&cOu@_91@JH7{j>;Jpl~? zNwt{Ab}gxIF{uPb2X=xeqgvIGNXOV>ZKXmcDAx)B1pT1bgLZ*XB92l;gve8_9p5NL zGGyi%(iXMy4A6=$K;TfW1vyN#sXa=lsHe;vAmx9)VgHC3Vj|VuW>`Q#O+7IMgTBr? z2n3zUGewi~hvyDRhoS;S2n57Pf&;@=f?Wz?IFNA|^BqV37& zNrztBYv6i1lhm0}q-7G6QMyt+gqw$Wv;817mPG}9g!FD^h!AsexM|+g{94!Yxg{rI zcXc4e91LqF``F64XNT$Dx}HtDi%jc$g_bkVV&jjm;PTaPvrCy^cXI1R)A-zV7a`MK zROvidogCwUIG&qd8HLR|Af|Zit5?#}5+G)}1VjKCofJRSqR8b6gaVR+@LYzpf5S*A zd{+uVm8r2)HiJqrE0JK(4-HfP--k?}weaaFqBPYK!dq8?>T1rtconCtJcrk=x`r_! z=-k-O{3T0x?zxxgwQZ&)6oG)`!yo<->({@*j~@LOK5*$}3}$Q&+Bq(~`lH-->z7#b z{Bxc?qn}7zQBlD;=bX!mrAsivCc{cmB_%x_9sKjX_jB0?KS4AaWk`Ds*}Ud9I(P48 z<;v5@DvfEHTyViE9)A3BYW-ovMpxr!LYw}7Fl!^lXvkxI8wr#U=<=H&($LG9a&R?&#ZF|?s z@hp^UO%o9iB$G*Qy6OM%&c=<5`bpN4+5m5YQX!y1h$+Ff99Bq7+Rh$ppArJHc7|}v z5|op|GzB9{)92XqYr}JhF-*q)l*xR^o6Kqr*6d1t^Y|mQE}FxdHBVA}<$2~=F%~VF zgUp-!@{xb#!WC@ z;!`k^>*y}H?2$1l&}4#pO;4*1ri-E7Ui z40g&J=7cP6TiMFZ=Qs1-8=J{@Bph&*X3?=>E!j|n-t9K=Gl8-;$mST37TX%a{QYD7{JMKKY`0-&#tUZ9 zKJ6^l!dtHwFwef9-OqfS8ObgRsU&$dibw?g{dj^ltS4VzUNNMq(AsOPr4WoMML`u% z!V}Dn_~CSiQ$LUU|54oO47J-vmps9tS z`1e}7*Tv|!Q$P)-Y0_)kl$k-wHLO|t3@4nt6d^n(C@F(z<%NJs87v`oqAiZ&B>DDt zzssF}`)v>9iJ0I@zPAM`T53u693#fkQ$clPi+x>!< zLO(0UN8Z)OgYD~hVP`i5aTWu6o&gNzEpB7jv3**4jO1RIYd`-0h=}Jvna_Irmr>+h zOA-XNLsj0OG897yL17@p^u}>6`q(m_cyb$rVD-I!^bhQMV#g)8^@?-o)G3x~$3w2& zGTNWoz{g*B!`Fv}AgjRbXkX8(7#a@+SR-y&l?xD_1pln4;i>G}kN+SC&;JUnI^_@tZ{a#3?nMU;%J2X{_0|Me1Nh{1gE{gbZN77_389w z3}%K;M`(wUt_(#bz-(gJNpa0mlM5D_$lx5prlMR|p>>K~?OW;XO48k}P^t`Yu`I!i zSQBlnt<=UF2?ixX1koBs$uX!L9LGy59+Q%pi3DT5z}RsdEXyht;Zqw?FMGzjv80a# zjB1!YyA{XrZs4b%evv>RKwDc2fB3^Qy!XBDEpex%46t?UdJF^J+`b$4SHB}3x2TmS zn>VbZDk7<^ttIE!R7Wj#wQuzJv>AsdpLqr|Y*J$-uq=z$)@{HLf^@ov>FH*&J!!hM z=0n$A$E(jh$Ik8)$IqF=-c&cH>Dg&+-m#UrjcxSWDL=_xOhFF)17HeD_ooD5Bf?9g zl~R^ADj`fP%Vfib4Q$=I0Vz#pSW#xRHc+k=U3L#z!%3}67}8~Q^lZg6O*&_T={@r?yctpcN7S=LVI-(uM|x3)8?5rC%Kuhf&ys zzsF@gf$63l9jvf|Q$@71qh*Q@aT!u3%J*v-q?Vs0iB7+X?*z+U#n!3wZGE2cT{l z%s1KePv@p@KZU+9jXPB@2mZ)7m%FeU_sm0-|ukWx~qJ@Iy= zp@pJMQ6VHbG;!0Ut1CH0Ku_sRkW!KtlCG{KH{bZzz_skm7z}BL*#g>xWJtq4f}C*a z^Ir2%@8|Q(XapStYXDRqWF=%no^~O>gMa$Qbnf`(mk0xcX-|78g8?G`kSU!`d+1Z9 z8u}cF`3wZ%bGP#T|B>&3d=F2rAK)`rok&pzsgNGc(iECuQ?j?GhZ$BQV?xrM^4_Z< z1f97gEex=}C&`?pCj*X0^X@4!C@UEg1^S&FajS&^Cq)d0TB$spV~34tN`|yUQJO?s zPNt)yi-bs0E1^T%Y}Y}ey8ajq3P(j!{-SbBYoH9Mnl$7P2GgwsJ9f15zym+xp>xhe zsRCLTy~b2{?p0oLc!BASarQV4Jv%zt^yWHDGmO@Q-rCGMuuHP~?|^F>U=!M!7 zU@*eKI-6TI-pyTKzaBf|hZ-6ZbRGt?-p3J=5Qz}Vx})OlhywKZ-e403oO{O=_%gNjz0+ zN*u@GOLzSpLX30!7yi!IT9^pS<@`W+Mmf9MQy54(cAtwMmt2V3-EIrodGOHCorNK}tImNKt17F&qda zbHFfz6d2M)%tnbpn9hwIBob{5rX95ICT7l|Q+Im7L!yP5fdJ8{VpKWY_P0M^)0!W0 zAb)`Na6on&LAF*VQq5)-2Ax=u$4Z;QhqoVPsBF2nbT? z9_pk?PfrTdl#KdFO26Zj8r2af*~tpwH7i1B9LJ_w2ppilKZ{bD&))WBnwpvb*w>k4 z1lYcPI~QJfAwmdpxg5tWoX5_sTgWTT{SQ6HXg*IUBv>%#c&bH+y1MDaOp|w#X1Qx2(FkbjOs`NC{xovZUCz^1RUY>BW1R(3N>BS$LRK`kZL?|J28Ogp zIZUNGX>Wg%H{N)OVqWo!pFhUZrOTK<|0J&e`1Snofd|;MX%pZ0##gZ{i=|5!^5U8` z)B&|pa3Gx`nrNUpwH?+z3JkJ&FoQ7SM>HnFn4m!!lxr95YQ{nahB3(*4TKCv@|ucJ z2%!&iE%B*EV}7rJ9{>O#07*naRH2C`?bxSdpn4jGe4Yvn#;OI8NPs{nLRarj_76M< zTzvE*@xN&wo;yX<1YW$xyNAO(c7J7%dp&;uiBh^(6YOGEe_>LIC=nhdE82 zef9|_!?qmrR{e$pk6%J<$Ey^DpkKBS4QM|5sZa90D?Y{r%Ujv6^wf(F*a%TURXE1< z#x|xCBG);Kx|a7KQ#)von~*X_PSg{yZKB~e=DK-y^=CNHCm4?gxap^RS#xg()YY@> zf-qOFI*SG&*q@B>;+9wV8q2_OwlSc3aU6&8q9V!+4$#kdPSGOso^@$RutLn{gLkh7qlpD`P1b#B z1%W~*`E-$d%3y}v#qEhkR@`z5=YHvJ_HE9BUPL?*r#s~p)k-PPNZT(8ANC=k7yz%YHUgqtI>>U@7}GA2Z_gnq|+H{gC@P16b%gxq|-Uictr@Rf`W() zFp~4G&p|uKw1g<3#il7sh|ENTGO@PHq+p(9lIiO5ni*-K9L)sgg9-x5W|k0CS|%wy&al-;ncc~-BM1nSKlT)8T+l!u-Oh9=C@N^i zVN^@nJ3E-!(n_E5f(*-$R2?G=W$GHxTK(C2YjUtQIbkbNcJg^baynx|5Rd{K*w)#> z{I+JcZGM$4T}i4%8CrY8>~hLL20Zo!Mamr*HQ|B_&gbeIu4TuYd#G;{-Vh~Xf?MB;wYh+rX8$ueW=dLH( zeRQ)QE9TW`}$7yV8V|O;i zTN{!ruq40x{MCS9?S>>l!BrRP~~ftm70`X9Nw%^P)SDTW;fDXkKWm`Ege-?`_altV*916^HRe#h+{ z!efp?sRE`M{IkW{U)E*mKO^8b7!$7V8usTKmP4JqCL5H)J3ApHl@xq#tBYYJDEPwt z<;$0|V*W{d@{^zBqgP)>#_pjk>Ch}(cIzgBT2m(_Wm;i7Hg#s0a5zXn6?si*${M0n z<{VlRCjHKC8p1)85KLp7K6@);B0*7F#6^}dC*>tf$4!#r0HO3O`gA9Gttr=%`a~Ne zIAl2fpt~ctf7onMYsW8z`l5-7=)~s6d&%0hTUZg5x;UH8kKj z4$~6#Joey&tXOga#59F$mZDO;=Y8jTo3GNu<8gYsx)?R8Igr{je^MpbX z#?Xu?#b{vMr=Uqf0m+Yl{4m#E`ymDgvwZ&VzKlJP;`KLP=Z!bs;GA>LE)|tye(^H3 zpsYNmNyO1K653DIRg^1lTH-i4lF3f8*#VB9vl!)MdFz!|*x9|Cy#6^7<4*A%a6t zFbsyN#PAI*GQC-p`vNSu^na{L0nd(fL~H6Siwd9mGU^Xylu}gq2T4~~nsTkFwk#5f z22!asZEdX#J5K4a7@IQfoLDatA$yb4BgL`R`QnJfM=3w$*;X_+$Jv+5VJHWUIZ0(H zeNKm7yfJ~d@f+TASBnS-Gd5M>dWyE9LKn&FEF-p{HZ;zjo*tT8=Aj8d#Dcs-Tqu6f zZlHI0Nyb0C?R-{UGXq$`h@+S(;HhL87k=rFAeuP$zL$9O#`$!1b&(1LX!Q@IvB0rb zOM;NLs1`9sRT%?LikS(Mz3tC49Ox%Xo&#yc!KeX*7|awHHU!iqs4^uZ2!8hCH{rNN z{N%HM#kwQN}iZ0ah$ExL?awXYo<51kWW=ILc~J@vYKuy$)h?2A;n)`J)NN5fbD2( znusrm^HMs%@j`G~tFQFS3-%)zNM%SQ>N#lV(ORK2l$jH##Ux!#0-=E9fGB!sKZJVuookEG!OaPwyA?o$F?q zg5i!N^Q-{Lr#{G-GMNEXXix(7i%w?eVn76C4`L zp-jYxN=d|4%taH_ih`r5GA$y)q*k>fGz|NdZA#2&&91IcE#g;*AtUkkRG_rX{yhp%lwo7m&;(X(CGv^^C-u z8KDuGvpJ(B$_Od;X~jVYrb&r#ie$_`y~{dIp~OO%N+}iMNbN7;DAfDBq9*2LtsO|E zsIgio69Ia9dg$Acq$q_K04N2vo$-u3L=fA~P%BM899-ZyHm|mCWO?gpjH*757L^w) zJgb2p-}q5P`yR#}$mkxb%rJJQlVLYPRbhbhPio};H7VGX@{o$@f+iWn$@URjU@@>U zM1EtRcO%ZSs6=`9fDbMVF~E5XPh#uV*IDtc>$&E(KR_OC`og{3^Yu@m4b3z$&Vjrl zqckzm$gh6AmFG7&yz4y)ZvSWt1D!8(YLm&zrHh!|6z2Z>p9C?Bq?3dG0SF1|LQorY z2o(CzS`iNmumT)Nr)W*IQI=IOXuymZy|zae9+rYpF-|3(W0p{$r6^syKR2j4nnnJ^ z=lj38NtybPQeuS1Jx+#JQyQ@;jY^eil1NxSbn9{IdwM)xKsEGu?U2pFAfL33l)6<+v8mDvz}mG zDWnvP_-lTmyB`zcmH&R6dAJFEc52gqe4j9niAZ6+l{>X{3`^5 z7FGVCGp-7}*1nEM9(e>I1T{v88q4IOi!P==>(D%}jaXRXIW!2vH>_o1Jp)GKPWn=_kUN zq|s=%tW-?p$x}}?qeh4!anL(R-4F!~qB_ZeqYfAT`*z?8DNwdUuMfpf&<`uLhk}hL zMXeO1Qfa0)#(n1`iD`O2>+$==5%B!P^*xk3u8+>qJ?h}ZN5D*rUfZT#O1^l@?OgHk z>p8i(fo#TKONKlQF&0y@UhrLLpuw6+L)(drpy*9?GbduA2VBfZjJwRK&w11rTwOAqSnQ^SJ4eZZ0{0DSep~9bIKCuo_7@J18j0Y0a7sTsn}WY!-@TjEOv^IZn}51TblCS;;}W4=W1$ z9FIDaRRZdRASLZcFRff;sF$-DEsP*l8I6`jU)P&dH!Nj;*9PV<7zddLAxIZ;3`>iC z$0jNzLMtk@#+|}l_o@}cH|g*+RYEJ2qX~)vNT2uZINtj?N>wug)Q3Vem?k&gaBb=9 zYo7Qudpp`OP0I^#qyc;19zJsAMSS$Ct0)r?k4M??`fEh%ZC1Vi{XXNu@|r58eA=%d ziYDhM4#+q|8fJ?OAqhKEHcFb*2$P*EiUwL$h6+1}ttGV!rV~mVB=JH{$1)HmLTCF9 z;t7kq2GG(TJmC>=ZHX|J^?RZAUkQ zZ7wgLb27(?41?(;!&uJ$ED`C2V5(_YmPh>`baJHvvfxwXC$3Sg3{xQmQWh9N6HuN|U#S9Zt*!L* zq&VT^u(#gwnn7i=wf$9E9EbVlJaUdpdvXU-wm@VNqk1f!%2nGaRN+C{pRzOm8$9b{s~PW<(0K(tmNY zF;%bfznS(W4x=h((-}`pFC}EV{j+)UYzs_mDq})m+cq^;g4u1&9JFmVZrp@vh8cEp z%x-H&Yq0GU2U2OTNf494PE(te|0-04DO!>v>0ZWvN&_?Tyj9Yq%D1BwVw`FLLt2t_ zihSwEPk}xWB55x$EbG9wcf6Z0B;d;PNnhN|crJ;?W>5)+n;ZD{@B8`XuR2&`8@zS% ziI5be06X5yqK`b{Szd~9Kymwb-y;3^M`;OWIamzw;8uehfATi;mVp*r9_eFl(=)ui z`eWpsc1D$n5Q~WlO|Shb3l=nU{a>BWE3Z6@>uOqCoB8r>KjxIP-VG>5Y<9J`vwHPvu3U8imtA}@KYjeSw0C&cl8HnD$59xT zRl=3W#L?Z?h8>5w3tAaWXLxhn8)&Wh+PA+|g5GPTq(Tas;tgan8Hz;^0m&C`yNyxb zY0ld;Cv-6;!Jx@ypZp{Psz|N0C=`nH@6V7-CTVDh)86j6lvN8!Z9GbUGEF$_O`!WT zo+$m6TW%wjN>k~l{7M?I>l@ZG!)n2{3#fvF6%Dd0oua9!3ELi^zO98}XVQsIsUkY)6);5v zV>ySXfBQIzdW+rxhy7F&KD;?G1cr~6cnE;&7u6G1;R4syxa2Vi0WRgP_KIKs_q3k; zTIEr0L$7I>xGo2&Hb8;zE8+qXsv;3$`Q7aLAKo%2uIH%IXyFZECjPB}8J5YVmtMw; zFFnWb*f8zwT~tVqHd9?PCD4a7u0l-7d^*I1=g6jH>eOheJ7Vd}%FAJjnUa6~;eCAR z>tACy=ioS_M^FW(A_2z4niJmKT`3sLl`$%`hYVx}7!8GR^NRU%=Hm?P!qFk32@?nW zoTPDbLO@>;gvmMQ9LKP-IbhCVTtw+kXBf9yQ7X*^t$fKt`$RDjtCeVwR$ zihQaW=0-vH5>O81Izp^DOlL`o?$TNX7eWWcw_J?a?| zzzeFwWOwH z*xN-$w9yr|m>o44!DU)BN?4CGZNYLJWqapKUQrud#zAFKsiy=eYE52i##I5RDBWNA z5=ElSqag~x2(GuTgx81*JynxJiLR^Byzs^wTyW_{CG(MA|LRwC@7;@(CRM&;*a#4; ztwrlHR^N9Yt5&UIR%wkX=$2a!V6Fr&OcV2?m)81J*KM2dl`QxQ0(%2HE0>NO) zA(UwJ0+p4gqr?}G3&6=aexp_-EG5+AH^BWWC)`P`ogs; z)1(2He6X31|85&UdZHbSgok78PVs79@#@=ekT|1_%{QJws;h%7&KxfJ?9(1a5*uFY z=Jfksx3*GI%#kC*JHn%rA5EJw zIgJh?eCnqt4Ndeh5Zj|Xvfe<>G)+`bib0jeu!7W?VGg8nREsb}dV)O@#3# z29zpzhDx|Ts**!W6WdOEFSa(uiL!#FEe-UpE3hGHvtJaL)*8p|a(ov%%?!&Ml4{ol zw~w>tFTx$jku?RU*IRs>c7Gs~XGK#Z6?w&Q1Q2=HV?bz-acc<&3NC@X;@yi(e!f6L zhvN6&`#G2W>leuP*;E@63>X;L%~hA2%HwO+gJJQ=zpUYr$dpUv0{wgW$lrc~{XJd& zy%u8EGh4agg>{h6gAwy@Dh>Uc+4|dmWWRn3+%h1+jI;0X#r_c>&pfGk@XpT=(E=e$ zNk~T>${j-e62}fH|G)B3O7Ym^4>E1lEnp0l0OLbK=%tjTQYk7CK0n)Ge@_npEiKJR zDM=*aq*5t*dXku?MU@%EG_5HY@#v0PN58rLV;6bMhtK}AkEu-x2>Sg%Ht)F=Mdi7d zcovvtUizrC!OTKL!FdZI;xEvA9x9ZBl;bomXyxF9-&=hzYo7cKyLPrSb6O1xT3da%*_nbK=s)?nnx@I- zH#e3h86Gt6CB)CLET0E0=}sr92ucQ(gDQCN{g{xHncjOC@?Ucf=qV`5!Y1j0Q(9x` zbOzHj$z*agHhTQ?LFLfZl_VTC$rm-5j7_zW3_GgiYBu8YfNeYD>9c&Q&P1Z}1WGs| zsGl&Bm=M*MYr&BjLBiLsh*I%dAw{XlX>Dz#zTTTYhQpG6r<*-{w=#le^Ny`#3l1&K z4cM6!}u~S>5ZzV&|F5Q zXtc_wpl`>TAWfpv>ZrW)sgHxU!>o9e!BmQDVVDgYHqvL?m}YqLpk&gv{fIp>?`1W8 zc-6I33&G5=H$fiEdkupONtDWyNYqmkjq${q=egwiZ$c~%0}cV@cwF;do3n(Vs!+sn z1Y@E=M6M@nw-cj}QI&$23;Fc~R44Cq63ani@X3cD5LBQ#nqM6C+gwH0DbNGxJV z>`Vs@jV_f)>a>SSjWsQVev1MoOXC5?ogTVV_Mab`2?0d7`TE;2nAjWgRB6Hb^}Dew zNh-CAtlEm!Wz1=8;{z9c6YLO#mQhhGqdeaOCp7Sh)z8!VvtEol*Hd%n0M_k6;&(oe zac4J?d%9uPDwxrRDma9cqE0JDeY$8sc$yP6F+B0tiy;IO9T#(D8Ei+gXp3PO#1 z`TLKNPp8@Q<~z`*p*O`nH!o-JV;|zecQrs=3!nPpPY6mF=-j{zYY^CRlu7!be~NEu{Q zsZyhg0QPj#sx+A$U6`gxMbM%m7(}Q6rfZuyI)#HlwSc8F{h_BGWPVE=5ZD@KOuWW? zAJhu!!X~3iQ-uLqQN4dJ?}-Q?kCRnEmRh}q)gNvJ27nOv-}4|dVl9m3y)!N@;h?>R zZ-4tEo{hMhhdmmy^{~&gJihs3@8$Zop~-8O*U+!Lz{z~X`_pSc_C(k}gQR0n88IOQ z^xM!Mg8UrF&x3s-w!djpEy9edV#)fv;uslQ6KC;M6Q7Bio;UFs?;GyO@Rr~u(z@4QkavscD1xs!T16qC${G5l|6?kn|&nY0VsRKmxK6x_-2R+1jCB z3+m!|G#6rg^m&-k#^+wi@zQm*q>2k@{@@#)7;MH;$accKEVW_<+hvAax&Yfk5b9*p zPgk%wFoL^uK9$$J&0v2Sd70qLFYE)|1d(pKZak6M!lpb?$;bb36L-Gc&fi>BM?vJh z!?txA|MH!`%)jjOJEGl_D%A^DknUhtOOO5ok>eT#v}&6s6B@>6z#A z+}me!#rxlnSzUoMG)z}A?Tb7$wW^Fl!eU6<{sb^Vv$KQE3rZ#2bPHwdd~BE1_9vVoAX|*-fi#!X?N)QNR#=$Y=}w4%8!n6hm54 zXGTdYI9|0g(7J#D6{bllv=$r`0fIUY;W#;9ft1j*mGZ`g9FPtt3X_7;yb}#mEg%*i zXGps=su1G>+^|bgCdlQAj0L)h3KJujAS5&$cB<6)RSW4gfLfOjiZC9;3mWZbbL4Ub z_Vjs8Qzp|*K$TJM)=(`>DlO>g>1N52Rv?67wUjs!aX&gCt^&aJLD1!3Cw&Y2erX8V}OQymR`5P zKY^ z=y6L|SLsDmOlb^+IJ^PzkjgQ?h?vYfIC5Y!aR8NTkGotgyaRq>a8j~*H8pl7M^Flq z=_K`St<<2gCm>N*ApORvLU|z?dsbt{9Mh%3Moy6J7}5&Mlt{Ecr4N8E^9%{xUR+M1k{C4<$?HC5&I^;= zzKsRT8j&(V+8H1uTCmv*W*7$g*sU9x77LSkb^}Bj!OnR`1r#BxAryibu(JnhZD2bh zu!xi_P|$)pe|@;VgJJ;5xHIG}QlpF^rKlD&P!zmoSqQ>r7^z*{RDlD^Dee0Ql}8h+ z7LvTVQF@G_p8RK)GyN&zqzMBK79_-#;DuMxWj)#Z{0g;HLA_P(f*sx(83l}c* z?=jael2ys!aYEk(kPt4)>3~=Q_9lrG3rIrfOp3i)F(R71fglPgyV1Ge>nRGsrW|C&oCWW-vmP?_qEyztkxp_rhyy1mi)UWGrLBC$UvWn|h z_u{&%?pIxLT@V!)5nK@w7Z4~ng;IL4O=y!gGfifi`AjpPN#;!QIg`onkMqeig|@&? z9^aqCgGZBgCYj6Uob!IaUpFF}XKy+iMjm7JTU+_amLxo(_tbS24d-%U?|u9WRC=esr!IAKoH zRfe@o!i{j>2VO&_s92Lq(x^OU$paoK9Yf_JXgoZjaFFCn9@oC7lecDFYU1_GsVu%7 zqEl(M7B%1a&;VMS0dhIJ8(|B|Ma}o#b0!DR&C=iBPpDF*35#hB%{oE^xb<(|R5$aP zC>ok>4aj5QlWyVh!@mixgS}a_ZlK%gp{r{n;jmz$5?hCTRRU&n50S6qQH9b|`B_eo=kbs9!iZ*2h3(UjA+NDB!~@`S)WD z2N%wEr8LVreYWr2!dD*NXE0)IoKc$@t5fDf|9^AUKp(fsXcdx4RYHhRAYQHDsS;9# zab&dKI5h`d|LiMhQeN1_)?Q2?2X-^#t%klZRwhR+m#5g1GTa6PeO{KiN*l%O5Ip}& zxaa~XW?_GYwKz2z*nvYMVWXNT5l-?a~kgX)vx#; zAGwwlsZO3x=NK8u1++0i#!b`a*feWF2|>;2=aet~8b*gfbQy|=Oo9}~)kVNlfBSY) zwns}LM@vtffB)|)*Z=4#$Y&w33VJ1(>rX&dJYt>m2&;jA`OJIy=%@acPyS#JU;U?_ zQhMmK98^x=NRpu=o`lXGIzGD@$`ZzhO>rP>@P^H2wlc--?_1C5j)Rn%Gj7~(@*JFG z;IW@I7MOXDuU#>~SWk$5y6zEJxysc0WdV8|ga@9c_^sD7UT{Gjo^l%W2W;D6$~}B= zx7d;i&&3Pe(zMoC!TlqV2#(|M*kg}z#@S~Z8fHAo{vD&#gdmyhHN~rAre9J@VlkUS zK@pE9$>nmy<8dlQMZCYC{*|Yr#IKHn`WqCbEn@6}4<0;7qNfLM`XG@=I|mOQB-Cor z;scg2?qHU{3Un=v7}u~Gni+h+GDrz5%3`t5Wlb%>a+_WdSur1oysN@Lx`_E`%ke1d zw^1JsbbQ4-&~c)07BYp7O`p)meeCg&k|R+^Gfmu|&5=xYB81uZve_(6@+BT@2_{P= zve_(&zO{H>7AJVl?J^1!A?EO@8$L=Rx}UNxGn(`04JVjI&>qrEl=5`OdztqX>rzQJ z|J8MzbK_o+J_l?}?nKvGHhyn6$RcQqg+NHgrvU}lsG+;WG&NzHht8x8j8av3md3+G&RoZd>nz&hhiKJ;k}eY!HdkJJ4qwhr!`>_{ z6_5R*W-f`uX}tO4cfkG#Ebjy{40#zi1p!41Vyl@_3R$VrVN0S~Gbbg}TGK29-FA|R zz#O4fNJ^!WnYI?Q{O|v|mD$XH;CVh3l_!MHs@1)$UU@QFk5TdRG}B5kJZPp4>MPPO36JQeaJR)=X=eIBiP4PB)wO$wF>Sr7C( zY%3fx`?@7SRB4dXwmk@%89T?9DGn{Ca3(d8l#Rf+=klQ~>Gn!9);uB=j zX$A)eIpvg-$mVhefk`Hr$Ykn>jpun>cG+d5)5Az9m{girIE?FN5kl6HN#l07;F4y8 z-UAUyEhKP(kk%~i>7!X`NSHF@09|xx+nk@Ve%g~u*d_K--LMk=Ap!X+{W!GQ6~+MU zBuZ83>FMFjGtZ=>GtN}0z|VjFbGGc<$;Up?Q-4pQonhL9U|FK;h&9_4PqJqHdNP@e zarW{&dV2bp%w`SjJ-63>i)mc|fZ>oC8)td)C`{hYk&VzzHRXbP?6 z^UMMrdLONU$X}VFO(>YRRndnbQh|i(EUvZ-z&3lAWZP$3FE`uGzGSLC<4O2+$s$ zu<*PhHDR=gMFEk{Fp0S2kdOft(MM~GMlH|?w9w1|(|L`INJPw`Ig&#AnnM9PZE_)-EoQSc7-&uAJ*Kq^MC#^j)yhLkn3I?~${=#{&z>F}6?}_Ui zWY|XQGFf*oj<$$K!_4ASt2D4AY2%eVmh~qYD`auv4%6DFi83oz#hKL}li5+)I}cMP zTL>Y9kJR%B;Ro-7I${u&*GZ;cK+`)7S+!u%l7OII6>oIKpXY;p=+Qqy=Bt*-l|=njX=} zGM4eBTeq9yx0vO+^UnZ$PE01b^UH7Kl#9;boxhsonfy-Ly(&%NGM%9W_wP7het)b; zSZnsG7;!XoNf=M^hinAg2Jnk)=wC`mxy*Q)Wu3|#N;ph-u)#?%^!U@HpZ`6N?Rb{K zZMy(Lp;RIsj~l0=V6nbhw^>Y&@vk@E%;u9%=Hnm#IRE^uZ!tEKqsau^(;RFr1vHI4 zoiJ_zs{_ub0Fg9)_W3NFa6V_f{zr`d$CbnedicV_bA0&|55lr}i21O87{+?(+4e(* zeta#Z%uXJ-^H$bh`RDw2>kME0&u5_HbbdE{fHkRQ6lEB^G&7|l*!{4r3bB5$A|^a2 z;Q)?lLiQ^D{Kh+Y`de>jE;9tr4MMjAo(s?KfEE3q*MjiaHu@-s^3rfkN7H7qELK9K z3%Zi9YX=WK{y1ybuE9>)9871a30R&?G3L5FaPP19i)-G+#N;%sLa=LikYqARJZj^4 ziZ;iDHX6E*`a9P{e zN3l|6%5|C4RntTihgoyl8&H|2AtdRD#)tr3!Gmaw=D?1m(}nQYtGt1)Lp@!q{%mMese7?;?ev z*9d8BZ;NTuSdF=Spz91G%B6xJtt@7hi{m(Cvo1@L4((Fb4GE&*a4@`ZX-Cr@)-+Ql zEWuJ`JXOVx#;~I{f(bfgi0Rz8VbdrVENJswE

A6{jtT^c6nsgu~JZ&S_^x+q7^B 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 z

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

Frgi^A*P-oJ=Al^z?MFd-pzcJ<6ke0 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

Lj1xV>vP(rc#fp+^#{>mwAC<;j^F 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%0A|LR4vyiw~trv-qqD&y2-X`Z%`BqDe6h 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ś->9anY9X`B19T}#I&Cp`{sia&^T~_2 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%0DBvvk8S&QFO@u1LGGHp3;0ppnp@L`~D$ zCS}mN=d^7zA~GTlevAiZmIhYLd2#kktEEY6<2)JBeCl;|#`9lop6WW7q=5}0@U81u zJJUOtS&Sa$FaP4*RI3a4b)WJ?nM!3gMu?JwnPmT$r4^$mI@)-2bZ?#+;YzJRWF8h$ zqEG+5hrb2%Q@;Awj&Kd_t7lS?QhJ@A@6o>^yXO^U*Qn^jG3U85TP2N4BOHK{bIdzd z@;I{ZAXPn&BMQb6n1EF1kkKw3H0`D}t8q<1JtzbzH#B)|i8?S>EXEN9j^mhM=)j<0 zuIu8ug62{{+7&n&gj*yCmKelg1&0+vhO}da`;f^SVZL$fatMP){I_TFE?J8|3BYk( z7J^d)6;sycI1EFaAfO!tEb9<-$g-u6t;BS)2DRE8VHmO$n!08*zl|({*6adKDdZy` z`hEW8=ga)=8$Jtj8j2hF$G`j#OTYLBw0{pB<+Ea46*o;z^fJ7>Qs1CDInan1e_<`& zE1C)dzd>8gq4hGt%~PLG@q4fTW6&O+G`hZ3G{%IjN~1Zz=;$cdKKljScl)>KjGe>L zqw{PU8>JCwE;@e`ci;9M9{b##pap}T2@F?ifI*RA|Rv65A{r9pd&&9!Enf<_>(Dv&V)Q5dz;oOy$Ud{yQ+#JjBdv z-A7&sN~0dHdfCf(=}TYANO_CR3hQTcWR$fkG{U;XG|%%abYnu8lIhdYze*{a_i=_o z#sYb1srbRSe!w-4FVL-K$wgkVAYtO}1y zE`1tzeg7vET$i&pK9c(U40qr0fHeZ>akQn(poO3`TH<4${2H&l>MXj|0zO^pwF;x+ zQoeWC=a1h0x-}Ysgu9W|>OA?$&*jf=`VbeKe=b?Q#B}WtEum1VnFs*Xr=_4`SA zQ+)cSS*GX4I9R=#v8io5{r7%@uYa?`z2EVHAMhJ*eg^;g%{%bj^ZC*zzRfFMyps*v zJ?a>{Jx7?2DB(8@jpzA_C6x+nP}O>4rZvcPC*AEO>{{4$$WAr_0)*(&N^n)fL}BAN zd2+>oAtz5OAF|R2AC^v~-EPxq2ecXvC&C74*Chy+m>l11l5OW2HV4KaH(;8_hk7h2 zpRKZluWPIdjSwE81j3^rBqz4y7^*AI1w5t5X&)gx8e$5@0=Rb{8z;_>3$9`7J1&Gn zM}%k0==q;(R5a7mvrJ8G!S{U|g!HS`#zZ*)Ajk_C87)znowhj-reS(G*)gWc8pij1 zN+k~y?BvDGSCp?%NAt#4zLF!Aqb!`L8cXc4jeOt(A4^PEs$?SH;sL$lP=aRR8EJstoM46J5f(;C}M3&7NgbZ z{hUUrCT-iK4BClw!_vQ^?2l+79R&$SYgvS@v{egVtN-HlnZx&+@#n(A3Thfo z!`d#dZBml(eKb{!j!o+pMLCSX*chKPxsBu1N=*Ix$VWfQ=F%AQ$yZY<8Jqi6-D@V> zO2t({L>2D8E^HEVPIBdyPhobp!gd8w6XNHTWcY{qo2L9dr@qEtUUOiJ0)pJ+q(8uVnm_xepgPJxfKHfsYR zMbvm%Coto4)6FJtjrD zJYj#PZvfLdCHzi5Op2y{*v-gV`d75EuAZg_F!tNYzssU0N%~x0 zgA%QC#AYXHi@5e9DuS~nCdnv)u9*gzhC+xgt_x@7%202`&3y_%RzurTzeEfXY8EW& zw_=;BFbrvlkXCS#rNt#17VX4Z62~!_YL4Sjn_aYZM1zr$5o+^GWUM<`DL=x2lLu)w zHJdhV#&wIV64DCHKy+D$iF0a9X;*+SXb=D=7njzlDNWrn2pn5liZ!|`>%9L#qrsN^ z2wTU;0S7m5xPN9pMOkJ+DUNv_vwN5M-B*7W!UFI3lZz2TbH~A9(lSG!cN!g(Utz`f zS@C_e9$*zg!y6{2HEp43>y}xk(RgaW+=GFN*Y#l`nVX%Z?7@I;kY$yS5psod8Q!v! z71d-==B&e^IVT&W04ZXd?sG1EEVBeG9r+nTC`x1F49aEp{`5y&_u|(wtIYM30XiaM z)@U?&C!nDh$%{c!0*;)h@vQ4!W9hrn_Ub)Dnv~Vz3E=#TFJ|Aqd#L#V*)fln8epMz zALX+=mh0=GDF4-=sbJX4p;SP#sbiF7_l_<7jfxZ!&nwu)QN)wnyj@VGq%W0PB<#i> z&LgKiyU~Vpof(?`2GY8Qbhol^{upz|2YJr3pTmk$NKe|yqP1MpkkN`!n+{$lV6ZSn zSFCbU9pb$6&LPVK7_aEAy&*HE=n#;T8TKCgIfJ^yLU1p$Y^A_O96o#(JJW&0DrGck(2T<1k3kzLra<2WSPx-gY^37;zG5xD~^cRw)Qi(5o<}>Wvxswf(vabl!53{h9QgZCz43m>vXlNBr zOe3n$^z<}Oc=FX;P+g!hTd_ryBrlBKtz4d@TCI@xOta%zUCZfo6uk{zoCcwwkNb~+ zj_&Chl8sC>1?xbckoCX!o~}V#^h1k%BV;Jc077Oga?p)muWiNaIU&u^2-Em!JwQgc zjELE4ReBWEmYrOi`z}o{L@}a(CEu&lQ@?cI+8-rMNA7C6&&oA(%Ilfq$gHuXG{{)i z(xsyJs-ab^b!lkD25*eCMfxIIZFWtL%-Y7#pa;DaZ!L3_FLiD@Ho#9mW1n$k)f;ej%m$ou1_j*W5bWKL*LaScL0BW&8CMRqFH7qVJ66hw~ zZktqSP~TPn%V9vVP-Mv36|Y)E1YsJGWnj@ZNCu^ZR4PL{EoikhGy@uGYev!5>+ces z7DG-RAq2JB93yTKZ@ftN2sDMJ>q&NxW_Z=#ejg6`yyKrrt((YYP)%c8@rZ5X z)aOq!x%E6|4jf0?;og9kv)ND9He8v#O1J6^jZTmPwr|iqZc#!m9!Q9-egXL+F-F9jW&ztOgw?Uoae_O~;-@je!{ z%kqP1HlAJJK5d}XdB4eU1V3v?OOJ+~_(|z;Vs?SCu>uXPsj4M5?mmag{S7)IBrh^1 zw_r_&n6*@oP6mRC!?HZWGk^DDzH;miUiYs59p7i% zD^aah?9Xb3N*=2ZVJOhAfmky;(EXWEy`R-qn_!x$jzu(jyxL#334HjkA!41u0MgQh zA}euYvF=;T+obaS#v2y-!na? zGLB$5Y3z1|=tCo7T4fVEC^NK__1=qU4N$6gZaYL@_ZpN4WsPcyo;`A_f6wScQlg<+ z%TC?9CWSplPR|64te1tO&w!5VHG_)&MtnUQmk=@UdtK_65Z%+z!A|{M>kUb=)`2l{ z{Sv|hw*XEUhk#a96%|_Xwkw$PD^Qzf)v{TP>sO7Gc1UT5Gy$RL8rLtUM<;7LM%^*U zDk-2P42tDA4xvR%9LHf8hk6KsZW8DwuE?>H?oxE})WeXC`4Jk82CYU&pqmVd9396v z%B=*wNWYHbAZ$3G)*+2Xz-S(F;~PkaAz^3&B_k(3V=8w)(QR zQly1PTEHL{@kkg%1**Z;!Wb>JL{S!uX-e!!DEfwYD|LmGs|Y0swS(t%I2k||k2Z?5 z>;+bKVy9ZwH~f%p!K~lm0Hbo8kP{r6pD|iH^~>#+Jc z0)|FQP&s6sWCThJgz#u-!6gO3UL4L*7a(fiq`CDx4&QeHsn8{hVoXX3(D&^5mB_-k2|B|iMM&wwcLt{1+TR%L*OhV72e$*oTz%>Om@aGEh^f{Efd z11`+XEs=6YAY6>Om~P&s(P)qwNE?{EYw}AX9ep~TrQKdd(?XDm;n^X_VX#me1#7Vf|n_OC~31G#aGSS&BKAg~k#hm7$aF za^Il`7!o-g$DvRxqQeHEhITMul59nnLc!c@g@VU@CyqjBvSlU}EK0~|s0mG3Yl@XD zWuaL_&?slP+pqAOrwwU>PaEx0Zx$%MG%`e#ZsZ<(`FYL6n#7@PuJCQ&E z%pcYf#yZo?ihITaQb>S_sV}~$r*ozw@zi#Y_hlB*_#Z69H8lwjINXDJzi2x94{A7hu7M}r`JJ1Oc<$eO&KK1RWtC6m?0_M z%i+=X{+jdaluE;KbCtD4-m1`j*v(p3t_b}Z>^q7~ugMVWpeu>zOp{~Ru0$S7lxi;N z*TxC$u_&rYG!rt%Q6*t10LNqrtty|<(K5lzwBymLCN*H7$Z<~iq z-eIK?k|t*y$HEY`xP%-jB81VsE-fw54gzvTqfJRU4&&n+s4XoK>X1fbkwF}W9fx{o zg!qPTmS`G7Lltw=#tca7wh7lx3)*c>JKZ4XjNpi!Ot=N+f}c?d7s-o&^k|uRA$ZB- zSNT65-Olr$ew)q1+X#=oldr!1S)4z$i)~M>@tk600lNAQgwRx!A}2jo{VD}1 zNDDmMhNKIt; zkN-HxORhSPZtYH%gH@zE$l>ZejEwGyHG^5D%;1(D71|7YOwM91(2R_&5{4Co*hMB- zWOUT0TGgave@zhm|IWjl*){B%JF9%8%pirJr4?yc#`|*SOw-bb%P~tOY6jyfllXq7 zhgNJE-%U%ED2=5!F@KB=?kMwGaPQA<=h0VOjkb`vw2nMk%iAr;GRF_iFmvE1?B1AR zl=C=o;t*5k6&N4if>N5a^jK9orWFVwSgF@}m!@Zmgj#6~bW@~9TKRa+AgdyQV zi*&AH-GBtmm`c(+VRwA(796q9Y({KF)k22HGORLBMiod2y~gshpKrUVRN~m|G`V4q zH@xT??!UCj?ROufBsG^k=~+0r`?=+|76=cxi=j(4QK=80okwuj(JD86`TYQF*suZ5 zQl)ZsiZc-Q#OL|^2$LH&aBOCVJ&%73d-v`o6@qXCjxeG&$8k7$a*2H2rPT~Yk?1}s6L=-R1SU}0XfY3f*q;Pi2QljzVYpmz>&@-wc6nFeO_h{q4KdBWzUU)3pKSX8)^4Zy=$X~Y_sS6RB1c`cKP z;6@1Pw0wh#D4C;9(up3=D6YyDH`2uN*-L2h-Ejq!^&+4O6Ywtu=P!PSv6z6{&R;wrek^w3IabDl2+`QhAh0 zWg%`FA4&t87lKMGlhfnv3}|hr zT?pC&YazbQ8)y-goV6A0I1X7`{0{&_1%t|TLTpnIvJyhuqF{!VWz2ROjgVBkO(We% zuqiSzdeX6ZCrRmS$1(cXwJ8K0;V^6)BY?p$BxpAYeM_xPcg=t_Y|w7E34l%qy4?=x zP7BgqpiRk{pxy{s&d+eyp`Vb+3!E*F;%`4X&%7Q+Pu|bJy!QFX17GFCM}Gt^y!WXu zkB8Oi+NV_~tAcwh2g>29QAvA$SJ-XS87Vg*)gAsIwCQO2+jSl zx@MTE^~38}vWcHcwfd3FRPw&;h+n4Y=}jgK|JH1LLDMy2+WG>|de*BrdNjrH`IC$n z1Vt%$>{gF&|HtRRP757>1|CHyxgiqc035LgtjLWUe+`pIe#+qcAX8*o>%p$3ybZTkoEFM`cIkJD2+JRfy zTpP>gOKk2N7H_U3jRvly-r8VXh3Wie>5 zZQC~P``KQmHl2;@x@26(x^ooC+UbN4W+4g!pHxU3$b^M?&2?a2ca@%lMk~C=8iMuo!pk`Gm=6=MC@7c9Oi%AaO2KPi_c}I?MlNTDs&sPtphZATFkysx z^eA28l(i;$|4qJxwoONsQpvOQ9%)^nP89@4pGzqi_l7xMU0~C;E%ECaH=-V*ljP%1 zO>MKbin7nDwIfa~Zlug0rLfd36WExx2vg6hSK5hklo`@w#Wz#=WRucXE$b|0MBCAO zv`QpqH`8<>WPCnT_IZ)ek0gb_(V7*}28fTVn?PR%;?(ts3X`&*3y~pj*TG1a(T~7m z?3oKS<(e~?N!lg0#NM6sq-=hzvXoA0iK0fhN8ifC z4d805RWVwc2qBDKBiWEd_ejeIOGd|{TRPsinu5M&udPhTYbS1;3_9s~B^$nJi~>rf zVJ^DlQf|BLy9|0pgQB%!+#9B9%@86>;^crK`skgjkhIJ&J$;Cj9-vejWyM$VI-Bjw zLm4=2py*lU2^K3A@pr4%dm3R?SUtyoy7nBmTjt*~<|C;h5ru^1<}$iZthK?Uql zHU~(B8Xc~A4_!CT9?9AFyBkxg!uURk0vB72khX5pX?N(fJG9$vn$0GSMo3$?S!uV; zz%kTu##)5P#8fSvaQ6(&{%`(;<*-4hdre+aAm8b9SZS}a(q5&l4K2)=^qAx5cH3r< znKHjColc{huqi*n__zxjGGttb<4Xbmc;oGS@oRgz>1{ved$%xfPmyUoyv30^wXJ-{$ z^MYsc_3!_X$35=pY;Xl*r3^Ry>kYJKXBY;$zM)vArKF||4krZMc;jc-cmIzlx=ot3 zBUDbzlPhfI)(4Jp{>7J(&PiLZXv;{5);7U2pZh{S^|>#S^EOl7dJfInQ988;xcipR z7)^{2)cqz+5k(1D`uXevOM8FJ?9m^SWr41=(WSr8El`rqA1jJ#zV( zx_AQzW*}eQ&EfeuHf|iJC><_1XA|#w=kKwwFhCaLaHbS=>jPvp%+Jj7-amg2o5qfk zsRb0}c2=A&zO%ySsi)D<9zxVCeWicu7;O?E;8?MgYPMLZS4nA~f>xx$c~)vCxND}! z@|*)YWWg`+XRrSWUwO|xaQjc-N!xkhbx)z-2!fyyi`WC35DzdivVlgUL9tLIi)j)% zj^M8S`z@sEuxuCCRhtGoh(kW_;JP^rmm2?L;W#$kHBS}?*DVs|sOT^x2pX~bN2D*w zBG|BD11p3qG=jKTTUuJe&AS{wID-yDT-Rm9%^T=8ZH{5oEwUIa(Fy{x7`wurRVQ}w zG?&tPO$xxH8vphLHjqg{v_~MIs&NH6DV;^%V?|a|hkr#rUJGSBb zRm$ZumC7_D9Gis5Ff%iY=ar~d7r61pFUJmSrBaD3f>NnOO2hQ@G|SaG_Z{5dmoVP5-xZ0; zxrk{YTC=7YYW3-8bfVZ!7O&Z8s-HNQQ5HuOzL<^IUXj?Oh>PQ-Axd)E+iT{&fB^g^3=VDFGsx5NO@5}WW6{HdataN0zo6tr@!rrWH0FNC!gw}@kE3C7Z zF=nVTIXQupIad6po%-o`kBL5#8({SMS$ht8&28@*0P#Q$zwe!w{(B{xxW1z%FWc7y zwfc+(Of%DhQ<_3f5xqx^OVn%{Bt_dMz32EPL?$*8XeaV!A{t=wH6nWD+VDuxcRdJ1 zMp|m2utNruz8=y0l6KG0?;|ldESJkX_j$j;D_;IW?!Nmc{O~)sFgZDaYWl4B3zSNu zwpr0Jg|YvGz9xFbZ?dUmtjv#BXJdMvQca6e_BSYNo0YVbvF0esN=i0rrBaC_l^GlU zs^aXVl!i^EvYjH+*F>GEL5cp3WYZp_`+cv~iia*HWVR>5kM8AF>l7H%ZxS_B^tH?x zDqCI@n3&j3&{S~zD1>I9nrbCbQ{jLxYjG+xR@7l=TwS$|G>GU@YajE3G|`E0Y2sXz zMkAonXiyIu1nnm6Zrf1GExV!9ZqwG9PPbpLno5~Dcqj3i9pTUsPCNkZ7@fXx8w;a4 zh1g=){9fzml_&w)-7Y~8&}ny0iDgKq)5c)P$GnIZ@VpmBir{`F;i z>3i4knSa>BmP^vy?(gTq3n%#OC;pT3ul*-3c=HjS_MCr%JE}bTQC&Xp<6SRBxY4HY|NZD_1f*TgUS}4jr1|!yo@VANjZ28QHjr`T1EKstoFr-2BnM zr!#YiL1`oiV3=cz`xp4YU%Z1WE=kkzf5^76tz5A6iMWo75Dgx2^>2`tC06Px-UFf` zPjsD+j!tmaxsRbM#(D7Q3}b~6wzyrs|D_L;Rnx5a2O0J*sFbrGM~;*qPKCfFpB??(59We6$CgLFaR(M&*}tM-?#?)Xszm zVO(7Dqj1sVpTr?QprNfRzgXpt?|q%WdHWyn*$=*#>Y=?jzEAbg&pG__@AByzKFDI_ zyA|)E5q!H@l$u$$S3^4xQlg zXHM~!w_VHoe*4MnnwsR$q5TNqFo>Wd9D*QVg^(=JY6J{Bc@}~tf=0mZ9T(DS1nk&x zHq~QutO83*C-G07q`72{aajkZ@XC)cS9sB49u z4_6FMVlpi(nzD+v(`27P&lE?ycJJWN{_HJ0>GI2Y*SoIg!yo=I(=*eYRW4JlR^uj7 z*{M)6TyH&>qn@s0l>Pe;@rAG6#Jk`9=gj$4lrj_RWCOL{V(DA)f2mYLN=c|Q}?IQxTM zE}o2;^(@kSPoM)w!qA5uHtXQ)_nMQN5GD}(t{_^kM!!@D(fr-@1fP1q8)neblalts zQd-JUlnif!IS0MrQw#;tGDA@g$IVMy_0W~5Np0AMC@m%9-Y{vIqpg~>l`If+wT)f7cJON#UdkI^`ASZlIKiWK z?`FArf;(^f4(Du{KRC|mo{ zD|{l;56_d__w%3g%%@&uLo&_pJ6^3aHMJu~Lw$dNbIv}CIls>FYBhGj>J3?YQ60uf)gW#MAP25X5E#DIFb`VSEV3 zG0(R(sW7D7)~7Ti-EQ}k=ghG=v4*ANbWl#nXuim~8+LQy_$~(9nkVcWWJ>JgIai#` za&;f6i3#5DzFRpg9s_$WfqQ=pj?YW}Z2wmF z_H1Cws^@t9pTCEA7oR+#od={)(&i+ts#I~hofG8P|o2d%0r zi*;m?hB3Okz z%BQI$Mi3ht*tUCsu3?MozH=ud7Kiw|oDEXx+$m)@{cpYb4nJ@HH;OM=zCcyE_+O7u z*eBt8Pd9GUm*SFD#E%(7MmNtekq^&-1SToNv!@jySJ`JRaM3YHe%CFh1>_S zp1E^RWuMW_j~;uGw>H~s=}%xuXL=*0U7oa-Ch)0vjML9MkAJ`U2Ko&T5h}@84v*!j zhi_y0+^c9%8}Kqr*M=7`2YVUVy%B|OfV^)1bh6ZSh~=vLiv|#^=^8p ziUgQ08ptRDU9aVyKfMXkfca~A^?@%iwqpl(y|@Qvod`|v`SYq77Sp)Bdpo=#_~%>u zxnx0i3Y|OT-*at@U{{O{~;xrLlsi#ogblh=+ zd7OrpHkVm%9by0<_pBI(;f7-xcqAB>;hO4ms1ZR#k4!*5AMQ_aCazIpu~=CWqU#}c zZQa38a*VNrQT`bRV{zmJ?foNM%FTmg zIG1GIfX<0>uG0HT9v8{Gdkfxc(^zi4C%pFZWk`S{zsd@M5l>8NQpROq4pLgU8>Rx| zllF00mnb)(rR|85nc*upt(L1buTlffb8L)axTgG|I+6O7D@(~HZc_5r__TN8=C8cP z!b3JU)o7hiGVNBpx3{2p`}3j~{c*HP@iJo5P9t>4|lUl+uxO#SK@^ zY?nh_JyN>ndS^SEF-B==nZXyoc0JK(BN@ZM`>yAy;N6H~LcEt(g~NPH9O6qWpJQ?| za(&`3W-|55IR-N)5qgAlLgKXy^v0;;=P;A#ZUN~j9hhl@;y#y(Bkl8};t>LYh6gAj zCT(^~by{k|@9IY(qbMi}F7?a#<5LtAH5eykh;0Kb3uJLL4K%$U7^ zXj2rgY4G%leSpuI%d5EVJHIEOs`T~u(;U&uHA@z#7fu$L zuB%uU^cbW3=5H@@+jVF0e?EO4HLV(nf&KVJitk)~7SY!EEI97NG}T6Vr+YhZt#}#* zo92iYBRN7<(+oU%11p|e#q;-lgVh^$(9q%x?Em|uOz~f6R6fA8^uMlKuW*pCKxQ;f zquNA53I?q~jF8SN>(+4caf@00)34FfwGu0Nkfrn5S@ZNS`1>zM2!v}8Lcu0WgBqkp z6G-Y1nnrK$es)^{o>{(`O^GydBTludPFP(#Cs#?&n>W(*_a}I5+csuaR&f8#SJ5)l zWcTiMOmAvqc>BxTz4;j|(?Hd9G&M-ICa6^v5(9h4iV&@fmT~)?f8mlFenExa!cboi zEmK>tECW@IOwe@;*Iem#mI#{F2&sfYK|16p5faFp#7bI7Mdg!cAH|~R7pd2E!YxG( zrh8F+O_(tSp_&w=q_L)kF?$RTH53#_HdQ5{pj0qCa*$fB8Y4Nvm~B$4RrA`5%kgPJ za^^5TO=HYXp(sJ5l=$6Xr@Se#Cm3$?u6bT4f-0?=gs{suPmg3~3 z29rY!4GrN5*Ta5DCX>#(zP^rxIf6_|a;A+>3*xb1#2!I$eKH8)Y-;4>#PO2%K!_qG zuU=UKAc{=HK~}3eX({Q8?c=!@9%n3+WszX_;uaIMTRi)}=j5w-LL074C_vr;!2V03lsWQaqBx8T+T2tC4Ryu(l4w=ca zkfMlRSIcbtiBDzF^~6l}Cdor?IHEk2lVyJdl1MRAJ3k_5~t;KqFyK~*I;fg0&h z^B{;yO0`^KlS_3oEDU3m`NuAxyQdo=RCL|(8d-*cAth}y+VH9>dt)*Dx=!H`0%hrV zDap$YE6~R$*b^Vi$%Uvop@9_SR0j|10V>@M&bTi~PBv~M%D#~j39MvH9S0ux@T=pb zHp>`KtuIm89Iryo%@hcgA3x{)R{3+w&4!!7Qj%&-H05WJRIB==p@U#Nqh%s6q6AK; z#L4rh1S~7gk!|gK=#*3W`d7bFrk?HV>EYnuAPX1F;p)pS8U!~L_)?^3Vp?2pH&R&|yg zdn{YmzRiXW8_SQI<&pynmPJr^fC1Ni{`0OBER8-X;8ijaATm+fH?g7kuM}P-vSHb$ zBIKk-=1};9f5P>+)cvQVBoxwVY*g8Y37SoFb(ontY&D#w*_r7%UlT%L3c*1k2w0_N z+wqYq6Pkp{=Y>M=2h_&K;+o+3pgIehM898wzb1#L79(u&QPJpu@l7K9_UY?nPW%Q&YjT>#Y^ z;k7k{5;>O4Sj-WZJOulv!BLA~z~I??ckyi9Hq4)0NzIM}jKzA9LPg+^YAb=9+xQkl zv7BL3-B?RH-iK+#8M9O>BaLkB8)j-{9pC@P>9n;jW_m>B_0=!n*Xrrty@u_t_Yu|< zG_^ooT?9R>F)%Pp``nN5+={noTXr$?F20y`Tl;BL1$7~nR3c7^%@{@nUXdhFHx?Xc)-5>ef%|GCh>%Yi~w^mWD&UM%H zyAdLK*!8J2HS|dEq@5dx=2NlK2DY>ifg-9_K^BYA?)4no5n(J2*_cIDWG?soWG8Fa zuj6OGozL+4oSWhvqe*Kdjm^Nw0qPY6zoIdvehP!hA;(*S#;o>PbnV&cctkV-b_yv$ z(~8asq(G%~JSJmi3N5VRlM;afrimgP^Zl4Ko#4mnAdteg9lfX!8Ua-IW?v+kG!a50 zgU#UnAu16JjvS!idR_XH2e55Peb@mkc#?KmZz!dt#2QqDMo=gdZkjF)r2J-=r@a%q z>xiL|6ehK*%HFQ!c;`%IRJOpr99~&PCA--fm_h$e1Ek8yi>I-l5h{dEdu$V{u<%7{ z$zmXcBxzU#Tuf)98lm4vFw~u3>C&a_>g&U@oTlpkttRE&wks2Z58Wt0x3HclLHJjI z4Jj?MSgsL#e3~8M@DpVeaa}0H=2*;?mk2lHPel#5Xx{X= z$yNwKIG{W2Z_X;O$|p7(j{gF5;YfI#DYS6C9|C{r`&-VI#VbVl>k880;d|Y}S#>|R zbYoCe6$^P7(zWFOkW$hzb*eMbpKyGt>UbH1@L{FX6f6tj9eU*|(Btj?@ zB0DGn!_^atzPSk%*HU;`(WZ+^^Ghl}K%bk+gGcBP9gCuDXB# zC(mU}j-sjoB9REys$Nc_cW&|l8d_S&TNZ|4ka6X8HLhXYa6>EOG652FJwzlDaV1Vp zbB7evL~F}(tkStuu!>kX&tJ7GZ7X^6N=SOV-3mHnrd3*C_Qc|*T;X(!n6I6x*PELkP1}(`RCrVJg zYLO8uO}!psq?7@q2I$?pgLvHd7h7vlCVF{Qha6|@Fo;BIUCEn;Krj}MyO17H#y}r% zGjk?`MZ|doqno95BAd6ZW zDOw8gc$#c{l$;Mn3PmnGc{V#p@X6DT;)vE+>`Nwy5MkyKvneDGkPBC1nFpzj<|!B| zPdv4jbFaRMV=w*;>-rPUbygJ&^>+h;NHofb<@&K)YM>B0DJglU-{Q(^zs!QR2;cea zHC%Pkhw!;{!=|PNw+0r}DGd}w!IeZ$W$or29F$QW`^)R}4~{y~AEk3*lB!zb$>k58pz{_w}Vr@*UlF^Y?Ch@`Z;ua_$@=k)x2(OF9*E^HdtJ3)ZB`X;oE~Gb!=< zkunQ-$$15p6bNJ`BdQ>x+T6LthV7$#_-G%EEzNkd1~o44ek`3MR8!66U;ifGx#g$q z*_R?%TSFkM;n#Ac3u&mRMDYgD6+hl^HE->UvAnCm4G+FVA5{#Gq^S3+DAFRAb&6NJ zP;e%ig#wD#Ls3c+sX>}srgAVg%xE^t7jOPP%h&DWj(h(^W6NTuH(7W@o=VM6FkFFJ zC8(_OkoTs^dehwfS{1k5`yk8C{204;>>*gt5F*Q%wI3-JOtq57{F1&CSD~EWbot_Dhi;6H1JlEmX5?q^C~0`#0dv=!jTA> zj3j5K@rVGyK!B{7!IOugERfBEnHi-b?^3@M*XWqZpoaVize3*1P*+`tnHi-}DBw{7 z`28CByp6xYhh1=tcpk+|AP~Uog-Wl2M*w)qTPAob(6x}0(Nf{VkC#lwMil{UX`+X! zX`9xH&mX|DEPQwwH41FsuW{|C7g0%u(QKAVyhxG7XK5rwl7OfpCC5OmqL|Ytj=aNL zd$#gg;wbLCaxP#0O%LyEFG6*U`#)PlB)fwlv5?Q+`8JI0Cgj{3^Zsd$Fw)$IhEgF_+~RzxXA|c!Dk4cCc{4 zJi2?ju|^Vv)I7Q$w(jbsp`o5VeS3NN<$u!FHjUxf07aRhF;c^-S60zKxR<3X zn^~RnsI0E$>tFg3Cmz#DQCj@<+2?3KW+9f9;#=Rok;^~+F+lR0-~Eb@oO=fAH*Mzn zZ+!zRpW=m=Um&Qf%$(N2)6e~#hkt$#O-*&Ic=JsfTI#8-ujW7Ry%*J6!K&An6Hg4% zeq;xMpw2@NJ&cmel1%JpQ`Z*SIy;dv%LDg6Kut{*2jYE@wVBb<%!*Cxcx~nD9E=UJ zyK4vadXO2-Q675eHz>s%v)bDD^WXl?tj?neseXR_>-#z3n1%Sr^2VCCnBH*&dB5Ps zuU&`Fw%M|FE#2L_SaS42wr<+Yy+8j6!-E6#?CL?If|iyjt5>by$%h|d=FBPl>i&Ca zZ);)B5wrN^Z|-H)s#oy{g)M8};@IO)03>&O_jdYsY$BZ;WyKq-IBw}uMn*=s`QL8f zj1!ONwHN=%u3fwM(6STx+w;%!AOCR|%Z^{nFMjna>`aEmix%*W>%WfCKR}2A4?g&7 zj$U#MwNvXk|BUmn#|%Oh86N)KL!5Z(X^f?_Tyx2#RN;grZd|j9rAwExXV-4-{@I;` z!y0caUrwd!W%i7A?z;OYw6#U?dL^5;uP1NW%xrJv>Ps&po;(QI9Iw6j46`~ri8eNK z)n!+KX_4sbXJ_|b+Bz4Kw^Cg6=}S3o;XKSG)UQFwhDO`WUH`umg1BGId#~%AFC!c->p_&Fh ze)efZt0Sa_M(EieWA^-G>Fev~%1f@{l*K3T$bJXgGsPNmTNeu^^7 z+#}mL`p6D$`sOzY3$N4UdA(EuRaI5AwauVwD8srn8`!ydCFh*Fh*zHb1G!v=Bj(K~ zk&*-pO1VK)yal{o=UP+Y7vure>zvnyloY*wJfadqW{Jm>X#PraUP;j_NT(b?kJsxV zB~$qPDj6>XQbi(Fc`Qq!$Rou508jqN4<1G{>UZ0(Y%kQtG=q+FuoJKU8wRqwWPx6&(KhL*r zxZe5wQzjV~R8c5M$mYm-ZM;SbZ`S!*+scwoS%^XbACh#+z#}dE=@jX794nip=+Tgg zU1Uc4NsC4*lY-&wcG5!Q#TRz~UY1_5jNZx^)p~@>KY9Us4<6v!PhCwq5yvw3;1Ab; zI-TV`J?z_CfWjaR!D_fKG;8AZD%90fQ&Gs{1GJD%CX? zoj$~i@?J_HFO^;=d!<@QGi(G2M|6Cq&VZsYR|L3YtA{gA{RDFxb@r-xK7Pvz4h|H! z^@2t|)F3GMBmCk&e^1riDRiD%OLfZP2N%!e_UHc&2af0dOp2e*&k?h{C|--PLIE`^ z@Q5k`RRwHP{PZ6O0J!d~ndFQtrs_rYTF6upS+J!tMhH&>HKg ztjb||lT_6C@TMYI8I@PpB^U{Ha@kEkW!BPD**822*#fnN0=cZjBUGgDlFeqRC^+}z ziUNp&z%Ez>1mv<7iA0+A1s~$nkAI2hw~f*F#uLa~4n=qgYl2G61E`Fe9tIA?dG^3j zoOIERT>9l(NJ$^bR0^M85D8>Yd9M5HEJUTmPNYE9S^dhZ{PX#L za%AU`PWF~w!_ZL7@jChah=QQ#9j~EsUO`2{i{dTN-``Jlbv5<%_0DiR?@ozJrao0w z@#`vmef`Aaqle@cl&BoWe>pXKoQyH9>wbOhZm#(D4;W)Ae|uvuPrnvp<+coKcBOe` zW1Q!=W!adl;;d_Keus$j#0clhe{ z-(}^hE{Y<|qc0ug!M_Z0=fj)0;jR^2|I=4_@GpaGOU|Ssavt~Gb2puxbBM(TiO1vR ziP!k!kao=U(w>A;6+S`G=S->m2x_8{vUaqgHCop8hw4gl0+lIst@uL$L_-*=r_s!8 zyqb?qbN+c0` zf;LtuyZpo?^J?ieSP(_957$9X%t#n)4|I7uD+zT6Cq~h#9^M@z40t1|X z#vIlTHgW6nc4lAj036kUCk(1I%G1*kOS*Xvhm(K~$Dqm&u)X+K6q)ybQ_Iqk!_%_= zXJ-EY$=8lcy$Tbq3n209f@#qf&N}TxZn@!KtXLA4j z_meR!@)rE%kALQ*Wy=T(jnhszg`Hb=0FrNi?Q5KT`YEhmzn+(0d6|PT$ItM~2OglS ztBZI%&gwT;I}`9xizgoWJ!@94=FumfVDpwPnrcIA*|L@4;Q{{i*zdUTyz}Yq?j{fj zaNkdVLQtrDN>;2`fv!8-9G~#9eEB~}8Wx*3Z)WSdb#!%g5ekKP`st?$)kS#x@yF@i zyVsfI>H+S#?>;)`&gG(uFXrvdn+XJp#N%;x?cPNs65+->ZszsZUnign-d_0@!^6XT z{p;W0H^2D}Z>?B?l+H2Cn>&x&Z@+`)NFD3ftwRXG?;d=Rg$oyQ?m6ev+S6?J$v^#`V>;(@^(B`g zT(fH+5MaZGw`gf;;gcUdi)Qpw^y#DQ56`YhI>7qEVCn68<*myEF%vbRb%lAwek zE-Hd5#i=iHsqy#%fI`tJEGsGwZA>aANwPd1@CAeTy^0&B0MeF>*%H%C;jtxwYA3#; zpg12(Crz?Alu#|Gp(sJ8X0UCiJt_Ur3eWhzOGn`T-|vP`DhlkeZPGOWG5mHvBO?dc zlnR1&9A{p;oT?jpS#(`5yLxp{EKa|A8C$JQD76N(&t=^oyZHO7^`ym2=;^2U$c?~m z`1uAlTAgM1#$@`VYcPKo(qIWkUpfbRdQ?97u^af^pL)3A);Fk%e3ng{+IjVjHeP*m zHk*elX>z?86AK%XjOP7*Pr!hv2Ni~gdRRAM{ z2{$uFAQNfgiBanH2zn^Qz(5~&-~AJsY8^#IJRYZQMjHho$QZ`E0fY|qdcZL)x+ln?gb*uj7`CICQk)7oYAyRJW`?v1rHVEOi2!jv~3qn>;~2;prDkc zJ`TcIy6*=M8UalpL^XcEc2}K^;d*Q-8MAHDBPL_g(XWQXVf5-cOfxxw8YY~tb&Ycw z!0#-2T}`UMt7?7IL9Hw4ki46z@`D9E zmYVsAJ&8EfeD}T$ge-?9jeo9~B;or1wn>@XB&96F^+1%2?mj+t&WE|-^Iv7KcQ*@` zEF%($^76{n%9{Zis ze5Wm@O>4p0VP+T4zmTN?QvjedGjIu3S$dF-j$Za9AfN1h?IGdpVFx2#x6- zZRm<%`s|q$T-jEAeLZb$ZG7f4S0bg2ss=Dd4XRwN@bu};q@+o0Z2)OYrcG;N+qP}| z;ujk^9znpm7An)RBk3a4>x;Aa*-h1!ifd_t#stObVEv->rk|tBy zrn0lI7a^d!rUuKhm^!tAX-!e8-6ZuBmn~!M=5-u1?`V`rog=~U38ptSv1RjSB6W3T z46_gd(=yOhl?BHwVk|z2cR`?hE`0Nww{X;=xvsQKP+eV3Utb@K7A|1^?AdNMPlVa? zk7UD}Z}RQ0e3kui=eib)^rm=+f})5= zCYd|8jaOg)E8qR@zq4)ob^wNl_7japXq(o?#h?BJ>({O3qvxGTU2_8+9UZ*+=9?US z^di=*S;K9&-Nv)e{+*8Y1w^A$F^oi6p3xj_HRG}@4lb$(0~4%*4A0P_SYw=#Afm0)9LH)r>3#CT%6TJ zqZBNM6c>q3B^Dc`T6J_2B2^KcAtR2@ z${|D%k96dPA`&7cyQ!2q)oKfd5hE-mnRo?WwHc4BM~Go?hf;=-qtXqnl+r@z`lQSI zczE6TbwBG4L`wrUDNBAKwH#gv6|R@b%}-%G7&;-1a_*7G4Z!udLn&1akRyx`us_yE zwW^Xa9Jx=%FsRmb1`-ykgry4?a(8MuFaXs8-s)vc4})#+_S=21V>kb_oA~Z^7xUVS zf1#zdgV$GVDWfvP1aILu^{eC+QBVk?xO*gzqG9LV-#>4=E|H?U=cpL(TMCX`yyQ)> zZRz+@Y+3$y&a}zf(up8&GhhPlFm%K=0h?S}Qt%e3r~nTh@{}@DCMXChya)3ex=@b*| z*m&zn%>U|N`TmW+W!mp9B^qs^*uR0NZoPmDu6UmNm#^ifk4(WZVq|d0uA@?7#VtaS z2xvMCO~hV17#jyW?hN=2stF2~gM!zhQ@QA~UnKPPFS_RnWLyH_SR&1E!lGJrq>DZw z$Xf=WzOR|RggY;tdzQ2&gwhHQ2$h*9pT^v?PMaiOloHYw2%HARBSE+Whf-WXP^d`D zz{y!R0Tne6U@R`lU~#}Qxccg=`9EL!BKv##T`-5FYeyH6NCcrr-gj6#k!t6I!|{z$ zO7cj5lFVp)SkqKy;{g9Cko=z8D~gx)L&OGZXa#~`RV6PnUi#i=1|Oj9BhIcefhCf;C?7e%lqBqmQv%9iC5(TiZn z)ogn#gHt*?c4=@(*CS%0OsVW8G zXzYDfntAyLtTaM>wLTg*Vo%rnxpke}6xh zUw#FDc=S=OyY4!kdFENpI`cF%pTKe-4^>sM41=1+C|PV)zxgKDTy`1DmoF!gI>#Xo$R(BOZ@Y z6OED_Nm3B7eEB~(Zpk7C03ZamEwRibRZ1&UqEQ4eHatvKozA5fUdTg_KSEudv;7$v zNz&Olhd=z`35JYh`I_0iXFo@@wzA^&6-=EuvrG@OrNzGPK6Y&0%;IIsPy+#E&Y4_o z-nNY|ed%-T-o2Z=B}pcS$c$PvH%}pxbUX}|69V4OJmpk`BFI~#G|iYw|L}g!Z8?Qa zo7QsF%-IYMCa4cb*fN}?wY8OH%a)a2kD8`p7)f?)-prCEi--;Mk}=Zk+_{rmZ@q;( z@4S5L8yGh!Jo zghVnlJj}<=IF%JEUS`gs;|7rkEL^ydl`B^=dv*t1U0s}i{`vIw_VJzXe3!?b`U?dSW?n}f#;%=g zdi^Daj2s{P*xBss>7(Eiw6(Pnj~fUf@Q7mBGgGQLDqXLYWl2xO3#{q(%uxo^a+Z39mu%bIG9w}5=ALeMHK}U#_SZPUCL~;8FeXI!I~gG z+r}6%XlQIG2SGaZhT?8CoGnN?Z6aK6it74OD&5VBaQ_~)Qv{V@xsg*8g-R6m**2+E z3J(!2k_?w*bM|~Gy>r%*h6cn zOqpDDY!yE^?@AYm-N!*yr~YGW;O#IsSiL-Y{cM_B_VTkY&*3X~zR3T%>R$eS)mePw zQwwFf((sV76B=ph8pR5MBn@MIcDYX>jCnX#E{Oty5v`j#Rn+}n+jDWF9ZkO{3@rW z7nqhsS~|y4YOE&41Z0uasu7d`fCWPa0o4HZlg4Di{}Fvi#r$5pitQx8$^#dX~2&>@_Y97ZsYDB|Co3@ zPCV|INGGm-KB(l&ci1%7`Fkwh=QaT@(XPRjB)#VeRB)jqo&6Q*+XiBMR07Q{Wsi0^A zFM_-&%h@F*V_gOtk2(J0@t37pN?H2lp@IT785^oxG_A*Rz?GYkLfKetgMccjkX7vR zb7hvB8M`crv+eN{I*VPV(m1lZ914@kP>UF2hZsH#d$G|G@+xza~RN@7_#q$s{GIO2bw z#C7=388^RAreBHoMBsjqh66VT;DZ_OCpIY)Z{Agr2xIXW9UU_`^ORG#{PHVVx9&~G z;z>ZTWpfvc7cXYz%9ZSVdlRAhFvl;NOI@9guImgL2CAyl*49CHcNg2YZ{~pq9%g$_ z&!ooHtEz-_A0Ao3maSVcO^bD_R&nV^KMKI;(D0nN3w8XC$ZQd3l_{FqG_aTNmEmFLY9Pz;ucK0 zUdQ(ByE*mD9Hl&ta5&8N?Yq%+$2eRi6fDa?)0}g?v$GQk?Ax~wAq1cO!WVe>;fDZ0 zB9Wl2xtTp(-Ly}e#?Ic|EIaKijAR^LR|$v1y!6uRTzl3Js|u1ygN}~b7)Fv{ZHR`jgZ0#cH5kSyu{{GMlLph;+X?A9dDG;$g^PIX zv4@y<;u6x9MRRQ})vAVNndo5^+cw<{5l60j_Nk{brLK+xNv8>ojSNv+8^JW4Er-ts z86%CZXiRHt0bo|^%<%$BfMq3_-qgfEtk?a0Dj4jI(LQZHQ)jl&*XI!2Dp9BpMX1E4 zKCELH!_EdzO4{3J&^DzWO$gk%A9>THsi}$P<~meWbEtA^h`cEYiZBDi!(R=4L%OTamGN+8sDbENhf{ zJya&^4H*VOcX%Wli;PhuJ8F_KhVe*)=172y43X{|rBQV#L=KR^30khOVt8a2j|!@4 zGA#S>sy3?XBd?ASV;h>)O2#nU&r!)3j+s9zouKNV(BF6B>yc@^YJh_9k+;%74%9&T zHB*2IN%7KcN?k;-<%A4d)+qTh$U=4QtwxSqE=`@!q4$kg!}xqYhKw|7V+%zDepSaG zw@4=XfH=!KW-^ktDfkKujoSD_Sr#yZR8B$obYihCJeces9;R3)7%0#Xon zC3so)C>2E`Wsl&oAs7q-3RQ|At0?4Bjzp`vx*AV4j7hWHuqaB<<>XA8t zrDKS1Cb+(43(+&M_1eg;Z(;J1-e1R1*j& zG$QdOhftJScI2x#{?1L%l!f6Kk6l;Ihud3#Fktb*v%P#;wD7arPvq*8(|FVnU;6rM z{Ph?Ad_u*CBQsNR&Rwqn74e>i^sFw&k@mu=@k_&jmX@hR2$8f#9UFph z;3s**q7sExJyH%Ol~N)t%k{3SaQl5!LiqoX1|HEmrQz+=F?wq93A}gHfsYez` zNlC`AP+g>D&PY=eZ6xFVJz^Q8Uu#HQfN5lT%@si>{4u6EMt%_1WsNhjpd z1X&K_a`d-;_d=&>LHELEQ|eB#*e-@qA+L=4RZ29F>?Ar7peat`HRF+6UR5BZK+!|g z;7l4Kky;cZM8+7Ut*wo{u|6vF4h~>Y-PuSaP)h`zVWW?Os-V!;K|?%-M?#Izk*dJ! zPDZ@0oW%)}6J_F9X=Pd{--yHq+(5{8-K6}hb4a*3L{j1o2`Fp2olWO|uSxl@f3BF+ zpp=e#%!qUBu?v_#yPY5Y@OxC0=umU(n1AdEqd+zvl%fA z+B-S`_{j}Fqp7Kt`|f*yq?L9N&`~$BIz}WCb;BS{TI(B##d^8o+N-(Z^3U?EZ+*+1 zE;}Bj#J~X4rcGnZmd)i2)c*bZsjG{iX`=j?<}C}`mLw7}W;9P{Yw`yv=x!-(12g#UP^~TUH z+S+g@Q@?E=E;lBuzXgr62;^;U>K8ZRCE>IsP?}Iy{L&G2aA5Ho7goZ8gh<&W;v08{ z3J@x~0mSdnem?mnv1im|Ep|}MhsWw<&XwUzU zr`+dA`~;fYFDZK;I$v=i%1m*ri2&aRQu>5nSE4PR@!)+q94R`)j2bM*ATUxh0|YZb zhK$u~PQO1}N}FEzE{8l?EYw-!a$>>!-yiXYSb-jm-qH%@nNv%%!0t6q*v_N!%k%T` z#m01W5${uOUe1!}0RrV#EzsM3$?zLnl=(?qG{?qf+gUon(^^jeHzjP8O}vU%h^$r5&xdE&WR& zU#ZX5jJQDKBa@dD#vnD43j8FegD1_M4$0)&g*2CnVplevW)&{a&0E6$9d|W3)xN1J zw7D2dT7-;|jM54RgXS7zyuL(IBekZ=2YYLH{2}g0+DW->!uRD{w~IgTQ7%t2qZYVx z`u3?q@QMngoV(($Is<-5H^+G?^@^T(=hzf}rZYVGL?N znhvZ-psmamxGo}Vi5&CTJVcxQJ2C=) z^DTBZU;=`MUwa_hAMW-|RGm7gj>2_%3OnG)ATEmF*|84P;n2jgCrj~Iq0_VeB75E; z!-FRVm*q`YVL1a2{R?|!l@bnGuCiD@<>;$8^l#631mwwb6W2Su%+guH%t;<%%vd&~ zj1B%Tl%D=UojSCSt7tLOf}{S6RfkE(1}nCU9(T&}Rwl}!8aCN8mAtVcC9t^~w0xmz ze2Ile*;wi)JSds!5-zj@il?-V(P*LPUvVbvXtKsJkSD3LzI`9NmGm)@#VQolK2pYv zFV;T~j1NhMb^wLTLg6(V6+qEUI&jB1@=}|$FdcLrX*ezHao^sP_~seJAT^#|X#AaC z${k7wZZGHL`*e_g{G_GXY-a+eCk5#%!82)rmGXT^xswRoull4Vq}B4%RWG1YeQYD4 zDKm(E1FCz9PExC8Lzvxl*MYLX{APM9Q)QiBrd8Xi!aAZNBe0__md0-|-L>M5=`w{f zsKHzvt{j86#;!L*&oFcU_H-3q6e_m~fK8fOJODnX%(b-CJG=jyN3N6r@+WtBM(F_E zHGGn?G6_7n-##6N)n7X#Dh>ON>@N--v7&wSYtK39rLXsc@{@V>lv%DRcH8h#f-U^- zRhab1e-@(+MYG&s^bJpF!!4fRqH40{Gm)dUyr}ikc#YUjnhFuVUN0PAlBN#D zz-becN-1DJU0(LeQmy%Ur(206Rbrt?gM-F)Xk^UFn`qdOPMXCh9Sn1?O_ZWckuv5? z7-!v&TlV6ODhC(47qwHeSN2hPMU-d6Oo3mr07c9=4rrgJ^rG&GH z>%tsMaoqtqScTE8h99IACS6r4)}NH9G<=OH(py2-qLK-&hO-+QUEqwa79w91yjnpFOidd=cKTKpzH8wA;=mF1;dTW9Xkq07v)6BPv*wxnqUsY@c zReow{@4I%cZk@mL>5YA;rjg5|&*U+p>8{WAo|-W{Ef2p#(^2_#2Ftc#+pc>;D+qQ1 zZ7p@ygErf(wv@|D`~P&4$O9Wzxun>G@u$;`t=(T90a1o^2@1ZuTw!5h$7gXxX9yc~ zvoa;gSR3%h^KI7JqZ-^&sYn(Q|9(2As}?jIaNe2=Cs`vi-6$_ zi`>b;&#+@Z)e98!(_H{*NC@;;-wK-8DSBf(I~{V<1MttWq@KV)3SH+DDqyh=>Lpcy zJf)zneIVYpyYhtH6R>1UmjcgV4Y)Z&1@lVy?9D&nG#3>W?cZ{FZ1`~(MTmlYig`}a z?5uXiTDo(H_}p2k3{$)Ri54l{Sgqx;s?7-Ue=kY)y-8{TyKH|7oB4YGiRHpGbaWTW z<#56%;0mHRo0QOgJ4K_}7|-8nTOlZfngZ>xZ~87G@;S`tZ`PKrk-AIztZ7(u(!s=~y?xsW zHL?Grk@e)Kf*(`wZ?(6BEbm`BJ7LF;l8x|yPrP}X`!F*%cZ7SN2qRbY@tq~y+vn-2 zC~kIkR_OcE%F`G_m1cc*Y^+#xbhP40l$OhiNylxZN1fB2I10&T_$P637%N*_)3e3u zfxYVn0SrUa;`$j%klc87lpM{(+pS-M_q z(I0BwSVM;-Ab@&#xH>${s-;N4yR+g$ND)}|_~CQ)jOu?o&k`~G5)Y=*!=p<0>B2~C zG3U`GFC^W!!y1lqVdBp*Ro>EF6In!9@EveFz0o zeST~w=@9*vs5NU&esQMdI_UAZoMvzk%fdg!O#&Jk`}eWinnQQmKS`e^@jZuSyBh2^ zSoDE8dY5chF4z4j=WhmSUv}5iup(#3?fd?(vus!phC1 zbK2k_`#%;dS)d`oz{3P{aB|KrE{5%4&4lFZmv{VWYXgEJ#D5o{!{JXL3Kh#2jg{~H zDMj~)RoWxkZvK*XI}f<;Fb%r0e=X(4?%?bkv-|#ij`BRYjtj;M8E(0$;Un%B{#1L@ zE$EA`u<>Ls;OF+uBm*hfzKF!rGYF^TA7d8$Nu~JUi^(1#_EhC%mg|e;${W&(i0KBD zN?*yMYG~WpYBYspnX@wY#wAb((hut9r`%;N7iUXVeqWpYr4jod~aaoc`< z`ix#=pZQ2EyXiwh0vE_ADIp@M&qQx&upzluF2Y^ll0E8sUv4KrIZ#ky;51j~sw}yI zy~gtpD&MFQBmq)t{P{RT{1c7!bdt^U7=1y!FDIGO6B-R6<9QNcmvmn@2CDATpaBSk zUgjA+?wp^ChHkBht0Lqq-Ai50T6DL{3=J=VfxnfsK}CS9LbuW2GbAhDeTFmI=4Hz_ zovwCgkQHWu{l?v!udJ>ZoKNe#FO}p9JDOxJ>`~78Es|UU9P?7KL?ho2Z_h@9!Nk(U zS(d+F!rk1a{qQ!~Ys;DdKJeLk5fFTzeSn}UPRkYLuFL=v(wj|rpo2lVbLDrgr=p5> zi;#V8WTrw?SKhh8%hZI!1{|*^;ZBA5OxN5pg6zI&wbn&bAH1ThmWnJ$9Fu<&5Ng+t zu^LfYZBvDNi-uSzLrQnNpnvmNq5)?kG`4af6L11$<$mgLRkLqitA!?HOwGu z5ygNp+WFggMe8vMEoo?LW{bTxkfSN+_okbju1CWBlo}fRcim$GWK(7% z1alVO#4)iKG$;56zQhJAxTk^Cipc9;#fI-_Fxhddy9e*~Yd`#U!pBcK?tw{udod(E z&2#78PiDM0jN5M?o}c&N7HhY9(#^i|ERXv=Y)D8*L|bx5tJpBqFg)#`21s*M)|4pt z-x!<_5f~GuW5+0_7fjM^5KLI34ElWKh}mdIji1H^T?Iw0G~3aX2GqclE&sOplGpj> zPHzU?Tz&WDmqxAF98}Au_nDNWm0k{l@Y^Gey@{h^JT<%UCbRN{Ie>H?u4Qr62YmQP z3ea!57^0@>yW{6Q?$fMvf1t|3^H@_k5{}*+jH5%Ie)(br&+T$|tfaei@Gkdodo$ks za7(P}G7pfHp|}PEhm%=W_Vx#V?DlxHm^;tem~~rXaSeRyU)ww`oIvlVG{kXur# z`;`ndTxD#x-pMoL=!Y^7%cs%cLNm*g~Juuv>Y-Z}96f@ptH$Kl)P&QvoI zIr{xdDYybtJ}D(7y>zNAYTDxEAMTsE`djWST92DuP_JT!d?WC@1nvq@>kWH@Ztj!E zE4qE|PZy%2348C8vOhy$8?LMqnlIJZ729Ub8503|M^ZiGf7@|9K5^-B8&(w89uK2I zR|tEWd;JBfj^ZhOxT|+OC$8?N^7((fWN@E=DD;ww){LDU3Q=;S1}UoeMYkMDo(Ze! z>S(j%O|rd#3eGa84Gx8_Rq%fJ zV-#E>Qz29YGir6K{c{+TCsroZ%DJgF4&cviYP`7p{5oydnqxE>!_2hk%N5~d*%hb0 zjkbvu&Z>X^`{b}O-pC@~li8^0w&8sF)H3(DEx0IBW@@>7us;13Ch5bDf8xxVK-z2y z67)9zVUc$p7@8KO899q)4$c`)6X=F*xc%O^{J8dj(do|R>hZT%VPi63A4)}7F`ml{ ztEafZ#ym)p9ikj_(1JX{lrXtBP65|l4_Z=7;IG=Miu9JphHtB)+eYDsu9z*~p2AeW zrg|8O;9u64+(uGYY96L|HqZ0$=|C>j)a+rcfDiO^KQ2tVUK79$A4{4;QoMC);x22k zyegvd{7Fuo#IDbXepBSLbeicA6{dh1FrS7pt=~zP!!8quT%hLQR|pktZfR+BHKHkq z4=lBs$YD>bX?}tdArtN;{qHE)n;6P?b`DI3h-q%-k~e4wSvblOQ&GW8Xmzo&u_*$6 z-^N=+Xbn2gfco>{G}9gpA@1omf!E$!#6(6~1 zrTh)`Z*2l?S-1DkJ`)4V=ZrqM1;(r%>l9JpJ z;wA^H-w&jrNmFOUEhNh`*V)iB@9W=6eT}+ zUTW4WoTW|YMH(pm`wCYkH0V?AS(dSh_^K*|ABALXyM@^__*AgdEG0qGO3`}YgsZfpdHrn1%I`N9Os-#ntiymM-l{|?3I$loU ze~!1q8+b=~pV^BymRKh=2M2{+Qnji$IF_s!6|u*|VMDOz>6u+;A?_Vr!q3Q3GSrq? zz$Gj(g|>k|k9YuOKE=hu#WBz^MTKRqh~`Fg_=muh=tfeTf|^oS*!zdohUq%av1e1} z4(3r4ii)gCc)omJIk8dTkEXw*v=P!#2MdTizFLieF6`;g~pS6rmz5vg;M9XD$_4{qD4{&$gfrb)% z_r83T%shYR%#ck?^RP4FKra)(IOycw97zx@lErzcvN*@*Ae^u;6ym;yee5mxfScVE~4QzY{K58G-=LzOq)+ZXw5G5(+fBNl!OZb1AA#SL1Bg@Hgq(eME?=qg)@1@1P#?uwdfx*i5 zXcn;0u&7YCd!UR9=JfStb6O8oQ?)hgjez`$g9{^r~0d# z+e8*FMFzg{3VsxbYhIy|*%AnwB~B~z=p0$6LX=v;`E3rB#47QUNU67mn~89$`@7j; z^O@s50WRGA+=wHCh8#&7S9E3RgT5?>i)6atn211lj-$qNN$0T#R-nfV*WicQ3L(#o zh+Uo13HgQZ3ZuC6C>D4rhPKI7T2;knt>gV!zb)0{_JC!pSB`r_R6_&zcd3LK<3uK> z&7YUccD14}8f_fo4Lm-BDbc1dCl?n+lbI=Z_xCri&DGhR#zZxI5SLJ1-{eX(MZbG< zykI6?Ttanwd!tw~cRw!EPeowQY`{Q{_jlOz>rVM?1^>MzuhnP&?s4ZzxS}xD{B*8C z90<~=@r;D{j_Q0RI@x2mYT-F z#n_h-KT#4YtmsJSc6q`EDH$u166<4tC9Xy8?mC38K@&+U}iW< zg4Jvz2m=k{rG~HRG+{pXe})Q{i$+2+#B&2G2e>a}v7c9f9(-MJsnUtmmK-qbMyR)F z`*STgxL{sMO~;csvx)+bW4YcT51|2uPy&MsNnff{8rZpWkFH;vaes17nn};4JL*QR zeB;P#0ZM|b?FtRurDw{v#BB>*)btxgD+NrIRs6CV5yo; zT^dr{RG!K#XC5t5Gswg1*0+=oC*;xynKBUuQ+kW}r$(j;^htIPhf`Oh45J)VVB{(< zwWLl*EFkW67HZf{FLUB&ZB&rfEbUwBV3i|#k+79drkfC1Qkk;!#3BrWa(#4V66+L{ za;0ouVx7M-{fxj#+k~^5rG0>b8z4s)rU6`G!wfkf7 zgqMy%-j6bx8j=zNUzQ!ArnnP0>2DdX^^(D$oZq+a&?XGgGUen<#6mk_z$Pf)UZg;a zk(I}Z#)AvMZh^~mkT#*oP_LmUk0DVLzmj%zww{@lrQILS)${@9R<3v~vUbQFPU!## z=P~64l$?18IR;VsEBkMAHZLTN@l-ulX-N^QflNxRE{D;WBIgFkYH3A14UOhcC` zzETvsk>k6iSvacPug{bw>Z=dgxW{dy+lIu#WU_O2weA7*iU+)aHwr)NK?FgU3 zHV*>Ebto~^=P0^=R9!;^RjE!!UatL4E&Wb){RB_;Y*1(x$%ZU`(j?Cr9q<47ip|;rS&w^;~6w{LH+w}Js! ze|`UoZhKh^O_j}w;xHY&zjXJHr7(;mnxxpX^5Fop%5r4eP$Cl00h8tJ+F{z4Isza- zLbqk4eFmD=Tet9Gz1#ZF1jN;FQ~9W5fK?{cI(dB>xg36mL%`}_YIb| zO$>)w_otmscBB8dt+yfWKi7Ez|IxM(9L25+)NDLKW@d0F)(!3ElaXw&{23F9z=}au z({@UK+4j)Y@MUgfgp`Si$<^Jx!E9W;kVy&XVguWLh)$tx$FZ?}+X2oYvu0%S%$&=Q zni}R(3ZPUjsAY*gQ;#2SJwVECN}sazdCO znJh~kY-Gv7k>1g9i)}sgb2$9dXsClXW)THW6d%s@>L&5?%S*i-q8>NvsgSEP1wL70JK(6tYB+v zyYJW$4lIggom>G^$8*q>VDEuRRl6T~;M2F+*H)j{coLOp-zUQm-~9jHAAVY6G1rG^?hD@856g zPyJ>h93~@-t=qqw1DVV!3%p*(vD+-#p08JcU^b<+@b-S-!<(#)F>7TecKLnF_PJbH zziwT7ni;lN`qvwSp1ai?(_+8e^WG(ZPvZMAdJjYnJ$qSNVy=)N>+tzyhJk0 z>4eTDedV@S#^pLQv`G}|%hcK7iJZ=fEhbhKkBNE^T|ziYsCoFE3mS4Ai+uqn!YR38 zLfZQl^&8I*%se|M7;C*Ecn*$Aq+sh}wrO+%WNkRd@;m+z1Hotz3TJE>H6dgHsb~CT z=_k&TD%>$o8ru;0`H;*?XllR7(PZlK`+X!*mB(G5-(}Xqv(xf_5ag4jiApLe;D<*m zv$416%Bg8G996enI|c1B90^N9NU>H;mPS4jv}HfcF{n`csjgVfG+V zoSj8TsPA5+7st%FZT(N#p&uYf=Y`1Ai?(C*BxyRl2D^|Nm2grsD_8d^Vd=-~&IdH` zj^&m;d4jbp`$)n7RDvWTV!H+ascT0LBA`%XbkXXk_Cjwg#nUq78|z{D!ZMk?F^z{I zM~G(6t?6XMb4|H?zWaBvA39*eks&>8xkjM&?3+1(H_la4LZ5Hannd+o(9aVf@J-v-+>Km-$&%(-Ecw`BUtaot2 zq7+I?H}yPva8L*&(I+s#jOsv)Cgy7M2bFarol zy{wbSKlTU8#M$~+F5?`i1Wwmu)ibmD8MQmoFRARZH_^pVp^ndWgV1<^4NE!HlV^fw zf$_{*Luzsvs3O@i_JIypyA;7#Lt?JQ`_a*R+X9h~TmN{UF2dUlNzpRt;2={7l0Obfg~HWt#8 zNMjO2B=G!NT}mM;Y{)Qn(|KaL=y8=2ks?5_Q-=M1{!QDUE?t^ zWvzl94YS!7t9H_Js0BFo`Nrr%x&SkNZ!d*eq#biwe}iptS$S59|13TjIhOF;0-OSe zeBLoxp48s}mTlt#_*!b>D_~Ekcii#Ch=AJI(3^jL&ISOQ!zsJM?(T5I9!gs{Muy(6 zd~$$b+PWn;{A!7`c1gjR%$UbLxC^Dsi$r+5myO6pztlv;r`7FF6cd9Udt_TB8x|X@ z?tZy0MY^aYK3P>jR(Pvp85_28J)w{Et=v_sl|xyY;7bbrcM}te4B0SU=HcQqAnGn1 zOpCi;kdHBWG{?0NHkOPBn2>SI3J zp~3mU>+az}>GS!6`Q_91d`HOEU*X1EfDu$E)e`-Eo~GDDcM z;Rt$f!=7*cjvKtVP{k*66=9)x+4FRew1^oFXPtzRZS3W~j_+uDL9OC`UoGTQxP4H-Th4$r3>y1qlFcf*`XXb9@K z_)0}Nyzxq+G`_|2t8f?j9||gPkd82Y-21(pLVT|bm|Gc9CcP20mdsYGKPh~dl=unf z0 z`mcSSyqu=@rA8p8n23e|5v`6WUo5EO^;H3p*zJVTr4weg zlOVEF;j5kC)Ka%MlYAk`bmd>aoIL@t@>Q0Jtok& z+FBAAG5dAsbe|#fra7|7MJ9SB_u#9?10Loie_Y+qs@}}QyMD|6ev&vIv7Ibi?y7d>ws|VZ zO3d22O*PxRa0oW8C3lH73mnpf>ypxGn^Sn8^yCH zB!HFl%ASOI?jIN2v|Fz$?!FLAqo!6tQ$_y5Q1zyVqd$rZrXg~Br`s20P+0<7$(-0X zfUJFs&nyiDQ&Y%rqLfLj9v$*(2fK}uZkE>R4-5p}U++tJ2Hm>e%tj9#N`n<6*h=oS zFwF>-^Q`6N?GA@OY>QllC5m7x;Y0g@I%#uc@+v^^3zx0o{i)menn!#%iT|JV;_@L8 z3w4g5vsI+Ka>f|I4wk85;F(L!-uHZe_ExxcgUjeQbcTIE?l`hko$Of^6GJ^580UXi z^m>yZ0T-I(^|u%H?OuG_3nfnAnRcry0JFB^)fxZyH9x1Z1Hf_4Y1*I_gXxTKc`Y3r zXj0@8=FE%XCl5JwEEmoK3=ceFE2x8%$*`ogJcJG+lP{q4Cdb$i(e&(*@ z$&O|Z*tVL;05Yh~&T#nfFL?M;iX{v!O#MeROWYi+JUqa;5KdWor~`5~l{SixmxqnD zr(9t#ii8)brzlQfXnjb$1OlGx1}xKk)VyZTM`oLbv7~mT2Iwggu}I1`^s^;196>@! z3Vx?5>kn@ZFQIt@PR<=?kqmz<_h3*6kHw@%>pda)()K16Z0c{jx*Cq1AO9Lzqcyd( z-0qvi6`n1O5iF^w|K4#-Hb9NG`B92_JZ9K2}QYlV(C^XIrz z@Nf~Aru7n+&i|&L(w}D)zVer1Q-8cZ7$>rOx4hJTsKE87x0kW@gT%v<#WD7MlJcKl zcb|mu{B?t&SSEiE_vre=tknzcANL+;QU>ALSgdOzXsH#uySidnMUz%894(+<=F88` zBD>*d|_~Xh#tgT?nDToaq|~#xOTi$swMcN;OA>0y2b?LOq!+B23T02v5OxrO{8u~^Y# zf&<}#y_1Sqv4|Tl-%f}RnlN^WPWaZn8|I-q)Nu$SZ(~P8tdJ<7OrnlSsDwPB1d&z} z-Ga#&*R8uHN{+59B4QR?0OatKqR|GFD!*UA&;%r+I>3Au?MrZ`7EjTi%v!7g7XB9` zlCDcT-aQSd3wf-ziqrLXalh~|v?l5QjK!kR;IvOxL;mla=k#FTYN zlvP}x9q*oUgK5v!{~U4scHv|2)$#`@0j?B((2b$)0u%Bqqp%`lZ?p0TDF&C+0n>NI zFZ1|BN>Pq}CQutcT4ShZQ-9tBa=Q|sL6vy>1*966?HDYNDKFph-{=Pl7kn=`R&oA1BQemAc-OMo;h~>g!LSsX!(PGshK(Eh2 zsv9K>&yrnX&qI<&VMU4Exb(T#NbWAn_A+gaXSVaCDP`E5 zhD5qa-rbMec%n=#3F)e?uFmdqr89Wx!(IO4RAk`Wy8bbjM}81Oz<1=_^;2QSG;<%uKdUuW4^f5)92yhU?hR!PYtD=7NGyY0Q(r+QY9C;+=OF>squHD|0R25}`7 z!e$l>QkOf*j!WMTu;d!9G?)Qs=5`x%CK{j{_2+o_r^v9hhV+X#S))M(3jy#a z*?&K-dWtsmq~-TbbDpP5Su5=paaW5p<4MyB0jKOh`r6t`qetykUkSDPe~ZbdRt&y9_B$Ij(X-X9(IFIZniLA|+` z%R&>j7*DOP(rSbugF+Q}=c!-j7yhq@p6$usYgLb8jmG~m;ga2L^tmWPNPqL5p6CK- zLjxH%N_y}a+so&%s0nT_mWxKr7a{9j9Ze6Un~AN292R?F8jeGPZ=w;H)4IKg_(`z2 z0tmtqrFz5@SQ+ki-rPBeLoDChULRHZ`EN=f;GWM+M(&mbJF^M&z25>Vqw*mj?& z39x}DdnCk`RtRR06G+}mD|DZpH?@ABKAqv%;WjH=pHKcVr(F8Q(!aMdgGfc-K=uaAci25fskR=xKd~mhl}nrApYY0VcV#Bv zidxH3n^Mw;wpGA+vyC$h>G11gJgXhmB5Y(+Ju!yarvEv}3y{uTI8yKR_cs+BsUK1h z8tk{^Xpyu=g+|KKjWqme>nzfVL+e+q>h#0zxQmf08 zn&V`rI+^jxMGME2+tKl7Z^YfNqaVAWGyy%8HSF`DCu=qEUoU)=5lJAb^J^V`KFykI zPku_P;f?tK%#L#*+Ju}zX+BtG`lsu&?N)ixS zHMpY`X$Oj3gf;fmF4;H!&jRp_jatsTjX!-;hJ^KjSnx7%ds18XS?cVn_4xb|(AKHc zsNC?0QOUZ}Hwjj37_87h%Lwu-|4>K{&HdnR0VS|bP8#t7!>syA{@~M5=``D#`CH)D zFo5jK0HL63`h-E<@j3Fc;a9j-CKM!uwH%NiIGy9MDdO=UUDNqbdx){UN`elQM*Fq$ zuB;u5dm&V!nsrgkqApjamK3lPio4r}lJ~KTYh{b%`1tn>D6#+fz3`k>H9msVx}i9;_j@718`lJ`OK;Suxx2L>kScS5`#KrL z=iz+Mxm4$V!5apq!-(K;6SkNx5CK-p*yb8$YQk`%@tdqN4gmEh=UfP z)Bp%?;a-;@5^T-pbR6#-t=;7d-Dc0q#@1I~K;~@_kmCmQQ%~B8Rp?MIPlT4-lq*bh z{q7fhw}-xfd>_%Aje|^rDLA0Nv;sM%t;g#wE58G{>opmG?PAt4c^U{hOD~l&A5fmJ zQB8F_n>y$l-;{N@GKyVe9=;%#2#59DTF`KLx%e2<MAP z`k!H7jii~K20Ze5NXwvJL+NCi{&jp;lYaO=DY1FlH*shP?xd+OuS8kmzdP`HS!0%f zi}CbDqoV?)1)Q)$FoJcA6*Z#OH0FRwOyHZ?H@mC&iMcJP`ti$fAC!wkRefo?EN8}ZtZAt zfdyWJZx-&gq$$!yB}}569Fw_|m2NgXA62(_#KhvLs_eA4Q3XO$1`Mo zJ8<347Y<&>1>uUz@|Y)0nKjtiklY)tpEWw~FPfT?bz4>O4h=GoQ=|D0C9?duS0#4EBIOTyF}f6d|MBDxxrYoQEWpNhp!1AxpP@q7CI35t1v`X3G5_Zo$>|w9f^(llXB4}?z|M#4 zb80;eqnS(-SQ=;qu+Px-xR6pUB)BY`Wn!vfmQ@E^6Hrpd_c!0lhEq`LN&)GV5LVl~ z%r$$7ZqAjnZnnBK;X1CPKFnD2ZJ460bWP6vtkmBSL}T9zDrr7FEP=jhoBC{(XXCQfMx+AFEz>~L$Kra8QU*;ynq|tQ%x#@ebrUk5j*>3;v2M*;hz_3zf zjd+mOcn57UHh*?1IXO;=A?P5~93<&_)wG1{oeFh7J~*e!5!14#X1fX+x=Q!YSJ&5N znJx09-<|^;Z|Rg09G4{|jhrO-#J^6LeVmYZeH@&zZurN7P}yoO3>UI+99Q_Zf;f&E zTbWv6d$J)tT*%;b{;37tA)VU4n zKW703^6q~*g$r|y<(+jgJ07kCgp#~aKKqm||9i!gcz{ippDqH>gau8Zm?}g1hk!pm zw~t(7d~qLkd4Uf9rKQkT$2k3oUj_^#EnRi{Q#9rX~>VA5HU?~GG| zCCL+Lhw1{GjKr{t)pGe`1ynXwuB*@+TL*?Uz8LnN2nB2ngaCDZX;*Gr`%wf-1F z+#YcU{Gi_Z=$;(AE2R?Q97zFbc|QCd@Ya1{|w8k&tpNh zr0Wj~{2p(~A;d#?SdFZc0CqChJ}phyixgrSFRZHr2ICkxmux4>boFsAt@k8SF#usT zS--ibWt)ghOa9iKP;a4t zTLdmPpR(oU<+TI=iH&NVztQR{m$HH0 zB*ZvK;=gn_@R==rWvSA!$_nsbrvr8{a{W%IT=i&DWYLN648^tZcN~8J9=LeGzgg#? zff^A)k@^oICN>r&Gb?LlzAN-=KF|IzVVW&~tG9XM05tM@0T5|hV?4gd1SEqgYk!Lp zB@eXHp2*=#Thd?K)@6xgA4LfZ!h(j3{n4ptCYlLXpsb=I0?2wh;lz87dkWvBlL`vR z=tZyrJLRUGgT>`~Yq2s6rg7x+GmQSmpIP|7>uU;XYMg+c?=l4nkFoo*vfP|-bAy0V z%4jZ&=*$s@X_=Y&+huy0l*L|upf@??cRv?Wuox4Qs)mNeh49CLfjWDl<0aFN?}}x$ z48k^N2yJa`=~~#-8ms4VNX9Z*|IO~GE(+e02NACUb4bkCfk73v8*S*_r7nFDG;K9; zkhO;gyHPBqU9IS9YFaO2hyV)o;7^dJ9(~lI;IOmqaZ;6YT;2p1E_3~hH(~${7C9MJ1UmzeL5x(WNJgAK~oWNaFjYw}pZ$gnMN7>H>{!D+pSEsg9 zj8w5N`Rf$Of=fuUN5|@Y);+#(Rjng9P*10iPXwWZ4Wgd3#rKV|Mo$e&FRtNvPR{qa z5wV~PDg*(%?Lw0$W!5kIey|qjyc4&08#UZ6;DcQ5V^#ogT{K!n$Z0?;sXYcD=A|&pfbe3r$BE*9%z(Zi2=^fwP6`XH&*c>`L!vrFyNpbqh z=L557aJ*GnWpSB0h2?aH%+_{S$Wqh3)OWx{zfHekvsqRx1itXyR z3&i?rj3k}AKd5L1mjG!P2F)*r+l^!})|UjQ#k74bAX;^wa3x@Lq|*2^)3Bn=(ot&t z;3w!Sm`XO_LqlZ@#^Hse43AGkS~5Y1rVukYZB?RlmArzCaM1z=@U|Al*!SxsnSqFb zC%vcYk=COZ{R*LP1sjUJX~kwJY!+%t#Xn3WXjHzJYmc98_{YHI;_Ok|!rDCHFoT$|X| zrW1NTM`mZAYv+mh>e7c?t@b%bFTegvYN#CK&+VPX^;>qSB>|~gSa^7Y?Uv9l<&mW- z6me@St3S+0GBQ^WT@TFz1oIEp=#l9DcVm`X@B1PO{1=jX9w!)j zj(a)2j|-CATfNZ{CEhdN&>kBCf9E9YxjznMJ1LWkQ$98EV;`w_nYFNeIl_E-k=)o@ zQ?<;G^h^2B_s?lxJs@gu5bNvHKgJh}SKB2QESH5}=bOF6FF`z(If{8$+s&Ra2?isr zsej58SgPdq0)6}yYUJ9oS6b$hn(kPEsjTSQSi?P5R{@cp!(KUNwf)D_%OSd#_wHi%*f#i{Z~>vH zzDxwTd<;|?4VCuR-Z?x1bpsDMENdL6Av!3{xCZd1vbkaT1R+iT%O`VhYsy(Qus~F!g zB5U1tj{+%8Ppgv69MuWn#Y_Fb=i}|UvzN}(P!TyWmR@wyE*3bKLnWfFj@8uUJne|S zmSeh-?fHZ|x3JJ)x7wiw8+<-m zk@9A=95Gqwc~b|)zQio? zvyK_5W12}aCFM1_v4(CmNkfDltf{G~Qhadh2jsQ2#1?AD{5y)io>#_0;Bvk|?Vg?5y2XqHS$15ku`kE75%m9sZ zVh7MyFH33-M$#B{6F31mGfT$WRKwm_=IUJkpFbaZjBqhZ#ihM)sq=hUU9#{FPfo~z zY!pqdECHW8$CaalI-9+J0FWBo-p(5pEK*rnsWrC}rBm*Vnw6=Zn)38IH$M;LX*dJ- z`oG6)x9YaG%+gXS8ClsGb`j=7iUj&7BN1DANp|*DHEc;W9StlafS|&lI~QdQ9{)+_ z##-GEN;mXn!ANs$mcJf>)2PuKC=+r)2^Gu{&5K8~X1y4;Kxqd8fZ*BIxjG+e@KaS!Pfl4_5=k|d1B1h6B~~;&Mi$TZOt{y>DQZBMa|E$IH--vgin`NP6@v`)m+h4(ZYU=yS+DRF@t!6CbAT;e(nDJXZv8I(d9g;P?*IUnq9-PN>)Qga@$lO`N6-ZqTO-&s zF&#$>KZ2{G&_oa7d~$bNI{amIG^Ha!JT1?;r{gE1ec|d+`$#%YKZ9M?pV<|!w`V%x z3leSl@Ti8YWzE9V*w%DNga1fj&p0}-zJS6-CuQM7`6mz}#+%L4R5UivZN+O^#Cha` zt4Km5EG^@s{RbOrYH;aIx`jffu$^xjz~FV=*_u1d@5QCYh{!O3mh94r3H?4E&g&eS zqDa5rUe|rk!&f&S;Tfw{U(Ub-a&Bcg`TtVIr<+n7{7z7QyX>(F2FzB}dElIW6?|{J z=Dte7tn(pw@(}LcWzu!2u&?|R^LtPZ3K~k@oWj^lUhS!)W4YOsT#~VzI%j2|*oLI? zb7Fh^A~}LW$8iVHDtJxV4wf&Q+vMDxp&;$|QlgTUn7_teC)>ZEl75Gr%(yFY#p(U`c8F#6A zSQ7_7rOwQlA(<0Mq(EMfzLb@zc4sRwZdt%{yHc^pCp;^2(S@%UCxtB?-qV>^b+7a6=d?+tIRFT(uK{ZTNfs+5O@xp0=g&L#YnTI4C;c>st zi)7HwLuf)I&3RE@(dG4a!{YHOG-XkvVSCr*VKI+iuIIGT)7((#)|_!EhNMJ370;NW z9wlB!oCQy?;s=01S*=o z8!~#DM#qfpJisATESE7?#Tyoliur-3r7=MvBgu6Z2y$UwqcZiKqnbK-P1xV*u14XY*$cFn3Uv{N|rNO z<=iQX`(5%Olx$$Eb;KBcEQC^;0*OIZMPEORjGZJ-k`X%S`^DO^fkCB@a=?SBH>v+{ zr2R3o-OLayf_PXQ#h1@euf=o2M^pElY?%mV`hBihO7l zPqlD~EzHeiLFW>Yz}y2lIL2rbIf;9B)#J}B>?yDn4SeX7#xjUEA26aY2f27U}$V3n~)@V%%4ioqA;M%D)g*;j)3e8VM#6&Zl0n8}Lmo0IXNY^`ic%zM zj+CmWOG+$~yKm|+S0LTh<-*rv!~+-W#6B^#xrw?{Ns<($3ZfCC!4rKDMx=1u`~ww& z+K+({=0wxmK`sW*f>C=36z@`86;aJak``pPUP?K{SY=wARJy6!faIhrXSHUeX@Wq; zBsY8mv*m^XP~nFpQe0}usUl$}3yD_f+B#Y^z@wGcYwLrTaaNckY0Fn!P0Br*2Qw5} zsKZmHA6J>yrY(*)9T#q z_%tn)O?rn_#eEw&wSM6Js{WOM88)xJn)^JoAEkkhD*V zN_=`AmU4+Ho98v|0MbS#sp4SG;2H?D~OUf`uEmXB(VY`D*~R}U`cr=VT7Qr z1T0zB3iv_h;bwKJ)R^1ODGnl*e@nf${OJ9d6SOFMG%W-ZD(xoqI4!PL+G3?6A++mZ z10x!$Af}d-;$&JlLQX>C4r?muG8Kh?6>Wt+)*bRKy%EuWK~FFCe_YX5i6+2rF;dBT znFuZJ1}}=s+Qpzfqk!H$J!92FsES}^ZGeo6JaFQ1d(oz!bKxsy%XBVC&`}duh zGR;r4p8n*Nl5n0^nq@4;;v-+wlw$_y5QJJyV41^1H=gi447y|R;~B%c8r$9nV_)tT zmie!rcX&Lu4B{9zCg=o0S+gb7`(lvzd@xFb(BY@^B3L^bQfw7?(jD|zqqjVx3LCHx z{S0O$FxBVFTpleQ@=J>|eAD4sN_EFU#*^I-Sp;rx>M^jkUjNP%N<*;Kt4R}aEOULc zXGosbPzKa7 zVOrOc7G2X#6f^{3n+`=aFOIR<{E(-=Jl=T!1`Zk(r3&55cij6TxOHrogJ-g9$|7Zk z)kBbq6^eeP$5?5XrA@(h(f3p5TByPC`H)LR>8EP`$wTOF?&`(*>n-ZM5FDtxi1gs9q>l*6;DGnPBGz>C+?5 zejaTgn~>VsIRgwP8+t`#KKi%mWDO6)z1>`YuM|Hk4Y}p^pu%tCW@c_7ulc1f@;ccLNQ)aZYlCC$`kHXTt8Ke2hA=P6{Vs?enLtk& z9ITARBp7u)#s8^K3Jsnc9I0)COQf!Zi=wKgHy)A#Y)PWVn7U)k$KovJE7d=ID*~b< zNh@niv{B4|3Tuuyl$)Iy`k+x#W~8O}Clt3d#jWS)PR|h(GguBc(cGraEb&H5$r#(8 zsGwx9{9S7g4sFO(4_y3jf#WbE`|9dy z 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

H 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 z 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�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 z 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

X6eai$Fvj zpdbVlQ#~mKlU5NgK^hQ5)KNx~1Asy_+QwT+%egtCB1c-8s0y_lmC6d1G?KJvDw@_n z+Agrkkb+>ubd)i3$ZO0 z*x69ZQ^`a%P%ZC%;J(w1&_>GgyFmnP6FmQOl9l)SdukQ4#5Rda?RB0~{@OXJYN`r0 zwZ7CLrXZ&q2iWhdFY)N2Q+Zn^*%D7tA5|&J3b)09v3f15DsK#GH6flZ2JlW`YX9KC zWEVkKCBUn^uTk@JU%!`6e(5Hd_aWF+m(b4PoeA#=PL$ z6p*Y-HuJI5?}XX=LdU_dMR42+e`MuDU!Wu`mYsZqBfUFf(YfLf0;(U6fI>1)Fxo|) zBza(y=4aB{LdcRV)4Ir815AiAS3WYxHMeetp)3d!R+KS*cr2b&62E^A;j{i5-YUX~ z!Tk9%$;GnNYbs@-qst~HjFogn%l!VQhx5swz6xeL*ZgcH5C$xWm|%xtk2taCevOAb z!$t5}l2xmM?Ei0f!d}Nf=2>{KpBqj;kTX~G&}YEh%btg~f{@k`<^U-ew&2dq9=8|UUPZRd{bF6D)1PEtubTy@*S{Q91GIPppznjEEj>z{Gu4G%zZ9++jv z?;hfVzY$D*;xeW^xcKI~DI7?`lm*>W2%#BOkPv#=lPa1hhHeIiwgeXHmC?=L7qQS! z*P5eQVSV`HuaC{)mueuXi~1AUQ4c)w@p^55% zxnS9~wgh&Fs5I&r-}jqzGAET>LcvQWlUSA@2()QffSwaiq`$wP?7saBj~`^ZP#_LO zEsIVo5mL=GZBin_y`mpTwTp&gcH_ z8qUAs6l^?v4MJ#Q@qiud0lmhYQ!Hj`MfNc&@~% zOqw}Q(=H@RSDG1t2?0o><8719F@XZtahUS5R6T{`I5bAGVY-8C|IVL zt05@_8e8q9plpP25Tcu^R(M{8gs@oO?NS#D2un~G))Kms?;A>(owAz^$=VHun$^?O zLvDPU*&rbA7wBKpPnYOvx|&oi(`?mzlZk@0m^wR0V48vELZGqj6uw`;PNk?63M6}s z2BrgxS?$waTui!8rBVnXSiO3+Y4Ge6Q&R`AEIUMSEDFBQ!NNfjiA3{r8^#2cqCyCp zTyEMlVcJ^aWMUq6nke0o#EdJwZ#J2Q!>L8WoM%I$Qpcq9RvXl_Bc?A~G&1ae@2y+^ z|A4?88%bFyjBY8_OCM(gcVt>x16psaJwgZ=_jve@uhRapmr&N4PA6u9K~;sQP|f4e z0HH0Slp=JCJMzMKytboHb)wpSjNflR#%DDqp^e|`PY?3)zx*~Np8;|^T)hQ8tJyn# z3fFvXoRN>+YXsr_3v51NKX={w66yk8f9DU3h+F)Mn?L*p-v9SMg%dB~+?yT-MxodT zQ;Ijd>s+q;i<1~186hnMa(#x;Tox$>Y2i{r)8XDeGcN!DAOJ~3K~#VvT;_5f>5Rhz zp5XR>_#Om9=Cf@Few^hpe#6^da~aoOaT9EP2^6;TvTL?buhf{)HQHnxtrQWRro(X= z_B2;*P4m6mUe5FX{Q;PUfr)@IVw`l6!|Tq!hzp;YAXX_cBVb+~;Pee!h+O#3aKekh ze*$n}zs2=${yO>3ypDIh_ruVA2|W1-16QPZ-PNb?t@~%V>z+yTte@(DcH#S3E|WiC z+i7v`_}hEom1f6JABCJt&)0tk-^_zbfXs2y)dSr7+RG?C`VgI&i&*eR zj(I;-IkMiNQJ6QT>D8xLFdrKM{6pwY0x6GgeLU9rAH6x!ErSu=vOWp4q)7!6A_g*s z&#!Z7P+*q8#q+)=~;s5Re-` zNX$;)`(-M{0@X${qyu7h;;?(&3bWs)rl#4qZy%juL$WGmGw*9=X3D6bVm`Y!&5SpK zkPe+R?5uE9nf)g`_ljamMA;{JW6Lk;x1)ABKw` z^@(#9P|71E9Xgy0xm=EdG7ZbTQpAPRG^-Jg4qfdUW*CA=jCs_&)^vo!Vb?XtPC?~J zVwhK58cKk!nP;u4kFQB-FeZ+rKaRE1Xc~}BBOvX!zuk`YxX(4$Tx|-(@WRzGBDhwc zq_If2;*JUB3Ohv=R!}Cg{ zWEW*!YZ1^}&1R(u87YsH6pVQl>`brGplE2*hW6Ah)`octjYY+vG$k};&rs3Yk@%j+ zs!ZCzW8pbgG;|>hqGC&2H_h-!mNo?a=?r`GIZ~lLYH>PCGATJUog>}nGFS9SBB&+1 zQ9e|VM2R#f$XaVun0Q|o4F`;%h4-fciy$x$ZaigEC=^MhdKe!cr>Ccflr6BVH4Gmd zr_-{qlQ!ey8N!fh#(Lma?}mHE*6eC@jG5*d~h ztxcHL$3ICt+(j*PWow4GElzaUH)_IC<8e@Cjj3uA^w{f)X24@rz?|oqA&hp68{x9U zY30e*pF-*NR3_HTxw!4i7WAWWb=$+^stbsR4NFl8qkFRy+duF(Y)Naru(rVUZ~G1- z|1t!rwP0`OSMT{t&fl<#sh#`qH=oFFiXNmY?796NbfzERZFgLWbIwZ2c}K8cxU3z^vcYlL z`^F*q0l#(%#dH@{JcjaR{7MI%bTR6Uabhn#F*XTe6R0f3f9=B&TZr87CFtJ5yKdbN z{^byC=NotY6<2NU;God_+ar5{ZZ3OuCwKn!DeT!Px$L^1!LI~&{6rh8(i0wM`;8Z} zCEdkOcMA|}!T$l(FTRAabcUgA-+=z}c-!CJ3!D#0#W&wvV(ZomSfkD z0^54id}Yh&yy_iyz`uCF5Xb}k<$F%&!y7iRX7@eIY7(*=XON*4RMc1!IG5gYC zL3_)jvejg!zN~3E*7|kKMq~xI&nicIPdw#DK!I5<;hug$2&3bYi2hZ~;C=V&) zNFkd;Fr!h?P3z}6jbusdxYx(JSXg0bb}W11#g|eF*X?4iqT$h9klN2|F2$;NH^qu) zeDqt^nrf?_Go*oe%RbXg^_9`7SSzn$K>#9bOxCP1dX!?ZK(eO?+qR89B`mt_7DT1q zf~s@?mYry>rJW?0OBvc#I~Fn91XdeMVzc))MD-2S#n%Bb2m_}f-eg`_OK4|WYYK%z z6M1P2(F1Len@Rv}K|rTv5zK3}4ybxHrkS8!!@L)vs4Db0KF`{+jvxNx8N@fgoYi?r z-P=h(k)r6PS7s1imWt3!r_*@6oFPXuGP0AJH-Y7zPfXdMVsz-W;15$_RrB6&=qxqH zyr-(Nv}3}ID_T=lI{bdZS{co}Rv?WPc3vym9f$qdJP8p;tfYkEN)*dRPawWu~QHv0Q5)KuuX_pRFjEm;HQemTIo{g9glynV*OIE zV@(`}tZ31^Us}&AR;wwrwvjSJO&X1b)+TK3&aZz0rOc$eIaN>wwu*;3lQtonRevD~_FI<$a;K+2-J2@o@#q}y|a=P%)q@=@aE{_m# zq%mUj98m%5my3yW&#civbW7PJw}S44(M zl_TK@JTKc!q}KuxGDg8uVB4UlDX0n}CTNdIa``N>%fYKD1e)~5L0gq{SnlfU!YABi$A{C11 z0wbgfZ|s_{2}D55wy|h<$QyT$WGcmMP{#LtVs-)n6bgsfeEwz*?RlItFL(x8YxW)3 zONS$w&Upr{5|R!ljv$5*ikJ|Wi0cC{LAHH~N5G?PZRM5s}!E6*fD_qZTj7IcNA78JBGqUe>1vX&rp zbL!M41u~pe6~YiI@yGNPSm9fbEic^k(qd|U1xn1)+Hr9`XzleH!{Kt*C|GNuXMv4r zsO=u%_=h7QmL=d(G*{k^A|pOE2Qq zJN5z7pe4`SG|e4vd;zh_7?Is`I-67Ggd_V>S+FQv2kOZP0j)flSy{a3&p$PqAf(6Ei8EO!IxacO}GCX^e|^$81P>o zx`F!GB&9LQnt=trr=~%`NB;Z_*6bXnYx4%^_f3L)Fv6Gqx{YlweGZRJI^+S*I|#)C z@apr3bPcl3tMJ;(HuJ@MJ;32g_X)oK_UDrCa_HH;3)XFhlg@<4f5^73%a|y^m0LYX z_CesV#+qQ??JuVy@(fQ_C<)2QZj4iRMW|;cNQm{!WJ?52k(v}t<|3Tx43O}~D5xj+ z>^FYK%ddYoZ8AneD5Ba3Vyjx>q>Jnwi_qb$ryGc>EOnvDYqO`%c}WHb)8ula;eF=- zl7gzxCgZe+W$sFicXcJikELSz`X5TB)JJce8k)+2GK0%%OOe&u3@jE*4f>~UQiu~m zfYf1dG&qjLL54}?0;OuS6M?4TP=%-#w8_{}I3;GVXe^NrUmxm1A2Cd_^|%dsYLi#H zV6zL~{RxLk7t`IPY14vusP)q|Kxpcr$hj(v{cQuJXo%}YV}c#(L>tsWj7K=#e z(4}pG@WJ;BbXq3I1g)twg!5tn-`7o(oYo}xuAUw$#Ue9)x!HVZZJLsH%QV=&Uk)$T z;@#1to`*V;XrL(sg{HIEyzf)DEINf?Hl)4VVW72b+fAC1`FDb1p@3!CR06+w|J3Gd z&1;=e{Zx@a5iM#|M3I^&`O%N|bGlefjXYiCs0){}b{O+U8PJ*<8Ge2LBW(Nh1AO9d zPUgDvVw7^H^Q1S*Dg|=`>sZY+J5uIe94jf3O~+eoC`{_QVLgSfy%oXicebBn1ry|nWef)bnn6lJ7%u0GUofT# zwrEnf>SBRZ%BI%Ps%W2}sHuyEC5TKAz?gp!A#6Ian9&7-AfVGS(~)B6AoAb?4{-S< zm*Bb%_uTtm3=N&azKQ9@g%piaHKIbHw4$Ocl+a8W! zig{F+)3fN3V=M(VmR5LJc-k`}y`xMY<1N#)rf#NX!%Bqj)CFWmC&^@b$>mD8ZWo4D zef0d3YAB~$PSH?LLsPQo9I$j_72#wps*U(_&hxnIM?dC2{^LLR^1prk>4tP#Dtmog zO~Z!h`*z-1^OHnPnKyQzS_e*MfGT z=>n>r3OUV^3L34aX+sj#7OSL-O$_uj_!G=|30NOTDcJm+t?VocF3f7~xaksNlX)hU zhbxW!@Pb!EN{Q{P=UWfvIrYpwCPwb(vAs`l>d+>>{q28i>Lb7Q^{;d4SzE{*oZ_e7 z{~<4Y@s)i36CdK-bN_<7zB>iB;6kbC@^b7D9{H|0cH&4%YD1^+?GC_ZI`YhJMs|g$O$^0&IC5@Mfqe6!;y1PNb-m#qw4fMjR&VgM&bW+>!x)P*J`6^^4&YA=YvqoT^y zr#X$jx(p!_93FhBwdSP3b&Th-P2^-=)zHUbs$zzYM$6Vfa%XcT>LP}eq9v40BZ!&2 zFp0^SQQy|8SQslL=?EK*vo^0`x>O<&Gl8QW6_>h#IZxBQu8a9f4&`b3-7S>02XZm?Ln(v4G~Ddw zya*?5*vkIwR5Mz`^Kx`JF6}r-DQSxf?C@EsnU0s3SRkqe2PP*ep%IQ78W};q>oAiY zrAvx%un`<}SbVfso0Lc?$mKj7M}{JQqnDA6Y~G_WuxOJq9#qcZw-&$eTaMg zG%-8LIMUw@L6Z8M9-J}l;Cl9-+3`WxR)E(d!?OO!QqI1btD0TLonkk4i4aX9z9MMQ@Iie z5j*VX#bMMTaRkcHpN2w8CgEsFhhOTo7In`^pyVd{x+LzJvpcQFS`5_WoEMM!APX_nH5m2qq#_|<5Q zZEwGa+dlC^Uc8}~$pcxoZ{N;2r=88oTQ;DzX4|%H2oYm8mnW{X{M9utqb405DZxM8 z^aa>@2~SS!1$h?h@+Gd@xPiO>`BS{;%8NP0gGjzYo6@Xx2PuoRL4<<}DY+U;gFCj9 zXFs@~`)+tWSJi*ZwCAzlt_KBaw~JD)3$(=+xsF2u<|j+6%WQ;w50UvF7g5Dy5={w7 zmy)bX$03mLnE4uqoDANWf{%R|Uh@{#0#ZdtOBa>f#oFEt6ec4aoXpa%EV|bX@?}KueRrr&`Y{|Hkys*ecFpqoO6v&kZ1jl1L`qTy{qDg028qz2j&t*e5 zQPo`j5~1@@^;nHih^jQ$44%>m0QEP~m-#9h+v2Ka&ZoW%&9DM9 z;A$sSURp*U8r1;-7M2x+!Oo3l#bllMOPa|=YvRTbyfOSVHASlnqp>^&Lc8Q64VJ8C z-L(9DA;OG4t%=z-B1BcH;or4{xh6pn&=x?4Wi5VpHARObafF~EV%RcGS9}%mY!Xs4 zOgkA8rAhK#arS5n^jf6OP#Sp{JCkHha)?Lt4nr?PpmoiBb_*K?+o2{PpU<=4dCVcG zOM#uqP*w)PRJlBx)~%*q$uqX=J|4bn2U5nE$!3WUX6Q(+ok81MC1O8({hz7gs}R2T?VhVW5;2<>c+MfjUnUc$#;a{)Cq)uf0N zl_s9-=hHngttl8e{#)^~q_vz~Pg2ULyy*&Xy} zGAwvC5;z=MQWq|>Lai+44LkTMYD^Oww7@s3=urU}!DB-TnmFDQKc- z=Duu`k~R^e?e{K%#fsFgd1EpA{6)dB;{b_|RRjr6(!cNPfYF%s1#*G`;vSoAg_@6c#Piv*YiCltA zXno}MNk8q$oJSA3T&YoNJ*36s3%Tdv4>X#UJ(Ut91)My{XCIx#QFClp^RRh6bjSJO zLo*C#hR6+%(I?}ao^d%x_QHXCL9XZeFHeyXRbt%*&}*UJ<$1U7;WDWRbQ|;HAnR?# z%g#NSsx}Gh2_cyCye2n1igBk3P}nlVI^Z`weT?Z7NvAb!Lf}dt2FkQaa2&|=ZsxZm zBeeCNM_Xl*`D~WF_V8E-!sWhQW1K~SfBeKpdH1{D&As>jl+n?>Oiz12z*%RV#rEyn zd8|9hyZ-hAY|n0EhgX5r5R6yI_4V<%lFTZJyDrAw2Y^R%ppt5ls}O zQFGLVWps|s_acAbc^m5en(hp+8-Do<;02sCnBjm@=$b+K0qS~DU(m29)_SRlQG+*H z7SbG^71H!A3oF!ySipiMSP&-ZeJ-SAnc6~74;G#0>Xy}PO6o$;0cdMcXA%w3kJf9W zL$t)QEGjL@_6?+^{U}XkBT}I;uW1hm+QJ6ZHz9%XBy?@Dl9JYQFPtw{z*0FXRO;do9zY3T0u?kAyJ# z?B&gPOzS3r?|3vS^GcDBlAqppKMy?c0PlVKjnrjB0wSA;ZLINtEfpOvdWE+)Zb%mC z9ZS8$kG4OXFDM}-yRu`f9vnbx%?Z6OU;pwa`M}$6n?xpARyt6m*onJkIlulEqFT~=p>SdIlz=6_{5(77>K#1gb0u!K^M*EGj)*uwtVSt8Oly?( zhzjShX?X{W`7!lBaDnc$63qJr=ECWPu#AW-W(#b4k<$qQwrwU1zV9>dYvybd3Rx)l z^z^KuSe&9tKyR{#gX0I6pf;LF)0;d1I(!42*2MyTF(3%SDUC2c6AjE7S1E>;%@+8+ z4s{g<_6`C~%`Y?;p2@-#^S+^x+1Li&wJc6M=L`-_Pczirjno3L8J)-xj<3RERG5sL zaDkcEDs+!qnRaz_ySo-|d2HsjCMqDNYG?tK(4w%cwQ()71hLoxaUG$ErmSm}(X7&% z`J)Kg%tj-YZS;B>NAvKFiI8>~)wSlPd$bLF`MK4_pRVX$bPFWZ3~A;(g%|$2x+3!W zN2Y$QK$$w6>ZMoUsvo;iIhx7A?_+?_n%KS4wb7at*5SpUYo^nOKlo(t0N4`zI5*$= z3sXf|K+h%+0nhpLW1w;n2q^C1{7b8R_aiR>;lgx@yYGG!qyxprjJu7H?D**nJJ6sf zq3|29HGlcSvnh=jDsYeE@c8fuCk+lTsUW6|E6of=R&@<9r9Ie}1= z&OU7;*@+z4>?o%Wt>wP$qrCG?@1~Z`G2ul(B#jxsisg z+c1#@>4Fyg{N_Ic-3`e>-uIE8@V=t=oaiF}03ZNKL_t)Beh*H&7@qTH2Cn}eC<(4Eu;_o@H%y~At>EO#_|ZKcLqGWuZ~)H8z;88geBY_&IQq}x`PY9F zHgAEmHo`kT2LJqXUVFEIeOZ&;V7nk5;J}^N;!i?EK+>zBRS9cdn$Pb%#9MB?0}75Y zQLr=IuND6&e#~uex|FwGeKtEsW_i_BpMtHg0QI=Z_!3ET^GyAQA6``Do=?1!|J?Z~ zZ+_FSjVoKvTCmGTdn5KT_TzUDjNC_6_Z^WAx*Rcy>Zj-NZayoT!%#&b1fJ*7?`9a+ zS)?PI?=@VL+R;Z$z-}$5=2fN1^>0k7wT?BX)lEv7t|3IMDYnb|e~z2p!@A3h+P(R4j~~w$~FIch47j&s(qOjn_S&_0K+u)p8zx^cM`s1peqFtR}%)H^zFWgQzplC*S#M z)}8)*-ucl_FrI_a(J@>%-PEUOt(&?nlRcQD>`B^j=y6t~b%k{U16+L0Y6g1ddC%3` z$Y=MX4~)~3lt^baO8Ly_DY{8;QD21FT|ef}PP>u+b=Q5Y%4{U3Oz85gBZ;Y_*Bgt? z%E}Xi#fEb!9kCrvU5c>z(!{imgdsduv(RdY%o@K~Z`owaw1fq?n=gF)t(?2%O!kjvc_Qb90{BR?0E`k@!WmU6Ag(Poxm`T_^dxuu<11-XPcZNK zSfq&xXqPsQvnE{Nic|?$1$5X892(xq-`)H-yzis$rzU;=>hOCQ>x>88~vTVl3NJzNOtE!M*ASXc=B5RmJ@qD=_WwoS2E z41<^grh+LfVUaByB9%%RL407~-H!100?RZX9aumS%Q{>K(J5>KZ4jDh=sq?dPF@Ux zV$he_puA)u)7og4gqZ=#c(Bo@6SUC!IM3zqfXQY~%kO!8 zj`!L%&fkcOMN?xUmR-}8oY903td#T9_}5TnlvDcy9uq)OnIZB?sOJ72Zv%#v&WeL0bOgmIhi=^qRf7-oK2ff;We+hhMDXrgM))uK(e=&smV!xwf9a&_hv~5!GP<4uOVgJ z8X4Ena~4bl@EMa}PZ49Aj09gXo6}tFIDGAQ!w}?*o7a?rUyi{OS@0d$UxFS9+J-%& zq(mHa*4ULYWQzL}T-g5vh(53~kc`28V{~BUHJmaC2Yj$I=Ck+aVEZE=GUo561avPz z(c>8>x!A&^q@d^qNWGVh?jXO;yS(Ks--DjZNL?D|mKU|ruUtN}W0oI&^C8~$xrgXn zznROobn^TcpUM4Vfr2a;oyh?KdOc9&+Dq0E6N10{{vp#Gt#KGw8>d@L(09@TC%fy> z`5IGR@~HN~b#ded=IMMb|J<2up3i*dv%LAuZ=xN6^3)RAWc?`H?qYI1%62a8OT=n`ZlZ1OBPQc!j@2nfQMf~ISk)w<7Ev|DD;YBVK{p-=k}{%QkB2?8DF zo&<+czM_F{zE>9(HNT7{78@QBqBe73<5X=>)WW?k+Jf#_mKD0)nd9rQ%%D|78-sa4 zR9kqegb-$e-zFOMKsbdG2RPGl*<94@^!GB9?qOa%OvXK*a}eyX=1}O+-A#vsLR0Il z5)!N^KAO2wiNI4Jl5{wNQwP%A@xhz<{vChM2j21uYU&UvxquKBlf^PtcY>N@Bh(0U zIfq_%J-(;7;Z+y#*yso^eCB$-_mf?Wj7)}Fa!5%B$90(V6v}Hf-Gceh(QD3|rQ2Cx zbzJh{_dTCXW}fQkI4NnPLncSrt6_-*2?2rDoS3OIo;$=py!lnU_1eq$+#Nq;V8d2^ zz55`JkgRSxUN5ldOsJ30tQ@{4Hy9)rTzV_j&I!rBZ|RiE9v^I>zfRJ0sz1XIc+ z=Wbn1G7{mJcfOUnx0{`N_b@PYCV5Zuia)=GCx%Cv$Q3!HG&LP%wOpW+fV_W*dApZt zZYMXt`xU(EhJWCq)1EQ4q5;PZt zXm}$vnxs{Bs`**%SX6C++tb6rg9n@1lUeOI9liik$s~c+%!cP+*%tG@#t(b~jDDq9 zEaDw9G_-7Xg0*Y=*q8Od^XLufU<7)J3yRe;S&1Gah@>u$;r^wqW<%b9i|axVY1OFc z)f$7)x)S~f=~+vZ+Yt*_}DEUVahXN`Xdedg*Y!Q3I72#ovZps?wrAw?5;Z0X;=8V(U z8yQSjz;rIpLUNAI^vQG}Dd$ThS;ZVaC+L^amrmoU40R#t5(4&l)GHC5$ZkgmK5bI) ziywWT?c0CHb1%P~JqMmJ1*uZ3PFn0dI8Ir6l$;p&MYi^(`SeF`AeV==y2g|@iRH%d zybAs9070%oO2$#DL@ZO}mP^;N?W%s->If?A;<%G#0 z((VL*dE0Y{DMdnL81s6tGjZY?=DZqO3$#vQXHI9zD{+Rq!26ziJ_k#Z!T4$HspOeS zr#Z>nL_t6gFfTlImOMIRf-TZzX7__Q&JYVEX=jXhZ!gc>_HF1ti<3@S;OFmOOFlos z7WFV^Uvx3gk*Bib>l0l6>D$?U=R5eyP0yfKQ|#?ZBE%qP-S#W^<&WST$&D{N9St1( zT@6mu-1)_4aef?578*(={H!9MEz#p_q^w7e(eOVlwt0s&?~7rl;;`qpE@1zG1I>X+ zSu0Y~36V=37Uuex!;8gG$B;561VYq88kkx#EpId`(eQs8&t#Q=sEYj2u7pyGgmCCi zyUl{UtTk@hVX|V7|AsDQQKMq&gK7&pvC`nm3^?aByc*U>DV?___D83OCEGP?t9J@=3OSfLa92xd{zk{Tt z7Mkq@sOB}OqR~PCQ7q9$T^P~$ob1Bs3b^abpX9Dj|2_Zk;ce{L@hB;2vv=<_>o%Rq zWiNj|Wi5zFNi~0f@^R+yjh`D~jbripzqp83U9g@n{A!ePzQlMgOIa)0v_aD9 zVu4O6@p7h-P01YVHuo~nZt>0k{XZ#;K1g(QhO&N~1=4glCz4sa0U1xBDn4Fu1XK}U zbzzArx!evudgJT3`g!N^wf}sO4VjHhs#ZCJnY`76Xzo+Tvp+V5UD>R$y%$1~k~(xh zb!f+;O+YLjj~#Zy2my1d<${OJWy7=msl4)9vCc^|<#}vcH^3EFoXc$=d_RY_e~$rs zn#Y44UUB`~`Io!yWA~0cuYK({z}Od`uxEOe z*In~MZn^zi2v4DOg(?AwFx#a;0qb#A^M>oM;o~2;g3;0MQ};Bh)}BdxXe%cSWVr5q zUt!HDXYkw?znT|ZdZFPl=11B0;Lq8e`z~j?4*PQd&B0y2<6rN5E8DJpC67Fw=b>G{ zr6zrrxi?Zp;|PK0P17Sb92pWCgD{Z3RXO213sP~G#4V1 z*)=jZoL&z4h1q4ti_{{rLl!7ufUo$ag zC}h6xhZcnif}m_n00tt=_=Pas(S^^8kQ3_uEY0r2)TnTC1camCW+Nb zG--W}jVquL{&#F>{n*pJAcRXB`92FvirvHimTqp4y2T~$NDrpg;;6`kQi@Dw5Tz8m zcJB|ZSB)Lu@lcDRhb1WgX*DVhG^jP-p|$vrYW}aimNp1S`Yw(KMG{LIiKWPgI4Z)T zmmxlj-|4aLo24jigT_!70@<9j3P$wVtm}&N_{cDuH*X-RLFhO^sm4iNgMj7`ITA5N zj`cj0&*OBtJeC*C640exywW6{K!7}HG*&qj*R?vZ@I9lRdw~LJ%I_Q=Tc@zn;hITCoN)<#*5|OK!Rvzt+pyX*LCr3!j zL1uHqq;wK+S?~pq9QZX`ZJTxi(tU%RFV6-vC#@Z9ZgQ0ad(nCd%k5%!HV-MA7oC;n z0_On8Zcq}hw}UyM(CIe1oEYr`oy3$Ts@s^zXNY=PE_DZaaQHsX+T4p2G3L`9%xFb- zZyO5=+MP5)<>*p*4k-uOn`VoM0|6PahN9ARqLAxi7^lotR1}D`&-`SBw#f<`dnIVa z>FIHHv?eW5d6oZU^zT+>x)@<^e$o> zt^_{^zUDPw*baIEbdEP(aS^ZHdLogLo%E}{l*4=C|K6)*cuH%)<02xO$@KD_yS~BB zox2f2;JU6EzUpIZXrwe^-l(q8E@ISWjJjT|c^sz;&nq$KRnW4wM6;r`NwGIhn6Xey z9ce*n7LF1KdAzTHh$ETUHQHQ65<-$KjZlwE+H_M9fJQfIPys8Sd#g=+-CEkG2n}sP zYwck&(rEelDl}cc>MU9Vr)`^jOVeV&A465IH?LQSc7%vYD|&MH+HEy+SQ>dL%h%P} z)&td=XkgsIn$B>1rhOu8h5;JR&ZXZOF} z#7}kKrQ8Hr^-U5^ij)o**>xYExcLp-aP15E;qS(n@+PSw!?QQ9 z_;C#qm%i7~qm)|)n~vj<%jKG~j+l9(IizYdoWL3Zh>gutvy?7T#f0!ww5DAc z=NA!+nXw!Z;#$xqAw`BK@Bb}l^-K}T-bc(%aexwk{`?p54-nNtik{;x==e?R)XFZSH^#Rt>j_sVo z&fh%5^Un|X!Ow1|=ggNA$%SHA-=y1A(a3llr4(nLbr!{nW}(8>9oM^Nis2V5LFH+&TFhTfmNPag1~@DXRTO1 z2QdyDwaPS;lWka*MXgc+Vytpf2-`eVwMMhr6s<4vKP}q`@n`%3lan(<=QXjoU}Sh0 z2zc_b-R3wfi&{{o!!iryt|xa@v9InQfS@SZxgOdQ@MibZ-`g_R8|+Cwc}JBH;G z)lcnnR=Qq`3#khKt#I88+3X}KxoGFU9Gq#OZ^r4+giLy#hjd)t{>C?P<9puS%+Fa) zacmX9O6gG7ib9xUQb*u*A(&yo0N*dJ$FN6|Z;;$yAbJp-3{7^@GtB14i0LdsD5`j1X`-Iuxogki2Y21U)!SZ)<_7-k&!5fx|NStpdhKgDapM-g_K{m?lQx4V z4ROU4SF&ZxX4-&sCC{bLdnxNrIfMMf1RGD^#2M$E$NfM18N2uI=fVrl=7KXX;f!-n zB`YS$4D@p0g%@(cr57?io#QWF{&Iele~4rN-}=_woPPS*fW=KWy_4O$M@UGI6P2cf zV6RwU*XUy)BqU>OOc$B(G+IkyTF}KPNnPaiSDix+hiN?Kw8D`Nbj3OUre8wp65ju+ zI_Kp}l$}0yFagC)&>z5^JIu}2e-gLf^$X7UyDZmktuv#CNC+J=E=(w$$ve=^BLDD= zB=d8+VKFL>9`M+H9P3p>Ba+MIkgkgkDYDT}7+x1J{(rc8_xQN#I{*JUm(NM&Gt)Uq zW|C&oCT)|_3%x)Ap->PCf&z-LToiN##amI=U39(e1zGR=Q&(LVM86_<`??D%f{Gvl zDz|bgw1u|Ngf?kAxlEEdlbO$C&Sx&aKR#zpCT&{qvinPd$;!>zCJ(j0NAG^_Dx5mE=3XSI9CjWPD?0Fiiv>0B3D?447 zgkAe^^op>U#u!$c#}$6_H0WAhBiCFb2^2iFwkDuOo4q}OAe|Yer)M==$`hcUh3s04 zK~1~)Y_huyXEmEK(9#wO+F^NWA;YSLupFdK2_#Xnw!jh^v}96*212;-e5JSE7GXIFr?hU*f_2J$X^6iB`4P|tge=i*E=FD!f*LD&x*f6gXo zP{XvNSk~Femp=Lx-gw^GC^do*^NGm${C@LR_Ki;R*{iRf1=DD@C0V6tk+#A6b#}9` z?`S5{&!e>_tQ42O{%C&u!|(E%^DjZ$5uaq8kYTj82+0Wd+c+r%x7Lw^5Wi?=xpg=^#vF5*>8M>fBnfj z8PCl9oOVG8jLbE3_bwH~Xs!{d6A9P*ZiWyT!8oD#3Lft1tp;UpYh*E9T$zSNg z=pa%qLrU1E(zK_J4vmtmADqU9g99-8JDZP&XW^`y8CD`+BYoMrXPb6;M0J)j#B zfIkiTR1Yc@r4gPUx>kyi6ij8tnU_qwylUD1@}quzLQ*n4IL`c@BvPi>xpO;xeams2 z%n_$XAt@2cBv#M&4`ADI=0_yIe&}Jo;B~%^Tnq|7u-l$uVqLybN=a3NQX0`IShj2# zC#*S{HEUc}tXRX)&=8SGjeY%tTzcshy!Gm?5@*|u4; z<~W{s=po+rwzu(e#BQd;a(IR&3+Qp@p zzJqoJgv+rrdvPhc({fWrw6dO_uhNhu;CPfdKeJA^wLY5citOW zu(FH({(e$jDQpSH9CHjCH=fC7KJyviBP5ea_M`_%CX<|?GwjnnNNs^N356`v&e0U) z0wB&P!&Joz$T%$583KAI*79EV4JcL%$-S8^Fg6HbfH*!ajb^l#Zhr<8tIv(#XwSBD^(LR`@(^<6IjjB)LsC?79o z;$t#tT;%Ig+d|4&P@B1qox66COr(tKyp#x`Q5s@edyT;(zrOl=L`IN0Oi7n1IS#^u z@>G;X9z{?aRj|f}Nh375beK3iTb1k3VkRUd6_qtAURpzkM5qk4+#n%cq!~#-Yojmb z)*nL<^`3WFWoVT)T4e|V2_eX#2`bp{s9DV#*Ag@d3*qhA(;hz{pU)e2_d?N^9&W}s zyjMewJ~C$S4^{$)%%j7RD6v>e)@}h`P=J11{x;EhiOf8Qud}Z7oB@9k4D1m-F82>|LP}P z^y*{LY9HwX`?>JEbNKR?zrZD%u4l+`(b^#*Y+uPPD4?^mlefS2wS4k#-p;U|WPHbd zn%g6E^c~B1QL$#-addZgd*<#%q#a@P>R!gjlXTlPzV)qNaM8+6qX=tvbJF^SeC6{W z;#2Q^hT_l!ZK)KmN>zAbPg4Wh#6ZAuN?|9B9f`4E=<)UkXAb#t?W0hH&kJ_FjFlN| ze&fay{NrgUhiqy=?II=IfB)^g>*A|;@u}ySM<+pI{OXs_@TRNZPe@A2{+m=tA+hkx z(gX->7Oy#t!NGf&FKcKu$r;D5=DHu<%Eeb)PR`K{+R=g{HIlZ?FaGm8{M!l3$$0#U zwyr+D^tGEf=A^S}U%Hm%%a=cfCO7k?3ZM6H|=1MX*BVbsIBDFX&P6USlg@rg&3z7hGM3V3{$kcFoCSPr~cY zGH%$yMI>v4BN5(n(HFrz2BI&Mlt*nSSWwsvR*GAf!N9j)M=3K%hixRQXBLU&FO1nO zz!}a%*`GK?2ub}16b6l((acQ~^UV@F2-2d}@E!+-xN9E^(6 z9xuhXIve?BftL84l)vPo!?ww5O*%bHGS$gMdYCjWJw4rIJcGG9BzCTeUY+Qe_avJ$ znGF2{{fwkv^q?y8kmTghLd7J0hG3`=!X%5EH$P5a-#TJaFgi5Oo8I(RuD$j{EMLBa z6OY-+M4`a3D;Lqfdp95Z*oVBtsz_&N3dbqZ+B%=oSeD248da@yI>W>F|DL5wm-6;2 zuEaeeY-Og~RTVQ%#>VMek{=&uVS5+<{>88I#>+0^l;e*l@2fBg`uqD$p__;k0;*at zSW{8Ku2_0S6Ae#C~01^|Cb-yzaf@6rteI61QFAw(e&8?%llSJ?~*Gm!ZS985$a5*|OE_+WI6bSFR+z_eEB$TuOHDUM4aQ zV`CZCuRo2VDpOJB{%9sfMJeo54_mixWpP)EY}P>t_}~XOasK%iqEwMgCQXNJQ_`9d zm7zu#apGP)lh`86=#V0ZgPnw+QdEV_9{OnQUQT9w7fXc3>g?sU|Naw*uI2J`tF-7e z+l1kb9%W0mee+~O@(nEQjx#i@%Uf$oP%%%)H5E%1o*7azYzK;gA^qOOu-o6zKWG28Zz-X2eR**s2!c9HiO8&?D5%Zzx3LD>mJAOM z8q>o_gqEU3Fk&-V)W8EqWWsf^(0;Mux-JzoK{w#@WUExo_bU|$nLMIW33%_R4ApwU z(O7l_&CcrW^GzPCE2!N$i<5fM;uG?{U#iuhLKQ0B_iE;E5j6j-hGss8`u_N0BXS{3_;FfJzXcGEd zmR0K(QyVH07h%H61_}hVprSRZSfu1Qpj(O2Ohigr!;){^_+>6S|5!4a{WM`Adsgu4 zN1x<_|9rEjFbAy(n`u?1**5!YSqj!{ID>S0kVs1}FQgs1lC6Nt>Bq0)Js9%nJX;jp@f0a)y*4~QY=oT*fThY zZQD4GGTuc;EHZ?j^M)J8jr0Cnwt9i|y3alHTN&BAjaE4iG$<8dXjJpM3$J9%acHuW zgthXq+){dpq!4Ie@rvWP{RagWB-<%xG|f7XGrEuVc!XW)G(l|<6EkDy=6EloySA|G z4Qt3{M#-uI^JEmT7TbVLKd6@v^&e`iz;$a$h+-mgg;RUVjwhCKq6`OIvrul!X@vIsejq2M+GZnpkHnSzoCF3nuoma&LZPkhX(UzOp!DVG`kk| z{8qy?se8G2MN!yupU>s<#Jz&WWky}D34?!~=b1>>&70~9EkSK02I+kbY#yZV^Jg;c zY&XV&dYJ1zbQyPT9Y^RRckDN-y>!b(3^@_lt|6<4B@&eShiN8)7J{lU$yS(%_kJ~H zDT#@IFJIE+K_CM{5b|)!0&xhm;guExO$|JXCWEK+)Y1;cP`?uX#LGSZ42(?s3FYB@ zJdT{09yGxb63L8%dL3JuOeUGiWcW)zM!gQMZO6^VpYk;69o0}|=tJ<|{zTP-cGWvd zb*S8yExQ`b9A_6Pjc(jZX;P^anM{Vk!9nk}*gW*`!@Tvw_UstVGQzGcTR3LjI!|Cj@|L$;#-wsswq^}lYq~po z`SpXp=5yEm>mk##gYUnpzcJ3-YufKtyS(Q7jeO`so0xVKiDZ&_@dW3;=5#*s@qZ@h zNres$4$>)m=uRXE?Hqw9G>aNdxH#D{?3NZR;S!bYfJH%Nv0GY!5(E1WnCslxiQ2LU zT9ZtqGc3{t3I)ZRuYMC3p8H0ob2;pIoNTek=Rf}`&OGyV9&81qE$R38f74EucmK^b z0L0@Fnx)N8etbIv2lf&Uhe;$73=a>pB#~nK_U)89qTKYYuX5L&w{ybk6Dqs4#N3jw+JRPf$X0$t7=O%tURmSl<@9_c6{VFJFMHOhZZC-u) z1}=Q#C7gf$c_h8gX+5@7l=k3afBezp-A~g_4!ftDfBWiJNhXt=bkd2mdYr~m!`f-w zt4e4l^3!bJ{v1+*W^Q;1ss_01+o8Jp+w-KXf&{!m zAqYX^QC9Vg#KPV*rP^Qs$w8czx*=p^(|mqwJJY!2^DaRT>OLI;QU4m3U?o5`RKp6H z#5d@@|7u9!Rv_lORQxHCCgA(11UTAGvNt`Vjjn3Wskq{K@0k?1;w zs&JV|JFHGEWHh^z=eBI&>=VyLN{6B@gDxY&l1L@2h)MJ@uwKd?qL%8Wm`rN2vlK8Rdy*x3YBg8n(Z% zpPrsRgb4eckb0pa8uYNoG}tZk(YoNNJz2CxEi##LVp15nZ4M93$!kTB00E@IH!eGx z-=@nX;!uOnP05QbLDyy46U1nC4Z%L>6scCK1Oq`T zwF-f1z_cU0x-{INilJTCpTwBAZU}5agpYA;lm4w;F*! z0M~A&UIsdo zcs-?DnS0X??|sW%5S5INk0V5llCscv1Ud=RUiYkurl1vhf0LQ*)uFW_kDyJ@Xu8ei zie4{pW^+nr-yiilt5Knn8ptk(Y;&8{|I53R`P(>+( z6ecOxnu;nikshYmjvKB2zu=?M8NQCquTNX+O%B6xI&>OR0<==TmtE&q~6-|u9G&(|3@O=L^PT9DDsHm~Ezn?@R&UDV9YPm;%7V25>81vqs2}xcl zx)TXT9L4greSnLUHG(=zdLT`zx0jwpUHtxuCul;muD6@1ameK|G^04-(v6(9v_N{- zcB-Pr6a|W7Beb`7AcVzacG7rB3Fv6=U}}8aDBeUOAOvlx6e1lZ(%R0Ce)L^VJMlOc z^mbEGnpP3v$t_!0x@s|wlcp#nDD&oemMvq-)pT@rQd0_5bf^f)?|=6@&N}NXip3%W z149TQ$QBh{OO~*>qelPsEhG~*5$TdlMo9H`ljyQ3QJ`4N;W!z3dpqgsT}WSF4?;k9 zcLFJEjE@^w*fGZ(Gvk9G49`O;MKejpb(-$Z0?EaYIRHoB`UFp1|2kHvos{h^a(0|m zpZ*m9-asM0EZYc$e&$D9CItK@hcT`@(It^k=$&PbS<%CO#`wZ*&vDal({Rc#&S%e} zNt!&djG%51*YQ64OE0;clTJF$FH-6gL@6cBw)m5wU(Fue zvDuC@I5@<>?&ldA8m6KYqssA(a{X!aLGgBIXn=CT{0Z~zvz z8xE)c&~wD{sDjBoy!EOx*|@TYsjQ+^N-711ijK}Q%x(7md(E<_Sv4wFjV1(cgMs6; z7yl-;LlpzZs`|4NGj*xeAW${muo|J?ZvAWRzf#K*1l^fD=aBu!G7Zr@F1lLwCnlOI zrRq!(7_5RD)Sg*Qt)KP4&*U#y@&D|A^k*dWa8yHRFPagLLtB@W@jBt>T*wk@%oGGJl1Eb?K( zT01le$yBb$yoC8&o9!@p4bfC5d$*OzYZob_RB*|S?c=DU7Be|K?yrNY2sa=%G=oEf zgk_1YC5ic(<3PD7K zfdJvMCYKv$+A;KvnAd=Pddn_uy6NkD=F?yBVa$hLCx@<^@Zm6;e=gHF)2)tU3BlOt z2t7UPnH+qHfYyvU!w9QN*$W^QrD&2fqRUO*RV$;YD1lqf5fc_l6^O|;q>SL|x?!d1 zTvn7Be;HyMXdOU^7%mR;WGetKzOaj~1uOgnxp9(m@WnHmuM0#dVbLOM5N}63=XByT9Ha6Nu`p6q~r&` z_$BYX@=7*s`Vc3dyaKIVf^Gm|MOm_V8S~oPkupNw6Roi4&!^dL=laiol~s4$&9jgH zj*Bk5m>X{RI9aT^ zlXT2)W&X0|-1D>h`0$56%!oI=(^^y2W=~r&xRY#Z1?er@c;Qo*(e~zB;Mt`de#?>kT@`Q3p*8|M0^UZ$`p&K{COfT?4+Kk4;^OX7;@)8q6SDrDRWfm{cm|7g5P% zf)@t|=;`V8rQweR{W4Ro`t+haCs(Tpi=Yrl5ozEU3eWr)zfl;}0ZPI*w?F7`kvcFd z7Fe>z(&JK$>j=1eU>{($LrXjC8*A7W^uZ5hj=~sBjA4l=&2gKcPLhn<`ku88OoSK#fM>0^Wfa(s5CrMtrqYhU(+U0Anv+g396PjL_)YxM%gdo zT(=?La7|8A4MMHzHAX80JmH}#P^y+`3Ysa7Wts0;UU6gzLB%!C5f#EiaD*92#!0IT z3sFRHhziXa$92)XF~Rhnr@-T|Qc&=!KCZvwD$eeO=tQnoVEu%3e6ny)BLb38%`MNK&bY@@sv2ZFjl zz%8M*i;!kAR!{{dm9YSE97UJ3QL0Q)C@Khou4F-b2U=H9oami1(G!NYUOYD{~LRe@GIUz_c=p*N-8Ay~adx@@~sES0R9aKdWA);iJ zW^q>!&u1NWZ-0cT%pfF|&kAt$;8Xv5dU%L(p#ZewlBb{rC7NhUbuzwl;AMF{c8eq$ zu5n@1k+J)wTs1!3}M~iafX*N)4A}I*kI5U zEw$N+Y~$j$EX#+E84k-#_oLoDtJW7f7R|U64(i(E^Z7%b18Orv90D|BVI9)%aS3V* ztzF7ql3v0^c%A>MC5$0eGzx_Pw%vo{D6C|SsZ5%A$pjOsMoe@a@%qn`iiixO#|I2w zC98-?K~6w4m7obtGcHvj342OjC0xo<(h?6GrU0@CN`cT4`LgoCM{WT48@~YI;X@mt z11}HF(nl;asy^4qGjR0^n>vwA{0SVAx_*7DlvIVl@sv8!!)cPq6iTT>0g*(hLp`adcm=rwC*|_hd5ZVf&9X(Gd+@ z>iVQtdlSecnT$gTMJSSB_3Bf(<<>h1SQd{yx|2Y_#PUiFmMvRHSJxu4s^}Ff@K;w| z&X0fd6gzhAVaJYs0KW9^-=$K6XE(pV`RAWcQI%&Ue+S=R5v>V%Fvxn+7)VGai$yw? zE#|=opT%`e<6?jR7#Vj20&vVpOIUsU$xNZC3Y#hsG8uvJpbi9*^TV8Jgo!hzfQqhYw%z7OwrkztGm!$x}}a;JPl!n8n|H z>{A2+(7kjedF^orfxf;q?0M+`L;FT~Ve3`^p4d4=<%f3y@SBG=bKG(3nJg;WQYkt* zI|)UjJi28MFKm61PynhmXb!;dw|<7TYu9ti#tWHL8rx2iRf?snPU58(_VB_B2MATG z9GJ+%jv)ep0EL3)yfa_N@bI`tpf*$9c3U#+ShV!?;YNzw@DH!ynp>WM9b??}_zsYd zfVQDUbNidm;I!rQ*juzIXhH12PS}^@ofr2oFK02N9Gs+}>L^~_tGMdgCERk;K5qZs z2)9qBA!-z$e)^4fF`);MvWt=~_*-0)4^f_hTTNv$C=ZJsM4+_txhl4u^dX^t%KEcy zNwbt>GR~~HS5bP-=+}6^PAWyKjCe_rXdvcydK|h})~Kip3c!preN2SOdq2;k{K-oF z2#GMLV#E3l98^V^W)_G1e1?Rt6ilgcYUKFzcdj9uwP?!-(#oNf5?IRd{8MJk9_uhL zFrt+KXN=PpbrLHoas|z#P^f}tyw30RQio~FA~KiS;z3A?0ze?>#g@vP*DL^pJlI#A zcT%;iL&RjXt9_-fxf;Gk5Xcls6)N7?Cg?x!EF?#*La9uL27FAwM7p1#R+I|`GMO=IqQ^K{1lvMY9{ASuP}*lt^8rpaYBy zrCGLm6=5N076J$m($Ex-(1C|Iu#H+@TPne(P4D$g96f5ooK1|mpkRWq5cp1-{~bpO z%~U2!^YU&wIu?=}bBM|)B_xTi7P_)!zWAw6@{4od=D&uJkW{S>KPLRnSKv+e7^#5#P`_sEP z-i~nHM}NSTmz+wtYbDvNL&-5+)=Hypxe)yN#{1E(#u9>1)FK+S$XYW-kPW?;Lu*jV zv-=#?s%PS4ij*b{zSOwSTOQ=dW!l(0;kxcj$KQW^%hN0Ox+s-{1MTdhB@_z!MO5AC zzG~quM3=B15Ir)zaJ^2j7awr~f({_1 zWN2uZkA3u`JilchzrFJw0#=RrZ85TA`>9r{tXX~%pZ(ld87bxt+vO4hnml=JEhQax zk`j;~&d}DGwVk%k6^ss4 zn3w9|fo;2B!)dHsyO1e8NX&|oY?l<&r15(aF`7jHA)^$XNn>cMHS-d2^v)?LD4JSq z?Cw^+`HdU-t5eUV-_f+SMXBPla^-w>?AXpnKl)L!3Z}+~85|sBVQ(Mz-FGjE?nPKu zj9APxaq4`(Yp=Z)tzqx*Fr!X}=D5wBcih2eulqXxwrwY^(HNHHlF4Ur-6}u0>ux$b z2knCa6?uy#HOBIBNBBhKI+^_4dq`pOS(W z9cIjN*sS-m@r)JJ)||y%=>Vf2{W-Th4C{D-zdLauE#qaj4+RL=D@n#9Tz%>3G_SF^ z^u#>jq9)iKCS%8G(Y=I*2KdgotN7au$MWq5_p@6!vvGNXtJckDo>OLge2|3{$s@=s zBV{Y4B;-#yjA(+{F9l#AyLEZrChzzDR4t8|Cs~@w7|GvM$~aaVBSZr=JyMg@cw-5I zN-^zdKh6pvP+Gri)?@g!GsTJU{Zh&Z8Agf-j-&mCMoMK!kn{(9R+sjt81x8C(oJ-UTWGB07%N4wHLLLL3l+ zq9r^-LT^8cMrn7UDQZ#6Tb`M8jgt0wD3-|!g03kJ0<|jDK=8=0J+C+ky6z#3si3P5 zL1)a>uqo$VT+8Gs9-8bhWl_!l(z0TvF0X09XmK*K~Q>)Lp}SNR6Nm$-A`|3 z-|j6Oy8EPV001BWNkljy0>-@SPv+ zV13W4QA!iB4S&$hq|thbftof#zq~&P2%&lCp`WsM?|zOsx(%%-C}<5dpChT0G!Y4R6eO;^&yY}>)Z?JILxGXyI|i}rSj;|zL9jqSN~YJ$3@VT@YW zH!jY4@Ss*0rjeitMO75gWecDASPE*6i2XZ$g^Wg7 zVN2SzW_wz3+=Z7gGT2XvMtMW+jnUjg7Hc`$&NPDJ&`wr#g(*Ze|8Ub6S-7-^pnHIn zEU+NyvLIQb$973cmz1p0V~0JWdY(dIlHBMdqoW3&ZCOz)D@NRknTdrzQ3-klM2Tqh zpwVtHXcn<2S6s-uUg2ONM9nCRxh63Rx-id*&Pt|T?K029lFqZDSeE7AN`b&kun2g6 z%@|sLBx3 z5`Ba-qD>J#p<19d31n!(Cal^C>OtS@B6yI&p6}5SHHm7$D~5wwBZR@f1{;uJx{7A{l3}sX1F1GPFQCBd?ol!A;57mzsCSKE76Y{sDL0{(XYFe2Cvt<2jo{GuJuy=5>f*g?sqTu8CK6eO~UYe>QcMA;-z^ z^?&~wsZ{cy->pxnW;bet(4JRL+;h?vzRyDa{;Qw$I9osKq9XbrY1sOvGVPQZRy*nF zPO$cr&vNxu--3`pSffNLG1{CWc^5wS>m9Vc@smW#VQS7!Qk@C<-t|q+zT(FaT}YRe zC7;g|j@UqrA3e60@Ol5`!_>sAW|sMS#%D`zJlzvUCx-2}02tWb?a zungoOG@rM=|C`uvxrJ5T%c&GINLe5zK8See{6wA;2CeIZ#c69>R%~QmpG_(Uk?KGc%J$G!GASSYu zrOm_J%e0;Fc4}^`zvA+Fm!t(5+Gsw1Ggp20S-ON`kxWt?>L+>1Pxg$|(-Tm}PNnWQ3b#`JO^L~E#pS!`bNkld695ZhMY*zH2KF-SQOwe#gW7>yMwM9EsCmA7EJZ z)A`}=(01bhyemiGnx{DS#+$iyN0hrCv-rp_ zw$O3S_qp`bzoJF1M>vB%&ZJXZWjgOuZvWaj(z-;Zd;xYms8C}Gt?DHq^{Vulxrib^rcP%gu0 z&SA3XFq(51Ru0*$Vz}TiQE+gw4x?GcWI++IC1o#`L|jcwDbuR=*7c~RsZLHJVljqs zY11)3h6a5;tJ&*o)TkXYO$qpC4R9+ng?{rP+!Jw#RI%%7%K5_Vc5BS?JXkECN~Kbn zV~TSyY9w!_G$BDgZ;1b{HohzQe4aqX_3xDt31cX#!X>PVgq1@?E0jtz5(NuYJds-H0AVOMu&!& zcFHtqf$&bV$Q1~OT?5;B@u?kXJwOw%NR%ksl3O2b;`QfjK&f#G^|jxTq-$jl$z;;= zsL@_-XV&JVm*3UnMIHGxV+A3oljxfev$*p?fZSNte{iLW{@AhE^CqdAJPD8cQ8!I` zC0rKADbmx^$+Nrm@%Hy_;(K@8Pg`m&S*J|rq9mi)ExhXkZ=v%Kgqz*W@6sOiD;-fX-0=1;)WZpq&GRA7Q4!rGem38629?+ z`+3I|pYS&7!Iw>g8b`9))u@6(6% zy<*u40t9BkziQr}z(Et1ple=dFju8#(oLCqtz`(Ww%sy3|4uaPvTc z_ndpCmjsyy{p=ey(tK(h^4n=^>mcaHC>AYN_w*pF2{xSD?RTFKEt<{OTglt~v;s<4--BcdlPewpjGA*)y`X6dZqIv~P5hRM%os zi;tpb=_*#OKZSGNZ~+Te9)sPofS?W_+vc%zmm#PkB&{t;mZT)Ci@?MPvNcMvSYX;q zT0ryaWBOQ_jIckGqr&V<$^lSw)yyzz|VVSW^Jfmo~sw`%q(m}Kb^ zmk+;r1Jk)8At`7}B}u1u;bt`5c9@{nlsivl!H4eQ$6xy{Jn?hLZi8$9p6K8k-rIYsVg55fZvz>`JT zyO^Kf{1|B+=74>YSDeqNVycGe%E5)mOhdEogYe%Uu$yh^H(BtYyLE-3ne{1NwrNp1 zEOfW*y{|CF%rfG~yT+JMS2qQXmO<%s5(V-&KPMMsOrbLFx;T+%l@|QWV^I7&iznR{SsFyP=1lo9F zN1D%m?gn-b=g4d286`@;=~W_wQj(K5UPXpUg0>(kR#J6>3=iJNz~cirLumu)lnz=r zAT$*v*!lQA?z!#z#KZ(gEwV`_C0P{&x|z}z&GGmlIhlJHPUFG6?|SYrv;T=%_w2#z zF)YG0W9;WR$dqwk9(9c7@dFP$Oe$s5*VjuXGwvr+^$vj$g7V>lkuW)CL`$YJ8Is8e zF7Sr8{0+bP{c{|D{1OItKSIn}%oD$Pf(tHs7nfX`;-1@XKqW>ovaDe^ai7NWTo!>K=47Q!* z-g|$^#*JrqF3iL9^mP0Dgg^GMZA0QV8)pI`B*~=B;9%NU-uTm?osdd(8WkQVN2`pm zb=LqrJ>5*C)BjzF(*Lnz#$j6c6OP8UD*jA9F{OhbRj>4zc5+1Q03oedwNx_gNFK6k zSU|oqNlBLp1mMb3j^=$=oK96hv)#kg_&6tYNBF?;5x)3;D+~{hGUc{HK(KvqkP}Zo znU7z%3K^N1o`^X_9)y5tRfo*lv?Xnx?;m7-kKhac{0@Hp!!Xy~cQaTarmZr=!@~f) z<8>!-@#QBlog4Qjw)M@6f~L)m<2ZXrEa>Ib3ojy->g0uOyV$VdLqBvK=vuhB$|YOBS3%i_jM+c-MW%;ZpkdC3IB!#Tcp%`tp)&te|x zzmK4{sN_fJjR|n`eCe_coVQ^WQv>5nE6pA?z$ZWWW~TQ($vrzW;8m?WDy{^6{@e2dn_Sn>THk=8WUc;(a@Ftk0d!8Z^b; z7*{>C2Y$7W3qNuZvQx8rSkt9-!@V!4lWz^JPRyF5G#a)2ack|B7Z5Wf7GpNsiXre% zD(%J3ah`tqY0f$4>?7jfgD)c=U-CSyl&X{JwO5RV4fM4R0~0l`&{n=Wpp+4WP(Iha z#EdFg6WZtU91&hCX1~Tt9nn1})XJ!cn#ULZemS>of<8ncZ6*gW63X?@qtVQ{8md8M zrU5ytK{=~gS)o)dB0>?LgEH;q9oAu+cGf`!m-UC#D2;$Irm4~F&ODywL8^?Ky{~&p zRoFYsbT*-R2XRPH5X)V^Utslf@vp< z5XMv~lNl$~lR`?#```69EL*#PpWk&SJw1Y*I|oQ66CS}+9kR$ue)>8yPBgH9B0?wz z#vML%{Z~1C+`HwYcZa-x%+vwC;0;Jc4sdE^NOS}mrL62+V0_A+3f-cSq7y%$i&{O3w zfhFj5In3j@XxE}Zo^aG6DvTmpp->=LC?G6B*oq-UjV1!dXC!JFg1t8#sk8p;g;Bjg zssFo?99V~cHF8v@T$j#hlwvGqh>^2Q3j;_QH6%6!S_f#F!^QOf`-#Y0o9rtuR_f3m zAq0Q_!T0g#Q_pyXTHGgZ|0zc%lcBG#7a;@-l5PCw&+bBqUY~FA=Sk!ZRL{2KMjb9Q zj*^mQ+os|@N7E}!JpOlAzK*BIUXBLDXnckt}aan9UuEGHkG;No|@m6{7vp(+=icP8nV_OpFx zn4{VypL);5-2Ka6ANI9qZ4~lC5>HtUMg}t+)zd>P5g}<=yzz~f5Vt}Uv`eh5jaaNi z)tbi*pZgdO-~XR{{ad$qd?^EetT#atsU#|`sfikoJn(zwFY03AK!$lqn{C^+VYk?1 z#>RN|*}X^?QmHt5gn)fT*7a@RYoET3EeD>bI5|YI22snHz3rWxq^oT{SG@LkHb42O zXE>(G4i52wO;>=Mr>MaWh4_Ejd-L$duKND}Wl87CI#p;P zv1dje`P$Nzb&u?OB>DHpxsqkiOfp&82m1T!dGaI^kF{K#d(P+m`Mj4y)dMuFC6>Y^ zrmp@H)8cqua?zWa)dl)9BV2l%!|Px38*CpQBGccGJ2=RV*Zz=n+Tv%I|1EoNaQWZ| zKS^=SW9Rk}>_iW*Jm;mr5unN;S!sw+iY)yd@( z{Cv6sk6VD^b6jW{+LI*k;DZnHwXc8qC_v@#_u83(lsrPi z(R{`f4ONeX_?7mgMX6e}j|-#Q5w%FPKii(fEL#)n4hq`SyH?#SyKi=alSap})3hKN zie(D(s%xA)3QW;qh$f^OT7*`B#%ib0KhdMBGX){40fdM@;qQc@rpFR(EYfWXB=ic) ze2bRD(CX(u+{6dsU2y~nXc(=I$y$MQ$7f&az(Y#a$jKCGVVc1;;jp(*<99xP4SV(~ z2wYg7hkgYo^z!M;F5vYe&^tAaqxVqg-A+|65i%cL=L9WJH=z_YdyuLsQPn@GaWP1pPhZ+-Wlka14rk?{%_o^uXKeo0OYaqZ>b zW+`e^WH4^`~b?IWV}#dy7U-} zl?tBc;rkV~Zr#G<5n?Mp{oePb>Ao*Xp-{ke zUA}kSkC4)dYz(~>A*WCGkro0SrPDi6KFA3>PhnzW%!pZ6t?i`#bptD6#rL{Aw(bNh zPqrRb0@qf9BH1>7)=w}^dE#|sxbO$r*qb5cEYVO0`P8TWkcQIi9DOeH*(I#9Peb{9 z>zW^+HH?lL6M$_aYuTRN$UlDhuQ}zc9Spj|_`c8a+lRR3s-N(szy6m_BbXzu6&+EV zJkKXBBr%{+D6n&&m(3@Q@Y0t)hkd*6;rrjennGa`DJA0*<9zy)pX3$KIjyZPNUh+R zXfl@Bj|cnuSwxeQl9yb3A!Cn@aq`x!xUS3O$6r?31SjhatgC&^|qcn{u5iYhn#_-YD;0{h1c zJnx)yDT^73_tdBse$K#Fmv~B`)ePQjo=abLAt#>P%QwGyJEdtO%KyYC{)Cu@uYCS9 zoN>~t33Q#|;b9s|v(~YIGFN>4>zs4WITU@5UXkbTzxG+O8zgt#{V;mAMp{Uk0!qHe zXnvSU^#C_bCV?zu%e-Sq)0_&JQN!5o1$bk3^7rSgr~3Res7sFnvp(xtN3u|0Xk#!_?S8gxH2NF~gGoC=ZOjoJ((+hrjtepZeuxEKbal78`KHFjeiX zqIH3eMCy&mY($8aQ^u#Z_Z@x^bzJ7VapIPA=g=_3cW zg2`RU$rM%P6VqLE(+Z-CTCx$%TX>CNHx zJ+wn6V;%KJ4NW{WuhrFogK{!KRU5j~B7(SdczCkLo;&uymX|`mnNna2C@Vhv$?x-F zrOf3~nx5j%`NYRh;f<$mr=%tg8%g)EMmTInaaY+VEhYV#40F3C=yn|DH2mk?H}J9F zeiMK2j?)pM%I5qQx^$ACT>f1a`7TSsV)VGpjPKdS+`iqs{JCdi3yTB(gEZt?((6v- zv6~;^Gar8|_f5>wCN}EHou)4?!FKDw(!y*NQ2=KgVQYn|}s(UI{?>ej#+j+nny@!6<1>#~p5b4v=A47EJ-RZPN%ewIFB%8zHRrW*q3y6i?CX z#lk4~$qKQeRQVR5s8<6HRZE0nNG6@;_#Io=H@4Tj=G+{OM#FGNMWnT{Ed1gjY&+N9 zoYEqTVkWwFOYMV2{1-aYJ==igseH9UfRs+u3^4ps*UcOzo_@LyrTliX`KhPwY-?1O zujkVRDv^z}5J(|tc7(m%d+&V_&{{oJGyqtztZ`fXHTXU|i}a&U&W`PSN*)uL zpYyy+U&8SAEzI1zi-G(Ai}Kz&-e2B3tq+e_&BeB#RX*EJVF&?4)8CJ-pY`39J5N}S9}H{JMP_M z2YKFkqdYV<#Tg?*#FZkqeJB3Z6q`3}B$LUb>%KAkNCrm6y|vMJAJ?P^jR@6lvkG-!G6Ia+#Ps0G6b8T|h<`DEW%Ljzs#?^a+;{ zEvZuAfbv;nm^r`BhJ45`r(tTh2e~@$xwMZ;Tx zC*8;NVPK_YaDhnB?KqSQHKa`7`;`cIz+z+?lBA18LK@0UOr%T@(+*XwSG-sB;SGx? zdaTS?(!}eXzp~OfE3TJ+)~YjF4q{LERfL*Oj+F_bx3TSzrZ$-*MrUS`NI|>?&1TpJ z4Dp!ZZ!E_lEa#}j8oCV}4*Tvbu}tymsBdD2ffVyv@pzJEvvabtgq==PtLgUpA(n^$ zidgZwVHifKG2yCWSw*$4gVxX`Br#bB0tgR+*asyaN)A|#3D~r=#$=~BP(-0+001BW zNklzq zJjBL)AKI0;Za?GWdujUn+0=I`CvMox5|fOp2~Irgr93p*&3CW3gD-ylZtk0y#`i0% zk-c;~l0?+xjY|{nvEHuOMZjt#xQQ7R6TWIVGW}>J%gH z06}3EAro{-huzaPzH`%luKV^6x%`T+uw|p&-^=jm7WNe;=pWt6ZFlcu zPkElRU;5j;>C(4y>#n^xP6{b!Snw@k(FCQH=pJv|>2{IQFz?lfOT|O}F5dEozsrlq z&*l%`e=fthG&@c|Ku%Xk%QRUxO`r}E=q{={!3_`GL|nd^FI{s7_dhyCQ%GVOdPTOK zYArJeq^r|mJw7uvTg}FI9sb8%}j}Xj;hN{)dO_>h@>S2gnV>3FqiKZp!i4x>3 zOR&k>#2VX<1oArCd|E<$LA`23^DRO90-8psX&Uxi6bNa+Nslm8tuQozWC2K6!lc+* z7S(D%K9?iYpGE7g$e}Et8{_V^-?pPsbqI6jIb!Bz=@Eir7*Y;P?HrdyG(n)~&Pvol z)v>R%1d-y&H{M?}uu>>Y<2acWiRE5vy7>(0SaP~*OCM`t_2i54*f8g@gA@SQbtow_t@iyI zU;EluiD^wq1;DjvT_z0s@qNV%WnOoQLs3CZI;1un$EH&%eEUb&Qz#TzeE4A!wq)M1 z*|zO8s=Cs<%6?=gnYd2Qs1=}@kjV!BqI;alJN0ZHJ;KmI4|{6^Bkp)yk^E&8cy zO;ZFE3LdW8%dA#xl)Y@w4(#8}?8%abb`fG7u296-M^$w(Bl0AqLsKanDVWzjsi72S zzVBujd;x6Kj0mVqWl6g(Mc*e7k_nN3A6yGrhxqIuIuno}g%%oH>PVMz_}P}kOjedT z=!dV3r?wA1y?wy!mzlO5aw`n7MK=*bAEOD2XoHm%O+gH$YkYiyjrjqpTBEgb{xW4x zy=_0-I=|35vh`0Kb^$skE5~weIssO^-Z@RtD}afav~-&BbZAw?>cHZbKIQ0dpl+Fl zq-~kN=`gemfU(k~)21GX0zhZGnB*;Q*FS zr%9*n2y_H(R!EPq33b@cW2slGRBKN}Q(Kwn))I6#6nOqD{SKTrn&%6jdmD2JhpL#Q zSGw35Y%Rzj@GBmRC?7#Oux*SbU z-r>H934Y@p?_$%|)A;j0{T(iP}Zxi=SXKa@|kb^kk5Yc2P6i1nVK$;lP(v|GknfmZ;SfX(8x$92R^Z->{~-!YmLX#1ga0qo@T9B{}<|^LhE3U&Ec(f0sRX-^~4w?8b3=x%I9o zQrSMXtXsp2&%1!%ea$PG)o|<71U;@Kturim6?9~OCZ(XN6EswvhN=@2O9%nB%9F^4 zj1^`OQgCPC$GFZ5xbk~N?tk>(dEoo|4Odz0C#FkCX_M*ON$;ZEXxd@hHc2dMr4kFkdOJ<2 zT*kI-#)BDRVaU7=$!2ZBFl1_Kimh9>5{3{2E!$y3|7rosMi2lYaofg@#>$~KKW_?% z+k$w+C#5x}4XyTu*_*ZzmPMslrcgRWE|(*hGt-=h@7;w)W7#%6+9ph!j>dc#&;x|F zMSuTVip3IXArWE;r2>3kF_3i$g5Ze7*W~%_EZjOBf6CBlw{xc86F;Da&j8S zNj>92+xIKv^8*oYy2kME5QRcv*=6Y&Jd%LpWJn7^(XWse2^M@sx06|s`LUXQ@aseW z(kl+N!vV~(f)(*BfRn=?CFRq?vbmJQ2j2aDe*W{@S+~w1m6gQ865F=DlA9lRlpo#n zV?OdhAFVCc4Gi$!PkxF&zW733_rgn<*)z-9?1_Xrz(erEo3H1zvrl|duolz82#KXc zYnbo~q=jT?V2J(u%Ut}9^VmB+PQI@XzdXapwi9@0&mIm2nl5J@m%XOfdI!YG3!B-VFCYdJlW|9-ybJdC`kr#I%~> zkUztEvfQ)p7C!MOpXGaxj#I4oY`|qMvqVjl=w0`6Lea-*`B5A_!!PchM5!{p>l}VL zInGPYK9Sj3=Gi78I(8-&dYt<#B%{}_MpkIcO-j9D3e8iVn6JD>@h7?`Lsm>}lKSxPd}2AWTEZy>K6|YPL~K80iq!wZfcfB$JC}%qf$Yk zG&H4T&>djOFObweZ#z3rGm*lX9e{xpVXej?74ce7`_axQtEI={<8ZpTFu_?z;MF{_%=$vt?a^6OLO$ zLsW757U&M#}B&1vIBhL6AzHc_i*3Dl!*~h;76>91-~VEsG9(3A!sO@rkLb_ z2T3-t;HTKFrue`oKgMIbCiv3l{|^H)WaGLx>zxHcWzm#r7SsUy$Ls9ccMBui(tP*d zZ{@zJS>m;NWJ#`wX&I&23)TP!R-I)@pmxOjds*AP*#5cfXykQT7DqrOnMt8kK#OlJ zWd^0nQQ@zM%T(J|Z<(`cXkuDxl<$$1d3u~)v<^{9M+nQ@oOumPzE2>-$aWakM%fls z?V&yJg<#v67qIhX7bC<{$D0@QAUHTX%j09l5-^8=C}=M(6D%r)&`Z&W>mn8{Sf%PX zPKtwi630)`E3#-0($Zl`O|i=d$Jxe(A32{ze(Nv}y6=1J^B!W~qF=XdDl%Ov(H#Mqpcr7=HhcH(<>aj=v3FvEQ=W4w|M?$3qknKMl`v#@Xo%_3AtR{k zaMoDBB(^3o!ueQeXn`j4#JG(m(iYWf6=!V@uyFhPDeT=#+!hS49im(+A^L3+cEHTk zA=a*4OMkYXVpt>=mPn-2Se5~8iGD#)s*>NdiEbxLOm`6kigoMO5tIYEvwd(N3$_Ag z0F#T7L`RyZCoi-s2&5L+x(fmYLPj@=MC%~3VqA7tS$x9tA?z5}>!SkBBheq8DBOt1 zJ*V@~G8C88vr=d~PNqGXG1LYB8B9`EQ!mU%t!mw#ur9U%m|4$Nt#G7ERrv@ZaU6$I zG|g#!=4G4il^xkwB-sAdn6BuffDC=q$%zmyIpr~rOfFyF>zLI(CpyCfg-4O{R3^ovtWn1i69*{^4{uGHI|?=a z?Pu3>`qmL~T8Z`m^L7MOW^e(0@{{d_J*HbC(XZ`v? z2C_D>z~?>x@DG%xja!YO(y*d)E`*>i18Q1D4Hi>m$0d}s#;b=abC%?%)J;n{Y_Ci_0_JENQm>ct% z7ceUvatPK+_|xkig8qYC@`ul3QhC6z*(+q3P_HAVLlR2Uqq~Sp(?M0b%h0SH*dQfJ zby3mK6ba&TIn}zM4BNqII1J+=8D*}u&byi@KO@kRT-BXz=w(*Ng0DMhTvmIpPp-1; z%?U}-_aYjujHq44#mh8$6c=1@0SCN7J3}QF>1fTCV6`(~S{pzz+AHEBVT$f3gu2s) zyP*`Zr$Dtej$bX|{PIM)l}x{q^0j(W)bW|4`?zTdg9g@`AFRg&Sf_vi1XE#^EX!Kh zblTKFwNi<|it3F(6VoM{!oq6PdCg>`8`!vUghPi8QL6=5QN)7KVf$LGPNlax%!XR_ z#BxoJY&J(sYl6T;8-!sm~FAP2DG9iG(xMWxL*cFGm5s2U$SFFM3mf}lc^|FsS=H#E#h(s zl<_m~;#1Sc~)XfbpQyiMy+kQW-6ws>Hqy;AV7TvaGY^~5%MpCyBRFrNhz08<6 zm4cMiJNS6q0zy7a5PPSEY4rZONMG2CG)9%-J?V*w|US z9mY7ieiQRyfMwZ)p=Mqi+SU5?>)E{dc$3Il3fR8$GzJIz*u8raAnnk)iYvy4s9;WDUbP>Pi*1S)R8g=+&p=ISeJUq;y z$pRY4=UqPbu|MXT>#pP0TW)?|&G%wyfu}sSx_vBi zkTDH`r-?g~6MB1@n0S;S$K{Zer2POXH&FFq#LZ9}@4}W2J|1!Dvc@R^d8}C&zu^Y< zk56;SInQUR;?dKaVWCnd35<@6ux(_Nsi|4h<((D$;+CIMC`?kEnkJT#_!Ykm*iYTL zld4w4lux%KNefApWe37#z@plKQwY&MbO7$Y>z5P?vz&Y0tI%3=*?WE)zoOVUkY`Q4 zmrI0X&(st#Es!!#9BoATLuE$tAnght`_7Em9gw1;#YENPzS4An>3^XWe` z0~e3LU9+6~``_oggNt3#4%RS2B>Jd95aE@z@Tfia&fuDLPWW9^fPOiJlRA&euV#SuA+`D=o)U` zW#02Bc+(xz=UJr8JfrugR4uAo3`M7*>L{&90zGa9&#OG)1SMVEJOq?E1f15YRcsjwFro`_8!Z!ux&e{nU$E=A@yny z1w;z6eQT*#P55J%4v1sXV+pF3)vhC}y56q+5>it24-!sKKzR?``v6$ag(z3XWGh58 zzt;Z?ZbN%<7W@HB&W;Jct*dVO9hb*~3Qg607$tHs0`pQzv{DqJyrO=`#eKz#Nee+L zm5Oqv4B(!h_1n=PNpWnfjU&kkTFf1-HI<54f19?BuzAOJL;_;<<#kk=o^99U$&R|c zlNz~V)jmZ#>6V72P?+X>S6|Ja|Jk20J~58(i?(AZKq6MJw_miUqqu4Frx4SEyUFFskVG)Q+u_DnMh+L-3!PgWZMU>2}YBVE{2NR%FN4mXe zZR`P?QPOsk1k%aiL|PglATCqHS&CA?yV@O?nAYu1QA{gh0)}LYBvwbFY$tbBulRz5 z5M~YQm0Z#onnqodh!%tj6$H!IwN>9#JN%|&T2mFGJ;rVYEH;HjZ#ox!?tn&MF;7Sj zu(vqFBGBIt^*|AZFj*`T(;*Y~<6sHA{RhZz8YGDs+Xg{EUT(yzR@o3uONeZPldBef zwOU2w1Ud+r-2FIB3+jR9_M2`c2ozJr{e<@E2m1)@ zz-ZLMkpBMlM$|71V2OpxHEdTHEU-d`=`^Tr~aeHYhMWImOFaG#reCR{Jhv#{1KKap7p_5Pf6%Anc z@28d>d8h1m62yhzpYEJuLf1K+LkQtArDN<(HK^7bxI0HUb68M%^d1fD=nA*nkcl5JP3U=&}?0#^Tb!VQ*tSpf9 zCHa8?615sL6(0m-GLmx5C!Ugwj*Q~EZkyKIj5@v*tq{^Bp}bWAzk+4{zlbQo8sAqa zRbyj*04XJp?b^-S;UQughKC23_bS9?iXC_&#&K$JVXGeECb4GCDfI z{_#6#R4nGTCf)1c&3fpHGBk&}X;QgDB2xxPOime-2;cX~54Z?1K+)H1ir$m&E3~fD z?ex;^xI8j36|FCg){=aFV1+KMMI9nKrxFQ4D?xm&U_w*pqU30$6t=G8y1i!VpiH88 zp!LTHvmh@Bs0Y-|^| zesBZNyX;yxu#H!}<7aTP12aC%Xef4Z?im?Aa(0|q{TRA;2Y>p=K`0*N{L|hL6-5q< z2nvNsa#Av1slm)FXvNk6=$BLw+;Z%0wtwQAoo=kki0;Ruu6&Y!RTyGJ@B7o(|?5YhBAP6ay%2*a;vsubz1G=y*=EJc4-h^eb#N zL7qF3AcH_i2jK|3$r+YrLu{OgTo%>3Q7@~rmRt@?H9+4q;RT*nXzi^48EwFejP5o4 zv~Q0VfT_0YZiNtf#l(DhfU(>p?#$;oI?Ldx-HX0&jDDu}JVW; zY}C@kRHFoDqUlYy>);hCZNOk`0ToKsX`t|RJ)$V2qVa3j3SMi`uOOwQsdZ#&Y`&=wEOS^NBGo6E22tinaAfRU1SONkaP!DW$7}DRLB?!z7P%4$om=vfK%N)?g%6Tp* z@%ZD9V_BWzJgYsn1x?FDBb`nY1e#nf$DaNB$>nT%?Hu>qeGltKMi}Z}9|_LVoX+{fwOHvQSCTE%NkkNl}`fr2(X+ zAd|^ZRyC%TrYDsmoUPzEE;5y%w-?Gav!6;FdV5oprj3h?nKBFFLZDP@uOuoy1vzOr z#s@qP*L7)%#IiN4(l|~p2ci(uxx#F;778?lA}#XtN|(5lENUMqX9x-b865mn7u_k% z-M(0fQKdvbUQA&h%V$f8Jvtn)f73`=sZW zf#+3-X_%ZeE@RzNaQe%)Fg`wk5QgRvi;ON>I*WP7XIeR|7kQlNF($t9TfFSL1tzYU zhFfbexDM<+yzh_B<`2&5C+Uqb=xk&fL28|5pmN;x3T>U zhlYTnugIWC3x{s$qO~9`9cHzPvTh)Og{AvQMwG6s7R0nMKIjvYhL)664Iw0HC&QFC zONKhRj!dO$p+-VDWXvh}-_R@(D{P3DK|#m~+fU+OzkTJ3^;0NJtw@!BX8VC`n-M_* zA*{CPi0{`{>=%bqkBxBuNPwi(5M4Mz(YSi*($cInEln&mYumSk0i70ysiBwJdJaSP zPDV}4PO4oHXkuZRKx@KCtI{29fR<&oC$HslxxM!XL5pEyY>0KJR|Gn@XkbZ9Bts%f zlJ5qRcDfxh-ZCUGQyUG@q{p^x16sn6mb}%rE#^a;R0|~8AxqZsG$JPjvsxgunUZRy zD0x0N|GdQdV1W0$V*QFH`sy`N)tZDV5EQ2IoDjzekrEn?LqeCpwn;}5=Vp5XrrR2l zYFnq&GJwz>XXoKM+-2s5xz^36?H;?zi2m{F{O?<3P#(X}{ z`M3sd0RrhvC?o2F$^4?-3R zar@UpvB-Q_B?vSFmYKY)v2)QzQ6!hM2?N9Hv~59;uqj2tcQa9T~W%Cwd0?1jcw}o*DD=W0!MLh_xvo_^&nOF#M z+a{H>DHivW&Gr-1nq1Cq-;hE`=C#Md%*-(W6MY!MUwuHurAtjKnl%NvEZ9qkM9Mg~ zM3#jA6`l0fxb}ZO{YyXL&y4l*Y`X~{gurnOa9`Bw8Fyr!2`%K=1SUt*AT^YQGduv= z1#2B=zikJ7Kus=jJn+RI?SgEccfRimUiNSA!(oEB7F4Md8yeuful*97{StW0XS`C! zc9*zwx{I&>^_|eafls{m75r%Ces1}{yZHL2Ze-KYD|y9m$nlvWuKdbBbN%(-S*D*4B0vDZoHp7l=i&SsC@mBut_pgbX zK<1#0uQ;qtQQvAJxUO-Mi)nKJwGQ%_*3^Y)7lUi^y=^){1%*-`3A&6+k~GFHbA=jR zvt5XcKnlr%<>O{tyx9W9vX7fs2EN0?Lo`$!5dq?sEv*3~##L;t;Ndt9{f=p7HI#3P z?P$8AltMbuUL85rbxwXtz9OF=XcsF&X!;$OQY0)-X+@F*3l+^n5ANc@2Oq$3vQdz2 znMWSEpYzUpJzKV%$_4Mdgm+x}7T)`zcku`Bx{T9LKaC9=Ht;~8Xo@A)X8YK zGZ0MgAuR+01H)vqIc~V&cJlcFrmuWI2WF>PtjuD$c@|Lg3UlTz`93k7CFPV^6lK6B zqu0?R9723%*hims>C!$+Knw}e!HEj6k}7cO@D}z=j`w>ImmY zCn!;?C}6Aq+#-Rg@Nn=F)6mo%=aLp^Aq`N70&=WSqrwm!hJ=>QTo90onvg+IC6%=? zx}1P|5Hj7~1FaSNxYn9F%NZ%U_3vnMA|kM|5Nhlw;IS1?5Qau$)XLLnMJcqhRy0s6 zmsyN{7SkaC5Cm0Xp{8Nmk=E8YmKKX8f-s;)NTXV%jLC@+QT|WGE6@-E=}2PQq3#IA z9-ZLw>+S|l;$TtCpfE>=)8ZskNLItk53?- zOcX$EYGB844s*&)G{w?UZ!X>Ov(^6pF}++2Dpg0zC8QJxm7q~m5QRZ4Mqf;`{myExU+Xz_XXDrau2s8Q5=bWmrCLjfYR23u@M&nx z8e6a!9$w(Ku2FZ?xtI+C*5{(pDIwjV;cE8VS#%Jv0CWeMMi4L!1VIU%%OQkKkFZ$? z&1%otf_k7=pxz$acn=>ANHq(DluISn4y?s5mav53giaQVK*($u(m%MKc^wewfHiiO z07zveWX%+3kq}$klu9K41}sBAt5-`jL_kl@Mwdc-e+Ju@2x07u!$8r~+C*8_DYf9# zYCy6Yth7dkzF)(29lDtX0yr?kS}B=f9;Je3+%;R)Q;9Z*^T}%O&X@e3H(gozC@G(~ zOto(mDGfD8M;p?!vf2I$T*RX-qqNBkK3`H1n##yp?05bJZ2DdBZw7l0qBkT*A3wcrH*PTk2@KmS=~CdOzepB-nO&6hv-ImX8)*t&H~Ti2nKLQ2zoszw2=LI@5`nzAL` z+T$YEE-9ty8Ujfn@O|_Dk^+3C(L#`s0!c{G*EDq(j+-}z8M=#!*?Vw%UEE%m7S(uk zXn45`>sN3`NAU3?z~Q$6v4{$8DM9Py`!g3ANi;gprHVM>bWGM;G_r2TL5O9mZynjs zR<$B01^dUx$>;M3As86w0SEfOak;LV%-~DOq z4KBa);oqX99;9FN;Z1A$fu7zW=9Pz1kdqFj>1h%|v$s${O2eP;Cgiqz?#Fe_)W({a zV!Z=z&M#2Auv^+}fRI#c%w^o0*)P0$|YX zjdUG#JkN{VPoLQvF!w+Lfus>NW}0FNAuPiR=`c)jI;dYq%9%>9qS~Z8>aaz0`_HS- z!gxeiY9v~k7ihK`)Kz7syIM0ZG>y=_=2G;mx!hX9Ff^U?azMg1&U}_2su`?~$xYbS zw&*aVu0s;G5#t9z&;}i?+Nc{2ql0x$R$8>MScmvtL^QJ&(Zp(!vCh zwd4{{R=+%v#yp9+Z#$Pu5?B-hty*ifBNpN?t;=%e%^KiVoqld)ov;K+&(D{n-^?q(Q7Y>S_ptNT5`W zE%^bOLeo$o3qA;$ATA|Z3etY99h%evQ8A4E@rSu>|4rcsPk@?-C&)l`v$>ra`;|MM532ZvA>nr4o$*`uqEtEbfm+ zy%yLoT{=W}$s*IAWj?z8CQuaS!vJlEbOZfs*RqJws4Nh+g=M}U5SJ2LbZ*Kk!yYXx znnE2@joXaqg839s+D9y_S*%PVM3Olno^ijfrMGHE$+k(oe6tJwhog{VI;iWouG8*X ziwJqqqNz=bdyMgPV4s_CC%>-uV_P#WDWv8((1bxM9Bf58vSAlh5F$8}H(S zr@mwrC1GVZ&+|O`9haVVz^9JvM+G|S$|W^)OG(N1k&Y3MHX}eYAcyh12l2EbC%4h% zWGMNQ#I$BjejQ!TP&;5x$`p=c9A`?(N622JlZbM^T(nkrURT>*-}eC)+KsJ}=i$0e`wUWQ`OGlIs@vX|CnpPSN<=QAi(Ct=M~Dx0&!fZY<%Y4QXNV`|rMt7oT??Z+zn$*|Fof{QVW* zFq%;}&m*;IGRmVz`=qw?GJITyKIb@Mb(exXjhZe14z^NgZ;UP!N;oXaVP>_(HpekW z2wG7nc+98@TeohZ=o{mNx^(Hvgrrp$waHmFZ5f~>T)uzr0w2HnMrsdS15O`jY#ZT! zo!ZMwhf^e_;*s$Rx7;yDLkX%vGlQmzz*ci?m2mdx5+{sGGNU`VZfuT!`SJbSw$J0W zFFcD^Znqe8Q+V1#KY^J3zoY+P&Ycvl>*D)9o@Xe0kchNO&+LRqMl`c#o5o{mkf!KD z$OKB&+l|3a>euRt%IXQplhMCADPTH;Bqk@VMg3}85l{&`J1xtU>xN}vMTI~&R-5?} z3!!OshC?pXymV&`Xjv?3X&w6MeUK3OIQNdNCEwM2sC@CproR~QUox=W%i4N zq8?&nUSnxNw+P8 z$!e%&K$8}RmRZ&6X|Bsw__C=@(?ZZp2x9eR;M;oL*5~ciX0IGvwCc0^F@vP#?^#5j zL9!;&2O5XTR?V!ViAt^Bwx4UIMnAPW!Pt_9Eis+$B9Tc&8WpcSMrt+0S5v=6whS>g zHpO+<{e=Jg(GR&}*S)Cf9GQrp`0@+h#ObG<#swFgPg*#Pk590Gh2uC34-cc1IVcVF z%a1Z05(WqE~#-Ud(hBZ=y2OisV#5AEL zu@r&kC%+ToQgXnX!;QVvf6Vp|oeoV>0#|l>HFp3au03=qpTK)gQ1#I=h zaZ=F~l(rV2q?Mt6IjLv47+LN@rhY{}e@bIO30deriI05aw*Qa4caM*wuJ`|+o88YO zJGA{p+&$VC@2@DC~!cIm7|Cp6s;mC9*=;c$T^@Q3PXR|Y#%xAOt{qdRIq@^mJ%j5ffcz*kM@MsctH$U={zk?zfPsquPQh z5k<;voO4uyxzfS+oo8XeGMK*rBz*CbWtiRF6vaZ4Eh~6fc9NLWNFvclRM$!O>|`>R zLvvmFd%LOfhuArp1K^`;R$)trwQE1jGcRq&7i(hv{0=HSq@ogm&=pD{r9z^OM1tPl zKI#pXj9k*C2whDdb6#S2&eI~QDVkbfbzNuN(x^8KREV%c!3mT#9a(F*oYUhtc`pH6 z4VdbU+I=>&C9O#!QOlT_2hVDD0-dxuLX{!Bx@u9S8)&*9FTv1DIs$W_dM--M4U)8H zlUW}(ylYutnkGW%6utbIqArNX6BLDD%iHg;X6;&j|KNixSg@EXBZ@8s(P)TFW{3$~ zss%W94iRdlC?H-N$F?P*L@kX?^BA@YyknXy7A8|pJC0t>eIp|r^^Gg3?#q(3M$ipt zj&zW5px6MZ!9N)MArp{;1qcgVQ1fSv>OYk zBS;`G`ObIl=cg}JLNu;s+jcvzykhaneJ}8x3udwI)Fat5Qo#?u`V7ontU~Q#0(1lV zM|q54s?YA=w4;`A%_IF>`_DgyxyOS&huhzHo7+QAaNi9dK{qn0KmQ+WOiG{UpR*?( zvJ`TXD(mLdwWc1)fw=CH14<)IL@5{A6vm~vfQe574l(Z#i}cm6cxo+ezXrRMEZ_Dz7F$#|&N zG&P_Og{aovZE_OwME0fTq=ceK>4Mj+jL$efB{9A0x)kgjS}4qO`^qVOr^OEXXgQj=` zH4SkpBVc7MEX&gj{x{IQ5)F#ZYGt$Zc6FEaA&Eo-iG~Cs62Qsl8Mhpjr!<55TlwFx zshRM=2O&fm#f<5C8Hq1bzX0m$>b;Jw;4Kn5j%Aj09`SfBra3}9UQ5n0345@&I$(pG zw2*ifmLkKrtOg8-DimSTacD3ELzZMvYGA~P3(5T22v?l{Pdxbhn>p$DSzK| zlQ;HKj1QA+oy+~-`8D_4cn-@K6wJ9AD`8+M=ELqHEPC2H7h-p9|bxC*Q3{oHc< z?|Ea#UQAO7N-LyEEFQ$NvfgIbfY5XnMj&8QC|LLdE%b{dm;TGW(Ek?LKFA%+uV(Fm zd4J-evrcD3I!I|TZVeNU*O5h#vs5~{0MeN>H8n9NZAmB;CKL*h$v{Kvtg;PY3E2on zb$0LWrwSOc)6|AyjM!FGpu zR4`(viN$6SiRu(HiZfbYU(bjqsILx%2-Pd0e0_aAp->2cMni0t62IYM582e$&tlZx zi)|}Q<`^1{jg52c5%m5M<{opREDA`5R}FNZs7f>kfA8Z0V;6`i#oDpVWfeS8h#_-QBd;b zX5{saud!%R#|*gl&rb{g-kX<_J5&+8LS3TT9N1TVe{|)qI}gr0iPHtN63?(h9{7D{ zZe-$~@OfVZPacqpvi}?Iuj||Yu~%4NwR+BgCimZ-^$a350*8W3!jfTbx#H8Fr}#%3h+6a;f~jnZ1}DU1ugR`>2kfeYHUrjGz`f7$$JZ9{*?1nO z7Pi}O;dj&MdXgO}lSLBxT@8FNIq5^wLKHL?;a1?fMK<>;C##Lyx8v7c7OhZCNHW=s zbR>?~U=}@l%?Zb1MO!1!Zrn;yP+sH|nqjJqnAb#9c;|H7vKTMj7eZ2HNOF!qhy;)) z;AE)=stiF;mrN2z$bzROQ96|Bxb6)ABz`X!NeTO{vIZ*WA$TB($AdVI63Q#xiNm;s zvYAJE>E;G$&qlY>n-KbS18G@=h3+BUs>vz>Rfcj(%X*9k%tQFg5Hc$^_?m|{N9iskc}%qy)(O2!dJ2CzBUk;oku z6S|Jj1)Ak>?GJu{l#+U*5h-mfPm}Wxmw%NXeDA0H^k44d!AI_7DBH{H8y}+H5X^3C zV@@K;NUuY`xtC?jj>fW{qoZRH>o)ZB>lb1W+Qo*oH5|FBiAJZ1&)+l5lW(+e<*fr8 z)-lfcNBMc{(uGVJRYX$n@YI6C+4igthC?8BaqcZB}MA)05$GZ; (p2HOeMxzsnjyz3acq2%_mh_V$htkH?vG9EwOr^*0gXAjU0?3Mr{KT%@$fSrWhALQqQb zd8msd$>dYWV1^LSdyZab5gElvr1#LAMRN9}J4c8<}}G~sZVP$-OR=cp24DsTyUSt{1hUhJGreD-WAq(s!$ zlgSJ*4n(6d@|iSa(xzG{gP~AJphqK-L-2n$3Lg)K zgb*^xSiGM(wGHgu*2hijzd$~-iP`meT3VX1?Hq$t^M>Q2FH^&DAH0M$XPin=Sd5tx zDLattC{xP9LdP`oRL3J!NQVh5a#ERysM@GA>G%|aSR0{2hhNZYAFcd%175LXbVcu&@|V!}OdZJ(POdu%twv zoi^8zWl?^~WJ1-|Qd6f8*NR|J$Feenh3#s&G_CK}ao zgPpyDWPwDY76XTnW6~7%5f;z#^B-NvVFw#bi7|?n!`@xPWX&o}vkF`GqS3;I=dGou z=hvKi?2#;KZ9vz1=r{8?jzg6ZB<+;A!)kLqT}T$-GqzDH0vz5tpR-n+%wrE+%vZkj zCEj=F0va1z86I}XXR0XJ5wgR6Mg}bWnF1dBx%A@0z|Fw!FkiU!agxb6Qc4nuMo&{Q z9meN4lG#o5M58hMAweuwPbOniux>WnK`A#SofCZAc+1 zp-_xaNcaAY5eS8;7AluTx(bnzUIOi;ttJko5Ty#KIH!t(Iz7?I4k;(EG4JQKo={$t zAzzJxt;BevcA8N;jqB#hg}f-HsBm3e*T#12vK6T23EhGKLyF=R7CIHOK)s=pcTD=t zF5+>62)jtiUDTPISs8bcau<~hlS~>|mPt_vJ_(xNlH@to!f zyM^i1t{B)CuAKCs{L$116%yj{h=(rftXp@c=jfvU#Rc?lNw5F^AOBN`kB((oq`W)~ z!!XMK9=OT;+d9h#I)(wH2f!WR(8Id87p(tM{KUX;r9>) zP7Cnz(k0yRyb`5j3!d9%5EcvAB^(M1Yl$$z?yrT}bY6@{9@q#22ebZ`#~6-en9OHc zY{n?qHU+FEfOhp8N&OyJ6e`SbzF(klgVas(qV!U z#X)!$_CYViSC*%2hGAeBaU4g{YlkcgU01&^?KLQ+d$n}D6*H{zOZTRfGhNKoVjqti z7>3SXPrER4%02VH5;{~8!+Nf>q|-LKuJh)bZ&ND-K9AO03Dg@=CT)q?KSTsYn_048 z0lmFl#N$zVdU|;Bsi%lUg5?^q|AxK9Pj?*2vrqhigWDGHzytU4>Z>oZygkWa&n^Z! zU!z*MtUdh*bY1fNQxDO%Ydg`XL1$+tS6+D~=bUpc_dawZkqFcq?F?H6zy8B!z~Q{^@bE75kXpNPuD%a-Ck#w!fwDqmyp)@yQFi@u zT@_EDOw`s-Y^E#h|yh7hN|z8Nw6`nj<`R@2#v^&_KH9PL>?( z=c8-aaB%w(OlGR^Nt-1LsyO3=vzS{q!KLS($c9VTv81(uphqmT0A9e}jE-m@cdpXpTHmio?|VR%e{mz=pn0~A zla58Ba5!RK8$bW{#T?dN$2(h}B_uQkdxjJ@w^3(=LB{A|T!hKkX|iS~Eumq~THVee zvjrU;4Ky3IKtA&(ni!@K9cNGuu-Dm*(6U6M8KU|-w1*~m@CO%jNLw5AhDs)P9Lb`EOBozg zzWvw^Xj2F=h2s>^^*GhF3;4kuPs8jM;2rMz*Gu@!+73=zHO9@ipADMJ+dF#Lx^*+N zS`ze|CYI$;Zz!A3fmDj>x;R5aL**MZogTur(;T+)XqxM1k`NiDeY@I7MNwr>mDlqLzE^xtn$C)-fxY z*k|$I-yy2}z3aXUnlHiZmEdjC@-wbONh+05=-zwekCvDK|C^eYzf?2+yXarPO zFrWKwp9H%Fh8;eA%w2rzy3J~O7hTNx=ibHRkH1d7b|F7}d5oM)5pxC*gPU1>!aUft z8D8$CDB?K5AXD)+j$F8utZ7njM2YEwryu=2ejkjEx)h7x_tzn%k1D?p%Q889=|ZXn z40oj%+_8sA@7kWOt<#H%5U_U5>M|Nt^jx?s%PG^tN}tJ0SHrT!yL8HpVTp#L>k%rX z@+6;h@PzDw>Ue}%$p+<^A}r>@?&dQvS0xKJGN}+tg}8zS9d3?k6F&B zG^xbk?nnC7(Cyd;E?8K_J3F=!7M*}3HpQsc!h?u41kn2OjQ8~ss||AX zhChN`fJT#xPilg}5pH~R8#GP9(Th3yhPU|Cr6#xEu!|>uaw$Lj)+ZP^3F8ZxAvmk^={zn-BGghWGv2!d!qH4=SRFQJA26F3y} zKB_Q?AlTX4$yC;1QWz8p65Ad?hzzEb}HQLELx zIW^;Fqjrvht=4X}X>>iUf>vJZD`sdJO2f{5uhr@AiyoR%MpT5h59O;w&k{lnL;WE^ zQ4<70Do@F_a}+g&oPg^gH*R@fQ6YV3LLJ-mny#UFw#ieP##F`hvFWizE>QmF(imGZxdvF0Q@w6xxg!W2p?)Xf!5*z$kUbFac{1LC0oM zqR3Z1w~TAP@&R7>KX=p7(812$K87rZnuMZ#X33z^>J26xH3&K=IbR`o0y;Wsx%i@! z`N_9G!?(Y9CMz22Y1Stgx3*x**9k_4X^QLAQc1q6AHTDet3Pu(bqsOh!3`|$XeHpe zp!s!UKNf*NXi!loc)5mRAH82mqbg^h-Nk*Hn?GOgDkgBt8!Q$6;`0`dQn#r-z_2JK z!v{QfEcu=slfpufcJlajg9)I$IYMh=lDlran1Ho|3YjCOHvkPRT>fE-dMoh-N6~)x zDi*x|REDft8d`!>5@umy3H8P{uD$XjtUmN4nrhXF7&A=|4dPu*OHP`sUcH*LPdJaO z*0-@F8pBP!gb-o&SX-%YKa}<(R+AMqBo9BCmgQ^cwQ~gYYIgQ)r9q65+4U@s{`j*j zZfj%3!d9|4nC1wTk$5>1r9@ej1<7Q_Gem_8 zleR3Q8KF=Je@J*DGYEv#jpGjqYC>T`A?4sT=^2g(LK@XVH46Taa`lm(TSuvQXhNe3 zjZjD@8r7)@#SmhOaZj%@V%rR6h8P;!OFC^cj!PvPp-{LS7^P`pWnb*7lv-D+*XAvU zQO6-C?ec~}FHzDwr>KBX(^8+2z}A!8^t(4%{)IO<;+iMcE?~XX#*ML6+U;a!mqnDd`nMZBC?FGtO0L#0mD?uC>6Tk+qeFZhL(1=zWol>@dRl{ zvh?s{@e7Tnw)s?4Bypw2tXT`0D8iyehw;je9SoZ`ISF6>%C|^64whx@*K|*B%F~|s z(eRwHW*V4Csd&wk&a`2R+=qWJ*w))cDwU$%Fg%Aif#x~C^qV7$nIoS5aQgRKR+cd{ zUv~D}+dEkPokcIVXEbFZ1SAs889`@% z?xE{~aVzgl4GjhdNBGKDzRp?e&SS}f#R##In{R%WhaTEXOUozt!0{Wn`ub0 z&!*VDV>54Veu&1}DMm(mDGEtrZ30abys~8r!PqSFJ$ZuO-@I|S7miHukyGa3+p&Yz zcpG6cMTL~)dpkLp9!^?V4LD@87D4IIqC31fnB|4vZG}*P2fp?prm|fSX@!gcxeLDg z5cx;;a{pTz8}7|=!X-DcX=IQllK%@vGV0ojc@ymlDM=(6cqcVTU0W+=GKWki=@Biw zC8M~>2KE>kwhV42UaNc8a|;u+kVq^i5YPz)pemv>Cy`)E2&y7&$Y7G{I)iX+9I4O8 zpE#QS5sj)vC(`dW;zkz}Y+1yJ^Z_bsXwtU!SvV%MErOT(i0ey@ON~c)cU_mF_nHbR%T3QTg5m`$hSWX>@WQC4 z8=z`Up!q{HYE%ZxGRwm4cs#=FS{?Rmffj=$$DPbODT}=h=z5&IFnA@U@k*+WZc`)R zm;@Y)N^~lu@Pb+e*{q2a0$fS8ZV<1nWpJ6-I6?F5Yv9dQU%GR$C4 zo}eMf>tno~8YXBgW>n50E5?v=F9Ayuvi5T2r|0s(FFwP)xBh~ojyeP>ee|1_cl-tu zIAvPA8omu8rDSnOD;J-C5)pd2>1+Q0<~FJ%@iBP+tVXh4`S3FajH?AiV} zbL+<0aQXSPhkY#UXhjI<^YnWATln*i~#Anu}{-lLcAvqK)Vi9 z0#(sax$#gb@2Y8u=|P0>64Pgh49kMUzjlvmYQk2NXdrD_EMM5nNk<;a?bm#g{w;rE zZe4(^o}nn3ICjlC9{WE#IN{7M5it^;>w#eTNj7gieFvK#f0D_}Fk0gTv-ByVGR;d* z{(_cq1P~(N(bQaicjtZ7ia}~bKj~c%Gy*iX%x1x1m+{+&b5uHY zd}Q5M@#_ZF!2oNd!!!T!VTx7Q@r^6o4AHc zSl0=QV7XZ-iocM%A*Ls)#r=5H@pvtjUKUS09>H;xo<@mn|FS;ie}hKlFNx^>ryqYy zj*8<*bX_6Gs?lu5vaAC(D}M{}WeG>o4{aZaIAM_hQlwIyEbeIKXTLa?PkrPTnAgrf z-1h=M|L%$0>R4p*dHlg3FUmSjU$+Ucca{od@=ecBX@Dl?vHt3f zU>k5sEj}ZF9LaLdk%!WoaR`L!dFG|9Olcva$@wfe;$-gn#XX#G;+eG0ox{K1`dt<+ zY2)lmzCb23gmfjbmiMvg#Z6ps^wDLCq7ag48}8|KAnauen5I>R`NusQ-_r9dQM#7t zvoWNto4ZL29rWj=F*OZt_O%4iUQ}LT$*x@gOjpIBx(uAy%0MqkCX~I zsYJOr`t=YM(np0>V_I7*555Y2fpz?r&jA93<_M9tg}kw2g!At2fp;v}qi8}fz(F5Q^22kEWq0oY!9YI0 zW@35^&ukpwJGVd1g1K?NyWwn#<|d?sY_q>JqW>XZ#tVDeS=(f&3{0&9r|BX zLU~a~b*zr2kj>d^JD6RkoUZgx$zIrl^IaF$Er6!(vnUXa#md)v6)-MbDy5GiE)ytg zYRZVK_O7e6L=&GZ#VDW>=fytFkh|Y&rvLAxZKH)kxVBA&R5}$+(@3Y&RJf8@eLX@` z*)HHB#1xtqMu;i$8Qc5&6tl$dx{Pc4Ca>$dDAP?{M%x~L+JF=0f0q{u;yEn}Z>;H+* zef9!c7PYZt4ES_P+fb=bZOp_H?~OrG!2^$DzlZ zN}}O?3|l^&yd)ZgV)h;O?0SV%Dnm<4J0qzy!rIM-%g^HM(~jhhhhJc1+cY(H6bZ7z ztASPCbx}fn9pdpgU0r?UVXqK>*~zHVt5y@GJu683Qi-R-LLh}C=kbjzJ=Yf9P@!$g z{&zaLw=_MQhHu_oP>bGk<8cGCyPJ{STbP$PoOgz&2pTbRP7NoWaw(tx(vAG&-ly<+ zzT!R!J^g>p!Gq;}RN%vLEDl?` zgpTDaxbNpjQ`{aP-je3+fj$mj)y&!F{EF}X{8y}4d6e>wmdZs#*L99P`*XbY^7Cw! zdzg}=3~m1tCw<^7e)y07&ZJ|NMVX~UQ9SSYG0#e~$P@_4%eyx*C-HHHEQ^g>x3e+r zuvZSSdj5RwwqIf8@t=Z7k}q7io)gv_!3D=Jqi$<$&*-2YlGp_5BPpb|8c6O6ar-^t4qNqV3=Mo6-YoF!1F5z%YP3AO>B2!*5am#72 zO2+J#H|e&WCZA4|bzN#|!b;<@p9i|@DobNcgX~ZVJ#oosHm<9Lqe2r%Bvsy2B@|NO zYPud`+$}Xd8h%%Tm;$MS19Of<=sI};cis6ou$ZIQ*AN?M;K3ii4D$?#Zesf_pP-UB zt;gO0p%!*^XQ^wQpg}jNGIYAl6bLZQk@5ufFK%jQOm3zp0Ft86yv^)%#)1l&Q}>2x zX3I$5f#^vkj{M(W(<0y1Mj7kYBzixcp1^f>;b0lS7sY?)t{Zuy+hH5jXhKzh23ntj4(I(Al|-R4RpV z^L+ifYk8}yo6r99Kca^Wo_+aco_gjv_V(^T79^{VJq}rb%197raHO0-Khu_2Fzp~z z;WZ&8BwJ;TIAtBk#Ef%Ys?kMJP&TNJWX#MmW@V|2tLOam=RfC=<;yv=qXWwmzK;t* zS9dp3!m_1HnG}K{E9;3yRVGVJ*U3r2lx0zA1c~W7SzIj3Bpz=imFgob1d~plupYsZ z62qwF;fMdgq4O6JkJl>a$V4*&*x9QR$|uBhbGH9tn)4bfWuLF|2P$+yzd1s@HcnU9 zv%E9lcowozMjiO%<*P7gKwV(L;DLB#50i*cLw#V^s}-VfzaO7q*QrzMGJ)($7Lv;p;}YJ zk=js*yrPXTj?1{K0wYU0nv#uiAf#dw#@v}}k}U6Ogb<8-gOi+;1a%!DY!02@z;AxG z0WF@#FjKtQ+eL&hHI9Z~3K))oY~sz=_LAuEdq{jOV^~PXLgG*viQq~J_83s*Y2}vg_;g5j2YCANQCj2egv1VN z^fBt?Y=*b*;+AXA<+$@!)7xt^YD6d^FwGS8UdCX~DX7>Fprtm#%8#$(5BGnGotqwD zmfnC*R&&%TXJd|7ygHaC**u?!(CO{&rh+CS3+528U#CjiMC5M9%}y337W2f@yV&@| zADFXj6|QMgkP=<0b=Z|E^t^<$G&eWX-QDe>&p~e;k)D=D?t{pbTv$u4d^6=J0a@^o z$vFF1t4ar&5^)}W_<6u#&6?Fz0{#+jc80sdyGPIRU4=C)bebE2Y`AnimwaL^dwaJL zsf+PaPZuBl*o}PX0UG6NwiYGdFYM z@;aV=`UMVIwh+@a35!5EVA3xF`1K&$pWMmGCsgw0i*M72g_K9J;)AuEd;TxE;@Us3 z=%}S0CBbts^8``4Avk#TQM|PIQJjIzB#df$Ha*FgKK(&%y5>uKP5U)#x$C8G(%YwT>4jf| zXcJHV>JiTW;9*oU?MN-9r2n06Y&*v6+4a=d*Yo<`%@lI#X6x+iBoqo!g+@_RVUM}o zD1^gkT9{mJlzcuqv2 zt7L&nrZCNMux&VM5f7i*2pF_&>cf0}Gnaq$IO@7LQXOB!q7Qel^|sd-me3TBlj$AA z)|DB8Ul)X({5}o0l#)vC8s9hhb(-qp-|vcVipNQ%M#|I_)6AmW>U`ym&wJg}%fI4K z^`E0Q{a+@5l|oYY`HSTLGkTno^GFGeE!in6p|_^LMM}GFvyLh5JK`!Doa?;^8Ih0&6E*jtb2q7qMfcC z&vVU{M{(%$bGdWl7>DV@v@e^>l`H45ZO1lh#eB9S=^q&(CUq>!WN&YZImslZX|Zeb zX8gLKCaUAu4&zet%;TNJ;|4+#SXoE8WLeNCJk)rf3>C^r%6QF6DL}U<1mjk=9LTHa zUz7()WtyFIaDcY9h3xL!K_#$x^G41;`)n%Y8Z67=o_p@$;?I4Cv(7q;`|iD$g$p}4 z=iKu#B02}Rb+Bg1q4d1{D)r5+ynpp-ZusH9Q7PdIU%rA@UU(X$xLj-#$!A*d|p ze@!>s^@dTl)%5E+sZ=ks8#>5INoQv#qp1o82C_7_w=*zck#Qv7x#QnxoLk3HM;?kT zO{xr?3h9tcHlPQCXh2`zAi=+K^9rF%Q=WS6k3^$&>>e2A*S~uLA?irm5REF!<6vB; zBIEGLQ-9?6GToco0M*8~*h%Zo6R}(WE_N;VFF(O29GcZRJ!dy-n6t`DdD@ zm79%9Y>J+v*G!t&Oe&V^X;!L$KsdY)rAz`M6na;a;<}P?p=^!Eq>VeIG&1$GXY)qq z77F&PvJLmxP`a#r4TLpZ7c!bnO(;x0ZIef3$VEh`>>ufyWS>Eyk~A1ppj@Y%R2MP5 zkzJje2+~44k)*~+P-UeEi@z}yy$NQ8o(VV05PrRSd~CmotruB7M;Q_TBtrGTbd za*l}}Jd_Cv)J6h)>&9>M#81!1-&JIQUCdo@ID0Z0|8e)5eDzzmEBk06fdP^WTRG{Z zGq~^82icvnaN{mEY5e$*64sr*l&2o~587H!B#%x^k9##&64nhyq)A6ZlIy;B8Mj^c zX@+)fq|OLYq=rPx5_a~5S+er|ENKXO0(`;2OP4Y>Qs9k^+n5R(ytMH?+VwEi#wd=n zozI;2A#S+tD(-&b4Yr#Q5W-8Qcgv09IFhvE@W#`xv1rjkOw%e41Epji*RKOo?)Q5H z{K0_Qyc*NgsZ#dIFMsk&lJn|Vvt~6_M$prPDBX%KRG`;;;b>1F$vZ)wef&W_bm{3# zIwMS=(XseguKVsKobid(Xpt$>jzv({sYFoe1wjRMgDei!ggE(>&vV<)Pg6x*Ea%J* zxAXnG?%>Brg@yoA{P8 zO@z**qfXlC>#pE;-@Zt}i*}ZS+T+~vo8Oi>!edfGOot)GMGXmoomB7{H>pcPlhS!Lf*RH&M{D1f#0()X^WLP4sO13FVF3tbN)Wx=yCg`Awi z&;>)5S$0bL??EU2vwD&L+j^DhhDDv%|6G7g<$F9=e@l)^NnfD~rgBm`V%Y*--Malf zY4HBq!!Y7x`uaFyX@Wk{OV;XUL<$BShj|#J^rNUA?BnvY>lyCLGL+4cV}M3lI7nZK zqjz$_vUYkMhZz0k?6&pbi@o__AU^C!%i zzns~#=P}x~8NY0$GbDNT_xB@2kmlxQ4m)fmhaY|fuf4R1AKvyO1_uYp9nd0Il=W{* zm#ic^Y_WX#3M^}w-rfNod-?^w``uf(>89Iw=)R}9(jj>_yMlks4{{sbBpT=EO-HZc``>V?>tm zqlaIFkikLiE?_cb3EFUAq=%!|9>;Uve1>1Yw3&-ftw%(PJo?(Cq7Ji#x*GkKhWy4Y%J3p*hfWINi4{BG>sQ71jW{kjy$|5e}`~clB@B_11iZfT}2< zS?ats9m+-j^aK9%qt9SjTSx>F${8~hqE-mrc1(x?T82aC`=P6crEL+mOFu1(zs${_ zy&E*awp}AEoj=W(m~IwInvtop#v_-@VdX6>!0-2$2c46X`>l_~Y0c;Uq2Psz05zIc z4#qBJqr|jnA^o(Cv0Fw}dIuHilT5bJGH(vgzxo2Z>^v2oAl~oyd(YL-T#aURieUBeY(z=>ChC{8MoB^F(+wIG$m5E88mxYU_dr9 ztaMjthrLWv6x9?1lCOUAbBwu?TOWFiT8~azug78dZCv3eCkwR1XL0vW?&FNp8yL5` zsdW7K6Jg9@AERa^pS$u(COnjJ-11@QEefs1;`H@LaNn){Jn`sGPCmYwn)qHa&JZ6s z{(and{a1M8$@AFOJzn1Imjfx#ke(!k*H_b671^9v-F$}>Kkei z=w)t@>4q4Zce$Z>i&=o~=9`{(xsfl36nEwLMW3gn9#{d7eD>) zyil;5*4oN=Mv^e*QgD3edWe(SM~Gn26z`zh>?R(cLMKQnHNqiFYuUE#O-}j9Fq2(P z{lQp$P1l(Ku{6T3FaMEMlxJ-RSmaZ{RWRcco2_0_B#l@&hSEmuUv66|8&j`5IPh@ z57=+9v_mH-Ee3Q!4ue@*9o0fGkWN!SD~5(3J(MZyPe!d#0zoKPl7_lj42+JF&s*hU zlFQo!P;M8woN8L8DPfA6n$DyNMq^Y;Ngx!W=uTmyJjlnS&G?Wi7{OQwY>=+>-X~1X z&6Nw?=xEMEOO(C^*CiYdlNnB<1=TS)mQ6UU66%%pvBs!vQvoyy9jpvhdK629m_#a% zb9)%1ju2CfVd2+xA~eC<4n!Sjbx9Ma@0C2*8AQI5k;CRuRU6>rzk8iuON)u#EUodm z^qUr;grK5VGTT_m+xo*)TL+gZDnT#MX#(N7ffQgU1yL2)S7j8ib(aY%gsuk=jzg6m zq3EHFrQ%#_PD-@0|A|KlGM)G@=M0FysPD*&KgW-k<>$hWpw1VhG$Q^qbHW2m5CbOG2H+1s`bO##5Hi*|qnxGCszcryR%UFJ8~mgBwYN1ffKnq7Xd4X%km}@tftO z_mT^m(vy{%dDW~GXPigFP`M>S2r>d{WD6B^Q5_#*Kwr-M-i^GST!e;2z=FP153`a1 zY`cpoOKJT&JNpPX9*nIUghR7P4G!}Dl}l-FZy}qt$P2;5tY#)qw9)JTthAv2QYryD-Wr~mOjcxwT^%QnICDM;DyY92xhVE3Q+{`!kBcXZRzkm8lD7O?N( zuq+vFu=(hHc@%l2YB^IkAVhPpSqH^9o=j>z`b5M zqXta8$Kk~PtB)3^j?H2hK7BEDy%xcw;16$9f;*cpoG`?g*~hrBnUoMWlH_|$u3oi- z(|;IX#ljByEQ_Gi2x*^cBJB)g%;C$Ack{h933i(UfDM|?kR=%}ZT4)3pwxI)b4iZ) zNV*|9k^yd>I|cplHqF83Mw!rZXm*SVP1yn$HI0xP#GRBd2`-9S z5b_K4Goa|70>7Wh$w`Wnsv1=IDwMjQ0s_GhMQvI@Ka(n6Y8pyeD`3=tIYhVHO3Tc>Kc29PA=Okt7Y!3SSr0*e7Ds7Mv?CtZed zKidJ&6mZBjMqR6XTQmp^xFUTROlpxTV6lyQ3zE?;@%c3^s zneA+T>19?fXk@k#VitYWghK4j7s!YVx(+_Gps1O$m#`G{3}#ujtcgnc7&F=!wtN(v zN@gFumgeRTwU_tM6j8dTq@pb@S`=j0<^>F!KHT;idS#r$#26B}R!F)r=1N*fX?;gBHzaTw3^rvZ54T zh#pcBMi55eNC-%WNL?E_=~9Vc)Uv5En#&fEind{T*#$wQbg*-2wRlK~Hb%)}kxy4J zcYZrk>QoA-D1m~a{23v=Ag`Q+DWRe35p2h%Qn<{DY4n>TRFnimuKfSFd-M1<>O24c zspB)YW@L|K%ZD5viJhAyG=%$TfpWK8rL;gVx|Hq$y=lL6*={LaN@3gXwm`c*pi4`+ zwp@jBw}hJzNCG4zb`m@B5zB{cX=KgFnvag(A2X8WTm!l7#k$P1O6TI(QCNrR8y_8Q613J?*{ zRQ_e%2!BmlNTKrZb_0Zx(OKvKPigZE>7c3j z{eB=J39$n`k><~ zCZ8kEv3NR9piPI*{oASh%e6n}rPZ%;>TxG>+DRV*6^=jWB6MKq<~8In`QrH}kw}j7 z;~(FSK=R+W-NsqxpU+S{PCPzBWhO~w2FiiRhN>{AqJe^1%Y^jv&{Lx{uiL?v`Hi%y zD&z4Cozc0pc6Cw^hmw{d*DkuA-rg-#0pW0%f@Lvn7@YLMBk=_S6(rS{rm4b)C7vood>IQm9^dL5sDyU)siJcsNK)a-})+(BLgHh8Wci;1_4DQ zj*XKQG=w0iJ3(>Py3WB-_|30R=hEx%gUt=FO}JBV3q+EaAO9k~8(yL_5=G`T*nBT2 zN!t7-(}sZpD3K_6sWP6DT>JA+am^LKVB^y{czQLM-Ee*z=YIJpUhCOF75ZM+p6ve* znverI;z+97>lqx_PJt~Le8bZ`_Vd+TeC%f_2o1D1KuE_i&kaCz)-Qv3Y74@WWQk)~HeStH zoBPKlS)&3GQJer)MRBry@)i9=HIP!EU<~1K|-i~T_1R4njNvFZiOQ!QS*$UJ~^99NVLHT^1LID?PafSarfo+3A$uz+E*JGF1 z5%2FF^SO4-mSr)GK?;LBDmD<5IkIl%K&@IsHf5l2U$O`3tec~B1lV1 z8^SN}2tNfJ_fTC8l!H($DN%)B@#5uddG!TGOdC~I3Frc^oGRPBmj-`DDBH#RRKcrj zH}HX_^YBPXPz_>OqiE_PI+iahuj@0;m$U1J=H@ou%8bypIAfu z3lK?KS_EB7$*Mj0W5VUpy;Ct$bZsC9>FCH&j7Lx+!z84{FeD9)O$-k7viz8~a)_1V zcke*zxOS4D;!#z)hsWtywUnuN2BB(1TNY3dg4n2SZAr$pO~kz~@<;}xL0W3ir~wxD-xPz^Jjf8Bl6cwR{%7OPx@0PV zg=NK=kY0DQZzdf#P%MkQaOjQ&VNnnQuT-c)lEtE^T8=%pv_J|nnGBYdA|ot3mV$+i zB`xyoUrcE20|`0siJ&MyM|;i^Wrba2aX*W~`(>WVcbsVEnaRi~Q68K^-El;#Ld8fL zY~8l4+~i10;(ZU7RQMYTZ%S}<2|+Q8IMHZ3@px>HCgr`nm6NJXGaAd)7BrUh5ufm|P!u`m%U|c~mt4#jzxWmIyyFjab+)nO1IzIQ z6b@>w2Z9XNHF4zpMkr?a>*M!v#NkJeyF~jtybkCWC{6 zr~#E^CPPPaJ-8H3RaM#9-|ud23UlYqrMbD8zQI1%j@T$~zTMp$Iq{fd_~tji%Y_%5 zhu2mJs|^@Nj89#5A%FPebNJ(NuK)3GfH|O;yku(5U}TP@`v;$)77JY()Tok}rJ(Bq z!^lvjLrr}>BmLW%(-Eb2^JYf+x3Ox~3hL{1#>a=z^%nPDO47IGO*ZPze&JI!q%;wt z$RqdP&s}%@k)EDSRH5QiRdgg%@i<;^a>1feq?Ak;l4!J($=C=|3RF$!?cO+=s$vdj z=(je}sOxwoq{l77s!FIW!elH(U34*7OH#n1HsU95K?sWvMopf(@hql|HZ~3>n6M01 z9^S;_<|2WK^)z(0F|cWhn)X`O-28c_jR_XC*E1C#z>*HaWmu9d23NGh#~;6(2R7_r z=fEJBobXlZMFw-j4uX2L!t#AKa{9mJ$Ou6^J^`vAFTpT8&OP5K7-5`Yse@?X>5UWI z{HJah>Vd`xC`mAfx!`kWk`yYmwt#$t8!!Ac5C7z8XkEo8uD+XVzjLKCO*F?50=!al zlIDXFUH4;l=K+Hh!-OMk6ha|rbOiQ|di#D+?9%YMMB6U!?-B|W@RBPJs%4q-<&670 z?yD7iv-OGlYEqo~Qkg{^tF~usg|T5eZ&NH5$QEph#Uge-L%yQcC>Ehma5RvGfaYBB z9;dV4!vFbqr#kJ7rN6(NggLSbTfJAps|aCDBPzgPH+ zWsBn3I^Wr~vg1@3qgq#~7AgrNj+CV^U%j0Df`iN9LUO|8wiOXL(@yVxLg>6@QOr9P z6?&NtuzkD1$sH=vl6c(A7DWgK24gI>Bx#p>o3|vos+UDxJ`o|4%8<_(1cioSjG-fu zmd&>QI7glw0S1{iQs}yhS2!ugepi1{9hyVhl!O`tt!67*HH{6g{Dt$*`wFV4pY;Z2 z5oIX9S{2wpGC4#>l|&kxn`Ue*LrtWX$(XUv2i+qbUUL;t$QXD@GOw+TFMaKsFgi|6 zXNVvD;4;jZ1&N)|q_OOf!}-P!e!}<;4~!nKUYl~W;lQ%a z!&h{9r4&6-0I%0eKA+#~=Q3U5iQ2YHeVa*sMO5mGN)LCCYD}j|DWNXzLtohpRUXdI zJvf4Tn_AZatkmczio%4MK;jrK_%)R&TT<$O8>N7R^G&txgk0&;pjJrQ<^~uvldRBM z=oJQLi&HqYB_%}*s)WQ?pfkC1n3Im}BukOHXa{L&ppZfn4&>`o1s);rAqbS30t7`N zP*wk|1xZx{c!Z9M>QcWXstCN#t;~O5)0=mYp!oLD3}yFg0Vv)vm*hYYqilJiGc!9Y zxTXXJ7o|;D7UzHbY(DalGcXJTBR1if4aoQIPn!Q5^edIgxsL1CMA_$E*CXsMBHy#Y z-2X*P$sA_RA~_z1T?R|%`)QR1^|GJ9L_Y|@wWloLnk}!vPK{awF)_?g+u^Lb{7Gn7 z1zG@-8`+v0CYfobCUP8G4T-7-xbFTGoVO6VBs_Q~q(T%#fGP|Mu^^xQ#Aiv3k8|p2 z$2m?ac@TDvh+>n@?7|vJGjDMxJGN|L>sxQJeA!|$$#H6Hbu=wlPL>C&y!jl+x?j1; zj~OXaSWF8YFgd78@OHS57KRw!HAcWYSV)qD^%m?n zBw`i^wMU4{K9+tcz*wq46$Z5v0>2d^9#2uN>uj?os1*j9kW9r*@|HzV)hW1E)-}40 z-MyZMXn@ZwmQ*bcV#hb2pc6pBi(q26V(@=clj77#mKy>n=!?Zza>OE-r^41auMaHZ zqUEi`Vg`q|2RP^;LF)Kb4B9$8yB@R<0U4r3^+V5U+U8nhHoe53e)bQX{kdPly!l*n z=d(@|Eq1xO00~VEU=K4f5yvZos4AF>%9ISjIMCfs)0_x~G2pstQZ6d9K+SG@gtw&8 zQfx~LYa8dh1y{h& z9)m>XJv1u^FgUBAK`T;H@H6~BOD5oGfh-g!*3+1CUBDNX#k zLxn8}P=&h3P_xvy2;tCA3&O%MlH}dE4?z)+tlGOHrUEkO*#kY#9&xK_ud# zYAnNJ_utJ&&byE>stMqrw0@Osb`7}&ZMfUf!Tsnr9tv~-ZkST4epDr>kzh1FSQNapVQ)oj?`X##Cg zq}md&qaS}_3&JeoN#|M8HiyCPjZ6o9w6?Yp9~xx`RVYdj2s(v|`#Egf*z0KE-0$N< zV`xG6^Milp*b|Or&6;&6ib7LU6RTH0&%%YBq!I~y;U>H`3=a0PYSjwEm!H`{eNbb^u5EP9jnKsuiP6{56@hK%NrsO^HlDNt zs;Y`tN|wx9#J26*IPB2Fm`;up6d@KaTh8jguEVkc2SVm}3am2iUM-6L;VKeI|#;sc8@tgw2nC{5wWA z<=7Q3l4Y2}L<5?13T@lUIeSh-FsYhk@jS`S55hIEz zb4=+rX&FZdlcF(<5E1@2AI+*t#<1May_qqin@B^FxY@xYkL0=O1f2%r%#9d4{?)_C zMi!H)Z)Qc?e?xcyeyf9C<8@dTMM-WWAO)R~VU~TOi%ri?z$ObCb=YOOxp(ffrwG*M zCCFq9f3%)NN@cV=2RkIx!N)#)2tt^<0Sz`D+a~MQ7v-AI-q+6IFSjVA%45Gxn?1Wc z5<dYSC=cvj+8tDc;){sa|pf>9S!Xb)6A!m&d5P}*Y zE}h}3P-mLJhwB(%096f~03hH%G5J7F`chqia0y%2tk#HZ$R7E@gp& z@R#YRdaX{M?I8>JRfl3`#CMh*eD~C0&NM7lz}AgxP>^^u0~f<-x8sa$>9y) zx_&8Ce4J&?`u>hmFy*vikgzi7dVsL%NI*(jR&d4ig>vC5aCrER^ULmGS5-h7SDSKx z1w%lBszTDTn7`~?*7vU_8f|4fKE|AeFrAGa)@|L${kPr3M=tz=`)Rpe+G@ZNw_C8Y zZxcOlJ;~7>4K(Ub;l5_gHctN7wd{(=5kjR}SFz)UD-2Q@GsgMU*S^Z_KRTL=j#@?1 z7(ga1RxYb$-PT?F{JL*)#q~dSn-p2zkn@(Lr9J>s^4y)baCA!^DeH)tlY}e}T`Nz* zFyb?*^!u48W`v-%Z3*kwcQdCULRVLW?_K!`hP&4@KcsTUmNt20|=YGA0R?SA*0!27tGl_6=NL(vGS+)e6y_yt?g$hrr*+`0m$T;8ExIv6nfGKVA zwk+EZYD&pk*m3nT1$a$2pvl#lNRQknqB3iaQFb45XXm^KN^q*h8NS4C({ zC*7bk({$lfrzyx=88Su>)fo6Jl@aNIluMpl4(P!~(W$ z&(J?If+;hYhCx7T6olp8s~#+H>0M41M5zkPWHKbI3|0+ z@?I-%x&POZvm1?q*n6{4xyWYU#korjiJXPHO004qpgYY`RpRkDsv4lFy}9fHXcz`n zZZOq*JDj!Z{T?Nl+_GFTp-Tr;)xBvk-u<;|mLwo0rmBLiu;&VO}&Q?45rA}FX9a$>97>0T!WO&8`k3Ud1$F?WpH#C;XnYju8CY)VR&+c zv@J;)8L~)T{OdD(=KPD?>?|s1U+iI`vOk1n%rFS6!qr*mFse{R9dnc*ZG_p;JIbML zM>3KaW8|$#B3<*z0;8jY1j1p*VaR>$MT=L^)7?k7&J|mR1%5?g-oh}O*Kee$smZ06 z+AN;iNo+JhIILleCJ2Yaw6%57)6>UMhabw89Yb_>b~0i1QcVyo7$zv1m=_3=+L@qj zPBTrx1Uu6O(r>G z(HtJT`8r;{LuJLm2RmWR+C~yG!vFc|e{sn-K8q=1v@D9Ub0mcjOUN5>g1R$s(4sn3 zu2GGtDilP6YaHTCL4y^Jp}MY8Gz`+Bod96U0kS|WmZ2t6Pe4jS!Wr;a4nC^>m!T?I zk_4n69BF4@U>*Lb;J5$$8P59XEnptZydVCRUtW4TAvr)$*ch=CpZcd?LFWQ6RjSa@ zkqjosnKyR{Lg;Mmdy#9u@Da{?_E$Kuf~v!ekRGRAGaU!a^?eys6efGe8J8h$x%E*; zPpge_*z$Tt2iEO%@Ks;YIM@<0u0yA{RA&_3mZXq-#}&G8fbWx6+Duni9hZiw)y&u& z=Zkqfc@NU(-OpIm>(I^I=H^}PsQaKfJA0(^j{8UfL8e@DNfbHzwbK%gKKf*Od!NUv zJ9x{KHA>F%^4R0|^P%%jC+L=xs_N)fYIPm2wD2Lh|E^!qxA_G=a8N6TF-n8pK(Ku- z>o+}5q_dv!z7pbXQ6+RT?s-3O_#$q(Y!l~R_X&K-Btk-3cGLgT)6^bw@_vG;B?CPh zh{aw<8{Wa(77fdqB&4>o@vVLiJN05L%c9y}tZ@A*H90ePLFLzb#xY1Dktk0+{WPDy z@El^XB)j5q8g+e^W2(R4FXFYG4z|YS*GV_ZzB1&lurFTWI~D@qQ&o0NSbXYhpW~Jv zJi^y62tmA;Y8fW1ruqEGPvzJD^?eEg&cEaH#UM z(C07brhor6FW!D0n>G!RmKjvla;amKy`<+aUdBLT4pk993e8LmCt0!P zMi6ixdcTC>?g5r|wKJA77#J9!y*&zMoV0|8UfBTQ4oKJ_w{zXkzr~i`0UrM23!rE$ za>eu0K(*~UZnzJw78FQ(Mx34|jmP7oSj>aR@fBxsZ=Z@Y+9*v-Y}=-)G(}Man&vbW zLKN}3*21M}f>{Bf78C_dfppqIZ9E>&9!*QJJlRl)+i4V~4zC2E70bGnLWOISlqOz8 zSr|)b#^EOG-t1|aBP#?xBqLH#OAA%BkhcU`VIz?wEbz(}>MWBnBZiDdK~ZV$Xrl^= zrq?orA3?D!3NIk2!mdD6TsuWgb&FURag(KDTq024xt`uHg-aYzW59d*y%|w^<@30& zAE>hykbR%KL>cqBP5n$`B4*9ost}}Ix{z?4ze=H)1tHwwzJpgkK0U6`vJ5NN6yh^t15Dq^7*Pu0U!MDyM zi(pqg16vK!;&{gDgS<32!SC*V5$1iE8%{rhAz-!fLD<|)OkKge&KMRJjVq2Mx2~7z zUIWJp+X$J#!q(xipiA#GwA8?7Ns3h;%)1cCz7v;mu@rY6P* z2MH`*Osp^A(nQBtuzWf3T|@Xah0)Pbg26D2jZKV_prf&oZ5w-NYHGrkHub?UdRTK) ztAqHoBGU;NNhZ)Vjnr6@Xlon8eM1x!51N*yrZYrg3`Qm$>vw;1>&z!_IqO5-%8(QW zQhG=Wi^QNoqps85-bG*E2+yv5l}8_aj3bWwFv)=dR8?h1Y?xy{d@3nZ@a=DZoukkA z7~i@2o4maGL4+7!-r_@PZHRK~9Tzb$Fi75VHt?OX0ovQ!-4IPjtJl`%g!FcIck{!W zzr%n1?9&`{NDxq{k2KI9+s1MFvHbH7FJ{-;LAtu;)7!h9oRk=;aXLHale7%#Bds*I zoz0W?t>p`!K8qtxK8b)DWy6L|M5FDD4y342ovCMCTP@8&oqKNo6NemfEX`^iDRNZF zI0e@Xpe7O_VL1&;y>RTQJJbj{)nZHzGp{~^J`$i>s*J=Yka`Fzr~3a3o0WdcAR6sr zsJE9$B#PI{p{N!&e)k-%y6Gu+JH$VI>mF!SAsGkL2I0If^(S}XQ!T=F68g3?Hb>x7 zb@KiQ#eqH^x&A`V{K79C)IS`;j=RG>%>>cFRo}VYc_14FytNa$4g-4|*L>@vOs58D z3@rgRx!bt_p-`hJ6cq(UD6*OXSIIb0b}xiy@>h0Gt1q3i z)UZrfutf^{L{o}D0dHQGvsDgcPtCqhW`jd>_LR3|#YHr1w}cq7EUIefvSTpCc^6&8 zJzxJm=U(u6Fie6XMxCf<+q&mjxU7xFwq|tI(GDdoi;$|5w+#Mx_pRj2T^M6M9ChC3 zkurglu%$P~2TwVZw48Zn{1tzrSL#&hMXDPQX3#XTvGK_|>co1wUwnd&k3KcZ zLB|K!b$L4@a*&R8oyh?Y4WR-aIm#`+_%VNeY7L(}=fj+G=J_-^_XL02t`oPW^TZAI*k?#GdVfxI)1sZrn`6)i$&6D zd$-cozek}bUB@n`CU;!K9P41mnoua7a@b?GBGt9pooD-l!E&Rr@5RG*sT__yawS*P zG)<~e$~pnVFqpC}$J{_soavC#LRwk`5P0-jrln3&m~LWyl7f^3g&WW(Onj;&ZAcpR z2#OU#*CkT|5R#4k-6-`3BjX;tB81a=iG3_UMdyLCOHi;vPRu+Xc}pVSRl4%tQqJFf z0la%Lxc_2*cUbq`iusuZc^8DcHn^`dEpv`x#$N4&dn&66T%=(&n)9A9PNX2!W#0dGe!N z{*AeO@2n{Kdmf7vT_h4FO-)UtY@2#bV{B}UX`!H+Hcd@!cx}j;CiOv$OwyvM zsR>ZfG=*d$K_X#N<>orcq)Ag#8@8QxEHD+p)R3e;*hC-%Q*w}=p;6{8>SSU^61}mN z+|Ur3GD1dcB5hmf?F~#zKc*!~NSkK&;Y+wETwY3Q>YF+1{0n(|{U&5IN+M%$;^O64 z8SrTe*WL67+B=%rITGinLyjYpahkwLXD0xyU7cirv3Q*J_I7T)^)_z!_aD&T*N2s{ z%I~{j7@TrsD;Xom1Gm4*__#&Fg!u~&W6a1<5WV=+B$l;JbYkHUyX#nIv8^0zXEmGDd z{8;#9l$`4D>3spgK=&Y0!oiD|p+y(5ruS{W{m>@1B}1GrzrYXAnMad+3)!yIBLj5o z#qN7%Ncw+&eR#h|F`~0=V378%W+r1P=7|V0Ho;MyHoyJp8C?F0H<;cUhaG^@;q0$- zB)_=eXii$>XLIjr7R~SCh1L<49NfjGfk9-hfqDeZ>M&LW z&RYse35^Xfv>A>%nTC+gf!)2x(SzxFm1DkzFGgp#HUsTB9K z>ldAgm2Y1(Fb@T#SZ+uZ7ggCkG}7xvDbxaS+fzYopQVVIId8G(XjCd@vU_*^dT-6J zy$|G}WbvEb%U(R{4(bxt6swjkqGtyPp-~VLk2OwMUBJM&#Zyl`NESHrluuC??LzwD z^_O1ap@;57BzI6q_HpzvOEHWgbX_B?YTWtcU%BMFPt(_zVhTx675LownxirI&_B}6 z_pbd7k3D!AOOITI-w2{GK)^D%>#n;v_Sj=twrts~jH^wXHu2(%FH&ReVq$m;Cof$> zNY%&+15i-4HmY<#xsg5JosyA&loFqqjiT({xYR|PiO1vR%$KQn9A8;8YL%aVKL~8srT@w zfBzy1Ptm9!!p`9_9=QE}jy&^hKK+HyGd8fD^vD}bCwDPsq?p@cQzx=iSzg9Wlc0Vi zFFf`#cm3rXZ0Q@s3z#tv&1#2Bj~Yi+L6tf~y?uQ0v*&TvZLO?Wp)qA_Cn%QUA&DyY+443vX%@86+gyMJUMw1QXLcQ*$nc}jeu8iP*VSBe%a_*2y3`knEhT594Po5m$;l%@eA99G#khXd%uO+o)d-HjYa9_rL2m)l|cwUSsYPZ zcCSt&?~Wo>vf3_XA*re;(|2YX7x@lTquFq6iSi~?v0uSt*7f@?U31BSDZ8KR-AxYX zP*kE(k^{X&qtP-7;xyPL_bK77OEWr_jBxIS{r!Ei!f~#Ym}|IpwR`@K*k=PL_xiaA z>MVnR>ZewVfSDmAL)1zb?^(-dFFc%k*F4B${YP=;)obW`S#W}C@k`O~6az^hWPpf* z)WD2^h(ja_!-jKG({fP9#w4J_n9Y);Mx6zAXfDIgJVGDd5aoRC_=gJ@Ofh8a0H^2Kmt&JfUO_|MOcBsLQW+*LXMar;M zZe|=Roywv`Z43^MFd;2;-RAb&F5=>k+{Kb5E663&)Y!Fz+;nOMg=8|}G!Qb4UsKAJ zL9L>YNhVOVAo)asKx1Rsdc6SnHAp5#35CN9jP`QyqE#dl&eX9^bLg$6X%Y%KV@|I$ zDF`>yNrW+yHk#HV=}L)4KtZ0hmBCWSSkcBK6VJ>sT2r^St=`{5qf+398(C( zz$-2CNTyR03=9mS>w?}s0~LWG4J>z$=xR`zwg&Lql5OJ_dPpZyA8{SZtTNK=glWe4 z@|XXSqfa=2bWRXAB))*4IyA?n{RA1XJjB#SmYlW%DIsrJgpF|uB25)KLg+NLM^RPh za|%XU5JI7&ql1(R9U_ftZYHfuOcka_;#BJqCWVf!3sSKd1tUpUS2KoTFd{AHM!QH$ zNto6)rlnj=R3U6_%}n9nY}3U*pK1vY6wNeC&oc~ob^M|Sd7V_V$+F26AA?-h(N)x6WF#*P;t`Y(?w>r z3LX#amHqAY&uTav>bIaqxO7hU`7I^VXG_SAd(;9c_v=K)+@mci?t}hSqMUj25*zR< zK>|WhEd+T}V&|RxJD=H8i?TZnu6!M$NV9Zup)e%~NnY6QJ)u$%NmutGD2g~<*-pvx z^GE@yREEW($gaK&Uw>#lKfmgueD{+dWy0ztDSK%P1!;`buweO7JpJgeF^n9RDN!}S z(d_{;dV#F!qcPOV+~`3J89fA)0%8{K7JClYJlMO-=ef6h>3AF4Wt+t7@!K9W))WINnTpFjU{?JwGlsA86!eF zzj>gKD{uZEMtf4EkSwH`TGaqMLtJyvcfTbl=(`t1a*rCxvK%ME($~IHP>;vnbREM=)3~JS0Xk+igJWPT`RrRJDd+dE%c%h${M$K5AO#^V}1-Q^}=mOrTZ?QmCMOl~$=D5DW(K+BQ?t(XMzr9{g^D z;w0BQt`-GFp$3>RlPHRlN-u=Kwq;o_;L|i1H!Emif-0c_P6}^UN_Vr~-;re6$WW!X zL1UDmWE{P%mbahX#GJ)#5V!Ve?fdsSbX~_V9Lhv>wApz`rNl5&RO|28RZNx(O{YoG ziA0?9IR*c_D+q)*aN615rjQWms>ZA2!T{o3YJsbGdFV3ay=Qj#}ko-xyO zCWTT;^pNVJ$-;Hs6tkENQc4B~N9gM6#4zIJM(|S~`xvoUKSR3)IbM&TL=<+$V$`D2 z-@l#1k2?~>h%?$h%;F_Wc;JEiS=6zBNJEJD_&7dI1)-9#lFZiwRG|>JOk58IR8=Kq zNn$YvS!`5wCSx&ts$fneLRvaW)05s)f(-I0Z5N5T@5t1ds9 z8y^~lH$t3s!xkRB_Ba%y2b&0nVY#pAguay;UsV-M8`fTn$M<^dz9(0H|F@-^DSHe; z_D(&`AZ5So>w}yw^bE&gBQsA!IzsoXpyAcE941%f#A$o3p?(*9 zkkY2G8-6go8=~Ozc*z%M)37`qk6Vou@cH(?uL?ylWy^i4KT6t^YQX0cHdS(VZ6_soq;yO_gi6dxIF6XY zacW%Exsp58cHZcXv$U&~f{~yGcyrCejP-6{Ui(50Ipsrupto-eJKx%ZJ)UI2{8nlr zIkpWv%F!o$fp359$NcJ%ZDdn9*Ptfq(5qdixh#^LD#;`08BB5S;~Tm5n3*s&kxjB}15ZNzx(#mCvO?nRb$giuu-Q`)4ZhiOaFvf>zI zZ3K@9P;i+N9W7B_I!q&;jFXdLR8_^4)&WuKvU{mlN?(_THvT=i-tV98Fnc3c$s(`} zgP?F+y%sJ%fv^7fKF+`3Om6z#iPS~w$Xk-(*me$I(vGf&85!7xU)8X&QPnV0C}h$2 z^}T=LwntuP9G%U*BXp=@k0zy3z?^2BDxt7-B*)M1*uWK^IgOf4q*$@ zp1q({hfGEXx|yrbchpv4iQW+*mWg93rW5WcO{DE)s7TvJC<5D7(1IFSBz_d8v5D3- z5t|$(5)2XuhcQMIw1wM9Bt{8`n;0A%#Li2C!61{9lW1C-BR-WLBsKvzExv%GSxO`l z)F_UYrA8=a(*=J}p$dVmzy&TnWb=l%>FeDBwv9g+q%G)(<>P5bjGwmC*x1w(LU(AGzqfd16i=Td(%P)SOxEAK6m)_u{#Xhoe$Ffli zEJBzd$1RQswIh25=~OjZ>+9+3+d+#I)ONKphZc4v1vORpuW$P8qt(R3yTyE%Aykzi&RBdMU!z!VVN*0_cnH9}x(8j27!hr_hYYXD$uY>ZH-fejlr zP@@DLogkoTK^87Nh_~O~fNk3(lSy{~qm>JqBuRu2GofX+L<%zh zkhTnTU1vgWr=zwRb_z%ikpJx`Nw)>iuX_t#55baQrmi{?h;icL4{+*dUu4s;z({3i zrIbSL(AWwU4T@z+VzE>?Q{sJ)J7?XSyANF}8~+zUFZ89 zlp%AD8}4pA*HXUV-tM_b)VuHVxDjJGo}yJWbL$_U;42?FohhnV&^`yRF~-XI z4TMxbudjQ6UER+!JUqg(j+Imc;SQZ@y?`kt3l2Gn>wfwG-@g9O)YjJ0)6;|M1}LYc zg|6!ag-TjljAIav=%ftTG??PTi*I7A_X&g;q9xKxJRW30MXCpN^QsGn3S#a&N42(Ow+w9Y7B~LxTU>SN zPkHs;HS`(7eEQ7AIKYyIA|MnFJDL((meGu9Y{#qls}Eni`mrCbc3&O-Lh=Ok$d*BZ^eQWU<+`Ym7QA$dql9*Cf>rF^4JJ(X@oa z8o&Sj?}-HK@CP*-+PW~!1kK?lwh#8AC<@WKu=D@phC?c#C{7bIW!uzi0-y<*wdtR(2i1q?8b9V9GMc2q)RKAQejX z09Ah@sQHPK=KS#JWlYfgIKvh+`yL*U4>fNR&&J~wm&J~yAHYxA^ zB!ABa!6^bkNXccFUB=;ym(V{lg04r{93R|me)<2-QOdHZvn+fgef*zOmvL2SkQ0t* zLkWOCP(%>{(tQ?}t!(1Wlk0hIdyIjB8q!_!9QuOL*(nFO{u52y{ooePKHP_aB!P-C zIKtA1j#8_WQhWbD_TD`_uB*QH{%AC7OS85#dq&zCYjm|G$959iiET(o;)H}02=Ee0 zN@#&5a0;j8QlOOf=?SG=+P;MzXlcqJc!B_)z9$^;(6qtW}v+A|u-w*aN|dEV~l$rD|y(P(C`wSK?f_r_H($)VKtun_8C1x0HV zl46anef!8}7wL(|SuH^}v%oPoAYrYMR1z^DNm*$!nJFq_O;7j{bo92fJe6gIb)6!0 zAB)W#z0;f-Yb8Z8W-+M@CMPn?XEHQY!0zc`C0D=~M(ylrG{pw0h?IgzplB9)5YvpN za8(CuhG8(7%h7I{G-2R*9{GHpty}f}>Zu|^Kq;T+@)sQB(4j*N_G}B?>a^a@^E^_i z1ex*a&>|S-y*zDZl58+b0+TX|Lcv2R$W3KQr~A13o}V(8D-gG|4QREMKlJ)4W?d zY?84kB}cIe*qw2nd(m^*x9>u(IByL0)3UOujBeWSyTz#t6}7&n>eO}-h7Q*?8UmU&G%JE- z6pd9hCHz`*t=DW#u&9kQZlk;W!uNE=)Pf&QqmAws39g=LLM zq>)%G7RC&$YBL|!>#)^T#d4#-uDw6&6{2B?vrgShC2zf9IgNI|sWIF?DC>afaBN+z zyMk4S5)i}Gud&gB(YQbms7>Y|>I?{+Vuei&X%Oc7sj5CjgtYT&;A7a3Rdqk2k*0W@ zMk%pHoSf@2H|p^B-~1`>e(OsZo|)uT*Ifp4C&*;RIRE^MX_O{0s|{0`w5Frv{Ylou zAbGcqPkihMANbhkuzUMBK0F+{>{+#8BtR~#O``~wl}n@4v~}CQn3#<5k@voY-?{1e zbay1k%$#6V<+-pgi5Rpf_#U2GA@Ao%SzAbSb@SLWi_DSY9q;{fMy9gl{VW#@4C2g> zvZJ>X?!E_J{hKU#`hIHy=GXDsGd{W=M9%wXn6W z`>qfFIc_2DXhlRr4rHj?IDO+C@bBX*b@t2meOiPdDJ{07I>G~5 z)J>*;@j~CW+c#)0Y}>9`@M>M!&x&~b(%X|7s?r4H+!EV%_OUdd;o?g#p+yKLT$k3< zyf~G*JeU7S3fP&hxTOPcBhrAr4(=ZE8F}&%MwDV+!ubjgPL6Z?N3Uc>_?&c2<`y#~ zqyw%bB?IC$S&2-$W)mtdIxDNPcS+* z#G`i~qNozMZkd^x3A(yswAvlK_{O*J>F+$uu0)buJ56r?`*+hS;Q7zHj-BZj@=u@s zBt_-&+c&-m5sDkD`+me%sIZ{&YYD`%hNM&}V2g{3Y~8w-&wu_KG)h5sVuIEVi~cQx zxH*jy#}k^)8iW+pR-=U#BVdI<(@zXd`w|!!La?Mfo%Q5_r#yOkdhk4tsa%dA@G#95 zd|%PEtq0Fjl=69EJxL};M(FA3VZke~b!#{G-FJvzJ9v;IM~>0jqxZIEPY0An6s#Cv z7$$|hM=Y7do1Nv0U%Vp>1)XDj#^D85yo^P+TwAZJzD8T79fyzHdMlZ1CgfU2L%pZo z%c~)=O&F|*AZ$?BL={>eH2A(x%CgA&+BNU|fdPK{=%WZjQuG!W9Nf-Wh>ULOOY`uL ze#9$o`b{P#CK-O>IOkpYJo>kGF*i3Cu6d8qXO7cqTg*;O5I=txv4lxxCKK*SE=Y+X z;nGVk=JEpvP|D}8|N6rS0q=kRExhto*Apo#n%Ko;JPH@5p>Gd+?wFvnbAY4YJ_h>+ z`QyKPj2mx%HN`6ix$WOZATVKT7qPO>lq`@?9W`2Em6u)#5oK^sTj-ywd8ywPDw_(S zCeB^6oC%Ss=F2s0Xi7G^V~I`8OHrva($DJA`_;OA*stFQ5vcO1)N)l@d+XO~z$te5 zRR`D2uTzE1y5nkbXoQH7K}7_ZLg)r12q>>AjF?GFTN|cn(u{8Et3v}J1cuR~QSfkR z;1r8cDYMy7I19`meE_f&D9Xhm>*Z_^x}+L) zbhBz$wy4o4_3Lzc3iJw)2nX)#6!8F%v`I<559(>Je1Sm4855QlgVUi;`Ajw?H!r>V6&#z=fyn(*;7^UxVhIY_EdO-qZeIW4 zCukB;N~IEU%O))?mY(%6RGoD#MuW4$UTeSbP&p}MxUNIDZL^SZNLn`YzDtX=P!jGL zn_|nZUjFp9f1*u9$!4cmcFSz(>&05LNp@;Jo4l*R>I`;mN1y6*%CCx ztGw-w4I5e$Ix)LZorBk|ste4;_rXvJX59?w?SjAj)PLvJ+keblt_%2y&Pp)@@`WI@ z?*!9K>Kk)s51H|Cf&hAZx6qsF;E^Yf;s<%IyY4#fyzedy!(e1&gj6a;qbbOooYJ;= zCr{GcQ>Annm@WFbP0r5JBi6#Hj6u>gX*5kdFVB(+XcY#53MhCUsZ@tv%*h1#LY|7y z?mMQL#57Gx`8=2=sf6Cx7K0*D&!bFGvq02*a}_#ZiMj)O{Y5M)p9BialC;S|GOkN= zZ<^HN0g!W&ibUvvf|86O#+IPCCU3fLaZ0hXG1mA zuh=zc8bwY?{`l{{4IJQqO&^EA1)~d0i#viD{<`oG&%I=vhd%c%n&%e@LR;spmc`Iy zColfp+rU#?e980KD|GSp&qIs+*?WEn=0y;AU@9m)fC%O|ao2n3iVyPUcfFq%Uq8Uk zbQe#n46ps8*Q3-NuY22@dHvh}gn#+c-Sh;KuYdbJ{PS0CXYB9;JbC{ZcYfzvblV*a z4Lw87UBupG{;;wMI}x?)t99C!@B288!@Y-o%2T6bM17w}o;=L#WQMQKW$EbXq%)af zp^&2qL93zjk5o{^Q)&bCsUp_!Jdaik%3h$SmIj!HNe~2-@_EW07(yTngQpH3CYDSB z1|`oUy{((f_%yL_f4=X&Lj*w)&-YnU9t&Q9&SZ-5!nk&KHCxE$bq33Fv4K+FBbiLH zfB!y;N*m2Ihe4s^!@~#})%t>v;$c}9qhq5rs*MOKbB#n#p*FOrwNt{B>(7%$DXA!h z<2W>17QXLL5^(Rsk8{n{zeYz-FGEAeSwyfBYS9vj1mFJlx3Mgf6DLME|NQNI=R4ow zEpK@%j^nbWFU^wUA`n=K1it6vd5W7}^g=S(EU|FE$Y&RcC=b_lSaRmL>dNQg%(*=L z#1j;!=WtzzUS%<>=J?_**YTQ<-pf(P;^_BAV7dXe`r!4k^^J$1D+V+7fd_y4=2x-m zJFNN!LTXJ;nsQbaSZz#r_GxcKu>r}b|DQY~0;At& z1X!Z|oO^gx?-fxEVNhRn|2uui;L3(93bpCEo@xLR*>sk!gaaKRbp8rKNEHi%KWa^a z0f86P5DjT1NhXsuI(Rb>PbI?VU?9Q<#|+IeV#y@I&=C1my$dg+Gg?-l)}&PP)mB2f zS9AEi>SedIg)9s~tJo6iYRy^>Tt4sB8kblQP%=!sqQ_!TBnS+eL#LNgNO9AYIIW45 zu^3CC1^t;ckBwntD21RRd@9lKr3}^w2@+@&PzgYrF`Ubui~jA_w)5{eub&0M|u3jlXzZ{9Xl4;+W#^x*#0u!@Xnht+G7k) zjZu~oDf>c06TfcV=-*d0ohiE|S}Z-_FDoBu+swN@l|{*WZ~ZFy>=+NXpP^ii4v zNi2~-Wpto>gVo2uYhKJ7-g`B3E<7=OlD@tkW+%sq+i}{3U{*nkl-%*nAHj(-YlFQc zVoBzG#n8|g-FEvgNY@M-72~W6sNol>GeWl??bx*B_%vHKu3M%_#)$epW;hjSLNYz? zFc~_WaGF#IFwSqP8yEID43Tt)H zw0V5!7)|(CRy&ElI7<1Hluv~K-z|~%eFp4yTz8RG-$w{Yr{hdcO<~2YjS%Uk7t*M~ zvDEm;>rm{*$$g_tAcaLz`S>#vG|B{j^5z!-X}c}2E|Q^tEAI>heXyE%Gvq_%k^lPOZE6yxLLn5Gu$$BZ!e(a@Vs zDX*slo)^$6V2OZMuliScEQem|!W1lcKB?3eJkKYVNHQ}vMx-qX!l3MVwN1q^41^&t zXrWb@EGZ8ZScYzZTz8HpOvY@Y)Mf584sKPh)W1T(z2L#=2>!%(QL(OQrh^t z+OYg$j}NZvU|AM+sClVQU#ipE|GbxC+4b4d*GDGfX!}=R)t{r$BKZ|v z6){6+=N>(IGYdrCxQ{>U@F6yC|MYJaUcDzmvy^20U97dox$vgX zLHAzB9cRS?SIyDdyPw;>^8h5aBhHI)aQha7O3;I((|VMqxQ{~8ciwjHz4tLX`&}Go zhD$FUKq;4@2Tsx*Yle=!%m5d3eF)SVSMR@;!LsL&b9FxFV`@?nM(L`{<*@TeFDf&jxXPeBGN zrb*OC1X@8W0IgtSt$KMxLbC=wbKnog6uGlofPAmF~20Luan4=>sSn$0eOk z*JaFTq(+7`u=?V%J{)ypQLNXl4$PFeK&uc)X)`u9&nN!jpZSa1K1njr8nnfXgJmUH z^?f?~`^h}@IE6xi%P+qi+fK7@-#(Pm<}%|$#~B>lPTtpi_LA!{Kb>Ri&H?T@GEPSr z@aQQY5e}1H_Ocgq?C@cpd+;E3hebpw?z``9ZocMajAbYJt(|FJ^N)YX!N2wzXOe@Y;7@%*|IXqm&5IlsWqPdU^86qomXANNKU``a}dZe=asIdG9pKW`WYvc<$O3{()X9B5;mWVlXEQ)oJOXmVkiCZ;Lr=-x+`vz0 z0-|A)vKdXOQn#vKZ4Mwp1Ir?y5kad`1U0IfQG2{5!=O1~UqCVzrmzc02uU`(NL0bHTVh~mFHcX6(jsh~Z%6uR=duFI-OpxhEd+E_y1 zhvpPT1;@u+T0|eud*K_o?)o>P6jVyO8h6B`GbG z?-Lbq7F-|vGEE7KQmKUNmf64WLT0D3&$>C;NO{!FUtKngI3-=|AT=F|)Wwxp<{DCOe%E=?F=*kD1^hAhZrrotPc zIwf?m;+D2;J{QePgtD@#3s|smBC>*F1(S&Kaa@O#oyK(qMb~FlJ_U)V$QSbD7xMJ< z8mItLsU*onl0-5A1ibA{Z{iDI`zrB7l1mR>Ntu+HTe_b-@LzMV>R2?e~(5;ggntICs%K3s?LV@S&kn!eeaherr&s3mK7%3%Wxyp z6YYZUpA%8}Rb5SWubu67&@Lq%=3eGT9RBf^=knT}d5ZHct+Wz-Nf!;$hi_SY;w#5^ z-Tn^p{xdZ6Uc(LV{}|-EHTPipID6D0(l;sig3OPyFs}Ii$9AxL_cA5FpEdyt>LLn$ zhL{*6wcX~P$L8pJ&iN!vi?(!{-8)~(fblk5BftwDMg*{; zQ})1_p5}sq0iHQ_jQ$-vm>3yh$BwOxjEvCJ(@ip&U@_;BN~M^do<<05W$JlFOf$*6 z=h05Ujtd7cO_Q&E?TaX-SQUcNXC~?E@8{qZFRY<^)uLL{tK1sewCt8xA;7Y%4Os=E zikQ~9M5?-jS^-HZnRYUyEM2s(AZTrGXE-xLcUK?dxrI6_PyM(L-g6IopL-FPTzMs5 z{_>ZxtOT=#0{7l~FE`xqaw1CMx;_yUC!9I9@3Qf{1-^C19cRO~$E+NJMEpP-GKY5(za)D`J5A{)We|>QB~l&Q6c4 zMCzKDsa_Hl>faa%pxM+;d_fRUE_###t%K2xhz_IH)G$5l6hdH{CWav>6bf{A zch`P?^J^bvU9S>^4N*Os5(EKlZOO3aFls2uN(h}*@A;aBP6%S5lc^|pEEpa^wy4pT zaL|VjU(sB3{X$`c zL!7c(BAxDJofDZ!EX!h%Nmg7z-d{&#L4m8! z_qfm~ZpxCZ;9}c)Fw<<=%=n6SX;JV?7(#+5vr=$ril=DGEd2~k%IRz8#u^$3(Z*PG z-Tqd9@0V-N5LLUp>V_(%ReNLouuy0UC(=!4fK>F)>M5EK>n;htSR*50)o-9lNPNG6 z2n{G@5EGCPX^Os2L{vpj4K!hpls1wmd9_G~kf@N+xl*?n>u;o_QY`!0J)}T^h-}cX zCtWN#in6Sxv};bgUgV}usaMb`4XvB7BtqI$l+TKCi76FAomL3%X?LRPG%*O9J$0Im zq<*RvsXOFzRr^Tk{e)1ExBrL{5YFILUrMn*;`6`sOMB{*{AA)095iH9B{mFnQZBM;GxPPC5%gbQ7xKucbr zsb8M{e8-L*JoL~JIyx+73k8}GBoY>@zNZCoq6?HyV8N0vS#}jy4Fr7VZ!aNN@JX7x zS(zitV|}-uFSwXYc9N78r&7yC zIn|EXb?33Hcx{km+wHinig{4{hl*hmRcLv$y{Pmmj#4>60gEP8k&N z5T=Re1r!R?ve38y^ZPVIeL1!k(j-aSqD#B-lcK-77$2j_pS$@4Iie*X09EZ6%hwa<@7`)&-gb;lB z%U?!Hlbl;%_xAHhclGn&gAdZ#-_L4ze%p3GbL7aIeZ28?3*0@sMn&oT6cLYc=-bcG z(~+RtUgPe&o!WCd^n>p)_`WYtQQ+W{{+p*^#^wDtwDJ1upUcA76eStZJa3Y+rYNV| z5%WV>R-7>;-3XRd148&@vr{~9|DkZ5`ZdJ#Ook%$jD(6jJHl}~%|X2mg0p;nrhV^R zmd359vr@=vN#3Vvr0N?C>okoGmbIY~SvdpJQvF<&6)jP*VTiIAA~#Z6;QEjhNJCJ} zD`ZIBnw!egyk&((Gl^wv+0b~|VaHJRJX(c`Fpco+R5jahr38sY0;K{B!=Qi57AoP; zQ$LRWxQf_So0Uk|2pNW8U|@hkAx|uk3{e}iMs4&wFU-smL_A$9M1p{_GC&BTra{Uy zXfq9#f+CLR(OA^)@tOfrnpp8T5tYVqGT3%H9Eh#E&b0_ZNeE2erxe-?i)a*rhH&qf zR75~uUz&1el157sAa%Z*5DZAk!^&jLHyDh2%%~Xi3exFzPGZp`d@6Df-*>ewy0sR9 z1U^DoB&7u`>P!^h3S$g>8l+&whZSMdQ5P7!QulFnh$q5*1L4yoz_MaYJ1!L=X_Piy zVUx2Ix`o9f(Wg1ElLE`$_y|)pcReV-`K|`m_g0es@(T|{1G6<}IxYD}1 zR@<&MQ|Yv}BNswDBsNM>quuGCPCbkiN>CAsl~4l|ji?5cQZ$Ft9;Fs(tl1Nanrn&g zyDYmdzA9te65p?i-_F802|HdXEtY&=d!k!fz}#xvI8Fx3(i76^1i4jO6qV16Tc9EY zF=bK_YqZ${$H^e1WGtj|>F&3Rs06HtwNs`hEkc3-DWePx4>LG0faAEd+Hr&hQNJ7p z{8c9jV#794mH`PXj#2@mW22-y(+DAH6bj!BsX3zB1qwuTje10}IdtgwxeLv}BbUq7 zKG#Ty7OLg*9z8uNlxkpTe1z`qZA^@eV}u%#=j_?d9pC=}sZu;oe9G4YpO)6VNfdgB$FEEoftWxCoD>lJ36b;r_>grrqm+lf)`qS zn)Ibo1cd^fAgPSW5OPCZ29+?xpJP(9wY?_vmtXyo{LbwVNmTnBnRksmAC8Q&*h;tPk zzj!z3x-M2Y?e={a$C+nvaG<6E%KAQ?opI>!fG+-@+aBkd{xmUP@ozE*&y-=NA4cxt z10TPRRq-e}ae%kK?o;3?e)?UT%ilBuN|02;_%a}y?FO%;(ZnC#2F!qY9)J47A-p$U z!k^!~pJ0B97H^W)o(>wUDDyKX7#vI^B{;=^c@}7IX(ONafPm(P23o}$%^@1F$KJ!S zpZ=7aZhS44Ws&!Nnou?2w^CK1uC|U|avW^iMx;AYzF*@@&&|2C+Fjgx=rHMY7rtKr z(a7-75IwyE%zJr+fMyKZ&7>ZXBoZ{D=uM?q3ScTX$I$puwr$&nl}gat(ZNVa`D%o4 zZ%X2Mc?Qh^R1gqP^^nWu=o;u@W^9ZFugH!a+vp_0e7-lyI_eNnNrVv0t7%^R>fa(SOEfqcx(3?esUhgNln?&%U3~C( zgzvxh02j2|G>r|hDkWtEi%3eo$*MG%SBe%(g3kuikd3(`;@ra!b@neldn(tte?j%J z{Bt%k4d*~6M_}juWcx*T&|_pN5cOUiWTM5_R8w} zv#KTmG@n6HQOQTR|ocCy)2+oN5gKmG>b`v14rLiwb$IX zZSuamVTf4WKUb&`UUZ|P%06u}!R+KDsXe=BlnU3KA)QWh*EfGm&!A0T-vCl-=qTcs zex^xk6A(C>Vq&G!IF5^yHVc_~>~tE}on#e3lMobrpPcK`C@rLAQBjH+-SBfFlR-*o zw!l&`EE&gf7HO2#=ER_h0L0pc#UJ&xcltucWzX(?_`aU>IZhVKis34QrVvqSs#_2% z;bE0^CP-N}uIn;5(95b{)}Hp#qEXsm*pI036we4{on1B8lr3h$U>4r}Rc76Z$^$1SE8`JnhVr$7PGO zND7!4K1@_v%=;OdgwGrn!|Hr)`%adB{@#zEV8Qedj~^K1qVx{dlr97SdiD?S=-qeM z4wj1eucqKX<5lHn>(p9mSrZnDhwu9_be#tUw^k%JiFMI!mD+LU{puHQM737KC!MzW z!*{=%r$;8Z=bj&M^ypD6%VN7_Yot{H2^*d{&fU*A;F-|Tt_x&wod5mNS8+}IDko(Z zTi^PBA<@rU-qFluRskLw1=C_jXFD_VB|4Oa82$-rzvMlCdNZ%wwS`+h{XPEW3sd~n zCy(&98!w=%Gseu&Gc*4bges@K5nw|^!KI)ulcc!KL*{Bq{!=XH}xl?n$afeI&-kKF$-_ucoC z(0*27+crZ(qqL>FxcWiGws zYF04VwR0cyLn`>Uu#S@u1z^zdwmkR}KJIzNw{&7D2iBIwM zuYWz{<~MNg+N-qNpp?wdIW*Bu*~{}6|MO;)8b>J`r6jH@)6#VwuB*6c*Io*fCDQ3W zGUYU8mm=%ONZLBT0cnSX{4RJr!;2sI3a`F)CvU#dqA%V~x@3@cOO$+#s3=ZPtM|{Kk5P36TV&JUTkrm*)TxMy zUsvR>R$DzooFcfFrl3)3Qk~CO*a-OF!gJ&6t3r|CmnjE zWY%@bDT6IiG4D7eEeYll8L`Gv^?oLFKobyCuqb?#>+4~ctC>SmYHeD|TGyV)TI1r= zVo4;5%;XR$tM9C9Vky+DSe6x{y^^9*%uZ&*ff^KD7k4sCql_V?RSOywLZUMB1O!Av z)I&%`%CgD(3fEP%*IO}*H8#haD5dG_Tl#vzqDD6tLXfX9kk;2mMGy`f_2*R@b#yb| zbIDmG-Iqp6!8_jd`+W9a{;@XItcZ>FpPL7gr{nq;l~0@1&XVKe_&#mvL6)3FY`dN5 zOcu-PV?~v*WSn$7R_i=hfK{dF9*Fbg(PLb+YZpU9N5d(eAn$AUtl=nfxkk|~ zkxuuLa~8?_i?j$qI^D~v?_&-Qt_N)?g;HgT3LWSO3=ZyRmOws$Qm z6~54?5ArZhqfx0&-G0_9Pyq=eNhIWLd!9#k_cjaz+*|>>y9cE-44cpANpI_>RPf1q zvy{DnojZ5qc?Eh>`cN1jKT0lllD#{3lgrH!HFcn)=Xor81sXjq#)>79G>6U5Dmtfy zzyowB+KO4Vk`x#QGzvj7X%bO7hb8b7M#y_yQ2N04JP$M6SWPpDph!i9;yI-#xH{>y zx$0eBa6s5JA!xTP)>xy#(R!6uJ55?BO1|V?r^KKA>%%<#ttiyz;J>c_Jcx>Ir#U$~MxWJ*<7)9>XJ}B88zs}dc@k3To?7iwjjy(81uD_FU}}I^7i(3tFtcG&jfWy881oqz=;YuFf0yC|Pw|ic z^e)`R8Mf`}XK3hA);iLB_DlEk=GT9NuN?mnSHwF*3be~d-}g%X=m(F$9m9O(j$yuX zuLaL3^3MJ3ylSwK&h#2FB}mC#JUuy&Wkt_P{rp)GkNRdrh;`0;{l95CXTzdSt8ZC( zmKv6`=~!0I!ppDz+KQ+;maf+fBD!u>TxDw1*Ic!~$xeu1gjzKFrpN5 za}Jf<)3C$B4+_i{JnftpHXzFa8r8-^zrN%Pf}mzEEb8cU_2U1kte}cwL;?lEs0(ux zRD`j?U$RQUt2Q8IuZRfgU&1g5Jdah++h7dbTt#g{JxoLeRD=-<^*5SV6ziOiY};np z)#euqnRzNg;Jb^oh%${bT4NTK>KmZY@iR}-)z?R$7Qle% z@cz*EV6>KGUlCQrK{4$(q|<#wl+Hl0EXlOv&?uorSWG)wz7WA=+Hq+S0bBa|Sa#3l zC``5LP#ttMyoAr?qN0g0g5K8J?tZOlcuxRd{S0A)W^)lLEY|Z0YO7btiEgpQVz+@bK7% z3h+9z9`nj(3+D=9Uk)F>rs%MO#bCB7ff*Vjo!w9^rX$)n@k_01nJJNXPVGbd;Q z4jgz6%eLgwORr(cap<;p;<_cIgcS-Dl}k*S8#aoS(=gBsJI0uk1q7{jnsyPzwl$yp zn_u{Q9LHgP<^-PS)6vnv&b@otvu8hB`uZ3enkNK9`5(L!)mNekEm~U+`On9lN#Y3B z>^`l4tD8#w*Y%$dQE?oHzP?@-GLzV8jffpRI?PgOiPrZ#T6+(xka0CJxFUY}I+`ji z*0L(w*MDzDfmKa__A=bG{~}(vGfvyS1Xm8mxamDl!CV&~z2j;A@HfumOSgRm z3MO>e-1aATf@eT?91?4M>`O=S`?I{~L(k(&_mA@;*+`>5k8(3a+jqlr_P_%r9-EwE zg^RE+*vn5J_%2F$JaXrc_||nl=J_vr8Sbp&1Mm9)U;oY{&};IckKe}g2b0|R)_3va zBg6dU@u$e=6|Z>Jt7-!6`a#sXZZSk$q+rQ$YLmZW=yFvNFf=^Q1BVY$a2=N20BsQ1}Sx#P5@@tMxp`esCJ`i?lY8K^H@&qxj1{Bx(vP}w}1go+629=qWbYvYPg zG@YSYsc*DSNBwFnuRrtUO~rTpzl;UzkH6mh=;mZuDH;QxVxXfI7&`$*0#BGstAJ&1 zfo_^;GYw*93rZO^qypCSQdT_=6-E_Q45PL;RM6qP_05V9A{5kz4q__UpiOD!)U^6# zbPlCPP4s#Sf&gKfv>Mu?xGLtarpeBNUbwmd|zQ%adOTgO4_8QB%8?)k#*^hVUYFaYua%TLK2sfRo^Gs z-cEaaFJ)DtvvUAYl>7!#mH?uh$jq{(uNT*K$hp3@Kt9Wr3XOAwkYPN5MrNGJEL+p< zl%=ILpi$_+A^;*~ZBJZ@O7bOG$Yg1@Vp^y#C2=IHzFTL|&_J^SRD(tg%j;_-9~$9E zX#qZ&OeS<7O|$Ht>S|g;R5txt(MmMR(p(|zexms9V$Hc_cz7zza#+9NH2UC&w!+VD zBHEU=QOXSuvKURQQ4xw{Y>gvhKjzKvdM6XZPwd&d zdpEh-OU@0h)&F3*gv9srSbS9ImC{6JQf+D6V!p%ktb5)>f+(Z=^dis-_gC1?; zXR0#Fic(S*@BQ@Gxbq$dL{SO-L0Lp|vb=1Vt3T zOs!FMh$E%M+2B&7Z=@M%k%)P~C?qAgCbLJEv8Bt6S8wB{m(IfD{e1A_ck%q+IFFmI zYh$p#g+;MO#gB5Qy#*c}10~=hn=20N zt%fkj<#H5@MOFw9LOTu#VG>IwSqi7Qt-`=GlPoEZvRBQbTB~i!>qyGFZY7yCStcN# z&vSBg6d?j6QNH`luMm-v-+$9v@O__(5J**LHyq}_TrjwuvRA-$=g4Fx$Y--C<JvL3NZSk4Ue1=OezL<%L304R~Dy2!$FEBYV!Kw1t17i$FE7Fe8W$3K|N}@QGW04|((mYdiNrM;tuKiQ!?=!smL+X5tU` z;=De|SMQ(YqxUYN9&@4KlJ`KV64*I#J8BI|C~K{=x&C?9?Xx!sIXjwuI`03uP!&!= zRnE4rt(*o?X$md9D?$sQ&*Z9jw&7=eozY?lR+ZeaUp1jMDqZO`yKj06v+h$2SRJI4 z;=$Zc2#Q6N5#Sc`nC6xZ4TY#qx($P-Gf=APbC#-;@eR~2w9Z5bLsPdxb#;MyQ@ot!4|$HNA>Lg@fL8>Q{-aeZ8E>WNHD!QbcRD zDy&-}Z@xbo%b`ZaEwOvw4vfV`jyo^7Y&%VFJWeZcV)zJO z{K7|>n3y2mA(<@{XcY$Ou6}I0pO?StH4F~4F*>H5!gMr)IwvBzg2J|JlyYd40^e~t zudkC>EQ(ildF1}PdHT^uYx|yC@M%sYNT>VRdGKZI+qaX6>>{q~(rs(=fq2*iT)&^RQQnIqCkBBI33ecoP4OIk)mdj-tr6A|J*tSGU z#k4a)I&Bj;4dnc}(1AlAP(IKUI_^}$H}aH)vO!D}*Ww#MDL3qv1bcT5@P;?s$dT`V zm3O`E26o)^JhGEVX=0fbmdQ>`5KFYNMYWLZFldxTUh~Q{@BWKVa`7cE;>c*0wsa># z_;soD>&;5_ieu6uEL?w)0o&py-}zVG^S0OX+Uxi8*7v-cHD?&#U!d&GvE(fyM4X;P z8|khza2{{J`4TRF!S#Ijwl8tl{YS}%-Kp=pv`e886+>%O^r3rd$Flkh67f+ zzmKWh9IZwRBO^yC<-Hm`!kf<5O>hh%%B#^HgfMFp&sL*_idg&q*gNm|wyyK;e=*Jl zaWBXVkl+BPBx+mokP~?&o^h5_+ez#U&ouFyIKye1(Kh3)>o%j=&1@1oZI+WXPSPxA zIK!?J$Cig=TaqP8q$qKL10--s+za9!0DS*A2OucPmJ=s$`}XrfA6pUy5*HWup7T7< zZz1cP!-7(|b<9Z@3#;}#HI-CuI+M99U0vOb4Ue&5!+Iu$m5?7D(&l**Y5GJkSnxb7 z%Vc_H2D;To7WO0wQ!tpBVeHU6zx>HQXnPT42f6XB=Wz4+d0JXJFs^z4TtOf+N!c7E zFAY2?X|YpeG6kAbNv6{ytV;E>kSUzNg8TnJ{;MA`Az1XJ)5FDG5{Aduphe{&(*fcRtsAN|-E9PZ>zpT3{&ZEN_@ z$9@gI3F|YQxhBfuXn-CYnzn5rFD04T44oUd;>F?ZhNmnORf~H;mHJ(ao!`x}KTo8NTw7nH%7zW>*zq9cvZNx6nlqrHkf>rKkx1wQ&c}5nuA8N;t&KIS*K_ZV9W)w(;o-w< zT-`-QERh+XCZ0$z=T6bx-NW?s483jLWOJUHq-L|ERALbtcJADz8VhF`Nn6z1ZXpDVVjd}BaPSDe zKh1e(UO}Rxg}Z+EQ_AHsP$3>@r&y7QK%T-y0c+*N;FG_gAp)7sA@~IE8^`n1Hs$(Nf9i0?`Cl39Fpd4ms z*Dki0f}qU6fxF?PjWl=kQWzbf-IREG!I`lOmFkfMjcuJ$L>9@_U)t`fN_KmdNMxbjM-{ zVGysm;2AY)Rn;yz0$|0c#=sX@*09uDa7XGIj|Cm_D0NdJgi%9I>c8JGltv+HEIWf4 zhN5^b0@0c+vaiHs8sV+CK#tTiQY3_Yl~b?WSN$6L+1}g3{X2Kj+uK7>N*a?bNa>Nu zs1VY;lq=|X>SLCAEf<((h*P%r@S^k1r({`t@;g5uH0clvhjl9ZlMT2`8cZ-H__L#2 z_LB1n$~4zs^>PxeIof-h@RCtNo@7BDK#m;dva@dD`nUca*SzlSJhEqs#$*p=FMWdj zNd?fR(~~qNTQoDtrlX^Yn{R#>gTMP8>sNKNsicVj1@d?!!+iULckt<)(A2sa=%5AY5Iz;>A>Q@&OL+U+uIH}1zQGyWPh}xf z?3>*OlyHWX}K>Y+29k|MDr`{pRcW*N?n~Eqxxj!EZ4s11u1sV8tj~NlNi% zW-*xZBtuS)_uu>qO725kcG;Pneg3nVo?jLNmA%q3#3_uYg)sdg9C%?^7{VeNw`yTz z)f;tuY^lhKT@ku1m9(Aho)S1u3bBC5oC7QFi5u z25Avr@wTP)Q_$X%;;e03=rd^6mA z_g$D8!VF3uUr%I}DTpc}d)m5akH>YR;40B&Hp`*$aXJzSZB^>Ce|Ui5;ls7hx~;8^ z2Gjs&LAtuYhj=1EA(vD1u(mcV%VPM@Au?lQbai#tg!8)IIjZQCNMDl6W~qoJ%ASX9 zn=CpRzWn9Sk;zPuY)N9NoHp!S;(aEJdf$oc`kp|wZwZ<l`dHgIh6A0Afdniy?r#LMCopiWI)Et_oCBNl5X5l=8RHC3|`HVlK1WvTn$_Z31})0imcg|F#h5jYmv(8sx) zL@&wb^G_;rM?Y5`ud++_eV+v>Dde&QeZTfP)%Vq)|85xS`C%(Y*oxunb5p>t`#g+V z{W3K&%F8af07q-_mb1oMYU@Gu8acWc7h!cSM@J|5`&(||b+3CZnc0j+YXXY;rDz{=8KOZx!N>pc zEgXLQ9!}fT&FNcK<7Z}{7UG|mlE!2cj+3D)nWU*HiXCYnd*mS3KJQev^+icCNh3#S z;Rp?KkXAWDuercwCpU7%S$(|h+3VQx%b#%JIVZ7q=N@c3sco*0hZd^qtRmnepZX$= zN!6J2_Vyz6UQl(CtkS!yD177?DyK$Ngiv1bQc85NE=4I7Vj$wRiF3$|QbDCf$`xte z%Ttfyu>?W-OdHRGCo+$-Ir&_ky`hK8&)dZRdg&aet&QTRcLD*@n%mgh+eOsL0)m`$ zNdp!!%DDy_M#lN+hpyrU*T0=2f^#mviLs#!2{VciP?jY<6*I|t^EB8^Oh}LRE!+A0 z=f6Pw$en!prf2imzTeUv@1R`D@1{a8e> z=y@1*Deeg@?M1Hg1uRQ|6(^{Z+^4g-8l7rrY?$7*ZWavKKYW0AJg%D%A0_NkO=F`F zWOM50EeZ{vx-J#XJ)NDNqS3HO#1mw5S&Ej*oe=`PCp%(Vi{z{ z$C=DdX{1FZ(JOmGm#~$JFxpi%TOCnZ@qL4$3Q^Om&Z zTaF?S#iAl|if1WJq?`gAKu|6ODB=-95}}o#Tmoi@Jc*gYAJC8fff|ng>C`VlMO!6C zgsNmBNR}K&Cx@{vC%U56v&SWa{2e_J?@!F_Bb9p-ruI_ zwNV63%t0Svd1-d>wiHm)Hi9Tu^fm7d;s72g_Qjc8du-em7_-$%d>lb2PycCn%`D|^c5 z!W81DVhSR{q_;O&6Wr&eM0oJ*i(bVCZu>l^Y+27@E{E$XWYrMbQOh!DG!*S~Xl$5{ zM1o)ab`QRPy(ucmjKK4yGT=dclNly-8 z+x<9>YK+yiFaxGZ8!bFMvJVHz_ER@wc_kX7Hcdb%5Tv|RqRD^-A6kqs8Qx_(xV(o0k3UXc`c#Yri^5^8lpOTp{P>)9w)dy_@%ui^x=S|DEHZ4A zf)QKdr9JNa?eBQ$W#Rl-eNmN~LzsjH zJ4(b;nFU$TsSRwafvNTMuA>nZaMg7v1^JRkF{~&{5v?JhhIZ-!fG_KsA%#j+gsLe* zmcYqXUthAA%RsXUMvgJp;fyxH-rb`VXvQ#_DZ5}LV#+xS#dg3F7&1Ub*AYVV^$h)f zD`E-X&ua~>OQT^Cv0^&JRejws1gYi((pTCL^*n({Bor0Qmoy5arWvhAJ}bgt)^%yr zx|oVS--|%dRa#!dPzcb1)|v@n)kfE01AHfsukDW;lN~&^f1)uqcWd zg3>060CIKcvP)Dh;Yp9y{vMk8*D#MDDkZLznn>kxfmnm-NlIppSqWW^#i?teyz#27 zM8*&D;}2fTv~UT^nv@hd{ZlbcKYRPYz}e% z6J_R^<#2iuE7d{RQw>o}REKp^qY{FwC+SJrG%~>{u}$3d$!n0(rQl2v6b40MFpDx9 z2{MNz=1G_pAVt&}<*OgQfp`ARWsJ{!kV{|pw;Uc=pjmc;ol_*qxR+<*=rdiDy4A(=Ue;VPbNs%-gQ)kj>`+Vi| z-(_`If$f_vXFhX?j3`nNjhwyh`IOC8_U?R`3op2W#$<|$Fd5$e8}{vZgoaj_lT(b} zyMtf<{QYcr-dlO>lIuyOl;|lY!n#v7bU0-b(kn6TP4L`}J^a}_ZsbQFy#!12(b;P9 zvtNCYp0(F<+O{6j=`zCTq_<}iQc4c&{uSx;F5+g9k~e|pO>z3^tGNH0Kjo+2|1Le- zwjrfYvHpY&PXKVn8P8$=z$hI}HghF!#YrvJ1?5$fXBFh7l19~YR5u#aQx{jfn;`;a+`RItp5r)O6w(YDgtAP(V7Acp*9YMK}6mu?(LcL0hWwD4`n~Ye(phc?9 zYeBpB;CeLJHbqB4yq+^pQ26})P1o|->r4D_X9Ms5`7RDVv=2BP#96%LZT|+RMESyV z&f)xR+n5;HO%oYPW|WZTx<*ASQs#~`6|390wBwx+f{O4cA(cA@Dx|SKWa$s#EB}7f zg5Q6ij+|h_J<-JOnSTE>eFRYOSh3L`;_&u# z&yPIndDUX5B9(`{5aDBfW{~CZ&5#);M3_(=1TImbTOl)ykl__YO?4A`>G|j3dGkb2 zIVXZv71zn>?Y=timDfMFEvAZ7_pYJ(lW{TA~>vxGh9-@J|;`|d@`7!geJ0va{abs(J~WC@x@6qqI1Y7+81 z#s>G%+}X!TYc~^>1}CjOg@A42T1k?dPNBiJ*;aLb@=84N$m2AuvME~ve;k^<3~fy& zt%Wr-ZZsK-CW*&eaU73>2M_bR`|e}i`t`JQc5?syI{=e$Oj^Vcjx6!MJ!#&1&omF+ zbUUMWT#YfXi?yV9{WpHf_wEVs-mfk4txr6kbz%oi7#QAZxaOh%kpq^ho+@Mt7BcfR zXc2QN)lt)SRjp^AYJG}eQPc=mENoIJIF$8jBX!h5HH1{4(!3Xu%bJcFVj~Iq(1f6( zgN#F#35ErJj-Xh=my&36GZi67B;q(M?@hiB7(Nkc)N~;#aMiDw>8xz9ovK8wQM5K?aDPRkRavxI+4x@JORw+W^y8Bq&(*{BOnl19OV_%Gl;S+K-^$PEUY7kdi8w(MBS~k{2ASTth=4b;KLvYY>sE97|p3)TeZ|LB?@4lIkm*y4M zU54+>vEk&?c=++Xv~PMACv7{6vL|Wil`IN@&psZ0{5Nb~+lAxgh?(tt?w|jHzSRN7 zrX2Fg7EEC>jS7@iqWP$nM5qCN%!IyAQc^pLSSlPoeZI~K8b|t-2?Vcl} zL)`w2Z}PUcy@i2+Lz+2Z*RI{La-}*xWc0^)OgoY_8(P@AYl>6XoWx7saTQ;_^(wL> z8DNePZ=RQ2^#*SJ%Fj9J^cV4p8$VtvK0GPee13|}+h4+uzj-T58H1!L_|fg3=Nq4R z1FyVrJwJPRQhP-kwPGMIOPHp>ac1e=vWAzRbq?S7=rzpA9R%c=-1nm|a^-7Y#n0|G zST)&KE{)b6&(}czB$?4Xaf^WX>ZRhyJcEy1Ke}{J;UV$QaPz z8{ngxl;wr9qIskZuB>rXj zNu!n^in1kaa9s_F8koXV4GMzUnTguXUPKU(9)?g80|$qpT@PU(c+u7koOS-G?4B=h z*PVO$;`jEciO26oc*E^Gx#dGwa`8Fsa6K@RM4FmtOiCJo25Dl7FeZY4I8j&k)CbUT!ba>wXGktzORRL3tC&LNnwTby zb=d?()f%gGU?B)$udq|CrUnZk2+0CbO-rZ-UWStPF_YS(iy^ai{*ToGH1O0xdG%D5 zdEIa=|9oX-E_6WWf!%xf+HE_SnVBFSw>f;|2(efK%ZgFRW(n#wu|ZQjLY76sfI`;g z?z`_p2#ahkN9XERMR!HgW?Agnb3oHd4cgjT85Lm|fvM>Q)IJ;7}>66CVeqz~=qzWeTDc6OG*!9m*l`gqPc=O{s_ zmmwk))i3Cw*9nO<9ZacE%0GYUU)Z$e!{k?+eDPa1 zv$^v--29g}^YHH7tlGGdP3J$GW~+;==iz9Rg0@tO)}|)@{q8%N^JcVzkxQFx(O|>m zk%Mg7^ei5E?Lm9 zb%=L<`5|zVU?f=_ohO7%ha=c<@>Y0a6mltE^;h5KfiIjzqnD-;R#?pb&v+~=*_CyF z7-@={fHtG0hFC`JN?0#2WMj9|E8po%;DP+<=Zoyi$3s!ZB z(w{_tiq@Ja)1IoWvcFW0AGjE!ENfp5C;usE5qQthv4<0feG9(s5Ms`s4t&e&Qdv{S%jyNk4`` zBZnu(x%BEcF)!lWy>mZdFQ8B~xyTu3oW=QD`$_M97?T)t>2ZqU5a0RwrM&5NFXwY# z`YyYMMoFc5h#>Lm2jW078KtA6iPfnfci#3_j1KOl%{Ix%JWI*-oN>mvG}uWd(*>$* z`?6@~)H9yN$jH4cWPZsSyPqc>xQEZ&@>;Hc*Y)gp_&R>GYd39nidqJhC}`SSsrK6S zPKfml%5o#48j|N<{9<1Hs+V*BJrA*Z;|7)GQrEzk70#Nj`l^-;)#xyb?>H#YN` zoBx$-uj?hBF4q>RvoE-kk9_i9*#6wtbHSz8A%&XSl}sogFhvqfc*%8t!N1=82D)v7 z&ejC&rjN)@F*Q0$o2~fk$||l<>*RzGEY1fAWgnwS3Jy%nQLx6i^aWS*^>5!r=X3vo z3ogA;!BqnCs2emU1if1>=ElF+#`iw@ViKl7vsfaZ-p}h_eFoqC#=mg-1(&lZ0%{^M zo<<2vn{b>oy*<55?BCCllmyX2Hvu8E1BM}p`I4d#we(F<6AxAYZqjIoWhmLF7C01i zVcyS^&-*oNKR2&Xj48vQ$uP*|^E4R-(S*hH^fZO6i_liX*|{n94G-h{KB+`I6$345 zUG^hy#Hg(|MZkCS6s61P=qSz2G4lC5i9~|3s}_%N%m4(Xyj!EE&CTT%%A!Sb>SseN z7NgO(@MV@3E2g>XvKI8C3JamQw}!gegAz>BX5LGa$z(`w?5DxDnL{w0o+px?WMeAJ zS(nH7!gX)rkpcLdul$BzWq-|)BZG8Zx>?Iz1S)RJWJwp=RsLz@sKRp@?T{;q(g?<~ zyU%}fi?9<-gd)%I`%g5`kSBm?izny<%0Nkq8ln=^)5MBKw#a#4cr|Wu5lL7|wOmU< zSw8i95#q!?^iSPrJ++l;bsefUA)YSgD|)dFN=Z?RqKkEnOm#9}U94rDK(+qWJWsjR z#B{@R;7}h zzGVY>DLJrvH{Jagu;>+tno9&RS#$!JW(x&8iu3U18(z)pufKw!p+h_|G(;wo!Ep*) z_Gd3=@6G|PdGi@;+tkASJAc9#ZoL)55q$8LZTPmJF&S2wBOOgN6nq?~RBQYP9v@=M zMH|>fBbgbGjhp&-?dxtJH<`vXZLYiS3MMCKNhO<@Oe^TR{ zgv0*v7+Fg)W13){g)=(O)-_S2Z}6S({!AlRYSKPEJ;O!kTuc$zVrCd?+Q>U^{WbVW zx}MdQ1e7!JmH?^pKnwKuLJ@9k2KjsJt270)Zw zh6XWV;^AT2O;lK-In{#a6^;@O*E27qstcM-VnX7~J2aF8BO@6M159%XL0@gi*`QJ8 z27{V|R$dMwbnZvlgQB@i3#(Z*i{-W4mlEOo%=uaJzE2`yA%sr@2Es6uwg#V|46rEt znr2mqC4C%*7FVnLCy_`{a$UVb z6}18D5)G*LQ*{I@YZl1y_NA50Vg0^uoEY`jXo@^)3y`AfN-J?o%8hcn`vhq?S001BWNkl+6K1~=Sr1DVV$QijP(Ny3bh_2x;XI(XklKhH~Fx{k7wrQLcKi(-La z|9S^AxlO$3y4O)(XT(IcL6a)Hup>!J=X1$=yNTcvHYMkuelq{`)!TXAB{y)`nP2{V zgtA+ko_Cm@AEF~}GhFa!5z97$i}lcF?L04A)l~&>>L&8=gvw2+2s9ZqW-^ zgRO$&q_5yU=}T~3h^J_?lg#cPppt^t{(hdwcr@6(+_C!}-n(r(xt&9Vdbjg~{j+@X zpFc|;i_8D=HGJ-t=OPLP3Zp}mG69MNn5RI<^oR+QpfqZ!x;h7%2lz(dKm!#r>CnZv-5Lh9gfKcw-UJ$7S|hG^=n5@rK$s^glSUt zBzc`nEu|zY1rf|Y%I9;UK)m|K%By?5vKDc^=GCtz>$xC2>7{8)_H$rzgpe7~l%Wi3dwN*gnquscQLcZ@|K>xV_%JVcVTs$mdJz>v(dQx< z%(*V68^E%v`4KQNybrsr9na0v+SWl&yqmpy#<~3J5AmMgeM(#&%7y?}^>q zb=NOwP9<5$WDtg+drg0Ba8z)1Gej>OFkqF>*x#JR`nf}!ound`7&>%_bv^wo%EAhIWxYm4 z2!U5n0ecncv*?v*UbB&M*rtd_(Oe=j?mViq7*AS%oBN`<5>_$pD}Fbpsh zMIDV~9*bZr3*(SRR0^)kysrkb;h0s^;0S$VFZeDExa16>hdr|9P&!|C-y4>oY$(=9 zz-NUOvN8w>Xlk)qpP!8KTg?cmU&|{`SpyhkQRhC{lH#!kck!Z4FnQ!rS_lx7jU;+c zwz__<2%EB3VAGmr{_4a3oA=!KA_gD0gLS?AAY&|G(Vg1Lstp@-%`FLO zs6E&eo-hg zd+!jG64O@J>(#J#rC(WQBGeF-VjUeoN)^8O$4KoiqP*S11ryhOh;Z&SgczVC)*)qu zpa0-KUibE!siHhVS)f5IkuYI)Hch;x7te!)FgfX*OSt#WTNxbM$Ews?a-QV2U;dPL z-1JtaR!qXx1T)#v!tOhN!t39)4tM_nN`3&lPw>Ux4sz4`Zqu|3M>j|&LZ1PZyzJ0m zOU}9cHQe@rm-3v=U0A|k-kZjm9;GYU!9aQv&jE7EdZVEB z3gDo>9GX_UN%XIyYadTH3qh%LB$j0<^uvXiA5%AD-X~a=@p4N6-f}pTy&%2s>7Q>2J%mOjJ z@%z3{upD499k5PElUqyO0ZPG z(#XgVC-<*mud|z+gjutfOJDhZ$ic|@JGlLmf6Yzbe3;LCegND!Sdve_=acy7t>JIp z`aI^+Bdkhoqauzz)gdLK2A3~eO^cON7g3#dhmYeH^WTvx{ij8IBG2&k zpU(Mf5Q2(sP@?)C3kVa_EY%i8ODN~1yo3g#G>Ro+n3Tk^&B<{w=s(dpkJQmRk4B-Y z5}PW5U0s}y_uQkuR{t~SH78vNv*tY?5`qNg3TKwc@6m`<&s9i>d+wobR28Tpd)O6Yk(AM4!xP&diBYXCc%jM|p?ZvW6KpN9@nRWu)ziSklO1J_#Qxa23&8-ix zx_>+4BLi&RvW2M5U9eNVyj(E>a}lS9TtBIrR1QvHRi2$xHaBT{}2Qv~%whKVntaEKQ`rc#J9ULJpfg4I>#+ zsie9-dwYohWlyrIzX#8ASWIn%bU_F6&VVz7w8KnEcrFX1?Dfb6{Vke+1QX{RwXbf}gBe)L;5_16-nph%92kQ9?P z(~ikhA%K%B;ffqB`hN54)`R-BVa~INBS|Kstn2T`D>#U-AYYOyywG>ShnzMcs$VIT zLzhoJpQlhLP^na?$yNdo32E(e$)OQljG7z`7QS|npJ!ZAxT z60}uu-2it{@48a@l=3c9*%``9s_hD7gEbUa1QpG{5)uS8Y+ea1)m|6W-e84n!ZEND z?JA@kzeW*Lu8_JOt8)cgvEB*)DK9w{s3|lf1PVu!--OLrZiYzH$+VhbKK!}Q@#gC< zVNPZl^ITd|{Y*O&D|HI5yzY%uL>TlCP6!i(M^Kt<*szA&$eG+f_&bV(ky23d3}VS? zp4jyp?eM17kdSUVA`&7xLS*mG-GtoJ+1%gHe8wZ1+{hwbtlF>v&nwYjhgHUk=TQ-o zm=NTp$GRh>proHcd~HjR*^*kO(P2NQ7K={R*P}&_%VAhY%*huyo*% zD&{Mo6H1m-oWrpgF+Z;g3Y(Xo#CE_);B{rzfC7K-QrvnPhBefaJywmgwZtSG^ln{~6>0 zJm;cj_Rp92%%{H%Vl!txzn?9=P2Bdw2l>M7JGuPI^XcjDXV!7>oPtUZHkEB-SS(Sh zQXdh(5)}jiR5OC>fiy9yqGllwg!Q6eQ~GaC{WAZ=)UantJ$pK@UwqPqPQY{ygk3B4 zLni7z)0e2$ zd_=N$@1vZw^)%+ErzzyJSXKflebRGT#>dBLYimOYL8oCTC&TF+4H#_LumOfT| ze@!@3W0YeCjlN)FLg^5T7^Kq^y!MT61)6wbXpuL4`UwyrRjlJEbD*pM>j=s1{rvc! zt|8=1VoHxxs+VcUqdU2pzq@mqFMaJNtXq}j*SB87)Sg|m_jGXYq{-E9|GLTvat%l% zdCM!ebIm2IsW8D6S6s#!XFQ+7=@F(zMmX)vZOqK1$xC?0dp^a~NSa%}dN&X6-cK@_ z1(b#IUwc{O}Ec&o*pYAmssIv12Mlwv$o4~eP5h6)NgvojZ zOg*G2dmb?%cr@d2YRUvA!1E~D{S@aX2}y@}FGI{UnM<~S6XoC`VAz2+Nv9|=;>8J> zGyhNHCXo}YVP#L!U`K0Vd7kIhkTKIVkDEYWPX$|aJQ{3+k}xUCIInrf$B<)y??JPG zd@FT8;c?c;88EVJ*|v(my73aqZibL$>S8ddMO!YOFImhvl#L~%@7K_iskSsR= zVM3uLod*;q7z8NkCdH_&gVCr})18D3t#|b$uJ7afSLx)BY!q&PX)o2KzKIegfJ-q0`El8PV$(y4oxt4o}(!B0(-=pYP zX1F$BsvnlcgiT3E8e6uK=v&2b=05sFF98Xi$pyyt4e{)A&ezS=u}q8d(-yYG# z=V2#prbZ?)?Ixt8<_ZQ7F8%=m)8FS2G9`;nn5a2I!dgXBa*>jgBy3JFGgu@qeTpbs z%pwZ1N(hsXNK*D7B&1GgtzJ9^t}J2;OK-Yk(9`XLN(!8M@I*_nJf#^C0H)d8fzsK3h~6D{hWUK>14Am zQo00vQCpzGmVreKLkLEE7t56tvMTE&Xh0=qz+9fy>(}7AF1g7$D)^Yq&4hgw_LxW{ zU{oz4`Mh%3sTc;9^zo&E>$}xA#e#J8jirvcP!(vo9vE?g6536hz3EA$jDU>8aDWHC zemdJ*e7^C^VQ^1@IQ-%R&!r;Zw#+etv%n0MNH%m4e5 ztkn|<{`|%pnVp>{)}l7j$;nv)(ILiU5VC35l7dYeLFB-*=<$+_J~~Qf?>^3c)h%Ry zaWl^7B;%P8np3?@db51#M-M{VCJvf955_iWvQu3BqL0ApKZo;Nu>0U=JNeAVe!%99 zFXy5yAr6d=5Tuj5^e|dYMrP7Sl4Mn$S3cIw)6h?zF=XiiPhtgXEJ^S|O_ufB+! z5X_rNVosW3lh2W;&pY4s?~qsreNWI59we=G2>-7?o~l`?uFs}vs)3_`%w&caUT_va zyZip*nqGJ{dvItGHdC`BIJ3~XVIy)(LibtvnHh+?D=4JLuE(dq)D!qpU^gX6yA$B5 ziMwfPXBuD9g1~hh#-9{>TGZHU~2qU=^))n1RRl5Rhy1K-wac z8769X(40yU)hwnE3Z+pD4_mp3A(iP$GR2%5rEJ1fW(TKtZpO*wm`hI*>`l^O+blY1 zglXdG+^65&y^~Fw*AtM7x;e;k&IMQFW79y@eYTEGC4?S~scX!(dzr^)(b>(W-e=*; zL$vhSeE(Mu^QxO}LR29Q?QmLLLGOBMy?aatB|DBoCgUjmmQW@$!cHo?e+1!ZG+Ohg zSG?yyjgAl$OLc`pwP>JjTIf-!6F433hFx+pSiMT~Izy2L86hMMf})u@d4za8!9vEN zNpI2>)7IiFm01BcMUkdRlConnopXt`&avniBvJwgYT=VXS)wY6R)I=k#(^fenuz#5 zQ?h}K*i1BWKmP0p(%hhJPV1QElEAn!j+gYD9kS<9G^ zkcdNeqSl4~dT^Fke*7NDTF~a}&_YuoFVa)f5S{!UbK#9|d=AZ>Hn;rszX9u)TXn}4qtn1U;*2dV_7^S?TSA}B+p}bGITqd8-QpIMwy1E!2AE#U{GdVe_n#Mqg zXf#Sm3+>J3X4>OzIMWC8rmtue(Rdu&fa&QRVFUWRyH)6!A@F?{>I7~8BO@cVqCTI` z*FO8n$w@+i5UuU4G`z{bq;qjQ4UiA)yL(>||Ct zOqdcg*}{L`F%Rxqx?g;d?JcL1E0nn9k)3c-5}wtMIXTOaGsJb5tmmtD+|Ry!`)RVz zB`*a_PKk&eW>I=ttYuP^CKcfj!6ibRA`U`0M6gyE3RF3`O$Zi5m>7ZrClZq%%QpJI z#6bF^P$!n@0LOn{QN1SAZ@5AT97pl7^D8o!{*c#4tph?3t1IG5rY-_>BWafc2%#uY zt_i&!xTZKRUFlDOs66%0l*hcyO5J)Rjyf0hYmtgvkjJ@JmaQ=B*I(*I_s5|oE;k|a zX}$mA3C>mZbFUf(RD{sSCFx2g`R1M9VAlgX0a&}XmtX$!URqn*nRD|9k)V-0K^b5y zo29F}i{bHM5{Vv4Zk~#^ERM(H>>C~+ms2Jdt5^80BN30(I8 z9f@`f!&1~ze+kP{c~rtRRM@0ORT_;LMV4KJg0<SEuR+cZQ3wlCqK{tmnC*#nZYN4$u$+b7Ug=DgWX=jp{Y1XW8 zr7YDo{XV9YRLn4IrA4F6K%y1Kj_~ELT}-n7A|g&2DFal*5)mvs&#UQ&JWpj!NqM%S zoE0)8tX4qK78i)HP_;`x&2r4|7g_#X4LwFQ^#{h&m0iqNQ6hz+n^C zRxi1%a?34M3wybYzz6{W>Cr6&xC?BxZCvRPA_Y{i<6+um0?#YaLI=BN0wg+G$V+Id z>7+$%C?)hSq{`v3+bld!k}y+bW~NED#)%2Rf>*#3J~6%T1vM2oVYMs{PXcVNrP=GVWt+K zAt5M}L=lV}x`&v^({A=4fJ|nL)vH%CKR>UJbqUb!6Ec95CBoLTSYQv9IETEq6N5pR zj`HY(zhzC&29V2>O(~%wOwCzT=*)fJzk_6Qj)F7Cs??b*N|o4Zn!Oa6BtPqDjMOHX zY@y_ZIsEuN@Y{#rw6o!W1(ple42*ktV;XdBi{?Nkt zPaXKU=&d}inuTVqxUk7;>(uJ`%w%RsCR=cv`QvQr{xOZn3ELR`zr28;RE}+hYO1zn z>Sj^}b_F%U5Re{){~}hNd^$~xe0qq^Gi_vp@&t|a2^z&;p|N5S^oVvR31uc}2Rs4E zWDM7J8J--a>bh9*IJsPop`jt-@i_5#9HkUHA9;}HoOKp2zVJdOCnxosysw*`J9lDP zaqu7(>t^rXDf;?i?AyJUL|->b;oGCqg6b|^pUTT241?U<92Z>hJTAKE0{t_04sp{> zH}aw@FQa0bS{JA4L=j94PZL|+OK5tU(@$Lqx!*%(ih@WJr;a^vCa?S4_u;tX*>cM* zZ2R_?*m&KwwDm@bt2)=;d<$T5|OL+yoGA1CHJy1DoGg)q;;&YP zIp@3(zrA|~9#VYtQBzM@+z#L|J@u5kxbBOuVZ9t8W(sBh&JDSE$9a$&u0~b1HC*h z656b2Yzo_sF^5ZbWQ67GPHXPr?M-`Sy+*21fobApXDMW-fO$fur!xe7-QUtCq;$Yp zXHem(g)T1<(=SCdXn{~f&j0`*07*naRLT8VYMEPWW`8JOY$%T5Mzye0ilC`jW?ewl zEHay};4#6b<^7bL5__K5PJVhEt9PKexOA#A)P!WgF|kefpX=Vm>X=1`Y9}Z6Q!_nY zaN(ssZ&(pjMoZ!5;S?PH_VTOQmHiq6vXj2V@mS_GCnOj6-q)_@oadcGysOtgWOY_U zgofB%AWYbE&+l2gB1@-gXEt5MUN2a&ZUbObR72QN?K*^q7S~IMD=v8+=WN)_4yVF$ zGt7({W0EM2y@vaCRAB2aP+B%d$|OM^U+Sqfxq=Fz7(~ z9{c-1EN3pArZ16VYC6qHCk?`nry*<7AKk?5+pBQnFNkb7o;MGkhbc`u!mGLO)7OEe z=(7b80VO3^cj{V_y(!K=_e`$+_OWZP~Q-)q*N;TL5~up zv?ZfXuB{w1!rtI=23tgY?S}w`4#oNW69*DceL5fx4oz&eh?KH~ZQIOe3oNJ-j-ydS z<*%Ou?Qstjj;fsUf?M% zpuiEEn${_LQ$y2|>!Ot6+0Qzi?92>_Zkva;Z3Ai~lX30hmF%aibnt6FpP^G&%=&v$ zKA&g*{{8gy^iVSlN;&=ixm=E*Qsf$kSR}&s?c3>%#qgBEFbqaVN2$7sAO>xg#rExw z(q&oP_lNC-;}-dyyRj^*h32LAwFPK8Pj+D787`J3u&f@0Q0&~f9VrzXH=fFM*X^M@ znqYwmST_is;-=q0c=kBCr#Ftk%TMNi-t!WU zBTpe3WyYy6KWk~r-cvU5+K+u7?t3;^8L%Gby;m%wE7eI=MiF9~Wm3?Yu=V$s-CXg7 z-;@5@-;!`{r)_W(x9%$OLpHGSyq9p|=2bkVW{4<*ZXuXiwTgea=!+l**|jeVr!K>r z9n;wdDC*Kg37d$JEI1NulYe;qo7l4DG^CVdvswBQDHg;Aa_M3EO@|wR(o z+szYq4}+EP>6viuS?l=7^Z$n9Is*tp(HeQ>4GsI;C5(>R!^5V^5E1RMoD4L77Lz2*#=LN`h& zKj0Q$7ofjiyAUkoWedQhP@V?IYC>n=5YeoGcEcjfqGO(6)DOcJFbFh&s$gS^aTKt` z^O~WmoqnieN2}|W=PjXsb)YH!HNzm-U}zY|pL`8GPh(ltMXHKkS(T^0HjYXS6OfgX zSU5pV!K%J>WM?X*QhkgMKS0brnUXWZ6FaxFthbk_KS2-J0&plJi1&6;m6AeXmh#Lb zL2sUz8KV>3;cSRPIMU z=R%=SsHM1HdSkcyDesMuz7QH=D=Rcr-!fkJ%8U5lUvEPy-K4Zq6l@c|^SSraNtURJ6HrCEQZ}Fd=3QKS%TJNAVe2a~ zMHmD~Sz$g~;H-=PijV%|wY=w5NyZ--Cbit;v{M4yac`b4fA+n+?-SQ+VVTg0oKo+} z%$H{Q*NDh z@i1kUVI(f#D>ps_zuf`CfSBTp(^m7A3txy3`*>pC4wAO1Ip)e?!O3Ho-SozjOp_s# z$&gGYNyd_7GDA9)&4YRG;F~QF2vDm*Z#=%FQPHe0Pmgu|$MThZcpgknj_L$?U(A}x zX386 zh>^4hnM+R-A2d1f{Nv!=--K;3jMq6}uZ9nQkdCRFDRkxegG%wztN#G`4dC9)HCMia z{bTo1cPc!wbCmlYx|jW9V|u;#Q$bUBgq2CV5L6HtrXV7MO%AQ_#c2W4q(g*>3xSQI z^dunfwnLyk$MSj4B(>|P6PrUdT(sn7P^T&tZDxoLGfZb9iV%WbyM|c3dexHTDB7Y}2$PCw(k?3vWCiV-rN5Vn-aje`BBuS63jL=}`}z|Ox2JKUa_p3Y4Ifk}wwchO8WR=Oq5;v@ExmV!ZR$ZzK50F7{AL^Ze1`7s9$$;51@o@! zGMLnQl8qbJ5%oNh$t0tryAh%v*L7Llw-U<|Oy~1-S#kRM`*>jIc9vOjLUEzR@s>px zuzj~8*K&y_lg$QpER!ML6Q|-9=}IP>AWhBCl(MqnEg7iP3_ux7jE@tEM7Z_VpR;k} zCcgFE>)5vKK`bi~1W*D1U(C5f4WT-HLV zG#f=cS5sZgPtSv(2T3Pxp?wvYM&r^>o`_V0D_Pp@K}eb~ktaKw#xnDOg%Hr;Thev_RiUki zb3jyxL+(2b-7J=#e6Z^L^UrMkr3Rj%noSCLI)AKQhw8B_j23{9=QTqe7n&22 zMH7pT!+ae;w4rt3=+l%#(eO$w=jt=()Tx%NU)lUWi)yKYqbgi_#T&Tqp3f8P4zV&7 zBjfDHG!4f0+|T*vzkmg&LWiy84@I;wN?gk{_{jVIk&3&Y=bW;hpvsYTGIV#JNtt%7 zo6GL^Gj7BZ%2m9#i`_$c+DwbOC}Rneea;R-W5@CE_Io+`)YAaLY@t9n9MvXH0u~&H z2Y&ZE#`oM$DZh{ShII&0L^=WXWlNm%@^wflX*2Z%{J=^3)2ZJL9z4cxTujmIh#Gdf z%14?aElx8>M-=oMHoSeFw_I}`|8@NwsZE0vm4~MS9KRyT3(kEuuf6PIUU2>vZvNia zs5@DTv*QGn!|1*D^7T)>pQ))kShsu)F|&vLazDoMZaVwVW?649#U@WabP!tGy{d~c z131DW&|O1H{WDM9D4Ctw!R41<#=ZC6i&RoemrTVIcm14ieeBJ2Og&0p_W}Xc1sGU^ z%lXZ{1)g)p#Ynl2h_G=>3X&^yfL3~hHdE2rRi{|lhb#@VS1jkgLN_mX)AjuHXO93` zFrMJ!?|Ct=zVIBRJ4JS8iY_7WvROh>XRjo&h+>n^<>|64oc;SL<@11OHU`>0u-HTm zH2$eavh{iu<#_}GfhFLm4q3u~>H~e5Wzic;60#zA9+dKus;dZD5o(6fOnWUBy@Q-K zj?|T6$AK$woC2MRE*6{;J9pm2XMXl^ zh`X>o3ys2MuaV+Fvw5ir^N3G4^2ZK*9_{-b{5`BAK9BbG;waD7&n>k)%jo8zu?Iwi zPF-%Gt*KP+A(|9*h$lz+oI|IiE2VP-4y@$cTZ-#;7L#!g_k6k^<-;^0<->kV9r1az z-~XvT%Ln{!2R;w|HH*)x)K;2R-_58oMUhhCI1bqJN#>QySSCYXUmrCCCMPCYyLK)4+o}75UnA*i_gDgn|Q}5AVjDs7;c@i zG#ZqH_aWssE{gSHIpvWOwpxxQW7;(>7oe|eGfHiss2qxFhHA*8Dl~1pHQ=#v&+0UK z)zlfcS%QdRg3?Vw0gcJEdEP-03I`Vb4a~EC6kpi3wl;!Q)skPdXhF;Yl&%hRHcHKZ z9{a~WmU~%y(%+DA<_Oz0f+~kf zKf$*@_bI9+MOEs!j4ojl7bZyf$UELaadHTlWy6N$6jhFBBF3-od7S56`f3V=5<=7o zDt#6=!jFS0fa54$@y2)Y>w6w!<%VbB;Sv#Lis>iVKR(R;_uhpg9U@&(KnI^sPfzp1 zAAXPAzK1DfcXP@K>oHBip0Qn=xcP-_eQ1jQ)vKFR^v**7YwgF(RygnsU%aOq*C`aN zR9cDveQ@a_Wl;>a7}%nkt^h}~Z%#x&8Nb zc27_H^phyTMsmBNDU_ZV8RuI+x{>E^N%7q;UC#b(W0YnjYu1dhLcN4{U;b{kZoPvq z-TpsBgrH64spTh$iZaU+AVe8dFI6+fukLw>*S`HzjATo6*a9yrvBC*(9l#}S+T`RE z8OI?SG6^M8T=%~@9{BqAAf5pCA5%+KSD+C2sx3yLt4%5vtt@{(9XqR*y_ml@=d;cB^#J>Q9&Up|wxXP;L4WaOIU(kD&no6U7hH|lyROR#n>Ulm zWa#hj!*yNGJo7AWzx6kqc6J}ab(xr$@B<=YI-emHk2OcLuB*sSWJvTUsk$zzCG|QM zi(wdge`y3l);tixAfI=ex~ZVIbgeH4kHT~g33V0c}U@P4S7>tfy;w5Ge4jm!8ax|NaA*3{a+h$#vuzkA3 zMHj8&(ru4$>+cos`RH$nC3&D{5cqB!?Ptk43;VU zJ=jJF8)2FxfM_&Ky%6wq7GT?nrW2i%4v9p9h%_lHC<-tKqRh`0*rOn5r&wce##S(^ zBz2+ajhgHl+Qk|>#Ytw0kWh>ZdBpp_VHQ!-&i;qFZ~pHoUWdOwHOQ8JHXWRG`0|Qlq}}FJj;Yhryo?z66)(x z2PSPsqM0!zr4C@zKt%|G%4<@yo)RM7BF1d!M;aQG4q(ABs0o91-vzdn685J&7C6{C z*f2CO(YW75=;@&S>Y6!xgwHU1V6!9?B>{i)cW>d&dxqIKIEW=+d}f&5*aq5dmoI+o zZJc`gc`Qrmpw7`B9}xv%*ve)N;Gd2D!$O{p?M z)Oqf+HZ#0uC!cuVn_019J%fYGab$*)ljrO;VdhCA#4;eloXYUv9*4hs!+$bdD3Hw- z{7H&xriSZ|Qm2ed#~@>7`Sh25%!fXGIq!MZ3n|PzK__b|lH=PSy^2lGK9#>ceGN{2 zhDRP5CMaCumiG6qi)B2!s-y)w*8dj2G`)tLT7h^P6RS9{rm$(ff;HdK$~e|S-M$C zCSznW8S?qO@1mi@BZD4v7zX89g+RcciUxF3;vUdMK%HQFefrzdqF=udE}js7SYY8C)q%b!6NKzTZx$S@4rOba0l z3?o2?ZR)T$;XqD;A!#%7^sipUf&)>qjE+CTCUcO~#hoZs!*J4MgKcNN1)oZxTUl)l)f{%Ud!~FV>e`H0n z8|5iVd6$8KI3vTm=vzI2=V>eSQqH9}7Gvkm2kGzE&W4s{(YJbl?BpaHPdt%$JkHeU zD9L0WYuB#jfk(HKTG_|w=qQ89BwJ43LOz!P%c47(Wc&8*!qx{_&2cfWZwVtdES4~Du{m#j^6~zW!_s3F$sBF7mS-%FoOx* zYhcFWyF2H3{d$93cpta#j6mF{>R{4l8idjXf~hbS(_nmjnr~clA-DeV2A$tB@i^bP z?kYm1F}m#pRq2rH>SE*Dz7KiD*M6{tw{E?g+Rr7f3{fb|QZXeJOi&6(D)Lei#l*I4 zvRQ|YsLj~;7!lt%BPS&x8N)Qggq37ryg&^}o2~8rAIgr=j=;9{`&E`%PF}YOcUm$& zRw5;ANXVzOUzS_1*Z~^vz;Sd2P5H2!t!e_qd0;j*fT1kn<_x!f z{tBia86hI}G8Im;;0*Hk zBpf1QkbJ4a%dhws?)=49dFh3#$?So?gdjgQO8d-XY~Fk}C1Eo%GR)bl6WE)3`QvYI zWk^2Gnl&rQ%N#-|`d4>z%Pl`<>)4O^?ert85Zx{Bt#?2Jr=GSmCUjsI(?GeEQY<(X z(xoh^-W0YS^@~)Unp!(XpJ_eD86zkM3D{%o7#ioBH(kd&E_gXr_h+1Q(gjE-haEFn zy=E=hY=-Hv2k9{_gqp@O1t^b@h|`&fv3=|gLe@pR;SE=D`^XSo!e|C6sfOjOsT~L! zp+;Y?~zAXwW?oJqCo;|wsNvWP0ciOIHc6CyCfW{nADX+0S80ELZRA(2TG+9QWhvFhk!D0RE0JKG>q;;A1-$8dehPj>@(%)kFLpZwiuhJs4@ z#e}cx3c+}GHy{7#dz({uAxthl|9txT`uqfXk4__kYq(8AkBI*bbGf`f0XDdM`*xI4 z#9}d~a~VcQM+wI)^7%ZShQZ^bqjY8Rv{`~u-eqEPl5i|Wj}>Rn&MAb5vvuos&fans zcl_oK`d6*@n^~{L?aQFUH~eTkD#|05&tOFizI@#mnVp@bx3`xIU;H9syG)Q*U{)l= zW2A^lh~H!28?z#P>};`SxG);Z1L1?xxRUl}Z@uaVC1#^Ywct`1l8R zGZ1qbyYY=ID2I={>I^>mAHU9=-1K0A-&jFbBsyu2 z)~P8M$5GUk1_9!x$%2z5CnYrj!z07Z+#JVoFio3z`(aAb!jdtP!ls=7b7?fCnrQbrx>73%D8=`0_%@a(lZ;sm4)&uI7+9pIsuWch z?|a+3xo77Pb|Qh}ID~~hb0enkwWNy4YzfoMbIGMIrLgCIX7Z1dNUTDsQP!r~*gw3D zZGZR$VSA9S<$XMyouK0GCm9QI@`ja!%sK{1qTM#{y!s1l-I-d2|88FQvgfjPbwBgjF$T!bjsT%>df5W!9)3ESOV`;#42tLWIt{_RrzjTZ@O<};5C%3zGj)Ce?d%nfTe@*@U3LuZq|=CCS%RET znNXhcCnNe`@9tTK=XpeY5A?aY9DM@=xNebTvWJn8T`YKBlZH_#de}X2YCzbsaNQh+ z5y3P=ddVn7r!X0rn!>a!coaxNNG@lkuo+{Rlx-7Mb;dc zgKipBnr2o)7g7rpK-fOL!Jv#yx5zSsLYN6+PFh>XHs3S#Cp0O?Ug$5XK4sSS z1(H%~1BXU1?XmxS@h3JqPxjC__&sX8uAo{J`8I$m&9|3G=`3k}g%D(C9gbgf3T^2u z*>nIk=(2yTLKl#vhY6;!gkJYSPdfm5o~J{7U6*(~MkcdZB*kKJ^7$N=7170qtEecC zlBej6_n;aH*p`81#VO@nJc<}bgk&s+QWkUWB*(4q2Rw4F3wUhYxDKUsW0cA4r`{Aerhd*@fUch@h$bWq_fFgi+Ke2ici##2)mX^Ys9 z!8@1`}ab&;E%rC+TD_s1+GyO}Uyeq@BVUAmF4{Gv{F zMsWJuAM^Jh3CTTt;Hr0$AKy-X%)+);leBkHLQ#lr=A^g&5|ZnI9nfdFMav%^nmrKfJCTXfrkSY;Z8e>)&uC zmSyp|&whplM^aTzGh;;vahRMHwS=k}R0mIIj&vW@gy#J}ndx^!3)#3=+FOEJ_3vZj z3YWU$&}(*+k^88wKa+E=`UMP0?doR0*LSD+`M#fX`)B`w_kZ?gZvMfq^bd%46I)>; zgafK^%|IA7Wt`^wK}!}*QAupeZm^k~Ob5e=P@J2_TGqn?9#z-X=euE0#Gv4Lek-ta zvJnVCFu0hZ(l|W?I)s`wEux?I3{Asqyf>br;MWiBz^vyHH4NICw&gm}zF3^oZO8## zN?V(LHZ{6|HmHFSj%a7oYSHJ9EM7;=ym2|2yIf;RV96MHQ74MT3F(O=hGYRjNqB@D zMak6Xc8{{i3kMYqvr6ipcNcjUM4VXKz)}V^+vPD7U)z@EgO{Xu%Nt(7iO)KXi9L^U z?uHW)Vi{6O>cV2hhSLeC{e;XirR+GV4V(Gnjw$}|Sc$LPbSFE8#xYHks%%W@G|Q>h zpk66KMC37r&Ca3yT=d$j+4snA`Oz)ca>3~*Fry+EDcF=M`lcw;q*5WutfVdko$3i9 zv6Bf$PvE_u{x+Ze!7xs!i!!tHWaD7g56UX5h3dMFQJNCoxY!Y)r?94fKX=$Rbw~OE zlNwaiV51*=85KyWJMB<79A@l^y_EeMDVr@&bR3RLCHTZ={~e{Y^{>uGh$7`;_pkhs ze+`A>6lh11N~Nfl0w5RNlCs&X4n0bkn5Id__h7&L^2>PpGE{ zHGv@}>4*vTPVM8A4VQ4=olkJad8hKe&%KwDuo)T}2P%YB9px8+<<`Q9#pLRw9cK3< zJ9+k|jqKjJoBq}7`0gJb<@!(lGe5rVmz;2d2P|NSI>Km22m_@$C{B&x?oqtuonNIh zk)q8s$vCBE(bN#Sc4&e$#4MkWI?Zb?+`{|iRuGB}Vh!VRh7~6c^7!N)y4VXC%;=Ms zljDCyYI%x<{0uoiBcdiiNl8s*$wLQKp&b;U1d9Y?+fP5~eZG{a3rCdfw zClD<+dbv4fjnIKdp*aol2*)gT@7_zrEmA@k3;BEoAq0a-J;m|7B4xC5*8(1uVv)$Q zWvpDevdJ?|kB-vU-_OdGE6HSL7)bVz=1XH6EC{Ho%?59AHkZaH>EK06RrxhV& z>7XiNizs`{w#hq==BJ58fmP#BY1n4BAIP~qM4_EZq!@P;Wk2P0_3A;M7#m@5aFCo_ zEQo~=1bsBCE(AgZb>59B2!$3uC*&hynkL3k3jO*)mb|SWv(0F;2ro;0ecMbyT$#-f zrURRk)E$OOVh@Ea%99rHxk+vN04zG z;-*QPU)Uc!k!f|I65vYcOHeIo!DzQnTP-WevcCXCHIYd8mZY+ojJ`;jRs6Z_k&hL@ zYHfZlHDb9`{mBdOV$U0fdLk@R*>TTS#bqGUd=`2);nJGpd z945Lt#yP7Cy!=Fui(hgI;n@-@o2AB1e*c*(_}q^l<(@nCkz8(a+Ot;il5;L3KfaT= zS*Iu@Q)(AgWfL$3@BQyPwNse;2zUJWb)5U*ZviPzz2}9 z6;(}W(W2f6Z9FF>hDruPkDC*o988P8lGZuKEu1?DDx^owEaHP7KczxyE`A1WNv z`CaoTby+Ftq>B}swh({tEN=M8UA*B{>j)}Ez$+6}MFL8{lO_f=5y7-BW^|^+wIBO8 ze)n*Ok?{gMhIZ34*sI$=shShHgV`Lascp+-&n5K#2OjB+_Ey_v}Qi?<(!Ghy4mv%UQ zRieoimr@e9HR|0!N!yhoot~vQ-V4^o_+WzT~<85>J8HkM{q3D%zbEIJ3v zeCnDD7@aM!Cz~aaFab$WX-x+$+-S`Kska~_A(W~RH*K=nG`4M`l)*?=@%*>^D=&V} zXW4z%ZuadPV|>pr(#g}^y_}WnH}UNC>*z}?!*L#^s6eI*P2Oij=s+BW)Lm$DIgCCG zn1o7-lTrzO`SI6Kl^PK;P2H>o?9*s7Lx9DcH2LM$A%1(~EtENt&h7*u*P@C}-3|!o zuo7C(Zs>#65THDdngFi|9e9K+!OGZ5X5Adh^{}iMo;QT&Dc?~?7XqF?<}G8vTn_vk zm3%&r>lTT{EG8y0#9bF51RWU6D}`m5`lk1ac%Fw5G3Z#fj5f;xJccJT1U=>d8%nu6 zLC?d8#n`rO8|R*TCb?XWkW!eQ)x2TDaSL)__!%@+xroxvd%B>Q$!7i0w4mgV`86D; zHSCv@?rsN2$t+zh0g^>c3Qw`E)Ux z)L{$TGKy5Hw^@kmNs%}z^{OhRpJuM_t42^@(Q$mLMA&~11vRl~;aO>=Oe;w!8YbfC zy+Io@*qA5^f5w92z-bD=*1PWFL%^j#O`8A^SOu=tEah1IWn?+ zV3X1c5VbZb_{E|UiW{&09^((*#eCM_&h*_3J)Whg>dd+Osd_H$#ZNJgh9o1nRAOQvm$gF2Kii$aLlCUY7nK6$wN|4LUTD6gwC0o&gCd%GI~S^+zc0yH#`T*f-(uO*4UFsRV6zeC2xM~94Z&YO|4r0NS*m%($(sfVrP|37qc~gO zf4};7#Aaui&yEqq_FeKMDIu|PsAQf(J3W!qMtWjcL(eX!15V>@ST4KDy$h? z&w_v_#>O}@G)jM(qHcnn0`MUWvX3$e$(9C1;JcWlxJ4J1vgLVWn41;)2j}K_ZTL4kR z|2n^6P#&{ImtwJ~_w>g6Oc>37M;nwb*F|}YwD1MPz)-r;Xln~&_{JC=Efg?(T30lw z*+7x~Ijx~J1hYk#pyyHJKt+viHni4uanjzp2dk!|XPt)5BJ79RmXR#0sAhQ}OC^G; zt+{sw(Nlz)5Qvc9_;`RUQEa-q8QP2j2U|++mI?m(hMRcguKW0}8$M4@%;UJ!dJ57d zX2y7E*EafB_p)P0fq^xfdDYb)q$UJ=#%C!bk72SWnp4DzS!Zv0mg5HpxcsWmP%0Jp z`ai!C(-g!lo4A=+lBHNw@W8%ZoN?|8_|?NXcF&f`C`JG30m?|`vst=?&62U)A%Mti zHcOi+FqP?p`B`d>^WN_rs#1|or;)Nm&)|S>+R@UewEHN!PLwVHnx^3RQxYLOpI0eJ zr>7AjMBFsVIN9dmRFn>#O%HuRzzoCa7-X_I&PunLtc(fY^Z9-5m3}RNCaGx%)^7%Zg`}!Hn zWUwrYdC#N2zYlM8FT;})oV{fWnM~eqP%Q>~2H4{#**7*cPbpm2U4q!0kzK8p<+5dLoMm71?t`cs&I zk}XCE&s>9Yq{nMt`3mm4?|ueTgFH4oLL$+H>8Dg58yYPRx~8ot;4|5r96VXmhi^kK z5LB&*wP+FRDi-`u(>W#ROmvY*EQi%yeEI&HShs!^rJSCU%zKMg>-l`1P7$Y+(?%gP zGkNAcMVCKSu`G*ef3I=fB9;}QWf=)j)P6&%+(xNw>B<$~P zuIsV@xNea`ChvnmE}rtRj0i!YLvWMUYC3S)>jfx@^{m~TXBC3o=`oDxYCiCh-*DN> z&)^IopB|&%9>f$jBV*&(Hq2%X=463@U7{>PgzXd)*$NdiM8Jj)CyjDKjLc5cH!#4? zkrBFti4v01^b8})qGCcx)CqSb$V@|2qyULflHO>DxBkPmAXf0o3!=PylgE5Po1%RC z6PI$uzdXjxpV-H1H;wYL3;I#BHdQ%8=PHK)!9YI0Z>))O-|t3w8$G)cxN*)C^b@0+i|S_=sZV`gMHhi{C^}&yvk%na>tTr_)?~ z@nuv@n-{$1L}m(*mnBS7kx7q{NN79pBLjg@RSF>#$E8v@j>Awot@jvZ@UH7_qc{uu z$0kUp$0(H~!LZ4IouI?ExqMX*u7W+|1xh|GU7JB@wt$zFc!ZgUC9Yo$c8XFOa9lZ% zB0ZfZolaxhwlC4plTy9Um?RQ5kZ7Kby6@2IH{|;E#5pPHON5b9kj+kEnu6X$FUseA zN~sHT(~eS9imI$2Y`r+crb$6M1eGF@7^E&MaN=q>Ww4o2opG|5rlxZ&_+wfrC94wa z7#o`)ZVK9MlZlaCw3#3hQHt4FdQ^&{Q=r!jBT#;`q_r>iKQcsLB1Nm)K)Hqf1+Yh! zhyqF5WdGO*WfVPwtH?=*q-iod+;A}o`Oaq*ivC#61LCGl8P#<5sY=O$lC=91B|YBL zi?<9=lGG}KUA@m7F*7{0Mj&C$V(QaXnIFW zDN#bw8;djNy5w_ibJK}L^ahb09RR^|hqbVLr>z=- za4begE=R?ce(pd9!_{`7$(2bmnG9B3Z$6n!o_Vi`J6UW_GF;)3%jFnMCYg0zcJAB> zz%nbsuF+BAaf@YEoN&yLN3rcb1G_53~T(V@2;E z4Mt7WskP9ZdIkrm$~1G+CFnnyJ?IU?Xck$bN&RY|#hUu%qbf^$`*pz&9$$dP(Mpre9`}((!c-M=A=$F&3ClkAk6g7^J;j2&(>?m9j*_2M2;m9rfqWrKjmk zbosAckj*+IQVASKHa*&p`T}145@wtcOw&e4EkZ3SL5FD{qYmV0#fX=@tGh<`lFg>s zwQGpu1_#JE4oWGGAJmPDc1C+9sa#JD+Q-BGEx&8#l7%dDlS>)^93s!MZ4BDnUt^1e9XH4iT_jEa!N7?K=Bq znsj=a<2DXbG%HA1pp821tYc5_W#j zhx>Z@<%uIp*44e|e81n%c1D5cZSAGH^K*;^Cy~iWIy*ZJ^CM8v0NLcoH4D8aBHi5M zVogJ&=?aK|*+3H7f>3J&ktMMO*=&|_xlA<-aU&*0JQ^I-%4MpddCV$1!#pq-YT|_0 zwj`J9A;}S9VMsMJXi3-%o3;d27!rmWE7G^tXM-r`%{*onW5N@LA=a#A=MO${Pu3HV<{Bc+VS_@;dj$l3#jK}Ix zVR+p8z_5#y)-0$R6<>i)Q(cDCm?5hs7X5x!8(Q!j4pr@-g@fff^cOlA5D+Uaupk$i zn5Z(LJQ_kHv_sBui7Cy`GB8VNi>xClE1y95B&8rJ1yTsK4taFcfCNc5MSp(dijB1) z1P|@sjqB!7%Jc#2`+KR?>Kqvv#c@)mmSQPKrFp+KGkXRG2AG&AF|>P#)ovaqZw8ZP zrEp!Bd8Ke1r#19!zK-wvEB5|`Qi_h~!Z22$n#p1fSY%F5L<;@)U2m z;VwqMyB%}}LJ9WCuzxRG{`5Rv^rTHVfDjc_;FER@Wo}lFBc)`Obe5hX@VcU|?u_=>UpUZJ*&p}d|3>!9Vps%kF_p!&8E}YOj&rBG!-p|D3VL}}; z6V8&$s|{E#KmWFMJ_dYex6(WpK@E z8qwl-XwM$AaM(uQB7j8NqM2|Tw*@u=A44}=h?g6(lu$dzyk+uygVi{+!F56~Chh#EYN>S6IArjD=rfH%wY0N<)El?1Y$z*$& z4$4poi0QUg%6uxDr9A|JMJ+6ov@MR5kI>W8gJl^sW{!}7L7TQCqoy|LxsvJ50=GU` z<27&mcgVa1w(O#$ip1(krgfbOCy(Vgc*POY z!dY_F7QZGc=`o1O&!&FOM<}|K5>F}cJd@tt#3!0V5?v?fbVf!b`WK*9{N{v{2BPP5yL6JLv-7De^cGO6h*vEV)6kPK@7b>? zoJ=<=Sh*f0mo+Ud>X#*m31M`wVTcGrLNpDaI9ra85R15NqjgB7Vj7HCs64P~-VycN6J5!J(Nh}TB0tJDL>RyS^O_K%loN+1X zlnx!P3&AvNv>AfWXl?3c(G1jt9vo(|QJ!Lk5^-tVE33*3wAM+NF>jPMCqbdV6R)K4 zJfA+%XRZf1^|;rbQi=|@m#j3|M-6Sh&tcZ7j%WbY6u&PaO)Bb@9pXacI0C2B<>lAD zob%5=kE^eKfpK|^jBL!J8)eJY>n2As(L<6z+U<>+9rJJBuQE?tG+8wrbGws3hy)ADF-id` z$!aJ?lV<}N6HD^mn^xSfo8rPfI@+_+8-=z7E#wOU1Jvs%_#Bccwp zc@Z`u&MXm!4+I<-hn%D#G(G+O+*h=C#Xo-*c2~gaHtfuBjP#jjGkd^?wBSuwU5r!u zDOLKItc;TuW~x|L3XN(;Lr|`i>CI$ua_g9!oMg}LJv_2|Pc&5wID5+$l9+0Khadm| zAOJ~3K~zRy-_AYE5wdT`D7$y>X5+?jTBN%m}TqdSNoLmo;N)Q#@Z7c-3 z6~NeKXPKBRvt`RhCMPGE(E;^9Qxbw&r2=D6%~e>ldJPXh{18E)SY=B_CMQ`40y=ZK zR`FIYm#Gm%nir#OX$a%mgKhLGI^rSQwq$zB$7<>uLUF0${d5}fDrU5t#3kk1#m@qkr^fe9@vfBq1)7H6MzbPL__|sz z&#j2EZA7bFY*8~CEOQ8>jYL#9YTX7_1}_N60&}5-ZHrc3LL!}Ry-tU)2(>{?l0e+H zNmjzvBsZ2exl41=0K*a%VX#yzS(b4Qo7S_f<|$#@I6YaTzY7fN(h;FFiKxJ-2O+EM zEc1i}WldmNtVy@gutN~t{Kd_W!rQ+Kwg$Th&pLd+UtbNi>$h@x*QgToW=Daq9kPNu1C>D1| zu5m82$|5d(VnyR_w_j_7>(H$fp;v``7yjsOrWr@N=aKTkRuv8mm&nR(Si&PAG#S^$ z_d@ddJfpskR3N2`K>rpHN%1rPzYvfXOU4@WXc|$l-BL)RUXeQf^XTJ#SB^$AqYk5I zt!drTNHA{k!LRJ0p%h=ui;11?{xaxn>R7tU)9XA0ET9%y2qkOUmU63qcT3ERFu7 zLx>ioI|;-rYlS7T5Ed~VG7~Q8VWOKB3#f)6oj`9k%S_Ao$BMKi5hKE~2}41Lm8KyC z9hN~t+oQF@(93MBoXKR;(Yg{_)&Pryp&qv%gQ_gsp8=^gZNdy}GO3hd&}czNLLx-m zpd67#B`#7(AxU<2vP!xTPSYz4;$_%60*OOXO5#dW)gYZt+MUiQY@NtKQRBFhDc`5f zN#Qt>nUW%<1-L4BI{#BmXoLMM}cv6U~F76ReOh_Wq6G&2!&GpA+=>1+t& zKB_%~RCaYG__IH|ir(IQw1@dfxr}Dns=b>O;YD8an!m+$UBjkdOk#hk5FEKF6xODGUVyU->PV=g7ze`Fs~;E*5F% zHndhPx22>o7L5z7j$1JwArVb+EZRVgSX0dTK9j1A_kI3Wm;|z?02QA3vS;$lbGztp z`?==nuLhB!M{B}yj|Imj7A;b~@}qMEaUq!TJaniTojlAu5NgBIjuX&CVv;|C591hb?vl5951 zLZC@yGvq9b!-o&kVWn|$-IU7}2*any~K69C>D!s z+O(CiscDME;_v)MyTlt-tp%`IkpHZs-AOU$`-sSPR7!_pae`9@2iQ9@5-o&FmW9jf znz#n0JhtEPbx!-}Gr4>BC>m}1B$fnq@`R;3)UYzXHg%0~}c2h?Xn5^3WE*sv_ZAYe{dXhIVL3oTpX zAehDJ=^+SaNor$dJdY+}S&{v!Wh_;(h=mZhp~K2D9h3=za+H%|5eot`*{m79mCJNt z5aR|g6V6gDmr1A7j0F9pX7@8|&l;Ox2Epp%jsN;o-dC%`kMHHr-u`Z8esVM4xc4y6 zdD-=#ZOC*3dC2-EfYItUlh{mXtcHbziiVsr|3An?VU88B?uVvzY*rW~9!OjJ*ni7k zqf0~7RRvdcv*_<*QLLq?!F55YLzGoFxqLrmHA0(q5VF9Lkvf~*1UcEwz$M%G&o6$J zC*;qe#y%2ClF}LG32+=iS!sHuL+Fhlr1LZBfxq6N$I zQ2?dZDoW&T!*v~s#nNw_TKOx#`_`If&O=-Z8UzRn69PK9mQQ`)!H8Zi&2@8lA2 zI817=GBA1{SHI>dTzSy|VPy(o+1R$k3n7U)PmN_+M>@JU7Xl4O#=%}>PDla-)8!x{ zPN!+JVF4q0uLp`+s9O}w86XxRCRjwx1BBr$rLfg^&|znzre&63HZY=nVfODZvLbFq zCZt;wuvxGyoLo1JvN6CoTCCq3?#%?V*dn_$UlOkRLTTlK+0OG5iJXZ zNUYGh=o4Ivv)Z6baiOWz>QJsgpqZ&F=ILO$POtg+uv+7Y??a`+qUto~T^pofUMw|= z72#9SK42{CjYdh*iG%hO^FrXbUCb1x0gJSgiqLpPO+W@GT64uQ%}Pu|6~!Eytm9Be zP*(NGNWcusTBuR<_nRD_CDboTgbt$_9UbM&i!WqBDW*^)9f4Lxzq=e6Z6p?3`|rEn z_0R0uzn`phm=!9bcWD}WN&XSjW}sXs6c`@fPtp;`Fd-7Lh!PZwIAzdgin2&#+}vQ7 z!>DEDj>K^!hlhu$OV4;JOG!BjOloM8ylT*m@VHQG^QZ_j9a2iMP6&#{N3f+p zh&)h4T&`f-Htj%-fP^h5mqU7-KH6o5Lx-klcU;DOk5ncDl>kH@ zAsia`G|(jJrjrEos8(ZgB2=YE*D2}*vul6^0Yk+q3o?jiCMzcrCX`A zG7{w{BY*g$SjyMwX}|ngtbEIWC(LODUM~s&u$r%twVtbMsz$J+lEdEh1IK1@?V~5HfmQpH7^X z22n>kfVgbtJO~hGt(}kb0&d=A4w#4<>v><(B_y2)d{reb7pZDR5=kdEvmBy|OWkpB zm4e(!#mzd@-`~$n7&1CNO*%~D`A1mgtYU7q%uF~+9Zpz@HBkgd}l-i4i6%Rs)1d8U}b zq6?QW^yo%Xu}s}2Ezw#}%)m`X6s*-y8DlC79TiPFou&(mFceJdSyGlwrBX)QX=>#% zaoc8cauQ()bZEkv=aB?6;!3yXBcWMOORca z1>nGe1Fh!?bQ@u4ocNkQYgiT?R+@ROnVg(7)G#2NJZzXFl$o47KrBL7!!V@7vJIUy z(9G)kiu|V~2E|fMS(k!@)-(_(&nM?-$aTY{xvkqgpQ;epzK@G!QW)X7trQCa$YeMo z1VLTlc_pNDSyVpKk))z^+Ho9|ikvc~q^#;_U82M7BBMOiNR6~KYdt7q1SB02+6-Qs zP0u{Ef^{3wUSKPYEd)9O31+kpLXsAe63~f5n{2v#nPAqma7YV@5D8{=)i~@%1~)Ta z(KI2B!@Sm{M6)qr1@)_WPac|>F#E(Z;|sB3dTaj9hStn@9*)x)U8gH+s|1KBiMI*) zFShb29*_HfVoFBD-48Vcn#04RY}mSy>EcM_7~s?4y3A^bYe89g6#5G!5vZCbAzh}1 zMk!I^l)R?X`sAE$kY?I3p+<0=6w}2jT~0UqOTKY|2#6fX zd@g_bg`7ONm3MygPT1|kew*5z4Q{gTGvQ6*G4?V=&!z%yO>^YXNDI+QVx~efzQS=_ zge6)usX&|XrS{0OxHpq)H7f~Bcw!ia26YjFQcxz9HF*QWV~1H~r-|D(8OuV4VGAmK zWcN-sZrsSc27hdlgl%Ej7GXsho4=^B5D`zcLx;>nQG8>l}{#muk9I$ttEj{<~kDkXBPeqvG}+Yu;1Er><`Bu z&gTh^m^RwC*w{I6|_eFi6R(vXGY? z87Y#IMqg!#6sz)iY9k&}N-SvxLi;_RLZP20|MB@04;~^OYBp>=m6)9&9%|n4j`#At zZ{Eb%*rS|v!D$>k@6uCP%bZ`~h8sS`b=O_X=FNkA>T_S`l`nY-cmMFmeCPK6=DHXB1^K=_ zxBcJ&{?|3vasB^(8=FqQjBBsGnlF6eD{R|#9w7Orcl`?|ZQMvlkYh><4q%f$b3FrH zUF_fgAek*&xUKjI=(Bn0zx^v^v5yX+x#&c&DMeUF;dxb7yC*R=Jc86ULfuDFO6Ek0ZO#z) z>puQ#q(*)J5K=nyZQR0^u0@_8A7-D*p*urjIzvn^a_Fud3=Z1t^yMMR zNov(Pdxhk~#Tp%2a>W@Nv1%D6Muw46;5Z_3>XA(N9%h52^Rrb$M8~goUBpkhhE@u&{KHpr(X3=-0O`o_`! zj%1G%D-ZdiDiuyXcQO z^~{S9p3j_LV<6JDh-J-`X_BlJ%}Pu|3`JZT*emC5WMCk{?YIAk4}IkI=m&R`winsB zuAh_FuA>ax?*}B^HLO{G8qa_J8+dqVl(I4nL|lf<>VT8-1?K!VoK69O1|(9tEYxz{L?_=kfN6z(gF z{9}y^=6(;}QL=RE++`aSN~JW0dlV0ghvkw&~&o?M`Ybm+F|;ThfjAeu;(% z$vHBj<|<;U!UE7GBvt&Dh_WfFBs$kpO4{5u?%y$lbR;8cluW@mx*hh5AfP-_B<|&TqyqS9k1ukyY6LmmrGhmDv>!!60rLm)^(r48{hn9 z?!EURzVqEX(OOg00Vi#H5|x_IRWEuGM=FX5r8x7F3t79ik5kUr!Y6LJiPN@jWZ&>G z?v@SotaZ8Y!gIL!rw>qMeZn;~(SZpX}hmv!BX+k8CFl%Y5~#H?g+2Kne&wLrt36KgxnK`h#zO<5r&c zg3D=-+srKl3=XDPyRo0YdgI@)^Um$ucEd;b#0_8I(TNhGE5#S?TFo{8`&KgmJA5Fb zBA4N$kh|aU6wc^OaQ%-S;>~~eWw6fzCL#O}u=57d+3xY>Z(hn%&)L8`zB|b$Z@bs* zXBBvxki6%m13d52(>OA^n+4_LI3{W!D;=t8Spo4splSF`t^p_7v*vt{tn3EB^QtD@ zyfDbl5ubng{P%h7d0m`&W(NyeanK*(vEc~{g#_{X6l*&3{QJkg#2q&caoyEta`CzC zOjdlzNb>nS#iB=h#zBV~9qN{ycoO4|(Rdse$rZ?m;ar)zA`FS!Hli737}2(f>WJymWBbmXNSWu>r_zJHL0NHJcjwg84v-)F6KQOb)bVaG-zEU)E`KWzNP z*NKGbOj+W9{~B({h7e#$u#7OjiHNj24v!7(WN>f*r&HpUifkyfaoV~h*FNpZoRohq z6C*=t9n$G;WFF{X6*Elo!!N&^&wet=2S4*w#OaRMowV-S=j=rx+?3zM_iE(AG8 za#C-CtDp8Xyu)|%@)!RJr#@*tZ91Ulk5a4bB$Zi3YHbfkRFOT8Jj})Kd-tm&W( zz$!aSBa>-a!zFABzfvKa$45xI5PHkBa2w$m&G2CB>D*3hH_c4mw{anowF zX$eS#q7d;^1Hg`M=s7TpSad!3l>jT3Zs}xd<$w-hi~!=cDT)4Ps$y)0kYWBOR?OY@X85fr4cU~YGpQv{dn zgO}@JT(^sI6xz4M_lJaPLt{nMfruj35+<7#J*MFqS6@d%NXpSvu1+)g+dNM%W@@|I z?V<(|wag&rT~g4{4mkJC*_0FJ{Y~p}Mn{J@ zc}pj8ze=bTT|zJ~0OdeXqU%rze>BcX`9bFMk{4b3D!j2N3LBoubr(LJ^@9bjEBpnz zt{IscXQXn7Ilo!-E2MNdG`tTd<8rVv!arUAF4n9sFf-*-+g_q~ZGqB|;A!Vx!QJXR zCTO@*^6Bq?pMQDxVaVm-v=nc6#g&X#e7^XfcR}EC!QXwG>IeS>cc2T_2}4D*3!tUp zMB~7D+Zb^3Jow-=pZwZ1h_!UBJ;)Q!-^@*S)Ogd4cd=p1X`JljnJ(@i8|l#69hX_p zJIZz8S8Z0r|G4$@Sfu~hbCebdv~G)hmK3u(!6PHn?7M9juMJ%8zWfy|D4%QI{w1cq z{V;$3k-y+cTlyLHs@yT9ARwZOJDila@v9my@Nv6MCPh=*x7?v{9!P7JlGDW^vk_%5 z6Nb?ka|!JT!;lV)178Z;1W#KQNy|FMwm#NGH1tyVWAk~4nun$4MzkEnn#F$81x!TW z8_S+kEPtLT)RCj!7t5ZTWvERUnjwy%kZE-N=&;A*O!=eXtkw$O_h@$t#(+S>bWKs$ zaTcOMszza2j%8*A8OfTyPLxtnAaXBx?7W9h-0*&OJ$MIaZW-W| z^(UcJ8DGGo-%j)JLx*_gl~?kTSN=IuRVXV-gHGC|UO_L6Evu0l!Z_Btj?1L)Bc+4# ztE|d*;zkpOuYUaB_|DCrA<025f5v&N&37~IDR%9ua`503Jtv>R3t#041#B&Ikc%G3@LMabdW@J_fpXz z+8bp-uA+baI{xvEtGVF(L9YME&2$c)$$}Cj>84cj*w8!34%J+Hbc^FXQ>u}clIcj> zrJQ?@+KXVd!G6>mZZ~rfhb_LI^?~wycG*n>S?B7SIGX z22q-PBV#U*AZi{mB4czO7;8Kcp&?CIj_Dv^^}5wePEHbPlL{RKWx&E+vl{R47z;tr z(xo(^%vfjwDVvLx;eJ}^NTk|?V>K`n24us~SdQ8jsceQY3?K+wMOm#J;QJN2yWN(? z!K8Rgb6Hxy>@_JKcLMU8DYE}?{QA!0?|;LxM8jH+Kre|en~QPsgpIJF9W>LpUDriQ zNwHWooaWXfO|NhlYYvUZynB$+p)Oq#j$~1o^`uIjtW41+jLmbi2@0iX*-Hl~Zu$I2 z7~4OJ(h3)ohqb6Q9j?*+)kGepJhIY!ZY>8p?c@6%^UJb^w61_QbcD`~M2DKJC77#d z)Wig*pR|GTU3+=oTi(v2kM3d9x-AGH8T#o?Vo!c5U-WP+CFgW8J-ibk zBwzUW=NP|#JL`H2OyjZVM|W`O+0SPEnv=+GI-g$IiPRPkKDw6=UH<{5$35n-NvJlw zu?nO64pH3Zar2jN;?=KyBXdl3eC&8dElwU&j)fv`_?Evp@*!0=vd4xr)NZ zUUrS{XLqs4m%jZ)-u2E8vVC6>vG-2?_MczFqBfZgH{W~{2ZnaBwXhc7dziY?B&6Wb zp>gKByAfLRwl}}kXjc%tuXsIo?Ap%3gNp8M!84z<38mW5GR41q=rC*;(e~+=@%2z4rRaRTMqyLAOJ~3K~&!-9%(+i zgrp{prgr=~nvMVIDD=|%%Syp~%e=^}2Q{Tw5E9mHV@uy6?OutvuHc4}sh-uS@gi-# zv#fUtMzbQk)*zx@tpS4ejKt}5&?Vn!C5|fQW6gclTKaS5Bg^0Uqu2&k7@9`GG9q|e zFXeYMjuP25nvIJNk3mM7je}@55SG=VXElHKX!=)2gvK0qD84MEzE!9%qlnF)0QYD% zD$Vt(iKZMcfOr0QlO?gtuYK8d-nMMU)-)W!mK;`!QmG0^hKKiaazV06NYYx-+ZFJa zFS~+?J@@g#%P-~9Z5L81?kCGWgkw?hlXR}F@<-cp`2Ibd)&CE?_mkh^$aTK?|O&!vO2m>4-ovgmV~ zD_MV5lDYG8_rmQvSdK)c2I3Oz}GoHy`Iq!@ueC5Uu@z1ZnmLGiPP1wFqIPMcDCJ2aNS-;hwr9akMgEhUqN@;CN1;|+Sl<93*YxiD9z~ut9atJJfC~( z#q`KSB=rRKV45T$S!t7ySwhkXkw(f@bZX6_H%yy8$c^v6hQEK^b4Y2AP9zB>>Fph4 zLX9t36o(bEaxoHT2{QfXvZHGA!H+yhtlrIZu|`Jsu~4*l*FSukwu;ZE-uLHx@P?1I zZjh#kH5YkEH-ipq<#H=cc_y4C2+S%I3qz&@6PT9GX3<(xt5k@EVH6x0U|Axv1T;d^ zxoDcv&+&mIq_`=tf&EMK5ujC(VOjw zK$vE_wAD(PwuD7CYNRTaspxT%4k59GZD@Srw^dN;)Vee>> z4}9PTMkfPq|Ms0c>D-GrW&I|T(V`V|6_0rog+c!#sHVL;U2MKjNY9Kg{U9aUQ$l zVWtmNn0joSBYS=B`Nn;G`9q&&`>l6lxn*W#z*(0*k$d+%#5_~9JBxgOCs2_fG@p9u z`P6pa%f8Vnqt!auT9un$@f_M$cX7(#R@6j|M6E_;=pI1xkuM#DM@t|AzW3&*Fa?ZG z8CSBquRV+M?w!n(CiuS>_ki8U)PZqo%Ip=*5L#o_u+l{1`0K(ihd?&J{->ZSCpwyg z$>uo~Vv!CvGFCZImv$zObdYud{#+GHsvrhG`xhi zT4IGW)`>o+Fbru6L)t=(B^FIyNkq9KY8)CuAR>!mt)o1XWnaq;j+%`~EL^gWZU~Ep zB_cG%giD&BNAq_kqsND#J|Vq#zBw>G>T7Npf+K|0dOqs}7gMugVcBP}{A;Os5s@vp zfWU`9u^>*o&$a5}K!fAZ(Pe_qH*FeV&i6>7u<+TETg$e-2Cu*NS-4EluBUOF1Z7ns zE(II%3F7Jq-8v*3AL7#=`5V6Rxi|Cr=U>j{7oOfa7dq0V=%e;XqkS`Oc?-&?uPeou zKlLuIf78qO^oL)^MVnU>7I#xuhba^sgqXqiN3jS=_yKV>%$r_z1x|Q?tDm@@HJu^8 zUo^B}r>nKsSo(OMQS;pDpL@TbKS4vEfXAQc{k+HHH9E6eM+xkU?NJUM;Lp=x~6AfE1&xA zPCojXZ$a5&P2ab8^)*jtd}tqIhb(3u%yM&3<>p&n!+*TzpU_q(-qZ*Uq0!5{>y=X2 zw#7^k5(8$!u;u8}VHqbdA(qgNTE#4StFl=dVv&VFGZ{>^nu!J`{W%B%db3$Ngkb2v z9(pqdNl79|WlYmEe&8^x*Q_z9NrckGLgR(i5Q2Er_y{4WXuY!FkAAL!gk_P6ERb`# z9J_b#CY$YHa`G^_T#mRfIVz$h6c)s7AZTMo2P+_GA;izU^(B9)O;Z1se&-Lz|4YY` zHR$rt(q@pNIA(Eg+O8%Mkt2*kDb*TeD5W@g%SOr*C6rR6g^0wMW^;{4_j*!;)`Q%4 z?<{}*nr|45To%Ylvw;RcsLc8mY9kW0#7eGOM#5na(#BziKpST&Fpr(wMfV2y!N*^R z6;0Xu3wg%8V)R}$j+0`>tJ3e}IanMamvQl?ycVT2E(LoJjdD_77cYLr%b8Y+O9wVF zG&GErFVLti@|5RZMb44z9WCMmGbNAH&pneWmryA5a(H+*e${8LqIkx0FDEV?V-s2$ zL8crIPI$cNFJ6x0q}Y7!B^;da5lHF?-tpc~pj45WlE?lj4`~aWjKe&NRb2_%#W+I1 zjvb?{KQlqivv7PtK{|lq)WJda@2|6ZpqFpmayw64zl|T?@nf{REN-{Uqk9k1*SC&IQD$0(kb&*kJsM|nE(z{cw}UT)o1iGheL7qv{~L(uf?y{Xj2N;%||KH8iAte zn%HbGesKegl~hmhKNL(k(S*NgvyYHurDUFQJkKN4Nmx^0%9T;hied^0p=MkeZ9vc9 z0I2t?RvAF_mS{b1Qkz;NwyYu1EQ#pbTSM5T z=hR^v!di^pgL$(_tSCoCEVI^Mo(Xlly4I|%jYPEWSmPatXJ7v6 z=t65204v?F2i!Hh;kxU1+iTCk^L|2gO3}OaLWX_CGq3$KKK;>Kxb(R%Y6t_}x$AnrEKNm%lT_Pae1zI}h=c17#m_g4M2Mx+s|R zH6MNdmto!cfX|bjbUMTP58=3yY(C)Jm!HKww^Tu#&MRL3*L>zvA8Ca%2`MQSJzTdy zO^67IFe&avBX31Df?!6QhGU+PO61UGXR~B88RiJ7=nAo@$!SE*Ogj*>1WvBI)tr`s zfZj}wxGgxe`v6^b79DCP%4NE2yX9SO+cv4J2?w1CwXqb8CMrP?Fb7nESylnbNXJqS z0?Oem2|G;~LWh;cpFBbs8p>BaT2q?tVOlF-@tnOoq zDcbv7(z=@;e)|rtx#oprQhn?$?jjyo)I=L;ktObAnDYZB4*7JF<>a-eun@E{<0(3E z*yNtV;i+9@P>ctPBz+Y6w@}-)7y33+A9{e-zxWlrZnlWre}pL!QWF+J1T5^nlZwa? z(+)kJ#adVJ$9TERq9&oqqFC|~19V8jG69bb%Yq;<87k3Z>?rL% z3^n!HV1X^D8&<53l`GdKqOw&M~4(tloSErw_bZLxp*&8%^t>OI1BS3HduyyD&5`Hy3>?E0W>j=imbcm30P-Y>}bmlVnlSgRsFc$(%BjT0na+$z_WQ4>VK70V% z&Z2dIZ5xZ~xgcQ8nl%JLKxZx!QNJ?iO2xpcB1=}*}Q?WUOW z$B7F`Om!nf<#CaY5urI%EaH0IKn840tlmZk6^>|!jJBwX3Lr@73`y$D18qp8K4M&S zP>4i;)`GZ}B#8n+wM~=)_bYA0j|a>=o@L+iY5lLeh+caBm{7>y{GpG#0X9#Ys}=i%WFChBzs5Qz;2@gA{ag6xS10-6 zkAGsCgp31gQ`~;p0Oz=pDc@p5baGK)oWB|=@xdGRz?9&s^Sk)#=dWXfqd4=D(+QnH z94E!wZh4ds-!=-4)Fgk4UX>{k))K8Mc*TzAEY5958ZPwi`9ADu4&c`4${%pOMBht^I!QkbEECl zr9)XM(lQYtLXvrH5Fe!j;!-fHd>UFahb9&Z76S{{mQXclj4NCgD<;1{N|(KN6(Kx@ zuWX;-FD~i9FV)F};B>+DyDT2OtpLG5KEKX`l^9RDNR!3nl7#sJ*S+q);DFD=V{Pob zB*BgyGjtD1UiUzf9bc-#*4Y2Y-kXQFRo(gjFD>WVI#P5c``WRb*bYv}LP#KiQg#9q z3Jrx)N}1A5X{STmnU>ORrlkv=?wxk%bfpVznU?87fq|A5TA&MC+1CUTL+r$>99y<@ z73s*nN6YVzb0ynJNJ`7h_xqjar{}p(99x!T>E3fbpU-=PQ40zt7vO$xi0glR4l}uJ zh5Ljx$V?>Y-rR9ApRjSS$q1@f4#|nii!wvZsfZR1dK+m!&#D zLFd?T?9pVV(j=uMr~^c!!qAqrCa8^=*ltTQHa0;MU?&9at|UF)?`Mb=(6Yu12}(i` zlt3Z}lbX{m?BY9PX>wCjOgIx1v?8TCNr*L!N<}~_jvBIv$RhcU2%o!Y062>Gy|;mRh}-`Yik-au9lwKI4wju|hK=uN!sI}x7iA{0e~Qdp zBDcACZF|n8NC<-rzA$S;yvX%rVUa$6{S^DGJM#m3^?tAMiY_l$ljmNe*JxCX6Y2h6 zUyJG{&k&F&CL~QHsOlOaJp)YARg~N%x^bld>u%6#9!sxc-MW(udtvNuXfIN+6g9UE z$Ph@leC!?XC7Bfb+rRx+BQ#i8=JOJm)cK&sL@Rg}h$6ES08<3K9xMyu!VC{1QIn+t znkC64?9oLgcJHRMcPUfZVxzIB4>ar4E6;yFW{U+AU*LIImT1tyiiILo%LwVMSd=D9 zP%M~%XR~GKVa;9uLCshcV>KEs?LW2<3w14ZjS7C_6pcoi0V;TS9t835D&B(d-RHM% zCD!T?69U_b`TD|NIY#wUlvD?oeeAvb?Ip+X;Ibn4ur>5y5G-<9x#r8)@i!NAX-mrK)&V~&e7`tx?=qa@Jn8}Rt&+om6?_d2D-gxDYC=6|-s)V6Wj0_UgN05}u zK|Ko-+qm?~P2|KF15;_53dPq}E zwE?EkPbN$Vl2_D#$LQ!zKrk{gLNpddTPA#QdV0Enbd?KpR)KZ6v>C{I1;C=ErRdYf z%+Z9!9uq=y-i4h8gg5i}`0%WI6dUM_@7)Om3%+D>4U>2;b5!&ay z0&y$Wup>++iw*u~GTBZkTcqf_jzyz3RZAKh!<>Ss2c9WFEghw-G%HixJlX#^%ThLj zYX6&2Q)45{pmmLy)da;cz%#l4A^p%W-$hJ_#zj>X5U7iS#oU;te*Zf1R#BQJDP9yM z^2Ih9^-a2dzv@9Y{ukQ}R1dNGiL6DPgu8t`&pbwYGKOzwc^huC!6R<8Wy@tk+eZq|w#7k*iD;|&!!Bo4*x z{QPRo&u@R2(Vtz)&p-VWcE{74_rbe)=+_xIu^S#q^T9{T{OVPE_~HB8sEk{zTGh)b zo6cbEVQabR=9{_r{PWrEPIAQhH9U0B1Kf7oZG7PiU*Hv+&m=q0Z$!9SQP2<*g6A?W z4?MnwFMZ~-Y&v!$XPk08k8at*cYgRoKK`EfAf@D@i!S1hyZ?mDml(}t_OVF@3n2mx zN~jbPEnr#1CX>k!jY`@R4xU!5T(`PGcOjYpkzlcqwA(fiN0o|%WSD{kVm)*hH7nP3 zF}OvODfe*MCvSwE0Z4R0RN~n-(ar$NQgL!WzZ*MN#ES0X_}3hVWu4E|*wY-l{^gV- zMM?_R#BFjV7uRuolK}S7Lux;1x+(>uQ-;QtkdmD1q8;rgUwg!evZT#ndMrankEBx6 zwA)JYt)vMPaWrCTUA}e89X{^i`uRZ-(#Ly0s)|ULWFsoc& z^#7ON>eJYybP%FWTbXmPJ9v1kKFA(xvS2#pxFH=z^$;Gw_|lX6Ef%P0$ctFR&%{(UH2;UkGG{Ubz zZ6@3)+HHqfBCP7};$N=%Fnn7PimI?_?|K!RHg4osKlvUiogt)hq*7}TLa=lD zGravRoA~CJzriamI~O-EQ0|P;0V;(S5+MaK1i$&kUHtt;%bD1*i)OnE4~HX8JdY>) z`Z@BL6Is%`3a!mK5?Tc_ZZA8AhnN|7oOC+G+U`!WLmATP9OqwfF<<$?=eg$G3vlzk zPDz`oMgG6Z2q#!BmkH`XBN=ZJG1_{iCvyP|TO zbKEi9eDn24DH~yvP5zrSiy+m}#qGcN8E2n%8YOo(ZFZ7ododsW*vEO(-~SU*rWO=a zb+kzNshGBHv+mT37|E4s!lDU}wLK2k|L2YL_D0Am#j@0L!`t4_O+hOv$}-8r-Xs;F zD2}@6TEcv>>FkF4kTkO3o=LDs*}7dv%wklHc_o=wPp7))$P`53LV;9Qc0v z&o~bD90&gWx>$SuQJwd-QZ6%o+PQ7p3$#Z6b2sslAxtmDYnlJ2PisMUR|mPFK0}i| z`~*(A?7JY=!`dExdfgiC{qj2Q`p#J-k8gz~=kuvAj^O5xBRO?EH{Lx3?KWS2*Gh)( zd?Re`hMeT@K6Nd$YM#AoCl6isG#sAd!LPlN|M>0&kd*xKt|@ZEiN@!UNF=%G=3n!V zZ+#0-KKUdUzWSA{?CIu{A9*i@bUzV2$)mSiOL=S?5B>TF?7Z(*#_qe72ky9@@huP0 zWec`EdN*JC?7y&lMK{ywK~6m31n#=`cWmCgnPjrPK~=MDo20afiMjVeh_G>`k)ny7{OZvtG0fc~-4u_VM&GQz3B;IZtcgfUp zE_>^z;0YI^osevUwl;D?6Nn4SQZhWMv8*Nh>t{dAgVOe9vie|**K?+{!jY$?wY>seSGedpW^(xZi7d+kVwQ2erhEX zq%%_x7NkBl!94d;pUoHzWfxryO*2i)h5)pPM_*%?cf!gFQz1x z&^K0M!VQqgOpuUK&N%8we)b<Mt!ts0 zHH5=ruYLHhUn{~vt!Yjq{0$~WvmHn4B0&we{Q4IR4ej8QpZpkGxAu`vk0WJ-q-_(D z#xB!jnH+E#GR1#sid8F@l1}d=E(J9WLqlVXj+QxM!zS`TNh=b5H)|F{GnETTK|#Zc zjVE!-W4Dp$6f{wz&6e!^#bb1~#@Ut5Fsn38{)Jf5il78Fl(TcuWs&rKb(@ZW$>h6RrzU2Xv8uEvP8Z zG$4oc@Y7odIQt(rp$5{dX-zTGzn!R*R5jSG4s4x-Y&);)Sx!{tKni9lQc;6QCq=1f z-~!L{$YryQ$wD%jWO#U(Lct>x3gNmg)k>9UEJ{m93u?MRxumh|*c=?&KvaxXu!Ti4 zCZXOEf~ZImjYip{iv)|Na8D+qlya)E;9B)*OUzm*va@1lDq>k!mT81$ERS-*^HCH( ztH(3z{45Z*K$I}N%~L+ehFK7c z$Wr3&!Cj{4namMuZKY^u=uSC!8AS|1NeDtZj9I260bzKb^=Xq4-bu<*64D0glL*T5 zWnO;?{-+D^px*m=7X}w5ZQE>wN|DJ-;W(|0IlAk+jr{Mv9T*jwacYzX@+^}Q zCE>dJM_@7m33%}8*Q3TC;t(-Tz|Qf==U&T-Gky#cX)^sUV^%t#j{7&$%(xk@|KaZ$-S#9=0b@^PX-^~=*)>5Tkz`g|Jicoe8;?7K zCm*_xOlFMpH=o1JH{C?%5l67ZS)ikNF7 zmbP)mg{N_wUJiHPLb5Z(pa3{Ivq5Eih z=pkA=JDHrE#B~)_E6UEXNg{~^$+k`=a+4Ib$HUv7X1P}U<`2K6v?IWx&URck%9Wpd zKX2H)nY@IOg!rrC}PpSPebxt&OGl925&r#dmbLmr)!a_vyJl zWXfE@``0xof^>SEcDvOytG1-2BSm_A$hW9}DHgoB>$CX)bl3g;Eyl@i|37P*hX^&Z z_x&RCsBQC~KQeD^4Ui;7S$d>^CL|S=Au3(obn%g#aOx)7Q3zqvgl3jOl(MKOhpNy7 z>`9(g0g`Asw89-uBc(%gLJ*Hj!eLD~?=Vv@J`p%^<0v|l*Vu8}go{{WuYz*U`Eqn* z1k18WbhI!uG{kql_H91!kq=TR6tJuqgea&_K05U5k14c!3Bn$Ff% z{`8w$`QYg%GUMjZx`4D-Gn@%<>Is|C+V(S90-y~t6xIqYY?k!)66;(;yDqYI@b?_o z(`Ix(xg5Pq1%;_R6{Shqwx5?}Q}VCRQmMqz>k~w+S!0tfV02QmxaVjVwWd%?H}ah1 zy!y9E3VIITz>X(&QuLabbSH?=K~PVz{)jmFfj$;@r4Z$MgJ(dFa@h=XgMaq^`NBV| zBa>ke3(`C5u2M>CW?aR$zH<#1UwkpPZPRYsOt>zinJHo-jFgh9n7i=z=laoXN0@Na z%($>PAx8jI}3+_0}Cf;NSDo1LV;e-xQ&XJl}Ma5PFZm3l$i*ZgM12)`_Zuqe4%EE#3v;j7rP zbt~;ooTr8|hBA~ZQ@` zho;O79(A^;hoNhEK!t#@^V1$tqQ<}6^Qc+^uUOAl)kKL>q)3yVvlPyI9&yVeQy~9B0Hk@-)PMKMFsKyL8g?R`=SXS`9x4~U4yWy65F?L=gc$D zXsiVl72YQd?Ehrb@IQg*?0uVH2R(8VB0tW6TEm2zBAA(C zk=w^(KRAogOrBM#FrLT(X-L%g&@Z3mEgKHw}!*Ge409uHXJuqw5P(Y_tX z?l#_e<}utarb%~tFJXTFkwZBJo| z8fD9(s1%)@hcGraN+JPqG^x%wyT-<_?F7HLp2O1}4*AWIq z)(@|3YEVqVK+WIE0cupKqY{!PEJibF9LMIlEn8vzDj3t$67|9%%F0wPW0~#jeDE1K zcO5f3`e+T?lvJ7fuK5s=?l9KX1M-0cS6oJ3G|}K5596Xx$r32 zbda9jbujic=pojxJDXWrnG*1Oxri02jd!20hOb|BE!E_)bX|Ne2oJn6|9IZZIcq~R zyNA_0`m3O-^-Cgh-;>F+eEBN&WHMBR;Mc#tlac-%{LLj7@8c}>mo8j;Hzw*uQ8!u8 zSnT~cCE@M!`12c+iaxL*k=B}7r3h->XjCl6qb6Kjw@gS*GCf?TqRK34Eg(dKin7pU zP1T*EfW#^*DiL%2Xl;giyT-Q@^om$k8$r*!CZ#paLJ-Uw_Qw8(ULhT5e6Gy^(I{1~ z!06~GPOOD@Uj7dV5v4g~@T8fLnA52Et8W#*kqCwxD{?h7m+#@tYYaWVA;G6*RjoPN zw&!_7qBfT0 zcP}IT11xgl1a+B=JH;Yu2$2B7Bs*HoHC9ZpIN|I=#$LE#YI9$^gId@)r9S)Qy|f&4 z3fh(oE2sdAdyW8Y8_kUbTSw+T8%}HU;pGwyy^7InAq_Qc|FMqFY95X ze+XeO_cdez7DPxSV_5F-(t*(4IDjCl zOy+k;3eLUoJl^@vH#0VsA(KgC+YU{DwByXUd8CL?@}KC1V)c|Nk@RgGJq;EXWu*y; z08K!_%d#jEHZQcn4V=sPFjICD61Kg+pQMZu(6e~LBTUq2BYY@Y5T*&;ct7S3+Z|^q zyHydbJydoNO+ZC~7J45PWj=jncHYKR&>qX=QgXR%NEtC*r!9@1dWpjf;JO)3I{ZYM zPwZyqxA5f~$Ke+@!pf9^adXNP*AoJ)LwW6G5z5gbvq;|g^_!uXFygkHg7y^4iuEAI zA|X+u;=#m($xiV+L#c9NEdcCxCn-*jQms@W5X8;8goL>&E0qdC!h|DHVn8?+BN~k% ze6fA8o)nMCRmtXZ?D1(^RUa-CejrmQD!>n^Z;d5srif)(LW4D zK-h{k;BU|KeEMk7FaGC5(KBw2Jrk3l4*|~<_<1xgFgRXjvRH(jW6<7q;L5rPOys~y zfTuY5&=jKsQ-q|%6FIb+b6GM|0Q3Jqo%&T&pv;s&>!t>s%0S81K{wLyUYlE$8vifd z_8WrL(9W0zO(VGDjvKi1&U-lV#1jxguzP5nmQ<@Rko|9N62$(|swTu<9)SN7@7KN? zV8sm(cOWoB2k(qGE3N;7(w?s%3%Pg+kZbsW3WX>?hUEf#6-TtX}nB{MdGQbiJpb^^LcE>}d#D9;Z* z$mu7a1hmoGsVJx-ZEX(MU3Wd}l;Y*boItzn@Z6TIeB>i<=Gtq&Z3Ojo!K7~isj4c?br# zQ_Cxwb$~9rNH~(CLsy|Q#r3!TnjPP}g5CXZVXa*QcF;1ijjw;_UueeVf*ZdMS3L#~ zY~j%@U>7;ns`KLCh*l;1MSDURb8!R=Dzpd)bmpvE;aQ94>2o<>C`rt%rH4Ea-NYAjjeJXC2OiPv6Jc zsaC44OF+3yOB=@zpWAlp+xgJ1pW&DHPJ;0G(tD3#b9XPhhsVuzuI4P_^-E;;)ojO6 z%B3mlVR?Ny9jzp>Ytd2sVK-{umUa(_b{JwY4V_m!A#A1wj1**CV)v}ME zn1Aaij_{wa(QJi;-}G3NOa7=<>v>q#9I_&OEnNNU?c29F#!T@*(s7CZxo5pG8Q^cV5nIVr-F0PwriQ_N}WK{{rw?ivvP3VOd60e>G;?k08 z#fi5vJE3SIN(qaaD&n-Y^VoA+$xZcRv79C;3F_I7y zSu8pa=_RL1z81#v-DWf~QKJcCy&Fj+*fBJS7B!@dkxYhp><_sF$ohSnZ65yQh`cw&-6yO*&}5MJ6{v(Z7(R(In}eJ0WSY zNLWl{CrmR^oI^F=LGsWbIaeUL__pTE?mB zNu-Pr5S|Y+N}BKp2#L%%*Z;f# zBe%aj4KV_d>9f(L1GYAIPjDeTzFMVG&UE3bYvLtCe5bu^DX@EN+MU=MvP zLg3cY*k9iT%HsArp5rYaJByiter(&Os-1afdA-4^4=BucmpCchOd73Sq_nYGHn{xTHWAb8COTx-QaBN!GmR(mCl?ESmVL>5rM znqHv!nQLfj*wRKy8?8++wk;%yL^oJ%kn1sfTf#AQMs^JJprPLh2^Q2WgQnQFLrK(i zM1oLR<2aIPNz)XUI9fARHrJsDn`_PZ5Cb|u*#A>%mT6W(o<~*0$PEuuwV-{;Vy363 znejYkJdcX5fG$z3&5hp{P`_$b$|b-@Q-YqyjAaqCgx{p-hIk(8A&=ey%}U-YU|ANG zN`-2r%523W7zhGobj72_!bULw1gmAdU>M6|0ea$j&}7lTeu8E52fJ>Gq>RvP3%a{| zjY)*BHJouvXtde$>w9p*h6(K(2UHJ^vI{{@X<8#;)~;_SGdYRlw6Q~t5ECBxyi2n* z20q{t)TT+O@BOYSVao`+hX&Y_8DqoRm88eUXx2qq&xoYZdVV=*r&Bi+SL1MQN5VIm8!{m#7L&CNo8McPle)7|=LQD_LLYX4`SUsrmCv z)E7B%_GB`w=vu|jox5?IC5&W73EELSax7Vzjy#^QPxqR|^D|w{bC*Avdm&b1_fkG5~i~hD@CA2rS?J>Y|UT5E#Gy+ zge^sqQG{htDP|3_A}nIUf~bY3YZR4n_8^)Aq6lGAkqM+OlF*8&^!=>0ZOW;-k;49w zilo|swxOVNL~Mb;C6l%Y$rM7`XcegE()ycbc^;xtZk&sC%7;>#ntx$um4y}uLsa%^ zHukaXJ;*hrU#$J+OJ9iZy}=v(SbZX{v2BO`f$az(aU6#k*X8-4VI0SyqSXK6IS7B< zt<~)yEBk1+g<BT#i(#ll1r?d&Wjt)w2X)L3-CHGLgU%78PMJGB&}=L;{gBS|mHs z#_+w5(b01#kw}<$TLRmT5Q;>oWL!=@<^+a@o~N&`kE*a2G`LL*gxH#j(zsgDlIj2i zqnR}AsSbkLC7+*ydv}45EX7PoXZ=eegXX(;{09ECgtL$AWJdKfNt8XpW?5^B(BvK% zE%TXMZsgsEpN?m@GU5(#&HW=>(Az=hs#dbYCDu)C=dEIvYexnNpS+QDS&@_`BzIax z8<{i4SfZ}YP>lw4&UnS4pf##g;@Fc;5Rpp-6^KD zYD5<_NkK)Gk&gVUk(H`Xxj}1|F7L&4U6gWJy?Pb>{R7x`e7{KfoOVtepb1*IW>)sw z@ciYkKd1x#@~mGFF{!+O``6qctA}ybkFo;@p(*GbmI%|*5rtK4Frh%?AUA0m-wi3Q ze9L*9wYrPyP?@Ji2BBQqf#-*Z2t_0_d2_CYw2Kfnlam=jMU(no@PigX;O71FvQfNS zjRG-`ht?Jq&z%2Gtc84`(4dw#hnhe{@Vo-1$}l^9%^y|<2oMaJpvNeF&WUAAd_uxP zYh%LG7@E$@V5z%)#ewPR0qBTuI8~K855R&QiAOTO4%T4>|zC}$~ zNNKUeNg1lVm_vMt) z%QvwQyNMGoMQuo-EAc0B37XB%xwQ?V`nn4Y9}(`jTfX~J|OlxxKEB#0`3*Og&src7`6Fvj}EIXW&m z`qU1fV~#dZUWC?~XYx@BoN2hxl}d$BC`7edW$zl^^E{(xu{2tEL=uui4`0Q|$OMsOl3Y%)C>mu?u1GW* zGog(@B$*_?dl+Y43mpuw(0UXA03ZNKL_t&qsZ=WL{UkMN{_^EBuyl#4WvGAklXg5i zL2FbHjm3xw;hQ*UrpLx;vD;8mLUb7*nQ_zD+G0`_DQM&BHmd>mz=(!IfLs4s8yHa26aLDLj~KPPPu?a%7|}SY$kZkwq$5%oMovFvdTpWNyXPM)ZusI?6k0uXhKjD zZUgZW!e$o3XP-d=ZNM1Su*7o9gi|TB9->bRjs&Lun`vhY?Ns-@?d!V6BsH;} z(~s@qcTcwQ`^N$#-=^qDFT-(a?9!819Vc?kRrkXELtL#L94#O@#?|MXOME!QxVx3J zj#I>(KX-UiYq?K1CMp0 zl%^~tEB7S-9}Z|%n)TPou|2;ZO zRC=sly%xtgl7ilW5Du_{)vH=qao#l`+MumyDn7b>TkABqtNDl5{ud+Hzm`5*Fd~Z_ zJEYjqeGG5;*#j6`v^9)mTvqhPdE((IctU_xh9$~qB-=DtJuo`N$iQ}9w|pf#hVn?6 zBB&L!(jlu1>Jc#)Ie1?QpRDl_^Y5o9RbZPQ4@03=C0#-D2nuyx4I004>ilCxJ z6pM&j1uR;Kh*=OZ$_3-#+0qijv&^J(wlWKq*?GJDUblduU{!R9A~54Y%x^}tpGd5w&rml@=y#%yK&ShBXy6Nf~^nEZGi0snWwxQuz8MwdKO z^F|^RnadAswhg)_Ww=3WE{YmaCFqe*6*eE(5ijI z0MF%6X%j4mnaYI^B z6IP0_kKQx^?(hIted2ONZj@dpfz}1m=?Q8g$*gF_acpcmZp1($j1Xa}qDIhv{YRg0 zJh$EVdqVOkv@Re-lEYSnxcI_z`1Yqh%$L9Z9uOHoGwW*8q-dA>{`ft<`Q10u+qRT; zThQ!Oi97B5?tdQDXv^WK`Y+%u6I!_DIZ>~QwB7uq){bh4&~dw zdUHa*Ih))$ul1nTl(I#CLoi5$C4`?+ZxU})ElHeMY@Q)PtufJvMD}%Ds%NQ$V=*Gh zB+k+$G-FZ97HMx!AVdw%D=<~e(vfIq785ervvQfgz`*e2ZiFR>#bSs9xL(z$LBMzW z3Wl+)7*z|3MNP4oLu-?0UoZHYfMQW$+lEFWEQ|mD_J8-SZtFbXf_d*kV3Ff6ou2Y( zrEY^FG#|Y*R*ZrP-yYp@oCfV|-)7KQeKz~;C(30OO-M%kHA}Nd$QNNx`j@S1ET9GL zzW|DG3Hud7pRyJ3hn-D~cf6xb&81={`J8w6(@3etb71d-$hw7L#{P zc-h$47{xJ{XfZ$=ZB&Lz9Ov%HI-SESueAZ3l1sG)ThPZyaT(>NsYGG&s= z;&z&6e}VHq7At&C-+2uYhJqGb99z|vU4CMKX& zz(wb-1;(Jg2mA7Eyl>0-ymr%%A+dtql|>HQ00q5+S<*DyMP?V!I_IX1QidC7O1teC zlG_L>J z8_lq2<#I0h);+B4>SayZLZnjM<4*CzZx29Q3X&elOo`<9FmF3M#;<;UI`?0@ksp6# z2|v8)SU^H<2OMT|@!4myV`$u;Dyst|dcUNjkOemB^?gsjL}L9HLWy6h+n?j!SQWJc z3_6rwds%30_IQ(n;qu@U57VCcJy&dw@zgg?<~yHX$;q#ez~MF&B|p3~&-*`kBOmzY zo%By?YOOX!ok4ppK~Lid+pnX9-vo($DaZBLdaJG}H3{-f{+?V%Aj}bM(6Va#X%Y4& zQdBCsA*iqap68hq`WcLdq%NMXBP&5|+)3+4xm2X=XSeOA9U=e(0)YiX(fPGb{T#9^ zgFsX*ffcgmQScV7JqP_P=aoC5KWBewPx1WV5L)L^O7SKQR4is}dxnBe(sIZKn(PR! zJ4IE53CS8-8*P$p+Z46tn3tbIP6en5i#9unLxHF6{Ta`1eV7?HLr98-j6?ea*1VhH zh8sRhOh}}hA)i@9v)zxB32wXVKRIsGrTZX-LgO=0%=ul<7qsvKs8ibND_U4TQnqyTSnL7dG!WGBP`=+mPpv-axT%RWOCA_wNp|VEY3%y z|16H<|K*B?|8_G;PL2Yzuvq04sAR8-0i4=larO?_8CYo)D?Jr#Ebh=Rl%pT~S zi`Jkmf=7{%G*mRC$!0hh+V;|Xj^YLHV^Xy>+o$qGfQqYF-T{}N)yh|Ib-DF7;{+bN z4_2H5gBf@}14P;MiViMX6^4!@`R@1c<@t#o0vG-YUcCXXdk|R95gTmQ$rRt-+{C(H z^fB?9Jb|Hck{a0A3GE*LazYEaQkjU1Ff}&GamSs)uBWz9Ryj(!0_ic2=S7yjr=KE{ z2op@y7#|#?wbMp>5JPvT-Y?QnDjBYIJLQ?amUtNx5oZ;ay zY`fDKuf%PR=Bj5PQE#URAc0-ZxU-d>t z2mVN})6I+ z-~29*djWoX=Zyqn@c*&*=JAc4<=yw!lI|nxKC+HvAA2l&>{&BQGBe3!h9p1;2?;5I zKzUkrO6bd0+CDrK+7j0Gp|reR2nG5nFKf$E`T`A0Swex7ums3HkW7-9$=H*z$Ck%F z9_h$Bx2$t(dH=YNWOA7SuHP)DJtSSNR4c~b=HVa|0m*@DM8uH+7FO!k<$j~~7N zjkL;(^f-Ac(R{2T&lrg7C$tFAcJ}_|0m$t!7kfn4`$wAJ`jlkl(GsiEH4N9#2q}pR zgD5TgikKAi=QFGk0~}QzG3}A|eRky~PyS!O%>k9+9shba4}I#}U~OjljtBYqxr?}i z8j)!+E?tUqRTgJGdYnhub0VWfgd~g_s!Zar66~*-Mr%`aJnN&5Akk6$>J&<&WT+Pi zD*<8Dklzc`BKhKGssD%!@u#Vn~(FrW zeCQDO+%w72qDSAb3rf)&Eo(+UTp%nRNd~T%Og2R~vZ6cH4gL<@xyza#5b2C(r?X!t{^mP$NW(Vo`JG&>^#M03+#P zyo%vTHX5f^GJ1M?XtfM~v=uEP?TSjLr`7#ks<=p%`BiptB`CMn|ACTG!)xT*KKE(Z=A8VqpF%hp@5V|i9|=u zep+i>*X5y!X-3@vD$(ys`4E|2HBb7?8k%K#z=rV`J)fqCp>?@KJw5LG?`k|GjD1>b)A)mY_e zPIwj~A^812dJA9t;uqO*-Nh6pgZdW*TZ$AqQ%e>)ruO%lXN+~K)KSB+SUG-VJ zaVtOGzn?FC=__m;aar&@76Y(_%`=|i^2ay)F)w-j8IY zG^cY$s?dEC2N)k8=Vzb%EhZ+)962z}Mt1<$J%uG zH`5!B^YWMf56-`62gi>l(c0!;zV<<*tT|vPr)0Oolb_8k{xYLw3yp*43r;APFMaPW z&{>|bD`j}_Ti5WSk30bP55hBNVL?L9Io1rc?GwmyS1q==E=Gqs21p>vNy#8`7 zb;~?dC{Pg&145vbM^n0|rB*$$Ns4$(f&DLTEk9EL`^e|r?CMcWcKT7ekG6Yycp61A z=yekKz9yy&9cCyJDwy}H6xAZ@^9iK03CQ!q+mG>?4}P6H@1HdZ#@azBdc?Lk?A$cW zP$t3D)B?V>ND|4wh|7t^X2*>ZEu0`Ol3cni z!_BvRnW>{kS@0C=M@G0{vqN(8Gnkt?#QOXOgb-BpJnJ^CV_7uW`P64}=fP>>l8(Y+ zOzY0r6v83Db%371ZJY?xH2q_&&u2L?^>h5-2unh9OthHa*Tcl&2_Rt1NwD2*u~<04 z1?OyM$f@G{y^L;O&!@lsAb)VfXE-!>5~6q-neHA$hw|k(PKQP-rKC{s=oLn3b$oo7 z_uud#eBVb(iSPULIxBleqIR0fMz_@3<2^jD%#Mq8@PmEdM+k?bb7g*X=r~vIuz2s= zUr3(|`Mkx9H;-VB5B$Zeu|yMFWRP~6b2pFDP#Uc?A^i+)+sb=C^v`_tC-dC4?>K28 zNDHWSWD|R+5Oz=%A)qh^AHC^gTzmdgxc;q8T7}DLiNlO<-o*(8@4No3WV3=Ey+lG< ztRLA()i08iIWq1tb-j^)_{fj=z(4<#ho+|~szt`fhw%$@hH8?_!odfSQu6ihev@-I zUP8ukxN~lTA!J0i5-bbo)!mtR1a+TO*)eE}k=+Xdc7Kc%r~1hYu6P0i+h5 z)#r}z$s0aGT*I=jS>re;ulxjpSZ9A9yOR{(SGdAw;=p}a4*tPO{%~iWKmF8i zu&{5LG8#CK@$nS#)B?feJ_em_RD8ipceME3@4lRU`%W|G*mWsZeKuZn5pTczDctu?jJ1dt?c5y5|Mn_{AvYu}S*u$}6tjw1vruX$Ch9 zaCq@{*60xi+;QfVV%{&)>!gfywwmIcafj*YDPm5ZWg%&Z1UXS=P<#B|QyWM%!|d2j z=H_l;$ZJP+nMI$dMEm z3mls`V8&}aMk-~ouy7p9im@Cv`1yf*S+{eHs?d1;0vBC&8KEPwWr~U}!JZv3aSMNc zYslY!t^f-b2)8pH6Z7BZv#6r|TH`ueDG{Cc-a}^ook<~t}a+LvVkZR;iUMP8;`P5B=ZAPEf`JOtUsx>LmP6$F` zge0?RngR4;P>*KhgLXExxfU&&k)cYgVT6CWds5m8Um43nSb`L=Xvm2c8VAA9zk%e;S# zloVWW;pP0npI*;jeWAqu{nI$Ep$o>e#`hI5Aff7{os98m5*cpz#OHbCHM{w+gAEjk|W-IOx#{#>(0GgeDw}uT5;&UyV!U4Ei{E@%XSATYc!PP!NXN{?Rqtt z%tjVUy+WO9Mv}}i4KI4hb^P-`eWXL>Y8UZL;v$Vmmy{$C9fiNxNqz62N!U>{ ztGQ`Ud=zEpGyMFHpRql^iHe2_nj@aaf9_x4HP5|(YcD?!DPuU!TC^@QhHtisEZ0?#UFnR9;-}=cz{AB+@gcyuwjp%A{4$-@gfHb4dZUPeYZmq^lllXan`?Dk7Gk z8E?^x6`ga~fs|t*2+Lxb7Pf7(w6MUsb$d8^)F3LQlE2b-W1X2U@GC|9`n60_9=Rea zqiV`q{_LH&18zqRWZ5s%6baHobd-IHN}+Wf$I*P@-@ij#o`tmWtOu|DU0#!a7^O76 zGJ)liR=6T@nn3yS)A7#!K5AO7L%)D^S6sm@_uNM>dDaStQQC3+nCb@2Hc$- zo|?dQL;8heerk@;X)!wOu%zeM>=ek4jq$GE{WBief0QrX^%Z_{a3AM7c@Fwz97l5r zRhFr<=(m``XP1yXtftUfkj)J6xE3<_*z;+_!HQ%2Z9C0MgxBEudicb@>U!tK~gw4*rbtE@mF0ptoJ*A;NvB$O;8kvdYM@^5daxc@lb);zCx(-&d=9=`CAk!YiEA=EU~ z7&QmRv>;H5r^e^2UP z=K7^io3ykGT}f@7bbjGkp)9N_q@9|qB(aS0SyYr8l!B&^{NRp5yzxU{1pQ+)AGe+AFV_tNJd=XPBpCld5}f@H!tqNqUAn-!6X=p!X*A`-<>R02gc+Ya|b zYG_)tPUE?9D*ft=@k{q8iF{6)mOu!j2G*u?HH8Hcg}ob5Q4ul{W3^98_c@%3v9yfe zN?Twk@==M0=6u?SP$v$F26pYF1i4$8FnLnK(!LaDMg7tmf;v(<)F^`p*?(|?x4-*? z-0%l8eEmOu#wC|rOuuO1c}G}3l0y5(_}Q&T_}1)kVvgXV?K`RHfTpN0ye`GE$nihl z`$^vWkN1)t&M@OG;waykEbDHnS_{vc!*z!vq`c1i|K(<`f7SDO|2tmKq5FP7zX<6A zPWY4Db;~3-mx?3_$&X~&yK6m4^%KjM`PqXdl5UYDeHE{I^Z(@j=_*afKS`Bzh3OJ> z0d{T5tc(zQrB>9y+7z&)F#W0d`~beM=yRN?I24{t{Sv2Sn5HTH@ht;$%41!Am}TE5 zfd$fJOB254)89J6```ao4%~GoyU$(EsJoF3yLM1097Xs7>F!}vN^ZG(f-=i&yX<-V z`ES2~AMBeXiA`E)D!SeUAog@FRC~~-1t^iFE@!!W{|Fzy>1MutTY4pCF}U{y?5i6JOZ_zkA41j_D?NR@#Z2mqcS-s!=myK!ZCLP zSoX_IE>19%WCUN<001BWNkl46)3a{3zOTuWk6a&Gj=?5z7*tz<%X0 z0e=RIN~MBK+oZBNh9l|0HXX_qHp9_`tW-kkl}ZOwk?b* znC=1FAS|L}5S&bZnz9vQSzz_&NQWBIX=6aCLv*NDsd)6;X{L@JH~lP@fs}QqS<-=V zxFsYY#K{_Ohdv=$(h4CY?7aD)s!zGU{?7wgiAAQao^$`^S*~I^OSu}#c{aTtFw0ZRu0T5l42ckwO}?+A?bCB zEcps+IAE^Y;^Da}ul@K3h-o-dE;H(eWRZ+8&Z4jJ5XgK6?N?cYB&B@@q(j{i%+Jkn z-L;pq>=PAu1iseHUG6ZwFw4Nm(-Ur~iDYS+{!SJ93k{NHBx(w;jf*~i5o5^!rEwVrg%kLrMY(i^ApBv))K4l<> zKoPDwHDC}|;CpLdz}>%=8oe9^@e3X6;kY~ZHb9^|V3_lNw^wqDN3K>WJ(yz(PI<;OQ4 z1~JYtzlT&l#jF123t*oQC65=s>ubPz(3`;;;YIJghrfJolXqObmvG_`N9V>_E)Bx` zZT#icFJ@x$AdZvA28w!jM>Kb&9jis5d2Hi7xs&o#e%`tWGk}j0<`q-;`B0 z43V;FtJOLq>q4?Zd5^II2^j$vQ~7UpU7wgf_5PoZSKgB!iK-g)v8u%NA*IAs*i+t}f%H*S~}#i-KOKOwC_`!ma3MsOxB5?<9NQ{q8qe zTrA^xUZ=6%ab$;W(d#${X^|pQ1T}UBQYnxUAxwW!qTZ#j0(Er6`xl5urPZ9x5s&n! z`>;sJ6th~fpfx$^a%fKT+Bd(C<#L&Cef87a|KMHRsSXpt!D)saN>swoC~pWmP29Fg*@E7pNl?mG zNPf*4;O9+G!HD&DhW&CxQy>$28Y z)RZEIVtpR|@jchzd7kMJ(mrc+jvBeBdewuJ8}R)qj^nWGE8;Rlh%7~=NQ)Lj&JbEF zEO&?=$7M0qVpv0UdV;JRVZpDHlnHtq&9pbgz$rZ{k2WV(2X_bac^>vPBSMnTXQ+w= z=BFme$*0j0E+sXKlnzozl=1*c5(k9^q&T8I(r${TACOmqL1iKQGAZQ~m$THJJW6@g z&?wJG$~*(OQO`-6nx;F6iRkzgnDZ-o9Z|+7?^wfo|NRim zTX6X}>&FrtpOftOHM^uk2A|`eX?|^Z)zd7$zr3EnUuKWW>8XjFG0`}?{YPLrElx%y z!qwGhT}P=Z8EFJXY6x^_L6|k~AtaOp%tYs9N5xTFKzJ_t*bfOrp15=X{bx{eN2PBpio%kBma6cU;El;_~w87HG6km$fzr6`XMzDl9o1c zdz4fr%jAKh-1ym#@%q2~4>B7!GPzhq>q$~dGAtd65uHnmQ%xR)fXT@@eBWbye4MGN zsZK+^)^r{_j_ED*eIFg6EH%LC@-<9ot%*n4=t3mW(U<8qZ0V?4oYd7{(RHLqt(w>| z4ZZc132ZA(O+ZbGNGl&kgaBNVoE~b?_lRlRG}8wPLPbNV$mLU$N{GmnT$^O2zT!W#YSFXgsnzI6no(f1zjN6f zbEP6Xc5LOyks}@Gav+^E5M~gdE#s}SX3ZLcK#ulFJeUjnQ6BT2}bayg9 zr+Iy4v(k?{m}m;o1?NWE=h8@TYAuM%R0rj2S9>}Y)3)BfR>Wnh^O~fDiZWbzfg4qM z6pkZNO43lm0P=bP#5jp+mE%H_#G{7GW)#&kHq)WrU7^dfq=m!WoLPgMDrj9m2*IM(Eb1Q8!lq9_Qu%~v zbl#;Y9O~L9EiCFH#hf?AuzYmqaI+zCxY;yrda>FWolG(Q=s#g6%@1wU3q#X&g|Rx=fsg^Yuh0|7Z4Msh#EP z9_#zB?$>za=X)JVp#i=r)dDWY0gmPMZs1fd|Zm?RbzAKT67>2yE2+#33An^X`O zHboe+JQT9tN*fQmQi)=*$il*LXlRz>#*IFGx;qqVQn?&K5OCte3C7087_x1SRRUsF zldSaj_mj)zI-k{x>1}BWD3wa&a;6}wwPt#Hnjr9@2@UFo20xUe5d`>^A}6Y$>D6^o z9G@;2g-BK?N=;#uDy5W2DTw(x>US1KvRn$7*EEHsDVoHTxwb7K0ISnSDFjfegVux` zrOzFqDHJ{4Ix4Pa0gvXiz#ZPkpMCnL967k3pWS{3Kb$%W7>2>3XOR|?4cj+y$qRSm zWCnP+yom4l3<*g>DbkV3S3L5dGG^o^*f&M+NJUHg#4t$n>|&X{PkkYKpZYQ$*!N=& zE)*CVkqFVEkq{KCiial(JpDP>^Qsq0EFoB0ER)sR6oVqhP+SUnwZ`c(TF+IXuHcx^ zWH1uRp67SwPdhF$>%Hjo0XC!Q+E5B99b!6C@ic6Tm0-mL={={B&^x(eN(AAEvuLmr zt226iGUC!AsT4}JnAI!hFztbpY|DH`ri|?XEBP3rz_vP*QP*lk0}iyRa%}QQWUwe` z$QCgnXlYGDDH6I)QzRmFsnaidwXR50N6o%kgI(9u5)i9v;@a3|wtu!KCxFuaDhJ(m z?@A33ou_6oC=!MN$BrE{3j!en=^P0=jSwv?+cHh+xg7PtxV#5J8^#P7*|?FRp+SNm zh#J}il}f-|smNs)UCiCV{nUdB*{Bz#St?;!Al43HM?EXHZF*DObehqjwTzCAa@)Rp z$Y$;6H38YIq*x5FZMfiq3wZe9hbfijx$wdZiQ9sW8@DkzIZ0E%fSqGWYl6TSSH`7S z6}$k%qa^0no;0OToh$kY1O(d2w~C~IMbvD0s&njPKa{Exm!^@py%Dx4Un{C?BJxQ& zwL;qFsCJ&$s-p~IDlNWQfVHBAj^Janu{6Y^U)R{9oPWzNBb>}i!@g4Fq>&X~R%LvB zALozn#P=OqejVwg@O|IB29Kt*iIQmYz`;r59z7`G&}|XGI|zrO>ZbzcJ>x(=??Ewo z93|!CBotLd6_9Ym?|M81JI0~Z-VCC?xP<};1;-X(%Pvq3l;CFvrrEM-gcF{ism!$% z2$uaSQaUt+B&{^lWsj^7=DDhm%s8YH>!P*NoK_Gh; ztdvG6pB5JRe4gV|(*|XeD*7x*yc3YL6Kp|3StOkdQu-)0MGco4ilmVAIVqq*ONF%1 zETf1=o39XpR4T(8Ui*g>mEypG`#5~~DA&L1JuK>g-~G+!(NG@SE;*m4@4b+mlwALg zcacz;* z7!^Wvqo8M|zx=u%%`S$65ttZTWmr?wws|@ zP?V+$3=ZbW+uI3(I!$Zg(POj74c)OMJ;EjlELkfQtfpm=h+O4~sANfCsjHA^Sr!(S z@pwZ-1xxe(Cr+H8(a=~{xj-eeb16JH3olcXAo~s8T2qVz5 z9EMm}CV3HI2ccTCW(~!n)lo!k+abh4u+zCttX1~wMm)%`B1EFI-}rtx^5iqULly!d z5~~Wy*e4egH9gwuT++_mu_Y|{q~tm#CKrjzkYUFGG|PUKy40M|9zqxg`RBdx1!N=t zyK1#cER~^Jt#(j|nZ>zi&6J&j`eTbV%$^_9f~GKrz31$>h_nD9G|RqEQwTOX4m&Wy zG)=ngHBK&qMhpjSjIFguU<*O1jfVUe6gZkEUqc|#jQXkCCm}@3IDWV3M_qitw(Qx; zYajbc)-5%f1e#j0tQFcJ5iJO&5@8%$bu^hRoLmktm4QBC6NCY4*RExLexBj%5J3p{-etw?8u`z60P$T5- z{r51O&5;?(lFeqBpTD0V5Nz491*J;dfB!yaW@hLUHWR@Sf*@qemaSM895`@*Sbx+o zi7~#kZ5ypML7=d0$x`^}-R+kLzYQ z>@7z7UV@!Fw&IuTj1DB2nS}HJ+%^Y)_~vgwVBw6P!@0_0MX z9w``d21u(a%f6!58K*kp+`{al7cwU)&ewd2Zs6v^I`8qo4AiZdc|`X%4C?DKERe; zyKrzgw&3x!D=s&5t0;-8=pGjQI(yF_;NZ=ZoVV#Rj!#d}<2Bg6W1OGQ-OXRW;Zklq z{2&C9`Kc)e9haOmd#bH`-nciz2k)9=%xRI8g0!f!xH!jnR`bw?1Xqn`(7Hgk&y5he zv&a2HWWIidk`;rfq*euKN|{9c*u*q$exQS}oG2_tuI8yua*WNowi9t{VX9Nwy-;EM-U-80F6Ks z5Mo&t>9oy>6Cr`Fk_y}2bEa@r?}`r^s!o4?fT^izBq?&zSyd1*0ePLc6cm*rzXFUA zCtrIu$8OV8(J=&H_N(+dE5^v}B6j=t<;dCn z?Ds&i5_1SMer7$Nv@kJd!`G%jjv&yc@E8+{ZbRet=hY%~O>0e4idB@!Fk(o=aL#(3 zJ=*h;;bVA85Mi>VRu`wSjcSN4^x(f1NwqVv_IoC!V|q)XM5TtN65XtU2>pn4aRs$D zQ2W_(SlbP6CXr~ZqM`VH)%?2@NFgxcMrx(n&{=HsX)jYat_YeI%+Jr$EVk&g(pXkVu~_6p5JU}CIgT7V$c7CYIPbjk zc-qsR#tk>zKra@TUw%2qyjk||KZI@D*tTG1<_KE%5QYImLqimc0RzIu9?B5}MK+FZ zAPhs+u3gK)g9oEt9!*YWJ7XgZ&De_T)uvk3BXEXKPF8*yNy@LnA%u)7M7jfU$0C^a zbX3Iu3R=@nN@5Wuv(4j|QlPb1m56ntvc~9X1&PsGMKG|b7O4pRX}i~^BB2ShICfF2 zqp^`>wS4i}Py=1pns{Rv4uLaf@RyS}dwA{8ZRTPfp{77kh~d|z{X z%A(I5N9zYUf9qBXg~g7P^!WI2bYBNLXjocg$fgq1Qx5axK_(UjyEkSjO_wPVJgRed zd;GMKH6fr-@JNe9m+G62=mTE#I-=_5YV$B5S2)eS?_&hV1ig-f@0UA?PMfw@`=C(q+;j&yw!p;K2h7 zk4wVEX&(Iec4B%RdU274XW^+Hgve5wp5uSL@+$t|`V`^hKBlLph)b7w-{-IY_*JAu zf*$Xn>4(s#r#=05I99JmXFhztjOz{{gmLih6B(Aga>w&5E)zJ>ypj=xHHl^H3m#$5 z(z--k3vyBt6An#a#+&2lQ4f7gL(YMcisC>&qKXO#+8d$;0YSrguXLGw4bz3<-5eHEM+Kc%*3^1*xW2H5TPC ziFBG&Xmy(9!*FGgg`uX;iV~bi`70+3f|E|0lV1u0dc(GASc@PqF;QE=t9=iHlY|X= zv8cyV(dUH3B3f1$h7tX_&ibtz7)bZ=JFk8 z;vr{T-;%T~3^eC#-p0)2G)vwxmMfU?3P{JHrgVgIr#emjwJ2d}3PG$DG5`vhnM;mC18a=D7 zOR`G>POG+lbXTyZHHj#A(^Y-SjaKdIOt|tl-4(`KbZrEJr7*x2E1%a0G<~+sVo;v1H@^VUM!IFoIqci_Gr}-r)7nv{=I1GuiVSCS#BG~wHXA{$J)F=1 zqOJ618Kg!C!QLGgGBtmUo4@fLzWn7cvvcQ8>Xzm!U;PU1=n%Fon4d2Z1R-0uZlzcZ zn4b^Wv12VkaD-*R7A*=#W(b0SQmKSxS@dFI+k&tZkg&~W9|(gyHHCNt`M<|+MEZYL zGI9EUdtwTjnzTrmv8Z)to-}pDQGVQr&E>$6yZ%m*)dW#Tf`@ug@7ddVmd zmQpYuRjgY|AtflKNlG^gO3nMX60OeT6{l$3r2u$_vq(rjcy9rIGR60^k{4gTgQBOX z85{?tZQ@Rdlqsy#7=>yNFaN#I!7;(XxiT+$`WQt@(VN*^o6j?`Zy!&2>XX=c#2}Y!e=^s6=vjQ?hJRu4*_R=N;ONn#QN>oH0>#M42z8~&Zn=Qx zKKELh78GWu`09V&#`NLCeB>h^!g4pWXU`xH9r`+h_>dihd5=KlNTQkAzmLy+^@}VM z(kE5oJaQ zqXeV1!p-M#G7jFNPczcpZ*!boH%~(;(n7EhZLDRjkU}u$d*q};HBy%eJ<~hr8@nQL z001BWNklOf+8q~j(F?yqurS4w z{^`Z6K~nU4i02*p^MZyFEaB6NCFB%{h?=XZMO&kvJCbB-7`bQ!NqTuP>WkA8O; zrRq4sVab~VH-m`GP}@a?9`6n;T$Z(FNo#}{#C7u&y(!W{qxOHFxJ&>x1I{KYIze6J z4aF19!oErJd6VR84WTQEX`gDLN(P@wBzDk2SoO*tSL46WaVphqZbTa0rVmPhu=1XjG?I4irgigcc4J-9v(-r^I#1t|F*$r8oZ@ z%9qu-9>TVW2}q~Gw$s?ro*cs@FE(Hai?|RSBga@6p0eWSbGfLX8g`PDHU+HD5(Jfi zCCel%8K7D$5=+~xUAq>oHT58*Mu=^vSFw2dB4nj4HEfG+!)%LKx`(x6YnUq*BeW%; z&$6S$O5>M(T4=uYz3+7-@?CczDi~WxnW7f$NAd1C5`Bl>tbFt+IM6(_P+)Z99)3D? zoGUi%i2cr8kVYF)C3O84OA2co1ZYPrx|TdI64L4r8taSgD1kA^UX z@nl3RZYV`VLpmw|b;iwUm`Sw7AiKP=6474%c#zDK3kNZ)GgeoBk#1-7cEzY2M6C3z z=*Mt@^l2#|wW#WA0+m+84~-i8w4y(sCmp%9n#G@0=W{j{-<9h6ib0^MW|-<#MH@Hf zst7v?jj5c;Q?ld^YSM<^x~N|#f45j&cZ>ngWDqDU(V^uCVVv$oheozit!STfsEq`% zWm%-MIr@Zcb0`7Hv&EP@Vg!wL(~+!|=>7%1PI=8$tP1LQ~GpIPkxI zD5dCiWLL%71aRrDG5mNDm2PCR&vl{%Lw1swZYo=?Ge^w5?u+^zmLs}^l(IvCY&QnR zB5GN$BRijGHa@i~4~m`C>ytc-^S98D9f9?iuq@rkFw5`si1p`F6xD-NH2mj}Yh3%> zzXdh}7R7;pV0wz2lxFWbc$iRY1_oS|(!^7F%FJ@(cR$Kc@Bcc|F7lk`?B+GExrPfa z9%g3dHa_~P_wcb#zl+;{_GP~NolkQA{a+_;A7}sJ@9@+6zs$nI?Ob==(;3PHyzR{| zVR7~jc5F`Z*-yNi_4yWCc5b8J9y8Z-eikhF%q>Sq4-D{~?|g$W40zJcU7QF?G?e1w zpZGAdvk&vY19uv8IW$kdyp$5hk;F6%ISvz(lQ@pU`g}ebQ;H$S(9)!o zfy40LJYG4=Vz46-w3xg24^bHInr74yz`$=Q%a|}6dC-{A&b*Q2} zl95-3DZZLGSf~T!Z1Wv0)n7IOoyHGUj`aMVD@E9|4OJsV%i`fVHgr> z-4Vet<2f{HrMaA;cXj$kv@v#!7$d!yzTIV5B~xtMHVNA@iBhC)+Aeao4JbS6V9`+z z+BONsc+j#0jp!|PXwXn0Bu>U<#w)OC(?(p^<@nTegx<@jSEahDA5I8CwOWn5QPfG) zV?nDc?x=yWq_8C@&ElfRo}K4$>#g^oRGnT7RkhZ+PAk3N>BzY~CsTNy5r1mSuZxrX zT^{d|M3YdulXxUMY$H04&m40R_2_9@QNey*Yea&m=lF?(XA^b38WO5SCs_j;S`kx< zUMFLc1)!#N=X6h&4Snnv2`VC_*U2D+G!re=Lf3mD>0!a7=XXtNg@`H|$!L>1Svu}y zR3)Z+I?eM+)uTWy6Aci>Ipf193ekpum*tZVLu*|SLGYo~HWhpRa=>P><+9^A2>7LRgZQ>?&5_yrAYfD$w zJ+kkS)Zxt|tu|cK>3SE4O#?lrx{lx8D91qKQt9KmO^A4e#Tv zm%N>+T#muPK?=%a?7&`r^@m;j<9FWAeL4!g+qwUbhZ&lj<)!Dmq|xBc%*@cab}d@_ zocR3blkRlr-7vsyx8Kf*gWHJ-1&)AqX{s_{z*)mBxdU`b`w1r5O{<(1E2Oi1?B25n zch*HlO|#*7#&3V;&b#UF-#|q`N7ghq5zpgbZq%SF;k8o)deSMTJ&$GSu&&EA46d8! z(9jS{DNZ`+Bo?%3Iv(D=o6}A^jYS-G?rY`kpZEgwY=_QeP~FT`DhMx+lxYGXv813& zI?RT9MSYkjg`lQa5O%GNg}%n zc^ei!CZu|SfVRM*7!(Q6Shmp$6E-!LWf6BGjq6@(&A`A0#@#%*+$@8Gn{i!t#SJ$c z(6<6~njqC#-=iivXbtyP>!_hwiw34ANS-l>9g$3q&XLV_(T+en5|q2jX-qVRv`ee# zh;{4pC8b%^nkB7Q4Ke>5&46SPg$S>Ux<02SVA4|!lZfWJuH~r4zAjg2?{uKE30S65 zS+R9*{WHx#B4w?QNI*9}-kO z{PySk>Q^^2dH4{`flnflVBNZI?Cgo0eDcW*3~XRYDW*NI;j$vag?90A7oh+t~_arWh65dq3x%`yx(0={P`!oLn>g^}G;4 z4J|^oR_xwA#A&CcSrnS~Rq%3C_5U(cM+9L)8myI3BFZDG6|>q*>leHPOHPq4nI)M_ zaOrp6&L^+=8S9TfmyH83nIECr7o}(|n9WN>7#$s=C+)Cr?*X=KIhLVayV!T|VU+S% zmmR=$T{dst5ZZkAqWyplJA)-Gnsh)pFx>1DwjGby+{f_nZk~1C8I(#M-?;T=P#*WH z2{MEI1g=Yqf;b}7sY=irnbv7yr5Vz_>uJU2?pyCd2*J$EFc5I-t#_jQBI~<5IreGC z;(3b2bQS^ub{ZX(OddMa*oe}dohZMEv?aTC-G?Ov;?7&K(%t0t?xW|G>v+}0$8+tq zAcSJpt&&dn!xOmDw5Q|De2|n<#Pct&2 z=uV|L^UP=Sl9!yrM?d;WzWBv2a^{(*AsvUZKFn+1{7HWPi+%jd<-Y>!S@5i9z}}z3 zev6u@Q-F<=m~aC2?c2>~ulgpR`^cxmV#d&tSDRIsYhTmuq{-(?QpZH*AI*Vew|%|Kb$9 z(h+W@_2CP^QmAo#L=+aW!$Q-hU1&-Z9!-gm8ubWpQ?CqJEy4#F*2J;}7J`^<6A52;OQW{2R%l+V zXag5ly}x#`64Yo}R_N@>5tOesjH{=%1hZwI<{&_JB7D8kc>u&N@$B$h*UsnMHxfm zUH#{bj6x&Rl4CY(fWvdNiHT5`rH`Oy|H+L?L@BzvJ41>Hw1@~*3(ke(+Tu z+Ov;*KHm_}3$em2Kl+2J30R1%hQK5#p@=9WQ1xY+ajL9O$LUE$`SBJ1!FxY;Dd#^o z&2yj9%erUv0IewHBg9^`_W=3pzs8OGE4=3u-=fdyXWXqK(-B-RM@&e>Dj#e!p)(Ck zS!+__0LnW7PbX*}DAL~*XU|XX=btZsB{7lX%+pThq)iFd$R?CJh!6)^5`8@Mvm3bf z;|DqaA3n*M=e?49_Z$S_(5y}Iq_jtyOwoo0;ef5fkex)>_!X&%PDBNoqnZ{16ct27 zqN|{NjgydMXA~tQb2dyegRnI{(3>~%%VOJm9Hm+ZmWo~-yYciP(qti3kcBmDx zZ33;agrFrvW>R*NXflC2HcmW~pfp`1nOp;yzi%K}W0$PM;LS|NxRA9A8{aR|+t-I} z+xSHvZEF_s8w<}OnmMJBGZmBm>ubmerqYtkaD_D*nnl1IkPum5FReH%Vl#tJSt`IM zEdP!=DgH;T_Z(g+^{pILnjJr{k z1+RqT^zn!LcJlRaev=1x-A8UT|AdR#<02AHx*>9wQnGXBPJVdpce&}J3(4hjjp^Fz zrcF?v#8-LCvm%Nr@QE_m#?uH^Bfu=5^ z!%s@A()t{kQB(ifR5S%*9B}!qj4+dW3e`z7-Os0&$*5gOZ-7nx9n9YKdPp7S3u%Xg zzrT}ry!T~1bk`6q_&hZb+%)a6R`k&#JDAmGQ(sau6pQ1eY=M(7KK!l5$B{NVSfpU~ z!vLBPlmj1O397zg)6<^Hf@gg4)#NM{*CpjECMTvT@7>EY&VC;EyDowBiL10hG+ZFi zc&Q=>e{c&Mx_fA)$lG3b4s(-vX0;}r%Cb;W%uVF^!+pERZjaFJ=8+2d zLpyozCqK_gC!K_@Y63KNM53z-5s|bxlK=R`r@3MLLEcemV(iObfKPvyQ{MXvetGwA z*e=gxlH4Nz1VQ`0uEo{Ylu|B^<1nl0Yc~iBKJ>23n9J|u@85VS2sriBQ@Q>2yP0vl zhAU&;o$9j7-eimqBFmg|>WK^v_OW~SKJM5F3nId(=kgS}72Adrwr!(4JIZ_Cc{vF1 zCrjk|k7qD3Nhk27cdutqr0F`f8Rr}YxE!OQKsSrHbmCFf1B?y-f}dRTZT{uspEjVL zR!2}XbSS*9g_hcN7O}usiYBGRxHHwKqvpCrgPk>EUQ;K{ATTtpmQ}_RqAse{oniKq zu^w-8Owm~bDhM6G(qUo< zB2meqe2KQsEG@npq7p|M)6}TjyK7^MevHi+KAS@d*PNxv_?n2F1i#Fp4oqWW$7l(W z!v&0XWj<^m0Gb2M{1NxN(Ut^3z>@D%vqU441>YwK0%9>6A(ChvFg-P8&UMU20Bu1) zvo@iRZH>L8ZZNb${||zoF+6U=*aX)gq@qJK8p>1M3x;mD0VJn7M^ zHT&_*{jUX8sYptP?o^85`-k}cb=Och{72TvMU}OFGD;>AFwib}=`oJ9RV%Uc@i8!K_p_Ra^+AH(+bF_3|%2$ zu@ih{3h0dPW`4p0ENZHW!R~GR*fKYz;e|GZ0f`oYHe5^J*L2uM+?q}%m$ztzeBdy@zUd}5q+dbyv{WP4MJdI$6OSX88|IxeXhm$Q+ zjP2h20R8=I>Bx4ITz3qVS^cX+_7^fuO2v`HYr$89?7mQ4&8DK2M!#-E0tDdx(M#P z^HyGX&e<#|V-8@aqCB|sPNruLp_E7OKo{*QEZ%(&Y=>ynOj`-9wa|eKwj1cnBO1ie-WXwF>6Jg)9Oy8KUPGAkR<}X6EKN;VA!2f5 zF4k&lxMf)c;Tx%~7?~j~!9t)}vW%B&)v{;}Obo}9(Resclw58YDc7Qu;+%6{#7FZd znV{WO=TL|v>t>X$vM3{HrD$;+j!kXg(9j-Ue(p(3Pml24%U(vC z(?(TAX(dC86!_XlaW@yg{KITJ@k0LbQ&*zYEE6ivn*I$;dmia@iWVsu&rgzBsEgI+k0@FG}&y5nl{ML#=btj{*xc^hTklK$j)bH**^hV_kO- zd+z%+AH4K@?)l|c_~<{pg5w7IcxZT(W^E=N^$CtxWnm0Z)}~zwCM~J6H_e7Wjr}gM9vfMj4*e2m>^%|ov%ELQ`bta{mO?qZXiWX1V|aD zSws0zebSF^)Xe*DMUaf9O_x|wEEGLvX7Wr%mYEHT#Dpf|H?g5}ElC+c>j~VMedvG? zJu!EluuPNUhpu0lOega}fMtm=)W}#EkB=FLt(2W4nn+?li$pr1f*waO9NgJ4k1ZWo`6xV4i z%OYZ%$5}#zFs^TGXOl^Sz`(+_kfUAJ+Dw8D9)l{=YO_57w;-8-@`OuIMt zQ!MTL$%9re9^l%5?Vw075BORG2_kAOi)a=+7a>gYZ+EH-4h+MsdpYZzR~b=tJWjJM zV0wa$=@iqYSvs-~+qMrPgpKljjyvvT@)L&o)8?49Hr?9^SVS5@XS#6>+IE6N2M^Ne zI85b?sQg#I`Zb%kAB$4;^%RDO_pKDhjsPjaFVYrwShsyUOTMuPzUlfO^QljLlDqD{ zjqhCdpBxw+=BjUfnQV6_nM@}Ir5JN(O$cQO+Z%y+z`W~n@2_rU^uPh;U6*`*0vT#g zniCEk-D_!$_w$+S9$^0jERx36O;3utS?BvZPMkyeNpx7~-+S*pbQCTm1^@sc07*na zRCQ(9KXgCiqeJZ5x0`Q&``aWOiC3!Nc_qr)SgY^abssnW;zq_tM=6y`jE;`*^{;;| z6sH=&`0Q*cM2`huyZUO{9Ldno5I6qtyZrp7pAbz5q%_xUL_kGVAR!^pES7XbWNUI> z1i9QWBcqe6TpL$DyE--aZ^7!fe(gyqS<~N#)|z?OtjUc*!e8*=IB{b!?bHV&n)Y;@ zv5{eV(kWtL=;&fdvyH7V6A$5 z{WY7%SpS3llZLhV#=Z?~a?&uKqdO5_l`XOwNi}*|GY>W|WPY|pn-izaF^#Pd(ASmX znkzoQMJI0KT^F9kKVNnhLH;&ukw=J0+MGqAsz6*%Vtc#z*rn&N&YogxUn@yzsA6No zCdjrN8hI=dPzu-YR*Y#*M>gAdeNnCGb>NJrNQQoO4OhJ2<(#qhSZpuO;rsHmsBX4p z&p^1%wC0z%@c1lmyWkYwaQ1e-{+W+(#u+E#I8hGe^9`H$=BkCSG~Bxz!h9+zokqUY z6V)bQ+#ZcZ{A?KVdz2m~A_d8$naIz(B_n7|ryKMx&vWU>rf89Z;o*@+3ae73CpF59 zH9{PX^T~;u`&b`OaP4Q`z_PmsUlp)~jj-0zn%+j#IR} z7ST+5ij0#wYS9*rul3i_=0pHZtrGgJSIwrD&Gs`eu#IBLCY#N&P&`a4GmOvdB1lY7 z>nvkumkD%$71{zWVuF^6g(>EI-w4org>4HC9(*{YblK=2VBPxlq--1C_gV6N+_7=W z+Gk$-Oce`^kB>7pHjUPrWHN&gHtW}K4g-{up_U~b&4e?BOOH-bggSB=J` zHROrT2W8WQgw2x?`>z}eAtYNV_*j-ffR>a`5I`%EDbJ%=^b9=Qn*a?-X{cMv>3$}3 zCoOU#OA0zv2`LqMIYG8Bjek}A?6ZT9Zn%TlGv zX{VirpAQQ{E#Pnt5)R&M3CEH6eu4h}Zb0*fSHFf#Ji(SN8%abZ+qP||C!OZkzy38Z zIRAXo=`}E(hiMZ6*xA{GlaM^?CmhVg42`kB;z=wJ3EQT1-Ja-m$XR9?gO)M z+rGvmT_2SpaWw5~_4TvhmFP)lDV0h*xN{G$eCaFLxpOC*HgBM3Lm$DJbE_tk?HF~2*GoodltU(O$ekig8k{~X>424kxjGUc^r4# zR=lFeC;s`fl%|Uz-B2=_pG8;0W;tOfJxS@Hl;%+0rOlD7>F*B%*z^$wD2tD=mi)CI zORC<~dbqA@vL~cza_ixpf8i@Aj^nW4Rq(u7Iojo$Lb&>?QXc7ax?$AgYt8;Uc0xfRB6Ww_)#$)c(+SHgBkifUv7T2Z z(`x(XK0a{S>)3VAr?~d(Z>3EaS$3?>S)xvo4bBF1{vZR+VXpbo zs~G4`vqr3c*tjOmM=p5 zJ{GavA+SN{ZW(3I&LQ(g zHB>4U)4)7J`2Xm%^g7bxx^AdNH(}4Qh-h3}kw|#KDP{QK0&v|KgfP~jLYNd_jW*ul z;fI%$@rJ1V@s6aFOnZuHPjTFFn|bM3C-Bc7d<9W8#)5yCmd*%ELUQ3H|G*8m?4ftt z)7i0kD{WG;tQ5<9}W9E*vM$f>#MG=fn|V zj?KCWAvL$&crUfWE>3$+8~SjSw$6az1GjR{i$2A8$s?~VHlBPgsq`T2(Fm2r9Y$?bPluBUt&&1n2`NE`y)Ss z2YP^h@b81C`h5P}lQ{3WCvtetJ!G7^lUNf;8D%z1f&ObgVnQ(Oc_ClkET-wSv1#?f zpa1D-ji$|sv!oO~Aq4HZ9*z^P5urf0l}Ebk^oLW}CAGpyuTN8?6gW7pi zUw{7~hxUy;X)gL>9mmK4`t)H&r(JB7WicK{N3$p`31*jRk^N|InCaXkQl^p8p-*c@ zHMEi-szD;z+?j=k?`PxbI|y8lyMBKMZ~DLox$CaGSd)-U3qk+dwVZzTX^f2+gd}cR zw1=C&ZP}2qsflGOMMcyWWIH2=p}@uhEJd^AT-Uq9!abuPAT({6Qh?s+fZLmzlQ zEq-Xzynh(%EigXA)PaEGP9EfY#Ue^6E;#3Gl70Q`-m{zY&Nz!ZZoiF)Dl(bd%Z?p8 z&>HsbdpMlp8WiQWdv3>ZB)`4+W?ppe1@!mzGdwcPn*JFX$?_mG_`&pmt!W*46 z?rFAUNma>8LA$3YJ&9>${cznpTeq$!-J4;5ZkUB)k*|F1YEC}+>D+qjt@I9T0W6j( zRb1EQn5|Fcjyvz=!V51%DaF^m_BC?3!=W{BHyqgCu%NF`_p{k-TwoK z%KzIaa4pm;WV8J!<+0!yCr+)6lht4Tpr>B%NT%}&clQvz1AQS1=n&N~u1f@NiE%d{ zT4=|a%1zRqjz6L6S4|jQa0|eF3JvG4)s53)NEvIf z?Nx&T-DpzG_rX#7O}$A8sGA4W#3MsL1uG^|CioDPu7o;D3BC_@nx;~P#l|>uH48u- z-Rp+?T9ulBXKdcgM?dg(M*jFK-gfDW$>(>|N{mHelSr>)>yA^HQbo$zIMFW7dQ2bK z&w}z4|B&i-^$rr(){E=E=2T1gE`UUNVI3@-c?k%$12vRqO`Z#{P(r*p?KhK zQgRuQP4IAjgiXhvMtf=`<~XFKL%F(Q z^c5+E3;2>!$gHFa%)1k44G~J@ynJYv7!QMtlnJSFqKGH4N;YfL*-0nD_{bjS$M>>E zZbYz*)!D_cYT}YhuHgLFyql}PeFILI%8Z64DXED8E_&x@_}$n3l|y@fLn6_{k~hYu zKllbNI{QR!J}}7xcRvUsLdJ0zcU_uwlMxTA5;rmyF#5>`@q+E z<3~Qs``>pr&w1&KIQxPNSqzaMr8Tl^kh5R;0e=0H|H8}Nz@fblV9R0N`112P<#lgk zvUWN5-u@u1(s*Pay>PGQDHoI?B@$uhu2_s15AU7BvwZYlzK?Bna?R(@r=xo#wa6B3 zxNVjzue}lc1Wc{vX?+&HZ*D3(^ds-kO=be@YjjYiKa(LhJw-B^#1=M_#c6taddMF< zNHm!+P_FNX5U9CHgPQJs*fg0;hVk)fY};Zk)Se{643wG$ZGI?B z3qv6%i$#|F0)cJNIomc3)U02i4U2gKv*_r6MKlqNpL)#}GzaE65{X2(1_oHdrY(`6 zG~+?i24P_LWID@N-3P(%X0IDs9y)RE*tx{(-hT}wH=6fXxYbZt#vR`Ixt}m}xWwOI z^b895eRN4dD^--L&>Ak_k6zGWy1qMhM8TE*aG$-__yMI?X7s8%ec}+wZo|D2J(zlCpb-a(X5v#7Cq?6 z5|a)$|K|4`d+dqK&Q{pCae%`j!MuI|AslYG<=0$v(MA0J7k2{|@k|fJLXkPYh;2(O z0R>-^6isY7?l>-e$H(a%I3Cx{GdNhGf74cGW~O=h`7ZBM6o!{cfNf!&AN#>zp$!cuxJkQ{P3n<(n^ON*;#SPU)O1jfg zhCPoZ*CU>m2rckj564NbLQOPvqlUk=BjY$+cin%H?M}08>sHF1IXBZ!Lc{w1^`nmL zHfwnPnWymG@BR$vqZOl@no||FZQaV+4Ff!F^H#p~{cnYXl)i>#`{UO~npR;@xw3{% zByG~6MNh)m1N0s9Ok%2nR+=ReROK=c4o`AIe?OJnC~Z}Tn$|=_f;BQ>==v3tE3^o- zX=9%7gzKY8>}{Y9SoO7ig(TIyDnqYTYZio{ZPgxfbd&Okrpyu$n4Fb5QqtD=e-@Fj zAz8gARm*;;RatGCVwra&!aS8#h~~oM8r&Rhef(iHqHTwM7Yi#IcO0= zu%uV^J0UP@h*IdP!g2ap!!nbT!~EzQU*@_`yn}~^@5XT?E&&%_d@;Yedmnd=xU{D> zqLj_UrNb=F%yRn4r!X@dVbPsIxdBp+@x!ZL&ATpt8P{BMGebjjEQl&ij`?f|BRonW z1@ZW;>v`=9PvBoa{32?_LkO|Vl+rXi&*7YlU&4W0o+%~h@9!s<8)iYTM`i`K_#K`% zjg$oz-G_Pg^H1PIpZX%Nx#TkAIw&MTy-6FNf{m%hIaW$NB8%|oBb&|Qc^=nZ`(3WQ z^2=O*{f|N_q(%zSaKMaoI%zuWWGGN9H5@FOwWg+*=}D((b0nUpaJ>>zMo6a(4E|(< zgQK3|=4JX)eCTy==1mu0!0g0smJ*VgnJNC)M{c0McPqI{6^(IB(AuLlym5T#5Z7?} zE8oSC;q@QpZP+T-F+;&L%jKdWBBS9 zKhF!!znHP%(FVNw*oabs8iHCyQNrWyK{An`ISBCmf=Od86dS4VZCDfv1(L}m13f*=hG>WH7ikTfg-j+vu~?)l zxrXtvF`~&N$)pVg*tVch@WbyRk+9Lai696NwxG+-Fg-oZ{K0Xmei=&`zw-bcz9tRR z(+$TL-}f7i8>ShGt%6i70$rx&o5az2T75LpiK~K03AYN#;rt{$1AV|BAGHB`vIYsB=h7r+fDvE- zlmnel2OJo00^eiWb6HYeLzMkYM{{dJ)0+}33&F#ad6q(yaY%W5>78%pAK&ykbid0} zcWkCN(#hHr&)_%r4b!(V%ey}I6~6nuA93ZEzQK+i$KkrON1)Sn8bj~E2Fmuk`1n_U zKvyEc#J6vzGn3%mSNszbp2vWOZ(aX$&OYzLm108(NJ`fA_jBj{cjL}Xu<4j}RQ+j= zS=Yn(Oc5z<+5x3}IxLHw_uo%Pwx1SlL&1YgC*@g}C1C`!~>Bf#p;>q|2H@dA{V*q7}_i!D3afVse-@mY|Jg z7KHVvG{$-s%fb=AV?D-mtz?~8mY_L&oDddO{8bb&eFU|u4TvU_jb>)ysK2w?@_8|| zR;~|I>#UAI8*Aj~DoskgpE^2st@)@uY7vb@5D9bm76~Xc0v|(HuMkz$VY0grf{NBG z6J5FYg}{nBpsF-$#j9U>I-kAb^~~q*C*$<82%LWQd3^EOU-9aJ_=k7$ z4{!TB-toqlbLDlvfzFgM)*- z`qi&$&??JH(bcs=os1}@nDYzaG&5p?9+hHVd1RbHYIx-HW-?+z+`JGDtvsn|NydpY zsT47h;=rE!x!~!iBRVB5(&m`{XYtlcpUpr0^V_N03AYGAOgM&btzl7^|5~M_XUnsA z=+1)(0lC~BUh|UE_|A3z#YGogNDGk5jk2k~53MEBUWs)BSw8up_woGa@4#}KsVa-s z^g;Fx_b@WHmD4YH24(HxI1;o34NF?Hgr?0AfX7*{dMp2Z*VOc|vC!!IILn0P%Q~vMy5eJm!20tTfom9QG=7_6_pxcYXyDYr!t^z7M^M z6U18H^;#ccK_Z#Nwrys8p97<##9}e#=H`f(V|4bdp-?DLE|>A9rWmm-VzC%%u8i!6 zF*jGHqa()1$Ud3_bED7t9&3R_LIO5gPm@R_DHMFxukQ)9D+z+YXUR7KN~5ErM=VCM zSd3CoZtz9h<}4zG!m5SGOgMr7Iy(HuLXs3#7#3=gvXc}GV=NSX)~(w}Fyj$~(-TYB zkm)wzWg0B1;5gvVg6tyE72yS6{39e4h?|+d{tA}w--DwoYbfB|ZC!;rity)UWkRJ|q(Fw#bHR*Q=hEI6r`8;3x(xvoo+QjqEd>+5N_4l+3nc2Nhk$Ot@v;f|r+`ox4J zDJ06xQ>Dm>Tl@LqCtgcBz0AX^Y^vx3%$ zMI>S_%9=j1k$B7_ppoBZS%RjJwq3IVtPrtyEHvoo;n3q5XtaiC2(cBamyX%S?F-}3 zRTCCA&|d%dDry(L-w^j(M^Vx0jZn>6mGg%&C|P|p1%^?w5`-L5#=@_yh$DgwJT#!nNPq z#k6M{>tvW;CWN4*6sf*G-u#;Lc-Px5rQ+?zacmZeG3{x(xAil4+;M1a!ra>&hZ@i# z1cN7?L|Hdc1iZt)B^6#QF#%c^(AuLTn`Wt^DbIKiG|{XCPCUxctVjGwbm{4Inu7A! zwrwlhwrveVQx!r=N~H=StOXx$Dj^(1As>j?ufN#J9eC4ez@A4LmqH87>kgy;W;XEfwXqTkq!eZx~>~%i!vL zG;ti?`|cPQU9yc<91zA|TC6IfKv2_0Y`t~!sr*7|@;J0OHd*f=Og}_28mFX25F!oQ z0}UA`%Yx_8tZkN5f|}4Iw4~;kbE*||3k%;_X0oIqP+-F`PL!YARRtU(BlmF2e_p}3 z+)qwVP%h80X3d&Vi(=AR<5rBMokY!*saX~WA0DB@NfNhWl!AbmWqiwP7R=4f5sP&& zH&-SW>mUfqhO62fL0Ez%Uo-0$>9CV%--z*-eBBVcF92Q1B=f#$dV(OJTn;&=;W>NC zhCvRDjZiL^Y4$Wd>w3{zGdVd)+=_u^rWn<7K&`_vLbm|AGD#LF(_#zS5(!3UjMLnb z2tw;)3DXmh*+Nw+T2Y2-mvKnBc^1V9aK`~CY~hN_&tPO^gf`v8g51KanxTCELH1v~ zo=rcIAi5bF8Ko!P#e?2Xl5&}h_Z(d3@DYVZt6o`zTlA6%xCo9eKvamNJ!+EH5re8H zGf}GtUDgrJI^E#Ukv_YU@38XkI?AE{EChFhWY&)s8Eu$n7*taljh*KblTKqw+2%O7 zUY?F@mO|*NQ}(av1=FlVluc9!7PU(g5-HP0b#7~PwTYsTbPA8El$2b^ zC`Cbvqoz6fh}?*MXlw=BaS@(}RqtEF$8YsUID0+&UjP6g07*naRD_^eY6KFkx6nK} z%l52^ABYRZ)T~29FPg;q!)w`c`YkJ)R&v?g=hH6O(pcV3&p^2dYdW9!^cHS0msnpn z*a<^v6cTLH1Tx+PJyD?BT$92y8E0rg+iVU?2x^wavRDo;qkyW?L>!xn5KLPZod^`l zSS$+xzQrNm!yvMx$wwQL3n;s22K& z#-$g{$A&U|^V8n~Ylh$b@EJ^&=h(D1&Py+NEjxCcY#Ow#4P5sA_p^TeQ^UeY(&nUC z_B}TBXL;dSXVKrEWh$5Bj5E&QCqMWB5x+nj%|gjz-QWg-AYjUy;hR@|iUs9SsZ>a& zQoQN1e@A5Ico4}4J~Ynn>@u%-SCYHW8N}BS9&(4U(vo@C}u&>GN5~6M# zV}zjfP(~?XCxV1q<=Awbd$dbesNZ=&N(NPe5{Ib?O-%HoRAsmG>JK7I~L-LY?IXe4YnjYC!4>2L8*p=Cbl_s8SBUh%l^X+@VnW2mxH zzyeCKgdiERHtK6?ETp{FWQZ;Zfnb@%Fp$rzGfj^Y^thUa1SN`QprWD73^)-WP2eiJ zQMBeXU2JE;nIJDbur`4m&@9(d_FNJq5JFHECbfJqd^fskCOQcf8W{y1%a*|R6~dP2 zK+%Q(e6x{jOcl}9B4xm?eG6Rh z>i2-qv}%RK4C)tUnq-JbR)pfXvrpr9w~TYged7!`F?yT?HKxh!*~fB9QOX0liB@Lt z{||R>9^c4a-~T^#d`8x1v>wSGAKG1e&+KlJ&9Mn2BwXQ2xhVw-g#vB4dVJwqp!}e; zK%r?l+I|bA?XMI9g%%1l+zlk00TK!!+0C&@b~o!i?6qZEV@o4zM$&wAeE;}-B+I*- z?1rRYpp%CZ+p#QZWDA8cXI>BIB&BX&IYGS=Y}Ne9#nAXskN zjHwDW!+$+liTBif07~ZEHP8j~fLOa`A2AUA14F=U8fg80cSD<2xDJ>{$}x(?1ymHU zb=y{!mgdcZ2ZSOax`~fA1yev%3aZM&bvF{J7$eSvfjD*5V`9Wr3@OvSLMoTDQ7Xds z%eb!g2RVB52p3=eRF;-1=Dq8a6RuGyP#V^vAnS|~QxO@_G1YjBQmxh#7wA^b%1Fd@ zB~+EtZlYnRAFY~NRk`VP33TQA?H}F@wjwqL1A|Exracl%IWn0Hky0!N0kv|ODAJ3y zZ9yiZ32(`?K3Uajl^`e)E-%xp>V>QWMwMnQpjoZ<#-7QvO*(5+H?XhuTQ&eNY}+ga zCDsX>bWTeHj*gBnIy$OHsm3hHvh?d!s}b|%ML-841uQJ+>CXD0ajkuBx)?oub1d4H zKt&Ojuvlkhv<#uSp%cm?q12j0y618#wC;PeyXzKz2$s(_p%|9|F=vrO;g4xbpPY;s zlNFs=logTJr0zG#h&(AIf%JYMx^|vdp{kS-uMj<`ij=?nsySg8;`=_Xo2O*pTw3bW z>p^vdkgRyVA)>lu%sJ2#8S9id(_UjDrC`=WBt_3~&G&s`jwC71Mkqk^C2gv=UQ3~m z@7H=sM)x(lIPLDEEb=7eIHSXZkVO|OqhYh}_V(;y@QxBV*vvY#s;X(Y+!#i;VrOJk<w5Ji)YTR=3&17>qN@0jI=rA=kV+2A%mMWSAYMYJp$lPIC2Fh{t=no-M zeD=mA;H|Ln+G9M~xLb9Z^#o8`+(5UXY z6bdzj5bSoOX#_e5(IE^Az+sy5u$FCCm!9@sRqCOjHpQBvL_b#dq5tW}s(^>+dz?Mo zH*N~*2CL_-(H94lT9v2n|9RYW>>ut?L9nE>VfHR5K$M|$m|^cY=Q$m6#!o5*j5^vx zG|}|YgG!(JaKs6Y6WC>1!e<~0e%Ye|)C~-~d(@TECd<8)MmH?0)he}GKrN`@`#uYP zkpst_(lAZPbu&zlon{T+IZDvZB)5D&r-F-;hAID2|?6~@S`ea zrF!onGN#u`!Lh;t?7Sq9fPZ7llLR#TLgeWrLz{sswzcB9-}R`;`>2w!yg_Vrm8|x zrZN@Xi)NCxvR`9la1g)Tq#%lnIve%mCD0v%j1VX~8rLq;y2=fkWGq2U#jr((n%|@t zl*#3C#FfqP@E~F68_8B5Aq8y|OG_0p!^0$mCZrvkTjYxM!_@pTgVN@L9XnX`J(3F3 zmC&8aR;a7eu7~-_7qFeAhuItGYvYePE{kO!gko~X2nneJ#wIbzI?JYx?oipbP13ge zNNc)q7_>6vayebVR6%Aky>9*Lc876MNtg~9Q_`mmcoj3Cng@jfDM+d{a~VUgfbHg zGXcgD0wn}OG|i5zJ6-W!ZmO_Ew@4g;lH$sV&9tX)!pCB4@(Qm?$uR!E;#U+<>_vhY6I;*>#r63?BY&t@rLap-G z5imMB$>w~Xx?j`gW`XWZ#+5c)E%M;d*yDwQzL1vSqMakW{q?`a6L;?9x_|ouU%BaC zo`2=V+<*8G2aXv!kPEuipQDq}0yg2k*L%I-nwW;~U?E zuymZZZJXKIMXq_rI|#!v#bOy-+T6Z(ACJ9cGp~EmujAT^X`T(7Lzs?$BChM|DUnj7 zge34P#2m$vQj95|ID&kB8>LXo;!Ek!Rv~Q^X*G%EPf^EXXwv17H_gUv+faoXrMssY za9k21WLS)_q7;@ZD20cCO|-)GAp8fJmOc^_h)4El@bl#Rojy)H(0OQZW~g4noU&Bk zd22kt@2s9%tt|OS9r=77AtH`?rV)|LQk3U%P&p_y&8U;7EuiH4B$|*LAJ*{r8IMD3 z!%l|`5JJtTUM`Z8SrWFxQdd6Q1CCt!;M2j|#4xS=;4&@u1iroCw2=eQbl;$f;?l#8O z!X+UURRu8zrVh-oenXOGsEC>E`ZeQT-l&Vx>xTW`IEq|7ls zIn46(F-DvXq;t7G+`FJ2R%jWYBO#J>1bD>~LL{-JO{*9&GMeQlKe?Sfd!9#5IA)R~ z4Mq_%!^41}<2Q**D3=$=h&)xQ*h1iBZ5+qpgf~we`=pMqJ~v4vXbM5R@AJe>A{3Zq zgSCpW91squkOkGzdg@k0TzMpH3oBYp;4Lgx(1k_Yf~Xo{WmdZ&1L%UF3$L1;nxRgF ziWJ1+2$3)ge3f*zPS`9i7D*blt|2?iOi%(W)>$@{#YN`Ji`0n>FC`*s1(49A*E$*= zEdbOGCP^?aqf zu!8I^2znO~7Xp4oecZzOMv`uiIoSfjv zPkkyM`rrr2Nw-&&Bw2MqZgw|?Z(zN2xzqCj$vRh_(R8Z6=;;18 z(_voZve*-@^L!8WvOs)(PFb zc%Y=SDg}v}BAre%LXzr%pYY9ZUeC*4{c0ndx{Vc2Lr`;4a0wF17M(E5^mLOjP}Ir+ z>Gd1P2%DyXDlGbojJR1gj&9`GfhjV(c2Qkg(z|%ZVej6(R3n8Q2?JyhIN2NxB76dD z%c4QVN>Oq5-3NKXRZrAp`hD66@BZm2O86ijJP};y8Yo*7(ut1o{r~y~kG=E~_FQrW zhf0d;ufLI`ondrzBLGXYi^MHx28x!d5;26kVT6DCkIxWSI<8EeIKkzYU(W38EZOWR zDu_6`IBNt#0=|38Eese;d=Mxu+`R=EL>xS^pG$XdV6O$JN!mhD!9$Wa+^H!BjRI!O z5yVhfNNRp))-R-mBpLeDRY+SX#t<~5LJ61Sg(llwhkBs^WLdv!f<-^Xk{za}3yeCK z5)^z!CnuTp3JB?(lJuX-_4&o)fc$)lm4|X3)I);iK6t@%5=2GCfSBIH(NLTRk3SFo z|D}_}^QL*{U%Zj`U-vDre*nVeEr0e6z**%+l#5_nu-S#;J}ruI{x-Pd1O#RFY!STU z51z+LAV}DX#d3k6{A9Psx(eX3EMi!!SU|LPnmvF;T~{y=r&lC&3y%R)2t-jt9bLG@ zNs_TF-HeGMt@xF(!4x8ckpf}$nl%|#VP2MHVJD2cIuJLBJ3y<|qSc0WyUj(rcCr2Z z^ZC-3zC?JAHN8-0Eiv*Ccz`{aBI?S~NeC^02zy8{H!-jJq5I|_^8BLfcaKQG# z&T9@}X&Oc!1GdNgp2bs7E>PAOy^3CrC#9rikTgOFEFcsSkR@pk^l||qH1$ESI;Cj? zt#Ea!kj>?2hKh`|$zh>X5j*K1rC`M?kdt|86i~{cszMq_q^uKD5h;{mvlaaTk~;C&vi0DZc)tFY$z{o=GWG)KwEl znw!&aG9a}dN?gIWum3!o*N?DNxDPikSqMv9eDR~HRBD8wHuKAfe#0K^S28$q5kWXh zGgRc)k5az%4u0~3@AIbDn`Cjmf*c>DUNO?M`D{ND(cip~I2$WELSXYf`s2(k{q-?BV zNl=^9Qxm1-iKB8EOK9iWD2iBT*~BfVN3c*`z^g9n%{(YU2ja0ftxjw8GIZJuT262A z3L#iginOH_Fl;MFGYD8VUC?z#y{lmhA_F7C(m|w}5LlM}S+y3RXwvGmh{a;GEl6fE zbe5~si4dl{6pvOhta=0((X=cY=rLtCrA#PAJ&I|Pon?V-I?Cy!*{M@z>Y(79G8~=Z z^d9XA*7uf0WE? za&8KY{I`ZfbxkgRnU4+bFvkua;UgdVN2*G3;>fg7@2Y7ca#vwRtm0QQLNILGXIH32 z3ZC*bp5dJUU~#&Dlix;LI80C9jpMjyfUF9`HRvl2PIJyvy*Riw7)HjMCuO`k>iFcO z!+>(6RxGMZe5K zc@Zfk*>qYjZrg!C%lAq!xHew!!4jrOY0Q^7$zX~{UVzK9LU0E#m;A}Nusk)414KZK3jk)C-0~0%0 znmqucJ~(=clAf4g=17)&KEZ%9O*~Y9jpxl#6OxLvlZ@LWtwK_MfiVe1-(%Eu85kU- zUYTZ{g!wQ}M2sQ-I4NaO%MWvxILwf<3rkcO*%neQ_++Fc@&crE2}6(6X*-S&g|~Jx zM@2l0Y0N__R(=r*lm}Y3XFFX=oz-XQcGY7hrgZvVulcY(oi;5D`N0o5@>Zc?m-Fd{l;Py{C7{^y{$j)mom3e!W#l zXDz7FrVT1iEv|pwHo-I=2NG#bd^ao9vMg+&o2^|V$N{vcR4<;JCPEunHWQG6E>*PM z)YqfarbCBBETIjt%OR~+i*~o}YiUoFcuN;f=`|2yjTVV3@Vq)K`Ve{gyjk7LX+%Y= z5pzzbVblRj!s1GL44#k;y+J2D~5gpN?E;^L`z)U}!9{025H#MiyOybX( z+{z)LRp@LfSYd^HevktP_p%hpU$`cV*J7~)8Wsi`R<6_9m?2*aQ!nlRvu^g$m_ z-B;TJuDJA3+?6A_7!I00UL+?wMX)i2o+rt&I2uUZLBv;Huoq3m7*5L z5TZdw43nbBfjf>ewSOPmcJEo!;z&sC>h1_Zapnk(;(pp$4aq2n1r8q;Jm)!o(yP)G zkTRsGs%qjb&GXckzM5O_`z#l^S!R#VF}8h#&0Eskv;Q`3{?@zgW7F?h zK}x2HDiv(|NzxV_ihh8UF}Cl%g5&cQT-W9Jv^Z_?mNf6Dr9s~)C1~}9FJTF7 zgk+DPl*jX*zMHS#bT^bNKJ(>$T=uLyQrZMTiLPf-e^FVDs$ki@g;(j*Fz z1)gY>s~$Yz^KpQTlf*9^-~(@X1%LbIS8>}d-(t_6-7GqJDq%p?pJrSpN!S9$v&5z1 z?z_Lq=Rf~%{OL7+!sKM0P5C_Y1&@X40y{3)Mi`dayY~Q3eabWV&=)_;lo-y~EL8*2xeRtjPja%^9E*#KjOTL9mr8x=KoL1B zLlkKdkhW>I2+^Tz#6sE#EX!hJHcMP(m<^WLdEpMeeb)k8wrtT|RT0t-ZN9W`hVOlT zjw>HC%&%OXq=_J{l1L%Qx|3{u&zJbs^=Ur%%BRy21(v*N5>B3IaDos1`*)b1_Ib}+ zpTLTmCZBhZVG-qA$|rwP=im0;%dlVM@?C@c=CgK?b_)y;Q7ANVWu6xPY0uXqQDk)Q z`~T@Qm4?~RyP`jhhg|5LeZkZg>c1g=Hc0|=bF(b^A=kb3Vg?+S!hC^D(m^&ul1ZIh zRw^DVDkMLCF;WT&^962y&PLKGTmhcCkB;(bTauymc}f+vdK#jL0g*NhP~9AD3qeYm zQmfDRq}r;X%-5Ap8x5>#(Q5U-^B7$UbiFr`F$IXFeNf_-qHPHSIoD0zpc?4y-V#)+ z+WXDIqHX~-)BFWpkaS=yH^Nd7@Y8R9!{k0KGMOQQz$X9_iBn^C6w%`vy>MHRi$D1a zmXt&(VW#l9+aFho*`)&Eu#SOl2-RjtF)i5cK844*WoA7^9Lp3H+KaDYKE0N#k3bCe zlJZAC>Pn`jZoqXdDnKG!0M>EGt+#OX#4|Kf=_G$MtxBu-+JAhE!rVRBqC-q6nkq(H z+T8J9_j1+mO|a-I!q8`23IZeYkwP*sk>-v&Jznv;I4K*$!h;kdrp9dmcZ$!{f5cE;H&X zT4ktfFd0{h70>4n-t;;?@#&jr5V2{~7JPq!Ctk6Gts8S(^M;plXx~jhNImpvh03Tt zDT1XVeDHm5V_YtiQuCyMmdtVUefRK+*ZeOQrss{D_G(unZZ33Ot&ZqZeH+8+-%tjJka0(|h@c?=A58y%kiX-Bpu@Y;N0j&yz$&tGtmx%OVj=kccIS#S%b_ z;Y^N}={$7k&~9runC_0~N5U2;6&SvX=n?Syt7{>IcAB^7Q~jVvluxG};;}ff7<4*% zESoWKv{t9Zpq1%8XTa#ouS8W=q6lGWQeA_Pw$SjlE)=n4na)(8yT)NH)CO`v$fyvs zLZ8IJTlvr*|E~VM+bTTz*Z!9C-ufLbecKJZ_r3bs4qut(51)G;)dNdpgobgH!#M(( z{JC$WU1(8TbY0_z&4Tt==MMkUCkk<;B|d#WWO{lY$8m7oK?;TW-aQtE3Z#N;mpD`iIrpj0<(Lvgo<)iga&j9|o{LW&mK`EBLMaq%+PRa2Eh!Y{ zxMzA=stor@nD)axR*V-zD+r8=pp6hV%8-PW zQW^##Eark~GMRB;qn@&Q2N;ogep)n5z3c!0AOJ~3K~%B$`cEs|c>6r5LC45vR!|C- z3pMzu&zHaQlb#=wozJu4O!9C0;s1Q$2%kBA5pn4V043U2nLK`@cWW zk8k-gAG&rQuYJc2R1nO12gv7#S@D`WL3zL;V2^lhKM9wG+1Vm zA`WFT0*3O#v;svdRE&4US}dI`u9HHmf&$g*s;qnzMMj86Pgff4Hmz2Rm6Hq}W9A=v zEz4xD0orc{88@W*y15=JW{P4N2-tx6x>>CndjoAy-DpR&IxSkAR<9Ym>=%hE)tjyW z1c6UHo@C6)8Q~wRhk7~r-0lxO#xK~)wr%5V+m;p2qhi*!5H`wPs>xfegS3St3}Yl@ zNLp!Og%lDYpd%(}$t=Er6d7v%Z8VC9Ie73OzS$>5&vd!FFNfTA^YxUc?;)-h5LO*& z+a#srmb-4}(kDF=zv7!~r(@M}AC54tl*!G7DY$g}EEJadCMoKyCY)!j`jtAXMcwy8 z-4PlBAws5()cNgKy@YRm^L_^1Byp8Oh=`GFjb}gS3jXw+zt59@R=s4HJWI-RCu2=V%6X#!fqTnNF53haK| z;|WxZju0BBN5o?vy_>iE{_pTdfAZVB;WaO0|Nea}EiG~H{{4LM3;)hL-|`gQf|@X_ImFB=ui0Kr}h~Fy)GaEv*GrNMav?YS;d8}F5(t3z!}Rikg!bHFk@*$ zUK_ybnNr!dO~Mvz*|LLDxzyv4jE;^Nr5r`6tYH(jtx5Zl!JDqA8ktN65l@=np##Q- z4I9?H&o1PvZKR5WK%rDX*Kjs61z8vR6{%1|zk~%{BTuEk)xmY#aj+0Ls?5u;O7Yv3H zNXJZ3wZc^cMcuD3B;-R*YT`z%uS=fp7AmU+%i2w3#G7W9P;3z)$*@2&oMv2>85Tv7 z;QR={b%S^aNW< z!{$j1>k1SJTSL$?LKh#i!2;==pir7YsQ}v+l*@~ZjpYb}66-{U6%}FIInxcaO|qgV zzd@kL=5i)ku~14YooS9-L^FVdouMr{q;pxOW#gF=3Kh2 zt7E^l338iA4Qj|>Q#xGpnQ!xFZ}}*k^Q-WfExhcvUdH=g{2F!)Uci5Rdma04O2MrYR$q zRFMHENkYPs(o+9JwGp<6?bul%lDc3=4;a>1pE1C#!rCg(^CLAN+GhMv?@<93zgNmel^O zuchG~r&zoX*Uhqhaw}eOkuZ!=jpA(BI^0792$S!xsMtyIrmJA8pJ$V^_f9+@Z>^Hv0Ju^qh2tmi!223?N#FeE+CzL5JB1T6y5-G)esigf$ zBB(@Fn$?J)RU;N#OUyfRE$Qq)R{ zb)y=UDukdFl$c+xGH7L}TM$<@%Eblht<|uc5FP&Ozy3>qok&qGE-*ea#*9CUWjSoz zILe6=C)mDmBc*bgbk4@MVdIEH7%HlB9_NfW98q&%Ukpl7L3e@febyM+t2Z(<aI) zC^q30_Va|iVCs*aOI0Z&dHWROW#Gg75@q3l8|Y~ll8S)sK!cF7kYts>4q;hF3<46t zGI0$zvO+8rDN@wBA`b{2$V261NYR-#JRvkhs=J})*SlPF;Vz@g{_v9uAvB3Cu9^%u zgQn9_qb-s=+*(Mx%2yb027BHwQaY@7OFd7Ou0&%>X;as3*G4H#kaXRyDP?Fh>1FS8 zCnU6dK}rf5l+Dkjc`TVdL6S%($@+>0lC*-fh?p^i_6P4Wi_I7)jG~i< z1fUdtSi?8UC_V8H^!~s4cYR}!rF{;hOqxVKd1?dbG!uxn=paQJrE~$;3Vo75+F*c= z;4>~S#PgHr-f*!cLzQwl={2J_5%1=hJXnd6_L!AoFd7g#lX zzrt=QIA%Pt)^0?)d)sw?Zi^8H)V@{$1|8=vyEoCZ}rLwh=rTl2tw{gv=?$w$LH1Otlb55~{}J?%h1=MPK6Pq6Ir7 zC=Ut+uKT-BGwbcAAwypOx&2@lx&7TEY!UDp0nhrxlX=;jKEPP^Dl(O6I*hOoy0o3> zVXuE7`aD5Sy5Ca|m^_O!CjUQ6!SJ&j-TSBACu!OWn>2__hc-MzqeK$=KKXo}Z(sj) zzWd$p^6vM&ceS~B8t7%?EI*Hilj)e&z%tDjh#Ou?MkI+V9e2BeJz7AdPias@z4cKO zYm>ATf~8Q=mXes+3o;_jidP{gp%r>;#HJByYla58sTWs@LD8Wh6m0}$6dj>J`AEa} zY+J&JQI#P#!iX(cACx&{4RO4*z@(KS2(;;A-T0~aevL6_glbhIITEqNYH^T=(@qFl zE!8Vs;&F?3OA#5rlYX=4WX5Kos(spqGd4k0^Tvj4n-vw|FD~F_GCkfcM8tY!QGc-% zV_|+_&0I&s(=@A5?|IE?L?$ytGtz&Po`VNx zNKv5f3#8nI3Tq4sNkaz2js*O{@BS}d^~`_a^}l;Q6&6`x6D|vk6~0f}E^^oW0hS^` z13`Iu3gOSPXWJ(3D<0wsxt$CVQs&6A%)aSa9{+-mP^swnl2#HGod5-!gaFDULxJuS zir(Z_N~br;?INJo#)mGdVO2^zWeTpOQXwl*(8JIv)x`IGMjZ#-VIVY)^dWV>f)GiB zGspnS5MmW+Biq;(+9**qS33+DAqainxD|Ws*u9(Ic0NY2l;YdNyx z%@;hC_rC8sUh;}JV&?}rK6Qk1CMPHqnyV+-S{-*agdnZ7=~+vK#>2qEacsOLpB2wz zbi(D8ul+4Ugwj%`e#IxQ6c=){Qq)@wv$%D!5^uGTj?*(rQc=W;=+Fw3o^%MUBxYNgUJ~kV9KjYA^JQJU zrYwu0p$zfJqEfB)Ubi215k+lNq$FsyBGQ>0^Th>nX$K-$TwG-5&YhIYWh~L5ZhRYr zk)|FTaVQskL*5rXC5^gL#&}edua&Y$3ADYOf~t`*P8m1dZngi5jBp6U5Z85a9IgBn zh9MX1-p%C1#3T9|86g;O9XwALL|yL7nKt^fNraSK4fvs%iVQe|eR$U{VgA%~MR$Dk z`|Ad>Zf8gPt5lHAAPperIK)+`;Y&iWau)A>wGa~z=#Kti&{hzHVH3xJ!n8J(?KW)k z`SG)ampu@4=Vwp$RL}ECQumvTI(huT4l`57VARDsJi|p#I+ul!c_8H0AKrzOaQp4| zv2kPr<#NDZ|MfqRlcTil3}L9qI>xJIrp$)n3BpiOBw)f3Y`y#vAY$v*$)54=fZW6D z-~M6RPAowcCtoB2&zj>C{IIn zl7F}rKK`W-!rUev{qzZbbp5-yK*8d^1&a7|+`|kD$ME$Y9(3rzy7{S}djvc)K3xc5 zrmH%ZIgZ1S95(W%XOI^*mIrYK_f8#VzFh9@HQnj$BQmiuFcKk>Ae3(Ah7}TW5QQ#O znj%Sx4uTG?u!$l>_2BUqmLD4EYO;q8(I&ZFNV#Ig(~T_y%w{Ppo7a_QZxjf_(`{6I z(tTEMtp_?+LBLWVz_3EQ6O=ZcUXjtYLI8-x;&cppqxZL4En2OrL2ek1Y`Y2ZWN)q3 zElaC>nS{o&ENZ0^Nn`l95-A2E!*{ks@AV?nl!&)ty@qHk7V9B6Iz6yi$KXaxlPj^d zA=S2`zTRSVQhZix_cV2C(b{c#HN?rqzJ?d3&EL=*74rvz5VDgrE807$Fkj#muXqJ7 z_?x%z8*lzqoin>}AmZ@!7umS&u{`%hFJR7#(I87+C<=ui@za~Xk5UV? zH~r_$yzUKuM8&U}J=g7VTdFEVGDyuN{j>8+y!9{M%cnm2R-X2la~M#|JbKq=?wP)k z_Z1lf z$3Q8L%@=sxTi?z5-c{z)H++xRJ?Bv@P9I`S+MIvsZanV>0Ws%VB|p8e#Lc^ZCnp<5w}q@YyuX?WUSAq+iAm5^kzLoS`9+4Km0?8%45=Jt6|fGQau6_NXGq$bfSR-=M~@z5 zVss24IvQ5f%euO*wN=wyiP37cdatRAlop9tf?D9?9P#S^1 z!w(rB$x|$PG;kRlS{Zzh1}WNR}<@ zH?ZQ(n)jvQSxTPIMUQ%>KF_!P1Z=qTz&)Jrr15>95yWXa)2|ltQ0lp%0Y7G^UolDgNS}&*jC*G-D31=z+3G z$bk4fEEfz^Xk?O)zy0&D8DNf|eqn?wZ}>E`*Zvxj6Hpf&CME`%x#BD;~xe%Ii2W>bSIpHjz6UXslN7^qHQX;oa~4Q>sffjuobRJ`t@o6BSK}PpPv% zZ(&$7qCYw|X$Y_0D>EX=6c&TRCLtnyPnpSRN`eq+N}=)RL6DLzviq4$fu-YW*N`uX zQcYb9sU~3<(lnjvwz<~zn)dsM3(9w03tNc8dXOb3*904+;kS%Orw8nd;r zvz|)CTQO5Sw0m%`)k2{QE?@mFjy9H#_X>`Ph*fTDcircNMcmR#rWI4b2v%i^E1b+O zSrrUA6^PcM-im0no5V?i(B%Er8URGJCMNe6D&6l-zO~|NbuT$tnJTU<4Y@rT(yh?a z>qVbrdK0M-l3~dH{WE;)&J%q0U9VzC{!ZMH308_QBz91mF7k;Fy^jWY%qYd z$FSwST>6wT3UfK)*$vc!Cifpdhqt}wg)Gl|y@p^b3~5Vggd?<>JZA1`y!MOUzM{R->cHW3Z#R*o-! z?Eu$&_(qDACXUmgdX{~ZvuhHbDss^_n6h|WDMm&{dxTck9nu>AzRx+6Tgm5#+2Fb; z73+0(QmiFgpBxn9eXvbUE?OP;3nBRKt@rS@cYlZ{zxeI^@!x%pB_@bFTR2`Q0~s7= zf{w_Mo4k~cXpo!S%>mEl`X46w@F%CR+)MDh0%16P((9h8NuHP6ND=YF19vdIYb&4r z&%?atjbGp=hgr-)yc-*2AMYLKi!wC^2Z5!LR z$>wr~w6D86K~N=%0&F`&(w05E_wsU;sv)@zS{4%%;|vXD7|Z2w9EXX?tt1i&+U+*6 zSd4^7Lp*7mXd#j4VB5J~kXlgzD^WyM1^9lMAW(#1dG)$lr#JEHb_)ADhW$U+r&aY~ zCC|Q_{{QmmCfgdz=@{u=|CA!@XYN-To<$heh%1HT43aRL+auxAB74)6t{kp1IB;P` z>hzRQ`lkt9zad?u>X_2)8fFZUy%pB9)VES>aPu_K#5~t^i7Wcn-b0%JogF@XbzM$R zAHj89?mTe3rxv4>BH#5Pc$gEZ2YWntCt9n-InE$Csf)!evIG9TY;s*(g+<6!w9OmYH%H@!2uf3Lc{pDZso)7#v3)9nFylX22_kk#qmhhvyf6R-X^E+I4 z&f|!yjab%Z*13DQ^wJk`?zvB;EjDxh_F=yIm9J6@L#}?p1e9)P_vAQ2NJGAVaBRL( zs^>M)pkMgZbkYoNK8hmBr3KcRdn=u@5kip5=1ACrIuR>Tm0CF<2m&H=U$rf*ZrC*3 zzHS{9H=MY-DWbIZlpsaKa%M}<8hW{4L6Bu2a&e?XUPv;&BC8}D#3Tp@7DJP)ND^TI zw|0Q!`~k>mspqs33^*>OFoa0L+&t`%eC)%2$e+Le1-k2cG|S(8`3_=Egp?8Y@1Nnq zU3(t!BXe(?o>bPeW{}NKN&K+d`{)5aK)uDC| z7OGe^>{DxE)tS~FC=xPF*H=y#D4o9UyCAK~q$rbCA!+3kHxSn_Y_jOrkW!H8drn+w zgo+RlbCNwAe_M2DnHb&*YZ}=iBq?k&mDX`HlkCEY6@!D&Y_4*L>*joP%~0cte%U?N z2|*NTsFo(r>*BsztrDmjmYGoW*9dEi6#f0`oTI(wtabfXpzFJ$VPBSIAuMqUJWQ{9 z&8KbF6pcR4ON^M7Cbl3JTYdd58#hjpgs|7VHl`U7wTxAQIJFtnom4*(ViPTamNQn+ ztTpMvyhk0EduD1p{ndZQQEw0BU>m8C5q4bYGCA2|&-Oun^T|)<@!PK8;_bV+Xjh4I zCNIG+?;^84&Cz0wuin_^z1MyW)zlOJE*ha~?x6uEiBciM=EEhV;GUTZJ0JUeHeK*s zuDjs?=Ux75w4~&v`no+s1Kh(%G%VvzPLvAI$T=ulWQm zIf(E3Mz!ly`;zEkoU@bvR;quZGJXFsT-N~xnVLGvbJdt7rR=jy!SCSUt8G=eg zZF-*d?jX{IBiT!G?2LtF#=}vcu6aCyQndsY)0@G25dWByQR9RfqUC1b^lF4MSjZ#>%8nHM#&-loYQ3iqCkJ-(R z9XmOC^e914qFId?8=K(3kwc{IG($r}1VM={TQ*ZR1bxkG$dbaswk74V&pII}mdjd) zT!|ibv1_W-I0?ScHuKsB##Q_QEBRk6g1YB(F?O7OPMBNx{J#9AF-lM z8rOB#mFDv-A!WMPnM$29K3{u1y7I-nDT>hEF#=2yu$mmS!X`LrgK>3O@#Y^A1g4)1 zukWJ=lPO)Dyyf!~J?N{RE-TtXvf_Cs5$qp$BC=X6KlsGtp(c2aBT&ktq(Tx(FgfXP z>pfp&`vkOV=W^5czt7z494~+Q@9^ZO{0i@X-v@Zv3!lqfciqPS`G>zHt`x6)?Th*7 z=RQJAD!%&VceBAAps5s(dcx!R$G5$UCp_(mBWwMb7uptq}h>O+aLI^?Iq(du8F^Ey| zG6{{Hvk`$sD^NY&-Rd(hk7d1M>mAu6*<;!AEm?2E zF3E0kb^{3sfddpmLQ1(qAt4lK3#HHk=_!=AEtYEOHGk#ITaGIhVG%z)Y{*>gHEYIph$lvLJ+9x*FZJM5X29@5CUn* z(49$9Q;MonAS*4pgr=$Kx*$nS1(XV9hUBo`??~c@@3FMxtOr&i7(gNrG?mht*oLA~ zQ8Yp=*;;tdyMfissI^jhNf=;C8K%+)w8H00DTQGeG}ctyM09r=tghALSxR?j2kDfF zs@15ht`a49iN<)k13g_ zXB0fLjV75EI^@T7eJo2;F$#rAEX(4rKl^EfP>gP$2sT1Wg;4rBO4*B24SZiCLG9LhhG?P0dhlX0ZIHwu zlgW@!9b_j)DV0j3vROQ@N-}NGXJ$#7W|$=)s00B<5U?8PH(3kO$4D@zlo`^#w8(xa zlcm!%A(Nq5G)Sm`q@jPG%xIRqd$+OovL|xv*dqV@-GAcHp$Ec%H86}UnQb|Z-e(7> zR+nj11Db;-^Q9s}2pXPt7wHO7Bb^Am&vGezz@wv`WcDQ+w{Rk5w1q+1G>92du_VCVbkLQyCtBP_YjOVG-8``W5a;jR#Z5Q=GsotqNGZjHEpVJ!R$Y%z ze(rO4g=s9y=4fFWZM2faSz2PHyvWf)z!R=`CU1H3|6*olhJGRG&$n=#X$*Imv&ZcX z8jJR3W&L?2CU$82rOs-&Gd2zFbQlFTM*m#}I)i|0HcJo$abC4y7&>FYSU&@VFbRZi zgz6#c-5sN~0W~9_J2YM?0sR2xxpW5_i5|`e;5`WE2(To@rD+n2SG>U}rznCnrgc`)spJ2rM}2P?r)YAQvyT;CJA zrOmh9h${sdC{E}&4jm&L^)q}k7lUiWhP?d=>m zP{Yi7RHsGQEbE3LD`j}!^?oD}EV(XeX|d*3*uH%mvy}!D7hlbXU+_}?oHY~C2939Hw(6oV4X^MC4=kZT|DIa+A3z)AEQrvX?T2*Sx^;zEX9I1!6SDpBI zOg3ZRWED0dsnDH5ao+X`s>;Q2oRBJ_$DI12xX6${9tZOw*2npQ4il=07M`!Uo9Atx z;OKP7>lUzmdq1wLSeTioQ%bsojbTf6kMBiaYrYEeNFsuz z8Q*xrFv(=HWV2ddG?>Y;|A7MxWe1s@on<_iV?}w?0V4?L3AvitY!-K6fdtyZQ)IFz z0z6NTe7n%piJ?r6)gVBr4!X)^jJ8ROoyoCn+Xxq3bRp-S)z9reyNjRSatlo(%}_Rn zmCN9HWlYmV$_#hkeK!*m6C9rcr@G9jF-Wmkq{lE&fug!xqUe?}gk(i2I!#IWcwx(d z*1rF(#`K{eZakuKeuT)0P)K&7diFnxz+Tg@)_ul>5FtfShMI~;_Cc%4M+$uyuK5k} z`F@U0&m%;O{P=i0zI`OrvJu;+;MWjBGCe&*VSbvOJ9cfDrZhL1KXn0}Lh|Du|AgJU zcg2mA*wA1q)_ncFw%yCB>vG@J0ru>FH_u zOv(88I3T%yYAWXIFFTWr*?Eet!Qtt7dhCn1ao;T{)nG7VkfDPlg6@pgK6O|Z@VW04 z*}ErCPAXh?QahuGehP(sSXTZN*Tc}Ii=io=x_Ic?vc96+6FvRa6p<*epynwWA<$w( zMMD5}Gl47}>g z-vA>A0}4wnB5NiG_CJ7SDd<;_72pY^R1EttkZi%(EhxhWzxqpl_qwN0S3d9j{4r1& zc0IntfYo9_Sk!<{*?Ppwql=BrVN;yCIrtAj1`8)YT_JEWSC|i}PJ&A=zL+OH{nr^9 z>c@56)6&<{mPOHVux&f0ms++>p)em$M^8;eQzr#I+V}9LP^`K>bp+kgqC-e(C`xjS zgaV5OX`$#-eylr@(xQTeP%dk}6HkA1mXw7M{lGjq%i?HZl4J;A_T`6g-3Fbqm%w-E zBuRyUPHE9&^;1q_4qTKqzG1nfNBu1 zTCI{97-T4$jj5m!eG`COz=~3MUO*zy4NQPc`ssDW?4jHBq4ENV+W<8x2M7Ws%dC5Q0Ue zr-_BaG~?sj@!bk5ZVl`d_fJi6?o+SezrXO+R4NUQ9Gt?fxOArALOVr1Zz1}Js4msG zXJ$z^aVS<@=n~?LCYq;b1*i>sRej6(t(^~(zVEXdBbniNG8A#GQ9}q7AJlqG=Esc< z2-bXG3l(KM#UV;O4aaCIh+U0_LYvRD1ji}RFKo?M_I<*^Co4`R9IF|W#Ux$ABB3N} zzDchTG(?M%a*#Hx`KMk;H8DU9kAyo(T1u7+4HC*=$9OM=!d)m~g+Et2c61>~2nG18 zg++iTAy;x@G!@Y z9>bI}K02D4Cf40;i(QXu8wipy1uQyb{xf8ewDV#kWW=)M84E^FN6pgBPbJLjuz1^_ zzMM+2%n$zMM~@1%Y|e4WTD^2z7O#K(YdL;ojvw9fBOJ%sGzo~bY8nNSQu4dMbqyc= z#Amqr>Su-AZ66t1p=%^s`>q>$Rm$N`a}P@Ld%) zQYyAk_QU<^q28Z%7qT;Jm``o~P*qC1z4$)9uj#isV6%bi*J#!RN6QX_nLMlbRF^88 zJ3daWrbsBwZ|=)$cc}z0VcX0(4!$zUS$UrF%D;lyV~{g}GS|N7X8`>dXsc_1o%}3TLB?jF=K$mER#jgJUy8%p#F6GdvLbH~up9^WzQLpMCKVf95#goCSC82k~?M_WBQU?A8@}>~Ut*ex%4h;^(v3<}lZc^ zdtWW}v@*LC^+_rJy6ci)SYsnhNON-46^;_&p0HttZ0s^gFg z17S~un4f$vILX(1H`bl>*!>t%a(Hrvf7`c@8}3>IRc6<)6Qm>9HgS56<)TfBbtMf6)+6zT{$7oC>zxOUbWc3CVYF`e&AW zpO-%OVwU^@C0~)1!z?*9zW?Jp*!Rn6Mu*3Fo2+rvJCR0?Y*?aW6gj_)-Loi^`*Q>~It>xoDr2*Nxy{oLt{6hWiv z(PNsBCT=pi!xdW%->(wZEyJTDluDW|-eU-6JdZ>W#39&1XuX9QHYAN&5dTg=us*>x z3?tr$BTzo7eb=doXZB>I!@8~^1wsiDr05VH9Z5mL6i_UHZJF!L zASesLaks#Z?Rk9HVb$$m#O|l)7U;G>hzahUS)wTv+1*1}$wAg?8q8Tzf~A=nmZew~ z)2#V0VeiCoYIKPfP2p~_GM5i?LpdGbkd(58A#~u6lr4PU3DH6eD91N&-Q##88rapg zA#|bbh^^j~wz&ihyO$Nm!S@weDK&yC1PLWcD9I8gLL@_^M~~ff!w|V)*fBDU5L5^d zN*DDJC$BDA8<4VS%$-mjBz+glN}SJgqs-10Nf`!XxdCR1 za|~s2%+Aen?yemiK5&Tbqob?@0iIV16P`yI$m#D984-pp2~=65Bb}xeuQm;jE=*>M zvj|~OEGl4#VsVzIU%rbYM~{-tWEdV9=BIbuNslm@oSVZm($wiV=Q|mYGqCD zDwk#$9nDb(OheK$AUSgUIHLm@jvYG;o&Zw^E}8h0T!WGb7~m{~I7UTD2=hRiZN>9u z1h=d0U~Jc|)PX_OK~pF^A;>6$gc4MMv^xDk^(eI}Tg)jU8Pk-uD z;m>d$l}|51T}j<_`P}FJ2GB|LTak3tM#)h4zQfVub20U+ebNzq_UIZoj>AXa|Cc2G z;xAZQa#%xdxIP_?jt%spb`4W|v1a$%oPWVi{`61Y!PQqkE2bvZPjUV9XY#jv?cv>z zhl4tu{NL9RZfGZ2PBtyHE*n5-y8K!7O(WzS>C>*B_dd3GKu z)6FvJU9SMoVb&O6O!+J@%nx4H-~+PGPi_{l=!aBaAm?-A4VST7)|j0>mjMYCrdg4B zs>)`h{9)!igIPXKOPW+%hxcAQgmv8x-u>0P;j0GlO*ns;cR&AkNT~`fyFeYqm^F^$ z`1;zM;yF4UcXiEIbjtPOf4MLpQmF*f)6-$tTpLYv()bc=7GP3D%<||wGdnwvwA@(oj*jx;};=fzL5gDvBnXnywYh* zR;(g9r-L53lOuLFU)=W#ZurA*LvS9Lt6;bsI55DQZ<^!$JqNh?Gq2>a{T3as_!P_y z@bzzemZ=9mj#4gtzDYkmw=@cT<9iLhapy9v>v}m%iD@y!*p3N4{K?z+)Mr+KdH%0CjxocnC4BpX;E^ zj*QKqCFnH_dJF?!2zpJEgr{g42BM}Yl{^eXFkRA(OF9iot&88gBb^}%!+^0dt(R>8 z)iuRxwHllJ=)`+PPugTDY&eWiU|$IW5>@TYw+f-I)#J#KqnM_45t}Ki7;sooiXfbx z^cV)otVuTfSc?mD+JV#{25Swk1Eqr4aQn|?Fy@wco z%r3U&2l&PP4`O8`_uY4lJ~;rM30{FHP|vcGbfYN|CEpLliyN(nPgF#<>!-xSJb)w7 z?SH1%$!Kqn=AbFjhR*7N(3z)SyI~H=$&k_Z=S4f3gjV0;%<$kk3QJmaA#far!hC@% zulRKaGZwDvgoxUI-d7hsg+hh2Ok&#>j#Hq8V0?Tp-?`~l{@O8-G${J>bV$KnK2*dM zSK2mbn_V=$LEP~Sm*DWMaSOwlCZ&`Xao_%Pz~p29>(y8m{N0ad_{sMV@#C)@=j{Wt zeD=+c;z?q#z7zTtPk9MfTQ%a-2#bOx<=r>J@MLoGKmr7u0;k}2Zw{}s2BOd1r zUcfQ$mlTV~A?t(Gd%jorCoY}X&1c_mAqQV{J|({c&vzM?f*m_X>8jMiHLP=hs;*15 zP+)L;2cQ4c`>-rYf3m@%TOch3)unlU^SS5qlowsfzwV!9SYFA1Q0&O3$Vwm2Ra8+3 zUvtbmQKzL$oa)sbqPO|HjqCdC+O>OBTUfLQMEk%>5NtW;jqq#Tz}VmjmGJML=h0bR-$NprF(N88qcMxN zc&?vzq8&z3h!)N8nx>SXAp{*FOlvnJ2zdg~Q6NN1>!qYzrzcBYu%{4AOl+rI)5ZI$ zyRJc5b#-$-WancBMs!AQt}p#C*fe4RsF3N?DW%SKQa(kuup!H>DfA$~aU8lWi>h*{ zhBWB4aAIQ#n>Ali7mqB5tuJp=C=`%VkRP&fmbBxk3>%o}cS$}P8&os4`}8-u`WX7p zC0}z%H78T&UUXZMs#5d{NmJ@VrR4i4Upp2=1w?OKZbm|B!ETpG(n(8)tqB>@vrhcd zO-kn^mCuN+Cp#6tOpk40sa|d4ya|2X(1dUz zSBQu63MiFJG=&k4Ek*d?skk993=<<~gbjpA7f@9CfIo2H0HdR$lu90V9k`p3kr9%n zz%4FfmNYrMx*mHKygK6)gt zP6@W`rHhD~W@6bx;HUWb`@hV5?xp(T&egzdz~gs=>vH3fL;4MJ63Peon)h>FbMr@- z3vEsx@GUUUhFvx<-`mS=`)=Y7pZiR9jc@1UpSy$a++5*n7cC(AcSGq`@Ev*>rtB-K zxO7+&H{8EZ^_rQf=zBbR4$0E(IMpUY+bg8KG(G7FI>iD3;CVWMe%UK&kS3GUNNmVq zc1s?)!9g&fTv|XFI?QplRKzf}Eoq@tBAYd1`s;mD2N?q%GjRd42d7v{D~5B!8j+4b zH)T?qU!tihJO+WZ1Xzkrzf9NEab`pw$5|q0X$Pt3ELm}8$XOOGcap_|UdIV#v0QLj z6%Hf$6j$za$@_ZJiNDB-9~I)daOsqfe54T>bojo{a$%nQP@e0qyN*sNa4YV^7QH^2 z`;ZI~)uvjfu}n|TaQp4I^W5h?XA4te!}LdO4&qZAj8fDiG`l$6W$6_e0-2}i9^||| zPvMQ%z7uv|$BWKy@zzf~jjow_ItzxyYj5~9a-L!a379Z9 z!0&(I=e*-Ny_9EM(&AhQeiEMk27URxT=Mdd!J+#gcODVfzUVp#(j1$wQ9aOrs>f&E z_-c0M1AhJL3wheD55m3o@sB^ajh#b6gL^_y^=k;>LSGIjlgJF|T(@s-p zW1rO+oYhT$l^cvFZc$SdH6fj*Nit;ev`+#JArMO8p(*SsuS6xN5_pP6P^BXluWRB4~zZpa|V7H)vE?r)MdZK%vbRR?&ggSxatU4n$V`08>-*G^7s0 zwrq=pf)z(M9+qXZ;#BCAn}F|4j((B$&<*ziopYw}-5S1V(J2M_d>+Sfm~#r`^LY{> z2;7&~0|xC%>eCrA6?|XQ9CKFxW=Q=6*Xz{RZ*p={TmRp22QUAf*Kq%R2jWPDdRxX( zQivqoak{FYD%u+r^^l5{b?1X9sa-EN-_=%tQcCL4hd`iwpH-!4XIYtK#FnH*Qm2fo z8cHcEGg#~Z03ZNKL_t*jAcoC|l)V()C2YGlK1jp~(53c;Yuo)e&ODaY9}4JfnzT?r z$yp+qpP&^cqI=!TNF#u=`?6 z+{3()Ce3Lnu9<<;m902cI<%AIK(tfF5GzmnE;L%0*op{J0@6V1k^BNBa#&aets{m(jwB7 zQq)7bMVGK}LKcE$X#<)SM+d0pLVekaa_Ge(ZCNCgpspJ9*f!F4aVHCm+a`fKO=pOx zDzpQnQn2PX5JH^-Y&o-yDQX0ig1&q|lT(xY=5^O;8tA-pib>?JCTAs@nrL$#5$8(n z+jl#E{`PmojY?C9SXUD@EF1s6KE>@i?N)c@_ROc-8(iN(i6luOxasaApoXF3^80`N zBAB_ImTNF56$=OM=3T#i6=r^cCtUKIl$PeH57?SYXqLgafbYEPC;Z-1uO%aEtdarT zaEt-|<;Hzn{TIK%(!u%A7(}l%s%0=dq+v5)=i^2onKlT5YDoPy*BK+Bz9h;ZQlXW6 z+(@+7gh3EDk5%~{1j^K=hE|=DPPpkiNhpJc^hqi~Rhcw>pO%y~y~tE*D;U-tPE=fX z-AXuey(|<8DAhr?)k~+)Y@<2Hr3-4iPmvbKqu?@B3tJo1T#2pu&lZ>ngg?j1>)nX*#-X+gM7l+P1$(*Ci#^Gmy@t4zVl?yWb`| zl;^saU)$zoloBf=Irk}7pgF6$lk3Y5F(2kYq@|6BH>=jxW<|7UxejTe2S=mZ zCnyw_=*#!BYpkC-P@I`z-yL_bS}v0g(~h_8*uk#xoj8ue@^lT$vdBu4ZYzoJyHr(; ze7>JGKXlWGTx-O}pWi$Q-D|_b5*s(f&G&bCd6}`XL4=WJC8*+g9!=!|24*-7QA)*J z?S$$;1p&3PM|Vd5|DNYDId?=`b*cbUY2oPX+$^b#8M}6PfkCjza;_-^1OeHM4wMwR zEOj6&GAwx|3~${+RO^Hc-5_~hh=f-0mrKl!M6)$||k05&vcfI8T{{FA7=SP434@}J;V_KcfP_0HW*-NU?;Mnwj z94pV@_z>N_z++lago$VU9iMpZ6ZyTXb|FlYFMjp&eCRb#$xm40|Bv- zE=S-M*|%>WJ9g|KC>wN!RMoro@8hu(J2^ZzOD2;gJ({CjE)xU+YhH;W0j8OyqWW-5 zkH=q>;|D>Nv*t`Nhbb){rz$OqGc$AnSs9AEeU}=7M%YmFqNy87LARAc5V`h&B_&`} z3f=6g_#_;{rg@lE7dkCLhm**c+qRW$lUkdNaK!Qg7Tp(7_clVuERgwbOZUJ6oq;C+xG!QpV8h4lKB~?oh1z{ z8-Ly+)1nqk&S-7sQZ2;n&&1Zo2~sk7UnrXbpnBRgMhY!T7P5`l_CAUlNt;q(Qn zTNpFZzr{?)eyCBSg#L}_4!>Rw0zBmrgeOPTi1iqPWEe^uO;nWH2)wliMz=4$t<6d@ z2Ko~r1*|2K8elf`gh`vnr05VbOuf;7bwfxRD1?;A@V#ZfjVV$DfL{ZpYDlzXqN)^@ zZIMZ(SXo+%&&Sx!a?^rdr+&#$ucgnyy7F-+m%#3if6r{HmuyM`+RfLk)aVx}4o}Zw z+crHz62IoNTyR1_!QTiBoCb(I*-@}CQ((mI=VKqcfddB)>F3;a$hKLJC*v+F6o@8b z@$s4QVB3+Gs5oyXTd|W%Htdd~dav7|){ z0|PaX;UB;I1^S0ac+Bogx#~GDSAj#d7_J!7Lq03rQ|obbkF%DB>eRU zKERj1@_7b|_jAQFFTs?8ic;h<8E(F@jPEISKkkV<>lGisb$yN&mQYF}rHSJ&;V2*5 z?%hBSN~jYDn?29?6kV9juh}BqnNj=1V2|O_NfWUKWlv8$ z0-XNEy(@03DV^-3<_- zex=F!+SQG=&Vq^8rZ{<#eLC$)yT#{!t(Q3EL?#hWNKb}Zo@q|ViKjI6HXcVkv`5_V zp6b*aVHdhNsfP}JmTi%cnpWdD&S?_r|KoQtj^mHR!@ z#{|Fq+b`s^ANw|MdfR>6{N6v}gU|gR9KQ7k!S)oUKaFqg#B&|2yv=06Wx|G``ALrb z$yJ>7`WvC7c-E|7Acpuq;6hb6JL8m?-Z8;uW zk)Eo-?YCPj-EtR`)#JSFJ#XPN?|T*3yySVj^ArET+WZXJ{vmF=^-eB(>g8CuL2kI= zquhS`?OcBOQ@QfWy)*Ztw| zv2*8k^7%afdiw#sb>oc`j{cB?cRs*5XT29jTt>~~C?(hy7V}+UBbXLZmJWDsjTHh? zmYyPIr9~5{t8m@6*hG`Sn@lNw3~kDeLpRdbV|8pQEw@d z)R_T?ny#V3U}q5r%x*?v&twYv=u*F6-MNT30ztcI5nBqMsDau_`Bw4y8`F4%cv#bv zrZ}_fTNjFj=?bIcLrl-iL#YhgJQ~U;Eyg+K8#F}&Gyhl;E=(V|8*ss&096Jg+r=XP z^r@Hd%qM<{YN>-i{ld-c+ItCVJ*gzq`}dQO4hxRMQD;Ddz=mXTY8h7*xMTkz zFir3lspH{R6g_^1l3D}|JRc5EPm)BTl*FB0VsISZ_Gj1f4?p-W*F5`a6bc7PtOaxg zP+AU1r~9;ZaM(!1=V;p$qsK5p%j0!QRx`f00o}sbK#z}{`(iP@q0f%!dzywor~nlx z8r3T1;Gmwqgqjz_FbG)BVrifB#1&OIy@}W$@$?y;zZ50Zcf|mhreg`QG4Cq^-A*NQ zifG8|8Wprgg{{232OVG}LSboS0oaYsO}XdL0}N$yn5G#{Rs=)YLFP*fy1Nchil&hb$9CGHxEVTt zC<2*PejAo+?1TT*f+9KJW-Hg^nQ`Gcf8L$1duu6WJf~5y5nlS zi!UC+TKJDVQL*B1%}yy%j?e7W44u+qe0&^d<{sYrhRf+29_4Wpy|}JV#hD?uX9xFH z7U`81C12a{dW8bx<2&i{9Sj7ffS-Ntb$s>5xAC~`L)<%~GaZuo2_9H#@QJtl8ejZB zCEoe7GOrwOVN@z81r=Y>Ygw%MjniJz%H$F^T=OjUontd1C4=K*xbr1;pLH&mT>T6l zCr$2o-~pcd+!yh(mtDt!1BdC95;LFYz|1s;k>&+2cqVUs$DeTPt#@LYCg+`Z9?yTt z^Eh&34&V2gJ~quIm+U1yFv!_w53^h-@acd35eWs`E9W!+MykZCk8_YbE;JC!%=$Dw`E;M{a3dgda^; zG}UC)tzg*ws5U^P9UN&2tvTJeM=4OEZEsPVinxa~=sE4H=odIUe+kQlgY4clt~FoE zq*QC*PS23eYdYld!XzDHn7f<-F5J1Bk%kW<10%!Kk1cS;ZkFY#SR3ZHPBgwlt+Hh{<*lI1mJi zm1y@@!KV5!h$kzFO-*MIsCfDkMBfuq%)GX#jS^j;kLxF6V>4?Q2m;n< zA%YGR0Ucp9L!`G@cgfn!1W+eA%ht~;6>3d7W9pYd)A#8R65k6){fZ4%!m026Am>t9_ypr$-ABbIaPBj)$@_ zM%e`QO&d{GTCsCM&g!KLxb@Z_^S7V;7+-$RYpA(p%995WN--$=2ryVBP5p7*?%*S+~O?AdcQ_f0P0IF(Rz z?`sz1CJj+ngwhK^GPXZGG4-n+C9Fr?`{qK+a~UEl zU(B-ShWtv80Rjvw#r=*$Q`#i`j(B5{QqokdP3vzX+EEwkBwhZQTYR3XS*h_~<8^YU zG|{%ntF{JRobib-#EHLu1C>K<=T4@kW;k;E zII9HV{ZyPgo~K$Zv!WEwdeW1)=%PzW$RtWBzW&88#(PpepGPSbqp5qIu$Rl8dO1=` z4$a@jns*L`gNi{b&#zy-M)!D%^F@`J=?2SEgGmt@+G#;b1vHgQT`5E;rth|rNU8OW zC0{3k3t_V6d$ce~`X&QXf`TRG&?Q^cap@OU=wzphm^B1S2x>y&34!?txru9`Gh!D| zC@hh)dPA%H^|k-2(xaUC*$=IV!-1_d!z1WhCFvoNDo!ci#-VU&0+_nVb955HDBWd{t{c@by$%9zdb_j!>m2zl` z0LwZHR2|BSrU>Yp8Q$xahUhT55CWOp3|cq+gP6o%13Q=5qqU?2<;PVlTYTkg#hmD8UM z5s20lExM4HelIoQ(dtdnXRhhVm$|-P8$w%ROCiWA$=PE=yzm)M;rNkTdBbnLfI%71 z>3i6ZJ)eqGBxN-yx(%*+(tqdQ_8;Y{iyp%@uX`82`-azZ=b;7CVr$LQY&(MM;n&*1 zilLz)zWIai@TzOB;V)nH-+1<==aP{vx|Kqy3cg>!k}b}E_Jw$v46pzFE6AVyWIp@# zo9QYLI*o}qGK6@3Wjy3ss^~goEh}ysJEhP%OQ5@LjFMDJ(VfY(6$XO3jxyr}ljkk4 zLsuKh8QI>6WNSlV*c3K1+=CS7aM46RH~i7dID7aO-v82Pu~IlhU8M0;7foqkS&}v1 z!%(374wlt8QktYJs7?Nq&%f*hlxp_FgQ}0BqDwqhJiIG2!dsn zf@MrI&5BAB1W+rLFw-WDFoCU7)b^hJxeU-^c6N%<(FscB5{;^d$c?i9p8Xg`8rhen zYhW7}Kj~?#2|XQZReW+2V=N-Tap`3oq5Rm%MF>xu<@hePoe#si^u51y@A-W9rXMjr zKCx*5pSU@R8XV0tZP7#v?bg3f&`|onQPEs~*r?;b7izCg@;OdT(eiy2TXOrpPtLNb zvmPLMvI*itDO65=AgDHEbp4s>46pq?sWEE%Qn!%U>DKU4h* zuKS}q_3D%sfn$&siy(cLR6j@y-u-s-ntojNQc3FFv0y{iKJNf95_2 zehI^hzkl&#c*%B)qpm_)T3@o3&*S*>Jo{yfc;yGd_#xQ~ZT{e*t9j>N{xg{8aM*LX zs=NX>evsDtUV~E@Wp;TyQ5!S{;)Ku6 z$!Ne^8y9sN#)e=5pM;;mB?V8}3ICSi#UK3z-~ReVY?CRns-MpO?L6~!cL7hL$2`W0 zWpTF@VBUi>@C=$_8@-bSe)76)Jmq)437IG9X~?4Dm{9aty=0V2k6mKYQNURcEaD1_ zDdn?mXD@IMcsBPsXLEl3FsARro#(>fZA|Pe5;!h7JI|`?Bb1;w1XC@`rg-=`{TDr% z#G260iIIk?r_b=TNww-B(|Tf2URXe+(+p>`tP-F+j|9*o(gdnXpgar$ng*z#gQn4n zsaMf#B>GwqsJ8It^|bj^Xm@NGQ9z@nxTk=o=aJ27kk&NK(CkN%AOHi_JT1x>;Y6nA z|7Y*r}j&6Gi#DrGs*9dwP!MED=knIe_!_N zHLtX3JDu#k*0Y}H^L(DqCtyq|LwOhtMCfsQ%ktKxVfu`hGYTQeXwzkh?1OZ@4*|ku zr=tj2wwF7DuMkCLyC7?PUn5v_>9q`t84M#)%1=Y1gRGK#`h@v>>#7g4YW-iSwp(yi zh8jJB*6S!RA1PxblUtY_-^!ieIfbA6;(9K){}24)!3TM2Z7+4wPth|<&UwH?L`VXz zA}Te?wrF>92qBmm3-OcBFXxZHxsB(3`Uyt+UGnUpSM?&q5F;``H8o5Wja0b-{7#zh zUHBoA$$pNBSMi6nNwz5nVd2wmxieJis3=h>L}2D(29)vuG?$WRobc2*%N^em#ZH$L zK6OR$qYd?|X1A76m6xiC{g8B743nfzH&J7`-1YMnJpbHpIpOk;vUT+qMns-LHNfnH z-bqnPWJn@Jn5eWVsw!Suc@M*6*pb{qlO3fy*~QI2{xnVT1cRfatlrSWuu|qg@dj>v z7411Q8zFW zFzRe4o9rTyn8Fu7dj;QJc@7(sDQs!ss6oc-O1%1OtVkK3xcRj4V7ctSuco6T$+m6V z5JE6@Y7^bv4oyvQ)~#Dd<-k`d;Fqd*5HvM4vAw^Wsm_52A*rz>K>{e1Wf)D}v{@BA zeN8lKktU zsgV{14a!MVEwePWwlI*3Gwq_kKwkmKbA26fj0Hct8>Y{Md^eEbtSg^F{@}w*7u&G3 zW&(nEZ6p8rx!;iOZ-B`H@=Xjp80Aa%{vDBHMf3RKH~tP=BmC^~0Zv$2O|SC= zGi5zBNK)FR7Ws-@`D*DW;~ILNn{sKWwaDk8p&`n`w;xJtd?rBz*Ijo#cm3%vL?- zttbl@9fa%Z@*u7d2Gz6Tjov}pQC6XRMj3Ut@%ZIO zbJV@p0dslpQGbF97xR8M%I){u4$-;5BV7Nz_ac-_y(8(*3gnkP<#ENSt+i%#XP z?>`F-b0MIxYHM-V_fSv}N`%cE)4*n!ZIMt_^r|pHrCEOdGJbpK8a{gFcR1rKALmbh zeir&VAUw$7^XD<@uBWTLhq}guaeh~d5sYfxJKk{=n>vhNSs*Zxo%sxrNQ3~8${1zP z;S7W$aNweaY}vAfRMt$Og~Jha-bexG2Tj*3msjJXG>|eE9&Q zkpLnPrn*{C6ajLoP#!k-d0jmzO#u_qRn%FM0ndoIk^wUg$kS=6r6wMavm==%B1Re3 ziYlQ9Mnf>Y39Sb`&pz9uyDR3l)FP|u`NpLuGrfM4es>GC_9R@lidcLhd6nhRcfOmp zwr;j1pP|W)l1bLHeY3+!Cm+mn>(iWb+;RN)z6WW0aSN6eV#Mo8n4C!C7lMA*C8td1 zXl8RQU%KpkoK;V7?N>fY-{y^E)c`ei1J!Z{L92mqK;p}53TluY$u2A_%BGG-X^J1h z4d49&ht7+$Dmlv54Ji-os{kA-07b2<$m%@JwoQ%J6$aKOpRjh3W!~H6-xb9O0vV5< zvp+7&ijj8PfCRG}n>qKt4(6sGT)=Y=KgZOm7JqklaM8!V#_e}M$?W-uGJU~Pqf&q* zpU#n3yqMLG-HTEWktc&+X6fm8iK{<;Jm2{IWnBE(Z`0A)!EhPwk{+F^z%ZHxEiIgM z@Jzn`KNqll{U)ZyXYkUtb)0{}m$~iUr%5CZQ# z9R2PSS@h0j>~x%0M1`D`LzQJS`?NXiOu1!hpH*ulT73l&eu2sIiJU^CIi&Bd1ZS5>sycoxEJj7q~*7aIwZ5|aA zye^;DLiQxO0d_hms^weSX#eU&ZkR0HS`);gQ3lA$KKh99>F+;b;`o6Y>MiIN@bHVU zz~=muC-RX6i}=#5T|A^0amv^3B7f`q*}7o^mWKXL_~VK+92n;D?;j5cj{4kI*jnJK zb0=}lS<~3=NfT3TC*D{G(NGf+Qawv z7JuGMb5U=;IW4m`3f}os@;QTK(&0U)z89s&3}by2rhUVVpM`j%uA+df%;O-42|vZQ z$9U-W4{_>e{!Avn2yR=;?OP<&H9>S6r+(pW9GVzr0)m++`Uf@>Wgb#aWT#Vw!sXIa z59O{$R>F&aFrsIoEV`7L3KF5&b*l$+1B1mBod*nF3S40PFk9q*}AnI%L<#KCosN? zo%i;Nu}CO=Gmn$WAOaC06AcYNlgZ-C2MFY=Nayp62u**_0FlT099l>Gsi%M zIb`Lpd-^ksRA(q^2nbmQvrXb`hR%07DJCTvab1@m{OtRjdFI*U_Q$T&upj{@NWt@K zR?=e6M9NyKgr-^wMpO>AY=cAR-~aR{2tl4MXMkx39l_fc z9Lu`4G`<4d_slxx&YZ=fIWyUr+C~tUoZF6YQ@msT96B~V&#gCphl?)y3~SeJp&V8{G*U^7OpGkPp9$KW{FvO ztQlQwS-*~ni6~MGvw8Ije)Zjt@xh}H=J)rlVq;IIiG>wi6zKt&QdUtQ&tIQeK_byo zE(S|`+HsQQf@+@%l~N$q8mcR}ok4VkeBo=q`rIBYD}n2}+;;s6&iP<7UF#fXO`VM6 zwDG}@|0f^5=yI<9%CDK$y4bi;YK#+RZ3qZ)&~axokaNj&|D8;-6CvQ;ie5_iy`@*@F3LEf8*1IP2>*XPrDe}FuknktB+)$V>9h%+LPZ4paSn^Q;5te{n5; z{7fUEt2*GhZKP5KYAiEPxY_N6*)|*yXKpMDWTD=HmpV9j-rLEiULc%opmts()aAV; zC79qg5fDu{!l-8L+VR~rfj6jH0F`sGY9-ZDQXLMH&uboeeaMjXc(bFLou`FEAWtrVUZeT6;uO2xsOs*mz2iJ&CfifF@!F3QZp^buj-ph6iLI@4Igjx8^{23UZII_*XeXKoape4?7;@J$ zEndq`2Ucy^z{F;g3lz0x_WTxRPn*L@?>mX}-hU3CxcsxItYS)i6FZc#2?&TVwr%`w zvP$#o-`vE9KJ-yWgdjKQ5)MmhER!JHwoQG##Sl=;xx!WYBe);IT$_C`H&Cx*kGPt<9b- z3Osg(^tx|7yF`Q}>2#LYmXt;X>#3D%`QI;pg|p8-d;D7VmQ=-oaTdIhqkMNHk$l6r(Vu36$$8x(epDOyTK!e#Er8G;f;|N9zH)oIHyUKbd49 z%q@33!aLr1I*GOMpbot@8c*BuWaWsrqaB_YD3oho#)pAVnAi1V)gG8bQXA;aXU zCPbaIaNVRgmr_MR8oBgE^O~9ajs(B@?x)eowIq`R#N#al=N!kDR29CSG_&U|rDbs= zsZ$DHIJfHXV$!ZYz`I1ZKuYIG}!rJMX-Q!nuzinx{!$j;V}{pWe-IrJpcEX^(#jWp^kFW) z)F$BMahw5K=P%;MAN`KwkN+SC%v*}94FB9yHbyIj(h^HbjymOhzInxcESTBC&SV#z zZO?M%d#15s#Zx2_&6K!rV`#8of^G4eZ`{a*?|&P;ZL6sgvuK_PGWNupF!)0>J=Aw_CLxW|rwWp(8ENMMn!mZYOzaM`23uU#ByyF@QPgLR#I#>Zo zBrKTH+-Qa^+t#phe*+x<(AvI{wvoo zZO%blbkRjjpECznD^HO{VhQL?cJPC5evxEPk{YE5)=GSiQ4CReg8)Q?V1keoD>^vU z!oP>)MwF3D^Kq1iwn=XoQ|;nz{?_$clZJ<%e2j$)7bB%KD728+cFYXGzEz~W2@vPq zQT}0J4sEh#rmNlplw!`*1Pr{$WXtULsd1yChwDH?l%jGy;Y^oA^9;}qJgE8MvI7}W zMR>UY;U>4C5c2MJ^j7RnR5`3=fH&vnHG=p{&UabhHu}*I z(Lo_D8B$I3DwhV~P@Q~&^A{h)NJoLD#SKWAWo5@oe7c?@350|Z@iNU;)XdGPFw&}} zMi+3C?M#i=qU=0HrP;E6Gg8_fr6zz7ip8xq8NH2l&U#{ECPQs0rpBWblk0hR%R&}6 zP9i5Zk(Gn|HvcUamSs^o;{moC!fs1`3tG`x~4mlX;W0?#?E+m&>F7veS(bO7opN5ex63!C_*Ky|^;+1z{SarR6y<^Yo%yF|h|XnH zbR%Um!@yr3c$w2qJjW{zAd@l<@I~byrI9K$1BVuik9;r5q#2b>BB6R0W+GYw!98Kpx?NzV|bJyF9}II)JegR>tHc9UsO{T z3)J4POHzKCVph@H(ZPg(U_!wBU7ywjYb6J_w%~Sd;O@I`mM{_Lo=j$bEm{ z;tMaNwPhYsSQHf$6$oVcC56S?moDXoA6`f2_APw*>d$h+x4*=P&OU>YoWlVvjnst% zJGF}y6|7&s20Lbv&AKQrz-Xu!r#X}=l#?9C3qX#OdMk^4 z4Tz}ll>dU5xbU$HF5t;0S72EZ+m0Kws^Xw|>-yJTCGRB@ixfo}0-{u>(#)DAAYjpO z@$Z@St3Iyy#R`}_hpxZ&@RP^3;9&9L8#6FyfdIQDhU>N=T!$6}%Z@x80!@7Ji+|&P zK7S8nyCFIXo9dZ)>R*VQ`3MjH+6Q$upI*|8Uv-0>B~1rfyA|>AAFmV33gI|ubU~qV ziph2(gM$ME2~g?rRU<9VJo8MlS>um1G^ogUX2m5HsHsyEghC-^w6yT^pa0wlj<^Nf zL1i4E5sZjYY`dOko_U6e@fhcvv7CGU@<$$f>~YgQbX|fNXXf#a)p{>`NWa4G|Njvi z{xyZTp^TJ#Rw@%prF2Cc+LK4w8-E3mXzd_GKQ7xSNI{oVMOZZ;Itn;ep4B?Ziev#P z7g1%!@L7=2F1CPCw~EPjoPx~L=eFU~+nAN8CGVv1=_r;JLQ1P*R>$%Z{Uk-@GG9uj z05h!wA#F3{hUw@?0fGTlMNzqBfT^UcR08yhN)tpgDG_HFb1&UNm%g;ifKnur$?{oT zracxk?>_z{biovdnS!D&Bsp~cJRB#<9e4be&t7u{zrE=vTyxD;JonsleDj;varDtg z)7aQdEEc1=xtZ41R$5wG_~3aLa?4G(@bap^bImnZv3m9MeDb3g@be%3h#(p%jTc`= z8}QK`bf^vs+_Zz6cFR6H8Li0_G{v0xIfl|Eo(R7*G%O)-oHScEY$TaX;<{;)$sRJ^ z{6wFdreuDuRE{nuMQ5j>HfcTHc)0R44D9Gh;W!Q%UBGqSvS3AhEM_Qw-5vD14z?ZR z$p;_jsKdaQ&k`VlQdRV-0MD*Za{eV(gD|5DwU#8OT!Kh?RgOhRAHuvv%Xxlvkq*^I zQ4V9<2Xo3h7qQ~L-w}(|mKilgrOHA8Qu=9%)$-%(zQD=HznzFM^td50iCz_9*|PHq zg&I9|RD}?VL8TZ5nwy)MK4&qLrk=pYq|1QLQg6*qQS4lAj(XqsnSW0~$w;kvoq^Yxj0`A;kdCuy?G9$QRx_}z zA0Yx{M25e;upO&m3V~S6`vjUu%y2M+!h(|Th&Jj9EiH>^d-|``#wD)11IY8liVf5? z#!&4k?_jC&EfGD6pqhf zBpjy8=_4MWPXD^+h=@_vwdashl*~C_^Hn+U=No5UXOs{|gh4k1rj6<5T#8DY@0GQ< zK?%z3?_qDzXfM!LhhLNFyp`8lHgtf};r7<`S`uKh@4EU2 za9u;)6G9@TWXLrpgSK7!s@k`&t^4y80_KObU1M+$P@a`#z}5};t) zwLpN5&Lo>UI?3m&sIfv^c*eO5rPCx@ThYLR1q;BFCpL$jpPl(E2h5nudFP#H;<1KV z^IAa*a)Se9{{XEERD~kUO3dWw^On=o(?cxQ2pUAL!1nFisj0Py#~ZzwJN>3g*#F<{ z7#bJt(z=lz1<0%cBkD0G0Ac{&Kp?+pYh%7kZ~V+nhjg)|&4}X=B7ml!T4@uuYH^$b zwbU{oG)mOtQ<5Ot7?z3=5vIy9DyOdN;<#xn%R&kmaut29%cMjjeQpYOB>fIP-DdbNtfedSu+`tc~nozB>SG{#srbarwbIlg52l2>_|Guu*9-$ z`qB=?tfryf#vODC21L0S9LOpr+qOZ&!;*dx()^+Smr@86YoB80Gr}EkVz7`P>*fE=8&U}75WM*4y zq83sZK%pc)RIJ#q8Es^^ODq5(pr}lKS7Vt1rsUQ>(aUdK*JWbd6o$PWJy^E28+cq< z5EqsC+S<}ga>EYlWQbvmEk-t%f-MdlYEy4nfS>1{e1h|qpFn4F3)L#f#Kbh7UER$| zAN>+JVdTprUhX+b8bP6Y%g-=^rAv>)S@#0T0jhL?jY&o8;ipj77}~9{kCr@Fw8m=oGbuTrjjQjZS8b-K zrxLaV=f3|aet+}reDJehhO~Fjg0cQ>-QAX(OvG9PN6%Xk&5}^iV7z zOc5X~Ga#>(rpAghkkvHlYGa-im$>2~^=AqC-Z0Lu!I>+pP3UdJ_3 zK~XB9*d=#SUC@jmkRi(}`ZO6Jf}p0>GK1@4Oyw-Mi{xq!GYGBoAcdLz8AdQEW;4OI zS@Fy>-0}14x$mL-sPz<`B3{v0R3L?9Sd7WRmXItVt#TmHS|b}9aorp>mT_i2<&-l> zr3Se8;*W6bDW~w{NI+<+8Dx^5yy7rxFF+MTd={RV>vTTY<;d=ff4N@}TsWrWEMao;(-mYpXDLMg0 z^&kjEm1QFc(cjj_96P|vzdMAXYY>!IJRe38LeSBfM1~}jZJQ-a7IWi`zhK29Pf*M%F1hkDT3cJW<<5JE z)-^DUCf*cB>jH_T?%nqQFFD(MFDj#zfgn)3$5bn(QDZqBKg2J}36pA_~Q?H^Ct>vnSye}Q~lF=&#}F_;sF_; zK{KH?#3dJ9#3dJ9$Y~$FjEOSJ1s9ynrnG|$kAa$Xa!fhO7%!G=H9SyNDXMEtm$XX= z>SU#+GxNeFOFG!S6cyai-5jH&{b*Uc>|O^tLwC5$0#ERRxK$#(mY2TjLj z4O;gQZ>s0zwss~Z<}u{-Fxj?D2idX_!eZ0f7ipSYhwJuHtp|gg47LU)piDwYe;ps5|SZAu0YA(a|e`x<7z19@})*V z(2I!GUXH%cs$aUIJzsh=4b)hYcPv@L=PtXFqm~`#anw^~#UIy`ejO2#5l>GLOGtJ-Yn!m7#O?h!n+qG3Ri(Pb<@@5T!X3g%y<~ z2VHytK~1ee7pBE)x$Wj3^4ACM<+)Wak5#YZrqoLnZAEpv3!gAp8YTk6!5l~Fu(;)x zJ2>-KcX7-ib9wx!N7&SvB%{L!&*V(!T?j}50WW=w-X=rxDD>{eV068&e z)J)te{8S;WQTmk&SmlAXQU53-UXdT%!#a86ilSFWZA<8G(L;anVyo+_GVlAfJzw+v zJ_ecM$+>S=E*6q{G(!TqaG0y$*Izh{0p&6?m16CN4P18W48D2ZIsEd$mpK1~1F7yw z)2`N&m6E&@#3ciuYqD{001BWNklHQ@`S$2P?*s_vEl$ibZ43;~#@6Bjp%f>CN)`oBGO_+X@_MrjpSq%)zZX3 zAq2HD52_!eO;$>3Nf^N-4HC%&dlnm?e-d{vMo|qAwCb1^PvCa8F=a+88GDp&?GO?c zeg(spCat1Osh32=BqqoR9qtB@^9aXf#ay?p5DpOtBpI*K5F}0_x{&sDk1_S29qe?I zG}XVCRM(wE1Y|=H@KAv+Im&1{N0ns})Nc8CW-9#5D)SO4&8&)LS>CLfMo80a&;?~Y zs1W##5tg|TV+vpef(ZWi+H0|6@v^j7rK*V#ej-AeuForObcG#H5b?L*Y&V1TBXTEF zT2$q0$m?E`?HiDdjpYhVc`}4}iH%=15fqY#pZpEenk*)0iQ_1wHIe!ArjT|EXkDmi z^D9P##4iNl@Jza#E}Cdyx;=w!$v%P%^TMMWn7e!#MGTs6Zm28==n){O;h}qPMan_u z&R9Y!>0?NA12y;xAuKBoZq+}abm>=>1C0pEa~q`vV}{ivS__K)-2-m5hOR+}y0AoL z71d#ZU2g^toqiX~LlR5!zdMo+OO`C)1E-!uU7g^$Rjc0cWAfDH@8kZ&UpV53ckhx7_+>hN>eRESe9ACeNLJNtC4E547d)BGEPK<=yci; zR(zia@&1*Gpy@>BnA6(Ajvj{rWjej)P>DdS60+ml8loxw2cY@jmiYIPD(=?^^)chp-tD^OF+$#ut0_cbs@Wa&rMg>F<_BF z8Q7U}P$7f32EC-pshEU;{WE~#_6Y@#rMAVJ=#+aYEU6O&ySISE-MUHV{!?f2V72Uj1%$p zbfn_5?P*W!x;H$?70}d4QO+-e2t=Y8fQaRpstSQm3u<*O0neG*3?_T=0b2Jn>MDFOv)7fE{|C!kRuBO)I)K)_ zROJOSEXe2qf=ocEEi_GTHE}bS^9*=LfE`Qcg{m35gve-3xweFtrA>v-xdZ`&)C*?m(UWWPi zzk(HA(h@DI)WNJ&DH}tW$G*NkF`cmi_tO8hr`Ice=HNg0-uOQgdwIRSt2C5cRAx5A z_?Bss$)0`g*0i;?Gh;>zlM;<(#Um+=lim%PM14T zGGt~(Wmqs#j?Ix4bDFKm4x|+LLINrMoN>l`*|B3sxk#xLS1EnnA3%~6W`D+FF~0MI z?{fKnT}gxI%cim}BZ0B?rnNSCM5!}S(B(mUrE&}?V-{Lc9UJ%uFIDl!8_ z(&ss>t6l!CQi?(4y?@TU=-LKR3y>%cFKyb!NT3eO3gf!#nQqsU>2`R2#orAR2jLm5 zYy3i&?_p87WK%t)y1UrAbqhWXuB(YRwGa>iro|iS?dU~H+lzyOjCS#9Ng`phaoZpn zoh25R2r-c%cOzL(ECDT$LL!BvS{Q16Q7bfx2sVFw;D6CtQSgLJq?|;kb{L-ym+y5z zh+SA5dsAK2<8qWzhqNR&FN8$+E0`BbDFOlE4QA^K6d{e1a>~e431t}`_d)hPN$$GJ zQ)YlO&io`BlP(*RE2**kB*G26?T{uOy7w;b`uX>XAUx_1^>d*1Fl`GMD zEQr04*N`&pzf;aUlM~-{JYWC%mx=f_lcIKcfeIn0@eY;OuGk`WL66=De)8BG7T>`4 z-k(%2;n8-RyoODzrNidWv~1GR(7p)8T=@OEUv%fDVY2&5Sw}YcOPPsbT~B8 zLQQ*$bCWz#akb~KB&DCA_Y7>?rol1@sn4U>j)*aELiRNZ}8qa7?mAhu8 z7-AS5reGNwS7-_vq82;*U1rQ^=E6^WjP>i+m#qLQmBjYDf0@^9mr}BL@nYV8${GCr z_rFIe2fN<(av`zX*<4dGZ(Q2XK3yQ=%}zUhXfmihNoV5u%(_4_7FVR-SXd z(tOHv3$*EMq|*gXIrqc-`Qc}oU{9vr8X?{!k>Ly**E~`N1WSNG@GF_fnEJSyg!WWffb)K+@5}=oK zTN^{^9IndYszUjROKDNFCID*kMPO?^8Cb${RkL zHd5HTO6TvXSQ+uw;IIb3q(m3S{$W|3xTws6&3Nq}+m4NsS`$K!o53gzA??dX znHZ0=Y3+7C{PF+fmOnhog2T?nbqA1AFf!Q5T{nM^2mW{~U;g~XWKx~@v?3xjLG9At z-p>DCb1^=>nucf$pRQtyvl=WQPgdmf0S+Zm?!Y}cKyl3PW6uq-^$op9ni3IMTVrzGj z2{EJ6Ap)TD+C2C?)P*e;E?B^6r=P^>XP?2MdGko8)1Cz98{IlL>!hi+k)QqSXZ+$v z*O5px0vdNvl>FsDMJl1X0EE-LGkG-29)}@DN>+hLYgigj*jCn zE#An`e&`65=6*^YFO%?@4(!tptbv!>SoibOnWUd)yQ}DQI;fLz3Q3oP#9E%X{&*Oy z;-#)8hC0(USb}bAlnu!gY;fRhHW2|`P5?Ro4Ax1D=S7lHyOymRI{EFgi2!tBGl1Fa zQ-nrq<1sas5SevYCyhDW`VAX6@ucJTSlDV^AfpTA1hF))Qh5fMB+!pfS9w3PL3*Y1 zm-m0^y+(uq-y*_arqhfFJSvF4ye3P<(%9Y>Z?Zz;)fY;`o+p~tV+GjwJuP-yt0lXF z;6I^5y=wuoFY$5g@9J0V*6goyV8mO$rDV0s=_ykV_jVaoyBKw{mSHp_Vie1&MJdI^ zcx;zkY5x~tW=2k9Sr#3gon*A~3NEXBHVmT?{xMZ9UC_9LF18&v27-eoPR*X*!p%3| z%;_hbKx<1YLtbZQ*UrgUxBT^Q5aq>sqd={aFN=Q0 z{Y+*}`^T;6;42i%rI+jGJP=4#p%xRiTy8m$|+tZP^TTql^6tKhLejQv zW19hneNcfD`9-;+F>a9=tr_szoUU78J}9WDG6h2DT}&ePeARjCK&1e)__z=7zzZ9h zV^0O0<$#&f`S}mN!S&zy5o$lXC$Ch%F3zpmcMQ73JxtXa#f z83|*m6E!GGFd(pF77yL~2MU=CpS|o;2m!HJY&VzpH!87Lo+O|pEuMVxQOk+ zI~eLr?bewXsqpa_+0W?Ro3Z2ZhGVGSz9=DhLvD&Wb6Q!oegm@-&1L%3@Ei1VmjabB zkoDq7sf#8BuB$xLwgN>_atF35P^tpblkhySc^;WmiVewa%v{jQs`cCdE$+YTx)n0o z=7uykC)luI!#LHO*Zh3dAP6H<9MS=lPLlQ15}9l6(m61K}>Ly?NE_@wn z{7Mtj1+r40Re?HL%YgT@Ymd66wWhtjooXp|iBO_vkM5lUhV z1=9uaX4-<31jkH~E(BzhnPrR!SuRivNS8yE1sr4rl|;Si;==B^-@ZA+m+4=-eBKg* zUn<~?S+W<4UmHnakDqtnm$}$uOfQ-IR?^AFzPG=g&+b3$keenRkI~W5L(!Xcm_Kg; zLuum`vA4G`37DAqCqI^D@zA{wa@4Y;E2LRPIg{GoouV2`lI%&6Xl`bX-3mZQM<>Is zOP#b#A)8iajw>|A#*ksttyOro_a&%{-Nu9aPt{i6secIj@p z+;!J)S-yNZ_uY3dt2VTw^WK{9M0tb;{GRZOR%1Rq<@=jQ>i|9qAV$ZD9qqaVO0lEV z`3FNywk*5+zQe-MoBdkjqreE7DlN<`VqU=@goPg^6gv^PfjCy}fvjKiD}0tju!G@# zhXyOkw=O%MBTo7N4OSe>vUusmXL;n|dr0?hV0u%OgPImGGhx&3ZYR++g}a|<9V1Xl;t7l0mBLDtrXko-S~~rI+%#3*W(&AAT?SZjULYw=*=jnfva&3EQ5^oH+}r zu_UY3uBW|yJw4kt6Qh?^&p*zxlMlvq`hgJ=3lC#`*Wa1g+DvbI4~>?EWd$JI3qZKG z7Pm8H1RnPB8JEDeYALA(23!X_);boa0J7QaxYk|K^SF6^jmC#BYA~HC}xBb`DJVS++32WCpMqAVMdTQXxH8+=)T6U9>(^X!;wV0HcP3zm1^XQs1b&1JzC%c#*Kb)7J{sVuy z>FZ2jJ7*k!5X%-d(kOQ@y&dTyxbG6tkW~dtp3sQ1qARN9LK`e#aeLa{dR(28srO5a_%~QZK#q z}LJ*I~dGW;;sqqvPUms#x5)Tok zFhLN~iV1#TN*oXrbeP@_V@MVeb{Uu&a>MLQhYg21zYS0Xi8Dz{8f6~xn_2mkLvJp? z0ShLP>v)!9WSr@)rl?%%7cAh~2YMi!hlVT@FrTBS0tjI zzxPH_*&N4VPHQVWk}2-J_dY)Kp$mz}8_QI4txYa5j4tOALKxqYKi&H$y1O0Xjb?WC z@dqB@h8u36q!3&3Bq_a0Ib@|M#_PSxa>r7Xm7|V6dMWvQhLtN{G_z{~SmD>8n6__Suo&EdMnh`g<>ouB^nNBBHIf25p)jqR~g;a@E2 zGDq!lN3$#C@Y}ne;G#>v$bk#r#i*D_jjrOLdP#QMGkoTPlgK7lbI%>$<6GbQG%H`Y zllL4mhXZF>Okf8xJc{e~A!Qw*&=mf>VjHuU9!ExNqp~KAr9iMukbW-PFVA z%|`H9qX-e9!P@!%vG?xran*JH|8pkunPfgm=HzmcX3}PQNlQ~`3oTax5nMpAt{@;P z-bGerzv8O6x}vMDu8823{VJ~O3SLoREh->4MFA0z7TQu8+NAA-WYXqLlQT&^lbO$4 zet&$^c-p#}7ZzA3Q z1aUdRQY%YlY%eFAu$V?-#N$!wtPIY zDZIkMx4v~_)!LrEwt^LTvWhFOUk(&AOF5M$#_S<(6wOl7AOu_cdTF!;J5yh-JFWc*^C}<4@tUU;MwOiEGlMTjVM|M>REJUir#1 z%>8=F!;uK{ib9~YF?DK;wgQ@Kul*9A{p@FH?y#qos9(xS%HQ%OWdx-%DCIJdO7X~s zXIQ&-%@Lvgm4owQ6?b_;mmQ@Q+Y=*Pbm^OM9EWko@q1^=vXBizGO7%B`aSQtjIVwD zt8Cx01>27CQn$&e^?-~7qNc*?H=_mNlUEbFdgRF4>AfWKtw~m5QIbtgoJQC zw|xITdX~4c!k(l>1!z&wAVydm@8aLr?}RZ27U#%IO)VDPS~4FO&RGldSF_^ETX2+~hV4ixAHb-?o_$oYYW`I`0>Ddmiy1P`GrH`6wV5K=}6>Hr1LeYxyz zU*jb-+WTHZ84DfK`2TgUzdZOqlq6|NV!X+BN&{ z5mglxmv$@4lJw-8&Co562vrWm!DeH$Y3w zBv~h(c!JljIK6SXCJ)7oqNpk?n*X@|-}%jN?q(w8vV8e+Zoc{ZTy)VzKEPU2wWq&O zz^AT~!LO!8z4482qMwRx*?0>#^4JbuS2*xvMk6JkQ z9IuuXzxLlg?wh&VwvC&vXbK0*RD?3xWH@S}Sr<~asvKUPFhRdjsVe))2YhdmqA==M z4I)IVuo+7XkjSLDdDA2xziT1C-~AK?S&wBk(+IQ@=J?KInJ2rMCl)YIlt?>cELwdm z|MlPwo?;#UeADeb)Z0(9Hr^p6*QLSB%F3B*jSP9nT8@-qjl2*7_lEpuT)uz*ziR~$m4g1q#wAID=F2|lGO`2zA$b)37VuA zyl8rQdiccuc`MD4EN{8^?G%(nT7X6!p>WMKzACM}nylo!^Ui1MhDT|)jJNd^+V5r1 z9wKTeV5K<@ve{9|>VtOf1Ffb{69GGY8oo2bJX63RR?4c!B2S4bw&vRu4nmqHq z|MEZ~>zA-4d%X&zs4})XJb@Uqer;w|wwe;)x{4{+^?0db+BlS-pK)ZCfJAGTSDbqi zLRgqvSN_}Te868%+5IYD2LlaWh(NM3?nNO;B>K4L_YZRN$tOP#e~#xv@34*by%=Lm zjIc}F?Cb64kx$Quy)IY&WSDn;ca%gT<)!kq001BWNkl=&GKdqNu2Qm7CUUWToPyR2s{YelIGX z$jxl~>vUDWnY1n8orC!OSxPA{#t@7u#gK+!rO61%kk$+t#-b=}COu#>qBSMgrA7*GyaiD#qSUiUI5fI>gou;2#>mSNrra=6E}_xQ&@3fE z9VV!o2je$}Q6w3^aG8H>HoaBeM{)#ue?Gg$?@#v#> z@Q!y}Y?vfkke8B)s%HD@>XMit1N_&r7)-TQcs&mW9KPa;%h|MP6H?kZBj!v~LNl6i z2}aC4L=hB}5p$BVqB3c~3E?TOX8iv*KaeLQ4BFym|hL7A0s9 z8m(h&7*2EZ;{&|+D|b?BTh!%h30hq&=sAiN-HRAbJjx^Y{3p-tc!)Y{ie;x9#j;q2 z$Yd?p`*=<);2&?;z$bt79X4)!ngw)F>&<~5{pn9&+a$F{ghF1?LsZ37v%kvwNTY2r z=!{Wk8I{s0*QGg9VH|`Ggaj7<+8O381lM(m#bP9rj;BN3%DCeY)SCP6y@Q9pe;Z%B z;oq1)Kg63Zd<9AkGO35LVj*@qy$EqSf7tXCzuNr={^6=?=w5RgTekEP)Y@~)KKN!` za$Q=5AQtQ3!N;EE{r~!JMD&%M|Eg6Sw`MV?oYKhr&UWgAMRsx@W6DU;C6i<992#Qz z>W^~Q@BhpL5C4&X6(bhwV9*&Lq!bNyl$Y{V44cI^IXTJlo+Z?H<+R!(cn=jrzv?Df z$+sxHh4z;x7Hh?E+-V2Qi*FkD zd<`oPcSX*;MVTTbX1l+aa79fB{3`Te+goQKj?>HNl|&cdf{T~4{;r3(`M)0H=KE7- z?oMt6kpuED`X?^9bS1Ap^C-spHZb3gkxZnR7w;l9?DFgHzKZw%+b^ z_MC#1tNGBi^LWE)i%BFl(`;FQMPFZv1>M~^$zd8qr6K}(ilXEP8>ZqO@o0&*?>)7C z{p~ae$=bDReELePssdGB7gMe}$i8FVAy}1ol*g-@LN;?8g(#VO)d3I8sR+nu9iFv{ zXOzSy$&vwGR;~%KEZ)k5=XxC!V`MON+y)V1)XC5w+Q>4-sGGsIJ3wj#iY_TgCX>Ws zJ-9kaQ7f;%38r)aJJ!LVlcLeKVGcnCDJ8p-11yU#VN@v`CxzoUY}>YtbI&~!%d$x( zhmq3wqK!Lgy1SR~zW2Q!A>dP=|J*@oO0)T}R8u;RzT^*3?==*ClyR8a({d$TQ@#SLo80tQfTc`avfTwq!GpAz&=r; z$&OHqrZJIWzHJe;CfVoS!LYTOpz9jvZzchar32JD30B(ziyUK)gRr|PXh}$Q5=cd8 z5cR$y>0E4y2G1n7lHhtOpKjWpgXKT7S|9c;HH)UU%EzjD&)C1OR?GkaHSw-EKf3={ zTz%D5SkgMcvp;hCsgZZLX=n&@-SyY=o+~aVG0+DZnj;oEuc-}HJisbzxI|E!lf3AK zsFoE$t2|ky{p!C-s_}d2%EM*)KHMtl-RWW!#-MseT%Z+rqEtdOA%tS*K!SN)ao+X5 z%Xsp>5TE__w|MWnFM^TXXt4*S_OPUIiXYJ#Ik_S)nO;{lL3}4 zTR|Z`kZHxN#>!2o}X+>`4sx=3ED+Ul@M-wrv{;+a2^fE>c?Dy>*h_ z-d^th`NRD2i9S+;yAa_x3)*bjm#$##=_m8fwZ|~%^s-|(Mc8gdh!TU&0G1VDQYj24 zJoC~?OvL^Pr`DR$(NSJ~*2ypOy@_d#!6%$>A{#br;JA}t#a`|Djs3OL7CryJzqHo0 zTb75s576Dcgx}wDFU7E6?V2@zOP}Ng{q0#a5$_Do9yo*CZxej6uYxiY+dtC}BY%6g zXJ9HTmBaNHA6UvQtBSn&*H6Qc7kG=3p*766xb6dMc-`5{7*F-mXj_asF6~wmL9MA* z0p^QGdFc9AvNs*(@y!G5+%~|9o-SgsrL5fAue_HTx61DdfYJmJxGHJ9ilj}A*0`?2lv`q- z8=zSV>ST!tEyw^hLQzZD3+62>3x<_Tvy>>;R2S#lF}C+@U{NfNQZ7+6mIS3rUUfak zlJIQUikOKE! zLRVM&y}z7fn?$4@SQdj3*SJ0(V;esE(>qM^Q3>r~Qo{mal9zh#{}#o}&q+WEaDlcM zfmE7#@h;LtNG6795H9VOKr6+Rv{_+EvP?4WBxpln+i|9Z#ZK)~XWKMrhbExtDn!g? zw}OneS=impkeg&)auFqK2YbX5$e4|EI>{vh)Z6u>v@>V0u62N-H1|`PH)@tjN_ZL- zsa#!|`L(}h|D5?K4{d)mRiJH8JxNzr7nI%Gb;Wz{g}%zdI@RJoZP6&JR`u}Ho4?I_ zu6XD4%GR{x0fLl&aJuQRFYF=kD5{!D&&uq{cy;0;gqUSaXG;DHXfyOQHS7}derC@= zlJ;1f*lF+J6Q{j_FMs@ftXgQXYV{hV9;3u0Jw1zY(+V}InV^+DI?Urwr1+1!HZYNo z@I+#qrPl1@Rqi!wv~3cJJ}fInP?!qyup8i~_w}>>*4y~hSKrQgXTO$JYmY@`#+Vx0 zOZ(DArUhY4@mQbB(>oH}cI%@&xM_%uTlN_R&a{gVnxa>=+Ly_gb*`&r zpi-p*7@Wp*F$a98cE)L6TOm{&B-5VTjk$Wz9M>Tp?*?F3GQoU1M!RLRFPS84+dS0U zPkTJh2R{2*KoIusV^V{bFxa0ajgeWakx`^D$`zIso%7Hyr~pV!ORN>wO%t}wpMTnz zp_V2tdC$evMI+REe9gShGm$sS4v!~$X}4nZ_4O0BqbS#<&MM2LT5~1}NBXK||2`Qv z?XqXj9+oa$3R+X}5a^4_k4712+5;z2^z75mY48vwl+dLTwh> zR~7?!;ITV-+1gbMoc1aPQyG*B5Y(Dx8DX()G2$l43~XVKlVDlA2W>%C2^ys&t6U;Z zJ4KylBH73JYnPB+yNGcoO+-(ED@db=Xp35Gq=aELL|Epi(TXe*yhiu~Bcvf**YRmW zi9|o^fAK3CgrKi)fcjVmj^h|)H`YNiIgIesz? ztpf$>p306eXTy*(JvWWECg)_ZtOyO1$Y@1Im^H54ZA1tYkR>8+fae$^?x{7li8cyK zFpR^Jlh%++g{c!3jY4@8C{QZH@>mSlO)xQs@>QAIBCIGvEBg8dxbg$<5pHc|aCn#rt%=1XS;ax; z%An)WAT4UqguIH7ZO7O&;BvzGZ{pmG-^2qC{E`2B^ll1j0_bFNQUfKLnz~tY%DG(r z$v1QLH_h+Mr1E67OM@|7A>b(q*7#+o=bwaTtNK(7tET+S^ZwX}idBtD+D}5lUafVu zWMy`={6Oex)>C^aH|n=r#%!o41oPrC5{Uq{GDbl`!X0KpyGUs?@(U_MVZf%K^C$() zGHRNUltRj=QG%IcAnIdXjJl2~f1+tbQ!h$1%P6j!X3&|W!JV#DA%yfer;=ncMZ9}C zyORCB(nW)i1PP#2=71>HOCedQ1(HKaCMI*Hx#>knPKsiB*|yw6)X@=R)3ZayZ{P^{n^H19Tb#e+;I>h#J;4%SHE}-T5Gm$+v0Qi|F*8#oxTrywc>A};#N_l znt>3`X@>RJzNdMEe9yV;a2-O)exfK^grGr6GGdY;PaQ^Uh{d{@&_M zY4T)MV~jgS-Zw}mT6?_weHKSTn zXGJ|OxWcwAuQG4?RQme*iN#tE0ThuGDVgercczt_rX!l4njXF zf95*N@_K(_>`M;w(8CWCk1z4u$?>RP5n5svdmSTRu1o|6RaCjztEd$zTHztN)ywkN zKe?4_uK5E0`mdkn1OIphqm$-$o!HaEqt86U>1V%&FMjn}f-=M(e|Hbd;&CEEuyfmH zq-;C}T z9YZ(M7PJfAcHwe9e(_rD^bW?IZJe}Z4Z$0Cz^%VBl^Zd{Kfmuxu08KW2Dd!Myp=1t zY2%|@{mDPV$gwaw#2M?NeCGYf(4a>ccQRO3e9pBvbNtGNwL(02 zI$cgyDs-n)k3ZfdE*^c{AmK0WdEM01L?95tady+w(~ZiT`IrTQA$*&Pa^IrxSQ@oe zpVw4U#I$`OJ7W(i&JxpQy$z(+3#zgRB2@``7-Jl^_+yL?r)lnpl2KrJK3OAa*zKl~WN2@VQ5e`plZFZ8G~jM#g|%7Q-dZ+P zI4LB%l6?d$$v_&mBj`HwI98l<9HvYO4Z=ceK}IPG8H-K*X=)@WCPcs3n@{bImcJv-P@`M(Mipmv&ao0q7}OgIiJU7|`?+jY}eRs_qkab1^DrAQb2=qU_U z+9?DzqC&hVXs8iKW-~1F4$B-+DJ9Q6H&7*$S=j(YRgzoFOYbTk#=aS)TwFJUlo2e; zV%$lQNF=DUENr{uh^fQ;bxFzoeG;>tgNJSW#Uag$qImJ?UzNty>DA~L_OVtTKx1N< zM!>SV$x9>ooKksD3`Ef^O%rHV!GyOir44(XB(`m{PY)U<7}eN zDq&em$vF-s*D>gx5NK^t()C1zB#V1cP(>p=`C@3$#__wL@*bKSVN|6(R9B-^nr0cr zaZ+@5FYzle=E}|3gsXY@CSVWh07X&q!JM*+*v!qlY@AsXA<#L$zs0QAJeDP@sxX>@ zf~*DGhSU7~7n@;aC$GQYD4KP^jH#QUvAdO9e||qqYX12RZzUx1gslh#5#g!6Fdz8b zV=$TG!yj}h=}jzOc>%9{#kH{N1oK`w1@$(BEzg_b&z!yP??Ab;Bq!DLPvW{6-}9l- zZl%#~_50!)WCW%221VA|a~uz$RAvTa;oxkFvRFZJ#@x?{PQvZ0xc%-8y#9S3XMx>D zyJgYS(+vow(z{9ZZeZU~l6oN+ODGCn)gdD!y^iAX`|m^u!Jjv8z;V*-*s+7HTc741 z-*Y9Gf9OL9p;5z0>Z~}w+%V32zw~3E$*A7FW(n*F!>$ZJ`0~SS?MrdTCy%GKRq?W` zehAx}j6C;=tKccYm%ex>M~$VqaNVig)$elkKW~M}dN?Wq^H=eQJ2vym$M0hI?f*op z*vRM{1wFq`+a?&t| z=Xi}2pel4VBXS}=!2nIYYpf&8b2ocOi99tjZ0^g=dti@4tRu=`YM3B`T47NqZBjZ( zbiXmq9V9-Oxjv>>t;?0J24ASl`#%5S&p^Nrmn&`gjchwgP#fwOzkB6r{8=jfq+@+DXl1| z0PR)>%`%4LWN@4eQrfgz9UfZdB4vmvH%&q1Srl7BGMV!EjW0zcJ6I*dr?n;=4x*I% zqTEr?QLIm<_?&8A0!>a8G*wg`l-ds*UnpRpTp^B$FW({5QbOUa5QT{KJK%Re{EZWhJXvaD+*@%VD)+uaBuS%wK_0#&}Z=4|COrUeB3lFQMziR+hcy zWH@e>3BD&4r<{2T3#xj3v<}QjQq1R2DvkE4Q$d~g{2(fOuu>V1erEs#LHoYGucxPn zq7cO6U4DWc)OmtBFw1^i;gQeu!6{$!?GVo37C!dDckt}v_cG;f<%CtOw2CphtTFa& zx{IfOb2Ed_{F>yZU(o;HO$=@N1;bCQXUCs@Oz)=k)ae~eCO7bkwH>Tn7{PU)<)Vwu zTqp1O)i%ajBYfui+hBAx$Dh-~jvu|8+rM!<92JAH zW!&=1y%odfIp%onG{6GxTE8Bp(l6P)wje4#VKQPdHRk%NUV2&(EMJuSE8l}jo=Pl= z#r*6gSk*sbRBC5GyUU42LsdV8))j!FTwR&&Lp1$o4+%uw>wpkUDTPuQB2rLi8TCHX zw4b3yLOkAq>l%@%1_2GiSbLOxxJs@|mnA)wzzBI6B_k|fWadDZ@gjp7X^|0ViS zmESaJ?qAA!gb0yL4p+HMI|jLVJ`?vvKy)K55nN9pM`=yoD}UA;!8k5BgZdrRP$-p9 zDosIYwAXN4?okmhl}`FYu9W>{yt*1Gy(C!q)ke#*eMfWgH)ay^Lf&p!0(7?cGB+b} ztmUO4b20r;6ID&$`moIL137<}=gs57qETQ_YGDk}vU-w~h6X7qqFB%!Ln}p-)?E3{ zcha%2lW`3?7pAVMM2#L}WMqi8wl-{gAw$VL7hifM$z%)v^5JjMfB9Ojde4arZF`iW zFzR)K&Nk|74XW(`NSnDFXUtdInNXUE8GiO`j|!3Y2nk~x|tt5&<;pg6NRUrqM&RR$(J#f+|BzhJ&HyIC2 zt*w0cC)>I0@jhUTUw`49Og?-kS}x>ZtHJmZ1#sQ87nJ32UB?eRl~Nx4G*6L=Y;)2> zm1_yi8JK0sA*zDJY7e&V?p3_ztk=@tKfuYyo=8N8*)xzNIh5p*3)V3>l4s9YfVQ@I zXg$f;n4+z%$<(Se)Y|jeFpxnA!4nVllM#Y|bsUj}r?BAk6z{ua9h1Xpy1G{Jr3dyw zy`f@#`+di=eBgI%V<{0mzy+su@a~Jc;FezGaFW&CD`8ASli(F=8mU#AS;`_us>moMk_{F(1v`EKg^xA3whE1`1?p507J9EFq?=|hlsubxK*mFHVG-OO<(ucf%T)L9Uf7Gq+Byau%JB+FsS)hrM(l#`((N;FFg$4w9tiUOKZGdIGRCu;``EUvk9WWSeV&h^Ldr^C zadq4u5G5}`KeS%VGCi;Sh>KnvC_0qlsuuNGVSTUXT$bibBxuq&%Kl$jb!N)W{OeS`pEThz`&pEnkN{ z4diE-d(F0)Dpilxf@T>4#;9e4rB;YmAqc5}-^>=&VG1ftP}fsSz0W;VstF<57*&dl z&@|c+-w9gldaB90wl%;(Ik;V5Y>_?H$Yar@KqKeprBl@`c%>HFIRYs5tjDc$EClS3*XCUruH_T zKDU??F+XhL2DkfIuv~Bz_0S$I?!w8 z7?jJmS%3W*l)TPUHmmV`9F)rYUn}d@mw&D(gjfBveABK8JzX-hpj?iPbr_tWO%slU z07;WJUJB14J!#yzJW>AI@jJBftsu@beP<3O0Y32k9M~twyicpr)GLT0iDLPOQp7_K z8$^tcet9c_t`5HW&2P}Z@kuVdbRD31&n4?P+O|1u^{e^d2S34G>mT4>KJYP?cGqz0 zL*Jw?uc4`vQSVT15N%$Au!|6qfYanZud*M8>FWyvVK3lss`|U|f(DJ&V@N4zv|AbM zAHcF~q>PeGrjXL&i(kE-hE^M`^S<{%*=4;t2{CIZ?9Ho?x5moGk9t~AZ{9cHS0l7% zBx&{`)3<5nr1t+0+NfoWdD3MEtgDd)nX zAwKe{lVC6p^-Jj#&oIbt@)m{Jg#Z8`07*naR8lbDCV4`+;B4d1TlR3vilxS?VdBwSB@nl~gZEbA?^`tjH!Zd_SUaB=gN#tm3 zlT3}dG)F8VT5){bqOEO`sj&pdbS}hAKf`FmW-Q~d;hsBzPIy_IX6f=2D<}#`3dwl? zFx%H1$EI5@XTjMm?2e4EVv&ZhMcq4p!D}C`TsbNk#eF;0hb0JO1 z49{+9rv1|o!qxz^+x-2?MsiMg7SLek{we&uG7IEoh(|X(!s4Fgo)?fsQG}TAJl9Oj zRTfRidq8Y>+MasgSfbMVcBs^(1|g?O?bej3HW9DNkXLkfck|Fg8<4{C#Itmj^zRX< zq*n<#l)Zk?FtB4cc0&t4_`wfZ6zgCrt&kDR>>(+a4lgJ-m6pJMV^S8TC_KESh7iD0`Gk6ezYvn9wc}ZKJhhUozwSwiE@VammXZ zO`bWeW!Yqe0o7x%7_CCm=qld_sr<@_%6(;lQDx4JkkYhUAupCL%bhD4T}6{tfB}Vs z&_uLLqwCOyVoWH8mBZWLejXpa@_mHe46Pzc&e7CJ%k!%97&8J8Ii|Golb4{@)7S)f z?3s!`j`qzq!3dEAwO4^AgAg9OMoLLg=h&A_5{sE~|CF2d8}P~$l(IIzWktP3r4K0( zti_nOlmm`B%VJdJX|!Wi6Gw5%n#C;Zif~Lv#)M?RP19&cY3f=|ofRW&hX}y^$0uABEJxWYaHJ}QNfr$CW1NP%rzyy22JvU4cOXh!W<$*Qdi(6xrM&N`jR z$w{7kY9m5O#?$4}e~2U3^l#p0ba>bgtnPp4A!-6pJ>?k@>sU%c1B1M;9g_=`El!zA{a-`{gDo40K79qH?=2+3r^I~26nFm3y$kKg<8 zf3dZ%cbW-g*^8jIs$xKsMfmlvrLVV_QRUKV$8cRw>Qx;nQ`5hlE9j$E=D_{w@1Er6 zKl?2=|8gtyR~*mklTPE6>t02ZWz*N!M|XEO=fCbe=G!(O`N);L@)hTD|NVcUtIakN z?OKzoay>7oynm>djU1&6`9VQhDz`cSsLZ3BZ@gOmx9g^9Xtmjs81SmzM(%#qsqSw*aU2>vkWF|8y5kJfXh;3TWIClQJWHje%rh@}09FRaNqGuu^(KMI zO+wg#$=x&vNvDVbO^m59!%9I|gC1guZIMX~@a1>DpS!R9KfM1H%YZQ$b*6c3WD$hj z49zQ7a?y3)hx#`D?%WvN-Caz%^%&oeLjj9IJ`Gq`^^FE~!1p0DpC#jo)nt5{*G$2f za$;y~1`K7ayieCz7C*W5HiQs#cN^;1pp)XbQ(lhaI812Gb0ZEaquAEFjlRAeNGU1Q z*H7zF%#tIg159W`O|;u=9LHgCPdCq{T?z`G+_rP>vB( zebfRu$02OT=))z=ZaUoo77k>XC*#b2*To>}VX%!mKE2CSw!%Aj!^h5GlbgU5lJWio zL92yVUic}vvk%%=K+{5E%R3miwjR>CS5SJI)V1R{ULTI|_ro%^F6$+mMbB{5sJ58^ zZYE>paP;39^{5Uk%SPubV6)07zjxGXvXHXg1CZTms)8@{r9E$@G9VuGn)?e{F*vxB zfssA5)HgAz(pXVRnZgx}h&dJ6Ofq7UMAJ7byb5IA`;281;_!Yk)*+w$lcwraXIVH- z3L%UK%(mWsnmypXLs~T2QPX=ZB}!=;TRW(c7C9@z2%41E3@eS4Hi^VAdtGIGlnzpP z5<<{!NhY*QUgDpJX`s<=rA8VP)k$gjvg}2Vnm;K8DGfnw(;n?&Q||y7p=pXo7DeCL%sk1D`9S04x#9G;t z7@*yXA}z~DO9~2vl%C`I^9$1IEQ`V9Ft#meiFGjOHES+yjWUrM;0Is%SMI+3M~JYw z)#Hv`3qXD6F*Mo>dFy4Sv!LsF|5<-qCGo1o7vcD)B`Pzu-0VB3PD*Br&K zZo7qhzk4G`AKl6Pwh%B%#?_2Y*0N~zD_FPg9h6#I8Qs!r97sL1!#Ei$_PP#G58)TC zlU{h4XQ9f$e!=|t#!WRM$Y%7kawuL!XUh9pEY?M-RAP7U9tuj+7_~hF;mAmUm5q~> z(lmFp`kT-C^>^^0k6g8%`IPd^sVXWc2X5lb9*Js7)mxWK$JGe-{tNAIwXZ}x?`q$H zo=f$ZxUOQwl5XDh-T$Voy^Wi0{1&4g_+k1WD({y_448mQMp%FQU94KYnp(Q{8}p)9 zcGntM7$^6&Z*tO~KE}4xI6EGD7(Atu=>H2wJkKj3u5AA0^^p=5G%aK-Vlk3*`29nV zbLl%TW5YAgkQ;Hx=`n8l-p}Y-W>c8doO;^JNKS6Y8F5(9ZF!0|tq38=`-mRCD{;GJ z;W~!GXjxGvR0i9QdS+`;l;>J+ZZF_dKg&UJP(z&+#c>pMfb`TFZM${9AUf#Fx>8Aa zv}Rts1LbCD_j(!~C*@b`e1pdsd+7d@uX2(So;DXlDnN~GvDY1=wO+#H)6k@tay3(K z8X;}!WGj2zjQRcbg1)}ZEEkfv)=0IDMq$BN62e9fHmx-w6`)qYJR!KJKLsQ8@Z4^$ z`Sx4cxorb=)(Q&lCJ@%F_gekjg|Bj^J)kJ!DWT=75aNti(K0lV8X2NN3noxiL7MiS zP3636_nu)8qaK#Yrr5Z#mkk>>vTD^D_PS{veCW3C)kQL(b-aXv+`QJl*C!E^FS5`0O!~b&~>=j(N?iaXs zyp~P9j}lV>igt!;fA~2bo0Q!4-CF_471!R+&F`pX(3x#NoUVpe@YJEoA|OgB3K;6; zsOOw6Ji1I!2h36sC9j%CRez^vEilbh{;vZqVzE}vTlZS#wYT$?FI)$}c-mopYmC8E z5)CZsigV}x{1m0%hGm&`Q{>3lF$km=11o=J8h}EhbDCl?&&uOhrRVJW?EC!dhxH;ie?!DVdRQ!+a?P*PLdjF zv8dG|YK15$Mc$iRjUvi~&a+TP*xLIXv6w{`MOtfWBwjC~L%nI9AxuIhsXTX?{5P~W2v*)1F6tu>&qRi`x)7RgJ zWm%Nf3X5fAKpSq~+&bc>yqH#scB_@NXNGnB%H?EKhL2o+9-ANfEf<}8I#*tN0(E+l z8d*;c*z1l_qL-q(mp7jJ@4WxxU*f#;E~d9P;Y%rtIh1|M>KaBXKFuj7E#S^uZsApz zznSy??kFxhuZ0@*ECF3hKnD=Ao|c{to=yIa_g?rBmY#VT*IoB5HuVlO=(x07F|>AZ z-88XS)NeXF7y_Sto^!ie@k4u?oQ#+fZ84+y%x6ABayV%|e@J+guu2dY^qik{4jgBg z6)TSA*=L{PPa8LK+DYf2J(TB27&cYtOWNPRmC|h9yqVj6{cHOAhW&dfn>7`oimMy& z4#&CqjJ(j+&nCZ#W-sDA{N*dEz;tglTRTQi_zDY zMCVOaeCIPM9(w!^PJjIynaoT_?*d*wVTK%KR$z^c&?t-;$zC^2vy{{biBf3~=@)(< zV^MgDJXJJ}qNmE(ZdpvIj7Li{U(=Z1AM~hSGxvckhKnsdV5SJligH@%ODWHBGo8X7l{G>^1yITa11*s@lQ=ZR3EMFm+-(SQB$Ig-tUVR@BTQ;q zVlirzM!ODEZqo3`>jmTlBM1u0rAdcrm69bAUib5-p*}|4>99~Lo>GdEEYptz2j8rw zC0Z34Of^D0Axl$fF1zTTurBx+>|DsB_dd&tlTN|PhuGDDQKQsthPaLpko!0cy#S^%CcD!crdp z^0O#cXtHR}@m~MM`+)(H(tPRKFB8mZCbaU;tKs3KFR|4uqx|8q$31Cc?SZFXNRbG$`nui~LfaeDLD3yvFvvw^`%AEtaoW1Y5pfU&)(O5L>n<^vDqPQm{{r5|VLIM2Ud**O8`0)_a?+_Ja%Cw&`5Z#pcahD0qB%%d$MR8uOsC zhY)C$OUtH7M^aE3j$RUH`<91U+AcY3q2zN{T*BhEBCU)PRC^drJWh=ophaX^#4sK1 zHvaki6S?o(SM!6f{0pm>cX&Mw){G=YRMDSG6h(=EW#Kq!YSEm%W&tmcHSqW?|IV$~ zy@h``VKo4J);Q9Yt_yC{fP^eqA)rjsPB&9Fp>-qFx?BDNjD8Ii_ z!mVY0N|@otYkGToNe(Cc_pvOSIxFg{z}dD%B9ZWEV2+c-agv@2$m|nUDFq{n+|Taz znj$61WYXi^|F2@&TywW51QCy0+!l$Tog~@4gY<5Cm#X6_?O8X59ssl|*wx$1GK zR57c^M)<$mwmXQ&ySyrysh~AWi=EpxF*>%F#hslbwr^)*XfIQ)OL90#Jid@Acg&vy z<`wpzSuKLp&=}p_aTP zp8PQ;J9^N`J{sH|w8#)l3TW;mFYN<@KGVM*^7|diaa60QIC$62h!x88Lap^Qu*=XY z^VCRD=?nM^uQJUi=rJBzV#YmvG-IA!L#ySTWri|&{4vKcFg)Ok@>Kc{Uihn!$yBjG z%=*0bM?a-|em4-rvO2tEPtzQce&3bWbAy|e1V&Tc<7?((Xx4pTdT;ijRkNc}i)1oI z7KmCA_9PN?#k-ilq?LklIDSP3AA8q%)Q@f9)vFshx_+3q9N)@0OADO8x{f96EoELE($8_`Dx+j47&P^)&X=r&xF@D za{cw!amGm}`QKCSK`i?b9_si7rIZW}4FYBX6$M6JB_g^0x-Sun#XRIjd5u284=$=D zZ?gxa{%EfuOfcoT9KEE2=lUPz(z8$Jj_-Vo28L-66SP~BUCF)dQ30a%(QMr@g4VS- z&M;vn2(ypZpK&w|?z7x-!{=DOyo(8aaE<<2U{^BDQLC1-v@62ANPthg>s7q!gic8I zGM?PQQh79aWe%%?97m}>7TY0CUV0Q^M{#u16z_h+=^WP?W5tpvwr$FSjdm-po1b;! zAF3>B?HmDYHA1hoMug0v-ETKuS_nh=4YjmvAhSB%jryN z*p;M|&QK#w$$!c<$x){r``-*@jY^2VL;ChuE z2ovw>@PN0#G)ebrz^l?k8}eS2IjMCX*EJ?+1*JJL76;)%a}&Sq%aD()W`rhcyN}`W zuYVsFFNAiBSclDCH%+5$)9++FFAm|G(UteZ39adKHH=EA*Brm3hN2J*t2{7Sb>`}W zBq@5@9$ECo0nAkvYH{5(<4)RJpOI<)XO#wf(<3n9jhU1ogpf?=JdTsXagr!ik+Ln* zJQ}@q8*OW6VDA`D@7TpPH{8gzU%QcQLoP~%JvC1AXO?D)qKQI%I~|LT;Ripvo8SEI zL7v+74EH_w2vE-r-}o{=`@wf{_wFT)ktaTHE=IQbGz{rn^3SDwS3 zj?=m5n}0UducIc}8XY=dg}QqGG>K>BoapQ8r$&Z+l)l=Gv_h+^Bq!zXEz8!MXBIgu z^5%Qf4p!9i;yD8%)*-6mHqBrv$-Cb5El`c3zOV{p(EeCg?tiZH(SYYhxS;G%uY9jJsI(Exj4=*v_;nRH7x9HH=EZFa%HgY@ zxPmi|?dFpoyo9%$e;TK)j!~ofIVu(*mE25J?<1lH$R(fPqwikF%U48L91Sxzu$dFO zI(*&vK?*hX$ePjE4C8lNaIcc$hC=^%hQEX3-)hXtzQvu!>B% z{nY6Jj_(Zdx>qmb>MJkg>sP;<|M>J(oVt7-wVsK4H5lk8NM5{Fmf!F1@5gZ*|8tk` z&446gTBUbp(yn!YlJ|chtu?uv_L~$Df_AHwzWzSet$U5PSQN_Jc%+m#PKsEpgP_jL zL9;QZ{()m%jcJdV7ZtilR4&FpFCw9KSHkkG}d|YE(ZN zcMN0$McG0uwg}svPl_Bx5hkc78BX+)8rsaV&IPntl07QRm#=v@XB^wj{eRxZgO5Fn z5K*LzFy$vJde+bXmzd6#f2KU?bVegWl_s}XM+_(B(hw44^J}0fs=D|8 zUrA<7GHa6ANoFTx2nmp&Tm%JF@UD1kt@YAcwYIi;)Y|H)z1a5D+E!2RH?>wzt*zQt zPwmZmX)9vY3bmq$2nq-UNPxsJA=yJ_51BQYS(C}{kF{rK5>V{1=X`(9_j~4f_5(>K znVG%U{;bdCeVJ$=Rq7i1X2nVNfCb+_o1h{N@c;c2^vZ*y#{Ns4um6*eg80YQ?8M(u zN?}fZlGV#ExhE@@Lt;qn8Dz%%yk0;eyMr zpg-kO6OB<2X--;vA`kz1DeGT;l@Bd>H~aGY!y(EwzSDca+sQjSyG%DNYBQoT%$v7> zLl0lTyt#9U#}ng{JRhQ_$0vHqgJq0$@XSPGL~BO8=M;Pxje)miJ!s4AKe?ZI^JcQM zql-i4&P1s^gPw>(r5B&dy;y}19t^CgJY(F>$8=kZo2%K7LlTCqCPupZu%t`Xf;7Wh zH*@2S+Yv{HnAKphVf%y78;6cgzV^e*=;Di%S z@C6Y{<%X-Z@Z&lDc^UPgaYpSePo1>rcTAacz!j{t@%Zh&p!ccDeEE-{A*$ z+`{oEECFBuNlRaXjvrmb%+vo3>W<*7PyQ4dk}%K!wXL9c@txaF;ZVJS!;hcEXBuAx zJ%e|>=PsxngOEwzFr~+ zn7xZ}@z2;I3~JXHnObn~kMH4{&s_NJgNRkdRh)^q00WcBLRBoYat(WuEy{zqV6Cg&9Xgh2Ak2kvIW zhAkw9a@_yN`*7V9g+Q@DQ686Am_&F&HDOF&HKkl4bFRlvA}UJ^s*AGS*$MEfw*yBf zXKu=j($v^CDaRp)LIeUlaR1$GTJdw1J@{qb*uIIp-h<;9D~v8TiI9`nqYNalZB`?$ z(?LuGS@owM@V=85^7Dt65@|nSZ2IX5Tvd8a5ABNtSPUu$DFrP}AzDL0{_{URPMO|A znNAay0x841;STbKo5XboIW$%cK$L2fO7oeIoWZhZpXW1|pU&;ST*j)69fV`;lxugK zQZNJ&fq>6HDU#>4)@Y>=2rSE}c)G6ZBa z8BvM?(An8ZEEc88iZG`^sbdevw7@%{h7AN=44x#n-nc>GVx_|*dsaLFYf{U7Y=n*dT1iSoPOJV5(lhhbTg&dwf# z&)#o35%9Yh#USx^CQ<*Dr2as^vmfNsPlQH&ewHXnXb$$--%iKne-iTZk9FM-KCzkD zT`K(@=_@};ufwXbEZgUel|H1j{8-f5+D<$kCo04NKZ6fz3x^@82na#59YyFI)ffmz zh5TRDuhMm1smJ>WWP!NW&}h>Uk8{o0=dmb%LnJpa~ zkWzB=(es%%Z!QlnjYH1h?yH5MOiCj$&!`6jGt;wpUz}J|45eJ0jG~zs%b$IYmtI;u z4iaOMh9a@PSRg2rGV5rh1e&Zo(&Uf_Cn)Wz`j8o~z*(~76w`^08pFe^2Zw63Y#+K* zB+44{ER=gjv_-SvV)tRHb^rh%07*naRNA*FQ1Fe3{Z293C$bjAC|YSO%VNzduONhA$&yq2_*TxC z1No3v{vr(oj!tT#HUkO6KtJvM zlI`2KP%b12O-dUf6+@;q{EO;bkehz+Gb&`7T|GTaiMF$#eI`|r01*o!3Vz$uL4%C3 z*U3}U(?xRGxB1YWukplg3$zO=PgU)1zIEeqysv#4g?JBp+;w#P@x7dS=U?f4?noFA zFg?i$=S2ANSq+G;4IFRH;+J<_!Vm7*!RrGqG+Q8H*MncARqSGu(?~`n-}1gIPCrnP zmFDX|Jo+21zWQ>oWC?Nr4>CE%w=%`>nDUopMHo?eqr4@c(Xtslh^cC6cl|(a_ogwR zup(xiyD0||5Y*T

+7*w)>{hdy)}-~8&=`QcqZ@}QbyJ|+KM4=E+XuA<7bxG2}~ z#ZP~p`ub`nO$sxA(IQ@0@w8Fwib$X6U#b}OR{O5us2JYWPzj_<07J@<-A9!6^W0*r zDMCam5BBkchIbW`l5Jgk5K<70+B~@Ietvb&ojiQoN7=D{Ig{*K9Az2-tqYH5il}8o zT2$#E!|qN7yI%#eNI6Q!hNt-DkH5mlFF2duzplJkYtD`Eij?BDm%^YIEK4#q8evL( zm_I)9WzxG|qLKtk*$n9%cEe;^+vm^}o63kvQi*2U+SeG0yFiW#(a(9Owz7P~PQG#D zNBQ&*e#0vp_tI#UPHr_Y>a8&|>Bfr{#i2!3Yla+$f(H%NZ&E*Gfg14Ti33V0f!AkX|FS9^xbPE+;r3Dc>bObGq7bV!fL_MY2J0sds*_Xuk-z1evg?mXZli? zMh?$r%7Tv(h@HdAd#|EZBnXQjXCAYF8@~8CuKnmISnduJQZ67tq(Mk3v4FVO9SQs7 z-(r%G-7i3RsvsVjytu&@rzWoJqBEL8pp+o0ks--YUi(4;71DGQhO{9kX{G&eB!M@Q zaZXx%0_UA~34j0lvwY;LYgo8&A#)bY1Z^>*jrpTyj4&z~&yJor?I?cFkov|5)uQAk zmQwhg+ajj+gO^>!w(f2^w{%gS2O;-|xQ$ClJ=Gs0EoxwQSx@g=$`Bb`Duhj$lc&m( z6hxXK?NBWwBg%OA>~jn}qZsrGq6kGY>vKdkP+?h=yWPZekgT-XD>O6oFobslIbK#V zCN*V9^|?fZAS!J32$zsY@EcUhOSFv_L^>X)*|r$)AWB7fZ_^nz-JWs}##Ai?{jTF} zMllAJi&8GJnEf^+cHc~`%Y47ed(9%0s$6S7=xhCUcrI42QDhH_Yzg|s8+c*479%qF|1r<+()Yz%e?D8fWC4g*mb)|$}T zK3=^13_9KwXIFQey{d|OIn3f&=V4g^l+#DfolY;VcON#8aNzc9reinQ^t)vkuMsk8>zt;>K~lvkKZ&r?im#Yjf`iKlHFGsi*K;K?n^ra}f7 zbTdATXUCQ$+$GbwW@fL+o>u=ZB;zD)5zSs1uSQ zH$y>ahBOE{%CCR>B47O2Juqo1=m8)Jdy^1sG%NBzgutA)U~@Thj|K%)*FtRrgvU&l zd;fejM`(*mZ9E^e*2qMhd#*Xe6QZf}o;kzBJhul|XuyV^1Zyrk87{-ydm1R$u&XbF z78a;Di(-o?22N8U1ww0o?Bv&N}^cCN;IQt$QnvEPaygYgf`3F&=XTFZZb`$)!YzO5K>E;Ml%U5CIBW zkJ|;xwI=I9_liw6%j3NaX@$UWz3}J{1&ktWL8QIOj|3!zfc8NcHExhHtBed0suRivybHduU$&n?rn^yG+7yA zbVf6Co90ty&B1Ykyxu+5h}b9Fm^R~e`jdZ0sUXz~u2?dI>u&xH1M6<5(T<>XnqVpC z)uVY-lJ^yB$Dp!faJ%BZU-00CLt2eBpuktxRcTN4>%V)G40;Q>F%sg3Ke(9>p0$KG z+%7B`rrw%HLDX`~9pB=)*ZO_K8zD-&rV0c!walWieIY}ROInwa-?fujZ8keQI*`&- zy@vc`D&q(O%Zl>ryZ_8*J`tsB%TA`-(|L9KQm($~w;aCs9B#So3Fgk7yPvU7@n&sl zY2nBv=dt7YUm=7b;|_4{sfY24`|jq5v#+5_EsJvxRJ*nf0)+RR^~2T zOkZ~=jZKmYA#hcODl0^VSCA{EJe80ACj;X#&SKm+v{a|xPs+W(_@T=$!)mI>ir6@b zjkLD3`^kwZ=7c}GEO_cC1!24t>STx^&m7V6iXPX^P;J=+R33$*ih#Fi+r+yQ%#7I# zc*V0omULKz-zBZKB>R*@L5xyo2}WH5Eeb>;sPr4aiNGkQUi)|0u?42Ln$Oz%95lBY zdDgIioGPjGB!ng8dLikW|ATR+2J`dcX;WS`S-hduCaAT{My)m-oG9X%U%h#b?2W&} za%}T2?e^rgo)Ds6Au9eWjrsGN)i-7!ZJ*bFcx7(#SnSI1j3^vlO9R6sQwrn6I4(t z&xp>OZY!E{^aRPw;u08>pDg&vfaw^!Zi>BqaoXG3m?WD#?n{CyE8-<%d75KQba(d= zL6A}k+m2G94Ll?skJH-Pf^A!D*su;E1^b+Y>1R0~Ng7G+BNDWv0lNExEvRUFdVL>A4U(!^p5*ym(W%4JG>8;%qAnjIFg zSQIG*TQ_t7&=zZ<9agsFsZeLVK+lO-p3)WZ4`u{(Q4w2&MwxjU5#x= zP%6cw)+VZ~D0|}$gDQ{Z@ganOe%GZD2YsGQm zM%7IS+!Ev5a$oSFn6wH5cR#>%y*MezYDGM55Fw6ZI@3k;+dm@OQRGe(7)50ilUkeT z?(Xqa>q_`l6SAkGPffMglvE|c2SNxOCxK;I)Jcm$<$}^6z1&HT8FugNGex%cAU8#^ zgMMY2p;koF7_k}B3Mb*7N27yguuxw zD!ih}sG_CE!Rf}sxb@q*ZiaIw5JFOk;b^H6SQ90pGFfjjHVy~kI+V!}s?Vjlt%*-w zcriEK@DaLq?Eq2FUJaLCbpsDQwt)*iaW=7;Grj4E#X=5cIF;a`dvD>%=eKe6Y@0pF zUK(oaIO>ek_*W;-!w)>n!V8b4-v!ql_KH`4 zJ0N$!N$$k8eBj53QdCNbv~A+?IL&sCFX9(m+(uKe)Dw6r#H^a;na zYjYIDwz;~WnLXDX`un7}d?089aB5}Vs@yOT$M^DzJU&||!`dNq?; zn&@@9sgu_D;-{E@VurIzLv71j|Yaru-OYEUd@AuglDP2?tFK9$qRR7<{n?tC*LN%uq`w}@u(i(5tju2r4L579F3J3hj zsX{9wu7c;El0}pErgV8PZj@ti(+7fV7P0xmo(;zw|}s&0RpRrz*CotCN!!E#jeve#6Z-e2QCd zy@Q1d7c$^Dta{}Y4mUj~S|`)qK8thCJd-yD1_%ZP z6|$D~+g|7OSJv|P=l+ILd9oyM5-!tc&ZH8}i|bbMiAyfw{U7=O!^tF*CpVMWJ;1uP zt7uzz3_2&c^*`>!b&cb@kyI8;i8XP}6(42Ys+TzT+;bQaqfD|IP|9V)wym@`H*?;_ zmwG$|d}92xSSvyZ<{x(==bm^NmtFlYoV0i`H{5Uo*Is)qk3IGnH{Wmrn>xE0R0&)+ zg_CfY)Y3$S=l${cLl3fd_im~zNo{QdQc9ApL(jHd^d$#**y9cc|F{x!TU%6os z`!wuLHzC9*6*|a>64Zz$U!VsBBSC!0|4P6j?eEK>kVTbcVOh2x$Ftt#KzSR-h7IeG zGBmC`Tk0EBK7p|NW-wP>(m=6o8^?)z;sVB)7F;jkmj{7v8+9Ysb!m>p*ctC($CfT{ z!XNTDJ_q8tm_D`AuE*63c$1Q`33Q#b=yl>ou2_yG{RPh?u@WOUErh_1+I~S$%r*Q; zPf;i-W6q)#v5+BieuumeT^$mLARN2+c-q?9IP0u)dEte>QCGazi+&>>T431CQ=!E{ z!*7xEQkq*7(JekaSio!R*75l-eFITm!KIh}3m1Io64q?&puD8m>FnxcPTMRBVict^ zp7+i>kCDaZc_onbs?;n+s}6&V$a?4!&je@eiU!S;VN_+PlMn$`{&f{seB>;g&7D9E z3m3kdhaP*04_|*LN(-~+OEaYufQUr7?7ADc@4j1ke)CR_p54qqatDvz`Yo26a1LL( z`MaEZ<==4K3?rUwwN_@@B}9OhmMGVJ_+mbB%?EMaE-Wj|KI%wN%L%jIiws#n2<Jrva6qG)nKg{hOa+9C|{# znx#vZa^Zy+`hQP`0{a&#Vw@*R?wWD~lip zESM7@JCGpn1Zl7&z0LreUrln-c~_J5U~8pQfQdn-AYxR=NuWBJBqi0PX{;TkJfHce zsAdUah-@mOu%kAyn1Os1GMc)k7=zmAgBPpQLSQ_OuN;jCNQUwXD`KirgD*A7#7J6` zjc8`gp2e(#zk4TFU-vl{FFKyi&MvxpdN`z|g%MSDKvJHWri?P^bxZ*! z**1IQ2|o~7NFtOW#3)_yE!eirkgH60PeVLzOiK-%u^32%FO_FtcR_lcI4KfDg``3T zh{+~0Xd<}0@w-#0kb*wtGUTaf7zMi&QjX#xsF%{~{HCz15Ct)ZecCunH+xRcL%t#j zepj#B`HOwgMOz`9E79t z_MuZ+AAGGBlf%+t)-6$g^JQ(lE?>1c0wDz5Jw3FywXm(H2RmvE2IGBwi0FK#NkNMh z!qFBkpFw7ir=Zkc%VcuN(4ZL1rQ{y(r9v&d9g?5G^1ktgk+*w>w(^z zMwN7n_cQJBxFN=9P=~ay6m>{z3-#@@_|oUD=iTR?g%GfDV+WRH@zhf*_}f!|;iN^2 z*x23Uuc79s;laGNem!5j>Fc;|lJ@o%_9Yx<&7RG)Sd6PLyNbt_{mDyi@}>*Tm}GC? zo;}Q-)z0OYe3UgSU*)48{UDpWx_I@ab+j~0rh8X6b~J{RmVu5bO|_K7;|VG%f_(p* zH=%PmF23XvG@2DFRuYdN!*~08iN#{{IvZ(kpGiUVc!fify}KPQzU(qS^#1o!rZuM? zzl0o`pa0}uLai}=bjN+nXlY@elk%m6hh3wxmQN@7!4JNLl#-+7Euf{JC|IF468~E(CpJw^;()_`&(jpL z2&CgE@A`(cfuiOxP~0+vFH`Tis89xUi!y{LLxzLYQHCYTfQ)HiN;5gK?I4#_;L*eE8rI$cuI-Iq+KcHHRyy74J;Na zMdh$T?T$MKN<&rNJ3krCp14CrSQxHXMqx!Po_lE}k38})Q>RYh=%bHg)!&{eX=<7# zMui94c{`lZ(jrB9P|qSHy4ds_O!RTmi6>#zRZ~|ti67o|7r+10GAg9SGeeCcEV&h9PGGo&Fa>Zoa$Lsg`SyeOS`dtO!^l&fvgB3@bX z1|zbTK-eX{tCE6H9DR6%XCGV2doH_Xd=u(z=L_1)Uo0wt_?8a7dDEA9|JmnL@I3Y0 zREC_FD+B=F^}M*bjQkTf(ke^hb|)Bi2dJ$rcI0w|MIDHgD5a=YRNvbZ;Ht6QB4L*M0hPytaBBk%;97m2wgElj{QoHl;GOw%Y7-QvL>Ef`#Et z1u3K7O%t?jDx`%4C^wE}+2m!2A!T4H#iFZ}i&f!a+Os&6iB<|4hO|p1(m)0zXdS0N z?%~PNSTaVn5ajd#QjRjD^SF+t*={9lg;2^NAOj4lJOyD=Koez0Qp?F7dugU|E z;3g)kV{pD4J=zyghxItCIIC+&5+g{9;>H9j&j`GL+I$}U`T5g z93Nw!qsfw{yL-3ka(N_RJox62ek&f&|2~2O$SFbyga}a~jW>r%Yh>6IDCH7HgJTMN zQd$@%v|-SifY(hd^Cu;ma$V+e4BvWP)k({fDK=f-a;+J36^@47o;|q9-Sqc#dCwJ8 zMTzTa+Y~Q|%^Or29Ivl2_ zr-y#m#kLIusm6|BSrL-SBF0hKm}hN9@LW+A;KNtWyZ#r;5_ zkztdxih%HJ2Xbibf)XA_Ls7(jZGL?t!>*#Mt7qJ_qsY_BPFRY1!kV0DEl@1R4YbiD zP3`ToJjmF=;X{@cVV{$t(XxF)_Mmb-g{r*i4wS^s$_e*LL5xzVg)eGURQt+mP1ZHW z+@%ek(!Do}Hrj4NcmgFYxNeGJSCO@}pTrJ&iN2JQY)X+zxl~3h+M}L>xp#lMDTP&Q zv3&VTwr_uf_8F5o`Q+32)vta*0Rh!slUxKmm9})6gc>Cn2@%kWr4QfFT~{7M$H0I;6p(TX(Y6KS?2NMr3PO3s ziz$T8xZnbk$pN1D^N+du{l}4W2Z@LUMIm}3+FOi$kWl$MIP82PcUb}^wNf@rV8=T!=z7mWR$|PB4mNG zTqQyT$&w?jH9}NVNsd&iZ=8O-lotCEDFmjg44QfYxkQF)k)=#)f&|HtqYxA&y4GV0 zsnT0q88=UB>nw5%d7D!i`Sc(os+W)+5BZwdB^fkI<{xXaks*se{Q3{P|Gn>`wIznuite6nWLOZ7$FXWn)mkA1 zRkapNmp;uMKfRkJr@xz24ra|dio+Hz=JwmZR}wJBg7%mvf*E(~35G|BM8a2=8E_qx z(med|pC~U2uoP3M_DGT@ zC|1Y-HFhiIvYkO?3V~_?L)!5OyykOA>1}qtM~Lu@+Z2>lXw4hHpWQ1k_#cNwO5)1{XkJ(IWjj=P{jn=NG>uzD&F&ZsX9BS*G zA*jXV4oY2#kvAl6WJ=jLrfj&77R}x?XRC z2y=i#sR18qGVCh)QyzKM3SmvELxyXKMx!*hwb9tpLMoMF{rdHEbZkWkiIZ@s@}MF` zB}!Q|lUiGF_v~SxSS(6!B2J@a`2rb^lcGXYm zKSoZTY_o0Gb`GD_M#7VTKXUF|_QvB33=H_jYW=R6&Ntg;YM;vuvTau*JNGbO0L6%VnD<^~8I!{eTQ>4WXD2(hbW#_R?2S7d(%MQUV^o56#^YX6 zK7iIPBY`BbSb!-rVl=czsgH%IkBw4e3&N8HH4WylYR$jF20>M=;IP^lhsqd-hGHBl zZJMM-RMcWqi;Yn<5+!EBjwfecTn|M9+EP=zf5ebiN=c(-(eIk6N+odbz4sB1_xaPm zgFT80Yq3}pot<4+mSw~qinAk6>bmkxkOfs%$WP{t65ZI>Mr20#Uk|&=|GIci%sy)I z{PQch=bn3*(%!}L?0se_CH*Ov9b2~09E}-YHi54Q_TsvAY}&q?m21{; z`q^jm$Z!7SH(HA*04Wb1Z!0ED)Q3GoNdY|czrM=cU!_7}7>i zsI*yE&^aCSXx&cvvii%e6-5^Ij7%?8CP+ znGEm0;5b?Y|zYfs7mDK|f6Dm}52kma9CKsEjel4d(b zA*l(AFqNJ*b98be)nbSjRy^eqYm7W08mhcbeZf-?6Tpiro~EHeB0c6A?pnwD9Nd)4;qzwk?OX1mv#Zk!R7PpZ zsx>B_ZqjA%Zqo&-^1345z3o=M|D(HDv*tx6*EjL`FaJB!nkMnHJMX5WqhpMA=A9SI zvc_>d%(z$)jYa^?uD%|gdu9d49(yvEUi@J$|Io*IZuvU24)R(@7Zo8%cTXp=SPUsc zo-*4+_v4AUM!}#bZyk$8iN|}eZQCpC%mgGOqWt@<%Xq`7rKP2fX){}Bv?R^ZR%W!c z(A?HSTU!fuG=h|ZSW}FamKH3_qM+Sy z4sEiS-PS^Lw25ICzVx}DQ7xJncFSn9V??~ysV+GtZnWiokUa3wVp*i)37VuNf?%KH zaNWnQX(4>pIle*Yo=J?c-wZWIM*<#f#|~*lpgMlb|kS;*#qs zk7Ntg)%El`E|XeYsfk7n;W}jCI_5J7_9a{oa+>!!eermlbb64z@m*9|l9rYx7M^k( zuWi|gJSdn&gzJZGTRLXPHsN@jB;i-hfGpGx< zV+(UcMJx5Pow`svb)i=3LhZOwL4S0VUMokJm1Cz&vqh%aD$~3!#)#ZSxRY(i{OJQg zM(lqSgz*0_#27K%z{4iqKboC!123!=g8HTyKfC8%;(c+SOYv3@*G*yDQIyK~3R2?} zXb+N1ZoeZ-&R4=Lh*7`b)SiM}sR&T%6v|IFC*(8hR=vWyS6}rL`yxlISlCn|5CIqo z2;zNlp8oUWba!{tn{e2tH8NzO^V**#tzEZ{4I4V?>e|UAmtV@Y*IvWMjq9lN)@J$J zXygth5>$Dxx?xvQB_+?Tc!E<;KAA6n{YLie9isKnxjgsMTGn-TnMto#qztFb^)Kd5 zMgGlie*0UNJ^3VcGV)J=)=o4vEMBwmS$P)xYgPPLYi()?DN$Ne2n0A{Ry$=nO25S0XJVz4QLwA@3TvMuO<>IMaok1tZ$L&!DcIw>OlxYQW5*5}tg}g~ zUZf17+1sQ6l|Yyg|zIV_X#}1r;HQn}S)k&0xk{ z-i2yw1nl$SJ2wp&Yz!piLD#fa{v8zv0?psKJ)2M6AlZe zw6t*g+3#c4tXa&PHxJvk$8}$nQgnBBvV8foY}>YpH5*@{w{wtVk3E)0A9Z6kxc>4_@#6`)m9_#KmmUqe2u-=J30;L&D{(^WWo{Ix5fKLNnx; z&TpM9eHAy?&C~BDxa+PT)6vo6aZilzMpkR2C-YsL%oa4b%B60c!~Oq0CO&fGrlX^z zOT-%n(`f^lNSn1143@xQwD$Ncf}ppl=Ej+!j(Yd!fr_iK3o@kB2od(Ky;+A+N(M86 zDO09!|1W>R`RAX{&W;WiELgzzzIPj6`R4aI>)q%0P#VXHo2iVH6ogU!3yLtWyt1Bm zU3j6FFuHvE+y73>A#>>4x!W@$wY`a)1dr<_grIZN>wM&*i->o15Nm6rCKBPa(@x{i zc}IFA=z!NG)qdjH?>dYG;fW`n;Hs;xqOUJOWh6uyf-PIR7#cD#%SkP*?Co=?ii|ZL zv`$l37iR0OO-!5FVw!MTF_;!-CZibk=pUDI&Idk*QkwFjB)U`N=9$UILw~-XE3UZGGlnxwnrp7Oj*76P#ts?1 z5UokLj>l_I3?~(J^^=Il;~cl-d_tiJsYD-l|L8}YchN;mZEQs6wO7Oqn5F@WN>NLd z7tbm}qhwK3G3pnEm0pLr2pP$UQ5rm-7_@=EnA{*x;>KOHP%yt!ga;S-9Ak=1CHp&L zhM?s>hf2Ijqt!?}8#!PH9EZ;BuhP-c<4*$KI{yhV>}Gr?`B}4OvS{(KEMB~b?|t_> z#N&N_UU8slN&tbYQvPQW8c#GvQXd;DfQnO-I*bgl^1d!Y9FbDmmTVsP4tl;=z{pnyW>&7N=7n#rC@Yc_7|;ML7rx$mx@aK|0D z@Rz^*h3V7V_|&Ja&@9(WnPcO0jh5WBlySyXk$Si%Ott&miBrKc;kccJZ^H-fbqEPT$+$sT`z`D&eSTpDR?H1}k3{ zd}14{tccPXOoEJ2Aq62VxaXd``P#eMaa=QTX||{E*UjCW=0O*Sv}?>&C-6r{lxaM! zU%!Tc>gV{wXVdE>X|@~8^=fU$bxmxIAaGrWIw{!gIvm#8iVTNwlS%f)dug_(^FsGF zP7HYkMTw4)$-Rn&tY+8^GLlj3jl0x~N`%Of(>ZiL&7|5{Il8H#8YSwOD$4o$x)=HD{XgNN>%K_VlYCTtebhCD(AWrUetq9Jka9Ca zIzugWSXL!3KDU97-}o~&cl98oNrIG{r(6fUE?tIWFS?F(s~+SCy91@3Bd>;-KKU$? zgT37No#Xiak5+mZ`Y~2%(F!M2$u(QDh8DDkQm<~nSk%B^sbs|s*L%r7&$lXVPCZ`iCK=3 z7938wC7(@G9TZdtC5{tkuhvYRH;Ycq#W{Qy!* zrcRwoG#Vw9O0jwKX0E^fdV~-xK4K0HTEq0&(5uVGF?pAG(CyyW{-w zkyUg#WlU*5oJXJd8_&PIlJ9-*o4D)#&JHn`p58FjokR<;`p=K>qaS{skajsrpGFo# zblcRqolTwFIr7M3sI8sMHP>9jSx+rxZ+ru5g3ZwKQ3@i-sOwN6Ewrmj?sIX#LSp>a z;sC{i@Xzza;86UXcT$|Z`Fk0g)cWhZM9NwS)Aj51)O3Up#uN>xBuupkF{1KR3U3pa zAhc$4R~L9mN)pW^C1@}tDXMiDIf5Q9W|T(D@{6;OE`=Y3{dHIn>5_YEOlHy$Tyt-O z5c*CHJ^%6FFP%(Oz6C#M;`7JLzMC}}mNry}DJYj$mcPbxPp#yPGZ(Vx#B&)Arm4zl z4xKlT=bwL;Y9VOq?&brRp3m*SS_;&{-XwKiA}D2uL{Gwu=m;909--NxHxbfDaJZO9 zjo9!DrcPFO(mLPH%@C~BRQR>P71#G#m{o{ z&EMjwr=DWXnwP1qZA9xdmKCDcNm0$j;;JQh)9$-pyBLf49s4b9EBSn;#UtUcXfz{Z^u;*(tJtf)2 zb~3`I-kwE;UQ44jO1!U(>d54hBE=LadB(gis)4-6;V^RfAx~f>g=Iy&B2VlW?@Akv zO5fwr4-sjK4`7k=eX3^mj4+#JG)Fgj!2Zs_&JAZ zAc}G3(oVwlxM&)kH!-wAYifjKxJW7wONO;#?YfPechQGA@1hTL^<|gy;)}1aYSk5# zmj_sKSR0Lvjm$XY5N6DnLH%T#N?9HMaWt9%Eb3LBXj>HWZ`v8Bq`QJdkKy|#HX_I$SrbE2EBEh$BzKNT^c8jT6y>nP0AfQ~n{Q0YB zvi31KW|MSw6O7H~)mL`%*;{XC*oDr{jtTsp{|a&+=Np7 zeDjVwN%!o7Jp;s=4)K-2YNaXs-^t_uU(*ClspdSuBrO?I3Q$C(L`YNQYrUI{fF$D> zi@uzAC4!JHBQBFZ!8BLGr%IvF3L3Dyad`3d$FTibjQUV%r?q%rRf>RT2KIlKyZxB4 zoVh2v+&5q-P0NgS_HExpYd4U%DZH*%^)*REYgQLDium8<{$BImyMTxQLjMZwWf zUCW4&R7gpxvxlZ8+f&d=qLro=NmMj|(Cq47M`P_n?W*GBNNYhSHX{Q(y{RfGKS$Eu}yi zXiI=n8YpYS8VF>8I1p#C6U&L^*jKTxZ5`P6#3Kb!tBS3gHc($xRX|u;HgBdZBx&2e zomXGoNFd~;HdKk@I1KicFsUkx2RB4fD{MPSDy2F2-~;*D&;A{)HPzL1^zEl)YxX==qQJwKAU83FUOpG3ejjI z-@NK7!qpayjkDO*(?f1R7jj~{9UBC$`<0;E>EW#{&75@d$vm`T1r^m6byX1>XV0dt zu8#Kh&H@Fd!|Tv*g-NQpT=dyn`02Nfqf%2_6^m8FbS7MN|x4q$qWD1^F{_Nar1s1pRg& zWtK#`IV(9gM@0w$mMj|PSz{${0zEXdfRr^K<;=#*0|+iG%P;h1Nqz>8EA$TB>Kv zpy`nL1{{EbOK2w1#|zIt!TMKU#ZQK13lB!AUJjf&o8D9jE1!Omf4Y4Jo7?)_p{U01 zHvMUlMC%z$4$h+=O{A`x*6jn73C-&--%Zt=3MN%mQEi3MTA)%0i{Qy6$ZjF1(t7tagWh`h(0k-?KjU=0)N{2qs4&^xLL;$ED#E3Q7T< zf}L;vSkF7`?Eeo9Iux`7OHMwSZ(goQswsrSB?ytBR|$5tZsO4u_jAt!PjSvkM{?L< zhcT_L5v3GawUvR+og6;54%mxUDN3yd*2mH;zw+k{WYg|~8YvWJLvGlZ5U{6h|HTCzdb2f&~kfVkhDx+c(p;`Dqr`1t`%r zS(PJTMd{I%>`Csys%T(OY%BAd8hEj}%cSS(eT%~Xigjq|drY@Wi%iCby<@-M-_&Sm zfDkOhMS|AdnZlc1~JuZ>FwtXj2-V^295zwqL5U3qFOi`{mDja%Mk!2%-` z?N?c{GQ-rS`LH_<%jPh9{%o?TB#RC_lJ@p(Os{LCKHNwkBq`O3GAY>Ext+OlXA+OM z13o-R=v5H(Q7$Aw8D`U_jZ9iJ6<<#$_pM#Wfd|ed8f|3d%0FY<4u>3g5YImQB8SiY z96n*vv6()T3di^0^YxcPhCskX} z5F(LMlt@V^R7sf?;+^epQDzI8nhqiwZDRGRzq4e?Qox7L4gLcOQ=@e0(WLghU2!H= zNlJAIS_r&-0))k|$l#4=Qd029s($Xfb_Gn8&>Lh^s+B)Hpt%3ePgBEoa>^#tlf_e6 zNiZ0sv$LI?N}*DUFMs7LY>UO%xwDf2t~5ls zjXe3cXZiMbzQZlQ{4qT}J+59LL{8}fXWwxgQmI~&$q-UXwr<_VQ40@c)7xA5^$mbG%@I8$x2;tdh1ojq@`nfjC0RAhn}7u)~;Pme~Y`c$DFFa4Q zp`ox348i|ElcL|pdA%>PnHTkIokdEpB2@)CqSjgTyEuoA(xAQWFg05k)CeKy#>P`j zl}4K!75DGvl-_TRwh!gKh^3+RzT=xwU0c!DKu!qCfS#noAez=yt<0M_hbzDReU#GJ z37c4ZjLvw>(2t7j=?`DHl%|dvB`|?gM z_|%bP=yo;RDKhM4#fo22*L)DCoN^|CKm}=nbZl6|>Q$@Q{LX@EyK?{lAOJ~3K~yV* zg~o?*!VHHc@y^}k4OoE3WhesNd2Q+Nkw1LM~te{rz!J~SaEQ6GjqH<;cM+~v4J;~R; z`BC2K>%zOw;?ffirT=SZR%R4YkShme(ESE#fsZ+U91L5+a&D0`Y@Eo@+NxRZq^TVq-xazz7^42x0-ea!|^Sw-{O&4vAhWGA7}Jd#O=>C+qd!bP7W8^};8 zjTr>MF-zvt+SbK8+qdI%8^@wj?ed|!J4qz^2nK!B)mbcBw16(w`R>C^RDP)M_78k^}6N6~L*kvila!Xt$lqt=Q+r5FUJxXa5|6po5kC`XaiieXXhHrFEr z+=FJw{cA(oOmjyafka^s8v;s|o={`)|I(wY$0^YNw9z=5IQ6u1n9^X;+8P63 z-r~iywzjf<)7wm*J|CqtDyu-3FeMyjx821jPdSS2)*jYvdY!aaP-a=Ay$YpDTw%K+ z5?RE3=l%i?I1#43!|i8%jIaIf71-tQ*-QVxbN_xm)wI*8n%SG$P9zfMz@{eR@w_35 z?dlCOZjn_&xv&^ej++p#=(_J2S?7>VX=cuvhn+~^^9hp49>QUZSj?eP zhH?6gW<;wLoxQ!xn>U||>M)Du%_AO4CRi(+zBK8iaw$TZNTiNd+sH!xZ)cm5;mC(q*7xM#Bw3%clCu;!O3V{!rZxY zu`J13Z@j_%_utRG_ddYf>GK)LYCPJc&O44nE~|;uM%c1*D~B9-Ff$tuf z!`thd*%pg&?6JqPV#QzRcKV1!8d$k$kQ;CQKGd8ATNI_iFq0!qbTx0mvSdND?$;%5 z#z{$`7#sqImAST``q*jg?A*(s*h zc3C79E=>G~#ssCB0(2-(MRkXL&(>@^zNyv{Z6wwHh2ZbvbUW@ndOprAz}5vD~V zObS~CLH?-Of!?QiGg&_)6P_=5i}Z<#W%k4tItpKv#w_22jQp-+f=AD6}G} zFkD!Tlp#7g;GTO|@gEO0s%#KW9YrL1b=rjg(H~)U!)ePto*LgGv3^1oU zNZRRQT3rasGEA7V#t;`@zkA2%tkW0i`_lLq-8BL z=AJ-OxS#(xJ&n$Oc)`(mG|lTc4#A+|*X?$F-iM{3f!VGItT-866nvzMX+`@N%@{gQ z1!-Y6`I_1WzVV}9bI;9R;`(dOW&3MyQ7K2Li-dV?zLIz4KFaOF@jQi z35RFU9v>juG>`MI`aUmhO!Cs}JFqNoVe>WxiFXXtDuia^mOeIh46$I!JbrbLO>A=q zRgo~3s^hso|CP>P-bT1iGQYX{%B!a^WTo+kYkBC&jok2?huPU>4tAx| zR7z1u(Pcji{)5xO#C|tUofYrukZ9 zqT6vO)n*oDJ0<2ix!&z{b&Y_J`WX#Ob^|nph)`iwFztXD^dyWWXlq+59o@UgX~&f= z7=hk^PEuJZh<9%1q%)Vf6S0g5nY1jZ0{^&J!?P_5_E7B;aw_t;D-RbS!!=7Xh zv*ynr+txx;(*eZe31-i4VsAXoqD6BU0**RrDUUz?GDn|zCL$qVM<*~FDJ5ODU4Vf9 zF%8N;uIYLIgOpJO!*AeSGIksxZ2Ukqg2__TpD$WmN0JdCC>3F3Aizjpy5Lx4)|MAP zJ|xopK1EJt3YxQ0EeRkf(LTKH{V`lXV_lA{J0<&nL4!Xm#6IqX`FsU{sg?yPLl3D9 zH`45D1v31{eUC7NaR3X2YDlFtJ9lj5_+`h@+}=s0lo$}jXnYndn9sA1ucFgVFuAst zE@jY$J{%^6t8kn&A*JbSO#mU-)z01bUBrR$RxZEvY<~9Rzd*C1#+t*{j+mjQ)dVTk z8gCFc4czSU;c%GVM;|p#TdvW@sIXNrM25!78lurCc4wUP&O0C5wwZpw4219jhQBYR z504ahw4^^_BLgtd;}oWN^A|5>*@8tpx$0>=QWl)H9LF)pgffEVA#g?YJ~t~R$SJ3M zgx1!LL?RIe++e-D^?Uy7!9F9#-m6mhd_MNZZ5Aw?!;&RS5aMyd;RwNCkS*<N!EMEHa|eK+D=?e6(XIWFTN$;_EE z4SI1HJhtLd!r?IQyz`E+nynDn37c?Lm~9;~q$_?ebIbQA`>dZIO<^E{I=TA2b`6|%sRB$dO6<40SPSqlzf>rav- z2vToN!Et(-9xmsd)@KP=Gr94quP`Dc8(UfkNiTjhf4JvX8XGIA3rmK@2z!(UrC4^x zMfCJ#sjToFU3v%^-9g9_l-DidJ3s#$_dM|+YuY-f%4g?!#Xh&( zM7s9>>cgwGW^c-*!`6qxfN?M>)tX48%7ygJRDS4v+@RxcWRHZLttiooaC8puwC&>X z(@&>V{~MqC@`e1zufImTvy<+48#CrkN2wIYFFcu~(u8CsePS;;SFI?on47OB9SU`uB*{_YLjtLfDlo-R5NSZ4&jAeYdLMP6xcnEi>O#wAz7H@%YeXfMfjyI%oR)veEC|X-Pm>j94#!Us5QZlSH zkw}zY6{k{42uV;5T30f2=1dMcsvh%#t`xl24p@7I#1JJ2t-2&e3O{NpDgWisXW?e9`Lq-`}J#VUse^ zW>x&NCL~$gI1WimGN6sErJ)v%kO~L}vw{H~#MXkClchc8usgnolv3Dk^88+{Nh(E+ z5Y&dl)P*d90m+i6Vp85(yUH@Nt*pbKsG1jeK&C@Tu$OV^P%_JFyOeg8Mm%Z^x z%$ail@3eL?M4D1e+IE>0pxv>lpqff4Nec;?6x3L(eEKgeIsR-Ox#t<^ZHE~EJ!H_d z#~er+icCpH^Mx;dkwN9~$}6w4Gae_E8o+VVq(uqkLQ*L$y8CP@1CrXx8d`R2!nWfq zTC@Zq;Ge(oO*bcMto`}kt~fFv>DL-9AUb;*p-_k|8=Lu;Yp*4z6w~H3@%oxI^d@`V zoQMFW+K0!I#JggJ!lbfN((UvxD>{=y4?mbg4w=necin~UICwM#hp+*qjCE*0;@F)C z0h2-@B9Sn5kIiYPpUgprAI^_{^dn=xn=wU?-t1!A$)>K;c7N--psY%{3e6S;icDKr@6V=?91-Gn$OJ#T^i)h(v0Mcg30BG?Np)ejIoG{T0~I&Hz>P zD#c`Jp>@xM{Y3F}+@R?;wl?&$Qmyd_qbHTp`!0Lgdpiz&a9Z|zTY#Hl*8~F#Jwjf` zl-D|y7BMm=I{W6Scas=UimU)dzK7(Y)&G#r566Ff)^Y*iOG@{r{MWsjS zN*)b^`C>c6J{G(aU58--JDQuZEQ={2lgrW4((J|~6uYhIF?6!g-6I{ z&6Yq5R)pcK^qIwD=!cacb z$vqr2cRGD`2UBMr#*UseRnY_a-VN9D`_&G++q&F3$U<6{YaeYK0tb*-(xO*64C*ld zcIT7Co9{!2Nd&A~rdqua+s%^?{*s{w?NLObQ=E9JzRbp<{|lY8M^KcYg3E zZu`Y5y1LR>77Q1gS>(YC@5qN&Pvl*{!r?GEm2wYifo&(yI_)ODj>2pnDUF^$>-Xf! z7kA-ZDo&MU;U~DS=3lVMJk0y8EN}$8}uy<3AFNG#N`ur;mQy6jI}_ zgTDaXez?V7UO?~nx;LEbJTd$}{*Elzv+6?H=#Ut7JkeSct~Q%NK3gC^#Zk6$ElAxB zN(gdAYd{D^y*o|OX-#QXqrCzVka)&5QsZ?h`Hf>hYibCfifDV2!d0%wUQ>=_z;!5U zwG%`lwb*uoX^{rb{KVPJnO@B`H{V})-grF0ipL(q>Dp_ilsV0F&%MgX2-Mb2=Ec{W zsjr_xEY`(~&#tDoSJR(Jn~@KKq@(c264JdIAuQ%JMTx~)iAE#H+D4{C8)$9q;?-B1 z>FU~xWrY#K58Vy~>*!UQH03<>*XMZRi5FS%*o%|`x#D}b1g^X84g!-)x%QvFX@uZf zLohgs1X|WOzSsZF`F{S;C=Rb05_w)a__StFEBXneMVO=v0|8=Anm0CV;Kj|Atn2I~ z(e6O9#4sz7;FA!ngiIWQUUOn7KikLvUFLt861QH-Ku|-qX2DD^r!A`Ds6~^RH=~y1 zCIwRBcN@ceLGb_LV^}ao?^6oQjf}v++Z?y#JN)xMeV=2e9n7r7b6ENGY8D-TFl{?_ z5)6ju)0(HAU(NP)uX6km$FQTNnZ?JS0z2R0u%<&00^VwAV^~}oKIhPF=wBB zI>SP+w<|%oD$1S?n@B^HU2QE4Xiax_lE)u^oNP*S>?zAAuL^ME4}Ze3ryfPlMO#X< zSv&y?%d+TI8c#4tGTBWi6y&$}{g(4S`Y{HTqOENc*Ie^mzV)rk#vqou!0$I=@<`Y6IO4b?X>M-e z#kaqGB{S-$o8~{2Bpk4aM54UY)`Ad%rluz1y-7B2ev=~?A4&a;29rV4XLHe4FXQ^_ zujh#;o@Gz0gUW!#?Kd@2e)v@GTIYpewVT^vuD_okV+}Tn>0jpO9v5}Un;!@v8F0*C zLm=OS`t{-MnfnvVzh6|-ud}X$XNmh>vSxf(j0)i0hx#=vMi6eEM!`G+uVF2?VTr{W zm7xM<*of^190x5#f%avJ_mKi+D$hO{nt=W_mWnp zRw9uwu~-iWFJ1&>sIfwfcxxCDrCfLGBRu+o!%MI4U{t?9%sw{&7 zLJbkRI^xWWMDg=co_O@v9MV)tzeq8C?mVVM6^_$OsrI|p^3_Ng0(yaZ!qEe{=<09t z!(Xh#TU$kUM?W5^C>8leGBajCAVkTBa{Kw+VT)HOMJD5BRVc&#ZE89I$FceOPjBOl zkAED?vaqax8``Cd+!aK@fntA;NmT*tHk%59OpDaAOFIk;*qu;R5azkHSzdf*HFy2y z1_HX9O4&~+6eOz#@Jd0is-nEEjL&`T1|}acgEzJ$@FP)nni{L3kiSss7UQCbtFE;s zAU2a!O*lG4nWfpdCCE>IeoY(lU59B`wA@;jjLI|Hbv~-cvrz0MY!%{Qc7$)fs_FTwBp-WUX9i^gH9T{ZRixtJLDLqO*;@?_#1Xc zv-0tk+v|%Q2HI@f zHPQVC1swgiJ;sIsYWLV3cKN(R;S92221;1m{rnETz4CRS4uTPQXAndjls3MP^(OBE z>oa)5q+s5gqe~TI`#IJ6-8OsXs^Pm2l zwav{u^Wv+-VqH`>&7t3R3VTg1rP;M>7Yk?4=Anll;lT&*Mk&QhFRtZ}_x_g0o_do0 zjApPeiwulzQT;s*;pz~O;m9M8D!gH}~F&5ODAB@8X@-R-Rb(9JzEFtF{iMG>+q-vWi?Pg-^g> zvX?u5aVP(=;vR0fx zkwK%`+HJ=PS4FTBF=9RKOr2_|fbn=IKm7g;oOAwp+;II(eDdtmQA*L3OuBotrb<7{ zuv$ukQ$ojXsFfx$yF_dJ!g9|VgRqXJf0Y1Pl+IFPRnYD96%wp-Dh+aclk$(-BR@!! zV)QqL01iR%zTRx2ANt6tG^JV>f)0zDg7K(Ie(;)aLh>~Ce4SHcg^ep4hK6Wi(Qi9w zq20R8{EY#vz;Qz&HTxhd;|I+7m*vrVziwXz%3hIWZ~k1@8IAD45OR!7aB-pUFM58D zl!frWZJ2yGDPn8nGh`-0QbwDSVmG;waWrMI-}cr&4rtkz0)|UF)`fd( zNQiM!A_|lym(Efy1WNT#7nXD>MVo@B-s<9-%g?9(ud7&o&S^}Nl9bjgJL))k`gXIl zdb(?1rSXJ9+Q$v zqcsiTC7gIvmg{f*JQtpG7&SgYFeoY28Dk49Lk#Oa3AEVE%LT4mu7EHT85mHd2ONq#{OrIL!0UKTlO%9iKbzTs%@@ z+qN6tWG;qQ3ja7E&9Kl0Dsux?eSJPWQj%hXlvV`XvSCPw_HLbc^(Ad#lqap>F9f#2;|{c?mpRADkWx`B*cMQNgxYDFaizbzP+J+#;$ zM3~QCb{SU1wZyx+P)bwfin2a&UYO4Xyu`b@h{xj$0Tq}qZ0wbx!_`6ZXIrz2)K(_RT#?FKn&hSM5ZWj4$0>zkRqU`|2smxsVdCn{MNQAih> zlvuCRIzS<}6}u^LlEk!z46xx5f}b$)vEwiTJ{e)(nQ&74JN=T3fo(@l74 z8*n;0C`~%9A%MWrf{^x+l$k=l(f$wP51QlgpF4ENKgx@W4N#Q3_Q6US5pEv>OA4NS z`~kGqeD=JHX^+R59Fdd;GOX;4x&l%T1gqVS#es|iK?y;32TCe>QY9?E zr3`jFO!MQ{V(INT0)~Z!QVvx@pta9+p0g>l%)L42D5SKC5}?O6l*MV#@9j*aKTxqW z-o~Fnf@JK-`?@;H=qD~0f!vp;Gf7x1URm zCHeD~X70GQok#B19D7uZs&qTG@<6s`CNb#PyuR@*PCfN>{_w~jsH>}|v2iBbcWogY z4v#JO}04Dj$$>=1{KK>^%J&IJw;n*V%bzQ+mNOks-OLbCN6-I05O~i>dM$kG* z@4x`%VuY6-|1%-2dF{1VX>4r73Q4-VJILr%0Sz2d8mmI$B#rx6b|A~1SSzvEcAj|R z87f0HXzeqUuC87@I#o!59zZedH5RReBAHBb;)y2$K7zp@6=WzECO|SjfWp<?mt zmE=oTE+-m|@bb%#an(Ov!t&)8GqowobwBH(%3PC&e%ryaEK1FYlHs(*PLB%tg;x|(-9fu7 z2)99Tugf4{BwOPtQhD207=eNvKra7&5acv?(d5t*(%J@#uW3q=aT|# zXy`A}mVc|(*mY7Aw|l-T-RT))(Wjf@y~{uvSdup3kh3Z*o@ zd^mQm0Bti;<)zy$p;k(A%A7H!D#4~LC4BFv53swfgU43z7J7@MG0LMgIIp*`(Ega;c zW!&lPB`dHF^S@y=`NU05C zqoEu{s=`IJQYD4^HmEeoLVnqMMR1s=deAZY?_mLQT#SKtSO`+76g5_u-L`{YNOC%h zQi>N|eUTko+FXmk(FI-z36k;yyKdOFgOZAJrSM2esUD>(?d`Hjc9@?FA&iTKHZ-7I z-WvIR@#aOLi7|*mi4k{cpGxE9YE|JhgnTcw6rwSvblv{ z+qly!41e`IpPDMLmMjNVS^^{5gs;a68%6>>0bTFwD9%)P=av#{$=EG}bCMtxLTfi8)k42yB zI1>(s8E_OS%fTYThSyq&ZF`5$eC9KR=Fi}#Pwe2P2j7I<+l?bo{US)V!s0owW-UB& zJN)bM1{P6S2#rAZdhYnmH~7SS4|ZE09yvm=BEWfPU&-3_+t`|TonJk_haZ0XF{qyd znI7~0gK~82mr_PgR39mI-#edhc!Z3t@koob#sqFEg-4FyN8@M>j@e7fMcCvP zXpKfqxbg09TKA89{8!MQ`fz~mc!E;xqgS`npJ-tqqueQ|kMdZMcGbe%r3>j;-$7tO zE#)FjR_)+WIl?Y7##IPaaKG`$QC|5>LWG2I)|zY0BK_nu;G4y=WfepsDVny}TsnU~ z_fPGozu9J6Ynu6sj-mOv*YTw$v9*0SA3gP>9Cp+a79W2+t5&Vzjyvwc=c~jcEryh$ z%(CcJHY%-{I%5t!nGAck?%|kYj%A1>EuF7ZmZ~8Xs^+;@-em6dB}|SiC6Op0C(IfV zUO}%?glnVx`H2^}=9+Kt`=9@U%4yRW!pGm9dx<@JQj}TMhW^>s#jw{+v-e5D;RwS% z$sZnhk|oC+!CB{?kJiQn;J5eP#UYF5kP|@$w5BwForHwGG{dP9ws!AgMqQk&g6ise zLZNEjT(h3lt5*}AI+YU3V!$z0+PSP|YSSESJI35Y7I52bH?w^C7fB|Q%$n5*z;n+% z$?n~|IQZaYc%;RE;~<2@BLum$A{31>L@9UPd5=5kRm`6?iybX3{NWD|QHhUP(I{Cd z=~IeID~wPITS{tb>iOk;f8?mc4x+a`&VdIW&gRXntX{W{GJ=!`VZ>47(okBFWLTs~ z=uQZQ$mkRa?cmXUSXO`m?Hg_U7_}-Mawp*C91;JgwPEkCb{Kgd&B_GDw5#pRTOj9) zJ3oRUY4U|cUZWQYjB(ByOUcbsyfR~6NB(sU?Wa+B?=wS;p_YyR`S=ECl$JIT^=hoU zmkGDd7X6MGhuDl|BNW$X`+HscJ2(CBQs+62LaP#xBZYx(K}_%S6}54r&y}a@l}Omt z*M~oB@tMo6#1Hh_arVaJXssx-BvYbMgb2G$hrmwsA;bulCEeow-PVUH47^9>5!wyB zRh+o|8ggmKsXqGc7<=Pg=&WW&ZIozq2Io`-NF>s6%Z15o zDLBIEJk7Ie6j8A(i#^HiLSZJQ2~@IelkPb=QtNi>21OWq_-n5COK6~ zgcJoQFAo^V*F{f+D-1K-+xK5&jh&ig^Y}-BtEkcLRNrKTgu_+)z@sp6SkOP}5p9SN z?~3E}Ig}xYMx*@dmfNVT4b$6YQ%bSsWb|_xatBj?c<2H4cG<{)Rj@@Y7pC#+RSs6j zqP4Y!sZC8xPAhKt^)JliO&E=kloH`{z4+Z}fs~SHG>R1pv+Ts9u_`2X!UhB~An`~8 zQRcoNx@kzUOxUR8&;Z?IZ~2?_?q9v2EHrk_Kv( zl1YI8PM?F*XRN!+rEr^AMXyryc6E_Z{iYb!h9jC2lGa_j@Ow(xvZa|DZ@iHq;IWk} zSvY?_3l}VA$&w}1)J!3f=p&$&DTIT9nrJP!Yg@|^{Nmk{UH>O2M8%I<%j7GlLRhSz z#L8#EXsU!{w;kgLxBrB+fV-dB%h!Ha zrq8Codk24C_Xg*k^%+h-{d5wE1fT!%MFc8q@KsC7tPBIX4?jk$(c9+`sg07%K)Al1 zKmF;?-1@uw0L|;KZ{UgNo@Dld1%#|>94C!%=_fj^i8eG5?~IX3rKxOeBp!G8=y~U% zRF=2buc5AfHjn-FVOKb8*aT*6r0^q|HS0j0-MWREP&MJ1Va_=7Og6W6@bJo&>`i5; z4AtO~0s0&>6Lz$wCLkElu(PF&Pk;Ixc5L3v7ryX0&N$-?wrtr#YwKpFPoIwMnnZN> zImm#~z2yMQs%9{kV|ra3T5JCGTi>Fxs)FC#aTgys`D9i;^9(ATr9_zD-<@zM_ZmUI zucn^2US7pP2Oq{~KYJ0&mYvL>|Mo0@e)tilO`FZmojdU(s0{e%(@qiGpD&Ir(%1}W zFW__OQNnFjz^{EpqUFs0Z<>{Nr@6A{mK76hr7aOXkR%ocJN$`3Qa`!8Xx@VA5**e z#?iv|KhX0Rp+CbDxP(b53Xu$@8n-?*HESlD7p;tpLF@8}nAR|Wa&L=K9Z^n32}Gk* z$pC)3=vA6w7kSLN^{8J!EY@16pWh9I&o?Q41PEO))zBKcgln3Cpwx;|8*V}f=mWMY zMV;GlmAe7A#o0SULccGtz>nB(LpX$yotO+Y3QQccKaS=Ld9~I|4ptTxfGIdMHC7ef zb^;+rOh$&=q~w$;Oi;C(L-0W!TIZ*fpfTyG!){V|PHQT|W`eG@D)_(~iWCftYZxZF z$+gx+owyjoJ2a59C|Gz7xkWr=7*J^!ZWZr3tm{6qhHi3{9=P!c0>0znfE<=8jER71n9>J`cv$*@7`#Jyo3%UBLZ?k;)a=vuog{0Hz(HmWB z@KNw*FL&33qca7sa2b#Y1ikJxpB9NQECj)P3N2=Wnu;eV^Z6La<+%Ftf2LO{URk@A zJ@Ghq{{HvWhr>*ZMELrbzC=}31v;UrsWy&#N~J-XRCFQo5cdDJg!$1&ZxOmWEDZEq zsx>*SsJ1Kw7UF;g{{5A$eD~j<0cJw*XoEwiY!`{LA!zPTq=ZLaF{sD1qs+f;-N?lk zpUjaBn*O#mq~bmrqI1~g#0b+wCv6O9#hh@I!L}`gXk+yQpXJE29|ZThlBX|7385e) zw?j32clj|4^>wjFIY?>YIEpeW%%IZ;!fTpt_ueWkgsp)`c&Q8r7|1Kf|Zb`7~%KuN7SM#f!N3a~IK6KOG@7D&2{ono`X9Bc(*|*+Z!=;ncHEptiOO zfuP}|4ZQf`i>!b3RW4cnRfFWF6{OA0={Ppg#wak%pyTk}?_EXxj0T2)S~aV2k=f?2SZtf?o(J50Rk1HI)$z6+qm-DYe6fj8yZ-(>M82$r;|)3ahyI%vkJeE zR0fQd{H$n{(hRh|y_J)`@}pXodpD4p`=!7di2MHpx9Q%iiPNflJW}HG=C7T1?0V8;U%ORdp|b{= z8F0)1w-mvUN>eE%Lnwr+^%)R~a*-c4zk6L^STT~~7=YrTrw{_avk9*-Yr!=<$K&cf zb2#+dKFX{LQ|~**9XPLhGR&3_=L|D8^Lex<%jAevp!XFTm0>YbD2S!Bh{ZY>3JW5U zTH_h-c8*GElrq^W<&0Y1ey~QxbZ9xoX0!~u;%Udt%NQ1dN|(ZwQwmjhb85ny*k6SC zj3OZUJPo zCz^Q3pee9b+H~$t(p;}_wS^T5v)i_*kA%&237E-SxGIcJIGC(Pw;OgHSIR1+34}~* zbf3fCj7g21TpMQ4QRu8Pc9ve#eMf3dUdgoDC_|XtMPkHD3uVf+qQ{BEQGJrOzKlk0ahRE?KOx)V}$7e ziyfUkbSAo3_0&`7OopG_a09z{?V`_d7*UEzRUz=1jn8W}AO(f|h5S@R>;HLFW&8v! zp^XjVBnf-tar%K8%K|B}Dk}K>rar!M&BF}t4npV%sP=+Ny1yMZjR-yFJ@v#Psi7_k z83nuhFic^a?|=P3Vw;|)#u7}9M9Cm27f~hyy=eLn#FSvNu<(i$^DH>`q*@+&p$mLX z#w9G{K+*wU2vRmb`ImDjO(aOhZECD20~&HFjo*Tt0i9(;Yf5#hi2kM#D#VP21!U|vBa~1R)_mh#v|!_Tj|m_XZh`T(eA+T7!)2}y4H_P5BT9E4A>Xz@}?bcRoyc$z^yvx-u!D8;xU zrn=%RIe0FyZ5e8%;8(X?#pH-V!)8Qg(oj8}QomOaGfqE)WLFnjE2?W7Sh#Q@4Gpg#gv5^~)zyXHYtf&usjmt% zB@`m)5nOfI#q92A!-uh$|LRvS<~iw{NpfbINt#KUbV*y<(iRFu zR#^l^R1jrR#EbY-RNU}#;c`WgD=5fyx%%~9mJ5oYA|SFO$c~h)(3Y-A+f15Fk~!1N znPi?x=E?H=<2f@)OIz^b_j4wJ{bG*8&ScVmhH7L`P9@XVN}C-!c9y!LM%WTU zYfU22T>>jb22|0z+@$RCo;w}}ovA(i?X^}WC7A%i4o=}gpH4Jhx{*y~uy>$Y)qXBm zt;^7ul-LO|3BF!sR6vcaWI{|`c)pZt+B?15?#|z~1EliWbQKVWZcu3uvJBdY5Dezk zJBa^G_iZqzs0m1%h*LVoUdF?Y*v7mdAV}ssnj$g!6A5I=zg(BNo>~{7shOTs)Z5hf zxgR5*hsqmqX>k$LT9NGYXlrdF*_R~NV8Ry-xTyCXybcUjs{O#K>F0lRim8RxCixmP zi|4iBc^*SPc)k4c%Xs*)CyCZap+a!s#TU~Ui{Yk|OioT3Duob)LLu{EIYoum=t6;j zm_!H&gk&iRx*SUIv%*gS9tAR)sqw8+nvheE9vq|+`0QuTXUUQ!v@cu5XU_UG(y~~* zXc1RjaRn_4<`A-N+;p0BUmAo-^PUtiybsFZ-+QvMuQ9*lIG`1~Iuk5vYh%Duq_rU2 z+{|ace+Rd}Y5`%0I>vCIOPRbGAtB>}Wt$z#xzN%My)JZh`U-Uyv|!$et(0ps<<&Ys zkDH}JLXB|f@t&tPejFJsNb3YuQs6L`#D;F}xZ-Gj|IBR$^aO;trE}VRjpBk;b!0ZY zMUAvk{wcI=Q_NNQ3-_pJy1TW$mTC;;i(zeojzoKV3+TljU}ews;C~-*@w`0Mc8J}{ zPAHc2fov~X!W6b|4Z-4Iw9(>>d?!5I@>Kkps;V{DmP4nEjeEi%~$>a?yz)cyw z$VkS3>~gKS;f5Rd*Bh<}G+{f;maeTdHqPe88-GG&rDXm3E!4$g*dd!_Uy|X1Ca7WI z!j;SnJ6v+fS7~f?s1X)BdV84=VV-&BWqRB+ZrV_UrN1^;Xc)=C(I=hAbI(1;+LxZA z3b3SPA|U9`jB)={FY)ZlFVh@y7}kcuTNjJ5Es-D|k8|lieS?d>@CA-KdNs4!Vsv(P z(c^lYd%+i|ZHTionPx%=dfZLai5O>|x`5*jZ)N_HX2z9E+Dj448>{B2LS6WOmKnN? zF581P^Zzz=>)nBs=~|Toz1LJjw%ADAYmF|3a{H8a^t2kv2PD%w*3%oud(rYv!%|Nq{Z zD#iCV*60eY6tz-PBaPN=T@kfFgae}hU>5Aa~EF7kZ%mp&`?h z4AL_DQV|r4WIdFIS}Tm>IMg=Oqu6Ndk+mQei&N%$5U2rm^TZQ>W>#w}o40Jowu_4b z+;!V+C0=WDb2Gh9y=nOUzPnAiHXu#ybHV%jYgLL1^|0p>LbJ5JjqRNYW-VXEOKDj4 z!RsO10%9(NbC64zr&>5}+(F2}A_p=KY};%c&r-@Dv4~?pOhm%Y0H-dkC#YS9-7?DU z7~!}XL90ZT8Eq>_Ci)25_5OO|QRT!axM`|%2$~!-rO_I!;`7mjbB49Ypc7;a7F%R8zIr9WWR~i1J^hI!3s)S;h^MfE zf?U=G6u-asULLsn*Oa_PeB1cdN1V$)Uv(w(mmEg7=Q5nvR5!$#B_z8#JCPEe-PXn3 zci-ff`6di;6v;j8+k8@ z2nDGSVQiq<&M}I{(`5ujm^#Ptr)PpPQJkch$w8S<)kY;t_tW3!CEj5je7lC@y@Hi@ zUVEn~VtZ4GMyKgUigd8)lM*2W!k?~GmG0F&-2taJev35i{Q;GCny8E(fJ(RbaoX3^ zqUe&hFa60oOiRT$o-;?|XlAF*nbzFMXS0;eU2P2%}NiOH5y+ z;Z^vJ^8v4qx>!Bc(g@=ReP_PW61B?E&7&o{mB)yWON1}Kn0SY4s;YGEeTIyf?mTM- z4u&D-F{s?qB(6r-egp@lNlq2Um|@h{J=KW6&3!c?1UKJ&3!ggk?9%6tX%NECQ5jSo zvt~7s%^HL@Gu}XdqK{;9N}nO6U7}$Xg*8G<`Zlxg?J0cFK?@ku(7AmJFFy4G>(;$S zK^KTbB7|+plBGv6XF)5D<1pdB`(BCw03ZNKL_t(}ei5fj3BARgEZ2I!h;mAkGU*2j znf;llgeM+(n$4TmlS=gh5DrV0EM3Xs<;$tH?UG0NJHG<{0`a%aRZ)4P2Psm(^q85Z zkavC1sNb=}qqRZj!x}1tV8ZX>O_V&pHM*dgQ7_q@G@@~>HBra$lWU8U8zZEbL35#& zkC{VT)XyZ7uAfpbv4zCTdL^J$6wd=RIWcNXy2lcX<8v^*nR!wOn@DWz)SvfthQOGxzt z5RW(Dgc}WE*7t5)y?Qm@{N^|L!PQrD&N=7uvm39Yp!Wp9c}d9*{C@+bVef^dXvh{ z&NDYbL4lU0h-``ZLSYZB1$8l-Dg?We3FF|TAcLSv81PiG?Ua&1CHURl&+wavpXWE% ze;nH`(pEJ}P0=m>x6$_Yy*?V_j1UUcdcqpEJo7Eixa2-IypZI=Gk?XAm#yMOl?UCz zXr_^2t=OIDBtj#jWDrs^A%dh-8EAVU%_5_I0LRn)Ug?IUB(1d>H-x7&6*cp<${YYGEFYu z=%ZjuG6;Tp>+e{8%=;;q@cib7XqFKMQVPq`45fP6u_I+Ppg!2G@Vkw}BFt|ddx2=g zCan|^$04mUjCdX)VKKDrO@tNj3o4`cs1TA=I!kxY01rR4mT}?dFiguq8%U-2^NW9B z`33I>t(erBvavG2&|y1zQ#`e1Eg_|tv~6_nTC~<=JeLZcVOOreD_gobHr~c4c}DVz zP$9(nZ~^oghRp7y*84CaRo`8p5_o|-e*)#=~CY<^=p6hFXKRKBqulg z>vuWx%#SmyG;OVIc-d@epDKfzQWE(npo>mV!q{>aLvE%Qnr7r@KuVFbT`Zc*wea0n zfPg`K(0JEXU(k(USSbWXJ5r8GU{%wmEye9MW27#|y_2Yr(htRA>l=Y?8?&bv}Q3 z$o0&221JR%Rjy4anjLf4olH_;Nk+A%!t#NIRlI>EDz8g?!5SeELGzv}po#geW1*0Z z>$~p6Vh&!`qc&(Gn)i35(LUKBM!YP8N-;auz_4#cEyPr3codD4 z#*2PfD}oyHFcghE=elh3lC)(qxJ)uW4lg{phI#WA^T>Vo@$B7q6RfrH1~N=e!WrkB z$q9!Z!9QN`X@8<()7The{0wVkz{Z}OYl@8`JHt9kb2mx(k)=%ZTo?m`|e1XqC+3BQ&9w$CNQnufG%GE=y_hr9=d!V ze&h~^+=%AK0qYmIsH6qhdyF_z6!sT_g=P=axw+Kw^kZ*Ev?DkPM73Mn1ZS`ySA zwj+2=2T0YP&hZ!aaQYX!`OhyLLSchTt&EZP>5y%vJ%(#ZVE^5N(9*T~H^WFGW1?8b7(_VwTUfX!X+8%G`1&U0&?V;2!NY)rCsOD$Ws zY==Mr3a-)p3@Sjv@HWaA;P#(>pDKFz^f{m4*SG(gSgetq17UXlZW9D7|7Q~>B(u90 z>H;vFhq`C^;Wb|*kgDPgZTH`OB(tKWxfWBS`Xef;F%u7%5 z+;hKYp(B|)cQ%i|)WM{4EbF!gSohrPP$NMo7|cLT1crg(UKrOr@%&T#^4WhR5}BZ} zG0LpAV<>2gU)|RU-3r=Tfc|OxpyG6|e`?&A5fJtDV_Jc*0UNXngbG1jp|Hlta^xbUfhB?F#4_fKnuv?Sv>jb%v+e#fmkEOApV(vqm0!ihL2--MExRO+n zXHw=EcLNMb<8(EwB-OV0#HQ8;I=Z`g{)M&lcXcr0rD$>{nHfKU6Hh#WERgL>qm&}3 zGz~Tkcu*H}*wwim$7%2#7ssf!CsE2}0vqi+Ynf+>WKiWPvnQ#nw+XfesY27a_GO+} z|2j(L7*_%68(Ubm>U}h|Hjwi2jAUK%NXoSl_18+xfY*r-4)xhF0+o|s6+l%|CL|d# zR??a)|2m$onJPWs{Cc1YNc8tG;wh?>rjYi0gAX65>|0#)w{zPlZrILb5-A-fw5G|i zX{--&$`Q*546NhI%RYK`j~*XqP`%6y zW>BtY5TJ%S5nzmdWJ{hCj%w$WBii}m*T2ohS6s!*FK;#49G@pReVq38?uvN#i=qz> zwbr<4%X3I?(+buot_*Q3G`%y4W1m=MHaU*Dm% z32f}_?4+%&%}49|AIlZ(|GbRL>{y%$OH)&C<7GW+>TLs3D+QxjMR{<_ooqPmQX912 zMVG|z`fWQzf1;aNZLL%&lWOdF#%upTub{Nq?JCHmsBMV@nn+Y~$HhM(i)P3*KBvUUA>{^Q3#=Gc?pZ{8@A0R$1Jm7I!^OYLGZAXv7bjVGUfisO$wl3ksh z)Wzadp-FXiaLnqJRND?@g(+HmGl<1YR+8Aho=<(`6z=)`UF32(RxX~82ngcQT5iAX zKiSyX%~!wpIaVKkJXU2T1Fj3RBGfoG1xyafpmHe}`w9)+UtufuF~&AyX4?*tO!m>% z*6M4{l&`VT2ka=#^~R`@8f{myMJXn*iAskdx04#F$;FnCsSL98gsWiAN|PR+>owbA zwfSMF2Y3~<-wDRgJDIjG!W1zz!dxE}vYz!@-ePvlW?Vs;5Ln8lO2U{F?yhAJTq{ijKi*ExbsHX}V5>P48I9Rpa64u81s0c_jm zjWw?`cg0cEM++1J8JH6>g^#dF>5M5aUV8&sr}@zG#q93gMs;`=o~QWZgRgVM$vNt0 z2@16~L%ALza|Eee0rXCoX+nEz+5{~vF}81di%KQ=?Qb4tFgJsh$DGX*Gdl=|6)6oA zGR&xz3=Jv+l6DP1YCC70^;x`*H~HGPzRnRx9MAHjm(sheoUJ=H8D~37z~F#6_^pkQ z%V5 zoYI?=C^ZH1WdO>f1txSCgaw3SSV(fIE@*0jt;O}>-BYpt=G1Fxo<&uF zULMmL$X+S*#_ag(K5rbvY!Ezy+5DA!|C&jKN^Wf0FzGdtG6D3IvxCK|Gd z$D8Tw-0nAWCF4q!0ErA5edUna)5xG=3>Y(XFO^r!@N1G0u_qi8)1DcQ6JsK;8L|wh z87*i7PL#s-9YpQ0&4fQ`mO)8>BFW5n3@blngDm#*EStz{L~yFOwQU|EYZpiG^yI#5o@ZEWX@3^wK8a!DN17_P(E#Hls&D0@xxh1 z{boIWGkugSSvOCE3^PLrq<{(pq0l57*RJQ2$F;F+PBY66K8RW=P+eOXN*&Hv^2eNV z<%v{SE4lU7=ZH20*`D4`)-#ka&+|--h-au`6T-wNNZ)U_ z?V^kM%hL}qD_Y61N35V;Oj02y$#vxTL3al;WgX=jGCGG73sZ3W7*xGX$QGh@1wDz^ z`02OL=PTzO#^v9?lcPTL5q2hx8`S8u@FHU+YaBz29w5vpT^!un&bQ9LkbLGLe)_#n z5z-(;f-(`q^9HFA!xR`Ir*edCi$+;Pdh>ej_`%n?{DG-85}& ztrT4MZQbhw@j3TLO%p;GOXg`bDwS6>)yEiA-X7M&rx?Kr{MPT z;!}?Sf@Cs@9d^j3QmmXepINO7P~D>@>m%bas5HkOdnk1uI)Wxga>_?fBxKv9-E8T& z#bR-Ob@T1K@ahYEFj$FW+ceLOgLn(xsMZWKNkVAG9h)W*qmb+)gdo=1%x!%^KKseax%rBd8Cko55iiD=lvJaUdP?(Fe~sm1?f-rA>|}!#gLn&O4!B$EnvamHacGU zHOf&tGc7Lt7l#+9P8qYXFZF%hu1{kA(ustkD{ zx%%Qya`0g%`MD%z40uVZ?I1&Lo^hqgB@_JR(OX%zu$^IDOS#VQFaLZ2T6_HawO?Xp zyq#gK7*{S}mx`NYUxJ}jl8rAt%aJROV8d%Ka`x%xvoqB8 zWc^GfFYEFAlMnLEFI~u4r=QHC#fLMqWiEwOl63DnHa_)BHYECx(zwSNvk^geHp%YZ z1lu>o*}8r`n>KA?rX8j_+{DICmm9x%D(&q{{4iuQi5u~Co7)nb>D`=XS85c?lKkPx zM~Ort{Hfy!CPb9S@A@GHyBOXnd?OPW$hstZ6Lcjy(7j!}v8jh}OPHm{FQmS)g%@AD zm#3e-n!K>77Y>7}&ksjd)CikYXD1t8dyIUdgJ@(vW!mD?=bcN1v}tVg=(zc33}o}Z z(MfVI8swC%s+58ePf%@}`=j7mI8HT$U}qja@cy5d)~5;I+=S^gqW=N$SMgpQRC%N{ zz(q<))VAqy-S-^os+1xYYd{D=f1;Zz8APiw%0*?V;aY5pmivr?pl>`>)CdSShhs1D)Hqn<RAbCLXaR{0{b)xrt`)NyLY#QQGDZg0@r!SN z8Q~2urUuEn101q4LPqs5tcSVzUoK>%(&B^flN|erOZfH;*Yj3)AIW5znem2_&U)B0 zjcfDK66G1&eeF*-Y6R3u#pCzMF6wGZdYTgG2JH_MMzwzor#VDd zP;~$GH7ZpH5L*82x)LG!{37kJ)&>rVmvhsm^MM5Nn8;@oz#I3SQ+D zNGSpqfYGc+Rmi5M()Z1lHszIoPunVuqW7>XG!F|qZ0~n7iv`rUfc6EgM)=j8KxI9~ zg#lEdhQ3f>89H_>7-*( zsz|^5@7<5u=d_NiqAOEnX-u9>Cf*VFNLk5%QeaE!q@a*o&rI7v+Y7jNZ9kv=-eWNT zD98x|P#UFi?J7t^FL}3`x`4m21)mBe1Y{H^9AYL|IU%TXLX4uQ#9>^Slw8X;R>xsa z6O|4lNsp)<T%f^eyz*k!P$keH1vMBUVTEmq z?h$W{h3&2Inej8i+Od&wG0Bp7iy2C#s6ycC3_@7+WilkTZeU^SEQFY3m;i5V z>Yyzm8Qi&pOE0~Eg4Wbqf?8>jN-4A!>=rpjG8t^3%xyv!G+Qz~RJs{PJGQZQ?ONu{ znL~9rN-n3dEK#D_^z`gRh$dhMPd+&S+CU}0NR4P>Yu7f$^0ug_1+$nC5mcg!u$STSKRw7>8`lyJN2$;=85adqZh&w&%0NnC zBY11W8lq8)==@bk9p>J9{y-!;i~IllEbBWunBCGs=f;h+&z`qeV`}PwFe703-R1#m zWrU!fhY*VK*dWSTJuR0{P_6_1kX64&r=h>Lc9GM>#Rg2N{g|EnHS6=3 zA8eNgA($15kxVAhdW>3snloLyQl-s!V?s<)MW7`7F0SiJ<9b?CeXhdCL~;;#6k)_9+^iKUt~Jf)O<10;-Enu_42je)cQdPR@|dxDfwvn=E=Gj70BG~}4IL@Bl|#twXelyC~CTgq$XX2v9&!DFRsTE{t8`$*{k^H!V&Xm)Sj%nZ4f-H8-42p}bF-}Dr}x%sQCJmsVGr6=j| z4F9s0DO6joHAtHpA<0X{TWh!Q=lg!njo&|$^t!jmX^%-U#EKQ4q2SEsjWwN2h&e1e z>^#b}B9nNHF}0O()rrsr`V$*C_vH6+$@gyI)1UhqH9|7vdDPgUDKh~}yiII1A$$(r z0bWh@F$O%B(X1lc9P<|xo6hZ>eD>_qdEoJ98N~!0Qn~l}(4~pV`t_T+?~zBj>N}U? zrd=vDRE3PrWJ*wPc$G8iB^Q77TU_+T3veQ_1CORd4%grCL+-ifLGHWvE~53uVmR5C z#Ho)F)S3yv%X-8bVpJjc`ZvDGz`y`E{pWw+`CZZjJqX&{Te$!J$B}+Wnh=u=`iqa= zMmCeEAA; zYTSHIHjkGYq}O%vJQpGC_jLc&2xFI6BPG%w!G7q&r?7bO!F>0-SMSp-LWn6xyFnqy zD@mhp$aQWeBr}xT^{i8H#y>v+fw>?mA?%r{(u?b1b{p6NQeD1o;6ObPJv}JcEbPT% zMk_wJw3VLi+nH&{gBrZx001BWNkldCo_jONww*g! zb?BkgS%UHcRJ7R4ip*xfOR;lj7aeb{<)mYdVa3Xoyt(OB7Oz;!wnPWHoLS>%H@2`l zrwE7b5_6!jv5~~K4*D|%jymcDCj5Kt?6W?|l~?`?l~#gTP79VLfdG1%)}Ys)@~t}T zWIlHK#~93c1Og`Z;UmY+;>|ZUF~4OQ`9J|FVYjjg2*E(AgHfPm!3q{FnoG-)HpY@k z=Cz!RoAMZ?);Pay>t)sK#cb;7p&A&{n(~6C!V-H}+g1~%FY^*JL>)1!kAZ;=BzTqT zIVTWlI+xTyv9tR3u_;!{==oeX&5%m7c=>W}zU3DjdE{~L8Ke~TnbUPDYhHdCJ7iNU zjW(h}2KQ*v6^}!?9%Gm>I=6SS|d6`k*kR?ml z*_R~NP;bmXDn-fa-wxTn1|!6scizcihadj7Z65dC#40q5lyXLd-{cc`8ISh%b_V+l zU3_OUf$d+nJ?SLz<~Yf|qz_WW0h^ekS`&*k@ci>H5NnK4Aq6#BfSdx61D;1L)&MHc zFq$T(o&hh*xK9V0_$%CL_a2Z%?NDjbTNi7fTx%YB=wVi@Sng+Th4w>T^MOikipo@^ zrf z<>WMao$Io(9J z7Lpcg_}Evz&Q+JZM09R7XMN^t)YdnnG`>CL`*`bxhj{w&dpIZ_1h$#+qAW|ar!y`uJ^~-=6Nrl8;kTfG%MIe9?-Z#efSs0b;B9C6NZ0XX{jhF08 zqBW%siV$G?U1HDg9-ngZ$t07#CPY&on14U0Jg&O#Cp0v~aNR7kV`hvwsPjG_xN;v= z?w+3OT5HHDn!_<%*W=*jtBgp!w~Ov=E|wMLi6>rV_Uzf%c9{N5hDfA|QQ(nBp5W4N zTxzP-o-Vo)vw$S)w{2s|ykn^s25wh}b0`reo5~OjM_9LRGe@8JL3VCl&+cR`^d!M@ z2uhnf?)V*-edls^Ck-&#xN##ba}Q?F^ANg>3M+~bg2$eJkW)`RmA<6QM6L#UQfywc zf#vP3*tSht!>HOHrBJ`ah@yCW6}BxI^gOgKqpi*6yz?$#UOdi-=e^@Xo$)DAwuTyM zW5pU+>sg%gjhi5_6dIdBb(%swl`tSBrwzplV^HueMn1kZR#Eh>jIciE@uBz4Cn9>0 zl|c$XQ&X5gr6epti4;4wjMKhg34v^aF`dG;V|c*^&ba0!GX;p)W|=Ff68O1jbsJ>+ zeClALB+9H3Q?$ehV8{=(l2S0D6)9zmL8{QS)&ukH(sqJ?xpC-7^6@L5;n^RZ!oh8d zN@DbPCy>&n0t4!c<{08_=S{y&JYV&Hxe(i-HxZ|W`q&Dt{K+4o$7bcKNzVV$X?*4S zyC8Q6SQ#Gt(FGiCSMrh<;M6bO1CMvm|A{%2ivY1$j6Sb}0WZn>k6p+ge)oGOqLcKj zb*Y?Fi3ortEh?-qS*;n&7;qZ0!i-og3=Q-WvBC^y1`yFOy}d4DIWuwj@JT1rpGca# z9t1*IJp0UF&;{u2^{{P8Hl-NSiXrXN)YwQk93eTF^wPB4G| zeB)GY*`#}uMC~YDT}fs+HeiB12U5HE))lui(A~$d*0i>^a^ZzvW!J8^Xlp8CB5aY% znM*g_n`B1Bp+W~J6rfhta?S;xBbUx%HPkcdS={{Fdx=TOZl!=QAq3-E^W2+nQfFBx zrLnA9Y}@AO6OQ1>Q;skJXd4_Jy7wh=In8cA&m!mlo$gIBBM_jcr-xv;hS{+;R;^k^ zwJq7ceG7*!UCsJeJLv882#3oMVhqc&DKEf8z^rMO6(!rT_!-g&F z*xUg?-c#gcflNj-iV-k0M`n}BWDp`iK2t_CELe5ehiG(SJou-_skUuKJ%zNws2qgD zKJ`Xvu%@U-l_d>ElxSdynXCv&%lyU64m<1?vxw>fPYeWn8co1oQ~o-t)!tO$|Axxe zpX^WK#2e6Knr~luCI4~-eDtFq`J08hmTQQ%HuK5$7Owd24>|M9k7N7A?dV?5zH)7Z z^y6Cd*|R^&vuj=>9&aX*=mssQwL=W5d`TPUI1N+*KfmQx01o-lzZuH7E<*^@<8bBG*YU>(9%RESYxZcwy|WYB+ck=V%JU2DG{%S~&*wjLCfgDz zux-Yb$DXDNZ!2)Xj?vfGjSx0YC`3$zSae7Ozx(&k5>x|Zyguq;tqf7a5htBNudCS7 z=Ta7wOlHTJ-M)xw-OF(28??lhF`OLc%=aHjBd>7zC1-KdP4}~IOPUciMmTOW4k*vK zk7Yywr4$QdG5+%O?|JT_ySViy-(oPajVi}xv+Hr#VaG5tzK~%JSx-@inE+MWm27?L zF8aMOqINsU^>6aPZ@$e*$F#92UEsA1We8m`E@b z|Gpd*HdR`2-9=}!Xl{_1a*|=4Bjn8C!ms~34{ucrDplg&7DM=oLY?H6Zhn31xtzEN zR>zK{v!j<2&p(n6ed%gGfAQ0tamF#z76CmqrO<-y-F@8kVFlxDP6?N`k$rz4R{o(y16Kn&~QuqWhN&qEsHo3GFvWq_~)bfY&{Xv%dBs z&4)^Ud)Xqs@qr8Y)aO3UmoK@9Nb^!^!(rymYNBs&fGWQjoDlHhGmq0UcP<-Vf1S`- z4}g|j`{@M~^g3?2_96~C=mZ7^1_*}3M50Y}_ViLwDA2oO2VeTqg)CjVg!0~3Df{R@ zaq0!XhL<|<(pR!#?kWyD>`?x)_GNYtYUUj@AFXp#6F?Voh=AbrEgLxepo93pX(zL? zrG-aRbNTU4wsPCGO`N-8Ie$rPr*XkdGTrI@fHb||WZ*r4q3{Eu@}-c?s2!q0N_Hpv zDD%w<_7DTIXR+LDOK?3Vh0XYa2AY>$YUo~8e9E4%7yuz{3 zwvPorPsI`p-F7NN+t*U2ZK_&ZsgNG!Te76QF|uu=)Tu@$gfvE;XWeiYY%PPu z$3bedFC_L89ks{P*POu7b{7fhlpMHp(ek{gSt%V~n;PNy1%n`{6;Z9xcAV><-paMN zbVHNxUPJ(_3>0kGx}F!G{XDa>E>~auT`suji~c<_wXRNg+?h@bo!;E2+Us2W6(!oc z`l*a?S>{C;b?TXO#UEj7l!0eIN`Lp`bU7z+>R~^J<0g6Ihi6f{{wXTrM>6aG48Y^B z^VqlNGiO0P8xmQpSS6!qzI^@_v_!+$3=oMfrh8!P9@{gdi-R)@5wIA+!rj%w%xIXg zT#njW3n)-t&=homa2OUXTEyCo8)<2oM_1QQ!r>^Hj3SfCQ78-&2$*?#C=wx`Nf8JL z>ZG9+Md#VH_}8`CPg?LW?bda1x+{{#t!?!b1_LcY|*i8 zCkq!H$}uOM%GbX3HD=GAN5=o0nPH2ef}p~(7)tdJ4-1wqU5M*?%y1&CdG=MRB4OUx zxs_<738BhLU}0Q3qjx7m16M+DUOop7&)X6ZD8C^Qx z#o)jSOO~$bfDqIKAWMc3G>!;Ut~Hs=0JSai7{%h&H|DYJw;!g=&C@S(giw_0FuP@r zpnf+%MeiXP|L=g9DK>&h5MRE0G21q5VTNPE{`Pn8zT1hn(L9-TXz79l^z|9*{t?eS z3t{iX__7k^t9?N`$-X4JlWA-_#IROAb=qc>0!rm+avJDy`-sPzsS%RRo3|i+*C|6+ zQYCGQ=Vg7}Of$)3Hxqg7)3K&Kcc#@L)yNWMtH`P-QqR(9m)Zu0!M-HrQX+%W@2E=# z`;tVP<9;^PzCv-uwECdvkfwY(Q9a3IH}QBgN{!*VNgO9el}~}25U@L$CgwYbPG3j& z&Q;mdOy=!*JvBm>ViaPrIJ=Wc<{i|^h7DU7S7X?AkWq@76y@iN2quKh+Ri>canXyg z+-Bg{?`NQU4Di_f!dh;>=R162SsAmPX0|1F;Ve9gXzLL?`TTZHJ?C@OHq z^Z(yT>fEHxt<F%UgXuxLQWKmEA1(Xq7P)6JrTyex19A}hq8+BA%QJg_s zaA(8?ltobx5W1l|&8Qn@r|3l z!WX~(1BQmijbF9}xHTG5!y;Nz_*uB;ap^EVo+jRrU{)zAB}F{!kT1E2u&yX*$1inQ z09lW=rpxABd|W8$1fhzm=*dW#PNV{9YYt^41VcmVT9^8jgBvpzQ$9^X&={2*8qd-! zG^H#(K7Xew)4S5<3BDQZ0AqF+sTmp4sPG^%Q{65yH+@j`@jBS&Amp=7fwAu3B3 znK|Dlkx0Sr0oqPKo^{>5Typ8f?AkTJTR-wiDCn-YGXf(y;UW^C*rEvr(vg)G8?3ogElp4B}J9o)e= zXP?g_znOr+FER*TkShkBD=mtRE8Jrh(>PA^leJ}cQ7Ld;8f5rco0fJ+ zhsl9$9J8sHVzh(ill~JnTmgkKU_iV5${uh{j}%uou%j&jzOgn{&lF4>yfefHE*OHHFFzvCdgdBoSqAc!-35ko$Mf@XH~KFW)r?d$X`+6Lcz_q$nfU zUu0x>`j!^zhM%G-+D&HMW;8p_&~TbeL7OgULj^tVf!a?KlXSI8PCRBStD<3=N;&e` z-Ms6vt$gyy`vgRiWf{CjHOifj{Q*1jC_UCXY+E3N=F?Y;1k=jH^AtTvL93UCjE!U4jO`yK9*Z$v z&{~zLy&3lI-Ggo0?A^N)+qT)hzn?h|y1KduDG#^c<0LyNj*j7Z6C{&yw(r?Sce0DU zdkZvMaSnNVIpk%SPfCah8nF1?BYTM^LyQ+J#s)`N*R_fM{(c&P<4!r6d+)i2=k>NT zZwa2--p|M z4RHJm&Z58nNn*qaR6xkK$a9FPjN{U7c1GxRAwhV$zJyF&(IM|lEWhw7wp?RO4_y& zR=`t%MX8`@->`vwnf=UJ^Bf2)!m17@sV!@(`?HjwA}s1vfDjhN(E^Q0iLzlbfUt@a zj3~O=Ec&5MCA6{sSEh)5f0ah$`##&ZKdA-h1B1r${coX` zm2eDw2*1SO;D8a%Q=@h3;)XCmTwN`I7DBMMzu$2G^?KJfSyJ6SWOHdEA-U8Rcv-&n{DQpW1r7KWwB@6<#q4BUKhv|bhLIbE8x8IQk>j- zJa_!~TeLZoBzlIJQ%#Hv9L?9h_#eFE>euq)-#x+XV40koL&^Z@Nb+u$IY)3zZ#TDm z{TsaLRTq;VdJ?|?reEdO6_t9HZp({zs;dlAI*gC!IKQip%4C6AVIiD$h94ec zRp+TRIXyMbYRFeKRQt6^Xz?WtQW4+SLdLZ?A<;!^UHf7e}1s4Yx8iq&o7WVb&=CFId6Li~1U3Ni=55=2A-E8&_-Y#U9|qd`d|i=4lN zs{LM_eB&Ldg_~R`N`N$!86lQu`Nm}nm^E2YqSdKwt73E|wL~bia-}@dlhT#r70ObL zE85&bOGl#iw^T>ZlH-{*$5iz{Z#3erS+s*g!?H=BET~PsLe$kJjHc?Ojdt3YbP7mi z8^~LqhwcX>P^ykPC&4BGpZ~(qoOb+46#D1b^qNaJTKSxswt4KBfK`4EQC!M$l6uv~ z8sU&rS$vryr+kXI{QGB5XL!Kk&F3CXi8Pm9`)TU4W#AyE`!N!UJ`Tx%2L|>4l1t9m zz-qaVN5?m_VQ`RvYm@x^g42o8N>5J*Z+OqEfk{@0Q^>e`fD3V5ft~V@QqmD_rC$07 zaUR3{{k-q|6b)ZlOY5c$Wc_gxK-#ZEIMsV)S+cjNS!XRNIU?_Np>n^#dDdS!CD89YCy)!^k1+Fr zVi_gU%!ta@@9|8&j|;Irc>G}=`r-=-a%rSY(GU(XOTbI@(*jIwWq8=^6 zfiB~2*jqr z7Tj>fR$g;PinZb(*I&`a4L=;wIu&ogoTsDhRwoCz@atpTweJb6;hjX>HnOxaAqvd- zSvq85iCDJUV`<6N{;QhE9XS|VZqHd!G3KO0I6cJmFYMrkzl?D0jZIwpvxC~C-);kI z9jCteCf;)S8Qk>6AL>3L6gV@rk-_XB6%Gk1 ziGRxl574g-Wr~0zX+;+W&zKuNrj@5P z6qd#A{gbTf-9*8%a5H(FWIK1>cOT7Gg!KLl70aR{76!+)$O9%aNMJAIs&$q?y!U*H}n5hnCC=~M8w#7s~PYQ5VK%wB9{n*TT z9u2mQWyAi=1hyR^X2%%c?_mcX(<%>{3A&SAY%}}Kc^R6p7|LWwCX)<|j<9y^T1sAl zhFFZj(NW3);ML)J1?uB*#`aHQ2|>lO$mjEP#N&*P>?hIH1t{`CfRzE;7Uc7JPS}#< zkv;vK?3~ERQTaCg* zqfX7#L@7mFYInbg2|R@m%o+2YlF@6;8YV`yXP;7KB0^BYH|}y4QYP@#K}yo4A`+C; zX2NRM5+r3IQBvl0VXnO%hlRdw!XQU5r54&$ROfS1Ylf+}6EE3>q|YC=@8O~|1+%*! zpeQyWohb$i7CX}|y!HAwG3RHA2pzu_@u?uG7tpb>g|@y9ymS%a#%W}jIx$Q#H%}%1 zG`>=lL>Wi6GUsOr`HEFSV)>Fv2YmUnU*yL(p3IX6OZ3QY%6=U`xo?7(U-N$ErEUu# z7dyHM-S6;>tqF4KAiw+h&Aj5Y<2V#}j1T;Y_gvh^|9<{%E_u_1HN6|k1`$vv=7}kV zCv{=Yah94kEoaH-_+-Havs&;kg{m}FO%(+Kq!dPD(5j)ItcDWv2JZA1-3Y~62K4N> zsSuJ`8y%xvop1w+G*ErXmiZe8?Z13e|sitB&xUSE38kaIjQDw~_ z>ie}K=NVIJ9AEIte>j`rsWN_gH(OF6_J|(7o3*(2OaIG5g;BD;1jnbV?P*@zm*CA8 zolb9Pl36TD!$Z9D{L?vj3}n(HJT^SY8$b0;KK;fkS>Mx&l!{OM>eu|>3qRBWZ|_U^ z=fPj_uK&7_54|4h_efTCggN)@9>S$ENk@>4Mw!m_^5NU>WJ6nmGqws+XLRtEPd~x~ zcbA~B3tr#LA1-)e?9Wue#uZ!IMhatH2O1S+gIQAU4?QxxCBpoAwuRQ=7!BFPdt>vO|f9dZ^ zK+FNp0@(+T-_9qmJBcna&t!LqA3iY7=k6Qk=_g7sY0f!jkR~r?`mfBJZJEY#wn0)< z0tz-{c5vyNqqJ>>Gv9nC+aE7OXP-WPDZw%ca-bHbHcLREtaUeILnaXuT>trBbN#Iz zpZnme`S3q9bHfjBhr(&lb|!d3;Af#AA(r6YI|lfudXz7|<|L-w0Wxk5Uxw&S^l&Jh zqd`7*q37RfY_if|)CCL|bP;Ln@+DSaG zsA(R_I6;6BdKdL}g9$9l!t?Z-ZQG(gfNVa)3<0(sr`5KpST>#!vt}|nG00>x*tShR zpQmD3rsx(dSFgiD-AALx(69^>{=g7C{go1gz`oB45Ze9ViZs53stUovDnbpQ?;bR*FRrA*>qe zQL!v+OK)R1GlGApNZ!ulc^<8HoHX09z?MuSgImEK5)|i=v8< zDFw}Pe$l>tbDYrR2-D;+N;W%$|L==(&ZPChX~eWwIDAg{il@LbzqYxoXH&p$- zcFhhmLReHmU2@q~?X_9+TjL73Ls6(&LUN=8rIsC+lsU%3(Z9Jx0<|j2q6NZwFnj~u z$4%&}oBrr3Mx$S%C_=PQ$E?Z%^Z0&=CMSgN`;?TAG96({K6t}0f#PWC(-qyw`m6p6 z3aeqnhAjiS+CJIC$Qa!GU_Ceg><(`I=o-%HJ%+j=pF=~xqs~dtDYGI~)1I4fnz^XKSaYU=rF-;LEqpP_}O4Ket}O=->d22|*!U$9y8hK(3C9U;0hh z&;$GXVT%Mu!sB(?ws*~H_(d0I-~Sa3-ttb|!89d*h#6lY6OyL}259WtM3b-n?tyCK zBAczStWLId)JcKzeQg2ix`a@i=GL*TJIo3H^-Z|!D)`cW!)I@XAKU@QMPbZbaNk|H z@KS1EMF|t!vw*571;L_wNl1-A6w(k&!6W@#@%A&g^0K2C9V~Of*T(37dPsk^tw%SX zE0_-R!U1~>gtrK#F`cagvo=~T6w+L}A>hUjT|nd-Wl$j@ zbb~ryfeh=!BWBLUtAoyCppfMQ|8h4k_{Ldee)U0;ulyd20&CDcWW+isxDXu6_rCQQ zSDt$sM>`Jf4iuFnj!SkF9=(7Q6wk+l> zOS@c|qfQ$1!ZL`0ZAS>IW3mD*p~=jf!hF7142Z||S{RSpCYcZf0YoAZgG5`jv@FnA z7RE-SAH`ykNF+i_OA8@8!YoB9!lFS~G+P!bVq@ES+cQALE7Ay*iXKjTJEGe%iJ?cu z(sT`-AlfwwmtJ2jgwXF5!Xji@q;#H2hnBFAId2s}*RghchQ;YOhHt zX^{~Q`7=~|(>F0!YfQb;Hs_3`@eGO?W@xq+ifnO>C~9v<>YO%wUuiQ9ih$(k^=sL^XD3@yTbTAs$W)Z9pG5#sA(+C4`3e?+ zS@|toVH4SS{9)9$!>Di)>{Kg7RYxxEVx_`BKwC5nWHgnlRH_x27ssxPd*1R;2&|+)X)wa0VY?f&^$MIXY@{6DRgrZWs=tbx2iKuoW)kZ=KoUG^wiyS<9pkj2-0IRRY00Q`tRC zIrBu5owXaJ9`FeeY90`Tr65p{TGh$mz&@f0eXPl3JFe?fA1>h-i@S;tG>D}f$vNL= zwqzmgd0e+lMC6GJn|=Gn*dP>+;i|_i<68kEn9l=MQ0b^ipxwL1aBntcT0aKN;(z zUx3~dXYfpICPaCkJ zMX6weI>=YQa31y2;cf4_2c9hP#qa!?_g=IXsT9gQi!G@h3JRJR4RGaeN>0Rz3w6B_ zR91wffw1ml;QQo#m$iu$w03jCEB^&J5!^a>(IupMHj&2Hfjq{7(PqI`*f)p@0?00! z*M+8t83dBRe5Q~EZx@W-$#*{fVJ^5h$@Mqi!%esD(ajo(nTDDMF^Nf#^Dwy!>_s}O zK+Hh>{Te`o6n)*DK@rLlM?GiZ6fQEM9!w z=lRg5uc4D6p6=g6rQ;Z8mA~j%6;>@+7FbwJ2LTn!!m`97+iQy%0xBM43VBU6wk@2v zPAcpOsK6o|k5l$^kE(hT+y?^e^&a&>Kp+C5mWAgPNhXtc zo<|}QF@blnHjmkMWC@ZJkH_hVCCOwmG}ty#lWdf|fJWP*P{`mZZHYWnMNmwr)nE`3 zeQX+4DSJiQ+uJF7MOs?o%y}LGVA~NqugHukZVAi6HmC+co=C(t>z`$;ifxn%XpPu} z%x6U{c-KinH36#+yc+6aS%S{aE;1RdaVh2Vgd#TMo=34*q}d=U&6Xf!N3d<1knJ(C z2>ofcbV3sZ0aKX*+2SGE+uLb6Lef=5hiuzMnIvo`2xt-(wh&Zo8#gn7=Xte+tYSe| zmv&@4bm$Pra)3s?sxNvLL=BO6HW7T|5fYQA1HfL+WSY6FJxU$IM%J;uD!?54g1(+JG)zye`b^fr+kjd)5#U02SlM`DU z0eM#ogA^$9KB0>?)e0{_U;>FZ+G*aaHI0CH=9g+h4T4WL(%1(#Nh==|Wa=k{w@v7v=Qs8iQqVkbbzy$;!#d z63cs*x^q?yTCnuF&-gCFk>m>nT(_QNk4@3f6OwTn?AU_tSW)ZE;``NRjf#?Crc}+B z(&B6q=piI*d^gXURY~st^WD7enrm=fjfAKwbY~I> zWrD2Scn;6cm}Q_ygHs~o=jl7@XmYs{Qz#-r;+P9ty`gdeC}rU|?FgocOF?@)#)J3$ zme;)TZOkbbgsk0sqB>bAMWYnl@snTEmYAiHPKs)r)vMZg;-`bWA{r3nBy*veMcq$X z!hfZvO;JaL*On(H%SH2ZzM?1ub7f`RCsa+iUIAuG{xep08V{qKi6zJBiscXA(qu#| z>h(}DXv|_Bd}Spi9MEWzzsjN{g%yO~Qfj!mQI)m0+cYPv?z>L*0jA22c43-VWg-Zo zLZJLKX`yINv=U{ANNX#%J*YcQ&p&uMlLBID9X~vGhS$C4Hi$W7zWH*lzxk)!bZZxv zef1XvpS_ateiu8{LB2FapcIH0)5;<{SO=a29_7AIT@Uy~vuQqlaW6OQs=#NCV(0i2 z8#+>K8&13-!`Amei5f4-VGZEaz~hoAiV6#n5n#c%G} z#^>I68iT{b8d3CJ;?iNtU)s6+Zy|YAjxZ_IqiB#0MHQmKaF%sa>=5hd=AFMe0F&z> zu;35dKpan6CgA?KtRp+?^`Cp4C2%TcX-{Hkj>ySGBU zO7rcXKE+M9O@X}`+6o#zw?c-BWobHA0MG`bK8V0*OtN4HtUs=YH=Vha6OLcY3!~tZ zW~X1~%^&#*tbM6=<{}G|zM+t5YJpxfO(NozjonWOGE*8+v7H4g;+Uh8&kZl-1uy*! z^N;>B-@WEI-hAfC{AuSPU-;w0WD9M;LD)Y=DW>@3*S^Dt-~MWp(&E>W7$dZ-n)LVX zp>m`IrTR4_#%NFlX8a*GY&wPSZr{uMKXns$@QP!5iFJpt{W3eg{|9)W%;hitE~l&w z`0z%fs_Wm#0Lr3H-{0`LNpOejL}IQ2n5y-7N3Q}wS80xGtR zZITb$j!^cBgbXUtY*~1wqOYs?f>I$*spw(H<8*X&k;zPeZDX5xch2*um|&+^^oT@k zQ`uiUW&uGEFe3!hDu9AVvuzWz<0zpu9z&TCTI@K7Okz_XC@m5X0Zs!GS2Fa zYsh3KshDH0ji33snxrgF0Bt)`)1a0Y?Jp9ssaIfGHnCV7AuQ%pi5MA8MPH=f3ae+X zYAf|j!6nZaxL3sC&*5K_pezsA8l;X~DvJt-6#-I6B0^V>qf#<29cG;l)_>%?sJ~3< zqDnzQJf-I+Tbn^>^cR>^3x$@LDFR8MDXlT%!1zpwisx$TE-WM|@q~VR#{4aBbc8Xf zlOU=I$O;2(FaKSvtecCOW{95BNmX3xb6fnCcl9|ePf!*oDzU`j7riDp0Xm-#?1K&K zVA9rwu}2=GF&d&Uq!FX#_tA5)oL+uEsTGV->K9R1(G#e^-GS zU)w#07ae+oT+nu?T!~0)n4zJ4c!dm|o7V$r!?doe6|pr%UQsWk(fB|}gixh9EOUf) zN>j63Hw(0{c+Rz?4JhW)*isO920bO9A{rPS%{t~~W2>~;%OKWcjo(Dq2@ZEg~(TouDjPLz3 z`?vp|wI`pWEBwop`i*9=?!Eo{td>QhN>Y*Ygq=7K@7T{J7rYPOuihk@FIa`kW~a&= zf9^|paK{sz+Ovh}>`sK3r9CG2(RaScC6}Iq-P%_}QmUC~4YKlGet*}kymZ|RQpWI^ z=1^df=-i4Bf?Re&Kbe+3$f{tzUMcjyGIOf5q!WGh2A(~_q*v9RESYpmi){o2%2>kA zEfmi4eyLW`;hQ@){oiA9>#4ARC-bgi7MGY(;5(p>gHvsWhWcrwl~igYkx)SY@H8a*z;+j?PwS6` z$t*|rb>NNv7K;R%qkVuNVoQRl64`7PE73!}kQ_=+Q7=O)XqHye8U4Rg9SpEwSr_O|H&cK8D40LmC)Le zi&wXD!Lfbx^>*;0jm>}}lM9$A`RoPWf8(#fei_6HT9YE?%>t}>)MV27hF#Ue#m5yn zwy%$qkJ-rjo+eTus4q`p`!03<9!RH|>p7ke{`fDjApx;5{ZJKvwoL|EsU}gbIS09b zoG4!>D8zI^)8-fiNSW6sVeO0gm(Ty1x4q_QR?9Lc{lglrdHqog4-4*5Q%JXtnc;Dc z>5ekzhlq$W4N@@dmWYVh|5=jqT<9t7J;yUKbRQ8Rc*?bS|NFnMoxbb>Egd}^LihclA5eC@mZ(`$~VqAW1;rfcTyc@uC?6A+4+>bIE#gFxHsRxF`| zdrQ=-^%j2oG9q8*kYn8Uz6qAt<4+t;hnB5-99=oCaHHG{-nhB|E#= zwSPa!WRg-LPm68inIxrNX%S2#fE}srr%))cWy?k~nF6*g7R5)3IZrWb1+>@^eO^M- z&gLwgG*t^a3rUqeJ|U|55zA;^bTD5{wyFt&ZBt89D#9Z0bn>P0S~ru==dn~!qfqJ3 z3tH?5(;}c*1v&`;rhLBKR3QYGWzj4wX3X}zLLO!IQPmfP<8exPk6Bf$ zb%AdX4OH#=W|7*V6Ccpx>XP7Dla$$IMZ=0XQpsm&AiYw;^4BFP%af_4?Fs6Mkyiyq z{WNPgoykqNKgqv;{oAnS1X$B%Xs#w8FBtvZsIR}b$pr+%^J~@n+WVAv_Mp+0I^eG+ zDYi7dp?sDo%&X`?-XP=!4?0(^kQJ(>sLEkFMf3N-7^uV@2&zenL3ccZ3dNlTL}qE1 z=Y`;MG_AL7%Y|ZD73mjf6x+n+%(DAI9l@smhzOg|v7A_z zBbAq}xy|7yuIsX4{d%MvM5zEF1XGjyX|)nO`oP_sbm4haOblCfk2UIPTBCx8fA?#c z9HkMh9TF;n5D^ZHjdH@7oACXzaYf70C?#{MO5bysB}8j$Ct`96r97HZ9Lf!#)P|Y` z^h#FV^S;X;e|0;SUm$M!AQfCiM1^T;>tYrSEHs1{OnMrOd4%av{{QsM9O=EGY&J`@ zEryhm18IE|_Vx8Loz3#ZBTph_xR#_;8xux^&#VcWpRLTR`R@AReBp&x^2F|ki6$Bm zQUFC>{-UkC|DCVo+jl%fyra(u+jXWZ5FlK({eCa~kNuisSIy8O!h}SG0)o39{0ras z*m)cpAFpvKwSAvL3PHxr@|J5q!hd{d1M6frB{xrNN^NVEDa7)LaM4Xtuc`uig$zsll1r0mv=|8qDrNQT&|0lxu%HiF-~_4_t51!K@s}zh z5)!pby%-&-HxFck5yv&uT*(%Yn~LdVyEJf~M=sJzG{`Uls5f?vQc6a%IaY}}nw=1{ zL}_vojArWqhrB-pj^qSqBV*~`Bb@}UD>!!J7T_=N;5L4H>GRln^2y|KoqXWy2Z030 zFq{2w{x#eU|Hgc!F{`1#HT9 zi6UuKijZ=t2#FsGbHgq7Yr(k{f{YJsDcyBXjT{kv}R@fNgbTH zshbxZvytO_8|aW=`#PBjE05tlJBUlkv=6OYw{ppQ?gmyt+dNDf-Ak+w3MEZ#I4Z$E zy<#J0ZE2vdH_Rp^uJ2OJ9YkdnJ`!69$_Cj9C8D^YDEB^;)8}5LZ^e4RD}h=EY6zsu zt556T^%ren%a(SE%IE3fVV+9IxbAy@fTz=7r;NTv=)hreO4G#(E}yvH<-H%e0B_G8 z#>cbFxIV4I;qpWed)xt1C-*SpYE(2LeDYbB4rdcZQ*`*-1ERlf0m$vnvC3J8m1yO4 zAG=Mvx^<56m#@B;QvZGuLXyc25toYp`S@AfaNh_&z4<=w{MA7|`KFiPx#PNcv8elV zT@YYJv?X*O=)6M7ES35-Rvu$dvC z6x8WB&m?rhvTOPfP2ut&0?i_VBES+hO##dZ2t1Fb*gTPlMky8q?*Vh3s%dwsXozjw zV9=y08WNAksW)B&!nUYbAkc|X*tRJY^0jMQiRok1f`6+<$!iuC!nD1w2tlss(QZd* z7Q%Q}1k?u_0V)?2wk>NeSp}nU1e->asLUx{87v8w^iomknJCcD4f*){>%`QG$5#yw zV=AB^B&)WZ&n2I}lSl6!ht9KfQKXR8bmfA(uq`PKUAC;XaIui#-ne>R^ITnMS~8GE zmNZKO^@Z!>`_E>7t?#X-nwgAWb2@EY=5RTco8pD%zL4fseuz}+A|8ME zUN)byg=jPi2&B;;&uXzJbH2-MH+`A7U8HYS7jwQMOM*uXbB2lF%7WT1c&mOwFyKx-nu%dS^mt$hv z!|dAi7uLES(ao~P*&7(ha{kNST4TR7ExXAZfzlDp2o}F?3g>ERA-{3i$Ldq56uz&> zX0xPH+9o%f%@UWg=15Z!7>hWC>$-*_B@IpFnZJDBr#ay;I+){K@4t@U{QMqTQoYQ$ zdENao@ObyzuI3Zhy`NwF;wO|!Q%IAfO;W*?XYCi!MH!k%1ER%3o}zwN!*Bs*VS$ zX16xG?003Vj8#6P7B#Eddu9PuRt8B?_`d#|@B65-s@eWM)BlFB{$K59Qnfp-@|vIR z^OcbP-?%JEsnY-alE2`5v8d9ZjSbY2-xtO~)tXjSd#5ZOBVk-Xp4_&L?SpB?l*71K z%_Hd~SAX?sp8wYSx%jnz;NokZ=A9q-5l8iI0VDzI2$gKkIPV2ut>(q=yPM=|he%v^ zKeybo8ntyuJt97-ia}#u4ttY~y z;Qrq~M!chgYrl0jzq~&U-VQE)+eVsER9u&O<+35wLoqkb2R{Bb*z5B2t|54I9NMyQ z)EIcHIQwk}Irgd_ajzGH(VblT_LmWs^E^GYn~KoZkvgGtkMNK${I3|Zh$H=f_Rovj zeWWEOdJ>r~!;fzHm9A7dzR`jR-Je7#owOhpDst6@-g7}^x%{k+Ja*%o+54dr`Tj)_ zUYpoQcdnoL;eLv_Jxsbo4EZi&J$;NK=u3qO2FvifDZOoPC&*R$=h2;@?&qVgYGVGA zr}F9Zx;S0Is$rYS;VFu_I%biSgu@{z7#8rfR6HdVyQ7l+Dd5R0SewD>F?0e~FJkJ4 zyx?UG{PD(@@%;~-#RUluyMH^eJ;R(zf;Vj%#r^8#eBz%jhQfeGT`Z;1B{8pE;5vbz zz*F0&X%SGbQZzZoGbhJj_c%v6f*`wFyVl_|%OpYw=3V>$*CYiX=^Uhy0`sks;R6R@ zf0}!*eLa=_-%_s}nzALNTur@dqamH+x{FTJ!IRg<}icjwM^V#>(?5w7#SI< zAwkt(xY^R%Yq2953GzHM20`t7s|bV+60Z$;D`nW$7exe0+k5i3tkh6ZnU;JKE61M9uvyYLJ#0U^*z0&*#ZxMvPXa zh?F+IU#^)X%o3_45nI>nVW6U*jN9<}*hn;2&QAS6m34Qtz{RPD{3HKC?=|YtMkwdLZWOv9VnJbIb!- zV8I&S*2T7?H`Cl2X53dy6I+4uw2-(+`P_u|)%Pwmrd&iLG)0zqzl>6f^Upt<2Oijt z6H6k5MNdx$b;=_m=DFpTuj&r=wb)ss6{CZLeC*nH6R`p+g$a@|Npr%XA|l9ej7%X< zYin!GHC2cOy-Xu8K0eL`FS(2zyZ6?%>H9;FeVT3CwlO?Be3)f$E|(*nPVZ@09bInkp@fVX%nOz05S?@MlsTK?An(GaH)oeIjO{T{l}B z>?(z4*6g{s2o|cjIKWbA{|X1>3PnsQLP9WB4s-fD{)@Zr`Vp7EU=xRi{zT{I^*piT ze|g>IZz9?k<-yuu*|o=y^CwESkJ$_?bXa>6)hqlF6QYxYds&m^rPH!`#1Sbc8sLc zhU@OvQDZBRU30DC4c(UpZN60{*^m^d+!k;Wg)0}lwbM!tFSD%?fc*7z<3%# z)x|?RCwQ}Z=gp#h(-V$^>t>OT^-4Cxq{pQTQaC1UaQBIss7?(23;NgTuV{Js*RQ{f42FU82z* zVpsf3Pvq=^t$pC7xqT9Dzv?dbed`Jisk^B2*Kx;H$MPokE`IjJW)NX`d^Z3ez3vQN z(i`F)-v+gcm%Oo^i%!|V9)Az@NWvn-J`_q$GXKRF!{8u~3&DZ(Nj$i%j-u#h3b^o; z^SOJ+jlAY9@8%2VH?n*C12o7Utc1gmdytK)jnAIl$n(0_^RZtY;`!nju6)fJnz}=r z{+@^630qI9$Nic8pS}Rwog$Ntv!-tygV~+T%6Wt%39{-4RlmRGYw0#~N^-R0Gn*|l zo9bl;`#5pqMlO2KFJbK~KzUloWP4`UDGcFXFEq-~ql7eu0gv(MmtV#4-BCuSavT^h zEjsSSNSyw;&2^a)62kMm>i38A0;Lp)gw}Vcb&yH()qmZ{YcD&I9ebu|6)sAQQ9`o0 zyPMXI6c@hW1$_Bi-y)aG;<_%WR0?1D^pphuecu6HsSCz*VkHyWZrIQAgV*(P*7+N- zLyG?XA-&)@De}Hc1fOs=#*Dj%tBwzI!nd#B#aDkBIKfap=QaJ%lMq|YYkxb!lW(&~ zjHlU0nnu=9pECB#I7Dkji8h_niLsSYFZI`7&jn3N-Lnc50j7|&iY(r^0!{>L7fp^w z*tLkO1S5%kxNZ+IC8DiLNePeMcuWWiJ2$;rK!j-D<~~RyrZ6SUM>QP{i$cP1v2ucqC)-S|z_;SfB#R z3M#^)y*e3wX>gUsWEnY8sMhjvKJP!(md@b?P$6hq+ zbbxI|DCP4+EsKeX3A(zvYHLS*pp5~P3OI0JkhZpVGMNdQMZ^g8^?s^I%0hyv5tr&d z>w|!46=?m7N$M8=T?oM=k32*;Y}3-xqLWOcgOL%9noSjp?BBn?hHO=x)xvS@)YcFL zKnn*CPO@rMjE05=qM{R+(wZ_HrVOcCqY<*UUe2yqFkH|_&Kl>cXNpyp&Qa>`Ld9&P z4b&JBA<6p|4N}tND1Lg&w|L+;kMZ5#|C}>E_)GeqQrZUHo791LQbLf`$nEM5LTA=d z{@h=HKJd#LRZ(|Qtf(rJ~wp!BU%+iQLST^6jugF{f>C23dj}wq0zr|3jR1+R^y_EKzxgx$t`KJLqs_ZHqNL&?L|6 zJCl*!2WYob9N75)V|U$7$QEqcw4R8_V8=!X$!;u)RKzs11k8vI{`k=EdFQ|1#Dt$> z!FFrq06VABBoaORm!=b-0@+5kYs8j9!aDV=yK}+-IokYDka4n3K=NNn#2x9_Q9;?quH^PvW?I4nODPs5<}r z)?xnfEdvZnkNd(q=ogZeP!VdEes7dseT0L>X_`YPldH^d>d7O#aJ)z}`E0)P{r_TW zx`$7{@eerbyab1*rs(q|J)XycQV8i06bkfd$*Fmt``$24Jej7tP-N;rg?lf59(NvS zl9x|q_XxCAfyJpwhR5>E1(PK3Xlsv^u*rb8my(+PjUHcV1VydM`$>+fMNafbxnrtM z@xEX~sQ9Z-aPxJ38l>QY3t!IOog=I)%uv!MkL6cG=azfi6x_5NZV2)_^A8Q%1;72$ z7jXE%9i+sl)lFqsLo>6mzzsM21kdv*76V#JkHPH3!2AG|lC6#hJO-?pzoV<>965p%1Zi=CdpjfL}lK`{LW!scQjaKAR zHZU;IdA$Y=l3ACc%^zu4dR4Tau;`5=Of!(Q4MT6ELCc~%07s9OjJCva*|TRHfW^f{ z8jiNXkD66s_OnSR*m(U7OJ%d2W>C6;l+`V=GceH4?CczFuOQyl^hNnHo0vw8MwhVO zG>cmVHk5Nai;GkA_xGc1zK3uei{cwGeN1l**dB|c&>Gs(jzx!34wzw^^d3b|@&w>1 z!c4|XT9FbNnqnPoT`Z3~ZWlkiW0n2$mR{w!mY!rAi-Ek+!|4RgSAWP3Zw?qXmy&j1 zA`B%p(vgHf*o2*@g3efqmZB4eAi6hGfXKnM*F&iWFMbvr=flB*X;O~Qn_yoz1EOqD znIjVxZCM7e~0aBQ%5s(}akILDMtBAlI%j zcrjW>i>L?%ssKN`6EbH3qc9vdj*UwNV>W=*xMV#0-f-5wL1Kj|vQo0F6-sM7&nFB6 z3WWuvOq0*&d2nKid-m^t)c^t)mvNnqlpjEfS>TCw|Jh@z&a7r^Z74Y8o zevED7F*uMCNcv$*Q&Tll-b`W(e# z<#C@Mo@cJr5h_(E7_dZI_p?a*9D6t?3`5I#VxUv44Q;H?lPrZr?w^_AbKkp>>+Y)X z#UD?zbNt0@_s(EQY-g7{$gqY)VGa>2k;7rg!dOaa#J01z@le3IFa9IWeCErz>%ih8 zP+Yo2ae_N0XE^WWuj8CozK!qQc!c{8Rp|FeaK$<&xz8Y@c5rk$WTg-?C|!pA0k+`K zr+dilJDnNjaQ!bUyz8=0QYciY>JY6%JWukQzNxyV6*m;Huo5B!oN>mv1jT^WW2Qbr zZ0=NBb%o#WGq!7#$*IW>-7KPYJ*HbF!%%XZcwGV^Ub;rBUO-C7<<_Z=R9W@sk+Muy zDpDdq$}+tYl-kzGr3u53;hj5)Y0c5Xf}L6z#|qC|Ck-@$CJ9`6yaq}@{l+3(x1Vjv zF^){TQ0wPCzyDjj4VipsL|;J;SQ+GZjpdl_tzAfrr-8y1e~nZ!xWDN{@hmKE2G2p>f{z z>7Rn*TbTYaoZt=X2veTqpWb{bwS}3E$gaCs?!IqcbL@FEy>=ktyQmUA1^xerLA3bwVZ7_x`pz>CbCC* zmG0tw)o%NSmGXx5Xml(`*2`^YgPs=cC)Z7p%ot>%R4UQzD*jjP{&w9ITeoIAs7EG~ z>1slZ-S8@#1^LHPS|05diT`J2W{jn>MPFi#hRv99>~=dFO_<#m(e|w9hDDBQq*7Zk ziRos)wvI`3KXy%dENp%ED~3Wi!QpD zzy0Lj@!MBi151Fkj)KY>u(-C!b|ifF9(c(m5cC+`id_Q{{RYLx+V~0=v}X|T^PXzZ z?`11auVK+|t1F4V-c^Jby%=8qyXLXi-)$|`J=i}DnQi9vmqI9M^BGP!3qr?;`fFnI zT}R(z5T0FU!s*YpNQ${FMqWSEw^izC!w?qu188p;;Knj`sgOya7T?DFZydvI^zPQ zn`H~IRjhI7=T{LP`UTH^(iks&{*&0gE6L%)?bK?MJo(IB^ywOdJ9e;d-!pmZ`#;U+ zzVaOoE))rZkgfS4mb$KGrgs%cnPz&X!du?^VXnIIPIP8Fz0$?^GmMQ5GdsDT2X4QC zaX-nsE`9~Cd-?O(DyrOj%a1sHm(T7U!zBDkR>fZCX)v`z>j=u8oo*yx*^O>ET z>0HaJT9Hh~JGK2I#3DDIu#?w_+(UYmVvC=qsx`MBnBkLOzmb3Z-yi40U;Q(l^Yjsp z_ww}W0y#O1)=<+ujEC&rSv z2su#L&jl~L2;bkqXFvKOe)|R6@%=S&QlnIfgjhk!b%a=FIjqs6`$*>p`23IO*tP4a zyze6)^W5$%5`%o0gH9=BLmveb2ktRlXVODA zH`@;ip;<$8_K8vU~vzUg4wtBZ^eZNvBD91Yh=Bk3nkn-HZ!^7$cxplG(W>uS?0lb~xPwL=|AuS`-> zM_8f)2Nj&|b635|+$lM@vo%$xLUw4*gO}k02tnf@dQjw z73h@$=}D8694bS}v=q*^5G1wHcQt}(T;cJd3(w=SzrWT5P-F+0mq@;B`RN9S|pRnlEAouxvqX`m=YNJSFbB*)f{?-u+P_> z&)S_=(`hgV2RolL*3zAT&Q+k#Hh^u%Jh#trjtS}19aLz=>T=5E27Q*Y*gbqS4QbOj zB6Zazk3}GFOoA4WGS2Aeh{>Rso?&Y~$C~C*guajemX#iBlnFycPE<%*oo|l^U;O$l za9?1M5=Vlnn}$PnS-sDNuzMW7d%dB3;aNAUBfufp?Q^~mT(32VGJ+bq7MQ`&a)`f8 zkkp3qmbTkfL9-033Sqi{`AM_x?v~I$2IVGwu4MJZaYp6?RvkfKzvL*ITBFRajLRW3 z3`_d8(e!V%uf1xIDJ7uh2nddt&!Uypomc}VVIxh;q0Lhf5QY}F`eVwv0+kT1+DKR;cq38 zJC1k!-Bo<_vlF!AY1U8(8yFhp))^L!IggrB&{lBkff@eedq3yxuf2emU2qm#g~Mui z8+-CYRP`!9z5a__dv%q8%vJ`x3_JVd#8e5HZ?USMgdFv_`fD{lc==0NSa8wQNj?FC z(yjSC6B7q`?lYdoop;{Fnh*#C<$4$O>)0T;garv>oiLxrcZ;+mS}S5epXU(-A@|Ny zc*8s2i&}Uq|MD+?%e6ON%lNkA7~0Xo^H!*jY93VAlH@#Y{qZ#CJndZm{?p%QzSu;C z6|$a35KI#jUT1-MIG$=xFvIZZ5KCdefrWs~=ox(U8$aRi|LhWGZ@HCowzWw258`=S zSk{78*h4uSBrK=kh|6Vv`vumJ+&?u-uUx0$Db@l-440VhH{99AZ%(|IupPglff)#H zB?$3yo^3WB8t9nlsz-(Jj6gf>q3Vj5*r0}`9)`2qhoBYj=3?GOPkI}(xJZADA0Mdj zPoKKROl#&Qpy64en*e07*naROP{9lXRiL zS^04S6u+Ea;Hp~-Fq{EB1JW@ZTDHMqVEBkRZm#L)_Szw?+ZN}{i_az~Oyc`_O3Fa> zy;466sG%SC6mX+YH2(f!7~=a$(nBMB{I6~RcNf-_{m~C;#~x6%kmv2%$(FDVLeTaE z)kkPj9HYx~kGzqj3@`WMN^H>L3VUv_^iYedsJB_@VBq`INdmi`QaTE>* z#+usAfNX%&yyodAfDG|{-$3*lls2!Ck|qRqHB_wWkeCo;q=%yd8o?wNz2F2c`={@3 zWC=tUUAwr(BHEYz`e+T~|E(qkU_Dgec_a{Qk!8O5r8n`4*Z(U#D4?YI#!vd8R5g=N zcQ4d#;l*z_gA1R#ot0pkxOR+cK=+^)qQdX}bgag9a6tfT&-hDV76eXr% z1>^43httug2w_l@hck$1JNDn;2v!@LLjaT6ER9BkV0IR7aFCqq8gabqQYw{zJ8ZP5`o;fzUt%Aj`cfM$?@jT;%6o!E{C`_^vgscH6u@NM> zImqvcxoNFf6Nb7Cup>W&_O?=v=XmcoZi3+_nRTS0je}Rigo6jbd{xGn^7Ri{@bJ402`rLkS>YBblwI=-JnsfcDStUGJd&~$~Q zB|TbdgG!}!h${r^Vx6)u!`r&O%%rR-P=r42#IpkdWv^@I_enfzVV!CDWcs`~L9oF3 z%mI3JNT@V@o=+P|OI7HVNw!GIN>HQ_7Rl#_@O}9Zf%(JTS~eOZ3`17Yq--eTI+|7N z5bJOODb8ex1-9msxGK)H(Cj#Q4^xGJ-8+1)`T7Ug>enDVOmTjm?VhA1dx>d@)(xsO z$Zs2Gg+c!0FaAG1^oeUx`JLQ<$Gz-5=OhXXW(X{;#w6PbGFKhsSxU)d2$y~GYX13s z@8Y~u_HyF*(^x3XlhAPX_{oN%Ya1`W|9E=k8u8@mTzmU1OikqY&=v1tYO04`8Io2b zz{2A?KYFEPae9G#eu&%ey^A&bKMunRBO|$PjmmHK*5^q|L4kZePg`pmLCApTp_FF- z{s(dV5iY&#GGh8N4&8At2k)8Sh*D%_hWs|4?K^Y4_Pu*p4x1cYm;%i7b3JU5)Q0nU z?1ZJ;j?nXJtONlGv4g78G`$7~3j2A_CzKgs+PfhjH=cOqW7QlXJ7JM{_EP?Vb3`5RM<7m z#d@BVLm953A8Lnq)@fq^yyE=r`!_S^L<2?k-*_7MTnK zT#=z_8D2 zr=zRsbxdJx66XbdT}?^!wcF*Z-C2JeRz;(8n719HSy|H!YBghHn{l(9#>UwFrZ&(Q z0lH=^f3=<1*GnbZ)(uPuVbbHHwDc&4WD}LCw)sK|EZO{(nWaTbSxPZGJKI4UI*;vG z2A4K9K9TcR^nTG>L^Q2ht%i1V=Q%6ZhIy--r7ghG+9bL+8pa0HB1MtI*|C$}xJ6Nf zaMvR`v105>-04oDvhe$*XDeSj*E7$*)}bObs@u^m+PHtoS`r4$J{7HXlrN# zt+mz+jv5_8+ZV@JqdvA2`(Ni=%SuU1NUEWxRR~zsNp396LfJJ4Zzsp;7~ZGWaCp)< zF6w@8r}_7HzJ}MF(~H)yUlk}60ve%N`;JIx+vtHn3wpFeefr2I#>Pg5o4J0pDoqyC zaeAd-AW%3s+%0OPgk(fRSg2906wI*@hn;NW9@${5SZ6-nAYM1eY~8*`JHC!?_H@>m zR9sM3%arROWlQB0@pa=uDg?{nGK&h_dJn0%pe579(5wa_vnX<1*AIbdlG+%ZQd`5d z8hWL1Qo}lp3L!0%M>7~ewV>JV`^*Iegy&Ngnm#09Sj6{p1VPcDhhCaqi+E|>?Bux} z%LM2?*Mgu(W^@FPD1%QE1R*`jUXR>3IP0{u`CRkCG^?VAd-hMzKbog5B!|}4`I|p_ zJ6qinFFpS>R)WLq9XpN1nUGa6MK-w|7~tza{27VC-)wV5 zuW|38I#=KLNiKW;4|w%C+qwHd5zm`vHQYv4HlGkJWv`5r5`vPIiS$}?meN9HbEC4> zfy+$@+!~KPdH%6b*dq(%gb=K#Ix%Ucq~2(nsxB}&rI1oGv~MT5@e$)5BhzTzq^jY^ zHys-N-9K3K}^@kN{`8@1%&V!IQ?u=s?Le> zIY=o`Dxj(rM>%4h&iWY}8{w{rn-EHJTz(&m(?x6Xy-d8Bc*2&nhjZsiAdpF;@u?Pr zPC=&X3NI}?6t2WWCbf3D5SR2y)07NkJVf01b0?a{S~x0PAFfGBAc%1aH67CD?c~b$ zegIB5m9w6ml&_|Mdeu$Q; zU_h?0LBL1r8xunXGf$JqP$q*kl}SJD$*K?QR!3D z9$&tB5%3KiKv@2<^JvsBWimf;-<0EB`6 z9b<(&7sMI#G<{y2Y9NVY#NAp6($W+<1GW%}G%H#|rBdgzUk0WSD9yw0Uf8#b**E+S z4_xv*wvRoBW*8EKO-)LKum~wgp($!8B1md;L0nZpqh^f+8YVj?v)R?GEliP=K(Hos zhYHqh+nC^qw<7*^nv|ICLC6Mm6e;b{&o<_#j}Yjaxac|KBzF!`%h%YZpjS3HEJFIi zGHQR39-X0TJg0`ZH}(qB3xENeraC6*LA@P?W5;!aZI>nACB3^nrUznz-pKA zKy>Cu`>G9O?e;{P7{@U#Nwr#y=V!%wAb zFr*CvRkhChZXOOs;`&D$%$V4MNQY1;EO5>_r?J&d@YQesh;cv1L!I-U$n(tvWG4`$ zgo7*7WQRui=%>E{?hYfC7hS~?RhVq$2WJvOxUW)ZSgN{&;$(ZTDGd_|B=?w~F- zy+W|M(8FRAc5Bo4$Mr@5-|nKTN53maL!_i>Xd8k~oI%^tz-PR5^0J4f(%cq=4B>LT z=%**2q#c-sA%PhV*D=)gi1I%q1-&xfF)h$EX%i==9i&{x5t`EUH0?0N^F}FJI&V`7 z21ug9N=GkS)vBW}jPy%Yt$yV-HlH7&suY1mr93Z*l+ws`w1!#%`t!y$RX6GLd=g4< z;@CLrL4lSOlysB#edHf07H7EkjvsM2T;&Jfx`&h)V2hta>lVlF-Oca+uRo%y0uy6W zDAFsp_JiAYSqJlm!_(eu}%yW4v_XFC8e3OkX2PHNaT|?@gKmmVnwB+8!o3mms!raCOqvDN4AmDH1n5}1lBR>U%kg##u(!S(sX zTVBHQ?cXD(cTkWCQo2q?9-yZ0EuP8g{sOU4#nZ>m<}LBFS*vJnyY^1L^1idU z;N%>w{Rc>3IG{lQdk8pr+~b0){+Lt#{1fogC(-kaFLCMLJq3=-!=1mxtyj1)tguyO zNz+5Grzwj$L>>O>qO-Z~x4r_Iy?9T#0*3b)LZsfsDSz-Yp7;DUet6w~gBXR(B*VEl z%c?;;KSE7}YzcqKabcO`a9F?M6`b<%Te#=j752RYc->(bZh$UxM$us|oZp^5z&+>rNRQopT38;U;b4X*lj}$3y?WuL%8{f)UW8HNe|aBwW!9A#H~)3fOf#+M>pNa(|>P(2aA)$*oNmxg5Y*? zp83DDl%^`o1xVTpqf&~UJ4axtZoT*IgfghYC9mYdb5EeCu=z`ZmeO5$GP2XGI4HnF zN)M$JeL|D)FyWH}QTnm&1gna!?TY?ordiqSQk3BT?k&=jEQOPJd7rh=p;v9=M1P!B zeLunNQ(Uy~IecsKR+`$QqFSu^Sr%s!>`U&VoIb>z-mRQ4vxgRSlonKVk4bH}bfX3v zO++%AWyR8m+FcZ>w(EA>rZkOBE?}`n552BI1|oV_%@+32cptl0*tR|rxG^w(* zw2U_}$i&11gM)+CjKEOh!v7`s${cSW@e@s%y=9;GDoA) zV6~(y;@N|+?1{~&@S_LvDOJJu)2xOH&r7p3v%qcl973u3ubh@YA&NjDscTd3xEK_# z7s1RouY+^n3ymXY&>=APz%`4mL%=lYveIF&^|PjA6toE~Dq42iKJ zGGW2!DFo!`p-05ot`!I5`X$|*zH~4w8rF+g!PcL@GMd-aCMZoE=X!kC9L6VOJCmpQjoWSqTc{gt>sFgkUMGAjCRSdg!pi5_P1EKk7g*s&BXWK5?ZGLR(WE ztMzqF!zl!mRFicn5W=HWsIXW1paiQFSVXWUJ%-P@nA6kdeUlQ_D$tvRnM#v`$_$p1 z0@7NLkv@wmU?4w4$(s2HAy^Gfy`{BgCG26l?-K_~VE}#}DFrj3p*}7FTgQ`}fBFk> zg$V@L8XDHjW~m~$eWqw?MigmAfF{!Osj6ub_>a3k81{WuEE?wfIjeazr$W?N$C^@5 zt7%d;_|06To5p+mF>*ko#Vyv+8#Fdg<+Y|Rpe7s4q6~Z|B)!t3COxX!Ky?`nP8c$% zVLO7P?QkPc=(?!U7MiN=A%TZdvO~M-4h@WT=^h643>mFRcKDU1ATDY}P5KOKNm4uX z1Wn?q&X7!!rbb)^49Ru0KE$w}qgK!)bq{S30P|GPw8ah@UEw7$O(&^yBk5E>EHx|& zN9#BZ)s+qUgH~O2Xc;1Ikd8HskiMi8?KqvltO(u~af6zux*}$i>;XIkeHJR!P2GV7 zdz)QpqQBx+7Melb&vpT1jr+%alM9?ab_O}WOf#P*oo?vErh#?iQe)%7A@k{4m*yEr6=3ZD< zFwoC0<2i;y1sq}3AETr^hSV-xwSxg~o{xR}G&no~?lPzXfARJU=oeRkSmuW}W}z(L z;62>%uP;FtD-3FfyqaV+3^^kDDNBzq^N z)EqladdSNQLthXQGCo(_Ho>d}IKpvxkC||rJ@*s|HbSuKc5SH(fl}Mpr9(8Hp*T1i z8U-l#n8{-13_fw=O?dd^grp_|f}qaI=(*H|#?y!Bm5Pc*g0~82sgT&n$$a1^4?=m_ zZVN{E|HBm!yI4GLJ3E26@>mZgF)c|6kC+z3l_sf;(ZDZ-M^j3C6a(5&&mNd*n$+fo zHW@0eF!V(NtA*M6EI1LmGvv`mL9I0Ay&X{*L#2;!%sI zhd(YJ&8;R%{`R~voKVnGie-P91A2n3s)wA&uw{3iG=j2F)TCxhs2E6VX1SYsU9oH7 z_+$9mHl;X~qS9!v(x{Qm8VyFcwAe{qZ`K;r%Qdz*Mx-7k&I_?Qi5}<(%cIA1BQ7~N zOR-k!{M@pXu2`c%&fO5CN3Ri~E`l_|=giX4xO9DZyR;6C5bp>D=i{4&$1C?2_`zQKaxm;q4NRi2y43wBQpRr^S zp-51l$z(h9w|co|n;!G?}jppB2p}rmP|8fo0Nvl zP>C9s$m}5QM*1UxpW50%!5qiwG))mbZed}OYPE{%x;A~@?KGAf$cjem8V8RYAuBVa zQVtEbA1OV0<$Bj3Kv)Wsdce+0oeCg?Pbef#Sf}6_ou3fWGz}utL5?dxTf|wk z`)3VJ!;@4x4V$1Q1qnS|EkgO zk}LytA*qXXl&X`)A#R@=4SA(pXEiL45;eOI1Z@$gq!dD!P*G*S-)K_Iu@McgJWsM_ z!?&YjCi+`cR9AJ^x?S!ESI`y;DdV;d4M}+G1PCe^Oa7KJ*PR54uu^BPSmDS*okL-f zxnhL`<~kZz=33g6nu0D+7t!%7I@DurYw?(d5wAf>1uSFSJrnkNl+iuJGz_3w4?~VF z6gjd`VRI^ zpvP;lMwzM(s0&3^hfD=itRbmtGa0FB6CzpF%AP3VA+86}LYm;Q**iwfp`Y_9Ed(9Z z#3a(|%_;F#NR~h#;`ZKUXIZL;Y{~h?x4nzjwfZo{YxKK5+sJg&z7n0lAk*=#p&1>` zv1^a%o`3)CpJMx;-^Ter+RER5Z=m+$g7-&g>5A3TuZlE0bbRd2e{Sm*92!}0SV_wj)bTtkIj zq=A!0bHvpl*4WRgSZ1j>!6z<#I{);?&)zsZ9=wg60tQBt40ttqf)F7*?$*;RiX#Z2 z`MqbHz^&iEguB1+4(|Q(D|qYJ3`^gBKOcI@2@Ic=o5mA> z0J1<$zi4jIBaC=dS_DBEl*?X_=Zh5+PGx4CJZ9$Sj-+vo0a$Wa3I(1w&hq3v^>!FXj+bh@`G=blwZR%zYzta)IM#USz zb6@(BO%wKR+DNp1M2)X*=uJVl06mQjHcPw9`Zg*6*MQ;S?Hx40aU8a9-`;5y+Ri#F zjammaIF^!Q=w%yLzAM^fh?undhabd54bjHkte>frYb=Z%!=sNL8zDFygh4p;+AN63 zTDa|CZG=s8<5;9-X=#y_Mva7}!bJ^+<2WR2vlD4IqGlu3LE#+xy1KLPqiv0zFND*f zavA$&^Zrp&=ejOigrT9$&CW45H^&;rrZ|(ylFVcXW|wK`4J}DSH##UvyL0W{pppq; z#PHo(6vq)AgegLMy7fEBtjqZLIH^>M<(Wm?l*{qQAJ5|ABG8~#D|Ou1a_*otT`9A? zT%uZ2R6EDj##+|y%2;?bL?za-{yLgwX&1yroC=I`uis^ z&R-=pPhCJ?dM6KDce`2VIyH;4`2)LgGX$BN#3cKi3^g`^+oD=Irs zGWV#?Y9=>ou0+~nu4rgGYiOEDXf{m)S=5T0@JJxZ4vn!;*EFsEpja&64y9?SWu!DU zVFf{5NRB8?W@Kk)pw;~u){eO_N$C?;4sq2(OEo(o_8$DXO!31F`jv{Xn-1>}S#t_o}um|?DEqC_s2k@fJS(G;WgBW1Ndt5zt#H9v%u zl9m$0w24GWlP9JPt4M1}R_;V=@cleJo~b!ek`@2}AOJ~3K~#S?ToKi#wf>Q6Jl$os zV6@fPyp#nz&wEV!sHHWri0%+|KuR?`w2c4BPJhUW$Ho-jxDTj~Lr?T~)0GM5OGN>zR`?yi{_)|B)WGu4&4)~e0~HsKSFtW zg0KDQYdP;U->5;$86LP{f$Oi^&zCO$3BUYa(S*pJKEz+V{{_7M<)={zr;phO&cjfT zJVr-NzRK+6B)dn4XaMtC@}K`T0XpQj&#dvjKR6y{=b=B(?o(^r{l49lKlwZZo7Z;n z)7uxQ5YiJ=NFZqCedgshekRXgY32Zba{3xmSH75cT)2}jUH(>L5b`_rMWPLQui}G^$Xtd>Jyo}>Y7)3<;Z%eB3BV1@0~``OM1fY4qlE>sQZwMK6PN2K>GAcStgu`*{A@DohN|TnD1P^8W2Aw)>R~yA zs`luWd8Et}(;h8lvR$&$XIN{F_ay_PdCJ1$$NO9Sr%(jm^?+n}9; zqZ)S7PqW~V6K3&O3etGwgilgSyB`D%&nKSWYKHzu02bD&36IJ)vTPB-j zrJ*@AJ8Nx~C0nh9@xg-!DAr1}1sxPdH+1KHx{U>*<|RV7qWu>xmYAKLBbk+K-@ct} zHp}ATBK4A?-bMRpc6OF(waUoI2+52Inj9P)qz?xnT>Jlrcxq!`_xERM*BTF@jYc%1 zUr+SDF=>wMv|CDb^i_}4uted+5&I#kT|CcYHLO3RDe10-BFbxA!4@A{62ALib5QGt zNPF0E3~X$;EH*UgG7L*z_p%eI6(%jhYjV2U7GW?MaZ~ilWJiZH;3etv%xA9ZCM(`L zE8aRsWsN(7Lx>Y{tauF;MVS?Eod@+YiJfU$`8bQBj2eog@^L09Q%IKSl?{ZbAw-R~ zy+fHbdsk|ntwTxXfTuaqo>6`Mg*w(q%dkABw{HCBQ;F|8T#d~!mNz)a+;T3Lsn?CBE-dQp&n-dJK4ylz;)xBaQi*&*v=SBG}^R*^(QwwdQ7; z!$$s=u*a{VESKy+yjMmwX2A6H)Mi$X4N3O>A$p}`E?8uX@A1I&4243G-cB|P9rh28 z0qu{d*eijFstCi76URQ=hX@wl1VyTmLs+7=oW6xrgZJ3RA8E0!OvqpNC# z6rR~p(TBmO((xZ(c@9(6gDk#-MN_u2{1OJ6V-FA~{4i}0Dp~>gdode-$p#nk0 z6yJ@_i&YhE>~+QF9iGq+-G?b*G&w;rz)O3bgC+<9UiqSD@!cQYxXC_|hh0ns_uPID zSA6KWwmIq#Gte{|t6PkYK!sJ`%Gp7rvRah3OoO$wO6pL54g;^ymrz=-d0 zw6K8hdmL7dnOg78^NDvpodk-HT<62#3a>bGCwnOquMe^FcXl%Msr@YL5Z~`3nCKyS z`uTj~KOW%UuDTZFI8WO)&o}?*BnG^7-u}`t4%a;fF8LbF3B>L^m%d2Qrwi=y#_3f8 z;b}g4&0#+BsVR7{$qUXunf388S~-uO-Ec3=X)b@?4P1V8lG?{Epio%A&HLoU7P5X1 zm%jBayy#<}dUzCb61gEsB!V>r}Jg5 zvw>%}31S+YGhy#e-tqP8c#Xb`H@x$mFateOFsK9iJy=u$6%i+U!c+P8JC1VcN3Vq8 zQw)7=n+M8+!*ysZ^IK<*vmS=HqRfiS8;y%H6Uvn3>Bf|zM{6cg^m%z!*vVl9uXybz zVPMpV=N+S8F`)qkKJ{C#q_i-_4gtO4A-0Z=lCaKaYd~2UTTbES@H~%XGRfPnxrOgv z`30`~!uyFUO&A2^^W!XqHI~8xIpO_A83YCNQXh&>GI60Nsw*NA>&8fw-m*|m8gYZ$s$G`KRfCt*zjQpUmT*lpQ@4r~cpfpWXxXB)N5nZ=Xp+y5G8Ys% zKAu*_J6X=T{LO;XWM38>>bS$ z1OdzSfNa{MI1`Xe_LG&Gl2RO(^C_wjnUu7YV&A?KSP4RcV8Jq0!1r_3ZA+07ag|E&DG?`B6;?yoJvzb~Fc$=mdwq-s`TvKxcaM*&uJiw&xqMDC zpOem+X(rQ5ZcUS3AuVk|?pG057w`fI2r761#Z}g?Ulny#mR%Kf*ZW-%FDNXah_H%+ zTJ8b`D$thRlD0{cNt2V#oJr1^p2A)RnCeu0HAO#+A1c6dadfI`o zS`=wk>SgP1$LLk21I4tVs5y>C6f;4X!AT0wf) zBb^@8Vtl2Tk&?g*4%yZ1OZU?#9Wp_ldZ&>IRX{opSrnb^UDW3DAO+*Di<=(9aiT0w zbr2?^>`Lz?@N#r?G?EECdV2?$pNbNA0f~gp9uRKzezdQOsU1~^)yPRHji4Md!!AMy zmiH{Ku4Xo^$<;z#B z#ukGAZfxc=U-=V{?ASu6e7c(3c;`E=WqHd=ol)=#O^TlQr?~v0x6|F-#ekQ_aU5!- zWaEZ@AOaP1v=c_pYA*lb^W6Q*J=%?GFwdjJ zNPOUSc0BkcuKVF5{PK4LKng6yRsXPt;q;5xLNO2ow1@;xyLoQB^$);8jypGGsSKD6 z3JiDyoW3T(b#LwBi@z9#zZCf3XaB@EKlNH38y;XxC9?;@>yt3PuI*jW_cED)AMk|B@-=dce7G8D}Z+iRbeC*iWNa+xdIMfP> zr6Sbi3)(kd!9?FqY$2HRT+ZlehnUh-EenlSSPsZWNJM$@zQ=g+xrg|qIF%1L9h`o4 zf(bmPlpyWe?DgO?pZ*!{rZGq^hL#T4{GuLS$`mv;!LFCM^i7u#j%^_-d@L`G5Rw{4 zmd^DQf=Hy9I!Cg}v)DFJ#ZT_p&AQtkgPxTT1~BSsYiv9S`#I^z6lySL4vo*vN!}A3V68Z~gopMh9DAB*q^e-^CegB&`XF=MFO?m9gCX`ywhe zvX;Qj8N{vDY$~+`0i=i1#3RleM5U%sVal!))nU;o&A4P$tbw!Efx4MGRjJW4y@dH4 zr4$nr+O~E)^h@Z)3}xA49TpZv`jNKJt~0qF`!^$XMn_RvlPhwJi|?m+ta>wWnz1NZ z`p$@Q^Du=L_fHZcMA4;7Q4UR0doDV3m4-*=+?1Zr_n8bsthfoA3{}~1Kv>MEkYUp}Se7VdvrGc>%xfDr&m$@_ zZ7SWO5G-(zM4Gpw4wcvT9jE-iACDp4Ey6=ya6j>Ld)PTS8BQ7Hhx?^;A>xN+Y@@1U$ z53gg*>eukEpZGY#hs@d##3k$tGVC6+m>2=-45S%S||JZ9w%<1iCg6hxF`QUSj5Xh}u6`OE*#m%sWY zdN*w|)U_z1o`)?$I-Oc_202>Q-OPwL#Nt>pzgxFXPyWq$lLrhMM@cv-zV!9$c;JBt zc;JBta9x+i##!o}S*C+oX2dL>=Q3MRG({Y`m-q0&_gzaQg!g^!lgu*%wSDOUl8(c` zKrih*JqC3T=V+emO9)hX&{>~y7;s&rbZASZ_{KNB%RTq}n&1EaJ_g-apPpV`pCFY= zkV?h)^K&n~;;`oB;FOvD{2yuqMMOwygv9fTLp@0l6j;#Sh&z@;CK{PB?2{QGX~3gF zM#u!-0U$!L*_;vDVm}B1QYqa;W=yu2tUx)YgrrUgW{U1~$^>#7*Rr^jq|^O+fMo`r zQ|Mk{((??mEB3oL%Wu##S!xYJH!S0BK#i1K{p8a)`ivwX;Q4u;QsWD>xNu`KO2bnPFK{UeMxBrCOzxSUE?cBnOHixB4yRiT- zn_;G9C17*I7rw$&B1(UMj%1>lF{R(IP{DqP!`y;BYB-U_ypeiG(A6I0`KLGViU0gK zJ0AZz)hbU{Yby&o+wihJBcmBsz2+3&@Rmzhwd@?8-MEn{AeCywb#rudq}Z2E)0#+W ze8QT0QP-(554-M=g@RyW%%eIYkV4Yfm>`$)*s^6SmtTJQem>Repd8rgKyl>SwS4=g z<8X~znh?SWzSLniC6%9Hae}qCzmF@=J%hKcd>^aN|0?({x7_pwj!H@Hd~ty5uDJzz z7D716lOr}yJ~YTX-+eUacFm(Xu<0ZHiqGr1{e1Z=U#GWs12Y0<8Dm0uENov0;UGt< zLE7Z;%m#`^vW)H8!RhU%(cHWfj~97O%kiuidvJHS#9ns~%xmo6J>Pg9M&P`+*7MyDuf-bJ zLJ-)rI~~l3fDc`^lvU@Rz~%3~iCcc;@rCQoF-4^g8ceJ?mL2!~9Q-D}|FPA)`J^Pt zD}D@Tzn{ft{Tx(G7q@SW^0g0s5~&L8+4>l*2}hd^1mJl&8q6gA)jTw(bqtwkM3}|t z%D29QLLp#yI9+OX8C0-Zlo6E@N^*!sCF|*eU1_l-F#w%=bI+|?x#ycUH2Kgu%O%}Y z9M@gTs*VV&nj%1Bp*APTVjA04?Odj^8jECuL-`ac z66Kfu;|y$ZdA@g$yLSwO>y>TJ#4*s?0p!^{6!4bUwUXYr4aaGwS_PVS?*4r{m7)%= zC>~7@kCBWzBoa{|itFa)OwuP&)Tqi;r7}yZ%9x8Ns>6^fLa@qO5jAJ8m}~o+OfJwa zTJz%?Wifh)aK8Y@$~CI^e`e+srsXEZ64n6$kozB}h&`0hW2KN2ueTCm^W`(7QWK7vT6kp$}U?WVMQ~;99OJ4jn;msP{9w4 z-Eg_tDb1{Tchz2YxEFnW<6Gf95o2rOFRG8${ zRnSrom-cl)qPXI)_Qc}vO$2#^q@+=*ib>Do;~)PN^@gr=s5)p0MWcjBVilKv_YcsT zGR7WCC$>{eqDRx1tpo^YUzi{z6oW$0ARIhTqp^-N%ZL|HuOdk4@Yn+nV5gSxM1Ky) zSY{FKd+Z@G$p>OPu>y(+4eg*!0JOf7_k9Ck#~C>$mNMSAN1 zPBcOF>)t}2vZ)6qi_XcW@vAQA^H?8kVJIE&x+_0~z2XF(?awiV#dN;F_*f1h9O|iJ z`LcHW^e|Gup58uAIqDdrk(5k&E>a3ZxrJj+I*Vss?4w3DF{Oe7XmwQ7D%CQDP%$Q? zu7mb@l2gvToJGr5G5$Z)qRFoQCJ^A@5}o!p3nHv&YNQ-rdcGr?hkCxmWP%&wrN} z`UaQ{s;H6CITx|E02L+Oi@wktrc^+^6F~@Qi`Meab5CT)#y|7k%g^VEYc4=%v+SV| zOpsWykVN7{Uh3V&*Z<{WMp?yu4?e<6ePbvkNF*fv{lhdHVSi1bj-pLsG4Zw7tY}W9 zRdI8v13s8ZFQ6_eP4}q-sgmu@>`RYTIETIbV%lJMv(rIkcD?B+?Nz&S@_0)-7PcCbf|F+&)NCBEi^D083YK&5!@W z&U4!6ld%524d7cWU$|5|y5xr;*#v>d?hl_qZQ!xzL$BxaU;7KhmcyOSMzV+dA zaQil5FaACBziU(a5^VBd2zh!$#*45V|+OVnZqTR5xdBsi)A z>=-X@+(arhOAtt!oDLrBGeYRj2v?sT$Im^*O&>aqt3LXW4xt=*j+_4VLM}UY9yTCE_I$C(1N4*mcdHtFb_51T_3IeSX_`e+!eB4A zT=7oE`(9-JvSZnz;HM9d@P{X#<#$hPfea8&L97Mr#peCx_3><1H)EF6?<*#CVX^6QKDoQZJ}q3MR=t?r^XgoYPOOomxM%Ofa}} zPwBH1!eZ&tWu$iw(m%4NRLLpjmvpjTW*B$WB?x>S6k1yUG<~a1l(nCSGYG6J?Qf!l zu2idnIfgh$5j?lpk}^`#kV+Y0#Pc|&r-yn+(%;`tjdWgNSgWt^836?qW&5xD^xz~W zVN_Jifs7S#v0+gG7aZL~)mR@wI4C8UPz4aPMZMm%lp zE&{!7Vr!!hgFGSxtX>JfT(9%5iVg#o&_9R9$fPv^_B6!a!TYb@ri;Lmc1D@vyPRi3 z(wu{M5^i3<-!XSXe3sW7*~HgAaw%@#Mj9IvoORh7aoxP8kL5k$iAIo(j46xT9^c9J z|MnBjIH2W~KVbiPu$we>&i5fHIpqk4Z~XJ6)Tp%H(_UqxB7}A?Z4iQbDLLbe(+L6( z`KruLL`BUfXpBl`@@a1Q;-}g2{GV8T#8Ucq@1h_DLd03Pa5anGauu=04y0^nz|~BE zI-_G%C9PE%AgD81sVU>ORcum%AWu(E7eZ)f*1LZALms~G7c>ZnHc4Z}ZjoqdW%UVX za_)t1rLj@+!qz^c^M*+;PdwGgR0-7)FEa=WN(K-ZRH#M>zWL2>P^}=Nyh8vWv*kvm zI8~c6-0aR&J5$D0VrsvezU~#er-O5#^$n?vZJOgq^7%afb=yz)+~+>auWz^*Pz1pM ze!owRm?i1hC?mZXq#Iu|D(kHLst=C>pgKR(kcBj)Y5wy!D+NNiQ!9jM9Wh0f|sCZ8a&fjCg699mm)z zzPd(bMwE+?qM^l%fO$@W=^&s%N}lZ>hIkA3d9zs-H%@sN!$(*9|7R`8n&87At#u|= z1yP_Fh$xidu?CEy_|_d3-2G?%P5hb9p4!O2eDDPR>#LvQ(yM=IoVskYv3urR1lqbd z=74YM=W2<<=nG&=ZD~9@q#Kh^Y3f)@0yaI%4cA`5(q%guk-#Z}+@E!Zi2+}4%Q z=@BK^>oR<`gVmIh1_kaN?-WQu}FFr*G25q&j?ij+~@V60RyPY2rRsH453 zRHXeik1zx~)M!emqeb-nUST^NhI$<mw+ZOb;gj)@Zb1C-9qjIgLvA>;cwn8oAqITX7vEH^2| zV-)=G0932obcs^KGGoC&?*I#%+p*&fgRfD67KvY^xiYPwc&U)9uVb;v=^RK*H9W2ja$qP8^UowHvb zq>aal@hsNAMQ}Hc zm4?}WyGF$`by+|V;C)*U%c@~F1zL75h;&2i34n|ddX zGOiv3u+X4yfF>}HE{=;>(Y zwD|MTxgA>uoXAmndfpPi(phMYK$;@3(i}_sM+b(mJ-}o2WYHNv^tO z96GzT4kqU4*Xn!bxngGhGFG91rzvhtDH!R8UH5U^!reS^+f|&_73JhF?&kcjZG%O% z&@`$wEVe-+Y*{k(K}aLaFjGk>VaU}Qrd>-I7%0$~Na5m=BcMfyIe8GT{8=AZC>=b5 z#X87loHwG!s?vs6tt#9I6(!nN89h-Ze?yf5x|Gtzpk?U+j%6%)XDmxk%lGar74g%4 z2H($=v=8}A##r|XBg76#&5u`Pq^Oe1S6f?KNoXFA#|if7?3Gw7rb81=vA%C#rc`Jb zi|u$kUecggCP=c<-3lO`*=s0RMTar{d$CxYT&RNy>kVyeo@ij7pTQf+lrluB6{Xx3 z+qO%EeUS<_=Ii%5-)>;q_n9K39!MsWV7~7j9$;i-#MlB`CNxqP^_C@=BxKvREo3qo zROsUyA$n_TTPfeA*ud2TV-vc8DjuhJU3h!<5|78pXEOM{Pc*5mi;H>5fT+k|DLTRJuUpaX zowd|Eky4XTBWo$TnQGy;q{?v^@$$@=J-v7jE%OT0G_T~Hx84JtUAjRCOmQcSpx$vo zHNoNp9A67o3?*UEh@^|T5=sTsp|t{@mm}5@tWW_O^+3T$m#+<2+GN*#P2>{%$*ZjrN6JPkpmyWz0HO6m4LJSwiRrCli#9nKePX{!83=S1w*Su=%s-r~SZ>gN`|exKnB zz$p0e_S08#M1FvAr;)?S8Pm0nM%s!EZ82s-2w5_0k}^^<0x1qwf9g&CyNW2I0WDQinz{VPv=6+ylV&@W-{ht*UXA<025KFfJ>Fhg zR-Vie%U7|d?8I{vFujd=GRl;gKmai*x$J^dx#NlTZ1e*2CWUFT z$`mXKWP&uS*7VR&)yU>`|IBj_Y@t>@ML{hhR8^dQ#(Nmec{E2PjfoZ}y-_wj_bi^* zN1GD^Lh{}yKf2`uEMBmJ{`@QtZ`?^b?Q%qSJJpdwc`{+3UWMk?P7r7h=!4`Clsnx+ zXqBbJ3p~7>M;(Ghqr-$!B#o0pa7buV9kSz{5p(}*9T1o|v_Q_1PUo1B3fcsW1ibFX zZ^Ob4Sh<3y{_+UzoP)Pt5(FWz5Rw6?e%d&i`B8^- zdLPxT0Y|qAA`0e39U2-Xxm>`$=qz<8M!g)LdGDwA{H_1ab)Q_##c%pPTmIGN7hi4U z%$_dnz@us`ORHRr-Pp|HkKPRwXg^YNd~+k#z!*X}6tD<_DnnV4Oh;fQ+Ra3I5*9gl zwxUl7;_WL5oCWL?3vhthV2nvmyR|h)&0U@jyz-{-_j(lI3D>LmNYsAc|Avu~m~#P_ zX#*4sbfF9Q(tpls5xq!2R&mPtpJZhHmso%6<-F#DzcMeyPze-z6SU1Lm~{;*Vxr4s z#Khg34SVOa-1_x*bI$4Wd0xTlOaB9w9%07DHFd<{+8UuQ`iGY5ZQu z_Hxo2dieHbXVY2Rj}X0l_$wnk{>+$e&T#Z`l+q49MXiH1NB{YmblxtZQW05Z5nNxaYNmj$!5VIIrD@?dwV<8VaPEjpF}q6 zv2o+ZQgVEe_NEAFXt3!>wvk%YVxD(!4#F}qp#}Jnc)Wy!Y~8vQ%d*(BXAi4Zt!((J0li z#~#b}?c1mh6*aa^wF>DquPK^LQe$4*mMvR2;e_Kk;)o;JzI{78ckU!qA+-%Q4V3d^ zG@4>D!)yuhsZ-WmiW?Ji5TVM4M$Z=E`y(c=#+WBqf-ns5ygcp8^x&lo z87z(?m{eL|JRJnYWrV=XQzL5+Fbw)@DDJ`xMQ4N}k%*RZ;Tp~UEF8fD8}>rjqyvPT zq+Vwfx;`kX@-@}(EAje*v#&Y16;AJiLKJ7-YMqV2{RA~NF*AmLvX?3M(%#- zC0KN-KBg5I)H%>i(Lv9VIQ*fPt+kifX2@bG7)k53E#??BL+Z7;SeS<$KV5Sbz3B~11_iwz9D>@Vj1ERfNxcxIx~f_gs5!*%J5It3%**BsLI`9rs$#^2 zBNIAIHPM0RxkMdkjYhcnE1%$xw|{}(-0@MiKlf{@)D#^ZN3c7+g@vg$CW3tgK{ZqO zbf%V52w*DM!`;7n52v2e!}ou+fz`+LFySgD6f{VO+S2B$r5x>v6r1~cNgAgz3!lX; zDek=O2GTclR<}*QE}a=SYKE6mM)%o?ukMrG@f~jz$~tyaA?=9KEcIuG6~t#Sd;^ z(<8s4vn9f?3OV-?a`y5q4H4RQk zgSDF{?!BMIYffU&O@nYsjt5f}#nw^Fy13}9v$*Ns&*QlV)?qP^SrujR@y)b$UB>OV zJ;bF~Tt=#^i)p2A^6s2fTp)jlTD6I}PP^SSn_xA4g?{FLp+R#{3L zEZZy)!q_~Dis_GF%J2xq%O;Dz67(1lmrkiu9~^T@HK%Zg)5wVS#oiyTel?uQ@;adZ zFr<1BQep){Pu*J=!*6y#&teD{12L}u#8;EtM*+d8=Nxgh|1&hjAerXt7oSK&evBGbMU5&TQx1v7 z8rYMDWH+@}{TLjnkqX~tV7ub@PyPwQECers8s!78UCRY)+leBWR(Wd7rc^C>)nfWX zJ!Weq`Q5`N9r@*&l~=MMT){t?h=a$4+^ z>5~N5-7s1(O-2YKkHV5D@tDKMj_&4+HK!79u7w;ldwtZQ2xNlq|Kd@Np2S)}M9MU= zLjxIe#Fm)A#E`i;CI1VVkB1>FKGby(0#!^O~bzjYSAK;3aJqmWJ8k4q(OMHRELVOP-}*Yw#b#Vg;JAJp+%{w zpl(%C!sb~PszGO~Oq=sDXSuP`4_$#^NrzO}WLeSW~P#~#Oq z4I8KqLl$*)5luD`HI2%^=w8;ewGjjw4SD{lr|9YFVaB$3^PAtqop;`eZ8w+(O;Hal zS+bP%>(|rO+R8Q+GBM$^V8MdYK2$`6#=}sDQ;IUB_+WdHK4%v5>;_`7Sc!&L@O?5F zAIs9NUtt*H`vF0aWoBlY8l`oo(+FU;WW#zeJ;=dO$3()xb-{IWv?dyj)6s#yf3Rld zaH#Ed2ozedo=8LqlvhfopH=}AT~WUJpX|*_bUVkMA7`l|4(v&%ut{Gmn=)X&5NjiDnfhAHq$$>0#RjIq zu!s(%Q_rP_<;^g$7^EC1sF7y<_I;3z%m{};H%B7j5O_KE^ghQ^zxWPc{q$A*<*~as zqPrVkh3xeToObrxm;&Zu5p@$nn+fI77OmyT1u^cw>pvLT@dR~Z061GZl4Z zahO%Dz;U8XdO4I~5cT&DP$MJMNJ%16ZW3$tqT^E^b*Kpx>2yDilQ1639+(Uh$BCLQ z%_|AtN(JaEh}tH`^3+I06o;F?c?*|bu!cQ59%JFc9@4w-=hQ22;QP1TP1o@kan|eJ zT3T(qAWxO!P!B9Ub~!?XJhSdOQgQ)-x0h?)bv7Tk{7tOeJAv>-$wIRX+38|09LuwN z+aGDU@MJ7^1+{WF4K2r!LGXkB{4rns&TR;xh4>1I5Q-WU4T+VU^rrXm;$1hANQ~3K zJkD6Ph9CUsOI-iuZxWXdBi;~`*roeurdC_=35uNBT51F|C~=q@{>yj$Qz(QKI5dtoG}#e&Kw@qC`+Za$uAr;nfB`W=RYex`<9{`~W+dCOIIvSDa3tk>f3KR(|F zBepgb7<`m#zx{fS>u6-$-GY=I%&01Yz{3s3z#4*#ggu@vtZf@wV|w9#JOE20jbvV6 zWK{ANvk?Dp%+sr+14Et>T?XX~AXHTJ+kZX#?B%#hV!sVX1sa7Asd9db za2VK?X4i(DoVjKJtB$SV^B11VP!9TBaNTh{ljK{iL`jfXqXObma76b4+M>GI%?~_H zbyp8x`Qe{+(Aw%A*!+~{Yy0L6*$!-a5t5PpNVW}IbwGb-${T)7 zsGY3rxGu)0O|f3oWfU8jqLyOYw(aCI8M5&>zVDM88DU&0jy&>61_y_9VLV?uYmJVM z5^YK{BP^C11VX8hR6I_>_d(jFCSuIbGPW&CdgmaCwj{P~Q-?(~7Q^>_`nPSP;7`!j z+J)`rX3>=)mA70$T-PJ%=+L?e6~*;(B%LTz zO4F%})AWNiD~I#Qp{Nrem}NT9qHD*ICUZlv16cP^8d{HrmQXh-IC}jNhGsS7!HNW2 zdl9H(!G#x|9bm;tN3hLMy%UK>W`s81QK||lYN?h`litFge*Z0Ad(I68DKRBvWemWhA#oYhclcZV}Qy+C0eQE={(z`k1jI)_9M(BNNJ+^4(#dQz!n>#M# zwAHOVwrzyYRI|~6=&V1_3kZ}VnMmNeE~(}SU--l|T>s(om>S(owc5uFkZO4yi`SgO zF1J7+Q?z$cf(E8oKyybY!~N@sQN`qF!0N>_{NdrPJoVsT=sK>QaW|l9fBmy4 zyWU3BTo>NDiY%TPAt<1zcOq1qn2u^gAKrhcUt1LVse&q5r3Hb9lW+`-sgP2cX}5m8Y!rE9KL+*7x_P* zIF@lYLPBNmyn0rjyMlkb_%fJ7`~8%XhAN z4QedMx`%opgb#l4EY9nSa?byG0_-Nf_uD6U=kgks^epG}E8BUF3^hkMoa#$5wxS?H zazTOlBEqcSVMKtnTyfqxc)0<_Jw+WZbvOtm>EAfOT{pd!urI-PZ+n)_UceuRvb^*B z9@e(B@!r>8MP~Rhc6vThA(>K&m?J?%ND=Ud2foN2cN)B2yqv|f5X|@<)v5+3wv>s8 zBufCf9**v6q(vxdJh!x&Xr~u#8+iCUtG@;CFx=!;QU2V;DyC#!xESY zB8J~=LQM&Trh$zr$QCqbd!f{uQ|r;3chgI3ylFnuL7LHlfGQp{3Gl-%c zokw=eXI6xar#F!GbQo1G5i&e1`TUI=;n?Lc`jkdge5v2$XaRzL{`G5b;N2%JAfjC6 z_FnJ%tS*?dyvt~7|tu5@@wTm!R zG&LnPoyqrEvScaSw{O$vjPDakE-?BONjB>di^WL*7eVO0?;Io&w-HAB5|783A|w`z zF*Z0#Z*~ub37;8Dkj-XMp(2ybphCq?e}dN5)>88!!jOgrjAle5Gj#}jYnJ-ZGP(>? zn5zlKLm$WJZnUUfl+x-O8f=ou1=Ioie4luz5uBYnchcC}LT+>v+m>XEcBEk3%e3XM zz)8l4ggU5M2!ZbhI&UQmiNxY;*u06>)>alR>SSbOgyvYBeSW}_C5w6NvBv<|y>%Or zcpNEhjy`%V&p!JcU0q%5*|Ue^k3Wv4rY5#++s>pxh>Fd{JoA2vW(A?qu~b(Kpo-Zs z$>f3((iDs7CNwlC%=~zqeHDmObqU?l`>|zNSR$m(?2=O^NO{Vvk;P*7l^%~h_7LZu z`$kf!Mnlz!=yYx)j+P~A&s?PDa2u9tv;I|5i0Tk{Dxkfin``fXK%=deaS6nr9@#(- zHtYbL6bvay3$2gyJ@()-PFasyEd;vMD3q+krIZA2KZ_aW(LY_!DHq%T)?$dI%Io;t z#dyE(2N_1~&*oR6Z0Q_xv{uht!^91;UDUqJK~ofr^z;79mJ`KeJjfFff+p`a;!j1&c)tKPZ zSH6+o-SIIdc5FuppGmQRqfWkvd)K{4Y+(~`|KPvj1!kK(YYl=9?zsJaHb40%F8YTh z)GMFKtYpfCYu|MiFFgJmUi12Q;CYHn;8BOdakPu4=jCXSf;LBT@6T@Mx3_+jk=_kB zPMjKW6^q0(+F3n9-?A@`Qgg?U#AG?f;|M?7l z`%DIxz)*e;UgRDC03ZNKL_t)oIr~|)xg^R1@B?#;>VSzLz)7Xp+uzTG7topN&?Znq zpbCY#jf!pS#$z&o) zoGKO4nwXETGRW9!ZvDnD`P_GICNM(%nuvA;s#c1)gq&$2gh+7Y+BdT9uCH@sN1TkC z<)5#)fcx*chbykQ0;S51SV}2sgdiG?@S8h+&c&CkV4#1PP%LNBiac+B+qJy=J?ofI z0gdKDE{gDV@tw5Wz&U3e#U=0mG><(0VKxm&?fPZn>St1Vo7>R=ibDkxwIAth5t zYLqY&sT99@d>3RTBw^iMSCjDi`P8rXKynqtM)}xd-{dF)!)o9|=N^GGC?8*QNr%3+~wXJYHq z6l6cwU$=sppo%8vct!>Wu$W-5FT;egkqL*XKv9iii`#FS`U3NVfZKk4J72l+1LSgf zYGe)5K|R%~9x3a|1QX;%K(%V4S_MpcX_V3dOfzO7|KDK!1VKR;*oyK7AVgV^ei$03 zm;F0I+08}>y=aT#hHd!9forH!2^bxK-CJOBH+UhNcGE+m`3TW$0Q+!wz7NA87&%Y5_DOV5w-)mGV z^HYkCqL9AaR9S$YMygO@vilI0V5%b5g#8@20LGQhTq&X~Gv*SkRw30URMGddTB~ad zMn?y+Ea>cPWoT%SFjVyP^ssH)HjSp3$?M?YU`fwVY*1|5rmMA+!NEax?b=2E$R4Uo zVs%@i1V-OjXKB_zk$#oWDl(Z23l=P3&z?Q3J@N=9Ooj?**RUdDti}7qw0cdY((l7B z(ZaghT1&L8h@piEp|ee<{QwoJ66LGj))vW`Oom=ykyxas`6F4DF6(61u3a=WC7A>k zE?dfcTeAMqM_CYy6K!guT7~qF_^ep7n!o(zdE!PFGv@oOYHMY5RBK=^z4TJX}uFefzTXEE2{d*f%0(-O$Vk4%wst9CzHwdVm)wMm(J^Kj~>rYrS#V zJlF(gf8FMx#yxdL>)>ZlFu za%ofvJP}mT-L&>$%21Ak5JaUzA>B)xPV`mZV^pru$xT(Hh*oKB|>OqO=*!AwU3t#S0tiv2B^)*1C(UYRS!gfH7k`Fv0%Av`L@Za~|&s#2Ege{;hA&JBi zeC@9P;^Oywimt96GC@F%Bgg_V)j>|c=@*@b6N5iI`Ae3jMv2QQs)9z&JNsxZx#r#6 zvF2Q3*5oi9xaO4ULVsa%Bj5P!C;0dWE?_LZ5h13SVm^~9&OAr5>ZCQ~&~(8%2Xac4 z=!@rHbRiG?0-oD_CyO0H-kZ<(mZv!HtQvN0-KlfK=4i*tL;t#pORQQ6rVfJI72Ur8 zmM>e*p1yu<=wyr|N;Pv31lYEX6OEDyJc2-#($Z6@W->v(G&I%DFc|TA?cq%v3IWrB z#rFPQQk~k;%@%@j#(3n(US_N~OM2E&BenRac(Dj1N=Y-J3s49a^_=S7adTI^jKu8Em0=p>zcJoRC zKSIaCWmKsuw!QcW%NDgWJPh?tZJFv(a>|-5X=Um-&}FL#U(W~*!;wpvMyjmiNF<^< zY{+p;c+UUaS3|{XEPk~nqRfbp8kyjQbc{D&ek%_>+yFzb;RoNC&43D`Tmo6 zAmFVhL}?oypfEhf;*1Z(s_+E*0>SJ4WcN zq&5(QZk`&6Nqq01js(v=_ZZJSeka+y#gGcv;kk?=$RQbYU4{df2_*;u7o|LAgrLev zP>|X;zgh*<5&Yc?(dvRhIj9hSi{c6+4zD*+uZ+}bh~Cf(Vxru@fOgXIJ;?Tg9YRw# zoOvvq-vviBv%SASO{AF-PZ_?khS_I?WLG**4u^tFVI?|f>t3nD(3}+YPJ#&qb)I13 zu70pQ#Fbm-;(BBY0e$#&PZ1yjW%2I zA}@(UVn{;5zJvk|r7c^b6xwv5P)bXIr{yW76!`J*0|KEfElW3O0wFAc5S9dzuq9-3 z632GDNwy_RBaN;+b4PRUNcU)Y{y67ejU0!B!tYl)uh+a}+49WjF6Vr|-_O=SFHrxj zP03?TlUvR~4O`kEv=OXW>(nn5HJJuPBn7;tJFUBLMNvegj9XR|CDX`sHb**_V{WdL zAST*LOOVaxsZ>HvoH)wx@Mf}EhbW3TJ~>GcgbAusFPC-phb3qiHrZ^Jlr30@0*)R% zLJ$Nj0xhX46IV=ctft|8t^0}95HEK$+9E8S=Y+aMN97L=bA+cpy^k%cP z7`;vGYNk}gLZq0Qnqq2dih89&sZ?TaPK(ONrlyz=0+xe-Y%YsC&`my{Hw{L>)YKH^ za)rss$wd1yH8n*pmt)tiT|9jB7=0rn{N#asNn_EQ%TcNL<}=plHO^i4J$!(2xste( z?Hn0NLO8Qohr;kMX_LLOY6;VHMN}$ff}qBN3XCAM^X;!6pJ%IH#*&l zm9QS-&$I+MPJwUz_(2GEYF8@ew9BC~Mfh`{1vP=OUZQ=`e97PD| zEV#*FrbSA8zY175j!TPlnKJ{$c7KvbzVLS75$H39C4zG!-tk{$4Z4Hf~Q}u?U%CwZ-4od@O?#27U%{_e)S0uNfa58qD7`n zZQGct?mvP5PeXk};_wQPlV(q-Xe2%(;Fd3cp5J@zE>0GY5Qd7ev2i9&Rp}Xe5}m!H zD5d+s4nkH#k5mZt&?7AsPrCSGgxJoaKZM&oij-?C%u*SX3<=zMe|>da?bl?^h8*(C)fVz;O!dp-;QpgYSFv^<|MVM9!-cF? ztBee+(5w`m*T$mwE)x?OItFYO{d%H}P-;Elb2YI9)lEy2NU>RTV;Gv`2z=ECG z`}z9Yp2wQok=POI=h~yVo~~OkNS0!Wh???I%RWjdV2;$`yJ@N)C)L}FI#q{k#LJ%D zi(f2Kb+>SoghrcqLjB$En+SvZuCh$zSFg*dUe*tud9J=KWI_t}9l7e0tkqUiM zVQB7iNoVg6@BYj8^7cP{8)>CEvAHnB4t+X9pZ<9Z<{p9Wibie1Zk=H;cbGfh`&#ZE zpF!+6pE(2%7bj?uDWnv}hElLw3Hm)nOR-AY@MqV$Qe1cck2HlWk~+^Nw(*Re5MyiR zpM#Y5KjEgk(9ez?J7@)FD;2WYEa{xqv#-I*g>UIA!SR1u?miJTRj%kkiY4<$`ntrl?dtH+wHk|+3M-*TUZ%&7;CVAF`qhM&)S56So(N(b;y8NXSuD=;na_O27}TV3 z-L7BAJuMlNjOHypNE}WV3VX*hB%H6qfRT8 zyvO6Mvn|GDGq%qy6bdYO^W1pj*EqLOv$1}0D2E~Y9(aI#4?KYH`x}gcw5`31QXxGO zj_$vor|!KFC!3>1X4$*v*Elw@%+sFs8f+m+8T(FG@sdA{;e*V*GRuUmx zT9rf~=@t&Hp`cYsT9M4FB8Aa*mgQzVZ<$iK4-1=N_h}q{=o_?lq>c7y`B8h95U}W1 zjjn1PacQgpYbrEBls*?-w9}X?>A_$owGM_fgP>jHP{yfC!(ORmN&p)z0b@>Q9M-ag z7Va#uE@W@iI0!L9Ih>@;QOtQ|ECkJAA8TG0t(>97hRMlsI#6_@n}*ed(iGCFbcbF; z;S0&}ieg1Bkr8Wjs9r2#C5T94imsHBOiB>Zic%xE?kXA4M@zViu%f7l`+-fgs`Ze@ zr3RjLoI$Wqhqh>lHfIqi(-d6*EYjLBK`UFR#W%Nk9g(Ews^s%DA}EiBtHn8=s}0kc znmKVTQd07LuK(J%5h?jo9ZA-66vR(`o-GWE8>(2qH?O8y@H|e1Aq%BVaKh)*KU~S$ z|9Js#x#~qw%5v;mlX}sL?&2M9-p)^Mcnx;A4|gn+_+YP#ZBxnh1u(6qX;yt?1T?D& z9A^vTp3O5Zxfqn-D-X?cSNa9~$!8w|sl%+cY#GII)AXe~_|d1%KxLU%?nzUrhq&%u zJgZhGayAm4eI4#lw_C#U)M$yQN@cOoc9JD3 zRKy$=0nzdOX+4`1~a$T_4I3<&E z(zpQW^@A4!i9PCC7ziP6(Qu03mvff_IMBu&8lg`K;`T;{;~8aXA9|-5s}6YSgWBTG-yH_ zDRQ|Ulu|61LN%WsAe+?%HHakdLkOXRAG1BI1bXc$m&-aMLFK9jF4N!N&*7V~Nw@SAu{A6;P>^lZGPBafu?uj^WM8-#4p>bS{@1 zpCAZ1dh{5}L5()^`Wayn1fkJknu;?frzW4z(;PKXHcb#f zyU1YM8JeS}WU{;xC{ni0e#zx>2078@32`$sYch4xofgfJ#cH{gD5_Dbm+_QEUDznK z%GS&hKe^?4de0l>G}=vRCiH1?TxLXwQa-J0r5yUSNI?gZcE5>Km^I1Ux`F5{xZHXB zk2rAbIF92|@~cnC+$J7eKGq&9Wkf23K+Z8MhOk469r)B#k+0nQ6yScn?kS*B)J}ul zF5Lee-2jADusyJb^ctufEwY!7KxHQ{eCJna9~tE<*L|Lq&}WH|x=_@VPb(44YMDME zNQDY1U3?+A|G*LW+F$WHc^A4viYfY81AQ5K8OB}fmT$lvx2>=1Q3JXjdS;Mi^e7^N z_rG1+yVDp3>45UUDrz^-z~wJ4_qgVo&+tdT{&se{TX5Yas!UT;5~Z?q5V5Cs2fzNQ z&%${-wRoqZ4E5_ATV6spGkZng!@l>yagUF@=0&u6MLe%g7;^M)<<@U*zVme1*ZmURtCybu_y1QVJm)!d|%V zzIl2DtX3xQrQpciQHoKC?h$R4&?Xgx9!*j*k1+INNXvM8-o@RArYVPt9y!3wv`b%K z9dAydmZ8lFNUH*22tuq8NG+<5BAE9Mn)-ALr~M3TuEVMbSry9cCITfSH6f@94IFd{ zmsA~6VH2KLp|j7Sty{9>d2~wOtXJW>jdK*&oQkflE-tzB0`A)P0IusM&cdrgBzs1j z^Olp6Lu03Cb7T^xs+LLEHqF2230o`L{VJx8#7-KnJ46sD0#zX;*9gNB{oQ%m#Ts*C zV~OQn9Ky7+VKP~u6~VV|{4iU(Q?#jeJkO^RmgybdOw~YivB*qM`4nlH=1kCvlo7rk zQuRWlJj0g$EYnBkjUj+aY;Vz<>_zv2D>hQ8xzv!k&!Ok=YN$yd;9l! z-_>8^6>mJmrOzK@COjYTnDTBTkTC70IOHFuS1DEuwAq|wNSs|fs>IU!7bSrIg+97c zFgKwsc^$dlWJpI(wPKo~CV|3p${<0+ft=%+0=@}?V`9E5Ht{JMTBV6K?Zi(;?( zRiPR*R1>`T#V_KwUj4dc@!BO! z*jmOkXUo#z*s;SVDDCHcDD6sT=(g((gL+J-nO~-dQs=U8wGuns#@v)8b1yVUB$^CO z2Qri&TNtXAMZ0CwW#{Pb?oM8{TrRVH`))H(3(WgR+tao*ja{BZX`FuCRvbf;lOQ=-Jv=}!q)qo>1sTWmzn!h*D{m6DLkkE?4O2&a-**W^7wBGc%je*1}Lz)D9jzlmt%#oH%g= zDQzyia5q~_Ba+MJXfqi%xtvWdXOqoJN~I}mTX6gBw{z;$F>Kp3Fquw+JSkSKHHLZy z=;`Uv6gE{O2x=@6CHX3=)>;y>nV1WhCQKt#Hkpj3^9}a*69hFOx_;0X;+O*&_?yJiZ_D z<~RQlAN$}(3>9qcQARZXHI1L5%~51TAFb#j*BTt;W1qcG2h+yRUZ4>UrC_=UL!`E-^cUj6WV;ZnV4tyC%*}m!(2Sn!)&NsA3KnScJ%m&c3dpS>>#C@C>D!6`SOc7bYOqO z`nEoKiwDoELg4#V=I7`6=tn-xhp+iK^Yc|^Cnj*ay7a!Hnm|aZrU9x&0n*OWN-Gf1 zogJpv9^mx2rXem=>xNmNbOWK3PUbUPZ8`L~aMyMwCJqpWC7M*gj-BV}VQC67BAWmX z0IASHN?2F{iyovLqFI&5$u%OcDQUQjtquZh;FDG%sW3G8Cw0Pb4zO5OP5715bQWB4 zcA-HR9wu37OX%p1YSp7uUf|^~dl{ZrOb{#3H16gNl>c)hq|GYQS%klc#-#D<*^io< zM+m{z!BI}0sL&!MX=f237U+?JHl_HFPyIatsLfZC&9A1KKnTjAN3()dxXj7@*E1;B zSn?_q3f-LWO1$s|SK?Qz8zzF zt~W307uKZszE8WWL#kZ23#FD>LXiqX28VXAxp%}YWP)8Im(zjErVwqvyYG9Py7kYn z{BeTf1bsWsCoBwc5XGv{md$nZJX=dt4mI@Wx`RwiRLRLT`b0=-<^adO@*e1(){az` zqHCAne_yd1gv0y3as<>)`0=%T;$y!_D`Ux2JSZNU;4^(yLTa&?og2YtCE$U~|5n0LDUi!A8FGxmJ}8@hj$= z&}=R-r64kv#EqNL26bWxr;1u+I_<+$k=4*ntS#5?EyWUoj(F;=;ApYPst{(ORkW#P z?mj%e9`qD%x&&lRI_|j&gryBAmrNGeFr1_nn4Vv5K!tt*4@;xQjw6#0MfE>}`IQ{A z#k1ErYyJASEGx+wiK2)F6_^xdl@z!2azMRep5?&kMqX$Y!$)4{v60aF9&KrZ<-*oy*c`3VpvcXOIt# z_~ddq^7%aZd^h=gH)nz%Nri7#5sQ@ygZXZ3+vZGIp?G4Na=FZ^rDJV?8+@J^rBzt`011fgh-)~QiL+qRq6*GclasZlIeDv7YXv$K;n)1*jg zCs{O>Wzo~qlQdb=(Tx38?~qr)^RN=W|Uv*VB# z>%)wS(a1%i4x0Vp0r>Q{^qL#0ji{^IIMBNN2Ti=@-M7&?(u?Z`v=o=gh#}@ECZA(- zp;uoYzR%p)5f&$BIC#gs-2VGd;FqhgrXrZv^}f2#;61yr24nkMDcfg$`;)9Ni@(YkrlyqbatZyyXBW z)2IuBrZm2{VB_#FFkzBG2-8Ile)3-a__@90sk7+1EK$Mon@p4XL%E7-pMsWfNvoKf?X{8MZ$baUaZKB}ch_~ZxwhOUmZK}71bIccMj(e6k8c=cbB z&o0uA#n4bc<#3j7-gdNNQf1n)80fayF)aCy zzyCN=N;8EOlqP5N1l1HPU-|NvX;TlA5rXAVu_z)AjZN~R-@J;NV&g*hGp=z@^aM4A zS2h;GaZ&v9penK0f5Gz;YwALwHxU`OA{f{*!qMUk$0jFDQg=vN2?kV_XX5Au>R0v< zhET<)Z^sT!7UxlFj-jDia&2hQ;YKY??6kH-$i&19ZO#xa(xH|h6+WeFF6HZ2Kb7yi z_X4~Rzkro+jKkGsKJlhsMd(i9-S!R^?^uK*zXC^ZWAe^7QvB2BQM&Ota8(Hg3S4u;ENVW> zCfS8ruG1_fsj%~$$3Jc?8+pr*)p-7QKP+ECciKSeZagQ1r=Ab5xKyJoS!W~lOYzvv z3THJd@d_V=hU##3lX8|TO@!Xa=X^c&LlM?397kXg+aRtB?J`19EEcJvts=uvyMkq< z#O~-|+&7D7oYZVPph6x#K1N!J4UJ@@@k8T15>p|Yl~0v`hbNY`-lg&jG7&bLb2gny z-s@b{t6%m5N}E+ zy{B`!2%adFICktPONLSvsfg33Pcu0=Nk**eP)0|$)89Y9Ou0gTe?OC@IgMOInpzb_ zis9kSjE-(6m&ZQmJqz z2)X~jfy6w(9T>p2ZTdHB@p>Vbqa&|#UXC6;N*D&L3X6Qcn}LCT1_t`+&1RVo0#2Mb z$&3-eFQ|xmxsp)3nxn|*Nuq>a6$AmE=hNTc&x%Q*Ux)%Wjcz8F%OYi#xw#7UN?D6} zb3J6Uc`VCL8pcJ|Gf`&BB}3!VsL-mlmS|2Qu%grVvBbnHs+>)*+-OalzwuGYp!|*L2-T?e)ZNmSK)TWMyVdw+Bj z%i(GA*}OrRmZ;P#q_e{bLwr@Nonfc-*YWe&?3Yy zg8C&IczlgFnQ`r?&eJp0%j9I8tKRfyeCgY_kdm9oItA)}iJZO0D_-;*Zo1)L_{+Dv zjy1oCBiCppMBw9%kMq%Yzmt09ZhB-d%V8^X{ur&@SyJ}JWV*TxBBCd*S}UV@+6$h~ ztKaZ@{M)tn((H7zCKhme9_vYi@7GyEA`334Imk-BHh!9KdLCaqaF1T}j(R*W zzR3P!mhT?6mFxvlxY8h?JT( zcW~?kY~RV&=cZZhdWieNeUJxU)=LLPgzw{xAK==nwn5qF^Y_h@>FT1@n_*`t$b=Tl za^;-A)433~$N&5Po=4lV4TZQtk#K54BP^E;z_p(;3Cax{M%eKExtzhy1}H>BbJIxi z5@I8qA5%Rox$dB4ORyXso>-aqgzKt@4cg78S!r(Ynh>lhn`5DEriJ19 zCWm5jsz~GvnO|eQIXU}wR%)4cH;wOyNGWi;hPdlU)%*@?KmQ4^L}DDM6!o@kQ!cLy%v%j|5k)F-533lLuprP$^WFKpHo7Uz(PG==a@s*_ zQ%?_-O2E;hCo~1NQlYEAk4mLXKA)#2tA+ae@3{xRG)GVi7|i!DH#rHApdB$?E2igJ zmPi`R$9pUX8sS>5DOzknM?RYzr`g$Arpsk4VbPn*lg;*^qKML*e&0f_lN05;Xm=%r zf=f>J@|NHJ1Z20uWn174&jO)1cC3j_fA|HC$t|P@yJ$l~ISVqIOwBVw;JPkS3fhbl zSZi{Rsh_z)XYKjfKMI-HrpZv%SxF- z|M5?xc7kH29cw*O=z5hsEGH4nspj)RfK}bWEHCwt$mG1ezVR=km+> z;y3T1(03knzf8m#`rI{A;Yn`(!e{C3NEzp4Nvj!}r$R+-eujU!`Xh7+i*_trw;yjV zWZOm0=8ij0knim^L633Hj;0Q`IRRk^d!F(FX6q%+L=(8~2+Lu}a(FLOUXk(faaM(( z!#HIw39vdkSWzK&-0&Z)1SOWk8HR?mUS`e8aPXAJ^RIjr^Yc|h$!^jYi#dL=R#G=i zIy#`aA;n&s77YEAx>>QB(llZaq<-FQDu%_D#72&?4&>2J4yjO4Qy~{U>sh?(?RB2> zoKZsWAibi-)}bB_9Y4W0zHvR*UiVdA_rimT6NzxzAf@ttoGh6*RUM#fs8l|jN# zQP?@k2S4{UKJX8xn3vtRfY zs?|DSSTq-M{oI@I<3h&f>*F*R&1cz~FP)`rY1G3sKS6|L!~Zdn7BP|%7xa$PVZx=9 zwircd$k^J-AH3fy*QYphAq3xt{8osvP`Quay=s(?U-c5k z9yq~@JcW>Z2tz+WfI-v3`j^DI}`Kw;Qj!Wv0zaH)isQS-kz|E3Pr}>kA zz7K54i!SJ3A{=9QD9sZFL?jm6tLAWC^;iKQXQ{T5j z=)!)c3g7-Z{Q1+9Tl$>8zy_hX`M!}A)!3{j8&E^zBF=WoV&kS|JKXZ4Nq+6s1LoS7 zfQJwcLMTvz7O5?t^Nu8E9C&I-gh<1oq7G5Zn#pC@WF~+i-yg5D$5^gE8vW7>>RPA_ zA6YNBJtL!h^auORrYZP^aI~V3!9JI?3IQ#0Uo#8#su287eKevQ@m|r06sPR!-whY>`W&1T}BUa z2>kjkuEPg@OcQE{%!LJ(jJlAnu%9HS^AldRtL%N*wIFsf z`mUR}|I@#Uv=2c}fzv{zUd44?YN4Vz)Xr0mlg4!&7Ce8$@bABZU@rO|j=P0be~jg@ zk4axJ`Ct)-9aH}pG}%^qUF~idLNtU$YX*wgxOD(1O9$Zw3g((PoqaM*um3kred0}Y z9vP?PW0)rzMQC#zniaG;k~775)X)fRUPSH4I9EM?3$phmy!kC(hvD;e*yLPj&>mxI z5}ifKtth>A=G}x*p($A2y5K$ZbmLO;A?NeL3kRu=AJ^zMO;piS^fWe7N@~i-a))^9 zUw;{f_v-hm`0HW08#c#=O)@l@E;cabL&fJU&mQ2=#81cwml5G0@R?Uy^O|>H<#A*x zZBkM!&JY55N3bM>k;W)yCnj;6j>j}DYF4@sFZn*6=Ou2lN(eerDHda0Xa5jUwXTPx zU1`ol?X-7oW%Bslq~t1uXApjcK^>D zDvp!lw7(zW?dJZ8{dnH_3=Qo_OaO|-3BG&tSIJbSXcqw;j!m;Fu_Tu0=^EuHH~os+&9$Gpn*ZmWZ${QnGGy1- zl3ienv&4X7Qiq3HI5F4Ejtky^<#yrwAwp8!}7-YfoXi-fG&82x=1NSot>K|`nvy?O`8=(F_HSq5v5KL>^VifEi0$b6%YbS^2&(`WRqHWp%tfrvJ z5iI&1n+qK@E1!oSKB}FN)R5Ll*yzP{`wqQuN&zYh*-N3nTf^g72l}7Nj~=Ne@8LK* zwN<2(W{D8jEufT*5Dt4ryKtYBg2-a$^S{b7Z#)fl0NFhZ{?%7$y5Uw*@4JcHzSjyz zzQ_N1^>!BKt4twy)gQf{tFF4rObH%KQ2az_lmGq2AnwC`(YIpWJ`b&$aoMmafV(G57&CI}ru#!;3WQ=7B)plVwq`d1tx1rslY!ePC zgkXGpoEGJvHv&Q<3W~D#V`1m+; zlau80T6jJ%Fu?x(`>}1?AR@I5jar*|4h{~|tQ46{CUGfKDxz8{;hjEBtri$NV4Hfm zOr=su5Et9d&@Kd-j7=Mm&u5b+=-|PJja9OC-?}P!J(Nl%79x#? z#CvM&VyToy$zmN+tVxNrG>szq7R*UO$;o{BB<5yE1otiXlY@s zoME;KDFM^oB&d-7Jv$JDWQ$`AjNik-Ti>XSR~~F)@4LUko$0jRGdv%ePA5Z%c2`gL zLu0nnNc}pyNm=5Ft?4l}bX7=lg%1Adv&W3s+c%9zY{zay_0vU7qe|8}Q{TlwhG#EF zb_9V7RsqDEcHL6XWz+LMM9X=jiDoq?B~#u!pa(ae=hNnN5ELIq=g##pJ2A$K&u`)1 zKk-_a`Uy;V8YziF<678&q$FXGj@HpczR{|<4cRKJXKRs~6}NV%?A90Vb*lvwFB z<n|ST3pUI!T@nyXAsuy$5 z4{zY*FTI>Ir|xCjCI=~(XhqT4>+*;1{5w8!&8MlNt$v3F+wlDfV-QfMv z!hz#0C^bS&)qsGUwDAsql_6QCI(9#|UiWFfb>p>s@iW(O+l~Lq=E5pH_B`#tuC3cy zVg@HGn4G9Hxb@jAZeRu(hJnCDQHaEZpw(ohEEp|Mzw6?G#KOqHRb0_D&HB&TNJ%QrvBn}21}D*Op<*1;vTO_i*SZw;QkL zd3J5xi4d!-i8Xw`lg>h#MRA-vf4Ic|`NZeAZ)VcC2xz@XBI+@@EG9b(DFnc6Yr=Sru!v$t{$8k3lD3{7%n$$b#njX+i@wLA zuMnc0RdI^7>JjYlH2Di($?|BL%Raatt~t5|Lq$9+Ku5$&ennF)PdcZjs| zm>NI8SFia)o__W9a90+-U{dervU&nPHwTq01QY!8*Wbm3PQ=k-A4f%+uJZ=DLX1*V zE=o+$`lv?biKMyza?pBCi8=NV5|<_IEW$L#Q4T?S3HqUs}Wfd8$-L! zMp)t|;w(@mL0E)C@W8$#SgQruXjOm^lCqfsE&4uEz^1|w^XU|?`18Mk;os17g~W2% z(M5#a$FXnTgnHffhL0m2^M3NZW%iDa@}{dl2lg=7X$Z!^a)0hY1WK{ZbwMrAtXj>$ zNBoaNQ*@!Nb5!b<5m_d-w02Uw#uNA!TM(7BJ#nl@StP=0fbW7JAd|^ZD(Up}S}kHz zPY(+!qTSH5ge8(tLQUn;uQfF`Mkj8kl)I-V2+e=f09xoD67eEUL{4;xtf$G`p8Miaj!_f z>yjNz^O(PeYDt%3=Q`2k$?U&AOFHJj?LF; zPWH`uQq#nlD%zAvo7l((X+|k=>6MRL2E~yl%}Rx2vo@{fz^;VLx?nfrS*1c#5Ug`3 z8*7i4o}iRsMLE&;}dW6^iYlTIzMopceP0g^w zS>)oa4!gGYvvuoJXmy8?a*;5s;qEN({fRoaj$O$6{{6fB;9JrCIcSaxzT^f)yk7ONGj$ z(#I*EY)I^lo0!K#PgVug#rjECN+sUZuG>W|NevZ9>7Y~-NEag!euf-bMjZhDycBbst}|KT}*ivX;tS{&noertJ)cH>)iP14|C*4-{6*O zKg4ozKf9eFE*^avd!O|zDib#|f9vA-M-EK-v(ULGmH_5p_)>;mdo@2STJ(>M;Np`DC+HLbO9(2$Wt)720k4Tdp^Mu? z_{4RS`u|D+%6;rcG(MeD=}k6L`glZfXqjB!e9Ix*hmJ8GW?2;lt?59&001BWNklGqMnxn}d#h);?47;gww_}$ylxY}o*$u>*HOc>ZMGY~UnI_2G5SP;4QP8d zn@!fCI2$FG%h7JxoIZV;AgIxXg%E<-+1Z3f97TFE-)?DJ+jK5xXil206l*?Kf*_%D zMNx$8>?D)1i6TY8gg?T1P@#6|(s?UgwoS8I4=xnKqSMYKG^+$jIif=lEs;s|CYpK{ z3rN?SvPGig_ZS!$pbgzX#SO@kd0j2QSIo}NlF#>Spi#wWMGyp}b2%0bN+EeV*@+Pw+qRjVouxOY(WtmdiA)IO*y$4qea*IQ z=7Vw)cG+&N)97LiO8jrJRw+hfV#-^)$RGkZQaX&MYP19vc`Jf!is?Yn(Xz%qY_=&l zqfQ}v)13FDHBf>l|L#d%{_)#z1|wSJR;1j|kN<76E}o}0fe;+C=UA=ly(SjauWK|L zv!ymZ8y{(n(Y}#E zuiXXXwE9r5Wduh5vWKD9-o**&vbj(qU7VqVO*AINTa2D#H34qcLp$U8HX{UKSSKf?aT8m=p5|4U0V*LStTa~echwX)(5!y3;X%KH+-DPsj}unmykG4#G;?2 zra($TpO8de$V})n)&*aAcmi?JUo$XrIm7O8A~HCR&&+^p5Q|NZ)Y0e&Jt#>=W^`0;BzyI|viYkp#X~1DM6_6334n9^6Ei!FtaB0F& z^)afcb=O+$`X!9Z<;H!e6`{kMO^(WnQl#R=72r&9hC*SGRRR0YEbSU}rED>_U9e48Of4-W3`u4S4 ze8F}$6{@79ph>k*4(C}D0x3J032PLKFSBpo9lZV}zs`$Z@ItzF6?n3B5U~-}av{ZG$wS zj6dzs{YSj!9e48imyGhkt1hI_t5~VevnjpCTy>fg@=`=s2RGb0%Uj?5FL2>ry)pZK z!*uiDlz&PCrsT+Wn|F3jOVlAwB}p zpsee^V=G#VsJ->q2UjtgB7{a%w9>{Mh`1d6grHg6Xhf*_y; zOMWgR%jv`co zmT2l!oL3TSR6wH`Ge$Ggm^vS!Xp1Z&A`}tAwi2^|N~N4M5ECUW(vMM`7%f^2))HG^ z%MwXArDX|vdU_IKXXI%)NPh9Cv;H|CF?!k#1Kc z

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

yGG5spNj+(KNrqS+5=4*ioJ{581DiwBQ zvz)Vr3!z1CchY5KWSBYM=fp%V;=*?dL+82g-uvk9&oDSR$nj#4RRJ@#fGu8%j)cST zbyqXz2jug4hK2?ym;I>2zs2*Std%v9HT*c2Lt1Las_n!llV;M^<+>CgvW05;qHk+m0acI_c4h$W@b(6H) z{Eo*aCpewYMQcF0TxQN%5{GV`bAE+#xlFNGpgU>81sf+f;h$aCOqf=Mpv&rL<|-A= z_?3w6R4$hgG2_ftE|utV&F@|=m95KG70)vcR{5L(SmtLbf}p~Ts^M3BT-QU&gr&dL zEYJ!_r9ASv97Q{cFtnjK#bN;vIF8G;!^7No>#;ZfvxEb zj~0$cE^p@w1r8iIU~*h0CL;5IVxh=FHHaq7?T*7EqodJUxhv)2x=GHL%k)Ue4a38@ zu1g|eCNiP@^NOXFedjy(u-#2^{m2Ms{0hmW%XF!P=XppOXImy6fy!dB$lzc<+ubDD ztg+et>bJf|!mcSxU|r-4K-mZcE=j9T_Cq4WVz5k-!2ElWhLb*M#S)U{ZM{}gmS9;r zP*YG1=t8g8I9LF_UMHy6#Y=>rrCG1t6B~ianuWZ+L{Y6T0wb3KDQoYo*X_&X_JGsv zJZ|07hOl)~gE3CsuxOg=W?iaOOmSSP_*APtEpcPquo@H8YQehcMD$7Png&mt4PZr3 zubbD@YUZ97k30DO8U?so4XD?#E}v#i)Rw}w7_E_FLq>{u{?cG&{W-Iy1&^%*6;B4N zEL{eZ;ZoZ5@c)LL5{s}w5X?qvYzSaN&2M1ySXRYaqrtUnPIIiggG7hR+*Fl?g&ZwX zuo%SHn(k)S{=(seq(vIQ5+WwEFixY?GLEx0QBi6ctyM$|`$@pcf5bF^%K|In3AUg1 z-#^*+d*b~yf|Sh)@wMY79`{7LoQG0@;VLR)(Ht(QVJ5%=3X&d72|Of{fUmvv3V7@u zs3f`OcYjRBEAM0Qy#?;R|1|G>{SEBTo`l{SUzb^917CG;-uPLzy=#mu?=8{v`z72D z9Oc(Pf1cfLmNqo>35Yqo_S27Y>&!<*jpCi3|_=g-e`<&{?= zgwYj*KIh4#%OaW^Zn(}k5M{Fz3MFE(cmoIu$Imf)tk+iiVzEqfJPtz8(qTd+!t|sxAFC_PxJLppW>0DagLu%@Xdc;=96DJ z%m4L(@A2CodJxBPNgud^kKOTIxZme*zw}+MIB4MFaO>@@LL~!h;RQmfOrO`nz;9lJTLw4f5(sf9!^XLv}k`rM{w=W&Gq%)?Q%^q zqpEZzO`+&nXRJ9tpv!eRl`AqnK1P@8k~CdaR9o8?EiLZuR-m}MyIXO0cXw@ZcMSwB z?he6oPmnJ`BGDrY zJY}(?Q7enCL4ZFh%^5m-;Z4s<@-*uxXFr9T6VStzEE<*79b~V%4$AR34?+&KG5H-; zRVQF#V_U`m%ZM-VhYQL-hsn!uXywH$~G*D=EC4sIhcZ|Q)=UfqOmrpz*AXa$;%OD?3ctIAa1{JFO z8P}@_48Oe;q0leMydNGziCYS52?6cPas-LT4Pra{AXIa6*ikym+)+{jk`V>VBCh2J z24Z~vA8D=zE7jgZ;y>X?c`XJQktUydmSVG5XZrfYl#h^JCud%fhs^q5WlMcr0{-Yw zp`q^aDpL_NXHJ|E@&6{+F4MJ#T%uc}Ln*H{y)X@7xvz5D6Y|LL@ahHVbjzBa^=E#M zF`FO5SKjoA)G>?p%O3wRE6DsaVV*)MQpdj7@a9c^@tBB!z_h9*#aW-HV@+MAZwovAekK?+guiNv^S9k(G3iwJ_ybR5~~; z!$@7sG-<2*;f~>W$Iq!7*`L>L-t2>r>GP+M<^sP>H^+Y^2!prd@x85m41A8)ZDd@u zg^?p1+@W;VI#E8hfu3x|Bj}90R5vEPO}KB0#e5~=^g!jwQb1D^Q%OTXBFwi!eA12bdcyD~_$|j3|X8Zz5)iSvG>)@YaQW1|&LNf1RYByebRcW&g7VuXZ zmQ-Y|`i8XNo0lOx2K;#C{&M)zELZ&TfZzLi?aukupU-|_rJJkSb#_K4YrwkKlZv#{ z=^}_K!}VG|IdT~o)sD_-Z(7RPzyE%jzxUqx-DPIediRPw3S%~=_iYm|2@|SAbdC;s zQwOvfF)g|Qn}q50b27{ZrP{#&j%U8RUk3kz8?s@Mc>n365q@{&4=JP^9$~?XETl~6&f)yRFuXFofgB);IWqj~o z=pm%J^$}E_D`k$nY{HNX5612P+p4G-r&^=+c#|peojTPlAYf4$KgtHGhYTHB6UhU* zLSud_%ItnMdw;zH;R^hQ8M+~4pM-8S^6^BOZq@xs2z3w|%wNyr+{6sn78s7PV?VM< zL~%MauRA?t_n zFX!WS>Ch*aCfbArBDK>rtKf3B6t&dNFpDPI_&_96R1eLHhd38o>EJdD>r zGsg5fGJ?X*bzEa1UUWmEL|ysh)}f#dgS~P4I!k(ZTHM$(S?b~yyBdVb2>G=O-oMrL zLEE!XM8vwkWaRBFYblE(xL*WbaL8sjfNziz=W!KZO+JTdp94pu_%uL@F2g=%M81U9 z(MX41r$R$|3ESL!e=dkUI}S+oPnH4CDzzHXbYUHM>`zPz2^nM2+l-D)Lk$nfP8e$+ z^i+p%8Pp)Wc>6n*Bw!0_6qB0UaBZx**pS+eTEM${{sAA4kU&v!3sh*Ru5!i%q*RUl zWZt>Y%FUgC9}%#6pg)f=ggO>AY4g|ySn--39YjJ1AKr9 z2}{n*`CB*;`IMcLPXaZSFb$1U za%Xjjs9qAb$BIL-FS7d#y+AlkmnB7rA&5y9U7U_kok&!iy0on2-V2<|U9n$C{W-ZE>-4*u~X&aVMTjSFP#UsK$0uCYFg=&Y~)<>ND5&7X^Ka4Mp zohhhHu6-vlWJ1dH5q{AsjgQ%qwgOgI?omHL$rgFnCLZr)4vK zSb*O4a%xVxTfCJ?$4ndLHpkB@>p}f~w`zBOI@Yj#)k4;j@BYKp*N|-<*hVN;19yz`w%j$ASns+ui$9U=QK|Zw(C?fuw_kr zR(GkbH;6LFU>l8`m02e0MB)zGn|C63=B)*2O5@LqDw!-eBTkHi>E91r&Z%u;(WhL6k;$9MiEgZ!Yo_fM=r4I z)$_%K1y=CnM`rKENf-TwSbhdP+h7Ixu~)oPz+7YW)1D6Mosk*gOemp`gRIOJV7e zX`{ne-6mt2DUofs?R9^XrBJ+DghS@2c!S&86 zekUC4*nt}|GIC=P1it)Mdv;l-J_y;@RJ9ah(`fZ)eexpXi2OH($O}dyWD?@De=jTR zw*wh)#}1I&H!eWL1SIikSi9~}=eZlW)2zl47gZL@nYa^+VeH3jKS4aReSq;kDTj<>B z_yN1ZVh1?KI9?KBQjrDz;^j-QP?3>RCcIBTOd!;cIea|mO02A?n510hyMDz=Ghx|U zy5ON_&HEKPQAt^Pq!w~x$>Dj~*v2qtt!;fe_WA7e7U;}4?Wa5{1~KdXO;`bO5U7~c zX9wz6nxZ1HVH@s|yRZ2+KlgBJoQ$FUMb9N^p7-etkOo9zzl62z+Sn`oH7)+nw+!n1&oTP6=~kX(4gJ>jit^eFgYLtEWnH-E6mlKU-6Mb*Iqx?<7kNe%KQq9`Z z6iSVhiYj#^VHcE#vm}O>P#ClrfEx2d8A`v_pXMcKfBy_UhN*Irp^FZ&?$Z1=l_he2 zpIngC@P}C>u(ZHuu8&zdcVAE`;f9f~k7@o$YX!a~<5S8eD_37+&=Xz24ou+d4%dtC zj610CAGibUjYKAtS{ZJln%2_YIRk~YF(eI_WSx{77n~UE%1ydGHF&!_0A`2Kj+o|c zw8jrU8`hqTbN*B9FDkr#6E9%pTM3&i4UzP`BeC}CAd6pN%zMX8l|rdA3(XtA ziQAN?f6BKaS&f+b{{3xz&#~!6gE2}Ar20A?FF;A+MP@cI147EUBRe7k&S)MOjAh43+f8@-RckNYA4I0AZoCtf^-Ow}x; z&zPv-GKI4-t88AtfM@)*@h=3C&t=KHe)|zgGjfcbB1{x;%!>-yu$a^7un}{auys{o;h_v1 zk>-cieslqEXiHXel$*F572(81$t{TuR~(dhiTT{ZaOv>t`B1P|m4jRqIVRkA6%p)}Iz-bu?n6I=mfKt=Bg7dnuP(FHI>8M1Kdz3!1@D1dwwD6k z&D*Du+tMQ2~-X#{9261 z)^$gHLQJUqKmW1XNxr@YoOm{v2k znMaHz_Y0Kk8Zr>FX}&D*CP>6Ov`{>0Jrl1O2`IJtZkQ?}RlnEj2!^-Sv_Ua$%o$a; zDR-HpIX~U;fXm1NVFD9m%8pxqQ{leNgY_E1tfZJYa1_B6!Ov86eg_P$#F5|wTdl=L z7;ZNbLx(%pTY8br$CKzE(;sVgM^~K+k2k&o7||_ugQW%U0!$iXY6z=-+wgI^9-MZ&NJ(vlS9sD4nYqeSb=cf z3r89@H#Dm&bBNaCr+CZ!$rEE%pW4ogF2dTQP+MI4%^ET2Ri#6W>2!(ITXwnnK*1Zl zOYlQ&CO1-wyjgLe?07&j7hAOgeL5)WA5PE~`c7DLqe@nFwSKZa-%5PG{r(I7shM1b zMl>~_yygm2A(@gQM2g=k8)?BFjqVy2<=$xUORa*vxH7jE;yG1mQ&U7Pv%lcP`8__B zaxaDXYthVW{@W@&%vP+E>7~1~?eUGb?%)z%M%0U;KB7X@kUq8PDzXTWIQv1xcZ2BNs>fz;O{bSR-D`e?A3CMfz&Mr^g zcF3_95>MW&K>m*uU%TSd2WgxJh~i7mE`C-|b;y1Ri9`)1qx*I=ari1{{fzKA-`B8B z+34_@ox~rDn&1XJ0NbYsVKX-xaAQ}AW6UT>F`G({I_Ktwl|a*JasbuzZSG|wA)O0f zZ~xCP5_5X>7O@8eB{tref{s2}+yxU#^OWDv0zOzb*iUH30)in_7JP9w@1|t~ZexLU-P&MirD3V6l>6l^Du&# z2-=08?Pe&KCA&?XQF#bBcoXMJhL|;=*9dhOBor1_T?gi8cE27(Wx0NP*#bU5fRl%M zE}&_N)n_s7wEjAc<(kf~@vS`R?6yaF81p=}*Xm;Fk*NQfg+bcWVGWf71Fon~PPC)W zoV;r}axx2@Z*RJ!d7RQnM)VSykVl{#ikk4}_tlkWva*WTXcTGZauz6VT?#%ag{k*} z>;6qF{hep?OQ)c$TyEQz+=u>01YXaz^W+_ox2}#3H&VS$F;aNQ-Q5E4?oPeQh-{fD z%+|`_A0$k`k%%Q;reVILgBs7u%DJf6t{N)a-Z7c);WsO>k@ucR)d;y$?|eew}AJ})&0tq(n-1M<)(XnimiTspWN7BZ6-#~YC3<&)4wKu_cKsDMftK2MJdv#RDxx}3eS#CpjxM?C*ft4_ylGdaroOQ z-c~i2wo&KIswlHDF%@M^k4Z6uxVzzkD$V*j`mpJ+)A!zg>G8&|nkUsAszWffKotm=*j`D7=6FxaV0PH` z=sEg#WxJ@?ckX}GoTtzV@EHd%j4@gjS8w?FK2NNQ@oxSVWJmGF=6~U) z9G<`|E}KV3yRFuJwH&-BsQlhu1L}HEQ%u1eBP_2^Jic3n;3yX0@LPCr0}%LGLBQX( z!kSz)vagWL@w9ub~rzxQ%jZeFR)14iPu}70C*X$HS{JS59wV6#z zK3TqmH>m5k9iw!ORXK*<3dG>gfP)ubmnx@UR{FlsYCA$PNusJqndptSgzr5%Syhg zhWJ6r_9fQsERj93IX`Z&VBGREdbg|As_##^j;XO^pf}SH^QxQLmqJh?C^c%{{g=s8 z!qCt!kcnO3yd0J9&J~6eK53x?4OO9nD*9uyK+5j!X*K?4)JY5Xg(d@6xEfU6(Voti zIA6mfI-adjS0n>SNC{YP=^)@$PkUTa^w^tp5vk)p{_V%HyINB|< z#Sqq}jdSfj0)2!d9TPqFN8iqliAERc)X_QUFZn(KCPHL1!v3mPqXu{DL^QOJn%le{ zp8_3Ux`0z}D*fg%X!RlRneek%JggE2FYh2^E_~hoONCaIG0nm5SueC~Lg^;mdCQgv zx7(?yMgkY_~MW64$!qLE2_JC)~zavWWv4IcR;OT3*iO5k#1f4jRHe= zW_=8l!tB-v`&xS~JAfCo;k}R|3E`{*$!~uB^EVr@Ih@pX@tfmE-Uc1aZM3X5_NXaZ zU651tou<-ULV+HavMDS)g2yIr+LY~7Mtf||Ew85?AiMJLSn{V83BPal%dEW8f&rdG z^6*7K0~Eep4JCbz8UP2X3JGv9=}|_c|91~iE0NW4fkwb3*C+vRhTWXcx^_b; z)}h2ecnH(8aSfP@IR3f|_kqWQY&^1jJ58%&mD!f+_Ede)5=moRY*Az7v9DLuG zcoTP8cQ_sjm#wRVriII*+H6d9+(_g6_?Vg)kdz;MU1QOtt5Bwj5v9u2LYD;3W4Ho2 z5E!`J8(V3Jg|ElHgXfP#a(@1Vl2mk{H(2Kt-=w{XaXMk^+l)lL&b8hOJ4@1_?|~B4 zTgXeAgV(5DD2qDgjX*`T3fLlI`p^4^E|1?5OBAPy;%|<8>x19bG5+9ZeyMmF&1e|B zKa77KPetr&XI>@*@B7FG3_Ew9#U4xSc^^cKXS~w}tjYLCZv2fV!Rp^sptifKvO6#B zLk60xpqOx;*0*~zFVwAlrMoQ7;;TOQWJX2?I@QSwUpGFm=IQ?k7J=x9A1z`1JC#fh z$JkmsZE-`X#}5{Mg(=k0-|S@y;*d^&<9pw6Tinpjl{4l;*qa;q(4*|7BF*l7vC$9l|0YeZM#^nQMCmByWaHr4}|MD<+)GFU0iv~ zCs%t$_SZl1vLqfK*dL}5g252k%>31Cv89xdRzfT|grhDD~$8(5g2zC@u&<+cT%7alb#foK> zffb@oKu{bput?h+e^ zGaF32GBl;ui8z50Y%D}UHe^O+LxztZ zmjI#r99XPjPY7k0aq_X5f}T$}DJdz5iHIoco6EQbYPiH7@Ov)Z7nFEZ8FAb1*X^^b zG~lbhtmiuZXx@;E*Y#iiY*FGdYV}e>ZluPD&r^$QoBPH4{?gJqI0Kh%?ZA=((YGwB z2|AY%$JfFG`Rm?aFdsyQ^|0xk&jcUt$y<${NEA3hm}i}p1MRk5NhXIQh;Gw zd>&zfIc+6`<#~iC%~9;RxlBf?&fOgZVJz8eBo(R9LNJZ&!*TG7!=xd)Ed|Y#_{(#Vz|Gm z)jr#O>wVUEKjA^WY1Ka4N!)&FYDKN+XXd4Oi)hi1amtL}=+eq@;9tiLg#mEg@;NOg zVToT=TMJpf{mSJ6y6?AMTNCB9fN_!U`8HKiWzg~MZ0xHleAg+bh6#0a;}NvXLv$49 z^O7c)a7t2K#~1WmCzxi;Ww;#ypr#lrM?!jcPpO*H)qIkj@4`1UR={Wly|YEz+S;OL zw(5oqt0~|1!0!P2S`mCUI8n;|Qe}0np(j1j*kw*{_^sy*<9$5icegOs7v%5eGvHN# zOLfAx*tV%}*hmWWrwI%rjDLoQB_s!`Njv?zb)aO_?I4Vz?V=mcvN^)=+6{l zss*(3m~_$2jO&eOl3orxa)CMR%8ib7XtwK4WX}G9h8y^J_QY4y+2MNN1|b#mj|Ac zo^Queu;Ra39X?zIJ_d;76OUP-_1-xL=b#C{35zT1dv@8XSJf==xZr>FkU#iFIR6zF zX(4;omfKN&=(C|T-gn_^Ub3fAnK{nBDYKsz6jI%5k_*rz70k=yp4^;cr5-NCa3i*R zyeZt6L~=xt^^2cS=tz{~^Zu?S28b|BFf~B%p8}Bwj5Gq@i~c7bjp4%EWf%tI!^-V9!^J7V##s?fOzqPL*q9zm< z+M*Jf-nD`72#Ej^jMO^z+;kgU#D#N5(x@{+0SPumvGwH?xzssov&<_E+&gV`Tm??o za}Qo_`OAs4`jYkv0o#zNY!5h8@TEs}7!6^XIR0wv@|-d`{~)=6F?vghzh0J+>Drtu z2=EhbK9|ocDK2+kAkp(W^lZAZ=cK;?NY#>>{4Lmdp;>mW;A%xKanHDrk*axqYQN1Issoc+^I}fCX(}40JSV@ z6p;`xbb5{->}iWo#1?e*2g*Weo_bhspj0l7k~7-MW4Vg!m&Q!#!Irv``=4#Xgita% zH)5H1Xr%#HVo2-+pfsyIn(2gDBQk&qe!JXkfIyKy68Pn}wFWg06 zxO-pUXimJD7rucDMtm+KNe|G1FX=g<$vz^n1V7SQSbNh7Fzc>`66N`C>1E=GG0G+r z>m+xU2;qux^IyZuvR_A8z)!&>{soa_^e&O0=FSbu8dww4ny> zBFG)bg6FdXJME*}Nf1Rx5x$N=eusn%fKdP_i}5Wv%6za$N6pR80of&L$iu0}6ZpP0 z5SJ@Be49=On@9ptjjOh#^ID7ojl&Ntk|Yq@fW$E^60lv8_M zNt6;78Xegyu&1n2HRz?ZzsF2TFXRW;%_wrPb4m*0N-TI<)W|zKCFvN@FcxVjN^u38 z4dU}09m?L{n=!GdS1rq0`w`&dtLP~ZdK~koZ%o|c({UQsS0GG=!*D850%Tn_IN9)U zWvMYabCmr2{3{mis{i!V{L}jEKQey4aeI63=D|9`!)&l)n3zi`l0V`~44GU)%vm53 zEh3(63es594Efxk9nP9o(DzbXH*%n9kZZC!&2anuvnFww5@R+MP<9p;^ro0nprx;Q z)mEw(JZ_mPUn5POPGNb=+AdBS;Tm71|XTW^O&=YkPQj zcszx2^IWyP*VDj;i-&j2mQuZ92hrq()fS&3K*G+$4=DU7lp*y;O*R22#qbvvog$cf z(=S)AX6&~p3uJ8p9K;t2sh8e}NJtLsS$amZQ_FNJmhgr62lx6Zm^Q2=kifN(Gpag9 zhm&KeHh^I>2tA#DU};U)#_8(!;1@=KlsKwE_cPOTB&@EUfoK#hPplN7+I&6z?freq z_^%3G`$aoVeyOw@yY#GCd_qDqThBETIMoCakzvOL$td1H#^hs>so_Fm5?;v?X^B*P z(BjBHaCRjh;vv z?*{6f?o6n4wltq*xGthYYLz~ z_IN-XafRorrz7E)ijxTZk}K>9`1w5-n3>3-4RYkwCSLJ_o6OGZQhN%+_(3qM2#Nh9I!yZQbmu+{dSeD2b^tv ze0qK`dd1eC5V}ar&)Em^u#wG~f=Edbg2^2C$n}+i$u<@_i%>mm2vMlI;ryQ_t%V0_ z^c9fr(CRTl@Ck|HscXEjgz`isVR8r=x4BO)Pb|k6DJ-!ta5#y^nVIVV4q?QQNxF7z zmvqfCRVGotk+Yf+SG0Xd((G(M;a#ax8M-9JzYf~4ABV6nT$w)P{Woq1loFxlgvku&EcfY##MOg4VD)@eoSK5XVM{=j=FiKnZ?~JFfu$dw7V*w@2=S9kN685T<2RUNl8AKQ3U!btD&5I})PF@QbWBWk&~pF-y)T&`Df!P8!9O&c zX2WYEpwO>btMyg)m@q(1)-&vax%*hX_lZw=mrqcQx{31*k&WF6loWA^B0p>aI?L<0 zS{$DoPv%n%eBV%{6UjW)Ln`Zs*&Xx8UFtrUnG9;c|LiEbx|0}@(e-gps8u$6dUaDE zX^yXySdHyCQ5HE-%*cO?CbM?3noh*6Sj?Joit0i(dHMBh41e4HQTlyrH{RC!Yf zoJ5tFQMn0i1Bf&ka5Ep%jX$_zmrqJ;o*5pEr?rc9(097cNDtBq8=id?FKgrWNELj-c5ZXmU8NJ z-g5kdz=qu4+j`9VO?>os1N)V~|9RwtE=$a=rRaS~*3zk`NX!WzL%4WfVjS$kg^@A* zV!#=8#%+%PVf^!2t_|luY2tJa^$LvuxN-AMIqGyh&t<$2b+d$4$J7{_iWLUo`10B+ zkIS<&lxS1buPBs$^lB%aKL#0<%7cWJZQ*i|5`tW zCkl<@y&r$ywe&8uOMiTnNnm|DJWVV4Tfl~VZ9hw2c;}glJEE)4!MD0FGV|ta{Ml5z zQOe#jArV4Jxa+NUI|W$iC79xKXqF&8$CzY8nTwVol#z zD%FbgaqGG~Fuv|_{^{67xMBiOx4Trnj7aM;W(&Gp5Z4*C@605B0V!M0@5EOyP|Xt% zW+0ur&_y#%P>}qnXVk}qi>Dego6GOx^%wg;7eIuKa_siD8OatiZ1c%h7q^ToC`;ty z^@z{=BG*_$NJL~}AQ5=9l*z)z&n>^zI_Duq?W97Rg&Y@`H1=z)d?U8&jg1} z!Ovxa{7>+ob-Z8@xD07(PA8|P*!lVU(km2lvvVz+oDvL}kF2yz0xUv?)P9OQ-@5o`+IKnBM%Pv9fnR>sD) zptxV4M4((~JZNglY;LANfI?nLUKzr*WVLl^O0sUzp~xhXT*0AI5+j5Wm>?5u7l2pu zicp4XW%X4DEc&M;$w^qHMPCM^{>z|!m7XJ&zpS)4!FT;l5Bf0umxAcpF)AdUT_RLT1+@Cn1%xkfU!! z{HBH~)!1?)o*tQjvwBUB#vfxeawM`hr@ilTsCU0~b=hn?pTAQS6?+qMayx_(c@4BF zbulY!8+ot(t;-LNK6>9%2zc=R2=v(8N>2XcPv$tD(b+pz(@%+DTCp687QFNJ+VuSm zcSiWdu!n5tYn=ve7u<#(O^#5UWsPda>EC(X;qR7X+w^Xtc*lNZkR@*Xl%5D?2|E2) zUB??-enW9|g1mV8Tk&*!ho7y5!7|m$-yq+%`DYZ*kR+Yyi+rD*U}(hxSC&SNJjLcY zqQtte^hTAoYd~)6pTk^exE@=lIl@W`{Q+x~Yg*B^$KT$0M;EBE-L-L}4#vyDE=t}i z87oX6isxlML+wq3#iW*%Zw*esd%prvfqqiyQ>}bJ-|6ORP!D;Ae=L?UO3V!?e5>Nc z!ES!2*{fb(w287n!*BN3YE4gKg;JKFNI~*7yg+@JfE(0diU)Z>5+mC~V?=nHD5Y)7MVWCvY<^W1P{N+{d#2Zp#FsWpm=fwo_BSzz>J* z6fo@wjxokZxBOy)@B&bG+>Q%z1FfZP3dd1>wCwagTvy^R%C?3)15{d`RwYgaU$uQ60T(gozBVQV|Z_l=Fo z@uR=ql^_l7gA_);%9bs8Vk5$|eQN7(k&4}ZrRg1f=~?}u&HZ>=Cp>tS?UZr|#Lg}e zNfcZL?ELYgk;F_u&pJc|ZOKv8z>5(#jEPa6*M)AaV^USDW@B!fbtZ4@1Xm5=DChAF zoxftvd9*R4bRO>A_`j~F3p~sWx2DT`FB$9=%*Cg1TW;*VH=&sbzWBkjAr5a}Z-$@Y4wh4y2=?ls?KN6cobzrktR61L-tjCtTEW0dauCQWbR z@p^7uU4v)uFP7G2=vyB^@Rfb<(Afyt&iB%rv>y&$VW{+r7K>%a-9eTyO-D1}*ZiPl z_0&{ILU~Jvu7^;9aD@P$^boR*OGX`Y^E-`{n0tnq z`1t`KqUG218V~++0Wt_F*hwi0(>gZ?c(4gMD69%c?HYdnzJgyVD;-5aeb)GmmM;*g z%T9-@#A%2Fg_an{#vwE`#$oMqP=ZH5sM(?#`i;}9QZof2BK7|0HHTicW<1qp`EL-N>_|9L zCO#37dnkSr#LVztPr~2P&IFYOl!SF=)gP45aGM~Vx~)1#hGf&bvmM#s1p6j;$Q7Kw z3SI_1q#ATRVuEV_$x_qM=y;qn$L>l1ITgg|Ghw)dVz6TMf}d-KDEO+ld2){gh;7*<`9)dE9!-lzsQxI-0KVBG z;1#OYz;|;S3jhUMCqS2Xc^6bRxE))PhMgI64Aj4}u%Eh_+4LxU(+|JxkIagpWz=Rw zJ(f1PM1j6FDDS0&HdOs-sI44h*w)&2Efk+btv~ohn*F@)0ijSmoqHEI%`wNsHvE7c znx3|~0BY59!aKrZqSR3VZ@p%kQa?$VVTy8w+qEd^Le9K4YY-GK$`rkN*E!L~#{c%? zmu;9>=BTiy(<&+Po`~YHR{uxYPnIJGps3<0A)`-N%2QNPtOUv2XZIu+OqWGuHUfT z*EJ8kM*UjvmY=2`3qK2V3@Fmi3r%bG+v(H&Ej2`+!<`dWEn3-b69%^c z_}*%MO9GmvX52YL25g&gacVTJ%hf`pThs1Hc1)Tp^WQw0m3KL0!u014#;!;S`JhF5&9X&+Z^_Rvfs#zB{n$~<*VYC``Wim#DObcmzfc^p{?tg z6c$dmG-5-TB3C|B1s+blSYKB=O1~(Q$1L*nR4y#STHIX6+EZ!W6-64)VDF;;YO}Qa zN&aO|6!)LH!E5}8@7pr$xgR`}k+o^-=r5x(ljFr$YA#=InQ!HcWMPJms;JIV#NEio ztnT#-*QnDiz_fnIayt68+N#7~b1a%V_Lp0lZRT-3TMjbI3JR20i5#j*l%r0?Mhtgc z95X^uxZ<5Dlmn%eJ!^#Jqk^d zULfwyy3vWHP4Z_|aNKS}&;29eQ4Cs&)NK3i`8PFVs?%ZFL1nItoMk87hA(rD`Rn3H z5LOX4Ue6-}rdFQk*R@#~Ia}7}(0p}h+`2hDw8;=vP9q$3XS*roaDTo2H(Ll%9z6I(Ejd2D4zk3 zPi{muXIFAcK$A(B1L@j6Pi-Of4H^gZ{e$~f@9 z4V!W5Xbk0$RiX59l1MHz(gMU92-Q)4W;6by6#TXQZyTX??{W$3zDHBnlv3Tf5 z3oO-PRBJsI^t#Bc^WTj}`3kMBt}X}$ULM6L%;+;>^K$TY#A_6n8P5@H12nl1rL0L8BZ$_`)DvDrBJ4B`JN_G1U?lS6`dd~a@4jx_Y-5yij z$(b4OU-j>9j$R3rx|$}!r&dZK%DJ`~5IG+>^xIQF9!IKm`z}9O-%+8g*JAfL%3)Rx z(A>iTyVD7LfM@*oHfvtFBfyqHz-+^F{v^m_6H5^gbpvq%nF(jCZ>}KoWc%<)Z*y2>j?UP+n@g zWgtAgh!d-@xOpz2W6$Okm*nH{jhM(}R!?Qh3%r*IcwWf2a&U-aE=1Olf#1r_I~Xg= z+dEKTai5hn1HhOKlRtpzL#>12;;)-LOy=l3>HDcA0L))ELu{fz;TLmx%F8f}Yq&yA zvyGul`i>G2E|Lm;o_{*DGBKkld7w8pG5Eg?YHjV5E_(C9sWs9J902Vcy1P$R_$L}I zonERlF?>6f$EVHtRql{ZJkUxzBG7Y$*AyGt_nIEYOwc8rWa`Tq%a!3mq?$$pJBpoL zScsMsht!;K%u?oJDl5Afx95sIg zL;gL~j)WQG?c6IGqD@sJnl6e)=PmJM=s_*a)#RB=tzqCYOcmLVQ(e_FiBR8Xh#vn!$lRSto3rS>we04er083 ztqHCC_t88iBn&7>DR&nZSt1AW62n)R{dB``*O_O^VN%|GKczkA8H!^IM^1wXTgXn| zZ%MFv+r;GV-qz0Iy*iarUC@C#xi$S8x6WIqa*WW6Wf3DJoagBE=dQ#Mx0j4bXu^;Y zYFt{1gpjS%UvQ9VF3)Vpm!P`nC6CMRyy$FcOwq}UbhwHU(vfW1)j|d4&WV8U@Hhza zcb2+YIh4S$B2UEiQ*LF8SWLEKDStwSEm76b;su^OyNlmU8}y+1B8A2w+OHDUnso~d zD2L}%z5dslX00B!a-pGGN~8+wk}w(;DWI*X#y>m1(iRDx5|~%9{0ut1bS@5_Xox)yyI!A z3JrOPbl-f#lO87)qT>oSR8fAQh5#FFU@3Z>A=c$`4WEN&{Z}-Rx4-~R!2z<@^?dNj zwr@n?oHFL}g`%nZiXce;AE?Fg;sU4o>M*MIl(X8?qk93byb@r4v8}J0YO=iCS*OqF z@3!%IbJr;Z#U7~93b$d&wh<%hbXN5Eht91dLW$?C*)i4z6z-_-Ytm))*kZ0r(b*~2 zvIQG*SgV%GEz>AO<@rtR>F`g^r~w+NmK*5fmHXW| zD0Em4TNPp^ad@(ek0CG<(~KcbW0q50NGY=&{?x*r4-7&Gq?(fTj$M!rL*^bT;S%5E zqc~lzExO(j5?mFUj1+n1ND~2nd0m+4{e2ycz@Pe7jcxUlic1$_ej3J8YV}HCucQt5 zmWRPE$UZrF8`sOT+By}TZ0a<5#AibbjMrfw!}>1Rw=|LYHVP{1dGALuHgz})%a@XE zk7(y1Bjt0C5P8|d^WCE>5q`%r_WkL8G(G1+c~D$j+;uarKukhZqM_!}B4Im3(W1uM z;5fk~N_O~k)H}K`6BO0!_wK8$4V{0d&_}N+84S^CNa`Ul9)f+h=&^lX|L`d;{BqbJ z_6Wrji!^jUvK^?rI>!3$cD*O1{nN;jA9l0I6D`Q1gZ^~L>}TW*aG#~;CIpE=Qxb}e zQf{Lp=>8&nJnA-ey4+zhy@Ek@jUwk)sDp)PuZXsF0E9BI zv;K#1V1QCXDOH1eLZ4&d6LEgl)vk3!^8G`8)&$})#;;sKj_E&th*2h}t&SNd59T~} zWnP86q|-4fAwlqBtjCxkySt`Fekb45 z);Kj6%zP}eR!Xg3&$JA%tK%zRoXP4ZMf~3nl(PgD#^8ko2YkK z8q#;&vun5j8B4=ekJM7rgJ=R+fD`Q$>Bim<)Qof)3xC>;7*8hZwuK1jp?5)#I7$ss zwQEo?y#wANWisGUyuOTU+BtX1uPs6%;~D98JGl0QI!fL@D*b@KG{>!z)| z*?M}x%Y7?X+Z6!jmRKEQn2GOH|MBwwXu8UnIGb==p*Y3ey~T^W>*BB!*A^@84#nLa ziWGNucXx-y-500$eZQM~6S6-@b~l^Md*+!lN3api#&0rUqNyaThu%rt;P4jux8DwX z&c#0Q*a*Q6$67`aHYQL~zzELQtyWF*IjK)6JsuK6SC=ibDAHD9BC>cT1bs%S~;4qhHfdZ%a7=W~e=3Z$#^ zS{KG{2ltc9Sj!{}2R7gc>D5eBIj&=3ViJV<)^2)qbhNzh1H-24Etx<6%c>^aL}6ne zsL)+?CQS=Nb6wwWiCJx_7YE{kt>^=f8O5}#DAaiA)6eXf$&Lw>NL*^_2m9cy*jD|} zr6CPpE45c$TvO8jcS{Pkdf;;zsDj?MST0+i1)q5U+N9GKdEWSS<<8pK6tJ=gI<}xc zSOX-{i~yFUNwZ#EBSr{;Jp;Sl!ZxGPUH_SH&Jq#VMMb~!7sTlCEbw}<#F-~Nv>?gwSrkLk)4de zlMY~B9g=&pKDv~ArHKIBZ@bgNbAY8xHa~7M4|^=83d8TddeFhMi@{?7jU2o%i@HR2wY2iIDlXi^DS|%m97!0KS?>^39VatBg zy}iGG`aCo=1YcWQ+qWabdF(`CXRKpVtBJF3@->m6J_!&U18O&+=a-HC)uqXcNuSsI zhY_e(LbvKS3=3sC-%|sJ=y&2QrQ3{o-SQ`A3|-o%e%c&j-D4ozX%t>eZH26*{0qX> zO%B~cbZ#5h^!@QQt}rL^BN|zam9p?0i>f?x4U5%eNS?+Y@c>l!jJTf&Xp;M{V=YgJaB=)azMc^F{3ESI?Fq ze?@_Q)3+P?=cRkkl+HHSR4E!jfQQ6Gq)Uuiuj-~;2`e8!o66? z8rQ;;YuKKM-84-Upe29`(#h#!NA6~;=)AulWE;jz;tucCFlaaUWDswfmYSFpe2bvE zzW&rn!jvxmR5wj48RT|(!i*73yXIuGJ}-g}gkqC;|BQR~L?1-CbDM(_v$rr(7&;Shh~&0!N?iek3B0sVA(MO%&wES!??3%+o`a@bT)m?P5Mk~okhGh-kN#6euXB{A^X%# zc5N;3IrE2QW9V(l^w9!U>A|1zy9buVR*_C{`N8)oD^tngSsaMwkCWSeOq9ET%+i8k zeStTAMgB|ciA;e~4gD8G`j?kEu{_ro$oJeUm&@9$L7Khx(46wh%8l8Fdk-HW|H6-M zQW(D*<0WG4O@o5@us%Zv+%}4FX#b_YR4}*M-5<=ZNMU`co7{n5dFWQI-aaHfX%*Gi z7R9*SJp0vy=&qDRLbz2HyxMGeGrk)c+xcrQ;wfv^$#YTsjaXp%`*hD!l)lYKck8~k zA?_ln)3zhvFGLdkG*zA*Usc;cRn&-)_vvm^PmhYdiOhXMfuH1_T$hiHEmIQ2PH-E2 zTSL>$0J7}{2!z_B177zW2fjx zjbhcw@o|;nA`7!b&?=o;itC~B%n|$BrO+!0>C+N0u9lD(EUN^Tt@o@t8#0ESgQY@> zP@huLRq1xaO?)YrDd&E^SPA#`335=lyg4S5>LL{@Gc?+?AgYquXI;}w7fDf1d718;P4EZHZ1avgVzfgt4*_sHN6Ri=XtK&$A_9n)_3}Xf~4M{Whd}SwWhe|G^VS>_{2ItE-%$HF`%*z;$&U zpdA-*LNup?k%C!)4&@;ZW;MUMb{iN}+g+z8ve8H~`Vb!{mdfr>>tI$fea3^ChQxSd zW(g%FyiKf9BUX(~NhdE(qc%F{aFw_u>0`*4cw|xSWzney0k>_v4A@l+>07ZxxcVK! z4L&ien`G(*1yfELqJO)VmQtW0p}#5f9hDMPUP5Ehab!W&{L)GGkk4qdi`zPL=ms4m!5k0*A-4zdbH%} znW1zWlUVx5IEnsGswa%uZQza35t&6EbW^a3e2l5vAKO-`2+oqaG=q4d|CI4k-l3* z8?IaQM8tesm4mvXEC3**B%d!)GP?fw1#m!zVoYW7#+UjTnR^~j;eVbyNNJzDG$~Fj z91WDvv0Jb|KW3g%K778PT)T^Qg&f=~5ste|nNoAMszsmhAg@30+ZlX#dQ>3n87*7T z5kUXicmrPX^QaSodVjESQ@dDbT{d!gd!B$oAU+q;@qTE`)#c6uPiN>OFn@JLEzesD zUi!N8SH0xWOcwXVo*EV}T-hOOUqa3j>D95?>>U&C+YSVL4azPX28K79b8FtjTN*=~ zNQ17<_z*WT{{r$0Rm`Lfy|??v=hwx?$-p(pS@X$3VpqAVX;!j5pRH5~pCIx>qy3AK zx|gH|DD!D$QD>T)ZL`Rd@g4B}m~KcovmP9jnO}^ilrIgmL}-mnw>(++FdV`Bv^xr) zt}^|rGrOG{?>UO`n3W+c#WczQopYwdvL-zuVP#+HoiNrzapnL@l5O2Ip z!0-CFLWFENh_VwxyUSJW>_g(A4DYF}nxfJ8`jtkSQ&sJpc`AFeQ-4}hqc25Nm3WG zpK{5b=@1;Pp}+dlXgrfQN|Ko0DKzTdpQ8a@ycn3X_><;2#n?q^V(lDtd1=R_-{EI? zsF8GL3UR0)%PYB8TE0iZWn$Sn9&jD_jnO)0s98X7t?4*yW?7SWC~)%sT7Vbxuup1F ztO8z;NLVUR4d*5ZPL4R@b<=`Oa+&jTW3W1y)PlafEdGE-&vxD zIZ^8Gh7c0PG7kUigK<;eWXq7bewg%*B7FSc*z&<4SQ;635f&C>*Vx=V4H z4Df!*O~@(6A5XHdvX0HP`I*&QrDwh}Tr=sM{Z2=}u3*c`I(VJ_2HdnPFZ1jl$gfi~ zeY;zV{y{=a`zzHkl!_YEch;nBadid}5>Z~ZnN$uvubpmq#X0RfjOxTjkA!FWx_;*I zLN+~sgFy>hN0|=MgIvFgpIg6ON6W`Bv_69p3Qr0ICGM~t25kL!j2*(-TQaB0|Ci4oKnA7MaILw z1^RSYiQQN!)V(P9MC*6lfZ9F}$zv9AwUGEl$Y{bX&p$J_@k^Wnda$b%# zx-agu68df#O@V|eNUl>rt1hw-4f91!ht@#uh_A@bMKC-g6&;$Ajo5}e4n96DL7g_6 zo2+o%4)+i^AoEYIIO*8g;t|SpzzlG4^Sa8`(UYWsr$@T;ptY<5ZbNcF&&d3$7)W~ku zc)W%&+*5FpWATVP?yQi8I#`ER1k^i;1y4S7dr(D(1B}mUB(zp|t3#6xMy>%9dEHl@ zne(E)z%-2P60ZyV*Tf#9)%pjXOvU&_?D*Y}Bso$V@E5EU+vR+maSW-N7r`|s=0$BCJ0z4w3pHs$nHFP+kb=`^d$*W};OARALMbdi-Z!Z9~4y0+L zVfz6)1#m7 zIe9fid7#k%n#+^u{a&xA0>Y8~^a!iAAU>;hmrp}2@S+I}#Qn+4UsUi_=V4J$Q5|lt zjDN=AW6%+uas zoBa0=Cfp=eTIar29N3!inxQZb4i0@0RD-kw)yz5uf5Dr@g_$?CXW5%S{!Xb3spGyEV_T+(mNZA3<`xSmx-|;j{0K+5ObHw>P;_N7Kyr z*>y?PL2K1cNGZ=#IVB`|V>!8i-qWQJr+KtpZKHDS_I1OeHvKa(ML~zuY>3&nG>i(} zR)rS6;T$)@!B}pE^s1?6_<9289#S6>^nq-%A7j{Y*XuxneSj$WTjLHlpnWycOkyqq zqL*3Z9TrU?XAR6Fhh9>-)55dtj=EB_>>QW6u?6n!3Z|w96^rek$Z^6AAq^X(HcYU% zVJgLW;wh^?+D<+Iai%x7#xXS_^;(qaBUL6`@PVRbV7fjdf}UxOYPoN&zy5p1R#3f`vFhxh42?!h`%v`rkfM>y@Ron@6nls{FDuJi{>}c0 zHL2FeG!+VV6v)e2lcEZyOBU@@q|ec5t@q!KlL`6le{bey9^63cm`AzzF^Q#*>A~uH zyPze<5x2`()_~v%slukl`P3*M7n~0HIY78v8QRoT=@ZbuHDOXawalnYm54 zg-eVxQF4}D^jqYK!(ws5_ajmQ;YFC@OsoR)8Dl)EIM@tbgoP2~^{2l0RZe*zEKzI` zp9pXBYEM=eUVgSnMus)E%baiS7YCq@P#`~a#{UD0idv;o&7FM$$Y|-TiN$P~1|@4l zaTd%zq-J7WBOzIipwuigV9$aj7Kf?Qt-H48mhkrGS=AskL30v%Lm$qctXUMW??Ob|ZTj)8br)NGby~gS zeed{9CxpcQZIWZ0XEu=&wS5QEuAYKOgg>&q0e| zmE|c3xP7W5oW&RKc};&xQN8M|c)x5wQ#^Ryya!J`p^)Z|!-h!@E0;IFN-L1e5TNOf zV*Yp3UcfPLy_JD$FpJ%bL(!Bht6rq@RN1S%3>ASMn4P+i-*Y0=H%`C3&>nktbiHPE zIv`meYo93$#5Yv_Xc$$7n9!XWnw&XIjC)yc6(qPo7nypGZ0>1KxdS-HvG>JZAa+g8 zXB;KYiCX2b@-pcSd?f6PRo}zgTx|T8Q6|4$5bc@NHmluWBa#PP_7%kDq4{W!+JkoK6h)XA-yD|LrVfRSktBYs=CQO1eWz>m2RCP{wTNbfNazD z`QNt+y^J2ajA<~xh=v*1Djif`a&9+EgCo@CvHqr)lh(!Zc{8oj%&a4KGcsn=6%LM^ zXo?7XS!^5yU3F3d)5V2+?w@lL#K%Zqe`C4ON(iTtXCx5a=tKkBZjjaXt-&G6Lw0ff zq<7&dE!VE`?N0Ztf%s{{w2+3#nWJ8^bO%~voa0{k+f+O^bqYD=^A*V zqJ9T1yRARnJRJ$l$$HfX?QmNL5PwERad^0*Zs9YkvrG>raSy3%yTNEFsQ&v^ig)#E zND#-!o?1{8iRoU$$gfof9KZzvJWVCd6fh`Xk0KDiGlmBxh_9M$J#T;5-=^5v+0kip z^>t+!i1f^SJf;J*HevOJLZg7oL^A5LvL2(u#l^d8r0_ok#QDY$agIonS{Z(v>p&cv zH9Zq=>!dx%DBuoKc1Bs*+cTCNlx!AsA=V9d$Yz%Cs+R=(6!XQUKjC1%B#$yMj5%yf z!JlxXt63zD2dTi4^6-w`+~T)HU{Q*RwO#Ze{o%EXvrwM7!LRIWMD_4$hG(e%iPr!Xbxy+!&KXN$zBgF(?H+p(&0cqJe?x;)j%#>IY_>|R*$_=^ zO7^b`mHI`V`>9-w@2MQ4&Wj^7x{{*!rY&S7v&G=iDR9YIp@JeSpMV%$;$Ner(0(Hz zc)R5muhwSm=gpi<5)RJM(V4Na8-B0S{jGsYcfd|D768tGQ)_g?GjK4|GY*NlJtX!x zUtQa1`){E+F}Jh^rwC$R)sd}Hk!v4cJ*wY$bEEL(tL&iwhmF@Fk=6Z1TDqN6oj{r? ze~7?_1y`ak(Y`{Ky8OCojHbiWi^7vjp*MG{-{y+$W7DF?3Zz5fRyWPz{)yh@=983| z*uO~P%0Q04&gC@hd8-YkK-J3f&4;$0HQZNvJMj5@Z1a7@I3L%#i{eddyHDl82JzSR z=3?mHDmNc1deqd?oa-QC4vz~;n6;UUkjx*( zl&DlBpB%!*_LKyDcBIyAs4M7ouNS4lp=5yMJw2whJoCcA!g9NBuqeY>ensFTIMbMo zoUn|HMUj83$Pnt&ou77n}nFA0eOH zt4|71MEN=mhjMt1lDTDxj6}sBKDJb}4m9`s?|_P?S&)GtOmeLR;MRLejH|ylggC-; z=2Ime@2$+M13s?J?ZyrXiddzc4h=G(LF#Z>F0nD~yfcc!b(AWIy;GZiENzA5!ey*=B8tVqfD7Gw0#69(LHKE<%=mnNX8(wF=?PK$vM5MoD`ArgWYZ0}#Dg+uKAM_&Fvx10?pkHZ!F zELVZ~5DI}xO|dyJePY-ftl15boaY-Z*PYS`w3{zjaPVUCI+YgGXit9$uGRdWl+5FH zOjS8PX8SrV^{{U-VhAeqcpu!|`w^(Suug9T#ucipPMO*x+qcx&vB~i`1=9p3EgynW zEy`4BG<)_13+x%M_CCJtfWXa#asKL*sMVz|7UYEt8uoM|LQ-1by*~PBiI7IOo9Syg z{btEx9h(0Pao>Tj#Vbz834or-mOibR&2XjUYL&;z3Cb7lk^2Aq@(=QUHE_{I~PSuvVRTR z=(b2FKi$Sp)+196AoWa;h=%_-U&L^^58U9+LIHkK6ki9lT%s|*54wIA?s~q;MS1F}4>OUUt$ik( zF@OF*-#D%a6@-aiVs#L9!`f2*t_gOYC8�Zs; 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 literal 0 HcmV?d00001 diff --git a/bsp/stm32/stm32h563-st-nucleo/figures/hardware_block_diagram.png b/bsp/stm32/stm32h563-st-nucleo/figures/hardware_block_diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..ab4cc5571c8482244109074b48f2e9a4f765d1f1 GIT binary patch literal 137233 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�uln@tB&Rn!UUqgc%qTdpZm5I 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 I{y{@;@<*P>b9~hGvOV-z2 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 W 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 literal 0 HcmV?d00001 diff --git a/bsp/stm32/stm32h563-st-nucleo/project.ewd b/bsp/stm32/stm32h563-st-nucleo/project.ewd new file mode 100644 index 0000000000..4b27053590 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/project.ewd @@ -0,0 +1,2834 @@ + + + 3 + + rt-thread + + ARM + + 1 + + C-SPY + 2 + + 29 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 6 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\IARProbe\IarProbePlugin.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + + 0 + + C-SPY + 2 + + 29 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 0 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IJET_ID + 2 + + 8 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 0 + + + + + + + + STLINK_ID + 2 + + 4 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 6 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin + 1 + + + $EW_DIR$\common\plugins\IARProbe\IarProbePlugin.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + diff --git a/bsp/stm32/stm32h563-st-nucleo/project.ewp b/bsp/stm32/stm32h563-st-nucleo/project.ewp new file mode 100644 index 0000000000..3b21afd4c0 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/project.ewp @@ -0,0 +1,2417 @@ + + 3 + + rt-thread + + ARM + + 1 + + General + 3 + + 31 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 10 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 23 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Release + + ARM + + 0 + + General + 3 + + 31 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 35 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 10 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 23 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + BILINK + 0 + + + + + Applications + + $PROJ_DIR$\applications\main.c + + + + Compiler + + $PROJ_DIR$\..\..\..\components\libc\compilers\common\cctype.c + + + $PROJ_DIR$\..\..\..\components\libc\compilers\common\cstdio.c + + + $PROJ_DIR$\..\..\..\components\libc\compilers\common\cstdlib.c + + + $PROJ_DIR$\..\..\..\components\libc\compilers\common\cstring.c + + + $PROJ_DIR$\..\..\..\components\libc\compilers\common\ctime.c + + + $PROJ_DIR$\..\..\..\components\libc\compilers\common\cwchar.c + + + $PROJ_DIR$\..\..\..\components\libc\compilers\dlib\environ.c + + + $PROJ_DIR$\..\..\..\components\libc\compilers\dlib\syscall_close.c + + + $PROJ_DIR$\..\..\..\components\libc\compilers\dlib\syscall_lseek.c + + + $PROJ_DIR$\..\..\..\components\libc\compilers\dlib\syscall_mem.c + + + $PROJ_DIR$\..\..\..\components\libc\compilers\dlib\syscall_open.c + + + $PROJ_DIR$\..\..\..\components\libc\compilers\dlib\syscall_read.c + + + $PROJ_DIR$\..\..\..\components\libc\compilers\dlib\syscall_remove.c + + + $PROJ_DIR$\..\..\..\components\libc\compilers\dlib\syscall_write.c + + + $PROJ_DIR$\..\..\..\components\libc\compilers\dlib\syscalls.c + + + + CPU + + $PROJ_DIR$\..\..\..\libcpu\arm\common\atomic_arm.c + + + $PROJ_DIR$\..\..\..\libcpu\arm\common\div0.c + + + $PROJ_DIR$\..\..\..\libcpu\arm\common\showmem.c + + + $PROJ_DIR$\..\..\..\libcpu\arm\cortex-m33\context_iar.S + + + $PROJ_DIR$\..\..\..\libcpu\arm\cortex-m33\cpuport.c + + + $PROJ_DIR$\..\..\..\libcpu\arm\cortex-m33\syscall_iar.S + + + $PROJ_DIR$\..\..\..\libcpu\arm\cortex-m33\trustzone.c + + + + DeviceDrivers + + $PROJ_DIR$\..\..\..\components\drivers\ipc\completion.c + + + $PROJ_DIR$\..\..\..\components\drivers\ipc\dataqueue.c + + + $PROJ_DIR$\..\..\..\components\drivers\ipc\pipe.c + + + $PROJ_DIR$\..\..\..\components\drivers\ipc\ringblk_buf.c + + + $PROJ_DIR$\..\..\..\components\drivers\ipc\ringbuffer.c + + + $PROJ_DIR$\..\..\..\components\drivers\ipc\waitqueue.c + + + $PROJ_DIR$\..\..\..\components\drivers\ipc\workqueue.c + + + $PROJ_DIR$\..\..\..\components\drivers\misc\pin.c + + + $PROJ_DIR$\..\..\..\components\drivers\serial\serial.c + + + + Drivers + + $PROJ_DIR$\..\libraries\STM32U5xx_HAL\CMSIS\Device\ST\STM32U5xx\Source\Templates\iar\startup_stm32u575xx.s + + + $PROJ_DIR$\board\CubeMX_Config\Src\stm32u5xx_hal_msp.c + + + $PROJ_DIR$\board\board.c + + + $PROJ_DIR$\..\libraries\HAL_Drivers\drv_common.c + + + $PROJ_DIR$\..\libraries\HAL_Drivers\drv_gpio.c + + + $PROJ_DIR$\..\libraries\HAL_Drivers\drv_usart.c + + + + Finsh + + $PROJ_DIR$\..\..\..\components\finsh\shell.c + + + $PROJ_DIR$\..\..\..\components\finsh\msh.c + + + $PROJ_DIR$\..\..\..\components\finsh\msh_parse.c + + + $PROJ_DIR$\..\..\..\components\finsh\cmd.c + + + + Kernel + + $PROJ_DIR$\..\..\..\src\clock.c + + + $PROJ_DIR$\..\..\..\src\components.c + + + $PROJ_DIR$\..\..\..\src\device.c + + + $PROJ_DIR$\..\..\..\src\idle.c + + + $PROJ_DIR$\..\..\..\src\ipc.c + + + $PROJ_DIR$\..\..\..\src\irq.c + + + $PROJ_DIR$\..\..\..\src\kservice.c + + + $PROJ_DIR$\..\..\..\src\mem.c + + + $PROJ_DIR$\..\..\..\src\mempool.c + + + $PROJ_DIR$\..\..\..\src\object.c + + + $PROJ_DIR$\..\..\..\src\scheduler_up.c + + + $PROJ_DIR$\..\..\..\src\thread.c + + + $PROJ_DIR$\..\..\..\src\timer.c + + + + Libraries + + $PROJ_DIR$\..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_uart.c + + + $PROJ_DIR$\..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal.c + + + $PROJ_DIR$\..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_crc.c + + + $PROJ_DIR$\..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_icache.c + + + $PROJ_DIR$\..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_uart_ex.c + + + $PROJ_DIR$\..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_dma.c + + + $PROJ_DIR$\..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_usart.c + + + $PROJ_DIR$\..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_pwr.c + + + $PROJ_DIR$\..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_rcc.c + + + $PROJ_DIR$\..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_gpio.c + + + $PROJ_DIR$\..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_rng.c + + + $PROJ_DIR$\..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_cortex.c + + + $PROJ_DIR$\..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_cryp.c + + + $PROJ_DIR$\..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_crc_ex.c + + + $PROJ_DIR$\..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_rcc_ex.c + + + $PROJ_DIR$\..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_usart_ex.c + + + $PROJ_DIR$\..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_cryp_ex.c + + + $PROJ_DIR$\..\libraries\STM32U5xx_HAL\CMSIS\Device\ST\STM32U5xx\Source\Templates\system_stm32u5xx.c + + + $PROJ_DIR$\..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_pwr_ex.c + + + $PROJ_DIR$\..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_comp.c + + + $PROJ_DIR$\..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_dma_ex.c + + + $PROJ_DIR$\..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_exti.c + + + + POSIX + + diff --git a/bsp/stm32/stm32h563-st-nucleo/project.eww b/bsp/stm32/stm32h563-st-nucleo/project.eww new file mode 100644 index 0000000000..c2cb02eb1e --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/project.eww @@ -0,0 +1,10 @@ + + + + + $WS_DIR$\project.ewp + + + + + diff --git a/bsp/stm32/stm32h563-st-nucleo/project.uvoptx b/bsp/stm32/stm32h563-st-nucleo/project.uvoptx new file mode 100644 index 0000000000..0970633078 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/project.uvoptx @@ -0,0 +1,1304 @@ + + + + 1.0 + +

### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc; *.md + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + rtthread + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + UL2V8M + UL2V8M(-S0 -C0 -P0 -FD20000000 -FC8000 -FN2 -FF0STM32H5xx_2M_0800 -FS08000000 -FL0200000 -FF1STM32H5xx_2M_0C00 -FS1C000000 -FL1200000 -FP0($$Device:STM32H563ZITx$CMSIS\Flash\STM32H5xx_2M_0800.FLM) -FP1($$Device:STM32H563ZITx$CMSIS\Flash\STM32H5xx_2M_0C00.FLM)) + + + 0 + ST-LINKIII-KEIL_SWO + -U001300334D46501220383832 -O2254 -SF10000 -C0 -A1 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(6BA02477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8000 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0STM32H5xx_2M_0800 -FS08000000 -FL0200000 -FP0($$Device:STM32H563ZITx$CMSIS\Flash\STM32H5xx_2M_0800.FLM) + + + + + 0 + + + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 0 + 0 + 2 + 10000000 + + + + + + Applications + 0 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + applications\main.c + main.c + 0 + 0 + + + + + Compiler + 0 + 0 + 0 + 0 + + 2 + 2 + 1 + 0 + 0 + 0 + ..\..\..\components\libc\compilers\armlibc\syscall_mem.c + syscall_mem.c + 0 + 0 + + + 2 + 3 + 1 + 0 + 0 + 0 + ..\..\..\components\libc\compilers\armlibc\syscalls.c + syscalls.c + 0 + 0 + + + 2 + 4 + 1 + 0 + 0 + 0 + ..\..\..\components\libc\compilers\common\cctype.c + cctype.c + 0 + 0 + + + 2 + 5 + 1 + 0 + 0 + 0 + ..\..\..\components\libc\compilers\common\cstdlib.c + cstdlib.c + 0 + 0 + + + 2 + 6 + 1 + 0 + 0 + 0 + ..\..\..\components\libc\compilers\common\cstring.c + cstring.c + 0 + 0 + + + 2 + 7 + 1 + 0 + 0 + 0 + ..\..\..\components\libc\compilers\common\ctime.c + ctime.c + 0 + 0 + + + 2 + 8 + 1 + 0 + 0 + 0 + ..\..\..\components\libc\compilers\common\cunistd.c + cunistd.c + 0 + 0 + + + 2 + 9 + 1 + 0 + 0 + 0 + ..\..\..\components\libc\compilers\common\cwchar.c + cwchar.c + 0 + 0 + + + + + CPU + 0 + 0 + 0 + 0 + + 3 + 10 + 1 + 0 + 0 + 0 + ..\..\..\libcpu\arm\common\atomic_arm.c + atomic_arm.c + 0 + 0 + + + 3 + 11 + 1 + 0 + 0 + 0 + ..\..\..\libcpu\arm\common\div0.c + div0.c + 0 + 0 + + + 3 + 12 + 1 + 0 + 0 + 0 + ..\..\..\libcpu\arm\common\showmem.c + showmem.c + 0 + 0 + + + 3 + 13 + 2 + 0 + 0 + 0 + ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + context_rvds.S + 0 + 0 + + + 3 + 14 + 1 + 0 + 0 + 0 + ..\..\..\libcpu\arm\cortex-m33\cpuport.c + cpuport.c + 0 + 0 + + + 3 + 15 + 2 + 0 + 0 + 0 + ..\..\..\libcpu\arm\cortex-m33\syscall_rvds.S + syscall_rvds.S + 0 + 0 + + + 3 + 16 + 1 + 0 + 0 + 0 + ..\..\..\libcpu\arm\cortex-m33\trustzone.c + trustzone.c + 0 + 0 + + + + + DeviceDrivers + 0 + 0 + 0 + 0 + + 4 + 17 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\core\device.c + device.c + 0 + 0 + + + 4 + 18 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\i2c\i2c-bit-ops.c + i2c-bit-ops.c + 0 + 0 + + + 4 + 19 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\i2c\i2c_core.c + i2c_core.c + 0 + 0 + + + 4 + 20 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\i2c\i2c_dev.c + i2c_dev.c + 0 + 0 + + + 4 + 21 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\ipc\completion.c + completion.c + 0 + 0 + + + 4 + 22 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\ipc\dataqueue.c + dataqueue.c + 0 + 0 + + + 4 + 23 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\ipc\pipe.c + pipe.c + 0 + 0 + + + 4 + 24 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\ipc\ringblk_buf.c + ringblk_buf.c + 0 + 0 + + + 4 + 25 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\ipc\ringbuffer.c + ringbuffer.c + 0 + 0 + + + 4 + 26 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\ipc\waitqueue.c + waitqueue.c + 0 + 0 + + + 4 + 27 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\ipc\workqueue.c + workqueue.c + 0 + 0 + + + 4 + 28 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\misc\adc.c + adc.c + 0 + 0 + + + 4 + 29 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\misc\pin.c + pin.c + 0 + 0 + + + 4 + 30 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\misc\rt_drv_pwm.c + rt_drv_pwm.c + 0 + 0 + + + 4 + 31 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\serial\serial.c + serial.c + 0 + 0 + + + 4 + 32 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\spi\spi_core.c + spi_core.c + 0 + 0 + + + 4 + 33 + 1 + 0 + 0 + 0 + ..\..\..\components\drivers\spi\spi_dev.c + spi_dev.c + 0 + 0 + + + + + Drivers + 0 + 0 + 0 + 0 + + 5 + 34 + 1 + 0 + 0 + 0 + ..\libraries\HAL_Drivers\drv_adc.c + drv_adc.c + 0 + 0 + + + 5 + 35 + 1 + 0 + 0 + 0 + ..\libraries\HAL_Drivers\drv_common.c + drv_common.c + 0 + 0 + + + 5 + 36 + 1 + 0 + 0 + 0 + ..\libraries\HAL_Drivers\drv_gpio.c + drv_gpio.c + 0 + 0 + + + 5 + 37 + 1 + 0 + 0 + 0 + ..\libraries\HAL_Drivers\drv_spi.c + drv_spi.c + 0 + 0 + + + 5 + 38 + 1 + 0 + 0 + 0 + ..\libraries\HAL_Drivers\drv_usart.c + drv_usart.c + 0 + 0 + + + 5 + 39 + 2 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\Source\Templates\arm\startup_stm32h563xx.s + startup_stm32h563xx.s + 0 + 0 + + + 5 + 40 + 1 + 0 + 0 + 0 + board\CubeMX_Config\Src\stm32h5xx_hal_msp.c + stm32h5xx_hal_msp.c + 0 + 0 + + + 5 + 41 + 1 + 0 + 0 + 0 + board\board.c + board.c + 0 + 0 + + + + + Finsh + 0 + 0 + 0 + 0 + + 6 + 42 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\shell.c + shell.c + 0 + 0 + + + 6 + 43 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\msh.c + msh.c + 0 + 0 + + + 6 + 44 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\msh_parse.c + msh_parse.c + 0 + 0 + + + 6 + 45 + 1 + 0 + 0 + 0 + ..\..\..\components\finsh\cmd.c + cmd.c + 0 + 0 + + + + + Kernel + 0 + 0 + 0 + 0 + + 7 + 46 + 1 + 0 + 0 + 0 + ..\..\..\src\clock.c + clock.c + 0 + 0 + + + 7 + 47 + 1 + 0 + 0 + 0 + ..\..\..\src\components.c + components.c + 0 + 0 + + + 7 + 48 + 1 + 0 + 0 + 0 + ..\..\..\src\idle.c + idle.c + 0 + 0 + + + 7 + 49 + 1 + 0 + 0 + 0 + ..\..\..\src\ipc.c + ipc.c + 0 + 0 + + + 7 + 50 + 1 + 0 + 0 + 0 + ..\..\..\src\irq.c + irq.c + 0 + 0 + + + 7 + 51 + 1 + 0 + 0 + 0 + ..\..\..\src\kservice.c + kservice.c + 0 + 0 + + + 7 + 52 + 1 + 0 + 0 + 0 + ..\..\..\src\mem.c + mem.c + 0 + 0 + + + 7 + 53 + 1 + 0 + 0 + 0 + ..\..\..\src\mempool.c + mempool.c + 0 + 0 + + + 7 + 54 + 1 + 0 + 0 + 0 + ..\..\..\src\object.c + object.c + 0 + 0 + + + 7 + 55 + 1 + 0 + 0 + 0 + ..\..\..\src\scheduler_up.c + scheduler_up.c + 0 + 0 + + + 7 + 56 + 1 + 0 + 0 + 0 + ..\..\..\src\thread.c + thread.c + 0 + 0 + + + 7 + 57 + 1 + 0 + 0 + 0 + ..\..\..\src\timer.c + timer.c + 0 + 0 + + + + + Libraries + 0 + 0 + 0 + 0 + + 8 + 58 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_dma_ex.c + stm32h5xx_hal_dma_ex.c + 0 + 0 + + + 8 + 59 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_gpio.c + stm32h5xx_hal_gpio.c + 0 + 0 + + + 8 + 60 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_rcc_ex.c + stm32h5xx_hal_rcc_ex.c + 0 + 0 + + + 8 + 61 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_i2c.c + stm32h5xx_hal_i2c.c + 0 + 0 + + + 8 + 62 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_icache.c + stm32h5xx_hal_icache.c + 0 + 0 + + + 8 + 63 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_adc_ex.c + stm32h5xx_hal_adc_ex.c + 0 + 0 + + + 8 + 64 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_uart_ex.c + stm32h5xx_hal_uart_ex.c + 0 + 0 + + + 8 + 65 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_i2c_ex.c + stm32h5xx_hal_i2c_ex.c + 0 + 0 + + + 8 + 66 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_tim.c + stm32h5xx_hal_tim.c + 0 + 0 + + + 8 + 67 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_comp.c + stm32h5xx_hal_comp.c + 0 + 0 + + + 8 + 68 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_cryp_ex.c + stm32h5xx_hal_cryp_ex.c + 0 + 0 + + + 8 + 69 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_pwr.c + stm32h5xx_hal_pwr.c + 0 + 0 + + + 8 + 70 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_cryp.c + stm32h5xx_hal_cryp.c + 0 + 0 + + + 8 + 71 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_usart_ex.c + stm32h5xx_hal_usart_ex.c + 0 + 0 + + + 8 + 72 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_exti.c + stm32h5xx_hal_exti.c + 0 + 0 + + + 8 + 73 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_rng.c + stm32h5xx_hal_rng.c + 0 + 0 + + + 8 + 74 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_crc_ex.c + stm32h5xx_hal_crc_ex.c + 0 + 0 + + + 8 + 75 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_tim_ex.c + stm32h5xx_hal_tim_ex.c + 0 + 0 + + + 8 + 76 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal.c + stm32h5xx_hal.c + 0 + 0 + + + 8 + 77 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\Source\Templates\system_stm32h5xx.c + system_stm32h5xx.c + 0 + 0 + + + 8 + 78 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_cortex.c + stm32h5xx_hal_cortex.c + 0 + 0 + + + 8 + 79 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_rcc.c + stm32h5xx_hal_rcc.c + 0 + 0 + + + 8 + 80 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_dma.c + stm32h5xx_hal_dma.c + 0 + 0 + + + 8 + 81 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_uart.c + stm32h5xx_hal_uart.c + 0 + 0 + + + 8 + 82 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_pwr_ex.c + stm32h5xx_hal_pwr_ex.c + 0 + 0 + + + 8 + 83 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_spi.c + stm32h5xx_hal_spi.c + 0 + 0 + + + 8 + 84 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_adc.c + stm32h5xx_hal_adc.c + 0 + 0 + + + 8 + 85 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_spi_ex.c + stm32h5xx_hal_spi_ex.c + 0 + 0 + + + 8 + 86 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_usart.c + stm32h5xx_hal_usart.c + 0 + 0 + + + 8 + 87 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_lptim.c + stm32h5xx_hal_lptim.c + 0 + 0 + + + 8 + 88 + 1 + 0 + 0 + 0 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_crc.c + stm32h5xx_hal_crc.c + 0 + 0 + + + + diff --git a/bsp/stm32/stm32h563-st-nucleo/project.uvprojx b/bsp/stm32/stm32h563-st-nucleo/project.uvprojx new file mode 100644 index 0000000000..3efe0f17ef --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/project.uvprojx @@ -0,0 +1,883 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + rtthread + 0x4 + ARM-ADS + 6140000::V6.14::ARMCLANG + 1 + + + STM32H563ZITx + STMicroelectronics + Keil.STM32H5xx_DFP.1.1.0 + https://www.keil.com/pack/ + IRAM(0x20000000,0x00050000) IRAM2(0x20050000,0x00050000) IROM(0x08000000,0x00200000) CPUTYPE("Cortex-M33") FPU3(SFPU) DSP TZ CLOCK(12000000) ELITTLE + + + UL2V8M(-S0 -C0 -P0 -FD20000000 -FC8000 -FN2 -FF0STM32H5xx_2M_0800 -FS08000000 -FL0200000 -FF1STM32H5xx_2M_0C00 -FS1C000000 -FL1200000 -FP0($$Device:STM32H563ZITx$CMSIS\Flash\STM32H5xx_2M_0800.FLM) -FP1($$Device:STM32H563ZITx$CMSIS\Flash\STM32H5xx_2M_0C00.FLM)) + 0 + $$Device:STM32H563ZITx$Drivers\CMSIS\Device\ST\STM32H5xx\Include\stm32h5xx.h + + + + + + + + + + $$Device:STM32H563ZITx$CMSIS\SVD\STM32H563.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\build\keil\Obj\ + rtthread + 1 + 0 + 0 + 1 + 0 + + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin !L --output rtthread.bin + + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 0 + + + + + + + SARMV8M.DLL + -MPU + TCM.DLL + -pCM33 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4102 + + 1 + BIN\UL2V8M.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M33" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 0 + 0 + 1 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 4 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x50000 + + + 1 + 0x8000000 + 0x200000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x200000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x50000 + + + 0 + 0x20050000 + 0x50000 + + + + + + 1 + 7 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 0 + 0 + 0 + 0 + 3 + 3 + 1 + 1 + 0 + 0 + 0 + + + STM32H563xx, __STDC_LIMIT_MACROS, RT_USING_ARMLIBC, USE_HAL_DRIVER, RT_USING_LIBC, __CLK_TCK=RT_TICK_PER_SECOND, __RTTHREAD__ + + ..\..\..\components\libc\compilers\common\include;.;..\..\..\components\drivers\include;..\libraries\HAL_Drivers\CMSIS\Include;..\..\..\components\libc\posix\io\poll;..\libraries\HAL_Drivers\config;..\..\..\components\libc\compilers\common\extension;..\..\..\components\drivers\spi;..\..\..\libcpu\arm\common;..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Inc;..\..\..\libcpu\arm\cortex-m33;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\libc\posix\ipc;..\libraries\HAL_Drivers;..\..\..\include;..\..\..\components\libc\posix\io\epoll;..\..\..\components\drivers\include;..\..\..\components\finsh;..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\Include;board\CubeMX_Config\Inc;..\..\..\components\libc\posix\io\eventfd;applications;board;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\libc\compilers\common\extension\fcntl\octal + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 4 + + + + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x08000000 + 0x20000000 + + .\board\linker_scripts\link.sct + + + + + + + + + + + Applications + + + main.c + 1 + applications\main.c + + + + + Compiler + + + syscall_mem.c + 1 + ..\..\..\components\libc\compilers\armlibc\syscall_mem.c + + + syscalls.c + 1 + ..\..\..\components\libc\compilers\armlibc\syscalls.c + + + cctype.c + 1 + ..\..\..\components\libc\compilers\common\cctype.c + + + cstdlib.c + 1 + ..\..\..\components\libc\compilers\common\cstdlib.c + + + cstring.c + 1 + ..\..\..\components\libc\compilers\common\cstring.c + + + ctime.c + 1 + ..\..\..\components\libc\compilers\common\ctime.c + + + cunistd.c + 1 + ..\..\..\components\libc\compilers\common\cunistd.c + + + cwchar.c + 1 + ..\..\..\components\libc\compilers\common\cwchar.c + + + + + CPU + + + atomic_arm.c + 1 + ..\..\..\libcpu\arm\common\atomic_arm.c + + + div0.c + 1 + ..\..\..\libcpu\arm\common\div0.c + + + showmem.c + 1 + ..\..\..\libcpu\arm\common\showmem.c + + + context_rvds.S + 2 + ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + + + cpuport.c + 1 + ..\..\..\libcpu\arm\cortex-m33\cpuport.c + + + syscall_rvds.S + 2 + ..\..\..\libcpu\arm\cortex-m33\syscall_rvds.S + + + trustzone.c + 1 + ..\..\..\libcpu\arm\cortex-m33\trustzone.c + + + + + DeviceDrivers + + + device.c + 1 + ..\..\..\components\drivers\core\device.c + + + i2c-bit-ops.c + 1 + ..\..\..\components\drivers\i2c\i2c-bit-ops.c + + + i2c_core.c + 1 + ..\..\..\components\drivers\i2c\i2c_core.c + + + i2c_dev.c + 1 + ..\..\..\components\drivers\i2c\i2c_dev.c + + + completion.c + 1 + ..\..\..\components\drivers\ipc\completion.c + + + dataqueue.c + 1 + ..\..\..\components\drivers\ipc\dataqueue.c + + + pipe.c + 1 + ..\..\..\components\drivers\ipc\pipe.c + + + ringblk_buf.c + 1 + ..\..\..\components\drivers\ipc\ringblk_buf.c + + + ringbuffer.c + 1 + ..\..\..\components\drivers\ipc\ringbuffer.c + + + waitqueue.c + 1 + ..\..\..\components\drivers\ipc\waitqueue.c + + + workqueue.c + 1 + ..\..\..\components\drivers\ipc\workqueue.c + + + adc.c + 1 + ..\..\..\components\drivers\misc\adc.c + + + pin.c + 1 + ..\..\..\components\drivers\misc\pin.c + + + rt_drv_pwm.c + 1 + ..\..\..\components\drivers\misc\rt_drv_pwm.c + + + serial.c + 1 + ..\..\..\components\drivers\serial\serial.c + + + spi_core.c + 1 + ..\..\..\components\drivers\spi\spi_core.c + + + spi_dev.c + 1 + ..\..\..\components\drivers\spi\spi_dev.c + + + + + Drivers + + + drv_adc.c + 1 + ..\libraries\HAL_Drivers\drv_adc.c + + + drv_common.c + 1 + ..\libraries\HAL_Drivers\drv_common.c + + + drv_gpio.c + 1 + ..\libraries\HAL_Drivers\drv_gpio.c + + + drv_spi.c + 1 + ..\libraries\HAL_Drivers\drv_spi.c + + + drv_usart.c + 1 + ..\libraries\HAL_Drivers\drv_usart.c + + + startup_stm32h563xx.s + 2 + ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\Source\Templates\arm\startup_stm32h563xx.s + + + stm32h5xx_hal_msp.c + 1 + board\CubeMX_Config\Src\stm32h5xx_hal_msp.c + + + board.c + 1 + board\board.c + + + + + Finsh + + + shell.c + 1 + ..\..\..\components\finsh\shell.c + + + msh.c + 1 + ..\..\..\components\finsh\msh.c + + + msh_parse.c + 1 + ..\..\..\components\finsh\msh_parse.c + + + cmd.c + 1 + ..\..\..\components\finsh\cmd.c + + + + + Kernel + + + clock.c + 1 + ..\..\..\src\clock.c + + + components.c + 1 + ..\..\..\src\components.c + + + idle.c + 1 + ..\..\..\src\idle.c + + + ipc.c + 1 + ..\..\..\src\ipc.c + + + irq.c + 1 + ..\..\..\src\irq.c + + + kservice.c + 1 + ..\..\..\src\kservice.c + + + mem.c + 1 + ..\..\..\src\mem.c + + + mempool.c + 1 + ..\..\..\src\mempool.c + + + object.c + 1 + ..\..\..\src\object.c + + + scheduler_up.c + 1 + ..\..\..\src\scheduler_up.c + + + thread.c + 1 + ..\..\..\src\thread.c + + + timer.c + 1 + ..\..\..\src\timer.c + + + + + Libraries + + + stm32h5xx_hal_dma_ex.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_dma_ex.c + + + stm32h5xx_hal_gpio.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_gpio.c + + + stm32h5xx_hal_rcc_ex.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_rcc_ex.c + + + stm32h5xx_hal_i2c.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_i2c.c + + + stm32h5xx_hal_icache.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_icache.c + + + stm32h5xx_hal_adc_ex.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_adc_ex.c + + + stm32h5xx_hal_uart_ex.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_uart_ex.c + + + stm32h5xx_hal_i2c_ex.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_i2c_ex.c + + + stm32h5xx_hal_tim.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_tim.c + + + stm32h5xx_hal_comp.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_comp.c + + + stm32h5xx_hal_cryp_ex.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_cryp_ex.c + + + stm32h5xx_hal_pwr.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_pwr.c + + + stm32h5xx_hal_cryp.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_cryp.c + + + stm32h5xx_hal_usart_ex.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_usart_ex.c + + + stm32h5xx_hal_exti.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_exti.c + + + stm32h5xx_hal_rng.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_rng.c + + + stm32h5xx_hal_crc_ex.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_crc_ex.c + + + stm32h5xx_hal_tim_ex.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_tim_ex.c + + + stm32h5xx_hal.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal.c + + + system_stm32h5xx.c + 1 + ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\Source\Templates\system_stm32h5xx.c + + + stm32h5xx_hal_cortex.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_cortex.c + + + stm32h5xx_hal_rcc.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_rcc.c + + + stm32h5xx_hal_dma.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_dma.c + + + stm32h5xx_hal_uart.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_uart.c + + + stm32h5xx_hal_pwr_ex.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_pwr_ex.c + + + stm32h5xx_hal_spi.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_spi.c + + + stm32h5xx_hal_adc.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_adc.c + + + stm32h5xx_hal_spi_ex.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_spi_ex.c + + + stm32h5xx_hal_usart.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_usart.c + + + stm32h5xx_hal_lptim.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_lptim.c + + + stm32h5xx_hal_crc.c + 1 + ..\libraries\stm32h5xx_HAL\stm32h5xx_HAL_Driver\Src\stm32h5xx_hal_crc.c + + + + + + + + + + + + + + + + + <Project Info> + 0 + 1 + + + + +
diff --git a/bsp/stm32/stm32h563-st-nucleo/rtconfig.h b/bsp/stm32/stm32h563-st-nucleo/rtconfig.h new file mode 100644 index 0000000000..90dc6d2d1e --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/rtconfig.h @@ -0,0 +1,217 @@ +#ifndef RT_CONFIG_H__ +#define RT_CONFIG_H__ + +/* Automatically generated file; DO NOT EDIT. */ +/* RT-Thread Configuration */ + +/* RT-Thread Kernel */ + +#define RT_NAME_MAX 8 +#define RT_ALIGN_SIZE 8 +#define RT_THREAD_PRIORITY_32 +#define RT_THREAD_PRIORITY_MAX 32 +#define RT_TICK_PER_SECOND 1000 +#define RT_USING_OVERFLOW_CHECK +#define RT_USING_HOOK +#define RT_HOOK_USING_FUNC_PTR +#define RT_USING_IDLE_HOOK +#define RT_IDLE_HOOK_LIST_SIZE 4 +#define IDLE_THREAD_STACK_SIZE 256 +#define RT_USING_TIMER_SOFT +#define RT_TIMER_THREAD_PRIO 4 +#define RT_TIMER_THREAD_STACK_SIZE 512 + +/* kservice optimization */ + +#define RT_USING_DEBUG +#define RT_DEBUGING_COLOR +#define RT_DEBUGING_CONTEXT +#define RT_DEBUGING_INIT + +/* Inter-Thread communication */ + +#define RT_USING_SEMAPHORE +#define RT_USING_MUTEX +#define RT_USING_EVENT +#define RT_USING_MAILBOX +#define RT_USING_MESSAGEQUEUE + +/* Memory Management */ + +#define RT_USING_MEMPOOL +#define RT_USING_SMALL_MEM +#define RT_USING_SMALL_MEM_AS_HEAP +#define RT_USING_HEAP + +/* Kernel Device Object */ + +#define RT_USING_DEVICE +#define RT_USING_CONSOLE +#define RT_CONSOLEBUF_SIZE 256 +#define RT_CONSOLE_DEVICE_NAME "uart3" +#define RT_VER_NUM 0x50001 +#define RT_USING_HW_ATOMIC +#define RT_USING_CPU_FFS +#define ARCH_ARM +#define ARCH_ARM_CORTEX_M +#define ARCH_ARM_CORTEX_M33 + +/* RT-Thread Components */ + +#define RT_USING_COMPONENTS_INIT +#define RT_USING_USER_MAIN +#define RT_MAIN_THREAD_STACK_SIZE 2048 +#define RT_MAIN_THREAD_PRIORITY 10 +#define RT_USING_MSH +#define RT_USING_FINSH +#define FINSH_USING_MSH +#define FINSH_THREAD_NAME "tshell" +#define FINSH_THREAD_PRIORITY 20 +#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_USING_HISTORY +#define FINSH_HISTORY_LINES 5 +#define FINSH_USING_SYMTAB +#define FINSH_CMD_SIZE 80 +#define MSH_USING_BUILT_IN_COMMANDS +#define FINSH_USING_DESCRIPTION +#define FINSH_ARG_MAX 10 + +/* DFS: device virtual file system */ + + +/* Device Drivers */ + +#define RT_USING_DEVICE_IPC +#define RT_UNAMED_PIPE_NUMBER 64 +#define RT_USING_SYSTEM_WORKQUEUE +#define RT_SYSTEM_WORKQUEUE_STACKSIZE 2048 +#define RT_SYSTEM_WORKQUEUE_PRIORITY 23 +#define RT_USING_SERIAL +#define RT_USING_SERIAL_V1 +#define RT_SERIAL_RB_BUFSZ 64 +#define RT_USING_I2C +#define RT_USING_I2C_BITOPS +#define RT_USING_PIN +#define RT_USING_ADC +#define RT_USING_PWM +#define RT_USING_SPI + +/* Using USB */ + + +/* C/C++ and POSIX layer */ + +/* ISO-ANSI C layer */ + +/* Timezone and Daylight Saving Time */ + +#define RT_LIBC_USING_LIGHT_TZ_DST +#define RT_LIBC_TZ_DEFAULT_HOUR 8 +#define RT_LIBC_TZ_DEFAULT_MIN 0 +#define RT_LIBC_TZ_DEFAULT_SEC 0 + +/* POSIX (Portable Operating System Interface) layer */ + + +/* Interprocess Communication (IPC) */ + + +/* Socket is in the 'Network' category */ + + +/* Network */ + + +/* Utilities */ + + +/* RT-Thread Utestcases */ + + +/* RT-Thread online packages */ + +/* IoT - internet of things */ + + +/* Wi-Fi */ + +/* Marvell WiFi */ + + +/* Wiced WiFi */ + + +/* IoT Cloud */ + + +/* security packages */ + + +/* language packages */ + +/* JSON: JavaScript Object Notation, a lightweight data-interchange format */ + + +/* XML: Extensible Markup Language */ + + +/* multimedia packages */ + +/* LVGL: powerful and easy-to-use embedded GUI library */ + + +/* u8g2: a monochrome graphic library */ + + +/* PainterEngine: A cross-platform graphics application framework written in C language */ + + +/* tools packages */ + + +/* system packages */ + +/* enhanced kernel services */ + + +/* acceleration: Assembly language or algorithmic acceleration packages */ + + +/* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */ + + +/* Micrium: Micrium software products porting for RT-Thread */ + + +/* peripheral libraries and drivers */ + + +/* AI packages */ + + +/* miscellaneous packages */ + +/* project laboratory */ + +/* samples: kernel and components samples */ + + +/* entertainment: terminal games and other interesting software packages */ + +#define SOC_FAMILY_STM32 +#define SOC_SERIES_STM32H5 + +/* Hardware Drivers Config */ + +#define SOC_STM32H563ZI + +/* On-chip Peripheral Drivers */ + +#define BSP_USING_GPIO +#define BSP_USING_UART +#define BSP_USING_UART3 + +/* Board extended module Drivers */ + + +#endif diff --git a/bsp/stm32/stm32h563-st-nucleo/rtconfig.py b/bsp/stm32/stm32h563-st-nucleo/rtconfig.py new file mode 100644 index 0000000000..3f5483a3a9 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/rtconfig.py @@ -0,0 +1,152 @@ +import os + +# toolchains options +ARCH='arm' +CPU='cortex-m33' +CROSS_TOOL='gcc' + +# bsp lib config +BSP_LIBRARY_TYPE = None + +if os.getenv('RTT_CC'): + CROSS_TOOL = os.getenv('RTT_CC') +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') + +# cross_tool provides the cross compiler +# EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR +if CROSS_TOOL == 'gcc': + PLATFORM = 'gcc' + EXEC_PATH = r'C:\Users\XXYYZZ' +elif CROSS_TOOL == 'keil': + PLATFORM = 'armclang' + EXEC_PATH = r'C:/Keil_v5' +elif CROSS_TOOL == 'iar': + PLATFORM = 'iccarm' + EXEC_PATH = r'C:/Program Files (x86)/IAR Systems/Embedded Workbench 8.3' + +if os.getenv('RTT_EXEC_PATH'): + EXEC_PATH = os.getenv('RTT_EXEC_PATH') + +BUILD = 'debug' + +if PLATFORM == 'gcc': + # toolchains + PREFIX = 'arm-none-eabi-' + CC = PREFIX + 'gcc' + AS = PREFIX + 'gcc' + AR = PREFIX + 'ar' + CXX = PREFIX + 'g++' + LINK = PREFIX + 'gcc' + TARGET_EXT = 'elf' + SIZE = PREFIX + 'size' + OBJDUMP = PREFIX + 'objdump' + OBJCPY = PREFIX + 'objcopy' + + DEVICE = ' -mcpu=cortex-m33 -mthumb -mfpu=fpv5-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections' + CFLAGS = DEVICE + ' -Dgcc' + AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -Wa,-mimplicit-it=thumb ' + LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rt-thread.map,-cref,-u,Reset_Handler -T board/linker_scripts/link.lds' + + CPATH = '' + LPATH = '' + + if BUILD == 'debug': + CFLAGS += ' -O0 -gdwarf-2 -g' + AFLAGS += ' -gdwarf-2' + else: + CFLAGS += ' -O2' + + CXXFLAGS = CFLAGS + + POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n' + +elif PLATFORM == 'armclang': + # toolchains + CC = 'armclang' + CXX = 'armclang' + AS = 'armasm' + AR = 'armar' + LINK = 'armlink' + TARGET_EXT = 'axf' + + DEVICE = ' --cpu Cortex-M33.no_dsp ' + CFLAGS = ' --target=arm-arm-none-eabi -mcpu=cortex-m33+nodsp ' + CFLAGS += ' -mfpu=fpv5-sp-d16 ' + CFLAGS += ' -mfloat-abi=hard -c -fno-rtti -funsigned-char -fshort-enums -fshort-wchar ' + CFLAGS += ' -gdwarf-3 -ffunction-sections ' + AFLAGS = DEVICE + ' --apcs=interwork -mfpu=FPv5-SP' + LFLAGS = DEVICE + ' --info sizes --info totals --info unused --info veneers ' + LFLAGS += ' --list rt-thread.map ' + LFLAGS += r' --strict --scatter "board\linker_scripts\link.sct" ' + CFLAGS += ' -I' + EXEC_PATH + '/ARM/ARMCLANG/include' + LFLAGS += ' --libpath=' + EXEC_PATH + '/ARM/ARMCLANG/lib' + + EXEC_PATH += '/ARM/ARMCLANG/bin/' + + if BUILD == 'debug': + CFLAGS += ' -g -O1' # armclang recommend + AFLAGS += ' -g' + else: + CFLAGS += ' -O2' + + CXXFLAGS = CFLAGS + CFLAGS += ' -std=c99' + + POST_ACTION = 'fromelf --bin $TARGET --output rtthread.bin \nfromelf -z $TARGET' + +elif PLATFORM == 'iccarm': + # toolchains + CC = 'iccarm' + CXX = 'iccarm' + AS = 'iasmarm' + AR = 'iarchive' + LINK = 'ilinkarm' + TARGET_EXT = 'out' + + DEVICE = '-Dewarm' + + CFLAGS = DEVICE + CFLAGS += ' --diag_suppress Pa050' + CFLAGS += ' --no_cse' + CFLAGS += ' --no_unroll' + CFLAGS += ' --no_inline' + CFLAGS += ' --no_code_motion' + CFLAGS += ' --no_tbaa' + CFLAGS += ' --no_clustering' + CFLAGS += ' --no_scheduling' + CFLAGS += ' --endian=little' + CFLAGS += ' --cpu=Cortex-M33' + CFLAGS += ' -e' + CFLAGS += ' --fpu=VFPv4_sp' + CFLAGS += ' --dlib_config "' + EXEC_PATH + '/arm/INC/c/DLib_Config_Normal.h"' + CFLAGS += ' --silent' + + AFLAGS = DEVICE + AFLAGS += ' -s+' + AFLAGS += ' -w+' + AFLAGS += ' -r' + AFLAGS += ' --cpu Cortex-M33' + AFLAGS += ' --fpu VFPv5_sp' + AFLAGS += ' -S' + + if BUILD == 'debug': + CFLAGS += ' --debug' + CFLAGS += ' -On' + else: + CFLAGS += ' -Oh' + + LFLAGS = ' --config "board/linker_scripts/link.icf"' + LFLAGS += ' --entry __iar_program_start' + + CXXFLAGS = CFLAGS + + EXEC_PATH = EXEC_PATH + '/arm/bin/' + POST_ACTION = 'ielftool --bin $TARGET rtthread.bin' + +def dist_handle(BSP_ROOT, dist_dir): + import sys + cwd_path = os.getcwd() + sys.path.append(os.path.join(os.path.dirname(BSP_ROOT), 'tools')) + from sdk_dist import dist_do_building + dist_do_building(BSP_ROOT, dist_dir) diff --git a/bsp/stm32/stm32h563-st-nucleo/startup_stm32h563xx.lst b/bsp/stm32/stm32h563-st-nucleo/startup_stm32h563xx.lst new file mode 100644 index 0000000000..234860dd5a --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/startup_stm32h563xx.lst @@ -0,0 +1,3069 @@ + + + +ARM Macro Assembler Page 1 + + + 1 00000000 ;******************************************************* + ************************ + 2 00000000 ;* File Name : startup_stm32h563xx.s + 3 00000000 ;* Author : MCD Application Team + 4 00000000 ;* Description : STM32H563xx Non Crypto devices v + ector table for MDK-ARM toolchain. + 5 00000000 ;* This module performs: + 6 00000000 ;* - Set the initial SP + 7 00000000 ;* - Set the initial PC == Reset_Ha + ndler + 8 00000000 ;* - Set the vector table entries w + ith the exceptions ISR address + 9 00000000 ;* - Branches to __main in the C li + brary (which eventually + 10 00000000 ;* calls main()). + 11 00000000 ;* After Reset the Cortex-M33 proce + ssor is in Thread mode, + 12 00000000 ;* priority is Privileged, and the + Stack is set to Main. + 13 00000000 ;******************************************************* + ************************ + 14 00000000 ;* @attention + 15 00000000 ;* + 16 00000000 ;* Copyright (c) 2023 STMicroelectronics. + 17 00000000 ;* All rights reserved. + 18 00000000 ;* + 19 00000000 ;* This software is licensed under terms that can be fou + nd in the LICENSE file + 20 00000000 ;* in the root directory of this software component. + 21 00000000 ;* If no LICENSE file comes with this software, it is pr + ovided AS-IS. + 22 00000000 ;* + 23 00000000 ;******************************************************* + ************************ + 24 00000000 ;* <<< Use Configuration Wizard in Context Menu >>> + 25 00000000 ; + 26 00000000 ; Amount of memory (in bytes) allocated for Stack + 27 00000000 ; Tailor this value to your application needs + 28 00000000 ; Stack Configuration + 29 00000000 ; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> + 30 00000000 ; + 31 00000000 + 32 00000000 00000400 + Stack_Size + EQU 0x00000400 + 33 00000000 + 34 00000000 AREA STACK, NOINIT, READWRITE, ALIGN +=3 + 35 00000000 Stack_Mem + SPACE Stack_Size + 36 00000400 __initial_sp + 37 00000400 + 38 00000400 + 39 00000400 ; Heap Configuration + 40 00000400 ; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> + 41 00000400 ; + 42 00000400 + 43 00000400 00000200 + Heap_Size + + + +ARM Macro Assembler Page 2 + + + EQU 0x00000200 + 44 00000400 + 45 00000400 AREA HEAP, NOINIT, READWRITE, ALIGN= +3 + 46 00000000 __heap_base + 47 00000000 Heap_Mem + SPACE Heap_Size + 48 00000200 __heap_limit + 49 00000200 + 50 00000200 PRESERVE8 + 51 00000200 THUMB + 52 00000200 + 53 00000200 + 54 00000200 ; Vector Table Mapped to Address 0 at Reset + 55 00000200 AREA RESET, DATA, READONLY + 56 00000000 EXPORT __Vectors + 57 00000000 EXPORT __Vectors_End + 58 00000000 EXPORT __Vectors_Size + 59 00000000 + 60 00000000 00000000 + __Vectors + DCD __initial_sp ; Top of Stack + 61 00000004 00000000 DCD Reset_Handler ; Reset Handler + 62 00000008 00000000 DCD NMI_Handler ; NMI Handler + 63 0000000C 00000000 DCD HardFault_Handler ; Hard Fault + Handler + 64 00000010 00000000 DCD MemManage_Handler + ; MPU Fault Handler + + 65 00000014 00000000 DCD BusFault_Handler + ; Bus Fault Handler + + 66 00000018 00000000 DCD UsageFault_Handler ; Usage Faul + t Handler + 67 0000001C 00000000 DCD SecureFault_Handler ; Secure Fa + ult Handler + 68 00000020 00000000 DCD 0 ; Reserved + 69 00000024 00000000 DCD 0 ; Reserved + 70 00000028 00000000 DCD 0 ; Reserved + 71 0000002C 00000000 DCD SVC_Handler ; SVCall Handler + 72 00000030 00000000 DCD DebugMon_Handler ; Debug Monito + r Handler + 73 00000034 00000000 DCD 0 ; Reserved + 74 00000038 00000000 DCD PendSV_Handler ; PendSV Handler + + 75 0000003C 00000000 DCD SysTick_Handler + ; SysTick Handler + 76 00000040 ; External Interrupts + 77 00000040 00000000 DCD WWDG_IRQHandler + ; Window WatchDog + 78 00000044 00000000 DCD PVD_AVD_IRQHandler ; PVD/AVD th + rough EXTI Line det + ection Interrupt + 79 00000048 00000000 DCD RTC_IRQHandler ; RTC non-secure + interrupt + 80 0000004C 00000000 DCD RTC_S_IRQHandler ; RTC secure i + nterrupt + 81 00000050 00000000 DCD TAMP_IRQHandler ; Tamper non-se + cure interrupt + + + +ARM Macro Assembler Page 3 + + + 82 00000054 00000000 DCD RAMCFG_IRQHandler + ; RAMCFG global + 83 00000058 00000000 DCD FLASH_IRQHandler ; FLASH non-se + cure global interru + pt + 84 0000005C 00000000 DCD FLASH_S_IRQHandler ; FLASH secu + re global interrupt + + 85 00000060 00000000 DCD GTZC_IRQHandler ; Global TrustZ + one Controller inte + rrupt + 86 00000064 00000000 DCD RCC_IRQHandler ; RCC non-secure + global interrupt + 87 00000068 00000000 DCD RCC_S_IRQHandler ; RCC secure g + lobal interrupt + 88 0000006C 00000000 DCD EXTI0_IRQHandler ; EXTI Line0 i + nterrupt + 89 00000070 00000000 DCD EXTI1_IRQHandler ; EXTI Line1 i + nterrupt + 90 00000074 00000000 DCD EXTI2_IRQHandler ; EXTI Line2 i + nterrupt + 91 00000078 00000000 DCD EXTI3_IRQHandler ; EXTI Line3 i + nterrupt + 92 0000007C 00000000 DCD EXTI4_IRQHandler ; EXTI Line4 i + nterrupt + 93 00000080 00000000 DCD EXTI5_IRQHandler ; EXTI Line5 i + nterrupt + 94 00000084 00000000 DCD EXTI6_IRQHandler ; EXTI Line6 i + nterrupt + 95 00000088 00000000 DCD EXTI7_IRQHandler ; EXTI Line7 i + nterrupt + 96 0000008C 00000000 DCD EXTI8_IRQHandler ; EXTI Line8 i + nterrupt + 97 00000090 00000000 DCD EXTI9_IRQHandler ; EXTI Line9 i + nterrupt + 98 00000094 00000000 DCD EXTI10_IRQHandler ; EXTI Line10 + interrupt + 99 00000098 00000000 DCD EXTI11_IRQHandler ; EXTI Line11 + interrupt + 100 0000009C 00000000 DCD EXTI12_IRQHandler ; EXTI Line12 + interrupt + 101 000000A0 00000000 DCD EXTI13_IRQHandler ; EXTI Line13 + interrupt + 102 000000A4 00000000 DCD EXTI14_IRQHandler ; EXTI Line14 + interrupt + 103 000000A8 00000000 DCD EXTI15_IRQHandler ; EXTI Line15 + interrupt + 104 000000AC 00000000 DCD GPDMA1_Channel0_IRQHandler ; GP + DMA1 Channel 0 glob + al interrupt + 105 000000B0 00000000 DCD GPDMA1_Channel1_IRQHandler ; GP + DMA1 Channel 1 glob + al interrupt + 106 000000B4 00000000 DCD GPDMA1_Channel2_IRQHandler ; GP + DMA1 Channel 2 glob + al interrupt + 107 000000B8 00000000 DCD GPDMA1_Channel3_IRQHandler ; GP + DMA1 Channel 3 glob + al interrupt + + + +ARM Macro Assembler Page 4 + + + 108 000000BC 00000000 DCD GPDMA1_Channel4_IRQHandler ; GP + DMA1 Channel 4 glob + al interrupt + 109 000000C0 00000000 DCD GPDMA1_Channel5_IRQHandler ; GP + DMA1 Channel 5 glob + al interrupt + 110 000000C4 00000000 DCD GPDMA1_Channel6_IRQHandler ; GP + DMA1 Channel 6 glob + al interrupt + 111 000000C8 00000000 DCD GPDMA1_Channel7_IRQHandler ; GP + DMA1 Channel 7 glob + al interrupt + 112 000000CC 00000000 DCD IWDG_IRQHandler ; IWDG global i + nterrupt + 113 000000D0 00000000 DCD 0 ; Reserved + 114 000000D4 00000000 DCD ADC1_IRQHandler ; ADC1 global i + nterrupt + 115 000000D8 00000000 DCD DAC1_IRQHandler ; DAC1 global i + nterrupt + 116 000000DC 00000000 DCD FDCAN1_IT0_IRQHandler ; FDCAN1 + interrupt 0 + 117 000000E0 00000000 DCD FDCAN1_IT1_IRQHandler ; FDCAN1 + interrupt 1 + 118 000000E4 00000000 DCD TIM1_BRK_IRQHandler ; TIM1 Brea + k interrupt + 119 000000E8 00000000 DCD TIM1_UP_IRQHandler ; TIM1 Updat + e interrupt + 120 000000EC 00000000 DCD TIM1_TRG_COM_IRQHandler ; TIM1 + Trigger and Commuta + tion interrupt + 121 000000F0 00000000 DCD TIM1_CC_IRQHandler ; TIM1 Captu + re Compare interrup + t + 122 000000F4 00000000 DCD TIM2_IRQHandler ; TIM2 global i + nterrupt + 123 000000F8 00000000 DCD TIM3_IRQHandler ; TIM3 global i + nterrupt + 124 000000FC 00000000 DCD TIM4_IRQHandler ; TIM4 global i + nterrupt + 125 00000100 00000000 DCD TIM5_IRQHandler ; TIM5 global i + nterrupt + 126 00000104 00000000 DCD TIM6_IRQHandler ; TIM6 global i + nterrupt + 127 00000108 00000000 DCD TIM7_IRQHandler ; TIM7 global i + nterrupt + 128 0000010C 00000000 DCD I2C1_EV_IRQHandler ; I2C1 Event + interrupt + 129 00000110 00000000 DCD I2C1_ER_IRQHandler ; I2C1 Error + interrupt + 130 00000114 00000000 DCD I2C2_EV_IRQHandler ; I2C2 Event + interrupt + 131 00000118 00000000 DCD I2C2_ER_IRQHandler ; I2C2 Error + interrupt + 132 0000011C 00000000 DCD SPI1_IRQHandler ; SPI1 global i + nterrupt + 133 00000120 00000000 DCD SPI2_IRQHandler ; SPI2 global i + nterrupt + 134 00000124 00000000 DCD SPI3_IRQHandler ; SPI3 global i + nterrupt + + + +ARM Macro Assembler Page 5 + + + 135 00000128 00000000 DCD USART1_IRQHandler ; USART1 glob + al interrupt + 136 0000012C 00000000 DCD USART2_IRQHandler ; USART2 glob + al interrupt + 137 00000130 00000000 DCD USART3_IRQHandler ; USART3 glob + al interrupt + 138 00000134 00000000 DCD UART4_IRQHandler ; UART4 global + interrupt + 139 00000138 00000000 DCD UART5_IRQHandler ; UART5 global + interrupt + 140 0000013C 00000000 DCD LPUART1_IRQHandler ; LPUART1 gl + obal interrupt + 141 00000140 00000000 DCD LPTIM1_IRQHandler ; LPTIM1 glob + al interrupt + 142 00000144 00000000 DCD TIM8_BRK_IRQHandler ; TIM8 Brea + k interrupt + 143 00000148 00000000 DCD TIM8_UP_IRQHandler ; TIM8 Updat + e interrupt + 144 0000014C 00000000 DCD TIM8_TRG_COM_IRQHandler ; TIM8 + Trigger and Commuta + tion interrupt + 145 00000150 00000000 DCD TIM8_CC_IRQHandler ; TIM8 Captu + re Compare interrup + t + 146 00000154 00000000 DCD ADC2_IRQHandler ; ADC2 global i + nterrupt + 147 00000158 00000000 DCD LPTIM2_IRQHandler ; LPTIM2 glob + al interrupt + 148 0000015C 00000000 DCD TIM15_IRQHandler ; TIM15 global + interrupt + 149 00000160 00000000 DCD TIM16_IRQHandler ; TIM16 global + interrupt + 150 00000164 00000000 DCD TIM17_IRQHandler ; TIM17 global + interrupt + 151 00000168 00000000 DCD USB_DRD_FS_IRQHandler ; USB DRD + FS global interrup + t + 152 0000016C 00000000 DCD CRS_IRQHandler ; CRS global int + errupt + 153 00000170 00000000 DCD UCPD1_IRQHandler ; UCPD1 global + interrupt + 154 00000174 00000000 DCD FMC_IRQHandler ; FMC global int + errupt + 155 00000178 00000000 DCD OCTOSPI1_IRQHandler ; OctoSPI1 + global interrupt + 156 0000017C 00000000 DCD SDMMC1_IRQHandler ; SDMMC1 glob + al interrupt + 157 00000180 00000000 DCD I2C3_EV_IRQHandler ; I2C2 Event + interrupt + 158 00000184 00000000 DCD I2C3_ER_IRQHandler ; I2C2 Error + interrupt + 159 00000188 00000000 DCD SPI4_IRQHandler ; SPI4 global i + nterrupt + 160 0000018C 00000000 DCD SPI5_IRQHandler ; SPI5 global i + nterrupt + 161 00000190 00000000 DCD SPI6_IRQHandler ; SPI6 global i + nterrupt + 162 00000194 00000000 DCD USART6_IRQHandler ; USART6 glob + al interrupt + + + +ARM Macro Assembler Page 6 + + + 163 00000198 00000000 DCD USART10_IRQHandler ; USART10 gl + obal interrupt + 164 0000019C 00000000 DCD USART11_IRQHandler ; USART11 gl + obal interrupt + 165 000001A0 00000000 DCD SAI1_IRQHandler ; Serial Audio + Interface 1 global + interrupt + 166 000001A4 00000000 DCD SAI2_IRQHandler ; Serial Audio + Interface 2 global + interrupt + 167 000001A8 00000000 DCD GPDMA2_Channel0_IRQHandler ; GP + DMA2 Channel 0 glob + al interrupt + 168 000001AC 00000000 DCD GPDMA2_Channel1_IRQHandler ; GP + DMA2 Channel 1 glob + al interrupt + 169 000001B0 00000000 DCD GPDMA2_Channel2_IRQHandler ; GP + DMA2 Channel 2 glob + al interrupt + 170 000001B4 00000000 DCD GPDMA2_Channel3_IRQHandler ; GP + DMA2 Channel 3 glob + al interrupt + 171 000001B8 00000000 DCD GPDMA2_Channel4_IRQHandler ; GP + DMA2 Channel 4 glob + al interrupt + 172 000001BC 00000000 DCD GPDMA2_Channel5_IRQHandler ; GP + DMA2 Channel 5 glob + al interrupt + 173 000001C0 00000000 DCD GPDMA2_Channel6_IRQHandler ; GP + DMA2 Channel 6 glob + al interrupt + 174 000001C4 00000000 DCD GPDMA2_Channel7_IRQHandler ; GP + DMA2 Channel 7 glob + al interrupt + 175 000001C8 00000000 DCD UART7_IRQHandler ; UART7 global + interrupt + 176 000001CC 00000000 DCD UART8_IRQHandler ; UART8 global + interrupt + 177 000001D0 00000000 DCD UART9_IRQHandler ; UART9 global + interrupt + 178 000001D4 00000000 DCD UART12_IRQHandler ; UART12 glob + al interrupt + 179 000001D8 00000000 DCD SDMMC2_IRQHandler ; SDMMC2 glob + al interrupt + 180 000001DC 00000000 DCD FPU_IRQHandler ; FPU global int + errupt + 181 000001E0 00000000 DCD ICACHE_IRQHandler ; Instruction + cache global inter + rupt + 182 000001E4 00000000 DCD DCACHE1_IRQHandler ; DCACHE1 gl + obal interrupt + 183 000001E8 00000000 DCD ETH_IRQHandler ; Ethernet globa + l interrupt + 184 000001EC 00000000 DCD ETH_WKUP_IRQHandler ; Ethernet + Wakeup global inter + rupt + 185 000001F0 00000000 DCD DCMI_PSSI_IRQHandler ; DCMI PSS + I global interrupt + 186 000001F4 00000000 DCD FDCAN2_IT0_IRQHandler ; FDCAN2 + + + +ARM Macro Assembler Page 7 + + + interrupt 0 + 187 000001F8 00000000 DCD FDCAN2_IT1_IRQHandler ; FDCAN2 + interrupt 1 + 188 000001FC 00000000 DCD CORDIC_IRQHandler ; CORDIC glob + al interrupt + 189 00000200 00000000 DCD FMAC_IRQHandler ; FMAC global i + nterrupt + 190 00000204 00000000 DCD DTS_IRQHandler ; DTS global int + errupt + 191 00000208 00000000 DCD RNG_IRQHandler ; RNG global int + errupt + 192 0000020C 00000000 DCD 0 ; Reserved + 193 00000210 00000000 DCD 0 ; Reserved + 194 00000214 00000000 DCD HASH_IRQHandler ; HASH global i + nterrupt + 195 00000218 00000000 DCD 0 ; Reserved + 196 0000021C 00000000 DCD CEC_IRQHandler ; CEC global int + errupt + 197 00000220 00000000 DCD TIM12_IRQHandler ; TIM12 global + interrupt + 198 00000224 00000000 DCD TIM13_IRQHandler ; TIM13 global + interrupt + 199 00000228 00000000 DCD TIM14_IRQHandler ; TIM14 global + interrupt + 200 0000022C 00000000 DCD I3C1_EV_IRQHandler ; I3C1 Event + interrupt + 201 00000230 00000000 DCD I3C1_ER_IRQHandler ; I3C1 Error + interrupt + 202 00000234 00000000 DCD I2C4_EV_IRQHandler ; I2C4 Event + interrupt + 203 00000238 00000000 DCD I2C4_ER_IRQHandler ; I2C4 Error + interrupt + 204 0000023C 00000000 DCD LPTIM3_IRQHandler ; LPTIM3 glob + al interrupt + 205 00000240 00000000 DCD LPTIM4_IRQHandler ; LPTIM4 glob + al interrupt + 206 00000244 00000000 DCD LPTIM5_IRQHandler ; LPTIM5 glob + al interrupt + 207 00000248 00000000 DCD LPTIM6_IRQHandler ; LPTIM6 glob + al interrupt + 208 0000024C + 209 0000024C + 210 0000024C __Vectors_End + 211 0000024C + 212 0000024C 0000024C + __Vectors_Size + EQU __Vectors_End - __Vectors + 213 0000024C + 214 0000024C AREA |.text|, CODE, READONLY + 215 00000000 + 216 00000000 + 217 00000000 ; Reset Handler + 218 00000000 + 219 00000000 Reset_Handler + PROC + 220 00000000 EXPORT Reset_Handler [WEAK +] + 221 00000000 IMPORT SystemInit + 222 00000000 IMPORT __main + + + +ARM Macro Assembler Page 8 + + + 223 00000000 480A LDR R0, =SystemInit + 224 00000002 4780 BLX R0 + 225 00000004 480A LDR R0, =__main + 226 00000006 4700 BX R0 + 227 00000008 ENDP + 228 00000008 + 229 00000008 + 230 00000008 ; Dummy Exception Handlers (infinite loops which can be + modified) + 231 00000008 + 233 00000008 NMI_Handler + PROC + 234 00000008 EXPORT NMI_Handler [WEAK +] + 235 00000008 E7FE B . + 236 0000000A ENDP + 238 0000000A HardFault_Handler + PROC + 239 0000000A EXPORT HardFault_Handler [WEAK +] + 240 0000000A E7FE B . + 241 0000000C ENDP + 243 0000000C MemManage_Handler + PROC + 244 0000000C EXPORT MemManage_Handler [WEAK +] + 245 0000000C E7FE B . + 246 0000000E ENDP + 248 0000000E BusFault_Handler + PROC + 249 0000000E EXPORT BusFault_Handler [WEAK +] + 250 0000000E E7FE B . + 251 00000010 ENDP + 253 00000010 UsageFault_Handler + PROC + 254 00000010 EXPORT UsageFault_Handler [WEAK +] + 255 00000010 E7FE B . + 256 00000012 ENDP + 258 00000012 SecureFault_Handler + PROC + 259 00000012 EXPORT SecureFault_Handler [WEAK +] + 260 00000012 E7FE B . + 261 00000014 ENDP + 263 00000014 SVC_Handler + PROC + 264 00000014 EXPORT SVC_Handler [WEAK +] + 265 00000014 E7FE B . + 266 00000016 ENDP + 268 00000016 DebugMon_Handler + PROC + 269 00000016 EXPORT DebugMon_Handler [WEAK +] + 270 00000016 E7FE B . + 271 00000018 ENDP + 273 00000018 PendSV_Handler + + + +ARM Macro Assembler Page 9 + + + PROC + 274 00000018 EXPORT PendSV_Handler [WEAK +] + 275 00000018 E7FE B . + 276 0000001A ENDP + 278 0000001A SysTick_Handler + PROC + 279 0000001A EXPORT SysTick_Handler [WEAK +] + 280 0000001A E7FE B . + 281 0000001C ENDP + 282 0000001C + 283 0000001C Default_Handler + PROC + 284 0000001C + 285 0000001C EXPORT WWDG_IRQHandler + [WEAK] + 286 0000001C EXPORT PVD_AVD_IRQHandler + [WEAK] + 287 0000001C EXPORT RTC_IRQHandler + [WEAK] + 288 0000001C EXPORT RTC_S_IRQHandler + [WEAK] + 289 0000001C EXPORT TAMP_IRQHandler + [WEAK] + 290 0000001C EXPORT RAMCFG_IRQHandler + [WEAK] + 291 0000001C EXPORT FLASH_IRQHandler + [WEAK] + 292 0000001C EXPORT FLASH_S_IRQHandler + [WEAK] + 293 0000001C EXPORT GTZC_IRQHandler + [WEAK] + 294 0000001C EXPORT RCC_IRQHandler + [WEAK] + 295 0000001C EXPORT RCC_S_IRQHandler + [WEAK] + 296 0000001C EXPORT EXTI0_IRQHandler + [WEAK] + 297 0000001C EXPORT EXTI1_IRQHandler + [WEAK] + 298 0000001C EXPORT EXTI2_IRQHandler + [WEAK] + 299 0000001C EXPORT EXTI3_IRQHandler + [WEAK] + 300 0000001C EXPORT EXTI4_IRQHandler + [WEAK] + 301 0000001C EXPORT EXTI5_IRQHandler + [WEAK] + 302 0000001C EXPORT EXTI6_IRQHandler + [WEAK] + 303 0000001C EXPORT EXTI7_IRQHandler + [WEAK] + 304 0000001C EXPORT EXTI8_IRQHandler + [WEAK] + 305 0000001C EXPORT EXTI9_IRQHandler + [WEAK] + 306 0000001C EXPORT EXTI10_IRQHandler + [WEAK] + + + +ARM Macro Assembler Page 10 + + + 307 0000001C EXPORT EXTI11_IRQHandler + [WEAK] + 308 0000001C EXPORT EXTI12_IRQHandler + [WEAK] + 309 0000001C EXPORT EXTI13_IRQHandler + [WEAK] + 310 0000001C EXPORT EXTI14_IRQHandler + [WEAK] + 311 0000001C EXPORT EXTI15_IRQHandler + [WEAK] + 312 0000001C EXPORT GPDMA1_Channel0_IRQHandler + [WEAK] + 313 0000001C EXPORT GPDMA1_Channel1_IRQHandler + [WEAK] + 314 0000001C EXPORT GPDMA1_Channel2_IRQHandler + [WEAK] + 315 0000001C EXPORT GPDMA1_Channel3_IRQHandler + [WEAK] + 316 0000001C EXPORT GPDMA1_Channel4_IRQHandler + [WEAK] + 317 0000001C EXPORT GPDMA1_Channel5_IRQHandler + [WEAK] + 318 0000001C EXPORT GPDMA1_Channel6_IRQHandler + [WEAK] + 319 0000001C EXPORT GPDMA1_Channel7_IRQHandler + [WEAK] + 320 0000001C EXPORT IWDG_IRQHandler + [WEAK] + 321 0000001C EXPORT ADC1_IRQHandler + [WEAK] + 322 0000001C EXPORT DAC1_IRQHandler + [WEAK] + 323 0000001C EXPORT FDCAN1_IT0_IRQHandler + [WEAK] + 324 0000001C EXPORT FDCAN1_IT1_IRQHandler + [WEAK] + 325 0000001C EXPORT TIM1_BRK_IRQHandler + [WEAK] + 326 0000001C EXPORT TIM1_UP_IRQHandler + [WEAK] + 327 0000001C EXPORT TIM1_TRG_COM_IRQHandler + [WEAK] + 328 0000001C EXPORT TIM1_CC_IRQHandler + [WEAK] + 329 0000001C EXPORT TIM2_IRQHandler + [WEAK] + 330 0000001C EXPORT TIM3_IRQHandler + [WEAK] + 331 0000001C EXPORT TIM4_IRQHandler + [WEAK] + 332 0000001C EXPORT TIM5_IRQHandler + [WEAK] + 333 0000001C EXPORT TIM6_IRQHandler + [WEAK] + 334 0000001C EXPORT TIM7_IRQHandler + [WEAK] + 335 0000001C EXPORT I2C1_EV_IRQHandler + [WEAK] + 336 0000001C EXPORT I2C1_ER_IRQHandler + + + +ARM Macro Assembler Page 11 + + + [WEAK] + 337 0000001C EXPORT I2C2_EV_IRQHandler + [WEAK] + 338 0000001C EXPORT I2C2_ER_IRQHandler + [WEAK] + 339 0000001C EXPORT SPI1_IRQHandler + [WEAK] + 340 0000001C EXPORT SPI2_IRQHandler + [WEAK] + 341 0000001C EXPORT SPI3_IRQHandler + [WEAK] + 342 0000001C EXPORT USART1_IRQHandler + [WEAK] + 343 0000001C EXPORT USART2_IRQHandler + [WEAK] + 344 0000001C EXPORT USART3_IRQHandler + [WEAK] + 345 0000001C EXPORT UART4_IRQHandler + [WEAK] + 346 0000001C EXPORT UART5_IRQHandler + [WEAK] + 347 0000001C EXPORT LPUART1_IRQHandler + [WEAK] + 348 0000001C EXPORT LPTIM1_IRQHandler + [WEAK] + 349 0000001C EXPORT TIM8_BRK_IRQHandler + [WEAK] + 350 0000001C EXPORT TIM8_UP_IRQHandler + [WEAK] + 351 0000001C EXPORT TIM8_TRG_COM_IRQHandler + [WEAK] + 352 0000001C EXPORT TIM8_CC_IRQHandler + [WEAK] + 353 0000001C EXPORT ADC2_IRQHandler + [WEAK] + 354 0000001C EXPORT LPTIM2_IRQHandler + [WEAK] + 355 0000001C EXPORT TIM15_IRQHandler + [WEAK] + 356 0000001C EXPORT TIM16_IRQHandler + [WEAK] + 357 0000001C EXPORT TIM17_IRQHandler + [WEAK] + 358 0000001C EXPORT USB_DRD_FS_IRQHandler + [WEAK] + 359 0000001C EXPORT CRS_IRQHandler + [WEAK] + 360 0000001C EXPORT UCPD1_IRQHandler + [WEAK] + 361 0000001C EXPORT FMC_IRQHandler + [WEAK] + 362 0000001C EXPORT OCTOSPI1_IRQHandler + [WEAK] + 363 0000001C EXPORT SDMMC1_IRQHandler + [WEAK] + 364 0000001C EXPORT I2C3_EV_IRQHandler + [WEAK] + 365 0000001C EXPORT I2C3_ER_IRQHandler + [WEAK] + + + +ARM Macro Assembler Page 12 + + + 366 0000001C EXPORT SPI4_IRQHandler + [WEAK] + 367 0000001C EXPORT SPI5_IRQHandler + [WEAK] + 368 0000001C EXPORT SPI6_IRQHandler + [WEAK] + 369 0000001C EXPORT USART6_IRQHandler + [WEAK] + 370 0000001C EXPORT USART10_IRQHandler + [WEAK] + 371 0000001C EXPORT USART11_IRQHandler + [WEAK] + 372 0000001C EXPORT SAI1_IRQHandler + [WEAK] + 373 0000001C EXPORT SAI2_IRQHandler + [WEAK] + 374 0000001C EXPORT GPDMA2_Channel0_IRQHandler + [WEAK] + 375 0000001C EXPORT GPDMA2_Channel1_IRQHandler + [WEAK] + 376 0000001C EXPORT GPDMA2_Channel2_IRQHandler + [WEAK] + 377 0000001C EXPORT GPDMA2_Channel3_IRQHandler + [WEAK] + 378 0000001C EXPORT GPDMA2_Channel4_IRQHandler + [WEAK] + 379 0000001C EXPORT GPDMA2_Channel5_IRQHandler + [WEAK] + 380 0000001C EXPORT GPDMA2_Channel6_IRQHandler + [WEAK] + 381 0000001C EXPORT GPDMA2_Channel7_IRQHandler + [WEAK] + 382 0000001C EXPORT UART7_IRQHandler + [WEAK] + 383 0000001C EXPORT UART8_IRQHandler + [WEAK] + 384 0000001C EXPORT UART9_IRQHandler + [WEAK] + 385 0000001C EXPORT UART12_IRQHandler + [WEAK] + 386 0000001C EXPORT SDMMC2_IRQHandler + [WEAK] + 387 0000001C EXPORT FPU_IRQHandler + [WEAK] + 388 0000001C EXPORT ICACHE_IRQHandler + [WEAK] + 389 0000001C EXPORT DCACHE1_IRQHandler + [WEAK] + 390 0000001C EXPORT ETH_IRQHandler + [WEAK] + 391 0000001C EXPORT ETH_WKUP_IRQHandler + [WEAK] + 392 0000001C EXPORT DCMI_PSSI_IRQHandler + [WEAK] + 393 0000001C EXPORT FDCAN2_IT0_IRQHandler + [WEAK] + 394 0000001C EXPORT FDCAN2_IT1_IRQHandler + [WEAK] + 395 0000001C EXPORT CORDIC_IRQHandler + + + +ARM Macro Assembler Page 13 + + + [WEAK] + 396 0000001C EXPORT FMAC_IRQHandler + [WEAK] + 397 0000001C EXPORT DTS_IRQHandler + [WEAK] + 398 0000001C EXPORT RNG_IRQHandler + [WEAK] + 399 0000001C EXPORT HASH_IRQHandler + [WEAK] + 400 0000001C EXPORT CEC_IRQHandler + [WEAK] + 401 0000001C EXPORT TIM12_IRQHandler + [WEAK] + 402 0000001C EXPORT TIM13_IRQHandler + [WEAK] + 403 0000001C EXPORT TIM14_IRQHandler + [WEAK] + 404 0000001C EXPORT I3C1_EV_IRQHandler + [WEAK] + 405 0000001C EXPORT I3C1_ER_IRQHandler + [WEAK] + 406 0000001C EXPORT I2C4_EV_IRQHandler + [WEAK] + 407 0000001C EXPORT I2C4_ER_IRQHandler + [WEAK] + 408 0000001C EXPORT LPTIM3_IRQHandler + [WEAK] + 409 0000001C EXPORT LPTIM4_IRQHandler + [WEAK] + 410 0000001C EXPORT LPTIM5_IRQHandler + [WEAK] + 411 0000001C EXPORT LPTIM6_IRQHandler + [WEAK] + 412 0000001C + 413 0000001C WWDG_IRQHandler + 414 0000001C PVD_AVD_IRQHandler + 415 0000001C RTC_IRQHandler + 416 0000001C RTC_S_IRQHandler + 417 0000001C TAMP_IRQHandler + 418 0000001C RAMCFG_IRQHandler + 419 0000001C FLASH_IRQHandler + 420 0000001C FLASH_S_IRQHandler + 421 0000001C GTZC_IRQHandler + 422 0000001C RCC_IRQHandler + 423 0000001C RCC_S_IRQHandler + 424 0000001C EXTI0_IRQHandler + 425 0000001C EXTI1_IRQHandler + 426 0000001C EXTI2_IRQHandler + 427 0000001C EXTI3_IRQHandler + 428 0000001C EXTI4_IRQHandler + 429 0000001C EXTI5_IRQHandler + 430 0000001C EXTI6_IRQHandler + 431 0000001C EXTI7_IRQHandler + 432 0000001C EXTI8_IRQHandler + 433 0000001C EXTI9_IRQHandler + 434 0000001C EXTI10_IRQHandler + 435 0000001C EXTI11_IRQHandler + 436 0000001C EXTI12_IRQHandler + 437 0000001C EXTI13_IRQHandler + + + +ARM Macro Assembler Page 14 + + + 438 0000001C EXTI14_IRQHandler + 439 0000001C EXTI15_IRQHandler + 440 0000001C GPDMA1_Channel0_IRQHandler + 441 0000001C GPDMA1_Channel1_IRQHandler + 442 0000001C GPDMA1_Channel2_IRQHandler + 443 0000001C GPDMA1_Channel3_IRQHandler + 444 0000001C GPDMA1_Channel4_IRQHandler + 445 0000001C GPDMA1_Channel5_IRQHandler + 446 0000001C GPDMA1_Channel6_IRQHandler + 447 0000001C GPDMA1_Channel7_IRQHandler + 448 0000001C IWDG_IRQHandler + 449 0000001C ADC1_IRQHandler + 450 0000001C DAC1_IRQHandler + 451 0000001C FDCAN1_IT0_IRQHandler + 452 0000001C FDCAN1_IT1_IRQHandler + 453 0000001C TIM1_BRK_IRQHandler + 454 0000001C TIM1_UP_IRQHandler + 455 0000001C TIM1_TRG_COM_IRQHandler + 456 0000001C TIM1_CC_IRQHandler + 457 0000001C TIM2_IRQHandler + 458 0000001C TIM3_IRQHandler + 459 0000001C TIM4_IRQHandler + 460 0000001C TIM5_IRQHandler + 461 0000001C TIM6_IRQHandler + 462 0000001C TIM7_IRQHandler + 463 0000001C I2C1_EV_IRQHandler + 464 0000001C I2C1_ER_IRQHandler + 465 0000001C I2C2_EV_IRQHandler + 466 0000001C I2C2_ER_IRQHandler + 467 0000001C SPI1_IRQHandler + 468 0000001C SPI2_IRQHandler + 469 0000001C SPI3_IRQHandler + 470 0000001C USART1_IRQHandler + 471 0000001C USART2_IRQHandler + 472 0000001C USART3_IRQHandler + 473 0000001C UART4_IRQHandler + 474 0000001C UART5_IRQHandler + 475 0000001C LPUART1_IRQHandler + 476 0000001C LPTIM1_IRQHandler + 477 0000001C TIM8_BRK_IRQHandler + 478 0000001C TIM8_UP_IRQHandler + 479 0000001C TIM8_TRG_COM_IRQHandler + 480 0000001C TIM8_CC_IRQHandler + 481 0000001C ADC2_IRQHandler + 482 0000001C LPTIM2_IRQHandler + 483 0000001C TIM15_IRQHandler + 484 0000001C TIM16_IRQHandler + 485 0000001C TIM17_IRQHandler + 486 0000001C USB_DRD_FS_IRQHandler + 487 0000001C CRS_IRQHandler + 488 0000001C UCPD1_IRQHandler + 489 0000001C FMC_IRQHandler + 490 0000001C OCTOSPI1_IRQHandler + 491 0000001C SDMMC1_IRQHandler + 492 0000001C I2C3_EV_IRQHandler + 493 0000001C I2C3_ER_IRQHandler + 494 0000001C SPI4_IRQHandler + 495 0000001C SPI5_IRQHandler + 496 0000001C SPI6_IRQHandler + + + +ARM Macro Assembler Page 15 + + + 497 0000001C USART6_IRQHandler + 498 0000001C USART10_IRQHandler + 499 0000001C USART11_IRQHandler + 500 0000001C SAI1_IRQHandler + 501 0000001C SAI2_IRQHandler + 502 0000001C GPDMA2_Channel0_IRQHandler + 503 0000001C GPDMA2_Channel1_IRQHandler + 504 0000001C GPDMA2_Channel2_IRQHandler + 505 0000001C GPDMA2_Channel3_IRQHandler + 506 0000001C GPDMA2_Channel4_IRQHandler + 507 0000001C GPDMA2_Channel5_IRQHandler + 508 0000001C GPDMA2_Channel6_IRQHandler + 509 0000001C GPDMA2_Channel7_IRQHandler + 510 0000001C UART7_IRQHandler + 511 0000001C UART8_IRQHandler + 512 0000001C UART9_IRQHandler + 513 0000001C UART12_IRQHandler + 514 0000001C SDMMC2_IRQHandler + 515 0000001C FPU_IRQHandler + 516 0000001C ICACHE_IRQHandler + 517 0000001C DCACHE1_IRQHandler + 518 0000001C ETH_IRQHandler + 519 0000001C ETH_WKUP_IRQHandler + 520 0000001C DCMI_PSSI_IRQHandler + 521 0000001C FDCAN2_IT0_IRQHandler + 522 0000001C FDCAN2_IT1_IRQHandler + 523 0000001C CORDIC_IRQHandler + 524 0000001C FMAC_IRQHandler + 525 0000001C DTS_IRQHandler + 526 0000001C RNG_IRQHandler + 527 0000001C HASH_IRQHandler + 528 0000001C CEC_IRQHandler + 529 0000001C TIM12_IRQHandler + 530 0000001C TIM13_IRQHandler + 531 0000001C TIM14_IRQHandler + 532 0000001C I3C1_EV_IRQHandler + 533 0000001C I3C1_ER_IRQHandler + 534 0000001C I2C4_EV_IRQHandler + 535 0000001C I2C4_ER_IRQHandler + 536 0000001C LPTIM3_IRQHandler + 537 0000001C LPTIM4_IRQHandler + 538 0000001C LPTIM5_IRQHandler + 539 0000001C LPTIM6_IRQHandler + 540 0000001C + 541 0000001C E7FE B . + 542 0000001E + 543 0000001E ENDP + 544 0000001E + 545 0000001E 00 00 ALIGN + 546 00000020 + 547 00000020 ;******************************************************* + ************************ + 548 00000020 ; User Stack and Heap initialization + 549 00000020 ;******************************************************* + ************************ + 550 00000020 IF :DEF:__MICROLIB + 557 00000020 + 558 00000020 IMPORT __use_two_region_memory + 559 00000020 EXPORT __user_initial_stackheap + + + +ARM Macro Assembler Page 16 + + + 560 00000020 + 561 00000020 __user_initial_stackheap + PROC + 562 00000020 4804 LDR R0, = Heap_Mem + 563 00000022 4905 LDR R1, =(Stack_Mem + Stack_Size) + 564 00000024 4A05 LDR R2, = (Heap_Mem + Heap_Size) + 565 00000026 4B06 LDR R3, = Stack_Mem + 566 00000028 4770 BX LR + 567 0000002A ENDP + 568 0000002A + 569 0000002A 00 00 ALIGN + 570 0000002C + 571 0000002C ENDIF + 572 0000002C + 573 0000002C END + 00000000 + 00000000 + 00000000 + 00000400 + 00000200 + 00000000 +Command Line: --debug --xref --diag_suppress=9931 --cpu=Cortex-M33 --fpu=FPv5-S +P --depend=.\build\keil\obj\startup_stm32h563xx.d -o.\build\keil\obj\startup_st +m32h563xx.o -ID:\1_tool_prog\2_MDK\pack\Keil\STM32H5xx_DFP\1.1.0\Drivers\CMSIS\ +Device\ST\STM32H5xx\Include --predefine="__UVISION_VERSION SETA 536" --predefin +e="STM32H563xx SETA 1" --list=startup_stm32h563xx.lst ..\libraries\stm32h5xx_HA +L\CMSIS\Device\ST\stm32h5xx\Source\Templates\arm\startup_stm32h563xx.s + + + +ARM Macro Assembler Page 1 Alphabetic symbol ordering +Relocatable symbols + +STACK 00000000 + +Symbol: STACK + Definitions + At line 34 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + Uses + None +Comment: STACK unused +Stack_Mem 00000000 + +Symbol: Stack_Mem + Definitions + At line 35 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + Uses + At line 563 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 565 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +__initial_sp 00000400 + +Symbol: __initial_sp + Definitions + At line 36 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + Uses + At line 60 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s +Comment: __initial_sp used once +3 symbols + + + +ARM Macro Assembler Page 1 Alphabetic symbol ordering +Relocatable symbols + +HEAP 00000000 + +Symbol: HEAP + Definitions + At line 45 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + Uses + None +Comment: HEAP unused +Heap_Mem 00000000 + +Symbol: Heap_Mem + Definitions + At line 47 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + Uses + At line 562 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 564 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +__heap_base 00000000 + +Symbol: __heap_base + Definitions + At line 46 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + Uses + None +Comment: __heap_base unused +__heap_limit 00000200 + +Symbol: __heap_limit + Definitions + At line 48 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + Uses + None +Comment: __heap_limit unused +4 symbols + + + +ARM Macro Assembler Page 1 Alphabetic symbol ordering +Relocatable symbols + +RESET 00000000 + +Symbol: RESET + Definitions + At line 55 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + Uses + None +Comment: RESET unused +__Vectors 00000000 + +Symbol: __Vectors + Definitions + At line 60 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + Uses + At line 56 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 212 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +__Vectors_End 0000024C + +Symbol: __Vectors_End + Definitions + At line 210 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 57 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 212 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +3 symbols + + + +ARM Macro Assembler Page 1 Alphabetic symbol ordering +Relocatable symbols + +.text 00000000 + +Symbol: .text + Definitions + At line 214 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + None +Comment: .text unused +ADC1_IRQHandler 0000001C + +Symbol: ADC1_IRQHandler + Definitions + At line 449 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 114 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 321 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +ADC2_IRQHandler 0000001C + +Symbol: ADC2_IRQHandler + Definitions + At line 481 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 146 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 353 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +BusFault_Handler 0000000E + +Symbol: BusFault_Handler + Definitions + At line 248 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 65 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 249 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +CEC_IRQHandler 0000001C + +Symbol: CEC_IRQHandler + Definitions + At line 528 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 196 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 400 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +CORDIC_IRQHandler 0000001C + + + + +ARM Macro Assembler Page 2 Alphabetic symbol ordering +Relocatable symbols + +Symbol: CORDIC_IRQHandler + Definitions + At line 523 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 188 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 395 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +CRS_IRQHandler 0000001C + +Symbol: CRS_IRQHandler + Definitions + At line 487 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 152 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 359 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +DAC1_IRQHandler 0000001C + +Symbol: DAC1_IRQHandler + Definitions + At line 450 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 115 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 322 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +DCACHE1_IRQHandler 0000001C + +Symbol: DCACHE1_IRQHandler + Definitions + At line 517 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 182 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 389 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +DCMI_PSSI_IRQHandler 0000001C + +Symbol: DCMI_PSSI_IRQHandler + Definitions + At line 520 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 185 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 392 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +DTS_IRQHandler 0000001C + + + +ARM Macro Assembler Page 3 Alphabetic symbol ordering +Relocatable symbols + + +Symbol: DTS_IRQHandler + Definitions + At line 525 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 190 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 397 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +DebugMon_Handler 00000016 + +Symbol: DebugMon_Handler + Definitions + At line 268 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 72 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 269 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +Default_Handler 0000001C + +Symbol: Default_Handler + Definitions + At line 283 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + None +Comment: Default_Handler unused +ETH_IRQHandler 0000001C + +Symbol: ETH_IRQHandler + Definitions + At line 518 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 183 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 390 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +ETH_WKUP_IRQHandler 0000001C + +Symbol: ETH_WKUP_IRQHandler + Definitions + At line 519 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 184 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 391 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +EXTI0_IRQHandler 0000001C + +Symbol: EXTI0_IRQHandler + + + +ARM Macro Assembler Page 4 Alphabetic symbol ordering +Relocatable symbols + + Definitions + At line 424 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 88 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 296 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +EXTI10_IRQHandler 0000001C + +Symbol: EXTI10_IRQHandler + Definitions + At line 434 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 98 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 306 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +EXTI11_IRQHandler 0000001C + +Symbol: EXTI11_IRQHandler + Definitions + At line 435 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 99 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 307 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +EXTI12_IRQHandler 0000001C + +Symbol: EXTI12_IRQHandler + Definitions + At line 436 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 100 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 308 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +EXTI13_IRQHandler 0000001C + +Symbol: EXTI13_IRQHandler + Definitions + At line 437 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 101 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 309 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +EXTI14_IRQHandler 0000001C + + + + +ARM Macro Assembler Page 5 Alphabetic symbol ordering +Relocatable symbols + +Symbol: EXTI14_IRQHandler + Definitions + At line 438 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 102 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 310 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +EXTI15_IRQHandler 0000001C + +Symbol: EXTI15_IRQHandler + Definitions + At line 439 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 103 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 311 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +EXTI1_IRQHandler 0000001C + +Symbol: EXTI1_IRQHandler + Definitions + At line 425 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 89 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 297 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +EXTI2_IRQHandler 0000001C + +Symbol: EXTI2_IRQHandler + Definitions + At line 426 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 90 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 298 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +EXTI3_IRQHandler 0000001C + +Symbol: EXTI3_IRQHandler + Definitions + At line 427 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 91 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 299 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +EXTI4_IRQHandler 0000001C + + + +ARM Macro Assembler Page 6 Alphabetic symbol ordering +Relocatable symbols + + +Symbol: EXTI4_IRQHandler + Definitions + At line 428 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 92 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 300 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +EXTI5_IRQHandler 0000001C + +Symbol: EXTI5_IRQHandler + Definitions + At line 429 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 93 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 301 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +EXTI6_IRQHandler 0000001C + +Symbol: EXTI6_IRQHandler + Definitions + At line 430 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 94 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 302 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +EXTI7_IRQHandler 0000001C + +Symbol: EXTI7_IRQHandler + Definitions + At line 431 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 95 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 303 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +EXTI8_IRQHandler 0000001C + +Symbol: EXTI8_IRQHandler + Definitions + At line 432 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 96 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 304 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + + + + +ARM Macro Assembler Page 7 Alphabetic symbol ordering +Relocatable symbols + +EXTI9_IRQHandler 0000001C + +Symbol: EXTI9_IRQHandler + Definitions + At line 433 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 97 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 305 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +FDCAN1_IT0_IRQHandler 0000001C + +Symbol: FDCAN1_IT0_IRQHandler + Definitions + At line 451 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 116 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 323 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +FDCAN1_IT1_IRQHandler 0000001C + +Symbol: FDCAN1_IT1_IRQHandler + Definitions + At line 452 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 117 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 324 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +FDCAN2_IT0_IRQHandler 0000001C + +Symbol: FDCAN2_IT0_IRQHandler + Definitions + At line 521 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 186 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 393 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +FDCAN2_IT1_IRQHandler 0000001C + +Symbol: FDCAN2_IT1_IRQHandler + Definitions + At line 522 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 187 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 394 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + + + +ARM Macro Assembler Page 8 Alphabetic symbol ordering +Relocatable symbols + + +FLASH_IRQHandler 0000001C + +Symbol: FLASH_IRQHandler + Definitions + At line 419 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 83 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 291 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +FLASH_S_IRQHandler 0000001C + +Symbol: FLASH_S_IRQHandler + Definitions + At line 420 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 84 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 292 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +FMAC_IRQHandler 0000001C + +Symbol: FMAC_IRQHandler + Definitions + At line 524 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 189 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 396 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +FMC_IRQHandler 0000001C + +Symbol: FMC_IRQHandler + Definitions + At line 489 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 154 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 361 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +FPU_IRQHandler 0000001C + +Symbol: FPU_IRQHandler + Definitions + At line 515 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 180 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 387 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ + + + +ARM Macro Assembler Page 9 Alphabetic symbol ordering +Relocatable symbols + +Source\Templates\arm\startup_stm32h563xx.s + +GPDMA1_Channel0_IRQHandler 0000001C + +Symbol: GPDMA1_Channel0_IRQHandler + Definitions + At line 440 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 104 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 312 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +GPDMA1_Channel1_IRQHandler 0000001C + +Symbol: GPDMA1_Channel1_IRQHandler + Definitions + At line 441 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 105 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 313 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +GPDMA1_Channel2_IRQHandler 0000001C + +Symbol: GPDMA1_Channel2_IRQHandler + Definitions + At line 442 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 106 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 314 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +GPDMA1_Channel3_IRQHandler 0000001C + +Symbol: GPDMA1_Channel3_IRQHandler + Definitions + At line 443 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 107 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 315 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +GPDMA1_Channel4_IRQHandler 0000001C + +Symbol: GPDMA1_Channel4_IRQHandler + Definitions + At line 444 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 108 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + + + +ARM Macro Assembler Page 10 Alphabetic symbol ordering +Relocatable symbols + + At line 316 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +GPDMA1_Channel5_IRQHandler 0000001C + +Symbol: GPDMA1_Channel5_IRQHandler + Definitions + At line 445 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 109 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 317 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +GPDMA1_Channel6_IRQHandler 0000001C + +Symbol: GPDMA1_Channel6_IRQHandler + Definitions + At line 446 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 110 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 318 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +GPDMA1_Channel7_IRQHandler 0000001C + +Symbol: GPDMA1_Channel7_IRQHandler + Definitions + At line 447 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 111 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 319 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +GPDMA2_Channel0_IRQHandler 0000001C + +Symbol: GPDMA2_Channel0_IRQHandler + Definitions + At line 502 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 167 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 374 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +GPDMA2_Channel1_IRQHandler 0000001C + +Symbol: GPDMA2_Channel1_IRQHandler + Definitions + At line 503 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 168 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ + + + +ARM Macro Assembler Page 11 Alphabetic symbol ordering +Relocatable symbols + +Source\Templates\arm\startup_stm32h563xx.s + At line 375 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +GPDMA2_Channel2_IRQHandler 0000001C + +Symbol: GPDMA2_Channel2_IRQHandler + Definitions + At line 504 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 169 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 376 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +GPDMA2_Channel3_IRQHandler 0000001C + +Symbol: GPDMA2_Channel3_IRQHandler + Definitions + At line 505 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 170 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 377 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +GPDMA2_Channel4_IRQHandler 0000001C + +Symbol: GPDMA2_Channel4_IRQHandler + Definitions + At line 506 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 171 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 378 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +GPDMA2_Channel5_IRQHandler 0000001C + +Symbol: GPDMA2_Channel5_IRQHandler + Definitions + At line 507 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 172 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 379 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +GPDMA2_Channel6_IRQHandler 0000001C + +Symbol: GPDMA2_Channel6_IRQHandler + Definitions + At line 508 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + + + +ARM Macro Assembler Page 12 Alphabetic symbol ordering +Relocatable symbols + + At line 173 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 380 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +GPDMA2_Channel7_IRQHandler 0000001C + +Symbol: GPDMA2_Channel7_IRQHandler + Definitions + At line 509 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 174 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 381 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +GTZC_IRQHandler 0000001C + +Symbol: GTZC_IRQHandler + Definitions + At line 421 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 85 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 293 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +HASH_IRQHandler 0000001C + +Symbol: HASH_IRQHandler + Definitions + At line 527 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 194 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 399 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +HardFault_Handler 0000000A + +Symbol: HardFault_Handler + Definitions + At line 238 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 63 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 239 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +I2C1_ER_IRQHandler 0000001C + +Symbol: I2C1_ER_IRQHandler + Definitions + At line 464 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + + + +ARM Macro Assembler Page 13 Alphabetic symbol ordering +Relocatable symbols + + Uses + At line 129 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 336 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +I2C1_EV_IRQHandler 0000001C + +Symbol: I2C1_EV_IRQHandler + Definitions + At line 463 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 128 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 335 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +I2C2_ER_IRQHandler 0000001C + +Symbol: I2C2_ER_IRQHandler + Definitions + At line 466 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 131 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 338 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +I2C2_EV_IRQHandler 0000001C + +Symbol: I2C2_EV_IRQHandler + Definitions + At line 465 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 130 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 337 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +I2C3_ER_IRQHandler 0000001C + +Symbol: I2C3_ER_IRQHandler + Definitions + At line 493 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 158 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 365 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +I2C3_EV_IRQHandler 0000001C + +Symbol: I2C3_EV_IRQHandler + Definitions + At line 492 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ + + + +ARM Macro Assembler Page 14 Alphabetic symbol ordering +Relocatable symbols + +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 157 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 364 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +I2C4_ER_IRQHandler 0000001C + +Symbol: I2C4_ER_IRQHandler + Definitions + At line 535 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 203 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 407 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +I2C4_EV_IRQHandler 0000001C + +Symbol: I2C4_EV_IRQHandler + Definitions + At line 534 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 202 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 406 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +I3C1_ER_IRQHandler 0000001C + +Symbol: I3C1_ER_IRQHandler + Definitions + At line 533 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 201 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 405 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +I3C1_EV_IRQHandler 0000001C + +Symbol: I3C1_EV_IRQHandler + Definitions + At line 532 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 200 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 404 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +ICACHE_IRQHandler 0000001C + +Symbol: ICACHE_IRQHandler + Definitions + + + +ARM Macro Assembler Page 15 Alphabetic symbol ordering +Relocatable symbols + + At line 516 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 181 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 388 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +IWDG_IRQHandler 0000001C + +Symbol: IWDG_IRQHandler + Definitions + At line 448 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 112 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 320 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +LPTIM1_IRQHandler 0000001C + +Symbol: LPTIM1_IRQHandler + Definitions + At line 476 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 141 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 348 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +LPTIM2_IRQHandler 0000001C + +Symbol: LPTIM2_IRQHandler + Definitions + At line 482 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 147 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 354 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +LPTIM3_IRQHandler 0000001C + +Symbol: LPTIM3_IRQHandler + Definitions + At line 536 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 204 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 408 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +LPTIM4_IRQHandler 0000001C + +Symbol: LPTIM4_IRQHandler + + + +ARM Macro Assembler Page 16 Alphabetic symbol ordering +Relocatable symbols + + Definitions + At line 537 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 205 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 409 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +LPTIM5_IRQHandler 0000001C + +Symbol: LPTIM5_IRQHandler + Definitions + At line 538 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 206 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 410 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +LPTIM6_IRQHandler 0000001C + +Symbol: LPTIM6_IRQHandler + Definitions + At line 539 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 207 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 411 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +LPUART1_IRQHandler 0000001C + +Symbol: LPUART1_IRQHandler + Definitions + At line 475 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 140 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 347 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +MemManage_Handler 0000000C + +Symbol: MemManage_Handler + Definitions + At line 243 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 64 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 244 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +NMI_Handler 00000008 + + + + +ARM Macro Assembler Page 17 Alphabetic symbol ordering +Relocatable symbols + +Symbol: NMI_Handler + Definitions + At line 233 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 62 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 234 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +OCTOSPI1_IRQHandler 0000001C + +Symbol: OCTOSPI1_IRQHandler + Definitions + At line 490 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 155 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 362 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +PVD_AVD_IRQHandler 0000001C + +Symbol: PVD_AVD_IRQHandler + Definitions + At line 414 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 78 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 286 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +PendSV_Handler 00000018 + +Symbol: PendSV_Handler + Definitions + At line 273 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 74 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 274 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +RAMCFG_IRQHandler 0000001C + +Symbol: RAMCFG_IRQHandler + Definitions + At line 418 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 82 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 290 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +RCC_IRQHandler 0000001C + + + +ARM Macro Assembler Page 18 Alphabetic symbol ordering +Relocatable symbols + + +Symbol: RCC_IRQHandler + Definitions + At line 422 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 86 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 294 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +RCC_S_IRQHandler 0000001C + +Symbol: RCC_S_IRQHandler + Definitions + At line 423 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 87 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 295 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +RNG_IRQHandler 0000001C + +Symbol: RNG_IRQHandler + Definitions + At line 526 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 191 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 398 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +RTC_IRQHandler 0000001C + +Symbol: RTC_IRQHandler + Definitions + At line 415 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 79 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 287 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +RTC_S_IRQHandler 0000001C + +Symbol: RTC_S_IRQHandler + Definitions + At line 416 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 80 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 288 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + + + + +ARM Macro Assembler Page 19 Alphabetic symbol ordering +Relocatable symbols + +Reset_Handler 00000000 + +Symbol: Reset_Handler + Definitions + At line 219 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 61 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 220 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +SAI1_IRQHandler 0000001C + +Symbol: SAI1_IRQHandler + Definitions + At line 500 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 165 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 372 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +SAI2_IRQHandler 0000001C + +Symbol: SAI2_IRQHandler + Definitions + At line 501 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 166 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 373 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +SDMMC1_IRQHandler 0000001C + +Symbol: SDMMC1_IRQHandler + Definitions + At line 491 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 156 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 363 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +SDMMC2_IRQHandler 0000001C + +Symbol: SDMMC2_IRQHandler + Definitions + At line 514 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 179 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 386 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + + + +ARM Macro Assembler Page 20 Alphabetic symbol ordering +Relocatable symbols + + +SPI1_IRQHandler 0000001C + +Symbol: SPI1_IRQHandler + Definitions + At line 467 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 132 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 339 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +SPI2_IRQHandler 0000001C + +Symbol: SPI2_IRQHandler + Definitions + At line 468 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 133 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 340 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +SPI3_IRQHandler 0000001C + +Symbol: SPI3_IRQHandler + Definitions + At line 469 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 134 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 341 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +SPI4_IRQHandler 0000001C + +Symbol: SPI4_IRQHandler + Definitions + At line 494 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 159 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 366 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +SPI5_IRQHandler 0000001C + +Symbol: SPI5_IRQHandler + Definitions + At line 495 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 160 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 367 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ + + + +ARM Macro Assembler Page 21 Alphabetic symbol ordering +Relocatable symbols + +Source\Templates\arm\startup_stm32h563xx.s + +SPI6_IRQHandler 0000001C + +Symbol: SPI6_IRQHandler + Definitions + At line 496 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 161 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 368 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +SVC_Handler 00000014 + +Symbol: SVC_Handler + Definitions + At line 263 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 71 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 264 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +SecureFault_Handler 00000012 + +Symbol: SecureFault_Handler + Definitions + At line 258 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 67 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 259 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +SysTick_Handler 0000001A + +Symbol: SysTick_Handler + Definitions + At line 278 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 75 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 279 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +TAMP_IRQHandler 0000001C + +Symbol: TAMP_IRQHandler + Definitions + At line 417 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 81 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + + + +ARM Macro Assembler Page 22 Alphabetic symbol ordering +Relocatable symbols + + At line 289 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +TIM12_IRQHandler 0000001C + +Symbol: TIM12_IRQHandler + Definitions + At line 529 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 197 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 401 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +TIM13_IRQHandler 0000001C + +Symbol: TIM13_IRQHandler + Definitions + At line 530 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 198 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 402 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +TIM14_IRQHandler 0000001C + +Symbol: TIM14_IRQHandler + Definitions + At line 531 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 199 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 403 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +TIM15_IRQHandler 0000001C + +Symbol: TIM15_IRQHandler + Definitions + At line 483 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 148 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 355 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +TIM16_IRQHandler 0000001C + +Symbol: TIM16_IRQHandler + Definitions + At line 484 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 149 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ + + + +ARM Macro Assembler Page 23 Alphabetic symbol ordering +Relocatable symbols + +Source\Templates\arm\startup_stm32h563xx.s + At line 356 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +TIM17_IRQHandler 0000001C + +Symbol: TIM17_IRQHandler + Definitions + At line 485 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 150 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 357 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +TIM1_BRK_IRQHandler 0000001C + +Symbol: TIM1_BRK_IRQHandler + Definitions + At line 453 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 118 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 325 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +TIM1_CC_IRQHandler 0000001C + +Symbol: TIM1_CC_IRQHandler + Definitions + At line 456 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 121 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 328 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +TIM1_TRG_COM_IRQHandler 0000001C + +Symbol: TIM1_TRG_COM_IRQHandler + Definitions + At line 455 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 120 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 327 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +TIM1_UP_IRQHandler 0000001C + +Symbol: TIM1_UP_IRQHandler + Definitions + At line 454 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + + + +ARM Macro Assembler Page 24 Alphabetic symbol ordering +Relocatable symbols + + At line 119 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 326 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +TIM2_IRQHandler 0000001C + +Symbol: TIM2_IRQHandler + Definitions + At line 457 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 122 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 329 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +TIM3_IRQHandler 0000001C + +Symbol: TIM3_IRQHandler + Definitions + At line 458 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 123 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 330 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +TIM4_IRQHandler 0000001C + +Symbol: TIM4_IRQHandler + Definitions + At line 459 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 124 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 331 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +TIM5_IRQHandler 0000001C + +Symbol: TIM5_IRQHandler + Definitions + At line 460 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 125 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 332 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +TIM6_IRQHandler 0000001C + +Symbol: TIM6_IRQHandler + Definitions + At line 461 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + + + +ARM Macro Assembler Page 25 Alphabetic symbol ordering +Relocatable symbols + + Uses + At line 126 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 333 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +TIM7_IRQHandler 0000001C + +Symbol: TIM7_IRQHandler + Definitions + At line 462 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 127 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 334 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +TIM8_BRK_IRQHandler 0000001C + +Symbol: TIM8_BRK_IRQHandler + Definitions + At line 477 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 142 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 349 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +TIM8_CC_IRQHandler 0000001C + +Symbol: TIM8_CC_IRQHandler + Definitions + At line 480 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 145 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 352 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +TIM8_TRG_COM_IRQHandler 0000001C + +Symbol: TIM8_TRG_COM_IRQHandler + Definitions + At line 479 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 144 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 351 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +TIM8_UP_IRQHandler 0000001C + +Symbol: TIM8_UP_IRQHandler + Definitions + At line 478 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ + + + +ARM Macro Assembler Page 26 Alphabetic symbol ordering +Relocatable symbols + +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 143 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 350 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +UART12_IRQHandler 0000001C + +Symbol: UART12_IRQHandler + Definitions + At line 513 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 178 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 385 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +UART4_IRQHandler 0000001C + +Symbol: UART4_IRQHandler + Definitions + At line 473 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 138 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 345 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +UART5_IRQHandler 0000001C + +Symbol: UART5_IRQHandler + Definitions + At line 474 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 139 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 346 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +UART7_IRQHandler 0000001C + +Symbol: UART7_IRQHandler + Definitions + At line 510 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 175 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 382 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +UART8_IRQHandler 0000001C + +Symbol: UART8_IRQHandler + Definitions + + + +ARM Macro Assembler Page 27 Alphabetic symbol ordering +Relocatable symbols + + At line 511 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 176 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 383 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +UART9_IRQHandler 0000001C + +Symbol: UART9_IRQHandler + Definitions + At line 512 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 177 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 384 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +UCPD1_IRQHandler 0000001C + +Symbol: UCPD1_IRQHandler + Definitions + At line 488 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 153 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 360 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +USART10_IRQHandler 0000001C + +Symbol: USART10_IRQHandler + Definitions + At line 498 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 163 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 370 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +USART11_IRQHandler 0000001C + +Symbol: USART11_IRQHandler + Definitions + At line 499 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 164 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 371 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +USART1_IRQHandler 0000001C + +Symbol: USART1_IRQHandler + + + +ARM Macro Assembler Page 28 Alphabetic symbol ordering +Relocatable symbols + + Definitions + At line 470 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 135 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 342 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +USART2_IRQHandler 0000001C + +Symbol: USART2_IRQHandler + Definitions + At line 471 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 136 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 343 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +USART3_IRQHandler 0000001C + +Symbol: USART3_IRQHandler + Definitions + At line 472 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 137 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 344 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +USART6_IRQHandler 0000001C + +Symbol: USART6_IRQHandler + Definitions + At line 497 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 162 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 369 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +USB_DRD_FS_IRQHandler 0000001C + +Symbol: USB_DRD_FS_IRQHandler + Definitions + At line 486 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 151 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + At line 358 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +UsageFault_Handler 00000010 + + + + +ARM Macro Assembler Page 29 Alphabetic symbol ordering +Relocatable symbols + +Symbol: UsageFault_Handler + Definitions + At line 253 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 66 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 254 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +WWDG_IRQHandler 0000001C + +Symbol: WWDG_IRQHandler + Definitions + At line 413 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 77 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 285 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +__user_initial_stackheap 00000020 + +Symbol: __user_initial_stackheap + Definitions + At line 561 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 559 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s +Comment: __user_initial_stackheap used once +141 symbols + + + +ARM Macro Assembler Page 1 Alphabetic symbol ordering +Absolute symbols + +Heap_Size 00000200 + +Symbol: Heap_Size + Definitions + At line 43 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + Uses + At line 47 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 564 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +Stack_Size 00000400 + +Symbol: Stack_Size + Definitions + At line 32 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + Uses + At line 35 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s + At line 563 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + +__Vectors_Size 0000024C + +Symbol: __Vectors_Size + Definitions + At line 212 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 58 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\S +ource\Templates\arm\startup_stm32h563xx.s +Comment: __Vectors_Size used once +3 symbols + + + +ARM Macro Assembler Page 1 Alphabetic symbol ordering +External symbols + +SystemInit 00000000 + +Symbol: SystemInit + Definitions + At line 221 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 223 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s +Comment: SystemInit used once +__main 00000000 + +Symbol: __main + Definitions + At line 222 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + At line 225 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s +Comment: __main used once +__use_two_region_memory 00000000 + +Symbol: __use_two_region_memory + Definitions + At line 558 in file ..\libraries\stm32h5xx_HAL\CMSIS\Device\ST\stm32h5xx\ +Source\Templates\arm\startup_stm32h563xx.s + Uses + None +Comment: __use_two_region_memory unused +3 symbols +494 symbols in table diff --git a/bsp/stm32/stm32h563-st-nucleo/syscall_rvds.lst b/bsp/stm32/stm32h563-st-nucleo/syscall_rvds.lst new file mode 100644 index 0000000000..920ceefcd8 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/syscall_rvds.lst @@ -0,0 +1,177 @@ + + + +ARM Macro Assembler Page 1 + + + 1 00000000 ;/* + 2 00000000 ; * Copyright (c) 2006-2022, RT-Thread Development Team + 3 00000000 ; * + 4 00000000 ; * SPDX-License-Identifier: Apache-2.0 + 5 00000000 ; * + 6 00000000 ; * Change Logs: + 7 00000000 ; * Date Author Notes + 8 00000000 ; * 2019-10-25 tyx first version + 9 00000000 ; */ + 10 00000000 + 11 00000000 AREA |.text|, CODE, READONLY, ALIGN= +2 + 12 00000000 THUMB + 13 00000000 REQUIRE8 + 14 00000000 PRESERVE8 + 15 00000000 + 16 00000000 IMPORT rt_secure_svc_handle + 17 00000000 + 18 00000000 ;/* + 19 00000000 ; * int tzcall(int id, rt_ubase_t arg0, rt_ubase_t arg1, + rt_ubase_t arg2); + 20 00000000 ; */ + 21 00000000 tzcall PROC + 22 00000000 EXPORT tzcall + 23 00000000 DF01 SVC 1 ;call SVC 1 + 24 00000002 4770 BX LR + 25 00000004 + 26 00000004 ENDP + 27 00000004 + 28 00000004 tzcall_entry + PROC + 29 00000004 B512 PUSH {R1, R4, LR} + 30 00000006 460C MOV R4, R1 ; copy thread SP to + R4 + 31 00000008 CC0F LDMFD R4!, {r0 - r3} ; pop user stack + , get input arg0, a + rg1, arg2 + 32 0000000A E924 000F STMFD R4!, {r0 - r3} ; push stack, us + er stack recovery + 33 0000000E F7FF FFFE BL rt_secure_svc_handle ; call fun + + 34 00000012 E8BD 4012 POP {R1, R4, LR} + 35 00000016 6008 STR R0, [R1] ; update return val + ue + 36 00000018 4770 BX LR ; return to thread + 37 0000001A + 38 0000001A ENDP + 39 0000001A + 40 0000001A syscall_entry + PROC + 41 0000001A 4770 BX LR ; return to user ap + p + 42 0000001C + 43 0000001C ENDP + 44 0000001C + 45 0000001C ;/* + 46 0000001C ; * void SVC_Handler(void); + 47 0000001C ; */ + 48 0000001C SVC_Handler + + + +ARM Macro Assembler Page 2 + + + PROC + 49 0000001C EXPORT SVC_Handler + 50 0000001C + 51 0000001C ; get SP, save to R1 + 52 0000001C F3EF 8108 MRS R1, MSP ;get fault context + from handler + 53 00000020 F01E 0F04 TST LR, #0x04 ;if(!EXC_RETURN[2]) + + 54 00000024 D001 BEQ get_sp_done + 55 00000026 F3EF 8109 MRS R1, PSP ;get fault context + from thread + 56 0000002A get_sp_done + 57 0000002A + 58 0000002A ; get svc index + 59 0000002A 6988 LDR R0, [R1, #24] + 60 0000002C F810 0C02 LDRB R0, [R0, #-2] + 61 00000030 + 62 00000030 ;if svc == 0, do system call + 63 00000030 2800 CMP R0, #0x0 + 64 00000032 D0FE BEQ syscall_entry + 65 00000034 + 66 00000034 ;if svc == 1, do TrustZone call + 67 00000034 2801 CMP R0, #0x1 + 68 00000036 D0FE BEQ tzcall_entry + 69 00000038 + 70 00000038 ENDP + 71 00000038 + 72 00000038 ALIGN + 73 00000038 + 74 00000038 END +Command Line: --debug --xref --diag_suppress=9931 --cpu=Cortex-M33 --fpu=FPv5-S +P --depend=.\build\keil\obj\syscall_rvds.d -o.\build\keil\obj\syscall_rvds.o -I +D:\1_tool_prog\2_MDK\pack\Keil\STM32H5xx_DFP\1.1.0\Drivers\CMSIS\Device\ST\STM3 +2H5xx\Include --predefine="__UVISION_VERSION SETA 536" --predefine="STM32H563xx + SETA 1" --list=syscall_rvds.lst ..\..\..\libcpu\arm\cortex-m33\syscall_rvds.S + + + +ARM Macro Assembler Page 1 Alphabetic symbol ordering +Relocatable symbols + +.text 00000000 + +Symbol: .text + Definitions + At line 11 in file ..\..\..\libcpu\arm\cortex-m33\syscall_rvds.S + Uses + None +Comment: .text unused +SVC_Handler 0000001C + +Symbol: SVC_Handler + Definitions + At line 48 in file ..\..\..\libcpu\arm\cortex-m33\syscall_rvds.S + Uses + At line 49 in file ..\..\..\libcpu\arm\cortex-m33\syscall_rvds.S +Comment: SVC_Handler used once +get_sp_done 0000002A + +Symbol: get_sp_done + Definitions + At line 56 in file ..\..\..\libcpu\arm\cortex-m33\syscall_rvds.S + Uses + At line 54 in file ..\..\..\libcpu\arm\cortex-m33\syscall_rvds.S +Comment: get_sp_done used once +syscall_entry 0000001A + +Symbol: syscall_entry + Definitions + At line 40 in file ..\..\..\libcpu\arm\cortex-m33\syscall_rvds.S + Uses + At line 64 in file ..\..\..\libcpu\arm\cortex-m33\syscall_rvds.S +Comment: syscall_entry used once +tzcall 00000000 + +Symbol: tzcall + Definitions + At line 21 in file ..\..\..\libcpu\arm\cortex-m33\syscall_rvds.S + Uses + At line 22 in file ..\..\..\libcpu\arm\cortex-m33\syscall_rvds.S +Comment: tzcall used once +tzcall_entry 00000004 + +Symbol: tzcall_entry + Definitions + At line 28 in file ..\..\..\libcpu\arm\cortex-m33\syscall_rvds.S + Uses + At line 68 in file ..\..\..\libcpu\arm\cortex-m33\syscall_rvds.S +Comment: tzcall_entry used once +6 symbols + + + +ARM Macro Assembler Page 1 Alphabetic symbol ordering +External symbols + +rt_secure_svc_handle 00000000 + +Symbol: rt_secure_svc_handle + Definitions + At line 16 in file ..\..\..\libcpu\arm\cortex-m33\syscall_rvds.S + Uses + At line 33 in file ..\..\..\libcpu\arm\cortex-m33\syscall_rvds.S +Comment: rt_secure_svc_handle used once +1 symbol +340 symbols in table diff --git a/bsp/stm32/stm32h563-st-nucleo/template.ewp b/bsp/stm32/stm32h563-st-nucleo/template.ewp new file mode 100644 index 0000000000..d8f8a59a6e --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/template.ewp @@ -0,0 +1,2106 @@ + + + 3 + + rt-thread + + ARM + + 1 + + General + 3 + + 31 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 35 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 10 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 23 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Release + + ARM + + 0 + + General + 3 + + 31 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 35 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 10 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 23 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + BILINK + 0 + + + + diff --git a/bsp/stm32/stm32h563-st-nucleo/template.eww b/bsp/stm32/stm32h563-st-nucleo/template.eww new file mode 100644 index 0000000000..bd036bb4c9 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/template.eww @@ -0,0 +1,10 @@ + + + + + $WS_DIR$\template.ewp + + + + + diff --git a/bsp/stm32/stm32h563-st-nucleo/template.uvoptx b/bsp/stm32/stm32h563-st-nucleo/template.uvoptx new file mode 100644 index 0000000000..44f0ad4de5 --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/template.uvoptx @@ -0,0 +1,192 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc; *.md + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + rtthread + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 6 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.dll + + + + 0 + UL2V8M + UL2V8M(-S0 -C0 -P0 -FD20000000 -FC8000 -FN2 -FF0STM32H5xx_2M_0800 -FS08000000 -FL0200000 -FF1STM32H5xx_2M_0C00 -FS1C000000 -FL1200000 -FP0($$Device:STM32H563ZITx$CMSIS\Flash\STM32H5xx_2M_0800.FLM) -FP1($$Device:STM32H563ZITx$CMSIS\Flash\STM32H5xx_2M_0C00.FLM)) + + + 0 + ST-LINKIII-KEIL_SWO + -U001300334D46501220383832 -O2254 -SF10000 -C0 -A1 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(6BA02477) -L00(0) -TO131090 -TC10000000 -TT10000000 -TP21 -TDS8000 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0STM32H5xx_2M_0800 -FS08000000 -FL0200000 -FP0($$Device:STM32H563ZITx$CMSIS\Flash\STM32H5xx_2M_0800.FLM) + + + + + 0 + + + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 0 + 0 + 2 + 10000000 + + + + + + Source Group 1 + 0 + 0 + 0 + 0 + + +
diff --git a/bsp/stm32/stm32h563-st-nucleo/template.uvprojx b/bsp/stm32/stm32h563-st-nucleo/template.uvprojx new file mode 100644 index 0000000000..f6efb05cef --- /dev/null +++ b/bsp/stm32/stm32h563-st-nucleo/template.uvprojx @@ -0,0 +1,406 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + rtthread + 0x4 + ARM-ADS + 6140000::V6.14::ARMCLANG + 1 + + + STM32H563ZITx + STMicroelectronics + Keil.STM32H5xx_DFP.1.1.0 + https://www.keil.com/pack/ + IRAM(0x20000000,0x00050000) IRAM2(0x20050000,0x00050000) IROM(0x08000000,0x00200000) CPUTYPE("Cortex-M33") FPU3(SFPU) DSP TZ CLOCK(12000000) ELITTLE + + + UL2V8M(-S0 -C0 -P0 -FD20000000 -FC8000 -FN2 -FF0STM32H5xx_2M_0800 -FS08000000 -FL0200000 -FF1STM32H5xx_2M_0C00 -FS1C000000 -FL1200000 -FP0($$Device:STM32H563ZITx$CMSIS\Flash\STM32H5xx_2M_0800.FLM) -FP1($$Device:STM32H563ZITx$CMSIS\Flash\STM32H5xx_2M_0C00.FLM)) + 0 + $$Device:STM32H563ZITx$Drivers\CMSIS\Device\ST\STM32H5xx\Include\stm32h5xx.h + + + + + + + + + + $$Device:STM32H563ZITx$CMSIS\SVD\STM32H563.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\build\keil\Obj\ + rtthread + 1 + 0 + 0 + 1 + 0 + + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin !L --output rtthread.bin + + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 0 + + + + + + + SARMV8M.DLL + -MPU + TCM.DLL + -pCM33 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4102 + + 1 + BIN\UL2V8M.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M33" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 0 + 0 + 1 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 4 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x50000 + + + 1 + 0x8000000 + 0x200000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x200000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x50000 + + + 0 + 0x20050000 + 0x50000 + + + + + + 1 + 7 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 0 + 0 + 0 + 0 + 3 + 3 + 1 + 1 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 4 + + + + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x08000000 + 0x20000000 + + .\board\linker_scripts\link.sct + + + + + + + + + + + Source Group 1 + + + + + + + + + + + + + + + <Project Info> + 0 + 1 + + + + +
diff --git a/bsp/stm32/stm32u575-st-nucleo/.config b/bsp/stm32/stm32u575-st-nucleo/.config index ffcd1e31f8..4136d387dd 100644 --- a/bsp/stm32/stm32u575-st-nucleo/.config +++ b/bsp/stm32/stm32u575-st-nucleo/.config @@ -9,6 +9,7 @@ CONFIG_RT_NAME_MAX=8 # CONFIG_RT_USING_ARCH_DATA_TYPE is not set # CONFIG_RT_USING_SMART is not set +# CONFIG_RT_USING_AMP is not set # CONFIG_RT_USING_SMP is not set CONFIG_RT_ALIGN_SIZE=8 # CONFIG_RT_THREAD_PRIORITY_8 is not set @@ -33,18 +34,10 @@ CONFIG_RT_TIMER_THREAD_STACK_SIZE=512 # CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set # CONFIG_RT_USING_TINY_FFS is not set # CONFIG_RT_KPRINTF_USING_LONGLONG is not set -CONFIG_RT_DEBUG=y -CONFIG_RT_DEBUG_COLOR=y -# CONFIG_RT_DEBUG_INIT_CONFIG is not set -# CONFIG_RT_DEBUG_THREAD_CONFIG is not set -# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set -# CONFIG_RT_DEBUG_IPC_CONFIG is not set -# CONFIG_RT_DEBUG_TIMER_CONFIG is not set -# CONFIG_RT_DEBUG_IRQ_CONFIG is not set -# CONFIG_RT_DEBUG_MEM_CONFIG is not set -# CONFIG_RT_DEBUG_SLAB_CONFIG is not set -# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set -# CONFIG_RT_DEBUG_MODULE_CONFIG is not set +CONFIG_RT_USING_DEBUG=y +CONFIG_RT_DEBUGING_COLOR=y +CONFIG_RT_DEBUGING_CONTEXT=y +CONFIG_RT_DEBUGING_INIT=y # # Inter-Thread communication @@ -54,12 +47,12 @@ CONFIG_RT_USING_MUTEX=y CONFIG_RT_USING_EVENT=y CONFIG_RT_USING_MAILBOX=y CONFIG_RT_USING_MESSAGEQUEUE=y +# CONFIG_RT_USING_MESSAGEQUEUE_PRIORITY is not set # CONFIG_RT_USING_SIGNALS is not set # # Memory Management # -CONFIG_RT_PAGE_MAX_ORDER=11 CONFIG_RT_USING_MEMPOOL=y CONFIG_RT_USING_SMALL_MEM=y # CONFIG_RT_USING_SLAB is not set @@ -187,7 +180,19 @@ CONFIG_RT_USING_SPI=y # # C/C++ and POSIX layer # -CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 + +# +# ISO-ANSI C layer +# + +# +# Timezone and Daylight Saving Time +# +# CONFIG_RT_LIBC_USING_FULL_TZ_DST is not set +CONFIG_RT_LIBC_USING_LIGHT_TZ_DST=y +CONFIG_RT_LIBC_TZ_DEFAULT_HOUR=8 +CONFIG_RT_LIBC_TZ_DEFAULT_MIN=0 +CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0 # # POSIX (Portable Operating System Interface) layer @@ -226,9 +231,11 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_RT_USING_ULOG is not set # CONFIG_RT_USING_UTEST is not set # CONFIG_RT_USING_VAR_EXPORT is not set +# CONFIG_RT_USING_RESOURCE_ID is not set # CONFIG_RT_USING_ADT is not set # CONFIG_RT_USING_RT_LINK is not set # CONFIG_RT_USING_VBUS is not set +# CONFIG_RT_USING_KTIME is not set # # RT-Thread Utestcases @@ -321,8 +328,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_AGILE_FTP is not set # CONFIG_PKG_USING_EMBEDDEDPROTO is not set # CONFIG_PKG_USING_RT_LINK_HW is not set -# CONFIG_PKG_USING_RYANMQTT is not set -# CONFIG_PKG_USING_RYANW5500 is not set # CONFIG_PKG_USING_LORA_PKT_FWD is not set # CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set # CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set @@ -330,8 +335,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_SMALL_MODBUS is not set # CONFIG_PKG_USING_NET_SERVER is not set # CONFIG_PKG_USING_ZFTP is not set -# CONFIG_PKG_USING_WOL is not set -# CONFIG_PKG_USING_ZEPHYR_POLLING is not set # # security packages @@ -400,12 +403,17 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_MP3PLAYER is not set # CONFIG_PKG_USING_TINYJPEG is not set # CONFIG_PKG_USING_UGUI is not set + +# +# PainterEngine: A cross-platform graphics application framework written in C language +# +# CONFIG_PKG_USING_PAINTERENGINE is not set +# CONFIG_PKG_USING_PAINTERENGINE_AUX is not set # CONFIG_PKG_USING_MCURSES is not set # CONFIG_PKG_USING_TERMBOX is not set # CONFIG_PKG_USING_VT100 is not set # CONFIG_PKG_USING_QRCODE is not set # CONFIG_PKG_USING_GUIENGINE is not set -# CONFIG_PKG_USING_3GPP_AMRNB is not set # # tools packages @@ -415,9 +423,9 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_EASYLOGGER is not set # CONFIG_PKG_USING_SYSTEMVIEW is not set # CONFIG_PKG_USING_SEGGER_RTT is not set -# CONFIG_PKG_USING_RTT_AUTO_EXE_CMD is not set # CONFIG_PKG_USING_RDB is not set # CONFIG_PKG_USING_ULOG_EASYFLASH is not set +# CONFIG_PKG_USING_ULOG_FILE is not set # CONFIG_PKG_USING_LOGMGR is not set # CONFIG_PKG_USING_ADBD is not set # CONFIG_PKG_USING_COREMARK is not set @@ -451,8 +459,8 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_CBOX is not set # CONFIG_PKG_USING_SNOWFLAKE is not set # CONFIG_PKG_USING_HASH_MATCH is not set +# CONFIG_PKG_USING_FIRE_PID_CURVE is not set # CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set -# CONFIG_PKG_USING_VOFA_PLUS is not set # # system packages @@ -488,7 +496,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_UC_CLK is not set # CONFIG_PKG_USING_UC_COMMON is not set # CONFIG_PKG_USING_UC_MODBUS is not set -# CONFIG_PKG_USING_FREERTOS_WRAPPER is not set +# CONFIG_PKG_USING_RTDUINO is not set # CONFIG_PKG_USING_CAIRO is not set # CONFIG_PKG_USING_PIXMAN is not set # CONFIG_PKG_USING_PARTITION is not set @@ -522,95 +530,19 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_KMULTI_RTIMER is not set # CONFIG_PKG_USING_TFDB is not set # CONFIG_PKG_USING_QPC is not set -# CONFIG_PKG_USING_AGILE_UPGRADE is not set -# CONFIG_PKG_USING_FLASH_BLOB is not set # # peripheral libraries and drivers # - -# -# sensors drivers -# -# CONFIG_PKG_USING_LSM6DSM is not set -# CONFIG_PKG_USING_LSM6DSL is not set -# CONFIG_PKG_USING_LPS22HB is not set -# CONFIG_PKG_USING_HTS221 is not set -# CONFIG_PKG_USING_LSM303AGR is not set -# CONFIG_PKG_USING_BME280 is not set -# CONFIG_PKG_USING_BME680 is not set -# CONFIG_PKG_USING_BMA400 is not set -# CONFIG_PKG_USING_BMI160_BMX160 is not set -# CONFIG_PKG_USING_SPL0601 is not set -# CONFIG_PKG_USING_MS5805 is not set -# CONFIG_PKG_USING_DA270 is not set -# CONFIG_PKG_USING_DF220 is not set -# CONFIG_PKG_USING_HSHCAL001 is not set -# CONFIG_PKG_USING_BH1750 is not set -# CONFIG_PKG_USING_MPU6XXX is not set -# CONFIG_PKG_USING_AHT10 is not set -# CONFIG_PKG_USING_AP3216C is not set -# CONFIG_PKG_USING_TSL4531 is not set -# CONFIG_PKG_USING_DS18B20 is not set -# CONFIG_PKG_USING_DHT11 is not set -# CONFIG_PKG_USING_DHTXX is not set -# CONFIG_PKG_USING_GY271 is not set -# CONFIG_PKG_USING_GP2Y10 is not set -# CONFIG_PKG_USING_SGP30 is not set -# CONFIG_PKG_USING_HDC1000 is not set -# CONFIG_PKG_USING_BMP180 is not set -# CONFIG_PKG_USING_BMP280 is not set -# CONFIG_PKG_USING_SHTC1 is not set -# CONFIG_PKG_USING_BMI088 is not set -# CONFIG_PKG_USING_HMC5883 is not set -# CONFIG_PKG_USING_MAX6675 is not set -# CONFIG_PKG_USING_TMP1075 is not set -# CONFIG_PKG_USING_SR04 is not set -# CONFIG_PKG_USING_CCS811 is not set -# CONFIG_PKG_USING_PMSXX is not set -# CONFIG_PKG_USING_RT3020 is not set -# CONFIG_PKG_USING_MLX90632 is not set -# CONFIG_PKG_USING_MLX90393 is not set -# CONFIG_PKG_USING_MLX90392 is not set -# CONFIG_PKG_USING_MLX90397 is not set -# CONFIG_PKG_USING_MS5611 is not set -# CONFIG_PKG_USING_MAX31865 is not set -# CONFIG_PKG_USING_VL53L0X is not set -# CONFIG_PKG_USING_INA260 is not set -# CONFIG_PKG_USING_MAX30102 is not set -# CONFIG_PKG_USING_INA226 is not set -# CONFIG_PKG_USING_LIS2DH12 is not set -# CONFIG_PKG_USING_HS300X is not set -# CONFIG_PKG_USING_ZMOD4410 is not set -# CONFIG_PKG_USING_ISL29035 is not set -# CONFIG_PKG_USING_MMC3680KJ is not set -# CONFIG_PKG_USING_QMP6989 is not set -# CONFIG_PKG_USING_BALANCE is not set +# CONFIG_PKG_USING_SENSORS_DRIVERS is not set +# CONFIG_PKG_USING_REALTEK_AMEBA is not set # CONFIG_PKG_USING_SHT2X is not set # CONFIG_PKG_USING_SHT3X is not set -# CONFIG_PKG_USING_AD7746 is not set # CONFIG_PKG_USING_ADT74XX is not set -# CONFIG_PKG_USING_MAX17048 is not set # CONFIG_PKG_USING_AS7341 is not set -# CONFIG_PKG_USING_CW2015 is not set -# CONFIG_PKG_USING_ICM20608 is not set -# CONFIG_PKG_USING_PAJ7620 is not set -# CONFIG_PKG_USING_STHS34PF80 is not set - -# -# touch drivers -# -# CONFIG_PKG_USING_GT9147 is not set -# CONFIG_PKG_USING_GT1151 is not set -# CONFIG_PKG_USING_GT917S is not set -# CONFIG_PKG_USING_GT911 is not set -# CONFIG_PKG_USING_FT6206 is not set -# CONFIG_PKG_USING_FT5426 is not set -# CONFIG_PKG_USING_FT6236 is not set -# CONFIG_PKG_USING_XPT2046_TOUCH is not set -# CONFIG_PKG_USING_REALTEK_AMEBA is not set # CONFIG_PKG_USING_STM32_SDIO is not set -# CONFIG_PKG_USING_ESP_IDF is not set +# CONFIG_PKG_USING_RTT_ESP_IDF is not set +# CONFIG_PKG_USING_ICM20608 is not set # CONFIG_PKG_USING_BUTTON is not set # CONFIG_PKG_USING_PCF8574 is not set # CONFIG_PKG_USING_SX12XX is not set @@ -620,11 +552,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_LKDGUI is not set # CONFIG_PKG_USING_NRF5X_SDK is not set # CONFIG_PKG_USING_NRFX is not set - -# -# Kendryte SDK -# -# CONFIG_PKG_USING_K210_SDK is not set +# CONFIG_PKG_USING_WM_LIBRARIES is not set # CONFIG_PKG_USING_KENDRYTE_SDK is not set # CONFIG_PKG_USING_INFRARED is not set # CONFIG_PKG_USING_MULTI_INFRARED is not set @@ -632,10 +560,12 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_AGILE_LED is not set # CONFIG_PKG_USING_AT24CXX is not set # CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set +# CONFIG_PKG_USING_AD7746 is not set # CONFIG_PKG_USING_PCA9685 is not set -# CONFIG_PKG_USING_ILI9341 is not set # CONFIG_PKG_USING_I2C_TOOLS is not set # CONFIG_PKG_USING_NRF24L01 is not set +# CONFIG_PKG_USING_TOUCH_DRIVERS is not set +# CONFIG_PKG_USING_MAX17048 is not set # CONFIG_PKG_USING_RPLIDAR is not set # CONFIG_PKG_USING_AS608 is not set # CONFIG_PKG_USING_RC522 is not set @@ -650,6 +580,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_CAN_YMODEM is not set # CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set # CONFIG_PKG_USING_QLED is not set +# CONFIG_PKG_USING_PAJ7620 is not set # CONFIG_PKG_USING_AGILE_CONSOLE is not set # CONFIG_PKG_USING_LD3320 is not set # CONFIG_PKG_USING_WK2124 is not set @@ -680,11 +611,9 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_BL_MCU_SDK is not set # CONFIG_PKG_USING_SOFT_SERIAL is not set # CONFIG_PKG_USING_MB85RS16 is not set +# CONFIG_PKG_USING_CW2015 is not set # CONFIG_PKG_USING_RFM300 is not set # CONFIG_PKG_USING_IO_INPUT_FILTER is not set -# CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set -# CONFIG_PKG_USING_LRF_NV7LIDAR is not set -# CONFIG_PKG_USING_FINGERPRINT is not set # # AI packages @@ -699,12 +628,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_QUEST is not set # CONFIG_PKG_USING_NAXOS is not set -# -# Signal Processing and Control Algorithm Packages -# -# CONFIG_PKG_USING_FIRE_PID_CURVE is not set -# CONFIG_PKG_USING_UKAL is not set - # # miscellaneous packages # @@ -734,7 +657,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_TETRIS is not set # CONFIG_PKG_USING_DONUT is not set # CONFIG_PKG_USING_COWSAY is not set -# CONFIG_PKG_USING_MORSE is not set # CONFIG_PKG_USING_LIBCSV is not set # CONFIG_PKG_USING_OPTPARSE is not set # CONFIG_PKG_USING_FASTLZ is not set @@ -757,6 +679,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_VI is not set # CONFIG_PKG_USING_KI is not set # CONFIG_PKG_USING_ARMv7M_DWT is not set +# CONFIG_PKG_USING_UKAL is not set # CONFIG_PKG_USING_CRCLIB is not set # CONFIG_PKG_USING_LWGPS is not set # CONFIG_PKG_USING_STATE_MACHINE is not set @@ -766,222 +689,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_MFBD is not set # CONFIG_PKG_USING_SLCAN2RTT is not set # CONFIG_PKG_USING_SOEM is not set -# CONFIG_PKG_USING_QPARAM is not set -# CONFIG_PKG_USING_CorevMCU_CLI is not set -# CONFIG_PKG_USING_GET_IRQ_PRIORITY is not set - -# -# Arduino libraries -# -# CONFIG_PKG_USING_RTDUINO is not set - -# -# Projects -# -# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set -# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set -# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set - -# -# Sensors -# -# CONFIG_PKG_USING_ARDUINO_SENSOR_DEVICE_DRIVERS is not set -# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L1X is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL6180X is not set -# CONFIG_PKG_USING_ADAFRUIT_MAX31855 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31856 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX6675 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90614 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS1 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AHTX0 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS0 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP280 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADT7410 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME680 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9808 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4728 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA219 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR390 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL345 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DHT is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9600 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM6DS is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO055 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX1704X is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMC56X3 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90393 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90395 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ICM20X is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DPS310 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTS221 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT4X is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT31 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL343 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME280 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS726X is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AMG88XX is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2320 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2315 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR329_LTR303 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085_UNIFIED is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183_UNIFIED is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP3XX is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MS8607 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3MDL is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90640 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMA8451 is not set -# CONFIG_PKG_USING_ADAFRUIT_MSA301 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL115A2 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X_RVC is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS2MDL is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303DLH_MAG is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LC709203F is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CAP1188 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CCS811 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_NAU7802 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS331 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS2X is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS35HW is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303_ACCEL is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3DH is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8591 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL3115A2 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPR121 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPRLS is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPU6050 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCT2075 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PM25AQI is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_EMC2101 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXAS21002C is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SCD30 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXOS8700 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HMC5883_UNIFIED is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP30 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP006 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TLA202X is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCS34725 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI7021 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI1145 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP40 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHTC3 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HDC1000 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSORLAB is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP117 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSC2007 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2561 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2591_LIBRARY is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VCNL4040 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL335 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL345 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_BME280 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_H3LIS331DL is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_MMA7660 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_TSL2561 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_PAJ7620 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_VL53L0X is not set -# CONFIG_PKG_USING_SEEED_ITG3200 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_SHT31 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_HP20X is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_DRV2605L is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_BBM150 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_HMC5883L is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_LSM303DLH is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_TCS3414CS is not set -# CONFIG_PKG_USING_SEEED_MP503 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_BMP085 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_HIGHTEMP is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_VEML6070 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_SI1145 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_SHT35 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_AT42QT1070 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_LSM6DS3 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_HDC1000 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_HM3301 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_MCP9600 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_LTC2941 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_LDC1612 is not set - -# -# Display -# -# CONFIG_PKG_USING_ARDUINO_U8G2 is not set -# CONFIG_PKG_USING_ARDUINO_U8GLIB_ARDUINO is not set -# CONFIG_PKG_USING_SEEED_TM1637 is not set - -# -# Timing -# -# CONFIG_PKG_USING_ARDUINO_MSTIMER2 is not set - -# -# Data Processing -# -# CONFIG_PKG_USING_ARDUINO_KALMANFILTER is not set -# CONFIG_PKG_USING_ARDUINO_ARDUINOJSON is not set - -# -# Data Storage -# - -# -# Communication -# -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PN532 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI4713 is not set - -# -# Device Control -# -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set -# CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TPA2016 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DRV2605 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS1841 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS3502 is not set - -# -# Other -# -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MFRC630 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI5351 is not set -# CONFIG_PKG_USING_ARDUINO_RTCLIB is not set - -# -# Signal IO -# -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BUSIO is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCA8418 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP23017 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADS1X15 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AW9523 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP3008 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4725 is not set -# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BD3491FS is not set - -# -# Uncategorized -# CONFIG_SOC_FAMILY_STM32=y CONFIG_SOC_SERIES_STM32U5=y diff --git a/bsp/stm32/stm32u575-st-nucleo/project.uvoptx b/bsp/stm32/stm32u575-st-nucleo/project.uvoptx index 5c1ff1426b..87711a8dfb 100644 --- a/bsp/stm32/stm32u575-st-nucleo/project.uvoptx +++ b/bsp/stm32/stm32u575-st-nucleo/project.uvoptx @@ -182,1135 +182,11 @@ - Applications - 1 - 0 - 0 - 0 - - 1 - 1 - 1 - 0 - 0 - 0 - applications\main.c - main.c - 0 - 0 - - - - - Compiler + Source Group 1 0 0 0 0 - - 2 - 2 - 1 - 0 - 0 - 0 - ..\..\..\components\libc\compilers\armlibc\syscall_mem.c - syscall_mem.c - 0 - 0 - - - 2 - 3 - 1 - 0 - 0 - 0 - ..\..\..\components\libc\compilers\armlibc\syscalls.c - syscalls.c - 0 - 0 - - - 2 - 4 - 1 - 0 - 0 - 0 - ..\..\..\components\libc\compilers\common\cctype.c - cctype.c - 0 - 0 - - - 2 - 5 - 1 - 0 - 0 - 0 - ..\..\..\components\libc\compilers\common\cstdio.c - cstdio.c - 0 - 0 - - - 2 - 6 - 1 - 0 - 0 - 0 - ..\..\..\components\libc\compilers\common\cstdlib.c - cstdlib.c - 0 - 0 - - - 2 - 7 - 1 - 0 - 0 - 0 - ..\..\..\components\libc\compilers\common\cstring.c - cstring.c - 0 - 0 - - - 2 - 8 - 1 - 0 - 0 - 0 - ..\..\..\components\libc\compilers\common\ctime.c - ctime.c - 0 - 0 - - - 2 - 9 - 1 - 0 - 0 - 0 - ..\..\..\components\libc\compilers\common\cwchar.c - cwchar.c - 0 - 0 - - - - - CPU - 0 - 0 - 0 - 0 - - 3 - 10 - 1 - 0 - 0 - 0 - ..\..\..\libcpu\arm\common\atomic_arm.c - atomic_arm.c - 0 - 0 - - - 3 - 11 - 1 - 0 - 0 - 0 - ..\..\..\libcpu\arm\common\div0.c - div0.c - 0 - 0 - - - 3 - 12 - 1 - 0 - 0 - 0 - ..\..\..\libcpu\arm\common\showmem.c - showmem.c - 0 - 0 - - - 3 - 13 - 2 - 0 - 0 - 0 - ..\..\..\libcpu\arm\cortex-m33\context_rvds.S - context_rvds.S - 0 - 0 - - - 3 - 14 - 1 - 0 - 0 - 0 - ..\..\..\libcpu\arm\cortex-m33\cpuport.c - cpuport.c - 0 - 0 - - - 3 - 15 - 2 - 0 - 0 - 0 - ..\..\..\libcpu\arm\cortex-m33\syscall_rvds.S - syscall_rvds.S - 0 - 0 - - - 3 - 16 - 1 - 0 - 0 - 0 - ..\..\..\libcpu\arm\cortex-m33\trustzone.c - trustzone.c - 0 - 0 - - - - - DeviceDrivers - 0 - 0 - 0 - 0 - - 4 - 17 - 1 - 0 - 0 - 0 - ..\..\..\components\drivers\i2c\i2c-bit-ops.c - i2c-bit-ops.c - 0 - 0 - - - 4 - 18 - 1 - 0 - 0 - 0 - ..\..\..\components\drivers\i2c\i2c_core.c - i2c_core.c - 0 - 0 - - - 4 - 19 - 1 - 0 - 0 - 0 - ..\..\..\components\drivers\i2c\i2c_dev.c - i2c_dev.c - 0 - 0 - - - 4 - 20 - 1 - 0 - 0 - 0 - ..\..\..\components\drivers\ipc\completion.c - completion.c - 0 - 0 - - - 4 - 21 - 1 - 0 - 0 - 0 - ..\..\..\components\drivers\ipc\dataqueue.c - dataqueue.c - 0 - 0 - - - 4 - 22 - 1 - 0 - 0 - 0 - ..\..\..\components\drivers\ipc\pipe.c - pipe.c - 0 - 0 - - - 4 - 23 - 1 - 0 - 0 - 0 - ..\..\..\components\drivers\ipc\ringblk_buf.c - ringblk_buf.c - 0 - 0 - - - 4 - 24 - 1 - 0 - 0 - 0 - ..\..\..\components\drivers\ipc\ringbuffer.c - ringbuffer.c - 0 - 0 - - - 4 - 25 - 1 - 0 - 0 - 0 - ..\..\..\components\drivers\ipc\waitqueue.c - waitqueue.c - 0 - 0 - - - 4 - 26 - 1 - 0 - 0 - 0 - ..\..\..\components\drivers\ipc\workqueue.c - workqueue.c - 0 - 0 - - - 4 - 27 - 1 - 0 - 0 - 0 - ..\..\..\components\drivers\misc\adc.c - adc.c - 0 - 0 - - - 4 - 28 - 1 - 0 - 0 - 0 - ..\..\..\components\drivers\misc\pin.c - pin.c - 0 - 0 - - - 4 - 29 - 1 - 0 - 0 - 0 - ..\..\..\components\drivers\misc\rt_drv_pwm.c - rt_drv_pwm.c - 0 - 0 - - - 4 - 30 - 1 - 0 - 0 - 0 - ..\..\..\components\drivers\serial\serial.c - serial.c - 0 - 0 - - - 4 - 31 - 1 - 0 - 0 - 0 - ..\..\..\components\drivers\spi\spi_core.c - spi_core.c - 0 - 0 - - - 4 - 32 - 1 - 0 - 0 - 0 - ..\..\..\components\drivers\spi\spi_dev.c - spi_dev.c - 0 - 0 - - - - - Drivers - 1 - 0 - 0 - 0 - - 5 - 33 - 2 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\CMSIS\Device\ST\STM32U5xx\Source\Templates\arm\startup_stm32u575xx.s - startup_stm32u575xx.s - 0 - 0 - - - 5 - 34 - 1 - 0 - 0 - 0 - board\CubeMX_Config\Src\stm32u5xx_hal_msp.c - stm32u5xx_hal_msp.c - 0 - 0 - - - 5 - 35 - 1 - 0 - 0 - 0 - board\board.c - board.c - 0 - 0 - - - 5 - 36 - 1 - 0 - 0 - 0 - ..\libraries\HAL_Drivers\drv_adc.c - drv_adc.c - 0 - 0 - - - 5 - 37 - 1 - 0 - 0 - 0 - ..\libraries\HAL_Drivers\drv_common.c - drv_common.c - 0 - 0 - - - 5 - 38 - 1 - 0 - 0 - 0 - ..\libraries\HAL_Drivers\drv_gpio.c - drv_gpio.c - 0 - 0 - - - 5 - 39 - 1 - 0 - 0 - 0 - ..\libraries\HAL_Drivers\drv_spi.c - drv_spi.c - 0 - 0 - - - 5 - 40 - 1 - 0 - 0 - 0 - ..\libraries\HAL_Drivers\drv_usart.c - drv_usart.c - 0 - 0 - - - - - Finsh - 0 - 0 - 0 - 0 - - 6 - 41 - 1 - 0 - 0 - 0 - ..\..\..\components\finsh\shell.c - shell.c - 0 - 0 - - - 6 - 42 - 1 - 0 - 0 - 0 - ..\..\..\components\finsh\msh.c - msh.c - 0 - 0 - - - 6 - 43 - 1 - 0 - 0 - 0 - ..\..\..\components\finsh\msh_parse.c - msh_parse.c - 0 - 0 - - - 6 - 44 - 1 - 0 - 0 - 0 - ..\..\..\components\finsh\cmd.c - cmd.c - 0 - 0 - - - - - Kernel - 0 - 0 - 0 - 0 - - 7 - 45 - 1 - 0 - 0 - 0 - ..\..\..\src\clock.c - clock.c - 0 - 0 - - - 7 - 46 - 1 - 0 - 0 - 0 - ..\..\..\src\components.c - components.c - 0 - 0 - - - 7 - 47 - 1 - 0 - 0 - 0 - ..\..\..\src\device.c - device.c - 0 - 0 - - - 7 - 48 - 1 - 0 - 0 - 0 - ..\..\..\src\idle.c - idle.c - 0 - 0 - - - 7 - 49 - 1 - 0 - 0 - 0 - ..\..\..\src\ipc.c - ipc.c - 0 - 0 - - - 7 - 50 - 1 - 0 - 0 - 0 - ..\..\..\src\irq.c - irq.c - 0 - 0 - - - 7 - 51 - 1 - 0 - 0 - 0 - ..\..\..\src\kservice.c - kservice.c - 0 - 0 - - - 7 - 52 - 1 - 0 - 0 - 0 - ..\..\..\src\mem.c - mem.c - 0 - 0 - - - 7 - 53 - 1 - 0 - 0 - 0 - ..\..\..\src\mempool.c - mempool.c - 0 - 0 - - - 7 - 54 - 1 - 0 - 0 - 0 - ..\..\..\src\object.c - object.c - 0 - 0 - - - 7 - 55 - 1 - 0 - 0 - 0 - ..\..\..\src\scheduler_up.c - scheduler_up.c - 0 - 0 - - - 7 - 56 - 1 - 0 - 0 - 0 - ..\..\..\src\thread.c - thread.c - 0 - 0 - - - 7 - 57 - 1 - 0 - 0 - 0 - ..\..\..\src\timer.c - timer.c - 0 - 0 - - - - - Libraries - 0 - 0 - 0 - 0 - - 8 - 58 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_uart.c - stm32u5xx_hal_uart.c - 0 - 0 - - - 8 - 59 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal.c - stm32u5xx_hal.c - 0 - 0 - - - 8 - 60 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_spi.c - stm32u5xx_hal_spi.c - 0 - 0 - - - 8 - 61 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_crc.c - stm32u5xx_hal_crc.c - 0 - 0 - - - 8 - 62 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_spi_ex.c - stm32u5xx_hal_spi_ex.c - 0 - 0 - - - 8 - 63 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_icache.c - stm32u5xx_hal_icache.c - 0 - 0 - - - 8 - 64 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_uart_ex.c - stm32u5xx_hal_uart_ex.c - 0 - 0 - - - 8 - 65 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_dma.c - stm32u5xx_hal_dma.c - 0 - 0 - - - 8 - 66 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_usart.c - stm32u5xx_hal_usart.c - 0 - 0 - - - 8 - 67 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_pwr.c - stm32u5xx_hal_pwr.c - 0 - 0 - - - 8 - 68 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_rcc.c - stm32u5xx_hal_rcc.c - 0 - 0 - - - 8 - 69 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_gpio.c - stm32u5xx_hal_gpio.c - 0 - 0 - - - 8 - 70 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_rng.c - stm32u5xx_hal_rng.c - 0 - 0 - - - 8 - 71 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_tim.c - stm32u5xx_hal_tim.c - 0 - 0 - - - 8 - 72 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_cortex.c - stm32u5xx_hal_cortex.c - 0 - 0 - - - 8 - 73 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_ospi.c - stm32u5xx_hal_ospi.c - 0 - 0 - - - 8 - 74 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_cryp.c - stm32u5xx_hal_cryp.c - 0 - 0 - - - 8 - 75 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_crc_ex.c - stm32u5xx_hal_crc_ex.c - 0 - 0 - - - 8 - 76 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_lptim.c - stm32u5xx_hal_lptim.c - 0 - 0 - - - 8 - 77 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_rcc_ex.c - stm32u5xx_hal_rcc_ex.c - 0 - 0 - - - 8 - 78 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_i2c.c - stm32u5xx_hal_i2c.c - 0 - 0 - - - 8 - 79 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_usart_ex.c - stm32u5xx_hal_usart_ex.c - 0 - 0 - - - 8 - 80 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_cryp_ex.c - stm32u5xx_hal_cryp_ex.c - 0 - 0 - - - 8 - 81 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\CMSIS\Device\ST\STM32U5xx\Source\Templates\system_stm32u5xx.c - system_stm32u5xx.c - 0 - 0 - - - 8 - 82 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_pwr_ex.c - stm32u5xx_hal_pwr_ex.c - 0 - 0 - - - 8 - 83 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_comp.c - stm32u5xx_hal_comp.c - 0 - 0 - - - 8 - 84 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_i2c_ex.c - stm32u5xx_hal_i2c_ex.c - 0 - 0 - - - 8 - 85 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_adc_ex.c - stm32u5xx_hal_adc_ex.c - 0 - 0 - - - 8 - 86 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_tim_ex.c - stm32u5xx_hal_tim_ex.c - 0 - 0 - - - 8 - 87 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_dma_ex.c - stm32u5xx_hal_dma_ex.c - 0 - 0 - - - 8 - 88 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_adc.c - stm32u5xx_hal_adc.c - 0 - 0 - - - 8 - 89 - 1 - 0 - 0 - 0 - ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_exti.c - stm32u5xx_hal_exti.c - 0 - 0 - diff --git a/bsp/stm32/stm32u575-st-nucleo/project.uvprojx b/bsp/stm32/stm32u575-st-nucleo/project.uvprojx index 29334b4a15..915bd849ec 100644 --- a/bsp/stm32/stm32u575-st-nucleo/project.uvprojx +++ b/bsp/stm32/stm32u575-st-nucleo/project.uvprojx @@ -1,46 +1,43 @@ - 2.1 -
### uVision Project, (C) Keil Software
- rtthread 0x4 ARM-ADS - 6160000::V6.16::ARMCLANG + 6140000::V6.14::ARMCLANG 1 STM32U575ZITx STMicroelectronics - Keil.STM32U5xx_DFP.2.1.0 - https://www.keil.com/pack/ + Keil.STM32U5xx_DFP.1.1.0 + http://www.keil.com/pack/ IROM(0x08000000-0x81FFFFF) IRAM(0x20000000-0x200BFFFF) CLOCK(8000000) FPU3(SFPU) CPUTYPE("Cortex-M33") ELITTLE TZ - - - + + + 0 - - - - - - - - - - + + + + + + + + + + $$Device:STM32U575ZITx$CMSIS\SVD\STM32U5xx.svd 0 0 - - - - - + + + + + 0 0 @@ -55,15 +52,15 @@ 0 1 0 - + 1 0 0 0 0 - - + + 0 0 0 @@ -72,8 +69,8 @@ 0 0 - - + + 0 0 0 @@ -83,14 +80,14 @@ 1 0 fromelf --bin !L --output rtthread.bin - + 0 0 0 0 1 - + 0 @@ -104,15 +101,15 @@ 0 0 3 - - + + 0 - - - - + + + + SARMV8M.DLL -MPU TCM.DLL @@ -139,10 +136,10 @@ 1 BIN\UL2V8M.DLL "" () - - - - + + + + 0 @@ -175,7 +172,7 @@ 0 0 "Cortex-M33" - + 0 0 0 @@ -309,7 +306,7 @@ 0x0 - + 1 @@ -336,10 +333,10 @@ 0 0 - + __STDC_LIMIT_MACROS, STM32U575xx, USE_HAL_DRIVER, RT_USING_LIBC, __CLK_TCK=RT_TICK_PER_SECOND, __RTTHREAD__, RT_USING_ARMLIBC - - .;..\..\..\components\drivers\include;..\..\..\libcpu\arm\common;..\..\..\components\libc\compilers\common\include;..\libraries\STM32U5xx_HAL\CMSIS\Device\ST\STM32U5xx\Include;..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Inc;..\..\..\components\drivers\include;..\libraries\HAL_Drivers\config;..\..\..\components\libc\posix\ipc;..\libraries\HAL_Drivers;..\..\..\include;..\..\..\components\drivers\spi;..\..\..\components\drivers\include;..\..\..\components\libc\posix\io\poll;..\..\..\components\drivers\include;..\..\..\components\finsh;..\..\..\components\libc\compilers\common\extension\fcntl\octal;..\..\..\components\drivers\include;..\..\..\libcpu\arm\cortex-m33;..\libraries\HAL_Drivers\CMSIS\Include;..\..\..\components\libc\compilers\common\extension;applications;board\CubeMX_Config\Inc;board;..\..\..\components\libc\posix\io\stdio + + ..\..\..\components\libc\compilers\common\include;..\..\..\components\drivers\include;..\libraries\HAL_Drivers\CMSIS\Include;board\CubeMX_Config\Inc;..\..\..\components\libc\posix\io\poll;..\libraries\HAL_Drivers\config;..\..\..\components\libc\compilers\common\extension;..\..\..\components\drivers\spi;..\..\..\libcpu\arm\common;..\..\..\libcpu\arm\cortex-m33;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\libc\posix\ipc;..\libraries\HAL_Drivers;..\..\..\include;..\..\..\components\libc\posix\io\epoll;..\..\..\components\drivers\include;..\..\..\components\finsh;board;..\..\..\components\libc\posix\io\eventfd;.;..\libraries\STM32U5xx_HAL\CMSIS\Device\ST\STM32U5xx\Include;..\..\..\components\drivers\include;..\..\..\components\drivers\include;applications;..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Inc;..\..\..\components\libc\compilers\common\extension\fcntl\octal @@ -354,10 +351,10 @@ 0 4 - - - - + + + + @@ -369,13 +366,13 @@ 0 0x08000000 0x20000000 - + .\board\linker_scripts\link.sct - - - - - + + + + + @@ -398,36 +395,50 @@ 1 ..\..\..\components\libc\compilers\armlibc\syscall_mem.c + + syscalls.c 1 ..\..\..\components\libc\compilers\armlibc\syscalls.c + + cctype.c 1 ..\..\..\components\libc\compilers\common\cctype.c - - cstdio.c - 1 - ..\..\..\components\libc\compilers\common\cstdio.c - + + cstdlib.c 1 ..\..\..\components\libc\compilers\common\cstdlib.c + + cstring.c 1 ..\..\..\components\libc\compilers\common\cstring.c + + ctime.c 1 ..\..\..\components\libc\compilers\common\ctime.c + + + + cunistd.c + 1 + ..\..\..\components\libc\compilers\common\cunistd.c + + + cwchar.c 1 @@ -443,31 +454,43 @@ 1 ..\..\..\libcpu\arm\common\atomic_arm.c + + div0.c 1 ..\..\..\libcpu\arm\common\div0.c + + showmem.c 1 ..\..\..\libcpu\arm\common\showmem.c + + context_rvds.S 2 ..\..\..\libcpu\arm\cortex-m33\context_rvds.S + + cpuport.c 1 ..\..\..\libcpu\arm\cortex-m33\cpuport.c + + syscall_rvds.S 2 ..\..\..\libcpu\arm\cortex-m33\syscall_rvds.S + + trustzone.c 1 @@ -477,82 +500,119 @@ DeviceDrivers + + + device.c + 1 + ..\..\..\components\drivers\core\device.c + + i2c-bit-ops.c 1 ..\..\..\components\drivers\i2c\i2c-bit-ops.c + + i2c_core.c 1 ..\..\..\components\drivers\i2c\i2c_core.c + + i2c_dev.c 1 ..\..\..\components\drivers\i2c\i2c_dev.c + + completion.c 1 ..\..\..\components\drivers\ipc\completion.c + + dataqueue.c 1 ..\..\..\components\drivers\ipc\dataqueue.c + + pipe.c 1 ..\..\..\components\drivers\ipc\pipe.c + + ringblk_buf.c 1 ..\..\..\components\drivers\ipc\ringblk_buf.c + + ringbuffer.c 1 ..\..\..\components\drivers\ipc\ringbuffer.c + + waitqueue.c 1 ..\..\..\components\drivers\ipc\waitqueue.c + + workqueue.c 1 ..\..\..\components\drivers\ipc\workqueue.c + + adc.c 1 ..\..\..\components\drivers\misc\adc.c + + pin.c 1 ..\..\..\components\drivers\misc\pin.c + + rt_drv_pwm.c 1 ..\..\..\components\drivers\misc\rt_drv_pwm.c + + serial.c 1 ..\..\..\components\drivers\serial\serial.c + + spi_core.c 1 ..\..\..\components\drivers\spi\spi_core.c + + spi_dev.c 1 @@ -563,47 +623,61 @@ Drivers - - startup_stm32u575xx.s - 2 - ..\libraries\STM32U5xx_HAL\CMSIS\Device\ST\STM32U5xx\Source\Templates\arm\startup_stm32u575xx.s - - - stm32u5xx_hal_msp.c - 1 - board\CubeMX_Config\Src\stm32u5xx_hal_msp.c - - - board.c - 1 - board\board.c - drv_adc.c 1 ..\libraries\HAL_Drivers\drv_adc.c + + drv_common.c 1 ..\libraries\HAL_Drivers\drv_common.c + + drv_gpio.c 1 ..\libraries\HAL_Drivers\drv_gpio.c + + drv_spi.c 1 ..\libraries\HAL_Drivers\drv_spi.c + + drv_usart.c 1 ..\libraries\HAL_Drivers\drv_usart.c + + + startup_stm32u575xx.s + 2 + ..\libraries\STM32U5xx_HAL\CMSIS\Device\ST\STM32U5xx\Source\Templates\arm\startup_stm32u575xx.s + + + + + stm32u5xx_hal_msp.c + 1 + board\CubeMX_Config\Src\stm32u5xx_hal_msp.c + + + + + board.c + 1 + board\board.c + + Finsh @@ -613,16 +687,22 @@ 1 ..\..\..\components\finsh\shell.c + + msh.c 1 ..\..\..\components\finsh\msh.c + + msh_parse.c 1 ..\..\..\components\finsh\msh_parse.c + + cmd.c 1 @@ -638,61 +718,78 @@ 1 ..\..\..\src\clock.c + + components.c 1 ..\..\..\src\components.c - - device.c - 1 - ..\..\..\src\device.c - + + idle.c 1 ..\..\..\src\idle.c + + ipc.c 1 ..\..\..\src\ipc.c + + irq.c 1 ..\..\..\src\irq.c + + kservice.c 1 ..\..\..\src\kservice.c + + mem.c 1 ..\..\..\src\mem.c + + mempool.c 1 ..\..\..\src\mempool.c + + object.c 1 ..\..\..\src\object.c + + scheduler_up.c 1 ..\..\..\src\scheduler_up.c + + thread.c 1 ..\..\..\src\thread.c + + timer.c 1 @@ -708,156 +805,218 @@ 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_uart.c + + stm32u5xx_hal.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal.c + + stm32u5xx_hal_spi.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_spi.c + + stm32u5xx_hal_crc.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_crc.c + + stm32u5xx_hal_spi_ex.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_spi_ex.c + + stm32u5xx_hal_icache.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_icache.c + + stm32u5xx_hal_uart_ex.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_uart_ex.c + + stm32u5xx_hal_dma.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_dma.c + + stm32u5xx_hal_usart.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_usart.c + + stm32u5xx_hal_pwr.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_pwr.c + + stm32u5xx_hal_rcc.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_rcc.c + + stm32u5xx_hal_gpio.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_gpio.c + + stm32u5xx_hal_rng.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_rng.c + + stm32u5xx_hal_tim.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_tim.c + + stm32u5xx_hal_cortex.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_cortex.c + + stm32u5xx_hal_ospi.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_ospi.c + + stm32u5xx_hal_cryp.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_cryp.c + + stm32u5xx_hal_crc_ex.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_crc_ex.c + + stm32u5xx_hal_lptim.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_lptim.c + + stm32u5xx_hal_rcc_ex.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_rcc_ex.c + + stm32u5xx_hal_i2c.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_i2c.c + + stm32u5xx_hal_usart_ex.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_usart_ex.c + + stm32u5xx_hal_cryp_ex.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_cryp_ex.c + + system_stm32u5xx.c 1 ..\libraries\STM32U5xx_HAL\CMSIS\Device\ST\STM32U5xx\Source\Templates\system_stm32u5xx.c + + stm32u5xx_hal_pwr_ex.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_pwr_ex.c + + stm32u5xx_hal_comp.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_comp.c + + stm32u5xx_hal_i2c_ex.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_i2c_ex.c + + stm32u5xx_hal_adc_ex.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_adc_ex.c + + stm32u5xx_hal_tim_ex.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_tim_ex.c + + stm32u5xx_hal_dma_ex.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_dma_ex.c + + stm32u5xx_hal_adc.c 1 ..\libraries\STM32U5xx_HAL\STM32U5xx_HAL_Driver\Src\stm32u5xx_hal_adc.c + + stm32u5xx_hal_exti.c 1 @@ -868,21 +1027,23 @@ - - - - + + + - <Project Info> + + + + + 0 1 -
diff --git a/bsp/stm32/stm32u575-st-nucleo/rtconfig.h b/bsp/stm32/stm32u575-st-nucleo/rtconfig.h index a5c568b626..f2af471bc3 100644 --- a/bsp/stm32/stm32u575-st-nucleo/rtconfig.h +++ b/bsp/stm32/stm32u575-st-nucleo/rtconfig.h @@ -23,8 +23,10 @@ /* kservice optimization */ -#define RT_DEBUG -#define RT_DEBUG_COLOR +#define RT_USING_DEBUG +#define RT_DEBUGING_COLOR +#define RT_DEBUGING_CONTEXT +#define RT_DEBUGING_INIT /* Inter-Thread communication */ @@ -36,7 +38,6 @@ /* Memory Management */ -#define RT_PAGE_MAX_ORDER 11 #define RT_USING_MEMPOOL #define RT_USING_SMALL_MEM #define RT_USING_SMALL_MEM_AS_HEAP @@ -88,15 +89,26 @@ #define RT_USING_SERIAL #define RT_USING_SERIAL_V1 #define RT_SERIAL_RB_BUFSZ 64 +#define RT_USING_I2C +#define RT_USING_I2C_BITOPS #define RT_USING_PIN - +#define RT_USING_ADC +#define RT_USING_PWM +#define RT_USING_SPI /* Using USB */ /* C/C++ and POSIX layer */ -#define RT_LIBC_DEFAULT_TIMEZONE 8 +/* ISO-ANSI C layer */ + +/* Timezone and Daylight Saving Time */ + +#define RT_LIBC_USING_LIGHT_TZ_DST +#define RT_LIBC_TZ_DEFAULT_HOUR 8 +#define RT_LIBC_TZ_DEFAULT_MIN 0 +#define RT_LIBC_TZ_DEFAULT_SEC 0 /* POSIX (Portable Operating System Interface) layer */ @@ -151,6 +163,9 @@ /* u8g2: a monochrome graphic library */ +/* PainterEngine: A cross-platform graphics application framework written in C language */ + + /* tools packages */ @@ -170,21 +185,10 @@ /* peripheral libraries and drivers */ -/* sensors drivers */ - - -/* touch drivers */ - - -/* Kendryte SDK */ - /* AI packages */ -/* Signal Processing and Control Algorithm Packages */ - - /* miscellaneous packages */ /* project laboratory */ @@ -194,41 +198,6 @@ /* entertainment: terminal games and other interesting software packages */ - -/* Arduino libraries */ - - -/* Projects */ - - -/* Sensors */ - - -/* Display */ - - -/* Timing */ - - -/* Data Processing */ - - -/* Data Storage */ - -/* Communication */ - - -/* Device Control */ - - -/* Other */ - - -/* Signal IO */ - - -/* Uncategorized */ - #define SOC_FAMILY_STM32 #define SOC_SERIES_STM32U5

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 _OZ}6)RV)rLL)o2OfBofLBFl^L%!1d!CYL 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%0D! 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%0AN=YMSwDC>LqogJ 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 JZJykfA24qN@)Mwva=Gz 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ȫ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